Index: azure_iot_hub_f767zi/trunk/Makefile
===================================================================
--- azure_iot_hub_f767zi/trunk/Makefile	(revision 457)
+++ azure_iot_hub_f767zi/trunk/Makefile	(revision 457)
@@ -0,0 +1,50 @@
+
+MAKE = make
+
+LIBKERNEL = asp_baseplatform/OBJ/STM32F767NUCLEO144_GCC/libkernel/libkernel.a
+LIBWOLFSSL = wolfssl-4.4.0/Debug/libwolfssl.a
+LIBZLIB = zlib-1.2.11/Debug/libzlib.a
+LIBAZURE_IOT_SDK = azure_iot_sdk/Debug/libazure_iot_sdk.a
+ASP_ELF = app_iothub_client/Debug/asp.elf
+
+$(LIBKERNEL):
+	$(MAKE) -j 1 -C asp_baseplatform/OBJ/STM32F767NUCLEO144_GCC/MAC all
+
+$(LIBWOLFSSL):
+	$(MAKE) -j -C wolfssl-4.4.0 all
+
+$(LIBZLIB):
+	$(MAKE) -j -C zlib-1.2.11 all
+
+$(LIBAZURE_IOT_SDK):
+	$(MAKE) -j -C azure_iot_sdk all
+
+$(ASP_ELF): $(LIBKERNEL) $(LIBWOLFSSL) $(LIBZLIB) $(LIBAZURE_IOT_SDK)
+	$(MAKE) -j 1 -C app_iothub_client/Debug all
+
+.PHONY: refresh
+refresh: 
+	rm -f $(LIBKERNEL)
+	rm -f $(LIBWOLFSSL)
+	rm -f $(LIBZLIB)
+	rm -f $(LIBAZURE_IOT_SDK)
+	rm -f $(ASP_ELF)
+
+.PHONY: all
+all: refresh $(ASP_ELF)
+
+.PHONY: clean
+clean:
+	$(MAKE) -j -C asp_baseplatform/OBJ/STM32F767NUCLEO144_GCC/MAC clean
+	$(MAKE) -j -C wolfssl-4.4.0 clean
+	$(MAKE) -j -C zlib-1.2.11 clean
+	$(MAKE) -j -C azure_iot_sdk clean
+	$(MAKE) -j -C app_iothub_client/Debug clean
+
+.PHONY: realclean
+realclean:
+	$(MAKE) -j -C asp_baseplatform/OBJ/STM32F767NUCLEO144_GCC/MAC realclean
+	$(MAKE) -j -C wolfssl-4.4.0 clean
+	$(MAKE) -j -C zlib-1.2.11 clean
+	$(MAKE) -j -C azure_iot_sdk clean
+	$(MAKE) -j -C app_iothub_client/Debug realclean
Index: azure_iot_hub_f767zi/trunk/STM32F7x7.svd
===================================================================
--- azure_iot_hub_f767zi/trunk/STM32F7x7.svd	(revision 457)
+++ azure_iot_hub_f767zi/trunk/STM32F7x7.svd	(revision 457)
@@ -0,0 +1,83873 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<device xmlns:xs="http://www.w3.org/2001/XMLSchema-instance" schemaVersion="1.1" xs:noNamespaceSchemaLocation="CMSIS-SVD_Schema_1_1.xsd">
+   <name>STM32F7x7</name>
+   <version>1.9</version>
+   <description>STM32F7x7</description>
+  <cpu>
+    <name>CM7</name>
+    <revision>r0p1</revision>
+    <endian>little</endian>
+    <mpuPresent>true</mpuPresent>
+    <fpuPresent>true</fpuPresent>
+    <nvicPrioBits>4</nvicPrioBits>
+    <vendorSystickConfig>false</vendorSystickConfig>
+  </cpu>
+   <!--Bus Interface Properties-->
+   <!--Cortex-M3 is byte addressable-->
+   <addressUnitBits>8</addressUnitBits>
+   <!--the maximum data bit width accessible within a single transfer-->
+   <width>32</width>
+   <!--Register Default Properties-->
+   <size>0x20</size>
+   <resetValue>0x0</resetValue>
+   <resetMask>0xFFFFFFFF</resetMask>
+   <peripherals>
+      <peripheral>
+         <name>RNG</name>
+         <description>Random number generator</description>
+         <groupName>RNG</groupName>
+         <baseAddress>0x50060800</baseAddress>
+         <addressBlock>
+            <offset>0x0</offset>
+            <size>0x400</size>
+            <usage>registers</usage>
+         </addressBlock>
+         <interrupt>
+            <name>HASH_RNG</name>
+            <description>Hash and Rng global interrupt</description>
+            <value>80</value>
+         </interrupt>
+         <registers>
+            <register>
+               <name>CR</name>
+               <displayName>CR</displayName>
+               <description>control register</description>
+               <addressOffset>0x0</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>IE</name>
+                     <description>Interrupt enable</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>RNGEN</name>
+                     <description>Random number generator               enable</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>SR</name>
+               <displayName>SR</displayName>
+               <description>status register</description>
+               <addressOffset>0x4</addressOffset>
+               <size>0x20</size>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>SEIS</name>
+                     <description>Seed error interrupt               status</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>CEIS</name>
+                     <description>Clock error interrupt               status</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>SECS</name>
+                     <description>Seed error current status</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-only</access>
+                  </field>
+                  <field>
+                     <name>CECS</name>
+                     <description>Clock error current status</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-only</access>
+                  </field>
+                  <field>
+                     <name>DRDY</name>
+                     <description>Data ready</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-only</access>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DR</name>
+               <displayName>DR</displayName>
+               <description>data register</description>
+               <addressOffset>0x8</addressOffset>
+               <size>0x20</size>
+               <access>read-only</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>RNDATA</name>
+                     <description>Random data</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+         </registers>
+      </peripheral>
+      <peripheral>
+         <name>HASH</name>
+         <description>Hash processor</description>
+         <groupName>HASH</groupName>
+         <baseAddress>0x50060400</baseAddress>
+         <addressBlock>
+            <offset>0x0</offset>
+            <size>0x400</size>
+            <usage>registers</usage>
+         </addressBlock>
+         <registers>
+            <register>
+               <name>CR</name>
+               <displayName>CR</displayName>
+               <description>control register</description>
+               <addressOffset>0x0</addressOffset>
+               <size>0x20</size>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>INIT</name>
+                     <description>Initialize message digest               calculation</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>write-only</access>
+                  </field>
+                  <field>
+                     <name>DMAE</name>
+                     <description>DMA enable</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>DATATYPE</name>
+                     <description>Data type selection</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>2</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>MODE</name>
+                     <description>Mode selection</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>ALGO0</name>
+                     <description>Algorithm selection</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>NBW</name>
+                     <description>Number of words already               pushed</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>4</bitWidth>
+                     <access>read-only</access>
+                  </field>
+                  <field>
+                     <name>DINNE</name>
+                     <description>DIN not empty</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-only</access>
+                  </field>
+                  <field>
+                     <name>MDMAT</name>
+                     <description>Multiple DMA Transfers</description>
+                     <bitOffset>13</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>LKEY</name>
+                     <description>Long key selection</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>ALGO1</name>
+                     <description>ALGO</description>
+                     <bitOffset>18</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DIN</name>
+               <displayName>DIN</displayName>
+               <description>data input register</description>
+               <addressOffset>0x4</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DATAIN</name>
+                     <description>Data input</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>STR</name>
+               <displayName>STR</displayName>
+               <description>start register</description>
+               <addressOffset>0x8</addressOffset>
+               <size>0x20</size>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DCAL</name>
+                     <description>Digest calculation</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>write-only</access>
+                  </field>
+                  <field>
+                     <name>NBLW</name>
+                     <description>Number of valid bits in the last word of               the message</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>5</bitWidth>
+                     <access>read-write</access>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HR0</name>
+               <displayName>HR0</displayName>
+               <description>digest registers</description>
+               <addressOffset>0xC</addressOffset>
+               <size>0x20</size>
+               <access>read-only</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>H0</name>
+                     <description>H0</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HR1</name>
+               <displayName>HR1</displayName>
+               <description>digest registers</description>
+               <addressOffset>0x10</addressOffset>
+               <size>0x20</size>
+               <access>read-only</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>H1</name>
+                     <description>H1</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HR2</name>
+               <displayName>HR2</displayName>
+               <description>digest registers</description>
+               <addressOffset>0x14</addressOffset>
+               <size>0x20</size>
+               <access>read-only</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>H2</name>
+                     <description>H2</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HR3</name>
+               <displayName>HR3</displayName>
+               <description>digest registers</description>
+               <addressOffset>0x18</addressOffset>
+               <size>0x20</size>
+               <access>read-only</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>H3</name>
+                     <description>H3</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HR4</name>
+               <displayName>HR4</displayName>
+               <description>digest registers</description>
+               <addressOffset>0x1C</addressOffset>
+               <size>0x20</size>
+               <access>read-only</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>H4</name>
+                     <description>H4</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>IMR</name>
+               <displayName>IMR</displayName>
+               <description>interrupt enable register</description>
+               <addressOffset>0x20</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DCIE</name>
+                     <description>Digest calculation completion interrupt               enable</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>DINIE</name>
+                     <description>Data input interrupt               enable</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>SR</name>
+               <displayName>SR</displayName>
+               <description>status register</description>
+               <addressOffset>0x24</addressOffset>
+               <size>0x20</size>
+               <resetValue>0x00000001</resetValue>
+               <fields>
+                  <field>
+                     <name>BUSY</name>
+                     <description>Busy bit</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-only</access>
+                  </field>
+                  <field>
+                     <name>DMAS</name>
+                     <description>DMA Status</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-only</access>
+                  </field>
+                  <field>
+                     <name>DCIS</name>
+                     <description>Digest calculation completion interrupt               status</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>DINIS</name>
+                     <description>Data input interrupt               status</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>CSR0</name>
+               <displayName>CSR0</displayName>
+               <description>context swap registers</description>
+               <addressOffset>0xF8</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>CSR0</name>
+                     <description>CSR0</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>CSR1</name>
+               <displayName>CSR1</displayName>
+               <description>context swap registers</description>
+               <addressOffset>0xFC</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>CSR1</name>
+                     <description>CSR1</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>CSR2</name>
+               <displayName>CSR2</displayName>
+               <description>context swap registers</description>
+               <addressOffset>0x100</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>CSR2</name>
+                     <description>CSR2</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>CSR3</name>
+               <displayName>CSR3</displayName>
+               <description>context swap registers</description>
+               <addressOffset>0x104</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>CSR3</name>
+                     <description>CSR3</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>CSR4</name>
+               <displayName>CSR4</displayName>
+               <description>context swap registers</description>
+               <addressOffset>0x108</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>CSR4</name>
+                     <description>CSR4</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>CSR5</name>
+               <displayName>CSR5</displayName>
+               <description>context swap registers</description>
+               <addressOffset>0x10C</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>CSR5</name>
+                     <description>CSR5</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>CSR6</name>
+               <displayName>CSR6</displayName>
+               <description>context swap registers</description>
+               <addressOffset>0x110</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>CSR6</name>
+                     <description>CSR6</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>CSR7</name>
+               <displayName>CSR7</displayName>
+               <description>context swap registers</description>
+               <addressOffset>0x114</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>CSR7</name>
+                     <description>CSR7</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>CSR8</name>
+               <displayName>CSR8</displayName>
+               <description>context swap registers</description>
+               <addressOffset>0x118</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>CSR8</name>
+                     <description>CSR8</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>CSR9</name>
+               <displayName>CSR9</displayName>
+               <description>context swap registers</description>
+               <addressOffset>0x11C</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>CSR9</name>
+                     <description>CSR9</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>CSR10</name>
+               <displayName>CSR10</displayName>
+               <description>context swap registers</description>
+               <addressOffset>0x120</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>CSR10</name>
+                     <description>CSR10</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>CSR11</name>
+               <displayName>CSR11</displayName>
+               <description>context swap registers</description>
+               <addressOffset>0x124</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>CSR11</name>
+                     <description>CSR11</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>CSR12</name>
+               <displayName>CSR12</displayName>
+               <description>context swap registers</description>
+               <addressOffset>0x128</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>CSR12</name>
+                     <description>CSR12</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>CSR13</name>
+               <displayName>CSR13</displayName>
+               <description>context swap registers</description>
+               <addressOffset>0x12C</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>CSR13</name>
+                     <description>CSR13</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>CSR14</name>
+               <displayName>CSR14</displayName>
+               <description>context swap registers</description>
+               <addressOffset>0x130</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>CSR14</name>
+                     <description>CSR14</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>CSR15</name>
+               <displayName>CSR15</displayName>
+               <description>context swap registers</description>
+               <addressOffset>0x134</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>CSR15</name>
+                     <description>CSR15</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>CSR16</name>
+               <displayName>CSR16</displayName>
+               <description>context swap registers</description>
+               <addressOffset>0x138</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>CSR16</name>
+                     <description>CSR16</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>CSR17</name>
+               <displayName>CSR17</displayName>
+               <description>context swap registers</description>
+               <addressOffset>0x13C</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>CSR17</name>
+                     <description>CSR17</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>CSR18</name>
+               <displayName>CSR18</displayName>
+               <description>context swap registers</description>
+               <addressOffset>0x140</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>CSR18</name>
+                     <description>CSR18</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>CSR19</name>
+               <displayName>CSR19</displayName>
+               <description>context swap registers</description>
+               <addressOffset>0x144</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>CSR19</name>
+                     <description>CSR19</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>CSR20</name>
+               <displayName>CSR20</displayName>
+               <description>context swap registers</description>
+               <addressOffset>0x148</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>CSR20</name>
+                     <description>CSR20</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>CSR21</name>
+               <displayName>CSR21</displayName>
+               <description>context swap registers</description>
+               <addressOffset>0x14C</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>CSR21</name>
+                     <description>CSR21</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>CSR22</name>
+               <displayName>CSR22</displayName>
+               <description>context swap registers</description>
+               <addressOffset>0x150</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>CSR22</name>
+                     <description>CSR22</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>CSR23</name>
+               <displayName>CSR23</displayName>
+               <description>context swap registers</description>
+               <addressOffset>0x154</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>CSR23</name>
+                     <description>CSR23</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>CSR24</name>
+               <displayName>CSR24</displayName>
+               <description>context swap registers</description>
+               <addressOffset>0x158</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>CSR24</name>
+                     <description>CSR24</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>CSR25</name>
+               <displayName>CSR25</displayName>
+               <description>context swap registers</description>
+               <addressOffset>0x15C</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>CSR25</name>
+                     <description>CSR25</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>CSR26</name>
+               <displayName>CSR26</displayName>
+               <description>context swap registers</description>
+               <addressOffset>0x160</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>CSR26</name>
+                     <description>CSR26</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>CSR27</name>
+               <displayName>CSR27</displayName>
+               <description>context swap registers</description>
+               <addressOffset>0x164</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>CSR27</name>
+                     <description>CSR27</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>CSR28</name>
+               <displayName>CSR28</displayName>
+               <description>context swap registers</description>
+               <addressOffset>0x168</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>CSR28</name>
+                     <description>CSR28</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>CSR29</name>
+               <displayName>CSR29</displayName>
+               <description>context swap registers</description>
+               <addressOffset>0x16C</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>CSR29</name>
+                     <description>CSR29</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>CSR30</name>
+               <displayName>CSR30</displayName>
+               <description>context swap registers</description>
+               <addressOffset>0x170</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>CSR30</name>
+                     <description>CSR30</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>CSR31</name>
+               <displayName>CSR31</displayName>
+               <description>context swap registers</description>
+               <addressOffset>0x174</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>CSR31</name>
+                     <description>CSR31</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>CSR32</name>
+               <displayName>CSR32</displayName>
+               <description>context swap registers</description>
+               <addressOffset>0x178</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>CSR32</name>
+                     <description>CSR32</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>CSR33</name>
+               <displayName>CSR33</displayName>
+               <description>context swap registers</description>
+               <addressOffset>0x17C</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>CSR33</name>
+                     <description>CSR33</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>CSR34</name>
+               <displayName>CSR34</displayName>
+               <description>context swap registers</description>
+               <addressOffset>0x180</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>CSR34</name>
+                     <description>CSR34</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>CSR35</name>
+               <displayName>CSR35</displayName>
+               <description>context swap registers</description>
+               <addressOffset>0x184</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>CSR35</name>
+                     <description>CSR35</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>CSR36</name>
+               <displayName>CSR36</displayName>
+               <description>context swap registers</description>
+               <addressOffset>0x188</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>CSR36</name>
+                     <description>CSR36</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>CSR37</name>
+               <displayName>CSR37</displayName>
+               <description>context swap registers</description>
+               <addressOffset>0x18C</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>CSR37</name>
+                     <description>CSR37</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>CSR38</name>
+               <displayName>CSR38</displayName>
+               <description>context swap registers</description>
+               <addressOffset>0x190</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>CSR38</name>
+                     <description>CSR38</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>CSR39</name>
+               <displayName>CSR39</displayName>
+               <description>context swap registers</description>
+               <addressOffset>0x194</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>CSR39</name>
+                     <description>CSR39</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>CSR40</name>
+               <displayName>CSR40</displayName>
+               <description>context swap registers</description>
+               <addressOffset>0x198</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>CSR40</name>
+                     <description>CSR40</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>CSR41</name>
+               <displayName>CSR41</displayName>
+               <description>context swap registers</description>
+               <addressOffset>0x19C</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>CSR41</name>
+                     <description>CSR41</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>CSR42</name>
+               <displayName>CSR42</displayName>
+               <description>context swap registers</description>
+               <addressOffset>0x1A0</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>CSR42</name>
+                     <description>CSR42</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>CSR43</name>
+               <displayName>CSR43</displayName>
+               <description>context swap registers</description>
+               <addressOffset>0x1A4</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>CSR43</name>
+                     <description>CSR43</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>CSR44</name>
+               <displayName>CSR44</displayName>
+               <description>context swap registers</description>
+               <addressOffset>0x1A8</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>CSR44</name>
+                     <description>CSR44</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>CSR45</name>
+               <displayName>CSR45</displayName>
+               <description>context swap registers</description>
+               <addressOffset>0x1AC</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>CSR45</name>
+                     <description>CSR45</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>CSR46</name>
+               <displayName>CSR46</displayName>
+               <description>context swap registers</description>
+               <addressOffset>0x1B0</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>CSR46</name>
+                     <description>CSR46</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>CSR47</name>
+               <displayName>CSR47</displayName>
+               <description>context swap registers</description>
+               <addressOffset>0x1B4</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>CSR47</name>
+                     <description>CSR47</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>CSR48</name>
+               <displayName>CSR48</displayName>
+               <description>context swap registers</description>
+               <addressOffset>0x1B8</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>CSR48</name>
+                     <description>CSR48</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>CSR49</name>
+               <displayName>CSR49</displayName>
+               <description>context swap registers</description>
+               <addressOffset>0x1BC</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>CSR49</name>
+                     <description>CSR49</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>CSR50</name>
+               <displayName>CSR50</displayName>
+               <description>context swap registers</description>
+               <addressOffset>0x1C0</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>CSR50</name>
+                     <description>CSR50</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>CSR51</name>
+               <displayName>CSR51</displayName>
+               <description>context swap registers</description>
+               <addressOffset>0x1C4</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>CSR51</name>
+                     <description>CSR51</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>CSR52</name>
+               <displayName>CSR52</displayName>
+               <description>context swap registers</description>
+               <addressOffset>0x1C8</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>CSR52</name>
+                     <description>CSR52</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>CSR53</name>
+               <displayName>CSR53</displayName>
+               <description>context swap registers</description>
+               <addressOffset>0x1CC</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>CSR53</name>
+                     <description>CSR53</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HASH_HR0</name>
+               <displayName>HASH_HR0</displayName>
+               <description>HASH digest register</description>
+               <addressOffset>0x310</addressOffset>
+               <size>0x20</size>
+               <access>read-only</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>H0</name>
+                     <description>H0</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HASH_HR1</name>
+               <displayName>HASH_HR1</displayName>
+               <description>read-only</description>
+               <addressOffset>0x314</addressOffset>
+               <size>0x20</size>
+               <access>read-only</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>H1</name>
+                     <description>H1</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HASH_HR2</name>
+               <displayName>HASH_HR2</displayName>
+               <description>read-only</description>
+               <addressOffset>0x318</addressOffset>
+               <size>0x20</size>
+               <access>read-only</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>H2</name>
+                     <description>H2</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HASH_HR3</name>
+               <displayName>HASH_HR3</displayName>
+               <description>read-only</description>
+               <addressOffset>0x31C</addressOffset>
+               <size>0x20</size>
+               <access>read-only</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>H3</name>
+                     <description>H3</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HASH_HR4</name>
+               <displayName>HASH_HR4</displayName>
+               <description>read-only</description>
+               <addressOffset>0x320</addressOffset>
+               <size>0x20</size>
+               <access>read-only</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>H4</name>
+                     <description>H4</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HASH_HR5</name>
+               <displayName>HASH_HR5</displayName>
+               <description>read-only</description>
+               <addressOffset>0x324</addressOffset>
+               <size>0x20</size>
+               <access>read-only</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>H5</name>
+                     <description>H5</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HASH_HR6</name>
+               <displayName>HASH_HR6</displayName>
+               <description>read-only</description>
+               <addressOffset>0x328</addressOffset>
+               <size>0x20</size>
+               <access>read-only</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>H6</name>
+                     <description>H6</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HASH_HR7</name>
+               <displayName>HASH_HR7</displayName>
+               <description>read-only</description>
+               <addressOffset>0x32C</addressOffset>
+               <size>0x20</size>
+               <access>read-only</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>H7</name>
+                     <description>H7</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+         </registers>
+      </peripheral>
+      <peripheral>
+         <name>CRYP</name>
+         <description>Cryptographic processor</description>
+         <groupName>CRYP</groupName>
+         <baseAddress>0x50060000</baseAddress>
+         <addressBlock>
+            <offset>0x0</offset>
+            <size>0x400</size>
+            <usage>registers</usage>
+         </addressBlock>
+         <interrupt>
+            <name>CRYP</name>
+            <description>CRYP crypto global interrupt</description>
+            <value>79</value>
+         </interrupt>
+         <registers>
+            <register>
+               <name>CR</name>
+               <displayName>CR</displayName>
+               <description>control register</description>
+               <addressOffset>0x0</addressOffset>
+               <size>0x20</size>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>ALGODIR</name>
+                     <description>Algorithm direction</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>ALGOMODE0</name>
+                     <description>Algorithm mode</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>3</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>DATATYPE</name>
+                     <description>Data type selection</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>2</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>KEYSIZE</name>
+                     <description>Key size selection (AES mode               only)</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>2</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>FFLUSH</name>
+                     <description>FIFO flush</description>
+                     <bitOffset>14</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>write-only</access>
+                  </field>
+                  <field>
+                     <name>CRYPEN</name>
+                     <description>Cryptographic processor               enable</description>
+                     <bitOffset>15</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>GCM_CCMPH</name>
+                     <description>GCM_CCMPH</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>2</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>ALGOMODE3</name>
+                     <description>ALGOMODE</description>
+                     <bitOffset>19</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>SR</name>
+               <displayName>SR</displayName>
+               <description>status register</description>
+               <addressOffset>0x4</addressOffset>
+               <size>0x20</size>
+               <access>read-only</access>
+               <resetValue>0x00000003</resetValue>
+               <fields>
+                  <field>
+                     <name>BUSY</name>
+                     <description>Busy bit</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>OFFU</name>
+                     <description>Output FIFO full</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>OFNE</name>
+                     <description>Output FIFO not empty</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>IFNF</name>
+                     <description>Input FIFO not full</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>IFEM</name>
+                     <description>Input FIFO empty</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DIN</name>
+               <displayName>DIN</displayName>
+               <description>data input register</description>
+               <addressOffset>0x8</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DATAIN</name>
+                     <description>Data input</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DOUT</name>
+               <displayName>DOUT</displayName>
+               <description>data output register</description>
+               <addressOffset>0xC</addressOffset>
+               <size>0x20</size>
+               <access>read-only</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DATAOUT</name>
+                     <description>Data output</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DMACR</name>
+               <displayName>DMACR</displayName>
+               <description>DMA control register</description>
+               <addressOffset>0x10</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DOEN</name>
+                     <description>DMA output enable</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>DIEN</name>
+                     <description>DMA input enable</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>IMSCR</name>
+               <displayName>IMSCR</displayName>
+               <description>interrupt mask set/clear           register</description>
+               <addressOffset>0x14</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>OUTIM</name>
+                     <description>Output FIFO service interrupt               mask</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>INIM</name>
+                     <description>Input FIFO service interrupt               mask</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>RISR</name>
+               <displayName>RISR</displayName>
+               <description>raw interrupt status register</description>
+               <addressOffset>0x18</addressOffset>
+               <size>0x20</size>
+               <access>read-only</access>
+               <resetValue>0x00000001</resetValue>
+               <fields>
+                  <field>
+                     <name>OUTRIS</name>
+                     <description>Output FIFO service raw interrupt               status</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>INRIS</name>
+                     <description>Input FIFO service raw interrupt               status</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>MISR</name>
+               <displayName>MISR</displayName>
+               <description>masked interrupt status           register</description>
+               <addressOffset>0x1C</addressOffset>
+               <size>0x20</size>
+               <access>read-only</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>OUTMIS</name>
+                     <description>Output FIFO service masked interrupt               status</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>INMIS</name>
+                     <description>Input FIFO service masked interrupt               status</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>K0LR</name>
+               <displayName>K0LR</displayName>
+               <description>key registers</description>
+               <addressOffset>0x20</addressOffset>
+               <size>0x20</size>
+               <access>write-only</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>b224</name>
+                     <description>b224</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>b225</name>
+                     <description>b225</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>b226</name>
+                     <description>b226</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>b227</name>
+                     <description>b227</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>b228</name>
+                     <description>b228</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>b229</name>
+                     <description>b229</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>b230</name>
+                     <description>b230</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>b231</name>
+                     <description>b231</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>b232</name>
+                     <description>b232</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>b233</name>
+                     <description>b233</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>b234</name>
+                     <description>b234</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>b235</name>
+                     <description>b235</description>
+                     <bitOffset>11</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>b236</name>
+                     <description>b236</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>b237</name>
+                     <description>b237</description>
+                     <bitOffset>13</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>b238</name>
+                     <description>b238</description>
+                     <bitOffset>14</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>b239</name>
+                     <description>b239</description>
+                     <bitOffset>15</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>b240</name>
+                     <description>b240</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>b241</name>
+                     <description>b241</description>
+                     <bitOffset>17</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>b242</name>
+                     <description>b242</description>
+                     <bitOffset>18</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>b243</name>
+                     <description>b243</description>
+                     <bitOffset>19</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>b244</name>
+                     <description>b244</description>
+                     <bitOffset>20</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>b245</name>
+                     <description>b245</description>
+                     <bitOffset>21</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>b246</name>
+                     <description>b246</description>
+                     <bitOffset>22</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>b247</name>
+                     <description>b247</description>
+                     <bitOffset>23</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>b248</name>
+                     <description>b248</description>
+                     <bitOffset>24</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>b249</name>
+                     <description>b249</description>
+                     <bitOffset>25</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>b250</name>
+                     <description>b250</description>
+                     <bitOffset>26</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>b251</name>
+                     <description>b251</description>
+                     <bitOffset>27</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>b252</name>
+                     <description>b252</description>
+                     <bitOffset>28</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>b253</name>
+                     <description>b253</description>
+                     <bitOffset>29</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>b254</name>
+                     <description>b254</description>
+                     <bitOffset>30</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>b255</name>
+                     <description>b255</description>
+                     <bitOffset>31</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>K0RR</name>
+               <displayName>K0RR</displayName>
+               <description>key registers</description>
+               <addressOffset>0x24</addressOffset>
+               <size>0x20</size>
+               <access>write-only</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>b192</name>
+                     <description>b192</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>b193</name>
+                     <description>b193</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>b194</name>
+                     <description>b194</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>b195</name>
+                     <description>b195</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>b196</name>
+                     <description>b196</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>b197</name>
+                     <description>b197</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>b198</name>
+                     <description>b198</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>b199</name>
+                     <description>b199</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>b200</name>
+                     <description>b200</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>b201</name>
+                     <description>b201</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>b202</name>
+                     <description>b202</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>b203</name>
+                     <description>b203</description>
+                     <bitOffset>11</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>b204</name>
+                     <description>b204</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>b205</name>
+                     <description>b205</description>
+                     <bitOffset>13</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>b206</name>
+                     <description>b206</description>
+                     <bitOffset>14</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>b207</name>
+                     <description>b207</description>
+                     <bitOffset>15</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>b208</name>
+                     <description>b208</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>b209</name>
+                     <description>b209</description>
+                     <bitOffset>17</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>b210</name>
+                     <description>b210</description>
+                     <bitOffset>18</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>b211</name>
+                     <description>b211</description>
+                     <bitOffset>19</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>b212</name>
+                     <description>b212</description>
+                     <bitOffset>20</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>b213</name>
+                     <description>b213</description>
+                     <bitOffset>21</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>b214</name>
+                     <description>b214</description>
+                     <bitOffset>22</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>b215</name>
+                     <description>b215</description>
+                     <bitOffset>23</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>b216</name>
+                     <description>b216</description>
+                     <bitOffset>24</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>b217</name>
+                     <description>b217</description>
+                     <bitOffset>25</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>b218</name>
+                     <description>b218</description>
+                     <bitOffset>26</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>b219</name>
+                     <description>b219</description>
+                     <bitOffset>27</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>b220</name>
+                     <description>b220</description>
+                     <bitOffset>28</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>b221</name>
+                     <description>b221</description>
+                     <bitOffset>29</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>b222</name>
+                     <description>b222</description>
+                     <bitOffset>30</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>b223</name>
+                     <description>b223</description>
+                     <bitOffset>31</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>K1LR</name>
+               <displayName>K1LR</displayName>
+               <description>key registers</description>
+               <addressOffset>0x28</addressOffset>
+               <size>0x20</size>
+               <access>write-only</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>b160</name>
+                     <description>b160</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>b161</name>
+                     <description>b161</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>b162</name>
+                     <description>b162</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>b163</name>
+                     <description>b163</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>b164</name>
+                     <description>b164</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>b165</name>
+                     <description>b165</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>b166</name>
+                     <description>b166</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>b167</name>
+                     <description>b167</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>b168</name>
+                     <description>b168</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>b169</name>
+                     <description>b169</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>b170</name>
+                     <description>b170</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>b171</name>
+                     <description>b171</description>
+                     <bitOffset>11</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>b172</name>
+                     <description>b172</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>b173</name>
+                     <description>b173</description>
+                     <bitOffset>13</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>b174</name>
+                     <description>b174</description>
+                     <bitOffset>14</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>b175</name>
+                     <description>b175</description>
+                     <bitOffset>15</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>b176</name>
+                     <description>b176</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>b177</name>
+                     <description>b177</description>
+                     <bitOffset>17</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>b178</name>
+                     <description>b178</description>
+                     <bitOffset>18</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>b179</name>
+                     <description>b179</description>
+                     <bitOffset>19</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>b180</name>
+                     <description>b180</description>
+                     <bitOffset>20</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>b181</name>
+                     <description>b181</description>
+                     <bitOffset>21</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>b182</name>
+                     <description>b182</description>
+                     <bitOffset>22</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>b183</name>
+                     <description>b183</description>
+                     <bitOffset>23</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>b184</name>
+                     <description>b184</description>
+                     <bitOffset>24</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>b185</name>
+                     <description>b185</description>
+                     <bitOffset>25</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>b186</name>
+                     <description>b186</description>
+                     <bitOffset>26</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>b187</name>
+                     <description>b187</description>
+                     <bitOffset>27</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>b188</name>
+                     <description>b188</description>
+                     <bitOffset>28</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>b189</name>
+                     <description>b189</description>
+                     <bitOffset>29</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>b190</name>
+                     <description>b190</description>
+                     <bitOffset>30</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>b191</name>
+                     <description>b191</description>
+                     <bitOffset>31</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>K1RR</name>
+               <displayName>K1RR</displayName>
+               <description>key registers</description>
+               <addressOffset>0x2C</addressOffset>
+               <size>0x20</size>
+               <access>write-only</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>b128</name>
+                     <description>b128</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>b129</name>
+                     <description>b129</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>b130</name>
+                     <description>b130</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>b131</name>
+                     <description>b131</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>b132</name>
+                     <description>b132</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>b133</name>
+                     <description>b133</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>b134</name>
+                     <description>b134</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>b135</name>
+                     <description>b135</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>b136</name>
+                     <description>b136</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>b137</name>
+                     <description>b137</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>b138</name>
+                     <description>b138</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>b139</name>
+                     <description>b139</description>
+                     <bitOffset>11</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>b140</name>
+                     <description>b140</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>b141</name>
+                     <description>b141</description>
+                     <bitOffset>13</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>b142</name>
+                     <description>b142</description>
+                     <bitOffset>14</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>b143</name>
+                     <description>b143</description>
+                     <bitOffset>15</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>b144</name>
+                     <description>b144</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>b145</name>
+                     <description>b145</description>
+                     <bitOffset>17</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>b146</name>
+                     <description>b146</description>
+                     <bitOffset>18</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>b147</name>
+                     <description>b147</description>
+                     <bitOffset>19</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>b148</name>
+                     <description>b148</description>
+                     <bitOffset>20</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>b149</name>
+                     <description>b149</description>
+                     <bitOffset>21</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>b150</name>
+                     <description>b150</description>
+                     <bitOffset>22</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>b151</name>
+                     <description>b151</description>
+                     <bitOffset>23</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>b152</name>
+                     <description>b152</description>
+                     <bitOffset>24</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>b153</name>
+                     <description>b153</description>
+                     <bitOffset>25</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>b154</name>
+                     <description>b154</description>
+                     <bitOffset>26</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>b155</name>
+                     <description>b155</description>
+                     <bitOffset>27</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>b156</name>
+                     <description>b156</description>
+                     <bitOffset>28</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>b157</name>
+                     <description>b157</description>
+                     <bitOffset>29</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>b158</name>
+                     <description>b158</description>
+                     <bitOffset>30</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>b159</name>
+                     <description>b159</description>
+                     <bitOffset>31</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>K2LR</name>
+               <displayName>K2LR</displayName>
+               <description>key registers</description>
+               <addressOffset>0x30</addressOffset>
+               <size>0x20</size>
+               <access>write-only</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>b96</name>
+                     <description>b96</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>b97</name>
+                     <description>b97</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>b98</name>
+                     <description>b98</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>b99</name>
+                     <description>b99</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>b100</name>
+                     <description>b100</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>b101</name>
+                     <description>b101</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>b102</name>
+                     <description>b102</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>b103</name>
+                     <description>b103</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>b104</name>
+                     <description>b104</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>b105</name>
+                     <description>b105</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>b106</name>
+                     <description>b106</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>b107</name>
+                     <description>b107</description>
+                     <bitOffset>11</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>b108</name>
+                     <description>b108</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>b109</name>
+                     <description>b109</description>
+                     <bitOffset>13</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>b110</name>
+                     <description>b110</description>
+                     <bitOffset>14</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>b111</name>
+                     <description>b111</description>
+                     <bitOffset>15</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>b112</name>
+                     <description>b112</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>b113</name>
+                     <description>b113</description>
+                     <bitOffset>17</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>b114</name>
+                     <description>b114</description>
+                     <bitOffset>18</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>b115</name>
+                     <description>b115</description>
+                     <bitOffset>19</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>b116</name>
+                     <description>b116</description>
+                     <bitOffset>20</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>b117</name>
+                     <description>b117</description>
+                     <bitOffset>21</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>b118</name>
+                     <description>b118</description>
+                     <bitOffset>22</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>b119</name>
+                     <description>b119</description>
+                     <bitOffset>23</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>b120</name>
+                     <description>b120</description>
+                     <bitOffset>24</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>b121</name>
+                     <description>b121</description>
+                     <bitOffset>25</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>b122</name>
+                     <description>b122</description>
+                     <bitOffset>26</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>b123</name>
+                     <description>b123</description>
+                     <bitOffset>27</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>b124</name>
+                     <description>b124</description>
+                     <bitOffset>28</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>b125</name>
+                     <description>b125</description>
+                     <bitOffset>29</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>b126</name>
+                     <description>b126</description>
+                     <bitOffset>30</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>b127</name>
+                     <description>b127</description>
+                     <bitOffset>31</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>K2RR</name>
+               <displayName>K2RR</displayName>
+               <description>key registers</description>
+               <addressOffset>0x34</addressOffset>
+               <size>0x20</size>
+               <access>write-only</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>b64</name>
+                     <description>b64</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>b65</name>
+                     <description>b65</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>b66</name>
+                     <description>b66</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>b67</name>
+                     <description>b67</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>b68</name>
+                     <description>b68</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>b69</name>
+                     <description>b69</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>b70</name>
+                     <description>b70</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>b71</name>
+                     <description>b71</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>b72</name>
+                     <description>b72</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>b73</name>
+                     <description>b73</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>b74</name>
+                     <description>b74</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>b75</name>
+                     <description>b75</description>
+                     <bitOffset>11</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>b76</name>
+                     <description>b76</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>b77</name>
+                     <description>b77</description>
+                     <bitOffset>13</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>b78</name>
+                     <description>b78</description>
+                     <bitOffset>14</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>b79</name>
+                     <description>b79</description>
+                     <bitOffset>15</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>b80</name>
+                     <description>b80</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>b81</name>
+                     <description>b81</description>
+                     <bitOffset>17</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>b82</name>
+                     <description>b82</description>
+                     <bitOffset>18</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>b83</name>
+                     <description>b83</description>
+                     <bitOffset>19</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>b84</name>
+                     <description>b84</description>
+                     <bitOffset>20</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>b85</name>
+                     <description>b85</description>
+                     <bitOffset>21</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>b86</name>
+                     <description>b86</description>
+                     <bitOffset>22</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>b87</name>
+                     <description>b87</description>
+                     <bitOffset>23</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>b88</name>
+                     <description>b88</description>
+                     <bitOffset>24</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>b89</name>
+                     <description>b89</description>
+                     <bitOffset>25</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>b90</name>
+                     <description>b90</description>
+                     <bitOffset>26</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>b91</name>
+                     <description>b91</description>
+                     <bitOffset>27</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>b92</name>
+                     <description>b92</description>
+                     <bitOffset>28</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>b93</name>
+                     <description>b93</description>
+                     <bitOffset>29</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>b94</name>
+                     <description>b94</description>
+                     <bitOffset>30</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>b95</name>
+                     <description>b95</description>
+                     <bitOffset>31</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>K3LR</name>
+               <displayName>K3LR</displayName>
+               <description>key registers</description>
+               <addressOffset>0x38</addressOffset>
+               <size>0x20</size>
+               <access>write-only</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>b32</name>
+                     <description>b32</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>b33</name>
+                     <description>b33</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>b34</name>
+                     <description>b34</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>b35</name>
+                     <description>b35</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>b36</name>
+                     <description>b36</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>b37</name>
+                     <description>b37</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>b38</name>
+                     <description>b38</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>b39</name>
+                     <description>b39</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>b40</name>
+                     <description>b40</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>b41</name>
+                     <description>b41</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>b42</name>
+                     <description>b42</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>b43</name>
+                     <description>b43</description>
+                     <bitOffset>11</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>b44</name>
+                     <description>b44</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>b45</name>
+                     <description>b45</description>
+                     <bitOffset>13</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>b46</name>
+                     <description>b46</description>
+                     <bitOffset>14</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>b47</name>
+                     <description>b47</description>
+                     <bitOffset>15</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>b48</name>
+                     <description>b48</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>b49</name>
+                     <description>b49</description>
+                     <bitOffset>17</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>b50</name>
+                     <description>b50</description>
+                     <bitOffset>18</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>b51</name>
+                     <description>b51</description>
+                     <bitOffset>19</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>b52</name>
+                     <description>b52</description>
+                     <bitOffset>20</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>b53</name>
+                     <description>b53</description>
+                     <bitOffset>21</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>b54</name>
+                     <description>b54</description>
+                     <bitOffset>22</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>b55</name>
+                     <description>b55</description>
+                     <bitOffset>23</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>b56</name>
+                     <description>b56</description>
+                     <bitOffset>24</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>b57</name>
+                     <description>b57</description>
+                     <bitOffset>25</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>b58</name>
+                     <description>b58</description>
+                     <bitOffset>26</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>b59</name>
+                     <description>b59</description>
+                     <bitOffset>27</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>b60</name>
+                     <description>b60</description>
+                     <bitOffset>28</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>b61</name>
+                     <description>b61</description>
+                     <bitOffset>29</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>b62</name>
+                     <description>b62</description>
+                     <bitOffset>30</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>b63</name>
+                     <description>b63</description>
+                     <bitOffset>31</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>K3RR</name>
+               <displayName>K3RR</displayName>
+               <description>key registers</description>
+               <addressOffset>0x3C</addressOffset>
+               <size>0x20</size>
+               <access>write-only</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>b0</name>
+                     <description>b0</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>b1</name>
+                     <description>b1</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>b2</name>
+                     <description>b2</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>b3</name>
+                     <description>b3</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>b4</name>
+                     <description>b4</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>b5</name>
+                     <description>b5</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>b6</name>
+                     <description>b6</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>b7</name>
+                     <description>b7</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>b8</name>
+                     <description>b8</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>b9</name>
+                     <description>b9</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>b10</name>
+                     <description>b10</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>b11</name>
+                     <description>b11</description>
+                     <bitOffset>11</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>b12</name>
+                     <description>b12</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>b13</name>
+                     <description>b13</description>
+                     <bitOffset>13</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>b14</name>
+                     <description>b14</description>
+                     <bitOffset>14</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>b15</name>
+                     <description>b15</description>
+                     <bitOffset>15</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>b16</name>
+                     <description>b16</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>b17</name>
+                     <description>b17</description>
+                     <bitOffset>17</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>b18</name>
+                     <description>b18</description>
+                     <bitOffset>18</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>b19</name>
+                     <description>b19</description>
+                     <bitOffset>19</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>b20</name>
+                     <description>b20</description>
+                     <bitOffset>20</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>b21</name>
+                     <description>b21</description>
+                     <bitOffset>21</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>b22</name>
+                     <description>b22</description>
+                     <bitOffset>22</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>b23</name>
+                     <description>b23</description>
+                     <bitOffset>23</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>b24</name>
+                     <description>b24</description>
+                     <bitOffset>24</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>b25</name>
+                     <description>b25</description>
+                     <bitOffset>25</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>b26</name>
+                     <description>b26</description>
+                     <bitOffset>26</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>b27</name>
+                     <description>b27</description>
+                     <bitOffset>27</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>b28</name>
+                     <description>b28</description>
+                     <bitOffset>28</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>b29</name>
+                     <description>b29</description>
+                     <bitOffset>29</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>b30</name>
+                     <description>b30</description>
+                     <bitOffset>30</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>b31</name>
+                     <description>b31</description>
+                     <bitOffset>31</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>IV0LR</name>
+               <displayName>IV0LR</displayName>
+               <description>initialization vector           registers</description>
+               <addressOffset>0x40</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>IV31</name>
+                     <description>IV31</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>IV30</name>
+                     <description>IV30</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>IV29</name>
+                     <description>IV29</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>IV28</name>
+                     <description>IV28</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>IV27</name>
+                     <description>IV27</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>IV26</name>
+                     <description>IV26</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>IV25</name>
+                     <description>IV25</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>IV24</name>
+                     <description>IV24</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>IV23</name>
+                     <description>IV23</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>IV22</name>
+                     <description>IV22</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>IV21</name>
+                     <description>IV21</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>IV20</name>
+                     <description>IV20</description>
+                     <bitOffset>11</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>IV19</name>
+                     <description>IV19</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>IV18</name>
+                     <description>IV18</description>
+                     <bitOffset>13</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>IV17</name>
+                     <description>IV17</description>
+                     <bitOffset>14</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>IV16</name>
+                     <description>IV16</description>
+                     <bitOffset>15</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>IV15</name>
+                     <description>IV15</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>IV14</name>
+                     <description>IV14</description>
+                     <bitOffset>17</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>IV13</name>
+                     <description>IV13</description>
+                     <bitOffset>18</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>IV12</name>
+                     <description>IV12</description>
+                     <bitOffset>19</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>IV11</name>
+                     <description>IV11</description>
+                     <bitOffset>20</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>IV10</name>
+                     <description>IV10</description>
+                     <bitOffset>21</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>IV9</name>
+                     <description>IV9</description>
+                     <bitOffset>22</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>IV8</name>
+                     <description>IV8</description>
+                     <bitOffset>23</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>IV7</name>
+                     <description>IV7</description>
+                     <bitOffset>24</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>IV6</name>
+                     <description>IV6</description>
+                     <bitOffset>25</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>IV5</name>
+                     <description>IV5</description>
+                     <bitOffset>26</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>IV4</name>
+                     <description>IV4</description>
+                     <bitOffset>27</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>IV3</name>
+                     <description>IV3</description>
+                     <bitOffset>28</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>IV2</name>
+                     <description>IV2</description>
+                     <bitOffset>29</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>IV1</name>
+                     <description>IV1</description>
+                     <bitOffset>30</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>IV0</name>
+                     <description>IV0</description>
+                     <bitOffset>31</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>IV0RR</name>
+               <displayName>IV0RR</displayName>
+               <description>initialization vector           registers</description>
+               <addressOffset>0x44</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>IV63</name>
+                     <description>IV63</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>IV62</name>
+                     <description>IV62</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>IV61</name>
+                     <description>IV61</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>IV60</name>
+                     <description>IV60</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>IV59</name>
+                     <description>IV59</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>IV58</name>
+                     <description>IV58</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>IV57</name>
+                     <description>IV57</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>IV56</name>
+                     <description>IV56</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>IV55</name>
+                     <description>IV55</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>IV54</name>
+                     <description>IV54</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>IV53</name>
+                     <description>IV53</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>IV52</name>
+                     <description>IV52</description>
+                     <bitOffset>11</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>IV51</name>
+                     <description>IV51</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>IV50</name>
+                     <description>IV50</description>
+                     <bitOffset>13</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>IV49</name>
+                     <description>IV49</description>
+                     <bitOffset>14</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>IV48</name>
+                     <description>IV48</description>
+                     <bitOffset>15</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>IV47</name>
+                     <description>IV47</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>IV46</name>
+                     <description>IV46</description>
+                     <bitOffset>17</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>IV45</name>
+                     <description>IV45</description>
+                     <bitOffset>18</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>IV44</name>
+                     <description>IV44</description>
+                     <bitOffset>19</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>IV43</name>
+                     <description>IV43</description>
+                     <bitOffset>20</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>IV42</name>
+                     <description>IV42</description>
+                     <bitOffset>21</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>IV41</name>
+                     <description>IV41</description>
+                     <bitOffset>22</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>IV40</name>
+                     <description>IV40</description>
+                     <bitOffset>23</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>IV39</name>
+                     <description>IV39</description>
+                     <bitOffset>24</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>IV38</name>
+                     <description>IV38</description>
+                     <bitOffset>25</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>IV37</name>
+                     <description>IV37</description>
+                     <bitOffset>26</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>IV36</name>
+                     <description>IV36</description>
+                     <bitOffset>27</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>IV35</name>
+                     <description>IV35</description>
+                     <bitOffset>28</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>IV34</name>
+                     <description>IV34</description>
+                     <bitOffset>29</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>IV33</name>
+                     <description>IV33</description>
+                     <bitOffset>30</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>IV32</name>
+                     <description>IV32</description>
+                     <bitOffset>31</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>IV1LR</name>
+               <displayName>IV1LR</displayName>
+               <description>initialization vector           registers</description>
+               <addressOffset>0x48</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>IV95</name>
+                     <description>IV95</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>IV94</name>
+                     <description>IV94</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>IV93</name>
+                     <description>IV93</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>IV92</name>
+                     <description>IV92</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>IV91</name>
+                     <description>IV91</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>IV90</name>
+                     <description>IV90</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>IV89</name>
+                     <description>IV89</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>IV88</name>
+                     <description>IV88</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>IV87</name>
+                     <description>IV87</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>IV86</name>
+                     <description>IV86</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>IV85</name>
+                     <description>IV85</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>IV84</name>
+                     <description>IV84</description>
+                     <bitOffset>11</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>IV83</name>
+                     <description>IV83</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>IV82</name>
+                     <description>IV82</description>
+                     <bitOffset>13</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>IV81</name>
+                     <description>IV81</description>
+                     <bitOffset>14</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>IV80</name>
+                     <description>IV80</description>
+                     <bitOffset>15</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>IV79</name>
+                     <description>IV79</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>IV78</name>
+                     <description>IV78</description>
+                     <bitOffset>17</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>IV77</name>
+                     <description>IV77</description>
+                     <bitOffset>18</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>IV76</name>
+                     <description>IV76</description>
+                     <bitOffset>19</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>IV75</name>
+                     <description>IV75</description>
+                     <bitOffset>20</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>IV74</name>
+                     <description>IV74</description>
+                     <bitOffset>21</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>IV73</name>
+                     <description>IV73</description>
+                     <bitOffset>22</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>IV72</name>
+                     <description>IV72</description>
+                     <bitOffset>23</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>IV71</name>
+                     <description>IV71</description>
+                     <bitOffset>24</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>IV70</name>
+                     <description>IV70</description>
+                     <bitOffset>25</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>IV69</name>
+                     <description>IV69</description>
+                     <bitOffset>26</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>IV68</name>
+                     <description>IV68</description>
+                     <bitOffset>27</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>IV67</name>
+                     <description>IV67</description>
+                     <bitOffset>28</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>IV66</name>
+                     <description>IV66</description>
+                     <bitOffset>29</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>IV65</name>
+                     <description>IV65</description>
+                     <bitOffset>30</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>IV64</name>
+                     <description>IV64</description>
+                     <bitOffset>31</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>IV1RR</name>
+               <displayName>IV1RR</displayName>
+               <description>initialization vector           registers</description>
+               <addressOffset>0x4C</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>IV127</name>
+                     <description>IV127</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>IV126</name>
+                     <description>IV126</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>IV125</name>
+                     <description>IV125</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>IV124</name>
+                     <description>IV124</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>IV123</name>
+                     <description>IV123</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>IV122</name>
+                     <description>IV122</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>IV121</name>
+                     <description>IV121</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>IV120</name>
+                     <description>IV120</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>IV119</name>
+                     <description>IV119</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>IV118</name>
+                     <description>IV118</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>IV117</name>
+                     <description>IV117</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>IV116</name>
+                     <description>IV116</description>
+                     <bitOffset>11</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>IV115</name>
+                     <description>IV115</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>IV114</name>
+                     <description>IV114</description>
+                     <bitOffset>13</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>IV113</name>
+                     <description>IV113</description>
+                     <bitOffset>14</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>IV112</name>
+                     <description>IV112</description>
+                     <bitOffset>15</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>IV111</name>
+                     <description>IV111</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>IV110</name>
+                     <description>IV110</description>
+                     <bitOffset>17</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>IV109</name>
+                     <description>IV109</description>
+                     <bitOffset>18</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>IV108</name>
+                     <description>IV108</description>
+                     <bitOffset>19</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>IV107</name>
+                     <description>IV107</description>
+                     <bitOffset>20</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>IV106</name>
+                     <description>IV106</description>
+                     <bitOffset>21</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>IV105</name>
+                     <description>IV105</description>
+                     <bitOffset>22</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>IV104</name>
+                     <description>IV104</description>
+                     <bitOffset>23</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>IV103</name>
+                     <description>IV103</description>
+                     <bitOffset>24</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>IV102</name>
+                     <description>IV102</description>
+                     <bitOffset>25</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>IV101</name>
+                     <description>IV101</description>
+                     <bitOffset>26</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>IV100</name>
+                     <description>IV100</description>
+                     <bitOffset>27</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>IV99</name>
+                     <description>IV99</description>
+                     <bitOffset>28</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>IV98</name>
+                     <description>IV98</description>
+                     <bitOffset>29</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>IV97</name>
+                     <description>IV97</description>
+                     <bitOffset>30</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>IV96</name>
+                     <description>IV96</description>
+                     <bitOffset>31</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>CSGCMCCM0R</name>
+               <displayName>CSGCMCCM0R</displayName>
+               <description>context swap register</description>
+               <addressOffset>0x50</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>CSGCMCCM0R</name>
+                     <description>CSGCMCCM0R</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>CSGCMCCM1R</name>
+               <displayName>CSGCMCCM1R</displayName>
+               <description>context swap register</description>
+               <addressOffset>0x54</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>CSGCMCCM1R</name>
+                     <description>CSGCMCCM1R</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>CSGCMCCM2R</name>
+               <displayName>CSGCMCCM2R</displayName>
+               <description>context swap register</description>
+               <addressOffset>0x58</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>CSGCMCCM2R</name>
+                     <description>CSGCMCCM2R</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>CSGCMCCM3R</name>
+               <displayName>CSGCMCCM3R</displayName>
+               <description>context swap register</description>
+               <addressOffset>0x5C</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>CSGCMCCM3R</name>
+                     <description>CSGCMCCM3R</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>CSGCMCCM4R</name>
+               <displayName>CSGCMCCM4R</displayName>
+               <description>context swap register</description>
+               <addressOffset>0x60</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>CSGCMCCM4R</name>
+                     <description>CSGCMCCM4R</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>CSGCMCCM5R</name>
+               <displayName>CSGCMCCM5R</displayName>
+               <description>context swap register</description>
+               <addressOffset>0x64</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>CSGCMCCM5R</name>
+                     <description>CSGCMCCM5R</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>CSGCMCCM6R</name>
+               <displayName>CSGCMCCM6R</displayName>
+               <description>context swap register</description>
+               <addressOffset>0x68</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>CSGCMCCM6R</name>
+                     <description>CSGCMCCM6R</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>CSGCMCCM7R</name>
+               <displayName>CSGCMCCM7R</displayName>
+               <description>context swap register</description>
+               <addressOffset>0x6C</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>CSGCMCCM7R</name>
+                     <description>CSGCMCCM7R</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>CSGCM0R</name>
+               <displayName>CSGCM0R</displayName>
+               <description>context swap register</description>
+               <addressOffset>0x70</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>CSGCM0R</name>
+                     <description>CSGCM0R</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>CSGCM1R</name>
+               <displayName>CSGCM1R</displayName>
+               <description>context swap register</description>
+               <addressOffset>0x74</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>CSGCM1R</name>
+                     <description>CSGCM1R</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>CSGCM2R</name>
+               <displayName>CSGCM2R</displayName>
+               <description>context swap register</description>
+               <addressOffset>0x78</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>CSGCM2R</name>
+                     <description>CSGCM2R</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>CSGCM3R</name>
+               <displayName>CSGCM3R</displayName>
+               <description>context swap register</description>
+               <addressOffset>0x7C</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>CSGCM3R</name>
+                     <description>CSGCM3R</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>CSGCM4R</name>
+               <displayName>CSGCM4R</displayName>
+               <description>context swap register</description>
+               <addressOffset>0x80</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>CSGCM4R</name>
+                     <description>CSGCM4R</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>CSGCM5R</name>
+               <displayName>CSGCM5R</displayName>
+               <description>context swap register</description>
+               <addressOffset>0x84</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>CSGCM5R</name>
+                     <description>CSGCM5R</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>CSGCM6R</name>
+               <displayName>CSGCM6R</displayName>
+               <description>context swap register</description>
+               <addressOffset>0x88</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>CSGCM6R</name>
+                     <description>CSGCM6R</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>CSGCM7R</name>
+               <displayName>CSGCM7R</displayName>
+               <description>context swap register</description>
+               <addressOffset>0x8C</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>CSGCM7R</name>
+                     <description>CSGCM7R</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+         </registers>
+      </peripheral>
+      <peripheral>
+         <name>DCMI</name>
+         <description>Digital camera interface</description>
+         <groupName>DCMI</groupName>
+         <baseAddress>0x50050000</baseAddress>
+         <addressBlock>
+            <offset>0x0</offset>
+            <size>0x400</size>
+            <usage>registers</usage>
+         </addressBlock>
+         <interrupt>
+            <name>DCMI</name>
+            <description>DCMI global interrupt</description>
+            <value>78</value>
+         </interrupt>
+         <registers>
+            <register>
+               <name>CR</name>
+               <displayName>CR</displayName>
+               <description>control register 1</description>
+               <addressOffset>0x0</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x0000</resetValue>
+               <fields>
+                  <field>
+                     <name>ENABLE</name>
+                     <description>DCMI enable</description>
+                     <bitOffset>14</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>EDM</name>
+                     <description>Extended data mode</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>FCRC</name>
+                     <description>Frame capture rate control</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>VSPOL</name>
+                     <description>Vertical synchronization               polarity</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>HSPOL</name>
+                     <description>Horizontal synchronization               polarity</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>PCKPOL</name>
+                     <description>Pixel clock polarity</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>ESS</name>
+                     <description>Embedded synchronization               select</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>JPEG</name>
+                     <description>JPEG format</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CROP</name>
+                     <description>Crop feature</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CM</name>
+                     <description>Capture mode</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CAPTURE</name>
+                     <description>Capture enable</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>SR</name>
+               <displayName>SR</displayName>
+               <description>status register</description>
+               <addressOffset>0x4</addressOffset>
+               <size>0x20</size>
+               <access>read-only</access>
+               <resetValue>0x0000</resetValue>
+               <fields>
+                  <field>
+                     <name>FNE</name>
+                     <description>FIFO not empty</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>VSYNC</name>
+                     <description>VSYNC</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>HSYNC</name>
+                     <description>HSYNC</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>RIS</name>
+               <displayName>RIS</displayName>
+               <description>raw interrupt status register</description>
+               <addressOffset>0x8</addressOffset>
+               <size>0x20</size>
+               <access>read-only</access>
+               <resetValue>0x0000</resetValue>
+               <fields>
+                  <field>
+                     <name>LINE_RIS</name>
+                     <description>Line raw interrupt status</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>VSYNC_RIS</name>
+                     <description>VSYNC raw interrupt status</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>ERR_RIS</name>
+                     <description>Synchronization error raw interrupt               status</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>OVR_RIS</name>
+                     <description>Overrun raw interrupt               status</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FRAME_RIS</name>
+                     <description>Capture complete raw interrupt               status</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>IER</name>
+               <displayName>IER</displayName>
+               <description>interrupt enable register</description>
+               <addressOffset>0xC</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x0000</resetValue>
+               <fields>
+                  <field>
+                     <name>LINE_IE</name>
+                     <description>Line interrupt enable</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>VSYNC_IE</name>
+                     <description>VSYNC interrupt enable</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>ERR_IE</name>
+                     <description>Synchronization error interrupt               enable</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>OVR_IE</name>
+                     <description>Overrun interrupt enable</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FRAME_IE</name>
+                     <description>Capture complete interrupt               enable</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>MIS</name>
+               <displayName>MIS</displayName>
+               <description>masked interrupt status           register</description>
+               <addressOffset>0x10</addressOffset>
+               <size>0x20</size>
+               <access>read-only</access>
+               <resetValue>0x0000</resetValue>
+               <fields>
+                  <field>
+                     <name>LINE_MIS</name>
+                     <description>Line masked interrupt               status</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>VSYNC_MIS</name>
+                     <description>VSYNC masked interrupt               status</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>ERR_MIS</name>
+                     <description>Synchronization error masked interrupt               status</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>OVR_MIS</name>
+                     <description>Overrun masked interrupt               status</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FRAME_MIS</name>
+                     <description>Capture complete masked interrupt               status</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>ICR</name>
+               <displayName>ICR</displayName>
+               <description>interrupt clear register</description>
+               <addressOffset>0x14</addressOffset>
+               <size>0x20</size>
+               <access>write-only</access>
+               <resetValue>0x0000</resetValue>
+               <fields>
+                  <field>
+                     <name>LINE_ISC</name>
+                     <description>line interrupt status               clear</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>VSYNC_ISC</name>
+                     <description>Vertical synch interrupt status               clear</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>ERR_ISC</name>
+                     <description>Synchronization error interrupt status               clear</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>OVR_ISC</name>
+                     <description>Overrun interrupt status               clear</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FRAME_ISC</name>
+                     <description>Capture complete interrupt status               clear</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>ESCR</name>
+               <displayName>ESCR</displayName>
+               <description>embedded synchronization code           register</description>
+               <addressOffset>0x18</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x0000</resetValue>
+               <fields>
+                  <field>
+                     <name>FEC</name>
+                     <description>Frame end delimiter code</description>
+                     <bitOffset>24</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+                  <field>
+                     <name>LEC</name>
+                     <description>Line end delimiter code</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+                  <field>
+                     <name>LSC</name>
+                     <description>Line start delimiter code</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+                  <field>
+                     <name>FSC</name>
+                     <description>Frame start delimiter code</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>ESUR</name>
+               <displayName>ESUR</displayName>
+               <description>embedded synchronization unmask           register</description>
+               <addressOffset>0x1C</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x0000</resetValue>
+               <fields>
+                  <field>
+                     <name>FEU</name>
+                     <description>Frame end delimiter unmask</description>
+                     <bitOffset>24</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+                  <field>
+                     <name>LEU</name>
+                     <description>Line end delimiter unmask</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+                  <field>
+                     <name>LSU</name>
+                     <description>Line start delimiter               unmask</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+                  <field>
+                     <name>FSU</name>
+                     <description>Frame start delimiter               unmask</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>CWSTRT</name>
+               <displayName>CWSTRT</displayName>
+               <description>crop window start</description>
+               <addressOffset>0x20</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x0000</resetValue>
+               <fields>
+                  <field>
+                     <name>VST</name>
+                     <description>Vertical start line count</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>13</bitWidth>
+                  </field>
+                  <field>
+                     <name>HOFFCNT</name>
+                     <description>Horizontal offset count</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>14</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>CWSIZE</name>
+               <displayName>CWSIZE</displayName>
+               <description>crop window size</description>
+               <addressOffset>0x24</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x0000</resetValue>
+               <fields>
+                  <field>
+                     <name>VLINE</name>
+                     <description>Vertical line count</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>14</bitWidth>
+                  </field>
+                  <field>
+                     <name>CAPCNT</name>
+                     <description>Capture count</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>14</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DR</name>
+               <displayName>DR</displayName>
+               <description>data register</description>
+               <addressOffset>0x28</addressOffset>
+               <size>0x20</size>
+               <access>read-only</access>
+               <resetValue>0x0000</resetValue>
+               <fields>
+                  <field>
+                     <name>Byte3</name>
+                     <description>Data byte 3</description>
+                     <bitOffset>24</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+                  <field>
+                     <name>Byte2</name>
+                     <description>Data byte 2</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+                  <field>
+                     <name>Byte1</name>
+                     <description>Data byte 1</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+                  <field>
+                     <name>Byte0</name>
+                     <description>Data byte 0</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+               </fields>
+            </register>
+         </registers>
+      </peripheral>
+      <peripheral>
+         <name>FMC</name>
+         <description>Flexible memory controller</description>
+         <groupName>FSMC</groupName>
+         <baseAddress>0xA0000000</baseAddress>
+         <addressBlock>
+            <offset>0x0</offset>
+            <size>0x1000</size>
+            <usage>registers</usage>
+         </addressBlock>
+         <interrupt>
+            <name>FMC</name>
+            <description>FMC global interrupt</description>
+            <value>48</value>
+         </interrupt>
+         <registers>
+            <register>
+               <name>BCR1</name>
+               <displayName>BCR1</displayName>
+               <description>SRAM/NOR-Flash chip-select control register           1</description>
+               <addressOffset>0x0</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x000030D0</resetValue>
+               <fields>
+                  <field>
+                     <name>CCLKEN</name>
+                     <description>CCLKEN</description>
+                     <bitOffset>20</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CBURSTRW</name>
+                     <description>CBURSTRW</description>
+                     <bitOffset>19</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>ASYNCWAIT</name>
+                     <description>ASYNCWAIT</description>
+                     <bitOffset>15</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>EXTMOD</name>
+                     <description>EXTMOD</description>
+                     <bitOffset>14</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>WAITEN</name>
+                     <description>WAITEN</description>
+                     <bitOffset>13</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>WREN</name>
+                     <description>WREN</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>WAITCFG</name>
+                     <description>WAITCFG</description>
+                     <bitOffset>11</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>WAITPOL</name>
+                     <description>WAITPOL</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>BURSTEN</name>
+                     <description>BURSTEN</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FACCEN</name>
+                     <description>FACCEN</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>MWID</name>
+                     <description>MWID</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>MTYP</name>
+                     <description>MTYP</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>MUXEN</name>
+                     <description>MUXEN</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>MBKEN</name>
+                     <description>MBKEN</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>BTR1</name>
+               <displayName>BTR1</displayName>
+               <description>SRAM/NOR-Flash chip-select timing register           1</description>
+               <addressOffset>0x4</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0xFFFFFFFF</resetValue>
+               <fields>
+                  <field>
+                     <name>ACCMOD</name>
+                     <description>ACCMOD</description>
+                     <bitOffset>28</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>DATLAT</name>
+                     <description>DATLAT</description>
+                     <bitOffset>24</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+                  <field>
+                     <name>CLKDIV</name>
+                     <description>CLKDIV</description>
+                     <bitOffset>20</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+                  <field>
+                     <name>BUSTURN</name>
+                     <description>BUSTURN</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+                  <field>
+                     <name>DATAST</name>
+                     <description>DATAST</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+                  <field>
+                     <name>ADDHLD</name>
+                     <description>ADDHLD</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+                  <field>
+                     <name>ADDSET</name>
+                     <description>ADDSET</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>BCR2</name>
+               <displayName>BCR2</displayName>
+               <description>SRAM/NOR-Flash chip-select control register           2</description>
+               <addressOffset>0x8</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x000030D0</resetValue>
+               <fields>
+                  <field>
+                     <name>CBURSTRW</name>
+                     <description>CBURSTRW</description>
+                     <bitOffset>19</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>ASYNCWAIT</name>
+                     <description>ASYNCWAIT</description>
+                     <bitOffset>15</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>EXTMOD</name>
+                     <description>EXTMOD</description>
+                     <bitOffset>14</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>WAITEN</name>
+                     <description>WAITEN</description>
+                     <bitOffset>13</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>WREN</name>
+                     <description>WREN</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>WAITCFG</name>
+                     <description>WAITCFG</description>
+                     <bitOffset>11</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>WRAPMOD</name>
+                     <description>WRAPMOD</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>WAITPOL</name>
+                     <description>WAITPOL</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>BURSTEN</name>
+                     <description>BURSTEN</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FACCEN</name>
+                     <description>FACCEN</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>MWID</name>
+                     <description>MWID</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>MTYP</name>
+                     <description>MTYP</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>MUXEN</name>
+                     <description>MUXEN</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>MBKEN</name>
+                     <description>MBKEN</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>BTR2</name>
+               <displayName>BTR2</displayName>
+               <description>SRAM/NOR-Flash chip-select timing register           2</description>
+               <addressOffset>0xC</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0xFFFFFFFF</resetValue>
+               <fields>
+                  <field>
+                     <name>ACCMOD</name>
+                     <description>ACCMOD</description>
+                     <bitOffset>28</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>DATLAT</name>
+                     <description>DATLAT</description>
+                     <bitOffset>24</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+                  <field>
+                     <name>CLKDIV</name>
+                     <description>CLKDIV</description>
+                     <bitOffset>20</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+                  <field>
+                     <name>BUSTURN</name>
+                     <description>BUSTURN</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+                  <field>
+                     <name>DATAST</name>
+                     <description>DATAST</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+                  <field>
+                     <name>ADDHLD</name>
+                     <description>ADDHLD</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+                  <field>
+                     <name>ADDSET</name>
+                     <description>ADDSET</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>BCR3</name>
+               <displayName>BCR3</displayName>
+               <description>SRAM/NOR-Flash chip-select control register           3</description>
+               <addressOffset>0x10</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x000030D0</resetValue>
+               <fields>
+                  <field>
+                     <name>CBURSTRW</name>
+                     <description>CBURSTRW</description>
+                     <bitOffset>19</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>ASYNCWAIT</name>
+                     <description>ASYNCWAIT</description>
+                     <bitOffset>15</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>EXTMOD</name>
+                     <description>EXTMOD</description>
+                     <bitOffset>14</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>WAITEN</name>
+                     <description>WAITEN</description>
+                     <bitOffset>13</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>WREN</name>
+                     <description>WREN</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>WAITCFG</name>
+                     <description>WAITCFG</description>
+                     <bitOffset>11</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>WRAPMOD</name>
+                     <description>WRAPMOD</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>WAITPOL</name>
+                     <description>WAITPOL</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>BURSTEN</name>
+                     <description>BURSTEN</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FACCEN</name>
+                     <description>FACCEN</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>MWID</name>
+                     <description>MWID</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>MTYP</name>
+                     <description>MTYP</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>MUXEN</name>
+                     <description>MUXEN</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>MBKEN</name>
+                     <description>MBKEN</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>BTR3</name>
+               <displayName>BTR3</displayName>
+               <description>SRAM/NOR-Flash chip-select timing register           3</description>
+               <addressOffset>0x14</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0xFFFFFFFF</resetValue>
+               <fields>
+                  <field>
+                     <name>ACCMOD</name>
+                     <description>ACCMOD</description>
+                     <bitOffset>28</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>DATLAT</name>
+                     <description>DATLAT</description>
+                     <bitOffset>24</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+                  <field>
+                     <name>CLKDIV</name>
+                     <description>CLKDIV</description>
+                     <bitOffset>20</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+                  <field>
+                     <name>BUSTURN</name>
+                     <description>BUSTURN</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+                  <field>
+                     <name>DATAST</name>
+                     <description>DATAST</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+                  <field>
+                     <name>ADDHLD</name>
+                     <description>ADDHLD</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+                  <field>
+                     <name>ADDSET</name>
+                     <description>ADDSET</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>BCR4</name>
+               <displayName>BCR4</displayName>
+               <description>SRAM/NOR-Flash chip-select control register           4</description>
+               <addressOffset>0x18</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x000030D0</resetValue>
+               <fields>
+                  <field>
+                     <name>CBURSTRW</name>
+                     <description>CBURSTRW</description>
+                     <bitOffset>19</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>ASYNCWAIT</name>
+                     <description>ASYNCWAIT</description>
+                     <bitOffset>15</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>EXTMOD</name>
+                     <description>EXTMOD</description>
+                     <bitOffset>14</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>WAITEN</name>
+                     <description>WAITEN</description>
+                     <bitOffset>13</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>WREN</name>
+                     <description>WREN</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>WAITCFG</name>
+                     <description>WAITCFG</description>
+                     <bitOffset>11</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>WRAPMOD</name>
+                     <description>WRAPMOD</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>WAITPOL</name>
+                     <description>WAITPOL</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>BURSTEN</name>
+                     <description>BURSTEN</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FACCEN</name>
+                     <description>FACCEN</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>MWID</name>
+                     <description>MWID</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>MTYP</name>
+                     <description>MTYP</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>MUXEN</name>
+                     <description>MUXEN</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>MBKEN</name>
+                     <description>MBKEN</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>BTR4</name>
+               <displayName>BTR4</displayName>
+               <description>SRAM/NOR-Flash chip-select timing register           4</description>
+               <addressOffset>0x1C</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0xFFFFFFFF</resetValue>
+               <fields>
+                  <field>
+                     <name>ACCMOD</name>
+                     <description>ACCMOD</description>
+                     <bitOffset>28</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>DATLAT</name>
+                     <description>DATLAT</description>
+                     <bitOffset>24</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+                  <field>
+                     <name>CLKDIV</name>
+                     <description>CLKDIV</description>
+                     <bitOffset>20</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+                  <field>
+                     <name>BUSTURN</name>
+                     <description>BUSTURN</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+                  <field>
+                     <name>DATAST</name>
+                     <description>DATAST</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+                  <field>
+                     <name>ADDHLD</name>
+                     <description>ADDHLD</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+                  <field>
+                     <name>ADDSET</name>
+                     <description>ADDSET</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>PCR</name>
+               <displayName>PCR</displayName>
+               <description>PC Card/NAND Flash control           register</description>
+               <addressOffset>0x80</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000018</resetValue>
+               <fields>
+                  <field>
+                     <name>ECCPS</name>
+                     <description>ECCPS</description>
+                     <bitOffset>17</bitOffset>
+                     <bitWidth>3</bitWidth>
+                  </field>
+                  <field>
+                     <name>TAR</name>
+                     <description>TAR</description>
+                     <bitOffset>13</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+                  <field>
+                     <name>TCLR</name>
+                     <description>TCLR</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+                  <field>
+                     <name>ECCEN</name>
+                     <description>ECCEN</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>PWID</name>
+                     <description>PWID</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>PTYP</name>
+                     <description>PTYP</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>PBKEN</name>
+                     <description>PBKEN</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>PWAITEN</name>
+                     <description>PWAITEN</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>SR</name>
+               <displayName>SR</displayName>
+               <description>FIFO status and interrupt           register</description>
+               <addressOffset>0x84</addressOffset>
+               <size>0x20</size>
+               <resetValue>0x00000040</resetValue>
+               <fields>
+                  <field>
+                     <name>FEMPT</name>
+                     <description>FEMPT</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-only</access>
+                  </field>
+                  <field>
+                     <name>IFEN</name>
+                     <description>IFEN</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>ILEN</name>
+                     <description>ILEN</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>IREN</name>
+                     <description>IREN</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>IFS</name>
+                     <description>IFS</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>ILS</name>
+                     <description>ILS</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>IRS</name>
+                     <description>IRS</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>PMEM</name>
+               <displayName>PMEM</displayName>
+               <description>Common memory space timing           register</description>
+               <addressOffset>0x88</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0xFCFCFCFC</resetValue>
+               <fields>
+                  <field>
+                     <name>MEMHIZx</name>
+                     <description>MEMHIZx</description>
+                     <bitOffset>24</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+                  <field>
+                     <name>MEMHOLDx</name>
+                     <description>MEMHOLDx</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+                  <field>
+                     <name>MEMWAITx</name>
+                     <description>MEMWAITx</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+                  <field>
+                     <name>MEMSETx</name>
+                     <description>MEMSETx</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>PATT</name>
+               <displayName>PATT</displayName>
+               <description>Attribute memory space timing           register</description>
+               <addressOffset>0x8C</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0xFCFCFCFC</resetValue>
+               <fields>
+                  <field>
+                     <name>ATTHIZx</name>
+                     <description>ATTHIZx</description>
+                     <bitOffset>24</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+                  <field>
+                     <name>ATTHOLDx</name>
+                     <description>ATTHOLDx</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+                  <field>
+                     <name>ATTWAITx</name>
+                     <description>ATTWAITx</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+                  <field>
+                     <name>ATTSETx</name>
+                     <description>ATTSETx</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>ECCR</name>
+               <displayName>ECCR</displayName>
+               <description>ECC result register</description>
+               <addressOffset>0x94</addressOffset>
+               <size>0x20</size>
+               <access>read-only</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>ECCx</name>
+                     <description>ECCx</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>BWTR1</name>
+               <displayName>BWTR1</displayName>
+               <description>SRAM/NOR-Flash write timing registers           1</description>
+               <addressOffset>0x104</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x0FFFFFFF</resetValue>
+               <fields>
+                  <field>
+                     <name>ACCMOD</name>
+                     <description>ACCMOD</description>
+                     <bitOffset>28</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>DATLAT</name>
+                     <description>DATLAT</description>
+                     <bitOffset>24</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+                  <field>
+                     <name>CLKDIV</name>
+                     <description>CLKDIV</description>
+                     <bitOffset>20</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+                  <field>
+                     <name>DATAST</name>
+                     <description>DATAST</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+                  <field>
+                     <name>ADDHLD</name>
+                     <description>ADDHLD</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+                  <field>
+                     <name>ADDSET</name>
+                     <description>ADDSET</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>BWTR2</name>
+               <displayName>BWTR2</displayName>
+               <description>SRAM/NOR-Flash write timing registers           2</description>
+               <addressOffset>0x10C</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x0FFFFFFF</resetValue>
+               <fields>
+                  <field>
+                     <name>ACCMOD</name>
+                     <description>ACCMOD</description>
+                     <bitOffset>28</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>DATLAT</name>
+                     <description>DATLAT</description>
+                     <bitOffset>24</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+                  <field>
+                     <name>CLKDIV</name>
+                     <description>CLKDIV</description>
+                     <bitOffset>20</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+                  <field>
+                     <name>DATAST</name>
+                     <description>DATAST</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+                  <field>
+                     <name>ADDHLD</name>
+                     <description>ADDHLD</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+                  <field>
+                     <name>ADDSET</name>
+                     <description>ADDSET</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>BWTR3</name>
+               <displayName>BWTR3</displayName>
+               <description>SRAM/NOR-Flash write timing registers           3</description>
+               <addressOffset>0x114</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x0FFFFFFF</resetValue>
+               <fields>
+                  <field>
+                     <name>ACCMOD</name>
+                     <description>ACCMOD</description>
+                     <bitOffset>28</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>DATLAT</name>
+                     <description>DATLAT</description>
+                     <bitOffset>24</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+                  <field>
+                     <name>CLKDIV</name>
+                     <description>CLKDIV</description>
+                     <bitOffset>20</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+                  <field>
+                     <name>DATAST</name>
+                     <description>DATAST</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+                  <field>
+                     <name>ADDHLD</name>
+                     <description>ADDHLD</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+                  <field>
+                     <name>ADDSET</name>
+                     <description>ADDSET</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>BWTR4</name>
+               <displayName>BWTR4</displayName>
+               <description>SRAM/NOR-Flash write timing registers           4</description>
+               <addressOffset>0x11C</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x0FFFFFFF</resetValue>
+               <fields>
+                  <field>
+                     <name>ACCMOD</name>
+                     <description>ACCMOD</description>
+                     <bitOffset>28</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>DATLAT</name>
+                     <description>DATLAT</description>
+                     <bitOffset>24</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+                  <field>
+                     <name>CLKDIV</name>
+                     <description>CLKDIV</description>
+                     <bitOffset>20</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+                  <field>
+                     <name>DATAST</name>
+                     <description>DATAST</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+                  <field>
+                     <name>ADDHLD</name>
+                     <description>ADDHLD</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+                  <field>
+                     <name>ADDSET</name>
+                     <description>ADDSET</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>SDCR1</name>
+               <displayName>SDCR1</displayName>
+               <description>SDRAM Control Register 1</description>
+               <addressOffset>0x140</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x000002D0</resetValue>
+               <fields>
+                  <field>
+                     <name>NC</name>
+                     <description>Number of column address               bits</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>NR</name>
+                     <description>Number of row address bits</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>MWID</name>
+                     <description>Memory data bus width</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>NB</name>
+                     <description>Number of internal banks</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CAS</name>
+                     <description>CAS latency</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>WP</name>
+                     <description>Write protection</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>SDCLK</name>
+                     <description>SDRAM clock configuration</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>RBURST</name>
+                     <description>Burst read</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>RPIPE</name>
+                     <description>Read pipe</description>
+                     <bitOffset>13</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>SDCR2</name>
+               <displayName>SDCR2</displayName>
+               <description>SDRAM Control Register 2</description>
+               <addressOffset>0x144</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x000002D0</resetValue>
+               <fields>
+                  <field>
+                     <name>NC</name>
+                     <description>Number of column address               bits</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>NR</name>
+                     <description>Number of row address bits</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>MWID</name>
+                     <description>Memory data bus width</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>NB</name>
+                     <description>Number of internal banks</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CAS</name>
+                     <description>CAS latency</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>WP</name>
+                     <description>Write protection</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>SDCLK</name>
+                     <description>SDRAM clock configuration</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>RBURST</name>
+                     <description>Burst read</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>RPIPE</name>
+                     <description>Read pipe</description>
+                     <bitOffset>13</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>SDTR1</name>
+               <displayName>SDTR1</displayName>
+               <description>SDRAM Timing register 1</description>
+               <addressOffset>0x148</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x0FFFFFFF</resetValue>
+               <fields>
+                  <field>
+                     <name>TMRD</name>
+                     <description>Load Mode Register to               Active</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+                  <field>
+                     <name>TXSR</name>
+                     <description>Exit self-refresh delay</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+                  <field>
+                     <name>TRAS</name>
+                     <description>Self refresh time</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+                  <field>
+                     <name>TRC</name>
+                     <description>Row cycle delay</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+                  <field>
+                     <name>TWR</name>
+                     <description>Recovery delay</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+                  <field>
+                     <name>TRP</name>
+                     <description>Row precharge delay</description>
+                     <bitOffset>20</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+                  <field>
+                     <name>TRCD</name>
+                     <description>Row to column delay</description>
+                     <bitOffset>24</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>SDTR2</name>
+               <displayName>SDTR2</displayName>
+               <description>SDRAM Timing register 2</description>
+               <addressOffset>0x14C</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x0FFFFFFF</resetValue>
+               <fields>
+                  <field>
+                     <name>TMRD</name>
+                     <description>Load Mode Register to               Active</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+                  <field>
+                     <name>TXSR</name>
+                     <description>Exit self-refresh delay</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+                  <field>
+                     <name>TRAS</name>
+                     <description>Self refresh time</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+                  <field>
+                     <name>TRC</name>
+                     <description>Row cycle delay</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+                  <field>
+                     <name>TWR</name>
+                     <description>Recovery delay</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+                  <field>
+                     <name>TRP</name>
+                     <description>Row precharge delay</description>
+                     <bitOffset>20</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+                  <field>
+                     <name>TRCD</name>
+                     <description>Row to column delay</description>
+                     <bitOffset>24</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>SDCMR</name>
+               <displayName>SDCMR</displayName>
+               <description>SDRAM Command Mode register</description>
+               <addressOffset>0x150</addressOffset>
+               <size>0x20</size>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>MODE</name>
+                     <description>Command mode</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>3</bitWidth>
+                     <access>write-only</access>
+                  </field>
+                  <field>
+                     <name>CTB2</name>
+                     <description>Command target bank 2</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>write-only</access>
+                  </field>
+                  <field>
+                     <name>CTB1</name>
+                     <description>Command target bank 1</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>write-only</access>
+                  </field>
+                  <field>
+                     <name>NRFS</name>
+                     <description>Number of Auto-refresh</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>4</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>MRD</name>
+                     <description>Mode Register definition</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>13</bitWidth>
+                     <access>read-write</access>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>SDRTR</name>
+               <displayName>SDRTR</displayName>
+               <description>SDRAM Refresh Timer register</description>
+               <addressOffset>0x154</addressOffset>
+               <size>0x20</size>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>CRE</name>
+                     <description>Clear Refresh error flag</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>write-only</access>
+                  </field>
+                  <field>
+                     <name>COUNT</name>
+                     <description>Refresh Timer Count</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>13</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>REIE</name>
+                     <description>RES Interrupt Enable</description>
+                     <bitOffset>14</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>SDSR</name>
+               <displayName>SDSR</displayName>
+               <description>SDRAM Status register</description>
+               <addressOffset>0x158</addressOffset>
+               <size>0x20</size>
+               <access>read-only</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>RE</name>
+                     <description>Refresh error flag</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>MODES1</name>
+                     <description>Status Mode for Bank 1</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>MODES2</name>
+                     <description>Status Mode for Bank 2</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>BUSY</name>
+                     <description>Busy status</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+         </registers>
+      </peripheral>
+      <peripheral>
+         <name>DMA2</name>
+         <description>DMA controller</description>
+         <groupName>DMA</groupName>
+         <baseAddress>0x40026400</baseAddress>
+         <addressBlock>
+            <offset>0x0</offset>
+            <size>0x400</size>
+            <usage>registers</usage>
+         </addressBlock>
+         <interrupt>
+            <name>DMA2_Stream0</name>
+            <description>DMA2 Stream0 global interrupt</description>
+            <value>56</value>
+         </interrupt>
+         <interrupt>
+            <name>DMA2_Stream1</name>
+            <description>DMA2 Stream1 global interrupt</description>
+            <value>57</value>
+         </interrupt>
+         <interrupt>
+            <name>DMA2_Stream2</name>
+            <description>DMA2 Stream2 global interrupt</description>
+            <value>58</value>
+         </interrupt>
+         <interrupt>
+            <name>DMA2_Stream3</name>
+            <description>DMA2 Stream3 global interrupt</description>
+            <value>59</value>
+         </interrupt>
+         <interrupt>
+            <name>DMA2_Stream4</name>
+            <description>DMA2 Stream4 global interrupt</description>
+            <value>60</value>
+         </interrupt>
+         <interrupt>
+            <name>DMA2_Stream5</name>
+            <description>DMA2 Stream5 global interrupt</description>
+            <value>68</value>
+         </interrupt>
+         <interrupt>
+            <name>DMA2_Stream6</name>
+            <description>DMA2 Stream6 global interrupt</description>
+            <value>69</value>
+         </interrupt>
+         <interrupt>
+            <name>DMA2_Stream7</name>
+            <description>DMA2 Stream7 global interrupt</description>
+            <value>70</value>
+         </interrupt>
+         <registers>
+            <register>
+               <name>LISR</name>
+               <displayName>LISR</displayName>
+               <description>low interrupt status register</description>
+               <addressOffset>0x0</addressOffset>
+               <size>0x20</size>
+               <access>read-only</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>TCIF3</name>
+                     <description>Stream x transfer complete interrupt               flag (x = 3..0)</description>
+                     <bitOffset>27</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>HTIF3</name>
+                     <description>Stream x half transfer interrupt flag               (x=3..0)</description>
+                     <bitOffset>26</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TEIF3</name>
+                     <description>Stream x transfer error interrupt flag               (x=3..0)</description>
+                     <bitOffset>25</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>DMEIF3</name>
+                     <description>Stream x direct mode error interrupt               flag (x=3..0)</description>
+                     <bitOffset>24</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FEIF3</name>
+                     <description>Stream x FIFO error interrupt flag               (x=3..0)</description>
+                     <bitOffset>22</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TCIF2</name>
+                     <description>Stream x transfer complete interrupt               flag (x = 3..0)</description>
+                     <bitOffset>21</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>HTIF2</name>
+                     <description>Stream x half transfer interrupt flag               (x=3..0)</description>
+                     <bitOffset>20</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TEIF2</name>
+                     <description>Stream x transfer error interrupt flag               (x=3..0)</description>
+                     <bitOffset>19</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>DMEIF2</name>
+                     <description>Stream x direct mode error interrupt               flag (x=3..0)</description>
+                     <bitOffset>18</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FEIF2</name>
+                     <description>Stream x FIFO error interrupt flag               (x=3..0)</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TCIF1</name>
+                     <description>Stream x transfer complete interrupt               flag (x = 3..0)</description>
+                     <bitOffset>11</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>HTIF1</name>
+                     <description>Stream x half transfer interrupt flag               (x=3..0)</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TEIF1</name>
+                     <description>Stream x transfer error interrupt flag               (x=3..0)</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>DMEIF1</name>
+                     <description>Stream x direct mode error interrupt               flag (x=3..0)</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FEIF1</name>
+                     <description>Stream x FIFO error interrupt flag               (x=3..0)</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TCIF0</name>
+                     <description>Stream x transfer complete interrupt               flag (x = 3..0)</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>HTIF0</name>
+                     <description>Stream x half transfer interrupt flag               (x=3..0)</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TEIF0</name>
+                     <description>Stream x transfer error interrupt flag               (x=3..0)</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>DMEIF0</name>
+                     <description>Stream x direct mode error interrupt               flag (x=3..0)</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FEIF0</name>
+                     <description>Stream x FIFO error interrupt flag               (x=3..0)</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HISR</name>
+               <displayName>HISR</displayName>
+               <description>high interrupt status register</description>
+               <addressOffset>0x4</addressOffset>
+               <size>0x20</size>
+               <access>read-only</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>TCIF7</name>
+                     <description>Stream x transfer complete interrupt               flag (x=7..4)</description>
+                     <bitOffset>27</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>HTIF7</name>
+                     <description>Stream x half transfer interrupt flag               (x=7..4)</description>
+                     <bitOffset>26</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TEIF7</name>
+                     <description>Stream x transfer error interrupt flag               (x=7..4)</description>
+                     <bitOffset>25</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>DMEIF7</name>
+                     <description>Stream x direct mode error interrupt               flag (x=7..4)</description>
+                     <bitOffset>24</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FEIF7</name>
+                     <description>Stream x FIFO error interrupt flag               (x=7..4)</description>
+                     <bitOffset>22</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TCIF6</name>
+                     <description>Stream x transfer complete interrupt               flag (x=7..4)</description>
+                     <bitOffset>21</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>HTIF6</name>
+                     <description>Stream x half transfer interrupt flag               (x=7..4)</description>
+                     <bitOffset>20</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TEIF6</name>
+                     <description>Stream x transfer error interrupt flag               (x=7..4)</description>
+                     <bitOffset>19</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>DMEIF6</name>
+                     <description>Stream x direct mode error interrupt               flag (x=7..4)</description>
+                     <bitOffset>18</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FEIF6</name>
+                     <description>Stream x FIFO error interrupt flag               (x=7..4)</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TCIF5</name>
+                     <description>Stream x transfer complete interrupt               flag (x=7..4)</description>
+                     <bitOffset>11</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>HTIF5</name>
+                     <description>Stream x half transfer interrupt flag               (x=7..4)</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TEIF5</name>
+                     <description>Stream x transfer error interrupt flag               (x=7..4)</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>DMEIF5</name>
+                     <description>Stream x direct mode error interrupt               flag (x=7..4)</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FEIF5</name>
+                     <description>Stream x FIFO error interrupt flag               (x=7..4)</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TCIF4</name>
+                     <description>Stream x transfer complete interrupt               flag (x=7..4)</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>HTIF4</name>
+                     <description>Stream x half transfer interrupt flag               (x=7..4)</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TEIF4</name>
+                     <description>Stream x transfer error interrupt flag               (x=7..4)</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>DMEIF4</name>
+                     <description>Stream x direct mode error interrupt               flag (x=7..4)</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FEIF4</name>
+                     <description>Stream x FIFO error interrupt flag               (x=7..4)</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>LIFCR</name>
+               <displayName>LIFCR</displayName>
+               <description>low interrupt flag clear           register</description>
+               <addressOffset>0x8</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>CTCIF3</name>
+                     <description>Stream x clear transfer complete               interrupt flag (x = 3..0)</description>
+                     <bitOffset>27</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CHTIF3</name>
+                     <description>Stream x clear half transfer interrupt               flag (x = 3..0)</description>
+                     <bitOffset>26</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CTEIF3</name>
+                     <description>Stream x clear transfer error interrupt               flag (x = 3..0)</description>
+                     <bitOffset>25</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CDMEIF3</name>
+                     <description>Stream x clear direct mode error               interrupt flag (x = 3..0)</description>
+                     <bitOffset>24</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CFEIF3</name>
+                     <description>Stream x clear FIFO error interrupt flag               (x = 3..0)</description>
+                     <bitOffset>22</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CTCIF2</name>
+                     <description>Stream x clear transfer complete               interrupt flag (x = 3..0)</description>
+                     <bitOffset>21</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CHTIF2</name>
+                     <description>Stream x clear half transfer interrupt               flag (x = 3..0)</description>
+                     <bitOffset>20</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CTEIF2</name>
+                     <description>Stream x clear transfer error interrupt               flag (x = 3..0)</description>
+                     <bitOffset>19</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CDMEIF2</name>
+                     <description>Stream x clear direct mode error               interrupt flag (x = 3..0)</description>
+                     <bitOffset>18</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CFEIF2</name>
+                     <description>Stream x clear FIFO error interrupt flag               (x = 3..0)</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CTCIF1</name>
+                     <description>Stream x clear transfer complete               interrupt flag (x = 3..0)</description>
+                     <bitOffset>11</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CHTIF1</name>
+                     <description>Stream x clear half transfer interrupt               flag (x = 3..0)</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CTEIF1</name>
+                     <description>Stream x clear transfer error interrupt               flag (x = 3..0)</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CDMEIF1</name>
+                     <description>Stream x clear direct mode error               interrupt flag (x = 3..0)</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CFEIF1</name>
+                     <description>Stream x clear FIFO error interrupt flag               (x = 3..0)</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CTCIF0</name>
+                     <description>Stream x clear transfer complete               interrupt flag (x = 3..0)</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CHTIF0</name>
+                     <description>Stream x clear half transfer interrupt               flag (x = 3..0)</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CTEIF0</name>
+                     <description>Stream x clear transfer error interrupt               flag (x = 3..0)</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CDMEIF0</name>
+                     <description>Stream x clear direct mode error               interrupt flag (x = 3..0)</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CFEIF0</name>
+                     <description>Stream x clear FIFO error interrupt flag               (x = 3..0)</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HIFCR</name>
+               <displayName>HIFCR</displayName>
+               <description>high interrupt flag clear           register</description>
+               <addressOffset>0xC</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>CTCIF7</name>
+                     <description>Stream x clear transfer complete               interrupt flag (x = 7..4)</description>
+                     <bitOffset>27</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CHTIF7</name>
+                     <description>Stream x clear half transfer interrupt               flag (x = 7..4)</description>
+                     <bitOffset>26</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CTEIF7</name>
+                     <description>Stream x clear transfer error interrupt               flag (x = 7..4)</description>
+                     <bitOffset>25</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CDMEIF7</name>
+                     <description>Stream x clear direct mode error               interrupt flag (x = 7..4)</description>
+                     <bitOffset>24</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CFEIF7</name>
+                     <description>Stream x clear FIFO error interrupt flag               (x = 7..4)</description>
+                     <bitOffset>22</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CTCIF6</name>
+                     <description>Stream x clear transfer complete               interrupt flag (x = 7..4)</description>
+                     <bitOffset>21</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CHTIF6</name>
+                     <description>Stream x clear half transfer interrupt               flag (x = 7..4)</description>
+                     <bitOffset>20</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CTEIF6</name>
+                     <description>Stream x clear transfer error interrupt               flag (x = 7..4)</description>
+                     <bitOffset>19</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CDMEIF6</name>
+                     <description>Stream x clear direct mode error               interrupt flag (x = 7..4)</description>
+                     <bitOffset>18</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CFEIF6</name>
+                     <description>Stream x clear FIFO error interrupt flag               (x = 7..4)</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CTCIF5</name>
+                     <description>Stream x clear transfer complete               interrupt flag (x = 7..4)</description>
+                     <bitOffset>11</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CHTIF5</name>
+                     <description>Stream x clear half transfer interrupt               flag (x = 7..4)</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CTEIF5</name>
+                     <description>Stream x clear transfer error interrupt               flag (x = 7..4)</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CDMEIF5</name>
+                     <description>Stream x clear direct mode error               interrupt flag (x = 7..4)</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CFEIF5</name>
+                     <description>Stream x clear FIFO error interrupt flag               (x = 7..4)</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CTCIF4</name>
+                     <description>Stream x clear transfer complete               interrupt flag (x = 7..4)</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CHTIF4</name>
+                     <description>Stream x clear half transfer interrupt               flag (x = 7..4)</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CTEIF4</name>
+                     <description>Stream x clear transfer error interrupt               flag (x = 7..4)</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CDMEIF4</name>
+                     <description>Stream x clear direct mode error               interrupt flag (x = 7..4)</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CFEIF4</name>
+                     <description>Stream x clear FIFO error interrupt flag               (x = 7..4)</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>S0CR</name>
+               <displayName>S0CR</displayName>
+               <description>stream x configuration           register</description>
+               <addressOffset>0x10</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>CHSEL</name>
+                     <description>Channel selection</description>
+                     <bitOffset>25</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+                  <field>
+                     <name>MBURST</name>
+                     <description>Memory burst transfer               configuration</description>
+                     <bitOffset>23</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>PBURST</name>
+                     <description>Peripheral burst transfer               configuration</description>
+                     <bitOffset>21</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>CT</name>
+                     <description>Current target (only in double buffer               mode)</description>
+                     <bitOffset>19</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>DBM</name>
+                     <description>Double buffer mode</description>
+                     <bitOffset>18</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>PL</name>
+                     <description>Priority level</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>PINCOS</name>
+                     <description>Peripheral increment offset               size</description>
+                     <bitOffset>15</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>MSIZE</name>
+                     <description>Memory data size</description>
+                     <bitOffset>13</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>PSIZE</name>
+                     <description>Peripheral data size</description>
+                     <bitOffset>11</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>MINC</name>
+                     <description>Memory increment mode</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>PINC</name>
+                     <description>Peripheral increment mode</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CIRC</name>
+                     <description>Circular mode</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>DIR</name>
+                     <description>Data transfer direction</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>PFCTRL</name>
+                     <description>Peripheral flow controller</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TCIE</name>
+                     <description>Transfer complete interrupt               enable</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>HTIE</name>
+                     <description>Half transfer interrupt               enable</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TEIE</name>
+                     <description>Transfer error interrupt               enable</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>DMEIE</name>
+                     <description>Direct mode error interrupt               enable</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>EN</name>
+                     <description>Stream enable / flag stream ready when               read low</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>S0NDTR</name>
+               <displayName>S0NDTR</displayName>
+               <description>stream x number of data           register</description>
+               <addressOffset>0x14</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>NDT</name>
+                     <description>Number of data items to               transfer</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>S0PAR</name>
+               <displayName>S0PAR</displayName>
+               <description>stream x peripheral address           register</description>
+               <addressOffset>0x18</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>PA</name>
+                     <description>Peripheral address</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>S0M0AR</name>
+               <displayName>S0M0AR</displayName>
+               <description>stream x memory 0 address           register</description>
+               <addressOffset>0x1C</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>M0A</name>
+                     <description>Memory 0 address</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>S0M1AR</name>
+               <displayName>S0M1AR</displayName>
+               <description>stream x memory 1 address           register</description>
+               <addressOffset>0x20</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>M1A</name>
+                     <description>Memory 1 address (used in case of Double               buffer mode)</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>S0FCR</name>
+               <displayName>S0FCR</displayName>
+               <description>stream x FIFO control register</description>
+               <addressOffset>0x24</addressOffset>
+               <size>0x20</size>
+               <resetValue>0x00000021</resetValue>
+               <fields>
+                  <field>
+                     <name>FEIE</name>
+                     <description>FIFO error interrupt               enable</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>FS</name>
+                     <description>FIFO status</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>3</bitWidth>
+                     <access>read-only</access>
+                  </field>
+                  <field>
+                     <name>DMDIS</name>
+                     <description>Direct mode disable</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>FTH</name>
+                     <description>FIFO threshold selection</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>2</bitWidth>
+                     <access>read-write</access>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>S1CR</name>
+               <displayName>S1CR</displayName>
+               <description>stream x configuration           register</description>
+               <addressOffset>0x28</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>CHSEL</name>
+                     <description>Channel selection</description>
+                     <bitOffset>25</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+                  <field>
+                     <name>MBURST</name>
+                     <description>Memory burst transfer               configuration</description>
+                     <bitOffset>23</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>PBURST</name>
+                     <description>Peripheral burst transfer               configuration</description>
+                     <bitOffset>21</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>ACK</name>
+                     <description>ACK</description>
+                     <bitOffset>20</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CT</name>
+                     <description>Current target (only in double buffer               mode)</description>
+                     <bitOffset>19</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>DBM</name>
+                     <description>Double buffer mode</description>
+                     <bitOffset>18</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>PL</name>
+                     <description>Priority level</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>PINCOS</name>
+                     <description>Peripheral increment offset               size</description>
+                     <bitOffset>15</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>MSIZE</name>
+                     <description>Memory data size</description>
+                     <bitOffset>13</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>PSIZE</name>
+                     <description>Peripheral data size</description>
+                     <bitOffset>11</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>MINC</name>
+                     <description>Memory increment mode</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>PINC</name>
+                     <description>Peripheral increment mode</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CIRC</name>
+                     <description>Circular mode</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>DIR</name>
+                     <description>Data transfer direction</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>PFCTRL</name>
+                     <description>Peripheral flow controller</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TCIE</name>
+                     <description>Transfer complete interrupt               enable</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>HTIE</name>
+                     <description>Half transfer interrupt               enable</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TEIE</name>
+                     <description>Transfer error interrupt               enable</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>DMEIE</name>
+                     <description>Direct mode error interrupt               enable</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>EN</name>
+                     <description>Stream enable / flag stream ready when               read low</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>S1NDTR</name>
+               <displayName>S1NDTR</displayName>
+               <description>stream x number of data           register</description>
+               <addressOffset>0x2C</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>NDT</name>
+                     <description>Number of data items to               transfer</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>S1PAR</name>
+               <displayName>S1PAR</displayName>
+               <description>stream x peripheral address           register</description>
+               <addressOffset>0x30</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>PA</name>
+                     <description>Peripheral address</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>S1M0AR</name>
+               <displayName>S1M0AR</displayName>
+               <description>stream x memory 0 address           register</description>
+               <addressOffset>0x34</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>M0A</name>
+                     <description>Memory 0 address</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>S1M1AR</name>
+               <displayName>S1M1AR</displayName>
+               <description>stream x memory 1 address           register</description>
+               <addressOffset>0x38</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>M1A</name>
+                     <description>Memory 1 address (used in case of Double               buffer mode)</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>S1FCR</name>
+               <displayName>S1FCR</displayName>
+               <description>stream x FIFO control register</description>
+               <addressOffset>0x3C</addressOffset>
+               <size>0x20</size>
+               <resetValue>0x00000021</resetValue>
+               <fields>
+                  <field>
+                     <name>FEIE</name>
+                     <description>FIFO error interrupt               enable</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>FS</name>
+                     <description>FIFO status</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>3</bitWidth>
+                     <access>read-only</access>
+                  </field>
+                  <field>
+                     <name>DMDIS</name>
+                     <description>Direct mode disable</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>FTH</name>
+                     <description>FIFO threshold selection</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>2</bitWidth>
+                     <access>read-write</access>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>S2CR</name>
+               <displayName>S2CR</displayName>
+               <description>stream x configuration           register</description>
+               <addressOffset>0x40</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>CHSEL</name>
+                     <description>Channel selection</description>
+                     <bitOffset>25</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+                  <field>
+                     <name>MBURST</name>
+                     <description>Memory burst transfer               configuration</description>
+                     <bitOffset>23</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>PBURST</name>
+                     <description>Peripheral burst transfer               configuration</description>
+                     <bitOffset>21</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>ACK</name>
+                     <description>ACK</description>
+                     <bitOffset>20</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CT</name>
+                     <description>Current target (only in double buffer               mode)</description>
+                     <bitOffset>19</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>DBM</name>
+                     <description>Double buffer mode</description>
+                     <bitOffset>18</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>PL</name>
+                     <description>Priority level</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>PINCOS</name>
+                     <description>Peripheral increment offset               size</description>
+                     <bitOffset>15</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>MSIZE</name>
+                     <description>Memory data size</description>
+                     <bitOffset>13</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>PSIZE</name>
+                     <description>Peripheral data size</description>
+                     <bitOffset>11</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>MINC</name>
+                     <description>Memory increment mode</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>PINC</name>
+                     <description>Peripheral increment mode</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CIRC</name>
+                     <description>Circular mode</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>DIR</name>
+                     <description>Data transfer direction</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>PFCTRL</name>
+                     <description>Peripheral flow controller</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TCIE</name>
+                     <description>Transfer complete interrupt               enable</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>HTIE</name>
+                     <description>Half transfer interrupt               enable</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TEIE</name>
+                     <description>Transfer error interrupt               enable</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>DMEIE</name>
+                     <description>Direct mode error interrupt               enable</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>EN</name>
+                     <description>Stream enable / flag stream ready when               read low</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>S2NDTR</name>
+               <displayName>S2NDTR</displayName>
+               <description>stream x number of data           register</description>
+               <addressOffset>0x44</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>NDT</name>
+                     <description>Number of data items to               transfer</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>S2PAR</name>
+               <displayName>S2PAR</displayName>
+               <description>stream x peripheral address           register</description>
+               <addressOffset>0x48</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>PA</name>
+                     <description>Peripheral address</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>S2M0AR</name>
+               <displayName>S2M0AR</displayName>
+               <description>stream x memory 0 address           register</description>
+               <addressOffset>0x4C</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>M0A</name>
+                     <description>Memory 0 address</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>S2M1AR</name>
+               <displayName>S2M1AR</displayName>
+               <description>stream x memory 1 address           register</description>
+               <addressOffset>0x50</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>M1A</name>
+                     <description>Memory 1 address (used in case of Double               buffer mode)</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>S2FCR</name>
+               <displayName>S2FCR</displayName>
+               <description>stream x FIFO control register</description>
+               <addressOffset>0x54</addressOffset>
+               <size>0x20</size>
+               <resetValue>0x00000021</resetValue>
+               <fields>
+                  <field>
+                     <name>FEIE</name>
+                     <description>FIFO error interrupt               enable</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>FS</name>
+                     <description>FIFO status</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>3</bitWidth>
+                     <access>read-only</access>
+                  </field>
+                  <field>
+                     <name>DMDIS</name>
+                     <description>Direct mode disable</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>FTH</name>
+                     <description>FIFO threshold selection</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>2</bitWidth>
+                     <access>read-write</access>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>S3CR</name>
+               <displayName>S3CR</displayName>
+               <description>stream x configuration           register</description>
+               <addressOffset>0x58</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>CHSEL</name>
+                     <description>Channel selection</description>
+                     <bitOffset>25</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+                  <field>
+                     <name>MBURST</name>
+                     <description>Memory burst transfer               configuration</description>
+                     <bitOffset>23</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>PBURST</name>
+                     <description>Peripheral burst transfer               configuration</description>
+                     <bitOffset>21</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>ACK</name>
+                     <description>ACK</description>
+                     <bitOffset>20</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CT</name>
+                     <description>Current target (only in double buffer               mode)</description>
+                     <bitOffset>19</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>DBM</name>
+                     <description>Double buffer mode</description>
+                     <bitOffset>18</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>PL</name>
+                     <description>Priority level</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>PINCOS</name>
+                     <description>Peripheral increment offset               size</description>
+                     <bitOffset>15</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>MSIZE</name>
+                     <description>Memory data size</description>
+                     <bitOffset>13</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>PSIZE</name>
+                     <description>Peripheral data size</description>
+                     <bitOffset>11</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>MINC</name>
+                     <description>Memory increment mode</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>PINC</name>
+                     <description>Peripheral increment mode</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CIRC</name>
+                     <description>Circular mode</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>DIR</name>
+                     <description>Data transfer direction</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>PFCTRL</name>
+                     <description>Peripheral flow controller</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TCIE</name>
+                     <description>Transfer complete interrupt               enable</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>HTIE</name>
+                     <description>Half transfer interrupt               enable</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TEIE</name>
+                     <description>Transfer error interrupt               enable</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>DMEIE</name>
+                     <description>Direct mode error interrupt               enable</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>EN</name>
+                     <description>Stream enable / flag stream ready when               read low</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>S3NDTR</name>
+               <displayName>S3NDTR</displayName>
+               <description>stream x number of data           register</description>
+               <addressOffset>0x5C</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>NDT</name>
+                     <description>Number of data items to               transfer</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>S3PAR</name>
+               <displayName>S3PAR</displayName>
+               <description>stream x peripheral address           register</description>
+               <addressOffset>0x60</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>PA</name>
+                     <description>Peripheral address</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>S3M0AR</name>
+               <displayName>S3M0AR</displayName>
+               <description>stream x memory 0 address           register</description>
+               <addressOffset>0x64</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>M0A</name>
+                     <description>Memory 0 address</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>S3M1AR</name>
+               <displayName>S3M1AR</displayName>
+               <description>stream x memory 1 address           register</description>
+               <addressOffset>0x68</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>M1A</name>
+                     <description>Memory 1 address (used in case of Double               buffer mode)</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>S3FCR</name>
+               <displayName>S3FCR</displayName>
+               <description>stream x FIFO control register</description>
+               <addressOffset>0x6C</addressOffset>
+               <size>0x20</size>
+               <resetValue>0x00000021</resetValue>
+               <fields>
+                  <field>
+                     <name>FEIE</name>
+                     <description>FIFO error interrupt               enable</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>FS</name>
+                     <description>FIFO status</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>3</bitWidth>
+                     <access>read-only</access>
+                  </field>
+                  <field>
+                     <name>DMDIS</name>
+                     <description>Direct mode disable</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>FTH</name>
+                     <description>FIFO threshold selection</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>2</bitWidth>
+                     <access>read-write</access>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>S4CR</name>
+               <displayName>S4CR</displayName>
+               <description>stream x configuration           register</description>
+               <addressOffset>0x70</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>CHSEL</name>
+                     <description>Channel selection</description>
+                     <bitOffset>25</bitOffset>
+                     <bitWidth>3</bitWidth>
+                  </field>
+                  <field>
+                     <name>MBURST</name>
+                     <description>Memory burst transfer               configuration</description>
+                     <bitOffset>23</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>PBURST</name>
+                     <description>Peripheral burst transfer               configuration</description>
+                     <bitOffset>21</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>ACK</name>
+                     <description>ACK</description>
+                     <bitOffset>20</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CT</name>
+                     <description>Current target (only in double buffer               mode)</description>
+                     <bitOffset>19</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>DBM</name>
+                     <description>Double buffer mode</description>
+                     <bitOffset>18</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>PL</name>
+                     <description>Priority level</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>PINCOS</name>
+                     <description>Peripheral increment offset               size</description>
+                     <bitOffset>15</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>MSIZE</name>
+                     <description>Memory data size</description>
+                     <bitOffset>13</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>PSIZE</name>
+                     <description>Peripheral data size</description>
+                     <bitOffset>11</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>MINC</name>
+                     <description>Memory increment mode</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>PINC</name>
+                     <description>Peripheral increment mode</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CIRC</name>
+                     <description>Circular mode</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>DIR</name>
+                     <description>Data transfer direction</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>PFCTRL</name>
+                     <description>Peripheral flow controller</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TCIE</name>
+                     <description>Transfer complete interrupt               enable</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>HTIE</name>
+                     <description>Half transfer interrupt               enable</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TEIE</name>
+                     <description>Transfer error interrupt               enable</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>DMEIE</name>
+                     <description>Direct mode error interrupt               enable</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>EN</name>
+                     <description>Stream enable / flag stream ready when               read low</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>S4NDTR</name>
+               <displayName>S4NDTR</displayName>
+               <description>stream x number of data           register</description>
+               <addressOffset>0x74</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>NDT</name>
+                     <description>Number of data items to               transfer</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>S4PAR</name>
+               <displayName>S4PAR</displayName>
+               <description>stream x peripheral address           register</description>
+               <addressOffset>0x78</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>PA</name>
+                     <description>Peripheral address</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>S4M0AR</name>
+               <displayName>S4M0AR</displayName>
+               <description>stream x memory 0 address           register</description>
+               <addressOffset>0x7C</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>M0A</name>
+                     <description>Memory 0 address</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>S4M1AR</name>
+               <displayName>S4M1AR</displayName>
+               <description>stream x memory 1 address           register</description>
+               <addressOffset>0x80</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>M1A</name>
+                     <description>Memory 1 address (used in case of Double               buffer mode)</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>S4FCR</name>
+               <displayName>S4FCR</displayName>
+               <description>stream x FIFO control register</description>
+               <addressOffset>0x84</addressOffset>
+               <size>0x20</size>
+               <resetValue>0x00000021</resetValue>
+               <fields>
+                  <field>
+                     <name>FEIE</name>
+                     <description>FIFO error interrupt               enable</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>FS</name>
+                     <description>FIFO status</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>3</bitWidth>
+                     <access>read-only</access>
+                  </field>
+                  <field>
+                     <name>DMDIS</name>
+                     <description>Direct mode disable</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>FTH</name>
+                     <description>FIFO threshold selection</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>2</bitWidth>
+                     <access>read-write</access>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>S5CR</name>
+               <displayName>S5CR</displayName>
+               <description>stream x configuration           register</description>
+               <addressOffset>0x88</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>CHSEL</name>
+                     <description>Channel selection</description>
+                     <bitOffset>25</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+                  <field>
+                     <name>MBURST</name>
+                     <description>Memory burst transfer               configuration</description>
+                     <bitOffset>23</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>PBURST</name>
+                     <description>Peripheral burst transfer               configuration</description>
+                     <bitOffset>21</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>ACK</name>
+                     <description>ACK</description>
+                     <bitOffset>20</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CT</name>
+                     <description>Current target (only in double buffer               mode)</description>
+                     <bitOffset>19</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>DBM</name>
+                     <description>Double buffer mode</description>
+                     <bitOffset>18</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>PL</name>
+                     <description>Priority level</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>PINCOS</name>
+                     <description>Peripheral increment offset               size</description>
+                     <bitOffset>15</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>MSIZE</name>
+                     <description>Memory data size</description>
+                     <bitOffset>13</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>PSIZE</name>
+                     <description>Peripheral data size</description>
+                     <bitOffset>11</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>MINC</name>
+                     <description>Memory increment mode</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>PINC</name>
+                     <description>Peripheral increment mode</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CIRC</name>
+                     <description>Circular mode</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>DIR</name>
+                     <description>Data transfer direction</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>PFCTRL</name>
+                     <description>Peripheral flow controller</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TCIE</name>
+                     <description>Transfer complete interrupt               enable</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>HTIE</name>
+                     <description>Half transfer interrupt               enable</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TEIE</name>
+                     <description>Transfer error interrupt               enable</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>DMEIE</name>
+                     <description>Direct mode error interrupt               enable</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>EN</name>
+                     <description>Stream enable / flag stream ready when               read low</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>S5NDTR</name>
+               <displayName>S5NDTR</displayName>
+               <description>stream x number of data           register</description>
+               <addressOffset>0x8C</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>NDT</name>
+                     <description>Number of data items to               transfer</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>S5PAR</name>
+               <displayName>S5PAR</displayName>
+               <description>stream x peripheral address           register</description>
+               <addressOffset>0x90</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>PA</name>
+                     <description>Peripheral address</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>S5M0AR</name>
+               <displayName>S5M0AR</displayName>
+               <description>stream x memory 0 address           register</description>
+               <addressOffset>0x94</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>M0A</name>
+                     <description>Memory 0 address</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>S5M1AR</name>
+               <displayName>S5M1AR</displayName>
+               <description>stream x memory 1 address           register</description>
+               <addressOffset>0x98</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>M1A</name>
+                     <description>Memory 1 address (used in case of Double               buffer mode)</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>S5FCR</name>
+               <displayName>S5FCR</displayName>
+               <description>stream x FIFO control register</description>
+               <addressOffset>0x9C</addressOffset>
+               <size>0x20</size>
+               <resetValue>0x00000021</resetValue>
+               <fields>
+                  <field>
+                     <name>FEIE</name>
+                     <description>FIFO error interrupt               enable</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>FS</name>
+                     <description>FIFO status</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>3</bitWidth>
+                     <access>read-only</access>
+                  </field>
+                  <field>
+                     <name>DMDIS</name>
+                     <description>Direct mode disable</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>FTH</name>
+                     <description>FIFO threshold selection</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>2</bitWidth>
+                     <access>read-write</access>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>S6CR</name>
+               <displayName>S6CR</displayName>
+               <description>stream x configuration           register</description>
+               <addressOffset>0xA0</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>CHSEL</name>
+                     <description>Channel selection</description>
+                     <bitOffset>25</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+                  <field>
+                     <name>MBURST</name>
+                     <description>Memory burst transfer               configuration</description>
+                     <bitOffset>23</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>PBURST</name>
+                     <description>Peripheral burst transfer               configuration</description>
+                     <bitOffset>21</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>ACK</name>
+                     <description>ACK</description>
+                     <bitOffset>20</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CT</name>
+                     <description>Current target (only in double buffer               mode)</description>
+                     <bitOffset>19</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>DBM</name>
+                     <description>Double buffer mode</description>
+                     <bitOffset>18</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>PL</name>
+                     <description>Priority level</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>PINCOS</name>
+                     <description>Peripheral increment offset               size</description>
+                     <bitOffset>15</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>MSIZE</name>
+                     <description>Memory data size</description>
+                     <bitOffset>13</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>PSIZE</name>
+                     <description>Peripheral data size</description>
+                     <bitOffset>11</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>MINC</name>
+                     <description>Memory increment mode</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>PINC</name>
+                     <description>Peripheral increment mode</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CIRC</name>
+                     <description>Circular mode</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>DIR</name>
+                     <description>Data transfer direction</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>PFCTRL</name>
+                     <description>Peripheral flow controller</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TCIE</name>
+                     <description>Transfer complete interrupt               enable</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>HTIE</name>
+                     <description>Half transfer interrupt               enable</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TEIE</name>
+                     <description>Transfer error interrupt               enable</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>DMEIE</name>
+                     <description>Direct mode error interrupt               enable</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>EN</name>
+                     <description>Stream enable / flag stream ready when               read low</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>S6NDTR</name>
+               <displayName>S6NDTR</displayName>
+               <description>stream x number of data           register</description>
+               <addressOffset>0xA4</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>NDT</name>
+                     <description>Number of data items to               transfer</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>S6PAR</name>
+               <displayName>S6PAR</displayName>
+               <description>stream x peripheral address           register</description>
+               <addressOffset>0xA8</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>PA</name>
+                     <description>Peripheral address</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>S6M0AR</name>
+               <displayName>S6M0AR</displayName>
+               <description>stream x memory 0 address           register</description>
+               <addressOffset>0xAC</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>M0A</name>
+                     <description>Memory 0 address</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>S6M1AR</name>
+               <displayName>S6M1AR</displayName>
+               <description>stream x memory 1 address           register</description>
+               <addressOffset>0xB0</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>M1A</name>
+                     <description>Memory 1 address (used in case of Double               buffer mode)</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>S6FCR</name>
+               <displayName>S6FCR</displayName>
+               <description>stream x FIFO control register</description>
+               <addressOffset>0xB4</addressOffset>
+               <size>0x20</size>
+               <resetValue>0x00000021</resetValue>
+               <fields>
+                  <field>
+                     <name>FEIE</name>
+                     <description>FIFO error interrupt               enable</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>FS</name>
+                     <description>FIFO status</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>3</bitWidth>
+                     <access>read-only</access>
+                  </field>
+                  <field>
+                     <name>DMDIS</name>
+                     <description>Direct mode disable</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>FTH</name>
+                     <description>FIFO threshold selection</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>2</bitWidth>
+                     <access>read-write</access>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>S7CR</name>
+               <displayName>S7CR</displayName>
+               <description>stream x configuration           register</description>
+               <addressOffset>0xB8</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>CHSEL</name>
+                     <description>Channel selection</description>
+                     <bitOffset>25</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+                  <field>
+                     <name>MBURST</name>
+                     <description>Memory burst transfer               configuration</description>
+                     <bitOffset>23</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>PBURST</name>
+                     <description>Peripheral burst transfer               configuration</description>
+                     <bitOffset>21</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>ACK</name>
+                     <description>ACK</description>
+                     <bitOffset>20</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CT</name>
+                     <description>Current target (only in double buffer               mode)</description>
+                     <bitOffset>19</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>DBM</name>
+                     <description>Double buffer mode</description>
+                     <bitOffset>18</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>PL</name>
+                     <description>Priority level</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>PINCOS</name>
+                     <description>Peripheral increment offset               size</description>
+                     <bitOffset>15</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>MSIZE</name>
+                     <description>Memory data size</description>
+                     <bitOffset>13</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>PSIZE</name>
+                     <description>Peripheral data size</description>
+                     <bitOffset>11</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>MINC</name>
+                     <description>Memory increment mode</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>PINC</name>
+                     <description>Peripheral increment mode</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CIRC</name>
+                     <description>Circular mode</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>DIR</name>
+                     <description>Data transfer direction</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>PFCTRL</name>
+                     <description>Peripheral flow controller</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TCIE</name>
+                     <description>Transfer complete interrupt               enable</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>HTIE</name>
+                     <description>Half transfer interrupt               enable</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TEIE</name>
+                     <description>Transfer error interrupt               enable</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>DMEIE</name>
+                     <description>Direct mode error interrupt               enable</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>EN</name>
+                     <description>Stream enable / flag stream ready when               read low</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>S7NDTR</name>
+               <displayName>S7NDTR</displayName>
+               <description>stream x number of data           register</description>
+               <addressOffset>0xBC</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>NDT</name>
+                     <description>Number of data items to               transfer</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>S7PAR</name>
+               <displayName>S7PAR</displayName>
+               <description>stream x peripheral address           register</description>
+               <addressOffset>0xC0</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>PA</name>
+                     <description>Peripheral address</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>S7M0AR</name>
+               <displayName>S7M0AR</displayName>
+               <description>stream x memory 0 address           register</description>
+               <addressOffset>0xC4</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>M0A</name>
+                     <description>Memory 0 address</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>S7M1AR</name>
+               <displayName>S7M1AR</displayName>
+               <description>stream x memory 1 address           register</description>
+               <addressOffset>0xC8</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>M1A</name>
+                     <description>Memory 1 address (used in case of Double               buffer mode)</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>S7FCR</name>
+               <displayName>S7FCR</displayName>
+               <description>stream x FIFO control register</description>
+               <addressOffset>0xCC</addressOffset>
+               <size>0x20</size>
+               <resetValue>0x00000021</resetValue>
+               <fields>
+                  <field>
+                     <name>FEIE</name>
+                     <description>FIFO error interrupt               enable</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>FS</name>
+                     <description>FIFO status</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>3</bitWidth>
+                     <access>read-only</access>
+                  </field>
+                  <field>
+                     <name>DMDIS</name>
+                     <description>Direct mode disable</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>FTH</name>
+                     <description>FIFO threshold selection</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>2</bitWidth>
+                     <access>read-write</access>
+                  </field>
+               </fields>
+            </register>
+         </registers>
+      </peripheral>
+      <peripheral derivedFrom="DMA2">
+         <name>DMA1</name>
+         <baseAddress>0x40026000</baseAddress>
+         <interrupt>
+            <name>DMA1_Stream0</name>
+            <description>DMA1 Stream0 global interrupt</description>
+            <value>11</value>
+         </interrupt>
+         <interrupt>
+            <name>DMA1_Stream1</name>
+            <description>DMA1 Stream1 global interrupt</description>
+            <value>12</value>
+         </interrupt>
+         <interrupt>
+            <name>DMA1_Stream2</name>
+            <description>DMA1 Stream2 global interrupt</description>
+            <value>13</value>
+         </interrupt>
+         <interrupt>
+            <name>DMA1_Stream3</name>
+            <description>DMA1 Stream3 global interrupt</description>
+            <value>14</value>
+         </interrupt>
+         <interrupt>
+            <name>DMA1_Stream4</name>
+            <description>DMA1 Stream4 global interrupt</description>
+            <value>15</value>
+         </interrupt>
+         <interrupt>
+            <name>DMA1_Stream5</name>
+            <description>DMA1 Stream5 global interrupt</description>
+            <value>16</value>
+         </interrupt>
+         <interrupt>
+            <name>DMA1_Stream6</name>
+            <description>DMA1 Stream6 global interrupt</description>
+            <value>17</value>
+         </interrupt>
+         <interrupt>
+            <name>DMA1_Stream7</name>
+            <description>DMA1 Stream7 global interrupt</description>
+            <value>47</value>
+         </interrupt>
+      </peripheral>
+      <peripheral>
+         <name>RCC</name>
+         <description>Reset and clock control</description>
+         <groupName>RCC</groupName>
+         <baseAddress>0x40023800</baseAddress>
+         <addressBlock>
+            <offset>0x0</offset>
+            <size>0x400</size>
+            <usage>registers</usage>
+         </addressBlock>
+         <interrupt>
+            <name>RCC</name>
+            <description>RCC global interrupt</description>
+            <value>5</value>
+         </interrupt>
+         <registers>
+            <register>
+               <name>CR</name>
+               <displayName>CR</displayName>
+               <description>clock control register</description>
+               <addressOffset>0x0</addressOffset>
+               <size>0x20</size>
+               <resetValue>0x00000083</resetValue>
+               <fields>
+                  <field>
+                     <name>PLLI2SRDY</name>
+                     <description>PLLI2S clock ready flag</description>
+                     <bitOffset>27</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-only</access>
+                  </field>
+                  <field>
+                     <name>PLLI2SON</name>
+                     <description>PLLI2S enable</description>
+                     <bitOffset>26</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>PLLRDY</name>
+                     <description>Main PLL (PLL) clock ready               flag</description>
+                     <bitOffset>25</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-only</access>
+                  </field>
+                  <field>
+                     <name>PLLON</name>
+                     <description>Main PLL (PLL) enable</description>
+                     <bitOffset>24</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>CSSON</name>
+                     <description>Clock security system               enable</description>
+                     <bitOffset>19</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>HSEBYP</name>
+                     <description>HSE clock bypass</description>
+                     <bitOffset>18</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>HSERDY</name>
+                     <description>HSE clock ready flag</description>
+                     <bitOffset>17</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-only</access>
+                  </field>
+                  <field>
+                     <name>HSEON</name>
+                     <description>HSE clock enable</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>HSICAL</name>
+                     <description>Internal high-speed clock               calibration</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>8</bitWidth>
+                     <access>read-only</access>
+                  </field>
+                  <field>
+                     <name>HSITRIM</name>
+                     <description>Internal high-speed clock               trimming</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>5</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>HSIRDY</name>
+                     <description>Internal high-speed clock ready               flag</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-only</access>
+                  </field>
+                  <field>
+                     <name>HSION</name>
+                     <description>Internal high-speed clock               enable</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>PLLCFGR</name>
+               <displayName>PLLCFGR</displayName>
+               <description>PLL configuration register</description>
+               <addressOffset>0x4</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x24003010</resetValue>
+               <fields>
+                  <field>
+                     <name>PLLQ3</name>
+                     <description>Main PLL (PLL) division factor for USB               OTG FS, SDIO and random number generator               clocks</description>
+                     <bitOffset>27</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>PLLQ2</name>
+                     <description>Main PLL (PLL) division factor for USB               OTG FS, SDIO and random number generator               clocks</description>
+                     <bitOffset>26</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>PLLQ1</name>
+                     <description>Main PLL (PLL) division factor for USB               OTG FS, SDIO and random number generator               clocks</description>
+                     <bitOffset>25</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>PLLQ0</name>
+                     <description>Main PLL (PLL) division factor for USB               OTG FS, SDIO and random number generator               clocks</description>
+                     <bitOffset>24</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>PLLSRC</name>
+                     <description>Main PLL(PLL) and audio PLL (PLLI2S)               entry clock source</description>
+                     <bitOffset>22</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>PLLP1</name>
+                     <description>Main PLL (PLL) division factor for main               system clock</description>
+                     <bitOffset>17</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>PLLP0</name>
+                     <description>Main PLL (PLL) division factor for main               system clock</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>PLLN8</name>
+                     <description>Main PLL (PLL) multiplication factor for               VCO</description>
+                     <bitOffset>14</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>PLLN7</name>
+                     <description>Main PLL (PLL) multiplication factor for               VCO</description>
+                     <bitOffset>13</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>PLLN6</name>
+                     <description>Main PLL (PLL) multiplication factor for               VCO</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>PLLN5</name>
+                     <description>Main PLL (PLL) multiplication factor for               VCO</description>
+                     <bitOffset>11</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>PLLN4</name>
+                     <description>Main PLL (PLL) multiplication factor for               VCO</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>PLLN3</name>
+                     <description>Main PLL (PLL) multiplication factor for               VCO</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>PLLN2</name>
+                     <description>Main PLL (PLL) multiplication factor for               VCO</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>PLLN1</name>
+                     <description>Main PLL (PLL) multiplication factor for               VCO</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>PLLN0</name>
+                     <description>Main PLL (PLL) multiplication factor for               VCO</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>PLLM5</name>
+                     <description>Division factor for the main PLL (PLL)               and audio PLL (PLLI2S) input clock</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>PLLM4</name>
+                     <description>Division factor for the main PLL (PLL)               and audio PLL (PLLI2S) input clock</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>PLLM3</name>
+                     <description>Division factor for the main PLL (PLL)               and audio PLL (PLLI2S) input clock</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>PLLM2</name>
+                     <description>Division factor for the main PLL (PLL)               and audio PLL (PLLI2S) input clock</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>PLLM1</name>
+                     <description>Division factor for the main PLL (PLL)               and audio PLL (PLLI2S) input clock</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>PLLM0</name>
+                     <description>Division factor for the main PLL (PLL)               and audio PLL (PLLI2S) input clock</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>CFGR</name>
+               <displayName>CFGR</displayName>
+               <description>clock configuration register</description>
+               <addressOffset>0x8</addressOffset>
+               <size>0x20</size>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>MCO2</name>
+                     <description>Microcontroller clock output               2</description>
+                     <bitOffset>30</bitOffset>
+                     <bitWidth>2</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>MCO2PRE</name>
+                     <description>MCO2 prescaler</description>
+                     <bitOffset>27</bitOffset>
+                     <bitWidth>3</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>MCO1PRE</name>
+                     <description>MCO1 prescaler</description>
+                     <bitOffset>24</bitOffset>
+                     <bitWidth>3</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>I2SSRC</name>
+                     <description>I2S clock selection</description>
+                     <bitOffset>23</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>MCO1</name>
+                     <description>Microcontroller clock output               1</description>
+                     <bitOffset>21</bitOffset>
+                     <bitWidth>2</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>RTCPRE</name>
+                     <description>HSE division factor for RTC               clock</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>5</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>PPRE2</name>
+                     <description>APB high-speed prescaler               (APB2)</description>
+                     <bitOffset>13</bitOffset>
+                     <bitWidth>3</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>PPRE1</name>
+                     <description>APB Low speed prescaler               (APB1)</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>3</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>HPRE</name>
+                     <description>AHB prescaler</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>4</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>SWS1</name>
+                     <description>System clock switch status</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-only</access>
+                  </field>
+                  <field>
+                     <name>SWS0</name>
+                     <description>System clock switch status</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-only</access>
+                  </field>
+                  <field>
+                     <name>SW1</name>
+                     <description>System clock switch</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>SW0</name>
+                     <description>System clock switch</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>CIR</name>
+               <displayName>CIR</displayName>
+               <description>clock interrupt register</description>
+               <addressOffset>0xC</addressOffset>
+               <size>0x20</size>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>CSSC</name>
+                     <description>Clock security system interrupt               clear</description>
+                     <bitOffset>23</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>write-only</access>
+                  </field>
+                  <field>
+                     <name>PLLSAIRDYC</name>
+                     <description>PLLSAI Ready Interrupt               Clear</description>
+                     <bitOffset>22</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>write-only</access>
+                  </field>
+                  <field>
+                     <name>PLLI2SRDYC</name>
+                     <description>PLLI2S ready interrupt               clear</description>
+                     <bitOffset>21</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>write-only</access>
+                  </field>
+                  <field>
+                     <name>PLLRDYC</name>
+                     <description>Main PLL(PLL) ready interrupt               clear</description>
+                     <bitOffset>20</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>write-only</access>
+                  </field>
+                  <field>
+                     <name>HSERDYC</name>
+                     <description>HSE ready interrupt clear</description>
+                     <bitOffset>19</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>write-only</access>
+                  </field>
+                  <field>
+                     <name>HSIRDYC</name>
+                     <description>HSI ready interrupt clear</description>
+                     <bitOffset>18</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>write-only</access>
+                  </field>
+                  <field>
+                     <name>LSERDYC</name>
+                     <description>LSE ready interrupt clear</description>
+                     <bitOffset>17</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>write-only</access>
+                  </field>
+                  <field>
+                     <name>LSIRDYC</name>
+                     <description>LSI ready interrupt clear</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>write-only</access>
+                  </field>
+                  <field>
+                     <name>PLLSAIRDYIE</name>
+                     <description>PLLSAI Ready Interrupt               Enable</description>
+                     <bitOffset>14</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>PLLI2SRDYIE</name>
+                     <description>PLLI2S ready interrupt               enable</description>
+                     <bitOffset>13</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>PLLRDYIE</name>
+                     <description>Main PLL (PLL) ready interrupt               enable</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>HSERDYIE</name>
+                     <description>HSE ready interrupt enable</description>
+                     <bitOffset>11</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>HSIRDYIE</name>
+                     <description>HSI ready interrupt enable</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>LSERDYIE</name>
+                     <description>LSE ready interrupt enable</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>LSIRDYIE</name>
+                     <description>LSI ready interrupt enable</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>CSSF</name>
+                     <description>Clock security system interrupt               flag</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-only</access>
+                  </field>
+                  <field>
+                     <name>PLLSAIRDYF</name>
+                     <description>PLLSAI ready interrupt               flag</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-only</access>
+                  </field>
+                  <field>
+                     <name>PLLI2SRDYF</name>
+                     <description>PLLI2S ready interrupt               flag</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-only</access>
+                  </field>
+                  <field>
+                     <name>PLLRDYF</name>
+                     <description>Main PLL (PLL) ready interrupt               flag</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-only</access>
+                  </field>
+                  <field>
+                     <name>HSERDYF</name>
+                     <description>HSE ready interrupt flag</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-only</access>
+                  </field>
+                  <field>
+                     <name>HSIRDYF</name>
+                     <description>HSI ready interrupt flag</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-only</access>
+                  </field>
+                  <field>
+                     <name>LSERDYF</name>
+                     <description>LSE ready interrupt flag</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-only</access>
+                  </field>
+                  <field>
+                     <name>LSIRDYF</name>
+                     <description>LSI ready interrupt flag</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-only</access>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>AHB1RSTR</name>
+               <displayName>AHB1RSTR</displayName>
+               <description>AHB1 peripheral reset register</description>
+               <addressOffset>0x10</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>OTGHSRST</name>
+                     <description>USB OTG HS module reset</description>
+                     <bitOffset>29</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>ETHMACRST</name>
+                     <description>Ethernet MAC reset</description>
+                     <bitOffset>25</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>DMA2DRST</name>
+                     <description>DMA2D reset</description>
+                     <bitOffset>23</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>DMA2RST</name>
+                     <description>DMA2 reset</description>
+                     <bitOffset>22</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>DMA1RST</name>
+                     <description>DMA2 reset</description>
+                     <bitOffset>21</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CRCRST</name>
+                     <description>CRC reset</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>GPIOKRST</name>
+                     <description>IO port K reset</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>GPIOJRST</name>
+                     <description>IO port J reset</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>GPIOIRST</name>
+                     <description>IO port I reset</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>GPIOHRST</name>
+                     <description>IO port H reset</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>GPIOGRST</name>
+                     <description>IO port G reset</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>GPIOFRST</name>
+                     <description>IO port F reset</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>GPIOERST</name>
+                     <description>IO port E reset</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>GPIODRST</name>
+                     <description>IO port D reset</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>GPIOCRST</name>
+                     <description>IO port C reset</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>GPIOBRST</name>
+                     <description>IO port B reset</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>GPIOARST</name>
+                     <description>IO port A reset</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>AHB2RSTR</name>
+               <displayName>AHB2RSTR</displayName>
+               <description>AHB2 peripheral reset register</description>
+               <addressOffset>0x14</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>OTGFSRST</name>
+                     <description>USB OTG FS module reset</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>RNGRST</name>
+                     <description>Random number generator module               reset</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>HSAHRST</name>
+                     <description>Hash module reset</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CRYPRST</name>
+                     <description>Cryptographic module reset</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>DCMIRST</name>
+                     <description>Camera interface reset</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>AHB3RSTR</name>
+               <displayName>AHB3RSTR</displayName>
+               <description>AHB3 peripheral reset register</description>
+               <addressOffset>0x18</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>FMCRST</name>
+                     <description>Flexible memory controller module               reset</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>QSPIRST</name>
+                     <description>Quad SPI memory controller               reset</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>APB1RSTR</name>
+               <displayName>APB1RSTR</displayName>
+               <description>APB1 peripheral reset register</description>
+               <addressOffset>0x20</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>TIM2RST</name>
+                     <description>TIM2 reset</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TIM3RST</name>
+                     <description>TIM3 reset</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TIM4RST</name>
+                     <description>TIM4 reset</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TIM5RST</name>
+                     <description>TIM5 reset</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TIM6RST</name>
+                     <description>TIM6 reset</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TIM7RST</name>
+                     <description>TIM7 reset</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TIM12RST</name>
+                     <description>TIM12 reset</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TIM13RST</name>
+                     <description>TIM13 reset</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TIM14RST</name>
+                     <description>TIM14 reset</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>WWDGRST</name>
+                     <description>Window watchdog reset</description>
+                     <bitOffset>11</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>SPI2RST</name>
+                     <description>SPI 2 reset</description>
+                     <bitOffset>14</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>SPI3RST</name>
+                     <description>SPI 3 reset</description>
+                     <bitOffset>15</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>UART2RST</name>
+                     <description>USART 2 reset</description>
+                     <bitOffset>17</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>UART3RST</name>
+                     <description>USART 3 reset</description>
+                     <bitOffset>18</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>UART4RST</name>
+                     <description>USART 4 reset</description>
+                     <bitOffset>19</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>UART5RST</name>
+                     <description>USART 5 reset</description>
+                     <bitOffset>20</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>I2C1RST</name>
+                     <description>I2C 1 reset</description>
+                     <bitOffset>21</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>I2C2RST</name>
+                     <description>I2C 2 reset</description>
+                     <bitOffset>22</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>I2C3RST</name>
+                     <description>I2C3 reset</description>
+                     <bitOffset>23</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CAN1RST</name>
+                     <description>CAN1 reset</description>
+                     <bitOffset>25</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CAN2RST</name>
+                     <description>CAN2 reset</description>
+                     <bitOffset>26</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>PWRRST</name>
+                     <description>Power interface reset</description>
+                     <bitOffset>28</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>DACRST</name>
+                     <description>DAC reset</description>
+                     <bitOffset>29</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>UART7RST</name>
+                     <description>UART7 reset</description>
+                     <bitOffset>30</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>UART8RST</name>
+                     <description>UART8 reset</description>
+                     <bitOffset>31</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>SPDIFRXRST</name>
+                     <description>SPDIF-RX reset</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CECRST</name>
+                     <description>HDMI-CEC reset</description>
+                     <bitOffset>27</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>LPTIM1RST</name>
+                     <description>Low power timer 1 reset</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>I2C4RST</name>
+                     <description>I2C 4 reset</description>
+                     <bitOffset>24</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>APB2RSTR</name>
+               <displayName>APB2RSTR</displayName>
+               <description>APB2 peripheral reset register</description>
+               <addressOffset>0x24</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>TIM1RST</name>
+                     <description>TIM1 reset</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TIM8RST</name>
+                     <description>TIM8 reset</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>USART1RST</name>
+                     <description>USART1 reset</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>USART6RST</name>
+                     <description>USART6 reset</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>ADCRST</name>
+                     <description>ADC interface reset (common to all               ADCs)</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>SPI1RST</name>
+                     <description>SPI 1 reset</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>SPI4RST</name>
+                     <description>SPI4 reset</description>
+                     <bitOffset>13</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>SYSCFGRST</name>
+                     <description>System configuration controller               reset</description>
+                     <bitOffset>14</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TIM9RST</name>
+                     <description>TIM9 reset</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TIM10RST</name>
+                     <description>TIM10 reset</description>
+                     <bitOffset>17</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TIM11RST</name>
+                     <description>TIM11 reset</description>
+                     <bitOffset>18</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>SPI5RST</name>
+                     <description>SPI5 reset</description>
+                     <bitOffset>20</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>SPI6RST</name>
+                     <description>SPI6 reset</description>
+                     <bitOffset>21</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>SAI1RST</name>
+                     <description>SAI1 reset</description>
+                     <bitOffset>22</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>LTDCRST</name>
+                     <description>LTDC reset</description>
+                     <bitOffset>26</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>SAI2RST</name>
+                     <description>SAI2 reset</description>
+                     <bitOffset>23</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>SDMMC1RST</name>
+                     <description>SDMMC1 reset</description>
+                     <bitOffset>11</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>AHB1ENR</name>
+               <displayName>AHB1ENR</displayName>
+               <description>AHB1 peripheral clock register</description>
+               <addressOffset>0x30</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00100000</resetValue>
+               <fields>
+                  <field>
+                     <name>OTGHSULPIEN</name>
+                     <description>USB OTG HSULPI clock               enable</description>
+                     <bitOffset>30</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>OTGHSEN</name>
+                     <description>USB OTG HS clock enable</description>
+                     <bitOffset>29</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>ETHMACPTPEN</name>
+                     <description>Ethernet PTP clock enable</description>
+                     <bitOffset>28</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>ETHMACRXEN</name>
+                     <description>Ethernet Reception clock               enable</description>
+                     <bitOffset>27</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>ETHMACTXEN</name>
+                     <description>Ethernet Transmission clock               enable</description>
+                     <bitOffset>26</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>ETHMACEN</name>
+                     <description>Ethernet MAC clock enable</description>
+                     <bitOffset>25</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>DMA2DEN</name>
+                     <description>DMA2D clock enable</description>
+                     <bitOffset>23</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>DMA2EN</name>
+                     <description>DMA2 clock enable</description>
+                     <bitOffset>22</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>DMA1EN</name>
+                     <description>DMA1 clock enable</description>
+                     <bitOffset>21</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CCMDATARAMEN</name>
+                     <description>CCM data RAM clock enable</description>
+                     <bitOffset>20</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>BKPSRAMEN</name>
+                     <description>Backup SRAM interface clock               enable</description>
+                     <bitOffset>18</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CRCEN</name>
+                     <description>CRC clock enable</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>GPIOKEN</name>
+                     <description>IO port K clock enable</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>GPIOJEN</name>
+                     <description>IO port J clock enable</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>GPIOIEN</name>
+                     <description>IO port I clock enable</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>GPIOHEN</name>
+                     <description>IO port H clock enable</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>GPIOGEN</name>
+                     <description>IO port G clock enable</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>GPIOFEN</name>
+                     <description>IO port F clock enable</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>GPIOEEN</name>
+                     <description>IO port E clock enable</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>GPIODEN</name>
+                     <description>IO port D clock enable</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>GPIOCEN</name>
+                     <description>IO port C clock enable</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>GPIOBEN</name>
+                     <description>IO port B clock enable</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>GPIOAEN</name>
+                     <description>IO port A clock enable</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>AHB2ENR</name>
+               <displayName>AHB2ENR</displayName>
+               <description>AHB2 peripheral clock enable           register</description>
+               <addressOffset>0x34</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>OTGFSEN</name>
+                     <description>USB OTG FS clock enable</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>RNGEN</name>
+                     <description>Random number generator clock               enable</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>HASHEN</name>
+                     <description>Hash modules clock enable</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CRYPEN</name>
+                     <description>Cryptographic modules clock               enable</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>DCMIEN</name>
+                     <description>Camera interface enable</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>AHB3ENR</name>
+               <displayName>AHB3ENR</displayName>
+               <description>AHB3 peripheral clock enable           register</description>
+               <addressOffset>0x38</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>FMCEN</name>
+                     <description>Flexible memory controller module clock               enable</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>QSPIEN</name>
+                     <description>Quad SPI memory controller clock               enable</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>APB1ENR</name>
+               <displayName>APB1ENR</displayName>
+               <description>APB1 peripheral clock enable           register</description>
+               <addressOffset>0x40</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>TIM2EN</name>
+                     <description>TIM2 clock enable</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TIM3EN</name>
+                     <description>TIM3 clock enable</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TIM4EN</name>
+                     <description>TIM4 clock enable</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TIM5EN</name>
+                     <description>TIM5 clock enable</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TIM6EN</name>
+                     <description>TIM6 clock enable</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TIM7EN</name>
+                     <description>TIM7 clock enable</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TIM12EN</name>
+                     <description>TIM12 clock enable</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TIM13EN</name>
+                     <description>TIM13 clock enable</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TIM14EN</name>
+                     <description>TIM14 clock enable</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>WWDGEN</name>
+                     <description>Window watchdog clock               enable</description>
+                     <bitOffset>11</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>SPI2EN</name>
+                     <description>SPI2 clock enable</description>
+                     <bitOffset>14</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>SPI3EN</name>
+                     <description>SPI3 clock enable</description>
+                     <bitOffset>15</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>USART2EN</name>
+                     <description>USART 2 clock enable</description>
+                     <bitOffset>17</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>USART3EN</name>
+                     <description>USART3 clock enable</description>
+                     <bitOffset>18</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>UART4EN</name>
+                     <description>UART4 clock enable</description>
+                     <bitOffset>19</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>UART5EN</name>
+                     <description>UART5 clock enable</description>
+                     <bitOffset>20</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>I2C1EN</name>
+                     <description>I2C1 clock enable</description>
+                     <bitOffset>21</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>I2C2EN</name>
+                     <description>I2C2 clock enable</description>
+                     <bitOffset>22</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>I2C3EN</name>
+                     <description>I2C3 clock enable</description>
+                     <bitOffset>23</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CAN1EN</name>
+                     <description>CAN 1 clock enable</description>
+                     <bitOffset>25</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CAN2EN</name>
+                     <description>CAN 2 clock enable</description>
+                     <bitOffset>26</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>PWREN</name>
+                     <description>Power interface clock               enable</description>
+                     <bitOffset>28</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>DACEN</name>
+                     <description>DAC interface clock enable</description>
+                     <bitOffset>29</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>UART7ENR</name>
+                     <description>UART7 clock enable</description>
+                     <bitOffset>30</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>UART8ENR</name>
+                     <description>UART8 clock enable</description>
+                     <bitOffset>31</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>SPDIFRXEN</name>
+                     <description>SPDIF-RX clock enable</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CECEN</name>
+                     <description>HDMI-CEN clock enable</description>
+                     <bitOffset>27</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>LPTMI1EN</name>
+                     <description>Low power timer 1 clock               enable</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>I2C4EN</name>
+                     <description>I2C4 clock enable</description>
+                     <bitOffset>24</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>APB2ENR</name>
+               <displayName>APB2ENR</displayName>
+               <description>APB2 peripheral clock enable           register</description>
+               <addressOffset>0x44</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>TIM1EN</name>
+                     <description>TIM1 clock enable</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TIM8EN</name>
+                     <description>TIM8 clock enable</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>USART1EN</name>
+                     <description>USART1 clock enable</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>USART6EN</name>
+                     <description>USART6 clock enable</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>ADC1EN</name>
+                     <description>ADC1 clock enable</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>ADC2EN</name>
+                     <description>ADC2 clock enable</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>ADC3EN</name>
+                     <description>ADC3 clock enable</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>SPI1EN</name>
+                     <description>SPI1 clock enable</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>SPI4ENR</name>
+                     <description>SPI4 clock enable</description>
+                     <bitOffset>13</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>SYSCFGEN</name>
+                     <description>System configuration controller clock               enable</description>
+                     <bitOffset>14</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TIM9EN</name>
+                     <description>TIM9 clock enable</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TIM10EN</name>
+                     <description>TIM10 clock enable</description>
+                     <bitOffset>17</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TIM11EN</name>
+                     <description>TIM11 clock enable</description>
+                     <bitOffset>18</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>SPI5ENR</name>
+                     <description>SPI5 clock enable</description>
+                     <bitOffset>20</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>SPI6ENR</name>
+                     <description>SPI6 clock enable</description>
+                     <bitOffset>21</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>SAI1EN</name>
+                     <description>SAI1 clock enable</description>
+                     <bitOffset>22</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>LTDCEN</name>
+                     <description>LTDC clock enable</description>
+                     <bitOffset>26</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>SAI2EN</name>
+                     <description>SAI2 clock enable</description>
+                     <bitOffset>23</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>SDMMC1EN</name>
+                     <description>SDMMC1 clock enable</description>
+                     <bitOffset>11</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>AHB1LPENR</name>
+               <displayName>AHB1LPENR</displayName>
+               <description>AHB1 peripheral clock enable in low power           mode register</description>
+               <addressOffset>0x50</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x7E6791FF</resetValue>
+               <fields>
+                  <field>
+                     <name>GPIOALPEN</name>
+                     <description>IO port A clock enable during sleep               mode</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>GPIOBLPEN</name>
+                     <description>IO port B clock enable during Sleep               mode</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>GPIOCLPEN</name>
+                     <description>IO port C clock enable during Sleep               mode</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>GPIODLPEN</name>
+                     <description>IO port D clock enable during Sleep               mode</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>GPIOELPEN</name>
+                     <description>IO port E clock enable during Sleep               mode</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>GPIOFLPEN</name>
+                     <description>IO port F clock enable during Sleep               mode</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>GPIOGLPEN</name>
+                     <description>IO port G clock enable during Sleep               mode</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>GPIOHLPEN</name>
+                     <description>IO port H clock enable during Sleep               mode</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>GPIOILPEN</name>
+                     <description>IO port I clock enable during Sleep               mode</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>GPIOJLPEN</name>
+                     <description>IO port J clock enable during Sleep               mode</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>GPIOKLPEN</name>
+                     <description>IO port K clock enable during Sleep               mode</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CRCLPEN</name>
+                     <description>CRC clock enable during Sleep               mode</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FLITFLPEN</name>
+                     <description>Flash interface clock enable during               Sleep mode</description>
+                     <bitOffset>15</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>SRAM1LPEN</name>
+                     <description>SRAM 1interface clock enable during               Sleep mode</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>SRAM2LPEN</name>
+                     <description>SRAM 2 interface clock enable during               Sleep mode</description>
+                     <bitOffset>17</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>BKPSRAMLPEN</name>
+                     <description>Backup SRAM interface clock enable               during Sleep mode</description>
+                     <bitOffset>18</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>SRAM3LPEN</name>
+                     <description>SRAM 3 interface clock enable during               Sleep mode</description>
+                     <bitOffset>19</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>DMA1LPEN</name>
+                     <description>DMA1 clock enable during Sleep               mode</description>
+                     <bitOffset>21</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>DMA2LPEN</name>
+                     <description>DMA2 clock enable during Sleep               mode</description>
+                     <bitOffset>22</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>DMA2DLPEN</name>
+                     <description>DMA2D clock enable during Sleep               mode</description>
+                     <bitOffset>23</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>ETHMACLPEN</name>
+                     <description>Ethernet MAC clock enable during Sleep               mode</description>
+                     <bitOffset>25</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>ETHMACTXLPEN</name>
+                     <description>Ethernet transmission clock enable               during Sleep mode</description>
+                     <bitOffset>26</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>ETHMACRXLPEN</name>
+                     <description>Ethernet reception clock enable during               Sleep mode</description>
+                     <bitOffset>27</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>ETHMACPTPLPEN</name>
+                     <description>Ethernet PTP clock enable during Sleep               mode</description>
+                     <bitOffset>28</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>OTGHSLPEN</name>
+                     <description>USB OTG HS clock enable during Sleep               mode</description>
+                     <bitOffset>29</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>OTGHSULPILPEN</name>
+                     <description>USB OTG HS ULPI clock enable during               Sleep mode</description>
+                     <bitOffset>30</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>AHB2LPENR</name>
+               <displayName>AHB2LPENR</displayName>
+               <description>AHB2 peripheral clock enable in low power           mode register</description>
+               <addressOffset>0x54</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x000000F1</resetValue>
+               <fields>
+                  <field>
+                     <name>OTGFSLPEN</name>
+                     <description>USB OTG FS clock enable during Sleep               mode</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>RNGLPEN</name>
+                     <description>Random number generator clock enable               during Sleep mode</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>HASHLPEN</name>
+                     <description>Hash modules clock enable during Sleep               mode</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CRYPLPEN</name>
+                     <description>Cryptography modules clock enable during               Sleep mode</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>DCMILPEN</name>
+                     <description>Camera interface enable during Sleep               mode</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>AHB3LPENR</name>
+               <displayName>AHB3LPENR</displayName>
+               <description>AHB3 peripheral clock enable in low power           mode register</description>
+               <addressOffset>0x58</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000001</resetValue>
+               <fields>
+                  <field>
+                     <name>FMCLPEN</name>
+                     <description>Flexible memory controller module clock               enable during Sleep mode</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>QSPILPEN</name>
+                     <description>Quand SPI memory controller clock enable               during Sleep mode</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>APB1LPENR</name>
+               <displayName>APB1LPENR</displayName>
+               <description>APB1 peripheral clock enable in low power           mode register</description>
+               <addressOffset>0x60</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x36FEC9FF</resetValue>
+               <fields>
+                  <field>
+                     <name>TIM2LPEN</name>
+                     <description>TIM2 clock enable during Sleep               mode</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TIM3LPEN</name>
+                     <description>TIM3 clock enable during Sleep               mode</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TIM4LPEN</name>
+                     <description>TIM4 clock enable during Sleep               mode</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TIM5LPEN</name>
+                     <description>TIM5 clock enable during Sleep               mode</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TIM6LPEN</name>
+                     <description>TIM6 clock enable during Sleep               mode</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TIM7LPEN</name>
+                     <description>TIM7 clock enable during Sleep               mode</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TIM12LPEN</name>
+                     <description>TIM12 clock enable during Sleep               mode</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TIM13LPEN</name>
+                     <description>TIM13 clock enable during Sleep               mode</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TIM14LPEN</name>
+                     <description>TIM14 clock enable during Sleep               mode</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>WWDGLPEN</name>
+                     <description>Window watchdog clock enable during               Sleep mode</description>
+                     <bitOffset>11</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>SPI2LPEN</name>
+                     <description>SPI2 clock enable during Sleep               mode</description>
+                     <bitOffset>14</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>SPI3LPEN</name>
+                     <description>SPI3 clock enable during Sleep               mode</description>
+                     <bitOffset>15</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>USART2LPEN</name>
+                     <description>USART2 clock enable during Sleep               mode</description>
+                     <bitOffset>17</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>USART3LPEN</name>
+                     <description>USART3 clock enable during Sleep               mode</description>
+                     <bitOffset>18</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>UART4LPEN</name>
+                     <description>UART4 clock enable during Sleep               mode</description>
+                     <bitOffset>19</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>UART5LPEN</name>
+                     <description>UART5 clock enable during Sleep               mode</description>
+                     <bitOffset>20</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>I2C1LPEN</name>
+                     <description>I2C1 clock enable during Sleep               mode</description>
+                     <bitOffset>21</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>I2C2LPEN</name>
+                     <description>I2C2 clock enable during Sleep               mode</description>
+                     <bitOffset>22</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>I2C3LPEN</name>
+                     <description>I2C3 clock enable during Sleep               mode</description>
+                     <bitOffset>23</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CAN1LPEN</name>
+                     <description>CAN 1 clock enable during Sleep               mode</description>
+                     <bitOffset>25</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CAN2LPEN</name>
+                     <description>CAN 2 clock enable during Sleep               mode</description>
+                     <bitOffset>26</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>PWRLPEN</name>
+                     <description>Power interface clock enable during               Sleep mode</description>
+                     <bitOffset>28</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>DACLPEN</name>
+                     <description>DAC interface clock enable during Sleep               mode</description>
+                     <bitOffset>29</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>UART7LPEN</name>
+                     <description>UART7 clock enable during Sleep               mode</description>
+                     <bitOffset>30</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>UART8LPEN</name>
+                     <description>UART8 clock enable during Sleep               mode</description>
+                     <bitOffset>31</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>SPDIFRXLPEN</name>
+                     <description>SPDIF-RX clock enable during sleep               mode</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CECLPEN</name>
+                     <description>HDMI-CEN clock enable during Sleep               mode</description>
+                     <bitOffset>27</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>LPTIM1LPEN</name>
+                     <description>low power timer 1 clock enable during               Sleep mode</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>I2C4LPEN</name>
+                     <description>I2C4 clock enable during Sleep               mode</description>
+                     <bitOffset>24</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>APB2LPENR</name>
+               <displayName>APB2LPENR</displayName>
+               <description>APB2 peripheral clock enabled in low power           mode register</description>
+               <addressOffset>0x64</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00075F33</resetValue>
+               <fields>
+                  <field>
+                     <name>TIM1LPEN</name>
+                     <description>TIM1 clock enable during Sleep               mode</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TIM8LPEN</name>
+                     <description>TIM8 clock enable during Sleep               mode</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>USART1LPEN</name>
+                     <description>USART1 clock enable during Sleep               mode</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>USART6LPEN</name>
+                     <description>USART6 clock enable during Sleep               mode</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>ADC1LPEN</name>
+                     <description>ADC1 clock enable during Sleep               mode</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>ADC2LPEN</name>
+                     <description>ADC2 clock enable during Sleep               mode</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>ADC3LPEN</name>
+                     <description>ADC 3 clock enable during Sleep               mode</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>SPI1LPEN</name>
+                     <description>SPI 1 clock enable during Sleep               mode</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>SPI4LPEN</name>
+                     <description>SPI 4 clock enable during Sleep               mode</description>
+                     <bitOffset>13</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>SYSCFGLPEN</name>
+                     <description>System configuration controller clock               enable during Sleep mode</description>
+                     <bitOffset>14</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TIM9LPEN</name>
+                     <description>TIM9 clock enable during sleep               mode</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TIM10LPEN</name>
+                     <description>TIM10 clock enable during Sleep               mode</description>
+                     <bitOffset>17</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TIM11LPEN</name>
+                     <description>TIM11 clock enable during Sleep               mode</description>
+                     <bitOffset>18</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>SPI5LPEN</name>
+                     <description>SPI 5 clock enable during Sleep               mode</description>
+                     <bitOffset>20</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>SPI6LPEN</name>
+                     <description>SPI 6 clock enable during Sleep               mode</description>
+                     <bitOffset>21</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>SAI1LPEN</name>
+                     <description>SAI1 clock enable during sleep               mode</description>
+                     <bitOffset>22</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>LTDCLPEN</name>
+                     <description>LTDC clock enable during sleep               mode</description>
+                     <bitOffset>26</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>SAI2LPEN</name>
+                     <description>SAI2 clock enable during sleep               mode</description>
+                     <bitOffset>23</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>SDMMC1LPEN</name>
+                     <description>SDMMC1 clock enable during Sleep               mode</description>
+                     <bitOffset>11</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>BDCR</name>
+               <displayName>BDCR</displayName>
+               <description>Backup domain control register</description>
+               <addressOffset>0x70</addressOffset>
+               <size>0x20</size>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>BDRST</name>
+                     <description>Backup domain software               reset</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>RTCEN</name>
+                     <description>RTC clock enable</description>
+                     <bitOffset>15</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>RTCSEL1</name>
+                     <description>RTC clock source selection</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>RTCSEL0</name>
+                     <description>RTC clock source selection</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>LSEBYP</name>
+                     <description>External low-speed oscillator               bypass</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>LSERDY</name>
+                     <description>External low-speed oscillator               ready</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-only</access>
+                  </field>
+                  <field>
+                     <name>LSEON</name>
+                     <description>External low-speed oscillator               enable</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>CSR</name>
+               <displayName>CSR</displayName>
+               <description>clock control &amp; status           register</description>
+               <addressOffset>0x74</addressOffset>
+               <size>0x20</size>
+               <resetValue>0x0E000000</resetValue>
+               <fields>
+                  <field>
+                     <name>LPWRRSTF</name>
+                     <description>Low-power reset flag</description>
+                     <bitOffset>31</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>WWDGRSTF</name>
+                     <description>Window watchdog reset flag</description>
+                     <bitOffset>30</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>WDGRSTF</name>
+                     <description>Independent watchdog reset               flag</description>
+                     <bitOffset>29</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>SFTRSTF</name>
+                     <description>Software reset flag</description>
+                     <bitOffset>28</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>PORRSTF</name>
+                     <description>POR/PDR reset flag</description>
+                     <bitOffset>27</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>PADRSTF</name>
+                     <description>PIN reset flag</description>
+                     <bitOffset>26</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>BORRSTF</name>
+                     <description>BOR reset flag</description>
+                     <bitOffset>25</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>RMVF</name>
+                     <description>Remove reset flag</description>
+                     <bitOffset>24</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>LSIRDY</name>
+                     <description>Internal low-speed oscillator               ready</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-only</access>
+                  </field>
+                  <field>
+                     <name>LSION</name>
+                     <description>Internal low-speed oscillator               enable</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>SSCGR</name>
+               <displayName>SSCGR</displayName>
+               <description>spread spectrum clock generation           register</description>
+               <addressOffset>0x80</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>SSCGEN</name>
+                     <description>Spread spectrum modulation               enable</description>
+                     <bitOffset>31</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>SPREADSEL</name>
+                     <description>Spread Select</description>
+                     <bitOffset>30</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>INCSTEP</name>
+                     <description>Incrementation step</description>
+                     <bitOffset>13</bitOffset>
+                     <bitWidth>15</bitWidth>
+                  </field>
+                  <field>
+                     <name>MODPER</name>
+                     <description>Modulation period</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>13</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>PLLI2SCFGR</name>
+               <displayName>PLLI2SCFGR</displayName>
+               <description>PLLI2S configuration register</description>
+               <addressOffset>0x84</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x20003000</resetValue>
+               <fields>
+                  <field>
+                     <name>PLLI2SR</name>
+                     <description>PLLI2S division factor for I2S               clocks</description>
+                     <bitOffset>28</bitOffset>
+                     <bitWidth>3</bitWidth>
+                  </field>
+                  <field>
+                     <name>PLLI2SQ</name>
+                     <description>PLLI2S division factor for SAI1               clock</description>
+                     <bitOffset>24</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+                  <field>
+                     <name>PLLI2SN</name>
+                     <description>PLLI2S multiplication factor for               VCO</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>9</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>PLLSAICFGR</name>
+               <displayName>PLLSAICFGR</displayName>
+               <description>PLL configuration register</description>
+               <addressOffset>0x88</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x20003000</resetValue>
+               <fields>
+                  <field>
+                     <name>PLLSAIN</name>
+                     <description>PLLSAI division factor for               VCO</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>9</bitWidth>
+                  </field>
+                  <field>
+                     <name>PLLSAIP</name>
+                     <description>PLLSAI division factor for 48MHz               clock</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>PLLSAIQ</name>
+                     <description>PLLSAI division factor for SAI               clock</description>
+                     <bitOffset>24</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+                  <field>
+                     <name>PLLSAIR</name>
+                     <description>PLLSAI division factor for LCD               clock</description>
+                     <bitOffset>28</bitOffset>
+                     <bitWidth>3</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DKCFGR1</name>
+               <displayName>DKCFGR1</displayName>
+               <description>dedicated clocks configuration           register</description>
+               <addressOffset>0x8C</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x20003000</resetValue>
+               <fields>
+                  <field>
+                     <name>PLLI2SDIV</name>
+                     <description>PLLI2S division factor for SAI1               clock</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>5</bitWidth>
+                  </field>
+                  <field>
+                     <name>PLLSAIDIVQ</name>
+                     <description>PLLSAI division factor for SAI1               clock</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>5</bitWidth>
+                  </field>
+                  <field>
+                     <name>PLLSAIDIVR</name>
+                     <description>division factor for               LCD_CLK</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>SAI1SEL</name>
+                     <description>SAI1 clock source               selection</description>
+                     <bitOffset>20</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>SAI2SEL</name>
+                     <description>SAI2 clock source               selection</description>
+                     <bitOffset>22</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>TIMPRE</name>
+                     <description>Timers clocks prescalers               selection</description>
+                     <bitOffset>24</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DKCFGR2</name>
+               <displayName>DKCFGR2</displayName>
+               <description>dedicated clocks configuration           register</description>
+               <addressOffset>0x90</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x20003000</resetValue>
+               <fields>
+                  <field>
+                     <name>USART1SEL</name>
+                     <description>USART 1 clock source               selection</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>USART2SEL</name>
+                     <description>USART 2 clock source               selection</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>USART3SEL</name>
+                     <description>USART 3 clock source               selection</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>UART4SEL</name>
+                     <description>UART 4 clock source               selection</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>UART5SEL</name>
+                     <description>UART 5 clock source               selection</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>USART6SEL</name>
+                     <description>USART 6 clock source               selection</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>UART7SEL</name>
+                     <description>UART 7 clock source               selection</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>UART8SEL</name>
+                     <description>UART 8 clock source               selection</description>
+                     <bitOffset>14</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>I2C1SEL</name>
+                     <description>I2C1 clock source               selection</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>I2C2SEL</name>
+                     <description>I2C2 clock source               selection</description>
+                     <bitOffset>18</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>I2C3SEL</name>
+                     <description>I2C3 clock source               selection</description>
+                     <bitOffset>20</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>I2C4SEL</name>
+                     <description>I2C4 clock source               selection</description>
+                     <bitOffset>22</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>LPTIM1SEL</name>
+                     <description>Low power timer 1 clock source               selection</description>
+                     <bitOffset>24</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>CECSEL</name>
+                     <description>HDMI-CEC clock source               selection</description>
+                     <bitOffset>26</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CK48MSEL</name>
+                     <description>48MHz clock source               selection</description>
+                     <bitOffset>27</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>SDMMCSEL</name>
+                     <description>SDMMC clock source               selection</description>
+                     <bitOffset>28</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+         </registers>
+      </peripheral>
+      <peripheral>
+         <name>GPIOD</name>
+         <description>General-purpose I/Os</description>
+         <groupName>GPIO</groupName>
+         <baseAddress>0X40020C00</baseAddress>
+         <addressBlock>
+            <offset>0x0</offset>
+            <size>0x400</size>
+            <usage>registers</usage>
+         </addressBlock>
+         <registers>
+            <register>
+               <name>MODER</name>
+               <displayName>MODER</displayName>
+               <description>GPIO port mode register</description>
+               <addressOffset>0x0</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>MODER15</name>
+                     <description>Port x configuration bits (y =               0..15)</description>
+                     <bitOffset>30</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>MODER14</name>
+                     <description>Port x configuration bits (y =               0..15)</description>
+                     <bitOffset>28</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>MODER13</name>
+                     <description>Port x configuration bits (y =               0..15)</description>
+                     <bitOffset>26</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>MODER12</name>
+                     <description>Port x configuration bits (y =               0..15)</description>
+                     <bitOffset>24</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>MODER11</name>
+                     <description>Port x configuration bits (y =               0..15)</description>
+                     <bitOffset>22</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>MODER10</name>
+                     <description>Port x configuration bits (y =               0..15)</description>
+                     <bitOffset>20</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>MODER9</name>
+                     <description>Port x configuration bits (y =               0..15)</description>
+                     <bitOffset>18</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>MODER8</name>
+                     <description>Port x configuration bits (y =               0..15)</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>MODER7</name>
+                     <description>Port x configuration bits (y =               0..15)</description>
+                     <bitOffset>14</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>MODER6</name>
+                     <description>Port x configuration bits (y =               0..15)</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>MODER5</name>
+                     <description>Port x configuration bits (y =               0..15)</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>MODER4</name>
+                     <description>Port x configuration bits (y =               0..15)</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>MODER3</name>
+                     <description>Port x configuration bits (y =               0..15)</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>MODER2</name>
+                     <description>Port x configuration bits (y =               0..15)</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>MODER1</name>
+                     <description>Port x configuration bits (y =               0..15)</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>MODER0</name>
+                     <description>Port x configuration bits (y =               0..15)</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTYPER</name>
+               <displayName>OTYPER</displayName>
+               <description>GPIO port output type register</description>
+               <addressOffset>0x4</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>OT15</name>
+                     <description>Port x configuration bits (y =               0..15)</description>
+                     <bitOffset>15</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>OT14</name>
+                     <description>Port x configuration bits (y =               0..15)</description>
+                     <bitOffset>14</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>OT13</name>
+                     <description>Port x configuration bits (y =               0..15)</description>
+                     <bitOffset>13</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>OT12</name>
+                     <description>Port x configuration bits (y =               0..15)</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>OT11</name>
+                     <description>Port x configuration bits (y =               0..15)</description>
+                     <bitOffset>11</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>OT10</name>
+                     <description>Port x configuration bits (y =               0..15)</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>OT9</name>
+                     <description>Port x configuration bits (y =               0..15)</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>OT8</name>
+                     <description>Port x configuration bits (y =               0..15)</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>OT7</name>
+                     <description>Port x configuration bits (y =               0..15)</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>OT6</name>
+                     <description>Port x configuration bits (y =               0..15)</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>OT5</name>
+                     <description>Port x configuration bits (y =               0..15)</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>OT4</name>
+                     <description>Port x configuration bits (y =               0..15)</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>OT3</name>
+                     <description>Port x configuration bits (y =               0..15)</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>OT2</name>
+                     <description>Port x configuration bits (y =               0..15)</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>OT1</name>
+                     <description>Port x configuration bits (y =               0..15)</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>OT0</name>
+                     <description>Port x configuration bits (y =               0..15)</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>GPIOB_OSPEEDR</name>
+               <displayName>GPIOB_OSPEEDR</displayName>
+               <description>GPIO port output speed           register</description>
+               <addressOffset>0x8</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>OSPEEDR15</name>
+                     <description>Port x configuration bits (y =               0..15)</description>
+                     <bitOffset>30</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>OSPEEDR14</name>
+                     <description>Port x configuration bits (y =               0..15)</description>
+                     <bitOffset>28</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>OSPEEDR13</name>
+                     <description>Port x configuration bits (y =               0..15)</description>
+                     <bitOffset>26</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>OSPEEDR12</name>
+                     <description>Port x configuration bits (y =               0..15)</description>
+                     <bitOffset>24</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>OSPEEDR11</name>
+                     <description>Port x configuration bits (y =               0..15)</description>
+                     <bitOffset>22</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>OSPEEDR10</name>
+                     <description>Port x configuration bits (y =               0..15)</description>
+                     <bitOffset>20</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>OSPEEDR9</name>
+                     <description>Port x configuration bits (y =               0..15)</description>
+                     <bitOffset>18</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>OSPEEDR8</name>
+                     <description>Port x configuration bits (y =               0..15)</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>OSPEEDR7</name>
+                     <description>Port x configuration bits (y =               0..15)</description>
+                     <bitOffset>14</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>OSPEEDR6</name>
+                     <description>Port x configuration bits (y =               0..15)</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>OSPEEDR5</name>
+                     <description>Port x configuration bits (y =               0..15)</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>OSPEEDR4</name>
+                     <description>Port x configuration bits (y =               0..15)</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>OSPEEDR3</name>
+                     <description>Port x configuration bits (y =               0..15)</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>OSPEEDR2</name>
+                     <description>Port x configuration bits (y =               0..15)</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>OSPEEDR1</name>
+                     <description>Port x configuration bits (y =               0..15)</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>OSPEEDR0</name>
+                     <description>Port x configuration bits (y =               0..15)</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>PUPDR</name>
+               <displayName>PUPDR</displayName>
+               <description>GPIO port pull-up/pull-down           register</description>
+               <addressOffset>0xC</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>PUPDR15</name>
+                     <description>Port x configuration bits (y =               0..15)</description>
+                     <bitOffset>30</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>PUPDR14</name>
+                     <description>Port x configuration bits (y =               0..15)</description>
+                     <bitOffset>28</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>PUPDR13</name>
+                     <description>Port x configuration bits (y =               0..15)</description>
+                     <bitOffset>26</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>PUPDR12</name>
+                     <description>Port x configuration bits (y =               0..15)</description>
+                     <bitOffset>24</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>PUPDR11</name>
+                     <description>Port x configuration bits (y =               0..15)</description>
+                     <bitOffset>22</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>PUPDR10</name>
+                     <description>Port x configuration bits (y =               0..15)</description>
+                     <bitOffset>20</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>PUPDR9</name>
+                     <description>Port x configuration bits (y =               0..15)</description>
+                     <bitOffset>18</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>PUPDR8</name>
+                     <description>Port x configuration bits (y =               0..15)</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>PUPDR7</name>
+                     <description>Port x configuration bits (y =               0..15)</description>
+                     <bitOffset>14</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>PUPDR6</name>
+                     <description>Port x configuration bits (y =               0..15)</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>PUPDR5</name>
+                     <description>Port x configuration bits (y =               0..15)</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>PUPDR4</name>
+                     <description>Port x configuration bits (y =               0..15)</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>PUPDR3</name>
+                     <description>Port x configuration bits (y =               0..15)</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>PUPDR2</name>
+                     <description>Port x configuration bits (y =               0..15)</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>PUPDR1</name>
+                     <description>Port x configuration bits (y =               0..15)</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>PUPDR0</name>
+                     <description>Port x configuration bits (y =               0..15)</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>IDR</name>
+               <displayName>IDR</displayName>
+               <description>GPIO port input data register</description>
+               <addressOffset>0x10</addressOffset>
+               <size>0x20</size>
+               <access>read-only</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>IDR15</name>
+                     <description>Port input data (y =               0..15)</description>
+                     <bitOffset>15</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>IDR14</name>
+                     <description>Port input data (y =               0..15)</description>
+                     <bitOffset>14</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>IDR13</name>
+                     <description>Port input data (y =               0..15)</description>
+                     <bitOffset>13</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>IDR12</name>
+                     <description>Port input data (y =               0..15)</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>IDR11</name>
+                     <description>Port input data (y =               0..15)</description>
+                     <bitOffset>11</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>IDR10</name>
+                     <description>Port input data (y =               0..15)</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>IDR9</name>
+                     <description>Port input data (y =               0..15)</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>IDR8</name>
+                     <description>Port input data (y =               0..15)</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>IDR7</name>
+                     <description>Port input data (y =               0..15)</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>IDR6</name>
+                     <description>Port input data (y =               0..15)</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>IDR5</name>
+                     <description>Port input data (y =               0..15)</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>IDR4</name>
+                     <description>Port input data (y =               0..15)</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>IDR3</name>
+                     <description>Port input data (y =               0..15)</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>IDR2</name>
+                     <description>Port input data (y =               0..15)</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>IDR1</name>
+                     <description>Port input data (y =               0..15)</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>IDR0</name>
+                     <description>Port input data (y =               0..15)</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>ODR</name>
+               <displayName>ODR</displayName>
+               <description>GPIO port output data register</description>
+               <addressOffset>0x14</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>ODR15</name>
+                     <description>Port output data (y =               0..15)</description>
+                     <bitOffset>15</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>ODR14</name>
+                     <description>Port output data (y =               0..15)</description>
+                     <bitOffset>14</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>ODR13</name>
+                     <description>Port output data (y =               0..15)</description>
+                     <bitOffset>13</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>ODR12</name>
+                     <description>Port output data (y =               0..15)</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>ODR11</name>
+                     <description>Port output data (y =               0..15)</description>
+                     <bitOffset>11</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>ODR10</name>
+                     <description>Port output data (y =               0..15)</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>ODR9</name>
+                     <description>Port output data (y =               0..15)</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>ODR8</name>
+                     <description>Port output data (y =               0..15)</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>ODR7</name>
+                     <description>Port output data (y =               0..15)</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>ODR6</name>
+                     <description>Port output data (y =               0..15)</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>ODR5</name>
+                     <description>Port output data (y =               0..15)</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>ODR4</name>
+                     <description>Port output data (y =               0..15)</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>ODR3</name>
+                     <description>Port output data (y =               0..15)</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>ODR2</name>
+                     <description>Port output data (y =               0..15)</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>ODR1</name>
+                     <description>Port output data (y =               0..15)</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>ODR0</name>
+                     <description>Port output data (y =               0..15)</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>BSRR</name>
+               <displayName>BSRR</displayName>
+               <description>GPIO port bit set/reset           register</description>
+               <addressOffset>0x18</addressOffset>
+               <size>0x20</size>
+               <access>write-only</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>BR15</name>
+                     <description>Port x reset bit y (y =               0..15)</description>
+                     <bitOffset>31</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>BR14</name>
+                     <description>Port x reset bit y (y =               0..15)</description>
+                     <bitOffset>30</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>BR13</name>
+                     <description>Port x reset bit y (y =               0..15)</description>
+                     <bitOffset>29</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>BR12</name>
+                     <description>Port x reset bit y (y =               0..15)</description>
+                     <bitOffset>28</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>BR11</name>
+                     <description>Port x reset bit y (y =               0..15)</description>
+                     <bitOffset>27</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>BR10</name>
+                     <description>Port x reset bit y (y =               0..15)</description>
+                     <bitOffset>26</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>BR9</name>
+                     <description>Port x reset bit y (y =               0..15)</description>
+                     <bitOffset>25</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>BR8</name>
+                     <description>Port x reset bit y (y =               0..15)</description>
+                     <bitOffset>24</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>BR7</name>
+                     <description>Port x reset bit y (y =               0..15)</description>
+                     <bitOffset>23</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>BR6</name>
+                     <description>Port x reset bit y (y =               0..15)</description>
+                     <bitOffset>22</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>BR5</name>
+                     <description>Port x reset bit y (y =               0..15)</description>
+                     <bitOffset>21</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>BR4</name>
+                     <description>Port x reset bit y (y =               0..15)</description>
+                     <bitOffset>20</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>BR3</name>
+                     <description>Port x reset bit y (y =               0..15)</description>
+                     <bitOffset>19</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>BR2</name>
+                     <description>Port x reset bit y (y =               0..15)</description>
+                     <bitOffset>18</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>BR1</name>
+                     <description>Port x reset bit y (y =               0..15)</description>
+                     <bitOffset>17</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>BR0</name>
+                     <description>Port x set bit y (y=               0..15)</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>BS15</name>
+                     <description>Port x set bit y (y=               0..15)</description>
+                     <bitOffset>15</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>BS14</name>
+                     <description>Port x set bit y (y=               0..15)</description>
+                     <bitOffset>14</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>BS13</name>
+                     <description>Port x set bit y (y=               0..15)</description>
+                     <bitOffset>13</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>BS12</name>
+                     <description>Port x set bit y (y=               0..15)</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>BS11</name>
+                     <description>Port x set bit y (y=               0..15)</description>
+                     <bitOffset>11</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>BS10</name>
+                     <description>Port x set bit y (y=               0..15)</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>BS9</name>
+                     <description>Port x set bit y (y=               0..15)</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>BS8</name>
+                     <description>Port x set bit y (y=               0..15)</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>BS7</name>
+                     <description>Port x set bit y (y=               0..15)</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>BS6</name>
+                     <description>Port x set bit y (y=               0..15)</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>BS5</name>
+                     <description>Port x set bit y (y=               0..15)</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>BS4</name>
+                     <description>Port x set bit y (y=               0..15)</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>BS3</name>
+                     <description>Port x set bit y (y=               0..15)</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>BS2</name>
+                     <description>Port x set bit y (y=               0..15)</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>BS1</name>
+                     <description>Port x set bit y (y=               0..15)</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>BS0</name>
+                     <description>Port x set bit y (y=               0..15)</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>LCKR</name>
+               <displayName>LCKR</displayName>
+               <description>GPIO port configuration lock           register</description>
+               <addressOffset>0x1C</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>LCKK</name>
+                     <description>Port x lock bit y (y=               0..15)</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>LCK15</name>
+                     <description>Port x lock bit y (y=               0..15)</description>
+                     <bitOffset>15</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>LCK14</name>
+                     <description>Port x lock bit y (y=               0..15)</description>
+                     <bitOffset>14</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>LCK13</name>
+                     <description>Port x lock bit y (y=               0..15)</description>
+                     <bitOffset>13</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>LCK12</name>
+                     <description>Port x lock bit y (y=               0..15)</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>LCK11</name>
+                     <description>Port x lock bit y (y=               0..15)</description>
+                     <bitOffset>11</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>LCK10</name>
+                     <description>Port x lock bit y (y=               0..15)</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>LCK9</name>
+                     <description>Port x lock bit y (y=               0..15)</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>LCK8</name>
+                     <description>Port x lock bit y (y=               0..15)</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>LCK7</name>
+                     <description>Port x lock bit y (y=               0..15)</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>LCK6</name>
+                     <description>Port x lock bit y (y=               0..15)</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>LCK5</name>
+                     <description>Port x lock bit y (y=               0..15)</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>LCK4</name>
+                     <description>Port x lock bit y (y=               0..15)</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>LCK3</name>
+                     <description>Port x lock bit y (y=               0..15)</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>LCK2</name>
+                     <description>Port x lock bit y (y=               0..15)</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>LCK1</name>
+                     <description>Port x lock bit y (y=               0..15)</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>LCK0</name>
+                     <description>Port x lock bit y (y=               0..15)</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>AFRL</name>
+               <displayName>AFRL</displayName>
+               <description>GPIO alternate function           lowregister</description>
+               <addressOffset>0x20</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>AFRL7</name>
+                     <description>Alternate function selection for port x               bit y (y = 0..7)</description>
+                     <bitOffset>28</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+                  <field>
+                     <name>AFRL6</name>
+                     <description>Alternate function selection for port x               bit y (y = 0..7)</description>
+                     <bitOffset>24</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+                  <field>
+                     <name>AFRL5</name>
+                     <description>Alternate function selection for port x               bit y (y = 0..7)</description>
+                     <bitOffset>20</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+                  <field>
+                     <name>AFRL4</name>
+                     <description>Alternate function selection for port x               bit y (y = 0..7)</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+                  <field>
+                     <name>AFRL3</name>
+                     <description>Alternate function selection for port x               bit y (y = 0..7)</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+                  <field>
+                     <name>AFRL2</name>
+                     <description>Alternate function selection for port x               bit y (y = 0..7)</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+                  <field>
+                     <name>AFRL1</name>
+                     <description>Alternate function selection for port x               bit y (y = 0..7)</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+                  <field>
+                     <name>AFRL0</name>
+                     <description>Alternate function selection for port x               bit y (y = 0..7)</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>AFRH</name>
+               <displayName>AFRH</displayName>
+               <description>GPIO alternate function high           register</description>
+               <addressOffset>0x24</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>AFRH15</name>
+                     <description>Alternate function selection for port x               bit y (y = 8..15)</description>
+                     <bitOffset>28</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+                  <field>
+                     <name>AFRH14</name>
+                     <description>Alternate function selection for port x               bit y (y = 8..15)</description>
+                     <bitOffset>24</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+                  <field>
+                     <name>AFRH13</name>
+                     <description>Alternate function selection for port x               bit y (y = 8..15)</description>
+                     <bitOffset>20</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+                  <field>
+                     <name>AFRH12</name>
+                     <description>Alternate function selection for port x               bit y (y = 8..15)</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+                  <field>
+                     <name>AFRH11</name>
+                     <description>Alternate function selection for port x               bit y (y = 8..15)</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+                  <field>
+                     <name>AFRH10</name>
+                     <description>Alternate function selection for port x               bit y (y = 8..15)</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+                  <field>
+                     <name>AFRH9</name>
+                     <description>Alternate function selection for port x               bit y (y = 8..15)</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+                  <field>
+                     <name>AFRH8</name>
+                     <description>Alternate function selection for port x               bit y (y = 8..15)</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>BRR</name>
+               <displayName>BRR</displayName>
+               <description>GPIO port bit reset register</description>
+               <addressOffset>0x28</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>BR0</name>
+                     <description>Port D Reset bit 0</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>BR1</name>
+                     <description>Port D Reset bit 1</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>BR2</name>
+                     <description>Port D Reset bit 2</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>BR3</name>
+                     <description>Port D Reset bit 3</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>BR4</name>
+                     <description>Port D Reset bit 4</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>BR5</name>
+                     <description>Port D Reset bit 5</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>BR6</name>
+                     <description>Port D Reset bit 6</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>BR7</name>
+                     <description>Port D Reset bit 7</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>BR8</name>
+                     <description>Port D Reset bit 8</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>BR9</name>
+                     <description>Port D Reset bit 9</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>BR10</name>
+                     <description>Port D Reset bit 10</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>BR11</name>
+                     <description>Port D Reset bit 11</description>
+                     <bitOffset>11</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>BR12</name>
+                     <description>Port D Reset bit 12</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>BR13</name>
+                     <description>Port D Reset bit 13</description>
+                     <bitOffset>13</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>BR14</name>
+                     <description>Port D Reset bit 14</description>
+                     <bitOffset>14</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>BR15</name>
+                     <description>Port D Reset bit 15</description>
+                     <bitOffset>15</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+         </registers>
+      </peripheral>
+      <peripheral derivedFrom="GPIOD">
+         <name>GPIOC</name>
+         <baseAddress>0x40020800</baseAddress>
+      </peripheral>
+      <peripheral derivedFrom="GPIOD">
+         <name>GPIOK</name>
+         <baseAddress>0X40022800</baseAddress>
+      </peripheral>
+      <peripheral derivedFrom="GPIOD">
+         <name>GPIOJ</name>
+         <baseAddress>0X40022400</baseAddress>
+      </peripheral>
+      <peripheral derivedFrom="GPIOD">
+         <name>GPIOI</name>
+         <baseAddress>0X40022000</baseAddress>
+      </peripheral>
+      <peripheral derivedFrom="GPIOD">
+         <name>GPIOH</name>
+         <baseAddress>0X40021C00</baseAddress>
+      </peripheral>
+      <peripheral derivedFrom="GPIOD">
+         <name>GPIOG</name>
+         <baseAddress>0X40021800</baseAddress>
+      </peripheral>
+      <peripheral derivedFrom="GPIOD">
+         <name>GPIOF</name>
+         <baseAddress>0X40021400</baseAddress>
+      </peripheral>
+      <peripheral derivedFrom="GPIOD">
+         <name>GPIOE</name>
+         <baseAddress>0X40021000</baseAddress>
+      </peripheral>
+      <peripheral>
+         <name>GPIOB</name>
+         <description>General-purpose I/Os</description>
+         <groupName>GPIO</groupName>
+         <baseAddress>0x40020400</baseAddress>
+         <addressBlock>
+            <offset>0x0</offset>
+            <size>0x400</size>
+            <usage>registers</usage>
+         </addressBlock>
+         <registers>
+            <register>
+               <name>MODER</name>
+               <displayName>MODER</displayName>
+               <description>GPIO port mode register</description>
+               <addressOffset>0x0</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000280</resetValue>
+               <fields>
+                  <field>
+                     <name>MODER15</name>
+                     <description>Port x configuration bits (y =               0..15)</description>
+                     <bitOffset>30</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>MODER14</name>
+                     <description>Port x configuration bits (y =               0..15)</description>
+                     <bitOffset>28</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>MODER13</name>
+                     <description>Port x configuration bits (y =               0..15)</description>
+                     <bitOffset>26</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>MODER12</name>
+                     <description>Port x configuration bits (y =               0..15)</description>
+                     <bitOffset>24</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>MODER11</name>
+                     <description>Port x configuration bits (y =               0..15)</description>
+                     <bitOffset>22</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>MODER10</name>
+                     <description>Port x configuration bits (y =               0..15)</description>
+                     <bitOffset>20</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>MODER9</name>
+                     <description>Port x configuration bits (y =               0..15)</description>
+                     <bitOffset>18</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>MODER8</name>
+                     <description>Port x configuration bits (y =               0..15)</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>MODER7</name>
+                     <description>Port x configuration bits (y =               0..15)</description>
+                     <bitOffset>14</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>MODER6</name>
+                     <description>Port x configuration bits (y =               0..15)</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>MODER5</name>
+                     <description>Port x configuration bits (y =               0..15)</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>MODER4</name>
+                     <description>Port x configuration bits (y =               0..15)</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>MODER3</name>
+                     <description>Port x configuration bits (y =               0..15)</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>MODER2</name>
+                     <description>Port x configuration bits (y =               0..15)</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>MODER1</name>
+                     <description>Port x configuration bits (y =               0..15)</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>MODER0</name>
+                     <description>Port x configuration bits (y =               0..15)</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTYPER</name>
+               <displayName>OTYPER</displayName>
+               <description>GPIO port output type register</description>
+               <addressOffset>0x4</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>OT15</name>
+                     <description>Port x configuration bits (y =               0..15)</description>
+                     <bitOffset>15</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>OT14</name>
+                     <description>Port x configuration bits (y =               0..15)</description>
+                     <bitOffset>14</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>OT13</name>
+                     <description>Port x configuration bits (y =               0..15)</description>
+                     <bitOffset>13</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>OT12</name>
+                     <description>Port x configuration bits (y =               0..15)</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>OT11</name>
+                     <description>Port x configuration bits (y =               0..15)</description>
+                     <bitOffset>11</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>OT10</name>
+                     <description>Port x configuration bits (y =               0..15)</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>OT9</name>
+                     <description>Port x configuration bits (y =               0..15)</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>OT8</name>
+                     <description>Port x configuration bits (y =               0..15)</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>OT7</name>
+                     <description>Port x configuration bits (y =               0..15)</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>OT6</name>
+                     <description>Port x configuration bits (y =               0..15)</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>OT5</name>
+                     <description>Port x configuration bits (y =               0..15)</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>OT4</name>
+                     <description>Port x configuration bits (y =               0..15)</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>OT3</name>
+                     <description>Port x configuration bits (y =               0..15)</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>OT2</name>
+                     <description>Port x configuration bits (y =               0..15)</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>OT1</name>
+                     <description>Port x configuration bits (y =               0..15)</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>OT0</name>
+                     <description>Port x configuration bits (y =               0..15)</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>GPIOB_OSPEEDR</name>
+               <displayName>GPIOB_OSPEEDR</displayName>
+               <description>GPIO port output speed           register</description>
+               <addressOffset>0x8</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x000000C0</resetValue>
+               <fields>
+                  <field>
+                     <name>OSPEEDR15</name>
+                     <description>Port x configuration bits (y =               0..15)</description>
+                     <bitOffset>30</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>OSPEEDR14</name>
+                     <description>Port x configuration bits (y =               0..15)</description>
+                     <bitOffset>28</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>OSPEEDR13</name>
+                     <description>Port x configuration bits (y =               0..15)</description>
+                     <bitOffset>26</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>OSPEEDR12</name>
+                     <description>Port x configuration bits (y =               0..15)</description>
+                     <bitOffset>24</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>OSPEEDR11</name>
+                     <description>Port x configuration bits (y =               0..15)</description>
+                     <bitOffset>22</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>OSPEEDR10</name>
+                     <description>Port x configuration bits (y =               0..15)</description>
+                     <bitOffset>20</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>OSPEEDR9</name>
+                     <description>Port x configuration bits (y =               0..15)</description>
+                     <bitOffset>18</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>OSPEEDR8</name>
+                     <description>Port x configuration bits (y =               0..15)</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>OSPEEDR7</name>
+                     <description>Port x configuration bits (y =               0..15)</description>
+                     <bitOffset>14</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>OSPEEDR6</name>
+                     <description>Port x configuration bits (y =               0..15)</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>OSPEEDR5</name>
+                     <description>Port x configuration bits (y =               0..15)</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>OSPEEDR4</name>
+                     <description>Port x configuration bits (y =               0..15)</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>OSPEEDR3</name>
+                     <description>Port x configuration bits (y =               0..15)</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>OSPEEDR2</name>
+                     <description>Port x configuration bits (y =               0..15)</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>OSPEEDR1</name>
+                     <description>Port x configuration bits (y =               0..15)</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>OSPEEDR0</name>
+                     <description>Port x configuration bits (y =               0..15)</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>PUPDR</name>
+               <displayName>PUPDR</displayName>
+               <description>GPIO port pull-up/pull-down           register</description>
+               <addressOffset>0xC</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000100</resetValue>
+               <fields>
+                  <field>
+                     <name>PUPDR15</name>
+                     <description>Port x configuration bits (y =               0..15)</description>
+                     <bitOffset>30</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>PUPDR14</name>
+                     <description>Port x configuration bits (y =               0..15)</description>
+                     <bitOffset>28</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>PUPDR13</name>
+                     <description>Port x configuration bits (y =               0..15)</description>
+                     <bitOffset>26</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>PUPDR12</name>
+                     <description>Port x configuration bits (y =               0..15)</description>
+                     <bitOffset>24</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>PUPDR11</name>
+                     <description>Port x configuration bits (y =               0..15)</description>
+                     <bitOffset>22</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>PUPDR10</name>
+                     <description>Port x configuration bits (y =               0..15)</description>
+                     <bitOffset>20</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>PUPDR9</name>
+                     <description>Port x configuration bits (y =               0..15)</description>
+                     <bitOffset>18</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>PUPDR8</name>
+                     <description>Port x configuration bits (y =               0..15)</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>PUPDR7</name>
+                     <description>Port x configuration bits (y =               0..15)</description>
+                     <bitOffset>14</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>PUPDR6</name>
+                     <description>Port x configuration bits (y =               0..15)</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>PUPDR5</name>
+                     <description>Port x configuration bits (y =               0..15)</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>PUPDR4</name>
+                     <description>Port x configuration bits (y =               0..15)</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>PUPDR3</name>
+                     <description>Port x configuration bits (y =               0..15)</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>PUPDR2</name>
+                     <description>Port x configuration bits (y =               0..15)</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>PUPDR1</name>
+                     <description>Port x configuration bits (y =               0..15)</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>PUPDR0</name>
+                     <description>Port x configuration bits (y =               0..15)</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>IDR</name>
+               <displayName>IDR</displayName>
+               <description>GPIO port input data register</description>
+               <addressOffset>0x10</addressOffset>
+               <size>0x20</size>
+               <access>read-only</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>IDR15</name>
+                     <description>Port input data (y =               0..15)</description>
+                     <bitOffset>15</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>IDR14</name>
+                     <description>Port input data (y =               0..15)</description>
+                     <bitOffset>14</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>IDR13</name>
+                     <description>Port input data (y =               0..15)</description>
+                     <bitOffset>13</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>IDR12</name>
+                     <description>Port input data (y =               0..15)</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>IDR11</name>
+                     <description>Port input data (y =               0..15)</description>
+                     <bitOffset>11</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>IDR10</name>
+                     <description>Port input data (y =               0..15)</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>IDR9</name>
+                     <description>Port input data (y =               0..15)</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>IDR8</name>
+                     <description>Port input data (y =               0..15)</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>IDR7</name>
+                     <description>Port input data (y =               0..15)</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>IDR6</name>
+                     <description>Port input data (y =               0..15)</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>IDR5</name>
+                     <description>Port input data (y =               0..15)</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>IDR4</name>
+                     <description>Port input data (y =               0..15)</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>IDR3</name>
+                     <description>Port input data (y =               0..15)</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>IDR2</name>
+                     <description>Port input data (y =               0..15)</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>IDR1</name>
+                     <description>Port input data (y =               0..15)</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>IDR0</name>
+                     <description>Port input data (y =               0..15)</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>ODR</name>
+               <displayName>ODR</displayName>
+               <description>GPIO port output data register</description>
+               <addressOffset>0x14</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>ODR15</name>
+                     <description>Port output data (y =               0..15)</description>
+                     <bitOffset>15</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>ODR14</name>
+                     <description>Port output data (y =               0..15)</description>
+                     <bitOffset>14</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>ODR13</name>
+                     <description>Port output data (y =               0..15)</description>
+                     <bitOffset>13</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>ODR12</name>
+                     <description>Port output data (y =               0..15)</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>ODR11</name>
+                     <description>Port output data (y =               0..15)</description>
+                     <bitOffset>11</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>ODR10</name>
+                     <description>Port output data (y =               0..15)</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>ODR9</name>
+                     <description>Port output data (y =               0..15)</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>ODR8</name>
+                     <description>Port output data (y =               0..15)</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>ODR7</name>
+                     <description>Port output data (y =               0..15)</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>ODR6</name>
+                     <description>Port output data (y =               0..15)</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>ODR5</name>
+                     <description>Port output data (y =               0..15)</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>ODR4</name>
+                     <description>Port output data (y =               0..15)</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>ODR3</name>
+                     <description>Port output data (y =               0..15)</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>ODR2</name>
+                     <description>Port output data (y =               0..15)</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>ODR1</name>
+                     <description>Port output data (y =               0..15)</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>ODR0</name>
+                     <description>Port output data (y =               0..15)</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>BSRR</name>
+               <displayName>BSRR</displayName>
+               <description>GPIO port bit set/reset           register</description>
+               <addressOffset>0x18</addressOffset>
+               <size>0x20</size>
+               <access>write-only</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>BR15</name>
+                     <description>Port x reset bit y (y =               0..15)</description>
+                     <bitOffset>31</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>BR14</name>
+                     <description>Port x reset bit y (y =               0..15)</description>
+                     <bitOffset>30</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>BR13</name>
+                     <description>Port x reset bit y (y =               0..15)</description>
+                     <bitOffset>29</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>BR12</name>
+                     <description>Port x reset bit y (y =               0..15)</description>
+                     <bitOffset>28</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>BR11</name>
+                     <description>Port x reset bit y (y =               0..15)</description>
+                     <bitOffset>27</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>BR10</name>
+                     <description>Port x reset bit y (y =               0..15)</description>
+                     <bitOffset>26</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>BR9</name>
+                     <description>Port x reset bit y (y =               0..15)</description>
+                     <bitOffset>25</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>BR8</name>
+                     <description>Port x reset bit y (y =               0..15)</description>
+                     <bitOffset>24</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>BR7</name>
+                     <description>Port x reset bit y (y =               0..15)</description>
+                     <bitOffset>23</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>BR6</name>
+                     <description>Port x reset bit y (y =               0..15)</description>
+                     <bitOffset>22</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>BR5</name>
+                     <description>Port x reset bit y (y =               0..15)</description>
+                     <bitOffset>21</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>BR4</name>
+                     <description>Port x reset bit y (y =               0..15)</description>
+                     <bitOffset>20</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>BR3</name>
+                     <description>Port x reset bit y (y =               0..15)</description>
+                     <bitOffset>19</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>BR2</name>
+                     <description>Port x reset bit y (y =               0..15)</description>
+                     <bitOffset>18</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>BR1</name>
+                     <description>Port x reset bit y (y =               0..15)</description>
+                     <bitOffset>17</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>BR0</name>
+                     <description>Port x set bit y (y=               0..15)</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>BS15</name>
+                     <description>Port x set bit y (y=               0..15)</description>
+                     <bitOffset>15</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>BS14</name>
+                     <description>Port x set bit y (y=               0..15)</description>
+                     <bitOffset>14</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>BS13</name>
+                     <description>Port x set bit y (y=               0..15)</description>
+                     <bitOffset>13</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>BS12</name>
+                     <description>Port x set bit y (y=               0..15)</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>BS11</name>
+                     <description>Port x set bit y (y=               0..15)</description>
+                     <bitOffset>11</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>BS10</name>
+                     <description>Port x set bit y (y=               0..15)</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>BS9</name>
+                     <description>Port x set bit y (y=               0..15)</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>BS8</name>
+                     <description>Port x set bit y (y=               0..15)</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>BS7</name>
+                     <description>Port x set bit y (y=               0..15)</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>BS6</name>
+                     <description>Port x set bit y (y=               0..15)</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>BS5</name>
+                     <description>Port x set bit y (y=               0..15)</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>BS4</name>
+                     <description>Port x set bit y (y=               0..15)</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>BS3</name>
+                     <description>Port x set bit y (y=               0..15)</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>BS2</name>
+                     <description>Port x set bit y (y=               0..15)</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>BS1</name>
+                     <description>Port x set bit y (y=               0..15)</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>BS0</name>
+                     <description>Port x set bit y (y=               0..15)</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>LCKR</name>
+               <displayName>LCKR</displayName>
+               <description>GPIO port configuration lock           register</description>
+               <addressOffset>0x1C</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>LCKK</name>
+                     <description>Port x lock bit y (y=               0..15)</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>LCK15</name>
+                     <description>Port x lock bit y (y=               0..15)</description>
+                     <bitOffset>15</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>LCK14</name>
+                     <description>Port x lock bit y (y=               0..15)</description>
+                     <bitOffset>14</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>LCK13</name>
+                     <description>Port x lock bit y (y=               0..15)</description>
+                     <bitOffset>13</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>LCK12</name>
+                     <description>Port x lock bit y (y=               0..15)</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>LCK11</name>
+                     <description>Port x lock bit y (y=               0..15)</description>
+                     <bitOffset>11</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>LCK10</name>
+                     <description>Port x lock bit y (y=               0..15)</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>LCK9</name>
+                     <description>Port x lock bit y (y=               0..15)</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>LCK8</name>
+                     <description>Port x lock bit y (y=               0..15)</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>LCK7</name>
+                     <description>Port x lock bit y (y=               0..15)</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>LCK6</name>
+                     <description>Port x lock bit y (y=               0..15)</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>LCK5</name>
+                     <description>Port x lock bit y (y=               0..15)</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>LCK4</name>
+                     <description>Port x lock bit y (y=               0..15)</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>LCK3</name>
+                     <description>Port x lock bit y (y=               0..15)</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>LCK2</name>
+                     <description>Port x lock bit y (y=               0..15)</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>LCK1</name>
+                     <description>Port x lock bit y (y=               0..15)</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>LCK0</name>
+                     <description>Port x lock bit y (y=               0..15)</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>AFRL</name>
+               <displayName>AFRL</displayName>
+               <description>GPIO alternate function low           register</description>
+               <addressOffset>0x20</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>AFRL7</name>
+                     <description>Alternate function selection for port x               bit y (y = 0..7)</description>
+                     <bitOffset>28</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+                  <field>
+                     <name>AFRL6</name>
+                     <description>Alternate function selection for port x               bit y (y = 0..7)</description>
+                     <bitOffset>24</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+                  <field>
+                     <name>AFRL5</name>
+                     <description>Alternate function selection for port x               bit y (y = 0..7)</description>
+                     <bitOffset>20</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+                  <field>
+                     <name>AFRL4</name>
+                     <description>Alternate function selection for port x               bit y (y = 0..7)</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+                  <field>
+                     <name>AFRL3</name>
+                     <description>Alternate function selection for port x               bit y (y = 0..7)</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+                  <field>
+                     <name>AFRL2</name>
+                     <description>Alternate function selection for port x               bit y (y = 0..7)</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+                  <field>
+                     <name>AFRL1</name>
+                     <description>Alternate function selection for port x               bit y (y = 0..7)</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+                  <field>
+                     <name>AFRL0</name>
+                     <description>Alternate function selection for port x               bit y (y = 0..7)</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>AFRH</name>
+               <displayName>AFRH</displayName>
+               <description>GPIO alternate function high           register</description>
+               <addressOffset>0x24</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>AFRH15</name>
+                     <description>Alternate function selection for port x               bit y (y = 8..15)</description>
+                     <bitOffset>28</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+                  <field>
+                     <name>AFRH14</name>
+                     <description>Alternate function selection for port x               bit y (y = 8..15)</description>
+                     <bitOffset>24</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+                  <field>
+                     <name>AFRH13</name>
+                     <description>Alternate function selection for port x               bit y (y = 8..15)</description>
+                     <bitOffset>20</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+                  <field>
+                     <name>AFRH12</name>
+                     <description>Alternate function selection for port x               bit y (y = 8..15)</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+                  <field>
+                     <name>AFRH11</name>
+                     <description>Alternate function selection for port x               bit y (y = 8..15)</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+                  <field>
+                     <name>AFRH10</name>
+                     <description>Alternate function selection for port x               bit y (y = 8..15)</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+                  <field>
+                     <name>AFRH9</name>
+                     <description>Alternate function selection for port x               bit y (y = 8..15)</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+                  <field>
+                     <name>AFRH8</name>
+                     <description>Alternate function selection for port x               bit y (y = 8..15)</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>BRR</name>
+               <displayName>BRR</displayName>
+               <description>GPIO port bit reset register</description>
+               <addressOffset>0x28</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>BR0</name>
+                     <description>Port B Reset bit 0</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>BR1</name>
+                     <description>Port B Reset bit 1</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>BR2</name>
+                     <description>Port B Reset bit 2</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>BR3</name>
+                     <description>Port B Reset bit 3</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>BR4</name>
+                     <description>Port B Reset bit 4</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>BR5</name>
+                     <description>Port B Reset bit 5</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>BR6</name>
+                     <description>Port B Reset bit 6</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>BR7</name>
+                     <description>Port B Reset bit 7</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>BR8</name>
+                     <description>Port B Reset bit 8</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>BR9</name>
+                     <description>Port B Reset bit 9</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>BR10</name>
+                     <description>Port B Reset bit 10</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>BR11</name>
+                     <description>Port B Reset bit 11</description>
+                     <bitOffset>11</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>BR12</name>
+                     <description>Port B Reset bit 12</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>BR13</name>
+                     <description>Port B Reset bit 13</description>
+                     <bitOffset>13</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>BR14</name>
+                     <description>Port B Reset bit 14</description>
+                     <bitOffset>14</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>BR15</name>
+                     <description>Port B Reset bit 15</description>
+                     <bitOffset>15</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+         </registers>
+      </peripheral>
+      <peripheral>
+         <name>GPIOA</name>
+         <description>General-purpose I/Os</description>
+         <groupName>GPIO</groupName>
+         <baseAddress>0x40020000</baseAddress>
+         <addressBlock>
+            <offset>0x0</offset>
+            <size>0x400</size>
+            <usage>registers</usage>
+         </addressBlock>
+         <registers>
+            <register>
+               <name>MODER</name>
+               <displayName>MODER</displayName>
+               <description>GPIO port mode register</description>
+               <addressOffset>0x0</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0xA8000000</resetValue>
+               <fields>
+                  <field>
+                     <name>MODER15</name>
+                     <description>Port x configuration bits (y =               0..15)</description>
+                     <bitOffset>30</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>MODER14</name>
+                     <description>Port x configuration bits (y =               0..15)</description>
+                     <bitOffset>28</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>MODER13</name>
+                     <description>Port x configuration bits (y =               0..15)</description>
+                     <bitOffset>26</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>MODER12</name>
+                     <description>Port x configuration bits (y =               0..15)</description>
+                     <bitOffset>24</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>MODER11</name>
+                     <description>Port x configuration bits (y =               0..15)</description>
+                     <bitOffset>22</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>MODER10</name>
+                     <description>Port x configuration bits (y =               0..15)</description>
+                     <bitOffset>20</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>MODER9</name>
+                     <description>Port x configuration bits (y =               0..15)</description>
+                     <bitOffset>18</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>MODER8</name>
+                     <description>Port x configuration bits (y =               0..15)</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>MODER7</name>
+                     <description>Port x configuration bits (y =               0..15)</description>
+                     <bitOffset>14</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>MODER6</name>
+                     <description>Port x configuration bits (y =               0..15)</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>MODER5</name>
+                     <description>Port x configuration bits (y =               0..15)</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>MODER4</name>
+                     <description>Port x configuration bits (y =               0..15)</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>MODER3</name>
+                     <description>Port x configuration bits (y =               0..15)</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>MODER2</name>
+                     <description>Port x configuration bits (y =               0..15)</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>MODER1</name>
+                     <description>Port x configuration bits (y =               0..15)</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>MODER0</name>
+                     <description>Port x configuration bits (y =               0..15)</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTYPER</name>
+               <displayName>OTYPER</displayName>
+               <description>GPIO port output type register</description>
+               <addressOffset>0x4</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>OT15</name>
+                     <description>Port x configuration bits (y =               0..15)</description>
+                     <bitOffset>15</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>OT14</name>
+                     <description>Port x configuration bits (y =               0..15)</description>
+                     <bitOffset>14</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>OT13</name>
+                     <description>Port x configuration bits (y =               0..15)</description>
+                     <bitOffset>13</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>OT12</name>
+                     <description>Port x configuration bits (y =               0..15)</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>OT11</name>
+                     <description>Port x configuration bits (y =               0..15)</description>
+                     <bitOffset>11</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>OT10</name>
+                     <description>Port x configuration bits (y =               0..15)</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>OT9</name>
+                     <description>Port x configuration bits (y =               0..15)</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>OT8</name>
+                     <description>Port x configuration bits (y =               0..15)</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>OT7</name>
+                     <description>Port x configuration bits (y =               0..15)</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>OT6</name>
+                     <description>Port x configuration bits (y =               0..15)</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>OT5</name>
+                     <description>Port x configuration bits (y =               0..15)</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>OT4</name>
+                     <description>Port x configuration bits (y =               0..15)</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>OT3</name>
+                     <description>Port x configuration bits (y =               0..15)</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>OT2</name>
+                     <description>Port x configuration bits (y =               0..15)</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>OT1</name>
+                     <description>Port x configuration bits (y =               0..15)</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>OT0</name>
+                     <description>Port x configuration bits (y =               0..15)</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>GPIOB_OSPEEDR</name>
+               <displayName>GPIOB_OSPEEDR</displayName>
+               <description>GPIO port output speed           register</description>
+               <addressOffset>0x8</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>OSPEEDR15</name>
+                     <description>Port x configuration bits (y =               0..15)</description>
+                     <bitOffset>30</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>OSPEEDR14</name>
+                     <description>Port x configuration bits (y =               0..15)</description>
+                     <bitOffset>28</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>OSPEEDR13</name>
+                     <description>Port x configuration bits (y =               0..15)</description>
+                     <bitOffset>26</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>OSPEEDR12</name>
+                     <description>Port x configuration bits (y =               0..15)</description>
+                     <bitOffset>24</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>OSPEEDR11</name>
+                     <description>Port x configuration bits (y =               0..15)</description>
+                     <bitOffset>22</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>OSPEEDR10</name>
+                     <description>Port x configuration bits (y =               0..15)</description>
+                     <bitOffset>20</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>OSPEEDR9</name>
+                     <description>Port x configuration bits (y =               0..15)</description>
+                     <bitOffset>18</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>OSPEEDR8</name>
+                     <description>Port x configuration bits (y =               0..15)</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>OSPEEDR7</name>
+                     <description>Port x configuration bits (y =               0..15)</description>
+                     <bitOffset>14</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>OSPEEDR6</name>
+                     <description>Port x configuration bits (y =               0..15)</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>OSPEEDR5</name>
+                     <description>Port x configuration bits (y =               0..15)</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>OSPEEDR4</name>
+                     <description>Port x configuration bits (y =               0..15)</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>OSPEEDR3</name>
+                     <description>Port x configuration bits (y =               0..15)</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>OSPEEDR2</name>
+                     <description>Port x configuration bits (y =               0..15)</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>OSPEEDR1</name>
+                     <description>Port x configuration bits (y =               0..15)</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>OSPEEDR0</name>
+                     <description>Port x configuration bits (y =               0..15)</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>PUPDR</name>
+               <displayName>PUPDR</displayName>
+               <description>GPIO port pull-up/pull-down           register</description>
+               <addressOffset>0xC</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x64000000</resetValue>
+               <fields>
+                  <field>
+                     <name>PUPDR15</name>
+                     <description>Port x configuration bits (y =               0..15)</description>
+                     <bitOffset>30</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>PUPDR14</name>
+                     <description>Port x configuration bits (y =               0..15)</description>
+                     <bitOffset>28</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>PUPDR13</name>
+                     <description>Port x configuration bits (y =               0..15)</description>
+                     <bitOffset>26</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>PUPDR12</name>
+                     <description>Port x configuration bits (y =               0..15)</description>
+                     <bitOffset>24</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>PUPDR11</name>
+                     <description>Port x configuration bits (y =               0..15)</description>
+                     <bitOffset>22</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>PUPDR10</name>
+                     <description>Port x configuration bits (y =               0..15)</description>
+                     <bitOffset>20</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>PUPDR9</name>
+                     <description>Port x configuration bits (y =               0..15)</description>
+                     <bitOffset>18</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>PUPDR8</name>
+                     <description>Port x configuration bits (y =               0..15)</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>PUPDR7</name>
+                     <description>Port x configuration bits (y =               0..15)</description>
+                     <bitOffset>14</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>PUPDR6</name>
+                     <description>Port x configuration bits (y =               0..15)</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>PUPDR5</name>
+                     <description>Port x configuration bits (y =               0..15)</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>PUPDR4</name>
+                     <description>Port x configuration bits (y =               0..15)</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>PUPDR3</name>
+                     <description>Port x configuration bits (y =               0..15)</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>PUPDR2</name>
+                     <description>Port x configuration bits (y =               0..15)</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>PUPDR1</name>
+                     <description>Port x configuration bits (y =               0..15)</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>PUPDR0</name>
+                     <description>Port x configuration bits (y =               0..15)</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>IDR</name>
+               <displayName>IDR</displayName>
+               <description>GPIO port input data register</description>
+               <addressOffset>0x10</addressOffset>
+               <size>0x20</size>
+               <access>read-only</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>IDR15</name>
+                     <description>Port input data (y =               0..15)</description>
+                     <bitOffset>15</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>IDR14</name>
+                     <description>Port input data (y =               0..15)</description>
+                     <bitOffset>14</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>IDR13</name>
+                     <description>Port input data (y =               0..15)</description>
+                     <bitOffset>13</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>IDR12</name>
+                     <description>Port input data (y =               0..15)</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>IDR11</name>
+                     <description>Port input data (y =               0..15)</description>
+                     <bitOffset>11</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>IDR10</name>
+                     <description>Port input data (y =               0..15)</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>IDR9</name>
+                     <description>Port input data (y =               0..15)</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>IDR8</name>
+                     <description>Port input data (y =               0..15)</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>IDR7</name>
+                     <description>Port input data (y =               0..15)</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>IDR6</name>
+                     <description>Port input data (y =               0..15)</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>IDR5</name>
+                     <description>Port input data (y =               0..15)</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>IDR4</name>
+                     <description>Port input data (y =               0..15)</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>IDR3</name>
+                     <description>Port input data (y =               0..15)</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>IDR2</name>
+                     <description>Port input data (y =               0..15)</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>IDR1</name>
+                     <description>Port input data (y =               0..15)</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>IDR0</name>
+                     <description>Port input data (y =               0..15)</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>ODR</name>
+               <displayName>ODR</displayName>
+               <description>GPIO port output data register</description>
+               <addressOffset>0x14</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>ODR15</name>
+                     <description>Port output data (y =               0..15)</description>
+                     <bitOffset>15</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>ODR14</name>
+                     <description>Port output data (y =               0..15)</description>
+                     <bitOffset>14</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>ODR13</name>
+                     <description>Port output data (y =               0..15)</description>
+                     <bitOffset>13</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>ODR12</name>
+                     <description>Port output data (y =               0..15)</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>ODR11</name>
+                     <description>Port output data (y =               0..15)</description>
+                     <bitOffset>11</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>ODR10</name>
+                     <description>Port output data (y =               0..15)</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>ODR9</name>
+                     <description>Port output data (y =               0..15)</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>ODR8</name>
+                     <description>Port output data (y =               0..15)</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>ODR7</name>
+                     <description>Port output data (y =               0..15)</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>ODR6</name>
+                     <description>Port output data (y =               0..15)</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>ODR5</name>
+                     <description>Port output data (y =               0..15)</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>ODR4</name>
+                     <description>Port output data (y =               0..15)</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>ODR3</name>
+                     <description>Port output data (y =               0..15)</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>ODR2</name>
+                     <description>Port output data (y =               0..15)</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>ODR1</name>
+                     <description>Port output data (y =               0..15)</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>ODR0</name>
+                     <description>Port output data (y =               0..15)</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>BSRR</name>
+               <displayName>BSRR</displayName>
+               <description>GPIO port bit set/reset           register</description>
+               <addressOffset>0x18</addressOffset>
+               <size>0x20</size>
+               <access>write-only</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>BR15</name>
+                     <description>Port x reset bit y (y =               0..15)</description>
+                     <bitOffset>31</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>BR14</name>
+                     <description>Port x reset bit y (y =               0..15)</description>
+                     <bitOffset>30</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>BR13</name>
+                     <description>Port x reset bit y (y =               0..15)</description>
+                     <bitOffset>29</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>BR12</name>
+                     <description>Port x reset bit y (y =               0..15)</description>
+                     <bitOffset>28</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>BR11</name>
+                     <description>Port x reset bit y (y =               0..15)</description>
+                     <bitOffset>27</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>BR10</name>
+                     <description>Port x reset bit y (y =               0..15)</description>
+                     <bitOffset>26</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>BR9</name>
+                     <description>Port x reset bit y (y =               0..15)</description>
+                     <bitOffset>25</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>BR8</name>
+                     <description>Port x reset bit y (y =               0..15)</description>
+                     <bitOffset>24</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>BR7</name>
+                     <description>Port x reset bit y (y =               0..15)</description>
+                     <bitOffset>23</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>BR6</name>
+                     <description>Port x reset bit y (y =               0..15)</description>
+                     <bitOffset>22</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>BR5</name>
+                     <description>Port x reset bit y (y =               0..15)</description>
+                     <bitOffset>21</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>BR4</name>
+                     <description>Port x reset bit y (y =               0..15)</description>
+                     <bitOffset>20</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>BR3</name>
+                     <description>Port x reset bit y (y =               0..15)</description>
+                     <bitOffset>19</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>BR2</name>
+                     <description>Port x reset bit y (y =               0..15)</description>
+                     <bitOffset>18</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>BR1</name>
+                     <description>Port x reset bit y (y =               0..15)</description>
+                     <bitOffset>17</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>BR0</name>
+                     <description>Port x set bit y (y=               0..15)</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>BS15</name>
+                     <description>Port x set bit y (y=               0..15)</description>
+                     <bitOffset>15</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>BS14</name>
+                     <description>Port x set bit y (y=               0..15)</description>
+                     <bitOffset>14</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>BS13</name>
+                     <description>Port x set bit y (y=               0..15)</description>
+                     <bitOffset>13</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>BS12</name>
+                     <description>Port x set bit y (y=               0..15)</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>BS11</name>
+                     <description>Port x set bit y (y=               0..15)</description>
+                     <bitOffset>11</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>BS10</name>
+                     <description>Port x set bit y (y=               0..15)</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>BS9</name>
+                     <description>Port x set bit y (y=               0..15)</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>BS8</name>
+                     <description>Port x set bit y (y=               0..15)</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>BS7</name>
+                     <description>Port x set bit y (y=               0..15)</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>BS6</name>
+                     <description>Port x set bit y (y=               0..15)</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>BS5</name>
+                     <description>Port x set bit y (y=               0..15)</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>BS4</name>
+                     <description>Port x set bit y (y=               0..15)</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>BS3</name>
+                     <description>Port x set bit y (y=               0..15)</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>BS2</name>
+                     <description>Port x set bit y (y=               0..15)</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>BS1</name>
+                     <description>Port x set bit y (y=               0..15)</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>BS0</name>
+                     <description>Port x set bit y (y=               0..15)</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>LCKR</name>
+               <displayName>LCKR</displayName>
+               <description>GPIO port configuration lock           register</description>
+               <addressOffset>0x1C</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>LCKK</name>
+                     <description>Port x lock bit y (y=               0..15)</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>LCK15</name>
+                     <description>Port x lock bit y (y=               0..15)</description>
+                     <bitOffset>15</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>LCK14</name>
+                     <description>Port x lock bit y (y=               0..15)</description>
+                     <bitOffset>14</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>LCK13</name>
+                     <description>Port x lock bit y (y=               0..15)</description>
+                     <bitOffset>13</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>LCK12</name>
+                     <description>Port x lock bit y (y=               0..15)</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>LCK11</name>
+                     <description>Port x lock bit y (y=               0..15)</description>
+                     <bitOffset>11</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>LCK10</name>
+                     <description>Port x lock bit y (y=               0..15)</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>LCK9</name>
+                     <description>Port x lock bit y (y=               0..15)</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>LCK8</name>
+                     <description>Port x lock bit y (y=               0..15)</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>LCK7</name>
+                     <description>Port x lock bit y (y=               0..15)</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>LCK6</name>
+                     <description>Port x lock bit y (y=               0..15)</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>LCK5</name>
+                     <description>Port x lock bit y (y=               0..15)</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>LCK4</name>
+                     <description>Port x lock bit y (y=               0..15)</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>LCK3</name>
+                     <description>Port x lock bit y (y=               0..15)</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>LCK2</name>
+                     <description>Port x lock bit y (y=               0..15)</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>LCK1</name>
+                     <description>Port x lock bit y (y=               0..15)</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>LCK0</name>
+                     <description>Port x lock bit y (y=               0..15)</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>AFRL</name>
+               <displayName>AFRL</displayName>
+               <description>GPIO alternate function low           register</description>
+               <addressOffset>0x20</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>AFRL7</name>
+                     <description>Alternate function selection for port x               bit y (y = 0..7)</description>
+                     <bitOffset>28</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+                  <field>
+                     <name>AFRL6</name>
+                     <description>Alternate function selection for port x               bit y (y = 0..7)</description>
+                     <bitOffset>24</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+                  <field>
+                     <name>AFRL5</name>
+                     <description>Alternate function selection for port x               bit y (y = 0..7)</description>
+                     <bitOffset>20</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+                  <field>
+                     <name>AFRL4</name>
+                     <description>Alternate function selection for port x               bit y (y = 0..7)</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+                  <field>
+                     <name>AFRL3</name>
+                     <description>Alternate function selection for port x               bit y (y = 0..7)</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+                  <field>
+                     <name>AFRL2</name>
+                     <description>Alternate function selection for port x               bit y (y = 0..7)</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+                  <field>
+                     <name>AFRL1</name>
+                     <description>Alternate function selection for port x               bit y (y = 0..7)</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+                  <field>
+                     <name>AFRL0</name>
+                     <description>Alternate function selection for port x               bit y (y = 0..7)</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>AFRH</name>
+               <displayName>AFRH</displayName>
+               <description>GPIO alternate function high           register</description>
+               <addressOffset>0x24</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>AFRH15</name>
+                     <description>Alternate function selection for port x               bit y (y = 8..15)</description>
+                     <bitOffset>28</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+                  <field>
+                     <name>AFRH14</name>
+                     <description>Alternate function selection for port x               bit y (y = 8..15)</description>
+                     <bitOffset>24</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+                  <field>
+                     <name>AFRH13</name>
+                     <description>Alternate function selection for port x               bit y (y = 8..15)</description>
+                     <bitOffset>20</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+                  <field>
+                     <name>AFRH12</name>
+                     <description>Alternate function selection for port x               bit y (y = 8..15)</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+                  <field>
+                     <name>AFRH11</name>
+                     <description>Alternate function selection for port x               bit y (y = 8..15)</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+                  <field>
+                     <name>AFRH10</name>
+                     <description>Alternate function selection for port x               bit y (y = 8..15)</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+                  <field>
+                     <name>AFRH9</name>
+                     <description>Alternate function selection for port x               bit y (y = 8..15)</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+                  <field>
+                     <name>AFRH8</name>
+                     <description>Alternate function selection for port x               bit y (y = 8..15)</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>BRR</name>
+               <displayName>BRR</displayName>
+               <description>GPIO port bit reset register</description>
+               <addressOffset>0x28</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>BR0</name>
+                     <description>Port A Reset bit 0</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>BR1</name>
+                     <description>Port A Reset bit 1</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>BR2</name>
+                     <description>Port A Reset bit 2</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>BR3</name>
+                     <description>Port A Reset bit 3</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>BR4</name>
+                     <description>Port A Reset bit 4</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>BR5</name>
+                     <description>Port A Reset bit 5</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>BR6</name>
+                     <description>Port A Reset bit 6</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>BR7</name>
+                     <description>Port A Reset bit 7</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>BR8</name>
+                     <description>Port A Reset bit 8</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>BR9</name>
+                     <description>Port A Reset bit 9</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>BR10</name>
+                     <description>Port A Reset bit 10</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>BR11</name>
+                     <description>Port A Reset bit 11</description>
+                     <bitOffset>11</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>BR12</name>
+                     <description>Port A Reset bit 12</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>BR13</name>
+                     <description>Port A Reset bit 13</description>
+                     <bitOffset>13</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>BR14</name>
+                     <description>Port A Reset bit 14</description>
+                     <bitOffset>14</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>BR15</name>
+                     <description>Port A Reset bit 15</description>
+                     <bitOffset>15</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+         </registers>
+      </peripheral>
+      <peripheral>
+         <name>SYSCFG</name>
+         <description>System configuration controller</description>
+         <groupName>SYSCFG</groupName>
+         <baseAddress>0x40013800</baseAddress>
+         <addressBlock>
+            <offset>0x0</offset>
+            <size>0x400</size>
+            <usage>registers</usage>
+         </addressBlock>
+         <registers>
+            <register>
+               <name>MEMRM</name>
+               <displayName>MEMRM</displayName>
+               <description>memory remap register</description>
+               <addressOffset>0x0</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>MEM_MODE</name>
+                     <description>Memory mapping selection</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>3</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB_MODE</name>
+                     <description>Flash bank mode selection</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>SWP_FMC</name>
+                     <description>FMC memory mapping swap</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>PMC</name>
+               <displayName>PMC</displayName>
+               <description>peripheral mode configuration           register</description>
+               <addressOffset>0x4</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>MII_RMII_SEL</name>
+                     <description>Ethernet PHY interface               selection</description>
+                     <bitOffset>23</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>ADC1DC2</name>
+                     <description>ADC1DC2</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>ADC2DC2</name>
+                     <description>ADC2DC2</description>
+                     <bitOffset>17</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>ADC3DC2</name>
+                     <description>ADC3DC2</description>
+                     <bitOffset>18</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>EXTICR1</name>
+               <displayName>EXTICR1</displayName>
+               <description>external interrupt configuration register           1</description>
+               <addressOffset>0x8</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x0000</resetValue>
+               <fields>
+                  <field>
+                     <name>EXTI3</name>
+                     <description>EXTI x configuration (x = 0 to               3)</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+                  <field>
+                     <name>EXTI2</name>
+                     <description>EXTI x configuration (x = 0 to               3)</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+                  <field>
+                     <name>EXTI1</name>
+                     <description>EXTI x configuration (x = 0 to               3)</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+                  <field>
+                     <name>EXTI0</name>
+                     <description>EXTI x configuration (x = 0 to               3)</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>EXTICR2</name>
+               <displayName>EXTICR2</displayName>
+               <description>external interrupt configuration register           2</description>
+               <addressOffset>0xC</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x0000</resetValue>
+               <fields>
+                  <field>
+                     <name>EXTI7</name>
+                     <description>EXTI x configuration (x = 4 to               7)</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+                  <field>
+                     <name>EXTI6</name>
+                     <description>EXTI x configuration (x = 4 to               7)</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+                  <field>
+                     <name>EXTI5</name>
+                     <description>EXTI x configuration (x = 4 to               7)</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+                  <field>
+                     <name>EXTI4</name>
+                     <description>EXTI x configuration (x = 4 to               7)</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>EXTICR3</name>
+               <displayName>EXTICR3</displayName>
+               <description>external interrupt configuration register           3</description>
+               <addressOffset>0x10</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x0000</resetValue>
+               <fields>
+                  <field>
+                     <name>EXTI11</name>
+                     <description>EXTI x configuration (x = 8 to               11)</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+                  <field>
+                     <name>EXTI10</name>
+                     <description>EXTI10</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+                  <field>
+                     <name>EXTI9</name>
+                     <description>EXTI x configuration (x = 8 to               11)</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+                  <field>
+                     <name>EXTI8</name>
+                     <description>EXTI x configuration (x = 8 to               11)</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>EXTICR4</name>
+               <displayName>EXTICR4</displayName>
+               <description>external interrupt configuration register           4</description>
+               <addressOffset>0x14</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x0000</resetValue>
+               <fields>
+                  <field>
+                     <name>EXTI15</name>
+                     <description>EXTI x configuration (x = 12 to               15)</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+                  <field>
+                     <name>EXTI14</name>
+                     <description>EXTI x configuration (x = 12 to               15)</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+                  <field>
+                     <name>EXTI13</name>
+                     <description>EXTI x configuration (x = 12 to               15)</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+                  <field>
+                     <name>EXTI12</name>
+                     <description>EXTI x configuration (x = 12 to               15)</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>CMPCR</name>
+               <displayName>CMPCR</displayName>
+               <description>Compensation cell control           register</description>
+               <addressOffset>0x20</addressOffset>
+               <size>0x20</size>
+               <access>read-only</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>READY</name>
+                     <description>READY</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CMP_PD</name>
+                     <description>Compensation cell               power-down</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+         </registers>
+      </peripheral>
+      <peripheral>
+         <name>SPI1</name>
+         <description>Serial peripheral interface</description>
+         <groupName>SPI</groupName>
+         <baseAddress>0x40013000</baseAddress>
+         <addressBlock>
+            <offset>0x0</offset>
+            <size>0x400</size>
+            <usage>registers</usage>
+         </addressBlock>
+         <interrupt>
+            <name>SPI1</name>
+            <description>SPI1 global interrupt</description>
+            <value>35</value>
+         </interrupt>
+         <registers>
+            <register>
+               <name>CR1</name>
+               <displayName>CR1</displayName>
+               <description>control register 1</description>
+               <addressOffset>0x0</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x0000</resetValue>
+               <fields>
+                  <field>
+                     <name>BIDIMODE</name>
+                     <description>Bidirectional data mode               enable</description>
+                     <bitOffset>15</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>BIDIOE</name>
+                     <description>Output enable in bidirectional               mode</description>
+                     <bitOffset>14</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CRCEN</name>
+                     <description>Hardware CRC calculation               enable</description>
+                     <bitOffset>13</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CRCNEXT</name>
+                     <description>CRC transfer next</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CRCL</name>
+                     <description>CRC length</description>
+                     <bitOffset>11</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>RXONLY</name>
+                     <description>Receive only</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>SSM</name>
+                     <description>Software slave management</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>SSI</name>
+                     <description>Internal slave select</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>LSBFIRST</name>
+                     <description>Frame format</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>SPE</name>
+                     <description>SPI enable</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>BR</name>
+                     <description>Baud rate control</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>3</bitWidth>
+                  </field>
+                  <field>
+                     <name>MSTR</name>
+                     <description>Master selection</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CPOL</name>
+                     <description>Clock polarity</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CPHA</name>
+                     <description>Clock phase</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>CR2</name>
+               <displayName>CR2</displayName>
+               <description>control register 2</description>
+               <addressOffset>0x4</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x0700</resetValue>
+               <fields>
+                  <field>
+                     <name>RXDMAEN</name>
+                     <description>Rx buffer DMA enable</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TXDMAEN</name>
+                     <description>Tx buffer DMA enable</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>SSOE</name>
+                     <description>SS output enable</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>NSSP</name>
+                     <description>NSS pulse management</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FRF</name>
+                     <description>Frame format</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>ERRIE</name>
+                     <description>Error interrupt enable</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>RXNEIE</name>
+                     <description>RX buffer not empty interrupt               enable</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TXEIE</name>
+                     <description>Tx buffer empty interrupt               enable</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>DS</name>
+                     <description>Data size</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+                  <field>
+                     <name>FRXTH</name>
+                     <description>FIFO reception threshold</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>LDMA_RX</name>
+                     <description>Last DMA transfer for               reception</description>
+                     <bitOffset>13</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>LDMA_TX</name>
+                     <description>Last DMA transfer for               transmission</description>
+                     <bitOffset>14</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>SR</name>
+               <displayName>SR</displayName>
+               <description>status register</description>
+               <addressOffset>0x8</addressOffset>
+               <size>0x20</size>
+               <resetValue>0x0002</resetValue>
+               <fields>
+                  <field>
+                     <name>FRE</name>
+                     <description>Frame format error</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-only</access>
+                  </field>
+                  <field>
+                     <name>BSY</name>
+                     <description>Busy flag</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-only</access>
+                  </field>
+                  <field>
+                     <name>OVR</name>
+                     <description>Overrun flag</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-only</access>
+                  </field>
+                  <field>
+                     <name>MODF</name>
+                     <description>Mode fault</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-only</access>
+                  </field>
+                  <field>
+                     <name>CRCERR</name>
+                     <description>CRC error flag</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>UDR</name>
+                     <description>Underrun flag</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-only</access>
+                  </field>
+                  <field>
+                     <name>CHSIDE</name>
+                     <description>Channel side</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-only</access>
+                  </field>
+                  <field>
+                     <name>TXE</name>
+                     <description>Transmit buffer empty</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-only</access>
+                  </field>
+                  <field>
+                     <name>RXNE</name>
+                     <description>Receive buffer not empty</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-only</access>
+                  </field>
+                  <field>
+                     <name>FRLVL</name>
+                     <description>FIFO reception level</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>2</bitWidth>
+                     <access>read-only</access>
+                  </field>
+                  <field>
+                     <name>FTLVL</name>
+                     <description>FIFO Transmission Level</description>
+                     <bitOffset>11</bitOffset>
+                     <bitWidth>2</bitWidth>
+                     <access>read-only</access>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DR</name>
+               <displayName>DR</displayName>
+               <description>data register</description>
+               <addressOffset>0xC</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x0000</resetValue>
+               <fields>
+                  <field>
+                     <name>DR</name>
+                     <description>Data register</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>CRCPR</name>
+               <displayName>CRCPR</displayName>
+               <description>CRC polynomial register</description>
+               <addressOffset>0x10</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x0007</resetValue>
+               <fields>
+                  <field>
+                     <name>CRCPOLY</name>
+                     <description>CRC polynomial register</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>RXCRCR</name>
+               <displayName>RXCRCR</displayName>
+               <description>RX CRC register</description>
+               <addressOffset>0x14</addressOffset>
+               <size>0x20</size>
+               <access>read-only</access>
+               <resetValue>0x0000</resetValue>
+               <fields>
+                  <field>
+                     <name>RxCRC</name>
+                     <description>Rx CRC register</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>TXCRCR</name>
+               <displayName>TXCRCR</displayName>
+               <description>TX CRC register</description>
+               <addressOffset>0x18</addressOffset>
+               <size>0x20</size>
+               <access>read-only</access>
+               <resetValue>0x0000</resetValue>
+               <fields>
+                  <field>
+                     <name>TxCRC</name>
+                     <description>Tx CRC register</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>I2SCFGR</name>
+               <displayName>I2SCFGR</displayName>
+               <description>I2S configuration register</description>
+               <addressOffset>0x1C</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x0000</resetValue>
+               <fields>
+                  <field>
+                     <name>I2SMOD</name>
+                     <description>I2S mode selection</description>
+                     <bitOffset>11</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>I2SE</name>
+                     <description>I2S Enable</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>I2SCFG</name>
+                     <description>I2S configuration mode</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>PCMSYNC</name>
+                     <description>PCM frame synchronization</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>I2SSTD</name>
+                     <description>I2S standard selection</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>CKPOL</name>
+                     <description>Steady state clock               polarity</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>DATLEN</name>
+                     <description>Data length to be               transferred</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>CHLEN</name>
+                     <description>Channel length (number of bits per audio               channel)</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>ASTRTEN</name>
+                     <description>Asynchronous start enable</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>I2SPR</name>
+               <displayName>I2SPR</displayName>
+               <description>I2S prescaler register</description>
+               <addressOffset>0x20</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>00000010</resetValue>
+               <fields>
+                  <field>
+                     <name>MCKOE</name>
+                     <description>Master clock output enable</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>ODD</name>
+                     <description>Odd factor for the               prescaler</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>I2SDIV</name>
+                     <description>I2S Linear prescaler</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+               </fields>
+            </register>
+         </registers>
+      </peripheral>
+      <peripheral derivedFrom="SPI1">
+         <name>SPI2</name>
+         <baseAddress>0x40003800</baseAddress>
+         <interrupt>
+            <name>SPI2</name>
+            <description>SPI2 global interrupt</description>
+            <value>36</value>
+         </interrupt>
+      </peripheral>
+      <peripheral derivedFrom="SPI1">
+         <name>SPI4</name>
+         <baseAddress>0x40013400</baseAddress>
+         <interrupt>
+            <name>SPI4</name>
+            <description>SPI 4 global interrupt</description>
+            <value>84</value>
+         </interrupt>
+      </peripheral>
+      <peripheral derivedFrom="SPI1">
+         <name>SPI5</name>
+         <baseAddress>0x40015000</baseAddress>
+         <interrupt>
+            <name>SPI5</name>
+            <description>SPI 5 global interrupt</description>
+            <value>85</value>
+         </interrupt>
+      </peripheral>
+      <peripheral derivedFrom="SPI1">
+         <name>SPI3</name>
+         <baseAddress>0x40003C00</baseAddress>
+         <interrupt>
+            <name>SPI3</name>
+            <description>SPI3 global interrupt</description>
+            <value>51</value>
+         </interrupt>
+      </peripheral>
+      <peripheral derivedFrom="SPI1">
+         <name>SPI6</name>
+         <baseAddress>0x40015400</baseAddress>
+         <interrupt>
+            <name>SPI6</name>
+            <description>SPI 6 global interrupt</description>
+            <value>86</value>
+         </interrupt>
+      </peripheral>
+      <peripheral>
+         <name>ADC1</name>
+         <description>Analog-to-digital converter</description>
+         <groupName>ADC</groupName>
+         <baseAddress>0x40012000</baseAddress>
+         <addressBlock>
+            <offset>0x0</offset>
+            <size>0x100</size>
+            <usage>registers</usage>
+         </addressBlock>
+         <interrupt>
+            <name>ADC</name>
+            <description>ADC1 global interrupt</description>
+            <value>18</value>
+         </interrupt>
+         <registers>
+            <register>
+               <name>SR</name>
+               <displayName>SR</displayName>
+               <description>status register</description>
+               <addressOffset>0x0</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>OVR</name>
+                     <description>Overrun</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>STRT</name>
+                     <description>Regular channel start flag</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>JSTRT</name>
+                     <description>Injected channel start               flag</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>JEOC</name>
+                     <description>Injected channel end of               conversion</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>EOC</name>
+                     <description>Regular channel end of               conversion</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>AWD</name>
+                     <description>Analog watchdog flag</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>CR1</name>
+               <displayName>CR1</displayName>
+               <description>control register 1</description>
+               <addressOffset>0x4</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>OVRIE</name>
+                     <description>Overrun interrupt enable</description>
+                     <bitOffset>26</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>RES</name>
+                     <description>Resolution</description>
+                     <bitOffset>24</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>AWDEN</name>
+                     <description>Analog watchdog enable on regular               channels</description>
+                     <bitOffset>23</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>JAWDEN</name>
+                     <description>Analog watchdog enable on injected               channels</description>
+                     <bitOffset>22</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>DISCNUM</name>
+                     <description>Discontinuous mode channel               count</description>
+                     <bitOffset>13</bitOffset>
+                     <bitWidth>3</bitWidth>
+                  </field>
+                  <field>
+                     <name>JDISCEN</name>
+                     <description>Discontinuous mode on injected               channels</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>DISCEN</name>
+                     <description>Discontinuous mode on regular               channels</description>
+                     <bitOffset>11</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>JAUTO</name>
+                     <description>Automatic injected group               conversion</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>AWDSGL</name>
+                     <description>Enable the watchdog on a single channel               in scan mode</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>SCAN</name>
+                     <description>Scan mode</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>JEOCIE</name>
+                     <description>Interrupt enable for injected               channels</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>AWDIE</name>
+                     <description>Analog watchdog interrupt               enable</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>EOCIE</name>
+                     <description>Interrupt enable for EOC</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>AWDCH</name>
+                     <description>Analog watchdog channel select               bits</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>5</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>CR2</name>
+               <displayName>CR2</displayName>
+               <description>control register 2</description>
+               <addressOffset>0x8</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>SWSTART</name>
+                     <description>Start conversion of regular               channels</description>
+                     <bitOffset>30</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>EXTEN</name>
+                     <description>External trigger enable for regular               channels</description>
+                     <bitOffset>28</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>EXTSEL</name>
+                     <description>External event select for regular               group</description>
+                     <bitOffset>24</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+                  <field>
+                     <name>JSWSTART</name>
+                     <description>Start conversion of injected               channels</description>
+                     <bitOffset>22</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>JEXTEN</name>
+                     <description>External trigger enable for injected               channels</description>
+                     <bitOffset>20</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>JEXTSEL</name>
+                     <description>External event select for injected               group</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+                  <field>
+                     <name>ALIGN</name>
+                     <description>Data alignment</description>
+                     <bitOffset>11</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>EOCS</name>
+                     <description>End of conversion               selection</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>DDS</name>
+                     <description>DMA disable selection (for single ADC               mode)</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>DMA</name>
+                     <description>Direct memory access mode (for single               ADC mode)</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CONT</name>
+                     <description>Continuous conversion</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>ADON</name>
+                     <description>A/D Converter ON / OFF</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>SMPR1</name>
+               <displayName>SMPR1</displayName>
+               <description>sample time register 1</description>
+               <addressOffset>0xC</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>SMPx_x</name>
+                     <description>Sample time bits</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>SMPR2</name>
+               <displayName>SMPR2</displayName>
+               <description>sample time register 2</description>
+               <addressOffset>0x10</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>SMPx_x</name>
+                     <description>Sample time bits</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>JOFR1</name>
+               <displayName>JOFR1</displayName>
+               <description>injected channel data offset register           x</description>
+               <addressOffset>0x14</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>JOFFSET1</name>
+                     <description>Data offset for injected channel               x</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>12</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>JOFR2</name>
+               <displayName>JOFR2</displayName>
+               <description>injected channel data offset register           x</description>
+               <addressOffset>0x18</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>JOFFSET2</name>
+                     <description>Data offset for injected channel               x</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>12</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>JOFR3</name>
+               <displayName>JOFR3</displayName>
+               <description>injected channel data offset register           x</description>
+               <addressOffset>0x1C</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>JOFFSET3</name>
+                     <description>Data offset for injected channel               x</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>12</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>JOFR4</name>
+               <displayName>JOFR4</displayName>
+               <description>injected channel data offset register           x</description>
+               <addressOffset>0x20</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>JOFFSET4</name>
+                     <description>Data offset for injected channel               x</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>12</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HTR</name>
+               <displayName>HTR</displayName>
+               <description>watchdog higher threshold           register</description>
+               <addressOffset>0x24</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000FFF</resetValue>
+               <fields>
+                  <field>
+                     <name>HT</name>
+                     <description>Analog watchdog higher               threshold</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>12</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>LTR</name>
+               <displayName>LTR</displayName>
+               <description>watchdog lower threshold           register</description>
+               <addressOffset>0x28</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>LT</name>
+                     <description>Analog watchdog lower               threshold</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>12</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>SQR1</name>
+               <displayName>SQR1</displayName>
+               <description>regular sequence register 1</description>
+               <addressOffset>0x2C</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>L</name>
+                     <description>Regular channel sequence               length</description>
+                     <bitOffset>20</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+                  <field>
+                     <name>SQ16</name>
+                     <description>16th conversion in regular               sequence</description>
+                     <bitOffset>15</bitOffset>
+                     <bitWidth>5</bitWidth>
+                  </field>
+                  <field>
+                     <name>SQ15</name>
+                     <description>15th conversion in regular               sequence</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>5</bitWidth>
+                  </field>
+                  <field>
+                     <name>SQ14</name>
+                     <description>14th conversion in regular               sequence</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>5</bitWidth>
+                  </field>
+                  <field>
+                     <name>SQ13</name>
+                     <description>13th conversion in regular               sequence</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>5</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>SQR2</name>
+               <displayName>SQR2</displayName>
+               <description>regular sequence register 2</description>
+               <addressOffset>0x30</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>SQ12</name>
+                     <description>12th conversion in regular               sequence</description>
+                     <bitOffset>25</bitOffset>
+                     <bitWidth>5</bitWidth>
+                  </field>
+                  <field>
+                     <name>SQ11</name>
+                     <description>11th conversion in regular               sequence</description>
+                     <bitOffset>20</bitOffset>
+                     <bitWidth>5</bitWidth>
+                  </field>
+                  <field>
+                     <name>SQ10</name>
+                     <description>10th conversion in regular               sequence</description>
+                     <bitOffset>15</bitOffset>
+                     <bitWidth>5</bitWidth>
+                  </field>
+                  <field>
+                     <name>SQ9</name>
+                     <description>9th conversion in regular               sequence</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>5</bitWidth>
+                  </field>
+                  <field>
+                     <name>SQ8</name>
+                     <description>8th conversion in regular               sequence</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>5</bitWidth>
+                  </field>
+                  <field>
+                     <name>SQ7</name>
+                     <description>7th conversion in regular               sequence</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>5</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>SQR3</name>
+               <displayName>SQR3</displayName>
+               <description>regular sequence register 3</description>
+               <addressOffset>0x34</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>SQ6</name>
+                     <description>6th conversion in regular               sequence</description>
+                     <bitOffset>25</bitOffset>
+                     <bitWidth>5</bitWidth>
+                  </field>
+                  <field>
+                     <name>SQ5</name>
+                     <description>5th conversion in regular               sequence</description>
+                     <bitOffset>20</bitOffset>
+                     <bitWidth>5</bitWidth>
+                  </field>
+                  <field>
+                     <name>SQ4</name>
+                     <description>4th conversion in regular               sequence</description>
+                     <bitOffset>15</bitOffset>
+                     <bitWidth>5</bitWidth>
+                  </field>
+                  <field>
+                     <name>SQ3</name>
+                     <description>3rd conversion in regular               sequence</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>5</bitWidth>
+                  </field>
+                  <field>
+                     <name>SQ2</name>
+                     <description>2nd conversion in regular               sequence</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>5</bitWidth>
+                  </field>
+                  <field>
+                     <name>SQ1</name>
+                     <description>1st conversion in regular               sequence</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>5</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>JSQR</name>
+               <displayName>JSQR</displayName>
+               <description>injected sequence register</description>
+               <addressOffset>0x38</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>JL</name>
+                     <description>Injected sequence length</description>
+                     <bitOffset>20</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>JSQ4</name>
+                     <description>4th conversion in injected               sequence</description>
+                     <bitOffset>15</bitOffset>
+                     <bitWidth>5</bitWidth>
+                  </field>
+                  <field>
+                     <name>JSQ3</name>
+                     <description>3rd conversion in injected               sequence</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>5</bitWidth>
+                  </field>
+                  <field>
+                     <name>JSQ2</name>
+                     <description>2nd conversion in injected               sequence</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>5</bitWidth>
+                  </field>
+                  <field>
+                     <name>JSQ1</name>
+                     <description>1st conversion in injected               sequence</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>5</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>JDR1</name>
+               <displayName>JDR1</displayName>
+               <description>injected data register x</description>
+               <addressOffset>0x3C</addressOffset>
+               <size>0x20</size>
+               <access>read-only</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>JDATA</name>
+                     <description>Injected data</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>JDR2</name>
+               <displayName>JDR2</displayName>
+               <description>injected data register x</description>
+               <addressOffset>0x40</addressOffset>
+               <size>0x20</size>
+               <access>read-only</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>JDATA</name>
+                     <description>Injected data</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>JDR3</name>
+               <displayName>JDR3</displayName>
+               <description>injected data register x</description>
+               <addressOffset>0x44</addressOffset>
+               <size>0x20</size>
+               <access>read-only</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>JDATA</name>
+                     <description>Injected data</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>JDR4</name>
+               <displayName>JDR4</displayName>
+               <description>injected data register x</description>
+               <addressOffset>0x48</addressOffset>
+               <size>0x20</size>
+               <access>read-only</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>JDATA</name>
+                     <description>Injected data</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DR</name>
+               <displayName>DR</displayName>
+               <description>regular data register</description>
+               <addressOffset>0x4C</addressOffset>
+               <size>0x20</size>
+               <access>read-only</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DATA</name>
+                     <description>Regular data</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+               </fields>
+            </register>
+         </registers>
+      </peripheral>
+      <peripheral derivedFrom="ADC1">
+         <name>ADC2</name>
+         <baseAddress>0x40012100</baseAddress>
+      </peripheral>
+      <peripheral derivedFrom="ADC1">
+         <name>ADC3</name>
+         <baseAddress>0x40012200</baseAddress>
+      </peripheral>
+      <peripheral>
+         <name>DAC</name>
+         <description>Digital-to-analog converter</description>
+         <groupName>DAC</groupName>
+         <baseAddress>0x40007400</baseAddress>
+         <addressBlock>
+            <offset>0x0</offset>
+            <size>0x400</size>
+            <usage>registers</usage>
+         </addressBlock>
+         <registers>
+            <register>
+               <name>CR</name>
+               <displayName>CR</displayName>
+               <description>control register</description>
+               <addressOffset>0x0</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DMAUDRIE2</name>
+                     <description>DAC channel2 DMA underrun interrupt               enable</description>
+                     <bitOffset>29</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>DMAEN2</name>
+                     <description>DAC channel2 DMA enable</description>
+                     <bitOffset>28</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>MAMP2</name>
+                     <description>DAC channel2 mask/amplitude               selector</description>
+                     <bitOffset>24</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+                  <field>
+                     <name>WAVE2</name>
+                     <description>DAC channel2 noise/triangle wave               generation enable</description>
+                     <bitOffset>22</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>TSEL2</name>
+                     <description>DAC channel2 trigger               selection</description>
+                     <bitOffset>19</bitOffset>
+                     <bitWidth>3</bitWidth>
+                  </field>
+                  <field>
+                     <name>TEN2</name>
+                     <description>DAC channel2 trigger               enable</description>
+                     <bitOffset>18</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>BOFF2</name>
+                     <description>DAC channel2 output buffer               disable</description>
+                     <bitOffset>17</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>EN2</name>
+                     <description>DAC channel2 enable</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>DMAUDRIE1</name>
+                     <description>DAC channel1 DMA Underrun Interrupt               enable</description>
+                     <bitOffset>13</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>DMAEN1</name>
+                     <description>DAC channel1 DMA enable</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>MAMP1</name>
+                     <description>DAC channel1 mask/amplitude               selector</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+                  <field>
+                     <name>WAVE1</name>
+                     <description>DAC channel1 noise/triangle wave               generation enable</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>TSEL1</name>
+                     <description>DAC channel1 trigger               selection</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>3</bitWidth>
+                  </field>
+                  <field>
+                     <name>TEN1</name>
+                     <description>DAC channel1 trigger               enable</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>BOFF1</name>
+                     <description>DAC channel1 output buffer               disable</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>EN1</name>
+                     <description>DAC channel1 enable</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>SWTRIGR</name>
+               <displayName>SWTRIGR</displayName>
+               <description>software trigger register</description>
+               <addressOffset>0x4</addressOffset>
+               <size>0x20</size>
+               <access>write-only</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>SWTRIG2</name>
+                     <description>DAC channel2 software               trigger</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>SWTRIG1</name>
+                     <description>DAC channel1 software               trigger</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DHR12R1</name>
+               <displayName>DHR12R1</displayName>
+               <description>channel1 12-bit right-aligned data holding           register</description>
+               <addressOffset>0x8</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DACC1DHR</name>
+                     <description>DAC channel1 12-bit right-aligned               data</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>12</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DHR12L1</name>
+               <displayName>DHR12L1</displayName>
+               <description>channel1 12-bit left aligned data holding           register</description>
+               <addressOffset>0xC</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DACC1DHR</name>
+                     <description>DAC channel1 12-bit left-aligned               data</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>12</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DHR8R1</name>
+               <displayName>DHR8R1</displayName>
+               <description>channel1 8-bit right aligned data holding           register</description>
+               <addressOffset>0x10</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DACC1DHR</name>
+                     <description>DAC channel1 8-bit right-aligned               data</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DHR12R2</name>
+               <displayName>DHR12R2</displayName>
+               <description>channel2 12-bit right aligned data holding           register</description>
+               <addressOffset>0x14</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DACC2DHR</name>
+                     <description>DAC channel2 12-bit right-aligned               data</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>12</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DHR12L2</name>
+               <displayName>DHR12L2</displayName>
+               <description>channel2 12-bit left aligned data holding           register</description>
+               <addressOffset>0x18</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DACC2DHR</name>
+                     <description>DAC channel2 12-bit left-aligned               data</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>12</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DHR8R2</name>
+               <displayName>DHR8R2</displayName>
+               <description>channel2 8-bit right-aligned data holding           register</description>
+               <addressOffset>0x1C</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DACC2DHR</name>
+                     <description>DAC channel2 8-bit right-aligned               data</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DHR12RD</name>
+               <displayName>DHR12RD</displayName>
+               <description>Dual DAC 12-bit right-aligned data holding           register</description>
+               <addressOffset>0x20</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DACC2DHR</name>
+                     <description>DAC channel2 12-bit right-aligned               data</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>12</bitWidth>
+                  </field>
+                  <field>
+                     <name>DACC1DHR</name>
+                     <description>DAC channel1 12-bit right-aligned               data</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>12</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DHR12LD</name>
+               <displayName>DHR12LD</displayName>
+               <description>DUAL DAC 12-bit left aligned data holding           register</description>
+               <addressOffset>0x24</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DACC2DHR</name>
+                     <description>DAC channel2 12-bit left-aligned               data</description>
+                     <bitOffset>20</bitOffset>
+                     <bitWidth>12</bitWidth>
+                  </field>
+                  <field>
+                     <name>DACC1DHR</name>
+                     <description>DAC channel1 12-bit left-aligned               data</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>12</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DHR8RD</name>
+               <displayName>DHR8RD</displayName>
+               <description>DUAL DAC 8-bit right aligned data holding           register</description>
+               <addressOffset>0x28</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DACC2DHR</name>
+                     <description>DAC channel2 8-bit right-aligned               data</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+                  <field>
+                     <name>DACC1DHR</name>
+                     <description>DAC channel1 8-bit right-aligned               data</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DOR1</name>
+               <displayName>DOR1</displayName>
+               <description>channel1 data output register</description>
+               <addressOffset>0x2C</addressOffset>
+               <size>0x20</size>
+               <access>read-only</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DACC1DOR</name>
+                     <description>DAC channel1 data output</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>12</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DOR2</name>
+               <displayName>DOR2</displayName>
+               <description>channel2 data output register</description>
+               <addressOffset>0x30</addressOffset>
+               <size>0x20</size>
+               <access>read-only</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DACC2DOR</name>
+                     <description>DAC channel2 data output</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>12</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>SR</name>
+               <displayName>SR</displayName>
+               <description>status register</description>
+               <addressOffset>0x34</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DMAUDR2</name>
+                     <description>DAC channel2 DMA underrun               flag</description>
+                     <bitOffset>29</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>DMAUDR1</name>
+                     <description>DAC channel1 DMA underrun               flag</description>
+                     <bitOffset>13</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+         </registers>
+      </peripheral>
+      <peripheral>
+         <name>PWR</name>
+         <description>Power control</description>
+         <groupName>PWR</groupName>
+         <baseAddress>0x40007000</baseAddress>
+         <addressBlock>
+            <offset>0x0</offset>
+            <size>0x400</size>
+            <usage>registers</usage>
+         </addressBlock>
+         <registers>
+            <register>
+               <name>CR1</name>
+               <displayName>CR1</displayName>
+               <description>power control register</description>
+               <addressOffset>0x0</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x0000C000</resetValue>
+               <fields>
+                  <field>
+                     <name>LPDS</name>
+                     <description>Low-power deep sleep</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>PDDS</name>
+                     <description>Power down deepsleep</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CSBF</name>
+                     <description>Clear standby flag</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>PVDE</name>
+                     <description>Power voltage detector               enable</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>PLS</name>
+                     <description>PVD level selection</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>3</bitWidth>
+                  </field>
+                  <field>
+                     <name>DBP</name>
+                     <description>Disable backup domain write               protection</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FPDS</name>
+                     <description>Flash power down in Stop               mode</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>LPUDS</name>
+                     <description>Low-power regulator in deepsleep               under-drive mode</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>MRUDS</name>
+                     <description>Main regulator in deepsleep under-drive               mode</description>
+                     <bitOffset>11</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>ADCDC1</name>
+                     <description>ADCDC1</description>
+                     <bitOffset>13</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>VOS</name>
+                     <description>Regulator voltage scaling output               selection</description>
+                     <bitOffset>14</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>ODEN</name>
+                     <description>Over-drive enable</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>ODSWEN</name>
+                     <description>Over-drive switching               enabled</description>
+                     <bitOffset>17</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>UDEN</name>
+                     <description>Under-drive enable in stop               mode</description>
+                     <bitOffset>18</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>CSR1</name>
+               <displayName>CSR1</displayName>
+               <description>power control/status register</description>
+               <addressOffset>0x4</addressOffset>
+               <size>0x20</size>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>WUIF</name>
+                     <description>Wakeup internal flag</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-only</access>
+                  </field>
+                  <field>
+                     <name>SBF</name>
+                     <description>Standby flag</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-only</access>
+                  </field>
+                  <field>
+                     <name>PVDO</name>
+                     <description>PVD output</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-only</access>
+                  </field>
+                  <field>
+                     <name>BRR</name>
+                     <description>Backup regulator ready</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-only</access>
+                  </field>
+                  <field>
+                     <name>BRE</name>
+                     <description>Backup regulator enable</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>VOSRDY</name>
+                     <description>Regulator voltage scaling output               selection ready bit</description>
+                     <bitOffset>14</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>ODRDY</name>
+                     <description>Over-drive mode ready</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>ODSWRDY</name>
+                     <description>Over-drive mode switching               ready</description>
+                     <bitOffset>17</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>UDRDY</name>
+                     <description>Under-drive ready flag</description>
+                     <bitOffset>18</bitOffset>
+                     <bitWidth>2</bitWidth>
+                     <access>read-write</access>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>CR2</name>
+               <displayName>CR2</displayName>
+               <description>power control register</description>
+               <addressOffset>0x8</addressOffset>
+               <size>0x20</size>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>CWUPF1</name>
+                     <description>Clear Wakeup Pin flag for               PA0</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-only</access>
+                  </field>
+                  <field>
+                     <name>CWUPF2</name>
+                     <description>Clear Wakeup Pin flag for               PA2</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-only</access>
+                  </field>
+                  <field>
+                     <name>CWUPF3</name>
+                     <description>Clear Wakeup Pin flag for               PC1</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-only</access>
+                  </field>
+                  <field>
+                     <name>CWUPF4</name>
+                     <description>Clear Wakeup Pin flag for               PC13</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-only</access>
+                  </field>
+                  <field>
+                     <name>CWUPF5</name>
+                     <description>Clear Wakeup Pin flag for               PI8</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-only</access>
+                  </field>
+                  <field>
+                     <name>CWUPF6</name>
+                     <description>Clear Wakeup Pin flag for               PI11</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-only</access>
+                  </field>
+                  <field>
+                     <name>WUPP1</name>
+                     <description>Wakeup pin polarity bit for               PA0</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>WUPP2</name>
+                     <description>Wakeup pin polarity bit for               PA2</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>WUPP3</name>
+                     <description>Wakeup pin polarity bit for               PC1</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>WUPP4</name>
+                     <description>Wakeup pin polarity bit for               PC13</description>
+                     <bitOffset>11</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>WUPP5</name>
+                     <description>Wakeup pin polarity bit for               PI8</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>WUPP6</name>
+                     <description>Wakeup pin polarity bit for               PI11</description>
+                     <bitOffset>13</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>CSR2</name>
+               <displayName>CSR2</displayName>
+               <description>power control/status register</description>
+               <addressOffset>0xC</addressOffset>
+               <size>0x20</size>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>WUPF1</name>
+                     <description>Wakeup Pin flag for PA0</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-only</access>
+                  </field>
+                  <field>
+                     <name>WUPF2</name>
+                     <description>Wakeup Pin flag for PA2</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-only</access>
+                  </field>
+                  <field>
+                     <name>WUPF3</name>
+                     <description>Wakeup Pin flag for PC1</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-only</access>
+                  </field>
+                  <field>
+                     <name>WUPF4</name>
+                     <description>Wakeup Pin flag for PC13</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-only</access>
+                  </field>
+                  <field>
+                     <name>WUPF5</name>
+                     <description>Wakeup Pin flag for PI8</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-only</access>
+                  </field>
+                  <field>
+                     <name>WUPF6</name>
+                     <description>Wakeup Pin flag for PI11</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-only</access>
+                  </field>
+                  <field>
+                     <name>EWUP1</name>
+                     <description>Enable Wakeup pin for PA0</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>EWUP2</name>
+                     <description>Enable Wakeup pin for PA2</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>EWUP3</name>
+                     <description>Enable Wakeup pin for PC1</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>EWUP4</name>
+                     <description>Enable Wakeup pin for PC13</description>
+                     <bitOffset>11</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>EWUP5</name>
+                     <description>Enable Wakeup pin for PI8</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>EWUP6</name>
+                     <description>Enable Wakeup pin for PI11</description>
+                     <bitOffset>13</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+               </fields>
+            </register>
+         </registers>
+      </peripheral>
+      <peripheral>
+         <name>IWDG</name>
+         <description>Independent watchdog</description>
+         <groupName>IWDG</groupName>
+         <baseAddress>0x40003000</baseAddress>
+         <addressBlock>
+            <offset>0x0</offset>
+            <size>0x400</size>
+            <usage>registers</usage>
+         </addressBlock>
+         <registers>
+            <register>
+               <name>KR</name>
+               <displayName>KR</displayName>
+               <description>Key register</description>
+               <addressOffset>0x0</addressOffset>
+               <size>0x20</size>
+               <access>write-only</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>KEY</name>
+                     <description>Key value (write only, read               0000h)</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>PR</name>
+               <displayName>PR</displayName>
+               <description>Prescaler register</description>
+               <addressOffset>0x4</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>PR</name>
+                     <description>Prescaler divider</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>3</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>RLR</name>
+               <displayName>RLR</displayName>
+               <description>Reload register</description>
+               <addressOffset>0x8</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000FFF</resetValue>
+               <fields>
+                  <field>
+                     <name>RL</name>
+                     <description>Watchdog counter reload               value</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>12</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>SR</name>
+               <displayName>SR</displayName>
+               <description>Status register</description>
+               <addressOffset>0xC</addressOffset>
+               <size>0x20</size>
+               <access>read-only</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>RVU</name>
+                     <description>Watchdog counter reload value               update</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>PVU</name>
+                     <description>Watchdog prescaler value               update</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>WINR</name>
+               <displayName>WINR</displayName>
+               <description>Window register</description>
+               <addressOffset>0x10</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>WIN</name>
+                     <description>Watchdog counter window               value</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>12</bitWidth>
+                  </field>
+               </fields>
+            </register>
+         </registers>
+      </peripheral>
+      <peripheral>
+         <name>WWDG</name>
+         <description>Window watchdog</description>
+         <groupName>WWDG</groupName>
+         <baseAddress>0x40002C00</baseAddress>
+         <addressBlock>
+            <offset>0x0</offset>
+            <size>0x400</size>
+            <usage>registers</usage>
+         </addressBlock>
+         <interrupt>
+            <name>WWDG</name>
+            <description>Window Watchdog interrupt</description>
+            <value>0</value>
+         </interrupt>
+         <registers>
+            <register>
+               <name>CR</name>
+               <displayName>CR</displayName>
+               <description>Control register</description>
+               <addressOffset>0x0</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x7F</resetValue>
+               <fields>
+                  <field>
+                     <name>WDGA</name>
+                     <description>Activation bit</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>T</name>
+                     <description>7-bit counter (MSB to LSB)</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>7</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>CFR</name>
+               <displayName>CFR</displayName>
+               <description>Configuration register</description>
+               <addressOffset>0x4</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x7F</resetValue>
+               <fields>
+                  <field>
+                     <name>EWI</name>
+                     <description>Early wakeup interrupt</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>WDGTB1</name>
+                     <description>Timer base</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>WDGTB0</name>
+                     <description>Timer base</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>W</name>
+                     <description>7-bit window value</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>7</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>SR</name>
+               <displayName>SR</displayName>
+               <description>Status register</description>
+               <addressOffset>0x8</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00</resetValue>
+               <fields>
+                  <field>
+                     <name>EWIF</name>
+                     <description>Early wakeup interrupt               flag</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+         </registers>
+      </peripheral>
+      <peripheral>
+         <name>TIM1</name>
+         <description>Advanced-timers</description>
+         <groupName>TIM</groupName>
+         <baseAddress>0x40010000</baseAddress>
+         <addressBlock>
+            <offset>0x0</offset>
+            <size>0x400</size>
+            <usage>registers</usage>
+         </addressBlock>
+         <interrupt>
+            <name>TIM1_BRK_TIM9</name>
+            <description>TIM1 Break interrupt and TIM9 global
+        interrupt</description>
+            <value>24</value>
+         </interrupt>
+         <interrupt>
+            <name>TIM1_UP_TIM10</name>
+            <description>TIM1 Update interrupt and TIM10</description>
+            <value>25</value>
+         </interrupt>
+         <interrupt>
+            <name>TIM1_TRG_COM_TIM11</name>
+            <description>TIM1 Trigger and Commutation interrupts and
+        TIM11 global interrupt</description>
+            <value>26</value>
+         </interrupt>
+         <interrupt>
+            <name>TIM1_CC</name>
+            <description>TIM1 Capture Compare interrupt</description>
+            <value>27</value>
+         </interrupt>
+         <registers>
+            <register>
+               <name>CR1</name>
+               <displayName>CR1</displayName>
+               <description>control register 1</description>
+               <addressOffset>0x0</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x0000</resetValue>
+               <fields>
+                  <field>
+                     <name>CKD</name>
+                     <description>Clock division</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>ARPE</name>
+                     <description>Auto-reload preload enable</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CMS</name>
+                     <description>Center-aligned mode               selection</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>DIR</name>
+                     <description>Direction</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>OPM</name>
+                     <description>One-pulse mode</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>URS</name>
+                     <description>Update request source</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>UDIS</name>
+                     <description>Update disable</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CEN</name>
+                     <description>Counter enable</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>CR2</name>
+               <displayName>CR2</displayName>
+               <description>control register 2</description>
+               <addressOffset>0x4</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x0000</resetValue>
+               <fields>
+                  <field>
+                     <name>OIS4</name>
+                     <description>Output Idle state 4</description>
+                     <bitOffset>14</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>OIS3N</name>
+                     <description>Output Idle state 3</description>
+                     <bitOffset>13</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>OIS3</name>
+                     <description>Output Idle state 3</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>OIS2N</name>
+                     <description>Output Idle state 2</description>
+                     <bitOffset>11</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>OIS2</name>
+                     <description>Output Idle state 2</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>OIS1N</name>
+                     <description>Output Idle state 1</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>OIS1</name>
+                     <description>Output Idle state 1</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TI1S</name>
+                     <description>TI1 selection</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>MMS</name>
+                     <description>Master mode selection</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>3</bitWidth>
+                  </field>
+                  <field>
+                     <name>CCDS</name>
+                     <description>Capture/compare DMA               selection</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CCUS</name>
+                     <description>Capture/compare control update               selection</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CCPC</name>
+                     <description>Capture/compare preloaded               control</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>SMCR</name>
+               <displayName>SMCR</displayName>
+               <description>slave mode control register</description>
+               <addressOffset>0x8</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x0000</resetValue>
+               <fields>
+                  <field>
+                     <name>ETP</name>
+                     <description>External trigger polarity</description>
+                     <bitOffset>15</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>ECE</name>
+                     <description>External clock enable</description>
+                     <bitOffset>14</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>ETPS</name>
+                     <description>External trigger prescaler</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>ETF</name>
+                     <description>External trigger filter</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+                  <field>
+                     <name>MSM</name>
+                     <description>Master/Slave mode</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TS</name>
+                     <description>Trigger selection</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>3</bitWidth>
+                  </field>
+                  <field>
+                     <name>SMS</name>
+                     <description>Slave mode selection</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>3</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DIER</name>
+               <displayName>DIER</displayName>
+               <description>DMA/Interrupt enable register</description>
+               <addressOffset>0xC</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x0000</resetValue>
+               <fields>
+                  <field>
+                     <name>TDE</name>
+                     <description>Trigger DMA request enable</description>
+                     <bitOffset>14</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>COMDE</name>
+                     <description>COM DMA request enable</description>
+                     <bitOffset>13</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CC4DE</name>
+                     <description>Capture/Compare 4 DMA request               enable</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CC3DE</name>
+                     <description>Capture/Compare 3 DMA request               enable</description>
+                     <bitOffset>11</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CC2DE</name>
+                     <description>Capture/Compare 2 DMA request               enable</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CC1DE</name>
+                     <description>Capture/Compare 1 DMA request               enable</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>UDE</name>
+                     <description>Update DMA request enable</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TIE</name>
+                     <description>Trigger interrupt enable</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CC4IE</name>
+                     <description>Capture/Compare 4 interrupt               enable</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CC3IE</name>
+                     <description>Capture/Compare 3 interrupt               enable</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CC2IE</name>
+                     <description>Capture/Compare 2 interrupt               enable</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CC1IE</name>
+                     <description>Capture/Compare 1 interrupt               enable</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>UIE</name>
+                     <description>Update interrupt enable</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>BIE</name>
+                     <description>Break interrupt enable</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>COMIE</name>
+                     <description>COM interrupt enable</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>SR</name>
+               <displayName>SR</displayName>
+               <description>status register</description>
+               <addressOffset>0x10</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x0000</resetValue>
+               <fields>
+                  <field>
+                     <name>CC4OF</name>
+                     <description>Capture/Compare 4 overcapture               flag</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CC3OF</name>
+                     <description>Capture/Compare 3 overcapture               flag</description>
+                     <bitOffset>11</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CC2OF</name>
+                     <description>Capture/compare 2 overcapture               flag</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CC1OF</name>
+                     <description>Capture/Compare 1 overcapture               flag</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>BIF</name>
+                     <description>Break interrupt flag</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TIF</name>
+                     <description>Trigger interrupt flag</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>COMIF</name>
+                     <description>COM interrupt flag</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CC4IF</name>
+                     <description>Capture/Compare 4 interrupt               flag</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CC3IF</name>
+                     <description>Capture/Compare 3 interrupt               flag</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CC2IF</name>
+                     <description>Capture/Compare 2 interrupt               flag</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CC1IF</name>
+                     <description>Capture/compare 1 interrupt               flag</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>UIF</name>
+                     <description>Update interrupt flag</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>EGR</name>
+               <displayName>EGR</displayName>
+               <description>event generation register</description>
+               <addressOffset>0x14</addressOffset>
+               <size>0x20</size>
+               <access>write-only</access>
+               <resetValue>0x0000</resetValue>
+               <fields>
+                  <field>
+                     <name>BG</name>
+                     <description>Break generation</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TG</name>
+                     <description>Trigger generation</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>COMG</name>
+                     <description>Capture/Compare control update               generation</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CC4G</name>
+                     <description>Capture/compare 4               generation</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CC3G</name>
+                     <description>Capture/compare 3               generation</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CC2G</name>
+                     <description>Capture/compare 2               generation</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CC1G</name>
+                     <description>Capture/compare 1               generation</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>UG</name>
+                     <description>Update generation</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>CCMR1_Output</name>
+               <displayName>CCMR1_Output</displayName>
+               <description>capture/compare mode register 1 (output           mode)</description>
+               <addressOffset>0x18</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>OC2CE</name>
+                     <description>Output Compare 2 clear               enable</description>
+                     <bitOffset>15</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>OC2M</name>
+                     <description>Output Compare 2 mode</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>3</bitWidth>
+                  </field>
+                  <field>
+                     <name>OC2PE</name>
+                     <description>Output Compare 2 preload               enable</description>
+                     <bitOffset>11</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>OC2FE</name>
+                     <description>Output Compare 2 fast               enable</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CC2S</name>
+                     <description>Capture/Compare 2               selection</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>OC1CE</name>
+                     <description>Output Compare 1 clear               enable</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>OC1M</name>
+                     <description>Output Compare 1 mode</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>3</bitWidth>
+                  </field>
+                  <field>
+                     <name>OC1PE</name>
+                     <description>Output Compare 1 preload               enable</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>OC1FE</name>
+                     <description>Output Compare 1 fast               enable</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CC1S</name>
+                     <description>Capture/Compare 1               selection</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>CCMR1_Input</name>
+               <displayName>CCMR1_Input</displayName>
+               <description>capture/compare mode register 1 (input           mode)</description>
+               <alternateRegister>CCMR1_Output</alternateRegister>
+               <addressOffset>0x18</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>IC2F</name>
+                     <description>Input capture 2 filter</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+                  <field>
+                     <name>IC2PCS</name>
+                     <description>Input capture 2 prescaler</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>CC2S</name>
+                     <description>Capture/Compare 2               selection</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>IC1F</name>
+                     <description>Input capture 1 filter</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+                  <field>
+                     <name>ICPCS</name>
+                     <description>Input capture 1 prescaler</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>CC1S</name>
+                     <description>Capture/Compare 1               selection</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>CCMR2_Output</name>
+               <displayName>CCMR2_Output</displayName>
+               <description>capture/compare mode register 2 (output           mode)</description>
+               <addressOffset>0x1C</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>OC4CE</name>
+                     <description>Output compare 4 clear               enable</description>
+                     <bitOffset>15</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>OC4M</name>
+                     <description>Output compare 4 mode</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>3</bitWidth>
+                  </field>
+                  <field>
+                     <name>OC4PE</name>
+                     <description>Output compare 4 preload               enable</description>
+                     <bitOffset>11</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>OC4FE</name>
+                     <description>Output compare 4 fast               enable</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CC4S</name>
+                     <description>Capture/Compare 4               selection</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>OC3CE</name>
+                     <description>Output compare 3 clear               enable</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>OC3M</name>
+                     <description>Output compare 3 mode</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>3</bitWidth>
+                  </field>
+                  <field>
+                     <name>OC3PE</name>
+                     <description>Output compare 3 preload               enable</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>OC3FE</name>
+                     <description>Output compare 3 fast               enable</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CC3S</name>
+                     <description>Capture/Compare 3               selection</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>CCMR2_Input</name>
+               <displayName>CCMR2_Input</displayName>
+               <description>capture/compare mode register 2 (input           mode)</description>
+               <alternateRegister>CCMR2_Output</alternateRegister>
+               <addressOffset>0x1C</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>IC4F</name>
+                     <description>Input capture 4 filter</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+                  <field>
+                     <name>IC4PSC</name>
+                     <description>Input capture 4 prescaler</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>CC4S</name>
+                     <description>Capture/Compare 4               selection</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>IC3F</name>
+                     <description>Input capture 3 filter</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+                  <field>
+                     <name>IC3PSC</name>
+                     <description>Input capture 3 prescaler</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>CC3S</name>
+                     <description>Capture/compare 3               selection</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>CCER</name>
+               <displayName>CCER</displayName>
+               <description>capture/compare enable           register</description>
+               <addressOffset>0x20</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x0000</resetValue>
+               <fields>
+                  <field>
+                     <name>CC4P</name>
+                     <description>Capture/Compare 3 output               Polarity</description>
+                     <bitOffset>13</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CC4E</name>
+                     <description>Capture/Compare 4 output               enable</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CC3NP</name>
+                     <description>Capture/Compare 3 output               Polarity</description>
+                     <bitOffset>11</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CC3NE</name>
+                     <description>Capture/Compare 3 complementary output               enable</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CC3P</name>
+                     <description>Capture/Compare 3 output               Polarity</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CC3E</name>
+                     <description>Capture/Compare 3 output               enable</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CC2NP</name>
+                     <description>Capture/Compare 2 output               Polarity</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CC2NE</name>
+                     <description>Capture/Compare 2 complementary output               enable</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CC2P</name>
+                     <description>Capture/Compare 2 output               Polarity</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CC2E</name>
+                     <description>Capture/Compare 2 output               enable</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CC1NP</name>
+                     <description>Capture/Compare 1 output               Polarity</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CC1NE</name>
+                     <description>Capture/Compare 1 complementary output               enable</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CC1P</name>
+                     <description>Capture/Compare 1 output               Polarity</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CC1E</name>
+                     <description>Capture/Compare 1 output               enable</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>CNT</name>
+               <displayName>CNT</displayName>
+               <description>counter</description>
+               <addressOffset>0x24</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>CNT</name>
+                     <description>counter value</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>PSC</name>
+               <displayName>PSC</displayName>
+               <description>prescaler</description>
+               <addressOffset>0x28</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x0000</resetValue>
+               <fields>
+                  <field>
+                     <name>PSC</name>
+                     <description>Prescaler value</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>ARR</name>
+               <displayName>ARR</displayName>
+               <description>auto-reload register</description>
+               <addressOffset>0x2C</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>ARR</name>
+                     <description>Auto-reload value</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>CCR1</name>
+               <displayName>CCR1</displayName>
+               <description>capture/compare register 1</description>
+               <addressOffset>0x34</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>CCR1</name>
+                     <description>Capture/Compare 1 value</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>CCR2</name>
+               <displayName>CCR2</displayName>
+               <description>capture/compare register 2</description>
+               <addressOffset>0x38</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>CCR2</name>
+                     <description>Capture/Compare 2 value</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>CCR3</name>
+               <displayName>CCR3</displayName>
+               <description>capture/compare register 3</description>
+               <addressOffset>0x3C</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>CCR3</name>
+                     <description>Capture/Compare value</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>CCR4</name>
+               <displayName>CCR4</displayName>
+               <description>capture/compare register 4</description>
+               <addressOffset>0x40</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>CCR4</name>
+                     <description>Capture/Compare value</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DCR</name>
+               <displayName>DCR</displayName>
+               <description>DMA control register</description>
+               <addressOffset>0x48</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x0000</resetValue>
+               <fields>
+                  <field>
+                     <name>DBL</name>
+                     <description>DMA burst length</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>5</bitWidth>
+                  </field>
+                  <field>
+                     <name>DBA</name>
+                     <description>DMA base address</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>5</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DMAR</name>
+               <displayName>DMAR</displayName>
+               <description>DMA address for full transfer</description>
+               <addressOffset>0x4C</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x0000</resetValue>
+               <fields>
+                  <field>
+                     <name>DMAB</name>
+                     <description>DMA register for burst               accesses</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>RCR</name>
+               <displayName>RCR</displayName>
+               <description>repetition counter register</description>
+               <addressOffset>0x30</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x0000</resetValue>
+               <fields>
+                  <field>
+                     <name>REP</name>
+                     <description>Repetition counter value</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>BDTR</name>
+               <displayName>BDTR</displayName>
+               <description>break and dead-time register</description>
+               <addressOffset>0x44</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x0000</resetValue>
+               <fields>
+                  <field>
+                     <name>DTG</name>
+                     <description>Dead-time generator setup</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+                  <field>
+                     <name>LOCK</name>
+                     <description>Lock configuration</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>OSSI</name>
+                     <description>Off-state selection for Idle               mode</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>OSSR</name>
+                     <description>Off-state selection for Run               mode</description>
+                     <bitOffset>11</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>BKE</name>
+                     <description>Break enable</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>BKP</name>
+                     <description>Break polarity</description>
+                     <bitOffset>13</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>AOE</name>
+                     <description>Automatic output enable</description>
+                     <bitOffset>14</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>MOE</name>
+                     <description>Main output enable</description>
+                     <bitOffset>15</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>BKF</name>
+                     <description>Break filter</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+                  <field>
+                     <name>BK2F</name>
+                     <description>Break 2 filter</description>
+                     <bitOffset>20</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+                  <field>
+                     <name>BK2E</name>
+                     <description>Break 2 enable</description>
+                     <bitOffset>24</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>BK2P</name>
+                     <description>Break 2 polarity</description>
+                     <bitOffset>25</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>CCMR3_Output</name>
+               <displayName>CCMR3_Output</displayName>
+               <description>capture/compare mode register 3 (output           mode)</description>
+               <addressOffset>0x54</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x0000</resetValue>
+               <fields>
+                  <field>
+                     <name>OC5FE</name>
+                     <description>Output compare 5 fast               enable</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>OC5PE</name>
+                     <description>Output compare 5 preload               enable</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>OC5M</name>
+                     <description>Output compare 5 mode</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>3</bitWidth>
+                  </field>
+                  <field>
+                     <name>OC5CE</name>
+                     <description>Output compare 5 clear               enable</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>OC6FE</name>
+                     <description>Output compare 6 fast               enable</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>OC6PE</name>
+                     <description>Output compare 6 preload               enable</description>
+                     <bitOffset>11</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>OC6M</name>
+                     <description>Output compare 6 mode</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>3</bitWidth>
+                  </field>
+                  <field>
+                     <name>OC6CE</name>
+                     <description>Output compare 6 clear               enable</description>
+                     <bitOffset>15</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>OC5M3</name>
+                     <description>Output Compare 5 mode</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>OC6M3</name>
+                     <description>Output Compare 6 mode</description>
+                     <bitOffset>24</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>CCR5</name>
+               <displayName>CCR5</displayName>
+               <description>capture/compare register 5</description>
+               <addressOffset>0x58</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x0000</resetValue>
+               <fields>
+                  <field>
+                     <name>CCR5</name>
+                     <description>Capture/Compare 5 value</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+                  <field>
+                     <name>GC5C1</name>
+                     <description>Group Channel 5 and Channel               1</description>
+                     <bitOffset>29</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>GC5C2</name>
+                     <description>Group Channel 5 and Channel               2</description>
+                     <bitOffset>30</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>GC5C3</name>
+                     <description>Group Channel 5 and Channel               3</description>
+                     <bitOffset>31</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>CRR6</name>
+               <displayName>CRR6</displayName>
+               <description>capture/compare register 6</description>
+               <addressOffset>0x5C</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x0000</resetValue>
+               <fields>
+                  <field>
+                     <name>CCR6</name>
+                     <description>Capture/Compare 6 value</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>AF1</name>
+               <displayName>AF1</displayName>
+               <description>alternate function option register           1</description>
+               <addressOffset>0x60</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x0000</resetValue>
+               <fields>
+                  <field>
+                     <name>BKINE</name>
+                     <description>BRK BKIN input enable</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>BKDFBKE</name>
+                     <description>BRK DFSDM_BREAK[0] enable</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>BKINP</name>
+                     <description>BRK BKIN input polarity</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>AF2</name>
+               <displayName>AF2</displayName>
+               <description>alternate function option register           2</description>
+               <addressOffset>0x64</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x0000</resetValue>
+               <fields>
+                  <field>
+                     <name>BK2INE</name>
+                     <description>BRK2 BKIN input enable</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>BK2DFBKE</name>
+                     <description>BRK2 DFSDM_BREAK enable</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>BK2INP</name>
+                     <description>BRK2 BKIN2 input polarity</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+         </registers>
+      </peripheral>
+      <peripheral derivedFrom="TIM1">
+         <name>TIM8</name>
+         <baseAddress>0x40010400</baseAddress>
+         <interrupt>
+            <name>TIM8_BRK_TIM12</name>
+            <description>TIM8 Break interrupt and TIM12 global
+        interrupt</description>
+            <value>43</value>
+         </interrupt>
+         <interrupt>
+            <name>TIM8_UP_TIM13</name>
+            <description>TIM8 Update interrupt and TIM13 global
+        interrupt</description>
+            <value>44</value>
+         </interrupt>
+         <interrupt>
+            <name>TIM8_TRG_COM_TIM14</name>
+            <description>TIM8 Trigger and Commutation interrupts and
+        TIM14 global interrupt</description>
+            <value>45</value>
+         </interrupt>
+         <interrupt>
+            <name>TIM8_CC</name>
+            <description>TIM8 Capture Compare interrupt</description>
+            <value>46</value>
+         </interrupt>
+      </peripheral>
+      <peripheral>
+         <name>TIM2</name>
+         <description>General purpose timers</description>
+         <groupName>TIM</groupName>
+         <baseAddress>0x40000000</baseAddress>
+         <addressBlock>
+            <offset>0x0</offset>
+            <size>0x400</size>
+            <usage>registers</usage>
+         </addressBlock>
+         <interrupt>
+            <name>TIM2</name>
+            <description>TIM2 global interrupt</description>
+            <value>28</value>
+         </interrupt>
+         <registers>
+            <register>
+               <name>CR1</name>
+               <displayName>CR1</displayName>
+               <description>control register 1</description>
+               <addressOffset>0x0</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x0000</resetValue>
+               <fields>
+                  <field>
+                     <name>CKD</name>
+                     <description>Clock division</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>ARPE</name>
+                     <description>Auto-reload preload enable</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CMS</name>
+                     <description>Center-aligned mode               selection</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>DIR</name>
+                     <description>Direction</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>OPM</name>
+                     <description>One-pulse mode</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>URS</name>
+                     <description>Update request source</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>UDIS</name>
+                     <description>Update disable</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CEN</name>
+                     <description>Counter enable</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>CR2</name>
+               <displayName>CR2</displayName>
+               <description>control register 2</description>
+               <addressOffset>0x4</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x0000</resetValue>
+               <fields>
+                  <field>
+                     <name>TI1S</name>
+                     <description>TI1 selection</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>MMS</name>
+                     <description>Master mode selection</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>3</bitWidth>
+                  </field>
+                  <field>
+                     <name>CCDS</name>
+                     <description>Capture/compare DMA               selection</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>SMCR</name>
+               <displayName>SMCR</displayName>
+               <description>slave mode control register</description>
+               <addressOffset>0x8</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x0000</resetValue>
+               <fields>
+                  <field>
+                     <name>ETP</name>
+                     <description>External trigger polarity</description>
+                     <bitOffset>15</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>ECE</name>
+                     <description>External clock enable</description>
+                     <bitOffset>14</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>ETPS</name>
+                     <description>External trigger prescaler</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>ETF</name>
+                     <description>External trigger filter</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+                  <field>
+                     <name>MSM</name>
+                     <description>Master/Slave mode</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TS</name>
+                     <description>Trigger selection</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>3</bitWidth>
+                  </field>
+                  <field>
+                     <name>SMS</name>
+                     <description>Slave mode selection</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>3</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DIER</name>
+               <displayName>DIER</displayName>
+               <description>DMA/Interrupt enable register</description>
+               <addressOffset>0xC</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x0000</resetValue>
+               <fields>
+                  <field>
+                     <name>TDE</name>
+                     <description>Trigger DMA request enable</description>
+                     <bitOffset>14</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CC4DE</name>
+                     <description>Capture/Compare 4 DMA request               enable</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CC3DE</name>
+                     <description>Capture/Compare 3 DMA request               enable</description>
+                     <bitOffset>11</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CC2DE</name>
+                     <description>Capture/Compare 2 DMA request               enable</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CC1DE</name>
+                     <description>Capture/Compare 1 DMA request               enable</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>UDE</name>
+                     <description>Update DMA request enable</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TIE</name>
+                     <description>Trigger interrupt enable</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CC4IE</name>
+                     <description>Capture/Compare 4 interrupt               enable</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CC3IE</name>
+                     <description>Capture/Compare 3 interrupt               enable</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CC2IE</name>
+                     <description>Capture/Compare 2 interrupt               enable</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CC1IE</name>
+                     <description>Capture/Compare 1 interrupt               enable</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>UIE</name>
+                     <description>Update interrupt enable</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>SR</name>
+               <displayName>SR</displayName>
+               <description>status register</description>
+               <addressOffset>0x10</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x0000</resetValue>
+               <fields>
+                  <field>
+                     <name>CC4OF</name>
+                     <description>Capture/Compare 4 overcapture               flag</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CC3OF</name>
+                     <description>Capture/Compare 3 overcapture               flag</description>
+                     <bitOffset>11</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CC2OF</name>
+                     <description>Capture/compare 2 overcapture               flag</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CC1OF</name>
+                     <description>Capture/Compare 1 overcapture               flag</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TIF</name>
+                     <description>Trigger interrupt flag</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CC4IF</name>
+                     <description>Capture/Compare 4 interrupt               flag</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CC3IF</name>
+                     <description>Capture/Compare 3 interrupt               flag</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CC2IF</name>
+                     <description>Capture/Compare 2 interrupt               flag</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CC1IF</name>
+                     <description>Capture/compare 1 interrupt               flag</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>UIF</name>
+                     <description>Update interrupt flag</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>EGR</name>
+               <displayName>EGR</displayName>
+               <description>event generation register</description>
+               <addressOffset>0x14</addressOffset>
+               <size>0x20</size>
+               <access>write-only</access>
+               <resetValue>0x0000</resetValue>
+               <fields>
+                  <field>
+                     <name>TG</name>
+                     <description>Trigger generation</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CC4G</name>
+                     <description>Capture/compare 4               generation</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CC3G</name>
+                     <description>Capture/compare 3               generation</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CC2G</name>
+                     <description>Capture/compare 2               generation</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CC1G</name>
+                     <description>Capture/compare 1               generation</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>UG</name>
+                     <description>Update generation</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>CCMR1_Output</name>
+               <displayName>CCMR1_Output</displayName>
+               <description>capture/compare mode register 1 (output           mode)</description>
+               <addressOffset>0x18</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>OC2CE</name>
+                     <description>OC2CE</description>
+                     <bitOffset>15</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>OC2M</name>
+                     <description>OC2M</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>3</bitWidth>
+                  </field>
+                  <field>
+                     <name>OC2PE</name>
+                     <description>OC2PE</description>
+                     <bitOffset>11</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>OC2FE</name>
+                     <description>OC2FE</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CC2S</name>
+                     <description>CC2S</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>OC1CE</name>
+                     <description>OC1CE</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>OC1M</name>
+                     <description>OC1M</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>3</bitWidth>
+                  </field>
+                  <field>
+                     <name>OC1PE</name>
+                     <description>OC1PE</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>OC1FE</name>
+                     <description>OC1FE</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CC1S</name>
+                     <description>CC1S</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>CCMR1_Input</name>
+               <displayName>CCMR1_Input</displayName>
+               <description>capture/compare mode register 1 (input           mode)</description>
+               <alternateRegister>CCMR1_Output</alternateRegister>
+               <addressOffset>0x18</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>IC2F</name>
+                     <description>Input capture 2 filter</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+                  <field>
+                     <name>IC2PCS</name>
+                     <description>Input capture 2 prescaler</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>CC2S</name>
+                     <description>Capture/Compare 2               selection</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>IC1F</name>
+                     <description>Input capture 1 filter</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+                  <field>
+                     <name>ICPCS</name>
+                     <description>Input capture 1 prescaler</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>CC1S</name>
+                     <description>Capture/Compare 1               selection</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>CCMR2_Output</name>
+               <displayName>CCMR2_Output</displayName>
+               <description>capture/compare mode register 2 (output           mode)</description>
+               <addressOffset>0x1C</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>O24CE</name>
+                     <description>O24CE</description>
+                     <bitOffset>15</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>OC4M</name>
+                     <description>OC4M</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>3</bitWidth>
+                  </field>
+                  <field>
+                     <name>OC4PE</name>
+                     <description>OC4PE</description>
+                     <bitOffset>11</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>OC4FE</name>
+                     <description>OC4FE</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CC4S</name>
+                     <description>CC4S</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>OC3CE</name>
+                     <description>OC3CE</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>OC3M</name>
+                     <description>OC3M</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>3</bitWidth>
+                  </field>
+                  <field>
+                     <name>OC3PE</name>
+                     <description>OC3PE</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>OC3FE</name>
+                     <description>OC3FE</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CC3S</name>
+                     <description>CC3S</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>CCMR2_Input</name>
+               <displayName>CCMR2_Input</displayName>
+               <description>capture/compare mode register 2 (input           mode)</description>
+               <alternateRegister>CCMR2_Output</alternateRegister>
+               <addressOffset>0x1C</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>IC4F</name>
+                     <description>Input capture 4 filter</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+                  <field>
+                     <name>IC4PSC</name>
+                     <description>Input capture 4 prescaler</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>CC4S</name>
+                     <description>Capture/Compare 4               selection</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>IC3F</name>
+                     <description>Input capture 3 filter</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+                  <field>
+                     <name>IC3PSC</name>
+                     <description>Input capture 3 prescaler</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>CC3S</name>
+                     <description>Capture/compare 3               selection</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>CCER</name>
+               <displayName>CCER</displayName>
+               <description>capture/compare enable           register</description>
+               <addressOffset>0x20</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x0000</resetValue>
+               <fields>
+                  <field>
+                     <name>CC4NP</name>
+                     <description>Capture/Compare 4 output               Polarity</description>
+                     <bitOffset>15</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CC4P</name>
+                     <description>Capture/Compare 3 output               Polarity</description>
+                     <bitOffset>13</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CC4E</name>
+                     <description>Capture/Compare 4 output               enable</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CC3NP</name>
+                     <description>Capture/Compare 3 output               Polarity</description>
+                     <bitOffset>11</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CC3P</name>
+                     <description>Capture/Compare 3 output               Polarity</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CC3E</name>
+                     <description>Capture/Compare 3 output               enable</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CC2NP</name>
+                     <description>Capture/Compare 2 output               Polarity</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CC2P</name>
+                     <description>Capture/Compare 2 output               Polarity</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CC2E</name>
+                     <description>Capture/Compare 2 output               enable</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CC1NP</name>
+                     <description>Capture/Compare 1 output               Polarity</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CC1P</name>
+                     <description>Capture/Compare 1 output               Polarity</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CC1E</name>
+                     <description>Capture/Compare 1 output               enable</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>CNT</name>
+               <displayName>CNT</displayName>
+               <description>counter</description>
+               <addressOffset>0x24</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>CNT_H</name>
+                     <description>High counter value</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+                  <field>
+                     <name>CNT_L</name>
+                     <description>Low counter value</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>PSC</name>
+               <displayName>PSC</displayName>
+               <description>prescaler</description>
+               <addressOffset>0x28</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x0000</resetValue>
+               <fields>
+                  <field>
+                     <name>PSC</name>
+                     <description>Prescaler value</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>ARR</name>
+               <displayName>ARR</displayName>
+               <description>auto-reload register</description>
+               <addressOffset>0x2C</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>ARR_H</name>
+                     <description>High Auto-reload value</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+                  <field>
+                     <name>ARR_L</name>
+                     <description>Low Auto-reload value</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>CCR1</name>
+               <displayName>CCR1</displayName>
+               <description>capture/compare register 1</description>
+               <addressOffset>0x34</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>CCR1_H</name>
+                     <description>High Capture/Compare 1               value</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+                  <field>
+                     <name>CCR1_L</name>
+                     <description>Low Capture/Compare 1               value</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>CCR2</name>
+               <displayName>CCR2</displayName>
+               <description>capture/compare register 2</description>
+               <addressOffset>0x38</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>CCR2_H</name>
+                     <description>High Capture/Compare 2               value</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+                  <field>
+                     <name>CCR2_L</name>
+                     <description>Low Capture/Compare 2               value</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>CCR3</name>
+               <displayName>CCR3</displayName>
+               <description>capture/compare register 3</description>
+               <addressOffset>0x3C</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>CCR3_H</name>
+                     <description>High Capture/Compare value</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+                  <field>
+                     <name>CCR3_L</name>
+                     <description>Low Capture/Compare value</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>CCR4</name>
+               <displayName>CCR4</displayName>
+               <description>capture/compare register 4</description>
+               <addressOffset>0x40</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>CCR4_H</name>
+                     <description>High Capture/Compare value</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+                  <field>
+                     <name>CCR4_L</name>
+                     <description>Low Capture/Compare value</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DCR</name>
+               <displayName>DCR</displayName>
+               <description>DMA control register</description>
+               <addressOffset>0x48</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x0000</resetValue>
+               <fields>
+                  <field>
+                     <name>DBL</name>
+                     <description>DMA burst length</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>5</bitWidth>
+                  </field>
+                  <field>
+                     <name>DBA</name>
+                     <description>DMA base address</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>5</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DMAR</name>
+               <displayName>DMAR</displayName>
+               <description>DMA address for full transfer</description>
+               <addressOffset>0x4C</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x0000</resetValue>
+               <fields>
+                  <field>
+                     <name>DMAB</name>
+                     <description>DMA register for burst               accesses</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OR1</name>
+               <displayName>OR1</displayName>
+               <description>TIM2 option register 1</description>
+               <addressOffset>0x50</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x0000</resetValue>
+               <fields>
+                  <field>
+                     <name>TI4_RMP</name>
+                     <description>Input Capture 4 remap</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>ETR1_RMP</name>
+                     <description>External trigger remap</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>ITR1_RMP</name>
+                     <description>Internal trigger 1 remap</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OR2</name>
+               <displayName>OR2</displayName>
+               <description>TIM2 option register 2</description>
+               <addressOffset>0x60</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x0000</resetValue>
+               <fields>
+                  <field>
+                     <name>ETRSEL</name>
+                     <description>ETR source selection</description>
+                     <bitOffset>14</bitOffset>
+                     <bitWidth>3</bitWidth>
+                  </field>
+               </fields>
+            </register>
+         </registers>
+      </peripheral>
+      <peripheral>
+         <name>TIM3</name>
+         <description>General purpose timers</description>
+         <groupName>TIM</groupName>
+         <baseAddress>0x40000400</baseAddress>
+         <addressBlock>
+            <offset>0x0</offset>
+            <size>0x400</size>
+            <usage>registers</usage>
+         </addressBlock>
+         <interrupt>
+            <name>TIM3</name>
+            <description>TIM3 global interrupt</description>
+            <value>29</value>
+         </interrupt>
+         <registers>
+            <register>
+               <name>CR1</name>
+               <displayName>CR1</displayName>
+               <description>control register 1</description>
+               <addressOffset>0x0</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x0000</resetValue>
+               <fields>
+                  <field>
+                     <name>CKD</name>
+                     <description>Clock division</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>ARPE</name>
+                     <description>Auto-reload preload enable</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CMS</name>
+                     <description>Center-aligned mode               selection</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>DIR</name>
+                     <description>Direction</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>OPM</name>
+                     <description>One-pulse mode</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>URS</name>
+                     <description>Update request source</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>UDIS</name>
+                     <description>Update disable</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CEN</name>
+                     <description>Counter enable</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>CR2</name>
+               <displayName>CR2</displayName>
+               <description>control register 2</description>
+               <addressOffset>0x4</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x0000</resetValue>
+               <fields>
+                  <field>
+                     <name>TI1S</name>
+                     <description>TI1 selection</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>MMS</name>
+                     <description>Master mode selection</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>3</bitWidth>
+                  </field>
+                  <field>
+                     <name>CCDS</name>
+                     <description>Capture/compare DMA               selection</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>SMCR</name>
+               <displayName>SMCR</displayName>
+               <description>slave mode control register</description>
+               <addressOffset>0x8</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x0000</resetValue>
+               <fields>
+                  <field>
+                     <name>ETP</name>
+                     <description>External trigger polarity</description>
+                     <bitOffset>15</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>ECE</name>
+                     <description>External clock enable</description>
+                     <bitOffset>14</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>ETPS</name>
+                     <description>External trigger prescaler</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>ETF</name>
+                     <description>External trigger filter</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+                  <field>
+                     <name>MSM</name>
+                     <description>Master/Slave mode</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TS</name>
+                     <description>Trigger selection</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>3</bitWidth>
+                  </field>
+                  <field>
+                     <name>SMS</name>
+                     <description>Slave mode selection</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>3</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DIER</name>
+               <displayName>DIER</displayName>
+               <description>DMA/Interrupt enable register</description>
+               <addressOffset>0xC</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x0000</resetValue>
+               <fields>
+                  <field>
+                     <name>TDE</name>
+                     <description>Trigger DMA request enable</description>
+                     <bitOffset>14</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CC4DE</name>
+                     <description>Capture/Compare 4 DMA request               enable</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CC3DE</name>
+                     <description>Capture/Compare 3 DMA request               enable</description>
+                     <bitOffset>11</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CC2DE</name>
+                     <description>Capture/Compare 2 DMA request               enable</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CC1DE</name>
+                     <description>Capture/Compare 1 DMA request               enable</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>UDE</name>
+                     <description>Update DMA request enable</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TIE</name>
+                     <description>Trigger interrupt enable</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CC4IE</name>
+                     <description>Capture/Compare 4 interrupt               enable</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CC3IE</name>
+                     <description>Capture/Compare 3 interrupt               enable</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CC2IE</name>
+                     <description>Capture/Compare 2 interrupt               enable</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CC1IE</name>
+                     <description>Capture/Compare 1 interrupt               enable</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>UIE</name>
+                     <description>Update interrupt enable</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>SR</name>
+               <displayName>SR</displayName>
+               <description>status register</description>
+               <addressOffset>0x10</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x0000</resetValue>
+               <fields>
+                  <field>
+                     <name>CC4OF</name>
+                     <description>Capture/Compare 4 overcapture               flag</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CC3OF</name>
+                     <description>Capture/Compare 3 overcapture               flag</description>
+                     <bitOffset>11</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CC2OF</name>
+                     <description>Capture/compare 2 overcapture               flag</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CC1OF</name>
+                     <description>Capture/Compare 1 overcapture               flag</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TIF</name>
+                     <description>Trigger interrupt flag</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CC4IF</name>
+                     <description>Capture/Compare 4 interrupt               flag</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CC3IF</name>
+                     <description>Capture/Compare 3 interrupt               flag</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CC2IF</name>
+                     <description>Capture/Compare 2 interrupt               flag</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CC1IF</name>
+                     <description>Capture/compare 1 interrupt               flag</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>UIF</name>
+                     <description>Update interrupt flag</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>EGR</name>
+               <displayName>EGR</displayName>
+               <description>event generation register</description>
+               <addressOffset>0x14</addressOffset>
+               <size>0x20</size>
+               <access>write-only</access>
+               <resetValue>0x0000</resetValue>
+               <fields>
+                  <field>
+                     <name>TG</name>
+                     <description>Trigger generation</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CC4G</name>
+                     <description>Capture/compare 4               generation</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CC3G</name>
+                     <description>Capture/compare 3               generation</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CC2G</name>
+                     <description>Capture/compare 2               generation</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CC1G</name>
+                     <description>Capture/compare 1               generation</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>UG</name>
+                     <description>Update generation</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>CCMR1_Output</name>
+               <displayName>CCMR1_Output</displayName>
+               <description>capture/compare mode register 1 (output           mode)</description>
+               <addressOffset>0x18</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>OC2CE</name>
+                     <description>OC2CE</description>
+                     <bitOffset>15</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>OC2M</name>
+                     <description>OC2M</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>3</bitWidth>
+                  </field>
+                  <field>
+                     <name>OC2PE</name>
+                     <description>OC2PE</description>
+                     <bitOffset>11</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>OC2FE</name>
+                     <description>OC2FE</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CC2S</name>
+                     <description>CC2S</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>OC1CE</name>
+                     <description>OC1CE</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>OC1M</name>
+                     <description>OC1M</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>3</bitWidth>
+                  </field>
+                  <field>
+                     <name>OC1PE</name>
+                     <description>OC1PE</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>OC1FE</name>
+                     <description>OC1FE</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CC1S</name>
+                     <description>CC1S</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>CCMR1_Input</name>
+               <displayName>CCMR1_Input</displayName>
+               <description>capture/compare mode register 1 (input           mode)</description>
+               <alternateRegister>CCMR1_Output</alternateRegister>
+               <addressOffset>0x18</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>IC2F</name>
+                     <description>Input capture 2 filter</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+                  <field>
+                     <name>IC2PCS</name>
+                     <description>Input capture 2 prescaler</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>CC2S</name>
+                     <description>Capture/Compare 2               selection</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>IC1F</name>
+                     <description>Input capture 1 filter</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+                  <field>
+                     <name>ICPCS</name>
+                     <description>Input capture 1 prescaler</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>CC1S</name>
+                     <description>Capture/Compare 1               selection</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>CCMR2_Output</name>
+               <displayName>CCMR2_Output</displayName>
+               <description>capture/compare mode register 2 (output           mode)</description>
+               <addressOffset>0x1C</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>O24CE</name>
+                     <description>O24CE</description>
+                     <bitOffset>15</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>OC4M</name>
+                     <description>OC4M</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>3</bitWidth>
+                  </field>
+                  <field>
+                     <name>OC4PE</name>
+                     <description>OC4PE</description>
+                     <bitOffset>11</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>OC4FE</name>
+                     <description>OC4FE</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CC4S</name>
+                     <description>CC4S</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>OC3CE</name>
+                     <description>OC3CE</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>OC3M</name>
+                     <description>OC3M</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>3</bitWidth>
+                  </field>
+                  <field>
+                     <name>OC3PE</name>
+                     <description>OC3PE</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>OC3FE</name>
+                     <description>OC3FE</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CC3S</name>
+                     <description>CC3S</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>CCMR2_Input</name>
+               <displayName>CCMR2_Input</displayName>
+               <description>capture/compare mode register 2 (input           mode)</description>
+               <alternateRegister>CCMR2_Output</alternateRegister>
+               <addressOffset>0x1C</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>IC4F</name>
+                     <description>Input capture 4 filter</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+                  <field>
+                     <name>IC4PSC</name>
+                     <description>Input capture 4 prescaler</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>CC4S</name>
+                     <description>Capture/Compare 4               selection</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>IC3F</name>
+                     <description>Input capture 3 filter</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+                  <field>
+                     <name>IC3PSC</name>
+                     <description>Input capture 3 prescaler</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>CC3S</name>
+                     <description>Capture/compare 3               selection</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>CCER</name>
+               <displayName>CCER</displayName>
+               <description>capture/compare enable           register</description>
+               <addressOffset>0x20</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x0000</resetValue>
+               <fields>
+                  <field>
+                     <name>CC4NP</name>
+                     <description>Capture/Compare 4 output               Polarity</description>
+                     <bitOffset>15</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CC4P</name>
+                     <description>Capture/Compare 3 output               Polarity</description>
+                     <bitOffset>13</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CC4E</name>
+                     <description>Capture/Compare 4 output               enable</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CC3NP</name>
+                     <description>Capture/Compare 3 output               Polarity</description>
+                     <bitOffset>11</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CC3P</name>
+                     <description>Capture/Compare 3 output               Polarity</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CC3E</name>
+                     <description>Capture/Compare 3 output               enable</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CC2NP</name>
+                     <description>Capture/Compare 2 output               Polarity</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CC2P</name>
+                     <description>Capture/Compare 2 output               Polarity</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CC2E</name>
+                     <description>Capture/Compare 2 output               enable</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CC1NP</name>
+                     <description>Capture/Compare 1 output               Polarity</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CC1P</name>
+                     <description>Capture/Compare 1 output               Polarity</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CC1E</name>
+                     <description>Capture/Compare 1 output               enable</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>CNT</name>
+               <displayName>CNT</displayName>
+               <description>counter</description>
+               <addressOffset>0x24</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>CNT_H</name>
+                     <description>High counter value</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+                  <field>
+                     <name>CNT_L</name>
+                     <description>Low counter value</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>PSC</name>
+               <displayName>PSC</displayName>
+               <description>prescaler</description>
+               <addressOffset>0x28</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x0000</resetValue>
+               <fields>
+                  <field>
+                     <name>PSC</name>
+                     <description>Prescaler value</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>ARR</name>
+               <displayName>ARR</displayName>
+               <description>auto-reload register</description>
+               <addressOffset>0x2C</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>ARR_H</name>
+                     <description>High Auto-reload value</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+                  <field>
+                     <name>ARR_L</name>
+                     <description>Low Auto-reload value</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>CCR1</name>
+               <displayName>CCR1</displayName>
+               <description>capture/compare register 1</description>
+               <addressOffset>0x34</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>CCR1_H</name>
+                     <description>High Capture/Compare 1               value</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+                  <field>
+                     <name>CCR1_L</name>
+                     <description>Low Capture/Compare 1               value</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>CCR2</name>
+               <displayName>CCR2</displayName>
+               <description>capture/compare register 2</description>
+               <addressOffset>0x38</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>CCR2_H</name>
+                     <description>High Capture/Compare 2               value</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+                  <field>
+                     <name>CCR2_L</name>
+                     <description>Low Capture/Compare 2               value</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>CCR3</name>
+               <displayName>CCR3</displayName>
+               <description>capture/compare register 3</description>
+               <addressOffset>0x3C</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>CCR3_H</name>
+                     <description>High Capture/Compare value</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+                  <field>
+                     <name>CCR3_L</name>
+                     <description>Low Capture/Compare value</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>CCR4</name>
+               <displayName>CCR4</displayName>
+               <description>capture/compare register 4</description>
+               <addressOffset>0x40</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>CCR4_H</name>
+                     <description>High Capture/Compare value</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+                  <field>
+                     <name>CCR4_L</name>
+                     <description>Low Capture/Compare value</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DCR</name>
+               <displayName>DCR</displayName>
+               <description>DMA control register</description>
+               <addressOffset>0x48</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x0000</resetValue>
+               <fields>
+                  <field>
+                     <name>DBL</name>
+                     <description>DMA burst length</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>5</bitWidth>
+                  </field>
+                  <field>
+                     <name>DBA</name>
+                     <description>DMA base address</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>5</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DMAR</name>
+               <displayName>DMAR</displayName>
+               <description>DMA address for full transfer</description>
+               <addressOffset>0x4C</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x0000</resetValue>
+               <fields>
+                  <field>
+                     <name>DMAB</name>
+                     <description>DMA register for burst               accesses</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OR1</name>
+               <displayName>OR1</displayName>
+               <description>TIM3 option register 1</description>
+               <addressOffset>0x50</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x0000</resetValue>
+               <fields>
+                  <field>
+                     <name>TI1_RMP</name>
+                     <description>Input Capture 1 remap</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OR2</name>
+               <displayName>OR2</displayName>
+               <description>TIM3 option register 2</description>
+               <addressOffset>0x60</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x0000</resetValue>
+               <fields>
+                  <field>
+                     <name>ETRSEL</name>
+                     <description>ETR source selection</description>
+                     <bitOffset>14</bitOffset>
+                     <bitWidth>3</bitWidth>
+                  </field>
+               </fields>
+            </register>
+         </registers>
+      </peripheral>
+      <peripheral>
+         <name>TIM4</name>
+         <description>General purpose timers</description>
+         <groupName>TIM</groupName>
+         <baseAddress>0x40000800</baseAddress>
+         <addressBlock>
+            <offset>0x0</offset>
+            <size>0x400</size>
+            <usage>registers</usage>
+         </addressBlock>
+         <interrupt>
+            <name>TIM4</name>
+            <description>TIM4 global interrupt</description>
+            <value>30</value>
+         </interrupt>
+         <registers>
+            <register>
+               <name>CR1</name>
+               <displayName>CR1</displayName>
+               <description>control register 1</description>
+               <addressOffset>0x0</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x0000</resetValue>
+               <fields>
+                  <field>
+                     <name>CKD</name>
+                     <description>Clock division</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>ARPE</name>
+                     <description>Auto-reload preload enable</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CMS</name>
+                     <description>Center-aligned mode               selection</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>DIR</name>
+                     <description>Direction</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>OPM</name>
+                     <description>One-pulse mode</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>URS</name>
+                     <description>Update request source</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>UDIS</name>
+                     <description>Update disable</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CEN</name>
+                     <description>Counter enable</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>CR2</name>
+               <displayName>CR2</displayName>
+               <description>control register 2</description>
+               <addressOffset>0x4</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x0000</resetValue>
+               <fields>
+                  <field>
+                     <name>TI1S</name>
+                     <description>TI1 selection</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>MMS</name>
+                     <description>Master mode selection</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>3</bitWidth>
+                  </field>
+                  <field>
+                     <name>CCDS</name>
+                     <description>Capture/compare DMA               selection</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>SMCR</name>
+               <displayName>SMCR</displayName>
+               <description>slave mode control register</description>
+               <addressOffset>0x8</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x0000</resetValue>
+               <fields>
+                  <field>
+                     <name>ETP</name>
+                     <description>External trigger polarity</description>
+                     <bitOffset>15</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>ECE</name>
+                     <description>External clock enable</description>
+                     <bitOffset>14</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>ETPS</name>
+                     <description>External trigger prescaler</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>ETF</name>
+                     <description>External trigger filter</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+                  <field>
+                     <name>MSM</name>
+                     <description>Master/Slave mode</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TS</name>
+                     <description>Trigger selection</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>3</bitWidth>
+                  </field>
+                  <field>
+                     <name>SMS</name>
+                     <description>Slave mode selection</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>3</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DIER</name>
+               <displayName>DIER</displayName>
+               <description>DMA/Interrupt enable register</description>
+               <addressOffset>0xC</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x0000</resetValue>
+               <fields>
+                  <field>
+                     <name>TDE</name>
+                     <description>Trigger DMA request enable</description>
+                     <bitOffset>14</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CC4DE</name>
+                     <description>Capture/Compare 4 DMA request               enable</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CC3DE</name>
+                     <description>Capture/Compare 3 DMA request               enable</description>
+                     <bitOffset>11</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CC2DE</name>
+                     <description>Capture/Compare 2 DMA request               enable</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CC1DE</name>
+                     <description>Capture/Compare 1 DMA request               enable</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>UDE</name>
+                     <description>Update DMA request enable</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TIE</name>
+                     <description>Trigger interrupt enable</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CC4IE</name>
+                     <description>Capture/Compare 4 interrupt               enable</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CC3IE</name>
+                     <description>Capture/Compare 3 interrupt               enable</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CC2IE</name>
+                     <description>Capture/Compare 2 interrupt               enable</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CC1IE</name>
+                     <description>Capture/Compare 1 interrupt               enable</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>UIE</name>
+                     <description>Update interrupt enable</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>SR</name>
+               <displayName>SR</displayName>
+               <description>status register</description>
+               <addressOffset>0x10</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x0000</resetValue>
+               <fields>
+                  <field>
+                     <name>CC4OF</name>
+                     <description>Capture/Compare 4 overcapture               flag</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CC3OF</name>
+                     <description>Capture/Compare 3 overcapture               flag</description>
+                     <bitOffset>11</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CC2OF</name>
+                     <description>Capture/compare 2 overcapture               flag</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CC1OF</name>
+                     <description>Capture/Compare 1 overcapture               flag</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TIF</name>
+                     <description>Trigger interrupt flag</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CC4IF</name>
+                     <description>Capture/Compare 4 interrupt               flag</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CC3IF</name>
+                     <description>Capture/Compare 3 interrupt               flag</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CC2IF</name>
+                     <description>Capture/Compare 2 interrupt               flag</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CC1IF</name>
+                     <description>Capture/compare 1 interrupt               flag</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>UIF</name>
+                     <description>Update interrupt flag</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>EGR</name>
+               <displayName>EGR</displayName>
+               <description>event generation register</description>
+               <addressOffset>0x14</addressOffset>
+               <size>0x20</size>
+               <access>write-only</access>
+               <resetValue>0x0000</resetValue>
+               <fields>
+                  <field>
+                     <name>TG</name>
+                     <description>Trigger generation</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CC4G</name>
+                     <description>Capture/compare 4               generation</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CC3G</name>
+                     <description>Capture/compare 3               generation</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CC2G</name>
+                     <description>Capture/compare 2               generation</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CC1G</name>
+                     <description>Capture/compare 1               generation</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>UG</name>
+                     <description>Update generation</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>CCMR1_Output</name>
+               <displayName>CCMR1_Output</displayName>
+               <description>capture/compare mode register 1 (output           mode)</description>
+               <addressOffset>0x18</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>OC2CE</name>
+                     <description>OC2CE</description>
+                     <bitOffset>15</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>OC2M</name>
+                     <description>OC2M</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>3</bitWidth>
+                  </field>
+                  <field>
+                     <name>OC2PE</name>
+                     <description>OC2PE</description>
+                     <bitOffset>11</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>OC2FE</name>
+                     <description>OC2FE</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CC2S</name>
+                     <description>CC2S</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>OC1CE</name>
+                     <description>OC1CE</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>OC1M</name>
+                     <description>OC1M</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>3</bitWidth>
+                  </field>
+                  <field>
+                     <name>OC1PE</name>
+                     <description>OC1PE</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>OC1FE</name>
+                     <description>OC1FE</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CC1S</name>
+                     <description>CC1S</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>CCMR1_Input</name>
+               <displayName>CCMR1_Input</displayName>
+               <description>capture/compare mode register 1 (input           mode)</description>
+               <alternateRegister>CCMR1_Output</alternateRegister>
+               <addressOffset>0x18</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>IC2F</name>
+                     <description>Input capture 2 filter</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+                  <field>
+                     <name>IC2PCS</name>
+                     <description>Input capture 2 prescaler</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>CC2S</name>
+                     <description>Capture/Compare 2               selection</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>IC1F</name>
+                     <description>Input capture 1 filter</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+                  <field>
+                     <name>ICPCS</name>
+                     <description>Input capture 1 prescaler</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>CC1S</name>
+                     <description>Capture/Compare 1               selection</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>CCMR2_Output</name>
+               <displayName>CCMR2_Output</displayName>
+               <description>capture/compare mode register 2 (output           mode)</description>
+               <addressOffset>0x1C</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>O24CE</name>
+                     <description>O24CE</description>
+                     <bitOffset>15</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>OC4M</name>
+                     <description>OC4M</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>3</bitWidth>
+                  </field>
+                  <field>
+                     <name>OC4PE</name>
+                     <description>OC4PE</description>
+                     <bitOffset>11</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>OC4FE</name>
+                     <description>OC4FE</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CC4S</name>
+                     <description>CC4S</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>OC3CE</name>
+                     <description>OC3CE</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>OC3M</name>
+                     <description>OC3M</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>3</bitWidth>
+                  </field>
+                  <field>
+                     <name>OC3PE</name>
+                     <description>OC3PE</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>OC3FE</name>
+                     <description>OC3FE</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CC3S</name>
+                     <description>CC3S</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>CCMR2_Input</name>
+               <displayName>CCMR2_Input</displayName>
+               <description>capture/compare mode register 2 (input           mode)</description>
+               <alternateRegister>CCMR2_Output</alternateRegister>
+               <addressOffset>0x1C</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>IC4F</name>
+                     <description>Input capture 4 filter</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+                  <field>
+                     <name>IC4PSC</name>
+                     <description>Input capture 4 prescaler</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>CC4S</name>
+                     <description>Capture/Compare 4               selection</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>IC3F</name>
+                     <description>Input capture 3 filter</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+                  <field>
+                     <name>IC3PSC</name>
+                     <description>Input capture 3 prescaler</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>CC3S</name>
+                     <description>Capture/compare 3               selection</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>CCER</name>
+               <displayName>CCER</displayName>
+               <description>capture/compare enable           register</description>
+               <addressOffset>0x20</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x0000</resetValue>
+               <fields>
+                  <field>
+                     <name>CC4NP</name>
+                     <description>Capture/Compare 4 output               Polarity</description>
+                     <bitOffset>15</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CC4P</name>
+                     <description>Capture/Compare 3 output               Polarity</description>
+                     <bitOffset>13</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CC4E</name>
+                     <description>Capture/Compare 4 output               enable</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CC3NP</name>
+                     <description>Capture/Compare 3 output               Polarity</description>
+                     <bitOffset>11</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CC3P</name>
+                     <description>Capture/Compare 3 output               Polarity</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CC3E</name>
+                     <description>Capture/Compare 3 output               enable</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CC2NP</name>
+                     <description>Capture/Compare 2 output               Polarity</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CC2P</name>
+                     <description>Capture/Compare 2 output               Polarity</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CC2E</name>
+                     <description>Capture/Compare 2 output               enable</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CC1NP</name>
+                     <description>Capture/Compare 1 output               Polarity</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CC1P</name>
+                     <description>Capture/Compare 1 output               Polarity</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CC1E</name>
+                     <description>Capture/Compare 1 output               enable</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>CNT</name>
+               <displayName>CNT</displayName>
+               <description>counter</description>
+               <addressOffset>0x24</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>CNT_H</name>
+                     <description>High counter value</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+                  <field>
+                     <name>CNT_L</name>
+                     <description>Low counter value</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>PSC</name>
+               <displayName>PSC</displayName>
+               <description>prescaler</description>
+               <addressOffset>0x28</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x0000</resetValue>
+               <fields>
+                  <field>
+                     <name>PSC</name>
+                     <description>Prescaler value</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>ARR</name>
+               <displayName>ARR</displayName>
+               <description>auto-reload register</description>
+               <addressOffset>0x2C</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>ARR_H</name>
+                     <description>High Auto-reload value</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+                  <field>
+                     <name>ARR_L</name>
+                     <description>Low Auto-reload value</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>CCR1</name>
+               <displayName>CCR1</displayName>
+               <description>capture/compare register 1</description>
+               <addressOffset>0x34</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>CCR1_H</name>
+                     <description>High Capture/Compare 1               value</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+                  <field>
+                     <name>CCR1_L</name>
+                     <description>Low Capture/Compare 1               value</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>CCR2</name>
+               <displayName>CCR2</displayName>
+               <description>capture/compare register 2</description>
+               <addressOffset>0x38</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>CCR2_H</name>
+                     <description>High Capture/Compare 2               value</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+                  <field>
+                     <name>CCR2_L</name>
+                     <description>Low Capture/Compare 2               value</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>CCR3</name>
+               <displayName>CCR3</displayName>
+               <description>capture/compare register 3</description>
+               <addressOffset>0x3C</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>CCR3_H</name>
+                     <description>High Capture/Compare value</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+                  <field>
+                     <name>CCR3_L</name>
+                     <description>Low Capture/Compare value</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>CCR4</name>
+               <displayName>CCR4</displayName>
+               <description>capture/compare register 4</description>
+               <addressOffset>0x40</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>CCR4_H</name>
+                     <description>High Capture/Compare value</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+                  <field>
+                     <name>CCR4_L</name>
+                     <description>Low Capture/Compare value</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DCR</name>
+               <displayName>DCR</displayName>
+               <description>DMA control register</description>
+               <addressOffset>0x48</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x0000</resetValue>
+               <fields>
+                  <field>
+                     <name>DBL</name>
+                     <description>DMA burst length</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>5</bitWidth>
+                  </field>
+                  <field>
+                     <name>DBA</name>
+                     <description>DMA base address</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>5</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DMAR</name>
+               <displayName>DMAR</displayName>
+               <description>DMA address for full transfer</description>
+               <addressOffset>0x4C</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x0000</resetValue>
+               <fields>
+                  <field>
+                     <name>DMAB</name>
+                     <description>DMA register for burst               accesses</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+               </fields>
+            </register>
+         </registers>
+      </peripheral>
+      <peripheral derivedFrom="TIM4">
+         <name>TIM5</name>
+         <baseAddress>0x40000C00</baseAddress>
+      </peripheral>
+      <peripheral>
+         <name>TIM9</name>
+         <description>General purpose timers</description>
+         <groupName>TIM</groupName>
+         <baseAddress>0x40014000</baseAddress>
+         <addressBlock>
+            <offset>0x0</offset>
+            <size>0x400</size>
+            <usage>registers</usage>
+         </addressBlock>
+         <registers>
+            <register>
+               <name>CR1</name>
+               <displayName>CR1</displayName>
+               <description>control register 1</description>
+               <addressOffset>0x0</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x0000</resetValue>
+               <fields>
+                  <field>
+                     <name>CKD</name>
+                     <description>Clock division</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>ARPE</name>
+                     <description>Auto-reload preload enable</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>OPM</name>
+                     <description>One-pulse mode</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>URS</name>
+                     <description>Update request source</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>UDIS</name>
+                     <description>Update disable</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CEN</name>
+                     <description>Counter enable</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>SMCR</name>
+               <displayName>SMCR</displayName>
+               <description>slave mode control register</description>
+               <addressOffset>0x8</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x0000</resetValue>
+               <fields>
+                  <field>
+                     <name>MSM</name>
+                     <description>Master/Slave mode</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TS</name>
+                     <description>Trigger selection</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>3</bitWidth>
+                  </field>
+                  <field>
+                     <name>SMS</name>
+                     <description>Slave mode selection</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>3</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DIER</name>
+               <displayName>DIER</displayName>
+               <description>DMA/Interrupt enable register</description>
+               <addressOffset>0xC</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x0000</resetValue>
+               <fields>
+                  <field>
+                     <name>TIE</name>
+                     <description>Trigger interrupt enable</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CC2IE</name>
+                     <description>Capture/Compare 2 interrupt               enable</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CC1IE</name>
+                     <description>Capture/Compare 1 interrupt               enable</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>UIE</name>
+                     <description>Update interrupt enable</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>SR</name>
+               <displayName>SR</displayName>
+               <description>status register</description>
+               <addressOffset>0x10</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x0000</resetValue>
+               <fields>
+                  <field>
+                     <name>CC2OF</name>
+                     <description>Capture/compare 2 overcapture               flag</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CC1OF</name>
+                     <description>Capture/Compare 1 overcapture               flag</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TIF</name>
+                     <description>Trigger interrupt flag</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CC2IF</name>
+                     <description>Capture/Compare 2 interrupt               flag</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CC1IF</name>
+                     <description>Capture/compare 1 interrupt               flag</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>UIF</name>
+                     <description>Update interrupt flag</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>EGR</name>
+               <displayName>EGR</displayName>
+               <description>event generation register</description>
+               <addressOffset>0x14</addressOffset>
+               <size>0x20</size>
+               <access>write-only</access>
+               <resetValue>0x0000</resetValue>
+               <fields>
+                  <field>
+                     <name>TG</name>
+                     <description>Trigger generation</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CC2G</name>
+                     <description>Capture/compare 2               generation</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CC1G</name>
+                     <description>Capture/compare 1               generation</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>UG</name>
+                     <description>Update generation</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>CCMR1_Output</name>
+               <displayName>CCMR1_Output</displayName>
+               <description>capture/compare mode register 1 (output           mode)</description>
+               <addressOffset>0x18</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>OC2M</name>
+                     <description>Output Compare 2 mode</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>3</bitWidth>
+                  </field>
+                  <field>
+                     <name>OC2PE</name>
+                     <description>Output Compare 2 preload               enable</description>
+                     <bitOffset>11</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>OC2FE</name>
+                     <description>Output Compare 2 fast               enable</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CC2S</name>
+                     <description>Capture/Compare 2               selection</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>OC1M</name>
+                     <description>Output Compare 1 mode</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>3</bitWidth>
+                  </field>
+                  <field>
+                     <name>OC1PE</name>
+                     <description>Output Compare 1 preload               enable</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>OC1FE</name>
+                     <description>Output Compare 1 fast               enable</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CC1S</name>
+                     <description>Capture/Compare 1               selection</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>CCMR1_Input</name>
+               <displayName>CCMR1_Input</displayName>
+               <description>capture/compare mode register 1 (input           mode)</description>
+               <alternateRegister>CCMR1_Output</alternateRegister>
+               <addressOffset>0x18</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>IC2F</name>
+                     <description>Input capture 2 filter</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>3</bitWidth>
+                  </field>
+                  <field>
+                     <name>IC2PCS</name>
+                     <description>Input capture 2 prescaler</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>CC2S</name>
+                     <description>Capture/Compare 2               selection</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>IC1F</name>
+                     <description>Input capture 1 filter</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>3</bitWidth>
+                  </field>
+                  <field>
+                     <name>ICPCS</name>
+                     <description>Input capture 1 prescaler</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>CC1S</name>
+                     <description>Capture/Compare 1               selection</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>CCER</name>
+               <displayName>CCER</displayName>
+               <description>capture/compare enable           register</description>
+               <addressOffset>0x20</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x0000</resetValue>
+               <fields>
+                  <field>
+                     <name>CC2NP</name>
+                     <description>Capture/Compare 2 output               Polarity</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CC2P</name>
+                     <description>Capture/Compare 2 output               Polarity</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CC2E</name>
+                     <description>Capture/Compare 2 output               enable</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CC1NP</name>
+                     <description>Capture/Compare 1 output               Polarity</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CC1P</name>
+                     <description>Capture/Compare 1 output               Polarity</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CC1E</name>
+                     <description>Capture/Compare 1 output               enable</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>CNT</name>
+               <displayName>CNT</displayName>
+               <description>counter</description>
+               <addressOffset>0x24</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>CNT</name>
+                     <description>counter value</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>PSC</name>
+               <displayName>PSC</displayName>
+               <description>prescaler</description>
+               <addressOffset>0x28</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x0000</resetValue>
+               <fields>
+                  <field>
+                     <name>PSC</name>
+                     <description>Prescaler value</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>ARR</name>
+               <displayName>ARR</displayName>
+               <description>auto-reload register</description>
+               <addressOffset>0x2C</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>ARR</name>
+                     <description>Auto-reload value</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>CCR1</name>
+               <displayName>CCR1</displayName>
+               <description>capture/compare register 1</description>
+               <addressOffset>0x34</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>CCR1</name>
+                     <description>Capture/Compare 1 value</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>CCR2</name>
+               <displayName>CCR2</displayName>
+               <description>capture/compare register 2</description>
+               <addressOffset>0x38</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>CCR2</name>
+                     <description>Capture/Compare 2 value</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+               </fields>
+            </register>
+         </registers>
+      </peripheral>
+      <peripheral derivedFrom="TIM9">
+         <name>TIM12</name>
+         <baseAddress>0x40001800</baseAddress>
+      </peripheral>
+      <peripheral>
+         <name>TIM10</name>
+         <description>General-purpose-timers</description>
+         <groupName>TIM</groupName>
+         <baseAddress>0x40014400</baseAddress>
+         <addressBlock>
+            <offset>0x0</offset>
+            <size>0x400</size>
+            <usage>registers</usage>
+         </addressBlock>
+         <interrupt>
+            <name>TIM5</name>
+            <description>TIM5 global interrupt</description>
+            <value>50</value>
+         </interrupt>
+         <registers>
+            <register>
+               <name>CR1</name>
+               <displayName>CR1</displayName>
+               <description>control register 1</description>
+               <addressOffset>0x0</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x0000</resetValue>
+               <fields>
+                  <field>
+                     <name>CKD</name>
+                     <description>Clock division</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>ARPE</name>
+                     <description>Auto-reload preload enable</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>URS</name>
+                     <description>Update request source</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>UDIS</name>
+                     <description>Update disable</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CEN</name>
+                     <description>Counter enable</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DIER</name>
+               <displayName>DIER</displayName>
+               <description>DMA/Interrupt enable register</description>
+               <addressOffset>0xC</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x0000</resetValue>
+               <fields>
+                  <field>
+                     <name>CC1IE</name>
+                     <description>Capture/Compare 1 interrupt               enable</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>UIE</name>
+                     <description>Update interrupt enable</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>SR</name>
+               <displayName>SR</displayName>
+               <description>status register</description>
+               <addressOffset>0x10</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x0000</resetValue>
+               <fields>
+                  <field>
+                     <name>CC1OF</name>
+                     <description>Capture/Compare 1 overcapture               flag</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CC1IF</name>
+                     <description>Capture/compare 1 interrupt               flag</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>UIF</name>
+                     <description>Update interrupt flag</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>EGR</name>
+               <displayName>EGR</displayName>
+               <description>event generation register</description>
+               <addressOffset>0x14</addressOffset>
+               <size>0x20</size>
+               <access>write-only</access>
+               <resetValue>0x0000</resetValue>
+               <fields>
+                  <field>
+                     <name>CC1G</name>
+                     <description>Capture/compare 1               generation</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>UG</name>
+                     <description>Update generation</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>CCMR1_Output</name>
+               <displayName>CCMR1_Output</displayName>
+               <description>capture/compare mode register 1 (output           mode)</description>
+               <addressOffset>0x18</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>OC1M</name>
+                     <description>Output Compare 1 mode</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>3</bitWidth>
+                  </field>
+                  <field>
+                     <name>OC1PE</name>
+                     <description>Output Compare 1 preload               enable</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>OC1FE</name>
+                     <description>Output Compare 1 fast               enable</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CC1S</name>
+                     <description>Capture/Compare 1               selection</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>CCMR1_Input</name>
+               <displayName>CCMR1_Input</displayName>
+               <description>capture/compare mode register 1 (input           mode)</description>
+               <alternateRegister>CCMR1_Output</alternateRegister>
+               <addressOffset>0x18</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>IC1F</name>
+                     <description>Input capture 1 filter</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+                  <field>
+                     <name>ICPCS</name>
+                     <description>Input capture 1 prescaler</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>CC1S</name>
+                     <description>Capture/Compare 1               selection</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>CCER</name>
+               <displayName>CCER</displayName>
+               <description>capture/compare enable           register</description>
+               <addressOffset>0x20</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x0000</resetValue>
+               <fields>
+                  <field>
+                     <name>CC1NP</name>
+                     <description>Capture/Compare 1 output               Polarity</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CC1P</name>
+                     <description>Capture/Compare 1 output               Polarity</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CC1E</name>
+                     <description>Capture/Compare 1 output               enable</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>CNT</name>
+               <displayName>CNT</displayName>
+               <description>counter</description>
+               <addressOffset>0x24</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>CNT</name>
+                     <description>counter value</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>PSC</name>
+               <displayName>PSC</displayName>
+               <description>prescaler</description>
+               <addressOffset>0x28</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x0000</resetValue>
+               <fields>
+                  <field>
+                     <name>PSC</name>
+                     <description>Prescaler value</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>ARR</name>
+               <displayName>ARR</displayName>
+               <description>auto-reload register</description>
+               <addressOffset>0x2C</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>ARR</name>
+                     <description>Auto-reload value</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>CCR1</name>
+               <displayName>CCR1</displayName>
+               <description>capture/compare register 1</description>
+               <addressOffset>0x34</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>CCR1</name>
+                     <description>Capture/Compare 1 value</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>SMCR</name>
+               <displayName>SMCR</displayName>
+               <description>slave mode control register</description>
+               <addressOffset>0x8</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>SMS3</name>
+                     <description>Slave mode selection</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>ETP</name>
+                     <description>External trigger polarity</description>
+                     <bitOffset>15</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>ECE</name>
+                     <description>External clock enable</description>
+                     <bitOffset>14</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>ETPS</name>
+                     <description>External trigger prescaler</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>ETF</name>
+                     <description>External trigger filter</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+                  <field>
+                     <name>MSM</name>
+                     <description>Master/slave mode</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TS</name>
+                     <description>Trigger selection</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>3</bitWidth>
+                  </field>
+                  <field>
+                     <name>SMS</name>
+                     <description>Slave mode selection</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>3</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OR</name>
+               <displayName>OR</displayName>
+               <description>option register</description>
+               <addressOffset>0x50</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>TI1_RMP</name>
+                     <description>TIM11 Input 1 remapping               capability</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+               </fields>
+            </register>
+         </registers>
+      </peripheral>
+      <peripheral derivedFrom="TIM10">
+         <name>TIM11</name>
+         <baseAddress>0x40014800</baseAddress>
+      </peripheral>
+      <peripheral derivedFrom="TIM10">
+         <name>TIM13</name>
+         <baseAddress>0x40001C00</baseAddress>
+      </peripheral>
+      <peripheral derivedFrom="TIM10">
+         <name>TIM14</name>
+         <baseAddress>0x40002000</baseAddress>
+      </peripheral>
+      <peripheral>
+         <name>TIM6</name>
+         <description>Basic timers</description>
+         <groupName>TIM</groupName>
+         <baseAddress>0x40001000</baseAddress>
+         <addressBlock>
+            <offset>0x0</offset>
+            <size>0x400</size>
+            <usage>registers</usage>
+         </addressBlock>
+         <interrupt>
+            <name>TIM6_DAC</name>
+            <description>TIM6 global interrupt, DAC1 and DAC2 underrun
+        error interrupt</description>
+            <value>54</value>
+         </interrupt>
+         <registers>
+            <register>
+               <name>CR1</name>
+               <displayName>CR1</displayName>
+               <description>control register 1</description>
+               <addressOffset>0x0</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x0000</resetValue>
+               <fields>
+                  <field>
+                     <name>ARPE</name>
+                     <description>Auto-reload preload enable</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>OPM</name>
+                     <description>One-pulse mode</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>URS</name>
+                     <description>Update request source</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>UDIS</name>
+                     <description>Update disable</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CEN</name>
+                     <description>Counter enable</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>CR2</name>
+               <displayName>CR2</displayName>
+               <description>control register 2</description>
+               <addressOffset>0x4</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x0000</resetValue>
+               <fields>
+                  <field>
+                     <name>MMS</name>
+                     <description>Master mode selection</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>3</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DIER</name>
+               <displayName>DIER</displayName>
+               <description>DMA/Interrupt enable register</description>
+               <addressOffset>0xC</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x0000</resetValue>
+               <fields>
+                  <field>
+                     <name>UDE</name>
+                     <description>Update DMA request enable</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>UIE</name>
+                     <description>Update interrupt enable</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>SR</name>
+               <displayName>SR</displayName>
+               <description>status register</description>
+               <addressOffset>0x10</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x0000</resetValue>
+               <fields>
+                  <field>
+                     <name>UIF</name>
+                     <description>Update interrupt flag</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>EGR</name>
+               <displayName>EGR</displayName>
+               <description>event generation register</description>
+               <addressOffset>0x14</addressOffset>
+               <size>0x20</size>
+               <access>write-only</access>
+               <resetValue>0x0000</resetValue>
+               <fields>
+                  <field>
+                     <name>UG</name>
+                     <description>Update generation</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>CNT</name>
+               <displayName>CNT</displayName>
+               <description>counter</description>
+               <addressOffset>0x24</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>CNT</name>
+                     <description>Low counter value</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>PSC</name>
+               <displayName>PSC</displayName>
+               <description>prescaler</description>
+               <addressOffset>0x28</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x0000</resetValue>
+               <fields>
+                  <field>
+                     <name>PSC</name>
+                     <description>Prescaler value</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>ARR</name>
+               <displayName>ARR</displayName>
+               <description>auto-reload register</description>
+               <addressOffset>0x2C</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>ARR</name>
+                     <description>Low Auto-reload value</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+               </fields>
+            </register>
+         </registers>
+      </peripheral>
+      <peripheral derivedFrom="TIM6">
+         <name>TIM7</name>
+         <baseAddress>0x40001400</baseAddress>
+         <interrupt>
+            <name>TIM7</name>
+            <description>TIM7 global interrupt</description>
+            <value>55</value>
+         </interrupt>
+      </peripheral>
+      <peripheral>
+         <name>Ethernet_MAC</name>
+         <description>Ethernet: media access control       (MAC)</description>
+         <groupName>Ethernet</groupName>
+         <baseAddress>0x40028000</baseAddress>
+         <addressBlock>
+            <offset>0x0</offset>
+            <size>0x100</size>
+            <usage>registers</usage>
+         </addressBlock>
+         <interrupt>
+            <name>ETH</name>
+            <description>Ethernet global interrupt</description>
+            <value>61</value>
+         </interrupt>
+         <interrupt>
+            <name>ETH_WKUP</name>
+            <description>Ethernet Wakeup through EXTI
+        line</description>
+            <value>62</value>
+         </interrupt>
+         <registers>
+            <register>
+               <name>MACCR</name>
+               <displayName>MACCR</displayName>
+               <description>Ethernet MAC configuration           register</description>
+               <addressOffset>0x0</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x0008000</resetValue>
+               <fields>
+                  <field>
+                     <name>RE</name>
+                     <description>RE</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TE</name>
+                     <description>TE</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>DC</name>
+                     <description>DC</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>BL</name>
+                     <description>BL</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>APCS</name>
+                     <description>APCS</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>RD</name>
+                     <description>RD</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>IPCO</name>
+                     <description>IPCO</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>DM</name>
+                     <description>DM</description>
+                     <bitOffset>11</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>LM</name>
+                     <description>LM</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>ROD</name>
+                     <description>ROD</description>
+                     <bitOffset>13</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FES</name>
+                     <description>FES</description>
+                     <bitOffset>14</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CSD</name>
+                     <description>CSD</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>IFG</name>
+                     <description>IFG</description>
+                     <bitOffset>17</bitOffset>
+                     <bitWidth>3</bitWidth>
+                  </field>
+                  <field>
+                     <name>JD</name>
+                     <description>JD</description>
+                     <bitOffset>22</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>WD</name>
+                     <description>WD</description>
+                     <bitOffset>23</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CSTF</name>
+                     <description>CSTF</description>
+                     <bitOffset>25</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>MACFFR</name>
+               <displayName>MACFFR</displayName>
+               <description>Ethernet MAC frame filter           register</description>
+               <addressOffset>0x4</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>PM</name>
+                     <description>PM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>HU</name>
+                     <description>HU</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>HM</name>
+                     <description>HM</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>DAIF</name>
+                     <description>DAIF</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>RAM</name>
+                     <description>RAM</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>BFD</name>
+                     <description>BFD</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>PCF</name>
+                     <description>PCF</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>SAIF</name>
+                     <description>SAIF</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>SAF</name>
+                     <description>SAF</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>HPF</name>
+                     <description>HPF</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>RA</name>
+                     <description>RA</description>
+                     <bitOffset>31</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>MACHTHR</name>
+               <displayName>MACHTHR</displayName>
+               <description>Ethernet MAC hash table high           register</description>
+               <addressOffset>0x8</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>HTH</name>
+                     <description>HTH</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>MACHTLR</name>
+               <displayName>MACHTLR</displayName>
+               <description>Ethernet MAC hash table low           register</description>
+               <addressOffset>0xC</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>HTL</name>
+                     <description>HTL</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>MACMIIAR</name>
+               <displayName>MACMIIAR</displayName>
+               <description>Ethernet MAC MII address           register</description>
+               <addressOffset>0x10</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>MB</name>
+                     <description>MB</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>MW</name>
+                     <description>MW</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CR</name>
+                     <description>CR</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>3</bitWidth>
+                  </field>
+                  <field>
+                     <name>MR</name>
+                     <description>MR</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>5</bitWidth>
+                  </field>
+                  <field>
+                     <name>PA</name>
+                     <description>PA</description>
+                     <bitOffset>11</bitOffset>
+                     <bitWidth>5</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>MACMIIDR</name>
+               <displayName>MACMIIDR</displayName>
+               <description>Ethernet MAC MII data register</description>
+               <addressOffset>0x14</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>TD</name>
+                     <description>TD</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>MACFCR</name>
+               <displayName>MACFCR</displayName>
+               <description>Ethernet MAC flow control           register</description>
+               <addressOffset>0x18</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>FCB</name>
+                     <description>FCB</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TFCE</name>
+                     <description>TFCE</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>RFCE</name>
+                     <description>RFCE</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>UPFD</name>
+                     <description>UPFD</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>PLT</name>
+                     <description>PLT</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>ZQPD</name>
+                     <description>ZQPD</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>PT</name>
+                     <description>PT</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>MACVLANTR</name>
+               <displayName>MACVLANTR</displayName>
+               <description>Ethernet MAC VLAN tag register</description>
+               <addressOffset>0x1C</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>VLANTI</name>
+                     <description>VLANTI</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+                  <field>
+                     <name>VLANTC</name>
+                     <description>VLANTC</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>MACPMTCSR</name>
+               <displayName>MACPMTCSR</displayName>
+               <description>Ethernet MAC PMT control and status           register</description>
+               <addressOffset>0x2C</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>PD</name>
+                     <description>PD</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>MPE</name>
+                     <description>MPE</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>WFE</name>
+                     <description>WFE</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>MPR</name>
+                     <description>MPR</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>WFR</name>
+                     <description>WFR</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>GU</name>
+                     <description>GU</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>WFFRPR</name>
+                     <description>WFFRPR</description>
+                     <bitOffset>31</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>MACDBGR</name>
+               <displayName>MACDBGR</displayName>
+               <description>Ethernet MAC debug register</description>
+               <addressOffset>0x34</addressOffset>
+               <size>0x20</size>
+               <access>read-only</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>CR</name>
+                     <description>CR</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CSR</name>
+                     <description>CSR</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>ROR</name>
+                     <description>ROR</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>MCF</name>
+                     <description>MCF</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>MCP</name>
+                     <description>MCP</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>MCFHP</name>
+                     <description>MCFHP</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>MACSR</name>
+               <displayName>MACSR</displayName>
+               <description>Ethernet MAC interrupt status           register</description>
+               <addressOffset>0x38</addressOffset>
+               <size>0x20</size>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>PMTS</name>
+                     <description>PMTS</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-only</access>
+                  </field>
+                  <field>
+                     <name>MMCS</name>
+                     <description>MMCS</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-only</access>
+                  </field>
+                  <field>
+                     <name>MMCRS</name>
+                     <description>MMCRS</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-only</access>
+                  </field>
+                  <field>
+                     <name>MMCTS</name>
+                     <description>MMCTS</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-only</access>
+                  </field>
+                  <field>
+                     <name>TSTS</name>
+                     <description>TSTS</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>MACIMR</name>
+               <displayName>MACIMR</displayName>
+               <description>Ethernet MAC interrupt mask           register</description>
+               <addressOffset>0x3C</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>PMTIM</name>
+                     <description>PMTIM</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TSTIM</name>
+                     <description>TSTIM</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>MACA0HR</name>
+               <displayName>MACA0HR</displayName>
+               <description>Ethernet MAC address 0 high           register</description>
+               <addressOffset>0x40</addressOffset>
+               <size>0x20</size>
+               <resetValue>0x0010FFFF</resetValue>
+               <fields>
+                  <field>
+                     <name>MACA0H</name>
+                     <description>MAC address0 high</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>16</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>MO</name>
+                     <description>Always 1</description>
+                     <bitOffset>31</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-only</access>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>MACA0LR</name>
+               <displayName>MACA0LR</displayName>
+               <description>Ethernet MAC address 0 low           register</description>
+               <addressOffset>0x44</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0xFFFFFFFF</resetValue>
+               <fields>
+                  <field>
+                     <name>MACA0L</name>
+                     <description>0</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>MACA1HR</name>
+               <displayName>MACA1HR</displayName>
+               <description>Ethernet MAC address 1 high           register</description>
+               <addressOffset>0x48</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x0000FFFF</resetValue>
+               <fields>
+                  <field>
+                     <name>MACA1H</name>
+                     <description>MACA1H</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+                  <field>
+                     <name>MBC</name>
+                     <description>MBC</description>
+                     <bitOffset>24</bitOffset>
+                     <bitWidth>6</bitWidth>
+                  </field>
+                  <field>
+                     <name>SA</name>
+                     <description>SA</description>
+                     <bitOffset>30</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>AE</name>
+                     <description>AE</description>
+                     <bitOffset>31</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>MACA1LR</name>
+               <displayName>MACA1LR</displayName>
+               <description>Ethernet MAC address1 low           register</description>
+               <addressOffset>0x4C</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0xFFFFFFFF</resetValue>
+               <fields>
+                  <field>
+                     <name>MACA1LR</name>
+                     <description>MACA1LR</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>MACA2HR</name>
+               <displayName>MACA2HR</displayName>
+               <description>Ethernet MAC address 2 high           register</description>
+               <addressOffset>0x50</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x0000FFFF</resetValue>
+               <fields>
+                  <field>
+                     <name>MAC2AH</name>
+                     <description>MAC2AH</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+                  <field>
+                     <name>MBC</name>
+                     <description>MBC</description>
+                     <bitOffset>24</bitOffset>
+                     <bitWidth>6</bitWidth>
+                  </field>
+                  <field>
+                     <name>SA</name>
+                     <description>SA</description>
+                     <bitOffset>30</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>AE</name>
+                     <description>AE</description>
+                     <bitOffset>31</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>MACA2LR</name>
+               <displayName>MACA2LR</displayName>
+               <description>Ethernet MAC address 2 low           register</description>
+               <addressOffset>0x54</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0xFFFFFFFF</resetValue>
+               <fields>
+                  <field>
+                     <name>MACA2L</name>
+                     <description>MACA2L</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>31</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>MACA3HR</name>
+               <displayName>MACA3HR</displayName>
+               <description>Ethernet MAC address 3 high           register</description>
+               <addressOffset>0x58</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x0000FFFF</resetValue>
+               <fields>
+                  <field>
+                     <name>MACA3H</name>
+                     <description>MACA3H</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+                  <field>
+                     <name>MBC</name>
+                     <description>MBC</description>
+                     <bitOffset>24</bitOffset>
+                     <bitWidth>6</bitWidth>
+                  </field>
+                  <field>
+                     <name>SA</name>
+                     <description>SA</description>
+                     <bitOffset>30</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>AE</name>
+                     <description>AE</description>
+                     <bitOffset>31</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>MACA3LR</name>
+               <displayName>MACA3LR</displayName>
+               <description>Ethernet MAC address 3 low           register</description>
+               <addressOffset>0x5C</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0xFFFFFFFF</resetValue>
+               <fields>
+                  <field>
+                     <name>MBCA3L</name>
+                     <description>MBCA3L</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>MACRWUFFER</name>
+               <displayName>MACRWUFFER</displayName>
+               <description>Ethernet MAC remote wakeup frame filter           register</description>
+               <addressOffset>0x60</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0xFFFFFFFF</resetValue>
+            </register>
+         </registers>
+      </peripheral>
+      <peripheral>
+         <name>CRC</name>
+         <description>Cryptographic processor</description>
+         <groupName>CRC</groupName>
+         <baseAddress>0x40023000</baseAddress>
+         <addressBlock>
+            <offset>0x0</offset>
+            <size>0x400</size>
+            <usage>registers</usage>
+         </addressBlock>
+         <registers>
+            <register>
+               <name>DR</name>
+               <displayName>DR</displayName>
+               <description>Data register</description>
+               <addressOffset>0x0</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0xFFFFFFFF</resetValue>
+               <fields>
+                  <field>
+                     <name>DR</name>
+                     <description>Data Register</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>IDR</name>
+               <displayName>IDR</displayName>
+               <description>Independent Data register</description>
+               <addressOffset>0x4</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>IDR</name>
+                     <description>Independent Data register</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>CR</name>
+               <displayName>CR</displayName>
+               <description>Control register</description>
+               <addressOffset>0x8</addressOffset>
+               <size>0x20</size>
+               <access>write-only</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>CR</name>
+                     <description>Control regidter</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>INIT</name>
+               <displayName>INIT</displayName>
+               <description>Initial CRC value</description>
+               <addressOffset>0xC</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>CRC_INIT</name>
+                     <description>Programmable initial CRC               value</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>POL</name>
+               <displayName>POL</displayName>
+               <description>CRC polynomial</description>
+               <addressOffset>0x10</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>POL</name>
+                     <description>Programmable polynomial</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+         </registers>
+      </peripheral>
+      <peripheral>
+         <name>CAN1</name>
+         <description>Controller area network</description>
+         <groupName>CAN</groupName>
+         <baseAddress>0x40006400</baseAddress>
+         <addressBlock>
+            <offset>0x0</offset>
+            <size>0x400</size>
+            <usage>registers</usage>
+         </addressBlock>
+         <interrupt>
+            <name>CAN1_TX</name>
+            <description>CAN1 TX interrupts</description>
+            <value>19</value>
+         </interrupt>
+         <interrupt>
+            <name>CAN1_RX0</name>
+            <description>CAN1 RX0 interrupts</description>
+            <value>20</value>
+         </interrupt>
+         <interrupt>
+            <name>CAN1_RX1</name>
+            <description>CAN1 RX1 interrupts</description>
+            <value>21</value>
+         </interrupt>
+         <interrupt>
+            <name>CAN1_SCE</name>
+            <description>CAN1 SCE interrupt</description>
+            <value>22</value>
+         </interrupt>
+         <registers>
+            <register>
+               <name>MCR</name>
+               <displayName>MCR</displayName>
+               <description>master control register</description>
+               <addressOffset>0x0</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00010002</resetValue>
+               <fields>
+                  <field>
+                     <name>DBF</name>
+                     <description>DBF</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>RESET</name>
+                     <description>RESET</description>
+                     <bitOffset>15</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TTCM</name>
+                     <description>TTCM</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>ABOM</name>
+                     <description>ABOM</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>AWUM</name>
+                     <description>AWUM</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>NART</name>
+                     <description>NART</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>RFLM</name>
+                     <description>RFLM</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TXFP</name>
+                     <description>TXFP</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>SLEEP</name>
+                     <description>SLEEP</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>INRQ</name>
+                     <description>INRQ</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>MSR</name>
+               <displayName>MSR</displayName>
+               <description>master status register</description>
+               <addressOffset>0x4</addressOffset>
+               <size>0x20</size>
+               <resetValue>0x00000C02</resetValue>
+               <fields>
+                  <field>
+                     <name>RX</name>
+                     <description>RX</description>
+                     <bitOffset>11</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-only</access>
+                  </field>
+                  <field>
+                     <name>SAMP</name>
+                     <description>SAMP</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-only</access>
+                  </field>
+                  <field>
+                     <name>RXM</name>
+                     <description>RXM</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-only</access>
+                  </field>
+                  <field>
+                     <name>TXM</name>
+                     <description>TXM</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-only</access>
+                  </field>
+                  <field>
+                     <name>SLAKI</name>
+                     <description>SLAKI</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>WKUI</name>
+                     <description>WKUI</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>ERRI</name>
+                     <description>ERRI</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>SLAK</name>
+                     <description>SLAK</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-only</access>
+                  </field>
+                  <field>
+                     <name>INAK</name>
+                     <description>INAK</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-only</access>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>TSR</name>
+               <displayName>TSR</displayName>
+               <description>transmit status register</description>
+               <addressOffset>0x8</addressOffset>
+               <size>0x20</size>
+               <resetValue>0x1C000000</resetValue>
+               <fields>
+                  <field>
+                     <name>LOW2</name>
+                     <description>Lowest priority flag for mailbox               2</description>
+                     <bitOffset>31</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-only</access>
+                  </field>
+                  <field>
+                     <name>LOW1</name>
+                     <description>Lowest priority flag for mailbox               1</description>
+                     <bitOffset>30</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-only</access>
+                  </field>
+                  <field>
+                     <name>LOW0</name>
+                     <description>Lowest priority flag for mailbox               0</description>
+                     <bitOffset>29</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-only</access>
+                  </field>
+                  <field>
+                     <name>TME2</name>
+                     <description>Lowest priority flag for mailbox               2</description>
+                     <bitOffset>28</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-only</access>
+                  </field>
+                  <field>
+                     <name>TME1</name>
+                     <description>Lowest priority flag for mailbox               1</description>
+                     <bitOffset>27</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-only</access>
+                  </field>
+                  <field>
+                     <name>TME0</name>
+                     <description>Lowest priority flag for mailbox               0</description>
+                     <bitOffset>26</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-only</access>
+                  </field>
+                  <field>
+                     <name>CODE</name>
+                     <description>CODE</description>
+                     <bitOffset>24</bitOffset>
+                     <bitWidth>2</bitWidth>
+                     <access>read-only</access>
+                  </field>
+                  <field>
+                     <name>ABRQ2</name>
+                     <description>ABRQ2</description>
+                     <bitOffset>23</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>TERR2</name>
+                     <description>TERR2</description>
+                     <bitOffset>19</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>ALST2</name>
+                     <description>ALST2</description>
+                     <bitOffset>18</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>TXOK2</name>
+                     <description>TXOK2</description>
+                     <bitOffset>17</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>RQCP2</name>
+                     <description>RQCP2</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>ABRQ1</name>
+                     <description>ABRQ1</description>
+                     <bitOffset>15</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>TERR1</name>
+                     <description>TERR1</description>
+                     <bitOffset>11</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>ALST1</name>
+                     <description>ALST1</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>TXOK1</name>
+                     <description>TXOK1</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>RQCP1</name>
+                     <description>RQCP1</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>ABRQ0</name>
+                     <description>ABRQ0</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>TERR0</name>
+                     <description>TERR0</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>ALST0</name>
+                     <description>ALST0</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>TXOK0</name>
+                     <description>TXOK0</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>RQCP0</name>
+                     <description>RQCP0</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>RF0R</name>
+               <displayName>RF0R</displayName>
+               <description>receive FIFO 0 register</description>
+               <addressOffset>0xC</addressOffset>
+               <size>0x20</size>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>RFOM0</name>
+                     <description>RFOM0</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>FOVR0</name>
+                     <description>FOVR0</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>FULL0</name>
+                     <description>FULL0</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>FMP0</name>
+                     <description>FMP0</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>2</bitWidth>
+                     <access>read-only</access>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>RF1R</name>
+               <displayName>RF1R</displayName>
+               <description>receive FIFO 1 register</description>
+               <addressOffset>0x10</addressOffset>
+               <size>0x20</size>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>RFOM1</name>
+                     <description>RFOM1</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>FOVR1</name>
+                     <description>FOVR1</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>FULL1</name>
+                     <description>FULL1</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>FMP1</name>
+                     <description>FMP1</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>2</bitWidth>
+                     <access>read-only</access>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>IER</name>
+               <displayName>IER</displayName>
+               <description>interrupt enable register</description>
+               <addressOffset>0x14</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>SLKIE</name>
+                     <description>SLKIE</description>
+                     <bitOffset>17</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>WKUIE</name>
+                     <description>WKUIE</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>ERRIE</name>
+                     <description>ERRIE</description>
+                     <bitOffset>15</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>LECIE</name>
+                     <description>LECIE</description>
+                     <bitOffset>11</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>BOFIE</name>
+                     <description>BOFIE</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>EPVIE</name>
+                     <description>EPVIE</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>EWGIE</name>
+                     <description>EWGIE</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FOVIE1</name>
+                     <description>FOVIE1</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FFIE1</name>
+                     <description>FFIE1</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FMPIE1</name>
+                     <description>FMPIE1</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FOVIE0</name>
+                     <description>FOVIE0</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FFIE0</name>
+                     <description>FFIE0</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FMPIE0</name>
+                     <description>FMPIE0</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TMEIE</name>
+                     <description>TMEIE</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>ESR</name>
+               <displayName>ESR</displayName>
+               <description>interrupt enable register</description>
+               <addressOffset>0x18</addressOffset>
+               <size>0x20</size>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>REC</name>
+                     <description>REC</description>
+                     <bitOffset>24</bitOffset>
+                     <bitWidth>8</bitWidth>
+                     <access>read-only</access>
+                  </field>
+                  <field>
+                     <name>TEC</name>
+                     <description>TEC</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>8</bitWidth>
+                     <access>read-only</access>
+                  </field>
+                  <field>
+                     <name>LEC</name>
+                     <description>LEC</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>3</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>BOFF</name>
+                     <description>BOFF</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-only</access>
+                  </field>
+                  <field>
+                     <name>EPVF</name>
+                     <description>EPVF</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-only</access>
+                  </field>
+                  <field>
+                     <name>EWGF</name>
+                     <description>EWGF</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-only</access>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>BTR</name>
+               <displayName>BTR</displayName>
+               <description>bit timing register</description>
+               <addressOffset>0x1C</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>SILM</name>
+                     <description>SILM</description>
+                     <bitOffset>31</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>LBKM</name>
+                     <description>LBKM</description>
+                     <bitOffset>30</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>SJW</name>
+                     <description>SJW</description>
+                     <bitOffset>24</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>TS2</name>
+                     <description>TS2</description>
+                     <bitOffset>20</bitOffset>
+                     <bitWidth>3</bitWidth>
+                  </field>
+                  <field>
+                     <name>TS1</name>
+                     <description>TS1</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+                  <field>
+                     <name>BRP</name>
+                     <description>BRP</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>10</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>TI0R</name>
+               <displayName>TI0R</displayName>
+               <description>TX mailbox identifier register</description>
+               <addressOffset>0x180</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>STID</name>
+                     <description>STID</description>
+                     <bitOffset>21</bitOffset>
+                     <bitWidth>11</bitWidth>
+                  </field>
+                  <field>
+                     <name>EXID</name>
+                     <description>EXID</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>18</bitWidth>
+                  </field>
+                  <field>
+                     <name>IDE</name>
+                     <description>IDE</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>RTR</name>
+                     <description>RTR</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TXRQ</name>
+                     <description>TXRQ</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>TDT0R</name>
+               <displayName>TDT0R</displayName>
+               <description>mailbox data length control and time stamp           register</description>
+               <addressOffset>0x184</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>TIME</name>
+                     <description>TIME</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+                  <field>
+                     <name>TGT</name>
+                     <description>TGT</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>DLC</name>
+                     <description>DLC</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>TDL0R</name>
+               <displayName>TDL0R</displayName>
+               <description>mailbox data low register</description>
+               <addressOffset>0x188</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DATA3</name>
+                     <description>DATA3</description>
+                     <bitOffset>24</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+                  <field>
+                     <name>DATA2</name>
+                     <description>DATA2</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+                  <field>
+                     <name>DATA1</name>
+                     <description>DATA1</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+                  <field>
+                     <name>DATA0</name>
+                     <description>DATA0</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>TDH0R</name>
+               <displayName>TDH0R</displayName>
+               <description>mailbox data high register</description>
+               <addressOffset>0x18C</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DATA7</name>
+                     <description>DATA7</description>
+                     <bitOffset>24</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+                  <field>
+                     <name>DATA6</name>
+                     <description>DATA6</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+                  <field>
+                     <name>DATA5</name>
+                     <description>DATA5</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+                  <field>
+                     <name>DATA4</name>
+                     <description>DATA4</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>TI1R</name>
+               <displayName>TI1R</displayName>
+               <description>mailbox identifier register</description>
+               <addressOffset>0x190</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>STID</name>
+                     <description>STID</description>
+                     <bitOffset>21</bitOffset>
+                     <bitWidth>11</bitWidth>
+                  </field>
+                  <field>
+                     <name>EXID</name>
+                     <description>EXID</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>18</bitWidth>
+                  </field>
+                  <field>
+                     <name>IDE</name>
+                     <description>IDE</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>RTR</name>
+                     <description>RTR</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TXRQ</name>
+                     <description>TXRQ</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>TDT1R</name>
+               <displayName>TDT1R</displayName>
+               <description>mailbox data length control and time stamp           register</description>
+               <addressOffset>0x194</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>TIME</name>
+                     <description>TIME</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+                  <field>
+                     <name>TGT</name>
+                     <description>TGT</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>DLC</name>
+                     <description>DLC</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>TDL1R</name>
+               <displayName>TDL1R</displayName>
+               <description>mailbox data low register</description>
+               <addressOffset>0x198</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DATA3</name>
+                     <description>DATA3</description>
+                     <bitOffset>24</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+                  <field>
+                     <name>DATA2</name>
+                     <description>DATA2</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+                  <field>
+                     <name>DATA1</name>
+                     <description>DATA1</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+                  <field>
+                     <name>DATA0</name>
+                     <description>DATA0</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>TDH1R</name>
+               <displayName>TDH1R</displayName>
+               <description>mailbox data high register</description>
+               <addressOffset>0x19C</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DATA7</name>
+                     <description>DATA7</description>
+                     <bitOffset>24</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+                  <field>
+                     <name>DATA6</name>
+                     <description>DATA6</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+                  <field>
+                     <name>DATA5</name>
+                     <description>DATA5</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+                  <field>
+                     <name>DATA4</name>
+                     <description>DATA4</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>TI2R</name>
+               <displayName>TI2R</displayName>
+               <description>mailbox identifier register</description>
+               <addressOffset>0x1A0</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>STID</name>
+                     <description>STID</description>
+                     <bitOffset>21</bitOffset>
+                     <bitWidth>11</bitWidth>
+                  </field>
+                  <field>
+                     <name>EXID</name>
+                     <description>EXID</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>18</bitWidth>
+                  </field>
+                  <field>
+                     <name>IDE</name>
+                     <description>IDE</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>RTR</name>
+                     <description>RTR</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TXRQ</name>
+                     <description>TXRQ</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>TDT2R</name>
+               <displayName>TDT2R</displayName>
+               <description>mailbox data length control and time stamp           register</description>
+               <addressOffset>0x1A4</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>TIME</name>
+                     <description>TIME</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+                  <field>
+                     <name>TGT</name>
+                     <description>TGT</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>DLC</name>
+                     <description>DLC</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>TDL2R</name>
+               <displayName>TDL2R</displayName>
+               <description>mailbox data low register</description>
+               <addressOffset>0x1A8</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DATA3</name>
+                     <description>DATA3</description>
+                     <bitOffset>24</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+                  <field>
+                     <name>DATA2</name>
+                     <description>DATA2</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+                  <field>
+                     <name>DATA1</name>
+                     <description>DATA1</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+                  <field>
+                     <name>DATA0</name>
+                     <description>DATA0</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>TDH2R</name>
+               <displayName>TDH2R</displayName>
+               <description>mailbox data high register</description>
+               <addressOffset>0x1AC</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DATA7</name>
+                     <description>DATA7</description>
+                     <bitOffset>24</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+                  <field>
+                     <name>DATA6</name>
+                     <description>DATA6</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+                  <field>
+                     <name>DATA5</name>
+                     <description>DATA5</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+                  <field>
+                     <name>DATA4</name>
+                     <description>DATA4</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>RI0R</name>
+               <displayName>RI0R</displayName>
+               <description>receive FIFO mailbox identifier           register</description>
+               <addressOffset>0x1B0</addressOffset>
+               <size>0x20</size>
+               <access>read-only</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>STID</name>
+                     <description>STID</description>
+                     <bitOffset>21</bitOffset>
+                     <bitWidth>11</bitWidth>
+                  </field>
+                  <field>
+                     <name>EXID</name>
+                     <description>EXID</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>18</bitWidth>
+                  </field>
+                  <field>
+                     <name>IDE</name>
+                     <description>IDE</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>RTR</name>
+                     <description>RTR</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>RDT0R</name>
+               <displayName>RDT0R</displayName>
+               <description>mailbox data high register</description>
+               <addressOffset>0x1B4</addressOffset>
+               <size>0x20</size>
+               <access>read-only</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>TIME</name>
+                     <description>TIME</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+                  <field>
+                     <name>FMI</name>
+                     <description>FMI</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+                  <field>
+                     <name>DLC</name>
+                     <description>DLC</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>RDL0R</name>
+               <displayName>RDL0R</displayName>
+               <description>mailbox data high register</description>
+               <addressOffset>0x1B8</addressOffset>
+               <size>0x20</size>
+               <access>read-only</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DATA3</name>
+                     <description>DATA3</description>
+                     <bitOffset>24</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+                  <field>
+                     <name>DATA2</name>
+                     <description>DATA2</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+                  <field>
+                     <name>DATA1</name>
+                     <description>DATA1</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+                  <field>
+                     <name>DATA0</name>
+                     <description>DATA0</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>RDH0R</name>
+               <displayName>RDH0R</displayName>
+               <description>receive FIFO mailbox data high           register</description>
+               <addressOffset>0x1BC</addressOffset>
+               <size>0x20</size>
+               <access>read-only</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DATA7</name>
+                     <description>DATA7</description>
+                     <bitOffset>24</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+                  <field>
+                     <name>DATA6</name>
+                     <description>DATA6</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+                  <field>
+                     <name>DATA5</name>
+                     <description>DATA5</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+                  <field>
+                     <name>DATA4</name>
+                     <description>DATA4</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>RI1R</name>
+               <displayName>RI1R</displayName>
+               <description>mailbox data high register</description>
+               <addressOffset>0x1C0</addressOffset>
+               <size>0x20</size>
+               <access>read-only</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>STID</name>
+                     <description>STID</description>
+                     <bitOffset>21</bitOffset>
+                     <bitWidth>11</bitWidth>
+                  </field>
+                  <field>
+                     <name>EXID</name>
+                     <description>EXID</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>18</bitWidth>
+                  </field>
+                  <field>
+                     <name>IDE</name>
+                     <description>IDE</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>RTR</name>
+                     <description>RTR</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>RDT1R</name>
+               <displayName>RDT1R</displayName>
+               <description>mailbox data high register</description>
+               <addressOffset>0x1C4</addressOffset>
+               <size>0x20</size>
+               <access>read-only</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>TIME</name>
+                     <description>TIME</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+                  <field>
+                     <name>FMI</name>
+                     <description>FMI</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+                  <field>
+                     <name>DLC</name>
+                     <description>DLC</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>RDL1R</name>
+               <displayName>RDL1R</displayName>
+               <description>mailbox data high register</description>
+               <addressOffset>0x1C8</addressOffset>
+               <size>0x20</size>
+               <access>read-only</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DATA3</name>
+                     <description>DATA3</description>
+                     <bitOffset>24</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+                  <field>
+                     <name>DATA2</name>
+                     <description>DATA2</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+                  <field>
+                     <name>DATA1</name>
+                     <description>DATA1</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+                  <field>
+                     <name>DATA0</name>
+                     <description>DATA0</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>RDH1R</name>
+               <displayName>RDH1R</displayName>
+               <description>mailbox data high register</description>
+               <addressOffset>0x1CC</addressOffset>
+               <size>0x20</size>
+               <access>read-only</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DATA7</name>
+                     <description>DATA7</description>
+                     <bitOffset>24</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+                  <field>
+                     <name>DATA6</name>
+                     <description>DATA6</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+                  <field>
+                     <name>DATA5</name>
+                     <description>DATA5</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+                  <field>
+                     <name>DATA4</name>
+                     <description>DATA4</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>FMR</name>
+               <displayName>FMR</displayName>
+               <description>filter master register</description>
+               <addressOffset>0x200</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x2A1C0E01</resetValue>
+               <fields>
+                  <field>
+                     <name>CAN2SB</name>
+                     <description>CAN2SB</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>6</bitWidth>
+                  </field>
+                  <field>
+                     <name>FINIT</name>
+                     <description>FINIT</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>FM1R</name>
+               <displayName>FM1R</displayName>
+               <description>filter mode register</description>
+               <addressOffset>0x204</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>FBM0</name>
+                     <description>Filter mode</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FBM1</name>
+                     <description>Filter mode</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FBM2</name>
+                     <description>Filter mode</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FBM3</name>
+                     <description>Filter mode</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FBM4</name>
+                     <description>Filter mode</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FBM5</name>
+                     <description>Filter mode</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FBM6</name>
+                     <description>Filter mode</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FBM7</name>
+                     <description>Filter mode</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FBM8</name>
+                     <description>Filter mode</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FBM9</name>
+                     <description>Filter mode</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FBM10</name>
+                     <description>Filter mode</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FBM11</name>
+                     <description>Filter mode</description>
+                     <bitOffset>11</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FBM12</name>
+                     <description>Filter mode</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FBM13</name>
+                     <description>Filter mode</description>
+                     <bitOffset>13</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FBM14</name>
+                     <description>Filter mode</description>
+                     <bitOffset>14</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FBM15</name>
+                     <description>Filter mode</description>
+                     <bitOffset>15</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FBM16</name>
+                     <description>Filter mode</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FBM17</name>
+                     <description>Filter mode</description>
+                     <bitOffset>17</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FBM18</name>
+                     <description>Filter mode</description>
+                     <bitOffset>18</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FBM19</name>
+                     <description>Filter mode</description>
+                     <bitOffset>19</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FBM20</name>
+                     <description>Filter mode</description>
+                     <bitOffset>20</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FBM21</name>
+                     <description>Filter mode</description>
+                     <bitOffset>21</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FBM22</name>
+                     <description>Filter mode</description>
+                     <bitOffset>22</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FBM23</name>
+                     <description>Filter mode</description>
+                     <bitOffset>23</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FBM24</name>
+                     <description>Filter mode</description>
+                     <bitOffset>24</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FBM25</name>
+                     <description>Filter mode</description>
+                     <bitOffset>25</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FBM26</name>
+                     <description>Filter mode</description>
+                     <bitOffset>26</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FBM27</name>
+                     <description>Filter mode</description>
+                     <bitOffset>27</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>FS1R</name>
+               <displayName>FS1R</displayName>
+               <description>filter scale register</description>
+               <addressOffset>0x20C</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>FSC0</name>
+                     <description>Filter scale configuration</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FSC1</name>
+                     <description>Filter scale configuration</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FSC2</name>
+                     <description>Filter scale configuration</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FSC3</name>
+                     <description>Filter scale configuration</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FSC4</name>
+                     <description>Filter scale configuration</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FSC5</name>
+                     <description>Filter scale configuration</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FSC6</name>
+                     <description>Filter scale configuration</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FSC7</name>
+                     <description>Filter scale configuration</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FSC8</name>
+                     <description>Filter scale configuration</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FSC9</name>
+                     <description>Filter scale configuration</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FSC10</name>
+                     <description>Filter scale configuration</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FSC11</name>
+                     <description>Filter scale configuration</description>
+                     <bitOffset>11</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FSC12</name>
+                     <description>Filter scale configuration</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FSC13</name>
+                     <description>Filter scale configuration</description>
+                     <bitOffset>13</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FSC14</name>
+                     <description>Filter scale configuration</description>
+                     <bitOffset>14</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FSC15</name>
+                     <description>Filter scale configuration</description>
+                     <bitOffset>15</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FSC16</name>
+                     <description>Filter scale configuration</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FSC17</name>
+                     <description>Filter scale configuration</description>
+                     <bitOffset>17</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FSC18</name>
+                     <description>Filter scale configuration</description>
+                     <bitOffset>18</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FSC19</name>
+                     <description>Filter scale configuration</description>
+                     <bitOffset>19</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FSC20</name>
+                     <description>Filter scale configuration</description>
+                     <bitOffset>20</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FSC21</name>
+                     <description>Filter scale configuration</description>
+                     <bitOffset>21</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FSC22</name>
+                     <description>Filter scale configuration</description>
+                     <bitOffset>22</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FSC23</name>
+                     <description>Filter scale configuration</description>
+                     <bitOffset>23</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FSC24</name>
+                     <description>Filter scale configuration</description>
+                     <bitOffset>24</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FSC25</name>
+                     <description>Filter scale configuration</description>
+                     <bitOffset>25</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FSC26</name>
+                     <description>Filter scale configuration</description>
+                     <bitOffset>26</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FSC27</name>
+                     <description>Filter scale configuration</description>
+                     <bitOffset>27</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>FFA1R</name>
+               <displayName>FFA1R</displayName>
+               <description>filter FIFO assignment           register</description>
+               <addressOffset>0x214</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>FFA0</name>
+                     <description>Filter FIFO assignment for filter               0</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FFA1</name>
+                     <description>Filter FIFO assignment for filter               1</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FFA2</name>
+                     <description>Filter FIFO assignment for filter               2</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FFA3</name>
+                     <description>Filter FIFO assignment for filter               3</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FFA4</name>
+                     <description>Filter FIFO assignment for filter               4</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FFA5</name>
+                     <description>Filter FIFO assignment for filter               5</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FFA6</name>
+                     <description>Filter FIFO assignment for filter               6</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FFA7</name>
+                     <description>Filter FIFO assignment for filter               7</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FFA8</name>
+                     <description>Filter FIFO assignment for filter               8</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FFA9</name>
+                     <description>Filter FIFO assignment for filter               9</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FFA10</name>
+                     <description>Filter FIFO assignment for filter               10</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FFA11</name>
+                     <description>Filter FIFO assignment for filter               11</description>
+                     <bitOffset>11</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FFA12</name>
+                     <description>Filter FIFO assignment for filter               12</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FFA13</name>
+                     <description>Filter FIFO assignment for filter               13</description>
+                     <bitOffset>13</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FFA14</name>
+                     <description>Filter FIFO assignment for filter               14</description>
+                     <bitOffset>14</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FFA15</name>
+                     <description>Filter FIFO assignment for filter               15</description>
+                     <bitOffset>15</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FFA16</name>
+                     <description>Filter FIFO assignment for filter               16</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FFA17</name>
+                     <description>Filter FIFO assignment for filter               17</description>
+                     <bitOffset>17</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FFA18</name>
+                     <description>Filter FIFO assignment for filter               18</description>
+                     <bitOffset>18</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FFA19</name>
+                     <description>Filter FIFO assignment for filter               19</description>
+                     <bitOffset>19</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FFA20</name>
+                     <description>Filter FIFO assignment for filter               20</description>
+                     <bitOffset>20</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FFA21</name>
+                     <description>Filter FIFO assignment for filter               21</description>
+                     <bitOffset>21</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FFA22</name>
+                     <description>Filter FIFO assignment for filter               22</description>
+                     <bitOffset>22</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FFA23</name>
+                     <description>Filter FIFO assignment for filter               23</description>
+                     <bitOffset>23</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FFA24</name>
+                     <description>Filter FIFO assignment for filter               24</description>
+                     <bitOffset>24</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FFA25</name>
+                     <description>Filter FIFO assignment for filter               25</description>
+                     <bitOffset>25</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FFA26</name>
+                     <description>Filter FIFO assignment for filter               26</description>
+                     <bitOffset>26</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FFA27</name>
+                     <description>Filter FIFO assignment for filter               27</description>
+                     <bitOffset>27</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>FA1R</name>
+               <displayName>FA1R</displayName>
+               <description>filter activation register</description>
+               <addressOffset>0x21C</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>FACT0</name>
+                     <description>Filter active</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FACT1</name>
+                     <description>Filter active</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FACT2</name>
+                     <description>Filter active</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FACT3</name>
+                     <description>Filter active</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FACT4</name>
+                     <description>Filter active</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FACT5</name>
+                     <description>Filter active</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FACT6</name>
+                     <description>Filter active</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FACT7</name>
+                     <description>Filter active</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FACT8</name>
+                     <description>Filter active</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FACT9</name>
+                     <description>Filter active</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FACT10</name>
+                     <description>Filter active</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FACT11</name>
+                     <description>Filter active</description>
+                     <bitOffset>11</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FACT12</name>
+                     <description>Filter active</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FACT13</name>
+                     <description>Filter active</description>
+                     <bitOffset>13</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FACT14</name>
+                     <description>Filter active</description>
+                     <bitOffset>14</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FACT15</name>
+                     <description>Filter active</description>
+                     <bitOffset>15</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FACT16</name>
+                     <description>Filter active</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FACT17</name>
+                     <description>Filter active</description>
+                     <bitOffset>17</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FACT18</name>
+                     <description>Filter active</description>
+                     <bitOffset>18</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FACT19</name>
+                     <description>Filter active</description>
+                     <bitOffset>19</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FACT20</name>
+                     <description>Filter active</description>
+                     <bitOffset>20</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FACT21</name>
+                     <description>Filter active</description>
+                     <bitOffset>21</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FACT22</name>
+                     <description>Filter active</description>
+                     <bitOffset>22</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FACT23</name>
+                     <description>Filter active</description>
+                     <bitOffset>23</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FACT24</name>
+                     <description>Filter active</description>
+                     <bitOffset>24</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FACT25</name>
+                     <description>Filter active</description>
+                     <bitOffset>25</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FACT26</name>
+                     <description>Filter active</description>
+                     <bitOffset>26</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FACT27</name>
+                     <description>Filter active</description>
+                     <bitOffset>27</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>F0R1</name>
+               <displayName>F0R1</displayName>
+               <description>Filter bank 0 register 1</description>
+               <addressOffset>0x240</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>FB0</name>
+                     <description>Filter bits</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB1</name>
+                     <description>Filter bits</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB2</name>
+                     <description>Filter bits</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB3</name>
+                     <description>Filter bits</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB4</name>
+                     <description>Filter bits</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB5</name>
+                     <description>Filter bits</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB6</name>
+                     <description>Filter bits</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB7</name>
+                     <description>Filter bits</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB8</name>
+                     <description>Filter bits</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB9</name>
+                     <description>Filter bits</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB10</name>
+                     <description>Filter bits</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB11</name>
+                     <description>Filter bits</description>
+                     <bitOffset>11</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB12</name>
+                     <description>Filter bits</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB13</name>
+                     <description>Filter bits</description>
+                     <bitOffset>13</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB14</name>
+                     <description>Filter bits</description>
+                     <bitOffset>14</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB15</name>
+                     <description>Filter bits</description>
+                     <bitOffset>15</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB16</name>
+                     <description>Filter bits</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB17</name>
+                     <description>Filter bits</description>
+                     <bitOffset>17</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB18</name>
+                     <description>Filter bits</description>
+                     <bitOffset>18</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB19</name>
+                     <description>Filter bits</description>
+                     <bitOffset>19</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB20</name>
+                     <description>Filter bits</description>
+                     <bitOffset>20</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB21</name>
+                     <description>Filter bits</description>
+                     <bitOffset>21</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB22</name>
+                     <description>Filter bits</description>
+                     <bitOffset>22</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB23</name>
+                     <description>Filter bits</description>
+                     <bitOffset>23</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB24</name>
+                     <description>Filter bits</description>
+                     <bitOffset>24</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB25</name>
+                     <description>Filter bits</description>
+                     <bitOffset>25</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB26</name>
+                     <description>Filter bits</description>
+                     <bitOffset>26</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB27</name>
+                     <description>Filter bits</description>
+                     <bitOffset>27</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB28</name>
+                     <description>Filter bits</description>
+                     <bitOffset>28</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB29</name>
+                     <description>Filter bits</description>
+                     <bitOffset>29</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB30</name>
+                     <description>Filter bits</description>
+                     <bitOffset>30</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB31</name>
+                     <description>Filter bits</description>
+                     <bitOffset>31</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>F0R2</name>
+               <displayName>F0R2</displayName>
+               <description>Filter bank 0 register 2</description>
+               <addressOffset>0x244</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>FB0</name>
+                     <description>Filter bits</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB1</name>
+                     <description>Filter bits</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB2</name>
+                     <description>Filter bits</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB3</name>
+                     <description>Filter bits</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB4</name>
+                     <description>Filter bits</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB5</name>
+                     <description>Filter bits</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB6</name>
+                     <description>Filter bits</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB7</name>
+                     <description>Filter bits</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB8</name>
+                     <description>Filter bits</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB9</name>
+                     <description>Filter bits</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB10</name>
+                     <description>Filter bits</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB11</name>
+                     <description>Filter bits</description>
+                     <bitOffset>11</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB12</name>
+                     <description>Filter bits</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB13</name>
+                     <description>Filter bits</description>
+                     <bitOffset>13</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB14</name>
+                     <description>Filter bits</description>
+                     <bitOffset>14</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB15</name>
+                     <description>Filter bits</description>
+                     <bitOffset>15</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB16</name>
+                     <description>Filter bits</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB17</name>
+                     <description>Filter bits</description>
+                     <bitOffset>17</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB18</name>
+                     <description>Filter bits</description>
+                     <bitOffset>18</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB19</name>
+                     <description>Filter bits</description>
+                     <bitOffset>19</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB20</name>
+                     <description>Filter bits</description>
+                     <bitOffset>20</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB21</name>
+                     <description>Filter bits</description>
+                     <bitOffset>21</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB22</name>
+                     <description>Filter bits</description>
+                     <bitOffset>22</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB23</name>
+                     <description>Filter bits</description>
+                     <bitOffset>23</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB24</name>
+                     <description>Filter bits</description>
+                     <bitOffset>24</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB25</name>
+                     <description>Filter bits</description>
+                     <bitOffset>25</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB26</name>
+                     <description>Filter bits</description>
+                     <bitOffset>26</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB27</name>
+                     <description>Filter bits</description>
+                     <bitOffset>27</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB28</name>
+                     <description>Filter bits</description>
+                     <bitOffset>28</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB29</name>
+                     <description>Filter bits</description>
+                     <bitOffset>29</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB30</name>
+                     <description>Filter bits</description>
+                     <bitOffset>30</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB31</name>
+                     <description>Filter bits</description>
+                     <bitOffset>31</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>F1R1</name>
+               <displayName>F1R1</displayName>
+               <description>Filter bank 1 register 1</description>
+               <addressOffset>0x248</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>FB0</name>
+                     <description>Filter bits</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB1</name>
+                     <description>Filter bits</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB2</name>
+                     <description>Filter bits</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB3</name>
+                     <description>Filter bits</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB4</name>
+                     <description>Filter bits</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB5</name>
+                     <description>Filter bits</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB6</name>
+                     <description>Filter bits</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB7</name>
+                     <description>Filter bits</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB8</name>
+                     <description>Filter bits</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB9</name>
+                     <description>Filter bits</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB10</name>
+                     <description>Filter bits</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB11</name>
+                     <description>Filter bits</description>
+                     <bitOffset>11</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB12</name>
+                     <description>Filter bits</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB13</name>
+                     <description>Filter bits</description>
+                     <bitOffset>13</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB14</name>
+                     <description>Filter bits</description>
+                     <bitOffset>14</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB15</name>
+                     <description>Filter bits</description>
+                     <bitOffset>15</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB16</name>
+                     <description>Filter bits</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB17</name>
+                     <description>Filter bits</description>
+                     <bitOffset>17</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB18</name>
+                     <description>Filter bits</description>
+                     <bitOffset>18</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB19</name>
+                     <description>Filter bits</description>
+                     <bitOffset>19</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB20</name>
+                     <description>Filter bits</description>
+                     <bitOffset>20</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB21</name>
+                     <description>Filter bits</description>
+                     <bitOffset>21</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB22</name>
+                     <description>Filter bits</description>
+                     <bitOffset>22</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB23</name>
+                     <description>Filter bits</description>
+                     <bitOffset>23</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB24</name>
+                     <description>Filter bits</description>
+                     <bitOffset>24</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB25</name>
+                     <description>Filter bits</description>
+                     <bitOffset>25</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB26</name>
+                     <description>Filter bits</description>
+                     <bitOffset>26</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB27</name>
+                     <description>Filter bits</description>
+                     <bitOffset>27</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB28</name>
+                     <description>Filter bits</description>
+                     <bitOffset>28</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB29</name>
+                     <description>Filter bits</description>
+                     <bitOffset>29</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB30</name>
+                     <description>Filter bits</description>
+                     <bitOffset>30</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB31</name>
+                     <description>Filter bits</description>
+                     <bitOffset>31</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>F1R2</name>
+               <displayName>F1R2</displayName>
+               <description>Filter bank 1 register 2</description>
+               <addressOffset>0x24C</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>FB0</name>
+                     <description>Filter bits</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB1</name>
+                     <description>Filter bits</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB2</name>
+                     <description>Filter bits</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB3</name>
+                     <description>Filter bits</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB4</name>
+                     <description>Filter bits</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB5</name>
+                     <description>Filter bits</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB6</name>
+                     <description>Filter bits</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB7</name>
+                     <description>Filter bits</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB8</name>
+                     <description>Filter bits</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB9</name>
+                     <description>Filter bits</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB10</name>
+                     <description>Filter bits</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB11</name>
+                     <description>Filter bits</description>
+                     <bitOffset>11</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB12</name>
+                     <description>Filter bits</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB13</name>
+                     <description>Filter bits</description>
+                     <bitOffset>13</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB14</name>
+                     <description>Filter bits</description>
+                     <bitOffset>14</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB15</name>
+                     <description>Filter bits</description>
+                     <bitOffset>15</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB16</name>
+                     <description>Filter bits</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB17</name>
+                     <description>Filter bits</description>
+                     <bitOffset>17</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB18</name>
+                     <description>Filter bits</description>
+                     <bitOffset>18</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB19</name>
+                     <description>Filter bits</description>
+                     <bitOffset>19</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB20</name>
+                     <description>Filter bits</description>
+                     <bitOffset>20</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB21</name>
+                     <description>Filter bits</description>
+                     <bitOffset>21</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB22</name>
+                     <description>Filter bits</description>
+                     <bitOffset>22</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB23</name>
+                     <description>Filter bits</description>
+                     <bitOffset>23</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB24</name>
+                     <description>Filter bits</description>
+                     <bitOffset>24</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB25</name>
+                     <description>Filter bits</description>
+                     <bitOffset>25</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB26</name>
+                     <description>Filter bits</description>
+                     <bitOffset>26</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB27</name>
+                     <description>Filter bits</description>
+                     <bitOffset>27</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB28</name>
+                     <description>Filter bits</description>
+                     <bitOffset>28</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB29</name>
+                     <description>Filter bits</description>
+                     <bitOffset>29</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB30</name>
+                     <description>Filter bits</description>
+                     <bitOffset>30</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB31</name>
+                     <description>Filter bits</description>
+                     <bitOffset>31</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>F2R1</name>
+               <displayName>F2R1</displayName>
+               <description>Filter bank 2 register 1</description>
+               <addressOffset>0x250</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>FB0</name>
+                     <description>Filter bits</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB1</name>
+                     <description>Filter bits</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB2</name>
+                     <description>Filter bits</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB3</name>
+                     <description>Filter bits</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB4</name>
+                     <description>Filter bits</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB5</name>
+                     <description>Filter bits</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB6</name>
+                     <description>Filter bits</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB7</name>
+                     <description>Filter bits</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB8</name>
+                     <description>Filter bits</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB9</name>
+                     <description>Filter bits</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB10</name>
+                     <description>Filter bits</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB11</name>
+                     <description>Filter bits</description>
+                     <bitOffset>11</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB12</name>
+                     <description>Filter bits</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB13</name>
+                     <description>Filter bits</description>
+                     <bitOffset>13</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB14</name>
+                     <description>Filter bits</description>
+                     <bitOffset>14</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB15</name>
+                     <description>Filter bits</description>
+                     <bitOffset>15</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB16</name>
+                     <description>Filter bits</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB17</name>
+                     <description>Filter bits</description>
+                     <bitOffset>17</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB18</name>
+                     <description>Filter bits</description>
+                     <bitOffset>18</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB19</name>
+                     <description>Filter bits</description>
+                     <bitOffset>19</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB20</name>
+                     <description>Filter bits</description>
+                     <bitOffset>20</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB21</name>
+                     <description>Filter bits</description>
+                     <bitOffset>21</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB22</name>
+                     <description>Filter bits</description>
+                     <bitOffset>22</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB23</name>
+                     <description>Filter bits</description>
+                     <bitOffset>23</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB24</name>
+                     <description>Filter bits</description>
+                     <bitOffset>24</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB25</name>
+                     <description>Filter bits</description>
+                     <bitOffset>25</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB26</name>
+                     <description>Filter bits</description>
+                     <bitOffset>26</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB27</name>
+                     <description>Filter bits</description>
+                     <bitOffset>27</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB28</name>
+                     <description>Filter bits</description>
+                     <bitOffset>28</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB29</name>
+                     <description>Filter bits</description>
+                     <bitOffset>29</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB30</name>
+                     <description>Filter bits</description>
+                     <bitOffset>30</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB31</name>
+                     <description>Filter bits</description>
+                     <bitOffset>31</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>F2R2</name>
+               <displayName>F2R2</displayName>
+               <description>Filter bank 2 register 2</description>
+               <addressOffset>0x254</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>FB0</name>
+                     <description>Filter bits</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB1</name>
+                     <description>Filter bits</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB2</name>
+                     <description>Filter bits</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB3</name>
+                     <description>Filter bits</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB4</name>
+                     <description>Filter bits</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB5</name>
+                     <description>Filter bits</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB6</name>
+                     <description>Filter bits</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB7</name>
+                     <description>Filter bits</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB8</name>
+                     <description>Filter bits</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB9</name>
+                     <description>Filter bits</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB10</name>
+                     <description>Filter bits</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB11</name>
+                     <description>Filter bits</description>
+                     <bitOffset>11</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB12</name>
+                     <description>Filter bits</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB13</name>
+                     <description>Filter bits</description>
+                     <bitOffset>13</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB14</name>
+                     <description>Filter bits</description>
+                     <bitOffset>14</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB15</name>
+                     <description>Filter bits</description>
+                     <bitOffset>15</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB16</name>
+                     <description>Filter bits</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB17</name>
+                     <description>Filter bits</description>
+                     <bitOffset>17</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB18</name>
+                     <description>Filter bits</description>
+                     <bitOffset>18</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB19</name>
+                     <description>Filter bits</description>
+                     <bitOffset>19</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB20</name>
+                     <description>Filter bits</description>
+                     <bitOffset>20</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB21</name>
+                     <description>Filter bits</description>
+                     <bitOffset>21</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB22</name>
+                     <description>Filter bits</description>
+                     <bitOffset>22</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB23</name>
+                     <description>Filter bits</description>
+                     <bitOffset>23</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB24</name>
+                     <description>Filter bits</description>
+                     <bitOffset>24</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB25</name>
+                     <description>Filter bits</description>
+                     <bitOffset>25</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB26</name>
+                     <description>Filter bits</description>
+                     <bitOffset>26</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB27</name>
+                     <description>Filter bits</description>
+                     <bitOffset>27</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB28</name>
+                     <description>Filter bits</description>
+                     <bitOffset>28</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB29</name>
+                     <description>Filter bits</description>
+                     <bitOffset>29</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB30</name>
+                     <description>Filter bits</description>
+                     <bitOffset>30</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB31</name>
+                     <description>Filter bits</description>
+                     <bitOffset>31</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>F3R1</name>
+               <displayName>F3R1</displayName>
+               <description>Filter bank 3 register 1</description>
+               <addressOffset>0x258</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>FB0</name>
+                     <description>Filter bits</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB1</name>
+                     <description>Filter bits</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB2</name>
+                     <description>Filter bits</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB3</name>
+                     <description>Filter bits</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB4</name>
+                     <description>Filter bits</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB5</name>
+                     <description>Filter bits</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB6</name>
+                     <description>Filter bits</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB7</name>
+                     <description>Filter bits</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB8</name>
+                     <description>Filter bits</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB9</name>
+                     <description>Filter bits</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB10</name>
+                     <description>Filter bits</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB11</name>
+                     <description>Filter bits</description>
+                     <bitOffset>11</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB12</name>
+                     <description>Filter bits</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB13</name>
+                     <description>Filter bits</description>
+                     <bitOffset>13</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB14</name>
+                     <description>Filter bits</description>
+                     <bitOffset>14</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB15</name>
+                     <description>Filter bits</description>
+                     <bitOffset>15</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB16</name>
+                     <description>Filter bits</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB17</name>
+                     <description>Filter bits</description>
+                     <bitOffset>17</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB18</name>
+                     <description>Filter bits</description>
+                     <bitOffset>18</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB19</name>
+                     <description>Filter bits</description>
+                     <bitOffset>19</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB20</name>
+                     <description>Filter bits</description>
+                     <bitOffset>20</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB21</name>
+                     <description>Filter bits</description>
+                     <bitOffset>21</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB22</name>
+                     <description>Filter bits</description>
+                     <bitOffset>22</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB23</name>
+                     <description>Filter bits</description>
+                     <bitOffset>23</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB24</name>
+                     <description>Filter bits</description>
+                     <bitOffset>24</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB25</name>
+                     <description>Filter bits</description>
+                     <bitOffset>25</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB26</name>
+                     <description>Filter bits</description>
+                     <bitOffset>26</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB27</name>
+                     <description>Filter bits</description>
+                     <bitOffset>27</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB28</name>
+                     <description>Filter bits</description>
+                     <bitOffset>28</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB29</name>
+                     <description>Filter bits</description>
+                     <bitOffset>29</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB30</name>
+                     <description>Filter bits</description>
+                     <bitOffset>30</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB31</name>
+                     <description>Filter bits</description>
+                     <bitOffset>31</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>F3R2</name>
+               <displayName>F3R2</displayName>
+               <description>Filter bank 3 register 2</description>
+               <addressOffset>0x25C</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>FB0</name>
+                     <description>Filter bits</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB1</name>
+                     <description>Filter bits</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB2</name>
+                     <description>Filter bits</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB3</name>
+                     <description>Filter bits</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB4</name>
+                     <description>Filter bits</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB5</name>
+                     <description>Filter bits</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB6</name>
+                     <description>Filter bits</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB7</name>
+                     <description>Filter bits</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB8</name>
+                     <description>Filter bits</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB9</name>
+                     <description>Filter bits</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB10</name>
+                     <description>Filter bits</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB11</name>
+                     <description>Filter bits</description>
+                     <bitOffset>11</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB12</name>
+                     <description>Filter bits</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB13</name>
+                     <description>Filter bits</description>
+                     <bitOffset>13</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB14</name>
+                     <description>Filter bits</description>
+                     <bitOffset>14</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB15</name>
+                     <description>Filter bits</description>
+                     <bitOffset>15</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB16</name>
+                     <description>Filter bits</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB17</name>
+                     <description>Filter bits</description>
+                     <bitOffset>17</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB18</name>
+                     <description>Filter bits</description>
+                     <bitOffset>18</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB19</name>
+                     <description>Filter bits</description>
+                     <bitOffset>19</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB20</name>
+                     <description>Filter bits</description>
+                     <bitOffset>20</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB21</name>
+                     <description>Filter bits</description>
+                     <bitOffset>21</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB22</name>
+                     <description>Filter bits</description>
+                     <bitOffset>22</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB23</name>
+                     <description>Filter bits</description>
+                     <bitOffset>23</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB24</name>
+                     <description>Filter bits</description>
+                     <bitOffset>24</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB25</name>
+                     <description>Filter bits</description>
+                     <bitOffset>25</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB26</name>
+                     <description>Filter bits</description>
+                     <bitOffset>26</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB27</name>
+                     <description>Filter bits</description>
+                     <bitOffset>27</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB28</name>
+                     <description>Filter bits</description>
+                     <bitOffset>28</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB29</name>
+                     <description>Filter bits</description>
+                     <bitOffset>29</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB30</name>
+                     <description>Filter bits</description>
+                     <bitOffset>30</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB31</name>
+                     <description>Filter bits</description>
+                     <bitOffset>31</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>F4R1</name>
+               <displayName>F4R1</displayName>
+               <description>Filter bank 4 register 1</description>
+               <addressOffset>0x260</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>FB0</name>
+                     <description>Filter bits</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB1</name>
+                     <description>Filter bits</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB2</name>
+                     <description>Filter bits</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB3</name>
+                     <description>Filter bits</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB4</name>
+                     <description>Filter bits</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB5</name>
+                     <description>Filter bits</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB6</name>
+                     <description>Filter bits</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB7</name>
+                     <description>Filter bits</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB8</name>
+                     <description>Filter bits</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB9</name>
+                     <description>Filter bits</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB10</name>
+                     <description>Filter bits</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB11</name>
+                     <description>Filter bits</description>
+                     <bitOffset>11</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB12</name>
+                     <description>Filter bits</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB13</name>
+                     <description>Filter bits</description>
+                     <bitOffset>13</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB14</name>
+                     <description>Filter bits</description>
+                     <bitOffset>14</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB15</name>
+                     <description>Filter bits</description>
+                     <bitOffset>15</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB16</name>
+                     <description>Filter bits</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB17</name>
+                     <description>Filter bits</description>
+                     <bitOffset>17</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB18</name>
+                     <description>Filter bits</description>
+                     <bitOffset>18</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB19</name>
+                     <description>Filter bits</description>
+                     <bitOffset>19</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB20</name>
+                     <description>Filter bits</description>
+                     <bitOffset>20</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB21</name>
+                     <description>Filter bits</description>
+                     <bitOffset>21</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB22</name>
+                     <description>Filter bits</description>
+                     <bitOffset>22</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB23</name>
+                     <description>Filter bits</description>
+                     <bitOffset>23</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB24</name>
+                     <description>Filter bits</description>
+                     <bitOffset>24</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB25</name>
+                     <description>Filter bits</description>
+                     <bitOffset>25</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB26</name>
+                     <description>Filter bits</description>
+                     <bitOffset>26</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB27</name>
+                     <description>Filter bits</description>
+                     <bitOffset>27</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB28</name>
+                     <description>Filter bits</description>
+                     <bitOffset>28</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB29</name>
+                     <description>Filter bits</description>
+                     <bitOffset>29</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB30</name>
+                     <description>Filter bits</description>
+                     <bitOffset>30</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB31</name>
+                     <description>Filter bits</description>
+                     <bitOffset>31</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>F4R2</name>
+               <displayName>F4R2</displayName>
+               <description>Filter bank 4 register 2</description>
+               <addressOffset>0x264</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>FB0</name>
+                     <description>Filter bits</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB1</name>
+                     <description>Filter bits</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB2</name>
+                     <description>Filter bits</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB3</name>
+                     <description>Filter bits</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB4</name>
+                     <description>Filter bits</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB5</name>
+                     <description>Filter bits</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB6</name>
+                     <description>Filter bits</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB7</name>
+                     <description>Filter bits</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB8</name>
+                     <description>Filter bits</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB9</name>
+                     <description>Filter bits</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB10</name>
+                     <description>Filter bits</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB11</name>
+                     <description>Filter bits</description>
+                     <bitOffset>11</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB12</name>
+                     <description>Filter bits</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB13</name>
+                     <description>Filter bits</description>
+                     <bitOffset>13</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB14</name>
+                     <description>Filter bits</description>
+                     <bitOffset>14</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB15</name>
+                     <description>Filter bits</description>
+                     <bitOffset>15</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB16</name>
+                     <description>Filter bits</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB17</name>
+                     <description>Filter bits</description>
+                     <bitOffset>17</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB18</name>
+                     <description>Filter bits</description>
+                     <bitOffset>18</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB19</name>
+                     <description>Filter bits</description>
+                     <bitOffset>19</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB20</name>
+                     <description>Filter bits</description>
+                     <bitOffset>20</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB21</name>
+                     <description>Filter bits</description>
+                     <bitOffset>21</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB22</name>
+                     <description>Filter bits</description>
+                     <bitOffset>22</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB23</name>
+                     <description>Filter bits</description>
+                     <bitOffset>23</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB24</name>
+                     <description>Filter bits</description>
+                     <bitOffset>24</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB25</name>
+                     <description>Filter bits</description>
+                     <bitOffset>25</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB26</name>
+                     <description>Filter bits</description>
+                     <bitOffset>26</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB27</name>
+                     <description>Filter bits</description>
+                     <bitOffset>27</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB28</name>
+                     <description>Filter bits</description>
+                     <bitOffset>28</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB29</name>
+                     <description>Filter bits</description>
+                     <bitOffset>29</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB30</name>
+                     <description>Filter bits</description>
+                     <bitOffset>30</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB31</name>
+                     <description>Filter bits</description>
+                     <bitOffset>31</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>F5R1</name>
+               <displayName>F5R1</displayName>
+               <description>Filter bank 5 register 1</description>
+               <addressOffset>0x268</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>FB0</name>
+                     <description>Filter bits</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB1</name>
+                     <description>Filter bits</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB2</name>
+                     <description>Filter bits</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB3</name>
+                     <description>Filter bits</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB4</name>
+                     <description>Filter bits</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB5</name>
+                     <description>Filter bits</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB6</name>
+                     <description>Filter bits</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB7</name>
+                     <description>Filter bits</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB8</name>
+                     <description>Filter bits</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB9</name>
+                     <description>Filter bits</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB10</name>
+                     <description>Filter bits</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB11</name>
+                     <description>Filter bits</description>
+                     <bitOffset>11</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB12</name>
+                     <description>Filter bits</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB13</name>
+                     <description>Filter bits</description>
+                     <bitOffset>13</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB14</name>
+                     <description>Filter bits</description>
+                     <bitOffset>14</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB15</name>
+                     <description>Filter bits</description>
+                     <bitOffset>15</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB16</name>
+                     <description>Filter bits</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB17</name>
+                     <description>Filter bits</description>
+                     <bitOffset>17</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB18</name>
+                     <description>Filter bits</description>
+                     <bitOffset>18</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB19</name>
+                     <description>Filter bits</description>
+                     <bitOffset>19</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB20</name>
+                     <description>Filter bits</description>
+                     <bitOffset>20</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB21</name>
+                     <description>Filter bits</description>
+                     <bitOffset>21</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB22</name>
+                     <description>Filter bits</description>
+                     <bitOffset>22</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB23</name>
+                     <description>Filter bits</description>
+                     <bitOffset>23</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB24</name>
+                     <description>Filter bits</description>
+                     <bitOffset>24</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB25</name>
+                     <description>Filter bits</description>
+                     <bitOffset>25</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB26</name>
+                     <description>Filter bits</description>
+                     <bitOffset>26</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB27</name>
+                     <description>Filter bits</description>
+                     <bitOffset>27</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB28</name>
+                     <description>Filter bits</description>
+                     <bitOffset>28</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB29</name>
+                     <description>Filter bits</description>
+                     <bitOffset>29</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB30</name>
+                     <description>Filter bits</description>
+                     <bitOffset>30</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB31</name>
+                     <description>Filter bits</description>
+                     <bitOffset>31</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>F5R2</name>
+               <displayName>F5R2</displayName>
+               <description>Filter bank 5 register 2</description>
+               <addressOffset>0x26C</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>FB0</name>
+                     <description>Filter bits</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB1</name>
+                     <description>Filter bits</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB2</name>
+                     <description>Filter bits</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB3</name>
+                     <description>Filter bits</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB4</name>
+                     <description>Filter bits</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB5</name>
+                     <description>Filter bits</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB6</name>
+                     <description>Filter bits</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB7</name>
+                     <description>Filter bits</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB8</name>
+                     <description>Filter bits</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB9</name>
+                     <description>Filter bits</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB10</name>
+                     <description>Filter bits</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB11</name>
+                     <description>Filter bits</description>
+                     <bitOffset>11</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB12</name>
+                     <description>Filter bits</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB13</name>
+                     <description>Filter bits</description>
+                     <bitOffset>13</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB14</name>
+                     <description>Filter bits</description>
+                     <bitOffset>14</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB15</name>
+                     <description>Filter bits</description>
+                     <bitOffset>15</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB16</name>
+                     <description>Filter bits</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB17</name>
+                     <description>Filter bits</description>
+                     <bitOffset>17</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB18</name>
+                     <description>Filter bits</description>
+                     <bitOffset>18</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB19</name>
+                     <description>Filter bits</description>
+                     <bitOffset>19</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB20</name>
+                     <description>Filter bits</description>
+                     <bitOffset>20</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB21</name>
+                     <description>Filter bits</description>
+                     <bitOffset>21</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB22</name>
+                     <description>Filter bits</description>
+                     <bitOffset>22</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB23</name>
+                     <description>Filter bits</description>
+                     <bitOffset>23</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB24</name>
+                     <description>Filter bits</description>
+                     <bitOffset>24</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB25</name>
+                     <description>Filter bits</description>
+                     <bitOffset>25</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB26</name>
+                     <description>Filter bits</description>
+                     <bitOffset>26</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB27</name>
+                     <description>Filter bits</description>
+                     <bitOffset>27</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB28</name>
+                     <description>Filter bits</description>
+                     <bitOffset>28</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB29</name>
+                     <description>Filter bits</description>
+                     <bitOffset>29</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB30</name>
+                     <description>Filter bits</description>
+                     <bitOffset>30</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB31</name>
+                     <description>Filter bits</description>
+                     <bitOffset>31</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>F6R1</name>
+               <displayName>F6R1</displayName>
+               <description>Filter bank 6 register 1</description>
+               <addressOffset>0x270</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>FB0</name>
+                     <description>Filter bits</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB1</name>
+                     <description>Filter bits</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB2</name>
+                     <description>Filter bits</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB3</name>
+                     <description>Filter bits</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB4</name>
+                     <description>Filter bits</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB5</name>
+                     <description>Filter bits</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB6</name>
+                     <description>Filter bits</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB7</name>
+                     <description>Filter bits</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB8</name>
+                     <description>Filter bits</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB9</name>
+                     <description>Filter bits</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB10</name>
+                     <description>Filter bits</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB11</name>
+                     <description>Filter bits</description>
+                     <bitOffset>11</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB12</name>
+                     <description>Filter bits</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB13</name>
+                     <description>Filter bits</description>
+                     <bitOffset>13</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB14</name>
+                     <description>Filter bits</description>
+                     <bitOffset>14</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB15</name>
+                     <description>Filter bits</description>
+                     <bitOffset>15</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB16</name>
+                     <description>Filter bits</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB17</name>
+                     <description>Filter bits</description>
+                     <bitOffset>17</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB18</name>
+                     <description>Filter bits</description>
+                     <bitOffset>18</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB19</name>
+                     <description>Filter bits</description>
+                     <bitOffset>19</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB20</name>
+                     <description>Filter bits</description>
+                     <bitOffset>20</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB21</name>
+                     <description>Filter bits</description>
+                     <bitOffset>21</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB22</name>
+                     <description>Filter bits</description>
+                     <bitOffset>22</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB23</name>
+                     <description>Filter bits</description>
+                     <bitOffset>23</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB24</name>
+                     <description>Filter bits</description>
+                     <bitOffset>24</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB25</name>
+                     <description>Filter bits</description>
+                     <bitOffset>25</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB26</name>
+                     <description>Filter bits</description>
+                     <bitOffset>26</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB27</name>
+                     <description>Filter bits</description>
+                     <bitOffset>27</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB28</name>
+                     <description>Filter bits</description>
+                     <bitOffset>28</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB29</name>
+                     <description>Filter bits</description>
+                     <bitOffset>29</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB30</name>
+                     <description>Filter bits</description>
+                     <bitOffset>30</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB31</name>
+                     <description>Filter bits</description>
+                     <bitOffset>31</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>F6R2</name>
+               <displayName>F6R2</displayName>
+               <description>Filter bank 6 register 2</description>
+               <addressOffset>0x274</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>FB0</name>
+                     <description>Filter bits</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB1</name>
+                     <description>Filter bits</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB2</name>
+                     <description>Filter bits</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB3</name>
+                     <description>Filter bits</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB4</name>
+                     <description>Filter bits</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB5</name>
+                     <description>Filter bits</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB6</name>
+                     <description>Filter bits</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB7</name>
+                     <description>Filter bits</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB8</name>
+                     <description>Filter bits</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB9</name>
+                     <description>Filter bits</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB10</name>
+                     <description>Filter bits</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB11</name>
+                     <description>Filter bits</description>
+                     <bitOffset>11</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB12</name>
+                     <description>Filter bits</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB13</name>
+                     <description>Filter bits</description>
+                     <bitOffset>13</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB14</name>
+                     <description>Filter bits</description>
+                     <bitOffset>14</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB15</name>
+                     <description>Filter bits</description>
+                     <bitOffset>15</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB16</name>
+                     <description>Filter bits</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB17</name>
+                     <description>Filter bits</description>
+                     <bitOffset>17</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB18</name>
+                     <description>Filter bits</description>
+                     <bitOffset>18</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB19</name>
+                     <description>Filter bits</description>
+                     <bitOffset>19</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB20</name>
+                     <description>Filter bits</description>
+                     <bitOffset>20</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB21</name>
+                     <description>Filter bits</description>
+                     <bitOffset>21</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB22</name>
+                     <description>Filter bits</description>
+                     <bitOffset>22</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB23</name>
+                     <description>Filter bits</description>
+                     <bitOffset>23</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB24</name>
+                     <description>Filter bits</description>
+                     <bitOffset>24</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB25</name>
+                     <description>Filter bits</description>
+                     <bitOffset>25</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB26</name>
+                     <description>Filter bits</description>
+                     <bitOffset>26</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB27</name>
+                     <description>Filter bits</description>
+                     <bitOffset>27</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB28</name>
+                     <description>Filter bits</description>
+                     <bitOffset>28</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB29</name>
+                     <description>Filter bits</description>
+                     <bitOffset>29</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB30</name>
+                     <description>Filter bits</description>
+                     <bitOffset>30</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB31</name>
+                     <description>Filter bits</description>
+                     <bitOffset>31</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>F7R1</name>
+               <displayName>F7R1</displayName>
+               <description>Filter bank 7 register 1</description>
+               <addressOffset>0x278</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>FB0</name>
+                     <description>Filter bits</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB1</name>
+                     <description>Filter bits</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB2</name>
+                     <description>Filter bits</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB3</name>
+                     <description>Filter bits</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB4</name>
+                     <description>Filter bits</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB5</name>
+                     <description>Filter bits</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB6</name>
+                     <description>Filter bits</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB7</name>
+                     <description>Filter bits</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB8</name>
+                     <description>Filter bits</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB9</name>
+                     <description>Filter bits</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB10</name>
+                     <description>Filter bits</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB11</name>
+                     <description>Filter bits</description>
+                     <bitOffset>11</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB12</name>
+                     <description>Filter bits</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB13</name>
+                     <description>Filter bits</description>
+                     <bitOffset>13</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB14</name>
+                     <description>Filter bits</description>
+                     <bitOffset>14</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB15</name>
+                     <description>Filter bits</description>
+                     <bitOffset>15</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB16</name>
+                     <description>Filter bits</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB17</name>
+                     <description>Filter bits</description>
+                     <bitOffset>17</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB18</name>
+                     <description>Filter bits</description>
+                     <bitOffset>18</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB19</name>
+                     <description>Filter bits</description>
+                     <bitOffset>19</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB20</name>
+                     <description>Filter bits</description>
+                     <bitOffset>20</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB21</name>
+                     <description>Filter bits</description>
+                     <bitOffset>21</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB22</name>
+                     <description>Filter bits</description>
+                     <bitOffset>22</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB23</name>
+                     <description>Filter bits</description>
+                     <bitOffset>23</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB24</name>
+                     <description>Filter bits</description>
+                     <bitOffset>24</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB25</name>
+                     <description>Filter bits</description>
+                     <bitOffset>25</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB26</name>
+                     <description>Filter bits</description>
+                     <bitOffset>26</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB27</name>
+                     <description>Filter bits</description>
+                     <bitOffset>27</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB28</name>
+                     <description>Filter bits</description>
+                     <bitOffset>28</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB29</name>
+                     <description>Filter bits</description>
+                     <bitOffset>29</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB30</name>
+                     <description>Filter bits</description>
+                     <bitOffset>30</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB31</name>
+                     <description>Filter bits</description>
+                     <bitOffset>31</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>F7R2</name>
+               <displayName>F7R2</displayName>
+               <description>Filter bank 7 register 2</description>
+               <addressOffset>0x27C</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>FB0</name>
+                     <description>Filter bits</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB1</name>
+                     <description>Filter bits</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB2</name>
+                     <description>Filter bits</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB3</name>
+                     <description>Filter bits</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB4</name>
+                     <description>Filter bits</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB5</name>
+                     <description>Filter bits</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB6</name>
+                     <description>Filter bits</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB7</name>
+                     <description>Filter bits</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB8</name>
+                     <description>Filter bits</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB9</name>
+                     <description>Filter bits</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB10</name>
+                     <description>Filter bits</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB11</name>
+                     <description>Filter bits</description>
+                     <bitOffset>11</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB12</name>
+                     <description>Filter bits</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB13</name>
+                     <description>Filter bits</description>
+                     <bitOffset>13</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB14</name>
+                     <description>Filter bits</description>
+                     <bitOffset>14</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB15</name>
+                     <description>Filter bits</description>
+                     <bitOffset>15</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB16</name>
+                     <description>Filter bits</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB17</name>
+                     <description>Filter bits</description>
+                     <bitOffset>17</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB18</name>
+                     <description>Filter bits</description>
+                     <bitOffset>18</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB19</name>
+                     <description>Filter bits</description>
+                     <bitOffset>19</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB20</name>
+                     <description>Filter bits</description>
+                     <bitOffset>20</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB21</name>
+                     <description>Filter bits</description>
+                     <bitOffset>21</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB22</name>
+                     <description>Filter bits</description>
+                     <bitOffset>22</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB23</name>
+                     <description>Filter bits</description>
+                     <bitOffset>23</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB24</name>
+                     <description>Filter bits</description>
+                     <bitOffset>24</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB25</name>
+                     <description>Filter bits</description>
+                     <bitOffset>25</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB26</name>
+                     <description>Filter bits</description>
+                     <bitOffset>26</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB27</name>
+                     <description>Filter bits</description>
+                     <bitOffset>27</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB28</name>
+                     <description>Filter bits</description>
+                     <bitOffset>28</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB29</name>
+                     <description>Filter bits</description>
+                     <bitOffset>29</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB30</name>
+                     <description>Filter bits</description>
+                     <bitOffset>30</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB31</name>
+                     <description>Filter bits</description>
+                     <bitOffset>31</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>F8R1</name>
+               <displayName>F8R1</displayName>
+               <description>Filter bank 8 register 1</description>
+               <addressOffset>0x280</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>FB0</name>
+                     <description>Filter bits</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB1</name>
+                     <description>Filter bits</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB2</name>
+                     <description>Filter bits</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB3</name>
+                     <description>Filter bits</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB4</name>
+                     <description>Filter bits</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB5</name>
+                     <description>Filter bits</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB6</name>
+                     <description>Filter bits</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB7</name>
+                     <description>Filter bits</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB8</name>
+                     <description>Filter bits</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB9</name>
+                     <description>Filter bits</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB10</name>
+                     <description>Filter bits</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB11</name>
+                     <description>Filter bits</description>
+                     <bitOffset>11</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB12</name>
+                     <description>Filter bits</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB13</name>
+                     <description>Filter bits</description>
+                     <bitOffset>13</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB14</name>
+                     <description>Filter bits</description>
+                     <bitOffset>14</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB15</name>
+                     <description>Filter bits</description>
+                     <bitOffset>15</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB16</name>
+                     <description>Filter bits</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB17</name>
+                     <description>Filter bits</description>
+                     <bitOffset>17</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB18</name>
+                     <description>Filter bits</description>
+                     <bitOffset>18</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB19</name>
+                     <description>Filter bits</description>
+                     <bitOffset>19</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB20</name>
+                     <description>Filter bits</description>
+                     <bitOffset>20</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB21</name>
+                     <description>Filter bits</description>
+                     <bitOffset>21</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB22</name>
+                     <description>Filter bits</description>
+                     <bitOffset>22</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB23</name>
+                     <description>Filter bits</description>
+                     <bitOffset>23</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB24</name>
+                     <description>Filter bits</description>
+                     <bitOffset>24</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB25</name>
+                     <description>Filter bits</description>
+                     <bitOffset>25</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB26</name>
+                     <description>Filter bits</description>
+                     <bitOffset>26</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB27</name>
+                     <description>Filter bits</description>
+                     <bitOffset>27</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB28</name>
+                     <description>Filter bits</description>
+                     <bitOffset>28</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB29</name>
+                     <description>Filter bits</description>
+                     <bitOffset>29</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB30</name>
+                     <description>Filter bits</description>
+                     <bitOffset>30</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB31</name>
+                     <description>Filter bits</description>
+                     <bitOffset>31</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>F8R2</name>
+               <displayName>F8R2</displayName>
+               <description>Filter bank 8 register 2</description>
+               <addressOffset>0x284</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>FB0</name>
+                     <description>Filter bits</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB1</name>
+                     <description>Filter bits</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB2</name>
+                     <description>Filter bits</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB3</name>
+                     <description>Filter bits</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB4</name>
+                     <description>Filter bits</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB5</name>
+                     <description>Filter bits</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB6</name>
+                     <description>Filter bits</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB7</name>
+                     <description>Filter bits</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB8</name>
+                     <description>Filter bits</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB9</name>
+                     <description>Filter bits</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB10</name>
+                     <description>Filter bits</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB11</name>
+                     <description>Filter bits</description>
+                     <bitOffset>11</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB12</name>
+                     <description>Filter bits</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB13</name>
+                     <description>Filter bits</description>
+                     <bitOffset>13</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB14</name>
+                     <description>Filter bits</description>
+                     <bitOffset>14</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB15</name>
+                     <description>Filter bits</description>
+                     <bitOffset>15</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB16</name>
+                     <description>Filter bits</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB17</name>
+                     <description>Filter bits</description>
+                     <bitOffset>17</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB18</name>
+                     <description>Filter bits</description>
+                     <bitOffset>18</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB19</name>
+                     <description>Filter bits</description>
+                     <bitOffset>19</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB20</name>
+                     <description>Filter bits</description>
+                     <bitOffset>20</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB21</name>
+                     <description>Filter bits</description>
+                     <bitOffset>21</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB22</name>
+                     <description>Filter bits</description>
+                     <bitOffset>22</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB23</name>
+                     <description>Filter bits</description>
+                     <bitOffset>23</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB24</name>
+                     <description>Filter bits</description>
+                     <bitOffset>24</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB25</name>
+                     <description>Filter bits</description>
+                     <bitOffset>25</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB26</name>
+                     <description>Filter bits</description>
+                     <bitOffset>26</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB27</name>
+                     <description>Filter bits</description>
+                     <bitOffset>27</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB28</name>
+                     <description>Filter bits</description>
+                     <bitOffset>28</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB29</name>
+                     <description>Filter bits</description>
+                     <bitOffset>29</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB30</name>
+                     <description>Filter bits</description>
+                     <bitOffset>30</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB31</name>
+                     <description>Filter bits</description>
+                     <bitOffset>31</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>F9R1</name>
+               <displayName>F9R1</displayName>
+               <description>Filter bank 9 register 1</description>
+               <addressOffset>0x288</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>FB0</name>
+                     <description>Filter bits</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB1</name>
+                     <description>Filter bits</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB2</name>
+                     <description>Filter bits</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB3</name>
+                     <description>Filter bits</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB4</name>
+                     <description>Filter bits</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB5</name>
+                     <description>Filter bits</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB6</name>
+                     <description>Filter bits</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB7</name>
+                     <description>Filter bits</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB8</name>
+                     <description>Filter bits</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB9</name>
+                     <description>Filter bits</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB10</name>
+                     <description>Filter bits</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB11</name>
+                     <description>Filter bits</description>
+                     <bitOffset>11</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB12</name>
+                     <description>Filter bits</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB13</name>
+                     <description>Filter bits</description>
+                     <bitOffset>13</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB14</name>
+                     <description>Filter bits</description>
+                     <bitOffset>14</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB15</name>
+                     <description>Filter bits</description>
+                     <bitOffset>15</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB16</name>
+                     <description>Filter bits</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB17</name>
+                     <description>Filter bits</description>
+                     <bitOffset>17</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB18</name>
+                     <description>Filter bits</description>
+                     <bitOffset>18</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB19</name>
+                     <description>Filter bits</description>
+                     <bitOffset>19</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB20</name>
+                     <description>Filter bits</description>
+                     <bitOffset>20</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB21</name>
+                     <description>Filter bits</description>
+                     <bitOffset>21</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB22</name>
+                     <description>Filter bits</description>
+                     <bitOffset>22</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB23</name>
+                     <description>Filter bits</description>
+                     <bitOffset>23</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB24</name>
+                     <description>Filter bits</description>
+                     <bitOffset>24</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB25</name>
+                     <description>Filter bits</description>
+                     <bitOffset>25</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB26</name>
+                     <description>Filter bits</description>
+                     <bitOffset>26</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB27</name>
+                     <description>Filter bits</description>
+                     <bitOffset>27</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB28</name>
+                     <description>Filter bits</description>
+                     <bitOffset>28</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB29</name>
+                     <description>Filter bits</description>
+                     <bitOffset>29</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB30</name>
+                     <description>Filter bits</description>
+                     <bitOffset>30</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB31</name>
+                     <description>Filter bits</description>
+                     <bitOffset>31</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>F9R2</name>
+               <displayName>F9R2</displayName>
+               <description>Filter bank 9 register 2</description>
+               <addressOffset>0x28C</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>FB0</name>
+                     <description>Filter bits</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB1</name>
+                     <description>Filter bits</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB2</name>
+                     <description>Filter bits</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB3</name>
+                     <description>Filter bits</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB4</name>
+                     <description>Filter bits</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB5</name>
+                     <description>Filter bits</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB6</name>
+                     <description>Filter bits</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB7</name>
+                     <description>Filter bits</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB8</name>
+                     <description>Filter bits</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB9</name>
+                     <description>Filter bits</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB10</name>
+                     <description>Filter bits</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB11</name>
+                     <description>Filter bits</description>
+                     <bitOffset>11</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB12</name>
+                     <description>Filter bits</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB13</name>
+                     <description>Filter bits</description>
+                     <bitOffset>13</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB14</name>
+                     <description>Filter bits</description>
+                     <bitOffset>14</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB15</name>
+                     <description>Filter bits</description>
+                     <bitOffset>15</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB16</name>
+                     <description>Filter bits</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB17</name>
+                     <description>Filter bits</description>
+                     <bitOffset>17</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB18</name>
+                     <description>Filter bits</description>
+                     <bitOffset>18</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB19</name>
+                     <description>Filter bits</description>
+                     <bitOffset>19</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB20</name>
+                     <description>Filter bits</description>
+                     <bitOffset>20</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB21</name>
+                     <description>Filter bits</description>
+                     <bitOffset>21</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB22</name>
+                     <description>Filter bits</description>
+                     <bitOffset>22</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB23</name>
+                     <description>Filter bits</description>
+                     <bitOffset>23</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB24</name>
+                     <description>Filter bits</description>
+                     <bitOffset>24</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB25</name>
+                     <description>Filter bits</description>
+                     <bitOffset>25</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB26</name>
+                     <description>Filter bits</description>
+                     <bitOffset>26</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB27</name>
+                     <description>Filter bits</description>
+                     <bitOffset>27</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB28</name>
+                     <description>Filter bits</description>
+                     <bitOffset>28</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB29</name>
+                     <description>Filter bits</description>
+                     <bitOffset>29</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB30</name>
+                     <description>Filter bits</description>
+                     <bitOffset>30</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB31</name>
+                     <description>Filter bits</description>
+                     <bitOffset>31</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>F10R1</name>
+               <displayName>F10R1</displayName>
+               <description>Filter bank 10 register 1</description>
+               <addressOffset>0x290</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>FB0</name>
+                     <description>Filter bits</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB1</name>
+                     <description>Filter bits</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB2</name>
+                     <description>Filter bits</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB3</name>
+                     <description>Filter bits</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB4</name>
+                     <description>Filter bits</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB5</name>
+                     <description>Filter bits</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB6</name>
+                     <description>Filter bits</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB7</name>
+                     <description>Filter bits</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB8</name>
+                     <description>Filter bits</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB9</name>
+                     <description>Filter bits</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB10</name>
+                     <description>Filter bits</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB11</name>
+                     <description>Filter bits</description>
+                     <bitOffset>11</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB12</name>
+                     <description>Filter bits</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB13</name>
+                     <description>Filter bits</description>
+                     <bitOffset>13</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB14</name>
+                     <description>Filter bits</description>
+                     <bitOffset>14</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB15</name>
+                     <description>Filter bits</description>
+                     <bitOffset>15</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB16</name>
+                     <description>Filter bits</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB17</name>
+                     <description>Filter bits</description>
+                     <bitOffset>17</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB18</name>
+                     <description>Filter bits</description>
+                     <bitOffset>18</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB19</name>
+                     <description>Filter bits</description>
+                     <bitOffset>19</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB20</name>
+                     <description>Filter bits</description>
+                     <bitOffset>20</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB21</name>
+                     <description>Filter bits</description>
+                     <bitOffset>21</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB22</name>
+                     <description>Filter bits</description>
+                     <bitOffset>22</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB23</name>
+                     <description>Filter bits</description>
+                     <bitOffset>23</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB24</name>
+                     <description>Filter bits</description>
+                     <bitOffset>24</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB25</name>
+                     <description>Filter bits</description>
+                     <bitOffset>25</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB26</name>
+                     <description>Filter bits</description>
+                     <bitOffset>26</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB27</name>
+                     <description>Filter bits</description>
+                     <bitOffset>27</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB28</name>
+                     <description>Filter bits</description>
+                     <bitOffset>28</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB29</name>
+                     <description>Filter bits</description>
+                     <bitOffset>29</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB30</name>
+                     <description>Filter bits</description>
+                     <bitOffset>30</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB31</name>
+                     <description>Filter bits</description>
+                     <bitOffset>31</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>F10R2</name>
+               <displayName>F10R2</displayName>
+               <description>Filter bank 10 register 2</description>
+               <addressOffset>0x294</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>FB0</name>
+                     <description>Filter bits</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB1</name>
+                     <description>Filter bits</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB2</name>
+                     <description>Filter bits</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB3</name>
+                     <description>Filter bits</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB4</name>
+                     <description>Filter bits</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB5</name>
+                     <description>Filter bits</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB6</name>
+                     <description>Filter bits</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB7</name>
+                     <description>Filter bits</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB8</name>
+                     <description>Filter bits</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB9</name>
+                     <description>Filter bits</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB10</name>
+                     <description>Filter bits</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB11</name>
+                     <description>Filter bits</description>
+                     <bitOffset>11</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB12</name>
+                     <description>Filter bits</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB13</name>
+                     <description>Filter bits</description>
+                     <bitOffset>13</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB14</name>
+                     <description>Filter bits</description>
+                     <bitOffset>14</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB15</name>
+                     <description>Filter bits</description>
+                     <bitOffset>15</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB16</name>
+                     <description>Filter bits</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB17</name>
+                     <description>Filter bits</description>
+                     <bitOffset>17</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB18</name>
+                     <description>Filter bits</description>
+                     <bitOffset>18</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB19</name>
+                     <description>Filter bits</description>
+                     <bitOffset>19</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB20</name>
+                     <description>Filter bits</description>
+                     <bitOffset>20</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB21</name>
+                     <description>Filter bits</description>
+                     <bitOffset>21</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB22</name>
+                     <description>Filter bits</description>
+                     <bitOffset>22</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB23</name>
+                     <description>Filter bits</description>
+                     <bitOffset>23</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB24</name>
+                     <description>Filter bits</description>
+                     <bitOffset>24</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB25</name>
+                     <description>Filter bits</description>
+                     <bitOffset>25</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB26</name>
+                     <description>Filter bits</description>
+                     <bitOffset>26</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB27</name>
+                     <description>Filter bits</description>
+                     <bitOffset>27</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB28</name>
+                     <description>Filter bits</description>
+                     <bitOffset>28</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB29</name>
+                     <description>Filter bits</description>
+                     <bitOffset>29</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB30</name>
+                     <description>Filter bits</description>
+                     <bitOffset>30</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB31</name>
+                     <description>Filter bits</description>
+                     <bitOffset>31</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>F11R1</name>
+               <displayName>F11R1</displayName>
+               <description>Filter bank 11 register 1</description>
+               <addressOffset>0x298</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>FB0</name>
+                     <description>Filter bits</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB1</name>
+                     <description>Filter bits</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB2</name>
+                     <description>Filter bits</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB3</name>
+                     <description>Filter bits</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB4</name>
+                     <description>Filter bits</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB5</name>
+                     <description>Filter bits</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB6</name>
+                     <description>Filter bits</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB7</name>
+                     <description>Filter bits</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB8</name>
+                     <description>Filter bits</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB9</name>
+                     <description>Filter bits</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB10</name>
+                     <description>Filter bits</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB11</name>
+                     <description>Filter bits</description>
+                     <bitOffset>11</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB12</name>
+                     <description>Filter bits</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB13</name>
+                     <description>Filter bits</description>
+                     <bitOffset>13</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB14</name>
+                     <description>Filter bits</description>
+                     <bitOffset>14</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB15</name>
+                     <description>Filter bits</description>
+                     <bitOffset>15</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB16</name>
+                     <description>Filter bits</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB17</name>
+                     <description>Filter bits</description>
+                     <bitOffset>17</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB18</name>
+                     <description>Filter bits</description>
+                     <bitOffset>18</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB19</name>
+                     <description>Filter bits</description>
+                     <bitOffset>19</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB20</name>
+                     <description>Filter bits</description>
+                     <bitOffset>20</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB21</name>
+                     <description>Filter bits</description>
+                     <bitOffset>21</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB22</name>
+                     <description>Filter bits</description>
+                     <bitOffset>22</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB23</name>
+                     <description>Filter bits</description>
+                     <bitOffset>23</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB24</name>
+                     <description>Filter bits</description>
+                     <bitOffset>24</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB25</name>
+                     <description>Filter bits</description>
+                     <bitOffset>25</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB26</name>
+                     <description>Filter bits</description>
+                     <bitOffset>26</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB27</name>
+                     <description>Filter bits</description>
+                     <bitOffset>27</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB28</name>
+                     <description>Filter bits</description>
+                     <bitOffset>28</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB29</name>
+                     <description>Filter bits</description>
+                     <bitOffset>29</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB30</name>
+                     <description>Filter bits</description>
+                     <bitOffset>30</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB31</name>
+                     <description>Filter bits</description>
+                     <bitOffset>31</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>F11R2</name>
+               <displayName>F11R2</displayName>
+               <description>Filter bank 11 register 2</description>
+               <addressOffset>0x29C</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>FB0</name>
+                     <description>Filter bits</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB1</name>
+                     <description>Filter bits</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB2</name>
+                     <description>Filter bits</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB3</name>
+                     <description>Filter bits</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB4</name>
+                     <description>Filter bits</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB5</name>
+                     <description>Filter bits</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB6</name>
+                     <description>Filter bits</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB7</name>
+                     <description>Filter bits</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB8</name>
+                     <description>Filter bits</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB9</name>
+                     <description>Filter bits</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB10</name>
+                     <description>Filter bits</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB11</name>
+                     <description>Filter bits</description>
+                     <bitOffset>11</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB12</name>
+                     <description>Filter bits</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB13</name>
+                     <description>Filter bits</description>
+                     <bitOffset>13</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB14</name>
+                     <description>Filter bits</description>
+                     <bitOffset>14</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB15</name>
+                     <description>Filter bits</description>
+                     <bitOffset>15</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB16</name>
+                     <description>Filter bits</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB17</name>
+                     <description>Filter bits</description>
+                     <bitOffset>17</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB18</name>
+                     <description>Filter bits</description>
+                     <bitOffset>18</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB19</name>
+                     <description>Filter bits</description>
+                     <bitOffset>19</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB20</name>
+                     <description>Filter bits</description>
+                     <bitOffset>20</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB21</name>
+                     <description>Filter bits</description>
+                     <bitOffset>21</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB22</name>
+                     <description>Filter bits</description>
+                     <bitOffset>22</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB23</name>
+                     <description>Filter bits</description>
+                     <bitOffset>23</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB24</name>
+                     <description>Filter bits</description>
+                     <bitOffset>24</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB25</name>
+                     <description>Filter bits</description>
+                     <bitOffset>25</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB26</name>
+                     <description>Filter bits</description>
+                     <bitOffset>26</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB27</name>
+                     <description>Filter bits</description>
+                     <bitOffset>27</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB28</name>
+                     <description>Filter bits</description>
+                     <bitOffset>28</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB29</name>
+                     <description>Filter bits</description>
+                     <bitOffset>29</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB30</name>
+                     <description>Filter bits</description>
+                     <bitOffset>30</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB31</name>
+                     <description>Filter bits</description>
+                     <bitOffset>31</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>F12R1</name>
+               <displayName>F12R1</displayName>
+               <description>Filter bank 4 register 1</description>
+               <addressOffset>0x2A0</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>FB0</name>
+                     <description>Filter bits</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB1</name>
+                     <description>Filter bits</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB2</name>
+                     <description>Filter bits</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB3</name>
+                     <description>Filter bits</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB4</name>
+                     <description>Filter bits</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB5</name>
+                     <description>Filter bits</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB6</name>
+                     <description>Filter bits</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB7</name>
+                     <description>Filter bits</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB8</name>
+                     <description>Filter bits</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB9</name>
+                     <description>Filter bits</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB10</name>
+                     <description>Filter bits</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB11</name>
+                     <description>Filter bits</description>
+                     <bitOffset>11</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB12</name>
+                     <description>Filter bits</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB13</name>
+                     <description>Filter bits</description>
+                     <bitOffset>13</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB14</name>
+                     <description>Filter bits</description>
+                     <bitOffset>14</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB15</name>
+                     <description>Filter bits</description>
+                     <bitOffset>15</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB16</name>
+                     <description>Filter bits</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB17</name>
+                     <description>Filter bits</description>
+                     <bitOffset>17</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB18</name>
+                     <description>Filter bits</description>
+                     <bitOffset>18</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB19</name>
+                     <description>Filter bits</description>
+                     <bitOffset>19</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB20</name>
+                     <description>Filter bits</description>
+                     <bitOffset>20</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB21</name>
+                     <description>Filter bits</description>
+                     <bitOffset>21</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB22</name>
+                     <description>Filter bits</description>
+                     <bitOffset>22</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB23</name>
+                     <description>Filter bits</description>
+                     <bitOffset>23</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB24</name>
+                     <description>Filter bits</description>
+                     <bitOffset>24</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB25</name>
+                     <description>Filter bits</description>
+                     <bitOffset>25</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB26</name>
+                     <description>Filter bits</description>
+                     <bitOffset>26</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB27</name>
+                     <description>Filter bits</description>
+                     <bitOffset>27</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB28</name>
+                     <description>Filter bits</description>
+                     <bitOffset>28</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB29</name>
+                     <description>Filter bits</description>
+                     <bitOffset>29</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB30</name>
+                     <description>Filter bits</description>
+                     <bitOffset>30</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB31</name>
+                     <description>Filter bits</description>
+                     <bitOffset>31</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>F12R2</name>
+               <displayName>F12R2</displayName>
+               <description>Filter bank 12 register 2</description>
+               <addressOffset>0x2A4</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>FB0</name>
+                     <description>Filter bits</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB1</name>
+                     <description>Filter bits</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB2</name>
+                     <description>Filter bits</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB3</name>
+                     <description>Filter bits</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB4</name>
+                     <description>Filter bits</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB5</name>
+                     <description>Filter bits</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB6</name>
+                     <description>Filter bits</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB7</name>
+                     <description>Filter bits</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB8</name>
+                     <description>Filter bits</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB9</name>
+                     <description>Filter bits</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB10</name>
+                     <description>Filter bits</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB11</name>
+                     <description>Filter bits</description>
+                     <bitOffset>11</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB12</name>
+                     <description>Filter bits</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB13</name>
+                     <description>Filter bits</description>
+                     <bitOffset>13</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB14</name>
+                     <description>Filter bits</description>
+                     <bitOffset>14</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB15</name>
+                     <description>Filter bits</description>
+                     <bitOffset>15</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB16</name>
+                     <description>Filter bits</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB17</name>
+                     <description>Filter bits</description>
+                     <bitOffset>17</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB18</name>
+                     <description>Filter bits</description>
+                     <bitOffset>18</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB19</name>
+                     <description>Filter bits</description>
+                     <bitOffset>19</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB20</name>
+                     <description>Filter bits</description>
+                     <bitOffset>20</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB21</name>
+                     <description>Filter bits</description>
+                     <bitOffset>21</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB22</name>
+                     <description>Filter bits</description>
+                     <bitOffset>22</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB23</name>
+                     <description>Filter bits</description>
+                     <bitOffset>23</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB24</name>
+                     <description>Filter bits</description>
+                     <bitOffset>24</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB25</name>
+                     <description>Filter bits</description>
+                     <bitOffset>25</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB26</name>
+                     <description>Filter bits</description>
+                     <bitOffset>26</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB27</name>
+                     <description>Filter bits</description>
+                     <bitOffset>27</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB28</name>
+                     <description>Filter bits</description>
+                     <bitOffset>28</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB29</name>
+                     <description>Filter bits</description>
+                     <bitOffset>29</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB30</name>
+                     <description>Filter bits</description>
+                     <bitOffset>30</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB31</name>
+                     <description>Filter bits</description>
+                     <bitOffset>31</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>F13R1</name>
+               <displayName>F13R1</displayName>
+               <description>Filter bank 13 register 1</description>
+               <addressOffset>0x2A8</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>FB0</name>
+                     <description>Filter bits</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB1</name>
+                     <description>Filter bits</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB2</name>
+                     <description>Filter bits</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB3</name>
+                     <description>Filter bits</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB4</name>
+                     <description>Filter bits</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB5</name>
+                     <description>Filter bits</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB6</name>
+                     <description>Filter bits</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB7</name>
+                     <description>Filter bits</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB8</name>
+                     <description>Filter bits</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB9</name>
+                     <description>Filter bits</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB10</name>
+                     <description>Filter bits</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB11</name>
+                     <description>Filter bits</description>
+                     <bitOffset>11</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB12</name>
+                     <description>Filter bits</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB13</name>
+                     <description>Filter bits</description>
+                     <bitOffset>13</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB14</name>
+                     <description>Filter bits</description>
+                     <bitOffset>14</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB15</name>
+                     <description>Filter bits</description>
+                     <bitOffset>15</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB16</name>
+                     <description>Filter bits</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB17</name>
+                     <description>Filter bits</description>
+                     <bitOffset>17</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB18</name>
+                     <description>Filter bits</description>
+                     <bitOffset>18</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB19</name>
+                     <description>Filter bits</description>
+                     <bitOffset>19</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB20</name>
+                     <description>Filter bits</description>
+                     <bitOffset>20</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB21</name>
+                     <description>Filter bits</description>
+                     <bitOffset>21</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB22</name>
+                     <description>Filter bits</description>
+                     <bitOffset>22</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB23</name>
+                     <description>Filter bits</description>
+                     <bitOffset>23</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB24</name>
+                     <description>Filter bits</description>
+                     <bitOffset>24</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB25</name>
+                     <description>Filter bits</description>
+                     <bitOffset>25</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB26</name>
+                     <description>Filter bits</description>
+                     <bitOffset>26</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB27</name>
+                     <description>Filter bits</description>
+                     <bitOffset>27</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB28</name>
+                     <description>Filter bits</description>
+                     <bitOffset>28</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB29</name>
+                     <description>Filter bits</description>
+                     <bitOffset>29</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB30</name>
+                     <description>Filter bits</description>
+                     <bitOffset>30</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB31</name>
+                     <description>Filter bits</description>
+                     <bitOffset>31</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>F13R2</name>
+               <displayName>F13R2</displayName>
+               <description>Filter bank 13 register 2</description>
+               <addressOffset>0x2AC</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>FB0</name>
+                     <description>Filter bits</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB1</name>
+                     <description>Filter bits</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB2</name>
+                     <description>Filter bits</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB3</name>
+                     <description>Filter bits</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB4</name>
+                     <description>Filter bits</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB5</name>
+                     <description>Filter bits</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB6</name>
+                     <description>Filter bits</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB7</name>
+                     <description>Filter bits</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB8</name>
+                     <description>Filter bits</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB9</name>
+                     <description>Filter bits</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB10</name>
+                     <description>Filter bits</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB11</name>
+                     <description>Filter bits</description>
+                     <bitOffset>11</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB12</name>
+                     <description>Filter bits</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB13</name>
+                     <description>Filter bits</description>
+                     <bitOffset>13</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB14</name>
+                     <description>Filter bits</description>
+                     <bitOffset>14</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB15</name>
+                     <description>Filter bits</description>
+                     <bitOffset>15</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB16</name>
+                     <description>Filter bits</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB17</name>
+                     <description>Filter bits</description>
+                     <bitOffset>17</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB18</name>
+                     <description>Filter bits</description>
+                     <bitOffset>18</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB19</name>
+                     <description>Filter bits</description>
+                     <bitOffset>19</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB20</name>
+                     <description>Filter bits</description>
+                     <bitOffset>20</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB21</name>
+                     <description>Filter bits</description>
+                     <bitOffset>21</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB22</name>
+                     <description>Filter bits</description>
+                     <bitOffset>22</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB23</name>
+                     <description>Filter bits</description>
+                     <bitOffset>23</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB24</name>
+                     <description>Filter bits</description>
+                     <bitOffset>24</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB25</name>
+                     <description>Filter bits</description>
+                     <bitOffset>25</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB26</name>
+                     <description>Filter bits</description>
+                     <bitOffset>26</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB27</name>
+                     <description>Filter bits</description>
+                     <bitOffset>27</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB28</name>
+                     <description>Filter bits</description>
+                     <bitOffset>28</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB29</name>
+                     <description>Filter bits</description>
+                     <bitOffset>29</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB30</name>
+                     <description>Filter bits</description>
+                     <bitOffset>30</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB31</name>
+                     <description>Filter bits</description>
+                     <bitOffset>31</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>F14R1</name>
+               <displayName>F14R1</displayName>
+               <description>Filter bank 14 register 1</description>
+               <addressOffset>0x2B0</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>FB0</name>
+                     <description>Filter bits</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB1</name>
+                     <description>Filter bits</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB2</name>
+                     <description>Filter bits</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB3</name>
+                     <description>Filter bits</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB4</name>
+                     <description>Filter bits</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB5</name>
+                     <description>Filter bits</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB6</name>
+                     <description>Filter bits</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB7</name>
+                     <description>Filter bits</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB8</name>
+                     <description>Filter bits</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB9</name>
+                     <description>Filter bits</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB10</name>
+                     <description>Filter bits</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB11</name>
+                     <description>Filter bits</description>
+                     <bitOffset>11</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB12</name>
+                     <description>Filter bits</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB13</name>
+                     <description>Filter bits</description>
+                     <bitOffset>13</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB14</name>
+                     <description>Filter bits</description>
+                     <bitOffset>14</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB15</name>
+                     <description>Filter bits</description>
+                     <bitOffset>15</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB16</name>
+                     <description>Filter bits</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB17</name>
+                     <description>Filter bits</description>
+                     <bitOffset>17</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB18</name>
+                     <description>Filter bits</description>
+                     <bitOffset>18</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB19</name>
+                     <description>Filter bits</description>
+                     <bitOffset>19</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB20</name>
+                     <description>Filter bits</description>
+                     <bitOffset>20</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB21</name>
+                     <description>Filter bits</description>
+                     <bitOffset>21</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB22</name>
+                     <description>Filter bits</description>
+                     <bitOffset>22</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB23</name>
+                     <description>Filter bits</description>
+                     <bitOffset>23</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB24</name>
+                     <description>Filter bits</description>
+                     <bitOffset>24</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB25</name>
+                     <description>Filter bits</description>
+                     <bitOffset>25</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB26</name>
+                     <description>Filter bits</description>
+                     <bitOffset>26</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB27</name>
+                     <description>Filter bits</description>
+                     <bitOffset>27</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB28</name>
+                     <description>Filter bits</description>
+                     <bitOffset>28</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB29</name>
+                     <description>Filter bits</description>
+                     <bitOffset>29</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB30</name>
+                     <description>Filter bits</description>
+                     <bitOffset>30</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB31</name>
+                     <description>Filter bits</description>
+                     <bitOffset>31</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>F14R2</name>
+               <displayName>F14R2</displayName>
+               <description>Filter bank 14 register 2</description>
+               <addressOffset>0x2B4</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>FB0</name>
+                     <description>Filter bits</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB1</name>
+                     <description>Filter bits</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB2</name>
+                     <description>Filter bits</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB3</name>
+                     <description>Filter bits</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB4</name>
+                     <description>Filter bits</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB5</name>
+                     <description>Filter bits</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB6</name>
+                     <description>Filter bits</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB7</name>
+                     <description>Filter bits</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB8</name>
+                     <description>Filter bits</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB9</name>
+                     <description>Filter bits</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB10</name>
+                     <description>Filter bits</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB11</name>
+                     <description>Filter bits</description>
+                     <bitOffset>11</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB12</name>
+                     <description>Filter bits</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB13</name>
+                     <description>Filter bits</description>
+                     <bitOffset>13</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB14</name>
+                     <description>Filter bits</description>
+                     <bitOffset>14</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB15</name>
+                     <description>Filter bits</description>
+                     <bitOffset>15</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB16</name>
+                     <description>Filter bits</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB17</name>
+                     <description>Filter bits</description>
+                     <bitOffset>17</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB18</name>
+                     <description>Filter bits</description>
+                     <bitOffset>18</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB19</name>
+                     <description>Filter bits</description>
+                     <bitOffset>19</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB20</name>
+                     <description>Filter bits</description>
+                     <bitOffset>20</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB21</name>
+                     <description>Filter bits</description>
+                     <bitOffset>21</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB22</name>
+                     <description>Filter bits</description>
+                     <bitOffset>22</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB23</name>
+                     <description>Filter bits</description>
+                     <bitOffset>23</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB24</name>
+                     <description>Filter bits</description>
+                     <bitOffset>24</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB25</name>
+                     <description>Filter bits</description>
+                     <bitOffset>25</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB26</name>
+                     <description>Filter bits</description>
+                     <bitOffset>26</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB27</name>
+                     <description>Filter bits</description>
+                     <bitOffset>27</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB28</name>
+                     <description>Filter bits</description>
+                     <bitOffset>28</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB29</name>
+                     <description>Filter bits</description>
+                     <bitOffset>29</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB30</name>
+                     <description>Filter bits</description>
+                     <bitOffset>30</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB31</name>
+                     <description>Filter bits</description>
+                     <bitOffset>31</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>F15R1</name>
+               <displayName>F15R1</displayName>
+               <description>Filter bank 15 register 1</description>
+               <addressOffset>0x2B8</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>FB0</name>
+                     <description>Filter bits</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB1</name>
+                     <description>Filter bits</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB2</name>
+                     <description>Filter bits</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB3</name>
+                     <description>Filter bits</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB4</name>
+                     <description>Filter bits</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB5</name>
+                     <description>Filter bits</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB6</name>
+                     <description>Filter bits</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB7</name>
+                     <description>Filter bits</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB8</name>
+                     <description>Filter bits</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB9</name>
+                     <description>Filter bits</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB10</name>
+                     <description>Filter bits</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB11</name>
+                     <description>Filter bits</description>
+                     <bitOffset>11</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB12</name>
+                     <description>Filter bits</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB13</name>
+                     <description>Filter bits</description>
+                     <bitOffset>13</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB14</name>
+                     <description>Filter bits</description>
+                     <bitOffset>14</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB15</name>
+                     <description>Filter bits</description>
+                     <bitOffset>15</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB16</name>
+                     <description>Filter bits</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB17</name>
+                     <description>Filter bits</description>
+                     <bitOffset>17</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB18</name>
+                     <description>Filter bits</description>
+                     <bitOffset>18</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB19</name>
+                     <description>Filter bits</description>
+                     <bitOffset>19</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB20</name>
+                     <description>Filter bits</description>
+                     <bitOffset>20</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB21</name>
+                     <description>Filter bits</description>
+                     <bitOffset>21</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB22</name>
+                     <description>Filter bits</description>
+                     <bitOffset>22</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB23</name>
+                     <description>Filter bits</description>
+                     <bitOffset>23</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB24</name>
+                     <description>Filter bits</description>
+                     <bitOffset>24</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB25</name>
+                     <description>Filter bits</description>
+                     <bitOffset>25</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB26</name>
+                     <description>Filter bits</description>
+                     <bitOffset>26</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB27</name>
+                     <description>Filter bits</description>
+                     <bitOffset>27</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB28</name>
+                     <description>Filter bits</description>
+                     <bitOffset>28</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB29</name>
+                     <description>Filter bits</description>
+                     <bitOffset>29</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB30</name>
+                     <description>Filter bits</description>
+                     <bitOffset>30</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB31</name>
+                     <description>Filter bits</description>
+                     <bitOffset>31</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>F15R2</name>
+               <displayName>F15R2</displayName>
+               <description>Filter bank 15 register 2</description>
+               <addressOffset>0x2BC</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>FB0</name>
+                     <description>Filter bits</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB1</name>
+                     <description>Filter bits</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB2</name>
+                     <description>Filter bits</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB3</name>
+                     <description>Filter bits</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB4</name>
+                     <description>Filter bits</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB5</name>
+                     <description>Filter bits</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB6</name>
+                     <description>Filter bits</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB7</name>
+                     <description>Filter bits</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB8</name>
+                     <description>Filter bits</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB9</name>
+                     <description>Filter bits</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB10</name>
+                     <description>Filter bits</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB11</name>
+                     <description>Filter bits</description>
+                     <bitOffset>11</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB12</name>
+                     <description>Filter bits</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB13</name>
+                     <description>Filter bits</description>
+                     <bitOffset>13</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB14</name>
+                     <description>Filter bits</description>
+                     <bitOffset>14</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB15</name>
+                     <description>Filter bits</description>
+                     <bitOffset>15</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB16</name>
+                     <description>Filter bits</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB17</name>
+                     <description>Filter bits</description>
+                     <bitOffset>17</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB18</name>
+                     <description>Filter bits</description>
+                     <bitOffset>18</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB19</name>
+                     <description>Filter bits</description>
+                     <bitOffset>19</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB20</name>
+                     <description>Filter bits</description>
+                     <bitOffset>20</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB21</name>
+                     <description>Filter bits</description>
+                     <bitOffset>21</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB22</name>
+                     <description>Filter bits</description>
+                     <bitOffset>22</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB23</name>
+                     <description>Filter bits</description>
+                     <bitOffset>23</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB24</name>
+                     <description>Filter bits</description>
+                     <bitOffset>24</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB25</name>
+                     <description>Filter bits</description>
+                     <bitOffset>25</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB26</name>
+                     <description>Filter bits</description>
+                     <bitOffset>26</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB27</name>
+                     <description>Filter bits</description>
+                     <bitOffset>27</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB28</name>
+                     <description>Filter bits</description>
+                     <bitOffset>28</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB29</name>
+                     <description>Filter bits</description>
+                     <bitOffset>29</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB30</name>
+                     <description>Filter bits</description>
+                     <bitOffset>30</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB31</name>
+                     <description>Filter bits</description>
+                     <bitOffset>31</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>F16R1</name>
+               <displayName>F16R1</displayName>
+               <description>Filter bank 16 register 1</description>
+               <addressOffset>0x2C0</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>FB0</name>
+                     <description>Filter bits</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB1</name>
+                     <description>Filter bits</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB2</name>
+                     <description>Filter bits</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB3</name>
+                     <description>Filter bits</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB4</name>
+                     <description>Filter bits</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB5</name>
+                     <description>Filter bits</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB6</name>
+                     <description>Filter bits</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB7</name>
+                     <description>Filter bits</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB8</name>
+                     <description>Filter bits</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB9</name>
+                     <description>Filter bits</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB10</name>
+                     <description>Filter bits</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB11</name>
+                     <description>Filter bits</description>
+                     <bitOffset>11</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB12</name>
+                     <description>Filter bits</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB13</name>
+                     <description>Filter bits</description>
+                     <bitOffset>13</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB14</name>
+                     <description>Filter bits</description>
+                     <bitOffset>14</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB15</name>
+                     <description>Filter bits</description>
+                     <bitOffset>15</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB16</name>
+                     <description>Filter bits</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB17</name>
+                     <description>Filter bits</description>
+                     <bitOffset>17</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB18</name>
+                     <description>Filter bits</description>
+                     <bitOffset>18</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB19</name>
+                     <description>Filter bits</description>
+                     <bitOffset>19</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB20</name>
+                     <description>Filter bits</description>
+                     <bitOffset>20</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB21</name>
+                     <description>Filter bits</description>
+                     <bitOffset>21</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB22</name>
+                     <description>Filter bits</description>
+                     <bitOffset>22</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB23</name>
+                     <description>Filter bits</description>
+                     <bitOffset>23</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB24</name>
+                     <description>Filter bits</description>
+                     <bitOffset>24</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB25</name>
+                     <description>Filter bits</description>
+                     <bitOffset>25</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB26</name>
+                     <description>Filter bits</description>
+                     <bitOffset>26</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB27</name>
+                     <description>Filter bits</description>
+                     <bitOffset>27</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB28</name>
+                     <description>Filter bits</description>
+                     <bitOffset>28</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB29</name>
+                     <description>Filter bits</description>
+                     <bitOffset>29</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB30</name>
+                     <description>Filter bits</description>
+                     <bitOffset>30</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB31</name>
+                     <description>Filter bits</description>
+                     <bitOffset>31</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>F16R2</name>
+               <displayName>F16R2</displayName>
+               <description>Filter bank 16 register 2</description>
+               <addressOffset>0x2C4</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>FB0</name>
+                     <description>Filter bits</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB1</name>
+                     <description>Filter bits</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB2</name>
+                     <description>Filter bits</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB3</name>
+                     <description>Filter bits</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB4</name>
+                     <description>Filter bits</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB5</name>
+                     <description>Filter bits</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB6</name>
+                     <description>Filter bits</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB7</name>
+                     <description>Filter bits</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB8</name>
+                     <description>Filter bits</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB9</name>
+                     <description>Filter bits</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB10</name>
+                     <description>Filter bits</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB11</name>
+                     <description>Filter bits</description>
+                     <bitOffset>11</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB12</name>
+                     <description>Filter bits</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB13</name>
+                     <description>Filter bits</description>
+                     <bitOffset>13</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB14</name>
+                     <description>Filter bits</description>
+                     <bitOffset>14</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB15</name>
+                     <description>Filter bits</description>
+                     <bitOffset>15</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB16</name>
+                     <description>Filter bits</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB17</name>
+                     <description>Filter bits</description>
+                     <bitOffset>17</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB18</name>
+                     <description>Filter bits</description>
+                     <bitOffset>18</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB19</name>
+                     <description>Filter bits</description>
+                     <bitOffset>19</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB20</name>
+                     <description>Filter bits</description>
+                     <bitOffset>20</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB21</name>
+                     <description>Filter bits</description>
+                     <bitOffset>21</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB22</name>
+                     <description>Filter bits</description>
+                     <bitOffset>22</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB23</name>
+                     <description>Filter bits</description>
+                     <bitOffset>23</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB24</name>
+                     <description>Filter bits</description>
+                     <bitOffset>24</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB25</name>
+                     <description>Filter bits</description>
+                     <bitOffset>25</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB26</name>
+                     <description>Filter bits</description>
+                     <bitOffset>26</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB27</name>
+                     <description>Filter bits</description>
+                     <bitOffset>27</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB28</name>
+                     <description>Filter bits</description>
+                     <bitOffset>28</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB29</name>
+                     <description>Filter bits</description>
+                     <bitOffset>29</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB30</name>
+                     <description>Filter bits</description>
+                     <bitOffset>30</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB31</name>
+                     <description>Filter bits</description>
+                     <bitOffset>31</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>F17R1</name>
+               <displayName>F17R1</displayName>
+               <description>Filter bank 17 register 1</description>
+               <addressOffset>0x2C8</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>FB0</name>
+                     <description>Filter bits</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB1</name>
+                     <description>Filter bits</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB2</name>
+                     <description>Filter bits</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB3</name>
+                     <description>Filter bits</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB4</name>
+                     <description>Filter bits</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB5</name>
+                     <description>Filter bits</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB6</name>
+                     <description>Filter bits</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB7</name>
+                     <description>Filter bits</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB8</name>
+                     <description>Filter bits</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB9</name>
+                     <description>Filter bits</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB10</name>
+                     <description>Filter bits</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB11</name>
+                     <description>Filter bits</description>
+                     <bitOffset>11</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB12</name>
+                     <description>Filter bits</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB13</name>
+                     <description>Filter bits</description>
+                     <bitOffset>13</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB14</name>
+                     <description>Filter bits</description>
+                     <bitOffset>14</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB15</name>
+                     <description>Filter bits</description>
+                     <bitOffset>15</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB16</name>
+                     <description>Filter bits</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB17</name>
+                     <description>Filter bits</description>
+                     <bitOffset>17</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB18</name>
+                     <description>Filter bits</description>
+                     <bitOffset>18</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB19</name>
+                     <description>Filter bits</description>
+                     <bitOffset>19</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB20</name>
+                     <description>Filter bits</description>
+                     <bitOffset>20</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB21</name>
+                     <description>Filter bits</description>
+                     <bitOffset>21</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB22</name>
+                     <description>Filter bits</description>
+                     <bitOffset>22</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB23</name>
+                     <description>Filter bits</description>
+                     <bitOffset>23</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB24</name>
+                     <description>Filter bits</description>
+                     <bitOffset>24</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB25</name>
+                     <description>Filter bits</description>
+                     <bitOffset>25</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB26</name>
+                     <description>Filter bits</description>
+                     <bitOffset>26</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB27</name>
+                     <description>Filter bits</description>
+                     <bitOffset>27</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB28</name>
+                     <description>Filter bits</description>
+                     <bitOffset>28</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB29</name>
+                     <description>Filter bits</description>
+                     <bitOffset>29</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB30</name>
+                     <description>Filter bits</description>
+                     <bitOffset>30</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB31</name>
+                     <description>Filter bits</description>
+                     <bitOffset>31</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>F17R2</name>
+               <displayName>F17R2</displayName>
+               <description>Filter bank 17 register 2</description>
+               <addressOffset>0x2CC</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>FB0</name>
+                     <description>Filter bits</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB1</name>
+                     <description>Filter bits</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB2</name>
+                     <description>Filter bits</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB3</name>
+                     <description>Filter bits</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB4</name>
+                     <description>Filter bits</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB5</name>
+                     <description>Filter bits</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB6</name>
+                     <description>Filter bits</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB7</name>
+                     <description>Filter bits</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB8</name>
+                     <description>Filter bits</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB9</name>
+                     <description>Filter bits</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB10</name>
+                     <description>Filter bits</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB11</name>
+                     <description>Filter bits</description>
+                     <bitOffset>11</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB12</name>
+                     <description>Filter bits</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB13</name>
+                     <description>Filter bits</description>
+                     <bitOffset>13</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB14</name>
+                     <description>Filter bits</description>
+                     <bitOffset>14</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB15</name>
+                     <description>Filter bits</description>
+                     <bitOffset>15</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB16</name>
+                     <description>Filter bits</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB17</name>
+                     <description>Filter bits</description>
+                     <bitOffset>17</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB18</name>
+                     <description>Filter bits</description>
+                     <bitOffset>18</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB19</name>
+                     <description>Filter bits</description>
+                     <bitOffset>19</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB20</name>
+                     <description>Filter bits</description>
+                     <bitOffset>20</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB21</name>
+                     <description>Filter bits</description>
+                     <bitOffset>21</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB22</name>
+                     <description>Filter bits</description>
+                     <bitOffset>22</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB23</name>
+                     <description>Filter bits</description>
+                     <bitOffset>23</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB24</name>
+                     <description>Filter bits</description>
+                     <bitOffset>24</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB25</name>
+                     <description>Filter bits</description>
+                     <bitOffset>25</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB26</name>
+                     <description>Filter bits</description>
+                     <bitOffset>26</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB27</name>
+                     <description>Filter bits</description>
+                     <bitOffset>27</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB28</name>
+                     <description>Filter bits</description>
+                     <bitOffset>28</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB29</name>
+                     <description>Filter bits</description>
+                     <bitOffset>29</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB30</name>
+                     <description>Filter bits</description>
+                     <bitOffset>30</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB31</name>
+                     <description>Filter bits</description>
+                     <bitOffset>31</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>F18R1</name>
+               <displayName>F18R1</displayName>
+               <description>Filter bank 18 register 1</description>
+               <addressOffset>0x2D0</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>FB0</name>
+                     <description>Filter bits</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB1</name>
+                     <description>Filter bits</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB2</name>
+                     <description>Filter bits</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB3</name>
+                     <description>Filter bits</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB4</name>
+                     <description>Filter bits</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB5</name>
+                     <description>Filter bits</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB6</name>
+                     <description>Filter bits</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB7</name>
+                     <description>Filter bits</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB8</name>
+                     <description>Filter bits</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB9</name>
+                     <description>Filter bits</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB10</name>
+                     <description>Filter bits</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB11</name>
+                     <description>Filter bits</description>
+                     <bitOffset>11</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB12</name>
+                     <description>Filter bits</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB13</name>
+                     <description>Filter bits</description>
+                     <bitOffset>13</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB14</name>
+                     <description>Filter bits</description>
+                     <bitOffset>14</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB15</name>
+                     <description>Filter bits</description>
+                     <bitOffset>15</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB16</name>
+                     <description>Filter bits</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB17</name>
+                     <description>Filter bits</description>
+                     <bitOffset>17</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB18</name>
+                     <description>Filter bits</description>
+                     <bitOffset>18</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB19</name>
+                     <description>Filter bits</description>
+                     <bitOffset>19</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB20</name>
+                     <description>Filter bits</description>
+                     <bitOffset>20</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB21</name>
+                     <description>Filter bits</description>
+                     <bitOffset>21</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB22</name>
+                     <description>Filter bits</description>
+                     <bitOffset>22</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB23</name>
+                     <description>Filter bits</description>
+                     <bitOffset>23</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB24</name>
+                     <description>Filter bits</description>
+                     <bitOffset>24</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB25</name>
+                     <description>Filter bits</description>
+                     <bitOffset>25</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB26</name>
+                     <description>Filter bits</description>
+                     <bitOffset>26</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB27</name>
+                     <description>Filter bits</description>
+                     <bitOffset>27</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB28</name>
+                     <description>Filter bits</description>
+                     <bitOffset>28</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB29</name>
+                     <description>Filter bits</description>
+                     <bitOffset>29</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB30</name>
+                     <description>Filter bits</description>
+                     <bitOffset>30</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB31</name>
+                     <description>Filter bits</description>
+                     <bitOffset>31</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>F18R2</name>
+               <displayName>F18R2</displayName>
+               <description>Filter bank 18 register 2</description>
+               <addressOffset>0x2D4</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>FB0</name>
+                     <description>Filter bits</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB1</name>
+                     <description>Filter bits</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB2</name>
+                     <description>Filter bits</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB3</name>
+                     <description>Filter bits</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB4</name>
+                     <description>Filter bits</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB5</name>
+                     <description>Filter bits</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB6</name>
+                     <description>Filter bits</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB7</name>
+                     <description>Filter bits</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB8</name>
+                     <description>Filter bits</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB9</name>
+                     <description>Filter bits</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB10</name>
+                     <description>Filter bits</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB11</name>
+                     <description>Filter bits</description>
+                     <bitOffset>11</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB12</name>
+                     <description>Filter bits</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB13</name>
+                     <description>Filter bits</description>
+                     <bitOffset>13</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB14</name>
+                     <description>Filter bits</description>
+                     <bitOffset>14</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB15</name>
+                     <description>Filter bits</description>
+                     <bitOffset>15</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB16</name>
+                     <description>Filter bits</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB17</name>
+                     <description>Filter bits</description>
+                     <bitOffset>17</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB18</name>
+                     <description>Filter bits</description>
+                     <bitOffset>18</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB19</name>
+                     <description>Filter bits</description>
+                     <bitOffset>19</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB20</name>
+                     <description>Filter bits</description>
+                     <bitOffset>20</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB21</name>
+                     <description>Filter bits</description>
+                     <bitOffset>21</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB22</name>
+                     <description>Filter bits</description>
+                     <bitOffset>22</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB23</name>
+                     <description>Filter bits</description>
+                     <bitOffset>23</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB24</name>
+                     <description>Filter bits</description>
+                     <bitOffset>24</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB25</name>
+                     <description>Filter bits</description>
+                     <bitOffset>25</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB26</name>
+                     <description>Filter bits</description>
+                     <bitOffset>26</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB27</name>
+                     <description>Filter bits</description>
+                     <bitOffset>27</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB28</name>
+                     <description>Filter bits</description>
+                     <bitOffset>28</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB29</name>
+                     <description>Filter bits</description>
+                     <bitOffset>29</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB30</name>
+                     <description>Filter bits</description>
+                     <bitOffset>30</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB31</name>
+                     <description>Filter bits</description>
+                     <bitOffset>31</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>F19R1</name>
+               <displayName>F19R1</displayName>
+               <description>Filter bank 19 register 1</description>
+               <addressOffset>0x2D8</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>FB0</name>
+                     <description>Filter bits</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB1</name>
+                     <description>Filter bits</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB2</name>
+                     <description>Filter bits</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB3</name>
+                     <description>Filter bits</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB4</name>
+                     <description>Filter bits</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB5</name>
+                     <description>Filter bits</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB6</name>
+                     <description>Filter bits</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB7</name>
+                     <description>Filter bits</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB8</name>
+                     <description>Filter bits</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB9</name>
+                     <description>Filter bits</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB10</name>
+                     <description>Filter bits</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB11</name>
+                     <description>Filter bits</description>
+                     <bitOffset>11</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB12</name>
+                     <description>Filter bits</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB13</name>
+                     <description>Filter bits</description>
+                     <bitOffset>13</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB14</name>
+                     <description>Filter bits</description>
+                     <bitOffset>14</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB15</name>
+                     <description>Filter bits</description>
+                     <bitOffset>15</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB16</name>
+                     <description>Filter bits</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB17</name>
+                     <description>Filter bits</description>
+                     <bitOffset>17</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB18</name>
+                     <description>Filter bits</description>
+                     <bitOffset>18</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB19</name>
+                     <description>Filter bits</description>
+                     <bitOffset>19</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB20</name>
+                     <description>Filter bits</description>
+                     <bitOffset>20</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB21</name>
+                     <description>Filter bits</description>
+                     <bitOffset>21</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB22</name>
+                     <description>Filter bits</description>
+                     <bitOffset>22</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB23</name>
+                     <description>Filter bits</description>
+                     <bitOffset>23</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB24</name>
+                     <description>Filter bits</description>
+                     <bitOffset>24</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB25</name>
+                     <description>Filter bits</description>
+                     <bitOffset>25</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB26</name>
+                     <description>Filter bits</description>
+                     <bitOffset>26</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB27</name>
+                     <description>Filter bits</description>
+                     <bitOffset>27</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB28</name>
+                     <description>Filter bits</description>
+                     <bitOffset>28</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB29</name>
+                     <description>Filter bits</description>
+                     <bitOffset>29</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB30</name>
+                     <description>Filter bits</description>
+                     <bitOffset>30</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB31</name>
+                     <description>Filter bits</description>
+                     <bitOffset>31</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>F19R2</name>
+               <displayName>F19R2</displayName>
+               <description>Filter bank 19 register 2</description>
+               <addressOffset>0x2DC</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>FB0</name>
+                     <description>Filter bits</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB1</name>
+                     <description>Filter bits</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB2</name>
+                     <description>Filter bits</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB3</name>
+                     <description>Filter bits</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB4</name>
+                     <description>Filter bits</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB5</name>
+                     <description>Filter bits</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB6</name>
+                     <description>Filter bits</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB7</name>
+                     <description>Filter bits</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB8</name>
+                     <description>Filter bits</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB9</name>
+                     <description>Filter bits</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB10</name>
+                     <description>Filter bits</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB11</name>
+                     <description>Filter bits</description>
+                     <bitOffset>11</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB12</name>
+                     <description>Filter bits</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB13</name>
+                     <description>Filter bits</description>
+                     <bitOffset>13</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB14</name>
+                     <description>Filter bits</description>
+                     <bitOffset>14</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB15</name>
+                     <description>Filter bits</description>
+                     <bitOffset>15</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB16</name>
+                     <description>Filter bits</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB17</name>
+                     <description>Filter bits</description>
+                     <bitOffset>17</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB18</name>
+                     <description>Filter bits</description>
+                     <bitOffset>18</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB19</name>
+                     <description>Filter bits</description>
+                     <bitOffset>19</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB20</name>
+                     <description>Filter bits</description>
+                     <bitOffset>20</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB21</name>
+                     <description>Filter bits</description>
+                     <bitOffset>21</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB22</name>
+                     <description>Filter bits</description>
+                     <bitOffset>22</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB23</name>
+                     <description>Filter bits</description>
+                     <bitOffset>23</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB24</name>
+                     <description>Filter bits</description>
+                     <bitOffset>24</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB25</name>
+                     <description>Filter bits</description>
+                     <bitOffset>25</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB26</name>
+                     <description>Filter bits</description>
+                     <bitOffset>26</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB27</name>
+                     <description>Filter bits</description>
+                     <bitOffset>27</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB28</name>
+                     <description>Filter bits</description>
+                     <bitOffset>28</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB29</name>
+                     <description>Filter bits</description>
+                     <bitOffset>29</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB30</name>
+                     <description>Filter bits</description>
+                     <bitOffset>30</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB31</name>
+                     <description>Filter bits</description>
+                     <bitOffset>31</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>F20R1</name>
+               <displayName>F20R1</displayName>
+               <description>Filter bank 20 register 1</description>
+               <addressOffset>0x2E0</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>FB0</name>
+                     <description>Filter bits</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB1</name>
+                     <description>Filter bits</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB2</name>
+                     <description>Filter bits</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB3</name>
+                     <description>Filter bits</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB4</name>
+                     <description>Filter bits</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB5</name>
+                     <description>Filter bits</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB6</name>
+                     <description>Filter bits</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB7</name>
+                     <description>Filter bits</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB8</name>
+                     <description>Filter bits</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB9</name>
+                     <description>Filter bits</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB10</name>
+                     <description>Filter bits</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB11</name>
+                     <description>Filter bits</description>
+                     <bitOffset>11</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB12</name>
+                     <description>Filter bits</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB13</name>
+                     <description>Filter bits</description>
+                     <bitOffset>13</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB14</name>
+                     <description>Filter bits</description>
+                     <bitOffset>14</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB15</name>
+                     <description>Filter bits</description>
+                     <bitOffset>15</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB16</name>
+                     <description>Filter bits</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB17</name>
+                     <description>Filter bits</description>
+                     <bitOffset>17</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB18</name>
+                     <description>Filter bits</description>
+                     <bitOffset>18</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB19</name>
+                     <description>Filter bits</description>
+                     <bitOffset>19</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB20</name>
+                     <description>Filter bits</description>
+                     <bitOffset>20</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB21</name>
+                     <description>Filter bits</description>
+                     <bitOffset>21</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB22</name>
+                     <description>Filter bits</description>
+                     <bitOffset>22</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB23</name>
+                     <description>Filter bits</description>
+                     <bitOffset>23</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB24</name>
+                     <description>Filter bits</description>
+                     <bitOffset>24</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB25</name>
+                     <description>Filter bits</description>
+                     <bitOffset>25</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB26</name>
+                     <description>Filter bits</description>
+                     <bitOffset>26</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB27</name>
+                     <description>Filter bits</description>
+                     <bitOffset>27</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB28</name>
+                     <description>Filter bits</description>
+                     <bitOffset>28</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB29</name>
+                     <description>Filter bits</description>
+                     <bitOffset>29</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB30</name>
+                     <description>Filter bits</description>
+                     <bitOffset>30</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB31</name>
+                     <description>Filter bits</description>
+                     <bitOffset>31</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>F20R2</name>
+               <displayName>F20R2</displayName>
+               <description>Filter bank 20 register 2</description>
+               <addressOffset>0x2E4</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>FB0</name>
+                     <description>Filter bits</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB1</name>
+                     <description>Filter bits</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB2</name>
+                     <description>Filter bits</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB3</name>
+                     <description>Filter bits</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB4</name>
+                     <description>Filter bits</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB5</name>
+                     <description>Filter bits</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB6</name>
+                     <description>Filter bits</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB7</name>
+                     <description>Filter bits</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB8</name>
+                     <description>Filter bits</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB9</name>
+                     <description>Filter bits</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB10</name>
+                     <description>Filter bits</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB11</name>
+                     <description>Filter bits</description>
+                     <bitOffset>11</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB12</name>
+                     <description>Filter bits</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB13</name>
+                     <description>Filter bits</description>
+                     <bitOffset>13</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB14</name>
+                     <description>Filter bits</description>
+                     <bitOffset>14</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB15</name>
+                     <description>Filter bits</description>
+                     <bitOffset>15</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB16</name>
+                     <description>Filter bits</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB17</name>
+                     <description>Filter bits</description>
+                     <bitOffset>17</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB18</name>
+                     <description>Filter bits</description>
+                     <bitOffset>18</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB19</name>
+                     <description>Filter bits</description>
+                     <bitOffset>19</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB20</name>
+                     <description>Filter bits</description>
+                     <bitOffset>20</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB21</name>
+                     <description>Filter bits</description>
+                     <bitOffset>21</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB22</name>
+                     <description>Filter bits</description>
+                     <bitOffset>22</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB23</name>
+                     <description>Filter bits</description>
+                     <bitOffset>23</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB24</name>
+                     <description>Filter bits</description>
+                     <bitOffset>24</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB25</name>
+                     <description>Filter bits</description>
+                     <bitOffset>25</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB26</name>
+                     <description>Filter bits</description>
+                     <bitOffset>26</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB27</name>
+                     <description>Filter bits</description>
+                     <bitOffset>27</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB28</name>
+                     <description>Filter bits</description>
+                     <bitOffset>28</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB29</name>
+                     <description>Filter bits</description>
+                     <bitOffset>29</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB30</name>
+                     <description>Filter bits</description>
+                     <bitOffset>30</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB31</name>
+                     <description>Filter bits</description>
+                     <bitOffset>31</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>F21R1</name>
+               <displayName>F21R1</displayName>
+               <description>Filter bank 21 register 1</description>
+               <addressOffset>0x2E8</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>FB0</name>
+                     <description>Filter bits</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB1</name>
+                     <description>Filter bits</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB2</name>
+                     <description>Filter bits</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB3</name>
+                     <description>Filter bits</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB4</name>
+                     <description>Filter bits</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB5</name>
+                     <description>Filter bits</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB6</name>
+                     <description>Filter bits</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB7</name>
+                     <description>Filter bits</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB8</name>
+                     <description>Filter bits</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB9</name>
+                     <description>Filter bits</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB10</name>
+                     <description>Filter bits</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB11</name>
+                     <description>Filter bits</description>
+                     <bitOffset>11</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB12</name>
+                     <description>Filter bits</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB13</name>
+                     <description>Filter bits</description>
+                     <bitOffset>13</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB14</name>
+                     <description>Filter bits</description>
+                     <bitOffset>14</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB15</name>
+                     <description>Filter bits</description>
+                     <bitOffset>15</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB16</name>
+                     <description>Filter bits</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB17</name>
+                     <description>Filter bits</description>
+                     <bitOffset>17</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB18</name>
+                     <description>Filter bits</description>
+                     <bitOffset>18</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB19</name>
+                     <description>Filter bits</description>
+                     <bitOffset>19</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB20</name>
+                     <description>Filter bits</description>
+                     <bitOffset>20</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB21</name>
+                     <description>Filter bits</description>
+                     <bitOffset>21</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB22</name>
+                     <description>Filter bits</description>
+                     <bitOffset>22</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB23</name>
+                     <description>Filter bits</description>
+                     <bitOffset>23</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB24</name>
+                     <description>Filter bits</description>
+                     <bitOffset>24</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB25</name>
+                     <description>Filter bits</description>
+                     <bitOffset>25</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB26</name>
+                     <description>Filter bits</description>
+                     <bitOffset>26</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB27</name>
+                     <description>Filter bits</description>
+                     <bitOffset>27</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB28</name>
+                     <description>Filter bits</description>
+                     <bitOffset>28</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB29</name>
+                     <description>Filter bits</description>
+                     <bitOffset>29</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB30</name>
+                     <description>Filter bits</description>
+                     <bitOffset>30</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB31</name>
+                     <description>Filter bits</description>
+                     <bitOffset>31</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>F21R2</name>
+               <displayName>F21R2</displayName>
+               <description>Filter bank 21 register 2</description>
+               <addressOffset>0x2EC</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>FB0</name>
+                     <description>Filter bits</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB1</name>
+                     <description>Filter bits</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB2</name>
+                     <description>Filter bits</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB3</name>
+                     <description>Filter bits</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB4</name>
+                     <description>Filter bits</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB5</name>
+                     <description>Filter bits</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB6</name>
+                     <description>Filter bits</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB7</name>
+                     <description>Filter bits</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB8</name>
+                     <description>Filter bits</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB9</name>
+                     <description>Filter bits</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB10</name>
+                     <description>Filter bits</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB11</name>
+                     <description>Filter bits</description>
+                     <bitOffset>11</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB12</name>
+                     <description>Filter bits</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB13</name>
+                     <description>Filter bits</description>
+                     <bitOffset>13</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB14</name>
+                     <description>Filter bits</description>
+                     <bitOffset>14</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB15</name>
+                     <description>Filter bits</description>
+                     <bitOffset>15</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB16</name>
+                     <description>Filter bits</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB17</name>
+                     <description>Filter bits</description>
+                     <bitOffset>17</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB18</name>
+                     <description>Filter bits</description>
+                     <bitOffset>18</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB19</name>
+                     <description>Filter bits</description>
+                     <bitOffset>19</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB20</name>
+                     <description>Filter bits</description>
+                     <bitOffset>20</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB21</name>
+                     <description>Filter bits</description>
+                     <bitOffset>21</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB22</name>
+                     <description>Filter bits</description>
+                     <bitOffset>22</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB23</name>
+                     <description>Filter bits</description>
+                     <bitOffset>23</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB24</name>
+                     <description>Filter bits</description>
+                     <bitOffset>24</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB25</name>
+                     <description>Filter bits</description>
+                     <bitOffset>25</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB26</name>
+                     <description>Filter bits</description>
+                     <bitOffset>26</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB27</name>
+                     <description>Filter bits</description>
+                     <bitOffset>27</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB28</name>
+                     <description>Filter bits</description>
+                     <bitOffset>28</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB29</name>
+                     <description>Filter bits</description>
+                     <bitOffset>29</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB30</name>
+                     <description>Filter bits</description>
+                     <bitOffset>30</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB31</name>
+                     <description>Filter bits</description>
+                     <bitOffset>31</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>F22R1</name>
+               <displayName>F22R1</displayName>
+               <description>Filter bank 22 register 1</description>
+               <addressOffset>0x2F0</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>FB0</name>
+                     <description>Filter bits</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB1</name>
+                     <description>Filter bits</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB2</name>
+                     <description>Filter bits</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB3</name>
+                     <description>Filter bits</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB4</name>
+                     <description>Filter bits</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB5</name>
+                     <description>Filter bits</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB6</name>
+                     <description>Filter bits</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB7</name>
+                     <description>Filter bits</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB8</name>
+                     <description>Filter bits</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB9</name>
+                     <description>Filter bits</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB10</name>
+                     <description>Filter bits</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB11</name>
+                     <description>Filter bits</description>
+                     <bitOffset>11</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB12</name>
+                     <description>Filter bits</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB13</name>
+                     <description>Filter bits</description>
+                     <bitOffset>13</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB14</name>
+                     <description>Filter bits</description>
+                     <bitOffset>14</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB15</name>
+                     <description>Filter bits</description>
+                     <bitOffset>15</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB16</name>
+                     <description>Filter bits</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB17</name>
+                     <description>Filter bits</description>
+                     <bitOffset>17</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB18</name>
+                     <description>Filter bits</description>
+                     <bitOffset>18</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB19</name>
+                     <description>Filter bits</description>
+                     <bitOffset>19</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB20</name>
+                     <description>Filter bits</description>
+                     <bitOffset>20</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB21</name>
+                     <description>Filter bits</description>
+                     <bitOffset>21</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB22</name>
+                     <description>Filter bits</description>
+                     <bitOffset>22</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB23</name>
+                     <description>Filter bits</description>
+                     <bitOffset>23</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB24</name>
+                     <description>Filter bits</description>
+                     <bitOffset>24</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB25</name>
+                     <description>Filter bits</description>
+                     <bitOffset>25</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB26</name>
+                     <description>Filter bits</description>
+                     <bitOffset>26</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB27</name>
+                     <description>Filter bits</description>
+                     <bitOffset>27</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB28</name>
+                     <description>Filter bits</description>
+                     <bitOffset>28</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB29</name>
+                     <description>Filter bits</description>
+                     <bitOffset>29</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB30</name>
+                     <description>Filter bits</description>
+                     <bitOffset>30</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB31</name>
+                     <description>Filter bits</description>
+                     <bitOffset>31</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>F22R2</name>
+               <displayName>F22R2</displayName>
+               <description>Filter bank 22 register 2</description>
+               <addressOffset>0x2F4</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>FB0</name>
+                     <description>Filter bits</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB1</name>
+                     <description>Filter bits</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB2</name>
+                     <description>Filter bits</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB3</name>
+                     <description>Filter bits</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB4</name>
+                     <description>Filter bits</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB5</name>
+                     <description>Filter bits</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB6</name>
+                     <description>Filter bits</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB7</name>
+                     <description>Filter bits</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB8</name>
+                     <description>Filter bits</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB9</name>
+                     <description>Filter bits</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB10</name>
+                     <description>Filter bits</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB11</name>
+                     <description>Filter bits</description>
+                     <bitOffset>11</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB12</name>
+                     <description>Filter bits</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB13</name>
+                     <description>Filter bits</description>
+                     <bitOffset>13</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB14</name>
+                     <description>Filter bits</description>
+                     <bitOffset>14</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB15</name>
+                     <description>Filter bits</description>
+                     <bitOffset>15</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB16</name>
+                     <description>Filter bits</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB17</name>
+                     <description>Filter bits</description>
+                     <bitOffset>17</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB18</name>
+                     <description>Filter bits</description>
+                     <bitOffset>18</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB19</name>
+                     <description>Filter bits</description>
+                     <bitOffset>19</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB20</name>
+                     <description>Filter bits</description>
+                     <bitOffset>20</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB21</name>
+                     <description>Filter bits</description>
+                     <bitOffset>21</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB22</name>
+                     <description>Filter bits</description>
+                     <bitOffset>22</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB23</name>
+                     <description>Filter bits</description>
+                     <bitOffset>23</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB24</name>
+                     <description>Filter bits</description>
+                     <bitOffset>24</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB25</name>
+                     <description>Filter bits</description>
+                     <bitOffset>25</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB26</name>
+                     <description>Filter bits</description>
+                     <bitOffset>26</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB27</name>
+                     <description>Filter bits</description>
+                     <bitOffset>27</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB28</name>
+                     <description>Filter bits</description>
+                     <bitOffset>28</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB29</name>
+                     <description>Filter bits</description>
+                     <bitOffset>29</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB30</name>
+                     <description>Filter bits</description>
+                     <bitOffset>30</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB31</name>
+                     <description>Filter bits</description>
+                     <bitOffset>31</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>F23R1</name>
+               <displayName>F23R1</displayName>
+               <description>Filter bank 23 register 1</description>
+               <addressOffset>0x2F8</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>FB0</name>
+                     <description>Filter bits</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB1</name>
+                     <description>Filter bits</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB2</name>
+                     <description>Filter bits</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB3</name>
+                     <description>Filter bits</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB4</name>
+                     <description>Filter bits</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB5</name>
+                     <description>Filter bits</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB6</name>
+                     <description>Filter bits</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB7</name>
+                     <description>Filter bits</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB8</name>
+                     <description>Filter bits</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB9</name>
+                     <description>Filter bits</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB10</name>
+                     <description>Filter bits</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB11</name>
+                     <description>Filter bits</description>
+                     <bitOffset>11</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB12</name>
+                     <description>Filter bits</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB13</name>
+                     <description>Filter bits</description>
+                     <bitOffset>13</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB14</name>
+                     <description>Filter bits</description>
+                     <bitOffset>14</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB15</name>
+                     <description>Filter bits</description>
+                     <bitOffset>15</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB16</name>
+                     <description>Filter bits</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB17</name>
+                     <description>Filter bits</description>
+                     <bitOffset>17</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB18</name>
+                     <description>Filter bits</description>
+                     <bitOffset>18</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB19</name>
+                     <description>Filter bits</description>
+                     <bitOffset>19</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB20</name>
+                     <description>Filter bits</description>
+                     <bitOffset>20</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB21</name>
+                     <description>Filter bits</description>
+                     <bitOffset>21</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB22</name>
+                     <description>Filter bits</description>
+                     <bitOffset>22</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB23</name>
+                     <description>Filter bits</description>
+                     <bitOffset>23</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB24</name>
+                     <description>Filter bits</description>
+                     <bitOffset>24</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB25</name>
+                     <description>Filter bits</description>
+                     <bitOffset>25</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB26</name>
+                     <description>Filter bits</description>
+                     <bitOffset>26</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB27</name>
+                     <description>Filter bits</description>
+                     <bitOffset>27</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB28</name>
+                     <description>Filter bits</description>
+                     <bitOffset>28</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB29</name>
+                     <description>Filter bits</description>
+                     <bitOffset>29</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB30</name>
+                     <description>Filter bits</description>
+                     <bitOffset>30</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB31</name>
+                     <description>Filter bits</description>
+                     <bitOffset>31</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>F23R2</name>
+               <displayName>F23R2</displayName>
+               <description>Filter bank 23 register 2</description>
+               <addressOffset>0x2FC</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>FB0</name>
+                     <description>Filter bits</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB1</name>
+                     <description>Filter bits</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB2</name>
+                     <description>Filter bits</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB3</name>
+                     <description>Filter bits</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB4</name>
+                     <description>Filter bits</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB5</name>
+                     <description>Filter bits</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB6</name>
+                     <description>Filter bits</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB7</name>
+                     <description>Filter bits</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB8</name>
+                     <description>Filter bits</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB9</name>
+                     <description>Filter bits</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB10</name>
+                     <description>Filter bits</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB11</name>
+                     <description>Filter bits</description>
+                     <bitOffset>11</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB12</name>
+                     <description>Filter bits</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB13</name>
+                     <description>Filter bits</description>
+                     <bitOffset>13</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB14</name>
+                     <description>Filter bits</description>
+                     <bitOffset>14</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB15</name>
+                     <description>Filter bits</description>
+                     <bitOffset>15</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB16</name>
+                     <description>Filter bits</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB17</name>
+                     <description>Filter bits</description>
+                     <bitOffset>17</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB18</name>
+                     <description>Filter bits</description>
+                     <bitOffset>18</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB19</name>
+                     <description>Filter bits</description>
+                     <bitOffset>19</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB20</name>
+                     <description>Filter bits</description>
+                     <bitOffset>20</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB21</name>
+                     <description>Filter bits</description>
+                     <bitOffset>21</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB22</name>
+                     <description>Filter bits</description>
+                     <bitOffset>22</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB23</name>
+                     <description>Filter bits</description>
+                     <bitOffset>23</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB24</name>
+                     <description>Filter bits</description>
+                     <bitOffset>24</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB25</name>
+                     <description>Filter bits</description>
+                     <bitOffset>25</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB26</name>
+                     <description>Filter bits</description>
+                     <bitOffset>26</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB27</name>
+                     <description>Filter bits</description>
+                     <bitOffset>27</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB28</name>
+                     <description>Filter bits</description>
+                     <bitOffset>28</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB29</name>
+                     <description>Filter bits</description>
+                     <bitOffset>29</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB30</name>
+                     <description>Filter bits</description>
+                     <bitOffset>30</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB31</name>
+                     <description>Filter bits</description>
+                     <bitOffset>31</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>F24R1</name>
+               <displayName>F24R1</displayName>
+               <description>Filter bank 24 register 1</description>
+               <addressOffset>0x300</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>FB0</name>
+                     <description>Filter bits</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB1</name>
+                     <description>Filter bits</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB2</name>
+                     <description>Filter bits</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB3</name>
+                     <description>Filter bits</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB4</name>
+                     <description>Filter bits</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB5</name>
+                     <description>Filter bits</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB6</name>
+                     <description>Filter bits</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB7</name>
+                     <description>Filter bits</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB8</name>
+                     <description>Filter bits</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB9</name>
+                     <description>Filter bits</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB10</name>
+                     <description>Filter bits</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB11</name>
+                     <description>Filter bits</description>
+                     <bitOffset>11</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB12</name>
+                     <description>Filter bits</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB13</name>
+                     <description>Filter bits</description>
+                     <bitOffset>13</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB14</name>
+                     <description>Filter bits</description>
+                     <bitOffset>14</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB15</name>
+                     <description>Filter bits</description>
+                     <bitOffset>15</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB16</name>
+                     <description>Filter bits</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB17</name>
+                     <description>Filter bits</description>
+                     <bitOffset>17</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB18</name>
+                     <description>Filter bits</description>
+                     <bitOffset>18</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB19</name>
+                     <description>Filter bits</description>
+                     <bitOffset>19</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB20</name>
+                     <description>Filter bits</description>
+                     <bitOffset>20</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB21</name>
+                     <description>Filter bits</description>
+                     <bitOffset>21</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB22</name>
+                     <description>Filter bits</description>
+                     <bitOffset>22</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB23</name>
+                     <description>Filter bits</description>
+                     <bitOffset>23</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB24</name>
+                     <description>Filter bits</description>
+                     <bitOffset>24</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB25</name>
+                     <description>Filter bits</description>
+                     <bitOffset>25</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB26</name>
+                     <description>Filter bits</description>
+                     <bitOffset>26</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB27</name>
+                     <description>Filter bits</description>
+                     <bitOffset>27</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB28</name>
+                     <description>Filter bits</description>
+                     <bitOffset>28</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB29</name>
+                     <description>Filter bits</description>
+                     <bitOffset>29</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB30</name>
+                     <description>Filter bits</description>
+                     <bitOffset>30</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB31</name>
+                     <description>Filter bits</description>
+                     <bitOffset>31</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>F24R2</name>
+               <displayName>F24R2</displayName>
+               <description>Filter bank 24 register 2</description>
+               <addressOffset>0x304</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>FB0</name>
+                     <description>Filter bits</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB1</name>
+                     <description>Filter bits</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB2</name>
+                     <description>Filter bits</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB3</name>
+                     <description>Filter bits</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB4</name>
+                     <description>Filter bits</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB5</name>
+                     <description>Filter bits</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB6</name>
+                     <description>Filter bits</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB7</name>
+                     <description>Filter bits</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB8</name>
+                     <description>Filter bits</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB9</name>
+                     <description>Filter bits</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB10</name>
+                     <description>Filter bits</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB11</name>
+                     <description>Filter bits</description>
+                     <bitOffset>11</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB12</name>
+                     <description>Filter bits</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB13</name>
+                     <description>Filter bits</description>
+                     <bitOffset>13</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB14</name>
+                     <description>Filter bits</description>
+                     <bitOffset>14</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB15</name>
+                     <description>Filter bits</description>
+                     <bitOffset>15</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB16</name>
+                     <description>Filter bits</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB17</name>
+                     <description>Filter bits</description>
+                     <bitOffset>17</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB18</name>
+                     <description>Filter bits</description>
+                     <bitOffset>18</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB19</name>
+                     <description>Filter bits</description>
+                     <bitOffset>19</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB20</name>
+                     <description>Filter bits</description>
+                     <bitOffset>20</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB21</name>
+                     <description>Filter bits</description>
+                     <bitOffset>21</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB22</name>
+                     <description>Filter bits</description>
+                     <bitOffset>22</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB23</name>
+                     <description>Filter bits</description>
+                     <bitOffset>23</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB24</name>
+                     <description>Filter bits</description>
+                     <bitOffset>24</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB25</name>
+                     <description>Filter bits</description>
+                     <bitOffset>25</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB26</name>
+                     <description>Filter bits</description>
+                     <bitOffset>26</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB27</name>
+                     <description>Filter bits</description>
+                     <bitOffset>27</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB28</name>
+                     <description>Filter bits</description>
+                     <bitOffset>28</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB29</name>
+                     <description>Filter bits</description>
+                     <bitOffset>29</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB30</name>
+                     <description>Filter bits</description>
+                     <bitOffset>30</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB31</name>
+                     <description>Filter bits</description>
+                     <bitOffset>31</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>F25R1</name>
+               <displayName>F25R1</displayName>
+               <description>Filter bank 25 register 1</description>
+               <addressOffset>0x308</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>FB0</name>
+                     <description>Filter bits</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB1</name>
+                     <description>Filter bits</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB2</name>
+                     <description>Filter bits</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB3</name>
+                     <description>Filter bits</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB4</name>
+                     <description>Filter bits</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB5</name>
+                     <description>Filter bits</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB6</name>
+                     <description>Filter bits</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB7</name>
+                     <description>Filter bits</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB8</name>
+                     <description>Filter bits</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB9</name>
+                     <description>Filter bits</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB10</name>
+                     <description>Filter bits</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB11</name>
+                     <description>Filter bits</description>
+                     <bitOffset>11</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB12</name>
+                     <description>Filter bits</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB13</name>
+                     <description>Filter bits</description>
+                     <bitOffset>13</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB14</name>
+                     <description>Filter bits</description>
+                     <bitOffset>14</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB15</name>
+                     <description>Filter bits</description>
+                     <bitOffset>15</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB16</name>
+                     <description>Filter bits</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB17</name>
+                     <description>Filter bits</description>
+                     <bitOffset>17</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB18</name>
+                     <description>Filter bits</description>
+                     <bitOffset>18</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB19</name>
+                     <description>Filter bits</description>
+                     <bitOffset>19</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB20</name>
+                     <description>Filter bits</description>
+                     <bitOffset>20</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB21</name>
+                     <description>Filter bits</description>
+                     <bitOffset>21</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB22</name>
+                     <description>Filter bits</description>
+                     <bitOffset>22</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB23</name>
+                     <description>Filter bits</description>
+                     <bitOffset>23</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB24</name>
+                     <description>Filter bits</description>
+                     <bitOffset>24</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB25</name>
+                     <description>Filter bits</description>
+                     <bitOffset>25</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB26</name>
+                     <description>Filter bits</description>
+                     <bitOffset>26</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB27</name>
+                     <description>Filter bits</description>
+                     <bitOffset>27</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB28</name>
+                     <description>Filter bits</description>
+                     <bitOffset>28</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB29</name>
+                     <description>Filter bits</description>
+                     <bitOffset>29</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB30</name>
+                     <description>Filter bits</description>
+                     <bitOffset>30</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB31</name>
+                     <description>Filter bits</description>
+                     <bitOffset>31</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>F25R2</name>
+               <displayName>F25R2</displayName>
+               <description>Filter bank 25 register 2</description>
+               <addressOffset>0x30C</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>FB0</name>
+                     <description>Filter bits</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB1</name>
+                     <description>Filter bits</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB2</name>
+                     <description>Filter bits</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB3</name>
+                     <description>Filter bits</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB4</name>
+                     <description>Filter bits</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB5</name>
+                     <description>Filter bits</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB6</name>
+                     <description>Filter bits</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB7</name>
+                     <description>Filter bits</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB8</name>
+                     <description>Filter bits</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB9</name>
+                     <description>Filter bits</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB10</name>
+                     <description>Filter bits</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB11</name>
+                     <description>Filter bits</description>
+                     <bitOffset>11</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB12</name>
+                     <description>Filter bits</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB13</name>
+                     <description>Filter bits</description>
+                     <bitOffset>13</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB14</name>
+                     <description>Filter bits</description>
+                     <bitOffset>14</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB15</name>
+                     <description>Filter bits</description>
+                     <bitOffset>15</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB16</name>
+                     <description>Filter bits</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB17</name>
+                     <description>Filter bits</description>
+                     <bitOffset>17</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB18</name>
+                     <description>Filter bits</description>
+                     <bitOffset>18</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB19</name>
+                     <description>Filter bits</description>
+                     <bitOffset>19</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB20</name>
+                     <description>Filter bits</description>
+                     <bitOffset>20</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB21</name>
+                     <description>Filter bits</description>
+                     <bitOffset>21</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB22</name>
+                     <description>Filter bits</description>
+                     <bitOffset>22</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB23</name>
+                     <description>Filter bits</description>
+                     <bitOffset>23</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB24</name>
+                     <description>Filter bits</description>
+                     <bitOffset>24</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB25</name>
+                     <description>Filter bits</description>
+                     <bitOffset>25</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB26</name>
+                     <description>Filter bits</description>
+                     <bitOffset>26</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB27</name>
+                     <description>Filter bits</description>
+                     <bitOffset>27</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB28</name>
+                     <description>Filter bits</description>
+                     <bitOffset>28</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB29</name>
+                     <description>Filter bits</description>
+                     <bitOffset>29</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB30</name>
+                     <description>Filter bits</description>
+                     <bitOffset>30</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB31</name>
+                     <description>Filter bits</description>
+                     <bitOffset>31</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>F26R1</name>
+               <displayName>F26R1</displayName>
+               <description>Filter bank 26 register 1</description>
+               <addressOffset>0x310</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>FB0</name>
+                     <description>Filter bits</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB1</name>
+                     <description>Filter bits</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB2</name>
+                     <description>Filter bits</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB3</name>
+                     <description>Filter bits</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB4</name>
+                     <description>Filter bits</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB5</name>
+                     <description>Filter bits</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB6</name>
+                     <description>Filter bits</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB7</name>
+                     <description>Filter bits</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB8</name>
+                     <description>Filter bits</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB9</name>
+                     <description>Filter bits</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB10</name>
+                     <description>Filter bits</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB11</name>
+                     <description>Filter bits</description>
+                     <bitOffset>11</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB12</name>
+                     <description>Filter bits</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB13</name>
+                     <description>Filter bits</description>
+                     <bitOffset>13</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB14</name>
+                     <description>Filter bits</description>
+                     <bitOffset>14</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB15</name>
+                     <description>Filter bits</description>
+                     <bitOffset>15</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB16</name>
+                     <description>Filter bits</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB17</name>
+                     <description>Filter bits</description>
+                     <bitOffset>17</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB18</name>
+                     <description>Filter bits</description>
+                     <bitOffset>18</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB19</name>
+                     <description>Filter bits</description>
+                     <bitOffset>19</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB20</name>
+                     <description>Filter bits</description>
+                     <bitOffset>20</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB21</name>
+                     <description>Filter bits</description>
+                     <bitOffset>21</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB22</name>
+                     <description>Filter bits</description>
+                     <bitOffset>22</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB23</name>
+                     <description>Filter bits</description>
+                     <bitOffset>23</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB24</name>
+                     <description>Filter bits</description>
+                     <bitOffset>24</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB25</name>
+                     <description>Filter bits</description>
+                     <bitOffset>25</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB26</name>
+                     <description>Filter bits</description>
+                     <bitOffset>26</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB27</name>
+                     <description>Filter bits</description>
+                     <bitOffset>27</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB28</name>
+                     <description>Filter bits</description>
+                     <bitOffset>28</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB29</name>
+                     <description>Filter bits</description>
+                     <bitOffset>29</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB30</name>
+                     <description>Filter bits</description>
+                     <bitOffset>30</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB31</name>
+                     <description>Filter bits</description>
+                     <bitOffset>31</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>F26R2</name>
+               <displayName>F26R2</displayName>
+               <description>Filter bank 26 register 2</description>
+               <addressOffset>0x314</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>FB0</name>
+                     <description>Filter bits</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB1</name>
+                     <description>Filter bits</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB2</name>
+                     <description>Filter bits</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB3</name>
+                     <description>Filter bits</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB4</name>
+                     <description>Filter bits</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB5</name>
+                     <description>Filter bits</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB6</name>
+                     <description>Filter bits</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB7</name>
+                     <description>Filter bits</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB8</name>
+                     <description>Filter bits</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB9</name>
+                     <description>Filter bits</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB10</name>
+                     <description>Filter bits</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB11</name>
+                     <description>Filter bits</description>
+                     <bitOffset>11</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB12</name>
+                     <description>Filter bits</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB13</name>
+                     <description>Filter bits</description>
+                     <bitOffset>13</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB14</name>
+                     <description>Filter bits</description>
+                     <bitOffset>14</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB15</name>
+                     <description>Filter bits</description>
+                     <bitOffset>15</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB16</name>
+                     <description>Filter bits</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB17</name>
+                     <description>Filter bits</description>
+                     <bitOffset>17</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB18</name>
+                     <description>Filter bits</description>
+                     <bitOffset>18</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB19</name>
+                     <description>Filter bits</description>
+                     <bitOffset>19</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB20</name>
+                     <description>Filter bits</description>
+                     <bitOffset>20</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB21</name>
+                     <description>Filter bits</description>
+                     <bitOffset>21</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB22</name>
+                     <description>Filter bits</description>
+                     <bitOffset>22</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB23</name>
+                     <description>Filter bits</description>
+                     <bitOffset>23</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB24</name>
+                     <description>Filter bits</description>
+                     <bitOffset>24</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB25</name>
+                     <description>Filter bits</description>
+                     <bitOffset>25</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB26</name>
+                     <description>Filter bits</description>
+                     <bitOffset>26</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB27</name>
+                     <description>Filter bits</description>
+                     <bitOffset>27</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB28</name>
+                     <description>Filter bits</description>
+                     <bitOffset>28</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB29</name>
+                     <description>Filter bits</description>
+                     <bitOffset>29</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB30</name>
+                     <description>Filter bits</description>
+                     <bitOffset>30</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB31</name>
+                     <description>Filter bits</description>
+                     <bitOffset>31</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>F27R1</name>
+               <displayName>F27R1</displayName>
+               <description>Filter bank 27 register 1</description>
+               <addressOffset>0x318</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>FB0</name>
+                     <description>Filter bits</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB1</name>
+                     <description>Filter bits</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB2</name>
+                     <description>Filter bits</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB3</name>
+                     <description>Filter bits</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB4</name>
+                     <description>Filter bits</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB5</name>
+                     <description>Filter bits</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB6</name>
+                     <description>Filter bits</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB7</name>
+                     <description>Filter bits</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB8</name>
+                     <description>Filter bits</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB9</name>
+                     <description>Filter bits</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB10</name>
+                     <description>Filter bits</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB11</name>
+                     <description>Filter bits</description>
+                     <bitOffset>11</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB12</name>
+                     <description>Filter bits</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB13</name>
+                     <description>Filter bits</description>
+                     <bitOffset>13</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB14</name>
+                     <description>Filter bits</description>
+                     <bitOffset>14</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB15</name>
+                     <description>Filter bits</description>
+                     <bitOffset>15</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB16</name>
+                     <description>Filter bits</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB17</name>
+                     <description>Filter bits</description>
+                     <bitOffset>17</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB18</name>
+                     <description>Filter bits</description>
+                     <bitOffset>18</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB19</name>
+                     <description>Filter bits</description>
+                     <bitOffset>19</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB20</name>
+                     <description>Filter bits</description>
+                     <bitOffset>20</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB21</name>
+                     <description>Filter bits</description>
+                     <bitOffset>21</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB22</name>
+                     <description>Filter bits</description>
+                     <bitOffset>22</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB23</name>
+                     <description>Filter bits</description>
+                     <bitOffset>23</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB24</name>
+                     <description>Filter bits</description>
+                     <bitOffset>24</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB25</name>
+                     <description>Filter bits</description>
+                     <bitOffset>25</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB26</name>
+                     <description>Filter bits</description>
+                     <bitOffset>26</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB27</name>
+                     <description>Filter bits</description>
+                     <bitOffset>27</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB28</name>
+                     <description>Filter bits</description>
+                     <bitOffset>28</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB29</name>
+                     <description>Filter bits</description>
+                     <bitOffset>29</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB30</name>
+                     <description>Filter bits</description>
+                     <bitOffset>30</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB31</name>
+                     <description>Filter bits</description>
+                     <bitOffset>31</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>F27R2</name>
+               <displayName>F27R2</displayName>
+               <description>Filter bank 27 register 2</description>
+               <addressOffset>0x31C</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>FB0</name>
+                     <description>Filter bits</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB1</name>
+                     <description>Filter bits</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB2</name>
+                     <description>Filter bits</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB3</name>
+                     <description>Filter bits</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB4</name>
+                     <description>Filter bits</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB5</name>
+                     <description>Filter bits</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB6</name>
+                     <description>Filter bits</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB7</name>
+                     <description>Filter bits</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB8</name>
+                     <description>Filter bits</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB9</name>
+                     <description>Filter bits</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB10</name>
+                     <description>Filter bits</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB11</name>
+                     <description>Filter bits</description>
+                     <bitOffset>11</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB12</name>
+                     <description>Filter bits</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB13</name>
+                     <description>Filter bits</description>
+                     <bitOffset>13</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB14</name>
+                     <description>Filter bits</description>
+                     <bitOffset>14</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB15</name>
+                     <description>Filter bits</description>
+                     <bitOffset>15</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB16</name>
+                     <description>Filter bits</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB17</name>
+                     <description>Filter bits</description>
+                     <bitOffset>17</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB18</name>
+                     <description>Filter bits</description>
+                     <bitOffset>18</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB19</name>
+                     <description>Filter bits</description>
+                     <bitOffset>19</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB20</name>
+                     <description>Filter bits</description>
+                     <bitOffset>20</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB21</name>
+                     <description>Filter bits</description>
+                     <bitOffset>21</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB22</name>
+                     <description>Filter bits</description>
+                     <bitOffset>22</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB23</name>
+                     <description>Filter bits</description>
+                     <bitOffset>23</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB24</name>
+                     <description>Filter bits</description>
+                     <bitOffset>24</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB25</name>
+                     <description>Filter bits</description>
+                     <bitOffset>25</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB26</name>
+                     <description>Filter bits</description>
+                     <bitOffset>26</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB27</name>
+                     <description>Filter bits</description>
+                     <bitOffset>27</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB28</name>
+                     <description>Filter bits</description>
+                     <bitOffset>28</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB29</name>
+                     <description>Filter bits</description>
+                     <bitOffset>29</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB30</name>
+                     <description>Filter bits</description>
+                     <bitOffset>30</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB31</name>
+                     <description>Filter bits</description>
+                     <bitOffset>31</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+         </registers>
+      </peripheral>
+      <peripheral derivedFrom="CAN1">
+         <name>CAN2</name>
+         <baseAddress>0x40006800</baseAddress>
+         <interrupt>
+            <name>CAN2_TX</name>
+            <description>CAN2 TX interrupts</description>
+            <value>63</value>
+         </interrupt>
+         <interrupt>
+            <name>CAN2_RX0</name>
+            <description>CAN2 RX0 interrupts</description>
+            <value>64</value>
+         </interrupt>
+         <interrupt>
+            <name>CAN2_RX1</name>
+            <description>CAN2 RX1 interrupts</description>
+            <value>65</value>
+         </interrupt>
+         <interrupt>
+            <name>CAN2_SCE</name>
+            <description>CAN2 SCE interrupt</description>
+            <value>66</value>
+         </interrupt>
+      </peripheral>
+      <peripheral derivedFrom="CAN1">
+         <name>CAN3</name>
+         <baseAddress>0x40003400</baseAddress>
+         <interrupt>
+            <name>CAN3_TX</name>
+            <description>CAN3 TX interrupt</description>
+            <value>104</value>
+         </interrupt>
+         <interrupt>
+            <name>CAN3_RX0</name>
+            <description>CAN3 RX0 interrupt</description>
+            <value>105</value>
+         </interrupt>
+         <interrupt>
+            <name>CAN3_RX1</name>
+            <description>CAN3 RX1 interrupt</description>
+            <value>106</value>
+         </interrupt>
+         <interrupt>
+            <name>CAN3_SCE</name>
+            <description>CAN3 SCE interrupt</description>
+            <value>107</value>
+         </interrupt>
+      </peripheral>
+      <peripheral>
+         <name>Flash</name>
+         <description>FLASH</description>
+         <groupName>FLASH</groupName>
+         <baseAddress>0x40023C00</baseAddress>
+         <addressBlock>
+            <offset>0x0</offset>
+            <size>0x400</size>
+            <usage>registers</usage>
+         </addressBlock>
+         <interrupt>
+            <name>FLASH</name>
+            <description>Flash global interrupt</description>
+            <value>4</value>
+         </interrupt>
+         <registers>
+            <register>
+               <name>ACR</name>
+               <displayName>ACR</displayName>
+               <description>Flash access control register</description>
+               <addressOffset>0x0</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>LATENCY</name>
+                     <description>Latency</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+                  <field>
+                     <name>PRFTEN</name>
+                     <description>Prefetch enable</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>ARTEN</name>
+                     <description>ART Accelerator Enable</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>ARTRST</name>
+                     <description>ART Accelerator reset</description>
+                     <bitOffset>11</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>KEYR</name>
+               <displayName>KEYR</displayName>
+               <description>Flash key register</description>
+               <addressOffset>0x4</addressOffset>
+               <size>0x20</size>
+               <access>write-only</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>KEY</name>
+                     <description>FPEC key</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OPTKEYR</name>
+               <displayName>OPTKEYR</displayName>
+               <description>Flash option key register</description>
+               <addressOffset>0x8</addressOffset>
+               <size>0x20</size>
+               <access>write-only</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>OPTKEY</name>
+                     <description>Option byte key</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>SR</name>
+               <displayName>SR</displayName>
+               <description>Status register</description>
+               <addressOffset>0xC</addressOffset>
+               <size>0x20</size>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>EOP</name>
+                     <description>End of operation</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>OPERR</name>
+                     <description>Operation error</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>WRPERR</name>
+                     <description>Write protection error</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>PGAERR</name>
+                     <description>Programming alignment               error</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>PGPERR</name>
+                     <description>Programming parallelism               error</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>ERSERR</name>
+                     <description>Programming sequence error</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>BSY</name>
+                     <description>Busy</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-only</access>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>CR</name>
+               <displayName>CR</displayName>
+               <description>Control register</description>
+               <addressOffset>0x10</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x80000000</resetValue>
+               <fields>
+                  <field>
+                     <name>PG</name>
+                     <description>Programming</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>SER</name>
+                     <description>Sector Erase</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>MER1</name>
+                     <description>Mass Erase of sectors 0 to               11</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>SNB</name>
+                     <description>Sector number</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>5</bitWidth>
+                  </field>
+                  <field>
+                     <name>PSIZE</name>
+                     <description>Program size</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>MER2</name>
+                     <description>Mass Erase of sectors 12 to               23</description>
+                     <bitOffset>15</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>STRT</name>
+                     <description>Start</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>EOPIE</name>
+                     <description>End of operation interrupt               enable</description>
+                     <bitOffset>24</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>ERRIE</name>
+                     <description>Error interrupt enable</description>
+                     <bitOffset>25</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>LOCK</name>
+                     <description>Lock</description>
+                     <bitOffset>31</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OPTCR</name>
+               <displayName>OPTCR</displayName>
+               <description>Flash option control register</description>
+               <addressOffset>0x14</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x0FFFAAED</resetValue>
+               <fields>
+                  <field>
+                     <name>OPTLOCK</name>
+                     <description>Option lock</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>OPTSTRT</name>
+                     <description>Option start</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>BOR_LEV</name>
+                     <description>BOR reset Level</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>WWDG_SW</name>
+                     <description>User option bytes</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>IWDG_SW</name>
+                     <description>User option bytes</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>nRST_STOP</name>
+                     <description>User option bytes</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>nRST_STDBY</name>
+                     <description>User option bytes</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>RDP</name>
+                     <description>Read protect</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+                  <field>
+                     <name>nWRP</name>
+                     <description>Not write protect</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>12</bitWidth>
+                  </field>
+                  <field>
+                     <name>nDBOOT</name>
+                     <description>Dual Boot mode (valid only when               nDBANK=0)</description>
+                     <bitOffset>28</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>nDBANK</name>
+                     <description>Not dual bank mode</description>
+                     <bitOffset>29</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>IWDG_STDBY</name>
+                     <description>Independent watchdog counter freeze in               standby mode</description>
+                     <bitOffset>30</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>IWDG_STOP</name>
+                     <description>Independent watchdog counter freeze in               Stop mode</description>
+                     <bitOffset>31</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OPTCR1</name>
+               <displayName>OPTCR1</displayName>
+               <description>Flash option control register           1</description>
+               <addressOffset>0x18</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x0FFF0000</resetValue>
+               <fields>
+                  <field>
+                     <name>BOOT_ADD0</name>
+                     <description>Boot base address when Boot pin               =0</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+                  <field>
+                     <name>BOOT_ADD1</name>
+                     <description>Boot base address when Boot pin               =1</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+               </fields>
+            </register>
+         </registers>
+      </peripheral>
+      <peripheral>
+         <name>EXTI</name>
+         <description>External interrupt/event       controller</description>
+         <groupName>EXTI</groupName>
+         <baseAddress>0x40013C00</baseAddress>
+         <addressBlock>
+            <offset>0x0</offset>
+            <size>0x400</size>
+            <usage>registers</usage>
+         </addressBlock>
+         <interrupt>
+            <name>PVD</name>
+            <description>PVD through EXTI line detection</description>
+            <value>1</value>
+         </interrupt>
+         <interrupt>
+            <name>TAMP_STAMP</name>
+            <description>Tamper and TimeStamp interrupts through the
+        EXTI line</description>
+            <value>2</value>
+         </interrupt>
+         <interrupt>
+            <name>EXTI0</name>
+            <description>EXTI Line0 interrupt</description>
+            <value>6</value>
+         </interrupt>
+         <interrupt>
+            <name>EXTI1</name>
+            <description>EXTI Line1 interrupt</description>
+            <value>7</value>
+         </interrupt>
+         <interrupt>
+            <name>EXTI2</name>
+            <description>EXTI Line2 interrupt</description>
+            <value>8</value>
+         </interrupt>
+         <interrupt>
+            <name>EXTI3</name>
+            <description>EXTI Line3 interrupt</description>
+            <value>9</value>
+         </interrupt>
+         <interrupt>
+            <name>EXTI4</name>
+            <description>EXTI Line4 interrupt</description>
+            <value>10</value>
+         </interrupt>
+         <interrupt>
+            <name>EXTI9_5</name>
+            <description>EXTI Line[9:5] interrupts</description>
+            <value>23</value>
+         </interrupt>
+         <interrupt>
+            <name>EXTI15_10</name>
+            <description>EXTI Line[15:10] interrupts</description>
+            <value>40</value>
+         </interrupt>
+         <interrupt>
+            <name>RTC_ALARM</name>
+            <description>RTC alarms through EXTI line 18
+        interrupts</description>
+            <value>41</value>
+         </interrupt>
+         <interrupt>
+            <name>OTG_FS_WKUP</name>
+            <description>USB On-The-Go FS Wakeup through EXTI line
+        interrupt</description>
+            <value>42</value>
+         </interrupt>
+         <registers>
+            <register>
+               <name>IMR</name>
+               <displayName>IMR</displayName>
+               <description>Interrupt mask register           (EXTI_IMR)</description>
+               <addressOffset>0x0</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>MR0</name>
+                     <description>Interrupt Mask on line 0</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>MR1</name>
+                     <description>Interrupt Mask on line 1</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>MR2</name>
+                     <description>Interrupt Mask on line 2</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>MR3</name>
+                     <description>Interrupt Mask on line 3</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>MR4</name>
+                     <description>Interrupt Mask on line 4</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>MR5</name>
+                     <description>Interrupt Mask on line 5</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>MR6</name>
+                     <description>Interrupt Mask on line 6</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>MR7</name>
+                     <description>Interrupt Mask on line 7</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>MR8</name>
+                     <description>Interrupt Mask on line 8</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>MR9</name>
+                     <description>Interrupt Mask on line 9</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>MR10</name>
+                     <description>Interrupt Mask on line 10</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>MR11</name>
+                     <description>Interrupt Mask on line 11</description>
+                     <bitOffset>11</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>MR12</name>
+                     <description>Interrupt Mask on line 12</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>MR13</name>
+                     <description>Interrupt Mask on line 13</description>
+                     <bitOffset>13</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>MR14</name>
+                     <description>Interrupt Mask on line 14</description>
+                     <bitOffset>14</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>MR15</name>
+                     <description>Interrupt Mask on line 15</description>
+                     <bitOffset>15</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>MR16</name>
+                     <description>Interrupt Mask on line 16</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>MR17</name>
+                     <description>Interrupt Mask on line 17</description>
+                     <bitOffset>17</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>MR18</name>
+                     <description>Interrupt Mask on line 18</description>
+                     <bitOffset>18</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>MR19</name>
+                     <description>Interrupt Mask on line 19</description>
+                     <bitOffset>19</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>MR20</name>
+                     <description>Interrupt Mask on line 20</description>
+                     <bitOffset>20</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>MR21</name>
+                     <description>Interrupt Mask on line 21</description>
+                     <bitOffset>21</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>MR22</name>
+                     <description>Interrupt Mask on line 22</description>
+                     <bitOffset>22</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>EMR</name>
+               <displayName>EMR</displayName>
+               <description>Event mask register (EXTI_EMR)</description>
+               <addressOffset>0x4</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>MR0</name>
+                     <description>Event Mask on line 0</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>MR1</name>
+                     <description>Event Mask on line 1</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>MR2</name>
+                     <description>Event Mask on line 2</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>MR3</name>
+                     <description>Event Mask on line 3</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>MR4</name>
+                     <description>Event Mask on line 4</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>MR5</name>
+                     <description>Event Mask on line 5</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>MR6</name>
+                     <description>Event Mask on line 6</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>MR7</name>
+                     <description>Event Mask on line 7</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>MR8</name>
+                     <description>Event Mask on line 8</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>MR9</name>
+                     <description>Event Mask on line 9</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>MR10</name>
+                     <description>Event Mask on line 10</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>MR11</name>
+                     <description>Event Mask on line 11</description>
+                     <bitOffset>11</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>MR12</name>
+                     <description>Event Mask on line 12</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>MR13</name>
+                     <description>Event Mask on line 13</description>
+                     <bitOffset>13</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>MR14</name>
+                     <description>Event Mask on line 14</description>
+                     <bitOffset>14</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>MR15</name>
+                     <description>Event Mask on line 15</description>
+                     <bitOffset>15</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>MR16</name>
+                     <description>Event Mask on line 16</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>MR17</name>
+                     <description>Event Mask on line 17</description>
+                     <bitOffset>17</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>MR18</name>
+                     <description>Event Mask on line 18</description>
+                     <bitOffset>18</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>MR19</name>
+                     <description>Event Mask on line 19</description>
+                     <bitOffset>19</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>MR20</name>
+                     <description>Event Mask on line 20</description>
+                     <bitOffset>20</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>MR21</name>
+                     <description>Event Mask on line 21</description>
+                     <bitOffset>21</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>MR22</name>
+                     <description>Event Mask on line 22</description>
+                     <bitOffset>22</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>RTSR</name>
+               <displayName>RTSR</displayName>
+               <description>Rising Trigger selection register           (EXTI_RTSR)</description>
+               <addressOffset>0x8</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>TR0</name>
+                     <description>Rising trigger event configuration of               line 0</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TR1</name>
+                     <description>Rising trigger event configuration of               line 1</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TR2</name>
+                     <description>Rising trigger event configuration of               line 2</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TR3</name>
+                     <description>Rising trigger event configuration of               line 3</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TR4</name>
+                     <description>Rising trigger event configuration of               line 4</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TR5</name>
+                     <description>Rising trigger event configuration of               line 5</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TR6</name>
+                     <description>Rising trigger event configuration of               line 6</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TR7</name>
+                     <description>Rising trigger event configuration of               line 7</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TR8</name>
+                     <description>Rising trigger event configuration of               line 8</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TR9</name>
+                     <description>Rising trigger event configuration of               line 9</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TR10</name>
+                     <description>Rising trigger event configuration of               line 10</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TR11</name>
+                     <description>Rising trigger event configuration of               line 11</description>
+                     <bitOffset>11</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TR12</name>
+                     <description>Rising trigger event configuration of               line 12</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TR13</name>
+                     <description>Rising trigger event configuration of               line 13</description>
+                     <bitOffset>13</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TR14</name>
+                     <description>Rising trigger event configuration of               line 14</description>
+                     <bitOffset>14</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TR15</name>
+                     <description>Rising trigger event configuration of               line 15</description>
+                     <bitOffset>15</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TR16</name>
+                     <description>Rising trigger event configuration of               line 16</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TR17</name>
+                     <description>Rising trigger event configuration of               line 17</description>
+                     <bitOffset>17</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TR18</name>
+                     <description>Rising trigger event configuration of               line 18</description>
+                     <bitOffset>18</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TR19</name>
+                     <description>Rising trigger event configuration of               line 19</description>
+                     <bitOffset>19</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TR20</name>
+                     <description>Rising trigger event configuration of               line 20</description>
+                     <bitOffset>20</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TR21</name>
+                     <description>Rising trigger event configuration of               line 21</description>
+                     <bitOffset>21</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TR22</name>
+                     <description>Rising trigger event configuration of               line 22</description>
+                     <bitOffset>22</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>FTSR</name>
+               <displayName>FTSR</displayName>
+               <description>Falling Trigger selection register           (EXTI_FTSR)</description>
+               <addressOffset>0xC</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>TR0</name>
+                     <description>Falling trigger event configuration of               line 0</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TR1</name>
+                     <description>Falling trigger event configuration of               line 1</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TR2</name>
+                     <description>Falling trigger event configuration of               line 2</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TR3</name>
+                     <description>Falling trigger event configuration of               line 3</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TR4</name>
+                     <description>Falling trigger event configuration of               line 4</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TR5</name>
+                     <description>Falling trigger event configuration of               line 5</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TR6</name>
+                     <description>Falling trigger event configuration of               line 6</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TR7</name>
+                     <description>Falling trigger event configuration of               line 7</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TR8</name>
+                     <description>Falling trigger event configuration of               line 8</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TR9</name>
+                     <description>Falling trigger event configuration of               line 9</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TR10</name>
+                     <description>Falling trigger event configuration of               line 10</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TR11</name>
+                     <description>Falling trigger event configuration of               line 11</description>
+                     <bitOffset>11</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TR12</name>
+                     <description>Falling trigger event configuration of               line 12</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TR13</name>
+                     <description>Falling trigger event configuration of               line 13</description>
+                     <bitOffset>13</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TR14</name>
+                     <description>Falling trigger event configuration of               line 14</description>
+                     <bitOffset>14</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TR15</name>
+                     <description>Falling trigger event configuration of               line 15</description>
+                     <bitOffset>15</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TR16</name>
+                     <description>Falling trigger event configuration of               line 16</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TR17</name>
+                     <description>Falling trigger event configuration of               line 17</description>
+                     <bitOffset>17</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TR18</name>
+                     <description>Falling trigger event configuration of               line 18</description>
+                     <bitOffset>18</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TR19</name>
+                     <description>Falling trigger event configuration of               line 19</description>
+                     <bitOffset>19</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TR20</name>
+                     <description>Falling trigger event configuration of               line 20</description>
+                     <bitOffset>20</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TR21</name>
+                     <description>Falling trigger event configuration of               line 21</description>
+                     <bitOffset>21</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TR22</name>
+                     <description>Falling trigger event configuration of               line 22</description>
+                     <bitOffset>22</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>SWIER</name>
+               <displayName>SWIER</displayName>
+               <description>Software interrupt event register           (EXTI_SWIER)</description>
+               <addressOffset>0x10</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>SWIER0</name>
+                     <description>Software Interrupt on line               0</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>SWIER1</name>
+                     <description>Software Interrupt on line               1</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>SWIER2</name>
+                     <description>Software Interrupt on line               2</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>SWIER3</name>
+                     <description>Software Interrupt on line               3</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>SWIER4</name>
+                     <description>Software Interrupt on line               4</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>SWIER5</name>
+                     <description>Software Interrupt on line               5</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>SWIER6</name>
+                     <description>Software Interrupt on line               6</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>SWIER7</name>
+                     <description>Software Interrupt on line               7</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>SWIER8</name>
+                     <description>Software Interrupt on line               8</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>SWIER9</name>
+                     <description>Software Interrupt on line               9</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>SWIER10</name>
+                     <description>Software Interrupt on line               10</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>SWIER11</name>
+                     <description>Software Interrupt on line               11</description>
+                     <bitOffset>11</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>SWIER12</name>
+                     <description>Software Interrupt on line               12</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>SWIER13</name>
+                     <description>Software Interrupt on line               13</description>
+                     <bitOffset>13</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>SWIER14</name>
+                     <description>Software Interrupt on line               14</description>
+                     <bitOffset>14</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>SWIER15</name>
+                     <description>Software Interrupt on line               15</description>
+                     <bitOffset>15</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>SWIER16</name>
+                     <description>Software Interrupt on line               16</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>SWIER17</name>
+                     <description>Software Interrupt on line               17</description>
+                     <bitOffset>17</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>SWIER18</name>
+                     <description>Software Interrupt on line               18</description>
+                     <bitOffset>18</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>SWIER19</name>
+                     <description>Software Interrupt on line               19</description>
+                     <bitOffset>19</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>SWIER20</name>
+                     <description>Software Interrupt on line               20</description>
+                     <bitOffset>20</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>SWIER21</name>
+                     <description>Software Interrupt on line               21</description>
+                     <bitOffset>21</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>SWIER22</name>
+                     <description>Software Interrupt on line               22</description>
+                     <bitOffset>22</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>PR</name>
+               <displayName>PR</displayName>
+               <description>Pending register (EXTI_PR)</description>
+               <addressOffset>0x14</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>PR0</name>
+                     <description>Pending bit 0</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>PR1</name>
+                     <description>Pending bit 1</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>PR2</name>
+                     <description>Pending bit 2</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>PR3</name>
+                     <description>Pending bit 3</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>PR4</name>
+                     <description>Pending bit 4</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>PR5</name>
+                     <description>Pending bit 5</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>PR6</name>
+                     <description>Pending bit 6</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>PR7</name>
+                     <description>Pending bit 7</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>PR8</name>
+                     <description>Pending bit 8</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>PR9</name>
+                     <description>Pending bit 9</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>PR10</name>
+                     <description>Pending bit 10</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>PR11</name>
+                     <description>Pending bit 11</description>
+                     <bitOffset>11</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>PR12</name>
+                     <description>Pending bit 12</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>PR13</name>
+                     <description>Pending bit 13</description>
+                     <bitOffset>13</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>PR14</name>
+                     <description>Pending bit 14</description>
+                     <bitOffset>14</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>PR15</name>
+                     <description>Pending bit 15</description>
+                     <bitOffset>15</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>PR16</name>
+                     <description>Pending bit 16</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>PR17</name>
+                     <description>Pending bit 17</description>
+                     <bitOffset>17</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>PR18</name>
+                     <description>Pending bit 18</description>
+                     <bitOffset>18</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>PR19</name>
+                     <description>Pending bit 19</description>
+                     <bitOffset>19</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>PR20</name>
+                     <description>Pending bit 20</description>
+                     <bitOffset>20</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>PR21</name>
+                     <description>Pending bit 21</description>
+                     <bitOffset>21</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>PR22</name>
+                     <description>Pending bit 22</description>
+                     <bitOffset>22</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+         </registers>
+      </peripheral>
+      <peripheral>
+         <name>LTCD</name>
+         <description>LCD-TFT Controller</description>
+         <groupName>LTDC</groupName>
+         <baseAddress>0x40016800</baseAddress>
+         <addressBlock>
+            <offset>0x0</offset>
+            <size>0x400</size>
+            <usage>registers</usage>
+         </addressBlock>
+         <interrupt>
+            <name>LCD_TFT</name>
+            <description>LTDC global interrupt</description>
+            <value>88</value>
+         </interrupt>
+         <interrupt>
+            <name>LCD_TFT</name>
+            <description>LCD-TFT global Error interrupt</description>
+            <value>89</value>
+         </interrupt>
+         <registers>
+            <register>
+               <name>SSCR</name>
+               <displayName>SSCR</displayName>
+               <description>Synchronization Size Configuration           Register</description>
+               <addressOffset>0x8</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>HSW</name>
+                     <description>Horizontal Synchronization Width (in               units of pixel clock period)</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>10</bitWidth>
+                  </field>
+                  <field>
+                     <name>VSH</name>
+                     <description>Vertical Synchronization Height (in               units of horizontal scan line)</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>11</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>BPCR</name>
+               <displayName>BPCR</displayName>
+               <description>Back Porch Configuration           Register</description>
+               <addressOffset>0xC</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>AHBP</name>
+                     <description>Accumulated Horizontal back porch (in               units of pixel clock period)</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>10</bitWidth>
+                  </field>
+                  <field>
+                     <name>AVBP</name>
+                     <description>Accumulated Vertical back porch (in               units of horizontal scan line)</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>11</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>AWCR</name>
+               <displayName>AWCR</displayName>
+               <description>Active Width Configuration           Register</description>
+               <addressOffset>0x10</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>AAV</name>
+                     <description>AAV</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>10</bitWidth>
+                  </field>
+                  <field>
+                     <name>AAH</name>
+                     <description>Accumulated Active Height (in units of               horizontal scan line)</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>11</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>TWCR</name>
+               <displayName>TWCR</displayName>
+               <description>Total Width Configuration           Register</description>
+               <addressOffset>0x14</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>TOTALW</name>
+                     <description>Total Width (in units of pixel clock               period)</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>10</bitWidth>
+                  </field>
+                  <field>
+                     <name>TOTALH</name>
+                     <description>Total Height (in units of horizontal               scan line)</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>11</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>GCR</name>
+               <displayName>GCR</displayName>
+               <description>Global Control Register</description>
+               <addressOffset>0x18</addressOffset>
+               <size>0x20</size>
+               <resetValue>0x00002220</resetValue>
+               <fields>
+                  <field>
+                     <name>HSPOL</name>
+                     <description>Horizontal Synchronization               Polarity</description>
+                     <bitOffset>31</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>VSPOL</name>
+                     <description>Vertical Synchronization               Polarity</description>
+                     <bitOffset>30</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>DEPOL</name>
+                     <description>Data Enable Polarity</description>
+                     <bitOffset>29</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>PCPOL</name>
+                     <description>Pixel Clock Polarity</description>
+                     <bitOffset>28</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>DEN</name>
+                     <description>Dither Enable</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>DRW</name>
+                     <description>Dither Red Width</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>3</bitWidth>
+                     <access>read-only</access>
+                  </field>
+                  <field>
+                     <name>DGW</name>
+                     <description>Dither Green Width</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>3</bitWidth>
+                     <access>read-only</access>
+                  </field>
+                  <field>
+                     <name>DBW</name>
+                     <description>Dither Blue Width</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>3</bitWidth>
+                     <access>read-only</access>
+                  </field>
+                  <field>
+                     <name>LTDCEN</name>
+                     <description>LCD-TFT controller enable               bit</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>SRCR</name>
+               <displayName>SRCR</displayName>
+               <description>Shadow Reload Configuration           Register</description>
+               <addressOffset>0x24</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>VBR</name>
+                     <description>Vertical Blanking Reload</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>IMR</name>
+                     <description>Immediate Reload</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>BCCR</name>
+               <displayName>BCCR</displayName>
+               <description>Background Color Configuration           Register</description>
+               <addressOffset>0x2C</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>BC</name>
+                     <description>Background Color Red value</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>24</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>IER</name>
+               <displayName>IER</displayName>
+               <description>Interrupt Enable Register</description>
+               <addressOffset>0x34</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>RRIE</name>
+                     <description>Register Reload interrupt               enable</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TERRIE</name>
+                     <description>Transfer Error Interrupt               Enable</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FUIE</name>
+                     <description>FIFO Underrun Interrupt               Enable</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>LIE</name>
+                     <description>Line Interrupt Enable</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>ISR</name>
+               <displayName>ISR</displayName>
+               <description>Interrupt Status Register</description>
+               <addressOffset>0x38</addressOffset>
+               <size>0x20</size>
+               <access>read-only</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>RRIF</name>
+                     <description>Register Reload Interrupt               Flag</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TERRIF</name>
+                     <description>Transfer Error interrupt               flag</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FUIF</name>
+                     <description>FIFO Underrun Interrupt               flag</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>LIF</name>
+                     <description>Line Interrupt flag</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>ICR</name>
+               <displayName>ICR</displayName>
+               <description>Interrupt Clear Register</description>
+               <addressOffset>0x3C</addressOffset>
+               <size>0x20</size>
+               <access>write-only</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>CRRIF</name>
+                     <description>Clears Register Reload Interrupt               Flag</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CTERRIF</name>
+                     <description>Clears the Transfer Error Interrupt               Flag</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CFUIF</name>
+                     <description>Clears the FIFO Underrun Interrupt               flag</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CLIF</name>
+                     <description>Clears the Line Interrupt               Flag</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>LIPCR</name>
+               <displayName>LIPCR</displayName>
+               <description>Line Interrupt Position Configuration           Register</description>
+               <addressOffset>0x40</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>LIPOS</name>
+                     <description>Line Interrupt Position</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>11</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>CPSR</name>
+               <displayName>CPSR</displayName>
+               <description>Current Position Status           Register</description>
+               <addressOffset>0x44</addressOffset>
+               <size>0x20</size>
+               <access>read-only</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>CXPOS</name>
+                     <description>Current X Position</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+                  <field>
+                     <name>CYPOS</name>
+                     <description>Current Y Position</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>CDSR</name>
+               <displayName>CDSR</displayName>
+               <description>Current Display Status           Register</description>
+               <addressOffset>0x48</addressOffset>
+               <size>0x20</size>
+               <access>read-only</access>
+               <resetValue>0x0000000F</resetValue>
+               <fields>
+                  <field>
+                     <name>HSYNCS</name>
+                     <description>Horizontal Synchronization display               Status</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>VSYNCS</name>
+                     <description>Vertical Synchronization display               Status</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>HDES</name>
+                     <description>Horizontal Data Enable display               Status</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>VDES</name>
+                     <description>Vertical Data Enable display               Status</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>L1CR</name>
+               <displayName>L1CR</displayName>
+               <description>Layerx Control Register</description>
+               <addressOffset>0x84</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>CLUTEN</name>
+                     <description>Color Look-Up Table Enable</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>COLKEN</name>
+                     <description>Color Keying Enable</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>LEN</name>
+                     <description>Layer Enable</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>L1WHPCR</name>
+               <displayName>L1WHPCR</displayName>
+               <description>Layerx Window Horizontal Position           Configuration Register</description>
+               <addressOffset>0x88</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>WHSPPOS</name>
+                     <description>Window Horizontal Stop               Position</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>12</bitWidth>
+                  </field>
+                  <field>
+                     <name>WHSTPOS</name>
+                     <description>Window Horizontal Start               Position</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>12</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>L1WVPCR</name>
+               <displayName>L1WVPCR</displayName>
+               <description>Layerx Window Vertical Position           Configuration Register</description>
+               <addressOffset>0x8C</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>WVSPPOS</name>
+                     <description>Window Vertical Stop               Position</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>11</bitWidth>
+                  </field>
+                  <field>
+                     <name>WVSTPOS</name>
+                     <description>Window Vertical Start               Position</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>11</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>L1CKCR</name>
+               <displayName>L1CKCR</displayName>
+               <description>Layerx Color Keying Configuration           Register</description>
+               <addressOffset>0x90</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>CKRED</name>
+                     <description>Color Key Red value</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+                  <field>
+                     <name>CKGREEN</name>
+                     <description>Color Key Green value</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+                  <field>
+                     <name>CKBLUE</name>
+                     <description>Color Key Blue value</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>L1PFCR</name>
+               <displayName>L1PFCR</displayName>
+               <description>Layerx Pixel Format Configuration           Register</description>
+               <addressOffset>0x94</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>PF</name>
+                     <description>Pixel Format</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>3</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>L1CACR</name>
+               <displayName>L1CACR</displayName>
+               <description>Layerx Constant Alpha Configuration           Register</description>
+               <addressOffset>0x98</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>CONSTA</name>
+                     <description>Constant Alpha</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>L1DCCR</name>
+               <displayName>L1DCCR</displayName>
+               <description>Layerx Default Color Configuration           Register</description>
+               <addressOffset>0x9C</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DCALPHA</name>
+                     <description>Default Color Alpha</description>
+                     <bitOffset>24</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+                  <field>
+                     <name>DCRED</name>
+                     <description>Default Color Red</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+                  <field>
+                     <name>DCGREEN</name>
+                     <description>Default Color Green</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+                  <field>
+                     <name>DCBLUE</name>
+                     <description>Default Color Blue</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>L1BFCR</name>
+               <displayName>L1BFCR</displayName>
+               <description>Layerx Blending Factors Configuration           Register</description>
+               <addressOffset>0xA0</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000607</resetValue>
+               <fields>
+                  <field>
+                     <name>BF1</name>
+                     <description>Blending Factor 1</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>3</bitWidth>
+                  </field>
+                  <field>
+                     <name>BF2</name>
+                     <description>Blending Factor 2</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>3</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>L1CFBAR</name>
+               <displayName>L1CFBAR</displayName>
+               <description>Layerx Color Frame Buffer Address           Register</description>
+               <addressOffset>0xAC</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>CFBADD</name>
+                     <description>Color Frame Buffer Start               Address</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>L1CFBLR</name>
+               <displayName>L1CFBLR</displayName>
+               <description>Layerx Color Frame Buffer Length           Register</description>
+               <addressOffset>0xB0</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>CFBP</name>
+                     <description>Color Frame Buffer Pitch in               bytes</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>13</bitWidth>
+                  </field>
+                  <field>
+                     <name>CFBLL</name>
+                     <description>Color Frame Buffer Line               Length</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>13</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>L1CFBLNR</name>
+               <displayName>L1CFBLNR</displayName>
+               <description>Layerx ColorFrame Buffer Line Number           Register</description>
+               <addressOffset>0xB4</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>CFBLNBR</name>
+                     <description>Frame Buffer Line Number</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>11</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>L1CLUTWR</name>
+               <displayName>L1CLUTWR</displayName>
+               <description>Layerx CLUT Write Register</description>
+               <addressOffset>0xC4</addressOffset>
+               <size>0x20</size>
+               <access>write-only</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>CLUTADD</name>
+                     <description>CLUT Address</description>
+                     <bitOffset>24</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+                  <field>
+                     <name>RED</name>
+                     <description>Red value</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+                  <field>
+                     <name>GREEN</name>
+                     <description>Green value</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+                  <field>
+                     <name>BLUE</name>
+                     <description>Blue value</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>L2CR</name>
+               <displayName>L2CR</displayName>
+               <description>Layerx Control Register</description>
+               <addressOffset>0x104</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>CLUTEN</name>
+                     <description>Color Look-Up Table Enable</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>COLKEN</name>
+                     <description>Color Keying Enable</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>LEN</name>
+                     <description>Layer Enable</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>L2WHPCR</name>
+               <displayName>L2WHPCR</displayName>
+               <description>Layerx Window Horizontal Position           Configuration Register</description>
+               <addressOffset>0x108</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>WHSPPOS</name>
+                     <description>Window Horizontal Stop               Position</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>12</bitWidth>
+                  </field>
+                  <field>
+                     <name>WHSTPOS</name>
+                     <description>Window Horizontal Start               Position</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>12</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>L2WVPCR</name>
+               <displayName>L2WVPCR</displayName>
+               <description>Layerx Window Vertical Position           Configuration Register</description>
+               <addressOffset>0x10C</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>WVSPPOS</name>
+                     <description>Window Vertical Stop               Position</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>11</bitWidth>
+                  </field>
+                  <field>
+                     <name>WVSTPOS</name>
+                     <description>Window Vertical Start               Position</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>11</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>L2CKCR</name>
+               <displayName>L2CKCR</displayName>
+               <description>Layerx Color Keying Configuration           Register</description>
+               <addressOffset>0x110</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>CKRED</name>
+                     <description>Color Key Red value</description>
+                     <bitOffset>15</bitOffset>
+                     <bitWidth>9</bitWidth>
+                  </field>
+                  <field>
+                     <name>CKGREEN</name>
+                     <description>Color Key Green value</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>7</bitWidth>
+                  </field>
+                  <field>
+                     <name>CKBLUE</name>
+                     <description>Color Key Blue value</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>L2PFCR</name>
+               <displayName>L2PFCR</displayName>
+               <description>Layerx Pixel Format Configuration           Register</description>
+               <addressOffset>0x114</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>PF</name>
+                     <description>Pixel Format</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>3</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>L2CACR</name>
+               <displayName>L2CACR</displayName>
+               <description>Layerx Constant Alpha Configuration           Register</description>
+               <addressOffset>0x118</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>CONSTA</name>
+                     <description>Constant Alpha</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>L2DCCR</name>
+               <displayName>L2DCCR</displayName>
+               <description>Layerx Default Color Configuration           Register</description>
+               <addressOffset>0x11C</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DCALPHA</name>
+                     <description>Default Color Alpha</description>
+                     <bitOffset>24</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+                  <field>
+                     <name>DCRED</name>
+                     <description>Default Color Red</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+                  <field>
+                     <name>DCGREEN</name>
+                     <description>Default Color Green</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+                  <field>
+                     <name>DCBLUE</name>
+                     <description>Default Color Blue</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>L2BFCR</name>
+               <displayName>L2BFCR</displayName>
+               <description>Layerx Blending Factors Configuration           Register</description>
+               <addressOffset>0x120</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000607</resetValue>
+               <fields>
+                  <field>
+                     <name>BF1</name>
+                     <description>Blending Factor 1</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>3</bitWidth>
+                  </field>
+                  <field>
+                     <name>BF2</name>
+                     <description>Blending Factor 2</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>3</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>L2CFBAR</name>
+               <displayName>L2CFBAR</displayName>
+               <description>Layerx Color Frame Buffer Address           Register</description>
+               <addressOffset>0x12C</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>CFBADD</name>
+                     <description>Color Frame Buffer Start               Address</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>L2CFBLR</name>
+               <displayName>L2CFBLR</displayName>
+               <description>Layerx Color Frame Buffer Length           Register</description>
+               <addressOffset>0x130</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>CFBP</name>
+                     <description>Color Frame Buffer Pitch in               bytes</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>13</bitWidth>
+                  </field>
+                  <field>
+                     <name>CFBLL</name>
+                     <description>Color Frame Buffer Line               Length</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>13</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>L2CFBLNR</name>
+               <displayName>L2CFBLNR</displayName>
+               <description>Layerx ColorFrame Buffer Line Number           Register</description>
+               <addressOffset>0x134</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>CFBLNBR</name>
+                     <description>Frame Buffer Line Number</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>11</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>L2CLUTWR</name>
+               <displayName>L2CLUTWR</displayName>
+               <description>Layerx CLUT Write Register</description>
+               <addressOffset>0x144</addressOffset>
+               <size>0x20</size>
+               <access>write-only</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>CLUTADD</name>
+                     <description>CLUT Address</description>
+                     <bitOffset>24</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+                  <field>
+                     <name>RED</name>
+                     <description>Red value</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+                  <field>
+                     <name>GREEN</name>
+                     <description>Green value</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+                  <field>
+                     <name>BLUE</name>
+                     <description>Blue value</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+               </fields>
+            </register>
+         </registers>
+      </peripheral>
+      <peripheral>
+         <name>SAI1</name>
+         <description>Serial audio interface</description>
+         <groupName>SAI</groupName>
+         <baseAddress>0x40015800</baseAddress>
+         <addressBlock>
+            <offset>0x0</offset>
+            <size>0x400</size>
+            <usage>registers</usage>
+         </addressBlock>
+         <interrupt>
+            <name>SAI1</name>
+            <description>SAI1 global interrupt</description>
+            <value>87</value>
+         </interrupt>
+         <registers>
+            <register>
+               <name>BCR1</name>
+               <displayName>BCR1</displayName>
+               <description>BConfiguration register 1</description>
+               <addressOffset>0x24</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000040</resetValue>
+               <fields>
+                  <field>
+                     <name>MCJDIV</name>
+                     <description>Master clock divider</description>
+                     <bitOffset>20</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+                  <field>
+                     <name>NODIV</name>
+                     <description>No divider</description>
+                     <bitOffset>19</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>DMAEN</name>
+                     <description>DMA enable</description>
+                     <bitOffset>17</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>SAIBEN</name>
+                     <description>Audio block B enable</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>OutDri</name>
+                     <description>Output drive</description>
+                     <bitOffset>13</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>MONO</name>
+                     <description>Mono mode</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>SYNCEN</name>
+                     <description>Synchronization enable</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>CKSTR</name>
+                     <description>Clock strobing edge</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>LSBFIRST</name>
+                     <description>Least significant bit               first</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>DS</name>
+                     <description>Data size</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>3</bitWidth>
+                  </field>
+                  <field>
+                     <name>PRTCFG</name>
+                     <description>Protocol configuration</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>MODE</name>
+                     <description>Audio block mode</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>BCR2</name>
+               <displayName>BCR2</displayName>
+               <description>BConfiguration register 2</description>
+               <addressOffset>0x28</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>COMP</name>
+                     <description>Companding mode</description>
+                     <bitOffset>14</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>CPL</name>
+                     <description>Complement bit</description>
+                     <bitOffset>13</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>MUTECN</name>
+                     <description>Mute counter</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>6</bitWidth>
+                  </field>
+                  <field>
+                     <name>MUTEVAL</name>
+                     <description>Mute value</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>MUTE</name>
+                     <description>Mute</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TRIS</name>
+                     <description>Tristate management on data               line</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FFLUS</name>
+                     <description>FIFO flush</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FTH</name>
+                     <description>FIFO threshold</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>3</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>BFRCR</name>
+               <displayName>BFRCR</displayName>
+               <description>BFRCR</description>
+               <addressOffset>0x2C</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000007</resetValue>
+               <fields>
+                  <field>
+                     <name>FSOFF</name>
+                     <description>Frame synchronization               offset</description>
+                     <bitOffset>18</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FSPOL</name>
+                     <description>Frame synchronization               polarity</description>
+                     <bitOffset>17</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FSDEF</name>
+                     <description>Frame synchronization               definition</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FSALL</name>
+                     <description>Frame synchronization active level               length</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>7</bitWidth>
+                  </field>
+                  <field>
+                     <name>FRL</name>
+                     <description>Frame length</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>BSLOTR</name>
+               <displayName>BSLOTR</displayName>
+               <description>BSlot register</description>
+               <addressOffset>0x30</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>SLOTEN</name>
+                     <description>Slot enable</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+                  <field>
+                     <name>NBSLOT</name>
+                     <description>Number of slots in an audio               frame</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+                  <field>
+                     <name>SLOTSZ</name>
+                     <description>Slot size</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>FBOFF</name>
+                     <description>First bit offset</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>5</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>BIM</name>
+               <displayName>BIM</displayName>
+               <description>BInterrupt mask register2</description>
+               <addressOffset>0x34</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>LFSDETIE</name>
+                     <description>Late frame synchronization detection               interrupt enable</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>AFSDETIE</name>
+                     <description>Anticipated frame synchronization               detection interrupt enable</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CNRDYIE</name>
+                     <description>Codec not ready interrupt               enable</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FREQIE</name>
+                     <description>FIFO request interrupt               enable</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>WCKCFG</name>
+                     <description>Wrong clock configuration interrupt               enable</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>MUTEDET</name>
+                     <description>Mute detection interrupt               enable</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>OVRUDRIE</name>
+                     <description>Overrun/underrun interrupt               enable</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>BSR</name>
+               <displayName>BSR</displayName>
+               <description>BStatus register</description>
+               <addressOffset>0x38</addressOffset>
+               <size>0x20</size>
+               <access>read-only</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>FLVL</name>
+                     <description>FIFO level threshold</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>3</bitWidth>
+                  </field>
+                  <field>
+                     <name>LFSDET</name>
+                     <description>Late frame synchronization               detection</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>AFSDET</name>
+                     <description>Anticipated frame synchronization               detection</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CNRDY</name>
+                     <description>Codec not ready</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FREQ</name>
+                     <description>FIFO request</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>WCKCFG</name>
+                     <description>Wrong clock configuration               flag</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>MUTEDET</name>
+                     <description>Mute detection</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>OVRUDR</name>
+                     <description>Overrun / underrun</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>BCLRFR</name>
+               <displayName>BCLRFR</displayName>
+               <description>BClear flag register</description>
+               <addressOffset>0x3C</addressOffset>
+               <size>0x20</size>
+               <access>write-only</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>LFSDET</name>
+                     <description>Clear late frame synchronization               detection flag</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CAFSDET</name>
+                     <description>Clear anticipated frame synchronization               detection flag</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CNRDY</name>
+                     <description>Clear codec not ready flag</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>WCKCFG</name>
+                     <description>Clear wrong clock configuration               flag</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>MUTEDET</name>
+                     <description>Mute detection flag</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>OVRUDR</name>
+                     <description>Clear overrun / underrun</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>BDR</name>
+               <displayName>BDR</displayName>
+               <description>BData register</description>
+               <addressOffset>0x40</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DATA</name>
+                     <description>Data</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>ACR1</name>
+               <displayName>ACR1</displayName>
+               <description>AConfiguration register 1</description>
+               <addressOffset>0x4</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000040</resetValue>
+               <fields>
+                  <field>
+                     <name>MCJDIV</name>
+                     <description>Master clock divider</description>
+                     <bitOffset>20</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+                  <field>
+                     <name>NODIV</name>
+                     <description>No divider</description>
+                     <bitOffset>19</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>DMAEN</name>
+                     <description>DMA enable</description>
+                     <bitOffset>17</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>SAIAEN</name>
+                     <description>Audio block A enable</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>OutDri</name>
+                     <description>Output drive</description>
+                     <bitOffset>13</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>MONO</name>
+                     <description>Mono mode</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>SYNCEN</name>
+                     <description>Synchronization enable</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>CKSTR</name>
+                     <description>Clock strobing edge</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>LSBFIRST</name>
+                     <description>Least significant bit               first</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>DS</name>
+                     <description>Data size</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>3</bitWidth>
+                  </field>
+                  <field>
+                     <name>PRTCFG</name>
+                     <description>Protocol configuration</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>MODE</name>
+                     <description>Audio block mode</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>ACR2</name>
+               <displayName>ACR2</displayName>
+               <description>AConfiguration register 2</description>
+               <addressOffset>0x8</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>COMP</name>
+                     <description>Companding mode</description>
+                     <bitOffset>14</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>CPL</name>
+                     <description>Complement bit</description>
+                     <bitOffset>13</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>MUTECN</name>
+                     <description>Mute counter</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>6</bitWidth>
+                  </field>
+                  <field>
+                     <name>MUTEVAL</name>
+                     <description>Mute value</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>MUTE</name>
+                     <description>Mute</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TRIS</name>
+                     <description>Tristate management on data               line</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FFLUS</name>
+                     <description>FIFO flush</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FTH</name>
+                     <description>FIFO threshold</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>3</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>AFRCR</name>
+               <displayName>AFRCR</displayName>
+               <description>AFRCR</description>
+               <addressOffset>0xC</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000007</resetValue>
+               <fields>
+                  <field>
+                     <name>FSOFF</name>
+                     <description>Frame synchronization               offset</description>
+                     <bitOffset>18</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FSPOL</name>
+                     <description>Frame synchronization               polarity</description>
+                     <bitOffset>17</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FSDEF</name>
+                     <description>Frame synchronization               definition</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FSALL</name>
+                     <description>Frame synchronization active level               length</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>7</bitWidth>
+                  </field>
+                  <field>
+                     <name>FRL</name>
+                     <description>Frame length</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>ASLOTR</name>
+               <displayName>ASLOTR</displayName>
+               <description>ASlot register</description>
+               <addressOffset>0x10</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>SLOTEN</name>
+                     <description>Slot enable</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+                  <field>
+                     <name>NBSLOT</name>
+                     <description>Number of slots in an audio               frame</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+                  <field>
+                     <name>SLOTSZ</name>
+                     <description>Slot size</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>FBOFF</name>
+                     <description>First bit offset</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>5</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>AIM</name>
+               <displayName>AIM</displayName>
+               <description>AInterrupt mask register2</description>
+               <addressOffset>0x14</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>LFSDET</name>
+                     <description>Late frame synchronization detection               interrupt enable</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>AFSDETIE</name>
+                     <description>Anticipated frame synchronization               detection interrupt enable</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CNRDYIE</name>
+                     <description>Codec not ready interrupt               enable</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FREQIE</name>
+                     <description>FIFO request interrupt               enable</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>WCKCFG</name>
+                     <description>Wrong clock configuration interrupt               enable</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>MUTEDET</name>
+                     <description>Mute detection interrupt               enable</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>OVRUDRIE</name>
+                     <description>Overrun/underrun interrupt               enable</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>ASR</name>
+               <displayName>ASR</displayName>
+               <description>AStatus register</description>
+               <addressOffset>0x18</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>FLVL</name>
+                     <description>FIFO level threshold</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>3</bitWidth>
+                  </field>
+                  <field>
+                     <name>LFSDET</name>
+                     <description>Late frame synchronization               detection</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>AFSDET</name>
+                     <description>Anticipated frame synchronization               detection</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CNRDY</name>
+                     <description>Codec not ready</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FREQ</name>
+                     <description>FIFO request</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>WCKCFG</name>
+                     <description>Wrong clock configuration flag. This bit               is read only.</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>MUTEDET</name>
+                     <description>Mute detection</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>OVRUDR</name>
+                     <description>Overrun / underrun</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>ACLRFR</name>
+               <displayName>ACLRFR</displayName>
+               <description>AClear flag register</description>
+               <addressOffset>0x1C</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>LFSDET</name>
+                     <description>Clear late frame synchronization               detection flag</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CAFSDET</name>
+                     <description>Clear anticipated frame synchronization               detection flag.</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CNRDY</name>
+                     <description>Clear codec not ready flag</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>WCKCFG</name>
+                     <description>Clear wrong clock configuration               flag</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>MUTEDET</name>
+                     <description>Mute detection flag</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>OVRUDR</name>
+                     <description>Clear overrun / underrun</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>ADR</name>
+               <displayName>ADR</displayName>
+               <description>AData register</description>
+               <addressOffset>0x20</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DATA</name>
+                     <description>Data</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>GCR</name>
+               <displayName>GCR</displayName>
+               <description>Global configuration register</description>
+               <addressOffset>0x0</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>SYNCIN</name>
+                     <description>Synchronization inputs</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>SYNCOUT</name>
+                     <description>Synchronization outputs</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+               </fields>
+            </register>
+         </registers>
+      </peripheral>
+      <peripheral derivedFrom="SAI1">
+         <name>SAI2</name>
+         <baseAddress>0x40015C00</baseAddress>
+         <interrupt>
+            <name>SAI2</name>
+            <description>SAI2 global interrupt</description>
+            <value>91</value>
+         </interrupt>
+      </peripheral>
+      <peripheral>
+         <name>DMA2D</name>
+         <description>DMA2D controller</description>
+         <groupName>DMA2D</groupName>
+         <baseAddress>0x4002B000</baseAddress>
+         <addressBlock>
+            <offset>0x0</offset>
+            <size>0xC00</size>
+            <usage>registers</usage>
+         </addressBlock>
+         <interrupt>
+            <name>DMA2D</name>
+            <description>DMA2D global interrupt</description>
+            <value>90</value>
+         </interrupt>
+         <registers>
+            <register>
+               <name>CR</name>
+               <displayName>CR</displayName>
+               <description>control register</description>
+               <addressOffset>0x0</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>MODE</name>
+                     <description>DMA2D mode</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>CEIE</name>
+                     <description>Configuration Error Interrupt               Enable</description>
+                     <bitOffset>13</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CTCIE</name>
+                     <description>CLUT transfer complete interrupt               enable</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CAEIE</name>
+                     <description>CLUT access error interrupt               enable</description>
+                     <bitOffset>11</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TWIE</name>
+                     <description>Transfer watermark interrupt               enable</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TCIE</name>
+                     <description>Transfer complete interrupt               enable</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TEIE</name>
+                     <description>Transfer error interrupt               enable</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>ABORT</name>
+                     <description>Abort</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>SUSP</name>
+                     <description>Suspend</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>START</name>
+                     <description>Start</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>ISR</name>
+               <displayName>ISR</displayName>
+               <description>Interrupt Status Register</description>
+               <addressOffset>0x4</addressOffset>
+               <size>0x20</size>
+               <access>read-only</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>CEIF</name>
+                     <description>Configuration error interrupt               flag</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CTCIF</name>
+                     <description>CLUT transfer complete interrupt               flag</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CAEIF</name>
+                     <description>CLUT access error interrupt               flag</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TWIF</name>
+                     <description>Transfer watermark interrupt               flag</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TCIF</name>
+                     <description>Transfer complete interrupt               flag</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TEIF</name>
+                     <description>Transfer error interrupt               flag</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>IFCR</name>
+               <displayName>IFCR</displayName>
+               <description>interrupt flag clear register</description>
+               <addressOffset>0x8</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>CCEIF</name>
+                     <description>Clear configuration error interrupt               flag</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CCTCIF</name>
+                     <description>Clear CLUT transfer complete interrupt               flag</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CAECIF</name>
+                     <description>Clear CLUT access error interrupt               flag</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CTWIF</name>
+                     <description>Clear transfer watermark interrupt               flag</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CTCIF</name>
+                     <description>Clear transfer complete interrupt               flag</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CTEIF</name>
+                     <description>Clear Transfer error interrupt               flag</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>FGMAR</name>
+               <displayName>FGMAR</displayName>
+               <description>foreground memory address           register</description>
+               <addressOffset>0xC</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>MA</name>
+                     <description>Memory address</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>FGOR</name>
+               <displayName>FGOR</displayName>
+               <description>foreground offset register</description>
+               <addressOffset>0x10</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>LO</name>
+                     <description>Line offset</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>14</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>BGMAR</name>
+               <displayName>BGMAR</displayName>
+               <description>background memory address           register</description>
+               <addressOffset>0x14</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>MA</name>
+                     <description>Memory address</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>BGOR</name>
+               <displayName>BGOR</displayName>
+               <description>background offset register</description>
+               <addressOffset>0x18</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>LO</name>
+                     <description>Line offset</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>14</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>FGPFCCR</name>
+               <displayName>FGPFCCR</displayName>
+               <description>foreground PFC control           register</description>
+               <addressOffset>0x1C</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>ALPHA</name>
+                     <description>Alpha value</description>
+                     <bitOffset>24</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+                  <field>
+                     <name>AM</name>
+                     <description>Alpha mode</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>CS</name>
+                     <description>CLUT size</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+                  <field>
+                     <name>START</name>
+                     <description>Start</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CCM</name>
+                     <description>CLUT color mode</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CM</name>
+                     <description>Color mode</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>FGCOLR</name>
+               <displayName>FGCOLR</displayName>
+               <description>foreground color register</description>
+               <addressOffset>0x20</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>RED</name>
+                     <description>Red Value</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+                  <field>
+                     <name>GREEN</name>
+                     <description>Green Value</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+                  <field>
+                     <name>BLUE</name>
+                     <description>Blue Value</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>BGPFCCR</name>
+               <displayName>BGPFCCR</displayName>
+               <description>background PFC control           register</description>
+               <addressOffset>0x24</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>ALPHA</name>
+                     <description>Alpha value</description>
+                     <bitOffset>24</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+                  <field>
+                     <name>AM</name>
+                     <description>Alpha mode</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>CS</name>
+                     <description>CLUT size</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+                  <field>
+                     <name>START</name>
+                     <description>Start</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CCM</name>
+                     <description>CLUT Color mode</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CM</name>
+                     <description>Color mode</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>BGCOLR</name>
+               <displayName>BGCOLR</displayName>
+               <description>background color register</description>
+               <addressOffset>0x28</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>RED</name>
+                     <description>Red Value</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+                  <field>
+                     <name>GREEN</name>
+                     <description>Green Value</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+                  <field>
+                     <name>BLUE</name>
+                     <description>Blue Value</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>FGCMAR</name>
+               <displayName>FGCMAR</displayName>
+               <description>foreground CLUT memory address           register</description>
+               <addressOffset>0x2C</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>MA</name>
+                     <description>Memory Address</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>BGCMAR</name>
+               <displayName>BGCMAR</displayName>
+               <description>background CLUT memory address           register</description>
+               <addressOffset>0x30</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>MA</name>
+                     <description>Memory address</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OPFCCR</name>
+               <displayName>OPFCCR</displayName>
+               <description>output PFC control register</description>
+               <addressOffset>0x34</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>CM</name>
+                     <description>Color mode</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>3</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OCOLR</name>
+               <displayName>OCOLR</displayName>
+               <description>output color register</description>
+               <addressOffset>0x38</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>APLHA</name>
+                     <description>Alpha Channel Value</description>
+                     <bitOffset>24</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+                  <field>
+                     <name>RED</name>
+                     <description>Red Value</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+                  <field>
+                     <name>GREEN</name>
+                     <description>Green Value</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+                  <field>
+                     <name>BLUE</name>
+                     <description>Blue Value</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OMAR</name>
+               <displayName>OMAR</displayName>
+               <description>output memory address register</description>
+               <addressOffset>0x3C</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>MA</name>
+                     <description>Memory Address</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OOR</name>
+               <displayName>OOR</displayName>
+               <description>output offset register</description>
+               <addressOffset>0x40</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>LO</name>
+                     <description>Line Offset</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>14</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>NLR</name>
+               <displayName>NLR</displayName>
+               <description>number of line register</description>
+               <addressOffset>0x44</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>PL</name>
+                     <description>Pixel per lines</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>14</bitWidth>
+                  </field>
+                  <field>
+                     <name>NL</name>
+                     <description>Number of lines</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>LWR</name>
+               <displayName>LWR</displayName>
+               <description>line watermark register</description>
+               <addressOffset>0x48</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>LW</name>
+                     <description>Line watermark</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>AMTCR</name>
+               <displayName>AMTCR</displayName>
+               <description>AHB master timer configuration           register</description>
+               <addressOffset>0x4C</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DT</name>
+                     <description>Dead Time</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+                  <field>
+                     <name>EN</name>
+                     <description>Enable</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>FGCLUT</name>
+               <displayName>FGCLUT</displayName>
+               <description>FGCLUT</description>
+               <addressOffset>0x400</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>APLHA</name>
+                     <description>APLHA</description>
+                     <bitOffset>24</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+                  <field>
+                     <name>RED</name>
+                     <description>RED</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+                  <field>
+                     <name>GREEN</name>
+                     <description>GREEN</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+                  <field>
+                     <name>BLUE</name>
+                     <description>BLUE</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>BGCLUT</name>
+               <displayName>BGCLUT</displayName>
+               <description>BGCLUT</description>
+               <addressOffset>0x800</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>APLHA</name>
+                     <description>APLHA</description>
+                     <bitOffset>24</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+                  <field>
+                     <name>RED</name>
+                     <description>RED</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+                  <field>
+                     <name>GREEN</name>
+                     <description>GREEN</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+                  <field>
+                     <name>BLUE</name>
+                     <description>BLUE</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+               </fields>
+            </register>
+         </registers>
+      </peripheral>
+      <peripheral>
+         <name>QUADSPI</name>
+         <description>QuadSPI interface</description>
+         <groupName>QUADSPI</groupName>
+         <baseAddress>0xA0001000</baseAddress>
+         <addressBlock>
+            <offset>0x0</offset>
+            <size>0x1000</size>
+            <usage>registers</usage>
+         </addressBlock>
+         <interrupt>
+            <name>QuadSPI</name>
+            <description>QuadSPI global interrupt</description>
+            <value>92</value>
+         </interrupt>
+         <registers>
+            <register>
+               <name>CR</name>
+               <displayName>CR</displayName>
+               <description>control register</description>
+               <addressOffset>0x0</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>PRESCALER</name>
+                     <description>Clock prescaler</description>
+                     <bitOffset>24</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+                  <field>
+                     <name>PMM</name>
+                     <description>Polling match mode</description>
+                     <bitOffset>23</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>APMS</name>
+                     <description>Automatic poll mode stop</description>
+                     <bitOffset>22</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TOIE</name>
+                     <description>TimeOut interrupt enable</description>
+                     <bitOffset>20</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>SMIE</name>
+                     <description>Status match interrupt               enable</description>
+                     <bitOffset>19</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FTIE</name>
+                     <description>FIFO threshold interrupt               enable</description>
+                     <bitOffset>18</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TCIE</name>
+                     <description>Transfer complete interrupt               enable</description>
+                     <bitOffset>17</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TEIE</name>
+                     <description>Transfer error interrupt               enable</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FTHRES</name>
+                     <description>IFO threshold level</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>5</bitWidth>
+                  </field>
+                  <field>
+                     <name>FSEL</name>
+                     <description>FLASH memory selection</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>DFM</name>
+                     <description>Dual-flash mode</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>SSHIFT</name>
+                     <description>Sample shift</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TCEN</name>
+                     <description>Timeout counter enable</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>DMAEN</name>
+                     <description>DMA enable</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>ABORT</name>
+                     <description>Abort request</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>EN</name>
+                     <description>Enable</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DCR</name>
+               <displayName>DCR</displayName>
+               <description>device configuration register</description>
+               <addressOffset>0x4</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>FSIZE</name>
+                     <description>FLASH memory size</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>5</bitWidth>
+                  </field>
+                  <field>
+                     <name>CSHT</name>
+                     <description>Chip select high time</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>3</bitWidth>
+                  </field>
+                  <field>
+                     <name>CKMODE</name>
+                     <description>Mode 0 / mode 3</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>SR</name>
+               <displayName>SR</displayName>
+               <description>status register</description>
+               <addressOffset>0x8</addressOffset>
+               <size>0x20</size>
+               <access>read-only</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>FLEVEL</name>
+                     <description>FIFO level</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>7</bitWidth>
+                  </field>
+                  <field>
+                     <name>BUSY</name>
+                     <description>Busy</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TOF</name>
+                     <description>Timeout flag</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>SMF</name>
+                     <description>Status match flag</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FTF</name>
+                     <description>FIFO threshold flag</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TCF</name>
+                     <description>Transfer complete flag</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TEF</name>
+                     <description>Transfer error flag</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>FCR</name>
+               <displayName>FCR</displayName>
+               <description>flag clear register</description>
+               <addressOffset>0xC</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>CTOF</name>
+                     <description>Clear timeout flag</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CSMF</name>
+                     <description>Clear status match flag</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CTCF</name>
+                     <description>Clear transfer complete               flag</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CTEF</name>
+                     <description>Clear transfer error flag</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DLR</name>
+               <displayName>DLR</displayName>
+               <description>data length register</description>
+               <addressOffset>0x10</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DL</name>
+                     <description>Data length</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>CCR</name>
+               <displayName>CCR</displayName>
+               <description>communication configuration           register</description>
+               <addressOffset>0x14</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DDRM</name>
+                     <description>Double data rate mode</description>
+                     <bitOffset>31</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>DHHC</name>
+                     <description>DDR hold half cycle</description>
+                     <bitOffset>30</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>SIOO</name>
+                     <description>Send instruction only once               mode</description>
+                     <bitOffset>28</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FMODE</name>
+                     <description>Functional mode</description>
+                     <bitOffset>26</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>DMODE</name>
+                     <description>Data mode</description>
+                     <bitOffset>24</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>DCYC</name>
+                     <description>Number of dummy cycles</description>
+                     <bitOffset>18</bitOffset>
+                     <bitWidth>5</bitWidth>
+                  </field>
+                  <field>
+                     <name>ABSIZE</name>
+                     <description>Alternate bytes size</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>ABMODE</name>
+                     <description>Alternate bytes mode</description>
+                     <bitOffset>14</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>ADSIZE</name>
+                     <description>Address size</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>ADMODE</name>
+                     <description>Address mode</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>IMODE</name>
+                     <description>Instruction mode</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>INSTRUCTION</name>
+                     <description>Instruction</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>AR</name>
+               <displayName>AR</displayName>
+               <description>address register</description>
+               <addressOffset>0x18</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>ADDRESS</name>
+                     <description>Address</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>ABR</name>
+               <displayName>ABR</displayName>
+               <description>ABR</description>
+               <addressOffset>0x1C</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>ALTERNATE</name>
+                     <description>ALTERNATE</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DR</name>
+               <displayName>DR</displayName>
+               <description>data register</description>
+               <addressOffset>0x20</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DATA</name>
+                     <description>Data</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>PSMKR</name>
+               <displayName>PSMKR</displayName>
+               <description>polling status mask register</description>
+               <addressOffset>0x24</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>MASK</name>
+                     <description>Status mask</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>PSMAR</name>
+               <displayName>PSMAR</displayName>
+               <description>polling status match register</description>
+               <addressOffset>0x28</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>MATCH</name>
+                     <description>Status match</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>PIR</name>
+               <displayName>PIR</displayName>
+               <description>polling interval register</description>
+               <addressOffset>0x2C</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>INTERVAL</name>
+                     <description>Polling interval</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>LPTR</name>
+               <displayName>LPTR</displayName>
+               <description>low-power timeout register</description>
+               <addressOffset>0x30</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>TIMEOUT</name>
+                     <description>Timeout period</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+               </fields>
+            </register>
+         </registers>
+      </peripheral>
+      <peripheral>
+         <name>CEC</name>
+         <description>HDMI-CEC controller</description>
+         <groupName>CEC</groupName>
+         <baseAddress>0x40006C00</baseAddress>
+         <addressBlock>
+            <offset>0x0</offset>
+            <size>0x400</size>
+            <usage>registers</usage>
+         </addressBlock>
+         <registers>
+            <register>
+               <name>CR</name>
+               <displayName>CR</displayName>
+               <description>control register</description>
+               <addressOffset>0x0</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>TXEOM</name>
+                     <description>Tx End Of Message</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TXSOM</name>
+                     <description>Tx start of message</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CECEN</name>
+                     <description>CEC Enable</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>CFGR</name>
+               <displayName>CFGR</displayName>
+               <description>configuration register</description>
+               <addressOffset>0x4</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>SFT</name>
+                     <description>Signal Free Time</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>3</bitWidth>
+                  </field>
+                  <field>
+                     <name>RXTOL</name>
+                     <description>Rx-Tolerance</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>BRESTP</name>
+                     <description>Rx-stop on bit rising               error</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>BREGEN</name>
+                     <description>Generate error-bit on bit rising               error</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>LBPEGEN</name>
+                     <description>Generate Error-Bit on Long Bit Period               Error</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>BRDNOGEN</name>
+                     <description>Avoid Error-Bit Generation in               Broadcast</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>SFTOP</name>
+                     <description>SFT Option Bit</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>OAR</name>
+                     <description>Own addresses               configuration</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>15</bitWidth>
+                  </field>
+                  <field>
+                     <name>LSTN</name>
+                     <description>Listen mode</description>
+                     <bitOffset>31</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>TXDR</name>
+               <displayName>TXDR</displayName>
+               <description>Tx data register</description>
+               <addressOffset>0x8</addressOffset>
+               <size>0x20</size>
+               <access>write-only</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>TXD</name>
+                     <description>Tx Data register</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>RXDR</name>
+               <displayName>RXDR</displayName>
+               <description>Rx Data Register</description>
+               <addressOffset>0xC</addressOffset>
+               <size>0x20</size>
+               <access>read-only</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>RXDR</name>
+                     <description>CEC Rx Data Register</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>ISR</name>
+               <displayName>ISR</displayName>
+               <description>Interrupt and Status Register</description>
+               <addressOffset>0x10</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>TXACKE</name>
+                     <description>Tx-Missing acknowledge               error</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TXERR</name>
+                     <description>Tx-Error</description>
+                     <bitOffset>11</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TXUDR</name>
+                     <description>Tx-Buffer Underrun</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TXEND</name>
+                     <description>End of Transmission</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TXBR</name>
+                     <description>Tx-Byte Request</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>ARBLST</name>
+                     <description>Arbitration Lost</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>RXACKE</name>
+                     <description>Rx-Missing Acknowledge</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>LBPE</name>
+                     <description>Rx-Long Bit Period Error</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>SBPE</name>
+                     <description>Rx-Short Bit period error</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>BRE</name>
+                     <description>Rx-Bit rising error</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>RXOVR</name>
+                     <description>Rx-Overrun</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>RXEND</name>
+                     <description>End Of Reception</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>RXBR</name>
+                     <description>Rx-Byte Received</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>IER</name>
+               <displayName>IER</displayName>
+               <description>interrupt enable register</description>
+               <addressOffset>0x14</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>TXACKIE</name>
+                     <description>Tx-Missing Acknowledge Error Interrupt               Enable</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TXERRIE</name>
+                     <description>Tx-Error Interrupt Enable</description>
+                     <bitOffset>11</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TXUDRIE</name>
+                     <description>Tx-Underrun interrupt               enable</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TXENDIE</name>
+                     <description>Tx-End of message interrupt               enable</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TXBRIE</name>
+                     <description>Tx-Byte Request Interrupt               Enable</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>ARBLSTIE</name>
+                     <description>Arbitration Lost Interrupt               Enable</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>RXACKIE</name>
+                     <description>Rx-Missing Acknowledge Error Interrupt               Enable</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>LBPEIE</name>
+                     <description>Long Bit Period Error Interrupt               Enable</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>SBPEIE</name>
+                     <description>Short Bit Period Error Interrupt               Enable</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>BREIE</name>
+                     <description>Bit Rising Error Interrupt               Enable</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>RXOVRIE</name>
+                     <description>Rx-Buffer Overrun Interrupt               Enable</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>RXENDIE</name>
+                     <description>End Of Reception Interrupt               Enable</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>RXBRIE</name>
+                     <description>Rx-Byte Received Interrupt               Enable</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+         </registers>
+      </peripheral>
+      <peripheral>
+         <name>SPDIFRX</name>
+         <description>Receiver Interface</description>
+         <groupName>SPDIF_RX</groupName>
+         <baseAddress>0x40004000</baseAddress>
+         <addressBlock>
+            <offset>0x0</offset>
+            <size>0x400</size>
+            <usage>registers</usage>
+         </addressBlock>
+         <interrupt>
+            <name>SPDIFRX</name>
+            <description>SPDIFRX global interrupt</description>
+            <value>97</value>
+         </interrupt>
+         <registers>
+            <register>
+               <name>CR</name>
+               <displayName>CR</displayName>
+               <description>Control register</description>
+               <addressOffset>0x0</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>SPDIFEN</name>
+                     <description>Peripheral Block Enable</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>RXDMAEN</name>
+                     <description>Receiver DMA ENable for data               flow</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>RXSTEO</name>
+                     <description>STerEO Mode</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>DRFMT</name>
+                     <description>RX Data format</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>PMSK</name>
+                     <description>Mask Parity error bit</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>VMSK</name>
+                     <description>Mask of Validity bit</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CUMSK</name>
+                     <description>Mask of channel status and user               bits</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>PTMSK</name>
+                     <description>Mask of Preamble Type bits</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CBDMAEN</name>
+                     <description>Control Buffer DMA ENable for control               flow</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CHSEL</name>
+                     <description>Channel Selection</description>
+                     <bitOffset>11</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>NBTR</name>
+                     <description>Maximum allowed re-tries during               synchronization phase</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>WFA</name>
+                     <description>Wait For Activity</description>
+                     <bitOffset>14</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>INSEL</name>
+                     <description>input selection</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>3</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>IMR</name>
+               <displayName>IMR</displayName>
+               <description>Interrupt mask register</description>
+               <addressOffset>0x4</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>RXNEIE</name>
+                     <description>RXNE interrupt enable</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CSRNEIE</name>
+                     <description>Control Buffer Ready Interrupt               Enable</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>PERRIE</name>
+                     <description>Parity error interrupt               enable</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>OVRIE</name>
+                     <description>Overrun error Interrupt               Enable</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>SBLKIE</name>
+                     <description>Synchronization Block Detected Interrupt               Enable</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>SYNCDIE</name>
+                     <description>Synchronization Done</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>IFEIE</name>
+                     <description>Serial Interface Error Interrupt               Enable</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>SR</name>
+               <displayName>SR</displayName>
+               <description>Status register</description>
+               <addressOffset>0x8</addressOffset>
+               <size>0x20</size>
+               <access>read-only</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>RXNE</name>
+                     <description>Read data register not               empty</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CSRNE</name>
+                     <description>Control Buffer register is not               empty</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>PERR</name>
+                     <description>Parity error</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>OVR</name>
+                     <description>Overrun error</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>SBD</name>
+                     <description>Synchronization Block               Detected</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>SYNCD</name>
+                     <description>Synchronization Done</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FERR</name>
+                     <description>Framing error</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>SERR</name>
+                     <description>Synchronization error</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TERR</name>
+                     <description>Time-out error</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>WIDTH5</name>
+                     <description>Duration of 5 symbols counted with               SPDIF_CLK</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>15</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>IFCR</name>
+               <displayName>IFCR</displayName>
+               <description>Interrupt Flag Clear register</description>
+               <addressOffset>0xC</addressOffset>
+               <size>0x20</size>
+               <access>write-only</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>PERRCF</name>
+                     <description>Clears the Parity error               flag</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>OVRCF</name>
+                     <description>Clears the Overrun error               flag</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>SBDCF</name>
+                     <description>Clears the Synchronization Block               Detected flag</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>SYNCDCF</name>
+                     <description>Clears the Synchronization Done               flag</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DR</name>
+               <displayName>DR</displayName>
+               <description>Data input register</description>
+               <addressOffset>0x10</addressOffset>
+               <size>0x20</size>
+               <access>read-only</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DR</name>
+                     <description>Parity Error bit</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>24</bitWidth>
+                  </field>
+                  <field>
+                     <name>PE</name>
+                     <description>Parity Error bit</description>
+                     <bitOffset>24</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>V</name>
+                     <description>Validity bit</description>
+                     <bitOffset>25</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>U</name>
+                     <description>User bit</description>
+                     <bitOffset>26</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>C</name>
+                     <description>Channel Status bit</description>
+                     <bitOffset>27</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>PT</name>
+                     <description>Preamble Type</description>
+                     <bitOffset>28</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>CSR</name>
+               <displayName>CSR</displayName>
+               <description>Channel Status register</description>
+               <addressOffset>0x14</addressOffset>
+               <size>0x20</size>
+               <access>read-only</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>USR</name>
+                     <description>User data information</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+                  <field>
+                     <name>CS</name>
+                     <description>Channel A status               information</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+                  <field>
+                     <name>SOB</name>
+                     <description>Start Of Block</description>
+                     <bitOffset>24</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DIR</name>
+               <displayName>DIR</displayName>
+               <description>Debug Information register</description>
+               <addressOffset>0x18</addressOffset>
+               <size>0x20</size>
+               <access>read-only</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>THI</name>
+                     <description>Threshold HIGH</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>13</bitWidth>
+                  </field>
+                  <field>
+                     <name>TLO</name>
+                     <description>Threshold LOW</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>13</bitWidth>
+                  </field>
+               </fields>
+            </register>
+         </registers>
+      </peripheral>
+      <peripheral>
+         <name>SDMMC1</name>
+         <description>Secure digital input/output       interface</description>
+         <groupName>SDMMC</groupName>
+         <baseAddress>0x40012C00</baseAddress>
+         <addressBlock>
+            <offset>0x0</offset>
+            <size>0x400</size>
+            <usage>registers</usage>
+         </addressBlock>
+         <interrupt>
+            <name>SDMMC1</name>
+            <description>SDMMC1 global interrupt</description>
+            <value>49</value>
+         </interrupt>
+         <registers>
+            <register>
+               <name>POWER</name>
+               <displayName>POWER</displayName>
+               <description>power control register</description>
+               <addressOffset>0x0</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>PWRCTRL</name>
+                     <description>PWRCTRL</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>CLKCR</name>
+               <displayName>CLKCR</displayName>
+               <description>SDI clock control register</description>
+               <addressOffset>0x4</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>HWFC_EN</name>
+                     <description>HW Flow Control enable</description>
+                     <bitOffset>14</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>NEGEDGE</name>
+                     <description>SDIO_CK dephasing selection               bit</description>
+                     <bitOffset>13</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>WIDBUS</name>
+                     <description>Wide bus mode enable bit</description>
+                     <bitOffset>11</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>BYPASS</name>
+                     <description>Clock divider bypass enable               bit</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>PWRSAV</name>
+                     <description>Power saving configuration               bit</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CLKEN</name>
+                     <description>Clock enable bit</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CLKDIV</name>
+                     <description>Clock divide factor</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>ARG</name>
+               <displayName>ARG</displayName>
+               <description>argument register</description>
+               <addressOffset>0x8</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>CMDARG</name>
+                     <description>Command argument</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>CMD</name>
+               <displayName>CMD</displayName>
+               <description>command register</description>
+               <addressOffset>0xC</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>CE_ATACMD</name>
+                     <description>CE-ATA command</description>
+                     <bitOffset>14</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>nIEN</name>
+                     <description>not Interrupt Enable</description>
+                     <bitOffset>13</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>ENCMDcompl</name>
+                     <description>Enable CMD completion</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>SDIOSuspend</name>
+                     <description>SD I/O suspend command</description>
+                     <bitOffset>11</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CPSMEN</name>
+                     <description>Command path state machine (CPSM) Enable               bit</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>WAITPEND</name>
+                     <description>CPSM Waits for ends of data transfer               (CmdPend internal signal)</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>WAITINT</name>
+                     <description>CPSM waits for interrupt               request</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>WAITRESP</name>
+                     <description>Wait for response bits</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>CMDINDEX</name>
+                     <description>Command index</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>6</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>RESPCMD</name>
+               <displayName>RESPCMD</displayName>
+               <description>command response register</description>
+               <addressOffset>0x10</addressOffset>
+               <size>0x20</size>
+               <access>read-only</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>RESPCMD</name>
+                     <description>Response command index</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>6</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>RESP1</name>
+               <displayName>RESP1</displayName>
+               <description>response 1..4 register</description>
+               <addressOffset>0x14</addressOffset>
+               <size>0x20</size>
+               <access>read-only</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>CARDSTATUS1</name>
+                     <description>see Table 132</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>RESP2</name>
+               <displayName>RESP2</displayName>
+               <description>response 1..4 register</description>
+               <addressOffset>0x18</addressOffset>
+               <size>0x20</size>
+               <access>read-only</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>CARDSTATUS2</name>
+                     <description>see Table 132</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>RESP3</name>
+               <displayName>RESP3</displayName>
+               <description>response 1..4 register</description>
+               <addressOffset>0x1C</addressOffset>
+               <size>0x20</size>
+               <access>read-only</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>CARDSTATUS3</name>
+                     <description>see Table 132</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>RESP4</name>
+               <displayName>RESP4</displayName>
+               <description>response 1..4 register</description>
+               <addressOffset>0x20</addressOffset>
+               <size>0x20</size>
+               <access>read-only</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>CARDSTATUS4</name>
+                     <description>see Table 132</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DTIMER</name>
+               <displayName>DTIMER</displayName>
+               <description>data timer register</description>
+               <addressOffset>0x24</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DATATIME</name>
+                     <description>Data timeout period</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DLEN</name>
+               <displayName>DLEN</displayName>
+               <description>data length register</description>
+               <addressOffset>0x28</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DATALENGTH</name>
+                     <description>Data length value</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>25</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DCTRL</name>
+               <displayName>DCTRL</displayName>
+               <description>data control register</description>
+               <addressOffset>0x2C</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>SDIOEN</name>
+                     <description>SD I/O enable functions</description>
+                     <bitOffset>11</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>RWMOD</name>
+                     <description>Read wait mode</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>RWSTOP</name>
+                     <description>Read wait stop</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>RWSTART</name>
+                     <description>Read wait start</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>DBLOCKSIZE</name>
+                     <description>Data block size</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+                  <field>
+                     <name>DMAEN</name>
+                     <description>DMA enable bit</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>DTMODE</name>
+                     <description>Data transfer mode selection 1: Stream               or SDIO multibyte data transfer</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>DTDIR</name>
+                     <description>Data transfer direction               selection</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>DTEN</name>
+                     <description>DTEN</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DCOUNT</name>
+               <displayName>DCOUNT</displayName>
+               <description>data counter register</description>
+               <addressOffset>0x30</addressOffset>
+               <size>0x20</size>
+               <access>read-only</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DATACOUNT</name>
+                     <description>Data count value</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>25</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>STA</name>
+               <displayName>STA</displayName>
+               <description>status register</description>
+               <addressOffset>0x34</addressOffset>
+               <size>0x20</size>
+               <access>read-only</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>CEATAEND</name>
+                     <description>CE-ATA command completion signal               received for CMD61</description>
+                     <bitOffset>23</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>SDIOIT</name>
+                     <description>SDIO interrupt received</description>
+                     <bitOffset>22</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>RXDAVL</name>
+                     <description>Data available in receive               FIFO</description>
+                     <bitOffset>21</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TXDAVL</name>
+                     <description>Data available in transmit               FIFO</description>
+                     <bitOffset>20</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>RXFIFOE</name>
+                     <description>Receive FIFO empty</description>
+                     <bitOffset>19</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TXFIFOE</name>
+                     <description>Transmit FIFO empty</description>
+                     <bitOffset>18</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>RXFIFOF</name>
+                     <description>Receive FIFO full</description>
+                     <bitOffset>17</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TXFIFOF</name>
+                     <description>Transmit FIFO full</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>RXFIFOHF</name>
+                     <description>Receive FIFO half full: there are at               least 8 words in the FIFO</description>
+                     <bitOffset>15</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TXFIFOHE</name>
+                     <description>Transmit FIFO half empty: at least 8               words can be written into the FIFO</description>
+                     <bitOffset>14</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>RXACT</name>
+                     <description>Data receive in progress</description>
+                     <bitOffset>13</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TXACT</name>
+                     <description>Data transmit in progress</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CMDACT</name>
+                     <description>Command transfer in               progress</description>
+                     <bitOffset>11</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>DBCKEND</name>
+                     <description>Data block sent/received (CRC check               passed)</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>STBITERR</name>
+                     <description>Start bit not detected on all data               signals in wide bus mode</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>DATAEND</name>
+                     <description>Data end (data counter, SDIDCOUNT, is               zero)</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CMDSENT</name>
+                     <description>Command sent (no response               required)</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CMDREND</name>
+                     <description>Command response received (CRC check               passed)</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>RXOVERR</name>
+                     <description>Received FIFO overrun               error</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TXUNDERR</name>
+                     <description>Transmit FIFO underrun               error</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>DTIMEOUT</name>
+                     <description>Data timeout</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CTIMEOUT</name>
+                     <description>Command response timeout</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>DCRCFAIL</name>
+                     <description>Data block sent/received (CRC check               failed)</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CCRCFAIL</name>
+                     <description>Command response received (CRC check               failed)</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>ICR</name>
+               <displayName>ICR</displayName>
+               <description>interrupt clear register</description>
+               <addressOffset>0x38</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>CEATAENDC</name>
+                     <description>CEATAEND flag clear bit</description>
+                     <bitOffset>23</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>SDIOITC</name>
+                     <description>SDIOIT flag clear bit</description>
+                     <bitOffset>22</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>DBCKENDC</name>
+                     <description>DBCKEND flag clear bit</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>STBITERRC</name>
+                     <description>STBITERR flag clear bit</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>DATAENDC</name>
+                     <description>DATAEND flag clear bit</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CMDSENTC</name>
+                     <description>CMDSENT flag clear bit</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CMDRENDC</name>
+                     <description>CMDREND flag clear bit</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>RXOVERRC</name>
+                     <description>RXOVERR flag clear bit</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TXUNDERRC</name>
+                     <description>TXUNDERR flag clear bit</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>DTIMEOUTC</name>
+                     <description>DTIMEOUT flag clear bit</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CTIMEOUTC</name>
+                     <description>CTIMEOUT flag clear bit</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>DCRCFAILC</name>
+                     <description>DCRCFAIL flag clear bit</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CCRCFAILC</name>
+                     <description>CCRCFAIL flag clear bit</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>MASK</name>
+               <displayName>MASK</displayName>
+               <description>mask register</description>
+               <addressOffset>0x3C</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>CEATAENDIE</name>
+                     <description>CE-ATA command completion signal               received interrupt enable</description>
+                     <bitOffset>23</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>SDIOITIE</name>
+                     <description>SDIO mode interrupt received interrupt               enable</description>
+                     <bitOffset>22</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>RXDAVLIE</name>
+                     <description>Data available in Rx FIFO interrupt               enable</description>
+                     <bitOffset>21</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TXDAVLIE</name>
+                     <description>Data available in Tx FIFO interrupt               enable</description>
+                     <bitOffset>20</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>RXFIFOEIE</name>
+                     <description>Rx FIFO empty interrupt               enable</description>
+                     <bitOffset>19</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TXFIFOEIE</name>
+                     <description>Tx FIFO empty interrupt               enable</description>
+                     <bitOffset>18</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>RXFIFOFIE</name>
+                     <description>Rx FIFO full interrupt               enable</description>
+                     <bitOffset>17</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TXFIFOFIE</name>
+                     <description>Tx FIFO full interrupt               enable</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>RXFIFOHFIE</name>
+                     <description>Rx FIFO half full interrupt               enable</description>
+                     <bitOffset>15</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TXFIFOHEIE</name>
+                     <description>Tx FIFO half empty interrupt               enable</description>
+                     <bitOffset>14</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>RXACTIE</name>
+                     <description>Data receive acting interrupt               enable</description>
+                     <bitOffset>13</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TXACTIE</name>
+                     <description>Data transmit acting interrupt               enable</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CMDACTIE</name>
+                     <description>Command acting interrupt               enable</description>
+                     <bitOffset>11</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>DBCKENDIE</name>
+                     <description>Data block end interrupt               enable</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>STBITERRIE</name>
+                     <description>Start bit error interrupt               enable</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>DATAENDIE</name>
+                     <description>Data end interrupt enable</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CMDSENTIE</name>
+                     <description>Command sent interrupt               enable</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CMDRENDIE</name>
+                     <description>Command response received interrupt               enable</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>RXOVERRIE</name>
+                     <description>Rx FIFO overrun error interrupt               enable</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TXUNDERRIE</name>
+                     <description>Tx FIFO underrun error interrupt               enable</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>DTIMEOUTIE</name>
+                     <description>Data timeout interrupt               enable</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CTIMEOUTIE</name>
+                     <description>Command timeout interrupt               enable</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>DCRCFAILIE</name>
+                     <description>Data CRC fail interrupt               enable</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CCRCFAILIE</name>
+                     <description>Command CRC fail interrupt               enable</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>FIFOCNT</name>
+               <displayName>FIFOCNT</displayName>
+               <description>FIFO counter register</description>
+               <addressOffset>0x48</addressOffset>
+               <size>0x20</size>
+               <access>read-only</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>FIFOCOUNT</name>
+                     <description>Remaining number of words to be written               to or read from the FIFO</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>24</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>FIFO</name>
+               <displayName>FIFO</displayName>
+               <description>data FIFO register</description>
+               <addressOffset>0x80</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>FIFOData</name>
+                     <description>Receive and transmit FIFO               data</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+         </registers>
+      </peripheral>
+      <peripheral derivedFrom="SDMMC1">
+         <name>SDMMC2</name>
+         <baseAddress>0x40011C00</baseAddress>
+         <interrupt>
+            <name>SDMMC2</name>
+            <description>SDMMC2 global interrupt</description>
+            <value>103</value>
+         </interrupt>
+      </peripheral>
+      <peripheral>
+         <name>LPTIM1</name>
+         <description>Low power timer</description>
+         <groupName>LPTIM</groupName>
+         <baseAddress>0x40002400</baseAddress>
+         <addressBlock>
+            <offset>0x0</offset>
+            <size>0x400</size>
+            <usage>registers</usage>
+         </addressBlock>
+         <interrupt>
+            <name>LP_Timer1</name>
+            <description>LP Timer1 global interrupt</description>
+            <value>93</value>
+         </interrupt>
+         <registers>
+            <register>
+               <name>ISR</name>
+               <displayName>ISR</displayName>
+               <description>Interrupt and Status Register</description>
+               <addressOffset>0x0</addressOffset>
+               <size>0x20</size>
+               <access>read-only</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DOWN</name>
+                     <description>Counter direction change up to               down</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>UP</name>
+                     <description>Counter direction change down to               up</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>ARROK</name>
+                     <description>Autoreload register update               OK</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CMPOK</name>
+                     <description>Compare register update OK</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>EXTTRIG</name>
+                     <description>External trigger edge               event</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>ARRM</name>
+                     <description>Autoreload match</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CMPM</name>
+                     <description>Compare match</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>ICR</name>
+               <displayName>ICR</displayName>
+               <description>Interrupt Clear Register</description>
+               <addressOffset>0x4</addressOffset>
+               <size>0x20</size>
+               <access>write-only</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DOWNCF</name>
+                     <description>Direction change to down Clear               Flag</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>UPCF</name>
+                     <description>Direction change to UP Clear               Flag</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>ARROKCF</name>
+                     <description>Autoreload register update OK Clear               Flag</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CMPOKCF</name>
+                     <description>Compare register update OK Clear               Flag</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>EXTTRIGCF</name>
+                     <description>External trigger valid edge Clear               Flag</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>ARRMCF</name>
+                     <description>Autoreload match Clear               Flag</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CMPMCF</name>
+                     <description>compare match Clear Flag</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>IER</name>
+               <displayName>IER</displayName>
+               <description>Interrupt Enable Register</description>
+               <addressOffset>0x8</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DOWNIE</name>
+                     <description>Direction change to down Interrupt               Enable</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>UPIE</name>
+                     <description>Direction change to UP Interrupt               Enable</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>ARROKIE</name>
+                     <description>Autoreload register update OK Interrupt               Enable</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CMPOKIE</name>
+                     <description>Compare register update OK Interrupt               Enable</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>EXTTRIGIE</name>
+                     <description>External trigger valid edge Interrupt               Enable</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>ARRMIE</name>
+                     <description>Autoreload match Interrupt               Enable</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CMPMIE</name>
+                     <description>Compare match Interrupt               Enable</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>CFGR</name>
+               <displayName>CFGR</displayName>
+               <description>Configuration Register</description>
+               <addressOffset>0xC</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>ENC</name>
+                     <description>Encoder mode enable</description>
+                     <bitOffset>24</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>COUNTMODE</name>
+                     <description>counter mode enabled</description>
+                     <bitOffset>23</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>PRELOAD</name>
+                     <description>Registers update mode</description>
+                     <bitOffset>22</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>WAVPOL</name>
+                     <description>Waveform shape polarity</description>
+                     <bitOffset>21</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>WAVE</name>
+                     <description>Waveform shape</description>
+                     <bitOffset>20</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TIMOUT</name>
+                     <description>Timeout enable</description>
+                     <bitOffset>19</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TRIGEN</name>
+                     <description>Trigger enable and               polarity</description>
+                     <bitOffset>17</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>TRIGSEL</name>
+                     <description>Trigger selector</description>
+                     <bitOffset>13</bitOffset>
+                     <bitWidth>3</bitWidth>
+                  </field>
+                  <field>
+                     <name>PRESC</name>
+                     <description>Clock prescaler</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>3</bitWidth>
+                  </field>
+                  <field>
+                     <name>TRGFLT</name>
+                     <description>Configurable digital filter for               trigger</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>CKFLT</name>
+                     <description>Configurable digital filter for external               clock</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>CKPOL</name>
+                     <description>Clock Polarity</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>CKSEL</name>
+                     <description>Clock selector</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>CR</name>
+               <displayName>CR</displayName>
+               <description>Control Register</description>
+               <addressOffset>0x10</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>CNTSTRT</name>
+                     <description>Timer start in continuous               mode</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>SNGSTRT</name>
+                     <description>LPTIM start in single mode</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>ENABLE</name>
+                     <description>LPTIM Enable</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>CMP</name>
+               <displayName>CMP</displayName>
+               <description>Compare Register</description>
+               <addressOffset>0x14</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>CMP</name>
+                     <description>Compare value</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>ARR</name>
+               <displayName>ARR</displayName>
+               <description>Autoreload Register</description>
+               <addressOffset>0x18</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000001</resetValue>
+               <fields>
+                  <field>
+                     <name>ARR</name>
+                     <description>Auto reload value</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>CNT</name>
+               <displayName>CNT</displayName>
+               <description>Counter Register</description>
+               <addressOffset>0x1C</addressOffset>
+               <size>0x20</size>
+               <access>read-only</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>CNT</name>
+                     <description>Counter value</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+               </fields>
+            </register>
+         </registers>
+      </peripheral>
+      <peripheral>
+         <name>I2C1</name>
+         <description>Inter-integrated circuit</description>
+         <groupName>I2C</groupName>
+         <baseAddress>0x40005400</baseAddress>
+         <addressBlock>
+            <offset>0x0</offset>
+            <size>0x400</size>
+            <usage>registers</usage>
+         </addressBlock>
+         <interrupt>
+            <name>I2C1_EV</name>
+            <description>I2C1 event interrupt</description>
+            <value>31</value>
+         </interrupt>
+         <interrupt>
+            <name>I2C1_ER</name>
+            <description>I2C1 error interrupt</description>
+            <value>32</value>
+         </interrupt>
+         <registers>
+            <register>
+               <name>CR1</name>
+               <displayName>CR1</displayName>
+               <description>Control register 1</description>
+               <addressOffset>0x0</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>PE</name>
+                     <description>Peripheral enable</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TXIE</name>
+                     <description>TX Interrupt enable</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>RXIE</name>
+                     <description>RX Interrupt enable</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>ADDRIE</name>
+                     <description>Address match interrupt enable (slave               only)</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>NACKIE</name>
+                     <description>Not acknowledge received interrupt               enable</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>STOPIE</name>
+                     <description>STOP detection Interrupt               enable</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TCIE</name>
+                     <description>Transfer Complete interrupt               enable</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>ERRIE</name>
+                     <description>Error interrupts enable</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>DNF</name>
+                     <description>Digital noise filter</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+                  <field>
+                     <name>ANFOFF</name>
+                     <description>Analog noise filter OFF</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TXDMAEN</name>
+                     <description>DMA transmission requests               enable</description>
+                     <bitOffset>14</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>RXDMAEN</name>
+                     <description>DMA reception requests               enable</description>
+                     <bitOffset>15</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>SBC</name>
+                     <description>Slave byte control</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>NOSTRETCH</name>
+                     <description>Clock stretching disable</description>
+                     <bitOffset>17</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>WUPEN</name>
+                     <description>Wakeup from STOP enable</description>
+                     <bitOffset>18</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>GCEN</name>
+                     <description>General call enable</description>
+                     <bitOffset>19</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>SMBHEN</name>
+                     <description>SMBus Host address enable</description>
+                     <bitOffset>20</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>SMBDEN</name>
+                     <description>SMBus Device Default address               enable</description>
+                     <bitOffset>21</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>ALERTEN</name>
+                     <description>SMBUS alert enable</description>
+                     <bitOffset>22</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>PECEN</name>
+                     <description>PEC enable</description>
+                     <bitOffset>23</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>CR2</name>
+               <displayName>CR2</displayName>
+               <description>Control register 2</description>
+               <addressOffset>0x4</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>PECBYTE</name>
+                     <description>Packet error checking byte</description>
+                     <bitOffset>26</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>AUTOEND</name>
+                     <description>Automatic end mode (master               mode)</description>
+                     <bitOffset>25</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>RELOAD</name>
+                     <description>NBYTES reload mode</description>
+                     <bitOffset>24</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>NBYTES</name>
+                     <description>Number of bytes</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+                  <field>
+                     <name>NACK</name>
+                     <description>NACK generation (slave               mode)</description>
+                     <bitOffset>15</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>STOP</name>
+                     <description>Stop generation (master               mode)</description>
+                     <bitOffset>14</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>START</name>
+                     <description>Start generation</description>
+                     <bitOffset>13</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>HEAD10R</name>
+                     <description>10-bit address header only read               direction (master receiver mode)</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>ADD10</name>
+                     <description>10-bit addressing mode (master               mode)</description>
+                     <bitOffset>11</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>RD_WRN</name>
+                     <description>Transfer direction (master               mode)</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>SADD</name>
+                     <description>Slave address bit (master               mode)</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>10</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OAR1</name>
+               <displayName>OAR1</displayName>
+               <description>Own address register 1</description>
+               <addressOffset>0x8</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>OA1</name>
+                     <description>Interface address</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>10</bitWidth>
+                  </field>
+                  <field>
+                     <name>OA1MODE</name>
+                     <description>Own Address 1 10-bit mode</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>OA1EN</name>
+                     <description>Own Address 1 enable</description>
+                     <bitOffset>15</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OAR2</name>
+               <displayName>OAR2</displayName>
+               <description>Own address register 2</description>
+               <addressOffset>0xC</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>OA2</name>
+                     <description>Interface address</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>7</bitWidth>
+                  </field>
+                  <field>
+                     <name>OA2MSK</name>
+                     <description>Own Address 2 masks</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>3</bitWidth>
+                  </field>
+                  <field>
+                     <name>OA2EN</name>
+                     <description>Own Address 2 enable</description>
+                     <bitOffset>15</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>TIMINGR</name>
+               <displayName>TIMINGR</displayName>
+               <description>Timing register</description>
+               <addressOffset>0x10</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>SCLL</name>
+                     <description>SCL low period (master               mode)</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+                  <field>
+                     <name>SCLH</name>
+                     <description>SCL high period (master               mode)</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+                  <field>
+                     <name>SDADEL</name>
+                     <description>Data hold time</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+                  <field>
+                     <name>SCLDEL</name>
+                     <description>Data setup time</description>
+                     <bitOffset>20</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+                  <field>
+                     <name>PRESC</name>
+                     <description>Timing prescaler</description>
+                     <bitOffset>28</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>TIMEOUTR</name>
+               <displayName>TIMEOUTR</displayName>
+               <description>Status register 1</description>
+               <addressOffset>0x14</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>TIMEOUTA</name>
+                     <description>Bus timeout A</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>12</bitWidth>
+                  </field>
+                  <field>
+                     <name>TIDLE</name>
+                     <description>Idle clock timeout               detection</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TIMOUTEN</name>
+                     <description>Clock timeout enable</description>
+                     <bitOffset>15</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TIMEOUTB</name>
+                     <description>Bus timeout B</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>12</bitWidth>
+                  </field>
+                  <field>
+                     <name>TEXTEN</name>
+                     <description>Extended clock timeout               enable</description>
+                     <bitOffset>31</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>ISR</name>
+               <displayName>ISR</displayName>
+               <description>Interrupt and Status register</description>
+               <addressOffset>0x18</addressOffset>
+               <size>0x20</size>
+               <resetValue>0x00000001</resetValue>
+               <fields>
+                  <field>
+                     <name>ADDCODE</name>
+                     <description>Address match code (Slave               mode)</description>
+                     <bitOffset>17</bitOffset>
+                     <bitWidth>7</bitWidth>
+                     <access>read-only</access>
+                  </field>
+                  <field>
+                     <name>DIR</name>
+                     <description>Transfer direction (Slave               mode)</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-only</access>
+                  </field>
+                  <field>
+                     <name>BUSY</name>
+                     <description>Bus busy</description>
+                     <bitOffset>15</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-only</access>
+                  </field>
+                  <field>
+                     <name>ALERT</name>
+                     <description>SMBus alert</description>
+                     <bitOffset>13</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-only</access>
+                  </field>
+                  <field>
+                     <name>TIMEOUT</name>
+                     <description>Timeout or t_low detection               flag</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-only</access>
+                  </field>
+                  <field>
+                     <name>PECERR</name>
+                     <description>PEC Error in reception</description>
+                     <bitOffset>11</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-only</access>
+                  </field>
+                  <field>
+                     <name>OVR</name>
+                     <description>Overrun/Underrun (slave               mode)</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-only</access>
+                  </field>
+                  <field>
+                     <name>ARLO</name>
+                     <description>Arbitration lost</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-only</access>
+                  </field>
+                  <field>
+                     <name>BERR</name>
+                     <description>Bus error</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-only</access>
+                  </field>
+                  <field>
+                     <name>TCR</name>
+                     <description>Transfer Complete Reload</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-only</access>
+                  </field>
+                  <field>
+                     <name>TC</name>
+                     <description>Transfer Complete (master               mode)</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-only</access>
+                  </field>
+                  <field>
+                     <name>STOPF</name>
+                     <description>Stop detection flag</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-only</access>
+                  </field>
+                  <field>
+                     <name>NACKF</name>
+                     <description>Not acknowledge received               flag</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-only</access>
+                  </field>
+                  <field>
+                     <name>ADDR</name>
+                     <description>Address matched (slave               mode)</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-only</access>
+                  </field>
+                  <field>
+                     <name>RXNE</name>
+                     <description>Receive data register not empty               (receivers)</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-only</access>
+                  </field>
+                  <field>
+                     <name>TXIS</name>
+                     <description>Transmit interrupt status               (transmitters)</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>TXE</name>
+                     <description>Transmit data register empty               (transmitters)</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>ICR</name>
+               <displayName>ICR</displayName>
+               <description>Interrupt clear register</description>
+               <addressOffset>0x1C</addressOffset>
+               <size>0x20</size>
+               <access>write-only</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>ALERTCF</name>
+                     <description>Alert flag clear</description>
+                     <bitOffset>13</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TIMOUTCF</name>
+                     <description>Timeout detection flag               clear</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>PECCF</name>
+                     <description>PEC Error flag clear</description>
+                     <bitOffset>11</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>OVRCF</name>
+                     <description>Overrun/Underrun flag               clear</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>ARLOCF</name>
+                     <description>Arbitration lost flag               clear</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>BERRCF</name>
+                     <description>Bus error flag clear</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>STOPCF</name>
+                     <description>Stop detection flag clear</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>NACKCF</name>
+                     <description>Not Acknowledge flag clear</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>ADDRCF</name>
+                     <description>Address Matched flag clear</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>PECR</name>
+               <displayName>PECR</displayName>
+               <description>PEC register</description>
+               <addressOffset>0x20</addressOffset>
+               <size>0x20</size>
+               <access>read-only</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>PEC</name>
+                     <description>Packet error checking               register</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>RXDR</name>
+               <displayName>RXDR</displayName>
+               <description>Receive data register</description>
+               <addressOffset>0x24</addressOffset>
+               <size>0x20</size>
+               <access>read-only</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>RXDATA</name>
+                     <description>8-bit receive data</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>TXDR</name>
+               <displayName>TXDR</displayName>
+               <description>Transmit data register</description>
+               <addressOffset>0x28</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>TXDATA</name>
+                     <description>8-bit transmit data</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+               </fields>
+            </register>
+         </registers>
+      </peripheral>
+      <peripheral derivedFrom="I2C1">
+         <name>I2C2</name>
+         <baseAddress>0x40005800</baseAddress>
+         <interrupt>
+            <name>I2C2_EV</name>
+            <description>I2C2 event interrupt</description>
+            <value>33</value>
+         </interrupt>
+         <interrupt>
+            <name>I2C2_ER</name>
+            <description>I2C2 error interrupt</description>
+            <value>34</value>
+         </interrupt>
+      </peripheral>
+      <peripheral derivedFrom="I2C1">
+         <name>I2C3</name>
+         <baseAddress>0x40005C00</baseAddress>
+         <interrupt>
+            <name>I2C3_EV</name>
+            <description>I2C3 event interrupt</description>
+            <value>72</value>
+         </interrupt>
+         <interrupt>
+            <name>I2C3_ER</name>
+            <description>I2C3 error interrupt</description>
+            <value>73</value>
+         </interrupt>
+      </peripheral>
+      <peripheral derivedFrom="I2C1">
+         <name>I2C4</name>
+         <baseAddress>0x40006000</baseAddress>
+         <interrupt>
+            <name>I2C4_EV</name>
+            <description>I2C4 event interrupt</description>
+            <value>95</value>
+         </interrupt>
+         <interrupt>
+            <name>I2C4_ER</name>
+            <description>I2C4 Error interrupt</description>
+            <value>96</value>
+         </interrupt>
+      </peripheral>
+      <peripheral>
+         <name>RTC</name>
+         <description>Real-time clock</description>
+         <groupName>RTC</groupName>
+         <baseAddress>0x40002800</baseAddress>
+         <addressBlock>
+            <offset>0x0</offset>
+            <size>0x400</size>
+            <usage>registers</usage>
+         </addressBlock>
+         <interrupt>
+            <name>RTC_WKUP</name>
+            <description>RTC Tamper or TimeStamp /CSS on LSE through
+        EXTI line 19 interrupts</description>
+            <value>3</value>
+         </interrupt>
+         <registers>
+            <register>
+               <name>TR</name>
+               <displayName>TR</displayName>
+               <description>time register</description>
+               <addressOffset>0x0</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>PM</name>
+                     <description>AM/PM notation</description>
+                     <bitOffset>22</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>HT</name>
+                     <description>Hour tens in BCD format</description>
+                     <bitOffset>20</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>HU</name>
+                     <description>Hour units in BCD format</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+                  <field>
+                     <name>MNT</name>
+                     <description>Minute tens in BCD format</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>3</bitWidth>
+                  </field>
+                  <field>
+                     <name>MNU</name>
+                     <description>Minute units in BCD format</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+                  <field>
+                     <name>ST</name>
+                     <description>Second tens in BCD format</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>3</bitWidth>
+                  </field>
+                  <field>
+                     <name>SU</name>
+                     <description>Second units in BCD format</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DR</name>
+               <displayName>DR</displayName>
+               <description>date register</description>
+               <addressOffset>0x4</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00002101</resetValue>
+               <fields>
+                  <field>
+                     <name>YT</name>
+                     <description>Year tens in BCD format</description>
+                     <bitOffset>20</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+                  <field>
+                     <name>YU</name>
+                     <description>Year units in BCD format</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+                  <field>
+                     <name>WDU</name>
+                     <description>Week day units</description>
+                     <bitOffset>13</bitOffset>
+                     <bitWidth>3</bitWidth>
+                  </field>
+                  <field>
+                     <name>MT</name>
+                     <description>Month tens in BCD format</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>MU</name>
+                     <description>Month units in BCD format</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+                  <field>
+                     <name>DT</name>
+                     <description>Date tens in BCD format</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>DU</name>
+                     <description>Date units in BCD format</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>CR</name>
+               <displayName>CR</displayName>
+               <description>control register</description>
+               <addressOffset>0x8</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>WCKSEL</name>
+                     <description>Wakeup clock selection</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>3</bitWidth>
+                  </field>
+                  <field>
+                     <name>TSEDGE</name>
+                     <description>Time-stamp event active               edge</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>REFCKON</name>
+                     <description>Reference clock detection enable (50 or               60 Hz)</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>BYPSHAD</name>
+                     <description>Bypass the shadow               registers</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FMT</name>
+                     <description>Hour format</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>ALRAE</name>
+                     <description>Alarm A enable</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>ALRBE</name>
+                     <description>Alarm B enable</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>WUTE</name>
+                     <description>Wakeup timer enable</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TSE</name>
+                     <description>Time stamp enable</description>
+                     <bitOffset>11</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>ALRAIE</name>
+                     <description>Alarm A interrupt enable</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>ALRBIE</name>
+                     <description>Alarm B interrupt enable</description>
+                     <bitOffset>13</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>WUTIE</name>
+                     <description>Wakeup timer interrupt               enable</description>
+                     <bitOffset>14</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TSIE</name>
+                     <description>Time-stamp interrupt               enable</description>
+                     <bitOffset>15</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>ADD1H</name>
+                     <description>Add 1 hour (summer time               change)</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>SUB1H</name>
+                     <description>Subtract 1 hour (winter time               change)</description>
+                     <bitOffset>17</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>BKP</name>
+                     <description>Backup</description>
+                     <bitOffset>18</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>COSEL</name>
+                     <description>Calibration output               selection</description>
+                     <bitOffset>19</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>POL</name>
+                     <description>Output polarity</description>
+                     <bitOffset>20</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>OSEL</name>
+                     <description>Output selection</description>
+                     <bitOffset>21</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>COE</name>
+                     <description>Calibration output enable</description>
+                     <bitOffset>23</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>ITSE</name>
+                     <description>timestamp on internal event               enable</description>
+                     <bitOffset>24</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>ISR</name>
+               <displayName>ISR</displayName>
+               <description>initialization and status           register</description>
+               <addressOffset>0xC</addressOffset>
+               <size>0x20</size>
+               <resetValue>0x00000007</resetValue>
+               <fields>
+                  <field>
+                     <name>ALRAWF</name>
+                     <description>Alarm A write flag</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-only</access>
+                  </field>
+                  <field>
+                     <name>ALRBWF</name>
+                     <description>Alarm B write flag</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-only</access>
+                  </field>
+                  <field>
+                     <name>WUTWF</name>
+                     <description>Wakeup timer write flag</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-only</access>
+                  </field>
+                  <field>
+                     <name>SHPF</name>
+                     <description>Shift operation pending</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>INITS</name>
+                     <description>Initialization status flag</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-only</access>
+                  </field>
+                  <field>
+                     <name>RSF</name>
+                     <description>Registers synchronization               flag</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>INITF</name>
+                     <description>Initialization flag</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-only</access>
+                  </field>
+                  <field>
+                     <name>INIT</name>
+                     <description>Initialization mode</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>ALRAF</name>
+                     <description>Alarm A flag</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>ALRBF</name>
+                     <description>Alarm B flag</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>WUTF</name>
+                     <description>Wakeup timer flag</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>TSF</name>
+                     <description>Time-stamp flag</description>
+                     <bitOffset>11</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>TSOVF</name>
+                     <description>Time-stamp overflow flag</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>TAMP1F</name>
+                     <description>Tamper detection flag</description>
+                     <bitOffset>13</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>TAMP2F</name>
+                     <description>RTC_TAMP2 detection flag</description>
+                     <bitOffset>14</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>TAMP3F</name>
+                     <description>RTC_TAMP3 detection flag</description>
+                     <bitOffset>15</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>RECALPF</name>
+                     <description>Recalibration pending Flag</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-only</access>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>PRER</name>
+               <displayName>PRER</displayName>
+               <description>prescaler register</description>
+               <addressOffset>0x10</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x007F00FF</resetValue>
+               <fields>
+                  <field>
+                     <name>PREDIV_A</name>
+                     <description>Asynchronous prescaler               factor</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>7</bitWidth>
+                  </field>
+                  <field>
+                     <name>PREDIV_S</name>
+                     <description>Synchronous prescaler               factor</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>15</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>WUTR</name>
+               <displayName>WUTR</displayName>
+               <description>wakeup timer register</description>
+               <addressOffset>0x14</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x0000FFFF</resetValue>
+               <fields>
+                  <field>
+                     <name>WUT</name>
+                     <description>Wakeup auto-reload value               bits</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>ALRMAR</name>
+               <displayName>ALRMAR</displayName>
+               <description>alarm A register</description>
+               <addressOffset>0x1C</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>MSK4</name>
+                     <description>Alarm A date mask</description>
+                     <bitOffset>31</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>WDSEL</name>
+                     <description>Week day selection</description>
+                     <bitOffset>30</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>DT</name>
+                     <description>Date tens in BCD format</description>
+                     <bitOffset>28</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>DU</name>
+                     <description>Date units or day in BCD               format</description>
+                     <bitOffset>24</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+                  <field>
+                     <name>MSK3</name>
+                     <description>Alarm A hours mask</description>
+                     <bitOffset>23</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>PM</name>
+                     <description>AM/PM notation</description>
+                     <bitOffset>22</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>HT</name>
+                     <description>Hour tens in BCD format</description>
+                     <bitOffset>20</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>HU</name>
+                     <description>Hour units in BCD format</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+                  <field>
+                     <name>MSK2</name>
+                     <description>Alarm A minutes mask</description>
+                     <bitOffset>15</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>MNT</name>
+                     <description>Minute tens in BCD format</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>3</bitWidth>
+                  </field>
+                  <field>
+                     <name>MNU</name>
+                     <description>Minute units in BCD format</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+                  <field>
+                     <name>MSK1</name>
+                     <description>Alarm A seconds mask</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>ST</name>
+                     <description>Second tens in BCD format</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>3</bitWidth>
+                  </field>
+                  <field>
+                     <name>SU</name>
+                     <description>Second units in BCD format</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>ALRMBR</name>
+               <displayName>ALRMBR</displayName>
+               <description>alarm B register</description>
+               <addressOffset>0x20</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>MSK4</name>
+                     <description>Alarm B date mask</description>
+                     <bitOffset>31</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>WDSEL</name>
+                     <description>Week day selection</description>
+                     <bitOffset>30</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>DT</name>
+                     <description>Date tens in BCD format</description>
+                     <bitOffset>28</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>DU</name>
+                     <description>Date units or day in BCD               format</description>
+                     <bitOffset>24</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+                  <field>
+                     <name>MSK3</name>
+                     <description>Alarm B hours mask</description>
+                     <bitOffset>23</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>PM</name>
+                     <description>AM/PM notation</description>
+                     <bitOffset>22</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>HT</name>
+                     <description>Hour tens in BCD format</description>
+                     <bitOffset>20</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>HU</name>
+                     <description>Hour units in BCD format</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+                  <field>
+                     <name>MSK2</name>
+                     <description>Alarm B minutes mask</description>
+                     <bitOffset>15</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>MNT</name>
+                     <description>Minute tens in BCD format</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>3</bitWidth>
+                  </field>
+                  <field>
+                     <name>MNU</name>
+                     <description>Minute units in BCD format</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+                  <field>
+                     <name>MSK1</name>
+                     <description>Alarm B seconds mask</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>ST</name>
+                     <description>Second tens in BCD format</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>3</bitWidth>
+                  </field>
+                  <field>
+                     <name>SU</name>
+                     <description>Second units in BCD format</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>WPR</name>
+               <displayName>WPR</displayName>
+               <description>write protection register</description>
+               <addressOffset>0x24</addressOffset>
+               <size>0x20</size>
+               <access>write-only</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>KEY</name>
+                     <description>Write protection key</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>SSR</name>
+               <displayName>SSR</displayName>
+               <description>sub second register</description>
+               <addressOffset>0x28</addressOffset>
+               <size>0x20</size>
+               <access>read-only</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>SS</name>
+                     <description>Sub second value</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>SHIFTR</name>
+               <displayName>SHIFTR</displayName>
+               <description>shift control register</description>
+               <addressOffset>0x2C</addressOffset>
+               <size>0x20</size>
+               <access>write-only</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>ADD1S</name>
+                     <description>Add one second</description>
+                     <bitOffset>31</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>SUBFS</name>
+                     <description>Subtract a fraction of a               second</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>15</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>TSTR</name>
+               <displayName>TSTR</displayName>
+               <description>time stamp time register</description>
+               <addressOffset>0x30</addressOffset>
+               <size>0x20</size>
+               <access>read-only</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>SU</name>
+                     <description>Second units in BCD format</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+                  <field>
+                     <name>ST</name>
+                     <description>Second tens in BCD format</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>3</bitWidth>
+                  </field>
+                  <field>
+                     <name>MNU</name>
+                     <description>Minute units in BCD format</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+                  <field>
+                     <name>MNT</name>
+                     <description>Minute tens in BCD format</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>3</bitWidth>
+                  </field>
+                  <field>
+                     <name>HU</name>
+                     <description>Hour units in BCD format</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+                  <field>
+                     <name>HT</name>
+                     <description>Hour tens in BCD format</description>
+                     <bitOffset>20</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>PM</name>
+                     <description>AM/PM notation</description>
+                     <bitOffset>22</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>TSDR</name>
+               <displayName>TSDR</displayName>
+               <description>time stamp date register</description>
+               <addressOffset>0x34</addressOffset>
+               <size>0x20</size>
+               <access>read-only</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>WDU</name>
+                     <description>Week day units</description>
+                     <bitOffset>13</bitOffset>
+                     <bitWidth>3</bitWidth>
+                  </field>
+                  <field>
+                     <name>MT</name>
+                     <description>Month tens in BCD format</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>MU</name>
+                     <description>Month units in BCD format</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+                  <field>
+                     <name>DT</name>
+                     <description>Date tens in BCD format</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>DU</name>
+                     <description>Date units in BCD format</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>TSSSR</name>
+               <displayName>TSSSR</displayName>
+               <description>timestamp sub second register</description>
+               <addressOffset>0x38</addressOffset>
+               <size>0x20</size>
+               <access>read-only</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>SS</name>
+                     <description>Sub second value</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>CALR</name>
+               <displayName>CALR</displayName>
+               <description>calibration register</description>
+               <addressOffset>0x3C</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>CALP</name>
+                     <description>Increase frequency of RTC by 488.5               ppm</description>
+                     <bitOffset>15</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CALW8</name>
+                     <description>Use an 8-second calibration cycle               period</description>
+                     <bitOffset>14</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CALW16</name>
+                     <description>Use a 16-second calibration cycle               period</description>
+                     <bitOffset>13</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CALM</name>
+                     <description>Calibration minus</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>9</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>TAMPCR</name>
+               <displayName>TAMPCR</displayName>
+               <description>tamper configuration register</description>
+               <addressOffset>0x40</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>TAMP1E</name>
+                     <description>Tamper 1 detection enable</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TAMP1TRG</name>
+                     <description>Active level for tamper 1</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TAMPIE</name>
+                     <description>Tamper interrupt enable</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TAMP2E</name>
+                     <description>Tamper 2 detection enable</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TAMP2TRG</name>
+                     <description>Active level for tamper 2</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TAMP3E</name>
+                     <description>Tamper 3 detection enable</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TAMP3TRG</name>
+                     <description>Active level for tamper 3</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TAMPTS</name>
+                     <description>Activate timestamp on tamper detection               event</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TAMPFREQ</name>
+                     <description>Tamper sampling frequency</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>3</bitWidth>
+                  </field>
+                  <field>
+                     <name>TAMPFLT</name>
+                     <description>Tamper filter count</description>
+                     <bitOffset>11</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>TAMPPRCH</name>
+                     <description>Tamper precharge duration</description>
+                     <bitOffset>13</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>TAMPPUDIS</name>
+                     <description>TAMPER pull-up disable</description>
+                     <bitOffset>15</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TAMP1IE</name>
+                     <description>Tamper 1 interrupt enable</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TAMP1NOERASE</name>
+                     <description>Tamper 1 no erase</description>
+                     <bitOffset>17</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TAMP1MF</name>
+                     <description>Tamper 1 mask flag</description>
+                     <bitOffset>18</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TAMP2IE</name>
+                     <description>Tamper 2 interrupt enable</description>
+                     <bitOffset>19</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TAMP2NOERASE</name>
+                     <description>Tamper 2 no erase</description>
+                     <bitOffset>20</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TAMP2MF</name>
+                     <description>Tamper 2 mask flag</description>
+                     <bitOffset>21</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TAMP3IE</name>
+                     <description>Tamper 3 interrupt enable</description>
+                     <bitOffset>22</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TAMP3NOERASE</name>
+                     <description>Tamper 3 no erase</description>
+                     <bitOffset>23</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TAMP3MF</name>
+                     <description>Tamper 3 mask flag</description>
+                     <bitOffset>24</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>ALRMASSR</name>
+               <displayName>ALRMASSR</displayName>
+               <description>alarm A sub second register</description>
+               <addressOffset>0x44</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>MASKSS</name>
+                     <description>Mask the most-significant bits starting               at this bit</description>
+                     <bitOffset>24</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+                  <field>
+                     <name>SS</name>
+                     <description>Sub seconds value</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>15</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>ALRMBSSR</name>
+               <displayName>ALRMBSSR</displayName>
+               <description>alarm B sub second register</description>
+               <addressOffset>0x48</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>MASKSS</name>
+                     <description>Mask the most-significant bits starting               at this bit</description>
+                     <bitOffset>24</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+                  <field>
+                     <name>SS</name>
+                     <description>Sub seconds value</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>15</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OR</name>
+               <displayName>OR</displayName>
+               <description>option register</description>
+               <addressOffset>0x4C</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>RTC_ALARM_TYPE</name>
+                     <description>RTC_ALARM on PC13 output               type</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>RTC_OUT_RMP</name>
+                     <description>RTC_OUT remap</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>BKP0R</name>
+               <displayName>BKP0R</displayName>
+               <description>backup register</description>
+               <addressOffset>0x50</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>BKP</name>
+                     <description>BKP</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>BKP1R</name>
+               <displayName>BKP1R</displayName>
+               <description>backup register</description>
+               <addressOffset>0x54</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>BKP</name>
+                     <description>BKP</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>BKP2R</name>
+               <displayName>BKP2R</displayName>
+               <description>backup register</description>
+               <addressOffset>0x58</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>BKP</name>
+                     <description>BKP</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>BKP3R</name>
+               <displayName>BKP3R</displayName>
+               <description>backup register</description>
+               <addressOffset>0x5C</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>BKP</name>
+                     <description>BKP</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>BKP4R</name>
+               <displayName>BKP4R</displayName>
+               <description>backup register</description>
+               <addressOffset>0x60</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>BKP</name>
+                     <description>BKP</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>BKP5R</name>
+               <displayName>BKP5R</displayName>
+               <description>backup register</description>
+               <addressOffset>0x64</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>BKP</name>
+                     <description>BKP</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>BKP6R</name>
+               <displayName>BKP6R</displayName>
+               <description>backup register</description>
+               <addressOffset>0x68</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>BKP</name>
+                     <description>BKP</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>BKP7R</name>
+               <displayName>BKP7R</displayName>
+               <description>backup register</description>
+               <addressOffset>0x6C</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>BKP</name>
+                     <description>BKP</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>BKP8R</name>
+               <displayName>BKP8R</displayName>
+               <description>backup register</description>
+               <addressOffset>0x70</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>BKP</name>
+                     <description>BKP</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>BKP9R</name>
+               <displayName>BKP9R</displayName>
+               <description>backup register</description>
+               <addressOffset>0x74</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>BKP</name>
+                     <description>BKP</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>BKP10R</name>
+               <displayName>BKP10R</displayName>
+               <description>backup register</description>
+               <addressOffset>0x78</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>BKP</name>
+                     <description>BKP</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>BKP11R</name>
+               <displayName>BKP11R</displayName>
+               <description>backup register</description>
+               <addressOffset>0x7C</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>BKP</name>
+                     <description>BKP</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>BKP12R</name>
+               <displayName>BKP12R</displayName>
+               <description>backup register</description>
+               <addressOffset>0x80</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>BKP</name>
+                     <description>BKP</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>BKP13R</name>
+               <displayName>BKP13R</displayName>
+               <description>backup register</description>
+               <addressOffset>0x84</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>BKP</name>
+                     <description>BKP</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>BKP14R</name>
+               <displayName>BKP14R</displayName>
+               <description>backup register</description>
+               <addressOffset>0x88</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>BKP</name>
+                     <description>BKP</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>BKP15R</name>
+               <displayName>BKP15R</displayName>
+               <description>backup register</description>
+               <addressOffset>0x8C</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>BKP</name>
+                     <description>BKP</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>BKP16R</name>
+               <displayName>BKP16R</displayName>
+               <description>backup register</description>
+               <addressOffset>0x90</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>BKP</name>
+                     <description>BKP</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>BKP17R</name>
+               <displayName>BKP17R</displayName>
+               <description>backup register</description>
+               <addressOffset>0x94</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>BKP</name>
+                     <description>BKP</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>BKP18R</name>
+               <displayName>BKP18R</displayName>
+               <description>backup register</description>
+               <addressOffset>0x98</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>BKP</name>
+                     <description>BKP</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>BKP19R</name>
+               <displayName>BKP19R</displayName>
+               <description>backup register</description>
+               <addressOffset>0x9C</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>BKP</name>
+                     <description>BKP</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>BKP20R</name>
+               <displayName>BKP20R</displayName>
+               <description>backup register</description>
+               <addressOffset>0xA0</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>BKP</name>
+                     <description>BKP</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>BKP21R</name>
+               <displayName>BKP21R</displayName>
+               <description>backup register</description>
+               <addressOffset>0xA4</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>BKP</name>
+                     <description>BKP</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>BKP22R</name>
+               <displayName>BKP22R</displayName>
+               <description>backup register</description>
+               <addressOffset>0xA8</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>BKP</name>
+                     <description>BKP</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>BKP23R</name>
+               <displayName>BKP23R</displayName>
+               <description>backup register</description>
+               <addressOffset>0xAC</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>BKP</name>
+                     <description>BKP</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>BKP24R</name>
+               <displayName>BKP24R</displayName>
+               <description>backup register</description>
+               <addressOffset>0xB0</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>BKP</name>
+                     <description>BKP</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>BKP25R</name>
+               <displayName>BKP25R</displayName>
+               <description>backup register</description>
+               <addressOffset>0xB4</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>BKP</name>
+                     <description>BKP</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>BKP26R</name>
+               <displayName>BKP26R</displayName>
+               <description>backup register</description>
+               <addressOffset>0xB8</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>BKP</name>
+                     <description>BKP</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>BKP27R</name>
+               <displayName>BKP27R</displayName>
+               <description>backup register</description>
+               <addressOffset>0xBC</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>BKP</name>
+                     <description>BKP</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>BKP28R</name>
+               <displayName>BKP28R</displayName>
+               <description>backup register</description>
+               <addressOffset>0xC0</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>BKP</name>
+                     <description>BKP</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>BKP29R</name>
+               <displayName>BKP29R</displayName>
+               <description>backup register</description>
+               <addressOffset>0xC4</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>BKP</name>
+                     <description>BKP</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>BKP30R</name>
+               <displayName>BKP30R</displayName>
+               <description>backup register</description>
+               <addressOffset>0xC8</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>BKP</name>
+                     <description>BKP</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>BKP31R</name>
+               <displayName>BKP31R</displayName>
+               <description>backup register</description>
+               <addressOffset>0xCC</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>BKP</name>
+                     <description>BKP</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+         </registers>
+      </peripheral>
+      <peripheral>
+         <name>USART6</name>
+         <description>Universal synchronous asynchronous receiver       transmitter</description>
+         <groupName>USART</groupName>
+         <baseAddress>0x40011400</baseAddress>
+         <addressBlock>
+            <offset>0x0</offset>
+            <size>0x400</size>
+            <usage>registers</usage>
+         </addressBlock>
+         <interrupt>
+            <name>USART6</name>
+            <description>USART6 global interrupt</description>
+            <value>71</value>
+         </interrupt>
+         <registers>
+            <register>
+               <name>CR1</name>
+               <displayName>CR1</displayName>
+               <description>Control register 1</description>
+               <addressOffset>0x0</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x0000</resetValue>
+               <fields>
+                  <field>
+                     <name>M1</name>
+                     <description>Word length</description>
+                     <bitOffset>28</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>EOBIE</name>
+                     <description>End of Block interrupt               enable</description>
+                     <bitOffset>27</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>RTOIE</name>
+                     <description>Receiver timeout interrupt               enable</description>
+                     <bitOffset>26</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>DEAT4</name>
+                     <description>Driver Enable assertion               time</description>
+                     <bitOffset>25</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>DEAT3</name>
+                     <description>DEAT3</description>
+                     <bitOffset>24</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>DEAT2</name>
+                     <description>DEAT2</description>
+                     <bitOffset>23</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>DEAT1</name>
+                     <description>DEAT1</description>
+                     <bitOffset>22</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>DEAT0</name>
+                     <description>DEAT0</description>
+                     <bitOffset>21</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>DEDT4</name>
+                     <description>Driver Enable de-assertion               time</description>
+                     <bitOffset>20</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>DEDT3</name>
+                     <description>DEDT3</description>
+                     <bitOffset>19</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>DEDT2</name>
+                     <description>DEDT2</description>
+                     <bitOffset>18</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>DEDT1</name>
+                     <description>DEDT1</description>
+                     <bitOffset>17</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>DEDT0</name>
+                     <description>DEDT0</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>OVER8</name>
+                     <description>Oversampling mode</description>
+                     <bitOffset>15</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CMIE</name>
+                     <description>Character match interrupt               enable</description>
+                     <bitOffset>14</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>MME</name>
+                     <description>Mute mode enable</description>
+                     <bitOffset>13</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>M0</name>
+                     <description>Word length</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>WAKE</name>
+                     <description>Receiver wakeup method</description>
+                     <bitOffset>11</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>PCE</name>
+                     <description>Parity control enable</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>PS</name>
+                     <description>Parity selection</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>PEIE</name>
+                     <description>PE interrupt enable</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TXEIE</name>
+                     <description>interrupt enable</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TCIE</name>
+                     <description>Transmission complete interrupt               enable</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>RXNEIE</name>
+                     <description>RXNE interrupt enable</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>IDLEIE</name>
+                     <description>IDLE interrupt enable</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TE</name>
+                     <description>Transmitter enable</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>RE</name>
+                     <description>Receiver enable</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>UESM</name>
+                     <description>USART enable in Stop mode</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>UE</name>
+                     <description>USART enable</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>CR2</name>
+               <displayName>CR2</displayName>
+               <description>Control register 2</description>
+               <addressOffset>0x4</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x0000</resetValue>
+               <fields>
+                  <field>
+                     <name>ADD4_7</name>
+                     <description>Address of the USART node</description>
+                     <bitOffset>28</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+                  <field>
+                     <name>ADD0_3</name>
+                     <description>Address of the USART node</description>
+                     <bitOffset>24</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+                  <field>
+                     <name>RTOEN</name>
+                     <description>Receiver timeout enable</description>
+                     <bitOffset>23</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>ABRMOD1</name>
+                     <description>Auto baud rate mode</description>
+                     <bitOffset>22</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>ABRMOD0</name>
+                     <description>ABRMOD0</description>
+                     <bitOffset>21</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>ABREN</name>
+                     <description>Auto baud rate enable</description>
+                     <bitOffset>20</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>MSBFIRST</name>
+                     <description>Most significant bit first</description>
+                     <bitOffset>19</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TAINV</name>
+                     <description>Binary data inversion</description>
+                     <bitOffset>18</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TXINV</name>
+                     <description>TX pin active level               inversion</description>
+                     <bitOffset>17</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>RXINV</name>
+                     <description>RX pin active level               inversion</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>SWAP</name>
+                     <description>Swap TX/RX pins</description>
+                     <bitOffset>15</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>LINEN</name>
+                     <description>LIN mode enable</description>
+                     <bitOffset>14</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>STOP</name>
+                     <description>STOP bits</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>CLKEN</name>
+                     <description>Clock enable</description>
+                     <bitOffset>11</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CPOL</name>
+                     <description>Clock polarity</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CPHA</name>
+                     <description>Clock phase</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>LBCL</name>
+                     <description>Last bit clock pulse</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>LBDIE</name>
+                     <description>LIN break detection interrupt               enable</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>LBDL</name>
+                     <description>LIN break detection length</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>ADDM7</name>
+                     <description>7-bit Address Detection/4-bit Address               Detection</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>CR3</name>
+               <displayName>CR3</displayName>
+               <description>Control register 3</description>
+               <addressOffset>0x8</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x0000</resetValue>
+               <fields>
+                  <field>
+                     <name>WUFIE</name>
+                     <description>Wakeup from Stop mode interrupt               enable</description>
+                     <bitOffset>22</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>WUS</name>
+                     <description>Wakeup from Stop mode interrupt flag               selection</description>
+                     <bitOffset>20</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>SCARCNT</name>
+                     <description>Smartcard auto-retry count</description>
+                     <bitOffset>17</bitOffset>
+                     <bitWidth>3</bitWidth>
+                  </field>
+                  <field>
+                     <name>DEP</name>
+                     <description>Driver enable polarity               selection</description>
+                     <bitOffset>15</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>DEM</name>
+                     <description>Driver enable mode</description>
+                     <bitOffset>14</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>DDRE</name>
+                     <description>DMA Disable on Reception               Error</description>
+                     <bitOffset>13</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>OVRDIS</name>
+                     <description>Overrun Disable</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>ONEBIT</name>
+                     <description>One sample bit method               enable</description>
+                     <bitOffset>11</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CTSIE</name>
+                     <description>CTS interrupt enable</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CTSE</name>
+                     <description>CTS enable</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>RTSE</name>
+                     <description>RTS enable</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>DMAT</name>
+                     <description>DMA enable transmitter</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>DMAR</name>
+                     <description>DMA enable receiver</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>SCEN</name>
+                     <description>Smartcard mode enable</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>NACK</name>
+                     <description>Smartcard NACK enable</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>HDSEL</name>
+                     <description>Half-duplex selection</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>IRLP</name>
+                     <description>Ir low-power</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>IREN</name>
+                     <description>Ir mode enable</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>EIE</name>
+                     <description>Error interrupt enable</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>BRR</name>
+               <displayName>BRR</displayName>
+               <description>Baud rate register</description>
+               <addressOffset>0xC</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x0000</resetValue>
+               <fields>
+                  <field>
+                     <name>DIV_Mantissa</name>
+                     <description>DIV_Mantissa</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>12</bitWidth>
+                  </field>
+                  <field>
+                     <name>DIV_Fraction</name>
+                     <description>DIV_Fraction</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>GTPR</name>
+               <displayName>GTPR</displayName>
+               <description>Guard time and prescaler           register</description>
+               <addressOffset>0x10</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x0000</resetValue>
+               <fields>
+                  <field>
+                     <name>GT</name>
+                     <description>Guard time value</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+                  <field>
+                     <name>PSC</name>
+                     <description>Prescaler value</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>RTOR</name>
+               <displayName>RTOR</displayName>
+               <description>Receiver timeout register</description>
+               <addressOffset>0x14</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x0000</resetValue>
+               <fields>
+                  <field>
+                     <name>BLEN</name>
+                     <description>Block Length</description>
+                     <bitOffset>24</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+                  <field>
+                     <name>RTO</name>
+                     <description>Receiver timeout value</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>24</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>RQR</name>
+               <displayName>RQR</displayName>
+               <description>Request register</description>
+               <addressOffset>0x18</addressOffset>
+               <size>0x20</size>
+               <access>write-only</access>
+               <resetValue>0x0000</resetValue>
+               <fields>
+                  <field>
+                     <name>TXFRQ</name>
+                     <description>Transmit data flush               request</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>RXFRQ</name>
+                     <description>Receive data flush request</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>MMRQ</name>
+                     <description>Mute mode request</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>SBKRQ</name>
+                     <description>Send break request</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>ABRRQ</name>
+                     <description>Auto baud rate request</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>ISR</name>
+               <displayName>ISR</displayName>
+               <description>Interrupt &amp; status           register</description>
+               <addressOffset>0x1C</addressOffset>
+               <size>0x20</size>
+               <access>read-only</access>
+               <resetValue>0x00C0</resetValue>
+               <fields>
+                  <field>
+                     <name>REACK</name>
+                     <description>REACK</description>
+                     <bitOffset>22</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TEACK</name>
+                     <description>TEACK</description>
+                     <bitOffset>21</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>WUF</name>
+                     <description>WUF</description>
+                     <bitOffset>20</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>RWU</name>
+                     <description>RWU</description>
+                     <bitOffset>19</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>SBKF</name>
+                     <description>SBKF</description>
+                     <bitOffset>18</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CMF</name>
+                     <description>CMF</description>
+                     <bitOffset>17</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>BUSY</name>
+                     <description>BUSY</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>ABRF</name>
+                     <description>ABRF</description>
+                     <bitOffset>15</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>ABRE</name>
+                     <description>ABRE</description>
+                     <bitOffset>14</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>EOBF</name>
+                     <description>EOBF</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>RTOF</name>
+                     <description>RTOF</description>
+                     <bitOffset>11</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CTS</name>
+                     <description>CTS</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CTSIF</name>
+                     <description>CTSIF</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>LBDF</name>
+                     <description>LBDF</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TXE</name>
+                     <description>TXE</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TC</name>
+                     <description>TC</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>RXNE</name>
+                     <description>RXNE</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>IDLE</name>
+                     <description>IDLE</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>ORE</name>
+                     <description>ORE</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>NF</name>
+                     <description>NF</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FE</name>
+                     <description>FE</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>PE</name>
+                     <description>PE</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>ICR</name>
+               <displayName>ICR</displayName>
+               <description>Interrupt flag clear register</description>
+               <addressOffset>0x20</addressOffset>
+               <size>0x20</size>
+               <access>write-only</access>
+               <resetValue>0x0000</resetValue>
+               <fields>
+                  <field>
+                     <name>WUCF</name>
+                     <description>Wakeup from Stop mode clear               flag</description>
+                     <bitOffset>20</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CMCF</name>
+                     <description>Character match clear flag</description>
+                     <bitOffset>17</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>EOBCF</name>
+                     <description>End of block clear flag</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>RTOCF</name>
+                     <description>Receiver timeout clear               flag</description>
+                     <bitOffset>11</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CTSCF</name>
+                     <description>CTS clear flag</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>LBDCF</name>
+                     <description>LIN break detection clear               flag</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TCCF</name>
+                     <description>Transmission complete clear               flag</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>IDLECF</name>
+                     <description>Idle line detected clear               flag</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>ORECF</name>
+                     <description>Overrun error clear flag</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>NCF</name>
+                     <description>Noise detected clear flag</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FECF</name>
+                     <description>Framing error clear flag</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>PECF</name>
+                     <description>Parity error clear flag</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>RDR</name>
+               <displayName>RDR</displayName>
+               <description>Receive data register</description>
+               <addressOffset>0x24</addressOffset>
+               <size>0x20</size>
+               <access>read-only</access>
+               <resetValue>0x0000</resetValue>
+               <fields>
+                  <field>
+                     <name>RDR</name>
+                     <description>Receive data value</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>9</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>TDR</name>
+               <displayName>TDR</displayName>
+               <description>Transmit data register</description>
+               <addressOffset>0x28</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x0000</resetValue>
+               <fields>
+                  <field>
+                     <name>TDR</name>
+                     <description>Transmit data value</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>9</bitWidth>
+                  </field>
+               </fields>
+            </register>
+         </registers>
+      </peripheral>
+      <peripheral derivedFrom="USART6">
+         <name>USART1</name>
+         <baseAddress>0x40011000</baseAddress>
+         <interrupt>
+            <name>USART1</name>
+            <description>USART1 global interrupt</description>
+            <value>37</value>
+         </interrupt>
+      </peripheral>
+      <peripheral derivedFrom="USART6">
+         <name>USART3</name>
+         <baseAddress>0x40004800</baseAddress>
+         <interrupt>
+            <name>USART3</name>
+            <description>USART3 global interrupt</description>
+            <value>39</value>
+         </interrupt>
+      </peripheral>
+      <peripheral derivedFrom="USART6">
+         <name>USART2</name>
+         <baseAddress>0x40004400</baseAddress>
+         <interrupt>
+            <name>USART2</name>
+            <description>USART2 global interrupt</description>
+            <value>38</value>
+         </interrupt>
+      </peripheral>
+      <peripheral derivedFrom="USART6">
+         <name>UART5</name>
+         <baseAddress>0x40005000</baseAddress>
+         <interrupt>
+            <name>UART5</name>
+            <description>UART5 global interrupt</description>
+            <value>53</value>
+         </interrupt>
+      </peripheral>
+      <peripheral derivedFrom="USART6">
+         <name>UART4</name>
+         <baseAddress>0x40004C00</baseAddress>
+         <interrupt>
+            <name>UART4</name>
+            <description>UART4 global interrupt</description>
+            <value>52</value>
+         </interrupt>
+      </peripheral>
+      <peripheral derivedFrom="USART6">
+         <name>UART8</name>
+         <baseAddress>0x40007C00</baseAddress>
+         <interrupt>
+            <name>UART8</name>
+            <description>UART 8 global interrupt</description>
+            <value>83</value>
+         </interrupt>
+      </peripheral>
+      <peripheral derivedFrom="USART6">
+         <name>UART7</name>
+         <baseAddress>0x40007800</baseAddress>
+         <interrupt>
+            <name>UART7</name>
+            <description>UART7 global interrupt</description>
+            <value>82</value>
+         </interrupt>
+      </peripheral>
+      <peripheral>
+         <name>OTG_FS_GLOBAL</name>
+         <description>USB on the go full speed</description>
+         <groupName>USB_OTG_FS</groupName>
+         <baseAddress>0x50000000</baseAddress>
+         <addressBlock>
+            <offset>0x0</offset>
+            <size>0x400</size>
+            <usage>registers</usage>
+         </addressBlock>
+         <interrupt>
+            <name>OTG_FS</name>
+            <description>USB On The Go FS global
+        interrupt</description>
+            <value>67</value>
+         </interrupt>
+         <registers>
+            <register>
+               <name>OTG_FS_GOTGCTL</name>
+               <displayName>OTG_FS_GOTGCTL</displayName>
+               <description>OTG_FS control and status register           (OTG_FS_GOTGCTL)</description>
+               <addressOffset>0x0</addressOffset>
+               <size>0x20</size>
+               <resetValue>0x00000800</resetValue>
+               <fields>
+                  <field>
+                     <name>SRQSCS</name>
+                     <description>Session request success</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-only</access>
+                  </field>
+                  <field>
+                     <name>SRQ</name>
+                     <description>Session request</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>HNGSCS</name>
+                     <description>Host negotiation success</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-only</access>
+                  </field>
+                  <field>
+                     <name>HNPRQ</name>
+                     <description>HNP request</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>HSHNPEN</name>
+                     <description>Host set HNP enable</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>DHNPEN</name>
+                     <description>Device HNP enabled</description>
+                     <bitOffset>11</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>CIDSTS</name>
+                     <description>Connector ID status</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-only</access>
+                  </field>
+                  <field>
+                     <name>DBCT</name>
+                     <description>Long/short debounce time</description>
+                     <bitOffset>17</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-only</access>
+                  </field>
+                  <field>
+                     <name>ASVLD</name>
+                     <description>A-session valid</description>
+                     <bitOffset>18</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-only</access>
+                  </field>
+                  <field>
+                     <name>BSVLD</name>
+                     <description>B-session valid</description>
+                     <bitOffset>19</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-only</access>
+                  </field>
+                  <field>
+                     <name>VBVALOEN</name>
+                     <description>VBUS valid override enable</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>VBVALOVAL</name>
+                     <description>VBUS valid override value</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>AVALOEN</name>
+                     <description>A-peripheral session valid override               enable</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>AVALOVAL</name>
+                     <description>A-peripheral session valid override               value</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>BVALOEN</name>
+                     <description>B-peripheral session valid override               enable</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>BVALOVAL</name>
+                     <description>B-peripheral session valid override               value</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>EHEN</name>
+                     <description>Embedded host enable</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>OTGVER</name>
+                     <description>OTG version</description>
+                     <bitOffset>20</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_FS_GOTGINT</name>
+               <displayName>OTG_FS_GOTGINT</displayName>
+               <description>OTG_FS interrupt register           (OTG_FS_GOTGINT)</description>
+               <addressOffset>0x4</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>SEDET</name>
+                     <description>Session end detected</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>SRSSCHG</name>
+                     <description>Session request success status               change</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>HNSSCHG</name>
+                     <description>Host negotiation success status               change</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>HNGDET</name>
+                     <description>Host negotiation detected</description>
+                     <bitOffset>17</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>ADTOCHG</name>
+                     <description>A-device timeout change</description>
+                     <bitOffset>18</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>DBCDNE</name>
+                     <description>Debounce done</description>
+                     <bitOffset>19</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>IDCHNG</name>
+                     <description>ID input pin changed</description>
+                     <bitOffset>20</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_FS_GAHBCFG</name>
+               <displayName>OTG_FS_GAHBCFG</displayName>
+               <description>OTG_FS AHB configuration register           (OTG_FS_GAHBCFG)</description>
+               <addressOffset>0x8</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>GINT</name>
+                     <description>Global interrupt mask</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TXFELVL</name>
+                     <description>TxFIFO empty level</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>PTXFELVL</name>
+                     <description>Periodic TxFIFO empty               level</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_FS_GUSBCFG</name>
+               <displayName>OTG_FS_GUSBCFG</displayName>
+               <description>OTG_FS USB configuration register           (OTG_FS_GUSBCFG)</description>
+               <addressOffset>0xC</addressOffset>
+               <size>0x20</size>
+               <resetValue>0x00000A00</resetValue>
+               <fields>
+                  <field>
+                     <name>TOCAL</name>
+                     <description>FS timeout calibration</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>3</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>PHYSEL</name>
+                     <description>Full Speed serial transceiver               select</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>write-only</access>
+                  </field>
+                  <field>
+                     <name>SRPCAP</name>
+                     <description>SRP-capable</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>HNPCAP</name>
+                     <description>HNP-capable</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>TRDT</name>
+                     <description>USB turnaround time</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>4</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>FHMOD</name>
+                     <description>Force host mode</description>
+                     <bitOffset>29</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>FDMOD</name>
+                     <description>Force device mode</description>
+                     <bitOffset>30</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_FS_GRSTCTL</name>
+               <displayName>OTG_FS_GRSTCTL</displayName>
+               <description>OTG_FS reset register           (OTG_FS_GRSTCTL)</description>
+               <addressOffset>0x10</addressOffset>
+               <size>0x20</size>
+               <resetValue>0x20000000</resetValue>
+               <fields>
+                  <field>
+                     <name>CSRST</name>
+                     <description>Core soft reset</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>HSRST</name>
+                     <description>HCLK soft reset</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>FCRST</name>
+                     <description>Host frame counter reset</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>RXFFLSH</name>
+                     <description>RxFIFO flush</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>TXFFLSH</name>
+                     <description>TxFIFO flush</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>TXFNUM</name>
+                     <description>TxFIFO number</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>5</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>AHBIDL</name>
+                     <description>AHB master idle</description>
+                     <bitOffset>31</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-only</access>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_FS_GINTSTS</name>
+               <displayName>OTG_FS_GINTSTS</displayName>
+               <description>OTG_FS core interrupt register           (OTG_FS_GINTSTS)</description>
+               <addressOffset>0x14</addressOffset>
+               <size>0x20</size>
+               <resetValue>0x04000020</resetValue>
+               <fields>
+                  <field>
+                     <name>CMOD</name>
+                     <description>Current mode of operation</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-only</access>
+                  </field>
+                  <field>
+                     <name>MMIS</name>
+                     <description>Mode mismatch interrupt</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>OTGINT</name>
+                     <description>OTG interrupt</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-only</access>
+                  </field>
+                  <field>
+                     <name>SOF</name>
+                     <description>Start of frame</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>RXFLVL</name>
+                     <description>RxFIFO non-empty</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-only</access>
+                  </field>
+                  <field>
+                     <name>NPTXFE</name>
+                     <description>Non-periodic TxFIFO empty</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-only</access>
+                  </field>
+                  <field>
+                     <name>GINAKEFF</name>
+                     <description>Global IN non-periodic NAK               effective</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-only</access>
+                  </field>
+                  <field>
+                     <name>GOUTNAKEFF</name>
+                     <description>Global OUT NAK effective</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-only</access>
+                  </field>
+                  <field>
+                     <name>ESUSP</name>
+                     <description>Early suspend</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>USBSUSP</name>
+                     <description>USB suspend</description>
+                     <bitOffset>11</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>USBRST</name>
+                     <description>USB reset</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>ENUMDNE</name>
+                     <description>Enumeration done</description>
+                     <bitOffset>13</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>ISOODRP</name>
+                     <description>Isochronous OUT packet dropped               interrupt</description>
+                     <bitOffset>14</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>EOPF</name>
+                     <description>End of periodic frame               interrupt</description>
+                     <bitOffset>15</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>IEPINT</name>
+                     <description>IN endpoint interrupt</description>
+                     <bitOffset>18</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-only</access>
+                  </field>
+                  <field>
+                     <name>OEPINT</name>
+                     <description>OUT endpoint interrupt</description>
+                     <bitOffset>19</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-only</access>
+                  </field>
+                  <field>
+                     <name>IISOIXFR</name>
+                     <description>Incomplete isochronous IN               transfer</description>
+                     <bitOffset>20</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>IPXFR_INCOMPISOOUT</name>
+                     <description>Incomplete periodic transfer(Host               mode)/Incomplete isochronous OUT transfer(Device               mode)</description>
+                     <bitOffset>21</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>HPRTINT</name>
+                     <description>Host port interrupt</description>
+                     <bitOffset>24</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-only</access>
+                  </field>
+                  <field>
+                     <name>HCINT</name>
+                     <description>Host channels interrupt</description>
+                     <bitOffset>25</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-only</access>
+                  </field>
+                  <field>
+                     <name>PTXFE</name>
+                     <description>Periodic TxFIFO empty</description>
+                     <bitOffset>26</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-only</access>
+                  </field>
+                  <field>
+                     <name>CIDSCHG</name>
+                     <description>Connector ID status change</description>
+                     <bitOffset>28</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>DISCINT</name>
+                     <description>Disconnect detected               interrupt</description>
+                     <bitOffset>29</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>SRQINT</name>
+                     <description>Session request/new session detected               interrupt</description>
+                     <bitOffset>30</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>WKUPINT</name>
+                     <description>Resume/remote wakeup detected               interrupt</description>
+                     <bitOffset>31</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>RSTDET</name>
+                     <description>Reset detected interrupt</description>
+                     <bitOffset>23</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_FS_GINTMSK</name>
+               <displayName>OTG_FS_GINTMSK</displayName>
+               <description>OTG_FS interrupt mask register           (OTG_FS_GINTMSK)</description>
+               <addressOffset>0x18</addressOffset>
+               <size>0x20</size>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>MMISM</name>
+                     <description>Mode mismatch interrupt               mask</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>OTGINT</name>
+                     <description>OTG interrupt mask</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>SOFM</name>
+                     <description>Start of frame mask</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>RXFLVLM</name>
+                     <description>Receive FIFO non-empty               mask</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>NPTXFEM</name>
+                     <description>Non-periodic TxFIFO empty               mask</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>GINAKEFFM</name>
+                     <description>Global non-periodic IN NAK effective               mask</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>GONAKEFFM</name>
+                     <description>Global OUT NAK effective               mask</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>ESUSPM</name>
+                     <description>Early suspend mask</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>USBSUSPM</name>
+                     <description>USB suspend mask</description>
+                     <bitOffset>11</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>USBRST</name>
+                     <description>USB reset mask</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>ENUMDNEM</name>
+                     <description>Enumeration done mask</description>
+                     <bitOffset>13</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>ISOODRPM</name>
+                     <description>Isochronous OUT packet dropped interrupt               mask</description>
+                     <bitOffset>14</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>EOPFM</name>
+                     <description>End of periodic frame interrupt               mask</description>
+                     <bitOffset>15</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>IEPINT</name>
+                     <description>IN endpoints interrupt               mask</description>
+                     <bitOffset>18</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>OEPINT</name>
+                     <description>OUT endpoints interrupt               mask</description>
+                     <bitOffset>19</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>IISOIXFRM</name>
+                     <description>Incomplete isochronous IN transfer               mask</description>
+                     <bitOffset>20</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>IPXFRM_IISOOXFRM</name>
+                     <description>Incomplete periodic transfer mask(Host               mode)/Incomplete isochronous OUT transfer mask(Device               mode)</description>
+                     <bitOffset>21</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>PRTIM</name>
+                     <description>Host port interrupt mask</description>
+                     <bitOffset>24</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-only</access>
+                  </field>
+                  <field>
+                     <name>HCIM</name>
+                     <description>Host channels interrupt               mask</description>
+                     <bitOffset>25</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>PTXFEM</name>
+                     <description>Periodic TxFIFO empty mask</description>
+                     <bitOffset>26</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>CIDSCHGM</name>
+                     <description>Connector ID status change               mask</description>
+                     <bitOffset>28</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>DISCINT</name>
+                     <description>Disconnect detected interrupt               mask</description>
+                     <bitOffset>29</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>SRQIM</name>
+                     <description>Session request/new session detected               interrupt mask</description>
+                     <bitOffset>30</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>WUIM</name>
+                     <description>Resume/remote wakeup detected interrupt               mask</description>
+                     <bitOffset>31</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>RSTDETM</name>
+                     <description>Reset detected interrupt               mask</description>
+                     <bitOffset>23</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>LPMIN</name>
+                     <description>LPM interrupt mask</description>
+                     <bitOffset>27</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_FS_GRXSTSR_Device</name>
+               <displayName>OTG_FS_GRXSTSR_Device</displayName>
+               <description>OTG_FS Receive status debug read(Device           mode)</description>
+               <addressOffset>0x1C</addressOffset>
+               <size>0x20</size>
+               <access>read-only</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>EPNUM</name>
+                     <description>Endpoint number</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+                  <field>
+                     <name>BCNT</name>
+                     <description>Byte count</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>11</bitWidth>
+                  </field>
+                  <field>
+                     <name>DPID</name>
+                     <description>Data PID</description>
+                     <bitOffset>15</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>PKTSTS</name>
+                     <description>Packet status</description>
+                     <bitOffset>17</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+                  <field>
+                     <name>FRMNUM</name>
+                     <description>Frame number</description>
+                     <bitOffset>21</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_FS_GRXSTSR_Host</name>
+               <displayName>OTG_FS_GRXSTSR_Host</displayName>
+               <description>OTG_FS Receive status debug read(Host           mode)</description>
+               <alternateRegister>OTG_FS_GRXSTSR_Device</alternateRegister>
+               <addressOffset>0x1C</addressOffset>
+               <size>0x20</size>
+               <access>read-only</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>CHNUM</name>
+                     <description>Endpoint number</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+                  <field>
+                     <name>BCNT</name>
+                     <description>Byte count</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>11</bitWidth>
+                  </field>
+                  <field>
+                     <name>DPID</name>
+                     <description>Data PID</description>
+                     <bitOffset>15</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>PKTSTS</name>
+                     <description>Packet status</description>
+                     <bitOffset>17</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_FS_GRXFSIZ</name>
+               <displayName>OTG_FS_GRXFSIZ</displayName>
+               <description>OTG_FS Receive FIFO size register           (OTG_FS_GRXFSIZ)</description>
+               <addressOffset>0x24</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000200</resetValue>
+               <fields>
+                  <field>
+                     <name>RXFD</name>
+                     <description>RxFIFO depth</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_FS_DIEPTXF0_Device</name>
+               <displayName>OTG_FS_DIEPTXF0_Device</displayName>
+               <description>OTG_FS Endpoint 0 Transmit FIFO           size</description>
+               <addressOffset>0x28</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000200</resetValue>
+               <fields>
+                  <field>
+                     <name>TX0FSA</name>
+                     <description>Endpoint 0 transmit RAM start               address</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+                  <field>
+                     <name>TX0FD</name>
+                     <description>Endpoint 0 TxFIFO depth</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_FS_HNPTXFSIZ_Host</name>
+               <displayName>OTG_FS_HNPTXFSIZ_Host</displayName>
+               <description>OTG_FS Host non-periodic transmit FIFO size           register</description>
+               <alternateRegister>OTG_FS_DIEPTXF0_Device</alternateRegister>
+               <addressOffset>0x28</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000200</resetValue>
+               <fields>
+                  <field>
+                     <name>NPTXFSA</name>
+                     <description>Non-periodic transmit RAM start               address</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+                  <field>
+                     <name>NPTXFD</name>
+                     <description>Non-periodic TxFIFO depth</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_FS_HNPTXSTS</name>
+               <displayName>OTG_FS_HNPTXSTS</displayName>
+               <description>OTG_FS non-periodic transmit FIFO/queue           status register (OTG_FS_GNPTXSTS)</description>
+               <addressOffset>0x2C</addressOffset>
+               <size>0x20</size>
+               <access>read-only</access>
+               <resetValue>0x00080200</resetValue>
+               <fields>
+                  <field>
+                     <name>NPTXFSAV</name>
+                     <description>Non-periodic TxFIFO space               available</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+                  <field>
+                     <name>NPTQXSAV</name>
+                     <description>Non-periodic transmit request queue               space available</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+                  <field>
+                     <name>NPTXQTOP</name>
+                     <description>Top of the non-periodic transmit request               queue</description>
+                     <bitOffset>24</bitOffset>
+                     <bitWidth>7</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_FS_GCCFG</name>
+               <displayName>OTG_FS_GCCFG</displayName>
+               <description>OTG_FS general core configuration register           (OTG_FS_GCCFG)</description>
+               <addressOffset>0x38</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>PWRDWN</name>
+                     <description>Power down</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>BCDEN</name>
+                     <description>Battery charging detector (BCD)               enable</description>
+                     <bitOffset>17</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>DCDEN</name>
+                     <description>Data contact detection (DCD) mode               enable</description>
+                     <bitOffset>18</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>PDEN</name>
+                     <description>Primary detection (PD) mode               enable</description>
+                     <bitOffset>19</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>SDEN</name>
+                     <description>Secondary detection (SD) mode               enable</description>
+                     <bitOffset>20</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>VBDEN</name>
+                     <description>USB VBUS detection enable</description>
+                     <bitOffset>21</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>DCDET</name>
+                     <description>Data contact detection (DCD)               status</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>PDET</name>
+                     <description>Primary detection (PD)               status</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>SDET</name>
+                     <description>Secondary detection (SD)               status</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>PS2DET</name>
+                     <description>DM pull-up detection               status</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_FS_CID</name>
+               <displayName>OTG_FS_CID</displayName>
+               <description>core ID register</description>
+               <addressOffset>0x3C</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00001000</resetValue>
+               <fields>
+                  <field>
+                     <name>PRODUCT_ID</name>
+                     <description>Product ID field</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_FS_HPTXFSIZ</name>
+               <displayName>OTG_FS_HPTXFSIZ</displayName>
+               <description>OTG_FS Host periodic transmit FIFO size           register (OTG_FS_HPTXFSIZ)</description>
+               <addressOffset>0x100</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x02000600</resetValue>
+               <fields>
+                  <field>
+                     <name>PTXSA</name>
+                     <description>Host periodic TxFIFO start               address</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+                  <field>
+                     <name>PTXFSIZ</name>
+                     <description>Host periodic TxFIFO depth</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_FS_DIEPTXF1</name>
+               <displayName>OTG_FS_DIEPTXF1</displayName>
+               <description>OTG_FS device IN endpoint transmit FIFO size           register (OTG_FS_DIEPTXF1)</description>
+               <addressOffset>0x104</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x02000400</resetValue>
+               <fields>
+                  <field>
+                     <name>INEPTXSA</name>
+                     <description>IN endpoint FIFO2 transmit RAM start               address</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+                  <field>
+                     <name>INEPTXFD</name>
+                     <description>IN endpoint TxFIFO depth</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_FS_DIEPTXF2</name>
+               <displayName>OTG_FS_DIEPTXF2</displayName>
+               <description>OTG_FS device IN endpoint transmit FIFO size           register (OTG_FS_DIEPTXF2)</description>
+               <addressOffset>0x108</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x02000400</resetValue>
+               <fields>
+                  <field>
+                     <name>INEPTXSA</name>
+                     <description>IN endpoint FIFO3 transmit RAM start               address</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+                  <field>
+                     <name>INEPTXFD</name>
+                     <description>IN endpoint TxFIFO depth</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_FS_DIEPTXF3</name>
+               <displayName>OTG_FS_DIEPTXF3</displayName>
+               <description>OTG_FS device IN endpoint transmit FIFO size           register (OTG_FS_DIEPTXF3)</description>
+               <addressOffset>0x10C</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x02000400</resetValue>
+               <fields>
+                  <field>
+                     <name>INEPTXSA</name>
+                     <description>IN endpoint FIFO4 transmit RAM start               address</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+                  <field>
+                     <name>INEPTXFD</name>
+                     <description>IN endpoint TxFIFO depth</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_FS_GRXSTSP_Device</name>
+               <displayName>OTG_FS_GRXSTSP_Device</displayName>
+               <description>OTG status read and pop register (Device           mode)</description>
+               <addressOffset>0x20</addressOffset>
+               <size>0x20</size>
+               <access>read-only</access>
+               <resetValue>0x02000400</resetValue>
+               <fields>
+                  <field>
+                     <name>EPNUM</name>
+                     <description>Endpoint number</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+                  <field>
+                     <name>BCNT</name>
+                     <description>Byte count</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>11</bitWidth>
+                  </field>
+                  <field>
+                     <name>DPID</name>
+                     <description>Data PID</description>
+                     <bitOffset>15</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>PKTSTS</name>
+                     <description>Packet status</description>
+                     <bitOffset>17</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+                  <field>
+                     <name>FRMNUM</name>
+                     <description>Frame number</description>
+                     <bitOffset>21</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_FS_GRXSTSP_Host</name>
+               <displayName>OTG_FS_GRXSTSP_Host</displayName>
+               <description>OTG status read and pop register (Host           mode)</description>
+               <alternateRegister>OTG_FS_GRXSTSP_Device</alternateRegister>
+               <addressOffset>0x20</addressOffset>
+               <size>0x20</size>
+               <access>read-only</access>
+               <resetValue>0x02000400</resetValue>
+               <fields>
+                  <field>
+                     <name>CHNUM</name>
+                     <description>Channel number</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+                  <field>
+                     <name>BCNT</name>
+                     <description>Byte count</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>11</bitWidth>
+                  </field>
+                  <field>
+                     <name>DPID</name>
+                     <description>Data PID</description>
+                     <bitOffset>15</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>PKTSTS</name>
+                     <description>Packet status</description>
+                     <bitOffset>17</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_FS_GI2CCTL</name>
+               <displayName>OTG_FS_GI2CCTL</displayName>
+               <description>OTG I2C access register</description>
+               <addressOffset>0x30</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x02000400</resetValue>
+               <fields>
+                  <field>
+                     <name>RWDATA</name>
+                     <description>I2C Read/Write Data</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+                  <field>
+                     <name>REGADDR</name>
+                     <description>I2C Register Address</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+                  <field>
+                     <name>ADDR</name>
+                     <description>I2C Address</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>7</bitWidth>
+                  </field>
+                  <field>
+                     <name>I2CEN</name>
+                     <description>I2C Enable</description>
+                     <bitOffset>23</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>ACK</name>
+                     <description>I2C ACK</description>
+                     <bitOffset>24</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>I2CDEVADR</name>
+                     <description>I2C Device Address</description>
+                     <bitOffset>26</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>I2CDATSE0</name>
+                     <description>I2C DatSe0 USB mode</description>
+                     <bitOffset>28</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>RW</name>
+                     <description>Read/Write Indicator</description>
+                     <bitOffset>30</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>BSYDNE</name>
+                     <description>I2C Busy/Done</description>
+                     <bitOffset>31</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_FS_GPWRDN</name>
+               <displayName>OTG_FS_GPWRDN</displayName>
+               <description>OTG power down register</description>
+               <addressOffset>0x58</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x02000400</resetValue>
+               <fields>
+                  <field>
+                     <name>ADPMEN</name>
+                     <description>ADP module enable</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>ADPIF</name>
+                     <description>ADP interrupt flag</description>
+                     <bitOffset>23</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_FS_GADPCTL</name>
+               <displayName>OTG_FS_GADPCTL</displayName>
+               <description>OTG ADP timer, control and status           register</description>
+               <addressOffset>0x60</addressOffset>
+               <size>0x20</size>
+               <resetValue>0x02000400</resetValue>
+               <fields>
+                  <field>
+                     <name>PRBDSCHG</name>
+                     <description>Probe discharge</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>2</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>PRBDELTA</name>
+                     <description>Probe delta</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>2</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>PRBPER</name>
+                     <description>Probe period</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>2</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>RTIM</name>
+                     <description>Ramp time</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>11</bitWidth>
+                     <access>read-only</access>
+                  </field>
+                  <field>
+                     <name>ENAPRB</name>
+                     <description>Enable probe</description>
+                     <bitOffset>17</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>ENASNS</name>
+                     <description>Enable sense</description>
+                     <bitOffset>18</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>ADPRST</name>
+                     <description>ADP reset</description>
+                     <bitOffset>19</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-only</access>
+                  </field>
+                  <field>
+                     <name>ADPEN</name>
+                     <description>ADP enable</description>
+                     <bitOffset>20</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>ADPPRBIF</name>
+                     <description>ADP probe interrupt flag</description>
+                     <bitOffset>21</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>ADPSNSIF</name>
+                     <description>ADP sense interrupt flag</description>
+                     <bitOffset>22</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>ADPTOIF</name>
+                     <description>ADP timeout interrupt flag</description>
+                     <bitOffset>23</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>ADPPRBIM</name>
+                     <description>ADP probe interrupt mask</description>
+                     <bitOffset>24</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>ADPSNSIM</name>
+                     <description>ADP sense interrupt mask</description>
+                     <bitOffset>25</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>ADPTOIM</name>
+                     <description>ADP timeout interrupt mask</description>
+                     <bitOffset>26</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>AR</name>
+                     <description>Access request</description>
+                     <bitOffset>27</bitOffset>
+                     <bitWidth>2</bitWidth>
+                     <access>read-write</access>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_FS_DIEPTXF4</name>
+               <displayName>OTG_FS_DIEPTXF4</displayName>
+               <description>OTG_FS device IN endpoint transmit FIFO size           register (OTG_FS_DIEPTXF4)</description>
+               <addressOffset>0x110</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x02000400</resetValue>
+               <fields>
+                  <field>
+                     <name>INEPTXSA</name>
+                     <description>IN endpoint FIFOx transmit RAM start               address</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+                  <field>
+                     <name>INEPTXFD</name>
+                     <description>IN endpoint Tx FIFO depth</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_FS_DIEPTXF5</name>
+               <displayName>OTG_FS_DIEPTXF5</displayName>
+               <description>OTG_FS device IN endpoint transmit FIFO size           register (OTG_FS_DIEPTXF5)</description>
+               <addressOffset>0x114</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x02000400</resetValue>
+               <fields>
+                  <field>
+                     <name>INEPTXSA</name>
+                     <description>IN endpoint FIFOx transmit RAM start               address</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+                  <field>
+                     <name>INEPTXFD</name>
+                     <description>IN endpoint Tx FIFO depth</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_FS_GLPMCFG</name>
+               <displayName>OTG_FS_GLPMCFG</displayName>
+               <description>OTG core LPM configuration           register</description>
+               <addressOffset>0x54</addressOffset>
+               <size>0x20</size>
+               <resetValue>0x02000400</resetValue>
+               <fields>
+                  <field>
+                     <name>LPMEN</name>
+                     <description>LPM support enable</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>LPMACK</name>
+                     <description>LPM token acknowledge               enable</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>BESL</name>
+                     <description>Best effort service               latency</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>4</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>REMWAKE</name>
+                     <description>bRemoteWake value</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>L1SSEN</name>
+                     <description>L1 Shallow Sleep enable</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>BESLTHRS</name>
+                     <description>BESL threshold</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>4</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>L1DSEN</name>
+                     <description>L1 deep sleep enable</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>LPMRST</name>
+                     <description>LPM response</description>
+                     <bitOffset>13</bitOffset>
+                     <bitWidth>2</bitWidth>
+                     <access>read-only</access>
+                  </field>
+                  <field>
+                     <name>SLPSTS</name>
+                     <description>Port sleep status</description>
+                     <bitOffset>15</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-only</access>
+                  </field>
+                  <field>
+                     <name>L1RSMOK</name>
+                     <description>Sleep State Resume OK</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-only</access>
+                  </field>
+                  <field>
+                     <name>LPMCHIDX</name>
+                     <description>LPM Channel Index</description>
+                     <bitOffset>17</bitOffset>
+                     <bitWidth>4</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>LPMRCNT</name>
+                     <description>LPM retry count</description>
+                     <bitOffset>21</bitOffset>
+                     <bitWidth>3</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>SNDLPM</name>
+                     <description>Send LPM transaction</description>
+                     <bitOffset>24</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>LPMRCNTSTS</name>
+                     <description>LPM retry count status</description>
+                     <bitOffset>25</bitOffset>
+                     <bitWidth>3</bitWidth>
+                     <access>read-only</access>
+                  </field>
+                  <field>
+                     <name>ENBESL</name>
+                     <description>Enable best effort service               latency</description>
+                     <bitOffset>28</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+               </fields>
+            </register>
+         </registers>
+      </peripheral>
+      <peripheral>
+         <name>OTG_HS_GLOBAL</name>
+         <description>USB on the go high speed</description>
+         <groupName>USB_OTG_HS</groupName>
+         <baseAddress>0x40040000</baseAddress>
+         <addressBlock>
+            <offset>0x0</offset>
+            <size>0x400</size>
+            <usage>registers</usage>
+         </addressBlock>
+         <interrupt>
+            <name>OTG_HS_EP1_OUT</name>
+            <description>USB On The Go HS End Point 1 Out global
+        interrupt</description>
+            <value>74</value>
+         </interrupt>
+         <interrupt>
+            <name>OTG_HS_EP1_IN</name>
+            <description>USB On The Go HS End Point 1 In global
+        interrupt</description>
+            <value>75</value>
+         </interrupt>
+         <interrupt>
+            <name>OTG_HS_WKUP</name>
+            <description>USB On The Go HS Wakeup through EXTI
+        interrupt</description>
+            <value>76</value>
+         </interrupt>
+         <interrupt>
+            <name>OTG_HS</name>
+            <description>USB On The Go HS global
+        interrupt</description>
+            <value>77</value>
+         </interrupt>
+         <registers>
+            <register>
+               <name>OTG_HS_GOTGCTL</name>
+               <displayName>OTG_HS_GOTGCTL</displayName>
+               <description>OTG_HS control and status           register</description>
+               <addressOffset>0x0</addressOffset>
+               <size>32</size>
+               <resetValue>0x00000800</resetValue>
+               <fields>
+                  <field>
+                     <name>SRQSCS</name>
+                     <description>Session request success</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-only</access>
+                  </field>
+                  <field>
+                     <name>SRQ</name>
+                     <description>Session request</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>HNGSCS</name>
+                     <description>Host negotiation success</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-only</access>
+                  </field>
+                  <field>
+                     <name>HNPRQ</name>
+                     <description>HNP request</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>HSHNPEN</name>
+                     <description>Host set HNP enable</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>DHNPEN</name>
+                     <description>Device HNP enabled</description>
+                     <bitOffset>11</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>CIDSTS</name>
+                     <description>Connector ID status</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-only</access>
+                  </field>
+                  <field>
+                     <name>DBCT</name>
+                     <description>Long/short debounce time</description>
+                     <bitOffset>17</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-only</access>
+                  </field>
+                  <field>
+                     <name>ASVLD</name>
+                     <description>A-session valid</description>
+                     <bitOffset>18</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-only</access>
+                  </field>
+                  <field>
+                     <name>BSVLD</name>
+                     <description>B-session valid</description>
+                     <bitOffset>19</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-only</access>
+                  </field>
+                  <field>
+                     <name>EHEN</name>
+                     <description>Embedded host enable</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_HS_GOTGINT</name>
+               <displayName>OTG_HS_GOTGINT</displayName>
+               <description>OTG_HS interrupt register</description>
+               <addressOffset>0x4</addressOffset>
+               <size>32</size>
+               <access>read-write</access>
+               <resetValue>0x0</resetValue>
+               <fields>
+                  <field>
+                     <name>SEDET</name>
+                     <description>Session end detected</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>SRSSCHG</name>
+                     <description>Session request success status               change</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>HNSSCHG</name>
+                     <description>Host negotiation success status               change</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>HNGDET</name>
+                     <description>Host negotiation detected</description>
+                     <bitOffset>17</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>ADTOCHG</name>
+                     <description>A-device timeout change</description>
+                     <bitOffset>18</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>DBCDNE</name>
+                     <description>Debounce done</description>
+                     <bitOffset>19</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>IDCHNG</name>
+                     <description>ID input pin changed</description>
+                     <bitOffset>20</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_HS_GAHBCFG</name>
+               <displayName>OTG_HS_GAHBCFG</displayName>
+               <description>OTG_HS AHB configuration           register</description>
+               <addressOffset>0x8</addressOffset>
+               <size>32</size>
+               <access>read-write</access>
+               <resetValue>0x0</resetValue>
+               <fields>
+                  <field>
+                     <name>GINT</name>
+                     <description>Global interrupt mask</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>HBSTLEN</name>
+                     <description>Burst length/type</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+                  <field>
+                     <name>DMAEN</name>
+                     <description>DMA enable</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TXFELVL</name>
+                     <description>TxFIFO empty level</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>PTXFELVL</name>
+                     <description>Periodic TxFIFO empty               level</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_HS_GUSBCFG</name>
+               <displayName>OTG_HS_GUSBCFG</displayName>
+               <description>OTG_HS USB configuration           register</description>
+               <addressOffset>0xC</addressOffset>
+               <size>32</size>
+               <resetValue>0x00000A00</resetValue>
+               <fields>
+                  <field>
+                     <name>TOCAL</name>
+                     <description>FS timeout calibration</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>3</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>PHYSEL</name>
+                     <description>USB 2.0 high-speed ULPI PHY or USB 1.1               full-speed serial transceiver select</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>write-only</access>
+                  </field>
+                  <field>
+                     <name>SRPCAP</name>
+                     <description>SRP-capable</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>HNPCAP</name>
+                     <description>HNP-capable</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>TRDT</name>
+                     <description>USB turnaround time</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>4</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>PHYLPCS</name>
+                     <description>PHY Low-power clock select</description>
+                     <bitOffset>15</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>ULPIFSLS</name>
+                     <description>ULPI FS/LS select</description>
+                     <bitOffset>17</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>ULPIAR</name>
+                     <description>ULPI Auto-resume</description>
+                     <bitOffset>18</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>ULPICSM</name>
+                     <description>ULPI Clock SuspendM</description>
+                     <bitOffset>19</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>ULPIEVBUSD</name>
+                     <description>ULPI External VBUS Drive</description>
+                     <bitOffset>20</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>ULPIEVBUSI</name>
+                     <description>ULPI external VBUS               indicator</description>
+                     <bitOffset>21</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>TSDPS</name>
+                     <description>TermSel DLine pulsing               selection</description>
+                     <bitOffset>22</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>PCCI</name>
+                     <description>Indicator complement</description>
+                     <bitOffset>23</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>PTCI</name>
+                     <description>Indicator pass through</description>
+                     <bitOffset>24</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>ULPIIPD</name>
+                     <description>ULPI interface protect               disable</description>
+                     <bitOffset>25</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>FHMOD</name>
+                     <description>Forced host mode</description>
+                     <bitOffset>29</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>FDMOD</name>
+                     <description>Forced peripheral mode</description>
+                     <bitOffset>30</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_HS_GRSTCTL</name>
+               <displayName>OTG_HS_GRSTCTL</displayName>
+               <description>OTG_HS reset register</description>
+               <addressOffset>0x10</addressOffset>
+               <size>32</size>
+               <resetValue>0x20000000</resetValue>
+               <fields>
+                  <field>
+                     <name>CSRST</name>
+                     <description>Core soft reset</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>HSRST</name>
+                     <description>HCLK soft reset</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>FCRST</name>
+                     <description>Host frame counter reset</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>RXFFLSH</name>
+                     <description>RxFIFO flush</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>TXFFLSH</name>
+                     <description>TxFIFO flush</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>TXFNUM</name>
+                     <description>TxFIFO number</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>5</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>AHBIDL</name>
+                     <description>AHB master idle</description>
+                     <bitOffset>31</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-only</access>
+                  </field>
+                  <field>
+                     <name>DMAREQ</name>
+                     <description>DMA request signal enabled for USB OTG               HS</description>
+                     <bitOffset>30</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-only</access>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_HS_GINTSTS</name>
+               <displayName>OTG_HS_GINTSTS</displayName>
+               <description>OTG_HS core interrupt register</description>
+               <addressOffset>0x14</addressOffset>
+               <size>32</size>
+               <resetValue>0x04000020</resetValue>
+               <fields>
+                  <field>
+                     <name>CMOD</name>
+                     <description>Current mode of operation</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-only</access>
+                  </field>
+                  <field>
+                     <name>MMIS</name>
+                     <description>Mode mismatch interrupt</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>OTGINT</name>
+                     <description>OTG interrupt</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-only</access>
+                  </field>
+                  <field>
+                     <name>SOF</name>
+                     <description>Start of frame</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>RXFLVL</name>
+                     <description>RxFIFO nonempty</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-only</access>
+                  </field>
+                  <field>
+                     <name>NPTXFE</name>
+                     <description>Nonperiodic TxFIFO empty</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-only</access>
+                  </field>
+                  <field>
+                     <name>GINAKEFF</name>
+                     <description>Global IN nonperiodic NAK               effective</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-only</access>
+                  </field>
+                  <field>
+                     <name>BOUTNAKEFF</name>
+                     <description>Global OUT NAK effective</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-only</access>
+                  </field>
+                  <field>
+                     <name>ESUSP</name>
+                     <description>Early suspend</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>USBSUSP</name>
+                     <description>USB suspend</description>
+                     <bitOffset>11</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>USBRST</name>
+                     <description>USB reset</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>ENUMDNE</name>
+                     <description>Enumeration done</description>
+                     <bitOffset>13</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>ISOODRP</name>
+                     <description>Isochronous OUT packet dropped               interrupt</description>
+                     <bitOffset>14</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>EOPF</name>
+                     <description>End of periodic frame               interrupt</description>
+                     <bitOffset>15</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>IEPINT</name>
+                     <description>IN endpoint interrupt</description>
+                     <bitOffset>18</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-only</access>
+                  </field>
+                  <field>
+                     <name>OEPINT</name>
+                     <description>OUT endpoint interrupt</description>
+                     <bitOffset>19</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-only</access>
+                  </field>
+                  <field>
+                     <name>IISOIXFR</name>
+                     <description>Incomplete isochronous IN               transfer</description>
+                     <bitOffset>20</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>PXFR_INCOMPISOOUT</name>
+                     <description>Incomplete periodic               transfer</description>
+                     <bitOffset>21</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>DATAFSUSP</name>
+                     <description>Data fetch suspended</description>
+                     <bitOffset>22</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>HPRTINT</name>
+                     <description>Host port interrupt</description>
+                     <bitOffset>24</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-only</access>
+                  </field>
+                  <field>
+                     <name>HCINT</name>
+                     <description>Host channels interrupt</description>
+                     <bitOffset>25</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-only</access>
+                  </field>
+                  <field>
+                     <name>PTXFE</name>
+                     <description>Periodic TxFIFO empty</description>
+                     <bitOffset>26</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-only</access>
+                  </field>
+                  <field>
+                     <name>CIDSCHG</name>
+                     <description>Connector ID status change</description>
+                     <bitOffset>28</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>DISCINT</name>
+                     <description>Disconnect detected               interrupt</description>
+                     <bitOffset>29</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>SRQINT</name>
+                     <description>Session request/new session detected               interrupt</description>
+                     <bitOffset>30</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>WKUINT</name>
+                     <description>Resume/remote wakeup detected               interrupt</description>
+                     <bitOffset>31</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_HS_GINTMSK</name>
+               <displayName>OTG_HS_GINTMSK</displayName>
+               <description>OTG_HS interrupt mask register</description>
+               <addressOffset>0x18</addressOffset>
+               <size>32</size>
+               <resetValue>0x0</resetValue>
+               <fields>
+                  <field>
+                     <name>MMISM</name>
+                     <description>Mode mismatch interrupt               mask</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>OTGINT</name>
+                     <description>OTG interrupt mask</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>SOFM</name>
+                     <description>Start of frame mask</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>RXFLVLM</name>
+                     <description>Receive FIFO nonempty mask</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>NPTXFEM</name>
+                     <description>Nonperiodic TxFIFO empty               mask</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>GINAKEFFM</name>
+                     <description>Global nonperiodic IN NAK effective               mask</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>GONAKEFFM</name>
+                     <description>Global OUT NAK effective               mask</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>ESUSPM</name>
+                     <description>Early suspend mask</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>USBSUSPM</name>
+                     <description>USB suspend mask</description>
+                     <bitOffset>11</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>USBRST</name>
+                     <description>USB reset mask</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>ENUMDNEM</name>
+                     <description>Enumeration done mask</description>
+                     <bitOffset>13</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>ISOODRPM</name>
+                     <description>Isochronous OUT packet dropped interrupt               mask</description>
+                     <bitOffset>14</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>EOPFM</name>
+                     <description>End of periodic frame interrupt               mask</description>
+                     <bitOffset>15</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>IEPINT</name>
+                     <description>IN endpoints interrupt               mask</description>
+                     <bitOffset>18</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>OEPINT</name>
+                     <description>OUT endpoints interrupt               mask</description>
+                     <bitOffset>19</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>IISOIXFRM</name>
+                     <description>Incomplete isochronous IN transfer               mask</description>
+                     <bitOffset>20</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>PXFRM_IISOOXFRM</name>
+                     <description>Incomplete periodic transfer               mask</description>
+                     <bitOffset>21</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>FSUSPM</name>
+                     <description>Data fetch suspended mask</description>
+                     <bitOffset>22</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>PRTIM</name>
+                     <description>Host port interrupt mask</description>
+                     <bitOffset>24</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-only</access>
+                  </field>
+                  <field>
+                     <name>HCIM</name>
+                     <description>Host channels interrupt               mask</description>
+                     <bitOffset>25</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>PTXFEM</name>
+                     <description>Periodic TxFIFO empty mask</description>
+                     <bitOffset>26</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>CIDSCHGM</name>
+                     <description>Connector ID status change               mask</description>
+                     <bitOffset>28</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>DISCINT</name>
+                     <description>Disconnect detected interrupt               mask</description>
+                     <bitOffset>29</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>SRQIM</name>
+                     <description>Session request/new session detected               interrupt mask</description>
+                     <bitOffset>30</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>WUIM</name>
+                     <description>Resume/remote wakeup detected interrupt               mask</description>
+                     <bitOffset>31</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>RSTDE</name>
+                     <description>Reset detected interrupt               mask</description>
+                     <bitOffset>23</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>LPMINTM</name>
+                     <description>LPM interrupt mask</description>
+                     <bitOffset>27</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_HS_GRXSTSR_Host</name>
+               <displayName>OTG_HS_GRXSTSR_Host</displayName>
+               <description>OTG_HS Receive status debug read register           (host mode)</description>
+               <addressOffset>0x1C</addressOffset>
+               <size>32</size>
+               <access>read-only</access>
+               <resetValue>0x0</resetValue>
+               <fields>
+                  <field>
+                     <name>CHNUM</name>
+                     <description>Channel number</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+                  <field>
+                     <name>BCNT</name>
+                     <description>Byte count</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>11</bitWidth>
+                  </field>
+                  <field>
+                     <name>DPID</name>
+                     <description>Data PID</description>
+                     <bitOffset>15</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>PKTSTS</name>
+                     <description>Packet status</description>
+                     <bitOffset>17</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_HS_GRXSTSP_Host</name>
+               <displayName>OTG_HS_GRXSTSP_Host</displayName>
+               <description>OTG_HS status read and pop register (host           mode)</description>
+               <addressOffset>0x20</addressOffset>
+               <size>32</size>
+               <access>read-only</access>
+               <resetValue>0x0</resetValue>
+               <fields>
+                  <field>
+                     <name>CHNUM</name>
+                     <description>Channel number</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+                  <field>
+                     <name>BCNT</name>
+                     <description>Byte count</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>11</bitWidth>
+                  </field>
+                  <field>
+                     <name>DPID</name>
+                     <description>Data PID</description>
+                     <bitOffset>15</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>PKTSTS</name>
+                     <description>Packet status</description>
+                     <bitOffset>17</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_HS_GRXFSIZ</name>
+               <displayName>OTG_HS_GRXFSIZ</displayName>
+               <description>OTG_HS Receive FIFO size           register</description>
+               <addressOffset>0x24</addressOffset>
+               <size>32</size>
+               <access>read-write</access>
+               <resetValue>0x00000200</resetValue>
+               <fields>
+                  <field>
+                     <name>RXFD</name>
+                     <description>RxFIFO depth</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_HS_HNPTXFSIZ_Host</name>
+               <displayName>OTG_HS_HNPTXFSIZ_Host</displayName>
+               <description>OTG_HS nonperiodic transmit FIFO size           register (host mode)</description>
+               <addressOffset>0x28</addressOffset>
+               <size>32</size>
+               <access>read-write</access>
+               <resetValue>0x00000200</resetValue>
+               <fields>
+                  <field>
+                     <name>NPTXFSA</name>
+                     <description>Nonperiodic transmit RAM start               address</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+                  <field>
+                     <name>NPTXFD</name>
+                     <description>Nonperiodic TxFIFO depth</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_HS_DIEPTXF0_Device</name>
+               <displayName>OTG_HS_DIEPTXF0_Device</displayName>
+               <description>Endpoint 0 transmit FIFO size (peripheral           mode)</description>
+               <alternateRegister>OTG_HS_HNPTXFSIZ_Host</alternateRegister>
+               <addressOffset>0x28</addressOffset>
+               <size>32</size>
+               <access>read-write</access>
+               <resetValue>0x00000200</resetValue>
+               <fields>
+                  <field>
+                     <name>TX0FSA</name>
+                     <description>Endpoint 0 transmit RAM start               address</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+                  <field>
+                     <name>TX0FD</name>
+                     <description>Endpoint 0 TxFIFO depth</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_HS_GNPTXSTS</name>
+               <displayName>OTG_HS_GNPTXSTS</displayName>
+               <description>OTG_HS nonperiodic transmit FIFO/queue           status register</description>
+               <addressOffset>0x2C</addressOffset>
+               <size>32</size>
+               <access>read-only</access>
+               <resetValue>0x00080200</resetValue>
+               <fields>
+                  <field>
+                     <name>NPTXFSAV</name>
+                     <description>Nonperiodic TxFIFO space               available</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+                  <field>
+                     <name>NPTQXSAV</name>
+                     <description>Nonperiodic transmit request queue space               available</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+                  <field>
+                     <name>NPTXQTOP</name>
+                     <description>Top of the nonperiodic transmit request               queue</description>
+                     <bitOffset>24</bitOffset>
+                     <bitWidth>7</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_HS_GCCFG</name>
+               <displayName>OTG_HS_GCCFG</displayName>
+               <description>OTG_HS general core configuration           register</description>
+               <addressOffset>0x38</addressOffset>
+               <size>32</size>
+               <access>read-write</access>
+               <resetValue>0x0</resetValue>
+               <fields>
+                  <field>
+                     <name>PWRDWN</name>
+                     <description>Power down</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>BCDEN</name>
+                     <description>Battery charging detector (BCD)               enable</description>
+                     <bitOffset>17</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>DCDEN</name>
+                     <description>Data contact detection (DCD) mode               enable</description>
+                     <bitOffset>18</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>PDEN</name>
+                     <description>Primary detection (PD) mode               enable</description>
+                     <bitOffset>19</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>SDEN</name>
+                     <description>Secondary detection (SD) mode               enable</description>
+                     <bitOffset>20</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>VBDEN</name>
+                     <description>USB VBUS detection enable</description>
+                     <bitOffset>21</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>DCDET</name>
+                     <description>Data contact detection (DCD)               status</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>PDET</name>
+                     <description>Primary detection (PD)               status</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>SDET</name>
+                     <description>Secondary detection (SD)               status</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>PS2DET</name>
+                     <description>DM pull-up detection               status</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_HS_CID</name>
+               <displayName>OTG_HS_CID</displayName>
+               <description>OTG_HS core ID register</description>
+               <addressOffset>0x3C</addressOffset>
+               <size>32</size>
+               <access>read-write</access>
+               <resetValue>0x00001200</resetValue>
+               <fields>
+                  <field>
+                     <name>PRODUCT_ID</name>
+                     <description>Product ID field</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_HS_HPTXFSIZ</name>
+               <displayName>OTG_HS_HPTXFSIZ</displayName>
+               <description>OTG_HS Host periodic transmit FIFO size           register</description>
+               <addressOffset>0x100</addressOffset>
+               <size>32</size>
+               <access>read-write</access>
+               <resetValue>0x02000600</resetValue>
+               <fields>
+                  <field>
+                     <name>PTXSA</name>
+                     <description>Host periodic TxFIFO start               address</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+                  <field>
+                     <name>PTXFD</name>
+                     <description>Host periodic TxFIFO depth</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_HS_DIEPTXF1</name>
+               <displayName>OTG_HS_DIEPTXF1</displayName>
+               <description>OTG_HS device IN endpoint transmit FIFO size           register</description>
+               <addressOffset>0x104</addressOffset>
+               <size>32</size>
+               <access>read-write</access>
+               <resetValue>0x02000400</resetValue>
+               <fields>
+                  <field>
+                     <name>INEPTXSA</name>
+                     <description>IN endpoint FIFOx transmit RAM start               address</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+                  <field>
+                     <name>INEPTXFD</name>
+                     <description>IN endpoint TxFIFO depth</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_HS_DIEPTXF2</name>
+               <displayName>OTG_HS_DIEPTXF2</displayName>
+               <description>OTG_HS device IN endpoint transmit FIFO size           register</description>
+               <addressOffset>0x108</addressOffset>
+               <size>32</size>
+               <access>read-write</access>
+               <resetValue>0x02000400</resetValue>
+               <fields>
+                  <field>
+                     <name>INEPTXSA</name>
+                     <description>IN endpoint FIFOx transmit RAM start               address</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+                  <field>
+                     <name>INEPTXFD</name>
+                     <description>IN endpoint TxFIFO depth</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_HS_DIEPTXF3</name>
+               <displayName>OTG_HS_DIEPTXF3</displayName>
+               <description>OTG_HS device IN endpoint transmit FIFO size           register</description>
+               <addressOffset>0x11C</addressOffset>
+               <size>32</size>
+               <access>read-write</access>
+               <resetValue>0x02000400</resetValue>
+               <fields>
+                  <field>
+                     <name>INEPTXSA</name>
+                     <description>IN endpoint FIFOx transmit RAM start               address</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+                  <field>
+                     <name>INEPTXFD</name>
+                     <description>IN endpoint TxFIFO depth</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_HS_DIEPTXF4</name>
+               <displayName>OTG_HS_DIEPTXF4</displayName>
+               <description>OTG_HS device IN endpoint transmit FIFO size           register</description>
+               <addressOffset>0x120</addressOffset>
+               <size>32</size>
+               <access>read-write</access>
+               <resetValue>0x02000400</resetValue>
+               <fields>
+                  <field>
+                     <name>INEPTXSA</name>
+                     <description>IN endpoint FIFOx transmit RAM start               address</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+                  <field>
+                     <name>INEPTXFD</name>
+                     <description>IN endpoint TxFIFO depth</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_HS_DIEPTXF5</name>
+               <displayName>OTG_HS_DIEPTXF5</displayName>
+               <description>OTG_HS device IN endpoint transmit FIFO size           register</description>
+               <addressOffset>0x124</addressOffset>
+               <size>32</size>
+               <access>read-write</access>
+               <resetValue>0x02000400</resetValue>
+               <fields>
+                  <field>
+                     <name>INEPTXSA</name>
+                     <description>IN endpoint FIFOx transmit RAM start               address</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+                  <field>
+                     <name>INEPTXFD</name>
+                     <description>IN endpoint TxFIFO depth</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_HS_DIEPTXF6</name>
+               <displayName>OTG_HS_DIEPTXF6</displayName>
+               <description>OTG_HS device IN endpoint transmit FIFO size           register</description>
+               <addressOffset>0x128</addressOffset>
+               <size>32</size>
+               <access>read-write</access>
+               <resetValue>0x02000400</resetValue>
+               <fields>
+                  <field>
+                     <name>INEPTXSA</name>
+                     <description>IN endpoint FIFOx transmit RAM start               address</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+                  <field>
+                     <name>INEPTXFD</name>
+                     <description>IN endpoint TxFIFO depth</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_HS_DIEPTXF7</name>
+               <displayName>OTG_HS_DIEPTXF7</displayName>
+               <description>OTG_HS device IN endpoint transmit FIFO size           register</description>
+               <addressOffset>0x12C</addressOffset>
+               <size>32</size>
+               <access>read-write</access>
+               <resetValue>0x02000400</resetValue>
+               <fields>
+                  <field>
+                     <name>INEPTXSA</name>
+                     <description>IN endpoint FIFOx transmit RAM start               address</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+                  <field>
+                     <name>INEPTXFD</name>
+                     <description>IN endpoint TxFIFO depth</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_HS_GRXSTSR_Device</name>
+               <displayName>OTG_HS_GRXSTSR_Device</displayName>
+               <description>OTG_HS Receive status debug read register           (peripheral mode mode)</description>
+               <alternateRegister>OTG_HS_GRXSTSR_Host</alternateRegister>
+               <addressOffset>0x1C</addressOffset>
+               <size>32</size>
+               <access>read-only</access>
+               <resetValue>0x0</resetValue>
+               <fields>
+                  <field>
+                     <name>EPNUM</name>
+                     <description>Endpoint number</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+                  <field>
+                     <name>BCNT</name>
+                     <description>Byte count</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>11</bitWidth>
+                  </field>
+                  <field>
+                     <name>DPID</name>
+                     <description>Data PID</description>
+                     <bitOffset>15</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>PKTSTS</name>
+                     <description>Packet status</description>
+                     <bitOffset>17</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+                  <field>
+                     <name>FRMNUM</name>
+                     <description>Frame number</description>
+                     <bitOffset>21</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_HS_GRXSTSP_Device</name>
+               <displayName>OTG_HS_GRXSTSP_Device</displayName>
+               <description>OTG_HS status read and pop register           (peripheral mode)</description>
+               <alternateRegister>OTG_HS_GRXSTSP_Host</alternateRegister>
+               <addressOffset>0x20</addressOffset>
+               <size>32</size>
+               <access>read-only</access>
+               <resetValue>0x0</resetValue>
+               <fields>
+                  <field>
+                     <name>EPNUM</name>
+                     <description>Endpoint number</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+                  <field>
+                     <name>BCNT</name>
+                     <description>Byte count</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>11</bitWidth>
+                  </field>
+                  <field>
+                     <name>DPID</name>
+                     <description>Data PID</description>
+                     <bitOffset>15</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>PKTSTS</name>
+                     <description>Packet status</description>
+                     <bitOffset>17</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+                  <field>
+                     <name>FRMNUM</name>
+                     <description>Frame number</description>
+                     <bitOffset>21</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_HS_GLPMCFG</name>
+               <displayName>OTG_HS_GLPMCFG</displayName>
+               <description>OTG core LPM configuration           register</description>
+               <addressOffset>0x54</addressOffset>
+               <size>32</size>
+               <resetValue>0x0</resetValue>
+               <fields>
+                  <field>
+                     <name>LPMEN</name>
+                     <description>LPM support enable</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>LPMACK</name>
+                     <description>LPM token acknowledge               enable</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>BESL</name>
+                     <description>Best effort service               latency</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>4</bitWidth>
+                     <access>read-only</access>
+                  </field>
+                  <field>
+                     <name>REMWAKE</name>
+                     <description>bRemoteWake value</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-only</access>
+                  </field>
+                  <field>
+                     <name>L1SSEN</name>
+                     <description>L1 Shallow Sleep enable</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>BESLTHRS</name>
+                     <description>BESL threshold</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>4</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>L1DSEN</name>
+                     <description>L1 deep sleep enable</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>LPMRST</name>
+                     <description>LPM response</description>
+                     <bitOffset>13</bitOffset>
+                     <bitWidth>2</bitWidth>
+                     <access>read-only</access>
+                  </field>
+                  <field>
+                     <name>SLPSTS</name>
+                     <description>Port sleep status</description>
+                     <bitOffset>15</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-only</access>
+                  </field>
+                  <field>
+                     <name>L1RSMOK</name>
+                     <description>Sleep State Resume OK</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-only</access>
+                  </field>
+                  <field>
+                     <name>LPMCHIDX</name>
+                     <description>LPM Channel Index</description>
+                     <bitOffset>17</bitOffset>
+                     <bitWidth>4</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>LPMRCNT</name>
+                     <description>LPM retry count</description>
+                     <bitOffset>21</bitOffset>
+                     <bitWidth>3</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>SNDLPM</name>
+                     <description>Send LPM transaction</description>
+                     <bitOffset>24</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>LPMRCNTSTS</name>
+                     <description>LPM retry count status</description>
+                     <bitOffset>25</bitOffset>
+                     <bitWidth>3</bitWidth>
+                     <access>read-only</access>
+                  </field>
+                  <field>
+                     <name>ENBESL</name>
+                     <description>Enable best effort service               latency</description>
+                     <bitOffset>28</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+               </fields>
+            </register>
+         </registers>
+      </peripheral>
+      <peripheral>
+         <name>MDIOS</name>
+         <description>Management data input/output slave</description>
+         <groupName>MDIOS</groupName>
+         <baseAddress>0x40017800</baseAddress>
+         <addressBlock>
+            <offset>0x0</offset>
+            <size>0x400</size>
+            <usage>registers</usage>
+         </addressBlock>
+         <interrupt>
+            <name>MDIOS</name>
+            <description>MDIO slave global interrupt</description>
+            <value>109</value>
+         </interrupt>
+         <registers>
+            <register>
+               <name>MDIOS_CR</name>
+               <displayName>MDIOS_CR</displayName>
+               <description>MDIOS configuration register</description>
+               <addressOffset>0x0</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>EN</name>
+                     <description>Peripheral enable</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>WRIE</name>
+                     <description>Register write interrupt               enable</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>RDIE</name>
+                     <description>Register Read Interrupt               Enable</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>EIE</name>
+                     <description>Error interrupt enable</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>DPC</name>
+                     <description>Disable Preamble Check</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>PORT_ADDRESS</name>
+                     <description>Slaves's address</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>5</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>MDIOS_WRFR</name>
+               <displayName>MDIOS_WRFR</displayName>
+               <description>MDIOS write flag register</description>
+               <addressOffset>0x4</addressOffset>
+               <size>0x20</size>
+               <access>read-only</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>WRF</name>
+                     <description>Write flags for MDIO registers 0 to               31</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>MDIOS_CWRFR</name>
+               <displayName>MDIOS_CWRFR</displayName>
+               <description>MDIOS clear write flag           register</description>
+               <addressOffset>0x8</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>CWRF</name>
+                     <description>Clear the write flag</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>MDIOS_RDFR</name>
+               <displayName>MDIOS_RDFR</displayName>
+               <description>MDIOS read flag register</description>
+               <addressOffset>0xC</addressOffset>
+               <size>0x20</size>
+               <access>read-only</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>RDF</name>
+                     <description>Read flags for MDIO registers 0 to               31</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>MDIOS_CRDFR</name>
+               <displayName>MDIOS_CRDFR</displayName>
+               <description>MDIOS clear read flag register</description>
+               <addressOffset>0x10</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>CRDF</name>
+                     <description>Clear the read flag</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>MDIOS_SR</name>
+               <displayName>MDIOS_SR</displayName>
+               <description>MDIOS status register</description>
+               <addressOffset>0x14</addressOffset>
+               <size>0x20</size>
+               <access>read-only</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>PERF</name>
+                     <description>Preamble error flag</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>SERF</name>
+                     <description>Start error flag</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TERF</name>
+                     <description>Turnaround error flag</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>MDIOS_CLRFR</name>
+               <displayName>MDIOS_CLRFR</displayName>
+               <description>MDIOS clear flag register</description>
+               <addressOffset>0x18</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>CPERF</name>
+                     <description>Clear the preamble error               flag</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CSERF</name>
+                     <description>Clear the start error flag</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CTERF</name>
+                     <description>Clear the turnaround error               flag</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>MDIOS_DINR0</name>
+               <displayName>MDIOS_DINR0</displayName>
+               <description>MDIOS input data register 0</description>
+               <addressOffset>0x1C</addressOffset>
+               <size>0x20</size>
+               <access>read-only</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DIN0</name>
+                     <description>Input data received from MDIO Master               during write frames</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>MDIOS_DINR1</name>
+               <displayName>MDIOS_DINR1</displayName>
+               <description>MDIOS input data register 1</description>
+               <addressOffset>0x20</addressOffset>
+               <size>0x20</size>
+               <access>read-only</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DIN1</name>
+                     <description>Input data received from MDIO Master               during write frames</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>MDIOS_DINR2</name>
+               <displayName>MDIOS_DINR2</displayName>
+               <description>MDIOS input data register 2</description>
+               <addressOffset>0x24</addressOffset>
+               <size>0x20</size>
+               <access>read-only</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DIN2</name>
+                     <description>Input data received from MDIO Master               during write frames</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>MDIOS_DINR3</name>
+               <displayName>MDIOS_DINR3</displayName>
+               <description>MDIOS input data register 3</description>
+               <addressOffset>0x28</addressOffset>
+               <size>0x20</size>
+               <access>read-only</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DIN3</name>
+                     <description>Input data received from MDIO Master               during write frames</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>MDIOS_DINR4</name>
+               <displayName>MDIOS_DINR4</displayName>
+               <description>MDIOS input data register 4</description>
+               <addressOffset>0x2C</addressOffset>
+               <size>0x20</size>
+               <access>read-only</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DIN4</name>
+                     <description>Input data received from MDIO Master               during write frames</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>MDIOS_DINR5</name>
+               <displayName>MDIOS_DINR5</displayName>
+               <description>MDIOS input data register 5</description>
+               <addressOffset>0x30</addressOffset>
+               <size>0x20</size>
+               <access>read-only</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DIN5</name>
+                     <description>Input data received from MDIO Master               during write frames</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>MDIOS_DINR6</name>
+               <displayName>MDIOS_DINR6</displayName>
+               <description>MDIOS input data register 6</description>
+               <addressOffset>0x34</addressOffset>
+               <size>0x20</size>
+               <access>read-only</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DIN6</name>
+                     <description>Input data received from MDIO Master               during write frames</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>MDIOS_DINR7</name>
+               <displayName>MDIOS_DINR7</displayName>
+               <description>MDIOS input data register 7</description>
+               <addressOffset>0x38</addressOffset>
+               <size>0x20</size>
+               <access>read-only</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DIN7</name>
+                     <description>Input data received from MDIO Master               during write frames</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>MDIOS_DINR8</name>
+               <displayName>MDIOS_DINR8</displayName>
+               <description>MDIOS input data register 8</description>
+               <addressOffset>0x3C</addressOffset>
+               <size>0x20</size>
+               <access>read-only</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DIN8</name>
+                     <description>Input data received from MDIO Master               during write frames</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>MDIOS_DINR9</name>
+               <displayName>MDIOS_DINR9</displayName>
+               <description>MDIOS input data register 9</description>
+               <addressOffset>0x40</addressOffset>
+               <size>0x20</size>
+               <access>read-only</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DIN9</name>
+                     <description>Input data received from MDIO Master               during write frames</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>MDIOS_DINR10</name>
+               <displayName>MDIOS_DINR10</displayName>
+               <description>MDIOS input data register 10</description>
+               <addressOffset>0x44</addressOffset>
+               <size>0x20</size>
+               <access>read-only</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DIN10</name>
+                     <description>Input data received from MDIO Master               during write frames</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>MDIOS_DINR11</name>
+               <displayName>MDIOS_DINR11</displayName>
+               <description>MDIOS input data register 11</description>
+               <addressOffset>0x48</addressOffset>
+               <size>0x20</size>
+               <access>read-only</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DIN11</name>
+                     <description>Input data received from MDIO Master               during write frames</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>MDIOS_DINR12</name>
+               <displayName>MDIOS_DINR12</displayName>
+               <description>MDIOS input data register 12</description>
+               <addressOffset>0x4C</addressOffset>
+               <size>0x20</size>
+               <access>read-only</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DIN12</name>
+                     <description>Input data received from MDIO Master               during write frames</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>MDIOS_DINR13</name>
+               <displayName>MDIOS_DINR13</displayName>
+               <description>MDIOS input data register 13</description>
+               <addressOffset>0x50</addressOffset>
+               <size>0x20</size>
+               <access>read-only</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DIN13</name>
+                     <description>Input data received from MDIO Master               during write frames</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>MDIOS_DINR14</name>
+               <displayName>MDIOS_DINR14</displayName>
+               <description>MDIOS input data register 14</description>
+               <addressOffset>0x54</addressOffset>
+               <size>0x20</size>
+               <access>read-only</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DIN14</name>
+                     <description>Input data received from MDIO Master               during write frames</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>MDIOS_DINR15</name>
+               <displayName>MDIOS_DINR15</displayName>
+               <description>MDIOS input data register 15</description>
+               <addressOffset>0x58</addressOffset>
+               <size>0x20</size>
+               <access>read-only</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DIN15</name>
+                     <description>Input data received from MDIO Master               during write frames</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>MDIOS_DINR16</name>
+               <displayName>MDIOS_DINR16</displayName>
+               <description>MDIOS input data register 16</description>
+               <addressOffset>0x5C</addressOffset>
+               <size>0x20</size>
+               <access>read-only</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DIN16</name>
+                     <description>Input data received from MDIO Master               during write frames</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>MDIOS_DINR17</name>
+               <displayName>MDIOS_DINR17</displayName>
+               <description>MDIOS input data register 17</description>
+               <addressOffset>0x60</addressOffset>
+               <size>0x20</size>
+               <access>read-only</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DIN17</name>
+                     <description>Input data received from MDIO Master               during write frames</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>MDIOS_DINR18</name>
+               <displayName>MDIOS_DINR18</displayName>
+               <description>MDIOS input data register 18</description>
+               <addressOffset>0x64</addressOffset>
+               <size>0x20</size>
+               <access>read-only</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DIN18</name>
+                     <description>Input data received from MDIO Master               during write frames</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>MDIOS_DINR19</name>
+               <displayName>MDIOS_DINR19</displayName>
+               <description>MDIOS input data register 19</description>
+               <addressOffset>0x68</addressOffset>
+               <size>0x20</size>
+               <access>read-only</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DIN19</name>
+                     <description>Input data received from MDIO Master               during write frames</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>MDIOS_DINR20</name>
+               <displayName>MDIOS_DINR20</displayName>
+               <description>MDIOS input data register 20</description>
+               <addressOffset>0x6C</addressOffset>
+               <size>0x20</size>
+               <access>read-only</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DIN20</name>
+                     <description>Input data received from MDIO Master               during write frames</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>MDIOS_DINR21</name>
+               <displayName>MDIOS_DINR21</displayName>
+               <description>MDIOS input data register 21</description>
+               <addressOffset>0x70</addressOffset>
+               <size>0x20</size>
+               <access>read-only</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DIN21</name>
+                     <description>Input data received from MDIO Master               during write frames</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>MDIOS_DINR22</name>
+               <displayName>MDIOS_DINR22</displayName>
+               <description>MDIOS input data register 22</description>
+               <addressOffset>0x74</addressOffset>
+               <size>0x20</size>
+               <access>read-only</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DIN22</name>
+                     <description>Input data received from MDIO Master               during write frames</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>MDIOS_DINR23</name>
+               <displayName>MDIOS_DINR23</displayName>
+               <description>MDIOS input data register 23</description>
+               <addressOffset>0x78</addressOffset>
+               <size>0x20</size>
+               <access>read-only</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DIN23</name>
+                     <description>Input data received from MDIO Master               during write frames</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>MDIOS_DINR24</name>
+               <displayName>MDIOS_DINR24</displayName>
+               <description>MDIOS input data register 24</description>
+               <addressOffset>0x7C</addressOffset>
+               <size>0x20</size>
+               <access>read-only</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DIN24</name>
+                     <description>Input data received from MDIO Master               during write frames</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>MDIOS_DINR25</name>
+               <displayName>MDIOS_DINR25</displayName>
+               <description>MDIOS input data register 25</description>
+               <addressOffset>0x80</addressOffset>
+               <size>0x20</size>
+               <access>read-only</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DIN25</name>
+                     <description>Input data received from MDIO Master               during write frames</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>MDIOS_DINR26</name>
+               <displayName>MDIOS_DINR26</displayName>
+               <description>MDIOS input data register 26</description>
+               <addressOffset>0x84</addressOffset>
+               <size>0x20</size>
+               <access>read-only</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DIN26</name>
+                     <description>Input data received from MDIO Master               during write frames</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>MDIOS_DINR27</name>
+               <displayName>MDIOS_DINR27</displayName>
+               <description>MDIOS input data register 27</description>
+               <addressOffset>0x88</addressOffset>
+               <size>0x20</size>
+               <access>read-only</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DIN27</name>
+                     <description>Input data received from MDIO Master               during write frames</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>MDIOS_DINR28</name>
+               <displayName>MDIOS_DINR28</displayName>
+               <description>MDIOS input data register 28</description>
+               <addressOffset>0x8C</addressOffset>
+               <size>0x20</size>
+               <access>read-only</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DIN28</name>
+                     <description>Input data received from MDIO Master               during write frames</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>MDIOS_DINR29</name>
+               <displayName>MDIOS_DINR29</displayName>
+               <description>MDIOS input data register 29</description>
+               <addressOffset>0x90</addressOffset>
+               <size>0x20</size>
+               <access>read-only</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DIN29</name>
+                     <description>Input data received from MDIO Master               during write frames</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>MDIOS_DINR30</name>
+               <displayName>MDIOS_DINR30</displayName>
+               <description>MDIOS input data register 30</description>
+               <addressOffset>0x94</addressOffset>
+               <size>0x20</size>
+               <access>read-only</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DIN30</name>
+                     <description>Input data received from MDIO Master               during write frames</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>MDIOS_DINR31</name>
+               <displayName>MDIOS_DINR31</displayName>
+               <description>MDIOS input data register 31</description>
+               <addressOffset>0x98</addressOffset>
+               <size>0x20</size>
+               <access>read-only</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DIN31</name>
+                     <description>Input data received from MDIO Master               during write frames</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>MDIOS_DOUTR0</name>
+               <displayName>MDIOS_DOUTR0</displayName>
+               <description>MDIOS output data register 0</description>
+               <addressOffset>0x9C</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DOUT0</name>
+                     <description>Output data sent to MDIO Master during               read frames</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>MDIOS_DOUTR1</name>
+               <displayName>MDIOS_DOUTR1</displayName>
+               <description>MDIOS output data register 1</description>
+               <addressOffset>0xA0</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DOUT1</name>
+                     <description>Output data sent to MDIO Master during               read frames</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>MDIOS_DOUTR2</name>
+               <displayName>MDIOS_DOUTR2</displayName>
+               <description>MDIOS output data register 2</description>
+               <addressOffset>0xA4</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DOUT2</name>
+                     <description>Output data sent to MDIO Master during               read frames</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>MDIOS_DOUTR3</name>
+               <displayName>MDIOS_DOUTR3</displayName>
+               <description>MDIOS output data register 3</description>
+               <addressOffset>0xA8</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DOUT3</name>
+                     <description>Output data sent to MDIO Master during               read frames</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>MDIOS_DOUTR4</name>
+               <displayName>MDIOS_DOUTR4</displayName>
+               <description>MDIOS output data register 4</description>
+               <addressOffset>0xAC</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DOUT4</name>
+                     <description>Output data sent to MDIO Master during               read frames</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>MDIOS_DOUTR5</name>
+               <displayName>MDIOS_DOUTR5</displayName>
+               <description>MDIOS output data register 5</description>
+               <addressOffset>0xB0</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DOUT5</name>
+                     <description>Output data sent to MDIO Master during               read frames</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>MDIOS_DOUTR6</name>
+               <displayName>MDIOS_DOUTR6</displayName>
+               <description>MDIOS output data register 6</description>
+               <addressOffset>0xB4</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DOUT6</name>
+                     <description>Output data sent to MDIO Master during               read frames</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>MDIOS_DOUTR7</name>
+               <displayName>MDIOS_DOUTR7</displayName>
+               <description>MDIOS output data register 7</description>
+               <addressOffset>0xB8</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DOUT7</name>
+                     <description>Output data sent to MDIO Master during               read frames</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>MDIOS_DOUTR8</name>
+               <displayName>MDIOS_DOUTR8</displayName>
+               <description>MDIOS output data register 8</description>
+               <addressOffset>0xBC</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DOUT8</name>
+                     <description>Output data sent to MDIO Master during               read frames</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>MDIOS_DOUTR9</name>
+               <displayName>MDIOS_DOUTR9</displayName>
+               <description>MDIOS output data register 9</description>
+               <addressOffset>0xC0</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DOUT9</name>
+                     <description>Output data sent to MDIO Master during               read frames</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>MDIOS_DOUTR10</name>
+               <displayName>MDIOS_DOUTR10</displayName>
+               <description>MDIOS output data register 10</description>
+               <addressOffset>0xC4</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DOUT10</name>
+                     <description>Output data sent to MDIO Master during               read frames</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>MDIOS_DOUTR11</name>
+               <displayName>MDIOS_DOUTR11</displayName>
+               <description>MDIOS output data register 11</description>
+               <addressOffset>0xC8</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DOUT11</name>
+                     <description>Output data sent to MDIO Master during               read frames</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>MDIOS_DOUTR12</name>
+               <displayName>MDIOS_DOUTR12</displayName>
+               <description>MDIOS output data register 12</description>
+               <addressOffset>0xCC</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DOUT12</name>
+                     <description>Output data sent to MDIO Master during               read frames</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>MDIOS_DOUTR13</name>
+               <displayName>MDIOS_DOUTR13</displayName>
+               <description>MDIOS output data register 13</description>
+               <addressOffset>0xD0</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DOUT13</name>
+                     <description>Output data sent to MDIO Master during               read frames</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>MDIOS_DOUTR14</name>
+               <displayName>MDIOS_DOUTR14</displayName>
+               <description>MDIOS output data register 14</description>
+               <addressOffset>0xD4</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DOUT14</name>
+                     <description>Output data sent to MDIO Master during               read frames</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>MDIOS_DOUTR15</name>
+               <displayName>MDIOS_DOUTR15</displayName>
+               <description>MDIOS output data register 15</description>
+               <addressOffset>0xD8</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DOUT15</name>
+                     <description>Output data sent to MDIO Master during               read frames</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>MDIOS_DOUTR16</name>
+               <displayName>MDIOS_DOUTR16</displayName>
+               <description>MDIOS output data register 16</description>
+               <addressOffset>0xDC</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DOUT16</name>
+                     <description>Output data sent to MDIO Master during               read frames</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>MDIOS_DOUTR17</name>
+               <displayName>MDIOS_DOUTR17</displayName>
+               <description>MDIOS output data register 17</description>
+               <addressOffset>0xE0</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DOUT17</name>
+                     <description>Output data sent to MDIO Master during               read frames</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>MDIOS_DOUTR18</name>
+               <displayName>MDIOS_DOUTR18</displayName>
+               <description>MDIOS output data register 18</description>
+               <addressOffset>0xE4</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DOUT18</name>
+                     <description>Output data sent to MDIO Master during               read frames</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>MDIOS_DOUTR19</name>
+               <displayName>MDIOS_DOUTR19</displayName>
+               <description>MDIOS output data register 19</description>
+               <addressOffset>0xE8</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DOUT19</name>
+                     <description>Output data sent to MDIO Master during               read frames</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>MDIOS_DOUTR20</name>
+               <displayName>MDIOS_DOUTR20</displayName>
+               <description>MDIOS output data register 20</description>
+               <addressOffset>0xEC</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DOUT20</name>
+                     <description>Output data sent to MDIO Master during               read frames</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>MDIOS_DOUTR21</name>
+               <displayName>MDIOS_DOUTR21</displayName>
+               <description>MDIOS output data register 21</description>
+               <addressOffset>0xF0</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DOUT21</name>
+                     <description>Output data sent to MDIO Master during               read frames</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>MDIOS_DOUTR22</name>
+               <displayName>MDIOS_DOUTR22</displayName>
+               <description>MDIOS output data register 22</description>
+               <addressOffset>0xF4</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DOUT22</name>
+                     <description>Output data sent to MDIO Master during               read frames</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>MDIOS_DOUTR23</name>
+               <displayName>MDIOS_DOUTR23</displayName>
+               <description>MDIOS output data register 23</description>
+               <addressOffset>0xF8</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DOUT23</name>
+                     <description>Output data sent to MDIO Master during               read frames</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>MDIOS_DOUTR24</name>
+               <displayName>MDIOS_DOUTR24</displayName>
+               <description>MDIOS output data register 24</description>
+               <addressOffset>0xFC</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DOUT24</name>
+                     <description>Output data sent to MDIO Master during               read frames</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>MDIOS_DOUTR25</name>
+               <displayName>MDIOS_DOUTR25</displayName>
+               <description>MDIOS output data register 25</description>
+               <addressOffset>0x100</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DOUT25</name>
+                     <description>Output data sent to MDIO Master during               read frames</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>MDIOS_DOUTR26</name>
+               <displayName>MDIOS_DOUTR26</displayName>
+               <description>MDIOS output data register 26</description>
+               <addressOffset>0x104</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DOUT26</name>
+                     <description>Output data sent to MDIO Master during               read frames</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>MDIOS_DOUTR27</name>
+               <displayName>MDIOS_DOUTR27</displayName>
+               <description>MDIOS output data register 27</description>
+               <addressOffset>0x108</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DOUT27</name>
+                     <description>Output data sent to MDIO Master during               read frames</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>MDIOS_DOUTR28</name>
+               <displayName>MDIOS_DOUTR28</displayName>
+               <description>MDIOS output data register 28</description>
+               <addressOffset>0x10C</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DOUT28</name>
+                     <description>Output data sent to MDIO Master during               read frames</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>MDIOS_DOUTR29</name>
+               <displayName>MDIOS_DOUTR29</displayName>
+               <description>MDIOS output data register 29</description>
+               <addressOffset>0x110</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DOUT29</name>
+                     <description>Output data sent to MDIO Master during               read frames</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>MDIOS_DOUTR30</name>
+               <displayName>MDIOS_DOUTR30</displayName>
+               <description>MDIOS output data register 30</description>
+               <addressOffset>0x114</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DOUT30</name>
+                     <description>Output data sent to MDIO Master during               read frames</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>MDIOS_DOUTR31</name>
+               <displayName>MDIOS_DOUTR31</displayName>
+               <description>MDIOS output data register 31</description>
+               <addressOffset>0x118</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DOUT31</name>
+                     <description>Output data sent to MDIO Master during               read frames</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+               </fields>
+            </register>
+         </registers>
+      </peripheral>
+      <peripheral>
+         <name>DFSDM</name>
+         <description>Digital filter for sigma delta       modulators</description>
+         <groupName>DFSDM</groupName>
+         <baseAddress>0x40017400</baseAddress>
+         <addressBlock>
+            <offset>0x0</offset>
+            <size>0x400</size>
+            <usage>registers</usage>
+         </addressBlock>
+         <interrupt>
+            <name>DFSDM1_FLT0</name>
+            <description>DFSDM1 Filter 0 global interrupt</description>
+            <value>99</value>
+         </interrupt>
+         <interrupt>
+            <name>DFSDM1_FLT1</name>
+            <description>DFSDM1 Filter 1 global interrupt</description>
+            <value>100</value>
+         </interrupt>
+         <interrupt>
+            <name>DFSDM1_FLT2</name>
+            <description>DFSDM1 Filter 2 global interrupt</description>
+            <value>101</value>
+         </interrupt>
+         <interrupt>
+            <name>DFSDM1_FLT3</name>
+            <description>DFSDM1 Filter 3 global interrupt</description>
+            <value>102</value>
+         </interrupt>
+         <registers>
+            <register>
+               <name>DFSDM_CHCFG0R1</name>
+               <displayName>DFSDM_CHCFG0R1</displayName>
+               <description>DFSDM channel configuration 0 register           1</description>
+               <addressOffset>0x0</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>SITP</name>
+                     <description>Serial interface type for channel               0</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>SPICKSEL</name>
+                     <description>SPI clock select for channel               0</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>SCDEN</name>
+                     <description>Short-circuit detector enable on channel               0</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CKABEN</name>
+                     <description>Clock absence detector enable on channel               0</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CHEN</name>
+                     <description>Channel 0 enable</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CHINSEL</name>
+                     <description>Channel inputs selection</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>DATMPX</name>
+                     <description>Input data multiplexer for channel               0</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>DATPACK</name>
+                     <description>Data packing mode in DFSDM_CHDATINyR               register</description>
+                     <bitOffset>14</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>CKOUTDIV</name>
+                     <description>Output serial clock               divider</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+                  <field>
+                     <name>CKOUTSRC</name>
+                     <description>Output serial clock source               selection</description>
+                     <bitOffset>30</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>DFSDMEN</name>
+                     <description>Global enable for DFSDM               interface</description>
+                     <bitOffset>31</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DFSDM_CHCFG1R1</name>
+               <displayName>DFSDM_CHCFG1R1</displayName>
+               <description>DFSDM channel configuration 1 register           1</description>
+               <addressOffset>0x20</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>SITP</name>
+                     <description>Serial interface type for channel               1</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>SPICKSEL</name>
+                     <description>SPI clock select for channel               1</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>SCDEN</name>
+                     <description>Short-circuit detector enable on channel               1</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CKABEN</name>
+                     <description>Clock absence detector enable on channel               1</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CHEN</name>
+                     <description>Channel 1 enable</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CHINSEL</name>
+                     <description>Channel inputs selection</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>DATMPX</name>
+                     <description>Input data multiplexer for channel               1</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>DATPACK</name>
+                     <description>Data packing mode in DFSDM_CHDATINyR               register</description>
+                     <bitOffset>14</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>CKOUTDIV</name>
+                     <description>Output serial clock               divider</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+                  <field>
+                     <name>CKOUTSRC</name>
+                     <description>Output serial clock source               selection</description>
+                     <bitOffset>30</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>DFSDMEN</name>
+                     <description>Global enable for DFSDM               interface</description>
+                     <bitOffset>31</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DFSDM_CHCFG2R1</name>
+               <displayName>DFSDM_CHCFG2R1</displayName>
+               <description>DFSDM channel configuration 2 register           1</description>
+               <addressOffset>0x40</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>SITP</name>
+                     <description>Serial interface type for channel               2</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>SPICKSEL</name>
+                     <description>SPI clock select for channel               2</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>SCDEN</name>
+                     <description>Short-circuit detector enable on channel               2</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CKABEN</name>
+                     <description>Clock absence detector enable on channel               2</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CHEN</name>
+                     <description>Channel 2 enable</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CHINSEL</name>
+                     <description>Channel inputs selection</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>DATMPX</name>
+                     <description>Input data multiplexer for channel               2</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>DATPACK</name>
+                     <description>Data packing mode in DFSDM_CHDATINyR               register</description>
+                     <bitOffset>14</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>CKOUTDIV</name>
+                     <description>Output serial clock               divider</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+                  <field>
+                     <name>CKOUTSRC</name>
+                     <description>Output serial clock source               selection</description>
+                     <bitOffset>30</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>DFSDMEN</name>
+                     <description>Global enable for DFSDM               interface</description>
+                     <bitOffset>31</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DFSDM_CHCFG3R1</name>
+               <displayName>DFSDM_CHCFG3R1</displayName>
+               <description>DFSDM channel configuration 3 register           1</description>
+               <addressOffset>0x60</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>SITP</name>
+                     <description>Serial interface type for channel               3</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>SPICKSEL</name>
+                     <description>SPI clock select for channel               3</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>SCDEN</name>
+                     <description>Short-circuit detector enable on channel               3</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CKABEN</name>
+                     <description>Clock absence detector enable on channel               3</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CHEN</name>
+                     <description>Channel 3 enable</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CHINSEL</name>
+                     <description>Channel inputs selection</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>DATMPX</name>
+                     <description>Input data multiplexer for channel               3</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>DATPACK</name>
+                     <description>Data packing mode in DFSDM_CHDATINyR               register</description>
+                     <bitOffset>14</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>CKOUTDIV</name>
+                     <description>Output serial clock               divider</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+                  <field>
+                     <name>CKOUTSRC</name>
+                     <description>Output serial clock source               selection</description>
+                     <bitOffset>30</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>DFSDMEN</name>
+                     <description>Global enable for DFSDM               interface</description>
+                     <bitOffset>31</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DFSDM_CHCFG4R1</name>
+               <displayName>DFSDM_CHCFG4R1</displayName>
+               <description>DFSDM channel configuration 4 register           1</description>
+               <addressOffset>0x80</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>SITP</name>
+                     <description>Serial interface type for channel               4</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>SPICKSEL</name>
+                     <description>SPI clock select for channel               4</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>SCDEN</name>
+                     <description>Short-circuit detector enable on channel               4</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CKABEN</name>
+                     <description>Clock absence detector enable on channel               4</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CHEN</name>
+                     <description>Channel 4 enable</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CHINSEL</name>
+                     <description>Channel inputs selection</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>DATMPX</name>
+                     <description>Input data multiplexer for channel               4</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>DATPACK</name>
+                     <description>Data packing mode in DFSDM_CHDATINyR               register</description>
+                     <bitOffset>14</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>CKOUTDIV</name>
+                     <description>Output serial clock               divider</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+                  <field>
+                     <name>CKOUTSRC</name>
+                     <description>Output serial clock source               selection</description>
+                     <bitOffset>30</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>DFSDMEN</name>
+                     <description>Global enable for DFSDM               interface</description>
+                     <bitOffset>31</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DFSDM_CHCFG5R1</name>
+               <displayName>DFSDM_CHCFG5R1</displayName>
+               <description>DFSDM channel configuration 5 register           1</description>
+               <addressOffset>0xA0</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>SITP</name>
+                     <description>Serial interface type for channel               5</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>SPICKSEL</name>
+                     <description>SPI clock select for channel               5</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>SCDEN</name>
+                     <description>Short-circuit detector enable on channel               5</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CKABEN</name>
+                     <description>Clock absence detector enable on channel               5</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CHEN</name>
+                     <description>Channel 5 enable</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CHINSEL</name>
+                     <description>Channel inputs selection</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>DATMPX</name>
+                     <description>Input data multiplexer for channel               5</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>DATPACK</name>
+                     <description>Data packing mode in DFSDM_CHDATINyR               register</description>
+                     <bitOffset>14</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>CKOUTDIV</name>
+                     <description>Output serial clock               divider</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+                  <field>
+                     <name>CKOUTSRC</name>
+                     <description>Output serial clock source               selection</description>
+                     <bitOffset>30</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>DFSDMEN</name>
+                     <description>Global enable for DFSDM               interface</description>
+                     <bitOffset>31</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DFSDM_CHCFG6R1</name>
+               <displayName>DFSDM_CHCFG6R1</displayName>
+               <description>DFSDM channel configuration 6 register           1</description>
+               <addressOffset>0xC0</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>SITP</name>
+                     <description>Serial interface type for channel               6</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>SPICKSEL</name>
+                     <description>SPI clock select for channel               6</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>SCDEN</name>
+                     <description>Short-circuit detector enable on channel               6</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CKABEN</name>
+                     <description>Clock absence detector enable on channel               6</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CHEN</name>
+                     <description>Channel 6 enable</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CHINSEL</name>
+                     <description>Channel inputs selection</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>DATMPX</name>
+                     <description>Input data multiplexer for channel               6</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>DATPACK</name>
+                     <description>Data packing mode in DFSDM_CHDATINyR               register</description>
+                     <bitOffset>14</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>CKOUTDIV</name>
+                     <description>Output serial clock               divider</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+                  <field>
+                     <name>CKOUTSRC</name>
+                     <description>Output serial clock source               selection</description>
+                     <bitOffset>30</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>DFSDMEN</name>
+                     <description>Global enable for DFSDM               interface</description>
+                     <bitOffset>31</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DFSDM_CHCFG7R1</name>
+               <displayName>DFSDM_CHCFG7R1</displayName>
+               <description>DFSDM channel configuration 7 register           1</description>
+               <addressOffset>0xE0</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>SITP</name>
+                     <description>Serial interface type for channel               7</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>SPICKSEL</name>
+                     <description>SPI clock select for channel               7</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>SCDEN</name>
+                     <description>Short-circuit detector enable on channel               7</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CKABEN</name>
+                     <description>Clock absence detector enable on channel               7</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CHEN</name>
+                     <description>Channel 7 enable</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CHINSEL</name>
+                     <description>Channel inputs selection</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>DATMPX</name>
+                     <description>Input data multiplexer for channel               7</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>DATPACK</name>
+                     <description>Data packing mode in DFSDM_CHDATINyR               register</description>
+                     <bitOffset>14</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>CKOUTDIV</name>
+                     <description>Output serial clock               divider</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+                  <field>
+                     <name>CKOUTSRC</name>
+                     <description>Output serial clock source               selection</description>
+                     <bitOffset>30</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>DFSDMEN</name>
+                     <description>Global enable for DFSDM               interface</description>
+                     <bitOffset>31</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DFSDM_CHCFG0R2</name>
+               <displayName>DFSDM_CHCFG0R2</displayName>
+               <description>DFSDM channel configuration 0 register           2</description>
+               <addressOffset>0x4</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DTRBS</name>
+                     <description>Data right bit-shift for channel               0</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>5</bitWidth>
+                  </field>
+                  <field>
+                     <name>OFFSET</name>
+                     <description>24-bit calibration offset for channel               0</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>24</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DFSDM_CHCFG1R2</name>
+               <displayName>DFSDM_CHCFG1R2</displayName>
+               <description>DFSDM channel configuration 1 register           2</description>
+               <addressOffset>0x24</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DTRBS</name>
+                     <description>Data right bit-shift for channel               1</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>5</bitWidth>
+                  </field>
+                  <field>
+                     <name>OFFSET</name>
+                     <description>24-bit calibration offset for channel               1</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>24</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DFSDM_CHCFG2R2</name>
+               <displayName>DFSDM_CHCFG2R2</displayName>
+               <description>DFSDM channel configuration 2 register           2</description>
+               <addressOffset>0x44</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DTRBS</name>
+                     <description>Data right bit-shift for channel               2</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>5</bitWidth>
+                  </field>
+                  <field>
+                     <name>OFFSET</name>
+                     <description>24-bit calibration offset for channel               2</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>24</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DFSDM_CHCFG3R2</name>
+               <displayName>DFSDM_CHCFG3R2</displayName>
+               <description>DFSDM channel configuration 3 register           2</description>
+               <addressOffset>0x64</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DTRBS</name>
+                     <description>Data right bit-shift for channel               3</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>5</bitWidth>
+                  </field>
+                  <field>
+                     <name>OFFSET</name>
+                     <description>24-bit calibration offset for channel               3</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>24</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DFSDM_CHCFG4R2</name>
+               <displayName>DFSDM_CHCFG4R2</displayName>
+               <description>DFSDM channel configuration 4 register           2</description>
+               <addressOffset>0x84</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DTRBS</name>
+                     <description>Data right bit-shift for channel               4</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>5</bitWidth>
+                  </field>
+                  <field>
+                     <name>OFFSET</name>
+                     <description>24-bit calibration offset for channel               4</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>24</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DFSDM_CHCFG5R2</name>
+               <displayName>DFSDM_CHCFG5R2</displayName>
+               <description>DFSDM channel configuration 5 register           2</description>
+               <addressOffset>0xA4</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DTRBS</name>
+                     <description>Data right bit-shift for channel               5</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>5</bitWidth>
+                  </field>
+                  <field>
+                     <name>OFFSET</name>
+                     <description>24-bit calibration offset for channel               5</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>24</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DFSDM_CHCFG6R2</name>
+               <displayName>DFSDM_CHCFG6R2</displayName>
+               <description>DFSDM channel configuration 6 register           2</description>
+               <addressOffset>0xC4</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DTRBS</name>
+                     <description>Data right bit-shift for channel               6</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>5</bitWidth>
+                  </field>
+                  <field>
+                     <name>OFFSET</name>
+                     <description>24-bit calibration offset for channel               6</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>24</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DFSDM_CHCFG7R2</name>
+               <displayName>DFSDM_CHCFG7R2</displayName>
+               <description>DFSDM channel configuration 7 register           2</description>
+               <addressOffset>0xE4</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DTRBS</name>
+                     <description>Data right bit-shift for channel               7</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>5</bitWidth>
+                  </field>
+                  <field>
+                     <name>OFFSET</name>
+                     <description>24-bit calibration offset for channel               7</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>24</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DFSDM_AWSCD0R</name>
+               <displayName>DFSDM_AWSCD0R</displayName>
+               <description>DFSDM analog watchdog and short-circuit           detector register</description>
+               <addressOffset>0x8</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>SCDT</name>
+                     <description>short-circuit detector threshold for               channel 0</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+                  <field>
+                     <name>BKSCD</name>
+                     <description>Break signal assignment for               short-circuit detector on channel 0</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+                  <field>
+                     <name>AWFOSR</name>
+                     <description>Analog watchdog filter oversampling               ratio (decimation rate) on channel 0</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>5</bitWidth>
+                  </field>
+                  <field>
+                     <name>AWFORD</name>
+                     <description>Analog watchdog Sinc filter order on               channel 0</description>
+                     <bitOffset>22</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DFSDM_AWSCD1R</name>
+               <displayName>DFSDM_AWSCD1R</displayName>
+               <description>DFSDM analog watchdog and short-circuit           detector register</description>
+               <addressOffset>0x28</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>SCDT</name>
+                     <description>short-circuit detector threshold for               channel 1</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+                  <field>
+                     <name>BKSCD</name>
+                     <description>Break signal assignment for               short-circuit detector on channel 1</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+                  <field>
+                     <name>AWFOSR</name>
+                     <description>Analog watchdog filter oversampling               ratio (decimation rate) on channel 1</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>5</bitWidth>
+                  </field>
+                  <field>
+                     <name>AWFORD</name>
+                     <description>Analog watchdog Sinc filter order on               channel 1</description>
+                     <bitOffset>22</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DFSDM_AWSCD2R</name>
+               <displayName>DFSDM_AWSCD2R</displayName>
+               <description>DFSDM analog watchdog and short-circuit           detector register</description>
+               <addressOffset>0x48</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>SCDT</name>
+                     <description>short-circuit detector threshold for               channel 2</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+                  <field>
+                     <name>BKSCD</name>
+                     <description>Break signal assignment for               short-circuit detector on channel 2</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+                  <field>
+                     <name>AWFOSR</name>
+                     <description>Analog watchdog filter oversampling               ratio (decimation rate) on channel 2</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>5</bitWidth>
+                  </field>
+                  <field>
+                     <name>AWFORD</name>
+                     <description>Analog watchdog Sinc filter order on               channel 2</description>
+                     <bitOffset>22</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DFSDM_AWSCD3R</name>
+               <displayName>DFSDM_AWSCD3R</displayName>
+               <description>DFSDM analog watchdog and short-circuit           detector register</description>
+               <addressOffset>0x68</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>SCDT</name>
+                     <description>short-circuit detector threshold for               channel 3</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+                  <field>
+                     <name>BKSCD</name>
+                     <description>Break signal assignment for               short-circuit detector on channel 3</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+                  <field>
+                     <name>AWFOSR</name>
+                     <description>Analog watchdog filter oversampling               ratio (decimation rate) on channel 3</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>5</bitWidth>
+                  </field>
+                  <field>
+                     <name>AWFORD</name>
+                     <description>Analog watchdog Sinc filter order on               channel 3</description>
+                     <bitOffset>22</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DFSDM_AWSCD4R</name>
+               <displayName>DFSDM_AWSCD4R</displayName>
+               <description>DFSDM analog watchdog and short-circuit           detector register</description>
+               <addressOffset>0x88</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>SCDT</name>
+                     <description>short-circuit detector threshold for               channel 4</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+                  <field>
+                     <name>BKSCD</name>
+                     <description>Break signal assignment for               short-circuit detector on channel 4</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+                  <field>
+                     <name>AWFOSR</name>
+                     <description>Analog watchdog filter oversampling               ratio (decimation rate) on channel 4</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>5</bitWidth>
+                  </field>
+                  <field>
+                     <name>AWFORD</name>
+                     <description>Analog watchdog Sinc filter order on               channel 4</description>
+                     <bitOffset>22</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DFSDM_AWSCD5R</name>
+               <displayName>DFSDM_AWSCD5R</displayName>
+               <description>DFSDM analog watchdog and short-circuit           detector register</description>
+               <addressOffset>0xA8</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>SCDT</name>
+                     <description>short-circuit detector threshold for               channel 5</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+                  <field>
+                     <name>BKSCD</name>
+                     <description>Break signal assignment for               short-circuit detector on channel 5</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+                  <field>
+                     <name>AWFOSR</name>
+                     <description>Analog watchdog filter oversampling               ratio (decimation rate) on channel 5</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>5</bitWidth>
+                  </field>
+                  <field>
+                     <name>AWFORD</name>
+                     <description>Analog watchdog Sinc filter order on               channel 5</description>
+                     <bitOffset>22</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DFSDM_AWSCD6R</name>
+               <displayName>DFSDM_AWSCD6R</displayName>
+               <description>DFSDM analog watchdog and short-circuit           detector register</description>
+               <addressOffset>0xC8</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>SCDT</name>
+                     <description>short-circuit detector threshold for               channel 6</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+                  <field>
+                     <name>BKSCD</name>
+                     <description>Break signal assignment for               short-circuit detector on channel 6</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+                  <field>
+                     <name>AWFOSR</name>
+                     <description>Analog watchdog filter oversampling               ratio (decimation rate) on channel 6</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>5</bitWidth>
+                  </field>
+                  <field>
+                     <name>AWFORD</name>
+                     <description>Analog watchdog Sinc filter order on               channel 6</description>
+                     <bitOffset>22</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DFSDM_AWSCD7R</name>
+               <displayName>DFSDM_AWSCD7R</displayName>
+               <description>DFSDM analog watchdog and short-circuit           detector register</description>
+               <addressOffset>0xE8</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>SCDT</name>
+                     <description>short-circuit detector threshold for               channel 7</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+                  <field>
+                     <name>BKSCD</name>
+                     <description>Break signal assignment for               short-circuit detector on channel 7</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+                  <field>
+                     <name>AWFOSR</name>
+                     <description>Analog watchdog filter oversampling               ratio (decimation rate) on channel 7</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>5</bitWidth>
+                  </field>
+                  <field>
+                     <name>AWFORD</name>
+                     <description>Analog watchdog Sinc filter order on               channel 7</description>
+                     <bitOffset>22</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DFSDM_CHWDAT0R</name>
+               <displayName>DFSDM_CHWDAT0R</displayName>
+               <description>DFSDM channel watchdog filter data           register</description>
+               <addressOffset>0xC</addressOffset>
+               <size>0x20</size>
+               <access>read-only</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>WDATA</name>
+                     <description>Input channel y watchdog               data</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DFSDM_CHWDAT1R</name>
+               <displayName>DFSDM_CHWDAT1R</displayName>
+               <description>DFSDM channel watchdog filter data           register</description>
+               <addressOffset>0x2C</addressOffset>
+               <size>0x20</size>
+               <access>read-only</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>WDATA</name>
+                     <description>Input channel y watchdog               data</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DFSDM_CHWDAT2R</name>
+               <displayName>DFSDM_CHWDAT2R</displayName>
+               <description>DFSDM channel watchdog filter data           register</description>
+               <addressOffset>0x4C</addressOffset>
+               <size>0x20</size>
+               <access>read-only</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>WDATA</name>
+                     <description>Input channel y watchdog               data</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DFSDM_CHWDAT3R</name>
+               <displayName>DFSDM_CHWDAT3R</displayName>
+               <description>DFSDM channel watchdog filter data           register</description>
+               <addressOffset>0x6C</addressOffset>
+               <size>0x20</size>
+               <access>read-only</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>WDATA</name>
+                     <description>Input channel y watchdog               data</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DFSDM_CHWDAT4R</name>
+               <displayName>DFSDM_CHWDAT4R</displayName>
+               <description>DFSDM channel watchdog filter data           register</description>
+               <addressOffset>0x8C</addressOffset>
+               <size>0x20</size>
+               <access>read-only</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>WDATA</name>
+                     <description>Input channel y watchdog               data</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DFSDM_CHWDAT5R</name>
+               <displayName>DFSDM_CHWDAT5R</displayName>
+               <description>DFSDM channel watchdog filter data           register</description>
+               <addressOffset>0xAC</addressOffset>
+               <size>0x20</size>
+               <access>read-only</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>WDATA</name>
+                     <description>Input channel y watchdog               data</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DFSDM_CHWDAT6R</name>
+               <displayName>DFSDM_CHWDAT6R</displayName>
+               <description>DFSDM channel watchdog filter data           register</description>
+               <addressOffset>0xCC</addressOffset>
+               <size>0x20</size>
+               <access>read-only</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>WDATA</name>
+                     <description>Input channel y watchdog               data</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DFSDM_CHWDAT7R</name>
+               <displayName>DFSDM_CHWDAT7R</displayName>
+               <description>DFSDM channel watchdog filter data           register</description>
+               <addressOffset>0xEC</addressOffset>
+               <size>0x20</size>
+               <access>read-only</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>WDATA</name>
+                     <description>Input channel y watchdog               data</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DFSDM_CHDATIN0R</name>
+               <displayName>DFSDM_CHDATIN0R</displayName>
+               <description>DFSDM channel data input           register</description>
+               <addressOffset>0x10</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>INDAT0</name>
+                     <description>Input data for channel 0</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+                  <field>
+                     <name>INDAT1</name>
+                     <description>Input data for channel 1</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DFSDM_CHDATIN1R</name>
+               <displayName>DFSDM_CHDATIN1R</displayName>
+               <description>DFSDM channel data input           register</description>
+               <addressOffset>0x30</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>INDAT0</name>
+                     <description>Input data for channel 1</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+                  <field>
+                     <name>INDAT1</name>
+                     <description>Input data for channel 2</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DFSDM_CHDATIN2R</name>
+               <displayName>DFSDM_CHDATIN2R</displayName>
+               <description>DFSDM channel data input           register</description>
+               <addressOffset>0x50</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>INDAT0</name>
+                     <description>Input data for channel 2</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+                  <field>
+                     <name>INDAT1</name>
+                     <description>Input data for channel 3</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DFSDM_CHDATIN3R</name>
+               <displayName>DFSDM_CHDATIN3R</displayName>
+               <description>DFSDM channel data input           register</description>
+               <addressOffset>0x70</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>INDAT0</name>
+                     <description>Input data for channel 3</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+                  <field>
+                     <name>INDAT1</name>
+                     <description>Input data for channel 4</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DFSDM_CHDATIN4R</name>
+               <displayName>DFSDM_CHDATIN4R</displayName>
+               <description>DFSDM channel data input           register</description>
+               <addressOffset>0x90</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>INDAT0</name>
+                     <description>Input data for channel 4</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+                  <field>
+                     <name>INDAT1</name>
+                     <description>Input data for channel 5</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DFSDM_CHDATIN5R</name>
+               <displayName>DFSDM_CHDATIN5R</displayName>
+               <description>DFSDM channel data input           register</description>
+               <addressOffset>0xB0</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>INDAT0</name>
+                     <description>Input data for channel 5</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+                  <field>
+                     <name>INDAT1</name>
+                     <description>Input data for channel 6</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DFSDM_CHDATIN6R</name>
+               <displayName>DFSDM_CHDATIN6R</displayName>
+               <description>DFSDM channel data input           register</description>
+               <addressOffset>0xD0</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>INDAT0</name>
+                     <description>Input data for channel 6</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+                  <field>
+                     <name>INDAT1</name>
+                     <description>Input data for channel 7</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DFSDM_CHDATIN7R</name>
+               <displayName>DFSDM_CHDATIN7R</displayName>
+               <description>DFSDM channel data input           register</description>
+               <addressOffset>0xF0</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>INDAT0</name>
+                     <description>Input data for channel 7</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+                  <field>
+                     <name>INDAT1</name>
+                     <description>Input data for channel 8</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DFSDM0_CR1</name>
+               <displayName>DFSDM0_CR1</displayName>
+               <description>DFSDM control register 1</description>
+               <addressOffset>0x100</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DFEN</name>
+                     <description>DFSDM enable</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>JSWSTART</name>
+                     <description>Start a conversion of the injected group               of channels</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>JSYNC</name>
+                     <description>Launch an injected conversion               synchronously with the DFSDM0 JSWSTART               trigger</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>JSCAN</name>
+                     <description>Scanning conversion mode for injected               conversions</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>JDMAEN</name>
+                     <description>DMA channel enabled to read data for the               injected channel group</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>JEXTSEL</name>
+                     <description>Trigger signal selection for launching               injected conversions</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>5</bitWidth>
+                  </field>
+                  <field>
+                     <name>JEXTEN</name>
+                     <description>Trigger enable and trigger edge               selection for injected conversions</description>
+                     <bitOffset>13</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>RSWSTART</name>
+                     <description>Software start of a conversion on the               regular channel</description>
+                     <bitOffset>17</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>RCONT</name>
+                     <description>Continuous mode selection for regular               conversions</description>
+                     <bitOffset>18</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>RSYNC</name>
+                     <description>Launch regular conversion synchronously               with DFSDM0</description>
+                     <bitOffset>19</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>RDMAEN</name>
+                     <description>DMA channel enabled to read data for the               regular conversion</description>
+                     <bitOffset>21</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>RCH</name>
+                     <description>Regular channel selection</description>
+                     <bitOffset>24</bitOffset>
+                     <bitWidth>3</bitWidth>
+                  </field>
+                  <field>
+                     <name>FAST</name>
+                     <description>Fast conversion mode selection for               regular conversions</description>
+                     <bitOffset>29</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>AWFSEL</name>
+                     <description>Analog watchdog fast mode               select</description>
+                     <bitOffset>30</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DFSDM1_CR1</name>
+               <displayName>DFSDM1_CR1</displayName>
+               <description>DFSDM control register 1</description>
+               <addressOffset>0x180</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DFEN</name>
+                     <description>DFSDM enable</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>JSWSTART</name>
+                     <description>Start a conversion of the injected group               of channels</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>JSYNC</name>
+                     <description>Launch an injected conversion               synchronously with the DFSDM0 JSWSTART               trigger</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>JSCAN</name>
+                     <description>Scanning conversion mode for injected               conversions</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>JDMAEN</name>
+                     <description>DMA channel enabled to read data for the               injected channel group</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>JEXTSEL</name>
+                     <description>Trigger signal selection for launching               injected conversions</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>5</bitWidth>
+                  </field>
+                  <field>
+                     <name>JEXTEN</name>
+                     <description>Trigger enable and trigger edge               selection for injected conversions</description>
+                     <bitOffset>13</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>RSWSTART</name>
+                     <description>Software start of a conversion on the               regular channel</description>
+                     <bitOffset>17</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>RCONT</name>
+                     <description>Continuous mode selection for regular               conversions</description>
+                     <bitOffset>18</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>RSYNC</name>
+                     <description>Launch regular conversion synchronously               with DFSDM0</description>
+                     <bitOffset>19</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>RDMAEN</name>
+                     <description>DMA channel enabled to read data for the               regular conversion</description>
+                     <bitOffset>21</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>RCH</name>
+                     <description>Regular channel selection</description>
+                     <bitOffset>24</bitOffset>
+                     <bitWidth>3</bitWidth>
+                  </field>
+                  <field>
+                     <name>FAST</name>
+                     <description>Fast conversion mode selection for               regular conversions</description>
+                     <bitOffset>29</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>AWFSEL</name>
+                     <description>Analog watchdog fast mode               select</description>
+                     <bitOffset>30</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DFSDM2_CR1</name>
+               <displayName>DFSDM2_CR1</displayName>
+               <description>DFSDM control register 1</description>
+               <addressOffset>0x200</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DFEN</name>
+                     <description>DFSDM enable</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>JSWSTART</name>
+                     <description>Start a conversion of the injected group               of channels</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>JSYNC</name>
+                     <description>Launch an injected conversion               synchronously with the DFSDM0 JSWSTART               trigger</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>JSCAN</name>
+                     <description>Scanning conversion mode for injected               conversions</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>JDMAEN</name>
+                     <description>DMA channel enabled to read data for the               injected channel group</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>JEXTSEL</name>
+                     <description>Trigger signal selection for launching               injected conversions</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>5</bitWidth>
+                  </field>
+                  <field>
+                     <name>JEXTEN</name>
+                     <description>Trigger enable and trigger edge               selection for injected conversions</description>
+                     <bitOffset>13</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>RSWSTART</name>
+                     <description>Software start of a conversion on the               regular channel</description>
+                     <bitOffset>17</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>RCONT</name>
+                     <description>Continuous mode selection for regular               conversions</description>
+                     <bitOffset>18</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>RSYNC</name>
+                     <description>Launch regular conversion synchronously               with DFSDM0</description>
+                     <bitOffset>19</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>RDMAEN</name>
+                     <description>DMA channel enabled to read data for the               regular conversion</description>
+                     <bitOffset>21</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>RCH</name>
+                     <description>Regular channel selection</description>
+                     <bitOffset>24</bitOffset>
+                     <bitWidth>3</bitWidth>
+                  </field>
+                  <field>
+                     <name>FAST</name>
+                     <description>Fast conversion mode selection for               regular conversions</description>
+                     <bitOffset>29</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>AWFSEL</name>
+                     <description>Analog watchdog fast mode               select</description>
+                     <bitOffset>30</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DFSDM3_CR1</name>
+               <displayName>DFSDM3_CR1</displayName>
+               <description>DFSDM control register 1</description>
+               <addressOffset>0x380</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DFEN</name>
+                     <description>DFSDM enable</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>JSWSTART</name>
+                     <description>Start a conversion of the injected group               of channels</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>JSYNC</name>
+                     <description>Launch an injected conversion               synchronously with the DFSDM0 JSWSTART               trigger</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>JSCAN</name>
+                     <description>Scanning conversion mode for injected               conversions</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>JDMAEN</name>
+                     <description>DMA channel enabled to read data for the               injected channel group</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>JEXTSEL</name>
+                     <description>Trigger signal selection for launching               injected conversions</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>5</bitWidth>
+                  </field>
+                  <field>
+                     <name>JEXTEN</name>
+                     <description>Trigger enable and trigger edge               selection for injected conversions</description>
+                     <bitOffset>13</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>RSWSTART</name>
+                     <description>Software start of a conversion on the               regular channel</description>
+                     <bitOffset>17</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>RCONT</name>
+                     <description>Continuous mode selection for regular               conversions</description>
+                     <bitOffset>18</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>RSYNC</name>
+                     <description>Launch regular conversion synchronously               with DFSDM0</description>
+                     <bitOffset>19</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>RDMAEN</name>
+                     <description>DMA channel enabled to read data for the               regular conversion</description>
+                     <bitOffset>21</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>RCH</name>
+                     <description>Regular channel selection</description>
+                     <bitOffset>24</bitOffset>
+                     <bitWidth>3</bitWidth>
+                  </field>
+                  <field>
+                     <name>FAST</name>
+                     <description>Fast conversion mode selection for               regular conversions</description>
+                     <bitOffset>29</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>AWFSEL</name>
+                     <description>Analog watchdog fast mode               select</description>
+                     <bitOffset>30</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DFSDM0_CR2</name>
+               <displayName>DFSDM0_CR2</displayName>
+               <description>DFSDM control register 2</description>
+               <addressOffset>0x104</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>JEOCIE</name>
+                     <description>Injected end of conversion interrupt               enable</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>REOCIE</name>
+                     <description>Regular end of conversion interrupt               enable</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>JOVRIE</name>
+                     <description>Injected data overrun interrupt               enable</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>ROVRIE</name>
+                     <description>Regular data overrun interrupt               enable</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>AWDIE</name>
+                     <description>Analog watchdog interrupt               enable</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>SCDIE</name>
+                     <description>Short-circuit detector interrupt               enable</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CKABIE</name>
+                     <description>Clock absence interrupt               enable</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>EXCH</name>
+                     <description>Extremes detector channel               selection</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+                  <field>
+                     <name>AWDCH</name>
+                     <description>Analog watchdog channel               selection</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DFSDM1_CR2</name>
+               <displayName>DFSDM1_CR2</displayName>
+               <description>DFSDM control register 2</description>
+               <addressOffset>0x184</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>JEOCIE</name>
+                     <description>Injected end of conversion interrupt               enable</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>REOCIE</name>
+                     <description>Regular end of conversion interrupt               enable</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>JOVRIE</name>
+                     <description>Injected data overrun interrupt               enable</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>ROVRIE</name>
+                     <description>Regular data overrun interrupt               enable</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>AWDIE</name>
+                     <description>Analog watchdog interrupt               enable</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>SCDIE</name>
+                     <description>Short-circuit detector interrupt               enable</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CKABIE</name>
+                     <description>Clock absence interrupt               enable</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>EXCH</name>
+                     <description>Extremes detector channel               selection</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+                  <field>
+                     <name>AWDCH</name>
+                     <description>Analog watchdog channel               selection</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DFSDM2_CR2</name>
+               <displayName>DFSDM2_CR2</displayName>
+               <description>DFSDM control register 2</description>
+               <addressOffset>0x204</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>JEOCIE</name>
+                     <description>Injected end of conversion interrupt               enable</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>REOCIE</name>
+                     <description>Regular end of conversion interrupt               enable</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>JOVRIE</name>
+                     <description>Injected data overrun interrupt               enable</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>ROVRIE</name>
+                     <description>Regular data overrun interrupt               enable</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>AWDIE</name>
+                     <description>Analog watchdog interrupt               enable</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>SCDIE</name>
+                     <description>Short-circuit detector interrupt               enable</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CKABIE</name>
+                     <description>Clock absence interrupt               enable</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>EXCH</name>
+                     <description>Extremes detector channel               selection</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+                  <field>
+                     <name>AWDCH</name>
+                     <description>Analog watchdog channel               selection</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DFSDM3_CR2</name>
+               <displayName>DFSDM3_CR2</displayName>
+               <description>DFSDM control register 2</description>
+               <addressOffset>0x384</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>JEOCIE</name>
+                     <description>Injected end of conversion interrupt               enable</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>REOCIE</name>
+                     <description>Regular end of conversion interrupt               enable</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>JOVRIE</name>
+                     <description>Injected data overrun interrupt               enable</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>ROVRIE</name>
+                     <description>Regular data overrun interrupt               enable</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>AWDIE</name>
+                     <description>Analog watchdog interrupt               enable</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>SCDIE</name>
+                     <description>Short-circuit detector interrupt               enable</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CKABIE</name>
+                     <description>Clock absence interrupt               enable</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>EXCH</name>
+                     <description>Extremes detector channel               selection</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+                  <field>
+                     <name>AWDCH</name>
+                     <description>Analog watchdog channel               selection</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DFSDM0_ISR</name>
+               <displayName>DFSDM0_ISR</displayName>
+               <description>DFSDM interrupt and status           register</description>
+               <addressOffset>0x108</addressOffset>
+               <size>0x20</size>
+               <access>read-only</access>
+               <resetValue>0x00FF0000</resetValue>
+               <fields>
+                  <field>
+                     <name>JEOCF</name>
+                     <description>End of injected conversion               flag</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>REOCF</name>
+                     <description>End of regular conversion               flag</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>JOVRF</name>
+                     <description>Injected conversion overrun               flag</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>ROVRF</name>
+                     <description>Regular conversion overrun               flag</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>AWDF</name>
+                     <description>Analog watchdog</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>JCIP</name>
+                     <description>Injected conversion in progress               status</description>
+                     <bitOffset>13</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>RCIP</name>
+                     <description>Regular conversion in progress               status</description>
+                     <bitOffset>14</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CKABF</name>
+                     <description>Clock absence flag</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+                  <field>
+                     <name>SCDF</name>
+                     <description>short-circuit detector               flag</description>
+                     <bitOffset>24</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DFSDM1_ISR</name>
+               <displayName>DFSDM1_ISR</displayName>
+               <description>DFSDM interrupt and status           register</description>
+               <addressOffset>0x188</addressOffset>
+               <size>0x20</size>
+               <access>read-only</access>
+               <resetValue>0x00FF0000</resetValue>
+               <fields>
+                  <field>
+                     <name>JEOCF</name>
+                     <description>End of injected conversion               flag</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>REOCF</name>
+                     <description>End of regular conversion               flag</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>JOVRF</name>
+                     <description>Injected conversion overrun               flag</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>ROVRF</name>
+                     <description>Regular conversion overrun               flag</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>AWDF</name>
+                     <description>Analog watchdog</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>JCIP</name>
+                     <description>Injected conversion in progress               status</description>
+                     <bitOffset>13</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>RCIP</name>
+                     <description>Regular conversion in progress               status</description>
+                     <bitOffset>14</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CKABF</name>
+                     <description>Clock absence flag</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+                  <field>
+                     <name>SCDF</name>
+                     <description>short-circuit detector               flag</description>
+                     <bitOffset>24</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DFSDM2_ISR</name>
+               <displayName>DFSDM2_ISR</displayName>
+               <description>DFSDM interrupt and status           register</description>
+               <addressOffset>0x208</addressOffset>
+               <size>0x20</size>
+               <access>read-only</access>
+               <resetValue>0x00FF0000</resetValue>
+               <fields>
+                  <field>
+                     <name>JEOCF</name>
+                     <description>End of injected conversion               flag</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>REOCF</name>
+                     <description>End of regular conversion               flag</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>JOVRF</name>
+                     <description>Injected conversion overrun               flag</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>ROVRF</name>
+                     <description>Regular conversion overrun               flag</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>AWDF</name>
+                     <description>Analog watchdog</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>JCIP</name>
+                     <description>Injected conversion in progress               status</description>
+                     <bitOffset>13</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>RCIP</name>
+                     <description>Regular conversion in progress               status</description>
+                     <bitOffset>14</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CKABF</name>
+                     <description>Clock absence flag</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+                  <field>
+                     <name>SCDF</name>
+                     <description>short-circuit detector               flag</description>
+                     <bitOffset>24</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DFSDM3_ISR</name>
+               <displayName>DFSDM3_ISR</displayName>
+               <description>DFSDM interrupt and status           register</description>
+               <addressOffset>0x388</addressOffset>
+               <size>0x20</size>
+               <access>read-only</access>
+               <resetValue>0x00FF0000</resetValue>
+               <fields>
+                  <field>
+                     <name>JEOCF</name>
+                     <description>End of injected conversion               flag</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>REOCF</name>
+                     <description>End of regular conversion               flag</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>JOVRF</name>
+                     <description>Injected conversion overrun               flag</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>ROVRF</name>
+                     <description>Regular conversion overrun               flag</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>AWDF</name>
+                     <description>Analog watchdog</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>JCIP</name>
+                     <description>Injected conversion in progress               status</description>
+                     <bitOffset>13</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>RCIP</name>
+                     <description>Regular conversion in progress               status</description>
+                     <bitOffset>14</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CKABF</name>
+                     <description>Clock absence flag</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+                  <field>
+                     <name>SCDF</name>
+                     <description>short-circuit detector               flag</description>
+                     <bitOffset>24</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DFSDM0_ICR</name>
+               <displayName>DFSDM0_ICR</displayName>
+               <description>DFSDM interrupt flag clear           register</description>
+               <addressOffset>0x10C</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>CLRJOVRF</name>
+                     <description>Clear the injected conversion overrun               flag</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CLRROVRF</name>
+                     <description>Clear the regular conversion overrun               flag</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CLRCKABF</name>
+                     <description>Clear the clock absence               flag</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+                  <field>
+                     <name>CLRSCDF</name>
+                     <description>Clear the short-circuit detector               flag</description>
+                     <bitOffset>24</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DFSDM1_ICR</name>
+               <displayName>DFSDM1_ICR</displayName>
+               <description>DFSDM interrupt flag clear           register</description>
+               <addressOffset>0x18C</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>CLRJOVRF</name>
+                     <description>Clear the injected conversion overrun               flag</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CLRROVRF</name>
+                     <description>Clear the regular conversion overrun               flag</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CLRCKABF</name>
+                     <description>Clear the clock absence               flag</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+                  <field>
+                     <name>CLRSCDF</name>
+                     <description>Clear the short-circuit detector               flag</description>
+                     <bitOffset>24</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DFSDM2_ICR</name>
+               <displayName>DFSDM2_ICR</displayName>
+               <description>DFSDM interrupt flag clear           register</description>
+               <addressOffset>0x20C</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>CLRJOVRF</name>
+                     <description>Clear the injected conversion overrun               flag</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CLRROVRF</name>
+                     <description>Clear the regular conversion overrun               flag</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CLRCKABF</name>
+                     <description>Clear the clock absence               flag</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+                  <field>
+                     <name>CLRSCDF</name>
+                     <description>Clear the short-circuit detector               flag</description>
+                     <bitOffset>24</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DFSDM3_ICR</name>
+               <displayName>DFSDM3_ICR</displayName>
+               <description>DFSDM interrupt flag clear           register</description>
+               <addressOffset>0x38C</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>CLRJOVRF</name>
+                     <description>Clear the injected conversion overrun               flag</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CLRROVRF</name>
+                     <description>Clear the regular conversion overrun               flag</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CLRCKABF</name>
+                     <description>Clear the clock absence               flag</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+                  <field>
+                     <name>CLRSCDF</name>
+                     <description>Clear the short-circuit detector               flag</description>
+                     <bitOffset>24</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DFSDM0_JCHGR</name>
+               <displayName>DFSDM0_JCHGR</displayName>
+               <description>DFSDM injected channel group selection           register</description>
+               <addressOffset>0x110</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000001</resetValue>
+               <fields>
+                  <field>
+                     <name>JCHG</name>
+                     <description>Injected channel group               selection</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DFSDM1_JCHGR</name>
+               <displayName>DFSDM1_JCHGR</displayName>
+               <description>DFSDM injected channel group selection           register</description>
+               <addressOffset>0x190</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000001</resetValue>
+               <fields>
+                  <field>
+                     <name>JCHG</name>
+                     <description>Injected channel group               selection</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DFSDM2_JCHGR</name>
+               <displayName>DFSDM2_JCHGR</displayName>
+               <description>DFSDM injected channel group selection           register</description>
+               <addressOffset>0x210</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000001</resetValue>
+               <fields>
+                  <field>
+                     <name>JCHG</name>
+                     <description>Injected channel group               selection</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DFSDM3_JCHGR</name>
+               <displayName>DFSDM3_JCHGR</displayName>
+               <description>DFSDM injected channel group selection           register</description>
+               <addressOffset>0x310</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000001</resetValue>
+               <fields>
+                  <field>
+                     <name>JCHG</name>
+                     <description>Injected channel group               selection</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DFSDM0_FCR</name>
+               <displayName>DFSDM0_FCR</displayName>
+               <description>DFSDM filter control register</description>
+               <addressOffset>0x114</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>IOSR</name>
+                     <description>Integrator oversampling ratio (averaging               length)</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+                  <field>
+                     <name>FOSR</name>
+                     <description>Sinc filter oversampling ratio               (decimation rate)</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>10</bitWidth>
+                  </field>
+                  <field>
+                     <name>FORD</name>
+                     <description>Sinc filter order</description>
+                     <bitOffset>29</bitOffset>
+                     <bitWidth>3</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DFSDM1_FCR</name>
+               <displayName>DFSDM1_FCR</displayName>
+               <description>DFSDM filter control register</description>
+               <addressOffset>0x194</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>IOSR</name>
+                     <description>Integrator oversampling ratio (averaging               length)</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+                  <field>
+                     <name>FOSR</name>
+                     <description>Sinc filter oversampling ratio               (decimation rate)</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>10</bitWidth>
+                  </field>
+                  <field>
+                     <name>FORD</name>
+                     <description>Sinc filter order</description>
+                     <bitOffset>29</bitOffset>
+                     <bitWidth>3</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DFSDM2_FCR</name>
+               <displayName>DFSDM2_FCR</displayName>
+               <description>DFSDM filter control register</description>
+               <addressOffset>0x214</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>IOSR</name>
+                     <description>Integrator oversampling ratio (averaging               length)</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+                  <field>
+                     <name>FOSR</name>
+                     <description>Sinc filter oversampling ratio               (decimation rate)</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>10</bitWidth>
+                  </field>
+                  <field>
+                     <name>FORD</name>
+                     <description>Sinc filter order</description>
+                     <bitOffset>29</bitOffset>
+                     <bitWidth>3</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DFSDM3_FCR</name>
+               <displayName>DFSDM3_FCR</displayName>
+               <description>DFSDM filter control register</description>
+               <addressOffset>0x314</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>IOSR</name>
+                     <description>Integrator oversampling ratio (averaging               length)</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+                  <field>
+                     <name>FOSR</name>
+                     <description>Sinc filter oversampling ratio               (decimation rate)</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>10</bitWidth>
+                  </field>
+                  <field>
+                     <name>FORD</name>
+                     <description>Sinc filter order</description>
+                     <bitOffset>29</bitOffset>
+                     <bitWidth>3</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DFSDM0_JDATAR</name>
+               <displayName>DFSDM0_JDATAR</displayName>
+               <description>DFSDM data register for injected           group</description>
+               <addressOffset>0x118</addressOffset>
+               <size>0x20</size>
+               <access>read-only</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>JDATACH</name>
+                     <description>Injected channel most recently               converted</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>3</bitWidth>
+                  </field>
+                  <field>
+                     <name>JDATA</name>
+                     <description>Injected group conversion               data</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>24</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DFSDM1_JDATAR</name>
+               <displayName>DFSDM1_JDATAR</displayName>
+               <description>DFSDM data register for injected           group</description>
+               <addressOffset>0x198</addressOffset>
+               <size>0x20</size>
+               <access>read-only</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>JDATACH</name>
+                     <description>Injected channel most recently               converted</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>3</bitWidth>
+                  </field>
+                  <field>
+                     <name>JDATA</name>
+                     <description>Injected group conversion               data</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>24</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DFSDM2_JDATAR</name>
+               <displayName>DFSDM2_JDATAR</displayName>
+               <description>DFSDM data register for injected           group</description>
+               <addressOffset>0x218</addressOffset>
+               <size>0x20</size>
+               <access>read-only</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>JDATACH</name>
+                     <description>Injected channel most recently               converted</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>3</bitWidth>
+                  </field>
+                  <field>
+                     <name>JDATA</name>
+                     <description>Injected group conversion               data</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>24</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DFSDM3_JDATAR</name>
+               <displayName>DFSDM3_JDATAR</displayName>
+               <description>DFSDM data register for injected           group</description>
+               <addressOffset>0x318</addressOffset>
+               <size>0x20</size>
+               <access>read-only</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>JDATACH</name>
+                     <description>Injected channel most recently               converted</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>3</bitWidth>
+                  </field>
+                  <field>
+                     <name>JDATA</name>
+                     <description>Injected group conversion               data</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>24</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DFSDM0_RDATAR</name>
+               <displayName>DFSDM0_RDATAR</displayName>
+               <description>DFSDM data register for the regular           channel</description>
+               <addressOffset>0x11C</addressOffset>
+               <size>0x20</size>
+               <access>read-only</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>RDATACH</name>
+                     <description>Regular channel most recently               converted</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>3</bitWidth>
+                  </field>
+                  <field>
+                     <name>RPEND</name>
+                     <description>Regular channel pending               data</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>RDATA</name>
+                     <description>Regular channel conversion               data</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>24</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DFSDM1_RDATAR</name>
+               <displayName>DFSDM1_RDATAR</displayName>
+               <description>DFSDM data register for the regular           channel</description>
+               <alternateRegister>DFSDM1_JDATAR</alternateRegister>
+               <addressOffset>0x198</addressOffset>
+               <size>0x20</size>
+               <access>read-only</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>RDATACH</name>
+                     <description>Regular channel most recently               converted</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>3</bitWidth>
+                  </field>
+                  <field>
+                     <name>RPEND</name>
+                     <description>Regular channel pending               data</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>RDATA</name>
+                     <description>Regular channel conversion               data</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>24</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DFSDM2_RDATAR</name>
+               <displayName>DFSDM2_RDATAR</displayName>
+               <description>DFSDM data register for the regular           channel</description>
+               <alternateRegister>DFSDM2_JDATAR</alternateRegister>
+               <addressOffset>0x218</addressOffset>
+               <size>0x20</size>
+               <access>read-only</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>RDATACH</name>
+                     <description>Regular channel most recently               converted</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>3</bitWidth>
+                  </field>
+                  <field>
+                     <name>RPEND</name>
+                     <description>Regular channel pending               data</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>RDATA</name>
+                     <description>Regular channel conversion               data</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>24</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DFSDM3_RDATAR</name>
+               <displayName>DFSDM3_RDATAR</displayName>
+               <description>DFSDM data register for the regular           channel</description>
+               <alternateRegister>DFSDM3_JDATAR</alternateRegister>
+               <addressOffset>0x318</addressOffset>
+               <size>0x20</size>
+               <access>read-only</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>RDATACH</name>
+                     <description>Regular channel most recently               converted</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>3</bitWidth>
+                  </field>
+                  <field>
+                     <name>RPEND</name>
+                     <description>Regular channel pending               data</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>RDATA</name>
+                     <description>Regular channel conversion               data</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>24</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DFSDM0_AWHTR</name>
+               <displayName>DFSDM0_AWHTR</displayName>
+               <description>DFSDM analog watchdog high threshold           register</description>
+               <addressOffset>0x120</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>BKAWH</name>
+                     <description>Break signal assignment to analog               watchdog high threshold event</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+                  <field>
+                     <name>AWHT</name>
+                     <description>Analog watchdog high               threshold</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>24</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DFSDM1_AWHTR</name>
+               <displayName>DFSDM1_AWHTR</displayName>
+               <description>DFSDM analog watchdog high threshold           register</description>
+               <addressOffset>0x1A0</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>BKAWH</name>
+                     <description>Break signal assignment to analog               watchdog high threshold event</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+                  <field>
+                     <name>AWHT</name>
+                     <description>Analog watchdog high               threshold</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>24</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DFSDM2_AWHTR</name>
+               <displayName>DFSDM2_AWHTR</displayName>
+               <description>DFSDM analog watchdog high threshold           register</description>
+               <addressOffset>0x220</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>BKAWH</name>
+                     <description>Break signal assignment to analog               watchdog high threshold event</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+                  <field>
+                     <name>AWHT</name>
+                     <description>Analog watchdog high               threshold</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>24</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DFSDM3_AWHTR</name>
+               <displayName>DFSDM3_AWHTR</displayName>
+               <description>DFSDM analog watchdog high threshold           register</description>
+               <addressOffset>0x2A0</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>BKAWH</name>
+                     <description>Break signal assignment to analog               watchdog high threshold event</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+                  <field>
+                     <name>AWHT</name>
+                     <description>Analog watchdog high               threshold</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>24</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DFSDM0_AWLTR</name>
+               <displayName>DFSDM0_AWLTR</displayName>
+               <description>DFSDM analog watchdog low threshold           register</description>
+               <addressOffset>0x124</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>BKAWL</name>
+                     <description>Break signal assignment to analog               watchdog low threshold event</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+                  <field>
+                     <name>AWLT</name>
+                     <description>Analog watchdog low               threshold</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>24</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DFSDM1_AWLTR</name>
+               <displayName>DFSDM1_AWLTR</displayName>
+               <description>DFSDM analog watchdog low threshold           register</description>
+               <addressOffset>0x1A4</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>BKAWL</name>
+                     <description>Break signal assignment to analog               watchdog low threshold event</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+                  <field>
+                     <name>AWLT</name>
+                     <description>Analog watchdog low               threshold</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>24</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DFSDM2_AWLTR</name>
+               <displayName>DFSDM2_AWLTR</displayName>
+               <description>DFSDM analog watchdog low threshold           register</description>
+               <addressOffset>0x224</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>BKAWL</name>
+                     <description>Break signal assignment to analog               watchdog low threshold event</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+                  <field>
+                     <name>AWLT</name>
+                     <description>Analog watchdog low               threshold</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>24</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DFSDM3_AWLTR</name>
+               <displayName>DFSDM3_AWLTR</displayName>
+               <description>DFSDM analog watchdog low threshold           register</description>
+               <addressOffset>0x2A4</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>BKAWL</name>
+                     <description>Break signal assignment to analog               watchdog low threshold event</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+                  <field>
+                     <name>AWLT</name>
+                     <description>Analog watchdog low               threshold</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>24</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DFSDM0_AWSR</name>
+               <displayName>DFSDM0_AWSR</displayName>
+               <description>DFSDM analog watchdog status           register</description>
+               <addressOffset>0x128</addressOffset>
+               <size>0x20</size>
+               <access>read-only</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>AWLTF</name>
+                     <description>Analog watchdog low threshold               flag</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+                  <field>
+                     <name>AWHTF</name>
+                     <description>Analog watchdog high threshold               flag</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DFSDM1_AWSR</name>
+               <displayName>DFSDM1_AWSR</displayName>
+               <description>DFSDM analog watchdog status           register</description>
+               <addressOffset>0x1A8</addressOffset>
+               <size>0x20</size>
+               <access>read-only</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>AWLTF</name>
+                     <description>Analog watchdog low threshold               flag</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+                  <field>
+                     <name>AWHTF</name>
+                     <description>Analog watchdog high threshold               flag</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DFSDM2_AWSR</name>
+               <displayName>DFSDM2_AWSR</displayName>
+               <description>DFSDM analog watchdog status           register</description>
+               <addressOffset>0x228</addressOffset>
+               <size>0x20</size>
+               <access>read-only</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>AWLTF</name>
+                     <description>Analog watchdog low threshold               flag</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+                  <field>
+                     <name>AWHTF</name>
+                     <description>Analog watchdog high threshold               flag</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DFSDM3_AWSR</name>
+               <displayName>DFSDM3_AWSR</displayName>
+               <description>DFSDM analog watchdog status           register</description>
+               <addressOffset>0x2A8</addressOffset>
+               <size>0x20</size>
+               <access>read-only</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>AWLTF</name>
+                     <description>Analog watchdog low threshold               flag</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+                  <field>
+                     <name>AWHTF</name>
+                     <description>Analog watchdog high threshold               flag</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DFSDM0_AWCFR</name>
+               <displayName>DFSDM0_AWCFR</displayName>
+               <description>DFSDM analog watchdog clear flag           register</description>
+               <addressOffset>0x12C</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>CLRAWLTF</name>
+                     <description>Clear the analog watchdog low threshold               flag</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+                  <field>
+                     <name>CLRAWHTF</name>
+                     <description>Clear the analog watchdog high threshold               flag</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DFSDM1_AWCFR</name>
+               <displayName>DFSDM1_AWCFR</displayName>
+               <description>DFSDM analog watchdog clear flag           register</description>
+               <addressOffset>0x1AC</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>CLRAWLTF</name>
+                     <description>Clear the analog watchdog low threshold               flag</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+                  <field>
+                     <name>CLRAWHTF</name>
+                     <description>Clear the analog watchdog high threshold               flag</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DFSDM2_AWCFR</name>
+               <displayName>DFSDM2_AWCFR</displayName>
+               <description>DFSDM analog watchdog clear flag           register</description>
+               <addressOffset>0x22C</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>CLRAWLTF</name>
+                     <description>Clear the analog watchdog low threshold               flag</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+                  <field>
+                     <name>CLRAWHTF</name>
+                     <description>Clear the analog watchdog high threshold               flag</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DFSDM3_AWCFR</name>
+               <displayName>DFSDM3_AWCFR</displayName>
+               <description>DFSDM analog watchdog clear flag           register</description>
+               <addressOffset>0x2AC</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>CLRAWLTF</name>
+                     <description>Clear the analog watchdog low threshold               flag</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+                  <field>
+                     <name>CLRAWHTF</name>
+                     <description>Clear the analog watchdog high threshold               flag</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DFSDM0_EXMAX</name>
+               <displayName>DFSDM0_EXMAX</displayName>
+               <description>DFSDM Extremes detector maximum           register</description>
+               <addressOffset>0x130</addressOffset>
+               <size>0x20</size>
+               <access>read-only</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>EXMAXCH</name>
+                     <description>Extremes detector maximum data               channel</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>3</bitWidth>
+                  </field>
+                  <field>
+                     <name>EXMAX</name>
+                     <description>Extremes detector maximum               value</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>24</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DFSDM1_EXMAX</name>
+               <displayName>DFSDM1_EXMAX</displayName>
+               <description>DFSDM Extremes detector maximum           register</description>
+               <addressOffset>0x1B0</addressOffset>
+               <size>0x20</size>
+               <access>read-only</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>EXMAXCH</name>
+                     <description>Extremes detector maximum data               channel</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>3</bitWidth>
+                  </field>
+                  <field>
+                     <name>EXMAX</name>
+                     <description>Extremes detector maximum               value</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>24</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DFSDM2_EXMAX</name>
+               <displayName>DFSDM2_EXMAX</displayName>
+               <description>DFSDM Extremes detector maximum           register</description>
+               <addressOffset>0x230</addressOffset>
+               <size>0x20</size>
+               <access>read-only</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>EXMAXCH</name>
+                     <description>Extremes detector maximum data               channel</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>3</bitWidth>
+                  </field>
+                  <field>
+                     <name>EXMAX</name>
+                     <description>Extremes detector maximum               value</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>24</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DFSDM3_EXMAX</name>
+               <displayName>DFSDM3_EXMAX</displayName>
+               <description>DFSDM Extremes detector maximum           register</description>
+               <addressOffset>0x2B0</addressOffset>
+               <size>0x20</size>
+               <access>read-only</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>EXMAXCH</name>
+                     <description>Extremes detector maximum data               channel</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>3</bitWidth>
+                  </field>
+                  <field>
+                     <name>EXMAX</name>
+                     <description>Extremes detector maximum               value</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>24</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DFSDM0_EXMIN</name>
+               <displayName>DFSDM0_EXMIN</displayName>
+               <description>DFSDM Extremes detector minimum           register</description>
+               <addressOffset>0x134</addressOffset>
+               <size>0x20</size>
+               <access>read-only</access>
+               <resetValue>0x7FFFFF00</resetValue>
+               <fields>
+                  <field>
+                     <name>EXMINCH</name>
+                     <description>Extremes detector minimum data               channel</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>3</bitWidth>
+                  </field>
+                  <field>
+                     <name>EXMIN</name>
+                     <description>Extremes detector minimum               value</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>24</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DFSDM1_EXMIN</name>
+               <displayName>DFSDM1_EXMIN</displayName>
+               <description>DFSDM Extremes detector minimum           register</description>
+               <addressOffset>0x1B4</addressOffset>
+               <size>0x20</size>
+               <access>read-only</access>
+               <resetValue>0x7FFFFF00</resetValue>
+               <fields>
+                  <field>
+                     <name>EXMINCH</name>
+                     <description>Extremes detector minimum data               channel</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>3</bitWidth>
+                  </field>
+                  <field>
+                     <name>EXMIN</name>
+                     <description>Extremes detector minimum               value</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>24</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DFSDM2_EXMIN</name>
+               <displayName>DFSDM2_EXMIN</displayName>
+               <description>DFSDM Extremes detector minimum           register</description>
+               <addressOffset>0x234</addressOffset>
+               <size>0x20</size>
+               <access>read-only</access>
+               <resetValue>0x7FFFFF00</resetValue>
+               <fields>
+                  <field>
+                     <name>EXMINCH</name>
+                     <description>Extremes detector minimum data               channel</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>3</bitWidth>
+                  </field>
+                  <field>
+                     <name>EXMIN</name>
+                     <description>Extremes detector minimum               value</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>24</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DFSDM3_EXMIN</name>
+               <displayName>DFSDM3_EXMIN</displayName>
+               <description>DFSDM Extremes detector minimum           register</description>
+               <addressOffset>0x2B4</addressOffset>
+               <size>0x20</size>
+               <access>read-only</access>
+               <resetValue>0x7FFFFF00</resetValue>
+               <fields>
+                  <field>
+                     <name>EXMINCH</name>
+                     <description>Extremes detector minimum data               channel</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>3</bitWidth>
+                  </field>
+                  <field>
+                     <name>EXMIN</name>
+                     <description>Extremes detector minimum               value</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>24</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DFSDM0_CNVTIMR</name>
+               <displayName>DFSDM0_CNVTIMR</displayName>
+               <description>DFSDM conversion timer           register</description>
+               <addressOffset>0x138</addressOffset>
+               <size>0x20</size>
+               <access>read-only</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>CNVCNT</name>
+                     <description>28-bit timer counting conversion               time</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>28</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DFSDM1_CNVTIMR</name>
+               <displayName>DFSDM1_CNVTIMR</displayName>
+               <description>DFSDM conversion timer           register</description>
+               <addressOffset>0x1B8</addressOffset>
+               <size>0x20</size>
+               <access>read-only</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>CNVCNT</name>
+                     <description>28-bit timer counting conversion               time</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>28</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DFSDM2_CNVTIMR</name>
+               <displayName>DFSDM2_CNVTIMR</displayName>
+               <description>DFSDM conversion timer           register</description>
+               <addressOffset>0x238</addressOffset>
+               <size>0x20</size>
+               <access>read-only</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>CNVCNT</name>
+                     <description>28-bit timer counting conversion               time</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>28</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DFSDM3_CNVTIMR</name>
+               <displayName>DFSDM3_CNVTIMR</displayName>
+               <description>DFSDM conversion timer           register</description>
+               <addressOffset>0x2B8</addressOffset>
+               <size>0x20</size>
+               <access>read-only</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>CNVCNT</name>
+                     <description>28-bit timer counting conversion               time</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>28</bitWidth>
+                  </field>
+               </fields>
+            </register>
+         </registers>
+      </peripheral>
+      <peripheral>
+         <name>JPEG</name>
+         <description>JPEG codec</description>
+         <groupName>JPEG</groupName>
+         <baseAddress>0x50051000</baseAddress>
+         <addressBlock>
+            <offset>0x0</offset>
+            <size>0x1000</size>
+            <usage>registers</usage>
+         </addressBlock>
+         <interrupt>
+            <name>JPEG</name>
+            <description>JPEG global interrupt</description>
+            <value>108</value>
+         </interrupt>
+         <registers>
+            <register>
+               <name>JPEG_CONFR0</name>
+               <displayName>JPEG_CONFR0</displayName>
+               <description>JPEG codec configuration register           0</description>
+               <addressOffset>0x0</addressOffset>
+               <size>0x20</size>
+               <access>write-only</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>START</name>
+                     <description>Start</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>JPEG_CONFR1</name>
+               <displayName>JPEG_CONFR1</displayName>
+               <description>JPEG codec configuration register           1</description>
+               <addressOffset>0x4</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>NF</name>
+                     <description>Number of color components</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>DE</name>
+                     <description>Decoding Enable</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>COLORSPACE</name>
+                     <description>Color Space</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>NS</name>
+                     <description>Number of components for               Scan</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>HDR</name>
+                     <description>Header Processing</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>YSIZE</name>
+                     <description>Y Size</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>JPEG_CONFR2</name>
+               <displayName>JPEG_CONFR2</displayName>
+               <description>JPEG codec configuration register           2</description>
+               <addressOffset>0x8</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>NMCU</name>
+                     <description>Number of MCU</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>26</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>JPEG_CONFR3</name>
+               <displayName>JPEG_CONFR3</displayName>
+               <description>JPEG codec configuration register           3</description>
+               <addressOffset>0xC</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>XSIZE</name>
+                     <description>X size</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>JPEG_CONFR4</name>
+               <displayName>JPEG_CONFR4</displayName>
+               <description>JPEG codec configuration register           4</description>
+               <addressOffset>0x10</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>HD</name>
+                     <description>Huffman DC</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>HA</name>
+                     <description>Huffman AC</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>QT</name>
+                     <description>Quantization Table</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>NB</name>
+                     <description>Number of Block</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+                  <field>
+                     <name>VSF</name>
+                     <description>Vertical Sampling Factor</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+                  <field>
+                     <name>HSF</name>
+                     <description>Horizontal Sampling Factor</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>JPEG_CONFR5</name>
+               <displayName>JPEG_CONFR5</displayName>
+               <description>JPEG codec configuration register           5</description>
+               <addressOffset>0x14</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>HD</name>
+                     <description>Huffman DC</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>HA</name>
+                     <description>Huffman AC</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>QT</name>
+                     <description>Quantization Table</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>NB</name>
+                     <description>Number of Block</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+                  <field>
+                     <name>VSF</name>
+                     <description>Vertical Sampling Factor</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+                  <field>
+                     <name>HSF</name>
+                     <description>Horizontal Sampling Factor</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>JPEG_CONFR6</name>
+               <displayName>JPEG_CONFR6</displayName>
+               <description>JPEG codec configuration register           6</description>
+               <addressOffset>0x18</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>HD</name>
+                     <description>Huffman DC</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>HA</name>
+                     <description>Huffman AC</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>QT</name>
+                     <description>Quantization Table</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>NB</name>
+                     <description>Number of Block</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+                  <field>
+                     <name>VSF</name>
+                     <description>Vertical Sampling Factor</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+                  <field>
+                     <name>HSF</name>
+                     <description>Horizontal Sampling Factor</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>JPEG_CONFR7</name>
+               <displayName>JPEG_CONFR7</displayName>
+               <description>JPEG codec configuration register           7</description>
+               <addressOffset>0x1C</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>HD</name>
+                     <description>Huffman DC</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>HA</name>
+                     <description>Huffman AC</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>QT</name>
+                     <description>Quantization Table</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>NB</name>
+                     <description>Number of Block</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+                  <field>
+                     <name>VSF</name>
+                     <description>Vertical Sampling Factor</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+                  <field>
+                     <name>HSF</name>
+                     <description>Horizontal Sampling Factor</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>JPEG_CR</name>
+               <displayName>JPEG_CR</displayName>
+               <description>JPEG control register</description>
+               <addressOffset>0x30</addressOffset>
+               <size>0x20</size>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>JCEN</name>
+                     <description>JPEG Core Enable</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>IFTIE</name>
+                     <description>Input FIFO Threshold Interrupt               Enable</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>IFNFIE</name>
+                     <description>Input FIFO Not Full Interrupt               Enable</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>OFTIE</name>
+                     <description>Output FIFO Threshold Interrupt               Enable</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>OFNEIE</name>
+                     <description>Output FIFO Not Empty Interrupt               Enable</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>EOCIE</name>
+                     <description>End of Conversion Interrupt               Enable</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>HPDIE</name>
+                     <description>Header Parsing Done Interrupt               Enable</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>IDMAEN</name>
+                     <description>Input DMA Enable</description>
+                     <bitOffset>11</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>ODMAEN</name>
+                     <description>Output DMA Enable</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>IFF</name>
+                     <description>Input FIFO Flush</description>
+                     <bitOffset>13</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-only</access>
+                  </field>
+                  <field>
+                     <name>OFF</name>
+                     <description>Output FIFO Flush</description>
+                     <bitOffset>14</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-only</access>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>JPEG_SR</name>
+               <displayName>JPEG_SR</displayName>
+               <description>JPEG status register</description>
+               <addressOffset>0x34</addressOffset>
+               <size>0x20</size>
+               <access>read-only</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>IFTF</name>
+                     <description>Input FIFO Threshold Flag</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>IFNFF</name>
+                     <description>Input FIFO Not Full Flag</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>OFTF</name>
+                     <description>Output FIFO Threshold Flag</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>OFNEF</name>
+                     <description>Output FIFO Not Empty Flag</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>EOCF</name>
+                     <description>End of Conversion Flag</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>HPDF</name>
+                     <description>Header Parsing Done Flag</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>COF</name>
+                     <description>Codec Operation Flag</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>JPEG_CFR</name>
+               <displayName>JPEG_CFR</displayName>
+               <description>JPEG clear flag register</description>
+               <addressOffset>0x38</addressOffset>
+               <size>0x20</size>
+               <access>write-only</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>CEOCF</name>
+                     <description>Clear End of Conversion               Flag</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CHPDF</name>
+                     <description>Clear Header Parsing Done               Flag</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>JPEG_DIR</name>
+               <displayName>JPEG_DIR</displayName>
+               <description>JPEG data input register</description>
+               <addressOffset>0x40</addressOffset>
+               <size>0x20</size>
+               <access>write-only</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DATAIN</name>
+                     <description>Data Input FIFO</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>JPEG_DOR</name>
+               <displayName>JPEG_DOR</displayName>
+               <description>JPEG data output register</description>
+               <addressOffset>0x44</addressOffset>
+               <size>0x20</size>
+               <access>read-only</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DATAOUT</name>
+                     <description>Data Output FIFO</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>QMEM0_0</name>
+               <displayName>QMEM0_0</displayName>
+               <description>JPEG quantization tables</description>
+               <addressOffset>0x50</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>QMem_RAM</name>
+                     <description>QMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>QMEM0_1</name>
+               <displayName>QMEM0_1</displayName>
+               <description>JPEG quantization tables</description>
+               <addressOffset>0x54</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>QMem_RAM</name>
+                     <description>QMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>QMEM0_2</name>
+               <displayName>QMEM0_2</displayName>
+               <description>JPEG quantization tables</description>
+               <addressOffset>0x58</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>QMem_RAM</name>
+                     <description>QMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>QMEM0_3</name>
+               <displayName>QMEM0_3</displayName>
+               <description>JPEG quantization tables</description>
+               <addressOffset>0x5C</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>QMem_RAM</name>
+                     <description>QMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>QMEM0_4</name>
+               <displayName>QMEM0_4</displayName>
+               <description>JPEG quantization tables</description>
+               <addressOffset>0x60</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>QMem_RAM</name>
+                     <description>QMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>QMEM0_5</name>
+               <displayName>QMEM0_5</displayName>
+               <description>JPEG quantization tables</description>
+               <addressOffset>0x64</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>QMem_RAM</name>
+                     <description>QMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>QMEM0_6</name>
+               <displayName>QMEM0_6</displayName>
+               <description>JPEG quantization tables</description>
+               <addressOffset>0x68</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>QMem_RAM</name>
+                     <description>QMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>QMEM0_7</name>
+               <displayName>QMEM0_7</displayName>
+               <description>JPEG quantization tables</description>
+               <addressOffset>0x6C</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>QMem_RAM</name>
+                     <description>QMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>QMEM0_8</name>
+               <displayName>QMEM0_8</displayName>
+               <description>JPEG quantization tables</description>
+               <addressOffset>0x70</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>QMem_RAM</name>
+                     <description>QMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>QMEM0_9</name>
+               <displayName>QMEM0_9</displayName>
+               <description>JPEG quantization tables</description>
+               <addressOffset>0x74</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>QMem_RAM</name>
+                     <description>QMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>QMEM0_10</name>
+               <displayName>QMEM0_10</displayName>
+               <description>JPEG quantization tables</description>
+               <addressOffset>0x78</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>QMem_RAM</name>
+                     <description>QMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>QMEM0_11</name>
+               <displayName>QMEM0_11</displayName>
+               <description>JPEG quantization tables</description>
+               <addressOffset>0x7C</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>QMem_RAM</name>
+                     <description>QMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>QMEM0_12</name>
+               <displayName>QMEM0_12</displayName>
+               <description>JPEG quantization tables</description>
+               <addressOffset>0x80</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>QMem_RAM</name>
+                     <description>QMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>QMEM0_13</name>
+               <displayName>QMEM0_13</displayName>
+               <description>JPEG quantization tables</description>
+               <addressOffset>0x84</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>QMem_RAM</name>
+                     <description>QMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>QMEM0_14</name>
+               <displayName>QMEM0_14</displayName>
+               <description>JPEG quantization tables</description>
+               <addressOffset>0x88</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>QMem_RAM</name>
+                     <description>QMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>QMEM0_15</name>
+               <displayName>QMEM0_15</displayName>
+               <description>JPEG quantization tables</description>
+               <addressOffset>0x8C</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>QMem_RAM</name>
+                     <description>QMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>QMEM1_0</name>
+               <displayName>QMEM1_0</displayName>
+               <description>JPEG quantization tables</description>
+               <addressOffset>0x90</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>QMem_RAM</name>
+                     <description>QMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>QMEM1_1</name>
+               <displayName>QMEM1_1</displayName>
+               <description>JPEG quantization tables</description>
+               <addressOffset>0x94</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>QMem_RAM</name>
+                     <description>QMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>QMEM1_2</name>
+               <displayName>QMEM1_2</displayName>
+               <description>JPEG quantization tables</description>
+               <addressOffset>0x98</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>QMem_RAM</name>
+                     <description>QMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>QMEM1_3</name>
+               <displayName>QMEM1_3</displayName>
+               <description>JPEG quantization tables</description>
+               <addressOffset>0x9C</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>QMem_RAM</name>
+                     <description>QMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>QMEM1_4</name>
+               <displayName>QMEM1_4</displayName>
+               <description>JPEG quantization tables</description>
+               <addressOffset>0xA0</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>QMem_RAM</name>
+                     <description>QMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>QMEM1_5</name>
+               <displayName>QMEM1_5</displayName>
+               <description>JPEG quantization tables</description>
+               <addressOffset>0xA4</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>QMem_RAM</name>
+                     <description>QMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>QMEM1_6</name>
+               <displayName>QMEM1_6</displayName>
+               <description>JPEG quantization tables</description>
+               <addressOffset>0xA8</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>QMem_RAM</name>
+                     <description>QMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>QMEM1_7</name>
+               <displayName>QMEM1_7</displayName>
+               <description>JPEG quantization tables</description>
+               <addressOffset>0xAC</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>QMem_RAM</name>
+                     <description>QMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>QMEM1_8</name>
+               <displayName>QMEM1_8</displayName>
+               <description>JPEG quantization tables</description>
+               <addressOffset>0xB0</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>QMem_RAM</name>
+                     <description>QMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>QMEM1_9</name>
+               <displayName>QMEM1_9</displayName>
+               <description>JPEG quantization tables</description>
+               <addressOffset>0xB4</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>QMem_RAM</name>
+                     <description>QMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>QMEM1_10</name>
+               <displayName>QMEM1_10</displayName>
+               <description>JPEG quantization tables</description>
+               <addressOffset>0xB8</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>QMem_RAM</name>
+                     <description>QMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>QMEM1_11</name>
+               <displayName>QMEM1_11</displayName>
+               <description>JPEG quantization tables</description>
+               <addressOffset>0xBC</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>QMem_RAM</name>
+                     <description>QMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>QMEM1_12</name>
+               <displayName>QMEM1_12</displayName>
+               <description>JPEG quantization tables</description>
+               <addressOffset>0xC0</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>QMem_RAM</name>
+                     <description>QMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>QMEM1_13</name>
+               <displayName>QMEM1_13</displayName>
+               <description>JPEG quantization tables</description>
+               <addressOffset>0xC4</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>QMem_RAM</name>
+                     <description>QMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>QMEM1_14</name>
+               <displayName>QMEM1_14</displayName>
+               <description>JPEG quantization tables</description>
+               <addressOffset>0xC8</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>QMem_RAM</name>
+                     <description>QMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>QMEM1_15</name>
+               <displayName>QMEM1_15</displayName>
+               <description>JPEG quantization tables</description>
+               <addressOffset>0xCC</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>QMem_RAM</name>
+                     <description>QMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>QMEM2_0</name>
+               <displayName>QMEM2_0</displayName>
+               <description>JPEG quantization tables</description>
+               <addressOffset>0xD0</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>QMem_RAM</name>
+                     <description>QMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>QMEM2_1</name>
+               <displayName>QMEM2_1</displayName>
+               <description>JPEG quantization tables</description>
+               <addressOffset>0xD4</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>QMem_RAM</name>
+                     <description>QMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>QMEM2_2</name>
+               <displayName>QMEM2_2</displayName>
+               <description>JPEG quantization tables</description>
+               <addressOffset>0xD8</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>QMem_RAM</name>
+                     <description>QMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>QMEM2_3</name>
+               <displayName>QMEM2_3</displayName>
+               <description>JPEG quantization tables</description>
+               <addressOffset>0xDC</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>QMem_RAM</name>
+                     <description>QMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>QMEM2_4</name>
+               <displayName>QMEM2_4</displayName>
+               <description>JPEG quantization tables</description>
+               <addressOffset>0xE0</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>QMem_RAM</name>
+                     <description>QMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>QMEM2_5</name>
+               <displayName>QMEM2_5</displayName>
+               <description>JPEG quantization tables</description>
+               <addressOffset>0xE4</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>QMem_RAM</name>
+                     <description>QMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>QMEM2_6</name>
+               <displayName>QMEM2_6</displayName>
+               <description>JPEG quantization tables</description>
+               <addressOffset>0xE8</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>QMem_RAM</name>
+                     <description>QMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>QMEM2_7</name>
+               <displayName>QMEM2_7</displayName>
+               <description>JPEG quantization tables</description>
+               <addressOffset>0xEC</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>QMem_RAM</name>
+                     <description>QMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>QMEM2_8</name>
+               <displayName>QMEM2_8</displayName>
+               <description>JPEG quantization tables</description>
+               <addressOffset>0xF0</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>QMem_RAM</name>
+                     <description>QMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>QMEM2_9</name>
+               <displayName>QMEM2_9</displayName>
+               <description>JPEG quantization tables</description>
+               <addressOffset>0xF4</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>QMem_RAM</name>
+                     <description>QMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>QMEM2_10</name>
+               <displayName>QMEM2_10</displayName>
+               <description>JPEG quantization tables</description>
+               <addressOffset>0xF8</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>QMem_RAM</name>
+                     <description>QMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>QMEM2_11</name>
+               <displayName>QMEM2_11</displayName>
+               <description>JPEG quantization tables</description>
+               <addressOffset>0xFC</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>QMem_RAM</name>
+                     <description>QMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>QMEM2_12</name>
+               <displayName>QMEM2_12</displayName>
+               <description>JPEG quantization tables</description>
+               <addressOffset>0x100</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>QMem_RAM</name>
+                     <description>QMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>QMEM2_13</name>
+               <displayName>QMEM2_13</displayName>
+               <description>JPEG quantization tables</description>
+               <addressOffset>0x104</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>QMem_RAM</name>
+                     <description>QMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>QMEM2_14</name>
+               <displayName>QMEM2_14</displayName>
+               <description>JPEG quantization tables</description>
+               <addressOffset>0x108</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>QMem_RAM</name>
+                     <description>QMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>QMEM2_15</name>
+               <displayName>QMEM2_15</displayName>
+               <description>JPEG quantization tables</description>
+               <addressOffset>0x10C</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>QMem_RAM</name>
+                     <description>QMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>QMEM3_0</name>
+               <displayName>QMEM3_0</displayName>
+               <description>JPEG quantization tables</description>
+               <addressOffset>0x110</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>QMem_RAM</name>
+                     <description>QMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>QMEM3_1</name>
+               <displayName>QMEM3_1</displayName>
+               <description>JPEG quantization tables</description>
+               <addressOffset>0x114</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>QMem_RAM</name>
+                     <description>QMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>QMEM3_2</name>
+               <displayName>QMEM3_2</displayName>
+               <description>JPEG quantization tables</description>
+               <addressOffset>0x118</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>QMem_RAM</name>
+                     <description>QMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>QMEM3_3</name>
+               <displayName>QMEM3_3</displayName>
+               <description>JPEG quantization tables</description>
+               <addressOffset>0x11C</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>QMem_RAM</name>
+                     <description>QMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>QMEM3_4</name>
+               <displayName>QMEM3_4</displayName>
+               <description>JPEG quantization tables</description>
+               <addressOffset>0x120</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>QMem_RAM</name>
+                     <description>QMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>QMEM3_5</name>
+               <displayName>QMEM3_5</displayName>
+               <description>JPEG quantization tables</description>
+               <addressOffset>0x124</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>QMem_RAM</name>
+                     <description>QMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>QMEM3_6</name>
+               <displayName>QMEM3_6</displayName>
+               <description>JPEG quantization tables</description>
+               <addressOffset>0x128</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>QMem_RAM</name>
+                     <description>QMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>QMEM3_7</name>
+               <displayName>QMEM3_7</displayName>
+               <description>JPEG quantization tables</description>
+               <addressOffset>0x12C</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>QMem_RAM</name>
+                     <description>QMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>QMEM3_8</name>
+               <displayName>QMEM3_8</displayName>
+               <description>JPEG quantization tables</description>
+               <addressOffset>0x130</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>QMem_RAM</name>
+                     <description>QMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>QMEM3_9</name>
+               <displayName>QMEM3_9</displayName>
+               <description>JPEG quantization tables</description>
+               <addressOffset>0x134</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>QMem_RAM</name>
+                     <description>QMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>QMEM3_10</name>
+               <displayName>QMEM3_10</displayName>
+               <description>JPEG quantization tables</description>
+               <addressOffset>0x138</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>QMem_RAM</name>
+                     <description>QMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>QMEM3_11</name>
+               <displayName>QMEM3_11</displayName>
+               <description>JPEG quantization tables</description>
+               <addressOffset>0x13C</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>QMem_RAM</name>
+                     <description>QMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>QMEM3_12</name>
+               <displayName>QMEM3_12</displayName>
+               <description>JPEG quantization tables</description>
+               <addressOffset>0x140</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>QMem_RAM</name>
+                     <description>QMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>QMEM3_13</name>
+               <displayName>QMEM3_13</displayName>
+               <description>JPEG quantization tables</description>
+               <addressOffset>0x144</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>QMem_RAM</name>
+                     <description>QMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>QMEM3_14</name>
+               <displayName>QMEM3_14</displayName>
+               <description>JPEG quantization tables</description>
+               <addressOffset>0x148</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>QMem_RAM</name>
+                     <description>QMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>QMEM3_15</name>
+               <displayName>QMEM3_15</displayName>
+               <description>JPEG quantization tables</description>
+               <addressOffset>0x14C</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>QMem_RAM</name>
+                     <description>QMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFMIN_0</name>
+               <displayName>HUFFMIN_0</displayName>
+               <description>JPEG HuffMin tables</description>
+               <addressOffset>0x150</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>HuffMin_RAM</name>
+                     <description>HuffMin RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFMIN_1</name>
+               <displayName>HUFFMIN_1</displayName>
+               <description>JPEG HuffMin tables</description>
+               <addressOffset>0x154</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>HuffMin_RAM</name>
+                     <description>HuffMin RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFMIN_2</name>
+               <displayName>HUFFMIN_2</displayName>
+               <description>JPEG HuffMin tables</description>
+               <addressOffset>0x158</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>HuffMin_RAM</name>
+                     <description>HuffMin RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFMIN_3</name>
+               <displayName>HUFFMIN_3</displayName>
+               <description>JPEG HuffMin tables</description>
+               <addressOffset>0x15C</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>HuffMin_RAM</name>
+                     <description>HuffMin RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFMIN_4</name>
+               <displayName>HUFFMIN_4</displayName>
+               <description>JPEG HuffMin tables</description>
+               <addressOffset>0x160</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>HuffMin_RAM</name>
+                     <description>HuffMin RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFMIN_5</name>
+               <displayName>HUFFMIN_5</displayName>
+               <description>JPEG HuffMin tables</description>
+               <addressOffset>0x164</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>HuffMin_RAM</name>
+                     <description>HuffMin RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFMIN_6</name>
+               <displayName>HUFFMIN_6</displayName>
+               <description>JPEG HuffMin tables</description>
+               <addressOffset>0x168</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>HuffMin_RAM</name>
+                     <description>HuffMin RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFMIN_7</name>
+               <displayName>HUFFMIN_7</displayName>
+               <description>JPEG HuffMin tables</description>
+               <addressOffset>0x16C</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>HuffMin_RAM</name>
+                     <description>HuffMin RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFMIN_8</name>
+               <displayName>HUFFMIN_8</displayName>
+               <description>JPEG HuffMin tables</description>
+               <addressOffset>0x170</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>HuffMin_RAM</name>
+                     <description>HuffMin RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFMIN_9</name>
+               <displayName>HUFFMIN_9</displayName>
+               <description>JPEG HuffMin tables</description>
+               <addressOffset>0x174</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>HuffMin_RAM</name>
+                     <description>HuffMin RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFMIN_10</name>
+               <displayName>HUFFMIN_10</displayName>
+               <description>JPEG HuffMin tables</description>
+               <addressOffset>0x178</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>HuffMin_RAM</name>
+                     <description>HuffMin RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFMIN_11</name>
+               <displayName>HUFFMIN_11</displayName>
+               <description>JPEG HuffMin tables</description>
+               <addressOffset>0x17C</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>HuffMin_RAM</name>
+                     <description>HuffMin RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFMIN_12</name>
+               <displayName>HUFFMIN_12</displayName>
+               <description>JPEG HuffMin tables</description>
+               <addressOffset>0x180</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>HuffMin_RAM</name>
+                     <description>HuffMin RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFMIN_13</name>
+               <displayName>HUFFMIN_13</displayName>
+               <description>JPEG HuffMin tables</description>
+               <addressOffset>0x184</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>HuffMin_RAM</name>
+                     <description>HuffMin RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFMIN_14</name>
+               <displayName>HUFFMIN_14</displayName>
+               <description>JPEG HuffMin tables</description>
+               <addressOffset>0x188</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>HuffMin_RAM</name>
+                     <description>HuffMin RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFMIN_15</name>
+               <displayName>HUFFMIN_15</displayName>
+               <description>JPEG HuffMin tables</description>
+               <addressOffset>0x18C</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>HuffMin_RAM</name>
+                     <description>HuffMin RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFBASE0</name>
+               <displayName>HUFFBASE0</displayName>
+               <description>JPEG HuffSymb tables</description>
+               <addressOffset>0x190</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>HuffBase_RAM_0</name>
+                     <description>HuffBase RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>9</bitWidth>
+                  </field>
+                  <field>
+                     <name>HuffBase_RAM_1</name>
+                     <description>HuffBase RAM</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>9</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFBASE1</name>
+               <displayName>HUFFBASE1</displayName>
+               <description>JPEG HuffSymb tables</description>
+               <addressOffset>0x194</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>HuffBase_RAM_0</name>
+                     <description>HuffBase RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>9</bitWidth>
+                  </field>
+                  <field>
+                     <name>HuffBase_RAM_1</name>
+                     <description>HuffBase RAM</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>9</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFBASE2</name>
+               <displayName>HUFFBASE2</displayName>
+               <description>JPEG HuffSymb tables</description>
+               <addressOffset>0x198</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>HuffBase_RAM_0</name>
+                     <description>HuffBase RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>9</bitWidth>
+                  </field>
+                  <field>
+                     <name>HuffBase_RAM_1</name>
+                     <description>HuffBase RAM</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>9</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFBASE3</name>
+               <displayName>HUFFBASE3</displayName>
+               <description>JPEG HuffSymb tables</description>
+               <addressOffset>0x19C</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>HuffBase_RAM_0</name>
+                     <description>HuffBase RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>9</bitWidth>
+                  </field>
+                  <field>
+                     <name>HuffBase_RAM_1</name>
+                     <description>HuffBase RAM</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>9</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFBASE4</name>
+               <displayName>HUFFBASE4</displayName>
+               <description>JPEG HuffSymb tables</description>
+               <addressOffset>0x1A0</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>HuffBase_RAM_0</name>
+                     <description>HuffBase RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>9</bitWidth>
+                  </field>
+                  <field>
+                     <name>HuffBase_RAM_1</name>
+                     <description>HuffBase RAM</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>9</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFBASE5</name>
+               <displayName>HUFFBASE5</displayName>
+               <description>JPEG HuffSymb tables</description>
+               <addressOffset>0x1A4</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>HuffBase_RAM_0</name>
+                     <description>HuffBase RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>9</bitWidth>
+                  </field>
+                  <field>
+                     <name>HuffBase_RAM_1</name>
+                     <description>HuffBase RAM</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>9</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFBASE6</name>
+               <displayName>HUFFBASE6</displayName>
+               <description>JPEG HuffSymb tables</description>
+               <addressOffset>0x1A8</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>HuffBase_RAM_0</name>
+                     <description>HuffBase RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>9</bitWidth>
+                  </field>
+                  <field>
+                     <name>HuffBase_RAM_1</name>
+                     <description>HuffBase RAM</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>9</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFBASE7</name>
+               <displayName>HUFFBASE7</displayName>
+               <description>JPEG HuffSymb tables</description>
+               <addressOffset>0x1AC</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>HuffBase_RAM_0</name>
+                     <description>HuffBase RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>9</bitWidth>
+                  </field>
+                  <field>
+                     <name>HuffBase_RAM_1</name>
+                     <description>HuffBase RAM</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>9</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFBASE8</name>
+               <displayName>HUFFBASE8</displayName>
+               <description>JPEG HuffSymb tables</description>
+               <addressOffset>0x1B0</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>HuffBase_RAM_0</name>
+                     <description>HuffBase RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>9</bitWidth>
+                  </field>
+                  <field>
+                     <name>HuffBase_RAM_1</name>
+                     <description>HuffBase RAM</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>9</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFBASE9</name>
+               <displayName>HUFFBASE9</displayName>
+               <description>JPEG HuffSymb tables</description>
+               <addressOffset>0x1B4</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>HuffBase_RAM_0</name>
+                     <description>HuffBase RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>9</bitWidth>
+                  </field>
+                  <field>
+                     <name>HuffBase_RAM_1</name>
+                     <description>HuffBase RAM</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>9</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFBASE10</name>
+               <displayName>HUFFBASE10</displayName>
+               <description>JPEG HuffSymb tables</description>
+               <addressOffset>0x1B8</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>HuffBase_RAM_0</name>
+                     <description>HuffBase RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>9</bitWidth>
+                  </field>
+                  <field>
+                     <name>HuffBase_RAM_1</name>
+                     <description>HuffBase RAM</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>9</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFBASE11</name>
+               <displayName>HUFFBASE11</displayName>
+               <description>JPEG HuffSymb tables</description>
+               <addressOffset>0x1BC</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>HuffBase_RAM_0</name>
+                     <description>HuffBase RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>9</bitWidth>
+                  </field>
+                  <field>
+                     <name>HuffBase_RAM_1</name>
+                     <description>HuffBase RAM</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>9</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFBASE12</name>
+               <displayName>HUFFBASE12</displayName>
+               <description>JPEG HuffSymb tables</description>
+               <addressOffset>0x1C0</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>HuffBase_RAM_0</name>
+                     <description>HuffBase RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>9</bitWidth>
+                  </field>
+                  <field>
+                     <name>HuffBase_RAM_1</name>
+                     <description>HuffBase RAM</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>9</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFBASE13</name>
+               <displayName>HUFFBASE13</displayName>
+               <description>JPEG HuffSymb tables</description>
+               <addressOffset>0x1C4</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>HuffBase_RAM_0</name>
+                     <description>HuffBase RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>9</bitWidth>
+                  </field>
+                  <field>
+                     <name>HuffBase_RAM_1</name>
+                     <description>HuffBase RAM</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>9</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFBASE14</name>
+               <displayName>HUFFBASE14</displayName>
+               <description>JPEG HuffSymb tables</description>
+               <addressOffset>0x1C8</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>HuffBase_RAM_0</name>
+                     <description>HuffBase RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>9</bitWidth>
+                  </field>
+                  <field>
+                     <name>HuffBase_RAM_1</name>
+                     <description>HuffBase RAM</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>9</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFBASE15</name>
+               <displayName>HUFFBASE15</displayName>
+               <description>JPEG HuffSymb tables</description>
+               <addressOffset>0x1CC</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>HuffBase_RAM_0</name>
+                     <description>HuffBase RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>9</bitWidth>
+                  </field>
+                  <field>
+                     <name>HuffBase_RAM_1</name>
+                     <description>HuffBase RAM</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>9</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFBASE16</name>
+               <displayName>HUFFBASE16</displayName>
+               <description>JPEG HuffSymb tables</description>
+               <addressOffset>0x1D0</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>HuffBase_RAM_0</name>
+                     <description>HuffBase RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>9</bitWidth>
+                  </field>
+                  <field>
+                     <name>HuffBase_RAM_1</name>
+                     <description>HuffBase RAM</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>9</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFBASE17</name>
+               <displayName>HUFFBASE17</displayName>
+               <description>JPEG HuffSymb tables</description>
+               <addressOffset>0x1D4</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>HuffBase_RAM_0</name>
+                     <description>HuffBase RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>9</bitWidth>
+                  </field>
+                  <field>
+                     <name>HuffBase_RAM_1</name>
+                     <description>HuffBase RAM</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>9</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFBASE18</name>
+               <displayName>HUFFBASE18</displayName>
+               <description>JPEG HuffSymb tables</description>
+               <addressOffset>0x1D8</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>HuffBase_RAM_0</name>
+                     <description>HuffBase RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>9</bitWidth>
+                  </field>
+                  <field>
+                     <name>HuffBase_RAM_1</name>
+                     <description>HuffBase RAM</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>9</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFBASE19</name>
+               <displayName>HUFFBASE19</displayName>
+               <description>JPEG HuffSymb tables</description>
+               <addressOffset>0x1DC</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>HuffBase_RAM_0</name>
+                     <description>HuffBase RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>9</bitWidth>
+                  </field>
+                  <field>
+                     <name>HuffBase_RAM_1</name>
+                     <description>HuffBase RAM</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>9</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFBASE20</name>
+               <displayName>HUFFBASE20</displayName>
+               <description>JPEG HuffSymb tables</description>
+               <addressOffset>0x1E0</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>HuffBase_RAM_0</name>
+                     <description>HuffBase RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>9</bitWidth>
+                  </field>
+                  <field>
+                     <name>HuffBase_RAM_1</name>
+                     <description>HuffBase RAM</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>9</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFBASE21</name>
+               <displayName>HUFFBASE21</displayName>
+               <description>JPEG HuffSymb tables</description>
+               <addressOffset>0x1E4</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>HuffBase_RAM_0</name>
+                     <description>HuffBase RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>9</bitWidth>
+                  </field>
+                  <field>
+                     <name>HuffBase_RAM_1</name>
+                     <description>HuffBase RAM</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>9</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFBASE22</name>
+               <displayName>HUFFBASE22</displayName>
+               <description>JPEG HuffSymb tables</description>
+               <addressOffset>0x1E8</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>HuffBase_RAM_0</name>
+                     <description>HuffBase RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>9</bitWidth>
+                  </field>
+                  <field>
+                     <name>HuffBase_RAM_1</name>
+                     <description>HuffBase RAM</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>9</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFBASE23</name>
+               <displayName>HUFFBASE23</displayName>
+               <description>JPEG HuffSymb tables</description>
+               <addressOffset>0x1EC</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>HuffBase_RAM_0</name>
+                     <description>HuffBase RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>9</bitWidth>
+                  </field>
+                  <field>
+                     <name>HuffBase_RAM_1</name>
+                     <description>HuffBase RAM</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>9</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFBASE24</name>
+               <displayName>HUFFBASE24</displayName>
+               <description>JPEG HuffSymb tables</description>
+               <addressOffset>0x1F0</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>HuffBase_RAM_0</name>
+                     <description>HuffBase RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>9</bitWidth>
+                  </field>
+                  <field>
+                     <name>HuffBase_RAM_1</name>
+                     <description>HuffBase RAM</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>9</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFBASE25</name>
+               <displayName>HUFFBASE25</displayName>
+               <description>JPEG HuffSymb tables</description>
+               <addressOffset>0x1F4</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>HuffBase_RAM_0</name>
+                     <description>HuffBase RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>9</bitWidth>
+                  </field>
+                  <field>
+                     <name>HuffBase_RAM_1</name>
+                     <description>HuffBase RAM</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>9</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFBASE26</name>
+               <displayName>HUFFBASE26</displayName>
+               <description>JPEG HuffSymb tables</description>
+               <addressOffset>0x1F8</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>HuffBase_RAM_0</name>
+                     <description>HuffBase RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>9</bitWidth>
+                  </field>
+                  <field>
+                     <name>HuffBase_RAM_1</name>
+                     <description>HuffBase RAM</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>9</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFBASE27</name>
+               <displayName>HUFFBASE27</displayName>
+               <description>JPEG HuffSymb tables</description>
+               <addressOffset>0x1FC</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>HuffBase_RAM_0</name>
+                     <description>HuffBase RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>9</bitWidth>
+                  </field>
+                  <field>
+                     <name>HuffBase_RAM_1</name>
+                     <description>HuffBase RAM</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>9</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFBASE28</name>
+               <displayName>HUFFBASE28</displayName>
+               <description>JPEG HuffSymb tables</description>
+               <addressOffset>0x200</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>HuffBase_RAM_0</name>
+                     <description>HuffBase RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>9</bitWidth>
+                  </field>
+                  <field>
+                     <name>HuffBase_RAM_1</name>
+                     <description>HuffBase RAM</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>9</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFBASE29</name>
+               <displayName>HUFFBASE29</displayName>
+               <description>JPEG HuffSymb tables</description>
+               <addressOffset>0x204</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>HuffBase_RAM_0</name>
+                     <description>HuffBase RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>9</bitWidth>
+                  </field>
+                  <field>
+                     <name>HuffBase_RAM_1</name>
+                     <description>HuffBase RAM</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>9</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFBASE30</name>
+               <displayName>HUFFBASE30</displayName>
+               <description>JPEG HuffSymb tables</description>
+               <addressOffset>0x208</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>HuffBase_RAM_0</name>
+                     <description>HuffBase RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>9</bitWidth>
+                  </field>
+                  <field>
+                     <name>HuffBase_RAM_1</name>
+                     <description>HuffBase RAM</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>9</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFBASE31</name>
+               <displayName>HUFFBASE31</displayName>
+               <description>JPEG HuffSymb tables</description>
+               <addressOffset>0x20C</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>HuffBase_RAM_0</name>
+                     <description>HuffBase RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>9</bitWidth>
+                  </field>
+                  <field>
+                     <name>HuffBase_RAM_1</name>
+                     <description>HuffBase RAM</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>9</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFSYMB0</name>
+               <displayName>HUFFSYMB0</displayName>
+               <description>JPEG HUFFSYMB tables</description>
+               <addressOffset>0x210</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>HuffSymb_RAM</name>
+                     <description>DHTSymb RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFSYMB1</name>
+               <displayName>HUFFSYMB1</displayName>
+               <description>JPEG HUFFSYMB tables</description>
+               <addressOffset>0x214</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>HuffSymb_RAM</name>
+                     <description>DHTSymb RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFSYMB2</name>
+               <displayName>HUFFSYMB2</displayName>
+               <description>JPEG HUFFSYMB tables</description>
+               <addressOffset>0x218</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>HuffSymb_RAM</name>
+                     <description>DHTSymb RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFSYMB3</name>
+               <displayName>HUFFSYMB3</displayName>
+               <description>JPEG HUFFSYMB tables</description>
+               <addressOffset>0x21C</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>HuffSymb_RAM</name>
+                     <description>DHTSymb RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFSYMB4</name>
+               <displayName>HUFFSYMB4</displayName>
+               <description>JPEG HUFFSYMB tables</description>
+               <addressOffset>0x220</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>HuffSymb_RAM</name>
+                     <description>DHTSymb RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFSYMB5</name>
+               <displayName>HUFFSYMB5</displayName>
+               <description>JPEG HUFFSYMB tables</description>
+               <addressOffset>0x224</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>HuffSymb_RAM</name>
+                     <description>DHTSymb RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFSYMB6</name>
+               <displayName>HUFFSYMB6</displayName>
+               <description>JPEG HUFFSYMB tables</description>
+               <addressOffset>0x228</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>HuffSymb_RAM</name>
+                     <description>DHTSymb RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFSYMB7</name>
+               <displayName>HUFFSYMB7</displayName>
+               <description>JPEG HUFFSYMB tables</description>
+               <addressOffset>0x22C</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>HuffSymb_RAM</name>
+                     <description>DHTSymb RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFSYMB8</name>
+               <displayName>HUFFSYMB8</displayName>
+               <description>JPEG HUFFSYMB tables</description>
+               <addressOffset>0x230</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>HuffSymb_RAM</name>
+                     <description>DHTSymb RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFSYMB9</name>
+               <displayName>HUFFSYMB9</displayName>
+               <description>JPEG HUFFSYMB tables</description>
+               <addressOffset>0x234</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>HuffSymb_RAM</name>
+                     <description>DHTSymb RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFSYMB10</name>
+               <displayName>HUFFSYMB10</displayName>
+               <description>JPEG HUFFSYMB tables</description>
+               <addressOffset>0x238</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>HuffSymb_RAM</name>
+                     <description>DHTSymb RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFSYMB11</name>
+               <displayName>HUFFSYMB11</displayName>
+               <description>JPEG HUFFSYMB tables</description>
+               <addressOffset>0x23C</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>HuffSymb_RAM</name>
+                     <description>DHTSymb RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFSYMB12</name>
+               <displayName>HUFFSYMB12</displayName>
+               <description>JPEG HUFFSYMB tables</description>
+               <addressOffset>0x240</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>HuffSymb_RAM</name>
+                     <description>DHTSymb RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFSYMB13</name>
+               <displayName>HUFFSYMB13</displayName>
+               <description>JPEG HUFFSYMB tables</description>
+               <addressOffset>0x244</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>HuffSymb_RAM</name>
+                     <description>DHTSymb RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFSYMB14</name>
+               <displayName>HUFFSYMB14</displayName>
+               <description>JPEG HUFFSYMB tables</description>
+               <addressOffset>0x248</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>HuffSymb_RAM</name>
+                     <description>DHTSymb RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFSYMB15</name>
+               <displayName>HUFFSYMB15</displayName>
+               <description>JPEG HUFFSYMB tables</description>
+               <addressOffset>0x24C</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>HuffSymb_RAM</name>
+                     <description>DHTSymb RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFSYMB16</name>
+               <displayName>HUFFSYMB16</displayName>
+               <description>JPEG HUFFSYMB tables</description>
+               <addressOffset>0x250</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>HuffSymb_RAM</name>
+                     <description>DHTSymb RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFSYMB17</name>
+               <displayName>HUFFSYMB17</displayName>
+               <description>JPEG HUFFSYMB tables</description>
+               <addressOffset>0x254</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>HuffSymb_RAM</name>
+                     <description>DHTSymb RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFSYMB18</name>
+               <displayName>HUFFSYMB18</displayName>
+               <description>JPEG HUFFSYMB tables</description>
+               <addressOffset>0x258</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>HuffSymb_RAM</name>
+                     <description>DHTSymb RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFSYMB19</name>
+               <displayName>HUFFSYMB19</displayName>
+               <description>JPEG HUFFSYMB tables</description>
+               <addressOffset>0x25C</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>HuffSymb_RAM</name>
+                     <description>DHTSymb RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFSYMB20</name>
+               <displayName>HUFFSYMB20</displayName>
+               <description>JPEG HUFFSYMB tables</description>
+               <addressOffset>0x260</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>HuffSymb_RAM</name>
+                     <description>DHTSymb RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFSYMB21</name>
+               <displayName>HUFFSYMB21</displayName>
+               <description>JPEG HUFFSYMB tables</description>
+               <addressOffset>0x264</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>HuffSymb_RAM</name>
+                     <description>DHTSymb RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFSYMB22</name>
+               <displayName>HUFFSYMB22</displayName>
+               <description>JPEG HUFFSYMB tables</description>
+               <addressOffset>0x268</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>HuffSymb_RAM</name>
+                     <description>DHTSymb RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFSYMB23</name>
+               <displayName>HUFFSYMB23</displayName>
+               <description>JPEG HUFFSYMB tables</description>
+               <addressOffset>0x26C</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>HuffSymb_RAM</name>
+                     <description>DHTSymb RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFSYMB24</name>
+               <displayName>HUFFSYMB24</displayName>
+               <description>JPEG HUFFSYMB tables</description>
+               <addressOffset>0x270</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>HuffSymb_RAM</name>
+                     <description>DHTSymb RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFSYMB25</name>
+               <displayName>HUFFSYMB25</displayName>
+               <description>JPEG HUFFSYMB tables</description>
+               <addressOffset>0x274</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>HuffSymb_RAM</name>
+                     <description>DHTSymb RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFSYMB26</name>
+               <displayName>HUFFSYMB26</displayName>
+               <description>JPEG HUFFSYMB tables</description>
+               <addressOffset>0x278</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>HuffSymb_RAM</name>
+                     <description>DHTSymb RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFSYMB27</name>
+               <displayName>HUFFSYMB27</displayName>
+               <description>JPEG HUFFSYMB tables</description>
+               <addressOffset>0x27C</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>HuffSymb_RAM</name>
+                     <description>DHTSymb RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFSYMB28</name>
+               <displayName>HUFFSYMB28</displayName>
+               <description>JPEG HUFFSYMB tables</description>
+               <addressOffset>0x280</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>HuffSymb_RAM</name>
+                     <description>DHTSymb RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFSYMB29</name>
+               <displayName>HUFFSYMB29</displayName>
+               <description>JPEG HUFFSYMB tables</description>
+               <addressOffset>0x284</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>HuffSymb_RAM</name>
+                     <description>DHTSymb RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFSYMB30</name>
+               <displayName>HUFFSYMB30</displayName>
+               <description>JPEG HUFFSYMB tables</description>
+               <addressOffset>0x288</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>HuffSymb_RAM</name>
+                     <description>DHTSymb RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFSYMB31</name>
+               <displayName>HUFFSYMB31</displayName>
+               <description>JPEG HUFFSYMB tables</description>
+               <addressOffset>0x28C</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>HuffSymb_RAM</name>
+                     <description>DHTSymb RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFSYMB32</name>
+               <displayName>HUFFSYMB32</displayName>
+               <description>JPEG HUFFSYMB tables</description>
+               <addressOffset>0x290</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>HuffSymb_RAM</name>
+                     <description>DHTSymb RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFSYMB33</name>
+               <displayName>HUFFSYMB33</displayName>
+               <description>JPEG HUFFSYMB tables</description>
+               <addressOffset>0x294</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>HuffSymb_RAM</name>
+                     <description>DHTSymb RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFSYMB34</name>
+               <displayName>HUFFSYMB34</displayName>
+               <description>JPEG HUFFSYMB tables</description>
+               <addressOffset>0x298</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>HuffSymb_RAM</name>
+                     <description>DHTSymb RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFSYMB35</name>
+               <displayName>HUFFSYMB35</displayName>
+               <description>JPEG HUFFSYMB tables</description>
+               <addressOffset>0x29C</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>HuffSymb_RAM</name>
+                     <description>DHTSymb RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFSYMB36</name>
+               <displayName>HUFFSYMB36</displayName>
+               <description>JPEG HUFFSYMB tables</description>
+               <addressOffset>0x2A0</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>HuffSymb_RAM</name>
+                     <description>DHTSymb RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFSYMB37</name>
+               <displayName>HUFFSYMB37</displayName>
+               <description>JPEG HUFFSYMB tables</description>
+               <addressOffset>0x2A4</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>HuffSymb_RAM</name>
+                     <description>DHTSymb RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFSYMB38</name>
+               <displayName>HUFFSYMB38</displayName>
+               <description>JPEG HUFFSYMB tables</description>
+               <addressOffset>0x2A8</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>HuffSymb_RAM</name>
+                     <description>DHTSymb RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFSYMB39</name>
+               <displayName>HUFFSYMB39</displayName>
+               <description>JPEG HUFFSYMB tables</description>
+               <addressOffset>0x2AC</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>HuffSymb_RAM</name>
+                     <description>DHTSymb RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFSYMB40</name>
+               <displayName>HUFFSYMB40</displayName>
+               <description>JPEG HUFFSYMB tables</description>
+               <addressOffset>0x2B0</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>HuffSymb_RAM</name>
+                     <description>DHTSymb RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFSYMB41</name>
+               <displayName>HUFFSYMB41</displayName>
+               <description>JPEG HUFFSYMB tables</description>
+               <addressOffset>0x2B4</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>HuffSymb_RAM</name>
+                     <description>DHTSymb RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFSYMB42</name>
+               <displayName>HUFFSYMB42</displayName>
+               <description>JPEG HUFFSYMB tables</description>
+               <addressOffset>0x2B8</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>HuffSymb_RAM</name>
+                     <description>DHTSymb RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFSYMB43</name>
+               <displayName>HUFFSYMB43</displayName>
+               <description>JPEG HUFFSYMB tables</description>
+               <addressOffset>0x2BC</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>HuffSymb_RAM</name>
+                     <description>DHTSymb RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFSYMB44</name>
+               <displayName>HUFFSYMB44</displayName>
+               <description>JPEG HUFFSYMB tables</description>
+               <addressOffset>0x2C0</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>HuffSymb_RAM</name>
+                     <description>DHTSymb RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFSYMB45</name>
+               <displayName>HUFFSYMB45</displayName>
+               <description>JPEG HUFFSYMB tables</description>
+               <addressOffset>0x2C4</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>HuffSymb_RAM</name>
+                     <description>DHTSymb RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFSYMB46</name>
+               <displayName>HUFFSYMB46</displayName>
+               <description>JPEG HUFFSYMB tables</description>
+               <addressOffset>0x2C8</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>HuffSymb_RAM</name>
+                     <description>DHTSymb RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFSYMB47</name>
+               <displayName>HUFFSYMB47</displayName>
+               <description>JPEG HUFFSYMB tables</description>
+               <addressOffset>0x2CC</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>HuffSymb_RAM</name>
+                     <description>DHTSymb RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFSYMB48</name>
+               <displayName>HUFFSYMB48</displayName>
+               <description>JPEG HUFFSYMB tables</description>
+               <addressOffset>0x2D0</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>HuffSymb_RAM</name>
+                     <description>DHTSymb RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFSYMB49</name>
+               <displayName>HUFFSYMB49</displayName>
+               <description>JPEG HUFFSYMB tables</description>
+               <addressOffset>0x2D4</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>HuffSymb_RAM</name>
+                     <description>DHTSymb RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFSYMB50</name>
+               <displayName>HUFFSYMB50</displayName>
+               <description>JPEG HUFFSYMB tables</description>
+               <addressOffset>0x2D8</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>HuffSymb_RAM</name>
+                     <description>DHTSymb RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFSYMB51</name>
+               <displayName>HUFFSYMB51</displayName>
+               <description>JPEG HUFFSYMB tables</description>
+               <addressOffset>0x2DC</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>HuffSymb_RAM</name>
+                     <description>DHTSymb RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFSYMB52</name>
+               <displayName>HUFFSYMB52</displayName>
+               <description>JPEG HUFFSYMB tables</description>
+               <addressOffset>0x2E0</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>HuffSymb_RAM</name>
+                     <description>DHTSymb RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFSYMB53</name>
+               <displayName>HUFFSYMB53</displayName>
+               <description>JPEG HUFFSYMB tables</description>
+               <addressOffset>0x2E4</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>HuffSymb_RAM</name>
+                     <description>DHTSymb RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFSYMB54</name>
+               <displayName>HUFFSYMB54</displayName>
+               <description>JPEG HUFFSYMB tables</description>
+               <addressOffset>0x2E8</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>HuffSymb_RAM</name>
+                     <description>DHTSymb RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFSYMB55</name>
+               <displayName>HUFFSYMB55</displayName>
+               <description>JPEG HUFFSYMB tables</description>
+               <addressOffset>0x2EC</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>HuffSymb_RAM</name>
+                     <description>DHTSymb RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFSYMB56</name>
+               <displayName>HUFFSYMB56</displayName>
+               <description>JPEG HUFFSYMB tables</description>
+               <addressOffset>0x2F0</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>HuffSymb_RAM</name>
+                     <description>DHTSymb RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFSYMB57</name>
+               <displayName>HUFFSYMB57</displayName>
+               <description>JPEG HUFFSYMB tables</description>
+               <addressOffset>0x2F4</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>HuffSymb_RAM</name>
+                     <description>DHTSymb RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFSYMB58</name>
+               <displayName>HUFFSYMB58</displayName>
+               <description>JPEG HUFFSYMB tables</description>
+               <addressOffset>0x2F8</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>HuffSymb_RAM</name>
+                     <description>DHTSymb RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFSYMB59</name>
+               <displayName>HUFFSYMB59</displayName>
+               <description>JPEG HUFFSYMB tables</description>
+               <addressOffset>0x2FC</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>HuffSymb_RAM</name>
+                     <description>DHTSymb RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFSYMB60</name>
+               <displayName>HUFFSYMB60</displayName>
+               <description>JPEG HUFFSYMB tables</description>
+               <addressOffset>0x300</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>HuffSymb_RAM</name>
+                     <description>DHTSymb RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFSYMB61</name>
+               <displayName>HUFFSYMB61</displayName>
+               <description>JPEG HUFFSYMB tables</description>
+               <addressOffset>0x304</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>HuffSymb_RAM</name>
+                     <description>DHTSymb RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFSYMB62</name>
+               <displayName>HUFFSYMB62</displayName>
+               <description>JPEG HUFFSYMB tables</description>
+               <addressOffset>0x308</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>HuffSymb_RAM</name>
+                     <description>DHTSymb RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFSYMB63</name>
+               <displayName>HUFFSYMB63</displayName>
+               <description>JPEG HUFFSYMB tables</description>
+               <addressOffset>0x30C</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>HuffSymb_RAM</name>
+                     <description>DHTSymb RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFSYMB64</name>
+               <displayName>HUFFSYMB64</displayName>
+               <description>JPEG HUFFSYMB tables</description>
+               <addressOffset>0x310</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>HuffSymb_RAM</name>
+                     <description>DHTSymb RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFSYMB65</name>
+               <displayName>HUFFSYMB65</displayName>
+               <description>JPEG HUFFSYMB tables</description>
+               <addressOffset>0x314</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>HuffSymb_RAM</name>
+                     <description>DHTSymb RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFSYMB66</name>
+               <displayName>HUFFSYMB66</displayName>
+               <description>JPEG HUFFSYMB tables</description>
+               <addressOffset>0x318</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>HuffSymb_RAM</name>
+                     <description>DHTSymb RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFSYMB67</name>
+               <displayName>HUFFSYMB67</displayName>
+               <description>JPEG HUFFSYMB tables</description>
+               <addressOffset>0x31C</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>HuffSymb_RAM</name>
+                     <description>DHTSymb RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFSYMB68</name>
+               <displayName>HUFFSYMB68</displayName>
+               <description>JPEG HUFFSYMB tables</description>
+               <addressOffset>0x320</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>HuffSymb_RAM</name>
+                     <description>DHTSymb RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFSYMB69</name>
+               <displayName>HUFFSYMB69</displayName>
+               <description>JPEG HUFFSYMB tables</description>
+               <addressOffset>0x324</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>HuffSymb_RAM</name>
+                     <description>DHTSymb RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFSYMB70</name>
+               <displayName>HUFFSYMB70</displayName>
+               <description>JPEG HUFFSYMB tables</description>
+               <addressOffset>0x328</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>HuffSymb_RAM</name>
+                     <description>DHTSymb RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFSYMB71</name>
+               <displayName>HUFFSYMB71</displayName>
+               <description>JPEG HUFFSYMB tables</description>
+               <addressOffset>0x32C</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>HuffSymb_RAM</name>
+                     <description>DHTSymb RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFSYMB72</name>
+               <displayName>HUFFSYMB72</displayName>
+               <description>JPEG HUFFSYMB tables</description>
+               <addressOffset>0x330</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>HuffSymb_RAM</name>
+                     <description>DHTSymb RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFSYMB73</name>
+               <displayName>HUFFSYMB73</displayName>
+               <description>JPEG HUFFSYMB tables</description>
+               <addressOffset>0x334</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>HuffSymb_RAM</name>
+                     <description>DHTSymb RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFSYMB74</name>
+               <displayName>HUFFSYMB74</displayName>
+               <description>JPEG HUFFSYMB tables</description>
+               <addressOffset>0x338</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>HuffSymb_RAM</name>
+                     <description>DHTSymb RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFSYMB75</name>
+               <displayName>HUFFSYMB75</displayName>
+               <description>JPEG HUFFSYMB tables</description>
+               <addressOffset>0x33C</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>HuffSymb_RAM</name>
+                     <description>DHTSymb RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFSYMB76</name>
+               <displayName>HUFFSYMB76</displayName>
+               <description>JPEG HUFFSYMB tables</description>
+               <addressOffset>0x340</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>HuffSymb_RAM</name>
+                     <description>DHTSymb RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFSYMB77</name>
+               <displayName>HUFFSYMB77</displayName>
+               <description>JPEG HUFFSYMB tables</description>
+               <addressOffset>0x344</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>HuffSymb_RAM</name>
+                     <description>DHTSymb RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFSYMB78</name>
+               <displayName>HUFFSYMB78</displayName>
+               <description>JPEG HUFFSYMB tables</description>
+               <addressOffset>0x348</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>HuffSymb_RAM</name>
+                     <description>DHTSymb RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFSYMB79</name>
+               <displayName>HUFFSYMB79</displayName>
+               <description>JPEG HUFFSYMB tables</description>
+               <addressOffset>0x34C</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>HuffSymb_RAM</name>
+                     <description>DHTSymb RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFSYMB80</name>
+               <displayName>HUFFSYMB80</displayName>
+               <description>JPEG HUFFSYMB tables</description>
+               <addressOffset>0x350</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>HuffSymb_RAM</name>
+                     <description>DHTSymb RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFSYMB81</name>
+               <displayName>HUFFSYMB81</displayName>
+               <description>JPEG HUFFSYMB tables</description>
+               <addressOffset>0x354</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>HuffSymb_RAM</name>
+                     <description>DHTSymb RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFSYMB82</name>
+               <displayName>HUFFSYMB82</displayName>
+               <description>JPEG HUFFSYMB tables</description>
+               <addressOffset>0x358</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>HuffSymb_RAM</name>
+                     <description>DHTSymb RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFSYMB83</name>
+               <displayName>HUFFSYMB83</displayName>
+               <description>JPEG HUFFSYMB tables</description>
+               <addressOffset>0x35C</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>HuffSymb_RAM</name>
+                     <description>DHTSymb RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DHTMEM0</name>
+               <displayName>DHTMEM0</displayName>
+               <description>JPEG DHTMem tables</description>
+               <addressOffset>0x360</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DHTMEM2</name>
+               <displayName>DHTMEM2</displayName>
+               <description>JPEG DHTMem tables</description>
+               <addressOffset>0x364</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DHTMEM3</name>
+               <displayName>DHTMEM3</displayName>
+               <description>JPEG DHTMem tables</description>
+               <addressOffset>0x368</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DHTMEM4</name>
+               <displayName>DHTMEM4</displayName>
+               <description>JPEG DHTMem tables</description>
+               <addressOffset>0x36C</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DHTMEM5</name>
+               <displayName>DHTMEM5</displayName>
+               <description>JPEG DHTMem tables</description>
+               <addressOffset>0x370</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DHTMEM6</name>
+               <displayName>DHTMEM6</displayName>
+               <description>JPEG DHTMem tables</description>
+               <addressOffset>0x374</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DHTMEM7</name>
+               <displayName>DHTMEM7</displayName>
+               <description>JPEG DHTMem tables</description>
+               <addressOffset>0x378</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DHTMEM8</name>
+               <displayName>DHTMEM8</displayName>
+               <description>JPEG DHTMem tables</description>
+               <addressOffset>0x37C</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DHTMEM9</name>
+               <displayName>DHTMEM9</displayName>
+               <description>JPEG DHTMem tables</description>
+               <addressOffset>0x380</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DHTMEM10</name>
+               <displayName>DHTMEM10</displayName>
+               <description>JPEG DHTMem tables</description>
+               <addressOffset>0x384</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DHTMEM11</name>
+               <displayName>DHTMEM11</displayName>
+               <description>JPEG DHTMem tables</description>
+               <addressOffset>0x388</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DHTMEM12</name>
+               <displayName>DHTMEM12</displayName>
+               <description>JPEG DHTMem tables</description>
+               <addressOffset>0x38C</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DHTMEM13</name>
+               <displayName>DHTMEM13</displayName>
+               <description>JPEG DHTMem tables</description>
+               <addressOffset>0x390</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DHTMEM14</name>
+               <displayName>DHTMEM14</displayName>
+               <description>JPEG DHTMem tables</description>
+               <addressOffset>0x394</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DHTMEM15</name>
+               <displayName>DHTMEM15</displayName>
+               <description>JPEG DHTMem tables</description>
+               <addressOffset>0x398</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DHTMEM16</name>
+               <displayName>DHTMEM16</displayName>
+               <description>JPEG DHTMem tables</description>
+               <addressOffset>0x39C</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DHTMEM17</name>
+               <displayName>DHTMEM17</displayName>
+               <description>JPEG DHTMem tables</description>
+               <addressOffset>0x3A0</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DHTMEM18</name>
+               <displayName>DHTMEM18</displayName>
+               <description>JPEG DHTMem tables</description>
+               <addressOffset>0x3A4</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DHTMEM19</name>
+               <displayName>DHTMEM19</displayName>
+               <description>JPEG DHTMem tables</description>
+               <addressOffset>0x3A8</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DHTMEM20</name>
+               <displayName>DHTMEM20</displayName>
+               <description>JPEG DHTMem tables</description>
+               <addressOffset>0x3AC</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DHTMEM21</name>
+               <displayName>DHTMEM21</displayName>
+               <description>JPEG DHTMem tables</description>
+               <addressOffset>0x3B0</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DHTMEM22</name>
+               <displayName>DHTMEM22</displayName>
+               <description>JPEG DHTMem tables</description>
+               <addressOffset>0x3B4</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DHTMEM23</name>
+               <displayName>DHTMEM23</displayName>
+               <description>JPEG DHTMem tables</description>
+               <addressOffset>0x3B8</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DHTMEM24</name>
+               <displayName>DHTMEM24</displayName>
+               <description>JPEG DHTMem tables</description>
+               <addressOffset>0x3BC</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DHTMEM25</name>
+               <displayName>DHTMEM25</displayName>
+               <description>JPEG DHTMem tables</description>
+               <addressOffset>0x3C0</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DHTMEM26</name>
+               <displayName>DHTMEM26</displayName>
+               <description>JPEG DHTMem tables</description>
+               <addressOffset>0x3C4</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DHTMEM27</name>
+               <displayName>DHTMEM27</displayName>
+               <description>JPEG DHTMem tables</description>
+               <addressOffset>0x3C8</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DHTMEM28</name>
+               <displayName>DHTMEM28</displayName>
+               <description>JPEG DHTMem tables</description>
+               <addressOffset>0x3CC</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DHTMEM29</name>
+               <displayName>DHTMEM29</displayName>
+               <description>JPEG DHTMem tables</description>
+               <addressOffset>0x3D0</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DHTMEM30</name>
+               <displayName>DHTMEM30</displayName>
+               <description>JPEG DHTMem tables</description>
+               <addressOffset>0x3D4</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DHTMEM31</name>
+               <displayName>DHTMEM31</displayName>
+               <description>JPEG DHTMem tables</description>
+               <addressOffset>0x3D8</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DHTMEM32</name>
+               <displayName>DHTMEM32</displayName>
+               <description>JPEG DHTMem tables</description>
+               <addressOffset>0x3DC</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DHTMEM33</name>
+               <displayName>DHTMEM33</displayName>
+               <description>JPEG DHTMem tables</description>
+               <addressOffset>0x3E0</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DHTMEM34</name>
+               <displayName>DHTMEM34</displayName>
+               <description>JPEG DHTMem tables</description>
+               <addressOffset>0x3E4</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DHTMEM35</name>
+               <displayName>DHTMEM35</displayName>
+               <description>JPEG DHTMem tables</description>
+               <addressOffset>0x3E8</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DHTMEM36</name>
+               <displayName>DHTMEM36</displayName>
+               <description>JPEG DHTMem tables</description>
+               <addressOffset>0x3EC</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DHTMEM37</name>
+               <displayName>DHTMEM37</displayName>
+               <description>JPEG DHTMem tables</description>
+               <addressOffset>0x3F0</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DHTMEM38</name>
+               <displayName>DHTMEM38</displayName>
+               <description>JPEG DHTMem tables</description>
+               <addressOffset>0x3F4</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DHTMEM39</name>
+               <displayName>DHTMEM39</displayName>
+               <description>JPEG DHTMem tables</description>
+               <addressOffset>0x3F8</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DHTMEM40</name>
+               <displayName>DHTMEM40</displayName>
+               <description>JPEG DHTMem tables</description>
+               <addressOffset>0x3FC</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DHTMEM41</name>
+               <displayName>DHTMEM41</displayName>
+               <description>JPEG DHTMem tables</description>
+               <addressOffset>0x400</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DHTMEM42</name>
+               <displayName>DHTMEM42</displayName>
+               <description>JPEG DHTMem tables</description>
+               <addressOffset>0x404</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DHTMEM43</name>
+               <displayName>DHTMEM43</displayName>
+               <description>JPEG DHTMem tables</description>
+               <addressOffset>0x408</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DHTMEM44</name>
+               <displayName>DHTMEM44</displayName>
+               <description>JPEG DHTMem tables</description>
+               <addressOffset>0x40C</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DHTMEM45</name>
+               <displayName>DHTMEM45</displayName>
+               <description>JPEG DHTMem tables</description>
+               <addressOffset>0x410</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DHTMEM46</name>
+               <displayName>DHTMEM46</displayName>
+               <description>JPEG DHTMem tables</description>
+               <addressOffset>0x414</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DHTMEM47</name>
+               <displayName>DHTMEM47</displayName>
+               <description>JPEG DHTMem tables</description>
+               <addressOffset>0x418</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DHTMEM48</name>
+               <displayName>DHTMEM48</displayName>
+               <description>JPEG DHTMem tables</description>
+               <addressOffset>0x41C</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DHTMEM49</name>
+               <displayName>DHTMEM49</displayName>
+               <description>JPEG DHTMem tables</description>
+               <addressOffset>0x420</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DHTMEM50</name>
+               <displayName>DHTMEM50</displayName>
+               <description>JPEG DHTMem tables</description>
+               <addressOffset>0x424</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DHTMEM51</name>
+               <displayName>DHTMEM51</displayName>
+               <description>JPEG DHTMem tables</description>
+               <addressOffset>0x428</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DHTMEM52</name>
+               <displayName>DHTMEM52</displayName>
+               <description>JPEG DHTMem tables</description>
+               <addressOffset>0x42C</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DHTMEM53</name>
+               <displayName>DHTMEM53</displayName>
+               <description>JPEG DHTMem tables</description>
+               <addressOffset>0x430</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DHTMEM54</name>
+               <displayName>DHTMEM54</displayName>
+               <description>JPEG DHTMem tables</description>
+               <addressOffset>0x434</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DHTMEM55</name>
+               <displayName>DHTMEM55</displayName>
+               <description>JPEG DHTMem tables</description>
+               <addressOffset>0x438</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DHTMEM56</name>
+               <displayName>DHTMEM56</displayName>
+               <description>JPEG DHTMem tables</description>
+               <addressOffset>0x43C</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DHTMEM57</name>
+               <displayName>DHTMEM57</displayName>
+               <description>JPEG DHTMem tables</description>
+               <addressOffset>0x440</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DHTMEM58</name>
+               <displayName>DHTMEM58</displayName>
+               <description>JPEG DHTMem tables</description>
+               <addressOffset>0x444</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DHTMEM59</name>
+               <displayName>DHTMEM59</displayName>
+               <description>JPEG DHTMem tables</description>
+               <addressOffset>0x448</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DHTMEM60</name>
+               <displayName>DHTMEM60</displayName>
+               <description>JPEG DHTMem tables</description>
+               <addressOffset>0x44C</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DHTMEM61</name>
+               <displayName>DHTMEM61</displayName>
+               <description>JPEG DHTMem tables</description>
+               <addressOffset>0x450</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DHTMEM62</name>
+               <displayName>DHTMEM62</displayName>
+               <description>JPEG DHTMem tables</description>
+               <addressOffset>0x454</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DHTMEM63</name>
+               <displayName>DHTMEM63</displayName>
+               <description>JPEG DHTMem tables</description>
+               <addressOffset>0x458</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DHTMEM64</name>
+               <displayName>DHTMEM64</displayName>
+               <description>JPEG DHTMem tables</description>
+               <addressOffset>0x45C</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DHTMEM65</name>
+               <displayName>DHTMEM65</displayName>
+               <description>JPEG DHTMem tables</description>
+               <addressOffset>0x460</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DHTMEM66</name>
+               <displayName>DHTMEM66</displayName>
+               <description>JPEG DHTMem tables</description>
+               <addressOffset>0x464</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DHTMEM67</name>
+               <displayName>DHTMEM67</displayName>
+               <description>JPEG DHTMem tables</description>
+               <addressOffset>0x468</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DHTMEM68</name>
+               <displayName>DHTMEM68</displayName>
+               <description>JPEG DHTMem tables</description>
+               <addressOffset>0x46C</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DHTMEM69</name>
+               <displayName>DHTMEM69</displayName>
+               <description>JPEG DHTMem tables</description>
+               <addressOffset>0x470</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DHTMEM70</name>
+               <displayName>DHTMEM70</displayName>
+               <description>JPEG DHTMem tables</description>
+               <addressOffset>0x474</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DHTMEM71</name>
+               <displayName>DHTMEM71</displayName>
+               <description>JPEG DHTMem tables</description>
+               <addressOffset>0x478</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DHTMEM72</name>
+               <displayName>DHTMEM72</displayName>
+               <description>JPEG DHTMem tables</description>
+               <addressOffset>0x47C</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DHTMEM73</name>
+               <displayName>DHTMEM73</displayName>
+               <description>JPEG DHTMem tables</description>
+               <addressOffset>0x480</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DHTMEM74</name>
+               <displayName>DHTMEM74</displayName>
+               <description>JPEG DHTMem tables</description>
+               <addressOffset>0x484</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DHTMEM75</name>
+               <displayName>DHTMEM75</displayName>
+               <description>JPEG DHTMem tables</description>
+               <addressOffset>0x488</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DHTMEM76</name>
+               <displayName>DHTMEM76</displayName>
+               <description>JPEG DHTMem tables</description>
+               <addressOffset>0x48C</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DHTMEM77</name>
+               <displayName>DHTMEM77</displayName>
+               <description>JPEG DHTMem tables</description>
+               <addressOffset>0x490</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DHTMEM78</name>
+               <displayName>DHTMEM78</displayName>
+               <description>JPEG DHTMem tables</description>
+               <addressOffset>0x494</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DHTMEM79</name>
+               <displayName>DHTMEM79</displayName>
+               <description>JPEG DHTMem tables</description>
+               <addressOffset>0x498</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DHTMEM80</name>
+               <displayName>DHTMEM80</displayName>
+               <description>JPEG DHTMem tables</description>
+               <addressOffset>0x49C</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DHTMEM81</name>
+               <displayName>DHTMEM81</displayName>
+               <description>JPEG DHTMem tables</description>
+               <addressOffset>0x4A0</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DHTMEM82</name>
+               <displayName>DHTMEM82</displayName>
+               <description>JPEG DHTMem tables</description>
+               <addressOffset>0x4A4</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DHTMEM83</name>
+               <displayName>DHTMEM83</displayName>
+               <description>JPEG DHTMem tables</description>
+               <addressOffset>0x4A8</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DHTMEM84</name>
+               <displayName>DHTMEM84</displayName>
+               <description>JPEG DHTMem tables</description>
+               <addressOffset>0x4AC</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DHTMEM85</name>
+               <displayName>DHTMEM85</displayName>
+               <description>JPEG DHTMem tables</description>
+               <addressOffset>0x4B0</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DHTMEM86</name>
+               <displayName>DHTMEM86</displayName>
+               <description>JPEG DHTMem tables</description>
+               <addressOffset>0x4B4</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DHTMEM87</name>
+               <displayName>DHTMEM87</displayName>
+               <description>JPEG DHTMem tables</description>
+               <addressOffset>0x4B8</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DHTMEM88</name>
+               <displayName>DHTMEM88</displayName>
+               <description>JPEG DHTMem tables</description>
+               <addressOffset>0x4BC</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DHTMEM89</name>
+               <displayName>DHTMEM89</displayName>
+               <description>JPEG DHTMem tables</description>
+               <addressOffset>0x4C0</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DHTMEM90</name>
+               <displayName>DHTMEM90</displayName>
+               <description>JPEG DHTMem tables</description>
+               <addressOffset>0x4C4</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DHTMEM91</name>
+               <displayName>DHTMEM91</displayName>
+               <description>JPEG DHTMem tables</description>
+               <addressOffset>0x4C8</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DHTMEM92</name>
+               <displayName>DHTMEM92</displayName>
+               <description>JPEG DHTMem tables</description>
+               <addressOffset>0x4CC</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DHTMEM93</name>
+               <displayName>DHTMEM93</displayName>
+               <description>JPEG DHTMem tables</description>
+               <addressOffset>0x4D0</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DHTMEM94</name>
+               <displayName>DHTMEM94</displayName>
+               <description>JPEG DHTMem tables</description>
+               <addressOffset>0x4D4</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DHTMEM95</name>
+               <displayName>DHTMEM95</displayName>
+               <description>JPEG DHTMem tables</description>
+               <addressOffset>0x4D8</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DHTMEM96</name>
+               <displayName>DHTMEM96</displayName>
+               <description>JPEG DHTMem tables</description>
+               <addressOffset>0x4DC</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DHTMEM97</name>
+               <displayName>DHTMEM97</displayName>
+               <description>JPEG DHTMem tables</description>
+               <addressOffset>0x4E0</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DHTMEM98</name>
+               <displayName>DHTMEM98</displayName>
+               <description>JPEG DHTMem tables</description>
+               <addressOffset>0x4E4</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DHTMEM99</name>
+               <displayName>DHTMEM99</displayName>
+               <description>JPEG DHTMem tables</description>
+               <addressOffset>0x4E8</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DHTMEM100</name>
+               <displayName>DHTMEM100</displayName>
+               <description>JPEG DHTMem tables</description>
+               <addressOffset>0x4EC</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DHTMEM101</name>
+               <displayName>DHTMEM101</displayName>
+               <description>JPEG DHTMem tables</description>
+               <addressOffset>0x4F0</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DHTMEM102</name>
+               <displayName>DHTMEM102</displayName>
+               <description>JPEG DHTMem tables</description>
+               <addressOffset>0x4F4</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DHTMEM103</name>
+               <displayName>DHTMEM103</displayName>
+               <description>JPEG DHTMem tables</description>
+               <addressOffset>0x4F8</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFENC_AC0_0</name>
+               <displayName>HUFFENC_AC0_0</displayName>
+               <description>JPEG encoder, AC Huffman table           0</description>
+               <addressOffset>0x500</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFENC_AC0_1</name>
+               <displayName>HUFFENC_AC0_1</displayName>
+               <description>JPEG encoder, AC Huffman table           0</description>
+               <addressOffset>0x504</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFENC_AC0_2</name>
+               <displayName>HUFFENC_AC0_2</displayName>
+               <description>JPEG encoder, AC Huffman table           0</description>
+               <addressOffset>0x508</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFENC_AC0_3</name>
+               <displayName>HUFFENC_AC0_3</displayName>
+               <description>JPEG encoder, AC Huffman table           0</description>
+               <addressOffset>0x50C</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFENC_AC0_4</name>
+               <displayName>HUFFENC_AC0_4</displayName>
+               <description>JPEG encoder, AC Huffman table           0</description>
+               <addressOffset>0x510</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFENC_AC0_5</name>
+               <displayName>HUFFENC_AC0_5</displayName>
+               <description>JPEG encoder, AC Huffman table           0</description>
+               <addressOffset>0x514</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFENC_AC0_6</name>
+               <displayName>HUFFENC_AC0_6</displayName>
+               <description>JPEG encoder, AC Huffman table           0</description>
+               <addressOffset>0x518</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFENC_AC0_7</name>
+               <displayName>HUFFENC_AC0_7</displayName>
+               <description>JPEG encoder, AC Huffman table           0</description>
+               <addressOffset>0x51C</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFENC_AC0_8</name>
+               <displayName>HUFFENC_AC0_8</displayName>
+               <description>JPEG encoder, AC Huffman table           0</description>
+               <addressOffset>0x520</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFENC_AC0_9</name>
+               <displayName>HUFFENC_AC0_9</displayName>
+               <description>JPEG encoder, AC Huffman table           0</description>
+               <addressOffset>0x524</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFENC_AC0_10</name>
+               <displayName>HUFFENC_AC0_10</displayName>
+               <description>JPEG encoder, AC Huffman table           0</description>
+               <addressOffset>0x528</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFENC_AC0_11</name>
+               <displayName>HUFFENC_AC0_11</displayName>
+               <description>JPEG encoder, AC Huffman table           0</description>
+               <addressOffset>0x52C</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFENC_AC0_12</name>
+               <displayName>HUFFENC_AC0_12</displayName>
+               <description>JPEG encoder, AC Huffman table           0</description>
+               <addressOffset>0x530</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFENC_AC0_13</name>
+               <displayName>HUFFENC_AC0_13</displayName>
+               <description>JPEG encoder, AC Huffman table           0</description>
+               <addressOffset>0x534</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFENC_AC0_14</name>
+               <displayName>HUFFENC_AC0_14</displayName>
+               <description>JPEG encoder, AC Huffman table           0</description>
+               <addressOffset>0x538</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFENC_AC0_15</name>
+               <displayName>HUFFENC_AC0_15</displayName>
+               <description>JPEG encoder, AC Huffman table           0</description>
+               <addressOffset>0x53C</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFENC_AC0_16</name>
+               <displayName>HUFFENC_AC0_16</displayName>
+               <description>JPEG encoder, AC Huffman table           0</description>
+               <addressOffset>0x540</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFENC_AC0_17</name>
+               <displayName>HUFFENC_AC0_17</displayName>
+               <description>JPEG encoder, AC Huffman table           0</description>
+               <addressOffset>0x544</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFENC_AC0_18</name>
+               <displayName>HUFFENC_AC0_18</displayName>
+               <description>JPEG encoder, AC Huffman table           0</description>
+               <addressOffset>0x548</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFENC_AC0_19</name>
+               <displayName>HUFFENC_AC0_19</displayName>
+               <description>JPEG encoder, AC Huffman table           0</description>
+               <addressOffset>0x54C</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFENC_AC0_20</name>
+               <displayName>HUFFENC_AC0_20</displayName>
+               <description>JPEG encoder, AC Huffman table           0</description>
+               <addressOffset>0x550</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFENC_AC0_21</name>
+               <displayName>HUFFENC_AC0_21</displayName>
+               <description>JPEG encoder, AC Huffman table           0</description>
+               <addressOffset>0x554</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFENC_AC0_22</name>
+               <displayName>HUFFENC_AC0_22</displayName>
+               <description>JPEG encoder, AC Huffman table           0</description>
+               <addressOffset>0x558</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFENC_AC0_23</name>
+               <displayName>HUFFENC_AC0_23</displayName>
+               <description>JPEG encoder, AC Huffman table           0</description>
+               <addressOffset>0x55C</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFENC_AC0_24</name>
+               <displayName>HUFFENC_AC0_24</displayName>
+               <description>JPEG encoder, AC Huffman table           0</description>
+               <addressOffset>0x560</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFENC_AC0_25</name>
+               <displayName>HUFFENC_AC0_25</displayName>
+               <description>JPEG encoder, AC Huffman table           0</description>
+               <addressOffset>0x564</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFENC_AC0_26</name>
+               <displayName>HUFFENC_AC0_26</displayName>
+               <description>JPEG encoder, AC Huffman table           0</description>
+               <addressOffset>0x568</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFENC_AC0_27</name>
+               <displayName>HUFFENC_AC0_27</displayName>
+               <description>JPEG encoder, AC Huffman table           0</description>
+               <addressOffset>0x56C</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFENC_AC0_28</name>
+               <displayName>HUFFENC_AC0_28</displayName>
+               <description>JPEG encoder, AC Huffman table           0</description>
+               <addressOffset>0x570</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFENC_AC0_29</name>
+               <displayName>HUFFENC_AC0_29</displayName>
+               <description>JPEG encoder, AC Huffman table           0</description>
+               <addressOffset>0x574</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFENC_AC0_30</name>
+               <displayName>HUFFENC_AC0_30</displayName>
+               <description>JPEG encoder, AC Huffman table           0</description>
+               <addressOffset>0x578</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFENC_AC0_31</name>
+               <displayName>HUFFENC_AC0_31</displayName>
+               <description>JPEG encoder, AC Huffman table           0</description>
+               <addressOffset>0x57C</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFENC_AC0_32</name>
+               <displayName>HUFFENC_AC0_32</displayName>
+               <description>JPEG encoder, AC Huffman table           0</description>
+               <addressOffset>0x580</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFENC_AC0_33</name>
+               <displayName>HUFFENC_AC0_33</displayName>
+               <description>JPEG encoder, AC Huffman table           0</description>
+               <addressOffset>0x584</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFENC_AC0_34</name>
+               <displayName>HUFFENC_AC0_34</displayName>
+               <description>JPEG encoder, AC Huffman table           0</description>
+               <addressOffset>0x588</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFENC_AC0_35</name>
+               <displayName>HUFFENC_AC0_35</displayName>
+               <description>JPEG encoder, AC Huffman table           0</description>
+               <addressOffset>0x58C</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFENC_AC0_36</name>
+               <displayName>HUFFENC_AC0_36</displayName>
+               <description>JPEG encoder, AC Huffman table           0</description>
+               <addressOffset>0x590</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFENC_AC0_37</name>
+               <displayName>HUFFENC_AC0_37</displayName>
+               <description>JPEG encoder, AC Huffman table           0</description>
+               <addressOffset>0x594</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFENC_AC0_38</name>
+               <displayName>HUFFENC_AC0_38</displayName>
+               <description>JPEG encoder, AC Huffman table           0</description>
+               <addressOffset>0x598</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFENC_AC0_39</name>
+               <displayName>HUFFENC_AC0_39</displayName>
+               <description>JPEG encoder, AC Huffman table           0</description>
+               <addressOffset>0x59C</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFENC_AC0_40</name>
+               <displayName>HUFFENC_AC0_40</displayName>
+               <description>JPEG encoder, AC Huffman table           0</description>
+               <addressOffset>0x5A0</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFENC_AC0_41</name>
+               <displayName>HUFFENC_AC0_41</displayName>
+               <description>JPEG encoder, AC Huffman table           0</description>
+               <addressOffset>0x5A4</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFENC_AC0_42</name>
+               <displayName>HUFFENC_AC0_42</displayName>
+               <description>JPEG encoder, AC Huffman table           0</description>
+               <addressOffset>0x5A8</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFENC_AC0_43</name>
+               <displayName>HUFFENC_AC0_43</displayName>
+               <description>JPEG encoder, AC Huffman table           0</description>
+               <addressOffset>0x5AC</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFENC_AC0_44</name>
+               <displayName>HUFFENC_AC0_44</displayName>
+               <description>JPEG encoder, AC Huffman table           0</description>
+               <addressOffset>0x5B0</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFENC_AC0_45</name>
+               <displayName>HUFFENC_AC0_45</displayName>
+               <description>JPEG encoder, AC Huffman table           0</description>
+               <addressOffset>0x5B4</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFENC_AC0_46</name>
+               <displayName>HUFFENC_AC0_46</displayName>
+               <description>JPEG encoder, AC Huffman table           0</description>
+               <addressOffset>0x5B8</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFENC_AC0_47</name>
+               <displayName>HUFFENC_AC0_47</displayName>
+               <description>JPEG encoder, AC Huffman table           0</description>
+               <addressOffset>0x5BC</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFENC_AC0_48</name>
+               <displayName>HUFFENC_AC0_48</displayName>
+               <description>JPEG encoder, AC Huffman table           0</description>
+               <addressOffset>0x5C0</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFENC_AC0_49</name>
+               <displayName>HUFFENC_AC0_49</displayName>
+               <description>JPEG encoder, AC Huffman table           0</description>
+               <addressOffset>0x5C4</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFENC_AC0_50</name>
+               <displayName>HUFFENC_AC0_50</displayName>
+               <description>JPEG encoder, AC Huffman table           0</description>
+               <addressOffset>0x5C8</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFENC_AC0_51</name>
+               <displayName>HUFFENC_AC0_51</displayName>
+               <description>JPEG encoder, AC Huffman table           0</description>
+               <addressOffset>0x5CC</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFENC_AC0_52</name>
+               <displayName>HUFFENC_AC0_52</displayName>
+               <description>JPEG encoder, AC Huffman table           0</description>
+               <addressOffset>0x5D0</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFENC_AC0_53</name>
+               <displayName>HUFFENC_AC0_53</displayName>
+               <description>JPEG encoder, AC Huffman table           0</description>
+               <addressOffset>0x5D4</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFENC_AC0_54</name>
+               <displayName>HUFFENC_AC0_54</displayName>
+               <description>JPEG encoder, AC Huffman table           0</description>
+               <addressOffset>0x5D8</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFENC_AC0_55</name>
+               <displayName>HUFFENC_AC0_55</displayName>
+               <description>JPEG encoder, AC Huffman table           0</description>
+               <addressOffset>0x5DC</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFENC_AC0_56</name>
+               <displayName>HUFFENC_AC0_56</displayName>
+               <description>JPEG encoder, AC Huffman table           0</description>
+               <addressOffset>0x5E0</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFENC_AC0_57</name>
+               <displayName>HUFFENC_AC0_57</displayName>
+               <description>JPEG encoder, AC Huffman table           0</description>
+               <addressOffset>0x5E4</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFENC_AC0_58</name>
+               <displayName>HUFFENC_AC0_58</displayName>
+               <description>JPEG encoder, AC Huffman table           0</description>
+               <addressOffset>0x5E8</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFENC_AC0_59</name>
+               <displayName>HUFFENC_AC0_59</displayName>
+               <description>JPEG encoder, AC Huffman table           0</description>
+               <addressOffset>0x5EC</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFENC_AC0_60</name>
+               <displayName>HUFFENC_AC0_60</displayName>
+               <description>JPEG encoder, AC Huffman table           0</description>
+               <addressOffset>0x5F0</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFENC_AC0_61</name>
+               <displayName>HUFFENC_AC0_61</displayName>
+               <description>JPEG encoder, AC Huffman table           0</description>
+               <addressOffset>0x5F4</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFENC_AC0_62</name>
+               <displayName>HUFFENC_AC0_62</displayName>
+               <description>JPEG encoder, AC Huffman table           0</description>
+               <addressOffset>0x5F8</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFENC_AC0_63</name>
+               <displayName>HUFFENC_AC0_63</displayName>
+               <description>JPEG encoder, AC Huffman table           0</description>
+               <addressOffset>0x5FC</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFENC_AC0_64</name>
+               <displayName>HUFFENC_AC0_64</displayName>
+               <description>JPEG encoder, AC Huffman table           0</description>
+               <addressOffset>0x600</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFENC_AC0_65</name>
+               <displayName>HUFFENC_AC0_65</displayName>
+               <description>JPEG encoder, AC Huffman table           0</description>
+               <addressOffset>0x604</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFENC_AC0_66</name>
+               <displayName>HUFFENC_AC0_66</displayName>
+               <description>JPEG encoder, AC Huffman table           0</description>
+               <addressOffset>0x608</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFENC_AC0_67</name>
+               <displayName>HUFFENC_AC0_67</displayName>
+               <description>JPEG encoder, AC Huffman table           0</description>
+               <addressOffset>0x60C</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFENC_AC0_68</name>
+               <displayName>HUFFENC_AC0_68</displayName>
+               <description>JPEG encoder, AC Huffman table           0</description>
+               <addressOffset>0x610</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFENC_AC0_69</name>
+               <displayName>HUFFENC_AC0_69</displayName>
+               <description>JPEG encoder, AC Huffman table           0</description>
+               <addressOffset>0x614</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFENC_AC0_70</name>
+               <displayName>HUFFENC_AC0_70</displayName>
+               <description>JPEG encoder, AC Huffman table           0</description>
+               <addressOffset>0x618</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFENC_AC0_71</name>
+               <displayName>HUFFENC_AC0_71</displayName>
+               <description>JPEG encoder, AC Huffman table           0</description>
+               <addressOffset>0x61C</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFENC_AC0_72</name>
+               <displayName>HUFFENC_AC0_72</displayName>
+               <description>JPEG encoder, AC Huffman table           0</description>
+               <addressOffset>0x620</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFENC_AC0_73</name>
+               <displayName>HUFFENC_AC0_73</displayName>
+               <description>JPEG encoder, AC Huffman table           0</description>
+               <addressOffset>0x624</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFENC_AC0_74</name>
+               <displayName>HUFFENC_AC0_74</displayName>
+               <description>JPEG encoder, AC Huffman table           0</description>
+               <addressOffset>0x628</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFENC_AC0_75</name>
+               <displayName>HUFFENC_AC0_75</displayName>
+               <description>JPEG encoder, AC Huffman table           0</description>
+               <addressOffset>0x62C</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFENC_AC0_76</name>
+               <displayName>HUFFENC_AC0_76</displayName>
+               <description>JPEG encoder, AC Huffman table           0</description>
+               <addressOffset>0x630</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFENC_AC0_77</name>
+               <displayName>HUFFENC_AC0_77</displayName>
+               <description>JPEG encoder, AC Huffman table           0</description>
+               <addressOffset>0x634</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFENC_AC0_78</name>
+               <displayName>HUFFENC_AC0_78</displayName>
+               <description>JPEG encoder, AC Huffman table           0</description>
+               <addressOffset>0x638</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFENC_AC0_79</name>
+               <displayName>HUFFENC_AC0_79</displayName>
+               <description>JPEG encoder, AC Huffman table           0</description>
+               <addressOffset>0x63C</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFENC_AC0_80</name>
+               <displayName>HUFFENC_AC0_80</displayName>
+               <description>JPEG encoder, AC Huffman table           0</description>
+               <addressOffset>0x640</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFENC_AC0_81</name>
+               <displayName>HUFFENC_AC0_81</displayName>
+               <description>JPEG encoder, AC Huffman table           0</description>
+               <addressOffset>0x644</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFENC_AC0_82</name>
+               <displayName>HUFFENC_AC0_82</displayName>
+               <description>JPEG encoder, AC Huffman table           0</description>
+               <addressOffset>0x648</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFENC_AC0_83</name>
+               <displayName>HUFFENC_AC0_83</displayName>
+               <description>JPEG encoder, AC Huffman table           0</description>
+               <addressOffset>0x64C</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFENC_AC0_84</name>
+               <displayName>HUFFENC_AC0_84</displayName>
+               <description>JPEG encoder, AC Huffman table           0</description>
+               <addressOffset>0x650</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFENC_AC0_85</name>
+               <displayName>HUFFENC_AC0_85</displayName>
+               <description>JPEG encoder, AC Huffman table           0</description>
+               <addressOffset>0x654</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFENC_AC0_86</name>
+               <displayName>HUFFENC_AC0_86</displayName>
+               <description>JPEG encoder, AC Huffman table           0</description>
+               <addressOffset>0x658</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFENC_AC0_87</name>
+               <displayName>HUFFENC_AC0_87</displayName>
+               <description>JPEG encoder, AC Huffman table           0</description>
+               <addressOffset>0x65C</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFENC_AC1_0</name>
+               <displayName>HUFFENC_AC1_0</displayName>
+               <description>JPEG encoder, AC Huffman table           1</description>
+               <addressOffset>0x660</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFENC_AC1_1</name>
+               <displayName>HUFFENC_AC1_1</displayName>
+               <description>JPEG encoder, AC Huffman table           1</description>
+               <addressOffset>0x664</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFENC_AC1_2</name>
+               <displayName>HUFFENC_AC1_2</displayName>
+               <description>JPEG encoder, AC Huffman table           1</description>
+               <addressOffset>0x668</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFENC_AC1_3</name>
+               <displayName>HUFFENC_AC1_3</displayName>
+               <description>JPEG encoder, AC Huffman table           1</description>
+               <addressOffset>0x66C</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFENC_AC1_4</name>
+               <displayName>HUFFENC_AC1_4</displayName>
+               <description>JPEG encoder, AC Huffman table           1</description>
+               <addressOffset>0x670</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFENC_AC1_5</name>
+               <displayName>HUFFENC_AC1_5</displayName>
+               <description>JPEG encoder, AC Huffman table           1</description>
+               <addressOffset>0x674</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFENC_AC1_6</name>
+               <displayName>HUFFENC_AC1_6</displayName>
+               <description>JPEG encoder, AC Huffman table           1</description>
+               <addressOffset>0x678</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFENC_AC1_7</name>
+               <displayName>HUFFENC_AC1_7</displayName>
+               <description>JPEG encoder, AC Huffman table           1</description>
+               <addressOffset>0x67C</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFENC_AC1_8</name>
+               <displayName>HUFFENC_AC1_8</displayName>
+               <description>JPEG encoder, AC Huffman table           1</description>
+               <addressOffset>0x680</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFENC_AC1_9</name>
+               <displayName>HUFFENC_AC1_9</displayName>
+               <description>JPEG encoder, AC Huffman table           1</description>
+               <addressOffset>0x684</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFENC_AC1_10</name>
+               <displayName>HUFFENC_AC1_10</displayName>
+               <description>JPEG encoder, AC Huffman table           1</description>
+               <addressOffset>0x688</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFENC_AC1_11</name>
+               <displayName>HUFFENC_AC1_11</displayName>
+               <description>JPEG encoder, AC Huffman table           1</description>
+               <addressOffset>0x68C</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFENC_AC1_12</name>
+               <displayName>HUFFENC_AC1_12</displayName>
+               <description>JPEG encoder, AC Huffman table           1</description>
+               <addressOffset>0x690</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFENC_AC1_13</name>
+               <displayName>HUFFENC_AC1_13</displayName>
+               <description>JPEG encoder, AC Huffman table           1</description>
+               <addressOffset>0x694</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFENC_AC1_14</name>
+               <displayName>HUFFENC_AC1_14</displayName>
+               <description>JPEG encoder, AC Huffman table           1</description>
+               <addressOffset>0x698</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFENC_AC1_15</name>
+               <displayName>HUFFENC_AC1_15</displayName>
+               <description>JPEG encoder, AC Huffman table           1</description>
+               <addressOffset>0x69C</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFENC_AC1_16</name>
+               <displayName>HUFFENC_AC1_16</displayName>
+               <description>JPEG encoder, AC Huffman table           1</description>
+               <addressOffset>0x6A0</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFENC_AC1_17</name>
+               <displayName>HUFFENC_AC1_17</displayName>
+               <description>JPEG encoder, AC Huffman table           1</description>
+               <addressOffset>0x6A4</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFENC_AC1_18</name>
+               <displayName>HUFFENC_AC1_18</displayName>
+               <description>JPEG encoder, AC Huffman table           1</description>
+               <addressOffset>0x6A8</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFENC_AC1_19</name>
+               <displayName>HUFFENC_AC1_19</displayName>
+               <description>JPEG encoder, AC Huffman table           1</description>
+               <addressOffset>0x6AC</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFENC_AC1_20</name>
+               <displayName>HUFFENC_AC1_20</displayName>
+               <description>JPEG encoder, AC Huffman table           1</description>
+               <addressOffset>0x6B0</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFENC_AC1_21</name>
+               <displayName>HUFFENC_AC1_21</displayName>
+               <description>JPEG encoder, AC Huffman table           1</description>
+               <addressOffset>0x6B4</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFENC_AC1_22</name>
+               <displayName>HUFFENC_AC1_22</displayName>
+               <description>JPEG encoder, AC Huffman table           1</description>
+               <addressOffset>0x6B8</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFENC_AC1_23</name>
+               <displayName>HUFFENC_AC1_23</displayName>
+               <description>JPEG encoder, AC Huffman table           1</description>
+               <addressOffset>0x6BC</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFENC_AC1_24</name>
+               <displayName>HUFFENC_AC1_24</displayName>
+               <description>JPEG encoder, AC Huffman table           1</description>
+               <addressOffset>0x6C0</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFENC_AC1_25</name>
+               <displayName>HUFFENC_AC1_25</displayName>
+               <description>JPEG encoder, AC Huffman table           1</description>
+               <addressOffset>0x6C4</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFENC_AC1_26</name>
+               <displayName>HUFFENC_AC1_26</displayName>
+               <description>JPEG encoder, AC Huffman table           1</description>
+               <addressOffset>0x6C8</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFENC_AC1_27</name>
+               <displayName>HUFFENC_AC1_27</displayName>
+               <description>JPEG encoder, AC Huffman table           1</description>
+               <addressOffset>0x6CC</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFENC_AC1_28</name>
+               <displayName>HUFFENC_AC1_28</displayName>
+               <description>JPEG encoder, AC Huffman table           1</description>
+               <addressOffset>0x6D0</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFENC_AC1_29</name>
+               <displayName>HUFFENC_AC1_29</displayName>
+               <description>JPEG encoder, AC Huffman table           1</description>
+               <addressOffset>0x6D4</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFENC_AC1_30</name>
+               <displayName>HUFFENC_AC1_30</displayName>
+               <description>JPEG encoder, AC Huffman table           1</description>
+               <addressOffset>0x6D8</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFENC_AC1_31</name>
+               <displayName>HUFFENC_AC1_31</displayName>
+               <description>JPEG encoder, AC Huffman table           1</description>
+               <addressOffset>0x6DC</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFENC_AC1_32</name>
+               <displayName>HUFFENC_AC1_32</displayName>
+               <description>JPEG encoder, AC Huffman table           1</description>
+               <addressOffset>0x6E0</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFENC_AC1_33</name>
+               <displayName>HUFFENC_AC1_33</displayName>
+               <description>JPEG encoder, AC Huffman table           1</description>
+               <addressOffset>0x6E4</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFENC_AC1_34</name>
+               <displayName>HUFFENC_AC1_34</displayName>
+               <description>JPEG encoder, AC Huffman table           1</description>
+               <addressOffset>0x6E8</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFENC_AC1_35</name>
+               <displayName>HUFFENC_AC1_35</displayName>
+               <description>JPEG encoder, AC Huffman table           1</description>
+               <addressOffset>0x6EC</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFENC_AC1_36</name>
+               <displayName>HUFFENC_AC1_36</displayName>
+               <description>JPEG encoder, AC Huffman table           1</description>
+               <addressOffset>0x6F0</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFENC_AC1_37</name>
+               <displayName>HUFFENC_AC1_37</displayName>
+               <description>JPEG encoder, AC Huffman table           1</description>
+               <addressOffset>0x6F4</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFENC_AC1_38</name>
+               <displayName>HUFFENC_AC1_38</displayName>
+               <description>JPEG encoder, AC Huffman table           1</description>
+               <addressOffset>0x6F8</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFENC_AC1_39</name>
+               <displayName>HUFFENC_AC1_39</displayName>
+               <description>JPEG encoder, AC Huffman table           1</description>
+               <addressOffset>0x6FC</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFENC_AC1_40</name>
+               <displayName>HUFFENC_AC1_40</displayName>
+               <description>JPEG encoder, AC Huffman table           1</description>
+               <addressOffset>0x700</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFENC_AC1_41</name>
+               <displayName>HUFFENC_AC1_41</displayName>
+               <description>JPEG encoder, AC Huffman table           1</description>
+               <addressOffset>0x704</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFENC_AC1_42</name>
+               <displayName>HUFFENC_AC1_42</displayName>
+               <description>JPEG encoder, AC Huffman table           1</description>
+               <addressOffset>0x708</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFENC_AC1_43</name>
+               <displayName>HUFFENC_AC1_43</displayName>
+               <description>JPEG encoder, AC Huffman table           1</description>
+               <addressOffset>0x70C</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFENC_AC1_44</name>
+               <displayName>HUFFENC_AC1_44</displayName>
+               <description>JPEG encoder, AC Huffman table           1</description>
+               <addressOffset>0x710</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFENC_AC1_45</name>
+               <displayName>HUFFENC_AC1_45</displayName>
+               <description>JPEG encoder, AC Huffman table           1</description>
+               <addressOffset>0x714</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFENC_AC1_46</name>
+               <displayName>HUFFENC_AC1_46</displayName>
+               <description>JPEG encoder, AC Huffman table           1</description>
+               <addressOffset>0x718</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFENC_AC1_47</name>
+               <displayName>HUFFENC_AC1_47</displayName>
+               <description>JPEG encoder, AC Huffman table           1</description>
+               <addressOffset>0x71C</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFENC_AC1_48</name>
+               <displayName>HUFFENC_AC1_48</displayName>
+               <description>JPEG encoder, AC Huffman table           1</description>
+               <addressOffset>0x720</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFENC_AC1_49</name>
+               <displayName>HUFFENC_AC1_49</displayName>
+               <description>JPEG encoder, AC Huffman table           1</description>
+               <addressOffset>0x724</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFENC_AC1_50</name>
+               <displayName>HUFFENC_AC1_50</displayName>
+               <description>JPEG encoder, AC Huffman table           1</description>
+               <addressOffset>0x728</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFENC_AC1_51</name>
+               <displayName>HUFFENC_AC1_51</displayName>
+               <description>JPEG encoder, AC Huffman table           1</description>
+               <addressOffset>0x72C</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFENC_AC1_52</name>
+               <displayName>HUFFENC_AC1_52</displayName>
+               <description>JPEG encoder, AC Huffman table           1</description>
+               <addressOffset>0x730</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFENC_AC1_53</name>
+               <displayName>HUFFENC_AC1_53</displayName>
+               <description>JPEG encoder, AC Huffman table           1</description>
+               <addressOffset>0x734</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFENC_AC1_54</name>
+               <displayName>HUFFENC_AC1_54</displayName>
+               <description>JPEG encoder, AC Huffman table           1</description>
+               <addressOffset>0x738</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFENC_AC1_55</name>
+               <displayName>HUFFENC_AC1_55</displayName>
+               <description>JPEG encoder, AC Huffman table           1</description>
+               <addressOffset>0x73C</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFENC_AC1_56</name>
+               <displayName>HUFFENC_AC1_56</displayName>
+               <description>JPEG encoder, AC Huffman table           1</description>
+               <addressOffset>0x740</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFENC_AC1_57</name>
+               <displayName>HUFFENC_AC1_57</displayName>
+               <description>JPEG encoder, AC Huffman table           1</description>
+               <addressOffset>0x744</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFENC_AC1_58</name>
+               <displayName>HUFFENC_AC1_58</displayName>
+               <description>JPEG encoder, AC Huffman table           1</description>
+               <addressOffset>0x748</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFENC_AC1_59</name>
+               <displayName>HUFFENC_AC1_59</displayName>
+               <description>JPEG encoder, AC Huffman table           1</description>
+               <addressOffset>0x74C</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFENC_AC1_60</name>
+               <displayName>HUFFENC_AC1_60</displayName>
+               <description>JPEG encoder, AC Huffman table           1</description>
+               <addressOffset>0x750</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFENC_AC1_61</name>
+               <displayName>HUFFENC_AC1_61</displayName>
+               <description>JPEG encoder, AC Huffman table           1</description>
+               <addressOffset>0x754</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFENC_AC1_62</name>
+               <displayName>HUFFENC_AC1_62</displayName>
+               <description>JPEG encoder, AC Huffman table           1</description>
+               <addressOffset>0x758</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFENC_AC1_63</name>
+               <displayName>HUFFENC_AC1_63</displayName>
+               <description>JPEG encoder, AC Huffman table           1</description>
+               <addressOffset>0x75C</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFENC_AC1_64</name>
+               <displayName>HUFFENC_AC1_64</displayName>
+               <description>JPEG encoder, AC Huffman table           1</description>
+               <addressOffset>0x760</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFENC_AC1_65</name>
+               <displayName>HUFFENC_AC1_65</displayName>
+               <description>JPEG encoder, AC Huffman table           1</description>
+               <addressOffset>0x764</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFENC_AC1_66</name>
+               <displayName>HUFFENC_AC1_66</displayName>
+               <description>JPEG encoder, AC Huffman table           1</description>
+               <addressOffset>0x768</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFENC_AC1_67</name>
+               <displayName>HUFFENC_AC1_67</displayName>
+               <description>JPEG encoder, AC Huffman table           1</description>
+               <addressOffset>0x76C</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFENC_AC1_68</name>
+               <displayName>HUFFENC_AC1_68</displayName>
+               <description>JPEG encoder, AC Huffman table           1</description>
+               <addressOffset>0x770</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFENC_AC1_69</name>
+               <displayName>HUFFENC_AC1_69</displayName>
+               <description>JPEG encoder, AC Huffman table           1</description>
+               <addressOffset>0x774</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFENC_AC1_70</name>
+               <displayName>HUFFENC_AC1_70</displayName>
+               <description>JPEG encoder, AC Huffman table           1</description>
+               <addressOffset>0x778</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFENC_AC1_71</name>
+               <displayName>HUFFENC_AC1_71</displayName>
+               <description>JPEG encoder, AC Huffman table           1</description>
+               <addressOffset>0x77C</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFENC_AC1_72</name>
+               <displayName>HUFFENC_AC1_72</displayName>
+               <description>JPEG encoder, AC Huffman table           1</description>
+               <addressOffset>0x780</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFENC_AC1_73</name>
+               <displayName>HUFFENC_AC1_73</displayName>
+               <description>JPEG encoder, AC Huffman table           1</description>
+               <addressOffset>0x784</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFENC_AC1_74</name>
+               <displayName>HUFFENC_AC1_74</displayName>
+               <description>JPEG encoder, AC Huffman table           1</description>
+               <addressOffset>0x788</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFENC_AC1_75</name>
+               <displayName>HUFFENC_AC1_75</displayName>
+               <description>JPEG encoder, AC Huffman table           1</description>
+               <addressOffset>0x78C</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFENC_AC1_76</name>
+               <displayName>HUFFENC_AC1_76</displayName>
+               <description>JPEG encoder, AC Huffman table           1</description>
+               <addressOffset>0x790</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFENC_AC1_77</name>
+               <displayName>HUFFENC_AC1_77</displayName>
+               <description>JPEG encoder, AC Huffman table           1</description>
+               <addressOffset>0x794</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFENC_AC1_78</name>
+               <displayName>HUFFENC_AC1_78</displayName>
+               <description>JPEG encoder, AC Huffman table           1</description>
+               <addressOffset>0x798</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFENC_AC1_79</name>
+               <displayName>HUFFENC_AC1_79</displayName>
+               <description>JPEG encoder, AC Huffman table           1</description>
+               <addressOffset>0x79C</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFENC_AC1_80</name>
+               <displayName>HUFFENC_AC1_80</displayName>
+               <description>JPEG encoder, AC Huffman table           1</description>
+               <addressOffset>0x7A0</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFENC_AC1_81</name>
+               <displayName>HUFFENC_AC1_81</displayName>
+               <description>JPEG encoder, AC Huffman table           1</description>
+               <addressOffset>0x7A4</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFENC_AC1_82</name>
+               <displayName>HUFFENC_AC1_82</displayName>
+               <description>JPEG encoder, AC Huffman table           1</description>
+               <addressOffset>0x7A8</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFENC_AC1_83</name>
+               <displayName>HUFFENC_AC1_83</displayName>
+               <description>JPEG encoder, AC Huffman table           1</description>
+               <addressOffset>0x7AC</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFENC_AC1_84</name>
+               <displayName>HUFFENC_AC1_84</displayName>
+               <description>JPEG encoder, AC Huffman table           1</description>
+               <addressOffset>0x7B0</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFENC_AC1_85</name>
+               <displayName>HUFFENC_AC1_85</displayName>
+               <description>JPEG encoder, AC Huffman table           1</description>
+               <addressOffset>0x7B4</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFENC_AC1_86</name>
+               <displayName>HUFFENC_AC1_86</displayName>
+               <description>JPEG encoder, AC Huffman table           1</description>
+               <addressOffset>0x7B8</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFENC_AC1_87</name>
+               <displayName>HUFFENC_AC1_87</displayName>
+               <description>JPEG encoder, AC Huffman table           1</description>
+               <addressOffset>0x7BC</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFENC_DC0_0</name>
+               <displayName>HUFFENC_DC0_0</displayName>
+               <description>JPEG encoder, DC Huffman table           0</description>
+               <addressOffset>0x7C0</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFENC_DC0_1</name>
+               <displayName>HUFFENC_DC0_1</displayName>
+               <description>JPEG encoder, DC Huffman table           0</description>
+               <addressOffset>0x7C4</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFENC_DC0_2</name>
+               <displayName>HUFFENC_DC0_2</displayName>
+               <description>JPEG encoder, DC Huffman table           0</description>
+               <addressOffset>0x7C8</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFENC_DC0_3</name>
+               <displayName>HUFFENC_DC0_3</displayName>
+               <description>JPEG encoder, DC Huffman table           0</description>
+               <addressOffset>0x7CC</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFENC_DC0_4</name>
+               <displayName>HUFFENC_DC0_4</displayName>
+               <description>JPEG encoder, DC Huffman table           0</description>
+               <addressOffset>0x7D0</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFENC_DC0_5</name>
+               <displayName>HUFFENC_DC0_5</displayName>
+               <description>JPEG encoder, DC Huffman table           0</description>
+               <addressOffset>0x7D4</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFENC_DC0_6</name>
+               <displayName>HUFFENC_DC0_6</displayName>
+               <description>JPEG encoder, DC Huffman table           0</description>
+               <addressOffset>0x7D8</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFENC_DC0_7</name>
+               <displayName>HUFFENC_DC0_7</displayName>
+               <description>JPEG encoder, DC Huffman table           0</description>
+               <addressOffset>0x7DC</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFENC_DC1_0</name>
+               <displayName>HUFFENC_DC1_0</displayName>
+               <description>JPEG encoder, DC Huffman table           1</description>
+               <addressOffset>0x7E0</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFENC_DC1_1</name>
+               <displayName>HUFFENC_DC1_1</displayName>
+               <description>JPEG encoder, DC Huffman table           1</description>
+               <addressOffset>0x7E4</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFENC_DC1_2</name>
+               <displayName>HUFFENC_DC1_2</displayName>
+               <description>JPEG encoder, DC Huffman table           1</description>
+               <addressOffset>0x7E8</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFENC_DC1_3</name>
+               <displayName>HUFFENC_DC1_3</displayName>
+               <description>JPEG encoder, DC Huffman table           1</description>
+               <addressOffset>0x7EC</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFENC_DC1_4</name>
+               <displayName>HUFFENC_DC1_4</displayName>
+               <description>JPEG encoder, DC Huffman table           1</description>
+               <addressOffset>0x7F0</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFENC_DC1_5</name>
+               <displayName>HUFFENC_DC1_5</displayName>
+               <description>JPEG encoder, DC Huffman table           1</description>
+               <addressOffset>0x7F4</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFENC_DC1_6</name>
+               <displayName>HUFFENC_DC1_6</displayName>
+               <description>JPEG encoder, DC Huffman table           1</description>
+               <addressOffset>0x7F8</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HUFFENC_DC1_7</name>
+               <displayName>HUFFENC_DC1_7</displayName>
+               <description>JPEG encoder, DC Huffman table           1</description>
+               <addressOffset>0x7FC</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DHTMem_RAM</name>
+                     <description>DHTMem RAM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+         </registers>
+      </peripheral>
+      <peripheral>
+         <name>Ethernet_MMC</name>
+         <description>Ethernet: MAC management counters</description>
+         <groupName>Ethernet</groupName>
+         <baseAddress>0x40028100</baseAddress>
+         <addressBlock>
+            <offset>0x0</offset>
+            <size>0x400</size>
+            <usage>registers</usage>
+         </addressBlock>
+         <registers>
+            <register>
+               <name>MMCCR</name>
+               <displayName>MMCCR</displayName>
+               <description>Ethernet MMC control register</description>
+               <addressOffset>0x0</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>CR</name>
+                     <description>CR</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CSR</name>
+                     <description>CSR</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>ROR</name>
+                     <description>ROR</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>MCF</name>
+                     <description>MCF</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>MCP</name>
+                     <description>MCP</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>MCFHP</name>
+                     <description>MCFHP</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>MMCRIR</name>
+               <displayName>MMCRIR</displayName>
+               <description>Ethernet MMC receive interrupt           register</description>
+               <addressOffset>0x4</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>RFCES</name>
+                     <description>RFCES</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>RFAES</name>
+                     <description>RFAES</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>RGUFS</name>
+                     <description>RGUFS</description>
+                     <bitOffset>17</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>MMCTIR</name>
+               <displayName>MMCTIR</displayName>
+               <description>Ethernet MMC transmit interrupt           register</description>
+               <addressOffset>0x8</addressOffset>
+               <size>0x20</size>
+               <access>read-only</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>TGFSCS</name>
+                     <description>TGFSCS</description>
+                     <bitOffset>14</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TGFMSCS</name>
+                     <description>TGFMSCS</description>
+                     <bitOffset>15</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TGFS</name>
+                     <description>TGFS</description>
+                     <bitOffset>21</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>MMCRIMR</name>
+               <displayName>MMCRIMR</displayName>
+               <description>Ethernet MMC receive interrupt mask           register</description>
+               <addressOffset>0xC</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>RFCEM</name>
+                     <description>RFCEM</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>RFAEM</name>
+                     <description>RFAEM</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>RGUFM</name>
+                     <description>RGUFM</description>
+                     <bitOffset>17</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>MMCTIMR</name>
+               <displayName>MMCTIMR</displayName>
+               <description>Ethernet MMC transmit interrupt mask           register</description>
+               <addressOffset>0x10</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>TGFSCM</name>
+                     <description>TGFSCM</description>
+                     <bitOffset>14</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TGFMSCM</name>
+                     <description>TGFMSCM</description>
+                     <bitOffset>15</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TGFM</name>
+                     <description>TGFM</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>MMCTGFSCCR</name>
+               <displayName>MMCTGFSCCR</displayName>
+               <description>Ethernet MMC transmitted good frames after a           single collision counter</description>
+               <addressOffset>0x4C</addressOffset>
+               <size>0x20</size>
+               <access>read-only</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>TGFSCC</name>
+                     <description>TGFSCC</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>MMCTGFMSCCR</name>
+               <displayName>MMCTGFMSCCR</displayName>
+               <description>Ethernet MMC transmitted good frames after           more than a single collision</description>
+               <addressOffset>0x50</addressOffset>
+               <size>0x20</size>
+               <access>read-only</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>TGFMSCC</name>
+                     <description>TGFMSCC</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>MMCTGFCR</name>
+               <displayName>MMCTGFCR</displayName>
+               <description>Ethernet MMC transmitted good frames counter           register</description>
+               <addressOffset>0x68</addressOffset>
+               <size>0x20</size>
+               <access>read-only</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>TGFC</name>
+                     <description>HTL</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>MMCRFCECR</name>
+               <displayName>MMCRFCECR</displayName>
+               <description>Ethernet MMC received frames with CRC error           counter register</description>
+               <addressOffset>0x94</addressOffset>
+               <size>0x20</size>
+               <access>read-only</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>RFCFC</name>
+                     <description>RFCFC</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>MMCRFAECR</name>
+               <displayName>MMCRFAECR</displayName>
+               <description>Ethernet MMC received frames with alignment           error counter register</description>
+               <addressOffset>0x98</addressOffset>
+               <size>0x20</size>
+               <access>read-only</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>RFAEC</name>
+                     <description>RFAEC</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>MMCRGUFCR</name>
+               <displayName>MMCRGUFCR</displayName>
+               <description>MMC received good unicast frames counter           register</description>
+               <addressOffset>0xC4</addressOffset>
+               <size>0x20</size>
+               <access>read-only</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>RGUFC</name>
+                     <description>RGUFC</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+         </registers>
+      </peripheral>
+      <peripheral>
+         <name>Ethernet_PTP</name>
+         <description>Ethernet: Precision time protocol</description>
+         <groupName>Ethernet</groupName>
+         <baseAddress>0x40028700</baseAddress>
+         <addressBlock>
+            <offset>0x0</offset>
+            <size>0x400</size>
+            <usage>registers</usage>
+         </addressBlock>
+         <registers>
+            <register>
+               <name>PTPTSCR</name>
+               <displayName>PTPTSCR</displayName>
+               <description>Ethernet PTP time stamp control           register</description>
+               <addressOffset>0x0</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00002000</resetValue>
+               <fields>
+                  <field>
+                     <name>TSE</name>
+                     <description>TSE</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TSFCU</name>
+                     <description>TSFCU</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TSPTPPSV2E</name>
+                     <description>TSPTPPSV2E</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TSSPTPOEFE</name>
+                     <description>TSSPTPOEFE</description>
+                     <bitOffset>11</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TSSIPV6FE</name>
+                     <description>TSSIPV6FE</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TSSIPV4FE</name>
+                     <description>TSSIPV4FE</description>
+                     <bitOffset>13</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TSSEME</name>
+                     <description>TSSEME</description>
+                     <bitOffset>14</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TSSMRME</name>
+                     <description>TSSMRME</description>
+                     <bitOffset>15</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TSCNT</name>
+                     <description>TSCNT</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>TSPFFMAE</name>
+                     <description>TSPFFMAE</description>
+                     <bitOffset>18</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TSSTI</name>
+                     <description>TSSTI</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TSSTU</name>
+                     <description>TSSTU</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TSITE</name>
+                     <description>TSITE</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TTSARU</name>
+                     <description>TTSARU</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TSSARFE</name>
+                     <description>TSSARFE</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TSSSR</name>
+                     <description>TSSSR</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>PTPSSIR</name>
+               <displayName>PTPSSIR</displayName>
+               <description>Ethernet PTP subsecond increment           register</description>
+               <addressOffset>0x4</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>STSSI</name>
+                     <description>STSSI</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>PTPTSHR</name>
+               <displayName>PTPTSHR</displayName>
+               <description>Ethernet PTP time stamp high           register</description>
+               <addressOffset>0x8</addressOffset>
+               <size>0x20</size>
+               <access>read-only</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>STS</name>
+                     <description>STS</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>PTPTSLR</name>
+               <displayName>PTPTSLR</displayName>
+               <description>Ethernet PTP time stamp low           register</description>
+               <addressOffset>0xC</addressOffset>
+               <size>0x20</size>
+               <access>read-only</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>STSS</name>
+                     <description>STSS</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>31</bitWidth>
+                  </field>
+                  <field>
+                     <name>STPNS</name>
+                     <description>STPNS</description>
+                     <bitOffset>31</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>PTPTSHUR</name>
+               <displayName>PTPTSHUR</displayName>
+               <description>Ethernet PTP time stamp high update           register</description>
+               <addressOffset>0x10</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>TSUS</name>
+                     <description>TSUS</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>PTPTSLUR</name>
+               <displayName>PTPTSLUR</displayName>
+               <description>Ethernet PTP time stamp low update           register</description>
+               <addressOffset>0x14</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>TSUSS</name>
+                     <description>TSUSS</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>31</bitWidth>
+                  </field>
+                  <field>
+                     <name>TSUPNS</name>
+                     <description>TSUPNS</description>
+                     <bitOffset>31</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>PTPTSAR</name>
+               <displayName>PTPTSAR</displayName>
+               <description>Ethernet PTP time stamp addend           register</description>
+               <addressOffset>0x18</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>TSA</name>
+                     <description>TSA</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>PTPTTHR</name>
+               <displayName>PTPTTHR</displayName>
+               <description>Ethernet PTP target time high           register</description>
+               <addressOffset>0x1C</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>TTSH</name>
+                     <description>0</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>PTPTTLR</name>
+               <displayName>PTPTTLR</displayName>
+               <description>Ethernet PTP target time low           register</description>
+               <addressOffset>0x20</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>TTSL</name>
+                     <description>TTSL</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>PTPTSSR</name>
+               <displayName>PTPTSSR</displayName>
+               <description>Ethernet PTP time stamp status           register</description>
+               <addressOffset>0x28</addressOffset>
+               <size>0x20</size>
+               <access>read-only</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>TSSO</name>
+                     <description>TSSO</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TSTTR</name>
+                     <description>TSTTR</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>PTPPPSCR</name>
+               <displayName>PTPPPSCR</displayName>
+               <description>Ethernet PTP PPS control           register</description>
+               <addressOffset>0x2C</addressOffset>
+               <size>0x20</size>
+               <access>read-only</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>TSSO</name>
+                     <description>TSSO</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TSTTR</name>
+                     <description>TSTTR</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+         </registers>
+      </peripheral>
+      <peripheral>
+         <name>Ethernet_DMA</name>
+         <description>Ethernet: DMA controller operation</description>
+         <groupName>Ethernet</groupName>
+         <baseAddress>0x40029000</baseAddress>
+         <addressBlock>
+            <offset>0x0</offset>
+            <size>0x400</size>
+            <usage>registers</usage>
+         </addressBlock>
+         <registers>
+            <register>
+               <name>DMABMR</name>
+               <displayName>DMABMR</displayName>
+               <description>Ethernet DMA bus mode register</description>
+               <addressOffset>0x0</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00002101</resetValue>
+               <fields>
+                  <field>
+                     <name>SR</name>
+                     <description>SR</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>DA</name>
+                     <description>DA</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>DSL</name>
+                     <description>DSL</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>5</bitWidth>
+                  </field>
+                  <field>
+                     <name>EDFE</name>
+                     <description>EDFE</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>PBL</name>
+                     <description>PBL</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>6</bitWidth>
+                  </field>
+                  <field>
+                     <name>RTPR</name>
+                     <description>RTPR</description>
+                     <bitOffset>14</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>FB</name>
+                     <description>FB</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>RDP</name>
+                     <description>RDP</description>
+                     <bitOffset>17</bitOffset>
+                     <bitWidth>6</bitWidth>
+                  </field>
+                  <field>
+                     <name>USP</name>
+                     <description>USP</description>
+                     <bitOffset>23</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FPM</name>
+                     <description>FPM</description>
+                     <bitOffset>24</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>AAB</name>
+                     <description>AAB</description>
+                     <bitOffset>25</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>MB</name>
+                     <description>MB</description>
+                     <bitOffset>26</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DMATPDR</name>
+               <displayName>DMATPDR</displayName>
+               <description>Ethernet DMA transmit poll demand           register</description>
+               <addressOffset>0x4</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>TPD</name>
+                     <description>TPD</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DMARPDR</name>
+               <displayName>DMARPDR</displayName>
+               <description>EHERNET DMA receive poll demand           register</description>
+               <addressOffset>0x8</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>RPD</name>
+                     <description>RPD</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DMARDLAR</name>
+               <displayName>DMARDLAR</displayName>
+               <description>Ethernet DMA receive descriptor list address           register</description>
+               <addressOffset>0xC</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>SRL</name>
+                     <description>SRL</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DMATDLAR</name>
+               <displayName>DMATDLAR</displayName>
+               <description>Ethernet DMA transmit descriptor list           address register</description>
+               <addressOffset>0x10</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>STL</name>
+                     <description>STL</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DMASR</name>
+               <displayName>DMASR</displayName>
+               <description>Ethernet DMA status register</description>
+               <addressOffset>0x14</addressOffset>
+               <size>0x20</size>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>TS</name>
+                     <description>TS</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>TPSS</name>
+                     <description>TPSS</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>TBUS</name>
+                     <description>TBUS</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>TJTS</name>
+                     <description>TJTS</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>ROS</name>
+                     <description>ROS</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>TUS</name>
+                     <description>TUS</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>RS</name>
+                     <description>RS</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>RBUS</name>
+                     <description>RBUS</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>RPSS</name>
+                     <description>RPSS</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>PWTS</name>
+                     <description>PWTS</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>ETS</name>
+                     <description>ETS</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>FBES</name>
+                     <description>FBES</description>
+                     <bitOffset>13</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>ERS</name>
+                     <description>ERS</description>
+                     <bitOffset>14</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>AIS</name>
+                     <description>AIS</description>
+                     <bitOffset>15</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>NIS</name>
+                     <description>NIS</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>RPS</name>
+                     <description>RPS</description>
+                     <bitOffset>17</bitOffset>
+                     <bitWidth>3</bitWidth>
+                     <access>read-only</access>
+                  </field>
+                  <field>
+                     <name>TPS</name>
+                     <description>TPS</description>
+                     <bitOffset>20</bitOffset>
+                     <bitWidth>3</bitWidth>
+                     <access>read-only</access>
+                  </field>
+                  <field>
+                     <name>EBS</name>
+                     <description>EBS</description>
+                     <bitOffset>23</bitOffset>
+                     <bitWidth>3</bitWidth>
+                     <access>read-only</access>
+                  </field>
+                  <field>
+                     <name>MMCS</name>
+                     <description>MMCS</description>
+                     <bitOffset>27</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-only</access>
+                  </field>
+                  <field>
+                     <name>PMTS</name>
+                     <description>PMTS</description>
+                     <bitOffset>28</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-only</access>
+                  </field>
+                  <field>
+                     <name>TSTS</name>
+                     <description>TSTS</description>
+                     <bitOffset>29</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-only</access>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DMAOMR</name>
+               <displayName>DMAOMR</displayName>
+               <description>Ethernet DMA operation mode           register</description>
+               <addressOffset>0x18</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>SR</name>
+                     <description>SR</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>OSF</name>
+                     <description>OSF</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>RTC</name>
+                     <description>RTC</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>FUGF</name>
+                     <description>FUGF</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FEF</name>
+                     <description>FEF</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>ST</name>
+                     <description>ST</description>
+                     <bitOffset>13</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TTC</name>
+                     <description>TTC</description>
+                     <bitOffset>14</bitOffset>
+                     <bitWidth>3</bitWidth>
+                  </field>
+                  <field>
+                     <name>FTF</name>
+                     <description>FTF</description>
+                     <bitOffset>20</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TSF</name>
+                     <description>TSF</description>
+                     <bitOffset>21</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>DFRF</name>
+                     <description>DFRF</description>
+                     <bitOffset>24</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>RSF</name>
+                     <description>RSF</description>
+                     <bitOffset>25</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>DTCEFD</name>
+                     <description>DTCEFD</description>
+                     <bitOffset>26</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DMAIER</name>
+               <displayName>DMAIER</displayName>
+               <description>Ethernet DMA interrupt enable           register</description>
+               <addressOffset>0x1C</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>TIE</name>
+                     <description>TIE</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TPSIE</name>
+                     <description>TPSIE</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TBUIE</name>
+                     <description>TBUIE</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TJTIE</name>
+                     <description>TJTIE</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>ROIE</name>
+                     <description>ROIE</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TUIE</name>
+                     <description>TUIE</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>RIE</name>
+                     <description>RIE</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>RBUIE</name>
+                     <description>RBUIE</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>RPSIE</name>
+                     <description>RPSIE</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>RWTIE</name>
+                     <description>RWTIE</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>ETIE</name>
+                     <description>ETIE</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FBEIE</name>
+                     <description>FBEIE</description>
+                     <bitOffset>13</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>ERIE</name>
+                     <description>ERIE</description>
+                     <bitOffset>14</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>AISE</name>
+                     <description>AISE</description>
+                     <bitOffset>15</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>NISE</name>
+                     <description>NISE</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DMAMFBOCR</name>
+               <displayName>DMAMFBOCR</displayName>
+               <description>Ethernet DMA missed frame and buffer           overflow counter register</description>
+               <addressOffset>0x20</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>MFC</name>
+                     <description>MFC</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+                  <field>
+                     <name>OMFC</name>
+                     <description>OMFC</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>MFA</name>
+                     <description>MFA</description>
+                     <bitOffset>17</bitOffset>
+                     <bitWidth>11</bitWidth>
+                  </field>
+                  <field>
+                     <name>OFOC</name>
+                     <description>OFOC</description>
+                     <bitOffset>28</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DMARSWTR</name>
+               <displayName>DMARSWTR</displayName>
+               <description>Ethernet DMA receive status watchdog timer           register</description>
+               <addressOffset>0x24</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>RSWTC</name>
+                     <description>RSWTC</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DMACHTDR</name>
+               <displayName>DMACHTDR</displayName>
+               <description>Ethernet DMA current host transmit           descriptor register</description>
+               <addressOffset>0x48</addressOffset>
+               <size>0x20</size>
+               <access>read-only</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>HTDAP</name>
+                     <description>HTDAP</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DMACHRDR</name>
+               <displayName>DMACHRDR</displayName>
+               <description>Ethernet DMA current host receive descriptor           register</description>
+               <addressOffset>0x4C</addressOffset>
+               <size>0x20</size>
+               <access>read-only</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>HRDAP</name>
+                     <description>HRDAP</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DMACHTBAR</name>
+               <displayName>DMACHTBAR</displayName>
+               <description>Ethernet DMA current host transmit buffer           address register</description>
+               <addressOffset>0x50</addressOffset>
+               <size>0x20</size>
+               <access>read-only</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>HTBAP</name>
+                     <description>HTBAP</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DMACHRBAR</name>
+               <displayName>DMACHRBAR</displayName>
+               <description>Ethernet DMA current host receive buffer           address register</description>
+               <addressOffset>0x54</addressOffset>
+               <size>0x20</size>
+               <access>read-only</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>HRBAP</name>
+                     <description>HRBAP</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+         </registers>
+      </peripheral>
+      <peripheral>
+         <name>OTG_FS_HOST</name>
+         <description>USB on the go full speed</description>
+         <groupName>USB_OTG_FS</groupName>
+         <baseAddress>0x50000400</baseAddress>
+         <addressBlock>
+            <offset>0x0</offset>
+            <size>0x400</size>
+            <usage>registers</usage>
+         </addressBlock>
+         <registers>
+            <register>
+               <name>OTG_FS_HCFG</name>
+               <displayName>OTG_FS_HCFG</displayName>
+               <description>OTG_FS host configuration register           (OTG_FS_HCFG)</description>
+               <addressOffset>0x0</addressOffset>
+               <size>0x20</size>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>FSLSPCS</name>
+                     <description>FS/LS PHY clock select</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>2</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>FSLSS</name>
+                     <description>FS- and LS-only support</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-only</access>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_FS_HFIR</name>
+               <displayName>OTG_FS_HFIR</displayName>
+               <description>OTG_FS Host frame interval           register</description>
+               <addressOffset>0x4</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x0000EA60</resetValue>
+               <fields>
+                  <field>
+                     <name>FRIVL</name>
+                     <description>Frame interval</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_FS_HFNUM</name>
+               <displayName>OTG_FS_HFNUM</displayName>
+               <description>OTG_FS host frame number/frame time           remaining register (OTG_FS_HFNUM)</description>
+               <addressOffset>0x8</addressOffset>
+               <size>0x20</size>
+               <access>read-only</access>
+               <resetValue>0x00003FFF</resetValue>
+               <fields>
+                  <field>
+                     <name>FRNUM</name>
+                     <description>Frame number</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+                  <field>
+                     <name>FTREM</name>
+                     <description>Frame time remaining</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_FS_HPTXSTS</name>
+               <displayName>OTG_FS_HPTXSTS</displayName>
+               <description>OTG_FS_Host periodic transmit FIFO/queue           status register (OTG_FS_HPTXSTS)</description>
+               <addressOffset>0x10</addressOffset>
+               <size>0x20</size>
+               <resetValue>0x00080100</resetValue>
+               <fields>
+                  <field>
+                     <name>PTXFSAVL</name>
+                     <description>Periodic transmit data FIFO space               available</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>16</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>PTXQSAV</name>
+                     <description>Periodic transmit request queue space               available</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>8</bitWidth>
+                     <access>read-only</access>
+                  </field>
+                  <field>
+                     <name>PTXQTOP</name>
+                     <description>Top of the periodic transmit request               queue</description>
+                     <bitOffset>24</bitOffset>
+                     <bitWidth>8</bitWidth>
+                     <access>read-only</access>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_FS_HAINT</name>
+               <displayName>OTG_FS_HAINT</displayName>
+               <description>OTG_FS Host all channels interrupt           register</description>
+               <addressOffset>0x14</addressOffset>
+               <size>0x20</size>
+               <access>read-only</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>HAINT</name>
+                     <description>Channel interrupts</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_FS_HAINTMSK</name>
+               <displayName>OTG_FS_HAINTMSK</displayName>
+               <description>OTG_FS host all channels interrupt mask           register</description>
+               <addressOffset>0x18</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>HAINTM</name>
+                     <description>Channel interrupt mask</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_FS_HPRT</name>
+               <displayName>OTG_FS_HPRT</displayName>
+               <description>OTG_FS host port control and status register           (OTG_FS_HPRT)</description>
+               <addressOffset>0x40</addressOffset>
+               <size>0x20</size>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>PCSTS</name>
+                     <description>Port connect status</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-only</access>
+                  </field>
+                  <field>
+                     <name>PCDET</name>
+                     <description>Port connect detected</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>PENA</name>
+                     <description>Port enable</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>PENCHNG</name>
+                     <description>Port enable/disable change</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>POCA</name>
+                     <description>Port overcurrent active</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-only</access>
+                  </field>
+                  <field>
+                     <name>POCCHNG</name>
+                     <description>Port overcurrent change</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>PRES</name>
+                     <description>Port resume</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>PSUSP</name>
+                     <description>Port suspend</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>PRST</name>
+                     <description>Port reset</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>PLSTS</name>
+                     <description>Port line status</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>2</bitWidth>
+                     <access>read-only</access>
+                  </field>
+                  <field>
+                     <name>PPWR</name>
+                     <description>Port power</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>PTCTL</name>
+                     <description>Port test control</description>
+                     <bitOffset>13</bitOffset>
+                     <bitWidth>4</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>PSPD</name>
+                     <description>Port speed</description>
+                     <bitOffset>17</bitOffset>
+                     <bitWidth>2</bitWidth>
+                     <access>read-only</access>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_FS_HCCHAR0</name>
+               <displayName>OTG_FS_HCCHAR0</displayName>
+               <description>OTG_FS host channel-0 characteristics           register (OTG_FS_HCCHAR0)</description>
+               <addressOffset>0x100</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>MPSIZ</name>
+                     <description>Maximum packet size</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>11</bitWidth>
+                  </field>
+                  <field>
+                     <name>EPNUM</name>
+                     <description>Endpoint number</description>
+                     <bitOffset>11</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+                  <field>
+                     <name>EPDIR</name>
+                     <description>Endpoint direction</description>
+                     <bitOffset>15</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>LSDEV</name>
+                     <description>Low-speed device</description>
+                     <bitOffset>17</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>EPTYP</name>
+                     <description>Endpoint type</description>
+                     <bitOffset>18</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>MCNT</name>
+                     <description>Multicount</description>
+                     <bitOffset>20</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>DAD</name>
+                     <description>Device address</description>
+                     <bitOffset>22</bitOffset>
+                     <bitWidth>7</bitWidth>
+                  </field>
+                  <field>
+                     <name>ODDFRM</name>
+                     <description>Odd frame</description>
+                     <bitOffset>29</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CHDIS</name>
+                     <description>Channel disable</description>
+                     <bitOffset>30</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CHENA</name>
+                     <description>Channel enable</description>
+                     <bitOffset>31</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_FS_HCCHAR1</name>
+               <displayName>OTG_FS_HCCHAR1</displayName>
+               <description>OTG_FS host channel-1 characteristics           register (OTG_FS_HCCHAR1)</description>
+               <addressOffset>0x120</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>MPSIZ</name>
+                     <description>Maximum packet size</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>11</bitWidth>
+                  </field>
+                  <field>
+                     <name>EPNUM</name>
+                     <description>Endpoint number</description>
+                     <bitOffset>11</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+                  <field>
+                     <name>EPDIR</name>
+                     <description>Endpoint direction</description>
+                     <bitOffset>15</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>LSDEV</name>
+                     <description>Low-speed device</description>
+                     <bitOffset>17</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>EPTYP</name>
+                     <description>Endpoint type</description>
+                     <bitOffset>18</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>MCNT</name>
+                     <description>Multicount</description>
+                     <bitOffset>20</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>DAD</name>
+                     <description>Device address</description>
+                     <bitOffset>22</bitOffset>
+                     <bitWidth>7</bitWidth>
+                  </field>
+                  <field>
+                     <name>ODDFRM</name>
+                     <description>Odd frame</description>
+                     <bitOffset>29</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CHDIS</name>
+                     <description>Channel disable</description>
+                     <bitOffset>30</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CHENA</name>
+                     <description>Channel enable</description>
+                     <bitOffset>31</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_FS_HCCHAR2</name>
+               <displayName>OTG_FS_HCCHAR2</displayName>
+               <description>OTG_FS host channel-2 characteristics           register (OTG_FS_HCCHAR2)</description>
+               <addressOffset>0x140</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>MPSIZ</name>
+                     <description>Maximum packet size</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>11</bitWidth>
+                  </field>
+                  <field>
+                     <name>EPNUM</name>
+                     <description>Endpoint number</description>
+                     <bitOffset>11</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+                  <field>
+                     <name>EPDIR</name>
+                     <description>Endpoint direction</description>
+                     <bitOffset>15</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>LSDEV</name>
+                     <description>Low-speed device</description>
+                     <bitOffset>17</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>EPTYP</name>
+                     <description>Endpoint type</description>
+                     <bitOffset>18</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>MCNT</name>
+                     <description>Multicount</description>
+                     <bitOffset>20</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>DAD</name>
+                     <description>Device address</description>
+                     <bitOffset>22</bitOffset>
+                     <bitWidth>7</bitWidth>
+                  </field>
+                  <field>
+                     <name>ODDFRM</name>
+                     <description>Odd frame</description>
+                     <bitOffset>29</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CHDIS</name>
+                     <description>Channel disable</description>
+                     <bitOffset>30</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CHENA</name>
+                     <description>Channel enable</description>
+                     <bitOffset>31</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_FS_HCCHAR3</name>
+               <displayName>OTG_FS_HCCHAR3</displayName>
+               <description>OTG_FS host channel-3 characteristics           register (OTG_FS_HCCHAR3)</description>
+               <addressOffset>0x160</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>MPSIZ</name>
+                     <description>Maximum packet size</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>11</bitWidth>
+                  </field>
+                  <field>
+                     <name>EPNUM</name>
+                     <description>Endpoint number</description>
+                     <bitOffset>11</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+                  <field>
+                     <name>EPDIR</name>
+                     <description>Endpoint direction</description>
+                     <bitOffset>15</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>LSDEV</name>
+                     <description>Low-speed device</description>
+                     <bitOffset>17</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>EPTYP</name>
+                     <description>Endpoint type</description>
+                     <bitOffset>18</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>MCNT</name>
+                     <description>Multicount</description>
+                     <bitOffset>20</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>DAD</name>
+                     <description>Device address</description>
+                     <bitOffset>22</bitOffset>
+                     <bitWidth>7</bitWidth>
+                  </field>
+                  <field>
+                     <name>ODDFRM</name>
+                     <description>Odd frame</description>
+                     <bitOffset>29</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CHDIS</name>
+                     <description>Channel disable</description>
+                     <bitOffset>30</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CHENA</name>
+                     <description>Channel enable</description>
+                     <bitOffset>31</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_FS_HCCHAR4</name>
+               <displayName>OTG_FS_HCCHAR4</displayName>
+               <description>OTG_FS host channel-4 characteristics           register (OTG_FS_HCCHAR4)</description>
+               <addressOffset>0x180</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>MPSIZ</name>
+                     <description>Maximum packet size</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>11</bitWidth>
+                  </field>
+                  <field>
+                     <name>EPNUM</name>
+                     <description>Endpoint number</description>
+                     <bitOffset>11</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+                  <field>
+                     <name>EPDIR</name>
+                     <description>Endpoint direction</description>
+                     <bitOffset>15</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>LSDEV</name>
+                     <description>Low-speed device</description>
+                     <bitOffset>17</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>EPTYP</name>
+                     <description>Endpoint type</description>
+                     <bitOffset>18</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>MCNT</name>
+                     <description>Multicount</description>
+                     <bitOffset>20</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>DAD</name>
+                     <description>Device address</description>
+                     <bitOffset>22</bitOffset>
+                     <bitWidth>7</bitWidth>
+                  </field>
+                  <field>
+                     <name>ODDFRM</name>
+                     <description>Odd frame</description>
+                     <bitOffset>29</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CHDIS</name>
+                     <description>Channel disable</description>
+                     <bitOffset>30</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CHENA</name>
+                     <description>Channel enable</description>
+                     <bitOffset>31</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_FS_HCCHAR5</name>
+               <displayName>OTG_FS_HCCHAR5</displayName>
+               <description>OTG_FS host channel-5 characteristics           register (OTG_FS_HCCHAR5)</description>
+               <addressOffset>0x1A0</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>MPSIZ</name>
+                     <description>Maximum packet size</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>11</bitWidth>
+                  </field>
+                  <field>
+                     <name>EPNUM</name>
+                     <description>Endpoint number</description>
+                     <bitOffset>11</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+                  <field>
+                     <name>EPDIR</name>
+                     <description>Endpoint direction</description>
+                     <bitOffset>15</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>LSDEV</name>
+                     <description>Low-speed device</description>
+                     <bitOffset>17</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>EPTYP</name>
+                     <description>Endpoint type</description>
+                     <bitOffset>18</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>MCNT</name>
+                     <description>Multicount</description>
+                     <bitOffset>20</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>DAD</name>
+                     <description>Device address</description>
+                     <bitOffset>22</bitOffset>
+                     <bitWidth>7</bitWidth>
+                  </field>
+                  <field>
+                     <name>ODDFRM</name>
+                     <description>Odd frame</description>
+                     <bitOffset>29</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CHDIS</name>
+                     <description>Channel disable</description>
+                     <bitOffset>30</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CHENA</name>
+                     <description>Channel enable</description>
+                     <bitOffset>31</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_FS_HCCHAR6</name>
+               <displayName>OTG_FS_HCCHAR6</displayName>
+               <description>OTG_FS host channel-6 characteristics           register (OTG_FS_HCCHAR6)</description>
+               <addressOffset>0x1C0</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>MPSIZ</name>
+                     <description>Maximum packet size</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>11</bitWidth>
+                  </field>
+                  <field>
+                     <name>EPNUM</name>
+                     <description>Endpoint number</description>
+                     <bitOffset>11</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+                  <field>
+                     <name>EPDIR</name>
+                     <description>Endpoint direction</description>
+                     <bitOffset>15</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>LSDEV</name>
+                     <description>Low-speed device</description>
+                     <bitOffset>17</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>EPTYP</name>
+                     <description>Endpoint type</description>
+                     <bitOffset>18</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>MCNT</name>
+                     <description>Multicount</description>
+                     <bitOffset>20</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>DAD</name>
+                     <description>Device address</description>
+                     <bitOffset>22</bitOffset>
+                     <bitWidth>7</bitWidth>
+                  </field>
+                  <field>
+                     <name>ODDFRM</name>
+                     <description>Odd frame</description>
+                     <bitOffset>29</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CHDIS</name>
+                     <description>Channel disable</description>
+                     <bitOffset>30</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CHENA</name>
+                     <description>Channel enable</description>
+                     <bitOffset>31</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_FS_HCCHAR7</name>
+               <displayName>OTG_FS_HCCHAR7</displayName>
+               <description>OTG_FS host channel-7 characteristics           register (OTG_FS_HCCHAR7)</description>
+               <addressOffset>0x1E0</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>MPSIZ</name>
+                     <description>Maximum packet size</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>11</bitWidth>
+                  </field>
+                  <field>
+                     <name>EPNUM</name>
+                     <description>Endpoint number</description>
+                     <bitOffset>11</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+                  <field>
+                     <name>EPDIR</name>
+                     <description>Endpoint direction</description>
+                     <bitOffset>15</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>LSDEV</name>
+                     <description>Low-speed device</description>
+                     <bitOffset>17</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>EPTYP</name>
+                     <description>Endpoint type</description>
+                     <bitOffset>18</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>MCNT</name>
+                     <description>Multicount</description>
+                     <bitOffset>20</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>DAD</name>
+                     <description>Device address</description>
+                     <bitOffset>22</bitOffset>
+                     <bitWidth>7</bitWidth>
+                  </field>
+                  <field>
+                     <name>ODDFRM</name>
+                     <description>Odd frame</description>
+                     <bitOffset>29</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CHDIS</name>
+                     <description>Channel disable</description>
+                     <bitOffset>30</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CHENA</name>
+                     <description>Channel enable</description>
+                     <bitOffset>31</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_FS_HCINT0</name>
+               <displayName>OTG_FS_HCINT0</displayName>
+               <description>OTG_FS host channel-0 interrupt register           (OTG_FS_HCINT0)</description>
+               <addressOffset>0x108</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>XFRC</name>
+                     <description>Transfer completed</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CHH</name>
+                     <description>Channel halted</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>STALL</name>
+                     <description>STALL response received               interrupt</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>NAK</name>
+                     <description>NAK response received               interrupt</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>ACK</name>
+                     <description>ACK response received/transmitted               interrupt</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TXERR</name>
+                     <description>Transaction error</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>BBERR</name>
+                     <description>Babble error</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FRMOR</name>
+                     <description>Frame overrun</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>DTERR</name>
+                     <description>Data toggle error</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_FS_HCINT1</name>
+               <displayName>OTG_FS_HCINT1</displayName>
+               <description>OTG_FS host channel-1 interrupt register           (OTG_FS_HCINT1)</description>
+               <addressOffset>0x128</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>XFRC</name>
+                     <description>Transfer completed</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CHH</name>
+                     <description>Channel halted</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>STALL</name>
+                     <description>STALL response received               interrupt</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>NAK</name>
+                     <description>NAK response received               interrupt</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>ACK</name>
+                     <description>ACK response received/transmitted               interrupt</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TXERR</name>
+                     <description>Transaction error</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>BBERR</name>
+                     <description>Babble error</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FRMOR</name>
+                     <description>Frame overrun</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>DTERR</name>
+                     <description>Data toggle error</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_FS_HCINT2</name>
+               <displayName>OTG_FS_HCINT2</displayName>
+               <description>OTG_FS host channel-2 interrupt register           (OTG_FS_HCINT2)</description>
+               <addressOffset>0x148</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>XFRC</name>
+                     <description>Transfer completed</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CHH</name>
+                     <description>Channel halted</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>STALL</name>
+                     <description>STALL response received               interrupt</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>NAK</name>
+                     <description>NAK response received               interrupt</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>ACK</name>
+                     <description>ACK response received/transmitted               interrupt</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TXERR</name>
+                     <description>Transaction error</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>BBERR</name>
+                     <description>Babble error</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FRMOR</name>
+                     <description>Frame overrun</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>DTERR</name>
+                     <description>Data toggle error</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_FS_HCINT3</name>
+               <displayName>OTG_FS_HCINT3</displayName>
+               <description>OTG_FS host channel-3 interrupt register           (OTG_FS_HCINT3)</description>
+               <addressOffset>0x168</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>XFRC</name>
+                     <description>Transfer completed</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CHH</name>
+                     <description>Channel halted</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>STALL</name>
+                     <description>STALL response received               interrupt</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>NAK</name>
+                     <description>NAK response received               interrupt</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>ACK</name>
+                     <description>ACK response received/transmitted               interrupt</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TXERR</name>
+                     <description>Transaction error</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>BBERR</name>
+                     <description>Babble error</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FRMOR</name>
+                     <description>Frame overrun</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>DTERR</name>
+                     <description>Data toggle error</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_FS_HCINT4</name>
+               <displayName>OTG_FS_HCINT4</displayName>
+               <description>OTG_FS host channel-4 interrupt register           (OTG_FS_HCINT4)</description>
+               <addressOffset>0x188</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>XFRC</name>
+                     <description>Transfer completed</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CHH</name>
+                     <description>Channel halted</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>STALL</name>
+                     <description>STALL response received               interrupt</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>NAK</name>
+                     <description>NAK response received               interrupt</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>ACK</name>
+                     <description>ACK response received/transmitted               interrupt</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TXERR</name>
+                     <description>Transaction error</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>BBERR</name>
+                     <description>Babble error</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FRMOR</name>
+                     <description>Frame overrun</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>DTERR</name>
+                     <description>Data toggle error</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_FS_HCINT5</name>
+               <displayName>OTG_FS_HCINT5</displayName>
+               <description>OTG_FS host channel-5 interrupt register           (OTG_FS_HCINT5)</description>
+               <addressOffset>0x1A8</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>XFRC</name>
+                     <description>Transfer completed</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CHH</name>
+                     <description>Channel halted</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>STALL</name>
+                     <description>STALL response received               interrupt</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>NAK</name>
+                     <description>NAK response received               interrupt</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>ACK</name>
+                     <description>ACK response received/transmitted               interrupt</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TXERR</name>
+                     <description>Transaction error</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>BBERR</name>
+                     <description>Babble error</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FRMOR</name>
+                     <description>Frame overrun</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>DTERR</name>
+                     <description>Data toggle error</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_FS_HCINT6</name>
+               <displayName>OTG_FS_HCINT6</displayName>
+               <description>OTG_FS host channel-6 interrupt register           (OTG_FS_HCINT6)</description>
+               <addressOffset>0x1C8</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>XFRC</name>
+                     <description>Transfer completed</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CHH</name>
+                     <description>Channel halted</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>STALL</name>
+                     <description>STALL response received               interrupt</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>NAK</name>
+                     <description>NAK response received               interrupt</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>ACK</name>
+                     <description>ACK response received/transmitted               interrupt</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TXERR</name>
+                     <description>Transaction error</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>BBERR</name>
+                     <description>Babble error</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FRMOR</name>
+                     <description>Frame overrun</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>DTERR</name>
+                     <description>Data toggle error</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_FS_HCINT7</name>
+               <displayName>OTG_FS_HCINT7</displayName>
+               <description>OTG_FS host channel-7 interrupt register           (OTG_FS_HCINT7)</description>
+               <addressOffset>0x1E8</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>XFRC</name>
+                     <description>Transfer completed</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CHH</name>
+                     <description>Channel halted</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>STALL</name>
+                     <description>STALL response received               interrupt</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>NAK</name>
+                     <description>NAK response received               interrupt</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>ACK</name>
+                     <description>ACK response received/transmitted               interrupt</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TXERR</name>
+                     <description>Transaction error</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>BBERR</name>
+                     <description>Babble error</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FRMOR</name>
+                     <description>Frame overrun</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>DTERR</name>
+                     <description>Data toggle error</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_FS_HCINTMSK0</name>
+               <displayName>OTG_FS_HCINTMSK0</displayName>
+               <description>OTG_FS host channel-0 mask register           (OTG_FS_HCINTMSK0)</description>
+               <addressOffset>0x10C</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>XFRCM</name>
+                     <description>Transfer completed mask</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CHHM</name>
+                     <description>Channel halted mask</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>STALLM</name>
+                     <description>STALL response received interrupt               mask</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>NAKM</name>
+                     <description>NAK response received interrupt               mask</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>ACKM</name>
+                     <description>ACK response received/transmitted               interrupt mask</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>NYET</name>
+                     <description>response received interrupt               mask</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TXERRM</name>
+                     <description>Transaction error mask</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>BBERRM</name>
+                     <description>Babble error mask</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FRMORM</name>
+                     <description>Frame overrun mask</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>DTERRM</name>
+                     <description>Data toggle error mask</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_FS_HCINTMSK1</name>
+               <displayName>OTG_FS_HCINTMSK1</displayName>
+               <description>OTG_FS host channel-1 mask register           (OTG_FS_HCINTMSK1)</description>
+               <addressOffset>0x12C</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>XFRCM</name>
+                     <description>Transfer completed mask</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CHHM</name>
+                     <description>Channel halted mask</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>STALLM</name>
+                     <description>STALL response received interrupt               mask</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>NAKM</name>
+                     <description>NAK response received interrupt               mask</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>ACKM</name>
+                     <description>ACK response received/transmitted               interrupt mask</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>NYET</name>
+                     <description>response received interrupt               mask</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TXERRM</name>
+                     <description>Transaction error mask</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>BBERRM</name>
+                     <description>Babble error mask</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FRMORM</name>
+                     <description>Frame overrun mask</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>DTERRM</name>
+                     <description>Data toggle error mask</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_FS_HCINTMSK2</name>
+               <displayName>OTG_FS_HCINTMSK2</displayName>
+               <description>OTG_FS host channel-2 mask register           (OTG_FS_HCINTMSK2)</description>
+               <addressOffset>0x14C</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>XFRCM</name>
+                     <description>Transfer completed mask</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CHHM</name>
+                     <description>Channel halted mask</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>STALLM</name>
+                     <description>STALL response received interrupt               mask</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>NAKM</name>
+                     <description>NAK response received interrupt               mask</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>ACKM</name>
+                     <description>ACK response received/transmitted               interrupt mask</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>NYET</name>
+                     <description>response received interrupt               mask</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TXERRM</name>
+                     <description>Transaction error mask</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>BBERRM</name>
+                     <description>Babble error mask</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FRMORM</name>
+                     <description>Frame overrun mask</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>DTERRM</name>
+                     <description>Data toggle error mask</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_FS_HCINTMSK3</name>
+               <displayName>OTG_FS_HCINTMSK3</displayName>
+               <description>OTG_FS host channel-3 mask register           (OTG_FS_HCINTMSK3)</description>
+               <addressOffset>0x16C</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>XFRCM</name>
+                     <description>Transfer completed mask</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CHHM</name>
+                     <description>Channel halted mask</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>STALLM</name>
+                     <description>STALL response received interrupt               mask</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>NAKM</name>
+                     <description>NAK response received interrupt               mask</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>ACKM</name>
+                     <description>ACK response received/transmitted               interrupt mask</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>NYET</name>
+                     <description>response received interrupt               mask</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TXERRM</name>
+                     <description>Transaction error mask</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>BBERRM</name>
+                     <description>Babble error mask</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FRMORM</name>
+                     <description>Frame overrun mask</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>DTERRM</name>
+                     <description>Data toggle error mask</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_FS_HCINTMSK4</name>
+               <displayName>OTG_FS_HCINTMSK4</displayName>
+               <description>OTG_FS host channel-4 mask register           (OTG_FS_HCINTMSK4)</description>
+               <addressOffset>0x18C</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>XFRCM</name>
+                     <description>Transfer completed mask</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CHHM</name>
+                     <description>Channel halted mask</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>STALLM</name>
+                     <description>STALL response received interrupt               mask</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>NAKM</name>
+                     <description>NAK response received interrupt               mask</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>ACKM</name>
+                     <description>ACK response received/transmitted               interrupt mask</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>NYET</name>
+                     <description>response received interrupt               mask</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TXERRM</name>
+                     <description>Transaction error mask</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>BBERRM</name>
+                     <description>Babble error mask</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FRMORM</name>
+                     <description>Frame overrun mask</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>DTERRM</name>
+                     <description>Data toggle error mask</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_FS_HCINTMSK5</name>
+               <displayName>OTG_FS_HCINTMSK5</displayName>
+               <description>OTG_FS host channel-5 mask register           (OTG_FS_HCINTMSK5)</description>
+               <addressOffset>0x1AC</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>XFRCM</name>
+                     <description>Transfer completed mask</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CHHM</name>
+                     <description>Channel halted mask</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>STALLM</name>
+                     <description>STALL response received interrupt               mask</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>NAKM</name>
+                     <description>NAK response received interrupt               mask</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>ACKM</name>
+                     <description>ACK response received/transmitted               interrupt mask</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>NYET</name>
+                     <description>response received interrupt               mask</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TXERRM</name>
+                     <description>Transaction error mask</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>BBERRM</name>
+                     <description>Babble error mask</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FRMORM</name>
+                     <description>Frame overrun mask</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>DTERRM</name>
+                     <description>Data toggle error mask</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_FS_HCINTMSK6</name>
+               <displayName>OTG_FS_HCINTMSK6</displayName>
+               <description>OTG_FS host channel-6 mask register           (OTG_FS_HCINTMSK6)</description>
+               <addressOffset>0x1CC</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>XFRCM</name>
+                     <description>Transfer completed mask</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CHHM</name>
+                     <description>Channel halted mask</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>STALLM</name>
+                     <description>STALL response received interrupt               mask</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>NAKM</name>
+                     <description>NAK response received interrupt               mask</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>ACKM</name>
+                     <description>ACK response received/transmitted               interrupt mask</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>NYET</name>
+                     <description>response received interrupt               mask</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TXERRM</name>
+                     <description>Transaction error mask</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>BBERRM</name>
+                     <description>Babble error mask</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FRMORM</name>
+                     <description>Frame overrun mask</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>DTERRM</name>
+                     <description>Data toggle error mask</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_FS_HCINTMSK7</name>
+               <displayName>OTG_FS_HCINTMSK7</displayName>
+               <description>OTG_FS host channel-7 mask register           (OTG_FS_HCINTMSK7)</description>
+               <addressOffset>0x1EC</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>XFRCM</name>
+                     <description>Transfer completed mask</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CHHM</name>
+                     <description>Channel halted mask</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>STALLM</name>
+                     <description>STALL response received interrupt               mask</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>NAKM</name>
+                     <description>NAK response received interrupt               mask</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>ACKM</name>
+                     <description>ACK response received/transmitted               interrupt mask</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>NYET</name>
+                     <description>response received interrupt               mask</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TXERRM</name>
+                     <description>Transaction error mask</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>BBERRM</name>
+                     <description>Babble error mask</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FRMORM</name>
+                     <description>Frame overrun mask</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>DTERRM</name>
+                     <description>Data toggle error mask</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_FS_HCTSIZ0</name>
+               <displayName>OTG_FS_HCTSIZ0</displayName>
+               <description>OTG_FS host channel-0 transfer size           register</description>
+               <addressOffset>0x110</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>XFRSIZ</name>
+                     <description>Transfer size</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>19</bitWidth>
+                  </field>
+                  <field>
+                     <name>PKTCNT</name>
+                     <description>Packet count</description>
+                     <bitOffset>19</bitOffset>
+                     <bitWidth>10</bitWidth>
+                  </field>
+                  <field>
+                     <name>DPID</name>
+                     <description>Data PID</description>
+                     <bitOffset>29</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_FS_HCTSIZ1</name>
+               <displayName>OTG_FS_HCTSIZ1</displayName>
+               <description>OTG_FS host channel-1 transfer size           register</description>
+               <addressOffset>0x130</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>XFRSIZ</name>
+                     <description>Transfer size</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>19</bitWidth>
+                  </field>
+                  <field>
+                     <name>PKTCNT</name>
+                     <description>Packet count</description>
+                     <bitOffset>19</bitOffset>
+                     <bitWidth>10</bitWidth>
+                  </field>
+                  <field>
+                     <name>DPID</name>
+                     <description>Data PID</description>
+                     <bitOffset>29</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_FS_HCTSIZ2</name>
+               <displayName>OTG_FS_HCTSIZ2</displayName>
+               <description>OTG_FS host channel-2 transfer size           register</description>
+               <addressOffset>0x150</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>XFRSIZ</name>
+                     <description>Transfer size</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>19</bitWidth>
+                  </field>
+                  <field>
+                     <name>PKTCNT</name>
+                     <description>Packet count</description>
+                     <bitOffset>19</bitOffset>
+                     <bitWidth>10</bitWidth>
+                  </field>
+                  <field>
+                     <name>DPID</name>
+                     <description>Data PID</description>
+                     <bitOffset>29</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_FS_HCTSIZ3</name>
+               <displayName>OTG_FS_HCTSIZ3</displayName>
+               <description>OTG_FS host channel-3 transfer size           register</description>
+               <addressOffset>0x170</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>XFRSIZ</name>
+                     <description>Transfer size</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>19</bitWidth>
+                  </field>
+                  <field>
+                     <name>PKTCNT</name>
+                     <description>Packet count</description>
+                     <bitOffset>19</bitOffset>
+                     <bitWidth>10</bitWidth>
+                  </field>
+                  <field>
+                     <name>DPID</name>
+                     <description>Data PID</description>
+                     <bitOffset>29</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_FS_HCTSIZ4</name>
+               <displayName>OTG_FS_HCTSIZ4</displayName>
+               <description>OTG_FS host channel-x transfer size           register</description>
+               <addressOffset>0x190</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>XFRSIZ</name>
+                     <description>Transfer size</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>19</bitWidth>
+                  </field>
+                  <field>
+                     <name>PKTCNT</name>
+                     <description>Packet count</description>
+                     <bitOffset>19</bitOffset>
+                     <bitWidth>10</bitWidth>
+                  </field>
+                  <field>
+                     <name>DPID</name>
+                     <description>Data PID</description>
+                     <bitOffset>29</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_FS_HCTSIZ5</name>
+               <displayName>OTG_FS_HCTSIZ5</displayName>
+               <description>OTG_FS host channel-5 transfer size           register</description>
+               <addressOffset>0x1B0</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>XFRSIZ</name>
+                     <description>Transfer size</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>19</bitWidth>
+                  </field>
+                  <field>
+                     <name>PKTCNT</name>
+                     <description>Packet count</description>
+                     <bitOffset>19</bitOffset>
+                     <bitWidth>10</bitWidth>
+                  </field>
+                  <field>
+                     <name>DPID</name>
+                     <description>Data PID</description>
+                     <bitOffset>29</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_FS_HCTSIZ6</name>
+               <displayName>OTG_FS_HCTSIZ6</displayName>
+               <description>OTG_FS host channel-6 transfer size           register</description>
+               <addressOffset>0x1D0</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>XFRSIZ</name>
+                     <description>Transfer size</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>19</bitWidth>
+                  </field>
+                  <field>
+                     <name>PKTCNT</name>
+                     <description>Packet count</description>
+                     <bitOffset>19</bitOffset>
+                     <bitWidth>10</bitWidth>
+                  </field>
+                  <field>
+                     <name>DPID</name>
+                     <description>Data PID</description>
+                     <bitOffset>29</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_FS_HCTSIZ7</name>
+               <displayName>OTG_FS_HCTSIZ7</displayName>
+               <description>OTG_FS host channel-7 transfer size           register</description>
+               <addressOffset>0x1F0</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>XFRSIZ</name>
+                     <description>Transfer size</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>19</bitWidth>
+                  </field>
+                  <field>
+                     <name>PKTCNT</name>
+                     <description>Packet count</description>
+                     <bitOffset>19</bitOffset>
+                     <bitWidth>10</bitWidth>
+                  </field>
+                  <field>
+                     <name>DPID</name>
+                     <description>Data PID</description>
+                     <bitOffset>29</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_FS_HCCHAR8</name>
+               <displayName>OTG_FS_HCCHAR8</displayName>
+               <description>OTG_FS host channel-8 characteristics           register</description>
+               <addressOffset>0x1F4</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>MPSIZ</name>
+                     <description>Maximum packet size</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>11</bitWidth>
+                  </field>
+                  <field>
+                     <name>EPNUM</name>
+                     <description>Endpoint number</description>
+                     <bitOffset>11</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+                  <field>
+                     <name>EPDIR</name>
+                     <description>Endpoint direction</description>
+                     <bitOffset>15</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>LSDEV</name>
+                     <description>Low-speed device</description>
+                     <bitOffset>17</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>EPTYP</name>
+                     <description>Endpoint type</description>
+                     <bitOffset>18</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>MCNT</name>
+                     <description>Multicount</description>
+                     <bitOffset>20</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>DAD</name>
+                     <description>Device address</description>
+                     <bitOffset>22</bitOffset>
+                     <bitWidth>7</bitWidth>
+                  </field>
+                  <field>
+                     <name>ODDFRM</name>
+                     <description>Odd frame</description>
+                     <bitOffset>29</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CHDIS</name>
+                     <description>Channel disable</description>
+                     <bitOffset>30</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CHENA</name>
+                     <description>Channel enable</description>
+                     <bitOffset>31</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_FS_HCINT8</name>
+               <displayName>OTG_FS_HCINT8</displayName>
+               <description>OTG_FS host channel-8 interrupt           register</description>
+               <addressOffset>0x1F8</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>XFRC</name>
+                     <description>Transfer completed</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CHH</name>
+                     <description>Channel halted</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>STALL</name>
+                     <description>STALL response received               interrupt</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>NAK</name>
+                     <description>NAK response received               interrupt</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>ACK</name>
+                     <description>ACK response received/transmitted               interrupt</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TXERR</name>
+                     <description>Transaction error</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>BBERR</name>
+                     <description>Babble error</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FRMOR</name>
+                     <description>Frame overrun</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>DTERR</name>
+                     <description>Data toggle error</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_FS_HCINTMSK8</name>
+               <displayName>OTG_FS_HCINTMSK8</displayName>
+               <description>OTG_FS host channel-8 mask           register</description>
+               <addressOffset>0x1FC</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>XFRCM</name>
+                     <description>Transfer completed mask</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CHHM</name>
+                     <description>Channel halted mask</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>STALLM</name>
+                     <description>STALL response received interrupt               mask</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>NAKM</name>
+                     <description>NAK response received interrupt               mask</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>ACKM</name>
+                     <description>ACK response received/transmitted               interrupt mask</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>NYET</name>
+                     <description>response received interrupt               mask</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TXERRM</name>
+                     <description>Transaction error</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>BBERRM</name>
+                     <description>Babble error mask</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FRMORM</name>
+                     <description>Frame overrun mask</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>DTERRM</name>
+                     <description>Data toggle error mask</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_FS_HCTSIZ8</name>
+               <displayName>OTG_FS_HCTSIZ8</displayName>
+               <description>OTG_FS host channel-8 transfer size           register</description>
+               <addressOffset>0x200</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>XFRSIZ</name>
+                     <description>Transfer size</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>19</bitWidth>
+                  </field>
+                  <field>
+                     <name>PKTCNT</name>
+                     <description>Packet count</description>
+                     <bitOffset>19</bitOffset>
+                     <bitWidth>10</bitWidth>
+                  </field>
+                  <field>
+                     <name>DPID</name>
+                     <description>Data PID</description>
+                     <bitOffset>29</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_FS_HCCHAR9</name>
+               <displayName>OTG_FS_HCCHAR9</displayName>
+               <description>OTG_FS host channel-9 characteristics           register</description>
+               <addressOffset>0x204</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>MPSIZ</name>
+                     <description>Maximum packet size</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>11</bitWidth>
+                  </field>
+                  <field>
+                     <name>EPNUM</name>
+                     <description>Endpoint number</description>
+                     <bitOffset>11</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+                  <field>
+                     <name>EPDIR</name>
+                     <description>Endpoint direction</description>
+                     <bitOffset>15</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>LSDEV</name>
+                     <description>Low-speed device</description>
+                     <bitOffset>17</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>EPTYP</name>
+                     <description>Endpoint type</description>
+                     <bitOffset>18</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>MCNT</name>
+                     <description>Multicount</description>
+                     <bitOffset>20</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>DAD</name>
+                     <description>Device address</description>
+                     <bitOffset>22</bitOffset>
+                     <bitWidth>7</bitWidth>
+                  </field>
+                  <field>
+                     <name>ODDFRM</name>
+                     <description>Odd frame</description>
+                     <bitOffset>29</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CHDIS</name>
+                     <description>Channel disable</description>
+                     <bitOffset>30</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CHENA</name>
+                     <description>Channel enable</description>
+                     <bitOffset>31</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_FS_HCINT9</name>
+               <displayName>OTG_FS_HCINT9</displayName>
+               <description>OTG_FS host channel-9 interrupt           register</description>
+               <addressOffset>0x208</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>XFRC</name>
+                     <description>Transfer completed</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CHH</name>
+                     <description>Channel halted</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>STALL</name>
+                     <description>STALL response received               interrupt</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>NAK</name>
+                     <description>NAK response received               interrupt</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>ACK</name>
+                     <description>ACK response received/transmitted               interrupt</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TXERR</name>
+                     <description>Transaction error</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>BBERR</name>
+                     <description>Babble error</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FRMOR</name>
+                     <description>Frame overrun</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>DTERR</name>
+                     <description>Data toggle error</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_FS_HCINTMSK9</name>
+               <displayName>OTG_FS_HCINTMSK9</displayName>
+               <description>OTG_FS host channel-9 mask           register</description>
+               <addressOffset>0x20C</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>XFRCM</name>
+                     <description>Transfer completed mask</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CHHM</name>
+                     <description>Channel halted mask</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>STALLM</name>
+                     <description>STALL response received interrupt               mask</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>NAKM</name>
+                     <description>NAK response received interrupt               mask</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>ACKM</name>
+                     <description>ACK response received/transmitted               interrupt mask</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>NYET</name>
+                     <description>response received interrupt               mask</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TXERRM</name>
+                     <description>Transaction error mask</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>BBERRM</name>
+                     <description>Babble error mask</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FRMORM</name>
+                     <description>Frame overrun mask</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>DTERRM</name>
+                     <description>Data toggle error mask</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_FS_HCTSIZ9</name>
+               <displayName>OTG_FS_HCTSIZ9</displayName>
+               <description>OTG_FS host channel-9 transfer size           register</description>
+               <addressOffset>0x210</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>XFRSIZ</name>
+                     <description>Transfer size</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>19</bitWidth>
+                  </field>
+                  <field>
+                     <name>PKTCNT</name>
+                     <description>Packet count</description>
+                     <bitOffset>19</bitOffset>
+                     <bitWidth>10</bitWidth>
+                  </field>
+                  <field>
+                     <name>DPID</name>
+                     <description>Data PID</description>
+                     <bitOffset>29</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_FS_HCCHAR10</name>
+               <displayName>OTG_FS_HCCHAR10</displayName>
+               <description>OTG_FS host channel-10 characteristics           register</description>
+               <addressOffset>0x214</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>MPSIZ</name>
+                     <description>Maximum packet size</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>11</bitWidth>
+                  </field>
+                  <field>
+                     <name>EPNUM</name>
+                     <description>Endpoint number</description>
+                     <bitOffset>11</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+                  <field>
+                     <name>EPDIR</name>
+                     <description>Endpoint direction</description>
+                     <bitOffset>15</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>LSDEV</name>
+                     <description>Low-speed device</description>
+                     <bitOffset>17</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>EPTYP</name>
+                     <description>Endpoint type</description>
+                     <bitOffset>18</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>MCNT</name>
+                     <description>Multicount</description>
+                     <bitOffset>20</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>DAD</name>
+                     <description>Device address</description>
+                     <bitOffset>22</bitOffset>
+                     <bitWidth>7</bitWidth>
+                  </field>
+                  <field>
+                     <name>ODDFRM</name>
+                     <description>Odd frame</description>
+                     <bitOffset>29</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CHDIS</name>
+                     <description>Channel disable</description>
+                     <bitOffset>30</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CHENA</name>
+                     <description>Channel enable</description>
+                     <bitOffset>31</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_FS_HCINT10</name>
+               <displayName>OTG_FS_HCINT10</displayName>
+               <description>OTG_FS host channel-10 interrupt           register</description>
+               <addressOffset>0x218</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>XFRC</name>
+                     <description>Transfer completed</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CHH</name>
+                     <description>Channel halted</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>STALL</name>
+                     <description>STALL response received               interrupt</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>NAK</name>
+                     <description>NAK response received               interrupt</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>ACK</name>
+                     <description>ACK response received/transmitted               interrupt</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TXERR</name>
+                     <description>Transaction error</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>BBERR</name>
+                     <description>Babble error</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FRMOR</name>
+                     <description>Frame overrun</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>DTERR</name>
+                     <description>Data toggle error</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_FS_HCINTMSK10</name>
+               <displayName>OTG_FS_HCINTMSK10</displayName>
+               <description>OTG_FS host channel-10 mask           register</description>
+               <addressOffset>0x21C</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>XFRCM</name>
+                     <description>Transfer completed mask</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CHHM</name>
+                     <description>Channel halted mask</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>STALLM</name>
+                     <description>STALL response received interrupt               mask</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>NAKM</name>
+                     <description>NAK response received interrupt               mask</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>ACKM</name>
+                     <description>ACK response received/transmitted               interrupt mask</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>NYET</name>
+                     <description>response received interrupt               mask</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TXERRM</name>
+                     <description>Transaction error mask</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>BBERRM</name>
+                     <description>Babble error mask</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FRMORM</name>
+                     <description>Frame overrun mask</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>DTERRM</name>
+                     <description>Data toggle error mask</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_FS_HCTSIZ10</name>
+               <displayName>OTG_FS_HCTSIZ10</displayName>
+               <description>OTG_FS host channel-10 transfer size           register</description>
+               <addressOffset>0x220</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>XFRSIZ</name>
+                     <description>Transfer size</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>19</bitWidth>
+                  </field>
+                  <field>
+                     <name>PKTCNT</name>
+                     <description>Packet count</description>
+                     <bitOffset>19</bitOffset>
+                     <bitWidth>10</bitWidth>
+                  </field>
+                  <field>
+                     <name>DPID</name>
+                     <description>Data PID</description>
+                     <bitOffset>29</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_FS_HCCHAR11</name>
+               <displayName>OTG_FS_HCCHAR11</displayName>
+               <description>OTG_FS host channel-11 characteristics           register</description>
+               <addressOffset>0x224</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>MPSIZ</name>
+                     <description>Maximum packet size</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>11</bitWidth>
+                  </field>
+                  <field>
+                     <name>EPNUM</name>
+                     <description>Endpoint number</description>
+                     <bitOffset>11</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+                  <field>
+                     <name>EPDIR</name>
+                     <description>Endpoint direction</description>
+                     <bitOffset>15</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>LSDEV</name>
+                     <description>Low-speed device</description>
+                     <bitOffset>17</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>EPTYP</name>
+                     <description>Endpoint type</description>
+                     <bitOffset>18</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>MCNT</name>
+                     <description>Multicount</description>
+                     <bitOffset>20</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>DAD</name>
+                     <description>Device address</description>
+                     <bitOffset>22</bitOffset>
+                     <bitWidth>7</bitWidth>
+                  </field>
+                  <field>
+                     <name>ODDFRM</name>
+                     <description>Odd frame</description>
+                     <bitOffset>29</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CHDIS</name>
+                     <description>Channel disable</description>
+                     <bitOffset>30</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CHENA</name>
+                     <description>Channel enable</description>
+                     <bitOffset>31</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_FS_HCINT11</name>
+               <displayName>OTG_FS_HCINT11</displayName>
+               <description>OTG_FS host channel-11 interrupt           register</description>
+               <addressOffset>0x228</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>XFRC</name>
+                     <description>Transfer completed</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CHH</name>
+                     <description>Channel halted</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>STALL</name>
+                     <description>STALL response received               interrupt</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>NAK</name>
+                     <description>NAK response received               interrupt</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>ACK</name>
+                     <description>ACK response received/transmitted               interrupt</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TXERR</name>
+                     <description>Transaction error</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>BBERR</name>
+                     <description>Babble error</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FRMOR</name>
+                     <description>Frame overrun</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>DTERR</name>
+                     <description>Data toggle error</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_FS_HCINTMSK11</name>
+               <displayName>OTG_FS_HCINTMSK11</displayName>
+               <description>OTG_FS host channel-11 mask           register</description>
+               <addressOffset>0x22C</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>XFRCM</name>
+                     <description>Transfer completed mask</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CHHM</name>
+                     <description>Channel halted mask</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>STALLM</name>
+                     <description>STALL response received interrupt               mask</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>NAKM</name>
+                     <description>NAK response received interrupt               mask</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>ACKM</name>
+                     <description>ACK response received/transmitted               interrupt mask</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>NYET</name>
+                     <description>response received interrupt               mask</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TXERRM</name>
+                     <description>Transaction error mask</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>BBERRM</name>
+                     <description>Babble error mask</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FRMORM</name>
+                     <description>Frame overrun mask</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>DTERRM</name>
+                     <description>Data toggle error mask</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_FS_HCTSIZ11</name>
+               <displayName>OTG_FS_HCTSIZ11</displayName>
+               <description>OTG_FS host channel-11 transfer size           register</description>
+               <addressOffset>0x230</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>XFRSIZ</name>
+                     <description>Transfer size</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>19</bitWidth>
+                  </field>
+                  <field>
+                     <name>PKTCNT</name>
+                     <description>Packet count</description>
+                     <bitOffset>19</bitOffset>
+                     <bitWidth>10</bitWidth>
+                  </field>
+                  <field>
+                     <name>DPID</name>
+                     <description>Data PID</description>
+                     <bitOffset>29</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+               </fields>
+            </register>
+         </registers>
+      </peripheral>
+      <peripheral>
+         <name>OTG_FS_DEVICE</name>
+         <description>USB on the go full speed</description>
+         <groupName>USB_OTG_FS</groupName>
+         <baseAddress>0x50000800</baseAddress>
+         <addressBlock>
+            <offset>0x0</offset>
+            <size>0x400</size>
+            <usage>registers</usage>
+         </addressBlock>
+         <registers>
+            <register>
+               <name>OTG_FS_DCFG</name>
+               <displayName>OTG_FS_DCFG</displayName>
+               <description>OTG_FS device configuration register           (OTG_FS_DCFG)</description>
+               <addressOffset>0x0</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x02200000</resetValue>
+               <fields>
+                  <field>
+                     <name>DSPD</name>
+                     <description>Device speed</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>NZLSOHSK</name>
+                     <description>Non-zero-length status OUT               handshake</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>DAD</name>
+                     <description>Device address</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>7</bitWidth>
+                  </field>
+                  <field>
+                     <name>PFIVL</name>
+                     <description>Periodic frame interval</description>
+                     <bitOffset>11</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_FS_DCTL</name>
+               <displayName>OTG_FS_DCTL</displayName>
+               <description>OTG_FS device control register           (OTG_FS_DCTL)</description>
+               <addressOffset>0x4</addressOffset>
+               <size>0x20</size>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>RWUSIG</name>
+                     <description>Remote wakeup signaling</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>SDIS</name>
+                     <description>Soft disconnect</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>GINSTS</name>
+                     <description>Global IN NAK status</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-only</access>
+                  </field>
+                  <field>
+                     <name>GONSTS</name>
+                     <description>Global OUT NAK status</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-only</access>
+                  </field>
+                  <field>
+                     <name>TCTL</name>
+                     <description>Test control</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>3</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>SGINAK</name>
+                     <description>Set global IN NAK</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>CGINAK</name>
+                     <description>Clear global IN NAK</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>SGONAK</name>
+                     <description>Set global OUT NAK</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>CGONAK</name>
+                     <description>Clear global OUT NAK</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>POPRGDNE</name>
+                     <description>Power-on programming done</description>
+                     <bitOffset>11</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_FS_DSTS</name>
+               <displayName>OTG_FS_DSTS</displayName>
+               <description>OTG_FS device status register           (OTG_FS_DSTS)</description>
+               <addressOffset>0x8</addressOffset>
+               <size>0x20</size>
+               <access>read-only</access>
+               <resetValue>0x00000010</resetValue>
+               <fields>
+                  <field>
+                     <name>SUSPSTS</name>
+                     <description>Suspend status</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>ENUMSPD</name>
+                     <description>Enumerated speed</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>EERR</name>
+                     <description>Erratic error</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FNSOF</name>
+                     <description>Frame number of the received               SOF</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>14</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_FS_DIEPMSK</name>
+               <displayName>OTG_FS_DIEPMSK</displayName>
+               <description>OTG_FS device IN endpoint common interrupt           mask register (OTG_FS_DIEPMSK)</description>
+               <addressOffset>0x10</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>XFRCM</name>
+                     <description>Transfer completed interrupt               mask</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>EPDM</name>
+                     <description>Endpoint disabled interrupt               mask</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TOM</name>
+                     <description>Timeout condition mask (Non-isochronous               endpoints)</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>ITTXFEMSK</name>
+                     <description>IN token received when TxFIFO empty               mask</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>INEPNMM</name>
+                     <description>IN token received with EP mismatch               mask</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>INEPNEM</name>
+                     <description>IN endpoint NAK effective               mask</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_FS_DOEPMSK</name>
+               <displayName>OTG_FS_DOEPMSK</displayName>
+               <description>OTG_FS device OUT endpoint common interrupt           mask register (OTG_FS_DOEPMSK)</description>
+               <addressOffset>0x14</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>XFRCM</name>
+                     <description>Transfer completed interrupt               mask</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>EPDM</name>
+                     <description>Endpoint disabled interrupt               mask</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>STUPM</name>
+                     <description>SETUP phase done mask</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>OTEPDM</name>
+                     <description>OUT token received when endpoint               disabled mask</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_FS_DAINT</name>
+               <displayName>OTG_FS_DAINT</displayName>
+               <description>OTG_FS device all endpoints interrupt           register (OTG_FS_DAINT)</description>
+               <addressOffset>0x18</addressOffset>
+               <size>0x20</size>
+               <access>read-only</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>IEPINT</name>
+                     <description>IN endpoint interrupt bits</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+                  <field>
+                     <name>OEPINT</name>
+                     <description>OUT endpoint interrupt               bits</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_FS_DAINTMSK</name>
+               <displayName>OTG_FS_DAINTMSK</displayName>
+               <description>OTG_FS all endpoints interrupt mask register           (OTG_FS_DAINTMSK)</description>
+               <addressOffset>0x1C</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>IEPM</name>
+                     <description>IN EP interrupt mask bits</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+                  <field>
+                     <name>OEPINT</name>
+                     <description>OUT endpoint interrupt               bits</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_FS_DVBUSDIS</name>
+               <displayName>OTG_FS_DVBUSDIS</displayName>
+               <description>OTG_FS device VBUS discharge time           register</description>
+               <addressOffset>0x28</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x000017D7</resetValue>
+               <fields>
+                  <field>
+                     <name>VBUSDT</name>
+                     <description>Device VBUS discharge time</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_FS_DVBUSPULSE</name>
+               <displayName>OTG_FS_DVBUSPULSE</displayName>
+               <description>OTG_FS device VBUS pulsing time           register</description>
+               <addressOffset>0x2C</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x000005B8</resetValue>
+               <fields>
+                  <field>
+                     <name>DVBUSP</name>
+                     <description>Device VBUS pulsing time</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>12</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_FS_DIEPEMPMSK</name>
+               <displayName>OTG_FS_DIEPEMPMSK</displayName>
+               <description>OTG_FS device IN endpoint FIFO empty           interrupt mask register</description>
+               <addressOffset>0x34</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>INEPTXFEM</name>
+                     <description>IN EP Tx FIFO empty interrupt mask               bits</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_FS_DIEPCTL0</name>
+               <displayName>OTG_FS_DIEPCTL0</displayName>
+               <description>OTG_FS device control IN endpoint 0 control           register (OTG_FS_DIEPCTL0)</description>
+               <addressOffset>0x100</addressOffset>
+               <size>0x20</size>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>MPSIZ</name>
+                     <description>Maximum packet size</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>2</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>USBAEP</name>
+                     <description>USB active endpoint</description>
+                     <bitOffset>15</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-only</access>
+                  </field>
+                  <field>
+                     <name>NAKSTS</name>
+                     <description>NAK status</description>
+                     <bitOffset>17</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-only</access>
+                  </field>
+                  <field>
+                     <name>EPTYP</name>
+                     <description>Endpoint type</description>
+                     <bitOffset>18</bitOffset>
+                     <bitWidth>2</bitWidth>
+                     <access>read-only</access>
+                  </field>
+                  <field>
+                     <name>STALL</name>
+                     <description>STALL handshake</description>
+                     <bitOffset>21</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>TXFNUM</name>
+                     <description>TxFIFO number</description>
+                     <bitOffset>22</bitOffset>
+                     <bitWidth>4</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>CNAK</name>
+                     <description>Clear NAK</description>
+                     <bitOffset>26</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>write-only</access>
+                  </field>
+                  <field>
+                     <name>SNAK</name>
+                     <description>Set NAK</description>
+                     <bitOffset>27</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>write-only</access>
+                  </field>
+                  <field>
+                     <name>EPDIS</name>
+                     <description>Endpoint disable</description>
+                     <bitOffset>30</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-only</access>
+                  </field>
+                  <field>
+                     <name>EPENA</name>
+                     <description>Endpoint enable</description>
+                     <bitOffset>31</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-only</access>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_FS_DIEPCTL1</name>
+               <displayName>OTG_FS_DIEPCTL1</displayName>
+               <description>OTG device endpoint-1 control           register</description>
+               <addressOffset>0x120</addressOffset>
+               <size>0x20</size>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>EPENA</name>
+                     <description>EPENA</description>
+                     <bitOffset>31</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>EPDIS</name>
+                     <description>EPDIS</description>
+                     <bitOffset>30</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>SODDFRM_SD1PID</name>
+                     <description>SODDFRM/SD1PID</description>
+                     <bitOffset>29</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>write-only</access>
+                  </field>
+                  <field>
+                     <name>SD0PID_SEVNFRM</name>
+                     <description>SD0PID/SEVNFRM</description>
+                     <bitOffset>28</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>write-only</access>
+                  </field>
+                  <field>
+                     <name>SNAK</name>
+                     <description>SNAK</description>
+                     <bitOffset>27</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>write-only</access>
+                  </field>
+                  <field>
+                     <name>CNAK</name>
+                     <description>CNAK</description>
+                     <bitOffset>26</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>write-only</access>
+                  </field>
+                  <field>
+                     <name>TXFNUM</name>
+                     <description>TXFNUM</description>
+                     <bitOffset>22</bitOffset>
+                     <bitWidth>4</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>Stall</name>
+                     <description>Stall</description>
+                     <bitOffset>21</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>EPTYP</name>
+                     <description>EPTYP</description>
+                     <bitOffset>18</bitOffset>
+                     <bitWidth>2</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>NAKSTS</name>
+                     <description>NAKSTS</description>
+                     <bitOffset>17</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-only</access>
+                  </field>
+                  <field>
+                     <name>EONUM_DPID</name>
+                     <description>EONUM/DPID</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-only</access>
+                  </field>
+                  <field>
+                     <name>USBAEP</name>
+                     <description>USBAEP</description>
+                     <bitOffset>15</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>MPSIZ</name>
+                     <description>MPSIZ</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>11</bitWidth>
+                     <access>read-write</access>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_FS_DIEPCTL2</name>
+               <displayName>OTG_FS_DIEPCTL2</displayName>
+               <description>OTG device endpoint-2 control           register</description>
+               <addressOffset>0x140</addressOffset>
+               <size>0x20</size>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>EPENA</name>
+                     <description>EPENA</description>
+                     <bitOffset>31</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>EPDIS</name>
+                     <description>EPDIS</description>
+                     <bitOffset>30</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>SODDFRM</name>
+                     <description>SODDFRM</description>
+                     <bitOffset>29</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>write-only</access>
+                  </field>
+                  <field>
+                     <name>SD0PID_SEVNFRM</name>
+                     <description>SD0PID/SEVNFRM</description>
+                     <bitOffset>28</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>write-only</access>
+                  </field>
+                  <field>
+                     <name>SNAK</name>
+                     <description>SNAK</description>
+                     <bitOffset>27</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>write-only</access>
+                  </field>
+                  <field>
+                     <name>CNAK</name>
+                     <description>CNAK</description>
+                     <bitOffset>26</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>write-only</access>
+                  </field>
+                  <field>
+                     <name>TXFNUM</name>
+                     <description>TXFNUM</description>
+                     <bitOffset>22</bitOffset>
+                     <bitWidth>4</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>Stall</name>
+                     <description>Stall</description>
+                     <bitOffset>21</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>EPTYP</name>
+                     <description>EPTYP</description>
+                     <bitOffset>18</bitOffset>
+                     <bitWidth>2</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>NAKSTS</name>
+                     <description>NAKSTS</description>
+                     <bitOffset>17</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-only</access>
+                  </field>
+                  <field>
+                     <name>EONUM_DPID</name>
+                     <description>EONUM/DPID</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-only</access>
+                  </field>
+                  <field>
+                     <name>USBAEP</name>
+                     <description>USBAEP</description>
+                     <bitOffset>15</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>MPSIZ</name>
+                     <description>MPSIZ</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>11</bitWidth>
+                     <access>read-write</access>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_FS_DIEPCTL3</name>
+               <displayName>OTG_FS_DIEPCTL3</displayName>
+               <description>OTG device endpoint-3 control           register</description>
+               <addressOffset>0x160</addressOffset>
+               <size>0x20</size>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>EPENA</name>
+                     <description>EPENA</description>
+                     <bitOffset>31</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>EPDIS</name>
+                     <description>EPDIS</description>
+                     <bitOffset>30</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>SODDFRM</name>
+                     <description>SODDFRM</description>
+                     <bitOffset>29</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>write-only</access>
+                  </field>
+                  <field>
+                     <name>SD0PID_SEVNFRM</name>
+                     <description>SD0PID/SEVNFRM</description>
+                     <bitOffset>28</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>write-only</access>
+                  </field>
+                  <field>
+                     <name>SNAK</name>
+                     <description>SNAK</description>
+                     <bitOffset>27</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>write-only</access>
+                  </field>
+                  <field>
+                     <name>CNAK</name>
+                     <description>CNAK</description>
+                     <bitOffset>26</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>write-only</access>
+                  </field>
+                  <field>
+                     <name>TXFNUM</name>
+                     <description>TXFNUM</description>
+                     <bitOffset>22</bitOffset>
+                     <bitWidth>4</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>Stall</name>
+                     <description>Stall</description>
+                     <bitOffset>21</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>EPTYP</name>
+                     <description>EPTYP</description>
+                     <bitOffset>18</bitOffset>
+                     <bitWidth>2</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>NAKSTS</name>
+                     <description>NAKSTS</description>
+                     <bitOffset>17</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-only</access>
+                  </field>
+                  <field>
+                     <name>EONUM_DPID</name>
+                     <description>EONUM/DPID</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-only</access>
+                  </field>
+                  <field>
+                     <name>USBAEP</name>
+                     <description>USBAEP</description>
+                     <bitOffset>15</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>MPSIZ</name>
+                     <description>MPSIZ</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>11</bitWidth>
+                     <access>read-write</access>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_FS_DOEPCTL0</name>
+               <displayName>OTG_FS_DOEPCTL0</displayName>
+               <description>device endpoint-0 control           register</description>
+               <addressOffset>0x300</addressOffset>
+               <size>0x20</size>
+               <resetValue>0x00008000</resetValue>
+               <fields>
+                  <field>
+                     <name>EPENA</name>
+                     <description>EPENA</description>
+                     <bitOffset>31</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>write-only</access>
+                  </field>
+                  <field>
+                     <name>EPDIS</name>
+                     <description>EPDIS</description>
+                     <bitOffset>30</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-only</access>
+                  </field>
+                  <field>
+                     <name>SNAK</name>
+                     <description>SNAK</description>
+                     <bitOffset>27</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>write-only</access>
+                  </field>
+                  <field>
+                     <name>CNAK</name>
+                     <description>CNAK</description>
+                     <bitOffset>26</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>write-only</access>
+                  </field>
+                  <field>
+                     <name>Stall</name>
+                     <description>Stall</description>
+                     <bitOffset>21</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>SNPM</name>
+                     <description>SNPM</description>
+                     <bitOffset>20</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>EPTYP</name>
+                     <description>EPTYP</description>
+                     <bitOffset>18</bitOffset>
+                     <bitWidth>2</bitWidth>
+                     <access>read-only</access>
+                  </field>
+                  <field>
+                     <name>NAKSTS</name>
+                     <description>NAKSTS</description>
+                     <bitOffset>17</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-only</access>
+                  </field>
+                  <field>
+                     <name>USBAEP</name>
+                     <description>USBAEP</description>
+                     <bitOffset>15</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-only</access>
+                  </field>
+                  <field>
+                     <name>MPSIZ</name>
+                     <description>MPSIZ</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>2</bitWidth>
+                     <access>read-only</access>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_FS_DOEPCTL1</name>
+               <displayName>OTG_FS_DOEPCTL1</displayName>
+               <description>device endpoint-1 control           register</description>
+               <addressOffset>0x320</addressOffset>
+               <size>0x20</size>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>EPENA</name>
+                     <description>EPENA</description>
+                     <bitOffset>31</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>EPDIS</name>
+                     <description>EPDIS</description>
+                     <bitOffset>30</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>SODDFRM</name>
+                     <description>SODDFRM</description>
+                     <bitOffset>29</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>write-only</access>
+                  </field>
+                  <field>
+                     <name>SD0PID_SEVNFRM</name>
+                     <description>SD0PID/SEVNFRM</description>
+                     <bitOffset>28</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>write-only</access>
+                  </field>
+                  <field>
+                     <name>SNAK</name>
+                     <description>SNAK</description>
+                     <bitOffset>27</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>write-only</access>
+                  </field>
+                  <field>
+                     <name>CNAK</name>
+                     <description>CNAK</description>
+                     <bitOffset>26</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>write-only</access>
+                  </field>
+                  <field>
+                     <name>Stall</name>
+                     <description>Stall</description>
+                     <bitOffset>21</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>SNPM</name>
+                     <description>SNPM</description>
+                     <bitOffset>20</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>EPTYP</name>
+                     <description>EPTYP</description>
+                     <bitOffset>18</bitOffset>
+                     <bitWidth>2</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>NAKSTS</name>
+                     <description>NAKSTS</description>
+                     <bitOffset>17</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-only</access>
+                  </field>
+                  <field>
+                     <name>EONUM_DPID</name>
+                     <description>EONUM/DPID</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-only</access>
+                  </field>
+                  <field>
+                     <name>USBAEP</name>
+                     <description>USBAEP</description>
+                     <bitOffset>15</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>MPSIZ</name>
+                     <description>MPSIZ</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>11</bitWidth>
+                     <access>read-write</access>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_FS_DOEPCTL2</name>
+               <displayName>OTG_FS_DOEPCTL2</displayName>
+               <description>device endpoint-2 control           register</description>
+               <addressOffset>0x340</addressOffset>
+               <size>0x20</size>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>EPENA</name>
+                     <description>EPENA</description>
+                     <bitOffset>31</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>EPDIS</name>
+                     <description>EPDIS</description>
+                     <bitOffset>30</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>SODDFRM</name>
+                     <description>SODDFRM</description>
+                     <bitOffset>29</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>write-only</access>
+                  </field>
+                  <field>
+                     <name>SD0PID_SEVNFRM</name>
+                     <description>SD0PID/SEVNFRM</description>
+                     <bitOffset>28</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>write-only</access>
+                  </field>
+                  <field>
+                     <name>SNAK</name>
+                     <description>SNAK</description>
+                     <bitOffset>27</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>write-only</access>
+                  </field>
+                  <field>
+                     <name>CNAK</name>
+                     <description>CNAK</description>
+                     <bitOffset>26</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>write-only</access>
+                  </field>
+                  <field>
+                     <name>Stall</name>
+                     <description>Stall</description>
+                     <bitOffset>21</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>SNPM</name>
+                     <description>SNPM</description>
+                     <bitOffset>20</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>EPTYP</name>
+                     <description>EPTYP</description>
+                     <bitOffset>18</bitOffset>
+                     <bitWidth>2</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>NAKSTS</name>
+                     <description>NAKSTS</description>
+                     <bitOffset>17</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-only</access>
+                  </field>
+                  <field>
+                     <name>EONUM_DPID</name>
+                     <description>EONUM/DPID</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-only</access>
+                  </field>
+                  <field>
+                     <name>USBAEP</name>
+                     <description>USBAEP</description>
+                     <bitOffset>15</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>MPSIZ</name>
+                     <description>MPSIZ</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>11</bitWidth>
+                     <access>read-write</access>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_FS_DOEPCTL3</name>
+               <displayName>OTG_FS_DOEPCTL3</displayName>
+               <description>device endpoint-3 control           register</description>
+               <addressOffset>0x360</addressOffset>
+               <size>0x20</size>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>EPENA</name>
+                     <description>EPENA</description>
+                     <bitOffset>31</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>EPDIS</name>
+                     <description>EPDIS</description>
+                     <bitOffset>30</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>SODDFRM</name>
+                     <description>SODDFRM</description>
+                     <bitOffset>29</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>write-only</access>
+                  </field>
+                  <field>
+                     <name>SD0PID_SEVNFRM</name>
+                     <description>SD0PID/SEVNFRM</description>
+                     <bitOffset>28</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>write-only</access>
+                  </field>
+                  <field>
+                     <name>SNAK</name>
+                     <description>SNAK</description>
+                     <bitOffset>27</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>write-only</access>
+                  </field>
+                  <field>
+                     <name>CNAK</name>
+                     <description>CNAK</description>
+                     <bitOffset>26</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>write-only</access>
+                  </field>
+                  <field>
+                     <name>Stall</name>
+                     <description>Stall</description>
+                     <bitOffset>21</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>SNPM</name>
+                     <description>SNPM</description>
+                     <bitOffset>20</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>EPTYP</name>
+                     <description>EPTYP</description>
+                     <bitOffset>18</bitOffset>
+                     <bitWidth>2</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>NAKSTS</name>
+                     <description>NAKSTS</description>
+                     <bitOffset>17</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-only</access>
+                  </field>
+                  <field>
+                     <name>EONUM_DPID</name>
+                     <description>EONUM/DPID</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-only</access>
+                  </field>
+                  <field>
+                     <name>USBAEP</name>
+                     <description>USBAEP</description>
+                     <bitOffset>15</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>MPSIZ</name>
+                     <description>MPSIZ</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>11</bitWidth>
+                     <access>read-write</access>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_FS_DIEPINT0</name>
+               <displayName>OTG_FS_DIEPINT0</displayName>
+               <description>device endpoint-x interrupt           register</description>
+               <addressOffset>0x108</addressOffset>
+               <size>0x20</size>
+               <resetValue>0x00000080</resetValue>
+               <fields>
+                  <field>
+                     <name>TXFE</name>
+                     <description>TXFE</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-only</access>
+                  </field>
+                  <field>
+                     <name>INEPNE</name>
+                     <description>INEPNE</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>ITTXFE</name>
+                     <description>ITTXFE</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>TOC</name>
+                     <description>TOC</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>EPDISD</name>
+                     <description>EPDISD</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>XFRC</name>
+                     <description>XFRC</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_FS_DIEPINT1</name>
+               <displayName>OTG_FS_DIEPINT1</displayName>
+               <description>device endpoint-1 interrupt           register</description>
+               <addressOffset>0x128</addressOffset>
+               <size>0x20</size>
+               <resetValue>0x00000080</resetValue>
+               <fields>
+                  <field>
+                     <name>TXFE</name>
+                     <description>TXFE</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-only</access>
+                  </field>
+                  <field>
+                     <name>INEPNE</name>
+                     <description>INEPNE</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>ITTXFE</name>
+                     <description>ITTXFE</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>TOC</name>
+                     <description>TOC</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>EPDISD</name>
+                     <description>EPDISD</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>XFRC</name>
+                     <description>XFRC</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_FS_DIEPINT2</name>
+               <displayName>OTG_FS_DIEPINT2</displayName>
+               <description>device endpoint-2 interrupt           register</description>
+               <addressOffset>0x148</addressOffset>
+               <size>0x20</size>
+               <resetValue>0x00000080</resetValue>
+               <fields>
+                  <field>
+                     <name>TXFE</name>
+                     <description>TXFE</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-only</access>
+                  </field>
+                  <field>
+                     <name>INEPNE</name>
+                     <description>INEPNE</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>ITTXFE</name>
+                     <description>ITTXFE</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>TOC</name>
+                     <description>TOC</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>EPDISD</name>
+                     <description>EPDISD</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>XFRC</name>
+                     <description>XFRC</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_FS_DIEPINT3</name>
+               <displayName>OTG_FS_DIEPINT3</displayName>
+               <description>device endpoint-3 interrupt           register</description>
+               <addressOffset>0x168</addressOffset>
+               <size>0x20</size>
+               <resetValue>0x00000080</resetValue>
+               <fields>
+                  <field>
+                     <name>TXFE</name>
+                     <description>TXFE</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-only</access>
+                  </field>
+                  <field>
+                     <name>INEPNE</name>
+                     <description>INEPNE</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>ITTXFE</name>
+                     <description>ITTXFE</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>TOC</name>
+                     <description>TOC</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>EPDISD</name>
+                     <description>EPDISD</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>XFRC</name>
+                     <description>XFRC</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_FS_DOEPINT0</name>
+               <displayName>OTG_FS_DOEPINT0</displayName>
+               <description>device endpoint-0 interrupt           register</description>
+               <addressOffset>0x308</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000080</resetValue>
+               <fields>
+                  <field>
+                     <name>B2BSTUP</name>
+                     <description>B2BSTUP</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>OTEPDIS</name>
+                     <description>OTEPDIS</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>STUP</name>
+                     <description>STUP</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>EPDISD</name>
+                     <description>EPDISD</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>XFRC</name>
+                     <description>XFRC</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_FS_DOEPINT1</name>
+               <displayName>OTG_FS_DOEPINT1</displayName>
+               <description>device endpoint-1 interrupt           register</description>
+               <addressOffset>0x328</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000080</resetValue>
+               <fields>
+                  <field>
+                     <name>B2BSTUP</name>
+                     <description>B2BSTUP</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>OTEPDIS</name>
+                     <description>OTEPDIS</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>STUP</name>
+                     <description>STUP</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>EPDISD</name>
+                     <description>EPDISD</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>XFRC</name>
+                     <description>XFRC</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_FS_DOEPINT2</name>
+               <displayName>OTG_FS_DOEPINT2</displayName>
+               <description>device endpoint-2 interrupt           register</description>
+               <addressOffset>0x348</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000080</resetValue>
+               <fields>
+                  <field>
+                     <name>B2BSTUP</name>
+                     <description>B2BSTUP</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>OTEPDIS</name>
+                     <description>OTEPDIS</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>STUP</name>
+                     <description>STUP</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>EPDISD</name>
+                     <description>EPDISD</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>XFRC</name>
+                     <description>XFRC</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_FS_DOEPINT3</name>
+               <displayName>OTG_FS_DOEPINT3</displayName>
+               <description>device endpoint-3 interrupt           register</description>
+               <addressOffset>0x368</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000080</resetValue>
+               <fields>
+                  <field>
+                     <name>B2BSTUP</name>
+                     <description>B2BSTUP</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>OTEPDIS</name>
+                     <description>OTEPDIS</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>STUP</name>
+                     <description>STUP</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>EPDISD</name>
+                     <description>EPDISD</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>XFRC</name>
+                     <description>XFRC</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_FS_DIEPTSIZ0</name>
+               <displayName>OTG_FS_DIEPTSIZ0</displayName>
+               <description>device endpoint-0 transfer size           register</description>
+               <addressOffset>0x110</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>PKTCNT</name>
+                     <description>Packet count</description>
+                     <bitOffset>19</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>XFRSIZ</name>
+                     <description>Transfer size</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>7</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_FS_DOEPTSIZ0</name>
+               <displayName>OTG_FS_DOEPTSIZ0</displayName>
+               <description>device OUT endpoint-0 transfer size           register</description>
+               <addressOffset>0x310</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>STUPCNT</name>
+                     <description>SETUP packet count</description>
+                     <bitOffset>29</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>PKTCNT</name>
+                     <description>Packet count</description>
+                     <bitOffset>19</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>XFRSIZ</name>
+                     <description>Transfer size</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>7</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_FS_DIEPTSIZ1</name>
+               <displayName>OTG_FS_DIEPTSIZ1</displayName>
+               <description>device endpoint-1 transfer size           register</description>
+               <addressOffset>0x130</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>MCNT</name>
+                     <description>Multi count</description>
+                     <bitOffset>29</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>PKTCNT</name>
+                     <description>Packet count</description>
+                     <bitOffset>19</bitOffset>
+                     <bitWidth>10</bitWidth>
+                  </field>
+                  <field>
+                     <name>XFRSIZ</name>
+                     <description>Transfer size</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>19</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_FS_DIEPTSIZ2</name>
+               <displayName>OTG_FS_DIEPTSIZ2</displayName>
+               <description>device endpoint-2 transfer size           register</description>
+               <addressOffset>0x150</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>MCNT</name>
+                     <description>Multi count</description>
+                     <bitOffset>29</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>PKTCNT</name>
+                     <description>Packet count</description>
+                     <bitOffset>19</bitOffset>
+                     <bitWidth>10</bitWidth>
+                  </field>
+                  <field>
+                     <name>XFRSIZ</name>
+                     <description>Transfer size</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>19</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_FS_DIEPTSIZ3</name>
+               <displayName>OTG_FS_DIEPTSIZ3</displayName>
+               <description>device endpoint-3 transfer size           register</description>
+               <addressOffset>0x170</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>MCNT</name>
+                     <description>Multi count</description>
+                     <bitOffset>29</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>PKTCNT</name>
+                     <description>Packet count</description>
+                     <bitOffset>19</bitOffset>
+                     <bitWidth>10</bitWidth>
+                  </field>
+                  <field>
+                     <name>XFRSIZ</name>
+                     <description>Transfer size</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>19</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_FS_DTXFSTS0</name>
+               <displayName>OTG_FS_DTXFSTS0</displayName>
+               <description>OTG_FS device IN endpoint transmit FIFO           status register</description>
+               <addressOffset>0x118</addressOffset>
+               <size>0x20</size>
+               <access>read-only</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>INEPTFSAV</name>
+                     <description>IN endpoint TxFIFO space               available</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_FS_DTXFSTS1</name>
+               <displayName>OTG_FS_DTXFSTS1</displayName>
+               <description>OTG_FS device IN endpoint transmit FIFO           status register</description>
+               <addressOffset>0x138</addressOffset>
+               <size>0x20</size>
+               <access>read-only</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>INEPTFSAV</name>
+                     <description>IN endpoint TxFIFO space               available</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_FS_DTXFSTS2</name>
+               <displayName>OTG_FS_DTXFSTS2</displayName>
+               <description>OTG_FS device IN endpoint transmit FIFO           status register</description>
+               <addressOffset>0x158</addressOffset>
+               <size>0x20</size>
+               <access>read-only</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>INEPTFSAV</name>
+                     <description>IN endpoint TxFIFO space               available</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_FS_DTXFSTS3</name>
+               <displayName>OTG_FS_DTXFSTS3</displayName>
+               <description>OTG_FS device IN endpoint transmit FIFO           status register</description>
+               <addressOffset>0x178</addressOffset>
+               <size>0x20</size>
+               <access>read-only</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>INEPTFSAV</name>
+                     <description>IN endpoint TxFIFO space               available</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_FS_DOEPTSIZ1</name>
+               <displayName>OTG_FS_DOEPTSIZ1</displayName>
+               <description>device OUT endpoint-1 transfer size           register</description>
+               <addressOffset>0x330</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>RXDPID_STUPCNT</name>
+                     <description>Received data PID/SETUP packet               count</description>
+                     <bitOffset>29</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>PKTCNT</name>
+                     <description>Packet count</description>
+                     <bitOffset>19</bitOffset>
+                     <bitWidth>10</bitWidth>
+                  </field>
+                  <field>
+                     <name>XFRSIZ</name>
+                     <description>Transfer size</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>19</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_FS_DOEPTSIZ2</name>
+               <displayName>OTG_FS_DOEPTSIZ2</displayName>
+               <description>device OUT endpoint-2 transfer size           register</description>
+               <addressOffset>0x350</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>RXDPID_STUPCNT</name>
+                     <description>Received data PID/SETUP packet               count</description>
+                     <bitOffset>29</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>PKTCNT</name>
+                     <description>Packet count</description>
+                     <bitOffset>19</bitOffset>
+                     <bitWidth>10</bitWidth>
+                  </field>
+                  <field>
+                     <name>XFRSIZ</name>
+                     <description>Transfer size</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>19</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_FS_DOEPTSIZ3</name>
+               <displayName>OTG_FS_DOEPTSIZ3</displayName>
+               <description>device OUT endpoint-3 transfer size           register</description>
+               <addressOffset>0x370</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>RXDPID_STUPCNT</name>
+                     <description>Received data PID/SETUP packet               count</description>
+                     <bitOffset>29</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>PKTCNT</name>
+                     <description>Packet count</description>
+                     <bitOffset>19</bitOffset>
+                     <bitWidth>10</bitWidth>
+                  </field>
+                  <field>
+                     <name>XFRSIZ</name>
+                     <description>Transfer size</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>19</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_FS_DIEPCTL4</name>
+               <displayName>OTG_FS_DIEPCTL4</displayName>
+               <description>OTG device endpoint-4 control           register</description>
+               <addressOffset>0x180</addressOffset>
+               <size>0x20</size>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>EPENA</name>
+                     <description>EPENA</description>
+                     <bitOffset>31</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>EPDIS</name>
+                     <description>EPDIS</description>
+                     <bitOffset>30</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>SODDFRM</name>
+                     <description>SODDFRM</description>
+                     <bitOffset>29</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>write-only</access>
+                  </field>
+                  <field>
+                     <name>SD0PID_SEVNFRM</name>
+                     <description>SD0PID/SEVNFRM</description>
+                     <bitOffset>28</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>write-only</access>
+                  </field>
+                  <field>
+                     <name>SNAK</name>
+                     <description>SNAK</description>
+                     <bitOffset>27</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>write-only</access>
+                  </field>
+                  <field>
+                     <name>CNAK</name>
+                     <description>CNAK</description>
+                     <bitOffset>26</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>write-only</access>
+                  </field>
+                  <field>
+                     <name>TXFNUM</name>
+                     <description>TXFNUM</description>
+                     <bitOffset>22</bitOffset>
+                     <bitWidth>4</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>Stall</name>
+                     <description>Stall</description>
+                     <bitOffset>21</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>EPTYP</name>
+                     <description>EPTYP</description>
+                     <bitOffset>18</bitOffset>
+                     <bitWidth>2</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>NAKSTS</name>
+                     <description>NAKSTS</description>
+                     <bitOffset>17</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-only</access>
+                  </field>
+                  <field>
+                     <name>EONUM_DPID</name>
+                     <description>EONUM/DPID</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-only</access>
+                  </field>
+                  <field>
+                     <name>USBAEP</name>
+                     <description>USBAEP</description>
+                     <bitOffset>15</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>MPSIZ</name>
+                     <description>MPSIZ</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>11</bitWidth>
+                     <access>read-write</access>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_FS_DIEPINT4</name>
+               <displayName>OTG_FS_DIEPINT4</displayName>
+               <description>device endpoint-4 interrupt           register</description>
+               <addressOffset>0x188</addressOffset>
+               <size>0x20</size>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>TXFE</name>
+                     <description>TXFE</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-only</access>
+                  </field>
+                  <field>
+                     <name>INEPNE</name>
+                     <description>INEPNE</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>ITTXFE</name>
+                     <description>ITTXFE</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>TOC</name>
+                     <description>TOC</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>EPDISD</name>
+                     <description>EPDISD</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>XFRC</name>
+                     <description>XFRC</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_FS_DIEPTSIZ4</name>
+               <displayName>OTG_FS_DIEPTSIZ4</displayName>
+               <description>device endpoint-4 transfer size           register</description>
+               <addressOffset>0x194</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>MCNT</name>
+                     <description>Multi count</description>
+                     <bitOffset>29</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>PKTCNT</name>
+                     <description>Packet count</description>
+                     <bitOffset>19</bitOffset>
+                     <bitWidth>10</bitWidth>
+                  </field>
+                  <field>
+                     <name>XFRSIZ</name>
+                     <description>Transfer size</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>19</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_FS_DTXFSTS4</name>
+               <displayName>OTG_FS_DTXFSTS4</displayName>
+               <description>OTG_FS device IN endpoint transmit FIFO           status register</description>
+               <addressOffset>0x19C</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>INEPTFSAV</name>
+                     <description>IN endpoint TxFIFO space               available</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_FS_DIEPCTL5</name>
+               <displayName>OTG_FS_DIEPCTL5</displayName>
+               <description>OTG device endpoint-5 control           register</description>
+               <addressOffset>0x1A0</addressOffset>
+               <size>0x20</size>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>EPENA</name>
+                     <description>EPENA</description>
+                     <bitOffset>31</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>EPDIS</name>
+                     <description>EPDIS</description>
+                     <bitOffset>30</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>SODDFRM</name>
+                     <description>SODDFRM</description>
+                     <bitOffset>29</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>write-only</access>
+                  </field>
+                  <field>
+                     <name>SD0PID_SEVNFRM</name>
+                     <description>SD0PID/SEVNFRM</description>
+                     <bitOffset>28</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>write-only</access>
+                  </field>
+                  <field>
+                     <name>SNAK</name>
+                     <description>SNAK</description>
+                     <bitOffset>27</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>write-only</access>
+                  </field>
+                  <field>
+                     <name>CNAK</name>
+                     <description>CNAK</description>
+                     <bitOffset>26</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>write-only</access>
+                  </field>
+                  <field>
+                     <name>TXFNUM</name>
+                     <description>TXFNUM</description>
+                     <bitOffset>22</bitOffset>
+                     <bitWidth>4</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>Stall</name>
+                     <description>Stall</description>
+                     <bitOffset>21</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>EPTYP</name>
+                     <description>EPTYP</description>
+                     <bitOffset>18</bitOffset>
+                     <bitWidth>2</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>NAKSTS</name>
+                     <description>NAKSTS</description>
+                     <bitOffset>17</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-only</access>
+                  </field>
+                  <field>
+                     <name>EONUM_DPID</name>
+                     <description>EONUM/DPID</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-only</access>
+                  </field>
+                  <field>
+                     <name>USBAEP</name>
+                     <description>USBAEP</description>
+                     <bitOffset>15</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>MPSIZ</name>
+                     <description>MPSIZ</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>11</bitWidth>
+                     <access>read-write</access>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_FS_DIEPINT5</name>
+               <displayName>OTG_FS_DIEPINT5</displayName>
+               <description>device endpoint-5 interrupt           register</description>
+               <addressOffset>0x1A8</addressOffset>
+               <size>0x20</size>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>TXFE</name>
+                     <description>TXFE</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-only</access>
+                  </field>
+                  <field>
+                     <name>INEPNE</name>
+                     <description>INEPNE</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>ITTXFE</name>
+                     <description>ITTXFE</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>TOC</name>
+                     <description>TOC</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>EPDISD</name>
+                     <description>EPDISD</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>XFRC</name>
+                     <description>XFRC</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_FS_DIEPTSIZ55</name>
+               <displayName>OTG_FS_DIEPTSIZ55</displayName>
+               <description>device endpoint-5 transfer size           register</description>
+               <addressOffset>0x1B0</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>MCNT</name>
+                     <description>Multi count</description>
+                     <bitOffset>29</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>PKTCNT</name>
+                     <description>Packet count</description>
+                     <bitOffset>19</bitOffset>
+                     <bitWidth>10</bitWidth>
+                  </field>
+                  <field>
+                     <name>XFRSIZ</name>
+                     <description>Transfer size</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>19</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_FS_DTXFSTS55</name>
+               <displayName>OTG_FS_DTXFSTS55</displayName>
+               <description>OTG_FS device IN endpoint transmit FIFO           status register</description>
+               <addressOffset>0x1B8</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>INEPTFSAV</name>
+                     <description>IN endpoint TxFIFO space               available</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_FS_DOEPCTL4</name>
+               <displayName>OTG_FS_DOEPCTL4</displayName>
+               <description>device endpoint-4 control           register</description>
+               <addressOffset>0x378</addressOffset>
+               <size>0x20</size>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>EPENA</name>
+                     <description>EPENA</description>
+                     <bitOffset>31</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>EPDIS</name>
+                     <description>EPDIS</description>
+                     <bitOffset>30</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>SODDFRM</name>
+                     <description>SODDFRM</description>
+                     <bitOffset>29</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>write-only</access>
+                  </field>
+                  <field>
+                     <name>SD0PID_SEVNFRM</name>
+                     <description>SD0PID/SEVNFRM</description>
+                     <bitOffset>28</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>write-only</access>
+                  </field>
+                  <field>
+                     <name>SNAK</name>
+                     <description>SNAK</description>
+                     <bitOffset>27</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>write-only</access>
+                  </field>
+                  <field>
+                     <name>CNAK</name>
+                     <description>CNAK</description>
+                     <bitOffset>26</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>write-only</access>
+                  </field>
+                  <field>
+                     <name>Stall</name>
+                     <description>Stall</description>
+                     <bitOffset>21</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>SNPM</name>
+                     <description>SNPM</description>
+                     <bitOffset>20</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>EPTYP</name>
+                     <description>EPTYP</description>
+                     <bitOffset>18</bitOffset>
+                     <bitWidth>2</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>NAKSTS</name>
+                     <description>NAKSTS</description>
+                     <bitOffset>17</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-only</access>
+                  </field>
+                  <field>
+                     <name>EONUM_DPID</name>
+                     <description>EONUM/DPID</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-only</access>
+                  </field>
+                  <field>
+                     <name>USBAEP</name>
+                     <description>USBAEP</description>
+                     <bitOffset>15</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>MPSIZ</name>
+                     <description>MPSIZ</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>11</bitWidth>
+                     <access>read-write</access>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_FS_DOEPINT4</name>
+               <displayName>OTG_FS_DOEPINT4</displayName>
+               <description>device endpoint-4 interrupt           register</description>
+               <addressOffset>0x380</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>B2BSTUP</name>
+                     <description>B2BSTUP</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>OTEPDIS</name>
+                     <description>OTEPDIS</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>STUP</name>
+                     <description>STUP</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>EPDISD</name>
+                     <description>EPDISD</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>XFRC</name>
+                     <description>XFRC</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_FS_DOEPTSIZ4</name>
+               <displayName>OTG_FS_DOEPTSIZ4</displayName>
+               <description>device OUT endpoint-4 transfer size           register</description>
+               <addressOffset>0x388</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>RXDPID_STUPCNT</name>
+                     <description>Received data PID/SETUP packet               count</description>
+                     <bitOffset>29</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>PKTCNT</name>
+                     <description>Packet count</description>
+                     <bitOffset>19</bitOffset>
+                     <bitWidth>10</bitWidth>
+                  </field>
+                  <field>
+                     <name>XFRSIZ</name>
+                     <description>Transfer size</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>19</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_FS_DOEPCTL5</name>
+               <displayName>OTG_FS_DOEPCTL5</displayName>
+               <description>device endpoint-5 control           register</description>
+               <addressOffset>0x390</addressOffset>
+               <size>0x20</size>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>EPENA</name>
+                     <description>EPENA</description>
+                     <bitOffset>31</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>EPDIS</name>
+                     <description>EPDIS</description>
+                     <bitOffset>30</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>SODDFRM</name>
+                     <description>SODDFRM</description>
+                     <bitOffset>29</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>write-only</access>
+                  </field>
+                  <field>
+                     <name>SD0PID_SEVNFRM</name>
+                     <description>SD0PID/SEVNFRM</description>
+                     <bitOffset>28</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>write-only</access>
+                  </field>
+                  <field>
+                     <name>SNAK</name>
+                     <description>SNAK</description>
+                     <bitOffset>27</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>write-only</access>
+                  </field>
+                  <field>
+                     <name>CNAK</name>
+                     <description>CNAK</description>
+                     <bitOffset>26</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>write-only</access>
+                  </field>
+                  <field>
+                     <name>Stall</name>
+                     <description>Stall</description>
+                     <bitOffset>21</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>SNPM</name>
+                     <description>SNPM</description>
+                     <bitOffset>20</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>EPTYP</name>
+                     <description>EPTYP</description>
+                     <bitOffset>18</bitOffset>
+                     <bitWidth>2</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>NAKSTS</name>
+                     <description>NAKSTS</description>
+                     <bitOffset>17</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-only</access>
+                  </field>
+                  <field>
+                     <name>EONUM_DPID</name>
+                     <description>EONUM/DPID</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-only</access>
+                  </field>
+                  <field>
+                     <name>USBAEP</name>
+                     <description>USBAEP</description>
+                     <bitOffset>15</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>MPSIZ</name>
+                     <description>MPSIZ</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>11</bitWidth>
+                     <access>read-write</access>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_FS_DOEPINT5</name>
+               <displayName>OTG_FS_DOEPINT5</displayName>
+               <description>device endpoint-5 interrupt           register</description>
+               <addressOffset>0x398</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>B2BSTUP</name>
+                     <description>B2BSTUP</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>OTEPDIS</name>
+                     <description>OTEPDIS</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>STUP</name>
+                     <description>STUP</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>EPDISD</name>
+                     <description>EPDISD</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>XFRC</name>
+                     <description>XFRC</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_FS_DOEPTSIZ5</name>
+               <displayName>OTG_FS_DOEPTSIZ5</displayName>
+               <description>device OUT endpoint-5 transfer size           register</description>
+               <addressOffset>0x3A0</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>RXDPID_STUPCNT</name>
+                     <description>Received data PID/SETUP packet               count</description>
+                     <bitOffset>29</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>PKTCNT</name>
+                     <description>Packet count</description>
+                     <bitOffset>19</bitOffset>
+                     <bitWidth>10</bitWidth>
+                  </field>
+                  <field>
+                     <name>XFRSIZ</name>
+                     <description>Transfer size</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>19</bitWidth>
+                  </field>
+               </fields>
+            </register>
+         </registers>
+      </peripheral>
+      <peripheral>
+         <name>OTG_FS_PWRCLK</name>
+         <description>USB on the go full speed</description>
+         <groupName>USB_OTG_FS</groupName>
+         <baseAddress>0x50000E00</baseAddress>
+         <addressBlock>
+            <offset>0x0</offset>
+            <size>0x400</size>
+            <usage>registers</usage>
+         </addressBlock>
+         <registers>
+            <register>
+               <name>OTG_FS_PCGCCTL</name>
+               <displayName>OTG_FS_PCGCCTL</displayName>
+               <description>OTG_FS power and clock gating control           register (OTG_FS_PCGCCTL)</description>
+               <addressOffset>0x0</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>STPPCLK</name>
+                     <description>Stop PHY clock</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>GATEHCLK</name>
+                     <description>Gate HCLK</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>PHYSUSP</name>
+                     <description>PHY Suspended</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+         </registers>
+      </peripheral>
+      <peripheral>
+         <name>OTG_HS_HOST</name>
+         <description>USB on the go high speed</description>
+         <groupName>USB_OTG_HS</groupName>
+         <baseAddress>0x40040400</baseAddress>
+         <addressBlock>
+            <offset>0x0</offset>
+            <size>0x400</size>
+            <usage>registers</usage>
+         </addressBlock>
+         <registers>
+            <register>
+               <name>OTG_HS_HCFG</name>
+               <displayName>OTG_HS_HCFG</displayName>
+               <description>OTG_HS host configuration           register</description>
+               <addressOffset>0x0</addressOffset>
+               <size>32</size>
+               <resetValue>0x0</resetValue>
+               <fields>
+                  <field>
+                     <name>FSLSPCS</name>
+                     <description>FS/LS PHY clock select</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>2</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>FSLSS</name>
+                     <description>FS- and LS-only support</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-only</access>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_HS_HFIR</name>
+               <displayName>OTG_HS_HFIR</displayName>
+               <description>OTG_HS Host frame interval           register</description>
+               <addressOffset>0x4</addressOffset>
+               <size>32</size>
+               <access>read-write</access>
+               <resetValue>0x0000EA60</resetValue>
+               <fields>
+                  <field>
+                     <name>FRIVL</name>
+                     <description>Frame interval</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_HS_HFNUM</name>
+               <displayName>OTG_HS_HFNUM</displayName>
+               <description>OTG_HS host frame number/frame time           remaining register</description>
+               <addressOffset>0x8</addressOffset>
+               <size>32</size>
+               <access>read-only</access>
+               <resetValue>0x00003FFF</resetValue>
+               <fields>
+                  <field>
+                     <name>FRNUM</name>
+                     <description>Frame number</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+                  <field>
+                     <name>FTREM</name>
+                     <description>Frame time remaining</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_HS_HPTXSTS</name>
+               <displayName>OTG_HS_HPTXSTS</displayName>
+               <description>OTG_HS_Host periodic transmit FIFO/queue           status register</description>
+               <addressOffset>0x10</addressOffset>
+               <size>32</size>
+               <resetValue>0x00080100</resetValue>
+               <fields>
+                  <field>
+                     <name>PTXFSAVL</name>
+                     <description>Periodic transmit data FIFO space               available</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>16</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>PTXQSAV</name>
+                     <description>Periodic transmit request queue space               available</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>8</bitWidth>
+                     <access>read-only</access>
+                  </field>
+                  <field>
+                     <name>PTXQTOP</name>
+                     <description>Top of the periodic transmit request               queue</description>
+                     <bitOffset>24</bitOffset>
+                     <bitWidth>8</bitWidth>
+                     <access>read-only</access>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_HS_HAINT</name>
+               <displayName>OTG_HS_HAINT</displayName>
+               <description>OTG_HS Host all channels interrupt           register</description>
+               <addressOffset>0x14</addressOffset>
+               <size>32</size>
+               <access>read-only</access>
+               <resetValue>0x0</resetValue>
+               <fields>
+                  <field>
+                     <name>HAINT</name>
+                     <description>Channel interrupts</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_HS_HAINTMSK</name>
+               <displayName>OTG_HS_HAINTMSK</displayName>
+               <description>OTG_HS host all channels interrupt mask           register</description>
+               <addressOffset>0x18</addressOffset>
+               <size>32</size>
+               <access>read-write</access>
+               <resetValue>0x0</resetValue>
+               <fields>
+                  <field>
+                     <name>HAINTM</name>
+                     <description>Channel interrupt mask</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_HS_HPRT</name>
+               <displayName>OTG_HS_HPRT</displayName>
+               <description>OTG_HS host port control and status           register</description>
+               <addressOffset>0x40</addressOffset>
+               <size>32</size>
+               <resetValue>0x0</resetValue>
+               <fields>
+                  <field>
+                     <name>PCSTS</name>
+                     <description>Port connect status</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-only</access>
+                  </field>
+                  <field>
+                     <name>PCDET</name>
+                     <description>Port connect detected</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>PENA</name>
+                     <description>Port enable</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>PENCHNG</name>
+                     <description>Port enable/disable change</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>POCA</name>
+                     <description>Port overcurrent active</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-only</access>
+                  </field>
+                  <field>
+                     <name>POCCHNG</name>
+                     <description>Port overcurrent change</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>PRES</name>
+                     <description>Port resume</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>PSUSP</name>
+                     <description>Port suspend</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>PRST</name>
+                     <description>Port reset</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>PLSTS</name>
+                     <description>Port line status</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>2</bitWidth>
+                     <access>read-only</access>
+                  </field>
+                  <field>
+                     <name>PPWR</name>
+                     <description>Port power</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>PTCTL</name>
+                     <description>Port test control</description>
+                     <bitOffset>13</bitOffset>
+                     <bitWidth>4</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>PSPD</name>
+                     <description>Port speed</description>
+                     <bitOffset>17</bitOffset>
+                     <bitWidth>2</bitWidth>
+                     <access>read-only</access>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_HS_HCCHAR0</name>
+               <displayName>OTG_HS_HCCHAR0</displayName>
+               <description>OTG_HS host channel-0 characteristics           register</description>
+               <addressOffset>0x100</addressOffset>
+               <size>32</size>
+               <access>read-write</access>
+               <resetValue>0x0</resetValue>
+               <fields>
+                  <field>
+                     <name>MPSIZ</name>
+                     <description>Maximum packet size</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>11</bitWidth>
+                  </field>
+                  <field>
+                     <name>EPNUM</name>
+                     <description>Endpoint number</description>
+                     <bitOffset>11</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+                  <field>
+                     <name>EPDIR</name>
+                     <description>Endpoint direction</description>
+                     <bitOffset>15</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>LSDEV</name>
+                     <description>Low-speed device</description>
+                     <bitOffset>17</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>EPTYP</name>
+                     <description>Endpoint type</description>
+                     <bitOffset>18</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>MC</name>
+                     <description>Multi Count (MC) / Error Count               (EC)</description>
+                     <bitOffset>20</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>DAD</name>
+                     <description>Device address</description>
+                     <bitOffset>22</bitOffset>
+                     <bitWidth>7</bitWidth>
+                  </field>
+                  <field>
+                     <name>ODDFRM</name>
+                     <description>Odd frame</description>
+                     <bitOffset>29</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CHDIS</name>
+                     <description>Channel disable</description>
+                     <bitOffset>30</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CHENA</name>
+                     <description>Channel enable</description>
+                     <bitOffset>31</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_HS_HCCHAR1</name>
+               <displayName>OTG_HS_HCCHAR1</displayName>
+               <description>OTG_HS host channel-1 characteristics           register</description>
+               <addressOffset>0x120</addressOffset>
+               <size>32</size>
+               <access>read-write</access>
+               <resetValue>0x0</resetValue>
+               <fields>
+                  <field>
+                     <name>MPSIZ</name>
+                     <description>Maximum packet size</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>11</bitWidth>
+                  </field>
+                  <field>
+                     <name>EPNUM</name>
+                     <description>Endpoint number</description>
+                     <bitOffset>11</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+                  <field>
+                     <name>EPDIR</name>
+                     <description>Endpoint direction</description>
+                     <bitOffset>15</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>LSDEV</name>
+                     <description>Low-speed device</description>
+                     <bitOffset>17</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>EPTYP</name>
+                     <description>Endpoint type</description>
+                     <bitOffset>18</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>MC</name>
+                     <description>Multi Count (MC) / Error Count               (EC)</description>
+                     <bitOffset>20</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>DAD</name>
+                     <description>Device address</description>
+                     <bitOffset>22</bitOffset>
+                     <bitWidth>7</bitWidth>
+                  </field>
+                  <field>
+                     <name>ODDFRM</name>
+                     <description>Odd frame</description>
+                     <bitOffset>29</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CHDIS</name>
+                     <description>Channel disable</description>
+                     <bitOffset>30</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CHENA</name>
+                     <description>Channel enable</description>
+                     <bitOffset>31</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_HS_HCCHAR2</name>
+               <displayName>OTG_HS_HCCHAR2</displayName>
+               <description>OTG_HS host channel-2 characteristics           register</description>
+               <addressOffset>0x140</addressOffset>
+               <size>32</size>
+               <access>read-write</access>
+               <resetValue>0x0</resetValue>
+               <fields>
+                  <field>
+                     <name>MPSIZ</name>
+                     <description>Maximum packet size</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>11</bitWidth>
+                  </field>
+                  <field>
+                     <name>EPNUM</name>
+                     <description>Endpoint number</description>
+                     <bitOffset>11</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+                  <field>
+                     <name>EPDIR</name>
+                     <description>Endpoint direction</description>
+                     <bitOffset>15</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>LSDEV</name>
+                     <description>Low-speed device</description>
+                     <bitOffset>17</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>EPTYP</name>
+                     <description>Endpoint type</description>
+                     <bitOffset>18</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>MC</name>
+                     <description>Multi Count (MC) / Error Count               (EC)</description>
+                     <bitOffset>20</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>DAD</name>
+                     <description>Device address</description>
+                     <bitOffset>22</bitOffset>
+                     <bitWidth>7</bitWidth>
+                  </field>
+                  <field>
+                     <name>ODDFRM</name>
+                     <description>Odd frame</description>
+                     <bitOffset>29</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CHDIS</name>
+                     <description>Channel disable</description>
+                     <bitOffset>30</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CHENA</name>
+                     <description>Channel enable</description>
+                     <bitOffset>31</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_HS_HCCHAR3</name>
+               <displayName>OTG_HS_HCCHAR3</displayName>
+               <description>OTG_HS host channel-3 characteristics           register</description>
+               <addressOffset>0x160</addressOffset>
+               <size>32</size>
+               <access>read-write</access>
+               <resetValue>0x0</resetValue>
+               <fields>
+                  <field>
+                     <name>MPSIZ</name>
+                     <description>Maximum packet size</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>11</bitWidth>
+                  </field>
+                  <field>
+                     <name>EPNUM</name>
+                     <description>Endpoint number</description>
+                     <bitOffset>11</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+                  <field>
+                     <name>EPDIR</name>
+                     <description>Endpoint direction</description>
+                     <bitOffset>15</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>LSDEV</name>
+                     <description>Low-speed device</description>
+                     <bitOffset>17</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>EPTYP</name>
+                     <description>Endpoint type</description>
+                     <bitOffset>18</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>MC</name>
+                     <description>Multi Count (MC) / Error Count               (EC)</description>
+                     <bitOffset>20</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>DAD</name>
+                     <description>Device address</description>
+                     <bitOffset>22</bitOffset>
+                     <bitWidth>7</bitWidth>
+                  </field>
+                  <field>
+                     <name>ODDFRM</name>
+                     <description>Odd frame</description>
+                     <bitOffset>29</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CHDIS</name>
+                     <description>Channel disable</description>
+                     <bitOffset>30</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CHENA</name>
+                     <description>Channel enable</description>
+                     <bitOffset>31</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_HS_HCCHAR4</name>
+               <displayName>OTG_HS_HCCHAR4</displayName>
+               <description>OTG_HS host channel-4 characteristics           register</description>
+               <addressOffset>0x180</addressOffset>
+               <size>32</size>
+               <access>read-write</access>
+               <resetValue>0x0</resetValue>
+               <fields>
+                  <field>
+                     <name>MPSIZ</name>
+                     <description>Maximum packet size</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>11</bitWidth>
+                  </field>
+                  <field>
+                     <name>EPNUM</name>
+                     <description>Endpoint number</description>
+                     <bitOffset>11</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+                  <field>
+                     <name>EPDIR</name>
+                     <description>Endpoint direction</description>
+                     <bitOffset>15</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>LSDEV</name>
+                     <description>Low-speed device</description>
+                     <bitOffset>17</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>EPTYP</name>
+                     <description>Endpoint type</description>
+                     <bitOffset>18</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>MC</name>
+                     <description>Multi Count (MC) / Error Count               (EC)</description>
+                     <bitOffset>20</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>DAD</name>
+                     <description>Device address</description>
+                     <bitOffset>22</bitOffset>
+                     <bitWidth>7</bitWidth>
+                  </field>
+                  <field>
+                     <name>ODDFRM</name>
+                     <description>Odd frame</description>
+                     <bitOffset>29</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CHDIS</name>
+                     <description>Channel disable</description>
+                     <bitOffset>30</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CHENA</name>
+                     <description>Channel enable</description>
+                     <bitOffset>31</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_HS_HCCHAR5</name>
+               <displayName>OTG_HS_HCCHAR5</displayName>
+               <description>OTG_HS host channel-5 characteristics           register</description>
+               <addressOffset>0x1A0</addressOffset>
+               <size>32</size>
+               <access>read-write</access>
+               <resetValue>0x0</resetValue>
+               <fields>
+                  <field>
+                     <name>MPSIZ</name>
+                     <description>Maximum packet size</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>11</bitWidth>
+                  </field>
+                  <field>
+                     <name>EPNUM</name>
+                     <description>Endpoint number</description>
+                     <bitOffset>11</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+                  <field>
+                     <name>EPDIR</name>
+                     <description>Endpoint direction</description>
+                     <bitOffset>15</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>LSDEV</name>
+                     <description>Low-speed device</description>
+                     <bitOffset>17</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>EPTYP</name>
+                     <description>Endpoint type</description>
+                     <bitOffset>18</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>MC</name>
+                     <description>Multi Count (MC) / Error Count               (EC)</description>
+                     <bitOffset>20</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>DAD</name>
+                     <description>Device address</description>
+                     <bitOffset>22</bitOffset>
+                     <bitWidth>7</bitWidth>
+                  </field>
+                  <field>
+                     <name>ODDFRM</name>
+                     <description>Odd frame</description>
+                     <bitOffset>29</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CHDIS</name>
+                     <description>Channel disable</description>
+                     <bitOffset>30</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CHENA</name>
+                     <description>Channel enable</description>
+                     <bitOffset>31</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_HS_HCCHAR6</name>
+               <displayName>OTG_HS_HCCHAR6</displayName>
+               <description>OTG_HS host channel-6 characteristics           register</description>
+               <addressOffset>0x1C0</addressOffset>
+               <size>32</size>
+               <access>read-write</access>
+               <resetValue>0x0</resetValue>
+               <fields>
+                  <field>
+                     <name>MPSIZ</name>
+                     <description>Maximum packet size</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>11</bitWidth>
+                  </field>
+                  <field>
+                     <name>EPNUM</name>
+                     <description>Endpoint number</description>
+                     <bitOffset>11</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+                  <field>
+                     <name>EPDIR</name>
+                     <description>Endpoint direction</description>
+                     <bitOffset>15</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>LSDEV</name>
+                     <description>Low-speed device</description>
+                     <bitOffset>17</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>EPTYP</name>
+                     <description>Endpoint type</description>
+                     <bitOffset>18</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>MC</name>
+                     <description>Multi Count (MC) / Error Count               (EC)</description>
+                     <bitOffset>20</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>DAD</name>
+                     <description>Device address</description>
+                     <bitOffset>22</bitOffset>
+                     <bitWidth>7</bitWidth>
+                  </field>
+                  <field>
+                     <name>ODDFRM</name>
+                     <description>Odd frame</description>
+                     <bitOffset>29</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CHDIS</name>
+                     <description>Channel disable</description>
+                     <bitOffset>30</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CHENA</name>
+                     <description>Channel enable</description>
+                     <bitOffset>31</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_HS_HCCHAR7</name>
+               <displayName>OTG_HS_HCCHAR7</displayName>
+               <description>OTG_HS host channel-7 characteristics           register</description>
+               <addressOffset>0x1E0</addressOffset>
+               <size>32</size>
+               <access>read-write</access>
+               <resetValue>0x0</resetValue>
+               <fields>
+                  <field>
+                     <name>MPSIZ</name>
+                     <description>Maximum packet size</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>11</bitWidth>
+                  </field>
+                  <field>
+                     <name>EPNUM</name>
+                     <description>Endpoint number</description>
+                     <bitOffset>11</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+                  <field>
+                     <name>EPDIR</name>
+                     <description>Endpoint direction</description>
+                     <bitOffset>15</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>LSDEV</name>
+                     <description>Low-speed device</description>
+                     <bitOffset>17</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>EPTYP</name>
+                     <description>Endpoint type</description>
+                     <bitOffset>18</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>MC</name>
+                     <description>Multi Count (MC) / Error Count               (EC)</description>
+                     <bitOffset>20</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>DAD</name>
+                     <description>Device address</description>
+                     <bitOffset>22</bitOffset>
+                     <bitWidth>7</bitWidth>
+                  </field>
+                  <field>
+                     <name>ODDFRM</name>
+                     <description>Odd frame</description>
+                     <bitOffset>29</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CHDIS</name>
+                     <description>Channel disable</description>
+                     <bitOffset>30</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CHENA</name>
+                     <description>Channel enable</description>
+                     <bitOffset>31</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_HS_HCCHAR8</name>
+               <displayName>OTG_HS_HCCHAR8</displayName>
+               <description>OTG_HS host channel-8 characteristics           register</description>
+               <addressOffset>0x200</addressOffset>
+               <size>32</size>
+               <access>read-write</access>
+               <resetValue>0x0</resetValue>
+               <fields>
+                  <field>
+                     <name>MPSIZ</name>
+                     <description>Maximum packet size</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>11</bitWidth>
+                  </field>
+                  <field>
+                     <name>EPNUM</name>
+                     <description>Endpoint number</description>
+                     <bitOffset>11</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+                  <field>
+                     <name>EPDIR</name>
+                     <description>Endpoint direction</description>
+                     <bitOffset>15</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>LSDEV</name>
+                     <description>Low-speed device</description>
+                     <bitOffset>17</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>EPTYP</name>
+                     <description>Endpoint type</description>
+                     <bitOffset>18</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>MC</name>
+                     <description>Multi Count (MC) / Error Count               (EC)</description>
+                     <bitOffset>20</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>DAD</name>
+                     <description>Device address</description>
+                     <bitOffset>22</bitOffset>
+                     <bitWidth>7</bitWidth>
+                  </field>
+                  <field>
+                     <name>ODDFRM</name>
+                     <description>Odd frame</description>
+                     <bitOffset>29</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CHDIS</name>
+                     <description>Channel disable</description>
+                     <bitOffset>30</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CHENA</name>
+                     <description>Channel enable</description>
+                     <bitOffset>31</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_HS_HCCHAR9</name>
+               <displayName>OTG_HS_HCCHAR9</displayName>
+               <description>OTG_HS host channel-9 characteristics           register</description>
+               <addressOffset>0x220</addressOffset>
+               <size>32</size>
+               <access>read-write</access>
+               <resetValue>0x0</resetValue>
+               <fields>
+                  <field>
+                     <name>MPSIZ</name>
+                     <description>Maximum packet size</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>11</bitWidth>
+                  </field>
+                  <field>
+                     <name>EPNUM</name>
+                     <description>Endpoint number</description>
+                     <bitOffset>11</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+                  <field>
+                     <name>EPDIR</name>
+                     <description>Endpoint direction</description>
+                     <bitOffset>15</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>LSDEV</name>
+                     <description>Low-speed device</description>
+                     <bitOffset>17</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>EPTYP</name>
+                     <description>Endpoint type</description>
+                     <bitOffset>18</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>MC</name>
+                     <description>Multi Count (MC) / Error Count               (EC)</description>
+                     <bitOffset>20</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>DAD</name>
+                     <description>Device address</description>
+                     <bitOffset>22</bitOffset>
+                     <bitWidth>7</bitWidth>
+                  </field>
+                  <field>
+                     <name>ODDFRM</name>
+                     <description>Odd frame</description>
+                     <bitOffset>29</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CHDIS</name>
+                     <description>Channel disable</description>
+                     <bitOffset>30</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CHENA</name>
+                     <description>Channel enable</description>
+                     <bitOffset>31</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_HS_HCCHAR10</name>
+               <displayName>OTG_HS_HCCHAR10</displayName>
+               <description>OTG_HS host channel-10 characteristics           register</description>
+               <addressOffset>0x240</addressOffset>
+               <size>32</size>
+               <access>read-write</access>
+               <resetValue>0x0</resetValue>
+               <fields>
+                  <field>
+                     <name>MPSIZ</name>
+                     <description>Maximum packet size</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>11</bitWidth>
+                  </field>
+                  <field>
+                     <name>EPNUM</name>
+                     <description>Endpoint number</description>
+                     <bitOffset>11</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+                  <field>
+                     <name>EPDIR</name>
+                     <description>Endpoint direction</description>
+                     <bitOffset>15</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>LSDEV</name>
+                     <description>Low-speed device</description>
+                     <bitOffset>17</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>EPTYP</name>
+                     <description>Endpoint type</description>
+                     <bitOffset>18</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>MC</name>
+                     <description>Multi Count (MC) / Error Count               (EC)</description>
+                     <bitOffset>20</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>DAD</name>
+                     <description>Device address</description>
+                     <bitOffset>22</bitOffset>
+                     <bitWidth>7</bitWidth>
+                  </field>
+                  <field>
+                     <name>ODDFRM</name>
+                     <description>Odd frame</description>
+                     <bitOffset>29</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CHDIS</name>
+                     <description>Channel disable</description>
+                     <bitOffset>30</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CHENA</name>
+                     <description>Channel enable</description>
+                     <bitOffset>31</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_HS_HCCHAR11</name>
+               <displayName>OTG_HS_HCCHAR11</displayName>
+               <description>OTG_HS host channel-11 characteristics           register</description>
+               <addressOffset>0x260</addressOffset>
+               <size>32</size>
+               <access>read-write</access>
+               <resetValue>0x0</resetValue>
+               <fields>
+                  <field>
+                     <name>MPSIZ</name>
+                     <description>Maximum packet size</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>11</bitWidth>
+                  </field>
+                  <field>
+                     <name>EPNUM</name>
+                     <description>Endpoint number</description>
+                     <bitOffset>11</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+                  <field>
+                     <name>EPDIR</name>
+                     <description>Endpoint direction</description>
+                     <bitOffset>15</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>LSDEV</name>
+                     <description>Low-speed device</description>
+                     <bitOffset>17</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>EPTYP</name>
+                     <description>Endpoint type</description>
+                     <bitOffset>18</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>MC</name>
+                     <description>Multi Count (MC) / Error Count               (EC)</description>
+                     <bitOffset>20</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>DAD</name>
+                     <description>Device address</description>
+                     <bitOffset>22</bitOffset>
+                     <bitWidth>7</bitWidth>
+                  </field>
+                  <field>
+                     <name>ODDFRM</name>
+                     <description>Odd frame</description>
+                     <bitOffset>29</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CHDIS</name>
+                     <description>Channel disable</description>
+                     <bitOffset>30</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CHENA</name>
+                     <description>Channel enable</description>
+                     <bitOffset>31</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_HS_HCSPLT0</name>
+               <displayName>OTG_HS_HCSPLT0</displayName>
+               <description>OTG_HS host channel-0 split control           register</description>
+               <addressOffset>0x104</addressOffset>
+               <size>32</size>
+               <access>read-write</access>
+               <resetValue>0x0</resetValue>
+               <fields>
+                  <field>
+                     <name>PRTADDR</name>
+                     <description>Port address</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>7</bitWidth>
+                  </field>
+                  <field>
+                     <name>HUBADDR</name>
+                     <description>Hub address</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>7</bitWidth>
+                  </field>
+                  <field>
+                     <name>XACTPOS</name>
+                     <description>XACTPOS</description>
+                     <bitOffset>14</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>COMPLSPLT</name>
+                     <description>Do complete split</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>SPLITEN</name>
+                     <description>Split enable</description>
+                     <bitOffset>31</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_HS_HCSPLT1</name>
+               <displayName>OTG_HS_HCSPLT1</displayName>
+               <description>OTG_HS host channel-1 split control           register</description>
+               <addressOffset>0x124</addressOffset>
+               <size>32</size>
+               <access>read-write</access>
+               <resetValue>0x0</resetValue>
+               <fields>
+                  <field>
+                     <name>PRTADDR</name>
+                     <description>Port address</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>7</bitWidth>
+                  </field>
+                  <field>
+                     <name>HUBADDR</name>
+                     <description>Hub address</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>7</bitWidth>
+                  </field>
+                  <field>
+                     <name>XACTPOS</name>
+                     <description>XACTPOS</description>
+                     <bitOffset>14</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>COMPLSPLT</name>
+                     <description>Do complete split</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>SPLITEN</name>
+                     <description>Split enable</description>
+                     <bitOffset>31</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_HS_HCSPLT2</name>
+               <displayName>OTG_HS_HCSPLT2</displayName>
+               <description>OTG_HS host channel-2 split control           register</description>
+               <addressOffset>0x144</addressOffset>
+               <size>32</size>
+               <access>read-write</access>
+               <resetValue>0x0</resetValue>
+               <fields>
+                  <field>
+                     <name>PRTADDR</name>
+                     <description>Port address</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>7</bitWidth>
+                  </field>
+                  <field>
+                     <name>HUBADDR</name>
+                     <description>Hub address</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>7</bitWidth>
+                  </field>
+                  <field>
+                     <name>XACTPOS</name>
+                     <description>XACTPOS</description>
+                     <bitOffset>14</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>COMPLSPLT</name>
+                     <description>Do complete split</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>SPLITEN</name>
+                     <description>Split enable</description>
+                     <bitOffset>31</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_HS_HCSPLT3</name>
+               <displayName>OTG_HS_HCSPLT3</displayName>
+               <description>OTG_HS host channel-3 split control           register</description>
+               <addressOffset>0x164</addressOffset>
+               <size>32</size>
+               <access>read-write</access>
+               <resetValue>0x0</resetValue>
+               <fields>
+                  <field>
+                     <name>PRTADDR</name>
+                     <description>Port address</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>7</bitWidth>
+                  </field>
+                  <field>
+                     <name>HUBADDR</name>
+                     <description>Hub address</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>7</bitWidth>
+                  </field>
+                  <field>
+                     <name>XACTPOS</name>
+                     <description>XACTPOS</description>
+                     <bitOffset>14</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>COMPLSPLT</name>
+                     <description>Do complete split</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>SPLITEN</name>
+                     <description>Split enable</description>
+                     <bitOffset>31</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_HS_HCSPLT4</name>
+               <displayName>OTG_HS_HCSPLT4</displayName>
+               <description>OTG_HS host channel-4 split control           register</description>
+               <addressOffset>0x184</addressOffset>
+               <size>32</size>
+               <access>read-write</access>
+               <resetValue>0x0</resetValue>
+               <fields>
+                  <field>
+                     <name>PRTADDR</name>
+                     <description>Port address</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>7</bitWidth>
+                  </field>
+                  <field>
+                     <name>HUBADDR</name>
+                     <description>Hub address</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>7</bitWidth>
+                  </field>
+                  <field>
+                     <name>XACTPOS</name>
+                     <description>XACTPOS</description>
+                     <bitOffset>14</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>COMPLSPLT</name>
+                     <description>Do complete split</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>SPLITEN</name>
+                     <description>Split enable</description>
+                     <bitOffset>31</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_HS_HCSPLT5</name>
+               <displayName>OTG_HS_HCSPLT5</displayName>
+               <description>OTG_HS host channel-5 split control           register</description>
+               <addressOffset>0x1A4</addressOffset>
+               <size>32</size>
+               <access>read-write</access>
+               <resetValue>0x0</resetValue>
+               <fields>
+                  <field>
+                     <name>PRTADDR</name>
+                     <description>Port address</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>7</bitWidth>
+                  </field>
+                  <field>
+                     <name>HUBADDR</name>
+                     <description>Hub address</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>7</bitWidth>
+                  </field>
+                  <field>
+                     <name>XACTPOS</name>
+                     <description>XACTPOS</description>
+                     <bitOffset>14</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>COMPLSPLT</name>
+                     <description>Do complete split</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>SPLITEN</name>
+                     <description>Split enable</description>
+                     <bitOffset>31</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_HS_HCSPLT6</name>
+               <displayName>OTG_HS_HCSPLT6</displayName>
+               <description>OTG_HS host channel-6 split control           register</description>
+               <addressOffset>0x1C4</addressOffset>
+               <size>32</size>
+               <access>read-write</access>
+               <resetValue>0x0</resetValue>
+               <fields>
+                  <field>
+                     <name>PRTADDR</name>
+                     <description>Port address</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>7</bitWidth>
+                  </field>
+                  <field>
+                     <name>HUBADDR</name>
+                     <description>Hub address</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>7</bitWidth>
+                  </field>
+                  <field>
+                     <name>XACTPOS</name>
+                     <description>XACTPOS</description>
+                     <bitOffset>14</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>COMPLSPLT</name>
+                     <description>Do complete split</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>SPLITEN</name>
+                     <description>Split enable</description>
+                     <bitOffset>31</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_HS_HCSPLT7</name>
+               <displayName>OTG_HS_HCSPLT7</displayName>
+               <description>OTG_HS host channel-7 split control           register</description>
+               <addressOffset>0x1E4</addressOffset>
+               <size>32</size>
+               <access>read-write</access>
+               <resetValue>0x0</resetValue>
+               <fields>
+                  <field>
+                     <name>PRTADDR</name>
+                     <description>Port address</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>7</bitWidth>
+                  </field>
+                  <field>
+                     <name>HUBADDR</name>
+                     <description>Hub address</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>7</bitWidth>
+                  </field>
+                  <field>
+                     <name>XACTPOS</name>
+                     <description>XACTPOS</description>
+                     <bitOffset>14</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>COMPLSPLT</name>
+                     <description>Do complete split</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>SPLITEN</name>
+                     <description>Split enable</description>
+                     <bitOffset>31</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_HS_HCSPLT8</name>
+               <displayName>OTG_HS_HCSPLT8</displayName>
+               <description>OTG_HS host channel-8 split control           register</description>
+               <addressOffset>0x204</addressOffset>
+               <size>32</size>
+               <access>read-write</access>
+               <resetValue>0x0</resetValue>
+               <fields>
+                  <field>
+                     <name>PRTADDR</name>
+                     <description>Port address</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>7</bitWidth>
+                  </field>
+                  <field>
+                     <name>HUBADDR</name>
+                     <description>Hub address</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>7</bitWidth>
+                  </field>
+                  <field>
+                     <name>XACTPOS</name>
+                     <description>XACTPOS</description>
+                     <bitOffset>14</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>COMPLSPLT</name>
+                     <description>Do complete split</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>SPLITEN</name>
+                     <description>Split enable</description>
+                     <bitOffset>31</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_HS_HCSPLT9</name>
+               <displayName>OTG_HS_HCSPLT9</displayName>
+               <description>OTG_HS host channel-9 split control           register</description>
+               <addressOffset>0x224</addressOffset>
+               <size>32</size>
+               <access>read-write</access>
+               <resetValue>0x0</resetValue>
+               <fields>
+                  <field>
+                     <name>PRTADDR</name>
+                     <description>Port address</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>7</bitWidth>
+                  </field>
+                  <field>
+                     <name>HUBADDR</name>
+                     <description>Hub address</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>7</bitWidth>
+                  </field>
+                  <field>
+                     <name>XACTPOS</name>
+                     <description>XACTPOS</description>
+                     <bitOffset>14</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>COMPLSPLT</name>
+                     <description>Do complete split</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>SPLITEN</name>
+                     <description>Split enable</description>
+                     <bitOffset>31</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_HS_HCSPLT10</name>
+               <displayName>OTG_HS_HCSPLT10</displayName>
+               <description>OTG_HS host channel-10 split control           register</description>
+               <addressOffset>0x244</addressOffset>
+               <size>32</size>
+               <access>read-write</access>
+               <resetValue>0x0</resetValue>
+               <fields>
+                  <field>
+                     <name>PRTADDR</name>
+                     <description>Port address</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>7</bitWidth>
+                  </field>
+                  <field>
+                     <name>HUBADDR</name>
+                     <description>Hub address</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>7</bitWidth>
+                  </field>
+                  <field>
+                     <name>XACTPOS</name>
+                     <description>XACTPOS</description>
+                     <bitOffset>14</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>COMPLSPLT</name>
+                     <description>Do complete split</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>SPLITEN</name>
+                     <description>Split enable</description>
+                     <bitOffset>31</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_HS_HCSPLT11</name>
+               <displayName>OTG_HS_HCSPLT11</displayName>
+               <description>OTG_HS host channel-11 split control           register</description>
+               <addressOffset>0x264</addressOffset>
+               <size>32</size>
+               <access>read-write</access>
+               <resetValue>0x0</resetValue>
+               <fields>
+                  <field>
+                     <name>PRTADDR</name>
+                     <description>Port address</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>7</bitWidth>
+                  </field>
+                  <field>
+                     <name>HUBADDR</name>
+                     <description>Hub address</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>7</bitWidth>
+                  </field>
+                  <field>
+                     <name>XACTPOS</name>
+                     <description>XACTPOS</description>
+                     <bitOffset>14</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>COMPLSPLT</name>
+                     <description>Do complete split</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>SPLITEN</name>
+                     <description>Split enable</description>
+                     <bitOffset>31</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_HS_HCINT0</name>
+               <displayName>OTG_HS_HCINT0</displayName>
+               <description>OTG_HS host channel-11 interrupt           register</description>
+               <addressOffset>0x108</addressOffset>
+               <size>32</size>
+               <access>read-write</access>
+               <resetValue>0x0</resetValue>
+               <fields>
+                  <field>
+                     <name>XFRC</name>
+                     <description>Transfer completed</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CHH</name>
+                     <description>Channel halted</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>AHBERR</name>
+                     <description>AHB error</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>STALL</name>
+                     <description>STALL response received               interrupt</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>NAK</name>
+                     <description>NAK response received               interrupt</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>ACK</name>
+                     <description>ACK response received/transmitted               interrupt</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>NYET</name>
+                     <description>Response received               interrupt</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TXERR</name>
+                     <description>Transaction error</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>BBERR</name>
+                     <description>Babble error</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FRMOR</name>
+                     <description>Frame overrun</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>DTERR</name>
+                     <description>Data toggle error</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_HS_HCINT1</name>
+               <displayName>OTG_HS_HCINT1</displayName>
+               <description>OTG_HS host channel-1 interrupt           register</description>
+               <addressOffset>0x128</addressOffset>
+               <size>32</size>
+               <access>read-write</access>
+               <resetValue>0x0</resetValue>
+               <fields>
+                  <field>
+                     <name>XFRC</name>
+                     <description>Transfer completed</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CHH</name>
+                     <description>Channel halted</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>AHBERR</name>
+                     <description>AHB error</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>STALL</name>
+                     <description>STALL response received               interrupt</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>NAK</name>
+                     <description>NAK response received               interrupt</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>ACK</name>
+                     <description>ACK response received/transmitted               interrupt</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>NYET</name>
+                     <description>Response received               interrupt</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TXERR</name>
+                     <description>Transaction error</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>BBERR</name>
+                     <description>Babble error</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FRMOR</name>
+                     <description>Frame overrun</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>DTERR</name>
+                     <description>Data toggle error</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_HS_HCINT2</name>
+               <displayName>OTG_HS_HCINT2</displayName>
+               <description>OTG_HS host channel-2 interrupt           register</description>
+               <addressOffset>0x148</addressOffset>
+               <size>32</size>
+               <access>read-write</access>
+               <resetValue>0x0</resetValue>
+               <fields>
+                  <field>
+                     <name>XFRC</name>
+                     <description>Transfer completed</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CHH</name>
+                     <description>Channel halted</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>AHBERR</name>
+                     <description>AHB error</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>STALL</name>
+                     <description>STALL response received               interrupt</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>NAK</name>
+                     <description>NAK response received               interrupt</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>ACK</name>
+                     <description>ACK response received/transmitted               interrupt</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>NYET</name>
+                     <description>Response received               interrupt</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TXERR</name>
+                     <description>Transaction error</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>BBERR</name>
+                     <description>Babble error</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FRMOR</name>
+                     <description>Frame overrun</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>DTERR</name>
+                     <description>Data toggle error</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_HS_HCINT3</name>
+               <displayName>OTG_HS_HCINT3</displayName>
+               <description>OTG_HS host channel-3 interrupt           register</description>
+               <addressOffset>0x168</addressOffset>
+               <size>32</size>
+               <access>read-write</access>
+               <resetValue>0x0</resetValue>
+               <fields>
+                  <field>
+                     <name>XFRC</name>
+                     <description>Transfer completed</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CHH</name>
+                     <description>Channel halted</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>AHBERR</name>
+                     <description>AHB error</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>STALL</name>
+                     <description>STALL response received               interrupt</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>NAK</name>
+                     <description>NAK response received               interrupt</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>ACK</name>
+                     <description>ACK response received/transmitted               interrupt</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>NYET</name>
+                     <description>Response received               interrupt</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TXERR</name>
+                     <description>Transaction error</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>BBERR</name>
+                     <description>Babble error</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FRMOR</name>
+                     <description>Frame overrun</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>DTERR</name>
+                     <description>Data toggle error</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_HS_HCINT4</name>
+               <displayName>OTG_HS_HCINT4</displayName>
+               <description>OTG_HS host channel-4 interrupt           register</description>
+               <addressOffset>0x188</addressOffset>
+               <size>32</size>
+               <access>read-write</access>
+               <resetValue>0x0</resetValue>
+               <fields>
+                  <field>
+                     <name>XFRC</name>
+                     <description>Transfer completed</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CHH</name>
+                     <description>Channel halted</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>AHBERR</name>
+                     <description>AHB error</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>STALL</name>
+                     <description>STALL response received               interrupt</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>NAK</name>
+                     <description>NAK response received               interrupt</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>ACK</name>
+                     <description>ACK response received/transmitted               interrupt</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>NYET</name>
+                     <description>Response received               interrupt</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TXERR</name>
+                     <description>Transaction error</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>BBERR</name>
+                     <description>Babble error</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FRMOR</name>
+                     <description>Frame overrun</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>DTERR</name>
+                     <description>Data toggle error</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_HS_HCINT5</name>
+               <displayName>OTG_HS_HCINT5</displayName>
+               <description>OTG_HS host channel-5 interrupt           register</description>
+               <addressOffset>0x1A8</addressOffset>
+               <size>32</size>
+               <access>read-write</access>
+               <resetValue>0x0</resetValue>
+               <fields>
+                  <field>
+                     <name>XFRC</name>
+                     <description>Transfer completed</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CHH</name>
+                     <description>Channel halted</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>AHBERR</name>
+                     <description>AHB error</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>STALL</name>
+                     <description>STALL response received               interrupt</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>NAK</name>
+                     <description>NAK response received               interrupt</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>ACK</name>
+                     <description>ACK response received/transmitted               interrupt</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>NYET</name>
+                     <description>Response received               interrupt</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TXERR</name>
+                     <description>Transaction error</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>BBERR</name>
+                     <description>Babble error</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FRMOR</name>
+                     <description>Frame overrun</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>DTERR</name>
+                     <description>Data toggle error</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_HS_HCINT6</name>
+               <displayName>OTG_HS_HCINT6</displayName>
+               <description>OTG_HS host channel-6 interrupt           register</description>
+               <addressOffset>0x1C8</addressOffset>
+               <size>32</size>
+               <access>read-write</access>
+               <resetValue>0x0</resetValue>
+               <fields>
+                  <field>
+                     <name>XFRC</name>
+                     <description>Transfer completed</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CHH</name>
+                     <description>Channel halted</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>AHBERR</name>
+                     <description>AHB error</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>STALL</name>
+                     <description>STALL response received               interrupt</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>NAK</name>
+                     <description>NAK response received               interrupt</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>ACK</name>
+                     <description>ACK response received/transmitted               interrupt</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>NYET</name>
+                     <description>Response received               interrupt</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TXERR</name>
+                     <description>Transaction error</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>BBERR</name>
+                     <description>Babble error</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FRMOR</name>
+                     <description>Frame overrun</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>DTERR</name>
+                     <description>Data toggle error</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_HS_HCINT7</name>
+               <displayName>OTG_HS_HCINT7</displayName>
+               <description>OTG_HS host channel-7 interrupt           register</description>
+               <addressOffset>0x1E8</addressOffset>
+               <size>32</size>
+               <access>read-write</access>
+               <resetValue>0x0</resetValue>
+               <fields>
+                  <field>
+                     <name>XFRC</name>
+                     <description>Transfer completed</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CHH</name>
+                     <description>Channel halted</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>AHBERR</name>
+                     <description>AHB error</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>STALL</name>
+                     <description>STALL response received               interrupt</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>NAK</name>
+                     <description>NAK response received               interrupt</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>ACK</name>
+                     <description>ACK response received/transmitted               interrupt</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>NYET</name>
+                     <description>Response received               interrupt</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TXERR</name>
+                     <description>Transaction error</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>BBERR</name>
+                     <description>Babble error</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FRMOR</name>
+                     <description>Frame overrun</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>DTERR</name>
+                     <description>Data toggle error</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_HS_HCINT8</name>
+               <displayName>OTG_HS_HCINT8</displayName>
+               <description>OTG_HS host channel-8 interrupt           register</description>
+               <addressOffset>0x208</addressOffset>
+               <size>32</size>
+               <access>read-write</access>
+               <resetValue>0x0</resetValue>
+               <fields>
+                  <field>
+                     <name>XFRC</name>
+                     <description>Transfer completed</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CHH</name>
+                     <description>Channel halted</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>AHBERR</name>
+                     <description>AHB error</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>STALL</name>
+                     <description>STALL response received               interrupt</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>NAK</name>
+                     <description>NAK response received               interrupt</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>ACK</name>
+                     <description>ACK response received/transmitted               interrupt</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>NYET</name>
+                     <description>Response received               interrupt</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TXERR</name>
+                     <description>Transaction error</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>BBERR</name>
+                     <description>Babble error</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FRMOR</name>
+                     <description>Frame overrun</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>DTERR</name>
+                     <description>Data toggle error</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_HS_HCINT9</name>
+               <displayName>OTG_HS_HCINT9</displayName>
+               <description>OTG_HS host channel-9 interrupt           register</description>
+               <addressOffset>0x228</addressOffset>
+               <size>32</size>
+               <access>read-write</access>
+               <resetValue>0x0</resetValue>
+               <fields>
+                  <field>
+                     <name>XFRC</name>
+                     <description>Transfer completed</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CHH</name>
+                     <description>Channel halted</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>AHBERR</name>
+                     <description>AHB error</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>STALL</name>
+                     <description>STALL response received               interrupt</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>NAK</name>
+                     <description>NAK response received               interrupt</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>ACK</name>
+                     <description>ACK response received/transmitted               interrupt</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>NYET</name>
+                     <description>Response received               interrupt</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TXERR</name>
+                     <description>Transaction error</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>BBERR</name>
+                     <description>Babble error</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FRMOR</name>
+                     <description>Frame overrun</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>DTERR</name>
+                     <description>Data toggle error</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_HS_HCINT10</name>
+               <displayName>OTG_HS_HCINT10</displayName>
+               <description>OTG_HS host channel-10 interrupt           register</description>
+               <addressOffset>0x248</addressOffset>
+               <size>32</size>
+               <access>read-write</access>
+               <resetValue>0x0</resetValue>
+               <fields>
+                  <field>
+                     <name>XFRC</name>
+                     <description>Transfer completed</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CHH</name>
+                     <description>Channel halted</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>AHBERR</name>
+                     <description>AHB error</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>STALL</name>
+                     <description>STALL response received               interrupt</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>NAK</name>
+                     <description>NAK response received               interrupt</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>ACK</name>
+                     <description>ACK response received/transmitted               interrupt</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>NYET</name>
+                     <description>Response received               interrupt</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TXERR</name>
+                     <description>Transaction error</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>BBERR</name>
+                     <description>Babble error</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FRMOR</name>
+                     <description>Frame overrun</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>DTERR</name>
+                     <description>Data toggle error</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_HS_HCINT11</name>
+               <displayName>OTG_HS_HCINT11</displayName>
+               <description>OTG_HS host channel-11 interrupt           register</description>
+               <addressOffset>0x268</addressOffset>
+               <size>32</size>
+               <access>read-write</access>
+               <resetValue>0x0</resetValue>
+               <fields>
+                  <field>
+                     <name>XFRC</name>
+                     <description>Transfer completed</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CHH</name>
+                     <description>Channel halted</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>AHBERR</name>
+                     <description>AHB error</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>STALL</name>
+                     <description>STALL response received               interrupt</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>NAK</name>
+                     <description>NAK response received               interrupt</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>ACK</name>
+                     <description>ACK response received/transmitted               interrupt</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>NYET</name>
+                     <description>Response received               interrupt</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TXERR</name>
+                     <description>Transaction error</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>BBERR</name>
+                     <description>Babble error</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FRMOR</name>
+                     <description>Frame overrun</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>DTERR</name>
+                     <description>Data toggle error</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_HS_HCINTMSK0</name>
+               <displayName>OTG_HS_HCINTMSK0</displayName>
+               <description>OTG_HS host channel-11 interrupt mask           register</description>
+               <addressOffset>0x10C</addressOffset>
+               <size>32</size>
+               <access>read-write</access>
+               <resetValue>0x0</resetValue>
+               <fields>
+                  <field>
+                     <name>XFRCM</name>
+                     <description>Transfer completed mask</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CHHM</name>
+                     <description>Channel halted mask</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>AHBERR</name>
+                     <description>AHB error</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>STALLM</name>
+                     <description>STALL response received interrupt               mask</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>NAKM</name>
+                     <description>NAK response received interrupt               mask</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>ACKM</name>
+                     <description>ACK response received/transmitted               interrupt mask</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>NYET</name>
+                     <description>response received interrupt               mask</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TXERRM</name>
+                     <description>Transaction error mask</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>BBERRM</name>
+                     <description>Babble error mask</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FRMORM</name>
+                     <description>Frame overrun mask</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>DTERRM</name>
+                     <description>Data toggle error mask</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_HS_HCINTMSK1</name>
+               <displayName>OTG_HS_HCINTMSK1</displayName>
+               <description>OTG_HS host channel-1 interrupt mask           register</description>
+               <addressOffset>0x12C</addressOffset>
+               <size>32</size>
+               <access>read-write</access>
+               <resetValue>0x0</resetValue>
+               <fields>
+                  <field>
+                     <name>XFRCM</name>
+                     <description>Transfer completed mask</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CHHM</name>
+                     <description>Channel halted mask</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>AHBERR</name>
+                     <description>AHB error</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>STALLM</name>
+                     <description>STALL response received interrupt               mask</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>NAKM</name>
+                     <description>NAK response received interrupt               mask</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>ACKM</name>
+                     <description>ACK response received/transmitted               interrupt mask</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>NYET</name>
+                     <description>response received interrupt               mask</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TXERRM</name>
+                     <description>Transaction error mask</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>BBERRM</name>
+                     <description>Babble error mask</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FRMORM</name>
+                     <description>Frame overrun mask</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>DTERRM</name>
+                     <description>Data toggle error mask</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_HS_HCINTMSK2</name>
+               <displayName>OTG_HS_HCINTMSK2</displayName>
+               <description>OTG_HS host channel-2 interrupt mask           register</description>
+               <addressOffset>0x14C</addressOffset>
+               <size>32</size>
+               <access>read-write</access>
+               <resetValue>0x0</resetValue>
+               <fields>
+                  <field>
+                     <name>XFRCM</name>
+                     <description>Transfer completed mask</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CHHM</name>
+                     <description>Channel halted mask</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>AHBERR</name>
+                     <description>AHB error</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>STALLM</name>
+                     <description>STALL response received interrupt               mask</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>NAKM</name>
+                     <description>NAK response received interrupt               mask</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>ACKM</name>
+                     <description>ACK response received/transmitted               interrupt mask</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>NYET</name>
+                     <description>response received interrupt               mask</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TXERRM</name>
+                     <description>Transaction error mask</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>BBERRM</name>
+                     <description>Babble error mask</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FRMORM</name>
+                     <description>Frame overrun mask</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>DTERRM</name>
+                     <description>Data toggle error mask</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_HS_HCINTMSK3</name>
+               <displayName>OTG_HS_HCINTMSK3</displayName>
+               <description>OTG_HS host channel-3 interrupt mask           register</description>
+               <addressOffset>0x16C</addressOffset>
+               <size>32</size>
+               <access>read-write</access>
+               <resetValue>0x0</resetValue>
+               <fields>
+                  <field>
+                     <name>XFRCM</name>
+                     <description>Transfer completed mask</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CHHM</name>
+                     <description>Channel halted mask</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>AHBERR</name>
+                     <description>AHB error</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>STALLM</name>
+                     <description>STALL response received interrupt               mask</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>NAKM</name>
+                     <description>NAK response received interrupt               mask</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>ACKM</name>
+                     <description>ACK response received/transmitted               interrupt mask</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>NYET</name>
+                     <description>response received interrupt               mask</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TXERRM</name>
+                     <description>Transaction error mask</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>BBERRM</name>
+                     <description>Babble error mask</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FRMORM</name>
+                     <description>Frame overrun mask</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>DTERRM</name>
+                     <description>Data toggle error mask</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_HS_HCINTMSK4</name>
+               <displayName>OTG_HS_HCINTMSK4</displayName>
+               <description>OTG_HS host channel-4 interrupt mask           register</description>
+               <addressOffset>0x18C</addressOffset>
+               <size>32</size>
+               <access>read-write</access>
+               <resetValue>0x0</resetValue>
+               <fields>
+                  <field>
+                     <name>XFRCM</name>
+                     <description>Transfer completed mask</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CHHM</name>
+                     <description>Channel halted mask</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>AHBERR</name>
+                     <description>AHB error</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>STALLM</name>
+                     <description>STALL response received interrupt               mask</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>NAKM</name>
+                     <description>NAK response received interrupt               mask</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>ACKM</name>
+                     <description>ACK response received/transmitted               interrupt mask</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>NYET</name>
+                     <description>response received interrupt               mask</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TXERRM</name>
+                     <description>Transaction error mask</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>BBERRM</name>
+                     <description>Babble error mask</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FRMORM</name>
+                     <description>Frame overrun mask</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>DTERRM</name>
+                     <description>Data toggle error mask</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_HS_HCINTMSK5</name>
+               <displayName>OTG_HS_HCINTMSK5</displayName>
+               <description>OTG_HS host channel-5 interrupt mask           register</description>
+               <addressOffset>0x1AC</addressOffset>
+               <size>32</size>
+               <access>read-write</access>
+               <resetValue>0x0</resetValue>
+               <fields>
+                  <field>
+                     <name>XFRCM</name>
+                     <description>Transfer completed mask</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CHHM</name>
+                     <description>Channel halted mask</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>AHBERR</name>
+                     <description>AHB error</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>STALLM</name>
+                     <description>STALL response received interrupt               mask</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>NAKM</name>
+                     <description>NAK response received interrupt               mask</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>ACKM</name>
+                     <description>ACK response received/transmitted               interrupt mask</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>NYET</name>
+                     <description>response received interrupt               mask</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TXERRM</name>
+                     <description>Transaction error mask</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>BBERRM</name>
+                     <description>Babble error mask</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FRMORM</name>
+                     <description>Frame overrun mask</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>DTERRM</name>
+                     <description>Data toggle error mask</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_HS_HCINTMSK6</name>
+               <displayName>OTG_HS_HCINTMSK6</displayName>
+               <description>OTG_HS host channel-6 interrupt mask           register</description>
+               <addressOffset>0x1CC</addressOffset>
+               <size>32</size>
+               <access>read-write</access>
+               <resetValue>0x0</resetValue>
+               <fields>
+                  <field>
+                     <name>XFRCM</name>
+                     <description>Transfer completed mask</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CHHM</name>
+                     <description>Channel halted mask</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>AHBERR</name>
+                     <description>AHB error</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>STALLM</name>
+                     <description>STALL response received interrupt               mask</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>NAKM</name>
+                     <description>NAK response received interrupt               mask</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>ACKM</name>
+                     <description>ACK response received/transmitted               interrupt mask</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>NYET</name>
+                     <description>response received interrupt               mask</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TXERRM</name>
+                     <description>Transaction error mask</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>BBERRM</name>
+                     <description>Babble error mask</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FRMORM</name>
+                     <description>Frame overrun mask</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>DTERRM</name>
+                     <description>Data toggle error mask</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_HS_HCINTMSK7</name>
+               <displayName>OTG_HS_HCINTMSK7</displayName>
+               <description>OTG_HS host channel-7 interrupt mask           register</description>
+               <addressOffset>0x1EC</addressOffset>
+               <size>32</size>
+               <access>read-write</access>
+               <resetValue>0x0</resetValue>
+               <fields>
+                  <field>
+                     <name>XFRCM</name>
+                     <description>Transfer completed mask</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CHHM</name>
+                     <description>Channel halted mask</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>AHBERR</name>
+                     <description>AHB error</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>STALLM</name>
+                     <description>STALL response received interrupt               mask</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>NAKM</name>
+                     <description>NAK response received interrupt               mask</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>ACKM</name>
+                     <description>ACK response received/transmitted               interrupt mask</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>NYET</name>
+                     <description>response received interrupt               mask</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TXERRM</name>
+                     <description>Transaction error mask</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>BBERRM</name>
+                     <description>Babble error mask</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FRMORM</name>
+                     <description>Frame overrun mask</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>DTERRM</name>
+                     <description>Data toggle error mask</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_HS_HCINTMSK8</name>
+               <displayName>OTG_HS_HCINTMSK8</displayName>
+               <description>OTG_HS host channel-8 interrupt mask           register</description>
+               <addressOffset>0x20C</addressOffset>
+               <size>32</size>
+               <access>read-write</access>
+               <resetValue>0x0</resetValue>
+               <fields>
+                  <field>
+                     <name>XFRCM</name>
+                     <description>Transfer completed mask</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CHHM</name>
+                     <description>Channel halted mask</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>AHBERR</name>
+                     <description>AHB error</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>STALLM</name>
+                     <description>STALL response received interrupt               mask</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>NAKM</name>
+                     <description>NAK response received interrupt               mask</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>ACKM</name>
+                     <description>ACK response received/transmitted               interrupt mask</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>NYET</name>
+                     <description>response received interrupt               mask</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TXERRM</name>
+                     <description>Transaction error mask</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>BBERRM</name>
+                     <description>Babble error mask</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FRMORM</name>
+                     <description>Frame overrun mask</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>DTERRM</name>
+                     <description>Data toggle error mask</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_HS_HCINTMSK9</name>
+               <displayName>OTG_HS_HCINTMSK9</displayName>
+               <description>OTG_HS host channel-9 interrupt mask           register</description>
+               <addressOffset>0x22C</addressOffset>
+               <size>32</size>
+               <access>read-write</access>
+               <resetValue>0x0</resetValue>
+               <fields>
+                  <field>
+                     <name>XFRCM</name>
+                     <description>Transfer completed mask</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CHHM</name>
+                     <description>Channel halted mask</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>AHBERR</name>
+                     <description>AHB error</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>STALLM</name>
+                     <description>STALL response received interrupt               mask</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>NAKM</name>
+                     <description>NAK response received interrupt               mask</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>ACKM</name>
+                     <description>ACK response received/transmitted               interrupt mask</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>NYET</name>
+                     <description>response received interrupt               mask</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TXERRM</name>
+                     <description>Transaction error mask</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>BBERRM</name>
+                     <description>Babble error mask</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FRMORM</name>
+                     <description>Frame overrun mask</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>DTERRM</name>
+                     <description>Data toggle error mask</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_HS_HCINTMSK10</name>
+               <displayName>OTG_HS_HCINTMSK10</displayName>
+               <description>OTG_HS host channel-10 interrupt mask           register</description>
+               <addressOffset>0x24C</addressOffset>
+               <size>32</size>
+               <access>read-write</access>
+               <resetValue>0x0</resetValue>
+               <fields>
+                  <field>
+                     <name>XFRCM</name>
+                     <description>Transfer completed mask</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CHHM</name>
+                     <description>Channel halted mask</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>AHBERR</name>
+                     <description>AHB error</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>STALLM</name>
+                     <description>STALL response received interrupt               mask</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>NAKM</name>
+                     <description>NAK response received interrupt               mask</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>ACKM</name>
+                     <description>ACK response received/transmitted               interrupt mask</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>NYET</name>
+                     <description>response received interrupt               mask</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TXERRM</name>
+                     <description>Transaction error mask</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>BBERRM</name>
+                     <description>Babble error mask</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FRMORM</name>
+                     <description>Frame overrun mask</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>DTERRM</name>
+                     <description>Data toggle error mask</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_HS_HCINTMSK11</name>
+               <displayName>OTG_HS_HCINTMSK11</displayName>
+               <description>OTG_HS host channel-11 interrupt mask           register</description>
+               <addressOffset>0x26C</addressOffset>
+               <size>32</size>
+               <access>read-write</access>
+               <resetValue>0x0</resetValue>
+               <fields>
+                  <field>
+                     <name>XFRCM</name>
+                     <description>Transfer completed mask</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CHHM</name>
+                     <description>Channel halted mask</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>AHBERR</name>
+                     <description>AHB error</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>STALLM</name>
+                     <description>STALL response received interrupt               mask</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>NAKM</name>
+                     <description>NAK response received interrupt               mask</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>ACKM</name>
+                     <description>ACK response received/transmitted               interrupt mask</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>NYET</name>
+                     <description>response received interrupt               mask</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TXERRM</name>
+                     <description>Transaction error mask</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>BBERRM</name>
+                     <description>Babble error mask</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FRMORM</name>
+                     <description>Frame overrun mask</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>DTERRM</name>
+                     <description>Data toggle error mask</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_HS_HCTSIZ0</name>
+               <displayName>OTG_HS_HCTSIZ0</displayName>
+               <description>OTG_HS host channel-11 transfer size           register</description>
+               <addressOffset>0x110</addressOffset>
+               <size>32</size>
+               <access>read-write</access>
+               <resetValue>0x0</resetValue>
+               <fields>
+                  <field>
+                     <name>XFRSIZ</name>
+                     <description>Transfer size</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>19</bitWidth>
+                  </field>
+                  <field>
+                     <name>PKTCNT</name>
+                     <description>Packet count</description>
+                     <bitOffset>19</bitOffset>
+                     <bitWidth>10</bitWidth>
+                  </field>
+                  <field>
+                     <name>DPID</name>
+                     <description>Data PID</description>
+                     <bitOffset>29</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_HS_HCTSIZ1</name>
+               <displayName>OTG_HS_HCTSIZ1</displayName>
+               <description>OTG_HS host channel-1 transfer size           register</description>
+               <addressOffset>0x130</addressOffset>
+               <size>32</size>
+               <access>read-write</access>
+               <resetValue>0x0</resetValue>
+               <fields>
+                  <field>
+                     <name>XFRSIZ</name>
+                     <description>Transfer size</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>19</bitWidth>
+                  </field>
+                  <field>
+                     <name>PKTCNT</name>
+                     <description>Packet count</description>
+                     <bitOffset>19</bitOffset>
+                     <bitWidth>10</bitWidth>
+                  </field>
+                  <field>
+                     <name>DPID</name>
+                     <description>Data PID</description>
+                     <bitOffset>29</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_HS_HCTSIZ2</name>
+               <displayName>OTG_HS_HCTSIZ2</displayName>
+               <description>OTG_HS host channel-2 transfer size           register</description>
+               <addressOffset>0x150</addressOffset>
+               <size>32</size>
+               <access>read-write</access>
+               <resetValue>0x0</resetValue>
+               <fields>
+                  <field>
+                     <name>XFRSIZ</name>
+                     <description>Transfer size</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>19</bitWidth>
+                  </field>
+                  <field>
+                     <name>PKTCNT</name>
+                     <description>Packet count</description>
+                     <bitOffset>19</bitOffset>
+                     <bitWidth>10</bitWidth>
+                  </field>
+                  <field>
+                     <name>DPID</name>
+                     <description>Data PID</description>
+                     <bitOffset>29</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_HS_HCTSIZ3</name>
+               <displayName>OTG_HS_HCTSIZ3</displayName>
+               <description>OTG_HS host channel-3 transfer size           register</description>
+               <addressOffset>0x170</addressOffset>
+               <size>32</size>
+               <access>read-write</access>
+               <resetValue>0x0</resetValue>
+               <fields>
+                  <field>
+                     <name>XFRSIZ</name>
+                     <description>Transfer size</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>19</bitWidth>
+                  </field>
+                  <field>
+                     <name>PKTCNT</name>
+                     <description>Packet count</description>
+                     <bitOffset>19</bitOffset>
+                     <bitWidth>10</bitWidth>
+                  </field>
+                  <field>
+                     <name>DPID</name>
+                     <description>Data PID</description>
+                     <bitOffset>29</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_HS_HCTSIZ4</name>
+               <displayName>OTG_HS_HCTSIZ4</displayName>
+               <description>OTG_HS host channel-4 transfer size           register</description>
+               <addressOffset>0x190</addressOffset>
+               <size>32</size>
+               <access>read-write</access>
+               <resetValue>0x0</resetValue>
+               <fields>
+                  <field>
+                     <name>XFRSIZ</name>
+                     <description>Transfer size</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>19</bitWidth>
+                  </field>
+                  <field>
+                     <name>PKTCNT</name>
+                     <description>Packet count</description>
+                     <bitOffset>19</bitOffset>
+                     <bitWidth>10</bitWidth>
+                  </field>
+                  <field>
+                     <name>DPID</name>
+                     <description>Data PID</description>
+                     <bitOffset>29</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_HS_HCTSIZ5</name>
+               <displayName>OTG_HS_HCTSIZ5</displayName>
+               <description>OTG_HS host channel-5 transfer size           register</description>
+               <addressOffset>0x1B0</addressOffset>
+               <size>32</size>
+               <access>read-write</access>
+               <resetValue>0x0</resetValue>
+               <fields>
+                  <field>
+                     <name>XFRSIZ</name>
+                     <description>Transfer size</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>19</bitWidth>
+                  </field>
+                  <field>
+                     <name>PKTCNT</name>
+                     <description>Packet count</description>
+                     <bitOffset>19</bitOffset>
+                     <bitWidth>10</bitWidth>
+                  </field>
+                  <field>
+                     <name>DPID</name>
+                     <description>Data PID</description>
+                     <bitOffset>29</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_HS_HCTSIZ6</name>
+               <displayName>OTG_HS_HCTSIZ6</displayName>
+               <description>OTG_HS host channel-6 transfer size           register</description>
+               <addressOffset>0x1D0</addressOffset>
+               <size>32</size>
+               <access>read-write</access>
+               <resetValue>0x0</resetValue>
+               <fields>
+                  <field>
+                     <name>XFRSIZ</name>
+                     <description>Transfer size</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>19</bitWidth>
+                  </field>
+                  <field>
+                     <name>PKTCNT</name>
+                     <description>Packet count</description>
+                     <bitOffset>19</bitOffset>
+                     <bitWidth>10</bitWidth>
+                  </field>
+                  <field>
+                     <name>DPID</name>
+                     <description>Data PID</description>
+                     <bitOffset>29</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_HS_HCTSIZ7</name>
+               <displayName>OTG_HS_HCTSIZ7</displayName>
+               <description>OTG_HS host channel-7 transfer size           register</description>
+               <addressOffset>0x1F0</addressOffset>
+               <size>32</size>
+               <access>read-write</access>
+               <resetValue>0x0</resetValue>
+               <fields>
+                  <field>
+                     <name>XFRSIZ</name>
+                     <description>Transfer size</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>19</bitWidth>
+                  </field>
+                  <field>
+                     <name>PKTCNT</name>
+                     <description>Packet count</description>
+                     <bitOffset>19</bitOffset>
+                     <bitWidth>10</bitWidth>
+                  </field>
+                  <field>
+                     <name>DPID</name>
+                     <description>Data PID</description>
+                     <bitOffset>29</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_HS_HCTSIZ8</name>
+               <displayName>OTG_HS_HCTSIZ8</displayName>
+               <description>OTG_HS host channel-8 transfer size           register</description>
+               <addressOffset>0x210</addressOffset>
+               <size>32</size>
+               <access>read-write</access>
+               <resetValue>0x0</resetValue>
+               <fields>
+                  <field>
+                     <name>XFRSIZ</name>
+                     <description>Transfer size</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>19</bitWidth>
+                  </field>
+                  <field>
+                     <name>PKTCNT</name>
+                     <description>Packet count</description>
+                     <bitOffset>19</bitOffset>
+                     <bitWidth>10</bitWidth>
+                  </field>
+                  <field>
+                     <name>DPID</name>
+                     <description>Data PID</description>
+                     <bitOffset>29</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_HS_HCTSIZ9</name>
+               <displayName>OTG_HS_HCTSIZ9</displayName>
+               <description>OTG_HS host channel-9 transfer size           register</description>
+               <addressOffset>0x230</addressOffset>
+               <size>32</size>
+               <access>read-write</access>
+               <resetValue>0x0</resetValue>
+               <fields>
+                  <field>
+                     <name>XFRSIZ</name>
+                     <description>Transfer size</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>19</bitWidth>
+                  </field>
+                  <field>
+                     <name>PKTCNT</name>
+                     <description>Packet count</description>
+                     <bitOffset>19</bitOffset>
+                     <bitWidth>10</bitWidth>
+                  </field>
+                  <field>
+                     <name>DPID</name>
+                     <description>Data PID</description>
+                     <bitOffset>29</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_HS_HCTSIZ10</name>
+               <displayName>OTG_HS_HCTSIZ10</displayName>
+               <description>OTG_HS host channel-10 transfer size           register</description>
+               <addressOffset>0x250</addressOffset>
+               <size>32</size>
+               <access>read-write</access>
+               <resetValue>0x0</resetValue>
+               <fields>
+                  <field>
+                     <name>XFRSIZ</name>
+                     <description>Transfer size</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>19</bitWidth>
+                  </field>
+                  <field>
+                     <name>PKTCNT</name>
+                     <description>Packet count</description>
+                     <bitOffset>19</bitOffset>
+                     <bitWidth>10</bitWidth>
+                  </field>
+                  <field>
+                     <name>DPID</name>
+                     <description>Data PID</description>
+                     <bitOffset>29</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_HS_HCTSIZ11</name>
+               <displayName>OTG_HS_HCTSIZ11</displayName>
+               <description>OTG_HS host channel-11 transfer size           register</description>
+               <addressOffset>0x270</addressOffset>
+               <size>32</size>
+               <access>read-write</access>
+               <resetValue>0x0</resetValue>
+               <fields>
+                  <field>
+                     <name>XFRSIZ</name>
+                     <description>Transfer size</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>19</bitWidth>
+                  </field>
+                  <field>
+                     <name>PKTCNT</name>
+                     <description>Packet count</description>
+                     <bitOffset>19</bitOffset>
+                     <bitWidth>10</bitWidth>
+                  </field>
+                  <field>
+                     <name>DPID</name>
+                     <description>Data PID</description>
+                     <bitOffset>29</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_HS_HCDMA0</name>
+               <displayName>OTG_HS_HCDMA0</displayName>
+               <description>OTG_HS host channel-0 DMA address           register</description>
+               <addressOffset>0x114</addressOffset>
+               <size>32</size>
+               <access>read-write</access>
+               <resetValue>0x0</resetValue>
+               <fields>
+                  <field>
+                     <name>DMAADDR</name>
+                     <description>DMA address</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_HS_HCDMA1</name>
+               <displayName>OTG_HS_HCDMA1</displayName>
+               <description>OTG_HS host channel-1 DMA address           register</description>
+               <addressOffset>0x134</addressOffset>
+               <size>32</size>
+               <access>read-write</access>
+               <resetValue>0x0</resetValue>
+               <fields>
+                  <field>
+                     <name>DMAADDR</name>
+                     <description>DMA address</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_HS_HCDMA2</name>
+               <displayName>OTG_HS_HCDMA2</displayName>
+               <description>OTG_HS host channel-2 DMA address           register</description>
+               <addressOffset>0x154</addressOffset>
+               <size>32</size>
+               <access>read-write</access>
+               <resetValue>0x0</resetValue>
+               <fields>
+                  <field>
+                     <name>DMAADDR</name>
+                     <description>DMA address</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_HS_HCDMA3</name>
+               <displayName>OTG_HS_HCDMA3</displayName>
+               <description>OTG_HS host channel-3 DMA address           register</description>
+               <addressOffset>0x174</addressOffset>
+               <size>32</size>
+               <access>read-write</access>
+               <resetValue>0x0</resetValue>
+               <fields>
+                  <field>
+                     <name>DMAADDR</name>
+                     <description>DMA address</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_HS_HCDMA4</name>
+               <displayName>OTG_HS_HCDMA4</displayName>
+               <description>OTG_HS host channel-4 DMA address           register</description>
+               <addressOffset>0x194</addressOffset>
+               <size>32</size>
+               <access>read-write</access>
+               <resetValue>0x0</resetValue>
+               <fields>
+                  <field>
+                     <name>DMAADDR</name>
+                     <description>DMA address</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_HS_HCDMA5</name>
+               <displayName>OTG_HS_HCDMA5</displayName>
+               <description>OTG_HS host channel-5 DMA address           register</description>
+               <addressOffset>0x1B4</addressOffset>
+               <size>32</size>
+               <access>read-write</access>
+               <resetValue>0x0</resetValue>
+               <fields>
+                  <field>
+                     <name>DMAADDR</name>
+                     <description>DMA address</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_HS_HCDMA6</name>
+               <displayName>OTG_HS_HCDMA6</displayName>
+               <description>OTG_HS host channel-6 DMA address           register</description>
+               <addressOffset>0x1D4</addressOffset>
+               <size>32</size>
+               <access>read-write</access>
+               <resetValue>0x0</resetValue>
+               <fields>
+                  <field>
+                     <name>DMAADDR</name>
+                     <description>DMA address</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_HS_HCDMA7</name>
+               <displayName>OTG_HS_HCDMA7</displayName>
+               <description>OTG_HS host channel-7 DMA address           register</description>
+               <addressOffset>0x1F4</addressOffset>
+               <size>32</size>
+               <access>read-write</access>
+               <resetValue>0x0</resetValue>
+               <fields>
+                  <field>
+                     <name>DMAADDR</name>
+                     <description>DMA address</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_HS_HCDMA8</name>
+               <displayName>OTG_HS_HCDMA8</displayName>
+               <description>OTG_HS host channel-8 DMA address           register</description>
+               <addressOffset>0x214</addressOffset>
+               <size>32</size>
+               <access>read-write</access>
+               <resetValue>0x0</resetValue>
+               <fields>
+                  <field>
+                     <name>DMAADDR</name>
+                     <description>DMA address</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_HS_HCDMA9</name>
+               <displayName>OTG_HS_HCDMA9</displayName>
+               <description>OTG_HS host channel-9 DMA address           register</description>
+               <addressOffset>0x234</addressOffset>
+               <size>32</size>
+               <access>read-write</access>
+               <resetValue>0x0</resetValue>
+               <fields>
+                  <field>
+                     <name>DMAADDR</name>
+                     <description>DMA address</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_HS_HCDMA10</name>
+               <displayName>OTG_HS_HCDMA10</displayName>
+               <description>OTG_HS host channel-10 DMA address           register</description>
+               <addressOffset>0x254</addressOffset>
+               <size>32</size>
+               <access>read-write</access>
+               <resetValue>0x0</resetValue>
+               <fields>
+                  <field>
+                     <name>DMAADDR</name>
+                     <description>DMA address</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_HS_HCDMA11</name>
+               <displayName>OTG_HS_HCDMA11</displayName>
+               <description>OTG_HS host channel-11 DMA address           register</description>
+               <addressOffset>0x274</addressOffset>
+               <size>32</size>
+               <access>read-write</access>
+               <resetValue>0x0</resetValue>
+               <fields>
+                  <field>
+                     <name>DMAADDR</name>
+                     <description>DMA address</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_HS_HCCHAR12</name>
+               <displayName>OTG_HS_HCCHAR12</displayName>
+               <description>OTG_HS host channel-12 characteristics           register</description>
+               <addressOffset>0x278</addressOffset>
+               <size>32</size>
+               <access>read-write</access>
+               <resetValue>0x0</resetValue>
+               <fields>
+                  <field>
+                     <name>MPSIZ</name>
+                     <description>Maximum packet size</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>11</bitWidth>
+                  </field>
+                  <field>
+                     <name>EPNUM</name>
+                     <description>Endpoint number</description>
+                     <bitOffset>11</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+                  <field>
+                     <name>EPDIR</name>
+                     <description>Endpoint direction</description>
+                     <bitOffset>15</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>LSDEV</name>
+                     <description>Low-speed device</description>
+                     <bitOffset>17</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>EPTYP</name>
+                     <description>Endpoint type</description>
+                     <bitOffset>18</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>MC</name>
+                     <description>Multi Count (MC) / Error Count               (EC)</description>
+                     <bitOffset>20</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>DAD</name>
+                     <description>Device address</description>
+                     <bitOffset>22</bitOffset>
+                     <bitWidth>7</bitWidth>
+                  </field>
+                  <field>
+                     <name>ODDFRM</name>
+                     <description>Odd frame</description>
+                     <bitOffset>29</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CHDIS</name>
+                     <description>Channel disable</description>
+                     <bitOffset>30</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CHENA</name>
+                     <description>Channel enable</description>
+                     <bitOffset>31</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_HS_HCSPLT12</name>
+               <displayName>OTG_HS_HCSPLT12</displayName>
+               <description>OTG_HS host channel-12 split control           register</description>
+               <addressOffset>0x27C</addressOffset>
+               <size>32</size>
+               <access>read-write</access>
+               <resetValue>0x0</resetValue>
+               <fields>
+                  <field>
+                     <name>PRTADDR</name>
+                     <description>Port address</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>7</bitWidth>
+                  </field>
+                  <field>
+                     <name>HUBADDR</name>
+                     <description>Hub address</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>7</bitWidth>
+                  </field>
+                  <field>
+                     <name>XACTPOS</name>
+                     <description>XACTPOS</description>
+                     <bitOffset>14</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>COMPLSPLT</name>
+                     <description>Do complete split</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>SPLITEN</name>
+                     <description>Split enable</description>
+                     <bitOffset>31</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_HS_HCINT12</name>
+               <displayName>OTG_HS_HCINT12</displayName>
+               <description>OTG_HS host channel-12 interrupt           register</description>
+               <addressOffset>0x280</addressOffset>
+               <size>32</size>
+               <access>read-write</access>
+               <resetValue>0x0</resetValue>
+               <fields>
+                  <field>
+                     <name>XFRC</name>
+                     <description>Transfer completed</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CHH</name>
+                     <description>Channel halted</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>AHBERR</name>
+                     <description>AHB error</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>STALL</name>
+                     <description>STALL response received               interrupt</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>NAK</name>
+                     <description>NAK response received               interrupt</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>ACK</name>
+                     <description>ACK response received/transmitted               interrupt</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>NYET</name>
+                     <description>Response received               interrupt</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TXERR</name>
+                     <description>Transaction error</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>BBERR</name>
+                     <description>Babble error</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FRMOR</name>
+                     <description>Frame overrun</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>DTERR</name>
+                     <description>Data toggle error</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_HS_HCINTMSK12</name>
+               <displayName>OTG_HS_HCINTMSK12</displayName>
+               <description>OTG_HS host channel-12 interrupt mask           register</description>
+               <addressOffset>0x284</addressOffset>
+               <size>32</size>
+               <access>read-write</access>
+               <resetValue>0x0</resetValue>
+               <fields>
+                  <field>
+                     <name>XFRCM</name>
+                     <description>Transfer completed mask</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CHHM</name>
+                     <description>Channel halted mask</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>AHBERR</name>
+                     <description>AHB error</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>STALLM</name>
+                     <description>STALL response received interrupt               mask</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>NAKM</name>
+                     <description>NAK response received interrupt               mask</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>ACKM</name>
+                     <description>ACK response received/transmitted               interrupt mask</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>NYET</name>
+                     <description>Response received               interrupt</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TXERRM</name>
+                     <description>Transaction error</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>BBERRM</name>
+                     <description>Babble error</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FRMORM</name>
+                     <description>Frame overrun mask</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>DTERRM</name>
+                     <description>Data toggle error mask</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_HS_HCTSIZ12</name>
+               <displayName>OTG_HS_HCTSIZ12</displayName>
+               <description>OTG_HS host channel-12 transfer size           register</description>
+               <addressOffset>0x288</addressOffset>
+               <size>32</size>
+               <access>read-write</access>
+               <resetValue>0x0</resetValue>
+               <fields>
+                  <field>
+                     <name>XFRSIZ</name>
+                     <description>Transfer size</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>19</bitWidth>
+                  </field>
+                  <field>
+                     <name>PKTCNT</name>
+                     <description>Packet count</description>
+                     <bitOffset>19</bitOffset>
+                     <bitWidth>10</bitWidth>
+                  </field>
+                  <field>
+                     <name>DPID</name>
+                     <description>Data PID</description>
+                     <bitOffset>29</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_HS_HCDMA12</name>
+               <displayName>OTG_HS_HCDMA12</displayName>
+               <description>OTG_HS host channel-12 DMA address           register</description>
+               <addressOffset>0x28C</addressOffset>
+               <size>32</size>
+               <access>read-write</access>
+               <resetValue>0x0</resetValue>
+               <fields>
+                  <field>
+                     <name>DMAADDR</name>
+                     <description>DMA address</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_HS_HCCHAR13</name>
+               <displayName>OTG_HS_HCCHAR13</displayName>
+               <description>OTG_HS host channel-13 characteristics           register</description>
+               <addressOffset>0x290</addressOffset>
+               <size>32</size>
+               <access>read-write</access>
+               <resetValue>0x0</resetValue>
+               <fields>
+                  <field>
+                     <name>MPSIZ</name>
+                     <description>Maximum packet size</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>11</bitWidth>
+                  </field>
+                  <field>
+                     <name>EPNUM</name>
+                     <description>Endpoint number</description>
+                     <bitOffset>11</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+                  <field>
+                     <name>EPDIR</name>
+                     <description>Endpoint direction</description>
+                     <bitOffset>15</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>LSDEV</name>
+                     <description>Low-speed device</description>
+                     <bitOffset>17</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>EPTYP</name>
+                     <description>Endpoint type</description>
+                     <bitOffset>18</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>MC</name>
+                     <description>Multi Count (MC) / Error Count               (EC)</description>
+                     <bitOffset>20</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>DAD</name>
+                     <description>Device address</description>
+                     <bitOffset>22</bitOffset>
+                     <bitWidth>7</bitWidth>
+                  </field>
+                  <field>
+                     <name>ODDFRM</name>
+                     <description>Odd frame</description>
+                     <bitOffset>29</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CHDIS</name>
+                     <description>Channel disable</description>
+                     <bitOffset>30</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CHENA</name>
+                     <description>Channel enable</description>
+                     <bitOffset>31</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_HS_HCSPLT13</name>
+               <displayName>OTG_HS_HCSPLT13</displayName>
+               <description>OTG_HS host channel-13 split control           register</description>
+               <addressOffset>0x294</addressOffset>
+               <size>32</size>
+               <access>read-write</access>
+               <resetValue>0x0</resetValue>
+               <fields>
+                  <field>
+                     <name>PRTADDR</name>
+                     <description>Port address</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>7</bitWidth>
+                  </field>
+                  <field>
+                     <name>HUBADDR</name>
+                     <description>Hub address</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>7</bitWidth>
+                  </field>
+                  <field>
+                     <name>XACTPOS</name>
+                     <description>XACTPOS</description>
+                     <bitOffset>14</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>COMPLSPLT</name>
+                     <description>Do complete split</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>SPLITEN</name>
+                     <description>Split enable</description>
+                     <bitOffset>31</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_HS_HCINT13</name>
+               <displayName>OTG_HS_HCINT13</displayName>
+               <description>OTG_HS host channel-13 interrupt           register</description>
+               <addressOffset>0x298</addressOffset>
+               <size>32</size>
+               <access>read-write</access>
+               <resetValue>0x0</resetValue>
+               <fields>
+                  <field>
+                     <name>XFRC</name>
+                     <description>Transfer completed</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CHH</name>
+                     <description>Channel halted</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>AHBERR</name>
+                     <description>AHB error</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>STALL</name>
+                     <description>STALL response received               interrupt</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>NAK</name>
+                     <description>NAK response received               interrupt</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>ACK</name>
+                     <description>ACK response received/transmitted               interrupt</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>NYET</name>
+                     <description>Response received               interrupt</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TXERR</name>
+                     <description>Transaction error</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>BBERR</name>
+                     <description>Babble error</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FRMOR</name>
+                     <description>Frame overrun</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>DTERR</name>
+                     <description>Data toggle error</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_HS_HCINTMSK13</name>
+               <displayName>OTG_HS_HCINTMSK13</displayName>
+               <description>OTG_HS host channel-13 interrupt mask           register</description>
+               <addressOffset>0x29C</addressOffset>
+               <size>32</size>
+               <access>read-write</access>
+               <resetValue>0x0</resetValue>
+               <fields>
+                  <field>
+                     <name>XFRCM</name>
+                     <description>Transfer completed mask</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CHHM</name>
+                     <description>Channel halted mask</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>AHBERR</name>
+                     <description>AHB error</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>STALLM</name>
+                     <description>STALLM response received interrupt               mask</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>NAKM</name>
+                     <description>NAK response received interrupt               mask</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>ACKM</name>
+                     <description>ACK response received/transmitted               interrupt mask</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>NYET</name>
+                     <description>Response received               interrupt</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TXERRM</name>
+                     <description>Transaction error</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>BBERRM</name>
+                     <description>Babble error</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FRMORM</name>
+                     <description>Frame overrun mask</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>DTERRM</name>
+                     <description>Data toggle error mask</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_HS_HCTSIZ13</name>
+               <displayName>OTG_HS_HCTSIZ13</displayName>
+               <description>OTG_HS host channel-13 transfer size           register</description>
+               <addressOffset>0x2A0</addressOffset>
+               <size>32</size>
+               <access>read-write</access>
+               <resetValue>0x0</resetValue>
+               <fields>
+                  <field>
+                     <name>XFRSIZ</name>
+                     <description>Transfer size</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>19</bitWidth>
+                  </field>
+                  <field>
+                     <name>PKTCNT</name>
+                     <description>Packet count</description>
+                     <bitOffset>19</bitOffset>
+                     <bitWidth>10</bitWidth>
+                  </field>
+                  <field>
+                     <name>DPID</name>
+                     <description>Data PID</description>
+                     <bitOffset>29</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_HS_HCDMA13</name>
+               <displayName>OTG_HS_HCDMA13</displayName>
+               <description>OTG_HS host channel-13 DMA address           register</description>
+               <addressOffset>0x2A4</addressOffset>
+               <size>32</size>
+               <access>read-write</access>
+               <resetValue>0x0</resetValue>
+               <fields>
+                  <field>
+                     <name>DMAADDR</name>
+                     <description>DMA address</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_HS_HCCHAR14</name>
+               <displayName>OTG_HS_HCCHAR14</displayName>
+               <description>OTG_HS host channel-14 characteristics           register</description>
+               <addressOffset>0x2A8</addressOffset>
+               <size>32</size>
+               <access>read-write</access>
+               <resetValue>0x0</resetValue>
+               <fields>
+                  <field>
+                     <name>MPSIZ</name>
+                     <description>Maximum packet size</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>11</bitWidth>
+                  </field>
+                  <field>
+                     <name>EPNUM</name>
+                     <description>Endpoint number</description>
+                     <bitOffset>11</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+                  <field>
+                     <name>EPDIR</name>
+                     <description>Endpoint direction</description>
+                     <bitOffset>15</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>LSDEV</name>
+                     <description>Low-speed device</description>
+                     <bitOffset>17</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>EPTYP</name>
+                     <description>Endpoint type</description>
+                     <bitOffset>18</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>MC</name>
+                     <description>Multi Count (MC) / Error Count               (EC)</description>
+                     <bitOffset>20</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>DAD</name>
+                     <description>Device address</description>
+                     <bitOffset>22</bitOffset>
+                     <bitWidth>7</bitWidth>
+                  </field>
+                  <field>
+                     <name>ODDFRM</name>
+                     <description>Odd frame</description>
+                     <bitOffset>29</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CHDIS</name>
+                     <description>Channel disable</description>
+                     <bitOffset>30</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CHENA</name>
+                     <description>Channel enable</description>
+                     <bitOffset>31</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_HS_HCSPLT14</name>
+               <displayName>OTG_HS_HCSPLT14</displayName>
+               <description>OTG_HS host channel-14 split control           register</description>
+               <addressOffset>0x2AC</addressOffset>
+               <size>32</size>
+               <access>read-write</access>
+               <resetValue>0x0</resetValue>
+               <fields>
+                  <field>
+                     <name>PRTADDR</name>
+                     <description>Port address</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>7</bitWidth>
+                  </field>
+                  <field>
+                     <name>HUBADDR</name>
+                     <description>Hub address</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>7</bitWidth>
+                  </field>
+                  <field>
+                     <name>XACTPOS</name>
+                     <description>XACTPOS</description>
+                     <bitOffset>14</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>COMPLSPLT</name>
+                     <description>Do complete split</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>SPLITEN</name>
+                     <description>Split enable</description>
+                     <bitOffset>31</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_HS_HCINT14</name>
+               <displayName>OTG_HS_HCINT14</displayName>
+               <description>OTG_HS host channel-14 interrupt           register</description>
+               <addressOffset>0x2B0</addressOffset>
+               <size>32</size>
+               <access>read-write</access>
+               <resetValue>0x0</resetValue>
+               <fields>
+                  <field>
+                     <name>XFRC</name>
+                     <description>Transfer completed</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CHH</name>
+                     <description>Channel halted</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>AHBERR</name>
+                     <description>AHB error</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>STALL</name>
+                     <description>STALL response received               interrupt</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>NAK</name>
+                     <description>NAK response received               interrupt</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>ACK</name>
+                     <description>ACK response received/transmitted               interrupt</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>NYET</name>
+                     <description>Response received               interrupt</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TXERR</name>
+                     <description>Transaction error</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>BBERR</name>
+                     <description>Babble error</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FRMOR</name>
+                     <description>Frame overrun</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>DTERR</name>
+                     <description>Data toggle error</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_HS_HCINTMSK14</name>
+               <displayName>OTG_HS_HCINTMSK14</displayName>
+               <description>OTG_HS host channel-14 interrupt mask           register</description>
+               <addressOffset>0x2B4</addressOffset>
+               <size>32</size>
+               <access>read-write</access>
+               <resetValue>0x0</resetValue>
+               <fields>
+                  <field>
+                     <name>XFRCM</name>
+                     <description>Transfer completed mask</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CHHM</name>
+                     <description>Channel halted mask</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>AHBERR</name>
+                     <description>AHB error</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>STALLM</name>
+                     <description>STALL response received interrupt               mask</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>NAKM</name>
+                     <description>NAKM response received interrupt               mask</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>ACKM</name>
+                     <description>ACKM response received/transmitted               interrupt mask</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>NYET</name>
+                     <description>Response received               interrupt</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TXERRM</name>
+                     <description>Transaction error</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>BBERRM</name>
+                     <description>Babble error</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FRMORM</name>
+                     <description>Frame overrun mask</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>DTERRM</name>
+                     <description>Data toggle error mask</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_HS_HCTSIZ14</name>
+               <displayName>OTG_HS_HCTSIZ14</displayName>
+               <description>OTG_HS host channel-14 transfer size           register</description>
+               <addressOffset>0x2B8</addressOffset>
+               <size>32</size>
+               <access>read-write</access>
+               <resetValue>0x0</resetValue>
+               <fields>
+                  <field>
+                     <name>XFRSIZ</name>
+                     <description>Transfer size</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>19</bitWidth>
+                  </field>
+                  <field>
+                     <name>PKTCNT</name>
+                     <description>Packet count</description>
+                     <bitOffset>19</bitOffset>
+                     <bitWidth>10</bitWidth>
+                  </field>
+                  <field>
+                     <name>DPID</name>
+                     <description>Data PID</description>
+                     <bitOffset>29</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_HS_HCDMA14</name>
+               <displayName>OTG_HS_HCDMA14</displayName>
+               <description>OTG_HS host channel-14 DMA address           register</description>
+               <addressOffset>0x2BC</addressOffset>
+               <size>32</size>
+               <access>read-write</access>
+               <resetValue>0x0</resetValue>
+               <fields>
+                  <field>
+                     <name>DMAADDR</name>
+                     <description>DMA address</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_HS_HCCHAR15</name>
+               <displayName>OTG_HS_HCCHAR15</displayName>
+               <description>OTG_HS host channel-15 characteristics           register</description>
+               <addressOffset>0x2C0</addressOffset>
+               <size>32</size>
+               <access>read-write</access>
+               <resetValue>0x0</resetValue>
+               <fields>
+                  <field>
+                     <name>MPSIZ</name>
+                     <description>Maximum packet size</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>11</bitWidth>
+                  </field>
+                  <field>
+                     <name>EPNUM</name>
+                     <description>Endpoint number</description>
+                     <bitOffset>11</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+                  <field>
+                     <name>EPDIR</name>
+                     <description>Endpoint direction</description>
+                     <bitOffset>15</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>LSDEV</name>
+                     <description>Low-speed device</description>
+                     <bitOffset>17</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>EPTYP</name>
+                     <description>Endpoint type</description>
+                     <bitOffset>18</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>MC</name>
+                     <description>Multi Count (MC) / Error Count               (EC)</description>
+                     <bitOffset>20</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>DAD</name>
+                     <description>Device address</description>
+                     <bitOffset>22</bitOffset>
+                     <bitWidth>7</bitWidth>
+                  </field>
+                  <field>
+                     <name>ODDFRM</name>
+                     <description>Odd frame</description>
+                     <bitOffset>29</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CHDIS</name>
+                     <description>Channel disable</description>
+                     <bitOffset>30</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CHENA</name>
+                     <description>Channel enable</description>
+                     <bitOffset>31</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_HS_HCSPLT15</name>
+               <displayName>OTG_HS_HCSPLT15</displayName>
+               <description>OTG_HS host channel-15 split control           register</description>
+               <addressOffset>0x2C4</addressOffset>
+               <size>32</size>
+               <access>read-write</access>
+               <resetValue>0x0</resetValue>
+               <fields>
+                  <field>
+                     <name>PRTADDR</name>
+                     <description>Port address</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>7</bitWidth>
+                  </field>
+                  <field>
+                     <name>HUBADDR</name>
+                     <description>Hub address</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>7</bitWidth>
+                  </field>
+                  <field>
+                     <name>XACTPOS</name>
+                     <description>XACTPOS</description>
+                     <bitOffset>14</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>COMPLSPLT</name>
+                     <description>Do complete split</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>SPLITEN</name>
+                     <description>Split enable</description>
+                     <bitOffset>31</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_HS_HCINT15</name>
+               <displayName>OTG_HS_HCINT15</displayName>
+               <description>OTG_HS host channel-15 interrupt           register</description>
+               <addressOffset>0x2C8</addressOffset>
+               <size>32</size>
+               <access>read-write</access>
+               <resetValue>0x0</resetValue>
+               <fields>
+                  <field>
+                     <name>XFRC</name>
+                     <description>Transfer completed</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CHH</name>
+                     <description>Channel halted</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>AHBERR</name>
+                     <description>AHB error</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>STALL</name>
+                     <description>STALL response received               interrupt</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>NAK</name>
+                     <description>NAK response received               interrupt</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>ACK</name>
+                     <description>ACK response received/transmitted               interrupt</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>NYET</name>
+                     <description>Response received               interrupt</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TXERR</name>
+                     <description>Transaction error</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>BBERR</name>
+                     <description>Babble error</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FRMOR</name>
+                     <description>Frame overrun</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>DTERR</name>
+                     <description>Data toggle error</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_HS_HCINTMSK15</name>
+               <displayName>OTG_HS_HCINTMSK15</displayName>
+               <description>OTG_HS host channel-15 interrupt mask           register</description>
+               <addressOffset>0x2CC</addressOffset>
+               <size>32</size>
+               <access>read-write</access>
+               <resetValue>0x0</resetValue>
+               <fields>
+                  <field>
+                     <name>XFRCM</name>
+                     <description>Transfer completed mask</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CHHM</name>
+                     <description>Channel halted mask</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>AHBERR</name>
+                     <description>AHB error</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>STALL</name>
+                     <description>STALL response received interrupt               mask</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>NAKM</name>
+                     <description>NAK response received interrupt               mask</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>ACKM</name>
+                     <description>ACK response received/transmitted               interrupt mask</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>NYET</name>
+                     <description>Response received               interrupt</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TXERRM</name>
+                     <description>Transaction error</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>BBERRM</name>
+                     <description>Babble error</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FRMORM</name>
+                     <description>Frame overrun mask</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>DTERRM</name>
+                     <description>Data toggle error mask</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_HS_HCTSIZ15</name>
+               <displayName>OTG_HS_HCTSIZ15</displayName>
+               <description>OTG_HS host channel-15 transfer size           register</description>
+               <addressOffset>0x2D0</addressOffset>
+               <size>32</size>
+               <access>read-write</access>
+               <resetValue>0x0</resetValue>
+               <fields>
+                  <field>
+                     <name>XFRSIZ</name>
+                     <description>Transfer size</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>19</bitWidth>
+                  </field>
+                  <field>
+                     <name>PKTCNT</name>
+                     <description>Packet count</description>
+                     <bitOffset>19</bitOffset>
+                     <bitWidth>10</bitWidth>
+                  </field>
+                  <field>
+                     <name>DPID</name>
+                     <description>Data PID</description>
+                     <bitOffset>29</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_HS_HCDMA15</name>
+               <displayName>OTG_HS_HCDMA15</displayName>
+               <description>OTG_HS host channel-15 DMA address           register</description>
+               <addressOffset>0x2D4</addressOffset>
+               <size>32</size>
+               <access>read-write</access>
+               <resetValue>0x0</resetValue>
+               <fields>
+                  <field>
+                     <name>DMAADDR</name>
+                     <description>DMA address</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+         </registers>
+      </peripheral>
+      <peripheral>
+         <name>OTG_HS_DEVICE</name>
+         <description>USB on the go high speed</description>
+         <groupName>USB_OTG_HS</groupName>
+         <baseAddress>0x40040800</baseAddress>
+         <addressBlock>
+            <offset>0x0</offset>
+            <size>0x400</size>
+            <usage>registers</usage>
+         </addressBlock>
+         <registers>
+            <register>
+               <name>OTG_HS_DCFG</name>
+               <displayName>OTG_HS_DCFG</displayName>
+               <description>OTG_HS device configuration           register</description>
+               <addressOffset>0x0</addressOffset>
+               <size>32</size>
+               <access>read-write</access>
+               <resetValue>0x02200000</resetValue>
+               <fields>
+                  <field>
+                     <name>DSPD</name>
+                     <description>Device speed</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>NZLSOHSK</name>
+                     <description>Nonzero-length status OUT               handshake</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>DAD</name>
+                     <description>Device address</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>7</bitWidth>
+                  </field>
+                  <field>
+                     <name>PFIVL</name>
+                     <description>Periodic (micro)frame               interval</description>
+                     <bitOffset>11</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>PERSCHIVL</name>
+                     <description>Periodic scheduling               interval</description>
+                     <bitOffset>24</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_HS_DCTL</name>
+               <displayName>OTG_HS_DCTL</displayName>
+               <description>OTG_HS device control register</description>
+               <addressOffset>0x4</addressOffset>
+               <size>32</size>
+               <resetValue>0x0</resetValue>
+               <fields>
+                  <field>
+                     <name>RWUSIG</name>
+                     <description>Remote wakeup signaling</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>SDIS</name>
+                     <description>Soft disconnect</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>GINSTS</name>
+                     <description>Global IN NAK status</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-only</access>
+                  </field>
+                  <field>
+                     <name>GONSTS</name>
+                     <description>Global OUT NAK status</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-only</access>
+                  </field>
+                  <field>
+                     <name>TCTL</name>
+                     <description>Test control</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>3</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>SGINAK</name>
+                     <description>Set global IN NAK</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>write-only</access>
+                  </field>
+                  <field>
+                     <name>CGINAK</name>
+                     <description>Clear global IN NAK</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>write-only</access>
+                  </field>
+                  <field>
+                     <name>SGONAK</name>
+                     <description>Set global OUT NAK</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>write-only</access>
+                  </field>
+                  <field>
+                     <name>CGONAK</name>
+                     <description>Clear global OUT NAK</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>write-only</access>
+                  </field>
+                  <field>
+                     <name>POPRGDNE</name>
+                     <description>Power-on programming done</description>
+                     <bitOffset>11</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_HS_DSTS</name>
+               <displayName>OTG_HS_DSTS</displayName>
+               <description>OTG_HS device status register</description>
+               <addressOffset>0x8</addressOffset>
+               <size>32</size>
+               <access>read-only</access>
+               <resetValue>0x00000010</resetValue>
+               <fields>
+                  <field>
+                     <name>SUSPSTS</name>
+                     <description>Suspend status</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>ENUMSPD</name>
+                     <description>Enumerated speed</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>EERR</name>
+                     <description>Erratic error</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FNSOF</name>
+                     <description>Frame number of the received               SOF</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>14</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_HS_DIEPMSK</name>
+               <displayName>OTG_HS_DIEPMSK</displayName>
+               <description>OTG_HS device IN endpoint common interrupt           mask register</description>
+               <addressOffset>0x10</addressOffset>
+               <size>32</size>
+               <access>read-write</access>
+               <resetValue>0x0</resetValue>
+               <fields>
+                  <field>
+                     <name>XFRCM</name>
+                     <description>Transfer completed interrupt               mask</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>EPDM</name>
+                     <description>Endpoint disabled interrupt               mask</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TOM</name>
+                     <description>Timeout condition mask (nonisochronous               endpoints)</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>ITTXFEMSK</name>
+                     <description>IN token received when TxFIFO empty               mask</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>INEPNMM</name>
+                     <description>IN token received with EP mismatch               mask</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>INEPNEM</name>
+                     <description>IN endpoint NAK effective               mask</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TXFURM</name>
+                     <description>FIFO underrun mask</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>BIM</name>
+                     <description>BNA interrupt mask</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_HS_DOEPMSK</name>
+               <displayName>OTG_HS_DOEPMSK</displayName>
+               <description>OTG_HS device OUT endpoint common interrupt           mask register</description>
+               <addressOffset>0x14</addressOffset>
+               <size>32</size>
+               <access>read-write</access>
+               <resetValue>0x0</resetValue>
+               <fields>
+                  <field>
+                     <name>XFRCM</name>
+                     <description>Transfer completed interrupt               mask</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>EPDM</name>
+                     <description>Endpoint disabled interrupt               mask</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>STUPM</name>
+                     <description>SETUP phase done mask</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>OTEPDM</name>
+                     <description>OUT token received when endpoint               disabled mask</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>B2BSTUP</name>
+                     <description>Back-to-back SETUP packets received               mask</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>OPEM</name>
+                     <description>OUT packet error mask</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>BOIM</name>
+                     <description>BNA interrupt mask</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_HS_DAINT</name>
+               <displayName>OTG_HS_DAINT</displayName>
+               <description>OTG_HS device all endpoints interrupt           register</description>
+               <addressOffset>0x18</addressOffset>
+               <size>32</size>
+               <access>read-only</access>
+               <resetValue>0x0</resetValue>
+               <fields>
+                  <field>
+                     <name>IEPINT</name>
+                     <description>IN endpoint interrupt bits</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+                  <field>
+                     <name>OEPINT</name>
+                     <description>OUT endpoint interrupt               bits</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_HS_DAINTMSK</name>
+               <displayName>OTG_HS_DAINTMSK</displayName>
+               <description>OTG_HS all endpoints interrupt mask           register</description>
+               <addressOffset>0x1C</addressOffset>
+               <size>32</size>
+               <access>read-write</access>
+               <resetValue>0x0</resetValue>
+               <fields>
+                  <field>
+                     <name>IEPM</name>
+                     <description>IN EP interrupt mask bits</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+                  <field>
+                     <name>OEPM</name>
+                     <description>OUT EP interrupt mask bits</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_HS_DVBUSDIS</name>
+               <displayName>OTG_HS_DVBUSDIS</displayName>
+               <description>OTG_HS device VBUS discharge time           register</description>
+               <addressOffset>0x28</addressOffset>
+               <size>32</size>
+               <access>read-write</access>
+               <resetValue>0x000017D7</resetValue>
+               <fields>
+                  <field>
+                     <name>VBUSDT</name>
+                     <description>Device VBUS discharge time</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_HS_DVBUSPULSE</name>
+               <displayName>OTG_HS_DVBUSPULSE</displayName>
+               <description>OTG_HS device VBUS pulsing time           register</description>
+               <addressOffset>0x2C</addressOffset>
+               <size>32</size>
+               <access>read-write</access>
+               <resetValue>0x000005B8</resetValue>
+               <fields>
+                  <field>
+                     <name>DVBUSP</name>
+                     <description>Device VBUS pulsing time</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>12</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_HS_DTHRCTL</name>
+               <displayName>OTG_HS_DTHRCTL</displayName>
+               <description>OTG_HS Device threshold control           register</description>
+               <addressOffset>0x30</addressOffset>
+               <size>32</size>
+               <access>read-write</access>
+               <resetValue>0x0</resetValue>
+               <fields>
+                  <field>
+                     <name>NONISOTHREN</name>
+                     <description>Nonisochronous IN endpoints threshold               enable</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>ISOTHREN</name>
+                     <description>ISO IN endpoint threshold               enable</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TXTHRLEN</name>
+                     <description>Transmit threshold length</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>9</bitWidth>
+                  </field>
+                  <field>
+                     <name>RXTHREN</name>
+                     <description>Receive threshold enable</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>RXTHRLEN</name>
+                     <description>Receive threshold length</description>
+                     <bitOffset>17</bitOffset>
+                     <bitWidth>9</bitWidth>
+                  </field>
+                  <field>
+                     <name>ARPEN</name>
+                     <description>Arbiter parking enable</description>
+                     <bitOffset>27</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_HS_DIEPEMPMSK</name>
+               <displayName>OTG_HS_DIEPEMPMSK</displayName>
+               <description>OTG_HS device IN endpoint FIFO empty           interrupt mask register</description>
+               <addressOffset>0x34</addressOffset>
+               <size>32</size>
+               <access>read-write</access>
+               <resetValue>0x0</resetValue>
+               <fields>
+                  <field>
+                     <name>INEPTXFEM</name>
+                     <description>IN EP Tx FIFO empty interrupt mask               bits</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_HS_DEACHINT</name>
+               <displayName>OTG_HS_DEACHINT</displayName>
+               <description>OTG_HS device each endpoint interrupt           register</description>
+               <addressOffset>0x38</addressOffset>
+               <size>32</size>
+               <access>read-write</access>
+               <resetValue>0x0</resetValue>
+               <fields>
+                  <field>
+                     <name>IEP1INT</name>
+                     <description>IN endpoint 1interrupt bit</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>OEP1INT</name>
+                     <description>OUT endpoint 1 interrupt               bit</description>
+                     <bitOffset>17</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_HS_DEACHINTMSK</name>
+               <displayName>OTG_HS_DEACHINTMSK</displayName>
+               <description>OTG_HS device each endpoint interrupt           register mask</description>
+               <addressOffset>0x3C</addressOffset>
+               <size>32</size>
+               <access>read-write</access>
+               <resetValue>0x0</resetValue>
+               <fields>
+                  <field>
+                     <name>IEP1INTM</name>
+                     <description>IN Endpoint 1 interrupt mask               bit</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>OEP1INTM</name>
+                     <description>OUT Endpoint 1 interrupt mask               bit</description>
+                     <bitOffset>17</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_HS_DIEPCTL0</name>
+               <displayName>OTG_HS_DIEPCTL0</displayName>
+               <description>OTG device endpoint-0 control           register</description>
+               <addressOffset>0x100</addressOffset>
+               <size>32</size>
+               <resetValue>0x0</resetValue>
+               <fields>
+                  <field>
+                     <name>MPSIZ</name>
+                     <description>Maximum packet size</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>11</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>USBAEP</name>
+                     <description>USB active endpoint</description>
+                     <bitOffset>15</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>EONUM_DPID</name>
+                     <description>Even/odd frame</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-only</access>
+                  </field>
+                  <field>
+                     <name>NAKSTS</name>
+                     <description>NAK status</description>
+                     <bitOffset>17</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-only</access>
+                  </field>
+                  <field>
+                     <name>EPTYP</name>
+                     <description>Endpoint type</description>
+                     <bitOffset>18</bitOffset>
+                     <bitWidth>2</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>Stall</name>
+                     <description>STALL handshake</description>
+                     <bitOffset>21</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>TXFNUM</name>
+                     <description>TxFIFO number</description>
+                     <bitOffset>22</bitOffset>
+                     <bitWidth>4</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>CNAK</name>
+                     <description>Clear NAK</description>
+                     <bitOffset>26</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>write-only</access>
+                  </field>
+                  <field>
+                     <name>SNAK</name>
+                     <description>Set NAK</description>
+                     <bitOffset>27</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>write-only</access>
+                  </field>
+                  <field>
+                     <name>SD0PID_SEVNFRM</name>
+                     <description>Set DATA0 PID</description>
+                     <bitOffset>28</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>write-only</access>
+                  </field>
+                  <field>
+                     <name>SODDFRM</name>
+                     <description>Set odd frame</description>
+                     <bitOffset>29</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>write-only</access>
+                  </field>
+                  <field>
+                     <name>EPDIS</name>
+                     <description>Endpoint disable</description>
+                     <bitOffset>30</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>EPENA</name>
+                     <description>Endpoint enable</description>
+                     <bitOffset>31</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_HS_DIEPCTL1</name>
+               <displayName>OTG_HS_DIEPCTL1</displayName>
+               <description>OTG device endpoint-1 control           register</description>
+               <addressOffset>0x120</addressOffset>
+               <size>32</size>
+               <resetValue>0x0</resetValue>
+               <fields>
+                  <field>
+                     <name>MPSIZ</name>
+                     <description>Maximum packet size</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>11</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>USBAEP</name>
+                     <description>USB active endpoint</description>
+                     <bitOffset>15</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>EONUM_DPID</name>
+                     <description>Even/odd frame</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-only</access>
+                  </field>
+                  <field>
+                     <name>NAKSTS</name>
+                     <description>NAK status</description>
+                     <bitOffset>17</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-only</access>
+                  </field>
+                  <field>
+                     <name>EPTYP</name>
+                     <description>Endpoint type</description>
+                     <bitOffset>18</bitOffset>
+                     <bitWidth>2</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>Stall</name>
+                     <description>STALL handshake</description>
+                     <bitOffset>21</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>TXFNUM</name>
+                     <description>TxFIFO number</description>
+                     <bitOffset>22</bitOffset>
+                     <bitWidth>4</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>CNAK</name>
+                     <description>Clear NAK</description>
+                     <bitOffset>26</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>write-only</access>
+                  </field>
+                  <field>
+                     <name>SNAK</name>
+                     <description>Set NAK</description>
+                     <bitOffset>27</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>write-only</access>
+                  </field>
+                  <field>
+                     <name>SD0PID_SEVNFRM</name>
+                     <description>Set DATA0 PID</description>
+                     <bitOffset>28</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>write-only</access>
+                  </field>
+                  <field>
+                     <name>SODDFRM</name>
+                     <description>Set odd frame</description>
+                     <bitOffset>29</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>write-only</access>
+                  </field>
+                  <field>
+                     <name>EPDIS</name>
+                     <description>Endpoint disable</description>
+                     <bitOffset>30</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>EPENA</name>
+                     <description>Endpoint enable</description>
+                     <bitOffset>31</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_HS_DIEPCTL2</name>
+               <displayName>OTG_HS_DIEPCTL2</displayName>
+               <description>OTG device endpoint-2 control           register</description>
+               <addressOffset>0x140</addressOffset>
+               <size>32</size>
+               <resetValue>0x0</resetValue>
+               <fields>
+                  <field>
+                     <name>MPSIZ</name>
+                     <description>Maximum packet size</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>11</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>USBAEP</name>
+                     <description>USB active endpoint</description>
+                     <bitOffset>15</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>EONUM_DPID</name>
+                     <description>Even/odd frame</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-only</access>
+                  </field>
+                  <field>
+                     <name>NAKSTS</name>
+                     <description>NAK status</description>
+                     <bitOffset>17</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-only</access>
+                  </field>
+                  <field>
+                     <name>EPTYP</name>
+                     <description>Endpoint type</description>
+                     <bitOffset>18</bitOffset>
+                     <bitWidth>2</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>Stall</name>
+                     <description>STALL handshake</description>
+                     <bitOffset>21</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>TXFNUM</name>
+                     <description>TxFIFO number</description>
+                     <bitOffset>22</bitOffset>
+                     <bitWidth>4</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>CNAK</name>
+                     <description>Clear NAK</description>
+                     <bitOffset>26</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>write-only</access>
+                  </field>
+                  <field>
+                     <name>SNAK</name>
+                     <description>Set NAK</description>
+                     <bitOffset>27</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>write-only</access>
+                  </field>
+                  <field>
+                     <name>SD0PID_SEVNFRM</name>
+                     <description>Set DATA0 PID</description>
+                     <bitOffset>28</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>write-only</access>
+                  </field>
+                  <field>
+                     <name>SODDFRM</name>
+                     <description>Set odd frame</description>
+                     <bitOffset>29</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>write-only</access>
+                  </field>
+                  <field>
+                     <name>EPDIS</name>
+                     <description>Endpoint disable</description>
+                     <bitOffset>30</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>EPENA</name>
+                     <description>Endpoint enable</description>
+                     <bitOffset>31</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_HS_DIEPCTL3</name>
+               <displayName>OTG_HS_DIEPCTL3</displayName>
+               <description>OTG device endpoint-3 control           register</description>
+               <addressOffset>0x160</addressOffset>
+               <size>32</size>
+               <resetValue>0x0</resetValue>
+               <fields>
+                  <field>
+                     <name>MPSIZ</name>
+                     <description>Maximum packet size</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>11</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>USBAEP</name>
+                     <description>USB active endpoint</description>
+                     <bitOffset>15</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>EONUM_DPID</name>
+                     <description>Even/odd frame</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-only</access>
+                  </field>
+                  <field>
+                     <name>NAKSTS</name>
+                     <description>NAK status</description>
+                     <bitOffset>17</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-only</access>
+                  </field>
+                  <field>
+                     <name>EPTYP</name>
+                     <description>Endpoint type</description>
+                     <bitOffset>18</bitOffset>
+                     <bitWidth>2</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>Stall</name>
+                     <description>STALL handshake</description>
+                     <bitOffset>21</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>TXFNUM</name>
+                     <description>TxFIFO number</description>
+                     <bitOffset>22</bitOffset>
+                     <bitWidth>4</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>CNAK</name>
+                     <description>Clear NAK</description>
+                     <bitOffset>26</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>write-only</access>
+                  </field>
+                  <field>
+                     <name>SNAK</name>
+                     <description>Set NAK</description>
+                     <bitOffset>27</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>write-only</access>
+                  </field>
+                  <field>
+                     <name>SD0PID_SEVNFRM</name>
+                     <description>Set DATA0 PID</description>
+                     <bitOffset>28</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>write-only</access>
+                  </field>
+                  <field>
+                     <name>SODDFRM</name>
+                     <description>Set odd frame</description>
+                     <bitOffset>29</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>write-only</access>
+                  </field>
+                  <field>
+                     <name>EPDIS</name>
+                     <description>Endpoint disable</description>
+                     <bitOffset>30</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>EPENA</name>
+                     <description>Endpoint enable</description>
+                     <bitOffset>31</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_HS_DIEPCTL4</name>
+               <displayName>OTG_HS_DIEPCTL4</displayName>
+               <description>OTG device endpoint-4 control           register</description>
+               <addressOffset>0x180</addressOffset>
+               <size>32</size>
+               <resetValue>0x0</resetValue>
+               <fields>
+                  <field>
+                     <name>MPSIZ</name>
+                     <description>Maximum packet size</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>11</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>USBAEP</name>
+                     <description>USB active endpoint</description>
+                     <bitOffset>15</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>EONUM_DPID</name>
+                     <description>Even/odd frame</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-only</access>
+                  </field>
+                  <field>
+                     <name>NAKSTS</name>
+                     <description>NAK status</description>
+                     <bitOffset>17</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-only</access>
+                  </field>
+                  <field>
+                     <name>EPTYP</name>
+                     <description>Endpoint type</description>
+                     <bitOffset>18</bitOffset>
+                     <bitWidth>2</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>Stall</name>
+                     <description>STALL handshake</description>
+                     <bitOffset>21</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>TXFNUM</name>
+                     <description>TxFIFO number</description>
+                     <bitOffset>22</bitOffset>
+                     <bitWidth>4</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>CNAK</name>
+                     <description>Clear NAK</description>
+                     <bitOffset>26</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>write-only</access>
+                  </field>
+                  <field>
+                     <name>SNAK</name>
+                     <description>Set NAK</description>
+                     <bitOffset>27</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>write-only</access>
+                  </field>
+                  <field>
+                     <name>SD0PID_SEVNFRM</name>
+                     <description>Set DATA0 PID</description>
+                     <bitOffset>28</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>write-only</access>
+                  </field>
+                  <field>
+                     <name>SODDFRM</name>
+                     <description>Set odd frame</description>
+                     <bitOffset>29</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>write-only</access>
+                  </field>
+                  <field>
+                     <name>EPDIS</name>
+                     <description>Endpoint disable</description>
+                     <bitOffset>30</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>EPENA</name>
+                     <description>Endpoint enable</description>
+                     <bitOffset>31</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_HS_DIEPCTL5</name>
+               <displayName>OTG_HS_DIEPCTL5</displayName>
+               <description>OTG device endpoint-5 control           register</description>
+               <addressOffset>0x1A0</addressOffset>
+               <size>32</size>
+               <resetValue>0x0</resetValue>
+               <fields>
+                  <field>
+                     <name>MPSIZ</name>
+                     <description>Maximum packet size</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>11</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>USBAEP</name>
+                     <description>USB active endpoint</description>
+                     <bitOffset>15</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>EONUM_DPID</name>
+                     <description>Even/odd frame</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-only</access>
+                  </field>
+                  <field>
+                     <name>NAKSTS</name>
+                     <description>NAK status</description>
+                     <bitOffset>17</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-only</access>
+                  </field>
+                  <field>
+                     <name>EPTYP</name>
+                     <description>Endpoint type</description>
+                     <bitOffset>18</bitOffset>
+                     <bitWidth>2</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>Stall</name>
+                     <description>STALL handshake</description>
+                     <bitOffset>21</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>TXFNUM</name>
+                     <description>TxFIFO number</description>
+                     <bitOffset>22</bitOffset>
+                     <bitWidth>4</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>CNAK</name>
+                     <description>Clear NAK</description>
+                     <bitOffset>26</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>write-only</access>
+                  </field>
+                  <field>
+                     <name>SNAK</name>
+                     <description>Set NAK</description>
+                     <bitOffset>27</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>write-only</access>
+                  </field>
+                  <field>
+                     <name>SD0PID_SEVNFRM</name>
+                     <description>Set DATA0 PID</description>
+                     <bitOffset>28</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>write-only</access>
+                  </field>
+                  <field>
+                     <name>SODDFRM</name>
+                     <description>Set odd frame</description>
+                     <bitOffset>29</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>write-only</access>
+                  </field>
+                  <field>
+                     <name>EPDIS</name>
+                     <description>Endpoint disable</description>
+                     <bitOffset>30</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>EPENA</name>
+                     <description>Endpoint enable</description>
+                     <bitOffset>31</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_HS_DIEPCTL6</name>
+               <displayName>OTG_HS_DIEPCTL6</displayName>
+               <description>OTG device endpoint-6 control           register</description>
+               <addressOffset>0x1C0</addressOffset>
+               <size>32</size>
+               <resetValue>0x0</resetValue>
+               <fields>
+                  <field>
+                     <name>MPSIZ</name>
+                     <description>Maximum packet size</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>11</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>USBAEP</name>
+                     <description>USB active endpoint</description>
+                     <bitOffset>15</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>EONUM_DPID</name>
+                     <description>Even/odd frame</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-only</access>
+                  </field>
+                  <field>
+                     <name>NAKSTS</name>
+                     <description>NAK status</description>
+                     <bitOffset>17</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-only</access>
+                  </field>
+                  <field>
+                     <name>EPTYP</name>
+                     <description>Endpoint type</description>
+                     <bitOffset>18</bitOffset>
+                     <bitWidth>2</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>Stall</name>
+                     <description>STALL handshake</description>
+                     <bitOffset>21</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>TXFNUM</name>
+                     <description>TxFIFO number</description>
+                     <bitOffset>22</bitOffset>
+                     <bitWidth>4</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>CNAK</name>
+                     <description>Clear NAK</description>
+                     <bitOffset>26</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>write-only</access>
+                  </field>
+                  <field>
+                     <name>SNAK</name>
+                     <description>Set NAK</description>
+                     <bitOffset>27</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>write-only</access>
+                  </field>
+                  <field>
+                     <name>SD0PID_SEVNFRM</name>
+                     <description>Set DATA0 PID</description>
+                     <bitOffset>28</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>write-only</access>
+                  </field>
+                  <field>
+                     <name>SODDFRM</name>
+                     <description>Set odd frame</description>
+                     <bitOffset>29</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>write-only</access>
+                  </field>
+                  <field>
+                     <name>EPDIS</name>
+                     <description>Endpoint disable</description>
+                     <bitOffset>30</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>EPENA</name>
+                     <description>Endpoint enable</description>
+                     <bitOffset>31</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_HS_DIEPCTL7</name>
+               <displayName>OTG_HS_DIEPCTL7</displayName>
+               <description>OTG device endpoint-7 control           register</description>
+               <addressOffset>0x1E0</addressOffset>
+               <size>32</size>
+               <resetValue>0x0</resetValue>
+               <fields>
+                  <field>
+                     <name>MPSIZ</name>
+                     <description>Maximum packet size</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>11</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>USBAEP</name>
+                     <description>USB active endpoint</description>
+                     <bitOffset>15</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>EONUM_DPID</name>
+                     <description>Even/odd frame</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-only</access>
+                  </field>
+                  <field>
+                     <name>NAKSTS</name>
+                     <description>NAK status</description>
+                     <bitOffset>17</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-only</access>
+                  </field>
+                  <field>
+                     <name>EPTYP</name>
+                     <description>Endpoint type</description>
+                     <bitOffset>18</bitOffset>
+                     <bitWidth>2</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>Stall</name>
+                     <description>STALL handshake</description>
+                     <bitOffset>21</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>TXFNUM</name>
+                     <description>TxFIFO number</description>
+                     <bitOffset>22</bitOffset>
+                     <bitWidth>4</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>CNAK</name>
+                     <description>Clear NAK</description>
+                     <bitOffset>26</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>write-only</access>
+                  </field>
+                  <field>
+                     <name>SNAK</name>
+                     <description>Set NAK</description>
+                     <bitOffset>27</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>write-only</access>
+                  </field>
+                  <field>
+                     <name>SD0PID_SEVNFRM</name>
+                     <description>Set DATA0 PID</description>
+                     <bitOffset>28</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>write-only</access>
+                  </field>
+                  <field>
+                     <name>SODDFRM</name>
+                     <description>Set odd frame</description>
+                     <bitOffset>29</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>write-only</access>
+                  </field>
+                  <field>
+                     <name>EPDIS</name>
+                     <description>Endpoint disable</description>
+                     <bitOffset>30</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>EPENA</name>
+                     <description>Endpoint enable</description>
+                     <bitOffset>31</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_HS_DIEPINT0</name>
+               <displayName>OTG_HS_DIEPINT0</displayName>
+               <description>OTG device endpoint-0 interrupt           register</description>
+               <addressOffset>0x108</addressOffset>
+               <size>32</size>
+               <resetValue>0x00000080</resetValue>
+               <fields>
+                  <field>
+                     <name>XFRC</name>
+                     <description>Transfer completed               interrupt</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>EPDISD</name>
+                     <description>Endpoint disabled               interrupt</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>TOC</name>
+                     <description>Timeout condition</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>ITTXFE</name>
+                     <description>IN token received when TxFIFO is               empty</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>INEPNE</name>
+                     <description>IN endpoint NAK effective</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>TXFE</name>
+                     <description>Transmit FIFO empty</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-only</access>
+                  </field>
+                  <field>
+                     <name>TXFIFOUDRN</name>
+                     <description>Transmit Fifo Underrun</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>BNA</name>
+                     <description>Buffer not available               interrupt</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>PKTDRPSTS</name>
+                     <description>Packet dropped status</description>
+                     <bitOffset>11</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>BERR</name>
+                     <description>Babble error interrupt</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>NAK</name>
+                     <description>NAK interrupt</description>
+                     <bitOffset>13</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_HS_DIEPINT1</name>
+               <displayName>OTG_HS_DIEPINT1</displayName>
+               <description>OTG device endpoint-1 interrupt           register</description>
+               <addressOffset>0x128</addressOffset>
+               <size>32</size>
+               <resetValue>0x0</resetValue>
+               <fields>
+                  <field>
+                     <name>XFRC</name>
+                     <description>Transfer completed               interrupt</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>EPDISD</name>
+                     <description>Endpoint disabled               interrupt</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>TOC</name>
+                     <description>Timeout condition</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>ITTXFE</name>
+                     <description>IN token received when TxFIFO is               empty</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>INEPNE</name>
+                     <description>IN endpoint NAK effective</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>TXFE</name>
+                     <description>Transmit FIFO empty</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-only</access>
+                  </field>
+                  <field>
+                     <name>TXFIFOUDRN</name>
+                     <description>Transmit Fifo Underrun</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>BNA</name>
+                     <description>Buffer not available               interrupt</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>PKTDRPSTS</name>
+                     <description>Packet dropped status</description>
+                     <bitOffset>11</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>BERR</name>
+                     <description>Babble error interrupt</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>NAK</name>
+                     <description>NAK interrupt</description>
+                     <bitOffset>13</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_HS_DIEPINT2</name>
+               <displayName>OTG_HS_DIEPINT2</displayName>
+               <description>OTG device endpoint-2 interrupt           register</description>
+               <addressOffset>0x148</addressOffset>
+               <size>32</size>
+               <resetValue>0x0</resetValue>
+               <fields>
+                  <field>
+                     <name>XFRC</name>
+                     <description>Transfer completed               interrupt</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>EPDISD</name>
+                     <description>Endpoint disabled               interrupt</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>TOC</name>
+                     <description>Timeout condition</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>ITTXFE</name>
+                     <description>IN token received when TxFIFO is               empty</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>INEPNE</name>
+                     <description>IN endpoint NAK effective</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>TXFE</name>
+                     <description>Transmit FIFO empty</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-only</access>
+                  </field>
+                  <field>
+                     <name>TXFIFOUDRN</name>
+                     <description>Transmit Fifo Underrun</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>BNA</name>
+                     <description>Buffer not available               interrupt</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>PKTDRPSTS</name>
+                     <description>Packet dropped status</description>
+                     <bitOffset>11</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>BERR</name>
+                     <description>Babble error interrupt</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>NAK</name>
+                     <description>NAK interrupt</description>
+                     <bitOffset>13</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_HS_DIEPINT3</name>
+               <displayName>OTG_HS_DIEPINT3</displayName>
+               <description>OTG device endpoint-3 interrupt           register</description>
+               <addressOffset>0x168</addressOffset>
+               <size>32</size>
+               <resetValue>0x0</resetValue>
+               <fields>
+                  <field>
+                     <name>XFRC</name>
+                     <description>Transfer completed               interrupt</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>EPDISD</name>
+                     <description>Endpoint disabled               interrupt</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>TOC</name>
+                     <description>Timeout condition</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>ITTXFE</name>
+                     <description>IN token received when TxFIFO is               empty</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>INEPNE</name>
+                     <description>IN endpoint NAK effective</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>TXFE</name>
+                     <description>Transmit FIFO empty</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-only</access>
+                  </field>
+                  <field>
+                     <name>TXFIFOUDRN</name>
+                     <description>Transmit Fifo Underrun</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>BNA</name>
+                     <description>Buffer not available               interrupt</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>PKTDRPSTS</name>
+                     <description>Packet dropped status</description>
+                     <bitOffset>11</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>BERR</name>
+                     <description>Babble error interrupt</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>NAK</name>
+                     <description>NAK interrupt</description>
+                     <bitOffset>13</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_HS_DIEPINT4</name>
+               <displayName>OTG_HS_DIEPINT4</displayName>
+               <description>OTG device endpoint-4 interrupt           register</description>
+               <addressOffset>0x188</addressOffset>
+               <size>32</size>
+               <resetValue>0x0</resetValue>
+               <fields>
+                  <field>
+                     <name>XFRC</name>
+                     <description>Transfer completed               interrupt</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>EPDISD</name>
+                     <description>Endpoint disabled               interrupt</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>TOC</name>
+                     <description>Timeout condition</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>ITTXFE</name>
+                     <description>IN token received when TxFIFO is               empty</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>INEPNE</name>
+                     <description>IN endpoint NAK effective</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>TXFE</name>
+                     <description>Transmit FIFO empty</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-only</access>
+                  </field>
+                  <field>
+                     <name>TXFIFOUDRN</name>
+                     <description>Transmit Fifo Underrun</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>BNA</name>
+                     <description>Buffer not available               interrupt</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>PKTDRPSTS</name>
+                     <description>Packet dropped status</description>
+                     <bitOffset>11</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>BERR</name>
+                     <description>Babble error interrupt</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>NAK</name>
+                     <description>NAK interrupt</description>
+                     <bitOffset>13</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_HS_DIEPINT5</name>
+               <displayName>OTG_HS_DIEPINT5</displayName>
+               <description>OTG device endpoint-5 interrupt           register</description>
+               <addressOffset>0x1A8</addressOffset>
+               <size>32</size>
+               <resetValue>0x0</resetValue>
+               <fields>
+                  <field>
+                     <name>XFRC</name>
+                     <description>Transfer completed               interrupt</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>EPDISD</name>
+                     <description>Endpoint disabled               interrupt</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>TOC</name>
+                     <description>Timeout condition</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>ITTXFE</name>
+                     <description>IN token received when TxFIFO is               empty</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>INEPNE</name>
+                     <description>IN endpoint NAK effective</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>TXFE</name>
+                     <description>Transmit FIFO empty</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-only</access>
+                  </field>
+                  <field>
+                     <name>TXFIFOUDRN</name>
+                     <description>Transmit Fifo Underrun</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>BNA</name>
+                     <description>Buffer not available               interrupt</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>PKTDRPSTS</name>
+                     <description>Packet dropped status</description>
+                     <bitOffset>11</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>BERR</name>
+                     <description>Babble error interrupt</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>NAK</name>
+                     <description>NAK interrupt</description>
+                     <bitOffset>13</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_HS_DIEPINT6</name>
+               <displayName>OTG_HS_DIEPINT6</displayName>
+               <description>OTG device endpoint-6 interrupt           register</description>
+               <addressOffset>0x1C8</addressOffset>
+               <size>32</size>
+               <resetValue>0x0</resetValue>
+               <fields>
+                  <field>
+                     <name>XFRC</name>
+                     <description>Transfer completed               interrupt</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>EPDISD</name>
+                     <description>Endpoint disabled               interrupt</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>TOC</name>
+                     <description>Timeout condition</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>ITTXFE</name>
+                     <description>IN token received when TxFIFO is               empty</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>INEPNE</name>
+                     <description>IN endpoint NAK effective</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>TXFE</name>
+                     <description>Transmit FIFO empty</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-only</access>
+                  </field>
+                  <field>
+                     <name>TXFIFOUDRN</name>
+                     <description>Transmit Fifo Underrun</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>BNA</name>
+                     <description>Buffer not available               interrupt</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>PKTDRPSTS</name>
+                     <description>Packet dropped status</description>
+                     <bitOffset>11</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>BERR</name>
+                     <description>Babble error interrupt</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>NAK</name>
+                     <description>NAK interrupt</description>
+                     <bitOffset>13</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_HS_DIEPINT7</name>
+               <displayName>OTG_HS_DIEPINT7</displayName>
+               <description>OTG device endpoint-7 interrupt           register</description>
+               <addressOffset>0x1E8</addressOffset>
+               <size>32</size>
+               <resetValue>0x0</resetValue>
+               <fields>
+                  <field>
+                     <name>XFRC</name>
+                     <description>Transfer completed               interrupt</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>EPDISD</name>
+                     <description>Endpoint disabled               interrupt</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>TOC</name>
+                     <description>Timeout condition</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>ITTXFE</name>
+                     <description>IN token received when TxFIFO is               empty</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>INEPNE</name>
+                     <description>IN endpoint NAK effective</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>TXFE</name>
+                     <description>Transmit FIFO empty</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-only</access>
+                  </field>
+                  <field>
+                     <name>TXFIFOUDRN</name>
+                     <description>Transmit Fifo Underrun</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>BNA</name>
+                     <description>Buffer not available               interrupt</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>PKTDRPSTS</name>
+                     <description>Packet dropped status</description>
+                     <bitOffset>11</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>BERR</name>
+                     <description>Babble error interrupt</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>NAK</name>
+                     <description>NAK interrupt</description>
+                     <bitOffset>13</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_HS_DIEPTSIZ0</name>
+               <displayName>OTG_HS_DIEPTSIZ0</displayName>
+               <description>OTG_HS device IN endpoint 0 transfer size           register</description>
+               <addressOffset>0x110</addressOffset>
+               <size>32</size>
+               <access>read-write</access>
+               <resetValue>0x0</resetValue>
+               <fields>
+                  <field>
+                     <name>XFRSIZ</name>
+                     <description>Transfer size</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>7</bitWidth>
+                  </field>
+                  <field>
+                     <name>PKTCNT</name>
+                     <description>Packet count</description>
+                     <bitOffset>19</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_HS_DIEPDMA1</name>
+               <displayName>OTG_HS_DIEPDMA1</displayName>
+               <description>OTG_HS device endpoint-1 DMA address           register</description>
+               <addressOffset>0x114</addressOffset>
+               <size>32</size>
+               <access>read-write</access>
+               <resetValue>0x0</resetValue>
+               <fields>
+                  <field>
+                     <name>DMAADDR</name>
+                     <description>DMA address</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_HS_DIEPDMA2</name>
+               <displayName>OTG_HS_DIEPDMA2</displayName>
+               <description>OTG_HS device endpoint-2 DMA address           register</description>
+               <addressOffset>0x134</addressOffset>
+               <size>32</size>
+               <access>read-write</access>
+               <resetValue>0x0</resetValue>
+               <fields>
+                  <field>
+                     <name>DMAADDR</name>
+                     <description>DMA address</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_HS_DIEPDMA3</name>
+               <displayName>OTG_HS_DIEPDMA3</displayName>
+               <description>OTG_HS device endpoint-3 DMA address           register</description>
+               <addressOffset>0x154</addressOffset>
+               <size>32</size>
+               <access>read-write</access>
+               <resetValue>0x0</resetValue>
+               <fields>
+                  <field>
+                     <name>DMAADDR</name>
+                     <description>DMA address</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_HS_DIEPDMA4</name>
+               <displayName>OTG_HS_DIEPDMA4</displayName>
+               <description>OTG_HS device endpoint-4 DMA address           register</description>
+               <addressOffset>0x174</addressOffset>
+               <size>32</size>
+               <access>read-write</access>
+               <resetValue>0x0</resetValue>
+               <fields>
+                  <field>
+                     <name>DMAADDR</name>
+                     <description>DMA address</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_HS_DIEPDMA5</name>
+               <displayName>OTG_HS_DIEPDMA5</displayName>
+               <description>OTG_HS device endpoint-5 DMA address           register</description>
+               <addressOffset>0x194</addressOffset>
+               <size>32</size>
+               <access>read-write</access>
+               <resetValue>0x0</resetValue>
+               <fields>
+                  <field>
+                     <name>DMAADDR</name>
+                     <description>DMA address</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_HS_DTXFSTS0</name>
+               <displayName>OTG_HS_DTXFSTS0</displayName>
+               <description>OTG_HS device IN endpoint transmit FIFO           status register</description>
+               <addressOffset>0x118</addressOffset>
+               <size>32</size>
+               <access>read-only</access>
+               <resetValue>0x0</resetValue>
+               <fields>
+                  <field>
+                     <name>INEPTFSAV</name>
+                     <description>IN endpoint TxFIFO space               avail</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_HS_DTXFSTS1</name>
+               <displayName>OTG_HS_DTXFSTS1</displayName>
+               <description>OTG_HS device IN endpoint transmit FIFO           status register</description>
+               <addressOffset>0x138</addressOffset>
+               <size>32</size>
+               <access>read-only</access>
+               <resetValue>0x0</resetValue>
+               <fields>
+                  <field>
+                     <name>INEPTFSAV</name>
+                     <description>IN endpoint TxFIFO space               avail</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_HS_DTXFSTS2</name>
+               <displayName>OTG_HS_DTXFSTS2</displayName>
+               <description>OTG_HS device IN endpoint transmit FIFO           status register</description>
+               <addressOffset>0x158</addressOffset>
+               <size>32</size>
+               <access>read-only</access>
+               <resetValue>0x0</resetValue>
+               <fields>
+                  <field>
+                     <name>INEPTFSAV</name>
+                     <description>IN endpoint TxFIFO space               avail</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_HS_DTXFSTS3</name>
+               <displayName>OTG_HS_DTXFSTS3</displayName>
+               <description>OTG_HS device IN endpoint transmit FIFO           status register</description>
+               <addressOffset>0x178</addressOffset>
+               <size>32</size>
+               <access>read-only</access>
+               <resetValue>0x0</resetValue>
+               <fields>
+                  <field>
+                     <name>INEPTFSAV</name>
+                     <description>IN endpoint TxFIFO space               avail</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_HS_DTXFSTS4</name>
+               <displayName>OTG_HS_DTXFSTS4</displayName>
+               <description>OTG_HS device IN endpoint transmit FIFO           status register</description>
+               <addressOffset>0x198</addressOffset>
+               <size>32</size>
+               <access>read-only</access>
+               <resetValue>0x0</resetValue>
+               <fields>
+                  <field>
+                     <name>INEPTFSAV</name>
+                     <description>IN endpoint TxFIFO space               avail</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_HS_DTXFSTS5</name>
+               <displayName>OTG_HS_DTXFSTS5</displayName>
+               <description>OTG_HS device IN endpoint transmit FIFO           status register</description>
+               <addressOffset>0x1B8</addressOffset>
+               <size>32</size>
+               <access>read-only</access>
+               <resetValue>0x0</resetValue>
+               <fields>
+                  <field>
+                     <name>INEPTFSAV</name>
+                     <description>IN endpoint TxFIFO space               avail</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_HS_DIEPTSIZ1</name>
+               <displayName>OTG_HS_DIEPTSIZ1</displayName>
+               <description>OTG_HS device endpoint transfer size           register</description>
+               <addressOffset>0x130</addressOffset>
+               <size>32</size>
+               <access>read-write</access>
+               <resetValue>0x0</resetValue>
+               <fields>
+                  <field>
+                     <name>XFRSIZ</name>
+                     <description>Transfer size</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>19</bitWidth>
+                  </field>
+                  <field>
+                     <name>PKTCNT</name>
+                     <description>Packet count</description>
+                     <bitOffset>19</bitOffset>
+                     <bitWidth>10</bitWidth>
+                  </field>
+                  <field>
+                     <name>MCNT</name>
+                     <description>Multi count</description>
+                     <bitOffset>29</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_HS_DIEPTSIZ2</name>
+               <displayName>OTG_HS_DIEPTSIZ2</displayName>
+               <description>OTG_HS device endpoint transfer size           register</description>
+               <addressOffset>0x150</addressOffset>
+               <size>32</size>
+               <access>read-write</access>
+               <resetValue>0x0</resetValue>
+               <fields>
+                  <field>
+                     <name>XFRSIZ</name>
+                     <description>Transfer size</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>19</bitWidth>
+                  </field>
+                  <field>
+                     <name>PKTCNT</name>
+                     <description>Packet count</description>
+                     <bitOffset>19</bitOffset>
+                     <bitWidth>10</bitWidth>
+                  </field>
+                  <field>
+                     <name>MCNT</name>
+                     <description>Multi count</description>
+                     <bitOffset>29</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_HS_DIEPTSIZ3</name>
+               <displayName>OTG_HS_DIEPTSIZ3</displayName>
+               <description>OTG_HS device endpoint transfer size           register</description>
+               <addressOffset>0x170</addressOffset>
+               <size>32</size>
+               <access>read-write</access>
+               <resetValue>0x0</resetValue>
+               <fields>
+                  <field>
+                     <name>XFRSIZ</name>
+                     <description>Transfer size</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>19</bitWidth>
+                  </field>
+                  <field>
+                     <name>PKTCNT</name>
+                     <description>Packet count</description>
+                     <bitOffset>19</bitOffset>
+                     <bitWidth>10</bitWidth>
+                  </field>
+                  <field>
+                     <name>MCNT</name>
+                     <description>Multi count</description>
+                     <bitOffset>29</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_HS_DIEPTSIZ4</name>
+               <displayName>OTG_HS_DIEPTSIZ4</displayName>
+               <description>OTG_HS device endpoint transfer size           register</description>
+               <addressOffset>0x190</addressOffset>
+               <size>32</size>
+               <access>read-write</access>
+               <resetValue>0x0</resetValue>
+               <fields>
+                  <field>
+                     <name>XFRSIZ</name>
+                     <description>Transfer size</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>19</bitWidth>
+                  </field>
+                  <field>
+                     <name>PKTCNT</name>
+                     <description>Packet count</description>
+                     <bitOffset>19</bitOffset>
+                     <bitWidth>10</bitWidth>
+                  </field>
+                  <field>
+                     <name>MCNT</name>
+                     <description>Multi count</description>
+                     <bitOffset>29</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_HS_DIEPTSIZ5</name>
+               <displayName>OTG_HS_DIEPTSIZ5</displayName>
+               <description>OTG_HS device endpoint transfer size           register</description>
+               <addressOffset>0x1B0</addressOffset>
+               <size>32</size>
+               <access>read-write</access>
+               <resetValue>0x0</resetValue>
+               <fields>
+                  <field>
+                     <name>XFRSIZ</name>
+                     <description>Transfer size</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>19</bitWidth>
+                  </field>
+                  <field>
+                     <name>PKTCNT</name>
+                     <description>Packet count</description>
+                     <bitOffset>19</bitOffset>
+                     <bitWidth>10</bitWidth>
+                  </field>
+                  <field>
+                     <name>MCNT</name>
+                     <description>Multi count</description>
+                     <bitOffset>29</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_HS_DOEPCTL0</name>
+               <displayName>OTG_HS_DOEPCTL0</displayName>
+               <description>OTG_HS device control OUT endpoint 0 control           register</description>
+               <addressOffset>0x300</addressOffset>
+               <size>32</size>
+               <resetValue>0x00008000</resetValue>
+               <fields>
+                  <field>
+                     <name>MPSIZ</name>
+                     <description>Maximum packet size</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>2</bitWidth>
+                     <access>read-only</access>
+                  </field>
+                  <field>
+                     <name>USBAEP</name>
+                     <description>USB active endpoint</description>
+                     <bitOffset>15</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-only</access>
+                  </field>
+                  <field>
+                     <name>NAKSTS</name>
+                     <description>NAK status</description>
+                     <bitOffset>17</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-only</access>
+                  </field>
+                  <field>
+                     <name>EPTYP</name>
+                     <description>Endpoint type</description>
+                     <bitOffset>18</bitOffset>
+                     <bitWidth>2</bitWidth>
+                     <access>read-only</access>
+                  </field>
+                  <field>
+                     <name>SNPM</name>
+                     <description>Snoop mode</description>
+                     <bitOffset>20</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>Stall</name>
+                     <description>STALL handshake</description>
+                     <bitOffset>21</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>CNAK</name>
+                     <description>Clear NAK</description>
+                     <bitOffset>26</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>write-only</access>
+                  </field>
+                  <field>
+                     <name>SNAK</name>
+                     <description>Set NAK</description>
+                     <bitOffset>27</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>write-only</access>
+                  </field>
+                  <field>
+                     <name>EPDIS</name>
+                     <description>Endpoint disable</description>
+                     <bitOffset>30</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-only</access>
+                  </field>
+                  <field>
+                     <name>EPENA</name>
+                     <description>Endpoint enable</description>
+                     <bitOffset>31</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>write-only</access>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_HS_DOEPCTL1</name>
+               <displayName>OTG_HS_DOEPCTL1</displayName>
+               <description>OTG device endpoint-1 control           register</description>
+               <addressOffset>0x320</addressOffset>
+               <size>32</size>
+               <resetValue>0x0</resetValue>
+               <fields>
+                  <field>
+                     <name>MPSIZ</name>
+                     <description>Maximum packet size</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>11</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>USBAEP</name>
+                     <description>USB active endpoint</description>
+                     <bitOffset>15</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>EONUM_DPID</name>
+                     <description>Even odd frame/Endpoint data               PID</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-only</access>
+                  </field>
+                  <field>
+                     <name>NAKSTS</name>
+                     <description>NAK status</description>
+                     <bitOffset>17</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-only</access>
+                  </field>
+                  <field>
+                     <name>EPTYP</name>
+                     <description>Endpoint type</description>
+                     <bitOffset>18</bitOffset>
+                     <bitWidth>2</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>SNPM</name>
+                     <description>Snoop mode</description>
+                     <bitOffset>20</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>Stall</name>
+                     <description>STALL handshake</description>
+                     <bitOffset>21</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>CNAK</name>
+                     <description>Clear NAK</description>
+                     <bitOffset>26</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>write-only</access>
+                  </field>
+                  <field>
+                     <name>SNAK</name>
+                     <description>Set NAK</description>
+                     <bitOffset>27</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>write-only</access>
+                  </field>
+                  <field>
+                     <name>SD0PID_SEVNFRM</name>
+                     <description>Set DATA0 PID/Set even               frame</description>
+                     <bitOffset>28</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>write-only</access>
+                  </field>
+                  <field>
+                     <name>SODDFRM</name>
+                     <description>Set odd frame</description>
+                     <bitOffset>29</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>write-only</access>
+                  </field>
+                  <field>
+                     <name>EPDIS</name>
+                     <description>Endpoint disable</description>
+                     <bitOffset>30</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>EPENA</name>
+                     <description>Endpoint enable</description>
+                     <bitOffset>31</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_HS_DOEPCTL2</name>
+               <displayName>OTG_HS_DOEPCTL2</displayName>
+               <description>OTG device endpoint-2 control           register</description>
+               <addressOffset>0x340</addressOffset>
+               <size>32</size>
+               <resetValue>0x0</resetValue>
+               <fields>
+                  <field>
+                     <name>MPSIZ</name>
+                     <description>Maximum packet size</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>11</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>USBAEP</name>
+                     <description>USB active endpoint</description>
+                     <bitOffset>15</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>EONUM_DPID</name>
+                     <description>Even odd frame/Endpoint data               PID</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-only</access>
+                  </field>
+                  <field>
+                     <name>NAKSTS</name>
+                     <description>NAK status</description>
+                     <bitOffset>17</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-only</access>
+                  </field>
+                  <field>
+                     <name>EPTYP</name>
+                     <description>Endpoint type</description>
+                     <bitOffset>18</bitOffset>
+                     <bitWidth>2</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>SNPM</name>
+                     <description>Snoop mode</description>
+                     <bitOffset>20</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>Stall</name>
+                     <description>STALL handshake</description>
+                     <bitOffset>21</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>CNAK</name>
+                     <description>Clear NAK</description>
+                     <bitOffset>26</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>write-only</access>
+                  </field>
+                  <field>
+                     <name>SNAK</name>
+                     <description>Set NAK</description>
+                     <bitOffset>27</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>write-only</access>
+                  </field>
+                  <field>
+                     <name>SD0PID_SEVNFRM</name>
+                     <description>Set DATA0 PID/Set even               frame</description>
+                     <bitOffset>28</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>write-only</access>
+                  </field>
+                  <field>
+                     <name>SODDFRM</name>
+                     <description>Set odd frame</description>
+                     <bitOffset>29</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>write-only</access>
+                  </field>
+                  <field>
+                     <name>EPDIS</name>
+                     <description>Endpoint disable</description>
+                     <bitOffset>30</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>EPENA</name>
+                     <description>Endpoint enable</description>
+                     <bitOffset>31</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_HS_DOEPCTL3</name>
+               <displayName>OTG_HS_DOEPCTL3</displayName>
+               <description>OTG device endpoint-3 control           register</description>
+               <addressOffset>0x360</addressOffset>
+               <size>32</size>
+               <resetValue>0x0</resetValue>
+               <fields>
+                  <field>
+                     <name>MPSIZ</name>
+                     <description>Maximum packet size</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>11</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>USBAEP</name>
+                     <description>USB active endpoint</description>
+                     <bitOffset>15</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>EONUM_DPID</name>
+                     <description>Even odd frame/Endpoint data               PID</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-only</access>
+                  </field>
+                  <field>
+                     <name>NAKSTS</name>
+                     <description>NAK status</description>
+                     <bitOffset>17</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-only</access>
+                  </field>
+                  <field>
+                     <name>EPTYP</name>
+                     <description>Endpoint type</description>
+                     <bitOffset>18</bitOffset>
+                     <bitWidth>2</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>SNPM</name>
+                     <description>Snoop mode</description>
+                     <bitOffset>20</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>Stall</name>
+                     <description>STALL handshake</description>
+                     <bitOffset>21</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>CNAK</name>
+                     <description>Clear NAK</description>
+                     <bitOffset>26</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>write-only</access>
+                  </field>
+                  <field>
+                     <name>SNAK</name>
+                     <description>Set NAK</description>
+                     <bitOffset>27</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>write-only</access>
+                  </field>
+                  <field>
+                     <name>SD0PID_SEVNFRM</name>
+                     <description>Set DATA0 PID/Set even               frame</description>
+                     <bitOffset>28</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>write-only</access>
+                  </field>
+                  <field>
+                     <name>SODDFRM</name>
+                     <description>Set odd frame</description>
+                     <bitOffset>29</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>write-only</access>
+                  </field>
+                  <field>
+                     <name>EPDIS</name>
+                     <description>Endpoint disable</description>
+                     <bitOffset>30</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>EPENA</name>
+                     <description>Endpoint enable</description>
+                     <bitOffset>31</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_HS_DOEPINT0</name>
+               <displayName>OTG_HS_DOEPINT0</displayName>
+               <description>OTG_HS device endpoint-0 interrupt           register</description>
+               <addressOffset>0x308</addressOffset>
+               <size>32</size>
+               <access>read-write</access>
+               <resetValue>0x00000080</resetValue>
+               <fields>
+                  <field>
+                     <name>XFRC</name>
+                     <description>Transfer completed               interrupt</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>EPDISD</name>
+                     <description>Endpoint disabled               interrupt</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>STUP</name>
+                     <description>SETUP phase done</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>OTEPDIS</name>
+                     <description>OUT token received when endpoint               disabled</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>B2BSTUP</name>
+                     <description>Back-to-back SETUP packets               received</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>NYET</name>
+                     <description>NYET interrupt</description>
+                     <bitOffset>14</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_HS_DOEPINT1</name>
+               <displayName>OTG_HS_DOEPINT1</displayName>
+               <description>OTG_HS device endpoint-1 interrupt           register</description>
+               <addressOffset>0x328</addressOffset>
+               <size>32</size>
+               <access>read-write</access>
+               <resetValue>0x0</resetValue>
+               <fields>
+                  <field>
+                     <name>XFRC</name>
+                     <description>Transfer completed               interrupt</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>EPDISD</name>
+                     <description>Endpoint disabled               interrupt</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>STUP</name>
+                     <description>SETUP phase done</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>OTEPDIS</name>
+                     <description>OUT token received when endpoint               disabled</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>B2BSTUP</name>
+                     <description>Back-to-back SETUP packets               received</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>NYET</name>
+                     <description>NYET interrupt</description>
+                     <bitOffset>14</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_HS_DOEPINT2</name>
+               <displayName>OTG_HS_DOEPINT2</displayName>
+               <description>OTG_HS device endpoint-2 interrupt           register</description>
+               <addressOffset>0x348</addressOffset>
+               <size>32</size>
+               <access>read-write</access>
+               <resetValue>0x0</resetValue>
+               <fields>
+                  <field>
+                     <name>XFRC</name>
+                     <description>Transfer completed               interrupt</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>EPDISD</name>
+                     <description>Endpoint disabled               interrupt</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>STUP</name>
+                     <description>SETUP phase done</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>OTEPDIS</name>
+                     <description>OUT token received when endpoint               disabled</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>B2BSTUP</name>
+                     <description>Back-to-back SETUP packets               received</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>NYET</name>
+                     <description>NYET interrupt</description>
+                     <bitOffset>14</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_HS_DOEPINT3</name>
+               <displayName>OTG_HS_DOEPINT3</displayName>
+               <description>OTG_HS device endpoint-3 interrupt           register</description>
+               <addressOffset>0x368</addressOffset>
+               <size>32</size>
+               <access>read-write</access>
+               <resetValue>0x0</resetValue>
+               <fields>
+                  <field>
+                     <name>XFRC</name>
+                     <description>Transfer completed               interrupt</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>EPDISD</name>
+                     <description>Endpoint disabled               interrupt</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>STUP</name>
+                     <description>SETUP phase done</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>OTEPDIS</name>
+                     <description>OUT token received when endpoint               disabled</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>B2BSTUP</name>
+                     <description>Back-to-back SETUP packets               received</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>NYET</name>
+                     <description>NYET interrupt</description>
+                     <bitOffset>14</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_HS_DOEPINT4</name>
+               <displayName>OTG_HS_DOEPINT4</displayName>
+               <description>OTG_HS device endpoint-4 interrupt           register</description>
+               <addressOffset>0x388</addressOffset>
+               <size>32</size>
+               <access>read-write</access>
+               <resetValue>0x0</resetValue>
+               <fields>
+                  <field>
+                     <name>XFRC</name>
+                     <description>Transfer completed               interrupt</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>EPDISD</name>
+                     <description>Endpoint disabled               interrupt</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>STUP</name>
+                     <description>SETUP phase done</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>OTEPDIS</name>
+                     <description>OUT token received when endpoint               disabled</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>B2BSTUP</name>
+                     <description>Back-to-back SETUP packets               received</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>NYET</name>
+                     <description>NYET interrupt</description>
+                     <bitOffset>14</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_HS_DOEPINT5</name>
+               <displayName>OTG_HS_DOEPINT5</displayName>
+               <description>OTG_HS device endpoint-5 interrupt           register</description>
+               <addressOffset>0x3A8</addressOffset>
+               <size>32</size>
+               <access>read-write</access>
+               <resetValue>0x0</resetValue>
+               <fields>
+                  <field>
+                     <name>XFRC</name>
+                     <description>Transfer completed               interrupt</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>EPDISD</name>
+                     <description>Endpoint disabled               interrupt</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>STUP</name>
+                     <description>SETUP phase done</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>OTEPDIS</name>
+                     <description>OUT token received when endpoint               disabled</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>B2BSTUP</name>
+                     <description>Back-to-back SETUP packets               received</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>NYET</name>
+                     <description>NYET interrupt</description>
+                     <bitOffset>14</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_HS_DOEPINT6</name>
+               <displayName>OTG_HS_DOEPINT6</displayName>
+               <description>OTG_HS device endpoint-6 interrupt           register</description>
+               <addressOffset>0x3C8</addressOffset>
+               <size>32</size>
+               <access>read-write</access>
+               <resetValue>0x0</resetValue>
+               <fields>
+                  <field>
+                     <name>XFRC</name>
+                     <description>Transfer completed               interrupt</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>EPDISD</name>
+                     <description>Endpoint disabled               interrupt</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>STUP</name>
+                     <description>SETUP phase done</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>OTEPDIS</name>
+                     <description>OUT token received when endpoint               disabled</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>B2BSTUP</name>
+                     <description>Back-to-back SETUP packets               received</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>NYET</name>
+                     <description>NYET interrupt</description>
+                     <bitOffset>14</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_HS_DOEPINT7</name>
+               <displayName>OTG_HS_DOEPINT7</displayName>
+               <description>OTG_HS device endpoint-7 interrupt           register</description>
+               <addressOffset>0x3E8</addressOffset>
+               <size>32</size>
+               <access>read-write</access>
+               <resetValue>0x0</resetValue>
+               <fields>
+                  <field>
+                     <name>XFRC</name>
+                     <description>Transfer completed               interrupt</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>EPDISD</name>
+                     <description>Endpoint disabled               interrupt</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>STUP</name>
+                     <description>SETUP phase done</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>OTEPDIS</name>
+                     <description>OUT token received when endpoint               disabled</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>B2BSTUP</name>
+                     <description>Back-to-back SETUP packets               received</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>NYET</name>
+                     <description>NYET interrupt</description>
+                     <bitOffset>14</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_HS_DOEPTSIZ0</name>
+               <displayName>OTG_HS_DOEPTSIZ0</displayName>
+               <description>OTG_HS device endpoint-0 transfer size           register</description>
+               <addressOffset>0x310</addressOffset>
+               <size>32</size>
+               <access>read-write</access>
+               <resetValue>0x0</resetValue>
+               <fields>
+                  <field>
+                     <name>XFRSIZ</name>
+                     <description>Transfer size</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>7</bitWidth>
+                  </field>
+                  <field>
+                     <name>PKTCNT</name>
+                     <description>Packet count</description>
+                     <bitOffset>19</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>STUPCNT</name>
+                     <description>SETUP packet count</description>
+                     <bitOffset>29</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_HS_DOEPTSIZ1</name>
+               <displayName>OTG_HS_DOEPTSIZ1</displayName>
+               <description>OTG_HS device endpoint-1 transfer size           register</description>
+               <addressOffset>0x330</addressOffset>
+               <size>32</size>
+               <access>read-write</access>
+               <resetValue>0x0</resetValue>
+               <fields>
+                  <field>
+                     <name>XFRSIZ</name>
+                     <description>Transfer size</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>19</bitWidth>
+                  </field>
+                  <field>
+                     <name>PKTCNT</name>
+                     <description>Packet count</description>
+                     <bitOffset>19</bitOffset>
+                     <bitWidth>10</bitWidth>
+                  </field>
+                  <field>
+                     <name>RXDPID_STUPCNT</name>
+                     <description>Received data PID/SETUP packet               count</description>
+                     <bitOffset>29</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_HS_DOEPTSIZ2</name>
+               <displayName>OTG_HS_DOEPTSIZ2</displayName>
+               <description>OTG_HS device endpoint-2 transfer size           register</description>
+               <addressOffset>0x350</addressOffset>
+               <size>32</size>
+               <access>read-write</access>
+               <resetValue>0x0</resetValue>
+               <fields>
+                  <field>
+                     <name>XFRSIZ</name>
+                     <description>Transfer size</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>19</bitWidth>
+                  </field>
+                  <field>
+                     <name>PKTCNT</name>
+                     <description>Packet count</description>
+                     <bitOffset>19</bitOffset>
+                     <bitWidth>10</bitWidth>
+                  </field>
+                  <field>
+                     <name>RXDPID_STUPCNT</name>
+                     <description>Received data PID/SETUP packet               count</description>
+                     <bitOffset>29</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_HS_DOEPTSIZ3</name>
+               <displayName>OTG_HS_DOEPTSIZ3</displayName>
+               <description>OTG_HS device endpoint-3 transfer size           register</description>
+               <addressOffset>0x370</addressOffset>
+               <size>32</size>
+               <access>read-write</access>
+               <resetValue>0x0</resetValue>
+               <fields>
+                  <field>
+                     <name>XFRSIZ</name>
+                     <description>Transfer size</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>19</bitWidth>
+                  </field>
+                  <field>
+                     <name>PKTCNT</name>
+                     <description>Packet count</description>
+                     <bitOffset>19</bitOffset>
+                     <bitWidth>10</bitWidth>
+                  </field>
+                  <field>
+                     <name>RXDPID_STUPCNT</name>
+                     <description>Received data PID/SETUP packet               count</description>
+                     <bitOffset>29</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_HS_DOEPTSIZ4</name>
+               <displayName>OTG_HS_DOEPTSIZ4</displayName>
+               <description>OTG_HS device endpoint-4 transfer size           register</description>
+               <addressOffset>0x390</addressOffset>
+               <size>32</size>
+               <access>read-write</access>
+               <resetValue>0x0</resetValue>
+               <fields>
+                  <field>
+                     <name>XFRSIZ</name>
+                     <description>Transfer size</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>19</bitWidth>
+                  </field>
+                  <field>
+                     <name>PKTCNT</name>
+                     <description>Packet count</description>
+                     <bitOffset>19</bitOffset>
+                     <bitWidth>10</bitWidth>
+                  </field>
+                  <field>
+                     <name>RXDPID_STUPCNT</name>
+                     <description>Received data PID/SETUP packet               count</description>
+                     <bitOffset>29</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_HS_DIEPTSIZ6</name>
+               <displayName>OTG_HS_DIEPTSIZ6</displayName>
+               <description>OTG_HS device endpoint transfer size           register</description>
+               <alternateRegister>OTG_HS_DIEPCTL5</alternateRegister>
+               <addressOffset>0x1A0</addressOffset>
+               <size>32</size>
+               <access>read-write</access>
+               <resetValue>0x0</resetValue>
+               <fields>
+                  <field>
+                     <name>XFRSIZ</name>
+                     <description>Transfer size</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>19</bitWidth>
+                  </field>
+                  <field>
+                     <name>PKTCNT</name>
+                     <description>Packet count</description>
+                     <bitOffset>19</bitOffset>
+                     <bitWidth>10</bitWidth>
+                  </field>
+                  <field>
+                     <name>MCNT</name>
+                     <description>Multi count</description>
+                     <bitOffset>29</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_HS_DTXFSTS6</name>
+               <displayName>OTG_HS_DTXFSTS6</displayName>
+               <description>OTG_HS device IN endpoint transmit FIFO           status register</description>
+               <addressOffset>0x1A4</addressOffset>
+               <size>32</size>
+               <access>read-write</access>
+               <resetValue>0x0</resetValue>
+               <fields>
+                  <field>
+                     <name>INEPTFSAV</name>
+                     <description>IN endpoint TxFIFO space               avail</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_HS_DIEPTSIZ7</name>
+               <displayName>OTG_HS_DIEPTSIZ7</displayName>
+               <description>OTG_HS device endpoint transfer size           register</description>
+               <alternateRegister>OTG_HS_DIEPINT5</alternateRegister>
+               <addressOffset>0x1A8</addressOffset>
+               <size>32</size>
+               <access>read-write</access>
+               <resetValue>0x0</resetValue>
+               <fields>
+                  <field>
+                     <name>XFRSIZ</name>
+                     <description>Transfer size</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>19</bitWidth>
+                  </field>
+                  <field>
+                     <name>PKTCNT</name>
+                     <description>Packet count</description>
+                     <bitOffset>19</bitOffset>
+                     <bitWidth>10</bitWidth>
+                  </field>
+                  <field>
+                     <name>MCNT</name>
+                     <description>Multi count</description>
+                     <bitOffset>29</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_HS_DTXFSTS7</name>
+               <displayName>OTG_HS_DTXFSTS7</displayName>
+               <description>OTG_HS device IN endpoint transmit FIFO           status register</description>
+               <addressOffset>0x1AC</addressOffset>
+               <size>32</size>
+               <access>read-write</access>
+               <resetValue>0x0</resetValue>
+               <fields>
+                  <field>
+                     <name>INEPTFSAV</name>
+                     <description>IN endpoint TxFIFO space               avail</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_HS_DOEPCTL4</name>
+               <displayName>OTG_HS_DOEPCTL4</displayName>
+               <description>OTG device endpoint-4 control           register</description>
+               <addressOffset>0x380</addressOffset>
+               <size>32</size>
+               <resetValue>0x0</resetValue>
+               <fields>
+                  <field>
+                     <name>MPSIZ</name>
+                     <description>Maximum packet size</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>11</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>USBAEP</name>
+                     <description>USB active endpoint</description>
+                     <bitOffset>15</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>EONUM_DPID</name>
+                     <description>Even odd frame/Endpoint data               PID</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-only</access>
+                  </field>
+                  <field>
+                     <name>NAKSTS</name>
+                     <description>NAK status</description>
+                     <bitOffset>17</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-only</access>
+                  </field>
+                  <field>
+                     <name>EPTYP</name>
+                     <description>Endpoint type</description>
+                     <bitOffset>18</bitOffset>
+                     <bitWidth>2</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>SNPM</name>
+                     <description>Snoop mode</description>
+                     <bitOffset>20</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>Stall</name>
+                     <description>STALL handshake</description>
+                     <bitOffset>21</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>CNAK</name>
+                     <description>Clear NAK</description>
+                     <bitOffset>26</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>write-only</access>
+                  </field>
+                  <field>
+                     <name>SNAK</name>
+                     <description>Set NAK</description>
+                     <bitOffset>27</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>write-only</access>
+                  </field>
+                  <field>
+                     <name>SD0PID_SEVNFRM</name>
+                     <description>Set DATA0 PID/Set even               frame</description>
+                     <bitOffset>28</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>write-only</access>
+                  </field>
+                  <field>
+                     <name>SODDFRM</name>
+                     <description>Set odd frame</description>
+                     <bitOffset>29</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>write-only</access>
+                  </field>
+                  <field>
+                     <name>EPDIS</name>
+                     <description>Endpoint disable</description>
+                     <bitOffset>30</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>EPENA</name>
+                     <description>Endpoint enable</description>
+                     <bitOffset>31</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_HS_DOEPCTL5</name>
+               <displayName>OTG_HS_DOEPCTL5</displayName>
+               <description>OTG device endpoint-5 control           register</description>
+               <addressOffset>0x3A0</addressOffset>
+               <size>32</size>
+               <resetValue>0x0</resetValue>
+               <fields>
+                  <field>
+                     <name>MPSIZ</name>
+                     <description>Maximum packet size</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>11</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>USBAEP</name>
+                     <description>USB active endpoint</description>
+                     <bitOffset>15</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>EONUM_DPID</name>
+                     <description>Even odd frame/Endpoint data               PID</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-only</access>
+                  </field>
+                  <field>
+                     <name>NAKSTS</name>
+                     <description>NAK status</description>
+                     <bitOffset>17</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-only</access>
+                  </field>
+                  <field>
+                     <name>EPTYP</name>
+                     <description>Endpoint type</description>
+                     <bitOffset>18</bitOffset>
+                     <bitWidth>2</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>SNPM</name>
+                     <description>Snoop mode</description>
+                     <bitOffset>20</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>Stall</name>
+                     <description>STALL handshake</description>
+                     <bitOffset>21</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>CNAK</name>
+                     <description>Clear NAK</description>
+                     <bitOffset>26</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>write-only</access>
+                  </field>
+                  <field>
+                     <name>SNAK</name>
+                     <description>Set NAK</description>
+                     <bitOffset>27</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>write-only</access>
+                  </field>
+                  <field>
+                     <name>SD0PID_SEVNFRM</name>
+                     <description>Set DATA0 PID/Set even               frame</description>
+                     <bitOffset>28</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>write-only</access>
+                  </field>
+                  <field>
+                     <name>SODDFRM</name>
+                     <description>Set odd frame</description>
+                     <bitOffset>29</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>write-only</access>
+                  </field>
+                  <field>
+                     <name>EPDIS</name>
+                     <description>Endpoint disable</description>
+                     <bitOffset>30</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>EPENA</name>
+                     <description>Endpoint enable</description>
+                     <bitOffset>31</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_HS_DOEPCTL6</name>
+               <displayName>OTG_HS_DOEPCTL6</displayName>
+               <description>OTG device endpoint-6 control           register</description>
+               <addressOffset>0x3C0</addressOffset>
+               <size>32</size>
+               <resetValue>0x0</resetValue>
+               <fields>
+                  <field>
+                     <name>MPSIZ</name>
+                     <description>Maximum packet size</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>11</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>USBAEP</name>
+                     <description>USB active endpoint</description>
+                     <bitOffset>15</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>EONUM_DPID</name>
+                     <description>Even odd frame/Endpoint data               PID</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-only</access>
+                  </field>
+                  <field>
+                     <name>NAKSTS</name>
+                     <description>NAK status</description>
+                     <bitOffset>17</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-only</access>
+                  </field>
+                  <field>
+                     <name>EPTYP</name>
+                     <description>Endpoint type</description>
+                     <bitOffset>18</bitOffset>
+                     <bitWidth>2</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>SNPM</name>
+                     <description>Snoop mode</description>
+                     <bitOffset>20</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>Stall</name>
+                     <description>STALL handshake</description>
+                     <bitOffset>21</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>CNAK</name>
+                     <description>Clear NAK</description>
+                     <bitOffset>26</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>write-only</access>
+                  </field>
+                  <field>
+                     <name>SNAK</name>
+                     <description>Set NAK</description>
+                     <bitOffset>27</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>write-only</access>
+                  </field>
+                  <field>
+                     <name>SD0PID_SEVNFRM</name>
+                     <description>Set DATA0 PID/Set even               frame</description>
+                     <bitOffset>28</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>write-only</access>
+                  </field>
+                  <field>
+                     <name>SODDFRM</name>
+                     <description>Set odd frame</description>
+                     <bitOffset>29</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>write-only</access>
+                  </field>
+                  <field>
+                     <name>EPDIS</name>
+                     <description>Endpoint disable</description>
+                     <bitOffset>30</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>EPENA</name>
+                     <description>Endpoint enable</description>
+                     <bitOffset>31</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_HS_DOEPCTL7</name>
+               <displayName>OTG_HS_DOEPCTL7</displayName>
+               <description>OTG device endpoint-7 control           register</description>
+               <addressOffset>0x3E0</addressOffset>
+               <size>32</size>
+               <resetValue>0x0</resetValue>
+               <fields>
+                  <field>
+                     <name>MPSIZ</name>
+                     <description>Maximum packet size</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>11</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>USBAEP</name>
+                     <description>USB active endpoint</description>
+                     <bitOffset>15</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>EONUM_DPID</name>
+                     <description>Even odd frame/Endpoint data               PID</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-only</access>
+                  </field>
+                  <field>
+                     <name>NAKSTS</name>
+                     <description>NAK status</description>
+                     <bitOffset>17</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-only</access>
+                  </field>
+                  <field>
+                     <name>EPTYP</name>
+                     <description>Endpoint type</description>
+                     <bitOffset>18</bitOffset>
+                     <bitWidth>2</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>SNPM</name>
+                     <description>Snoop mode</description>
+                     <bitOffset>20</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>Stall</name>
+                     <description>STALL handshake</description>
+                     <bitOffset>21</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>CNAK</name>
+                     <description>Clear NAK</description>
+                     <bitOffset>26</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>write-only</access>
+                  </field>
+                  <field>
+                     <name>SNAK</name>
+                     <description>Set NAK</description>
+                     <bitOffset>27</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>write-only</access>
+                  </field>
+                  <field>
+                     <name>SD0PID_SEVNFRM</name>
+                     <description>Set DATA0 PID/Set even               frame</description>
+                     <bitOffset>28</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>write-only</access>
+                  </field>
+                  <field>
+                     <name>SODDFRM</name>
+                     <description>Set odd frame</description>
+                     <bitOffset>29</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>write-only</access>
+                  </field>
+                  <field>
+                     <name>EPDIS</name>
+                     <description>Endpoint disable</description>
+                     <bitOffset>30</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+                  <field>
+                     <name>EPENA</name>
+                     <description>Endpoint enable</description>
+                     <bitOffset>31</bitOffset>
+                     <bitWidth>1</bitWidth>
+                     <access>read-write</access>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_HS_DOEPTSIZ5</name>
+               <displayName>OTG_HS_DOEPTSIZ5</displayName>
+               <description>OTG_HS device endpoint-5 transfer size           register</description>
+               <addressOffset>0x3B0</addressOffset>
+               <size>32</size>
+               <access>read-write</access>
+               <resetValue>0x0</resetValue>
+               <fields>
+                  <field>
+                     <name>XFRSIZ</name>
+                     <description>Transfer size</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>19</bitWidth>
+                  </field>
+                  <field>
+                     <name>PKTCNT</name>
+                     <description>Packet count</description>
+                     <bitOffset>19</bitOffset>
+                     <bitWidth>10</bitWidth>
+                  </field>
+                  <field>
+                     <name>RXDPID_STUPCNT</name>
+                     <description>Received data PID/SETUP packet               count</description>
+                     <bitOffset>29</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_HS_DOEPTSIZ6</name>
+               <displayName>OTG_HS_DOEPTSIZ6</displayName>
+               <description>OTG_HS device endpoint-6 transfer size           register</description>
+               <addressOffset>0x3D0</addressOffset>
+               <size>32</size>
+               <access>read-write</access>
+               <resetValue>0x0</resetValue>
+               <fields>
+                  <field>
+                     <name>XFRSIZ</name>
+                     <description>Transfer size</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>19</bitWidth>
+                  </field>
+                  <field>
+                     <name>PKTCNT</name>
+                     <description>Packet count</description>
+                     <bitOffset>19</bitOffset>
+                     <bitWidth>10</bitWidth>
+                  </field>
+                  <field>
+                     <name>RXDPID_STUPCNT</name>
+                     <description>Received data PID/SETUP packet               count</description>
+                     <bitOffset>29</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>OTG_HS_DOEPTSIZ7</name>
+               <displayName>OTG_HS_DOEPTSIZ7</displayName>
+               <description>OTG_HS device endpoint-7 transfer size           register</description>
+               <addressOffset>0x3F0</addressOffset>
+               <size>32</size>
+               <access>read-write</access>
+               <resetValue>0x0</resetValue>
+               <fields>
+                  <field>
+                     <name>XFRSIZ</name>
+                     <description>Transfer size</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>19</bitWidth>
+                  </field>
+                  <field>
+                     <name>PKTCNT</name>
+                     <description>Packet count</description>
+                     <bitOffset>19</bitOffset>
+                     <bitWidth>10</bitWidth>
+                  </field>
+                  <field>
+                     <name>RXDPID_STUPCNT</name>
+                     <description>Received data PID/SETUP packet               count</description>
+                     <bitOffset>29</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+               </fields>
+            </register>
+         </registers>
+      </peripheral>
+      <peripheral>
+         <name>OTG_HS_PWRCLK</name>
+         <description>USB on the go high speed</description>
+         <groupName>USB_OTG_HS</groupName>
+         <baseAddress>0x40040E00</baseAddress>
+         <addressBlock>
+            <offset>0x0</offset>
+            <size>0x3F200</size>
+            <usage>registers</usage>
+         </addressBlock>
+         <registers>
+            <register>
+               <name>OTG_HS_PCGCR</name>
+               <displayName>OTG_HS_PCGCR</displayName>
+               <description>Power and clock gating control           register</description>
+               <addressOffset>0x0</addressOffset>
+               <size>32</size>
+               <access>read-write</access>
+               <resetValue>0x0</resetValue>
+               <fields>
+                  <field>
+                     <name>STPPCLK</name>
+                     <description>Stop PHY clock</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>GATEHCLK</name>
+                     <description>Gate HCLK</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>PHYSUSP</name>
+                     <description>PHY suspended</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+         </registers>
+      </peripheral>
+      <peripheral>
+         <name>DSI</name>
+         <description>DSI Host</description>
+         <groupName>DSI</groupName>
+         <baseAddress>0x40016C00</baseAddress>
+         <addressBlock>
+            <offset>0x0</offset>
+            <size>0x800</size>
+            <usage>registers</usage>
+         </addressBlock>
+         <interrupt>
+            <name>DSIHOST</name>
+            <description>DSI host global interrupt</description>
+            <value>98</value>
+         </interrupt>
+         <registers>
+            <register>
+               <name>DSI_VR</name>
+               <displayName>DSI_VR</displayName>
+               <description>DSI Host Version Register</description>
+               <addressOffset>0x0</addressOffset>
+               <size>0x20</size>
+               <access>read-only</access>
+               <resetValue>0x3133302A</resetValue>
+               <fields>
+                  <field>
+                     <name>VERSION</name>
+                     <description>Version of the DSI Host</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DSI_CR</name>
+               <displayName>DSI_CR</displayName>
+               <description>DSI Host Control Register</description>
+               <addressOffset>0x4</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>EN</name>
+                     <description>Enable</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DSI_CCR</name>
+               <displayName>DSI_CCR</displayName>
+               <description>DSI HOST Clock Control           Register</description>
+               <addressOffset>0x8</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>TXECKDIV</name>
+                     <description>TX Escape Clock Division</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+                  <field>
+                     <name>TOCKDIV</name>
+                     <description>Timeout Clock Division</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DSI_LVCIDR</name>
+               <displayName>DSI_LVCIDR</displayName>
+               <description>DSI Host LTDC VCID Register</description>
+               <addressOffset>0xC</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>VCID</name>
+                     <description>Virtual Channel ID</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DSI_LCOLCR</name>
+               <displayName>DSI_LCOLCR</displayName>
+               <description>DSI Host LTDC Color Coding           Register</description>
+               <addressOffset>0x10</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>COLC</name>
+                     <description>Color Coding</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+                  <field>
+                     <name>LPE</name>
+                     <description>Loosely Packet Enable</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DSI_LPCR</name>
+               <displayName>DSI_LPCR</displayName>
+               <description>DSI Host LTDC Polarity Configuration           Register</description>
+               <addressOffset>0x14</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DEP</name>
+                     <description>Data Enable Polarity</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>VSP</name>
+                     <description>VSYNC Polarity</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>HSP</name>
+                     <description>HSYNC Polarity</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DSI_LPMCR</name>
+               <displayName>DSI_LPMCR</displayName>
+               <description>DSI Host Low-Power mode Configuration           Register</description>
+               <addressOffset>0x18</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>VLPSIZE</name>
+                     <description>VACT Largest Packet Size</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+                  <field>
+                     <name>LPSIZE</name>
+                     <description>Largest Packet Size</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DSI_PCR</name>
+               <displayName>DSI_PCR</displayName>
+               <description>DSI Host Protocol Configuration           Register</description>
+               <addressOffset>0x2C</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>ETTXE</name>
+                     <description>EoTp Transmission Enable</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>ETRXE</name>
+                     <description>EoTp Reception Enable</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>BTAE</name>
+                     <description>Bus Turn Around Enable</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>ECCRXE</name>
+                     <description>ECC Reception Enable</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CRCRXE</name>
+                     <description>CRC Reception Enable</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DSI_GVCIDR</name>
+               <displayName>DSI_GVCIDR</displayName>
+               <description>DSI Host Generic VCID Register</description>
+               <addressOffset>0x30</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>VCID</name>
+                     <description>Virtual Channel ID</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DSI_MCR</name>
+               <displayName>DSI_MCR</displayName>
+               <description>DSI Host mode Configuration           Register</description>
+               <addressOffset>0x34</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>CMDM</name>
+                     <description>Command mode</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DSI_VMCR</name>
+               <displayName>DSI_VMCR</displayName>
+               <description>DSI Host Video mode Configuration           Register</description>
+               <addressOffset>0x38</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>VMT</name>
+                     <description>Video mode Type</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>LPVSAE</name>
+                     <description>Low-Power Vertical Sync Active               Enable</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>LPVBPE</name>
+                     <description>Low-power Vertical Back-Porch               Enable</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>LPVFPE</name>
+                     <description>Low-power Vertical Front-porch               Enable</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>LPVAE</name>
+                     <description>Low-Power Vertical Active               Enable</description>
+                     <bitOffset>11</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>LPHBPE</name>
+                     <description>Low-Power Horizontal Back-Porch               Enable</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>LPHFPE</name>
+                     <description>Low-Power Horizontal Front-Porch               Enable</description>
+                     <bitOffset>13</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FBTAAE</name>
+                     <description>Frame Bus-Turn-Around Acknowledge               Enable</description>
+                     <bitOffset>14</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>LPCE</name>
+                     <description>Low-Power Command Enable</description>
+                     <bitOffset>15</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>PGE</name>
+                     <description>Pattern Generator Enable</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>PGM</name>
+                     <description>Pattern Generator mode</description>
+                     <bitOffset>20</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>PGO</name>
+                     <description>Pattern Generator               Orientation</description>
+                     <bitOffset>24</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DSI_VPCR</name>
+               <displayName>DSI_VPCR</displayName>
+               <description>DSI Host Video Packet Configuration           Register</description>
+               <addressOffset>0x3C</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>VPSIZE</name>
+                     <description>Video Packet Size</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>14</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DSI_VCCR</name>
+               <displayName>DSI_VCCR</displayName>
+               <description>DSI Host Video Chunks Configuration           Register</description>
+               <addressOffset>0x40</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>NUMC</name>
+                     <description>Number of Chunks</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>13</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DSI_VNPCR</name>
+               <displayName>DSI_VNPCR</displayName>
+               <description>DSI Host Video Null Packet Configuration           Register</description>
+               <addressOffset>0x44</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>NPSIZE</name>
+                     <description>Null Packet Size</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>13</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DSI_VHSACR</name>
+               <displayName>DSI_VHSACR</displayName>
+               <description>DSI Host Video HSA Configuration           Register</description>
+               <addressOffset>0x48</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>HSA</name>
+                     <description>Horizontal Synchronism Active               duration</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>12</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DSI_VHBPCR</name>
+               <displayName>DSI_VHBPCR</displayName>
+               <description>DSI Host Video HBP Configuration           Register</description>
+               <addressOffset>0x4C</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>HBP</name>
+                     <description>Horizontal Back-Porch               duration</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>12</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DSI_VLCR</name>
+               <displayName>DSI_VLCR</displayName>
+               <description>DSI Host Video Line Configuration           Register</description>
+               <addressOffset>0x50</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>HLINE</name>
+                     <description>Horizontal Line duration</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>15</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DSI_VVSACR</name>
+               <displayName>DSI_VVSACR</displayName>
+               <description>DSI Host Video VSA Configuration           Register</description>
+               <addressOffset>0x54</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>VSA</name>
+                     <description>Vertical Synchronism Active               duration</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>10</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DSI_VVBPCR</name>
+               <displayName>DSI_VVBPCR</displayName>
+               <description>DSI Host Video VBP Configuration           Register</description>
+               <addressOffset>0x58</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>VBP</name>
+                     <description>Vertical Back-Porch               duration</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>10</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DSI_VVFPCR</name>
+               <displayName>DSI_VVFPCR</displayName>
+               <description>DSI Host Video VFP Configuration           Register</description>
+               <addressOffset>0x5C</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>VFP</name>
+                     <description>Vertical Front-Porch               duration</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>10</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DSI_VVACR</name>
+               <displayName>DSI_VVACR</displayName>
+               <description>DSI Host Video VA Configuration           Register</description>
+               <addressOffset>0x60</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>VA</name>
+                     <description>Vertical Active duration</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>14</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DSI_LCCR</name>
+               <displayName>DSI_LCCR</displayName>
+               <description>DSI Host LTDC Command Configuration           Register</description>
+               <addressOffset>0x64</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>CMDSIZE</name>
+                     <description>Command Size</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DSI_CMCR</name>
+               <displayName>DSI_CMCR</displayName>
+               <description>DSI Host Command mode Configuration           Register</description>
+               <addressOffset>0x68</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>TEARE</name>
+                     <description>Tearing Effect Acknowledge Request               Enable</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>ARE</name>
+                     <description>Acknowledge Request Enable</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>GSW0TX</name>
+                     <description>Generic Short Write Zero parameters               Transmission</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>GSW1TX</name>
+                     <description>Generic Short Write One parameters               Transmission</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>GSW2TX</name>
+                     <description>Generic Short Write Two parameters               Transmission</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>GSR0TX</name>
+                     <description>Generic Short Read Zero parameters               Transmission</description>
+                     <bitOffset>11</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>GSR1TX</name>
+                     <description>Generic Short Read One parameters               Transmission</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>GSR2TX</name>
+                     <description>Generic Short Read Two parameters               Transmission</description>
+                     <bitOffset>13</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>GLWTX</name>
+                     <description>Generic Long Write               Transmission</description>
+                     <bitOffset>14</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>DSW0TX</name>
+                     <description>DCS Short Write Zero parameter               Transmission</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>DSW1TX</name>
+                     <description>DCS Short Read One parameter               Transmission</description>
+                     <bitOffset>17</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>DSR0TX</name>
+                     <description>DCS Short Read Zero parameter               Transmission</description>
+                     <bitOffset>18</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>DLWTX</name>
+                     <description>DCS Long Write               Transmission</description>
+                     <bitOffset>19</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>MRDPS</name>
+                     <description>Maximum Read Packet Size</description>
+                     <bitOffset>24</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DSI_GHCR</name>
+               <displayName>DSI_GHCR</displayName>
+               <description>DSI Host Generic Header Configuration           Register</description>
+               <addressOffset>0x6C</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DT</name>
+                     <description>Type</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>6</bitWidth>
+                  </field>
+                  <field>
+                     <name>VCID</name>
+                     <description>Channel</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>WCLSB</name>
+                     <description>WordCount LSB</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+                  <field>
+                     <name>WCMSB</name>
+                     <description>WordCount MSB</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DSI_GPDR</name>
+               <displayName>DSI_GPDR</displayName>
+               <description>DSI Host Generic Payload Data           Register</description>
+               <addressOffset>0x70</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DATA1</name>
+                     <description>Payload Byte 1</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+                  <field>
+                     <name>DATA2</name>
+                     <description>Payload Byte 2</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+                  <field>
+                     <name>DATA3</name>
+                     <description>Payload Byte 3</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+                  <field>
+                     <name>DATA4</name>
+                     <description>Payload Byte 4</description>
+                     <bitOffset>24</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DSI_GPSR</name>
+               <displayName>DSI_GPSR</displayName>
+               <description>DSI Host Generic Packet Status           Register</description>
+               <addressOffset>0x74</addressOffset>
+               <size>0x20</size>
+               <access>read-only</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>CMDFE</name>
+                     <description>Command FIFO Empty</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CMDFF</name>
+                     <description>Command FIFO Full</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>PWRFE</name>
+                     <description>Payload Write FIFO Empty</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>PWRFF</name>
+                     <description>Payload Write FIFO Full</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>PRDFE</name>
+                     <description>Payload Read FIFO Empty</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>PRDFF</name>
+                     <description>Payload Read FIFO Full</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>RCB</name>
+                     <description>Read Command Busy</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DSI_TCCR0</name>
+               <displayName>DSI_TCCR0</displayName>
+               <description>DSI Host Timeout Counter Configuration           Register 0</description>
+               <addressOffset>0x78</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>LPRX_TOCNT</name>
+                     <description>Low-power Reception Timeout               Counter</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+                  <field>
+                     <name>HSTX_TOCNT</name>
+                     <description>High-Speed Transmission Timeout               Counter</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DSI_TCCR1</name>
+               <displayName>DSI_TCCR1</displayName>
+               <description>DSI Host Timeout Counter Configuration           Register 1</description>
+               <addressOffset>0x7C</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>HSRD_TOCNT</name>
+                     <description>High-Speed Read Timeout               Counter</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DSI_TCCR2</name>
+               <displayName>DSI_TCCR2</displayName>
+               <description>DSI Host Timeout Counter Configuration           Register 2</description>
+               <addressOffset>0x80</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>LPRD_TOCNT</name>
+                     <description>Low-Power Read Timeout               Counter</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DSI_TCCR3</name>
+               <displayName>DSI_TCCR3</displayName>
+               <description>DSI Host Timeout Counter Configuration           Register 3</description>
+               <addressOffset>0x84</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>HSWR_TOCNT</name>
+                     <description>High-Speed Write Timeout               Counter</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+                  <field>
+                     <name>PM</name>
+                     <description>Presp mode</description>
+                     <bitOffset>24</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DSI_TCCR4</name>
+               <displayName>DSI_TCCR4</displayName>
+               <description>DSI Host Timeout Counter Configuration           Register 4</description>
+               <addressOffset>0x88</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>LSWR_TOCNT</name>
+                     <description>Low-Power Write Timeout               Counter</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DSI_TCCR5</name>
+               <displayName>DSI_TCCR5</displayName>
+               <description>DSI Host Timeout Counter Configuration           Register 5</description>
+               <addressOffset>0x8C</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>BTA_TOCNT</name>
+                     <description>Bus-Turn-Around Timeout               Counter</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DSI_CLCR</name>
+               <displayName>DSI_CLCR</displayName>
+               <description>DSI Host Clock Lane Configuration           Register</description>
+               <addressOffset>0x94</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DPCC</name>
+                     <description>D-PHY Clock Control</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>ACR</name>
+                     <description>Automatic Clock lane               Control</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DSI_CLTCR</name>
+               <displayName>DSI_CLTCR</displayName>
+               <description>DSI Host Clock Lane Timer Configuration           Register</description>
+               <addressOffset>0x98</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>LP2HS_TIME</name>
+                     <description>Low-Power to High-Speed               Time</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>10</bitWidth>
+                  </field>
+                  <field>
+                     <name>HS2LP_TIME</name>
+                     <description>High-Speed to Low-Power               Time</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>10</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DSI_DLTCR</name>
+               <displayName>DSI_DLTCR</displayName>
+               <description>DSI Host Data Lane Timer Configuration           Register</description>
+               <addressOffset>0x9C</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>MRD_TIME</name>
+                     <description>Maximum Read Time</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>15</bitWidth>
+                  </field>
+                  <field>
+                     <name>LP2HS_TIME</name>
+                     <description>Low-Power To High-Speed               Time</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+                  <field>
+                     <name>HS2LP_TIME</name>
+                     <description>High-Speed To Low-Power               Time</description>
+                     <bitOffset>24</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DSI_PCTLR</name>
+               <displayName>DSI_PCTLR</displayName>
+               <description>DSI Host PHY Control Register</description>
+               <addressOffset>0xA0</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DEN</name>
+                     <description>Digital Enable</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CKE</name>
+                     <description>Clock Enable</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DSI_PCONFR</name>
+               <displayName>DSI_PCONFR</displayName>
+               <description>DSI Host PHY Configuration           Register</description>
+               <addressOffset>0xA4</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>NL</name>
+                     <description>Number of Lanes</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>SW_TIME</name>
+                     <description>Stop Wait Time</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DSI_PUCR</name>
+               <displayName>DSI_PUCR</displayName>
+               <description>DSI Host PHY ULPS Control           Register</description>
+               <addressOffset>0xA8</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>URCL</name>
+                     <description>ULPS Request on Clock Lane</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>UECL</name>
+                     <description>ULPS Exit on Clock Lane</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>URDL</name>
+                     <description>ULPS Request on Data Lane</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>UEDL</name>
+                     <description>ULPS Exit on Data Lane</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DSI_PTTCR</name>
+               <displayName>DSI_PTTCR</displayName>
+               <description>DSI Host PHY TX Triggers Configuration           Register</description>
+               <addressOffset>0xAC</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>TX_TRIG</name>
+                     <description>Transmission Trigger</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DSI_PSR</name>
+               <displayName>DSI_PSR</displayName>
+               <description>DSI Host PHY Status Register</description>
+               <addressOffset>0xB0</addressOffset>
+               <size>0x20</size>
+               <access>read-only</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>PD</name>
+                     <description>PHY Direction</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>PSSC</name>
+                     <description>PHY Stop State Clock lane</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>UANC</name>
+                     <description>ULPS Active Not Clock lane</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>PSS0</name>
+                     <description>PHY Stop State lane 0</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>UAN0</name>
+                     <description>ULPS Active Not lane 1</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>RUE0</name>
+                     <description>RX ULPS Escape lane 0</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>PSS1</name>
+                     <description>PHY Stop State lane 1</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>UAN1</name>
+                     <description>ULPS Active Not lane 1</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DSI_ISR0</name>
+               <displayName>DSI_ISR0</displayName>
+               <description>DSI Host Interrupt &amp; Status Register           0</description>
+               <addressOffset>0xBC</addressOffset>
+               <size>0x20</size>
+               <access>read-only</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>AE0</name>
+                     <description>Acknowledge Error 0</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>AE1</name>
+                     <description>Acknowledge Error 1</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>AE2</name>
+                     <description>Acknowledge Error 2</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>AE3</name>
+                     <description>Acknowledge Error 3</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>AE4</name>
+                     <description>Acknowledge Error 4</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>AE5</name>
+                     <description>Acknowledge Error 5</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>AE6</name>
+                     <description>Acknowledge Error 6</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>AE7</name>
+                     <description>Acknowledge Error 7</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>AE8</name>
+                     <description>Acknowledge Error 8</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>AE9</name>
+                     <description>Acknowledge Error 9</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>AE10</name>
+                     <description>Acknowledge Error 10</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>AE11</name>
+                     <description>Acknowledge Error 11</description>
+                     <bitOffset>11</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>AE12</name>
+                     <description>Acknowledge Error 12</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>AE13</name>
+                     <description>Acknowledge Error 13</description>
+                     <bitOffset>13</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>AE14</name>
+                     <description>Acknowledge Error 14</description>
+                     <bitOffset>14</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>AE15</name>
+                     <description>Acknowledge Error 15</description>
+                     <bitOffset>15</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>PE0</name>
+                     <description>PHY Error 0</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>PE1</name>
+                     <description>PHY Error 1</description>
+                     <bitOffset>17</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>PE2</name>
+                     <description>PHY Error 2</description>
+                     <bitOffset>18</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>PE3</name>
+                     <description>PHY Error 3</description>
+                     <bitOffset>19</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>PE4</name>
+                     <description>PHY Error 4</description>
+                     <bitOffset>20</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DSI_ISR1</name>
+               <displayName>DSI_ISR1</displayName>
+               <description>DSI Host Interrupt &amp; Status Register           1</description>
+               <addressOffset>0xC0</addressOffset>
+               <size>0x20</size>
+               <access>read-only</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>TOHSTX</name>
+                     <description>Timeout High-Speed               Transmission</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TOLPRX</name>
+                     <description>Timeout Low-Power               Reception</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>ECCSE</name>
+                     <description>ECC Single-bit Error</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>ECCME</name>
+                     <description>ECC Multi-bit Error</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CRCE</name>
+                     <description>CRC Error</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>PSE</name>
+                     <description>Packet Size Error</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>EOTPE</name>
+                     <description>EoTp Error</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>LPWRE</name>
+                     <description>LTDC Payload Write Error</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>GCWRE</name>
+                     <description>Generic Command Write               Error</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>GPWRE</name>
+                     <description>Generic Payload Write               Error</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>GPTXE</name>
+                     <description>Generic Payload Transmit               Error</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>GPRDE</name>
+                     <description>Generic Payload Read Error</description>
+                     <bitOffset>11</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>GPRXE</name>
+                     <description>Generic Payload Receive               Error</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DSI_IER0</name>
+               <displayName>DSI_IER0</displayName>
+               <description>DSI Host Interrupt Enable Register           0</description>
+               <addressOffset>0xC4</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>AE0IE</name>
+                     <description>Acknowledge Error 0 Interrupt               Enable</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>AE1IE</name>
+                     <description>Acknowledge Error 1 Interrupt               Enable</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>AE2IE</name>
+                     <description>Acknowledge Error 2 Interrupt               Enable</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>AE3IE</name>
+                     <description>Acknowledge Error 3 Interrupt               Enable</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>AE4IE</name>
+                     <description>Acknowledge Error 4 Interrupt               Enable</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>AE5IE</name>
+                     <description>Acknowledge Error 5 Interrupt               Enable</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>AE6IE</name>
+                     <description>Acknowledge Error 6 Interrupt               Enable</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>AE7IE</name>
+                     <description>Acknowledge Error 7 Interrupt               Enable</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>AE8IE</name>
+                     <description>Acknowledge Error 8 Interrupt               Enable</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>AE9IE</name>
+                     <description>Acknowledge Error 9 Interrupt               Enable</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>AE10IE</name>
+                     <description>Acknowledge Error 10 Interrupt               Enable</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>AE11IE</name>
+                     <description>Acknowledge Error 11 Interrupt               Enable</description>
+                     <bitOffset>11</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>AE12IE</name>
+                     <description>Acknowledge Error 12 Interrupt               Enable</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>AE13IE</name>
+                     <description>Acknowledge Error 13 Interrupt               Enable</description>
+                     <bitOffset>13</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>AE14IE</name>
+                     <description>Acknowledge Error 14 Interrupt               Enable</description>
+                     <bitOffset>14</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>AE15IE</name>
+                     <description>Acknowledge Error 15 Interrupt               Enable</description>
+                     <bitOffset>15</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>PE0IE</name>
+                     <description>PHY Error 0 Interrupt               Enable</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>PE1IE</name>
+                     <description>PHY Error 1 Interrupt               Enable</description>
+                     <bitOffset>17</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>PE2IE</name>
+                     <description>PHY Error 2 Interrupt               Enable</description>
+                     <bitOffset>18</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>PE3IE</name>
+                     <description>PHY Error 3 Interrupt               Enable</description>
+                     <bitOffset>19</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>PE4IE</name>
+                     <description>PHY Error 4 Interrupt               Enable</description>
+                     <bitOffset>20</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DSI_IER1</name>
+               <displayName>DSI_IER1</displayName>
+               <description>DSI Host Interrupt Enable Register           1</description>
+               <addressOffset>0xC8</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>TOHSTXIE</name>
+                     <description>Timeout High-Speed Transmission               Interrupt Enable</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TOLPRXIE</name>
+                     <description>Timeout Low-Power Reception Interrupt               Enable</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>ECCSEIE</name>
+                     <description>ECC Single-bit Error Interrupt               Enable</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>ECCMEIE</name>
+                     <description>ECC Multi-bit Error Interrupt               Enable</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CRCEIE</name>
+                     <description>CRC Error Interrupt Enable</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>PSEIE</name>
+                     <description>Packet Size Error Interrupt               Enable</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>EOTPEIE</name>
+                     <description>EoTp Error Interrupt               Enable</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>LPWREIE</name>
+                     <description>LTDC Payload Write Error Interrupt               Enable</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>GCWREIE</name>
+                     <description>Generic Command Write Error Interrupt               Enable</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>GPWREIE</name>
+                     <description>Generic Payload Write Error Interrupt               Enable</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>GPTXEIE</name>
+                     <description>Generic Payload Transmit Error Interrupt               Enable</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>GPRDEIE</name>
+                     <description>Generic Payload Read Error Interrupt               Enable</description>
+                     <bitOffset>11</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>GPRXEIE</name>
+                     <description>Generic Payload Receive Error Interrupt               Enable</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DSI_FIR0</name>
+               <displayName>DSI_FIR0</displayName>
+               <description>DSI Host Force Interrupt Register           0</description>
+               <addressOffset>0xD8</addressOffset>
+               <size>0x20</size>
+               <access>write-only</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>FAE0</name>
+                     <description>Force Acknowledge Error 0</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FAE1</name>
+                     <description>Force Acknowledge Error 1</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FAE2</name>
+                     <description>Force Acknowledge Error 2</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FAE3</name>
+                     <description>Force Acknowledge Error 3</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FAE4</name>
+                     <description>Force Acknowledge Error 4</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FAE5</name>
+                     <description>Force Acknowledge Error 5</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FAE6</name>
+                     <description>Force Acknowledge Error 6</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FAE7</name>
+                     <description>Force Acknowledge Error 7</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FAE8</name>
+                     <description>Force Acknowledge Error 8</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FAE9</name>
+                     <description>Force Acknowledge Error 9</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FAE10</name>
+                     <description>Force Acknowledge Error 10</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FAE11</name>
+                     <description>Force Acknowledge Error 11</description>
+                     <bitOffset>11</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FAE12</name>
+                     <description>Force Acknowledge Error 12</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FAE13</name>
+                     <description>Force Acknowledge Error 13</description>
+                     <bitOffset>13</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FAE14</name>
+                     <description>Force Acknowledge Error 14</description>
+                     <bitOffset>14</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FAE15</name>
+                     <description>Force Acknowledge Error 15</description>
+                     <bitOffset>15</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FPE0</name>
+                     <description>Force PHY Error 0</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FPE1</name>
+                     <description>Force PHY Error 1</description>
+                     <bitOffset>17</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FPE2</name>
+                     <description>Force PHY Error 2</description>
+                     <bitOffset>18</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FPE3</name>
+                     <description>Force PHY Error 3</description>
+                     <bitOffset>19</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FPE4</name>
+                     <description>Force PHY Error 4</description>
+                     <bitOffset>20</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DSI_FIR1</name>
+               <displayName>DSI_FIR1</displayName>
+               <description>DSI Host Force Interrupt Register           1</description>
+               <addressOffset>0xDC</addressOffset>
+               <size>0x20</size>
+               <access>write-only</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>FTOHSTX</name>
+                     <description>Force Timeout High-Speed               Transmission</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FTOLPRX</name>
+                     <description>Force Timeout Low-Power               Reception</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FECCSE</name>
+                     <description>Force ECC Single-bit Error</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FECCME</name>
+                     <description>Force ECC Multi-bit Error</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FCRCE</name>
+                     <description>Force CRC Error</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FPSE</name>
+                     <description>Force Packet Size Error</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FEOTPE</name>
+                     <description>Force EoTp Error</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FLPWRE</name>
+                     <description>Force LTDC Payload Write               Error</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FGCWRE</name>
+                     <description>Force Generic Command Write               Error</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FGPWRE</name>
+                     <description>Force Generic Payload Write               Error</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FGPTXE</name>
+                     <description>Force Generic Payload Transmit               Error</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FGPRDE</name>
+                     <description>Force Generic Payload Read               Error</description>
+                     <bitOffset>11</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FGPRXE</name>
+                     <description>Force Generic Payload Receive               Error</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DSI_VSCR</name>
+               <displayName>DSI_VSCR</displayName>
+               <description>DSI Host Video Shadow Control           Register</description>
+               <addressOffset>0x100</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>EN</name>
+                     <description>Enable</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>UR</name>
+                     <description>Update Register</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DSI_LCVCIDR</name>
+               <displayName>DSI_LCVCIDR</displayName>
+               <description>DSI Host LTDC Current VCID           Register</description>
+               <addressOffset>0x10C</addressOffset>
+               <size>0x20</size>
+               <access>read-only</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>VCID</name>
+                     <description>Virtual Channel ID</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DSI_LCCCR</name>
+               <displayName>DSI_LCCCR</displayName>
+               <description>DSI Host LTDC Current Color Coding           Register</description>
+               <addressOffset>0x110</addressOffset>
+               <size>0x20</size>
+               <access>read-only</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>COLC</name>
+                     <description>Color Coding</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+                  <field>
+                     <name>LPE</name>
+                     <description>Loosely Packed Enable</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DSI_LPMCCR</name>
+               <displayName>DSI_LPMCCR</displayName>
+               <description>DSI Host Low-Power mode Current           Configuration Register</description>
+               <addressOffset>0x118</addressOffset>
+               <size>0x20</size>
+               <access>read-only</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>VLPSIZE</name>
+                     <description>VACT Largest Packet Size</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+                  <field>
+                     <name>LPSIZE</name>
+                     <description>Largest Packet Size</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DSI_VMCCR</name>
+               <displayName>DSI_VMCCR</displayName>
+               <description>DSI Host Video mode Current Configuration           Register</description>
+               <addressOffset>0x138</addressOffset>
+               <size>0x20</size>
+               <access>read-only</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>VMT</name>
+                     <description>Video mode Type</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>LPVSAE</name>
+                     <description>Low-Power Vertical Sync time               Enable</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>LPVBPE</name>
+                     <description>Low-power Vertical Back-Porch               Enable</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>LPVFPE</name>
+                     <description>Low-power Vertical Front-Porch               Enable</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>LPVAE</name>
+                     <description>Low-Power Vertical Active               Enable</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>LPHBPE</name>
+                     <description>Low-power Horizontal Back-Porch               Enable</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>LPHFE</name>
+                     <description>Low-Power Horizontal Front-Porch               Enable</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FBTAAE</name>
+                     <description>Frame BTA Acknowledge               Enable</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>LPCE</name>
+                     <description>Low-Power Command Enable</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DSI_VPCCR</name>
+               <displayName>DSI_VPCCR</displayName>
+               <description>DSI Host Video Packet Current Configuration           Register</description>
+               <addressOffset>0x13C</addressOffset>
+               <size>0x20</size>
+               <access>read-only</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>VPSIZE</name>
+                     <description>Video Packet Size</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>14</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DSI_VCCCR</name>
+               <displayName>DSI_VCCCR</displayName>
+               <description>DSI Host Video Chunks Current Configuration           Register</description>
+               <addressOffset>0x140</addressOffset>
+               <size>0x20</size>
+               <access>read-only</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>NUMC</name>
+                     <description>Number of Chunks</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>13</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DSI_VNPCCR</name>
+               <displayName>DSI_VNPCCR</displayName>
+               <description>DSI Host Video Null Packet Current           Configuration Register</description>
+               <addressOffset>0x144</addressOffset>
+               <size>0x20</size>
+               <access>read-only</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>NPSIZE</name>
+                     <description>Null Packet Size</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>13</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DSI_VHSACCR</name>
+               <displayName>DSI_VHSACCR</displayName>
+               <description>DSI Host Video HSA Current Configuration           Register</description>
+               <addressOffset>0x148</addressOffset>
+               <size>0x20</size>
+               <access>read-only</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>HSA</name>
+                     <description>Horizontal Synchronism Active               duration</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>12</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DSI_VHBPCCR</name>
+               <displayName>DSI_VHBPCCR</displayName>
+               <description>DSI Host Video HBP Current Configuration           Register</description>
+               <addressOffset>0x14C</addressOffset>
+               <size>0x20</size>
+               <access>read-only</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>HBP</name>
+                     <description>Horizontal Back-Porch               duration</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>12</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DSI_VLCCR</name>
+               <displayName>DSI_VLCCR</displayName>
+               <description>DSI Host Video Line Current Configuration           Register</description>
+               <addressOffset>0x150</addressOffset>
+               <size>0x20</size>
+               <access>read-only</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>HLINE</name>
+                     <description>Horizontal Line duration</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>15</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DSI_VVSACCR</name>
+               <displayName>DSI_VVSACCR</displayName>
+               <description>DSI Host Video VSA Current Configuration           Register</description>
+               <addressOffset>0x154</addressOffset>
+               <size>0x20</size>
+               <access>read-only</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>VSA</name>
+                     <description>Vertical Synchronism Active               duration</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>10</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DSI_VVBPCCR</name>
+               <displayName>DSI_VVBPCCR</displayName>
+               <description>DSI Host Video VBP Current Configuration           Register</description>
+               <addressOffset>0x158</addressOffset>
+               <size>0x20</size>
+               <access>read-only</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>VBP</name>
+                     <description>Vertical Back-Porch               duration</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>10</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DSI_VVFPCCR</name>
+               <displayName>DSI_VVFPCCR</displayName>
+               <description>DSI Host Video VFP Current Configuration           Register</description>
+               <addressOffset>0x15C</addressOffset>
+               <size>0x20</size>
+               <access>read-only</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>VFP</name>
+                     <description>Vertical Front-Porch               duration</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>10</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DSI_VVACCR</name>
+               <displayName>DSI_VVACCR</displayName>
+               <description>DSI Host Video VA Current Configuration           Register</description>
+               <addressOffset>0x160</addressOffset>
+               <size>0x20</size>
+               <access>read-only</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>VA</name>
+                     <description>Vertical Active duration</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>14</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DSI_WCFGR</name>
+               <displayName>DSI_WCFGR</displayName>
+               <description>DSI Wrapper Configuration           Register</description>
+               <addressOffset>0x400</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>VSPOL</name>
+                     <description>VSync Polarity</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>AR</name>
+                     <description>Automatic Refresh</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TEPOL</name>
+                     <description>TE Polarity</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TESRC</name>
+                     <description>TE Source</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>COLMUX</name>
+                     <description>Color Multiplexing</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>3</bitWidth>
+                  </field>
+                  <field>
+                     <name>DSIM</name>
+                     <description>DSI Mode</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DSI_WCR</name>
+               <displayName>DSI_WCR</displayName>
+               <description>DSI Wrapper Control Register</description>
+               <addressOffset>0x404</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DSIEN</name>
+                     <description>DSI Enable</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>LTDCEN</name>
+                     <description>LTDC Enable</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>SHTDN</name>
+                     <description>Shutdown</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>COLM</name>
+                     <description>Color Mode</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DSI_WIER</name>
+               <displayName>DSI_WIER</displayName>
+               <description>DSI Wrapper Interrupt Enable           Register</description>
+               <addressOffset>0x408</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>RRIE</name>
+                     <description>Regulator Ready Interrupt               Enable</description>
+                     <bitOffset>13</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>PLLUIE</name>
+                     <description>PLL Unlock Interrupt               Enable</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>PLLLIE</name>
+                     <description>PLL Lock Interrupt Enable</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>ERIE</name>
+                     <description>End of Refresh Interrupt               Enable</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TEIE</name>
+                     <description>Tearing Effect Interrupt               Enable</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DSI_WISR</name>
+               <displayName>DSI_WISR</displayName>
+               <description>DSI Wrapper Interrupt &amp; Status           Register</description>
+               <addressOffset>0x40C</addressOffset>
+               <size>0x20</size>
+               <access>read-only</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>RRIF</name>
+                     <description>Regulator Ready Interrupt               Flag</description>
+                     <bitOffset>13</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>RRS</name>
+                     <description>Regulator Ready Status</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>PLLUIF</name>
+                     <description>PLL Unlock Interrupt Flag</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>PLLLIF</name>
+                     <description>PLL Lock Interrupt Flag</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>PLLLS</name>
+                     <description>PLL Lock Status</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>BUSY</name>
+                     <description>Busy Flag</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>ERIF</name>
+                     <description>End of Refresh Interrupt               Flag</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TEIF</name>
+                     <description>Tearing Effect Interrupt               Flag</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DSI_WIFCR</name>
+               <displayName>DSI_WIFCR</displayName>
+               <description>DSI Wrapper Interrupt Flag Clear           Register</description>
+               <addressOffset>0x410</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>CRRIF</name>
+                     <description>Clear Regulator Ready Interrupt               Flag</description>
+                     <bitOffset>13</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CPLLUIF</name>
+                     <description>Clear PLL Unlock Interrupt               Flag</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CPLLLIF</name>
+                     <description>Clear PLL Lock Interrupt               Flag</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CERIF</name>
+                     <description>Clear End of Refresh Interrupt               Flag</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CTEIF</name>
+                     <description>Clear Tearing Effect Interrupt               Flag</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DSI_WPCR1</name>
+               <displayName>DSI_WPCR1</displayName>
+               <description>DSI Wrapper PHY Configuration Register           1</description>
+               <addressOffset>0x418</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>TCLKPOSTEN</name>
+                     <description>custom time for tCLK-POST               Enable</description>
+                     <bitOffset>27</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TLPXCEN</name>
+                     <description>custom time for tLPX for Clock lane               Enable</description>
+                     <bitOffset>26</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>THSEXITEN</name>
+                     <description>custom time for tHS-EXIT               Enable</description>
+                     <bitOffset>25</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TLPXDEN</name>
+                     <description>custom time for tLPX for Data lanes               Enable</description>
+                     <bitOffset>24</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>THSZEROEN</name>
+                     <description>custom time for tHS-ZERO               Enable</description>
+                     <bitOffset>23</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>THSTRAILEN</name>
+                     <description>custom time for tHS-TRAIL               Enable</description>
+                     <bitOffset>22</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>THSPREPEN</name>
+                     <description>custom time for tHS-PREPARE               Enable</description>
+                     <bitOffset>21</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TCLKZEROEN</name>
+                     <description>custom time for tCLK-ZERO               Enable</description>
+                     <bitOffset>20</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TCLKPREPEN</name>
+                     <description>custom time for tCLK-PREPARE               Enable</description>
+                     <bitOffset>19</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>PDEN</name>
+                     <description>Pull-Down Enable</description>
+                     <bitOffset>18</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TDDL</name>
+                     <description>Turn Disable Data Lanes</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CDOFFDL</name>
+                     <description>Contention Detection OFF on Data               Lanes</description>
+                     <bitOffset>14</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FTXSMDL</name>
+                     <description>Force in TX Stop Mode the Data               Lanes</description>
+                     <bitOffset>13</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FTXSMCL</name>
+                     <description>Force in TX Stop Mode the Clock               Lane</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>HSIDL1</name>
+                     <description>Invert the High-Speed data signal on               Data Lane 1</description>
+                     <bitOffset>11</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>HSIDL0</name>
+                     <description>Invert the Hight-Speed data signal on               Data Lane 0</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>HSICL</name>
+                     <description>Invert Hight-Speed data signal on Clock               Lane</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>SWDL1</name>
+                     <description>Swap Data Lane 1 pins</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>SWDL0</name>
+                     <description>Swap Data Lane 0 pins</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>SWCL</name>
+                     <description>Swap Clock Lane pins</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>UIX4</name>
+                     <description>Unit Interval multiplied by               4</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>6</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DSI_WPCR2</name>
+               <displayName>DSI_WPCR2</displayName>
+               <description>DSI Wrapper PHY Configuration Register           2</description>
+               <addressOffset>0x41C</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>LPRXFT</name>
+                     <description>Low-Power RX low-pass Filtering               Tuning</description>
+                     <bitOffset>25</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>FLPRXLPM</name>
+                     <description>Forces LP Receiver in Low-Power               Mode</description>
+                     <bitOffset>22</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>HSTXSRCDL</name>
+                     <description>High-Speed Transmission Slew Rate               Control on Data Lanes</description>
+                     <bitOffset>18</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>HSTXSRCCL</name>
+                     <description>High-Speed Transmission Slew Rate               Control on Clock Lane</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>SDCC</name>
+                     <description>SDD Control</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>LPSRDL</name>
+                     <description>Low-Power transmission Slew Rate               Compensation on Data Lanes</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>LPSRCL</name>
+                     <description>Low-Power transmission Slew Rate               Compensation on Clock Lane</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>HSTXDLL</name>
+                     <description>High-Speed Transmission Delay on Data               Lanes</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>HSTXDCL</name>
+                     <description>High-Speed Transmission Delay on Clock               Lane</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DSI_WPCR3</name>
+               <displayName>DSI_WPCR3</displayName>
+               <description>DSI Wrapper PHY Configuration Register           3</description>
+               <addressOffset>0x420</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>THSTRAIL</name>
+                     <description>tHSTRAIL</description>
+                     <bitOffset>24</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+                  <field>
+                     <name>THSPREP</name>
+                     <description>tHS-PREPARE</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+                  <field>
+                     <name>TCLKZEO</name>
+                     <description>tCLK-ZERO</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+                  <field>
+                     <name>TCLKPREP</name>
+                     <description>tCLK-PREPARE</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DSI_WPCR4</name>
+               <displayName>DSI_WPCR4</displayName>
+               <description>DSI_WPCR4</description>
+               <addressOffset>0x424</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x3133302A</resetValue>
+               <fields>
+                  <field>
+                     <name>TLPXC</name>
+                     <description>tLPXC for Clock lane</description>
+                     <bitOffset>24</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+                  <field>
+                     <name>THSEXIT</name>
+                     <description>tHSEXIT</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+                  <field>
+                     <name>TLPXD</name>
+                     <description>tLPX for Data lanes</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+                  <field>
+                     <name>THSZERO</name>
+                     <description>tHS-ZERO</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DSI_WPCR5</name>
+               <displayName>DSI_WPCR5</displayName>
+               <description>DSI Wrapper PHY Configuration Register           5</description>
+               <addressOffset>0x428</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>THSZERO</name>
+                     <description>tCLK-POST</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DSI_WRPCR</name>
+               <displayName>DSI_WRPCR</displayName>
+               <description>DSI Wrapper Regulator and PLL Control           Register</description>
+               <addressOffset>0x430</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>REGEN</name>
+                     <description>Regulator Enable</description>
+                     <bitOffset>24</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>ODF</name>
+                     <description>PLL Output Division Factor</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>IDF</name>
+                     <description>PLL Input Division Factor</description>
+                     <bitOffset>11</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+                  <field>
+                     <name>NDIV</name>
+                     <description>PLL Loop Division Factor</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>7</bitWidth>
+                  </field>
+                  <field>
+                     <name>PLLEN</name>
+                     <description>PLL Enable</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+         </registers>
+      </peripheral>
+      <peripheral>
+         <name>NVIC</name>
+         <description>Nested Vectored Interrupt       Controller</description>
+         <groupName>NVIC</groupName>
+         <baseAddress>0xE000E100</baseAddress>
+         <addressBlock>
+            <offset>0x0</offset>
+            <size>0x400</size>
+            <usage>registers</usage>
+         </addressBlock>
+         <registers>
+            <register>
+               <name>ISER0</name>
+               <displayName>ISER0</displayName>
+               <description>Interrupt Set-Enable Register</description>
+               <addressOffset>0x0</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>SETENA</name>
+                     <description>SETENA</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>ISER1</name>
+               <displayName>ISER1</displayName>
+               <description>Interrupt Set-Enable Register</description>
+               <addressOffset>0x4</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>SETENA</name>
+                     <description>SETENA</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>ISER2</name>
+               <displayName>ISER2</displayName>
+               <description>Interrupt Set-Enable Register</description>
+               <addressOffset>0x8</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>SETENA</name>
+                     <description>SETENA</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>ICER0</name>
+               <displayName>ICER0</displayName>
+               <description>Interrupt Clear-Enable           Register</description>
+               <addressOffset>0x80</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>CLRENA</name>
+                     <description>CLRENA</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>ICER1</name>
+               <displayName>ICER1</displayName>
+               <description>Interrupt Clear-Enable           Register</description>
+               <addressOffset>0x84</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>CLRENA</name>
+                     <description>CLRENA</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>ICER2</name>
+               <displayName>ICER2</displayName>
+               <description>Interrupt Clear-Enable           Register</description>
+               <addressOffset>0x88</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>CLRENA</name>
+                     <description>CLRENA</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>ISPR0</name>
+               <displayName>ISPR0</displayName>
+               <description>Interrupt Set-Pending Register</description>
+               <addressOffset>0x100</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>SETPEND</name>
+                     <description>SETPEND</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>ISPR1</name>
+               <displayName>ISPR1</displayName>
+               <description>Interrupt Set-Pending Register</description>
+               <addressOffset>0x104</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>SETPEND</name>
+                     <description>SETPEND</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>ISPR2</name>
+               <displayName>ISPR2</displayName>
+               <description>Interrupt Set-Pending Register</description>
+               <addressOffset>0x108</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>SETPEND</name>
+                     <description>SETPEND</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>ICPR0</name>
+               <displayName>ICPR0</displayName>
+               <description>Interrupt Clear-Pending           Register</description>
+               <addressOffset>0x180</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>CLRPEND</name>
+                     <description>CLRPEND</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>ICPR1</name>
+               <displayName>ICPR1</displayName>
+               <description>Interrupt Clear-Pending           Register</description>
+               <addressOffset>0x184</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>CLRPEND</name>
+                     <description>CLRPEND</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>ICPR2</name>
+               <displayName>ICPR2</displayName>
+               <description>Interrupt Clear-Pending           Register</description>
+               <addressOffset>0x188</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>CLRPEND</name>
+                     <description>CLRPEND</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>IABR0</name>
+               <displayName>IABR0</displayName>
+               <description>Interrupt Active Bit Register</description>
+               <addressOffset>0x200</addressOffset>
+               <size>0x20</size>
+               <access>read-only</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>ACTIVE</name>
+                     <description>ACTIVE</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>IABR1</name>
+               <displayName>IABR1</displayName>
+               <description>Interrupt Active Bit Register</description>
+               <addressOffset>0x204</addressOffset>
+               <size>0x20</size>
+               <access>read-only</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>ACTIVE</name>
+                     <description>ACTIVE</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>IABR2</name>
+               <displayName>IABR2</displayName>
+               <description>Interrupt Active Bit Register</description>
+               <addressOffset>0x208</addressOffset>
+               <size>0x20</size>
+               <access>read-only</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>ACTIVE</name>
+                     <description>ACTIVE</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>IPR0</name>
+               <displayName>IPR0</displayName>
+               <description>Interrupt Priority Register</description>
+               <addressOffset>0x300</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>IPR_N0</name>
+                     <description>IPR_N0</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+                  <field>
+                     <name>IPR_N1</name>
+                     <description>IPR_N1</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+                  <field>
+                     <name>IPR_N2</name>
+                     <description>IPR_N2</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+                  <field>
+                     <name>IPR_N3</name>
+                     <description>IPR_N3</description>
+                     <bitOffset>24</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>IPR1</name>
+               <displayName>IPR1</displayName>
+               <description>Interrupt Priority Register</description>
+               <addressOffset>0x304</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>IPR_N0</name>
+                     <description>IPR_N0</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+                  <field>
+                     <name>IPR_N1</name>
+                     <description>IPR_N1</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+                  <field>
+                     <name>IPR_N2</name>
+                     <description>IPR_N2</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+                  <field>
+                     <name>IPR_N3</name>
+                     <description>IPR_N3</description>
+                     <bitOffset>24</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>IPR2</name>
+               <displayName>IPR2</displayName>
+               <description>Interrupt Priority Register</description>
+               <addressOffset>0x308</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>IPR_N0</name>
+                     <description>IPR_N0</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+                  <field>
+                     <name>IPR_N1</name>
+                     <description>IPR_N1</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+                  <field>
+                     <name>IPR_N2</name>
+                     <description>IPR_N2</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+                  <field>
+                     <name>IPR_N3</name>
+                     <description>IPR_N3</description>
+                     <bitOffset>24</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>IPR3</name>
+               <displayName>IPR3</displayName>
+               <description>Interrupt Priority Register</description>
+               <addressOffset>0x30C</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>IPR_N0</name>
+                     <description>IPR_N0</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+                  <field>
+                     <name>IPR_N1</name>
+                     <description>IPR_N1</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+                  <field>
+                     <name>IPR_N2</name>
+                     <description>IPR_N2</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+                  <field>
+                     <name>IPR_N3</name>
+                     <description>IPR_N3</description>
+                     <bitOffset>24</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>IPR4</name>
+               <displayName>IPR4</displayName>
+               <description>Interrupt Priority Register</description>
+               <addressOffset>0x310</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>IPR_N0</name>
+                     <description>IPR_N0</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+                  <field>
+                     <name>IPR_N1</name>
+                     <description>IPR_N1</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+                  <field>
+                     <name>IPR_N2</name>
+                     <description>IPR_N2</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+                  <field>
+                     <name>IPR_N3</name>
+                     <description>IPR_N3</description>
+                     <bitOffset>24</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>IPR5</name>
+               <displayName>IPR5</displayName>
+               <description>Interrupt Priority Register</description>
+               <addressOffset>0x314</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>IPR_N0</name>
+                     <description>IPR_N0</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+                  <field>
+                     <name>IPR_N1</name>
+                     <description>IPR_N1</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+                  <field>
+                     <name>IPR_N2</name>
+                     <description>IPR_N2</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+                  <field>
+                     <name>IPR_N3</name>
+                     <description>IPR_N3</description>
+                     <bitOffset>24</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>IPR6</name>
+               <displayName>IPR6</displayName>
+               <description>Interrupt Priority Register</description>
+               <addressOffset>0x318</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>IPR_N0</name>
+                     <description>IPR_N0</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+                  <field>
+                     <name>IPR_N1</name>
+                     <description>IPR_N1</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+                  <field>
+                     <name>IPR_N2</name>
+                     <description>IPR_N2</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+                  <field>
+                     <name>IPR_N3</name>
+                     <description>IPR_N3</description>
+                     <bitOffset>24</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>IPR7</name>
+               <displayName>IPR7</displayName>
+               <description>Interrupt Priority Register</description>
+               <addressOffset>0x31C</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>IPR_N0</name>
+                     <description>IPR_N0</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+                  <field>
+                     <name>IPR_N1</name>
+                     <description>IPR_N1</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+                  <field>
+                     <name>IPR_N2</name>
+                     <description>IPR_N2</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+                  <field>
+                     <name>IPR_N3</name>
+                     <description>IPR_N3</description>
+                     <bitOffset>24</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>IPR8</name>
+               <displayName>IPR8</displayName>
+               <description>Interrupt Priority Register</description>
+               <addressOffset>0x320</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>IPR_N0</name>
+                     <description>IPR_N0</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+                  <field>
+                     <name>IPR_N1</name>
+                     <description>IPR_N1</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+                  <field>
+                     <name>IPR_N2</name>
+                     <description>IPR_N2</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+                  <field>
+                     <name>IPR_N3</name>
+                     <description>IPR_N3</description>
+                     <bitOffset>24</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>IPR9</name>
+               <displayName>IPR9</displayName>
+               <description>Interrupt Priority Register</description>
+               <addressOffset>0x324</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>IPR_N0</name>
+                     <description>IPR_N0</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+                  <field>
+                     <name>IPR_N1</name>
+                     <description>IPR_N1</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+                  <field>
+                     <name>IPR_N2</name>
+                     <description>IPR_N2</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+                  <field>
+                     <name>IPR_N3</name>
+                     <description>IPR_N3</description>
+                     <bitOffset>24</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>IPR10</name>
+               <displayName>IPR10</displayName>
+               <description>Interrupt Priority Register</description>
+               <addressOffset>0x328</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>IPR_N0</name>
+                     <description>IPR_N0</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+                  <field>
+                     <name>IPR_N1</name>
+                     <description>IPR_N1</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+                  <field>
+                     <name>IPR_N2</name>
+                     <description>IPR_N2</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+                  <field>
+                     <name>IPR_N3</name>
+                     <description>IPR_N3</description>
+                     <bitOffset>24</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>IPR11</name>
+               <displayName>IPR11</displayName>
+               <description>Interrupt Priority Register</description>
+               <addressOffset>0x32C</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>IPR_N0</name>
+                     <description>IPR_N0</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+                  <field>
+                     <name>IPR_N1</name>
+                     <description>IPR_N1</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+                  <field>
+                     <name>IPR_N2</name>
+                     <description>IPR_N2</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+                  <field>
+                     <name>IPR_N3</name>
+                     <description>IPR_N3</description>
+                     <bitOffset>24</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>IPR12</name>
+               <displayName>IPR12</displayName>
+               <description>Interrupt Priority Register</description>
+               <addressOffset>0x330</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>IPR_N0</name>
+                     <description>IPR_N0</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+                  <field>
+                     <name>IPR_N1</name>
+                     <description>IPR_N1</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+                  <field>
+                     <name>IPR_N2</name>
+                     <description>IPR_N2</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+                  <field>
+                     <name>IPR_N3</name>
+                     <description>IPR_N3</description>
+                     <bitOffset>24</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>IPR13</name>
+               <displayName>IPR13</displayName>
+               <description>Interrupt Priority Register</description>
+               <addressOffset>0x334</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>IPR_N0</name>
+                     <description>IPR_N0</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+                  <field>
+                     <name>IPR_N1</name>
+                     <description>IPR_N1</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+                  <field>
+                     <name>IPR_N2</name>
+                     <description>IPR_N2</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+                  <field>
+                     <name>IPR_N3</name>
+                     <description>IPR_N3</description>
+                     <bitOffset>24</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>IPR14</name>
+               <displayName>IPR14</displayName>
+               <description>Interrupt Priority Register</description>
+               <addressOffset>0x338</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>IPR_N0</name>
+                     <description>IPR_N0</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+                  <field>
+                     <name>IPR_N1</name>
+                     <description>IPR_N1</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+                  <field>
+                     <name>IPR_N2</name>
+                     <description>IPR_N2</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+                  <field>
+                     <name>IPR_N3</name>
+                     <description>IPR_N3</description>
+                     <bitOffset>24</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>IPR15</name>
+               <displayName>IPR15</displayName>
+               <description>Interrupt Priority Register</description>
+               <addressOffset>0x33C</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>IPR_N0</name>
+                     <description>IPR_N0</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+                  <field>
+                     <name>IPR_N1</name>
+                     <description>IPR_N1</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+                  <field>
+                     <name>IPR_N2</name>
+                     <description>IPR_N2</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+                  <field>
+                     <name>IPR_N3</name>
+                     <description>IPR_N3</description>
+                     <bitOffset>24</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>IPR16</name>
+               <displayName>IPR16</displayName>
+               <description>Interrupt Priority Register</description>
+               <addressOffset>0x340</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>IPR_N0</name>
+                     <description>IPR_N0</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+                  <field>
+                     <name>IPR_N1</name>
+                     <description>IPR_N1</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+                  <field>
+                     <name>IPR_N2</name>
+                     <description>IPR_N2</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+                  <field>
+                     <name>IPR_N3</name>
+                     <description>IPR_N3</description>
+                     <bitOffset>24</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>IPR17</name>
+               <displayName>IPR17</displayName>
+               <description>Interrupt Priority Register</description>
+               <addressOffset>0x344</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>IPR_N0</name>
+                     <description>IPR_N0</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+                  <field>
+                     <name>IPR_N1</name>
+                     <description>IPR_N1</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+                  <field>
+                     <name>IPR_N2</name>
+                     <description>IPR_N2</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+                  <field>
+                     <name>IPR_N3</name>
+                     <description>IPR_N3</description>
+                     <bitOffset>24</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>IPR18</name>
+               <displayName>IPR18</displayName>
+               <description>Interrupt Priority Register</description>
+               <addressOffset>0x348</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>IPR_N0</name>
+                     <description>IPR_N0</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+                  <field>
+                     <name>IPR_N1</name>
+                     <description>IPR_N1</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+                  <field>
+                     <name>IPR_N2</name>
+                     <description>IPR_N2</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+                  <field>
+                     <name>IPR_N3</name>
+                     <description>IPR_N3</description>
+                     <bitOffset>24</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>IPR19</name>
+               <displayName>IPR19</displayName>
+               <description>Interrupt Priority Register</description>
+               <addressOffset>0x34C</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>IPR_N0</name>
+                     <description>IPR_N0</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+                  <field>
+                     <name>IPR_N1</name>
+                     <description>IPR_N1</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+                  <field>
+                     <name>IPR_N2</name>
+                     <description>IPR_N2</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+                  <field>
+                     <name>IPR_N3</name>
+                     <description>IPR_N3</description>
+                     <bitOffset>24</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>IPR20</name>
+               <displayName>IPR20</displayName>
+               <description>Interrupt Priority Register</description>
+               <addressOffset>0x350</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>IPR_N0</name>
+                     <description>IPR_N0</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+                  <field>
+                     <name>IPR_N1</name>
+                     <description>IPR_N1</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+                  <field>
+                     <name>IPR_N2</name>
+                     <description>IPR_N2</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+                  <field>
+                     <name>IPR_N3</name>
+                     <description>IPR_N3</description>
+                     <bitOffset>24</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>IPR21</name>
+               <displayName>IPR21</displayName>
+               <description>Interrupt Priority Register</description>
+               <addressOffset>0x354</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>IPR_N0</name>
+                     <description>IPR_N0</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+                  <field>
+                     <name>IPR_N1</name>
+                     <description>IPR_N1</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+                  <field>
+                     <name>IPR_N2</name>
+                     <description>IPR_N2</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+                  <field>
+                     <name>IPR_N3</name>
+                     <description>IPR_N3</description>
+                     <bitOffset>24</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>IPR22</name>
+               <displayName>IPR22</displayName>
+               <description>Interrupt Priority Register</description>
+               <addressOffset>0x358</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>IPR_N0</name>
+                     <description>IPR_N0</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+                  <field>
+                     <name>IPR_N1</name>
+                     <description>IPR_N1</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+                  <field>
+                     <name>IPR_N2</name>
+                     <description>IPR_N2</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+                  <field>
+                     <name>IPR_N3</name>
+                     <description>IPR_N3</description>
+                     <bitOffset>24</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>IPR23</name>
+               <displayName>IPR23</displayName>
+               <description>Interrupt Priority Register</description>
+               <addressOffset>0x35C</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>IPR_N0</name>
+                     <description>IPR_N0</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+                  <field>
+                     <name>IPR_N1</name>
+                     <description>IPR_N1</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+                  <field>
+                     <name>IPR_N2</name>
+                     <description>IPR_N2</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+                  <field>
+                     <name>IPR_N3</name>
+                     <description>IPR_N3</description>
+                     <bitOffset>24</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>IPR24</name>
+               <displayName>IPR24</displayName>
+               <description>Interrupt Priority Register</description>
+               <addressOffset>0x360</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>IPR_N0</name>
+                     <description>IPR_N0</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+                  <field>
+                     <name>IPR_N1</name>
+                     <description>IPR_N1</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+                  <field>
+                     <name>IPR_N2</name>
+                     <description>IPR_N2</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+                  <field>
+                     <name>IPR_N3</name>
+                     <description>IPR_N3</description>
+                     <bitOffset>24</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>IPR25</name>
+               <displayName>IPR25</displayName>
+               <description>Interrupt Priority Register</description>
+               <addressOffset>0x364</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>IPR_N0</name>
+                     <description>IPR_N0</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+                  <field>
+                     <name>IPR_N1</name>
+                     <description>IPR_N1</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+                  <field>
+                     <name>IPR_N2</name>
+                     <description>IPR_N2</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+                  <field>
+                     <name>IPR_N3</name>
+                     <description>IPR_N3</description>
+                     <bitOffset>24</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>IPR26</name>
+               <displayName>IPR26</displayName>
+               <description>Interrupt Priority Register</description>
+               <addressOffset>0x368</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>IPR_N0</name>
+                     <description>IPR_N0</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+                  <field>
+                     <name>IPR_N1</name>
+                     <description>IPR_N1</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+                  <field>
+                     <name>IPR_N2</name>
+                     <description>IPR_N2</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+                  <field>
+                     <name>IPR_N3</name>
+                     <description>IPR_N3</description>
+                     <bitOffset>24</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>IPR27</name>
+               <displayName>IPR27</displayName>
+               <description>Interrupt Priority Register</description>
+               <addressOffset>0x36C</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>IPR_N0</name>
+                     <description>IPR_N0</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+                  <field>
+                     <name>IPR_N1</name>
+                     <description>IPR_N1</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+                  <field>
+                     <name>IPR_N2</name>
+                     <description>IPR_N2</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+                  <field>
+                     <name>IPR_N3</name>
+                     <description>IPR_N3</description>
+                     <bitOffset>24</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>IPR28</name>
+               <displayName>IPR28</displayName>
+               <description>Interrupt Priority Register</description>
+               <addressOffset>0x370</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>IPR_N0</name>
+                     <description>IPR_N0</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+                  <field>
+                     <name>IPR_N1</name>
+                     <description>IPR_N1</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+                  <field>
+                     <name>IPR_N2</name>
+                     <description>IPR_N2</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+                  <field>
+                     <name>IPR_N3</name>
+                     <description>IPR_N3</description>
+                     <bitOffset>24</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+               </fields>
+            </register>
+         </registers>
+      </peripheral>
+      <peripheral>
+         <name>MPU</name>
+         <description>Memory protection unit</description>
+         <groupName>MPU</groupName>
+         <baseAddress>0xE000ED90</baseAddress>
+         <addressBlock>
+            <offset>0x0</offset>
+            <size>0x15</size>
+            <usage>registers</usage>
+         </addressBlock>
+         <registers>
+            <register>
+               <name>MPU_TYPER</name>
+               <displayName>MPU_TYPER</displayName>
+               <description>MPU type register</description>
+               <addressOffset>0x0</addressOffset>
+               <size>0x20</size>
+               <access>read-only</access>
+               <resetValue>0X00000800</resetValue>
+               <fields>
+                  <field>
+                     <name>SEPARATE</name>
+                     <description>Separate flag</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>DREGION</name>
+                     <description>Number of MPU data regions</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+                  <field>
+                     <name>IREGION</name>
+                     <description>Number of MPU instruction               regions</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>MPU_CTRL</name>
+               <displayName>MPU_CTRL</displayName>
+               <description>MPU control register</description>
+               <addressOffset>0x4</addressOffset>
+               <size>0x20</size>
+               <access>read-only</access>
+               <resetValue>0X00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>ENABLE</name>
+                     <description>Enables the MPU</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>HFNMIENA</name>
+                     <description>Enables the operation of MPU during hard               fault</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>PRIVDEFENA</name>
+                     <description>Enable priviliged software access to               default memory map</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>MPU_RNR</name>
+               <displayName>MPU_RNR</displayName>
+               <description>MPU region number register</description>
+               <addressOffset>0x8</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0X00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>REGION</name>
+                     <description>MPU region</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>MPU_RBAR</name>
+               <displayName>MPU_RBAR</displayName>
+               <description>MPU region base address           register</description>
+               <addressOffset>0xC</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0X00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>REGION</name>
+                     <description>MPU region field</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+                  <field>
+                     <name>VALID</name>
+                     <description>MPU region number valid</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>ADDR</name>
+                     <description>Region base address field</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>27</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>MPU_RASR</name>
+               <displayName>MPU_RASR</displayName>
+               <description>MPU region attribute and size           register</description>
+               <addressOffset>0x10</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0X00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>ENABLE</name>
+                     <description>Region enable bit.</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>SIZE</name>
+                     <description>Size of the MPU protection               region</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>5</bitWidth>
+                  </field>
+                  <field>
+                     <name>SRD</name>
+                     <description>Subregion disable bits</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+                  <field>
+                     <name>B</name>
+                     <description>memory attribute</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>C</name>
+                     <description>memory attribute</description>
+                     <bitOffset>17</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>S</name>
+                     <description>Shareable memory attribute</description>
+                     <bitOffset>18</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TEX</name>
+                     <description>memory attribute</description>
+                     <bitOffset>19</bitOffset>
+                     <bitWidth>3</bitWidth>
+                  </field>
+                  <field>
+                     <name>AP</name>
+                     <description>Access permission</description>
+                     <bitOffset>24</bitOffset>
+                     <bitWidth>3</bitWidth>
+                  </field>
+                  <field>
+                     <name>XN</name>
+                     <description>Instruction access disable               bit</description>
+                     <bitOffset>28</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+         </registers>
+      </peripheral>
+      <peripheral>
+         <name>STK</name>
+         <description>SysTick timer</description>
+         <groupName>STK</groupName>
+         <baseAddress>0xE000E010</baseAddress>
+         <addressBlock>
+            <offset>0x0</offset>
+            <size>0x11</size>
+            <usage>registers</usage>
+         </addressBlock>
+         <registers>
+            <register>
+               <name>CSR</name>
+               <displayName>CSR</displayName>
+               <description>SysTick control and status           register</description>
+               <addressOffset>0x0</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0X00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>ENABLE</name>
+                     <description>Counter enable</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>TICKINT</name>
+                     <description>SysTick exception request               enable</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>CLKSOURCE</name>
+                     <description>Clock source selection</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>COUNTFLAG</name>
+                     <description>COUNTFLAG</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>RVR</name>
+               <displayName>RVR</displayName>
+               <description>SysTick reload value register</description>
+               <addressOffset>0x4</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0X00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>RELOAD</name>
+                     <description>RELOAD value</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>24</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>CVR</name>
+               <displayName>CVR</displayName>
+               <description>SysTick current value register</description>
+               <addressOffset>0x8</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0X00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>CURRENT</name>
+                     <description>Current counter value</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>24</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>CALIB</name>
+               <displayName>CALIB</displayName>
+               <description>SysTick calibration value           register</description>
+               <addressOffset>0xC</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0X00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>TENMS</name>
+                     <description>Calibration value</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>24</bitWidth>
+                  </field>
+                  <field>
+                     <name>SKEW</name>
+                     <description>SKEW flag: Indicates whether the TENMS               value is exact</description>
+                     <bitOffset>30</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>NOREF</name>
+                     <description>NOREF flag. Reads as zero</description>
+                     <bitOffset>31</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+         </registers>
+      </peripheral>
+      <peripheral>
+         <name>NVIC_STIR</name>
+         <description>Nested vectored interrupt       controller</description>
+         <groupName>NVIC</groupName>
+         <baseAddress>0xE000EF00</baseAddress>
+         <addressBlock>
+            <offset>0x0</offset>
+            <size>0x5</size>
+            <usage>registers</usage>
+         </addressBlock>
+         <registers>
+            <register>
+               <name>STIR</name>
+               <displayName>STIR</displayName>
+               <description>Software trigger interrupt           register</description>
+               <addressOffset>0x0</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>INTID</name>
+                     <description>Software generated interrupt               ID</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>9</bitWidth>
+                  </field>
+               </fields>
+            </register>
+         </registers>
+      </peripheral>
+      <peripheral>
+         <name>FPU_CPACR</name>
+         <description>Floating point unit CPACR</description>
+         <groupName>FPU</groupName>
+         <baseAddress>0xE000ED88</baseAddress>
+         <addressBlock>
+            <offset>0x0</offset>
+            <size>0x5</size>
+            <usage>registers</usage>
+         </addressBlock>
+         <registers>
+            <register>
+               <name>CPACR</name>
+               <displayName>CPACR</displayName>
+               <description>Coprocessor access control           register</description>
+               <addressOffset>0x0</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x0000000</resetValue>
+               <fields>
+                  <field>
+                     <name>CP</name>
+                     <description>CP</description>
+                     <bitOffset>20</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+               </fields>
+            </register>
+         </registers>
+      </peripheral>
+      <peripheral>
+         <name>SCB_ACTRL</name>
+         <description>System control block ACTLR</description>
+         <groupName>SCB</groupName>
+         <baseAddress>0xE000E008</baseAddress>
+         <addressBlock>
+            <offset>0x0</offset>
+            <size>0x5</size>
+            <usage>registers</usage>
+         </addressBlock>
+         <registers>
+            <register>
+               <name>ACTRL</name>
+               <displayName>ACTRL</displayName>
+               <description>Auxiliary control register</description>
+               <addressOffset>0x0</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>DISFOLD</name>
+                     <description>DISFOLD</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FPEXCODIS</name>
+                     <description>FPEXCODIS</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>DISRAMODE</name>
+                     <description>DISRAMODE</description>
+                     <bitOffset>11</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>DISITMATBFLUSH</name>
+                     <description>DISITMATBFLUSH</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+         </registers>
+      </peripheral>
+      <peripheral>
+         <name>FPU</name>
+         <description>Floting point unit</description>
+         <groupName>FPU</groupName>
+         <baseAddress>0xE000EF34</baseAddress>
+         <addressBlock>
+            <offset>0x0</offset>
+            <size>0xD</size>
+            <usage>registers</usage>
+         </addressBlock>
+         <interrupt>
+            <name>FPU</name>
+            <description>Floating point unit interrupt</description>
+            <value>81</value>
+         </interrupt>
+         <registers>
+            <register>
+               <name>FPCCR</name>
+               <displayName>FPCCR</displayName>
+               <description>Floating-point context control           register</description>
+               <addressOffset>0x0</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>LSPACT</name>
+                     <description>LSPACT</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>USER</name>
+                     <description>USER</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>THREAD</name>
+                     <description>THREAD</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>HFRDY</name>
+                     <description>HFRDY</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>MMRDY</name>
+                     <description>MMRDY</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>BFRDY</name>
+                     <description>BFRDY</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>MONRDY</name>
+                     <description>MONRDY</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>LSPEN</name>
+                     <description>LSPEN</description>
+                     <bitOffset>30</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>ASPEN</name>
+                     <description>ASPEN</description>
+                     <bitOffset>31</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>FPCAR</name>
+               <displayName>FPCAR</displayName>
+               <description>Floating-point context address           register</description>
+               <addressOffset>0x4</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>ADDRESS</name>
+                     <description>Location of unpopulated               floating-point</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>29</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>FPSCR</name>
+               <displayName>FPSCR</displayName>
+               <description>Floating-point status control           register</description>
+               <addressOffset>0x8</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>IOC</name>
+                     <description>Invalid operation cumulative exception               bit</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>DZC</name>
+                     <description>Division by zero cumulative exception               bit.</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>OFC</name>
+                     <description>Overflow cumulative exception               bit</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>UFC</name>
+                     <description>Underflow cumulative exception               bit</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>IXC</name>
+                     <description>Inexact cumulative exception               bit</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>IDC</name>
+                     <description>Input denormal cumulative exception               bit.</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>RMode</name>
+                     <description>Rounding Mode control               field</description>
+                     <bitOffset>22</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>FZ</name>
+                     <description>Flush-to-zero mode control               bit:</description>
+                     <bitOffset>24</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>DN</name>
+                     <description>Default NaN mode control               bit</description>
+                     <bitOffset>25</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>AHP</name>
+                     <description>Alternative half-precision control               bit</description>
+                     <bitOffset>26</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>V</name>
+                     <description>Overflow condition code               flag</description>
+                     <bitOffset>28</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>C</name>
+                     <description>Carry condition code flag</description>
+                     <bitOffset>29</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>Z</name>
+                     <description>Zero condition code flag</description>
+                     <bitOffset>30</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>N</name>
+                     <description>Negative condition code               flag</description>
+                     <bitOffset>31</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+         </registers>
+      </peripheral>
+      <peripheral>
+         <name>SCB</name>
+         <description>System control block</description>
+         <groupName>SCB</groupName>
+         <baseAddress>0xE000ED00</baseAddress>
+         <addressBlock>
+            <offset>0x0</offset>
+            <size>0x41</size>
+            <usage>registers</usage>
+         </addressBlock>
+         <registers>
+            <register>
+               <name>CPUID</name>
+               <displayName>CPUID</displayName>
+               <description>CPUID base register</description>
+               <addressOffset>0x0</addressOffset>
+               <size>0x20</size>
+               <access>read-only</access>
+               <resetValue>0x410FC241</resetValue>
+               <fields>
+                  <field>
+                     <name>Revision</name>
+                     <description>Revision number</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+                  <field>
+                     <name>PartNo</name>
+                     <description>Part number of the               processor</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>12</bitWidth>
+                  </field>
+                  <field>
+                     <name>Constant</name>
+                     <description>Reads as 0xF</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+                  <field>
+                     <name>Variant</name>
+                     <description>Variant number</description>
+                     <bitOffset>20</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+                  <field>
+                     <name>Implementer</name>
+                     <description>Implementer code</description>
+                     <bitOffset>24</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>ICSR</name>
+               <displayName>ICSR</displayName>
+               <description>Interrupt control and state           register</description>
+               <addressOffset>0x4</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>VECTACTIVE</name>
+                     <description>Active vector</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>9</bitWidth>
+                  </field>
+                  <field>
+                     <name>RETTOBASE</name>
+                     <description>Return to base level</description>
+                     <bitOffset>11</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>VECTPENDING</name>
+                     <description>Pending vector</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>7</bitWidth>
+                  </field>
+                  <field>
+                     <name>ISRPENDING</name>
+                     <description>Interrupt pending flag</description>
+                     <bitOffset>22</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>PENDSTCLR</name>
+                     <description>SysTick exception clear-pending               bit</description>
+                     <bitOffset>25</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>PENDSTSET</name>
+                     <description>SysTick exception set-pending               bit</description>
+                     <bitOffset>26</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>PENDSVCLR</name>
+                     <description>PendSV clear-pending bit</description>
+                     <bitOffset>27</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>PENDSVSET</name>
+                     <description>PendSV set-pending bit</description>
+                     <bitOffset>28</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>NMIPENDSET</name>
+                     <description>NMI set-pending bit.</description>
+                     <bitOffset>31</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>VTOR</name>
+               <displayName>VTOR</displayName>
+               <description>Vector table offset register</description>
+               <addressOffset>0x8</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>TBLOFF</name>
+                     <description>Vector table base offset               field</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>21</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>AIRCR</name>
+               <displayName>AIRCR</displayName>
+               <description>Application interrupt and reset control           register</description>
+               <addressOffset>0xC</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>VECTRESET</name>
+                     <description>VECTRESET</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>VECTCLRACTIVE</name>
+                     <description>VECTCLRACTIVE</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>SYSRESETREQ</name>
+                     <description>SYSRESETREQ</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>PRIGROUP</name>
+                     <description>PRIGROUP</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>3</bitWidth>
+                  </field>
+                  <field>
+                     <name>ENDIANESS</name>
+                     <description>ENDIANESS</description>
+                     <bitOffset>15</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>VECTKEYSTAT</name>
+                     <description>Register key</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>16</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>SCR</name>
+               <displayName>SCR</displayName>
+               <description>System control register</description>
+               <addressOffset>0x10</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>SLEEPONEXIT</name>
+                     <description>SLEEPONEXIT</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>SLEEPDEEP</name>
+                     <description>SLEEPDEEP</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>SEVEONPEND</name>
+                     <description>Send Event on Pending bit</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>CCR</name>
+               <displayName>CCR</displayName>
+               <description>Configuration and control           register</description>
+               <addressOffset>0x14</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>NONBASETHRDENA</name>
+                     <description>Configures how the processor enters               Thread mode</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>USERSETMPEND</name>
+                     <description>USERSETMPEND</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>UNALIGN__TRP</name>
+                     <description>UNALIGN_ TRP</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>DIV_0_TRP</name>
+                     <description>DIV_0_TRP</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>BFHFNMIGN</name>
+                     <description>BFHFNMIGN</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>STKALIGN</name>
+                     <description>STKALIGN</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>DC</name>
+                     <description>DC</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>IC</name>
+                     <description>IC</description>
+                     <bitOffset>17</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>BP</name>
+                     <description>BP</description>
+                     <bitOffset>18</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>SHPR1</name>
+               <displayName>SHPR1</displayName>
+               <description>System handler priority           registers</description>
+               <addressOffset>0x18</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>PRI_4</name>
+                     <description>Priority of system handler               4</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+                  <field>
+                     <name>PRI_5</name>
+                     <description>Priority of system handler               5</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+                  <field>
+                     <name>PRI_6</name>
+                     <description>Priority of system handler               6</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>SHPR2</name>
+               <displayName>SHPR2</displayName>
+               <description>System handler priority           registers</description>
+               <addressOffset>0x1C</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>PRI_11</name>
+                     <description>Priority of system handler               11</description>
+                     <bitOffset>24</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>SHPR3</name>
+               <displayName>SHPR3</displayName>
+               <description>System handler priority           registers</description>
+               <addressOffset>0x20</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>PRI_14</name>
+                     <description>Priority of system handler               14</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+                  <field>
+                     <name>PRI_15</name>
+                     <description>Priority of system handler               15</description>
+                     <bitOffset>24</bitOffset>
+                     <bitWidth>8</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>SHCRS</name>
+               <displayName>SHCRS</displayName>
+               <description>System handler control and state           register</description>
+               <addressOffset>0x24</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>MEMFAULTACT</name>
+                     <description>Memory management fault exception active               bit</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>BUSFAULTACT</name>
+                     <description>Bus fault exception active               bit</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>USGFAULTACT</name>
+                     <description>Usage fault exception active               bit</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>SVCALLACT</name>
+                     <description>SVC call active bit</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>MONITORACT</name>
+                     <description>Debug monitor active bit</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>PENDSVACT</name>
+                     <description>PendSV exception active               bit</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>SYSTICKACT</name>
+                     <description>SysTick exception active               bit</description>
+                     <bitOffset>11</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>USGFAULTPENDED</name>
+                     <description>Usage fault exception pending               bit</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>MEMFAULTPENDED</name>
+                     <description>Memory management fault exception               pending bit</description>
+                     <bitOffset>13</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>BUSFAULTPENDED</name>
+                     <description>Bus fault exception pending               bit</description>
+                     <bitOffset>14</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>SVCALLPENDED</name>
+                     <description>SVC call pending bit</description>
+                     <bitOffset>15</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>MEMFAULTENA</name>
+                     <description>Memory management fault enable               bit</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>BUSFAULTENA</name>
+                     <description>Bus fault enable bit</description>
+                     <bitOffset>17</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>USGFAULTENA</name>
+                     <description>Usage fault enable bit</description>
+                     <bitOffset>18</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>CFSR_UFSR_BFSR_MMFSR</name>
+               <displayName>CFSR_UFSR_BFSR_MMFSR</displayName>
+               <description>Configurable fault status           register</description>
+               <addressOffset>0x28</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>IACCVIOL</name>
+                     <description>IACCVIOL</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>DACCVIOL</name>
+                     <description>DACCVIOL</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>MUNSTKERR</name>
+                     <description>MUNSTKERR</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>MSTKERR</name>
+                     <description>MSTKERR</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>MLSPERR</name>
+                     <description>MLSPERR</description>
+                     <bitOffset>5</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>MMARVALID</name>
+                     <description>MMARVALID</description>
+                     <bitOffset>7</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>IBUSERR</name>
+                     <description>Instruction bus error</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>PRECISERR</name>
+                     <description>Precise data bus error</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>IMPRECISERR</name>
+                     <description>Imprecise data bus error</description>
+                     <bitOffset>10</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>UNSTKERR</name>
+                     <description>Bus fault on unstacking for a return               from exception</description>
+                     <bitOffset>11</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>STKERR</name>
+                     <description>Bus fault on stacking for exception               entry</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>LSPERR</name>
+                     <description>Bus fault on floating-point lazy state               preservation</description>
+                     <bitOffset>13</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>BFARVALID</name>
+                     <description>Bus Fault Address Register (BFAR) valid               flag</description>
+                     <bitOffset>15</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>UNDEFINSTR</name>
+                     <description>Undefined instruction usage               fault</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>INVSTATE</name>
+                     <description>Invalid state usage fault</description>
+                     <bitOffset>17</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>INVPC</name>
+                     <description>Invalid PC load usage               fault</description>
+                     <bitOffset>18</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>NOCP</name>
+                     <description>No coprocessor usage               fault.</description>
+                     <bitOffset>19</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>UNALIGNED</name>
+                     <description>Unaligned access usage               fault</description>
+                     <bitOffset>24</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>DIVBYZERO</name>
+                     <description>Divide by zero usage fault</description>
+                     <bitOffset>25</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>HFSR</name>
+               <displayName>HFSR</displayName>
+               <description>Hard fault status register</description>
+               <addressOffset>0x2C</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>VECTTBL</name>
+                     <description>Vector table hard fault</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FORCED</name>
+                     <description>Forced hard fault</description>
+                     <bitOffset>30</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>DEBUG_VT</name>
+                     <description>Reserved for Debug use</description>
+                     <bitOffset>31</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>MMFAR</name>
+               <displayName>MMFAR</displayName>
+               <description>Memory management fault address           register</description>
+               <addressOffset>0x34</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>ADDRESS</name>
+                     <description>Memory management fault               address</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>BFAR</name>
+               <displayName>BFAR</displayName>
+               <description>Bus fault address register</description>
+               <addressOffset>0x38</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0x00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>ADDRESS</name>
+                     <description>Bus fault address</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>32</bitWidth>
+                  </field>
+               </fields>
+            </register>
+         </registers>
+      </peripheral>
+      <peripheral>
+         <name>PF</name>
+         <description>Processor features</description>
+         <groupName>PF</groupName>
+         <baseAddress>0xE000ED78</baseAddress>
+         <addressBlock>
+            <offset>0x0</offset>
+            <size>0xD</size>
+            <usage>registers</usage>
+         </addressBlock>
+         <registers>
+            <register>
+               <name>CLIDR</name>
+               <displayName>CLIDR</displayName>
+               <description>Cache Level ID register</description>
+               <addressOffset>0x0</addressOffset>
+               <size>0x20</size>
+               <access>read-only</access>
+               <resetValue>0x09000003</resetValue>
+               <fields>
+                  <field>
+                     <name>CL1</name>
+                     <description>CL1</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>3</bitWidth>
+                  </field>
+                  <field>
+                     <name>CL2</name>
+                     <description>CL2</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>3</bitWidth>
+                  </field>
+                  <field>
+                     <name>CL3</name>
+                     <description>CL3</description>
+                     <bitOffset>6</bitOffset>
+                     <bitWidth>3</bitWidth>
+                  </field>
+                  <field>
+                     <name>CL4</name>
+                     <description>CL4</description>
+                     <bitOffset>9</bitOffset>
+                     <bitWidth>3</bitWidth>
+                  </field>
+                  <field>
+                     <name>CL5</name>
+                     <description>CL5</description>
+                     <bitOffset>12</bitOffset>
+                     <bitWidth>3</bitWidth>
+                  </field>
+                  <field>
+                     <name>CL6</name>
+                     <description>CL6</description>
+                     <bitOffset>15</bitOffset>
+                     <bitWidth>3</bitWidth>
+                  </field>
+                  <field>
+                     <name>CL7</name>
+                     <description>CL7</description>
+                     <bitOffset>18</bitOffset>
+                     <bitWidth>3</bitWidth>
+                  </field>
+                  <field>
+                     <name>LoUIS</name>
+                     <description>LoUIS</description>
+                     <bitOffset>21</bitOffset>
+                     <bitWidth>3</bitWidth>
+                  </field>
+                  <field>
+                     <name>LoC</name>
+                     <description>LoC</description>
+                     <bitOffset>24</bitOffset>
+                     <bitWidth>3</bitWidth>
+                  </field>
+                  <field>
+                     <name>LoU</name>
+                     <description>LoU</description>
+                     <bitOffset>27</bitOffset>
+                     <bitWidth>3</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>CTR</name>
+               <displayName>CTR</displayName>
+               <description>Cache Type register</description>
+               <addressOffset>0x4</addressOffset>
+               <size>0x20</size>
+               <access>read-only</access>
+               <resetValue>0X8303C003</resetValue>
+               <fields>
+                  <field>
+                     <name>_IminLine</name>
+                     <description>IminLine</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+                  <field>
+                     <name>DMinLine</name>
+                     <description>DMinLine</description>
+                     <bitOffset>16</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+                  <field>
+                     <name>ERG</name>
+                     <description>ERG</description>
+                     <bitOffset>20</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+                  <field>
+                     <name>CWG</name>
+                     <description>CWG</description>
+                     <bitOffset>24</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+                  <field>
+                     <name>Format</name>
+                     <description>Format</description>
+                     <bitOffset>29</bitOffset>
+                     <bitWidth>3</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>CCSIDR</name>
+               <displayName>CCSIDR</displayName>
+               <description>Cache Size ID register</description>
+               <addressOffset>0x8</addressOffset>
+               <size>0x20</size>
+               <access>read-only</access>
+               <resetValue>0X00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>LineSize</name>
+                     <description>LineSize</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>3</bitWidth>
+                  </field>
+                  <field>
+                     <name>Associativity</name>
+                     <description>Associativity</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>10</bitWidth>
+                  </field>
+                  <field>
+                     <name>NumSets</name>
+                     <description>NumSets</description>
+                     <bitOffset>13</bitOffset>
+                     <bitWidth>15</bitWidth>
+                  </field>
+                  <field>
+                     <name>WA</name>
+                     <description>WA</description>
+                     <bitOffset>28</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>RA</name>
+                     <description>RA</description>
+                     <bitOffset>29</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>WB</name>
+                     <description>WB</description>
+                     <bitOffset>30</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>WT</name>
+                     <description>WT</description>
+                     <bitOffset>31</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+         </registers>
+      </peripheral>
+      <peripheral>
+         <name>AC</name>
+         <description>Access control</description>
+         <groupName>AC</groupName>
+         <baseAddress>0xE000EF90</baseAddress>
+         <addressBlock>
+            <offset>0x0</offset>
+            <size>0x1D</size>
+            <usage>registers</usage>
+         </addressBlock>
+         <registers>
+            <register>
+               <name>ITCMCR</name>
+               <displayName>ITCMCR</displayName>
+               <description>Instruction and Data Tightly-Coupled Memory           Control Registers</description>
+               <addressOffset>0x0</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0X00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>EN</name>
+                     <description>EN</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>RMW</name>
+                     <description>RMW</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>RETEN</name>
+                     <description>RETEN</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>SZ</name>
+                     <description>SZ</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>DTCMCR</name>
+               <displayName>DTCMCR</displayName>
+               <description>Instruction and Data Tightly-Coupled Memory           Control Registers</description>
+               <addressOffset>0x4</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0X00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>EN</name>
+                     <description>EN</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>RMW</name>
+                     <description>RMW</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>RETEN</name>
+                     <description>RETEN</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>SZ</name>
+                     <description>SZ</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>4</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>AHBPCR</name>
+               <displayName>AHBPCR</displayName>
+               <description>AHBP Control register</description>
+               <addressOffset>0x8</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0X00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>EN</name>
+                     <description>EN</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>SZ</name>
+                     <description>SZ</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>3</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>CACR</name>
+               <displayName>CACR</displayName>
+               <description>Auxiliary Cache Control           register</description>
+               <addressOffset>0xC</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0X00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>SIWT</name>
+                     <description>SIWT</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>ECCEN</name>
+                     <description>ECCEN</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>FORCEWT</name>
+                     <description>FORCEWT</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>AHBSCR</name>
+               <displayName>AHBSCR</displayName>
+               <description>AHB Slave Control register</description>
+               <addressOffset>0x10</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0X00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>CTL</name>
+                     <description>CTL</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+                  <field>
+                     <name>TPRI</name>
+                     <description>TPRI</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>9</bitWidth>
+                  </field>
+                  <field>
+                     <name>INITCOUNT</name>
+                     <description>INITCOUNT</description>
+                     <bitOffset>11</bitOffset>
+                     <bitWidth>5</bitWidth>
+                  </field>
+               </fields>
+            </register>
+            <register>
+               <name>ABFSR</name>
+               <displayName>ABFSR</displayName>
+               <description>Auxiliary Bus Fault Status           register</description>
+               <addressOffset>0x18</addressOffset>
+               <size>0x20</size>
+               <access>read-write</access>
+               <resetValue>0X00000000</resetValue>
+               <fields>
+                  <field>
+                     <name>ITCM</name>
+                     <description>ITCM</description>
+                     <bitOffset>0</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>DTCM</name>
+                     <description>DTCM</description>
+                     <bitOffset>1</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>AHBP</name>
+                     <description>AHBP</description>
+                     <bitOffset>2</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>AXIM</name>
+                     <description>AXIM</description>
+                     <bitOffset>3</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>EPPB</name>
+                     <description>EPPB</description>
+                     <bitOffset>4</bitOffset>
+                     <bitWidth>1</bitWidth>
+                  </field>
+                  <field>
+                     <name>AXIMTYPE</name>
+                     <description>AXIMTYPE</description>
+                     <bitOffset>8</bitOffset>
+                     <bitWidth>2</bitWidth>
+                  </field>
+               </fields>
+            </register>
+         </registers>
+      </peripheral>
+   </peripherals>
+</device>
Index: azure_iot_hub_f767zi/trunk/app_iothub_client/.vscode/c_cpp_properties.json
===================================================================
--- azure_iot_hub_f767zi/trunk/app_iothub_client/.vscode/c_cpp_properties.json	(revision 457)
+++ azure_iot_hub_f767zi/trunk/app_iothub_client/.vscode/c_cpp_properties.json	(revision 457)
@@ -0,0 +1,50 @@
+{
+    "configurations": [
+        {
+            "name": "STM32F767 NUCLEO-144",
+            "includePath": [
+                "${workspaceFolder}/../asp_baseplatform",
+                "${workspaceFolder}/../asp_baseplatform/arch",
+                "${workspaceFolder}/../asp_baseplatform/arch/arm_m_gcc/common",
+                "${workspaceFolder}/../asp_baseplatform/arch/arm_m_gcc/stm32f7xx",
+                "${workspaceFolder}/../asp_baseplatform/arch/gcc",
+                "${workspaceFolder}/../asp_baseplatform/files",
+                "${workspaceFolder}/../asp_baseplatform/files/ff",
+                "${workspaceFolder}/../asp_baseplatform/include",
+                "${workspaceFolder}/../asp_baseplatform/target/stm32f767nucleo144_gcc",
+                "${workspaceFolder}/../asp_baseplatform/pdic/stm32f7xx",
+                "${workspaceFolder}/../asp_baseplatform/monitor",
+                "${workspaceFolder}/../asp_baseplatform/lwip",
+                "${workspaceFolder}/../asp_baseplatform/lwip/lwip-2.1.2/src/include",
+                "${workspaceFolder}/../asp_baseplatform/lwip/contrib-2.1.0/ports/toppers/include",
+                "${workspaceFolder}/../asp_baseplatform/lwip/contrib-2.1.0",
+                "${workspaceFolder}/../wolfssl-4.4.0",
+                "${workspaceFolder}/../wolfssl-4.4.0/wolfssl",
+                "${workspaceFolder}/../wolfssl-4.4.0/wolfssl/wolfcrypt",
+                "${workspaceFolder}/../zlib-1.2.11/src",
+                "${workspaceFolder}/../azure_iot_sdk/c-utility/adapters",
+                "${workspaceFolder}/../azure_iot_sdk/c-utility/inc",
+                "${workspaceFolder}/../azure_iot_sdk/c-utility/pal/toppers",
+                "${workspaceFolder}/../azure_iot_sdk/certs",
+                "${workspaceFolder}/../azure_iot_sdk/deps",
+                "${workspaceFolder}/../azure_iot_sdk/deps/parson",
+                "${workspaceFolder}/../azure_iot_sdk/deps/azure-macro-utils-c/inc",
+                "${workspaceFolder}/../azure_iot_sdk/deps/umock-c/inc",
+                "${workspaceFolder}/../azure_iot_sdk/serializer/inc",
+                "${workspaceFolder}/../azure_iot_sdk/iothub_client/inc",
+                "${workspaceFolder}/../azure_iot_sdk/provisioning_client/inc",
+                "${workspaceFolder}/pinkit",
+                "${workspaceFolder}/src",
+                "${workspaceFolder}/Debug"
+            ],
+            "defines": [
+            ],
+            "windowsSdkVersion": "10.0.17763.0",
+            "compilerPath": "C:\\Program Files (x86)\\GNU Tools ARM Embedded\\9 2019-q4-major\\bin\\arm-none-eabi-gcc.exe",
+            "cStandard": "c11",
+            "cppStandard": "c++17",
+            "intelliSenseMode": "gcc-x64"
+        }
+    ],
+    "version": 4
+}
Index: azure_iot_hub_f767zi/trunk/app_iothub_client/.vscode/launch.json
===================================================================
--- azure_iot_hub_f767zi/trunk/app_iothub_client/.vscode/launch.json	(revision 457)
+++ azure_iot_hub_f767zi/trunk/app_iothub_client/.vscode/launch.json	(revision 457)
@@ -0,0 +1,36 @@
+{
+    "version": "0.2.0",
+    "configurations": [
+        {
+            "name": "Cortex Debug",
+            "armToolchainPath": "C:\\Program Files (x86)\\GNU Tools ARM Embedded\\9 2019-q4-major\\bin",
+            "serverpath": "C:\\Program Files\\GNU MCU Eclipse\\OpenOCD\\0.10.0-12-20190422-2015\\bin\\openocd.exe",
+            "cwd": "${workspaceFolder}\\Debug",
+            "executable": "${workspaceFolder}\\Debug\\${workspaceFolderBasename}.elf",
+            "request": "launch",
+            "type": "cortex-debug",
+            "servertype": "openocd",
+            "device": "STM32F767ZI",
+            "interface": "swd",
+            "svdFile": "${workspaceFolder}\\..\\STM32F7x7.svd",
+            "configFiles": [
+                "board/st_nucleo_f7.cfg"
+            ],
+            "openOCDLaunchCommands": [
+                "gdb_breakpoint_override hard",
+                "gdb_flash_program disable",
+                "gdb_memory_map disable"
+            ],
+            "preLaunchCommands": [
+                "-environment-cd ${workspaceRoot}/Debug",
+                "-gdb-set breakpoint pending on",
+                "monitor reset init",
+                "monitor halt",
+                "monitor arm semihosting enable",
+                "load ${workspaceFolderBasename}.elf",
+                "enable breakpoint"
+            ],
+            //"preLaunchTask": "build app_iothub_client"
+        }
+    ]
+}
Index: azure_iot_hub_f767zi/trunk/app_iothub_client/.vscode/settings.json
===================================================================
--- azure_iot_hub_f767zi/trunk/app_iothub_client/.vscode/settings.json	(revision 457)
+++ azure_iot_hub_f767zi/trunk/app_iothub_client/.vscode/settings.json	(revision 457)
@@ -0,0 +1,17 @@
+// Place your settings in this file to overwrite default and user settings.
+{
+    "terminal.integrated.setLocaleVariables": true,
+    "terminal.integrated.shell.windows": "C:\\msys64\\usr\\bin\\bash.exe",
+    "terminal.integrated.shellArgs.windows": [
+        "--login",
+        "-i"
+    ],
+    "terminal.integrated.env.windows": {
+        "PATH": "C:\\Program Files (x86)\\GNU Tools ARM Embedded\\9 2019-q4-major\\bin",
+        "CHERE_INVOKING": "1",
+        "MSYS2_PATH_TYPE": "inherit",
+        "MSYSTEM": "MINGW64"
+    },
+    "C_Cpp.intelliSenseEngine": "Tag Parser",
+    "C_Cpp.default.intelliSenseMode": "gcc-x64"
+}
Index: azure_iot_hub_f767zi/trunk/app_iothub_client/.vscode/tasks.json
===================================================================
--- azure_iot_hub_f767zi/trunk/app_iothub_client/.vscode/tasks.json	(revision 457)
+++ azure_iot_hub_f767zi/trunk/app_iothub_client/.vscode/tasks.json	(revision 457)
@@ -0,0 +1,180 @@
+{
+    // See https://go.microsoft.com/fwlink/?LinkId=733558
+    // for the documentation about the tasks.json format
+    "version": "2.0.0",
+    "name": "make",
+    "type": "shell",
+    "problemMatcher": {
+        "owner": "cpp",
+        "fileLocation": [
+            "relative",
+            "${workspaceFolder}/Debug"
+        ],
+        "pattern": {
+            "regexp": "^(.*):(\\d+):(\\d+):\\s+(warning|error|fatal error):\\s+(.*)$",
+            "file": 1,
+            "line": 2,
+            "column": 3,
+            "severity": 4,
+            "message": 5
+        }
+    },
+    "tasks": [
+        {
+            "label": "build all",
+            "args": [
+                "-j", "1",
+                "-C", "..",
+                "all"
+            ],
+            "linux": {
+                "command": "make"
+            },
+            "osx": {
+                "command": "make"
+            },
+            "windows": {
+                "command": "make.exe"
+            },
+            "group": {
+                "kind": "build",
+                "isDefault": true
+            }
+        },
+        {
+            "label": "clean all",
+            "args": [
+                "-C", "..",
+                "clean"
+            ],
+            "linux": {
+                "command": "make"
+            },
+            "osx": {
+                "command": "make"
+            },
+            "windows": {
+                "command": "make.exe"
+            },
+            "group": "build"
+        },
+        {
+            "label": "realclean all",
+            "args": [
+                "-C", "..",
+                "realclean"
+            ],
+            "linux": {
+                "command": "make"
+            },
+            "osx": {
+                "command": "make"
+            },
+            "windows": {
+                "command": "make.exe"
+            },
+            "group": "build"
+        },
+        {
+            "label": "build app_iothub_client",
+            "args": [
+                "-j", "1",
+                "all"
+            ],
+            "linux": {
+                "command": "make"
+            },
+            "osx": {
+                "command": "make"
+            },
+            "windows": {
+                "command": "make.exe"
+            },
+            "group": "build"
+        },
+        {
+            "label": "cfg app_iothub_client",
+            "args": [
+                "-j", "1",
+                "kernel_cfg.h"
+            ],
+            "linux": {
+                "command": "make"
+            },
+            "osx": {
+                "command": "make"
+            },
+            "windows": {
+                "command": "make.exe"
+            },
+            "group": "build"
+        },
+        {
+            "label": "clean app_iothub_client",
+            "args": [
+                "clean"
+            ],
+            "linux": {
+                "command": "make"
+            },
+            "osx": {
+                "command": "make"
+            },
+            "windows": {
+                "command": "make.exe"
+            },
+            "group": "build"
+        },
+        {
+            "label": "realclean app_iothub_client",
+            "args": [
+                "realclean"
+            ],
+            "linux": {
+                "command": "make"
+            },
+            "osx": {
+                "command": "make"
+            },
+            "windows": {
+                "command": "make.exe"
+            },
+            "group": "build"
+        },
+        {
+            "label": "write app",
+            "linux": {
+                "command": "rsync",
+                "args": [
+                    "-av",
+                    "--progress",
+                    "${workspaceFolder}/Debug/app_iothub_client.bin",
+                    "/media/${env:USER}/NODE_F767ZI/"
+                ]
+            },
+            "osx": {
+                "command": "rsync",
+                "args": [
+                    "-av",
+                    "--progress",
+                    "${workspaceFolder}/Debug/app_iothub_client.bin",
+                    "/Volumes/NODE_F767ZI/"
+                ]
+            },
+            "windows": {
+                "command": "C:\\Windows\\System32\\robocopy.exe",
+                "args": [
+                    "${workspaceFolder}\\Debug",
+                    "G:\\",
+                    "app_iothub_client.bin"
+                ],
+                "options": {
+                    "shell": {
+                        "executable": "C:\\Windows\\System32\\cmd.exe",
+                        "args":["/D", "/C"]
+                    }
+                }
+            }
+        }
+    ]
+}
Index: azure_iot_hub_f767zi/trunk/app_iothub_client/Debug/Makefile
===================================================================
--- azure_iot_hub_f767zi/trunk/app_iothub_client/Debug/Makefile	(revision 457)
+++ azure_iot_hub_f767zi/trunk/app_iothub_client/Debug/Makefile	(revision 457)
@@ -0,0 +1,626 @@
+#
+#  TOPPERS/ASP Kernel
+#      Toyohashi Open Platform for Embedded Real-Time Systems/
+#      Advanced Standard Profile Kernel
+# 
+#  Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
+#                              Toyohashi Univ. of Technology, JAPAN
+#  Copyright (C) 2006-2019 by Embedded and Real-Time Systems Laboratory
+#              Graduate School of Information Science, Nagoya Univ., JAPAN
+# 
+#  ä¸è¨èä½æ¨©è
+ã¯ï¼ä»¥ä¸ã®(1)ï½(4)ã®æ¡ä»¶ãæºããå ´åã«éãï¼æ¬ã½ããã¦ã§
+#  ã¢ï¼æ¬ã½ããã¦ã§ã¢ãæ¹å¤ãããã®ãå«ãï¼ä»¥ä¸åãï¼ãä½¿ç¨ã»è¤è£½ã»æ¹
+#  å¤ã»åé
+å¸ï¼ä»¥ä¸ï¼å©ç¨ã¨å¼ã¶ï¼ãããã¨ãç¡åã§è¨±è«¾ããï¼
+#   (1) æ¬ã½ããã¦ã§ã¢ãã½ã¼ã¹ã³ã¼ãã®å½¢ã§å©ç¨ããå ´åã«ã¯ï¼ä¸è¨ã®èä½
+#       æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨ã®ç¡ä¿è¨¼è¦å®ãï¼ãã®ã¾ã¾ã®å½¢ã§ã½ã¼
+#       ã¹ã³ã¼ãä¸­ã«å«ã¾ãã¦ãããã¨ï¼
+#   (2) æ¬ã½ããã¦ã§ã¢ãï¼ã©ã¤ãã©ãªå½¢å¼ãªã©ï¼ä»ã®ã½ããã¦ã§ã¢éçºã«ä½¿
+#       ç¨ã§ããå½¢ã§åé
+å¸ããå ´åã«ã¯ï¼åé
+å¸ã«ä¼´ããã­ã¥ã¡ã³ãï¼å©ç¨
+#       è
+ããã¥ã¢ã«ãªã©ï¼ã«ï¼ä¸è¨ã®èä½æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨
+#       ã®ç¡ä¿è¨¼è¦å®ãæ²è¼ãããã¨ï¼
+#   (3) æ¬ã½ããã¦ã§ã¢ãï¼æ©å¨ã«çµã¿è¾¼ããªã©ï¼ä»ã®ã½ããã¦ã§ã¢éçºã«ä½¿
+#      ç¨ã§ããªãå½¢ã§åé
+å¸ããå ´åã«ã¯ï¼æ¬¡ã®ããããã®æ¡ä»¶ãæºããã
+#      ã¨ï¼
+#     (a) åé
+å¸ã«ä¼´ããã­ã¥ã¡ã³ãï¼å©ç¨è
+ããã¥ã¢ã«ãªã©ï¼ã«ï¼ä¸è¨ã®è
+#         ä½æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨ã®ç¡ä¿è¨¼è¦å®ãæ²è¼ãããã¨ï¼
+#     (b) åé
+å¸ã®å½¢æ
+ãï¼å¥ã«å®ããæ¹æ³ã«ãã£ã¦ï¼TOPPERSãã­ã¸ã§ã¯ãã«
+#        å ±åãããã¨ï¼
+#   (4) æ¬ã½ããã¦ã§ã¢ã®å©ç¨ã«ããç´æ¥çã¾ãã¯éæ¥çã«çãããããªãæ
+#      å®³ãããï¼ä¸è¨èä½æ¨©è
+ããã³TOPPERSãã­ã¸ã§ã¯ããå
+è²¬ãããã¨ï¼
+#      ã¾ãï¼æ¬ã½ããã¦ã§ã¢ã®ã¦ã¼ã¶ã¾ãã¯ã¨ã³ãã¦ã¼ã¶ããã®ãããªãç
+#      ç±ã«åºã¥ãè«æ±ãããï¼ä¸è¨èä½æ¨©è
+ããã³TOPPERSãã­ã¸ã§ã¯ãã
+#      å
+è²¬ãããã¨ï¼
+# 
+#  æ¬ã½ããã¦ã§ã¢ã¯ï¼ç¡ä¿è¨¼ã§æä¾ããã¦ãããã®ã§ããï¼ä¸è¨èä½æ¨©è
+ã
+#  ãã³TOPPERSãã­ã¸ã§ã¯ãã¯ï¼æ¬ã½ããã¦ã§ã¢ã«é¢ãã¦ï¼ç¹å®ã®ä½¿ç¨ç®ç
+#  ã«å¯¾ããé©åæ§ãå«ãã¦ï¼ãããªãä¿è¨¼ãè¡ããªãï¼ã¾ãï¼æ¬ã½ããã¦ã§
+#  ã¢ã®å©ç¨ã«ããç´æ¥çã¾ãã¯éæ¥çã«çãããããªãæå®³ã«é¢ãã¦ãï¼ã
+#  ã®è²¬ä»»ãè² ããªãï¼
+# 
+#  $Id$
+# 
+
+#
+#  ã¿ã¼ã²ããã®æå®ï¼Makefile.targetã§ä¸æ¸ããããã®ãé²ãããï¼
+#
+all:
+
+#
+#  ã¿ã¼ã²ããç¥ç§°ã®å®ç¾©
+#
+TARGET = stm32f767nucleo144_gcc
+
+#
+#  ãã­ã°ã©ãã³ã°è¨èªã®å®ç¾©
+#
+SRCLANG = c
+ifeq ($(SRCLANG),c)
+	LIBS = -lc -lm \
+		$(SRCDIR)/../zlib-1.2.11/Debug/libzlib.a \
+		$(SRCDIR)/../wolfssl-4.4.0/Debug/libwolfssl.a \
+		$(SRCDIR)/../azure_iot_sdk/Debug/libazure_iot_sdk.a
+endif
+ifeq ($(SRCLANG),c++)
+	USE_CXX = true
+	CXXLIBS = -lstdc++ -lc -lm
+	CXXRTS = cxxrt.o newlibrt.o
+endif
+
+#
+#  ã½ã¼ã¹ãã¡ã¤ã«ã®ãã£ã¬ã¯ããªã®å®ç¾©
+#
+SRCDIR = ../../asp_baseplatform
+
+#
+#  ãªãã¸ã§ã¯ããã¡ã¤ã«åã®æ¡å¼µå­ã®è¨­å®
+#
+OBJEXT = elf
+
+#
+#  å®è¡ç°å¢ã®å®ç¾©ï¼ã¿ã¼ã²ããä¾å­ã«ä¸æ¸ããããå ´åãããï¼
+#
+DBGENV := ROM
+
+#
+#  ã«ã¼ãã«ã©ã¤ãã©ãªï¼libkernel.aï¼ã®ãã£ã¬ã¯ããªå
+#  ï¼ã«ã¼ãã«ã©ã¤ãã©ãªãmakeå¯¾è±¡ã«ããæã¯ï¼ç©ºã«å®ç¾©ããï¼
+#
+KERNEL_LIB = 
+
+#
+#  ã«ã¼ãã«ãé¢æ°åä½ã§ã³ã³ãã¤ã«ãããã©ããã®å®ç¾©
+#
+KERNEL_FUNCOBJS = 
+
+#
+#  ãã¬ã¼ã¹ã­ã°ãåå¾ãããã©ããã®å®ç¾©
+#
+ENABLE_TRACE = 
+
+#
+#  éçºãã¼ã«ï¼ã³ã³ãã¤ã©ç­ï¼ã®ãã£ã¬ã¯ããªã®å®ç¾©
+#
+DEVTOOLDIR = 
+
+#
+#  ã¦ã¼ãã£ãªãã£ãã­ã°ã©ã ã®åç§°
+#
+PERL = /usr/bin/perl
+CFG = $(SRCDIR)/cfg/cfg/cfg
+
+#
+#  ãªãã¸ã§ã¯ããã¡ã¤ã«åã®å®ç¾©
+#
+OBJNAME = app_iothub_client
+ifdef OBJEXT
+	OBJFILE = $(OBJNAME).$(OBJEXT)
+	CFG1_OUT = cfg1_out.$(OBJEXT)
+else
+	OBJFILE = $(OBJNAME)
+	CFG1_OUT = cfg1_out
+endif
+
+#
+#  ä¸­éãªãã¸ã§ã¯ããã¡ã¤ã«ã¨ä¾å­é¢ä¿ãã¡ã¤ã«ãç½®ããã£ã¬ã¯ããªã®å®ç¾©
+#
+OBJDIR = obj
+DEPDIR = obj
+
+#
+#  ã¿ã¼ã²ããä¾å­é¨ã®ãã£ã¬ã¯ããªã®å®ç¾©
+#
+TARGETDIR = $(SRCDIR)/target/$(TARGET)
+
+#
+#  ã¿ã¼ã²ããä¾å­ã®å®ç¾©ã®ã¤ã³ã¯ã«ã¼ã
+#
+include $(TARGETDIR)/Makefile.target
+
+#
+#  å
+±éã³ã³ãã¤ã«ãªãã·ã§ã³ã®å®ç¾©
+#
+COPTS := $(COPTS) -g -std=gnu11 -ffunction-sections -fdata-sections
+ifndef OMIT_WARNING_ALL
+  COPTS := $(COPTS) -Wall
+endif
+ifndef OMIT_OPTIMIZATION
+  COPTS := $(COPTS) -Os
+endif
+COPTS := $(COPTS) -Wno-unused-variable -Wno-unused-function
+#CDEFS := $(CDEFS) -DLWIP_DEBUG
+CDEFS := $(CDEFS) -DMONITOR_PORTID=1 -DUSE_CUPCOMMAND -DLWIP_COMPAT_MUTEX=1 -DLWIP_COMPAT_MUTEX_ALLOWED -DUSE_PINGSEND -DNOT_USE_TBP_MKTIME_GMTIME
+CDEFS := $(CDEFS) -DUSE_WOLFSSL=1 -DHSM_TYPE_SYMM_KEY -DUSE_PROV_MODULE -Dget_time=azure_get_time
+INCLUDES := -I. -I$(SRCDIR)/include -I$(SRCDIR)/arch -I$(SRCDIR) $(INCLUDES)
+LDFLAGS := $(LDFLAGS) -Wl,--wrap=exit
+CFG1_OUT_LDFLAGS := $(CFG1_OUT_LDFLAGS) 
+LIBS := $(LIBS) $(CXXLIBS)
+CFLAGS = $(COPTS) $(CDEFS) $(INCLUDES)
+
+#
+#  ã¢ããªã±ã¼ã·ã§ã³ãã­ã°ã©ã ã«é¢ããå®ç¾©
+#
+APPLNAME = app_iothub_client
+APPLDIR := $(APPLDIR) ../src ../pinkit
+APPL_CFG = main.cfg
+
+APPL_DIR := $(APPLDIR) $(SRCDIR)/library
+APPL_ASMOBJS :=
+ifdef USE_CXX
+	APPL_CXXOBJS := $(APPL_CXXOBJS) main.o
+	APPL_COBJS := $(APPL_COBJS) client.o code.o envcmd.o temperature.o accelerometer.o boardfullcolorled.o lightsensor.o pinkit.o command.o lwip_prvmib.o ping.o chargen.o udpecho.o shell.o tcpecho.o netio.o esp_at_socket.o
+else
+	APPL_COBJS := $(APPL_COBJS) main.o client.o code.o envcmd.o temperature.o accelerometer.o boardfullcolorled.o lightsensor.o pinkit.o command.o lwip_prvmib.o ping.o chargen.o udpecho.o shell.o tcpecho.o netio.o esp_at_socket.o
+endif
+APPL_COBJS := $(APPL_COBJS) log_output.o vasyslog.o t_perror.o strerror.o stub.o
+APPL_CFLAGS := $(APPL_CFLAGS)
+APPL_LIBS =
+ifdef APPLDIR
+	INCLUDES := $(INCLUDES) $(foreach dir,$(APPLDIR),-I$(dir))
+endif
+INCLUDES += -I$(SRCDIR)/../azure_iot_sdk/certs
+INCLUDES += -I$(SRCDIR)/../azure_iot_sdk/c-utility/inc
+INCLUDES += -I$(SRCDIR)/../azure_iot_sdk/c-utility/pal/toppers
+INCLUDES += -I$(SRCDIR)/../azure_iot_sdk/iothub_client/inc
+INCLUDES += -I$(SRCDIR)/../azure_iot_sdk/iothub_client/inc/internal
+INCLUDES += -I$(SRCDIR)/../azure_iot_sdk/provisioning_client/adapters
+INCLUDES += -I$(SRCDIR)/../azure_iot_sdk/provisioning_client/inc
+INCLUDES += -I$(SRCDIR)/../azure_iot_sdk/provisioning_client/inc/azure_prov_client/internal
+INCLUDES += -I$(SRCDIR)/../azure_iot_sdk/deps/parson
+INCLUDES += -I$(SRCDIR)/../azure_iot_sdk/deps/azure-macro-utils-c/inc
+INCLUDES += -I$(SRCDIR)/../azure_iot_sdk/deps/umock-c/inc
+INCLUDES += -I$(SRCDIR)/../azure_iot_sdk/serializer/inc
+INCLUDES += -I$(SRCDIR)/../azure_iot_sdk/uhttp/inc
+INCLUDES += -I$(SRCDIR)/../azure_iot_sdk/umqtt/inc
+INCLUDES += -I$(SRCDIR)/../wolfssl-4.4.0/wolfssl
+INCLUDES += -I$(SRCDIR)/../wolfssl-4.4.0/wolfssl/wolfcrypt
+INCLUDES += -I$(SRCDIR)/../wolfssl-4.4.0
+INCLUDES += -I$(SRCDIR)/../zlib-1.2.11/src
+
+#  ããã«ã¦ã§ã¢ã® Makefile ã®ã¤ã³ã¯ã«ã¼ã
+#
+include $(SRCDIR)/files/ff/Makefile.config
+include $(SRCDIR)/files/Makefile.config
+include $(SRCDIR)/monitor/Makefile.config
+include $(SRCDIR)/lwip/Makefile.config
+
+#
+#  ã·ã¹ãã ãµã¼ãã¹ã«é¢ããå®ç¾©
+#
+SYSSVC_DIR := $(SYSSVC_DIR) $(SRCDIR)/syssvc $(SRCDIR)/pdic/stm32f7xx $(SRCDIR)/library
+SYSSVC_ASMOBJS := $(SYSSVC_ASMOBJS)
+SYSSVC_COBJS := $(SYSSVC_COBJS) banner.o syslog.o serial.o logtask.o armv7m.o \
+				 device.o i2c.o adc.o pinmode.o usb_otg.o clock.o malloc.o sdmmc.o emac.o $(CXXRTS)
+SYSSVC_CFLAGS := $(SYSSVC_CFLAGS)
+SYSSVC_LIBS := $(SYSSVC_LIBS)
+INCLUDES := -I$(SRCDIR)/pdic/stm32f7xx $(INCLUDES)
+
+#
+#  ãã¬ã¼ã¹ã­ã°è¨é²ã®ãµã³ãã«ã³ã¼ãã«é¢ããå®ç¾©
+#
+ifdef ENABLE_TRACE
+	COPTS := $(COPTS) -DTOPPERS_ENABLE_TRACE
+	SYSSVC_DIR := $(SYSSVC_DIR) $(SRCDIR)/arch/tracelog
+endif
+
+#
+#  ã¿ã¼ã²ãããã¡ã¤ã«
+#
+.PHONY: all
+#all: $(DEPDIR) check
+all: $(DEPDIR) check $(OBJNAME).bin
+#all: $(DEPDIR) check $(OBJNAME).srec
+
+##### ä»¥ä¸ã¯ç·¨éããªããã¨ #####
+
+#
+#  ã³ã³ãã£ã®ã¥ã¬ã¼ã¿ã«é¢ããå®ç¾©
+#
+CFG_TABS := --api-table $(SRCDIR)/kernel/kernel_api.csv \
+			--cfg1-def-table $(SRCDIR)/kernel/kernel_def.csv $(CFG_TABS)
+
+CFG_ASMOBJS := $(CFG_ASMOBJS)
+CFG_COBJS := kernel_cfg.o $(CFG_COBJS)
+CFG_OBJS := $(CFG_ASMOBJS) $(CFG_COBJS)
+CFG2_OUT_SRCS := kernel_cfg.h kernel_cfg.c $(CFG2_OUT_SRCS)
+
+#
+#  ã«ã¼ãã«ã«é¢ããå®ç¾©
+#
+#  KERNEL_ASMOBJS: ã«ã¼ãã«ã©ã¤ãã©ãªã«å«ããï¼ã½ã¼ã¹ãã¢ã»ã³ããªè¨èªã®
+#				   ãªãã¸ã§ã¯ããã¡ã¤ã«ï¼
+#  KERNEL_COBJS: ã«ã¼ãã«ã®ã©ã¤ãã©ãªã«å«ããï¼ã½ã¼ã¹ãCè¨èªã§ï¼ã½ã¼ã¹
+#				 ãã¡ã¤ã«ã¨1å¯¾1ã«å¯¾å¿ãããªãã¸ã§ã¯ããã¡ã¤ã«ï¼
+#  KERNEL_LCSRCS: ã«ã¼ãã«ã®ã©ã¤ãã©ãªã«å«ããCè¨èªã®ã½ã¼ã¹ãã¡ã¤ã«ã§ï¼
+#				  1ã¤ã®ã½ã¼ã¹ãã¡ã¤ã«ããè¤æ°ã®ãªãã¸ã§ã¯ããã¡ã¤ã«ãç
+#				  æãããã®ï¼
+#  KERNEL_LCOBJS: ä¸ã®ã½ã¼ã¹ãã¡ã¤ã«ããçæããããªãã¸ã§ã¯ããã¡ã¤ã«ï¼
+#  KERNEL_AUX_COBJS: ã­ã¼ãã¢ã¸ã¥ã¼ã«ã«å«ããªããï¼ã«ã¼ãã«ã®ã½ã¼ã¹ãã¡
+#					 ã¤ã«ã¨åããªãã·ã§ã³ãé©ç¨ãã¦ã³ã³ãã¤ã«ãã¹ãï¼ã½ã¼
+#					 ã¹ãCè¨èªã®ãªãã¸ã§ã¯ããã¡ã¤ã«ï¼
+#
+KERNEL_DIR := $(KERNEL_DIR) $(SRCDIR)/kernel
+KERNEL_ASMOBJS := $(KERNEL_ASMOBJS)
+KERNEL_COBJS := $(KERNEL_COBJS)
+KERNEL_CFLAGS := $(KERNEL_CFLAGS) -I$(SRCDIR)/kernel
+ifdef OMIT_MAKEOFFSET
+  OFFSET_H =
+else
+  OFFSET_H = offset.h
+ifndef OFFSET_TF
+  KERNEL_AUX_COBJS := $(KERNEL_AUX_COBJS) makeoffset.o
+endif
+endif
+
+#
+#  ç°å¢ã«ä¾å­ããã³ã³ãã¤ã«ãªãã·ã§ã³ã®å®ç¾©
+#
+ifdef DBGENV
+  CDEFS := $(CDEFS) -D$(DBGENV)
+endif
+
+#
+#  ã«ã¼ãã«ã®ãã¡ã¤ã«æ§æã®å®ç¾©
+#
+include $(SRCDIR)/kernel/Makefile.kernel
+ifdef KERNEL_FUNCOBJS
+	KERNEL_LCSRCS := $(KERNEL_FCSRCS)
+	KERNEL_LCOBJS := $(foreach file,$(KERNEL_FCSRCS),$($(file:.c=)))
+else
+	KERNEL_CFLAGS := -DALLFUNC $(KERNEL_CFLAGS)
+	KERNEL_COBJS := $(KERNEL_COBJS) \
+					$(foreach file,$(KERNEL_FCSRCS),$(file:.c=.o))
+endif
+
+#
+#  ã½ã¼ã¹ãã¡ã¤ã«ã®ãããã£ã¬ã¯ããªã«é¢ããå®ç¾©
+#
+vpath %.c $(KERNEL_DIR) $(SYSSVC_DIR) $(APPL_DIR)
+vpath %.cpp $(KERNEL_DIR) $(SYSSVC_DIR) $(APPL_DIR)
+vpath %.S $(KERNEL_DIR) $(SYSSVC_DIR) $(APPL_DIR)
+vpath %.cfg $(APPL_DIR)
+
+#
+#  ä¸­éãªãã¸ã§ã¯ããã¡ã¤ã«ãç½®ããã£ã¬ã¯ããªã®å¦ç
+#
+APPL_ASMOBJS   := $(addprefix $(OBJDIR)/, $(APPL_ASMOBJS))
+APPL_CXXOBJS   := $(addprefix $(OBJDIR)/, $(APPL_CXXOBJS))
+APPL_COBJS     := $(addprefix $(OBJDIR)/, $(APPL_COBJS))
+SYSSVC_ASMOBJS := $(addprefix $(OBJDIR)/, $(SYSSVC_ASMOBJS))
+SYSSVC_COBJS   := $(addprefix $(OBJDIR)/, $(SYSSVC_COBJS))
+KERNEL_ASMOBJS := $(addprefix $(OBJDIR)/, $(KERNEL_ASMOBJS))
+KERNEL_COBJS   := $(addprefix $(OBJDIR)/, $(KERNEL_COBJS))
+KERNEL_LCOBJS  := $(addprefix $(OBJDIR)/, $(KERNEL_LCOBJS))
+CFG_ASMOBJS    := $(addprefix $(OBJDIR)/, $(CFG_ASMOBJS))
+CFG_COBJS      := $(addprefix $(OBJDIR)/, $(CFG_COBJS))
+
+#
+#  ã³ã³ãã¤ã«ã®ããã®å¤æ°ã®å®ç¾©
+#
+APPL_OBJS = $(APPL_ASMOBJS) $(APPL_COBJS) $(APPL_CXXOBJS)
+SYSSVC_OBJS = $(SYSSVC_ASMOBJS) $(SYSSVC_COBJS)
+KERNEL_LIB_OBJS = $(KERNEL_ASMOBJS) $(KERNEL_COBJS) $(KERNEL_LCOBJS)
+CFG_OBJS = $(CFG_ASMOBJS) $(CFG_COBJS)
+ALL_OBJS = $(START_OBJS) $(APPL_OBJS) $(SYSSVC_OBJS) $(CFG_OBJS) \
+											$(END_OBJS) $(HIDDEN_OBJS)
+ALL_LIBS = -lkernel $(LIBS)
+ifdef KERNEL_LIB
+	LIBS_DEP = $(KERNEL_LIB)/libkernel.a $(filter %.a,$(LIBS))
+	OBJ_LDFLAGS := $(OBJ_LDFLAGS) -L$(KERNEL_LIB)
+	REALCLEAN_FILES := libkernel.a $(REALCLEAN_FILES)
+else
+	LIBS_DEP = libkernel.a $(filter %.a,$(LIBS))
+	OBJ_LDFLAGS := $(OBJ_LDFLAGS) -L.
+endif
+
+ifdef TEXT_START_ADDRESS
+	LDFLAGS := $(LDFLAGS) -Wl,-Ttext,$(TEXT_START_ADDRESS)
+endif
+ifdef DATA_START_ADDRESS
+	LDFLAGS := $(LDFLAGS) -Wl,-Tdata,$(DATA_START_ADDRESS)
+endif
+ifdef LDSCRIPT
+	LDFLAGS := $(LDFLAGS) -T $(LDSCRIPT)
+endif
+
+#
+#  ã«ã¼ãã«ã®ã³ã³ãã£ã®ã¥ã¬ã¼ã·ã§ã³ãã¡ã¤ã«ã®çæ
+#
+cfg1_out.c: cfg1_out.timestamp ;
+cfg1_out.timestamp: $(APPL_CFG)
+	$(CFG) --pass 1 $(CFG_KERNEL) $(INCLUDES) $(CFG_TABS) $<
+	touch -r cfg1_out.c cfg1_out.timestamp
+
+$(CFG1_OUT): $(START_OBJS) $(OBJDIR)/cfg1_out.o $(END_OBJS) $(HIDDEN_OBJS)
+	$(LINK) $(CFLAGS) $(LDFLAGS) $(CFG1_OUT_LDFLAGS) -o $(CFG1_OUT) \
+						$(START_OBJS) $(OBJDIR)/cfg1_out.o $(LIBS) $(END_OBJS)
+
+cfg1_out.syms: $(CFG1_OUT)
+	$(NM) -n $(CFG1_OUT) > cfg1_out.syms
+
+cfg1_out.srec: $(CFG1_OUT)
+	$(OBJCOPY) -O srec -S $(CFG1_OUT) cfg1_out.srec
+
+$(CFG2_OUT_SRCS): kernel_cfg.timestamp ;
+kernel_cfg.timestamp: $(APPL_CFG) cfg1_out.syms cfg1_out.srec
+	$(CFG) --pass 2 $(CFG_KERNEL) $(INCLUDES) \
+				-T $(TARGETDIR)/target.tf $(CFG_TABS) $<
+	touch -r kernel_cfg.c kernel_cfg.timestamp
+
+#
+#  ãªãã»ãããã¡ã¤ã«ï¼offset.hï¼ã®çæè¦å
+#
+$(OFFSET_H): offset.timestamp ;
+ifdef OFFSET_TF
+offset.timestamp: $(APPL_CFG) kernel_cfg.timestamp
+	$(CFG) --pass 3 --kernel asp $(INCLUDES) \
+				--rom-image cfg1_out.srec --symbol-table cfg1_out.syms \
+				-T $(OFFSET_TF) $(CFG_TABS) $<
+	touch -r $(OFFSET_H) offset.timestamp
+else
+offset.timestamp: makeoffset.s $(SRCDIR)/utils/genoffset
+	$(PERL) $(SRCDIR)/utils/genoffset makeoffset.s > offset.h
+	touch -r $(OFFSET_H) offset.timestamp
+endif
+
+#
+#  ã«ã¼ãã«ã©ã¤ãã©ãªãã¡ã¤ã«ã®çæ
+#
+libkernel.a: $(OFFSET_H) $(KERNEL_LIB_OBJS)
+	rm -f libkernel.a
+	$(AR) -rcs libkernel.a $(KERNEL_LIB_OBJS)
+	$(RANLIB) libkernel.a
+
+#
+#  ä¸¦åmakeã®ããã®ä¾å­é¢ä¿ã®å®ç¾©
+#
+$(APPL_OBJS) $(SYSSVC_OBJS): | kernel_cfg.timestamp
+$(APPL_ASMOBJS) $(SYSSVC_ASMOBJS) $(KERNEL_ASMOBJS) $(CFG_ASMOBJS): \
+														| offset.timestamp
+
+#
+#  ç¹å¥ãªä¾å­é¢ä¿ã®å®ç¾©
+#
+$(OBJDIR)/banner.o: $(filter-out $(OBJDIR)/banner.o,$(ALL_OBJS)) \
+																$(LIBS_DEP)
+
+#
+#  å
+¨ä½ã®ãªã³ã¯
+#
+$(OBJFILE): $(ALL_OBJS) $(LIBS_DEP)
+	$(LINK) $(CFLAGS) $(LDFLAGS) $(OBJ_LDFLAGS) -o $(OBJFILE) \
+			-Wl,-Map=$(OBJNAME).map,--cref -Wl,--gc-sections -Wl,-e_kernel__start,--gc-keep-exported=_kernel_istk \
+			$(START_OBJS) $(APPL_OBJS) $(SYSSVC_OBJS) $(CFG_OBJS) \
+			-Wl,--start-group $(ALL_LIBS) -Wl,--end-group $(END_OBJS)
+
+#
+#  ä¾å­é¢ä¿ãã©ã«ãã®ä½æ
+#
+$(DEPDIR):
+	mkdir $@
+
+#
+#  ã·ã³ãã«ãã¡ã¤ã«ã®çæ
+#
+$(OBJNAME).syms: $(OBJFILE)
+	$(NM) -n $(OBJFILE) > $(OBJNAME).syms
+
+#
+#  ãã¤ããªãã¡ã¤ã«ã®çæ
+#
+$(OBJNAME).bin: $(OBJFILE)
+	$(OBJCOPY) -O binary -S $(OBJFILE) $(OBJNAME).bin
+	$(OBJDUMP) -h $(OBJFILE)
+	$(SIZE) $(OBJFILE)
+
+#
+#  Sã¬ã³ã¼ããã¡ã¤ã«ã®çæ
+#
+$(OBJNAME).srec: $(OBJFILE)
+	$(OBJCOPY) -O srec -S $(OBJFILE) $(OBJNAME).srec
+
+#
+#  ã¨ã©ã¼ãã§ãã¯å¦ç
+#
+.PHONY: check
+check: check.timestamp ;
+check.timestamp: $(APPL_CFG) $(OBJNAME).syms $(OBJNAME).srec
+#	$(CFG) --pass 3 --kernel asp $(INCLUDES) \
+#				--rom-image cfg1_out.srec --symbol-table cfg1_out.syms \
+#				-T $(OFFSET_TF) $(CFG_TABS) $<
+	touch -r $(OFFSET_H) check.timestamp
+	@echo "configuration check passed"
+
+#
+#  ã³ã³ãã¤ã«çµæã®æ¶å»
+#
+.PHONY: clean
+clean:
+	rm -f \#* *~ $(OBJDIR)/*.o $(DEPDIR)/*.d $(CLEAN_FILES)
+	rm -f $(OBJFILE) $(OBJNAME).syms $(OBJNAME).srec $(OBJNAME).bin
+	rm -f kernel_cfg.timestamp $(CFG2_OUT_SRCS)
+	rm -f offset.timestamp $(OFFSET_H)
+	rm -f cfg1_out.syms cfg1_out.srec $(CFG1_OUT)
+	rm -f cfg1_out.timestamp cfg1_out.c
+ifndef KERNEL_LIB
+	rm -f libkernel.a
+endif
+	rm -f makeoffset.s offset.h
+
+.PHONY: cleankernel
+cleankernel:
+	rm -f makeoffset.s $(OFFSET_H) $(KERNEL_LIB_OBJS)
+	rm -f $(KERNEL_LIB_OBJS:$(OBJDIR)/%.o=$(DEPDIR)/%.d)
+
+
+.PHONY: realclean
+realclean: clean
+	rm -f $(REALCLEAN_FILES)
+
+#
+#  ã³ã³ãã£ã®ã¥ã¬ã¼ã¿ãçæãããã¡ã¤ã«ã®ã³ã³ãã¤ã«ã«ã¼ã«ã®å®ç¾©
+#
+#  ã³ã³ãã£ã®ã¥ã¬ã¼ã¿ãçæãããã¡ã¤ã«ã¯ï¼å
+±éã®ã³ã³ãã¤ã«ãªãã·ã§ã³
+#  ã®ã¿ãä»ãã¦ã³ã³ãã¤ã«ããï¼
+#
+ALL_CFG_COBJS = $(CFG_COBJS) $(OBJDIR)/cfg1_out.o
+ALL_CFG_ASMOBJS = $(CFG_ASMOBJS)
+
+$(ALL_CFG_COBJS): $(OBJDIR)/%.o: %.c
+	$(CC) -c -o $@ -MD -MP -MF $(DEPDIR)/$*.d $(CFLAGS) $(CFG_CFLAGS) $<
+
+$(ALL_CFG_COBJS:$(OBJDIR)/%.o=%.s): %.s: %.c
+	$(CC) -S -o $@ $(CFLAGS) $(CFG_CFLAGS) $<
+
+$(ALL_CFG_ASMOBJS): $(OBJDIR)/%.o: %.S
+	$(CC) -c -o $@ -MD -MP -MF $(DEPDIR)/$*.d $(CFLAGS) $(CFG_CFLAGS) $<
+
+#
+#  ä¾å­é¢ä¿ãã¡ã¤ã«ã®ã¤ã³ã¯ã«ã¼ã
+#
+-include $(DEPDIR)/*.d
+
+#
+#  éçºãã¼ã«ã®ã³ãã³ãåã®å®ç¾©
+#
+ifeq ($(TOOL),gcc)
+	#
+	#  GNUéçºç°å¢ç¨
+	#
+	ifdef GCC_TARGET
+		GCC_TARGET_PREFIX = $(GCC_TARGET)-
+	else
+		GCC_TARGET_PREFIX =
+	endif
+	CC := $(GCC_TARGET_PREFIX)gcc
+	CXX := $(GCC_TARGET_PREFIX)g++
+	AS := $(GCC_TARGET_PREFIX)as
+	LD := $(GCC_TARGET_PREFIX)ld
+	AR := $(GCC_TARGET_PREFIX)ar
+	NM := $(GCC_TARGET_PREFIX)nm
+	RANLIB := $(GCC_TARGET_PREFIX)ranlib
+	OBJCOPY := $(GCC_TARGET_PREFIX)objcopy
+	OBJDUMP := $(GCC_TARGET_PREFIX)objdump
+	SIZE := $(GCC_TARGET_PREFIX)size
+endif
+
+ifdef DEVTOOLDIR
+	CC := $(DEVTOOLDIR)/$(CC)
+	CXX := $(DEVTOOLDIR)/$(CXX)
+	AS := $(DEVTOOLDIR)/$(AS)
+	LD := $(DEVTOOLDIR)/$(LD)
+	AR := $(DEVTOOLDIR)/$(AR)
+	NM := $(DEVTOOLDIR)/$(NM)
+	RANLIB := $(DEVTOOLDIR)/$(RANLIB)
+	OBJCOPY := $(DEVTOOLDIR)/$(OBJCOPY)
+	OBJDUMP := $(DEVTOOLDIR)/$(OBJDUMP)
+endif
+
+ifdef USE_CXX
+	LINK = $(CXX)
+else
+	LINK = $(CC)
+endif
+
+#
+#  ã³ã³ãã¤ã«ã«ã¼ã«ã®å®ç¾©
+#
+$(KERNEL_COBJS): $(OBJDIR)/%.o: %.c
+	$(CC) -c -o $@ -MD -MP -MF $(DEPDIR)/$*.d $(CFLAGS) $(KERNEL_CFLAGS) $<
+
+$(KERNEL_COBJS:$(OBJDIR)/%.o=%.s): %.s: %.c
+	$(CC) -S -o $@ $(CFLAGS) $(KERNEL_CFLAGS) $<
+
+$(KERNEL_LCOBJS): $(OBJDIR)/%.o:
+	$(CC) -c -o $@ -DTOPPERS_$(*F) -MD -MP -MF $(DEPDIR)/$*.d \
+									$(CFLAGS) $(KERNEL_CFLAGS) $<
+
+$(KERNEL_LCOBJS:$(OBJDIR)/%.o=%.s): %.s:
+	$(CC) -S -o $@ -DTOPPERS_$(*F) $(CFLAGS) $(KERNEL_CFLAGS) $<
+
+$(KERNEL_ASMOBJS): $(OBJDIR)/%.o: %.S
+	$(CC) -c -o $@ -MD -MP -MF $(DEPDIR)/$*.d $(CFLAGS) $(KERNEL_CFLAGS) $<
+
+$(SYSSVC_COBJS): $(OBJDIR)/%.o: %.c
+	$(CC) -c -o $@ -MD -MP -MF $(DEPDIR)/$*.d $(CFLAGS) $(SYSSVC_CFLAGS) $<
+
+$(SYSSVC_COBJS:$(OBJDIR)/%.o=%.s): %.s: %.c
+	$(CC) -S -o $@ $(CFLAGS) $(SYSSVC_CFLAGS) $<
+
+$(SYSSVC_ASMOBJS): $(OBJDIR)/%.o: %.S
+	$(CC) -c -o $@ -MD -MP -MF $(DEPDIR)/$*.d $(CFLAGS) $(SYSSVC_CFLAGS) $<
+
+$(APPL_COBJS): $(OBJDIR)/%.o: %.c
+	$(CC) -c -o $@ -MD -MP -MF $(DEPDIR)/$*.d $(CFLAGS) $(APPL_CFLAGS) $<
+
+$(APPL_COBJS:$(OBJDIR)/%.o=%.s): %.s: %.c
+	$(CC) -S -o $@ $(CFLAGS) $(APPL_CFLAGS) $<
+
+$(APPL_CXXOBJS): $(OBJDIR)/%.o: %.cpp
+	$(CXX) -c -o $@ -MD -MP -MF $(DEPDIR)/$*.d $(CFLAGS) $(APPL_CFLAGS) $<
+
+$(APPL_CXXOBJS:$(OBJDIR)/%.o=%.s): %.s: %.cpp
+	$(CXX) -S -o $@ $(CFLAGS) $(APPL_CFLAGS) $<
+
+$(APPL_ASMOBJS): $(OBJDIR)/%.o: %.S
+	$(CC) -c -o $@ -MD -MP -MF $(DEPDIR)/$*.d $(CFLAGS) $(APPL_CFLAGS) $<
+
+#
+#  ããã©ã«ãã³ã³ãã¤ã«ã«ã¼ã«ãä¸æ¸ã
+#
+$(OBJDIR)/%.o: %.c
+	@echo "*** Default compile rules should not be used."
+	$(CC) -c -o $@ -MD -MP -MF $(DEPDIR)/$*.d $(CFLAGS) $<
+
+%.s: %.c
+	@echo "*** Default compile rules should not be used."
+	$(CC) -S -o $@ $(CFLAGS) $<
+
+$(OBJDIR)/%.o: %.cpp
+	@echo "*** Default compile rules should not be used."
+	$(CXX) -c -o $@ -MD -MP -MF $(DEPDIR)/$*.d $(CFLAGS) $<
+
+%.s: %.cpp
+	@echo "*** Default compile rules should not be used."
+	$(CXX) -S -o $@ $(CFLAGS) $<
+
+$(OBJDIR)/%.o: %.S
+	@echo "*** Default compile rules should not be used."
+	$(CC) -c -o $@ -MD -MP -MF $(DEPDIR)/$*.d $(CFLAGS) $<
Index: azure_iot_hub_f767zi/trunk/app_iothub_client/Makefile
===================================================================
--- azure_iot_hub_f767zi/trunk/app_iothub_client/Makefile	(revision 457)
+++ azure_iot_hub_f767zi/trunk/app_iothub_client/Makefile	(revision 457)
@@ -0,0 +1,17 @@
+
+MAKE = make
+
+.PHONY: all
+all:
+	$(MAKE) -j -C Debug all
+
+kernel_cfg.h:
+	$(MAKE) -j 1 -C Debug kernel_cfg.h
+
+.PHONY: clean
+clean:
+	$(MAKE) -j -C Debug clean
+
+.PHONY: realclean
+realclean:
+	$(MAKE) -j -C Debug realclean
Index: azure_iot_hub_f767zi/trunk/app_iothub_client/pinkit/accelerometer.c
===================================================================
--- azure_iot_hub_f767zi/trunk/app_iothub_client/pinkit/accelerometer.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/app_iothub_client/pinkit/accelerometer.c	(revision 457)
@@ -0,0 +1,283 @@
+// https://github.com/ms-iotkithol-jp/IoTKitHoLV3/blob/master/PinKitIoTHubApp/PinKitIoTHubApp/PinKit/Accelerometer.cs
+
+#include <kernel.h>
+#include <t_syslog.h>
+#include <target_syssvc.h>
+#include "pinkit.h"
+#include "kernel_cfg.h"
+
+#define ADXL345_ADDR (0x1d << 1)
+// ADXL345 registers
+#define R_DEVID (0x00)
+#define R_THRESH_TAP (0x1D)
+#define R_OFSX (0x1E)
+#define R_OFSY (0x1F)
+#define R_OFSZ (0x20)
+#define R_DUR (0x21)
+#define R_Latent (0x22)
+#define R_Window (0x23)
+#define R_THRESH_INACT (0x25)
+#define R_TIME_INACT (0x26)
+#define R_ACT_INACT_CTL (0x27)
+#define R_THRESH_FF (0x28)
+#define R_TIME_FF (0x29)
+#define R_TAP_AXES (0x2A)
+#define R_ACT_TAP_STATUS (0x2B)
+#define R_BW_RATE (0x2C)
+#define R_POWER_CTL (0x2D)
+#define R_INT_ENABLE (0x2E)
+#define R_INT_MAP (0x2F)
+#define R_INT_SOURCE (0x30)
+#define R_DATA_FORMAT (0x31)
+#define R_DATAX0 (0x32)
+#define R_DATAX1 (0x33)
+#define R_DATAY0 (0x34)
+#define R_DATAY1 (0x35)
+#define R_DATAZ0 (0x36)
+#define R_DATAZ1 (0x37)
+#define R_FIFO_CTL (0x38)
+#define R_FIFO_STATUS (0x39)
+
+I2C_Handle_t *hi2c;
+#define GPIO_I2C_CS 13
+static int timeout = 1000;
+char xyz[6];
+
+int RegRead(uint8_t reg)
+{
+	ER ret;
+	int result = -1;
+	uint8_t rdata[1];
+
+	digitalWrite(GPIO_I2C_CS, 0);
+
+	ret = i2c_memread(hi2c, ADXL345_ADDR, (uint16_t)reg, I2C_MEMADD_SIZE_8BIT, rdata, 1, timeout);
+	if (ret != E_OK)
+		goto exit;
+
+	digitalWrite(GPIO_I2C_CS, 1);
+
+	result = rdata[0];
+exit:
+#ifdef DEBUG_ADXL345
+	printf("R[0x%2X]=0x%02X\n", reg, rdata[0]);
+#endif
+	return result;
+}
+
+int RegReads(uint8_t reg, char *data, int len)
+{
+	ER ret;
+	int result = -1;
+
+	digitalWrite(GPIO_I2C_CS, 0);
+
+	ret = i2c_memread(hi2c, ADXL345_ADDR, (uint16_t)reg, I2C_MEMADD_SIZE_8BIT, (uint8_t *)data, len, timeout);
+	if (ret != E_OK)
+		goto exit;
+
+	result = 0;
+exit:
+	digitalWrite(GPIO_I2C_CS, 1);
+
+#ifdef DEBUG_ADXL345
+	for (int i = 0; i < len; i++)
+	{
+		printf("R[0x%2X]=0x%02X\n", (reg + i), data[i]);
+	}
+#endif
+	return result;
+}
+
+int RegWrite(uint8_t reg, uint8_t val)
+{
+	ER ret;
+	int result = -1;
+	uint8_t wdata[1];
+
+	wdata[0] = val;
+
+	digitalWrite(GPIO_I2C_CS, 0);
+
+	ret = i2c_memwrite(hi2c, ADXL345_ADDR, (uint16_t)reg, I2C_MEMADD_SIZE_8BIT, wdata, 1, timeout);
+	if (ret != E_OK)
+		goto exit;
+
+	digitalWrite(GPIO_I2C_CS, 1);
+
+	result = 0;
+exit:
+	return result;
+}
+
+int RegWriteMask(uint8_t reg, uint8_t val, uint8_t mask)
+{
+	ER ret;
+	int result = -1;
+	uint8_t wdata[1];
+
+	uint8_t tmp = RegRead(reg);
+
+	wdata[0] = (uint8_t)(((int)tmp & ~(int)mask) | ((int)val & (int)mask));
+
+	digitalWrite(GPIO_I2C_CS, 0);
+
+	ret = i2c_memwrite(hi2c, ADXL345_ADDR, (uint16_t)reg, I2C_MEMADD_SIZE_8BIT, wdata, 1, timeout);
+	if (ret != E_OK)
+		goto exit;
+
+	digitalWrite(GPIO_I2C_CS, 1);
+
+	result = 0;
+exit:
+	return result;
+}
+
+uint8_t DeviceID()
+{
+	return RegRead(R_DEVID);
+}
+
+void ToSleep()
+{
+	RegWriteMask(R_POWER_CTL, 0x04, 0x04);
+}
+
+void ToWakeup()
+{
+	RegWriteMask(R_POWER_CTL, 0x00, 0x04);
+}
+
+// Normal Power
+// Code     Output  BandWidth
+// 0b1111   3200Hz  (1600Hz)
+// 0b1110   1600Hz  (800Hz)
+// 0b1101   800Hz   (40Hz)
+// 0b1100   400Hz   (200Hz)
+// 0b1011   200Hz   (100Hz)
+// 0b1010   100Hz   (50Hz)
+// 0b1001   50Hz    (25H)
+// 0b1000   25Hz    (12.5Hz)
+// 0b0111   12.5Hz  (6.25Hz)
+// 0b0110   6.25Hz  (3.125Hz)
+// Low Power
+// 0b1100   400Hz   (200Hz)
+// 0b1011   200Hz   (100Hz)
+// 0b1010   100Hz   (50Hz)
+// 0b1001   50Hz    (25H)
+// 0b1000   25Hz    (12.5Hz)
+// 0b0111   12.5Hz  (6.25Hz)
+void SetBW_RATE(uint8_t n)
+{
+	RegWrite(R_BW_RATE, n);
+}
+
+// D7: SELF_TEST
+// D6: SPI
+// D5: INT_INVERT
+// D4: 0
+// D3: FULL_RES
+// D2: Justfy
+// D1-D0: Range
+// 0 - 0: +-2g
+// 0 - 1: +-4g
+// 1 - 0: +-8g
+// 1 - 1: +-16g
+void SetDataFormat(uint8_t n)
+{
+	RegWrite(R_DATA_FORMAT, n);
+}
+
+void SetFullResolution()
+{
+	RegWriteMask(R_DATA_FORMAT, 0x08, 0x08);
+}
+
+void Measure()
+{
+	RegWriteMask(R_POWER_CTL, 0x08, 0x08);
+}
+
+static int ReadXYZ(int16_t *x, int16_t *y, int16_t *z)
+{
+	int result;
+	result = RegReads(R_DATAX0, xyz, 6);
+	*x = (int16_t)(((uint16_t)xyz[1] << 8) + (uint16_t)xyz[0]);
+	*y = (int16_t)(((uint16_t)xyz[3] << 8) + (uint16_t)xyz[2]);
+	*z = (int16_t)(((uint16_t)xyz[5] << 8) + (uint16_t)xyz[4]);
+	return result;
+}
+
+static bool measuring = false;
+
+/*
+ *  GPIO設定関数
+ */
+static void
+pinMode(uint8_t no, uint32_t mode)
+{
+	Arduino_PortControlBlock *pgcb = getGpioTable(DIGITAL_PIN, no);
+	GPIO_Init_t GPIO_Init_Data;
+
+	if(pgcb == NULL)
+		return;
+	pinClock(no);
+	GPIO_Init_Data.mode  = mode;
+	GPIO_Init_Data.pull  = GPIO_PULLUP;
+	GPIO_Init_Data.otype = GPIO_OTYPE_PP;
+	GPIO_Init_Data.speed = GPIO_SPEED_FAST;
+	gpio_setup(pgcb->giobase, &GPIO_Init_Data, pgcb->giopin);
+}
+
+bool Accelerometer_Init(int clockRate, int tmout)
+{
+	I2C_Init_t i2c_initd;
+
+	timeout = tmout;
+
+	i2c_initd.Timing          = 0x00D00E28;
+	i2c_initd.AddressingMode  = I2C_ADDRESSINGMODE_7BIT;
+	i2c_initd.DualAddressMode = I2C_DUALADDRESS_DISABLE;
+	i2c_initd.GeneralCallMode = I2C_GENERALCALL_DISABLE;
+	i2c_initd.NoStretchMode   = I2C_NOSTRETCH_DISABLE;
+	i2c_initd.OwnAddress1     = 0;
+	i2c_initd.OwnAddress2     = 0;
+	i2c_initd.semid           = I2CTRS_SEM;
+	i2c_initd.semlock         = I2CLOC_SEM;
+
+	if ((hi2c = i2c_init(I2C_PORTID, &i2c_initd)) == NULL) {
+		/* Initialization Error */
+		syslog_0(LOG_ERROR, "## I2C ERROR(1) ##");
+		return false;
+	}
+
+	pinMode(GPIO_I2C_CS, GPIO_MODE_OUTPUT);
+
+	ToWakeup();
+	dly_tsk(10);			// 10[ms]
+
+	SetDataFormat(0x01);    // +-2g 10bit
+	SetBW_RATE(0x19);       // sampling rate 50Hz
+
+	return true;
+}
+
+bool Accelerometer_TakeMeasurements(SensorReading *result)
+{
+	if (result == NULL)
+		return false;
+
+	if (!measuring)
+	{
+		Measure();
+	}
+
+	int16_t x, y, z;
+	int ret = ReadXYZ(&x, &y, &z);
+
+	result->X = ((double)x) / 127.0;
+	result->Y = ((double)y) / 127.0;
+	result->Z = ((double)z) / 127.0;
+
+	return ret == 0;
+}
Index: azure_iot_hub_f767zi/trunk/app_iothub_client/pinkit/accelerometer.h
===================================================================
--- azure_iot_hub_f767zi/trunk/app_iothub_client/pinkit/accelerometer.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/app_iothub_client/pinkit/accelerometer.h	(revision 457)
@@ -0,0 +1,20 @@
+// https://github.com/ms-iotkithol-jp/IoTKitHoLV3/blob/master/PinKitIoTHubApp/PinKitIoTHubApp/PinKit/Accelerometer.cs
+
+#include <stdint.h>
+#include <stdbool.h>
+
+#ifndef _ACCELEROMETER_H_
+#define _ACCELEROMETER_H_
+
+typedef struct SensorReading
+{
+	double X;
+	double Y;
+	double Z;
+} SensorReading;
+
+bool Accelerometer_Init(int clockRate, int tmout);
+bool Accelerometer_TakeMeasurements(SensorReading *result);
+
+
+#endif // _ACCELEROMETER_H_
Index: azure_iot_hub_f767zi/trunk/app_iothub_client/pinkit/boardfullcolorled.c
===================================================================
--- azure_iot_hub_f767zi/trunk/app_iothub_client/pinkit/boardfullcolorled.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/app_iothub_client/pinkit/boardfullcolorled.c	(revision 457)
@@ -0,0 +1,61 @@
+// https://github.com/ms-iotkithol-jp/IoTKitHoLV3/blob/master/PinKitIoTHubApp/PinKitIoTHubApp/PinKit/BoardFullColorLED.cs
+
+#include <kernel.h>
+#include "pinkit.h"
+#include "kernel_cfg.h"
+
+extern uint16_t led_state;
+
+// コンストラクター
+void BoardFullColorLED_Init()
+{
+	// 各 LED の InputPort インスタンス
+	led_state = 0;
+}
+
+/// <summary>
+/// 指定の色で LED を点灯、消灯する
+/// </summary>
+/// <param name="redOn">true ならば赤を点灯</param>
+/// <param name="greenOn">true ならば緑を点灯</param>
+/// <param name="blueOn">true ならば青を点灯</param>
+void BoardFullColorLED_SetRgb(bool redOn, bool greenOn, bool blueOn)
+{
+	if (redOn)
+		led_state |= LED01;
+	else
+		led_state &= ~LED01;
+	if (greenOn)
+		led_state |= LED02;
+	else
+		led_state &= ~LED02;
+	if (blueOn)
+		led_state |= LED03;
+	else
+		led_state &= ~LED03;
+	led_out(led_state);
+}
+
+/// <summary>
+/// 色名指定で LED を点灯する
+/// </summary>
+/// <param name="color"></param>
+void BoardFullColorLED_SetColor(Colors color)
+{
+	int redFlag = (int)color & (int)Colors_Red;
+	int greenFlag = (int)color & (int)Colors_Green;
+	int blueFlag = (int)color & (int)Colors_Blue;
+	if (redFlag != 0)
+		led_state |= LED01;
+	else
+		led_state &= ~LED01;
+	if (greenFlag != 0)
+		led_state |= LED02;
+	else
+		led_state &= ~LED02;
+	if (blueFlag != 0)
+		led_state |= LED03;
+	else
+		led_state &= ~LED03;
+	led_out(led_state);
+}
Index: azure_iot_hub_f767zi/trunk/app_iothub_client/pinkit/boardfullcolorled.h
===================================================================
--- azure_iot_hub_f767zi/trunk/app_iothub_client/pinkit/boardfullcolorled.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/app_iothub_client/pinkit/boardfullcolorled.h	(revision 457)
@@ -0,0 +1,25 @@
+// https://github.com/ms-iotkithol-jp/IoTKitHoLV3/blob/master/PinKitIoTHubApp/PinKitIoTHubApp/PinKit/BoardFullColorLED.cs
+
+#include <stdint.h>
+#include <stdbool.h>
+
+#ifndef _BOARD_FULL_COLOR_LED_H_
+#define _BOARD_FULL_COLOR_LED_H_
+
+typedef enum Colors
+{
+	Colors_Black = 0,
+	Colors_Red = 1,
+	Colors_Green = 2,
+	Colors_Yellow = 3,
+	Colors_Blue = 4,
+	Colors_Magenta = 5,
+	Colors_Cyan = 6,
+	Colors_White = 7
+} Colors;
+
+void BoardFullColorLED_Init();
+void BoardFullColorLED_SetRgb(bool redOn, bool greenOn, bool blueOn);
+void BoardFullColorLED_SetColor(Colors color);
+
+#endif // _BOARD_FULL_COLOR_LED_H_
Index: azure_iot_hub_f767zi/trunk/app_iothub_client/pinkit/lightsensor.c
===================================================================
--- azure_iot_hub_f767zi/trunk/app_iothub_client/pinkit/lightsensor.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/app_iothub_client/pinkit/lightsensor.c	(revision 457)
@@ -0,0 +1,107 @@
+// https://github.com/ms-iotkithol-jp/IoTKitHoLV3/blob/master/PinKitIoTHubApp/PinKitIoTHubApp/PinKit/LightSensor.cs
+
+#include <math.h>
+#include <kernel.h>
+#include <t_syslog.h>
+#include <target_syssvc.h>
+#include "pinkit.h"
+#include "kernel_cfg.h"
+
+ADC_Handle_t *aiLightSensor;
+
+volatile uint16_t LightSensorValue;
+
+/*
+ *  ADC転送終了コールバック関数
+ */
+static void HAL_ADC_ConvCpltCallback2(ADC_Handle_t* hadc)
+{
+	LightSensorValue = adc_getvalue(aiLightSensor);
+	adc_end_int(hadc);
+}
+
+bool LightSensor_Init()
+{
+	ADC_Init_t     aInit;
+	ADC_ChannelConf_t sConfig;
+	uint32_t event = 0;
+	int i;
+	Arduino_PortControlBlock *pcb;
+
+	/*
+	 *  ADC1初期化
+	 */
+	aInit.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV2;
+	aInit.Resolution = ADC_RESOLUTION_12B;
+	aInit.ScanConvMode = ADC_SCANMODE_DISABLE;
+//	aInit.ContinuousConvMode = ADC_CONTINUOUS_ENABLE;
+	aInit.ContinuousConvMode = ADC_CONTINUOUS_DISABLE;
+	aInit.DiscontinuousConvMode = ADC_DISCONTINUOUS_DISABLE;
+	aInit.NumDiscConversion = 0;
+	aInit.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
+	aInit.ExternalTrigConv = ADC_EXTERNALTRIGCONV_T1_CC1;
+	aInit.DataAlign = ADC_DATAALIGN_RIGHT;
+	aInit.NumConversion = 1;
+	aInit.DMAContinuousRequests = ADC_DMACONTINUOUS_ENABLE;
+	aInit.EOCSelection = ADC_EOC_SEQ_DISABLE;
+
+	if((aiLightSensor = adc_init(ADC1_PORTID, &aInit)) == NULL){
+		/* Initialization Error */
+		syslog_0(LOG_ERROR, "## adc_init ERROR ##");
+		return false;
+	}
+	aiLightSensor->xfercallback = HAL_ADC_ConvCpltCallback2;
+
+	/*
+	 *  ADCチャネル設定
+	 */
+	pcb = getGpioTable(ANALOG_PIN, 0);
+	sConfig.Channel = ADC_CHANNEL_0;
+	sConfig.Rank = 1;
+	sConfig.SamplingTime = ADC_SAMPLETIME_480CYCLES;
+	sConfig.GpioBase = pcb->giobase;
+	sConfig.GpioPin  = pcb->giopin;
+	if(adc_setupchannel(aiLightSensor, &sConfig) != E_OK){
+		/* Channel Configuration Error */
+		syslog_0(LOG_ERROR, "## adc_setupchannel ERROR ##");
+		return false;
+	}
+
+	/*
+	 *  ADC DMAスタート
+	 */
+	if(adc_start_int(aiLightSensor) != E_OK){
+		/* Start Conversation Error */
+		syslog_0(LOG_ERROR, "## adc_start_int ERROR ##");
+		return false;
+	}
+
+	return true;
+}
+
+bool LightSensor_Start()
+{
+	if (aiLightSensor->status >= ADC_STATUS_EOC)
+		return false;
+
+	/*
+	 *  ADC DMAスタート
+	 */
+	if(adc_start_int(aiLightSensor) != E_OK){
+		/* Start Conversation Error */
+		syslog_0(LOG_NOTICE, "## adc_start_dma ERROR ##");
+		return false;
+	}
+
+	return true;
+}
+
+double LightSensor_TakeMeasurement()
+{
+	if (aiLightSensor == NULL)
+		return 0.0;
+
+	int raw = LightSensorValue << (16 - 12);
+
+	return (double)raw / 65536.0;
+}
Index: azure_iot_hub_f767zi/trunk/app_iothub_client/pinkit/lightsensor.h
===================================================================
--- azure_iot_hub_f767zi/trunk/app_iothub_client/pinkit/lightsensor.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/app_iothub_client/pinkit/lightsensor.h	(revision 457)
@@ -0,0 +1,13 @@
+// https://github.com/ms-iotkithol-jp/IoTKitHoLV3/blob/master/PinKitIoTHubApp/PinKitIoTHubApp/PinKit/LightSensor.cs
+
+#include <stdint.h>
+#include <stdbool.h>
+
+#ifndef _LIGHT_SENSOR_H_
+#define _LIGHT_SENSOR_H_
+
+bool LightSensor_Init();
+bool LightSensor_Start();
+double LightSensor_TakeMeasurement();
+
+#endif // _LIGHT_SENSOR_H_
Index: azure_iot_hub_f767zi/trunk/app_iothub_client/pinkit/pinkit.c
===================================================================
--- azure_iot_hub_f767zi/trunk/app_iothub_client/pinkit/pinkit.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/app_iothub_client/pinkit/pinkit.c	(revision 457)
@@ -0,0 +1,54 @@
+/*
+ *  PinKitセンサータスク
+ */
+
+#include "pinkit.h"
+#include <math.h>
+#include "device.h"
+#include "syssvc/syslog.h"
+
+pinkit_t pinkit;
+uint16_t led_state = 0;
+
+void pinkit_task(intptr_t exinf)
+{
+	int i2c_error = 0;
+
+	Accelerometer_Init(100, 1000);
+	Temperature_Init();
+	BoardFullColorLED_Init();
+	LightSensor_Init();
+
+	for (;;) {
+		if (i2c_error < 3) {
+			if (Accelerometer_TakeMeasurements(&pinkit.accel))
+				i2c_error = 0;
+			else 
+				i2c_error++;
+		}
+		else {
+			i2c_error++;
+			if (i2c_error == 4) {
+				syslog(LOG_NOTICE, "Accelerometer error.");
+			}
+			else if (i2c_error >= 10000)
+				i2c_error = 0;
+		}
+
+		pinkit.temperature = Temperature_TakeMeasurement();
+		pinkit.humidity = LightSensor_TakeMeasurement();
+
+		BoardFullColorLED_SetRgb(fabs(pinkit.accel.X) > 0.5, fabs(pinkit.accel.Y) > 0.5, fabs(pinkit.accel.Z) > 0.5);
+		if (pinkit.ledOn)
+			led_state |= LED04;
+		else
+			led_state &= ~LED04;
+		led_out(led_state);
+
+		Temperature_Start();
+		LightSensor_Start();
+
+		dly_tsk(10);
+	}
+}
+
Index: azure_iot_hub_f767zi/trunk/app_iothub_client/pinkit/pinkit.cfg
===================================================================
--- azure_iot_hub_f767zi/trunk/app_iothub_client/pinkit/pinkit.cfg	(revision 457)
+++ azure_iot_hub_f767zi/trunk/app_iothub_client/pinkit/pinkit.cfg	(revision 457)
@@ -0,0 +1,19 @@
+/*
+ *  PinKitのシステムコンフィギュレーションファイル
+ */
+#include "pinkit.h"
+
+CRE_SEM(I2CTRS_SEM, { TA_TPRI, 0, 1 });
+CRE_SEM(I2CLOC_SEM, { TA_TPRI, 1, 1 });
+
+CRE_TSK(PINKIT_TASK, { TA_ACT, 0, pinkit_task, PINKIT_PRIORITY, PINKIT_STACK_SIZE, NULL });
+
+ATT_ISR({TA_NULL, I2C_PORTID, INTNO_I2CEV, i2c_ev_isr, 1 });
+CFG_INT(INTNO_I2CEV, { TA_ENAINT | INTATR_I2CEV, INTPRI_I2CEV });
+ATT_ISR({TA_NULL, I2C_PORTID, INTNO_I2CER, i2c_er_isr, 1 });
+CFG_INT(INTNO_I2CER, { TA_ENAINT | INTATR_I2CER, INTPRI_I2CER });
+
+ATT_ISR({TA_NULL, DMA2STM0_SID, INTNO_DMAADC, stream_dma_isr, 1 });
+CFG_INT(INTNO_DMAADC, { TA_ENAINT | INTATR_DMAADC, INTPRI_DMAADC });
+DEF_INH(INHNO_ADC, { TA_NULL, adc_int_handler });
+CFG_INT(INTNO_ADC, { TA_ENAINT | INTATR_ADC, INTPRI_ADC });
Index: azure_iot_hub_f767zi/trunk/app_iothub_client/pinkit/pinkit.h
===================================================================
--- azure_iot_hub_f767zi/trunk/app_iothub_client/pinkit/pinkit.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/app_iothub_client/pinkit/pinkit.h	(revision 457)
@@ -0,0 +1,61 @@
+/*
+ *  PinKitセンサータスク
+ */
+
+#ifndef _PINKIT_H_
+#define _PINKIT_H_
+
+#include <kernel.h>
+#include <t_syslog.h>
+#include <target_syssvc.h>
+#include "device.h"
+#include "pinmode.h"
+#include "i2c.h"
+#include "adc.h"
+#include "accelerometer.h"
+#include "temperature.h"
+#include "lightsensor.h"
+#include "boardfullcolorled.h"
+
+#define PINKIT_PRIORITY			5		/* PinKitタスクの優先度 */
+
+#define PINKIT_STACK_SIZE		1024	/* PinKitタスクのスタック領域のサイズ */
+
+#define I2C_PORTID I2C1_PORTID
+#define INHNO_I2CEV   IRQ_VECTOR_I2C1_EV	/* 割込みハンドラ番号 */
+#define INTNO_I2CEV   IRQ_VECTOR_I2C1_EV	/* 割込み番号 */
+#define INTPRI_I2CEV  -5			/* 割込み優先度 */
+#define INTATR_I2CEV  0				/* 割込み属性 */
+
+#define INHNO_I2CER   IRQ_VECTOR_I2C1_ER	/* 割込みハンドラ番号 */
+#define INTNO_I2CER   IRQ_VECTOR_I2C1_ER	/* 割込み番号 */
+#define INTPRI_I2CER  -5			/* 割込み優先度 */
+#define INTATR_I2CER  0				/* 割込み属性 */
+
+#define INHNO_ADC     IRQ_VECTOR_ADC	/* 割込みハンドラ番号 */
+#define INTNO_ADC     IRQ_VECTOR_ADC	/* 割込み番号 */
+#define INTPRI_ADC    -5          /* 割込み優先度 */
+#define INTATR_ADC    0           /* 割込み属性 */
+
+#define INHNO_DMAADC  IRQ_VECTOR_DMA2_STREAM0	/* 割込みハンドラ番号 */
+#define INTNO_DMAADC  IRQ_VECTOR_DMA2_STREAM0	/* 割込み番号 */
+#define INTPRI_DMAADC -4          /* 割込み優先度 */
+#define INTATR_DMAADC TA_EDGE     /* 割込み属性 */
+
+typedef struct pinkit_t {
+	SensorReading accel;
+	double temperature;
+	double humidity;
+	int ledOn;
+} pinkit_t;
+
+extern pinkit_t pinkit;
+
+extern void pinkit_task(intptr_t exinf);
+
+extern void device_info_init(intptr_t exinf);
+
+extern void i2c_ev_isr(intptr_t exinf);
+extern void i2c_er_isr(intptr_t exinf);
+
+#endif // _PINKIT_H_
Index: azure_iot_hub_f767zi/trunk/app_iothub_client/pinkit/temperature.c
===================================================================
--- azure_iot_hub_f767zi/trunk/app_iothub_client/pinkit/temperature.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/app_iothub_client/pinkit/temperature.c	(revision 457)
@@ -0,0 +1,119 @@
+// https://github.com/ms-iotkithol-jp/IoTKitHoLV3/blob/master/PinKitIoTHubApp/PinKitIoTHubApp/PinKit/Temperature.cs
+
+#include <math.h>
+#include <kernel.h>
+#include <t_syslog.h>
+#include <target_syssvc.h>
+#include "pinkit.h"
+#include "kernel_cfg.h"
+
+ADC_Handle_t *aiTemperature;
+
+// Adjust VR1 - Default 5000Ω
+double VR1;
+
+// B constant - Default 3435Ω
+double Bc;
+
+volatile uint16_t TemperatureValue;
+
+/*
+ *  ADC転送終了コールバック関数
+ */
+static void HAL_ADC_ConvCpltCallback2(ADC_Handle_t* hadc)
+{
+	TemperatureValue = adc_getvalue(aiTemperature);
+	adc_end_int(hadc);
+}
+
+bool Temperature_Init()
+{
+	ADC_Init_t     aInit;
+	ADC_ChannelConf_t sConfig;
+	uint32_t event = 0;
+	int i;
+	Arduino_PortControlBlock *pcb;
+
+	VR1 = 5000.0;
+	Bc = 3435.0;
+
+	/*
+	 *  ADC5初期化
+	 */
+	aInit.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV2;
+	aInit.Resolution = ADC_RESOLUTION_12B;
+	aInit.ScanConvMode = ADC_SCANMODE_DISABLE;
+	aInit.ContinuousConvMode = ADC_CONTINUOUS_ENABLE;
+	aInit.DiscontinuousConvMode = ADC_DISCONTINUOUS_DISABLE;
+	aInit.NumDiscConversion = 0;
+	aInit.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
+	aInit.ExternalTrigConv = ADC_EXTERNALTRIGCONV_T1_CC1;
+	aInit.DataAlign = ADC_DATAALIGN_RIGHT;
+	aInit.NumConversion = 1;
+	aInit.DMAContinuousRequests = ADC_DMACONTINUOUS_DISABLE;
+	aInit.EOCSelection = ADC_EOC_SEQ_DISABLE;
+
+	if((aiTemperature = adc_init(ADC3_PORTID, &aInit)) == NULL){
+		/* Initialization Error */
+		syslog_0(LOG_ERROR, "## adc_init ERROR ##");
+		return false;
+	}
+	aiTemperature->xfercallback = HAL_ADC_ConvCpltCallback2;
+
+	/*
+	 *  ADCチャネル設定
+	 */
+	pcb = getGpioTable(ANALOG_PIN, 5);
+	sConfig.Channel = ADC_CHANNEL_8;
+	sConfig.Rank = 1;
+	sConfig.SamplingTime = ADC_SAMPLETIME_480CYCLES;
+	sConfig.GpioBase = pcb->giobase;
+	sConfig.GpioPin  = pcb->giopin;
+	if(adc_setupchannel(aiTemperature, &sConfig) != E_OK){
+		/* Channel Configuration Error */
+		syslog_0(LOG_ERROR, "## adc_setupchannel ERROR ##");
+		return false;
+	}
+
+	/*
+	 *  ADC DMAスタート
+	 */
+	if(adc_start_int(aiTemperature) != E_OK){
+		/* Start Conversation Error */
+		syslog_0(LOG_ERROR, "## adc_start_int ERROR ##");
+		return false;
+	}
+
+	return true;
+}
+
+bool Temperature_Start()
+{
+	if (aiTemperature->status >= ADC_STATUS_EOC)
+		return false;
+
+	/*
+	 *  ADC DMAスタート
+	 */
+	if(adc_start_int(aiTemperature) != E_OK){
+		/* Start Conversation Error */
+		syslog_0(LOG_NOTICE, "## adc_start_int ERROR ##");
+		return false;
+	}
+
+	return true;
+}
+
+double Temperature_TakeMeasurement()
+{
+	if (aiTemperature == NULL)
+		return -273.15;
+
+	int raw = TemperatureValue << (16 - 12);
+
+	double tk = 273.0;
+	double t25 = tk + 25.0;
+	double r25 = 10000.0;
+	double t = 1.0 / (log(VR1 * raw / (65536 - raw) / r25) / Bc + 1.0 / t25) - tk;
+	return t;
+}
Index: azure_iot_hub_f767zi/trunk/app_iothub_client/pinkit/temperature.h
===================================================================
--- azure_iot_hub_f767zi/trunk/app_iothub_client/pinkit/temperature.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/app_iothub_client/pinkit/temperature.h	(revision 457)
@@ -0,0 +1,13 @@
+// https://github.com/ms-iotkithol-jp/IoTKitHoLV3/blob/master/PinKitIoTHubApp/PinKitIoTHubApp/PinKit/Temperature.cs
+
+#include <stdint.h>
+#include <stdbool.h>
+
+#ifndef _TEMPERATURE_H_
+#define _TEMPERATURE_H_
+
+bool Temperature_Init();
+bool Temperature_Start();
+double Temperature_TakeMeasurement();
+
+#endif // _TEMPERATURE_H_
Index: azure_iot_hub_f767zi/trunk/app_iothub_client/src/client.c
===================================================================
--- azure_iot_hub_f767zi/trunk/app_iothub_client/src/client.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/app_iothub_client/src/client.c	(revision 457)
@@ -0,0 +1,563 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+#include <stdio.h>
+#include <stdlib.h>
+
+/* This sample uses the _LL APIs of iothub_client for example purposes.
+That does not mean that HTTP only works with the _LL APIs.
+Simply changing the using the convenience layer (functions not having _LL)
+and removing calls to _DoWork will yield the same results. */
+
+#include "azure_c_shared_utility/threadapi.h"
+#include "azure_c_shared_utility/crt_abstractions.h"
+#include "azure_c_shared_utility/platform.h"
+#include "azure_c_shared_utility/shared_util_options.h"
+#include "iothub_client_ll.h"
+#include "iothub_message.h"
+#include "iothubtransporthttp.h"
+#include "iothubtransportmqtt.h"
+#include "iothubtransportmqtt_websockets.h"
+#include "iothub_client_options.h"
+#include "serializer.h"
+#include "serializer_devicetwin.h"
+#include "pinkit.h"
+#include "client.h"
+
+#ifdef _MSC_VER
+extern int sprintf_s(char* dst, size_t dstSizeInBytes, const char* format, ...);
+#endif // _MSC_VER
+
+#define SET_TRUSTED_CERT_IN_SAMPLES
+
+#ifdef SET_TRUSTED_CERT_IN_SAMPLES
+#include "certs.h"
+#endif // SET_TRUSTED_CERT_IN_SAMPLES
+
+/*String containing Hostname, Device Id & Device Key in the format:                         */
+/*  "HostName=<host_name>;DeviceId=<device_id>;SharedAccessKey=<device_key>"                */
+/*  "HostName=<host_name>;DeviceId=<device_id>;SharedAccessSignature=<device_sas_token>"    */
+char* connectionString = NULL;
+
+bool g_use_proxy;
+HTTP_PROXY_OPTIONS g_proxy_options;
+
+static int callbackCounter;
+static bool g_continueRunning;
+static bool g_twinReport;
+static char propText[1024];
+#define MESSAGE_COUNT       5
+#define DOWORK_LOOP_NUM     3
+
+typedef struct EVENT_INSTANCE_TAG
+{
+	IOTHUB_MESSAGE_HANDLE messageHandle;
+	size_t messageTrackingId;  // For tracking the messages within the user callback.
+} EVENT_INSTANCE;
+
+static IOTHUBMESSAGE_DISPOSITION_RESULT ReceiveMessageCallback(IOTHUB_MESSAGE_HANDLE message, void* userContextCallback)
+{
+	int* counter = (int*)userContextCallback;
+	const char* buffer;
+	size_t size;
+	MAP_HANDLE mapProperties;
+	const char* messageId;
+	const char* correlationId;
+	const char* contentType;
+	const char* contentEncoding;
+
+	// Message properties
+	if ((messageId = IoTHubMessage_GetMessageId(message)) == NULL)
+	{
+		messageId = "<null>";
+	}
+
+	if ((correlationId = IoTHubMessage_GetCorrelationId(message)) == NULL)
+	{
+		correlationId = "<null>";
+	}
+
+	if ((contentType = IoTHubMessage_GetContentTypeSystemProperty(message)) == NULL)
+	{
+		contentType = "<null>";
+	}
+
+	if ((contentEncoding = IoTHubMessage_GetContentEncodingSystemProperty(message)) == NULL)
+	{
+		contentEncoding = "<null>";
+	}
+
+	// Message content
+	if (IoTHubMessage_GetByteArray(message, (const unsigned char**)&buffer, &size) != IOTHUB_MESSAGE_OK)
+	{
+		printf("unable to retrieve the message data\r\n");
+	}
+	else
+	{
+		(void)printf("Received Message [%d]\r\n Message ID: %s\r\n Correlation ID: %s\r\n Content-Type: %s\r\n Content-Encoding: %s\r\n Data: <<<%.*s>>> & Size=%d\r\n",
+			*counter, messageId, correlationId, contentType, contentEncoding, (int)size, buffer, (int)size);
+		// If we receive the work 'quit' then we stop running
+		if (size == (strlen("quit") * sizeof(char)) && memcmp(buffer, "quit", size) == 0)
+		{
+			g_continueRunning = false;
+		}
+	}
+
+	// Retrieve properties from the message
+	mapProperties = IoTHubMessage_Properties(message);
+	if (mapProperties != NULL)
+	{
+		const char*const* keys;
+		const char*const* values;
+		size_t propertyCount = 0;
+		if (Map_GetInternals(mapProperties, &keys, &values, &propertyCount) == MAP_OK)
+		{
+			if (propertyCount > 0)
+			{
+				size_t index;
+
+				printf(" Message Properties:\r\n");
+				for (index = 0; index < propertyCount; index++)
+				{
+					(void)printf("\tKey: %s Value: %s\r\n", keys[index], values[index]);
+				}
+				(void)printf("\r\n");
+			}
+		}
+	}
+
+	/* Some device specific action code goes here... */
+	(*counter)++;
+	return IOTHUBMESSAGE_ACCEPTED;
+}
+
+// Define the Model
+BEGIN_NAMESPACE(WeatherStation);
+
+DECLARE_MODEL(ContosoAnemometer,
+WITH_DATA(double, windSpeed),
+WITH_DATA(double, temperature),
+WITH_DATA(double, humidity),
+WITH_METHOD(quit),
+WITH_METHOD(turnLedOn),
+WITH_METHOD(turnLedOff)
+);
+
+DECLARE_STRUCT(ThresholdD,
+	double, value
+);
+
+DECLARE_STRUCT(ThresholdR,
+	double, value,
+	ascii_char_ptr, status
+);
+
+DECLARE_DEVICETWIN_MODEL(AnemometerState,
+WITH_REPORTED_PROPERTY(ThresholdR, threshold)
+);
+
+DECLARE_DEVICETWIN_MODEL(AnemometerSettings,
+WITH_DESIRED_PROPERTY(ThresholdD, threshold, onDesiredThreshold)
+);
+
+END_NAMESPACE(WeatherStation);
+
+void anemometerReportedStateCallback(int status_code, void* userContextCallback)
+{
+	AnemometerState *anemometer = (AnemometerState *)userContextCallback;
+
+	printf("received states \033[43m%d\033[49m, reported threshold = %.1f\n", status_code, anemometer->threshold.value);
+}
+
+void onDesiredThreshold(void* argument)
+{
+	// Note: The argument is NOT a pointer to threshold, but instead a pointer to the MODEL
+	//       that contains threshold as one of its arguments.  In this case, it
+	//       is AnemometerSettings*.
+
+	AnemometerSettings *anemometer = (AnemometerSettings *)argument;
+	printf("received a new desired.threshold = \033[42m%.1f\033[49m\n", anemometer->threshold.value);
+
+	g_twinReport = true;
+}
+
+METHODRETURN_HANDLE quit(ContosoAnemometer* device)
+{
+	(void)device;
+	(void)printf("quit with Method.\r\n");
+
+	g_continueRunning = false;
+
+	METHODRETURN_HANDLE result = MethodReturn_Create(0, "{\"Message\":\"quit with Method\"}");
+	return result;
+}
+
+METHODRETURN_HANDLE turnLedOn(ContosoAnemometer* device)
+{
+	(void)device;
+	(void)printf("\033[41mTurning LED on with Method.\033[49m\r\n");
+
+	pinkit.ledOn = 1;
+
+	METHODRETURN_HANDLE result = MethodReturn_Create(1, "{\"Message\":\"Turning fan on with Method\"}");
+	return result;
+}
+
+METHODRETURN_HANDLE turnLedOff(ContosoAnemometer* device)
+{
+	(void)device;
+	(void)printf("\033[44mTurning LED off with Method.\033[49m\r\n");
+
+	pinkit.ledOn = 0;
+
+	METHODRETURN_HANDLE result = MethodReturn_Create(0, "{\"Message\":\"Turning fan off with Method\"}");
+	return result;
+}
+
+static int ReceiveDeviceMethodCallback(const char* method_name, const unsigned char* payload, size_t size, unsigned char** response, size_t* resp_size, void* userContextCallback)
+{
+	int result;
+
+	/*this is step  3: receive the method and push that payload into serializer (from below)*/
+	char* payloadZeroTerminated = (char*)malloc(size + 1);
+	if (payloadZeroTerminated == 0)
+	{
+		printf("failed to malloc\r\n");
+		*resp_size = 0;
+		*response = NULL;
+		result = -1;
+	}
+	else
+	{
+		(void)memcpy(payloadZeroTerminated, payload, size);
+		payloadZeroTerminated[size] = '\0';
+
+		/*execute method - userContextCallback is of type deviceModel*/
+		METHODRETURN_HANDLE methodResult = EXECUTE_METHOD(userContextCallback, method_name, payloadZeroTerminated);
+		free(payloadZeroTerminated);
+
+		if (methodResult == NULL)
+		{
+			printf("failed to EXECUTE_METHOD\r\n");
+			*resp_size = 0;
+			*response = NULL;
+			result = -1;
+		}
+		else
+		{
+			/* get the serializer answer and push it in the networking stack*/
+			const METHODRETURN_DATA* data = MethodReturn_GetReturn(methodResult);
+			if (data == NULL)
+			{
+				printf("failed to MethodReturn_GetReturn\r\n");
+				*resp_size = 0;
+				*response = NULL;
+				result = -1;
+			}
+			else
+			{
+				result = data->statusCode;
+				if (data->jsonValue == NULL)
+				{
+					char* resp = "{}";
+					*resp_size = strlen(resp);
+					*response = (unsigned char*)malloc(*resp_size);
+					(void)memcpy(*response, resp, *resp_size);
+				}
+				else
+				{
+					*resp_size = strlen(data->jsonValue);
+					*response = (unsigned char*)malloc(*resp_size);
+					(void)memcpy(*response, data->jsonValue, *resp_size);
+				}
+			}
+			MethodReturn_Destroy(methodResult);
+		}
+	}
+	return result;
+}
+
+static void SendConfirmationCallback(IOTHUB_CLIENT_CONFIRMATION_RESULT result, void* userContextCallback)
+{
+	EVENT_INSTANCE* eventInstance = (EVENT_INSTANCE*)userContextCallback;
+
+	(void)printf("Confirmation[%d] received for message tracking id = %u with result = %s\r\n", callbackCounter, eventInstance->messageTrackingId, MU_ENUM_TO_STRING(IOTHUB_CLIENT_CONFIRMATION_RESULT, result));
+
+	/* Some device specific action code goes here... */
+	callbackCounter++;
+	IoTHubMessage_Destroy(eventInstance->messageHandle);
+}
+
+void iothub_client_run(int proto)
+{
+	IOTHUB_CLIENT_LL_HANDLE iotHubClientHandle;
+
+	EVENT_INSTANCE messages[MESSAGE_COUNT];
+	int msg_id = 0;
+	double avgWindSpeed = 10.0;
+	double minTemperature = 20.0;
+	double minHumidity = 60.0;
+	int receiveContext = 0;
+
+	g_continueRunning = true;
+
+	srand((unsigned int)time(NULL));
+
+	callbackCounter = 0;
+
+	if (platform_init() != 0)
+	{
+		(void)printf("Failed to initialize the platform.\r\n");
+	}
+	else {
+		if (serializer_init(NULL) != SERIALIZER_OK)
+		{
+			(void)printf("Failed in serializer_init.");
+		}
+		else if (SERIALIZER_REGISTER_NAMESPACE(WeatherStation) == NULL)
+		{
+			LogError("unable to SERIALIZER_REGISTER_NAMESPACE");
+		}
+		else
+		{
+			IOTHUB_CLIENT_TRANSPORT_PROVIDER protocol;
+			switch (proto) {
+			case 0:
+				(void)printf("Starting the IoTHub client sample HTTP...\r\n");
+				protocol = HTTP_Protocol;
+				break;
+			case 1:
+				(void)printf("Starting the IoTHub client sample MQTT...\r\n");
+				protocol = MQTT_Protocol;
+				break;
+			case 2:
+				(void)printf("Starting the IoTHub client sample MQTT over WebSocket...\r\n");
+				protocol = MQTT_WebSocket_Protocol;
+				break;
+			default:
+				platform_deinit();
+				return;
+			}
+
+			if ((iotHubClientHandle = IoTHubClient_LL_CreateFromConnectionString(connectionString, protocol)) == NULL)
+			{
+				(void)printf("ERROR: iotHubClientHandle is NULL!\r\n");
+			}
+			else
+			{
+				if (g_use_proxy)
+				{
+					if (IoTHubClient_LL_SetOption(iotHubClientHandle, OPTION_HTTP_PROXY, &g_proxy_options) != IOTHUB_CLIENT_OK)
+					{
+						printf("failure to set option \"HTTP Proxy\"\r\n");
+					}
+				}
+#if 0
+				long curl_verbose = 1;
+				if (IoTHubClient_LL_SetOption(iotHubClientHandle, OPTION_CURL_VERBOSE, &curl_verbose) != IOTHUB_CLIENT_OK)
+				{
+					printf("failure to set option \"CURL Verbose\"\r\n");
+				}
+
+				unsigned int timeout = 241000;
+				// Because it can poll "after 9 seconds" polls will happen effectively // at ~10 seconds.
+				// Note that for scalabilty, the default value of minimumPollingTime
+				// is 25 minutes. For more information, see:
+				// https://azure.microsoft.com/documentation/articles/iot-hub-devguide/#messaging
+				unsigned int minimumPollingTime = 9;
+				if (IoTHubClient_LL_SetOption(iotHubClientHandle, "timeout", &timeout) != IOTHUB_CLIENT_OK)
+				{
+					printf("failure to set option \"timeout\"\r\n");
+				}
+
+				if (IoTHubClient_LL_SetOption(iotHubClientHandle, "MinimumPollingTime", &minimumPollingTime) != IOTHUB_CLIENT_OK)
+				{
+					printf("failure to set option \"MinimumPollingTime\"\r\n");
+				}
+
+				bool traceOn = 1;
+				if (IoTHubClient_LL_SetOption(iotHubClientHandle, OPTION_LOG_TRACE, &traceOn) != IOTHUB_CLIENT_OK)
+				{
+					printf("failure to set option \"log trace on\"\r\n");
+				}
+#endif
+#ifdef SET_TRUSTED_CERT_IN_SAMPLES
+				// For mbed add the certificate information
+				if (IoTHubClient_LL_SetOption(iotHubClientHandle, OPTION_TRUSTED_CERT, certificates) != IOTHUB_CLIENT_OK)
+				{
+					printf("failure to set option \"TrustedCerts\"\r\n");
+				}
+#endif // SET_TRUSTED_CERT_IN_SAMPLES
+				AnemometerState *anemometerState = IoTHubDeviceTwin_LL_CreateAnemometerState(iotHubClientHandle);
+				if (anemometerState == NULL)
+				{
+					printf("Failure in IoTHubDeviceTwin_LL_CreateAnemometerState");
+				}
+				else
+				{
+					(void)printf("IoTHubDeviceTwin_LL_CreateAnemometerState...successful.\r\n");
+				}
+				AnemometerSettings *anemometerSettings = IoTHubDeviceTwin_LL_CreateAnemometerSettings(iotHubClientHandle);
+				if (anemometerSettings == NULL)
+				{
+					printf("Failure in IoTHubDeviceTwin_LL_CreateAnemometerSettings");
+				}
+				else
+				{
+					(void)printf("IoTHubDeviceTwin_LL_CreateAnemometerSettings...successful.\r\n");
+				}
+				ContosoAnemometer* myWeather = CREATE_MODEL_INSTANCE(WeatherStation, ContosoAnemometer);
+				if (myWeather == NULL)
+				{
+					(void)printf("Failed on CREATE_MODEL_INSTANCE\r\n");
+				}
+				else if (IoTHubClient_LL_SetDeviceMethodCallback(iotHubClientHandle, ReceiveDeviceMethodCallback, myWeather) != IOTHUB_CLIENT_OK)
+				{
+					(void)printf("ERROR: IoTHubClient_LL_SetDeviceMethodCallback..........FAILED!\r\n");
+				}
+				else
+				{
+					(void)printf("IoTHubClient_LL_SetDeviceMethodCallback...successful.\r\n");
+				}
+				/* Setting Message call back, so we can receive Commands. */
+				if (IoTHubClient_LL_SetMessageCallback(iotHubClientHandle, ReceiveMessageCallback, &receiveContext) != IOTHUB_CLIENT_OK)
+				{
+					(void)printf("ERROR: IoTHubClient_LL_SetMessageCallback..........FAILED!\r\n");
+				}
+				else
+				{
+					(void)printf("IoTHubClient_LL_SetMessageCallback...successful.\r\n");
+				}
+
+				/* Now that we are ready to receive commands, let's send some messages */
+				int iterator = 4000;
+				do
+				{
+					if (iterator >= 5000)
+					{
+						iterator = 0;
+						int msgPos = msg_id % MESSAGE_COUNT;
+						unsigned char *msgText;
+						size_t msgSize;
+						myWeather->windSpeed = avgWindSpeed + (rand() % 4 + 2);
+						myWeather->temperature = pinkit.temperature;
+						myWeather->humidity = minHumidity + (rand() % 20);
+						if (SERIALIZE(&msgText, &msgSize, myWeather->windSpeed, myWeather->temperature, myWeather->humidity) != CODEFIRST_OK)
+						{
+							(void)printf("Failed to serialize\r\n");
+						}
+						else if ((messages[msgPos].messageHandle = IoTHubMessage_CreateFromByteArray((const unsigned char*)msgText, msgSize)) == NULL)
+						{
+							(void)printf("ERROR: iotHubMessageHandle is NULL!\r\n");
+							free(msgText);
+						}
+						else
+						{
+							MAP_HANDLE propMap;
+
+							messages[msgPos].messageTrackingId = msg_id;
+
+							propMap = IoTHubMessage_Properties(messages[msgPos].messageHandle);
+							(void)sprintf_s(propText, sizeof(propText), myWeather->temperature > anemometerSettings->threshold.value ? "true" : "false");
+							if (Map_AddOrUpdate(propMap, "temperatureAlert", propText) != MAP_OK)
+							{
+								(void)printf("ERROR: Map_AddOrUpdate Failed!\r\n");
+							}
+
+							if (proto == 0) {
+								(void)IoTHubMessage_SetContentTypeSystemProperty(messages[msgPos].messageHandle, "application/json");
+								(void)IoTHubMessage_SetContentEncodingSystemProperty(messages[msgPos].messageHandle, "utf-8");
+							}
+
+							if (IoTHubClient_LL_SendEventAsync(iotHubClientHandle, messages[msgPos].messageHandle, SendConfirmationCallback, &messages[msgPos]) != IOTHUB_CLIENT_OK)
+							{
+								(void)printf("ERROR: IoTHubClient_LL_SendEventAsync..........FAILED!\r\n");
+							}
+							else
+							{
+								(void)printf("IoTHubClient_LL_SendEventAsync accepted message [%d] for transmission to IoT Hub.\r\n", msg_id);
+							}
+
+							free(msgText);
+							msg_id++;
+						}
+					}
+					else if (g_twinReport) {
+						g_twinReport = false;
+						anemometerState->threshold.value = anemometerSettings->threshold.value;
+						anemometerState->threshold.status = "success";
+						IoTHubDeviceTwin_LL_SendReportedStateAnemometerState(anemometerState, anemometerReportedStateCallback, anemometerState);
+					}
+					iterator++;
+
+					IoTHubClient_LL_DoWork(iotHubClientHandle);
+					ThreadAPI_Sleep(1);
+
+				} while (g_continueRunning);
+
+				(void)printf("iothub_client_run has gotten quit message, call DoWork %d more time to complete final sending...\r\n", DOWORK_LOOP_NUM);
+				for (size_t index = 0; index < DOWORK_LOOP_NUM; index++)
+				{
+					IoTHubClient_LL_DoWork(iotHubClientHandle);
+					ThreadAPI_Sleep(1);
+				}
+
+				if (anemometerSettings != NULL)
+					IoTHubDeviceTwin_LL_DestroyAnemometerSettings(anemometerSettings);
+				if (anemometerState != NULL)
+					IoTHubDeviceTwin_LL_DestroyAnemometerState(anemometerState);
+				if (myWeather != NULL)
+					DESTROY_MODEL_INSTANCE(myWeather);
+				IoTHubClient_LL_Destroy(iotHubClientHandle);
+			}
+			serializer_deinit();
+		}
+		platform_deinit();
+	}
+}
+
+void iothub_client_init()
+{
+#if 0
+	char *set_cs_argv[2] = {
+		"set_cs",
+		"[device connection string]"
+	};
+	set_cs_main(2, set_cs_argv);
+
+	char *set_proxy_argv[2] = {
+		"set_proxy",
+		"example.com:8080"
+	};
+	set_proxy_main(2, set_proxy_argv);
+#endif
+}
+
+int iothub_client_main(int argc, char **argv)
+{
+	if (connectionString == NULL) {
+		printf("Not set connection string, use 'device csgen' or 'device setcs'.\n");
+		return 0;
+	}
+
+	if (argc < 2) {
+		iothub_client_run(1);
+		return 0;
+	}
+
+	if (strcmp(argv[1], "http") == 0) {
+		iothub_client_run(0);
+		return 0;
+	}
+	else if (strcmp(argv[1], "mqtt") == 0) {
+		iothub_client_run(1);
+		return 0;
+	}
+	else if (strcmp(argv[1], "mqttows") == 0) {
+		iothub_client_run(2);
+		return 0;
+	}
+
+	printf("%s [http|mqtt|mqttows] \n", argv[0]);
+	return 0;
+}
Index: azure_iot_hub_f767zi/trunk/app_iothub_client/src/client.h
===================================================================
--- azure_iot_hub_f767zi/trunk/app_iothub_client/src/client.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/app_iothub_client/src/client.h	(revision 457)
@@ -0,0 +1,20 @@
+#ifndef CLIENT_H
+#define CLIENT_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void iothub_client_init(void);
+int iothub_client_main(int argc, char **argv);
+int set_cs_main(int argc, char **argv);
+int set_proxy_main(int argc, char **argv);
+int clear_proxy_main(int argc, char **argv);
+int pinkit_main(int argc, char **argv);
+int dps_csgen_main(int argc, char **argv);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* CLIENT_H */
Index: azure_iot_hub_f767zi/trunk/app_iothub_client/src/code.c
===================================================================
--- azure_iot_hub_f767zi/trunk/app_iothub_client/src/code.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/app_iothub_client/src/code.c	(revision 457)
@@ -0,0 +1,260 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+
+// hint on compile; copy the source code here and paste onto ->
+// azure-iot-sdk-c/provisioning_client/samples/prov_dev_client_ll_sample/prov_dev_client_ll_sample.c
+// compile the whole SDK with provisioning enabled
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "iothub.h"
+#include "iothub_message.h"
+#include "iothub_client_version.h"
+#include "azure_c_shared_utility/threadapi.h"
+#include "azure_c_shared_utility/tickcounter.h"
+#include "azure_c_shared_utility/shared_util_options.h"
+#include "azure_c_shared_utility/http_proxy_io.h"
+
+#include "iothub_device_client_ll.h"
+#include "iothub_client_options.h"
+#include "azure_prov_client/prov_device_ll_client.h"
+#include "azure_prov_client/prov_security_factory.h"
+
+#include "iothubtransporthttp.h"
+#include "azure_prov_client/prov_transport_http_client.h"
+#include "iothubtransportmqtt.h"
+#include "azure_prov_client/prov_transport_mqtt_client.h"
+#include "iothubtransportmqtt_websockets.h"
+#include "azure_prov_client/prov_transport_mqtt_ws_client.h"
+#include "client.h"
+
+#define SET_TRUSTED_CERT_IN_SAMPLES
+
+#ifdef SET_TRUSTED_CERT_IN_SAMPLES
+#include "certs.h"
+#endif // SET_TRUSTED_CERT_IN_SAMPLES
+
+extern char* connectionString;
+
+MU_DEFINE_ENUM_STRINGS(PROV_DEVICE_RESULT, PROV_DEVICE_RESULT_VALUE);
+MU_DEFINE_ENUM_STRINGS(PROV_DEVICE_REG_STATUS, PROV_DEVICE_REG_STATUS_VALUES);
+
+static const char *global_prov_uri = "global.azure-devices-provisioning.net";
+static char *g_access_key = NULL;
+
+extern bool g_use_proxy;
+extern HTTP_PROXY_OPTIONS g_proxy_options;
+
+#define MESSAGES_TO_SEND            2
+#define TIME_BETWEEN_MESSAGES       2
+
+typedef struct CLIENT_SAMPLE_INFO_TAG
+{
+	unsigned int sleep_time;
+	char *iothub_uri;
+	char *access_key_name;
+	char *device_key;
+	char *device_id;
+	int registration_complete;
+} CLIENT_SAMPLE_INFO;
+
+typedef struct IOTHUB_CLIENT_SAMPLE_INFO_TAG
+{
+	int connected;
+	int stop_running;
+} IOTHUB_CLIENT_SAMPLE_INFO;
+
+static IOTHUBMESSAGE_DISPOSITION_RESULT receive_msg_callback(IOTHUB_MESSAGE_HANDLE message, void *user_context)
+{
+	(void)message;
+	IOTHUB_CLIENT_SAMPLE_INFO *iothub_info = (IOTHUB_CLIENT_SAMPLE_INFO *)user_context;
+	(void)printf("Stop message recieved from IoTHub\r\n");
+	iothub_info->stop_running = 1;
+	return IOTHUBMESSAGE_ACCEPTED;
+}
+
+static void registation_status_callback(PROV_DEVICE_REG_STATUS reg_status, void *user_context)
+{
+	(void)user_context;
+	(void)printf(".");
+}
+
+static void iothub_connection_status(IOTHUB_CLIENT_CONNECTION_STATUS result, IOTHUB_CLIENT_CONNECTION_STATUS_REASON reason, void *user_context)
+{
+	(void)reason;
+	if (user_context == NULL)
+	{
+		printf("iothub_connection_status user_context is NULL\r\n");
+	}
+	else
+	{
+		IOTHUB_CLIENT_SAMPLE_INFO *iothub_info = (IOTHUB_CLIENT_SAMPLE_INFO *)user_context;
+		if (result == IOTHUB_CLIENT_CONNECTION_AUTHENTICATED)
+		{
+			iothub_info->connected = 1;
+		}
+		else
+		{
+			iothub_info->connected = 0;
+			iothub_info->stop_running = 1;
+		}
+	}
+}
+
+static void register_device_callback(PROV_DEVICE_RESULT register_result, const char *iothub_uri, const char *device_id, void *user_context)
+{
+	if (user_context == NULL)
+	{
+		printf("user_context is NULL\r\n");
+	}
+	else
+	{
+		CLIENT_SAMPLE_INFO *user_ctx = (CLIENT_SAMPLE_INFO *)user_context;
+		if (register_result == PROV_DEVICE_RESULT_OK)
+		{
+			(void)printf("\nRegistration Information received from service: %s!\r\n", iothub_uri);
+			(void)mallocAndStrcpy_s(&user_ctx->iothub_uri, iothub_uri);
+			(void)mallocAndStrcpy_s(&user_ctx->device_id, device_id);
+			user_ctx->registration_complete = 1;
+
+			size_t len = snprintf(NULL, 0,
+				"HostName=%s;DeviceId=%s;SharedAccessKey=%s",
+				iothub_uri,
+				device_id,
+				g_access_key);
+			char *conn_str = (char *)malloc(len + 1);
+			if (conn_str == NULL) {
+				printf("OOM while creating connection string\n");
+				exit(1);
+			}
+
+			snprintf(conn_str, len + 1,
+				"HostName=%s;DeviceId=%s;SharedAccessKey=%s",
+				iothub_uri,
+				device_id,
+				g_access_key);
+			conn_str[len] = 0;
+			free(connectionString);
+			connectionString = conn_str;
+			printf("Connection String:\n%s\n", connectionString);
+		}
+		else
+		{
+			(void)printf("Failure encountered on registration %s\r\n", MU_ENUM_TO_STRING(PROV_DEVICE_RESULT, register_result));
+			user_ctx->registration_complete = 2;
+		}
+	}
+}
+
+int dps_csgen_main(int argc, char *argv[])
+{
+	if (argc < 5) {
+		printf("usage:\ndps_csgen [http|mqtt|mqttows] <scope_id> <device_id> <primary_key (groupSAS)>\n");
+		return 0;
+	}
+
+	IOTHUB_CLIENT_TRANSPORT_PROVIDER iothub_transport;
+	PROV_DEVICE_TRANSPORT_PROVIDER_FUNCTION prov_device_protocol;
+
+	if (strcmp(argv[1], "http") == 0) {
+		iothub_transport = HTTP_Protocol;
+		prov_device_protocol = Prov_Device_HTTP_Protocol;
+	}
+	else if (strcmp(argv[1], "mqtt") == 0) {
+		iothub_transport = MQTT_Protocol;
+		prov_device_protocol = Prov_Device_MQTT_Protocol;
+	}
+	else if (strcmp(argv[1], "mqttows") == 0) {
+		iothub_transport = MQTT_WebSocket_Protocol;
+		prov_device_protocol = Prov_Device_MQTT_WS_Protocol;
+	}
+	else {
+		iothub_transport = MQTT_Protocol;
+		prov_device_protocol = Prov_Device_MQTT_Protocol;
+	}
+
+	const char *scope_id = argv[2];
+	const char *reg_id = argv[3];
+	g_access_key = argv[4];
+	prov_dev_set_symmetric_key_info(reg_id, g_access_key);
+
+	bool traceOn = false;
+
+	(void)IoTHub_Init();
+	(void)prov_dev_security_init(SECURE_DEVICE_TYPE_SYMMETRIC_KEY);
+	HTTP_PROXY_OPTIONS http_proxy;
+	CLIENT_SAMPLE_INFO user_ctx;
+
+	memset(&http_proxy, 0, sizeof(HTTP_PROXY_OPTIONS));
+	memset(&user_ctx, 0, sizeof(CLIENT_SAMPLE_INFO));
+
+	user_ctx.registration_complete = 0;
+	user_ctx.sleep_time = 10;
+
+	PROV_DEVICE_LL_HANDLE handle;
+	if ((handle = Prov_Device_LL_Create(global_prov_uri, scope_id, prov_device_protocol)) == NULL)
+	{
+		(void)printf("failed calling Prov_Device_LL_Create\r\n");
+	}
+	else
+	{
+		if (g_use_proxy)
+		{
+			Prov_Device_LL_SetOption(handle, OPTION_HTTP_PROXY, &g_proxy_options);
+		}
+
+#ifdef SET_TRUSTED_CERT_IN_SAMPLES
+	// For mbed add the certificate information
+		if (Prov_Device_LL_SetOption(handle, OPTION_TRUSTED_CERT, certificates) != PROV_DEVICE_RESULT_OK)
+		{
+			printf("failure to set option \"TrustedCerts\"\r\n");
+		}
+#endif // SET_TRUSTED_CERT_IN_SAMPLES
+
+		Prov_Device_LL_SetOption(handle, PROV_OPTION_LOG_TRACE, &traceOn);
+		if (Prov_Device_LL_Register_Device(handle, register_device_callback, &user_ctx, registation_status_callback, &user_ctx) != PROV_DEVICE_RESULT_OK)
+		{
+			(void)printf("failed calling Prov_Device_LL_Register_Device\r\n");
+		}
+		else
+		{
+			do
+			{
+				Prov_Device_LL_DoWork(handle);
+				ThreadAPI_Sleep(user_ctx.sleep_time);
+			} while (user_ctx.registration_complete == 0);
+		}
+		Prov_Device_LL_Destroy(handle);
+	}
+
+	if (user_ctx.registration_complete != 1)
+	{
+		(void)printf("error: registration failed!\r\n");
+	}
+	else
+	{
+		IOTHUB_DEVICE_CLIENT_LL_HANDLE device_ll_handle;
+
+		if ((device_ll_handle = IoTHubDeviceClient_LL_CreateFromDeviceAuth(user_ctx.iothub_uri, user_ctx.device_id, iothub_transport)) == NULL)
+		{
+			(void)printf("failed create IoTHub client from connection string %s!\r\n", user_ctx.iothub_uri);
+		}
+		else
+		{
+			IOTHUB_CLIENT_SAMPLE_INFO iothub_info;
+			iothub_info.stop_running = 0;
+			iothub_info.connected = 0;
+
+			(void)IoTHubDeviceClient_LL_SetConnectionStatusCallback(device_ll_handle, iothub_connection_status, &iothub_info);
+			IoTHubDeviceClient_LL_Destroy(device_ll_handle);
+		}
+	}
+	free(user_ctx.iothub_uri);
+	free(user_ctx.device_id);
+	prov_dev_security_deinit();
+
+	IoTHub_Deinit();
+	return 0;
+}
Index: azure_iot_hub_f767zi/trunk/app_iothub_client/src/command.c
===================================================================
--- azure_iot_hub_f767zi/trunk/app_iothub_client/src/command.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/app_iothub_client/src/command.c	(revision 457)
@@ -0,0 +1,200 @@
+#include <kernel.h>
+#include <t_syslog.h>
+#include <stdio.h>
+#include <t_stdlib.h>
+#include <stdlib.h>
+#include "syssvc/serial.h"
+#include "syssvc/syslog.h"
+#include "kernel_cfg.h"
+#include "monitor.h"
+#include "device.h"
+
+/*
+ *  デバイスコマンド番号
+ */
+static int_t led_func(int argc, char **argv);
+static int_t dip_func(int argc, char **argv);
+#ifdef USE_PINGSEND
+static int_t png_func(int argc, char **argv);
+#endif
+static int_t cup_func(int argc, char **argv);
+extern int iothub_client_main(int argc, char **argv);
+extern int dps_csgen_main(int argc, char *argv[]);
+extern int set_cs_main(int argc, char **argv);
+extern int set_proxy_main(int argc, char **argv);
+extern int clear_proxy_main(int argc, char **argv);
+extern int set_wifi_main(int argc, char **argv);
+extern int pinkit_main(int argc, char **argv);
+
+/*
+ *  デバイスコマンドテーブル
+ */
+static const COMMAND_INFO device_command_info[] = {
+	{"LED",		led_func},
+	{"DIP",		dip_func},
+#ifdef USE_PINGSEND
+	{"PING",    png_func},
+#endif
+	{"CUP",		cup_func},
+	{"IOT",		iothub_client_main},
+	{"CSGEN",	dps_csgen_main},
+	{"SETCS",	set_cs_main},
+	{"PROXY",	set_proxy_main},
+	{"CPRX",	clear_proxy_main},
+	{"WIFI",	set_wifi_main},
+	{"PINKIT",	pinkit_main},
+};
+
+#define NUM_DEVICE_CMD   (sizeof(device_command_info)/sizeof(COMMAND_INFO))
+
+static const char device_name[] = "DEVICE";
+static const char device_help[] =
+"  Device  LED (no) (on-1,off-0)  led   control\n"
+"          DIP (no) (on-1,off-0)  dipsw control\n"
+#ifdef USE_PINGSEND
+"          PING addr              send  ping   \n"
+#endif
+"          CUP command            cup   control\n"
+"          IOT                    connect azure\n"
+"          CS             set connection string\n"
+"          CSGEN               provision device\n"
+"          PROXY                  set proxy    \n"
+"          CPRX                   clear proxy  \n"
+"          WIFI                   set ssid pwd \n"
+"          PINKIT                 test pinkit  \n";
+
+static const uint16_t led_pattern[4] = {
+	LED01, LED02, LED03, LED04
+};
+
+static COMMAND_LINK device_command_link = {
+	NULL,
+	NUM_DEVICE_CMD,
+	device_name,
+	NULL,
+	device_help,
+	&device_command_info[0]
+};
+
+static uint8_t cup_command;
+
+static int a2i(char *str)
+{
+	int num = 0;
+
+	while(*str >= '0' && *str <= '9'){
+		num = num * 10 + *str++ - '0';
+	}
+	return num;
+}
+
+/*
+ *  DEVICEコマンド設定関数
+ */
+void device_info_init(intptr_t exinf)
+{
+	setup_command(&device_command_link);
+}
+
+/*
+ *  LED設定コマンド関数
+ */
+static int_t led_func(int argc, char **argv)
+{
+	int_t    arg1=0, arg2;
+	uint16_t reg;
+
+	if(argc < 3)
+		return -1;
+	arg1 = a2i(argv[1]);
+	arg2 = a2i(argv[2]);
+	if(arg1 >= 1 && arg1 <= 4){
+		reg = led_in();
+		if(arg2 != 0)
+			reg |= led_pattern[arg1-1];
+		else
+			reg &= ~led_pattern[arg1-1];
+		led_out(reg);
+	}
+	return 0;
+}
+
+/*
+ *  DIPSW設定コマンド関数
+ */
+static int_t dip_func(int argc, char **argv)
+{
+	int_t   arg1=0, arg2=0, i;
+
+	if(argc > 1)
+		arg1 = a2i(argv[1]);
+	if(argc > 2)
+		arg2 = a2i(argv[2]);
+	if(arg1 >= 1 && arg1 <= 8){
+		if(arg2 != 0)
+			dipsw_value |= (0x1<<(arg1-1));
+		else
+			dipsw_value &= ~(0x1<<(arg1-1));
+	}
+	printf("dipsw\n1   2   3   4   5   6   7   8\n");
+	for(i = 0 ; i < 8 ; i++){
+		if(dipsw_value & (1<<i))
+			printf("ON  ");
+		else
+			printf("OFF ");
+	}
+	printf("\n");
+	return 0;
+}
+
+#ifdef USE_PINGSEND
+/*
+ *  PING送信マンド関数
+ */
+static int_t png_func(int argc, char **argv)
+{
+	const char *addr;
+	uint32_t paddr = 0;
+	int      a, i;
+
+	if(argc < 2)
+		return -1;
+	addr = argv[1];
+	for(i = a = 0 ; i < 4 ; addr++){
+		if(*addr <= '9' && *addr >= '0'){
+			a *= 10;
+			a += *addr - '0';
+		}
+		else{
+			paddr |= a << (i * 8);
+			a = 0;
+			i++;
+		}
+		if(*addr == 0)
+			break;
+	}
+	set_pingaddr(paddr);
+	return 0;
+}
+#endif
+
+/*
+ *  カップラーメンタイマ補助コマンド関数
+ */
+static int_t cup_func(int argc, char **argv)
+{
+	if(argc > 1)
+		cup_command = *argv[1];
+	return 0;
+}
+
+/*
+ * CUPラーメンコマンド
+ */
+int8_t
+get_cup_command(void)
+{
+	uint8_t cmd = cup_command;
+	cup_command = 0;
+	return cmd;
+}
Index: azure_iot_hub_f767zi/trunk/app_iothub_client/src/envcmd.c
===================================================================
--- azure_iot_hub_f767zi/trunk/app_iothub_client/src/envcmd.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/app_iothub_client/src/envcmd.c	(revision 457)
@@ -0,0 +1,281 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdbool.h>
+#include <string.h>
+#include "azure_c_shared_utility/shared_util_options.h"
+#include "pinkit.h"
+
+extern char* connectionString;
+
+extern bool g_use_proxy;
+extern HTTP_PROXY_OPTIONS g_proxy_options;
+
+enum proxy_parse_state_t {
+	proxy_parse_state_schema,
+	proxy_parse_state_colonslash,
+	proxy_parse_state_colonslashslash,
+	proxy_parse_state_username,
+	proxy_parse_state_password,
+	proxy_parse_state_address,
+	proxy_parse_state_port,
+	proxy_parse_state_error,
+};
+
+int set_proxy(const char *proxy, bool silent)
+{
+	const char *schema = NULL, *address = NULL, *port = NULL, *username = NULL, *password = NULL;
+	int schema_len = 0, address_len = 0, port_len = 0, username_len = 0, password_len = 0;
+
+	enum proxy_parse_state_t state = proxy_parse_state_schema;
+
+	const char *pos = proxy;
+	schema = pos;
+	for (char c = *pos; c != '\0'; pos++, c = *pos) {
+		switch (state) {
+		case proxy_parse_state_schema:
+			if (c == ':') {
+				schema_len = (int)pos - (int)schema;
+				username = pos + 3;
+				state = proxy_parse_state_colonslash;
+			}
+			break;
+		case proxy_parse_state_colonslash:
+			if (c == '/') {
+				state = proxy_parse_state_colonslashslash;
+			}
+			else {
+				username = schema;
+				username_len = schema_len;
+				schema = NULL;
+				schema_len = 0;
+				password = pos;
+				state = proxy_parse_state_password;
+				goto case_proxy_parse_state_password;
+			}
+			break;
+		case proxy_parse_state_colonslashslash:
+			if (c == '/') {
+				state = proxy_parse_state_username;
+			}
+			else {
+				state = proxy_parse_state_error;
+			}
+			break;
+		case proxy_parse_state_username:
+			if (c == ':') {
+				username_len = (int)pos - (int)username;
+				password = pos + 1;
+				state = proxy_parse_state_password;
+			}
+			else if (c == '@') {
+				username_len = (int)pos - (int)username;
+				address = pos + 1;
+				state = proxy_parse_state_address;
+			}
+			break;
+		case proxy_parse_state_password:
+		case_proxy_parse_state_password:
+			if (c == '@') {
+				password_len = (int)pos - (int)password;
+				address = pos + 1;
+				state = proxy_parse_state_address;
+			}
+			break;
+		case proxy_parse_state_address:
+			if (c == ':') {
+				address_len = (int)pos - (int)address;
+				port = pos + 1;
+				state = proxy_parse_state_port;
+			}
+			break;
+		case proxy_parse_state_port:
+			if ((c < '0') && (c > '9')) {
+				state = proxy_parse_state_error;
+			}
+			break;
+		}
+
+		if (state == proxy_parse_state_error)
+			break;
+	}
+
+	switch (state)
+	{
+	case proxy_parse_state_schema:
+	case proxy_parse_state_colonslash:
+	case proxy_parse_state_colonslashslash:
+		goto error;
+	case proxy_parse_state_username:
+		username_len = (int)pos - (int)username;
+		address = username;
+		address_len = username_len;
+		username = NULL;
+		username_len = 0;
+		break;
+	case proxy_parse_state_password:
+		password_len = (int)pos - (int)password;
+		address = username;
+		address_len = username_len;
+		username = NULL;
+		username_len = 0;
+		port = password;
+		port_len = password_len;
+		password = NULL;
+		password_len = 0;
+		break;
+	case proxy_parse_state_address:
+		address_len = (int)pos - (int)address;
+		break;
+	case proxy_parse_state_port:
+		port_len = (int)pos - (int)port;
+		break;
+	case proxy_parse_state_error:
+	default:
+		goto error;
+	}
+
+	if (schema_len > 0) {
+		if (strncmp(schema, "http", schema_len) != 0)
+			goto error;
+	}
+
+	if (address_len == 0)
+		goto error;
+
+	char *buf = malloc(address_len + port_len + username_len + password_len + 4);
+	if (buf == NULL) {
+		if (!silent)
+			printf("Memory error.\n");
+		return -1;
+	}
+
+	free((char *)g_proxy_options.host_address);
+
+	memcpy(buf, address, address_len);
+	buf[address_len] = '\0';
+	g_proxy_options.host_address = buf;
+
+	buf = buf + address_len + 1;
+	memcpy(buf, port, port_len);
+	buf[port_len] = '\0';
+	g_proxy_options.port = port_len == 0 ? 8080 : atoi(buf);
+
+	buf = buf + port_len + 1;
+	memcpy(buf, username, username_len);
+	buf[username_len] = '\0';
+	g_proxy_options.username = (username_len == 0) && (password_len == 0) ? NULL : buf;
+
+	buf = buf + username_len + 1;
+	memcpy(buf, password, password_len);
+	buf[password_len] = '\0';
+	g_proxy_options.password = (username_len == 0) && (password_len == 0) ? NULL : buf;
+
+	return 0;
+error:
+	if (!silent)
+		printf("proxy string parse error. 'http://[<user>:<password>@]<address>:<port>'\n");
+	return -1;
+}
+
+
+int set_cs_main(int argc, char **argv)
+{
+	if (argc < 2) {
+		printf("usage:\n%s <connection string>\n", argv[0]);
+		return 0;
+	}
+
+	int len = strlen(argv[1]);
+	if (len < 70) {
+		printf("String containing Hostname, Device Id & Device Key in the format:\n");
+		printf("  HostName=<host_name>;DeviceId=<device_id>;SharedAccessKey=<device_key>\n");
+		printf("  HostName=<host_name>;DeviceId=<device_id>;SharedAccessSignature=<device_sas_token>\n");
+		return 0;
+	}
+
+	char *conn_str = (char *)malloc(len + 1);
+	if (conn_str == NULL) {
+		printf("OOM while creating connection string\n");
+		return 1;
+	}
+
+	memcpy(conn_str, argv[1], len);
+	conn_str[len] = 0;
+	free(connectionString);
+	connectionString = conn_str;
+	printf("Connection String:\n%s\n", connectionString);
+
+	return 0;
+}
+
+int set_proxy_main(int argc, char **argv)
+{
+	int result;
+
+	if (argc < 2) {
+		if (g_proxy_options.username != NULL) {
+			printf("HTTP_PROXY=http://%s:%s@%s:%d\n",
+				g_proxy_options.username,
+				g_proxy_options.password,
+				g_proxy_options.host_address,
+				g_proxy_options.port);
+		}
+		else if (g_proxy_options.host_address != NULL) {
+			printf("HTTP_PROXY=http://%s:%d\n",
+				g_proxy_options.host_address,
+				g_proxy_options.port);
+		}
+		else {
+			printf("HTTP_PROXY=\n");
+		}
+		return 0;
+	}
+
+	if ((result = set_proxy(argv[1], false)) == 0) {
+		g_use_proxy = true;
+	}
+	else {
+		g_use_proxy = false;
+	}
+
+	return 0;
+}
+int clear_proxy_main(int argc, char **argv)
+{
+	free((char *)g_proxy_options.host_address);
+	g_proxy_options.host_address = NULL;
+	g_proxy_options.port = 0;
+	g_proxy_options.username = NULL;
+	g_proxy_options.password = NULL;
+
+	g_use_proxy = false;
+	return 0;
+}
+
+int set_wifi_main(int argc, char **argv)
+{
+	if (argc < 3) {
+		return 0;
+	}
+
+	set_ssid_pwd(argv[1], argv[2]);
+
+	prepare_esp_at();
+}
+
+int pinkit_main(int argc, char **argv)
+{
+	for (;;) {
+		int x = (int)(pinkit.accel.X * 1000);
+		int y = (int)(pinkit.accel.Y * 1000);
+		int z = (int)(pinkit.accel.Z * 1000);
+		int temp = (int)(pinkit.temperature * 1000);
+		int humi = (int)(pinkit.humidity * 1000);
+		printf("x:%d.%03d, y:%d.%03d, z:%d.%03d, temperature:%d.%03d, humidity %d.%03d\n",
+			x / 1000, x % 1000, y / 1000, y % 1000, z / 1000, z % 1000,
+			temp / 1000, temp % 1000, humi / 1000, humi % 1000);
+
+		ThreadAPI_Sleep(1000);
+	}
+	return 0;
+}
Index: azure_iot_hub_f767zi/trunk/app_iothub_client/src/esp_at_socket.c
===================================================================
--- azure_iot_hub_f767zi/trunk/app_iothub_client/src/esp_at_socket.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/app_iothub_client/src/esp_at_socket.c	(revision 457)
@@ -0,0 +1,1715 @@
+/*
+ *  TOPPERS/ASP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Advanced Standard Profile Kernel
+ * 
+ *  Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
+ *                              Toyohashi Univ. of Technology, JAPAN
+ *  Copyright (C) 2004-2012 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  $Id$
+ */
+
+#include <stddef.h>
+#include <stdbool.h>
+#include <kernel.h>
+#include <t_syslog.h>
+#include <t_stdlib.h>
+#include <target_syssvc.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <ctype.h>
+#include <string.h>
+#include <time.h>
+#include "syssvc/serial.h"
+#include "syssvc/syslog.h"
+#include "kernel_cfg.h"
+#include "device.h"
+#include "monitor.h"
+#include "main.h"
+#include "lwip/inet.h"
+#include "esp_at_socket.h"
+#include "azure_c_shared_utility/esp_at_socket.h"
+#include "azure_c_shared_utility/optimize_size.h"
+
+//#define AT_DEBUG
+time_t MINIMUM_YEAR;
+
+typedef enum at_param_type_t {
+	at_param_number,
+	at_param_string,
+	at_param_symbol,
+} at_param_type_t;
+
+typedef enum at_parse_state_t {
+	at_none,
+	at_informtion,
+	at_response,
+	at_link_id,
+	at_parameter,
+	at_number,
+	at_string_str,
+	at_string_esc,
+	at_string_edq,
+	at_symbol,
+	at_line_text,
+	at_cr,
+	at_crlf,
+	at_receive_data,
+} at_parse_state_t;
+
+typedef struct esp_serial_state_t esp_serial_state_t;
+typedef bool (*set_parameter_t)(esp_serial_state_t *esp_state, int pos, at_param_type_t type, intptr_t value);
+typedef at_parse_state_t (*exec_response_t)(esp_serial_state_t *esp_state, int pos);
+
+typedef struct at_response_table_t {
+	const char *name;
+	set_parameter_t next_parameter;
+	exec_response_t exec_response;
+} at_response_table_t;
+
+typedef enum at_response_kind_t {
+	at_response_kind_no_set,
+	at_response_kind_ok,
+	at_response_kind_send_ok,
+	at_response_kind_busy,
+	at_response_kind_ready,
+	at_response_kind_progress,
+	at_response_kind_connect,
+	at_response_kind_closed,
+	at_response_kind_error,
+	at_response_kind_fail,
+	at_response_kind_already_connect,
+	at_response_kind_received,
+} at_response_kind_t;
+
+typedef enum at_symbol_kind_t {
+	at_symbol_kind_unknown,
+	at_symbol_kind_apip,
+	at_symbol_kind_apmac,
+	at_symbol_kind_staip,
+	at_symbol_kind_stamac,
+	at_symbol_kind_gateway,
+	at_symbol_kind_netmask,
+} at_symbol_kind_t;
+
+typedef enum at_connection_mode_t {
+	at_single_connection_mode,
+	at_multiple_connections_mode
+} at_connection_mode_t;
+
+typedef enum at_encryption_method_t {
+	at_encryption_method_unknown,
+	at_encryption_method_open,
+	at_encryption_method_wep,
+	at_encryption_method_wpa_psk,
+	at_encryption_method_wpa2_psk,
+	at_encryption_method_wpa_wpa2_psk,
+	at_encryption_method_wpa2_enterprise,
+} at_encryption_method_t;
+
+typedef struct esp_ap_status_t {
+	at_encryption_method_t encryption_method;
+	char ssid[36];
+	int rssi;
+	struct ether_addr mac;
+	int channel;
+	int freq_offset;
+	int freq_calibration;
+} esp_ap_status_t;
+
+typedef struct esp_ap_config_t {
+	char ssid[36];
+	char pwd[64];
+	int channel;
+	at_encryption_method_t encryption_method;
+	int max_connection;
+	int ssid_hidden;
+} esp_ap_config_t;
+
+typedef enum at_wifi_mode_t {
+	at_wifi_mode_unknown,
+	at_wifi_mode_station,
+	at_wifi_mode_soft_ap,
+	at_wifi_mode_soft_ap_station,
+}at_wifi_mode_t;
+
+typedef enum at_wifi_state_t {
+	at_wifi_state_disconnected,
+	at_wifi_state_connected,
+	at_wifi_state_got_ip,
+	at_wifi_state_busy,
+}at_wifi_state_t;
+
+typedef struct esp_socket_state_t {
+	at_wifi_mode_t wifi_mode;
+	at_wifi_state_t wifi_state;
+	at_connection_mode_t connection_mode;
+	struct ether_addr ap_mac;
+	struct in_addr ap_ip;
+	struct in_addr ap_gateway;
+	struct in_addr ap_netmask;
+	struct ether_addr sta_mac;
+	struct in_addr sta_ip;
+	struct in_addr sta_gateway;
+	struct in_addr sta_netmask;
+	char ssid[36];
+	struct ether_addr baseid;
+	int channel;
+	int rssi;
+	at_symbol_kind_t symbol_kind;
+	int ap_status_count;
+	esp_ap_status_t ap_status[10];
+	esp_ap_config_t config;
+	int link_id;
+	int length;
+	struct in_addr remote_ip;
+	in_port_t remote_port;
+	int received;
+	int lost;
+	time_t date_time;
+} esp_socket_state_t;
+
+typedef enum esp_state_t {
+	esp_state_echo_off,
+	esp_state_reset,
+	esp_state_set_station_mode,
+	esp_state_auto_connect_to_ap_off,
+	esp_state_set_multiple_connections_mode,
+	esp_state_show_remote_ip_and_port,
+	esp_state_connect_ap,
+	esp_state_update_time,
+	esp_state_get_time,
+	esp_state_done
+} esp_state_t;
+
+typedef struct esp_serial_state_t {
+	esp_state_t esp_state;
+	char *ssid;
+	char *pwd;
+	ID dtqid;
+	at_parse_state_t parse_state;
+	char string[64];
+	int string_pos;
+	int number;
+	const at_response_table_t *response;
+	at_response_kind_t response_kind;
+	int param_pos;
+	esp_socket_state_t params;
+	esp_socket_state_t current_state;
+} esp_serial_state_t;
+
+typedef enum connection_state_t {
+	connection_state_disconnected,
+	connection_state_connecting,
+	connection_state_connected,
+	connection_state_disconnecting,
+} connection_state_t;
+
+typedef struct at_connection_t {
+	int link_id;
+	bool used;
+	connection_state_t state;
+	const char *ssl;
+	bool blocking;
+	unsigned int timeout;
+	esp_serial_state_t *esp_state;
+	uint8_t *rx_buff;
+	uint32_t rx_pos_w;
+	uint32_t rx_pos_r;
+} at_connection_t;
+
+esp_serial_state_t esp_serial_state;
+extern const at_response_table_t response_table[];
+extern const int response_table_count;
+ER esp_serial_clear(esp_serial_state_t *esp_state, TMO tmo);
+ER esp_serial_read(esp_serial_state_t *esp_state, at_response_kind_t *res_kind, TMO tmo);
+ER esp_serial_write(esp_serial_state_t *esp_state, const char *text, at_response_kind_t *res_kind, TMO tmo);
+int connection_read_data(at_connection_t *connection, void *data, int len);
+
+at_connection_t connections[5] = {
+	{ 0, false },
+	{ 1, false },
+	{ 2, false },
+	{ 3, false },
+	{ 4, false },
+};
+
+at_connection_t *new_connection()
+{
+	for (int i = 0; i < sizeof(connections) / sizeof(connections[0]); i++) {
+		at_connection_t *connection = &connections[i];
+		if (connection->used)
+			continue;
+
+		memset(&connection->used, 0, sizeof(*connection) - offsetof(at_connection_t, used));
+		connection->rx_buff = calloc(1, AT_CONNECTION_RX_BUFF_SIZE);
+		if (connection->rx_buff == NULL)
+			return NULL;
+
+		connection->used = true;
+		return connection;
+	}
+
+	return NULL;
+}
+
+void delete_connection(at_connection_t *connection)
+{
+#ifdef AT_DEBUG
+	printf("delete_connection %d\n", connection->link_id);
+#endif
+	free(connection->rx_buff);
+	connection->used = false;
+}
+
+at_connection_t *get_connection(int link_id)
+{
+	for (int i = 0; i < sizeof(connections) / sizeof(connections[0]); i++) {
+		if (connections[i].link_id == link_id) {
+			return &connections[i];
+		}
+	}
+
+	return NULL;
+}
+
+void init_esp_at()
+{
+	struct tm tm = {
+        0,  /* tm_sec */
+        0,  /* tm_min */
+        0,  /* tm_hour */
+        1,  /* tm_mday */
+        0,  /* tm_mon */
+        2020 - 1900,  /* tm_year */
+	};
+	MINIMUM_YEAR = mktime(&tm);
+
+	esp_serial_state.current_state.wifi_mode = at_wifi_mode_station;
+	esp_serial_state.dtqid = DTQ_ESP_AT;
+}
+
+const at_response_table_t *get_response(const char *name)
+{
+	const at_response_table_t *result;
+
+	result = response_table;
+	for (int i = 0; i < response_table_count; i++, result++) {
+		if (strcmp(result->name, name) == 0)
+			return result;
+	}
+
+	return NULL;
+}
+
+at_symbol_kind_t get_symbol(const char *name)
+{
+	if (strcmp("APIP", name) == 0)
+		return at_symbol_kind_apip;
+	if (strcmp("APMAC", name) == 0)
+		return at_symbol_kind_apmac;
+	if (strcmp("STAIP", name) == 0)
+		return at_symbol_kind_staip;
+	if (strcmp("STAMAC", name) == 0)
+		return at_symbol_kind_stamac;
+	if (strcmp("gateway", name) == 0)
+		return at_symbol_kind_gateway;
+	if (strcmp("netmask", name) == 0)
+		return at_symbol_kind_netmask;
+	return at_symbol_kind_unknown;
+}
+
+bool append_char(esp_serial_state_t *esp_state, int c)
+{
+	if (esp_state->string_pos >= sizeof(esp_state->string)) {
+		esp_state->string[0] = '\0';
+		return false;
+	}
+
+	esp_state->string[esp_state->string_pos++] = c;
+
+	return true;
+}
+
+bool proc_atc_res(esp_serial_state_t *esp_state, int c)
+{
+	switch (esp_state->parse_state) {
+	case at_none:
+		if (c == '+') {
+			esp_state->string_pos = 0;
+			esp_state->string[esp_state->string_pos++] = c;
+			esp_state->parse_state = at_informtion;
+			return false;
+		}
+		else if (isalpha(c) || c == '>') {
+			esp_state->string_pos = 0;
+			esp_state->string[esp_state->string_pos++] = c;
+			esp_state->parse_state = at_response;
+			if (c == '>') {
+				append_char(esp_state, '\0');
+				esp_state->response = get_response(esp_state->string);
+				if (esp_state->response != NULL) {
+#ifdef AT_DEBUG
+					printf("\033[35m%s\033[0m\r\n", esp_state->response->name);
+#endif
+					esp_state->parse_state = esp_state->response->exec_response(esp_state, esp_state->param_pos);
+					esp_state->response = NULL;
+					return true;
+				}
+			}
+			return false;
+		}
+		else if (isdigit(c)) {
+			esp_state->number = c - '0';
+			esp_state->parse_state = at_link_id;
+			return false;
+		}
+		else if (c == '\r') {
+			esp_state->parse_state = at_crlf;
+			return false;
+		}
+		return false;
+	case at_informtion:
+		if ((c == ':') || (c == ',')) {
+			append_char(esp_state, '\0');
+			esp_state->response = get_response(esp_state->string);
+			if (esp_state->response != NULL) {
+				esp_state->param_pos = 0;
+				memset(&esp_state->params, 0, sizeof(esp_state->params));
+				esp_state->parse_state = at_parameter;
+				return false;
+			}
+		}
+		else if (isalpha(c) || isdigit(c) || c == ' ') {
+			append_char(esp_state, c);
+			esp_state->parse_state = at_informtion;
+			return false;
+		}
+		break;
+	case at_response:
+		if ((c == '\r') || (c == '.')) {
+			append_char(esp_state, '\0');
+			esp_state->response = get_response(esp_state->string);
+			if (esp_state->response != NULL) {
+				esp_state->param_pos = 0;
+				memset(&esp_state->params, 0, sizeof(esp_state->params));
+				esp_state->parse_state = at_crlf;
+				return false;
+			}
+		}
+		else if (isalpha(c) || isdigit(c) || c == ' ') {
+			append_char(esp_state, c);
+			esp_state->parse_state = at_response;
+			return false;
+		}
+		break;
+	case at_link_id:
+		if (isdigit(c)) {
+			esp_state->parse_state = at_link_id;
+			esp_state->number *= 10;
+			esp_state->number += c - '0';
+			return false;
+		}
+		else if (c == ',') {
+			esp_state->param_pos = 0;
+			memset(&esp_state->params, 0, sizeof(esp_state->params));
+			esp_state->params.link_id = esp_state->number;
+			esp_state->string_pos = 0;
+			esp_state->parse_state = at_response;
+			return false;
+		}
+		break;
+	case at_parameter:
+		if (isdigit(c)) {
+			esp_state->parse_state = at_number;
+			esp_state->number = c - '0';
+			return false;
+		}
+		else if (c == '"') {
+			esp_state->string_pos = 0;
+			esp_state->string[esp_state->string_pos] = '\0';
+			esp_state->parse_state = at_string_str;
+			return false;
+		}
+		else if (isalpha(c)) {
+			esp_state->string_pos = 0;
+			esp_state->string[esp_state->string_pos++] = c;
+			esp_state->parse_state = at_line_text;
+			return false;
+		}
+		break;
+	case at_number:
+		if (isdigit(c)) {
+			esp_state->parse_state = at_number;
+			esp_state->number *= 10;
+			esp_state->number += c - '0';
+			return false;
+		}
+		else if (c == ',') {
+			esp_state->param_pos++;
+			if (esp_state->response->next_parameter(esp_state, esp_state->param_pos, at_param_number, esp_state->number)) {
+				esp_state->parse_state = at_parameter;
+				return false;
+			}
+		}
+		else if (c == ':') {
+			esp_state->param_pos++;
+			if (esp_state->response->next_parameter(esp_state, esp_state->param_pos, at_param_number, esp_state->number)) {
+#ifdef AT_DEBUG
+				printf("\033[35m%s\033[0m\r\n", esp_state->response->name);
+#endif
+				esp_state->parse_state = esp_state->response->exec_response(esp_state, esp_state->param_pos);
+				esp_state->string_pos = 0;
+				esp_state->response = NULL;
+				return true;
+			}
+		}
+		else if (c == '\r') {
+			esp_state->param_pos++;
+			if (esp_state->response->next_parameter(esp_state, esp_state->param_pos, at_param_number, esp_state->number)) {
+				esp_state->parse_state = at_crlf;
+				return false;
+			}
+		}
+		break;
+	case at_string_str:
+		if (c == '"') {
+			esp_state->parse_state = at_string_edq;
+			return false;
+		}
+		else if (c == '\\') {
+			esp_state->parse_state = at_string_esc;
+			return false;
+		}
+		else {
+			append_char(esp_state, c);
+			esp_state->parse_state = at_string_str;
+			return false;
+		}
+		break;
+	case at_string_esc:
+		append_char(esp_state, c);
+		esp_state->parse_state = at_string_str;
+		return false;
+	case at_string_edq:
+		if (c == ',') {
+			append_char(esp_state, '\0');
+			esp_state->param_pos++;
+			if (esp_state->response->next_parameter(esp_state, esp_state->param_pos, at_param_string, (intptr_t)esp_state->string)) {
+				esp_state->parse_state = at_parameter;
+				return false;
+			}
+		}
+		else if (c == '\r') {
+			append_char(esp_state, '\0');
+			esp_state->param_pos++;
+			if (esp_state->response->next_parameter(esp_state, esp_state->param_pos, at_param_string, (intptr_t)esp_state->string)) {
+				esp_state->parse_state = at_crlf;
+				return false;
+			}
+		}
+		break;
+	case at_symbol:
+		if (c == ',' || c == ':') {
+			append_char(esp_state, '\0');
+			esp_state->param_pos++;
+			if (esp_state->response->next_parameter(esp_state, esp_state->param_pos, at_param_symbol, (intptr_t)get_symbol(esp_state->string))) {
+				esp_state->parse_state = at_parameter;
+				return false;
+			}
+		}
+		else if (c == '\r') {
+			append_char(esp_state, '\0');
+			esp_state->param_pos++;
+			if (esp_state->response->next_parameter(esp_state, esp_state->param_pos, at_param_symbol, (intptr_t)get_symbol(esp_state->string))) {
+				esp_state->parse_state = at_crlf;
+				return false;
+			}
+		}
+		else if (isalpha(c) || isdigit(c) || c == ' ') {
+			append_char(esp_state, c);
+			esp_state->parse_state = at_symbol;
+			return false;
+		}
+		break;
+	case at_line_text:
+		if (c == '\r') {
+			append_char(esp_state, '\0');
+			esp_state->param_pos++;
+			if (esp_state->response->next_parameter(esp_state, esp_state->param_pos, at_param_symbol, (intptr_t)esp_state->string)) {
+				esp_state->parse_state = at_crlf;
+				return false;
+			}
+		}
+		else if (isprint(c)) {
+			append_char(esp_state, c);
+			esp_state->parse_state = at_line_text;
+			return false;
+		}
+		break;
+	case at_cr:
+		if (c == '\r') {
+			esp_state->parse_state = at_crlf;
+			return false;
+		}
+		break;
+	case at_crlf:
+		if (c == '\n') {
+			if (esp_state->response != NULL) {
+#ifdef AT_DEBUG
+				printf("\033[35m%s\033[0m\r\n", esp_state->response->name);
+#endif
+				esp_state->parse_state = esp_state->response->exec_response(esp_state, esp_state->param_pos);
+			}
+			else {
+				esp_state->parse_state = at_none;
+			}
+			esp_state->string_pos = 0;
+			esp_state->response = NULL;
+			return true;
+		}
+		else if (c == '\r' || (c == '.')) {
+			esp_state->parse_state = at_crlf;
+			return false;
+		}
+		break;
+	case at_receive_data: {
+		esp_state->current_state.received++;
+		at_connection_t *connection = get_connection(esp_state->current_state.link_id);
+		if (connection != NULL) {
+			int pos = connection->rx_pos_w + 1;
+			if (pos >= AT_CONNECTION_RX_BUFF_SIZE)
+				pos = 0;
+			if (pos != connection->rx_pos_r) {
+				connection->rx_buff[connection->rx_pos_w] = c;
+				connection->rx_pos_w = pos;
+			}
+			else {
+				esp_state->current_state.lost++;
+			}
+		}
+		else {
+			esp_state->current_state.lost++;
+		}
+		if (esp_state->current_state.received >= esp_state->current_state.length) {
+#ifdef AT_DEBUG
+			printf("\033[35mrecv:%d, lost:%d\033[0m\r\n", esp_state->current_state.received, esp_state->current_state.lost);
+#endif
+			esp_state->parse_state = at_none;
+			esp_state->response_kind = at_response_kind_received;
+			return true;
+		}
+		return false;
+	}
+	}
+#ifdef AT_DEBUG
+	if (esp_state->parse_state != at_none)
+		printf("\033[35mparse error. state:%d\033[0m\r\n", esp_state->parse_state);
+#endif
+	esp_state->parse_state = at_none;
+	esp_state->response = NULL;
+	return false;
+}
+
+ER esp_serial_clear(esp_serial_state_t *esp_state, TMO tmo)
+{
+	return ini_dtq(esp_state->dtqid);
+}
+
+ER esp_serial_read(esp_serial_state_t *esp_state, at_response_kind_t *res_kind, TMO tmo)
+{
+	ER ret;
+	intptr_t data = 0;
+	ret = trcv_dtq(esp_state->dtqid, (intptr_t *)&data, tmo);
+	if ((ret != E_OK) && (ret != E_TMOUT)) {
+		printf("trcv_dtq error %s", itron_strerror(ret));
+	}
+	*res_kind = (at_response_kind_t)data;
+	return ret;
+}
+
+ER esp_serial_write(esp_serial_state_t *esp_state, const char *text, at_response_kind_t *res_kind, TMO tmo)
+{
+	ER ret;
+
+	ret = esp_serial_clear(esp_state, 100);
+	if ((ret != E_OK) && (ret != E_TMOUT)) {
+		printf("esp_serial_clear error %s", itron_strerror(ret));
+		return ret;
+	}
+
+#ifdef AT_DEBUG
+	printf("\033[32m%s\033[0m", text);
+#endif
+	ret = serial_wri_dat(AT_PORTID, text, (uint_t)strlen(text));
+	if (ret < 0) {
+		printf("serial_wri_dat error %s", itron_strerror(ret));
+		return ret;
+	}
+
+	return esp_serial_read(esp_state, res_kind, tmo);
+}
+
+int connection_read_data(at_connection_t *connection, void *data, int len)
+{
+	esp_serial_state_t *esp_state = connection->esp_state;
+	int ret = 0;
+
+	for (unsigned char *pos = (unsigned char *)data, *end = &pos[len]; pos < end; pos++) {
+		if (connection->rx_pos_w == connection->rx_pos_r) {
+			return ret;
+		}
+
+		*pos = connection->rx_buff[connection->rx_pos_r];
+		connection->rx_pos_r++;
+		if (connection->rx_pos_r >= AT_CONNECTION_RX_BUFF_SIZE)
+			connection->rx_pos_r = 0;
+
+		ret++;
+	}
+
+	return ret;
+}
+
+static bool at_cipmux_set_param(esp_serial_state_t *esp_state, int pos, at_param_type_t type, intptr_t value)
+{
+	esp_socket_state_t *params = &esp_state->params;
+
+	switch (pos) {
+	case 1:
+		switch (value) {
+		case 0:
+			params->connection_mode = at_single_connection_mode;
+			return true;
+		case 1:
+			params->connection_mode = at_multiple_connections_mode;
+			return true;
+		}
+		break;
+	}
+
+	return false;
+}
+
+static at_parse_state_t at_cipmux_exec(esp_serial_state_t *esp_state, int pos)
+{
+	if (pos >= 1)
+		esp_state->current_state.connection_mode = esp_state->params.connection_mode;
+
+	return at_none;
+}
+
+static bool at_cifsr_set_param(esp_serial_state_t *esp_state, int pos, at_param_type_t type, intptr_t value)
+{
+	esp_socket_state_t *params = &esp_state->params;
+
+	switch (pos) {
+	case 1:
+		params->symbol_kind = (at_symbol_kind_t)value;
+		return true;
+	case 2:
+		switch (params->symbol_kind)
+		{
+		case at_symbol_kind_apip:
+			if (inet_aton((const char *)value, &params->ap_ip)) {
+				return true;
+			}
+			break;
+		case at_symbol_kind_apmac:
+			if (ether_aton_r((const char *)value, &params->ap_mac)) {
+				return true;
+			}
+			break;
+		case at_symbol_kind_staip:
+			if (inet_aton((const char *)value, &params->sta_ip)) {
+				return true;
+			}
+			break;
+		case at_symbol_kind_stamac:
+			if (ether_aton_r((const char *)value, &params->sta_mac)) {
+				return true;
+			}
+			break;
+		}
+		break;
+	}
+
+	return false;
+}
+
+static at_parse_state_t at_cifsr_exec(esp_serial_state_t *esp_state, int pos)
+{
+	if (pos < 2)
+		return at_none;
+
+	switch (esp_state->params.symbol_kind)
+	{
+	case at_symbol_kind_apip:
+		esp_state->current_state.ap_ip = esp_state->params.ap_ip;
+		break;
+	case at_symbol_kind_apmac:
+		esp_state->current_state.ap_mac = esp_state->params.ap_mac;
+		break;
+	case at_symbol_kind_staip:
+		esp_state->current_state.sta_ip = esp_state->params.sta_ip;
+		break;
+	case at_symbol_kind_stamac:
+		esp_state->current_state.sta_mac = esp_state->params.sta_mac;
+		break;
+	}
+
+	return at_none;
+}
+
+static bool at_cipap_set_param(esp_serial_state_t *esp_state, int pos, at_param_type_t type, intptr_t value)
+{
+	esp_socket_state_t *params = &esp_state->params;
+
+	switch (pos) {
+	case 1:
+		params->symbol_kind = (at_symbol_kind_t)value;
+		return true;
+	case 2:
+		switch (params->symbol_kind)
+		{
+		case at_symbol_kind_gateway:
+			if (inet_aton((const char *)value, &params->ap_gateway)) {
+				return true;
+			}
+			break;
+		case at_symbol_kind_netmask:
+			if (inet_aton((const char *)value, &params->ap_netmask)) {
+				return true;
+			}
+			break;
+		}
+		break;
+	}
+
+	return false;
+}
+
+static at_parse_state_t at_cipap_exec(esp_serial_state_t *esp_state, int pos)
+{
+	if (pos < 2)
+		return at_none;
+
+	switch (esp_state->params.symbol_kind)
+	{
+	case at_symbol_kind_gateway:
+		esp_state->current_state.ap_gateway = esp_state->params.ap_gateway;
+		break;
+	case at_symbol_kind_netmask:
+		esp_state->current_state.ap_netmask = esp_state->params.ap_netmask;
+		break;
+	}
+
+	return at_none;
+}
+
+static bool at_cipsntptime_set_param(esp_serial_state_t *esp_state, int pos, at_param_type_t type, intptr_t value)
+{
+	esp_socket_state_t *params = &esp_state->params;
+	struct tm date_time = { 0 };
+
+	switch (pos) {
+	case 1:
+		if (strptime((const char *)value, "%a %b %d %T %Y", &date_time) != NULL) {
+			printf("%04d/%02d/%02d %02d:%02d:%02d\r\n",
+				date_time.tm_year+1900, date_time.tm_mon+1, date_time.tm_mday,
+				date_time.tm_hour, date_time.tm_min, date_time.tm_sec);
+			params->date_time = mktime(&date_time);
+			return true;
+		}
+		break;
+	}
+
+	return false;
+}
+
+static at_parse_state_t at_cipsntptime_exec(esp_serial_state_t *esp_state, int pos)
+{
+	esp_socket_state_t *params = &esp_state->params;
+	struct tm current_time_val = { 0 };
+	time_t current_time = params->date_time;
+
+	if (current_time <= MINIMUM_YEAR)
+		return at_none;
+
+	esp_state->current_state.date_time = current_time;
+	gmtime_r(&current_time, &current_time_val);
+	rtc_set_time((struct tm2 *)&current_time_val);
+
+	current_time = time(NULL);
+	printf("%s\r\n", ctime(&current_time));
+
+	return at_none;
+}
+
+static bool at_cipsta_set_param(esp_serial_state_t *esp_state, int pos, at_param_type_t type, intptr_t value)
+{
+	esp_socket_state_t *params = &esp_state->params;
+
+	switch (pos) {
+	case 1:
+		params->symbol_kind = (at_symbol_kind_t)value;
+		return true;
+	case 2:
+		switch (params->symbol_kind)
+		{
+		case at_symbol_kind_gateway:
+			if (inet_aton((const char *)value, &params->sta_gateway)) {
+				return true;
+			}
+			break;
+		case at_symbol_kind_netmask:
+			if (inet_aton((const char *)value, &params->sta_netmask)) {
+				return true;
+			}
+			break;
+		}
+		break;
+	}
+
+	return false;
+}
+
+static at_parse_state_t at_cipsta_exec(esp_serial_state_t *esp_state, int pos)
+{
+	if (pos < 2)
+		return at_none;
+
+	switch (esp_state->params.symbol_kind)
+	{
+	case at_symbol_kind_gateway:
+		esp_state->current_state.sta_gateway = esp_state->params.sta_gateway;
+		break;
+	case at_symbol_kind_netmask:
+		esp_state->current_state.sta_netmask = esp_state->params.sta_netmask;
+		break;
+	}
+
+	return at_none;
+}
+
+static bool at_cwjap_set_param(esp_serial_state_t *esp_state, int pos, at_param_type_t type, intptr_t value)
+{
+	esp_socket_state_t *params = &esp_state->params;
+
+	switch (pos) {
+	case 1:
+		if (type == at_param_string) {
+			strcpy(params->ssid, (const char *)value);
+			return true;
+		}
+		break;
+	case 2:
+		if (ether_aton_r((const char *)value, &params->baseid)) {
+			return true;
+		}
+		break;
+	case 3:
+		params->channel = (int)value;
+		return true;
+	case 4:
+		params->rssi = (int)value;
+		return true;
+		break;
+	}
+
+	return false;
+}
+
+static at_parse_state_t at_cwjap_exec(esp_serial_state_t *esp_state, int pos)
+{
+	if (pos >= 1)
+		strcpy(esp_state->current_state.ssid, esp_state->params.ssid);
+
+	if (pos >= 2)
+		esp_state->current_state.baseid = esp_state->params.baseid;
+
+	if (pos >= 3)
+		esp_state->current_state.channel = esp_state->params.channel;
+
+	if (pos >= 4)
+		esp_state->current_state.rssi = esp_state->params.rssi;
+
+	return at_none;
+}
+
+static bool at_cwlap_set_param(esp_serial_state_t *esp_state, int pos, at_param_type_t type, intptr_t value)
+{
+	if (esp_state->params.ap_status_count >= sizeof(esp_state->params.ap_status) / sizeof(esp_state->params.ap_status[0]))
+		return false;
+
+	esp_ap_status_t *ap_status = &esp_state->params.ap_status[esp_state->params.ap_status_count];
+
+	switch (pos) {
+	case 1:
+		switch (value) {
+		case 0:
+			ap_status->encryption_method = at_encryption_method_open;
+			return true;
+		case 1:
+			ap_status->encryption_method = at_encryption_method_wep;
+			return true;
+		case 2:
+			ap_status->encryption_method = at_encryption_method_wpa_psk;
+			return true;
+		case 3:
+			ap_status->encryption_method = at_encryption_method_wpa2_psk;
+			return true;
+		case 4:
+			ap_status->encryption_method = at_encryption_method_wpa_wpa2_psk;
+			return true;
+		case 5:
+			ap_status->encryption_method = at_encryption_method_wpa2_enterprise;
+			return true;
+		}
+		break;
+	case 2:
+		strcpy(ap_status->ssid, (const char *)value);
+		return true;
+	case 3:
+		ap_status->rssi = (int)value;
+		return true;
+		break;
+	case 4:
+		if (ether_aton_r((const char *)value, &ap_status->mac)) {
+			return true;
+		}
+		break;
+	case 5:
+		ap_status->channel = (int)value;
+		return true;
+	case 6:
+		ap_status->freq_offset = (int)value;
+		return true;
+	case 7:
+		ap_status->freq_calibration = (int)value;
+		return true;
+	}
+
+	return false;
+}
+
+static at_parse_state_t at_cwlap_exec(esp_serial_state_t *esp_state, int pos)
+{
+	esp_state->params.ap_status_count++;
+
+	return at_none;
+}
+
+static bool at_cwmode_set_param(esp_serial_state_t *esp_state, int pos, at_param_type_t type, intptr_t value)
+{
+	esp_socket_state_t *params = &esp_state->params;
+
+	switch (pos) {
+	case 1:
+		switch (value) {
+		case 1:
+			params->wifi_mode = at_wifi_mode_unknown;
+			return true;
+		case 2:
+			params->wifi_mode = at_wifi_mode_station;
+			return true;
+		case 3:
+			params->wifi_mode = at_wifi_mode_soft_ap;
+			return true;
+		case 4:
+			params->wifi_mode = at_wifi_mode_soft_ap_station;
+			return true;
+		}
+	}
+
+	return false;
+}
+
+static at_parse_state_t at_cwmode_exec(esp_serial_state_t *esp_state, int pos)
+{
+	if (pos >= 1)
+		esp_state->current_state.wifi_mode = esp_state->params.wifi_mode;
+
+	return at_none;
+}
+
+static bool at_cwsap_set_param(esp_serial_state_t *esp_state, int pos, at_param_type_t type, intptr_t value)
+{
+	esp_ap_config_t *ap_config = &esp_state->params.config;
+
+	switch (pos) {
+	case 1:
+		strcpy(ap_config->ssid, (const char *)value);
+		return true;
+	case 2:
+		strcpy(ap_config->pwd, (const char *)value);
+		return true;
+	case 3:
+		ap_config->channel = (int)value;
+		return true;
+	case 4:
+		switch (value) {
+		case 0:
+			ap_config->encryption_method = at_encryption_method_open;
+			return true;
+		case 1:
+			ap_config->encryption_method = at_encryption_method_wep;
+			return true;
+		case 2:
+			ap_config->encryption_method = at_encryption_method_wpa_psk;
+			return true;
+		case 3:
+			ap_config->encryption_method = at_encryption_method_wpa2_psk;
+			return true;
+		case 4:
+			ap_config->encryption_method = at_encryption_method_wpa_wpa2_psk;
+			return true;
+		case 5:
+			ap_config->encryption_method = at_encryption_method_wpa2_enterprise;
+			return true;
+		}
+		break;
+	case 5:
+		ap_config->max_connection = (int)value;
+		break;
+	case 6:
+		switch (value) {
+		case 0:
+			ap_config->ssid_hidden = 0;
+			return true;
+		case 1:
+			ap_config->ssid_hidden = 1;
+			return true;
+		}
+	}
+
+	return false;
+}
+
+static at_parse_state_t at_cwsap_exec(esp_serial_state_t *esp_state, int pos)
+{
+	return at_none;
+}
+
+static bool at_ipd_set_param(esp_serial_state_t *esp_state, int pos, at_param_type_t type, intptr_t value)
+{
+	esp_socket_state_t *params = &esp_state->params;
+
+	switch (pos) {
+	case 1:
+		if ((value >= 0) && (value <= 4)) {
+			params->link_id = (int)value;
+			return true;
+		}
+		break;
+	case 2:
+		if ((value >= 1) && (value <= AT_CONNECTION_RX_BUFF_SIZE)) {
+			params->length = (int)value;
+			return true;
+		}
+		break;
+	case 3:
+		if (inet_aton((const char *)value, &params->remote_ip)) {
+			return true;
+		}
+		break;
+	case 4:
+		if (value >= 0 && value < 65536) {
+			params->remote_port = (in_port_t)value;
+			return true;
+		}
+		break;
+	}
+
+	return false;
+}
+
+static at_parse_state_t at_ipd_exec(esp_serial_state_t *esp_state, int pos)
+{
+	if (pos >= 1)
+		esp_state->current_state.link_id = esp_state->params.link_id;
+	if (pos >= 2)
+		esp_state->current_state.length = esp_state->params.length;
+	if (pos >= 3)
+		esp_state->current_state.remote_ip = esp_state->params.remote_ip;
+	if (pos >= 4)
+		esp_state->current_state.remote_port = esp_state->params.remote_port;
+
+	esp_state->current_state.received = 0;
+	esp_state->current_state.lost = 0;
+	esp_state->response_kind = at_response_kind_no_set;
+
+	return at_receive_data;
+}
+
+static bool at_already_connect_set_param(esp_serial_state_t *esp_state, int pos, at_param_type_t type, intptr_t value)
+{
+	// 引数なし
+	return false;
+}
+
+static at_parse_state_t at_already_connect_exec(esp_serial_state_t *esp_state, int pos)
+{
+	at_connection_t *connection = get_connection(esp_state->params.link_id);
+	if (connection != NULL) {
+		connection->state = connection_state_connected;
+	}
+
+	esp_state->response_kind = at_response_kind_already_connect;
+
+	return at_none;
+}
+
+static bool at_error_set_param(esp_serial_state_t *esp_state, int pos, at_param_type_t type, intptr_t value)
+{
+	// 引数なし
+	return false;
+}
+
+static at_parse_state_t at_error_exec(esp_serial_state_t *esp_state, int pos)
+{
+	esp_state->response_kind = at_response_kind_error;
+
+	return at_none;
+}
+
+static bool at_fail_set_param(esp_serial_state_t *esp_state, int pos, at_param_type_t type, intptr_t value)
+{
+	// 引数なし
+	return false;
+}
+
+static at_parse_state_t at_fail_exec(esp_serial_state_t *esp_state, int pos)
+{
+	esp_state->response_kind = at_response_kind_fail;
+
+	return at_none;
+}
+
+static bool at_ok_set_param(esp_serial_state_t *esp_state, int pos, at_param_type_t type, intptr_t value)
+{
+	// 引数なし
+	return false;
+}
+
+static at_parse_state_t at_ok_exec(esp_serial_state_t *esp_state, int pos)
+{
+	esp_state->response_kind = at_response_kind_ok;
+
+	return at_none;
+}
+
+static bool at_send_ok_set_param(esp_serial_state_t *esp_state, int pos, at_param_type_t type, intptr_t value)
+{
+	// 引数なし
+	return false;
+}
+
+static at_parse_state_t at_send_ok_exec(esp_serial_state_t *esp_state, int pos)
+{
+	esp_state->response_kind = at_response_kind_send_ok;
+
+	return at_none;
+}
+
+static bool at_wifi_connected_set_param(esp_serial_state_t *esp_state, int pos, at_param_type_t type, intptr_t value)
+{
+	// 引数なし
+	return false;
+}
+
+static at_parse_state_t at_wifi_connected_exec(esp_serial_state_t *esp_state, int pos)
+{
+	esp_state->current_state.wifi_state = at_wifi_state_connected;
+
+	return at_none;
+}
+
+static bool at_wifi_disconnect_set_param(esp_serial_state_t *esp_state, int pos, at_param_type_t type, intptr_t value)
+{
+	// 引数なし
+	return false;
+}
+
+static at_parse_state_t at_wifi_disconnect_exec(esp_serial_state_t *esp_state, int pos)
+{
+	esp_state->current_state.wifi_state = at_wifi_state_disconnected;
+
+	return at_none;
+}
+
+static bool at_wifi_got_ip_set_param(esp_serial_state_t *esp_state, int pos, at_param_type_t type, intptr_t value)
+{
+	// 引数なし
+	return false;
+}
+
+static at_parse_state_t at_wifi_got_ip_exec(esp_serial_state_t *esp_state, int pos)
+{
+	esp_state->current_state.wifi_state = at_wifi_state_got_ip;
+
+	return at_none;
+}
+
+static bool at_busy_set_param(esp_serial_state_t *esp_state, int pos, at_param_type_t type, intptr_t value)
+{
+	// 引数なし
+	return false;
+}
+
+static at_parse_state_t at_busy_exec(esp_serial_state_t *esp_state, int pos)
+{
+	esp_state->response_kind = at_response_kind_busy;
+	esp_state->current_state.wifi_state = at_wifi_state_busy;
+
+	return at_none;
+}
+
+static bool at_ready_set_param(esp_serial_state_t *esp_state, int pos, at_param_type_t type, intptr_t value)
+{
+	// 引数なし
+	return false;
+}
+
+static at_parse_state_t at_ready_exec(esp_serial_state_t *esp_state, int pos)
+{
+	esp_state->response_kind = at_response_kind_ready;
+	esp_state->current_state.wifi_state = at_wifi_state_disconnected;
+
+	return at_none;
+}
+
+static bool at_progress_set_param(esp_serial_state_t *esp_state, int pos, at_param_type_t type, intptr_t value)
+{
+	// 引数なし
+	return false;
+}
+
+static at_parse_state_t at_progress_exec(esp_serial_state_t *esp_state, int pos)
+{
+	esp_state->response_kind = at_response_kind_progress;
+
+	return at_none;
+}
+
+static bool at_connect_set_param(esp_serial_state_t *esp_state, int pos, at_param_type_t type, intptr_t value)
+{
+	// 引数なし
+	return false;
+}
+
+static at_parse_state_t at_connect_exec(esp_serial_state_t *esp_state, int pos)
+{
+	at_connection_t *connection = get_connection(esp_state->params.link_id);
+	if (connection != NULL) {
+		connection->state = connection_state_connected;
+	}
+
+	esp_state->response_kind = at_response_kind_connect;
+
+	return at_none;
+}
+
+static bool at_closed_set_param(esp_serial_state_t *esp_state, int pos, at_param_type_t type, intptr_t value)
+{
+	// 引数なし
+	return false;
+}
+
+static at_parse_state_t at_closed_exec(esp_serial_state_t *esp_state, int pos)
+{
+	at_connection_t *connection = get_connection(esp_state->params.link_id);
+	if (connection != NULL) {
+		connection->state = connection_state_disconnected;
+	}
+
+	esp_state->response_kind = at_response_kind_closed;
+
+	return at_none;
+}
+
+const at_response_table_t response_table[] = {
+	{ "+CIPMUX", at_cipmux_set_param, at_cipmux_exec },
+	{ "+CIFSR", at_cifsr_set_param, at_cifsr_exec },
+	{ "+CIPAP", at_cipap_set_param, at_cipap_exec },
+	{ "+CIPSNTPTIME", at_cipsntptime_set_param, at_cipsntptime_exec },
+	{ "+CIPSTA", at_cipsta_set_param, at_cipsta_exec },
+	{ "+CWJAP", at_cwjap_set_param, at_cwjap_exec },
+	{ "+CWLAP", at_cwlap_set_param, at_cwlap_exec },
+	{ "+CWMODE", at_cwmode_set_param, at_cwmode_exec },
+	{ "+CWSAP", at_cwsap_set_param, at_cwsap_exec },
+	{ "+IPD", at_ipd_set_param, at_ipd_exec },
+	{ "ALREADY CONNECT", at_already_connect_set_param, at_already_connect_exec },
+	{ "ERROR", at_error_set_param, at_error_exec },
+	{ "FAIL", at_fail_set_param, at_fail_exec },
+	{ "OK", at_ok_set_param, at_ok_exec },
+	{ "SEND OK", at_send_ok_set_param, at_send_ok_exec },
+	{ "WIFI CONNECTED", at_wifi_connected_set_param, at_wifi_connected_exec },
+	{ "WIFI DISCONNECT", at_wifi_disconnect_set_param, at_wifi_disconnect_exec },
+	{ "WIFI GOT IP", at_wifi_got_ip_set_param, at_wifi_got_ip_exec },
+	{ "busy p", at_busy_set_param, at_busy_exec },
+	{ "ready", at_ready_set_param, at_ready_exec },
+	{ ">", at_progress_set_param, at_progress_exec },
+	{ "CONNECT", at_connect_set_param, at_connect_exec},
+	{ "CLOSED", at_closed_set_param, at_closed_exec},
+};
+const int response_table_count = sizeof(response_table) / sizeof(response_table[0]);
+
+int esp_at_rx_handler(void *data, int len)
+{
+	esp_serial_state_t *esp_state = &esp_serial_state;
+	uint8_t *c = (uint8_t *)data;
+	ER ret;
+
+	for (uint8_t *end = &c[len]; c < end; c++) {
+		if (proc_atc_res(esp_state, *c)) {
+			if (esp_state->response_kind != at_response_kind_no_set) {
+				ret = tsnd_dtq(esp_state->dtqid, (intptr_t)esp_state->response_kind, 20);
+				if (ret != E_OK) {
+					printf("snd_dtq error %s\n", itron_strerror(ret));
+				}
+				esp_state->response_kind = at_response_kind_no_set;
+			}
+		}
+	}
+
+	return (int)((intptr_t)c - (intptr_t)data);
+}
+
+void set_ssid_pwd(const char *ssid, const char *pwd)
+{
+	esp_serial_state_t *esp_state = &esp_serial_state;
+
+	free(esp_state->ssid);
+	esp_state->ssid = strdup(ssid);
+	free(esp_state->pwd);
+	esp_state->pwd = strdup(pwd);
+}
+
+bool prepare_esp_at()
+{
+	esp_serial_state_t *esp_state = &esp_serial_state;
+	ER ret;
+	char temp[64];
+	int tmo = 0;
+	at_response_kind_t res_kind = at_response_kind_no_set;
+
+	if (esp_state->current_state.wifi_state != at_wifi_state_got_ip)
+		esp_state->esp_state = esp_state_echo_off;
+
+retry:
+	ret = esp_serial_clear(esp_state, 100);
+	if ((ret != E_OK) && (ret != E_TMOUT))
+		return false;
+
+	switch (esp_state->esp_state) {
+	case esp_state_reset:
+		ret = esp_serial_write(esp_state, "AT+RST\r\n", &res_kind, 10000);
+		if ((ret != E_OK) || (res_kind != at_response_kind_ok)) {
+			printf("reset error %s %d\n", itron_strerror(ret), res_kind);
+			return false;
+		}
+
+		ret = esp_serial_read(esp_state, &res_kind, 10000);
+		if ((ret != E_OK) || (res_kind != at_response_kind_ready)) {
+			printf("ready error %s %d\n", itron_strerror(ret), res_kind);
+			return false;
+		}
+		esp_state->esp_state = esp_state_echo_off;
+	case esp_state_echo_off:
+		ret = esp_serial_write(esp_state, "ATE0\r\n", &res_kind, 10000);
+		if ((ret != E_OK) || (res_kind != at_response_kind_ok)) {
+			printf("echo off error %s %d\n", itron_strerror(ret), res_kind);
+			break;
+		}
+		esp_state->esp_state = esp_state_set_station_mode;
+	case esp_state_set_station_mode:
+		ret = esp_serial_write(esp_state, "AT+CWMODE=1\r\n", &res_kind, 10000);
+		if ((ret != E_OK) || (res_kind != at_response_kind_ok)) {
+			printf("set station mode error %s %d\n", itron_strerror(ret), res_kind);
+			break;
+		}
+		esp_state->esp_state = esp_state_auto_connect_to_ap_off;
+	case esp_state_auto_connect_to_ap_off:
+		ret = esp_serial_write(esp_state, "AT+CWAUTOCONN=0\r\n", &res_kind, 10000);
+		if ((ret != E_OK) || (res_kind != at_response_kind_ok)) {
+			printf("auto connect off error %s %d\n", itron_strerror(ret), res_kind);
+			break;
+		}
+		esp_state->esp_state = esp_state_set_multiple_connections_mode;
+	case esp_state_set_multiple_connections_mode:
+		ret = esp_serial_write(esp_state, "AT+CIPMUX=1\r\n", &res_kind, 10000);
+		if ((ret != E_OK) || (res_kind != at_response_kind_ok)) {
+			printf("set multiple connections mode error %s %d\n", itron_strerror(ret), res_kind);
+			break;
+		}
+		esp_state->esp_state = esp_state_show_remote_ip_and_port;
+	case esp_state_show_remote_ip_and_port:
+		ret = esp_serial_write(esp_state, "AT+CIPDINFO=1\r\n", &res_kind, 10000);
+		if ((ret != E_OK) || (res_kind != at_response_kind_ok)) {
+			printf("show remote ip/port error %s %d\n", itron_strerror(ret), res_kind);
+			break;
+		}
+		esp_state->esp_state = esp_state_connect_ap;
+	case esp_state_connect_ap:
+		if ((esp_state->ssid == NULL) || (esp_state->pwd == NULL)) {
+			printf("ssid psw error %s %d\n", itron_strerror(ret), res_kind);
+			break;
+		}
+
+		sprintf(temp, "AT+CWJAP=\"%s\",\"%s\"\r\n", esp_state->ssid, esp_state->pwd);
+		ret = esp_serial_write(esp_state, temp, &res_kind, 20000);
+		if ((ret != E_OK) || (res_kind != at_response_kind_ok)) {
+			printf("connect wifi error %s %d\n", itron_strerror(ret), res_kind);
+			break;
+		}
+		esp_state->esp_state = esp_state_update_time;
+	case esp_state_update_time:
+		sprintf(temp, "AT+CIPSNTPCFG=%d,%d,\"%s\"\r\n", 1, 9, "ntp.nict.jp");
+		ret = esp_serial_write(esp_state, temp, &res_kind, 10000);
+		if ((ret != E_OK) || (res_kind != at_response_kind_ok)) {
+			printf("ntp config error %s %d\n", itron_strerror(ret), res_kind);
+			break;
+		}
+		esp_state->esp_state = esp_state_get_time;
+	case esp_state_get_time:
+		ret = esp_serial_write(esp_state, "AT+CIPSNTPTIME?\r\n", &res_kind, 10000);
+		if ((ret != E_OK) || (res_kind != at_response_kind_ok)) {
+			printf("get time error %s %d\n", itron_strerror(ret), res_kind);
+			break;
+		}
+		if (esp_state->current_state.date_time <= MINIMUM_YEAR) {
+			tmo++;
+			if (tmo < 10) {
+				printf("retry to get time %s\n", ctime(NULL));
+				dly_tsk(1000);
+				esp_state->esp_state = esp_state_get_time;
+				goto retry;
+			}
+		}
+		esp_state->esp_state = esp_state_done;
+	case esp_state_done: {
+		time_t ntp = esp_state->current_state.date_time;
+		time_t local = time(NULL);
+		if ((local > ntp) && ((local - ntp) > 60 * 60)) {
+			esp_state->esp_state = esp_state_get_time;
+			goto retry;
+		}
+		return true;
+	}
+	default:
+		esp_state->esp_state = esp_state_echo_off;
+		goto retry;
+	}
+
+	if (res_kind == at_response_kind_busy){
+		esp_state->esp_state = esp_state_reset;
+		goto retry;
+	}
+
+	printf("prepare error %s %d\n", itron_strerror(ret), res_kind);
+	esp_state->esp_state = esp_state_echo_off;
+	return false;
+}
+
+ESP_AT_SOCKET_HANDLE esp_at_socket_create(bool ssl)
+{
+	at_connection_t *connection = new_connection();
+	if (connection == NULL)
+		return NULL;
+
+	connection->ssl = ssl ? "SSL" : "TCP";
+	connection->esp_state = &esp_serial_state;
+
+	return (ESP_AT_SOCKET_HANDLE)connection;
+}
+
+void esp_at_socket_set_blocking(ESP_AT_SOCKET_HANDLE espAtSocketHandle, bool blocking, unsigned int timeout)
+{
+	at_connection_t *connection = (at_connection_t *)espAtSocketHandle;
+
+	connection->blocking = blocking;
+	connection->timeout = timeout;
+
+#ifdef AT_DEBUG
+	printf("\033[35mblocking:%s timeout:%d\033[0m\n", blocking ? "true" : "false", timeout);
+#endif
+}
+
+void esp_at_socket_destroy(ESP_AT_SOCKET_HANDLE espAtSocketHandle)
+{
+	at_connection_t *connection = (at_connection_t *)espAtSocketHandle;
+
+	delete_connection(connection);
+}
+
+int esp_at_socket_connect(ESP_AT_SOCKET_HANDLE espAtSocketHandle, const char *host, const int port)
+{
+	at_connection_t *connection = (at_connection_t *)espAtSocketHandle;
+	at_response_kind_t res_kind;
+
+	if (connection->state == connection_state_connected) {
+		printf("esp_at_socket_connect state error %d\n", connection->state);
+		return 0;
+	}
+
+	if (!prepare_esp_at()) {
+		printf("prepare_esp_at error\n");
+		return -MU_FAILURE;
+	}
+
+	connection->state = connection_state_connecting;
+
+	ER ret;
+	char temp[64];
+	sprintf(temp, "AT+CIPSTART=%d,\"%s\",\"%s\",%d\r\n", connection->link_id, connection->ssl, host, port);
+	ret = esp_serial_write(connection->esp_state, temp, &res_kind, 10000);
+	if ((ret != E_OK) || (res_kind != at_response_kind_connect)) {
+		printf("connect error connect %s %d\n", itron_strerror(ret), res_kind);
+		return -MU_FAILURE;
+	}
+	ret = esp_serial_read(connection->esp_state, &res_kind, 10000);
+	if ((ret != E_OK) || (res_kind != at_response_kind_ok)) {
+		printf("connect error done %s %d\n", itron_strerror(ret), res_kind);
+		return -MU_FAILURE;
+	}
+#ifdef AT_DEBUG
+	printf("\033[35mconnected !\033[0m\n");
+#endif
+	return 0;
+}
+
+bool esp_at_socket_is_connected(ESP_AT_SOCKET_HANDLE espAtSocketHandle)
+{
+	at_connection_t *connection = (at_connection_t *)espAtSocketHandle;
+
+	return connection->state == connection_state_connected;
+}
+
+void esp_at_socket_close(ESP_AT_SOCKET_HANDLE espAtSocketHandle)
+{
+	at_connection_t *connection = (at_connection_t *)espAtSocketHandle;
+	at_response_kind_t res_kind;
+
+	if (connection->state == connection_state_disconnected) {
+		printf("esp_at_socket_close state error %d\n", connection->state);
+		return;
+	}
+
+	connection->state = connection_state_disconnecting;
+
+	ER ret;
+	char temp[64];
+	sprintf(temp, "AT+CIPCLOSE=%d\r\n", connection->link_id);
+	ret = esp_serial_write(connection->esp_state, temp, &res_kind, 10000);
+	if (ret == E_OK) {
+		if (res_kind == at_response_kind_closed) {
+			ret = esp_serial_read(connection->esp_state, &res_kind, 10000);
+		}
+		if ((ret == E_OK) && (res_kind == at_response_kind_ok)) {
+		return;
+	}
+}
+
+	printf("close error %s %d\n", itron_strerror(ret), res_kind);
+}
+
+int esp_at_socket_send(ESP_AT_SOCKET_HANDLE espAtSocketHandle, const char *data, int length)
+{
+	at_connection_t *connection = (at_connection_t *)espAtSocketHandle;
+	at_response_kind_t res_kind;
+
+	if (connection->state != connection_state_connected) {
+		printf("esp_at_socket_send state error %d\n", connection->state);
+		return -MU_FAILURE;
+	}
+
+	ER ret;
+	char temp[64];
+	sprintf(temp, "AT+CIPSEND=%d,%d\r\n", connection->link_id, length);
+	ret = esp_serial_write(connection->esp_state, temp, &res_kind, 10000);
+	if ((ret != E_OK) || (res_kind != at_response_kind_ok)) {
+		printf("send error command %s %d\n", itron_strerror(ret), res_kind);
+		return -MU_FAILURE;
+	}
+	do {
+		ret = esp_serial_read(connection->esp_state, &res_kind, 10000);
+		if ((ret != E_OK) || ((res_kind != at_response_kind_ok)
+			&& (res_kind != at_response_kind_progress))) {
+			printf("send error progress %s %d\n", itron_strerror(ret), res_kind);
+			return -MU_FAILURE;
+		}
+	} while(res_kind == at_response_kind_ok);
+	ret = serial_wri_dat(AT_PORTID, data, length);
+	if (ret < 0) {
+		printf("send error write data %s\n", itron_strerror(ret));
+		return -MU_FAILURE;
+	}
+	do {
+		ret = esp_serial_read(connection->esp_state, &res_kind, 60000);
+		if (ret != E_OK) {
+			printf("send error done %s\n", itron_strerror(ret));
+			break;
+		}
+		if (res_kind == at_response_kind_send_ok)
+			return length;
+	} while ((res_kind == at_response_kind_no_set)
+		|| (res_kind == at_response_kind_ok));
+
+	printf("send error done kind=%d\n", res_kind);
+
+	return -MU_FAILURE;
+}
+
+int esp_at_socket_receive(ESP_AT_SOCKET_HANDLE espAtSocketHandle, char *data, int length)
+{
+	at_connection_t *connection = (at_connection_t *)espAtSocketHandle;
+
+	if (connection->state != connection_state_connected) {
+		printf("esp_at_socket_receive state error %d\n", connection->state);
+		return -MU_FAILURE;
+	}
+
+	int ret;
+	ret = connection_read_data(connection, data, length);
+	if (ret < 0) {
+		printf("receive error %s\n", itron_strerror(ret));
+		return -MU_FAILURE;
+	}
+#ifdef AT_DEBUG
+	if (ret > 0)
+		printf("\033[35mreceived %d\033[0m\n", ret);
+#endif
+	return ret;
+}
Index: azure_iot_hub_f767zi/trunk/app_iothub_client/src/esp_at_socket.h
===================================================================
--- azure_iot_hub_f767zi/trunk/app_iothub_client/src/esp_at_socket.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/app_iothub_client/src/esp_at_socket.h	(revision 457)
@@ -0,0 +1,64 @@
+/*
+ *  TOPPERS/ASP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Advanced Standard Profile Kernel
+ * 
+ *  Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
+ *                              Toyohashi Univ. of Technology, JAPAN
+ *  Copyright (C) 2004-2012 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  $Id$
+ */
+
+#ifndef _ESP_AT_SOCKET_H_
+#define _ESP_AT_SOCKET_H_
+
+#include <stdint.h>
+#include <stdbool.h>
+
+#define ETH_ALEN	6
+struct ether_addr {
+	uint8_t ether_addr_octet[ETH_ALEN];
+};
+
+typedef uint16_t in_port_t;
+typedef uint32_t in_addr_t;
+
+struct ether_addr *ether_aton_r(const char *x, struct ether_addr *p_a);
+
+void init_esp_at();
+
+/*ESPのバッファサイズ*/
+#define AT_CONNECTION_RX_BUFF_SIZE 4096
+
+#endif /* _ESP_AT_SOCKET_H_ */
Index: azure_iot_hub_f767zi/trunk/app_iothub_client/src/lwipopts.h
===================================================================
--- azure_iot_hub_f767zi/trunk/app_iothub_client/src/lwipopts.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/app_iothub_client/src/lwipopts.h	(revision 457)
@@ -0,0 +1,582 @@
+/**
+ * @file
+ *
+ * lwIP Options Configuration
+ */
+
+/*
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Adam Dunkels <adam@sics.se>
+ *
+ */
+#ifndef LWIP_LWIPOPTS_H
+#define LWIP_LWIPOPTS_H
+
+/*
+ * Include user defined options first. Anything not defined in these files
+ * will be set to standard values. Override anything you dont like!
+ */
+#include "lwip/arch.h"
+#include "lwip/debug.h"
+
+/*
+   -----------------------------------------------
+   ---------- Platform specific locking ----------
+   -----------------------------------------------
+*/
+
+/**
+ * SYS_LIGHTWEIGHT_PROT==1: if you want inter-task protection for certain
+ * critical regions during buffer allocation, deallocation and memory
+ * allocation and deallocation.
+ */
+#define SYS_LIGHTWEIGHT_PROT            1
+
+/**
+ * NO_SYS==1: Provides VERY minimal functionality. Otherwise,
+ * use lwIP facilities.
+ */
+#define NO_SYS                          0
+
+#define LWIP_IPV4                       (NO_SYS==0)
+#define LWIP_IPV6                       (NO_SYS==0)
+/*
+   ------------------------------------
+   ---------- Memory options ----------
+   ------------------------------------
+*/
+
+/**
+ * MEM_ALIGNMENT: should be set to the alignment of the CPU
+ *    4 byte alignment -> #define MEM_ALIGNMENT 4
+ *    2 byte alignment -> #define MEM_ALIGNMENT 2
+ */
+#define MEM_ALIGNMENT                   4U
+
+/**
+ * MEM_SIZE: the size of the heap memory. If the application will send
+ * a lot of data that needs to be copied, this should be set high.
+ */
+#define MEM_SIZE                        10240
+
+/*
+   ------------------------------------------------
+   ---------- Internal Memory Pool Sizes ----------
+   ------------------------------------------------
+*/
+/**
+ * MEMP_NUM_PBUF: the number of memp struct pbufs (used for PBUF_ROM and PBUF_REF).
+ * If the application sends a lot of data out of ROM (or other static memory),
+ * this should be set high.
+ */
+#define MEMP_NUM_PBUF                   16
+
+/**
+ * MEMP_NUM_RAW_PCB: Number of raw connection PCBs
+ * (requires the LWIP_RAW option)
+ */
+#define MEMP_NUM_RAW_PCB                3
+
+/**
+ * MEMP_NUM_UDP_PCB: the number of UDP protocol control blocks. One
+ * per active UDP "connection".
+ * (requires the LWIP_UDP option)
+ */
+#define MEMP_NUM_UDP_PCB               11
+
+/**
+ * MEMP_NUM_TCP_PCB: the number of simulatenously active TCP connections.
+ * (requires the LWIP_TCP option)
+ */
+#define MEMP_NUM_TCP_PCB                5
+
+/**
+ * MEMP_NUM_TCP_PCB_LISTEN: the number of listening TCP connections.
+ * (requires the LWIP_TCP option)
+ */
+#define MEMP_NUM_TCP_PCB_LISTEN         8
+
+/**
+ * MEMP_NUM_TCP_SEG: the number of simultaneously queued TCP segments.
+ * (requires the LWIP_TCP option)
+ */
+#define MEMP_NUM_TCP_SEG                16
+
+/**
+ * MEMP_NUM_REASSDATA: the number of simultaneously IP packets queued for
+ * reassembly (whole packets, not fragments!)
+ */
+#define MEMP_NUM_REASSDATA              10
+
+/**
+ * MEMP_NUM_ARP_QUEUE: the number of simulateously queued outgoing
+ * packets (pbufs) that are waiting for an ARP request (to resolve
+ * their destination address) to finish.
+ * (requires the ARP_QUEUEING option)
+ */
+#define MEMP_NUM_ARP_QUEUE              2
+
+/**
+ * MEMP_NUM_SYS_TIMEOUT: the number of simulateously active timeouts.
+ * (requires NO_SYS==0)
+ */
+#define MEMP_NUM_SYS_TIMEOUT            12
+
+/**
+ * MEMP_NUM_NETBUF: the number of struct netbufs.
+ * (only needed if you use the sequential API, like api_lib.c)
+ */
+#define MEMP_NUM_NETBUF                 2
+
+/**
+ * MEMP_NUM_NETCONN: the number of struct netconns.
+ * (only needed if you use the sequential API, like api_lib.c)
+ */
+#define MEMP_NUM_NETCONN                32
+
+/**
+ * MEMP_NUM_TCPIP_MSG_API: the number of struct tcpip_msg, which are used
+ * for callback/timeout API communication.
+ * (only needed if you use tcpip.c)
+ */
+#define MEMP_NUM_TCPIP_MSG_API          16
+
+/**
+ * MEMP_NUM_TCPIP_MSG_INPKT: the number of struct tcpip_msg, which are used
+ * for incoming packets.
+ * (only needed if you use tcpip.c)
+ */
+#define MEMP_NUM_TCPIP_MSG_INPKT        16
+
+/**
+ * PBUF_POOL_SIZE: the number of buffers in the pbuf pool.
+ */
+#define PBUF_POOL_SIZE                  50
+
+/*
+   ---------------------------------
+   ---------- ARP options ----------
+   ---------------------------------
+*/
+/**
+ * LWIP_ARP==1: Enable ARP functionality.
+ */
+#define LWIP_ARP                        1
+
+/*
+   --------------------------------
+   ---------- IP options ----------
+   --------------------------------
+*/
+/**
+ * IP_FORWARD==1: Enables the ability to forward IP packets across network
+ * interfaces. If you are going to run lwIP on a device with only one network
+ * interface, define this to 0.
+ */
+#define IP_FORWARD                      1
+
+/**
+ * IP_OPTIONS: Defines the behavior for IP options.
+ *      IP_OPTIONS_ALLOWED==0: All packets with IP options are dropped.
+ *      IP_OPTIONS_ALLOWED==1: IP options are allowed (but not parsed).
+ */
+#define IP_OPTIONS_ALLOWED              1
+
+/**
+ * IP_REASSEMBLY==1: Reassemble incoming fragmented IP packets. Note that
+ * this option does not affect outgoing packet sizes, which can be controlled
+ * via IP_FRAG.
+ */
+#define IP_REASSEMBLY                   1
+
+/**
+ * IP_FRAG==1: Fragment outgoing IP packets if their size exceeds MTU. Note
+ * that this option does not affect incoming packet sizes, which can be
+ * controlled via IP_REASSEMBLY.
+ */
+#define IP_FRAG                         1
+
+/**
+ * IP_REASS_MAXAGE: Maximum time (in multiples of IP_TMR_INTERVAL - so seconds, normally)
+ * a fragmented IP packet waits for all fragments to arrive. If not all fragments arrived
+ * in this time, the whole packet is discarded.
+ */
+#define IP_REASS_MAXAGE                 3
+
+/**
+ * IP_REASS_MAX_PBUFS: Total maximum amount of pbufs waiting to be reassembled.
+ * Since the received pbufs are enqueued, be sure to configure
+ * PBUF_POOL_SIZE > IP_REASS_MAX_PBUFS so that the stack is still able to receive
+ * packets even if the maximum amount of fragments is enqueued for reassembly!
+ */
+#define IP_REASS_MAX_PBUFS              10
+
+/**
+ * IP_FRAG_USES_STATIC_BUF==1: Use a static MTU-sized buffer for IP
+ * fragmentation. Otherwise pbufs are allocated and reference the original
+    * packet data to be fragmented.
+*/
+#define IP_FRAG_USES_STATIC_BUF         0
+
+/**
+ * IP_DEFAULT_TTL: Default value for Time-To-Live used by transport layers.
+ */
+#define IP_DEFAULT_TTL                  255
+
+/*
+   ----------------------------------
+   ---------- ICMP options ----------
+   ----------------------------------
+*/
+/**
+ * LWIP_ICMP==1: Enable ICMP module inside the IP stack.
+ * Be careful, disable that make your product non-compliant to RFC1122
+ */
+#define LWIP_ICMP                       1
+
+/*
+   ---------------------------------
+   ---------- RAW options ----------
+   ---------------------------------
+*/
+/**
+ * LWIP_RAW==1: Enable application layer to hook into the IP layer itself.
+ */
+#define LWIP_RAW                        1
+
+/*
+   ----------------------------------
+   ---------- DHCP options ----------
+   ----------------------------------
+*/
+/**
+ * LWIP_DHCP==1: Enable DHCP module.
+ */
+#define LWIP_DHCP                       1
+
+
+/*
+   ------------------------------------
+   ---------- AUTOIP options ----------
+   ------------------------------------
+*/
+/**
+ * LWIP_AUTOIP==1: Enable AUTOIP module.
+ */
+#define LWIP_AUTOIP                     (LWIP_DHCP)
+
+/*
+   ----------------------------------
+   ---------- SNMP options ----------
+   ----------------------------------
+*/
+/**
+ * LWIP_SNMP==1: Turn on SNMP module. UDP must be available for SNMP
+ * transport.
+ */
+#define LWIP_SNMP                       1
+
+/*
+   ----------------------------------
+   ---------- IGMP options ----------
+   ----------------------------------
+*/
+/**
+ * LWIP_IGMP==1: Turn on IGMP module.
+ */
+#define LWIP_IGMP                       (LWIP_IPV4)
+
+/*
+   ----------------------------------
+   ---------- DNS options -----------
+   ----------------------------------
+*/
+/**
+ * LWIP_DNS==1: Turn on DNS module. UDP must be available for DNS
+ * transport.
+ */
+#define LWIP_DNS                        1
+
+/*
+   ---------------------------------
+   ---------- UDP options ----------
+   ---------------------------------
+*/
+/**
+ * LWIP_UDP==1: Turn on UDP.
+ */
+#define LWIP_UDP                        1
+
+/*
+   ---------------------------------
+   ---------- TCP options ----------
+   ---------------------------------
+*/
+/**
+ * LWIP_TCP==1: Turn on TCP.
+ */
+#define LWIP_TCP                        1
+
+#define LWIP_LISTEN_BACKLOG             0
+
+/*
+   ----------------------------------
+   ---------- Pbuf options ----------
+   ----------------------------------
+*/
+/**
+ * PBUF_LINK_HLEN: the number of bytes that should be allocated for a
+ * link level header. The default is 14, the standard value for
+ * Ethernet.
+ */
+#define PBUF_LINK_HLEN                  16
+
+/**
+ * PBUF_POOL_BUFSIZE: the size of each pbuf in the pbuf pool. The default is
+ * designed to accomodate single full size TCP frame in one pbuf, including
+ * TCP_MSS, IP header, and link header.
+*
+ */
+#define PBUF_POOL_BUFSIZE               LWIP_MEM_ALIGN_SIZE(TCP_MSS+40+PBUF_LINK_HLEN)
+
+/*
+   ------------------------------------
+   ---------- LOOPIF options ----------
+   ------------------------------------
+*/
+/**
+ * LWIP_HAVE_LOOPIF==1: Support loop interface (127.0.0.1) and loopif.c
+ */
+#define LWIP_HAVE_LOOPIF                0
+
+/*
+   ----------------------------------------------
+   ---------- Sequential layer options ----------
+   ----------------------------------------------
+*/
+
+/**
+ * LWIP_NETCONN==1: Enable Netconn API (require to use api_lib.c)
+ */
+#define LWIP_NETCONN                    1
+
+/*
+   ------------------------------------
+   ---------- Socket options ----------
+   ------------------------------------
+*/
+/**
+ * LWIP_SOCKET==1: Enable Socket API (require to use sockets.c)
+ */
+#define LWIP_SOCKET                     1
+
+/**
+ * SO_REUSE==1: Enable SO_REUSEADDR
+ */
+#define SO_REUSE                        1
+
+/*
+   ----------------------------------------
+   ---------- Statistics options ----------
+   ----------------------------------------
+*/
+/**
+ * LWIP_STATS==1: Enable statistics collection in lwip_stats.
+ */
+#define LWIP_STATS                      1
+/*
+   ---------------------------------
+   ---------- PPP options ----------
+   ---------------------------------
+*/
+/**
+ * PPP_SUPPORT==1: Enable PPP.
+ */
+#define PPP_SUPPORT                     0
+
+
+#define LWIP_DBG_MIN_LEVEL              LWIP_DBG_LEVEL_ALL
+#define LWIP_COMPAT_SOCKETS             1
+
+#define PPP_DEBUG                       LWIP_DBG_OFF
+#define MEM_DEBUG                       LWIP_DBG_OFF
+#define API_MSG_DEBUG                   LWIP_DBG_OFF
+#define TCPIP_DEBUG                     LWIP_DBG_OFF
+#define NETIF_DEBUG                     LWIP_DBG_OFF
+#define SOCKETS_DEBUG                   LWIP_DBG_OFF
+#define IP_DEBUG                        LWIP_DBG_OFF
+#define IP_REASS_DEBUG                  LWIP_DBG_OFF
+#define RAW_DEBUG                       LWIP_DBG_OFF
+#define ICMP_DEBUG                      LWIP_DBG_OFF
+#define UDP_DEBUG                       LWIP_DBG_OFF
+#define TCP_DEBUG                       LWIP_DBG_OFF
+#define TCP_INPUT_DEBUG                 LWIP_DBG_OFF
+#define TCP_OUTPUT_DEBUG                LWIP_DBG_OFF
+#define TCP_RTO_DEBUG                   LWIP_DBG_OFF
+#define TCP_CWND_DEBUG                  LWIP_DBG_OFF
+#define TCP_WND_DEBUG                   LWIP_DBG_OFF
+#define TCP_FR_DEBUG                    LWIP_DBG_OFF
+#define TCP_QLEN_DEBUG                  LWIP_DBG_OFF
+#define TCP_RST_DEBUG                   LWIP_DBG_OFF
+#define DHCP_DEBUG                      LWIP_DBG_OFF
+#define TIMERS_DEBUG                    LWIP_DBG_OFF
+#define LWIP_DEBUG_TIMERNAMES           LWIP_DBG_OFF
+#define SNTP_DEBUG                      LWIP_DBG_OFF
+#define DNS_DEBUG                       LWIP_DBG_OFF
+
+extern unsigned char debug_flags;
+#define LWIP_DBG_TYPES_ON               debug_flags
+
+#define IP_SOF_BROADCAST_RECV           1
+#define IP_SOF_BROADCAST                1
+#define SO_REUSE_RXTOALL                1
+#define LWIP_SO_RCVTIMEO                (LWIP_SOCKET)
+
+#define MEMP_OVERFLOW_CHECK             1
+
+#define LWIP_TCPIP_TIMEOUT              1
+
+/* ---------- TCP options ---------- */
+
+#define TCP_LISTEN_BACKLOG              1
+
+/* Controls if TCP should queue segments that arrive out of
+   order. Define to 0 if your device is low on memory. */
+#define TCP_QUEUE_OOSEQ                 1
+
+/* TCP Maximum segment size. */
+#define TCP_MSS                         1024
+
+/* TCP sender buffer space (bytes). */
+#define TCP_SND_BUF                     (2 * TCP_MSS)
+
+/* TCP sender buffer space (pbufs). This must be at least = 2 *
+   TCP_SND_BUF/TCP_MSS for things to work. */
+#define TCP_SND_QUEUELEN                (4 * TCP_SND_BUF/TCP_MSS)
+
+/* TCP writable space (bytes). This must be less than or equal
+   to TCP_SND_BUF. It is the amount of space which must be
+   available in the tcp snd_buf for select to return writable */
+#define TCP_SNDLOWAT		            (TCP_SND_BUF/2)
+
+/* TCP receive window. */
+#define TCP_WND                         (4 * TCP_MSS)
+
+/* Maximum number of retransmissions of data segments. */
+#define TCP_MAXRTX                      12
+
+/* Maximum number of retransmissions of SYN segments. */
+#define TCP_SYNMAXRTX                   4
+
+/* ---------- ARP options ---------- */
+#define ARP_TABLE_SIZE                  10
+#define ARP_QUEUEING                    1
+
+
+
+/* IP reassembly and segmentation.These are orthogonal even
+ * if they both deal with IP fragments */
+#define IPV6_FRAG_COPYHEADER            1
+#define LWIP_IPV6_FRAG                  1
+
+
+/* ---------- ICMP options ---------- */
+#define ICMP_TTL                        (IP_DEFAULT_TTL)
+
+/* ---------- DHCP options ---------- */
+/* Define LWIP_DHCP to 1 if you want DHCP configuration of
+   interfaces. */
+
+#define LWIP_DHCP_GET_NTP_SRV           (LWIP_DHCP)
+
+/* 1 if you want to do an ARP check on the offered address
+   (recommended if using DHCP). */
+#define DHCP_DOES_ARP_CHECK             (LWIP_DHCP)
+
+/* ---------- AUTOIP options ------- */
+#define LWIP_DHCP_AUTOIP_COOP           (LWIP_DHCP)
+#define LWIP_DHCP_AUTOIP_COOP_TRIES     3
+
+/* ---------- SNTP options --------- */
+extern void sntp_set_system_time(u32_t sec);
+#define SNTP_SET_SYSTEM_TIME(s)         sntp_set_system_time(s)
+#define SNTP_SERVER_DNS                 1
+#define SNTP_STARTUP_DELAY              1
+
+/* ---------- SNMP options ---------- */
+#define MIB2_STATS                      LWIP_SNMP
+#define SNMP_USE_NETCONN                LWIP_NETCONN
+#define SNMP_USE_RAW                    (!LWIP_NETCONN)
+
+
+/* ---------- MDNS options ---------- */
+#define LWIP_MDNS_RESPONDER             1
+#define LWIP_NUM_NETIF_CLIENT_DATA      (LWIP_MDNS_RESPONDER)
+
+/* ---------- UDP options ---------- */
+#define UDP_TTL                         (IP_DEFAULT_TTL)
+
+/* ---------- RAW options ---------- */
+#define RAW_TTL                         (IP_DEFAULT_TTL)
+
+
+#define LWIP_NETIF_API                  1
+#define LWIP_NETIF_STATUS_CALLBACK      1
+#define LWIP_NETIF_HOSTNAME             0
+
+/* ---------- SLIP options ---------- */
+
+#define LWIP_HAVE_SLIPIF                1      /* Set > 0 for SLIP */
+
+/* Maximum packet size that is received by this netif */
+#define SLIP_MAX_SIZE                   1500
+#define sio_tryread                     sio_read
+
+#define LWIP_HTTPD_SSI                  1
+
+
+/*
+ *  TOPPERS Additional DEFINE
+ */
+#define ETH_PAD_SIZE                    2
+#define SHELL_ECHO                      1
+#define TFTP_MAX_MODE_LEN               9
+
+#define IN_ADDR_T_DEFINED
+
+extern void sys_memcpy(volatile void *d, const volatile void *s, int len);
+#define MEMCPY(dst,src,len)             sys_memcpy(dst,src,len)
+
+extern void sys_memcpy(volatile void *d, const volatile void *s, int len);
+#define SMEMCPY(dst,src,len)            sys_memcpy(dst,src,len)
+
+extern void sys_memset(volatile void *d, unsigned char val, int len);
+#define MEMSET(a, b, c)  sys_memset(a, b, c)
+
+#endif /* LWIP_LWIPOPTS_H */
Index: azure_iot_hub_f767zi/trunk/app_iothub_client/src/main.c
===================================================================
--- azure_iot_hub_f767zi/trunk/app_iothub_client/src/main.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/app_iothub_client/src/main.c	(revision 457)
@@ -0,0 +1,1031 @@
+/*
+ *  TOPPERS/ASP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Advanced Standard Profile Kernel
+ * 
+ *  Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
+ *                              Toyohashi Univ. of Technology, JAPAN
+ *  Copyright (C) 2004-2012 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  $Id$
+ */
+
+/*
+ * Copyright (c) 2001-2003 Swedish Institute of Computer Science.
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission. 
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ * 
+ * Author: Adam Dunkels <adam@sics.se>
+ *
+ */
+
+/* 
+ *  サンプルプログラムの本体
+ */
+
+#include <kernel.h>
+#include <t_syslog.h>
+#include <t_stdlib.h>
+#include <sil.h>
+#include "syssvc/serial.h"
+#include "syssvc/syslog.h"
+#ifdef USE_STORAGEDEVICE
+#include "storagedevice.h"
+#endif	/* USE_STORAGEDEVICE */
+#include "kernel_cfg.h"
+#include "device.h"
+#include "sdmmc.h"
+#include "client.h"
+#include "monitor.h"
+#include "main.h"
+
+#include "lwip/opt.h"
+
+#include "lwip/init.h"
+
+#include "lwip/mem.h"
+#include "lwip/memp.h"
+#include "lwip/sys.h"
+#include "lwip/timeouts.h"
+
+#include "lwip/ip_addr.h"
+
+#include "lwip/dns.h"
+#include "lwip/dhcp.h"
+
+#include "lwip/stats.h"
+
+#include "lwip/tcp.h"
+#include "lwip/inet_chksum.h"
+
+#include "lwip/tcpip.h"
+#include "lwip/sockets.h"
+
+
+#if 0
+#include "netif/pcapif.h"
+#endif
+
+#ifndef LWIP_HAVE_SLIPIF
+#define LWIP_HAVE_SLIPIF 0
+#endif
+#if LWIP_HAVE_SLIPIF
+#include "netif/slipif.h"
+#define SLIP_PTY_TEST 1
+#endif
+
+#if PPP_SUPPORT
+#include "netif/ppp/pppos.h"
+#include "lwip/sio.h"
+#define PPP_PTY_TEST 1
+#include <termios.h>
+#endif
+
+#include "lwip/ip_addr.h"
+
+#include "lwip/apps/httpd.h"
+#include "apps/udpecho/udpecho.h"
+#include "apps/tcpecho/tcpecho.h"
+#include "apps/shell/shell.h"
+#include "apps/chargen/chargen.h"
+#include "apps/netio/netio.h"
+#include "apps/ping/ping.h"
+#include "lwip/apps/netbiosns.h"
+#include "lwip/apps/mdns.h"
+#include "lwip/apps/sntp.h"
+#include "lwip/apps/snmp.h"
+#include "lwip/apps/snmp_mib2.h"
+#include "examples/snmp/snmp_private_mib/private_mib.h"
+#include "lwip/apps/tftp_server.h"
+
+#if LWIP_RAW
+#include "lwip/icmp.h"
+#include "lwip/raw.h"
+#endif
+#include "lwip/inet.h"
+#include "esp_at_socket.h"
+
+err_t ethernetif_init(struct netif *netif);
+
+/*
+ *  サービスコールのエラーのログ出力
+ */
+Inline void
+svc_perror(const char *file, int_t line, const char *expr, ER ercd)
+{
+	if (ercd < 0) {
+		t_perror(LOG_ERROR, file, line, expr, ercd);
+	}
+}
+
+#define	SVC_PERROR(expr)	svc_perror(__FILE__, __LINE__, #expr, (expr))
+
+/*static*/ uint32_t heap_area[16*1024];
+
+intptr_t heap_param[2] = {
+	(intptr_t )heap_area,
+	sizeof(heap_area)
+};
+
+#ifdef _STORAGEDEVICE_H_
+static void storagedev_notice(void *psdev, bool_t sw)
+{
+	syslog_2(LOG_NOTICE, "SD-CARD[%08x] on/off(%d) !", psdev, sw);
+}
+
+static uint32_t get_fat_time(void)
+{
+	int    reqtime = 0;
+
+	reqtime = 0x00210000;
+	return reqtime;
+}
+#endif	/* _STORAGEDEVICE_H_ */
+
+uint32_t LWIP_RAND(void)
+{
+	return (uint32_t)rand();
+}
+
+#if LWIP_SNMP
+static const struct snmp_mib *mibs[] = {
+	&mib2,
+	&mib_private
+};
+#endif /* LWIP_SNMP */
+
+#if LWIP_IPV4
+/* (manual) host IP configuration */
+static ip_addr_t ipaddr, netmask, gw;
+#endif /* LWIP_IPV4 */
+
+struct netif netif;
+
+/* ping out destination cmd option */
+static ip_addr_t ping_addr;
+
+static bool_t tcpip_init_flag = false;
+
+/* nonstatic debug cmd option, exported in lwipopts.h */
+unsigned char debug_flags;
+
+static void init_netifs(void);
+
+#if 0
+static void
+tcp_debug_timeout(void *data)
+{
+  LWIP_UNUSED_ARG(data);
+#if TCP_DEBUG
+  tcp_debug_print_pcbs();
+#endif /* TCP_DEBUG */
+  sys_timeout(5000, tcp_debug_timeout, NULL);
+}
+#endif
+
+/*
+ * gmtime_r関数
+ */
+struct tm *gmtime_r(const time_t *pt, struct tm *ptm);
+
+void
+sntp_set_system_time(u32_t sec)
+{
+	struct tm current_time_val;
+	time_t current_time = (time_t)sec;
+
+	gmtime_r(&current_time, &current_time_val);
+	rtc_set_time((struct tm2 *)&current_time_val);
+
+	current_time = 0;
+	memset(&current_time_val, 0, sizeof(current_time_val));
+
+	current_time = time(NULL);
+	//gmtime_r(&current_time, &current_time_val);
+	//printf("%04d/%02d/%02d %02d:%02d:%02d\n",
+	//	current_time_val.tm_year+1900, current_time_val.tm_mon+1, current_time_val.tm_mday,
+	//	current_time_val.tm_hour, current_time_val.tm_min, current_time_val.tm_sec);
+	printf("%s\n", ctime(&current_time));
+}
+
+#if LWIP_MDNS_RESPONDER
+static void
+srv_txt(struct mdns_service *service, void *txt_userdata)
+{
+	err_t res;
+	LWIP_UNUSED_ARG(txt_userdata);
+
+	res = mdns_resp_add_service_txtitem(service, "path=/", 6);
+	LWIP_ERROR("mdns add service txt failed\n", (res == ERR_OK), return);
+}
+#endif
+
+#if LWIP_UDP
+
+static void*
+tftp_open(const char* fname, const char* mode, u8_t is_write)
+{
+#ifdef _STORAGEDEVICE_H_
+	LWIP_UNUSED_ARG(mode);
+
+	if(is_write)
+		return (void*)fopen(fname, "wb");
+	else
+		return (void*)fopen(fname, "rb");
+#else	/* _STORAGEDEVICE_H_ */
+	return NULL;
+#endif	/* _STORAGEDEVICE_H_ */
+}
+
+static void 
+tftp_close(void* handle)
+{
+#ifdef _STORAGEDEVICE_H_
+	fclose((FILE*)handle);
+#endif	/* _STORAGEDEVICE_H_ */
+}
+
+static int
+tftp_read(void* handle, void* buf, int bytes)
+{
+#ifdef _STORAGEDEVICE_H_
+	int rlen = fread(buf, 1, bytes, (FILE*)handle);
+	if(rlen <= 0)
+		return -1;
+	else
+		return rlen;
+#else	/* _STORAGEDEVICE_H_ */
+	return -1;
+#endif	/* _STORAGEDEVICE_H_ */
+}
+
+static int
+tftp_write(void* handle, struct pbuf* p)
+{
+#ifdef _STORAGEDEVICE_H_
+	while(p != NULL){
+		if(fwrite(p->payload, 1, p->len, (FILE*)handle) != (size_t)p->len)
+			return -1;
+		p = p->next;
+	}
+	return 0;
+#else	/* _STORAGEDEVICE_H_ */
+	return -1;
+#endif	/* _STORAGEDEVICE_H_ */
+}
+
+static const struct tftp_context tftp = {
+	tftp_open,
+	tftp_close,
+	tftp_read,
+	tftp_write
+};
+
+#endif /* LWIP_UDP */
+
+static void
+tcpip_init_done(void *arg)
+{
+	sys_sem_t *sem;
+	sem = (sys_sem_t *)arg;
+
+	init_netifs();
+
+#if LWIP_IPV4
+	netbiosns_set_name("toppershost");
+	netbiosns_init();
+#endif /* LWIP_IPV4 */
+
+	sntp_setoperatingmode(SNTP_OPMODE_POLL);
+#if LWIP_DHCP
+	sntp_servermode_dhcp(1); /* get SNTP server via DHCP */
+#else /* LWIP_DHCP */
+#if LWIP_IPV4
+	//sntp_setserver(0, netif_ip_gw4(&netif));
+#endif /* LWIP_IPV4 */
+#endif /* LWIP_DHCP */
+	sntp_setservername(0, "ntp.nict.jp");
+	sntp_init();
+
+#if LWIP_SNMP
+	lwip_privmib_init();
+#if SNMP_LWIP_MIB2
+#if SNMP_USE_NETCONN
+	snmp_threadsync_init(&snmp_mib2_lwip_locks, snmp_mib2_lwip_synchronizer);
+#endif /* SNMP_USE_NETCONN */
+	snmp_mib2_set_syscontact_readonly((const u8_t*)"root", NULL);
+	snmp_mib2_set_syslocation_readonly((const u8_t*)"lwIP development PC", NULL);
+	snmp_mib2_set_sysdescr((const u8_t*)"toppershost", NULL);
+#endif /* SNMP_LWIP_MIB2 */
+
+	snmp_set_mibs(mibs, LWIP_ARRAYSIZE(mibs));
+	snmp_init();
+#endif /* LWIP_SNMP */
+
+#if LWIP_MDNS_RESPONDER
+	mdns_resp_init();
+	mdns_resp_add_netif(&netif, "toppershost", 3600);
+	mdns_resp_add_service(&netif, "myweb", "_http", DNSSD_PROTO_TCP, 80, 3600, srv_txt, NULL);
+#endif
+
+#if LWIP_UDP
+	tftp_init(&tftp);
+#endif /* LWIP_UDP */
+
+	sys_sem_signal(sem);
+}
+
+/*-----------------------------------------------------------------------------------*/
+
+#if LWIP_HAVE_SLIPIF
+/* (manual) host IP configuration */
+#if LWIP_IPV4
+static ip_addr_t ipaddr_slip, netmask_slip, gw_slip;
+#endif /* LWIP_IPV4 */
+struct netif slipif;
+#endif /* LWIP_HAVE_SLIPIF */
+
+#if PPP_SUPPORT
+sio_fd_t ppp_sio;
+ppp_pcb *ppp;
+struct netif pppos_netif;
+
+static void
+pppos_rx_thread(void *arg)
+{
+	u32_t len;
+	u8_t buffer[128];
+	LWIP_UNUSED_ARG(arg);
+
+	/* Please read the "PPPoS input path" chapter in the PPP documentation. */
+	while(1){
+		len = sio_read(ppp_sio, buffer, sizeof(buffer));
+		if (len > 0) {
+			/* Pass received raw characters from PPPoS to be decoded through lwIP
+			 * TCPIP thread using the TCPIP API. This is thread safe in all cases
+			 * but you should avoid passing data byte after byte. */
+			pppos_input_tcpip(ppp, buffer, len);
+		}
+	}
+}
+
+static void
+ppp_link_status_cb(ppp_pcb *pcb, int err_code, void *ctx)
+{
+    struct netif *pppif = ppp_netif(pcb);
+    LWIP_UNUSED_ARG(ctx);
+
+    switch(err_code) {
+    case PPPERR_NONE:               /* No error. */
+        {
+#if LWIP_DNS
+        const ip_addr_t *ns;
+#endif /* LWIP_DNS */
+        fprintf(stderr, "ppp_link_status_cb: PPPERR_NONE\n\r");
+#if LWIP_IPV4
+        fprintf(stderr, "   our_ip4addr = %s\n\r", ip4addr_ntoa(netif_ip4_addr(pppif)));
+        fprintf(stderr, "   his_ipaddr  = %s\n\r", ip4addr_ntoa(netif_ip4_gw(pppif)));
+        fprintf(stderr, "   netmask     = %s\n\r", ip4addr_ntoa(netif_ip4_netmask(pppif)));
+#endif /* LWIP_IPV4 */
+#if LWIP_IPV6
+        fprintf(stderr, "   our_ip6addr = %s\n\r", ip6addr_ntoa(netif_ip6_addr(pppif, 0)));
+#endif /* LWIP_IPV6 */
+
+#if LWIP_DNS
+        ns = dns_getserver(0);
+        fprintf(stderr, "   dns1        = %s\n\r", ipaddr_ntoa(ns));
+        ns = dns_getserver(1);
+        fprintf(stderr, "   dns2        = %s\n\r", ipaddr_ntoa(ns));
+#endif /* LWIP_DNS */
+#if PPP_IPV6_SUPPORT
+        fprintf(stderr, "   our6_ipaddr = %s\n\r", ip6addr_ntoa(netif_ip6_addr(pppif, 0)));
+#endif /* PPP_IPV6_SUPPORT */
+        }
+        break;
+
+    case PPPERR_PARAM:             /* Invalid parameter. */
+        printf("ppp_link_status_cb: PPPERR_PARAM\n");
+        break;
+
+    case PPPERR_OPEN:              /* Unable to open PPP session. */
+        printf("ppp_link_status_cb: PPPERR_OPEN\n");
+        break;
+
+    case PPPERR_DEVICE:            /* Invalid I/O device for PPP. */
+        printf("ppp_link_status_cb: PPPERR_DEVICE\n");
+        break;
+
+    case PPPERR_ALLOC:             /* Unable to allocate resources. */
+        printf("ppp_link_status_cb: PPPERR_ALLOC\n");
+        break;
+
+    case PPPERR_USER:              /* User interrupt. */
+        printf("ppp_link_status_cb: PPPERR_USER\n");
+        break;
+
+    case PPPERR_CONNECT:           /* Connection lost. */
+        printf("ppp_link_status_cb: PPPERR_CONNECT\n");
+        break;
+
+    case PPPERR_AUTHFAIL:          /* Failed authentication challenge. */
+        printf("ppp_link_status_cb: PPPERR_AUTHFAIL\n");
+        break;
+
+    case PPPERR_PROTOCOL:          /* Failed to meet protocol. */
+        printf("ppp_link_status_cb: PPPERR_PROTOCOL\n");
+        break;
+
+    case PPPERR_PEERDEAD:          /* Connection timeout. */
+        printf("ppp_link_status_cb: PPPERR_PEERDEAD\n");
+        break;
+
+    case PPPERR_IDLETIMEOUT:       /* Idle Timeout. */
+        printf("ppp_link_status_cb: PPPERR_IDLETIMEOUT\n");
+        break;
+
+    case PPPERR_CONNECTTIME:       /* PPPERR_CONNECTTIME. */
+        printf("ppp_link_status_cb: PPPERR_CONNECTTIME\n");
+        break;
+
+    case PPPERR_LOOPBACK:          /* Connection timeout. */
+        printf("ppp_link_status_cb: PPPERR_LOOPBACK\n");
+        break;
+
+    default:
+        printf("ppp_link_status_cb: unknown errCode %d\n", err_code);
+        break;
+    }
+}
+
+static u32_t
+ppp_output_cb(ppp_pcb *pcb, u8_t *data, u32_t len, void *ctx)
+{
+  LWIP_UNUSED_ARG(pcb);
+  LWIP_UNUSED_ARG(ctx);
+  return sio_write(ppp_sio, data, len);
+}
+#endif
+
+#if LWIP_NETIF_STATUS_CALLBACK
+static void
+netif_status_callback(struct netif *nif)
+{
+	printf("NETIF: %c%c%d is %s\n", nif->name[0], nif->name[1], nif->num,
+		netif_is_up(nif) ? "UP" : "DOWN");
+#if LWIP_IPV4
+	printf("IPV4: Host at %s ", ip4addr_ntoa(netif_ip4_addr(nif)));
+	printf("mask %s ", ip4addr_ntoa(netif_ip4_netmask(nif)));
+	printf("gateway %s\n", ip4addr_ntoa(netif_ip4_gw(nif)));
+#endif /* LWIP_IPV4 */
+#if LWIP_IPV6
+	printf("IPV6: Host at %s\n", ip6addr_ntoa(netif_ip6_addr(nif, 0)));
+#endif /* LWIP_IPV6 */
+#if LWIP_NETIF_HOSTNAME
+	printf("FQDN: %s\n", netif_get_hostname(nif));
+#endif /* LWIP_NETIF_HOSTNAME */
+
+#if LWIP_MDNS_RESPONDER
+	if(tcpip_init_flag)
+		mdns_resp_netif_settings_changed(nif);
+#endif
+}
+#endif /* LWIP_NETIF_STATUS_CALLBACK */
+
+static void
+init_netifs(void)
+{
+#if LWIP_HAVE_SLIPIF
+#if SLIP_PTY_TEST
+	u8_t siodev_slip = 3;
+#else
+	u8_t siodev_slip = 0;
+#endif
+
+#if LWIP_IPV4
+	netif_add(&slipif, ip_2_ip4(&ipaddr_slip), ip_2_ip4(&netmask_slip), ip_2_ip4(&gw_slip),
+		(void*)&siodev_slip, slipif_init, tcpip_input);
+#else /* LWIP_IPV4 */
+	netif_add(&slipif, (void*)&siodev_slip, slipif_init, tcpip_input);
+#endif /* LWIP_IPV4 */
+#if LWIP_IPV6
+	netif_create_ip6_linklocal_address(&slipif, 1);
+#endif
+#if LWIP_NETIF_STATUS_CALLBACK
+	netif_set_status_callback(&slipif, netif_status_callback);
+#endif /* LWIP_NETIF_STATUS_CALLBACK */
+	netif_set_link_up(&slipif);
+	netif_set_up(&slipif);
+#endif /* LWIP_HAVE_SLIPIF */
+
+#if PPP_SUPPORT
+#if PPP_PTY_TEST
+	ppp_sio = sio_open(2);
+#else
+	ppp_sio = sio_open(0);
+#endif
+	if(!ppp_sio){
+		syslog_0(LOG_ERROR, "Error opening device: ");
+		slp_tsk();
+	}
+
+	ppp = pppos_create(&pppos_netif, ppp_output_cb, ppp_link_status_cb, NULL);
+	if(!ppp){
+		syslog_0(LOG_ERROR, "Could not create PPP control interface");
+		slp_tsk();
+	}
+
+#ifdef LWIP_PPP_CHAP_TEST
+	ppp_set_auth(ppp, PPPAUTHTYPE_CHAP, "lwip", "mysecret");
+#endif
+
+	ppp_connect(ppp, 0);
+
+#if LWIP_NETIF_STATUS_CALLBACK
+	netif_set_status_callback(&pppos_netif, netif_status_callback);
+#endif /* LWIP_NETIF_STATUS_CALLBACK */
+#endif /* PPP_SUPPORT */
+
+#if LWIP_IPV4
+#if LWIP_DHCP
+	IP_ADDR4(&gw,      0,0,0,0);
+	IP_ADDR4(&ipaddr,  0,0,0,0);
+	IP_ADDR4(&netmask, 0,0,0,0);
+#endif /* LWIP_DHCP */
+	netif_add(&netif, ip_2_ip4(&ipaddr), ip_2_ip4(&netmask), ip_2_ip4(&gw), NULL, ethernetif_init, tcpip_input);
+#else /* LWIP_IPV4 */
+	netif_add(&netif, NULL, ethernetif_init, tcpip_input);
+#endif /* LWIP_IPV4 */
+#if LWIP_IPV6
+	netif_create_ip6_linklocal_address(&netif, 1);
+	netif.ip6_autoconfig_enabled = 1;
+#endif
+#if LWIP_NETIF_STATUS_CALLBACK
+	netif_set_status_callback(&netif, netif_status_callback);
+#endif /* LWIP_NETIF_STATUS_CALLBACK */
+	netif_set_default(&netif);
+	netif_set_up(&netif);
+
+#if LWIP_DHCP
+	dhcp_start(&netif);
+#endif /* LWIP_DHCP */
+
+#if 0
+	/* Only used for testing purposes: */
+	netif_add(&ipaddr, &netmask, &gw, NULL, pcapif_init, tcpip_input);
+#endif
+
+#if LWIP_TCP
+	netio_init();
+#endif
+#if LWIP_TCP && LWIP_NETCONN
+	tcpecho_init();
+	shell_init();
+	httpd_init();
+#endif
+#if LWIP_UDP && LWIP_NETCONN
+	udpecho_init();
+#endif  
+#if LWIP_SOCKET
+	chargen_init();
+#endif
+	/*  sys_timeout(5000, tcp_debug_timeout, NULL);*/
+}
+
+/*-----------------------------------------------------------------------------------*/
+static void
+main_thread(void *arg)
+{
+	sys_sem_t sem;
+	LWIP_UNUSED_ARG(arg);
+
+	if(sys_sem_new(&sem, 0) != ERR_OK) {
+		LWIP_ASSERT("Failed to create semaphore", 0);
+	}
+	tcpip_init(tcpip_init_done, &sem);
+	sys_sem_wait(&sem);
+	syslog_0(LOG_NOTICE, "TCP/IP initialized.");
+
+#if LWIP_SOCKET && defined(USE_PINGSEND)
+	ping_init(&ping_addr);
+#endif
+
+	syslog_0(LOG_NOTICE, "Applications started.");
+
+#ifdef MEM_PERF
+	mem_perf_init("/tmp/memstats.client");
+#endif /* MEM_PERF */
+#if 0
+	stats_display();
+#endif
+#if PPP_SUPPORT
+	/* Block forever. */
+	sys_thread_new("pppos_rx_thread", pppos_rx_thread, NULL, DEFAULT_THREAD_STACKSIZE, DEFAULT_THREAD_PRIO);
+	sys_sem_wait(&sem);
+#endif
+	tcpip_init_flag = true;
+}
+
+int wolfSSL_Debugging_ON(void);
+void esp_at_task(intptr_t exinf);
+
+/*
+ *  メインタスク
+ */
+void
+main_task(intptr_t exinf)
+{
+#ifdef _STORAGEDEVICE_H_
+	StorageDevice_t *psdev;
+#endif	/* _STORAGEDEVICE_H_ */
+	ER_UINT	ercd;
+
+	SVC_PERROR(syslog_msk_log(LOG_UPTO(LOG_NOTICE), LOG_UPTO(LOG_EMERG)));
+	syslog(LOG_NOTICE, "Sample program starts (exinf = %d).", (int_t) exinf);
+
+	/*
+	 *  シリアルポートの初期化
+	 *
+	 *  システムログタスクと同じシリアルポートを使う場合など，シリアル
+	 *  ポートがオープン済みの場合にはここでE_OBJエラーになるが，支障は
+	 *  ない．
+	 */
+	ercd = serial_opn_por(TASK_PORTID);
+	if (ercd < 0 && MERCD(ercd) != E_OBJ) {
+		syslog(LOG_ERROR, "%s (%d) reported by `serial_opn_por'.",
+									itron_strerror(ercd), SERCD(ercd));
+	}
+	SVC_PERROR(serial_ctl_por(TASK_PORTID,
+							(IOCTL_CRLF | IOCTL_FCSND | IOCTL_FCRCV)));
+
+#ifdef _STORAGEDEVICE_H_
+	/*
+	 *  SD-CARDの設定
+	 */
+	psdev = SDMGetStorageDevice(0);
+	psdev->_sdev_notice = storagedev_notice;
+	SDeviceHead._get_datetime = get_fat_time;
+#endif	/* _STORAGEDEVICE_H_ */
+
+	/* startup defaults (may be overridden by one or more opts) */
+#if LWIP_IPV4
+	IP_ADDR4(&gw,      192,168,  0,1);
+	IP_ADDR4(&netmask, 255,255,255,0);
+	IP_ADDR4(&ipaddr,  192,168,  0,2);
+#if LWIP_HAVE_SLIPIF
+	IP_ADDR4(&gw_slip,      192,168,  2,  1);
+	IP_ADDR4(&netmask_slip, 255,255,255,255);
+	IP_ADDR4(&ipaddr_slip,  192,168,  2,  2);
+#endif
+#endif /* LWIP_IPV4 */
+
+	IP_SET_TYPE_VAL(ping_addr, IPADDR_TYPE_V4);
+	/* use debug flags defined by debug.h */
+	debug_flags = LWIP_DBG_OFF;
+
+	sys_init();
+	sys_thread_new("main_thread", main_thread, NULL, DEFAULT_THREAD_STACKSIZE, DEFAULT_THREAD_PRIO);
+
+	//wolfSSL_Debugging_ON();
+	iothub_client_init();
+
+	esp_at_task(0);
+
+	syslog(LOG_NOTICE, "Sample program ends.");
+	slp_tsk();
+	SVC_PERROR(ext_ker());
+	assert(0);
+}
+
+/* 
+ *  ESP-WROOM-02テストの本体
+ *  シールド上のプッシュスイッチがESP-WROOM-02の
+ *  リセットスイッチです．リセット後、ATコマンドを使って、
+ *  ESP-WROOM-02と通信ができます。
+ *  例えば、AT+GMRは、AT GMR(return)でESP-WROOM-02に送信され
+ *  ESP-WROOM-02からの受信データはコンソールに表示されます．
+ */
+
+static char    aTxBuffer[TX_BUF_SIZE];
+static uint8_t aRxBuffer[RX_BUF_SIZE];
+
+int     rx_mode = MODE_DEFAULT;
+queue_t rx_queue;
+
+/*
+ *  デバイスコマンド番号
+ */
+#define BASE_CMD_LEN     4
+
+static int_t mode_func(int argc, char **argv);
+static int_t count_func(int argc, char **argv);
+static int_t at_func(int argc, char **argv);
+
+/*
+ *  デバイスコマンドテーブル
+ */
+static const COMMAND_INFO at_command_info[] = {
+	{"MODE",	mode_func},
+	{"TCNT",	count_func},
+	{"",		at_func}
+};
+
+#define NUM_DEVICE_CMD   (sizeof(at_command_info)/sizeof(COMMAND_INFO))
+
+static const char at_name[] = "AT";
+static const char at_help[] =
+"  AT      MODE (no) echo mode\n"
+"          TCNT      recived count\n"
+"          any command\n";
+
+static COMMAND_LINK at_command_link = {
+	NULL,
+	NUM_DEVICE_CMD,
+	at_name,
+	NULL,
+	at_help,
+	&at_command_info[0]
+};
+
+static int a2i(char *str)
+{
+	int num = 0;
+
+	while(*str >= '0' && *str <= '9'){
+		num = num * 10 + *str++ - '0';
+	}
+	return num;
+}
+
+/*
+ *  ATコマンド設定関数
+ */
+void at_info_init(intptr_t exinf)
+{
+	setup_command(&at_command_link);
+}
+
+/*
+ *  ECHOモード設定関数
+ */
+static int_t mode_func(int argc, char **argv)
+{
+	int mode = rx_mode;
+
+	if(argc >= 2){
+		mode = a2i(argv[1]);
+		if(mode < 0 || mode > MODE_ECHO_HEX)
+			mode = MODE_DEFAULT;
+		rx_mode = mode;
+	}
+	printf("AT ECHO MODE(%d)\n", mode);
+	return mode;
+}
+
+/*
+ *  受信カウントコマンド取得関数
+ */
+static int_t count_func(int argc, char **argv)
+{
+	printf("AT RECIVED COUNT(%d)(%d)\n", rx_queue.size, rx_queue.clen);
+	return rx_queue.clen;
+}
+
+
+/*
+ *  AT設定コマンド関数
+ */
+static int_t at_func(int argc, char **argv)
+{
+	int  i, arg_count = BASE_CMD_LEN;
+	char *p = aTxBuffer;
+	char *s, c;
+	ER_UINT result;
+	int  caps = 1;
+
+	for(i = 0 ; i < argc ; i++){
+		arg_count++;
+		arg_count += strlen(argv[i]);
+	}
+	*p++ = 'A';
+	*p++ = 'T';
+	if(arg_count > BASE_CMD_LEN){
+		for(i = 0 ; i < argc ; i++){
+			s = argv[i];
+			*p++ = '+';
+			while(*s != 0){
+				c = *s++;
+				if(c == '"')
+					caps ^= 1;
+				if(caps && c >= 'a' && c <= 'z')
+					c -= 0x20;
+				*p++ = c;
+			}
+		}
+	}
+	*p++ = '\r';
+	*p++ = '\n';
+	*p++ = 0;
+	result = serial_wri_dat(AT_PORTID, (const char *)aTxBuffer, arg_count);
+	if(result < 0){
+		syslog_1(LOG_ERROR, "AT command send error(%d) !", result);
+	}
+	printf("%d:%s", arg_count, aTxBuffer);
+	return arg_count;
+}
+
+/*
+ *  SW1割込み
+ */
+void sw_int(void)
+{
+	syslog_0(LOG_NOTICE, "## sw_int() ##");
+}
+
+int esp_at_rx_handler(void *data, int len);
+
+/*
+ *  ATコマンドシリアルタスク
+ */
+void esp_at_task(intptr_t exinf)
+{
+	T_SERIAL_RPOR k_rpor;
+	queue_t *rxque;
+	ER_UINT	ercd;
+	int i, j, len;
+	int dlen = 0;
+	uint8_t ch;
+
+	init_esp_at();
+
+	SVC_PERROR(syslog_msk_log(LOG_UPTO(LOG_INFO), LOG_UPTO(LOG_EMERG)));
+	syslog(LOG_NOTICE, "Sample program starts (exinf = %d).", (int_t) exinf);
+
+	/*
+	 *  シリアルポートの初期化
+	 *
+	 *  システムログタスクと同じシリアルポートを使う場合など，シリアル
+	 *  ポートがオープン済みの場合にはここでE_OBJエラーになるが，支障は
+	 *  ない．
+	 */
+	ercd = serial_opn_por(TASK_PORTID);
+	if (ercd < 0 && MERCD(ercd) != E_OBJ) {
+		syslog(LOG_ERROR, "%s (%d) reported by `serial_opn_por'.",
+									itron_strerror(ercd), SERCD(ercd));
+	}
+	SVC_PERROR(serial_ctl_por(TASK_PORTID,
+							(IOCTL_CRLF | IOCTL_FCSND | IOCTL_FCRCV)));
+
+	/*
+	 * キューバッファの初期化
+	 */
+	rxque = &rx_queue;
+	rxque->size = RX_BUF_SIZE;
+	rxque->clen  = 0;
+	rxque->head = 0;
+	rxque->tail = 0;
+	rxque->pbuffer = aRxBuffer;
+
+	/*
+	 *  ESP-WROOM02用シリアルポートの初期化
+	 */
+	ercd = serial_opn_por(AT_PORTID);
+	if (ercd < 0 && MERCD(ercd) != E_OBJ) {
+		syslog(LOG_ERROR, "%s (%d) reported by `serial_opn_por'.(AT)",
+									itron_strerror(ercd), SERCD(ercd));
+		slp_tsk();
+	}
+	SVC_PERROR(serial_ctl_por(AT_PORTID, 0));
+	while(dlen < 500000){
+		serial_ref_por(AT_PORTID, &k_rpor);
+		len = k_rpor.reacnt;
+		if((rxque->size - rxque->clen) < len)
+			len = rxque->size - rxque->clen;
+		if(len > 0){
+			if(rxque->head >= rxque->tail){
+				if((rxque->size - rxque->head) < len)
+					i = rxque->size - rxque->head;
+				else
+					i = len;
+				j = serial_rea_dat(AT_PORTID, (char *)&rxque->pbuffer[rxque->head], i);
+				rxque->head += j;
+				if(rxque->head >= rxque->size)
+					rxque->head -= rxque->size;
+				rxque->clen += j;
+				len -= j;
+			}
+			if(len > 0){
+				j = serial_rea_dat(AT_PORTID, (char *)&rxque->pbuffer[rxque->head], len);
+				rxque->head += j;
+				if(rxque->head >= rxque->size)
+					rxque->head -= rxque->size;
+				rxque->clen += j;
+				len -= j;
+			}
+		}
+		while(rxque->clen > 0 && rx_mode != MODE_NOECHO){
+			if(rx_mode == MODE_ECHO_CHAR){
+				ch = rxque->pbuffer[rxque->tail];
+				if(ch >= 0x7f)
+					ch = '.';
+				else if(ch < 0x20 && ch != '\r' && ch != '\n')
+					ch = '.';
+				putchar(ch);
+			}
+			else
+				printf("%02x ", rxque->pbuffer[rxque->tail]);
+			rxque->clen--;
+			rxque->tail++;
+			if(rxque->tail >= rxque->size)
+				rxque->tail -= rxque->size;
+			dlen++;
+			if((dlen % 32) == 0 && rx_mode == MODE_ECHO_HEX){
+				printf("\n");
+				dly_tsk(50);
+			}
+		}
+		if (rxque->clen > 0) {
+			len = rxque->clen;
+			if (rxque->tail >= rxque->head) {
+				if ((rxque->size - rxque->tail) < len)
+					i = rxque->size - rxque->tail;
+				else
+					i = len;
+				j = esp_at_rx_handler((char *)&rxque->pbuffer[rxque->tail], i);
+				rxque->tail += j;
+				if(rxque->tail >= rxque->size)
+					rxque->tail -= rxque->size;
+				rxque->clen -= j;
+				len -= j;
+			}
+			if (len > 0) {
+				j = esp_at_rx_handler((char *)&rxque->pbuffer[rxque->tail], len);
+				rxque->tail += j;
+				if(rxque->tail >= rxque->size)
+					rxque->tail -= rxque->size;
+				rxque->clen -= j;
+				len -= j;
+			}
+		}
+		else {
+			dly_tsk(20);
+		}
+	}
+	syslog_0(LOG_NOTICE, "## STOP ##");
+	slp_tsk();
+
+	syslog(LOG_NOTICE, "Sample program ends.");
+//	SVC_PERROR(ext_ker());
+}
Index: azure_iot_hub_f767zi/trunk/app_iothub_client/src/main.cfg
===================================================================
--- azure_iot_hub_f767zi/trunk/app_iothub_client/src/main.cfg	(revision 457)
+++ azure_iot_hub_f767zi/trunk/app_iothub_client/src/main.cfg	(revision 457)
@@ -0,0 +1,40 @@
+/*
+ *  @(#) $Id$
+ */
+
+/*
+ *  LWIPテストプログラムのシステムコンフィギュレーションファイル
+ */
+INCLUDE("target_timer.cfg");
+INCLUDE("syssvc/syslog.cfg");
+INCLUDE("syssvc/banner.cfg");
+INCLUDE("syssvc/serial.cfg");
+INCLUDE("syssvc/logtask.cfg");
+INCLUDE("pdic/stm32f7xx/device.cfg");
+INCLUDE("pdic/stm32f7xx/sdmmc.cfg");
+INCLUDE("files/storagedevice.cfg");
+INCLUDE("files/ff/fatfs.cfg");
+INCLUDE("monitor/monitor.cfg");
+//INCLUDE("syssvc/tlsf.cfg");
+INCLUDE("lwip/lwip.cfg");
+INCLUDE("pinkit.cfg");
+
+#include "itron.h"
+#include "device.h"
+/* #include "sdmmc.h" */
+#include "emac.h"
+#include "main.h"
+
+ATT_INI({ TA_NULL, sw_int, setup_sw_func });
+ATT_INI({ TA_NULL, heap_param, heap_init });
+ATT_INI({ TA_NULL, 0, device_info_init });
+ATT_INI({ TA_NULL, 0, at_info_init });
+
+CRE_DTQ(DTQ_ESP_AT, { TA_NULL, NUM_ESP_AT, NULL });
+
+CRE_TSK(MAIN_TASK1, { TA_ACT, 1, main_task, MAIN_PRIORITY, STACK_SIZE, NULL });
+CRE_FLG(FLG_GMAC, {(TA_TFIFO|TA_WSGL), 0});
+CRE_SEM(SEM_GMAC_MDIO, { TA_TPRI, 1, 1 });
+
+ATT_ISR({ TA_NULL,  EMAC_PORTID, INTNO_EMAC, emac_hps_isr, 1 });
+CFG_INT(INTNO_EMAC, { TA_NULL | INTATR_EMAC, INTPRI_EMAC });
Index: azure_iot_hub_f767zi/trunk/app_iothub_client/src/main.h
===================================================================
--- azure_iot_hub_f767zi/trunk/app_iothub_client/src/main.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/app_iothub_client/src/main.h	(revision 457)
@@ -0,0 +1,122 @@
+/*
+ *  TOPPERS/ASP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Advanced Standard Profile Kernel
+ *
+ *  Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
+ *                              Toyohashi Univ. of Technology, JAPAN
+ *  Copyright (C) 2004-2010 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ *
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ *
+ *  $Id$
+ */
+
+/*
+ *	ESP-WROOM-02テストのヘッダファイル
+ */
+
+/*
+ *  ターゲット依存の定義
+ */
+#include "target_test.h"
+
+/*
+ *  各タスクの優先度の定義
+ */
+
+#define MAIN_PRIORITY	8		/* メインタスクの優先度 */
+								/* HIGH_PRIORITYより高くすること */
+
+/*
+ *  ターゲットに依存する可能性のある定数の定義
+ */
+
+#ifndef TASK_PORTID
+#define	TASK_PORTID		1			/* 文字入力するシリアルポートID */
+#endif /* TASK_PORTID */
+#define AT_PORTID       2
+
+#ifndef STACK_SIZE
+#define	STACK_SIZE		2048		/* タスクのスタックサイズ */
+#endif /* STACK_SIZE */
+
+#ifndef LOOP_REF
+#define LOOP_REF		ULONG_C(1000000)	/* 速度計測用のループ回数 */
+#endif /* LOOP_REF */
+
+#define INHNO_EMAC    IRQ_VECTOR_ETH	/* 割込みハンドラ番号 */
+#define INTNO_EMAC    IRQ_VECTOR_ETH	/* 割込み番号 */
+#define INTPRI_EMAC   -5			/* 割込み優先度 */
+#define INTATR_EMAC   0				/* 割込み属性 */
+#define EMAC_PORTID   MAC1_PORTID
+
+/*
+ *  シリアル設定情報
+ */
+#define TX_BUF_SIZE     256
+#define RX_BUF_SIZE     1024
+
+#define MODE_NOECHO     0
+#define MODE_ECHO_CHAR  1
+#define MODE_ECHO_HEX   2
+#define MODE_DEFAULT    MODE_NOECHO
+
+#define NUM_ESP_AT      4
+
+#ifndef TOPPERS_MACRO_ONLY
+
+/*
+ *  ヒープ領域の設定
+ */
+extern intptr_t heap_param[2];
+
+typedef struct queue_s {
+	uint16_t size;
+	int16_t  clen;
+	uint16_t head;
+	uint16_t tail;
+	uint8_t  *pbuffer;
+} queue_t;
+
+/*
+ *  関数のプロトタイプ宣言
+ */
+extern void	main_task(intptr_t exinf);
+
+extern void heap_init(intptr_t exinf);
+extern void sw_int(void);
+extern void device_info_init(intptr_t exinf);
+extern int8_t get_cup_command(void);
+extern void at_info_init(intptr_t exinf);
+
+
+#endif /* TOPPERS_MACRO_ONLY */
Index: azure_iot_hub_f767zi/trunk/app_iothub_client/src/stub.c
===================================================================
--- azure_iot_hub_f767zi/trunk/app_iothub_client/src/stub.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/app_iothub_client/src/stub.c	(revision 457)
@@ -0,0 +1,96 @@
+#include <stdint.h>
+#include <stdlib.h>
+#include <ctype.h>
+#include <errno.h>
+#include <sys/time.h>
+#include <kernel.h>
+#include <t_syslog.h>
+#include <t_stdlib.h>
+#include "main.h"
+#include "kernel_cfg.h"
+#include "esp_at_socket.h"
+
+void __wrap_exit(int status)
+{
+	ext_ker();
+}
+
+int _kill(int pid, int sig)
+{
+	return 0;
+}
+
+int _getpid(int n)
+{
+	return 1;
+}
+
+int custom_rand_generate_seed(uint8_t *output, uint32_t sz)
+{
+	SYSTIM now;
+	int32_t i;
+
+	get_tim(&now);
+	srand(now);
+
+	for (i = 0; i < sz; i++)
+		output[i] = rand();
+
+	return 0;
+}
+
+// musl-libc
+
+int inet_aton(const char *s0, struct in_addr *dest)
+{
+	const char *s = s0;
+	unsigned char *d = (unsigned char *)dest;
+	unsigned long a[4] = { 0 };
+	char *z;
+	int i;
+
+	for (i = 0; i < 4; i++) {
+		a[i] = strtoul(s, &z, 0);
+		if (z == s || (*z && *z != '.') || !isdigit(*s))
+			return 0;
+		if (!*z) break;
+		s = z + 1;
+	}
+	if (i == 4) return 0;
+	switch (i) {
+	case 0:
+		a[1] = a[0] & 0xffffff;
+		a[0] >>= 24;
+	case 1:
+		a[2] = a[1] & 0xffff;
+		a[1] >>= 16;
+	case 2:
+		a[3] = a[2] & 0xff;
+		a[2] >>= 8;
+	}
+	for (i = 0; i < 4; i++) {
+		if (a[i] > 255) return 0;
+		d[i] = a[i];
+	}
+	return 1;
+}
+
+struct ether_addr *ether_aton_r(const char *x, struct ether_addr *p_a)
+{
+	struct ether_addr a;
+	char *y;
+	for (int ii = 0; ii < 6; ii++) {
+		unsigned long int n;
+		if (ii != 0) {
+			if (x[0] != ':') return 0; /* bad format */
+			else x++;
+		}
+		n = strtoul(x, &y, 16);
+		x = y;
+		if (n > 0xFF) return 0; /* bad byte */
+		a.ether_addr_octet[ii] = n;
+	}
+	if (x[0] != 0) return 0; /* bad format */
+	*p_a = a;
+	return p_a;
+}
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/.vscode/c_cpp_properties.json
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/.vscode/c_cpp_properties.json	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/.vscode/c_cpp_properties.json	(revision 457)
@@ -0,0 +1,31 @@
+{
+    "configurations": [
+        {
+            "name": "STM32F767 NUCLEO-144",
+            "includePath": [
+                "${workspaceFolder}/../asp_baseplatform",
+                "${workspaceFolder}/../asp_baseplatform/arch/arm_m_gcc/common",
+                "${workspaceFolder}/../asp_baseplatform/arch/arm_m_gcc/stm32f7xx",
+                "${workspaceFolder}/../asp_baseplatform/arch/gcc",
+                "${workspaceFolder}/../asp_baseplatform/include",
+                "${workspaceFolder}/../asp_baseplatform/target/stm32f767nucleo144_gcc",
+                "${workspaceFolder}/../asp_baseplatform/lwip",
+                "${workspaceFolder}/../asp_baseplatform/lwip/lwip-2.1.2/src/include",
+                "${workspaceFolder}/../asp_baseplatform/lwip/contrib-2.1.0/ports/toppers/include",
+                "${workspaceFolder}/../asp_baseplatform/lwip/contrib-2.1.0/ports",
+                "${workspaceFolder}/../asp_baseplatform/sample"
+            ],
+            "defines": [
+                "USE_ARM_FPU",
+                "TOPPERS_EXECUTE_ON_ROM",
+                "TARGET_KERNEL_ASP"
+            ],
+            "windowsSdkVersion": "10.0.17763.0",
+            "compilerPath": "C:\\Program Files (x86)\\GNU Tools ARM Embedded\\9 2019-q4-major\\bin\\arm-none-eabi-gcc.exe",
+            "cStandard": "c11",
+            "cppStandard": "c++17",
+            "intelliSenseMode": "gcc-x64"
+        }
+    ],
+    "version": 4
+}
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/.vscode/launch.json
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/.vscode/launch.json	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/.vscode/launch.json	(revision 457)
@@ -0,0 +1,23 @@
+{
+    "version": "0.2.0",
+    "configurations": [
+        {
+            "name": "Cortex Debug",
+            "armToolchainPath": "C:\\Program Files (x86)\\GNU Tools ARM Embedded\\9 2019-q4-major\\bin",
+            "serverpath": "C:\\Program Files\\GNU MCU Eclipse\\OpenOCD\\0.10.0-12-20190422-2015\\bin\\openocd.exe",
+            "cwd": "${workspaceFolder}\\OBJ\\STM32F767NUCLEO144_GCC\\MAC",
+            "executable": "${workspaceFolder}\\OBJ\\STM32F767NUCLEO144_GCC\\MAC\\asp.exe",
+            "request": "launch",
+            "type": "cortex-debug",
+            "servertype": "openocd",
+            "configFiles": [
+                "interface/stlink-v2-1.cfg",
+                "target/stm32f7x.cfg"
+            ],
+            "openOCDLaunchCommands": [
+                "gdb_memory_map disable"
+            ],
+            "preLaunchTask": "build asp_baseplatform"
+        }
+    ]
+}
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/.vscode/settings.json
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/.vscode/settings.json	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/.vscode/settings.json	(revision 457)
@@ -0,0 +1,17 @@
+// Place your settings in this file to overwrite default and user settings.
+{
+    "terminal.integrated.setLocaleVariables": true,
+    "terminal.integrated.shell.windows": "C:\\msys64\\usr\\bin\\bash.exe",
+    "terminal.integrated.shellArgs.windows": [
+        "--login",
+        "-i"
+    ],
+    "terminal.integrated.env.windows": {
+        "PATH": "C:\\Program Files (x86)\\GNU Tools ARM Embedded\\9 2019-q4-major\\bin",
+        "CHERE_INVOKING": "1",
+        "MSYS2_PATH_TYPE": "inherit",
+        "MSYSTEM": "MINGW64"
+    },
+    "C_Cpp.intelliSenseEngine": "Tag Parser",
+    "C_Cpp.default.intelliSenseMode": "gcc-x64"
+}
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/.vscode/tasks.json
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/.vscode/tasks.json	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/.vscode/tasks.json	(revision 457)
@@ -0,0 +1,72 @@
+{
+    // See https://go.microsoft.com/fwlink/?LinkId=733558
+    // for the documentation about the tasks.json format
+    "version": "2.0.0",
+    "name": "make",
+    "type": "shell",
+    "problemMatcher": {
+        "owner": "cpp",
+        "fileLocation": [
+            "relative",
+            "${workspaceFolder}/Debug"
+        ],
+        "pattern": {
+            "regexp": "^(.*):(\\d+):(\\d+):\\s+(warning|error|fatal error):\\s+(.*)$",
+            "file": 1,
+            "line": 2,
+            "column": 3,
+            "severity": 4,
+            "message": 5
+        }
+    },
+    "tasks": [
+        {
+            "label": "build asp_baseplatform",
+            "args": [
+                "all"
+            ],
+            "linux": {
+                "command": "make"
+            },
+            "osx": {
+                "command": "make"
+            },
+            "windows": {
+                "command": "make.exe"
+            },
+            "group": "build"
+        },
+        {
+            "label": "clean asp_baseplatform",
+            "args": [
+                "clean"
+            ],
+            "linux": {
+                "command": "make"
+            },
+            "osx": {
+                "command": "make"
+            },
+            "windows": {
+                "command": "make.exe"
+            },
+            "group": "build"
+        },
+        {
+            "label": "realclean asp_baseplatform",
+            "args": [
+                "realclean"
+            ],
+            "linux": {
+                "command": "make"
+            },
+            "osx": {
+                "command": "make"
+            },
+            "windows": {
+                "command": "make.exe"
+            },
+            "group": "build"
+        }
+    ]
+}
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/MANIFEST
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/MANIFEST	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/MANIFEST	(revision 457)
@@ -0,0 +1,112 @@
+PACKAGE asp
+VERSION 1.9.3
+
+configure
+MANIFEST
+README.txt
+
+doc/asp_spec.txt
+doc/configurator.txt
+doc/design.txt
+doc/extension.txt
+doc/porting.txt
+doc/user.txt
+doc/version.txt
+
+include/histogram.h
+include/itron.h
+include/kernel.h
+include/log_output.h
+include/queue.h
+include/sil.h
+include/t_stddef.h
+include/t_stdlib.h
+include/t_syslog.h
+include/test_lib.h
+
+kernel/Makefile.kernel
+kernel/alarm.c
+kernel/alarm.h
+kernel/allfunc.h
+kernel/check.h
+kernel/cyclic.c
+kernel/cyclic.h
+kernel/dataqueue.c
+kernel/dataqueue.h
+kernel/eventflag.c
+kernel/eventflag.h
+kernel/exception.c
+kernel/exception.h
+kernel/genoffset.tf
+kernel/interrupt.c
+kernel/interrupt.h
+kernel/kernel.tf
+kernel/kernel_api.csv
+kernel/kernel_check.tf
+kernel/kernel_def.csv
+kernel/kernel_impl.h
+kernel/kernel_int.h
+kernel/kernel_rename.def
+kernel/kernel_rename.h
+kernel/kernel_unrename.h
+kernel/mailbox.c
+kernel/mailbox.h
+kernel/mempfix.c
+kernel/mempfix.h
+kernel/pridataq.c
+kernel/pridataq.h
+kernel/semaphore.c
+kernel/semaphore.h
+kernel/startup.c
+kernel/sys_manage.c
+kernel/task.c
+kernel/task.h
+kernel/task_except.c
+kernel/task_manage.c
+kernel/task_refer.c
+kernel/task_sync.c
+kernel/time_event.c
+kernel/time_event.h
+kernel/time_manage.c
+kernel/wait.c
+kernel/wait.h
+
+library/histogram.c
+library/log_output.c
+library/strerror.c
+library/t_perror.c
+library/test_lib.c
+library/vasyslog.c
+
+sample/Makefile
+sample/sample1.c
+sample/sample1.cfg
+sample/sample1.h
+
+syssvc/banner.c
+syssvc/banner.cfg
+syssvc/banner.h
+syssvc/logtask.c
+syssvc/logtask.cfg
+syssvc/logtask.h
+syssvc/serial.c
+syssvc/serial.cfg
+syssvc/serial.h
+syssvc/syslog.c
+syssvc/syslog.cfg
+syssvc/syslog.h
+
+utils/applyrename
+utils/genoffset
+utils/genrename
+utils/gentest
+utils/makedep
+utils/makerelease
+
+INCLUDE target/dve68k_gcc/MANIFEST
+INCLUDE arch/m68k_gcc/MANIFEST
+INCLUDE arch/gcc/MANIFEST
+INCLUDE arch/logtrace/MANIFEST
+INCLUDE pdic/upd72001/MANIFEST
+INCLUDE test/MANIFEST
+INCLUDE extension/MANIFEST
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/Makefile
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/Makefile	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/Makefile	(revision 457)
@@ -0,0 +1,14 @@
+
+MAKE = make
+
+.PHONY: all
+all:
+	$(MAKE) -j 1 -C OBJ/STM32F767NUCLEO144_GCC/MAC all
+
+.PHONY: clean
+clean:
+	$(MAKE) -j 1 -C OBJ/STM32F767NUCLEO144_GCC/MAC clean
+
+.PHONY: realclean
+realclean:
+	$(MAKE) -j 1 -C OBJ/STM32F767NUCLEO144_GCC/MAC realclean
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/OBJ/STM32F767NUCLEO144_GCC/LCD/Makefile
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/OBJ/STM32F767NUCLEO144_GCC/LCD/Makefile	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/OBJ/STM32F767NUCLEO144_GCC/LCD/Makefile	(revision 457)
@@ -0,0 +1,612 @@
+#
+#  TOPPERS/ASP Kernel
+#      Toyohashi Open Platform for Embedded Real-Time Systems/
+#      Advanced Standard Profile Kernel
+# 
+#  Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
+#                              Toyohashi Univ. of Technology, JAPAN
+#  Copyright (C) 2006-2014 by Embedded and Real-Time Systems Laboratory
+#              Graduate School of Information Science, Nagoya Univ., JAPAN
+# 
+#  ä¸è¨èä½æ¨©è
+ã¯ï¼ä»¥ä¸ã®(1)ï½(4)ã®æ¡ä»¶ãæºããå ´åã«éãï¼æ¬ã½ããã¦ã§
+#  ã¢ï¼æ¬ã½ããã¦ã§ã¢ãæ¹å¤ãããã®ãå«ãï¼ä»¥ä¸åãï¼ãä½¿ç¨ã»è¤è£½ã»æ¹
+#  å¤ã»åé
+å¸ï¼ä»¥ä¸ï¼å©ç¨ã¨å¼ã¶ï¼ãããã¨ãç¡åã§è¨±è«¾ããï¼
+#  (1) æ¬ã½ããã¦ã§ã¢ãã½ã¼ã¹ã³ã¼ãã®å½¢ã§å©ç¨ããå ´åã«ã¯ï¼ä¸è¨ã®èä½
+#      æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨ã®ç¡ä¿è¨¼è¦å®ãï¼ãã®ã¾ã¾ã®å½¢ã§ã½ã¼
+#      ã¹ã³ã¼ãä¸­ã«å«ã¾ãã¦ãããã¨ï¼
+#  (2) æ¬ã½ããã¦ã§ã¢ãï¼ã©ã¤ãã©ãªå½¢å¼ãªã©ï¼ä»ã®ã½ããã¦ã§ã¢éçºã«ä½¿
+#      ç¨ã§ããå½¢ã§åé
+å¸ããå ´åã«ã¯ï¼åé
+å¸ã«ä¼´ããã­ã¥ã¡ã³ãï¼å©ç¨
+#      è
+ããã¥ã¢ã«ãªã©ï¼ã«ï¼ä¸è¨ã®èä½æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨
+#      ã®ç¡ä¿è¨¼è¦å®ãæ²è¼ãããã¨ï¼
+#  (3) æ¬ã½ããã¦ã§ã¢ãï¼æ©å¨ã«çµã¿è¾¼ããªã©ï¼ä»ã®ã½ããã¦ã§ã¢éçºã«ä½¿
+#      ç¨ã§ããªãå½¢ã§åé
+å¸ããå ´åã«ã¯ï¼æ¬¡ã®ããããã®æ¡ä»¶ãæºããã
+#      ã¨ï¼
+#    (a) åé
+å¸ã«ä¼´ããã­ã¥ã¡ã³ãï¼å©ç¨è
+ããã¥ã¢ã«ãªã©ï¼ã«ï¼ä¸è¨ã®è
+#        ä½æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨ã®ç¡ä¿è¨¼è¦å®ãæ²è¼ãããã¨ï¼
+#    (b) åé
+å¸ã®å½¢æ
+ãï¼å¥ã«å®ããæ¹æ³ã«ãã£ã¦ï¼TOPPERSãã­ã¸ã§ã¯ãã«
+#        å ±åãããã¨ï¼
+#  (4) æ¬ã½ããã¦ã§ã¢ã®å©ç¨ã«ããç´æ¥çã¾ãã¯éæ¥çã«çãããããªãæ
+#      å®³ãããï¼ä¸è¨èä½æ¨©è
+ããã³TOPPERSãã­ã¸ã§ã¯ããå
+è²¬ãããã¨ï¼
+#      ã¾ãï¼æ¬ã½ããã¦ã§ã¢ã®ã¦ã¼ã¶ã¾ãã¯ã¨ã³ãã¦ã¼ã¶ããã®ãããªãç
+#      ç±ã«åºã¥ãè«æ±ãããï¼ä¸è¨èä½æ¨©è
+ããã³TOPPERSãã­ã¸ã§ã¯ãã
+#      å
+è²¬ãããã¨ï¼
+# 
+#  æ¬ã½ããã¦ã§ã¢ã¯ï¼ç¡ä¿è¨¼ã§æä¾ããã¦ãããã®ã§ããï¼ä¸è¨èä½æ¨©è
+ã
+#  ãã³TOPPERSãã­ã¸ã§ã¯ãã¯ï¼æ¬ã½ããã¦ã§ã¢ã«é¢ãã¦ï¼ç¹å®ã®ä½¿ç¨ç®ç
+#  ã«å¯¾ããé©åæ§ãå«ãã¦ï¼ãããªãä¿è¨¼ãè¡ããªãï¼ã¾ãï¼æ¬ã½ããã¦ã§
+#  ã¢ã®å©ç¨ã«ããç´æ¥çã¾ãã¯éæ¥çã«çãããããªãæå®³ã«é¢ãã¦ãï¼ã
+#  ã®è²¬ä»»ãè² ããªãï¼
+# 
+#  $Id$
+# 
+
+#
+#  ã¿ã¼ã²ããã®æå®ï¼Makefile.targetã§ä¸æ¸ããããã®ãé²ãããï¼
+#
+all:
+
+#
+#  ã¿ã¼ã²ããç¥ç§°ã®å®ç¾©
+#
+TARGET = stm32f767nucleo144_gcc
+
+#
+#  ãã­ã°ã©ãã³ã°è¨èªã®å®ç¾©
+#
+SRCLANG = c
+ifeq ($(SRCLANG),c)
+  LIBS = -lc
+endif
+ifeq ($(SRCLANG),c++)
+  USE_CXX = true
+  CXXLIBS = -lstdc++ -lm -lc
+  CXXRTS = cxxrt.o newlibrt.o
+endif
+
+#
+#  ã½ã¼ã¹ãã¡ã¤ã«ã®ãã£ã¬ã¯ããªã®å®ç¾©
+#
+SRCDIR = ../../..
+
+#
+#  ãªãã¸ã§ã¯ããã¡ã¤ã«åã®æ¡å¼µå­ã®è¨­å®
+#
+OBJEXT = exe
+
+#
+#  å®è¡ç°å¢ã®å®ç¾©ï¼ã¿ã¼ã²ããä¾å­ã«ä¸æ¸ããããå ´åãããï¼
+#
+DBGENV := 
+
+#
+#  ã«ã¼ãã«ã©ã¤ãã©ãªï¼libkernel.aï¼ã®ãã£ã¬ã¯ããªå
+#  ï¼ã«ã¼ãã«ã©ã¤ãã©ãªãmakeå¯¾è±¡ã«ããæã¯ï¼ç©ºã«å®ç¾©ããï¼
+#
+KERNEL_LIB = ../libkernel
+
+#
+#  ã«ã¼ãã«ãé¢æ°åä½ã§ã³ã³ãã¤ã«ãããã©ããã®å®ç¾©
+#
+KERNEL_FUNCOBJS = 
+
+#
+#  ãã¬ã¼ã¹ã­ã°ãåå¾ãããã©ããã®å®ç¾©
+#
+ENABLE_TRACE = 
+
+#
+#   USB OTGã®ã¢ã¼ãå®ç¾©
+#
+USB_OTG_MODE = USB_OTG_MODE_HOST
+
+#
+#  ã¦ã¼ãã£ãªãã£ãã­ã°ã©ã ã®åç§°
+#
+PERL = /usr/bin/perl
+CFG = $(SRCDIR)/cfg/cfg/cfg
+
+#
+#  ãªãã¸ã§ã¯ããã¡ã¤ã«åã®å®ç¾©
+#
+OBJNAME = asp
+ifdef OBJEXT
+  OBJFILE = $(OBJNAME).$(OBJEXT)
+  CFG1_OUT = cfg1_out.$(OBJEXT)
+else
+  OBJFILE = $(OBJNAME)
+  CFG1_OUT = cfg1_out
+endif
+
+#
+#  ã¿ã¼ã²ããä¾å­é¨ã®ãã£ã¬ã¯ããªã®å®ç¾©
+#
+TARGETDIR = $(SRCDIR)/target/$(TARGET)
+
+#
+#  ã¿ã¼ã²ããä¾å­ã®å®ç¾©ã®ã¤ã³ã¯ã«ã¼ã
+#
+include $(TARGETDIR)/Makefile.target
+
+#
+#  ã³ã³ãã£ã®ã¥ã¬ã¼ã¿é¢ä¿ã®å¤æ°ã®å®ç¾©
+#
+CFG_TABS := --api-table $(SRCDIR)/kernel/kernel_api.csv \
+			--cfg1-def-table $(SRCDIR)/kernel/kernel_def.csv $(CFG_TABS)
+
+CFG_ASMOBJS := $(CFG_ASMOBJS)
+CFG_COBJS := kernel_cfg.o $(CFG_COBJS)
+CFG_OBJS := $(CFG_ASMOBJS) $(CFG_COBJS)
+CFG2_OUT_SRCS := kernel_cfg.h kernel_cfg.c $(CFG2_OUT_SRCS)
+
+#
+#  å
+±éã³ã³ãã¤ã«ãªãã·ã§ã³ã®å®ç¾©
+#
+COPTS := $(COPTS) -g 
+ifndef OMIT_WARNING_ALL
+  COPTS := $(COPTS) -Wall
+endif
+ifndef OMIT_OPTIMIZATION
+  COPTS := $(COPTS) -O2
+endif
+CDEFS := $(CDEFS) 
+INCLUDES := -I. -I$(SRCDIR)/include -I$(SRCDIR)/arch -I$(SRCDIR) $(INCLUDES)
+LDFLAGS := $(LDFLAGS) 
+CFG1_OUT_LDFLAGS := $(CFG1_OUT_LDFLAGS) 
+LIBS := $(LIBS) $(CXXLIBS)
+CFLAGS = $(COPTS) $(CDEFS) $(INCLUDES)
+
+#
+#  ã¢ããªã±ã¼ã·ã§ã³ãã­ã°ã©ã ã«é¢ããå®ç¾©
+#
+APPLNAME = lcdshield
+APPLDIR = 
+APPL_CFG = $(APPLNAME).cfg
+
+APPL_DIR = $(APPLDIR) $(SRCDIR)/library
+APPL_ASMOBJS =
+ifdef USE_CXX
+  APPL_CXXOBJS = $(APPLNAME).o 
+  APPL_COBJS = command.o 
+else
+  APPL_COBJS = $(APPLNAME).o command.o 
+endif
+APPL_COBJS := $(APPL_COBJS) log_output.o vasyslog.o t_perror.o strerror.o
+APPL_CFLAGS =
+APPL_LIBS =
+ifdef APPLDIR
+  INCLUDES := $(INCLUDES) $(foreach dir,$(APPLDIR),-I$(dir))
+endif
+
+#
+#  ããã«ã¦ã§ã¢ Makefile ã®ã¤ã³ã¯ã«ã¼ã
+#
+include $(SRCDIR)/monitor/Makefile.config
+include $(SRCDIR)/usb/Makefile.config
+include $(SRCDIR)/ui/stfont_disp/Makefile.config
+
+#
+#   USB CLASSã®è¿½å 
+#
+SYSSVC_COBJS := $(SYSSVC_COBJS) tusbh_msc.o
+
+#
+#  GDIC Makefile ã®ã¤ã³ã¯ã«ã¼ã
+#
+include $(SRCDIR)/gdic/usb_otg/Makefile.config
+include $(SRCDIR)/gdic/adafruit_st7735/Makefile.config
+
+#
+#  ã·ã¹ãã ãµã¼ãã¹ã«é¢ããå®ç¾©
+#
+SYSSVC_DIR := $(SYSSVC_DIR) $(SRCDIR)/syssvc $(SRCDIR)/library $(SRCDIR)/pdic/stm32f7xx
+SYSSVC_ASMOBJS := $(SYSSVC_ASMOBJS)
+SYSSVC_COBJS := $(SYSSVC_COBJS) banner.o syslog.o serial.o logtask.o armv7m.o \
+				 device.o spi.o adc.o pinmode.o usb_otg.o clock.o malloc.o tlsf.o $(CXXRTS)
+SYSSVC_CFLAGS := $(SYSSVC_CFLAGS)
+SYSSVC_LIBS := $(SYSSVC_LIBS)
+INCLUDES := $(INCLUDES) -I$(SRCDIR)/pdic/stm32f7xx
+
+#
+#  ã«ã¼ãã«ã«é¢ããå®ç¾©
+#
+#  KERNEL_ASMOBJS: ã«ã¼ãã«ã©ã¤ãã©ãªã«å«ããï¼ã½ã¼ã¹ãã¢ã»ã³ããªè¨èªã®
+#				   ãªãã¸ã§ã¯ããã¡ã¤ã«ï¼
+#  KERNEL_COBJS: ã«ã¼ãã«ã®ã©ã¤ãã©ãªã«å«ããï¼ã½ã¼ã¹ãCè¨èªã§ï¼ã½ã¼ã¹
+#				 ãã¡ã¤ã«ã¨1å¯¾1ã«å¯¾å¿ãããªãã¸ã§ã¯ããã¡ã¤ã«ï¼
+#  KERNEL_LCSRCS: ã«ã¼ãã«ã®ã©ã¤ãã©ãªã«å«ããCè¨èªã®ã½ã¼ã¹ãã¡ã¤ã«ã§ï¼
+#				  1ã¤ã®ã½ã¼ã¹ãã¡ã¤ã«ããè¤æ°ã®ãªãã¸ã§ã¯ããã¡ã¤ã«ãç
+#				  æãããã®ï¼
+#  KERNEL_LCOBJS: ä¸ã®ã½ã¼ã¹ãã¡ã¤ã«ããçæããããªãã¸ã§ã¯ããã¡ã¤ã«ï¼
+#  KERNEL_AUX_COBJS: ã­ã¼ãã¢ã¸ã¥ã¼ã«ã«å«ããªããï¼ã«ã¼ãã«ã®ã½ã¼ã¹ãã¡
+#					 ã¤ã«ã¨åããªãã·ã§ã³ãé©ç¨ãã¦ã³ã³ãã¤ã«ãã¹ãï¼ã½ã¼
+#					 ã¹ãCè¨èªã®ãªãã¸ã§ã¯ããã¡ã¤ã«ï¼
+#
+KERNEL_DIR := $(KERNEL_DIR) $(SRCDIR)/kernel
+KERNEL_ASMOBJS := $(KERNEL_ASMOBJS)
+KERNEL_COBJS := $(KERNEL_COBJS)
+KERNEL_CFLAGS := $(KERNEL_CFLAGS) -I$(SRCDIR)/kernel
+ifdef OMIT_MAKEOFFSET
+  OFFSET_H =
+else
+  OFFSET_H = offset.h
+ifndef OFFSET_TF
+  KERNEL_AUX_COBJS := $(KERNEL_AUX_COBJS) makeoffset.o
+endif
+endif
+
+#
+#  ã¿ã¼ã²ãããã¡ã¤ã«ï¼è¤æ°ãåæã«é¸æãã¦ã¯ãªããªãï¼
+#
+#all: $(OBJFILE)
+all: $(OBJNAME).bin
+#all: $(OBJNAME).srec
+
+##### ä»¥ä¸ã¯ç·¨éããªããã¨ #####
+
+#
+#  ç°å¢ã«ä¾å­ããã³ã³ãã¤ã«ãªãã·ã§ã³ã®å®ç¾©
+#
+ifdef DBGENV
+  CDEFS := $(CDEFS) -D$(DBGENV)
+endif
+
+#
+#  ã«ã¼ãã«ã®ãã¡ã¤ã«æ§æã®å®ç¾©
+#
+include $(SRCDIR)/kernel/Makefile.kernel
+ifdef KERNEL_FUNCOBJS
+  KERNEL_LCSRCS := $(KERNEL_FCSRCS)
+  KERNEL_LCOBJS := $(foreach file,$(KERNEL_FCSRCS),$($(file:.c=)))
+else
+  KERNEL_CFLAGS := -DALLFUNC $(KERNEL_CFLAGS)
+  KERNEL_COBJS := $(KERNEL_COBJS) \
+					$(foreach file,$(KERNEL_FCSRCS),$(file:.c=.o))
+endif
+
+#
+#  ã½ã¼ã¹ãã¡ã¤ã«ã®ãããã£ã¬ã¯ããªã«é¢ããå®ç¾©
+#
+vpath %.c $(KERNEL_DIR) $(SYSSVC_DIR) $(APPL_DIR)
+vpath %.S $(KERNEL_DIR) $(SYSSVC_DIR) $(APPL_DIR)
+vpath %.cfg $(APPL_DIR)
+
+#
+#  ã³ã³ãã¤ã«ã®ããã®å¤æ°ã®å®ç¾©
+#
+KERNEL_LIB_OBJS = $(KERNEL_ASMOBJS) $(KERNEL_COBJS) $(KERNEL_LCOBJS)
+SYSSVC_OBJS = $(SYSSVC_ASMOBJS) $(SYSSVC_COBJS)
+APPL_OBJS = $(APPL_ASMOBJS) $(APPL_COBJS) $(APPL_CXXOBJS)
+ALL_OBJS = $(START_OBJS) $(APPL_OBJS) $(SYSSVC_OBJS) $(CFG_OBJS) \
+											$(END_OBJS) $(HIDDEN_OBJS)
+ifdef KERNEL_LIB
+  ALL_LIBS = $(APPL_LIBS) $(SYSSVC_LIBS) -lkernel $(LIBS)
+  LIBS_DEP = $(filter %.a,$(ALL_LIBS)) $(KERNEL_LIB)/libkernel.a
+  LDFLAGS := $(LDFLAGS) -L$(KERNEL_LIB)
+  REALCLEAN_FILES := libkernel.a $(REALCLEAN_FILES)
+else
+  ALL_LIBS = $(APPL_LIBS) $(SYSSVC_LIBS) libkernel.a $(LIBS)
+  LIBS_DEP = $(filter %.a,$(ALL_LIBS))
+endif
+
+ifdef TEXT_START_ADDRESS
+  LDFLAGS := $(LDFLAGS) -Wl,-Ttext,$(TEXT_START_ADDRESS)
+  CFG1_OUT_LDFLAGS := $(CFG1_OUT_LDFLAGS) -Wl,-Ttext,$(TEXT_START_ADDRESS)
+endif
+ifdef DATA_START_ADDRESS
+  LDFLAGS := $(LDFLAGS) -Wl,-Tdata,$(DATA_START_ADDRESS)
+  CFG1_OUT_LDFLAGS := $(CFG1_OUT_LDFLAGS) -Wl,-Tdata,$(DATA_START_ADDRESS)
+endif
+ifdef LDSCRIPT
+  LDFLAGS := $(LDFLAGS) -T $(LDSCRIPT)
+  CFG1_OUT_LDFLAGS := $(CFG1_OUT_LDFLAGS) -T $(LDSCRIPT)
+endif
+
+#
+#  ãªãã»ãããã¡ã¤ã«ï¼offset.hï¼ã®çæè¦å
+#
+ifdef OFFSET_TF
+offset.h: $(APPL_CFG) kernel_cfg.timestamp
+	$(CFG) --pass 3 --kernel asp $(INCLUDES) \
+				--rom-image cfg1_out.srec --symbol-table cfg1_out.syms \
+				-T $(OFFSET_TF) $(CFG_TABS) $<
+else
+offset.h: makeoffset.s $(SRCDIR)/utils/genoffset
+	$(PERL) $(SRCDIR)/utils/genoffset makeoffset.s > offset.h
+endif
+
+#
+#  ã«ã¼ãã«ã®ã³ã³ãã£ã®ã¥ã¬ã¼ã·ã§ã³ãã¡ã¤ã«ã®çæ
+#
+cfg1_out.c: $(APPL_CFG)
+	$(CFG) --pass 1 --kernel asp $(INCLUDES) $(CFG_TABS) $<
+
+$(CFG2_OUT_SRCS): kernel_cfg.timestamp
+kernel_cfg.timestamp: $(APPL_CFG) \
+						$(START_OBJS) cfg1_out.o $(END_OBJS) $(HIDDEN_OBJS)
+	$(LINK) $(CFLAGS) $(CFG1_OUT_LDFLAGS) -o $(CFG1_OUT) \
+						$(START_OBJS) cfg1_out.o $(END_OBJS)
+	$(NM) -n $(CFG1_OUT) > cfg1_out.syms
+	$(OBJCOPY) -O srec -S $(CFG1_OUT) cfg1_out.srec
+	$(CFG) --pass 2 --kernel asp $(INCLUDES) \
+				-T $(TARGETDIR)/target.tf $(CFG_TABS) $<
+	touch -r kernel_cfg.c kernel_cfg.timestamp
+
+#
+#  ã«ã¼ãã«ã©ã¤ãã©ãªãã¡ã¤ã«ã®çæ
+#
+libkernel.a: $(OFFSET_H) $(KERNEL_LIB_OBJS)
+	rm -f libkernel.a
+	$(AR) -rcs libkernel.a $(KERNEL_LIB_OBJS)
+	$(RANLIB) libkernel.a
+
+#
+#  ç¹å¥ãªä¾å­é¢ä¿ã®å®ç¾©
+#
+banner.o: kernel_cfg.timestamp $(filter-out banner.o,$(ALL_OBJS)) $(LIBS_DEP)
+
+#
+#  å
+¨ä½ã®ãªã³ã¯
+#
+$(OBJFILE): $(APPL_CFG) kernel_cfg.timestamp $(ALL_OBJS) $(LIBS_DEP)
+	$(LINK) $(CFLAGS) $(LDFLAGS) -o $(OBJFILE) $(START_OBJS) \
+			$(APPL_OBJS) $(SYSSVC_OBJS) $(CFG_OBJS) $(ALL_LIBS) $(END_OBJS)
+	$(NM) -n $(OBJFILE) > $(OBJNAME).syms
+	$(OBJCOPY) -O srec -S $(OBJFILE) $(OBJNAME).srec
+	$(CFG) --pass 3 --kernel asp $(INCLUDES) \
+				--rom-image $(OBJNAME).srec --symbol-table $(OBJNAME).syms \
+				-T $(TARGETDIR)/target_check.tf $(CFG_TABS) $<
+
+#
+#  ãã¤ããªãã¡ã¤ã«ã®çæ
+#
+$(OBJNAME).bin: $(OBJFILE)
+	$(OBJCOPY) -O binary -S $(OBJFILE) $(OBJNAME).bin
+
+#
+#  Sã¬ã³ã¼ããã¡ã¤ã«ã®çæ
+#
+$(OBJNAME).srec: $(OBJFILE)
+	$(OBJCOPY) -O srec -S $(OBJFILE) $(OBJNAME).srec
+
+#
+#  ã³ã³ãã¤ã«çµæã®æ¶å»
+#
+.PHONY: clean
+clean:
+	rm -f \#* *~ *.o $(CLEAN_FILES)
+	rm -f $(OBJFILE) $(OBJNAME).syms $(OBJNAME).srec $(OBJNAME).bin
+	rm -f kernel_cfg.timestamp $(CFG2_OUT_SRCS)
+	rm -f cfg1_out.c $(CFG1_OUT) cfg1_out.syms cfg1_out.srec
+ifndef KERNEL_LIB
+	rm -f libkernel.a
+endif
+	rm -f makeoffset.s offset.h
+
+.PHONY: cleankernel
+cleankernel:
+	rm -rf $(KERNEL_LIB_OBJS)
+	rm -f makeoffset.s offset.h
+
+.PHONY: cleandep
+cleandep:
+	if ! [ -f Makefile.depend ]; then \
+		rm -f kernel_cfg.timestamp $(CFG2_OUT_SRCS); \
+		rm -f cfg1_out.c cfg1_out.o $(CFG1_OUT) cfg1_out.syms cfg1_out.srec; \
+		rm -f makeoffset.s offset.h; \
+	fi
+	rm -f Makefile.depend
+
+.PHONY: realclean
+realclean: cleandep clean
+	rm -f $(REALCLEAN_FILES)
+
+#
+#  ã³ã³ãã£ã®ã¥ã¬ã¼ã¿ãçæãããã¡ã¤ã«ã®ã³ã³ãã¤ã«ã«ã¼ã«ã¨ä¾å­é¢ä¿ä½æ
+#  ã«ã¼ã«ã®å®ç¾©
+#
+#  ã³ã³ãã£ã®ã¥ã¬ã¼ã¿ãçæãããã¡ã¤ã«ã¯ï¼ã¢ããªã±ã¼ã·ã§ã³ãã­ã°ã©ã ç¨ï¼
+#  ã·ã¹ãã ãµã¼ãã¹ç¨ï¼ã«ã¼ãã«ç¨ã®ãã¹ã¦ã®ãªãã·ã§ã³ãä»ãã¦ã³ã³ãã¤ã«
+#  ããï¼
+#
+ALL_CFG_COBJS = $(CFG_COBJS) cfg1_out.o
+ALL_CFG_ASMOBJS = $(CFG_ASMOBJS)
+CFG_CFLAGS = $(APPL_CFLAGS) $(SYSSVC_CFLAGS) $(KERNEL_CFLAGS)
+
+$(ALL_CFG_COBJS): %.o: %.c
+	$(CC) -c $(CFLAGS) $(CFG_CFLAGS) $<
+
+$(ALL_CFG_COBJS:.o=.s): %.s: %.c
+	$(CC) -S $(CFLAGS) $(CFG_CFLAGS) $<
+
+$(ALL_CFG_COBJS:.o=.d): %.d: %.c
+	@$(PERL) $(SRCDIR)/utils/makedep -C $(CC) $(MAKEDEP_OPTS) \
+		-O "$(CFLAGS) $(CFG_CFLAGS)" $< >> Makefile.depend
+
+$(ALL_CFG_ASMOBJS): %.o: %.S
+	$(CC) -c $(CFLAGS) $(CFG_CFLAGS) $<
+
+$(ALL_CFG_ASMOBJS:.o=.d): %.d: %.S
+	@$(PERL) $(SRCDIR)/utils/makedep -C $(CC) $(MAKEDEP_OPTS) \
+		-O "$(CFLAGS) $(CFG_CFLAGS)" $< >> Makefile.depend
+
+#
+#  ç¹æ®ãªä¾å­é¢ä¿ä½æã«ã¼ã«ã®å®ç¾©
+#
+cfg1_out.depend: $(APPL_CFG)
+	@$(CFG) -M cfg1_out.c $(INCLUDES) $< >> Makefile.depend
+
+makeoffset.d: makeoffset.c
+	@$(PERL) $(SRCDIR)/utils/makedep -C $(CC) $(MAKEDEP_OPTS) \
+		-T "makeoffset.s" -O "$(CFLAGS) $(KERNEL_CFLAGS)" $< >> Makefile.depend
+
+#
+#  ä¾å­é¢ä¿ãã¡ã¤ã«ã®çæ
+#
+.PHONY: gendepend
+gendepend:
+	@echo "Generating Makefile.depend."
+
+.PHONY: depend
+ifdef KERNEL_LIB
+depend: cleandep kernel_cfg.timestamp gendepend \
+		cfg1_out.depend cfg1_out.d \
+		$(ALL_OBJS:.o=.d)
+else
+depend: cleandep $(OFFSET_H) kernel_cfg.timestamp gendepend \
+		cfg1_out.depend cfg1_out.d \
+		$(KERNEL_AUX_COBJS:.o=.d) $(KERNEL_ASMOBJS:.o=.d) \
+		$(KERNEL_COBJS:.o=.d) $(KERNEL_LCSRCS:.c=.d) $(ALL_OBJS:.o=.d)
+endif
+
+#
+#  ä¾å­é¢ä¿ãã¡ã¤ã«ãã¤ã³ã¯ã«ã¼ã
+#
+-include Makefile.depend
+
+#
+#  éçºãã¼ã«ã®ã³ãã³ãåã®å®ç¾©
+#
+ifeq ($(TOOL),gcc)
+  #
+  #  GNUéçºç°å¢ç¨
+  #
+  ifdef GCC_TARGET
+    GCC_TARGET_PREFIX = $(GCC_TARGET)-
+  else
+    GCC_TARGET_PREFIX =
+  endif
+  CC = $(GCC_TARGET_PREFIX)gcc
+  CXX = $(GCC_TARGET_PREFIX)g++
+  AS = $(GCC_TARGET_PREFIX)as
+  LD = $(GCC_TARGET_PREFIX)ld
+  AR = $(GCC_TARGET_PREFIX)ar
+  NM = $(GCC_TARGET_PREFIX)nm
+  RANLIB = $(GCC_TARGET_PREFIX)ranlib
+  OBJCOPY = $(GCC_TARGET_PREFIX)objcopy
+  OBJDUMP = $(GCC_TARGET_PREFIX)objdump
+endif
+
+ifdef USE_CXX
+  LINK = $(CXX)
+else
+  LINK = $(CC)
+endif
+
+#
+#  ã³ã³ãã¤ã«ã«ã¼ã«ã®å®ç¾©
+#
+KERNEL_ALL_COBJS = $(KERNEL_COBJS) $(KERNEL_AUX_COBJS)
+
+$(KERNEL_ALL_COBJS): %.o: %.c
+	$(CC) -c $(CFLAGS) $(KERNEL_CFLAGS) $<
+
+$(KERNEL_ALL_COBJS:.o=.s): %.s: %.c
+	$(CC) -S $(CFLAGS) $(KERNEL_CFLAGS) $<
+
+$(KERNEL_LCOBJS): %.o:
+	$(CC) -DTOPPERS_$(*F) -o $@ -c $(CFLAGS) $(KERNEL_CFLAGS) $<
+
+$(KERNEL_LCOBJS:.o=.s): %.s:
+	$(CC) -DTOPPERS_$(*F) -o $@ -S $(CFLAGS) $(KERNEL_CFLAGS) $<
+
+$(KERNEL_ASMOBJS): %.o: %.S
+	$(CC) -c $(CFLAGS) $(KERNEL_CFLAGS) $<
+
+$(SYSSVC_COBJS): %.o: %.c
+	$(CC) -c $(CFLAGS) $(SYSSVC_CFLAGS) $<
+
+$(SYSSVC_COBJS:.o=.s): %.s: %.c
+	$(CC) -S $(CFLAGS) $(SYSSVC_CFLAGS) $<
+
+$(SYSSVC_ASMOBJS): %.o: %.S
+	$(CC) -c $(CFLAGS) $(SYSSVC_CFLAGS) $<
+
+$(APPL_COBJS): %.o: %.c
+	$(CC) -c $(CFLAGS) $(APPL_CFLAGS) $<
+
+$(APPL_COBJS:.o=.s): %.s: %.c
+	$(CC) -S $(CFLAGS) $(APPL_CFLAGS) $<
+
+$(APPL_CXXOBJS): %.o: %.cpp
+	$(CXX) -c $(CFLAGS) $(APPL_CFLAGS) $<
+
+$(APPL_CXXOBJS:.o=.s): %.s: %.cpp
+	$(CXX) -S $(CFLAGS) $(APPL_CFLAGS) $<
+
+$(APPL_ASMOBJS): %.o: %.S
+	$(CC) -c $(CFLAGS) $(APPL_CFLAGS) $<
+
+#
+#  ä¾å­é¢ä¿ä½æã«ã¼ã«ã®å®ç¾©
+#
+$(KERNEL_COBJS:.o=.d): %.d: %.c
+	@$(PERL) $(SRCDIR)/utils/makedep -C $(CC) $(MAKEDEP_OPTS) \
+		-O "$(CFLAGS) $(KERNEL_CFLAGS)" $< >> Makefile.depend
+
+$(KERNEL_LCSRCS:.c=.d): %.d: %.c
+	@$(PERL) $(SRCDIR)/utils/makedep -C $(CC) $(MAKEDEP_OPTS) -T "$($*)" \
+		-O "-DALLFUNC $(CFLAGS) $(KERNEL_CFLAGS)" $< >> Makefile.depend
+
+$(KERNEL_ASMOBJS:.o=.d): %.d: %.S
+	@$(PERL) $(SRCDIR)/utils/makedep -C $(CC) $(MAKEDEP_OPTS) \
+		-O "$(CFLAGS) $(KERNEL_CFLAGS)" $< >> Makefile.depend
+
+$(SYSSVC_COBJS:.o=.d): %.d: %.c
+	@$(PERL) $(SRCDIR)/utils/makedep -C $(CC) $(MAKEDEP_OPTS) \
+		-O "$(CFLAGS) $(SYSSVC_CFLAGS)" $< >> Makefile.depend
+
+$(SYSSVC_ASMOBJS:.o=.d): %.d: %.S
+	@$(PERL) $(SRCDIR)/utils/makedep -C $(CC) $(MAKEDEP_OPTS) \
+		-O "$(CFLAGS) $(SYSSVC_CFLAGS)" $< >> Makefile.depend
+
+$(APPL_COBJS:.o=.d): %.d: %.c
+	@$(PERL) $(SRCDIR)/utils/makedep -C $(CC) $(MAKEDEP_OPTS) \
+		-O "$(CFLAGS) $(APPL_CFLAGS)" $< >> Makefile.depend
+
+$(APPL_CXXOBJS:.o=.d): %.d: %.cpp
+	@$(PERL) $(SRCDIR)/utils/makedep -C $(CXX) $(MAKEDEP_OPTS) \
+		-O "$(CFLAGS) $(APPL_CFLAGS)" $< >> Makefile.depend
+
+$(APPL_ASMOBJS:.o=.d): %.d: %.S
+	@$(PERL) $(SRCDIR)/utils/makedep -C $(CC) $(MAKEDEP_OPTS) \
+		-O "$(CFLAGS) $(APPL_CFLAGS)" $< >> Makefile.depend
+
+#
+#  ããã©ã«ãã³ã³ãã¤ã«ã«ã¼ã«ãä¸æ¸ã
+#
+%.o: %.c
+	@echo "*** Default compile rules should not be used."
+	$(CC) -c $(CFLAGS) $<
+
+%.s: %.c
+	@echo "*** Default compile rules should not be used."
+	$(CC) -S $(CFLAGS) $<
+
+%.o: %.cpp
+	@echo "*** Default compile rules should not be used."
+	$(CXX) -c $(CFLAGS) $<
+
+%.s: %.cpp
+	@echo "*** Default compile rules should not be used."
+	$(CXX) -S $(CFLAGS) $<
+
+%.o: %.S
+	@echo "*** Default compile rules should not be used."
+	$(CC) -c $(CFLAGS) $<
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/OBJ/STM32F767NUCLEO144_GCC/LCD/command.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/OBJ/STM32F767NUCLEO144_GCC/LCD/command.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/OBJ/STM32F767NUCLEO144_GCC/LCD/command.c	(revision 457)
@@ -0,0 +1,141 @@
+#include <kernel.h>
+#include <t_syslog.h>
+#include <stdio.h>
+#include <t_stdlib.h>
+#include <stdlib.h>
+#include "syssvc/serial.h"
+#include "syssvc/syslog.h"
+#include "kernel_cfg.h"
+#include "monitor.h"
+#include "device.h"
+
+/*
+ *  デバイスコマンド番号
+ */
+#define NUM_DEVICE_CMD   3
+
+static int_t led_func(int argc, char **argv);
+static int_t dip_func(int argc, char **argv);
+static int_t cup_func(int argc, char **argv);
+
+/*
+ *  デバイスコマンドテーブル
+ */
+static const COMMAND_INFO device_command_info[NUM_DEVICE_CMD] = {
+	{"LED",		led_func},
+	{"DIP",		dip_func},
+	{"CUP",		cup_func}
+};
+
+static const char device_name[] = "DEVICE";
+static const char device_help[] =
+"  Device  LED (no) (on-1,off-0)  led   control\n"
+"          DIP (no) (on-1,off-0)  dipsw control\n"
+"          CUP command            cup   control\n";
+
+static const uint16_t led_pattern[4] = {
+	LED01, LED02, LED03, LED04
+};
+
+static COMMAND_LINK device_command_link = {
+	NULL,
+	NUM_DEVICE_CMD,
+	device_name,
+	NULL,
+	device_help,
+	&device_command_info[0]
+};
+
+static uint8_t cup_command;
+
+static int a2i(char *str)
+{
+	int num = 0;
+
+	while(*str >= '0' && *str <= '9'){
+		num = num * 10 + *str++ - '0';
+	}
+	return num;
+}
+
+/*
+ *  DEVICEコマンド設定関数
+ */
+void device_info_init(intptr_t exinf)
+{
+	setup_command(&device_command_link);
+}
+
+/*
+ *  LED設定コマンド関数
+ */
+static int_t led_func(int argc, char **argv)
+{
+	int_t    arg1=0, arg2;
+	uint16_t reg;
+
+	if(argc < 3)
+		return -1;
+	arg1 = a2i(argv[1]);
+	arg2 = a2i(argv[2]);
+	if(arg1 >= 1 && arg1 <= 4){
+		reg = led_in();
+		if(arg2 != 0)
+			reg |= led_pattern[arg1-1];
+		else
+			reg &= ~led_pattern[arg1-1];
+		led_out(reg);
+	}
+	return 0;
+}
+
+/*
+ *  DIPSW設定コマンド関数
+ */
+static int_t dip_func(int argc, char **argv)
+{
+	int_t   arg1=0, arg2=0, i;
+
+	if(argc > 1)
+		arg1 = a2i(argv[1]);
+	if(argc > 2)
+		arg2 = a2i(argv[2]);
+	if(arg1 >= 1 && arg1 <= 8){
+		if(arg2 != 0)
+			dipsw_value |= (0x1<<(arg1-1));
+		else
+			dipsw_value &= ~(0x1<<(arg1-1));
+	}
+	printf("dipsw\n1   2   3   4   5   6   7   8\n");
+	for(i = 0 ; i < 8 ; i++){
+		if(dipsw_value & (1<<i))
+			printf("ON  ");
+		else
+			printf("OFF ");
+	}
+	printf("\n");
+	return 0;
+}
+
+/*
+ *  カップラーメンタイマ補助コマンド関数
+ */
+static int_t cup_func(int argc, char **argv)
+{
+	if(argc > 1)
+		cup_command = *argv[1];
+	return 0;
+}
+
+/*
+ * CUPラーメンコマンド
+ */
+int8_t
+get_cup_command(void)
+{
+	uint8_t cmd = cup_command;
+	cup_command = 0;
+	return cmd;
+}
+
+
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/OBJ/STM32F767NUCLEO144_GCC/LCD/lcdshield.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/OBJ/STM32F767NUCLEO144_GCC/LCD/lcdshield.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/OBJ/STM32F767NUCLEO144_GCC/LCD/lcdshield.c	(revision 457)
@@ -0,0 +1,580 @@
+/*
+ *  TOPPERS/ASP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Advanced Standard Profile Kernel
+ * 
+ *  Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
+ *                              Toyohashi Univ. of Technology, JAPAN
+ *  Copyright (C) 2004-2012 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ *  Copyright (C) 2015-2016 by TOPPERS PROJECT Educational Working Group.
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  $Id$
+ */
+
+/* 
+ *  LCDシールド制御プログラムの本体
+ */
+
+#include <kernel.h>
+#include <t_syslog.h>
+#include <t_stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <target_syssvc.h>
+#include "syssvc/serial.h"
+#include "syssvc/syslog.h"
+#include "kernel_cfg.h"
+#include "device.h"
+#include "spi.h"
+#include "pinmode.h"
+#include "adafruit_st7735.h"
+#ifdef USE_MSC_FILE
+#include "storagedevice.h"
+#include "mscdiskio.h"
+#endif
+#include "lcdshield.h"
+#include "adc.h"
+#include "topamelogo.h"
+
+/*
+ *  サービスコールのエラーのログ出力
+ */
+Inline void
+svc_perror(const char *file, int_t line, const char *expr, ER ercd)
+{
+	if (ercd < 0) {
+		t_perror(LOG_ERROR, file, line, expr, ercd);
+	}
+}
+
+#define	SVC_PERROR(expr)	svc_perror(__FILE__, __LINE__, #expr, (expr))
+#define ABS(X)  ((X) > 0 ? (X) : -(X))
+
+
+/*
+ *  使用する変数の定義
+ */
+static const Point testPolygon[7] = {
+	{0, 0},
+	{127, 159},
+	{64, 0},
+	{64, 159},
+	{127, 0},
+	{0, 159},
+	{0, 0}
+};
+
+static const uint32_t pos_tbl[NUM_JSPOSITION-1][2] = {
+	{  500, JS_DOWN  },
+	{ 1000, JS_RIGHT },
+	{ 1500, JS_ON    },
+	{ 2500, JS_UP    },
+	{ 3800, JS_LEFT  }
+};
+static const char *pos_str[NUM_JSPOSITION-1] = {
+	"      ON      ",
+	"      UP      ",
+	"     DOWN     ",
+	"     LEFT     ",
+	"     RIGHT    "
+};
+
+
+LCD_Handler_t  LcdHandle;
+LCD_DrawProp_t DrawProp;
+uint8_t msc_state;
+
+#define NUM_ADCBUF   1		/* 96:1ms */
+volatile uint32_t uhADCxConvertedValue;
+
+#ifndef USE_MSC_FILE
+uint32_t sdbuffer[514/4];
+#endif
+
+/* Buffer used for transmission */
+uint8_t aTxBuffer[BUFFERSIZE];
+
+/* Buffer used for reception */
+uint8_t aRxBuffer[BUFFERSIZE];
+
+static uint32_t heap_area[2*1024];
+
+uint32_t heap_param[2] = {
+	(uint32_t)heap_area,
+	(2*4*1024)
+};
+
+#ifdef USE_MSC_FILE
+/*
+ *  時刻の取出し
+ */
+static uint32_t get_fat_time(void)
+{
+	int    reqtime = 0;
+	struct tm2 timedate;
+
+	rtc_get_time(&timedate);
+	reqtime  = ((timedate.tm_year-10)<<25)+(timedate.tm_mon<<21)+(timedate.tm_mday<<16);
+	reqtime += (timedate.tm_hour<<11)+(timedate.tm_min<<5)+(timedate.tm_sec/2);
+	return reqtime;
+}
+#endif
+
+/*
+ *  SW1割込み
+ */
+void sw_int(void)
+{
+	syslog_0(LOG_NOTICE, "## sw_int() ##");
+}
+
+/*
+ *  GPIO設定関数
+ */
+static void
+pinMode(uint8_t no, uint32_t mode)
+{
+	Arduino_PortControlBlock *pgcb = getGpioTable(DIGITAL_PIN, no);
+	GPIO_Init_t GPIO_Init_Data;
+
+	if(pgcb == NULL)
+		return;
+	pinClock(no);
+	GPIO_Init_Data.mode  = mode;
+	GPIO_Init_Data.pull  = GPIO_PULLMODE;
+	GPIO_Init_Data.otype = GPIO_OTYPE;
+	GPIO_Init_Data.speed = GPIO_SPEED_FAST;
+	gpio_setup(pgcb->giobase, &GPIO_Init_Data, pgcb->giopin);
+}
+
+
+/*
+ *  グラフィック表示テスト
+ */
+void
+grapics_test(LCD_Handler_t *hlcd)
+{
+	uint16_t x, y;
+	int      i;
+
+	DrawProp.BackColor = ST7735_BLACK;
+	lcd_fillScreen(&DrawProp);
+	dly_tsk(1000);
+	lcd_drawPixel(hlcd, hlcd->_width/2, hlcd->_height/2, ST7735_GREEN);
+	dly_tsk(1000);
+
+	lcd_fillScreen(&DrawProp);
+	for(y=0; y < hlcd->_height; y+=5) {
+		lcd_drawFastHLine(hlcd, 0, y, hlcd->_width, ST7735_RED);
+	}
+	for (x=0; x < hlcd->_width; x+=5) {
+    	lcd_drawFastVLine(hlcd, x, 0, hlcd->_height, ST7735_BLUE);
+	}
+	dly_tsk(1000);
+
+	lcd_fillScreen(&DrawProp);
+	DrawProp.TextColor = ST7735_GREEN;
+	lcd_drawPolygon(&DrawProp, (Point *)testPolygon, sizeof(testPolygon)/sizeof(Point));
+	dly_tsk(1000);
+
+	lcd_fillScreen(&DrawProp);
+	DrawProp.TextColor = ST7735_GREEN;
+	for (x=0; x < hlcd->_width; x+=6) {
+		lcd_drawRect(&DrawProp, hlcd->_width/2 -x/2, hlcd->_height/2 -x/2 , x, x);
+	}
+	for(i = 0 ; i < 3 ; i++){
+		lcd_invertDisplay(hlcd, true);
+		dly_tsk(500);
+		lcd_invertDisplay(hlcd, false);
+		dly_tsk(500);
+	}
+	lcd_fillScreen(&DrawProp);
+	lcd_drawBitmap(hlcd, 33, 48, (uint8_t *)topamelogo);
+	dly_tsk(1000);
+}
+
+/*
+ *  USB HOST INFORMATION CALLBACK
+ *  parameter1:  Host Handler
+ *  parameter2:  Device Handler
+ *  parameter3:  Host state ID.
+ */
+static void USBH_UserProcess(USBH_HandleTypeDef *phost, TUSBH_Device_t *pdevice, uint8_t id)
+{
+	msc_state = id;
+	if(pdevice->pClass != NULL){
+		syslog_3(LOG_NOTICE, "## CLASS[%s](%d)(%d) ##", pdevice->pClass->Name, pdevice->type, id);
+	}
+}
+
+/*
+ *  メインタスク
+ */
+void
+main_task(intptr_t exinf)
+{
+#ifdef USE_MSC_FILE
+	StorageDevice_t *psdev;
+#else
+	TUSBH_ERCODE  status = TUSBH_E_OK;
+	char pdrv = 0;
+#endif
+	SPI_Init_t spi_initd;
+	USB_OTG_Init_t USB_Data_Init;
+	LCD_Handler_t   *hlcd;
+	SPI_Handle_t  *hspi;
+	USB_OTG_Handle_t *husb;
+	USBH_HandleTypeDef *husbh;
+    FLGPTN  flgptn;
+	ER_UINT	ercd;
+	int sens = 1000;
+	int i;
+
+	SVC_PERROR(syslog_msk_log(LOG_UPTO(LOG_INFO), LOG_UPTO(LOG_EMERG)));
+	syslog(LOG_NOTICE, "Sample program starts (exinf = %d).", (int_t) exinf);
+
+	/*
+	 *  シリアルポートの初期化
+	 *
+	 *  システムログタスクと同じシリアルポートを使う場合など，シリアル
+	 *  ポートがオープン済みの場合にはここでE_OBJエラーになるが，支障は
+	 *  ない．
+	 */
+	ercd = serial_opn_por(TASK_PORTID);
+	if (ercd < 0 && MERCD(ercd) != E_OBJ) {
+		syslog(LOG_ERROR, "%s (%d) reported by `serial_opn_por'.",
+									itron_strerror(ercd), SERCD(ercd));
+	}
+	SVC_PERROR(serial_ctl_por(TASK_PORTID,
+							(IOCTL_CRLF | IOCTL_FCSND | IOCTL_FCRCV)));
+
+	syslog_0(LOG_NOTICE, "## START ##");
+	/*
+	 *  CS PORT(D10-PB6)
+	 */
+	pinMode(CS_PORT, GPIO_MODE_OUTPUT);
+	/*
+	 *  RS PORT(D8-PA9)
+	 */
+	pinMode(RS_PORT, GPIO_MODE_OUTPUT);
+	/*
+	 *  RST PORT(D9-PC7)
+	 */
+	pinMode(RST_PORT, GPIO_MODE_OUTPUT);
+
+	spi_initd.Prescaler     = SPI_BAUDRATEPRESCALER_64;
+	spi_initd.Direction     = SPI_DIRECTION_2LINES;
+	spi_initd.CLKPhase      = SPI_PHASE_1EDGE;
+	spi_initd.CLKPolarity   = SPI_POLARITY_LOW;
+	spi_initd.CRC           = SPI_CRC_DISABLE;
+	spi_initd.CRCPolynomial = 7;
+	spi_initd.DataSize      = SPI_DATASIZE_8BIT;
+	spi_initd.SignBit       = SPI_DATA_MSB;
+	spi_initd.NSS           = SPI_NSS_SOFT;
+	spi_initd.TIMode        = SPI_TIMODE_DISABLE;
+	spi_initd.Mode = SPI_MODE_MASTER;
+	spi_initd.semid = SPI1DMA_SEM;
+	spi_initd.semlock = 0;
+	if((hspi = spi_init(SPI1_PORTID, &spi_initd)) == NULL){
+		syslog_0(LOG_ERROR, "spi_start initialize error !");
+	}
+
+	/* Init USB OTG Hard */
+	/* Set the LL Driver parameters */
+    USB_Data_Init.usb_otg_mode = USB_OTG_MODE_HOST;
+	USB_Data_Init.host_channels = 11;	/* HOST */
+	USB_Data_Init.dma_enable = 0;
+	USB_Data_Init.low_power_enable = 0;
+	USB_Data_Init.phy_itface = USB_PHY_EMBEDDED; 
+	USB_Data_Init.sof_enable = 0;
+	USB_Data_Init.speed = USB_SPEED_FULL;
+	USB_Data_Init.vbus_sensing_enable = 0;	/* HOST */
+	USB_Data_Init.lpm_enable = 0;
+	USB_Data_Init.use_external_vbus = 0;
+	husb = usbo_init(USB1_PORTID, &USB_Data_Init);
+
+	/*
+	 *  USB HOSTミドルウェア設定
+	 */
+	husbh = (USBH_HandleTypeDef *)malloc(sizeof(USBH_HandleTypeDef));
+	husbh->pSysData = husb;
+	tusbhInit(husbh, USBH_UserProcess, 0);
+#ifdef USE_MSC_FILE
+	psdev = SDMGetStorageDevice(MSC_DEVNO);
+	psdev->_sdev_local[1] = husbh;
+	SDeviceHead._get_datetime = get_fat_time;
+#endif
+
+	/*
+	 *  USB HOSTスタート
+	 */
+	tusbhStart(husbh);
+
+	i = 0;
+	while(msc_state != HOST_USER_CLASS_ACTIVE && i < 15){
+		syslog_2(LOG_NOTICE, " WAIT MSC READY(%d)(%d) !", msc_state, i);
+		dly_tsk(1000);
+		i++;
+	}
+	if(msc_state != HOST_USER_CLASS_ACTIVE)
+		syslog_0(LOG_NOTICE, "MSC INITIAL ERROR !");
+
+#ifndef USE_MSC_FILE
+	if(msc_state == HOST_USER_CLASS_ACTIVE && tusbhMscUnitIsReady(husbh, pdrv)){
+		unsigned char *p;
+		int j, bpb;
+		int SecPerCls, Rsv, NumFat, Fsize, RootDirC, RootSec, tsect;
+		p = (unsigned char *)sdbuffer;
+		for(i = 0 ; i < 1 ; i++){
+			status = tusbhMscRead(husbh, pdrv, i, (uint8_t *)sdbuffer, 1);
+			syslog_3(LOG_NOTICE, "## status(%d) i(%d) sdbuffer[%08x] ##", status, i, sdbuffer);
+			dly_tsk(300);
+			if(i == 0){
+				if(p[0x36] == 'F' && p[0x37] == 'A' && p[0x38] == 'T')
+					bpb = 0;
+				else{
+					bpb = p[0x1c6];
+					bpb |= p[0x1c7]<<8;
+					bpb |= p[0x1c8]<<16;
+					bpb |= p[0x1c9]<<24;
+				}
+			}
+			printf("\nsec(%d) ", i);
+			for(j = 0 ; j < 512 ; j++){
+				if((j % 16) == 0)
+					printf("\n%03x ", j);
+				printf("%02x ", p[j]);
+			}
+			printf("\n");
+		}
+		syslog_1(LOG_NOTICE, "## bpb(%08x) ##", bpb);
+		if(bpb != 0){
+			status = tusbhMscRead(husbh, pdrv, bpb, (uint8_t *)sdbuffer, 1);
+			syslog_3(LOG_NOTICE, "## status(%d) i(%d) sdbuffer[%08x] ##", status, bpb, sdbuffer);
+			dly_tsk(300);
+			printf("\nsec(%d) ", bpb);
+			for(j = 0 ; j < 512 ; j++){
+				if((j % 16) == 0)
+					printf("\n%03x ", j);
+				printf("%02x ", p[j]);
+			}
+			printf("\n");
+		}
+		SecPerCls = p[13];
+		Rsv = p[14] + (p[15] << 8);
+		NumFat = p[16];
+		RootDirC = p[17] + (p[18]<<8);
+		Fsize = p[22] + (p[23] << 8);
+		if(Fsize == 0){
+			Fsize = p[36] + (p[37] << 8);
+			RootSec = p[44] + (p[45] << 8) + (p[46] << 16) + (p[47] << 24);
+		}
+		else
+			RootSec = bpb + Rsv + (NumFat * Fsize);
+		tsect = p[32] + (p[33] << 8) + (p[34] << 16) + (p[35] << 24);
+		if(tsect == 0)
+			tsect = p[19] + (p[20] << 8) + (p[21] << 16) + (p[22] << 24);
+		syslog_4(LOG_NOTICE, "## SecPerCls(%d) Rsv(%d) NumFat(%d) RootDirC(%d) ##", SecPerCls, Rsv, NumFat, RootDirC);
+		syslog_3(LOG_NOTICE, "## Fsize(%d) RootSec(%d) totalsec(%d) ##", Fsize, RootSec, tsect);
+
+		for(i = 0 ; i < 2 ; i++){
+			status = tusbhMscRead(husbh, pdrv, (i+RootSec), (uint8_t *)sdbuffer, 1);
+			syslog_3(LOG_NOTICE, "## status(%d) i(%d) sdbuffer[%08x] ##", status, (i+RootSec), sdbuffer);
+			dly_tsk(300);
+			p = (unsigned char *)sdbuffer;
+			printf("\nsec(%d) ", (i+RootSec));
+			for(j = 0 ; j < 512 ; j++){
+				if((j % 16) == 0)
+					printf("\n%03x ", j);
+				printf("%02x ", p[j]);
+			}
+			printf("\n");
+		}
+	}
+#endif
+	hlcd = &LcdHandle;
+	hlcd->hspi = hspi;
+	hlcd->spi_lock= 0;
+	hlcd->cs_pin  = CS_PORT;
+	hlcd->rs_pin  = RS_PORT;
+	hlcd->rst_pin = RST_PORT;
+	hlcd->cs2_pin = CS2_PORT;
+	DrawProp.hlcd = hlcd;
+	lcd_initR(hlcd, INITR_BLACKTAB);
+	DrawProp.BackColor = ST7735_BLACK;
+	DrawProp.TextColor = ST7735_WHITE;
+	grapics_test(hlcd);
+#if 1	/* LOCAL DEFINE */
+	DrawProp.TextColor = ST7735_BLACK;
+	DrawProp.BackColor = ST7735_WHITE;
+	lcd_fillScreen(&DrawProp);
+	lcd_fillRect(hlcd, 0, 0, hlcd->_width, hlcd->_height/3, ST7735_BLUE);
+	DrawProp.TextColor = ST7735_WHITE;
+	DrawProp.BackColor = ST7735_BLUE;
+	DrawProp.pFont = &Font20;
+	lcd_DisplayStringAt(&DrawProp, 0, 20, "TBP TEST", CENTER_MODE);
+
+	DrawProp.TextColor = ST7735_BLACK;
+	DrawProp.BackColor = ST7735_WHITE;
+	DrawProp.pFont = &Font8;
+	lcd_DisplayStringAt(&DrawProp, 0, 80, (uint8_t *)"Helle World !", CENTER_MODE);
+	DrawProp.pFont = &Font12;
+	lcd_DisplayStringAt(&DrawProp, 0, 100, (uint8_t *)"Helle World !", CENTER_MODE);
+	DrawProp.pFont = &Font16;
+	lcd_DisplayStringAt(&DrawProp, 0, 120, (uint8_t *)"Helle World !", CENTER_MODE);
+
+	DrawProp.TextColor = ST7735_RED;
+	for(i = 20 ; i < 40 ; i++){
+		lcd_DrawCircle(&DrawProp, hlcd->_width/2, hlcd->_height/2+30, i);
+		if(i == 25)
+			i += 10;
+	}
+#endif	/* LOCAL DEFINE */
+	syslog_0(LOG_NOTICE, "LCD TEST END");
+	while(sens > 0){
+		wai_flg(SW_FLG, JS_MASK, TWF_ORW, &flgptn);
+		syslog_1(LOG_NOTICE, "## JS EVENT[%04x] ##", flgptn);
+		for(i = 0 ; i < NUM_JSPOSITION ; i++){
+			if(flgptn & (1<<i))
+				break;
+		}
+		if(i == NUM_JSPOSITION)
+			i = 0;
+#if 1	/* LOCAL DEFINE */
+		DrawProp.pFont = &Font12;
+		if(i == 0 || i == NUM_JSPOSITION)
+			lcd_DisplayStringAt(&DrawProp, 0, 100, (uint8_t *)"Helle World !", CENTER_MODE);
+		else
+			lcd_DisplayStringAt(&DrawProp, 0, 100, (uint8_t *)pos_str[i-1], CENTER_MODE);
+#else	/* LOCAL DEFINE */
+		syslog_1(LOG_NOTICE, "## event(%d) ##", i);
+#endif	/* LOCAL DEFINE */
+		sens--;
+	}
+#ifdef USE_MSC_FILE
+	syslog_0(LOG_NOTICE, "## STOP ##");
+	slp_tsk();
+#endif
+	spi_deinit(hspi);
+
+	syslog(LOG_NOTICE, "Sample program ends.");
+//	SVC_PERROR(ext_ker());
+}
+
+
+/*
+ *  ADC転送終了コールバック関数
+ */
+static void HAL_ADC_ConvCpltCallback2(ADC_Handle_t* hadc)
+{
+	isig_sem(ADCDMA_SEM);
+}
+
+/*
+ *  ジョイスティック監視タスク
+ */
+void stick_task(intptr_t exinf)
+{
+	ADC_Init_t     aInit;
+	ADC_ChannelConf_t sConfig;
+	ADC_Handle_t *hadc;
+	uint32_t event = 0;
+	int i;
+
+	/*
+	 *  ADC3初期化
+	 */
+	aInit.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV2;
+	aInit.Resolution = ADC_RESOLUTION_12B;
+	aInit.ScanConvMode = ADC_SCANMODE_DISABLE;
+//	aInit.ContinuousConvMode = ADC_CONTINUOUS_ENABLE;
+	aInit.ContinuousConvMode = ADC_CONTINUOUS_DISABLE;
+	aInit.DiscontinuousConvMode = ADC_DISCONTINUOUS_DISABLE;
+	aInit.NumDiscConversion = 0;
+	aInit.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
+	aInit.ExternalTrigConv = ADC_EXTERNALTRIGCONV_T1_CC1;
+	aInit.DataAlign = ADC_DATAALIGN_RIGHT;
+	aInit.NumConversion = 1;
+	aInit.DMAContinuousRequests = ADC_DMACONTINUOUS_ENABLE;
+	aInit.EOCSelection = ADC_EOC_SEQ_DISABLE;
+
+	if((hadc = adc_init(ADC3_PORTID, &aInit)) == NULL){
+		/* Initialization Error */
+		syslog_0(LOG_NOTICE, "## adc_init ERROR ##");
+	}
+	hadc->xfercallback = HAL_ADC_ConvCpltCallback2;
+
+	/*
+	 *  ADCチャネル設定
+	 */
+	sConfig.Channel = ADCx_CHANNEL;
+	sConfig.Rank = 1;
+//  sConfig.SamplingTime = ADC_SAMPLETIME_3CYCLES;
+	sConfig.SamplingTime = ADC_SAMPLETIME_480CYCLES;
+	sConfig.GpioBase = ADCx_CHANNEL_GPIO_PORT;
+	sConfig.GpioPin  = ADCx_CHANNEL_PINNO;
+	if(adc_setupchannel(hadc, &sConfig) != E_OK){
+		/* Channel Configuration Error */
+		syslog_0(LOG_NOTICE, "## adc_setupchannel ERROR ##");
+	}
+
+	for(;;){
+		uhADCxConvertedValue = 0;
+		/*
+		 *  ADC DMAスタート
+		 */
+		if(adc_start_dma(hadc, (uint32_t*)&uhADCxConvertedValue, 1) != E_OK){
+			/* Start Conversation Error */
+			syslog_0(LOG_NOTICE, "## adc_start_dma ERROR ##");
+		}
+		while(hadc->status == ADC_STATUS_BUSY){
+ 			twai_sem(ADCDMA_SEM, 10);
+		}
+		adc_end_dma(hadc);
+		for(i = 0 ; i < (NUM_JSPOSITION-1) ; i++){
+			if(uhADCxConvertedValue < pos_tbl[i][0]){
+				event = pos_tbl[i][1];
+				set_flg(SW_FLG, event);
+				break;
+			}
+		}
+		if(i == 5 && event != JS_OFF){
+			event = JS_OFF;
+			set_flg(SW_FLG, JS_OFF);
+		}
+  		dly_tsk(50);
+	}
+	syslog_2(LOG_NOTICE, "## STOP[%08x] (%d) ##", &uhADCxConvertedValue, hadc->status);
+	slp_tsk();
+}
+
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/OBJ/STM32F767NUCLEO144_GCC/LCD/lcdshield.cfg
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/OBJ/STM32F767NUCLEO144_GCC/LCD/lcdshield.cfg	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/OBJ/STM32F767NUCLEO144_GCC/LCD/lcdshield.cfg	(revision 457)
@@ -0,0 +1,52 @@
+/*
+ *  $Id$
+ */
+
+/*
+ *  LCDシールドのコンフィギュレーションファイル
+ */
+INCLUDE("target_timer.cfg");
+INCLUDE("syssvc/syslog.cfg");
+INCLUDE("syssvc/banner.cfg");
+INCLUDE("syssvc/serial.cfg");
+INCLUDE("syssvc/logtask.cfg");
+INCLUDE("syssvc/tlsf.cfg");
+INCLUDE("monitor/monitor.cfg");
+INCLUDE("pdic/stm32f7xx/device.cfg");
+INCLUDE("usb/host/tusbh.cfg");
+
+#include "device.h"
+#include "spi.h"
+#include "adc.h"
+#include "usb_otg.h"
+#include "lcdshield.h"
+
+ATT_INI({ TA_NULL, heap_param, heap_init });
+ATT_INI({ TA_NULL, sw_int, setup_sw_func });
+ATT_INI({ TA_NULL, 0, device_info_init });
+
+CRE_TSK(MAIN_TASK, { TA_ACT, 0, main_task, MAIN_PRIORITY, STACK_SIZE, NULL });
+CRE_TSK(STICK_TASK, { TA_ACT, 0, stick_task, HIGH_PRIORITY, STACK_SIZE, NULL });
+
+CRE_FLG(SW_FLG,{TA_CLR, 0});
+
+CRE_SEM(ADCDMA_SEM, { TA_TPRI, 0, 1 });
+CRE_SEM(SPI1DMA_SEM, { TA_TPRI, 0, 1 });
+
+ATT_ISR({TA_NULL, SPI1_PORTID, INTNO_SPI, spi_isr, 1 });
+CFG_INT(INTNO_SPI, { TA_ENAINT | INTATR_SPI, INTPRI_SPI });
+
+ATT_ISR({TA_NULL, DMA2STM2_SID, INTNO_DMARX, stream_dma_isr, 1 });
+CFG_INT(INTNO_DMARX, { TA_ENAINT | INTATR_DMARX, INTPRI_DMARX });
+ATT_ISR({TA_NULL, DMA2STM3_SID, INTNO_DMATX, stream_dma_isr, 1 });
+CFG_INT(INTNO_DMATX, { TA_ENAINT | INTATR_DMATX, INTPRI_DMATX });
+ATT_ISR({TA_NULL, DMA2STM0_SID, INTNO_DMAADC, stream_dma_isr, 1 });
+CFG_INT(INTNO_DMAADC, { TA_ENAINT | INTATR_DMAADC, INTPRI_DMAADC });
+DEF_INH(INHNO_ADC, { TA_NULL, adc_int_handler });
+CFG_INT(INTNO_ADC, { TA_ENAINT | INTATR_ADC, INTPRI_ADC });
+
+ATT_ISR({TA_NULL, USB1_PORTID, INTNO_USBFS, usb_otg_isr, 1 });
+CFG_INT(INTNO_USBFS, { TA_ENAINT | INTATR_USBFS, INTPRI_USBFS });
+ATT_ISR({TA_NULL, USB1_PORTID, INTNO_FSWKUP, usb_otg_wkup_isr, 1 });
+CFG_INT(INTNO_FSWKUP, { TA_ENAINT | INTATR_FSWKUP, INTPRI_FSWKUP });
+
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/OBJ/STM32F767NUCLEO144_GCC/LCD/lcdshield.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/OBJ/STM32F767NUCLEO144_GCC/LCD/lcdshield.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/OBJ/STM32F767NUCLEO144_GCC/LCD/lcdshield.h	(revision 457)
@@ -0,0 +1,178 @@
+/*
+ *  TOPPERS/ASP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Advanced Standard Profile Kernel
+ *
+ *  Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
+ *                              Toyohashi Univ. of Technology, JAPAN
+ *  Copyright (C) 2004-2010 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ *  Copyright (C) 2015-2016 by TOPPERS PROJECT Educational Working Group.
+ *
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ *
+ *  $Id$
+ */
+
+/*
+ *  LCDシールド制御プログラムのヘッダファイル
+ */
+
+/*
+ *  ターゲット依存の定義
+ */
+#include "target_test.h"
+#include "usb_otg.h"
+#include "tusbh_msc.h"
+#include "glcd_disp.h"
+
+/*
+ *  各タスクの優先度の定義
+ */
+
+#define MAIN_PRIORITY	9		/* メインタスクの優先度 */
+								/* HIGH_PRIORITYより高くすること */
+
+#define HIGH_PRIORITY	6		/* 並行実行されるタスクの優先度 */
+#define MID_PRIORITY	10
+#define LOW_PRIORITY	11
+
+/*
+ *  ターゲットに依存する可能性のある定数の定義
+ */
+
+#ifndef TASK_PORTID
+#define	TASK_PORTID		1			/* 文字入力するシリアルポートID */
+#endif /* TASK_PORTID */
+
+#ifndef STACK_SIZE
+#define	STACK_SIZE		4096		/* タスクのスタックサイズ */
+#endif /* STACK_SIZE */
+
+//#define SPISDCARD_PORTID    0
+
+#define PORT_HIGH      1
+#define PORT_LOW       0 
+
+#define GPIO_OTYPE     GPIO_OTYPE_PP
+#ifndef GPIO_SELECT_PDOWN
+#define GPIO_PULLMODE  GPIO_PULLUP
+#else
+#define GPIO_PULLMODE  GPIO_PULLDOWN
+#endif
+
+#define BUFFERSIZE      140
+
+#define INHNO_SPI   IRQ_VECTOR_SPI1	/* 割込みハンドラ番号 */
+#define INTNO_SPI   IRQ_VECTOR_SPI1	/* 割込み番号 */
+#define INTPRI_SPI  -4          /* 割込み優先度 */
+#define INTATR_SPI  TA_EDGE     /* 割込み属性 */
+
+#define INHNO_DMARX   IRQ_VECTOR_DMA2_STREAM2	/* 割込みハンドラ番号 */
+#define INTNO_DMARX   IRQ_VECTOR_DMA2_STREAM2	/* 割込み番号 */
+#define INTPRI_DMARX  -4          /* 割込み優先度 */
+#define INTATR_DMARX  TA_EDGE     /* 割込み属性 */
+
+#define INHNO_DMATX   IRQ_VECTOR_DMA2_STREAM3	/* 割込みハンドラ番号 */
+#define INTNO_DMATX   IRQ_VECTOR_DMA2_STREAM3	/* 割込み番号 */
+#define INTPRI_DMATX  -4          /* 割込み優先度 */
+#define INTATR_DMATX  TA_EDGE     /* 割込み属性 */
+
+
+#define INHNO_USBFS   IRQ_VECTOR_OTG_FS	/* 割込みハンドラ番号 */
+#define INTNO_USBFS   IRQ_VECTOR_OTG_FS	/* 割込み番号 */
+#define INTPRI_USBFS  -5			/* 割込み優先度 */
+#define INTATR_USBFS  0				/* 割込み属性 */
+
+#define INHNO_FSWKUP  IRQ_VECTOR_OTG_FS_WKUP	/* 割込みハンドラ番号 */
+#define INTNO_FSWKUP  IRQ_VECTOR_OTG_FS_WKUP	/* 割込み番号 */
+#define INTPRI_FSWKUP -10			/* 割込み優先度 */
+#define INTATR_FSWKUP 0				/* 割込み属性 */
+
+
+#define INHNO_ADC     IRQ_VECTOR_ADC	/* 割込みハンドラ番号 */
+#define INTNO_ADC     IRQ_VECTOR_ADC	/* 割込み番号 */
+#define INTPRI_ADC    -5          /* 割込み優先度 */
+#define INTATR_ADC    0           /* 割込み属性 */
+
+#define INHNO_DMAADC  IRQ_VECTOR_DMA2_STREAM0	/* 割込みハンドラ番号 */
+#define INTNO_DMAADC  IRQ_VECTOR_DMA2_STREAM0	/* 割込み番号 */
+#define INTPRI_DMAADC -4          /* 割込み優先度 */
+#define INTATR_DMAADC TA_EDGE     /* 割込み属性 */
+
+/* Definition for ADCx's Channel */
+#define ADCx_CHANNEL                    ADC_CHANNEL_9
+
+/* Definition for ADCx Channel Pin */
+#define ADCx_CHANNEL_GPIO_PORT          TADR_GPIOF_BASE
+#define ADCx_CHANNEL_PINNO              3
+
+#define NUM_USBH_EVT1   64
+#define NUM_USBH_EVT2   16
+
+#define NUM_JSPOSITION 6
+
+#define JS_OFF      0x01
+#define JS_ON       0x02
+#define JS_UP       0x04
+#define JS_DOWN     0x08
+#define JS_LEFT     0x10
+#define JS_RIGHT    0x20
+#define JS_MASK     0x3F
+
+#define CS_PORT     10
+#define RST_PORT    9
+#define RS_PORT     8
+#define CS2_PORT    4
+
+#define cs_set(sw)  digitalWrite(CS_PORT, sw)
+#define rs_set(sw)  digitalWrite(RS_PORT, sw)
+#define rst_set(sw) digitalWrite(RST_PORT, sw)
+#define cs2_set(sw) digitalWrite(CS2_PORT, sw)
+
+#ifndef TOPPERS_MACRO_ONLY
+
+/*
+ *  ヒープ領域の設定
+ */
+extern uint32_t heap_param[2];
+
+/*
+ *  関数のプロトタイプ宣言
+ */
+extern void	main_task(intptr_t exinf);
+extern void stick_task(intptr_t exinf);
+
+extern void heap_init(intptr_t exinf);
+extern void sw_int(void);
+extern void device_info_init(intptr_t exinf);
+
+
+#endif /* TOPPERS_MACRO_ONLY */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/OBJ/STM32F767NUCLEO144_GCC/LCD/topamelogo.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/OBJ/STM32F767NUCLEO144_GCC/LCD/topamelogo.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/OBJ/STM32F767NUCLEO144_GCC/LCD/topamelogo.h	(revision 457)
@@ -0,0 +1,798 @@
+const unsigned char topamelogo[12726] = {
+	 0x42, 0x4d, 0xd6, 0x23, 0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 
+	 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x42, 0x00,  0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xfd,  0xff, 0xff, 0xfd, 0xff, 0xff, 0xfd, 0xff, 0xff, 
+	 0xfd, 0xff, 0xff, 0xfd, 0xff, 0xff, 0xfd, 0xff,  0xff, 0xfd, 0xff, 0xff, 0xfd, 0xff, 0xff, 0xfd, 
+	 0xff, 0xff, 0xfd, 0xff, 0xff, 0xfd, 0xff, 0xff,  0xfd, 0xff, 0xff, 0xfd, 0xff, 0xff, 0xfd, 0xff, 
+	 0xff, 0xfd, 0xff, 0xff, 0xfd, 0xff, 0xff, 0xff,  0xff, 0xf9, 0xf7, 0xfb, 0xff, 0xff, 0xff, 0xe3, 
+	 0xe1, 0xe5, 0xff, 0xfd, 0xff, 0xff, 0xff, 0xff,  0xef, 0xef, 0xf3, 0xff, 0xff, 0xff, 0xff, 0xfd, 
+	 0xff, 0xff, 0xfd, 0xff, 0xff, 0xfd, 0xff, 0xff,  0xfd, 0xff, 0xff, 0xfd, 0xff, 0xff, 0xfd, 0xff, 
+	 0xff, 0xfd, 0xff, 0xff, 0xfd, 0xff, 0xfd, 0xfd,  0xff, 0xfd, 0xfd, 0xff, 0xfd, 0xfb, 0xff, 0xfd, 
+	 0xfb, 0xff, 0xfd, 0xfd, 0xff, 0xfd, 0xfd, 0xff,  0xff, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfd, 
+	 0xff, 0xff, 0xfd, 0xff, 0xff, 0xfd, 0xff, 0xff,  0xfd, 0xff, 0xff, 0xfd, 0xff, 0xff, 0xfd, 0xff, 
+	 0xff, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfd,  0xff, 0xff, 0xfd, 0xff, 0xff, 0xfd, 0xff, 0xff, 
+	 0xfd, 0xff, 0xff, 0xfd, 0xff, 0xff, 0xfd, 0xff,  0xff, 0xfd, 0xff, 0xff, 0xfd, 0xff, 0xff, 0xfd, 
+	 0xff, 0xff, 0xfd, 0xff, 0xff, 0xfd, 0xff, 0xff,  0xfd, 0xff, 0xff, 0xfd, 0xff, 0xff, 0xfd, 0xff, 
+	 0xff, 0xfd, 0xff, 0xff, 0xfd, 0xff, 0xfd, 0xfd,  0xff, 0xfd, 0xfb, 0xff, 0xf1, 0xf1, 0xf5, 0x4f, 
+	 0x4d, 0x51, 0xc5, 0xc3, 0xc7, 0xf9, 0xf7, 0xfb,  0xff, 0xff, 0xff, 0xfb, 0xfb, 0xff, 0xff, 0xfd, 
+	 0xff, 0xff, 0xfd, 0xff, 0xff, 0xfd, 0xff, 0xff,  0xfd, 0xff, 0xff, 0xfd, 0xff, 0xff, 0xfd, 0xff, 
+	 0xff, 0xfd, 0xff, 0xff, 0xfd, 0xff, 0xfd, 0xfd,  0xff, 0xfd, 0xfd, 0xff, 0xfd, 0xfb, 0xff, 0xfd, 
+	 0xfb, 0xff, 0xfd, 0xfd, 0xff, 0xfd, 0xfd, 0xff,  0xff, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfd, 
+	 0xff, 0xff, 0xfd, 0xff, 0xff, 0xfd, 0xff, 0xff,  0xfd, 0xff, 0xff, 0xfd, 0xff, 0xff, 0xfd, 0xff, 
+	 0xff, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfd, 
+	 0xff, 0xff, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf5,  0xf9, 0xff, 0xfd, 0xff, 0xbb, 0xbb, 0xbd, 0x61, 
+	 0x61, 0x63, 0xc9, 0x93, 0x9d, 0xff, 0xe1, 0xeb,  0xe9, 0xff, 0xff, 0xe9, 0xff, 0xff, 0xff, 0xf9, 
+	 0xff, 0xff, 0xfb, 0xff, 0xff, 0xf9, 0xff, 0xff,  0xef, 0xf5, 0xff, 0xfb, 0xff, 0xff, 0xfb, 0xff, 
+	 0xf3, 0xff, 0xff, 0xf3, 0xff, 0xff, 0xff, 0xf9,  0xfd, 0xff, 0xfd, 0xff, 0xf7, 0xed, 0xf1, 0xff, 
+	 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf9, 0xfd,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfd, 
+	 0xff, 0xff, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xfd, 0xff, 0xff, 0xff, 0xfd,  0xff, 0xff, 0xfd, 0xff, 0x17, 0x17, 0x19, 0x29, 
+	 0x29, 0x2b, 0x35, 0x00, 0x09, 0xff, 0xf7, 0xff,  0xe9, 0xff, 0xff, 0xdb, 0xf5, 0xf3, 0xff, 0xfb, 
+	 0xff, 0xff, 0xed, 0xf3, 0xff, 0xfb, 0xff, 0xff,  0xfb, 0xff, 0xff, 0xf7, 0xfd, 0xff, 0xf9, 0xff, 
+	 0xeb, 0xf9, 0xf9, 0xf3, 0xff, 0xff, 0xff, 0xf5,  0xf9, 0xff, 0xfd, 0xff, 0xc3, 0xb9, 0xbd, 0xed, 
+	 0xe3, 0xe7, 0xfd, 0xf7, 0xfb, 0xfb, 0xf7, 0xf9,  0xf5, 0xf5, 0xf7, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfd, 
+	 0xff, 0xff, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xfd, 0xff, 0xff, 0xfd, 0xff, 0xff, 0xff, 0xfb,  0xff, 0xc5, 0xb1, 0xb7, 0x5b, 0x5b, 0x5f, 0x3b, 
+	 0x3b, 0x3f, 0x55, 0x65, 0x65, 0xd5, 0xe5, 0xe7,  0xf1, 0xff, 0xff, 0xed, 0xff, 0xff, 0xff, 0xfd, 
+	 0xff, 0xff, 0xfd, 0xff, 0xeb, 0xff, 0xff, 0xe7,  0xfb, 0xfb, 0xff, 0xfd, 0xff, 0xf7, 0xf1, 0xf7, 
+	 0xfd, 0xff, 0xff, 0xef, 0xf1, 0xf5, 0xff, 0xfd,  0xff, 0x59, 0x4f, 0x53, 0x3f, 0x37, 0x3b, 0xff, 
+	 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf9, 0xfd,  0xff, 0xff, 0xff, 0xef, 0xef, 0xf1, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfd, 
+	 0xff, 0xff, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xfd, 0xff, 0xff, 
+	 0xfd, 0xfd, 0xff, 0xfd, 0xfd, 0xff, 0xff, 0xef,  0xf5, 0x45, 0x31, 0x37, 0x39, 0x39, 0x3d, 0x35, 
+	 0x35, 0x39, 0x31, 0x41, 0x43, 0x06, 0x15, 0x17,  0xdf, 0xef, 0xf1, 0xed, 0xfd, 0xff, 0xf9, 0xf1, 
+	 0xf5, 0xff, 0xfd, 0xff, 0xe9, 0xfd, 0xfd, 0xe3,  0xf7, 0xf7, 0xf1, 0xeb, 0xef, 0xff, 0xfd, 0xff, 
+	 0xf3, 0xf7, 0xf9, 0xf3, 0xf7, 0xf9, 0x4d, 0x41,  0x45, 0x61, 0x55, 0x59, 0x69, 0x5f, 0x63, 0xfd, 
+	 0xf3, 0xf7, 0xf9, 0xf3, 0xf7, 0xff, 0xfd, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfd, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xfd, 0xfd, 0xff, 
+	 0xfd, 0xfd, 0xff, 0xfd, 0xfd, 0xff, 0xff, 0xf9,  0xff, 0x5f, 0x43, 0x51, 0x6f, 0x2f, 0x41, 0x6f, 
+	 0x2f, 0x41, 0x3d, 0x43, 0x4b, 0x49, 0x4f, 0x57,  0xbb, 0xb7, 0xbf, 0xff, 0xfb, 0xff, 0xf7, 0xfd, 
+	 0xff, 0xf9, 0xff, 0xff, 0xff, 0xfb, 0xff, 0xff,  0xfb, 0xff, 0xff, 0xf3, 0xff, 0xff, 0xdf, 0xed, 
+	 0xe1, 0xdf, 0xe7, 0x4b, 0x49, 0x51, 0x53, 0x49,  0x4d, 0x3f, 0x35, 0x39, 0x6d, 0x65, 0x69, 0xff, 
+	 0xfd, 0xff, 0xfb, 0xf7, 0xf9, 0xfd, 0xf7, 0xfb,  0xff, 0xff, 0xff, 0xfd, 0xfd, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfd, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xfd, 0xfd, 0xff, 
+	 0xfd, 0xfd, 0xff, 0xfb, 0xfb, 0xfd, 0xff, 0xe9,  0xf5, 0x4d, 0x31, 0x3d, 0x79, 0x39, 0x4d, 0x77, 
+	 0x37, 0x49, 0x19, 0x1f, 0x27, 0x3d, 0x43, 0x49,  0x2b, 0x27, 0x2f, 0xff, 0xfd, 0xff, 0xf7, 0xfd, 
+	 0xff, 0xe9, 0xef, 0xf7, 0xf5, 0xe7, 0xf1, 0xfd,  0xef, 0xf9, 0xff, 0xf7, 0xff, 0x97, 0x6b, 0x7b, 
+	 0x4d, 0x4b, 0x53, 0x47, 0x45, 0x4d, 0x4b, 0x3f,  0x43, 0x4f, 0x45, 0x49, 0x9f, 0x95, 0x99, 0xff, 
+	 0xf5, 0xf9, 0xff, 0xfd, 0xff, 0xff, 0xfb, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xfd, 0xff, 0xff, 0xfd, 0xff, 0xff, 0xfb, 0xff, 
+	 0xfd, 0xfb, 0xfd, 0xfd, 0xfb, 0xfd, 0xc7, 0xad,  0xbb, 0x57, 0x3d, 0x4b, 0x49, 0x27, 0x37, 0x5f, 
+	 0x3d, 0x4d, 0x2f, 0x35, 0x3f, 0x47, 0x4d, 0x57,  0x71, 0x4d, 0x5d, 0x63, 0x3f, 0x4f, 0xf7, 0xfb, 
+	 0xff, 0xfb, 0xfd, 0xff, 0xff, 0xf9, 0xff, 0xe1,  0xc1, 0xd1, 0x0b, 0x11, 0x19, 0x4d, 0x53, 0x5d, 
+	 0x3f, 0x43, 0x4b, 0x39, 0x3d, 0x45, 0x37, 0x2d,  0x31, 0x53, 0x47, 0x4b, 0xd3, 0xc9, 0xcd, 0xfd, 
+	 0xf3, 0xf7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xfd, 0xff, 0xff, 0xfd, 0xff, 0xff, 0xfb, 0xff, 
+	 0xfd, 0xfb, 0xfd, 0xfd, 0xf9, 0xfd, 0xa3, 0x89,  0x97, 0x53, 0x3b, 0x49, 0x63, 0x43, 0x51, 0x3f, 
+	 0x1d, 0x2d, 0xd7, 0xdd, 0xe7, 0x00, 0x04, 0x0b,  0x59, 0x35, 0x45, 0x73, 0x4f, 0x5f, 0x97, 0x99, 
+	 0xa3, 0xf1, 0xf5, 0xff, 0x75, 0x57, 0x65, 0x7f,  0x5f, 0x6f, 0x49, 0x51, 0x59, 0x4d, 0x55, 0x5d, 
+	 0xb7, 0xbb, 0xc5, 0x43, 0x45, 0x4f, 0x45, 0x39,  0x3d, 0x4f, 0x43, 0x47, 0xff, 0xfb, 0xff, 0xff, 
+	 0xfd, 0xff, 0xff, 0xff, 0xff, 0xf3, 0xef, 0xf1,  0xff, 0xff, 0xff, 0xfb, 0xfb, 0xfd, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfd, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xfd, 0xff, 0xff,  0xfb, 0xff, 0xff, 0xff, 0xff, 0xfd, 0xf9, 0xfd, 
+	 0xff, 0xfd, 0xff, 0xfb, 0xf9, 0xfb, 0x79, 0x69,  0x75, 0x5b, 0x4b, 0x57, 0x00, 0x59, 0x51, 0x71, 
+	 0xe1, 0xd9, 0xa7, 0xe7, 0xe7, 0x00, 0x09, 0x07,  0x6d, 0x37, 0x4b, 0x63, 0x2f, 0x41, 0x4f, 0x41, 
+	 0x4d, 0x35, 0x27, 0x33, 0x3b, 0x55, 0x5b, 0x31,  0x4b, 0x51, 0x00, 0x4b, 0x3d, 0x61, 0xf9, 0xeb, 
+	 0xaf, 0xbb, 0xc3, 0x3d, 0x47, 0x4f, 0x49, 0x3f,  0x43, 0x27, 0x1d, 0x21, 0xff, 0xfd, 0xff, 0xff, 
+	 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xf9, 0xf9, 0xfb, 0xfd, 0xfd, 
+	 0xff, 0xfd, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xfd, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xfb, 0xff, 0xff, 0xff, 0xff, 0xf5,  0xf1, 0xf5, 0xf9, 0xf7, 0xf9, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xf5, 0xf3, 0xf5, 0x75, 0x65,  0x73, 0x45, 0x35, 0x41, 0x00, 0x39, 0x31, 0x7f, 
+	 0xed, 0xe5, 0x95, 0xd7, 0xd5, 0x00, 0x0f, 0x0d,  0x5d, 0x27, 0x3b, 0x61, 0x2d, 0x3f, 0x43, 0x35, 
+	 0x41, 0x4b, 0x3d, 0x49, 0x15, 0x2f, 0x35, 0x31,  0x4b, 0x51, 0x6f, 0xff, 0xf9, 0x4f, 0xe7, 0xd9, 
+	 0xbf, 0xcb, 0xd3, 0x3d, 0x47, 0x4f, 0x55, 0x4b,  0x4f, 0xb3, 0xa7, 0xab, 0xf3, 0xe9, 0xed, 0xff, 
+	 0xf9, 0xfd, 0xff, 0xff, 0xff, 0xfd, 0xf9, 0xfb,  0xef, 0xef, 0xf1, 0xff, 0xff, 0xff, 0xfd, 0xfd, 
+	 0xff, 0xfd, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xfd, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf9, 0xf7, 
+	 0xf9, 0xfb, 0xf9, 0xfb, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xfd, 0xf9, 0xfb, 0xff, 0xff, 0xff, 
+	 0xfd, 0xf9, 0xfb, 0xff, 0xfb, 0xff, 0x77, 0x65,  0x71, 0x63, 0x51, 0x5b, 0x53, 0xd1, 0xc5, 0x81, 
+	 0xff, 0xf3, 0xc5, 0xdf, 0xe1, 0x09, 0x23, 0x27,  0x65, 0x41, 0x4f, 0x67, 0x43, 0x51, 0x33, 0x1b, 
+	 0x27, 0x69, 0x51, 0x5d, 0x53, 0x55, 0x5d, 0x19,  0x1d, 0x25, 0x61, 0xf5, 0xe5, 0x4d, 0xe1, 0xd1, 
+	 0xab, 0xb3, 0xb9, 0x4b, 0x53, 0x59, 0x37, 0x2d,  0x31, 0xff, 0xfb, 0xff, 0xff, 0xf9, 0xfd, 0xff, 
+	 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xfb, 0xfb, 0xfd, 0xff, 0xff, 0xff, 0xfd, 0xfd, 
+	 0xff, 0xfd, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xfd, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xfd, 0xff, 0xff, 0xff, 
+	 0xff, 0xfd, 0xf9, 0xfd, 0xf5, 0xf1, 0xf3, 0xff,  0xf9, 0xfd, 0xff, 0xfd, 0xff, 0xff, 0xfd, 0xff, 
+	 0xfb, 0xf7, 0xf9, 0xff, 0xff, 0xff, 0x7d, 0x6b,  0x77, 0x73, 0x61, 0x6d, 0x7b, 0xf9, 0xed, 0x00, 
+	 0x61, 0x55, 0x9b, 0xb3, 0xb7, 0x95, 0xaf, 0xb1,  0xf5, 0xcf, 0xdd, 0xff, 0xdf, 0xed, 0xff, 0xf9, 
+	 0xff, 0xfb, 0xe1, 0xed, 0xbd, 0xc1, 0xc7, 0x91,  0x95, 0x9d, 0x00, 0x75, 0x65, 0x75, 0xff, 0xf9, 
+	 0x79, 0x81, 0x87, 0x31, 0x39, 0x41, 0x5f, 0x53,  0x57, 0xf5, 0xe9, 0xed, 0xff, 0xfd, 0xff, 0xff, 
+	 0xfd, 0xff, 0xf7, 0xf3, 0xf5, 0xfb, 0xf5, 0xf9,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfd, 0xfd, 
+	 0xff, 0xfd, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xfd, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xfd, 0xff, 0xff, 0xfd, 0xff, 0xf9, 0xf5, 
+	 0xf9, 0xff, 0xff, 0xff, 0xfd, 0xf9, 0xfb, 0xff,  0xfd, 0xff, 0xff, 0xff, 0xff, 0xf9, 0xf1, 0xf5, 
+	 0xfb, 0xf3, 0xf7, 0xff, 0xf9, 0xfd, 0xaf, 0x8d,  0x95, 0x39, 0x17, 0x21, 0xbd, 0xe7, 0xe3, 0xd3, 
+	 0xfd, 0xf9, 0xff, 0xe3, 0xed, 0xff, 0xf7, 0xff,  0xfb, 0xff, 0xff, 0xfb, 0xff, 0xff, 0xff, 0xfb, 
+	 0xff, 0xff, 0xf3, 0xf9, 0xff, 0xf1, 0xfb, 0xff,  0xf9, 0xff, 0xdd, 0xff, 0xfd, 0x8f, 0xb1, 0xaf, 
+	 0x2d, 0x25, 0x29, 0x4b, 0x43, 0x47, 0xfb, 0xef,  0xf3, 0xf7, 0xeb, 0xef, 0xfb, 0xf1, 0xf5, 0xff, 
+	 0xf7, 0xfb, 0xff, 0xfd, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xef, 0xef, 0xf1, 0xfd, 0xfd, 
+	 0xff, 0xfd, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xfd, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xfd, 0xff, 0xff, 0xfd, 0xff, 0xfb, 0xf7, 
+	 0xfb, 0xff, 0xff, 0xff, 0xff, 0xfb, 0xff, 0xf1,  0xeb, 0xef, 0xff, 0xfd, 0xff, 0xff, 0xfb, 0xfd, 
+	 0xff, 0xff, 0xff, 0xfb, 0xf5, 0xf7, 0x3d, 0x1b,  0x25, 0x85, 0x63, 0x6d, 0xc9, 0xf3, 0xef, 0xdd, 
+	 0xff, 0xff, 0xff, 0xf1, 0xfb, 0xff, 0xf9, 0xff,  0xf3, 0xf9, 0xfb, 0xef, 0xf3, 0xf7, 0xff, 0xfb, 
+	 0xff, 0xff, 0xfb, 0xff, 0xff, 0xf1, 0xfb, 0xff,  0xf5, 0xff, 0xcb, 0xed, 0xeb, 0xe1, 0xff, 0xff, 
+	 0x89, 0x7f, 0x83, 0x1d, 0x13, 0x19, 0xfd, 0xf1,  0xf5, 0xff, 0xfd, 0xff, 0xff, 0xf5, 0xf9, 0xff, 
+	 0xfd, 0xff, 0xfb, 0xf5, 0xf9, 0xfb, 0xf5, 0xf9,  0xff, 0xff, 0xff, 0xfd, 0xfd, 0xff, 0xfd, 0xfd, 
+	 0xff, 0xfd, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xfd, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xfd, 0xfd, 0xff,  0xff, 0xfd, 0xff, 0xff, 0xfb, 0xff, 0xff, 0xff, 
+	 0xff, 0xe1, 0xdd, 0xe1, 0xff, 0xff, 0xff, 0xc3,  0xbd, 0xc1, 0x79, 0x71, 0x75, 0x63, 0x5d, 0x5f, 
+	 0x9b, 0x95, 0x97, 0xb1, 0xa9, 0xad, 0x73, 0x41,  0x4b, 0xe7, 0xb3, 0xbd, 0xdd, 0xf9, 0xf5, 0xe1, 
+	 0xfb, 0xf9, 0xff, 0xf9, 0xfd, 0xff, 0xf5, 0xf9,  0xdd, 0xff, 0xff, 0xdb, 0xff, 0xff, 0xff, 0xf9, 
+	 0xfd, 0xf9, 0xef, 0xf3, 0xfb, 0xff, 0xff, 0xf1,  0xf7, 0xf7, 0xff, 0xff, 0xff, 0xfb, 0xfb, 0xfd, 
+	 0xbf, 0xa3, 0xa9, 0x65, 0x49, 0x51, 0xe3, 0xd7,  0xdb, 0xf5, 0xe9, 0xed, 0xbf, 0xb5, 0xb9, 0xd3, 
+	 0xc9, 0xcd, 0xf3, 0xed, 0xf1, 0xff, 0xff, 0xff,  0xf1, 0xf1, 0xf3, 0xfd, 0xfd, 0xff, 0xfd, 0xfd, 
+	 0xff, 0xfd, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xfd, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfd, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xfd, 0xfd, 0xff,  0xff, 0xfb, 0xff, 0xff, 0xfb, 0xff, 0xc1, 0xbf, 
+	 0xc1, 0x11, 0x0d, 0x11, 0x5b, 0x55, 0x59, 0x53,  0x4f, 0x51, 0x51, 0x49, 0x4d, 0x57, 0x51, 0x53, 
+	 0x57, 0x4f, 0x53, 0x2d, 0x27, 0x29, 0x6f, 0x3d,  0x47, 0xef, 0xbb, 0xc5, 0xdd, 0xf9, 0xf5, 0xe7, 
+	 0xff, 0xff, 0xff, 0xfd, 0xff, 0xff, 0xfd, 0xff,  0xd5, 0xff, 0xf9, 0xdd, 0xff, 0xff, 0xff, 0xfd, 
+	 0xff, 0xff, 0xfd, 0xff, 0xf7, 0xfd, 0xff, 0xf5,  0xfb, 0xfd, 0xfb, 0xfb, 0xfd, 0xeb, 0xeb, 0xed, 
+	 0xd9, 0xbd, 0xc3, 0x61, 0x45, 0x4d, 0x73, 0x69,  0x6d, 0x61, 0x55, 0x59, 0x5b, 0x51, 0x55, 0x55, 
+	 0x4b, 0x4f, 0x53, 0x4f, 0x51, 0x45, 0x41, 0x43,  0x6d, 0x6d, 0x6f, 0xf9, 0xf9, 0xfb, 0xfd, 0xfd, 
+	 0xff, 0xfd, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xfd, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf3, 0xff,  0xfb, 0xef, 0xfd, 0xf7, 0xfb, 0xfd, 0xfb, 0xff, 
+	 0xff, 0xff, 0xf3, 0xe3, 0xf3, 0xff, 0xf5, 0xff,  0xdb, 0xc7, 0xe3, 0x23, 0x0f, 0x29, 0x57, 0x4b, 
+	 0x63, 0x4f, 0x43, 0x5b, 0x47, 0x43, 0x4f, 0x3f,  0x3b, 0x49, 0x97, 0x8f, 0xa1, 0xa5, 0x9d, 0xaf, 
+	 0xa7, 0x95, 0xb7, 0x1f, 0x0d, 0x2f, 0x47, 0x39,  0x49, 0xcf, 0xc1, 0xd3, 0xe7, 0xff, 0xf1, 0xef, 
+	 0xff, 0xf7, 0xe3, 0xfb, 0xef, 0xef, 0xff, 0xfb,  0xff, 0xed, 0xff, 0xff, 0xf5, 0xff, 0xff, 0xeb, 
+	 0xff, 0xff, 0xf5, 0xff, 0xef, 0xff, 0xfb, 0xe7,  0xff, 0xf3, 0xef, 0xff, 0xf7, 0xe3, 0xfb, 0xeb, 
+	 0xdb, 0xcd, 0xdf, 0x45, 0x39, 0x49, 0x77, 0x6b,  0x85, 0x9f, 0x93, 0xad, 0xbb, 0xb3, 0xc5, 0x7d, 
+	 0x77, 0x87, 0x45, 0x3d, 0x51, 0x3f, 0x35, 0x49,  0x4b, 0x37, 0x53, 0x57, 0x43, 0x61, 0x5d, 0x43, 
+	 0x5d, 0xf7, 0xdd, 0xf7, 0xfd, 0xed, 0xf5, 0xfd,  0xed, 0xf5, 0xf7, 0xf9, 0xf7, 0xfd, 0xff, 0xfd, 
+	 0xe7, 0xf7, 0xf3, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf5, 0xff,  0xfd, 0xf3, 0xff, 0xfb, 0xf1, 0xf3, 0xf1, 0xfd, 
+	 0xff, 0xfd, 0xff, 0xf7, 0xff, 0x5f, 0x4f, 0x5f,  0x41, 0x2b, 0x47, 0x4b, 0x37, 0x51, 0x3b, 0x2f, 
+	 0x47, 0x3f, 0x33, 0x4b, 0xa9, 0xa5, 0xb1, 0xef,  0xeb, 0xf9, 0xff, 0xfb, 0xff, 0xfd, 0xf5, 0xff, 
+	 0xff, 0xed, 0xff, 0x51, 0x3f, 0x5f, 0x49, 0x3b,  0x4b, 0xcb, 0xbd, 0xcd, 0xe5, 0xfd, 0xed, 0xd7, 
+	 0xf1, 0xe1, 0xef, 0xff, 0xfb, 0xef, 0xff, 0xfb,  0xff, 0xef, 0xff, 0xff, 0xf5, 0xff, 0xff, 0xf5, 
+	 0xff, 0xff, 0xf3, 0xff, 0xef, 0xff, 0xfb, 0xe9,  0xff, 0xf5, 0xd9, 0xf3, 0xe3, 0xef, 0xff, 0xf7, 
+	 0xc1, 0xb3, 0xc5, 0x55, 0x47, 0x57, 0x9f, 0x91,  0xad, 0xff, 0xf7, 0xff, 0xf5, 0xef, 0xff, 0xfd, 
+	 0xf7, 0xff, 0xe1, 0xd9, 0xeb, 0x3b, 0x31, 0x45,  0x51, 0x3d, 0x5b, 0x41, 0x2d, 0x49, 0x4f, 0x33, 
+	 0x4f, 0x47, 0x2d, 0x47, 0x87, 0x77, 0x7f, 0xff,  0xfb, 0xff, 0xef, 0xef, 0xed, 0xf5, 0xf7, 0xf5, 
+	 0xf3, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xed, 0xed, 0xf1, 0xff, 0xfb, 0xff, 0xff, 
+	 0xf5, 0xff, 0x4f, 0x33, 0x45, 0x65, 0x49, 0x5b,  0x51, 0x35, 0x47, 0x47, 0x2b, 0x3d, 0x55, 0x45, 
+	 0x51, 0xa7, 0x99, 0xa3, 0xf5, 0xf1, 0xf1, 0xff,  0xfb, 0xfb, 0xf5, 0xef, 0xf3, 0xf9, 0xf3, 0xf7, 
+	 0xff, 0xf3, 0xfd, 0x99, 0x8d, 0x97, 0x77, 0x43,  0x65, 0xb3, 0x7f, 0xa1, 0xff, 0xfd, 0xff, 0xff, 
+	 0xfd, 0xff, 0xfd, 0xff, 0xf9, 0xf3, 0xf7, 0xef,  0xff, 0xff, 0xfb, 0xff, 0xfd, 0xf9, 0xff, 0xf9, 
+	 0xf5, 0xff, 0xf5, 0xf1, 0xfd, 0xff, 0xf9, 0xff,  0xff, 0xfb, 0xff, 0xfd, 0xff, 0xed, 0xe3, 0xe7, 
+	 0xe9, 0xb5, 0xd7, 0x75, 0x43, 0x65, 0xd1, 0xc9,  0xd1, 0xf3, 0xe9, 0xf1, 0xff, 0xfb, 0xfd, 0xfb, 
+	 0xf7, 0xf9, 0xf7, 0xed, 0xf5, 0xfb, 0xf1, 0xf9,  0x51, 0x3b, 0x4b, 0x49, 0x33, 0x43, 0x55, 0x35, 
+	 0x47, 0x55, 0x35, 0x47, 0x57, 0x3d, 0x47, 0x7f,  0x63, 0x6f, 0xff, 0xf3, 0xf9, 0xfd, 0xef, 0xf5, 
+	 0xed, 0xed, 0xf5, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf5, 0xf3,  0xf7, 0xf5, 0xf5, 0xf9, 0xff, 0xef, 0xf9, 0x59, 
+	 0x49, 0x53, 0x55, 0x39, 0x4b, 0x4f, 0x33, 0x45,  0x51, 0x35, 0x47, 0x51, 0x35, 0x47, 0x85, 0x75, 
+	 0x81, 0xff, 0xf3, 0xfd, 0xff, 0xff, 0xff, 0xf5,  0xf1, 0xf1, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xfd, 0xf1, 0xfb, 0xe9, 0xdd, 0xe7, 0x71, 0x3f,  0x61, 0x79, 0x47, 0x69, 0xf1, 0xe7, 0xeb, 0xff, 
+	 0xfd, 0xff, 0xf1, 0xf7, 0xed, 0xf3, 0xf9, 0xef,  0xff, 0xff, 0xfb, 0xff, 0xfb, 0xf7, 0xff, 0xff, 
+	 0xfb, 0xff, 0xf9, 0xf5, 0xfd, 0xff, 0xf9, 0xfd,  0xff, 0xf9, 0xfd, 0xf3, 0xf7, 0xff, 0xfd, 0xff, 
+	 0xa3, 0x6f, 0x93, 0x67, 0x35, 0x57, 0xfb, 0xf1,  0xf9, 0xff, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xfb, 0xfd, 0xff, 0xf9, 0xff, 0xff, 0xfd, 0xff,  0xdb, 0xc3, 0xd3, 0x55, 0x3f, 0x4f, 0x51, 0x31, 
+	 0x43, 0x4f, 0x2f, 0x41, 0x59, 0x3d, 0x49, 0x65,  0x49, 0x55, 0x8f, 0x81, 0x87, 0xff, 0xfd, 0xff, 
+	 0xf3, 0xf3, 0xfb, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf9,  0xff, 0xff, 0xfb, 0xff, 0x81, 0x63, 0x77, 0x63, 
+	 0x45, 0x59, 0x5d, 0x37, 0x47, 0x4b, 0x27, 0x37,  0x55, 0x35, 0x39, 0x5f, 0x3f, 0x45, 0xf7, 0xe7, 
+	 0xe7, 0xff, 0xfd, 0xfd, 0xfb, 0xf7, 0xf9, 0xfd,  0xf7, 0xfb, 0xfb, 0xfb, 0xfd, 0xfd, 0xfd, 0xff, 
+	 0xfb, 0xf9, 0xf9, 0xfb, 0xf9, 0xf9, 0x35, 0x0b,  0x19, 0x63, 0x39, 0x47, 0xd5, 0xc5, 0xd5, 0xff, 
+	 0xf9, 0xff, 0xf5, 0xfb, 0xff, 0xf9, 0xff, 0xff,  0xf9, 0xfd, 0xf7, 0xff, 0xff, 0xfb, 0xfd, 0xff, 
+	 0xf9, 0xff, 0xff, 0xfb, 0xf5, 0xfb, 0xff, 0xf1,  0xf7, 0xfd, 0xff, 0xf7, 0xff, 0xf3, 0xe3, 0xf3, 
+	 0x65, 0x3b, 0x49, 0x49, 0x1d, 0x2b, 0xf9, 0xf9,  0xf9, 0xe7, 0xe7, 0xe7, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xf5, 0xf9, 0xfd, 0xf3, 0xf7,  0xff, 0xfb, 0xfb, 0x9d, 0x87, 0x87, 0x51, 0x2d, 
+	 0x33, 0x53, 0x2f, 0x35, 0x5f, 0x35, 0x45, 0x65,  0x3b, 0x4b, 0x61, 0x43, 0x55, 0xd9, 0xbb, 0xcf, 
+	 0xff, 0xef, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf9,  0xff, 0xeb, 0xdb, 0xe7, 0x61, 0x43, 0x57, 0x57, 
+	 0x39, 0x4d, 0x4f, 0x29, 0x39, 0x5f, 0x39, 0x49,  0x61, 0x41, 0x47, 0x89, 0x69, 0x6d, 0xff, 0xf5, 
+	 0xf5, 0xff, 0xf5, 0xf5, 0xff, 0xfd, 0xff, 0xff,  0xff, 0xff, 0xfb, 0xfb, 0xfd, 0xf9, 0xf9, 0xfb, 
+	 0xfb, 0xf9, 0xf9, 0xf5, 0xf3, 0xf3, 0x87, 0x5d,  0x6b, 0x59, 0x2d, 0x3b, 0x87, 0x77, 0x89, 0xf3, 
+	 0xe3, 0xf5, 0xf5, 0xfb, 0xff, 0xf9, 0xff, 0xff,  0xfb, 0xff, 0xf7, 0xff, 0xff, 0xfb, 0xf9, 0xfd, 
+	 0xf7, 0xff, 0xff, 0xfb, 0xf7, 0xfd, 0xff, 0xf7,  0xfd, 0xff, 0xfd, 0xed, 0xff, 0x71, 0x61, 0x73, 
+	 0x63, 0x39, 0x47, 0xaf, 0x85, 0x91, 0xff, 0xff,  0xff, 0xf9, 0xf9, 0xf9, 0xeb, 0xe9, 0xed, 0xfd, 
+	 0xfd, 0xff, 0xf9, 0xef, 0xf3, 0xff, 0xfd, 0xff,  0xff, 0xfd, 0xff, 0xcf, 0xb9, 0xbb, 0x6b, 0x47, 
+	 0x4d, 0x51, 0x2d, 0x33, 0x61, 0x39, 0x47, 0x51,  0x27, 0x37, 0x4d, 0x2f, 0x41, 0x67, 0x49, 0x5d, 
+	 0xff, 0xf9, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf5,  0xff, 0x6b, 0x59, 0x63, 0x5b, 0x3d, 0x51, 0x45, 
+	 0x27, 0x3b, 0x47, 0x23, 0x31, 0x5d, 0x39, 0x47,  0x4d, 0x33, 0x2f, 0xab, 0x91, 0x8d, 0xff, 0xf3, 
+	 0xf7, 0xff, 0xfd, 0xff, 0xfb, 0xf7, 0xff, 0xeb,  0xe7, 0xff, 0xf3, 0xf5, 0xff, 0xf3, 0xf5, 0xff, 
+	 0xed, 0xf5, 0xff, 0xf1, 0xf9, 0xff, 0xe1, 0xe3,  0xff, 0x4d, 0x4d, 0x6d, 0x21, 0x21, 0x6d, 0x75, 
+	 0x75, 0xc3, 0x75, 0x79, 0xd7, 0x73, 0x77, 0xd5,  0x65, 0x6f, 0xbd, 0x47, 0x51, 0x9f, 0x5d, 0x65, 
+	 0xb5, 0x4b, 0x55, 0xa3, 0x6f, 0x73, 0xd1, 0x7d,  0x81, 0xdf, 0x5b, 0x5d, 0xa9, 0x37, 0x37, 0x83, 
+	 0x41, 0x41, 0x61, 0xf1, 0xf3, 0xff, 0xdd, 0xe5,  0xff, 0xf1, 0xf9, 0xff, 0xf3, 0xf5, 0xff, 0xe7, 
+	 0xe9, 0xff, 0xff, 0xf7, 0xff, 0xf5, 0xef, 0xff,  0xff, 0xfb, 0xfd, 0xb5, 0xa3, 0xa5, 0x4b, 0x2d, 
+	 0x2b, 0x5b, 0x3d, 0x3b, 0x53, 0x29, 0x3b, 0x63,  0x39, 0x4d, 0x4b, 0x2d, 0x41, 0x61, 0x41, 0x57, 
+	 0xb7, 0xa9, 0xaf, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfb, 0xe9,  0xf5, 0x31, 0x1f, 0x29, 0x55, 0x37, 0x4b, 0x49, 
+	 0x29, 0x3f, 0x69, 0x45, 0x53, 0x51, 0x2d, 0x3b,  0x47, 0x2b, 0x29, 0x9b, 0x7f, 0x7d, 0xff, 0xf5, 
+	 0xf9, 0xf7, 0xeb, 0xef, 0xf3, 0xef, 0xff, 0xf7,  0xf3, 0xff, 0xf3, 0xf5, 0xff, 0xad, 0xad, 0xd5, 
+	 0x53, 0x5b, 0x75, 0x27, 0x2d, 0x49, 0x4b, 0x4b,  0x6b, 0x5b, 0x5b, 0x7b, 0x63, 0x63, 0xaf, 0x7d, 
+	 0x7d, 0xcb, 0x6d, 0x71, 0xcf, 0x55, 0x5b, 0xb7,  0x5b, 0x65, 0xb3, 0x65, 0x6d, 0xbd, 0x55, 0x5f, 
+	 0xad, 0x5f, 0x69, 0xb7, 0x71, 0x75, 0xd3, 0x61,  0x65, 0xc3, 0x79, 0x79, 0xc7, 0x53, 0x53, 0x9f, 
+	 0x5b, 0x5b, 0x7b, 0x43, 0x43, 0x63, 0x29, 0x2f,  0x4f, 0x69, 0x71, 0x8f, 0x6d, 0x6f, 0x97, 0xd9, 
+	 0xdb, 0xff, 0xf1, 0xeb, 0xff, 0xf1, 0xe9, 0xff,  0xe5, 0xd5, 0xd7, 0x63, 0x51, 0x55, 0x55, 0x35, 
+	 0x35, 0x59, 0x39, 0x39, 0x61, 0x37, 0x49, 0x4f,  0x25, 0x37, 0x59, 0x39, 0x4f, 0x4d, 0x2d, 0x43, 
+	 0x37, 0x29, 0x2f, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfb, 0xf5,  0xf5, 0x5d, 0x57, 0x57, 0x51, 0x3b, 0x4d, 0x49, 
+	 0x35, 0x45, 0x45, 0x2b, 0x35, 0x57, 0x3d, 0x47,  0x53, 0x47, 0x3d, 0x5b, 0x4f, 0x45, 0xd9, 0xd5, 
+	 0xe9, 0xaf, 0xab, 0xbf, 0x2f, 0x27, 0x7b, 0x85,  0x7f, 0xd3, 0x77, 0x75, 0xdd, 0x4b, 0x4b, 0xb3, 
+	 0x5d, 0x69, 0xb9, 0x5d, 0x69, 0xb9, 0x4f, 0x59,  0xd5, 0x37, 0x43, 0xbf, 0x41, 0x3b, 0xdf, 0x47, 
+	 0x41, 0xe5, 0x41, 0x3b, 0xe9, 0x3b, 0x35, 0xe3,  0x3f, 0x47, 0xdb, 0x39, 0x41, 0xd7, 0x3b, 0x43, 
+	 0xd7, 0x35, 0x3d, 0xd3, 0x4d, 0x47, 0xf5, 0x31,  0x2b, 0xd9, 0x4b, 0x45, 0xe9, 0x45, 0x3f, 0xe3, 
+	 0x41, 0x4d, 0xc9, 0x43, 0x4d, 0xc9, 0x5d, 0x65,  0xc1, 0x5f, 0x69, 0xc5, 0x33, 0x33, 0x99, 0x87, 
+	 0x87, 0xed, 0xbd, 0xb9, 0xff, 0x65, 0x63, 0xab,  0x45, 0x3d, 0x4d, 0x55, 0x4d, 0x5d, 0x5f, 0x49, 
+	 0x47, 0x4f, 0x39, 0x37, 0x49, 0x29, 0x3d, 0x53,  0x33, 0x47, 0x4f, 0x39, 0x4b, 0x43, 0x2d, 0x41, 
+	 0x51, 0x4f, 0x49, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc7, 0xc1,  0xc1, 0x53, 0x4d, 0x4d, 0x4d, 0x37, 0x49, 0x45, 
+	 0x31, 0x41, 0x71, 0x55, 0x61, 0x41, 0x25, 0x31,  0x3f, 0x33, 0x29, 0x83, 0x77, 0x6d, 0xf1, 0xed, 
+	 0xff, 0xf9, 0xf5, 0xff, 0x9f, 0x99, 0xed, 0x51,  0x49, 0x9d, 0x5d, 0x5b, 0xc5, 0x51, 0x51, 0xb9, 
+	 0x51, 0x5d, 0xad, 0x4d, 0x59, 0xa9, 0x43, 0x4f,  0xcb, 0x3f, 0x49, 0xc5, 0x57, 0x51, 0xf5, 0x3f, 
+	 0x39, 0xdd, 0x31, 0x2d, 0xd9, 0x45, 0x3f, 0xed,  0x31, 0x3b, 0xcf, 0x45, 0x4d, 0xe3, 0x3d, 0x45, 
+	 0xdb, 0x3d, 0x45, 0xd9, 0x3f, 0x39, 0xe7, 0x49,  0x43, 0xf1, 0x47, 0x3f, 0xe3, 0x43, 0x3d, 0xe1, 
+	 0x45, 0x4f, 0xcb, 0x3b, 0x47, 0xc3, 0x47, 0x51,  0xad, 0x49, 0x53, 0xad, 0x57, 0x57, 0xbd, 0x69, 
+	 0x69, 0xcf, 0x4b, 0x45, 0x8f, 0x89, 0x85, 0xcd,  0xfd, 0xf5, 0xff, 0xf3, 0xed, 0xfd, 0xaf, 0x9b, 
+	 0x97, 0x81, 0x6b, 0x69, 0x57, 0x35, 0x4b, 0x61,  0x41, 0x55, 0x41, 0x2b, 0x3d, 0x53, 0x3d, 0x51, 
+	 0x59, 0x57, 0x51, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfd, 0xff,  0xfb, 0x57, 0x5d, 0x55, 0x31, 0x23, 0x35, 0x55, 
+	 0x47, 0x59, 0xc7, 0xb5, 0xbb, 0xff, 0xf7, 0xff,  0xff, 0xff, 0xf7, 0xff, 0xff, 0xf3, 0xe7, 0xe7, 
+	 0xff, 0x3d, 0x3d, 0x61, 0x63, 0x59, 0xd9, 0x59,  0x51, 0xd1, 0x49, 0x43, 0xe3, 0x4f, 0x4b, 0xe9, 
+	 0x41, 0x4d, 0xcd, 0x35, 0x41, 0xc1, 0x37, 0x33,  0xdf, 0x3f, 0x3b, 0xe5, 0x47, 0x3f, 0xdf, 0x3d, 
+	 0x35, 0xd5, 0x29, 0x41, 0xbb, 0x45, 0x5b, 0xd5,  0x49, 0x8b, 0xd9, 0x00, 0x1f, 0x6f, 0x00, 0x41, 
+	 0x8f, 0x3b, 0x7d, 0xcb, 0x3f, 0x53, 0xcd, 0x2b,  0x41, 0xbb, 0x47, 0x3f, 0xdf, 0x39, 0x31, 0xd1, 
+	 0x3b, 0x35, 0xe1, 0x45, 0x41, 0xed, 0x47, 0x4f,  0xdd, 0x35, 0x3f, 0xcd, 0x3b, 0x37, 0xd3, 0x37, 
+	 0x33, 0xcf, 0x67, 0x61, 0xd3, 0x5d, 0x57, 0xc9,  0x51, 0x4d, 0x69, 0xf3, 0xef, 0xff, 0xff, 0xff, 
+	 0xfd, 0xff, 0xf3, 0xf1, 0xfd, 0xe1, 0xfb, 0xc1,  0xa7, 0xbf, 0x59, 0x4b, 0x5f, 0x59, 0x49, 0x5f, 
+	 0x4f, 0x5d, 0x49, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe5, 0xeb,  0xe5, 0xd5, 0xdb, 0xd5, 0xe7, 0xd9, 0xeb, 0xff, 
+	 0xf9, 0xff, 0xff, 0xf7, 0xff, 0xff, 0xed, 0xf3,  0xfd, 0xf9, 0xeb, 0xf1, 0xed, 0xe1, 0x21, 0x21, 
+	 0x45, 0x6f, 0x6f, 0x93, 0x5b, 0x53, 0xd1, 0x51,  0x49, 0xc9, 0x3f, 0x3b, 0xd9, 0x3b, 0x37, 0xd5, 
+	 0x43, 0x4f, 0xcf, 0x49, 0x55, 0xd5, 0x47, 0x41,  0xed, 0x49, 0x43, 0xef, 0x3b, 0x33, 0xd3, 0x53, 
+	 0x4b, 0xeb, 0x45, 0x59, 0xd3, 0x23, 0x3b, 0xb5,  0x65, 0xa7, 0xf7, 0x9b, 0xdd, 0xff, 0x89, 0xcb, 
+	 0xff, 0x61, 0xa3, 0xf3, 0x43, 0x59, 0xd3, 0x4d,  0x61, 0xdb, 0x43, 0x3b, 0xdb, 0x53, 0x4b, 0xeb, 
+	 0x43, 0x3f, 0xe9, 0x41, 0x3b, 0xe7, 0x3b, 0x43,  0xd3, 0x3f, 0x47, 0xd7, 0x49, 0x43, 0xe1, 0x4b, 
+	 0x47, 0xe5, 0x4f, 0x4b, 0xbb, 0x55, 0x4f, 0xbf,  0x41, 0x3d, 0x59, 0x29, 0x25, 0x41, 0xed, 0xdf, 
+	 0xdd, 0xff, 0xf3, 0xf1, 0xff, 0xf5, 0xff, 0xff,  0xf1, 0xff, 0xff, 0xf9, 0xff, 0xef, 0xdf, 0xf3, 
+	 0xcb, 0xd7, 0xc3, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf5, 0xfd,  0xf9, 0xfb, 0xff, 0xff, 0xfb, 0xed, 0xff, 0xf5, 
+	 0xe7, 0xff, 0xff, 0xf9, 0xff, 0xff, 0xfb, 0xff,  0xff, 0xfd, 0xeb, 0x21, 0x1d, 0x0b, 0x37, 0x33, 
+	 0x5d, 0x51, 0x4d, 0x77, 0x4d, 0x3f, 0xd7, 0x57,  0x49, 0xdf, 0x35, 0x29, 0xe3, 0x57, 0x49, 0xff, 
+	 0x35, 0x3d, 0xd3, 0x3d, 0x45, 0xd9, 0x41, 0x39,  0xd5, 0x49, 0x3f, 0xdd, 0x49, 0x5b, 0xc3, 0x4b, 
+	 0x5d, 0xc5, 0x00, 0x4d, 0x6f, 0x91, 0xf1, 0xff,  0x4f, 0xf9, 0xf5, 0x35, 0xdf, 0xdb, 0x3f, 0xeb, 
+	 0xe7, 0x3b, 0xe7, 0xe3, 0x85, 0xe5, 0xff, 0x00,  0x55, 0x77, 0x5f, 0x71, 0xd9, 0x2f, 0x43, 0xa9, 
+	 0x49, 0x3f, 0xdd, 0x47, 0x3d, 0xdb, 0x45, 0x47,  0xed, 0x2d, 0x31, 0xd7, 0x4b, 0x3f, 0xf7, 0x3d, 
+	 0x33, 0xeb, 0x4b, 0x41, 0xc5, 0x61, 0x55, 0xd9,  0x31, 0x2d, 0x4b, 0x3b, 0x35, 0x55, 0x2d, 0x21, 
+	 0x1b, 0xfb, 0xef, 0xe9, 0xff, 0xf5, 0xff, 0xff,  0xe9, 0xff, 0xf5, 0xe7, 0xff, 0xff, 0xf7, 0xff, 
+	 0xef, 0xff, 0xe9, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfb, 0xff,  0xff, 0xef, 0xf5, 0xf3, 0xff, 0xf3, 0xff, 0xff, 
+	 0xf7, 0xff, 0xff, 0xf3, 0xfb, 0xff, 0xef, 0xf7,  0x2d, 0x29, 0x19, 0x4f, 0x4b, 0x39, 0x29, 0x27, 
+	 0x4f, 0x53, 0x4f, 0x79, 0x41, 0x33, 0xc9, 0x43,  0x35, 0xcb, 0x41, 0x35, 0xf1, 0x43, 0x37, 0xf3, 
+	 0x3d, 0x45, 0xd9, 0x3b, 0x43, 0xd7, 0x47, 0x3d,  0xdb, 0x4b, 0x41, 0xdf, 0x63, 0x75, 0xdd, 0x3f, 
+	 0x53, 0xb9, 0x49, 0xa7, 0xcb, 0x65, 0xc3, 0xe7,  0x31, 0xdb, 0xd7, 0x3d, 0xe7, 0xe3, 0x49, 0xf3, 
+	 0xef, 0x37, 0xe3, 0xdf, 0x69, 0xc7, 0xeb, 0x1d,  0x7b, 0x9f, 0x11, 0x25, 0x8d, 0x5f, 0x71, 0xd9, 
+	 0x5b, 0x4f, 0xed, 0x4b, 0x41, 0xdf, 0x31, 0x35,  0xdb, 0x4f, 0x51, 0xf7, 0x35, 0x2b, 0xe3, 0x41, 
+	 0x35, 0xed, 0x4f, 0x45, 0xc9, 0x43, 0x37, 0xbb,  0x47, 0x41, 0x61, 0x37, 0x31, 0x51, 0x5b, 0x4f, 
+	 0x49, 0x1f, 0x13, 0x0d, 0xff, 0xed, 0xff, 0xff,  0xeb, 0xff, 0xfb, 0xed, 0xff, 0xff, 0xf7, 0xff, 
+	 0xf3, 0xff, 0xed, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf3, 0xf7,  0xf9, 0xfb, 0xff, 0xff, 0xff, 0xed, 0xff, 0xff, 
+	 0xed, 0xff, 0xff, 0xf9, 0xff, 0x57, 0x41, 0x4b,  0x55, 0x4d, 0x39, 0x4f, 0x47, 0x33, 0x39, 0x33, 
+	 0x5b, 0x3d, 0x37, 0x5f, 0x59, 0x45, 0xe1, 0x49,  0x35, 0xd3, 0x51, 0x3f, 0xff, 0x4b, 0x3b, 0xfb, 
+	 0x25, 0x29, 0xbf, 0x49, 0x4d, 0xe1, 0x3d, 0x35,  0xd5, 0x49, 0x41, 0xe1, 0x2b, 0x59, 0xb3, 0x9f, 
+	 0xcd, 0xff, 0x51, 0xe9, 0xff, 0x49, 0xe1, 0xfd,  0x00, 0xed, 0xf7, 0x0b, 0xff, 0xff, 0x00, 0xef, 
+	 0xf9, 0x00, 0xf1, 0xfb, 0x57, 0xef, 0xff, 0x5f,  0xf7, 0xff, 0x55, 0x81, 0xdd, 0x43, 0x6f, 0xcb, 
+	 0x25, 0x1d, 0xbd, 0x53, 0x4b, 0xeb, 0x37, 0x37,  0xdf, 0x39, 0x39, 0xe3, 0x47, 0x37, 0xf3, 0x49, 
+	 0x39, 0xf7, 0x65, 0x53, 0xdb, 0x5d, 0x4d, 0xd3,  0x2b, 0x23, 0x3f, 0x39, 0x31, 0x4d, 0x39, 0x2b, 
+	 0x23, 0x5d, 0x4d, 0x45, 0x5d, 0x3d, 0x5d, 0xff,  0xeb, 0xff, 0xff, 0xf3, 0xff, 0xff, 0xf3, 0xff, 
+	 0xe1, 0xeb, 0xd9, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf9, 0xfd,  0xff, 0xfd, 0xff, 0xff, 0xff, 0xed, 0xff, 0xff, 
+	 0xf5, 0xff, 0xef, 0xd9, 0xe3, 0x4f, 0x39, 0x43,  0x47, 0x3f, 0x2b, 0x49, 0x41, 0x2d, 0x2f, 0x29, 
+	 0x51, 0x3b, 0x35, 0x5d, 0x45, 0x33, 0xcf, 0x5f,  0x4b, 0xe7, 0x3d, 0x2d, 0xed, 0x3d, 0x2d, 0xed, 
+	 0x4d, 0x51, 0xe7, 0x3b, 0x41, 0xd5, 0x4d, 0x45,  0xe5, 0x43, 0x3d, 0xdd, 0x2f, 0x5d, 0xb7, 0x21, 
+	 0x51, 0xab, 0x45, 0xdd, 0xf9, 0x4b, 0xe3, 0xff,  0x09, 0xff, 0xff, 0x00, 0xed, 0xf7, 0x04, 0xf9, 
+	 0xff, 0x00, 0xf1, 0xfb, 0x43, 0xdb, 0xf7, 0x29,  0xc1, 0xdd, 0x27, 0x55, 0xaf, 0x39, 0x65, 0xc1, 
+	 0x4f, 0x47, 0xe7, 0x3d, 0x35, 0xd5, 0x41, 0x41,  0xe9, 0x3d, 0x3d, 0xe5, 0x45, 0x35, 0xf3, 0x3d, 
+	 0x2d, 0xeb, 0x4b, 0x39, 0xc1, 0x57, 0x45, 0xcd,  0x3f, 0x37, 0x51, 0x39, 0x31, 0x4b, 0x53, 0x45, 
+	 0x3d, 0x4b, 0x3b, 0x33, 0x51, 0x31, 0x51, 0xf7,  0xd7, 0xf9, 0xff, 0xed, 0xff, 0xff, 0xed, 0xff, 
+	 0xfb, 0xff, 0xf3, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe7, 0xf9,  0xff, 0xef, 0xff, 0xff, 0xff, 0xf3, 0xff, 0xff, 
+	 0xfb, 0xff, 0x85, 0x5d, 0x73, 0x63, 0x39, 0x4f,  0x61, 0x31, 0x4d, 0x5b, 0x2b, 0x47, 0x4f, 0x33, 
+	 0x55, 0x3f, 0x23, 0x45, 0x5f, 0x59, 0x85, 0x6d,  0x65, 0x93, 0x65, 0x65, 0x9d, 0x81, 0x81, 0xb9, 
+	 0x6f, 0x6b, 0xab, 0x7d, 0x79, 0xbb, 0x4d, 0x61,  0xc1, 0x4d, 0x5f, 0xc1, 0x57, 0x3f, 0xe9, 0x51, 
+	 0x39, 0xe3, 0x2b, 0x5b, 0xbf, 0x91, 0xc3, 0xff,  0x3d, 0xdb, 0xff, 0x43, 0xe1, 0xff, 0x4b, 0xe7, 
+	 0xff, 0x41, 0xdd, 0xff, 0x6d, 0x9d, 0xfd, 0x21,  0x53, 0xb1, 0x55, 0x3b, 0xdd, 0x53, 0x39, 0xdd, 
+	 0x59, 0x69, 0xc1, 0x5b, 0x6b, 0xc3, 0x63, 0x65,  0x99, 0x5d, 0x5d, 0x91, 0x77, 0x79, 0xa9, 0x79, 
+	 0x7b, 0xab, 0x6d, 0x67, 0x91, 0x49, 0x43, 0x6d,  0x51, 0x35, 0x59, 0x49, 0x2d, 0x51, 0x61, 0x31, 
+	 0x4f, 0x5b, 0x2b, 0x49, 0x67, 0x3d, 0x53, 0x73,  0x49, 0x5f, 0xff, 0xfb, 0xff, 0xff, 0xfb, 0xff, 
+	 0xe1, 0xf5, 0xf7, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xef, 0xff,  0xff, 0xe7, 0xf7, 0xff, 0xfb, 0xef, 0xfd, 0xf7, 
+	 0xe9, 0xf7, 0x5d, 0x33, 0x49, 0x4b, 0x23, 0x37,  0x5d, 0x2d, 0x49, 0x63, 0x33, 0x4f, 0x47, 0x2b, 
+	 0x4d, 0x4d, 0x31, 0x53, 0x55, 0x4d, 0x7b, 0x7d,  0x77, 0xa5, 0x1f, 0x1d, 0x55, 0xdb, 0xd9, 0xff, 
+	 0xd9, 0xd5, 0xff, 0xb7, 0xb3, 0xf5, 0x00, 0x06,  0x65, 0x57, 0x6b, 0xcb, 0x51, 0x39, 0xe5, 0x61, 
+	 0x47, 0xf3, 0x25, 0x57, 0xb9, 0x43, 0x73, 0xd7,  0x06, 0xa3, 0xcf, 0x39, 0xd7, 0xff, 0x41, 0xdd, 
+	 0xff, 0x00, 0x6d, 0x95, 0x45, 0x75, 0xd5, 0x39,  0x69, 0xc9, 0x53, 0x39, 0xdb, 0x6b, 0x4f, 0xf3, 
+	 0x09, 0x1b, 0x71, 0x7b, 0x8b, 0xe3, 0xed, 0xef,  0xff, 0xeb, 0xed, 0xff, 0xd1, 0xd3, 0xff, 0x02, 
+	 0x02, 0x31, 0x6b, 0x67, 0x8f, 0x45, 0x3f, 0x69,  0x45, 0x29, 0x4d, 0x3f, 0x23, 0x47, 0x55, 0x25, 
+	 0x43, 0x61, 0x31, 0x4f, 0x5b, 0x31, 0x47, 0x4b,  0x23, 0x37, 0xf7, 0xeb, 0xf5, 0xff, 0xf9, 0xff, 
+	 0xef, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xeb, 0xf9,  0xf9, 0xe9, 0xf7, 0xf7, 0xff, 0xfd, 0xff, 0xcb, 
+	 0xbd, 0xc3, 0x71, 0x4d, 0x5b, 0x57, 0x33, 0x41,  0x59, 0x31, 0x45, 0x51, 0x29, 0x3b, 0x3d, 0x25, 
+	 0x3d, 0x59, 0x41, 0x59, 0x1f, 0x17, 0x31, 0xd7,  0xcf, 0xe9, 0xfd, 0xf7, 0xff, 0xed, 0xe7, 0xff, 
+	 0xff, 0xf3, 0xff, 0xff, 0xf3, 0xff, 0xf7, 0xf9,  0xff, 0x4d, 0x4f, 0x69, 0x6f, 0x63, 0xd1, 0x59, 
+	 0x4d, 0xbb, 0x31, 0x3d, 0xb9, 0x3f, 0x4b, 0xc7,  0x45, 0x6f, 0xd7, 0x15, 0x43, 0xa9, 0x1f, 0x4b, 
+	 0xaf, 0x4f, 0x79, 0xdd, 0x3d, 0x49, 0xbd, 0x3f,  0x4b, 0xbf, 0x53, 0x45, 0xa7, 0x3f, 0x31, 0x93, 
+	 0xeb, 0xeb, 0xf7, 0xf3, 0xf3, 0xff, 0xfd, 0xf1,  0xff, 0xf5, 0xe9, 0xff, 0xf1, 0xed, 0xff, 0xe7, 
+	 0xe3, 0xfd, 0x9f, 0x99, 0xaf, 0x4f, 0x47, 0x5f,  0x41, 0x2b, 0x41, 0x53, 0x3b, 0x51, 0x53, 0x2b, 
+	 0x3f, 0x5b, 0x33, 0x45, 0x53, 0x2f, 0x3d, 0x55,  0x31, 0x3f, 0xf7, 0xe9, 0xef, 0xff, 0xf3, 0xf9, 
+	 0xf3, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xed, 0xfb,  0xfb, 0xf3, 0xff, 0xff, 0xff, 0xfd, 0xff, 0x41, 
+	 0x35, 0x3b, 0x65, 0x41, 0x4f, 0x53, 0x2f, 0x3d,  0x5b, 0x33, 0x47, 0x55, 0x2d, 0x3f, 0x55, 0x3d, 
+	 0x55, 0x55, 0x3d, 0x55, 0xd3, 0xcb, 0xe5, 0xff,  0xf7, 0xff, 0xe9, 0xe3, 0xff, 0xf7, 0xf1, 0xff, 
+	 0xdf, 0xd1, 0xf7, 0xeb, 0xdd, 0xff, 0xe3, 0xe5,  0xff, 0xf1, 0xf3, 0xff, 0x00, 0x00, 0x57, 0x6d, 
+	 0x61, 0xcf, 0x37, 0x43, 0xbf, 0x47, 0x53, 0xcf,  0x2f, 0x5b, 0xc1, 0x2d, 0x59, 0xbf, 0x37, 0x61, 
+	 0xc5, 0x21, 0x4d, 0xb1, 0x43, 0x4f, 0xc3, 0x47,  0x51, 0xc5, 0x7f, 0x73, 0xd5, 0x79, 0x6d, 0xcf, 
+	 0xf7, 0xf7, 0xff, 0xf9, 0xf9, 0xff, 0xe5, 0xd9,  0xf9, 0xf3, 0xe7, 0xff, 0xfd, 0xf7, 0xff, 0xf5, 
+	 0xef, 0xff, 0xfb, 0xf3, 0xff, 0x97, 0x91, 0xa7,  0x61, 0x49, 0x5f, 0x3d, 0x25, 0x3b, 0x5b, 0x33, 
+	 0x45, 0x59, 0x31, 0x43, 0x57, 0x33, 0x41, 0x67,  0x43, 0x51, 0xb7, 0xab, 0xb1, 0xff, 0xf5, 0xfb, 
+	 0xf3, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf9, 0xff,  0xf9, 0xf7, 0xff, 0xf7, 0xff, 0xf9, 0xf7, 0x0f, 
+	 0x04, 0x02, 0x4f, 0x2f, 0x37, 0x4f, 0x2d, 0x35,  0x5b, 0x37, 0x45, 0x55, 0x33, 0x41, 0x4d, 0x3b, 
+	 0x45, 0x71, 0x5f, 0x69, 0xff, 0xfd, 0xff, 0xff,  0xf9, 0xff, 0xf7, 0xe3, 0xe3, 0x87, 0x71, 0x73, 
+	 0x99, 0x7b, 0x79, 0x73, 0x53, 0x53, 0xb1, 0x8b,  0x73, 0xff, 0xf9, 0xdf, 0x93, 0x93, 0xcd, 0x75, 
+	 0x75, 0xaf, 0x3d, 0x39, 0xd9, 0x3d, 0x39, 0xd9,  0x4d, 0x2d, 0xd9, 0x59, 0x39, 0xe7, 0x53, 0x35, 
+	 0xdf, 0x67, 0x47, 0xf1, 0x41, 0x3d, 0xd3, 0x41,  0x3f, 0xd3, 0x4b, 0x4b, 0x75, 0xe1, 0xe3, 0xff, 
+	 0xef, 0xcb, 0x9f, 0x9d, 0x7b, 0x4f, 0x7f, 0x5d,  0x63, 0x7f, 0x5d, 0x63, 0xa7, 0x91, 0x93, 0xf7, 
+	 0xe1, 0xe3, 0xff, 0xfd, 0xff, 0xff, 0xf3, 0xf7,  0x27, 0x17, 0x1b, 0x4b, 0x39, 0x3f, 0x55, 0x35, 
+	 0x3d, 0x59, 0x39, 0x41, 0x57, 0x37, 0x3f, 0x4f,  0x2f, 0x37, 0x39, 0x2d, 0x31, 0xff, 0xfd, 0xff, 
+	 0xf9, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf9, 0xff,  0xf9, 0xe9, 0xf5, 0xeb, 0xff, 0xff, 0xfd, 0x5d, 
+	 0x51, 0x4f, 0x55, 0x35, 0x3d, 0x5b, 0x3b, 0x43,  0x59, 0x35, 0x43, 0x4d, 0x29, 0x37, 0x61, 0x4f, 
+	 0x59, 0xff, 0xfb, 0xff, 0xf1, 0xe3, 0xe9, 0xf5,  0xe7, 0xed, 0xff, 0xf3, 0xf5, 0xf5, 0xe1, 0xe1, 
+	 0x7d, 0x5f, 0x5d, 0x79, 0x5b, 0x59, 0x7d, 0x59,  0x41, 0xbb, 0x97, 0x7f, 0xd7, 0xd7, 0xff, 0x6b, 
+	 0x6b, 0xa5, 0x4f, 0x49, 0xe9, 0x4d, 0x47, 0xe9,  0x67, 0x47, 0xf5, 0x55, 0x37, 0xe3, 0x59, 0x3b, 
+	 0xe5, 0x53, 0x35, 0xdd, 0x45, 0x41, 0xd7, 0x4d,  0x49, 0xdd, 0x23, 0x23, 0x4d, 0xdd, 0xdf, 0xff, 
+	 0x9d, 0x79, 0x4d, 0x8b, 0x69, 0x3d, 0x7b, 0x59,  0x5f, 0x9b, 0x79, 0x7f, 0xff, 0xef, 0xf3, 0xff, 
+	 0xe9, 0xed, 0xfb, 0xef, 0xf3, 0xff, 0xf5, 0xf9,  0x9f, 0x8d, 0x91, 0x5f, 0x4d, 0x53, 0x59, 0x39, 
+	 0x41, 0x51, 0x2f, 0x37, 0x55, 0x33, 0x3b, 0x53,  0x31, 0x39, 0x0b, 0x00, 0x02, 0xff, 0xfd, 0xff, 
+	 0xf5, 0xfd, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfd, 0xff,  0xfb, 0xeb, 0xf1, 0xe9, 0xff, 0xfd, 0xfd, 0x73, 
+	 0x65, 0x65, 0x45, 0x23, 0x31, 0x53, 0x31, 0x3f,  0x53, 0x31, 0x43, 0x4f, 0x2d, 0x3f, 0x4d, 0x37, 
+	 0x43, 0xff, 0xfb, 0xff, 0xff, 0xfd, 0xfd, 0xff,  0xf9, 0xf9, 0xff, 0xf3, 0xe3, 0xff, 0xe9, 0xd9, 
+	 0xa7, 0x75, 0x5f, 0x99, 0x67, 0x51, 0xa5, 0x5f,  0x59, 0x97, 0x51, 0x4b, 0xd3, 0xcf, 0xfd, 0x63, 
+	 0x5f, 0x8d, 0x2f, 0x35, 0xdd, 0x2b, 0x31, 0xd9,  0x49, 0x41, 0xf1, 0x3b, 0x33, 0xe3, 0x4f, 0x49, 
+	 0xf3, 0x3f, 0x39, 0xe3, 0x41, 0x47, 0xe3, 0x4b,  0x4f, 0xeb, 0x47, 0x45, 0x5f, 0xa7, 0xa5, 0xbf, 
+	 0x9f, 0x5b, 0x3f, 0x95, 0x51, 0x33, 0x99, 0x61,  0x5b, 0xe5, 0xad, 0xa5, 0xff, 0xf7, 0xed, 0xf3, 
+	 0xcf, 0xc7, 0xff, 0xff, 0xfb, 0xff, 0xfb, 0xf7,  0xf3, 0xe1, 0xe1, 0x69, 0x57, 0x57, 0x57, 0x39, 
+	 0x41, 0x49, 0x29, 0x33, 0x53, 0x33, 0x41, 0x61,  0x3f, 0x4d, 0x37, 0x25, 0x31, 0xff, 0xfb, 0xff, 
+	 0xf5, 0xf7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf3, 0xf9,  0xf1, 0xf9, 0xff, 0xf7, 0xff, 0xfd, 0xfd, 0x5f, 
+	 0x51, 0x51, 0x53, 0x31, 0x3f, 0x59, 0x39, 0x47,  0x55, 0x33, 0x45, 0x53, 0x31, 0x43, 0x5d, 0x47, 
+	 0x53, 0xff, 0xf3, 0xfd, 0xff, 0xf3, 0xf1, 0xdd,  0xc9, 0xc9, 0xa1, 0x7f, 0x71, 0xa7, 0x85, 0x77, 
+	 0x93, 0x61, 0x4b, 0x89, 0x57, 0x41, 0x99, 0x53,  0x4d, 0x9f, 0x59, 0x53, 0xcd, 0xc7, 0xf7, 0x5b, 
+	 0x55, 0x85, 0x33, 0x39, 0xe1, 0x49, 0x4d, 0xf5,  0x3b, 0x33, 0xe3, 0x49, 0x41, 0xf1, 0x37, 0x31, 
+	 0xd9, 0x4b, 0x45, 0xef, 0x3d, 0x43, 0xdf, 0x3d,  0x43, 0xdf, 0x31, 0x2f, 0x49, 0x61, 0x5f, 0x79, 
+	 0xa5, 0x61, 0x45, 0xa9, 0x65, 0x47, 0x91, 0x59,  0x53, 0x8f, 0x57, 0x51, 0xab, 0x89, 0x7f, 0xa7, 
+	 0x85, 0x7b, 0xfb, 0xe9, 0xe3, 0xff, 0xf5, 0xef,  0xe1, 0xcd, 0xcf, 0x5f, 0x4d, 0x4f, 0x4b, 0x2b, 
+	 0x35, 0x55, 0x35, 0x3f, 0x59, 0x39, 0x47, 0x4b,  0x2b, 0x39, 0x51, 0x3f, 0x4b, 0xff, 0xfb, 0xff, 
+	 0xfd, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfd, 0xff,  0xff, 0xf7, 0xfb, 0xf9, 0xff, 0xf1, 0xfd, 0x67, 
+	 0x55, 0x61, 0x4f, 0x2b, 0x41, 0x51, 0x2d, 0x43,  0x61, 0x3d, 0x55, 0x4d, 0x29, 0x41, 0x51, 0x39, 
+	 0x49, 0xa1, 0x87, 0x97, 0xff, 0xfb, 0xff, 0xe1,  0xc5, 0xc9, 0x7f, 0x51, 0x49, 0x8b, 0x5d, 0x55, 
+	 0xa1, 0x63, 0x53, 0x99, 0x5b, 0x4b, 0x8d, 0x4f,  0x63, 0x8d, 0x4f, 0x63, 0xd1, 0xb9, 0xdb, 0x75, 
+	 0x5b, 0x7d, 0x5d, 0x53, 0xc5, 0x53, 0x49, 0xbb,  0x3d, 0x4b, 0xab, 0x4d, 0x5b, 0xbd, 0x43, 0x51, 
+	 0xaf, 0x4f, 0x5d, 0xbb, 0x55, 0x4d, 0xb5, 0x51,  0x49, 0xb1, 0x65, 0x4d, 0x5f, 0x71, 0x59, 0x6b, 
+	 0x93, 0x55, 0x55, 0x95, 0x57, 0x57, 0x9f, 0x5d,  0x59, 0x8f, 0x4d, 0x47, 0x89, 0x5b, 0x57, 0x93, 
+	 0x65, 0x61, 0xff, 0xe5, 0xe7, 0xff, 0xf3, 0xf5,  0x3f, 0x27, 0x31, 0x51, 0x3b, 0x45, 0x51, 0x2f, 
+	 0x41, 0x59, 0x37, 0x49, 0x53, 0x31, 0x45, 0x51,  0x2f, 0x43, 0x4d, 0x39, 0x4d, 0xff, 0xf5, 0xff, 
+	 0xf9, 0xf7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf9, 0xfd,  0xfd, 0xf9, 0xfd, 0xfd, 0xff, 0xf7, 0xff, 0x75, 
+	 0x63, 0x6d, 0x53, 0x2f, 0x45, 0x4f, 0x2b, 0x41,  0x4d, 0x29, 0x41, 0x51, 0x2d, 0x45, 0x5b, 0x43, 
+	 0x53, 0x51, 0x37, 0x47, 0xff, 0xef, 0xf3, 0xff,  0xe7, 0xeb, 0x99, 0x6d, 0x65, 0x81, 0x53, 0x4b, 
+	 0x93, 0x55, 0x45, 0x9f, 0x61, 0x51, 0x8d, 0x4f,  0x63, 0x8b, 0x4d, 0x61, 0x8d, 0x75, 0x97, 0x55, 
+	 0x3b, 0x5d, 0x33, 0x29, 0x9b, 0x31, 0x27, 0x99,  0x27, 0x35, 0x95, 0x2d, 0x3b, 0x9d, 0x2d, 0x3b, 
+	 0x99, 0x2b, 0x39, 0x97, 0x2f, 0x27, 0x8f, 0x31,  0x29, 0x91, 0x5f, 0x47, 0x59, 0x73, 0x5b, 0x6d, 
+	 0x99, 0x5b, 0x5b, 0x91, 0x53, 0x53, 0x91, 0x4f,  0x49, 0xa3, 0x61, 0x5b, 0x91, 0x63, 0x5f, 0x9b, 
+	 0x6d, 0x69, 0xff, 0xe5, 0xe7, 0xc9, 0xad, 0xaf,  0x65, 0x4f, 0x59, 0x51, 0x39, 0x43, 0x57, 0x35, 
+	 0x47, 0x4f, 0x2d, 0x3f, 0x55, 0x33, 0x47, 0x57,  0x33, 0x49, 0x53, 0x3f, 0x53, 0xff, 0xf7, 0xff, 
+	 0xfb, 0xfb, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf9, 0xff,  0xff, 0xf7, 0xfd, 0xff, 0xff, 0xf9, 0xff, 0x55, 
+	 0x45, 0x53, 0x57, 0x31, 0x47, 0x51, 0x2b, 0x41,  0x51, 0x2b, 0x43, 0x55, 0x2f, 0x47, 0x3b, 0x1b, 
+	 0x31, 0x61, 0x43, 0x57, 0x61, 0x43, 0x51, 0xff,  0xf3, 0xff, 0xa7, 0x79, 0x7f, 0x77, 0x49, 0x4f, 
+	 0x9f, 0x5f, 0x63, 0x93, 0x53, 0x57, 0x79, 0x57,  0x65, 0x77, 0x55, 0x63, 0x69, 0x3b, 0x49, 0x5d, 
+	 0x2f, 0x3d, 0x53, 0x23, 0x47, 0x55, 0x25, 0x49,  0x4f, 0x39, 0x4d, 0x49, 0x35, 0x47, 0x4f, 0x3b, 
+	 0x4b, 0x47, 0x33, 0x43, 0x57, 0x27, 0x45, 0x55,  0x25, 0x43, 0x75, 0x45, 0x4b, 0x87, 0x57, 0x5d, 
+	 0x85, 0x63, 0x67, 0x7d, 0x59, 0x5d, 0xad, 0x6f,  0x71, 0x81, 0x41, 0x45, 0x8d, 0x5f, 0x65, 0xf1, 
+	 0xc3, 0xc9, 0xf7, 0xd9, 0xe3, 0x61, 0x45, 0x4f,  0x49, 0x2b, 0x3f, 0x4f, 0x31, 0x45, 0x55, 0x2f, 
+	 0x47, 0x53, 0x2d, 0x45, 0x55, 0x2d, 0x47, 0x55,  0x2f, 0x49, 0x31, 0x1f, 0x31, 0xff, 0xf7, 0xff, 
+	 0xf3, 0xf7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf9, 0xff,  0xff, 0xf1, 0xf7, 0xff, 0xff, 0xf9, 0xff, 0x25, 
+	 0x13, 0x23, 0x55, 0x2f, 0x45, 0x51, 0x2b, 0x41,  0x63, 0x3d, 0x55, 0x4d, 0x27, 0x3f, 0x65, 0x45, 
+	 0x5b, 0x41, 0x23, 0x37, 0x6b, 0x4d, 0x59, 0x3d,  0x1f, 0x2b, 0xff, 0xdb, 0xdf, 0x95, 0x67, 0x6d, 
+	 0x95, 0x55, 0x59, 0x9f, 0x5f, 0x63, 0x75, 0x55,  0x63, 0x71, 0x51, 0x5f, 0x5b, 0x2d, 0x3b, 0x65, 
+	 0x37, 0x45, 0x59, 0x29, 0x4d, 0x57, 0x27, 0x4b,  0x4b, 0x35, 0x49, 0x43, 0x2f, 0x41, 0x45, 0x31, 
+	 0x41, 0x43, 0x2f, 0x41, 0x61, 0x31, 0x4f, 0x55,  0x25, 0x43, 0x6f, 0x3f, 0x45, 0x73, 0x43, 0x49, 
+	 0x7d, 0x59, 0x5d, 0x7d, 0x5b, 0x5f, 0x89, 0x49,  0x4d, 0x9f, 0x5f, 0x63, 0xb3, 0x85, 0x8b, 0xed, 
+	 0xbf, 0xc3, 0x33, 0x15, 0x21, 0x55, 0x39, 0x43,  0x4f, 0x31, 0x45, 0x4f, 0x31, 0x45, 0x4f, 0x29, 
+	 0x41, 0x5f, 0x39, 0x51, 0x55, 0x2d, 0x47, 0x53,  0x2b, 0x45, 0x19, 0x07, 0x19, 0xff, 0xf3, 0xff, 
+	 0xef, 0xf3, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf1, 0xfd,  0xff, 0xe7, 0xf3, 0xfb, 0xff, 0xfb, 0xff, 0x3d, 
+	 0x31, 0x3d, 0x57, 0x33, 0x43, 0x51, 0x2d, 0x3d,  0x65, 0x3b, 0x4d, 0x53, 0x29, 0x39, 0x3d, 0x1f, 
+	 0x2d, 0x59, 0x3b, 0x49, 0x43, 0x29, 0x37, 0x6d,  0x51, 0x5f, 0x49, 0x23, 0x37, 0x57, 0x31, 0x45, 
+	 0x77, 0x41, 0x57, 0x83, 0x4d, 0x63, 0x61, 0x49,  0x4b, 0x55, 0x3d, 0x3f, 0x69, 0x35, 0x45, 0x67, 
+	 0x33, 0x43, 0x6d, 0x39, 0x39, 0x67, 0x33, 0x31,  0x5b, 0x2f, 0x3d, 0x5d, 0x31, 0x3f, 0x5b, 0x2d, 
+	 0x3b, 0x5d, 0x2f, 0x3d, 0x75, 0x3d, 0x3d, 0x65,  0x2d, 0x2d, 0x69, 0x33, 0x43, 0x63, 0x2d, 0x3d, 
+	 0x63, 0x45, 0x49, 0x65, 0x47, 0x4b, 0x91, 0x61,  0x69, 0x49, 0x17, 0x1f, 0x6d, 0x4b, 0x55, 0x6d, 
+	 0x4b, 0x55, 0x49, 0x2d, 0x3d, 0x49, 0x2d, 0x3f,  0x61, 0x41, 0x55, 0x49, 0x29, 0x3d, 0x5d, 0x31, 
+	 0x47, 0x5f, 0x33, 0x49, 0x5b, 0x35, 0x49, 0x5d,  0x37, 0x4b, 0x57, 0x4d, 0x55, 0xff, 0xf9, 0xff, 
+	 0xf3, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xef, 0xfb,  0xff, 0xed, 0xf9, 0xff, 0xff, 0xfb, 0xff, 0xa9, 
+	 0x9d, 0xa9, 0x65, 0x3f, 0x4f, 0x57, 0x33, 0x43,  0x53, 0x29, 0x3b, 0x5f, 0x35, 0x47, 0x57, 0x39, 
+	 0x47, 0x5d, 0x3d, 0x4d, 0x53, 0x37, 0x45, 0x47,  0x2d, 0x3b, 0x5d, 0x37, 0x4b, 0x5b, 0x35, 0x49, 
+	 0x6b, 0x37, 0x4b, 0x6f, 0x39, 0x4f, 0x53, 0x3b,  0x3d, 0x45, 0x2d, 0x2f, 0x6d, 0x3b, 0x49, 0x5d, 
+	 0x2b, 0x39, 0x6b, 0x37, 0x35, 0x63, 0x2f, 0x2f,  0x57, 0x2b, 0x39, 0x61, 0x35, 0x43, 0x61, 0x33, 
+	 0x41, 0x5d, 0x2f, 0x3d, 0x6b, 0x33, 0x33, 0x67,  0x2f, 0x2f, 0x67, 0x31, 0x41, 0x65, 0x2d, 0x3d, 
+	 0x55, 0x37, 0x3b, 0x51, 0x35, 0x37, 0x5d, 0x2b,  0x33, 0x69, 0x37, 0x3f, 0x4f, 0x2d, 0x37, 0x5b, 
+	 0x37, 0x41, 0x53, 0x37, 0x47, 0x51, 0x35, 0x45,  0x4d, 0x2b, 0x41, 0x55, 0x33, 0x49, 0x63, 0x37, 
+	 0x4d, 0x49, 0x1d, 0x35, 0x59, 0x33, 0x47, 0x67,  0x41, 0x53, 0xcd, 0xc1, 0xc9, 0xff, 0xfb, 0xff, 
+	 0xf3, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xef, 0xff,  0xff, 0xef, 0xff, 0xff, 0xff, 0xfd, 0xff, 0xf5, 
+	 0xed, 0xf3, 0x6b, 0x49, 0x4f, 0x5b, 0x39, 0x3f,  0x55, 0x2b, 0x33, 0x65, 0x3b, 0x43, 0x55, 0x37, 
+	 0x3f, 0x47, 0x29, 0x2f, 0x4b, 0x33, 0x41, 0x4b,  0x33, 0x41, 0x49, 0x2b, 0x41, 0x53, 0x35, 0x4b, 
+	 0x55, 0x29, 0x49, 0x57, 0x2b, 0x49, 0x5b, 0x37,  0x39, 0x55, 0x2f, 0x33, 0x5d, 0x31, 0x51, 0x53, 
+	 0x27, 0x47, 0x4f, 0x35, 0x3d, 0x4b, 0x31, 0x39,  0x45, 0x25, 0x57, 0x4b, 0x29, 0x5d, 0x4d, 0x29, 
+	 0x5f, 0x4b, 0x27, 0x5d, 0x4d, 0x2d, 0x39, 0x53,  0x33, 0x3f, 0x5b, 0x27, 0x4f, 0x61, 0x2d, 0x55, 
+	 0x5f, 0x31, 0x3d, 0x5d, 0x2f, 0x3b, 0x63, 0x3f,  0x47, 0x6d, 0x47, 0x51, 0x45, 0x2b, 0x35, 0x39, 
+	 0x1f, 0x29, 0x59, 0x41, 0x51, 0x47, 0x2f, 0x3f,  0x51, 0x2d, 0x41, 0x57, 0x35, 0x49, 0x5d, 0x2f, 
+	 0x43, 0x53, 0x25, 0x39, 0x53, 0x31, 0x3b, 0x67,  0x43, 0x4d, 0xff, 0xfd, 0xf9, 0xff, 0xfd, 0xfb, 
+	 0xf1, 0xff, 0xf9, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf1, 0xff,  0xff, 0xe9, 0xfb, 0xfd, 0xfd, 0xf5, 0xfb, 0xfb, 
+	 0xf3, 0xf7, 0x63, 0x41, 0x47, 0x55, 0x33, 0x39,  0x5f, 0x35, 0x3d, 0x59, 0x2f, 0x35, 0x4f, 0x31, 
+	 0x37, 0x5f, 0x41, 0x47, 0x3f, 0x27, 0x35, 0x57,  0x3d, 0x4b, 0x4d, 0x2f, 0x45, 0x4b, 0x2d, 0x43, 
+	 0x61, 0x35, 0x53, 0x57, 0x2b, 0x49, 0x5b, 0x37,  0x39, 0x5f, 0x3b, 0x3d, 0x55, 0x29, 0x49, 0x5b, 
+	 0x2f, 0x4d, 0x51, 0x37, 0x3d, 0x4f, 0x35, 0x3d,  0x49, 0x29, 0x5b, 0x43, 0x21, 0x55, 0x49, 0x25, 
+	 0x59, 0x4d, 0x29, 0x5f, 0x4f, 0x2f, 0x3b, 0x59,  0x39, 0x45, 0x55, 0x21, 0x49, 0x5f, 0x2b, 0x53, 
+	 0x5d, 0x2f, 0x3b, 0x65, 0x37, 0x43, 0x51, 0x2b,  0x35, 0x49, 0x23, 0x2d, 0x5b, 0x3f, 0x4b, 0x55, 
+	 0x3b, 0x45, 0x4f, 0x35, 0x45, 0x47, 0x2d, 0x3d,  0x4d, 0x29, 0x3d, 0x55, 0x31, 0x45, 0x53, 0x25, 
+	 0x39, 0x75, 0x47, 0x5b, 0x51, 0x2f, 0x39, 0x63,  0x41, 0x4b, 0xf7, 0xf1, 0xef, 0xff, 0xff, 0xfd, 
+	 0xf1, 0xff, 0xf9, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfb,  0xff, 0xff, 0xfb, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xc7, 0xc1, 0xc5, 0x49, 0x43, 0x47,  0x4f, 0x3f, 0x49, 0x3d, 0x2d, 0x37, 0x53, 0x33, 
+	 0x43, 0x4d, 0x2f, 0x3d, 0x53, 0x2b, 0x3f, 0x5b,  0x33, 0x45, 0x5d, 0x35, 0x49, 0x5b, 0x31, 0x47, 
+	 0x53, 0x31, 0x45, 0x53, 0x2f, 0x45, 0x55, 0x31,  0x43, 0x55, 0x31, 0x43, 0x55, 0x31, 0x43, 0x55, 
+	 0x31, 0x43, 0x55, 0x31, 0x43, 0x55, 0x31, 0x43,  0x55, 0x31, 0x43, 0x55, 0x31, 0x43, 0x55, 0x31, 
+	 0x43, 0x55, 0x31, 0x43, 0x55, 0x31, 0x43, 0x55,  0x31, 0x43, 0x55, 0x31, 0x43, 0x55, 0x31, 0x43, 
+	 0x55, 0x31, 0x43, 0x55, 0x31, 0x43, 0x4d, 0x29,  0x3f, 0x5b, 0x39, 0x4d, 0x5f, 0x35, 0x4b, 0x4f, 
+	 0x27, 0x3b, 0x5f, 0x31, 0x45, 0x55, 0x27, 0x3b,  0x61, 0x35, 0x45, 0x59, 0x2d, 0x3d, 0x55, 0x31, 
+	 0x3f, 0x59, 0x35, 0x41, 0x51, 0x43, 0x49, 0xcb,  0xbd, 0xc3, 0xf3, 0xf9, 0xf9, 0xf5, 0xfb, 0xfd, 
+	 0xef, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfd,  0xff, 0xff, 0xf5, 0xf9, 0xff, 0xff, 0xff, 0xfb, 
+	 0xf3, 0xf7, 0xfd, 0xf7, 0xfb, 0x43, 0x3d, 0x41,  0x45, 0x35, 0x3f, 0x4d, 0x3f, 0x47, 0x5b, 0x3d, 
+	 0x4b, 0x5d, 0x3d, 0x4d, 0x4d, 0x25, 0x39, 0x49,  0x21, 0x35, 0x59, 0x2f, 0x45, 0x53, 0x29, 0x3f, 
+	 0x49, 0x27, 0x3b, 0x57, 0x33, 0x49, 0x55, 0x31,  0x43, 0x55, 0x31, 0x43, 0x55, 0x31, 0x43, 0x55, 
+	 0x31, 0x43, 0x55, 0x31, 0x43, 0x55, 0x31, 0x43,  0x55, 0x31, 0x43, 0x55, 0x31, 0x43, 0x55, 0x31, 
+	 0x43, 0x55, 0x31, 0x43, 0x55, 0x31, 0x43, 0x55,  0x31, 0x43, 0x55, 0x31, 0x43, 0x55, 0x31, 0x43, 
+	 0x55, 0x31, 0x43, 0x55, 0x31, 0x43, 0x4f, 0x2b,  0x41, 0x53, 0x31, 0x45, 0x51, 0x29, 0x3d, 0x61, 
+	 0x37, 0x4d, 0x5f, 0x31, 0x45, 0x57, 0x29, 0x3d,  0x59, 0x2d, 0x3d, 0x65, 0x39, 0x49, 0x57, 0x33, 
+	 0x3f, 0x5b, 0x37, 0x45, 0x45, 0x37, 0x3d, 0xff,  0xf5, 0xfb, 0xfb, 0xff, 0xff, 0xfb, 0xff, 0xff, 
+	 0xd9, 0xed, 0xeb, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf9,  0xfd, 0xff, 0xfd, 0xff, 0xe9, 0xe7, 0xe9, 0xff, 
+	 0xff, 0xff, 0xf7, 0xf5, 0xf9, 0xd7, 0xd3, 0xd7,  0x5d, 0x51, 0x59, 0x43, 0x37, 0x3f, 0x35, 0x15, 
+	 0x25, 0x5d, 0x3d, 0x4d, 0x5d, 0x35, 0x47, 0x5d,  0x35, 0x49, 0x59, 0x2f, 0x45, 0x53, 0x2b, 0x3f, 
+	 0x61, 0x3f, 0x53, 0x4f, 0x2d, 0x41, 0x55, 0x2f,  0x43, 0x55, 0x2f, 0x43, 0x55, 0x2f, 0x43, 0x55, 
+	 0x2f, 0x43, 0x55, 0x2f, 0x43, 0x55, 0x2f, 0x43,  0x55, 0x2f, 0x43, 0x55, 0x2f, 0x43, 0x55, 0x2f, 
+	 0x43, 0x55, 0x2f, 0x43, 0x55, 0x2f, 0x43, 0x55,  0x2f, 0x43, 0x55, 0x2f, 0x43, 0x55, 0x2f, 0x43, 
+	 0x55, 0x2f, 0x43, 0x55, 0x2f, 0x43, 0x5b, 0x35,  0x49, 0x51, 0x2b, 0x3f, 0x5b, 0x31, 0x47, 0x49, 
+	 0x1f, 0x35, 0x5b, 0x33, 0x45, 0x5f, 0x37, 0x4b,  0x5f, 0x3b, 0x4b, 0x4b, 0x27, 0x37, 0x4b, 0x31, 
+	 0x3d, 0x7b, 0x61, 0x6b, 0xb7, 0xab, 0xb1, 0xff,  0xfb, 0xff, 0xeb, 0xef, 0xf1, 0xf9, 0xfd, 0xfd, 
+	 0xed, 0xf9, 0xf9, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf9,  0xfd, 0xff, 0xf7, 0xfb, 0xff, 0xff, 0xff, 0xff, 
+	 0xfb, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfd, 0xff,  0x4d, 0x41, 0x49, 0x4d, 0x41, 0x49, 0x77, 0x57, 
+	 0x67, 0x3b, 0x1b, 0x2b, 0x5f, 0x37, 0x49, 0x59,  0x31, 0x45, 0x55, 0x2b, 0x41, 0x63, 0x39, 0x4f, 
+	 0x3f, 0x1b, 0x2f, 0x59, 0x35, 0x49, 0x55, 0x2f,  0x43, 0x55, 0x2f, 0x43, 0x55, 0x2f, 0x43, 0x55, 
+	 0x2f, 0x43, 0x55, 0x2f, 0x43, 0x55, 0x2f, 0x43,  0x55, 0x2f, 0x43, 0x55, 0x2f, 0x43, 0x55, 0x2f, 
+	 0x43, 0x55, 0x2f, 0x43, 0x55, 0x2f, 0x43, 0x55,  0x2f, 0x43, 0x55, 0x2f, 0x43, 0x55, 0x2f, 0x43, 
+	 0x55, 0x2f, 0x43, 0x55, 0x2f, 0x43, 0x59, 0x33,  0x47, 0x53, 0x2d, 0x41, 0x55, 0x2d, 0x41, 0x6f, 
+	 0x47, 0x5b, 0x47, 0x1f, 0x33, 0x53, 0x2b, 0x3d,  0x59, 0x35, 0x45, 0x5d, 0x39, 0x49, 0x53, 0x39, 
+	 0x45, 0x41, 0x27, 0x31, 0xff, 0xf3, 0xf9, 0xff,  0xfd, 0xff, 0xf9, 0xfd, 0xff, 0xfd, 0xff, 0xff, 
+	 0xf5, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xfd, 0xf9, 0xfb, 0xf5, 0xf5, 0xf7, 0xfb, 
+	 0xfb, 0xfd, 0xef, 0xef, 0xf3, 0xf3, 0xf3, 0xf7,  0xff, 0xfd, 0xff, 0x31, 0x27, 0x2f, 0x55, 0x39, 
+	 0x45, 0x45, 0x29, 0x37, 0x5d, 0x35, 0x45, 0x61,  0x3b, 0x4b, 0x49, 0x23, 0x37, 0x4f, 0x29, 0x3d, 
+	 0x5b, 0x39, 0x4b, 0x4f, 0x2d, 0x3f, 0x57, 0x2f,  0x45, 0x57, 0x2f, 0x45, 0x57, 0x2f, 0x45, 0x57, 
+	 0x2f, 0x45, 0x57, 0x2f, 0x45, 0x57, 0x2f, 0x45,  0x57, 0x2f, 0x45, 0x57, 0x2f, 0x45, 0x57, 0x2f, 
+	 0x45, 0x57, 0x2f, 0x45, 0x57, 0x2f, 0x45, 0x57,  0x2f, 0x45, 0x57, 0x2f, 0x45, 0x57, 0x2f, 0x45, 
+	 0x57, 0x2f, 0x45, 0x57, 0x2f, 0x45, 0x57, 0x2d,  0x41, 0x57, 0x2d, 0x41, 0x61, 0x3b, 0x4f, 0x49, 
+	 0x23, 0x37, 0x4f, 0x2f, 0x3f, 0x63, 0x43, 0x53,  0x43, 0x2d, 0x39, 0x47, 0x31, 0x3d, 0x2d, 0x21, 
+	 0x29, 0xf7, 0xeb, 0xf3, 0xff, 0xf9, 0xfd, 0xf7,  0xf1, 0xf7, 0xff, 0xff, 0xff, 0xed, 0xed, 0xef, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf7, 0xf3,  0xf5, 0xff, 0xff, 0xff, 0xf9, 0xf9, 0xfb, 0xff, 
+	 0xff, 0xff, 0xfd, 0xfd, 0xff, 0xff, 0xff, 0xff,  0xfb, 0xf1, 0xf9, 0xf7, 0xeb, 0xf3, 0x37, 0x1b, 
+	 0x29, 0x65, 0x49, 0x55, 0x51, 0x2b, 0x3b, 0x4f,  0x29, 0x39, 0x69, 0x43, 0x57, 0x59, 0x33, 0x47, 
+	 0x4f, 0x2d, 0x3f, 0x59, 0x37, 0x49, 0x57, 0x2f,  0x45, 0x57, 0x2f, 0x45, 0x57, 0x2f, 0x45, 0x57, 
+	 0x2f, 0x45, 0x57, 0x2f, 0x45, 0x57, 0x2f, 0x45,  0x57, 0x2f, 0x45, 0x57, 0x2f, 0x45, 0x57, 0x2f, 
+	 0x45, 0x57, 0x2f, 0x45, 0x57, 0x2f, 0x45, 0x57,  0x2f, 0x45, 0x57, 0x2f, 0x45, 0x57, 0x2f, 0x45, 
+	 0x57, 0x2f, 0x45, 0x57, 0x2f, 0x45, 0x5d, 0x33,  0x45, 0x59, 0x2f, 0x41, 0x4b, 0x25, 0x39, 0x59, 
+	 0x33, 0x45, 0x47, 0x27, 0x37, 0x4f, 0x2f, 0x3f,  0x57, 0x41, 0x4d, 0x4b, 0x35, 0x41, 0xef, 0xe3, 
+	 0xeb, 0xff, 0xfd, 0xff, 0xf9, 0xf3, 0xf9, 0xff,  0xfd, 0xff, 0xf7, 0xf7, 0xf9, 0xfd, 0xfd, 0xff, 
+	 0xf5, 0xf7, 0xf9, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xf7, 0xfb, 0xfd, 0xef, 
+	 0xf3, 0xf5, 0xfd, 0xff, 0xff, 0xfd, 0xff, 0xff,  0xff, 0xfb, 0xff, 0xfd, 0xf7, 0xff, 0xff, 0xed, 
+	 0xf7, 0x2b, 0x13, 0x1d, 0x59, 0x35, 0x43, 0x63,  0x3f, 0x4d, 0x3f, 0x1b, 0x2b, 0x69, 0x45, 0x55, 
+	 0x45, 0x29, 0x37, 0x4b, 0x2f, 0x3d, 0x55, 0x2f,  0x45, 0x55, 0x2f, 0x45, 0x55, 0x2f, 0x45, 0x55, 
+	 0x2f, 0x45, 0x55, 0x2f, 0x45, 0x55, 0x2f, 0x45,  0x55, 0x2f, 0x45, 0x55, 0x2f, 0x45, 0x55, 0x2f, 
+	 0x45, 0x55, 0x2f, 0x45, 0x55, 0x2f, 0x45, 0x55,  0x2f, 0x45, 0x55, 0x2f, 0x45, 0x55, 0x2f, 0x45, 
+	 0x55, 0x2f, 0x45, 0x55, 0x2f, 0x45, 0x51, 0x29,  0x39, 0x59, 0x31, 0x41, 0x57, 0x37, 0x47, 0x59, 
+	 0x3b, 0x49, 0x45, 0x31, 0x3d, 0x61, 0x4f, 0x59,  0x04, 0x00, 0x06, 0xf5, 0xef, 0xf7, 0xe5, 0xe5, 
+	 0xeb, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfb,  0xfb, 0xff, 0xff, 0xf9, 0xfd, 0xff, 0xf9, 0xff, 
+	 0xff, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xf5, 0xf5, 0xf7, 0xed, 0xf1, 0xf3, 0xfd, 
+	 0xff, 0xff, 0xf7, 0xfb, 0xfd, 0xef, 0xf1, 0xf5,  0xff, 0xfd, 0xff, 0xf5, 0xef, 0xf5, 0xff, 0xef, 
+	 0xf9, 0xbf, 0xa7, 0xb1, 0x6d, 0x49, 0x57, 0x4f,  0x2b, 0x39, 0x59, 0x35, 0x45, 0x55, 0x31, 0x41, 
+	 0x4d, 0x31, 0x3f, 0x53, 0x37, 0x45, 0x55, 0x2f,  0x45, 0x55, 0x2f, 0x45, 0x55, 0x2f, 0x45, 0x55, 
+	 0x2f, 0x45, 0x55, 0x2f, 0x45, 0x55, 0x2f, 0x45,  0x55, 0x2f, 0x45, 0x55, 0x2f, 0x45, 0x55, 0x2f, 
+	 0x45, 0x55, 0x2f, 0x45, 0x55, 0x2f, 0x45, 0x55,  0x2f, 0x45, 0x55, 0x2f, 0x45, 0x55, 0x2f, 0x45, 
+	 0x55, 0x2f, 0x45, 0x55, 0x2f, 0x45, 0x5d, 0x35,  0x45, 0x51, 0x2b, 0x3b, 0x51, 0x31, 0x41, 0x57, 
+	 0x39, 0x47, 0x55, 0x41, 0x4d, 0x37, 0x25, 0x2f,  0xff, 0xfd, 0xff, 0xed, 0xe7, 0xed, 0xf3, 0xf3, 
+	 0xf9, 0xff, 0xff, 0xff, 0xf1, 0xf1, 0xf5, 0xff,  0xff, 0xff, 0xff, 0xfd, 0xff, 0xff, 0xfb, 0xff, 
+	 0xff, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfd, 0xfb,  0xff, 0xfb, 0xfb, 0xff, 0xf9, 0xfb, 0xff, 0xf9, 
+	 0xfb, 0xff, 0xf7, 0xfd, 0xff, 0xf7, 0xfd, 0xff,  0xfd, 0xfb, 0xff, 0xfb, 0xf9, 0xfd, 0xf3, 0xdf, 
+	 0xe9, 0x55, 0x41, 0x4b, 0x51, 0x37, 0x41, 0x53,  0x39, 0x43, 0x49, 0x2f, 0x39, 0x4b, 0x31, 0x3b, 
+	 0x4f, 0x39, 0x43, 0x4b, 0x35, 0x3f, 0x51, 0x31,  0x43, 0x51, 0x31, 0x43, 0x51, 0x31, 0x43, 0x51, 
+	 0x31, 0x43, 0x51, 0x31, 0x45, 0x51, 0x31, 0x45,  0x51, 0x31, 0x45, 0x51, 0x31, 0x45, 0x4f, 0x2f, 
+	 0x43, 0x4d, 0x2d, 0x41, 0x4d, 0x2d, 0x41, 0x51,  0x31, 0x43, 0x53, 0x33, 0x47, 0x55, 0x35, 0x47, 
+	 0x51, 0x31, 0x43, 0x4d, 0x2d, 0x41, 0x4f, 0x31,  0x3d, 0x5d, 0x3f, 0x4b, 0x61, 0x4d, 0x57, 0x13, 
+	 0x00, 0x07, 0xb3, 0xa9, 0xb1, 0xf9, 0xef, 0xf7,  0xe9, 0xeb, 0xf1, 0xfb, 0xfd, 0xff, 0xfb, 0xff, 
+	 0xff, 0xfb, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xfd, 0xff, 0xff, 0xfd, 0xff, 
+	 0xff, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xfb, 0xff, 0xff, 0xfd, 
+	 0xff, 0xff, 0xfb, 0xff, 0xff, 0xfb, 0xff, 0xff,  0xff, 0xfd, 0xff, 0xff, 0xfb, 0xff, 0x61, 0x4d, 
+	 0x57, 0x5d, 0x49, 0x53, 0x53, 0x39, 0x43, 0x49,  0x2d, 0x39, 0x55, 0x3b, 0x47, 0x5f, 0x45, 0x4f, 
+	 0x41, 0x2b, 0x35, 0x69, 0x53, 0x5d, 0x65, 0x45,  0x57, 0x5d, 0x3d, 0x51, 0x55, 0x35, 0x47, 0x4f, 
+	 0x2f, 0x43, 0x51, 0x31, 0x43, 0x51, 0x31, 0x43,  0x4f, 0x2f, 0x43, 0x4d, 0x2d, 0x3f, 0x4b, 0x2b, 
+	 0x3f, 0x53, 0x33, 0x45, 0x57, 0x37, 0x49, 0x51,  0x31, 0x45, 0x49, 0x29, 0x3b, 0x49, 0x29, 0x3b, 
+	 0x55, 0x35, 0x49, 0x63, 0x43, 0x55, 0x69, 0x4d,  0x57, 0x27, 0x09, 0x15, 0xbf, 0xa9, 0xb3, 0xff, 
+	 0xfb, 0xff, 0xff, 0xfd, 0xff, 0xff, 0xf9, 0xff,  0xfd, 0xff, 0xff, 0xed, 0xef, 0xf5, 0xfb, 0xff, 
+	 0xff, 0xfb, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xfd, 0xff, 0xff, 0xfd, 0xff, 
+	 0xff, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfd,  0xff, 0xff, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xfb, 0xff, 0xff, 0xfb, 0xff, 0xff,  0xff, 0xff, 0xff, 0xfd, 0xfd, 0xff, 0x3b, 0x2d, 
+	 0x33, 0x55, 0x47, 0x4d, 0x47, 0x33, 0x39, 0x47,  0x33, 0x39, 0x5f, 0x4f, 0x55, 0x53, 0x41, 0x49, 
+	 0xc9, 0xbf, 0xc3, 0xdf, 0xd5, 0xdb, 0x5f, 0x4d,  0x59, 0x55, 0x41, 0x4f, 0x49, 0x37, 0x43, 0x47, 
+	 0x35, 0x41, 0x4d, 0x3b, 0x47, 0x55, 0x43, 0x4f,  0x59, 0x45, 0x53, 0x57, 0x45, 0x51, 0x4d, 0x3b, 
+	 0x47, 0x57, 0x45, 0x51, 0x5d, 0x4b, 0x57, 0x59,  0x45, 0x53, 0x4f, 0x3d, 0x49, 0x51, 0x3d, 0x4b, 
+	 0x5f, 0x4d, 0x59, 0x6f, 0x5b, 0x69, 0xff, 0xf3,  0xf9, 0xff, 0xfd, 0xff, 0xff, 0xfd, 0xff, 0xff, 
+	 0xf5, 0xf9, 0xf9, 0xf5, 0xf9, 0xfd, 0xfb, 0xff,  0xef, 0xf1, 0xf5, 0xfd, 0xff, 0xff, 0xfb, 0xff, 
+	 0xff, 0xfb, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfd,  0xff, 0xff, 0xfd, 0xff, 0xfd, 0xfd, 0xff, 0xfd, 
+	 0xfd, 0xff, 0xfb, 0xff, 0xff, 0xf9, 0xff, 0xff,  0xfd, 0xfd, 0xff, 0xfb, 0xfb, 0xff, 0x77, 0x69, 
+	 0x6f, 0x4d, 0x3f, 0x45, 0x3f, 0x2b, 0x31, 0x49,  0x35, 0x3d, 0xc5, 0xb5, 0xbb, 0xf1, 0xe1, 0xe7, 
+	 0xff, 0xfd, 0xff, 0xff, 0xfd, 0xff, 0xff, 0xfb,  0xff, 0xff, 0xfb, 0xff, 0xff, 0xf7, 0xff, 0xff, 
+	 0xed, 0xf9, 0xe7, 0xd5, 0xe3, 0xc5, 0xb3, 0xc1,  0x9f, 0x8d, 0x9b, 0x87, 0x73, 0x81, 0x9f, 0x8d, 
+	 0x99, 0xa9, 0x97, 0xa5, 0xbb, 0xa9, 0xb7, 0xd1,  0xbf, 0xcb, 0xe7, 0xd5, 0xe1, 0xf9, 0xe7, 0xf5, 
+	 0xff, 0xf5, 0xff, 0xff, 0xfb, 0xff, 0xff, 0xf7,  0xfd, 0xff, 0xf9, 0xff, 0xff, 0xf5, 0xf9, 0xff, 
+	 0xfd, 0xff, 0xfd, 0xfb, 0xff, 0xff, 0xff, 0xff,  0xfd, 0xff, 0xff, 0xfb, 0xff, 0xff, 0xfb, 0xff, 
+	 0xff, 0xfb, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfd,  0xff, 0xff, 0xfb, 0xff, 0xfd, 0xfb, 0xff, 0xfd, 
+	 0xfd, 0xff, 0xfb, 0xff, 0xff, 0xfb, 0xff, 0xff,  0xfd, 0xfb, 0xff, 0xfb, 0xf9, 0xfd, 0xdf, 0xd5, 
+	 0xd9, 0x6d, 0x63, 0x67, 0x41, 0x35, 0x39, 0xeb,  0xdd, 0xe1, 0xff, 0xff, 0xff, 0xff, 0xf9, 0xfb, 
+	 0xfb, 0xfb, 0xfd, 0xf5, 0xf5, 0xf7, 0xff, 0xfb,  0xff, 0xff, 0xf9, 0xfd, 0xfb, 0xf5, 0xf9, 0xf7, 
+	 0xf1, 0xf5, 0xf7, 0xf1, 0xf7, 0xfd, 0xf7, 0xfd,  0xff, 0xfd, 0xff, 0xff, 0xfd, 0xff, 0xfd, 0xf7, 
+	 0xfd, 0xfd, 0xf7, 0xfd, 0xff, 0xf9, 0xff, 0xff,  0xfd, 0xff, 0xff, 0xfd, 0xff, 0xff, 0xfd, 0xff, 
+	 0xff, 0xfd, 0xff, 0xff, 0xfb, 0xff, 0xf9, 0xf9,  0xfb, 0xff, 0xff, 0xff, 0xf7, 0xf7, 0xf9, 0xfd, 
+	 0xfd, 0xff, 0xff, 0xff, 0xff, 0xef, 0xef, 0xf1,  0xef, 0xef, 0xf1, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfd,  0xff, 0xff, 0xfd, 0xff, 0xff, 0xfd, 0xff, 0xff, 
+	 0xff, 0xff, 0xfd, 0xff, 0xff, 0xfd, 0xff, 0xff,  0xff, 0xfd, 0xff, 0xfd, 0xfb, 0xff, 0xff, 0xfd, 
+	 0xff, 0x2b, 0x21, 0x25, 0x4f, 0x43, 0x47, 0xff,  0xf3, 0xf7, 0xf9, 0xf1, 0xf5, 0xff, 0xff, 0xff, 
+	 0xf7, 0xf7, 0xf9, 0xfd, 0xfd, 0xff, 0xfb, 0xf5,  0xf9, 0xff, 0xfb, 0xff, 0xff, 0xfd, 0xff, 0xff, 
+	 0xfd, 0xff, 0xff, 0xfd, 0xff, 0xff, 0xfb, 0xff,  0xfd, 0xf7, 0xfd, 0xfd, 0xf7, 0xfb, 0xff, 0xfd, 
+	 0xff, 0xff, 0xfd, 0xff, 0xff, 0xfd, 0xff, 0xff,  0xfd, 0xff, 0xfd, 0xf7, 0xfd, 0xf9, 0xf3, 0xf9, 
+	 0xf9, 0xf3, 0xf7, 0xf9, 0xf3, 0xf9, 0xf9, 0xf9,  0xfb, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfd, 
+	 0xfd, 0xff, 0xff, 0xff, 0xff, 0xfd, 0xfd, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfd,  0xff, 0xff, 0xfd, 0xff, 0xff, 0xfd, 0xff, 0xff, 
+	 0xfd, 0xff, 0xfd, 0xff, 0xff, 0xfd, 0xff, 0xff,  0xff, 0xff, 0xff, 0xfd, 0xfd, 0xff, 0xf7, 0xf1, 
+	 0xf3, 0xd5, 0xcf, 0xd1, 0xdd, 0xd3, 0xd7, 0xf9,  0xef, 0xf3, 0xff, 0xff, 0xff, 0xfd, 0xf9, 0xfd, 
+	 0xfb, 0xff, 0xff, 0xf9, 0xff, 0xff, 0xf9, 0xfb,  0xfd, 0xfb, 0xfb, 0xfd, 0xfb, 0xfb, 0xfd, 0xf9, 
+	 0xfb, 0xfd, 0xf9, 0xfb, 0xfd, 0xfb, 0xfd, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfb, 0xfb, 
+	 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xfb, 0xfd, 0xff, 0xfb, 0xfd, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf7, 0xff,  0xff, 0xe7, 0xf1, 0xf1, 0xf1, 0xf7, 0xf9, 0xf7, 
+	 0xfd, 0xff, 0xff, 0xff, 0xff, 0xfd, 0xfd, 0xff,  0xff, 0xfd, 0xff, 0xff, 0xfd, 0xff, 0xff, 0xfd, 
+	 0xff, 0xff, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xfb, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfd,  0xff, 0xff, 0xfd, 0xff, 0xff, 0xfd, 0xff, 0xff, 
+	 0xfd, 0xff, 0xfd, 0xff, 0xff, 0xfd, 0xff, 0xff,  0xfd, 0xfd, 0xff, 0xfb, 0xfb, 0xff, 0xff, 0xfb, 
+	 0xff, 0xf1, 0xeb, 0xed, 0xf7, 0xed, 0xf1, 0xff,  0xfd, 0xff, 0xf5, 0xf3, 0xf5, 0xff, 0xfb, 0xff, 
+	 0xf5, 0xfb, 0xfd, 0xfb, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xfd, 0xff, 0xff, 0xfb, 0xfb, 0xfd, 0xfb, 0xfd, 
+	 0xff, 0xfb, 0xfb, 0xfd, 0xfb, 0xfb, 0xfd, 0xfb,  0xfd, 0xff, 0xfd, 0xfd, 0xff, 0xfd, 0xff, 0xff, 
+	 0xfb, 0xfd, 0xff, 0xfb, 0xfb, 0xfd, 0xf7, 0xff,  0xff, 0xf3, 0xfd, 0xfd, 0xfb, 0xff, 0xff, 0xfb, 
+	 0xff, 0xff, 0xf9, 0xf9, 0xfb, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfd, 
+	 0xff, 0xff, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xfb, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
+};
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/OBJ/STM32F767NUCLEO144_GCC/MAC/Makefile
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/OBJ/STM32F767NUCLEO144_GCC/MAC/Makefile	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/OBJ/STM32F767NUCLEO144_GCC/MAC/Makefile	(revision 457)
@@ -0,0 +1,603 @@
+#
+#  TOPPERS/ASP Kernel
+#      Toyohashi Open Platform for Embedded Real-Time Systems/
+#      Advanced Standard Profile Kernel
+# 
+#  Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
+#                              Toyohashi Univ. of Technology, JAPAN
+#  Copyright (C) 2006-2014 by Embedded and Real-Time Systems Laboratory
+#              Graduate School of Information Science, Nagoya Univ., JAPAN
+# 
+#  ä¸è¨èä½æ¨©è
+ã¯ï¼ä»¥ä¸ã®(1)ï½(4)ã®æ¡ä»¶ãæºããå ´åã«éãï¼æ¬ã½ããã¦ã§
+#  ã¢ï¼æ¬ã½ããã¦ã§ã¢ãæ¹å¤ãããã®ãå«ãï¼ä»¥ä¸åãï¼ãä½¿ç¨ã»è¤è£½ã»æ¹
+#  å¤ã»åé
+å¸ï¼ä»¥ä¸ï¼å©ç¨ã¨å¼ã¶ï¼ãããã¨ãç¡åã§è¨±è«¾ããï¼
+#  (1) æ¬ã½ããã¦ã§ã¢ãã½ã¼ã¹ã³ã¼ãã®å½¢ã§å©ç¨ããå ´åã«ã¯ï¼ä¸è¨ã®èä½
+#      æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨ã®ç¡ä¿è¨¼è¦å®ãï¼ãã®ã¾ã¾ã®å½¢ã§ã½ã¼
+#      ã¹ã³ã¼ãä¸­ã«å«ã¾ãã¦ãããã¨ï¼
+#  (2) æ¬ã½ããã¦ã§ã¢ãï¼ã©ã¤ãã©ãªå½¢å¼ãªã©ï¼ä»ã®ã½ããã¦ã§ã¢éçºã«ä½¿
+#      ç¨ã§ããå½¢ã§åé
+å¸ããå ´åã«ã¯ï¼åé
+å¸ã«ä¼´ããã­ã¥ã¡ã³ãï¼å©ç¨
+#      è
+ããã¥ã¢ã«ãªã©ï¼ã«ï¼ä¸è¨ã®èä½æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨
+#      ã®ç¡ä¿è¨¼è¦å®ãæ²è¼ãããã¨ï¼
+#  (3) æ¬ã½ããã¦ã§ã¢ãï¼æ©å¨ã«çµã¿è¾¼ããªã©ï¼ä»ã®ã½ããã¦ã§ã¢éçºã«ä½¿
+#      ç¨ã§ããªãå½¢ã§åé
+å¸ããå ´åã«ã¯ï¼æ¬¡ã®ããããã®æ¡ä»¶ãæºããã
+#      ã¨ï¼
+#    (a) åé
+å¸ã«ä¼´ããã­ã¥ã¡ã³ãï¼å©ç¨è
+ããã¥ã¢ã«ãªã©ï¼ã«ï¼ä¸è¨ã®è
+#        ä½æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨ã®ç¡ä¿è¨¼è¦å®ãæ²è¼ãããã¨ï¼
+#    (b) åé
+å¸ã®å½¢æ
+ãï¼å¥ã«å®ããæ¹æ³ã«ãã£ã¦ï¼TOPPERSãã­ã¸ã§ã¯ãã«
+#        å ±åãããã¨ï¼
+#  (4) æ¬ã½ããã¦ã§ã¢ã®å©ç¨ã«ããç´æ¥çã¾ãã¯éæ¥çã«çãããããªãæ
+#      å®³ãããï¼ä¸è¨èä½æ¨©è
+ããã³TOPPERSãã­ã¸ã§ã¯ããå
+è²¬ãããã¨ï¼
+#      ã¾ãï¼æ¬ã½ããã¦ã§ã¢ã®ã¦ã¼ã¶ã¾ãã¯ã¨ã³ãã¦ã¼ã¶ããã®ãããªãç
+#      ç±ã«åºã¥ãè«æ±ãããï¼ä¸è¨èä½æ¨©è
+ããã³TOPPERSãã­ã¸ã§ã¯ãã
+#      å
+è²¬ãããã¨ï¼
+# 
+#  æ¬ã½ããã¦ã§ã¢ã¯ï¼ç¡ä¿è¨¼ã§æä¾ããã¦ãããã®ã§ããï¼ä¸è¨èä½æ¨©è
+ã
+#  ãã³TOPPERSãã­ã¸ã§ã¯ãã¯ï¼æ¬ã½ããã¦ã§ã¢ã«é¢ãã¦ï¼ç¹å®ã®ä½¿ç¨ç®ç
+#  ã«å¯¾ããé©åæ§ãå«ãã¦ï¼ãããªãä¿è¨¼ãè¡ããªãï¼ã¾ãï¼æ¬ã½ããã¦ã§
+#  ã¢ã®å©ç¨ã«ããç´æ¥çã¾ãã¯éæ¥çã«çãããããªãæå®³ã«é¢ãã¦ãï¼ã
+#  ã®è²¬ä»»ãè² ããªãï¼
+# 
+#  $Id$
+# 
+
+#
+#  ã¿ã¼ã²ããã®æå®ï¼Makefile.targetã§ä¸æ¸ããããã®ãé²ãããï¼
+#
+all:
+
+#
+#  ã¿ã¼ã²ããç¥ç§°ã®å®ç¾©
+#
+TARGET = stm32f767nucleo144_gcc
+
+#
+#  ãã­ã°ã©ãã³ã°è¨èªã®å®ç¾©
+#
+SRCLANG = c
+ifeq ($(SRCLANG),c)
+  LIBS = -lc -lnosys
+endif
+ifeq ($(SRCLANG),c++)
+  USE_CXX = true
+  CXXLIBS = -lstdc++ -lm -lc
+  CXXRTS = cxxrt.o newlibrt.o
+endif
+
+#
+#  ã½ã¼ã¹ãã¡ã¤ã«ã®ãã£ã¬ã¯ããªã®å®ç¾©
+#
+SRCDIR = ../../..
+
+#
+#  ãªãã¸ã§ã¯ããã¡ã¤ã«åã®æ¡å¼µå­ã®è¨­å®
+#
+OBJEXT = exe
+
+#
+#  å®è¡ç°å¢ã®å®ç¾©ï¼ã¿ã¼ã²ããä¾å­ã«ä¸æ¸ããããå ´åãããï¼
+#
+DBGENV := ROM
+
+#
+#  ã«ã¼ãã«ã©ã¤ãã©ãªï¼libkernel.aï¼ã®ãã£ã¬ã¯ããªå
+#  ï¼ã«ã¼ãã«ã©ã¤ãã©ãªãmakeå¯¾è±¡ã«ããæã¯ï¼ç©ºã«å®ç¾©ããï¼
+#
+KERNEL_LIB = ../libkernel
+
+#
+#  ã«ã¼ãã«ãé¢æ°åä½ã§ã³ã³ãã¤ã«ãããã©ããã®å®ç¾©
+#
+KERNEL_FUNCOBJS = 
+
+#
+#  ãã¬ã¼ã¹ã­ã°ãåå¾ãããã©ããã®å®ç¾©
+#
+ENABLE_TRACE = 
+
+#
+#  ã¦ã¼ãã£ãªãã£ãã­ã°ã©ã ã®åç§°
+#
+PERL = /usr/bin/perl
+CFG = $(SRCDIR)/cfg/cfg/cfg
+
+#
+#  ãªãã¸ã§ã¯ããã¡ã¤ã«åã®å®ç¾©
+#
+OBJNAME = asp
+ifdef OBJEXT
+  OBJFILE = $(OBJNAME).$(OBJEXT)
+  CFG1_OUT = cfg1_out.$(OBJEXT)
+else
+  OBJFILE = $(OBJNAME)
+  CFG1_OUT = cfg1_out
+endif
+
+#
+#  ã¿ã¼ã²ããä¾å­é¨ã®ãã£ã¬ã¯ããªã®å®ç¾©
+#
+TARGETDIR = $(SRCDIR)/target/$(TARGET)
+
+#
+#  ã¿ã¼ã²ããä¾å­ã®å®ç¾©ã®ã¤ã³ã¯ã«ã¼ã
+#
+include $(TARGETDIR)/Makefile.target
+
+#
+#  ã³ã³ãã£ã®ã¥ã¬ã¼ã¿é¢ä¿ã®å¤æ°ã®å®ç¾©
+#
+CFG_TABS := --api-table $(SRCDIR)/kernel/kernel_api.csv \
+			--cfg1-def-table $(SRCDIR)/kernel/kernel_def.csv $(CFG_TABS)
+
+CFG_ASMOBJS := $(CFG_ASMOBJS)
+CFG_COBJS := kernel_cfg.o $(CFG_COBJS)
+CFG_OBJS := $(CFG_ASMOBJS) $(CFG_COBJS)
+CFG2_OUT_SRCS := kernel_cfg.h kernel_cfg.c $(CFG2_OUT_SRCS)
+
+#
+#  å
+±éã³ã³ãã¤ã«ãªãã·ã§ã³ã®å®ç¾©
+#
+COPTS := $(COPTS) -g -ffunction-sections -fdata-sections
+ifndef OMIT_WARNING_ALL
+  COPTS := $(COPTS) -Wall
+endif
+ifndef OMIT_OPTIMIZATION
+  COPTS := $(COPTS) -O2
+endif
+CDEFS := $(CDEFS) -DMONITOR_PORTID=1 -DUSE_CUPCOMMAND -DLWIP_COMPAT_MUTEX=1 -DLWIP_COMPAT_MUTEX_ALLOWED -DUSE_PINGSEND
+INCLUDES := -I. -I$(SRCDIR)/include -I$(SRCDIR)/arch -I$(SRCDIR) $(INCLUDES)
+LDFLAGS := $(LDFLAGS) 
+CFG1_OUT_LDFLAGS := $(CFG1_OUT_LDFLAGS) 
+LIBS := $(LIBS) $(CXXLIBS)
+CFLAGS = $(COPTS) $(CDEFS) $(INCLUDES)
+
+#
+#  ã¢ããªã±ã¼ã·ã§ã³ãã­ã°ã©ã ã«é¢ããå®ç¾©
+#
+APPLNAME = lwip_test
+APPLDIR = 
+APPL_CFG = $(APPLNAME).cfg
+
+APPL_DIR = $(APPLDIR) $(SRCDIR)/library
+APPL_ASMOBJS =
+ifdef USE_CXX
+  APPL_CXXOBJS = $(APPLNAME).o 
+  APPL_COBJS = command.o lwip_prvmib.o ping.o chargen.o udpecho.o shell.o tcpecho.o netio.o
+else
+  APPL_COBJS = $(APPLNAME).o command.o lwip_prvmib.o ping.o chargen.o udpecho.o shell.o tcpecho.o netio.o
+endif
+APPL_COBJS := $(APPL_COBJS) log_output.o vasyslog.o t_perror.o strerror.o
+APPL_CFLAGS =
+APPL_LIBS =
+ifdef APPLDIR
+  INCLUDES := $(INCLUDES) $(foreach dir,$(APPLDIR),-I$(dir))
+endif
+
+#  ããã«ã¦ã§ã¢ã® Makefile ã®ã¤ã³ã¯ã«ã¼ã
+#
+#include $(SRCDIR)/files/ff/Makefile.config
+#include $(SRCDIR)/files/Makefile.config
+include $(SRCDIR)/monitor/Makefile.config
+include $(SRCDIR)/lwip/Makefile.config
+
+#
+#  ã·ã¹ãã ãµã¼ãã¹ã«é¢ããå®ç¾©
+#
+SYSSVC_DIR := $(SYSSVC_DIR) $(SRCDIR)/syssvc $(SRCDIR)/pdic/stm32f7xx $(SRCDIR)/library
+SYSSVC_ASMOBJS := $(SYSSVC_ASMOBJS)
+SYSSVC_COBJS := $(SYSSVC_COBJS) banner.o syslog.o serial.o logtask.o armv7m.o \
+				 device.o sdram.o emac.o clock.o malloc.o tlsf.o $(CXXRTS)
+SYSSVC_CFLAGS := $(SYSSVC_CFLAGS)
+SYSSVC_LIBS := $(SYSSVC_LIBS)
+INCLUDES := -I$(SRCDIR)/pdic/stm32f7xx $(INCLUDES)
+LDFLAGS := $(LDFLAGS) \
+	-Wl,--wrap=_malloc_r \
+	-Wl,--wrap=_calloc_r \
+	-Wl,--wrap=_free_r \
+	-Wl,--wrap=_realloc_r
+
+#
+#  ã«ã¼ãã«ã«é¢ããå®ç¾©
+#
+#  KERNEL_ASMOBJS: ã«ã¼ãã«ã©ã¤ãã©ãªã«å«ããï¼ã½ã¼ã¹ãã¢ã»ã³ããªè¨èªã®
+#				   ãªãã¸ã§ã¯ããã¡ã¤ã«ï¼
+#  KERNEL_COBJS: ã«ã¼ãã«ã®ã©ã¤ãã©ãªã«å«ããï¼ã½ã¼ã¹ãCè¨èªã§ï¼ã½ã¼ã¹
+#				 ãã¡ã¤ã«ã¨1å¯¾1ã«å¯¾å¿ãããªãã¸ã§ã¯ããã¡ã¤ã«ï¼
+#  KERNEL_LCSRCS: ã«ã¼ãã«ã®ã©ã¤ãã©ãªã«å«ããCè¨èªã®ã½ã¼ã¹ãã¡ã¤ã«ã§ï¼
+#				  1ã¤ã®ã½ã¼ã¹ãã¡ã¤ã«ããè¤æ°ã®ãªãã¸ã§ã¯ããã¡ã¤ã«ãç
+#				  æãããã®ï¼
+#  KERNEL_LCOBJS: ä¸ã®ã½ã¼ã¹ãã¡ã¤ã«ããçæããããªãã¸ã§ã¯ããã¡ã¤ã«ï¼
+#  KERNEL_AUX_COBJS: ã­ã¼ãã¢ã¸ã¥ã¼ã«ã«å«ããªããï¼ã«ã¼ãã«ã®ã½ã¼ã¹ãã¡
+#					 ã¤ã«ã¨åããªãã·ã§ã³ãé©ç¨ãã¦ã³ã³ãã¤ã«ãã¹ãï¼ã½ã¼
+#					 ã¹ãCè¨èªã®ãªãã¸ã§ã¯ããã¡ã¤ã«ï¼
+#
+KERNEL_DIR := $(KERNEL_DIR) $(SRCDIR)/kernel
+KERNEL_ASMOBJS := $(KERNEL_ASMOBJS)
+KERNEL_COBJS := $(KERNEL_COBJS)
+KERNEL_CFLAGS := $(KERNEL_CFLAGS) -I$(SRCDIR)/kernel
+ifdef OMIT_MAKEOFFSET
+  OFFSET_H =
+else
+  OFFSET_H = offset.h
+ifndef OFFSET_TF
+  KERNEL_AUX_COBJS := $(KERNEL_AUX_COBJS) makeoffset.o
+endif
+endif
+
+#
+#  ã¿ã¼ã²ãããã¡ã¤ã«ï¼è¤æ°ãåæã«é¸æãã¦ã¯ãªããªãï¼
+#
+#all: $(OBJFILE)
+all: $(OBJNAME).bin
+#all: $(OBJNAME).srec
+
+##### ä»¥ä¸ã¯ç·¨éããªããã¨ #####
+
+#
+#  ç°å¢ã«ä¾å­ããã³ã³ãã¤ã«ãªãã·ã§ã³ã®å®ç¾©
+#
+ifdef DBGENV
+  CDEFS := $(CDEFS) -D$(DBGENV)
+endif
+
+#
+#  ã«ã¼ãã«ã®ãã¡ã¤ã«æ§æã®å®ç¾©
+#
+include $(SRCDIR)/kernel/Makefile.kernel
+ifdef KERNEL_FUNCOBJS
+  KERNEL_LCSRCS := $(KERNEL_FCSRCS)
+  KERNEL_LCOBJS := $(foreach file,$(KERNEL_FCSRCS),$($(file:.c=)))
+else
+  KERNEL_CFLAGS := -DALLFUNC $(KERNEL_CFLAGS)
+  KERNEL_COBJS := $(KERNEL_COBJS) \
+					$(foreach file,$(KERNEL_FCSRCS),$(file:.c=.o))
+endif
+
+#
+#  ã½ã¼ã¹ãã¡ã¤ã«ã®ãããã£ã¬ã¯ããªã«é¢ããå®ç¾©
+#
+vpath %.c $(KERNEL_DIR) $(SYSSVC_DIR) $(APPL_DIR)
+vpath %.S $(KERNEL_DIR) $(SYSSVC_DIR) $(APPL_DIR)
+vpath %.cfg $(APPL_DIR)
+
+#
+#  ã³ã³ãã¤ã«ã®ããã®å¤æ°ã®å®ç¾©
+#
+KERNEL_LIB_OBJS = $(KERNEL_ASMOBJS) $(KERNEL_COBJS) $(KERNEL_LCOBJS)
+SYSSVC_OBJS = $(SYSSVC_ASMOBJS) $(SYSSVC_COBJS)
+APPL_OBJS = $(APPL_ASMOBJS) $(APPL_COBJS) $(APPL_CXXOBJS)
+ALL_OBJS = $(START_OBJS) $(APPL_OBJS) $(SYSSVC_OBJS) $(CFG_OBJS) \
+											$(END_OBJS) $(HIDDEN_OBJS)
+ifdef KERNEL_LIB
+  ALL_LIBS = $(APPL_LIBS) $(SYSSVC_LIBS) -lkernel $(LIBS)
+  LIBS_DEP = $(filter %.a,$(ALL_LIBS)) $(KERNEL_LIB)/libkernel.a
+  LDFLAGS := $(LDFLAGS) -L$(KERNEL_LIB)
+  REALCLEAN_FILES := libkernel.a $(REALCLEAN_FILES)
+else
+  ALL_LIBS = $(APPL_LIBS) $(SYSSVC_LIBS) libkernel.a $(LIBS)
+  LIBS_DEP = $(filter %.a,$(ALL_LIBS))
+endif
+
+ifdef TEXT_START_ADDRESS
+  LDFLAGS := $(LDFLAGS) -Wl,-Ttext,$(TEXT_START_ADDRESS)
+  CFG1_OUT_LDFLAGS := $(CFG1_OUT_LDFLAGS) -Wl,-Ttext,$(TEXT_START_ADDRESS)
+endif
+ifdef DATA_START_ADDRESS
+  LDFLAGS := $(LDFLAGS) -Wl,-Tdata,$(DATA_START_ADDRESS)
+  CFG1_OUT_LDFLAGS := $(CFG1_OUT_LDFLAGS) -Wl,-Tdata,$(DATA_START_ADDRESS)
+endif
+ifdef LDSCRIPT
+  LDFLAGS := $(LDFLAGS) -T $(LDSCRIPT)
+  CFG1_OUT_LDFLAGS := $(CFG1_OUT_LDFLAGS) -T $(LDSCRIPT)
+endif
+
+#
+#  ãªãã»ãããã¡ã¤ã«ï¼offset.hï¼ã®çæè¦å
+#
+ifdef OFFSET_TF
+offset.h: $(APPL_CFG) kernel_cfg.timestamp
+	$(CFG) --pass 3 --kernel asp $(INCLUDES) \
+				--rom-image cfg1_out.srec --symbol-table cfg1_out.syms \
+				-T $(OFFSET_TF) $(CFG_TABS) $<
+else
+offset.h: makeoffset.s $(SRCDIR)/utils/genoffset
+	$(PERL) $(SRCDIR)/utils/genoffset makeoffset.s > offset.h
+endif
+
+#
+#  ã«ã¼ãã«ã®ã³ã³ãã£ã®ã¥ã¬ã¼ã·ã§ã³ãã¡ã¤ã«ã®çæ
+#
+cfg1_out.c: $(APPL_CFG)
+	$(CFG) --pass 1 --kernel asp $(INCLUDES) $(CFG_TABS) $<
+
+$(CFG2_OUT_SRCS): kernel_cfg.timestamp
+kernel_cfg.timestamp: $(APPL_CFG) \
+						$(START_OBJS) cfg1_out.o $(END_OBJS) $(HIDDEN_OBJS)
+	$(LINK) $(CFLAGS) $(CFG1_OUT_LDFLAGS) -o $(CFG1_OUT) \
+						$(START_OBJS) cfg1_out.o $(END_OBJS)
+	$(NM) -n $(CFG1_OUT) > cfg1_out.syms
+	$(OBJCOPY) -O srec -S $(CFG1_OUT) cfg1_out.srec
+	$(CFG) --pass 2 --kernel asp $(INCLUDES) \
+				-T $(TARGETDIR)/target.tf $(CFG_TABS) $<
+	touch -r kernel_cfg.c kernel_cfg.timestamp
+
+#
+#  ã«ã¼ãã«ã©ã¤ãã©ãªãã¡ã¤ã«ã®çæ
+#
+$(KERNEL_LIB)/libkernel.a: $(OFFSET_H) $(KERNEL_LIB_OBJS)
+	rm -f libkernel.a
+	$(AR) -rcs $(KERNEL_LIB)/libkernel.a $(KERNEL_LIB_OBJS)
+	$(RANLIB) $(KERNEL_LIB)/libkernel.a
+
+#
+#  ç¹å¥ãªä¾å­é¢ä¿ã®å®ç¾©
+#
+banner.o: kernel_cfg.timestamp $(filter-out banner.o,$(ALL_OBJS)) $(LIBS_DEP)
+
+#
+#  å
+¨ä½ã®ãªã³ã¯
+#
+$(OBJFILE): $(APPL_CFG) kernel_cfg.timestamp $(ALL_OBJS) $(LIBS_DEP)
+	$(LINK) $(CFLAGS) $(LDFLAGS) -o $(OBJFILE) $(START_OBJS) \
+			-Wl,-Map=$(OBJNAME).map,--cref -Wl,--gc-sections -Wl,-e_kernel__start,--gc-keep-exported=_kernel_istk \
+			$(APPL_OBJS) $(SYSSVC_OBJS) $(CFG_OBJS) \
+			-Wl,--start-group $(ALL_LIBS) -Wl,--end-group $(END_OBJS)
+	$(NM) -n $(OBJFILE) > $(OBJNAME).syms
+	$(OBJCOPY) -O srec -S $(OBJFILE) $(OBJNAME).srec
+	$(CFG) --pass 3 --kernel asp $(INCLUDES) \
+				--rom-image $(OBJNAME).srec --symbol-table $(OBJNAME).syms \
+				-T $(TARGETDIR)/target_check.tf $(CFG_TABS) $<
+
+#
+#  ãã¤ããªãã¡ã¤ã«ã®çæ
+#
+$(OBJNAME).bin: $(OBJFILE)
+	$(OBJCOPY) -O binary -S $(OBJFILE) $(OBJNAME).bin
+
+#
+#  Sã¬ã³ã¼ããã¡ã¤ã«ã®çæ
+#
+$(OBJNAME).srec: $(OBJFILE)
+	$(OBJCOPY) -O srec -S $(OBJFILE) $(OBJNAME).srec
+
+#
+#  ã³ã³ãã¤ã«çµæã®æ¶å»
+#
+.PHONY: clean
+clean:
+	rm -f \#* *~ *.o $(CLEAN_FILES)
+	rm -f $(OBJFILE) $(OBJNAME).syms $(OBJNAME).srec $(OBJNAME).bin
+	rm -f kernel_cfg.timestamp $(CFG2_OUT_SRCS)
+	rm -f cfg1_out.c $(CFG1_OUT) cfg1_out.syms cfg1_out.srec
+ifndef KERNEL_LIB
+	rm -f libkernel.a
+endif
+	rm -f makeoffset.s offset.h
+
+.PHONY: cleankernel
+cleankernel:
+	rm -rf $(KERNEL_LIB_OBJS)
+	rm -f makeoffset.s offset.h
+
+.PHONY: cleandep
+cleandep:
+	if ! [ -f Makefile.depend ]; then \
+		rm -f kernel_cfg.timestamp $(CFG2_OUT_SRCS); \
+		rm -f cfg1_out.c cfg1_out.o $(CFG1_OUT) cfg1_out.syms cfg1_out.srec; \
+		rm -f makeoffset.s offset.h; \
+	fi
+	rm -f Makefile.depend
+
+.PHONY: realclean
+realclean: cleandep clean
+	rm -f $(REALCLEAN_FILES)
+
+#
+#  ã³ã³ãã£ã®ã¥ã¬ã¼ã¿ãçæãããã¡ã¤ã«ã®ã³ã³ãã¤ã«ã«ã¼ã«ã¨ä¾å­é¢ä¿ä½æ
+#  ã«ã¼ã«ã®å®ç¾©
+#
+#  ã³ã³ãã£ã®ã¥ã¬ã¼ã¿ãçæãããã¡ã¤ã«ã¯ï¼ã¢ããªã±ã¼ã·ã§ã³ãã­ã°ã©ã ç¨ï¼
+#  ã·ã¹ãã ãµã¼ãã¹ç¨ï¼ã«ã¼ãã«ç¨ã®ãã¹ã¦ã®ãªãã·ã§ã³ãä»ãã¦ã³ã³ãã¤ã«
+#  ããï¼
+#
+ALL_CFG_COBJS = $(CFG_COBJS) cfg1_out.o
+ALL_CFG_ASMOBJS = $(CFG_ASMOBJS)
+CFG_CFLAGS = $(APPL_CFLAGS) $(SYSSVC_CFLAGS) $(KERNEL_CFLAGS)
+
+$(ALL_CFG_COBJS): %.o: %.c
+	$(CC) -c $(CFLAGS) $(CFG_CFLAGS) $<
+
+$(ALL_CFG_COBJS:.o=.s): %.s: %.c
+	$(CC) -S $(CFLAGS) $(CFG_CFLAGS) $<
+
+$(ALL_CFG_COBJS:.o=.d): %.d: %.c
+	@$(PERL) $(SRCDIR)/utils/makedep -C $(CC) $(MAKEDEP_OPTS) \
+		-O "$(CFLAGS) $(CFG_CFLAGS)" $< >> Makefile.depend
+
+$(ALL_CFG_ASMOBJS): %.o: %.S
+	$(CC) -c $(CFLAGS) $(CFG_CFLAGS) $<
+
+$(ALL_CFG_ASMOBJS:.o=.d): %.d: %.S
+	@$(PERL) $(SRCDIR)/utils/makedep -C $(CC) $(MAKEDEP_OPTS) \
+		-O "$(CFLAGS) $(CFG_CFLAGS)" $< >> Makefile.depend
+
+#
+#  ç¹æ®ãªä¾å­é¢ä¿ä½æã«ã¼ã«ã®å®ç¾©
+#
+cfg1_out.depend: $(APPL_CFG)
+	@$(CFG) -M cfg1_out.c $(INCLUDES) $< >> Makefile.depend
+
+makeoffset.d: makeoffset.c
+	@$(PERL) $(SRCDIR)/utils/makedep -C $(CC) $(MAKEDEP_OPTS) \
+		-T "makeoffset.s" -O "$(CFLAGS) $(KERNEL_CFLAGS)" $< >> Makefile.depend
+
+#
+#  ä¾å­é¢ä¿ãã¡ã¤ã«ã®çæ
+#
+.PHONY: gendepend
+gendepend:
+	@echo "Generating Makefile.depend."
+
+.PHONY: depend
+ifdef KERNEL_LIB
+depend: cleandep kernel_cfg.timestamp gendepend \
+		cfg1_out.depend cfg1_out.d \
+		$(ALL_OBJS:.o=.d)
+else
+depend: cleandep $(OFFSET_H) kernel_cfg.timestamp gendepend \
+		cfg1_out.depend cfg1_out.d \
+		$(KERNEL_AUX_COBJS:.o=.d) $(KERNEL_ASMOBJS:.o=.d) \
+		$(KERNEL_COBJS:.o=.d) $(KERNEL_LCSRCS:.c=.d) $(ALL_OBJS:.o=.d)
+endif
+
+#
+#  ä¾å­é¢ä¿ãã¡ã¤ã«ãã¤ã³ã¯ã«ã¼ã
+#
+-include Makefile.depend
+
+#
+#  éçºãã¼ã«ã®ã³ãã³ãåã®å®ç¾©
+#
+ifeq ($(TOOL),gcc)
+  #
+  #  GNUéçºç°å¢ç¨
+  #
+  ifdef GCC_TARGET
+    GCC_TARGET_PREFIX = $(GCC_TARGET)-
+  else
+    GCC_TARGET_PREFIX =
+  endif
+  CC = $(GCC_TARGET_PREFIX)gcc
+  CXX = $(GCC_TARGET_PREFIX)g++
+  AS = $(GCC_TARGET_PREFIX)as
+  LD = $(GCC_TARGET_PREFIX)ld
+  AR = $(GCC_TARGET_PREFIX)ar
+  NM = $(GCC_TARGET_PREFIX)nm
+  RANLIB = $(GCC_TARGET_PREFIX)ranlib
+  OBJCOPY = $(GCC_TARGET_PREFIX)objcopy
+  OBJDUMP = $(GCC_TARGET_PREFIX)objdump
+endif
+
+ifdef USE_CXX
+  LINK = $(CXX)
+else
+  LINK = $(CC)
+endif
+
+#
+#  ã³ã³ãã¤ã«ã«ã¼ã«ã®å®ç¾©
+#
+KERNEL_ALL_COBJS = $(KERNEL_COBJS) $(KERNEL_AUX_COBJS)
+
+$(KERNEL_ALL_COBJS): %.o: %.c
+	$(CC) -c $(CFLAGS) $(KERNEL_CFLAGS) $<
+
+$(KERNEL_ALL_COBJS:.o=.s): %.s: %.c
+	$(CC) -S $(CFLAGS) $(KERNEL_CFLAGS) $<
+
+$(KERNEL_LCOBJS): %.o:
+	$(CC) -DTOPPERS_$(*F) -o $@ -c $(CFLAGS) $(KERNEL_CFLAGS) $<
+
+$(KERNEL_LCOBJS:.o=.s): %.s:
+	$(CC) -DTOPPERS_$(*F) -o $@ -S $(CFLAGS) $(KERNEL_CFLAGS) $<
+
+$(KERNEL_ASMOBJS): %.o: %.S
+	$(CC) -c $(CFLAGS) $(KERNEL_CFLAGS) $<
+
+$(SYSSVC_COBJS): %.o: %.c
+	$(CC) -c $(CFLAGS) $(SYSSVC_CFLAGS) $<
+
+$(SYSSVC_COBJS:.o=.s): %.s: %.c
+	$(CC) -S $(CFLAGS) $(SYSSVC_CFLAGS) $<
+
+$(SYSSVC_ASMOBJS): %.o: %.S
+	$(CC) -c $(CFLAGS) $(SYSSVC_CFLAGS) $<
+
+$(APPL_COBJS): %.o: %.c
+	$(CC) -c $(CFLAGS) $(APPL_CFLAGS) $<
+
+$(APPL_COBJS:.o=.s): %.s: %.c
+	$(CC) -S $(CFLAGS) $(APPL_CFLAGS) $<
+
+$(APPL_CXXOBJS): %.o: %.cpp
+	$(CXX) -c $(CFLAGS) $(APPL_CFLAGS) $<
+
+$(APPL_CXXOBJS:.o=.s): %.s: %.cpp
+	$(CXX) -S $(CFLAGS) $(APPL_CFLAGS) $<
+
+$(APPL_ASMOBJS): %.o: %.S
+	$(CC) -c $(CFLAGS) $(APPL_CFLAGS) $<
+
+#
+#  ä¾å­é¢ä¿ä½æã«ã¼ã«ã®å®ç¾©
+#
+$(KERNEL_COBJS:.o=.d): %.d: %.c
+	@$(PERL) $(SRCDIR)/utils/makedep -C $(CC) $(MAKEDEP_OPTS) \
+		-O "$(CFLAGS) $(KERNEL_CFLAGS)" $< >> Makefile.depend
+
+$(KERNEL_LCSRCS:.c=.d): %.d: %.c
+	@$(PERL) $(SRCDIR)/utils/makedep -C $(CC) $(MAKEDEP_OPTS) -T "$($*)" \
+		-O "-DALLFUNC $(CFLAGS) $(KERNEL_CFLAGS)" $< >> Makefile.depend
+
+$(KERNEL_ASMOBJS:.o=.d): %.d: %.S
+	@$(PERL) $(SRCDIR)/utils/makedep -C $(CC) $(MAKEDEP_OPTS) \
+		-O "$(CFLAGS) $(KERNEL_CFLAGS)" $< >> Makefile.depend
+
+$(SYSSVC_COBJS:.o=.d): %.d: %.c
+	@$(PERL) $(SRCDIR)/utils/makedep -C $(CC) $(MAKEDEP_OPTS) \
+		-O "$(CFLAGS) $(SYSSVC_CFLAGS)" $< >> Makefile.depend
+
+$(SYSSVC_ASMOBJS:.o=.d): %.d: %.S
+	@$(PERL) $(SRCDIR)/utils/makedep -C $(CC) $(MAKEDEP_OPTS) \
+		-O "$(CFLAGS) $(SYSSVC_CFLAGS)" $< >> Makefile.depend
+
+$(APPL_COBJS:.o=.d): %.d: %.c
+	@$(PERL) $(SRCDIR)/utils/makedep -C $(CC) $(MAKEDEP_OPTS) \
+		-O "$(CFLAGS) $(APPL_CFLAGS)" $< >> Makefile.depend
+
+$(APPL_CXXOBJS:.o=.d): %.d: %.cpp
+	@$(PERL) $(SRCDIR)/utils/makedep -C $(CXX) $(MAKEDEP_OPTS) \
+		-O "$(CFLAGS) $(APPL_CFLAGS)" $< >> Makefile.depend
+
+$(APPL_ASMOBJS:.o=.d): %.d: %.S
+	@$(PERL) $(SRCDIR)/utils/makedep -C $(CC) $(MAKEDEP_OPTS) \
+		-O "$(CFLAGS) $(APPL_CFLAGS)" $< >> Makefile.depend
+
+#
+#  ããã©ã«ãã³ã³ãã¤ã«ã«ã¼ã«ãä¸æ¸ã
+#
+%.o: %.c
+	@echo "*** Default compile rules should not be used."
+	$(CC) -c $(CFLAGS) $<
+
+%.s: %.c
+	@echo "*** Default compile rules should not be used."
+	$(CC) -S $(CFLAGS) $<
+
+%.o: %.cpp
+	@echo "*** Default compile rules should not be used."
+	$(CXX) -c $(CFLAGS) $<
+
+%.s: %.cpp
+	@echo "*** Default compile rules should not be used."
+	$(CXX) -S $(CFLAGS) $<
+
+%.o: %.S
+	@echo "*** Default compile rules should not be used."
+	$(CC) -c $(CFLAGS) $<
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/OBJ/STM32F767NUCLEO144_GCC/MAC/command.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/OBJ/STM32F767NUCLEO144_GCC/MAC/command.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/OBJ/STM32F767NUCLEO144_GCC/MAC/command.c	(revision 457)
@@ -0,0 +1,181 @@
+#include <kernel.h>
+#include <t_syslog.h>
+#include <stdio.h>
+#include <t_stdlib.h>
+#include <stdlib.h>
+#include "syssvc/serial.h"
+#include "syssvc/syslog.h"
+#include "kernel_cfg.h"
+#include "monitor.h"
+#include "device.h"
+
+/*
+ *  デバイスコマンド番号
+ */
+static int_t led_func(int argc, char **argv);
+static int_t dip_func(int argc, char **argv);
+#ifdef USE_PINGSEND
+static int_t png_func(int argc, char **argv);
+#endif
+static int_t cup_func(int argc, char **argv);
+
+/*
+ *  デバイスコマンドテーブル
+ */
+static const COMMAND_INFO device_command_info[] = {
+	{"LED",		led_func},
+	{"DIP",		dip_func},
+#ifdef USE_PINGSEND
+	{"PING",    png_func},
+#endif
+	{"CUP",		cup_func}
+};
+
+#define NUM_DEVICE_CMD   (sizeof(device_command_info)/sizeof(COMMAND_INFO))
+
+static const char device_name[] = "DEVICE";
+static const char device_help[] =
+"  Device  LED (no) (on-1,off-0)  led   control\n"
+"          DIP (no) (on-1,off-0)  dipsw control\n"
+#ifdef USE_PINGSEND
+"          PING addr              send  ping   \n"
+#endif
+"          CUP command            cup   control\n";
+
+static const uint16_t led_pattern[4] = {
+	LED01, LED02, LED03, LED04
+};
+
+static COMMAND_LINK device_command_link = {
+	NULL,
+	NUM_DEVICE_CMD,
+	device_name,
+	NULL,
+	device_help,
+	&device_command_info[0]
+};
+
+static uint8_t cup_command;
+
+static int a2i(char *str)
+{
+	int num = 0;
+
+	while(*str >= '0' && *str <= '9'){
+		num = num * 10 + *str++ - '0';
+	}
+	return num;
+}
+
+/*
+ *  DEVICEコマンド設定関数
+ */
+void device_info_init(intptr_t exinf)
+{
+	setup_command(&device_command_link);
+}
+
+/*
+ *  LED設定コマンド関数
+ */
+static int_t led_func(int argc, char **argv)
+{
+	int_t    arg1=0, arg2;
+	uint16_t reg;
+
+	if(argc < 3)
+		return -1;
+	arg1 = a2i(argv[1]);
+	arg2 = a2i(argv[2]);
+	if(arg1 >= 1 && arg1 <= 4){
+		reg = led_in();
+		if(arg2 != 0)
+			reg |= led_pattern[arg1-1];
+		else
+			reg &= ~led_pattern[arg1-1];
+		led_out(reg);
+	}
+	return 0;
+}
+
+/*
+ *  DIPSW設定コマンド関数
+ */
+static int_t dip_func(int argc, char **argv)
+{
+	int_t   arg1=0, arg2=0, i;
+
+	if(argc > 1)
+		arg1 = a2i(argv[1]);
+	if(argc > 2)
+		arg2 = a2i(argv[2]);
+	if(arg1 >= 1 && arg1 <= 8){
+		if(arg2 != 0)
+			dipsw_value |= (0x1<<(arg1-1));
+		else
+			dipsw_value &= ~(0x1<<(arg1-1));
+	}
+	printf("dipsw\n1   2   3   4   5   6   7   8\n");
+	for(i = 0 ; i < 8 ; i++){
+		if(dipsw_value & (1<<i))
+			printf("ON  ");
+		else
+			printf("OFF ");
+	}
+	printf("\n");
+	return 0;
+}
+
+#ifdef USE_PINGSEND
+/*
+ *  PING送信マンド関数
+ */
+static int_t png_func(int argc, char **argv)
+{
+	const char *addr;
+	uint32_t paddr = 0;
+	int      a, i;
+
+	if(argc < 2)
+		return -1;
+	addr = argv[1];
+	for(i = a = 0 ; i < 4 ; addr++){
+		if(*addr <= '9' && *addr >= '0'){
+			a *= 10;
+			a += *addr - '0';
+		}
+		else{
+			paddr |= a << (i * 8);
+			a = 0;
+			i++;
+		}
+		if(*addr == 0)
+			break;
+	}
+	set_pingaddr(paddr);
+	return 0;
+}
+#endif
+
+/*
+ *  カップラーメンタイマ補助コマンド関数
+ */
+static int_t cup_func(int argc, char **argv)
+{
+	if(argc > 1)
+		cup_command = *argv[1];
+	return 0;
+}
+
+/*
+ * CUPラーメンコマンド
+ */
+int8_t
+get_cup_command(void)
+{
+	uint8_t cmd = cup_command;
+	cup_command = 0;
+	return cmd;
+}
+
+
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/OBJ/STM32F767NUCLEO144_GCC/MAC/lwip_test.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/OBJ/STM32F767NUCLEO144_GCC/MAC/lwip_test.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/OBJ/STM32F767NUCLEO144_GCC/MAC/lwip_test.c	(revision 457)
@@ -0,0 +1,738 @@
+/*
+ *  TOPPERS/ASP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Advanced Standard Profile Kernel
+ * 
+ *  Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
+ *                              Toyohashi Univ. of Technology, JAPAN
+ *  Copyright (C) 2004-2012 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ *  Copyright (C) 2015-2020 by TOPPERS PROJECT Educational Working Group.
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  $Id$
+ */
+
+/*
+ * Copyright (c) 2001-2003 Swedish Institute of Computer Science.
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission. 
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ * 
+ * Author: Adam Dunkels <adam@sics.se>
+ *
+ */
+
+/* 
+ *  LWIPテストプログラムの本体
+ */
+
+#include <kernel.h>
+#include <t_syslog.h>
+#include <t_stdlib.h>
+#include <sil.h>
+#include "syssvc/serial.h"
+#include "syssvc/syslog.h"
+#ifdef USE_STORAGEDEVICE
+#include "storagedevice.h"
+#endif	/* USE_STORAGEDEVICE */
+#include "device.h"
+#include "sdmmc.h"
+#include "kernel_cfg.h"
+#include "lwip_test.h"
+
+#include "lwip/opt.h"
+
+#include "lwip/init.h"
+
+#include "lwip/mem.h"
+#include "lwip/memp.h"
+#include "lwip/sys.h"
+#include "lwip/timeouts.h"
+
+#include "lwip/ip_addr.h"
+
+#include "lwip/dns.h"
+#include "lwip/dhcp.h"
+
+#include "lwip/stats.h"
+
+#include "lwip/tcp.h"
+#include "lwip/inet_chksum.h"
+
+#include "lwip/tcpip.h"
+#include "lwip/sockets.h"
+
+
+#if 0
+#include "netif/pcapif.h"
+#endif
+
+#ifndef LWIP_HAVE_SLIPIF
+#define LWIP_HAVE_SLIPIF 0
+#endif
+#if LWIP_HAVE_SLIPIF
+#include "netif/slipif.h"
+#define SLIP_PTY_TEST 1
+#endif
+
+#if PPP_SUPPORT
+#include "netif/ppp/pppos.h"
+#include "lwip/sio.h"
+#define PPP_PTY_TEST 1
+#include <termios.h>
+#endif
+
+#include "lwip/ip_addr.h"
+
+#include "lwip/apps/httpd.h"
+#include "apps/udpecho/udpecho.h"
+#include "apps/tcpecho/tcpecho.h"
+#include "apps/shell/shell.h"
+#include "apps/chargen/chargen.h"
+#include "apps/netio/netio.h"
+#include "apps/ping/ping.h"
+#include "lwip/apps/netbiosns.h"
+#include "lwip/apps/mdns.h"
+#include "lwip/apps/sntp.h"
+#include "lwip/apps/snmp.h"
+#include "lwip/apps/snmp_mib2.h"
+#include "examples/snmp/snmp_private_mib/private_mib.h"
+#include "lwip/apps/tftp_server.h"
+
+#if LWIP_RAW
+#include "lwip/icmp.h"
+#include "lwip/raw.h"
+#endif
+
+err_t ethernetif_init(struct netif *netif);
+
+/*
+ *  サービスコールのエラーのログ出力
+ */
+Inline void
+svc_perror(const char *file, int_t line, const char *expr, ER ercd)
+{
+	if (ercd < 0) {
+		t_perror(LOG_ERROR, file, line, expr, ercd);
+	}
+}
+
+#define	SVC_PERROR(expr)	svc_perror(__FILE__, __LINE__, #expr, (expr))
+
+static uint32_t heap_area[HEAP_SIZE/sizeof(uint32_t)];
+
+uint32_t heap_param[2] = {
+	(uint32_t)heap_area,
+	HEAP_SIZE
+};
+
+
+#ifdef _STORAGEDEVICE_H_
+static void storagedev_notice(void *psdev, bool_t sw)
+{
+	syslog_2(LOG_NOTICE, "SD-CARD[%08x] on/off(%d) !", psdev, sw);
+}
+
+static uint32_t get_fat_time(void)
+{
+	int    reqtime = 0;
+
+	reqtime = 0x00210000;
+	return reqtime;
+}
+#endif	/* _STORAGEDEVICE_H_ */
+
+#if 1	/* ROI DEBUG */
+void sw_int(void)
+{
+	syslog_0(LOG_NOTICE, "## sw_int() ##");
+}
+#endif	/* ROI DEBUG */
+
+uint32_t LWIP_RAND(void)
+{
+	return rand();
+}
+
+#if LWIP_SNMP
+static const struct snmp_mib *mibs[] = {
+	&mib2,
+	&mib_private
+};
+#endif /* LWIP_SNMP */
+
+#if LWIP_IPV4
+/* (manual) host IP configuration */
+static ip_addr_t ipaddr, netmask, gw;
+#endif /* LWIP_IPV4 */
+
+struct netif netif;
+
+/* ping out destination cmd option */
+static ip_addr_t ping_addr;
+
+static bool_t tcpip_init_flag = false;
+
+/* nonstatic debug cmd option, exported in lwipopts.h */
+unsigned char debug_flags;
+
+static void init_netifs(void);
+
+#if 0
+static void
+tcp_debug_timeout(void *data)
+{
+  LWIP_UNUSED_ARG(data);
+#if TCP_DEBUG
+  tcp_debug_print_pcbs();
+#endif /* TCP_DEBUG */
+  sys_timeout(5000, tcp_debug_timeout, NULL);
+}
+#endif
+
+/*
+ * gmtime_r関数
+ */
+struct tm *gmtime_r(const time_t *pt, struct tm *ptm);
+
+void
+sntp_set_system_time(u32_t sec)
+{
+	struct tm current_time_val;
+	time_t current_time = (time_t)sec;
+
+	gmtime_r(&current_time, &current_time_val);
+	printf("%04d/%02d/%02d %02d:%02d:%02d\n",
+		current_time_val.tm_year+1900, current_time_val.tm_mon, current_time_val.tm_mday,
+		current_time_val.tm_hour, current_time_val.tm_min, current_time_val.tm_sec);
+}
+
+#if LWIP_MDNS_RESPONDER
+static void
+srv_txt(struct mdns_service *service, void *txt_userdata)
+{
+	err_t res;
+	LWIP_UNUSED_ARG(txt_userdata);
+
+	res = mdns_resp_add_service_txtitem(service, "path=/", 6);
+	LWIP_ERROR("mdns add service txt failed\n", (res == ERR_OK), return);
+}
+#endif
+
+#if LWIP_UDP
+
+static void*
+tftp_open(const char* fname, const char* mode, u8_t is_write)
+{
+#ifdef _STORAGEDEVICE_H_
+	LWIP_UNUSED_ARG(mode);
+
+	if(is_write)
+		return (void*)fopen(fname, "wb");
+	else
+		return (void*)fopen(fname, "rb");
+#else	/* _STORAGEDEVICE_H_ */
+	return NULL;
+#endif	/* _STORAGEDEVICE_H_ */
+}
+
+static void 
+tftp_close(void* handle)
+{
+#ifdef _STORAGEDEVICE_H_
+	fclose((FILE*)handle);
+#endif	/* _STORAGEDEVICE_H_ */
+}
+
+static int
+tftp_read(void* handle, void* buf, int bytes)
+{
+#ifdef _STORAGEDEVICE_H_
+	int rlen = fread(buf, 1, bytes, (FILE*)handle);
+	if(rlen <= 0)
+		return -1;
+	else
+		return rlen;
+#else	/* _STORAGEDEVICE_H_ */
+	return -1;
+#endif	/* _STORAGEDEVICE_H_ */
+}
+
+static int
+tftp_write(void* handle, struct pbuf* p)
+{
+#ifdef _STORAGEDEVICE_H_
+	while(p != NULL){
+		if(fwrite(p->payload, 1, p->len, (FILE*)handle) != (size_t)p->len)
+			return -1;
+		p = p->next;
+	}
+	return 0;
+#else	/* _STORAGEDEVICE_H_ */
+	return -1;
+#endif	/* _STORAGEDEVICE_H_ */
+}
+
+static const struct tftp_context tftp = {
+	tftp_open,
+	tftp_close,
+	tftp_read,
+	tftp_write
+};
+
+#endif /* LWIP_UDP */
+
+static void
+tcpip_init_done(void *arg)
+{
+	sys_sem_t *sem;
+	sem = (sys_sem_t *)arg;
+
+	init_netifs();
+
+#if LWIP_IPV4
+	netbiosns_set_name("toppershost");
+	netbiosns_init();
+#endif /* LWIP_IPV4 */
+
+	sntp_setoperatingmode(SNTP_OPMODE_POLL);
+#if LWIP_DHCP
+	sntp_servermode_dhcp(1); /* get SNTP server via DHCP */
+#else /* LWIP_DHCP */
+#if LWIP_IPV4
+	sntp_setserver(0, netif_ip_gw4(&netif));
+#endif /* LWIP_IPV4 */
+#endif /* LWIP_DHCP */
+	sntp_init();
+
+#if LWIP_SNMP
+	lwip_privmib_init();
+#if SNMP_LWIP_MIB2
+#if SNMP_USE_NETCONN
+	snmp_threadsync_init(&snmp_mib2_lwip_locks, snmp_mib2_lwip_synchronizer);
+#endif /* SNMP_USE_NETCONN */
+	snmp_mib2_set_syscontact_readonly((const u8_t*)"root", NULL);
+	snmp_mib2_set_syslocation_readonly((const u8_t*)"lwIP development PC", NULL);
+	snmp_mib2_set_sysdescr((const u8_t*)"toppershost", NULL);
+#endif /* SNMP_LWIP_MIB2 */
+
+	snmp_set_mibs(mibs, LWIP_ARRAYSIZE(mibs));
+	snmp_init();
+#endif /* LWIP_SNMP */
+
+#if LWIP_MDNS_RESPONDER
+	mdns_resp_init();
+	mdns_resp_add_netif(&netif, "toppershost", 3600);
+	mdns_resp_add_service(&netif, "myweb", "_http", DNSSD_PROTO_TCP, 80, 3600, srv_txt, NULL);
+#endif
+
+#if LWIP_UDP
+	tftp_init(&tftp);
+#endif /* LWIP_UDP */
+
+	sys_sem_signal(sem);
+}
+
+/*-----------------------------------------------------------------------------------*/
+
+#if LWIP_HAVE_SLIPIF
+/* (manual) host IP configuration */
+#if LWIP_IPV4
+static ip_addr_t ipaddr_slip, netmask_slip, gw_slip;
+#endif /* LWIP_IPV4 */
+struct netif slipif;
+#endif /* LWIP_HAVE_SLIPIF */
+
+#if PPP_SUPPORT
+sio_fd_t ppp_sio;
+ppp_pcb *ppp;
+struct netif pppos_netif;
+
+static void
+pppos_rx_thread(void *arg)
+{
+	u32_t len;
+	u8_t buffer[128];
+	LWIP_UNUSED_ARG(arg);
+
+	/* Please read the "PPPoS input path" chapter in the PPP documentation. */
+	while(1){
+		len = sio_read(ppp_sio, buffer, sizeof(buffer));
+		if (len > 0) {
+			/* Pass received raw characters from PPPoS to be decoded through lwIP
+			 * TCPIP thread using the TCPIP API. This is thread safe in all cases
+			 * but you should avoid passing data byte after byte. */
+			pppos_input_tcpip(ppp, buffer, len);
+		}
+	}
+}
+
+static void
+ppp_link_status_cb(ppp_pcb *pcb, int err_code, void *ctx)
+{
+    struct netif *pppif = ppp_netif(pcb);
+    LWIP_UNUSED_ARG(ctx);
+
+    switch(err_code) {
+    case PPPERR_NONE:               /* No error. */
+        {
+#if LWIP_DNS
+        const ip_addr_t *ns;
+#endif /* LWIP_DNS */
+        fprintf(stderr, "ppp_link_status_cb: PPPERR_NONE\n\r");
+#if LWIP_IPV4
+        fprintf(stderr, "   our_ip4addr = %s\n\r", ip4addr_ntoa(netif_ip4_addr(pppif)));
+        fprintf(stderr, "   his_ipaddr  = %s\n\r", ip4addr_ntoa(netif_ip4_gw(pppif)));
+        fprintf(stderr, "   netmask     = %s\n\r", ip4addr_ntoa(netif_ip4_netmask(pppif)));
+#endif /* LWIP_IPV4 */
+#if LWIP_IPV6
+        fprintf(stderr, "   our_ip6addr = %s\n\r", ip6addr_ntoa(netif_ip6_addr(pppif, 0)));
+#endif /* LWIP_IPV6 */
+
+#if LWIP_DNS
+        ns = dns_getserver(0);
+        fprintf(stderr, "   dns1        = %s\n\r", ipaddr_ntoa(ns));
+        ns = dns_getserver(1);
+        fprintf(stderr, "   dns2        = %s\n\r", ipaddr_ntoa(ns));
+#endif /* LWIP_DNS */
+#if PPP_IPV6_SUPPORT
+        fprintf(stderr, "   our6_ipaddr = %s\n\r", ip6addr_ntoa(netif_ip6_addr(pppif, 0)));
+#endif /* PPP_IPV6_SUPPORT */
+        }
+        break;
+
+    case PPPERR_PARAM:             /* Invalid parameter. */
+        printf("ppp_link_status_cb: PPPERR_PARAM\n");
+        break;
+
+    case PPPERR_OPEN:              /* Unable to open PPP session. */
+        printf("ppp_link_status_cb: PPPERR_OPEN\n");
+        break;
+
+    case PPPERR_DEVICE:            /* Invalid I/O device for PPP. */
+        printf("ppp_link_status_cb: PPPERR_DEVICE\n");
+        break;
+
+    case PPPERR_ALLOC:             /* Unable to allocate resources. */
+        printf("ppp_link_status_cb: PPPERR_ALLOC\n");
+        break;
+
+    case PPPERR_USER:              /* User interrupt. */
+        printf("ppp_link_status_cb: PPPERR_USER\n");
+        break;
+
+    case PPPERR_CONNECT:           /* Connection lost. */
+        printf("ppp_link_status_cb: PPPERR_CONNECT\n");
+        break;
+
+    case PPPERR_AUTHFAIL:          /* Failed authentication challenge. */
+        printf("ppp_link_status_cb: PPPERR_AUTHFAIL\n");
+        break;
+
+    case PPPERR_PROTOCOL:          /* Failed to meet protocol. */
+        printf("ppp_link_status_cb: PPPERR_PROTOCOL\n");
+        break;
+
+    case PPPERR_PEERDEAD:          /* Connection timeout. */
+        printf("ppp_link_status_cb: PPPERR_PEERDEAD\n");
+        break;
+
+    case PPPERR_IDLETIMEOUT:       /* Idle Timeout. */
+        printf("ppp_link_status_cb: PPPERR_IDLETIMEOUT\n");
+        break;
+
+    case PPPERR_CONNECTTIME:       /* PPPERR_CONNECTTIME. */
+        printf("ppp_link_status_cb: PPPERR_CONNECTTIME\n");
+        break;
+
+    case PPPERR_LOOPBACK:          /* Connection timeout. */
+        printf("ppp_link_status_cb: PPPERR_LOOPBACK\n");
+        break;
+
+    default:
+        printf("ppp_link_status_cb: unknown errCode %d\n", err_code);
+        break;
+    }
+}
+
+static u32_t
+ppp_output_cb(ppp_pcb *pcb, u8_t *data, u32_t len, void *ctx)
+{
+  LWIP_UNUSED_ARG(pcb);
+  LWIP_UNUSED_ARG(ctx);
+  return sio_write(ppp_sio, data, len);
+}
+#endif
+
+#if LWIP_NETIF_STATUS_CALLBACK
+static void
+netif_status_callback(struct netif *nif)
+{
+	printf("NETIF: %c%c%d is %s\n", nif->name[0], nif->name[1], nif->num,
+		netif_is_up(nif) ? "UP" : "DOWN");
+#if LWIP_IPV4
+	printf("IPV4: Host at %s ", ip4addr_ntoa(netif_ip4_addr(nif)));
+	printf("mask %s ", ip4addr_ntoa(netif_ip4_netmask(nif)));
+	printf("gateway %s\n", ip4addr_ntoa(netif_ip4_gw(nif)));
+#endif /* LWIP_IPV4 */
+#if LWIP_IPV6
+	printf("IPV6: Host at %s\n", ip6addr_ntoa(netif_ip6_addr(nif, 0)));
+#endif /* LWIP_IPV6 */
+#if LWIP_NETIF_HOSTNAME
+	printf("FQDN: %s\n", netif_get_hostname(nif));
+#endif /* LWIP_NETIF_HOSTNAME */
+
+#if LWIP_MDNS_RESPONDER
+	if(tcpip_init_flag)
+		mdns_resp_netif_settings_changed(nif);
+#endif
+}
+#endif /* LWIP_NETIF_STATUS_CALLBACK */
+
+static void
+init_netifs(void)
+{
+#if LWIP_HAVE_SLIPIF
+#if SLIP_PTY_TEST
+	u8_t siodev_slip = 3;
+#else
+	u8_t siodev_slip = 0;
+#endif
+
+#if LWIP_IPV4
+	netif_add(&slipif, ip_2_ip4(&ipaddr_slip), ip_2_ip4(&netmask_slip), ip_2_ip4(&gw_slip),
+		(void*)&siodev_slip, slipif_init, tcpip_input);
+#else /* LWIP_IPV4 */
+	netif_add(&slipif, (void*)&siodev_slip, slipif_init, tcpip_input);
+#endif /* LWIP_IPV4 */
+#if LWIP_IPV6
+	netif_create_ip6_linklocal_address(&slipif, 1);
+#endif
+#if LWIP_NETIF_STATUS_CALLBACK
+	netif_set_status_callback(&slipif, netif_status_callback);
+#endif /* LWIP_NETIF_STATUS_CALLBACK */
+	netif_set_link_up(&slipif);
+	netif_set_up(&slipif);
+#endif /* LWIP_HAVE_SLIPIF */
+
+#if PPP_SUPPORT
+#if PPP_PTY_TEST
+	ppp_sio = sio_open(2);
+#else
+	ppp_sio = sio_open(0);
+#endif
+	if(!ppp_sio){
+		syslog_0(LOG_ERROR, "Error opening device: ");
+		slp_tsk();
+	}
+
+	ppp = pppos_create(&pppos_netif, ppp_output_cb, ppp_link_status_cb, NULL);
+	if(!ppp){
+		syslog_0(LOG_ERROR, "Could not create PPP control interface");
+		slp_tsk();
+	}
+
+#ifdef LWIP_PPP_CHAP_TEST
+	ppp_set_auth(ppp, PPPAUTHTYPE_CHAP, "lwip", "mysecret");
+#endif
+
+	ppp_connect(ppp, 0);
+
+#if LWIP_NETIF_STATUS_CALLBACK
+	netif_set_status_callback(&pppos_netif, netif_status_callback);
+#endif /* LWIP_NETIF_STATUS_CALLBACK */
+#endif /* PPP_SUPPORT */
+
+#if LWIP_IPV4
+#if LWIP_DHCP
+	IP_ADDR4(&gw,      0,0,0,0);
+	IP_ADDR4(&ipaddr,  0,0,0,0);
+	IP_ADDR4(&netmask, 0,0,0,0);
+#endif /* LWIP_DHCP */
+	netif_add(&netif, ip_2_ip4(&ipaddr), ip_2_ip4(&netmask), ip_2_ip4(&gw), NULL, ethernetif_init, tcpip_input);
+#else /* LWIP_IPV4 */
+	netif_add(&netif, NULL, ethernetif_init, tcpip_input);
+#endif /* LWIP_IPV4 */
+#if LWIP_IPV6
+	netif_create_ip6_linklocal_address(&netif, 1);
+	netif.ip6_autoconfig_enabled = 1;
+#endif
+#if LWIP_NETIF_STATUS_CALLBACK
+	netif_set_status_callback(&netif, netif_status_callback);
+#endif /* LWIP_NETIF_STATUS_CALLBACK */
+	netif_set_default(&netif);
+	netif_set_up(&netif);
+
+#if LWIP_DHCP
+	dhcp_start(&netif);
+#endif /* LWIP_DHCP */
+
+#if 0
+	/* Only used for testing purposes: */
+	netif_add(&ipaddr, &netmask, &gw, NULL, pcapif_init, tcpip_input);
+#endif
+
+#if LWIP_TCP
+	netio_init();
+#endif
+#if LWIP_TCP && LWIP_NETCONN
+	tcpecho_init();
+	shell_init();
+	httpd_init();
+#endif
+#if LWIP_UDP && LWIP_NETCONN
+	udpecho_init();
+#endif  
+#if LWIP_SOCKET
+	chargen_init();
+#endif
+	/*  sys_timeout(5000, tcp_debug_timeout, NULL);*/
+}
+
+/*-----------------------------------------------------------------------------------*/
+static void
+main_thread(void *arg)
+{
+	sys_sem_t sem;
+	LWIP_UNUSED_ARG(arg);
+
+	if(sys_sem_new(&sem, 0) != ERR_OK) {
+		LWIP_ASSERT("Failed to create semaphore", 0);
+	}
+	tcpip_init(tcpip_init_done, &sem);
+	sys_sem_wait(&sem);
+	syslog_0(LOG_NOTICE, "TCP/IP initialized.");
+
+#if LWIP_SOCKET && defined(USE_PINGSEND)
+	ping_init(&ping_addr);
+#endif
+
+	syslog_0(LOG_NOTICE, "Applications started.");
+
+#ifdef MEM_PERF
+	mem_perf_init("/tmp/memstats.client");
+#endif /* MEM_PERF */
+#if 0
+	stats_display();
+#endif
+#if PPP_SUPPORT
+	/* Block forever. */
+	sys_thread_new("pppos_rx_thread", pppos_rx_thread, NULL, DEFAULT_THREAD_STACKSIZE, DEFAULT_THREAD_PRIO);
+	sys_sem_wait(&sem);
+#endif
+	tcpip_init_flag = true;
+}
+
+/*
+ *  メインタスク
+ */
+void
+main_task(intptr_t exinf)
+{
+#ifdef _STORAGEDEVICE_H_
+	StorageDevice_t *psdev;
+#endif	/* _STORAGEDEVICE_H_ */
+	ER_UINT	ercd;
+
+	SVC_PERROR(syslog_msk_log(LOG_UPTO(LOG_NOTICE), LOG_UPTO(LOG_EMERG)));
+	syslog(LOG_NOTICE, "Sample program starts (exinf = %d).", (int_t) exinf);
+
+	/*
+	 *  シリアルポートの初期化
+	 *
+	 *  システムログタスクと同じシリアルポートを使う場合など，シリアル
+	 *  ポートがオープン済みの場合にはここでE_OBJエラーになるが，支障は
+	 *  ない．
+	 */
+	ercd = serial_opn_por(TASK_PORTID);
+	if (ercd < 0 && MERCD(ercd) != E_OBJ) {
+		syslog(LOG_ERROR, "%s (%d) reported by `serial_opn_por'.",
+									itron_strerror(ercd), SERCD(ercd));
+	}
+	SVC_PERROR(serial_ctl_por(TASK_PORTID,
+							(IOCTL_CRLF | IOCTL_FCSND | IOCTL_FCRCV)));
+
+#ifdef _STORAGEDEVICE_H_
+	/*
+	 *  SD-CARDの設定
+	 */
+	psdev = SDMGetStorageDevice(0);
+	psdev->_sdev_notice = storagedev_notice;
+	SDeviceHead._get_datetime = get_fat_time;
+#endif	/* _STORAGEDEVICE_H_ */
+
+	/* startup defaults (may be overridden by one or more opts) */
+#if LWIP_IPV4
+	IP_ADDR4(&gw,      192,168,  0,1);
+	IP_ADDR4(&netmask, 255,255,255,0);
+	IP_ADDR4(&ipaddr,  192,168,  0,2);
+#if LWIP_HAVE_SLIPIF
+	IP_ADDR4(&gw_slip,      192,168,  2,  1);
+	IP_ADDR4(&netmask_slip, 255,255,255,255);
+	IP_ADDR4(&ipaddr_slip,  192,168,  2,  2);
+#endif
+#endif /* LWIP_IPV4 */
+
+	IP_SET_TYPE_VAL(ping_addr, IPADDR_TYPE_V4);
+	/* use debug flags defined by debug.h */
+	debug_flags = LWIP_DBG_OFF;
+
+	sys_init();
+	sys_thread_new("main_thread", main_thread, NULL, DEFAULT_THREAD_STACKSIZE, DEFAULT_THREAD_PRIO);
+
+	syslog(LOG_NOTICE, "Sample program ends.");
+	slp_tsk();
+	SVC_PERROR(ext_ker());
+	assert(0);
+}
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/OBJ/STM32F767NUCLEO144_GCC/MAC/lwip_test.cfg
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/OBJ/STM32F767NUCLEO144_GCC/MAC/lwip_test.cfg	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/OBJ/STM32F767NUCLEO144_GCC/MAC/lwip_test.cfg	(revision 457)
@@ -0,0 +1,37 @@
+/*
+ *  @(#) $Id$
+ */
+
+/*
+ *  LWIPテストプログラムのシステムコンフィギュレーションファイル
+ */
+INCLUDE("target_timer.cfg");
+INCLUDE("syssvc/syslog.cfg");
+INCLUDE("syssvc/banner.cfg");
+INCLUDE("syssvc/serial.cfg");
+INCLUDE("syssvc/logtask.cfg");
+INCLUDE("pdic/stm32f7xx/device.cfg");
+/* INCLUDE("pdic/stm32f7xx/sdmmc.cfg");
+ INCLUDE("files/storagedevice.cfg");
+INCLUDE("files/ff/fatfs.cfg"); */
+INCLUDE("monitor/monitor.cfg");
+INCLUDE("syssvc/tlsf.cfg");
+INCLUDE("lwip/lwip.cfg");
+
+#include "itron.h"
+#include "device.h"
+/* #include "sdmmc.h" */
+#include "emac.h"
+#include "lwip_test.h"
+
+ATT_INI({ TA_NULL, heap_param, heap_init });
+ATT_INI({ TA_NULL, sw_int, setup_sw_func });
+ATT_INI({ TA_NULL, 0, device_info_init });
+
+CRE_TSK(MAIN_TASK1, { TA_ACT, 1, main_task, MAIN_PRIORITY, STACK_SIZE, NULL });
+CRE_FLG(FLG_GMAC, {(TA_TFIFO|TA_WSGL), 0});
+CRE_SEM(SEM_GMAC_MDIO, { TA_TPRI, 1, 1 });
+
+ATT_ISR({ TA_NULL,  EMAC_PORTID, INTNO_EMAC, emac_hps_isr, 1 });
+CFG_INT(INTNO_EMAC, { TA_NULL | INTATR_EMAC, INTPRI_EMAC });
+
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/OBJ/STM32F767NUCLEO144_GCC/MAC/lwip_test.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/OBJ/STM32F767NUCLEO144_GCC/MAC/lwip_test.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/OBJ/STM32F767NUCLEO144_GCC/MAC/lwip_test.h	(revision 457)
@@ -0,0 +1,104 @@
+/*
+ *  TOPPERS/ASP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Advanced Standard Profile Kernel
+ *
+ *  Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
+ *                              Toyohashi Univ. of Technology, JAPAN
+ *  Copyright (C) 2004-2010 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ *  Copyright (C) 2016-2020 by TOPPERS PROJECT Educational Working Group.
+ *
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ *
+ *  $Id$
+ */
+
+/*
+ *	LWIP-MACテストプログラムのヘッダファイル
+ */
+
+/*
+ *  ターゲット依存の定義
+ */
+#include "target_test.h"
+
+/*
+ *  各タスクの優先度の定義
+ */
+
+#define MAIN_PRIORITY	5		/* メインタスクの優先度 */
+
+/*
+ *  ターゲットに依存する可能性のある定数の定義
+ */
+
+#ifndef TASK_PORTID
+#define	TASK_PORTID		1			/* 文字入力するシリアルポートID */
+#endif /* TASK_PORTID */
+
+#ifndef STACK_SIZE
+#define	STACK_SIZE		2048		/* タスクのスタックサイズ */
+#endif /* STACK_SIZE */
+
+#ifndef LOOP_REF
+#define LOOP_REF		ULONG_C(1000000)	/* 速度計測用のループ回数 */
+#endif /* LOOP_REF */
+
+#define INHNO_EMAC    IRQ_VECTOR_ETH	/* 割込みハンドラ番号 */
+#define INTNO_EMAC    IRQ_VECTOR_ETH	/* 割込み番号 */
+#define INTPRI_EMAC   -5			/* 割込み優先度 */
+#define INTATR_EMAC   0				/* 割込み属性 */
+#define EMAC_PORTID   MAC1_PORTID
+
+#define HEAP_SIZE       (32*1024)
+
+#ifndef TOPPERS_MACRO_ONLY
+
+/*
+ *  ヒープ領域の設定
+ */
+extern uint32_t heap_param[2];
+
+/*
+ *  関数のプロトタイプ宣言
+ */
+extern void	main_task(intptr_t exinf);
+
+#ifdef CPUEXC1
+extern void	cpuexc_handler(void *p_excinf);
+#endif /* CPUEXC1 */
+
+extern void sw_int(void);
+extern void heap_init(intptr_t exinf);
+extern void device_info_init(intptr_t exinf);
+extern int8_t get_cup_command(void);
+
+#endif /* TOPPERS_MACRO_ONLY */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/OBJ/STM32F767NUCLEO144_GCC/MAC/lwipopts.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/OBJ/STM32F767NUCLEO144_GCC/MAC/lwipopts.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/OBJ/STM32F767NUCLEO144_GCC/MAC/lwipopts.h	(revision 457)
@@ -0,0 +1,575 @@
+/**
+ * @file
+ *
+ * lwIP Options Configuration
+ */
+
+/*
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Adam Dunkels <adam@sics.se>
+ *
+ */
+#ifndef LWIP_LWIPOPTS_H
+#define LWIP_LWIPOPTS_H
+
+/*
+ * Include user defined options first. Anything not defined in these files
+ * will be set to standard values. Override anything you dont like!
+ */
+#include "lwip/arch.h"
+#include "lwip/debug.h"
+
+/*
+   -----------------------------------------------
+   ---------- Platform specific locking ----------
+   -----------------------------------------------
+*/
+
+/**
+ * SYS_LIGHTWEIGHT_PROT==1: if you want inter-task protection for certain
+ * critical regions during buffer allocation, deallocation and memory
+ * allocation and deallocation.
+ */
+#define SYS_LIGHTWEIGHT_PROT            1
+
+/**
+ * NO_SYS==1: Provides VERY minimal functionality. Otherwise,
+ * use lwIP facilities.
+ */
+#define NO_SYS                          0
+
+#define LWIP_IPV4                       (NO_SYS==0)
+#define LWIP_IPV6                       (NO_SYS==0)
+/*
+   ------------------------------------
+   ---------- Memory options ----------
+   ------------------------------------
+*/
+
+/**
+ * MEM_ALIGNMENT: should be set to the alignment of the CPU
+ *    4 byte alignment -> #define MEM_ALIGNMENT 4
+ *    2 byte alignment -> #define MEM_ALIGNMENT 2
+ */
+#define MEM_ALIGNMENT                   4U
+
+/**
+ * MEM_SIZE: the size of the heap memory. If the application will send
+ * a lot of data that needs to be copied, this should be set high.
+ */
+#define MEM_SIZE                        10240
+
+/*
+   ------------------------------------------------
+   ---------- Internal Memory Pool Sizes ----------
+   ------------------------------------------------
+*/
+/**
+ * MEMP_NUM_PBUF: the number of memp struct pbufs (used for PBUF_ROM and PBUF_REF).
+ * If the application sends a lot of data out of ROM (or other static memory),
+ * this should be set high.
+ */
+#define MEMP_NUM_PBUF                   16
+
+/**
+ * MEMP_NUM_RAW_PCB: Number of raw connection PCBs
+ * (requires the LWIP_RAW option)
+ */
+#define MEMP_NUM_RAW_PCB                3
+
+/**
+ * MEMP_NUM_UDP_PCB: the number of UDP protocol control blocks. One
+ * per active UDP "connection".
+ * (requires the LWIP_UDP option)
+ */
+#define MEMP_NUM_UDP_PCB                8
+
+/**
+ * MEMP_NUM_TCP_PCB: the number of simulatenously active TCP connections.
+ * (requires the LWIP_TCP option)
+ */
+#define MEMP_NUM_TCP_PCB                5
+
+/**
+ * MEMP_NUM_TCP_PCB_LISTEN: the number of listening TCP connections.
+ * (requires the LWIP_TCP option)
+ */
+#define MEMP_NUM_TCP_PCB_LISTEN         8
+
+/**
+ * MEMP_NUM_TCP_SEG: the number of simultaneously queued TCP segments.
+ * (requires the LWIP_TCP option)
+ */
+#define MEMP_NUM_TCP_SEG                16
+
+/**
+ * MEMP_NUM_REASSDATA: the number of simultaneously IP packets queued for
+ * reassembly (whole packets, not fragments!)
+ */
+#define MEMP_NUM_REASSDATA              10
+
+/**
+ * MEMP_NUM_ARP_QUEUE: the number of simulateously queued outgoing
+ * packets (pbufs) that are waiting for an ARP request (to resolve
+ * their destination address) to finish.
+ * (requires the ARP_QUEUEING option)
+ */
+#define MEMP_NUM_ARP_QUEUE              2
+
+/**
+ * MEMP_NUM_SYS_TIMEOUT: the number of simulateously active timeouts.
+ * (requires NO_SYS==0)
+ */
+#define MEMP_NUM_SYS_TIMEOUT            12
+
+/**
+ * MEMP_NUM_NETBUF: the number of struct netbufs.
+ * (only needed if you use the sequential API, like api_lib.c)
+ */
+#define MEMP_NUM_NETBUF                 2
+
+/**
+ * MEMP_NUM_NETCONN: the number of struct netconns.
+ * (only needed if you use the sequential API, like api_lib.c)
+ */
+#define MEMP_NUM_NETCONN                32
+
+/**
+ * MEMP_NUM_TCPIP_MSG_API: the number of struct tcpip_msg, which are used
+ * for callback/timeout API communication.
+ * (only needed if you use tcpip.c)
+ */
+#define MEMP_NUM_TCPIP_MSG_API          16
+
+/**
+ * MEMP_NUM_TCPIP_MSG_INPKT: the number of struct tcpip_msg, which are used
+ * for incoming packets.
+ * (only needed if you use tcpip.c)
+ */
+#define MEMP_NUM_TCPIP_MSG_INPKT        16
+
+/**
+ * PBUF_POOL_SIZE: the number of buffers in the pbuf pool.
+ */
+#define PBUF_POOL_SIZE                  50
+
+/*
+   ---------------------------------
+   ---------- ARP options ----------
+   ---------------------------------
+*/
+/**
+ * LWIP_ARP==1: Enable ARP functionality.
+ */
+#define LWIP_ARP                        1
+
+/*
+   --------------------------------
+   ---------- IP options ----------
+   --------------------------------
+*/
+/**
+ * IP_FORWARD==1: Enables the ability to forward IP packets across network
+ * interfaces. If you are going to run lwIP on a device with only one network
+ * interface, define this to 0.
+ */
+#define IP_FORWARD                      1
+
+/**
+ * IP_OPTIONS: Defines the behavior for IP options.
+ *      IP_OPTIONS_ALLOWED==0: All packets with IP options are dropped.
+ *      IP_OPTIONS_ALLOWED==1: IP options are allowed (but not parsed).
+ */
+#define IP_OPTIONS_ALLOWED              1
+
+/**
+ * IP_REASSEMBLY==1: Reassemble incoming fragmented IP packets. Note that
+ * this option does not affect outgoing packet sizes, which can be controlled
+ * via IP_FRAG.
+ */
+#define IP_REASSEMBLY                   1
+
+/**
+ * IP_FRAG==1: Fragment outgoing IP packets if their size exceeds MTU. Note
+ * that this option does not affect incoming packet sizes, which can be
+ * controlled via IP_REASSEMBLY.
+ */
+#define IP_FRAG                         1
+
+/**
+ * IP_REASS_MAXAGE: Maximum time (in multiples of IP_TMR_INTERVAL - so seconds, normally)
+ * a fragmented IP packet waits for all fragments to arrive. If not all fragments arrived
+ * in this time, the whole packet is discarded.
+ */
+#define IP_REASS_MAXAGE                 3
+
+/**
+ * IP_REASS_MAX_PBUFS: Total maximum amount of pbufs waiting to be reassembled.
+ * Since the received pbufs are enqueued, be sure to configure
+ * PBUF_POOL_SIZE > IP_REASS_MAX_PBUFS so that the stack is still able to receive
+ * packets even if the maximum amount of fragments is enqueued for reassembly!
+ */
+#define IP_REASS_MAX_PBUFS              10
+
+/**
+ * IP_FRAG_USES_STATIC_BUF==1: Use a static MTU-sized buffer for IP
+ * fragmentation. Otherwise pbufs are allocated and reference the original
+    * packet data to be fragmented.
+*/
+#define IP_FRAG_USES_STATIC_BUF         0
+
+/**
+ * IP_DEFAULT_TTL: Default value for Time-To-Live used by transport layers.
+ */
+#define IP_DEFAULT_TTL                  255
+
+/*
+   ----------------------------------
+   ---------- ICMP options ----------
+   ----------------------------------
+*/
+/**
+ * LWIP_ICMP==1: Enable ICMP module inside the IP stack.
+ * Be careful, disable that make your product non-compliant to RFC1122
+ */
+#define LWIP_ICMP                       1
+
+/*
+   ---------------------------------
+   ---------- RAW options ----------
+   ---------------------------------
+*/
+/**
+ * LWIP_RAW==1: Enable application layer to hook into the IP layer itself.
+ */
+#define LWIP_RAW                        1
+
+/*
+   ----------------------------------
+   ---------- DHCP options ----------
+   ----------------------------------
+*/
+/**
+ * LWIP_DHCP==1: Enable DHCP module.
+ */
+#define LWIP_DHCP                       1
+
+
+/*
+   ------------------------------------
+   ---------- AUTOIP options ----------
+   ------------------------------------
+*/
+/**
+ * LWIP_AUTOIP==1: Enable AUTOIP module.
+ */
+#define LWIP_AUTOIP                     (LWIP_DHCP)
+
+/*
+   ----------------------------------
+   ---------- SNMP options ----------
+   ----------------------------------
+*/
+/**
+ * LWIP_SNMP==1: Turn on SNMP module. UDP must be available for SNMP
+ * transport.
+ */
+#define LWIP_SNMP                       1
+
+/*
+   ----------------------------------
+   ---------- IGMP options ----------
+   ----------------------------------
+*/
+/**
+ * LWIP_IGMP==1: Turn on IGMP module.
+ */
+#define LWIP_IGMP                       (LWIP_IPV4)
+
+/*
+   ----------------------------------
+   ---------- DNS options -----------
+   ----------------------------------
+*/
+/**
+ * LWIP_DNS==1: Turn on DNS module. UDP must be available for DNS
+ * transport.
+ */
+#define LWIP_DNS                        1
+
+/*
+   ---------------------------------
+   ---------- UDP options ----------
+   ---------------------------------
+*/
+/**
+ * LWIP_UDP==1: Turn on UDP.
+ */
+#define LWIP_UDP                        1
+
+/*
+   ---------------------------------
+   ---------- TCP options ----------
+   ---------------------------------
+*/
+/**
+ * LWIP_TCP==1: Turn on TCP.
+ */
+#define LWIP_TCP                        1
+
+#define LWIP_LISTEN_BACKLOG             0
+
+/*
+   ----------------------------------
+   ---------- Pbuf options ----------
+   ----------------------------------
+*/
+/**
+ * PBUF_LINK_HLEN: the number of bytes that should be allocated for a
+ * link level header. The default is 14, the standard value for
+ * Ethernet.
+ */
+#define PBUF_LINK_HLEN                  16
+
+/**
+ * PBUF_POOL_BUFSIZE: the size of each pbuf in the pbuf pool. The default is
+ * designed to accomodate single full size TCP frame in one pbuf, including
+ * TCP_MSS, IP header, and link header.
+*
+ */
+#define PBUF_POOL_BUFSIZE               LWIP_MEM_ALIGN_SIZE(TCP_MSS+40+PBUF_LINK_HLEN)
+
+/*
+   ------------------------------------
+   ---------- LOOPIF options ----------
+   ------------------------------------
+*/
+/**
+ * LWIP_HAVE_LOOPIF==1: Support loop interface (127.0.0.1) and loopif.c
+ */
+#define LWIP_HAVE_LOOPIF                0
+
+/*
+   ----------------------------------------------
+   ---------- Sequential layer options ----------
+   ----------------------------------------------
+*/
+
+/**
+ * LWIP_NETCONN==1: Enable Netconn API (require to use api_lib.c)
+ */
+#define LWIP_NETCONN                    1
+
+/*
+   ------------------------------------
+   ---------- Socket options ----------
+   ------------------------------------
+*/
+/**
+ * LWIP_SOCKET==1: Enable Socket API (require to use sockets.c)
+ */
+#define LWIP_SOCKET                     1
+
+/**
+ * SO_REUSE==1: Enable SO_REUSEADDR
+ */
+#define SO_REUSE                        1
+
+/*
+   ----------------------------------------
+   ---------- Statistics options ----------
+   ----------------------------------------
+*/
+/**
+ * LWIP_STATS==1: Enable statistics collection in lwip_stats.
+ */
+#define LWIP_STATS                      1
+/*
+   ---------------------------------
+   ---------- PPP options ----------
+   ---------------------------------
+*/
+/**
+ * PPP_SUPPORT==1: Enable PPP.
+ */
+#define PPP_SUPPORT                     0
+
+
+#define LWIP_DBG_MIN_LEVEL              0
+#define LWIP_COMPAT_SOCKETS             1
+
+#define PPP_DEBUG                       LWIP_DBG_OFF
+#define MEM_DEBUG                       LWIP_DBG_OFF
+#define API_MSG_DEBUG                   LWIP_DBG_ON
+#define TCPIP_DEBUG                     LWIP_DBG_ON
+#define NETIF_DEBUG                     LWIP_DBG_ON
+#define SOCKETS_DEBUG                   LWIP_DBG_ON
+#define IP_DEBUG                        LWIP_DBG_ON
+#define IP_REASS_DEBUG                  LWIP_DBG_ON
+#define RAW_DEBUG                       LWIP_DBG_ON
+#define ICMP_DEBUG                      LWIP_DBG_ON
+#define UDP_DEBUG                       LWIP_DBG_ON
+#define TCP_DEBUG                       LWIP_DBG_ON
+#define TCP_INPUT_DEBUG                 LWIP_DBG_ON
+#define TCP_OUTPUT_DEBUG                LWIP_DBG_ON
+#define TCP_RTO_DEBUG                   LWIP_DBG_ON
+#define TCP_CWND_DEBUG                  LWIP_DBG_ON
+#define TCP_WND_DEBUG                   LWIP_DBG_ON
+#define TCP_FR_DEBUG                    LWIP_DBG_ON
+#define TCP_QLEN_DEBUG                  LWIP_DBG_ON
+#define TCP_RST_DEBUG                   LWIP_DBG_ON
+
+extern unsigned char debug_flags;
+#define LWIP_DBG_TYPES_ON               debug_flags
+
+#define IP_SOF_BROADCAST_RECV           1
+#define IP_SOF_BROADCAST                1
+#define SO_REUSE_RXTOALL                1
+#define LWIP_SO_RCVTIMEO                (LWIP_SOCKET)
+
+#define MEMP_OVERFLOW_CHECK             1
+
+#define LWIP_TCPIP_TIMEOUT              1
+
+/* ---------- TCP options ---------- */
+
+#define TCP_LISTEN_BACKLOG              1
+
+/* Controls if TCP should queue segments that arrive out of
+   order. Define to 0 if your device is low on memory. */
+#define TCP_QUEUE_OOSEQ                 1
+
+/* TCP Maximum segment size. */
+#define TCP_MSS                         1024
+
+/* TCP sender buffer space (bytes). */
+#define TCP_SND_BUF                     (2 * TCP_MSS)
+
+/* TCP sender buffer space (pbufs). This must be at least = 2 *
+   TCP_SND_BUF/TCP_MSS for things to work. */
+#define TCP_SND_QUEUELEN                (4 * TCP_SND_BUF/TCP_MSS)
+
+/* TCP writable space (bytes). This must be less than or equal
+   to TCP_SND_BUF. It is the amount of space which must be
+   available in the tcp snd_buf for select to return writable */
+#define TCP_SNDLOWAT		            (TCP_SND_BUF/2)
+
+/* TCP receive window. */
+#define TCP_WND                         (4 * TCP_MSS)
+
+/* Maximum number of retransmissions of data segments. */
+#define TCP_MAXRTX                      12
+
+/* Maximum number of retransmissions of SYN segments. */
+#define TCP_SYNMAXRTX                   4
+
+/* ---------- ARP options ---------- */
+#define ARP_TABLE_SIZE                  10
+#define ARP_QUEUEING                    1
+
+
+
+/* IP reassembly and segmentation.These are orthogonal even
+ * if they both deal with IP fragments */
+#define IPV6_FRAG_COPYHEADER            1
+#define LWIP_IPV6_FRAG                  1
+
+
+/* ---------- ICMP options ---------- */
+#define ICMP_TTL                        (IP_DEFAULT_TTL)
+
+/* ---------- DHCP options ---------- */
+/* Define LWIP_DHCP to 1 if you want DHCP configuration of
+   interfaces. */
+
+#define LWIP_DHCP_GET_NTP_SRV           (LWIP_DHCP)
+
+/* 1 if you want to do an ARP check on the offered address
+   (recommended if using DHCP). */
+#define DHCP_DOES_ARP_CHECK             (LWIP_DHCP)
+
+/* ---------- AUTOIP options ------- */
+#define LWIP_DHCP_AUTOIP_COOP           (LWIP_DHCP)
+#define LWIP_DHCP_AUTOIP_COOP_TRIES     3
+
+/* ---------- SNTP options --------- */
+extern void sntp_set_system_time(u32_t sec);
+#define SNTP_SET_SYSTEM_TIME(s)         sntp_set_system_time(s)
+
+/* ---------- SNMP options ---------- */
+#define MIB2_STATS                      LWIP_SNMP
+#define SNMP_USE_NETCONN                LWIP_NETCONN
+#define SNMP_USE_RAW                    (!LWIP_NETCONN)
+
+
+/* ---------- MDNS options ---------- */
+#define LWIP_MDNS_RESPONDER             1
+#define LWIP_NUM_NETIF_CLIENT_DATA      (LWIP_MDNS_RESPONDER)
+
+/* ---------- UDP options ---------- */
+#define UDP_TTL                         (IP_DEFAULT_TTL)
+
+/* ---------- RAW options ---------- */
+#define RAW_TTL                         (IP_DEFAULT_TTL)
+
+
+#define LWIP_NETIF_API                  1
+#define LWIP_NETIF_STATUS_CALLBACK      1
+#define LWIP_NETIF_HOSTNAME             0
+
+/* ---------- SLIP options ---------- */
+
+#define LWIP_HAVE_SLIPIF                1      /* Set > 0 for SLIP */
+
+/* Maximum packet size that is received by this netif */
+#define SLIP_MAX_SIZE                   1500
+#define sio_tryread                     sio_read
+
+#define LWIP_HTTPD_SSI                  1
+
+
+/*
+ *  TOPPERS Additional DEFINE
+ */
+#define ETH_PAD_SIZE                    2
+#define SHELL_ECHO                      1
+#define TFTP_MAX_MODE_LEN               9
+
+#define IN_ADDR_T_DEFINED
+
+extern void sys_memcpy(volatile void *d, const volatile void *s, int len);
+#define MEMCPY(dst,src,len)             sys_memcpy(dst,src,len)
+
+extern void sys_memcpy(volatile void *d, const volatile void *s, int len);
+#define SMEMCPY(dst,src,len)            sys_memcpy(dst,src,len)
+
+extern void sys_memset(volatile void *d, unsigned char val, int len);
+#define MEMSET(a, b, c)  sys_memset(a, b, c)
+
+#endif /* LWIP_LWIPOPTS_H */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/OBJ/STM32F767NUCLEO144_GCC/MON/Makefile
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/OBJ/STM32F767NUCLEO144_GCC/MON/Makefile	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/OBJ/STM32F767NUCLEO144_GCC/MON/Makefile	(revision 457)
@@ -0,0 +1,593 @@
+#
+#  TOPPERS/ASP Kernel
+#      Toyohashi Open Platform for Embedded Real-Time Systems/
+#      Advanced Standard Profile Kernel
+# 
+#  Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
+#                              Toyohashi Univ. of Technology, JAPAN
+#  Copyright (C) 2006-2014 by Embedded and Real-Time Systems Laboratory
+#              Graduate School of Information Science, Nagoya Univ., JAPAN
+# 
+#  ä¸è¨èä½æ¨©è
+ã¯ï¼ä»¥ä¸ã®(1)ï½(4)ã®æ¡ä»¶ãæºããå ´åã«éãï¼æ¬ã½ããã¦ã§
+#  ã¢ï¼æ¬ã½ããã¦ã§ã¢ãæ¹å¤ãããã®ãå«ãï¼ä»¥ä¸åãï¼ãä½¿ç¨ã»è¤è£½ã»æ¹
+#  å¤ã»åé
+å¸ï¼ä»¥ä¸ï¼å©ç¨ã¨å¼ã¶ï¼ãããã¨ãç¡åã§è¨±è«¾ããï¼
+#  (1) æ¬ã½ããã¦ã§ã¢ãã½ã¼ã¹ã³ã¼ãã®å½¢ã§å©ç¨ããå ´åã«ã¯ï¼ä¸è¨ã®èä½
+#      æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨ã®ç¡ä¿è¨¼è¦å®ãï¼ãã®ã¾ã¾ã®å½¢ã§ã½ã¼
+#      ã¹ã³ã¼ãä¸­ã«å«ã¾ãã¦ãããã¨ï¼
+#  (2) æ¬ã½ããã¦ã§ã¢ãï¼ã©ã¤ãã©ãªå½¢å¼ãªã©ï¼ä»ã®ã½ããã¦ã§ã¢éçºã«ä½¿
+#      ç¨ã§ããå½¢ã§åé
+å¸ããå ´åã«ã¯ï¼åé
+å¸ã«ä¼´ããã­ã¥ã¡ã³ãï¼å©ç¨
+#      è
+ããã¥ã¢ã«ãªã©ï¼ã«ï¼ä¸è¨ã®èä½æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨
+#      ã®ç¡ä¿è¨¼è¦å®ãæ²è¼ãããã¨ï¼
+#  (3) æ¬ã½ããã¦ã§ã¢ãï¼æ©å¨ã«çµã¿è¾¼ããªã©ï¼ä»ã®ã½ããã¦ã§ã¢éçºã«ä½¿
+#      ç¨ã§ããªãå½¢ã§åé
+å¸ããå ´åã«ã¯ï¼æ¬¡ã®ããããã®æ¡ä»¶ãæºããã
+#      ã¨ï¼
+#    (a) åé
+å¸ã«ä¼´ããã­ã¥ã¡ã³ãï¼å©ç¨è
+ããã¥ã¢ã«ãªã©ï¼ã«ï¼ä¸è¨ã®è
+#        ä½æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨ã®ç¡ä¿è¨¼è¦å®ãæ²è¼ãããã¨ï¼
+#    (b) åé
+å¸ã®å½¢æ
+ãï¼å¥ã«å®ããæ¹æ³ã«ãã£ã¦ï¼TOPPERSãã­ã¸ã§ã¯ãã«
+#        å ±åãããã¨ï¼
+#  (4) æ¬ã½ããã¦ã§ã¢ã®å©ç¨ã«ããç´æ¥çã¾ãã¯éæ¥çã«çãããããªãæ
+#      å®³ãããï¼ä¸è¨èä½æ¨©è
+ããã³TOPPERSãã­ã¸ã§ã¯ããå
+è²¬ãããã¨ï¼
+#      ã¾ãï¼æ¬ã½ããã¦ã§ã¢ã®ã¦ã¼ã¶ã¾ãã¯ã¨ã³ãã¦ã¼ã¶ããã®ãããªãç
+#      ç±ã«åºã¥ãè«æ±ãããï¼ä¸è¨èä½æ¨©è
+ããã³TOPPERSãã­ã¸ã§ã¯ãã
+#      å
+è²¬ãããã¨ï¼
+# 
+#  æ¬ã½ããã¦ã§ã¢ã¯ï¼ç¡ä¿è¨¼ã§æä¾ããã¦ãããã®ã§ããï¼ä¸è¨èä½æ¨©è
+ã
+#  ãã³TOPPERSãã­ã¸ã§ã¯ãã¯ï¼æ¬ã½ããã¦ã§ã¢ã«é¢ãã¦ï¼ç¹å®ã®ä½¿ç¨ç®ç
+#  ã«å¯¾ããé©åæ§ãå«ãã¦ï¼ãããªãä¿è¨¼ãè¡ããªãï¼ã¾ãï¼æ¬ã½ããã¦ã§
+#  ã¢ã®å©ç¨ã«ããç´æ¥çã¾ãã¯éæ¥çã«çãããããªãæå®³ã«é¢ãã¦ãï¼ã
+#  ã®è²¬ä»»ãè² ããªãï¼
+# 
+#  $Id$
+# 
+
+#
+#  ã¿ã¼ã²ããã®æå®ï¼Makefile.targetã§ä¸æ¸ããããã®ãé²ãããï¼
+#
+all:
+
+#
+#  ã¿ã¼ã²ããç¥ç§°ã®å®ç¾©
+#
+TARGET = stm32f767nucleo144_gcc
+
+#
+#  ãã­ã°ã©ãã³ã°è¨èªã®å®ç¾©
+#
+SRCLANG = c
+ifeq ($(SRCLANG),c)
+  LIBS = -lc
+endif
+ifeq ($(SRCLANG),c++)
+  USE_CXX = true
+  CXXLIBS = -lstdc++ -lm -lc
+  CXXRTS = cxxrt.o newlibrt.o
+endif
+
+#
+#  ã½ã¼ã¹ãã¡ã¤ã«ã®ãã£ã¬ã¯ããªã®å®ç¾©
+#
+SRCDIR = ../../..
+
+#
+#  ãªãã¸ã§ã¯ããã¡ã¤ã«åã®æ¡å¼µå­ã®è¨­å®
+#
+OBJEXT = exe
+
+#
+#  å®è¡ç°å¢ã®å®ç¾©ï¼ã¿ã¼ã²ããä¾å­ã«ä¸æ¸ããããå ´åãããï¼
+#
+DBGENV := 
+
+#
+#  ã«ã¼ãã«ã©ã¤ãã©ãªï¼libkernel.aï¼ã®ãã£ã¬ã¯ããªå
+#  ï¼ã«ã¼ãã«ã©ã¤ãã©ãªãmakeå¯¾è±¡ã«ããæã¯ï¼ç©ºã«å®ç¾©ããï¼
+#
+KERNEL_LIB = ../libkernel
+
+#
+#  ã«ã¼ãã«ãé¢æ°åä½ã§ã³ã³ãã¤ã«ãããã©ããã®å®ç¾©
+#
+KERNEL_FUNCOBJS = 
+
+#
+#  ãã¬ã¼ã¹ã­ã°ãåå¾ãããã©ããã®å®ç¾©
+#
+ENABLE_TRACE = 
+
+#
+#  ã¦ã¼ãã£ãªãã£ãã­ã°ã©ã ã®åç§°
+#
+PERL = /usr/bin/perl
+CFG = $(SRCDIR)/cfg/cfg/cfg
+
+#
+#  ãªãã¸ã§ã¯ããã¡ã¤ã«åã®å®ç¾©
+#
+OBJNAME = asp
+ifdef OBJEXT
+  OBJFILE = $(OBJNAME).$(OBJEXT)
+  CFG1_OUT = cfg1_out.$(OBJEXT)
+else
+  OBJFILE = $(OBJNAME)
+  CFG1_OUT = cfg1_out
+endif
+
+#
+#  ã¿ã¼ã²ããä¾å­é¨ã®ãã£ã¬ã¯ããªã®å®ç¾©
+#
+TARGETDIR = $(SRCDIR)/target/$(TARGET)
+
+#
+#  ã¿ã¼ã²ããä¾å­ã®å®ç¾©ã®ã¤ã³ã¯ã«ã¼ã
+#
+include $(TARGETDIR)/Makefile.target
+
+#
+#  ã³ã³ãã£ã®ã¥ã¬ã¼ã¿é¢ä¿ã®å¤æ°ã®å®ç¾©
+#
+CFG_TABS := --api-table $(SRCDIR)/kernel/kernel_api.csv \
+			--cfg1-def-table $(SRCDIR)/kernel/kernel_def.csv $(CFG_TABS)
+
+CFG_ASMOBJS := $(CFG_ASMOBJS)
+CFG_COBJS := kernel_cfg.o $(CFG_COBJS)
+CFG_OBJS := $(CFG_ASMOBJS) $(CFG_COBJS)
+CFG2_OUT_SRCS := kernel_cfg.h kernel_cfg.c $(CFG2_OUT_SRCS)
+
+#
+#  å
+±éã³ã³ãã¤ã«ãªãã·ã§ã³ã®å®ç¾©
+#
+COPTS := $(COPTS) -g 
+ifndef OMIT_WARNING_ALL
+  COPTS := $(COPTS) -Wall
+endif
+ifndef OMIT_OPTIMIZATION
+  COPTS := $(COPTS) -O2
+endif
+CDEFS := $(CDEFS) -DMONITOR_PORTID=1 -DUSE_RTC_WAKEUP_CMD
+INCLUDES := -I. -I$(SRCDIR)/include -I$(SRCDIR)/arch -I$(SRCDIR) $(INCLUDES)
+LDFLAGS := $(LDFLAGS) 
+CFG1_OUT_LDFLAGS := $(CFG1_OUT_LDFLAGS) 
+LIBS := $(LIBS) $(CXXLIBS)
+CFLAGS = $(COPTS) $(CDEFS) $(INCLUDES)
+
+#
+#  ã¢ããªã±ã¼ã·ã§ã³ãã­ã°ã©ã ã«é¢ããå®ç¾©
+#
+APPLNAME = sample1
+APPLDIR = 
+APPL_CFG = $(APPLNAME).cfg
+
+APPL_DIR = $(APPLDIR) $(SRCDIR)/library
+APPL_ASMOBJS =
+ifdef USE_CXX
+  APPL_CXXOBJS = $(APPLNAME).o command.o
+  APPL_COBJS =
+else
+  APPL_COBJS = $(APPLNAME).o command.o
+endif
+APPL_COBJS := $(APPL_COBJS) log_output.o vasyslog.o t_perror.o strerror.o
+APPL_CFLAGS =
+APPL_LIBS =
+ifdef APPLDIR
+  INCLUDES := $(INCLUDES) $(foreach dir,$(APPLDIR),-I$(dir))
+endif
+
+#  ããã«ã¦ã§ã¢ã® Makefile ã®ã¤ã³ã¯ã«ã¼ã
+#
+include $(SRCDIR)/monitor/Makefile.config
+
+#
+#  ã·ã¹ãã ãµã¼ãã¹ã«é¢ããå®ç¾©
+#
+SYSSVC_DIR := $(SYSSVC_DIR) $(SRCDIR)/syssvc $(SRCDIR)/pdic/stm32f7xx $(SRCDIR)/library
+SYSSVC_ASMOBJS := $(SYSSVC_ASMOBJS)
+SYSSVC_COBJS := $(SYSSVC_COBJS) banner.o syslog.o serial.o logtask.o armv7m.o \
+				 device.o clock.o $(CXXRTS)
+SYSSVC_CFLAGS := $(SYSSVC_CFLAGS)
+SYSSVC_LIBS := $(SYSSVC_LIBS)
+INCLUDES := -I$(SRCDIR)/pdic/stm32f7xx $(INCLUDES)
+
+#
+#  ã«ã¼ãã«ã«é¢ããå®ç¾©
+#
+#  KERNEL_ASMOBJS: ã«ã¼ãã«ã©ã¤ãã©ãªã«å«ããï¼ã½ã¼ã¹ãã¢ã»ã³ããªè¨èªã®
+#				   ãªãã¸ã§ã¯ããã¡ã¤ã«ï¼
+#  KERNEL_COBJS: ã«ã¼ãã«ã®ã©ã¤ãã©ãªã«å«ããï¼ã½ã¼ã¹ãCè¨èªã§ï¼ã½ã¼ã¹
+#				 ãã¡ã¤ã«ã¨1å¯¾1ã«å¯¾å¿ãããªãã¸ã§ã¯ããã¡ã¤ã«ï¼
+#  KERNEL_LCSRCS: ã«ã¼ãã«ã®ã©ã¤ãã©ãªã«å«ããCè¨èªã®ã½ã¼ã¹ãã¡ã¤ã«ã§ï¼
+#				  1ã¤ã®ã½ã¼ã¹ãã¡ã¤ã«ããè¤æ°ã®ãªãã¸ã§ã¯ããã¡ã¤ã«ãç
+#				  æãããã®ï¼
+#  KERNEL_LCOBJS: ä¸ã®ã½ã¼ã¹ãã¡ã¤ã«ããçæããããªãã¸ã§ã¯ããã¡ã¤ã«ï¼
+#  KERNEL_AUX_COBJS: ã­ã¼ãã¢ã¸ã¥ã¼ã«ã«å«ããªããï¼ã«ã¼ãã«ã®ã½ã¼ã¹ãã¡
+#					 ã¤ã«ã¨åããªãã·ã§ã³ãé©ç¨ãã¦ã³ã³ãã¤ã«ãã¹ãï¼ã½ã¼
+#					 ã¹ãCè¨èªã®ãªãã¸ã§ã¯ããã¡ã¤ã«ï¼
+#
+KERNEL_DIR := $(KERNEL_DIR) $(SRCDIR)/kernel
+KERNEL_ASMOBJS := $(KERNEL_ASMOBJS)
+KERNEL_COBJS := $(KERNEL_COBJS)
+KERNEL_CFLAGS := $(KERNEL_CFLAGS) -I$(SRCDIR)/kernel
+ifdef OMIT_MAKEOFFSET
+  OFFSET_H =
+else
+  OFFSET_H = offset.h
+ifndef OFFSET_TF
+  KERNEL_AUX_COBJS := $(KERNEL_AUX_COBJS) makeoffset.o
+endif
+endif
+
+#
+#  ã¿ã¼ã²ãããã¡ã¤ã«ï¼è¤æ°ãåæã«é¸æãã¦ã¯ãªããªãï¼
+#
+#all: $(OBJFILE)
+all: $(OBJNAME).bin
+#all: $(OBJNAME).srec
+
+##### ä»¥ä¸ã¯ç·¨éããªããã¨ #####
+
+#
+#  ç°å¢ã«ä¾å­ããã³ã³ãã¤ã«ãªãã·ã§ã³ã®å®ç¾©
+#
+ifdef DBGENV
+  CDEFS := $(CDEFS) -D$(DBGENV)
+endif
+
+#
+#  ã«ã¼ãã«ã®ãã¡ã¤ã«æ§æã®å®ç¾©
+#
+include $(SRCDIR)/kernel/Makefile.kernel
+ifdef KERNEL_FUNCOBJS
+  KERNEL_LCSRCS := $(KERNEL_FCSRCS)
+  KERNEL_LCOBJS := $(foreach file,$(KERNEL_FCSRCS),$($(file:.c=)))
+else
+  KERNEL_CFLAGS := -DALLFUNC $(KERNEL_CFLAGS)
+  KERNEL_COBJS := $(KERNEL_COBJS) \
+					$(foreach file,$(KERNEL_FCSRCS),$(file:.c=.o))
+endif
+
+#
+#  ã½ã¼ã¹ãã¡ã¤ã«ã®ãããã£ã¬ã¯ããªã«é¢ããå®ç¾©
+#
+vpath %.c $(KERNEL_DIR) $(SYSSVC_DIR) $(APPL_DIR)
+vpath %.S $(KERNEL_DIR) $(SYSSVC_DIR) $(APPL_DIR)
+vpath %.cfg $(APPL_DIR)
+
+#
+#  ã³ã³ãã¤ã«ã®ããã®å¤æ°ã®å®ç¾©
+#
+KERNEL_LIB_OBJS = $(KERNEL_ASMOBJS) $(KERNEL_COBJS) $(KERNEL_LCOBJS)
+SYSSVC_OBJS = $(SYSSVC_ASMOBJS) $(SYSSVC_COBJS)
+APPL_OBJS = $(APPL_ASMOBJS) $(APPL_COBJS) $(APPL_CXXOBJS)
+ALL_OBJS = $(START_OBJS) $(APPL_OBJS) $(SYSSVC_OBJS) $(CFG_OBJS) \
+											$(END_OBJS) $(HIDDEN_OBJS)
+ifdef KERNEL_LIB
+  ALL_LIBS = $(APPL_LIBS) $(SYSSVC_LIBS) -lkernel $(LIBS)
+  LIBS_DEP = $(filter %.a,$(ALL_LIBS)) $(KERNEL_LIB)/libkernel.a
+  LDFLAGS := $(LDFLAGS) -L$(KERNEL_LIB)
+  REALCLEAN_FILES := libkernel.a $(REALCLEAN_FILES)
+else
+  ALL_LIBS = $(APPL_LIBS) $(SYSSVC_LIBS) libkernel.a $(LIBS)
+  LIBS_DEP = $(filter %.a,$(ALL_LIBS))
+endif
+
+ifdef TEXT_START_ADDRESS
+  LDFLAGS := $(LDFLAGS) -Wl,-Ttext,$(TEXT_START_ADDRESS)
+  CFG1_OUT_LDFLAGS := $(CFG1_OUT_LDFLAGS) -Wl,-Ttext,$(TEXT_START_ADDRESS)
+endif
+ifdef DATA_START_ADDRESS
+  LDFLAGS := $(LDFLAGS) -Wl,-Tdata,$(DATA_START_ADDRESS)
+  CFG1_OUT_LDFLAGS := $(CFG1_OUT_LDFLAGS) -Wl,-Tdata,$(DATA_START_ADDRESS)
+endif
+ifdef LDSCRIPT
+  LDFLAGS := $(LDFLAGS) -T $(LDSCRIPT)
+  CFG1_OUT_LDFLAGS := $(CFG1_OUT_LDFLAGS) -T $(LDSCRIPT)
+endif
+
+#
+#  ãªãã»ãããã¡ã¤ã«ï¼offset.hï¼ã®çæè¦å
+#
+ifdef OFFSET_TF
+offset.h: $(APPL_CFG) kernel_cfg.timestamp
+	$(CFG) --pass 3 --kernel asp $(INCLUDES) \
+				--rom-image cfg1_out.srec --symbol-table cfg1_out.syms \
+				-T $(OFFSET_TF) $(CFG_TABS) $<
+else
+offset.h: makeoffset.s $(SRCDIR)/utils/genoffset
+	$(PERL) $(SRCDIR)/utils/genoffset makeoffset.s > offset.h
+endif
+
+#
+#  ã«ã¼ãã«ã®ã³ã³ãã£ã®ã¥ã¬ã¼ã·ã§ã³ãã¡ã¤ã«ã®çæ
+#
+cfg1_out.c: $(APPL_CFG)
+	$(CFG) --pass 1 --kernel asp $(INCLUDES) $(CFG_TABS) $<
+
+$(CFG2_OUT_SRCS): kernel_cfg.timestamp
+kernel_cfg.timestamp: $(APPL_CFG) \
+						$(START_OBJS) cfg1_out.o $(END_OBJS) $(HIDDEN_OBJS)
+	$(LINK) $(CFLAGS) $(CFG1_OUT_LDFLAGS) -o $(CFG1_OUT) \
+						$(START_OBJS) cfg1_out.o $(END_OBJS)
+	$(NM) -n $(CFG1_OUT) > cfg1_out.syms
+	$(OBJCOPY) -O srec -S $(CFG1_OUT) cfg1_out.srec
+	$(CFG) --pass 2 --kernel asp $(INCLUDES) \
+				-T $(TARGETDIR)/target.tf $(CFG_TABS) $<
+	touch -r kernel_cfg.c kernel_cfg.timestamp
+
+#
+#  ã«ã¼ãã«ã©ã¤ãã©ãªãã¡ã¤ã«ã®çæ
+#
+libkernel.a: $(OFFSET_H) $(KERNEL_LIB_OBJS)
+	rm -f libkernel.a
+	$(AR) -rcs libkernel.a $(KERNEL_LIB_OBJS)
+	$(RANLIB) libkernel.a
+
+#
+#  ç¹å¥ãªä¾å­é¢ä¿ã®å®ç¾©
+#
+banner.o: kernel_cfg.timestamp $(filter-out banner.o,$(ALL_OBJS)) $(LIBS_DEP)
+
+#
+#  å
+¨ä½ã®ãªã³ã¯
+#
+$(OBJFILE): $(APPL_CFG) kernel_cfg.timestamp $(ALL_OBJS) $(LIBS_DEP)
+	$(LINK) $(CFLAGS) $(LDFLAGS) -o $(OBJFILE) $(START_OBJS) \
+			$(APPL_OBJS) $(SYSSVC_OBJS) $(CFG_OBJS) $(ALL_LIBS) $(END_OBJS)
+	$(NM) -n $(OBJFILE) > $(OBJNAME).syms
+	$(OBJCOPY) -O srec -S $(OBJFILE) $(OBJNAME).srec
+	$(CFG) --pass 3 --kernel asp $(INCLUDES) \
+				--rom-image $(OBJNAME).srec --symbol-table $(OBJNAME).syms \
+				-T $(TARGETDIR)/target_check.tf $(CFG_TABS) $<
+
+#
+#  ãã¤ããªãã¡ã¤ã«ã®çæ
+#
+$(OBJNAME).bin: $(OBJFILE)
+	$(OBJCOPY) -O binary -S $(OBJFILE) $(OBJNAME).bin
+
+#
+#  Sã¬ã³ã¼ããã¡ã¤ã«ã®çæ
+#
+$(OBJNAME).srec: $(OBJFILE)
+	$(OBJCOPY) -O srec -S $(OBJFILE) $(OBJNAME).srec
+
+#
+#  ã³ã³ãã¤ã«çµæã®æ¶å»
+#
+.PHONY: clean
+clean:
+	rm -f \#* *~ *.o $(CLEAN_FILES)
+	rm -f $(OBJFILE) $(OBJNAME).syms $(OBJNAME).srec $(OBJNAME).bin
+	rm -f kernel_cfg.timestamp $(CFG2_OUT_SRCS)
+	rm -f cfg1_out.c $(CFG1_OUT) cfg1_out.syms cfg1_out.srec
+ifndef KERNEL_LIB
+	rm -f libkernel.a
+endif
+	rm -f makeoffset.s offset.h
+
+.PHONY: cleankernel
+cleankernel:
+	rm -rf $(KERNEL_LIB_OBJS)
+	rm -f makeoffset.s offset.h
+
+.PHONY: cleandep
+cleandep:
+	if ! [ -f Makefile.depend ]; then \
+		rm -f kernel_cfg.timestamp $(CFG2_OUT_SRCS); \
+		rm -f cfg1_out.c cfg1_out.o $(CFG1_OUT) cfg1_out.syms cfg1_out.srec; \
+		rm -f makeoffset.s offset.h; \
+	fi
+	rm -f Makefile.depend
+
+.PHONY: realclean
+realclean: cleandep clean
+	rm -f $(REALCLEAN_FILES)
+
+#
+#  ã³ã³ãã£ã®ã¥ã¬ã¼ã¿ãçæãããã¡ã¤ã«ã®ã³ã³ãã¤ã«ã«ã¼ã«ã¨ä¾å­é¢ä¿ä½æ
+#  ã«ã¼ã«ã®å®ç¾©
+#
+#  ã³ã³ãã£ã®ã¥ã¬ã¼ã¿ãçæãããã¡ã¤ã«ã¯ï¼ã¢ããªã±ã¼ã·ã§ã³ãã­ã°ã©ã ç¨ï¼
+#  ã·ã¹ãã ãµã¼ãã¹ç¨ï¼ã«ã¼ãã«ç¨ã®ãã¹ã¦ã®ãªãã·ã§ã³ãä»ãã¦ã³ã³ãã¤ã«
+#  ããï¼
+#
+ALL_CFG_COBJS = $(CFG_COBJS) cfg1_out.o
+ALL_CFG_ASMOBJS = $(CFG_ASMOBJS)
+CFG_CFLAGS = $(APPL_CFLAGS) $(SYSSVC_CFLAGS) $(KERNEL_CFLAGS)
+
+$(ALL_CFG_COBJS): %.o: %.c
+	$(CC) -c $(CFLAGS) $(CFG_CFLAGS) $<
+
+$(ALL_CFG_COBJS:.o=.s): %.s: %.c
+	$(CC) -S $(CFLAGS) $(CFG_CFLAGS) $<
+
+$(ALL_CFG_COBJS:.o=.d): %.d: %.c
+	@$(PERL) $(SRCDIR)/utils/makedep -C $(CC) $(MAKEDEP_OPTS) \
+		-O "$(CFLAGS) $(CFG_CFLAGS)" $< >> Makefile.depend
+
+$(ALL_CFG_ASMOBJS): %.o: %.S
+	$(CC) -c $(CFLAGS) $(CFG_CFLAGS) $<
+
+$(ALL_CFG_ASMOBJS:.o=.d): %.d: %.S
+	@$(PERL) $(SRCDIR)/utils/makedep -C $(CC) $(MAKEDEP_OPTS) \
+		-O "$(CFLAGS) $(CFG_CFLAGS)" $< >> Makefile.depend
+
+#
+#  ç¹æ®ãªä¾å­é¢ä¿ä½æã«ã¼ã«ã®å®ç¾©
+#
+cfg1_out.depend: $(APPL_CFG)
+	@$(CFG) -M cfg1_out.c $(INCLUDES) $< >> Makefile.depend
+
+makeoffset.d: makeoffset.c
+	@$(PERL) $(SRCDIR)/utils/makedep -C $(CC) $(MAKEDEP_OPTS) \
+		-T "makeoffset.s" -O "$(CFLAGS) $(KERNEL_CFLAGS)" $< >> Makefile.depend
+
+#
+#  ä¾å­é¢ä¿ãã¡ã¤ã«ã®çæ
+#
+.PHONY: gendepend
+gendepend:
+	@echo "Generating Makefile.depend."
+
+.PHONY: depend
+ifdef KERNEL_LIB
+depend: cleandep kernel_cfg.timestamp gendepend \
+		cfg1_out.depend cfg1_out.d \
+		$(ALL_OBJS:.o=.d)
+else
+depend: cleandep $(OFFSET_H) kernel_cfg.timestamp gendepend \
+		cfg1_out.depend cfg1_out.d \
+		$(KERNEL_AUX_COBJS:.o=.d) $(KERNEL_ASMOBJS:.o=.d) \
+		$(KERNEL_COBJS:.o=.d) $(KERNEL_LCSRCS:.c=.d) $(ALL_OBJS:.o=.d)
+endif
+
+#
+#  ä¾å­é¢ä¿ãã¡ã¤ã«ãã¤ã³ã¯ã«ã¼ã
+#
+-include Makefile.depend
+
+#
+#  éçºãã¼ã«ã®ã³ãã³ãåã®å®ç¾©
+#
+ifeq ($(TOOL),gcc)
+  #
+  #  GNUéçºç°å¢ç¨
+  #
+  ifdef GCC_TARGET
+    GCC_TARGET_PREFIX = $(GCC_TARGET)-
+  else
+    GCC_TARGET_PREFIX =
+  endif
+  CC = $(GCC_TARGET_PREFIX)gcc
+  CXX = $(GCC_TARGET_PREFIX)g++
+  AS = $(GCC_TARGET_PREFIX)as
+  LD = $(GCC_TARGET_PREFIX)ld
+  AR = $(GCC_TARGET_PREFIX)ar
+  NM = $(GCC_TARGET_PREFIX)nm
+  RANLIB = $(GCC_TARGET_PREFIX)ranlib
+  OBJCOPY = $(GCC_TARGET_PREFIX)objcopy
+  OBJDUMP = $(GCC_TARGET_PREFIX)objdump
+endif
+
+ifdef USE_CXX
+  LINK = $(CXX)
+else
+  LINK = $(CC)
+endif
+
+#
+#  ã³ã³ãã¤ã«ã«ã¼ã«ã®å®ç¾©
+#
+KERNEL_ALL_COBJS = $(KERNEL_COBJS) $(KERNEL_AUX_COBJS)
+
+$(KERNEL_ALL_COBJS): %.o: %.c
+	$(CC) -c $(CFLAGS) $(KERNEL_CFLAGS) $<
+
+$(KERNEL_ALL_COBJS:.o=.s): %.s: %.c
+	$(CC) -S $(CFLAGS) $(KERNEL_CFLAGS) $<
+
+$(KERNEL_LCOBJS): %.o:
+	$(CC) -DTOPPERS_$(*F) -o $@ -c $(CFLAGS) $(KERNEL_CFLAGS) $<
+
+$(KERNEL_LCOBJS:.o=.s): %.s:
+	$(CC) -DTOPPERS_$(*F) -o $@ -S $(CFLAGS) $(KERNEL_CFLAGS) $<
+
+$(KERNEL_ASMOBJS): %.o: %.S
+	$(CC) -c $(CFLAGS) $(KERNEL_CFLAGS) $<
+
+$(SYSSVC_COBJS): %.o: %.c
+	$(CC) -c $(CFLAGS) $(SYSSVC_CFLAGS) $<
+
+$(SYSSVC_COBJS:.o=.s): %.s: %.c
+	$(CC) -S $(CFLAGS) $(SYSSVC_CFLAGS) $<
+
+$(SYSSVC_ASMOBJS): %.o: %.S
+	$(CC) -c $(CFLAGS) $(SYSSVC_CFLAGS) $<
+
+$(APPL_COBJS): %.o: %.c
+	$(CC) -c $(CFLAGS) $(APPL_CFLAGS) $<
+
+$(APPL_COBJS:.o=.s): %.s: %.c
+	$(CC) -S $(CFLAGS) $(APPL_CFLAGS) $<
+
+$(APPL_CXXOBJS): %.o: %.cpp
+	$(CXX) -c $(CFLAGS) $(APPL_CFLAGS) $<
+
+$(APPL_CXXOBJS:.o=.s): %.s: %.cpp
+	$(CXX) -S $(CFLAGS) $(APPL_CFLAGS) $<
+
+$(APPL_ASMOBJS): %.o: %.S
+	$(CC) -c $(CFLAGS) $(APPL_CFLAGS) $<
+
+#
+#  ä¾å­é¢ä¿ä½æã«ã¼ã«ã®å®ç¾©
+#
+$(KERNEL_COBJS:.o=.d): %.d: %.c
+	@$(PERL) $(SRCDIR)/utils/makedep -C $(CC) $(MAKEDEP_OPTS) \
+		-O "$(CFLAGS) $(KERNEL_CFLAGS)" $< >> Makefile.depend
+
+$(KERNEL_LCSRCS:.c=.d): %.d: %.c
+	@$(PERL) $(SRCDIR)/utils/makedep -C $(CC) $(MAKEDEP_OPTS) -T "$($*)" \
+		-O "-DALLFUNC $(CFLAGS) $(KERNEL_CFLAGS)" $< >> Makefile.depend
+
+$(KERNEL_ASMOBJS:.o=.d): %.d: %.S
+	@$(PERL) $(SRCDIR)/utils/makedep -C $(CC) $(MAKEDEP_OPTS) \
+		-O "$(CFLAGS) $(KERNEL_CFLAGS)" $< >> Makefile.depend
+
+$(SYSSVC_COBJS:.o=.d): %.d: %.c
+	@$(PERL) $(SRCDIR)/utils/makedep -C $(CC) $(MAKEDEP_OPTS) \
+		-O "$(CFLAGS) $(SYSSVC_CFLAGS)" $< >> Makefile.depend
+
+$(SYSSVC_ASMOBJS:.o=.d): %.d: %.S
+	@$(PERL) $(SRCDIR)/utils/makedep -C $(CC) $(MAKEDEP_OPTS) \
+		-O "$(CFLAGS) $(SYSSVC_CFLAGS)" $< >> Makefile.depend
+
+$(APPL_COBJS:.o=.d): %.d: %.c
+	@$(PERL) $(SRCDIR)/utils/makedep -C $(CC) $(MAKEDEP_OPTS) \
+		-O "$(CFLAGS) $(APPL_CFLAGS)" $< >> Makefile.depend
+
+$(APPL_CXXOBJS:.o=.d): %.d: %.cpp
+	@$(PERL) $(SRCDIR)/utils/makedep -C $(CXX) $(MAKEDEP_OPTS) \
+		-O "$(CFLAGS) $(APPL_CFLAGS)" $< >> Makefile.depend
+
+$(APPL_ASMOBJS:.o=.d): %.d: %.S
+	@$(PERL) $(SRCDIR)/utils/makedep -C $(CC) $(MAKEDEP_OPTS) \
+		-O "$(CFLAGS) $(APPL_CFLAGS)" $< >> Makefile.depend
+
+#
+#  ããã©ã«ãã³ã³ãã¤ã«ã«ã¼ã«ãä¸æ¸ã
+#
+%.o: %.c
+	@echo "*** Default compile rules should not be used."
+	$(CC) -c $(CFLAGS) $<
+
+%.s: %.c
+	@echo "*** Default compile rules should not be used."
+	$(CC) -S $(CFLAGS) $<
+
+%.o: %.cpp
+	@echo "*** Default compile rules should not be used."
+	$(CXX) -c $(CFLAGS) $<
+
+%.s: %.cpp
+	@echo "*** Default compile rules should not be used."
+	$(CXX) -S $(CFLAGS) $<
+
+%.o: %.S
+	@echo "*** Default compile rules should not be used."
+	$(CC) -c $(CFLAGS) $<
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/OBJ/STM32F767NUCLEO144_GCC/MON/command.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/OBJ/STM32F767NUCLEO144_GCC/MON/command.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/OBJ/STM32F767NUCLEO144_GCC/MON/command.c	(revision 457)
@@ -0,0 +1,141 @@
+#include <kernel.h>
+#include <t_syslog.h>
+#include <stdio.h>
+#include <t_stdlib.h>
+#include <stdlib.h>
+#include "syssvc/serial.h"
+#include "syssvc/syslog.h"
+#include "kernel_cfg.h"
+#include "monitor.h"
+#include "device.h"
+
+/*
+ *  デバイスコマンド番号
+ */
+#define NUM_DEVICE_CMD   3
+
+static int_t led_func(int argc, char **argv);
+static int_t dip_func(int argc, char **argv);
+static int_t cup_func(int argc, char **argv);
+
+/*
+ *  デバイスコマンドテーブル
+ */
+static const COMMAND_INFO device_command_info[NUM_DEVICE_CMD] = {
+	{"LED",		led_func},
+	{"DIP",		dip_func},
+	{"CUP",		cup_func}
+};
+
+static const char device_name[] = "DEVICE";
+static const char device_help[] =
+"  Device  LED (no) (on-1,off-0)  led   control\n"
+"          DIP (no) (on-1,off-0)  dipsw control\n"
+"          CUP command            cup   control\n";
+
+static const uint16_t led_pattern[4] = {
+	LED01, LED02, LED03, LED04
+};
+
+static COMMAND_LINK device_command_link = {
+	NULL,
+	NUM_DEVICE_CMD,
+	device_name,
+	NULL,
+	device_help,
+	&device_command_info[0]
+};
+
+static uint8_t cup_command;
+
+static int a2i(char *str)
+{
+	int num = 0;
+
+	while(*str >= '0' && *str <= '9'){
+		num = num * 10 + *str++ - '0';
+	}
+	return num;
+}
+
+/*
+ *  DEVICEコマンド設定関数
+ */
+void device_info_init(intptr_t exinf)
+{
+	setup_command(&device_command_link);
+}
+
+/*
+ *  LED設定コマンド関数
+ */
+static int_t led_func(int argc, char **argv)
+{
+	int_t    arg1=0, arg2;
+	uint16_t reg;
+
+	if(argc < 3)
+		return -1;
+	arg1 = a2i(argv[1]);
+	arg2 = a2i(argv[2]);
+	if(arg1 >= 1 && arg1 <= 4){
+		reg = led_in();
+		if(arg2 != 0)
+			reg |= led_pattern[arg1-1];
+		else
+			reg &= ~led_pattern[arg1-1];
+		led_out(reg);
+	}
+	return 0;
+}
+
+/*
+ *  DIPSW設定コマンド関数
+ */
+static int_t dip_func(int argc, char **argv)
+{
+	int_t   arg1=0, arg2=0, i;
+
+	if(argc > 1)
+		arg1 = a2i(argv[1]);
+	if(argc > 2)
+		arg2 = a2i(argv[2]);
+	if(arg1 >= 1 && arg1 <= 8){
+		if(arg2 != 0)
+			dipsw_value |= (0x1<<(arg1-1));
+		else
+			dipsw_value &= ~(0x1<<(arg1-1));
+	}
+	printf("dipsw\n1   2   3   4   5   6   7   8\n");
+	for(i = 0 ; i < 8 ; i++){
+		if(dipsw_value & (1<<i))
+			printf("ON  ");
+		else
+			printf("OFF ");
+	}
+	printf("\n");
+	return 0;
+}
+
+/*
+ *  カップラーメンタイマ補助コマンド関数
+ */
+static int_t cup_func(int argc, char **argv)
+{
+	if(argc > 1)
+		cup_command = *argv[1];
+	return 0;
+}
+
+/*
+ * CUPラーメンコマンド
+ */
+int8_t
+get_cup_command(void)
+{
+	uint8_t cmd = cup_command;
+	cup_command = 0;
+	return cmd;
+}
+
+
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/OBJ/STM32F767NUCLEO144_GCC/MON/sample1.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/OBJ/STM32F767NUCLEO144_GCC/MON/sample1.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/OBJ/STM32F767NUCLEO144_GCC/MON/sample1.c	(revision 457)
@@ -0,0 +1,541 @@
+/*
+ *  TOPPERS/ASP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Advanced Standard Profile Kernel
+ * 
+ *  Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
+ *                              Toyohashi Univ. of Technology, JAPAN
+ *  Copyright (C) 2004-2012 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  $Id$
+ */
+
+/* 
+ *  サンプルプログラム(1)の本体
+ *
+ *  ASPカーネルの基本的な動作を確認するためのサンプルプログラム．
+ *
+ *  プログラムの概要:
+ *
+ *  ユーザインタフェースを受け持つメインタスク（タスクID: MAIN_TASK，優
+ *  先度: MAIN_PRIORITY）と，3つの並行実行されるタスク（タスクID:
+ *  TASK1～TASK3，初期優先度: MID_PRIORITY）で構成される．また，起動周
+ *  期が2秒の周期ハンドラ（周期ハンドラID: CYCHDR1）を用いる．
+ *
+ *  並行実行されるタスクは，task_loop回空ループを実行する度に，タスクが
+ *  実行中であることをあらわすメッセージを表示する．空ループを実行する
+ *  のは，空ループなしでメッセージを出力すると，多量のメッセージが出力
+ *  され，プログラムの動作が確認しずらくなるためである．また，低速なシ
+ *  リアルポートを用いてメッセージを出力する場合に，すべてのメッセージ
+ *  が出力できるように，メッセージの量を制限するという理由もある．
+ *
+ *  周期ハンドラは，三つの優先度（HIGH_PRIORITY，MID_PRIORITY，
+ *  LOW_PRIORITY）のレディキューを回転させる．プログラムの起動直後は，
+ *  周期ハンドラは停止状態になっている．
+ *
+ *  メインタスクは，シリアルI/Oポートからの文字入力を行い（文字入力を
+ *  待っている間は，並行実行されるタスクが実行されている），入力された
+ *  文字に対応した処理を実行する．入力された文字と処理の関係は次の通り．
+ *  Control-Cまたは'Q'が入力されると，プログラムを終了する．
+ *
+ *  '1' : 対象タスクをTASK1に切り換える（初期設定）．
+ *  '2' : 対象タスクをTASK2に切り換える．
+ *  '3' : 対象タスクをTASK3に切り換える．
+ *  'a' : 対象タスクをact_tskにより起動する．
+ *  'A' : 対象タスクに対する起動要求をcan_actによりキャンセルする．
+ *  'e' : 対象タスクにext_tskを呼び出させ，終了させる．
+ *  't' : 対象タスクをter_tskにより強制終了する．
+ *  '>' : 対象タスクの優先度をHIGH_PRIORITYにする．
+ *  '=' : 対象タスクの優先度をMID_PRIORITYにする．
+ *  '<' : 対象タスクの優先度をLOW_PRIORITYにする．
+ *  'G' : 対象タスクの優先度をget_priで読み出す．
+ *  's' : 対象タスクにslp_tskを呼び出させ，起床待ちにさせる．
+ *  'S' : 対象タスクにtslp_tsk(10秒)を呼び出させ，起床待ちにさせる．
+ *  'w' : 対象タスクをwup_tskにより起床する．
+ *  'W' : 対象タスクに対する起床要求をcan_wupによりキャンセルする．
+ *  'l' : 対象タスクをrel_waiにより強制的に待ち解除にする．
+ *  'u' : 対象タスクをsus_tskにより強制待ち状態にする．
+ *  'm' : 対象タスクの強制待ち状態をrsm_tskにより解除する．
+ *  'd' : 対象タスクにdly_tsk(10秒)を呼び出させ，時間経過待ちにさせる．
+ *  'x' : 対象タスクに例外パターン0x0001の例外処理を要求する．
+ *  'X' : 対象タスクに例外パターン0x0002の例外処理を要求する．
+ *  'y' : 対象タスクにdis_texを呼び出させ，タスク例外を禁止する．
+ *  'Y' : 対象タスクにena_texを呼び出させ，タスク例外を許可する．
+ *  'r' : 3つの優先度（HIGH_PRIORITY，MID_PRIORITY，LOW_PRIORITY）のレ
+ *        ディキューを回転させる．
+ *  'c' : 周期ハンドラを動作開始させる．
+ *  'C' : 周期ハンドラを動作停止させる．
+ *  'b' : アラームハンドラを5秒後に起動するよう動作開始させる．
+ *  'B' : アラームハンドラを動作停止させる．
+ *  'z' : 対象タスクにCPU例外を発生させる（タスクを終了させる）．
+ *  'Z' : 対象タスクにCPUロック状態でCPU例外を発生させる（プログラムを
+ *        終了する）．
+ *  'V' : get_utmで性能評価用システム時刻を2回読む．
+ *  'v' : 発行したシステムコールを表示する（デフォルト）．
+ *  'q' : 発行したシステムコールを表示しない．
+ */
+
+#include <kernel.h>
+#include <t_syslog.h>
+#include <t_stdlib.h>
+#include "syssvc/serial.h"
+#include "syssvc/syslog.h"
+#include "kernel_cfg.h"
+#include "sample1.h"
+
+/*
+ *  サービスコールのエラーのログ出力
+ */
+Inline void
+svc_perror(const char *file, int_t line, const char *expr, ER ercd)
+{
+	if (ercd < 0) {
+		t_perror(LOG_ERROR, file, line, expr, ercd);
+	}
+}
+
+#define	SVC_PERROR(expr)	svc_perror(__FILE__, __LINE__, #expr, (expr))
+
+/*
+ *  並行実行されるタスクへのメッセージ領域
+ */
+char	message[3];
+
+/*
+ *  ループ回数
+ */
+ulong_t	task_loop;		/* タスク内でのループ回数 */
+ulong_t	tex_loop;		/* 例外処理ルーチン内でのループ回数 */
+
+#if 1	/* ROI DEBUG */
+void sw_handle(void)
+{
+	syslog_0(LOG_NOTICE, "## sw int ##");
+}
+#endif	/* ROI DEBUG */
+
+/*
+ *  並行実行されるタスク
+ */
+void task(intptr_t exinf)
+{
+	volatile ulong_t	i;
+	int_t		n = 0;
+	int_t		tskno = (int_t) exinf;
+	const char	*graph[] = { "|", "  +", "    *" };
+	char		c;
+
+	SVC_PERROR(ena_tex());
+	while (true) {
+		syslog(LOG_NOTICE, "task%d is running (%03d).   %s",
+										tskno, ++n, graph[tskno-1]);
+		for (i = 0; i < task_loop; i++);
+		c = message[tskno-1];
+		message[tskno-1] = 0;
+		switch (c) {
+		case 'e':
+			syslog(LOG_INFO, "#%d#ext_tsk()", tskno);
+			SVC_PERROR(ext_tsk());
+			assert(0);
+		case 's':
+			syslog(LOG_INFO, "#%d#slp_tsk()", tskno);
+			SVC_PERROR(slp_tsk());
+			break;
+		case 'S':
+			syslog(LOG_INFO, "#%d#tslp_tsk(10000)", tskno);
+			SVC_PERROR(tslp_tsk(10000));
+			break;
+		case 'd':
+			syslog(LOG_INFO, "#%d#dly_tsk(10000)", tskno);
+			SVC_PERROR(dly_tsk(10000));
+			break;
+		case 'y':
+			syslog(LOG_INFO, "#%d#dis_tex()", tskno);
+			SVC_PERROR(dis_tex());
+			break;
+		case 'Y':
+			syslog(LOG_INFO, "#%d#ena_tex()", tskno);
+			SVC_PERROR(ena_tex());
+			break;
+#ifdef CPUEXC1
+		case 'z':
+			syslog(LOG_NOTICE, "#%d#raise CPU exception", tskno);
+			RAISE_CPU_EXCEPTION;
+			break;
+		case 'Z':
+			SVC_PERROR(loc_cpu());
+			syslog(LOG_NOTICE, "#%d#raise CPU exception", tskno);
+			RAISE_CPU_EXCEPTION;
+			SVC_PERROR(unl_cpu());
+			break;
+#endif /* CPUEXC1 */
+		default:
+			break;
+		}
+	}
+}
+
+/*
+ *  並行して実行されるタスク用のタスク例外処理ルーチン
+ */
+void tex_routine(TEXPTN texptn, intptr_t exinf)
+{
+	volatile ulong_t	i;
+	int_t	tskno = (int_t) exinf;
+
+	syslog(LOG_NOTICE, "task%d receives exception 0x%04x.", tskno, texptn);
+	for (i = 0; i < tex_loop; i++);
+
+	if ((texptn & 0x8000U) != 0U) {
+		syslog(LOG_INFO, "#%d#ext_tsk()", tskno);
+		SVC_PERROR(ext_tsk());
+		assert(0);
+	}
+}
+
+/*
+ *  CPU例外ハンドラ
+ */
+#ifdef CPUEXC1
+
+void
+cpuexc_handler(void *p_excinf)
+{
+	ID		tskid;
+
+	syslog(LOG_NOTICE, "CPU exception handler (p_excinf = %08p).", p_excinf);
+	if (sns_ctx() != true) {
+		syslog(LOG_WARNING,
+					"sns_ctx() is not true in CPU exception handler.");
+	}
+	if (sns_dpn() != true) {
+		syslog(LOG_WARNING,
+					"sns_dpn() is not true in CPU exception handler.");
+	}
+	syslog(LOG_INFO, "sns_loc = %d sns_dsp = %d sns_tex = %d",
+									sns_loc(), sns_dsp(), sns_tex());
+	syslog(LOG_INFO, "xsns_dpn = %d xsns_xpn = %d",
+									xsns_dpn(p_excinf), xsns_xpn(p_excinf));
+
+	if (xsns_xpn(p_excinf)) {
+		syslog(LOG_NOTICE, "Sample program ends with exception.");
+		SVC_PERROR(ext_ker());
+		assert(0);
+	}
+
+	SVC_PERROR(iget_tid(&tskid));
+	SVC_PERROR(iras_tex(tskid, 0x8000U));
+}
+
+#endif /* CPUEXC1 */
+
+/*
+ *  周期ハンドラ
+ *
+ *  HIGH_PRIORITY，MID_PRIORITY，LOW_PRIORITY の各優先度のレディキュー
+ *  を回転させる．
+ */
+void cyclic_handler(intptr_t exinf)
+{
+	SVC_PERROR(irot_rdq(HIGH_PRIORITY));
+	SVC_PERROR(irot_rdq(MID_PRIORITY));
+	SVC_PERROR(irot_rdq(LOW_PRIORITY));
+}
+
+/*
+ *  アラームハンドラ
+ *
+ *  HIGH_PRIORITY，MID_PRIORITY，LOW_PRIORITY の各優先度のレディキュー
+ *  を回転させる．
+ */
+void alarm_handler(intptr_t exinf)
+{
+	SVC_PERROR(irot_rdq(HIGH_PRIORITY));
+	SVC_PERROR(irot_rdq(MID_PRIORITY));
+	SVC_PERROR(irot_rdq(LOW_PRIORITY));
+}
+
+/*
+ *  メインタスク
+ */
+void main_task(intptr_t exinf)
+{
+	char	c;
+	ID		tskid = TASK1;
+	int_t	tskno = 1;
+	ER_UINT	ercd;
+	PRI		tskpri;
+#ifndef TASK_LOOP
+	volatile ulong_t	i;
+	SYSTIM	stime1, stime2;
+#endif /* TASK_LOOP */
+#ifdef TOPPERS_SUPPORT_GET_UTM
+	SYSUTM	utime1, utime2;
+#endif /* TOPPERS_SUPPORT_GET_UTM */
+
+	SVC_PERROR(syslog_msk_log(LOG_UPTO(LOG_INFO), LOG_UPTO(LOG_EMERG)));
+	syslog(LOG_NOTICE, "Sample program starts (exinf = %d).", (int_t) exinf);
+
+	/*
+	 *  シリアルポートの初期化
+	 *
+	 *  システムログタスクと同じシリアルポートを使う場合など，シリアル
+	 *  ポートがオープン済みの場合にはここでE_OBJエラーになるが，支障は
+	 *  ない．
+	 */
+	ercd = serial_opn_por(TASK_PORTID);
+	if (ercd < 0 && MERCD(ercd) != E_OBJ) {
+		syslog(LOG_ERROR, "%s (%d) reported by `serial_opn_por'.",
+									itron_strerror(ercd), SERCD(ercd));
+	}
+	SVC_PERROR(serial_ctl_por(TASK_PORTID,
+							(IOCTL_CRLF | IOCTL_FCSND | IOCTL_FCRCV)));
+
+	/*
+ 	 *  ループ回数の設定
+	 *
+	 *  並行実行されるタスク内での空ループの回数（task_loop）は，空ルー
+	 *  プの実行時間が約0.4秒になるように設定する．この設定のために，
+	 *  LOOP_REF回の空ループの実行時間を，その前後でget_timを呼ぶことで
+	 *  測定し，その測定結果から空ループの実行時間が0.4秒になるループ回
+	 *  数を求め，task_loopに設定する．
+	 *
+	 *  LOOP_REFは，デフォルトでは1,000,000に設定しているが，想定したよ
+	 *  り遅いプロセッサでは，サンプルプログラムの実行開始に時間がかか
+	 *  りすぎるという問題を生じる．逆に想定したより速いプロセッサでは，
+	 *  LOOP_REF回の空ループの実行時間が短くなり，task_loopに設定する値
+	 *  の誤差が大きくなるという問題がある．
+	 *
+	 *  そこで，そのようなターゲットでは，target_test.hで，LOOP_REFを適
+	 *  切な値に定義するのが望ましい．
+	 *
+	 *  また，task_loopの値を固定したい場合には，その値をTASK_LOOPにマ
+	 *  クロ定義する．TASK_LOOPがマクロ定義されている場合，上記の測定を
+	 *  行わずに，TASK_LOOPに定義された値を空ループの回数とする．
+	 *
+	 * ターゲットによっては，空ループの実行時間の1回目の測定で，本来よ
+	 * りも長めになるものがある．このようなターゲットでは，MEASURE_TWICE
+	 * をマクロ定義することで，1回目の測定結果を捨てて，2回目の測定結果
+	 * を使う．
+	 *
+	 *  タスク例外処理ルーチン内での空ループの回数（tex_loop）は，
+	 *  task_loopの4分の1の値（空ループの実行時間が0.1秒になるループ回
+	 *  数）に設定する．
+	 */
+#ifdef TASK_LOOP
+	task_loop = TASK_LOOP;
+#else /* TASK_LOOP */
+
+#ifdef MEASURE_TWICE
+	task_loop = LOOP_REF;
+	SVC_PERROR(get_tim(&stime1));
+	for (i = 0; i < task_loop; i++);
+	SVC_PERROR(get_tim(&stime2));
+#endif /* MEASURE_TWICE */
+
+	task_loop = LOOP_REF;
+	SVC_PERROR(get_tim(&stime1));
+	for (i = 0; i < task_loop; i++);
+	SVC_PERROR(get_tim(&stime2));
+	task_loop = LOOP_REF * 400UL / (stime2 - stime1);
+
+#endif /* TASK_LOOP */
+	tex_loop = task_loop / 4;
+
+	/*
+ 	 *  タスクの起動
+	 */
+	SVC_PERROR(act_tsk(TASK1));
+	SVC_PERROR(act_tsk(TASK2));
+	SVC_PERROR(act_tsk(TASK3));
+
+	/*
+ 	 *  メインループ
+	 */
+	do {
+		SVC_PERROR(serial_rea_dat(TASK_PORTID, &c, 1));
+		switch (c) {
+		case 'e':
+		case 's':
+		case 'S':
+		case 'd':
+		case 'y':
+		case 'Y':
+		case 'z':
+		case 'Z':
+			message[tskno-1] = c;
+			break;
+		case '1':
+			tskno = 1;
+			tskid = TASK1;
+			break;
+		case '2':
+			tskno = 2;
+			tskid = TASK2;
+			break;
+		case '3':
+			tskno = 3;
+			tskid = TASK3;
+			break;
+		case 'a':
+			syslog(LOG_INFO, "#act_tsk(%d)", tskno);
+			SVC_PERROR(act_tsk(tskid));
+			break;
+		case 'A':
+			syslog(LOG_INFO, "#can_act(%d)", tskno);
+			SVC_PERROR(ercd = can_act(tskid));
+			if (ercd >= 0) {
+				syslog(LOG_NOTICE, "can_act(%d) returns %d", tskno, ercd);
+			}
+			break;
+		case 't':
+			syslog(LOG_INFO, "#ter_tsk(%d)", tskno);
+			SVC_PERROR(ter_tsk(tskid));
+			break;
+		case '>':
+			syslog(LOG_INFO, "#chg_pri(%d, HIGH_PRIORITY)", tskno);
+			SVC_PERROR(chg_pri(tskid, HIGH_PRIORITY));
+			break;
+		case '=':
+			syslog(LOG_INFO, "#chg_pri(%d, MID_PRIORITY)", tskno);
+			SVC_PERROR(chg_pri(tskid, MID_PRIORITY));
+			break;
+		case '<':
+			syslog(LOG_INFO, "#chg_pri(%d, LOW_PRIORITY)", tskno);
+			SVC_PERROR(chg_pri(tskid, LOW_PRIORITY));
+			break;
+		case 'G':
+			syslog(LOG_INFO, "#get_pri(%d, &tskpri)", tskno);
+			SVC_PERROR(ercd = get_pri(tskid, &tskpri));
+			if (ercd >= 0) {
+				syslog(LOG_NOTICE, "priority of task %d is %d", tskno, tskpri);
+			}
+			break;
+		case 'w':
+			syslog(LOG_INFO, "#wup_tsk(%d)", tskno);
+			SVC_PERROR(wup_tsk(tskid));
+			break;
+		case 'W':
+			syslog(LOG_INFO, "#can_wup(%d)", tskno);
+			SVC_PERROR(ercd = can_wup(tskid));
+			if (ercd >= 0) {
+				syslog(LOG_NOTICE, "can_wup(%d) returns %d", tskno, ercd);
+			}
+			break;
+		case 'l':
+			syslog(LOG_INFO, "#rel_wai(%d)", tskno);
+			SVC_PERROR(rel_wai(tskid));
+			break;
+		case 'u':
+			syslog(LOG_INFO, "#sus_tsk(%d)", tskno);
+			SVC_PERROR(sus_tsk(tskid));
+			break;
+		case 'm':
+			syslog(LOG_INFO, "#rsm_tsk(%d)", tskno);
+			SVC_PERROR(rsm_tsk(tskid));
+			break;
+		case 'x':
+			syslog(LOG_INFO, "#ras_tex(%d, 0x0001U)", tskno);
+			SVC_PERROR(ras_tex(tskid, 0x0001U));
+			break;
+		case 'X':
+			syslog(LOG_INFO, "#ras_tex(%d, 0x0002U)", tskno);
+			SVC_PERROR(ras_tex(tskid, 0x0002U));
+			break;
+		case 'r':
+			syslog(LOG_INFO, "#rot_rdq(three priorities)");
+			SVC_PERROR(rot_rdq(HIGH_PRIORITY));
+			SVC_PERROR(rot_rdq(MID_PRIORITY));
+			SVC_PERROR(rot_rdq(LOW_PRIORITY));
+			break;
+		case 'c':
+			syslog(LOG_INFO, "#sta_cyc(1)");
+			SVC_PERROR(sta_cyc(CYCHDR1));
+			break;
+		case 'C':
+			syslog(LOG_INFO, "#stp_cyc(1)");
+			SVC_PERROR(stp_cyc(CYCHDR1));
+			break;
+		case 'b':
+			syslog(LOG_INFO, "#sta_alm(1, 5000)");
+			SVC_PERROR(sta_alm(ALMHDR1, 5000));
+			break;
+		case 'B':
+			syslog(LOG_INFO, "#stp_alm(1)");
+			SVC_PERROR(stp_alm(ALMHDR1));
+			break;
+
+		case 'V':
+#ifdef TOPPERS_SUPPORT_GET_UTM
+			SVC_PERROR(get_utm(&utime1));
+			SVC_PERROR(get_utm(&utime2));
+			syslog(LOG_NOTICE, "utime1 = %ld, utime2 = %ld",
+										(ulong_t) utime1, (ulong_t) utime2);
+#else /* TOPPERS_SUPPORT_GET_UTM */
+			syslog(LOG_NOTICE, "get_utm is not supported.");
+#endif /* TOPPERS_SUPPORT_GET_UTM */
+			break;
+
+		case 'v':
+			SVC_PERROR(syslog_msk_log(LOG_UPTO(LOG_INFO),
+										LOG_UPTO(LOG_EMERG)));
+			break;
+		case 'q':
+			SVC_PERROR(syslog_msk_log(LOG_UPTO(LOG_NOTICE),
+										LOG_UPTO(LOG_EMERG)));
+			break;
+
+#ifdef BIT_KERNEL
+		case ' ':
+			SVC_PERROR(loc_cpu());
+			{
+				extern ER	bit_kernel(void);
+
+				SVC_PERROR(ercd = bit_kernel());
+				if (ercd >= 0) {
+					syslog(LOG_NOTICE, "bit_kernel passed.");
+				}
+			}
+			SVC_PERROR(unl_cpu());
+			break;
+#endif /* BIT_KERNEL */
+
+		default:
+			break;
+		}
+	} while (c != '\003' && c != 'Q');
+
+	syslog(LOG_NOTICE, "Sample program ends.");
+	SVC_PERROR(ext_ker());
+	assert(0);
+}
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/OBJ/STM32F767NUCLEO144_GCC/MON/sample1.cfg
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/OBJ/STM32F767NUCLEO144_GCC/MON/sample1.cfg	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/OBJ/STM32F767NUCLEO144_GCC/MON/sample1.cfg	(revision 457)
@@ -0,0 +1,30 @@
+/*
+ *  $Id$
+ */
+
+/*
+ *  サンプルプログラム(1)のシステムコンフィギュレーションファイル
+ */
+INCLUDE("target_timer.cfg");
+INCLUDE("syssvc/syslog.cfg");
+INCLUDE("syssvc/banner.cfg");
+INCLUDE("syssvc/serial.cfg");
+INCLUDE("syssvc/logtask.cfg");
+INCLUDE("monitor/monitor.cfg");
+INCLUDE("pdic/stm32f7xx/device.cfg");
+
+#include "sample1.h"
+CRE_TSK(TASK1, { TA_NULL, 1, task, MID_PRIORITY, STACK_SIZE, NULL });
+CRE_TSK(TASK2, { TA_NULL, 2, task, MID_PRIORITY, STACK_SIZE, NULL });
+CRE_TSK(TASK3, { TA_NULL, 3, task, MID_PRIORITY, STACK_SIZE, NULL });
+CRE_TSK(MAIN_TASK, { TA_NULL, 0, main_task, MAIN_PRIORITY, STACK_SIZE, NULL });
+DEF_TEX(TASK1, { TA_NULL, tex_routine });
+DEF_TEX(TASK2, { TA_NULL, tex_routine });
+DEF_TEX(TASK3, { TA_NULL, tex_routine });
+CRE_CYC(CYCHDR1, { TA_NULL, 0, cyclic_handler, 2000, 0 });
+CRE_ALM(ALMHDR1, { TA_NULL, 0, alarm_handler });
+ATT_INI({ TA_NULL, 0, device_info_init });
+ATT_INI({ TA_NULL, sw_handle, setup_sw_func });
+#ifdef CPUEXC1
+DEF_EXC(CPUEXC1, { TA_NULL, cpuexc_handler });
+#endif /* CPUEXC1 */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/OBJ/STM32F767NUCLEO144_GCC/MON/sample1.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/OBJ/STM32F767NUCLEO144_GCC/MON/sample1.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/OBJ/STM32F767NUCLEO144_GCC/MON/sample1.h	(revision 457)
@@ -0,0 +1,94 @@
+/*
+ *  TOPPERS/ASP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Advanced Standard Profile Kernel
+ *
+ *  Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
+ *                              Toyohashi Univ. of Technology, JAPAN
+ *  Copyright (C) 2004-2010 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ *
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ *
+ *  $Id$
+ */
+
+/*
+ *		サンプルプログラム(1)のヘッダファイル
+ */
+
+/*
+ *  ターゲット依存の定義
+ */
+#include "target_test.h"
+
+/*
+ *  各タスクの優先度の定義
+ */
+
+#define MAIN_PRIORITY	5		/* メインタスクの優先度 */
+								/* HIGH_PRIORITYより高くすること */
+
+#define HIGH_PRIORITY	9		/* 並行実行されるタスクの優先度 */
+#define MID_PRIORITY	10
+#define LOW_PRIORITY	11
+
+/*
+ *  ターゲットに依存する可能性のある定数の定義
+ */
+
+#ifndef TASK_PORTID
+#define	TASK_PORTID		1			/* 文字入力するシリアルポートID */
+#endif /* TASK_PORTID */
+
+#ifndef STACK_SIZE
+#define	STACK_SIZE		4096		/* タスクのスタックサイズ */
+#endif /* STACK_SIZE */
+
+#ifndef LOOP_REF
+#define LOOP_REF		ULONG_C(1000000)	/* 速度計測用のループ回数 */
+#endif /* LOOP_REF */
+
+/*
+ *  関数のプロトタイプ宣言
+ */
+#ifndef TOPPERS_MACRO_ONLY
+
+extern void	task(intptr_t exinf);
+extern void	main_task(intptr_t exinf);
+extern void	tex_routine(TEXPTN texptn, intptr_t exinf);
+#ifdef CPUEXC1
+extern void	cpuexc_handler(void *p_excinf);
+#endif /* CPUEXC1 */
+extern void	cyclic_handler(intptr_t exinf);
+extern void	alarm_handler(intptr_t exinf);
+extern void sw_handle(void);
+
+#endif /* TOPPERS_MACRO_ONLY */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/OBJ/STM32F767NUCLEO144_GCC/USBO/Makefile
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/OBJ/STM32F767NUCLEO144_GCC/USBO/Makefile	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/OBJ/STM32F767NUCLEO144_GCC/USBO/Makefile	(revision 457)
@@ -0,0 +1,630 @@
+#
+#  TOPPERS/ASP Kernel
+#      Toyohashi Open Platform for Embedded Real-Time Systems/
+#      Advanced Standard Profile Kernel
+# 
+#  Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
+#                              Toyohashi Univ. of Technology, JAPAN
+#  Copyright (C) 2006-2014 by Embedded and Real-Time Systems Laboratory
+#              Graduate School of Information Science, Nagoya Univ., JAPAN
+# 
+#  ä¸è¨èä½æ¨©è
+ã¯ï¼ä»¥ä¸ã®(1)ï½(4)ã®æ¡ä»¶ãæºããå ´åã«éãï¼æ¬ã½ããã¦ã§
+#  ã¢ï¼æ¬ã½ããã¦ã§ã¢ãæ¹å¤ãããã®ãå«ãï¼ä»¥ä¸åãï¼ãä½¿ç¨ã»è¤è£½ã»æ¹
+#  å¤ã»åé
+å¸ï¼ä»¥ä¸ï¼å©ç¨ã¨å¼ã¶ï¼ãããã¨ãç¡åã§è¨±è«¾ããï¼
+#  (1) æ¬ã½ããã¦ã§ã¢ãã½ã¼ã¹ã³ã¼ãã®å½¢ã§å©ç¨ããå ´åã«ã¯ï¼ä¸è¨ã®èä½
+#      æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨ã®ç¡ä¿è¨¼è¦å®ãï¼ãã®ã¾ã¾ã®å½¢ã§ã½ã¼
+#      ã¹ã³ã¼ãä¸­ã«å«ã¾ãã¦ãããã¨ï¼
+#  (2) æ¬ã½ããã¦ã§ã¢ãï¼ã©ã¤ãã©ãªå½¢å¼ãªã©ï¼ä»ã®ã½ããã¦ã§ã¢éçºã«ä½¿
+#      ç¨ã§ããå½¢ã§åé
+å¸ããå ´åã«ã¯ï¼åé
+å¸ã«ä¼´ããã­ã¥ã¡ã³ãï¼å©ç¨
+#      è
+ããã¥ã¢ã«ãªã©ï¼ã«ï¼ä¸è¨ã®èä½æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨
+#      ã®ç¡ä¿è¨¼è¦å®ãæ²è¼ãããã¨ï¼
+#  (3) æ¬ã½ããã¦ã§ã¢ãï¼æ©å¨ã«çµã¿è¾¼ããªã©ï¼ä»ã®ã½ããã¦ã§ã¢éçºã«ä½¿
+#      ç¨ã§ããªãå½¢ã§åé
+å¸ããå ´åã«ã¯ï¼æ¬¡ã®ããããã®æ¡ä»¶ãæºããã
+#      ã¨ï¼
+#    (a) åé
+å¸ã«ä¼´ããã­ã¥ã¡ã³ãï¼å©ç¨è
+ããã¥ã¢ã«ãªã©ï¼ã«ï¼ä¸è¨ã®è
+#        ä½æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨ã®ç¡ä¿è¨¼è¦å®ãæ²è¼ãããã¨ï¼
+#    (b) åé
+å¸ã®å½¢æ
+ãï¼å¥ã«å®ããæ¹æ³ã«ãã£ã¦ï¼TOPPERSãã­ã¸ã§ã¯ãã«
+#        å ±åãããã¨ï¼
+#  (4) æ¬ã½ããã¦ã§ã¢ã®å©ç¨ã«ããç´æ¥çã¾ãã¯éæ¥çã«çãããããªãæ
+#      å®³ãããï¼ä¸è¨èä½æ¨©è
+ããã³TOPPERSãã­ã¸ã§ã¯ããå
+è²¬ãããã¨ï¼
+#      ã¾ãï¼æ¬ã½ããã¦ã§ã¢ã®ã¦ã¼ã¶ã¾ãã¯ã¨ã³ãã¦ã¼ã¶ããã®ãããªãç
+#      ç±ã«åºã¥ãè«æ±ãããï¼ä¸è¨èä½æ¨©è
+ããã³TOPPERSãã­ã¸ã§ã¯ãã
+#      å
+è²¬ãããã¨ï¼
+# 
+#  æ¬ã½ããã¦ã§ã¢ã¯ï¼ç¡ä¿è¨¼ã§æä¾ããã¦ãããã®ã§ããï¼ä¸è¨èä½æ¨©è
+ã
+#  ãã³TOPPERSãã­ã¸ã§ã¯ãã¯ï¼æ¬ã½ããã¦ã§ã¢ã«é¢ãã¦ï¼ç¹å®ã®ä½¿ç¨ç®ç
+#  ã«å¯¾ããé©åæ§ãå«ãã¦ï¼ãããªãä¿è¨¼ãè¡ããªãï¼ã¾ãï¼æ¬ã½ããã¦ã§
+#  ã¢ã®å©ç¨ã«ããç´æ¥çã¾ãã¯éæ¥çã«çãããããªãæå®³ã«é¢ãã¦ãï¼ã
+#  ã®è²¬ä»»ãè² ããªãï¼
+# 
+#  $Id$
+# 
+
+#
+#  ã¿ã¼ã²ããã®æå®ï¼Makefile.targetã§ä¸æ¸ããããã®ãé²ãããï¼
+#
+all:
+
+#
+#  ã¿ã¼ã²ããç¥ç§°ã®å®ç¾©
+#
+TARGET = stm32f767nucleo144_gcc
+
+#
+#  ãã­ã°ã©ãã³ã°è¨èªã®å®ç¾©
+#
+SRCLANG = c
+ifeq ($(SRCLANG),c)
+  LIBS = -lc
+endif
+ifeq ($(SRCLANG),c++)
+  USE_CXX = true
+  CXXLIBS = -lstdc++ -lm -lc
+  CXXRTS = cxxrt.o newlibrt.o
+endif
+
+#
+#  ã½ã¼ã¹ãã¡ã¤ã«ã®ãã£ã¬ã¯ããªã®å®ç¾©
+#
+SRCDIR = ../../..
+
+#
+#  ãªãã¸ã§ã¯ããã¡ã¤ã«åã®æ¡å¼µå­ã®è¨­å®
+#
+OBJEXT = exe
+
+#
+#  å®è¡ç°å¢ã®å®ç¾©ï¼ã¿ã¼ã²ããä¾å­ã«ä¸æ¸ããããå ´åãããï¼
+#
+DBGENV := 
+
+#
+#  ã«ã¼ãã«ã©ã¤ãã©ãªï¼libkernel.aï¼ã®ãã£ã¬ã¯ããªå
+#  ï¼ã«ã¼ãã«ã©ã¤ãã©ãªãmakeå¯¾è±¡ã«ããæã¯ï¼ç©ºã«å®ç¾©ããï¼
+#
+KERNEL_LIB = ../libkernel
+
+#
+#  ã«ã¼ãã«ãé¢æ°åä½ã§ã³ã³ãã¤ã«ãããã©ããã®å®ç¾©
+#
+KERNEL_FUNCOBJS = 
+
+#
+#  ãã¬ã¼ã¹ã­ã°ãåå¾ãããã©ããã®å®ç¾©
+#
+ENABLE_TRACE = 
+
+#
+#   USB OTGã®ã¢ã¼ãå®ç¾©
+#
+USB_OTG_MODE = USB_OTG_MODE_HOST
+
+#
+#  ã¦ã¼ãã£ãªãã£ãã­ã°ã©ã ã®åç§°
+#
+PERL = /usr/bin/perl
+CFG = $(SRCDIR)/cfg/cfg/cfg
+
+#
+#  ãªãã¸ã§ã¯ããã¡ã¤ã«åã®å®ç¾©
+#
+OBJNAME = asp
+ifdef OBJEXT
+  OBJFILE = $(OBJNAME).$(OBJEXT)
+  CFG1_OUT = cfg1_out.$(OBJEXT)
+else
+  OBJFILE = $(OBJNAME)
+  CFG1_OUT = cfg1_out
+endif
+
+#
+#  ã¿ã¼ã²ããä¾å­é¨ã®ãã£ã¬ã¯ããªã®å®ç¾©
+#
+TARGETDIR = $(SRCDIR)/target/$(TARGET)
+
+#
+#  ã¿ã¼ã²ããä¾å­ã®å®ç¾©ã®ã¤ã³ã¯ã«ã¼ã
+#
+include $(TARGETDIR)/Makefile.target
+
+#
+#  ã³ã³ãã£ã®ã¥ã¬ã¼ã¿é¢ä¿ã®å¤æ°ã®å®ç¾©
+#
+CFG_TABS := --api-table $(SRCDIR)/kernel/kernel_api.csv \
+			--cfg1-def-table $(SRCDIR)/kernel/kernel_def.csv $(CFG_TABS)
+
+CFG_ASMOBJS := $(CFG_ASMOBJS)
+CFG_COBJS := kernel_cfg.o $(CFG_COBJS)
+CFG_OBJS := $(CFG_ASMOBJS) $(CFG_COBJS)
+CFG2_OUT_SRCS := kernel_cfg.h kernel_cfg.c $(CFG2_OUT_SRCS)
+
+#
+#  å
+±éã³ã³ãã¤ã«ãªãã·ã§ã³ã®å®ç¾©
+#
+COPTS := $(COPTS) -g 
+ifndef OMIT_WARNING_ALL
+  COPTS := $(COPTS) -Wall
+endif
+ifndef OMIT_OPTIMIZATION
+  COPTS := $(COPTS) -O2
+endif
+CDEFS := $(CDEFS) 
+INCLUDES := -I. -I$(SRCDIR)/include -I$(SRCDIR)/arch -I$(SRCDIR) $(INCLUDES)
+LDFLAGS := $(LDFLAGS) 
+CFG1_OUT_LDFLAGS := $(CFG1_OUT_LDFLAGS) 
+LIBS := $(LIBS) $(CXXLIBS)
+CFLAGS = $(COPTS) $(CDEFS) $(INCLUDES)
+
+#
+#  ã¢ããªã±ã¼ã·ã§ã³ãã­ã°ã©ã ã«é¢ããå®ç¾©
+#
+APPLNAME = usbotest
+APPLDIR = 
+APPL_CFG = $(APPLNAME).cfg
+
+APPL_DIR = $(APPLDIR) $(SRCDIR)/library
+APPL_ASMOBJS =
+ifdef USE_CXX
+  APPL_CXXOBJS = $(APPLNAME).o command.o 
+  APPL_COBJS =
+else
+  APPL_COBJS = $(APPLNAME).o command.o 
+endif
+ifneq ($(USB_OTG_MODE),USB_OTG_MODE_DEVICE)
+APPL_COBJS := $(APPL_COBJS) hid_mouse.o hid_keyboard.o
+endif
+ifneq ($(USB_OTG_MODE),USB_OTG_MODE_HOST)
+APPL_COBJS := $(APPL_COBJS) usbddesc.o
+endif
+APPL_COBJS := $(APPL_COBJS) log_output.o vasyslog.o t_perror.o strerror.o
+
+
+APPL_CFLAGS = 
+APPL_LIBS =
+ifdef APPLDIR
+  INCLUDES := $(INCLUDES) $(foreach dir,$(APPLDIR),-I$(dir))
+endif
+
+#  ããã«ã¦ã§ã¢ã® Makefile ã®ã¤ã³ã¯ã«ã¼ã
+#
+include $(SRCDIR)/monitor/Makefile.config
+include $(SRCDIR)/usb/Makefile.config
+
+#
+#   USB CLASSã®è¿½å 
+#
+ifneq ($(USB_OTG_MODE),USB_OTG_MODE_DEVICE)
+SYSSVC_COBJS := $(SYSSVC_COBJS) tusbh_msc.o tusbh_hid.o tusbh_serial.o tusbh_prt.o tusbh_hub.o
+endif
+ifneq ($(USB_OTG_MODE),USB_OTG_MODE_HOST)
+ifeq ($(DEVICE_CLASS),SERIAL)
+SYSSVC_COBJS := $(SYSSVC_COBJS) tusbd_serial.o
+INCLUDES := $(INCLUDES) -I$(SRCDIR)/usb/device/SERIAL
+CDEFS := $(CDEFS) -DUSB_DEVICE_ID=1
+else
+SYSSVC_COBJS := $(SYSSVC_COBJS) tusbd_hid.o
+INCLUDES := $(INCLUDES) -I$(SRCDIR)/usb/device/HID
+CDEFS := $(CDEFS) -DUSB_DEVICE_ID=0
+endif
+endif
+
+#
+#  GDICã® Makefile ã®ã¤ã³ã¯ã«ã¼ã
+#
+include $(SRCDIR)/gdic/usb_otg/Makefile.config
+
+#
+#  ã·ã¹ãã ãµã¼ãã¹ã«é¢ããå®ç¾©
+#
+SYSSVC_DIR := $(SYSSVC_DIR) $(SRCDIR)/syssvc $(SRCDIR)/library $(SRCDIR)/pdic/stm32f7xx
+SYSSVC_ASMOBJS := $(SYSSVC_ASMOBJS)
+SYSSVC_COBJS := $(SYSSVC_COBJS) banner.o syslog.o serial.o logtask.o armv7m.o \
+				device.o clock.o usb_otg.o malloc.o tlsf.o $(CXXRTS)
+SYSSVC_CFLAGS := $(SYSSVC_CFLAGS)
+SYSSVC_LIBS := $(SYSSVC_LIBS)
+INCLUDES := $(INCLUDES) -I$(SRCDIR)/pdic/stm32f7xx
+
+#
+#  ã«ã¼ãã«ã«é¢ããå®ç¾©
+#
+#  KERNEL_ASMOBJS: ã«ã¼ãã«ã©ã¤ãã©ãªã«å«ããï¼ã½ã¼ã¹ãã¢ã»ã³ããªè¨èªã®
+#				   ãªãã¸ã§ã¯ããã¡ã¤ã«ï¼
+#  KERNEL_COBJS: ã«ã¼ãã«ã®ã©ã¤ãã©ãªã«å«ããï¼ã½ã¼ã¹ãCè¨èªã§ï¼ã½ã¼ã¹
+#				 ãã¡ã¤ã«ã¨1å¯¾1ã«å¯¾å¿ãããªãã¸ã§ã¯ããã¡ã¤ã«ï¼
+#  KERNEL_LCSRCS: ã«ã¼ãã«ã®ã©ã¤ãã©ãªã«å«ããCè¨èªã®ã½ã¼ã¹ãã¡ã¤ã«ã§ï¼
+#				  1ã¤ã®ã½ã¼ã¹ãã¡ã¤ã«ããè¤æ°ã®ãªãã¸ã§ã¯ããã¡ã¤ã«ãç
+#				  æãããã®ï¼
+#  KERNEL_LCOBJS: ä¸ã®ã½ã¼ã¹ãã¡ã¤ã«ããçæããããªãã¸ã§ã¯ããã¡ã¤ã«ï¼
+#  KERNEL_AUX_COBJS: ã­ã¼ãã¢ã¸ã¥ã¼ã«ã«å«ããªããï¼ã«ã¼ãã«ã®ã½ã¼ã¹ãã¡
+#					 ã¤ã«ã¨åããªãã·ã§ã³ãé©ç¨ãã¦ã³ã³ãã¤ã«ãã¹ãï¼ã½ã¼
+#					 ã¹ãCè¨èªã®ãªãã¸ã§ã¯ããã¡ã¤ã«ï¼
+#
+KERNEL_DIR := $(KERNEL_DIR) $(SRCDIR)/kernel
+KERNEL_ASMOBJS := $(KERNEL_ASMOBJS)
+KERNEL_COBJS := $(KERNEL_COBJS)
+KERNEL_CFLAGS := $(KERNEL_CFLAGS) -I$(SRCDIR)/kernel
+ifdef OMIT_MAKEOFFSET
+  OFFSET_H =
+else
+  OFFSET_H = offset.h
+ifndef OFFSET_TF
+  KERNEL_AUX_COBJS := $(KERNEL_AUX_COBJS) makeoffset.o
+endif
+endif
+
+#
+#  ã¿ã¼ã²ãããã¡ã¤ã«ï¼è¤æ°ãåæã«é¸æãã¦ã¯ãªããªãï¼
+#
+#all: $(OBJFILE)
+all: $(OBJNAME).bin
+#all: $(OBJNAME).srec
+
+##### ä»¥ä¸ã¯ç·¨éããªããã¨ #####
+
+#
+#  ç°å¢ã«ä¾å­ããã³ã³ãã¤ã«ãªãã·ã§ã³ã®å®ç¾©
+#
+ifdef DBGENV
+  CDEFS := $(CDEFS) -D$(DBGENV)
+endif
+
+#
+#  ã«ã¼ãã«ã®ãã¡ã¤ã«æ§æã®å®ç¾©
+#
+include $(SRCDIR)/kernel/Makefile.kernel
+ifdef KERNEL_FUNCOBJS
+  KERNEL_LCSRCS := $(KERNEL_FCSRCS)
+  KERNEL_LCOBJS := $(foreach file,$(KERNEL_FCSRCS),$($(file:.c=)))
+else
+  KERNEL_CFLAGS := -DALLFUNC $(KERNEL_CFLAGS)
+  KERNEL_COBJS := $(KERNEL_COBJS) \
+					$(foreach file,$(KERNEL_FCSRCS),$(file:.c=.o))
+endif
+
+#
+#  ã½ã¼ã¹ãã¡ã¤ã«ã®ãããã£ã¬ã¯ããªã«é¢ããå®ç¾©
+#
+vpath %.c $(KERNEL_DIR) $(SYSSVC_DIR) $(APPL_DIR)
+vpath %.S $(KERNEL_DIR) $(SYSSVC_DIR) $(APPL_DIR)
+vpath %.cfg $(APPL_DIR)
+
+#
+#  ã³ã³ãã¤ã«ã®ããã®å¤æ°ã®å®ç¾©
+#
+KERNEL_LIB_OBJS = $(KERNEL_ASMOBJS) $(KERNEL_COBJS) $(KERNEL_LCOBJS)
+SYSSVC_OBJS = $(SYSSVC_ASMOBJS) $(SYSSVC_COBJS)
+APPL_OBJS = $(APPL_ASMOBJS) $(APPL_COBJS) $(APPL_CXXOBJS)
+ALL_OBJS = $(START_OBJS) $(APPL_OBJS) $(SYSSVC_OBJS) $(CFG_OBJS) \
+											$(END_OBJS) $(HIDDEN_OBJS)
+ifdef KERNEL_LIB
+  ALL_LIBS = $(APPL_LIBS) $(SYSSVC_LIBS) -lkernel $(LIBS)
+  LIBS_DEP = $(filter %.a,$(ALL_LIBS)) $(KERNEL_LIB)/libkernel.a
+  LDFLAGS := $(LDFLAGS) -L$(KERNEL_LIB)
+  REALCLEAN_FILES := libkernel.a $(REALCLEAN_FILES)
+else
+  ALL_LIBS = $(APPL_LIBS) $(SYSSVC_LIBS) libkernel.a $(LIBS)
+  LIBS_DEP = $(filter %.a,$(ALL_LIBS))
+endif
+
+ifdef TEXT_START_ADDRESS
+  LDFLAGS := $(LDFLAGS) -Wl,-Ttext,$(TEXT_START_ADDRESS)
+  CFG1_OUT_LDFLAGS := $(CFG1_OUT_LDFLAGS) -Wl,-Ttext,$(TEXT_START_ADDRESS)
+endif
+ifdef DATA_START_ADDRESS
+  LDFLAGS := $(LDFLAGS) -Wl,-Tdata,$(DATA_START_ADDRESS)
+  CFG1_OUT_LDFLAGS := $(CFG1_OUT_LDFLAGS) -Wl,-Tdata,$(DATA_START_ADDRESS)
+endif
+ifdef LDSCRIPT
+  LDFLAGS := $(LDFLAGS) -T $(LDSCRIPT)
+  CFG1_OUT_LDFLAGS := $(CFG1_OUT_LDFLAGS) -T $(LDSCRIPT)
+endif
+
+#
+#  ãªãã»ãããã¡ã¤ã«ï¼offset.hï¼ã®çæè¦å
+#
+ifdef OFFSET_TF
+offset.h: $(APPL_CFG) kernel_cfg.timestamp
+	$(CFG) --pass 3 --kernel asp $(INCLUDES) \
+				--rom-image cfg1_out.srec --symbol-table cfg1_out.syms \
+				-T $(OFFSET_TF) $(CFG_TABS) $<
+else
+offset.h: makeoffset.s $(SRCDIR)/utils/genoffset
+	$(PERL) $(SRCDIR)/utils/genoffset makeoffset.s > offset.h
+endif
+
+#
+#  ã«ã¼ãã«ã®ã³ã³ãã£ã®ã¥ã¬ã¼ã·ã§ã³ãã¡ã¤ã«ã®çæ
+#
+cfg1_out.c: $(APPL_CFG)
+	$(CFG) --pass 1 --kernel asp $(INCLUDES) $(CFG_TABS) $<
+
+$(CFG2_OUT_SRCS): kernel_cfg.timestamp
+kernel_cfg.timestamp: $(APPL_CFG) \
+						$(START_OBJS) cfg1_out.o $(END_OBJS) $(HIDDEN_OBJS)
+	$(LINK) $(CFLAGS) $(CFG1_OUT_LDFLAGS) -o $(CFG1_OUT) \
+						$(START_OBJS) cfg1_out.o $(END_OBJS)
+	$(NM) -n $(CFG1_OUT) > cfg1_out.syms
+	$(OBJCOPY) -O srec -S $(CFG1_OUT) cfg1_out.srec
+	$(CFG) --pass 2 --kernel asp $(INCLUDES) \
+				-T $(TARGETDIR)/target.tf $(CFG_TABS) $<
+	touch -r kernel_cfg.c kernel_cfg.timestamp
+
+#
+#  ã«ã¼ãã«ã©ã¤ãã©ãªãã¡ã¤ã«ã®çæ
+#
+libkernel.a: $(OFFSET_H) $(KERNEL_LIB_OBJS)
+	rm -f libkernel.a
+	$(AR) -rcs libkernel.a $(KERNEL_LIB_OBJS)
+	$(RANLIB) libkernel.a
+
+#
+#  ç¹å¥ãªä¾å­é¢ä¿ã®å®ç¾©
+#
+banner.o: kernel_cfg.timestamp $(filter-out banner.o,$(ALL_OBJS)) $(LIBS_DEP)
+
+#
+#  å
+¨ä½ã®ãªã³ã¯
+#
+$(OBJFILE): $(APPL_CFG) kernel_cfg.timestamp $(ALL_OBJS) $(LIBS_DEP)
+	$(LINK) $(CFLAGS) $(LDFLAGS) -o $(OBJFILE) $(START_OBJS) \
+			$(APPL_OBJS) $(SYSSVC_OBJS) $(CFG_OBJS) $(ALL_LIBS) $(END_OBJS)
+	$(NM) -n $(OBJFILE) > $(OBJNAME).syms
+	$(OBJCOPY) -O srec -S $(OBJFILE) $(OBJNAME).srec
+	$(CFG) --pass 3 --kernel asp $(INCLUDES) \
+				--rom-image $(OBJNAME).srec --symbol-table $(OBJNAME).syms \
+				-T $(TARGETDIR)/target_check.tf $(CFG_TABS) $<
+
+#
+#  ãã¤ããªãã¡ã¤ã«ã®çæ
+#
+$(OBJNAME).bin: $(OBJFILE)
+	$(OBJCOPY) -O binary -S $(OBJFILE) $(OBJNAME).bin
+
+#
+#  Sã¬ã³ã¼ããã¡ã¤ã«ã®çæ
+#
+$(OBJNAME).srec: $(OBJFILE)
+	$(OBJCOPY) -O srec -S $(OBJFILE) $(OBJNAME).srec
+
+#
+#  ã³ã³ãã¤ã«çµæã®æ¶å»
+#
+.PHONY: clean
+clean:
+	rm -f \#* *~ *.o $(CLEAN_FILES)
+	rm -f $(OBJFILE) $(OBJNAME).syms $(OBJNAME).srec $(OBJNAME).bin
+	rm -f kernel_cfg.timestamp $(CFG2_OUT_SRCS)
+	rm -f cfg1_out.c $(CFG1_OUT) cfg1_out.syms cfg1_out.srec
+ifndef KERNEL_LIB
+	rm -f libkernel.a
+endif
+	rm -f makeoffset.s offset.h
+
+.PHONY: cleankernel
+cleankernel:
+	rm -rf $(KERNEL_LIB_OBJS)
+	rm -f makeoffset.s offset.h
+
+.PHONY: cleandep
+cleandep:
+	if ! [ -f Makefile.depend ]; then \
+		rm -f kernel_cfg.timestamp $(CFG2_OUT_SRCS); \
+		rm -f cfg1_out.c cfg1_out.o $(CFG1_OUT) cfg1_out.syms cfg1_out.srec; \
+		rm -f makeoffset.s offset.h; \
+	fi
+	rm -f Makefile.depend
+
+.PHONY: realclean
+realclean: cleandep clean
+	rm -f $(REALCLEAN_FILES)
+
+#
+#  ã³ã³ãã£ã®ã¥ã¬ã¼ã¿ãçæãããã¡ã¤ã«ã®ã³ã³ãã¤ã«ã«ã¼ã«ã¨ä¾å­é¢ä¿ä½æ
+#  ã«ã¼ã«ã®å®ç¾©
+#
+#  ã³ã³ãã£ã®ã¥ã¬ã¼ã¿ãçæãããã¡ã¤ã«ã¯ï¼ã¢ããªã±ã¼ã·ã§ã³ãã­ã°ã©ã ç¨ï¼
+#  ã·ã¹ãã ãµã¼ãã¹ç¨ï¼ã«ã¼ãã«ç¨ã®ãã¹ã¦ã®ãªãã·ã§ã³ãä»ãã¦ã³ã³ãã¤ã«
+#  ããï¼
+#
+ALL_CFG_COBJS = $(CFG_COBJS) cfg1_out.o
+ALL_CFG_ASMOBJS = $(CFG_ASMOBJS)
+CFG_CFLAGS = $(APPL_CFLAGS) $(SYSSVC_CFLAGS) $(KERNEL_CFLAGS)
+
+$(ALL_CFG_COBJS): %.o: %.c
+	$(CC) -c $(CFLAGS) $(CFG_CFLAGS) $<
+
+$(ALL_CFG_COBJS:.o=.s): %.s: %.c
+	$(CC) -S $(CFLAGS) $(CFG_CFLAGS) $<
+
+$(ALL_CFG_COBJS:.o=.d): %.d: %.c
+	@$(PERL) $(SRCDIR)/utils/makedep -C $(CC) $(MAKEDEP_OPTS) \
+		-O "$(CFLAGS) $(CFG_CFLAGS)" $< >> Makefile.depend
+
+$(ALL_CFG_ASMOBJS): %.o: %.S
+	$(CC) -c $(CFLAGS) $(CFG_CFLAGS) $<
+
+$(ALL_CFG_ASMOBJS:.o=.d): %.d: %.S
+	@$(PERL) $(SRCDIR)/utils/makedep -C $(CC) $(MAKEDEP_OPTS) \
+		-O "$(CFLAGS) $(CFG_CFLAGS)" $< >> Makefile.depend
+
+#
+#  ç¹æ®ãªä¾å­é¢ä¿ä½æã«ã¼ã«ã®å®ç¾©
+#
+cfg1_out.depend: $(APPL_CFG)
+	@$(CFG) -M cfg1_out.c $(INCLUDES) $< >> Makefile.depend
+
+makeoffset.d: makeoffset.c
+	@$(PERL) $(SRCDIR)/utils/makedep -C $(CC) $(MAKEDEP_OPTS) \
+		-T "makeoffset.s" -O "$(CFLAGS) $(KERNEL_CFLAGS)" $< >> Makefile.depend
+
+#
+#  ä¾å­é¢ä¿ãã¡ã¤ã«ã®çæ
+#
+.PHONY: gendepend
+gendepend:
+	@echo "Generating Makefile.depend."
+
+.PHONY: depend
+ifdef KERNEL_LIB
+depend: cleandep kernel_cfg.timestamp gendepend \
+		cfg1_out.depend cfg1_out.d \
+		$(ALL_OBJS:.o=.d)
+else
+depend: cleandep $(OFFSET_H) kernel_cfg.timestamp gendepend \
+		cfg1_out.depend cfg1_out.d \
+		$(KERNEL_AUX_COBJS:.o=.d) $(KERNEL_ASMOBJS:.o=.d) \
+		$(KERNEL_COBJS:.o=.d) $(KERNEL_LCSRCS:.c=.d) $(ALL_OBJS:.o=.d)
+endif
+
+#
+#  ä¾å­é¢ä¿ãã¡ã¤ã«ãã¤ã³ã¯ã«ã¼ã
+#
+-include Makefile.depend
+
+#
+#  éçºãã¼ã«ã®ã³ãã³ãåã®å®ç¾©
+#
+ifeq ($(TOOL),gcc)
+  #
+  #  GNUéçºç°å¢ç¨
+  #
+  ifdef GCC_TARGET
+    GCC_TARGET_PREFIX = $(GCC_TARGET)-
+  else
+    GCC_TARGET_PREFIX =
+  endif
+  CC = $(GCC_TARGET_PREFIX)gcc
+  CXX = $(GCC_TARGET_PREFIX)g++
+  AS = $(GCC_TARGET_PREFIX)as
+  LD = $(GCC_TARGET_PREFIX)ld
+  AR = $(GCC_TARGET_PREFIX)ar
+  NM = $(GCC_TARGET_PREFIX)nm
+  RANLIB = $(GCC_TARGET_PREFIX)ranlib
+  OBJCOPY = $(GCC_TARGET_PREFIX)objcopy
+  OBJDUMP = $(GCC_TARGET_PREFIX)objdump
+endif
+
+ifdef USE_CXX
+  LINK = $(CXX)
+else
+  LINK = $(CC)
+endif
+
+#
+#  ã³ã³ãã¤ã«ã«ã¼ã«ã®å®ç¾©
+#
+KERNEL_ALL_COBJS = $(KERNEL_COBJS) $(KERNEL_AUX_COBJS)
+
+$(KERNEL_ALL_COBJS): %.o: %.c
+	$(CC) -c $(CFLAGS) $(KERNEL_CFLAGS) $<
+
+$(KERNEL_ALL_COBJS:.o=.s): %.s: %.c
+	$(CC) -S $(CFLAGS) $(KERNEL_CFLAGS) $<
+
+$(KERNEL_LCOBJS): %.o:
+	$(CC) -DTOPPERS_$(*F) -o $@ -c $(CFLAGS) $(KERNEL_CFLAGS) $<
+
+$(KERNEL_LCOBJS:.o=.s): %.s:
+	$(CC) -DTOPPERS_$(*F) -o $@ -S $(CFLAGS) $(KERNEL_CFLAGS) $<
+
+$(KERNEL_ASMOBJS): %.o: %.S
+	$(CC) -c $(CFLAGS) $(KERNEL_CFLAGS) $<
+
+$(SYSSVC_COBJS): %.o: %.c
+	$(CC) -c $(CFLAGS) $(SYSSVC_CFLAGS) $<
+
+$(SYSSVC_COBJS:.o=.s): %.s: %.c
+	$(CC) -S $(CFLAGS) $(SYSSVC_CFLAGS) $<
+
+$(SYSSVC_ASMOBJS): %.o: %.S
+	$(CC) -c $(CFLAGS) $(SYSSVC_CFLAGS) $<
+
+$(APPL_COBJS): %.o: %.c
+	$(CC) -c $(CFLAGS) $(APPL_CFLAGS) $<
+
+$(APPL_COBJS:.o=.s): %.s: %.c
+	$(CC) -S $(CFLAGS) $(APPL_CFLAGS) $<
+
+$(APPL_CXXOBJS): %.o: %.cpp
+	$(CXX) -c $(CFLAGS) $(APPL_CFLAGS) $<
+
+$(APPL_CXXOBJS:.o=.s): %.s: %.cpp
+	$(CXX) -S $(CFLAGS) $(APPL_CFLAGS) $<
+
+$(APPL_ASMOBJS): %.o: %.S
+	$(CC) -c $(CFLAGS) $(APPL_CFLAGS) $<
+
+#
+#  ä¾å­é¢ä¿ä½æã«ã¼ã«ã®å®ç¾©
+#
+$(KERNEL_COBJS:.o=.d): %.d: %.c
+	@$(PERL) $(SRCDIR)/utils/makedep -C $(CC) $(MAKEDEP_OPTS) \
+		-O "$(CFLAGS) $(KERNEL_CFLAGS)" $< >> Makefile.depend
+
+$(KERNEL_LCSRCS:.c=.d): %.d: %.c
+	@$(PERL) $(SRCDIR)/utils/makedep -C $(CC) $(MAKEDEP_OPTS) -T "$($*)" \
+		-O "-DALLFUNC $(CFLAGS) $(KERNEL_CFLAGS)" $< >> Makefile.depend
+
+$(KERNEL_ASMOBJS:.o=.d): %.d: %.S
+	@$(PERL) $(SRCDIR)/utils/makedep -C $(CC) $(MAKEDEP_OPTS) \
+		-O "$(CFLAGS) $(KERNEL_CFLAGS)" $< >> Makefile.depend
+
+$(SYSSVC_COBJS:.o=.d): %.d: %.c
+	@$(PERL) $(SRCDIR)/utils/makedep -C $(CC) $(MAKEDEP_OPTS) \
+		-O "$(CFLAGS) $(SYSSVC_CFLAGS)" $< >> Makefile.depend
+
+$(SYSSVC_ASMOBJS:.o=.d): %.d: %.S
+	@$(PERL) $(SRCDIR)/utils/makedep -C $(CC) $(MAKEDEP_OPTS) \
+		-O "$(CFLAGS) $(SYSSVC_CFLAGS)" $< >> Makefile.depend
+
+$(APPL_COBJS:.o=.d): %.d: %.c
+	@$(PERL) $(SRCDIR)/utils/makedep -C $(CC) $(MAKEDEP_OPTS) \
+		-O "$(CFLAGS) $(APPL_CFLAGS)" $< >> Makefile.depend
+
+$(APPL_CXXOBJS:.o=.d): %.d: %.cpp
+	@$(PERL) $(SRCDIR)/utils/makedep -C $(CXX) $(MAKEDEP_OPTS) \
+		-O "$(CFLAGS) $(APPL_CFLAGS)" $< >> Makefile.depend
+
+$(APPL_ASMOBJS:.o=.d): %.d: %.S
+	@$(PERL) $(SRCDIR)/utils/makedep -C $(CC) $(MAKEDEP_OPTS) \
+		-O "$(CFLAGS) $(APPL_CFLAGS)" $< >> Makefile.depend
+
+#
+#  ããã©ã«ãã³ã³ãã¤ã«ã«ã¼ã«ãä¸æ¸ã
+#
+%.o: %.c
+	@echo "*** Default compile rules should not be used."
+	$(CC) -c $(CFLAGS) $<
+
+%.s: %.c
+	@echo "*** Default compile rules should not be used."
+	$(CC) -S $(CFLAGS) $<
+
+%.o: %.cpp
+	@echo "*** Default compile rules should not be used."
+	$(CXX) -c $(CFLAGS) $<
+
+%.s: %.cpp
+	@echo "*** Default compile rules should not be used."
+	$(CXX) -S $(CFLAGS) $<
+
+%.o: %.S
+	@echo "*** Default compile rules should not be used."
+	$(CC) -c $(CFLAGS) $<
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/OBJ/STM32F767NUCLEO144_GCC/USBO/command.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/OBJ/STM32F767NUCLEO144_GCC/USBO/command.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/OBJ/STM32F767NUCLEO144_GCC/USBO/command.c	(revision 457)
@@ -0,0 +1,141 @@
+#include <kernel.h>
+#include <t_syslog.h>
+#include <stdio.h>
+#include <t_stdlib.h>
+#include <stdlib.h>
+#include "syssvc/serial.h"
+#include "syssvc/syslog.h"
+#include "kernel_cfg.h"
+#include "monitor.h"
+#include "device.h"
+
+/*
+ *  デバイスコマンド番号
+ */
+#define NUM_DEVICE_CMD   3
+
+static int_t led_func(int argc, char **argv);
+static int_t dip_func(int argc, char **argv);
+static int_t cup_func(int argc, char **argv);
+
+/*
+ *  デバイスコマンドテーブル
+ */
+static const COMMAND_INFO device_command_info[NUM_DEVICE_CMD] = {
+	{"LED",		led_func},
+	{"DIP",		dip_func},
+	{"CUP",		cup_func}
+};
+
+static const char device_name[] = "DEVICE";
+static const char device_help[] =
+"  Device  LED (no) (on-1,off-0)  led   control\n"
+"          DIP (no) (on-1,off-0)  dipsw control\n"
+"          CUP command            cup   control\n";
+
+static const uint16_t led_pattern[4] = {
+	LED01, LED02, LED03, LED04
+};
+
+static COMMAND_LINK device_command_link = {
+	NULL,
+	NUM_DEVICE_CMD,
+	device_name,
+	NULL,
+	device_help,
+	&device_command_info[0]
+};
+
+static uint8_t cup_command;
+
+static int a2i(char *str)
+{
+	int num = 0;
+
+	while(*str >= '0' && *str <= '9'){
+		num = num * 10 + *str++ - '0';
+	}
+	return num;
+}
+
+/*
+ *  DEVICEコマンド設定関数
+ */
+void device_info_init(intptr_t exinf)
+{
+	setup_command(&device_command_link);
+}
+
+/*
+ *  LED設定コマンド関数
+ */
+static int_t led_func(int argc, char **argv)
+{
+	int_t    arg1=0, arg2;
+	uint16_t reg;
+
+	if(argc < 3)
+		return -1;
+	arg1 = a2i(argv[1]);
+	arg2 = a2i(argv[2]);
+	if(arg1 >= 1 && arg1 <= 4){
+		reg = led_in();
+		if(arg2 != 0)
+			reg |= led_pattern[arg1-1];
+		else
+			reg &= ~led_pattern[arg1-1];
+		led_out(reg);
+	}
+	return 0;
+}
+
+/*
+ *  DIPSW設定コマンド関数
+ */
+static int_t dip_func(int argc, char **argv)
+{
+	int_t   arg1=0, arg2=0, i;
+
+	if(argc > 1)
+		arg1 = a2i(argv[1]);
+	if(argc > 2)
+		arg2 = a2i(argv[2]);
+	if(arg1 >= 1 && arg1 <= 8){
+		if(arg2 != 0)
+			dipsw_value |= (0x1<<(arg1-1));
+		else
+			dipsw_value &= ~(0x1<<(arg1-1));
+	}
+	printf("dipsw\n1   2   3   4   5   6   7   8\n");
+	for(i = 0 ; i < 8 ; i++){
+		if(dipsw_value & (1<<i))
+			printf("ON  ");
+		else
+			printf("OFF ");
+	}
+	printf("\n");
+	return 0;
+}
+
+/*
+ *  カップラーメンタイマ補助コマンド関数
+ */
+static int_t cup_func(int argc, char **argv)
+{
+	if(argc > 1)
+		cup_command = *argv[1];
+	return 0;
+}
+
+/*
+ * CUPラーメンコマンド
+ */
+int8_t
+get_cup_command(void)
+{
+	uint8_t cmd = cup_command;
+	cup_command = 0;
+	return cmd;
+}
+
+
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/OBJ/STM32F767NUCLEO144_GCC/USBO/hid_appli.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/OBJ/STM32F767NUCLEO144_GCC/USBO/hid_appli.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/OBJ/STM32F767NUCLEO144_GCC/USBO/hid_appli.h	(revision 457)
@@ -0,0 +1,80 @@
+/*
+ *  TOPPERS/ASP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Advanced Standard Profile Kernel
+ * 
+ *  Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
+ *                              Toyohashi Univ. of Technology, JAPAN
+ *  Copyright (C) 2004-2012 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  $Id$
+ */
+
+/*
+ *	USB HOST HIDアプリのヘッダファイル
+ */
+#include "tusb_types.h"
+
+#ifndef TOPPERS_MACRO_ONLY
+
+typedef struct
+{
+	uint8_t              button_left:1;
+	uint8_t              button_right:1;
+	uint8_t              button_middle:1;
+	int8_t               x;
+	int8_t               y;
+	int8_t               z;
+} MOUSE_Info_t;
+
+typedef struct
+{
+	uint8_t lctrl:1;
+	uint8_t lshift:1;
+	uint8_t lalt:1;
+	uint8_t lgui:1;
+	uint8_t rctrl:1;
+	uint8_t rshift:1;
+	uint8_t ralt:1;
+	uint8_t rgui:1;
+	uint8_t keys[6];
+} KEYBOARD_Info_t;
+
+TUSBH_ERCODE HidMouseInit(void *phandle);
+TUSBH_ERCODE HidMouseInfo(void *phandle, MOUSE_Info_t *p, uint8_t *buffer, uint16_t length);
+
+TUSBH_ERCODE HidKeyboardInit(void *phandle);
+TUSBH_ERCODE HidGetKeyboardInfo(void *phandle, KEYBOARD_Info_t *pinfo, uint8_t *buffer, uint16_t length);
+uint8_t HidGetASCIICode(KEYBOARD_Info_t *info);
+
+#endif /* TOPPERS_MACRO_ONLY */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/OBJ/STM32F767NUCLEO144_GCC/USBO/hid_keyboard.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/OBJ/STM32F767NUCLEO144_GCC/USBO/hid_keyboard.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/OBJ/STM32F767NUCLEO144_GCC/USBO/hid_keyboard.c	(revision 457)
@@ -0,0 +1,175 @@
+/*
+ *  TOPPERS/ASP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Advanced Standard Profile Kernel
+ * 
+ *  Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
+ *                              Toyohashi Univ. of Technology, JAPAN
+ *  Copyright (C) 2004-2012 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  $Id$
+ */
+/* Copyright (c) 2010-2011 mbed.org, MIT License
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of this software
+ * and associated documentation files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all copies or
+ * substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+ * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/* 
+ *  USB HOST KEYBOARDコード生成
+ */
+
+#include <kernel.h>
+#include <t_syslog.h>
+#include <t_stdlib.h>
+#include <sil.h>
+#include "syssvc/serial.h"
+#include "syssvc/syslog.h"
+#include "device.h"
+#include "hid_appli.h"
+
+static const uint8_t keymap[4][60] = {
+	{
+		0,   0,   0,   0,   'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h',	/* 000 - 011 */
+		'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't',	/* 012 - 023 */
+		'u', 'v', 'w', 'x', 'y', 'z', '1', '2', '3', '4', '5', '6',	/* 024 - 035 */
+		'7', '8', '9', '0', 10,  27,  8,   9,   ' ', '-', '=', '[',	/* 036 - 047 */
+		']', '\\','#', ';', '\'', 0,  ',', '.', '/', 0,   0,   0	/* 048 - 059 */
+    },
+
+    /* CTRL MODIFIER */
+	{
+		0,   0,   0,   0,   1,   2,   3,   4,   5,   6,   7,   8,	/* 000 - 011 */
+		9,   10,  11,  12,  13,  14,  15,  16,  17,  18,  18,  19,	/* 012 - 023 */
+		20,  21,  22,  23,  24,  25,  0,   0,   0,   0,   0,   0,	/* 024 - 035 */
+        0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,	/* 036 - 047 */
+		0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0	/* 048 - 059 */
+	},
+
+	/* SHIFT MODIFIER */
+	{
+		0,   0,   0,   0,   'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H',	/* 000 - 011 */
+		'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T',	/* 012 - 023 */
+		'U', 'V', 'W', 'X', 'Y', 'Z', '!', '@', '#', '$', '%', '^',	/* 024 - 035 */
+		'&', '*', '(', ')', 0,   0,   0,   0,   0,   0,   '+', '{',	/* 036 - 047 */
+		'}', '|', '~', ':', '"', 0,   '<', '>', '?', 0,   0,   0	/* 048 - 059 */
+	},
+
+	/* ALT MODIFIER */
+	{
+		0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,	/* 000 - 011 */
+		0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,	/* 012 - 023 */
+		0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,	/* 024 - 035 */
+ 		0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,	/* 036 - 047 */
+		0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0	/* 048 - 059 */
+	}
+};
+
+/*
+ *  HID KEYBOARD初期化
+ *  parameter1:  phandle  HIDハンドラ
+ *  return       TUSBH_ERCODE
+ */
+TUSBH_ERCODE
+HidKeyboardInit(void *phandle)
+{
+	syslog_0(LOG_NOTICE, "## USBH_HID_KeybdInit ##");
+	return TUSBH_E_OK;
+}
+
+/*
+ *  HID KEYBOARD情報取得
+ *  parameter1:  phandle  HIDハンドラ
+ *  parameter2:  pinfo    KEYBOARD情報設定タイプへのポインタ
+ *  parameter3:  buffer   USB HOSTからのデータ
+ *  parameter4:  length   USB HOSTデータ長
+ *  return       TUSBH_ERCODE
+ */
+TUSBH_ERCODE
+HidGetKeyboardInfo(void *phandle, KEYBOARD_Info_t *pinfo, uint8_t *buffer, uint16_t length)
+{
+	uint8_t i;
+
+	if(length > 0){
+		pinfo->lctrl = (buffer[0] >> 0) & 1;
+		pinfo->lshift = (buffer[0] >> 1) & 1;
+		pinfo->lalt = (buffer[0] >> 2) & 1;
+		pinfo->lgui = (buffer[0] >> 3) & 1;
+		pinfo->rctrl = (buffer[0] >> 4) & 1;
+		pinfo->rshift = (buffer[0] >> 5) & 1;
+		pinfo->ralt = (buffer[0] >> 6) & 1;
+		pinfo->rgui = (buffer[0] >> 7) & 1;
+
+		for(i = 0 ; i < sizeof(pinfo->keys) ; i++)
+			pinfo->keys[i]=(uint32_t)buffer[i+2];
+		return TUSBH_E_OK;
+	}
+	else
+		return TUSBH_E_TMOUT;
+}
+
+/*
+ *  HID ASCII-CODE取得
+ *  parameter1:  phandle  HIDハンドラ
+ *  parameter2:  pinfo    KEYBOARD情報設定タイプへのポインタ
+ *  return       ASCII CODE
+ */
+uint8_t
+HidGetASCIICode(KEYBOARD_Info_t *pinfo)
+{
+	uint8_t   index = 0;
+
+	if(pinfo->lshift == 1 || pinfo->rshift == 1)
+		index = 2;
+	else if(pinfo->lctrl == 1 || pinfo->rctrl == 1)
+		index = 1;
+	else if(pinfo->lalt == 1 || pinfo->ralt == 1)
+		index = 3;
+	if(pinfo->keys[0] < 60)
+		return keymap[index][pinfo->keys[0]];
+	else
+		return 0;
+}
+
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/OBJ/STM32F767NUCLEO144_GCC/USBO/hid_mouse.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/OBJ/STM32F767NUCLEO144_GCC/USBO/hid_mouse.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/OBJ/STM32F767NUCLEO144_GCC/USBO/hid_mouse.c	(revision 457)
@@ -0,0 +1,91 @@
+/*
+ *  TOPPERS/ASP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Advanced Standard Profile Kernel
+ * 
+ *  Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
+ *                              Toyohashi Univ. of Technology, JAPAN
+ *  Copyright (C) 2004-2012 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  $Id$
+ */
+
+/* 
+ *  USB HOST MOUSEデータ生成
+ */
+
+#include <kernel.h>
+#include <t_syslog.h>
+#include <t_stdlib.h>
+#include <sil.h>
+#include "syssvc/serial.h"
+#include "syssvc/syslog.h"
+#include "device.h"
+#include "hid_appli.h"
+
+/*
+ *  HID MOUSE初期化
+ *  parameter1:  phandle  HIDハンドラ
+ *  return       TUSBH_ERCODE
+ */
+TUSBH_ERCODE
+HidMouseInit(void *phandle)
+{
+	syslog_0(LOG_NOTICE, "## HidMouseInit ##");
+	return TUSBH_E_OK;
+}
+
+/*
+ *  HID MOUSE情報取得
+ *  parameter1:  phandle  HIDハンドラ
+ *  parameter2:  pinfo    MOUSE情報設定タイプへのポインタ
+ *  parameter3:  buffer   USB HOSTからのデータ
+ *  parameter4:  length   USB HOSTデータ長
+ *  return       TUSBH_ERCODE
+ */
+TUSBH_ERCODE
+HidMouseInfo(void *phandle, MOUSE_Info_t *pinfo, uint8_t *buffer, uint16_t length)
+{
+	if(length > 0){
+		pinfo->x = (int8_t )buffer[1];
+		pinfo->y = (int8_t )buffer[2];
+		pinfo->z = (int8_t )buffer[3];
+		pinfo->button_left=(uint8_t)(buffer[0] & 1);
+		pinfo->button_right=(uint8_t)((buffer[0] >> 1) & 1);
+		pinfo->button_middle=(uint8_t)((buffer[0] >> 2) & 1);
+		return TUSBH_E_OK;
+	}
+	else
+		return TUSBH_E_TMOUT;
+}
+
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/OBJ/STM32F767NUCLEO144_GCC/USBO/usbddesc.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/OBJ/STM32F767NUCLEO144_GCC/USBO/usbddesc.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/OBJ/STM32F767NUCLEO144_GCC/USBO/usbddesc.c	(revision 457)
@@ -0,0 +1,217 @@
+/*
+ *  TOPPERS/ASP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Advanced Standard Profile Kernel
+ * 
+ *  Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
+ *                              Toyohashi Univ. of Technology, JAPAN
+ *  Copyright (C) 2004-2012 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ *  Copyright (C) 2016-2017 by TOPPERS PROJECT Educational Working Group.
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  $Id$
+ */
+
+/*
+ *  USB DEVICE DESCRIPTORの設定
+ */
+
+#include "tusbd_base.h"
+
+#define MANUFACTURE_LENGTH            64
+#define PRODUCT_LENGTH                32
+#define CONFIGURATION_LENGTH          32
+#define INTERFACE_LENGTH              32
+
+/* Private define STM defintion ------------------------------------------------------*/
+#define USBD_VID                      0x0483
+#if USB_DEVICE_ID == 0
+#define USBD_PID                      0x5710
+#else
+#define USBD_PID                      0x5740
+#endif
+#define USBD_RELNO                    0x0200
+#define USBD_MANUFACTURER_STRING      "STMicroelectronics"
+#if USB_DEVICE_ID == 0
+#define USBD_PRODUCT_STRING           "HID Mouse"
+#define USBD_CONFIGURATION_HS_STRING  "HID Config"
+#define USBD_INTERFACE_HS_STRING      "HID Interface"
+#define USBD_CONFIGURATION_FS_STRING  "HID Config"
+#define USBD_INTERFACE_FS_STRING      "HID Interface"
+#else
+#define USBD_PRODUCT_STRING           "STM32 Virtual ComPort"
+#define USBD_CONFIGURATION_HS_STRING  "VCP Config"
+#define USBD_INTERFACE_HS_STRING      "VCP Interface"
+#define USBD_CONFIGURATION_FS_STRING  "VCP Config"
+#define USBD_INTERFACE_FS_STRING      "VCP Interface"
+#endif
+
+/* USB Standard Device Descriptor */
+uint8_t defaultDeviceDescriptor[] __attribute__ ((aligned(USB_DATA_ALIGN))) = {
+	0x12,						/* 0:bLength */
+	DEVICE_DESCRIPTOR,			/* 1:bDescriptorType */
+	0x00,                       /* 2:bcdUSB */
+	0x02,						/* 3:bcdUSB */
+	0x00,						/* 4:bDeviceClass */
+	0x00,						/* 5:bDeviceSubClass */
+	0x00,						/* 6:bDeviceProtocol */
+	USB_MAX_EP0_SIZE,			/* 7:bMaxPacketSize */
+	(USBD_VID & 0xFF),			/* 8:idVendor */
+	(USBD_VID >> 8),			/* 9:idVendor */
+	(USBD_PID & 0xFF),			/* 10:idVendor */
+	(USBD_PID >> 8),			/* 11:idVendor */
+	(USBD_RELNO & 0XFF),		/* 12:bcdDevice */
+	(USBD_RELNO >> 8),			/* 13:bcdDevice */
+	0x01,						/* 14:iManufacturer */
+	0x02,						/* 15:iProduct */
+	0x03,						/* 16:iSerialNumber */
+	TUSBD_MAX_NUM_CONFIGURATION  /* 17:bNumConfigurations */
+}; /* USB_DeviceDescriptor */
+
+/* USB Standard Device Descriptor */
+uint8_t defaultDeviceQualifierDescriptor[] __attribute__ ((aligned(USB_DATA_ALIGN))) = {
+	0x0A,
+	DEVICE_QUALIFIER_DESCRIPTOR,
+	0x00,
+	0x02,
+	0x00,
+	0x00,
+	0x00,
+	0x40,
+	0x01,
+	0x00
+};
+
+/* USB Standard Device Descriptor */
+uint8_t defaultLanguageIDDescriptor[] __attribute__ ((aligned(USB_DATA_ALIGN))) = {
+	0x04,
+	STRING_DESCRIPTOR,
+	0x09,
+	0x04
+};
+
+uint8_t defaultManufacturerString[MANUFACTURE_LENGTH*2] __attribute__ ((aligned(USB_DATA_ALIGN))) = {
+	MANUFACTURE_LENGTH*2,
+	STRING_DESCRIPTOR,
+	0x00
+};
+
+uint8_t defaultProductString[PRODUCT_LENGTH*2] __attribute__ ((aligned(USB_DATA_ALIGN))) = {
+	PRODUCT_LENGTH*2,
+	STRING_DESCRIPTOR,
+	0x00
+};
+
+uint8_t defaultSerialString[] __attribute__ ((aligned(USB_DATA_ALIGN))) = {
+	0x1A,
+	STRING_DESCRIPTOR,
+	'A', 0x00,
+	'B', 0x00,
+	'0', 0x00,
+	'0', 0x00,
+	'0', 0x00,
+	'0', 0x00,
+	'0', 0x00,
+	'0', 0x00,
+	'0', 0x00,
+	'0', 0x00,
+	'0', 0x00,
+	'1', 0x00
+};
+
+uint8_t defaultConfigurationString[CONFIGURATION_LENGTH*2] __attribute__ ((aligned(USB_DATA_ALIGN))) = {
+	CONFIGURATION_LENGTH*2,
+	STRING_DESCRIPTOR,
+	0x00
+};
+
+uint8_t defaultInterfaceString[INTERFACE_LENGTH*2] __attribute__ ((aligned(USB_DATA_ALIGN))) = {
+	INTERFACE_LENGTH*2,
+	STRING_DESCRIPTOR,
+	0x00
+};
+
+/* ascii to unicode 変換 */
+static uint8_t
+ascii2unicode(const char *src, uint16_t *dst, uint16_t len)
+{
+	uint8_t i, size;
+	uint8_t us, *p;
+
+	for(i = 0 ; i < len ; i++, src++, dst++){
+		us = *src;
+		if(us == 0)
+			break;
+		p = (uint8_t *)dst;
+		p[0] = us;
+		p[1] = 0;
+	}
+	size = i;
+
+	/* 0が見つかったら残りすべて0にする */
+	for( ; i < len ; i++, dst++){
+		*dst = 0;
+	}
+	return size;
+}
+
+static void
+MakeDescriptor(uint8_t speed)
+{
+	uint8_t len;
+
+	len = ascii2unicode(USBD_MANUFACTURER_STRING, (uint16_t *)&defaultManufacturerString[2], MANUFACTURE_LENGTH-2);
+	defaultManufacturerString[0] = len * 2 + 2;
+	syslog_2(LOG_NOTICE, "defaultManufacturerString len(%d) [%08x]", len, defaultManufacturerString);
+	len = ascii2unicode(USBD_PRODUCT_STRING, (uint16_t *)&defaultProductString[2], PRODUCT_LENGTH-2);
+	defaultProductString[0] = len * 2 + 2;
+	syslog_2(LOG_NOTICE, "defaultProductString len(%d) [%08x]", len, defaultProductString);
+	if(speed == USB_DEVICE_SPEED_HIGH)
+		len = ascii2unicode(USBD_CONFIGURATION_HS_STRING, (uint16_t *)&defaultConfigurationString[2], CONFIGURATION_LENGTH-2);
+	else
+		len = ascii2unicode(USBD_CONFIGURATION_FS_STRING, (uint16_t *)&defaultConfigurationString[2], CONFIGURATION_LENGTH-2);
+	defaultConfigurationString[0] = len * 2 + 2;
+	syslog_2(LOG_NOTICE, "defaultConfigurationString len(%d) [%08x]", len, defaultConfigurationString);
+	if(speed == USB_DEVICE_SPEED_HIGH)
+		len = ascii2unicode(USBD_INTERFACE_HS_STRING, (uint16_t *)&defaultInterfaceString[2], INTERFACE_LENGTH-2);
+	else
+		len = ascii2unicode(USBD_INTERFACE_FS_STRING, (uint16_t *)&defaultInterfaceString[2], INTERFACE_LENGTH-2);
+	defaultInterfaceString[0] = len * 2 + 2;
+	syslog_2(LOG_NOTICE, "defaultInterfaceString len(%d) [%08x]", len, defaultInterfaceString);
+}
+
+void
+MakeUsbDescriptor(TUSBD_Handle_t *pdev)
+{
+	pdev->makeDescriptor = MakeDescriptor;
+}
+
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/OBJ/STM32F767NUCLEO144_GCC/USBO/usbotest.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/OBJ/STM32F767NUCLEO144_GCC/USBO/usbotest.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/OBJ/STM32F767NUCLEO144_GCC/USBO/usbotest.c	(revision 457)
@@ -0,0 +1,509 @@
+/*
+ *  TOPPERS/ASP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Advanced Standard Profile Kernel
+ * 
+ *  Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
+ *                              Toyohashi Univ. of Technology, JAPAN
+ *  Copyright (C) 2004-2012 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  $Id$
+ */
+
+/* 
+ *  USB OTGテストの本体
+ */
+
+#include <kernel.h>
+#include <t_syslog.h>
+#include <t_stdlib.h>
+#include <sil.h>
+#include "syssvc/serial.h"
+#include "syssvc/syslog.h"
+#include "kernel_cfg.h"
+#include <target_syssvc.h>
+#include "device.h"
+#include "usb_otg.h"
+
+#include "usbotest.h"
+
+#include "tusbd_base.h"
+#if USB_OTG_MODE != USB_OTG_MODE_HOST
+#include "tusbd_device.h" 
+#endif
+
+/*
+ *  サービスコールのエラーのログ出力
+ */
+Inline void
+svc_perror(const char *file, int_t line, const char *expr, ER ercd)
+{
+	if (ercd < 0) {
+		t_perror(LOG_ERROR, file, line, expr, ercd);
+	}
+}
+
+#define	SVC_PERROR(expr)	svc_perror(__FILE__, __LINE__, #expr, (expr))
+
+#define CURSOR_STEP     5
+
+USBH_HandleTypeDef hUSBHost;
+USBD_HandleTypeDef USBD_Device;
+
+uint8_t ukey;
+uint8_t device_state[16];
+Line_Coding_t CDC_Info = {
+	115200,
+	0,
+	0,
+	8
+};
+uint8_t send_buffer[] = "help\r\nhelp\r\n";
+uint8_t receive_buffer[512] __attribute__ ((aligned (32)));
+uint8_t scratch[512];
+
+uint8_t HID_Buffer[4];
+
+static uint32_t heap_area[4*1024];
+
+uint32_t heap_param[2] = {
+	(uint32_t)heap_area,
+	(4*4*1024)
+};
+
+/*
+ *  SW1割込み
+ */
+void sw_int(void)
+{
+	ukey = 1;
+	syslog_0(LOG_NOTICE, "## sw_int() ##");
+}
+
+
+#if USB_OTG_MODE != USB_OTG_MODE_DEVICE
+/*
+ *  USB HOST USER CALLBACK関数
+ */
+static void USBH_UserProcess(USBH_HandleTypeDef *phost, TUSBH_Device_t *pdevice, uint8_t id)
+{
+	device_state[pdevice->type] = id;
+	if(pdevice->pClass != NULL){
+		syslog_3(LOG_NOTICE, "## CLASS[%s](%d)(%d) ##", pdevice->pClass->Name, pdevice->type, id);
+	}
+}
+
+/*
+ *  MSC SECTOR READ
+ */
+static void MSC_Read_Operations(void){
+	TUSBH_ERCODE  status = TUSBH_E_OK;
+	char pdrv = 0;
+
+	if(tusbhMscUnitIsReady (&hUSBHost, pdrv)){
+		syslog_0(LOG_NOTICE, "READY");
+	}
+	else{
+		syslog_0(LOG_NOTICE, "NOT READY");
+	}
+	status = tusbhMscRead(&hUSBHost, pdrv, 0, (uint8_t *)scratch, 1);
+	syslog_1(LOG_NOTICE, "## status(%d) ##", status);
+}
+
+/*
+ *  HID CALLBACK関数
+ */
+static void HID_Callback(TUSBH_Device_t *pdevice, uint8_t length, uint8_t *buffer)
+{
+	void *phandle = pdevice->pData;
+	uint8_t type = tusbhHidGetType(pdevice);
+	if(length == 0){
+		if(type == HID_KEYBOARD_TYPE)
+			HidKeyboardInit(phandle);
+		else if(type == HID_MOUSE_TYPE)
+			HidMouseInit(phandle);
+	}
+	else{
+#if 1	/* ROI DEBUG */
+		uint8_t *p = buffer;
+		syslog_5(LOG_NOTICE, "## HID_Callback len(%d) [%02x][%02x][%02x][%02x] ##", length, p[0], p[1], p[2], p[3]);
+#endif	/* ROI DEBUG */
+
+		if(type == HID_KEYBOARD_TYPE){
+			KEYBOARD_Info_t k_info;
+			if(HidGetKeyboardInfo(phandle, &k_info, buffer, length) == TUSBH_E_OK){
+				char c = HidGetASCIICode(&k_info);
+				if(c != 0){
+					syslog_1(LOG_NOTICE, "## KEY[%02x] ##", c);
+				}
+			}
+		}
+		else if(type == HID_MOUSE_TYPE){
+			MOUSE_Info_t m_info;
+			if(HidMouseInfo(phandle, &m_info, buffer, length) == TUSBH_E_OK){
+				syslog_3(LOG_NOTICE, "button left(%d) right(%d) middle(%d)", m_info.button_left, m_info.button_right, m_info.button_middle);
+				syslog_3(LOG_NOTICE, "position x (%d) y    (%d) z     (%d)", m_info.x, m_info.y, m_info.z);
+			}
+		}
+	}
+}
+
+/*
+ *  CDC CALLBACK関数
+ */
+static void CDC_Callback(TUSBH_Device_t *pdevice, uint8_t type)
+{
+	syslog_2(LOG_NOTICE, "## CDC_Callback[%08x](%d) ##", pdevice, type);
+}
+#endif
+
+#if USB_OTG_MODE != USB_OTG_MODE_HOST
+#if USB_DEVICE_ID == 0
+
+uint8_t HID_Buffer[4];
+
+/*
+ *  HID MOUSE DEVICE CLASS REQUEST
+ *  parameter1:  pbuf  データ設定バッファ
+ */
+static void GetPointerData(uint8_t *pbuf)
+{
+  static int8_t cnt = 0;
+  int8_t  x = 0, y = 0 ;
+  
+  if(cnt++ > 0)
+  {
+    x = CURSOR_STEP;
+  }
+  else
+  {
+    x = -CURSOR_STEP;
+  }
+  pbuf[0]  = 0;
+  pbuf[1] += x;
+  pbuf[2] += y;
+  pbuf[3]  = 0;
+}
+#else
+
+#define APP_TX_DATA_SIZE   2048
+
+#define FLG_CDC_SET_LINE_CODING         0x0001
+#define FLG_CDC_GET_LINE_CODING         0x0002
+#define FLG_CDC_SET_CONTROL_LINE_STATE  0x0004
+#define FLG_CDC_SEND_BREAK              0x0008
+#define FLG_CDC_RECEIVE_DATA           	0x0010
+#define FLG_CDC_SEND_FLUSH              0x0100
+
+static uint8_t    txBuffer[APP_TX_DATA_SIZE] __attribute__ ((aligned (32)));/* Received Data over UART (CDC interface) are stored in this buffer */
+static uint8_t    *pTransRxBuffer;
+static uint16_t   TransRxLength;
+static uint16_t   TransRxCount;
+
+
+Line_Coding_t LineCoding =
+{
+	115200, /* baud rate*/
+	0x00,   /* stop bits-1*/
+	0x00,   /* parity - none*/
+	0x08    /* nb. of bits 8*/
+};
+
+/*
+ *  CDC DEVICE CLASS REQUEST
+ *  parameter1:  hcdc   CDCハンドラ
+ *  parameter2:  cmd    要求コマンド
+ *  parameter3:  length データ長
+ */
+static void CdcDeviceRequest(TUSBD_CDC_Handle_t *hcdc, uint8_t cmd, uint32_t length)
+{
+	switch (cmd){
+	case CDC_SEND_ENCAPSULATED_COMMAND:
+		syslog_2(LOG_NOTICE, "## CdcDeviceRequest CDC_SEND_ENCAPSULATED_COMMAND hcdc[%08x] length(%d) ##", hcdc, length);
+		break;
+
+	case CDC_GET_ENCAPSULATED_RESPONSE:
+		syslog_2(LOG_NOTICE, "## CdcDeviceRequest CDC_GET_ENCAPSULATED_RESPONSE hcdc[%08x] length(%d) ##", hcdc, length);
+		break;
+
+	case CDC_SET_COMM_FEATURE:
+		syslog_2(LOG_NOTICE, "## CdcDeviceRequest CDC_SET_COMM_FEATURE hcdc[%08x] length(%d) ##", hcdc, length);
+		break;
+
+	case CDC_GET_COMM_FEATURE:
+		syslog_2(LOG_NOTICE, "## CDC_GET_COMM_FEATURE hcdc[%08x] length(%d) ##", hcdc, length);
+		break;
+
+	case CDC_CLEAR_COMM_FEATURE:
+		syslog_2(LOG_NOTICE, "## CDC_CLEAR_COMM_FEATURE hcdc[%08x] length(%d) ##", hcdc, length);
+		break;
+
+	case CDC_SET_LINE_CODING:
+		memcpy(&LineCoding, hcdc->cmddata, sizeof(Line_Coding_t));
+		iset_flg(USBCDC_FLG, FLG_CDC_SET_LINE_CODING);
+		break;
+
+	case CDC_GET_LINE_CODING:
+		memcpy(hcdc->cmddata, &LineCoding, sizeof(Line_Coding_t));
+		break;
+
+	case CDC_SET_CONTROL_LINE_STATE:
+		iset_flg(USBCDC_FLG, FLG_CDC_SET_CONTROL_LINE_STATE);
+		break;
+
+	case CDC_SEND_BREAK:
+		iset_flg(USBCDC_FLG, FLG_CDC_SEND_BREAK);
+		break;
+
+	case CDC_RECEIVED:
+		pTransRxBuffer = hcdc->rxdata;
+		TransRxLength = length;
+		TransRxCount  = 0;
+		iset_flg(USBCDC_FLG, FLG_CDC_RECEIVE_DATA);
+		break;
+
+	default:
+		syslog_3(LOG_NOTICE, "## CdcDeviceRequest cmd[%02x] hcdc[%08x] length(%d) ##", cmd, hcdc, length);
+		break;
+	}
+}
+#endif
+#endif
+
+/*
+ *  メインタスク
+ */
+void main_task(intptr_t exinf)
+{
+	USB_OTG_Init_t USB_Data_Init;
+	USB_OTG_Handle_t *husb;
+	ER_UINT	ercd;
+	TUSBH_ERCODE result;
+#if USB_OTG_MODE != USB_OTG_MODE_DEVICE
+	Line_Coding_t CDC_data;
+	uint32_t length;
+	uint32_t count = 0;
+#endif
+
+	SVC_PERROR(syslog_msk_log(LOG_UPTO(LOG_INFO), LOG_UPTO(LOG_EMERG)));
+	syslog(LOG_NOTICE, "Sample program starts (exinf = %d).", (int_t) exinf);
+
+	/*
+	 *  シリアルポートの初期化
+	 *
+	 *  システムログタスクと同じシリアルポートを使う場合など，シリアル
+	 *  ポートがオープン済みの場合にはここでE_OBJエラーになるが，支障は
+	 *  ない．
+	 */
+	ercd = serial_opn_por(TASK_PORTID);
+	if (ercd < 0 && MERCD(ercd) != E_OBJ) {
+		syslog(LOG_ERROR, "%s (%d) reported by `serial_opn_por'.",
+									itron_strerror(ercd), SERCD(ercd));
+	}
+	SVC_PERROR(serial_ctl_por(TASK_PORTID,
+							(IOCTL_CRLF | IOCTL_FCSND | IOCTL_FCRCV)));
+
+	/*
+	 *  USB OTG初期化
+	 */
+    USB_Data_Init.usb_otg_mode = USB_OTG_MODE;
+	USB_Data_Init.host_channels = 11;	/* HOST */
+	USB_Data_Init.dev_endpoints = 4;		/* DEV */
+	USB_Data_Init.use_dedicated_ep1 = 0;	/* DEV */
+	USB_Data_Init.dma_enable = 0;
+	USB_Data_Init.low_power_enable = 0;
+	USB_Data_Init.phy_itface = USB_PHY_EMBEDDED; 
+	USB_Data_Init.sof_enable = 0;
+	USB_Data_Init.speed = USB_SPEED_FULL;
+#if USB_OTG_MODE != USB_OTG_MODE_HOST
+	USB_Data_Init.vbus_sensing_enable = 1;	/* HOST/DEV */
+#else
+	USB_Data_Init.vbus_sensing_enable = 0;	/* HOST */
+#endif
+	USB_Data_Init.lpm_enable = 0;
+	USB_Data_Init.use_external_vbus = 0;
+	husb = usbo_init(USB1_PORTID, &USB_Data_Init);
+#if 1	/* ROI DEBUG */
+	if(husb == NULL){
+		syslog_0(LOG_NOTICE, "## usbo_init error STOP ##");
+		slp_tsk();
+	}
+#endif	/* ROI DEBUG */
+
+#if USB_OTG_MODE != USB_OTG_MODE_HOST
+	/*
+	 *  USB DEVICEミドルウェア初期化
+	 */
+	USBD_Device.pSysData = husb;
+	result = tusbdInit(&USBD_Device, USB_DEVICE_ID);
+	syslog_1(LOG_NOTICE, "## tusbdInit result(%d) ##", result);
+	MakeUsbDescriptor(&USBD_Device);
+
+#if USB_DEVICE_ID != 0
+	USBD_Device.pUsrData = CdcDeviceRequest;
+#endif
+
+	/*
+	 *  USB DEVICEスタート
+	 */
+	result = tusbdStart(&USBD_Device);
+	syslog_1(LOG_NOTICE, "## tusbdStart result(%d) ##", result);
+	act_tsk(USBD_TASK);
+#endif
+
+#if USB_OTG_MODE != USB_OTG_MODE_DEVICE
+	/*
+	 *  USB HOSTミドルウェア設定
+	 */
+	hUSBHost.pSysData = husb;
+	tusbhInit(&hUSBHost, USBH_UserProcess, 0);
+
+	tusbhSetHidCallBack(&hUSBHost, HID_Callback);
+	tusbhSetCdcCallBack(&hUSBHost, CDC_Callback);
+
+	/*
+	 *  USB HOSTスタート
+	 */
+	result = tusbhStart(&hUSBHost);
+	syslog_1(LOG_NOTICE, "## tusbhStart result(%d) ##", result);
+
+	/*
+	 *  USB HOSTアプリ処理
+	 */
+	while (1){
+		if(device_state[MSC_CLASS] == HOST_USER_CLASS_ACTIVE){
+			syslog_0(LOG_NOTICE, "Press User button to start");
+			syslog_0(LOG_NOTICE, "read and write operations");
+			/* KEY待ち */
+			ukey = 0;
+			while((ukey != 1) && (device_state[MSC_CLASS] != HOST_USER_DISCONNECTION)){
+				dly_tsk(1);
+			}
+			MSC_Read_Operations();
+			dly_tsk(400);
+		}
+
+		if(device_state[MSC_CLASS] == HOST_USER_DISCONNECTION){
+			device_state[MSC_CLASS] = 0;
+			syslog_0(LOG_ERROR, "MSC device disconnected!\n");
+		}
+
+		/*
+		 *  CDC SERIAL処理
+		 */
+		if(device_state[CDC_CLASS] == HOST_USER_CLASS_ACTIVE){
+			static bool_t cdc_init = true;
+			if(cdc_init){
+				syslog_1(LOG_NOTICE, "## device_state(%d) ##", device_state[CDC_CLASS]);
+				tusbhCdcSetLineCoding(&hUSBHost, 0, &CDC_Info);
+				dly_tsk(100);
+				tusbhCdcGetLineCoding(&hUSBHost, 0, &CDC_data);
+				result = tusbhCdcSend(&hUSBHost, 0, send_buffer, sizeof(send_buffer));
+				syslog_4(LOG_NOTICE, "CDC INFO baud(%d) format(%d) parity(%d) data(%d)", CDC_data.baudrate, CDC_data.stop_bits, CDC_data.parity, CDC_data.data_bits);
+				syslog_1(LOG_NOTICE, "## send result(%d) ##", result);
+				cdc_init = false;
+			}
+			length = 512;
+			result = tusbhCdcReceive(&hUSBHost, 0, receive_buffer, &length, 500);
+			syslog_3(LOG_NOTICE, "## tusbhCdcReceive status(%d) length(%d) buffer[%08x] ##", result, length, receive_buffer);
+			if(length > 0){
+				syslog_4(LOG_NOTICE, "## 00[%02x] 01[%02x] 02[%02x] 03[%02x] ##", receive_buffer[0], receive_buffer[1], receive_buffer[2], receive_buffer[3]);
+				syslog_4(LOG_NOTICE, "## 04[%02x] 05[%02x] 06[%02x] 07[%02x] ##", receive_buffer[4], receive_buffer[5], receive_buffer[6], receive_buffer[7]);
+				syslog_4(LOG_NOTICE, "## 08[%02x] 09[%02x] 10[%02x] 11[%02x] ##", receive_buffer[8], receive_buffer[9], receive_buffer[10], receive_buffer[11]);
+				syslog_4(LOG_NOTICE, "## 12[%02x] 13[%02x] 14[%02x] 15[%02x] ##", receive_buffer[12], receive_buffer[13], receive_buffer[14], receive_buffer[15]);
+			}
+			if(length != 0 && count == 0){
+				dly_tsk(1000);
+				cdc_init = true;
+			}
+			count++;
+		}
+#if 1	/* ROI DEBUG */
+		/*
+		 *  PRINTER処理
+		 */
+		if(device_state[PRT_CLASS] == HOST_USER_CLASS_ACTIVE){
+			static bool_t prt_init = true;
+			if(prt_init){
+				syslog_1(LOG_NOTICE, "## [PRT]device_state(%d) ##", device_state[PRT_CLASS]);
+				dly_tsk(1000);
+				syslog_0(LOG_NOTICE, "## SEND EOJ ##");
+				tusbhPrtEOJ(&hUSBHost, 0, 1, 2, 3);
+				tusbhPrtPortID(&hUSBHost, 0, receive_buffer);
+				syslog_1(LOG_NOTICE, "## PORTID(%d) ##", receive_buffer[0]);
+				prt_init = false;
+			}
+		}
+#endif	/* ROI DEBUG */
+
+		dly_tsk(500);
+	}
+#endif
+#if 1	/* ROI DEBUG */
+	syslog_0(LOG_NOTICE, "## STOP ##");
+	slp_tsk();
+#endif	/* ROI DEBUG */
+
+	syslog(LOG_NOTICE, "Sample program ends.");
+//	SVC_PERROR(ext_ker());
+}
+
+#if USB_OTG_MODE != USB_OTG_MODE_HOST
+void usbd_task(intptr_t exinf)
+{
+	FLGPTN crcflag;
+	ER ercd;
+
+	while (1){
+		ercd = twai_flg(USBCDC_FLG, 0xffff, TWF_ORW, &crcflag, 1000);
+#if USB_DEVICE_ID == 0
+		GetPointerData(HID_Buffer);
+		if(USBD_HID_SendReport(&USBD_Device, HID_Buffer, 4) == TUSBD_E_OK)
+			memset(&HID_Buffer, 0, sizeof(HID_Buffer));
+#else
+		if(ercd == E_OK){
+			if((crcflag & FLG_CDC_RECEIVE_DATA) != 0 && TransRxLength > TransRxCount){
+				pTransRxBuffer[TransRxLength] = 0;
+				syslog_2(LOG_NOTICE, "## revlen(%d)[%s] ##", TransRxLength, pTransRxBuffer);
+				memcpy(txBuffer, pTransRxBuffer, TransRxLength);
+				tusbdCdcStartTransmit(&USBD_Device, txBuffer, TransRxLength);
+				TransRxLength = 0;
+				tusbdCdcSetReceivePacket(&USBD_Device);
+			}
+		}
+#endif
+		syslog_1(LOG_NOTICE, "## dev_state(%d) ##", USBD_Device.dev_state);
+	}
+}
+#endif
+
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/OBJ/STM32F767NUCLEO144_GCC/USBO/usbotest.cfg
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/OBJ/STM32F767NUCLEO144_GCC/USBO/usbotest.cfg	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/OBJ/STM32F767NUCLEO144_GCC/USBO/usbotest.cfg	(revision 457)
@@ -0,0 +1,40 @@
+/*
+ *  $Id$
+ */
+
+/*
+ *  USBテストのコンフィギュレーションファイル
+ */
+INCLUDE("target_timer.cfg");
+INCLUDE("syssvc/syslog.cfg");
+INCLUDE("syssvc/banner.cfg");
+INCLUDE("syssvc/serial.cfg");
+INCLUDE("syssvc/logtask.cfg");
+INCLUDE("monitor/monitor.cfg");
+INCLUDE("pdic/stm32f7xx/device.cfg");
+INCLUDE("syssvc/tlsf.cfg");
+#if USB_OTG_MODE != USB_OTG_MODE_DEVICE
+INCLUDE("usb/host/tusbh.cfg");
+#endif
+
+#include "device.h"
+#include "usb_otg.h"
+#include "usbotest.h"
+
+ATT_INI({ TA_NULL, heap_param, heap_init });
+ATT_INI({ TA_NULL, sw_int, setup_sw_func });
+ATT_INI({ TA_NULL, 0, device_info_init });
+
+CRE_FLG(USBCDC_FLG, {TA_CLR, 0});
+
+CRE_TSK(MAIN_TASK, { TA_ACT, 0, main_task, MAIN_PRIORITY, STACK_SIZE, NULL });
+#if USB_OTG_MODE != USB_OTG_MODE_HOST
+CRE_TSK(USBD_TASK, { TA_NULL, 0, usbd_task, USBD_PROCESS_PRIO, USBD_PROCESS_STACK_SIZE, NULL });
+#endif
+
+ATT_ISR({TA_NULL, USB1_PORTID, INTNO_USBFS, usb_otg_isr, 1 });
+CFG_INT(INTNO_USBFS, { TA_ENAINT | INTATR_USBFS, INTPRI_USBFS });
+
+ATT_ISR({TA_NULL, USB1_PORTID, INTNO_FSWKUP, usb_otg_wkup_isr, 1 });
+CFG_INT(INTNO_FSWKUP, { TA_ENAINT | INTATR_FSWKUP, INTPRI_FSWKUP });
+
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/OBJ/STM32F767NUCLEO144_GCC/USBO/usbotest.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/OBJ/STM32F767NUCLEO144_GCC/USBO/usbotest.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/OBJ/STM32F767NUCLEO144_GCC/USBO/usbotest.h	(revision 457)
@@ -0,0 +1,112 @@
+/*
+ *  TOPPERS/ASP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Advanced Standard Profile Kernel
+ *
+ *  Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
+ *                              Toyohashi Univ. of Technology, JAPAN
+ *  Copyright (C) 2004-2010 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ *
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ *
+ *  $Id$
+ */
+
+/*
+ *	USB OTGテストのヘッダファイル
+ */
+
+/*
+ *  ターゲット依存の定義
+ */
+#include "target_test.h"
+#include "usb_otg.h"
+#include "tusbh_hid.h"
+#include "tusbh_msc.h"
+#include "tusbh_serial.h"
+#include "hid_appli.h"
+
+/*
+ *  各タスクの優先度の定義
+ */
+
+#define MAIN_PRIORITY	10		/* メインタスクの優先度 */
+								/* HIGH_PRIORITYより高くすること */
+
+#define HIGH_PRIORITY	8		/* 並行実行されるタスクの優先度 */
+#define MID_PRIORITY	10
+#define LOW_PRIORITY	11
+#define USBD_PROCESS_PRIO    8
+
+/*
+ *  ターゲットに依存する可能性のある定数の定義
+ */
+
+#ifndef TASK_PORTID
+#define	TASK_PORTID		1			/* 文字入力するシリアルポートID */
+#endif /* TASK_PORTID */
+
+#ifndef STACK_SIZE
+#define	STACK_SIZE		4096		/* タスクのスタックサイズ */
+#endif /* STACK_SIZE */
+#define USBD_PROCESS_STACK_SIZE 1024
+
+#define INHNO_USBFS   IRQ_VECTOR_OTG_FS	/* 割込みハンドラ番号 */
+#define INTNO_USBFS   IRQ_VECTOR_OTG_FS	/* 割込み番号 */
+#define INTPRI_USBFS  -5			/* 割込み優先度 */
+#define INTATR_USBFS  0				/* 割込み属性 */
+
+#define INHNO_FSWKUP  IRQ_VECTOR_OTG_FS_WKUP	/* 割込みハンドラ番号 */
+#define INTNO_FSWKUP  IRQ_VECTOR_OTG_FS_WKUP	/* 割込み番号 */
+#define INTPRI_FSWKUP -10			/* 割込み優先度 */
+#define INTATR_FSWKUP 0				/* 割込み属性 */
+
+#define NUM_USBH_EVT1   64
+#define NUM_USBH_EVT2   16
+
+/*
+ *  関数のプロトタイプ宣言
+ */
+#ifndef TOPPERS_MACRO_ONLY
+
+/*
+ *  ヒープ領域の設定
+ */
+extern uint32_t heap_param[2];
+
+extern void	main_task(intptr_t exinf);
+extern void usbd_task(intptr_t exinf);
+
+extern void sw_int(void);
+extern void device_info_init(intptr_t exinf);
+extern void heap_init(intptr_t exinf);
+
+#endif /* TOPPERS_MACRO_ONLY */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/OBJ/STM32F767NUCLEO144_GCC/i2cshield/Makefile
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/OBJ/STM32F767NUCLEO144_GCC/i2cshield/Makefile	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/OBJ/STM32F767NUCLEO144_GCC/i2cshield/Makefile	(revision 457)
@@ -0,0 +1,599 @@
+#
+#  TOPPERS/ASP Kernel
+#      Toyohashi Open Platform for Embedded Real-Time Systems/
+#      Advanced Standard Profile Kernel
+# 
+#  Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
+#                              Toyohashi Univ. of Technology, JAPAN
+#  Copyright (C) 2006-2014 by Embedded and Real-Time Systems Laboratory
+#              Graduate School of Information Science, Nagoya Univ., JAPAN
+# 
+#  ä¸è¨èä½æ¨©è
+ã¯ï¼ä»¥ä¸ã®(1)ï½(4)ã®æ¡ä»¶ãæºããå ´åã«éãï¼æ¬ã½ããã¦ã§
+#  ã¢ï¼æ¬ã½ããã¦ã§ã¢ãæ¹å¤ãããã®ãå«ãï¼ä»¥ä¸åãï¼ãä½¿ç¨ã»è¤è£½ã»æ¹
+#  å¤ã»åé
+å¸ï¼ä»¥ä¸ï¼å©ç¨ã¨å¼ã¶ï¼ãããã¨ãç¡åã§è¨±è«¾ããï¼
+#  (1) æ¬ã½ããã¦ã§ã¢ãã½ã¼ã¹ã³ã¼ãã®å½¢ã§å©ç¨ããå ´åã«ã¯ï¼ä¸è¨ã®èä½
+#      æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨ã®ç¡ä¿è¨¼è¦å®ãï¼ãã®ã¾ã¾ã®å½¢ã§ã½ã¼
+#      ã¹ã³ã¼ãä¸­ã«å«ã¾ãã¦ãããã¨ï¼
+#  (2) æ¬ã½ããã¦ã§ã¢ãï¼ã©ã¤ãã©ãªå½¢å¼ãªã©ï¼ä»ã®ã½ããã¦ã§ã¢éçºã«ä½¿
+#      ç¨ã§ããå½¢ã§åé
+å¸ããå ´åã«ã¯ï¼åé
+å¸ã«ä¼´ããã­ã¥ã¡ã³ãï¼å©ç¨
+#      è
+ããã¥ã¢ã«ãªã©ï¼ã«ï¼ä¸è¨ã®èä½æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨
+#      ã®ç¡ä¿è¨¼è¦å®ãæ²è¼ãããã¨ï¼
+#  (3) æ¬ã½ããã¦ã§ã¢ãï¼æ©å¨ã«çµã¿è¾¼ããªã©ï¼ä»ã®ã½ããã¦ã§ã¢éçºã«ä½¿
+#      ç¨ã§ããªãå½¢ã§åé
+å¸ããå ´åã«ã¯ï¼æ¬¡ã®ããããã®æ¡ä»¶ãæºããã
+#      ã¨ï¼
+#    (a) åé
+å¸ã«ä¼´ããã­ã¥ã¡ã³ãï¼å©ç¨è
+ããã¥ã¢ã«ãªã©ï¼ã«ï¼ä¸è¨ã®è
+#        ä½æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨ã®ç¡ä¿è¨¼è¦å®ãæ²è¼ãããã¨ï¼
+#    (b) åé
+å¸ã®å½¢æ
+ãï¼å¥ã«å®ããæ¹æ³ã«ãã£ã¦ï¼TOPPERSãã­ã¸ã§ã¯ãã«
+#        å ±åãããã¨ï¼
+#  (4) æ¬ã½ããã¦ã§ã¢ã®å©ç¨ã«ããç´æ¥çã¾ãã¯éæ¥çã«çãããããªãæ
+#      å®³ãããï¼ä¸è¨èä½æ¨©è
+ããã³TOPPERSãã­ã¸ã§ã¯ããå
+è²¬ãããã¨ï¼
+#      ã¾ãï¼æ¬ã½ããã¦ã§ã¢ã®ã¦ã¼ã¶ã¾ãã¯ã¨ã³ãã¦ã¼ã¶ããã®ãããªãç
+#      ç±ã«åºã¥ãè«æ±ãããï¼ä¸è¨èä½æ¨©è
+ããã³TOPPERSãã­ã¸ã§ã¯ãã
+#      å
+è²¬ãããã¨ï¼
+# 
+#  æ¬ã½ããã¦ã§ã¢ã¯ï¼ç¡ä¿è¨¼ã§æä¾ããã¦ãããã®ã§ããï¼ä¸è¨èä½æ¨©è
+ã
+#  ãã³TOPPERSãã­ã¸ã§ã¯ãã¯ï¼æ¬ã½ããã¦ã§ã¢ã«é¢ãã¦ï¼ç¹å®ã®ä½¿ç¨ç®ç
+#  ã«å¯¾ããé©åæ§ãå«ãã¦ï¼ãããªãä¿è¨¼ãè¡ããªãï¼ã¾ãï¼æ¬ã½ããã¦ã§
+#  ã¢ã®å©ç¨ã«ããç´æ¥çã¾ãã¯éæ¥çã«çãããããªãæå®³ã«é¢ãã¦ãï¼ã
+#  ã®è²¬ä»»ãè² ããªãï¼
+# 
+#  $Id$
+# 
+
+#
+#  ã¿ã¼ã²ããã®æå®ï¼Makefile.targetã§ä¸æ¸ããããã®ãé²ãããï¼
+#
+all:
+
+#
+#  ã¿ã¼ã²ããç¥ç§°ã®å®ç¾©
+#
+TARGET = stm32f767nucleo144_gcc
+
+#
+#  ãã­ã°ã©ãã³ã°è¨èªã®å®ç¾©
+#
+SRCLANG = c
+ifeq ($(SRCLANG),c)
+  LIBS = -lc
+endif
+ifeq ($(SRCLANG),c++)
+  USE_CXX = true
+  CXXLIBS = -lstdc++ -lm -lc
+  CXXRTS = cxxrt.o newlibrt.o
+endif
+
+#
+#  ã½ã¼ã¹ãã¡ã¤ã«ã®ãã£ã¬ã¯ããªã®å®ç¾©
+#
+SRCDIR = ../../..
+
+#
+#  ãªãã¸ã§ã¯ããã¡ã¤ã«åã®æ¡å¼µå­ã®è¨­å®
+#
+OBJEXT = exe
+
+#
+#  å®è¡ç°å¢ã®å®ç¾©ï¼ã¿ã¼ã²ããä¾å­ã«ä¸æ¸ããããå ´åãããï¼
+#
+DBGENV := 
+
+#
+#  ã«ã¼ãã«ã©ã¤ãã©ãªï¼libkernel.aï¼ã®ãã£ã¬ã¯ããªå
+#  ï¼ã«ã¼ãã«ã©ã¤ãã©ãªãmakeå¯¾è±¡ã«ããæã¯ï¼ç©ºã«å®ç¾©ããï¼
+#
+KERNEL_LIB = ../libkernel
+
+#
+#  ã«ã¼ãã«ãé¢æ°åä½ã§ã³ã³ãã¤ã«ãããã©ããã®å®ç¾©
+#
+KERNEL_FUNCOBJS = 
+
+#
+#  ãã¬ã¼ã¹ã­ã°ãåå¾ãããã©ããã®å®ç¾©
+#
+ENABLE_TRACE = 
+
+#
+#  ã¦ã¼ãã£ãªãã£ãã­ã°ã©ã ã®åç§°
+#
+PERL = /usr/bin/perl
+CFG = $(SRCDIR)/cfg/cfg/cfg
+
+#
+#  ãªãã¸ã§ã¯ããã¡ã¤ã«åã®å®ç¾©
+#
+OBJNAME = asp
+ifdef OBJEXT
+  OBJFILE = $(OBJNAME).$(OBJEXT)
+  CFG1_OUT = cfg1_out.$(OBJEXT)
+else
+  OBJFILE = $(OBJNAME)
+  CFG1_OUT = cfg1_out
+endif
+
+#
+#  ã¿ã¼ã²ããä¾å­é¨ã®ãã£ã¬ã¯ããªã®å®ç¾©
+#
+TARGETDIR = $(SRCDIR)/target/$(TARGET)
+
+#
+#  ã¿ã¼ã²ããä¾å­ã®å®ç¾©ã®ã¤ã³ã¯ã«ã¼ã
+#
+include $(TARGETDIR)/Makefile.target
+
+#
+#  ã³ã³ãã£ã®ã¥ã¬ã¼ã¿é¢ä¿ã®å¤æ°ã®å®ç¾©
+#
+CFG_TABS := --api-table $(SRCDIR)/kernel/kernel_api.csv \
+			--cfg1-def-table $(SRCDIR)/kernel/kernel_def.csv $(CFG_TABS)
+
+CFG_ASMOBJS := $(CFG_ASMOBJS)
+CFG_COBJS := kernel_cfg.o $(CFG_COBJS)
+CFG_OBJS := $(CFG_ASMOBJS) $(CFG_COBJS)
+CFG2_OUT_SRCS := kernel_cfg.h kernel_cfg.c $(CFG2_OUT_SRCS)
+
+#
+#  å
+±éã³ã³ãã¤ã«ãªãã·ã§ã³ã®å®ç¾©
+#
+COPTS := $(COPTS) -g 
+ifndef OMIT_WARNING_ALL
+  COPTS := $(COPTS) -Wall
+endif
+ifndef OMIT_OPTIMIZATION
+  COPTS := $(COPTS) -O2
+endif
+CDEFS := $(CDEFS) 
+INCLUDES := -I. -I$(SRCDIR)/include -I$(SRCDIR)/arch -I$(SRCDIR) $(INCLUDES)
+LDFLAGS := $(LDFLAGS) 
+CFG1_OUT_LDFLAGS := $(CFG1_OUT_LDFLAGS) 
+LIBS := $(LIBS) $(CXXLIBS)
+CFLAGS = $(COPTS) $(CDEFS) $(INCLUDES)
+
+#
+#  ã¢ããªã±ã¼ã·ã§ã³ãã­ã°ã©ã ã«é¢ããå®ç¾©
+#
+APPLNAME = i2ctest
+APPLDIR = 
+APPL_CFG = $(APPLNAME).cfg
+
+APPL_DIR = $(APPLDIR) $(SRCDIR)/library
+APPL_ASMOBJS =
+ifdef USE_CXX
+  APPL_CXXOBJS = $(APPLNAME).o 
+  APPL_COBJS = command.o 
+else
+  APPL_COBJS = $(APPLNAME).o command.o
+endif
+APPL_COBJS := $(APPL_COBJS) log_output.o vasyslog.o t_perror.o strerror.o
+APPL_CFLAGS =
+APPL_LIBS =
+ifdef APPLDIR
+  INCLUDES := $(INCLUDES) $(foreach dir,$(APPLDIR),-I$(dir))
+endif
+
+#
+#  ããã«ã¦ã§ã¢ Makefile ã®ã¤ã³ã¯ã«ã¼ã
+#
+include $(SRCDIR)/monitor/Makefile.config
+
+#
+#  GDIC Makefile ã®ã¤ã³ã¯ã«ã¼ã
+#
+include $(SRCDIR)/gdic/aqm0802_st7032/Makefile.config
+
+#
+#  ã·ã¹ãã ãµã¼ãã¹ã«é¢ããå®ç¾©
+#
+SYSSVC_DIR := $(SYSSVC_DIR) $(SRCDIR)/syssvc $(SRCDIR)/library $(SRCDIR)/pdic/stm32f7xx
+SYSSVC_ASMOBJS := $(SYSSVC_ASMOBJS)
+SYSSVC_COBJS := $(SYSSVC_COBJS) banner.o syslog.o serial.o logtask.o armv7m.o \
+				 device.o i2c.o clock.o $(CXXRTS)
+SYSSVC_CFLAGS := $(SYSSVC_CFLAGS)
+SYSSVC_LIBS := $(SYSSVC_LIBS)
+INCLUDES := $(INCLUDES) -I$(SRCDIR)/pdic/stm32f7xx
+
+#
+#  ã«ã¼ãã«ã«é¢ããå®ç¾©
+#
+#  KERNEL_ASMOBJS: ã«ã¼ãã«ã©ã¤ãã©ãªã«å«ããï¼ã½ã¼ã¹ãã¢ã»ã³ããªè¨èªã®
+#				   ãªãã¸ã§ã¯ããã¡ã¤ã«ï¼
+#  KERNEL_COBJS: ã«ã¼ãã«ã®ã©ã¤ãã©ãªã«å«ããï¼ã½ã¼ã¹ãCè¨èªã§ï¼ã½ã¼ã¹
+#				 ãã¡ã¤ã«ã¨1å¯¾1ã«å¯¾å¿ãããªãã¸ã§ã¯ããã¡ã¤ã«ï¼
+#  KERNEL_LCSRCS: ã«ã¼ãã«ã®ã©ã¤ãã©ãªã«å«ããCè¨èªã®ã½ã¼ã¹ãã¡ã¤ã«ã§ï¼
+#				  1ã¤ã®ã½ã¼ã¹ãã¡ã¤ã«ããè¤æ°ã®ãªãã¸ã§ã¯ããã¡ã¤ã«ãç
+#				  æãããã®ï¼
+#  KERNEL_LCOBJS: ä¸ã®ã½ã¼ã¹ãã¡ã¤ã«ããçæããããªãã¸ã§ã¯ããã¡ã¤ã«ï¼
+#  KERNEL_AUX_COBJS: ã­ã¼ãã¢ã¸ã¥ã¼ã«ã«å«ããªããï¼ã«ã¼ãã«ã®ã½ã¼ã¹ãã¡
+#					 ã¤ã«ã¨åããªãã·ã§ã³ãé©ç¨ãã¦ã³ã³ãã¤ã«ãã¹ãï¼ã½ã¼
+#					 ã¹ãCè¨èªã®ãªãã¸ã§ã¯ããã¡ã¤ã«ï¼
+#
+KERNEL_DIR := $(KERNEL_DIR) $(SRCDIR)/kernel
+KERNEL_ASMOBJS := $(KERNEL_ASMOBJS)
+KERNEL_COBJS := $(KERNEL_COBJS)
+KERNEL_CFLAGS := $(KERNEL_CFLAGS) -I$(SRCDIR)/kernel
+ifdef OMIT_MAKEOFFSET
+  OFFSET_H =
+else
+  OFFSET_H = offset.h
+ifndef OFFSET_TF
+  KERNEL_AUX_COBJS := $(KERNEL_AUX_COBJS) makeoffset.o
+endif
+endif
+
+#
+#  ã¿ã¼ã²ãããã¡ã¤ã«ï¼è¤æ°ãåæã«é¸æãã¦ã¯ãªããªãï¼
+#
+#all: $(OBJFILE)
+all: $(OBJNAME).bin
+#all: $(OBJNAME).srec
+
+##### ä»¥ä¸ã¯ç·¨éããªããã¨ #####
+
+#
+#  ç°å¢ã«ä¾å­ããã³ã³ãã¤ã«ãªãã·ã§ã³ã®å®ç¾©
+#
+ifdef DBGENV
+  CDEFS := $(CDEFS) -D$(DBGENV)
+endif
+
+#
+#  ã«ã¼ãã«ã®ãã¡ã¤ã«æ§æã®å®ç¾©
+#
+include $(SRCDIR)/kernel/Makefile.kernel
+ifdef KERNEL_FUNCOBJS
+  KERNEL_LCSRCS := $(KERNEL_FCSRCS)
+  KERNEL_LCOBJS := $(foreach file,$(KERNEL_FCSRCS),$($(file:.c=)))
+else
+  KERNEL_CFLAGS := -DALLFUNC $(KERNEL_CFLAGS)
+  KERNEL_COBJS := $(KERNEL_COBJS) \
+					$(foreach file,$(KERNEL_FCSRCS),$(file:.c=.o))
+endif
+
+#
+#  ã½ã¼ã¹ãã¡ã¤ã«ã®ãããã£ã¬ã¯ããªã«é¢ããå®ç¾©
+#
+vpath %.c $(KERNEL_DIR) $(SYSSVC_DIR) $(APPL_DIR)
+vpath %.S $(KERNEL_DIR) $(SYSSVC_DIR) $(APPL_DIR)
+vpath %.cfg $(APPL_DIR)
+
+#
+#  ã³ã³ãã¤ã«ã®ããã®å¤æ°ã®å®ç¾©
+#
+KERNEL_LIB_OBJS = $(KERNEL_ASMOBJS) $(KERNEL_COBJS) $(KERNEL_LCOBJS)
+SYSSVC_OBJS = $(SYSSVC_ASMOBJS) $(SYSSVC_COBJS)
+APPL_OBJS = $(APPL_ASMOBJS) $(APPL_COBJS) $(APPL_CXXOBJS)
+ALL_OBJS = $(START_OBJS) $(APPL_OBJS) $(SYSSVC_OBJS) $(CFG_OBJS) \
+											$(END_OBJS) $(HIDDEN_OBJS)
+ifdef KERNEL_LIB
+  ALL_LIBS = $(APPL_LIBS) $(SYSSVC_LIBS) -lkernel $(LIBS)
+  LIBS_DEP = $(filter %.a,$(ALL_LIBS)) $(KERNEL_LIB)/libkernel.a
+  LDFLAGS := $(LDFLAGS) -L$(KERNEL_LIB)
+  REALCLEAN_FILES := libkernel.a $(REALCLEAN_FILES)
+else
+  ALL_LIBS = $(APPL_LIBS) $(SYSSVC_LIBS) libkernel.a $(LIBS)
+  LIBS_DEP = $(filter %.a,$(ALL_LIBS))
+endif
+
+ifdef TEXT_START_ADDRESS
+  LDFLAGS := $(LDFLAGS) -Wl,-Ttext,$(TEXT_START_ADDRESS)
+  CFG1_OUT_LDFLAGS := $(CFG1_OUT_LDFLAGS) -Wl,-Ttext,$(TEXT_START_ADDRESS)
+endif
+ifdef DATA_START_ADDRESS
+  LDFLAGS := $(LDFLAGS) -Wl,-Tdata,$(DATA_START_ADDRESS)
+  CFG1_OUT_LDFLAGS := $(CFG1_OUT_LDFLAGS) -Wl,-Tdata,$(DATA_START_ADDRESS)
+endif
+ifdef LDSCRIPT
+  LDFLAGS := $(LDFLAGS) -T $(LDSCRIPT)
+  CFG1_OUT_LDFLAGS := $(CFG1_OUT_LDFLAGS) -T $(LDSCRIPT)
+endif
+
+#
+#  ãªãã»ãããã¡ã¤ã«ï¼offset.hï¼ã®çæè¦å
+#
+ifdef OFFSET_TF
+offset.h: $(APPL_CFG) kernel_cfg.timestamp
+	$(CFG) --pass 3 --kernel asp $(INCLUDES) \
+				--rom-image cfg1_out.srec --symbol-table cfg1_out.syms \
+				-T $(OFFSET_TF) $(CFG_TABS) $<
+else
+offset.h: makeoffset.s $(SRCDIR)/utils/genoffset
+	$(PERL) $(SRCDIR)/utils/genoffset makeoffset.s > offset.h
+endif
+
+#
+#  ã«ã¼ãã«ã®ã³ã³ãã£ã®ã¥ã¬ã¼ã·ã§ã³ãã¡ã¤ã«ã®çæ
+#
+cfg1_out.c: $(APPL_CFG)
+	$(CFG) --pass 1 --kernel asp $(INCLUDES) $(CFG_TABS) $<
+
+$(CFG2_OUT_SRCS): kernel_cfg.timestamp
+kernel_cfg.timestamp: $(APPL_CFG) \
+						$(START_OBJS) cfg1_out.o $(END_OBJS) $(HIDDEN_OBJS)
+	$(LINK) $(CFLAGS) $(CFG1_OUT_LDFLAGS) -o $(CFG1_OUT) \
+						$(START_OBJS) cfg1_out.o $(END_OBJS)
+	$(NM) -n $(CFG1_OUT) > cfg1_out.syms
+	$(OBJCOPY) -O srec -S $(CFG1_OUT) cfg1_out.srec
+	$(CFG) --pass 2 --kernel asp $(INCLUDES) \
+				-T $(TARGETDIR)/target.tf $(CFG_TABS) $<
+	touch -r kernel_cfg.c kernel_cfg.timestamp
+
+#
+#  ã«ã¼ãã«ã©ã¤ãã©ãªãã¡ã¤ã«ã®çæ
+#
+libkernel.a: $(OFFSET_H) $(KERNEL_LIB_OBJS)
+	rm -f libkernel.a
+	$(AR) -rcs libkernel.a $(KERNEL_LIB_OBJS)
+	$(RANLIB) libkernel.a
+
+#
+#  ç¹å¥ãªä¾å­é¢ä¿ã®å®ç¾©
+#
+banner.o: kernel_cfg.timestamp $(filter-out banner.o,$(ALL_OBJS)) $(LIBS_DEP)
+
+#
+#  å
+¨ä½ã®ãªã³ã¯
+#
+$(OBJFILE): $(APPL_CFG) kernel_cfg.timestamp $(ALL_OBJS) $(LIBS_DEP)
+	$(LINK) $(CFLAGS) $(LDFLAGS) -o $(OBJFILE) $(START_OBJS) \
+			$(APPL_OBJS) $(SYSSVC_OBJS) $(CFG_OBJS) $(ALL_LIBS) $(END_OBJS)
+	$(NM) -n $(OBJFILE) > $(OBJNAME).syms
+	$(OBJCOPY) -O srec -S $(OBJFILE) $(OBJNAME).srec
+	$(CFG) --pass 3 --kernel asp $(INCLUDES) \
+				--rom-image $(OBJNAME).srec --symbol-table $(OBJNAME).syms \
+				-T $(TARGETDIR)/target_check.tf $(CFG_TABS) $<
+
+#
+#  ãã¤ããªãã¡ã¤ã«ã®çæ
+#
+$(OBJNAME).bin: $(OBJFILE)
+	$(OBJCOPY) -O binary -S $(OBJFILE) $(OBJNAME).bin
+
+#
+#  Sã¬ã³ã¼ããã¡ã¤ã«ã®çæ
+#
+$(OBJNAME).srec: $(OBJFILE)
+	$(OBJCOPY) -O srec -S $(OBJFILE) $(OBJNAME).srec
+
+#
+#  ã³ã³ãã¤ã«çµæã®æ¶å»
+#
+.PHONY: clean
+clean:
+	rm -f \#* *~ *.o $(CLEAN_FILES)
+	rm -f $(OBJFILE) $(OBJNAME).syms $(OBJNAME).srec $(OBJNAME).bin
+	rm -f kernel_cfg.timestamp $(CFG2_OUT_SRCS)
+	rm -f cfg1_out.c $(CFG1_OUT) cfg1_out.syms cfg1_out.srec
+ifndef KERNEL_LIB
+	rm -f libkernel.a
+endif
+	rm -f makeoffset.s offset.h
+
+.PHONY: cleankernel
+cleankernel:
+	rm -rf $(KERNEL_LIB_OBJS)
+	rm -f makeoffset.s offset.h
+
+.PHONY: cleandep
+cleandep:
+	if ! [ -f Makefile.depend ]; then \
+		rm -f kernel_cfg.timestamp $(CFG2_OUT_SRCS); \
+		rm -f cfg1_out.c cfg1_out.o $(CFG1_OUT) cfg1_out.syms cfg1_out.srec; \
+		rm -f makeoffset.s offset.h; \
+	fi
+	rm -f Makefile.depend
+
+.PHONY: realclean
+realclean: cleandep clean
+	rm -f $(REALCLEAN_FILES)
+
+#
+#  ã³ã³ãã£ã®ã¥ã¬ã¼ã¿ãçæãããã¡ã¤ã«ã®ã³ã³ãã¤ã«ã«ã¼ã«ã¨ä¾å­é¢ä¿ä½æ
+#  ã«ã¼ã«ã®å®ç¾©
+#
+#  ã³ã³ãã£ã®ã¥ã¬ã¼ã¿ãçæãããã¡ã¤ã«ã¯ï¼ã¢ããªã±ã¼ã·ã§ã³ãã­ã°ã©ã ç¨ï¼
+#  ã·ã¹ãã ãµã¼ãã¹ç¨ï¼ã«ã¼ãã«ç¨ã®ãã¹ã¦ã®ãªãã·ã§ã³ãä»ãã¦ã³ã³ãã¤ã«
+#  ããï¼
+#
+ALL_CFG_COBJS = $(CFG_COBJS) cfg1_out.o
+ALL_CFG_ASMOBJS = $(CFG_ASMOBJS)
+CFG_CFLAGS = $(APPL_CFLAGS) $(SYSSVC_CFLAGS) $(KERNEL_CFLAGS)
+
+$(ALL_CFG_COBJS): %.o: %.c
+	$(CC) -c $(CFLAGS) $(CFG_CFLAGS) $<
+
+$(ALL_CFG_COBJS:.o=.s): %.s: %.c
+	$(CC) -S $(CFLAGS) $(CFG_CFLAGS) $<
+
+$(ALL_CFG_COBJS:.o=.d): %.d: %.c
+	@$(PERL) $(SRCDIR)/utils/makedep -C $(CC) $(MAKEDEP_OPTS) \
+		-O "$(CFLAGS) $(CFG_CFLAGS)" $< >> Makefile.depend
+
+$(ALL_CFG_ASMOBJS): %.o: %.S
+	$(CC) -c $(CFLAGS) $(CFG_CFLAGS) $<
+
+$(ALL_CFG_ASMOBJS:.o=.d): %.d: %.S
+	@$(PERL) $(SRCDIR)/utils/makedep -C $(CC) $(MAKEDEP_OPTS) \
+		-O "$(CFLAGS) $(CFG_CFLAGS)" $< >> Makefile.depend
+
+#
+#  ç¹æ®ãªä¾å­é¢ä¿ä½æã«ã¼ã«ã®å®ç¾©
+#
+cfg1_out.depend: $(APPL_CFG)
+	@$(CFG) -M cfg1_out.c $(INCLUDES) $< >> Makefile.depend
+
+makeoffset.d: makeoffset.c
+	@$(PERL) $(SRCDIR)/utils/makedep -C $(CC) $(MAKEDEP_OPTS) \
+		-T "makeoffset.s" -O "$(CFLAGS) $(KERNEL_CFLAGS)" $< >> Makefile.depend
+
+#
+#  ä¾å­é¢ä¿ãã¡ã¤ã«ã®çæ
+#
+.PHONY: gendepend
+gendepend:
+	@echo "Generating Makefile.depend."
+
+.PHONY: depend
+ifdef KERNEL_LIB
+depend: cleandep kernel_cfg.timestamp gendepend \
+		cfg1_out.depend cfg1_out.d \
+		$(ALL_OBJS:.o=.d)
+else
+depend: cleandep $(OFFSET_H) kernel_cfg.timestamp gendepend \
+		cfg1_out.depend cfg1_out.d \
+		$(KERNEL_AUX_COBJS:.o=.d) $(KERNEL_ASMOBJS:.o=.d) \
+		$(KERNEL_COBJS:.o=.d) $(KERNEL_LCSRCS:.c=.d) $(ALL_OBJS:.o=.d)
+endif
+
+#
+#  ä¾å­é¢ä¿ãã¡ã¤ã«ãã¤ã³ã¯ã«ã¼ã
+#
+-include Makefile.depend
+
+#
+#  éçºãã¼ã«ã®ã³ãã³ãåã®å®ç¾©
+#
+ifeq ($(TOOL),gcc)
+  #
+  #  GNUéçºç°å¢ç¨
+  #
+  ifdef GCC_TARGET
+    GCC_TARGET_PREFIX = $(GCC_TARGET)-
+  else
+    GCC_TARGET_PREFIX =
+  endif
+  CC = $(GCC_TARGET_PREFIX)gcc
+  CXX = $(GCC_TARGET_PREFIX)g++
+  AS = $(GCC_TARGET_PREFIX)as
+  LD = $(GCC_TARGET_PREFIX)ld
+  AR = $(GCC_TARGET_PREFIX)ar
+  NM = $(GCC_TARGET_PREFIX)nm
+  RANLIB = $(GCC_TARGET_PREFIX)ranlib
+  OBJCOPY = $(GCC_TARGET_PREFIX)objcopy
+  OBJDUMP = $(GCC_TARGET_PREFIX)objdump
+endif
+
+ifdef USE_CXX
+  LINK = $(CXX)
+else
+  LINK = $(CC)
+endif
+
+#
+#  ã³ã³ãã¤ã«ã«ã¼ã«ã®å®ç¾©
+#
+KERNEL_ALL_COBJS = $(KERNEL_COBJS) $(KERNEL_AUX_COBJS)
+
+$(KERNEL_ALL_COBJS): %.o: %.c
+	$(CC) -c $(CFLAGS) $(KERNEL_CFLAGS) $<
+
+$(KERNEL_ALL_COBJS:.o=.s): %.s: %.c
+	$(CC) -S $(CFLAGS) $(KERNEL_CFLAGS) $<
+
+$(KERNEL_LCOBJS): %.o:
+	$(CC) -DTOPPERS_$(*F) -o $@ -c $(CFLAGS) $(KERNEL_CFLAGS) $<
+
+$(KERNEL_LCOBJS:.o=.s): %.s:
+	$(CC) -DTOPPERS_$(*F) -o $@ -S $(CFLAGS) $(KERNEL_CFLAGS) $<
+
+$(KERNEL_ASMOBJS): %.o: %.S
+	$(CC) -c $(CFLAGS) $(KERNEL_CFLAGS) $<
+
+$(SYSSVC_COBJS): %.o: %.c
+	$(CC) -c $(CFLAGS) $(SYSSVC_CFLAGS) $<
+
+$(SYSSVC_COBJS:.o=.s): %.s: %.c
+	$(CC) -S $(CFLAGS) $(SYSSVC_CFLAGS) $<
+
+$(SYSSVC_ASMOBJS): %.o: %.S
+	$(CC) -c $(CFLAGS) $(SYSSVC_CFLAGS) $<
+
+$(APPL_COBJS): %.o: %.c
+	$(CC) -c $(CFLAGS) $(APPL_CFLAGS) $<
+
+$(APPL_COBJS:.o=.s): %.s: %.c
+	$(CC) -S $(CFLAGS) $(APPL_CFLAGS) $<
+
+$(APPL_CXXOBJS): %.o: %.cpp
+	$(CXX) -c $(CFLAGS) $(APPL_CFLAGS) $<
+
+$(APPL_CXXOBJS:.o=.s): %.s: %.cpp
+	$(CXX) -S $(CFLAGS) $(APPL_CFLAGS) $<
+
+$(APPL_ASMOBJS): %.o: %.S
+	$(CC) -c $(CFLAGS) $(APPL_CFLAGS) $<
+
+#
+#  ä¾å­é¢ä¿ä½æã«ã¼ã«ã®å®ç¾©
+#
+$(KERNEL_COBJS:.o=.d): %.d: %.c
+	@$(PERL) $(SRCDIR)/utils/makedep -C $(CC) $(MAKEDEP_OPTS) \
+		-O "$(CFLAGS) $(KERNEL_CFLAGS)" $< >> Makefile.depend
+
+$(KERNEL_LCSRCS:.c=.d): %.d: %.c
+	@$(PERL) $(SRCDIR)/utils/makedep -C $(CC) $(MAKEDEP_OPTS) -T "$($*)" \
+		-O "-DALLFUNC $(CFLAGS) $(KERNEL_CFLAGS)" $< >> Makefile.depend
+
+$(KERNEL_ASMOBJS:.o=.d): %.d: %.S
+	@$(PERL) $(SRCDIR)/utils/makedep -C $(CC) $(MAKEDEP_OPTS) \
+		-O "$(CFLAGS) $(KERNEL_CFLAGS)" $< >> Makefile.depend
+
+$(SYSSVC_COBJS:.o=.d): %.d: %.c
+	@$(PERL) $(SRCDIR)/utils/makedep -C $(CC) $(MAKEDEP_OPTS) \
+		-O "$(CFLAGS) $(SYSSVC_CFLAGS)" $< >> Makefile.depend
+
+$(SYSSVC_ASMOBJS:.o=.d): %.d: %.S
+	@$(PERL) $(SRCDIR)/utils/makedep -C $(CC) $(MAKEDEP_OPTS) \
+		-O "$(CFLAGS) $(SYSSVC_CFLAGS)" $< >> Makefile.depend
+
+$(APPL_COBJS:.o=.d): %.d: %.c
+	@$(PERL) $(SRCDIR)/utils/makedep -C $(CC) $(MAKEDEP_OPTS) \
+		-O "$(CFLAGS) $(APPL_CFLAGS)" $< >> Makefile.depend
+
+$(APPL_CXXOBJS:.o=.d): %.d: %.cpp
+	@$(PERL) $(SRCDIR)/utils/makedep -C $(CXX) $(MAKEDEP_OPTS) \
+		-O "$(CFLAGS) $(APPL_CFLAGS)" $< >> Makefile.depend
+
+$(APPL_ASMOBJS:.o=.d): %.d: %.S
+	@$(PERL) $(SRCDIR)/utils/makedep -C $(CC) $(MAKEDEP_OPTS) \
+		-O "$(CFLAGS) $(APPL_CFLAGS)" $< >> Makefile.depend
+
+#
+#  ããã©ã«ãã³ã³ãã¤ã«ã«ã¼ã«ãä¸æ¸ã
+#
+%.o: %.c
+	@echo "*** Default compile rules should not be used."
+	$(CC) -c $(CFLAGS) $<
+
+%.s: %.c
+	@echo "*** Default compile rules should not be used."
+	$(CC) -S $(CFLAGS) $<
+
+%.o: %.cpp
+	@echo "*** Default compile rules should not be used."
+	$(CXX) -c $(CFLAGS) $<
+
+%.s: %.cpp
+	@echo "*** Default compile rules should not be used."
+	$(CXX) -S $(CFLAGS) $<
+
+%.o: %.S
+	@echo "*** Default compile rules should not be used."
+	$(CC) -c $(CFLAGS) $<
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/OBJ/STM32F767NUCLEO144_GCC/i2cshield/command.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/OBJ/STM32F767NUCLEO144_GCC/i2cshield/command.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/OBJ/STM32F767NUCLEO144_GCC/i2cshield/command.c	(revision 457)
@@ -0,0 +1,141 @@
+#include <kernel.h>
+#include <t_syslog.h>
+#include <stdio.h>
+#include <t_stdlib.h>
+#include <stdlib.h>
+#include "syssvc/serial.h"
+#include "syssvc/syslog.h"
+#include "kernel_cfg.h"
+#include "monitor.h"
+#include "device.h"
+
+/*
+ *  デバイスコマンド番号
+ */
+#define NUM_DEVICE_CMD   3
+
+static int_t led_func(int argc, char **argv);
+static int_t dip_func(int argc, char **argv);
+static int_t cup_func(int argc, char **argv);
+
+/*
+ *  デバイスコマンドテーブル
+ */
+static const COMMAND_INFO device_command_info[NUM_DEVICE_CMD] = {
+	{"LED",		led_func},
+	{"DIP",		dip_func},
+	{"CUP",		cup_func}
+};
+
+static const char device_name[] = "DEVICE";
+static const char device_help[] =
+"  Device  LED (no) (on-1,off-0)  led   control\n"
+"          DIP (no) (on-1,off-0)  dipsw control\n"
+"          CUP command            cup   control\n";
+
+static const uint16_t led_pattern[4] = {
+	LED01, LED02, LED03, LED04
+};
+
+static COMMAND_LINK device_command_link = {
+	NULL,
+	NUM_DEVICE_CMD,
+	device_name,
+	NULL,
+	device_help,
+	&device_command_info[0]
+};
+
+static uint8_t cup_command;
+
+static int a2i(char *str)
+{
+	int num = 0;
+
+	while(*str >= '0' && *str <= '9'){
+		num = num * 10 + *str++ - '0';
+	}
+	return num;
+}
+
+/*
+ *  DEVICEコマンド設定関数
+ */
+void device_info_init(intptr_t exinf)
+{
+	setup_command(&device_command_link);
+}
+
+/*
+ *  LED設定コマンド関数
+ */
+static int_t led_func(int argc, char **argv)
+{
+	int_t    arg1=0, arg2;
+	uint16_t reg;
+
+	if(argc < 3)
+		return -1;
+	arg1 = a2i(argv[1]);
+	arg2 = a2i(argv[2]);
+	if(arg1 >= 1 && arg1 <= 4){
+		reg = led_in();
+		if(arg2 != 0)
+			reg |= led_pattern[arg1-1];
+		else
+			reg &= ~led_pattern[arg1-1];
+		led_out(reg);
+	}
+	return 0;
+}
+
+/*
+ *  DIPSW設定コマンド関数
+ */
+static int_t dip_func(int argc, char **argv)
+{
+	int_t   arg1=0, arg2=0, i;
+
+	if(argc > 1)
+		arg1 = a2i(argv[1]);
+	if(argc > 2)
+		arg2 = a2i(argv[2]);
+	if(arg1 >= 1 && arg1 <= 8){
+		if(arg2 != 0)
+			dipsw_value |= (0x1<<(arg1-1));
+		else
+			dipsw_value &= ~(0x1<<(arg1-1));
+	}
+	printf("dipsw\n1   2   3   4   5   6   7   8\n");
+	for(i = 0 ; i < 8 ; i++){
+		if(dipsw_value & (1<<i))
+			printf("ON  ");
+		else
+			printf("OFF ");
+	}
+	printf("\n");
+	return 0;
+}
+
+/*
+ *  カップラーメンタイマ補助コマンド関数
+ */
+static int_t cup_func(int argc, char **argv)
+{
+	if(argc > 1)
+		cup_command = *argv[1];
+	return 0;
+}
+
+/*
+ * CUPラーメンコマンド
+ */
+int8_t
+get_cup_command(void)
+{
+	uint8_t cmd = cup_command;
+	cup_command = 0;
+	return cmd;
+}
+
+
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/OBJ/STM32F767NUCLEO144_GCC/i2cshield/i2ctest.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/OBJ/STM32F767NUCLEO144_GCC/i2cshield/i2ctest.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/OBJ/STM32F767NUCLEO144_GCC/i2cshield/i2ctest.c	(revision 457)
@@ -0,0 +1,272 @@
+/*
+ *  TOPPERS/ASP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Advanced Standard Profile Kernel
+ * 
+ *  Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
+ *                              Toyohashi Univ. of Technology, JAPAN
+ *  Copyright (C) 2004-2012 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ *  Copyright (C) 2015-2017 by TOPPERS PROJECT Educational Working Group.
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  $Id$
+ */
+
+/* 
+ *  I2Cテストの本体
+ */
+
+#include <kernel.h>
+#include <t_syslog.h>
+#include <t_stdlib.h>
+#include <sil.h>
+#include <string.h>
+#include "syssvc/serial.h"
+#include "syssvc/syslog.h"
+#include "kernel_cfg.h"
+#include <target_syssvc.h>
+#include "device.h"
+#include "i2ctest.h"
+
+/*
+ *  サービスコールのエラーのログ出力
+ */
+Inline void
+svc_perror(const char *file, int_t line, const char *expr, ER ercd)
+{
+	if (ercd < 0) {
+		t_perror(LOG_ERROR, file, line, expr, ercd);
+	}
+}
+
+#define	SVC_PERROR(expr)	svc_perror(__FILE__, __LINE__, #expr, (expr))
+
+
+#define RXBUFFERSIZE       8
+
+#define LCD_ADDR           (0x3E<<1)
+#define EEPROM_ADDR        (0x50<<1)
+#define ADT7410_ADDR       (0x48<<1)
+
+#define ADT7410_TEMP_H	0x00
+#define ADT7410_TEMP_L	0x01
+#define ADT7410_STATUS	0x02
+
+#define LCD_locate(h, x, y) aqm0802_set_command((h), (0x80 + ((y) << 6) + (x)))
+#define LCD_puts(h, b)      aqm0802_set_data((h), (b), strlen((const char *)(b)))
+
+
+/* Buffer used for reception */
+uint8_t aRxBuffer[RXBUFFERSIZE];
+uint8_t aRxBuffer2[RXBUFFERSIZE];
+
+uint8_t lcd_buf[2][12];
+
+/*
+ *  SW1割込み
+ */
+void sw_int(void)
+{
+	syslog_0(LOG_NOTICE, "## sw_int() ##");
+}
+
+/*
+ *  I2C SEND CALLBACK FUNCTION
+ */
+static void
+I2C_TxCpltCallback(I2C_Handle_t *hi2c)
+{
+	syslog_1(LOG_INFO, "## I2C_TxCpltCallback(%08x) ##", hi2c);
+}
+
+/*
+ *  I2C RECEIVE CALLBACK
+ */
+static void
+I2C_RxCpltCallback(I2C_Handle_t *hi2c)
+{
+	syslog_1(LOG_INFO, "## I2C_RxCpltCallback(%08x) ##", hi2c);
+}
+
+/*
+ *  I2C ERROR CALLBACK
+ */
+static void
+I2C_ErrorCallback(I2C_Handle_t *hi2c)
+{
+	syslog_1(LOG_ERROR, "## I2C_ErrorCallback(%08x) ##", hi2c);
+}
+
+static void
+set_value(uint8_t *buf, int value)
+{
+    buf[1] = (value % 10) + '0';
+    buf[0] = (value / 10) + '0';
+}
+
+static void
+set_time(uint8_t *buf, long time)
+{
+	struct tm2 timedate;
+
+	rtc_get_time(&timedate);
+    set_value(&buf[6], timedate.tm_sec);
+    buf[5] = ':';
+    set_value(&buf[3], timedate.tm_min);
+    buf[2] = ':';
+    set_value(&buf[0], timedate.tm_hour);
+}
+
+/*
+ *  メインタスク
+ */
+void main_task(intptr_t exinf)
+{
+	I2C_Init_t i2c_initd;
+	I2C_Handle_t *hi2c;
+	CLCD_Handler_t  CLcdHandle;
+	ER_UINT	ercd;
+	SYSTIM  tim;
+	uint32_t temp;
+	uint32_t count = 0;
+
+	SVC_PERROR(syslog_msk_log(LOG_UPTO(LOG_INFO), LOG_UPTO(LOG_EMERG)));
+	syslog(LOG_NOTICE, "Sample program starts (exinf = %d).", (int_t) exinf);
+
+	/*
+	 *  シリアルポートの初期化
+	 *
+	 *  システムログタスクと同じシリアルポートを使う場合など，シリアル
+	 *  ポートがオープン済みの場合にはここでE_OBJエラーになるが，支障は
+	 *  ない．
+	 */
+	ercd = serial_opn_por(TASK_PORTID);
+	if (ercd < 0 && MERCD(ercd) != E_OBJ) {
+		syslog(LOG_ERROR, "%s (%d) reported by `serial_opn_por'.",
+									itron_strerror(ercd), SERCD(ercd));
+	}
+	SVC_PERROR(serial_ctl_por(TASK_PORTID,
+							(IOCTL_CRLF | IOCTL_FCSND | IOCTL_FCRCV)));
+
+	syslog_0(LOG_NOTICE, "I2C SEND/RECV START");
+
+    i2c_initd.Timing          = 0x00D00E28;
+	i2c_initd.AddressingMode  = I2C_ADDRESSINGMODE_7BIT;
+	i2c_initd.DualAddressMode = I2C_DUALADDRESS_DISABLE;
+	i2c_initd.GeneralCallMode = I2C_GENERALCALL_DISABLE;
+	i2c_initd.NoStretchMode   = I2C_NOSTRETCH_DISABLE;
+	i2c_initd.OwnAddress1     = 0;
+	i2c_initd.OwnAddress2     = 0;
+	i2c_initd.semid           = I2CTRS_SEM;
+	i2c_initd.semlock         = I2CLOC_SEM;
+
+	if((hi2c = i2c_init(I2C_PORTID, &i2c_initd)) == NULL){
+		/* Initialization Error */
+		syslog_0(LOG_ERROR, "## I2C ERROR(1) ##");
+	}
+	syslog_0(LOG_NOTICE, "LCD INITAILIZE !");
+
+	hi2c->writecallback = I2C_TxCpltCallback;
+	hi2c->readcallback  = I2C_RxCpltCallback;
+	hi2c->errorcallback = I2C_ErrorCallback;
+
+	memset(&lcd_buf[0][0], ' ', 8);
+	memset(&lcd_buf[1][0], ' ', 8);
+
+	CLcdHandle.hi2c  = hi2c;
+	CLcdHandle.saddr = LCD_ADDR;
+	if((ercd = aqm0802_init(&CLcdHandle)) != E_OK){
+		syslog_2(LOG_ERROR, "## LCD INIT ERROR(%d)[%08x] ##", ercd, hi2c->ErrorCode);
+		goto stop_task;
+	}
+
+	get_tim(&tim);
+	set_time(&lcd_buf[0][0], tim);
+	LCD_locate(&CLcdHandle, 0, 0);
+	LCD_puts(&CLcdHandle, &lcd_buf[0][0]);
+
+#ifdef EEPROM_ADDR
+	syslog_1(LOG_NOTICE, "READ EEPROM [%08x] !", aRxBuffer2);
+	if(i2c_memread(hi2c, (uint16_t)EEPROM_ADDR, 0, I2C_MEMADD_SIZE_16BIT, (uint8_t*)aRxBuffer2, RXBUFFERSIZE, 500)!= E_OK){
+	    /* I2C RECEIVE ERROR */
+		syslog_1(LOG_ERROR, "## I2C ERROR(12)[%08x] ##", hi2c->ErrorCode);
+		goto stop_task;
+	}
+#endif
+
+	syslog_0(LOG_NOTICE, "TEMP SENSER !");
+	do{
+		/* STATUS READ */
+		if(i2c_memread(hi2c, (uint16_t)ADT7410_ADDR, ADT7410_STATUS, I2C_MEMADD_SIZE_8BIT, (uint8_t*)aRxBuffer, 1, 500)!= E_OK){
+			/* I2C RECEIVE ERROR */
+			syslog_1(LOG_ERROR, "## I2C ERROR(13)[%08x] ##", hi2c->ErrorCode);
+			goto stop_task;
+		}
+		temp = aRxBuffer[0];
+	}while((temp & 0x80) != 0);
+
+	while(count < 1000){
+		if(i2c_memread(hi2c, (uint16_t)ADT7410_ADDR, ADT7410_TEMP_H, I2C_MEMADD_SIZE_8BIT, (uint8_t*)aRxBuffer, 1, 500)!= E_OK){
+			/* I2C RECEIVE ERROR */
+			syslog_1(LOG_ERROR, "## I2C ERROR(14)[%08x] ##", hi2c->ErrorCode);
+			goto stop_task;
+		}
+		temp = aRxBuffer[0] << 8;
+		if(i2c_memread(hi2c, (uint16_t)ADT7410_ADDR, ADT7410_TEMP_L, I2C_MEMADD_SIZE_8BIT, (uint8_t*)aRxBuffer, 1, 500)!= E_OK){
+			/* I2C RECEIVE ERROR */
+			syslog_1(LOG_ERROR, "## I2C ERROR(15)[%08x] ##", hi2c->ErrorCode);
+			goto stop_task;
+		}
+		temp += aRxBuffer[0];
+		temp /= 13;
+
+		get_tim(&tim);
+		set_time(&lcd_buf[0][0], tim);
+		LCD_locate(&CLcdHandle, 0, 0);
+		LCD_puts(&CLcdHandle, &lcd_buf[0][0]);
+		set_value(&lcd_buf[1][0], temp/10);
+		lcd_buf[1][2] = '.';
+		lcd_buf[1][3] = (temp % 10) + '0';
+		LCD_locate(&CLcdHandle, 0, 1);
+		LCD_puts(&CLcdHandle, &lcd_buf[1][0]);
+		if((count % 10) == 0)
+			syslog_2(LOG_NOTICE, "count(%d) temp(%d)", count, temp);
+		dly_tsk(1000);
+		count++;
+	}
+
+stop_task:
+	syslog_0(LOG_NOTICE, "## STOP ##");
+	slp_tsk();
+	syslog(LOG_NOTICE, "Sample program ends.");
+//	SVC_PERROR(ext_ker());
+}
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/OBJ/STM32F767NUCLEO144_GCC/i2cshield/i2ctest.cfg
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/OBJ/STM32F767NUCLEO144_GCC/i2cshield/i2ctest.cfg	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/OBJ/STM32F767NUCLEO144_GCC/i2cshield/i2ctest.cfg	(revision 457)
@@ -0,0 +1,31 @@
+/*
+ *  $Id$
+ */
+
+/*
+ *  SPIテストのコンフィギュレーションファイル
+ */
+INCLUDE("target_timer.cfg");
+INCLUDE("syssvc/syslog.cfg");
+INCLUDE("syssvc/banner.cfg");
+INCLUDE("syssvc/serial.cfg");
+INCLUDE("syssvc/logtask.cfg");
+INCLUDE("monitor/monitor.cfg");
+INCLUDE("pdic/stm32f7xx/device.cfg");
+
+#include "device.h"
+#include "i2ctest.h"
+
+ATT_INI({ TA_NULL, sw_int, setup_sw_func });
+ATT_INI({ TA_NULL, 0, device_info_init });
+
+CRE_SEM(I2CTRS_SEM, { TA_TPRI, 0, 1 });
+CRE_SEM(I2CLOC_SEM, { TA_TPRI, 1, 1 });
+
+CRE_TSK(MAIN_TASK, { TA_ACT, 0, main_task, MAIN_PRIORITY, STACK_SIZE, NULL });
+
+ATT_ISR({TA_NULL, I2C_PORTID, INTNO_I2CEV, i2c_ev_isr, 1 });
+CFG_INT(INTNO_I2CEV, { TA_ENAINT | INTATR_I2CEV, INTPRI_I2CEV });
+ATT_ISR({TA_NULL, I2C_PORTID, INTNO_I2CER, i2c_er_isr, 1 });
+CFG_INT(INTNO_I2CER, { TA_ENAINT | INTATR_I2CER, INTPRI_I2CER });
+
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/OBJ/STM32F767NUCLEO144_GCC/i2cshield/i2ctest.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/OBJ/STM32F767NUCLEO144_GCC/i2cshield/i2ctest.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/OBJ/STM32F767NUCLEO144_GCC/i2cshield/i2ctest.h	(revision 457)
@@ -0,0 +1,102 @@
+/*
+ *  TOPPERS/ASP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Advanced Standard Profile Kernel
+ *
+ *  Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
+ *                              Toyohashi Univ. of Technology, JAPAN
+ *  Copyright (C) 2004-2010 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ *
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ *
+ *  $Id$
+ */
+
+/*
+ *	I2Cテストのヘッダファイル
+ */
+
+/*
+ *  ターゲット依存の定義
+ */
+#include "target_test.h"
+#include "i2c.h"
+#include "aqm0802_st7032.h"
+
+/*
+ *  各タスクの優先度の定義
+ */
+
+#define MAIN_PRIORITY	5		/* メインタスクの優先度 */
+								/* HIGH_PRIORITYより高くすること */
+
+#define HIGH_PRIORITY	9		/* 並行実行されるタスクの優先度 */
+#define MID_PRIORITY	10
+#define LOW_PRIORITY	11
+
+/*
+ *  ターゲットに依存する可能性のある定数の定義
+ */
+
+#ifndef TASK_PORTID
+#define	TASK_PORTID		1			/* 文字入力するシリアルポートID */
+#endif /* TASK_PORTID */
+
+#ifndef STACK_SIZE
+#define	STACK_SIZE		4096		/* タスクのスタックサイズ */
+#endif /* STACK_SIZE */
+
+#define I2C_PORTID I2C1_PORTID
+#define INHNO_I2CEV   IRQ_VECTOR_I2C1_EV	/* 割込みハンドラ番号 */
+#define INTNO_I2CEV   IRQ_VECTOR_I2C1_EV	/* 割込み番号 */
+#define INTPRI_I2CEV  -5			/* 割込み優先度 */
+#define INTATR_I2CEV  0				/* 割込み属性 */
+
+#define INHNO_I2CER   IRQ_VECTOR_I2C1_ER	/* 割込みハンドラ番号 */
+#define INTNO_I2CER   IRQ_VECTOR_I2C1_ER	/* 割込み番号 */
+#define INTPRI_I2CER  -5			/* 割込み優先度 */
+#define INTATR_I2CER  0				/* 割込み属性 */
+
+
+#ifndef TOPPERS_MACRO_ONLY
+
+/*
+ *  関数のプロトタイプ宣言
+ */
+extern void	main_task(intptr_t exinf);
+
+extern void sw_int(void);
+extern void device_info_init(intptr_t exinf);
+
+extern void i2c_ev_isr(intptr_t exinf);
+extern void i2c_er_isr(intptr_t exinf);
+
+#endif /* TOPPERS_MACRO_ONLY */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/OBJ/STM32F767NUCLEO144_GCC/lcdshield/Makefile
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/OBJ/STM32F767NUCLEO144_GCC/lcdshield/Makefile	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/OBJ/STM32F767NUCLEO144_GCC/lcdshield/Makefile	(revision 457)
@@ -0,0 +1,614 @@
+#
+#  TOPPERS/ASP Kernel
+#      Toyohashi Open Platform for Embedded Real-Time Systems/
+#      Advanced Standard Profile Kernel
+# 
+#  Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
+#                              Toyohashi Univ. of Technology, JAPAN
+#  Copyright (C) 2006-2014 by Embedded and Real-Time Systems Laboratory
+#              Graduate School of Information Science, Nagoya Univ., JAPAN
+# 
+#  ä¸è¨èä½æ¨©è
+ã¯ï¼ä»¥ä¸ã®(1)ï½(4)ã®æ¡ä»¶ãæºããå ´åã«éãï¼æ¬ã½ããã¦ã§
+#  ã¢ï¼æ¬ã½ããã¦ã§ã¢ãæ¹å¤ãããã®ãå«ãï¼ä»¥ä¸åãï¼ãä½¿ç¨ã»è¤è£½ã»æ¹
+#  å¤ã»åé
+å¸ï¼ä»¥ä¸ï¼å©ç¨ã¨å¼ã¶ï¼ãããã¨ãç¡åã§è¨±è«¾ããï¼
+#  (1) æ¬ã½ããã¦ã§ã¢ãã½ã¼ã¹ã³ã¼ãã®å½¢ã§å©ç¨ããå ´åã«ã¯ï¼ä¸è¨ã®èä½
+#      æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨ã®ç¡ä¿è¨¼è¦å®ãï¼ãã®ã¾ã¾ã®å½¢ã§ã½ã¼
+#      ã¹ã³ã¼ãä¸­ã«å«ã¾ãã¦ãããã¨ï¼
+#  (2) æ¬ã½ããã¦ã§ã¢ãï¼ã©ã¤ãã©ãªå½¢å¼ãªã©ï¼ä»ã®ã½ããã¦ã§ã¢éçºã«ä½¿
+#      ç¨ã§ããå½¢ã§åé
+å¸ããå ´åã«ã¯ï¼åé
+å¸ã«ä¼´ããã­ã¥ã¡ã³ãï¼å©ç¨
+#      è
+ããã¥ã¢ã«ãªã©ï¼ã«ï¼ä¸è¨ã®èä½æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨
+#      ã®ç¡ä¿è¨¼è¦å®ãæ²è¼ãããã¨ï¼
+#  (3) æ¬ã½ããã¦ã§ã¢ãï¼æ©å¨ã«çµã¿è¾¼ããªã©ï¼ä»ã®ã½ããã¦ã§ã¢éçºã«ä½¿
+#      ç¨ã§ããªãå½¢ã§åé
+å¸ããå ´åã«ã¯ï¼æ¬¡ã®ããããã®æ¡ä»¶ãæºããã
+#      ã¨ï¼
+#    (a) åé
+å¸ã«ä¼´ããã­ã¥ã¡ã³ãï¼å©ç¨è
+ããã¥ã¢ã«ãªã©ï¼ã«ï¼ä¸è¨ã®è
+#        ä½æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨ã®ç¡ä¿è¨¼è¦å®ãæ²è¼ãããã¨ï¼
+#    (b) åé
+å¸ã®å½¢æ
+ãï¼å¥ã«å®ããæ¹æ³ã«ãã£ã¦ï¼TOPPERSãã­ã¸ã§ã¯ãã«
+#        å ±åãããã¨ï¼
+#  (4) æ¬ã½ããã¦ã§ã¢ã®å©ç¨ã«ããç´æ¥çã¾ãã¯éæ¥çã«çãããããªãæ
+#      å®³ãããï¼ä¸è¨èä½æ¨©è
+ããã³TOPPERSãã­ã¸ã§ã¯ããå
+è²¬ãããã¨ï¼
+#      ã¾ãï¼æ¬ã½ããã¦ã§ã¢ã®ã¦ã¼ã¶ã¾ãã¯ã¨ã³ãã¦ã¼ã¶ããã®ãããªãç
+#      ç±ã«åºã¥ãè«æ±ãããï¼ä¸è¨èä½æ¨©è
+ããã³TOPPERSãã­ã¸ã§ã¯ãã
+#      å
+è²¬ãããã¨ï¼
+# 
+#  æ¬ã½ããã¦ã§ã¢ã¯ï¼ç¡ä¿è¨¼ã§æä¾ããã¦ãããã®ã§ããï¼ä¸è¨èä½æ¨©è
+ã
+#  ãã³TOPPERSãã­ã¸ã§ã¯ãã¯ï¼æ¬ã½ããã¦ã§ã¢ã«é¢ãã¦ï¼ç¹å®ã®ä½¿ç¨ç®ç
+#  ã«å¯¾ããé©åæ§ãå«ãã¦ï¼ãããªãä¿è¨¼ãè¡ããªãï¼ã¾ãï¼æ¬ã½ããã¦ã§
+#  ã¢ã®å©ç¨ã«ããç´æ¥çã¾ãã¯éæ¥çã«çãããããªãæå®³ã«é¢ãã¦ãï¼ã
+#  ã®è²¬ä»»ãè² ããªãï¼
+# 
+#  $Id$
+# 
+
+#
+#  ã¿ã¼ã²ããã®æå®ï¼Makefile.targetã§ä¸æ¸ããããã®ãé²ãããï¼
+#
+all:
+
+#
+#  ã¿ã¼ã²ããç¥ç§°ã®å®ç¾©
+#
+TARGET = stm32f767nucleo144_gcc
+
+#
+#  ãã­ã°ã©ãã³ã°è¨èªã®å®ç¾©
+#
+SRCLANG = c
+ifeq ($(SRCLANG),c)
+  LIBS = -lc
+endif
+ifeq ($(SRCLANG),c++)
+  USE_CXX = true
+  CXXLIBS = -lstdc++ -lm -lc
+  CXXRTS = cxxrt.o newlibrt.o
+endif
+
+#
+#  ã½ã¼ã¹ãã¡ã¤ã«ã®ãã£ã¬ã¯ããªã®å®ç¾©
+#
+SRCDIR = ../../..
+
+#
+#  ãªãã¸ã§ã¯ããã¡ã¤ã«åã®æ¡å¼µå­ã®è¨­å®
+#
+OBJEXT = exe
+
+#
+#  å®è¡ç°å¢ã®å®ç¾©ï¼ã¿ã¼ã²ããä¾å­ã«ä¸æ¸ããããå ´åãããï¼
+#
+DBGENV := 
+
+#
+#  ã«ã¼ãã«ã©ã¤ãã©ãªï¼libkernel.aï¼ã®ãã£ã¬ã¯ããªå
+#  ï¼ã«ã¼ãã«ã©ã¤ãã©ãªãmakeå¯¾è±¡ã«ããæã¯ï¼ç©ºã«å®ç¾©ããï¼
+#
+KERNEL_LIB = ../libkernel
+
+#
+#  ã«ã¼ãã«ãé¢æ°åä½ã§ã³ã³ãã¤ã«ãããã©ããã®å®ç¾©
+#
+KERNEL_FUNCOBJS = 
+
+#
+#  ãã¬ã¼ã¹ã­ã°ãåå¾ãããã©ããã®å®ç¾©
+#
+ENABLE_TRACE = 
+
+#
+#   USB OTGã®ã¢ã¼ãå®ç¾©
+#
+USB_OTG_MODE = USB_OTG_MODE_HOST
+
+#
+#  ã¦ã¼ãã£ãªãã£ãã­ã°ã©ã ã®åç§°
+#
+PERL = /usr/bin/perl
+CFG = $(SRCDIR)/cfg/cfg/cfg
+
+#
+#  ãªãã¸ã§ã¯ããã¡ã¤ã«åã®å®ç¾©
+#
+OBJNAME = asp
+ifdef OBJEXT
+  OBJFILE = $(OBJNAME).$(OBJEXT)
+  CFG1_OUT = cfg1_out.$(OBJEXT)
+else
+  OBJFILE = $(OBJNAME)
+  CFG1_OUT = cfg1_out
+endif
+
+#
+#  ã¿ã¼ã²ããä¾å­é¨ã®ãã£ã¬ã¯ããªã®å®ç¾©
+#
+TARGETDIR = $(SRCDIR)/target/$(TARGET)
+
+#
+#  ã¿ã¼ã²ããä¾å­ã®å®ç¾©ã®ã¤ã³ã¯ã«ã¼ã
+#
+include $(TARGETDIR)/Makefile.target
+
+#
+#  ã³ã³ãã£ã®ã¥ã¬ã¼ã¿é¢ä¿ã®å¤æ°ã®å®ç¾©
+#
+CFG_TABS := --api-table $(SRCDIR)/kernel/kernel_api.csv \
+			--cfg1-def-table $(SRCDIR)/kernel/kernel_def.csv $(CFG_TABS)
+
+CFG_ASMOBJS := $(CFG_ASMOBJS)
+CFG_COBJS := kernel_cfg.o $(CFG_COBJS)
+CFG_OBJS := $(CFG_ASMOBJS) $(CFG_COBJS)
+CFG2_OUT_SRCS := kernel_cfg.h kernel_cfg.c $(CFG2_OUT_SRCS)
+
+#
+#  å
+±éã³ã³ãã¤ã«ãªãã·ã§ã³ã®å®ç¾©
+#
+COPTS := $(COPTS) -g 
+ifndef OMIT_WARNING_ALL
+  COPTS := $(COPTS) -Wall
+endif
+ifndef OMIT_OPTIMIZATION
+  COPTS := $(COPTS) -O2
+endif
+CDEFS := $(CDEFS) -DUSE_MSC_FILE
+INCLUDES := -I. -I$(SRCDIR)/include -I$(SRCDIR)/arch -I$(SRCDIR) $(INCLUDES)
+LDFLAGS := $(LDFLAGS) 
+CFG1_OUT_LDFLAGS := $(CFG1_OUT_LDFLAGS) 
+LIBS := $(LIBS) $(CXXLIBS)
+CFLAGS = $(COPTS) $(CDEFS) $(INCLUDES)
+
+#
+#  ã¢ããªã±ã¼ã·ã§ã³ãã­ã°ã©ã ã«é¢ããå®ç¾©
+#
+APPLNAME = lcdshield
+APPLDIR = 
+APPL_CFG = $(APPLNAME).cfg
+
+APPL_DIR = $(APPLDIR) $(SRCDIR)/library
+APPL_ASMOBJS =
+ifdef USE_CXX
+  APPL_CXXOBJS = $(APPLNAME).o 
+  APPL_COBJS = command.o 
+else
+  APPL_COBJS = $(APPLNAME).o command.o 
+endif
+APPL_COBJS := $(APPL_COBJS) log_output.o vasyslog.o t_perror.o strerror.o
+APPL_CFLAGS =
+APPL_LIBS =
+ifdef APPLDIR
+  INCLUDES := $(INCLUDES) $(foreach dir,$(APPLDIR),-I$(dir))
+endif
+
+#
+#  ããã«ã¦ã§ã¢ Makefile ã®ã¤ã³ã¯ã«ã¼ã
+#
+include $(SRCDIR)/monitor/Makefile.config
+include $(SRCDIR)/usb/Makefile.config
+include $(SRCDIR)/files/ff/Makefile2.config
+include $(SRCDIR)/files/Makefile.config
+include $(SRCDIR)/ui/stfont_disp/Makefile.config
+
+#
+#   USB CLASSã®è¿½å 
+#
+SYSSVC_COBJS := $(SYSSVC_COBJS) tusbh_msc.o
+
+#
+#  GDIC Makefile ã®ã¤ã³ã¯ã«ã¼ã
+#
+include $(SRCDIR)/gdic/usb_otg/Makefile.config
+include $(SRCDIR)/gdic/adafruit_st7735/Makefile.config
+
+#
+#  ã·ã¹ãã ãµã¼ãã¹ã«é¢ããå®ç¾©
+#
+SYSSVC_DIR := $(SYSSVC_DIR) $(SRCDIR)/syssvc $(SRCDIR)/library $(SRCDIR)/pdic/stm32f7xx
+SYSSVC_ASMOBJS := $(SYSSVC_ASMOBJS)
+SYSSVC_COBJS := $(SYSSVC_COBJS) banner.o syslog.o serial.o logtask.o armv7m.o \
+				 device.o spi.o adc.o pinmode.o usb_otg.o clock.o malloc.o tlsf.o mscdiskio.o $(CXXRTS)
+SYSSVC_CFLAGS := $(SYSSVC_CFLAGS)
+SYSSVC_LIBS := $(SYSSVC_LIBS)
+INCLUDES := $(INCLUDES) -I$(SRCDIR)/pdic/stm32f7xx
+
+#
+#  ã«ã¼ãã«ã«é¢ããå®ç¾©
+#
+#  KERNEL_ASMOBJS: ã«ã¼ãã«ã©ã¤ãã©ãªã«å«ããï¼ã½ã¼ã¹ãã¢ã»ã³ããªè¨èªã®
+#				   ãªãã¸ã§ã¯ããã¡ã¤ã«ï¼
+#  KERNEL_COBJS: ã«ã¼ãã«ã®ã©ã¤ãã©ãªã«å«ããï¼ã½ã¼ã¹ãCè¨èªã§ï¼ã½ã¼ã¹
+#				 ãã¡ã¤ã«ã¨1å¯¾1ã«å¯¾å¿ãããªãã¸ã§ã¯ããã¡ã¤ã«ï¼
+#  KERNEL_LCSRCS: ã«ã¼ãã«ã®ã©ã¤ãã©ãªã«å«ããCè¨èªã®ã½ã¼ã¹ãã¡ã¤ã«ã§ï¼
+#				  1ã¤ã®ã½ã¼ã¹ãã¡ã¤ã«ããè¤æ°ã®ãªãã¸ã§ã¯ããã¡ã¤ã«ãç
+#				  æãããã®ï¼
+#  KERNEL_LCOBJS: ä¸ã®ã½ã¼ã¹ãã¡ã¤ã«ããçæããããªãã¸ã§ã¯ããã¡ã¤ã«ï¼
+#  KERNEL_AUX_COBJS: ã­ã¼ãã¢ã¸ã¥ã¼ã«ã«å«ããªããï¼ã«ã¼ãã«ã®ã½ã¼ã¹ãã¡
+#					 ã¤ã«ã¨åããªãã·ã§ã³ãé©ç¨ãã¦ã³ã³ãã¤ã«ãã¹ãï¼ã½ã¼
+#					 ã¹ãCè¨èªã®ãªãã¸ã§ã¯ããã¡ã¤ã«ï¼
+#
+KERNEL_DIR := $(KERNEL_DIR) $(SRCDIR)/kernel
+KERNEL_ASMOBJS := $(KERNEL_ASMOBJS)
+KERNEL_COBJS := $(KERNEL_COBJS)
+KERNEL_CFLAGS := $(KERNEL_CFLAGS) -I$(SRCDIR)/kernel
+ifdef OMIT_MAKEOFFSET
+  OFFSET_H =
+else
+  OFFSET_H = offset.h
+ifndef OFFSET_TF
+  KERNEL_AUX_COBJS := $(KERNEL_AUX_COBJS) makeoffset.o
+endif
+endif
+
+#
+#  ã¿ã¼ã²ãããã¡ã¤ã«ï¼è¤æ°ãåæã«é¸æãã¦ã¯ãªããªãï¼
+#
+#all: $(OBJFILE)
+all: $(OBJNAME).bin
+#all: $(OBJNAME).srec
+
+##### ä»¥ä¸ã¯ç·¨éããªããã¨ #####
+
+#
+#  ç°å¢ã«ä¾å­ããã³ã³ãã¤ã«ãªãã·ã§ã³ã®å®ç¾©
+#
+ifdef DBGENV
+  CDEFS := $(CDEFS) -D$(DBGENV)
+endif
+
+#
+#  ã«ã¼ãã«ã®ãã¡ã¤ã«æ§æã®å®ç¾©
+#
+include $(SRCDIR)/kernel/Makefile.kernel
+ifdef KERNEL_FUNCOBJS
+  KERNEL_LCSRCS := $(KERNEL_FCSRCS)
+  KERNEL_LCOBJS := $(foreach file,$(KERNEL_FCSRCS),$($(file:.c=)))
+else
+  KERNEL_CFLAGS := -DALLFUNC $(KERNEL_CFLAGS)
+  KERNEL_COBJS := $(KERNEL_COBJS) \
+					$(foreach file,$(KERNEL_FCSRCS),$(file:.c=.o))
+endif
+
+#
+#  ã½ã¼ã¹ãã¡ã¤ã«ã®ãããã£ã¬ã¯ããªã«é¢ããå®ç¾©
+#
+vpath %.c $(KERNEL_DIR) $(SYSSVC_DIR) $(APPL_DIR)
+vpath %.S $(KERNEL_DIR) $(SYSSVC_DIR) $(APPL_DIR)
+vpath %.cfg $(APPL_DIR)
+
+#
+#  ã³ã³ãã¤ã«ã®ããã®å¤æ°ã®å®ç¾©
+#
+KERNEL_LIB_OBJS = $(KERNEL_ASMOBJS) $(KERNEL_COBJS) $(KERNEL_LCOBJS)
+SYSSVC_OBJS = $(SYSSVC_ASMOBJS) $(SYSSVC_COBJS)
+APPL_OBJS = $(APPL_ASMOBJS) $(APPL_COBJS) $(APPL_CXXOBJS)
+ALL_OBJS = $(START_OBJS) $(APPL_OBJS) $(SYSSVC_OBJS) $(CFG_OBJS) \
+											$(END_OBJS) $(HIDDEN_OBJS)
+ifdef KERNEL_LIB
+  ALL_LIBS = $(APPL_LIBS) $(SYSSVC_LIBS) -lkernel $(LIBS)
+  LIBS_DEP = $(filter %.a,$(ALL_LIBS)) $(KERNEL_LIB)/libkernel.a
+  LDFLAGS := $(LDFLAGS) -L$(KERNEL_LIB)
+  REALCLEAN_FILES := libkernel.a $(REALCLEAN_FILES)
+else
+  ALL_LIBS = $(APPL_LIBS) $(SYSSVC_LIBS) libkernel.a $(LIBS)
+  LIBS_DEP = $(filter %.a,$(ALL_LIBS))
+endif
+
+ifdef TEXT_START_ADDRESS
+  LDFLAGS := $(LDFLAGS) -Wl,-Ttext,$(TEXT_START_ADDRESS)
+  CFG1_OUT_LDFLAGS := $(CFG1_OUT_LDFLAGS) -Wl,-Ttext,$(TEXT_START_ADDRESS)
+endif
+ifdef DATA_START_ADDRESS
+  LDFLAGS := $(LDFLAGS) -Wl,-Tdata,$(DATA_START_ADDRESS)
+  CFG1_OUT_LDFLAGS := $(CFG1_OUT_LDFLAGS) -Wl,-Tdata,$(DATA_START_ADDRESS)
+endif
+ifdef LDSCRIPT
+  LDFLAGS := $(LDFLAGS) -T $(LDSCRIPT)
+  CFG1_OUT_LDFLAGS := $(CFG1_OUT_LDFLAGS) -T $(LDSCRIPT)
+endif
+
+#
+#  ãªãã»ãããã¡ã¤ã«ï¼offset.hï¼ã®çæè¦å
+#
+ifdef OFFSET_TF
+offset.h: $(APPL_CFG) kernel_cfg.timestamp
+	$(CFG) --pass 3 --kernel asp $(INCLUDES) \
+				--rom-image cfg1_out.srec --symbol-table cfg1_out.syms \
+				-T $(OFFSET_TF) $(CFG_TABS) $<
+else
+offset.h: makeoffset.s $(SRCDIR)/utils/genoffset
+	$(PERL) $(SRCDIR)/utils/genoffset makeoffset.s > offset.h
+endif
+
+#
+#  ã«ã¼ãã«ã®ã³ã³ãã£ã®ã¥ã¬ã¼ã·ã§ã³ãã¡ã¤ã«ã®çæ
+#
+cfg1_out.c: $(APPL_CFG)
+	$(CFG) --pass 1 --kernel asp $(INCLUDES) $(CFG_TABS) $<
+
+$(CFG2_OUT_SRCS): kernel_cfg.timestamp
+kernel_cfg.timestamp: $(APPL_CFG) \
+						$(START_OBJS) cfg1_out.o $(END_OBJS) $(HIDDEN_OBJS)
+	$(LINK) $(CFLAGS) $(CFG1_OUT_LDFLAGS) -o $(CFG1_OUT) \
+						$(START_OBJS) cfg1_out.o $(END_OBJS)
+	$(NM) -n $(CFG1_OUT) > cfg1_out.syms
+	$(OBJCOPY) -O srec -S $(CFG1_OUT) cfg1_out.srec
+	$(CFG) --pass 2 --kernel asp $(INCLUDES) \
+				-T $(TARGETDIR)/target.tf $(CFG_TABS) $<
+	touch -r kernel_cfg.c kernel_cfg.timestamp
+
+#
+#  ã«ã¼ãã«ã©ã¤ãã©ãªãã¡ã¤ã«ã®çæ
+#
+libkernel.a: $(OFFSET_H) $(KERNEL_LIB_OBJS)
+	rm -f libkernel.a
+	$(AR) -rcs libkernel.a $(KERNEL_LIB_OBJS)
+	$(RANLIB) libkernel.a
+
+#
+#  ç¹å¥ãªä¾å­é¢ä¿ã®å®ç¾©
+#
+banner.o: kernel_cfg.timestamp $(filter-out banner.o,$(ALL_OBJS)) $(LIBS_DEP)
+
+#
+#  å
+¨ä½ã®ãªã³ã¯
+#
+$(OBJFILE): $(APPL_CFG) kernel_cfg.timestamp $(ALL_OBJS) $(LIBS_DEP)
+	$(LINK) $(CFLAGS) $(LDFLAGS) -o $(OBJFILE) $(START_OBJS) \
+			$(APPL_OBJS) $(SYSSVC_OBJS) $(CFG_OBJS) $(ALL_LIBS) $(END_OBJS)
+	$(NM) -n $(OBJFILE) > $(OBJNAME).syms
+	$(OBJCOPY) -O srec -S $(OBJFILE) $(OBJNAME).srec
+	$(CFG) --pass 3 --kernel asp $(INCLUDES) \
+				--rom-image $(OBJNAME).srec --symbol-table $(OBJNAME).syms \
+				-T $(TARGETDIR)/target_check.tf $(CFG_TABS) $<
+
+#
+#  ãã¤ããªãã¡ã¤ã«ã®çæ
+#
+$(OBJNAME).bin: $(OBJFILE)
+	$(OBJCOPY) -O binary -S $(OBJFILE) $(OBJNAME).bin
+
+#
+#  Sã¬ã³ã¼ããã¡ã¤ã«ã®çæ
+#
+$(OBJNAME).srec: $(OBJFILE)
+	$(OBJCOPY) -O srec -S $(OBJFILE) $(OBJNAME).srec
+
+#
+#  ã³ã³ãã¤ã«çµæã®æ¶å»
+#
+.PHONY: clean
+clean:
+	rm -f \#* *~ *.o $(CLEAN_FILES)
+	rm -f $(OBJFILE) $(OBJNAME).syms $(OBJNAME).srec $(OBJNAME).bin
+	rm -f kernel_cfg.timestamp $(CFG2_OUT_SRCS)
+	rm -f cfg1_out.c $(CFG1_OUT) cfg1_out.syms cfg1_out.srec
+ifndef KERNEL_LIB
+	rm -f libkernel.a
+endif
+	rm -f makeoffset.s offset.h
+
+.PHONY: cleankernel
+cleankernel:
+	rm -rf $(KERNEL_LIB_OBJS)
+	rm -f makeoffset.s offset.h
+
+.PHONY: cleandep
+cleandep:
+	if ! [ -f Makefile.depend ]; then \
+		rm -f kernel_cfg.timestamp $(CFG2_OUT_SRCS); \
+		rm -f cfg1_out.c cfg1_out.o $(CFG1_OUT) cfg1_out.syms cfg1_out.srec; \
+		rm -f makeoffset.s offset.h; \
+	fi
+	rm -f Makefile.depend
+
+.PHONY: realclean
+realclean: cleandep clean
+	rm -f $(REALCLEAN_FILES)
+
+#
+#  ã³ã³ãã£ã®ã¥ã¬ã¼ã¿ãçæãããã¡ã¤ã«ã®ã³ã³ãã¤ã«ã«ã¼ã«ã¨ä¾å­é¢ä¿ä½æ
+#  ã«ã¼ã«ã®å®ç¾©
+#
+#  ã³ã³ãã£ã®ã¥ã¬ã¼ã¿ãçæãããã¡ã¤ã«ã¯ï¼ã¢ããªã±ã¼ã·ã§ã³ãã­ã°ã©ã ç¨ï¼
+#  ã·ã¹ãã ãµã¼ãã¹ç¨ï¼ã«ã¼ãã«ç¨ã®ãã¹ã¦ã®ãªãã·ã§ã³ãä»ãã¦ã³ã³ãã¤ã«
+#  ããï¼
+#
+ALL_CFG_COBJS = $(CFG_COBJS) cfg1_out.o
+ALL_CFG_ASMOBJS = $(CFG_ASMOBJS)
+CFG_CFLAGS = $(APPL_CFLAGS) $(SYSSVC_CFLAGS) $(KERNEL_CFLAGS)
+
+$(ALL_CFG_COBJS): %.o: %.c
+	$(CC) -c $(CFLAGS) $(CFG_CFLAGS) $<
+
+$(ALL_CFG_COBJS:.o=.s): %.s: %.c
+	$(CC) -S $(CFLAGS) $(CFG_CFLAGS) $<
+
+$(ALL_CFG_COBJS:.o=.d): %.d: %.c
+	@$(PERL) $(SRCDIR)/utils/makedep -C $(CC) $(MAKEDEP_OPTS) \
+		-O "$(CFLAGS) $(CFG_CFLAGS)" $< >> Makefile.depend
+
+$(ALL_CFG_ASMOBJS): %.o: %.S
+	$(CC) -c $(CFLAGS) $(CFG_CFLAGS) $<
+
+$(ALL_CFG_ASMOBJS:.o=.d): %.d: %.S
+	@$(PERL) $(SRCDIR)/utils/makedep -C $(CC) $(MAKEDEP_OPTS) \
+		-O "$(CFLAGS) $(CFG_CFLAGS)" $< >> Makefile.depend
+
+#
+#  ç¹æ®ãªä¾å­é¢ä¿ä½æã«ã¼ã«ã®å®ç¾©
+#
+cfg1_out.depend: $(APPL_CFG)
+	@$(CFG) -M cfg1_out.c $(INCLUDES) $< >> Makefile.depend
+
+makeoffset.d: makeoffset.c
+	@$(PERL) $(SRCDIR)/utils/makedep -C $(CC) $(MAKEDEP_OPTS) \
+		-T "makeoffset.s" -O "$(CFLAGS) $(KERNEL_CFLAGS)" $< >> Makefile.depend
+
+#
+#  ä¾å­é¢ä¿ãã¡ã¤ã«ã®çæ
+#
+.PHONY: gendepend
+gendepend:
+	@echo "Generating Makefile.depend."
+
+.PHONY: depend
+ifdef KERNEL_LIB
+depend: cleandep kernel_cfg.timestamp gendepend \
+		cfg1_out.depend cfg1_out.d \
+		$(ALL_OBJS:.o=.d)
+else
+depend: cleandep $(OFFSET_H) kernel_cfg.timestamp gendepend \
+		cfg1_out.depend cfg1_out.d \
+		$(KERNEL_AUX_COBJS:.o=.d) $(KERNEL_ASMOBJS:.o=.d) \
+		$(KERNEL_COBJS:.o=.d) $(KERNEL_LCSRCS:.c=.d) $(ALL_OBJS:.o=.d)
+endif
+
+#
+#  ä¾å­é¢ä¿ãã¡ã¤ã«ãã¤ã³ã¯ã«ã¼ã
+#
+-include Makefile.depend
+
+#
+#  éçºãã¼ã«ã®ã³ãã³ãåã®å®ç¾©
+#
+ifeq ($(TOOL),gcc)
+  #
+  #  GNUéçºç°å¢ç¨
+  #
+  ifdef GCC_TARGET
+    GCC_TARGET_PREFIX = $(GCC_TARGET)-
+  else
+    GCC_TARGET_PREFIX =
+  endif
+  CC = $(GCC_TARGET_PREFIX)gcc
+  CXX = $(GCC_TARGET_PREFIX)g++
+  AS = $(GCC_TARGET_PREFIX)as
+  LD = $(GCC_TARGET_PREFIX)ld
+  AR = $(GCC_TARGET_PREFIX)ar
+  NM = $(GCC_TARGET_PREFIX)nm
+  RANLIB = $(GCC_TARGET_PREFIX)ranlib
+  OBJCOPY = $(GCC_TARGET_PREFIX)objcopy
+  OBJDUMP = $(GCC_TARGET_PREFIX)objdump
+endif
+
+ifdef USE_CXX
+  LINK = $(CXX)
+else
+  LINK = $(CC)
+endif
+
+#
+#  ã³ã³ãã¤ã«ã«ã¼ã«ã®å®ç¾©
+#
+KERNEL_ALL_COBJS = $(KERNEL_COBJS) $(KERNEL_AUX_COBJS)
+
+$(KERNEL_ALL_COBJS): %.o: %.c
+	$(CC) -c $(CFLAGS) $(KERNEL_CFLAGS) $<
+
+$(KERNEL_ALL_COBJS:.o=.s): %.s: %.c
+	$(CC) -S $(CFLAGS) $(KERNEL_CFLAGS) $<
+
+$(KERNEL_LCOBJS): %.o:
+	$(CC) -DTOPPERS_$(*F) -o $@ -c $(CFLAGS) $(KERNEL_CFLAGS) $<
+
+$(KERNEL_LCOBJS:.o=.s): %.s:
+	$(CC) -DTOPPERS_$(*F) -o $@ -S $(CFLAGS) $(KERNEL_CFLAGS) $<
+
+$(KERNEL_ASMOBJS): %.o: %.S
+	$(CC) -c $(CFLAGS) $(KERNEL_CFLAGS) $<
+
+$(SYSSVC_COBJS): %.o: %.c
+	$(CC) -c $(CFLAGS) $(SYSSVC_CFLAGS) $<
+
+$(SYSSVC_COBJS:.o=.s): %.s: %.c
+	$(CC) -S $(CFLAGS) $(SYSSVC_CFLAGS) $<
+
+$(SYSSVC_ASMOBJS): %.o: %.S
+	$(CC) -c $(CFLAGS) $(SYSSVC_CFLAGS) $<
+
+$(APPL_COBJS): %.o: %.c
+	$(CC) -c $(CFLAGS) $(APPL_CFLAGS) $<
+
+$(APPL_COBJS:.o=.s): %.s: %.c
+	$(CC) -S $(CFLAGS) $(APPL_CFLAGS) $<
+
+$(APPL_CXXOBJS): %.o: %.cpp
+	$(CXX) -c $(CFLAGS) $(APPL_CFLAGS) $<
+
+$(APPL_CXXOBJS:.o=.s): %.s: %.cpp
+	$(CXX) -S $(CFLAGS) $(APPL_CFLAGS) $<
+
+$(APPL_ASMOBJS): %.o: %.S
+	$(CC) -c $(CFLAGS) $(APPL_CFLAGS) $<
+
+#
+#  ä¾å­é¢ä¿ä½æã«ã¼ã«ã®å®ç¾©
+#
+$(KERNEL_COBJS:.o=.d): %.d: %.c
+	@$(PERL) $(SRCDIR)/utils/makedep -C $(CC) $(MAKEDEP_OPTS) \
+		-O "$(CFLAGS) $(KERNEL_CFLAGS)" $< >> Makefile.depend
+
+$(KERNEL_LCSRCS:.c=.d): %.d: %.c
+	@$(PERL) $(SRCDIR)/utils/makedep -C $(CC) $(MAKEDEP_OPTS) -T "$($*)" \
+		-O "-DALLFUNC $(CFLAGS) $(KERNEL_CFLAGS)" $< >> Makefile.depend
+
+$(KERNEL_ASMOBJS:.o=.d): %.d: %.S
+	@$(PERL) $(SRCDIR)/utils/makedep -C $(CC) $(MAKEDEP_OPTS) \
+		-O "$(CFLAGS) $(KERNEL_CFLAGS)" $< >> Makefile.depend
+
+$(SYSSVC_COBJS:.o=.d): %.d: %.c
+	@$(PERL) $(SRCDIR)/utils/makedep -C $(CC) $(MAKEDEP_OPTS) \
+		-O "$(CFLAGS) $(SYSSVC_CFLAGS)" $< >> Makefile.depend
+
+$(SYSSVC_ASMOBJS:.o=.d): %.d: %.S
+	@$(PERL) $(SRCDIR)/utils/makedep -C $(CC) $(MAKEDEP_OPTS) \
+		-O "$(CFLAGS) $(SYSSVC_CFLAGS)" $< >> Makefile.depend
+
+$(APPL_COBJS:.o=.d): %.d: %.c
+	@$(PERL) $(SRCDIR)/utils/makedep -C $(CC) $(MAKEDEP_OPTS) \
+		-O "$(CFLAGS) $(APPL_CFLAGS)" $< >> Makefile.depend
+
+$(APPL_CXXOBJS:.o=.d): %.d: %.cpp
+	@$(PERL) $(SRCDIR)/utils/makedep -C $(CXX) $(MAKEDEP_OPTS) \
+		-O "$(CFLAGS) $(APPL_CFLAGS)" $< >> Makefile.depend
+
+$(APPL_ASMOBJS:.o=.d): %.d: %.S
+	@$(PERL) $(SRCDIR)/utils/makedep -C $(CC) $(MAKEDEP_OPTS) \
+		-O "$(CFLAGS) $(APPL_CFLAGS)" $< >> Makefile.depend
+
+#
+#  ããã©ã«ãã³ã³ãã¤ã«ã«ã¼ã«ãä¸æ¸ã
+#
+%.o: %.c
+	@echo "*** Default compile rules should not be used."
+	$(CC) -c $(CFLAGS) $<
+
+%.s: %.c
+	@echo "*** Default compile rules should not be used."
+	$(CC) -S $(CFLAGS) $<
+
+%.o: %.cpp
+	@echo "*** Default compile rules should not be used."
+	$(CXX) -c $(CFLAGS) $<
+
+%.s: %.cpp
+	@echo "*** Default compile rules should not be used."
+	$(CXX) -S $(CFLAGS) $<
+
+%.o: %.S
+	@echo "*** Default compile rules should not be used."
+	$(CC) -c $(CFLAGS) $<
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/OBJ/STM32F767NUCLEO144_GCC/lcdshield/command.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/OBJ/STM32F767NUCLEO144_GCC/lcdshield/command.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/OBJ/STM32F767NUCLEO144_GCC/lcdshield/command.c	(revision 457)
@@ -0,0 +1,141 @@
+#include <kernel.h>
+#include <t_syslog.h>
+#include <stdio.h>
+#include <t_stdlib.h>
+#include <stdlib.h>
+#include "syssvc/serial.h"
+#include "syssvc/syslog.h"
+#include "kernel_cfg.h"
+#include "monitor.h"
+#include "device.h"
+
+/*
+ *  デバイスコマンド番号
+ */
+#define NUM_DEVICE_CMD   3
+
+static int_t led_func(int argc, char **argv);
+static int_t dip_func(int argc, char **argv);
+static int_t cup_func(int argc, char **argv);
+
+/*
+ *  デバイスコマンドテーブル
+ */
+static const COMMAND_INFO device_command_info[NUM_DEVICE_CMD] = {
+	{"LED",		led_func},
+	{"DIP",		dip_func},
+	{"CUP",		cup_func}
+};
+
+static const char device_name[] = "DEVICE";
+static const char device_help[] =
+"  Device  LED (no) (on-1,off-0)  led   control\n"
+"          DIP (no) (on-1,off-0)  dipsw control\n"
+"          CUP command            cup   control\n";
+
+static const uint16_t led_pattern[4] = {
+	LED01, LED02, LED03, LED04
+};
+
+static COMMAND_LINK device_command_link = {
+	NULL,
+	NUM_DEVICE_CMD,
+	device_name,
+	NULL,
+	device_help,
+	&device_command_info[0]
+};
+
+static uint8_t cup_command;
+
+static int a2i(char *str)
+{
+	int num = 0;
+
+	while(*str >= '0' && *str <= '9'){
+		num = num * 10 + *str++ - '0';
+	}
+	return num;
+}
+
+/*
+ *  DEVICEコマンド設定関数
+ */
+void device_info_init(intptr_t exinf)
+{
+	setup_command(&device_command_link);
+}
+
+/*
+ *  LED設定コマンド関数
+ */
+static int_t led_func(int argc, char **argv)
+{
+	int_t    arg1=0, arg2;
+	uint16_t reg;
+
+	if(argc < 3)
+		return -1;
+	arg1 = a2i(argv[1]);
+	arg2 = a2i(argv[2]);
+	if(arg1 >= 1 && arg1 <= 4){
+		reg = led_in();
+		if(arg2 != 0)
+			reg |= led_pattern[arg1-1];
+		else
+			reg &= ~led_pattern[arg1-1];
+		led_out(reg);
+	}
+	return 0;
+}
+
+/*
+ *  DIPSW設定コマンド関数
+ */
+static int_t dip_func(int argc, char **argv)
+{
+	int_t   arg1=0, arg2=0, i;
+
+	if(argc > 1)
+		arg1 = a2i(argv[1]);
+	if(argc > 2)
+		arg2 = a2i(argv[2]);
+	if(arg1 >= 1 && arg1 <= 8){
+		if(arg2 != 0)
+			dipsw_value |= (0x1<<(arg1-1));
+		else
+			dipsw_value &= ~(0x1<<(arg1-1));
+	}
+	printf("dipsw\n1   2   3   4   5   6   7   8\n");
+	for(i = 0 ; i < 8 ; i++){
+		if(dipsw_value & (1<<i))
+			printf("ON  ");
+		else
+			printf("OFF ");
+	}
+	printf("\n");
+	return 0;
+}
+
+/*
+ *  カップラーメンタイマ補助コマンド関数
+ */
+static int_t cup_func(int argc, char **argv)
+{
+	if(argc > 1)
+		cup_command = *argv[1];
+	return 0;
+}
+
+/*
+ * CUPラーメンコマンド
+ */
+int8_t
+get_cup_command(void)
+{
+	uint8_t cmd = cup_command;
+	cup_command = 0;
+	return cmd;
+}
+
+
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/OBJ/STM32F767NUCLEO144_GCC/lcdshield/lcdshield.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/OBJ/STM32F767NUCLEO144_GCC/lcdshield/lcdshield.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/OBJ/STM32F767NUCLEO144_GCC/lcdshield/lcdshield.c	(revision 457)
@@ -0,0 +1,579 @@
+/*
+ *  TOPPERS/ASP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Advanced Standard Profile Kernel
+ * 
+ *  Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
+ *                              Toyohashi Univ. of Technology, JAPAN
+ *  Copyright (C) 2004-2012 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ *  Copyright (C) 2015-2016 by TOPPERS PROJECT Educational Working Group.
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  $Id$
+ */
+
+/* 
+ *  LCDシールド制御プログラムの本体
+ */
+
+#include <kernel.h>
+#include <t_syslog.h>
+#include <t_stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <target_syssvc.h>
+#include "syssvc/serial.h"
+#include "syssvc/syslog.h"
+#include "kernel_cfg.h"
+#include "device.h"
+#include "spi.h"
+#include "pinmode.h"
+#include "adafruit_st7735.h"
+#ifdef USE_MSC_FILE
+#include "storagedevice.h"
+#include "mscdiskio.h"
+#endif
+#include "lcdshield.h"
+#include "adc.h"
+#include "topamelogo.h"
+
+/*
+ *  サービスコールのエラーのログ出力
+ */
+Inline void
+svc_perror(const char *file, int_t line, const char *expr, ER ercd)
+{
+	if (ercd < 0) {
+		t_perror(LOG_ERROR, file, line, expr, ercd);
+	}
+}
+
+#define	SVC_PERROR(expr)	svc_perror(__FILE__, __LINE__, #expr, (expr))
+#define ABS(X)  ((X) > 0 ? (X) : -(X))
+
+
+/*
+ *  使用する変数の定義
+ */
+static const Point testPolygon[7] = {
+	{0, 0},
+	{127, 159},
+	{64, 0},
+	{64, 159},
+	{127, 0},
+	{0, 159},
+	{0, 0}
+};
+
+static const uint32_t pos_tbl[NUM_JSPOSITION-1][2] = {
+	{  500, JS_DOWN  },
+	{ 1000, JS_RIGHT },
+	{ 1500, JS_ON    },
+	{ 2500, JS_UP    },
+	{ 3800, JS_LEFT  }
+};
+static const char *pos_str[NUM_JSPOSITION-1] = {
+	"      ON      ",
+	"      UP      ",
+	"     DOWN     ",
+	"     LEFT     ",
+	"     RIGHT    "
+};
+
+
+LCD_Handler_t  LcdHandle;
+LCD_DrawProp_t DrawProp;
+uint8_t msc_state;
+
+#define NUM_ADCBUF   1		/* 96:1ms */
+volatile uint32_t uhADCxConvertedValue;
+
+#ifndef USE_MSC_FILE
+uint32_t sdbuffer[514/4];
+#endif
+
+/* Buffer used for transmission */
+uint8_t aTxBuffer[BUFFERSIZE];
+
+/* Buffer used for reception */
+uint8_t aRxBuffer[BUFFERSIZE];
+
+static uint32_t heap_area[2*1024];
+
+uint32_t heap_param[2] = {
+	(uint32_t)heap_area,
+	(2*4*1024)
+};
+
+#ifdef USE_MSC_FILE
+/*
+ *  時刻の取出し
+ */
+static uint32_t get_fat_time(void)
+{
+	int    reqtime = 0;
+	struct tm2 timedate;
+
+	rtc_get_time(&timedate);
+	reqtime  = ((timedate.tm_year-10)<<25)+(timedate.tm_mon<<21)+(timedate.tm_mday<<16);
+	reqtime += (timedate.tm_hour<<11)+(timedate.tm_min<<5)+(timedate.tm_sec/2);
+	return reqtime;
+}
+#endif
+
+/*
+ *  SW1割込み
+ */
+void sw_int(void)
+{
+	syslog_0(LOG_NOTICE, "## sw_int() ##");
+}
+
+/*
+ *  GPIO設定関数
+ */
+static void
+pinMode(uint8_t no, uint32_t mode)
+{
+	Arduino_PortControlBlock *pgcb = getGpioTable(DIGITAL_PIN, no);
+	GPIO_Init_t GPIO_Init_Data;
+
+	if(pgcb == NULL)
+		return;
+	pinClock(no);
+	GPIO_Init_Data.mode  = mode;
+	GPIO_Init_Data.pull  = GPIO_PULLMODE;
+	GPIO_Init_Data.otype = GPIO_OTYPE;
+	GPIO_Init_Data.speed = GPIO_SPEED_FAST;
+	gpio_setup(pgcb->giobase, &GPIO_Init_Data, pgcb->giopin);
+}
+
+
+/*
+ *  グラフィック表示テスト
+ */
+void
+grapics_test(LCD_Handler_t *hlcd)
+{
+	uint16_t x, y;
+	int      i;
+
+	DrawProp.BackColor = ST7735_BLACK;
+	lcd_fillScreen(&DrawProp);
+	dly_tsk(1000);
+	lcd_drawPixel(hlcd, hlcd->_width/2, hlcd->_height/2, ST7735_GREEN);
+	dly_tsk(1000);
+
+	lcd_fillScreen(&DrawProp);
+	for(y=0; y < hlcd->_height; y+=5) {
+		lcd_drawFastHLine(hlcd, 0, y, hlcd->_width, ST7735_RED);
+	}
+	for (x=0; x < hlcd->_width; x+=5) {
+    	lcd_drawFastVLine(hlcd, x, 0, hlcd->_height, ST7735_BLUE);
+	}
+	dly_tsk(1000);
+
+	lcd_fillScreen(&DrawProp);
+	DrawProp.TextColor = ST7735_GREEN;
+	lcd_drawPolygon(&DrawProp, (Point *)testPolygon, sizeof(testPolygon)/sizeof(Point));
+	dly_tsk(1000);
+
+	lcd_fillScreen(&DrawProp);
+	DrawProp.TextColor = ST7735_GREEN;
+	for (x=0; x < hlcd->_width; x+=6) {
+		lcd_drawRect(&DrawProp, hlcd->_width/2 -x/2, hlcd->_height/2 -x/2 , x, x);
+	}
+	for(i = 0 ; i < 3 ; i++){
+		lcd_invertDisplay(hlcd, true);
+		dly_tsk(500);
+		lcd_invertDisplay(hlcd, false);
+		dly_tsk(500);
+	}
+	lcd_fillScreen(&DrawProp);
+	lcd_drawBitmap(hlcd, 33, 48, (uint8_t *)topamelogo);
+	dly_tsk(1000);
+}
+
+/*
+ *  USB HOST INFORMATION CALLBACK
+ *  parameter1:  Host Handler
+ *  parameter2:  Device Handler
+ *  parameter3:  Host state ID.
+ */
+static void USBH_UserProcess(USBH_HandleTypeDef *phost, TUSBH_Device_t *pdevice, uint8_t id)
+{
+	msc_state = id;
+	if(pdevice->pClass != NULL){
+		syslog_3(LOG_NOTICE, "## CLASS[%s](%d)(%d) ##", pdevice->pClass->Name, pdevice->type, id);
+	}
+}
+
+/*
+ *  メインタスク
+ */
+void
+main_task(intptr_t exinf)
+{
+#ifdef USE_MSC_FILE
+	StorageDevice_t *psdev;
+#else
+	TUSBH_ERCODE  status = TUSBH_E_OK;
+	char pdrv = 0;
+#endif
+	SPI_Init_t spi_initd;
+	USB_OTG_Init_t USB_Data_Init;
+	LCD_Handler_t   *hlcd;
+	SPI_Handle_t  *hspi;
+	USB_OTG_Handle_t *husb;
+	USBH_HandleTypeDef *husbh;
+    FLGPTN  flgptn;
+	ER_UINT	ercd;
+	int sens = 1000;
+	int i;
+
+	SVC_PERROR(syslog_msk_log(LOG_UPTO(LOG_INFO), LOG_UPTO(LOG_EMERG)));
+	syslog(LOG_NOTICE, "Sample program starts (exinf = %d).", (int_t) exinf);
+
+	/*
+	 *  シリアルポートの初期化
+	 *
+	 *  システムログタスクと同じシリアルポートを使う場合など，シリアル
+	 *  ポートがオープン済みの場合にはここでE_OBJエラーになるが，支障は
+	 *  ない．
+	 */
+	ercd = serial_opn_por(TASK_PORTID);
+	if (ercd < 0 && MERCD(ercd) != E_OBJ) {
+		syslog(LOG_ERROR, "%s (%d) reported by `serial_opn_por'.",
+									itron_strerror(ercd), SERCD(ercd));
+	}
+	SVC_PERROR(serial_ctl_por(TASK_PORTID,
+							(IOCTL_CRLF | IOCTL_FCSND | IOCTL_FCRCV)));
+
+	syslog_0(LOG_NOTICE, "## START ##");
+	/*
+	 *  CS PORT(D10-PB6)
+	 */
+	pinMode(CS_PORT, GPIO_MODE_OUTPUT);
+	/*
+	 *  RS PORT(D8-PA9)
+	 */
+	pinMode(RS_PORT, GPIO_MODE_OUTPUT);
+	/*
+	 *  RST PORT(D9-PC7)
+	 */
+	pinMode(RST_PORT, GPIO_MODE_OUTPUT);
+
+	spi_initd.Prescaler     = SPI_BAUDRATEPRESCALER_64;
+	spi_initd.Direction     = SPI_DIRECTION_2LINES;
+	spi_initd.CLKPhase      = SPI_PHASE_1EDGE;
+	spi_initd.CLKPolarity   = SPI_POLARITY_LOW;
+	spi_initd.CRC           = SPI_CRC_DISABLE;
+	spi_initd.CRCPolynomial = 7;
+	spi_initd.DataSize      = SPI_DATASIZE_8BIT;
+	spi_initd.SignBit       = SPI_DATA_MSB;
+	spi_initd.NSS           = SPI_NSS_SOFT;
+	spi_initd.TIMode        = SPI_TIMODE_DISABLE;
+	spi_initd.Mode = SPI_MODE_MASTER;
+	spi_initd.semid = SPI1DMA_SEM;
+	spi_initd.semlock = 0;
+	if((hspi = spi_init(SPI1_PORTID, &spi_initd)) == NULL){
+		syslog_0(LOG_ERROR, "spi_start initialize error !");
+	}
+
+	/* Init USB OTG Hard */
+	/* Set the LL Driver parameters */
+    USB_Data_Init.usb_otg_mode = USB_OTG_MODE_HOST;
+	USB_Data_Init.host_channels = 11;	/* HOST */
+	USB_Data_Init.dma_enable = 0;
+	USB_Data_Init.low_power_enable = 0;
+	USB_Data_Init.phy_itface = USB_PHY_EMBEDDED; 
+	USB_Data_Init.sof_enable = 0;
+	USB_Data_Init.speed = USB_SPEED_FULL;
+	USB_Data_Init.vbus_sensing_enable = 0;	/* HOST */
+	USB_Data_Init.lpm_enable = 0;
+	USB_Data_Init.use_external_vbus = 0;
+	husb = usbo_init(USB1_PORTID, &USB_Data_Init);
+
+	/*
+	 *  USB HOSTミドルウェア設定
+	 */
+	husbh = (USBH_HandleTypeDef *)malloc(sizeof(USBH_HandleTypeDef));
+	husbh->pSysData = husb;
+	tusbhInit(husbh, USBH_UserProcess, 0);
+#ifdef USE_MSC_FILE
+	psdev = SDMGetStorageDevice(MSC_DEVNO);
+	psdev->_sdev_local[1] = husbh;
+	SDeviceHead._get_datetime = get_fat_time;
+#endif
+
+	/*
+	 *  USB HOSTスタート
+	 */
+	tusbhStart(husbh);
+
+	i = 0;
+	while(msc_state != HOST_USER_CLASS_ACTIVE && i < 15){
+		syslog_2(LOG_NOTICE, " WAIT MSC READY(%d)(%d) !", msc_state, i);
+		dly_tsk(1000);
+		i++;
+	}
+	if(msc_state != HOST_USER_CLASS_ACTIVE)
+		syslog_0(LOG_NOTICE, "MSC INITIAL ERROR !");
+
+#ifndef USE_MSC_FILE
+	if(msc_state == HOST_USER_CLASS_ACTIVE && tusbhMscUnitIsReady(husbh, pdrv)){
+		unsigned char *p;
+		int j, bpb;
+		int SecPerCls, Rsv, NumFat, Fsize, RootDirC, RootSec, tsect;
+		p = (unsigned char *)sdbuffer;
+		for(i = 0 ; i < 1 ; i++){
+			status = tusbhMscRead(husbh, pdrv, i, (uint8_t *)sdbuffer, 1);
+			syslog_3(LOG_NOTICE, "## status(%d) i(%d) sdbuffer[%08x] ##", status, i, sdbuffer);
+			dly_tsk(300);
+			if(i == 0){
+				if(p[0x36] == 'F' && p[0x37] == 'A' && p[0x38] == 'T')
+					bpb = 0;
+				else{
+					bpb = p[0x1c6];
+					bpb |= p[0x1c7]<<8;
+					bpb |= p[0x1c8]<<16;
+					bpb |= p[0x1c9]<<24;
+				}
+			}
+			printf("\nsec(%d) ", i);
+			for(j = 0 ; j < 512 ; j++){
+				if((j % 16) == 0)
+					printf("\n%03x ", j);
+				printf("%02x ", p[j]);
+			}
+			printf("\n");
+		}
+		syslog_1(LOG_NOTICE, "## bpb(%08x) ##", bpb);
+		if(bpb != 0){
+			status = tusbhMscRead(husbh, pdrv, bpb, (uint8_t *)sdbuffer, 1);
+			syslog_3(LOG_NOTICE, "## status(%d) i(%d) sdbuffer[%08x] ##", status, bpb, sdbuffer);
+			dly_tsk(300);
+			printf("\nsec(%d) ", bpb);
+			for(j = 0 ; j < 512 ; j++){
+				if((j % 16) == 0)
+					printf("\n%03x ", j);
+				printf("%02x ", p[j]);
+			}
+			printf("\n");
+		}
+		SecPerCls = p[13];
+		Rsv = p[14] + (p[15] << 8);
+		NumFat = p[16];
+		RootDirC = p[17] + (p[18]<<8);
+		Fsize = p[22] + (p[23] << 8);
+		if(Fsize == 0){
+			Fsize = p[36] + (p[37] << 8);
+			RootSec = p[44] + (p[45] << 8) + (p[46] << 16) + (p[47] << 24);
+		}
+		else
+			RootSec = bpb + Rsv + (NumFat * Fsize);
+		tsect = p[32] + (p[33] << 8) + (p[34] << 16) + (p[35] << 24);
+		if(tsect == 0)
+			tsect = p[19] + (p[20] << 8) + (p[21] << 16) + (p[22] << 24);
+		syslog_4(LOG_NOTICE, "## SecPerCls(%d) Rsv(%d) NumFat(%d) RootDirC(%d) ##", SecPerCls, Rsv, NumFat, RootDirC);
+		syslog_3(LOG_NOTICE, "## Fsize(%d) RootSec(%d) totalsec(%d) ##", Fsize, RootSec, tsect);
+
+		for(i = 0 ; i < 2 ; i++){
+			status = tusbhMscRead(husbh, pdrv, (i+RootSec), (uint8_t *)sdbuffer, 1);
+			syslog_3(LOG_NOTICE, "## status(%d) i(%d) sdbuffer[%08x] ##", status, (i+RootSec), sdbuffer);
+			dly_tsk(300);
+			p = (unsigned char *)sdbuffer;
+			printf("\nsec(%d) ", (i+RootSec));
+			for(j = 0 ; j < 512 ; j++){
+				if((j % 16) == 0)
+					printf("\n%03x ", j);
+				printf("%02x ", p[j]);
+			}
+			printf("\n");
+		}
+	}
+#endif
+	hlcd = &LcdHandle;
+	hlcd->hspi = hspi;
+	hlcd->spi_lock= 0;
+	hlcd->cs_pin  = CS_PORT;
+	hlcd->rs_pin  = RS_PORT;
+	hlcd->rst_pin = RST_PORT;
+	hlcd->cs2_pin = CS2_PORT;
+	DrawProp.hlcd = hlcd;
+	lcd_initR(hlcd, INITR_BLACKTAB);
+	DrawProp.BackColor = ST7735_BLACK;
+	DrawProp.TextColor = ST7735_WHITE;
+	grapics_test(hlcd);
+#if 1	/* LOCAL DEFINE */
+	DrawProp.TextColor = ST7735_BLACK;
+	DrawProp.BackColor = ST7735_WHITE;
+	lcd_fillScreen(&DrawProp);
+	lcd_fillRect(hlcd, 0, 0, hlcd->_width, hlcd->_height/3, ST7735_BLUE);
+	DrawProp.TextColor = ST7735_WHITE;
+	DrawProp.BackColor = ST7735_BLUE;
+	DrawProp.pFont = &Font20;
+	lcd_DisplayStringAt(&DrawProp, 0, 20, (uint8_t *)"TBP TEST", CENTER_MODE);
+	DrawProp.TextColor = ST7735_BLACK;
+	DrawProp.BackColor = ST7735_WHITE;
+	DrawProp.pFont = &Font8;
+	lcd_DisplayStringAt(&DrawProp, 0, 80, (uint8_t *)"Helle World !", CENTER_MODE);
+	DrawProp.pFont = &Font12;
+	lcd_DisplayStringAt(&DrawProp, 0, 100, (uint8_t *)"Helle World !", CENTER_MODE);
+	DrawProp.pFont = &Font16;
+	lcd_DisplayStringAt(&DrawProp, 0, 120, (uint8_t *)"Helle World !", CENTER_MODE);
+
+	DrawProp.TextColor = ST7735_RED;
+	for(i = 20 ; i < 40 ; i++){
+		lcd_DrawCircle(&DrawProp, hlcd->_width/2, hlcd->_height/2+30, i);
+		if(i == 25)
+			i += 10;
+	}
+#endif	/* LOCAL DEFINE */
+	syslog_0(LOG_NOTICE, "LCD TEST END");
+	while(sens > 0){
+		wai_flg(SW_FLG, JS_MASK, TWF_ORW, &flgptn);
+		syslog_1(LOG_NOTICE, "## JS EVENT[%04x] ##", flgptn);
+		for(i = 0 ; i < NUM_JSPOSITION ; i++){
+			if(flgptn & (1<<i))
+				break;
+		}
+		if(i == NUM_JSPOSITION)
+			i = 0;
+#if 1	/* LOCAL DEFINE */
+		DrawProp.pFont = &Font12;
+		if(i == 0 || i == NUM_JSPOSITION)
+			lcd_DisplayStringAt(&DrawProp, 0, 100, (uint8_t *)"Helle World !", CENTER_MODE);
+		else
+			lcd_DisplayStringAt(&DrawProp, 0, 100, (uint8_t *)pos_str[i-1], CENTER_MODE);
+#else	/* LOCAL DEFINE */
+		syslog_1(LOG_NOTICE, "## event(%d) ##", i);
+#endif	/* LOCAL DEFINE */
+		sens--;
+	}
+#ifdef USE_MSC_FILE
+	syslog_0(LOG_NOTICE, "## STOP ##");
+	slp_tsk();
+#endif
+	spi_deinit(hspi);
+
+	syslog(LOG_NOTICE, "Sample program ends.");
+//	SVC_PERROR(ext_ker());
+}
+
+
+/*
+ *  ADC転送終了コールバック関数
+ */
+static void HAL_ADC_ConvCpltCallback2(ADC_Handle_t* hadc)
+{
+	isig_sem(ADCDMA_SEM);
+}
+
+/*
+ *  ジョイスティック監視タスク
+ */
+void stick_task(intptr_t exinf)
+{
+	ADC_Init_t     aInit;
+	ADC_ChannelConf_t sConfig;
+	ADC_Handle_t *hadc;
+	uint32_t event = 0;
+	int i;
+
+	/*
+	 *  ADC3初期化
+	 */
+	aInit.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV2;
+	aInit.Resolution = ADC_RESOLUTION_12B;
+	aInit.ScanConvMode = ADC_SCANMODE_DISABLE;
+//	aInit.ContinuousConvMode = ADC_CONTINUOUS_ENABLE;
+	aInit.ContinuousConvMode = ADC_CONTINUOUS_DISABLE;
+	aInit.DiscontinuousConvMode = ADC_DISCONTINUOUS_DISABLE;
+	aInit.NumDiscConversion = 0;
+	aInit.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
+	aInit.ExternalTrigConv = ADC_EXTERNALTRIGCONV_T1_CC1;
+	aInit.DataAlign = ADC_DATAALIGN_RIGHT;
+	aInit.NumConversion = 1;
+	aInit.DMAContinuousRequests = ADC_DMACONTINUOUS_ENABLE;
+	aInit.EOCSelection = ADC_EOC_SEQ_DISABLE;
+
+	if((hadc = adc_init(ADC3_PORTID, &aInit)) == NULL){
+		/* Initialization Error */
+		syslog_0(LOG_NOTICE, "## adc_init ERROR ##");
+	}
+	hadc->xfercallback = HAL_ADC_ConvCpltCallback2;
+
+	/*
+	 *  ADCチャネル設定
+	 */
+	sConfig.Channel = ADCx_CHANNEL;
+	sConfig.Rank = 1;
+//  sConfig.SamplingTime = ADC_SAMPLETIME_3CYCLES;
+	sConfig.SamplingTime = ADC_SAMPLETIME_480CYCLES;
+	sConfig.GpioBase = ADCx_CHANNEL_GPIO_PORT;
+	sConfig.GpioPin  = ADCx_CHANNEL_PINNO;
+	if(adc_setupchannel(hadc, &sConfig) != E_OK){
+		/* Channel Configuration Error */
+		syslog_0(LOG_NOTICE, "## adc_setupchannel ERROR ##");
+	}
+
+	for(;;){
+		uhADCxConvertedValue = 0;
+		/*
+		 *  ADC DMAスタート
+		 */
+		if(adc_start_dma(hadc, (uint32_t*)&uhADCxConvertedValue, 1) != E_OK){
+			/* Start Conversation Error */
+			syslog_0(LOG_NOTICE, "## adc_start_dma ERROR ##");
+		}
+		while(hadc->status == ADC_STATUS_BUSY){
+ 			twai_sem(ADCDMA_SEM, 10);
+		}
+		adc_end_dma(hadc);
+		for(i = 0 ; i < (NUM_JSPOSITION-1) ; i++){
+			if(uhADCxConvertedValue < pos_tbl[i][0]){
+				event = pos_tbl[i][1];
+				set_flg(SW_FLG, event);
+				break;
+			}
+		}
+		if(i == 5 && event != JS_OFF){
+			event = JS_OFF;
+			set_flg(SW_FLG, JS_OFF);
+		}
+  		dly_tsk(50);
+	}
+	syslog_2(LOG_NOTICE, "## STOP[%08x] (%d) ##", &uhADCxConvertedValue, hadc->status);
+	slp_tsk();
+}
+
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/OBJ/STM32F767NUCLEO144_GCC/lcdshield/lcdshield.cfg
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/OBJ/STM32F767NUCLEO144_GCC/lcdshield/lcdshield.cfg	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/OBJ/STM32F767NUCLEO144_GCC/lcdshield/lcdshield.cfg	(revision 457)
@@ -0,0 +1,54 @@
+/*
+ *  $Id$
+ */
+
+/*
+ *  LCDシールドのコンフィギュレーションファイル
+ */
+INCLUDE("target_timer.cfg");
+INCLUDE("syssvc/syslog.cfg");
+INCLUDE("syssvc/banner.cfg");
+INCLUDE("syssvc/serial.cfg");
+INCLUDE("syssvc/logtask.cfg");
+INCLUDE("syssvc/tlsf.cfg");
+INCLUDE("monitor/monitor.cfg");
+INCLUDE("pdic/stm32f7xx/device.cfg");
+INCLUDE("usb/host/tusbh.cfg");
+INCLUDE("files/storagedevice.cfg");
+INCLUDE("files/ff/fatfs.cfg");
+
+#include "device.h"
+#include "spi.h"
+#include "adc.h"
+#include "usb_otg.h"
+#include "lcdshield.h"
+
+ATT_INI({ TA_NULL, heap_param, heap_init });
+ATT_INI({ TA_NULL, sw_int, setup_sw_func });
+ATT_INI({ TA_NULL, 0, device_info_init });
+
+CRE_TSK(MAIN_TASK, { TA_ACT, 0, main_task, MAIN_PRIORITY, STACK_SIZE, NULL });
+CRE_TSK(STICK_TASK, { TA_ACT, 0, stick_task, HIGH_PRIORITY, STACK_SIZE, NULL });
+
+CRE_FLG(SW_FLG,{TA_CLR, 0});
+
+CRE_SEM(ADCDMA_SEM, { TA_TPRI, 0, 1 });
+CRE_SEM(SPI1DMA_SEM, { TA_TPRI, 0, 1 });
+
+ATT_ISR({TA_NULL, SPI1_PORTID, INTNO_SPI, spi_isr, 1 });
+CFG_INT(INTNO_SPI, { TA_ENAINT | INTATR_SPI, INTPRI_SPI });
+
+ATT_ISR({TA_NULL, DMA2STM2_SID, INTNO_DMARX, stream_dma_isr, 1 });
+CFG_INT(INTNO_DMARX, { TA_ENAINT | INTATR_DMARX, INTPRI_DMARX });
+ATT_ISR({TA_NULL, DMA2STM3_SID, INTNO_DMATX, stream_dma_isr, 1 });
+CFG_INT(INTNO_DMATX, { TA_ENAINT | INTATR_DMATX, INTPRI_DMATX });
+ATT_ISR({TA_NULL, DMA2STM0_SID, INTNO_DMAADC, stream_dma_isr, 1 });
+CFG_INT(INTNO_DMAADC, { TA_ENAINT | INTATR_DMAADC, INTPRI_DMAADC });
+DEF_INH(INHNO_ADC, { TA_NULL, adc_int_handler });
+CFG_INT(INTNO_ADC, { TA_ENAINT | INTATR_ADC, INTPRI_ADC });
+
+ATT_ISR({TA_NULL, USB1_PORTID, INTNO_USBFS, usb_otg_isr, 1 });
+CFG_INT(INTNO_USBFS, { TA_ENAINT | INTATR_USBFS, INTPRI_USBFS });
+ATT_ISR({TA_NULL, USB1_PORTID, INTNO_FSWKUP, usb_otg_wkup_isr, 1 });
+CFG_INT(INTNO_FSWKUP, { TA_ENAINT | INTATR_FSWKUP, INTPRI_FSWKUP });
+
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/OBJ/STM32F767NUCLEO144_GCC/lcdshield/lcdshield.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/OBJ/STM32F767NUCLEO144_GCC/lcdshield/lcdshield.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/OBJ/STM32F767NUCLEO144_GCC/lcdshield/lcdshield.h	(revision 457)
@@ -0,0 +1,177 @@
+/*
+ *  TOPPERS/ASP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Advanced Standard Profile Kernel
+ *
+ *  Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
+ *                              Toyohashi Univ. of Technology, JAPAN
+ *  Copyright (C) 2004-2010 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ *  Copyright (C) 2015-2016 by TOPPERS PROJECT Educational Working Group.
+ *
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ *
+ *  $Id$
+ */
+
+/*
+ *  LCDシールド制御プログラムのヘッダファイル
+ */
+
+/*
+ *  ターゲット依存の定義
+ */
+#include "target_test.h"
+#include "usb_otg.h"
+#include "tusbh_msc.h"
+#include "glcd_disp.h"
+
+/*
+ *  各タスクの優先度の定義
+ */
+
+#define MAIN_PRIORITY	9		/* メインタスクの優先度 */
+								/* HIGH_PRIORITYより高くすること */
+
+#define HIGH_PRIORITY	6		/* 並行実行されるタスクの優先度 */
+#define MID_PRIORITY	10
+#define LOW_PRIORITY	11
+
+/*
+ *  ターゲットに依存する可能性のある定数の定義
+ */
+
+#ifndef TASK_PORTID
+#define	TASK_PORTID		1			/* 文字入力するシリアルポートID */
+#endif /* TASK_PORTID */
+
+#ifndef STACK_SIZE
+#define	STACK_SIZE		4096		/* タスクのスタックサイズ */
+#endif /* STACK_SIZE */
+
+//#define SPISDCARD_PORTID    0
+
+#define PORT_HIGH      1
+#define PORT_LOW       0 
+
+#define GPIO_OTYPE     GPIO_OTYPE_PP
+#ifndef GPIO_SELECT_PDOWN
+#define GPIO_PULLMODE  GPIO_PULLUP
+#else
+#define GPIO_PULLMODE  GPIO_PULLDOWN
+#endif
+
+#define BUFFERSIZE      140
+
+#define INHNO_SPI   IRQ_VECTOR_SPI1	/* 割込みハンドラ番号 */
+#define INTNO_SPI   IRQ_VECTOR_SPI1	/* 割込み番号 */
+#define INTPRI_SPI  -4          /* 割込み優先度 */
+#define INTATR_SPI  TA_EDGE     /* 割込み属性 */
+
+#define INHNO_DMARX   IRQ_VECTOR_DMA2_STREAM2	/* 割込みハンドラ番号 */
+#define INTNO_DMARX   IRQ_VECTOR_DMA2_STREAM2	/* 割込み番号 */
+#define INTPRI_DMARX  -4          /* 割込み優先度 */
+#define INTATR_DMARX  TA_EDGE     /* 割込み属性 */
+
+#define INHNO_DMATX   IRQ_VECTOR_DMA2_STREAM3	/* 割込みハンドラ番号 */
+#define INTNO_DMATX   IRQ_VECTOR_DMA2_STREAM3	/* 割込み番号 */
+#define INTPRI_DMATX  -4          /* 割込み優先度 */
+#define INTATR_DMATX  TA_EDGE     /* 割込み属性 */
+
+
+#define INHNO_USBFS   IRQ_VECTOR_OTG_FS	/* 割込みハンドラ番号 */
+#define INTNO_USBFS   IRQ_VECTOR_OTG_FS	/* 割込み番号 */
+#define INTPRI_USBFS  -5			/* 割込み優先度 */
+#define INTATR_USBFS  0				/* 割込み属性 */
+
+#define INHNO_FSWKUP  IRQ_VECTOR_OTG_FS_WKUP	/* 割込みハンドラ番号 */
+#define INTNO_FSWKUP  IRQ_VECTOR_OTG_FS_WKUP	/* 割込み番号 */
+#define INTPRI_FSWKUP -10			/* 割込み優先度 */
+#define INTATR_FSWKUP 0				/* 割込み属性 */
+
+
+#define INHNO_ADC     IRQ_VECTOR_ADC	/* 割込みハンドラ番号 */
+#define INTNO_ADC     IRQ_VECTOR_ADC	/* 割込み番号 */
+#define INTPRI_ADC    -5          /* 割込み優先度 */
+#define INTATR_ADC    0           /* 割込み属性 */
+
+#define INHNO_DMAADC  IRQ_VECTOR_DMA2_STREAM0	/* 割込みハンドラ番号 */
+#define INTNO_DMAADC  IRQ_VECTOR_DMA2_STREAM0	/* 割込み番号 */
+#define INTPRI_DMAADC -4          /* 割込み優先度 */
+#define INTATR_DMAADC TA_EDGE     /* 割込み属性 */
+
+/* Definition for ADCx's Channel */
+#define ADCx_CHANNEL                    ADC_CHANNEL_9
+
+/* Definition for ADCx Channel Pin */
+#define ADCx_CHANNEL_GPIO_PORT          TADR_GPIOF_BASE
+#define ADCx_CHANNEL_PINNO              3
+
+#define NUM_USBH_EVT1   64
+#define NUM_USBH_EVT2   16
+
+#define NUM_JSPOSITION 6
+
+#define JS_OFF      0x01
+#define JS_ON       0x02
+#define JS_UP       0x04
+#define JS_DOWN     0x08
+#define JS_LEFT     0x10
+#define JS_RIGHT    0x20
+#define JS_MASK     0x3F
+
+#define CS_PORT     10
+#define RST_PORT    9
+#define RS_PORT     8
+#define CS2_PORT    4
+
+#define cs_set(sw)  digitalWrite(CS_PORT, sw)
+#define rs_set(sw)  digitalWrite(RS_PORT, sw)
+#define rst_set(sw) digitalWrite(RST_PORT, sw)
+#define cs2_set(sw) digitalWrite(CS2_PORT, sw)
+
+#ifndef TOPPERS_MACRO_ONLY
+/*
+ *  ヒープ領域の設定
+ */
+extern uint32_t heap_param[2];
+
+/*
+ *  関数のプロトタイプ宣言
+ */
+extern void	main_task(intptr_t exinf);
+extern void stick_task(intptr_t exinf);
+
+extern void heap_init(intptr_t exinf);
+extern void sw_int(void);
+extern void device_info_init(intptr_t exinf);
+
+
+#endif /* TOPPERS_MACRO_ONLY */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/OBJ/STM32F767NUCLEO144_GCC/lcdshield/topamelogo.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/OBJ/STM32F767NUCLEO144_GCC/lcdshield/topamelogo.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/OBJ/STM32F767NUCLEO144_GCC/lcdshield/topamelogo.h	(revision 457)
@@ -0,0 +1,798 @@
+const unsigned char topamelogo[12726] = {
+	 0x42, 0x4d, 0xd6, 0x23, 0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 
+	 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x42, 0x00,  0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xfd,  0xff, 0xff, 0xfd, 0xff, 0xff, 0xfd, 0xff, 0xff, 
+	 0xfd, 0xff, 0xff, 0xfd, 0xff, 0xff, 0xfd, 0xff,  0xff, 0xfd, 0xff, 0xff, 0xfd, 0xff, 0xff, 0xfd, 
+	 0xff, 0xff, 0xfd, 0xff, 0xff, 0xfd, 0xff, 0xff,  0xfd, 0xff, 0xff, 0xfd, 0xff, 0xff, 0xfd, 0xff, 
+	 0xff, 0xfd, 0xff, 0xff, 0xfd, 0xff, 0xff, 0xff,  0xff, 0xf9, 0xf7, 0xfb, 0xff, 0xff, 0xff, 0xe3, 
+	 0xe1, 0xe5, 0xff, 0xfd, 0xff, 0xff, 0xff, 0xff,  0xef, 0xef, 0xf3, 0xff, 0xff, 0xff, 0xff, 0xfd, 
+	 0xff, 0xff, 0xfd, 0xff, 0xff, 0xfd, 0xff, 0xff,  0xfd, 0xff, 0xff, 0xfd, 0xff, 0xff, 0xfd, 0xff, 
+	 0xff, 0xfd, 0xff, 0xff, 0xfd, 0xff, 0xfd, 0xfd,  0xff, 0xfd, 0xfd, 0xff, 0xfd, 0xfb, 0xff, 0xfd, 
+	 0xfb, 0xff, 0xfd, 0xfd, 0xff, 0xfd, 0xfd, 0xff,  0xff, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfd, 
+	 0xff, 0xff, 0xfd, 0xff, 0xff, 0xfd, 0xff, 0xff,  0xfd, 0xff, 0xff, 0xfd, 0xff, 0xff, 0xfd, 0xff, 
+	 0xff, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfd,  0xff, 0xff, 0xfd, 0xff, 0xff, 0xfd, 0xff, 0xff, 
+	 0xfd, 0xff, 0xff, 0xfd, 0xff, 0xff, 0xfd, 0xff,  0xff, 0xfd, 0xff, 0xff, 0xfd, 0xff, 0xff, 0xfd, 
+	 0xff, 0xff, 0xfd, 0xff, 0xff, 0xfd, 0xff, 0xff,  0xfd, 0xff, 0xff, 0xfd, 0xff, 0xff, 0xfd, 0xff, 
+	 0xff, 0xfd, 0xff, 0xff, 0xfd, 0xff, 0xfd, 0xfd,  0xff, 0xfd, 0xfb, 0xff, 0xf1, 0xf1, 0xf5, 0x4f, 
+	 0x4d, 0x51, 0xc5, 0xc3, 0xc7, 0xf9, 0xf7, 0xfb,  0xff, 0xff, 0xff, 0xfb, 0xfb, 0xff, 0xff, 0xfd, 
+	 0xff, 0xff, 0xfd, 0xff, 0xff, 0xfd, 0xff, 0xff,  0xfd, 0xff, 0xff, 0xfd, 0xff, 0xff, 0xfd, 0xff, 
+	 0xff, 0xfd, 0xff, 0xff, 0xfd, 0xff, 0xfd, 0xfd,  0xff, 0xfd, 0xfd, 0xff, 0xfd, 0xfb, 0xff, 0xfd, 
+	 0xfb, 0xff, 0xfd, 0xfd, 0xff, 0xfd, 0xfd, 0xff,  0xff, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfd, 
+	 0xff, 0xff, 0xfd, 0xff, 0xff, 0xfd, 0xff, 0xff,  0xfd, 0xff, 0xff, 0xfd, 0xff, 0xff, 0xfd, 0xff, 
+	 0xff, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfd, 
+	 0xff, 0xff, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf5,  0xf9, 0xff, 0xfd, 0xff, 0xbb, 0xbb, 0xbd, 0x61, 
+	 0x61, 0x63, 0xc9, 0x93, 0x9d, 0xff, 0xe1, 0xeb,  0xe9, 0xff, 0xff, 0xe9, 0xff, 0xff, 0xff, 0xf9, 
+	 0xff, 0xff, 0xfb, 0xff, 0xff, 0xf9, 0xff, 0xff,  0xef, 0xf5, 0xff, 0xfb, 0xff, 0xff, 0xfb, 0xff, 
+	 0xf3, 0xff, 0xff, 0xf3, 0xff, 0xff, 0xff, 0xf9,  0xfd, 0xff, 0xfd, 0xff, 0xf7, 0xed, 0xf1, 0xff, 
+	 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf9, 0xfd,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfd, 
+	 0xff, 0xff, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xfd, 0xff, 0xff, 0xff, 0xfd,  0xff, 0xff, 0xfd, 0xff, 0x17, 0x17, 0x19, 0x29, 
+	 0x29, 0x2b, 0x35, 0x00, 0x09, 0xff, 0xf7, 0xff,  0xe9, 0xff, 0xff, 0xdb, 0xf5, 0xf3, 0xff, 0xfb, 
+	 0xff, 0xff, 0xed, 0xf3, 0xff, 0xfb, 0xff, 0xff,  0xfb, 0xff, 0xff, 0xf7, 0xfd, 0xff, 0xf9, 0xff, 
+	 0xeb, 0xf9, 0xf9, 0xf3, 0xff, 0xff, 0xff, 0xf5,  0xf9, 0xff, 0xfd, 0xff, 0xc3, 0xb9, 0xbd, 0xed, 
+	 0xe3, 0xe7, 0xfd, 0xf7, 0xfb, 0xfb, 0xf7, 0xf9,  0xf5, 0xf5, 0xf7, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfd, 
+	 0xff, 0xff, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xfd, 0xff, 0xff, 0xfd, 0xff, 0xff, 0xff, 0xfb,  0xff, 0xc5, 0xb1, 0xb7, 0x5b, 0x5b, 0x5f, 0x3b, 
+	 0x3b, 0x3f, 0x55, 0x65, 0x65, 0xd5, 0xe5, 0xe7,  0xf1, 0xff, 0xff, 0xed, 0xff, 0xff, 0xff, 0xfd, 
+	 0xff, 0xff, 0xfd, 0xff, 0xeb, 0xff, 0xff, 0xe7,  0xfb, 0xfb, 0xff, 0xfd, 0xff, 0xf7, 0xf1, 0xf7, 
+	 0xfd, 0xff, 0xff, 0xef, 0xf1, 0xf5, 0xff, 0xfd,  0xff, 0x59, 0x4f, 0x53, 0x3f, 0x37, 0x3b, 0xff, 
+	 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf9, 0xfd,  0xff, 0xff, 0xff, 0xef, 0xef, 0xf1, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfd, 
+	 0xff, 0xff, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xfd, 0xff, 0xff, 
+	 0xfd, 0xfd, 0xff, 0xfd, 0xfd, 0xff, 0xff, 0xef,  0xf5, 0x45, 0x31, 0x37, 0x39, 0x39, 0x3d, 0x35, 
+	 0x35, 0x39, 0x31, 0x41, 0x43, 0x06, 0x15, 0x17,  0xdf, 0xef, 0xf1, 0xed, 0xfd, 0xff, 0xf9, 0xf1, 
+	 0xf5, 0xff, 0xfd, 0xff, 0xe9, 0xfd, 0xfd, 0xe3,  0xf7, 0xf7, 0xf1, 0xeb, 0xef, 0xff, 0xfd, 0xff, 
+	 0xf3, 0xf7, 0xf9, 0xf3, 0xf7, 0xf9, 0x4d, 0x41,  0x45, 0x61, 0x55, 0x59, 0x69, 0x5f, 0x63, 0xfd, 
+	 0xf3, 0xf7, 0xf9, 0xf3, 0xf7, 0xff, 0xfd, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfd, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xfd, 0xfd, 0xff, 
+	 0xfd, 0xfd, 0xff, 0xfd, 0xfd, 0xff, 0xff, 0xf9,  0xff, 0x5f, 0x43, 0x51, 0x6f, 0x2f, 0x41, 0x6f, 
+	 0x2f, 0x41, 0x3d, 0x43, 0x4b, 0x49, 0x4f, 0x57,  0xbb, 0xb7, 0xbf, 0xff, 0xfb, 0xff, 0xf7, 0xfd, 
+	 0xff, 0xf9, 0xff, 0xff, 0xff, 0xfb, 0xff, 0xff,  0xfb, 0xff, 0xff, 0xf3, 0xff, 0xff, 0xdf, 0xed, 
+	 0xe1, 0xdf, 0xe7, 0x4b, 0x49, 0x51, 0x53, 0x49,  0x4d, 0x3f, 0x35, 0x39, 0x6d, 0x65, 0x69, 0xff, 
+	 0xfd, 0xff, 0xfb, 0xf7, 0xf9, 0xfd, 0xf7, 0xfb,  0xff, 0xff, 0xff, 0xfd, 0xfd, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfd, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xfd, 0xfd, 0xff, 
+	 0xfd, 0xfd, 0xff, 0xfb, 0xfb, 0xfd, 0xff, 0xe9,  0xf5, 0x4d, 0x31, 0x3d, 0x79, 0x39, 0x4d, 0x77, 
+	 0x37, 0x49, 0x19, 0x1f, 0x27, 0x3d, 0x43, 0x49,  0x2b, 0x27, 0x2f, 0xff, 0xfd, 0xff, 0xf7, 0xfd, 
+	 0xff, 0xe9, 0xef, 0xf7, 0xf5, 0xe7, 0xf1, 0xfd,  0xef, 0xf9, 0xff, 0xf7, 0xff, 0x97, 0x6b, 0x7b, 
+	 0x4d, 0x4b, 0x53, 0x47, 0x45, 0x4d, 0x4b, 0x3f,  0x43, 0x4f, 0x45, 0x49, 0x9f, 0x95, 0x99, 0xff, 
+	 0xf5, 0xf9, 0xff, 0xfd, 0xff, 0xff, 0xfb, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xfd, 0xff, 0xff, 0xfd, 0xff, 0xff, 0xfb, 0xff, 
+	 0xfd, 0xfb, 0xfd, 0xfd, 0xfb, 0xfd, 0xc7, 0xad,  0xbb, 0x57, 0x3d, 0x4b, 0x49, 0x27, 0x37, 0x5f, 
+	 0x3d, 0x4d, 0x2f, 0x35, 0x3f, 0x47, 0x4d, 0x57,  0x71, 0x4d, 0x5d, 0x63, 0x3f, 0x4f, 0xf7, 0xfb, 
+	 0xff, 0xfb, 0xfd, 0xff, 0xff, 0xf9, 0xff, 0xe1,  0xc1, 0xd1, 0x0b, 0x11, 0x19, 0x4d, 0x53, 0x5d, 
+	 0x3f, 0x43, 0x4b, 0x39, 0x3d, 0x45, 0x37, 0x2d,  0x31, 0x53, 0x47, 0x4b, 0xd3, 0xc9, 0xcd, 0xfd, 
+	 0xf3, 0xf7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xfd, 0xff, 0xff, 0xfd, 0xff, 0xff, 0xfb, 0xff, 
+	 0xfd, 0xfb, 0xfd, 0xfd, 0xf9, 0xfd, 0xa3, 0x89,  0x97, 0x53, 0x3b, 0x49, 0x63, 0x43, 0x51, 0x3f, 
+	 0x1d, 0x2d, 0xd7, 0xdd, 0xe7, 0x00, 0x04, 0x0b,  0x59, 0x35, 0x45, 0x73, 0x4f, 0x5f, 0x97, 0x99, 
+	 0xa3, 0xf1, 0xf5, 0xff, 0x75, 0x57, 0x65, 0x7f,  0x5f, 0x6f, 0x49, 0x51, 0x59, 0x4d, 0x55, 0x5d, 
+	 0xb7, 0xbb, 0xc5, 0x43, 0x45, 0x4f, 0x45, 0x39,  0x3d, 0x4f, 0x43, 0x47, 0xff, 0xfb, 0xff, 0xff, 
+	 0xfd, 0xff, 0xff, 0xff, 0xff, 0xf3, 0xef, 0xf1,  0xff, 0xff, 0xff, 0xfb, 0xfb, 0xfd, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfd, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xfd, 0xff, 0xff,  0xfb, 0xff, 0xff, 0xff, 0xff, 0xfd, 0xf9, 0xfd, 
+	 0xff, 0xfd, 0xff, 0xfb, 0xf9, 0xfb, 0x79, 0x69,  0x75, 0x5b, 0x4b, 0x57, 0x00, 0x59, 0x51, 0x71, 
+	 0xe1, 0xd9, 0xa7, 0xe7, 0xe7, 0x00, 0x09, 0x07,  0x6d, 0x37, 0x4b, 0x63, 0x2f, 0x41, 0x4f, 0x41, 
+	 0x4d, 0x35, 0x27, 0x33, 0x3b, 0x55, 0x5b, 0x31,  0x4b, 0x51, 0x00, 0x4b, 0x3d, 0x61, 0xf9, 0xeb, 
+	 0xaf, 0xbb, 0xc3, 0x3d, 0x47, 0x4f, 0x49, 0x3f,  0x43, 0x27, 0x1d, 0x21, 0xff, 0xfd, 0xff, 0xff, 
+	 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xf9, 0xf9, 0xfb, 0xfd, 0xfd, 
+	 0xff, 0xfd, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xfd, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xfb, 0xff, 0xff, 0xff, 0xff, 0xf5,  0xf1, 0xf5, 0xf9, 0xf7, 0xf9, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xf5, 0xf3, 0xf5, 0x75, 0x65,  0x73, 0x45, 0x35, 0x41, 0x00, 0x39, 0x31, 0x7f, 
+	 0xed, 0xe5, 0x95, 0xd7, 0xd5, 0x00, 0x0f, 0x0d,  0x5d, 0x27, 0x3b, 0x61, 0x2d, 0x3f, 0x43, 0x35, 
+	 0x41, 0x4b, 0x3d, 0x49, 0x15, 0x2f, 0x35, 0x31,  0x4b, 0x51, 0x6f, 0xff, 0xf9, 0x4f, 0xe7, 0xd9, 
+	 0xbf, 0xcb, 0xd3, 0x3d, 0x47, 0x4f, 0x55, 0x4b,  0x4f, 0xb3, 0xa7, 0xab, 0xf3, 0xe9, 0xed, 0xff, 
+	 0xf9, 0xfd, 0xff, 0xff, 0xff, 0xfd, 0xf9, 0xfb,  0xef, 0xef, 0xf1, 0xff, 0xff, 0xff, 0xfd, 0xfd, 
+	 0xff, 0xfd, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xfd, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf9, 0xf7, 
+	 0xf9, 0xfb, 0xf9, 0xfb, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xfd, 0xf9, 0xfb, 0xff, 0xff, 0xff, 
+	 0xfd, 0xf9, 0xfb, 0xff, 0xfb, 0xff, 0x77, 0x65,  0x71, 0x63, 0x51, 0x5b, 0x53, 0xd1, 0xc5, 0x81, 
+	 0xff, 0xf3, 0xc5, 0xdf, 0xe1, 0x09, 0x23, 0x27,  0x65, 0x41, 0x4f, 0x67, 0x43, 0x51, 0x33, 0x1b, 
+	 0x27, 0x69, 0x51, 0x5d, 0x53, 0x55, 0x5d, 0x19,  0x1d, 0x25, 0x61, 0xf5, 0xe5, 0x4d, 0xe1, 0xd1, 
+	 0xab, 0xb3, 0xb9, 0x4b, 0x53, 0x59, 0x37, 0x2d,  0x31, 0xff, 0xfb, 0xff, 0xff, 0xf9, 0xfd, 0xff, 
+	 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xfb, 0xfb, 0xfd, 0xff, 0xff, 0xff, 0xfd, 0xfd, 
+	 0xff, 0xfd, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xfd, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xfd, 0xff, 0xff, 0xff, 
+	 0xff, 0xfd, 0xf9, 0xfd, 0xf5, 0xf1, 0xf3, 0xff,  0xf9, 0xfd, 0xff, 0xfd, 0xff, 0xff, 0xfd, 0xff, 
+	 0xfb, 0xf7, 0xf9, 0xff, 0xff, 0xff, 0x7d, 0x6b,  0x77, 0x73, 0x61, 0x6d, 0x7b, 0xf9, 0xed, 0x00, 
+	 0x61, 0x55, 0x9b, 0xb3, 0xb7, 0x95, 0xaf, 0xb1,  0xf5, 0xcf, 0xdd, 0xff, 0xdf, 0xed, 0xff, 0xf9, 
+	 0xff, 0xfb, 0xe1, 0xed, 0xbd, 0xc1, 0xc7, 0x91,  0x95, 0x9d, 0x00, 0x75, 0x65, 0x75, 0xff, 0xf9, 
+	 0x79, 0x81, 0x87, 0x31, 0x39, 0x41, 0x5f, 0x53,  0x57, 0xf5, 0xe9, 0xed, 0xff, 0xfd, 0xff, 0xff, 
+	 0xfd, 0xff, 0xf7, 0xf3, 0xf5, 0xfb, 0xf5, 0xf9,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfd, 0xfd, 
+	 0xff, 0xfd, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xfd, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xfd, 0xff, 0xff, 0xfd, 0xff, 0xf9, 0xf5, 
+	 0xf9, 0xff, 0xff, 0xff, 0xfd, 0xf9, 0xfb, 0xff,  0xfd, 0xff, 0xff, 0xff, 0xff, 0xf9, 0xf1, 0xf5, 
+	 0xfb, 0xf3, 0xf7, 0xff, 0xf9, 0xfd, 0xaf, 0x8d,  0x95, 0x39, 0x17, 0x21, 0xbd, 0xe7, 0xe3, 0xd3, 
+	 0xfd, 0xf9, 0xff, 0xe3, 0xed, 0xff, 0xf7, 0xff,  0xfb, 0xff, 0xff, 0xfb, 0xff, 0xff, 0xff, 0xfb, 
+	 0xff, 0xff, 0xf3, 0xf9, 0xff, 0xf1, 0xfb, 0xff,  0xf9, 0xff, 0xdd, 0xff, 0xfd, 0x8f, 0xb1, 0xaf, 
+	 0x2d, 0x25, 0x29, 0x4b, 0x43, 0x47, 0xfb, 0xef,  0xf3, 0xf7, 0xeb, 0xef, 0xfb, 0xf1, 0xf5, 0xff, 
+	 0xf7, 0xfb, 0xff, 0xfd, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xef, 0xef, 0xf1, 0xfd, 0xfd, 
+	 0xff, 0xfd, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xfd, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xfd, 0xff, 0xff, 0xfd, 0xff, 0xfb, 0xf7, 
+	 0xfb, 0xff, 0xff, 0xff, 0xff, 0xfb, 0xff, 0xf1,  0xeb, 0xef, 0xff, 0xfd, 0xff, 0xff, 0xfb, 0xfd, 
+	 0xff, 0xff, 0xff, 0xfb, 0xf5, 0xf7, 0x3d, 0x1b,  0x25, 0x85, 0x63, 0x6d, 0xc9, 0xf3, 0xef, 0xdd, 
+	 0xff, 0xff, 0xff, 0xf1, 0xfb, 0xff, 0xf9, 0xff,  0xf3, 0xf9, 0xfb, 0xef, 0xf3, 0xf7, 0xff, 0xfb, 
+	 0xff, 0xff, 0xfb, 0xff, 0xff, 0xf1, 0xfb, 0xff,  0xf5, 0xff, 0xcb, 0xed, 0xeb, 0xe1, 0xff, 0xff, 
+	 0x89, 0x7f, 0x83, 0x1d, 0x13, 0x19, 0xfd, 0xf1,  0xf5, 0xff, 0xfd, 0xff, 0xff, 0xf5, 0xf9, 0xff, 
+	 0xfd, 0xff, 0xfb, 0xf5, 0xf9, 0xfb, 0xf5, 0xf9,  0xff, 0xff, 0xff, 0xfd, 0xfd, 0xff, 0xfd, 0xfd, 
+	 0xff, 0xfd, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xfd, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xfd, 0xfd, 0xff,  0xff, 0xfd, 0xff, 0xff, 0xfb, 0xff, 0xff, 0xff, 
+	 0xff, 0xe1, 0xdd, 0xe1, 0xff, 0xff, 0xff, 0xc3,  0xbd, 0xc1, 0x79, 0x71, 0x75, 0x63, 0x5d, 0x5f, 
+	 0x9b, 0x95, 0x97, 0xb1, 0xa9, 0xad, 0x73, 0x41,  0x4b, 0xe7, 0xb3, 0xbd, 0xdd, 0xf9, 0xf5, 0xe1, 
+	 0xfb, 0xf9, 0xff, 0xf9, 0xfd, 0xff, 0xf5, 0xf9,  0xdd, 0xff, 0xff, 0xdb, 0xff, 0xff, 0xff, 0xf9, 
+	 0xfd, 0xf9, 0xef, 0xf3, 0xfb, 0xff, 0xff, 0xf1,  0xf7, 0xf7, 0xff, 0xff, 0xff, 0xfb, 0xfb, 0xfd, 
+	 0xbf, 0xa3, 0xa9, 0x65, 0x49, 0x51, 0xe3, 0xd7,  0xdb, 0xf5, 0xe9, 0xed, 0xbf, 0xb5, 0xb9, 0xd3, 
+	 0xc9, 0xcd, 0xf3, 0xed, 0xf1, 0xff, 0xff, 0xff,  0xf1, 0xf1, 0xf3, 0xfd, 0xfd, 0xff, 0xfd, 0xfd, 
+	 0xff, 0xfd, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xfd, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfd, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xfd, 0xfd, 0xff,  0xff, 0xfb, 0xff, 0xff, 0xfb, 0xff, 0xc1, 0xbf, 
+	 0xc1, 0x11, 0x0d, 0x11, 0x5b, 0x55, 0x59, 0x53,  0x4f, 0x51, 0x51, 0x49, 0x4d, 0x57, 0x51, 0x53, 
+	 0x57, 0x4f, 0x53, 0x2d, 0x27, 0x29, 0x6f, 0x3d,  0x47, 0xef, 0xbb, 0xc5, 0xdd, 0xf9, 0xf5, 0xe7, 
+	 0xff, 0xff, 0xff, 0xfd, 0xff, 0xff, 0xfd, 0xff,  0xd5, 0xff, 0xf9, 0xdd, 0xff, 0xff, 0xff, 0xfd, 
+	 0xff, 0xff, 0xfd, 0xff, 0xf7, 0xfd, 0xff, 0xf5,  0xfb, 0xfd, 0xfb, 0xfb, 0xfd, 0xeb, 0xeb, 0xed, 
+	 0xd9, 0xbd, 0xc3, 0x61, 0x45, 0x4d, 0x73, 0x69,  0x6d, 0x61, 0x55, 0x59, 0x5b, 0x51, 0x55, 0x55, 
+	 0x4b, 0x4f, 0x53, 0x4f, 0x51, 0x45, 0x41, 0x43,  0x6d, 0x6d, 0x6f, 0xf9, 0xf9, 0xfb, 0xfd, 0xfd, 
+	 0xff, 0xfd, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xfd, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf3, 0xff,  0xfb, 0xef, 0xfd, 0xf7, 0xfb, 0xfd, 0xfb, 0xff, 
+	 0xff, 0xff, 0xf3, 0xe3, 0xf3, 0xff, 0xf5, 0xff,  0xdb, 0xc7, 0xe3, 0x23, 0x0f, 0x29, 0x57, 0x4b, 
+	 0x63, 0x4f, 0x43, 0x5b, 0x47, 0x43, 0x4f, 0x3f,  0x3b, 0x49, 0x97, 0x8f, 0xa1, 0xa5, 0x9d, 0xaf, 
+	 0xa7, 0x95, 0xb7, 0x1f, 0x0d, 0x2f, 0x47, 0x39,  0x49, 0xcf, 0xc1, 0xd3, 0xe7, 0xff, 0xf1, 0xef, 
+	 0xff, 0xf7, 0xe3, 0xfb, 0xef, 0xef, 0xff, 0xfb,  0xff, 0xed, 0xff, 0xff, 0xf5, 0xff, 0xff, 0xeb, 
+	 0xff, 0xff, 0xf5, 0xff, 0xef, 0xff, 0xfb, 0xe7,  0xff, 0xf3, 0xef, 0xff, 0xf7, 0xe3, 0xfb, 0xeb, 
+	 0xdb, 0xcd, 0xdf, 0x45, 0x39, 0x49, 0x77, 0x6b,  0x85, 0x9f, 0x93, 0xad, 0xbb, 0xb3, 0xc5, 0x7d, 
+	 0x77, 0x87, 0x45, 0x3d, 0x51, 0x3f, 0x35, 0x49,  0x4b, 0x37, 0x53, 0x57, 0x43, 0x61, 0x5d, 0x43, 
+	 0x5d, 0xf7, 0xdd, 0xf7, 0xfd, 0xed, 0xf5, 0xfd,  0xed, 0xf5, 0xf7, 0xf9, 0xf7, 0xfd, 0xff, 0xfd, 
+	 0xe7, 0xf7, 0xf3, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf5, 0xff,  0xfd, 0xf3, 0xff, 0xfb, 0xf1, 0xf3, 0xf1, 0xfd, 
+	 0xff, 0xfd, 0xff, 0xf7, 0xff, 0x5f, 0x4f, 0x5f,  0x41, 0x2b, 0x47, 0x4b, 0x37, 0x51, 0x3b, 0x2f, 
+	 0x47, 0x3f, 0x33, 0x4b, 0xa9, 0xa5, 0xb1, 0xef,  0xeb, 0xf9, 0xff, 0xfb, 0xff, 0xfd, 0xf5, 0xff, 
+	 0xff, 0xed, 0xff, 0x51, 0x3f, 0x5f, 0x49, 0x3b,  0x4b, 0xcb, 0xbd, 0xcd, 0xe5, 0xfd, 0xed, 0xd7, 
+	 0xf1, 0xe1, 0xef, 0xff, 0xfb, 0xef, 0xff, 0xfb,  0xff, 0xef, 0xff, 0xff, 0xf5, 0xff, 0xff, 0xf5, 
+	 0xff, 0xff, 0xf3, 0xff, 0xef, 0xff, 0xfb, 0xe9,  0xff, 0xf5, 0xd9, 0xf3, 0xe3, 0xef, 0xff, 0xf7, 
+	 0xc1, 0xb3, 0xc5, 0x55, 0x47, 0x57, 0x9f, 0x91,  0xad, 0xff, 0xf7, 0xff, 0xf5, 0xef, 0xff, 0xfd, 
+	 0xf7, 0xff, 0xe1, 0xd9, 0xeb, 0x3b, 0x31, 0x45,  0x51, 0x3d, 0x5b, 0x41, 0x2d, 0x49, 0x4f, 0x33, 
+	 0x4f, 0x47, 0x2d, 0x47, 0x87, 0x77, 0x7f, 0xff,  0xfb, 0xff, 0xef, 0xef, 0xed, 0xf5, 0xf7, 0xf5, 
+	 0xf3, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xed, 0xed, 0xf1, 0xff, 0xfb, 0xff, 0xff, 
+	 0xf5, 0xff, 0x4f, 0x33, 0x45, 0x65, 0x49, 0x5b,  0x51, 0x35, 0x47, 0x47, 0x2b, 0x3d, 0x55, 0x45, 
+	 0x51, 0xa7, 0x99, 0xa3, 0xf5, 0xf1, 0xf1, 0xff,  0xfb, 0xfb, 0xf5, 0xef, 0xf3, 0xf9, 0xf3, 0xf7, 
+	 0xff, 0xf3, 0xfd, 0x99, 0x8d, 0x97, 0x77, 0x43,  0x65, 0xb3, 0x7f, 0xa1, 0xff, 0xfd, 0xff, 0xff, 
+	 0xfd, 0xff, 0xfd, 0xff, 0xf9, 0xf3, 0xf7, 0xef,  0xff, 0xff, 0xfb, 0xff, 0xfd, 0xf9, 0xff, 0xf9, 
+	 0xf5, 0xff, 0xf5, 0xf1, 0xfd, 0xff, 0xf9, 0xff,  0xff, 0xfb, 0xff, 0xfd, 0xff, 0xed, 0xe3, 0xe7, 
+	 0xe9, 0xb5, 0xd7, 0x75, 0x43, 0x65, 0xd1, 0xc9,  0xd1, 0xf3, 0xe9, 0xf1, 0xff, 0xfb, 0xfd, 0xfb, 
+	 0xf7, 0xf9, 0xf7, 0xed, 0xf5, 0xfb, 0xf1, 0xf9,  0x51, 0x3b, 0x4b, 0x49, 0x33, 0x43, 0x55, 0x35, 
+	 0x47, 0x55, 0x35, 0x47, 0x57, 0x3d, 0x47, 0x7f,  0x63, 0x6f, 0xff, 0xf3, 0xf9, 0xfd, 0xef, 0xf5, 
+	 0xed, 0xed, 0xf5, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf5, 0xf3,  0xf7, 0xf5, 0xf5, 0xf9, 0xff, 0xef, 0xf9, 0x59, 
+	 0x49, 0x53, 0x55, 0x39, 0x4b, 0x4f, 0x33, 0x45,  0x51, 0x35, 0x47, 0x51, 0x35, 0x47, 0x85, 0x75, 
+	 0x81, 0xff, 0xf3, 0xfd, 0xff, 0xff, 0xff, 0xf5,  0xf1, 0xf1, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xfd, 0xf1, 0xfb, 0xe9, 0xdd, 0xe7, 0x71, 0x3f,  0x61, 0x79, 0x47, 0x69, 0xf1, 0xe7, 0xeb, 0xff, 
+	 0xfd, 0xff, 0xf1, 0xf7, 0xed, 0xf3, 0xf9, 0xef,  0xff, 0xff, 0xfb, 0xff, 0xfb, 0xf7, 0xff, 0xff, 
+	 0xfb, 0xff, 0xf9, 0xf5, 0xfd, 0xff, 0xf9, 0xfd,  0xff, 0xf9, 0xfd, 0xf3, 0xf7, 0xff, 0xfd, 0xff, 
+	 0xa3, 0x6f, 0x93, 0x67, 0x35, 0x57, 0xfb, 0xf1,  0xf9, 0xff, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xfb, 0xfd, 0xff, 0xf9, 0xff, 0xff, 0xfd, 0xff,  0xdb, 0xc3, 0xd3, 0x55, 0x3f, 0x4f, 0x51, 0x31, 
+	 0x43, 0x4f, 0x2f, 0x41, 0x59, 0x3d, 0x49, 0x65,  0x49, 0x55, 0x8f, 0x81, 0x87, 0xff, 0xfd, 0xff, 
+	 0xf3, 0xf3, 0xfb, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf9,  0xff, 0xff, 0xfb, 0xff, 0x81, 0x63, 0x77, 0x63, 
+	 0x45, 0x59, 0x5d, 0x37, 0x47, 0x4b, 0x27, 0x37,  0x55, 0x35, 0x39, 0x5f, 0x3f, 0x45, 0xf7, 0xe7, 
+	 0xe7, 0xff, 0xfd, 0xfd, 0xfb, 0xf7, 0xf9, 0xfd,  0xf7, 0xfb, 0xfb, 0xfb, 0xfd, 0xfd, 0xfd, 0xff, 
+	 0xfb, 0xf9, 0xf9, 0xfb, 0xf9, 0xf9, 0x35, 0x0b,  0x19, 0x63, 0x39, 0x47, 0xd5, 0xc5, 0xd5, 0xff, 
+	 0xf9, 0xff, 0xf5, 0xfb, 0xff, 0xf9, 0xff, 0xff,  0xf9, 0xfd, 0xf7, 0xff, 0xff, 0xfb, 0xfd, 0xff, 
+	 0xf9, 0xff, 0xff, 0xfb, 0xf5, 0xfb, 0xff, 0xf1,  0xf7, 0xfd, 0xff, 0xf7, 0xff, 0xf3, 0xe3, 0xf3, 
+	 0x65, 0x3b, 0x49, 0x49, 0x1d, 0x2b, 0xf9, 0xf9,  0xf9, 0xe7, 0xe7, 0xe7, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xf5, 0xf9, 0xfd, 0xf3, 0xf7,  0xff, 0xfb, 0xfb, 0x9d, 0x87, 0x87, 0x51, 0x2d, 
+	 0x33, 0x53, 0x2f, 0x35, 0x5f, 0x35, 0x45, 0x65,  0x3b, 0x4b, 0x61, 0x43, 0x55, 0xd9, 0xbb, 0xcf, 
+	 0xff, 0xef, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf9,  0xff, 0xeb, 0xdb, 0xe7, 0x61, 0x43, 0x57, 0x57, 
+	 0x39, 0x4d, 0x4f, 0x29, 0x39, 0x5f, 0x39, 0x49,  0x61, 0x41, 0x47, 0x89, 0x69, 0x6d, 0xff, 0xf5, 
+	 0xf5, 0xff, 0xf5, 0xf5, 0xff, 0xfd, 0xff, 0xff,  0xff, 0xff, 0xfb, 0xfb, 0xfd, 0xf9, 0xf9, 0xfb, 
+	 0xfb, 0xf9, 0xf9, 0xf5, 0xf3, 0xf3, 0x87, 0x5d,  0x6b, 0x59, 0x2d, 0x3b, 0x87, 0x77, 0x89, 0xf3, 
+	 0xe3, 0xf5, 0xf5, 0xfb, 0xff, 0xf9, 0xff, 0xff,  0xfb, 0xff, 0xf7, 0xff, 0xff, 0xfb, 0xf9, 0xfd, 
+	 0xf7, 0xff, 0xff, 0xfb, 0xf7, 0xfd, 0xff, 0xf7,  0xfd, 0xff, 0xfd, 0xed, 0xff, 0x71, 0x61, 0x73, 
+	 0x63, 0x39, 0x47, 0xaf, 0x85, 0x91, 0xff, 0xff,  0xff, 0xf9, 0xf9, 0xf9, 0xeb, 0xe9, 0xed, 0xfd, 
+	 0xfd, 0xff, 0xf9, 0xef, 0xf3, 0xff, 0xfd, 0xff,  0xff, 0xfd, 0xff, 0xcf, 0xb9, 0xbb, 0x6b, 0x47, 
+	 0x4d, 0x51, 0x2d, 0x33, 0x61, 0x39, 0x47, 0x51,  0x27, 0x37, 0x4d, 0x2f, 0x41, 0x67, 0x49, 0x5d, 
+	 0xff, 0xf9, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf5,  0xff, 0x6b, 0x59, 0x63, 0x5b, 0x3d, 0x51, 0x45, 
+	 0x27, 0x3b, 0x47, 0x23, 0x31, 0x5d, 0x39, 0x47,  0x4d, 0x33, 0x2f, 0xab, 0x91, 0x8d, 0xff, 0xf3, 
+	 0xf7, 0xff, 0xfd, 0xff, 0xfb, 0xf7, 0xff, 0xeb,  0xe7, 0xff, 0xf3, 0xf5, 0xff, 0xf3, 0xf5, 0xff, 
+	 0xed, 0xf5, 0xff, 0xf1, 0xf9, 0xff, 0xe1, 0xe3,  0xff, 0x4d, 0x4d, 0x6d, 0x21, 0x21, 0x6d, 0x75, 
+	 0x75, 0xc3, 0x75, 0x79, 0xd7, 0x73, 0x77, 0xd5,  0x65, 0x6f, 0xbd, 0x47, 0x51, 0x9f, 0x5d, 0x65, 
+	 0xb5, 0x4b, 0x55, 0xa3, 0x6f, 0x73, 0xd1, 0x7d,  0x81, 0xdf, 0x5b, 0x5d, 0xa9, 0x37, 0x37, 0x83, 
+	 0x41, 0x41, 0x61, 0xf1, 0xf3, 0xff, 0xdd, 0xe5,  0xff, 0xf1, 0xf9, 0xff, 0xf3, 0xf5, 0xff, 0xe7, 
+	 0xe9, 0xff, 0xff, 0xf7, 0xff, 0xf5, 0xef, 0xff,  0xff, 0xfb, 0xfd, 0xb5, 0xa3, 0xa5, 0x4b, 0x2d, 
+	 0x2b, 0x5b, 0x3d, 0x3b, 0x53, 0x29, 0x3b, 0x63,  0x39, 0x4d, 0x4b, 0x2d, 0x41, 0x61, 0x41, 0x57, 
+	 0xb7, 0xa9, 0xaf, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfb, 0xe9,  0xf5, 0x31, 0x1f, 0x29, 0x55, 0x37, 0x4b, 0x49, 
+	 0x29, 0x3f, 0x69, 0x45, 0x53, 0x51, 0x2d, 0x3b,  0x47, 0x2b, 0x29, 0x9b, 0x7f, 0x7d, 0xff, 0xf5, 
+	 0xf9, 0xf7, 0xeb, 0xef, 0xf3, 0xef, 0xff, 0xf7,  0xf3, 0xff, 0xf3, 0xf5, 0xff, 0xad, 0xad, 0xd5, 
+	 0x53, 0x5b, 0x75, 0x27, 0x2d, 0x49, 0x4b, 0x4b,  0x6b, 0x5b, 0x5b, 0x7b, 0x63, 0x63, 0xaf, 0x7d, 
+	 0x7d, 0xcb, 0x6d, 0x71, 0xcf, 0x55, 0x5b, 0xb7,  0x5b, 0x65, 0xb3, 0x65, 0x6d, 0xbd, 0x55, 0x5f, 
+	 0xad, 0x5f, 0x69, 0xb7, 0x71, 0x75, 0xd3, 0x61,  0x65, 0xc3, 0x79, 0x79, 0xc7, 0x53, 0x53, 0x9f, 
+	 0x5b, 0x5b, 0x7b, 0x43, 0x43, 0x63, 0x29, 0x2f,  0x4f, 0x69, 0x71, 0x8f, 0x6d, 0x6f, 0x97, 0xd9, 
+	 0xdb, 0xff, 0xf1, 0xeb, 0xff, 0xf1, 0xe9, 0xff,  0xe5, 0xd5, 0xd7, 0x63, 0x51, 0x55, 0x55, 0x35, 
+	 0x35, 0x59, 0x39, 0x39, 0x61, 0x37, 0x49, 0x4f,  0x25, 0x37, 0x59, 0x39, 0x4f, 0x4d, 0x2d, 0x43, 
+	 0x37, 0x29, 0x2f, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfb, 0xf5,  0xf5, 0x5d, 0x57, 0x57, 0x51, 0x3b, 0x4d, 0x49, 
+	 0x35, 0x45, 0x45, 0x2b, 0x35, 0x57, 0x3d, 0x47,  0x53, 0x47, 0x3d, 0x5b, 0x4f, 0x45, 0xd9, 0xd5, 
+	 0xe9, 0xaf, 0xab, 0xbf, 0x2f, 0x27, 0x7b, 0x85,  0x7f, 0xd3, 0x77, 0x75, 0xdd, 0x4b, 0x4b, 0xb3, 
+	 0x5d, 0x69, 0xb9, 0x5d, 0x69, 0xb9, 0x4f, 0x59,  0xd5, 0x37, 0x43, 0xbf, 0x41, 0x3b, 0xdf, 0x47, 
+	 0x41, 0xe5, 0x41, 0x3b, 0xe9, 0x3b, 0x35, 0xe3,  0x3f, 0x47, 0xdb, 0x39, 0x41, 0xd7, 0x3b, 0x43, 
+	 0xd7, 0x35, 0x3d, 0xd3, 0x4d, 0x47, 0xf5, 0x31,  0x2b, 0xd9, 0x4b, 0x45, 0xe9, 0x45, 0x3f, 0xe3, 
+	 0x41, 0x4d, 0xc9, 0x43, 0x4d, 0xc9, 0x5d, 0x65,  0xc1, 0x5f, 0x69, 0xc5, 0x33, 0x33, 0x99, 0x87, 
+	 0x87, 0xed, 0xbd, 0xb9, 0xff, 0x65, 0x63, 0xab,  0x45, 0x3d, 0x4d, 0x55, 0x4d, 0x5d, 0x5f, 0x49, 
+	 0x47, 0x4f, 0x39, 0x37, 0x49, 0x29, 0x3d, 0x53,  0x33, 0x47, 0x4f, 0x39, 0x4b, 0x43, 0x2d, 0x41, 
+	 0x51, 0x4f, 0x49, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc7, 0xc1,  0xc1, 0x53, 0x4d, 0x4d, 0x4d, 0x37, 0x49, 0x45, 
+	 0x31, 0x41, 0x71, 0x55, 0x61, 0x41, 0x25, 0x31,  0x3f, 0x33, 0x29, 0x83, 0x77, 0x6d, 0xf1, 0xed, 
+	 0xff, 0xf9, 0xf5, 0xff, 0x9f, 0x99, 0xed, 0x51,  0x49, 0x9d, 0x5d, 0x5b, 0xc5, 0x51, 0x51, 0xb9, 
+	 0x51, 0x5d, 0xad, 0x4d, 0x59, 0xa9, 0x43, 0x4f,  0xcb, 0x3f, 0x49, 0xc5, 0x57, 0x51, 0xf5, 0x3f, 
+	 0x39, 0xdd, 0x31, 0x2d, 0xd9, 0x45, 0x3f, 0xed,  0x31, 0x3b, 0xcf, 0x45, 0x4d, 0xe3, 0x3d, 0x45, 
+	 0xdb, 0x3d, 0x45, 0xd9, 0x3f, 0x39, 0xe7, 0x49,  0x43, 0xf1, 0x47, 0x3f, 0xe3, 0x43, 0x3d, 0xe1, 
+	 0x45, 0x4f, 0xcb, 0x3b, 0x47, 0xc3, 0x47, 0x51,  0xad, 0x49, 0x53, 0xad, 0x57, 0x57, 0xbd, 0x69, 
+	 0x69, 0xcf, 0x4b, 0x45, 0x8f, 0x89, 0x85, 0xcd,  0xfd, 0xf5, 0xff, 0xf3, 0xed, 0xfd, 0xaf, 0x9b, 
+	 0x97, 0x81, 0x6b, 0x69, 0x57, 0x35, 0x4b, 0x61,  0x41, 0x55, 0x41, 0x2b, 0x3d, 0x53, 0x3d, 0x51, 
+	 0x59, 0x57, 0x51, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfd, 0xff,  0xfb, 0x57, 0x5d, 0x55, 0x31, 0x23, 0x35, 0x55, 
+	 0x47, 0x59, 0xc7, 0xb5, 0xbb, 0xff, 0xf7, 0xff,  0xff, 0xff, 0xf7, 0xff, 0xff, 0xf3, 0xe7, 0xe7, 
+	 0xff, 0x3d, 0x3d, 0x61, 0x63, 0x59, 0xd9, 0x59,  0x51, 0xd1, 0x49, 0x43, 0xe3, 0x4f, 0x4b, 0xe9, 
+	 0x41, 0x4d, 0xcd, 0x35, 0x41, 0xc1, 0x37, 0x33,  0xdf, 0x3f, 0x3b, 0xe5, 0x47, 0x3f, 0xdf, 0x3d, 
+	 0x35, 0xd5, 0x29, 0x41, 0xbb, 0x45, 0x5b, 0xd5,  0x49, 0x8b, 0xd9, 0x00, 0x1f, 0x6f, 0x00, 0x41, 
+	 0x8f, 0x3b, 0x7d, 0xcb, 0x3f, 0x53, 0xcd, 0x2b,  0x41, 0xbb, 0x47, 0x3f, 0xdf, 0x39, 0x31, 0xd1, 
+	 0x3b, 0x35, 0xe1, 0x45, 0x41, 0xed, 0x47, 0x4f,  0xdd, 0x35, 0x3f, 0xcd, 0x3b, 0x37, 0xd3, 0x37, 
+	 0x33, 0xcf, 0x67, 0x61, 0xd3, 0x5d, 0x57, 0xc9,  0x51, 0x4d, 0x69, 0xf3, 0xef, 0xff, 0xff, 0xff, 
+	 0xfd, 0xff, 0xf3, 0xf1, 0xfd, 0xe1, 0xfb, 0xc1,  0xa7, 0xbf, 0x59, 0x4b, 0x5f, 0x59, 0x49, 0x5f, 
+	 0x4f, 0x5d, 0x49, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe5, 0xeb,  0xe5, 0xd5, 0xdb, 0xd5, 0xe7, 0xd9, 0xeb, 0xff, 
+	 0xf9, 0xff, 0xff, 0xf7, 0xff, 0xff, 0xed, 0xf3,  0xfd, 0xf9, 0xeb, 0xf1, 0xed, 0xe1, 0x21, 0x21, 
+	 0x45, 0x6f, 0x6f, 0x93, 0x5b, 0x53, 0xd1, 0x51,  0x49, 0xc9, 0x3f, 0x3b, 0xd9, 0x3b, 0x37, 0xd5, 
+	 0x43, 0x4f, 0xcf, 0x49, 0x55, 0xd5, 0x47, 0x41,  0xed, 0x49, 0x43, 0xef, 0x3b, 0x33, 0xd3, 0x53, 
+	 0x4b, 0xeb, 0x45, 0x59, 0xd3, 0x23, 0x3b, 0xb5,  0x65, 0xa7, 0xf7, 0x9b, 0xdd, 0xff, 0x89, 0xcb, 
+	 0xff, 0x61, 0xa3, 0xf3, 0x43, 0x59, 0xd3, 0x4d,  0x61, 0xdb, 0x43, 0x3b, 0xdb, 0x53, 0x4b, 0xeb, 
+	 0x43, 0x3f, 0xe9, 0x41, 0x3b, 0xe7, 0x3b, 0x43,  0xd3, 0x3f, 0x47, 0xd7, 0x49, 0x43, 0xe1, 0x4b, 
+	 0x47, 0xe5, 0x4f, 0x4b, 0xbb, 0x55, 0x4f, 0xbf,  0x41, 0x3d, 0x59, 0x29, 0x25, 0x41, 0xed, 0xdf, 
+	 0xdd, 0xff, 0xf3, 0xf1, 0xff, 0xf5, 0xff, 0xff,  0xf1, 0xff, 0xff, 0xf9, 0xff, 0xef, 0xdf, 0xf3, 
+	 0xcb, 0xd7, 0xc3, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf5, 0xfd,  0xf9, 0xfb, 0xff, 0xff, 0xfb, 0xed, 0xff, 0xf5, 
+	 0xe7, 0xff, 0xff, 0xf9, 0xff, 0xff, 0xfb, 0xff,  0xff, 0xfd, 0xeb, 0x21, 0x1d, 0x0b, 0x37, 0x33, 
+	 0x5d, 0x51, 0x4d, 0x77, 0x4d, 0x3f, 0xd7, 0x57,  0x49, 0xdf, 0x35, 0x29, 0xe3, 0x57, 0x49, 0xff, 
+	 0x35, 0x3d, 0xd3, 0x3d, 0x45, 0xd9, 0x41, 0x39,  0xd5, 0x49, 0x3f, 0xdd, 0x49, 0x5b, 0xc3, 0x4b, 
+	 0x5d, 0xc5, 0x00, 0x4d, 0x6f, 0x91, 0xf1, 0xff,  0x4f, 0xf9, 0xf5, 0x35, 0xdf, 0xdb, 0x3f, 0xeb, 
+	 0xe7, 0x3b, 0xe7, 0xe3, 0x85, 0xe5, 0xff, 0x00,  0x55, 0x77, 0x5f, 0x71, 0xd9, 0x2f, 0x43, 0xa9, 
+	 0x49, 0x3f, 0xdd, 0x47, 0x3d, 0xdb, 0x45, 0x47,  0xed, 0x2d, 0x31, 0xd7, 0x4b, 0x3f, 0xf7, 0x3d, 
+	 0x33, 0xeb, 0x4b, 0x41, 0xc5, 0x61, 0x55, 0xd9,  0x31, 0x2d, 0x4b, 0x3b, 0x35, 0x55, 0x2d, 0x21, 
+	 0x1b, 0xfb, 0xef, 0xe9, 0xff, 0xf5, 0xff, 0xff,  0xe9, 0xff, 0xf5, 0xe7, 0xff, 0xff, 0xf7, 0xff, 
+	 0xef, 0xff, 0xe9, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfb, 0xff,  0xff, 0xef, 0xf5, 0xf3, 0xff, 0xf3, 0xff, 0xff, 
+	 0xf7, 0xff, 0xff, 0xf3, 0xfb, 0xff, 0xef, 0xf7,  0x2d, 0x29, 0x19, 0x4f, 0x4b, 0x39, 0x29, 0x27, 
+	 0x4f, 0x53, 0x4f, 0x79, 0x41, 0x33, 0xc9, 0x43,  0x35, 0xcb, 0x41, 0x35, 0xf1, 0x43, 0x37, 0xf3, 
+	 0x3d, 0x45, 0xd9, 0x3b, 0x43, 0xd7, 0x47, 0x3d,  0xdb, 0x4b, 0x41, 0xdf, 0x63, 0x75, 0xdd, 0x3f, 
+	 0x53, 0xb9, 0x49, 0xa7, 0xcb, 0x65, 0xc3, 0xe7,  0x31, 0xdb, 0xd7, 0x3d, 0xe7, 0xe3, 0x49, 0xf3, 
+	 0xef, 0x37, 0xe3, 0xdf, 0x69, 0xc7, 0xeb, 0x1d,  0x7b, 0x9f, 0x11, 0x25, 0x8d, 0x5f, 0x71, 0xd9, 
+	 0x5b, 0x4f, 0xed, 0x4b, 0x41, 0xdf, 0x31, 0x35,  0xdb, 0x4f, 0x51, 0xf7, 0x35, 0x2b, 0xe3, 0x41, 
+	 0x35, 0xed, 0x4f, 0x45, 0xc9, 0x43, 0x37, 0xbb,  0x47, 0x41, 0x61, 0x37, 0x31, 0x51, 0x5b, 0x4f, 
+	 0x49, 0x1f, 0x13, 0x0d, 0xff, 0xed, 0xff, 0xff,  0xeb, 0xff, 0xfb, 0xed, 0xff, 0xff, 0xf7, 0xff, 
+	 0xf3, 0xff, 0xed, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf3, 0xf7,  0xf9, 0xfb, 0xff, 0xff, 0xff, 0xed, 0xff, 0xff, 
+	 0xed, 0xff, 0xff, 0xf9, 0xff, 0x57, 0x41, 0x4b,  0x55, 0x4d, 0x39, 0x4f, 0x47, 0x33, 0x39, 0x33, 
+	 0x5b, 0x3d, 0x37, 0x5f, 0x59, 0x45, 0xe1, 0x49,  0x35, 0xd3, 0x51, 0x3f, 0xff, 0x4b, 0x3b, 0xfb, 
+	 0x25, 0x29, 0xbf, 0x49, 0x4d, 0xe1, 0x3d, 0x35,  0xd5, 0x49, 0x41, 0xe1, 0x2b, 0x59, 0xb3, 0x9f, 
+	 0xcd, 0xff, 0x51, 0xe9, 0xff, 0x49, 0xe1, 0xfd,  0x00, 0xed, 0xf7, 0x0b, 0xff, 0xff, 0x00, 0xef, 
+	 0xf9, 0x00, 0xf1, 0xfb, 0x57, 0xef, 0xff, 0x5f,  0xf7, 0xff, 0x55, 0x81, 0xdd, 0x43, 0x6f, 0xcb, 
+	 0x25, 0x1d, 0xbd, 0x53, 0x4b, 0xeb, 0x37, 0x37,  0xdf, 0x39, 0x39, 0xe3, 0x47, 0x37, 0xf3, 0x49, 
+	 0x39, 0xf7, 0x65, 0x53, 0xdb, 0x5d, 0x4d, 0xd3,  0x2b, 0x23, 0x3f, 0x39, 0x31, 0x4d, 0x39, 0x2b, 
+	 0x23, 0x5d, 0x4d, 0x45, 0x5d, 0x3d, 0x5d, 0xff,  0xeb, 0xff, 0xff, 0xf3, 0xff, 0xff, 0xf3, 0xff, 
+	 0xe1, 0xeb, 0xd9, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf9, 0xfd,  0xff, 0xfd, 0xff, 0xff, 0xff, 0xed, 0xff, 0xff, 
+	 0xf5, 0xff, 0xef, 0xd9, 0xe3, 0x4f, 0x39, 0x43,  0x47, 0x3f, 0x2b, 0x49, 0x41, 0x2d, 0x2f, 0x29, 
+	 0x51, 0x3b, 0x35, 0x5d, 0x45, 0x33, 0xcf, 0x5f,  0x4b, 0xe7, 0x3d, 0x2d, 0xed, 0x3d, 0x2d, 0xed, 
+	 0x4d, 0x51, 0xe7, 0x3b, 0x41, 0xd5, 0x4d, 0x45,  0xe5, 0x43, 0x3d, 0xdd, 0x2f, 0x5d, 0xb7, 0x21, 
+	 0x51, 0xab, 0x45, 0xdd, 0xf9, 0x4b, 0xe3, 0xff,  0x09, 0xff, 0xff, 0x00, 0xed, 0xf7, 0x04, 0xf9, 
+	 0xff, 0x00, 0xf1, 0xfb, 0x43, 0xdb, 0xf7, 0x29,  0xc1, 0xdd, 0x27, 0x55, 0xaf, 0x39, 0x65, 0xc1, 
+	 0x4f, 0x47, 0xe7, 0x3d, 0x35, 0xd5, 0x41, 0x41,  0xe9, 0x3d, 0x3d, 0xe5, 0x45, 0x35, 0xf3, 0x3d, 
+	 0x2d, 0xeb, 0x4b, 0x39, 0xc1, 0x57, 0x45, 0xcd,  0x3f, 0x37, 0x51, 0x39, 0x31, 0x4b, 0x53, 0x45, 
+	 0x3d, 0x4b, 0x3b, 0x33, 0x51, 0x31, 0x51, 0xf7,  0xd7, 0xf9, 0xff, 0xed, 0xff, 0xff, 0xed, 0xff, 
+	 0xfb, 0xff, 0xf3, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe7, 0xf9,  0xff, 0xef, 0xff, 0xff, 0xff, 0xf3, 0xff, 0xff, 
+	 0xfb, 0xff, 0x85, 0x5d, 0x73, 0x63, 0x39, 0x4f,  0x61, 0x31, 0x4d, 0x5b, 0x2b, 0x47, 0x4f, 0x33, 
+	 0x55, 0x3f, 0x23, 0x45, 0x5f, 0x59, 0x85, 0x6d,  0x65, 0x93, 0x65, 0x65, 0x9d, 0x81, 0x81, 0xb9, 
+	 0x6f, 0x6b, 0xab, 0x7d, 0x79, 0xbb, 0x4d, 0x61,  0xc1, 0x4d, 0x5f, 0xc1, 0x57, 0x3f, 0xe9, 0x51, 
+	 0x39, 0xe3, 0x2b, 0x5b, 0xbf, 0x91, 0xc3, 0xff,  0x3d, 0xdb, 0xff, 0x43, 0xe1, 0xff, 0x4b, 0xe7, 
+	 0xff, 0x41, 0xdd, 0xff, 0x6d, 0x9d, 0xfd, 0x21,  0x53, 0xb1, 0x55, 0x3b, 0xdd, 0x53, 0x39, 0xdd, 
+	 0x59, 0x69, 0xc1, 0x5b, 0x6b, 0xc3, 0x63, 0x65,  0x99, 0x5d, 0x5d, 0x91, 0x77, 0x79, 0xa9, 0x79, 
+	 0x7b, 0xab, 0x6d, 0x67, 0x91, 0x49, 0x43, 0x6d,  0x51, 0x35, 0x59, 0x49, 0x2d, 0x51, 0x61, 0x31, 
+	 0x4f, 0x5b, 0x2b, 0x49, 0x67, 0x3d, 0x53, 0x73,  0x49, 0x5f, 0xff, 0xfb, 0xff, 0xff, 0xfb, 0xff, 
+	 0xe1, 0xf5, 0xf7, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xef, 0xff,  0xff, 0xe7, 0xf7, 0xff, 0xfb, 0xef, 0xfd, 0xf7, 
+	 0xe9, 0xf7, 0x5d, 0x33, 0x49, 0x4b, 0x23, 0x37,  0x5d, 0x2d, 0x49, 0x63, 0x33, 0x4f, 0x47, 0x2b, 
+	 0x4d, 0x4d, 0x31, 0x53, 0x55, 0x4d, 0x7b, 0x7d,  0x77, 0xa5, 0x1f, 0x1d, 0x55, 0xdb, 0xd9, 0xff, 
+	 0xd9, 0xd5, 0xff, 0xb7, 0xb3, 0xf5, 0x00, 0x06,  0x65, 0x57, 0x6b, 0xcb, 0x51, 0x39, 0xe5, 0x61, 
+	 0x47, 0xf3, 0x25, 0x57, 0xb9, 0x43, 0x73, 0xd7,  0x06, 0xa3, 0xcf, 0x39, 0xd7, 0xff, 0x41, 0xdd, 
+	 0xff, 0x00, 0x6d, 0x95, 0x45, 0x75, 0xd5, 0x39,  0x69, 0xc9, 0x53, 0x39, 0xdb, 0x6b, 0x4f, 0xf3, 
+	 0x09, 0x1b, 0x71, 0x7b, 0x8b, 0xe3, 0xed, 0xef,  0xff, 0xeb, 0xed, 0xff, 0xd1, 0xd3, 0xff, 0x02, 
+	 0x02, 0x31, 0x6b, 0x67, 0x8f, 0x45, 0x3f, 0x69,  0x45, 0x29, 0x4d, 0x3f, 0x23, 0x47, 0x55, 0x25, 
+	 0x43, 0x61, 0x31, 0x4f, 0x5b, 0x31, 0x47, 0x4b,  0x23, 0x37, 0xf7, 0xeb, 0xf5, 0xff, 0xf9, 0xff, 
+	 0xef, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xeb, 0xf9,  0xf9, 0xe9, 0xf7, 0xf7, 0xff, 0xfd, 0xff, 0xcb, 
+	 0xbd, 0xc3, 0x71, 0x4d, 0x5b, 0x57, 0x33, 0x41,  0x59, 0x31, 0x45, 0x51, 0x29, 0x3b, 0x3d, 0x25, 
+	 0x3d, 0x59, 0x41, 0x59, 0x1f, 0x17, 0x31, 0xd7,  0xcf, 0xe9, 0xfd, 0xf7, 0xff, 0xed, 0xe7, 0xff, 
+	 0xff, 0xf3, 0xff, 0xff, 0xf3, 0xff, 0xf7, 0xf9,  0xff, 0x4d, 0x4f, 0x69, 0x6f, 0x63, 0xd1, 0x59, 
+	 0x4d, 0xbb, 0x31, 0x3d, 0xb9, 0x3f, 0x4b, 0xc7,  0x45, 0x6f, 0xd7, 0x15, 0x43, 0xa9, 0x1f, 0x4b, 
+	 0xaf, 0x4f, 0x79, 0xdd, 0x3d, 0x49, 0xbd, 0x3f,  0x4b, 0xbf, 0x53, 0x45, 0xa7, 0x3f, 0x31, 0x93, 
+	 0xeb, 0xeb, 0xf7, 0xf3, 0xf3, 0xff, 0xfd, 0xf1,  0xff, 0xf5, 0xe9, 0xff, 0xf1, 0xed, 0xff, 0xe7, 
+	 0xe3, 0xfd, 0x9f, 0x99, 0xaf, 0x4f, 0x47, 0x5f,  0x41, 0x2b, 0x41, 0x53, 0x3b, 0x51, 0x53, 0x2b, 
+	 0x3f, 0x5b, 0x33, 0x45, 0x53, 0x2f, 0x3d, 0x55,  0x31, 0x3f, 0xf7, 0xe9, 0xef, 0xff, 0xf3, 0xf9, 
+	 0xf3, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xed, 0xfb,  0xfb, 0xf3, 0xff, 0xff, 0xff, 0xfd, 0xff, 0x41, 
+	 0x35, 0x3b, 0x65, 0x41, 0x4f, 0x53, 0x2f, 0x3d,  0x5b, 0x33, 0x47, 0x55, 0x2d, 0x3f, 0x55, 0x3d, 
+	 0x55, 0x55, 0x3d, 0x55, 0xd3, 0xcb, 0xe5, 0xff,  0xf7, 0xff, 0xe9, 0xe3, 0xff, 0xf7, 0xf1, 0xff, 
+	 0xdf, 0xd1, 0xf7, 0xeb, 0xdd, 0xff, 0xe3, 0xe5,  0xff, 0xf1, 0xf3, 0xff, 0x00, 0x00, 0x57, 0x6d, 
+	 0x61, 0xcf, 0x37, 0x43, 0xbf, 0x47, 0x53, 0xcf,  0x2f, 0x5b, 0xc1, 0x2d, 0x59, 0xbf, 0x37, 0x61, 
+	 0xc5, 0x21, 0x4d, 0xb1, 0x43, 0x4f, 0xc3, 0x47,  0x51, 0xc5, 0x7f, 0x73, 0xd5, 0x79, 0x6d, 0xcf, 
+	 0xf7, 0xf7, 0xff, 0xf9, 0xf9, 0xff, 0xe5, 0xd9,  0xf9, 0xf3, 0xe7, 0xff, 0xfd, 0xf7, 0xff, 0xf5, 
+	 0xef, 0xff, 0xfb, 0xf3, 0xff, 0x97, 0x91, 0xa7,  0x61, 0x49, 0x5f, 0x3d, 0x25, 0x3b, 0x5b, 0x33, 
+	 0x45, 0x59, 0x31, 0x43, 0x57, 0x33, 0x41, 0x67,  0x43, 0x51, 0xb7, 0xab, 0xb1, 0xff, 0xf5, 0xfb, 
+	 0xf3, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf9, 0xff,  0xf9, 0xf7, 0xff, 0xf7, 0xff, 0xf9, 0xf7, 0x0f, 
+	 0x04, 0x02, 0x4f, 0x2f, 0x37, 0x4f, 0x2d, 0x35,  0x5b, 0x37, 0x45, 0x55, 0x33, 0x41, 0x4d, 0x3b, 
+	 0x45, 0x71, 0x5f, 0x69, 0xff, 0xfd, 0xff, 0xff,  0xf9, 0xff, 0xf7, 0xe3, 0xe3, 0x87, 0x71, 0x73, 
+	 0x99, 0x7b, 0x79, 0x73, 0x53, 0x53, 0xb1, 0x8b,  0x73, 0xff, 0xf9, 0xdf, 0x93, 0x93, 0xcd, 0x75, 
+	 0x75, 0xaf, 0x3d, 0x39, 0xd9, 0x3d, 0x39, 0xd9,  0x4d, 0x2d, 0xd9, 0x59, 0x39, 0xe7, 0x53, 0x35, 
+	 0xdf, 0x67, 0x47, 0xf1, 0x41, 0x3d, 0xd3, 0x41,  0x3f, 0xd3, 0x4b, 0x4b, 0x75, 0xe1, 0xe3, 0xff, 
+	 0xef, 0xcb, 0x9f, 0x9d, 0x7b, 0x4f, 0x7f, 0x5d,  0x63, 0x7f, 0x5d, 0x63, 0xa7, 0x91, 0x93, 0xf7, 
+	 0xe1, 0xe3, 0xff, 0xfd, 0xff, 0xff, 0xf3, 0xf7,  0x27, 0x17, 0x1b, 0x4b, 0x39, 0x3f, 0x55, 0x35, 
+	 0x3d, 0x59, 0x39, 0x41, 0x57, 0x37, 0x3f, 0x4f,  0x2f, 0x37, 0x39, 0x2d, 0x31, 0xff, 0xfd, 0xff, 
+	 0xf9, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf9, 0xff,  0xf9, 0xe9, 0xf5, 0xeb, 0xff, 0xff, 0xfd, 0x5d, 
+	 0x51, 0x4f, 0x55, 0x35, 0x3d, 0x5b, 0x3b, 0x43,  0x59, 0x35, 0x43, 0x4d, 0x29, 0x37, 0x61, 0x4f, 
+	 0x59, 0xff, 0xfb, 0xff, 0xf1, 0xe3, 0xe9, 0xf5,  0xe7, 0xed, 0xff, 0xf3, 0xf5, 0xf5, 0xe1, 0xe1, 
+	 0x7d, 0x5f, 0x5d, 0x79, 0x5b, 0x59, 0x7d, 0x59,  0x41, 0xbb, 0x97, 0x7f, 0xd7, 0xd7, 0xff, 0x6b, 
+	 0x6b, 0xa5, 0x4f, 0x49, 0xe9, 0x4d, 0x47, 0xe9,  0x67, 0x47, 0xf5, 0x55, 0x37, 0xe3, 0x59, 0x3b, 
+	 0xe5, 0x53, 0x35, 0xdd, 0x45, 0x41, 0xd7, 0x4d,  0x49, 0xdd, 0x23, 0x23, 0x4d, 0xdd, 0xdf, 0xff, 
+	 0x9d, 0x79, 0x4d, 0x8b, 0x69, 0x3d, 0x7b, 0x59,  0x5f, 0x9b, 0x79, 0x7f, 0xff, 0xef, 0xf3, 0xff, 
+	 0xe9, 0xed, 0xfb, 0xef, 0xf3, 0xff, 0xf5, 0xf9,  0x9f, 0x8d, 0x91, 0x5f, 0x4d, 0x53, 0x59, 0x39, 
+	 0x41, 0x51, 0x2f, 0x37, 0x55, 0x33, 0x3b, 0x53,  0x31, 0x39, 0x0b, 0x00, 0x02, 0xff, 0xfd, 0xff, 
+	 0xf5, 0xfd, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfd, 0xff,  0xfb, 0xeb, 0xf1, 0xe9, 0xff, 0xfd, 0xfd, 0x73, 
+	 0x65, 0x65, 0x45, 0x23, 0x31, 0x53, 0x31, 0x3f,  0x53, 0x31, 0x43, 0x4f, 0x2d, 0x3f, 0x4d, 0x37, 
+	 0x43, 0xff, 0xfb, 0xff, 0xff, 0xfd, 0xfd, 0xff,  0xf9, 0xf9, 0xff, 0xf3, 0xe3, 0xff, 0xe9, 0xd9, 
+	 0xa7, 0x75, 0x5f, 0x99, 0x67, 0x51, 0xa5, 0x5f,  0x59, 0x97, 0x51, 0x4b, 0xd3, 0xcf, 0xfd, 0x63, 
+	 0x5f, 0x8d, 0x2f, 0x35, 0xdd, 0x2b, 0x31, 0xd9,  0x49, 0x41, 0xf1, 0x3b, 0x33, 0xe3, 0x4f, 0x49, 
+	 0xf3, 0x3f, 0x39, 0xe3, 0x41, 0x47, 0xe3, 0x4b,  0x4f, 0xeb, 0x47, 0x45, 0x5f, 0xa7, 0xa5, 0xbf, 
+	 0x9f, 0x5b, 0x3f, 0x95, 0x51, 0x33, 0x99, 0x61,  0x5b, 0xe5, 0xad, 0xa5, 0xff, 0xf7, 0xed, 0xf3, 
+	 0xcf, 0xc7, 0xff, 0xff, 0xfb, 0xff, 0xfb, 0xf7,  0xf3, 0xe1, 0xe1, 0x69, 0x57, 0x57, 0x57, 0x39, 
+	 0x41, 0x49, 0x29, 0x33, 0x53, 0x33, 0x41, 0x61,  0x3f, 0x4d, 0x37, 0x25, 0x31, 0xff, 0xfb, 0xff, 
+	 0xf5, 0xf7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf3, 0xf9,  0xf1, 0xf9, 0xff, 0xf7, 0xff, 0xfd, 0xfd, 0x5f, 
+	 0x51, 0x51, 0x53, 0x31, 0x3f, 0x59, 0x39, 0x47,  0x55, 0x33, 0x45, 0x53, 0x31, 0x43, 0x5d, 0x47, 
+	 0x53, 0xff, 0xf3, 0xfd, 0xff, 0xf3, 0xf1, 0xdd,  0xc9, 0xc9, 0xa1, 0x7f, 0x71, 0xa7, 0x85, 0x77, 
+	 0x93, 0x61, 0x4b, 0x89, 0x57, 0x41, 0x99, 0x53,  0x4d, 0x9f, 0x59, 0x53, 0xcd, 0xc7, 0xf7, 0x5b, 
+	 0x55, 0x85, 0x33, 0x39, 0xe1, 0x49, 0x4d, 0xf5,  0x3b, 0x33, 0xe3, 0x49, 0x41, 0xf1, 0x37, 0x31, 
+	 0xd9, 0x4b, 0x45, 0xef, 0x3d, 0x43, 0xdf, 0x3d,  0x43, 0xdf, 0x31, 0x2f, 0x49, 0x61, 0x5f, 0x79, 
+	 0xa5, 0x61, 0x45, 0xa9, 0x65, 0x47, 0x91, 0x59,  0x53, 0x8f, 0x57, 0x51, 0xab, 0x89, 0x7f, 0xa7, 
+	 0x85, 0x7b, 0xfb, 0xe9, 0xe3, 0xff, 0xf5, 0xef,  0xe1, 0xcd, 0xcf, 0x5f, 0x4d, 0x4f, 0x4b, 0x2b, 
+	 0x35, 0x55, 0x35, 0x3f, 0x59, 0x39, 0x47, 0x4b,  0x2b, 0x39, 0x51, 0x3f, 0x4b, 0xff, 0xfb, 0xff, 
+	 0xfd, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfd, 0xff,  0xff, 0xf7, 0xfb, 0xf9, 0xff, 0xf1, 0xfd, 0x67, 
+	 0x55, 0x61, 0x4f, 0x2b, 0x41, 0x51, 0x2d, 0x43,  0x61, 0x3d, 0x55, 0x4d, 0x29, 0x41, 0x51, 0x39, 
+	 0x49, 0xa1, 0x87, 0x97, 0xff, 0xfb, 0xff, 0xe1,  0xc5, 0xc9, 0x7f, 0x51, 0x49, 0x8b, 0x5d, 0x55, 
+	 0xa1, 0x63, 0x53, 0x99, 0x5b, 0x4b, 0x8d, 0x4f,  0x63, 0x8d, 0x4f, 0x63, 0xd1, 0xb9, 0xdb, 0x75, 
+	 0x5b, 0x7d, 0x5d, 0x53, 0xc5, 0x53, 0x49, 0xbb,  0x3d, 0x4b, 0xab, 0x4d, 0x5b, 0xbd, 0x43, 0x51, 
+	 0xaf, 0x4f, 0x5d, 0xbb, 0x55, 0x4d, 0xb5, 0x51,  0x49, 0xb1, 0x65, 0x4d, 0x5f, 0x71, 0x59, 0x6b, 
+	 0x93, 0x55, 0x55, 0x95, 0x57, 0x57, 0x9f, 0x5d,  0x59, 0x8f, 0x4d, 0x47, 0x89, 0x5b, 0x57, 0x93, 
+	 0x65, 0x61, 0xff, 0xe5, 0xe7, 0xff, 0xf3, 0xf5,  0x3f, 0x27, 0x31, 0x51, 0x3b, 0x45, 0x51, 0x2f, 
+	 0x41, 0x59, 0x37, 0x49, 0x53, 0x31, 0x45, 0x51,  0x2f, 0x43, 0x4d, 0x39, 0x4d, 0xff, 0xf5, 0xff, 
+	 0xf9, 0xf7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf9, 0xfd,  0xfd, 0xf9, 0xfd, 0xfd, 0xff, 0xf7, 0xff, 0x75, 
+	 0x63, 0x6d, 0x53, 0x2f, 0x45, 0x4f, 0x2b, 0x41,  0x4d, 0x29, 0x41, 0x51, 0x2d, 0x45, 0x5b, 0x43, 
+	 0x53, 0x51, 0x37, 0x47, 0xff, 0xef, 0xf3, 0xff,  0xe7, 0xeb, 0x99, 0x6d, 0x65, 0x81, 0x53, 0x4b, 
+	 0x93, 0x55, 0x45, 0x9f, 0x61, 0x51, 0x8d, 0x4f,  0x63, 0x8b, 0x4d, 0x61, 0x8d, 0x75, 0x97, 0x55, 
+	 0x3b, 0x5d, 0x33, 0x29, 0x9b, 0x31, 0x27, 0x99,  0x27, 0x35, 0x95, 0x2d, 0x3b, 0x9d, 0x2d, 0x3b, 
+	 0x99, 0x2b, 0x39, 0x97, 0x2f, 0x27, 0x8f, 0x31,  0x29, 0x91, 0x5f, 0x47, 0x59, 0x73, 0x5b, 0x6d, 
+	 0x99, 0x5b, 0x5b, 0x91, 0x53, 0x53, 0x91, 0x4f,  0x49, 0xa3, 0x61, 0x5b, 0x91, 0x63, 0x5f, 0x9b, 
+	 0x6d, 0x69, 0xff, 0xe5, 0xe7, 0xc9, 0xad, 0xaf,  0x65, 0x4f, 0x59, 0x51, 0x39, 0x43, 0x57, 0x35, 
+	 0x47, 0x4f, 0x2d, 0x3f, 0x55, 0x33, 0x47, 0x57,  0x33, 0x49, 0x53, 0x3f, 0x53, 0xff, 0xf7, 0xff, 
+	 0xfb, 0xfb, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf9, 0xff,  0xff, 0xf7, 0xfd, 0xff, 0xff, 0xf9, 0xff, 0x55, 
+	 0x45, 0x53, 0x57, 0x31, 0x47, 0x51, 0x2b, 0x41,  0x51, 0x2b, 0x43, 0x55, 0x2f, 0x47, 0x3b, 0x1b, 
+	 0x31, 0x61, 0x43, 0x57, 0x61, 0x43, 0x51, 0xff,  0xf3, 0xff, 0xa7, 0x79, 0x7f, 0x77, 0x49, 0x4f, 
+	 0x9f, 0x5f, 0x63, 0x93, 0x53, 0x57, 0x79, 0x57,  0x65, 0x77, 0x55, 0x63, 0x69, 0x3b, 0x49, 0x5d, 
+	 0x2f, 0x3d, 0x53, 0x23, 0x47, 0x55, 0x25, 0x49,  0x4f, 0x39, 0x4d, 0x49, 0x35, 0x47, 0x4f, 0x3b, 
+	 0x4b, 0x47, 0x33, 0x43, 0x57, 0x27, 0x45, 0x55,  0x25, 0x43, 0x75, 0x45, 0x4b, 0x87, 0x57, 0x5d, 
+	 0x85, 0x63, 0x67, 0x7d, 0x59, 0x5d, 0xad, 0x6f,  0x71, 0x81, 0x41, 0x45, 0x8d, 0x5f, 0x65, 0xf1, 
+	 0xc3, 0xc9, 0xf7, 0xd9, 0xe3, 0x61, 0x45, 0x4f,  0x49, 0x2b, 0x3f, 0x4f, 0x31, 0x45, 0x55, 0x2f, 
+	 0x47, 0x53, 0x2d, 0x45, 0x55, 0x2d, 0x47, 0x55,  0x2f, 0x49, 0x31, 0x1f, 0x31, 0xff, 0xf7, 0xff, 
+	 0xf3, 0xf7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf9, 0xff,  0xff, 0xf1, 0xf7, 0xff, 0xff, 0xf9, 0xff, 0x25, 
+	 0x13, 0x23, 0x55, 0x2f, 0x45, 0x51, 0x2b, 0x41,  0x63, 0x3d, 0x55, 0x4d, 0x27, 0x3f, 0x65, 0x45, 
+	 0x5b, 0x41, 0x23, 0x37, 0x6b, 0x4d, 0x59, 0x3d,  0x1f, 0x2b, 0xff, 0xdb, 0xdf, 0x95, 0x67, 0x6d, 
+	 0x95, 0x55, 0x59, 0x9f, 0x5f, 0x63, 0x75, 0x55,  0x63, 0x71, 0x51, 0x5f, 0x5b, 0x2d, 0x3b, 0x65, 
+	 0x37, 0x45, 0x59, 0x29, 0x4d, 0x57, 0x27, 0x4b,  0x4b, 0x35, 0x49, 0x43, 0x2f, 0x41, 0x45, 0x31, 
+	 0x41, 0x43, 0x2f, 0x41, 0x61, 0x31, 0x4f, 0x55,  0x25, 0x43, 0x6f, 0x3f, 0x45, 0x73, 0x43, 0x49, 
+	 0x7d, 0x59, 0x5d, 0x7d, 0x5b, 0x5f, 0x89, 0x49,  0x4d, 0x9f, 0x5f, 0x63, 0xb3, 0x85, 0x8b, 0xed, 
+	 0xbf, 0xc3, 0x33, 0x15, 0x21, 0x55, 0x39, 0x43,  0x4f, 0x31, 0x45, 0x4f, 0x31, 0x45, 0x4f, 0x29, 
+	 0x41, 0x5f, 0x39, 0x51, 0x55, 0x2d, 0x47, 0x53,  0x2b, 0x45, 0x19, 0x07, 0x19, 0xff, 0xf3, 0xff, 
+	 0xef, 0xf3, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf1, 0xfd,  0xff, 0xe7, 0xf3, 0xfb, 0xff, 0xfb, 0xff, 0x3d, 
+	 0x31, 0x3d, 0x57, 0x33, 0x43, 0x51, 0x2d, 0x3d,  0x65, 0x3b, 0x4d, 0x53, 0x29, 0x39, 0x3d, 0x1f, 
+	 0x2d, 0x59, 0x3b, 0x49, 0x43, 0x29, 0x37, 0x6d,  0x51, 0x5f, 0x49, 0x23, 0x37, 0x57, 0x31, 0x45, 
+	 0x77, 0x41, 0x57, 0x83, 0x4d, 0x63, 0x61, 0x49,  0x4b, 0x55, 0x3d, 0x3f, 0x69, 0x35, 0x45, 0x67, 
+	 0x33, 0x43, 0x6d, 0x39, 0x39, 0x67, 0x33, 0x31,  0x5b, 0x2f, 0x3d, 0x5d, 0x31, 0x3f, 0x5b, 0x2d, 
+	 0x3b, 0x5d, 0x2f, 0x3d, 0x75, 0x3d, 0x3d, 0x65,  0x2d, 0x2d, 0x69, 0x33, 0x43, 0x63, 0x2d, 0x3d, 
+	 0x63, 0x45, 0x49, 0x65, 0x47, 0x4b, 0x91, 0x61,  0x69, 0x49, 0x17, 0x1f, 0x6d, 0x4b, 0x55, 0x6d, 
+	 0x4b, 0x55, 0x49, 0x2d, 0x3d, 0x49, 0x2d, 0x3f,  0x61, 0x41, 0x55, 0x49, 0x29, 0x3d, 0x5d, 0x31, 
+	 0x47, 0x5f, 0x33, 0x49, 0x5b, 0x35, 0x49, 0x5d,  0x37, 0x4b, 0x57, 0x4d, 0x55, 0xff, 0xf9, 0xff, 
+	 0xf3, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xef, 0xfb,  0xff, 0xed, 0xf9, 0xff, 0xff, 0xfb, 0xff, 0xa9, 
+	 0x9d, 0xa9, 0x65, 0x3f, 0x4f, 0x57, 0x33, 0x43,  0x53, 0x29, 0x3b, 0x5f, 0x35, 0x47, 0x57, 0x39, 
+	 0x47, 0x5d, 0x3d, 0x4d, 0x53, 0x37, 0x45, 0x47,  0x2d, 0x3b, 0x5d, 0x37, 0x4b, 0x5b, 0x35, 0x49, 
+	 0x6b, 0x37, 0x4b, 0x6f, 0x39, 0x4f, 0x53, 0x3b,  0x3d, 0x45, 0x2d, 0x2f, 0x6d, 0x3b, 0x49, 0x5d, 
+	 0x2b, 0x39, 0x6b, 0x37, 0x35, 0x63, 0x2f, 0x2f,  0x57, 0x2b, 0x39, 0x61, 0x35, 0x43, 0x61, 0x33, 
+	 0x41, 0x5d, 0x2f, 0x3d, 0x6b, 0x33, 0x33, 0x67,  0x2f, 0x2f, 0x67, 0x31, 0x41, 0x65, 0x2d, 0x3d, 
+	 0x55, 0x37, 0x3b, 0x51, 0x35, 0x37, 0x5d, 0x2b,  0x33, 0x69, 0x37, 0x3f, 0x4f, 0x2d, 0x37, 0x5b, 
+	 0x37, 0x41, 0x53, 0x37, 0x47, 0x51, 0x35, 0x45,  0x4d, 0x2b, 0x41, 0x55, 0x33, 0x49, 0x63, 0x37, 
+	 0x4d, 0x49, 0x1d, 0x35, 0x59, 0x33, 0x47, 0x67,  0x41, 0x53, 0xcd, 0xc1, 0xc9, 0xff, 0xfb, 0xff, 
+	 0xf3, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xef, 0xff,  0xff, 0xef, 0xff, 0xff, 0xff, 0xfd, 0xff, 0xf5, 
+	 0xed, 0xf3, 0x6b, 0x49, 0x4f, 0x5b, 0x39, 0x3f,  0x55, 0x2b, 0x33, 0x65, 0x3b, 0x43, 0x55, 0x37, 
+	 0x3f, 0x47, 0x29, 0x2f, 0x4b, 0x33, 0x41, 0x4b,  0x33, 0x41, 0x49, 0x2b, 0x41, 0x53, 0x35, 0x4b, 
+	 0x55, 0x29, 0x49, 0x57, 0x2b, 0x49, 0x5b, 0x37,  0x39, 0x55, 0x2f, 0x33, 0x5d, 0x31, 0x51, 0x53, 
+	 0x27, 0x47, 0x4f, 0x35, 0x3d, 0x4b, 0x31, 0x39,  0x45, 0x25, 0x57, 0x4b, 0x29, 0x5d, 0x4d, 0x29, 
+	 0x5f, 0x4b, 0x27, 0x5d, 0x4d, 0x2d, 0x39, 0x53,  0x33, 0x3f, 0x5b, 0x27, 0x4f, 0x61, 0x2d, 0x55, 
+	 0x5f, 0x31, 0x3d, 0x5d, 0x2f, 0x3b, 0x63, 0x3f,  0x47, 0x6d, 0x47, 0x51, 0x45, 0x2b, 0x35, 0x39, 
+	 0x1f, 0x29, 0x59, 0x41, 0x51, 0x47, 0x2f, 0x3f,  0x51, 0x2d, 0x41, 0x57, 0x35, 0x49, 0x5d, 0x2f, 
+	 0x43, 0x53, 0x25, 0x39, 0x53, 0x31, 0x3b, 0x67,  0x43, 0x4d, 0xff, 0xfd, 0xf9, 0xff, 0xfd, 0xfb, 
+	 0xf1, 0xff, 0xf9, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf1, 0xff,  0xff, 0xe9, 0xfb, 0xfd, 0xfd, 0xf5, 0xfb, 0xfb, 
+	 0xf3, 0xf7, 0x63, 0x41, 0x47, 0x55, 0x33, 0x39,  0x5f, 0x35, 0x3d, 0x59, 0x2f, 0x35, 0x4f, 0x31, 
+	 0x37, 0x5f, 0x41, 0x47, 0x3f, 0x27, 0x35, 0x57,  0x3d, 0x4b, 0x4d, 0x2f, 0x45, 0x4b, 0x2d, 0x43, 
+	 0x61, 0x35, 0x53, 0x57, 0x2b, 0x49, 0x5b, 0x37,  0x39, 0x5f, 0x3b, 0x3d, 0x55, 0x29, 0x49, 0x5b, 
+	 0x2f, 0x4d, 0x51, 0x37, 0x3d, 0x4f, 0x35, 0x3d,  0x49, 0x29, 0x5b, 0x43, 0x21, 0x55, 0x49, 0x25, 
+	 0x59, 0x4d, 0x29, 0x5f, 0x4f, 0x2f, 0x3b, 0x59,  0x39, 0x45, 0x55, 0x21, 0x49, 0x5f, 0x2b, 0x53, 
+	 0x5d, 0x2f, 0x3b, 0x65, 0x37, 0x43, 0x51, 0x2b,  0x35, 0x49, 0x23, 0x2d, 0x5b, 0x3f, 0x4b, 0x55, 
+	 0x3b, 0x45, 0x4f, 0x35, 0x45, 0x47, 0x2d, 0x3d,  0x4d, 0x29, 0x3d, 0x55, 0x31, 0x45, 0x53, 0x25, 
+	 0x39, 0x75, 0x47, 0x5b, 0x51, 0x2f, 0x39, 0x63,  0x41, 0x4b, 0xf7, 0xf1, 0xef, 0xff, 0xff, 0xfd, 
+	 0xf1, 0xff, 0xf9, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfb,  0xff, 0xff, 0xfb, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xc7, 0xc1, 0xc5, 0x49, 0x43, 0x47,  0x4f, 0x3f, 0x49, 0x3d, 0x2d, 0x37, 0x53, 0x33, 
+	 0x43, 0x4d, 0x2f, 0x3d, 0x53, 0x2b, 0x3f, 0x5b,  0x33, 0x45, 0x5d, 0x35, 0x49, 0x5b, 0x31, 0x47, 
+	 0x53, 0x31, 0x45, 0x53, 0x2f, 0x45, 0x55, 0x31,  0x43, 0x55, 0x31, 0x43, 0x55, 0x31, 0x43, 0x55, 
+	 0x31, 0x43, 0x55, 0x31, 0x43, 0x55, 0x31, 0x43,  0x55, 0x31, 0x43, 0x55, 0x31, 0x43, 0x55, 0x31, 
+	 0x43, 0x55, 0x31, 0x43, 0x55, 0x31, 0x43, 0x55,  0x31, 0x43, 0x55, 0x31, 0x43, 0x55, 0x31, 0x43, 
+	 0x55, 0x31, 0x43, 0x55, 0x31, 0x43, 0x4d, 0x29,  0x3f, 0x5b, 0x39, 0x4d, 0x5f, 0x35, 0x4b, 0x4f, 
+	 0x27, 0x3b, 0x5f, 0x31, 0x45, 0x55, 0x27, 0x3b,  0x61, 0x35, 0x45, 0x59, 0x2d, 0x3d, 0x55, 0x31, 
+	 0x3f, 0x59, 0x35, 0x41, 0x51, 0x43, 0x49, 0xcb,  0xbd, 0xc3, 0xf3, 0xf9, 0xf9, 0xf5, 0xfb, 0xfd, 
+	 0xef, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfd,  0xff, 0xff, 0xf5, 0xf9, 0xff, 0xff, 0xff, 0xfb, 
+	 0xf3, 0xf7, 0xfd, 0xf7, 0xfb, 0x43, 0x3d, 0x41,  0x45, 0x35, 0x3f, 0x4d, 0x3f, 0x47, 0x5b, 0x3d, 
+	 0x4b, 0x5d, 0x3d, 0x4d, 0x4d, 0x25, 0x39, 0x49,  0x21, 0x35, 0x59, 0x2f, 0x45, 0x53, 0x29, 0x3f, 
+	 0x49, 0x27, 0x3b, 0x57, 0x33, 0x49, 0x55, 0x31,  0x43, 0x55, 0x31, 0x43, 0x55, 0x31, 0x43, 0x55, 
+	 0x31, 0x43, 0x55, 0x31, 0x43, 0x55, 0x31, 0x43,  0x55, 0x31, 0x43, 0x55, 0x31, 0x43, 0x55, 0x31, 
+	 0x43, 0x55, 0x31, 0x43, 0x55, 0x31, 0x43, 0x55,  0x31, 0x43, 0x55, 0x31, 0x43, 0x55, 0x31, 0x43, 
+	 0x55, 0x31, 0x43, 0x55, 0x31, 0x43, 0x4f, 0x2b,  0x41, 0x53, 0x31, 0x45, 0x51, 0x29, 0x3d, 0x61, 
+	 0x37, 0x4d, 0x5f, 0x31, 0x45, 0x57, 0x29, 0x3d,  0x59, 0x2d, 0x3d, 0x65, 0x39, 0x49, 0x57, 0x33, 
+	 0x3f, 0x5b, 0x37, 0x45, 0x45, 0x37, 0x3d, 0xff,  0xf5, 0xfb, 0xfb, 0xff, 0xff, 0xfb, 0xff, 0xff, 
+	 0xd9, 0xed, 0xeb, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf9,  0xfd, 0xff, 0xfd, 0xff, 0xe9, 0xe7, 0xe9, 0xff, 
+	 0xff, 0xff, 0xf7, 0xf5, 0xf9, 0xd7, 0xd3, 0xd7,  0x5d, 0x51, 0x59, 0x43, 0x37, 0x3f, 0x35, 0x15, 
+	 0x25, 0x5d, 0x3d, 0x4d, 0x5d, 0x35, 0x47, 0x5d,  0x35, 0x49, 0x59, 0x2f, 0x45, 0x53, 0x2b, 0x3f, 
+	 0x61, 0x3f, 0x53, 0x4f, 0x2d, 0x41, 0x55, 0x2f,  0x43, 0x55, 0x2f, 0x43, 0x55, 0x2f, 0x43, 0x55, 
+	 0x2f, 0x43, 0x55, 0x2f, 0x43, 0x55, 0x2f, 0x43,  0x55, 0x2f, 0x43, 0x55, 0x2f, 0x43, 0x55, 0x2f, 
+	 0x43, 0x55, 0x2f, 0x43, 0x55, 0x2f, 0x43, 0x55,  0x2f, 0x43, 0x55, 0x2f, 0x43, 0x55, 0x2f, 0x43, 
+	 0x55, 0x2f, 0x43, 0x55, 0x2f, 0x43, 0x5b, 0x35,  0x49, 0x51, 0x2b, 0x3f, 0x5b, 0x31, 0x47, 0x49, 
+	 0x1f, 0x35, 0x5b, 0x33, 0x45, 0x5f, 0x37, 0x4b,  0x5f, 0x3b, 0x4b, 0x4b, 0x27, 0x37, 0x4b, 0x31, 
+	 0x3d, 0x7b, 0x61, 0x6b, 0xb7, 0xab, 0xb1, 0xff,  0xfb, 0xff, 0xeb, 0xef, 0xf1, 0xf9, 0xfd, 0xfd, 
+	 0xed, 0xf9, 0xf9, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf9,  0xfd, 0xff, 0xf7, 0xfb, 0xff, 0xff, 0xff, 0xff, 
+	 0xfb, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfd, 0xff,  0x4d, 0x41, 0x49, 0x4d, 0x41, 0x49, 0x77, 0x57, 
+	 0x67, 0x3b, 0x1b, 0x2b, 0x5f, 0x37, 0x49, 0x59,  0x31, 0x45, 0x55, 0x2b, 0x41, 0x63, 0x39, 0x4f, 
+	 0x3f, 0x1b, 0x2f, 0x59, 0x35, 0x49, 0x55, 0x2f,  0x43, 0x55, 0x2f, 0x43, 0x55, 0x2f, 0x43, 0x55, 
+	 0x2f, 0x43, 0x55, 0x2f, 0x43, 0x55, 0x2f, 0x43,  0x55, 0x2f, 0x43, 0x55, 0x2f, 0x43, 0x55, 0x2f, 
+	 0x43, 0x55, 0x2f, 0x43, 0x55, 0x2f, 0x43, 0x55,  0x2f, 0x43, 0x55, 0x2f, 0x43, 0x55, 0x2f, 0x43, 
+	 0x55, 0x2f, 0x43, 0x55, 0x2f, 0x43, 0x59, 0x33,  0x47, 0x53, 0x2d, 0x41, 0x55, 0x2d, 0x41, 0x6f, 
+	 0x47, 0x5b, 0x47, 0x1f, 0x33, 0x53, 0x2b, 0x3d,  0x59, 0x35, 0x45, 0x5d, 0x39, 0x49, 0x53, 0x39, 
+	 0x45, 0x41, 0x27, 0x31, 0xff, 0xf3, 0xf9, 0xff,  0xfd, 0xff, 0xf9, 0xfd, 0xff, 0xfd, 0xff, 0xff, 
+	 0xf5, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xfd, 0xf9, 0xfb, 0xf5, 0xf5, 0xf7, 0xfb, 
+	 0xfb, 0xfd, 0xef, 0xef, 0xf3, 0xf3, 0xf3, 0xf7,  0xff, 0xfd, 0xff, 0x31, 0x27, 0x2f, 0x55, 0x39, 
+	 0x45, 0x45, 0x29, 0x37, 0x5d, 0x35, 0x45, 0x61,  0x3b, 0x4b, 0x49, 0x23, 0x37, 0x4f, 0x29, 0x3d, 
+	 0x5b, 0x39, 0x4b, 0x4f, 0x2d, 0x3f, 0x57, 0x2f,  0x45, 0x57, 0x2f, 0x45, 0x57, 0x2f, 0x45, 0x57, 
+	 0x2f, 0x45, 0x57, 0x2f, 0x45, 0x57, 0x2f, 0x45,  0x57, 0x2f, 0x45, 0x57, 0x2f, 0x45, 0x57, 0x2f, 
+	 0x45, 0x57, 0x2f, 0x45, 0x57, 0x2f, 0x45, 0x57,  0x2f, 0x45, 0x57, 0x2f, 0x45, 0x57, 0x2f, 0x45, 
+	 0x57, 0x2f, 0x45, 0x57, 0x2f, 0x45, 0x57, 0x2d,  0x41, 0x57, 0x2d, 0x41, 0x61, 0x3b, 0x4f, 0x49, 
+	 0x23, 0x37, 0x4f, 0x2f, 0x3f, 0x63, 0x43, 0x53,  0x43, 0x2d, 0x39, 0x47, 0x31, 0x3d, 0x2d, 0x21, 
+	 0x29, 0xf7, 0xeb, 0xf3, 0xff, 0xf9, 0xfd, 0xf7,  0xf1, 0xf7, 0xff, 0xff, 0xff, 0xed, 0xed, 0xef, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf7, 0xf3,  0xf5, 0xff, 0xff, 0xff, 0xf9, 0xf9, 0xfb, 0xff, 
+	 0xff, 0xff, 0xfd, 0xfd, 0xff, 0xff, 0xff, 0xff,  0xfb, 0xf1, 0xf9, 0xf7, 0xeb, 0xf3, 0x37, 0x1b, 
+	 0x29, 0x65, 0x49, 0x55, 0x51, 0x2b, 0x3b, 0x4f,  0x29, 0x39, 0x69, 0x43, 0x57, 0x59, 0x33, 0x47, 
+	 0x4f, 0x2d, 0x3f, 0x59, 0x37, 0x49, 0x57, 0x2f,  0x45, 0x57, 0x2f, 0x45, 0x57, 0x2f, 0x45, 0x57, 
+	 0x2f, 0x45, 0x57, 0x2f, 0x45, 0x57, 0x2f, 0x45,  0x57, 0x2f, 0x45, 0x57, 0x2f, 0x45, 0x57, 0x2f, 
+	 0x45, 0x57, 0x2f, 0x45, 0x57, 0x2f, 0x45, 0x57,  0x2f, 0x45, 0x57, 0x2f, 0x45, 0x57, 0x2f, 0x45, 
+	 0x57, 0x2f, 0x45, 0x57, 0x2f, 0x45, 0x5d, 0x33,  0x45, 0x59, 0x2f, 0x41, 0x4b, 0x25, 0x39, 0x59, 
+	 0x33, 0x45, 0x47, 0x27, 0x37, 0x4f, 0x2f, 0x3f,  0x57, 0x41, 0x4d, 0x4b, 0x35, 0x41, 0xef, 0xe3, 
+	 0xeb, 0xff, 0xfd, 0xff, 0xf9, 0xf3, 0xf9, 0xff,  0xfd, 0xff, 0xf7, 0xf7, 0xf9, 0xfd, 0xfd, 0xff, 
+	 0xf5, 0xf7, 0xf9, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xf7, 0xfb, 0xfd, 0xef, 
+	 0xf3, 0xf5, 0xfd, 0xff, 0xff, 0xfd, 0xff, 0xff,  0xff, 0xfb, 0xff, 0xfd, 0xf7, 0xff, 0xff, 0xed, 
+	 0xf7, 0x2b, 0x13, 0x1d, 0x59, 0x35, 0x43, 0x63,  0x3f, 0x4d, 0x3f, 0x1b, 0x2b, 0x69, 0x45, 0x55, 
+	 0x45, 0x29, 0x37, 0x4b, 0x2f, 0x3d, 0x55, 0x2f,  0x45, 0x55, 0x2f, 0x45, 0x55, 0x2f, 0x45, 0x55, 
+	 0x2f, 0x45, 0x55, 0x2f, 0x45, 0x55, 0x2f, 0x45,  0x55, 0x2f, 0x45, 0x55, 0x2f, 0x45, 0x55, 0x2f, 
+	 0x45, 0x55, 0x2f, 0x45, 0x55, 0x2f, 0x45, 0x55,  0x2f, 0x45, 0x55, 0x2f, 0x45, 0x55, 0x2f, 0x45, 
+	 0x55, 0x2f, 0x45, 0x55, 0x2f, 0x45, 0x51, 0x29,  0x39, 0x59, 0x31, 0x41, 0x57, 0x37, 0x47, 0x59, 
+	 0x3b, 0x49, 0x45, 0x31, 0x3d, 0x61, 0x4f, 0x59,  0x04, 0x00, 0x06, 0xf5, 0xef, 0xf7, 0xe5, 0xe5, 
+	 0xeb, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfb,  0xfb, 0xff, 0xff, 0xf9, 0xfd, 0xff, 0xf9, 0xff, 
+	 0xff, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xf5, 0xf5, 0xf7, 0xed, 0xf1, 0xf3, 0xfd, 
+	 0xff, 0xff, 0xf7, 0xfb, 0xfd, 0xef, 0xf1, 0xf5,  0xff, 0xfd, 0xff, 0xf5, 0xef, 0xf5, 0xff, 0xef, 
+	 0xf9, 0xbf, 0xa7, 0xb1, 0x6d, 0x49, 0x57, 0x4f,  0x2b, 0x39, 0x59, 0x35, 0x45, 0x55, 0x31, 0x41, 
+	 0x4d, 0x31, 0x3f, 0x53, 0x37, 0x45, 0x55, 0x2f,  0x45, 0x55, 0x2f, 0x45, 0x55, 0x2f, 0x45, 0x55, 
+	 0x2f, 0x45, 0x55, 0x2f, 0x45, 0x55, 0x2f, 0x45,  0x55, 0x2f, 0x45, 0x55, 0x2f, 0x45, 0x55, 0x2f, 
+	 0x45, 0x55, 0x2f, 0x45, 0x55, 0x2f, 0x45, 0x55,  0x2f, 0x45, 0x55, 0x2f, 0x45, 0x55, 0x2f, 0x45, 
+	 0x55, 0x2f, 0x45, 0x55, 0x2f, 0x45, 0x5d, 0x35,  0x45, 0x51, 0x2b, 0x3b, 0x51, 0x31, 0x41, 0x57, 
+	 0x39, 0x47, 0x55, 0x41, 0x4d, 0x37, 0x25, 0x2f,  0xff, 0xfd, 0xff, 0xed, 0xe7, 0xed, 0xf3, 0xf3, 
+	 0xf9, 0xff, 0xff, 0xff, 0xf1, 0xf1, 0xf5, 0xff,  0xff, 0xff, 0xff, 0xfd, 0xff, 0xff, 0xfb, 0xff, 
+	 0xff, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfd, 0xfb,  0xff, 0xfb, 0xfb, 0xff, 0xf9, 0xfb, 0xff, 0xf9, 
+	 0xfb, 0xff, 0xf7, 0xfd, 0xff, 0xf7, 0xfd, 0xff,  0xfd, 0xfb, 0xff, 0xfb, 0xf9, 0xfd, 0xf3, 0xdf, 
+	 0xe9, 0x55, 0x41, 0x4b, 0x51, 0x37, 0x41, 0x53,  0x39, 0x43, 0x49, 0x2f, 0x39, 0x4b, 0x31, 0x3b, 
+	 0x4f, 0x39, 0x43, 0x4b, 0x35, 0x3f, 0x51, 0x31,  0x43, 0x51, 0x31, 0x43, 0x51, 0x31, 0x43, 0x51, 
+	 0x31, 0x43, 0x51, 0x31, 0x45, 0x51, 0x31, 0x45,  0x51, 0x31, 0x45, 0x51, 0x31, 0x45, 0x4f, 0x2f, 
+	 0x43, 0x4d, 0x2d, 0x41, 0x4d, 0x2d, 0x41, 0x51,  0x31, 0x43, 0x53, 0x33, 0x47, 0x55, 0x35, 0x47, 
+	 0x51, 0x31, 0x43, 0x4d, 0x2d, 0x41, 0x4f, 0x31,  0x3d, 0x5d, 0x3f, 0x4b, 0x61, 0x4d, 0x57, 0x13, 
+	 0x00, 0x07, 0xb3, 0xa9, 0xb1, 0xf9, 0xef, 0xf7,  0xe9, 0xeb, 0xf1, 0xfb, 0xfd, 0xff, 0xfb, 0xff, 
+	 0xff, 0xfb, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xfd, 0xff, 0xff, 0xfd, 0xff, 
+	 0xff, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xfb, 0xff, 0xff, 0xfd, 
+	 0xff, 0xff, 0xfb, 0xff, 0xff, 0xfb, 0xff, 0xff,  0xff, 0xfd, 0xff, 0xff, 0xfb, 0xff, 0x61, 0x4d, 
+	 0x57, 0x5d, 0x49, 0x53, 0x53, 0x39, 0x43, 0x49,  0x2d, 0x39, 0x55, 0x3b, 0x47, 0x5f, 0x45, 0x4f, 
+	 0x41, 0x2b, 0x35, 0x69, 0x53, 0x5d, 0x65, 0x45,  0x57, 0x5d, 0x3d, 0x51, 0x55, 0x35, 0x47, 0x4f, 
+	 0x2f, 0x43, 0x51, 0x31, 0x43, 0x51, 0x31, 0x43,  0x4f, 0x2f, 0x43, 0x4d, 0x2d, 0x3f, 0x4b, 0x2b, 
+	 0x3f, 0x53, 0x33, 0x45, 0x57, 0x37, 0x49, 0x51,  0x31, 0x45, 0x49, 0x29, 0x3b, 0x49, 0x29, 0x3b, 
+	 0x55, 0x35, 0x49, 0x63, 0x43, 0x55, 0x69, 0x4d,  0x57, 0x27, 0x09, 0x15, 0xbf, 0xa9, 0xb3, 0xff, 
+	 0xfb, 0xff, 0xff, 0xfd, 0xff, 0xff, 0xf9, 0xff,  0xfd, 0xff, 0xff, 0xed, 0xef, 0xf5, 0xfb, 0xff, 
+	 0xff, 0xfb, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xfd, 0xff, 0xff, 0xfd, 0xff, 
+	 0xff, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfd,  0xff, 0xff, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xfb, 0xff, 0xff, 0xfb, 0xff, 0xff,  0xff, 0xff, 0xff, 0xfd, 0xfd, 0xff, 0x3b, 0x2d, 
+	 0x33, 0x55, 0x47, 0x4d, 0x47, 0x33, 0x39, 0x47,  0x33, 0x39, 0x5f, 0x4f, 0x55, 0x53, 0x41, 0x49, 
+	 0xc9, 0xbf, 0xc3, 0xdf, 0xd5, 0xdb, 0x5f, 0x4d,  0x59, 0x55, 0x41, 0x4f, 0x49, 0x37, 0x43, 0x47, 
+	 0x35, 0x41, 0x4d, 0x3b, 0x47, 0x55, 0x43, 0x4f,  0x59, 0x45, 0x53, 0x57, 0x45, 0x51, 0x4d, 0x3b, 
+	 0x47, 0x57, 0x45, 0x51, 0x5d, 0x4b, 0x57, 0x59,  0x45, 0x53, 0x4f, 0x3d, 0x49, 0x51, 0x3d, 0x4b, 
+	 0x5f, 0x4d, 0x59, 0x6f, 0x5b, 0x69, 0xff, 0xf3,  0xf9, 0xff, 0xfd, 0xff, 0xff, 0xfd, 0xff, 0xff, 
+	 0xf5, 0xf9, 0xf9, 0xf5, 0xf9, 0xfd, 0xfb, 0xff,  0xef, 0xf1, 0xf5, 0xfd, 0xff, 0xff, 0xfb, 0xff, 
+	 0xff, 0xfb, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfd,  0xff, 0xff, 0xfd, 0xff, 0xfd, 0xfd, 0xff, 0xfd, 
+	 0xfd, 0xff, 0xfb, 0xff, 0xff, 0xf9, 0xff, 0xff,  0xfd, 0xfd, 0xff, 0xfb, 0xfb, 0xff, 0x77, 0x69, 
+	 0x6f, 0x4d, 0x3f, 0x45, 0x3f, 0x2b, 0x31, 0x49,  0x35, 0x3d, 0xc5, 0xb5, 0xbb, 0xf1, 0xe1, 0xe7, 
+	 0xff, 0xfd, 0xff, 0xff, 0xfd, 0xff, 0xff, 0xfb,  0xff, 0xff, 0xfb, 0xff, 0xff, 0xf7, 0xff, 0xff, 
+	 0xed, 0xf9, 0xe7, 0xd5, 0xe3, 0xc5, 0xb3, 0xc1,  0x9f, 0x8d, 0x9b, 0x87, 0x73, 0x81, 0x9f, 0x8d, 
+	 0x99, 0xa9, 0x97, 0xa5, 0xbb, 0xa9, 0xb7, 0xd1,  0xbf, 0xcb, 0xe7, 0xd5, 0xe1, 0xf9, 0xe7, 0xf5, 
+	 0xff, 0xf5, 0xff, 0xff, 0xfb, 0xff, 0xff, 0xf7,  0xfd, 0xff, 0xf9, 0xff, 0xff, 0xf5, 0xf9, 0xff, 
+	 0xfd, 0xff, 0xfd, 0xfb, 0xff, 0xff, 0xff, 0xff,  0xfd, 0xff, 0xff, 0xfb, 0xff, 0xff, 0xfb, 0xff, 
+	 0xff, 0xfb, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfd,  0xff, 0xff, 0xfb, 0xff, 0xfd, 0xfb, 0xff, 0xfd, 
+	 0xfd, 0xff, 0xfb, 0xff, 0xff, 0xfb, 0xff, 0xff,  0xfd, 0xfb, 0xff, 0xfb, 0xf9, 0xfd, 0xdf, 0xd5, 
+	 0xd9, 0x6d, 0x63, 0x67, 0x41, 0x35, 0x39, 0xeb,  0xdd, 0xe1, 0xff, 0xff, 0xff, 0xff, 0xf9, 0xfb, 
+	 0xfb, 0xfb, 0xfd, 0xf5, 0xf5, 0xf7, 0xff, 0xfb,  0xff, 0xff, 0xf9, 0xfd, 0xfb, 0xf5, 0xf9, 0xf7, 
+	 0xf1, 0xf5, 0xf7, 0xf1, 0xf7, 0xfd, 0xf7, 0xfd,  0xff, 0xfd, 0xff, 0xff, 0xfd, 0xff, 0xfd, 0xf7, 
+	 0xfd, 0xfd, 0xf7, 0xfd, 0xff, 0xf9, 0xff, 0xff,  0xfd, 0xff, 0xff, 0xfd, 0xff, 0xff, 0xfd, 0xff, 
+	 0xff, 0xfd, 0xff, 0xff, 0xfb, 0xff, 0xf9, 0xf9,  0xfb, 0xff, 0xff, 0xff, 0xf7, 0xf7, 0xf9, 0xfd, 
+	 0xfd, 0xff, 0xff, 0xff, 0xff, 0xef, 0xef, 0xf1,  0xef, 0xef, 0xf1, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfd,  0xff, 0xff, 0xfd, 0xff, 0xff, 0xfd, 0xff, 0xff, 
+	 0xff, 0xff, 0xfd, 0xff, 0xff, 0xfd, 0xff, 0xff,  0xff, 0xfd, 0xff, 0xfd, 0xfb, 0xff, 0xff, 0xfd, 
+	 0xff, 0x2b, 0x21, 0x25, 0x4f, 0x43, 0x47, 0xff,  0xf3, 0xf7, 0xf9, 0xf1, 0xf5, 0xff, 0xff, 0xff, 
+	 0xf7, 0xf7, 0xf9, 0xfd, 0xfd, 0xff, 0xfb, 0xf5,  0xf9, 0xff, 0xfb, 0xff, 0xff, 0xfd, 0xff, 0xff, 
+	 0xfd, 0xff, 0xff, 0xfd, 0xff, 0xff, 0xfb, 0xff,  0xfd, 0xf7, 0xfd, 0xfd, 0xf7, 0xfb, 0xff, 0xfd, 
+	 0xff, 0xff, 0xfd, 0xff, 0xff, 0xfd, 0xff, 0xff,  0xfd, 0xff, 0xfd, 0xf7, 0xfd, 0xf9, 0xf3, 0xf9, 
+	 0xf9, 0xf3, 0xf7, 0xf9, 0xf3, 0xf9, 0xf9, 0xf9,  0xfb, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfd, 
+	 0xfd, 0xff, 0xff, 0xff, 0xff, 0xfd, 0xfd, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfd,  0xff, 0xff, 0xfd, 0xff, 0xff, 0xfd, 0xff, 0xff, 
+	 0xfd, 0xff, 0xfd, 0xff, 0xff, 0xfd, 0xff, 0xff,  0xff, 0xff, 0xff, 0xfd, 0xfd, 0xff, 0xf7, 0xf1, 
+	 0xf3, 0xd5, 0xcf, 0xd1, 0xdd, 0xd3, 0xd7, 0xf9,  0xef, 0xf3, 0xff, 0xff, 0xff, 0xfd, 0xf9, 0xfd, 
+	 0xfb, 0xff, 0xff, 0xf9, 0xff, 0xff, 0xf9, 0xfb,  0xfd, 0xfb, 0xfb, 0xfd, 0xfb, 0xfb, 0xfd, 0xf9, 
+	 0xfb, 0xfd, 0xf9, 0xfb, 0xfd, 0xfb, 0xfd, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfb, 0xfb, 
+	 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xfb, 0xfd, 0xff, 0xfb, 0xfd, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf7, 0xff,  0xff, 0xe7, 0xf1, 0xf1, 0xf1, 0xf7, 0xf9, 0xf7, 
+	 0xfd, 0xff, 0xff, 0xff, 0xff, 0xfd, 0xfd, 0xff,  0xff, 0xfd, 0xff, 0xff, 0xfd, 0xff, 0xff, 0xfd, 
+	 0xff, 0xff, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xfb, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfd,  0xff, 0xff, 0xfd, 0xff, 0xff, 0xfd, 0xff, 0xff, 
+	 0xfd, 0xff, 0xfd, 0xff, 0xff, 0xfd, 0xff, 0xff,  0xfd, 0xfd, 0xff, 0xfb, 0xfb, 0xff, 0xff, 0xfb, 
+	 0xff, 0xf1, 0xeb, 0xed, 0xf7, 0xed, 0xf1, 0xff,  0xfd, 0xff, 0xf5, 0xf3, 0xf5, 0xff, 0xfb, 0xff, 
+	 0xf5, 0xfb, 0xfd, 0xfb, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xfd, 0xff, 0xff, 0xfb, 0xfb, 0xfd, 0xfb, 0xfd, 
+	 0xff, 0xfb, 0xfb, 0xfd, 0xfb, 0xfb, 0xfd, 0xfb,  0xfd, 0xff, 0xfd, 0xfd, 0xff, 0xfd, 0xff, 0xff, 
+	 0xfb, 0xfd, 0xff, 0xfb, 0xfb, 0xfd, 0xf7, 0xff,  0xff, 0xf3, 0xfd, 0xfd, 0xfb, 0xff, 0xff, 0xfb, 
+	 0xff, 0xff, 0xf9, 0xf9, 0xfb, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfd, 
+	 0xff, 0xff, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xfb, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
+};
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/README.txt
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/README.txt	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/README.txt	(revision 457)
@@ -0,0 +1,47 @@
+
+	TOPPERS/ASP Kernel（Release 1.9.3）
+		Toyohashi Open Platform for Embedded Real-Time Systems/
+		Advanced Standard Profile Kernel
+
+TOPPERS/ASPカーネル（以下，ASPカーネル）は，TOPPERS新世代カーネルの基盤
+となるものとして，TOPPERSプロジェクトにおいて開発したリアルタイムカーネ
+ルです．μITRON4.0仕様のスタンダードプロファイル準拠のリアルタイムカー
+ネルであるTOPPERS/JSPカーネルを拡張・改良する形で開発しました．
+
+【最初に読むべきドキュメント】
+
+ASPカーネルのユーザーズマニュアルが，doc/user.txtにあります．ASPカーネ
+ルを使用する場合には，まずはこのドキュメントからお読み下さい．
+
+【ファイルの閲覧にあたって】
+
+ASPカーネルのドキュメント（プレーンテキストファイル）およびソースファイ
+ルを読む際には，TABを4に設定してください．
+
+【利用条件】
+
+ASPカーネルの利用条件は，各ファイルの先頭に表示されているTOPPERSライセ
+ンスです．TOPPERSライセンスに関するFAQが，以下のページにあります．
+
+	http://www.toppers.jp/faq/faq_ct12.html
+
+【質問・バグレポート・意見等の送付先】
+
+ASPカーネルをより良いものにするためのご意見等を歓迎します．ASPカーネル
+に関する質問やバグレポート，ご意見等は，TOPPERSプロジェクトの会員は
+TOPPERS開発者メーリングリスト（dev@toppers.jp）宛またはASPカーネルのバ
+グトラッキングシステム（Trac）に，その他の方はTOPPERSユーザーズメーリン
+グリスト（users@toppers.jp）宛にお願いします．
+
+TOPPERSユーザーズメーリングリストへの登録方法については，以下のページに
+説明があります．
+
+	http://www.toppers.jp/community.html
+
+【ポーティングにあたって】
+
+ASPカーネルを，TOPPERSプロジェクトからオープンソースにすることを前提に，
+未サポートのターゲットにポーティングされる場合には，あらかじめご相談く
+ださると幸いです．
+
+以上
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/README_STM32M7.txt
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/README_STM32M7.txt	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/README_STM32M7.txt	(revision 457)
@@ -0,0 +1,71 @@
+
+	TOPPERS/ASP Kernel（Release 1.9.5）STM32M7
+		Toyohashi Open Platform for Embedded Real-Time Systems/
+		Advanced Standard Profile Kernel
+
+TOPPERS/ASP STM32M7は以下の６つのボードのGCCの開発環境に対応します．
+本パッケージは個別パッケージであるため、TOPPERS/ASPカーネルターゲット
+非依存部パッケージasp-1.9.3.tar.gzと組み合わせて使用してください．
+(1)STM社 STM32F746 Discoveryボード
+   Chip:STM32F746NGH6
+(2)STM社 STM32F746 nucleo-144ボード
+   Chip:STM32F746ZGT6
+(3)STM社 STM32F767 nucleo-144ボード
+   Chip:STM32F767ZT6
+(4)STM社 STM32F769 Discoveryボード
+   Chip:STM32F769NIH6
+(5)STM社 STM32F723 Discoveryボード
+   Chip:STM32F723IEK6
+(6)STM社 STM32H743 nucleo-144ボード
+   Chip:STM32H743ZIT6
+
+ASPの実行形態は以下の２つをサポートします．
+実行形態は、コンパイル時の変数DBGENVの設定で変更ができます．
+Makefileの設定で変更ができます．
+
+(1)RAM実行：ROMモニタ(rommon)で起動したボードに、UARTを用いて
+ASPの実行形式(srec)をダウンロードして実行する形態
+rommonのFLASH ROM書込みファイルはtools/rommonに置いてあります．
+DBGENVが設定されない場合、またはRAMが設定の場合、
+この形態のビルドを行います．
+
+(2)ROM実行：FLASH ROMに書き込んで実行する形態
+DBGENVにROMが設定の場合、この形態のビルドを行います．
+
+
+【ディレクトリ構成】
+
+arch/arm_m_gcc/common
+	cortex-mのコモン部
+arch/arm_m_gcc/stm32f7xx
+	stm32f7xxのchip依存部
+arch/arm_m_gcc/stm32h7xx
+	stm32h7xxのchip依存部
+arch/gcc
+	gccの環境部
+target/stm32f7discovery_gcc
+	STM32F746 Discoveryボードのターゲット依存部
+target/stm32f769discovery_gcc
+	STM32F769 Discoveryボードのターゲット依存部
+target/stm32f746nucleo144_gcc
+	STM32F746 nucleo-144ボードのターゲット依存部
+target/stm32f767nucleo144_gcc
+	STM32F767 nucleo-144ボードのターゲット依存部
+target/stm32f723discovery_gcc
+	STM32F723 Discoveryボードのターゲット依存部
+target/stm32h743nucleo144_gcc
+	STM32H743 nucleo-144ボードのターゲット依存部
+tools/rommon
+	ROMモニタとUARTの設定手順とROMモニタ書き込みバイナリファイル
+	ROMモニタのソース
+	STM32F46-Discovery用のSDCARD-PLAER2,3の開発環境や
+	STM32F746 nucleo-144でarduinoを動作させる環境は
+	aspにTOPPERS BASE PLATFORM(ST)を組み合わせることで構築できます
+	これらはTOPPERS教育コンテンツ基礎１，２の
+	STM32F4-Discoveryボード編にて配布します．
+
+1.9.x バージョン履歴
+	2016年07月23日	Release	1.9.2		最初のリリース
+	2017年05月01日	Release	1.9.3		STM32F767/STM32F769 Discoveryボード対応
+	2018年11月05日	Release 1.9.4		STM32F723 Discoveryボード対応
+	2019年07月24日	Release 1.9.5		STM32H743 Nucleoボード対応
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/arch/arm_m_gcc/MANIFEST
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/arch/arm_m_gcc/MANIFEST	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/arch/arm_m_gcc/MANIFEST	(revision 457)
@@ -0,0 +1,35 @@
+PACKAGE asp_arch_arm_m_gcc
+VERSION 1.9.2
+
+MANIFEST
+README.txt
+
+common/arm_m.h
+common/core.tf
+common/core_asm.inc
+common/core_cfg1_out.h
+common/core_check.tf
+common/core_config.c
+common/core_config.h
+common/core_config_v6m.h
+common/core_def.csv
+common/core_design.txt
+common/core_insn.h
+common/core_kernel.h
+common/core_offset.tf
+common/core_rename.def
+common/core_rename.h
+common/core_sil.h
+common/core_stddef.h
+common/core_support.S
+common/core_support_v6m.S
+common/core_test.h
+common/core_timer.c
+common/core_timer.cfg
+common/core_timer.h
+common/core_unrename.h
+common/core_user.txt
+common/Makefile.core
+common/start.S
+
+INCLUDE stm32f7xx/MANIFEST
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/arch/arm_m_gcc/README.txt
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/arch/arm_m_gcc/README.txt	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/arch/arm_m_gcc/README.txt	(revision 457)
@@ -0,0 +1,26 @@
+                  ARM-M依存部(GCC版) ディレクトリ解説
+
+                                   Last Modified: 2019 Jul 24 18:28:55
+
+
+本ディレクトリ（./arch/arm_m_gcc）は，armv7mアーキテクチャのコア及び，
+armv7mアーキテクチャのコアを用いたチップに依存し，コンパイラとしてGCC
+を対象した記述を置くためのディレクトリである．
+
+ターゲットディレクトリ（./target）との切り分けは，本ディレクトリは，特
+定のボードに依存しない再利用可能な記述を置こととし，ターゲットディレク
+トリは再利用の可能性が低いボードに依存した記述を置くこととする．
+
+再利用可能な範囲としては，armv7mアーキテクチャのコアを用いたチップをま
+でを想定している．そのため，本ディレクトリに置く依存部をチップ依存部と
+呼ぶ．各チップ依存部はチップ名でディレクトリを作成し，その下に関連する
+ファイルを置く．
+
+一方，armv7mアーキテクチャのコアに依存した記述は，コア依存部と呼び，
+commonディレクトリ以下に置く．各チップ依存部は必要に応じてコア依存部の
+ファイルを使用する．コア依存部に関しては，common/core_user.txt を参照
+のこと．
+
+チップによっては，コア依存部と同等の機能を持たない場合もある．その場合
+は，チップ依存部を作成せず，ターゲット依存部とコア依存部のファイルを組
+み合わせればよい．
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/arch/arm_m_gcc/common/Makefile.core
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/arch/arm_m_gcc/common/Makefile.core	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/arch/arm_m_gcc/common/Makefile.core	(revision 457)
@@ -0,0 +1,103 @@
+#
+#  @(#) $Id$
+# 
+
+#
+#		Makefile のプロセッサ依存部（ARM-M用）
+#
+
+# 
+#  コア依存部ディレクトリ名の定義 
+# 
+COREDIR = $(SRCDIR)/arch/$(PRC)_$(TOOL)/common
+
+#
+#  ツール依存部ディレクトリ名の定義 
+#
+TOOLDIR = $(SRCDIR)/arch/$(TOOL)
+
+#
+#  コンパイルオプション
+#
+COPTS := $(COPTS) -mthumb 
+INCLUDES := $(INCLUDES) -I$(COREDIR) -I$(TOOLDIR)
+LDFLAGS := $(LDFLAGS) 
+CDEFS := $(CDEFS)
+LIBS := $(LIBS)  -lgcc
+
+#
+#  カーネルに関する定義
+#
+KERNEL_DIR := $(KERNEL_DIR) $(COREDIR)
+KERNEL_ASMOBJS := $(KERNEL_ASMOBJS)
+KERNEL_COBJS := $(KERNEL_COBJS) core_config.o
+
+#
+#  コアのタイプによる違い
+#
+ifeq ($(CORE_TYPE),CORTEX_M7)
+	ARM_ARCH = ARMV7M
+	COPTS := $(COPTS) -mcpu=cortex-m7
+	CDEFS := $(CDEFS) -DTOPPERS_CORTEX_M4
+ifeq ($(FPU_ARCH_MACRO),__TARGET_FPU_FPV5_DP)
+	FPU_ARCH_OPT   = fpv5-d16
+else
+	FPU_ARCH_MACRO = __TARGET_FPU_FPV4_SP
+	FPU_ARCH_OPT   = fpv4-sp-d16
+endif
+else ifeq ($(CORE_TYPE),CORTEX_M4)
+	ARM_ARCH = ARMV7M
+	COPTS := $(COPTS) -mcpu=cortex-m4
+	CDEFS := $(CDEFS) -DTOPPERS_CORTEX_M4
+	FPU_ARCH_MACRO = __TARGET_FPU_FPV4_SP
+	FPU_ARCH_OPT   = fpv4-sp-d16
+else ifeq ($(CORE_TYPE),CORTEX_M0PLUS)
+	ARM_ARCH = ARMV6M
+	COPTS := $(COPTS) -mcpu=cortex-m0plus
+	CDEFS := $(CDEFS) -DTOPPERS_CORTEX_M0PLUS
+else ifeq ($(CORE_TYPE),CORTEX_M0)
+	ARM_ARCH = ARMV6M
+	COPTS := $(COPTS) -mcpu=cortex-m0
+	CDEFS := $(CDEFS) -DTOPPERS_CORTEX_M0
+else ifeq ($(CORE_TYPE),CORTEX_M3)
+	ARM_ARCH = ARMV7M
+	COPTS := $(COPTS) -mcpu=cortex-m3
+	CDEFS := $(CDEFS) -DTOPPERS_CORTEX_M3
+endif
+
+#
+#  アーキテクチャ毎に異なる設定
+#
+ifeq ($(ARM_ARCH),ARMV7M)
+	KERNEL_ASMOBJS := $(KERNEL_ASMOBJS) core_support.o
+	CDEFS := $(CDEFS) -D__TARGET_ARCH_THUMB=4
+else ifeq ($(ARM_ARCH),ARMV6M)
+	KERNEL_ASMOBJS := $(KERNEL_ASMOBJS) core_support_v6m.o
+	CDEFS := $(CDEFS) -D__TARGET_ARCH_THUMB=3
+endif
+
+#
+#  FPUの設定
+#
+ifeq ($(FPU_USAGE),FPU_NO_PRESERV)
+	COPTS := $(COPTS) -mfloat-abi=$(FPU_ABI) -mfpu=$(FPU_ARCH_OPT)
+	CDEFS := $(CDEFS) -D$(FPU_ARCH_MACRO) -DTOPPERS_FPU_ENABLE
+else ifeq ($(FPU_USAGE),FPU_NO_LAZYSTACKING)
+	COPTS := $(COPTS) -mfloat-abi=$(FPU_ABI) -mfpu=$(FPU_ARCH_OPT)
+	CDEFS := $(CDEFS) -D$(FPU_ARCH_MACRO) -DTOPPERS_FPU_ENABLE -DTOPPERS_FPU_NO_LAZYSTACKING -DTOPPERS_FPU_CONTEXT
+else ifeq ($(FPU_USAGE),FPU_LAZYSTACKING)
+	COPTS := $(COPTS) -mfloat-abi=$(FPU_ABI) -mfpu=$(FPU_ARCH_OPT)
+	CDEFS := $(CDEFS) -D$(FPU_ARCH_MACRO) -DTOPPERS_FPU_ENABLE -DTOPPERS_FPU_LAZYSTACKING -DTOPPERS_FPU_CONTEXT
+endif
+
+
+#
+#  依存関係の定義
+#
+cfg1_out.c: $(COREDIR)/core_def.csv
+kernel_cfg.timestamp: $(COREDIR)/core.tf
+
+#
+#  コンフィギュレータ関係の変数の定義
+#
+CFG_TABS := $(CFG_TABS) --cfg1-def-table $(COREDIR)/core_def.csv
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/arch/arm_m_gcc/common/arm_m.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/arch/arm_m_gcc/common/arm_m.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/arch/arm_m_gcc/common/arm_m.h	(revision 457)
@@ -0,0 +1,231 @@
+/*
+ *  TOPPERS/ASP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Advanced Standard Profile Kernel
+ * 
+ *  Copyright (C) 2008-2015 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *  ARMVx-Mのハードウェア資源の定義
+ */
+
+#ifndef ARM_M_H
+#define ARM_M_H
+
+#if !((__TARGET_ARCH_THUMB == 4) || (__TARGET_ARCH_THUMB == 3))
+#error __TARGET_ARCH_THUMB is not defined or other than 4(ARMv7)/3(ARMv6)
+#endif /* __TARGET_ARCH_THUMB == 4 */
+
+/*
+ *  EPSRのTビット
+ */
+#define EPSR_T   0x01000000
+
+/*
+ * IPSRの ISR NUMBER
+ */
+#define IPSR_ISR_NUMBER 0x1ff
+
+/*
+ *  例外・割込み発生時にスタック上に積まれる保存領域のサイズ
+ *  本カーネルでは例外フレームと呼ぶ
+ */
+#define EXC_FRAME_SIZE         (8*4)
+
+/*
+ *  例外・割込み発生時にLRに設定されるEXC_RETURNの値
+ */
+#define EXC_RETURN_PSP          0x04
+#define EXC_RETURN_HANDLER_MSP  0x00
+#define EXC_RETURN_TREAD_MSP    0x09
+#define EXC_RETURN_TREAD_PSP    0x0d
+#define EXC_RETURN_FP           0x10
+#define EXC_RETURN_FP_USED      0x00
+#define EXC_RETURN_FP_NONUSED   0x10
+#define EXC_RETURN_OTHER        0xFFFFFFE0
+
+/*
+ *  CONTROLレジスタ
+ */
+#define CONTROL_PSP            0x02
+#define CONTROL_MSP            0x00
+#define CONTROL_FPCA           0x04
+
+/*
+ *  例外番号
+ */
+#define EXCNO_NMI         2
+#define EXCNO_HARD        3
+#define EXCNO_MPU         4
+#define EXCNO_BUS         5
+#define EXCNO_USAGE       6
+#define EXCNO_SVCALL     11          
+#define EXCNO_DEBUG      12
+#define EXCNO_PENDSV     14
+
+/*
+ *  例外番号の最小値と最大値
+ */
+#define TMIN_EXCNO   2
+#define TMAX_EXCNO  14
+
+/*
+ *  割込み番号
+ */
+#define IRQNO_SYSTICK    15
+
+/*
+ *  割込み番号の最小値
+ */
+#define TMIN_INTNO       15
+
+/*
+ *  例外フレームのオフセット
+ */
+#define P_EXCINF_OFFSET_EXC_RETURN  0x01
+#define P_EXCINF_OFFSET_IIPM        0x00
+#define P_EXCINF_OFFSET_XPSR        0x09
+#define P_EXCINF_OFFSET_PC          0x08
+
+/*
+ *  NVIC関連
+ */
+
+/*
+ *  システムハンドラーコントロールレジスタ
+ */
+#define NVIC_SYS_HND_CTRL   0xE000ED24
+
+/*
+ *  各例外の許可ビット
+ */
+#define NVIC_SYS_HND_CTRL_USAGE 0x00040000
+#define NVIC_SYS_HND_CTRL_BUS   0x00020000
+#define NVIC_SYS_HND_CTRL_MEM   0x00010000
+
+/*
+ *  優先度設定レジスタ
+ */
+#define NVIC_SYS_PRI1       0xE000ED18  // Sys. Handlers 4 to 7 Priority
+#define NVIC_SYS_PRI2       0xE000ED1C  // Sys. Handlers 8 to 11 Priority
+#define NVIC_SYS_PRI3       0xE000ED20  // Sys. Handlers 12 to 15 Priority
+#define NVIC_PRI0           0xE000E400  // IRQ 0 to 3 Priority Register
+
+/*
+ *  割込み許可レジスタ
+ */
+#define NVIC_SETENA0        0xE000E100  // IRQ 0 to 31 Set Enable Register
+
+/*
+ *  割込み禁止レジスタ
+ */
+#define NVIC_CLRENA0        0xE000E180  // IRQ 0 to 31 Set Disable Register
+
+/*
+ *  割込みセットペンディングレジスタ
+ */
+#define NVIC_ISER0          0xE000E200  // IRQ 0 to 31 Set-Pending Register
+
+/*
+ *  割込みクリアペンディングレジスタ
+ */
+#define NVIC_ICER0          0xE000E280  // IRQ 0 to 31 Clear-Pending Register
+
+/*
+ *  ベクタテーブルオフセットレジスタ
+ */
+#define NVIC_VECTTBL        0xE000ED08
+
+/*
+ *  割り込み制御と状態レジスタ
+ */
+#define NVIC_ICSR           0xE000ED04
+#define NVIC_PENDSVSET          (1 << 28)       /*  PenvSVC例外 */
+#define NVIC_PENDSTSET          (1 << 26)       /*  SYSTick例外 */
+
+
+/*
+ *  SYSTIC関連レジスタ
+ */
+#define SYSTIC_CONTROL_STATUS 0xE000E010
+#define SYSTIC_RELOAD_VALUE   0xE000E014
+#define SYSTIC_CURRENT_VALUE  0xE000E018
+#define SYSTIC_CALIBRATION    0xE000E01C
+
+#define SYSTIC_ENABLE    0x01
+#define SYSTIC_TICINT    0x02
+#define SYSTIC_CLKSOURCE 0x04
+#define SYSTIC_COUNTFLAG 0x10000
+
+#define SYSTIC_SKEW      0x40000000
+#define SYSTIC_NOREF     0x80000000
+#define SYSTIC_TENMS     0x00ffffff
+
+/*
+ * FPU関連レジスタ
+ */
+#if __TARGET_ARCH_THUMB == 4
+
+#define CPACR 0xE000ED88
+#define FPCCR 0xE000EF34
+
+#define CPACR_FPU_ENABLE 0x00f00000
+#define FPCCR_NO_PRESERV       0x00000000
+#define FPCCR_NO_LAZYSTACKING  0x80000000
+#define FPCCR_LAZYSTACKING     0xC0000000
+
+#endif /* __TARGET_ARCH_THUMB == 4 */
+
+
+#if defined(TOPPERS_CORTEX_M0) || defined(TOPPERS_CORTEX_M0PLUS)
+/*
+ *  M0/M0+固有の内容
+ */
+
+/*
+ *  割込み優先度の範囲
+ */
+#define TMIN_INTPRI		(-4)	/* 割込み優先度の最小値（最高値）*/
+#define TMAX_INTPRI		(-1)	/* 割込み優先度の最大値（最低値）*/
+
+/*
+ *  割込み優先度のビット幅
+ */
+#define TBITW_IPRI		2
+
+#endif /* defined(TOPPERS_CORTEX_M0) || defined(TOPPERS_CORTEX_M0PLUS) */
+
+#endif  /* ARM_M_H */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/arch/arm_m_gcc/common/core.tf
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/arch/arm_m_gcc/common/core.tf	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/arch/arm_m_gcc/common/core.tf	(revision 457)
@@ -0,0 +1,221 @@
+$ 
+$     パス2のアーキテクチャ依存テンプレート（ARM-M用）
+$ 
+
+$ 
+$  有効な割込み番号，割込みハンドラ番号
+$ 
+$INTNO_VALID = RANGE(15, TMAX_INTNO)$
+$INHNO_VALID = INTNO_VALID$
+
+$ 
+$  有効なCPU例外番号
+$ 
+$EXCNO_VALID = { 2,3,4,5,6,11,12,14 }$
+
+$ 
+$  ATT_ISRで使用できる割込み番号とそれに対応する割込みハンドラ番号
+$ 
+$INTNO_ATTISR_VALID = INTNO_VALID$
+$INHNO_ATTISR_VALID = INHNO_VALID$
+
+$ 
+$  DEF_INT／DEF_EXCで使用できる割込みハンドラ番号／CPU例外ハンドラ番号
+$ 
+$INHNO_DEFINH_VALID = INHNO_VALID$
+$EXCNO_DEFEXC_VALID = EXCNO_VALID$
+
+$ 
+$  CFG_INTで使用できる割込み番号と割込み優先度
+$  最大優先度はBASEPRIレジスタでマスクできない優先度（内部優先度'0'）
+$  そのため，カーネル管理外の割込みでのみ指定可能．
+$INTNO_CFGINT_VALID = INTNO_VALID$
+$INTPRI_CFGINT_VALID = RANGE(-(1 << TBITW_IPRI),-1)$
+           
+$ 
+$  標準テンプレートファイルのインクルード
+$ 
+$INCLUDE "kernel/kernel.tf"$
+
+/*$NL$
+$SPC$*  Target-dependent Definitions (ARM-M)$NL$
+$SPC$*/$NL$
+$NL$
+
+$ 
+$  ベクターテーブル
+$ 
+$FILE "kernel_cfg.c"$
+$NL$
+
+$IF ISFUNCTION("GEN_VECTOR_TABLE_VARNAME")$
+	$GEN_VECTOR_TABLE_VARNAME()$
+$ELSE$
+	$IF ISFUNCTION("VECTOR_ATTRIBUTE")$
+		$VECTOR_ATTRIBUTE()$
+	$ELSE$
+		__attribute__ ((section(".vector"))) $NL$
+	$END$
+	const FP _kernel_vector_table[] =      $NL$ 
+$END$
+{                                    $NL$
+	$TAB$(FP)(TOPPERS_ISTKPT(TOPPERS_ISTK, TOPPERS_ISTKSZ)), /* 0 The initial stack pointer */$NL$
+	$TAB$(FP)_kernel__start,                    /* 1 The reset handler */$NL$
+
+$FOREACH excno {2,3,...,14}$ 
+	$IF (excno == 11) && (__TARGET_ARCH_THUMB == 4) $
+		$TAB$(FP)(_kernel_svc_handler),        /* 11 SVCall handler */$NL$
+	$ELSE$
+		$IF (excno == 14) && (__TARGET_ARCH_THUMB == 3) $
+			$TAB$(FP)(pendsvc_handler),        /* 14 PandSVCall handler */$NL$
+		$ELSE$
+			$TAB$(FP)(_kernel_core_exc_entry),$SPC$$FORMAT("/* %d */", +excno)$$NL$
+		$END$
+	$END$
+$END$
+
+$FOREACH inhno INTNO_VALID$ 
+	$IF LENGTH(INH.INHNO[inhno]) && ((INH.INHATR[inhno] & TA_NONKERNEL) != 0)$
+		$TAB$(FP)($INH.INTHDR[inhno]$),
+	$ELSE$
+		$TAB$(FP)(_kernel_core_int_entry),
+	$END$
+	$SPC$$FORMAT("/* %d */", +inhno)$$NL$
+$END$
+
+
+$NL$};$NL$
+$NL$
+
+$NL$
+const FP _kernel_exc_tbl[] = $NL$
+{$NL$
+$FOREACH excno {0,1,...,14}$
+	$IF LENGTH(EXC.EXCNO[excno])$
+		$TAB$(FP)($EXC.EXCHDR[excno]$),
+	$ELSE$
+		$TAB$(FP)(_kernel_default_exc_handler),
+	$END$
+	$SPC$$FORMAT("/* %d */", +excno)$$NL$
+$END$
+
+
+$FOREACH inhno INTNO_VALID$
+	$IF LENGTH(INH.INHNO[inhno])$
+		$TAB$(FP)($INH.INTHDR[inhno]$),
+	$ELSE$
+		$TAB$(FP)(_kernel_default_int_handler),
+	$END$
+	$SPC$$FORMAT("/* %d */", +inhno)$$NL$
+$END$
+
+
+$NL$};$NL$
+$NL$
+
+$ 
+$  _kernel_bitpat_cfgintの生成
+$ 
+
+$bitpat_cfgint_num = 0$
+$bitpat_cfgint = 0$
+
+
+const uint32_t _kernel_bitpat_cfgint[
+$IF (TMAX_INTNO & 0x0f) == 0x00 $
+	$bitpat_cfgint_num = (TMAX_INTNO >> 4)$
+$ELSE$
+	$bitpat_cfgint_num = (TMAX_INTNO >> 4) + 1$
+$END$
+	$bitpat_cfgint_num$
+] = {$NL$
+$FOREACH num RANGE(0,(bitpat_cfgint_num-1))$
+$   //boost のバージョンによって挙動が変わるための対策
+$   //http://www.toppers.jp/TOPPERS-USERS/201004/msg00034.html
+	$bitpat_cfgint = 1-1$
+	$FOREACH inhno RANGE(num*32, (num*32)+31)$
+		$IF LENGTH(INH.INHNO[inhno])$
+			$bitpat_cfgint = bitpat_cfgint | (1 << (inhno & 0x01f))$
+		$END$
+	$END$
+	$TAB$UINT32_C($FORMAT("0x%08x", bitpat_cfgint)$), $NL$
+$END$
+
+$NL$};$NL$
+$NL$
+
+
+
+
+$IF __TARGET_ARCH_THUMB == 4 $
+
+$ 
+$  割込み優先度テーブル（内部表現）
+$ 
+const uint32_t _kernel_int_iipm_tbl[] = {$NL$
+$FOREACH excno {0,1,...,14}$
+	$TAB$$FORMAT("UINT32_C(0x%08x), /* 0x%03x */", 0, +excno)$$NL$
+$END$
+
+$FOREACH intno INTNO_VALID$
+	$IF LENGTH(INT.INTNO[intno])$
+		$intpri = (((1 << TBITW_IPRI) + INT.INTPRI[intno]) << (8 - TBITW_IPRI))$
+	$ELSE$
+$		// LSBを1にしているのは，割込み属性が設定されていないことを判
+$		// 別するためである．
+		$intpri = 0 $
+	$END$
+	$TAB$$FORMAT("UINT32_C(0x%08x), /* 0x%03x */", intpri, +intno)$$NL$
+$END$
+$NL$};$NL$
+$NL$
+
+$END$
+
+$IF __TARGET_ARCH_THUMB == 3 $
+
+$ 
+$  割込み優先度テーブル（内部表現）
+$ 
+const uint8_t _kernel_int_iipm_tbl[] = {$NL$
+$FOREACH excno {0,1,...,14}$
+	$TAB$$FORMAT("UINT8_C(0x%02x), /* 0x%03x */", 0, +excno)$$NL$
+$END$
+
+$FOREACH intno INTNO_VALID$
+	$IF LENGTH(INT.INTNO[intno])$
+		$intpri = (((1 << TBITW_IPRI) + INT.INTPRI[intno]))$
+	$ELSE$
+		$intpri = +255 $
+	$END$
+	$TAB$$FORMAT("UINT8_C(0x%02x), /* 0x%03x */", intpri, +intno)$$NL$
+$END$
+};$NL$
+$NL$
+
+$ 
+$  割込み優先度マスク毎の割込みを許可する割込み
+$ 
+const uint32_t _kernel_iipm_enable_irq_tbl[]={$NL$
+$FOREACH intpri {-4,-3,...,0}$
+	$enable_mask = 0$
+	$FOREACH intno RANGE(16, TMAX_INTNO)$
+		$IF LENGTH(INT.INTNO[intno]) && (INT.INTPRI[intno] < intpri)$
+			$enable_mask = enable_mask | (1 << (intno - 16))$
+		$END$
+	$END$
+	$TAB$$FORMAT("UINT32_C(0x%08x), /* %d(%d) */", enable_mask, intpri+4, intpri)$$NL$
+$END$
+};$NL$
+$NL$
+
+const uint8_t _kernel_iipm_enable_systic_tbl[]={$NL$
+$FOREACH intpri {-4,-3,...,0}$
+	$enable_mask = 0$
+	$IF LENGTH(INT.INTNO[15]) && (INT.INTPRI[15] < intpri)$
+		$enable_mask = 1$
+	$END$
+	$TAB$$FORMAT("UINT8_C(0x%02x), /* %d(%d) */", enable_mask, intpri+4, intpri)$$NL$
+$END$
+};$NL$
+$END$
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/arch/arm_m_gcc/common/core_asm.inc
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/arch/arm_m_gcc/common/core_asm.inc	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/arch/arm_m_gcc/common/core_asm.inc	(revision 457)
@@ -0,0 +1,76 @@
+/*
+ *  TOPPERS/ASP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Advanced Standard Profile Kernel
+ * 
+ *  Copyright (C) 2011 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+#ifndef TOPPERS_CORE_ASM_INC
+#define TOPPERS_CORE_ASM_INC
+
+/*
+ *  ATHUMB相当の定義
+ */
+.macro __athumb name
+	.syntax unified
+	.thumb
+	.thumb_func
+	.type name, function
+.endm
+
+/*
+ *  ディレクティブのマクロ定義
+ */
+#define ASECTION(name) .section name,"a"
+#define ATEXT          .text
+#define AGLOBAL(name)  .global name
+#define ABALIGN(x)     .balign x
+#define ALONG          .long
+#define ALABEL(label)  label:
+#define AOR            |
+#define ATHUMB(name)        __athumb name
+#define AWEAK(name)    .weak name
+
+/*
+ *  セクション情報
+ */
+#define DATA_START  __data_start
+#define IDATA_START __idata_start
+#define IDATA_END   __idata_end
+#define BSS_START   __bss_start
+#define BSS_END     __bss_end
+
+#endif /* TOPPERS_CORE_ASM_INC */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/arch/arm_m_gcc/common/core_cfg1_out.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/arch/arm_m_gcc/common/core_cfg1_out.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/arch/arm_m_gcc/common/core_cfg1_out.h	(revision 457)
@@ -0,0 +1,34 @@
+/*
+ *  @(#) $Id$
+ */
+
+/*
+ *		cfg1_out.cをリンクするために必要なスタブの定義
+ */
+void sta_ker(void){}
+
+/* 
+ *  オフセットファイルを生成するための定義 
+ */ 
+const uint8_t   MAGIC_1 = 0x12; 
+const uint16_t  MAGIC_2 = 0x1234; 
+const uint32_t  MAGIC_4 = 0x12345678;
+
+const TCB	TCB_enatex = {
+	{ NULL, NULL },			/* task_queue */
+	NULL,					/* p_tinib */
+	0U,						/* tstat */
+#ifdef TOPPERS_SUPPORT_MUTEX
+	0U,						/* bpriority */
+#endif /* TOPPERS_SUPPORT_MUTEX */
+	0U,						/* priority */
+	false,					/* acqeue */
+	false,					/* wupque */
+	true,					/* enatex */
+	0U,						/* texprn */
+	NULL,					/* p_winifo */
+#ifdef TOPPERS_SUPPORT_MUTEX
+	{ NULL, NULL },			/* mutex_queue */
+#endif /* TOPPERS_SUPPORT_MUTEX */
+	{ NULL, NULL }			/* tskctxb */
+};
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/arch/arm_m_gcc/common/core_check.tf
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/arch/arm_m_gcc/common/core_check.tf	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/arch/arm_m_gcc/common/core_check.tf	(revision 457)
@@ -0,0 +1,8 @@
+$ 
+$ 		パス3のプロセッサ依存テンプレート（ARM-M用）
+$ 
+
+$ 
+$  標準テンプレートファイルのインクルード
+$ 
+$INCLUDE "kernel/kernel_check.tf"$
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/arch/arm_m_gcc/common/core_config.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/arch/arm_m_gcc/common/core_config.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/arch/arm_m_gcc/common/core_config.c	(revision 457)
@@ -0,0 +1,364 @@
+/*
+ *  TOPPERS/ASP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Advanced Standard Profile Kernel
+ * 
+ *  Copyright (C) 2008-2011 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *		コア依存モジュール（ARM-M用）
+ */
+
+#include "kernel_impl.h"
+#include "check.h"
+#include "task.h"
+
+/*
+ *  TOPPERS標準割込み処理モデル実現のための変数と初期化処理
+ *  ARMv6-MとARMv7-Mで異なるためifdefに切り分けている
+ */
+
+#if __TARGET_ARCH_THUMB == 4
+
+volatile bool_t		lock_flag;		/* CPUロックフラグの値を保持する変数 */
+volatile uint32_t	saved_iipm;		/* 割込み優先度マスクを保存する変数 */
+
+static void
+init_intmodel(void){
+	lock_flag = true;
+	saved_iipm = IIPM_ENAALL;
+}
+
+#else /* __TARGET_ARCH_THUMB == 3 */
+
+uint32_t ief;			/* IRQの割込み要求禁止フラグの状態 */
+uint8_t  ief_systick;	/* SysTickの割込み要求禁止フラグの状態 */
+uint8_t  iipm;			/* 現在の割込み優先度マスクの値 */
+
+static void
+init_intmodel(void){
+	ief = 0x00;
+	ief_systick = 0x00;
+	iipm = INT_IPM(0);
+}
+
+#endif /* __TARGET_ARCH_THUMB == 4 */
+
+/*
+ *  ベクタテーブル(kernel_cfg.c)
+ */
+extern const FP vector_table[];
+
+/*
+ *  システム例外・割込みの（例外番号 4～15）
+ *  割込み優先度設定レジスタへのアクセスのための配列
+ */
+static const unsigned int nvic_sys_pri_reg[] = {
+	0,
+	NVIC_SYS_PRI1,
+	NVIC_SYS_PRI2,
+	NVIC_SYS_PRI3
+};
+
+/*
+ *  例外と割込みの割込み優先度をセット
+ *
+ *  excnoはARM-Mで定められている Exception Number を指定．
+ */
+void
+set_exc_int_priority(uint32_t excno, uint32_t nvic_ipm){
+	uint32_t tmp, reg;
+
+	/*
+	 *  割込み優先度設定レジスタの決定
+	 */
+	if ((EXCNO_MPU <= excno) && (excno <= IRQNO_SYSTICK)) {
+		/*
+		 * Exception Number 4(Memory Management)から
+		 * Exception Number 15(SysTick)までの割込み優先度はシステム優先度
+		 * レジスタにより設定．
+		 */
+		reg = nvic_sys_pri_reg[excno >> 2];
+	}
+	else if ((TMIN_INTNO < excno) && (excno <= TMAX_INTNO)){
+		/*
+		 * IRQ割込みなら
+		 */
+		reg = NVIC_PRI0 + (((excno - (TMIN_INTNO + 1)) >> 2) * 4);
+	}
+	else {
+		return ;
+	}
+
+	tmp = sil_rew_mem((void *)reg);
+	tmp &= ~(0xFF << (8 * (excno & 0x03)));
+	tmp |= nvic_ipm << (8 * (excno & 0x03));
+	sil_wrw_mem((void *)reg, tmp);
+}
+
+/*
+ *  例外の許可
+ *
+ *  Memory Management, Bus Fault, Usage Fault は禁止・許可が可能
+ */
+void
+enable_exc(EXCNO excno)
+{
+	uint32_t tmp;
+
+	switch (excno) {
+	  case EXCNO_MPU:
+		tmp = sil_rew_mem((void *)NVIC_SYS_HND_CTRL);
+		tmp |= NVIC_SYS_HND_CTRL_MEM;
+		sil_wrw_mem((void *)NVIC_SYS_HND_CTRL, tmp);
+		break;
+	  case EXCNO_BUS:
+		tmp = sil_rew_mem((void *)NVIC_SYS_HND_CTRL);
+		tmp |= NVIC_SYS_HND_CTRL_BUS;
+		sil_wrw_mem((void *)NVIC_SYS_HND_CTRL, tmp);
+		break;
+	  case EXCNO_USAGE:
+		tmp = sil_rew_mem((void *)NVIC_SYS_HND_CTRL);
+		tmp |= NVIC_SYS_HND_CTRL_USAGE;
+		sil_wrw_mem((void *)NVIC_SYS_HND_CTRL, tmp);
+		break;
+	}
+}
+
+/*
+ *  例外の禁止
+ */
+void
+disable_exc(EXCNO excno)
+{
+	uint32_t tmp;
+
+	switch (excno) {
+	  case EXCNO_MPU:
+		tmp = sil_rew_mem((void *)NVIC_SYS_HND_CTRL);
+		tmp &= ~NVIC_SYS_HND_CTRL_MEM;
+		sil_wrw_mem((void *)NVIC_SYS_HND_CTRL, tmp);
+		break;
+	  case EXCNO_BUS:
+		tmp = sil_rew_mem((void *)NVIC_SYS_HND_CTRL);
+		tmp &= ~NVIC_SYS_HND_CTRL_BUS;
+		sil_wrw_mem((void *)NVIC_SYS_HND_CTRL, tmp);
+		break;
+	  case EXCNO_USAGE:
+		tmp = sil_rew_mem((void *)NVIC_SYS_HND_CTRL);
+		tmp &= ~NVIC_SYS_HND_CTRL_USAGE;
+		sil_wrw_mem((void *)NVIC_SYS_HND_CTRL, tmp);
+		break;
+	}
+}
+
+
+/*
+ *  コア依存の初期化
+ */
+void
+core_initialize(void)
+{
+	/*
+	 *  ベクタテーブルを設定
+	 */
+	sil_wrw_mem((void*)NVIC_VECTTBL, (uint32_t)vector_table);
+
+	/*
+	 *  各例外の優先度を設定
+	 *  CPUロック状態でも発生するように，BASEPRIレジスタでマスクでき
+	 *  ない'0'とする．
+	 */
+	set_exc_int_priority(EXCNO_HARD, 0);
+	set_exc_int_priority(EXCNO_MPU, 0);
+	set_exc_int_priority(EXCNO_BUS, 0);
+	set_exc_int_priority(EXCNO_USAGE, 0);
+	set_exc_int_priority(EXCNO_SVCALL, 0);
+	set_exc_int_priority(EXCNO_DEBUG, 0);
+	set_exc_int_priority(EXCNO_PENDSV, 0);
+
+	/*
+	 *  割込み処理モデル関連の初期化
+	 */
+	init_intmodel();
+}
+
+/*
+ *  コア依存の終了処理
+ */
+void
+core_terminate(void)
+{
+	extern void    software_term_hook(void);
+	void (*volatile fp)(void) = software_term_hook;
+
+	/*
+	 *  software_term_hookへのポインタを，一旦volatile指定のあるfpに代
+	 *  入してから使うのは，0との比較が最適化で削除されないようにするた
+	 *  めである．
+	 */
+	if (fp != 0) {
+		(*fp)();
+	}
+}
+
+/*
+ *  割込み要求ライン属性の設定
+ */
+void
+x_config_int(INTNO intno, ATR intatr, PRI intpri)
+{
+	assert(VALID_INTNO_CFGINT(intno));
+	assert(TMIN_INTPRI <= intpri && intpri <= TMAX_INTPRI);
+
+	/* 
+	 *  一旦割込みを禁止する
+	 */    
+	(void)x_disable_int(intno);
+
+	/*
+	 *  割込み優先度をセット
+	 */
+	set_exc_int_priority(intno, INT_NVIC_PRI(intpri));
+
+	/*
+	 *  割込み要求マスク解除(必要な場合)
+	 */
+	if ((intatr & TA_ENAINT) != 0U) {
+		(void) x_enable_int(intno);
+	}    
+}
+
+
+#ifndef OMIT_DEFAULT_EXC_HANDLER
+/*
+ *  CPU例外ハンドラ番号の定義
+ */
+#define EXCNO_UNDEF		0
+#define EXCNO_SVC		1
+#define EXCNO_PABORT	2
+#define EXCNO_DABORT	3
+#define EXCNO_IRQ		4
+#define EXCNO_FIQ		5
+
+/*
+ *  CPU例外の情報を記憶しているメモリ領域の構造
+ */
+
+typedef struct t_excinf {
+	uint32_t	basepri;
+	uint32_t	ret;
+	uint32_t	r0;
+	uint32_t	r1;
+	uint32_t	r2;
+	uint32_t	r3;
+	uint32_t	r12;
+	uint32_t	lr;
+	uint32_t	pc;						/* 戻り番地 */
+	uint32_t	cpsr;					/* CPU例外発生時のCPSR */
+} T_EXCINF;
+
+/*
+ *  CPU例外ハンドラの中から，CPU例外情報ポインタ（p_excinf）を引数とし
+ *  て呼び出すことで，CPU例外の発生状況をシステムログに出力する．
+ */
+static void
+xlog_sys(void *p_excinf)
+{
+	syslog_4(LOG_EMERG, "pc = %08x, cpsr = %08x, lr = %08x, r12 = %08x",
+			((T_EXCINF *)(p_excinf))->pc, ((T_EXCINF *)(p_excinf))->cpsr,
+			((T_EXCINF *)(p_excinf))->lr, ((T_EXCINF *)(p_excinf))->r12);
+	syslog_4(LOG_EMERG, "r0 = %08x, r1 = %08x, r2 = %08x, r3 = %08x",
+			((T_EXCINF *)(p_excinf))->r0, ((T_EXCINF *)(p_excinf))->r1,
+			((T_EXCINF *)(p_excinf))->r2, ((T_EXCINF *)(p_excinf))->r3);
+	syslog_2(LOG_EMERG, "basepri = %d, ret = %x",
+			((T_EXCINF *)(p_excinf))->basepri,
+			((T_EXCINF *)(p_excinf))->ret);
+}
+
+/*
+ *  未定義の例外が発生すると呼び出される
+ */
+void
+default_exc_handler(void *p_excinf)
+{
+	uint32_t excno   = get_ipsr() & IPSR_ISR_NUMBER;
+
+	switch (excno) {
+	case EXCNO_UNDEF:
+		syslog_0(LOG_EMERG, "Undefined Instruction exception occurs.");
+		break;
+	case EXCNO_SVC:
+		syslog_0(LOG_EMERG, "Supervisor Call exception occurs.");
+		break;
+	case EXCNO_PABORT:
+		syslog_0(LOG_EMERG, "Prefetch Abort exception occurs.");
+		break;
+	case EXCNO_DABORT:
+		syslog_0(LOG_EMERG, "Data Abort exception occurs.");
+		break;
+	case EXCNO_IRQ:
+		syslog_0(LOG_EMERG, "IRQ exception occurs.");
+		break;
+	case EXCNO_FIQ:
+		syslog_0(LOG_EMERG, "FIQ exception occurs.");
+		break;
+	}
+	xlog_sys(p_excinf);
+
+	target_exit();
+}
+#endif /* OMIT_DEFAULT_EXC_HANDLER */
+
+#ifndef OMIT_DEFAULT_INT_HANDLER
+/*
+ *  未登録の割込みが発生した場合に呼び出される
+ */
+void
+default_int_handler(void *p_excinf)
+{
+	uint32_t basepri = *(((uint32_t*)p_excinf) + P_EXCINF_OFFSET_IIPM);
+	uint32_t pc      = *(((uint32_t*)p_excinf) + P_EXCINF_OFFSET_PC);
+	uint32_t xpsr    = *(((uint32_t*)p_excinf) + P_EXCINF_OFFSET_XPSR);
+	uint32_t excno   = get_ipsr() & IPSR_ISR_NUMBER;
+
+	syslog(LOG_EMERG, "\nUnregistered Interrupt occurs.");
+	syslog(LOG_EMERG, "Excno = 0x%08X, PC = 0x%08X, XPSR = 0x%08X, iipm = 0x%08X, p_excinf = 0x%08X",
+		   excno, pc, xpsr, basepri, p_excinf);	
+
+	target_exit();
+}
+#endif /* OMIT_DEFAULT_INT_HANDLER */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/arch/arm_m_gcc/common/core_config.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/arch/arm_m_gcc/common/core_config.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/arch/arm_m_gcc/common/core_config.h	(revision 457)
@@ -0,0 +1,692 @@
+/*
+ *  TOPPERS/ASP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Advanced Standard Profile Kernel
+ * 
+ *  Copyright (C) 2008-2011,2015 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *		プロセッサ依存モジュール（ARM-M用）
+ *
+ *  このインクルードファイルは，target_config.h（または，そこからインク
+ *  ルードされるファイル）のみからインクルードされる．他のファイルから
+ *  直接インクルードしてはならない．
+ */
+#ifndef TOPPERS_CORE_CONFIG_H
+#define TOPPERS_CORE_CONFIG_H
+
+/*
+ *  エラーチェック方法の指定
+ */
+#define CHECK_STKSZ_ALIGN	8	/* スタックサイズのアライン単位 */
+#define CHECK_FUNC_ALIGN	1	/* 関数のアライン単位 */
+#define CHECK_FUNC_NONNULL		/* 関数の非NULLチェック */
+#define CHECK_STACK_ALIGN	8	/* スタック領域のアライン単位 */
+#define CHECK_STACK_NONNULL		/* スタック領域の非NULLチェック */
+#define CHECK_MPF_ALIGN		4	/* 固定長メモリプール領域のアライン単位 */
+#define CHECK_MPF_NONNULL		/* 固定長メモリプール領域の非NULLチェック */
+#define CHECK_MB_ALIGN		4	/* 管理領域のアライン単位 */
+
+#ifndef TOPPERS_MACRO_ONLY
+
+/*
+ *  プロセッサの特殊命令のインライン関数定義
+ */
+#include <core_insn.h>
+
+/*
+ *  非タスクコンテキスト用のスタック初期値
+ */
+#define TOPPERS_ISTKPT(istk, istksz) ((STK_T *)((uint8_t *)(istk) + (istksz)))
+
+/*
+ *  タスクコンテキストブロックの定義
+ */
+typedef struct task_context_block {
+	void	*sp;		/* スタックポインタ */
+	FP		pc;			/* プログラムカウンタ */
+} TSKCTXB;
+
+/*
+ *  コンテキストの参照
+ *
+ */
+Inline bool_t
+sense_context(void)
+{
+	/*
+	 *  PSPが有効ならタスクコンテキスト，MSPが有効なら非タスクコンテキスト
+	 *  とする． 
+	 */
+	if ((get_control() & CONTROL_PSP) == CONTROL_PSP){
+		return false;
+	}
+	else {
+		return true;
+	}
+}
+
+/*
+ *  スタートアップルーチン（start.S）
+ */
+extern void _start(void);
+
+/*
+ *  最高優先順位タスクへのディスパッチ（core_support.S）
+ *
+ *  dispatchは，タスクコンテキストから呼び出されたサービスコール処理か
+ *  ら呼び出すべきもので，タスクコンテキスト・CPUロック状態・ディスパッ
+ *  チ許可状態・（モデル上の）割込み優先度マスク全解除状態で呼び出さな
+ *  ければならない．
+ */
+extern void dispatch(void);
+
+/*
+ *  ディスパッチャの動作開始（core_support.S）
+ *
+ *  start_dispatchは，カーネル起動時に呼び出すべきもので，すべての割込
+ *  みを禁止した状態（割込みロック状態と同等の状態）で呼び出さなければ
+ *  ならない．
+ */
+extern void start_dispatch(void) NoReturn;
+
+/*
+ *  現在のコンテキストを捨ててディスパッチ（core_support.S）
+ *
+ *  exit_and_dispatchは，ext_tskから呼び出すべきもので，タスクコンテキ
+ *  スト・CPUロック状態・ディスパッチ許可状態・（モデル上の）割込み優先
+ *  度マスク全解除状態で呼び出さなければならない．
+ */
+extern void exit_and_dispatch(void) NoReturn;
+
+/*
+ *  カーネルの終了処理の呼出し（core_support.S）
+ *
+ *  call_exit_kernelは，カーネルの終了時に呼び出すべきもので，非タスク
+ *  コンテキストに切り換えて，カーネルの終了処理（exit_kernel）を呼び出
+ *  す．
+ */
+extern void call_exit_kernel(void) NoReturn;
+
+/*
+ *  タスクコンテキストの初期化
+ *
+ *  タスクが休止状態から実行できる状態に移行する時に呼ばれる．この時点
+ *  でスタック領域を使ってはならない．
+ *
+ *  activate_contextを，インライン関数ではなくマクロ定義としているのは，
+ *  この時点ではTCBが定義されていないためである．
+ */
+extern void start_r(void);
+
+#define activate_context(p_tcb)											\
+{																		\
+	(p_tcb)->tskctxb.sp = (void *)((uint8_t *)((p_tcb)->p_tinib->stk)	\
+								+ (p_tcb)->p_tinib->stksz);				\
+	(p_tcb)->tskctxb.pc = (FP) start_r;									\
+}
+
+/*
+ *  calltexは使用しない
+ */
+#define OMIT_CALLTEX
+
+/*
+ *  割込み番号・割込みハンドラ番号
+ *
+ *  割込みハンドラ番号(inhno)と割込み番号(intno)は，割り込み発生時に
+ *  IPSRに設定される例外番号とする． 
+ */
+
+/*
+ *  割込み番号の範囲の判定
+ */
+#define VALID_INTNO(intno)           ((TMIN_INTNO <= (intno)) && ((intno) <= TMAX_INTNO))
+#define VALID_INTNO_CREISR(intno)    VALID_INTNO(intno)
+#define VALID_INTNO_DISINT(intno)    VALID_INTNO(intno)
+#define VALID_INTNO_CFGINT(intno)    VALID_INTNO(intno)
+
+/*
+ *  割込みハンドラの設定
+ *
+ *  ベクトル番号inhnoの割込みハンドラの起動番地int_entryに設定する．割込み
+ *  ハンドラテーブル
+ */
+Inline void
+x_define_inh(INHNO inhno, FP int_entry)
+{
+
+}
+
+/*
+ *  割込みハンドラの出入口処理の生成マクロ
+ *
+ */
+#define INT_ENTRY(inhno, inthdr)    inthdr
+#define INTHDR_ENTRY(inhno, inhno_num, inthdr) extern void inthdr(void);
+
+/*
+ *  割込み要求ラインの属性の設定
+ */
+extern void x_config_int(INTNO intno, ATR intatr, PRI intpri);
+
+/*
+ *  割込みハンドラ入口で必要なIRC操作
+ */
+Inline void
+i_begin_int(INTNO intno)
+{
+}
+
+/*
+ *  割込みハンドラの出口で必要なIRC操作
+ */
+Inline void
+i_end_int(INTNO intno)
+{
+}
+
+/*
+ *  CPU例外エントリ（core_support.S）
+ */
+extern void core_exc_entry(void);
+
+/*
+ *  割込みエントリ（core_support.S）
+ */
+extern void core_int_entry(void);
+
+/*
+ *  プロセッサ依存の初期化
+ */
+extern void core_initialize(void);
+
+/*
+ *  プロセッサ依存の終了時処理
+ */
+extern void core_terminate(void);
+
+/*
+ * 登録されていない例外が発生すると呼び出される
+ */
+extern void default_exc_handler(void *p_excinf);
+
+/*
+ * 未登録の割込みが発生した場合に呼び出される
+ */
+extern void default_int_handler(void *p_excinf);
+
+#endif /* TOPPERS_MACRO_ONLY */
+
+/*
+ *  ARMv7-MとARMv6-Mで異なる処理
+ *  ARMv6-Mの処理はcore_config_armv6m.hに記述する
+ */
+#if __TARGET_ARCH_THUMB == 4
+
+/*
+ *  ARMv7-Mに関する処理
+ */
+  
+/*
+ *  ターゲット依存のオブジェクト属性
+ */
+#define TARGET_INHATR  TA_NONKERNEL /* ターゲット定義の割込みハンドラ属性 */
+
+/*
+ *  TOPPERS標準割込み処理モデルの実現
+ *
+ *  割込み優先度マスクとしては，BASEPRIを用いる．全割込みを禁止する
+ *  機能として，FAULTMASKやPRIMASKがあるが，カーネル管理外の割込みを
+ *  サポートするため，これらはCPUロックのために用いない．
+ *  そのため，BASEPRIを用いて擬似的にCPUロックフラグを実現する．
+ *
+ *  まず，CPUロック状態を管理すための変数(lock_flag)を用意する．
+ *
+ *  CPUロックフラグがクリアされている間は，BASEPRIをモデル上の割込み
+ *  優先度マスクの値に設定する．この間は，モデル上の割込み優先度マス
+ *  クは，BASEPRIを用いる．
+ * 
+ *  それに対してCPUロックフラグがセットされいる間は，BASEPRIを，カーネ
+ *  ル管理外のものを除くすべての割込み要求をマスクする値(TIPM_LOCK)と，
+ *  モデル上の割込み優先度マスクとの高い方に設定する．この間のモデル上
+ *  の割込み優先度マスクは，そのための変数(saved_iipm, 内部表現で保持)
+ *  を用意して保持する．
+ */
+
+/*
+ *  割込み優先度マスクの外部表現と内部表現の変換
+ *
+ *  アセンブリ言語のソースファイルからインクルードする場合のために，
+ *  CASTを使用
+ *  割込み優先度のビット幅(TBITW_IPRI)が 8 の場合は，内部優先度 255
+ *  は，外部優先度 -1 に対応する．
+ */
+#define EXT_IPM(iipm)   (CAST(PRI,((iipm >> (8 - TBITW_IPRI)) - (1 << TBITW_IPRI))))       /* 内部表現を外部表現に */
+#define INT_IPM(ipm)    (((1 << TBITW_IPRI) - CAST(uint8_t, -(ipm)))  << (8 - TBITW_IPRI)) /* 外部表現を内部表現に */
+
+/*
+ *  割込み優先度マスクをNVICの優先度に変換
+ */
+#define INT_NVIC_PRI(ipm)    INT_IPM(ipm)
+
+/*
+ *  CPUロック状態での割込み優先度マスク
+ */
+#define TIPM_LOCK    TMIN_INTPRI
+
+/*
+ *  CPUロック状態での割込み優先度マスクの内部表現
+ *
+ *  TIPM_LOCKは，CPUロック状態でのBASEPRIの値．カーネル管理外のものを
+ *  除くすべての割込みをマスクする値に定義する．  
+ */
+#define IIPM_LOCK    INT_IPM(TIPM_LOCK)
+
+/*
+ *  TIPM_ENAALL（割込み優先度マスク全解除）の内部表現
+ *
+ *  BASEPRIに '0' を設定することで，全割込みを許可する．
+ */
+#define IIPM_ENAALL  (0)
+
+#ifndef TOPPERS_MACRO_ONLY
+
+/*
+ *  CPUロックフラグ実現のための変数
+ * 
+ *  これらの変数は，CPUロック状態の時のみ書き換えてもよいとする．
+ *  インライン関数中で，アクセスの順序が変化しないよう，volatile を指定． 
+ */
+extern volatile bool_t  lock_flag;    /* CPUロックフラグの値を保持する変数 */
+extern volatile uint32_t saved_iipm;  /* 割込み優先度をマスクする変数 */
+
+/*
+ *  CPUロック状態への移行
+ *
+ *  BASEPRI（ハードウェアの割込み優先度マスク）を，saved_iipmに保存し，
+ *  カーネル管理外のものを除くすべての割込みをマスクする値（TIPM_LOCK）
+ *  に設定する．また，lock_flagをtrueにする．
+ *
+ *  BASEPRIが，最初からTIPM_LOCKと同じかそれより高い場合には，それを
+ *  saved_iipmに保存するのみで，TIPM_LOCKには設定しない．これは，モデル
+ *  上の割込み優先度マスクが，TIPM_LOCKと同じかそれより高いレベルに設定
+ *  されている状態にあたる．
+ *
+ *  この関数は，CPUロック状態（lock_flagがtrueの状態）で呼ばれることは
+ *  ないものと想定している．
+ */
+Inline void
+x_lock_cpu(void)
+{
+	uint32_t iipm;
+
+	/*
+	 *  get_basepri()の返り値を直接saved_iipmに保存せず，一時変数iipm
+	 *  を用いているのは，get_baespri()を呼んだ直後に割込みが発生し，
+	 *  起動された割込み処理でsaved_iipmが変更される可能性があるためで
+	 *  ある．
+	 */
+	iipm = get_basepri();
+	/*
+	 *  BASEPRIレジスタは値が小さいほど優先度が高いが，IIPM_ENAALL が
+	 *  '0'であるため，単純に優先度比較だけでは不十分である．
+	 */
+	if ((IIPM_LOCK < iipm) || (IIPM_ENAALL == iipm)) {
+		set_basepri(IIPM_LOCK);
+	}
+	saved_iipm = iipm;
+	lock_flag = true;
+
+	/* クリティカルセクションの前後でメモリが書き換わる可能性がある */
+	ARM_MEMORY_CHANGED;    
+}
+
+#define t_lock_cpu()    x_lock_cpu()
+#define i_lock_cpu()    x_lock_cpu()
+
+/*
+ *  CPUロック状態の解除
+ *
+ *  lock_flagをfalseにし，IPM（ハードウェアの割込み優先度マスク）を，
+ *  saved_iipmに保存した値に戻す．
+ *
+ *  この関数は，CPUロック状態（lock_flagがtrueの状態）でのみ呼ばれるも
+ *  のと想定している．
+ */
+Inline void
+x_unlock_cpu(void)
+{
+	/* クリティカルセクションの前後でメモリが書き換わる可能性がある */
+	ARM_MEMORY_CHANGED;
+	lock_flag = false;
+	set_basepri(saved_iipm);
+}
+
+#define t_unlock_cpu()    x_unlock_cpu()
+#define i_unlock_cpu()    x_unlock_cpu()
+
+/*
+ *  CPUロック状態の参照
+ */
+Inline bool_t
+x_sense_lock(void)
+{
+	return(lock_flag);
+}
+
+#define t_sense_lock()    x_sense_lock()
+#define i_sense_lock()    x_sense_lock()
+
+/*
+ *  chg_ipmで有効な割込み優先度の範囲の判定
+ *
+ *  TMIN_INTPRIの値によらず，chg_ipmでは，-(1 << TBITW_IPRI)～TIPM_ENAALL（＝0）
+ *  の範囲に設定できることとする（ターゲット定義の拡張）．
+ *  割込み優先度のビット幅(TBITW_IPRI)が 8 の場合は，-256 ～ 0 が指定可能である．
+ *   
+ */
+#define VALID_INTPRI_CHGIPM(intpri) \
+				((-((1 << TBITW_IPRI) - 1) <= (intpri) && (intpri) <= TIPM_ENAALL))
+
+/*
+ * （モデル上の）割込み優先度マスクの設定
+ *
+ *  CPUロックフラグがクリアされている時は，ハードウェアの割込み優先度マ
+ *  スクを設定する．CPUロックフラグがセットされている時は，saved_iipm
+ *  を設定し，さらに，ハードウェアの割込み優先度マスクを，設定しようと
+ *  した（モデル上の）割込み優先度マスクとTIPM_LOCKの高い方に設定する．
+ */
+Inline void
+x_set_ipm(PRI intpri)
+{
+	uint8_t   iipm = INT_IPM(intpri);
+
+	if (intpri == TIPM_ENAALL){
+		iipm = IIPM_ENAALL;
+	}
+
+	if (!lock_flag) {
+		set_basepri(iipm);
+	}
+	else {
+		saved_iipm = iipm;
+		/*
+		 *  BASEPRIレジスタは値が小さいほど優先度が高いが，IIPM_ENAALL が
+		 *  '0'であるため，単純に優先度比較だけでは不十分である．
+		 */
+		if ((iipm < IIPM_LOCK ) && (IIPM_ENAALL != iipm)) {
+			set_basepri(iipm);
+		}
+		else {
+			set_basepri(IIPM_LOCK);
+		}
+	}
+}
+
+#define t_set_ipm(intpri)    x_set_ipm(intpri)
+#define i_set_ipm(intpri)    x_set_ipm(intpri)
+
+/*
+ * （モデル上の）割込み優先度マスクの参照
+ *
+ *  CPUロックフラグがクリアされている時はハードウェアの割込み優先度マ
+ *  スクを，セットされている時はsaved_iipmを参照する．
+ */
+Inline PRI
+x_get_ipm(void)
+{
+	uint8_t iipm;
+
+	if (!lock_flag) {
+		iipm = get_basepri();
+	}
+	else {
+		iipm = saved_iipm;
+	}
+
+	if (iipm == IIPM_ENAALL) {
+		return(TIPM_ENAALL);
+	}
+	else {
+		return(EXT_IPM(iipm));
+	}
+}
+
+#define t_get_ipm()    x_get_ipm()
+#define i_get_ipm()    x_get_ipm()
+
+/*
+ *  割込み要求禁止フラグ
+ */
+
+/*
+ *  割込み属性が設定されているかを判別するための変数（kernel_cfg.c）
+ */
+extern const uint32_t	bitpat_cfgint[];
+
+/*
+ *  割込み要求禁止フラグのセット
+ *
+ *  割込み属性が設定されていない割込み要求ラインに対して割込み要求禁止
+ *  フラグをクリアしようとした場合には，falseを返す．  
+ */
+Inline bool_t
+x_disable_int(INTNO intno)
+{
+	uint32_t tmp;
+
+	/*
+	 *  割込み属性が設定されていない場合
+	 */
+	if ((bitpat_cfgint[intno >> 5] & (1 << (intno & 0x1f))) == 0x00) {
+		return(false);
+	}
+
+	if (intno == IRQNO_SYSTICK) {
+		tmp = sil_rew_mem((void *)SYSTIC_CONTROL_STATUS);
+		tmp &= ~SYSTIC_TICINT;
+		sil_wrw_mem((void *)SYSTIC_CONTROL_STATUS, tmp);
+	}else {
+		tmp = intno - 16;
+		sil_wrw_mem((void *)((uint32_t *)NVIC_CLRENA0 + (tmp >> 5)),
+					(1 << (tmp & 0x1f)));
+	}
+
+	return(true);
+}
+
+#define t_disable_int(intno) x_disable_int(intno)
+#define i_disable_int(intno) x_disable_int(intno)
+
+/*
+ *  割込み要求禁止フラグの解除
+ *
+ *  割込み属性が設定されていない割込み要求ラインに対して割込み要求禁止
+ *  フラグをクリアしようとした場合には，falseを返す．
+ */
+Inline bool_t
+x_enable_int(INTNO intno)
+{
+	uint32_t tmp;
+
+	/*
+	 *  割込み属性が設定されていない場合
+	 */
+	if ((bitpat_cfgint[intno >> 5] & (1 << (intno & 0x1f))) == 0x00) {
+		return(false);
+	}
+
+	if (intno == IRQNO_SYSTICK) {
+		tmp = sil_rew_mem((void *)SYSTIC_CONTROL_STATUS);
+		tmp |= SYSTIC_TICINT;
+		sil_wrw_mem((void *)SYSTIC_CONTROL_STATUS, tmp);
+	}else {
+		tmp = intno - 16;
+		sil_wrw_mem((void *)((uint32_t *)NVIC_SETENA0 + (tmp >> 5)),
+					(1 << (tmp & 0x1f)));
+	}
+	return(true);
+}
+
+#define t_enable_int(intno) x_enable_int(intno)
+#define i_enable_int(intno) x_enable_int(intno)
+
+/*
+ *  SVCハンドラ（core_support.S）
+ */
+extern void svc_handler(void);
+
+#endif /* TOPPERS_MACRO_ONLY */
+
+/*
+ *  FPU関連の定義
+ */
+
+/*
+ *  FPCCRの初期値
+ */
+#if defined(TOPPERS_FPU_NO_PRESERV)
+#define FPCCR_INIT FPCCR_NO_PRESERV
+#elif defined(TOPPERS_FPU_NO_LAZYSTACKING)
+#define FPCCR_INIT FPCCR_NO_LAZYSTACKING
+#elif defined(TOPPERS_FPU_LAZYSTACKING)
+#define FPCCR_INIT FPCCR_LAZYSTACKING
+#endif /* defined(TOPPERS_FPU_NO_PRESERV) */
+
+#else /* __TARGET_ARCH_THUMB == 3 */
+
+/*
+ *  ARMv6-Mに関する処理
+ */
+#include "core_config_v6m.h"
+
+#endif /* __TARGET_ARCH_THUMB == 4 */
+
+#ifndef TOPPERS_MACRO_ONLY
+
+/*
+ *  CPU例外ハンドラ関係
+ */ 
+
+/*
+ *  CPU例外ハンドラ番号
+ */
+#define VALID_EXCNO_DEFEXC(excno)    (TMIN_EXCNO <= (excno) && (excno) <= TMAX_EXCNO)
+
+/*
+ *  CPU例外ハンドラの許可
+ */
+extern void enable_exc(EXCNO excno);
+
+/*
+ *  CPU例外ハンドラの禁止
+ */
+extern void disable_exc(EXCNO excno);
+
+/*
+ *  CPU例外ハンドラの設定
+ */
+Inline void
+x_define_exc(EXCNO excno, FP exc_entry)
+{
+	/*
+	 *  一部の例外は許可を行う必要がある
+	 */
+	enable_exc(excno);
+}
+
+/*
+ *  CPU例外ハンドラの入口処理の生成マクロ
+ */
+#define EXC_ENTRY(excno, exchdr)    exchdr
+#define EXCHDR_ENTRY(excno, excno_num, exchdr) extern void exchdr(void *p_excinf);
+
+/*
+ *  CPU例外の発生した時のコンテキストの参照
+ *
+ *  CPU例外の発生した時のコンテキストが，タスクコンテキストの時にfalse，
+ *  そうでない時にtrueを返す．
+ */
+Inline bool_t
+exc_sense_context(void *p_excinf)
+{
+	uint32_t exc_return;
+
+	exc_return = *((uint32_t *)p_excinf + P_EXCINF_OFFSET_EXC_RETURN);
+	if ((exc_return & EXC_RETURN_PSP) == EXC_RETURN_PSP){
+		return false;
+	}
+	else {
+		return true;
+	}
+}
+
+/*
+ *  CPU例外の発生した時のIPM（ハードウェアの割込み優先度マスク，内部表
+ *  現）の参照
+ */
+Inline uint32_t
+exc_get_iipm(void *p_excinf)
+{
+	return(*((uint32_t *)p_excinf + P_EXCINF_OFFSET_IIPM));
+}
+
+/*
+ *  CPU例外の発生した時のコンテキストと割込みのマスク状態の参照
+ *
+ *  CPU例外の発生した時のシステム状態が，カーネル実行中でなく，タスクコ
+ *  ンテキストであり，割込みロック状態でなく，CPUロック状態でなく，（モ
+ *  デル上の）割込み優先度マスク全解除状態である時にtrue，そうでない時
+ *  にfalseを返す（CPU例外がカーネル管理外の割込み処理中で発生した場合
+ *  にもfalseを返す）．
+ *
+ *  PU例外の発生した時のBASEPRI（ハードウェアの割込み優先度マスク）
+ *  がすべての割込みを許可する状態であることをチェックすることで，カー
+ *  ネル実行中でないこと，割込みロック状態でないこと，CPUロック状態でな
+ *  いこと，（モデル上の）割込み優先度マスク全解除状態であることの4つの
+ *  条件をチェックすることができる（CPU例外が発生した時のlock_flagを参
+ *  照する必要はない）．
+ */
+Inline bool_t
+exc_sense_intmask(void *p_excinf)
+{
+	return(!exc_sense_context(p_excinf)
+		   && (exc_get_iipm(p_excinf) == IIPM_ENAALL) && !x_sense_lock());   
+}
+#endif /* TOPPERS_MACRO_ONLY */
+
+#endif /* TOPPERS_CORE_CONFIG_H */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/arch/arm_m_gcc/common/core_config_v6m.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/arch/arm_m_gcc/common/core_config_v6m.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/arch/arm_m_gcc/common/core_config_v6m.h	(revision 457)
@@ -0,0 +1,279 @@
+/*
+ *  TOPPERS/ASP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Advanced Standard Profile Kernel
+ * 
+ *  Copyright (C) 2015 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *		割込み処理モデル（ARMv6-M用）
+ *
+ *  このインクルードファイルは，core_config.h（または，そこからインク
+ *  ルードされるファイル）のみからインクルードされる．他のファイルから
+ *  直接インクルードしてはならない．
+ */
+
+#ifndef TOPPERS_CORE_INTMODEL_V6M_H
+#define TOPPERS_CORE_INTMODEL_V6M_H
+
+/*
+ *  ターゲット依存のオブジェクト属性
+ */
+#define TARGET_INHATR  TA_NONKERNEL /* ターゲット定義の割込みハンドラ属性 */
+
+/*
+ *  割込み優先度マスクの外部表現と内部表現の変換
+ *
+ *  アセンブリ言語のソースファイルからインクルードする場合のために，
+ *  CASTを使用
+ *   外部表現 : TMIN_INTPRI  ～       0  
+ *   内部表現 :      0       ～  -TMIN_INTPRI
+ */
+#define EXT_IPM(iipm)   (CAST(PRI,iipm + TMIN_INTPRI))     /* 内部表現を外部表現に */
+#define INT_IPM(ipm)    (CAST(uint8_t, ipm - TMIN_INTPRI)) /* 外部表現を内部表現に */
+
+/*
+ *  割込み優先度マスクをNVICの優先度に変換
+ */
+#define INT_NVIC_PRI(ipm)    (((1 << TBITW_IPRI) - CAST(uint8_t, -(ipm)))  << (8 - TBITW_IPRI))
+
+/*
+ *  TIPM_ENAALL（割込み優先度マスク全解除）の内部表現
+ *
+ */
+#define IIPM_ENAALL  (-TMIN_INTPRI)
+
+#ifndef TOPPERS_MACRO_ONLY
+
+/*
+ *  割込み要求禁止フラグの実現のための変数
+ */
+extern uint32_t ief;			/* IRQの割込み要求許可フラグの状態 */
+extern uint8_t  ief_systick;	/* SysTickの割込み要求許可フラグの状態 */
+
+/*
+ *  割込み優先度マスク実現のための変数
+ */
+extern uint8_t iipm;		/* 現在の割込み優先度マスクの値 */ 
+
+/*
+ *  割込み優先度マスク実現のための変数（kernel_cfg.c）
+ */
+extern const uint32_t iipm_enable_irq_tbl[];
+extern const uint8_t iipm_enable_systic_tbl[];
+
+/*
+ *  CPUロック状態への移行
+ *
+ */
+Inline void
+x_lock_cpu(void)
+{
+	set_primask();
+	/* クリティカルセクションの前後でメモリが書き換わる可能性がある */
+	ARM_MEMORY_CHANGED;    
+}
+
+#define t_lock_cpu()    x_lock_cpu()
+#define i_lock_cpu()    x_lock_cpu()
+
+/*
+ *  CPUロック状態の解除
+ *
+ */
+Inline void
+x_unlock_cpu(void)
+{
+	/* クリティカルセクションの前後でメモリが書き換わる可能性がある */
+	ARM_MEMORY_CHANGED;
+	clear_primask();
+}
+
+#define t_unlock_cpu()    x_unlock_cpu()
+#define i_unlock_cpu()    x_unlock_cpu()
+
+/*
+ *  CPUロック状態の参照
+ */
+Inline bool_t
+x_sense_lock(void)
+{
+	return(read_primask() == 0x1u);
+}
+
+#define t_sense_lock()    x_sense_lock()
+#define i_sense_lock()    x_sense_lock()
+
+/*
+ *  chg_ipmで有効な割込み優先度の範囲の判定
+ *
+ *  TMIN_INTPRIの値によらず，chg_ipmでは，-(1 << TBITW_IPRI)～TIPM_ENAALL（＝0）
+ *  の範囲に設定できることとする（ターゲット定義の拡張）．
+ *  割込み優先度のビット幅(TBITW_IPRI)が 2 の場合は，-4 ～ 0 が指定可能である．
+ *   
+ */
+#define VALID_INTPRI_CHGIPM(intpri) \
+				((-((1 << TBITW_IPRI) - 1) <= (intpri) && (intpri) <= TIPM_ENAALL))
+
+/*
+ * （モデル上の）割込み優先度マスクの設定
+ *
+ */
+Inline void
+x_set_ipm(PRI intpri)
+{
+	uint32_t tmp;
+	iipm = INT_IPM(intpri);
+
+	tmp = sil_rew_mem((void *)SYSTIC_CONTROL_STATUS);
+	if ((iipm_enable_systic_tbl[iipm] & ief_systick) ==  0x01) {
+		tmp |= SYSTIC_TICINT;
+	}else{
+		tmp &= ~SYSTIC_TICINT;
+	}
+	sil_wrw_mem((void *)SYSTIC_CONTROL_STATUS, tmp);
+
+	/* 一旦全割込み禁止 */
+	sil_wrw_mem((void *)NVIC_CLRENA0, 0xffffffff);
+	sil_wrw_mem((void *)NVIC_SETENA0, (iipm_enable_systic_tbl[iipm] & ief));
+}
+
+#define t_set_ipm(intpri)    x_set_ipm(intpri)
+#define i_set_ipm(intpri)    x_set_ipm(intpri)
+
+/*
+ * （モデル上の）割込み優先度マスクの参照
+ *
+ */
+Inline PRI
+x_get_ipm(void)
+{
+	return EXT_IPM(iipm);
+}
+
+#define t_get_ipm()    x_get_ipm()
+#define i_get_ipm()    x_get_ipm()
+
+/*
+ *  割込み要求禁止フラグ
+ */
+
+/*
+ *  割込み属性が設定されているかを判別するための変数（kernel_cfg.c）
+ */
+extern const uint32_t	bitpat_cfgint[];
+
+/*
+ *  割込み要求禁止フラグのセット
+ *
+ *  割込み属性が設定されていない割込み要求ラインに対して割込み要求禁止
+ *  フラグをクリアしようとした場合には，falseを返す．  
+ */
+Inline bool_t
+x_disable_int(INTNO intno)
+{
+	uint32_t tmp;
+
+	/*
+	 *  割込み属性が設定されていない場合
+	 */
+	if ((bitpat_cfgint[intno >> 5] & (1 << (intno & 0x1f))) == 0x00) {
+		return(false);
+	}
+
+	if (intno == IRQNO_SYSTICK) {
+		tmp = sil_rew_mem((void *)SYSTIC_CONTROL_STATUS);
+		tmp &= ~SYSTIC_TICINT;
+		sil_wrw_mem((void *)SYSTIC_CONTROL_STATUS, tmp);
+		ief_systick &= ~0x01;
+	}else {
+		tmp = intno - 16;
+		sil_wrw_mem((void *)(NVIC_CLRENA0), (1 << (tmp & 0x1f)));
+		ief &= ~(1 << (tmp & 0x1f));
+	}
+
+	return(true);
+}
+
+#define t_disable_int(intno) x_disable_int(intno)
+#define i_disable_int(intno) x_disable_int(intno)
+
+/*
+ *  割込み要求禁止フラグの解除
+ *
+ *  割込み属性が設定されていない割込み要求ラインに対して割込み要求禁止
+ *  フラグをクリアしようとした場合には，falseを返す．
+ */
+Inline bool_t
+x_enable_int(INTNO intno)
+{
+	uint32_t tmp;
+
+	/*
+	 *  割込み属性が設定されていない場合
+	 */
+	if ((bitpat_cfgint[intno >> 5] & (1 << (intno & 0x1f))) == 0x00) {
+		return(false);
+	}
+
+	if (intno == IRQNO_SYSTICK) {
+		ief_systick |= 0x01;
+		if ((iipm_enable_systic_tbl[iipm] & ief_systick) ==  0x01) {
+			tmp = sil_rew_mem((void *)SYSTIC_CONTROL_STATUS);
+			tmp |= SYSTIC_TICINT;;
+			sil_wrw_mem((void *)SYSTIC_CONTROL_STATUS, tmp);
+		}
+	}else {
+		tmp = intno - 16;
+		ief |= (1 << (tmp & 0x1f));
+		if ((iipm_enable_irq_tbl[iipm] & (1 << (tmp & 0x1f))) != 0) {
+			sil_wrw_mem((void *)(NVIC_SETENA0), (1 << (tmp & 0x1f)));
+		}
+	}
+
+	return(true);
+}
+
+#define t_enable_int(intno) x_enable_int(intno)
+#define i_enable_int(intno) x_enable_int(intno)
+
+/*
+ *  PendSVCハンドラ（core_support.S）
+ */
+extern void pendsvc_handler(void);
+
+#endif /* TOPPERS_MACRO_ONLY */
+#endif /* TOPPERS_CORE_INTMODEL_V6M_H */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/arch/arm_m_gcc/common/core_def.csv
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/arch/arm_m_gcc/common/core_def.csv	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/arch/arm_m_gcc/common/core_def.csv	(revision 457)
@@ -0,0 +1,8 @@
+TMAX_INTNO,TMAX_INTNO
+TBITW_IPRI,TBITW_IPRI
+__TARGET_ARCH_THUMB,__TARGET_ARCH_THUMB
+sizeof_TCB,sizeof(TCB)
+offsetof_TCB_p_tinib,"offsetof(TCB,p_tinib)"
+offsetof_TCB_texptn,"offsetof(TCB,texptn)"
+offsetof_TCB_sp,"offsetof(TCB,tskctxb.sp)"
+offsetof_TCB_pc,"offsetof(TCB,tskctxb.pc)"
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/arch/arm_m_gcc/common/core_design.txt
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/arch/arm_m_gcc/common/core_design.txt	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/arch/arm_m_gcc/common/core_design.txt	(revision 457)
@@ -0,0 +1,867 @@
+=====================================================================
+                         ARM-Mプロセッサ依存部設計メモ
+                                  Last Modified:2015 Nov 23 08:57:56
+=====================================================================
+
+○このドキュメントの位置づけ
+
+このドキュメントは，TOPPERS/ASPカーネルをARMvX-Mプロセッサに移植するため
+の設計メモである．
+
+
+○ARMVx-Mの仕様まとめ(FPU以外)
+
+ARMvX-Mの仕様のうち，カーネルの設計に関係する事項について，まずARMv7-M
+についてまとめる．ARMv6-Mは最後にARMv7-Mとの差分として説明する．
+
+●参考資料
+
+ARMv7-M Architecture Reference Manual E.b
+DDI0403E_B_armv7m_arm.pdf 
+
+●レジスタ
+
+汎用レジスタはR0～R15の16種類あり，R13のみが2バンク構成（PSP,MSP）とな
+っている．R15はPC, R14はリンクレジスタ（LR）となっている．R0～R3,R12は
+スクラッチレジスタである．
+
+●コーリングコンベンション
+
+R0～R4が引数，それ以上はスタック．戻り値は，R0～R1に格納される．(ARMに
+より規定されているため，コンパイラに依存せずこのルールとなる．)
+
+●CONTROLレジスタ
+
+PSP,MSPの切り替え，PrivilageとUserモードのレジスタ．変更後は，インスト
+ラクションバッファフラッシュ命令を実行する必要がある（isb）．CONTROLレ
+ジスタの詳細は，ARMv7-M Architecture Application Level Reference 
+Manual の B1-9 を参照のこと．
+
+●割込みベクタ
+
+ベクタテーブル型で，ベクタテーブルのアドレスは，リセット時は0x00で，
+Vector Table Offset Register（メモリマップドレジスタ） を操作すること
+で，任意のアドレスに配置可能である．
+
+●優先度
+
+値が小さい方が高優先度となり，0が最高優先度となる．一方，後述するプロ
+セッサの割込み優先度を設定するBASEPRIレジスタは'0'をセットすると，全て
+の割込みを許可するため，最高優先度は，有効なビットのLSBを'1'とした値で
+ある（3bitの場合は0x20）．また，割込みの優先度に'0'を設定すると，
+BASEPRIレジスタでマスクできない割込みとなる．
+
+優先度は最大8bitであり，SoC毎に実装されているビット幅が異なる．実装さ
+れるビットが8bit以下の場合は，LSBから無効になる．例えば，実装されてい
+るビット幅が7bitの場合は，ビット0が無効となる．
+
+優先度のビットフィールドのLSBから数ビットをサブ優先度と呼ぶフィールド
+に設定することが可能である．残りの上位ビットをプリエンプション優先度と
+呼ぶ．プリエンプション優先度が同じで，サブ優先度が異なる優先度のグルー
+プは，お互いをプリエンプトすることができない．
+
+Reset,NMI,Hard Fault 以外の例外は割込みと同様に優先度が設定可能であり，
+割込みマスク機能により，発生を禁止することが可能である．
+
+
+●CPUモード
+
+プロセッサは，ThreadモードもしくはHandlerモードのいずれかのモードとな
+る．
+
+●リセット時の状態
+
+リセット時はThreadモード，MSPが有効となっている．
+
+●Handlerモード
+
+例外/割込みを受け付けると遷移するモード．受け付けた例外/割込みの例外番
+号が，IPSRにセットされる．例外番号は，TRMで定められている番号である．
+
+        例外              例外番号
+  Reset                      1
+  Non-makable Interrupt      2
+  Hard Fault                 3
+  Memory Management          4
+  Bus Fault                  5
+  Usage Fault                6
+  SVCall                    11
+  Debug Monitor             12
+  PendSV                    14
+  SysTick                   15
+  IRQ0                      16
+  IRQ1                      17
+  ..
+
+例外/割込みを受け付けると，受け付けた例外/割込みの優先度以下の例外/割
+込みを禁止する．この優先度マスクを"NVIC優先度マスク"と呼ぶ．この優先度
+は，ソフトウェアから変更することができず，例外/割込みのリターンにより
+割込み前の値に自動的に戻る．
+
+●スタックポインタ（PSPとMSP）
+
+スタックポインタは，PSPとMSPがあり，排他的に使用可能である．Handlerモ
+ードではMSPのみ使用可能であり，ThreadモードではCONTROLレジスタで選択可
+能である．CONTROLレジスタの1ビット目をセットするとPSPが有効に，クリア
+すると，MSPが有効になる．
+
+●ThreadモードとHandlerモードの遷移
+
+ThreadモードからHandlerモードへの遷移は，例外/割込みを受け付けることで
+発生する．一方，HandlerモードからThreadモードへの遷移は，PCに
+EXC_RETURN(0xfffffffx)の値を設定することにより行う（例外リターン処理と
+呼ぶ）．EXC_RETURNの下位4bitにより，遷移先のモードや使用するスタックポ
+インタを変更可能である．例外リターンにより，PRIMASKやBASEPRIの値は変化
+しない．一方，FAULTMASKの値は'0'にクリアさせる．
+
+●EXC_RETURN
+
+例外/割込み受付け時にlrに設定される値．ビット31～4ビットは全て'1'で，
+下位4bitは，受付け時のCPUモードやスタックを反映した値となっている．
+
+ 0b0001 : Handlerモード
+ 0b1001 : Threadモード with MSP
+ 0b1101 : Threadモード with PSP
+
+●ThreadモードとHandlerモードの判定
+
+現状のモードを判定するには，IPSRを見て，'0'ならThreadモード，それ以外
+なら，Handlerモードとなる．
+
+●BASEPRIレジスタ
+
+設定した優先度以下の優先度の割込みの受付を禁止する．この優先度マスクを
+"BASEPRI優先度マスク"と呼ぶ．'0'を設定すると，全ての割込みを許可する．
+例外/割込みの受付とリターンにより変化しない．例外/割込みに対する割込み
+優先度マスクは，NVIC優先度マスクとBASEPRIの設定値の高い方（値が小さい
+方）となる．
+
+●FAULTMASK
+
+FAULTMASKは'1'をセットすることにより，NMI以外の全ての割込みを禁止する．
+FAULTMASKは，例外のリターン処理により'0'にクリアさせる．
+
+●PRIMASKとWFI
+
+PRIMASKを'1'に設定すると，NMI と Hardware Fault 以外の例外/割込みを禁
+止する．PRIMASKは割込みの許可と割込み待ちをアトミックに行うために用い
+る．具体的には，PRIMASKがセットされている状態でwfiを実行すると，割り込
+み待ちとなり，割込み受付けるとハンドラを実行せずに，wfiからリターンし
+てくる．
+
+●例外/割込みの受付
+
+・例外/割込みを受付けると，受付け時にアクティブなスタック上に以下のコ
+  ンテキストを保存する(例外フレームと呼ぶ)．
+
+   -----------
+  |    R0     |  <- new SP
+   -----------
+  |    R1     |
+   -----------
+  |    R2     |
+   -----------
+  |    R3     |
+   -----------
+  |    R12    |
+   -----------
+  |    LR     |
+   -----------
+  |    PC     |
+   -----------
+  |   xPSR    |
+   -----------
+  |           | <- old SP
+
+・プロセッサをHandlerモードとする．MSPが有効となる．
+・受付けた例外/割込みの例外番号をIPSRに設定する．
+・NVIC割込み優先度マスクを受付けた例外/割込みの優先度に設定する．
+・lrにEXC_RETURNの値が設定される．
+・ベクタテーブルを読み込みハンドラを実行する．
+・スタックフレームは，Configureation and Control Register(CCR)の
+  STKALIGNが'1'の場合は，8byte境界にアラインされる．
+
+●例外/割込みからのリターン
+
+pcにEXC_RETURNの値を設定することにより，例外/割込みからリターンする．
+pcへの設定に使用可能な命令には制限があり，以下命令が使用可能である．
+
+  ・POP/LDM, LDR, BX
+
+●未解決課題
+
+・ベクターテーブルに登録する関数のアドレスのLSBは'1'にするべきか?
+・NVICは例外・割込みのネスト回数を内部的に管理しているらしい．
+  (!リファレンスを明らかに)．
+    ソフトウェアでは，ネストの帳尻を合わせれば，リターンスタックを偽造し
+    ても問題ないか．
+
+●stmfdの制限
+
+stmfdはレジスタリストが1個の場合の動作は不定となっている．そのため，レ
+ジスタリストが1個の記述をアセンブラにした場合は，アセンブラがstr.w に
+変換するが，アセンブラによってはワーニングを出すため，レジスタリストが
+1個の場合は，str.wを使用する．
+
+なお，ldmfdにはこの制限がない．
+
+●ARMv6-M
+
+カーネルの設計に対して，ARMv6-MのARMv7-Mに対する差分は次の通りである．
+
+・BASEPRIレジスタ
+  ARMv6-MではBASEPRIレジスタを持たない．
+
+・FAULTMASK
+  ARMv6-MではFAULTMASKレジスタを持たない．
+  
+・命令
+  一部命令が使用出来ない．
+  同じ命令でも指定可能なレジスタに制限がある
+  
+・外部割込み数
+  最大32個
+  
+
+○FPU関連の仕様
+
+●参考資料
+
+ARMv7-M Architecture Reference Manual E.b
+DDI0403E_B_armv7m_arm.pdf 
+
+ARM CortexR-M4 Processor Technical Reference Manual Revision: r0p1 
+arm_cortexm4_processor_trm_100166_0001_00_en.pdf
+
+Cortex-M4(F) Lazy Stacking and Context Switching Application Note 298
+DAI0298A_cortex_m4f_lazy_stacking_and_context_switching.pdf
+
+●概要
+
+Cortex-M4はARMv7E-Mをベースとしている．FPUサポートした実装とサポートし
+ていない実装がある．FPUをサポートした実装をCortex-M4Fと呼ぶ．
+在する．
+
+FPUはARMv7E-M Floatng Point Extension(FPv4-SP)をサポートしている．
+
+FPv4-SPは次の仕様となっている．
+
+レジスタ : 単精度レジスタ S0～S32 / 倍精度レジスタ D0～D15 
+           D0は(S0とS1)と等価．
+命令     : 単精度命令をサポート
+
+●制御レジスタ
+
+FPSCR : Floating-point Status and Control Register
+・FPUのステータスとコントロールフィールドを持つ
+
+CPACR : Coprocessor Access Control Register
+・FPUを有効にする場合にセットする必要がある
+
+FPCCR : Floating-point Context Control Register
+・FPU関連のコンテキストの保存方法を選択可能
+
+FPCAR : Floating Point Context Address Register
+・例外フレームのFPUレジスタの保存アドレス(S0のアドレス)を保持． 
+
+FPDSCR : Floating-point Default Status Control Register
+・FPSCRのディフォルト値を保存
+・FPUを初めて使用した場合に[26:22]がFPSCRにコピーされる．
+
+CONTROLの拡張
+・.FPCA(Bit[2])
+  ・FPUを使用すると'1'にセットされる．
+
+EXC_RETURNの拡張
+
+EXC_RETURN[4]
+ '0' : FPUの領域あり(保存されているかは別の制御)
+       S0～S15とFPSCRのための領域．
+ '1' : FPUの領域なし
+
+●ABI
+
+S0～S15,FPSCR  : caller saved registers
+S16～S17       : callee saved registers
+
+●例外・割込み発生時の振る舞い
+
+詳細は ARMv7-M Architecture Reference Manual E.bの B1.5.6 Exception 
+entry behavior と B1.5.8 Exception return behavior を参照のこと．
+ 
+コンテキストの保存パターン
+    FPCCR
+ LSPEN  ASPEN      名称(本ドキュメントオリジナル)
+   0      0      :  NoAutomatic
+   0      1      :  DisableLazystacking
+   1      1      :  Lazystacking
+ 
+NoAutomatic 
+・自動保存なし
+
+DisableLazystacking
+・自動保存あり．Lazystackingしない．
+・FPUを使用すると CONTROL.FPCA に'1'がセットされる．
+・CONTROL.FPCA == 1の場合に例外/割込みが発生するとFPUコンテキストをス
+  タックに保存する．
+
+Lazystacking
+・自動保存あり．Lazystacking を行う．
+・FPUを使用すると CONTROL.FPCA に'1'がセットされる．
+・CONTROL.FPCA == '1'の場合に例外/割込みが発生するとFPUコンテキストの保
+  存用の領域のみ確保され，FPCCR.LSPACT に'1'に設定される．
+・FPCCR.LSPACT == '1' の場合にFPU命令を使用するとFPUのコンテキストが保
+  存領域に保存される．
+
+FPUに関する例外/割込みの入り口処理
+
+・DisableLazystacking or Lazystacking の場合
+ ・CONTROL.FPCA == 1の場合
+   ・例外フレームにFPUレジスタ保存用の領域を確保
+   ・DisableLazystacking の場合
+     ・FPUレジスタ保存用の領域にFPUレジスタ(S0～S15,FPSCR)を保存
+   ・Lazystacking
+     ・FPCAR に例外フレームのFPUレジスタの保存アドレス(S0のアドレス)を保持．
+     ・FPCCR.LSPACT を1に．
+・CONTROL.FPCAを0にクリア
+
+FPUに関する例外/割込みの出口処理
+
+・EXC_RETURNの4ビット目が'0'の場合(戻り先でFPUを使用していた)
+ ・FPCCR.LSPACT == '1'の場合(割込みハンドラでFPUを使用しなかった)
+   ・FPCCR.LSPACTを'0'に
+ ・FPCCR.LSPACT == '0'の場合(割込みハンドラでFPUを使用した)    
+   ・S0～S32とFPSCRを例外フレームから戻す    
+・EXC_RETURNの4ビット目の否定をCONTROL.FPCAに設定
+ ・実質，戻り先のCONTROL.FPCAを復帰
+
+ISRでのFPUの振る舞い
+
+FPCCR.LSPACT==1時(Lazystackingの時にのみ発生)にFPU命令を使用した場合
+・FPCARのアドレスにFPUレジスタ(S0～S15,FPSCR)を保存
+・FPCCR.LSPACT を0にする．
+
+○OSの実装
+
+1.ターゲット名
+
+ 1-1 cm3(Cortex-M3)
+ 1-2 armv7m(ARMv7-M)
+ 1-3 arm_m
+
+cm3では，ARMv6-Mをサポートする場合に問題となる．armv7mでは，armv8mがリ
+リースされた場合に問題となる．ARM依存部はJSPでは，armv4となっていたが，
+armv5やarmv7も動作するためASPでは単にarmとした．そのため，arm_mが無難
+と考えられる．
+
+
+2.ThreadモードとHandlerモードの使い分け
+
+ 2-1
+  タスクコンテキストはThreadモード，非タスクコンテキストはHandlerモー
+  ドで動作させる．
+
+ 2-2
+  タスクコンテキストと非タスクコンテキスト共にHandlerモードで動作させ
+  る．
+
+プロセッサの設計方針を考慮すると2-1が有力．2-1での問題点としては，割込
+みハンドラからタスクへのリターン時にモードの変更が以下の様に多発するこ
+とが挙げられる．
+
+1.割込みハンドラ               : Handlerモード
+2.タスク例外ハンドラの呼び出し : Threadモード
+3.タスクへのリターン処理       : Handlerモード
+4.タスクの再開                 : Threadモード
+
+3でHandlerモードに移行する必要があるのは，例外フレームを用いて復帰する
+には，Handlerモードで例外リターン処理を行う必要があるためである．ARMで
+は，複数レジスタのロードとCPSRの復帰を同時に行えるが，M3は行えないため，
+この方法で割込み先のタスクにリターンする必要がある．
+
+2-2の場合の割込みハンドラからタスクへのリターン時にモードの変更を以下
+に示す．また，2-2では割込み優先度の最低値をタスクの実行時の優先度とし
+てリザーブする必要がある．
+
+1.割込みハンドラ               : Handlerモード
+2.NVIC優先度マスク'0'を0へ     : Threadモード
+3.最低優先度のHandlerモードへ  : Handlerモード
+4.タスク例外ハンドラの呼び出し : Handlerモード
+5.タスクへのリターンの前処理   : Threadモード
+3.タスクへのリターン           : Handlerモード
+4.タスクの再開                 : Handlerモード
+
+割込みハンドラからタスクのリターンに関しては，2-2であっても，2を実行す
+る場合に，NVIC優先度マスクを'0'にするため，例外リターン処理を行う必要
+がある．また，NVIC自体が，割込みのネスト回数を管理しているため，3から4
+への遷移のために，いったん例外/割込みを受付けた状態にする必要があるた
+め，結果的に2-1以上の遷移が必要となる．
+
+2-2の場合は，MSPしか使えないため，割込みの入り口でネスト回数を判断して，
+スタックを入れ替える必要がある．
+
+HRP等でメモリ保護を用いる場合は2-1となる．
+
+以上の理由により，2-1を採用する．ただし2-1は，カーネル起動時とIDLEルー
+プの扱いを検討する必要がある．これらについては別途議論する．
+
+
+3.ディスパッチャの実行モード
+
+ 3-1
+  Threadモードで実行する
+
+ 3-2
+  Handlerモードで実行する
+
+ディスパッチャをThreadモードで実行すると，割込みによりプリエンプトされ
+たタスクに戻る場合は次のようなパスになる．
+
+ 1. ディスパッチャ呼び出し : Threadモード 
+ 2. ディスパッチャ実行     : Threadモード
+ 3. タスク例外実行         : Threadモード
+ 4．タスクへのリターン処理 : Handlerモード
+ 5. タスクの再開           : Threadモード
+
+割込みハンドラから自らディスパッチしたタスクへリターンする場合は次のパ
+スになる．
+
+ 1.割込みハンドラ               : Handlerモード
+ 2.ディスパッチャ実行           : Threadモード
+ 3.タスク例外ハンドラの呼び出し : Threadモード
+ 4.タスクへのリターン           : Handlerモード
+ 5.タスクの再開                 : Threadモード
+
+一方，ディスパッチャをHandlerモードで実行すると，割込みによりプリエン
+プトされたタスクに戻る場合は次のようなパスになる．
+
+ 1. ディスパッチャ呼び出し : Threadモード 
+ 2. ディスパッチャ実行     : Handlerモード
+ 3. タスク例外実行         : Threadモード
+ 4．タスクへのリターン     : Handlerモード
+ 5. タスクの再開           : Threadモード
+
+割込みハンドラの出口から自らディスパッチしたタスクへリターンする場合は
+次のパスになる．
+
+ 1.割込みハンドラ               : Handlerモード
+ 2.ディスパッチャ実行           : Handlerモード
+ 3.タスク例外ハンドラの呼び出し : Threadモード
+ 4.タスクへのリターン           : Handlerモード
+ 5.タスクの再開                 : Threadモード
+
+タスク例外ハンドラがないOSの場合は，Handlerモードで実行した方がモード
+の遷移の回数が減るが，タスク例外ハンドラがあると，Threadモードの方が遷
+移回数が減るため，Threadモードとする．
+
+メモリ保護を考慮すると，ディスパッチャはHandlerモードで動作させた方が
+効率がよいと考えられる（SVCでハンドラを呼び出すとHandlerモードとなるた
+め）．
+
+
+4.スタックの使い分け
+
+ 4-1
+  タスクコンテキストをPSP, 非タスクコンテキストをMSP
+ 4-2
+  タスクコンテキスト，非タスクコンテキスト共にMSP
+
+4-2の場合，割込みの入り口でネスト回数を判断して，スタックを入れ替える
+必要がある．2でタスクコンテキストはThreadモード，非タスクコンテキスト
+はHandlerモードで動作させるとしたため，4-1を採用すると，割込みの入り口
+で自動的にスタックが切り替わる．ThreadモードでのPSPのアクセスも，
+mrs/msr命令で行えるため，4-1を採用する．
+
+
+5.コンテキストの判定
+
+ 5-1
+  IPSRが'0'(Threadモード)ならタスクタスクコンテキスト，'1'(Handlerモー
+  ド)なら非タスクコンテキストとする．
+
+ 5-2
+  割込みのネスト回数を保持する変数を用意．1以上で非タスクコンテキスト．
+
+ 5-3
+  アクティブなスタックにより判断（MSPなら非タスクコンテキスト，PSPなら
+  タスクコンテキストとする）
+
+5-1は，ソフトウェア側でコンテキスト管理のための処理を行う必要がないと
+いうメリットがある．しかしながら，カーネルの起動時Threadモードであるた
+め，Handlerモードへ移行する必要がある．ASPカーネルでは，IDLEループ実行
+は非タスクコンテキストとして動作させる必要があるため，IDLEループは
+Handlerモードで動作させる必要がある．IDLEループはディスパッチャから呼
+び出される．3で定めたように，ディスパッチャをThreadモードで動作させる
+ため，IDLEループを呼び出す際には，Handlerモードへ遷移する必要がある．
+Handlerモードへの遷移は，SVC/PendSVCを用いると実現可能であるが，6の割
+込みにプリエンプトされたタスクへのリターン時のHandlerモードへの移行で
+もSVC/PendSVCの使用が必要となるため，SVCハンドラでは，どの目的で呼び出
+されたか判定する必要が出てくるため，オーバヘッドが増大する．
+
+5-2では，カーネル起動時やIDLEループ時に変数を'1'に設定すればよいことに
+なる．この場合，カーネル起動時やIDLEループ時にThreadモードで実行しても
+動作に問題がないよう，特に割込みの出入り口の設計を注意する必要がある．
+
+カーネル起動時に関しては，全割込みを禁止しており，割込みが入らないので
+特に問題はない．IDLEループ時は，ThreadモードでMSPとPSPの選択が可能であ
+ることを利用して，非タスクコンテキストのスタックであるMSPに変更する．
+例外/割込みの入り口では，多重割込みであるかをEXC_RETURNのモード判定の
+ビットではなく，スタックの判定ビットで行えば問題ない．例外/割込みから
+のリターンに関しては，多重割込みの判定は，入り口と同様にEXC_RETURNのス
+タック判定ビットで行えばよい．例外リターン処理時にpcに代入する
+EXC_RETURNの値を一律0xfffffffd (Threadモード with MSP)とするのではなく，
+例外/割込み受付け時にLRに設定されるEXC_RETURNを用いることにより，IDLE
+ループに割り込んだ場合でも問題なくリターンする．
+
+カーネル起動時は，MSPがアクティブであり，割込みハンドラ実行時はHandler
+モードであることからMSPがアクティブでり，IDLEループ時にMSPをアクティブ
+に設定すると，非タスクコンテキストは全て，MSPをアクティブにして動作す
+ることになる．また，割込み時は割込み前にアクティブなスタックの情報が，
+EXC_RETURNに設定される．そのため，コンテキストの判定は，割込みネスト回
+数を保持する変数がなくとも，アクティブなスタックを見ればよいことになる．
+また，exc_sense_context()に関しては，例外フレーム中にEXC_RETURNを追加
+し，その内容により判断すればよい．以上の理由により，5-3を採用する．
+
+
+6.割込みにプリエンプトされたタスクへのリターン時のHandlerモードへの移
+  行方法
+
+ 6-1
+  SVCを用いる
+ 6-2
+  PendSVCを用いる
+
+PendSVCとSVCの違いは，PendSVCが要求がキューイングされ，SVCは要求がキュ
+ーイングされないことである．割込みにプリエンプトされたタスクへのリター
+ン時のHandlerモードへの移行は，キューイングされずに即座に処理される必
+要があるため，どちらで実現しても問題ない．どちらをカーネルのリソースし
+て使用するかの選択だけである．
+
+どちらを使うとしても，優先度の設定が問題となる．ディスパッチャから割込
+みにプリエンプトされたタスクへのリターンまでの処理は，少なくともCPUロ
+ック状態で実行されなければならない．SVCやPendSVCはどちらも割込み優先度
+を持つため，NVIC優先度マスクよりBASEPRI優先度マスクの方が高い場合，処
+理されない．
+
+CPUロック状態をBASEPRIの設定で実現した場合，その設定値をSVCやPendSVCに
+設定した値より低くする必要がある．言い換えると，SVCやPendSVCの優先度を
+CPUロック時の優先度マスクの値より高い値（他の割込みより高い優先度）と
+する必要がある．
+
+CPUロック状態をFAULTMASKやPRIMASKで実現した場合は，これらが設定される
+と，SVCやPendSVCが受付けられないため，いったんBASEPRIにより割込みをマ
+スクするように設定する必要がある．この場合も，SVCやPendSVCは他の割込み
+より高い優先度を設定する必要がある．
+
+以上により，Handlerモードへの移行のためには，CPUロック状態をBASEPRIで
+実現し，SVCやPendSVCに設定する優先度をカーネル管理内の最高優先度より一
+つ高い優先度に設定する必要がある．
+
+ARMv7-MではSVCにより実現する．SVNの方がPendSVCより実行オーバヘッドが小
+さいため，SVCを使用する
+
+ARMv6-MではSVCにより実現する．ARMv6-MはCPUロック状態をPRIMASKで実現し
+ているPRIMASKをセットした状態でSVCを実行するとフォールトとなるため，
+PendSVCを発行して，PRIMASKをクリアすることで実現する．PendSVCの割込み
+優先度は最高としているため，この間で割込みが入ることはない．
+
+
+7. 例外/割込み出入り口での多重割込みの判断
+
+7-1
+ EXC_RETURNのモード判定ビット
+7-2
+ EXC_RETURNのスタック判定ビット
+7-3
+ 割込みネスト回数の管理変数
+
+例外/割込み受付け時は，受付けた例外/割込み以下の割込みは禁止するが，全
+割込み禁止状態にはならない．そのため，割込みネスト回数の管理変数をイン
+クリメントする前に割込みが入る可能性があるため，7-3は使用することがで
+きない．
+
+5で議論した通り，IDLEループをThreadモードで実行するため，7-1ではなく，
+7-2で判断する必要がある．
+
+
+8. IDLEループ
+
+8-1
+ Threadモードで実行
+8-2
+ Handlerモードで実行
+
+5で議論した通り，Threadモードで実行できた方がオーバヘッドが小さい．ま
+た，Threadモードで実行しても，割り込みの出入り口で正しく非タスクコンテ
+キストと判定できれば，Threadモードで問題ない．
+
+
+9．カーネル管理外の割込みのサポート
+
+9-1
+ カーネル管理外の割込みをサポートしない
+9-2
+ カーネル管理外の割込みをサポートする
+
+ARMv7-Mでは，CPUロックをBASEPRIで実現していること，ベクタテーブルをサ
+ポートしており，割込みハンドラもC言語で記述可能であるため，サポートが
+容易であるため，サポートする．
+
+ARMv6-Mでは，CPUロックをPRIMASKで実現しているため，サーポートしない．
+
+
+10. CPUロック
+
+10-1
+ BASEPRIを使用(ARMv7-M) 
+ 個別の割込み禁止許可でエミュレーション(ARMv6-M)
+10-2 
+ FAULTMASK/PRIMASKを使用
+
+カーネルの管理外の割込みをサポートするなら，BASEPRIを使用する必要があ
+る．
+
+ARMv7-MではCPUロックにBASEPRIを使用する．
+
+ARMv6-MではCPUロックにPRIMASKを使用する．個別の割込み禁止許可でエミュ
+レーションする方法は，SysTicのみ別のレジスタで設定する必要があり，実行
+オーバヘッドが大きいという問題がある．
+
+11. 割込みロックとCPU例外の関係
+
+11-1
+ BASEPRIを使用(ARMv7-M) 
+11-2 
+ FAULTMASK/PRIMASKを使用 
+
+FAULTMASK/PRIMASKを使用すると，NMI と Hardware Fault 以外のCPU例外も禁
+止されてしまう．
+
+BASEPRIを用いると，割込みロック中にもCPU例外を受付けたい場合は，
+BASEPRIを用いて，最高優先度をCPU例外のためにリザーブする必要がある．
+
+割込みロック時も，CPU例外を受付けるようにしたければBASEPRIを使用する必
+要がある．
+
+μIRON4.0仕様の3.5.3では，CPU例外の優先度は次のように定められている．
+
+"CPU例外ハンドラの優先順位は，CPU例外が発生した処理の優先度と，ディス
+パッチャの優先順位のいずれかよりも高い．"
+
+CPU例外が発生した処理の優先度よりも高いとあるので，CPUロックや割込みロ
+ック状態のタスクで発生した場合でも，優先して実行されるべきだとも考えら
+れる．
+
+一方，TOPPERS標準割込み処理モデルの仕様書では，CPU例外は，プロセッサ毎
+に異なるため，CPU例外の処理モデルの標準化検討の対象外としている．その
+ため，ARM-Mでの扱いを決めて，マニュアルに明記すればよいと考えられる．
+
+ARMv7-Mでは割込みロックはBASEPRIを使用する．
+
+ARMv6-Mでは割込みロックはPRIMASKを使用する．
+
+
+12. 外部優先度と内部優先度の変換
+
+外部優先度とはAPIで指定する割込み優先度(PRI型)のことであり，値が小さい
+ほど優先度が高い．割込みハンドラには，-1から連続した負の値を設定可能で
+ある．内部優先度は，BASEPRIやNVICの優先度レジスタに設定する値である．
+
+実装される割込み優先度のビット幅を TBITW_IPRI とすると，設定可能な外部
+優先度は次のようになる．
+
+  TIPM_ENAALL（＝0）～ -(1 << TBITW_IPRI)
+
+
+13. カーネル管理内の最高優先度(CPUロック状態での優先度マスク)
+
+6.で述べたように，割込みの出口でSVCハンドラを呼び出す必要があるため，
+SVCハンドラはCPUロック状態のBASEPRIに設定する優先度マスクより高い優先度
+を設定する必要がある．
+
+実装される割込み優先度のビット幅を TBITW_IPRI，優先度中のサブ優先度の
+ビット幅をTBIT_IPRIとすると，CPUロック状態（カーネル管理内割込みに設定
+可能な最高優先度）として指定可能な優先度マスクの設定範囲は以下の値の範
+囲となる．
+
+    -(2^(TBIW_IPRI) - 1) + (2^TBITW_SUBIPRI) ～ -1
+
+
+14. 割込み優先度マスク
+
+ARMv7-MではBASEPRIにより実現する．
+
+ARMv6-Mでは個別の割込み禁止許可機能を用いてエミュレーションする．
+
+
+15. FPUのサポート
+
+15-1
+ FPUを使用するタスク/ISRをユーザが指定する． 指定していないタスク/ISR
+ ではFPUを使用すると例外となる．
+15-2
+ FPUを使用するタスク/ISRをユーザは指定しない．全てのタスク/ISRでFPUを
+ 使用可能である．
+ 
+15-1は一般にコンテキストの保存復帰のオーバヘッドを低減する目的で採用さ
+れる．15-1を採用すると，タスクとISRの属性の拡張が必要となる．
+
+ARMv7-Mでは，FPUを使用した場合のみ例外・割込みの入り口でFPUコンテキス
+トを保存する機能があるため，15-2を選択しても，FPUを使わない限りはペナ
+ルティはないと考え，15-2を採用する．
+
+FPUに関するサポートのバリエーションは次の組み合わせが可能である．
+
+                       FPCCR                          コンテキスト  
+                    LSPEN  ASPEN コンパイルオプション  保存復帰     FPU
+NO_FPU                -      -        指定なし           なし       無効   
+FPU_NO_PRESERV        0      0    -mfpu=fpv4-sp-d16      なし       有効
+FPU_NO_LAZYSTACKING   0      1    -mfpu=fpv4-sp-d16      あり       有効
+FPU_LAZYSTACKING      1      1    -mfpu=fpv4-sp-d16      あり       有効
+
+NO_FPU
+FPUを使用しない．Cortex-M0/Cortex-M0+/Cortex-M3/Cortex-M4 の場合に指定．
+ディスパッチャ等ではFPUコンテキストの保存復帰を行わない．
+
+FPU_NO_PRESERV
+FPUを使用する．Cortex-M4F の場合に指定可能．
+ディスパッチャ等ではFPUコンテキストの保存復帰を行わない．
+FPUを使用可能なタスクは1個もしくは，システム中の最高優先度のISR群で使
+用可能．
+
+FPU_NO_LAZYSTACKING
+FPUを使用する．Cortex-M4F の場合に指定可能．
+ディスパッチャ等ではFPUコンテキストの保存復帰を行う．Lazy stacking は
+使用しない．
+全てのタスク/ISRでFPUを使用可能．
+
+FPU_LAZYSTACKING
+FPUを使用する．Cortex-M4F の場合に指定可能．
+ディスパッチャ等ではFPUコンテキストの保存復帰を行う．Lazy stacking を
+使用する．
+全てのタスク/ISRでFPUを使用可能．
+
+
+FPU_NO_LAZYSTACKING時のレジスタの保存・復帰コード
+
+FPU_NO_LAZYSTACKING の場合は一般レジスタと同じタイミングで，ディスパッ
+チ元のタスクがFPUを使用していたかを判断してレジスタを保存・復帰すれば
+よい．該当する箇所は次の通りである．
+
+ディスパッチ(dispatch)
+・CONTROL.FPCAをチェックして'1'ならs16-s31を保存する
+・復帰用にCONTROL.FPCAをタスクスタックに保存
+
+ディスパッチからの復帰(dispatch)
+・CONTROL.FPCAをタスクスタックから復帰する
+・復帰したCONTROL.FPCAをチェックして'1'ならs16-s31をタスクスタックから
+  復帰する．
+
+遅延ディスパッチ(ret_int_4)
+・タスクが割り込まれた際のEXC_RETURNをタスクスタックに保存しておく
+・EXC_RETURNをタスクスタックから復帰
+・復帰したEXC_RETURN[4] == 0(FPU使用)ならs16-s31をタスクスタックに保存
+  する．
+・復帰用にEXC_RETURNの値をタスクスタックに保存  
+
+遅延ディスパッチからの復帰(ret_int_r)
+・タスクが割り込まれた際のEXC_RETURNの値をタスクスタックから復帰
+・復帰したEXC_RETURN[4] == 0(FPU使用)ならs16-s31をタスクスタックから復帰
+・先のSVCハンドラ呼び出し時にFPUレジスタを積まないようにCONTROL.FPCAをクリア．
+
+FPU_LAZYSTACKING時のレジスタの保存・復帰コード
+
+FPU_NO_LAZYSTACKING時のコードをそのまま使用するとFPU_LAZYSTACKINGの場
+合は，割込み・例外発生後に次のタイミングで例外フレームにFPUのコンテキ
+ストがハードウェアによって自動的に保存される．
+
+例外・割込みハンドラ実行中
+FPUを使用したタスク/ISR実行中に例外・割込みが発生し，例外・割込みハン
+ドラでFPU命令を実行した場合．FPCCR.LSPACT==1 となっているため．
+
+遅延ディスパッチ時(ret_int_4)
+例外・割込みハンドラでFPUを使用しなかった場合は，ret_int_4実行時にはコ
+ンテキストは保存されていない．さらに各レジスタの値は次のようになってい
+る．
+・FPCCR.LSPACT == '1'
+・FPCAR = 例外フレームのFPUレジスタの保存アドレス(S0のアドレス)
+ret_int_4では，s16-s31 をタスクスタックに保存する．ここでFPUを使用する
+ため，s0-s15,FPSRは例外フレームに保存される．
+
+以下の箇所はFPU_LAZYSTACKINGの場合にのみ必要である．
+
+割込み出口でのタスク例外呼び出し時
+FPUを使用したタスク実行中に例外/割込みが発生し，例外/割込みの出口から
+タスク例外処理を呼び出した場合には，FPCCR.LSPACT == '1' とFPUコンテキ
+ストが保存されていない状態でタスク例外が呼び出される可能性がある．タス
+ク例外でext_tsk()を呼び出した場合や他のタスクにディスパッチされ，
+ter_tsk()で終了させられた場合には，FPCCR.LSPACT を '0'にクリアする必要
+がある．ext_tsk()のケースはターゲット依存部exit_and_dispatch()が呼び出
+されるため，ここでクリアすれば良いが，ter_tsk()ではターゲット依存部を
+呼び出さないため，クリアすることが出来ない．そのため，割込み出口でのタ
+スク例外呼び出すタイミングでFPUコンテキストをスタックに格納するため，
+副作用のないFPU命令を発行する．
+なお，他のタスクにディスパッチされた場合は，CONTROL.FPCAが'1'で無いた
+め(タスク例外でFPUを使用しなかった場合)，s16～s31のFPUレジスタの保存が
+行われず，例外フレームへの書き戻しが発生しない．
+
+CONTROL.FPCAのセット・クリアのタイミング
+
+クリアする箇所が複数箇所になると把握が困難であるため，ディスパッチャの先頭で
+は一律CONTROL.FPCAを'0'にクリアする．
+
+dispatchを呼び出したタスクへのリターンする際には，戻り先のタスクがFPU
+を使用しいた場合は，s16～s31の復帰を行うため，この処理により
+CONTROL.FPCAが'1'にセットされる．
+
+また，EXC_RETURNによるリータン時はEXC_RETURNの値によってリーターン時に
+ハードウェア的に自動的にCONTROL.FPCAが元の状態に復帰されるのでソフトウ
+ェアによる処理は必要ない．
+
+タスク例外の扱い
+
+タスク例外でFPUを使用して，通常の処理でFPUを使用しない場合は，タスク例
+外の呼び出しの前後で CONTROL.FPCA を保存復帰する方法もあるが，レアケー
+スであると考えられるためサポートしない．
+
+ABI
+
+GCCでは3種類選択可能．
+
+hard    : 浮動小数点命令を使用してABIはFPUレジスタを使用．
+soft    : 浮動小数点命令を使用しない．
+softfp  : 浮動小数点命令を使用するがABIはsoftと同じ．
+
+既存のライブラリとリンクする場合はsoftfpが有効だが，ユーザーカスタマイ
+ズとしてディフォルトは，hardとする．
+
+マクロ
+
+FPUコンテキスト復帰保存を有効化するマクロ．
+
+TOPPERS_FPU_CONTEXT
+
+FPUの使用を有効化するマクロ．
+
+TOPPERS_FPU_ENABLE
+
+FPUのアーキテクチャを指定するマクロ．ARMCCと合わせて次のマクロを使用する．
+__TARGET_FPU_FPV4_SP
+
+FPU_NO_PRESERV/FPU_NO_LAZYSTACKING/FPU_LAZYSTACKINGの場合は次のマクロを定義する．
+
+TOPPERS_FPU_NO_PRESERV
+
+TOPPERS_FPU_NO_LAZYSTACKING
+
+TOPPERS_FPU_LAZYSTACKING
+
+
+16. 未解決課題
+・割込みロックとCPU例外の関係
+  BASEPRIを使ったとしても，あるCPU例外処理中に他の例外が発生すると，そ
+  の例外は受け付けられないため，ITRON仕様は満たせない．
+  ->あきらめてマニュアル記載に逃げるか.
+  メモリプロテクションの例外もマスク可能であるため要件等．
+
+以上．
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/arch/arm_m_gcc/common/core_insn.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/arch/arm_m_gcc/common/core_insn.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/arch/arm_m_gcc/common/core_insn.h	(revision 457)
@@ -0,0 +1,152 @@
+/*
+ *  TOPPERS/ASP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Advanced Standard Profile Kernel
+ * 
+ *  Copyright (C) 2008 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+
+/*
+ *  コア依存の特殊命令のインライン関数定義（ARM-M用）
+ */
+
+#ifndef CORE_INSN_H
+#define CORE_INSN_H
+
+#include <arm_m.h>
+
+/*
+ *  メモリが変更されることをコンパイラに伝えるためのマクロ
+ */
+#define ARM_MEMORY_CHANGED Asm("":::"memory")
+
+/*
+ *  FAULTMASKのセット
+ */
+Inline void
+set_faultmask(void){
+	Asm("cpsid f":::"memory");
+}
+
+/*
+ *  FAULTMASKのクリア
+ */
+Inline void
+clear_faultmask(void){
+	Asm("cpsie f":::"memory");
+}
+
+/*
+ *  PRIMASKのセット
+ */
+Inline void
+set_primask(void){
+	Asm("cpsid i":::"memory");
+}
+
+/*
+ *  PRIMASKのクリア
+ */
+Inline void
+clear_primask(void){
+	Asm("cpsie i":::"memory");
+}
+
+/*
+ *  PRIMASKのリード
+ */
+Inline uint32_t
+read_primask(void){
+	uint32_t val;
+
+	Asm("mrs  %0, PRIMASK" : "=r"(val));
+	return val;
+}
+
+/*
+ *  BASEPRIのセット
+ */
+Inline void
+set_basepri(uint32_t val){
+	Asm("msr BASEPRI, %0" : : "r"(val) : "memory");
+}
+
+/*
+ *  BASEPRIの取得
+ */
+Inline uint32_t
+get_basepri(void){
+	uint32_t val;
+	Asm("mrs  %0, BASEPRI" : "=r"(val));
+	return(val);
+}
+
+/*
+ *  CONTROLのセット
+ */
+Inline void
+set_control(uint32_t val){
+	/*
+	 *  controlレジスタセット後にはisbが必須
+	 *  [ARMv7-M Architecture Reference Manaual(DDI0403B) A3-37]
+	 */
+	Asm("msr control, %0 \n"
+		" isb"
+		: : "r"(val) : "memory");
+}
+
+/*
+ *  CONTROLの取得
+ */
+Inline uint32_t
+get_control(void){
+	uint32_t val;
+	Asm("mrs  %0, CONTROL" : "=r"(val));
+	return(val);
+}
+
+/*
+ *  ステータスレジスタ（CPSR）の現在値の読出し
+ */
+Inline uint32_t
+get_ipsr(void)
+{
+    uint32_t sr;
+    Asm("mrs  %0, ipsr" : "=r"(sr));
+    return(sr);
+}
+
+#endif /* CORE_INSN_H */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/arch/arm_m_gcc/common/core_kernel.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/arch/arm_m_gcc/common/core_kernel.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/arch/arm_m_gcc/common/core_kernel.h	(revision 457)
@@ -0,0 +1,64 @@
+/*
+ *  TOPPERS/ASP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Advanced Standard Profile Kernel
+ * 
+ *  Copyright (C) 2008-2011 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *		kernel.hのコア依存部（ARM-M用）
+ *
+ *  このインクルードファイルは，target_kernel.h（または，そこからインク
+ *  ルードされるファイル）のみからインクルードされる．他のファイルから
+ *  直接インクルードしてはならない．
+ */
+
+#ifndef TOPPERS_CORE_KERNEL_H
+#define TOPPERS_CORE_KERNEL_H
+
+/*
+ *  サポートする機能の定義
+ */
+#define TOPPERS_TARGET_SUPPORT_DIS_INT      /* dis_intをサポートする */
+#define TOPPERS_TARGET_SUPPORT_ENA_INT      /* ena_intをサポートする */
+
+#define TMAX_INTPRI		(-1)		/* 割込み優先度の最大値（最低値）*/
+
+#ifndef TOPPERS_MACRO_ONLY
+
+#endif /* TOPPERS_MACRO_ONLY */
+
+#endif /* TOPPERS_CORE_KERNEL_H */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/arch/arm_m_gcc/common/core_offset.tf
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/arch/arm_m_gcc/common/core_offset.tf	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/arch/arm_m_gcc/common/core_offset.tf	(revision 457)
@@ -0,0 +1,19 @@
+$
+$       オフセットファイル生成用テンプレートファイル（ARM-M用）
+$
+
+$
+$  オフセット値のマクロ定義の生成
+$
+$DEFINE("TCB_p_tinib", offsetof_TCB_p_tinib)$
+$DEFINE("TCB_texptn", offsetof_TCB_texptn)$
+$DEFINE("TCB_sp", offsetof_TCB_sp)$
+$DEFINE("TCB_pc", offsetof_TCB_pc)$
+
+$DEFINE("TINIB_exinf", offsetof_TINIB_exinf)$
+$DEFINE("TINIB_task", offsetof_TINIB_task)$
+
+$
+$  ビットオフセット値等のマクロ定義の生成
+$
+$DEFINE_BIT("TCB_enatex", sizeof_TCB, "B")$
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/arch/arm_m_gcc/common/core_rename.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/arch/arm_m_gcc/common/core_rename.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/arch/arm_m_gcc/common/core_rename.h	(revision 457)
@@ -0,0 +1,93 @@
+/* This file is generated from core_rename.def by genrename. */
+
+#ifndef TOPPERS_CORE_RENAME_H
+#define TOPPERS_CORE_RENAME_H
+
+/*
+ *  core_config.c
+ */
+#define exc_tbl						_kernel_exc_tbl
+#define vector_table				_kernel_vector_table
+#define lock_flag					_kernel_lock_flag
+#define saved_iipm					_kernel_saved_iipm
+#define default_exc_handler			_kernel_default_exc_handler
+#define default_int_handler			_kernel_default_int_handler
+#define x_config_int				_kernel_x_config_int
+#define core_initialize				_kernel_core_initialize
+#define core_terminate				_kernel_core_terminate
+#define bitpat_cfgint				_kernel_bitpat_cfgint
+#define set_exc_int_priority		_kernel_set_exc_int_priority
+#define enable_exc					_kernel_enable_exc
+#define disable_exc					_kernel_disable_exc
+#define iipm_enable_irq_tbl			_kernel_iipm_enable_irq_tbl
+#define iipm_enable_systic_tbl		_kernel_iipm_enable_systic_tbl
+#define iipm						_kernel_iipm
+#define ief							_kernel_ief
+#define ief_systick					_kernel_ief_systick
+
+/*
+ *  core_support.S
+ */
+#define core_int_entry				_kernel_core_int_entry
+#define core_exc_entry				_kernel_core_exc_entry
+#define ret_int						_kernel_ret_int
+#define ret_exc						_kernel_ret_exc
+#define svc_handler					_kernel_svc_handler
+#define start_r						_kernel_start_r
+#define dispatch					_kernel_dispatch
+#define start_dispatch				_kernel_start_dispatch
+#define exit_and_dispatch			_kernel_exit_and_dispatch
+#define call_exit_kernel			_kernel_call_exit_kernel
+
+/*
+ *  start.S
+ */
+#define _start						_kernel__start
+
+#ifdef TOPPERS_LABEL_ASM
+
+/*
+ *  core_config.c
+ */
+#define _exc_tbl					__kernel_exc_tbl
+#define _vector_table				__kernel_vector_table
+#define _lock_flag					__kernel_lock_flag
+#define _saved_iipm					__kernel_saved_iipm
+#define _default_exc_handler		__kernel_default_exc_handler
+#define _default_int_handler		__kernel_default_int_handler
+#define _x_config_int				__kernel_x_config_int
+#define _core_initialize			__kernel_core_initialize
+#define _core_terminate				__kernel_core_terminate
+#define _bitpat_cfgint				__kernel_bitpat_cfgint
+#define _set_exc_int_priority		__kernel_set_exc_int_priority
+#define _enable_exc					__kernel_enable_exc
+#define _disable_exc				__kernel_disable_exc
+#define _iipm_enable_irq_tbl		__kernel_iipm_enable_irq_tbl
+#define _iipm_enable_systic_tbl		__kernel_iipm_enable_systic_tbl
+#define _iipm						__kernel_iipm
+#define _ief						__kernel_ief
+#define _ief_systick				__kernel_ief_systick
+
+/*
+ *  core_support.S
+ */
+#define _core_int_entry				__kernel_core_int_entry
+#define _core_exc_entry				__kernel_core_exc_entry
+#define _ret_int					__kernel_ret_int
+#define _ret_exc					__kernel_ret_exc
+#define _svc_handler				__kernel_svc_handler
+#define _start_r					__kernel_start_r
+#define _dispatch					__kernel_dispatch
+#define _start_dispatch				__kernel_start_dispatch
+#define _exit_and_dispatch			__kernel_exit_and_dispatch
+#define _call_exit_kernel			__kernel_call_exit_kernel
+
+/*
+ *  start.S
+ */
+#define __start						__kernel__start
+
+#endif /* TOPPERS_LABEL_ASM */
+
+
+#endif /* TOPPERS_CORE_RENAME_H */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/arch/arm_m_gcc/common/core_sil.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/arch/arm_m_gcc/common/core_sil.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/arch/arm_m_gcc/common/core_sil.h	(revision 457)
@@ -0,0 +1,104 @@
+/*
+ *  TOPPERS Software
+ *      Toyohashi Open Platform for Embedded Real-Time Systems
+ * 
+ *  Copyright (C) 2008-2015 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *   sil.hのコア依存部（ARM-M用）
+ */
+
+#ifndef TOPPERS_CORE_SIL_H
+#define TOPPERS_CORE_SIL_H
+
+#ifndef TOPPERS_MACRO_ONLY
+
+#if __TARGET_ARCH_THUMB == 4
+static uint32_t pre_basepri;
+#endif /* __TARGET_ARCH_THUMB == 4 */
+
+/*
+ *  NMIを除くすべての割込みの禁止
+ */
+Inline bool_t
+TOPPERS_disint(void)
+{
+	uint32_t val;
+#if __TARGET_ARCH_THUMB == 4
+	Asm("mrs  %0, BASEPRI" : "=r"(val));
+	if(val != (1 << (8 - TBITW_IPRI))){
+		pre_basepri = val;
+		val = (1 << (8 - TBITW_IPRI));
+		Asm("msr BASEPRI, %0" : : "r"(val) : "memory");
+		return (false);
+	} else {
+		return (true);
+	}
+#else /* __TARGET_ARCH_THUMB == 3 */
+	Asm("mrs  %0, PRIMASK" : "=r"(val));
+	Asm("cpsid i":::"memory");
+#endif /* __TARGET_ARCH_THUMB == 4 */
+
+	if (val == 1) {
+		return (true);
+	}
+	else {
+		return (false);
+	}
+}
+
+Inline void
+TOPPERS_enaint(bool_t locked)
+{
+	if (!locked) {
+#if __TARGET_ARCH_THUMB == 4
+		Asm("msr BASEPRI, %0" : : "r"(pre_basepri) : "memory");
+#else /* __TARGET_ARCH_THUMB == 3 */
+		Asm("cpsie i":::"memory");
+#endif /* __TARGET_ARCH_THUMB == 4 */
+	}
+}
+
+/*
+ *  全割込みロック状態の制御
+ */
+#define SIL_PRE_LOC      bool_t  TOPPERS_locked
+#define SIL_LOC_INT()    ((void)(TOPPERS_locked = TOPPERS_disint()))
+#define SIL_UNL_INT()    (TOPPERS_enaint(TOPPERS_locked))
+
+#endif /* TOPPERS_MACRO_ONLY */
+
+#endif /* TOPPERS_CORE_SIL_H */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/arch/arm_m_gcc/common/core_stddef.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/arch/arm_m_gcc/common/core_stddef.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/arch/arm_m_gcc/common/core_stddef.h	(revision 457)
@@ -0,0 +1,62 @@
+/*
+ *  TOPPERS Software
+ *      Toyohashi Open Platform for Embedded Real-Time Systems
+ * 
+ *  Copyright (C) 2008-2011 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *  t_stddef.hのコア依存部（ARM-M用）
+ *
+ *  このインクルードファイルは，target_stddef.h（または，そこからインク
+ *  ルードされるファイル）のみからインクルードされる．他のファイルから
+ *  直接インクルードしてはならない．
+ */
+
+#ifndef TOPPERS_CORE_STDDEF_H
+#define TOPPERS_CORE_STDDEF_H
+
+/*
+ *  ターゲットを識別するためのマクロの定義
+ */
+#define TOPPERS_ARM_M           /* コア略称 */
+
+/*
+ *  スタックの型
+ *  ARMでは，スタックを8byte境界に配置する必要がある
+ */
+#define TOPPERS_STK_T  long long
+
+#endif /* TOPPERS_CORE_STDDEF_H */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/arch/arm_m_gcc/common/core_support.S
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/arch/arm_m_gcc/common/core_support.S	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/arch/arm_m_gcc/common/core_support.S	(revision 457)
@@ -0,0 +1,805 @@
+/*
+ *  TOPPERS/ASP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Advanced Standard Profile Kernel
+ * 
+ *  Copyright (C) 2008-2015 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *  プロセッサ依存モジュール アセンブリ言語部（ARM-M用）
+ */
+
+#define TOPPERS_MACRO_ONLY
+#define UINT_C(val)		(val)		/* uint_t型の定数を作るマクロ */
+#define ULONG_C(val)	(val)		/* ulong_t型の定数を作るマクロ */
+#define CAST(type, val)	(val)		/* 型キャストを行うマクロ */
+
+#include "kernel_impl.h"
+#include "arm_m.h"
+#include "offset.h"
+#include "target_asm.inc"
+
+/*
+ *  タスクディスパッチャ
+ */
+	ATEXT
+	ABALIGN(4)
+	ATHUMB(dispatch)
+	AGLOBAL(dispatch)
+ALABEL(dispatch)
+	/*
+	 *
+	 *  このルーチンは，タスクコンテキスト・CPUロック状態・ディパッチ許可状態
+	 *  ・（モデル上の）割込み優先度マスク全開状態で呼び出される．
+	 */
+	stmfd sp!,{r4-r11,lr}         /* レジスタの保存 */
+#ifdef TOPPERS_FPU_CONTEXT
+	/* 
+	 * ディスパッチ元のタスクFPUを使用した場合はFPUレジスタを保存
+	 */ 
+	mrs   r0, control             /* CONTROL.FPCA == 0(FPU未使用)ならばスキップ */ 
+	tst   r0, #CONTROL_FPCA
+	beq   dispatch_1
+	vpush {s16-s31}               /* FPUレジスタの保存 */ 
+ALABEL(dispatch_1)
+	push  {r0}                    /* 復帰時の判定用にCONTROLを保存 */  
+#endif /* TOPPERS_FPU_CONTEXT */
+	ldr   r0, =p_runtsk           /* p_runtskを読み込む */
+	ldr   r1, [r0]
+	str   sp, [r1,#TCB_sp]        /* タスクスタックを保存 */
+	ldr   lr, =dispatch_r         /* 実行再開番地を保存 */
+	str   lr, [r1,#TCB_pc]        
+	b     dispatcher
+
+	ATHUMB(dispatch_r)
+	AGLOBAL(dispatch_r)
+ALABEL(dispatch_r)
+#ifdef TOPPERS_FPU_CONTEXT 
+	/* 
+	 * ディスパッチ先のタスクでFPUを使用していた場合はFPUレジスタを復帰
+	 * スタックに保存したCONTROL.FPCAをチェック 
+	 */ 
+	pop   {r3}
+	tst   r3, #CONTROL_FPCA /* CONTROL.FPCA == 0(FPU未使用)ならばスキップ */ 
+	beq   dispatch_r_0
+	vpop {s16-s31}          /* FPUレジスタの復帰 */ 
+ALABEL(dispatch_r_0)
+#endif /* TOPPERS_FPU_CONTEXT */
+	ldmfd sp!,{r4 - r11,lr}       /* レジスタの復帰 */
+	/*
+	 * タスク例外処理ルーチンの起動
+	 * dispatcherから呼び出されるため，TCBのアドレスはr1に入っている
+	 */
+	ldrb  r0,[r1,#TCB_enatex]
+	tst   r0,#TCB_enatex_mask
+	beq   dispatch_r_1            /* enatex が false ならリターン */
+	ldr   r0,[r1,#TCB_texptn]     /* texptn が 0 ならリターン     */
+	tst   r0,r0
+	beq   dispatch_r_1            
+	ldr   r1, =ipmflg             /* ipmflgが false ならリターン  */
+	ldr   r0, [r1]
+	tst   r0,r0
+	beq   dispatch_r_1
+	ldr   r0, =call_texrtn        /* タスク例外ルーチンの呼び出し */
+	bx    r0
+ALABEL(dispatch_r_1)              /* タスクへのcall_textnから戻る */
+	bx    lr
+
+/*
+ *  CPU例外エントリ
+ *
+ *  割込みエントリと処理の内容は同等だが，ログの種類が異なるため，
+ *  分けている．
+ */
+	ABALIGN(4)
+	ATEXT
+	ATHUMB(core_exc_entry)
+	AGLOBAL(core_exc_entry)
+ALABEL(core_exc_entry)
+	/*
+	 *  例外/割込みが発生すると，発生時にアクティブなスタックにスクラ
+	 *  ッチレジスタ等が保存される．
+	 *  この内容に加えて，CPU例外ハンドラへの情報として，basepri の値と，
+	 *  EXC_RETURNの情報を加えて保存する．basepriの値は，CPU例外からの
+	 *  リターン時に割込み優先度マスクの値を元に戻すためにも用いられる．
+	 *
+	 *   -----------
+	 *  |  basepri  |
+	 *   -----------
+	 *  | EXC_RETURN|
+	 *   -----------
+	 *  |    R0     |  
+	 *   -----------
+	 *  |    R1     |
+	 *   -----------
+	 *  |    R2     |
+	 *   -----------
+	 *  |    R3     |
+	 *   -----------
+	 *  |    R12    |
+	 *   -----------
+	 *  |    LR     |
+	 *   -----------
+	 *  |    PC     |
+	 *   -----------
+	 *  |   xPSR    |
+	 *   -----------
+	 *
+	 */
+
+	/*
+	 *  カーネル管理外の例外かチェック
+	 *  カーネル内のクリティカルセクションの実行中，全割込みロック状態，
+	 *  CPUロック状態，カーネル管理外の割込みハンドラ実行中のいずれかで
+	 *  発生したCPU例外を，カーネル管理外のCPU例外と呼ぶ
+	 *  全割込みロック状態はFAULTMASKが'1'の場合
+	 *  CPUロック状態はbasepriがIIPM_LOCKかで判断する．
+	 */
+	mrs   r2, FAULTMASK           /* 全割込みロック状態ならカーネル管理外例外処理へ */
+	cbnz  r2, core_nonkernel_exc_entry
+
+	mrs   r0, basepri             /* baepriの値を取得 */
+	cmp   r0, #IIPM_LOCK          /* CPUロック状態ならカーネル管理外例外処理へ */
+	beq   core_nonkernel_exc_entry
+
+	/*
+	 * スタックを変更する必要があるかチェック
+	 * EXC_RETURN（割込み時にLRに設定される値）をチェックして，例外発生時に
+	 * アクティブなスタックを特定することで多重割込みか判定する．
+	 */
+	tst   lr, #EXC_RETURN_PSP    /* 割込み元がMSPなら多重割込み */
+	beq   core_exc_entry_1       /* 多重割込みならcore_exc_entry_1へ */
+	mrs   r3, psp                /* 一段目の割込みの場合はPSP上に */
+	stmfd r3!, {r0, lr}          /* 割込み発生時の割込み優先度マスク(r0)，EXC_RETURN(lr)の順にPSP上に積む */
+	msr   psp, r3                
+	push  {r0,lr}                /* 割込み発生時の割込み優先度マスク(r0)，EXC_RETURN(lr)の順にMSP上に積む */
+	mov   r0, r3                 /* CPU例外ハンドラへの引数となる */
+	b     core_exc_entry_2
+ALABEL(core_exc_entry_1)         /* 多重割込みの場合 */
+	push  {r0,lr}                /* 割込み発生時の割込み優先度マスク(r0)，EXC_RETURN(lr)の順にPSP上に積む */
+	mov   r0, sp                 /* CPU例外ハンドラへの引数となる */
+
+	/*
+	 *  共通処理
+	 */
+ALABEL(core_exc_entry_2)
+	mrs   r3, ipsr               /* ハンドラアドレスを取得 */
+	ldr   r1, =_kernel_exc_tbl
+	ldr   r2, [r1, r3, lsl #2]
+
+#ifdef LOG_EXC_ENTER
+	push  {r0,r2,r3}
+	mov   r0, r3                 /* 例外番号をパラメータに  */
+	bl    log_exc_enter          /* log_exc_enterを呼び出す */
+	pop   {r0,r2,r3}
+	push  {r3}                   /* 例外番号をスタックへ    */
+#endif /* LOG_EXC_ENTER */
+
+	/*
+	 *  CPU例外ハンドラの呼び出し
+	 */
+	blx   r2
+
+#ifdef LOG_EXC_ENTER
+	pop   {r0}                   /* 例外番号を引数に        */
+	bl    log_exc_leave          /* log_exc_leaveを呼び出す */
+#endif /* LOG_EXC_ENTER */
+
+	b     ret_exc
+
+/*
+ *  カーネル管理外のCPU例外の出入口処理
+ */
+ALABEL(core_nonkernel_exc_entry)
+	tst   lr, #EXC_RETURN_PSP    /* 割込み元がMSPなら多重割込み */
+	beq   core_nonkernel_exc_entry_1  /* 多重割込みなら */
+	mrs   r3, psp                /* 一段目の割込みの場合はPSP上に */
+	stmfd r3!, {r0, lr}          /* 割込み発生時の割込み優先度マスク(r0)，EXC_RETURN(lr)の順にPSP上に積む */
+	msr   psp, r3                
+	push  {r0,lr}                /* 割込み発生時の割込み優先度マスク(r0)，EXC_RETURN(lr)の順にMSP上に積む */
+	mov   r0, r3                 /* CPU例外ハンドラへの引数となる */
+	b     core_nonkernel_exc_entry_2
+ALABEL(core_nonkernel_exc_entry_1) /* 多重割込みの場合 */
+	push  {r0,lr}                /* 割込み発生時の割込み優先度マスク(r0)，EXC_RETURN(lr)の順にPSP上に積む */
+	mov   r0, sp                 /* CPU例外ハンドラへの引数となる */
+
+ALABEL(core_nonkernel_exc_entry_2)
+	mrs   r3, ipsr               /* CPU例外ハンドラのアドレスを取得 */
+	ldr   r1, =_kernel_exc_tbl
+	ldr   r2, [r1, r3, lsl #2]
+
+	/*
+	 *  CPU例外ハンドラの呼び出し
+	 */
+	blx   r2
+
+	/*
+	 *  割込みロック状態とする．
+	 */
+	cpsid f
+
+	/*
+	 *  戻り先のコンテキストの判定
+	 * 
+	 *  割込みハンドラ実行にLRにセットされるEXC_RETURNをチェックして，戻り
+	 *  先でMSPが使われていれば，割込み先が非タスクコンテキストと判定する．
+	 */
+	pop   {r1,r3}                  /* 元の割込み優先度マスク(basepri)をr1へ，EXC_RETURNをr3へ */
+	tst   r3, #EXC_RETURN_PSP      /* 戻り先がPSPなら              */
+	bne   core_nonkernel_ret_exc_1
+	b     core_nonkernel_ret_exc_2 /* の値をMSPから取得 */
+
+ALABEL(core_nonkernel_ret_exc_1)
+	/*
+	 *  PSP上から，EXC_RETURN(r0)と元の割込み優先度マスク(basepri)分を削除
+	 */
+	mrs   r2, psp
+	add   r2, r2, #(0x04*2)
+	msr   psp, r2
+
+ALABEL(core_nonkernel_ret_exc_2)
+	msr   basepri, r1             /* 割込み優先度マスクを割込み前に状態へ */
+	bx    r3                      /* リターン */
+
+/*
+ *  割込みエントリ
+ */
+	ATHUMB(core_int_entry)
+	AGLOBAL(core_int_entry)
+ALABEL(core_int_entry)
+	/*
+	 *  割込み発生時の割込み優先度マスクをスタックに保存するため取得
+	 */
+	mrs   r0, basepri             /* baepriの値を取得 */
+
+	/*
+	 * 多重割込みかチェック
+	 * EXC_RETURN（割込み時にLRに設定される値）をチェックして，例外発生時に
+	 * アクティブなスタックを特定することで多重割込みか判定する．
+	 */
+	tst   lr, #EXC_RETURN_PSP    /* 割込み元がMSPなら多重割込み */
+	beq   core_int_entry_1       /* 多重割込みならcore_int_entry_1へ */
+	mrs   r3, psp                /* 一段目の割込みの場合はPSP上に */
+	stmfd r3!, {r0, lr}          /* 割込み発生時の割込み優先度マスク(r0)，EXC_RETURN(lr)の順にPSP上に積む */
+	msr   psp, r3                
+	push  {r0,lr}                /* 割込み発生時の割込み優先度マスク(r0)，EXC_RETURN(lr)の順にMSP上に積む */
+	mov   r0, r3                 /* 未定義の割込みが発生した場合の情報とする */
+	b     core_int_entry_2
+ALABEL(core_int_entry_1)         /* 多重割込みの場合 */
+	push  {r0,lr}                /* 割込み発生時の割込み優先度マスク(r0)，EXC_RETURN(lr)の順にPSP上に積む */
+	mov   r0, sp                 /* 未定義の割込みが発生した場合の情報とする */
+
+	/*
+	 *  共通処理
+	 */
+ALABEL(core_int_entry_2)
+	mrs   r3, ipsr               /* ハンドラアドレスを取得 */
+	ldr   r1, =_kernel_exc_tbl
+	ldr   r2, [r1, r3, lsl #2]
+
+	/*
+	 *  basepriの設定
+	 *  NVIC優先度マスクが自動的に設定されるため優先度マスクの点では必要な
+	 *  いが，x_get_ipm()がbasepriを参照するため，basepriも更新する．
+	 */
+	ldr   r1, =_kernel_int_iipm_tbl
+	ldr   lr, [r1, r3, lsl #2]
+	msr   basepri, lr
+
+#ifdef LOG_INH_ENTER
+	push  {r0,r2,r3}
+	mov   r0, r3                 /* 例外番号をパラメータに  */
+	bl    log_inh_enter          /* log_exc_enterを呼び出す */
+	pop   {r0,r2,r3}
+#endif /* LOG_EXC_ENTER */
+
+#ifdef LOG_INH_LEAVE
+	push  { r3 }                   /* 例外番号をスタックへ    */
+#endif /* LOG_INT_LEAVE */
+
+	/*
+	 *  割込みハンドラの呼び出し
+	 */
+	blx   r2
+
+#ifdef LOG_INH_LEAVE
+	pop   {r0}                   /* 例外番号を引数に        */
+	bl    log_exc_leave          /* log_exc_leaveを呼び出す */
+#endif /* LOG_INH_LEAVE */
+
+/*
+ *  割込み/例外出口
+ *
+ *  ret_exc/ret_intは，CPU例外/割込みハンドラから戻った直後に実行する
+ *  ルーチンである．
+ */
+ALABEL(ret_exc)
+ALABEL(ret_int)
+	/*
+	 *  割込みロック状態とする．この時点では，CPUロック状態にはならない
+	 * （basepriとlock_flagとsaved_iipmは更新しない）．
+	 *
+	 *  割込みロック状態とするのは，戻り先のコンテキストのチェックと，
+	 *  戻り先が非タスクコンテキストであった場合のリターンをアトミック
+	 *  に行うためである．bsepriをCPUロックの値にすることでもアトミッ
+	 *  クなチェックと復帰は可能であるが，割込みからリターンしても，
+	 *  basepri の設定内容は元に戻らないため，使用することができない． 
+	 *  一方，FAULTMASKは，割込みからのリターン処理によって，'0'にクリ
+	 *  アされる．
+	 */
+	cpsid f
+
+	/*
+	 *  戻り先のコンテキストの判定
+	 * 
+	 *  割込みハンドラ実行にLRにセットされるEXC_RETURNをチェックして，戻り
+	 *  先でMSPが使われていれば，割込み先が非タスクコンテキストと判定する．
+	 */
+	pop   {r1,r3}                  /* 元の割込み優先度マスク(basepri)をr1へ，EXC_RETURNをr3へ */
+	tst   r3, #EXC_RETURN_PSP      /* 戻り先がPSPなら ret_int_1 へ */
+	bne   ret_int_1
+	b     ret_int_2                /* の値をMSPから取得 */
+
+	/*
+	 *  一段目の割込みの出口処理
+	 */
+ALABEL(ret_int_1)
+	/*
+	 *  reqflgをチェックする
+	 * 
+	 *  カーネル管理内の割込みは禁止した状態で実行する必要があるため，
+	 *  FAULTMASKを'1'にした状態で実行する．
+	 *  reqflgをチェックする前に割込みを禁止するのは，reqflgをチェック
+	 *  した直後に割込みハンドラが起動され，その中でディスパッチが要求
+	 *  された場合に，すぐにディスパッチされないという問題が生じるため
+	 *  である．
+	 */
+	ldr   r0, =reqflg             /* reqflgがfalseならそのまま戻る */
+	ldr   r2, [r0]
+	cbnz  r2, ret_int_3           /* trueならret_int_3へ           */
+
+	/*
+	 *  PSP上から，EXC_RETURN(r0)と元の割込み優先度マスク(basepri)分を削除
+	 */
+	mrs   r2, psp
+	add   r2, r2, #(0x04*2)
+	msr   psp, r2
+
+ALABEL(ret_int_2)
+	/*
+	 *  ここには割込みロック状態（FAULTMASKがセット）された状態で来る．
+	 *  Threadモードからのリターンにより自動的に割込みロック解除状態になる．
+	 *  割込み優先度マスクは割込み前に状態に戻す．
+	 */ 
+	msr   basepri, r1             /* 割込み優先度マスクを割込み前の状態へ */
+	bx    r3                      /* リターン */
+
+ALABEL(ret_int_3)
+	/*
+	 *  ここでは，戻り先がタスクであり，PSP上にスクラッチレジスタと割
+	 *  込み優先度マスク(basepri)が保存された状態になっている．また，
+	 *  プロセッサは，Handlerモード・割込みロック状態となっている．
+	 *  また，r0には，reqflgのアドレス，r3には割込み受付時のlrの値が保
+	 *  持されている．
+	 */
+	/*
+	 *  タスク例外ハンドラやディスパッチをする際にThreadモードへ遷移する
+	 *  ダミーのスタックフレームを作成して，bx命令でHandlerモードからリ
+	 *  ターンする．また，遅延ディスパッチする場合も，再び割り込んだタス
+	 *  クに戻る際には，svc命令で，svc_handlerを呼び出す．
+	 *  スタックフレームは，Configureation and Control Register(CCR)の
+	 *  STKALIGNが'1'の場合は，8byte境界にアラインされる．
+	 *  参考 : DDI0403B_arm_architecture_v7m_reference_manual(P.220)
+	 *  そのため，この時点のスタックは割込みや例外発生時に作成された
+	 *  スタックフレームから，8byte境界のサイズにしておくと，svc_handler
+	 *  等でスタックフレームのアライメントの有無の確認を省略できる．
+	 *  ただし，システム起動後は，動的にCCRのSTKALIGNの設定を変更するのは
+	 *  禁止とする．
+	 *  この時点は標準のスタックフレームは，割込み・例外発生時と同等であ
+	 *  るため，タスクスタック(PSP)は8byte境界になっている．
+	 */
+	mov   r1, #0                   /* reqflgをfalseに */
+	str   r1, [r0]
+
+	/*
+	 *  CPUロック状態に移行する．
+	 *
+	 *  カーネルの管理内の割込みを禁止するようにbasepriを設定し，
+	 *  lock_flag と saved_iipm を更新する．saved_iipmは，戻り先の割込み
+	 *  優先度マスク（の内部表現）に設定する．
+	 *  この時点でCPUロック状態とするのは，dispatcherへ分岐する時と，
+	 *  call_texrtnを呼び出す時に，CPUロック状態になっている必要がある
+	 *  ためである．
+	 *  なお，この処理の後，Threadモードへの移行処理を行なうため，割込み
+	 *  ロック状態(FAULTMASKを"1")は保持する．
+	 */
+	ldr   r1, =IIPM_LOCK          /* CPUロック状態 */ 
+	msr   basepri, r1          
+	mov   r1, #0x01               /* lock_flag を trueに */
+	ldr   r0, =lock_flag          
+	str   r1, [r0]
+
+	/*
+	 *  割込み優先度マスクを，全解除状態（TIPM_ENAALL）に設定する
+	 *  すでにCPUロック状態なので，saved_iipmをIIPM_ENAALLとする．
+	 */
+	ldr   r1, =IIPM_ENAALL
+	ldr   r0, =saved_iipm
+	str   r1, [r0]
+
+	/*
+	 *  Threadモードへ移行する．
+	 *
+	 *  dispatcherやcall_texrnを呼び出す場合は，Threadモードである必
+	 *  要があるため，PSPスタック上にダミーの例外フレームを置いて，
+	 *  擬似的に割込みハンドラからリターンする．
+	 *  リターンと同時にFAULTMASKが自動的にクリアされ，カーネル管理外の
+	 *  割込みが許可される．
+	 */
+	ldr   r0, =ret_int_4          /* PC   */
+	ldr   r1, =EPSR_T             /* xPSR(Tビットが'1'である必要がある) */
+	mrs   r2, psp
+	stmfd r2!, {r0-r1}            /* ダミーフレームをスタック上に積む   */
+	subs  r2, #(EXC_FRAME_SIZE - (4*2)) /* r0-r3,r12,lrの内容は設定する必要がない */
+	msr   psp,r2       
+	/* Basicフレーム，THREADモード，PSPのための EXC_RETURN */
+	mov   r0, #(EXC_RETURN_TREAD_PSP|EXC_RETURN_OTHER|EXC_RETURN_FP_NONUSED)
+	bx    r0                      /* Threadモードへ移行 */
+    
+ALABEL(ret_int_4)
+	/*
+	 *  上記の処理により，Threadモードで実行される．
+	 *  dspflgがfalseである場合と，p_runtskとp_schedtskが同じ場合には，
+	 *  ディスパッチを行わない．このチェックが必要なのは，タスク例外処
+	 *  理ルーチンの呼出しが必要な場合に，ディスパッチが必要なくても，
+	 *  reqflgをtrueにするためである．
+	 */
+	ldr   r0, =p_runtsk       /* ディスパッチを行わない場合でも，r1にp_runtsk の値(TCB) */
+	ldr   r1, [r0]            /* が入っている必要があるので，先に読み込む */
+	ldr   r0, =dspflg         
+	ldr   r2, [r0]
+	cbz   r2, ret_int_r_1     /* dspflgがfalseならret_int_r_1へ */
+	ldr   r0, =p_schedtsk     
+	ldr   r2, [r0]
+	cmp   r1, r2              /* p_runtskとp_schedtskが同じなら */
+	beq   ret_int_r_1         /*                  ret_int_r_1へ */
+#ifdef TOPPERS_FPU_CONTEXT
+	ldr  r3, [sp,4]          /*  ディスパッチ元のEXC_RETURNを取得 */ 
+	/* 
+	 * ディスパッチ元のタスクFPUを使用した場合はFPUレジスタを保存
+	 */ 
+	tst   r3, #EXC_RETURN_FP
+	bne   ret_int_5         /* EXC_RETURN[4] == 1(FPU未使用)ならばスキップ */ 
+	vpush {s16-s31}         /* FPUレジスタの保存 */ 
+ALABEL(ret_int_5) 
+	push {r3}               /*  戻り先のEXC_RETURNを保存 */ 
+#endif /* TOPPERS_FPU_CONTEXT */ 
+	stmfd sp!, {r4-r11}       /* 残りのレジスタを保存 */
+	str   sp, [r1,#TCB_sp]    /* タスクスタックを保存 */
+	ldr   lr, =ret_int_r      /* 実行再開番地を保存   */
+	str   lr, [r1,#TCB_pc]
+	b     dispatcher          /* ディスパッチャへ */
+
+/*
+ * 割込みによりプリエンプトされたタスクへのリターン処理
+ *
+ * Threadモードで，ディスパッチャや割込みの出口処理から呼び出される．
+ * 割込みによりプリエンプトされたタスクへリターンするには，いったん
+ * Handlerモードに移行し，PCに0xfffffffdを代入してリターンする必要
+ * がある．そのため，SVCにより，SVCハンドラを呼び出し，Handlerモー
+ * ドへ移行する．
+ */
+	ATHUMB(ret_int_r)
+	AGLOBAL(ret_int_r)
+ALABEL(ret_int_r)
+	pop {r4-r11}                  /* レジスタの復帰 */
+#ifdef TOPPERS_FPU_CONTEXT 
+	pop {r3}     /*  戻り先のEXC_RETURNを取得 */ 
+	/* 
+	 * ディスパッチ元のタスクFPUを使用した場合はFPUレジスタを復帰
+	 */ 
+	tst r3, #EXC_RETURN_FP
+	bne ret_int_r_1      /* EXC_RETURN[4] == 1(FPU未使用)ならばスキップ */ 
+	vpop {s16-s31}       /* FPUレジスタの復帰 */ 
+#endif /* TOPPERS_FPU_CONTEXT */ 
+ALABEL(ret_int_r_1)
+	/*
+	 *  enatexがtrueで，texptnが0でなければ，タスク例外処理ルーチンを
+	 *  呼び出す．
+	 *  dispatcherから呼び出されるため，TCBのアドレスはr1に入っている
+	 */
+	ldrb  r0, [r1,#TCB_enatex]
+	tst   r0, #TCB_enatex_mask
+	beq   ret_int_r_2           /* enatex が false なら ret_int_r_2へ */
+	ldr   r0, [r1,#TCB_texptn]  /* texptn が 0 ならリターン     */
+	cbz   r0, ret_int_r_2
+	ldr   r1, =ipmflg           /* ipmflgが false ならリターン  */
+	ldr   r0, [r1]
+	cbz   r0, ret_int_r_2
+#ifdef TOPPERS_FPU_LAZYSTACKING
+	/*  
+	 *  Lazy Stacking かつ 割込みの出口処理からの分岐で来た場合は
+	 *  ここでFPU命令を実行して例外フレームにFPUのコンテキストを書き戻す必要がある
+	 *  他の状況では必要ないが，判断が困難なため一律実行する．
+	 */
+	vmov r3, s15
+#endif /* TOPPERS_FPU_LAZYSTACKING */ 
+	bl    call_texrtn           /* タスク例外ルーチンの呼び出し */
+ALABEL(ret_int_r_2)
+#ifdef TOPPERS_FPU_CONTEXT
+	/*
+	 *  SVCの実行でFPUコンテキストをスタックに積まないように
+	 *  CONTROL.FPCAをクリア
+	 */
+	mrs   r3, control       
+	bic   r3, r3, #CONTROL_FPCA
+	msr   control, r3
+#endif /* TOPPERS_FPU_CONTEXT */
+	svc   0                     /* SVCの呼び出し */
+
+/*
+ *  SVCハンドラ
+ */
+	ATHUMB(svc_handler)
+	AGLOBAL(svc_handler)
+ALABEL(svc_handler)
+	/*
+	 *  割込み処理からのリターンにより，CPUロック解除状態に移行するよ
+	 *  う準備する．
+	 */
+	cpsid f                       /* 割込みロック状態へ */
+	mrs   r0, psp
+	adds  r0, #EXC_FRAME_SIZE     /* スタックを捨てる   */
+	ldmfd r0!,{r1,lr}             /* EXC_RETURNは，FPU使用時・未使用時で異なるためスタックから取得 */
+	msr   psp, r0
+	mov   r0, #0
+	ldr   r1, =lock_flag          /* CPUロック解除状態へ */
+	str   r0, [r1]
+	ldr   r1, =IIPM_ENAALL        /* 割込み優先度マスクを全解除状態に設定 */
+	msr   basepri, r1             
+	bx    lr                      /* リターン     */
+
+/*
+ *  ディスパッチャの動作開始
+ */
+	ATHUMB(start_dispatch)
+	AGLOBAL(start_dispatch)
+ALABEL(start_dispatch)
+	/*
+	 *  このルーチンは，カーネル起動時に，すべての割込みを禁止した状態
+	 * （割込みロック状態と同等）で呼び出される．また，割込みモード（非
+	 *  タスクコンテキストと同等）で呼び出されることを想定している．
+	 *
+	 *  core_initializeで，lock_flagをtrueに，saved_iipmをIIPM_ENAALLに
+	 *  初期化しているため，カーネル管理外の割込みを許可することで，
+	 *  CPUロック状態・（モデル上の）割込み優先度マスク全解除状態になる．
+	 *  また，task_initializeでdisdspをfalseに初期化しているため，ディ
+	 *  スパッチ許可状態になっている．
+	 */
+	ldr   r0,=istkpt              /* MSPを初期化   */
+	ldr   r1,[r0]                 /* start_dispatch呼び出し時に呼び出し用に */
+	msr   msp, r1                 /* 使用しているため初期化する             */
+	ldr   r1, =IIPM_LOCK          /* カーネル管理内の割込みを禁止 */
+	msr   basepri, r1 
+	cpsie f                       /* カーネル管理外の割込みを許可 */
+	mov   r0, #CONTROL_PSP        /* PSPを有効に  */
+	msr   control, r0
+	isb                           /* control の操作後に必要 */
+
+/*
+ *  現在のコンテキストを捨ててディスパッチ
+ */
+	ATHUMB(exit_and_dispatch)
+	AGLOBAL(exit_and_dispatch)
+ALABEL(exit_and_dispatch)
+	/* ディスパッチャ本体（dispatcher）へ */ 
+
+/*
+ *  ディスパッチャ本体
+ */
+ALABEL(dispatcher)
+	/*
+	 *  このルーチンは，タスクコンテキスト・CPUロック状態・ディスパッチ
+	 *  許可状態・（モデル上の）割込み優先度マスク全解除状態で呼び出さ
+	 *  れる．
+	 *
+	 *  すなわち，Threadモード・lock_flagがtrue・disdspがfalse・dspflg
+	 *  がtrue・saved_iipmがIIPM_ENAALLとなっている．実行再開番地へもこ
+	 *  の状態のまま分岐する．
+	 */
+#ifdef TOPPERS_FPU_CONTEXT
+	mrs   r3, control       /* ディスパッチャ実行時はFPCAを一律クリアする */
+	bic   r3, r3, #CONTROL_FPCA
+	msr   control, r3
+#endif /* TOPPERS_FPU_CONTEXT */
+#ifdef LOG_DSP_ENTER
+	ldr   r1, =p_runtsk     /* p_runtskをパラメータに */
+	ldr   r0, [r1]        
+	bl    log_dsp_enter
+#endif /* LOG_DSP_ENTER */
+ALABEL(dispatcher_0)
+	ldr   r0, =p_schedtsk   /* p_schedtskをp_runtskに */
+	ldr   r1, [r0]
+	ldr   r2, =p_runtsk   
+	str   r1, [r2]        
+	cbz   r1, dispatcher_1  /* p_runtskがNULLならdispatcher_1へ */           
+	ldr   sp, [r1,#TCB_sp]  /* タスクスタックを復帰 */
+#ifdef LOG_DSP_LEAVE
+	mov   r0, r1            /* p_runtskをパラメータに */
+	mov   r4, r1            /* r1はスクラッチレジスタなので保存 */
+	bl    log_dsp_leave
+	mov   r1, r4
+#endif /* LOG_DSP_LEAVE */
+	ldr   pc, [r1,#TCB_pc]  /* 実行再開番地を復帰   */    
+ALABEL(dispatcher_1)
+	/*
+	 * CPUロック状態の解除と，非タスクコンテキスト実行状態への
+	 * 準備をする
+	 */
+	mov   r0, #CONTROL_MSP  /* MSPを有効に  */
+	msr   control, r0       
+	isb                     /* control の操作後に必要 */
+	mov   r4, #0            /* r4 <- '0' */
+	ldr   r5, =IIPM_LOCK    /* r5 <- 割込みロック状態の割込み優先度マスクの値 */
+	ldr   r6, =reqflg       /* r6 <- reqflg */
+	ldr   r7, =lock_flag    /* r7 <- lock_flg */
+	str   r4, [r7]          /* CPUロック解除状態へ */
+ALABEL(dispatcher_2)
+	/*
+	 *  割込みを許可し，非タスクコンテキスト実行状態とし割込みを待つ．
+	 *
+	 *  ここで非タスクコンテキスト実行状態に切り換えるのは，ここで発生
+	 *  する割込み処理にどのスタックを使うかという問題の解決と，割込み
+	 *  ハンドラ内でのタスクディスパッチの防止という2つの意味がある．
+	 *
+	 *  プロセッサを割込み待ちに移行させる処理と，割込み許可とは，不可
+	 *  分に行なう必要がある．
+	 *  これを不可分に行なわない場合，割込みを許可した直後に割込
+	 *  みが入り，その中でタスクが実行可能状態になると，実行すべきタス
+	 *  クがあるにもかかわらずプロセッサが割込み待ちになってしまう．
+	 *  ARM-Mでは，PRIMASKをセットした状態でWFIを呼び出すことで実現できる．
+	 *  この状態で割込みが入ると，割込みは実行されず，WFIからリターンす
+	 *  ることになるので，一旦割込みを許可して割込みハンドラを実行する．
+	 *
+	 *  割込み待ちの間は，p_runtskをNULL（＝0）に設定しなければならな
+	 *  い．このように設定しないと，割込みハンドラからiget_tidを呼び出
+	 *  した際の動作が仕様に合致しなくなる．
+	 *
+	 *  ターゲットによっては，省電力モード等に移行するため，標準の方法と
+	 *  異なる手順が必要な場合がある．
+	 *  そのようなターゲットでは，ターゲット依存において，TOPPERS_CUSTOM_IDLE
+	 *  を定義し，アセンブラマクロとして，toppers_asm_custom_idle を用意
+	 *  すればよい．
+	 *
+	 *  なお，toppers_asm_custom_idle の記述にあたっては，次のレジスタは
+	 *  toppers_asm_custom_idleの前後で使用するため，
+	 *  toppers_asm_custom_idle 内で使用する場合は，前後で保存復帰すること．
+	 *  これらのレジスタは Calee saved レジスタであるため， 
+	 *  toppers_asm_custom_idle として関数呼び出しをした場合は，呼び出した
+	 *  関数で自動的に保存復帰されるため，アセンブラレベルでの保存復帰は必
+	 *  要ない．
+	 *
+	 *  レジスタ : 内容
+	 *   r4      : '0'
+	 *   r5      : 'IIPM_LOCK'
+	 *   r6      : reqflgのアドレス
+	 *   r7      : lock_flgのアドレス
+	 *   sp      : 非タスクコンテキスト用のスタックの先頭アドレス(msp)
+	 */
+#ifdef TOPPERS_CUSTOM_IDLE
+	toppers_asm_custom_idle
+#else
+	cpsid i               /* PRIMASK をセット */
+	msr   basepri, r4     /* 全割込み許可 */ 
+	wfi
+	cpsie i               /* PRIMASK をクリア（割込みを受け付ける） */
+	msr   basepri, r5     /* CPUロック状態へ */ 
+#endif /* TOPPERS_CUSTOM_IDLE */
+
+	ldr   r0, [r6]        /* reqflgがfalseならdispatcher_2へ */
+	cmp   r0, #0
+	beq   dispatcher_2
+	str   r4, [r6]        /* reqflgをfalseに */
+
+	/*
+	 *  CPUロック状態に戻す．割込み待ちの間に実行した割込みハンドラによ
+	 *  り，saved_iipmが書き換えられる可能性があるため，元の値に戻す必
+	 *  要がある．dispatcherが実行される時は，saved_iipmがIIPM_ENAALL
+	 *  となっているため，ここではsaved_iipmをIIPM_ENAALL（＝0）に戻せ
+	 *  ばよい．
+	 */
+	mov   r0, #CONTROL_PSP  /* PSPを有効に  */ 
+	msr   control, r0      
+	isb                     /* control の操作後に必要 */
+	mov   r2, #1            /* lock_flagをtrueへ */
+	str   r2, [r7]
+	ldr   r0, =saved_iipm   /* saved_iipm を0に */
+	str   r4, [r0]
+	b     dispatcher_0
+
+
+/*
+ *  カーネルの終了処理の呼出し
+ *
+ *  スタックを非タスクコンテキスト用に切り替え．
+ *  
+ */
+	ATHUMB(call_exit_kernel)
+	AGLOBAL(call_exit_kernel)
+ALABEL(call_exit_kernel)
+	mov   r0, #CONTROL_MSP
+	msr   control, r0       /* MSPを有効に  */
+	isb                     /* control の操作後に必要 */
+	ldr   r0, =exit_kernel  /* カーネルの終了処理を呼ぶ */
+	bx    r0
+
+
+/*
+ *  タスク起動処理
+ *
+ *  dispatcherから呼び出されるため，TCBのアドレスはr1に入っている
+ *
+ */ 
+	ATHUMB(start_r)
+	AGLOBAL(start_r)
+ALABEL(start_r)
+	mov   r0, #0
+	ldr   r4, =lock_flag                    /* CPUロック解除状態へ */
+	str   r0, [r4]
+	msr   basepri, r0                       /* 割込み許可   */
+	ldr   lr, =ext_tsk                      /* 戻り番地設定 */
+	ldr   r2, [r1, #TCB_p_tinib]            /* p_runtsk->p_tinibをr2に  */
+	ldr   r0, [r2, #TINIB_exinf]            /* exinfを引数レジスタr0に  */
+	ldr   r1, [r2, #TINIB_task]             /* タスク起動番地にジャンプ */
+	bx    r1
+
+/*
+ *  微少時間待ち
+ */
+	ABALIGN(4)
+	ATEXT
+	ATHUMB(sil_dly_nse)
+	AGLOBAL(sil_dly_nse)
+ALABEL(sil_dly_nse)
+	subs  r0, r0, #SIL_DLY_TIM1
+	cmp   r0, #0
+	bgt   sil_dly_nse1
+	bx    lr
+ALABEL(sil_dly_nse1)
+	subs  r0, r0, #SIL_DLY_TIM2
+	cmp   r0, #0
+	bgt   sil_dly_nse1
+	bx    lr
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/arch/arm_m_gcc/common/core_support_v6m.S
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/arch/arm_m_gcc/common/core_support_v6m.S	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/arch/arm_m_gcc/common/core_support_v6m.S	(revision 457)
@@ -0,0 +1,860 @@
+/*
+ *  TOPPERS/ASP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Advanced Standard Profile Kernel
+ * 
+ *  Copyright (C) 2008-2015 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *  プロセッサ依存モジュール アセンブリ言語部（ARMv6-M用）
+ */
+
+#define TOPPERS_MACRO_ONLY
+#define UINT_C(val)		(val)		/* uint_t型の定数を作るマクロ */
+#define ULONG_C(val)	(val)		/* ulong_t型の定数を作るマクロ */
+#define CAST(type, val)	(val)		/* 型キャストを行うマクロ */
+
+#include "kernel_impl.h"
+#include "arm_m.h"
+#include "offset.h"
+#include "target_asm.inc"
+
+#if __TARGET_ARCH_THUMB != 3
+#error The core_support.S support ARMv6-M only.
+#endif /* __TARGET_ARCH_THUMB != 3 */
+
+/*
+ *  タスクディスパッチャ
+ */
+	ATEXT
+	ABALIGN(4)
+	ATHUMB(dispatch)
+	AGLOBAL(dispatch)
+ALABEL(dispatch)
+	/*
+	 *
+	 *  このルーチンは，タスクコンテキスト・CPUロック状態・ディパッチ許可状態
+	 *  ・（モデル上の）割込み優先度マスク全開状態で呼び出される．
+	 */
+	mov  r0, r8                  /* レジスタの保存 */
+	mov  r1, r9
+	mov  r2, r10
+	mov  r3, r11
+	push {r0-r7,lr}
+	ldr  r0, =p_runtsk           /* p_runtskを読み込む */
+	ldr  r1, [r0]
+	mov  r2, sp
+	str  r2, [r1,#TCB_sp]        /* タスクスタックを保存 */
+	ldr  r3, =dispatch_r         /* 実行再開番地を保存 */
+	str  r3, [r1,#TCB_pc]        
+	b    dispatcher
+
+	ATHUMB(dispatch_r)
+	AGLOBAL(dispatch_r)
+ALABEL(dispatch_r)
+	pop  {r0-r7}                 /* レジスタの復帰 */
+	mov  r8,  r0
+	mov  r9,  r1
+	mov  r10, r2
+	mov  r11, r3
+	/*
+	 * タスク例外処理ルーチンの起動
+	 */
+	ldr  r0, =p_runtsk           /* p_runtskを読み込む */
+	ldr  r1, [r0]
+	ldrb r0, [r1,#TCB_enatex]
+	movs r2, #TCB_enatex_mask
+	tst  r0, r2
+	beq  dispatch_r_1            /* enatex が false ならリターン */
+	ldr  r0, [r1,#TCB_texptn]    /* texptn が 0 ならリターン     */
+	tst  r0, r0
+	beq  dispatch_r_1            
+	ldr  r1, =ipmflg             /* ipmflgが false ならリターン  */
+	ldr  r0, [r1]
+	tst  r0, r0
+	beq  dispatch_r_1
+	ldr  r0, =call_texrtn        /* タスク例外ルーチンの呼び出し */
+	bx   r0
+ALABEL(dispatch_r_1)             /* タスクへのcall_textnから戻る */
+	pop  {pc}
+
+/*
+ *  CPU例外エントリ
+ *
+ *  割込みエントリと処理の内容は同等だが，ログの種類が異なるため，
+ *  分けている．
+ */
+	ABALIGN(4)
+	ATEXT
+	ATHUMB(core_exc_entry)
+	AGLOBAL(core_exc_entry)
+ALABEL(core_exc_entry)
+	/*
+	 *  例外/割込みが発生すると，発生時にアクティブなスタックにスクラ
+	 *  ッチレジスタ等が保存される．
+	 *  この内容に加えて，CPU例外ハンドラへの情報として，basepri の値と，
+	 *  EXC_RETURNの情報を加えて保存する．basepriの値は，CPU例外からの
+	 *  リターン時に割込み優先度マスクの値を元に戻すためにも用いられる．
+	 *
+	 *   -----------
+	 *  |   iipm    |
+	 *   -----------
+	 *  | EXC_RETURN|
+	 *   -----------
+	 *  |    R0     |  
+	 *   -----------
+	 *  |    R1     |
+	 *   -----------
+	 *  |    R2     |
+	 *   -----------
+	 *  |    R3     |
+	 *   -----------
+	 *  |    R12    |
+	 *   -----------
+	 *  |    LR     |
+	 *   -----------
+	 *  |    PC     |
+	 *   -----------
+	 *  |   xPSR    |
+	 *   -----------
+	 *
+	 */
+
+	/*
+	 *  カーネル管理外の例外かチェック
+	 *  カーネル内のクリティカルセクションの実行中，全割込みロック状態，
+	 *  CPUロック状態，カーネル管理外の割込みハンドラ実行中のいずれかで
+	 *  発生したCPU例外を，カーネル管理外のCPU例外と呼ぶ
+	 *  全割込みロック状態はFAULTMASKが'1'の場合
+	 *  CPUロック状態はbasepriがIIPM_LOCKかで判断する．
+	 */
+	ldr   r3, =iipm               /* 後で使用するため読み込む */
+	ldrb  r0, [r3]
+	mrs   r2, primask             /* CPUロック状態ならカーネル管理外例外処理へ */
+	cmp   r1, #1
+	beq   core_nonkernel_exc_entry
+
+	/*
+	 * スタックを変更する必要があるかチェック
+	 * EXC_RETURN（割込み時にLRに設定される値）をチェックして，例外発生時に
+	 * アクティブなスタックを特定することで多重割込みか判定する．
+	 */
+	movs  r1, #EXC_RETURN_PSP    /* 割込み元がMSPなら多重割込み */
+	mov   r2, lr
+	tst   r2, r1
+	beq   core_exc_entry_1       /* 多重割込みならcore_exc_entry_1へ */
+	mrs   r3, psp                /* 一段目の割込みの場合はPSP上に */
+	subs  r3, #(0x04*2)          /* 割込み発生時の割込み優先度マスク(r2)，EXC_RETURN(r0)の順にPSP上に積む */
+	str   r2, [r3, 0x04]
+	str   r0, [r3, 0x00]
+	msr   psp, r3
+	push  {r0, r2}               /* MSPにも割込み発生時の割込み優先度マスク(r0)とEXC_RETURN(r2)を積む */
+	mov   lr, r3                 /* 未定義の割込みが発生した場合の情報とする */
+	b     core_exc_entry_2
+ALABEL(core_exc_entry_1)         /* 多重割込みの場合 */
+	push  {r0,r2}                /* 割込み発生時の割込み優先度マスク(r0)，EXC_RETURN(r2)の順にPSP上に積む */
+	mov   lr, sp                 /* CPU例外ハンドラへの引数となる */
+
+	/*
+	 *  共通処理
+	 */
+ALABEL(core_exc_entry_2)
+	/*
+	 *  CPU例外からリターンする際に割込み優先度マスクを戻すためのデータを保存
+	 */
+	ldr  r3, =SYSTIC_CONTROL_STATUS
+	ldr  r2,[r3] 
+	ldr  r3, =NVIC_SETENA0
+	ldr  r1,[r3] 
+	push {r1,r2}
+
+	mrs   r3, ipsr               /* ハンドラアドレスを取得 */
+	ldr   r1, =_kernel_exc_tbl
+	lsls  r0, r3, #2
+	ldr   r2, [r1, r0]
+
+#ifdef LOG_EXC_ENTER
+	push  {r0,r2,r3}
+	mov   r0, r3                 /* 例外番号をパラメータに  */
+	bl    log_exc_enter          /* log_exc_enterを呼び出す */
+	pop   {r0,r2,r3}
+	push  {r3}                   /* 例外番号をスタックへ    */
+#endif /* LOG_EXC_ENTER */
+
+	/*
+	 *  CPU例外ハンドラの呼び出し
+	 */
+	mov   r0, lr
+	blx   r2
+
+#ifdef LOG_EXC_ENTER
+	pop   {r0}                   /* 例外番号を引数に        */
+	bl    log_exc_leave          /* log_exc_leaveを呼び出す */
+#endif /* LOG_EXC_ENTER */
+
+	b     ret_exc
+
+/*
+ *  カーネル管理外のCPU例外の出入口処理
+ */
+ALABEL(core_nonkernel_exc_entry)
+	movs  r1, #EXC_RETURN_PSP    /* 割込み元がMSPなら多重割込み */
+	mov   r2, lr
+	tst   r2, r1
+	beq   core_nonkernel_exc_entry_1  /* 多重割込みなら */
+	mrs   r3, psp                /* 一段目の割込みの場合はPSP上に */
+	subs  r3, #(0x04*2)
+	str   r2, [r3, 0x04]
+	str   r0, [r3, 0x00]
+	msr   psp, r3                
+	push  {r0, r2}               /* MSPにも割込み発生時の割込み優先度マスク(r0)とEXC_RETURN(r2)を積む */
+	mov   r0,  r3                /* CPU例外ハンドラへの引数となる */
+	b     core_nonkernel_exc_entry_2
+ALABEL(core_nonkernel_exc_entry_1) /* 多重割込みの場合 */
+	push  {r0, r2}               /* 割込み発生時の割込み優先度マスク(r0)とEXC_RETURN(r2)を積む */
+	mov   r0, sp                 /* CPU例外ハンドラへの引数となる */
+
+	/*
+	 *  共通処理
+	 */
+ALABEL(core_nonkernel_exc_entry_2)
+	/*
+	 *  割込みからリターンする際に割込み優先度マスクを戻すためのデータを保存
+	 */
+	ldr  r3, =SYSTIC_CONTROL_STATUS
+	ldr  r2,[r3] 
+	ldr  r3, =NVIC_SETENA0
+	ldr  r1,[r3] 
+	push {r1,r2}
+
+	mrs   r3, ipsr               /* CPU例外ハンドラのアドレスを取得 */
+	ldr   r1, =_kernel_exc_tbl
+	lsls  r4, r3, #2
+	ldr   r2, [r1, r4]
+
+	/*
+	 *  CPU例外ハンドラの呼び出し
+	 */
+	blx   r2
+
+	/*
+	 *  CPUロック状態の場合に呼び出されているため，CPU例外ハンドラからのリターン
+	 *  のために元に戻す
+	 */
+	cpsid i
+
+	/*
+	 *  割込み優先度マスクを元に戻す
+	 */
+	ldr  r1, =0xffffffff
+	ldr  r2, =NVIC_CLRENA0  /* 一旦IRQ割り込みを全て禁止 */
+	str  r1, [r2]
+	pop  {r0,r1}            /* スタックから例外発生時のNVIC_SETENA0(r0),SYSTIC_CONTROL_STATUS(r1)の値を取得 */
+	ldr  r2, =NVIC_SETENA0  /* NVIC_SETENA0を元に戻す */
+	str  r0, [r2]
+	ldr  r3, =SYSTIC_CONTROL_STATUS  /* SYSTIC_CONTROL_STATUSを元に戻す */
+	ldr  r0,[r3] 
+	movs r2, #SYSTIC_TICINT
+	orrs r1, r1, r2
+	bics r0, r2
+	orrs r0, r1
+	str  r0, [r3]
+	pop  {r0}               /* iipmを戻す */
+	ldr  r1, =iipm
+	strb r0, [r1]
+
+	/*
+	 *  戻り先のコンテキストの判定
+	 * 
+	 *  割込みハンドラ実行にLRにセットされるEXC_RETURNをチェックして，戻り
+	 *  先でMSPが使われていれば，割込み先が非タスクコンテキストと判定する．
+	 */
+	pop   {r3}                   /* lrをスタックから取得        */
+	movs  r1, #EXC_RETURN_PSP    /* 割込み元がMSPなら多重割込み */
+	tst   r3, r1
+	bne   core_nonkernel_ret_exc_1
+	b     core_nonkernel_ret_exc_2 /* の値をMSPから取得 */
+ALABEL(core_nonkernel_ret_exc_1)
+	/*
+	 *  PSP上からEXC_RETURN/元の割込み優先度マスク(iipm)を削除
+	 */
+	mrs   r2, psp
+	adds  r2, r2, #8
+	msr   psp, r2
+
+ALABEL(core_nonkernel_ret_exc_2)
+	bx    r3                      /* リターン */
+
+/*
+ *  割込みエントリ
+ */
+	ATHUMB(core_int_entry)
+	AGLOBAL(core_int_entry)
+ALABEL(core_int_entry)
+	/*
+	 *  割込み発生時の割込み優先度マスクをスタックに保存するため取得
+	 */
+	ldr   r3, =iipm               /* 後で使用するため読み込む */
+	ldrb  r0, [r3]
+
+	/*
+	 * 多重割込みかチェック
+	 * EXC_RETURN（割込み時にLRに設定される値）をチェックして，例外発生時に
+	 * アクティブなスタックを特定することで多重割込みか判定する．
+	 */
+	movs  r1, #EXC_RETURN_PSP    /* 割込み元がMSPなら多重割込み */
+	mov   r2, lr
+	tst   r2, r1
+	beq   core_int_entry_1       /* 多重割込みならcore_int_entry_1へ */
+	mrs   r3, psp                /* 一段目の割込みの場合はPSP上に */
+	subs  r3, #(0x04*2)
+	str   r2, [r3, 0x04]
+	str   r0, [r3, 0x00]
+	msr   psp, r3
+	push  {r0, r2}               /* MSPにも割込み発生時の割込み優先度マスク(r0)とEXC_RETURN(r2)を積む */
+	mov   lr, r3                 /* 未定義の割込みが発生した場合の情報とする */
+	b     core_int_entry_2
+ALABEL(core_int_entry_1)         /* 多重割込みの場合 */
+	push  {r0, r2}               /* 割込み発生時の割込み優先度マスク(r0)とEXC_RETURN(r2)を積む */
+	mov   lr, sp                 /* 未定義の割込みが発生した場合の情報とする */
+
+	/*
+	 *  共通処理
+	 */
+ALABEL(core_int_entry_2)
+	/*
+	 *  割込みからリターンする際に割込み優先度マスクを戻すためのデータを保存
+	 */
+	ldr  r3, =SYSTIC_CONTROL_STATUS
+	ldr  r2,[r3] 
+	ldr  r3, =NVIC_SETENA0
+	ldr  r1,[r3] 
+	push {r1,r2}
+
+	mrs   r3, ipsr   /* 割込み要因番号の取得 */
+
+	/*
+	 *  basepriの設定
+	 *  NVIC優先度マスクが自動的に設定されるため優先度マスクの点では必要な
+	 *  いが，x_get_ipm()がbasepriを参照するため，basepriも更新する．
+	 */
+	ldr   r1, =_kernel_int_iipm_tbl
+	ldrb  r2, [r1, r3]
+	ldr   r0, =iipm
+	strb  r2, [r0]
+
+	ldr   r1, =_kernel_exc_tbl   /* ハンドラアドレスを取得 */
+	lsls  r0, r3, #2
+	ldr   r2, [r1, r0]
+
+#ifdef LOG_INH_ENTER
+	push  {r0,r2,r3}
+	mov   r0, r3                 /* 例外番号をパラメータに  */
+	bl    log_inh_enter          /* log_exc_enterを呼び出す */
+	pop   {r0,r2,r3}
+#endif /* LOG_EXC_ENTER */
+
+#ifdef LOG_INH_LEAVE
+	mrs   r3, ipsr               /* 割込み要因番号の取得 */
+	push  { r3 }                 /* 割込み番号をスタックへ    */
+#endif /* LOG_INT_LEAVE */
+
+	/*
+	 *  割込みハンドラの呼び出し
+	 */
+	mov   r0, lr
+	blx   r2
+
+#ifdef LOG_INH_LEAVE
+	pop   {r0}                   /* 例外番号を引数に        */
+	bl    log_exc_leave          /* log_exc_leaveを呼び出す */
+#endif /* LOG_INH_LEAVE */
+
+
+/*
+ *  割込み/例外出口
+ *
+ *  ret_exc/ret_intは，CPU例外/割込みハンドラから戻った直後に実行する
+ *  ルーチンである．
+ */
+ALABEL(ret_exc)
+ALABEL(ret_int)
+	/*
+	 *  割込みロック状態とする．この時点では，CPUロック状態にはならない
+	 * （basepriとlock_flagとsaved_iipmは更新しない）．
+	 *
+	 *  割込みロック状態とするのは，戻り先のコンテキストのチェックと，
+	 *  戻り先が非タスクコンテキストであった場合のリターンをアトミック
+	 *  に行うためである．bsepriをCPUロックの値にすることでもアトミッ
+	 *  クなチェックと復帰は可能であるが，割込みからリターンしても，
+	 *  basepri の設定内容は元に戻らないため，使用することができない． 
+	 *  一方，FAULTMASKは，割込みからのリターン処理によって，'0'にクリ
+	 *  アされる．
+	 */
+	cpsid i
+
+	/*
+	 *  割込み優先度マスクを元に戻す
+	 */
+	ldr  r1, =0xffffffff
+	ldr  r2, =NVIC_CLRENA0  /* 一旦IRQ割り込みを全て禁止 */
+	str  r1, [r2]
+	pop  {r0,r1}            /* スタックから例外/割込み発生時のNVIC_SETENA0(r0),SYSTIC_CONTROL_STATUS(r1)の値を取得 */
+	ldr  r2, =NVIC_SETENA0  /* NVIC_SETENA0を元に戻す */
+	str  r0, [r2]
+	ldr  r3, =SYSTIC_CONTROL_STATUS  /* SYSTIC_CONTROL_STATUSを元に戻す */
+	ldr  r0,[r3] 
+	movs r2, #SYSTIC_TICINT
+	orrs r1, r1, r2
+	bics r0, r2
+	orrs r0, r1
+	str  r0, [r3]
+	pop  {r0}               /* iipmを戻す */
+	ldr  r1, =iipm
+	strb r0, [r1]
+
+	/*
+	 *  戻り先のコンテキストの判定
+	 * 
+	 *  割込みハンドラ実行にLRにセットされるEXC_RETURNをチェックして，戻り
+	 *  先でMSPが使われていれば，割込み先が非タスクコンテキストと判定する．
+	 */
+	pop   {r3}                     /* lrをスタックから取得         */
+	movs  r1, #EXC_RETURN_PSP      /* 戻り先がPSPなら ret_int_1 へ */
+	tst   r3, r1
+	bne   ret_int_1
+	b     ret_int_2
+
+	/*
+	 *  一段目の割込みの出口処理
+	 */
+ALABEL(ret_int_1)
+	/*
+	 *  PSP上から，EXC_RETURN(r0)と元の割込み優先度マスク(basepri)(r1)
+	 *  を取得
+	 */
+	mrs   r2, psp
+	adds  r2, r2, #(0x04*2)  
+	msr   psp, r2
+
+	/*
+	 *  reqflgをチェックする
+	 * 
+	 *  カーネル管理内の割込みは禁止した状態で実行する必要があるため，
+	 *  FAULTMASKを'1'にした状態で実行する．
+	 *  reqflgをチェックする前に割込みを禁止するのは，reqflgをチェック
+	 *  した直後に割込みハンドラが起動され，その中でディスパッチが要求
+	 *  された場合に，すぐにディスパッチされないという問題が生じるため
+	 *  である．
+	 */
+	ldr   r0, =reqflg             /* reqflgがfalseならそのまま戻る */
+	ldr   r2, [r0]
+	cmp   r2, #1                  /* trueならret_int_3へ           */
+	beq   ret_int_3
+
+ALABEL(ret_int_2)
+	/*
+	 *  ここには割込みロック状態（FAULTMASKがセット）された状態で来る．
+	 *  Threadモードからのリターンにより自動的に割込みロック解除状態になる．
+	 *  割込み優先度マスクは割込み前に状態に戻す．
+	 */ 
+	cpsie i                       /* 割込みのリターンでクリアされないためクリア */
+	bx    r3                      /* リターン */
+
+ALABEL(ret_int_3)
+	/*
+	 *  ここでは，戻り先がタスクであり，PSP上にスクラッチレジスタと割
+	 *  込み優先度マスク(basepri)が保存された状態になっている．また，
+	 *  プロセッサは，Handlerモード・割込みロック状態となっている．
+	 *  また，r0には，reqflgのアドレス，r3には割込み受付時のlrの値が保
+	 *  持されている．
+	 */
+	/*
+	 *  タスク例外ハンドラやディスパッチをする際にThreadモードへ遷移する
+	 *  ダミーのスタックフレームを作成して，bx命令でHandlerモードからリ
+	 *  ターンする．また，遅延ディスパッチする場合も，再び割り込んだタス
+	 *  クに戻る際には，svc命令で，svc_handlerを呼び出す．
+	 *  スタックフレームは，Configureation and Control Register(CCR)の
+	 *  STKALIGNが'1'の場合は，8byte境界にアラインされる．
+	 *  参考 : DDI0403B_arm_architecture_v7m_reference_manual(P.220)
+	 *  そのため，この時点のスタックは割込みや例外発生時に作成された
+	 *  スタックフレームから，8byte境界のサイズにしておくと，svc_handler
+	 *  等でスタックフレームのアライメントの有無の確認を省略できる．
+	 *  ただし，システム起動後は，動的にCCRのSTKALIGNの設定を変更するのは
+	 *  禁止とする．
+	 *  この時点は標準のスタックフレームは，割込み・例外発生時と同等であ
+	 *  るため，タスクスタック(PSP)は8byte境界になっている．
+	 */
+	movs  r1, #0                   /* reqflgをfalseに */
+	str   r1, [r0]
+
+	/*
+	 *  CPUロック状態に移行する．
+	 *
+	 *  カーネルの管理内の割込みを禁止するようにbasepriを設定し，
+	 *  lock_flag と saved_iipm を更新する．saved_iipmは，戻り先の割込み
+	 *  優先度マスク（の内部表現）に設定する．
+	 *  この時点でCPUロック状態とするのは，dispatcherへ分岐する時と，
+	 *  call_texrtnを呼び出す時に，CPUロック状態になっている必要がある
+	 *  ためである．
+	 *  なお，この処理の後，Threadモードへの移行処理を行なうため，割込み
+	 *  ロック状態(FAULTMASKを"1")は保持する．
+	 */
+
+	/*
+	 *  割込み優先度マスクを，全解除状態（TIPM_ENAALL）に設定する
+	 *  すでにCPUロック状態なので，saved_iipmをIIPM_ENAALLとする．
+	 */
+
+	/*
+	 *  Threadモードへ移行する．
+	 *
+	 *  dispatcherやcall_texrnを呼び出す場合は，Threadモードである必
+	 *  要があるため，PSPスタック上にダミーの例外フレームを置いて，
+	 *  擬似的に割込みハンドラからリターンする．
+	 *  リターンと同時にFAULTMASKが自動的にクリアされ，カーネル管理外の
+	 *  割込みが許可される．
+	 */
+	ldr   r0, =ret_int_4          /* PC   */
+	ldr   r1, =EPSR_T             /* xPSR(Tビットが'1'である必要がある) */
+	mrs   r2, psp
+	subs  r2, #(0x04*2)
+	str   r1, [r2, 0x04]
+	str   r0, [r2, 0x00]
+	subs  r2, #(EXC_FRAME_SIZE - (4*2)) /* r0-r3,r12,lrの内容は設定する必要がない */
+	msr   psp,r2                  
+	bx    r3                      /* Threadモードへ移行 */
+    
+ALABEL(ret_int_4)
+	/*
+	 *  上記の処理により，Threadモードで実行される．
+	 *  dspflgがfalseである場合と，p_runtskとp_schedtskが同じ場合には，
+	 *  ディスパッチを行わない．このチェックが必要なのは，タスク例外処
+	 *  理ルーチンの呼出しが必要な場合に，ディスパッチが必要なくても，
+	 *  reqflgをtrueにするためである．
+	 */
+	ldr   r0, =p_runtsk       /* ディスパッチを行わない場合でも，r1にp_runtsk の値(TCB) */
+	ldr   r1, [r0]            /* が入っている必要があるので，先に読み込む */
+	ldr   r0, =dspflg         
+	ldr   r2, [r0]
+	cmp   r2, #0x01           /* dspflgがfalseならret_int_r_1へ */
+	bne   ret_int_r_1     
+	ldr   r0, =p_schedtsk     
+	ldr   r2, [r0]
+	cmp   r1, r2              /* p_runtskとp_schedtskが同じなら */
+	beq   ret_int_r_1         /*                  ret_int_r_1へ */
+	mov  r0, r8
+	mov  r1, r9
+	mov  r2, r10
+	mov  r3, r11
+	push {r0-r7}
+	ldr   r2, =p_runtsk
+	ldr   r1, [r2]
+	mov   r0, sp
+	str   r0, [r1,#TCB_sp]    /* タスクスタックを保存 */
+	ldr   r2, =ret_int_r      /* 実行再開番地を保存   */
+	str   r2, [r1,#TCB_pc]
+	b     dispatcher          /* ディスパッチャへ */
+
+/*
+ * 割込みによりプリエンプトされたタスクへのリターン処理
+ *
+ * Threadモードで，ディスパッチャや割込みの出口処理から呼び出される．
+ * 割込みによりプリエンプトされたタスクへリターンするには，いったん
+ * Handlerモードに移行し，PCに0xfffffffdを代入してリターンする必要
+ * がある．そのため，SVCにより，SVCハンドラを呼び出し，Handlerモー
+ * ドへ移行する．
+ */
+	ATHUMB(ret_int_r)
+	AGLOBAL(ret_int_r)
+ALABEL(ret_int_r)
+	pop  {r0-r7}
+	mov  r8,  r0
+	mov  r9,  r1
+	mov  r10, r2
+	mov  r11, r3
+ALABEL(ret_int_r_1)
+	/*
+	 *  enatexがtrueで，texptnが0でなければ，タスク例外処理ルーチンを
+	 *  呼び出す．
+	 *  dispatcherから呼び出されるため，TCBのアドレスはr1に入っている
+	 */
+	ldr   r2, =p_runtsk
+	ldr   r1, [r2]
+	ldrb  r0, [r1,#TCB_enatex]
+	movs  r2, #TCB_enatex_mask
+	tst   r0, r2
+	beq   ret_int_r_2           /* enatex が false なら ret_int_r_2へ */
+	ldr   r0, [r1,#TCB_texptn]  /* texptn が 0 ならリターン     */
+	cmp   r0, #0x00
+	beq   ret_int_r_2
+	ldr   r1, =ipmflg             /* ipmflgが false ならリターン  */
+	ldr   r0, [r1]
+	cmp   r0, #0x00
+	beq   ret_int_r_2 
+	bl    call_texrtn           /* タスク例外ルーチンの呼び出し */
+ALABEL(ret_int_r_2)
+	ldr   r0, =NVIC_ICSR
+	ldr   r1, =NVIC_PENDSVSET
+	str   r1, [r0]
+	cpsie i                     /* PRIMASKをクリアしてPendSVCを受け付ける */                
+1:                              /* ここには来ない */
+	b  1b
+
+/*
+ *  SVCハンドラ
+ */
+	ATHUMB(svc_handler)
+	AGLOBAL(svc_handler)
+ALABEL(svc_handler)
+1:
+	b  1b
+
+/*
+ *  PendSVCハンドラ
+ */
+	ATHUMB(pendsvc_handler)
+	AGLOBAL(pendsvc_handler)
+ALABEL(pendsvc_handler)
+	/*
+	 *  割込み処理からのリターンにより，CPUロック解除状態に移行するよ
+	 *  う準備する．
+	 */
+	mrs   r0, psp
+	adds  r0, #EXC_FRAME_SIZE     /* スタックを捨てる   */
+	msr   psp, r0
+	movs  r0, #0
+	bx    lr                      /* リターン     */
+
+/*
+ *  ディスパッチャの動作開始
+ */
+	ATHUMB(start_dispatch)
+	AGLOBAL(start_dispatch)
+ALABEL(start_dispatch)
+	/*
+	 *  このルーチンは，カーネル起動時に，すべての割込みを禁止した状態
+	 * （割込みロック状態と同等）で呼び出される．また，割込みモード（非
+	 *  タスクコンテキストと同等）で呼び出されることを想定している．
+	 *
+	 *  core_initializeで，lock_flagをtrueに，saved_iipmをIIPM_ENAALLに
+	 *  初期化しているため，カーネル管理外の割込みを許可することで，
+	 *  CPUロック状態・（モデル上の）割込み優先度マスク全解除状態になる．
+	 *  また，task_initializeでdisdspをfalseに初期化しているため，ディ
+	 *  スパッチ許可状態になっている．
+	 */
+	ldr   r0,=istkpt              /* MSPを初期化   */
+	ldr   r1,[r0]                 /* start_dispatch呼び出し時に呼び出し用に */
+	msr   msp, r1                 /* 使用しているため初期化する             */
+	movs  r0, #CONTROL_PSP        /* PSPを有効に  */
+	msr   control, r0
+	isb                           /* control の操作後に必要 */
+
+/*
+ *  現在のコンテキストを捨ててディスパッチ
+ */
+	ATHUMB(exit_and_dispatch)
+	AGLOBAL(exit_and_dispatch)
+ALABEL(exit_and_dispatch)
+	/* ディスパッチャ本体（dispatcher）へ */ 
+
+
+/*
+ *  ディスパッチャ本体
+ */
+ALABEL(dispatcher)
+	/*
+	 *  このルーチンは，タスクコンテキスト・CPUロック状態・ディスパッチ
+	 *  許可状態・（モデル上の）割込み優先度マスク全解除状態で呼び出さ
+	 *  れる．
+	 *
+	 *  すなわち，Threadモード・lock_flagがtrue・disdspがfalse・dspflg
+	 *  がtrue・saved_iipmがIIPM_ENAALLとなっている．実行再開番地へもこ
+	 *  の状態のまま分岐する．
+	 */
+#ifdef LOG_DSP_ENTER
+	ldr   r1, =p_runtsk     /* p_runtskをパラメータに */
+	ldr   r0, [r1]        
+	bl    log_dsp_enter
+#endif /* LOG_DSP_ENTER */
+ALABEL(dispatcher_0)
+	ldr   r0, =p_schedtsk   /* p_schedtskをp_runtskに */
+	ldr   r1, [r0]
+	ldr   r2, =p_runtsk   
+	str   r1, [r2]        
+	cmp   r1, #0x00         /* p_runtskがNULLならdispatcher_1へ */
+	beq   dispatcher_1  
+	ldr   r2, [r1,#TCB_sp]  /* タスクスタックを復帰 */
+	mov   sp, r2
+#ifdef LOG_DSP_LEAVE
+	mov   r0, r1            /* p_runtskをパラメータに */
+	mov   r4, r1            /* r1はスクラッチレジスタなので保存 */
+	bl    log_dsp_leave
+	mov   r1, r4
+#endif /* LOG_DSP_LEAVE */
+	ldr   r2, [r1,#TCB_pc]  /* 実行再開番地を復帰   */    
+	mov   pc, r2
+ALABEL(dispatcher_1)
+	/*
+	 * CPUロック状態の解除と，非タスクコンテキスト実行状態への
+	 * 準備をする
+	 */
+	movs  r0, #CONTROL_MSP  /* MSPを有効に  */
+	msr   control, r0       
+	isb                     /* control の操作後に必要 */
+	movs  r4, #0            /* r4 <- '0' */
+	ldr   r6, =reqflg       /* r6 <- reqflg */
+ALABEL(dispatcher_2)
+	/*
+	 *  割込みを許可し，非タスクコンテキスト実行状態とし割込みを待つ．
+	 *
+	 *  ここで非タスクコンテキスト実行状態に切り換えるのは，ここで発生
+	 *  する割込み処理にどのスタックを使うかという問題の解決と，割込み
+	 *  ハンドラ内でのタスクディスパッチの防止という2つの意味がある．
+	 *
+	 *  プロセッサを割込み待ちに移行させる処理と，割込み許可とは，不可
+	 *  分に行なう必要がある．
+	 *  これを不可分に行なわない場合，割込みを許可した直後に割込
+	 *  みが入り，その中でタスクが実行可能状態になると，実行すべきタス
+	 *  クがあるにもかかわらずプロセッサが割込み待ちになってしまう．
+	 *  ARM-Mでは，PRIMASKをセットした状態でWFIを呼び出すことで実現できる．
+	 *  この状態で割込みが入ると，割込みは実行されず，WFIからリターンす
+	 *  ることになるので，一旦割込みを許可して割込みハンドラを実行する．
+	 *
+	 *  割込み待ちの間は，p_runtskをNULL（＝0）に設定しなければならな
+	 *  い．このように設定しないと，割込みハンドラからiget_tidを呼び出
+	 *  した際の動作が仕様に合致しなくなる．
+	 *
+	 *  ターゲットによっては，省電力モード等に移行するため，標準の方法と
+	 *  異なる手順が必要な場合がある．
+	 *  そのようなターゲットでは，ターゲット依存において，TOPPERS_CUSTOM_IDLE
+	 *  を定義し，アセンブラマクロとして，toppers_asm_custom_idle を用意
+	 *  すればよい．
+	 *
+	 *  なお，toppers_asm_custom_idle の記述にあたっては，次のレジスタは
+	 *  toppers_asm_custom_idleの前後で使用するため，
+	 *  toppers_asm_custom_idle 内で使用する場合は，前後で保存復帰すること．
+	 *  これらのレジスタは Calee saved レジスタであるため， 
+	 *  toppers_asm_custom_idle として関数呼び出しをした場合は，呼び出した
+	 *  関数で自動的に保存復帰されるため，アセンブラレベルでの保存復帰は必
+	 *  要ない．
+	 *
+	 *  レジスタ : 内容
+	 *   r4      : '0'
+	 *   r5      : 'IIPM_LOCK'
+	 *   r6      : reqflgのアドレス
+	 *   r7      : lock_flgのアドレス
+	 *   sp      : 非タスクコンテキスト用のスタックの先頭アドレス(msp)
+	 */
+#ifdef TOPPERS_CUSTOM_IDLE
+	toppers_asm_custom_idle
+#else
+	wfi
+	cpsie i               /* PRIMASK をクリア（割込みを受け付ける） */
+	cpsid i               /* PRIMASK をセット */
+#endif /* TOPPERS_CUSTOM_IDLE */
+
+	ldr   r0, [r6]        /* reqflgがfalseならdispatcher_2へ */
+	cmp   r0, #0
+	beq   dispatcher_2
+	str   r4, [r6]        /* reqflgをfalseに */
+
+	/*
+	 *  CPUロック状態に戻す．割込み待ちの間に実行した割込みハンドラによ
+	 *  り，saved_iipmが書き換えられる可能性があるため，元の値に戻す必
+	 *  要がある．dispatcherが実行される時は，saved_iipmがIIPM_ENAALL
+	 *  となっているため，ここではsaved_iipmをIIPM_ENAALL（＝0）に戻せ
+	 *  ばよい．
+	 */
+	movs  r0, #CONTROL_PSP  /* PSPを有効に  */ 
+	msr   control, r0      
+	isb                     /* control の操作後に必要 */
+	b     dispatcher_0
+
+/*
+ *  カーネルの終了処理の呼出し
+ *
+ *  スタックを非タスクコンテキスト用に切り替え．
+ *  
+ */
+	ATHUMB(call_exit_kernel)
+	AGLOBAL(call_exit_kernel)
+ALABEL(call_exit_kernel)
+	movs  r0, #CONTROL_MSP
+	msr   control, r0       /* MSPを有効に  */
+	isb                     /* control の操作後に必要 */
+	ldr   r0, =exit_kernel  /* カーネルの終了処理を呼ぶ */
+	bx    r0
+
+/*
+ *  タスク起動処理
+ *
+ *  dispatcherから呼び出されるため，TCBのアドレスはr1に入っている
+ *
+ */ 
+	ATHUMB(start_r)
+	AGLOBAL(start_r)
+ALABEL(start_r)
+	movs  r0, #0
+	cpsie i                                 /* 割込み許可   */
+	ldr   r0, =ext_tsk                      /* 戻り番地設定 */
+	mov   lr, r0
+	ldr   r2, [r1, #TCB_p_tinib]            /* p_runtsk->p_tinibをr2に  */
+	ldr   r0, [r2, #TINIB_exinf]            /* exinfを引数レジスタr0に  */
+	ldr   r1, [r2, #TINIB_task]             /* タスク起動番地にジャンプ */
+	bx    r1
+
+/*
+ *  微少時間待ち
+ */
+	ABALIGN(4)
+	ATEXT
+	ATHUMB(sil_dly_nse)
+	AGLOBAL(sil_dly_nse)
+ALABEL(sil_dly_nse)
+	ldr   r1, =SIL_DLY_TIM1
+	subs  r0, r0, r1
+	cmp   r0, #0
+	bgt   sil_dly_nse1
+	bx    lr
+ALABEL(sil_dly_nse1)
+	ldr   r1, =SIL_DLY_TIM2
+ALABEL(sil_dly_nse2)
+	subs  r0, r0, r1
+	cmp   r0, #0
+	bgt   sil_dly_nse2
+	bx    lr
+
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/arch/arm_m_gcc/common/core_test.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/arch/arm_m_gcc/common/core_test.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/arch/arm_m_gcc/common/core_test.h	(revision 457)
@@ -0,0 +1,58 @@
+/*
+ *  TOPPERS/ASP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Advanced Standard Profile Kernel
+ * 
+ *  Copyright (C) 2008,2015 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *		テストプログラムのチップ依存定義（ARM-M用）
+ */
+
+#ifndef TOPPERS_CORE_TEST_H
+#define TOPPERS_CORE_TEST_H
+
+#if __TARGET_ARCH_THUMB == 4
+#define CPUEXC1				6		/* Usage Fault */
+#define RAISE_CPU_EXCEPTION Asm("mcr p15, 0, r1, c2, c0, 0");
+#define CANNOT_RETURN_CPUEXC
+#else /* __TARGET_ARCH_THUMB == 3 */
+#define CPUEXC1				3		/* Hard Fault */
+#define RAISE_CPU_EXCEPTION *(volatile int*)(0x1) = 0x11;
+#define CANNOT_RETURN_CPUEXC
+#endif /* __TARGET_ARCH_THUMB == 4 */
+
+#endif /* TOPPERS_CORE_TEST_H */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/arch/arm_m_gcc/common/core_timer.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/arch/arm_m_gcc/common/core_timer.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/arch/arm_m_gcc/common/core_timer.c	(revision 457)
@@ -0,0 +1,108 @@
+/*
+ *  TOPPERS/ASP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Advanced Standard Profile Kernel
+ * 
+ *  Copyright (C) 2008-2011 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *  タイマドライバ（SYSTIC用）
+ */
+#include <sil.h>
+#include "kernel_impl.h"
+#include "time_event.h"
+#include "target_timer.h"
+
+/*
+ *  タイマの起動処理
+ */
+void
+target_timer_initialize(intptr_t exinf)
+{
+	CLOCK    cyc;
+	uint32_t tmp;
+
+#ifdef SYSTIC_USE_CALIBRATION
+	/* CALIBRATIONレジスタの値を使用 */
+	cyc = (sil_rew_mem((void *)SYSTIC_CALIBRATION) & SYSTIC_TENMS) / 10;
+#else 
+	cyc = TO_CLOCK(TIC_NUME, TIC_DENO) - 1;
+#endif /* SYSTIC_USE_CALIBRATION */
+
+	/* 停止 */
+	tmp = sil_rew_mem((void *)SYSTIC_CONTROL_STATUS);
+	tmp &= ~SYSTIC_ENABLE;
+	sil_wrw_mem((void *)SYSTIC_CONTROL_STATUS, tmp);
+
+	sil_wrw_mem((void *)SYSTIC_RELOAD_VALUE, cyc);
+	sil_wrw_mem((void *)SYSTIC_CURRENT_VALUE, cyc);
+
+	tmp = sil_rew_mem((void *)SYSTIC_CONTROL_STATUS);
+
+#ifdef SYSTIC_USE_STCLK
+	/* 外部クロックの使用 */
+	tmp |= SYSTIC_ENABLE;
+#else
+	/* プロセッサクロックの使用 */
+	tmp |= SYSTIC_ENABLE|SYSTIC_CLKSOURCE;
+#endif /* SYSTIC_USE_STCLK */
+
+	sil_wrw_mem((void *)SYSTIC_CONTROL_STATUS, tmp);
+}
+
+/*
+ *  タイマの停止処理
+ */
+void
+target_timer_terminate(intptr_t exinf)
+{
+	/* タイマを停止 */
+	sil_wrw_mem((void*)SYSTIC_CONTROL_STATUS, 0x00);
+}
+
+/*
+ *  タイマ割込みハンドラ
+ */
+void
+target_timer_handler(void)
+{
+	/* probe_int のため，COUNTFLAGをクリア */
+	sil_rew_mem((void *)SYSTIC_CONTROL_STATUS);
+
+	i_begin_int(INTNO_TIMER);
+	signal_time();                    /* タイムティックの供給 */
+	i_end_int(INTNO_TIMER);
+}
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/arch/arm_m_gcc/common/core_timer.cfg
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/arch/arm_m_gcc/common/core_timer.cfg	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/arch/arm_m_gcc/common/core_timer.cfg	(revision 457)
@@ -0,0 +1,11 @@
+/*
+ *  @(#) $Id$
+ */
+
+/*
+ *		タイマドライバのコンフィギュレーションファイル
+ */
+ATT_INI({ TA_NULL, 0, target_timer_initialize });
+ATT_TER({ TA_NULL, 0, target_timer_terminate });
+DEF_INH(INHNO_TIMER, { TA_NULL, target_timer_handler });
+CFG_INT(INTNO_TIMER, { TA_ENAINT|INTATR_TIMER, INTPRI_TIMER });
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/arch/arm_m_gcc/common/core_timer.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/arch/arm_m_gcc/common/core_timer.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/arch/arm_m_gcc/common/core_timer.h	(revision 457)
@@ -0,0 +1,113 @@
+/*
+ *  TOPPERS/ASP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Advanced Standard Profile Kernel
+ * 
+ *  Copyright (C) 2008-2011 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *  タイマドライバ（SYSTIC用）
+ */
+
+#ifndef TOPPERS_CORE_TIMER_H
+#define TOPPERS_CORE_TIMER_H
+
+#include <sil.h>
+
+/*
+ *  タイマ割込みハンドラ登録のための定数
+ */
+#define INHNO_TIMER     IRQNO_SYSTICK /* 割込みハンドラ番号 */
+#define INTNO_TIMER     IRQNO_SYSTICK /* 割込み番号 */
+
+#ifndef TOPPERS_MACRO_ONLY
+
+/*
+ *  タイマ値の内部表現の型
+ */
+typedef uint32_t    CLOCK;
+
+/*
+ *  タイマ値の内部表現とミリ秒・μ秒単位との変換
+ *
+ */
+#define TO_CLOCK(nume, deno)    ((CLOCK)(TIMER_CLOCK * (nume) / (deno)))
+#define TO_USEC(clock)          (((SYSUTM) clock) * 1000U / TIMER_CLOCK)
+
+/*
+ *  設定できる最大のタイマ周期（単位は内部表現）
+ */
+#define MAX_CLOCK    ((CLOCK) 0x00ffffffU)
+
+/*
+ *  タイマの起動処理
+ *
+ *  タイマを初期化し，周期的なタイマ割込み要求を発生させる．
+ */
+extern void target_timer_initialize(intptr_t exinf);
+
+/*
+ *  タイマの停止処理
+ *
+ *  タイマの動作を停止させる．
+ */
+extern void target_timer_terminate(intptr_t exinf);
+
+/*
+ *  タイマの現在値の読出し
+ */
+Inline CLOCK
+target_timer_get_current(void)
+{
+	return(TO_CLOCK(TIC_NUME, TIC_DENO) - sil_rew_mem((void*)SYSTIC_CURRENT_VALUE));
+}
+
+/*
+ *  タイマ割込み要求のチェック
+ */
+Inline bool_t
+target_timer_probe_int(void)
+{
+	return((sil_rew_mem((void*)NVIC_ICSR) & NVIC_PENDSTSET) == NVIC_PENDSTSET);
+}
+
+/*
+ *  タイマ割込みハンドラ
+ */
+extern void target_timer_handler(void);
+
+#endif /* TOPPERS_MACRO_ONLY */
+#endif /* TOPPERS_CORE_TIMER_H */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/arch/arm_m_gcc/common/core_unrename.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/arch/arm_m_gcc/common/core_unrename.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/arch/arm_m_gcc/common/core_unrename.h	(revision 457)
@@ -0,0 +1,94 @@
+/* This file is generated from core_rename.def by genrename. */
+
+/* This file is included only when core_rename.h has been included. */
+#ifdef TOPPERS_CORE_RENAME_H
+#undef TOPPERS_CORE_RENAME_H
+
+/*
+ *  core_config.c
+ */
+#undef exc_tbl
+#undef vector_table
+#undef lock_flag
+#undef saved_iipm
+#undef default_exc_handler
+#undef default_int_handler
+#undef x_config_int
+#undef core_initialize
+#undef core_terminate
+#undef bitpat_cfgint
+#undef set_exc_int_priority
+#undef enable_exc
+#undef disable_exc
+#undef iipm_enable_irq_tbl
+#undef iipm_enable_systic_tbl
+#undef iipm
+#undef ief
+#undef ief_systick
+
+/*
+ *  core_support.S
+ */
+#undef core_int_entry
+#undef core_exc_entry
+#undef ret_int
+#undef ret_exc
+#undef svc_handler
+#undef start_r
+#undef dispatch
+#undef start_dispatch
+#undef exit_and_dispatch
+#undef call_exit_kernel
+
+/*
+ *  start.S
+ */
+#undef _start
+
+#ifdef TOPPERS_LABEL_ASM
+
+/*
+ *  core_config.c
+ */
+#undef _exc_tbl
+#undef _vector_table
+#undef _lock_flag
+#undef _saved_iipm
+#undef _default_exc_handler
+#undef _default_int_handler
+#undef _x_config_int
+#undef _core_initialize
+#undef _core_terminate
+#undef _bitpat_cfgint
+#undef _set_exc_int_priority
+#undef _enable_exc
+#undef _disable_exc
+#undef _iipm_enable_irq_tbl
+#undef _iipm_enable_systic_tbl
+#undef _iipm
+#undef _ief
+#undef _ief_systick
+
+/*
+ *  core_support.S
+ */
+#undef _core_int_entry
+#undef _core_exc_entry
+#undef _ret_int
+#undef _ret_exc
+#undef _svc_handler
+#undef _start_r
+#undef _dispatch
+#undef _start_dispatch
+#undef _exit_and_dispatch
+#undef _call_exit_kernel
+
+/*
+ *  start.S
+ */
+#undef __start
+
+#endif /* TOPPERS_LABEL_ASM */
+
+
+#endif /* TOPPERS_CORE_RENAME_H */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/arch/arm_m_gcc/common/core_user.txt
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/arch/arm_m_gcc/common/core_user.txt	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/arch/arm_m_gcc/common/core_user.txt	(revision 457)
@@ -0,0 +1,573 @@
+=====================================================================
+                         ARM-Mプロセッサ依存部
+                                  Last Modified:2015 Nov 23 09:31:43
+=====================================================================
+
+
+(1) 対応しているターゲットシステムの種類・構成
+
+ARM-M依存部は，ARMvx-Mアーキテクチャをターゲットとしている．ARMvx-Mは，
+ARMとは異なり，ARM命令を実行できないため，ARM依存部と分けている．現状
+サポートしているコアは次の通りである．
+
+・Cortex-M0
+・Cortex-M0+
+・Cortex-M3
+・Cortex-M4
+
+(2) 使用する開発環境と動作検証した条件（バージョン，オプション等）
+
+カーネルはGCCを用いてコンパイルする．動作確認したバージョンは各ターゲ
+ット依存部のドキュメントに記載する．
+
+
+(3) ターゲット定義事項の規定
+
+(3-1) データ型に関する規定
+
+データ型は arch/gcc/tool_stddef.h で定義されている内容で，float型と
+double型は，それぞれIEEE754準拠の単精度浮動小数点数と倍精度浮動小数点
+数である．
+
+(3-2) 割込み処理に関する規定
+
+○割込みハンドラ番号と割込み番号の割当て，両者の対応
+
+割込みハンドラ番号と割込み番号は，例外発生時にIPSRにセットされる例外番
+号を用いる．SYSTICKは15番で，外部割込みは16番からの番号が割り付けられ
+ている．
+
+○割込み優先度の段階数とTMIN_INTPRIの値
+
+割込み優先度の段階数は，SoC毎にハードウェア的にサポートする割込み優先
+度ビット幅が異なるので，ターゲット依存部毎に異なる．ターゲット依存部で
+は，割込み優先度のビット幅（TBITW_IPRI）とその割込み優先度中のサブ優先
+度のビット幅（TBITW_SUBPRI）を定義する．
+
+各ビット幅の値とCFG_INTで使用可能な割込み優先度の範囲は次の通りである．
+
+   -(2^(TBIW_IPRI)) + (2^TBITW_SUBIPRI) ～ -1
+
+例えば優先度のビット幅(TBITW_IPRI)が8bit，サブ優先度のビット幅
+(TBITW_SUBIPRI) が1bitの場合は，-254 ～ -1 の範囲である．
+
+優先度のビット幅(TBITW_IPRI)が3bit，サブ優先度のビット幅(TBITW_SUBIPRI) 
+が0bitの場合は，-8 ～ -1 の範囲である．
+
+最大優先度(3bitの例では-8)は，内部優先度としては"0x00"となる．この優先
+度はCPUロックで用いるBASEPRIレジスタではマスクできないため，カーネル管
+理内の割込みの最高優先度（TMIN_INTPRI）は，最大値より1つ優先度が低い値
+以下の値を指定する．
+
+この範囲で，カーネル管理内の割込みの最高優先度（TMIN_INTPRI）をターゲ
+ット依存部で設定する．
+
+○dis_intとena_intのサポートの有無，その制限事項
+
+dis_intとena_intをサポートする．制限事項は特にない．
+
+○CFG_INTの制限事項と拡張（ターゲット定義で使用できる割込み属性）
+
+CFG_INTの制限事項はなく，ターゲット定義で使用可能な割込み属性は特にな
+い．
+
+○カーネル管理外の割込み
+
+ARMv7-Mでは，カーネル管理外の割込みをサポートする．指定方法は，割込み
+優先度の段階数で指定した，サポートする割込み優先度の最高値（最小値）よ
+り，TMIN_INTPRIの値を大きく（優先度を低く）設定すると，TMIN_INTPRIより
+値が小い（高優先度）な割込み優先度を設定した割込みを割込み優先度として
+扱う．
+
+カーネル管理外の割込みはOS実行中も禁止になることはなく（厳密には割込み
+の出口でごく短い区間禁止される），割込み発生時は，カーネルのコードを経
+由せずに呼び出される．
+
+カーネル管理外の割込みに対する，DEF_INH,CFG_INTはサポートする．
+
+(3-3) CPU例外処理に関する規定
+
+○CPU例外ハンドラ番号
+
+CPU例外ハンドラ番号としては，例外発生時にIPSRにセットされる，例外番号
+を用いる．各例外の例外番号は以下の通りである．
+
+        例外              例外番号
+  Reset                      1
+  Non-makable Interrupt      2
+  Hard Fault                 3
+  Memory Management          4
+  Bus Fault                  5
+  Usage Fault                6
+  SVCall                    11
+  Debug Monitor             12
+  PendSV                    14
+
+なお，Resetと，SVCall(ARMv7-M)，PendSV(ARMv6-M)については，カーネルが
+使用するため，ユーザーは使用することができない．
+
+ARM-MアーキテクチャではCPU例外に優先度を設定することが可能である．
+ARM-M依存部では，全てのCPU例外の優先度をCPUロックではマスクできないマ
+スク出来ない値（内部優先度0）に初期化している．
+
+(3-4) CPUロック・割込みロック
+
+ARMv7-Mでは，CPUロックは，basepriをTMIN_INTPRIの優先度の割込みを禁止す
+る値に設定する．割込みロックは，FAULTMASKを'1'に設定することで実現してい
+る．
+
+ARMv6-Mでは，CPUロック/割込みロック共にPRIMASKにより実現している．
+
+(3-5) 性能評価用システム時刻の参照に関する規定
+
+get_utmをサポートする．精度に関しては，ターゲット毎に異なる．
+
+(3-6) スタートアップルーチンでの初期化内容
+
+スタートアップルーチンは，Threadモードで呼び出されることを前提としてい
+る．実行後，割込みロック状態とする．割込みロック状態は，カーネルの初期
+化終了時に許可する．スタートアップルーチンで，MSPをアクティブなスタッ
+クとし，MSPの内容を初期化するためには，INIT_MSPをターゲット依存部で定
+義する．
+
+(3-7) ベクタテーブルオフセットの初期化
+
+プロセッサ依存の初期化処理で，Vector Table Offset Register をターゲッ
+ト依存部の初期化ルーチンで設定する．なお，ベクターテーブルは，.vector
+のセクション属性が付加されているため，リンカスクリプトでこのセクション
+を指定して配置する．
+
+
+(4) タイマドライバ関連の情報
+
+カーネルのタイムティックとして，SYSTICを使用する場合は，core_config.c 
+をコンパイル対象とし，コンフィギュレーションファイルに core_config.cfg 
+を指定すること．
+
+周期の基本は1msecとする．周期をCALIBRATIONレジスタの設定内容を元に計算
+する場合は，SYSTIC_USE_CALIBRATION を定義する．CALIBRATIONレジスタを用
+いない場合は，1msec周期分のカウント値を TIMER_CLOCK に設定する．クロッ
+クソースとして，外部クロックを用いる場合は，SYSTIC_USE_STCLK を用いる．
+
+
+(5) ターゲット依存部での設定項目
+
+ターゲット依存部では以下のマクロを定義する必要がある．
+
+   ･TMAX_INTNO     : 割込み番号の最大値(通常の割込み番号 + 15)
+   ･TBITW_IPRI     : 割込み優先度のビット幅
+   ･TBITW_SUBIPRI  : 割込み優先度のビット幅中のサブ優先度のビット幅
+   ･TMIN_INTPRI    : 割込み優先度の最小値（最高値）
+   ･TIC_NUME       : タイムティックの周期の分子
+   ･TIC_DENO       : タイムティックの周期の分母
+   ･TIMER_CLOCK    : タイマ値の内部表現とミリ秒単位との変換
+   ･INTPRI_TIMER   : タイマ割込み割込み優先度
+   ･INTATR_TIMER   : タイマ割込みの割込み属性
+   ･INIT_MSP       : スタートアップルーチンでMSPを初期化する場合は定義
+   ･DEFAULT_ISTKSZ : スタックサイズ（8byte単位で指定）
+   ･SIL_DLY_TIM1   : 微少時間待ちのための定義
+   ･SIL_DLY_TIM2   : 微少時間待ちのための定義
+
+ターゲット依存部のMakefileでは以下を定義する必要がある．
+
+   ・CORE_TYPE     : コアの種類
+                     CORTEX_M4/CORTEX_M3/CORTEX_M0/CORTEX_M0PLUS/
+   ・FPU_USAGE     : FPUを使用する場合にいずれかに定義．
+                     FPU_NO_PRESERV      : コンテキスト保存なし
+                     FPU_NO_LAZYSTACKING : コンテキスト保存あり
+                     FPU_LAZYSTACKING    : コンテキスト保存あり(Lazy stacking)                  
+   ・FPU_ABI       : FPU使用時のABIいずれかを指定
+                     softfp : float/dobuleの引数の受け渡しに一般レジスタを使用
+                     hard   : float/dobuleの引数の受け渡しにFPUレジスタを使用
+                     
+(6) その他
+
+(6-1) Configureation and Control Register(CCR)のSTKALIGNの制限
+
+システム起動後（正確にはOSの初期化終了後）はCCRのSTKALIGNの設定は，変
+更しないこと．
+
+
+(7) ディレクトリ構成・ファイル構成
+  ./arch/arm_m_gcc/common
+    ./Makefile.core
+    ./arm_m.h
+    ./makeoffset.c
+    ./core.tf
+    ./core_cfg1_out.h
+    ./core_check.tf
+    ./core_config.c
+    ./core_config.h
+    ./core_def.csv
+    ./core_insn.h
+    ./core_kernel.h
+    ./core_rename.def
+    ./core_rename.h
+    ./core_sil.h
+    ./core_stddef.h
+    ./core_support.S
+    ./core_test.h
+    ./core_timer.c
+    ./core_timer.cfg
+    ./core_timer.h
+    ./core_unrename.h
+    ./core_user.txt
+    ./start.S
+
+(8)ARMCC共有コードの記述方法
+
+ARMCCと共有するコードは，次のルールに従ってコードを記述する必要がある．
+
+1.メモリバリア命令(Asm("":::"memory"))のマクロ化
+
+ターゲット依存部 ポーティングガイドの(1-6-2)(c)には，次のように記述さ
+れている．
+
+-----
+(c) クリティカルセクションの出入処理の本質的な部分が，マクロやインライ
+	ン関数呼出しで実現している場合には，クリティカルセクションに入る処
+	理の最後と出る処理の先頭に，Asm("":::"memory")という記述を入れる．
+-----
+
+メモリバリア命令(Asm("":::"memory"))は，ARMCCと互換性がないため，この
+記述をする箇所は，次のマクロで記述すると，コンパイル時に適切なメモリバ
+リア命令に置き換えられる．
+
+  ARM_MEMORY_CHANGED
+
+2.インクルード方法
+
+ターゲット依存部 ポーティングガイドの1.5には，次のように記述されている．
+
+-----
+その他のヘッダファイルは，「#include "..."」によりインクルードする．ヘッ
+ダファイルが，カレントディレクトリやインクルードするファイルと同じディ
+レクトリ以外のディレクトリに置かれている場合には，次のようにパス指定を
+行う．
+-----
+
+GCC依存部とARMCC依存部でヘッダファイルを共有できない場合には，それぞれ
+で同じ名前のファイルを持つ．そして，コンパイルオプションでインクルード
+すべきファイルを先に指定している．そのため，ARMCCと共有するファイルで
+これらのファイルをインクルードする場合には，「#include "..."」ではなく，
+「#include <...>」で記述し，相対パスではなくファイル名のみを記載するこ
+と．
+
+3.アセンブラディレクティブ
+
+GCCとARMCCのアセンブラディレクティブは互換性がない．そのため，ARMCCと
+共有するファイルは次に示すマクロディレクティブで記述すること．
+
+マクロディレクティブ     GCCディレクティブ
+ ASECTION(name)          .section name,"a"
+ ATEXT                   .text
+ AGLOBAL(name)           .global name
+ AALIGN(x)               .align x
+ ALONG                   .long
+ ALABEL(label)           label:
+ AOR                       |
+ ATHUMB(name)            __athumb name
+
+
+(9)アイドル処理
+
+実行するべきタスクがない場合は，ディスパッチャーで割込みを許可して，割
+込みを待つ（dispatcher_2）．ARM-M依存部のコードでは，次のようになって
+いる．
+
+    PRIMASK をセット
+    全割込み許可
+    wfi
+    PRIMASK をクリア（割込みを受け付ける）
+    CPUロック状態へ
+
+ターゲット依存で，上記の処理の代わりに，省電力モード等に移行する処理を
+記述したい場合には，ターゲット依存部で，TOPPERS_CUSTOM_IDLEを定義し，
+代わりに実行した処理を toppers_asm_custom_idle というアセンブラマクロ
+として記述する．
+
+なお，toppers_asm_custom_idle の記述にあたっては，次のレジスタは
+oppers_asm_custom_idleの前後で使用するため，oppers_asm_custom_idle 内
+で使用する場合は，前後で保存復帰すること．これらのレジスタは Calee 
+saved レジスタであるため， oppers_asm_custom_idle として関数呼び出しを
+した場合は，呼び出した関数で自動的に保存復帰されるため，アセンブラレベ
+ルでの保存復帰は必要ない．
+
+レジスタ : 内容
+r4      : '0'
+r5      : 'IIPM_LOCK'
+r6      : reqflgのアドレス
+r7      : lock_flgのアドレス
+sp      : 非タスクコンテキスト用のスタックの先頭アドレス(msp)
+
+アセンブラマクロはC言語記述中に展開するとエラーとなる．core_support.S で
+は，TOPPERS_ASM_MACRO というマクロを定義しているため，ターゲット依存部
+で toppers_asm_custom_idle アセンブラマクロを定義する際には，
+TOPPERS_ASM_MACRO を条件コンパイルの条件として用いること．
+
+(10)FPU
+Cortex-M4FのFPUをサポートしている．FPUの使用方法は次の3種類から選択可
+能である．それぞれMakefile内でFPU_USAGEマクロを定義して指定する．指定
+がない場合はFPUを無効とする．
+
+FPU_NO_PRESERV       
+ディスパッチャ等ではFPUコンテキストの保存復帰を行わない．
+FPUを使用可能なタスクは1個もしくは，システム中の最高優先度のISR群で使
+用可能．
+
+FPU_NO_LAZYSTACKING 
+ディスパッチャ等ではFPUコンテキストの保存復帰を行う．Lazy stacking は
+使用しない．全てのタスク/ISRでFPUを使用可能．
+
+FPU_LAZYSTACKING
+ディスパッチャ等ではFPUコンテキストの保存復帰を行う．Lazy stacking を
+使用する．全てのタスク/ISRでFPUを使用可能．
+
+(11)その他
+
+1. ベクターテーブルのセクション指定
+
+core.tf で以下の _kernel_vector_table の配列の変数の宣言の生成の際に，
+GEN_VECTOR_TABLE_VARNAME という関数が定義されていれば，core.tf では変
+数の宣言は行わず，GEN_VECTOR_TABLE_VARNAME を呼び出す．
+
+const FP _kernel_vector_table[] = 
+
+GEN_VECTOR_TABLE_VARNAME が宣言されている場合でも，配列の本体の生成は，
+core.tfで行う．
+
+2. ARMv6-Mでの割込みロック(SIL_LOC_INT())
+
+CPUロック・割込みロックにPRIMASKを使用しているため，CPUロック・割込み
+ロック中にHardwareFault以外の例外が発生して受け付けられなくなるという
+制約がある．
+
+(12) バージョン履歴
+2015/11/22
+・Cortex-M4FのFPUのサポートを追加．
+
+2015/11/14
+・ARMv7-M
+  ・core_sil.h
+    ・割込みロック(SIL_LOC_INT())をBASEPRIを使用するように変更．
+    ・元のFAULTMASKだとFAULTMASKをセットした状態で例外が発生すると例外
+      が発生しないため．
+
+2015/11/04
+・ARMv6-M対応に関する変更
+ ・ARMv7-Mに影響を及ぼす変更
+  ・例外フレームのフォーマットを変更(basepriとEXC_RETURNの順序を変更)
+  ・エントリポイント(_start)をリネームの対象に変更．
+    ・Cライブラリの_startと名前が重複するため．
+  ・Makefile.coreで -nostdlib を付けないように変更．
+    ・ターゲット依存部で指定する
+  
+2014/12/01
+・core_support.S
+  2013/08/20 の修正でPSP上への割込み優先度マスク(r2)とEXC_RETURN(lr)の
+  保存をstfmdで行うにしたが，スタックへの積み方がlr,r2となっているため
+  ，割込み・例外出口のコードとの整合性がとれていなかった．r2,lrと保存
+  するようにlrをr0に一旦コピーしてr0(lr),r2とstmfdに指定するよう変更．
+    
+2014/07/23
+・target_timer_probe_int()において，SYSTIC_CONTROL_STATUS を一度読み込
+  むとクリアされるため，割込み等で複数回読み込む使い方には適応しない．
+  そのため，NVICのペンディングレジスタを読み込むように変更．
+
+2012/10/17
+・1.8.0対応のため，char_t の箇所を他の型に変更．
+
+2013/08/20
+・core_support.S
+ 例外/割込み例外発生時のPSP上への割込み優先度マスク(r2)とEXC_RETURN(lr)
+ の保存をstmfd1命令で実施するように変更．
+
+2013/03/10
+・core_support.S
+  sub/addはアセンブラにより32bit命令ｎsub.w/add.wと変換される．16bit命
+  令のsubs/addsでも問題ないため，変更．
+
+2012/06/18
+・xxx_stddef.h を相対パスではなくファイル名のみで指定するように変更．
+  どのファイルを用いるかは他のファイルと同様にコンパイラへのインクルー
+  ド指定の順序とする．
+・core.tf で _kernel_vector_table の配列の変数の宣言部分を生成する際に，
+  GEN_VECTOR_TABLE_VARNAME という関数が定義されていれば，呼び出すよう
+  に変更．
+  セクション指定方法がコンパイラ毎に異なるため用意．
+    
+2012/02/29
+・Makefile.core
+  ・CDEFSにTOPPERS_LABEL_ASMを指定していたが，ARM用のgccではアセンブラ
+    のシンボルの前に_を付けないため削除．
+  
+2012/02/02
+・core_config.h
+  ・x_set_ipm()で，iipmが'0'(IIPM_ENAALL)の時の問題を修正．
+・core_support.S
+  ・toppers_asm_custom_idleの前後で使用するレジスタを変更．この変更に
+    より，toppers_asm_custom_idle で関数呼び出しをする場合は，アセンブ
+    ラレベルでのレジスタの保存が必要なくなった．
+    
+2012/02/23
+・core_support.S
+  ・core_exc_entryでbasepriを読み込んだあと，全割込みロック状態のチェ
+    ックために上書きしていた問題を修正
+  ・call_texrtnとcall_texrtnの呼び出しをb命令で記述すると，16bit命令と
+    して解釈するコンパイラがあるため，メモリ配置によってはレンジが足り
+    なくなる．bx命令に変更することで問題を修正．
+
+2012/01/31
+・core_timer.c
+ ・タイマ割込みハンドラにて，probe_int のため，COUNTFLAGをクリアするた
+   めに読み込んでいたレジスタが誤っていた問題を修正．
+ 
+2011/12/03
+・core_test.h の多重インクルード防止マクロの名称修正
+ ・CHIP を CORE に修正．
+
+・ARMCC対応に伴う変更
+  ・core_asm.inc(追加)
+    ・GCCのアセンブラのディレクティブの定義を記述したファイルを追加．
+  ・core_config.h(変更)
+    ・core_insn.h のインクルード方法を""から<>に変更して，コンパイラの
+      引数で指定された順でインクルードファイルをサーチするよう変更．
+   ・メモリバリア命令(Asm("":::"memory"))をマクロ化してcore_insn.h に
+     定義を使用するよう変更．     
+  ・core_insn.h(変更)
+   ・メモリバリア命令(Asm("":::"memory"))のマクロ定義を追加
+  ・core_support.S(変更)
+   ・ARMCCとファイルを共有するため，ディレクティブをマクロに書き換え．      
+  ・start.S(変更)
+   ・ARMCCとファイルを共有するため，ディレクティブをマクロに書き換え．  
+   
+2011/07/26
+・CCRのSTKALIGNが'1'の場合への対応
+  割込み・例外の出入口処理では，スタックは常に8byte境界となるように変
+  更．
+  
+2011/07/25
+・CPU例外の優先度の初期化
+  CPUロックでマスクできない優先度（内部優先度0）に初期化する処理を追加．
+  
+・CFG_INTで使用できる割込み優先度の最大値の修正(core.tf)
+  ・最大値が1つ大きな値となっていた．
+  
+・カーネル管理外の割込みの扱いの変更
+  ・共通部での扱いの変更に伴う変更．
+  
+・タイマ割込みハンドラでのCOUNTFLAGのクリア処理の修正
+  SYSTIC_CONTROL_STATUSレジスタのCOUNTFLAGをクリアするには，
+  SYSTIC_CURRENT_VALUEレジスタを読み込む必要があるが，誤って
+  SYSTIC_CONTROL_STATUSレジスタを読み込んでいた．
+
+・core_int_entryにおけるbasepriの設定
+  NVIC優先度マスクが自動的に設定されるため優先度マスクの点では必要な
+  いが，x_get_ipm()がbasepriを参照するため，basepriも更新するよう変更．
+
+2011/07/24
+・_ret_int_2/svc_handler の変更
+  割込み優先度マスクが全解除状態でしかタスク例外を呼び出さないように
+  仕様が変更されたため，_ret_int_2では，割込み優先度マスクを，全解除
+  状態（TIPM_ENAALL）に設定するよう変更．
+  svc_handlerはタスクにリターンする時にbasepriをIIPM_ENAALLにするよう
+  に変更．
+  
+・x_config_int()/set_exc_int_priority()の修正  
+  x_config_int()から，set_exc_int_priority()に対して外部優先度を引数に
+  して呼び出しいたため，内部優先度を引数で呼び出すよう修正．
+  set_exc_int_priority()も受け取った引数を内部優先度として優先度を設定
+  するように修正．
+
+2011/07/23
+・共通部を1.4.0にupdate.
+
+・arm依存部と同様にチップ依存部を置けるようにディレクトリ構造を変更
+
+・arm依存部と同様にファイル名のプリフィックスをcoreに変更．
+
+・call_atexitの削除
+  software_term_hook の呼び出しは，core_terminate()に移動．
+  
+・共通部を1.7.0にupdate.  
+
+・タスクコンテキストブロックの型名の変更
+  CTXB型をTSKCTXB型に名称変更．
+
+・ターゲット依存部でサポートする機能を示すマクロの変更
+  TOPPERS_SUPPORT_DIS_INTをTOPPERS_TARGET_SUPPORT_DIS_INTに，
+  TOPPERS_SUPPORT_ENA_INTをTOPPERS_TARGET_SUPPORT_ENA_INTに，
+  変更．
+  
+・exc_sense_unlockの定義を削除．  
+  
+・オフセットファイルをコンフィギュレータで生成する方法への対応
+
+・CHECK_FUNC_ALIGN，CHECK_FUNC_NONNULL，CHECK_STACK_ALIGN，
+  CHECK_STACK_NONNULL，CHECK_MPF_ALIGN，CHECK_MPF_NONNULLの定義を，タ
+  ーゲット依存部のテンプレートファイル（パス3）からヘッダファイルに移
+  動．
+
+・割込みと例外の入り口処理の名前を変更
+  int_entryをcore_int_entryへexc_entryをcore_exc_entryに変更．
+  オフセットの取得方法が変更となったため，元の名前のままだとcfg1_out.c
+  がコンパイルエラーとなるために変更．
+  
+・ターゲット依存部で定義する名称のリネームの追加
+
+・call_texrtnを呼び出す条件に「ipmflgがtrue」を追加
+ 
+・カーネル管理外のCPU例外の扱いの変更
+
+2011/07/22
+・x_disable_int() : prc_config.h の修正   
+ 割込み禁止レジスタのアドレスを取得する際に，ベースの値をuint32_tの
+ ポインタにキャストしていなったため，正しいアドレスが生成できていな
+ かった問題を修正．
+ 
+・非タスクコンテキスト用のスタックの初期値マクロ(TOPPERS_ISTKPT)の修正 
+  : prc_config.h
+ バイト単位で取得するように，(char_t *) にキャストして掲載するように修
+ 正．
+  
+・LOG_INH_ENTRYとLOG_INH_LEAVEの誤記 : prc_support.S
+  LOG_INH_ENTRYとLOG_INH_LEAVEであるべき箇所が LOG_EXC_ENTRYと
+  LOG_EXC_ENTRYになっている問題を修正．
+
+・TOPPERS_CUSTOM_IDLE のtypoの修正 : prc_support.S
+
+・svn_hanlderの修正 :  prc_support.S
+  一律EXC_FRAME_SIZE分のスタックを捨てていたが，Configureation and 
+  Control Register(CCR)のSTKALIGNが'1'の場  合は，8byte境界にアライン
+  されるため，捨てるサイズが異なる．アラインされたかは，xPSRの9ビッ
+  トをチェックすることにより判定する．
+  
+・prc.tfの修正
+  boostのバージョンによって変わる挙動を吸収．
+  http://www.toppers.jp/TOPPERS-USERS/201004/msg00034.html
+  
+・_kernel_istkpt の削除 : prc_cfg1_out.h
+  _kernel_istkpt が必要ないターゲットが存在するため，必要なら，ターゲ
+  ット依存部で定義するように変更．
+
+2008/08/22
+・prc_user.txt/prc_design.txt
+  ・2008/8/21の技術検討会での議論結果を反映．
+  
+・prc_support.S/prc_config.c/prc_config.h/arm_m.h
+  ・コンテキスト判定をexc_ncntからアクティブなスタックに変更
+  
+・prc_config.c
+  ・set_exc_int_priority() でサポート可能なIRQの上限を239に拡張．
+  
+・start.S 
+  ・起動時はThreadモードを前提としていることを明記．
+  ・ブートローダー等から起動される場合を想定し，MSPを有効にするように
+    変更．
+    
+・prc_timer.c
+  ・コメントを修正
+  ・デバッグ用コードを削除
+
+2008/07/11
+・最初のリリース
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/arch/arm_m_gcc/common/start.S
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/arch/arm_m_gcc/common/start.S	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/arch/arm_m_gcc/common/start.S	(revision 457)
@@ -0,0 +1,174 @@
+/*
+ *  TOPPERS Software
+ *      Toyohashi Open Platform for Embedded Real-Time Systems
+ * 
+ *  Copyright (C) 2008 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+                
+/*
+ *   カーネル用のスタートアップモジュール(ARM-M用)
+ */
+#define TOPPERS_MACRO_ONLY
+#define UINT_C(val)		(val)		/* uint_t型の定数を作るマクロ */
+#define ULONG_C(val)	(val)		/* ulong_t型の定数を作るマクロ */
+#define CAST(type, val)	(val)		/* 型キャストを行うマクロ */
+
+#include "kernel_impl.h"
+#include "arm_m.h"
+#include "target_asm.inc"
+
+#if defined(TOPPERS_CORTEX_M0PLUS) || defined(TOPPERS_CORTEX_M0)
+#define mov  movs
+#define add  adds
+#endif
+
+/*
+ *  スタートアップルーチン
+ *
+ *  Threadモードで呼び出されることを前提としてる．
+ */
+	ATEXT
+	ABALIGN(4)
+	ATHUMB(_start)
+	AGLOBAL(_start) 
+ALABEL(_start)
+	cpsid f                 /* 割込みロック状態へ */
+
+#ifdef INIT_MSP
+	/*
+	 * MSPの設定
+	 */
+	mov   r0, #CONTROL_MSP  /* MSPを有効に  */
+	msr   control, r0
+	isb                     /* control の操作後に必要 */
+	ldr  r0,=_kernel_istkpt
+	ldr  r1,[r0]
+	msr  msp, r1
+#endif /* INIT_MSP */
+
+#ifdef TOPPERS_FPU_ENABLE
+	/*
+	 *  FPUの有効化
+	 */
+	ldr  r0,=(CPACR)
+	ldr  r1,=(CPACR_FPU_ENABLE)
+	ldr  r2,[r0]
+	orr  r2,r2,r1    
+	str  r2,[r0]
+
+	/*
+	 *  FPCAを初期化
+	 */ 
+	ldr r0, =(FPCCR_INIT)
+	ldr r1, =(FPCCR)
+	str r0, [r1] 
+#endif /* TOPPERS_FPU_ENABLE */
+
+	/*
+	 * hardware_init_hookの呼び出し （0でない場合）
+	 *
+	 * ターゲットハードウェアに依存して必要な初期化処理がある場合
+	 * は，hardware_init_hook という関数を用意する
+	 */
+	ldr  r0, =hardware_init_hook
+#if defined(TOPPERS_CORTEX_M0PLUS) || defined(TOPPERS_CORTEX_M0)
+	cmp  r0, #0
+	beq.n start_1
+#else
+	cbz  r0, start_1
+#endif
+	blx  r0
+
+ALABEL(start_1)
+#ifndef OMIT_BSS_INIT
+	/*
+	 *  BSSセクション初期化
+	 */
+	mov  r0, #0
+	ldr  r1, =BSS_START
+	ldr  r2, =BSS_END
+	cmp  r1, r2
+	bhs  start_3
+ALABEL(start_2)
+	str  r0, [r1]
+	add  r1,r1, #4
+	cmp  r1, r2
+	blo  start_2
+#endif /* OMIT_BSS_INIT */
+
+
+ALABEL(start_3)
+#ifndef OMIT_DATA_INIT
+	/*
+	 *  DATAセクション初期化
+	 *  __idata_start から __idata_end までを，__data_start 以降に
+	 *  コピーする
+	 */
+	ldr  r1, =IDATA_START
+	ldr  r2, =IDATA_END
+	cmp  r1, r2
+	bhs  start_5
+	ldr  r3, =DATA_START
+ALABEL(start_4)
+	ldr  r0, [r1]
+	str  r0, [r3]
+	add  r1, #4
+	add  r3, #4
+	cmp  r1, r2
+	blo  start_4
+#endif /* OMIT_DATA_INIT */
+
+	/*
+	 *  software_init_hook を呼出し（0 でない場合）
+	 *
+	 *  ソフトウェア環境（特にライブラリ）に依存して必要な初期化処
+	 *  理がある場合は，software_init_hook という関数を用意すれば
+	 *  よい．
+	 */
+ALABEL(start_5)
+	ldr  r0, =software_init_hook
+#if defined(TOPPERS_CORTEX_M0PLUS) || defined(TOPPERS_CORTEX_M0)
+	cmp  r0, #0
+	beq.n start_6
+#else
+	cbz  r0, start_6
+#endif
+	blx  r0
+
+ALABEL(start_6)
+	bl   sta_ker
+
+ALABEL(l_end)
+	b   l_end
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/arch/arm_m_gcc/stm32f7xx/MANIFEST
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/arch/arm_m_gcc/stm32f7xx/MANIFEST	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/arch/arm_m_gcc/stm32f7xx/MANIFEST	(revision 457)
@@ -0,0 +1,18 @@
+PACKAGE asp_arch_stm32f7xx_gcc
+
+MANIFEST
+Makefile.chip
+cmsis_f7.h
+stm32f7xx.h
+chip_config.c
+chip_config.h
+chip_kernel.h
+chip_rename.def
+chip_rename.h
+chip_sil.h
+chip_timer.cfg
+chip_timer.h
+chip_unrename.h
+chip_serial.c
+chip_serial.cfg
+chip_serial.h
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/arch/arm_m_gcc/stm32f7xx/Makefile.chip
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/arch/arm_m_gcc/stm32f7xx/Makefile.chip	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/arch/arm_m_gcc/stm32f7xx/Makefile.chip	(revision 457)
@@ -0,0 +1,65 @@
+#
+#		Makefile のターゲット依存部（stm32f7xx用）
+#
+
+#
+#  コンパイルオプション
+#
+INCLUDES := $(INCLUDES) -I$(SRCDIR)/arch/$(PRC)_$(TOOL)/$(CHIP)
+COPTS := $(COPTS) -mlittle-endian -nostartfiles
+LDFLAGS := $(LDFLAGS) -mlittle-endian
+LIBS := $(LIBS)
+ifeq ($(FPU_ABI),)
+FPU_ABI = softfp
+endif
+
+#
+#  CPUコアの定義
+#
+CORE_TYPE = CORTEX_M7
+
+#
+#  カーネルに関する定義
+#
+KERNEL_DIR := $(KERNEL_DIR) $(SRCDIR)/arch/$(PRC)_$(TOOL)/$(CHIP)
+KERNEL_ASMOBJS := $(KERNEL_ASMOBJS)
+KERNEL_COBJS := $(KERNEL_COBJS) core_timer.o chip_config.o
+
+#
+#  システムサービスに関する定義
+#
+SYSSVC_DIR := $(SYSSVC_DIR) $(SRCDIR)/arch/$(PRC)_$(TOOL)/$(CHIP)
+SYSSVC_COBJS := $(SYSSVC_COBJS) chip_serial.o
+
+#
+#  リンカスクリプトの定義
+#
+ifeq ($(DBGENV),RAM)
+LDSCRIPT = $(SRCDIR)/target/$(BOARD)/stm32f7xx_ram.ld
+COPTS := $(COPTS) -DTOPPERS_RAM_EXEC
+else
+LDSCRIPT = $(SRCDIR)/target/$(BOARD)/stm32f7xx_rom.ld
+endif
+
+#
+#  スタートアップモジュールに関する定義
+#
+#  stm32f7xx_xxx.ldに「STARTUP(start.o)」を記述したため，
+#  スタートアップモジュールの名前をHIDDEN_OBJSに定義する．
+#  また，LDFLAGSに-nostdlibを追加している．
+#
+HIDDEN_OBJS = start.o
+
+$(HIDDEN_OBJS): %.o: %.S
+	$(CC) -c $(CFLAGS) $(KERNEL_CFLAGS) $<
+
+$(HIDDEN_OBJS:.o=.d): %.d: %.S
+	@$(PERL) $(SRCDIR)/utils/makedep -C $(CC) \
+		-O "$(CFLAGS) $(KERNEL_CFLAGS)" $< >> Makefile.depend
+
+LDFLAGS := -nostdlib $(LDFLAGS)
+
+#
+#  コア依存部のインクルード
+#
+include $(SRCDIR)/arch/$(PRC)_$(TOOL)/common/Makefile.core
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/arch/arm_m_gcc/stm32f7xx/chip_config.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/arch/arm_m_gcc/stm32f7xx/chip_config.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/arch/arm_m_gcc/stm32f7xx/chip_config.c	(revision 457)
@@ -0,0 +1,103 @@
+/*
+ *  TOPPERS/ASP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Advanced Standard Profile Kernel
+ * 
+ *  Copyright (C) 2008-2011 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ *  Copyright (C) 2015      by 3rd Designing Center
+ *              Imageing System Development Division RICOH COMPANY, LTD.
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ * ターゲット依存モジュール（stm32f7xx用）
+ */
+#include "kernel_impl.h"
+#include <sil.h>
+
+#include "stm32f7xx.h"
+#include "chip_serial.h"
+
+/*
+ *  ターゲット依存の初期化
+ */
+void
+target_initialize(void){
+
+	/*
+	 * コア依存の初期化
+	 */
+	core_initialize();
+
+	/*
+	 *  バナー出力用のシリアル初期化
+	 */
+	chip_uart_init(SIO_PORTID);
+
+	/*
+	 *  タイマの割込みレベルの設定
+	 */
+	sil_wrb_mem((uint8_t *)(TADR_SCB_BASE+TOFF_SCB_SHP15), (14 << (8 - 4)) & 0xff);
+} 
+
+
+/*
+ *  ターゲット依存の終了処理
+ */
+void
+target_exit(void)
+{
+	/*
+	 *  コア依存の終了処理
+	 */
+	core_terminate();
+
+	/*
+	 *  開発環境依存の終了処理
+	 */
+	while(1);
+}
+
+
+/*
+ *  システムログの低レベル出力のための文字出力
+ */
+void
+target_fput_log(int8_t c)
+{
+	if (c == '\n') {
+		sio_pol_snd_chr('\r', SIO_PORTID);
+	}
+	sio_pol_snd_chr(c, SIO_PORTID);
+}
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/arch/arm_m_gcc/stm32f7xx/chip_config.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/arch/arm_m_gcc/stm32f7xx/chip_config.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/arch/arm_m_gcc/stm32f7xx/chip_config.h	(revision 457)
@@ -0,0 +1,97 @@
+/*
+ *  TOPPERS/ASP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Advanced Standard Profile Kernel
+ * 
+ *  Copyright (C) 2008-2011 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ *  Copyright (C) 2015      by 3rd Designing Center
+ *              Imageing System Development Division RICOH COMPANY, LTD.
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *  チップ依存モジュール（stm32f7xx用）
+ *
+ *  カーネルのターゲット依存部のインクルードファイル．kernel_impl.hのター
+ *  ゲット依存部の位置付けとなる．
+ */
+
+#ifndef TOPPERS_CHIP_CONFIG_H
+#define TOPPERS_CHIP_CONFIG_H
+
+/*
+ *  ターゲット依存部のハードウェア資源の定義
+ */
+#include "stm32f7xx.h"
+
+/*
+ *  RAM実行する場合やQEMU実行時ROMデバッグ時はMSPを初期化する
+ *  必要があるため,スタートアップルーチンでMSPを初期化する． 
+ */
+#define INIT_MSP
+
+/*
+ *  デフォルトの非タスクコンテキスト用のスタック領域の定義
+ */
+#define DEFAULT_ISTKSZ      (0x1000U)   /* 4KByte */
+
+/*
+ *  使用するシリアルポートID
+ */
+#ifndef SIO_PORTID
+#define SIO_PORTID		(1)
+#endif /* SIO_PORTID */
+
+#ifndef TOPPERS_MACRO_ONLY
+
+/*
+ *  ターゲットシステム依存の初期化
+ */
+extern void	target_initialize(void);
+
+/*
+ *  ターゲットシステムの終了
+ *
+ *  システムを終了する時に使う．
+ */
+extern void	target_exit(void) NoReturn;
+
+#endif /* TOPPERS_MACRO_ONLY */
+
+/*
+ *  コア依存モジュール（ARM-M用）
+ */
+#include "core_config.h"
+
+#endif /* TOPPERS_CHIP_CONFIG_H */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/arch/arm_m_gcc/stm32f7xx/chip_kernel.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/arch/arm_m_gcc/stm32f7xx/chip_kernel.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/arch/arm_m_gcc/stm32f7xx/chip_kernel.h	(revision 457)
@@ -0,0 +1,79 @@
+/*
+ *  TOPPERS/ASP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Advanced Standard Profile Kernel
+ * 
+ *  Copyright (C) 2008-2011 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ *  Copyright (C) 2015      by 3rd Designing Center
+ *              Imageing System Development Division RICOH COMPANY, LTD.
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *  kernel.hのチップ依存部（stm32f7xx用）
+ *
+ *  このインクルードファイルは，kernel.hでインクルードされる．他のファ
+ *  イルから直接インクルードすることはない．このファイルをインクルード
+ *  する前に，t_stddef.hがインクルードされるので，それらに依存してもよ
+ *  い．
+ */
+
+#ifndef TOPPERS_CHIP_KERNEL_H
+#define TOPPERS_CHIP_KERNEL_H
+
+/*
+ *  カーネル管理の割込み優先度の範囲
+ *
+ *  TMIN_INTPRIの定義を変更することで，このレベルよりも高い割込み優先度
+ *  を持つものをカーネル管理外の割込みとするかを変更できる．
+ */
+#define TMIN_INTPRI		(-15)		/* 割込み優先度の最小値（最高値）*/
+
+/*
+ *  サポートする機能の定義
+ */
+#define TOPPERS_TARGET_SUPPORT_GET_UTM	/* get_utmをサポートする */
+
+/*
+ *  タイムティックの定義
+ */
+#define TIC_NUME   1U            /* タイムティックの周期の分子 */
+#define TIC_DENO   1U            /* タイムティックの周期の分母 */
+
+/*
+ *  コア依存で共通な定義
+ */
+#include "arm_m_gcc/common/core_kernel.h"
+
+#endif /* TOPPERS_CHIP_KERNEL_H */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/arch/arm_m_gcc/stm32f7xx/chip_rename.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/arch/arm_m_gcc/stm32f7xx/chip_rename.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/arch/arm_m_gcc/stm32f7xx/chip_rename.h	(revision 457)
@@ -0,0 +1,26 @@
+/* This file is generated from target_rename.def by genrename. */
+
+#ifndef TOPPERS_CHIP_RENAME_H
+#define TOPPERS_CHIP_RENAME_H
+
+
+/*
+ * chip_config.c
+ */
+#define target_initialize			_kernel_target_initialize
+#define target_exit					_kernel_target_exit
+
+#ifdef TOPPERS_LABEL_ASM
+
+
+/*
+ * chip_config.c
+ */
+#define _target_initialize			__kernel_target_initialize
+#define _target_exit				__kernel_target_exit
+
+#endif /* TOPPERS_LABEL_ASM */
+
+#include "arm_m_gcc/common/core_rename.h"
+
+#endif /* TOPPERS_CHIP_RENAME_H */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/arch/arm_m_gcc/stm32f7xx/chip_serial.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/arch/arm_m_gcc/stm32f7xx/chip_serial.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/arch/arm_m_gcc/stm32f7xx/chip_serial.c	(revision 457)
@@ -0,0 +1,671 @@
+/*
+ *  TOPPERS/ASP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Advanced Standard Profile Kernel
+ * 
+ *  Copyright (C) 2008-2011 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ *  Copyright (C) 2015      by 3rd Designing Center
+ *              Imageing System Development Division RICOH COMPANY, LTD.
+ *  Copyright (C) 2016-2019 by TOPPERS PROJECT Educational Working Group.
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *  シリアルI/Oデバイス（SIO）ドライバ（stm32f7xx用）
+ */
+
+#include <kernel.h>
+#include <t_syslog.h>
+#include "target_stddef.h"
+#include "target_serial.h"
+#include "target_syssvc.h"
+
+/*
+ * レジスタ設定値
+ */
+#define PORT2SIOPID(x)	((x) + 1)
+#define INDEX_PORT(x)	((x) - 1)
+#define GET_SIOPCB(x)	(&siopcb_table[INDEX_PORT(x)])
+
+/*
+ *  GPIOモードパラメータ
+ */
+#define GPIO_MODE_INPUT     0x00000000	/* Input Floating Mode */
+#define GPIO_MODE_OUTPUT    0x00000001	/* Output Mode */
+#define GPIO_MODE_AF        0x00000002	/* Alternate Function Mode */
+#define GPIO_MODE_ANALOG    0x00000003	/* Analog Mode  */
+
+/*
+ *  GPIOアウトプット設定パラメータ
+ */
+#define GPIO_OTYPE_PP       0x0
+#define GPIO_OTYPE_OD       0x1
+
+/*
+ *  GPIOアウトプット最大周波数パラメータ
+ */
+#define GPIO_SPEED_LOW      0x00000000	/* Low speed     */
+#define GPIO_SPEED_MEDIUM   0x00000001	/* Medium speed  */
+#define GPIO_SPEED_FAST     0x00000002	/* Fast speed    */
+#define GPIO_SPEED_HIGH     0x00000003	/* High speed    */
+
+/*
+ *  GPIOプルアップダウンパラメータ
+ */
+#define GPIO_NOPULL         0x00000000	/* No Pull-up or Pull-down activation  */
+#define GPIO_PULLUP         0x00000001	/* Pull-up activation                  */
+#define GPIO_PULLDOWN       0x00000002	/* Pull-down activation                */
+
+/*
+ *  CLOCKソース
+ */
+#define SOURCE_PCLK2        0
+#define SOURCE_SYSCLK       1
+#define SOURCE_HSI          2
+#define SOURCE_LSE          3
+
+/*
+ *  ビット長パラメータ
+ */
+#define USART_WordLength_8b 0x0000
+#define USART_WordLength_9b USART_CR1_M
+
+/*
+ *  ストップビットパラメータ
+ */ 
+#define USART_StopBits_1    0x0000
+#define USART_StopBits_0_5  USART_CR2_STOP_0
+#define USART_StopBits_2    USART_CR2_STOP_1
+#define USART_StopBits_1_5  USART_CR2_STOP
+
+/*
+ *  パリティパラメータ
+ */
+#define USART_Parity_No     0x0000
+#define USART_Parity_Even   USART_CR1_PCE
+#define USART_Parity_Odd    (USART_CR1_PCE | USART_CR1_PS) 
+
+/*
+ * ハードウェアフロー制御パラメータ
+ */
+#define USART_HardwareFlowControl_None       0x0000
+#define USART_HardwareFlowControl_RTS        USART_CR3_RTSE
+#define USART_HardwareFlowControl_CTS        USART_CR3_CTSE
+#define USART_HardwareFlowControl_RTS_CTS    (USART_CR3_RTSE | USART_CR3_CTSE)
+
+#define ISR_ACK             (USART_ISR_TEACK | USART_ISR_REACK)
+#define CR1_CLEAR_MASK      (USART_CR1_M | USART_CR1_PCE | USART_CR1_PS | USART_CR1_TE | USART_CR1_RE | USART_CR1_OVER8)
+#define CR3_CLEAR_MASK      (USART_CR3_RTSE | USART_CR3_CTSE | USART_CR3_ONEBIT)
+
+#define UART_TIMEOUT_VALUE               0x1FFFFFF
+
+/*
+ *  シリアルI/Oポート初期化ブロックの定義
+ */
+typedef struct sio_port_initialization_block {
+	uint32_t base;
+	INTNO    intno_usart;
+	uint32_t clock_shift;
+} SIOPINIB;
+
+/*
+ *  兼用GPIOポート初期化ブロックの定義
+ */
+typedef struct gpio_port_initialization_block {
+	uint32_t clockbase;
+	uint32_t clock_set;
+	uint32_t portbase;
+	uint32_t txport_set;
+	uint32_t rxport_set;
+	uint32_t resetbase;
+	uint32_t reset_set;
+	uint32_t gpio_af;
+
+	uint32_t txportbase;
+	uint32_t txpinport;
+	uint32_t txmode_msk;
+	uint32_t txmode_set;
+	uint32_t txspeed_msk;
+	uint32_t txspeed_set;
+	uint32_t txtype_msk;
+	uint32_t txtype_set;
+	uint32_t txpupd_msk;
+	uint32_t txpupd_set;
+
+	uint32_t rxportbase;
+	uint32_t rxpinport;
+	uint32_t rxmode_msk;
+	uint32_t rxmode_set;
+	uint32_t rxspeed_msk;
+	uint32_t rxspeed_set;
+	uint32_t rxtype_msk;
+	uint32_t rxtype_set;
+	uint32_t rxpupd_msk;
+	uint32_t rxpupd_set;
+} GPIOINIB;
+
+/*
+ *  シリアルI/Oポート管理ブロックの定義
+ */
+struct sio_port_control_block {
+	const SIOPINIB  *p_siopinib;  /* シリアルI/Oポート初期化ブロック */
+	const GPIOINIB  *p_gpioinib;  /* 兼用GPIOポート初期化ブロック */
+	intptr_t        exinf;        /* 拡張情報 */
+	bool_t          opnflg;       /* オープン済みフラグ */
+};
+
+/*
+ * シリアルI/Oポート初期化ブロック
+ */
+const SIOPINIB siopinib_table[TNUM_SIOP] = {
+	{(uint32_t)USART1_BASE, (INTNO)INTNO_SIO1, U1_CLOCK_SHIFT}
+#if TNUM_SIOP > 1
+   ,{(uint32_t)USART2_BASE, (INTNO)INTNO_SIO2, U2_CLOCK_SHIFT}
+#endif
+};
+
+/*
+ * 兼用GPIOポート初期化ブロック
+ */
+const GPIOINIB gpioinib_table[TNUM_SIOP] = {
+	{(uint32_t)(TADR_RCC_BASE+TOFF_U1_APBNER), (uint32_t)ENABLE_U1_PORT,
+     (uint32_t)(TADR_RCC_BASE+TOFF_RCC_AHB1ENR), (uint32_t)ENABLE_U1T_GPIO, (uint32_t)ENABLE_U1R_GPIO,
+     (uint32_t)(TADR_RCC_BASE+TOFF_U1_APBRSTR), (uint32_t)RESET_U1_PORT,
+	 (uint32_t)GPIO_U1_AF,
+     (uint32_t)TADR_U1T_GPIO_BASE, (uint32_t)TX1_PINPOS,
+     (uint32_t)~(GPIO_MODER_MODER2 << (TX1_PINPOS*2)), (uint32_t)(GPIO_MODE_AF << (TX1_PINPOS*2)),
+     (uint32_t)~(GPIO_OSPEEDER_OSPEEDR2 << (TX1_PINPOS*2)), (uint32_t)(GPIO_SPEED_HIGH << (TX1_PINPOS*2)),
+     (uint32_t)~(GPIO_OTYPER_OT << TX1_PINPOS), (uint32_t)(GPIO_OTYPE_PP << TX1_PINPOS),
+     (uint32_t)~(GPIO_PUPDR_PUPDR2 << (TX1_PINPOS*2)), (uint32_t)(GPIO_PULLUP << (TX1_PINPOS*2)),
+     (uint32_t)TADR_U1R_GPIO_BASE, (uint32_t)RX1_PINPOS,
+     (uint32_t)~(GPIO_MODER_MODER2 << (RX1_PINPOS*2)), (uint32_t)(GPIO_MODE_AF << (RX1_PINPOS*2)),
+     (uint32_t)~(GPIO_OSPEEDER_OSPEEDR2 << (RX1_PINPOS*2)), (uint32_t)(GPIO_SPEED_HIGH << (RX1_PINPOS*2)),
+     (uint32_t)~(GPIO_OTYPER_OT << RX1_PINPOS), (uint32_t)(GPIO_MODE_AF << RX1_PINPOS),
+     (uint32_t)~(GPIO_PUPDR_PUPDR2 << (RX1_PINPOS*2)), (uint32_t)(GPIO_PULLUP << (RX1_PINPOS*2))
+    }
+#if TNUM_SIOP > 1
+   ,{(uint32_t)(TADR_RCC_BASE+TOFF_U2_APBNER), (uint32_t)ENABLE_U2_PORT,
+     (uint32_t)(TADR_RCC_BASE+TOFF_RCC_AHB1ENR), (uint32_t)ENABLE_U2T_GPIO, (uint32_t)ENABLE_U2R_GPIO,
+     (uint32_t)(TADR_RCC_BASE+TOFF_U2_APBRSTR), (uint32_t)RESET_U2_PORT,
+	 (uint32_t)GPIO_U2_AF,
+     (uint32_t)TADR_U2T_GPIO_BASE, (uint32_t)TX2_PINPOS,
+     (uint32_t)~(GPIO_MODER_MODER2 << (TX2_PINPOS*2)), (uint32_t)(GPIO_MODE_AF << (TX2_PINPOS*2)),
+     (uint32_t)~(GPIO_OSPEEDER_OSPEEDR2 << (TX2_PINPOS*2)), (uint32_t)(GPIO_SPEED_HIGH << (TX2_PINPOS*2)),
+     (uint32_t)~(GPIO_OTYPER_OT << TX2_PINPOS), (uint32_t)(GPIO_OTYPE_PP << TX2_PINPOS),
+     (uint32_t)~(GPIO_PUPDR_PUPDR2 << (TX2_PINPOS*2)), (uint32_t)(GPIO_PULLUP << (TX2_PINPOS*2)),
+     (uint32_t)TADR_U2R_GPIO_BASE, (uint32_t)RX2_PINPOS,
+     (uint32_t)~(GPIO_MODER_MODER2 << (RX2_PINPOS*2)), (uint32_t)(GPIO_MODE_AF << (RX2_PINPOS*2)),
+     (uint32_t)~(GPIO_OSPEEDER_OSPEEDR2 << (RX2_PINPOS*2)), (uint32_t)(GPIO_SPEED_HIGH << (RX2_PINPOS*2)),
+     (uint32_t)~(GPIO_OTYPER_OT << RX2_PINPOS), (uint32_t)(GPIO_MODE_AF << RX2_PINPOS),
+     (uint32_t)~(GPIO_PUPDR_PUPDR2 << (RX2_PINPOS*2)), (uint32_t)(GPIO_PULLUP << (RX2_PINPOS*2))
+    }
+#endif
+};
+
+/*
+ *  シリアルI/Oポート管理ブロックのエリア
+ */
+SIOPCB	siopcb_table[TNUM_SIOP];
+
+/*
+ *  シリアルI/OポートIDから管理ブロックを取り出すためのマクロ
+ */
+#define INDEX_SIOP(siopid)	((uint_t)((siopid) - 1))
+#define get_siopcb(siopid)	(&(siopcb_table[INDEX_SIOP(siopid)]))
+
+static void setup_gpio_source(uint32_t base, uint8_t source, uint8_t select)
+{
+	uint32_t tmpreg, regoff;
+	regoff = TOFF_GPIO_AFR0+((source>>3) * 4);
+	tmpreg = (sil_rew_mem((uint32_t *)(base+regoff)) & ~(0xF << ((source & 0x07) * 4)))
+			    | (select << ((source & 0x07) * 4));
+	sil_wrw_mem((uint32_t *)(base+regoff), tmpreg);
+}
+
+void put_hex(char a, int val)
+{
+	int i, j;
+	target_fput_log(a);
+	target_fput_log(' ');
+	for(i = 28 ; i >= 0 ; i-= 4){
+		j = (val >> i) & 0xf;;
+		if(j > 9)
+			j += ('A'-10);
+		else
+			j += '0';
+		target_fput_log(j);
+	}
+	target_fput_log('\n');
+}
+
+/*
+ *  SIOドライバの初期化
+ */
+void
+sio_initialize(intptr_t exinf)
+{
+	SIOPCB	*p_siopcb;
+	uint_t	i;
+
+	/*
+	 *  シリアルI/Oポート管理ブロックの初期化
+	 */
+	for (p_siopcb = siopcb_table, i = 0; i < TNUM_SIOP; p_siopcb++, i++) {
+		p_siopcb->p_siopinib = &(siopinib_table[i]);
+		p_siopcb->p_gpioinib = &(gpioinib_table[i]);
+		p_siopcb->opnflg = false;
+	}
+}
+
+/*
+ *  シリアルI/Oポートのオープン
+ */
+SIOPCB *
+sio_opn_por(ID siopid, intptr_t exinf)
+{
+	SIOPCB          *p_siopcb;
+	const SIOPINIB  *p_siopinib;
+	const GPIOINIB  *p_gpioinib;
+	bool_t   opnflg;
+	ER       ercd;
+	uint32_t base, txbase, rxbase, tmp;
+
+	p_siopcb = get_siopcb(siopid);
+	p_siopinib = p_siopcb->p_siopinib;
+	p_gpioinib = p_siopcb->p_gpioinib;
+
+	/*
+	 *  オープンしたポートがあるかをopnflgに読んでおく．
+	 */
+	opnflg = p_siopcb->opnflg;
+
+	p_siopcb->exinf = exinf;
+	txbase = p_gpioinib->txportbase;
+	rxbase = p_gpioinib->rxportbase;
+	base   = p_siopinib->base;
+
+	if(txbase == 0 || rxbase == 0)	/* no usart port */
+		goto sio_opn_exit;
+
+	/*
+	 *  USART停止
+	 */
+	sil_wrw_mem((uint32_t *)(base+TOFF_USART_ICR), 0xFFFFFFFF);
+	sil_wrw_mem((uint32_t *)(base+TOFF_USART_CR1), sil_rew_mem((uint32_t *)(base+TOFF_USART_CR1)) & ~USART_CR1_UE);
+
+	/*
+	 *  ハードウェアの初期化
+	 */
+	if(p_siopinib->clock_shift == 0){	/* USART1の場合、SYSLOCKを設定 */
+		sil_wrw_mem((uint32_t *)(TADR_RCC_BASE+TOFF_RCC_DCKCFGR2),
+			(sil_rew_mem((uint32_t *)(TADR_RCC_BASE+TOFF_RCC_DCKCFGR2)) & RCC_DCKCFGR2_USART1SEL) | RCC_DCKCFGR2_USART1SEL_0);
+	}
+	else if(p_siopinib->clock_shift == 10 && siopid == 1){	/* F723/USART6の場合、SYSLOCKを設定 */
+		sil_wrw_mem((uint32_t *)(TADR_RCC_BASE+TOFF_RCC_DCKCFGR2),
+			(sil_rew_mem((uint32_t *)(TADR_RCC_BASE+TOFF_RCC_DCKCFGR2)) & RCC_DCKCFGR2_USART6SEL) | RCC_DCKCFGR2_USART6SEL_0);
+	}
+	sil_wrw_mem((uint32_t *)p_gpioinib->clockbase, sil_rew_mem((uint32_t *)p_gpioinib->clockbase) | p_gpioinib->clock_set);
+	sil_wrw_mem((uint32_t *)p_gpioinib->portbase, sil_rew_mem((uint32_t *)p_gpioinib->portbase) | p_gpioinib->txport_set);
+	sil_wrw_mem((uint32_t *)p_gpioinib->portbase, sil_rew_mem((uint32_t *)p_gpioinib->portbase) | p_gpioinib->rxport_set);
+	sil_wrw_mem((uint32_t *)(txbase+TOFF_GPIO_MODER), (sil_rew_mem((uint32_t *)(txbase+TOFF_GPIO_MODER)) & p_gpioinib->txmode_msk) | p_gpioinib->txmode_set);
+	sil_wrw_mem((uint32_t *)(txbase+TOFF_GPIO_OSPEEDR), (sil_rew_mem((uint32_t *)(txbase+TOFF_GPIO_OSPEEDR)) & p_gpioinib->txspeed_msk) | p_gpioinib->txspeed_set);
+	sil_wrw_mem((uint32_t *)(txbase+TOFF_GPIO_OTYPER), (sil_rew_mem((uint32_t *)(txbase+TOFF_GPIO_OTYPER)) & p_gpioinib->txtype_msk) | p_gpioinib->txtype_set);
+	sil_wrw_mem((uint32_t *)(txbase+TOFF_GPIO_PUPDR), (sil_rew_mem((uint32_t *)(txbase+TOFF_GPIO_PUPDR)) & p_gpioinib->txpupd_msk) | p_gpioinib->txpupd_set);
+	sil_wrw_mem((uint32_t *)(rxbase+TOFF_GPIO_MODER), (sil_rew_mem((uint32_t *)(rxbase+TOFF_GPIO_MODER)) & p_gpioinib->rxmode_msk) | p_gpioinib->rxmode_set);
+	sil_wrw_mem((uint32_t *)(rxbase+TOFF_GPIO_OSPEEDR), (sil_rew_mem((uint32_t *)(rxbase+TOFF_GPIO_OSPEEDR)) & p_gpioinib->rxspeed_msk) | p_gpioinib->rxspeed_set);
+	sil_wrw_mem((uint32_t *)(rxbase+TOFF_GPIO_OTYPER), (sil_rew_mem((uint32_t *)(rxbase+TOFF_GPIO_OTYPER)) & p_gpioinib->rxtype_msk) | p_gpioinib->rxtype_set);
+	sil_wrw_mem((uint32_t *)(rxbase+TOFF_GPIO_PUPDR), (sil_rew_mem((uint32_t *)(txbase+TOFF_GPIO_PUPDR)) & p_gpioinib->rxpupd_msk) | p_gpioinib->rxpupd_set);
+	setup_gpio_source(txbase, p_gpioinib->txpinport, p_gpioinib->gpio_af);
+	setup_gpio_source(rxbase, p_gpioinib->rxpinport, p_gpioinib->gpio_af);
+
+	tmp = sil_rew_mem((uint32_t *)(base+TOFF_USART_CR2)) & ~USART_CR2_STOP;
+	sil_wrw_mem((uint32_t *)(base+TOFF_USART_CR2), tmp | USART_StopBits_1);
+	tmp = sil_rew_mem((uint32_t *)(base+TOFF_USART_CR1)) & ~CR1_CLEAR_MASK;
+	sil_wrw_mem((uint32_t *)(base+TOFF_USART_CR1), tmp | USART_WordLength_8b | USART_Parity_No | USART_CR1_RE | USART_CR1_TE);
+	tmp = sil_rew_mem((uint32_t *)(base+TOFF_USART_CR3)) & ~CR3_CLEAR_MASK;
+	sil_wrw_mem((uint32_t *)(base+TOFF_USART_CR3), tmp | USART_HardwareFlowControl_None);
+
+	switch((sil_rew_mem((uint32_t *)(TADR_RCC_BASE+TOFF_RCC_DCKCFGR2)) >> p_siopinib->clock_shift) & 3){
+	case SOURCE_HSI:
+		tmp = HSI_VALUE;
+		break;
+	case SOURCE_SYSCLK:
+		tmp = SysFreHCLK;
+		break;
+	case SOURCE_LSE:
+		tmp = LSE_VALUE;
+		break;
+	case SOURCE_PCLK2:
+	default:
+		if(p_siopinib->clock_shift == 10)	/* USART6,1の場合 PCLK2 */
+			tmp = SysFrePCLK2;
+		else
+			tmp = SysFrePCLK1;
+		break;
+	}
+	sil_wrw_mem((uint32_t *)(base+TOFF_USART_BRR), tmp/BPS_SETTING);
+	sil_wrw_mem((uint32_t *)(base+TOFF_USART_CR2), sil_rew_mem((uint32_t *)(base+TOFF_USART_CR2)) & ~(USART_CR2_LINEN | USART_CR2_CLKEN));
+	sil_wrw_mem((uint32_t *)(base+TOFF_USART_CR3), sil_rew_mem((uint32_t *)(base+TOFF_USART_CR3)) & ~(USART_CR3_SCEN | USART_CR3_HDSEL | USART_CR3_IREN));
+
+	sil_wrw_mem((uint32_t *)(base+TOFF_USART_CR1), sil_rew_mem((uint32_t *)(base+TOFF_USART_CR1)) | USART_CR1_UE);
+
+	/*
+	 * RX/TX ACKがセットされるまで待つ
+	 */
+	tmp = 0;
+    while((sil_rew_mem((uint32_t *)(base+TOFF_USART_ISR)) & ISR_ACK) != ISR_ACK){
+		/* Check for the Timeout */
+		if(tmp >=  UART_TIMEOUT_VALUE){
+			/* Disable TXE, RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts for the interrupt process */
+			sil_wrw_mem((uint32_t *)(base+TOFF_USART_CR1),
+				sil_rew_mem((uint32_t *)(base+TOFF_USART_CR1)) & ~(USART_CR1_TXEIE | USART_CR1_RXNEIE | USART_CR1_PEIE));
+			sil_wrw_mem((uint32_t *)(base+TOFF_USART_CR3),
+				sil_rew_mem((uint32_t *)(base+TOFF_USART_CR3)) & ~USART_CR3_EIE);
+			goto sio_opn_exit;
+		}
+		sil_dly_nse(1000);
+		tmp++;
+	}
+
+	sil_wrw_mem((uint32_t *)(base+TOFF_USART_CR1), sil_rew_mem((uint32_t *)(base+TOFF_USART_CR1)) | USART_CR1_PEIE);
+	sil_wrw_mem((uint32_t *)(base+TOFF_USART_CR3), sil_rew_mem((uint32_t *)(base+TOFF_USART_CR3)) | USART_CR3_EIE);
+	sil_wrw_mem((uint32_t *)(base+TOFF_USART_CR1), sil_rew_mem((uint32_t *)(base+TOFF_USART_CR1)) | USART_CR1_RXNEIE);
+	p_siopcb->opnflg = true;
+
+	/*
+	 *  シリアルI/O割込みのマスクを解除する．
+	 */
+	if (!opnflg) {
+		ercd = ena_int(p_siopinib->intno_usart);
+		assert(ercd == E_OK);
+	}
+
+sio_opn_exit:;
+	return(p_siopcb);
+}
+
+/*
+ *  シリアルI/Oポートのクローズ
+ */
+void
+sio_cls_por(SIOPCB *p_siopcb)
+{
+	const SIOPINIB  *p_siopinib;
+	const GPIOINIB  *p_gpioinib;
+	uint32_t base, tmp;
+
+	/*
+	 *  シリアルI/O割込みをマスクする．
+	 */
+	if ((p_siopcb->opnflg)) {
+		dis_int(p_siopcb->p_siopinib->intno_usart);
+	}
+
+	/*
+	 *  ハードウェアのリセット
+	 */
+	p_siopinib = p_siopcb->p_siopinib;
+	p_gpioinib = p_siopcb->p_gpioinib;
+	base = p_siopinib->base;
+	sil_wrw_mem((uint32_t *)(base+TOFF_USART_ICR), 0xFFFFFFFF);
+	sil_wrw_mem((uint32_t *)(base+TOFF_USART_CR1), sil_rew_mem((uint32_t *)(base+TOFF_USART_CR1)) & ~USART_CR1_UE);
+	sil_wrw_mem((uint32_t *)(base+TOFF_USART_CR1), 0x0);
+	sil_wrw_mem((uint32_t *)(base+TOFF_USART_CR2), 0x0);
+	sil_wrw_mem((uint32_t *)(base+TOFF_USART_CR3), 0x0);
+	tmp = sil_rew_mem((uint32_t *)p_gpioinib->resetbase);
+	sil_wrw_mem((uint32_t *)p_gpioinib->resetbase, tmp | p_gpioinib->reset_set);
+	sil_wrw_mem((uint32_t *)p_gpioinib->resetbase, tmp & ~(p_gpioinib->reset_set));
+	p_siopcb->opnflg = false;
+}
+
+/*
+ *  SIOの割込みサービスルーチン
+ */
+
+Inline bool_t
+sio_putready(SIOPCB* p_siopcb)
+{
+	uint32_t cr1 = sil_rew_mem((uint32_t *)(p_siopcb->p_siopinib->base+TOFF_USART_CR1));
+	uint32_t isr = sil_rew_mem((uint32_t *)(p_siopcb->p_siopinib->base+TOFF_USART_ISR));
+
+	if ((cr1 & USART_CR1_TXEIE) != 0 && (isr & USART_ISR_TXE) != 0)
+	{
+		return 1;
+	}
+	return 0;
+}
+
+Inline bool_t
+sio_getready(SIOPCB* p_siopcb)
+{
+	uint32_t base = p_siopcb->p_siopinib->base;
+	uint32_t cr1, cr3, isr;
+
+	cr1 = sil_rew_mem((uint32_t *)(base+TOFF_USART_CR1));
+	cr3 = sil_rew_mem((uint32_t *)(base+TOFF_USART_CR3));
+	isr = sil_rew_mem((uint32_t *)(base+TOFF_USART_ISR));
+
+	if((isr & USART_ISR_PE) != 0 && (cr3 & USART_CR3_EIE) != 0){
+		sil_wrw_mem((uint32_t *)(base+TOFF_USART_ICR), USART_ICR_PECF);
+	}
+	if((isr & USART_ISR_FE) != 0 && (cr3 & USART_CR3_EIE) != 0){
+		sil_wrw_mem((uint32_t *)(base+TOFF_USART_ICR), USART_ICR_FECF);
+	}
+	if((isr & USART_ISR_NE) != 0 && (cr3 & USART_CR3_EIE) != 0){
+		sil_wrw_mem((uint32_t *)(base+TOFF_USART_ICR), USART_ICR_NCF);
+	}
+	if((isr & USART_ISR_ORE) != 0 && (cr3 & USART_CR3_EIE) != 0){
+		sil_wrw_mem((uint32_t *)(base+TOFF_USART_ICR), USART_ICR_ORECF);
+	}
+	if ((cr1 & USART_CR1_RXNEIE) != 0 && (isr & USART_ISR_RXNE) != 0)
+	{
+		return 1;
+	}
+	return 0;
+}
+
+void
+sio_usart_isr(intptr_t exinf)
+{
+	if ((exinf <= 0) || (exinf > TNUM_SIOP))
+		return;
+
+	SIOPCB *p_siopcb = get_siopcb(exinf);
+	if (!p_siopcb->opnflg)
+		return;
+
+	if (sio_getready(p_siopcb)) {
+		sio_irdy_rcv(p_siopcb->exinf);
+	}
+	if (sio_putready(p_siopcb)) {
+		sio_irdy_snd(p_siopcb->exinf);
+	}
+}
+
+/*
+ *  シリアルI/Oポートへの文字送信
+ */
+bool_t
+sio_snd_chr(SIOPCB *p_siopcb, char c)
+{
+	uint32_t base = p_siopcb->p_siopinib->base;
+
+	if (sio_putready(p_siopcb)) {
+		sil_wrw_mem((uint32_t *)(base+TOFF_USART_TDR), (uint32_t)c);
+		return true;
+	}
+	return false;
+}
+
+/*
+ *  シリアルI/Oポートからの文字受信
+ */
+int_t
+sio_rcv_chr(SIOPCB *p_siopcb)
+{
+	uint32_t base = p_siopcb->p_siopinib->base;
+	int_t c = -1;
+
+	if (sio_getready(p_siopcb)) {
+		c = sil_rew_mem((uint32_t *)(base+TOFF_USART_RDR)) & 0xFF;
+	}
+	return c;
+}
+
+/*
+ *  シリアルI/Oポートからのコールバックの許可
+ */
+void
+sio_ena_cbr(SIOPCB *p_siopcb, uint_t cbrtn)
+{
+	uint32_t base = p_siopcb->p_siopinib->base;
+
+	switch (cbrtn) {
+	case SIO_RDY_SND:
+		sil_wrw_mem((uint32_t *)(base+TOFF_USART_CR1), sil_rew_mem((uint32_t *)(base+TOFF_USART_CR1)) | USART_CR1_TXEIE);
+		break;
+	case SIO_RDY_RCV:
+		sil_wrw_mem((uint32_t *)(base+TOFF_USART_CR1), sil_rew_mem((uint32_t *)(base+TOFF_USART_CR1)) | USART_CR1_RXNEIE);
+		break;
+	}
+}
+
+/*
+ *  シリアルI/Oポートからのコールバックの禁止
+ */
+void
+sio_dis_cbr(SIOPCB *p_siopcb, uint_t cbrtn)
+{
+	uint32_t base = p_siopcb->p_siopinib->base;
+
+	switch (cbrtn) {
+	case SIO_RDY_SND:
+		sil_wrw_mem((uint32_t *)(base+TOFF_USART_CR1), sil_rew_mem((uint32_t *)(base+TOFF_USART_CR1)) & ~USART_CR1_TXEIE);
+		break;
+	case SIO_RDY_RCV:
+		sil_wrw_mem((uint32_t *)(base+TOFF_USART_CR1), sil_rew_mem((uint32_t *)(base+TOFF_USART_CR1)) & ~USART_CR1_RXNEIE);
+		break;
+	}
+}
+
+/*
+ *  1文字出力（ポーリングでの出力）
+ */
+void sio_pol_snd_chr(int8_t c, ID siopid)
+{
+	uint32_t base = siopinib_table[INDEX_PORT(siopid)].base;
+
+	sil_wrw_mem((uint32_t *)(base+TOFF_USART_TDR), (uint32_t)c);
+	while(0 == (sil_rew_mem((uint32_t *)(base+TOFF_USART_ISR)) & USART_ISR_TXE));
+
+	/*
+	 *  出力が完全に終わるまで待つ
+	 */
+	volatile int n = 300000000/BPS_SETTING;
+	while(n--);
+}
+
+/*
+ *  ターゲットのシリアル初期化
+ */
+void chip_uart_init(ID siopid)
+{
+	const GPIOINIB  *p_gpioinib = &gpioinib_table[INDEX_PORT(siopid)];
+	const SIOPINIB  *p_siopinib = &siopinib_table[INDEX_PORT(siopid)];
+	uint32_t base, txbase, rxbase, tmp;
+
+	txbase = p_gpioinib->txportbase;
+	rxbase = p_gpioinib->rxportbase;
+	base = p_siopinib->base;
+
+	sil_wrw_mem((uint32_t *)(base+TOFF_USART_CR1), sil_rew_mem((uint32_t *)(base+TOFF_USART_CR1)) & ~USART_CR1_UE);
+	sil_wrw_mem((uint32_t *)(base+TOFF_USART_CR1), 0x0);
+	sil_wrw_mem((uint32_t *)(base+TOFF_USART_CR2), 0x0);
+	sil_wrw_mem((uint32_t *)(base+TOFF_USART_CR3), 0x0);
+	tmp = sil_rew_mem((uint32_t *)p_gpioinib->resetbase);
+	sil_wrw_mem((uint32_t *)p_gpioinib->resetbase, tmp | p_gpioinib->reset_set);
+	sil_wrw_mem((uint32_t *)p_gpioinib->resetbase, tmp & ~(p_gpioinib->reset_set));
+
+	if(p_siopinib->clock_shift == 0){	/* USART1の場合、SYSLOCKを設定 */
+		sil_wrw_mem((uint32_t *)(TADR_RCC_BASE+TOFF_RCC_DCKCFGR2),
+			(sil_rew_mem((uint32_t *)(TADR_RCC_BASE+TOFF_RCC_DCKCFGR2)) & RCC_DCKCFGR2_USART1SEL) | RCC_DCKCFGR2_USART1SEL_0);
+	}
+	else if(p_siopinib->clock_shift == 10){	/* F723/USART6の場合、SYSLOCKを設定 */
+		sil_wrw_mem((uint32_t *)(TADR_RCC_BASE+TOFF_RCC_DCKCFGR2),
+			(sil_rew_mem((uint32_t *)(TADR_RCC_BASE+TOFF_RCC_DCKCFGR2)) & RCC_DCKCFGR2_USART6SEL) | RCC_DCKCFGR2_USART6SEL_0);
+	}
+
+	sil_wrw_mem((uint32_t *)p_gpioinib->clockbase, sil_rew_mem((uint32_t *)p_gpioinib->clockbase) | p_gpioinib->clock_set);
+	sil_wrw_mem((uint32_t *)p_gpioinib->portbase, sil_rew_mem((uint32_t *)p_gpioinib->portbase) | p_gpioinib->txport_set);
+	sil_wrw_mem((uint32_t *)p_gpioinib->portbase, sil_rew_mem((uint32_t *)p_gpioinib->portbase) | p_gpioinib->rxport_set);
+	sil_wrw_mem((uint32_t *)(txbase+TOFF_GPIO_MODER), (sil_rew_mem((uint32_t *)(txbase+TOFF_GPIO_MODER)) & p_gpioinib->txmode_msk) | p_gpioinib->txmode_set);
+	sil_wrw_mem((uint32_t *)(txbase+TOFF_GPIO_OSPEEDR), (sil_rew_mem((uint32_t *)(txbase+TOFF_GPIO_OSPEEDR)) & p_gpioinib->txspeed_msk) | p_gpioinib->txspeed_set);
+	sil_wrw_mem((uint32_t *)(txbase+TOFF_GPIO_OTYPER), (sil_rew_mem((uint32_t *)(txbase+TOFF_GPIO_OTYPER)) & p_gpioinib->txtype_msk) | p_gpioinib->txtype_set);
+	sil_wrw_mem((uint32_t *)(txbase+TOFF_GPIO_PUPDR), (sil_rew_mem((uint32_t *)(txbase+TOFF_GPIO_PUPDR)) & p_gpioinib->txpupd_msk) | p_gpioinib->txpupd_set);
+	sil_wrw_mem((uint32_t *)(rxbase+TOFF_GPIO_MODER), (sil_rew_mem((uint32_t *)(rxbase+TOFF_GPIO_MODER)) & p_gpioinib->rxmode_msk) | p_gpioinib->rxmode_set);
+	sil_wrw_mem((uint32_t *)(rxbase+TOFF_GPIO_OSPEEDR), (sil_rew_mem((uint32_t *)(rxbase+TOFF_GPIO_OSPEEDR)) & p_gpioinib->rxspeed_msk) | p_gpioinib->rxspeed_set);
+	sil_wrw_mem((uint32_t *)(rxbase+TOFF_GPIO_OTYPER), (sil_rew_mem((uint32_t *)(rxbase+TOFF_GPIO_OTYPER)) & p_gpioinib->rxtype_msk) | p_gpioinib->rxtype_set);
+	sil_wrw_mem((uint32_t *)(rxbase+TOFF_GPIO_PUPDR), (sil_rew_mem((uint32_t *)(txbase+TOFF_GPIO_PUPDR)) & p_gpioinib->rxpupd_msk) | p_gpioinib->rxpupd_set);
+	setup_gpio_source(txbase, p_gpioinib->txpinport, p_gpioinib->gpio_af);
+	setup_gpio_source(rxbase, p_gpioinib->rxpinport, p_gpioinib->gpio_af);
+
+	tmp = sil_rew_mem((uint32_t *)(base+TOFF_USART_CR2)) & ~USART_CR2_STOP;
+	sil_wrw_mem((uint32_t *)(base+TOFF_USART_CR2), tmp | USART_StopBits_1);
+	tmp = sil_rew_mem((uint32_t *)(base+TOFF_USART_CR1)) & ~CR1_CLEAR_MASK;
+	sil_wrw_mem((uint32_t *)(base+TOFF_USART_CR1), tmp | USART_WordLength_8b | USART_Parity_No | USART_CR1_RE | USART_CR1_TE);
+	tmp = sil_rew_mem((uint32_t *)(base+TOFF_USART_CR3)) & ~CR3_CLEAR_MASK;
+	sil_wrw_mem((uint32_t *)(base+TOFF_USART_CR3), tmp | USART_HardwareFlowControl_None);
+
+	switch((sil_rew_mem((uint32_t *)(TADR_RCC_BASE+TOFF_RCC_DCKCFGR2)) >> p_siopinib->clock_shift) & 3){
+	case SOURCE_HSI:
+		tmp = HSI_VALUE;
+		break;
+	case SOURCE_SYSCLK:
+		tmp = SysFreHCLK;
+		break;
+	case SOURCE_LSE:
+		tmp = LSE_VALUE;
+		break;
+	case SOURCE_PCLK2:
+	default:
+		if(p_siopinib->clock_shift == 10)	/* USART6,1の場合 PCLK2 */
+			tmp = SysFrePCLK2;
+		else
+			tmp = SysFrePCLK1;
+		break;
+	}
+	sil_wrw_mem((uint32_t *)(base+TOFF_USART_BRR), tmp/BPS_SETTING);
+	sil_wrw_mem((uint32_t *)(base+TOFF_USART_CR1), sil_rew_mem((uint32_t *)(base+TOFF_USART_CR1)) | USART_CR1_UE);
+}
+
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/arch/arm_m_gcc/stm32f7xx/chip_serial.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/arch/arm_m_gcc/stm32f7xx/chip_serial.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/arch/arm_m_gcc/stm32f7xx/chip_serial.h	(revision 457)
@@ -0,0 +1,124 @@
+/*
+ *  TOPPERS/ASP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Advanced Standard Profile Kernel
+ * 
+ *  Copyright (C) 2008-2011 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ *  Copyright (C) 2015      by 3rd Designing Center
+ *              Imageing System Development Division RICOH COMPANY, LTD.
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *    シリアルI/Oデバイス（SIO）ドライバ
+ */
+
+#ifndef TOPPERS_CHIP_SERIAL_H
+#define TOPPERS_CHIP_SERIAL_H
+
+#ifndef TOPPERS_MACRO_ONLY
+
+/*
+ *  シリアルI/Oポート管理ブロックの定義
+ */
+typedef struct sio_port_control_block    SIOPCB;
+
+/*
+ *  コールバックルーチンの識別番号
+ */
+#define SIO_RDY_SND    1U        /* 送信可能コールバック */
+#define SIO_RDY_RCV    2U        /* 受信通知コールバック */
+
+/*
+ *  SIOドライバの初期化
+ */
+extern void sio_initialize(intptr_t exinf);
+
+/*
+ *  シリアルI/Oポートのオープン
+ */
+extern SIOPCB *sio_opn_por(ID siopid, intptr_t exinf);
+
+/*
+ *  シリアルI/Oポートのクローズ
+ */
+extern void sio_cls_por(SIOPCB *p_siopcb);
+
+/*
+ *  SIOの割込みサービスルーチン
+ */
+extern void sio_usart_isr(intptr_t exinf);
+
+/*
+ *  シリアルI/Oポートへの文字送信
+ */
+extern bool_t sio_snd_chr(SIOPCB *p_siopcb, char c);
+
+/*
+ *  シリアルI/Oポートからの文字受信
+ */
+extern int_t sio_rcv_chr(SIOPCB *p_siopcb);
+
+/*
+ *  シリアルI/Oポートからのコールバックの許可
+ */
+extern void sio_ena_cbr(SIOPCB *p_siopcb, uint_t cbrtn);
+
+/*
+ *  シリアルI/Oポートからのコールバックの禁止
+ */
+extern void sio_dis_cbr(SIOPCB *p_siopcb, uint_t cbrtn);
+
+/*
+ *  シリアルI/Oポートからの送信可能コールバック
+ */
+extern void sio_irdy_snd(intptr_t exinf);
+
+/*
+ *  シリアルI/Oポートからの受信通知コールバック
+ */
+extern void sio_irdy_rcv(intptr_t exinf);
+
+/*
+ *  1文字送信（ポーリングでの出力）
+ */
+extern void sio_pol_snd_chr(int8_t c, ID siopid);
+
+/*
+ *  ターゲットのシリアル初期化
+ */
+extern void chip_uart_init(ID siopid);
+
+#endif /* TOPPERS_MACRO_ONLY */
+#endif /* TOPPERS_CHIP_SERIAL_H */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/arch/arm_m_gcc/stm32f7xx/chip_sil.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/arch/arm_m_gcc/stm32f7xx/chip_sil.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/arch/arm_m_gcc/stm32f7xx/chip_sil.h	(revision 457)
@@ -0,0 +1,69 @@
+/*
+ *  TOPPERS Software
+ *      Toyohashi Open Platform for Embedded Real-Time Systems
+ * 
+ *  Copyright (C) 2008-2011 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ *  Copyright (C) 2015      by 3rd Designing Center
+ *              Imageing System Development Division RICOH COMPANY, LTD.
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *   sil.hのチップ依存部（stm32f7xx用）
+ *
+ *  このインクルードファイルは，sil.hの先頭でインクルードされる．他のファ
+ *  イルからは直接インクルードすることはない．このファイルをインクルー
+ *  ドする前に，t_stddef.hがインクルードされるので，それらに依存しても
+ *  よい．
+ */
+
+#ifndef TOPPERS_CHIP_SIL_H
+#define TOPPERS_CHIP_SIL_H
+
+/*
+ *  割込み優先度のビット幅
+ */
+#define TBITW_IPRI          4
+
+/*
+ *  プロセッサのエンディアン
+ */
+#define SIL_ENDIAN_LITTLE
+
+/*
+ *  コア依存で共通な定義
+ */
+#include "core_sil.h"
+
+#endif /* TOPPERS_CHIP_SIL_H */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/arch/arm_m_gcc/stm32f7xx/chip_timer.cfg
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/arch/arm_m_gcc/stm32f7xx/chip_timer.cfg	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/arch/arm_m_gcc/stm32f7xx/chip_timer.cfg	(revision 457)
@@ -0,0 +1,5 @@
+/*
+ *    タイマドライバのコンフィギュレーションファイル
+ */
+#include "target_timer.h"
+INCLUDE("arm_m_gcc/common/core_timer.cfg");
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/arch/arm_m_gcc/stm32f7xx/chip_timer.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/arch/arm_m_gcc/stm32f7xx/chip_timer.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/arch/arm_m_gcc/stm32f7xx/chip_timer.h	(revision 457)
@@ -0,0 +1,66 @@
+/*
+ *  TOPPERS/ASP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Advanced Standard Profile Kernel
+ * 
+ *  Copyright (C) 2008-2011 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ *  Copyright (C) 2015      by 3rd Designing Center
+ *              Imageing System Development Division RICOH COMPANY, LTD.
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *  タイマドライバ（stm32f7xx用）
+ */
+
+#ifndef TOPPERS_CHIP_TIMER_H
+#define TOPPERS_CHIP_TIMER_H
+
+/*
+ *  タイマ値の内部表現とミリ秒単位との変換
+ */
+#define TIMER_CLOCK		(SYS_CLOCK / 1000)
+
+/*
+ *  タイマ割込みハンドラ登録のための定数
+ */
+#define INTPRI_TIMER    (-6)          /* 割込み優先度 */
+#define INTATR_TIMER    0U            /* 割込み属性 */
+
+/*
+ *  コア依存モジュール（ARM-M用）
+ */
+#include "arm_m_gcc/common/core_timer.h"
+
+#endif /* TOPPERS_CHIP_TIMER_H */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/arch/arm_m_gcc/stm32f7xx/chip_unrename.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/arch/arm_m_gcc/stm32f7xx/chip_unrename.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/arch/arm_m_gcc/stm32f7xx/chip_unrename.h	(revision 457)
@@ -0,0 +1,27 @@
+/* This file is generated from target_rename.def by genrename. */
+
+/* This file is included only when target_rename.h has been included. */
+#ifdef TOPPERS_CHIP_RENAME_H
+#undef TOPPERS_CHIP_RENAME_H
+
+
+/*
+ * chip_config.c
+ */
+#undef target_initialize
+#undef target_exit
+
+#ifdef TOPPERS_LABEL_ASM
+
+
+/*
+ * chip_config.c
+ */
+#undef _target_initialize
+#undef _target_exit
+
+#endif /* TOPPERS_LABEL_ASM */
+
+#include "arm_m_gcc/common/core_unrename.h"
+
+#endif /* TOPPERS_CHIP_RENAME_H */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/arch/arm_m_gcc/stm32f7xx/cmsis_f7.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/arch/arm_m_gcc/stm32f7xx/cmsis_f7.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/arch/arm_m_gcc/stm32f7xx/cmsis_f7.h	(revision 457)
@@ -0,0 +1,442 @@
+/*
+ *  TOPPERS/ASP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Just Standard Profile Kernel
+ * 
+ *  Copyright (C) 2015      by 3rd Designing Center
+ *              Imageing System Development Division RICOH COMPANY, LTD.
+ *
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+#ifndef _CMSIS_F7_H_
+#define _CMSIS_F7_H_
+
+/*
+ *  SIL TYPE to ACCESS the INSTRUCTATION TRACE MACROCELL REGISTER (ITM).
+ */
+#define TADR_ITM_BASE       (0xE0000000UL)				/* ITM Base Address */
+#define TOFF_ITM_PORT       0x0000		/* (W)  ITM Stimulus Port Registers */
+#define TOFF_ITM_TER        0x0E00		/* (RW) ITM Trace Enable Register */
+#define TOFF_ITM_TPR        0x0E40		/* (RW) ITM Trace Privilege Register */
+#define TOFF_ITM_TCR        0x0E80		/* (RW) ITM Trace Control Register */
+#define TOFF_ITM_IWR        0x0EF8		/* (W)  ITM Integration Write Register */
+#define TOFF_ITM_IRR        0x0EFC		/* (R)  ITM Integration Read Register */
+#define TOFF_ITM_IMCR       0x0F00		/* (RW) ITM Integration Mode Control Register */
+#define TOFF_ITM_LAR        0x0FB0		/* (W)  ITM Lock Access Register */
+#define TOFF_ITM_LSR        0x0FB4		/* (R)  ITM Lock Status Register */
+#define TOFF_ITM_PID4       0x0FD0		/* (R)  ITM Peripheral Identification Register #4 */
+#define TOFF_ITM_PID5       0x0FD4		/* (R)  ITM Peripheral Identification Register #5 */
+#define TOFF_ITM_PID6       0x0FD8		/* (R)  ITM Peripheral Identification Register #6 */
+#define TOFF_ITM_PID7       0x0FDC		/* (R)  ITM Peripheral Identification Register #7 */
+#define TOFF_ITM_PID0       0x0FE0		/* (R)  ITM Peripheral Identification Register #0 */
+#define TOFF_ITM_PID1       0x0FE4		/* (R)  ITM Peripheral Identification Register #1 */
+#define TOFF_ITM_PID2       0x0FE8		/* (R)  ITM Peripheral Identification Register #2 */
+#define TOFF_ITM_PID3       0x0FEC		/* (R)  ITM Peripheral Identification Register #3 */
+#define TOFF_ITM_CID0       0x0FF0		/* (R)  ITM Component  Identification Register #0 */
+#define TOFF_ITM_CID1       0x0FF4		/* (R)  ITM Component  Identification Register #1 */
+#define TOFF_ITM_CID2       0x0FF8		/* (R)  ITM Component  Identification Register #2 */
+#define TOFF_ITM_CID3       0x0FFC		/* (R)  ITM Component  Identification Register #3 */
+
+/*
+ *  SIL TYPE to ACCESS the Data Watchpoint and Trace Register (DWT).
+ */
+#define TADR_DWT_BASE       (0xE0001000UL)				/* DWT Base Address */
+#define TOFF_DWT_CTRL       0x0000		/* (RW)  Control Register */
+#define TOFF_DWT_CYCCNT     0x0004		/* (RW)  Cycle Count Register */
+#define TOFF_DWT_CPICNT     0x0008		/* (RW)  CPI Count Register */
+#define TOFF_DWT_EXCCNT     0x000C		/* (RW)  Exception Overhead Count Register */
+#define TOFF_DWT_SLEEPCNT   0x0010		/* (RW)  Sleep Count Register */
+#define TOFF_DWT_LSUCNT     0x0014		/* (RW)  LSU Count Register */
+#define TOFF_DWT_FOLDCNT    0x0018		/* (RW)  Folded-instruction Count Register */
+#define TOFF_DWT_PCSR       0x001C		/* (R )  Program Counter Sample Register */
+#define TOFF_DWT_COMP0      0x0020		/* (RW)  Comparator Register 0 */
+#define TOFF_DWT_MASK0      0x0024		/* (RW)  Mask Register 0 */
+#define TOFF_DWT_FUNCTION0  0x0028		/* (RW)  Function Register 0 */
+#define TOFF_DWT_COMP1      0x0030		/* (RW)  Comparator Register 1 */
+#define TOFF_DWT_MASK1      0x0034		/* (RW)  Mask Register 1 */
+#define TOFF_DWT_FUNCTION1  0x0038		/* (RW)  Function Register 1 */
+#define TOFF_DWT_COMP2      0x0040		/* (RW)  Comparator Register 2 */
+#define TOFF_DWT_MASK2      0x0044		/* (RW)  Mask Register 2 */
+#define TOFF_DWT_FUNCTION2  0x0048		/* (RW)  Function Register 2 */
+#define TOFF_DWT_COMP3      0x0050		/* (RW)  Comparator Register 3 */
+#define TOFF_DWT_MASK3      0x0054		/* (RW)  Mask Register 3 */
+#define TOFF_DWT_FUNCTION3  0x0058		/* (RW)  Function Register 3 */
+#define TOFF_DWT_LAR        0x0FB0		/* (W)  Lock Access Register */
+#define TOFF_DWT_LSR        0x0FB4		/* (R)  Lock Status Register */
+
+/*
+ *  SIL TYPE to ACCESS the SYSTEM CONTROL and ID RREGISTER not in the SCB.
+ */
+#define TADR_SCS_BASE       (0xE000E000UL)				/* System Control Space Base Address  */
+#define TOFF_SCS_ICTR       0x0004		/* (R)  Interrupt Controller Type Register */
+#define TOFF_SCS_ACTLR      0x0008		/* (RW) Auxiliary Control Register */
+
+/*
+ *  SIL TYPE to ACCESS THE SYSTEM TIMER (SysTick).
+ */
+#define TADR_SYSTICK_BASE   (TADR_SCS_BASE+0x0010UL)	/* SysTick Base Address */
+#define TOFF_SYSTICK_CTRL   0x0000		/* (RW) SysTick Control and Status Register */
+#define TOFF_SYSTICK_LOAD   0x0004		/* (RW) SysTick Reload Value Register */
+#define TOFF_SYSTICK_VAL    0x0008		/* (RW) SysTick Current Value Register */
+#define TOFF_SYSTICK_CALIB  0x000C		/* (R)  SysTick Calibration Register */
+
+/*
+ *  SIL TYPE to ACCESS the NESTE VECTORED INTERRUPT CONTROLLER (NVIC).
+ */
+#define TADR_NVIC_BASE      (TADR_SCS_BASE+0x0100UL)	/* NVIC Base Address */
+#define TOFF_NVIC_ISER      0x0000		/* (RW) Interrupt Set Enable Register */
+#define TOFF_NVIC_ICER      0x0080		/* (RW) Interrupt Clear Enable Register */
+#define TOFF_NVIC_ISPR      0x0100		/* (RW) Interrupt Set Pending Register */
+#define TOFF_NVIC_ICPR      0x0180		/* (RW) Interrupt Clear Pending Register */
+#define TOFF_NVIC_IABR      0x0200		/* (RW) Interrupt Active bit Register */
+#define TOFF_NVIC_IP        0x0300		/* (RW) Interrupt Priority Register (8Bit wide) */
+#define TOFF_NVIC_STIR      0x0E00		/* (W)  Software Trigger Interrupt Register */
+
+/*
+ *  SIL TYPE to ACCESS the SYSTEM CONTROL BLOCK (SCB).
+ */
+#define TADR_SCB_BASE       (TADR_SCS_BASE+0x0D00UL)	/* System Control Block Base Address  */
+#define TOFF_SCB_CPUID      0x0000		/* (R)  CPUID Base Register */
+#define TOFF_SCB_ICSR       0x0004		/* (RW) Interrupt Control and State Register */
+#define TOFF_SCB_VTOR       0x0008		/* (RW) Vector Table Offset Register */
+#define TOFF_SCB_AIRCR      0x000C		/* (RW) Application Interrupt and Reset Control Register */
+  #define SCB_VTOR_TBLOFF_Pos         7                                    /* TBLOFF Position */
+  #define SCB_VTOR_TBLOFF_Msk         (0x1FFFFFF << SCB_VTOR_TBLOFF_Pos)   /* TBLOFF Mask */
+  #define SCB_AIRCR_VECTKEY_Pos       16                                   /* VECTKEY Position */
+  #define SCB_AIRCR_VECTKEY_Msk       (0xFFFF << SCB_AIRCR_VECTKEY_Pos)    /* VECTKEY Mask */
+  #define SCB_AIRCR_VECTKEYSTAT_Pos   16                                   /* VECTKEYSTAT Position */
+  #define SCB_AIRCR_VECTKEYSTAT_Msk   (0xFFFF << SCB_AIRCR_VECTKEYSTAT_Pos)/* VECTKEYSTAT Mask */
+  #define SCB_AIRCR_ENDIANESS_Pos     15                                   /* ENDIANESS Position */
+  #define SCB_AIRCR_ENDIANESS_Msk     (1 << SCB_AIRCR_ENDIANESS_Pos)       /* ENDIANESS Mask */
+  #define SCB_AIRCR_PRIGROUP_Pos      8                                    /* PRIGROUP Position */
+  #define SCB_AIRCR_PRIGROUP_Msk      (7 << SCB_AIRCR_PRIGROUP_Pos)        /* PRIGROUP Mask */
+  #define SCB_AIRCR_SYSRESETREQ_Pos   2                                    /* SYSRESETREQ Position */
+  #define SCB_AIRCR_SYSRESETREQ_Msk   (1 << SCB_AIRCR_SYSRESETREQ_Pos)     /* SYSRESETREQ Mask */
+  #define SCB_AIRCR_VECTCLRACTIVE_Pos 1                                    /* VECTCLRACTIVE Position */
+  #define SCB_AIRCR_VECTCLRACTIVE_Msk (1 << SCB_AIRCR_VECTCLRACTIVE_Pos)   /* VECTCLRACTIVE Mask */
+  #define SCB_AIRCR_VECTRESET_Pos     0                                    /* VECTRESET Position */
+  #define SCB_AIRCR_VECTRESET_Msk     (1 /*<< SCB_AIRCR_VECTRESET_Pos*/)   /* VECTRESET Mask */
+#define TOFF_SCB_SCR        0x0010		/* (RW) System Control Register */
+  #define SCB_SCR_SEVONPEND_Pos       4                                    /* SEVONPEND Position */
+  #define SCB_SCR_SEVONPEND_Msk       (1 << SCB_SCR_SEVONPEND_Pos)         /* SEVONPEND Mask */
+  #define SCB_SCR_SLEEPDEEP_Pos       2                                    /* SLEEPDEEP Position */
+  #define SCB_SCR_SLEEPDEEP_Msk       (1 << SCB_SCR_SLEEPDEEP_Pos)         /* SLEEPDEEP Mask */
+  #define SCB_SCR_SLEEPONEXIT_Pos     1                                    /* SCB SCR: SLEEPONEXIT Position */
+  #define SCB_SCR_SLEEPONEXIT_Msk     (1 << SCB_SCR_SLEEPONEXIT_Pos)       /* SCB SCR: SLEEPONEXIT Mask */
+#define TOFF_SCB_CCR        0x0014		/* (RW) Configuration Control Register */
+  #define SCB_CCR_BP_Pos              18                                   /* Branch prediction enable bit Position */
+  #define SCB_CCR_BP_Msk              (1 << SCB_CCR_BP_Pos)                /* Branch prediction enable bit Mask */
+  #define SCB_CCR_IC_Pos              17                                   /* Instruction cache enable bit Position */
+  #define SCB_CCR_IC_Msk              (1 << SCB_CCR_IC_Pos)                /* Instruction cache enable bit Mask */
+  #define SCB_CCR_DC_Pos              16                                   /* Cache enable bit Position */
+  #define SCB_CCR_DC_Msk              (1 << SCB_CCR_DC_Pos)                /* Cache enable bit Mask */
+  #define SCB_CCR_STKALIGN_Pos        9                                    /* STKALIGN Position */
+  #define SCB_CCR_STKALIGN_Msk        (1 << SCB_CCR_STKALIGN_Pos)          /* STKALIGN Mask */
+  #define SCB_CCR_BFHFNMIGN_Pos       8                                    /* BFHFNMIGN Position */
+  #define SCB_CCR_BFHFNMIGN_Msk       (1 << SCB_CCR_BFHFNMIGN_Pos)         /* BFHFNMIGN Mask */
+  #define SCB_CCR_DIV_0_TRP_Pos       4                                    /* DIV_0_TRP Position */
+  #define SCB_CCR_DIV_0_TRP_Msk       (1 << SCB_CCR_DIV_0_TRP_Pos)         /* DIV_0_TRP Mask */
+  #define SCB_CCR_UNALIGN_TRP_Pos     3                                    /* UNALIGN_TRP Position */
+  #define SCB_CCR_UNALIGN_TRP_Msk     (1 << SCB_CCR_UNALIGN_TRP_Pos)       /* UNALIGN_TRP Mask */
+  #define SCB_CCR_USERSETMPEND_Pos    1                                    /* USERSETMPEND Position */
+  #define SCB_CCR_USERSETMPEND_Msk    (1 << SCB_CCR_USERSETMPEND_Pos)      /* USERSETMPEND Mask */
+  #define SCB_CCR_NONBASETHRDENA_Pos  0                                    /* NONBASETHRDENA Position */
+  #define SCB_CCR_NONBASETHRDENA_Msk  (1 /*<< SCB_CCR_NONBASETHRDENA_Pos*/)/* NONBASETHRDENA Mask */
+#define TOFF_SCB_SHP4       0x0018		/* (RW-8) System Handlers Priority Registers 4 */
+#define TOFF_SCB_SHP5       0x0019		/* (RW-8) System Handlers Priority Registers 5 */
+#define TOFF_SCB_SHP6       0x001A		/* (RW-8) System Handlers Priority Registers 6 */
+#define TOFF_SCB_SHP7       0x001B		/* (RW-8) System Handlers Priority Registers 7 */
+#define TOFF_SCB_SHP8       0x001C		/* (RW-8) System Handlers Priority Registers 8 */
+#define TOFF_SCB_SHP9       0x001D		/* (RW-8) System Handlers Priority Registers 9 */
+#define TOFF_SCB_SHP10      0x001E		/* (RW-8) System Handlers Priority Registers 10 */
+#define TOFF_SCB_SHP11      0x001F		/* (RW-8) System Handlers Priority Registers 11 */
+#define TOFF_SCB_SHP12      0x0020		/* (RW-8) System Handlers Priority Registers 12 */
+#define TOFF_SCB_SHP13      0x0021		/* (RW-8) System Handlers Priority Registers 13 */
+#define TOFF_SCB_SHP14      0x0022		/* (RW-8) System Handlers Priority Registers 14 */
+#define TOFF_SCB_SHP15      0x0023		/* (RW-8) System Handlers Priority Registers 15 */
+#define TOFF_SCB_SHCSR      0x0024		/* (RW) System Handler Control and State Register */
+  #define SCB_SHCSR_USGFAULTENA_Pos   18                                   /* USGFAULTENA Position */
+  #define SCB_SHCSR_USGFAULTENA_Msk   (1 << SCB_SHCSR_USGFAULTENA_Pos)     /* USGFAULTENA Mask */
+  #define SCB_SHCSR_BUSFAULTENA_Pos   17                                   /* BUSFAULTENA Position */
+  #define SCB_SHCSR_BUSFAULTENA_Msk   (1 << SCB_SHCSR_BUSFAULTENA_Pos)     /* BUSFAULTENA Mask */
+  #define SCB_SHCSR_MEMFAULTENA_Pos   16                                   /* MEMFAULTENA Position */
+  #define SCB_SHCSR_MEMFAULTENA_Msk   (1 << SCB_SHCSR_MEMFAULTENA_Pos)     /* MEMFAULTENA Mask */
+  #define SCB_SHCSR_SVCALLPENDED_Pos  15                                   /* SVCALLPENDED Position */
+  #define SCB_SHCSR_SVCALLPENDED_Msk  (1 << SCB_SHCSR_SVCALLPENDED_Pos)    /* SVCALLPENDED Mask */
+  #define SCB_SHCSR_BUSFAULTPENDED_Pos 14                                  /* BUSFAULTPENDED Position */
+  #define SCB_SHCSR_BUSFAULTPENDED_Msk (1 << SCB_SHCSR_BUSFAULTPENDED_Pos) /* BUSFAULTPENDED Mask */
+  #define SCB_SHCSR_MEMFAULTPENDED_Pos 13                                  /* MEMFAULTPENDED Position */
+  #define SCB_SHCSR_MEMFAULTPENDED_Msk (1 << SCB_SHCSR_MEMFAULTPENDED_Pos) /* MEMFAULTPENDED Mask */
+  #define SCB_SHCSR_USGFAULTPENDED_Pos 12                                  /* USGFAULTPENDED Position */
+  #define SCB_SHCSR_USGFAULTPENDED_Msk (1 << SCB_SHCSR_USGFAULTPENDED_Pos) /* USGFAULTPENDED Mask */
+  #define SCB_SHCSR_SYSTICKACT_Pos    11                                   /* SYSTICKACT Position */
+  #define SCB_SHCSR_SYSTICKACT_Msk    (1 << SCB_SHCSR_SYSTICKACT_Pos)      /* SYSTICKACT Mask */
+  #define SCB_SHCSR_PENDSVACT_Pos     10                                   /* PENDSVACT Position */
+  #define SCB_SHCSR_PENDSVACT_Msk     (1 << SCB_SHCSR_PENDSVACT_Pos)       /* PENDSVACT Mask */
+  #define SCB_SHCSR_MONITORACT_Pos    8                                    /* MONITORACT Position */
+  #define SCB_SHCSR_MONITORACT_Msk    (1 << SCB_SHCSR_MONITORACT_Pos)      /* MONITORACT Mask */
+  #define SCB_SHCSR_SVCALLACT_Pos     7                                    /* SVCALLACT Position */
+  #define SCB_SHCSR_SVCALLACT_Msk     (1 << SCB_SHCSR_SVCALLACT_Pos)       /* SVCALLACT Mask */
+  #define SCB_SHCSR_USGFAULTACT_Pos   3                                    /* USGFAULTACT Position */
+  #define SCB_SHCSR_USGFAULTACT_Msk   (1 << SCB_SHCSR_USGFAULTACT_Pos)     /* USGFAULTACT Mask */
+  #define SCB_SHCSR_BUSFAULTACT_Pos   1                                    /* BUSFAULTACT Position */
+  #define SCB_SHCSR_BUSFAULTACT_Msk   (1 << SCB_SHCSR_BUSFAULTACT_Pos)     /* BUSFAULTACT Mask */
+  #define SCB_SHCSR_MEMFAULTACT_Pos   0                                    /* MEMFAULTACT Position */
+  #define SCB_SHCSR_MEMFAULTACT_Msk   (1 /*<< SCB_SHCSR_MEMFAULTACT_Pos*/) /* MEMFAULTACT Mask */
+#define TOFF_SCB_CFSR       0x0028		/* (RW) Configurable Fault Status Register */
+#define TOFF_SCB_HFSR       0x002C		/* (RW) HardFault Status Register */
+#define TOFF_SCB_DFSR       0x0030		/* (RW) Debug Fault Status Register */
+#define TOFF_SCB_MMFAR      0x0034		/* (RW) MemManage Fault Address Register */
+#define TOFF_SCB_BFAR       0x0038		/* (RW) BusFault Address Register */
+#define TOFF_SCB_AFSR       0x003C		/* (RW) Auxiliary Fault Status Register */
+#define TOFF_SCB_PFR0       0x0040		/* (R)  Processor Feature Register 0 */
+#define TOFF_SCB_PFR1       0x0044		/* (R)  Processor Feature Register 1 */
+#define TOFF_SCB_ID_DFR     0x0048		/* (R)  Debug Feature Register */
+#define TOFF_SCB_ID_AFR     0x004C		/* (R)  Auxiliary Feature Register */
+#define TOFF_SCB_ID_MFR0    0x0050		/* (R)  Memory Model Feature Register #0 */
+#define TOFF_SCB_ID_MFR1    0x0054		/* (R)  Memory Model Feature Register #1 */
+#define TOFF_SCB_ID_MFR2    0x0058		/* (R)  Memory Model Feature Register #2 */
+#define TOFF_SCB_ID_MFR3    0x005C		/* (R)  Memory Model Feature Register #3 */
+#define TOFF_SCB_ID_ISAR0   0x0060		/* (R)  Instruction Set Attributes Register #0 */
+#define TOFF_SCB_ID_ISAR1   0x0064		/* (R)  Instruction Set Attributes Register #1 */
+#define TOFF_SCB_ID_ISAR2   0x0068		/* (R)  Instruction Set Attributes Register #2 */
+#define TOFF_SCB_ID_ISAR3   0x006C		/* (R)  Instruction Set Attributes Register #3 */
+#define TOFF_SCB_ID_ISAR4   0x0070		/* (R)  Instruction Set Attributes Register #4 */
+#define TOFF_SCB_CLIDR      0x0078		/* (R)  Cache Level ID register */
+#define TOFF_SCB_CTR        0x007C		/* (R)  Cache Type register */
+#define TOFF_SCB_CCSIDR     0x0080		/* (R)  Cache Size ID Register */
+  #define SCB_CCSIDR_WT_Pos           31                                   /* WT Position */
+  #define SCB_CCSIDR_WT_Msk           (7 << SCB_CCSIDR_WT_Pos)             /* WT Mask */
+  #define SCB_CCSIDR_WB_Pos           30                                   /* WB Position */
+  #define SCB_CCSIDR_WB_Msk           (7 << SCB_CCSIDR_WB_Pos)             /* WB Mask */
+  #define SCB_CCSIDR_RA_Pos           29                                   /* RA Position */
+  #define SCB_CCSIDR_RA_Msk           (7 << SCB_CCSIDR_RA_Pos)             /* RA Mask */
+  #define SCB_CCSIDR_WA_Pos           28                                   /* WA Position */
+  #define SCB_CCSIDR_WA_Msk           (7 << SCB_CCSIDR_WA_Pos)             /* WA Mask */
+  #define SCB_CCSIDR_NUMSETS_Pos      13                                   /* NumSets Position */
+  #define SCB_CCSIDR_NUMSETS_Msk      (0x7FFF << SCB_CCSIDR_NUMSETS_Pos)   /* NumSets Mask */
+  #define SCB_CCSIDR_ASSOCIATIVITY_Pos 3                                   /* Associativity Position */
+  #define SCB_CCSIDR_ASSOCIATIVITY_Msk (0x3FF << SCB_CCSIDR_ASSOCIATIVITY_Pos) /* Associativity Mask */
+  #define SCB_CCSIDR_LINESIZE_Pos     0                                    /* LineSize Position */
+  #define SCB_CCSIDR_LINESIZE_Msk     (7 /*<< SCB_CCSIDR_LINESIZE_Pos*/)   /* LineSize Mask */
+#define TOFF_SCB_CSSELR     0x0084		/* (RW) Cache Size Selection Register */
+#define TOFF_SCB_CPACR      0x0088		/* (RW) Coprocessor Access Control Register */
+#define TOFF_SCB_STIR       0x0200		/* (W)  Software Triggered Interrupt Register */
+#define TOFF_SCB_MVFR0      0x0240		/* (R)  Media and VFP Feature Register 0 */
+#define TOFF_SCB_MVFR1      0x0244		/* (R)  Media and VFP Feature Register 1 */
+#define TOFF_SCB_MVFR2      0x0248		/* (R)  Media and VFP Feature Register 2 */
+#define TOFF_SCB_ICIALLU    0x0250		/* (W)  I-Cache Invalidate All to PoU */
+#define TOFF_SCB_ICIMVAU    0x0258		/* (W)  I-Cache Invalidate by MVA to PoU */
+#define TOFF_SCB_DCIMVAC    0x025C		/* (W)  D-Cache Invalidate by MVA to PoC */
+#define TOFF_SCB_DCISW      0x0260		/* (W)  D-Cache Invalidate by Set-way */
+#define TOFF_SCB_DCCMVAU    0x0264		/* (W)  D-Cache Clean by MVA to PoU */
+#define TOFF_SCB_DCCMVAC    0x0268		/* (W)  D-Cache Clean by MVA to PoC */
+#define TOFF_SCB_DCCSW      0x026C		/* (W)  D-Cache Clean by Set-way */
+#define TOFF_SCB_DCCIMVAC   0x0270		/* (W)  D-Cache Clean and Invalidate by MVA to PoC */
+#define TOFF_SCB_DCCISW     0x0274		/* (W)  D-Cache Clean and Invalidate by Set-way */
+#define TOFF_SCB_ITCMCR     0x0290		/* (RW)  Instruction Tightly-Coupled Memory Control Register   */
+#define TOFF_SCB_DTCMCR     0x0294		/* (RW)  Data Tightly-Coupled Memory Control Registers */
+#define TOFF_SCB_AHBPCR     0x0298		/* (RW)  AHBP Control Register */
+#define TOFF_SCB_CACR       0x029C		/* (RW)  L1 Cache Control Register */
+#define TOFF_SCB_AHBSCR     0x02A0		/* (RW)  AHB Slave Control Register */
+#define TOFF_SCB_ABFSR      0x02A8		/* (RW)  Auxiliary Bus Fault Status Register */
+
+/*
+ *  SIL type to ACCESS the MEMORY PROTECTION UNIT (MPU).
+ */
+#define TADR_MPU_BASE       (TADR_SCS_BASE+0x0D90UL)	/* Memory Protection Unit */
+#define TOFF_MPU_TYPE       0x0000		/* (R)  MPU Type Register */
+  #define MPU_TYPE_IREGION_Pos        16                                   /* IREGION Position */
+  #define MPU_TYPE_IREGION_Msk        (0xFF << MPU_TYPE_IREGION_Pos)       /* IREGION Mask */
+  #define MPU_TYPE_DREGION_Pos        8                                    /* DREGION Position */
+  #define MPU_TYPE_DREGION_Msk        (0xFF << MPU_TYPE_DREGION_Pos)       /* DREGION Mask */
+  #define MPU_TYPE_SEPARATE_Pos       0                                    /* SEPARATE Position */
+  #define MPU_TYPE_SEPARATE_Msk       (1 /*<< MPU_TYPE_SEPARATE_Pos*/)     /* SEPARATE Mask */
+#define TOFF_MPU_CTRL       0x0004		/* (RW) MPU Control Register */
+  #define MPU_CTRL_PRIVDEFENA_Pos     2                                    /* PRIVDEFENA Position */
+  #define MPU_CTRL_PRIVDEFENA_Msk     (1 << MPU_CTRL_PRIVDEFENA_Pos)       /* PRIVDEFENA Mask */
+  #define MPU_CTRL_HFNMIENA_Pos       1                                    /* HFNMIENA Position */
+  #define MPU_CTRL_HFNMIENA_Msk       (1 << MPU_CTRL_HFNMIENA_Pos)         /* HFNMIENA Mask */
+  #define MPU_CTRL_ENABLE_Pos         0                                    /* ENABLE Position */
+  #define MPU_CTRL_ENABLE_Msk         (1 /*<< MPU_CTRL_ENABLE_Pos*/)       /* ENABLE Mask */
+#define TOFF_MPU_RNR        0x0008		/* (RW) MPU Region RNRber Register */
+#define TOFF_MPU_RBAR       0x000C		/* (RW) MPU Region Base Address Register */
+#define TOFF_MPU_RASR       0x0010		/* (RW) MPU Region Attribute and Size Register         */
+  #define MPU_RASR_ATTRS_Pos          16                                   /* MPU Region Attribute field Position */
+  #define MPU_RASR_ATTRS_Msk          (0xFFFF << MPU_RASR_ATTRS_Pos)       /* MPU Region Attribute field Mask */
+  #define MPU_RASR_XN_Pos             28                                   /* ATTRS.XN Position */
+  #define MPU_RASR_XN_Msk             (1 << MPU_RASR_XN_Pos)               /* ATTRS.XN Mask */
+  #define MPU_RASR_AP_Pos             24                                   /* ATTRS.AP Position */
+  #define MPU_RASR_AP_Msk             (0x7 << MPU_RASR_AP_Pos)             /* ATTRS.AP Mask */
+  #define MPU_RASR_TEX_Pos            19                                   /* ATTRS.TEX Position */
+  #define MPU_RASR_TEX_Msk            (0x7 << MPU_RASR_TEX_Pos)            /* ATTRS.TEX Mask */
+  #define MPU_RASR_S_Pos              18                                   /* ATTRS.S Position */
+  #define MPU_RASR_S_Msk              (1 << MPU_RASR_S_Pos)                /* ATTRS.S Mask */
+  #define MPU_RASR_C_Pos              17                                   /* ATTRS.C Position */
+  #define MPU_RASR_C_Msk              (1 << MPU_RASR_C_Pos)                /* ATTRS.C Mask */
+  #define MPU_RASR_B_Pos              16                                   /* ATTRS.B Position */
+  #define MPU_RASR_B_Msk              (1 << MPU_RASR_B_Pos)                /* ATTRS.B Mask */
+  #define MPU_RASR_SRD_Pos            8                                    /* Sub-Region Disable Position */
+  #define MPU_RASR_SRD_Msk            (0xFF << MPU_RASR_SRD_Pos)           /* Sub-Region Disable Mask */
+  #define MPU_RASR_SIZE_Pos           1                                    /* Region Size Field Position */
+  #define MPU_RASR_SIZE_Msk           (0x1F << MPU_RASR_SIZE_Pos)          /* Region Size Field Mask */
+  #define MPU_RASR_ENABLE_Pos         0                                    /* Region enable bit Position */
+  #define MPU_RASR_ENABLE_Msk         (1 /*<< MPU_RASR_ENABLE_Pos*/)       /* Region enable bit Disable Mask */
+#define TOFF_MPU_RBAR_A1    0x0014		/* (RW) MPU Alias 1 Region Base Address Register       */
+#define TOFF_MPU_RASR_A1    0x0018		/* (RW) MPU Alias 1 Region Attribute and Size Register */
+#define TOFF_MPU_RBAR_A2    0x001C		/* (RW) MPU Alias 2 Region Base Address Register       */
+#define TOFF_MPU_RASR_A2    0x0020		/* (RW) MPU Alias 2 Region Attribute and Size Register */
+#define TOFF_MPU_RBAR_A3    0x0024		/* (RW) MPU Alias 3 Region Base Address Register       */
+#define TOFF_MPU_RASR_A3    0x0028		/* (RW) MPU Alias 3 Region Attribute and Size Register */
+
+/*
+ *  SIL TYPE to ACCESS the TRACE PORT INTERFACE REGISTER (TPI).
+ */
+#define TADR_TPI_BASE       (0xE0040000UL)				/* TPI Base Address                   */
+#define TOFF_TPI_SSPSR      0x0000		/* (R)  Supported Parallel Port Size Register */
+#define TOFF_TPI_CSPSR      0x0004		/* (RW) Current Parallel Port Size Register */
+#define TOFF_TPI_ACPR       0x0010		/* (RW) Asynchronous Clock Prescaler Register */
+#define TOFF_TPI_SPPR       0x00F0		/* (RW) Selected Pin Protocol Register */
+#define TOFF_TPI_FFSR       0x0300		/* (R)  Formatter and Flush Status Register */
+#define TOFF_TPI_FFCR       0x0304		/* (RW) Formatter and Flush Control Register */
+#define TOFF_TPI_FSCR       0x0308		/* (R)  Formatter Synchronization Counter Register */
+#define TOFF_TPI_TRIGGER    0x0EE8		/* (R)  TRIGGER */
+#define TOFF_TPI_FIFO0      0x0EEC		/* (R)  Integration ETM Data */
+#define TOFF_TPI_ITATBCTR2  0x0EF0		/* (R)  ITATBCTR2 */
+#define TOFF_TPI_ITATBCTR0  0x0EF8		/* (R)  ITATBCTR0 */
+#define TOFF_TPI_FIFO1      0x0EFC		/* (R)  Integration ITM Data */
+#define TOFF_TPI_ITCTRL     0x0F00		/* (RW) Integration Mode Control */
+#define TOFF_TPI_CLAIMSET   0x0FA0		/* (RW) Claim tag set */
+#define TOFF_TPI_CLAIMCLR   0x0FA4		/* (RW) Claim tag clear */
+#define TOFF_TPI_DEVID      0x0FC8		/* (R)  TPIU_DEVID */
+#define TOFF_TPI_DEVTYPE    0x0FCC		/* (R)  TPIU_DEVTYPE */
+
+/*
+ *  SIL TYPE to ACCESS the CORE DEBUG REGISTER (CoreDebug).
+ */
+#define TADR_COREDEBUG_BASE (0xE000EDF0UL)				/* Core Debug Base Address  */
+#define TOFF_COREDEBUG_DHCSR 0x0000	/* (RW) Debug Halting Control and Status Register    */
+#define TOFF_COREDEBUG_DCRSR 0x0004	/* (W)  Debug Core Register Selector Register        */
+#define TOFF_COREDEBUG_DCRDR 0x0008	/* (RW) Debug Core Register Data Register            */
+#define TOFF_COREDEBUG_DEMCR 0x000C	/* (RW) Debug Exception and Monitor Control Register */
+
+/*
+ *  SIL TYPE to ACCESS the FLOATING POINT UNIT (FPU).
+ */
+#define TADR_FPU_BASE       (TADR_SCS_BASE+0x0F30UL)	/* Floating Point Unit */
+#define TOFF_FPU_FPCCR      0x0004		/* (RW) Floating-Point Context Control Register */
+#define TOFF_FPU_FPCAR      0x0008		/* (RW) Floating-Point Context Address Register */
+#define TOFF_FPU_FPDSCR     0x000C		/* (RW) Floating-Point Default Status Control Register */
+#define TOFF_FPU_MVFR0      0x0010		/* (R)  Media and FP Feature Register 0 */
+#define TOFF_FPU_MVFR1      0x0014		/* (R)  Media and FP Feature Register 1 */
+#define TOFF_FPU_MVFR2      0x0018		/* (R)  Media and FP Feature Register 2 */
+
+/*
+ *  CORTEX_Preemption_Priority_Group CORTEX Preemption Priority Group
+ */
+#define NVIC_PRIORITYGROUP_0    0x00000007	/* 0 bits for pre-emption priority 4 bits for subpriority */
+#define NVIC_PRIORITYGROUP_1    0x00000006	/* 1 bits for pre-emption priority 3 bits for subpriority */
+#define NVIC_PRIORITYGROUP_2    0x00000005	/* 2 bits for pre-emption priority 2 bits for subpriority */
+#define NVIC_PRIORITYGROUP_3    0x00000004	/* 3 bits for pre-emption priority 1 bits for subpriority */
+#define NVIC_PRIORITYGROUP_4    0x00000003	/* 4 bits for pre-emption priority 0 bits for subpriority */
+
+/*
+ *  CORTEX_MPU_HFNMI_PRIVDEF_Control MPU HFNMI and PRIVILEGED Access control
+ */
+#define MPU_HFNMI_PRIVDEF_NONE  0x00000000
+#define MPU_HARDFAULT_NMI       0x00000002
+#define MPU_PRIVILEGED_DEFAULT  0x00000004
+#define MPU_HFNMI_PRIVDEF       0x00000006
+
+/*
+ *  CORTEX_MPU_TEX_Levels MPU TEX Levels
+ */
+#define MPU_TEX_LEVEL0          0x00
+#define MPU_TEX_LEVEL1          0x01
+#define MPU_TEX_LEVEL2          0x02
+
+/*
+ *  CORTEX_MPU_Region_Size CORTEX MPU Region Size
+ */
+#define MPU_REGION_SIZE_32B     0x04
+#define MPU_REGION_SIZE_64B     0x05
+#define MPU_REGION_SIZE_128B    0x06
+#define MPU_REGION_SIZE_256B    0x07
+#define MPU_REGION_SIZE_512B    0x08
+#define MPU_REGION_SIZE_1KB     0x09
+#define MPU_REGION_SIZE_2KB     0x0A
+#define MPU_REGION_SIZE_4KB     0x0B
+#define MPU_REGION_SIZE_8KB     0x0C
+#define MPU_REGION_SIZE_16KB    0x0D
+#define MPU_REGION_SIZE_32KB    0x0E
+#define MPU_REGION_SIZE_64KB    0x0F
+#define MPU_REGION_SIZE_128KB   0x10
+#define MPU_REGION_SIZE_256KB   0x11
+#define MPU_REGION_SIZE_512KB   0x12
+#define MPU_REGION_SIZE_1MB     0x13
+#define MPU_REGION_SIZE_2MB     0x14
+#define MPU_REGION_SIZE_4MB     0x15
+#define MPU_REGION_SIZE_8MB     0x16
+#define MPU_REGION_SIZE_16MB    0x17
+#define MPU_REGION_SIZE_32MB    0x18
+#define MPU_REGION_SIZE_64MB    0x19
+#define MPU_REGION_SIZE_128MB   0x1A
+#define MPU_REGION_SIZE_256MB   0x1B
+#define MPU_REGION_SIZE_512MB   0x1C
+#define MPU_REGION_SIZE_1GB     0x1D
+#define MPU_REGION_SIZE_2GB     0x1E
+#define MPU_REGION_SIZE_4GB     0x1F
+
+/*
+ *  CORTEX_MPU_Region_Number CORTEX MPU Region Number
+ */
+#define MPU_REGION_NUMBER0      0x00
+#define MPU_REGION_NUMBER1      0x01
+#define MPU_REGION_NUMBER2      0x02
+#define MPU_REGION_NUMBER3      0x03
+#define MPU_REGION_NUMBER4      0x04
+#define MPU_REGION_NUMBER5      0x05
+#define MPU_REGION_NUMBER6      0x06
+#define MPU_REGION_NUMBER7      0x07
+
+/*
+ *  CORTEX_MPU_Region_Permission_Attributes CORTEX MPU Region Permission Attributes 
+ */
+#define MPU_REGION_NO_ACCESS    0x00
+#define MPU_REGION_PRIV_RW      0x01
+#define MPU_REGION_PRIV_RW_URO  0x02
+#define MPU_REGION_FULL_ACCESS  0x03
+#define MPU_REGION_PRIV_RO      0x05
+#define MPU_REGION_PRIV_RO_URO  0x06
+
+
+#endif  /* _CMSIS_F7_H_ */
+
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/arch/arm_m_gcc/stm32f7xx/stm32f7xx.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/arch/arm_m_gcc/stm32f7xx/stm32f7xx.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/arch/arm_m_gcc/stm32f7xx/stm32f7xx.h	(revision 457)
@@ -0,0 +1,5375 @@
+/*
+ *  TOPPERS/ASP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Just Standard Profile Kernel
+ * 
+ *  Copyright (C) 2015-2016 by 3rd Designing Center
+ *              Imageing System Development Division RICOH COMPANY, LTD.
+ *  Copyright (C) 2017-2019 by TOPPERS PROJECT Educational Working Group.
+ *
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+#ifndef _STM32F7XX_H_
+#define _STM32F7XX_H_
+
+/*
+ *  Cortex-M7プロセッサとコアペイフェラル設定
+ */
+#include <sil.h>
+#define __NVIC_PRIO_BITS    4		/* CM7 uses 4 Bits for the Priority Levels       */
+#include "cmsis_f7.h"				/* Cortex-M7 processor and core peripherals      */
+
+/*
+ *  割込み番号の最大値
+ */
+#if defined(TOPPERS_STM32F769_DISCOVERY) || defined(TOPPERS_STM32F767_NUCLEO144)
+#define TMAX_INTNO          (16 + 109)
+#elif defined(TOPPERS_STM32F723_DISCOVERY)
+#define TMAX_INTNO          (16 + 103)
+#else
+#define TMAX_INTNO          (16 + 98)
+#endif
+
+/*
+ *  割込み優先度のビット幅
+ */
+#define TBITW_IPRI          4
+
+/*
+ *  INTERRUPT NUMBER
+ */
+#define IRQ_VECTOR_WWDG             (16 + 0)	/* Window WatchDog Interrupt */
+#define IRQ_VECTOR_PVD              (16 + 1)	/* PVD through EXTI Line detection Interrupt */
+#define IRQ_VECTOR_TAMP_STAMP       (16 + 2)	/* Tamper and TimeStamp interrupts through the EXTI line */
+#define IRQ_VECTOR_RTC_WKUP         (16 + 3)	/* RTC Wakeup interrupt through the EXTI line */
+#define IRQ_VECTOR_FLASH            (16 + 4)	/* FLASH global Interrupt */
+#define IRQ_VECTOR_RCC              (16 + 5)	/* RCC global Interrupt */
+#define IRQ_VECTOR_EXTI0            (16 + 6)	/* EXTI Line0 Interrupt */
+#define IRQ_VECTOR_EXTI1            (16 + 7)	/* EXTI Line1 Interrupt */
+#define IRQ_VECTOR_EXTI2            (16 + 8)	/* EXTI Line2 Interrupt */
+#define IRQ_VECTOR_EXTI3            (16 + 9)	/* EXTI Line3 Interrupt */
+#define IRQ_VECTOR_EXTI4            (16 + 10)	/* EXTI Line4 Interrupt */
+#define IRQ_VECTOR_DMA1_STREAM0     (16 + 11)	/* DMA1 Stream 0 global Interrupt */
+#define IRQ_VECTOR_DMA1_STREAM1     (16 + 12)	/* DMA1 Stream 1 global Interrupt */
+#define IRQ_VECTOR_DMA1_STREAM2     (16 + 13)	/* DMA1 Stream 2 global Interrupt */
+#define IRQ_VECTOR_DMA1_STREAM3     (16 + 14)	/* DMA1 Stream 3 global Interrupt */
+#define IRQ_VECTOR_DMA1_STREAM4     (16 + 15)	/* DMA1 Stream 4 global Interrupt */
+#define IRQ_VECTOR_DMA1_STREAM5     (16 + 16)	/* DMA1 Stream 5 global Interrupt */
+#define IRQ_VECTOR_DMA1_STREAM6     (16 + 17)	/* DMA1 Stream 6 global Interrupt */
+#define IRQ_VECTOR_ADC              (16 + 18)	/* ADC1, ADC2 and ADC3 global Interrupts */
+#define IRQ_VECTOR_CAN1_TX          (16 + 19)	/* CAN1 TX Interrupt */
+#define IRQ_VECTOR_CAN1_RX0         (16 + 20)	/* CAN1 RX0 Interrupt */
+#define IRQ_VECTOR_CAN1_RX1         (16 + 21)	/* CAN1 RX1 Interrupt */
+#define IRQ_VECTOR_CAN1_SCE         (16 + 22)	/* CAN1 SCE Interrupt */
+#define IRQ_VECTOR_EXTI9_5          (16 + 23)	/* External Line[9:5] Interrupts */
+#define IRQ_VECTOR_TIM1_BRK_TIM9    (16 + 24)	/* TIM1 Break interrupt and TIM9 global interrupt */
+#define IRQ_VECTOR_TIM1_UP_TIM10    (16 + 25)	/* TIM1 Update Interrupt and TIM10 global interrupt */
+#define IRQ_VECTOR_TIM1_TRG_COM_TIM11 (16+26)	/* TIM1 Trigger and Commutation Interrupt and TIM11 global interrupt */
+#define IRQ_VECTOR_TIM1_CC          (16 + 27)	/* TIM1 Capture Compare Interrupt */
+#define IRQ_VECTOR_TIM2             (16 + 28)	/* TIM2 global Interrupt */
+#define IRQ_VECTOR_TIM3             (16 + 29)	/* TIM3 global Interrupt */
+#define IRQ_VECTOR_TIM4             (16 + 30)	/* TIM4 global Interrupt */
+#define IRQ_VECTOR_I2C1_EV          (16 + 31)	/* I2C1 Event Interrupt */
+#define IRQ_VECTOR_I2C1_ER          (16 + 32)	/* I2C1 Error Interrupt */
+#define IRQ_VECTOR_I2C2_EV          (16 + 33)	/* I2C2 Event Interrupt */
+#define IRQ_VECTOR_I2C2_ER          (16 + 34)	/* I2C2 Error Interrupt */
+#define IRQ_VECTOR_SPI1             (16 + 35)	/* SPI1 global Interrupt */
+#define IRQ_VECTOR_SPI2             (16 + 36)	/* SPI2 global Interrupt */
+#define IRQ_VECTOR_USART1           (16 + 37)	/* USART1 global Interrupt */
+#define IRQ_VECTOR_USART2           (16 + 38)	/* USART2 global Interrupt */
+#define IRQ_VECTOR_USART3           (16 + 39)	/* USART3 global Interrupt */
+#define IRQ_VECTOR_EXTI15_10        (16 + 40)	/* External Line[15:10] Interrupts */
+#define IRQ_VECTOR_RTC_ALARM        (16 + 41)	/* RTC Alarm (A and B) through EXTI Line Interrupt */
+#define IRQ_VECTOR_OTG_FS_WKUP      (16 + 42)	/* USB OTG FS Wakeup through EXTI line interrupt */
+#define IRQ_VECTOR_TIM8_BRK_TIM12   (16 + 43)	/* TIM8 Break Interrupt and TIM12 global interrupt */
+#define IRQ_VECTOR_TIM8_UP_TIM13    (16 + 44)	/* TIM8 Update Interrupt and TIM13 global interrupt */
+#define IRQ_VECTOR_TIM8_TRG_COM_TIM14 (16+45)	/* TIM8 Trigger and Commutation Interrupt and TIM14 global interrupt */
+#define IRQ_VECTOR_TIM8_CC          (16 + 46)	/* TIM8 Capture Compare Interrupt */
+#define IRQ_VECTOR_DMA1_STREAM7     (16 + 47)	/* DMA1 Stream7 Interrupt */
+#define IRQ_VECTOR_FMC              (16 + 48)	/* FMC global Interrupt */
+#define IRQ_VECTOR_SDMMC            (16 + 49)	/* SDMMC global Interrupt */
+#define IRQ_VECTOR_TIM5             (16 + 50)	/* TIM5 global Interrupt */
+#define IRQ_VECTOR_SPI3             (16 + 51)	/* SPI3 global Interrupt */
+#define IRQ_VECTOR_UART4            (16 + 52)	/* UART4 global Interrupt */
+#define IRQ_VECTOR_UART5            (16 + 53)	/* UART5 global Interrupt */
+#define IRQ_VECTOR_TIM6_DAC         (16 + 54)	/* TIM6 global and DAC1&2 underrun error interrupts */
+#define IRQ_VECTOR_TIM7             (16 + 55)	/* TIM7 global interrupt */
+#define IRQ_VECTOR_DMA2_STREAM0     (16 + 56)	/* DMA2 Stream 0 global Interrupt */
+#define IRQ_VECTOR_DMA2_STREAM1     (16 + 57)	/* DMA2 Stream 1 global Interrupt */
+#define IRQ_VECTOR_DMA2_STREAM2     (16 + 58)	/* DMA2 Stream 2 global Interrupt */
+#define IRQ_VECTOR_DMA2_STREAM3     (16 + 59)	/* DMA2 Stream 3 global Interrupt */
+#define IRQ_VECTOR_DMA2_STREAM4     (16 + 60)	/* DMA2 Stream 4 global Interrupt */
+#define IRQ_VECTOR_ETH              (16 + 61)	/* Ethernet global Interrupt */
+#define IRQ_VECTOR_ETH_WKUP         (16 + 62)	/* Ethernet Wakeup through EXTI line Interrupt */
+#define IRQ_VECTOR_CAN2_TX          (16 + 63)	/* CAN2 TX Interrupt */
+#define IRQ_VECTOR_CAN2_RX0         (16 + 64)	/* CAN2 RX0 Interrupt */
+#define IRQ_VECTOR_CAN2_RX1         (16 + 65)	/* CAN2 RX1 Interrupt */
+#define IRQ_VECTOR_CAN2_SCE         (16 + 66)	/* CAN2 SCE Interrupt */
+#define IRQ_VECTOR_OTG_FS           (16 + 67)	/* USB OTG FS global Interrupt */
+#define IRQ_VECTOR_DMA2_STREAM5     (16 + 68)	/* DMA2 Stream 5 global interrupt */
+#define IRQ_VECTOR_DMA2_STREAM6     (16 + 69)	/* DMA2 Stream 6 global interrupt */
+#define IRQ_VECTOR_DMA2_STREAM7     (16 + 70)	/* DMA2 Stream 7 global interrupt */
+#define IRQ_VECTOR_USART6           (16 + 71)	/* USART6 global interrupt */
+#define IRQ_VECTOR_I2C3_EV          (16 + 72)	/* I2C3 event interrupt */
+#define IRQ_VECTOR_I2C3_ER          (16 + 73)	/* I2C3 error interrupt */
+#define IRQ_VECTOR_OTG_HS_EP1_OUT   (16 + 74)	/* USB OTG HS End Point 1 Out global interrupt */
+#define IRQ_VECTOR_OTG_HS_EP1_IN    (16 + 75)	/* USB OTG HS End Point 1 In global interrupt */
+#define IRQ_VECTOR_OTG_HS_WKUP      (16 + 76)	/* USB OTG HS Wakeup through EXTI interrupt */
+#define IRQ_VECTOR_OTG_HS           (16 + 77)	/* USB OTG HS global interrupt */
+#define IRQ_VECTOR_DCMI             (16 + 78)	/* DCMI global interrupt */
+#define IRQ_VECTOR_CRYP             (16 + 79)	/* CRYP crypto global interrupt */
+#define IRQ_VECTOR_HASH_RNG         (16 + 80)	/* Hash and Rng global interrupt */
+#define IRQ_VECTOR_FPU              (16 + 81)	/* FPU global interrupt */
+#define IRQ_VECTOR_UART7            (16 + 82)	/* UART7 global interrupt */
+#define IRQ_VECTOR_UART8            (16 + 83)	/* UART8 global interrupt */
+#define IRQ_VECTOR_SPI4             (16 + 84)	/* SPI4 global Interrupt */
+#define IRQ_VECTOR_SPI5             (16 + 85)	/* SPI5 global Interrupt */
+#define IRQ_VECTOR_SPI6             (16 + 86)	/* SPI6 global Interrupt */
+#define IRQ_VECTOR_SAI1             (16 + 87)	/* SAI1 global Interrupt */
+#define IRQ_VECTOR_LTDC             (16 + 88)	/* LTDC global Interrupt */
+#define IRQ_VECTOR_LTDC_ER          (16 + 89)	/* LTDC Error global Interrupt */
+#define IRQ_VECTOR_DMA2D            (16 + 90)	/* DMA2D global Interrupt */
+#define IRQ_VECTOR_SAI2             (16 + 91)	/* SAI2 global Interrupt */
+#define IRQ_VECTOR_QUADSPI          (16 + 92)	/* Quad SPI global interrupt */
+#define IRQ_VECTOR_LPTIM1           (16 + 93)	/* LP TIM1 interrupt */
+#if defined(TOPPERS_STM32F723_DISCOVERY)
+#define IRQ_VECTOR_SDMMC2           (16 + 103)	/* SDMMC2 global Interrupt */
+#else
+#define IRQ_VECTOR_CEC              (16 + 94)	/* HDMI-CEC global Interrupt */
+#define IRQ_VECTOR_I2C4_EV          (16 + 95)	/* I2C4 Event Interrupt */
+#define IRQ_VECTOR_I2C4_ER          (16 + 96)	/* I2C4 Error Interrupt */
+#define IRQ_VECTOR_SPDIF_RX         (16 + 97)	/* SPDIF-RX global Interrupt */
+#endif
+#if defined(TOPPERS_STM32F769_DISCOVERY)
+#define IRQ_VECTOR_DSI              (16 + 98)	/* DSI global Interrupt */
+#endif
+#if defined(TOPPERS_STM32F769_DISCOVERY) || defined(TOPPERS_STM32F767_NUCLEO144)
+#define IRQ_DFSDM1_FLT0	            (16 + 99)	/* DFSDM1 Filter 0 global Interrupt */
+#define IRQ_DFSDM1_FLT1	            (16 + 100)	/* DFSDM1 Filter 1 global Interrupt */
+#define IRQ_DFSDM1_FLT2	            (16 + 101)	/* DFSDM1 Filter 2 global Interrupt */
+#define IRQ_DFSDM1_FLT3             (16 + 102)	/* DFSDM1 Filter 3 global Interrupt */
+#define IRQ_VECTOR_SDMMC2           (16 + 103)	/* SDMMC2 global Interrupt */
+#define IRQ_VECTOR_CAN3_TX          (16 + 104)	/* CAN3 TX Interrupt */
+#define IRQ_VECTOR_CAN3_RX0         (16 + 105)	/* CAN3 RX0 Interrupt */
+#define IRQ_VECTOR_CAN3_RX1         (16 + 106)	/* CAN3 RX1 Interrupt */
+#define IRQ_VECTOR_CAN3_SCE         (16 + 107)	/* CAN3 SCE Interrupt */
+#define IRQ_VECTOR_JPEG             (16 + 108)	/* JPEG global Interrupt */
+#define IRQ_VECTOR_MDIOS            (16 + 109)	/* MDIO Slave global Interrupt */
+#endif
+
+/*
+ *  PERIPHERAL MEMORY MAP
+ */
+#define RAMITCM_BASE        0x00000000	/* Base address of :16KB RAM reserved for CPU execution/instruction accessible over ITCM   */
+#define FLASHITCM_BASE      0x00200000	/* Base address of :(up to 1 MB) embedded FLASH memory  accessible over ITCM               */                       
+#define FLASHAXI_BASE       0x08000000	/* Base address of : (up to 1 MB) embedded FLASH memory accessible over AXI                */                       
+#define RAMDTCM_BASE        0x20000000	/* Base address of : 64KB system data RAM accessible over DTCM                             */
+#define SRAM1_BASE          0x20010000	/* Base address of : 240KB RAM1 accessible over AXI/AHB                                    */
+#define SRAM2_BASE          0x2004C000	/* Base address of : 16KB RAM2 accessible over AXI/AHB                                     */
+#define PERIPH_BASE         0x40000000	/* Base address of : AHB/ABP Peripherals                                                   */
+#define BKPSRAM_BASE        0x40024000	/* Base address of : Backup SRAM(4 KB)                                                     */
+#define QSPI_BASE           0x90000000	/* Base address of : QSPI memories  accessible over AXI                                    */
+#define FMC_R_BASE          0xA0000000	/* Base address of : FMC Control registers                                                 */
+#define QSPI_R_BASE         0xA0001000	/* Base address of : QSPI Control  registers                                               */
+#define FLASH_END           0x080FFFFF	/* FLASH end address */
+
+#define FLASH_BASE          FLASHAXI_BASE	/* FLASH(up to 1 MB) base address in the alias region                         */
+
+/* Peripheral memory map */
+#define APB1PERIPH_BASE     PERIPH_BASE
+#define APB2PERIPH_BASE     (PERIPH_BASE + 0x00010000)
+#define AHB1PERIPH_BASE     (PERIPH_BASE + 0x00020000)
+#define AHB2PERIPH_BASE     (PERIPH_BASE + 0x10000000)
+
+/* USB registers base address */
+#define USB_OTG_HS_PERIPH_BASE     0x40040000
+#define USB_OTG_FS_PERIPH_BASE     0x50000000
+
+#define USB_OTG_DEVICE_BASE         0x800
+#define USB_OTG_IN_ENDPOINT_BASE    0x900
+#define USB_OTG_OUT_ENDPOINT_BASE   0xB00
+#define USB_OTG_HOST_BASE           0x400
+#define USB_OTG_HOST_PORT_BASE      0x440
+#define USB_OTG_HOST_CHANNEL_BASE   0x500
+#define USB_OTG_PCGCCTL_BASE        0xE00
+#define USB_OTG_FIFO_BASE           0x1000
+#define USB_OTG_FIFO_SIZE           0x1000
+
+
+/*
+ *  TIM
+ */
+#define TADR_TIM2_BASE      (APB1PERIPH_BASE + 0x0000)
+#define TADR_TIM3_BASE      (APB1PERIPH_BASE + 0x0400)
+#define TADR_TIM4_BASE      (APB1PERIPH_BASE + 0x0800)
+#define TADR_TIM5_BASE      (APB1PERIPH_BASE + 0x0C00)
+#define TADR_TIM6_BASE      (APB1PERIPH_BASE + 0x1000)
+#define TADR_TIM7_BASE      (APB1PERIPH_BASE + 0x1400)
+#define TADR_TIM12_BASE     (APB1PERIPH_BASE + 0x1800)
+#define TADR_TIM13_BASE     (APB1PERIPH_BASE + 0x1C00)
+#define TADR_TIM14_BASE     (APB1PERIPH_BASE + 0x2000)
+#define TADR_TIM1_BASE      (APB2PERIPH_BASE + 0x0000)
+#define TADR_TIM8_BASE      (APB2PERIPH_BASE + 0x0400)
+#define TADR_TIM9_BASE      (APB2PERIPH_BASE + 0x4000)
+#define TADR_TIM10_BASE     (APB2PERIPH_BASE + 0x4400)
+#define TADR_TIM11_BASE     (APB2PERIPH_BASE + 0x4800)
+#define TOFF_TIM_CR1        0x0000		/* (RW) TIM control register 1 */
+  #define TIM_CR1_CEN        0x0001		/* Counter enable */
+  #define TIM_CR1_UDIS       0x0002		/* Update disable */
+  #define TIM_CR1_URS        0x0004		/* Update request source */
+  #define TIM_CR1_OPM        0x0008		/* One pulse mode */
+  #define TIM_CR1_DIR        0x0010		/* Direction */
+  #define TIM_CR1_CMS_0      0x0020		/* CMS[1:0] bit 0 */
+  #define TIM_CR1_CMS_1      0x0040		/* CMS[1:0] bit 1 */
+  #define TIM_CR1_ARPE       0x0080		/* Auto-reload preload enable */
+  #define TIM_CR1_CKD_0      0x0100		/* CKD[1:0] bit 0 */
+  #define TIM_CR1_CKD_1      0x0200		/* CKD[1:0] bit 1 */
+  #define TIM_CR1_UIFREMAP   0x0800		/* UIF status bit */
+#define TOFF_TIM_CR2        0x0004		/* (RW) TIM control register 2 */
+  #define TIM_CR2_CCPC       0x00000001	/* Capture/Compare Preloaded Control        */
+  #define TIM_CR2_CCUS       0x00000004	/* Capture/Compare Control Update Selection */
+  #define TIM_CR2_CCDS       0x00000008	/* Capture/Compare DMA Selection            */
+  #define TIM_CR2_OIS5       0x00010000	/* Output Idle state 4 (OC4 output) */
+  #define TIM_CR2_OIS6       0x00040000	/* Output Idle state 4 (OC4 output) */
+  #define TIM_CR2_MMS        0x0070		/* MMS[2:0] bits (Master Mode Selection) */
+  #define TIM_CR2_MMS_0      0x0010		/* Bit 0 */
+  #define TIM_CR2_MMS_1      0x0020		/* Bit 1 */
+  #define TIM_CR2_MMS_2      0x0040		/* Bit 2 */
+  #define TIM_CR2_MMS2       0x00F00000	/* MMS[2:0] bits (Master Mode Selection) */
+  #define TIM_CR2_MMS2_0     0x00100000	/* Bit 0 */
+  #define TIM_CR2_MMS2_1     0x00200000	/* Bit 1 */
+  #define TIM_CR2_MMS2_2     0x00400000	/* Bit 2 */
+  #define TIM_CR2_MMS2_3     0x00800000	/* Bit 2 */
+  #define TIM_CR2_TI1S       0x0080		/* TI1 Selection */
+  #define TIM_CR2_OIS1       0x0100		/* Output Idle state 1 (OC1 output)  */
+  #define TIM_CR2_OIS1N      0x0200		/* Output Idle state 1 (OC1N output) */
+  #define TIM_CR2_OIS2       0x0400		/* Output Idle state 2 (OC2 output)  */
+  #define TIM_CR2_OIS2N      0x0800		/* Output Idle state 2 (OC2N output) */
+  #define TIM_CR2_OIS3       0x1000		/* Output Idle state 3 (OC3 output)  */
+  #define TIM_CR2_OIS3N      0x2000		/* Output Idle state 3 (OC3N output) */
+  #define TIM_CR2_OIS4       0x4000		/* Output Idle state 4 (OC4 output)  */
+#define TOFF_TIM_SMCR       0x0008		/* (RW) TIM slave mode control register */
+  #define TIM_SMCR_SMS       0x00010007	/* SMS[2:0] bits (Slave mode selection)    */
+  #define TIM_SMCR_SMS_0     0x00000001	/* Bit 0 */
+  #define TIM_SMCR_SMS_1     0x00000002	/* Bit 1 */
+  #define TIM_SMCR_SMS_2     0x00000004	/* Bit 2 */
+  #define TIM_SMCR_SMS_3     0x00010000	/* Bit 3 */
+  #define TIM_SMCR_OCCS      0x00000008	/* OCREF clear selection */
+  #define TIM_SMCR_TS        0x0070		/* TS[2:0] bits (Trigger selection)        */
+  #define TIM_SMCR_TS_0      0x0010		/* Bit 0 */
+  #define TIM_SMCR_TS_1      0x0020		/* Bit 1 */
+  #define TIM_SMCR_TS_2      0x0040		/* Bit 2 */
+  #define TIM_SMCR_MSM       0x0080		/* Master/slave mode                       */
+  #define TIM_SMCR_ETF       0x0F00		/* ETF[3:0] bits (External trigger filter) */
+  #define TIM_SMCR_ETF_0     0x0100		/* Bit 0 */
+  #define TIM_SMCR_ETF_1     0x0200		/* Bit 1 */
+  #define TIM_SMCR_ETF_2     0x0400		/* Bit 2 */
+  #define TIM_SMCR_ETF_3     0x0800		/* Bit 3 */
+  #define TIM_SMCR_ETPS      0x3000		/* ETPS[1:0] bits (External trigger prescaler) */
+  #define TIM_SMCR_ETPS_0    0x1000		/* Bit 0 */
+  #define TIM_SMCR_ETPS_1    0x2000		/* Bit 1 */
+  #define TIM_SMCR_ECE       0x4000		/* External clock enable     */
+  #define TIM_SMCR_ETP       0x8000		/* External trigger polarity */
+#define TOFF_TIM_DIER       0x000C		/* (RW) TIM DMA/interrupt enable register */
+  #define TIM_DIER_UIE       0x0001		/* Update interrupt enable */
+  #define TIM_DIER_CC1IE     0x0002		/* Capture/Compare 1 interrupt enable */
+  #define TIM_DIER_CC2IE     0x0004		/* Capture/Compare 2 interrupt enable */
+  #define TIM_DIER_CC3IE     0x0008		/* Capture/Compare 3 interrupt enable */
+  #define TIM_DIER_CC4IE     0x0010		/* Capture/Compare 4 interrupt enable */
+  #define TIM_DIER_COMIE     0x0020		/* COM interrupt enable */
+  #define TIM_DIER_TIE       0x0040		/* Trigger interrupt enable */
+  #define TIM_DIER_BIE       0x0080		/* Break interrupt enable */
+  #define TIM_DIER_UDE       0x0100		/* Update DMA request enable */
+  #define TIM_DIER_CC1DE     0x0200		/* Capture/Compare 1 DMA request enable */
+  #define TIM_DIER_CC2DE     0x0400		/* Capture/Compare 2 DMA request enable */
+  #define TIM_DIER_CC3DE     0x0800		/* Capture/Compare 3 DMA request enable */
+  #define TIM_DIER_CC4DE     0x1000		/* Capture/Compare 4 DMA request enable */
+  #define TIM_DIER_COMDE     0x2000		/* COM DMA request enable */
+  #define TIM_DIER_TDE       0x4000		/* Trigger DMA request enable */
+#define TOFF_TIM_SR         0x0010		/* (RW) TIM status register */
+  #define TIM_SR_UIF         0x0001		/* Update interrupt Flag */
+  #define TIM_SR_CC1IF       0x0002		/* Capture/Compare 1 interrupt Flag */
+  #define TIM_SR_CC2IF       0x0004		/* Capture/Compare 2 interrupt Flag */
+  #define TIM_SR_CC3IF       0x0008		/* Capture/Compare 3 interrupt Flag */
+  #define TIM_SR_CC4IF       0x0010		/* Capture/Compare 4 interrupt Flag */
+  #define TIM_SR_COMIF       0x0020		/* COM interrupt Flag */
+  #define TIM_SR_TIF         0x0040		/* Trigger interrupt Flag */
+  #define TIM_SR_BIF         0x0080		/* Break interrupt Flag */
+  #define TIM_SR_CC1OF       0x0200		/* Capture/Compare 1 Overcapture Flag */
+  #define TIM_SR_CC2OF       0x0400		/* Capture/Compare 2 Overcapture Flag */
+  #define TIM_SR_CC3OF       0x0800		/* Capture/Compare 3 Overcapture Flag */
+  #define TIM_SR_CC4OF       0x1000		/* Capture/Compare 4 Overcapture Flag */
+#define TOFF_TIM_EGR        0x0014		/* (RW) TIM event generation register */
+  #define TIM_EGR_UG         0x00000001	/* Update Generation */
+  #define TIM_EGR_CC1G       0x00000002	/* Capture/Compare 1 Generation */
+  #define TIM_EGR_CC2G       0x00000004	/* Capture/Compare 2 Generation */
+  #define TIM_EGR_CC3G       0x00000008	/* Capture/Compare 3 Generation */
+  #define TIM_EGR_CC4G       0x00000010	/* Capture/Compare 4 Generation              */
+  #define TIM_EGR_COMG       0x00000020	/* Capture/Compare Control Update Generation */
+  #define TIM_EGR_TG         0x00000040	/* Trigger Generation */
+  #define TIM_EGR_BG         0x00000080	/* Break Generation */
+  #define TIM_EGR_B2G        0x00000100	/* Break2 Generation */
+#define TOFF_TIM_CCMR1      0x0018		/* (RW) TIM capture/compare mode register 1 */
+  #define TIM_CCMR1_CC1S     0x00000003	/* CC1S[1:0] bits (Capture/Compare 1 Selection) */
+  #define TIM_CCMR1_CC1S_0   0x00000001	/* Bit 0 */
+  #define TIM_CCMR1_CC1S_1   0x00000002	/* Bit 1 */
+  #define TIM_CCMR1_OC1FE    0x00000004	/* Output Compare 1 Fast enable                 */
+  #define TIM_CCMR1_OC1PE    0x00000008	/* Output Compare 1 Preload enable              */
+  #define TIM_CCMR1_OC1M     0x00010070	/* OC1M[2:0] bits (Output Compare 1 Mode)       */
+  #define TIM_CCMR1_OC1M_0   0x00000010	/* Bit 0 */
+  #define TIM_CCMR1_OC1M_1   0x00000020	/* Bit 1 */
+  #define TIM_CCMR1_OC1M_2   0x00000040	/* Bit 2 */
+  #define TIM_CCMR1_OC1M_3   0x00010000	/* Bit 3 */
+  #define TIM_CCMR1_OC1CE    0x00000080	/* Output Compare 1Clear Enable                 */
+  #define TIM_CCMR1_CC2S     0x00000300	/* CC2S[1:0] bits (Capture/Compare 2 Selection) */
+  #define TIM_CCMR1_CC2S_0   0x00000100	/* Bit 0 */
+  #define TIM_CCMR1_CC2S_1   0x00000200	/* Bit 1 */
+  #define TIM_CCMR1_OC2FE    0x00000400	/* Output Compare 2 Fast enable                 */
+  #define TIM_CCMR1_OC2PE    0x00000800	/* Output Compare 2 Preload enable              */
+  #define TIM_CCMR1_OC2M     0x01007000	/* OC2M[2:0] bits (Output Compare 2 Mode)       */
+  #define TIM_CCMR1_OC2M_0   0x00001000	/* Bit 0 */
+  #define TIM_CCMR1_OC2M_1   0x00002000	/* Bit 1 */
+  #define TIM_CCMR1_OC2M_2   0x00004000	/* Bit 2 */
+  #define TIM_CCMR1_OC2M_3   0x01000000	/* Bit 3 */
+  #define TIM_CCMR1_IC1PSC   0x000C		/* IC1PSC[1:0] bits (Input Capture 1 Prescaler) */
+  #define TIM_CCMR1_IC1PSC_0 0x0004		/* Bit 0 */
+  #define TIM_CCMR1_IC1PSC_1 0x0008		/* Bit 1 */
+  #define TIM_CCMR1_IC1F     0x00F0		/* IC1F[3:0] bits (Input Capture 1 Filter)      */
+  #define TIM_CCMR1_IC1F_0   0x0010		/* Bit 0 */
+  #define TIM_CCMR1_IC1F_1   0x0020		/* Bit 1 */
+  #define TIM_CCMR1_IC1F_2   0x0040		/* Bit 2 */
+  #define TIM_CCMR1_IC1F_3   0x0080		/* Bit 3 */
+  #define TIM_CCMR1_IC2PSC   0x0C00		/* IC2PSC[1:0] bits (Input Capture 2 Prescaler)  */
+  #define TIM_CCMR1_IC2PSC_0 0x0400		/* Bit 0 */
+  #define TIM_CCMR1_IC2PSC_1 0x0800		/* Bit 1 */
+  #define TIM_CCMR1_IC2F     0xF000		/* IC2F[3:0] bits (Input Capture 2 Filter)       */
+  #define TIM_CCMR1_IC2F_0   0x1000		/* Bit 0 */
+  #define TIM_CCMR1_IC2F_1   0x2000		/* Bit 1 */
+  #define TIM_CCMR1_IC2F_2   0x4000		/* Bit 2 */
+  #define TIM_CCMR1_IC2F_3   0x8000		/* Bit 3 */
+  #define TIM_CCMR1_OC2CE    0x00008000	/* Output Compare 2 Clear Enable */
+#define TOFF_TIM_CCMR2      0x001C		/* (RW) TIM capture/compare mode register 2 */
+  #define TIM_CCMR2_CC3S     0x00000003	/* CC3S[1:0] bits (Capture/Compare 3 Selection)  */
+  #define TIM_CCMR2_CC3S_0   0x00000001	/* Bit 0 */
+  #define TIM_CCMR2_CC3S_1   0x00000002	/* Bit 1 */
+  #define TIM_CCMR2_OC3FE    0x00000004	/* Output Compare 3 Fast enable           */
+  #define TIM_CCMR2_OC3PE    0x00000008	/* Output Compare 3 Preload enable        */
+  #define TIM_CCMR2_OC3M     0x00010070	/* OC3M[2:0] bits (Output Compare 3 Mode) */
+  #define TIM_CCMR2_OC3M_0   0x00000010	/* Bit 0 */
+  #define TIM_CCMR2_OC3M_1   0x00000020	/* Bit 1 */
+  #define TIM_CCMR2_OC3M_2   0x00000040	/* Bit 2 */
+  #define TIM_CCMR2_OC3M_3   0x00010000	/* Bit 3 */
+  #define TIM_CCMR2_OC3CE    0x00000080	/* Output Compare 3 Clear Enable */
+  #define TIM_CCMR2_CC4S     0x00000300	/* CC4S[1:0] bits (Capture/Compare 4 Selection) */
+  #define TIM_CCMR2_CC4S_0   0x00000100	/* Bit 0 */
+  #define TIM_CCMR2_CC4S_1   0x00000200	/* Bit 1 */
+  #define TIM_CCMR2_OC4FE    0x00000400	/* Output Compare 4 Fast enable    */
+  #define TIM_CCMR2_OC4PE    0x00000800	/* Output Compare 4 Preload enable */
+  #define TIM_CCMR2_OC4M     0x01007000	/* OC4M[2:0] bits (Output Compare 4 Mode) */
+  #define TIM_CCMR2_OC4M_0   0x00001000	/* Bit 0 */
+  #define TIM_CCMR2_OC4M_1   0x00002000	/* Bit 1 */
+  #define TIM_CCMR2_OC4M_2   0x00004000	/* Bit 2 */
+  #define TIM_CCMR2_OC4M_3   0x01000000	/* Bit 3 */
+  #define TIM_CCMR2_OC4CE    0x8000		/* Output Compare 4 Clear Enable */
+  #define TIM_CCMR2_IC3PSC   0x000C		/* IC3PSC[1:0] bits (Input Capture 3 Prescaler) */
+  #define TIM_CCMR2_IC3PSC_0 0x0004		/* Bit 0 */
+  #define TIM_CCMR2_IC3PSC_1 0x0008		/* Bit 1 */
+  #define TIM_CCMR2_IC3F     0x00F0		/* IC3F[3:0] bits (Input Capture 3 Filter) */
+  #define TIM_CCMR2_IC3F_0   0x0010		/* Bit 0 */
+  #define TIM_CCMR2_IC3F_1   0x0020		/* Bit 1 */
+  #define TIM_CCMR2_IC3F_2   0x0040		/* Bit 2 */
+  #define TIM_CCMR2_IC3F_3   0x0080		/* Bit 3 */
+  #define TIM_CCMR2_IC4PSC   0x0C00		/* IC4PSC[1:0] bits (Input Capture 4 Prescaler) */
+  #define TIM_CCMR2_IC4PSC_0 0x0400		/* Bit 0 */
+  #define TIM_CCMR2_IC4PSC_1 0x0800		/* Bit 1 */
+  #define TIM_CCMR2_IC4F     0xF000		/* IC4F[3:0] bits (Input Capture 4 Filter) */
+  #define TIM_CCMR2_IC4F_0   0x1000		/* Bit 0 */
+  #define TIM_CCMR2_IC4F_1   0x2000		/* Bit 1 */
+  #define TIM_CCMR2_IC4F_2   0x4000		/* Bit 2 */
+  #define TIM_CCMR2_IC4F_3   0x8000		/* Bit 3 */
+#define TOFF_TIM_CCER       0x0020		/* (RW) TIM capture/compare enable register */
+  #define TIM_CCER_CC1E      0x00000001	/* Capture/Compare 1 output enable */
+  #define TIM_CCER_CC1P      0x00000002	/* Capture/Compare 1 output Polarity */
+  #define TIM_CCER_CC1NE     0x00000004	/* Capture/Compare 1 Complementary output enable */
+  #define TIM_CCER_CC1NP     0x00000008	/* Capture/Compare 1 Complementary output Polarity */
+  #define TIM_CCER_CC2E      0x00000010	/* Capture/Compare 2 output enable */
+  #define TIM_CCER_CC2P      0x00000020	/* Capture/Compare 2 output Polarity */
+  #define TIM_CCER_CC2NE     0x00000040	/* Capture/Compare 2 Complementary output enable */
+  #define TIM_CCER_CC2NP     0x00000080	/* Capture/Compare 2 Complementary output Polarity */
+  #define TIM_CCER_CC3E      0x00000100	/* Capture/Compare 3 output enable */
+  #define TIM_CCER_CC3P      0x00000200	/* Capture/Compare 3 output Polarity */
+  #define TIM_CCER_CC3NE     0x00000400	/* Capture/Compare 3 Complementary output enable */
+  #define TIM_CCER_CC3NP     0x00000800	/* Capture/Compare 3 Complementary output Polarity */
+  #define TIM_CCER_CC4E      0x00001000	/* Capture/Compare 4 output enable */
+  #define TIM_CCER_CC4P      0x00002000	/* Capture/Compare 4 output Polarity */
+  #define TIM_CCER_CC4NP     0x00008000	/* Capture/Compare 4 Complementary output Polarity */
+  #define TIM_CCER_CC5E      0x00010000	/* Capture/Compare 5 output enable */
+  #define TIM_CCER_CC5P      0x00020000	/* Capture/Compare 5 output Polarity */
+  #define TIM_CCER_CC6E      0x00100000	/* Capture/Compare 6 output enable */
+  #define TIM_CCER_CC6P      0x00200000	/* Capture/Compare 6 output Polarity */
+#define TOFF_TIM_CNT        0x0024		/* (RW) TIM counter register */
+#define TOFF_TIM_PSC        0x0028		/* (RW) TIM prescaler */
+#define TOFF_TIM_ARR        0x002C		/* (RW) TIM auto-reload register */
+#define TOFF_TIM_RCR        0x0030		/* (RW) TIM repetition counter register */
+#define TOFF_TIM_CCR1       0x0034		/* (RW) TIM capture/compare register 1 */
+#define TOFF_TIM_CCR2       0x0038		/* (RW) TIM capture/compare register 2 */
+#define TOFF_TIM_CCR3       0x003C		/* (RW) TIM capture/compare register 3 */
+#define TOFF_TIM_CCR4       0x0040		/* (RW) TIM capture/compare register 4 */
+#define TOFF_TIM_BDTR       0x0044		/* (RW) TIM break and dead-time register */
+  #define TIM_BDTR_DTG       0x000000FF	/* DTG[0:7] bits (Dead-Time Generator set-up) */
+  #define TIM_BDTR_DTG_0     0x00000001	/* Bit 0 */
+  #define TIM_BDTR_DTG_1     0x00000002	/* Bit 1 */
+  #define TIM_BDTR_DTG_2     0x00000004	/* Bit 2 */
+  #define TIM_BDTR_DTG_3     0x00000008	/* Bit 3 */
+  #define TIM_BDTR_DTG_4     0x00000010	/* Bit 4 */
+  #define TIM_BDTR_DTG_5     0x00000020	/* Bit 5 */
+  #define TIM_BDTR_DTG_6     0x00000040	/* Bit 6 */
+  #define TIM_BDTR_DTG_7     0x00000080	/* Bit 7 */
+  #define TIM_BDTR_LOCK      0x00000300	/* LOCK[1:0] bits (Lock Configuration) */
+  #define TIM_BDTR_LOCK_0    0x00000100	/* Bit 0 */
+  #define TIM_BDTR_LOCK_1    0x00000200	/* Bit 1 */
+  #define TIM_BDTR_OSSI      0x00000400	/* Off-State Selection for Idle mode */
+  #define TIM_BDTR_OSSR      0x00000800	/* Off-State Selection for Run mode  */
+  #define TIM_BDTR_BKE       0x00001000	/* Break enable                      */
+  #define TIM_BDTR_BKP       0x00002000	/* Break Polarity                    */
+  #define TIM_BDTR_AOE       0x00004000	/* Automatic Output enable           */
+  #define TIM_BDTR_MOE       0x00008000	/* Main Output enable                */
+  #define TIM_BDTR_BKF       0x000F0000	/* Break Filter for Break1 */
+  #define TIM_BDTR_BK2F      0x00F00000	/* Break Filter for Break2 */
+  #define TIM_BDTR_BK2E      0x01000000	/* Break enable for Break2 */
+  #define TIM_BDTR_BK2P      0x02000000	/* Break Polarity for Break2 */
+#define TOFF_TIM_DCR        0x0048		/* (RW) TIM DMA control register */
+  #define TIM_DCR_DBA        0x001F		/* DBA[4:0] bits (DMA Base Address) */
+  #define TIM_DCR_DBA_0      0x0001		/* Bit 0 */
+  #define TIM_DCR_DBA_1      0x0002		/* Bit 1 */
+  #define TIM_DCR_DBA_2      0x0004		/* Bit 2 */
+  #define TIM_DCR_DBA_3      0x0008		/* Bit 3 */
+  #define TIM_DCR_DBA_4      0x0010		/* Bit 4 */
+  #define TIM_DCR_DBL        0x1F00		/* DBL[4:0] bits (DMA Burst Length) */
+  #define TIM_DCR_DBL_0      0x0100		/* Bit 0 */
+  #define TIM_DCR_DBL_1      0x0200		/* Bit 1 */
+  #define TIM_DCR_DBL_2      0x0400		/* Bit 2 */
+  #define TIM_DCR_DBL_3      0x0800		/* Bit 3 */
+  #define TIM_DCR_DBL_4      0x1000		/* Bit 4 */
+#define TOFF_TIM_DMAR       0x004C		/* (RW) TIM DMA address for full transfer */
+#define TOFF_TIM_OR         0x0050		/* (RW) TIM option register */
+  #define TIM_OR_TI4_RMP     0x00C0		/* TI4_RMP[1:0] bits (TIM5 Input 4 remap)             */
+  #define TIM_OR_TI4_RMP_0   0x0040		/* Bit 0 */
+  #define TIM_OR_TI4_RMP_1   0x0080		/* Bit 1 */
+  #define TIM_OR_ITR1_RMP    0x0C00		/* ITR1_RMP[1:0] bits (TIM2 Internal trigger 1 remap) */
+  #define TIM_OR_ITR1_RMP_0  0x0400		/* Bit 0 */
+  #define TIM_OR_ITR1_RMP_1  0x0800		/* Bit 1 */
+#define TOFF_TIM_CCMR3      0x0054		/* (RW) TIM capture/compare mode register 3 */
+  #define TIM_CCMR3_OC5FE    0x00000004	/* Output Compare 5 Fast enable */
+  #define TIM_CCMR3_OC5PE    0x00000008	/* Output Compare 5 Preload enable */
+  #define TIM_CCMR3_OC5M     0x00010070	/* OC5M[2:0] bits (Output Compare 5 Mode) */
+  #define TIM_CCMR3_OC5M_0   0x00000010	/* Bit 0 */
+  #define TIM_CCMR3_OC5M_1   0x00000020	/* Bit 1 */
+  #define TIM_CCMR3_OC5M_2   0x00000040	/* Bit 2 */
+  #define TIM_CCMR3_OC5M_3   0x00010000	/* Bit 3 */
+  #define TIM_CCMR3_OC5CE    0x00000080	/* Output Compare 5 Clear Enable */
+  #define TIM_CCMR3_OC6FE    0x00000400	/* Output Compare 4 Fast enable */
+  #define TIM_CCMR3_OC6PE    0x00000800	/* Output Compare 4 Preload enable */
+  #define TIM_CCMR3_OC6M     0x01007000	/* OC4M[2:0] bits (Output Compare 4 Mode) */
+  #define TIM_CCMR3_OC6M_0   0x00001000	/* Bit 0 */
+  #define TIM_CCMR3_OC6M_1   0x00002000	/* Bit 1 */
+  #define TIM_CCMR3_OC6M_2   0x00004000	/* Bit 2 */
+  #define TIM_CCMR3_OC6M_3   0x01000000	/* Bit 3 */
+  #define TIM_CCMR3_OC6CE    0x00008000	/* Output Compare 4 Clear Enable */
+#define TOFF_TIM_CCR5       0x0058		/* (RW) TIM capture/compare mode register5 */
+  #define TIM_CCR5_CCR5      0xFFFFFFFF	/* Capture/Compare 5 Value */
+  #define TIM_CCR5_GC5C1     0x20000000	/* Group Channel 5 and Channel 1 */
+  #define TIM_CCR5_GC5C2     0x40000000	/* Group Channel 5 and Channel 2 */
+  #define TIM_CCR5_GC5C3     0x80000000	/* Group Channel 5 and Channel 3 */
+#define TOFF_TIM_CCR6       0x005C		/* (RW) TIM capture/compare mode register6 */
+
+/*
+ *  LPTIMIMER
+ */
+#define TADR_LPTIM1_BASE    (APB1PERIPH_BASE + 0x2400)
+#define TOFF_LPTIM_ISR      0x0000		/* (RW) LPTIM Interrupt and Status register */
+  #define LPTIM_ISR_CMPM     0x00000001	/* Compare match                       */
+  #define LPTIM_ISR_ARRM     0x00000002	/* Autoreload match                    */
+  #define LPTIM_ISR_EXTTRIG  0x00000004	/* External trigger edge event         */
+  #define LPTIM_ISR_CMPOK    0x00000008	/* Compare register update OK          */
+  #define LPTIM_ISR_ARROK    0x00000010	/* Autoreload register update OK       */
+  #define LPTIM_ISR_UP       0x00000020	/* Counter direction change down to up */
+  #define LPTIM_ISR_DOWN     0x00000040	/* Counter direction change up to down */
+#define TOFF_LPTIM_ICR      0x0004		/* (RW) LPTIM Interrupt Clear register */
+  #define LPTIM_ICR_CMPMCF   0x00000001	/* Compare match Clear Flag                       */
+  #define LPTIM_ICR_ARRMCF   0x00000002	/* Autoreload match Clear Flag                    */
+  #define LPTIM_ICR_EXTTRIGCF 0x00000004 /* External trigger edge event Clear Flag         */
+  #define LPTIM_ICR_CMPOKCF  0x00000008	/* Compare register update OK Clear Flag          */
+  #define LPTIM_ICR_ARROKCF  0x00000010	/* Autoreload register update OK Clear Flag       */
+  #define LPTIM_ICR_UPCF     0x00000020	/* Counter direction change down to up Clear Flag */
+  #define LPTIM_ICR_DOWNCF   0x00000040	/* Counter direction change up to down Clear Flag */
+#define TOFF_LPTIM_IER      0x0008		/* (RW) LPTIM Interrupt Enable register */
+  #define LPTIM_IER_CMPMIE   0x00000001	/* Compare match Interrupt Enable                       */
+  #define LPTIM_IER_ARRMIE   0x00000002	/* Autoreload match Interrupt Enable                    */
+  #define LPTIM_IER_EXTTRIGIE 0x00000004 /* External trigger edge event Interrupt Enable         */
+  #define LPTIM_IER_CMPOKIE  0x00000008	/* Compare register update OK Interrupt Enable          */
+  #define LPTIM_IER_ARROKIE  0x00000010	/* Autoreload register update OK Interrupt Enable       */
+  #define LPTIM_IER_UPIE     0x00000020	/* Counter direction change down to up Interrupt Enable */
+  #define LPTIM_IER_DOWNIE   0x00000040	/* Counter direction change up to down Interrupt Enable */
+#define TOFF_LPTIM_CFGR     0x000C		/* (RW) LPTIM Configuration register */
+  #define LPTIM_CFGR_CKSEL   0x00000001	/* Clock selector */
+  #define LPTIM_CFGR_CKPOL   0x00000006	/* CKPOL[1:0] bits (Clock polarity) */
+  #define LPTIM_CFGR_CKPOL_0 0x00000002	/* Bit 0 */
+  #define LPTIM_CFGR_CKPOL_1 0x00000004	/* Bit 1 */
+  #define LPTIM_CFGR_CKFLT   0x00000018	/* CKFLT[1:0] bits (Configurable digital filter for external clock) */
+  #define LPTIM_CFGR_CKFLT_0 0x00000008	/* Bit 0 */
+  #define LPTIM_CFGR_CKFLT_1 0x00000010	/* Bit 1 */
+  #define LPTIM_CFGR_TRGFLT  0x000000C0	/* TRGFLT[1:0] bits (Configurable digital filter for trigger) */
+  #define LPTIM_CFGR_TRGFLT_0 0x00000040	/* Bit 0 */
+  #define LPTIM_CFGR_TRGFLT_1 0x00000080	/* Bit 1 */
+  #define LPTIM_CFGR_PRESC   0x00000E00	/* PRESC[2:0] bits (Clock prescaler) */
+  #define LPTIM_CFGR_PRESC_0 0x00000200	/* Bit 0 */
+  #define LPTIM_CFGR_PRESC_1 0x00000400	/* Bit 1 */
+  #define LPTIM_CFGR_PRESC_2 0x00000800	/* Bit 2 */
+  #define LPTIM_CFGR_TRIGSEL 0x0000E000	/* TRIGSEL[2:0]] bits (Trigger selector) */
+  #define LPTIM_CFGR_TRIGSEL_0 0x00002000	/* Bit 0 */
+  #define LPTIM_CFGR_TRIGSEL_1 0x00004000	/* Bit 1 */
+  #define LPTIM_CFGR_TRIGSEL_2 0x00008000	/* Bit 2 */
+  #define LPTIM_CFGR_TRIGEN  0x00060000	/* TRIGEN[1:0] bits (Trigger enable and polarity) */
+  #define LPTIM_CFGR_TRIGEN_0 0x00020000	/* Bit 0 */
+  #define LPTIM_CFGR_TRIGEN_1 0x00040000	/* Bit 1 */
+  #define LPTIM_CFGR_TIMOUT  0x00080000	/* Timout enable           */
+  #define LPTIM_CFGR_WAVE    0x00100000	/* Waveform shape          */
+  #define LPTIM_CFGR_WAVPOL  0x00200000	/* Waveform shape polarity */
+  #define LPTIM_CFGR_PRELOAD 0x00400000	/* Reg update mode         */
+  #define LPTIM_CFGR_COUNTMODE 0x00800000	/* Counter mode enable     */     
+  #define LPTIM_CFGR_ENC     0x01000000	/* Encoder mode enable     */          
+#define TOFF_LPTIM_CR       0x0010		/* (RW) LPTIM Control register */
+  #define LPTIM_CR_ENABLE    0x00000001	/* LPTIMer enable                 */
+  #define LPTIM_CR_SNGSTRT   0x00080002	/* Timer start in single mode     */
+  #define LPTIM_CR_CNTSTRT   0x00000004	/* Timer start in continuous mode */
+#define TOFF_LPTIM_CMP      0x0014		/* (RW) LPTIM Compare register */
+#define TOFF_LPTIM_ARR      0x0018		/* (RW) LPTIM Autoreload register */
+#define TOFF_LPTIM_CNT      0x001C		/* (RW) LPTIM Counter register */
+#define TOFF_LPTIM_OR       0x0020		/* (RW) LPTIM Option register */
+
+
+/*
+ *  REAL-TIME CLOCK
+ */
+#define TADR_RTC_BASE       (APB1PERIPH_BASE + 0x2800)
+#define TOFF_RTC_TR         0x0000		/* (RW) RTC time register */
+  #define RTC_TR_SU          0x0000000F
+  #define RTC_TR_ST          0x00000070
+  #define RTC_TR_MNU         0x00000F00
+  #define RTC_TR_MNT         0x00007000
+  #define RTC_TR_HU          0x000F0000
+  #define RTC_TR_HT          0x00300000
+  #define RTC_TR_PM          0x00400000
+#define TOFF_RTC_DR         0x0004		/* (RW) RTC date register */
+  #define RTC_DR_DU          0x0000000F
+  #define RTC_DR_DT          0x00000030
+  #define RTC_DR_MU          0x00000F00
+  #define RTC_DR_MT          0x00001000
+  #define RTC_DR_WDU         0x0000E000
+  #define RTC_DR_YU          0x000F0000
+  #define RTC_DR_YT          0x00F00000
+#define TOFF_RTC_CR         0x0008		/* (RW) RTC control register */
+  #define RTC_CR_WUCKSEL     0x00000007
+  #define RTC_CR_WUCKSEL_0   0x00000001
+  #define RTC_CR_WUCKSEL_1   0x00000002
+  #define RTC_CR_WUCKSEL_2   0x00000004
+  #define RTC_CR_TSEDGE      0x00000008
+  #define RTC_CR_REFCKON     0x00000010
+  #define RTC_CR_BYPSHAD     0x00000020
+  #define RTC_CR_FMT         0x00000040
+  #define RTC_CR_ALRAE       0x00000100
+  #define RTC_CR_ALRBE       0x00000200
+  #define RTC_CR_WUTE        0x00000400
+  #define RTC_CR_TSE         0x00000800
+  #define RTC_CR_ALRAIE      0x00001000
+  #define RTC_CR_ALRBIE      0x00002000
+  #define RTC_CR_WUTIE       0x00004000
+  #define RTC_CR_TSIE        0x00008000
+  #define RTC_CR_ADD1H       0x00010000
+  #define RTC_CR_SUB1H       0x00020000
+  #define RTC_CR_BCK         0x00040000
+  #define RTC_CR_BKP         RTC_CR_BCK
+  #define RTC_CR_COSEL       0x00080000
+  #define RTC_CR_POL         0x00100000
+  #define RTC_CR_OSEL        0x00600000
+  #define RTC_CR_OSEL_0      0x00200000
+  #define RTC_CR_OSEL_1      0x00400000
+  #define RTC_CR_COE         0x00800000
+  #define RTC_CR_ITSE        0x01000000
+#define TOFF_RTC_ISR        0x000C		/* (RW) RTC initialization and status register */
+  #define RTC_ISR_ALRAWF     0x00000001
+  #define RTC_ISR_ALRBWF     0x00000002
+  #define RTC_ISR_WUTWF      0x00000004
+  #define RTC_ISR_SHPF       0x00000008
+  #define RTC_ISR_INITS      0x00000010
+  #define RTC_ISR_RSF        0x00000020
+  #define RTC_ISR_INITF      0x00000040
+  #define RTC_ISR_INIT       0x00000080
+  #define RTC_ISR_ALRAF      0x00000100
+  #define RTC_ISR_ALRBF      0x00000200
+  #define RTC_ISR_WUTF       0x00000400
+  #define RTC_ISR_TSF        0x00000800
+  #define RTC_ISR_TSOVF      0x00001000
+  #define RTC_ISR_TAMP1F     0x00002000
+  #define RTC_ISR_TAMP2F     0x00004000
+  #define RTC_ISR_TAMP3F     0x00008000
+  #define RTC_ISR_RECALPF    0x00010000
+  #define RTC_ISR_ITSF       0x00020000
+#define TOFF_RTC_PRER       0x0010		/* (RW) RTC prescaler register */
+#define TOFF_RTC_WUTR       0x0014		/* (RW) RTC wakeup timer register */
+#define TOFF_RTC_ALRMAR     0x001C		/* (RW) RTC alarm A register */
+
+  #define RTC_ALRMAR_SU      0x0000000F
+  #define RTC_ALRMAR_ST      0x00000070
+  #define RTC_ALRMAR_MSK1    0x00000080
+  #define RTC_ALRMAR_MNU     0x00000F00
+  #define RTC_ALRMAR_MNT     0x00007000
+  #define RTC_ALRMAR_MSK2    0x00008000
+  #define RTC_ALRMAR_HU      0x000F0000
+  #define RTC_ALRMAR_HT      0x00300000
+  #define RTC_ALRMAR_PM      0x00400000
+  #define RTC_ALRMAR_MSK3    0x00800000
+  #define RTC_ALRMAR_DU      0x0F000000
+  #define RTC_ALRMAR_DT      0x30000000
+  #define RTC_ALRMAR_WDSEL   0x40000000
+  #define RTC_ALRMAR_MSK4    0x80000000
+
+#define TOFF_RTC_ALRMBR     0x0020		/* (RW) RTC alarm B register */
+#define TOFF_RTC_WPR        0x0024		/* (RW) RTC write protection register */
+#define TOFF_RTC_SSR        0x0028		/* (RW) RTC sub second register */
+#define TOFF_RTC_SHIFTR     0x002C		/* (RW) RTC shift control register */
+#define TOFF_RTC_TSTR       0x0030		/* (RW) RTC time stamp time register */
+#define TOFF_RTC_TSDR       0x0034		/* (RW) RTC time stamp date register */
+#define TOFF_RTC_TSSSR      0x0038		/* (RW) RTC time-stamp sub second register */
+#define TOFF_RTC_CALR       0x003C		/* (RW) RTC calibration register */
+#define TOFF_RTC_TAFCR      0x0040		/* (RW) RTC tamper and alternate function configuration register */
+#define TOFF_RTC_TAMPCR     TOFF_RTC_TAFCR
+#define TOFF_RTC_ALRMASSR   0x0044		/* (RW) RTC alarm A sub second register */
+  #define RTC_ALRMASSR_SS    0x00007FFF
+#define TOFF_RTC_ALRMBSSR   0x0048		/* (RW) RTC alarm B sub second register */
+  #define RTC_ALRMBSSR_SS    0x00007FFF
+#define TOFF_RTC_OR         0x004C		/* (RW) RTC option register */
+  #define RTC_OR_TSINSEL     0x00000006
+  #define RTC_OR_TSINSEL_0   0x00000002
+  #define RTC_OR_TSINSEL_1   0x00000004
+  #define RTC_OR_ALARMTYPE   0x00000008
+#define TOFF_RTC_BKP0R      0x0050		/* (RW) RTC backup register 0 */
+#define TOFF_RTC_BKP1R      0x0054		/* (RW) RTC backup register 1 */
+#define TOFF_RTC_BKP2R      0x0058		/* (RW) RTC backup register 2 */
+#define TOFF_RTC_BKP3R      0x005C		/* (RW) RTC backup register 3 */
+#define TOFF_RTC_BKP4R      0x0060		/* (RW) RTC backup register 4 */
+#define TOFF_RTC_BKP5R      0x0064		/* (RW) RTC backup register 5 */
+#define TOFF_RTC_BKP6R      0x0068		/* (RW) RTC backup register 6 */
+#define TOFF_RTC_BKP7R      0x006C		/* (RW) RTC backup register 7 */
+#define TOFF_RTC_BKP8R      0x0070		/* (RW) RTC backup register 8 */
+#define TOFF_RTC_BKP9R      0x0074		/* (RW) RTC backup register 9 */
+#define TOFF_RTC_BKP10R     0x0078		/* (RW) RTC backup register 10 */
+#define TOFF_RTC_BKP11R     0x007C		/* (RW) RTC backup register 11 */
+#define TOFF_RTC_BKP12R     0x0080		/* (RW) RTC backup register 12 */
+#define TOFF_RTC_BKP13R     0x0084		/* (RW) RTC backup register 13 */
+#define TOFF_RTC_BKP14R     0x0088		/* (RW) RTC backup register 14 */
+#define TOFF_RTC_BKP15R     0x008C		/* (RW) RTC backup register 15 */
+#define TOFF_RTC_BKP16R     0x0090		/* (RW) RTC backup register 16 */
+#define TOFF_RTC_BKP17R     0x0094		/* (RW) RTC backup register 17 */
+#define TOFF_RTC_BKP18R     0x0098		/* (RW) RTC backup register 18 */
+#define TOFF_RTC_BKP19R     0x009C		/* (RW) RTC backup register 19 */
+#define TOFF_RTC_BKP20R     0x00A0		/* (RW) RTC backup register 20 */
+#define TOFF_RTC_BKP21R     0x00A4		/* (RW) RTC backup register 21 */
+#define TOFF_RTC_BKP22R     0x00A8		/* (RW) RTC backup register 22 */
+#define TOFF_RTC_BKP23R     0x00AC		/* (RW) RTC backup register 23 */
+#define TOFF_RTC_BKP24R     0x00B0		/* (RW) RTC backup register 24 */
+#define TOFF_RTC_BKP25R     0x00B4		/* (RW) RTC backup register 25 */
+#define TOFF_RTC_BKP26R     0x00B8		/* (RW) RTC backup register 26 */
+#define TOFF_RTC_BKP27R     0x00BC		/* (RW) RTC backup register 27 */
+#define TOFF_RTC_BKP28R     0x00C0		/* (RW) RTC backup register 28 */
+#define TOFF_RTC_BKP29R     0x00C4		/* (RW) RTC backup register 29 */
+#define TOFF_RTC_BKP30R     0x00C8		/* (RW) RTC backup register 30 */
+#define TOFF_RTC_BKP31R     0x00CC		/* (RW) RTC backup register 31 */
+
+/*
+ *  WINDOW WATCHDOG
+ */
+#define TADR_WWDG_BASE      (APB1PERIPH_BASE + 0x2C00)
+#define TOFF_WWDG_CR        0x0000		/* (RW) WWDG Control register */
+  #define WWDG_CR_T           0x0000007F	/* T[6:0] bits (7-Bit counter (MSB to LSB)) */
+  #define WWDG_CR_T_0         0x00000001
+  #define WWDG_CR_T_1         0x00000002
+  #define WWDG_CR_T_2         0x00000004
+  #define WWDG_CR_T_3         0x00000008
+  #define WWDG_CR_T_4         0x00000010
+  #define WWDG_CR_T_5         0x00000020
+  #define WWDG_CR_T_6         0x00000040
+  #define WWDG_CR_T0          WWDG_CR_T_0
+  #define WWDG_CR_T1          WWDG_CR_T_1
+  #define WWDG_CR_T2          WWDG_CR_T_2
+  #define WWDG_CR_T3          WWDG_CR_T_3
+  #define WWDG_CR_T4          WWDG_CR_T_4
+  #define WWDG_CR_T5          WWDG_CR_T_5
+  #define WWDG_CR_T6          WWDG_CR_T_6
+  #define WWDG_CR_WDGA        0x00000080	/* Activation bit */
+#define TOFF_WWDG_CFR       0x0004		/* (RW) WWDG Configuration register */
+  #define WWDG_CFR_W          0x0000007F	/* W[6:0] bits (7-bit window value) */
+  #define WWDG_CFR_W_0        0x00000001
+  #define WWDG_CFR_W_1        0x00000002
+  #define WWDG_CFR_W_2        0x00000004
+  #define WWDG_CFR_W_3        0x00000008
+  #define WWDG_CFR_W_4        0x00000010
+  #define WWDG_CFR_W_5        0x00000020
+  #define WWDG_CFR_W_6        0x00000040
+  #define WWDG_CFR_W0         WWDG_CFR_W_0
+  #define WWDG_CFR_W1         WWDG_CFR_W_1
+  #define WWDG_CFR_W2         WWDG_CFR_W_2
+  #define WWDG_CFR_W3         WWDG_CFR_W_3
+  #define WWDG_CFR_W4         WWDG_CFR_W_4
+  #define WWDG_CFR_W5         WWDG_CFR_W_5
+  #define WWDG_CFR_W6         WWDG_CFR_W_6
+  #define WWDG_CFR_WDGTB      0x00000180	/* WDGTB[1:0] bits (Timer Base) */
+  #define WWDG_CFR_WDGTB_0    0x00000080
+  #define WWDG_CFR_WDGTB_1    0x00000100
+  #define WWDG_CFR_WDGTB0     WWDG_CFR_WDGTB_0
+  #define WWDG_CFR_WDGTB1     WWDG_CFR_WDGTB_1
+  #define WWDG_CFR_EWI        0x00000200	/* Early Wakeup Interrupt */
+#define TOFF_WWDG_SR        0x0008		/* (R)  WWDG Status register */
+  #define WWDG_SR_EWIF        0x00000001	/* Early Wakeup Interrupt Flag */
+
+/*
+ *  INDEPENDENT WATCHDOG
+ */
+#define TADR_IWDG_BASE      (APB1PERIPH_BASE + 0x3000)
+#define TOFF_IWDG_KR        0x0000		/* (RW) IWDG Key register */
+#define TOFF_IWDG_PR        0x0004		/* (RW) IWDG Prescaler register */
+#define TOFF_IWDG_RLR       0x0008		/* (RW) IWDG Reload register */
+#define TOFF_IWDG_SR        0x000C		/* (RW) IWDG Status register */
+#define TOFF_IWDG_WINR      0x0010		/* (RW) IWDG Window register */
+
+/*
+ *  SERIAL PERIPHERAL IINTERFACE
+ */
+#define TADR_SPI2_BASE      (APB1PERIPH_BASE + 0x3800)
+#define TADR_SPI3_BASE      (APB1PERIPH_BASE + 0x3C00)
+#define TADR_SPI1_BASE      (APB2PERIPH_BASE + 0x3000)
+#define TADR_SPI4_BASE      (APB2PERIPH_BASE + 0x3400)
+#define TADR_SPI5_BASE      (APB2PERIPH_BASE + 0x5000)
+#define TADR_SPI6_BASE      (APB2PERIPH_BASE + 0x5400)
+#define TOFF_SPI_CR1        0x0000		/* (RW-16) SPI control register 1 (not used in I2S mode) */
+  #define SPI_CR1_CPHA          0x00000001	/* Clock Phase */
+  #define SPI_CR1_CPOL          0x00000002	/* Clock Polarity */
+  #define SPI_CR1_MSTR          0x00000004	/* Master Selection */
+  #define SPI_CR1_BR            0x00000038	/* BR[2:0] bits (Baud Rate Control) */
+  #define SPI_CR1_BR_0          0x00000008	/* Bit 0 */
+  #define SPI_CR1_BR_1          0x00000010	/* Bit 1 */
+  #define SPI_CR1_BR_2          0x00000020	/* Bit 2 */
+  #define SPI_CR1_SPE           0x00000040	/* SPI Enable */
+  #define SPI_CR1_LSBFIRST      0x00000080	/* Frame Format */
+  #define SPI_CR1_SSI           0x00000100	/* Internal slave select */
+  #define SPI_CR1_SSM           0x00000200	/* Software slave management */
+  #define SPI_CR1_RXONLY        0x00000400	/* Receive only */
+  #define SPI_CR1_CRCL          0x00000800	/* CRC Length */
+  #define SPI_CR1_CRCNEXT       0x00001000	/* Transmit CRC next */
+  #define SPI_CR1_CRCEN         0x00002000	/* Hardware CRC calculation enable */
+  #define SPI_CR1_BIDIOE        0x00004000	/* Output enable in bidirectional mode */
+  #define SPI_CR1_BIDIMODE      0x00008000	/* Bidirectional data mode enable */
+#define TOFF_SPI_CR2        0x0004		/* (RW-16) SPI control register 2 */
+  #define SPI_CR2_RXDMAEN       0x00000001	/* Rx Buffer DMA Enable */
+  #define SPI_CR2_TXDMAEN       0x00000002	/* Tx Buffer DMA Enable */
+  #define SPI_CR2_SSOE          0x00000004	/* SS Output Enable */
+  #define SPI_CR2_NSSP          0x00000008	/* NSS pulse management Enable */
+  #define SPI_CR2_FRF           0x00000010	/* Frame Format Enable */
+  #define SPI_CR2_ERRIE         0x00000020	/* Error Interrupt Enable */
+  #define SPI_CR2_RXNEIE        0x00000040	/* RX buffer Not Empty Interrupt Enable */
+  #define SPI_CR2_TXEIE         0x00000080	/* Tx buffer Empty Interrupt Enable */
+  #define SPI_CR2_DS            0x00000F00	/* DS[3:0] Data Size */
+  #define SPI_CR2_DS_0          0x00000100	/* Bit 0 */
+  #define SPI_CR2_DS_1          0x00000200	/* Bit 1 */
+  #define SPI_CR2_DS_2          0x00000400	/* Bit 2 */
+  #define SPI_CR2_DS_3          0x00000800	/* Bit 3 */
+  #define SPI_CR2_FRXTH         0x00001000	/* FIFO reception Threshold */
+  #define SPI_CR2_LDMARX        0x00002000	/* Last DMA transfer for reception */
+  #define SPI_CR2_LDMATX        0x00004000	/* Last DMA transfer for transmission */
+#define TOFF_SPI_SR         0x0008		/* (RW-16) SPI status register */
+  #define  SPI_SR_RXNE          0x00000001	/* Receive buffer Not Empty  */
+  #define  SPI_SR_TXE           0x00000002	/* Transmit buffer Empty */
+  #define  SPI_SR_CHSIDE        0x00000004	/* Channel side */
+  #define  SPI_SR_UDR           0x00000008	/* Underrun flag */
+  #define  SPI_SR_CRCERR        0x00000010	/* CRC Error flag */
+  #define  SPI_SR_MODF          0x00000020	/* Mode fault */
+  #define  SPI_SR_OVR           0x00000040	/* Overrun flag */
+  #define  SPI_SR_BSY           0x00000080	/* Busy flag */
+  #define  SPI_SR_FRE           0x00000100	/* TI frame format error */
+  #define  SPI_SR_FRLVL         0x00000600	/* FIFO Reception Level */
+  #define  SPI_SR_FRLVL_0       0x00000200	/* Bit 0 */
+  #define  SPI_SR_FRLVL_1       0x00000400	/* Bit 1 */
+  #define  SPI_SR_FTLVL         0x00001800	/* FIFO Transmission Level */
+  #define  SPI_SR_FTLVL_0       0x00000800	/* Bit 0 */
+  #define  SPI_SR_FTLVL_1       0x00001000	/* Bit 1 */
+#define TOFF_SPI_DR         0x000C		/* (RW-16) SPI data register */
+#define TOFF_SPI_CRCPR      0x0010		/* (RW-16) SPI CRC polynomial register (not used in I2S mode) */
+#define TOFF_SPI_RXCRCR     0x0014		/* (RW-16) SPI RX CRC register (not used in I2S mode) */
+#define TOFF_SPI_TXCRCR     0x0018		/* (RW-16) SPI TX CRC register (not used in I2S mode) */
+#define TOFF_SPI_I2SCFGR    0x001C		/* (RW-16) SPI_I2S configuration register */
+  #define SPI_I2SCFGR_CHLEN     0x00000001	/* Channel length (number of bits per audio channel) */
+  #define SPI_I2SCFGR_DATLEN    0x00000006	/* DATLEN[1:0] bits (Data length to be transferred)  */
+  #define SPI_I2SCFGR_DATLEN_0  0x00000002	/* Bit 0 */
+  #define SPI_I2SCFGR_DATLEN_1  0x00000004	/* Bit 1 */
+  #define SPI_I2SCFGR_CKPOL     0x00000008	/* steady state clock polarity */
+  #define SPI_I2SCFGR_I2SSTD    0x00000030	/* I2SSTD[1:0] bits (I2S standard selection) */
+  #define SPI_I2SCFGR_I2SSTD_0  0x00000010	/* Bit 0 */
+  #define SPI_I2SCFGR_I2SSTD_1  0x00000020	/* Bit 1 */
+  #define SPI_I2SCFGR_PCMSYNC   0x00000080	/* PCM frame synchronization */
+  #define SPI_I2SCFGR_I2SCFG    0x00000300	/* I2SCFG[1:0] bits (I2S configuration mode) */
+  #define SPI_I2SCFGR_I2SCFG_0  0x00000100	/* Bit 0 */
+  #define SPI_I2SCFGR_I2SCFG_1  0x00000200	/* Bit 1 */
+  #define SPI_I2SCFGR_I2SE      0x00000400	/* I2S Enable */
+  #define SPI_I2SCFGR_I2SMOD    0x00000800	/* I2S mode selection */
+  #define SPI_I2SCFGR_ASTRTEN   0x00001000	/* Asynchronous start enable */
+#define TOFF_SPI_I2SPR      0x0020		/* (RW-16) SPI_I2S prescaler register */
+
+/*
+ *  SPDIF-RX INTERFACE
+ */
+#define TADR_SPDIFRX_BASE   (APB1PERIPH_BASE + 0x4000)
+#define TOFF_SPDIFRX_CR     0x0000		/* (RW) Control register */
+#define TOFF_SPDIFRX_IMR    0x0004		/* (RW) Interrupt mask register */
+#define TOFF_SPDIFRX_SR     0x0008		/* (RW) Status register */
+#define TOFF_SPDIFRX_IFCR   0x000C		/* (RW) Interrupt Flag Clear register */
+#define TOFF_SPDIFRX_DR     0x0010		/* (RW) Data input register */
+#define TOFF_SPDIFRX_CSR    0x0014		/* (RW) Channel Status register */
+#define TOFF_SPDIFRX_DIR    0x0018		/* (RW) Debug Information register */
+
+
+/*
+ *  UNIVERSAL SYNCHRONOUS ASYNCHORONOUS RECEIVER TRANSMITTER
+ */
+#define TADR_USART2_BASE    (APB1PERIPH_BASE + 0x4400)
+#define TADR_USART3_BASE    (APB1PERIPH_BASE + 0x4800)
+#define TADR_UART4_BASE     (APB1PERIPH_BASE + 0x4C00)
+#define TADR_UART5_BASE     (APB1PERIPH_BASE + 0x5000)
+#define TADR_UART7_BASE     (APB1PERIPH_BASE + 0x7800)
+#define TADR_UART8_BASE     (APB1PERIPH_BASE + 0x7C00)
+#define TADR_USART1_BASE    (APB2PERIPH_BASE + 0x1000)
+#define TADR_USART6_BASE    (APB2PERIPH_BASE + 0x1400)
+#define TOFF_USART_CR1      0x0000		/* (RW) USART Control register 1 */
+  #define USART_CR1_UE       0x00000001	/* USART Enable */
+  #define USART_CR1_RE       0x00000004	/* Receiver Enable */
+  #define USART_CR1_TE       0x00000008	/* Transmitter Enable */
+  #define USART_CR1_IDLEIE   0x00000010	/* IDLE Interrupt Enable */
+  #define USART_CR1_RXNEIE   0x00000020	/* RXNE Interrupt Enable */
+  #define USART_CR1_TCIE     0x00000040	/* Transmission Complete Interrupt Enable */
+  #define USART_CR1_TXEIE    0x00000080	/* TXE Interrupt Enable */
+  #define USART_CR1_PEIE     0x00000100	/* PE Interrupt Enable */
+  #define USART_CR1_PS       0x00000200	/* Parity Selection */
+  #define USART_CR1_PCE      0x00000400	/* Parity Control Enable */
+  #define USART_CR1_WAKE     0x00000800	/* Receiver Wakeup method */
+  #define USART_CR1_M        0x10001000	/* Word length */
+  #define USART_CR1_M_0      0x00001000	/* Word length - Bit 0 */
+  #define USART_CR1_MME      0x00002000	/* Mute Mode Enable */
+  #define USART_CR1_CMIE     0x00004000	/* Character match interrupt enable */
+  #define USART_CR1_OVER8    0x00008000	/* Oversampling by 8-bit or 16-bit mode */
+  #define USART_CR1_DEDT     0x001F0000	/* DEDT[4:0] bits (Driver Enable Deassertion Time) */
+  #define USART_CR1_DEDT_0   0x00010000	/* Bit 0 */
+  #define USART_CR1_DEDT_1   0x00020000	/* Bit 1 */
+  #define USART_CR1_DEDT_2   0x00040000	/* Bit 2 */
+  #define USART_CR1_DEDT_3   0x00080000	/* Bit 3 */
+  #define USART_CR1_DEDT_4   0x00100000	/* Bit 4 */
+  #define USART_CR1_DEAT     0x03E00000	/* DEAT[4:0] bits (Driver Enable Assertion Time)   */
+  #define USART_CR1_DEAT_0   0x00200000	/* Bit 0 */
+  #define USART_CR1_DEAT_1   0x00400000	/* Bit 1 */
+  #define USART_CR1_DEAT_2   0x00800000	/* Bit 2 */
+  #define USART_CR1_DEAT_3   0x01000000	/* Bit 3 */
+  #define USART_CR1_DEAT_4   0x02000000	/* Bit 4 */
+  #define USART_CR1_RTOIE    0x04000000	/* Receive Time Out interrupt enable */
+  #define USART_CR1_EOBIE    0x08000000	/* End of Block interrupt enable */
+  #define USART_CR1_M_1      0x10000000	/* Word length - Bit 1 */
+#define TOFF_USART_CR2      0x0004		/* (RW) USART Control register 2 */
+  #define USART_CR2_ADDM7    0x00000010	/* 7-bit or 4-bit Address Detectio */
+  #define USART_CR2_LBDL     0x00000020	/* LIN Break Detection Length */
+  #define USART_CR2_LBDIE    0x00000040	/* LIN Break Detection Interrupt Enable */
+  #define USART_CR2_LBCL     0x00000100	/* Last Bit Clock pulse */
+  #define USART_CR2_CPHA     0x00000200	/* Clock Phase */
+  #define USART_CR2_CPOL     0x00000400	/* Clock Polarity */
+  #define USART_CR2_CLKEN    0x00000800	/* Clock Enable */
+  #define USART_CR2_STOP     0x00003000	/* STOP[1:0] bits (STOP bits) */
+  #define USART_CR2_STOP_0   0x00001000	/* Bit 0 */
+  #define USART_CR2_STOP_1   0x00002000	/* Bit 1 */
+  #define USART_CR2_LINEN    0x00004000	/* LIN mode enable */
+  #define USART_CR2_SWAP     0x00008000	/* SWAP TX/RX pins */
+  #define USART_CR2_RXINV    0x00010000	/* RX pin active level inversion */
+  #define USART_CR2_TXINV    0x00020000	/* TX pin active level inversion */
+  #define USART_CR2_DATAINV  0x00040000	/* Binary data inversion */
+  #define USART_CR2_MSBFIRST 0x00080000	/* Most Significant Bit First */
+  #define USART_CR2_ABREN    0x00100000	/* Auto Baud-Rate Enable */
+  #define USART_CR2_ABRMODE  0x00600000	/* ABRMOD[1:0] bits (Auto Baud-Rate Mode) */
+  #define USART_CR2_ABRMODE_0 0x00200000	/* Bit 0 */
+  #define USART_CR2_ABRMODE_1 0x00400000	/* Bit 1 */
+  #define USART_CR2_RTOEN    0x00800000	/* Receiver Time-Out enable */
+  #define USART_CR2_ADD      0xFF000000	/* Address of the USART node */
+#define TOFF_USART_CR3      0x0008		/* (RW) USART Control register 3 */
+  #define USART_CR3_EIE      0x00000001	/* Error Interrupt Enable */
+  #define USART_CR3_IREN     0x00000002	/* IrDA mode Enable */
+  #define USART_CR3_IRLP     0x00000004	/* IrDA Low-Power */
+  #define USART_CR3_HDSEL    0x00000008	/* Half-Duplex Selection */
+  #define USART_CR3_NACK     0x00000010	/* SmartCard NACK enable */
+  #define USART_CR3_SCEN     0x00000020	/* SmartCard mode enable */
+  #define USART_CR3_DMAR     0x00000040	/* DMA Enable Receiver  */
+  #define USART_CR3_DMAT     0x00000080	/* DMA Enable Transmitter */
+  #define USART_CR3_RTSE     0x00000100	/* RTS Enable */
+  #define USART_CR3_CTSE     0x00000200	/* CTS Enable */
+  #define USART_CR3_CTSIE    0x00000400	/* CTS Interrupt Enable */
+  #define USART_CR3_ONEBIT   0x00000800	/* One sample bit method enable */
+  #define USART_CR3_OVRDIS   0x00001000	/* Overrun Disable */
+  #define USART_CR3_DDRE     0x00002000	/* DMA Disable on Reception Error */
+  #define USART_CR3_DEM      0x00004000	/* Driver Enable Mode */
+  #define USART_CR3_DEP      0x00008000	/* Driver Enable Polarity Selection */
+  #define USART_CR3_SCARCNT  0x000E0000	/* SCARCNT[2:0] bits (SmartCard Auto-Retry Count) */
+  #define USART_CR3_SCARCNT_0 0x00020000	/* Bit 0 */
+  #define USART_CR3_SCARCNT_1 0x00040000	/* Bit 1 */
+  #define USART_CR3_SCARCNT_2 0x00080000	/* Bit 2 */
+#define TOFF_USART_BRR      0x000C		/* (RW) USART Baud rate register */
+#define TOFF_USART_GTPR     0x0010		/* (RW) USART Guard time and prescaler register */
+#define TOFF_USART_RTOR     0x0014		/* (RW) USART Receiver Time Out register */
+#define TOFF_USART_RQR      0x0018		/* (RW) USART Request register */
+  #define USART_RQR_ABRRQ    0x00000001	/* Auto-Baud Rate Request */
+  #define USART_RQR_SBKRQ    0x00000002	/* Send Break Request */
+  #define USART_RQR_MMRQ     0x00000004	/* Mute Mode Request */
+  #define USART_RQR_RXFRQ    0x00000008	/* Receive Data flush Request */
+  #define USART_RQR_TXFRQ    0x00000010	/* Transmit data flush Request */
+#define TOFF_USART_ISR      0x001C		/* (RW) USART Interrupt and status register */
+  #define USART_ISR_PE       0x00000001	/* Parity Error */
+  #define USART_ISR_FE       0x00000002	/* Framing Error */
+  #define USART_ISR_NE       0x00000004	/* Noise detected Flag */
+  #define USART_ISR_ORE      0x00000008	/* OverRun Error */
+  #define USART_ISR_IDLE     0x00000010	/* IDLE line detected */
+  #define USART_ISR_RXNE     0x00000020	/* Read Data Register Not Empty */
+  #define USART_ISR_TC       0x00000040	/* Transmission Complete */
+  #define USART_ISR_TXE      0x00000080	/* Transmit Data Register Empty */
+  #define USART_ISR_LBD      0x00000100	/* LIN Break Detection Flag */
+  #define USART_ISR_CTSIF    0x00000200	/* CTS interrupt flag */
+  #define USART_ISR_CTS      0x00000400	/* CTS flag */
+  #define USART_ISR_RTOF     0x00000800	/* Receiver Time Out */
+  #define USART_ISR_EOBF     0x00001000	/* End Of Block Flag */
+  #define USART_ISR_ABRE     0x00004000	/* Auto-Baud Rate Error */
+  #define USART_ISR_ABRF     0x00008000	/* Auto-Baud Rate Flag */
+  #define USART_ISR_BUSY     0x00010000	/* Busy Flag */
+  #define USART_ISR_CMF      0x00020000	/* Character Match Flag */
+  #define USART_ISR_SBKF     0x00040000	/* Send Break Flag */
+  #define USART_ISR_RWU      0x00080000	/* Receive Wake Up from mute mode Flag */
+  #define USART_ISR_WUF      0x00100000	/* Wake Up from stop mode Flag */
+  #define USART_ISR_TEACK    0x00200000	/* Transmit Enable Acknowledge Flag */
+  #define USART_ISR_REACK    0x00400000	/* Receive Enable Acknowledge Flag */
+#define TOFF_USART_ICR      0x0020		/* (RW) USART Interrupt flag Clear register */
+  #define USART_ICR_PECF     0x00000001	/* Parity Error Clear Flag */
+  #define USART_ICR_FECF     0x00000002	/* Framing Error Clear Flag */
+  #define USART_ICR_NCF      0x00000004	/* Noise detected Clear Flag */
+  #define USART_ICR_ORECF    0x00000008	/* OverRun Error Clear Flag */
+  #define USART_ICR_IDLECF   0x00000010	/* IDLE line detected Clear Flag */
+  #define USART_ICR_TCCF     0x00000040	/* Transmission Complete Clear Flag */
+  #define USART_ICR_LBDCF    0x00000100	/* LIN Break Detection Clear Flag */
+  #define USART_ICR_CTSCF    0x00000200	/* CTS Interrupt Clear Flag */
+  #define USART_ICR_RTOCF    0x00000800	/* Receiver Time Out Clear Flag */
+  #define USART_ICR_EOBCF    0x00001000	/* End Of Block Clear Flag */
+  #define USART_ICR_CMCF     0x00020000	/* Character Match Clear Flag */
+  #define USART_ICR_WUCF     0x00100000	/* Wake Up from stop mode Clear Flag */
+#define TOFF_USART_RDR      0x0024		/* (RW) USART Receive Data register */
+#define TOFF_USART_TDR      0x0028		/* (RW) USART Transmit Data register */
+
+/*
+ *  INTER-INTERATED CIRCUIT IINTERFACE(16)
+ */
+#define TADR_I2C1_BASE      (APB1PERIPH_BASE + 0x5400)
+#define TADR_I2C2_BASE      (APB1PERIPH_BASE + 0x5800)
+#define TADR_I2C3_BASE      (APB1PERIPH_BASE + 0x5C00)
+#define TADR_I2C4_BASE      (APB1PERIPH_BASE + 0x6000)
+#define TOFF_I2C_CR1        0x0000		/* (RW) I2C Control register 1 */
+  #define I2C_CR1_PE         0x00000001	/* Peripheral enable */
+  #define I2C_CR1_TXIE       0x00000002	/* TX interrupt enable */
+  #define I2C_CR1_RXIE       0x00000004	/* RX interrupt enable */
+  #define I2C_CR1_ADDRIE     0x00000008	/* Address match interrupt enable */
+  #define I2C_CR1_NACKIE     0x00000010	/* NACK received interrupt enable */
+  #define I2C_CR1_STOPIE     0x00000020	/* STOP detection interrupt enable */
+  #define I2C_CR1_TCIE       0x00000040	/* Transfer complete interrupt enable  */
+  #define I2C_CR1_ERRIE      0x00000080	/* Errors interrupt enable */
+  #define I2C_CR1_DNF        0x00000F00	/* Digital noise filter */
+  #define I2C_CR1_ANFOFF     0x00001000	/* Analog noise filter OFF */
+  #define I2C_CR1_SWRST      0x00002000	/* Software reset */
+  #define I2C_CR1_TXDMAEN    0x00004000	/* DMA transmission requests enable */
+  #define I2C_CR1_RXDMAEN    0x00008000	/* DMA reception requests enable */
+  #define I2C_CR1_SBC        0x00010000	/* Slave byte control */
+  #define I2C_CR1_NOSTRETCH  0x00020000	/* Clock stretching disable */
+  #define I2C_CR1_WUPEN      0x00040000	/* Wakeup from STOP enable */
+  #define I2C_CR1_GCEN       0x00080000	/* General call enable */
+  #define I2C_CR1_SMBHEN     0x00100000	/* SMBus host address enable */
+  #define I2C_CR1_SMBDEN     0x00200000	/* SMBus device default address enable */
+  #define I2C_CR1_ALERTEN    0x00400000	/* SMBus alert enable */
+  #define I2C_CR1_PECEN      0x00800000	/* PEC enable */
+#define TOFF_I2C_CR2        0x0004		/* (RW) I2C Control register 2 */
+  #define I2C_CR2_SADD       0x000003FF	/* Slave address (master mode) */
+  #define I2C_CR2_RD_WRN     0x00000400	/* Transfer direction (master mode) */
+  #define I2C_CR2_ADD10      0x00000800	/* 10-bit addressing mode (master mode) */
+  #define I2C_CR2_HEAD10R    0x00001000	/* 10-bit address header only read direction (master mode) */
+  #define I2C_CR2_START      0x00002000	/* START generation */
+  #define I2C_CR2_STOP       0x00004000	/* STOP generation (master mode) */
+  #define I2C_CR2_NACK       0x00008000	/* NACK generation (slave mode) */
+  #define I2C_CR2_NBYTES     0x00FF0000	/* Number of bytes */
+  #define I2C_CR2_RELOAD     0x01000000	/* NBYTES reload mode */
+  #define I2C_CR2_AUTOEND    0x02000000	/* Automatic end mode (master mode) */
+  #define I2C_CR2_PECBYTE    0x04000000	/* Packet error checking byte */
+#define TOFF_I2C_OAR1       0x0008		/* (RW) I2C Own address register 1 */
+  #define I2C_OAR1_OA1       0x000003FF	/* Interface own address 1 */
+  #define I2C_OAR1_OA1MODE   0x00000400	/* Own address 1 10-bit mode */
+  #define I2C_OAR1_OA1EN     0x00008000	/* Own address 1 enable */
+#define TOFF_I2C_OAR2       0x000C		/* (RW) I2C Own address register 2 */
+  #define I2C_OAR2_OA2       0x000000FE	/* Interface own address 2 */
+  #define I2C_OAR2_OA2MSK    0x00000700	/* Own address 2 masks     */
+  #define I2C_OAR2_OA2NOMASK 0x00000000	/* No mask */
+  #define I2C_OAR2_OA2MASK01 0x00000100	/* OA2[1] is masked, Only OA2[7:2] are compared */
+  #define I2C_OAR2_OA2MASK02 0x00000200	/* OA2[2:1] is masked, Only OA2[7:3] are compared */
+  #define I2C_OAR2_OA2MASK03 0x00000300	/* OA2[3:1] is masked, Only OA2[7:4] are compared */
+  #define I2C_OAR2_OA2MASK04 0x00000400	/* OA2[4:1] is masked, Only OA2[7:5] are compared */
+  #define I2C_OAR2_OA2MASK05 0x00000500	/* OA2[5:1] is masked, Only OA2[7:6] are compared */
+  #define I2C_OAR2_OA2MASK06 0x00000600	/* OA2[6:1] is masked, Only OA2[7] are compared */
+  #define I2C_OAR2_OA2MASK07 0x00000700	/* OA2[7:1] is masked, No comparison is done */
+  #define I2C_OAR2_OA2EN     0x00008000	/* Own address 2 enable    */
+#define TOFF_I2C_TIMINGR    0x0010		/* (RW) I2C Timing register */
+  #define I2C_TIMINGR_SCLL   0x000000FF	/* SCL low period (master mode)  */
+  #define I2C_TIMINGR_SCLH   0x0000FF00	/* SCL high period (master mode) */
+  #define I2C_TIMINGR_SDADEL 0x000F0000	/* Data hold time */
+  #define I2C_TIMINGR_SCLDEL 0x00F00000	/* Data setup time */
+  #define I2C_TIMINGR_PRESC  0xF0000000	/* Timings prescaler */
+#define TOFF_I2C_TIMEOUTR   0x0014		/* (RW) I2C Timeout register */
+  #define I2C_TIMEOUTR_TIMEOUTA 0x00000FFF	/* Bus timeout A */
+  #define I2C_TIMEOUTR_TIDLE    0x00001000	/* Idle clock timeout detection  */
+  #define I2C_TIMEOUTR_TIMOUTEN 0x00008000	/* Clock timeout enable */
+  #define I2C_TIMEOUTR_TIMEOUTB 0x0FFF0000	/* Bus timeout B */
+  #define I2C_TIMEOUTR_TEXTEN   0x80000000	/* Extended clock timeout enable */
+#define TOFF_I2C_ISR        0x0018		/* (RW) I2C Interrupt and status register */
+  #define I2C_ISR_TXE        0x00000001	/* Transmit data register empty */
+  #define I2C_ISR_TXIS       0x00000002	/* Transmit interrupt status */
+  #define I2C_ISR_RXNE       0x00000004	/* Receive data register not empty */
+  #define I2C_ISR_ADDR       0x00000008	/* Address matched (slave mode) */
+  #define I2C_ISR_NACKF      0x00000010	/* NACK received flag */
+  #define I2C_ISR_STOPF      0x00000020	/* STOP detection flag */
+  #define I2C_ISR_TC         0x00000040	/* Transfer complete (master mode) */
+  #define I2C_ISR_TCR        0x00000080	/* Transfer complete reload */
+  #define I2C_ISR_BERR       0x00000100	/* Bus error */
+  #define I2C_ISR_ARLO       0x00000200	/* Arbitration lost */
+  #define I2C_ISR_OVR        0x00000400	/* Overrun/Underrun */
+  #define I2C_ISR_PECERR     0x00000800	/* PEC error in reception */
+  #define I2C_ISR_TIMEOUT    0x00001000	/* Timeout or Tlow detection flag  */
+  #define I2C_ISR_ALERT      0x00002000	/* SMBus alert */
+  #define I2C_ISR_BUSY       0x00008000	/* Bus busy */
+  #define I2C_ISR_DIR        0x00010000	/* Transfer direction (slave mode) */
+  #define I2C_ISR_ADDCODE    0x00FE0000	/* Address match code (slave mode) */
+#define TOFF_I2C_ICR        0x001C		/* (RW) I2C Interrupt clear register */
+  #define I2C_ICR_ADDRCF     0x00000008	/* Address matched clear flag */
+  #define I2C_ICR_NACKCF     0x00000010	/* NACK clear flag */
+  #define I2C_ICR_STOPCF     0x00000020	/* STOP detection clear flag */
+  #define I2C_ICR_BERRCF     0x00000100	/* Bus error clear flag */
+  #define I2C_ICR_ARLOCF     0x00000200	/* Arbitration lost clear flag */
+  #define I2C_ICR_OVRCF      0x00000400	/* Overrun/Underrun clear flag */
+  #define I2C_ICR_PECCF      0x00000800	/* PAC error clear flag */
+  #define I2C_ICR_TIMOUTCF   0x00001000	/* Timeout clear flag */
+  #define I2C_ICR_ALERTCF    0x00002000	/* Alert clear flag */
+#define TOFF_I2C_PECR       0x0020		/* (RW) I2C PEC register */
+#define TOFF_I2C_RXDR       0x0024		/* (RW) I2C Receive data register */
+#define TOFF_I2C_TXDR       0x0028		/* (RW) I2C Transmit data register */  
+
+/*
+ *  CONTROLLER AREA NETWORK
+ */
+#define TADR_CAN1_BASE      (APB1PERIPH_BASE + 0x6400)
+#define TADR_CAN2_BASE      (APB1PERIPH_BASE + 0x6800)
+#define TOFF_CAN_MCR        0x0000		/* (RW) CAN master control register */
+#define TOFF_CAN_MSR        0x0004		/* (R)  CAN master status register */
+#define TOFF_CAN_TSR        0x0008		/* (R)  CAN transmit status register */
+#define TOFF_CAN_RF0R       0x000C		/* (RW) CAN receive FIFO 0 register */
+#define TOFF_CAN_RF1R       0x0010		/* (RW) CAN receive FIFO 1 register */
+#define TOFF_CAN_IER        0x0014		/* (RW) CAN interrupt enable register */
+#define TOFF_CAN_ESR        0x0018		/* (RW) CAN error status register */
+#define TOFF_CAN_BTR        0x001C		/* (RW) CAN bit timing register */
+										/* CAN TX MailBox */
+#define TOFF_CAN_TIR1       0x0180		/* (RW) CAN(1) TX mailbox identifier register */
+#define TOFF_CAN_TDTR1      0x0184		/* (RW) CAN(1) mailbox data length control and time stamp register */
+#define TOFF_CAN_TDLR1      0x0188		/* (RW) CAN(1) mailbox data low register */
+#define TOFF_CAN_TDHR1      0x018C		/* (RW) CAN(1) mailbox data high register */
+#define TOFF_CAN_TIR2       0x0190		/* (RW) CAN(2) TX mailbox identifier register */
+#define TOFF_CAN_TDTR2      0x0194		/* (RW) CAN(2) mailbox data length control and time stamp register */
+#define TOFF_CAN_TDLR2      0x0198		/* (RW) CAN(2) mailbox data low register */
+#define TOFF_CAN_TDHR2      0x019C		/* (RW) CAN(2) mailbox data high register */
+#define TOFF_CAN_TIR3       0x01A0		/* (RW) CAN(3) TX mailbox identifier register */
+#define TOFF_CAN_TDTR3      0x01A4		/* (RW) CAN(3) mailbox data length control and time stamp register */
+#define TOFF_CAN_TDLR3      0x01A8		/* (RW) CAN(3) mailbox data low register */
+#define TOFF_CAN_TDHR3      0x01AC		/* (RW) CAN(3) mailbox data high register */
+										/* CAN FIFO MailBox */
+#define TOFF_CAN_RIR1       0x01B0		/* (RW) CAN(1) receive FIFO mailbox identifier register */
+#define TOFF_CAN_RDTR1      0x01B4		/* (RW) CAN(1) receive FIFO mailbox data length control and time stamp register */
+#define TOFF_CAN_RDLR1      0x01B8		/* (RW) CAN(1) receive FIFO mailbox data low register */
+#define TOFF_CAN_RDHR1      0x01BC		/* (RW) CAN(1) receive FIFO mailbox data high register */
+#define TOFF_CAN_RIR2       0x01C0		/* (RW) CAN(2) receive FIFO mailbox identifier register */
+#define TOFF_CAN_RDTR2      0x01C4		/* (RW) CAN(2) receive FIFO mailbox data length control and time stamp register */
+#define TOFF_CAN_RDLR2      0x01C8		/* (RW) CAN(2) receive FIFO mailbox data low register */
+#define TOFF_CAN_RDHR2      0x01CC		/* (RW) CAN(2) receive FIFO mailbox data high register */
+#define TOFF_CAN_FMR        0x0200		/* (RW) CAN filter master register */
+#define TOFF_CAN_FM1R       0x0204		/* (RW) CAN filter mode register */
+#define TOFF_CAN_FS1R       0x020C		/* (RW) CAN filter scale register */
+#define TOFF_CAN_FFA1R      0x0214		/* (RW) CAN filter FIFO assignment register */
+#define TOFF_CAN_FA1R       0x0218		/* (RW) CAN filter activation register */
+#define TOFF_CAN_FR_BASE    0x0240		/*      0x240-0x31C */
+#define TOFF_CAN_FR1        0x0240		/* (RW) CAN Filter bank register 1 */
+#define TOFF_CAN_FR2        0x0244		/* (RW) CAN Filter bank register 2 */
+
+/* 
+ * HDMI-CEC 
+ */
+#define TADR_CEC_BASE      (APB1PERIPH_BASE + 0x6C00)
+#define TOFF_CEC_CR        0x0000		/* (RW) CEC control register */
+#define TOFF_CEC_CFGR      0x0004		/* (RW) CEC configuration register */
+#define TOFF_CEC_TXDR      0x0008		/* (RW) CEC Tx data register  */
+#define TOFF_CEC_RXDR      0x000C		/* (RW) CEC Rx Data Register */
+#define TOFF_CEC_ISR       0x0010		/* (RW) CEC Interrupt and Status Register */
+#define TOFF_CEC_IER       0x0014		/* (RW) CEC interrupt enable register */
+
+/*
+ *  POWER CONTROL
+ */
+#define TADR_PWR_BASE       (APB1PERIPH_BASE + 0x7000)
+#define TOFF_PWR_CR1        0x0000		/* (RW) PWR power control register */
+  #define PWR_CR1_LPDS       0x00000001	/* Low-Power Deepsleep                 */
+  #define PWR_CR1_PDDS       0x00000002	/* Power Down Deepsleep                */
+  #define PWR_CR1_CSBF       0x00000008	/* Clear Standby Flag                  */
+  #define PWR_CR1_PVDE       0x00000010	/* Power Voltage Detector Enable       */
+  #define PWR_CR1_PLS        0x000000E0	/* PLS[2:0] bits (PVD Level Selection) */
+  #define PWR_CR1_PLS_0      0x00000020	/* Bit 0 */
+  #define PWR_CR1_PLS_1      0x00000040	/* Bit 1 */
+  #define PWR_CR1_PLS_2      0x00000080	/* Bit 2 */
+  #define PWR_CR1_PLS_LEV0   0x00000000	/* PVD level 0 */
+  #define PWR_CR1_PLS_LEV1   0x00000020	/* PVD level 1 */
+  #define PWR_CR1_PLS_LEV2   0x00000040	/* PVD level 2 */
+  #define PWR_CR1_PLS_LEV3   0x00000060	/* PVD level 3 */
+  #define PWR_CR1_PLS_LEV4   0x00000080	/* PVD level 4 */
+  #define PWR_CR1_PLS_LEV5   0x000000A0	/* PVD level 5 */
+  #define PWR_CR1_PLS_LEV6   0x000000C0	/* PVD level 6 */
+  #define PWR_CR1_PLS_LEV7   0x000000E0	/* PVD level 7 */
+  #define PWR_CR1_DBP        0x00000100	/* Disable Backup Domain write protection                     */
+  #define PWR_CR1_FPDS       0x00000200	/* Flash power down in Stop mode                              */
+  #define PWR_CR1_LPUDS      0x00000400	/* Low-power regulator in deepsleep under-drive mode          */
+  #define PWR_CR1_MRUDS      0x00000800	/* Main regulator in deepsleep under-drive mode               */
+  #define PWR_CR1_ADCDC1     0x00002000	/* Refer to AN4073 on how to use this bit */ 
+  #define PWR_CR1_VOS        0x0000C000	/* VOS[1:0] bits (Regulator voltage scaling output selection) */
+  #define PWR_CR1_VOS_0      0x00004000	/* Bit 0 */
+  #define PWR_CR1_VOS_1      0x00008000	/* Bit 1 */
+  #define PWR_CR1_ODEN       0x00010000	/* Over Drive enable                   */
+  #define PWR_CR1_ODSWEN     0x00020000	/* Over Drive switch enabled           */
+  #define PWR_CR1_UDEN       0x000C0000	/* Under Drive enable in stop mode     */
+  #define PWR_CR1_UDEN_0     0x00040000	/* Bit 0                               */
+  #define PWR_CR1_UDEN_1     0x00080000	/* Bit 1                               */
+#define TOFF_PWR_CSR1       0x0004		/* (RW) PWR power control/status register */
+  #define PWR_CSR1_WUIF      0x00000001	/* Wake up internal Flag                            */
+  #define PWR_CSR1_SBF       0x00000002	/* Standby Flag                                     */
+  #define PWR_CSR1_PVDO      0x00000004	/* PVD Output                                       */
+  #define PWR_CSR1_BRR       0x00000008	/* Backup regulator ready                           */
+#ifdef TOPPERS_STM32F723_DISCOVERY
+  #define PWR_CSR1_EIWUP     0x00000100	/* Enable internal wakeup                           */
+#endif
+  #define PWR_CSR1_BRE       0x00000200	/* Backup regulator enable                          */
+  #define PWR_CSR1_VOSRDY    0x00004000	/* Regulator voltage scaling output selection ready */
+  #define PWR_CSR1_ODRDY     0x00010000	/* Over Drive generator ready                       */
+  #define PWR_CSR1_ODSWRDY   0x00020000	/* Over Drive Switch ready                          */
+  #define PWR_CSR1_UDSWRDY   0x000C0000	/* Under Drive ready                                */
+  #define PWR_CSR1_UDRDY     PWR_CSR1_UDSWRDY
+#define TOFF_PWR_CR2        0x0008		/* (RW) PWR power control register 2 */
+  #define PWR_CR2_CWUPF1     0x00000001	/* Clear Wakeup Pin Flag for PA0      */
+  #define PWR_CR2_CWUPF2     0x00000002	/* Clear Wakeup Pin Flag for PA2      */
+  #define PWR_CR2_CWUPF3     0x00000004	/* Clear Wakeup Pin Flag for PC1      */
+  #define PWR_CR2_CWUPF4     0x00000008	/* Clear Wakeup Pin Flag for PC13     */
+  #define PWR_CR2_CWUPF5     0x00000010	/* Clear Wakeup Pin Flag for PI8      */
+  #define PWR_CR2_CWUPF6     0x00000020	/* Clear Wakeup Pin Flag for PI11     */
+  #define PWR_CR2_WUPP1      0x00000100	/* Wakeup Pin Polarity bit for PA0    */
+  #define PWR_CR2_WUPP2      0x00000200	/* Wakeup Pin Polarity bit for PA2    */
+  #define PWR_CR2_WUPP3      0x00000400	/* Wakeup Pin Polarity bit for PC1    */
+  #define PWR_CR2_WUPP4      0x00000800	/* Wakeup Pin Polarity bit for PC13   */
+  #define PWR_CR2_WUPP5      0x00001000	/* Wakeup Pin Polarity bit for PI8    */
+  #define PWR_CR2_WUPP6      0x00002000	/* Wakeup Pin Polarity bit for PI11   */
+#define TOFF_PWR_CSR2       0x000C		/* (RW) PWR power control/status register 2, Address offset: 0x0C */
+  #define PWR_CSR2_WUPF1     0x00000001	/* Wakeup Pin Flag for PA0            */
+  #define PWR_CSR2_WUPF2     0x00000002	/* Wakeup Pin Flag for PA2            */
+  #define PWR_CSR2_WUPF3     0x00000004	/* Wakeup Pin Flag for PC1            */
+  #define PWR_CSR2_WUPF4     0x00000008	/* Wakeup Pin Flag for PC13           */
+  #define PWR_CSR2_WUPF5     0x00000010	/* Wakeup Pin Flag for PI8            */
+  #define PWR_CSR2_WUPF6     0x00000020	/* Wakeup Pin Flag for PI11           */
+  #define PWR_CSR2_EWUP1     0x00000100	/* Enable Wakeup Pin PA0              */
+  #define PWR_CSR2_EWUP2     0x00000200	/* Enable Wakeup Pin PA2              */
+  #define PWR_CSR2_EWUP3     0x00000400	/* Enable Wakeup Pin PC1              */
+  #define PWR_CSR2_EWUP4     0x00000800	/* Enable Wakeup Pin PC13             */
+  #define PWR_CSR2_EWUP5     0x00001000	/* Enable Wakeup Pin PI8              */
+  #define PWR_CSR2_EWUP6     0x00002000	/* Enable Wakeup Pin PI11             */
+
+/*
+ *  DIGITAL TO ANALOG CONVTER
+ */
+#define TADR_DAC_BASE       (APB1PERIPH_BASE + 0x7400)
+#define TOFF_DAC_CR         0x0000		/* (RW) DAC control register */
+#define TOFF_DAC_SWTRIGR	0x0004		/* (RW) DAC software trigger register */
+#define TOFF_DAC_DHR12R1    0x0008		/* (RW) DAC channel1 12-bit right-aligned data holding register */
+#define TOFF_DAC_DHR12L1    0x000C		/* (RW) DAC channel1 12-bit left aligned data holding register */
+#define TOFF_DAC_DHR8R1     0x0010		/* (RW) DAC channel1 8-bit right aligned data holding register */
+#define TOFF_DAC_DHR12R2    0x0014		/* (RW) DAC channel2 12-bit right aligned data holding register */
+#define TOFF_DAC_DHR12L2    0x0018		/* (RW) DAC channel2 12-bit left aligned data holding register */
+#define TOFF_DAC_DHR8R2     0x001C		/* (RW) DAC channel2 8-bit right-aligned data holding register */
+#define TOFF_DAC_DHR12RD    0x0020		/* (RW) Dual DAC 12-bit right-aligned data holding register */
+#define TOFF_DAC_DHR12LD    0x0024		/* (RW) DUAL DAC 12-bit left aligned data holding register */
+#define TOFF_DAC_DHR8RD     0x0028		/* (RW) DUAL DAC 8-bit right aligned data holding register */
+#define TOFF_DAC_DOR1       0x002C		/* (RW) DAC channel1 data output register */
+#define TOFF_DAC_DOR2       0x0030		/* (RW) DAC channel2 data output register */
+#define TOFF_DAC_SR         0x0034		/* (RW) DAC status register */
+
+
+/*
+ *  ANALOG TO DIGITAL CONVERTER
+ */
+#define TADR_ADC1_BASE      (APB2PERIPH_BASE + 0x2000)
+#define TADR_ADC2_BASE      (APB2PERIPH_BASE + 0x2100)
+#define TADR_ADC3_BASE      (APB2PERIPH_BASE + 0x2200)
+#define TOFF_ADC_SR         0x0000		/* (RW) ADC status register */
+  #define ADC_SR_AWD                0x00000001	/* Analog watchdog flag */
+  #define ADC_SR_EOC                0x00000002	/* End of conversion */
+  #define ADC_SR_JEOC               0x00000004	/* Injected channel end of conversion */
+  #define ADC_SR_JSTRT              0x00000008	/* Injected channel Start flag */
+  #define ADC_SR_STRT               0x00000010	/* Regular channel Start flag */
+  #define ADC_SR_OVR                0x00000020	/* Overrun flag */
+#define TOFF_ADC_CR1        0x0004		/* (RW) ADC control register 1 */
+  #define ADC_CR1_AWDCH             0x0000001F	/* AWDCH bits (Analog watchdog channel select bits) */
+  #define ADC_CR1_AWDCH_0           0x00000001	/* Bit 0 */
+  #define ADC_CR1_AWDCH_1           0x00000002	/* Bit 1 */
+  #define ADC_CR1_AWDCH_2           0x00000004	/* Bit 2 */
+  #define ADC_CR1_AWDCH_3           0x00000008	/* Bit 3 */
+  #define ADC_CR1_AWDCH_4           0x00000010	/* Bit 4 */
+  #define ADC_CR1_EOCIE             0x00000020	/* Interrupt enable for EOC */
+  #define ADC_CR1_AWDIE             0x00000040	/* Analog Watchdog interrupt enable */
+  #define ADC_CR1_JEOCIE            0x00000080	/* Interrupt enable for injected channels */
+  #define ADC_CR1_SCAN              0x00000100	/* Scan mode */
+  #define ADC_CR1_AWDSGL            0x00000200	/* Enable the watchdog on a single channel in scan mode */
+  #define ADC_CR1_JAUTO             0x00000400	/* Automatic injected group conversion */
+  #define ADC_CR1_DISCEN            0x00000800	/* Discontinuous mode on regular channels */
+  #define ADC_CR1_JDISCEN           0x00001000	/* Discontinuous mode on injected channels */
+  #define ADC_CR1_DISCNUM           0x0000E000	/* DISCNUM bits (Discontinuous mode channel count) */
+  #define ADC_CR1_DISCNUM_0         0x00002000	/* Bit 0 */
+  #define ADC_CR1_DISCNUM_1         0x00004000	/* Bit 1 */
+  #define ADC_CR1_DISCNUM_2         0x00008000	/* Bit 2 */
+  #define ADC_CR1_JAWDEN            0x00400000	/* Analog watchdog enable on injected channels */
+  #define ADC_CR1_AWDEN             0x00800000	/* Analog watchdog enable on regular channels */
+  #define ADC_CR1_RES               0x03000000	/* RES bits (Resolution) */
+  #define ADC_CR1_RES_0             0x01000000	/* Bit 0 */
+  #define ADC_CR1_RES_1             0x02000000	/* Bit 1 */
+  #define ADC_CR1_OVRIE             0x04000000	/* Overrun interrupt enable */
+#define TOFF_ADC_CR2        0x0008		/* (RW) ADC control register 2 */
+  #define ADC_CR2_ADON              0x00000001	/* A/D Converter ON / OFF */
+  #define ADC_CR2_CONT              0x00000002	/* Continuous Conversion */
+  #define ADC_CR2_DMA               0x00000100	/* Direct Memory access mode */
+  #define ADC_CR2_DDS               0x00000200	/* DMA disable selection (Single ADC) */
+  #define ADC_CR2_EOCS              0x00000400	/* End of conversion selection */
+  #define ADC_CR2_ALIGN             0x00000800	/* Data Alignment */
+  #define ADC_CR2_JEXTSEL           0x000F0000	/* JEXTSEL bits (External event select for injected group) */
+  #define ADC_CR2_JEXTSEL_0         0x00010000	/* Bit 0 */
+  #define ADC_CR2_JEXTSEL_1         0x00020000	/* Bit 1 */
+  #define ADC_CR2_JEXTSEL_2         0x00040000	/* Bit 2 */
+  #define ADC_CR2_JEXTSEL_3         0x00080000	/* Bit 3 */
+  #define ADC_CR2_JEXTEN            0x00300000	/* JEXTEN bits (External Trigger Conversion mode for injected channelsp) */
+  #define ADC_CR2_JEXTEN_0          0x00100000	/* Bit 0 */
+  #define ADC_CR2_JEXTEN_1          0x00200000	/* Bit 1 */
+  #define ADC_CR2_JSWSTART          0x00400000	/* Start Conversion of injected channels */
+  #define ADC_CR2_EXTSEL            0x0F000000	/* EXTSEL bits (External Event Select for regular group) */
+  #define ADC_CR2_EXTSEL_0          0x01000000	/* Bit 0 */
+  #define ADC_CR2_EXTSEL_1          0x02000000	/* Bit 1 */
+  #define ADC_CR2_EXTSEL_2          0x04000000	/* Bit 2 */
+  #define ADC_CR2_EXTSEL_3          0x08000000	/* Bit 3 */
+  #define ADC_CR2_EXTEN             0x30000000	/* EXTEN bits (External Trigger Conversion mode for regular channelsp) */
+  #define ADC_CR2_EXTEN_0           0x10000000	/* Bit 0 */
+  #define ADC_CR2_EXTEN_1           0x20000000	/* Bit 1 */
+  #define ADC_CR2_SWSTART           0x40000000	/* Start Conversion of regular channels */
+#define TOFF_ADC_SMPR1      0x000C		/* (RW) ADC sample time register 1 */
+  #define ADC_SMPR1_SMP10           0x00000007	/* SMP10 bits (Channel 10 Sample time selection) */
+  #define ADC_SMPR1_SMP11           0x00000038	/* SMP11 bits (Channel 11 Sample time selection) */
+  #define ADC_SMPR1_SMP12           0x000001C0	/* SMP12 bits (Channel 12 Sample time selection) */
+  #define ADC_SMPR1_SMP13           0x00000E00	/* SMP13 bits (Channel 13 Sample time selection) */
+  #define ADC_SMPR1_SMP14           0x00007000	/* SMP14 bits (Channel 14 Sample time selection) */
+  #define ADC_SMPR1_SMP15           0x00038000	/* SMP15 bits (Channel 15 Sample time selection) */
+  #define ADC_SMPR1_SMP16           0x001C0000	/* SMP16 bits (Channel 16 Sample time selection) */
+  #define ADC_SMPR1_SMP17           0x00E00000	/* SMP17 bits (Channel 17 Sample time selection) */
+  #define ADC_SMPR1_SMP18           0x07000000	/* SMP18 bits (Channel 18 Sample time selection) */
+#define TOFF_ADC_SMPR2      0x0010		/* (RW) ADC sample time register 2 */
+  #define ADC_SMPR2_SMP0            0x00000007	/* SMP0 bits (Channel 0 Sample time selection) */
+  #define ADC_SMPR2_SMP1            0x00000038	/* SMP1 bits (Channel 1 Sample time selection) */
+  #define ADC_SMPR2_SMP2            0x000001C0	/* SMP2 bits (Channel 2 Sample time selection) */
+  #define ADC_SMPR2_SMP3            0x00000E00	/* SMP3 bits (Channel 3 Sample time selection) */
+  #define ADC_SMPR2_SMP4            0x00007000	/* SMP4 bits (Channel 4 Sample time selection) */
+  #define ADC_SMPR2_SMP5            0x00038000	/* SMP5 bits (Channel 5 Sample time selection) */
+  #define ADC_SMPR2_SMP6            0x001C0000	/* SMP6 bits (Channel 6 Sample time selection) */
+  #define ADC_SMPR2_SMP7            0x00E00000	/* SMP7 bits (Channel 7 Sample time selection) */
+  #define ADC_SMPR2_SMP8            0x07000000	/* SMP8 bits (Channel 8 Sample time selection) */
+  #define ADC_SMPR2_SMP9            0x38000000	/* SMP9 bits (Channel 9 Sample time selection) */
+#define TOFF_ADC_JOFR1      0x0014		/* (RW) ADC injected channel data offset register 1 */
+#define TOFF_ADC_JOFR2      0x0018		/* (RW) ADC injected channel data offset register 2 */
+#define TOFF_ADC_JOFR3      0x001C		/* (RW) ADC injected channel data offset register 3 */
+#define TOFF_ADC_JOFR4      0x0020		/* (RW) ADC injected channel data offset register 4 */
+#define TOFF_ADC_HTR        0x0024		/* (RW) ADC watchdog higher threshold register */
+#define TOFF_ADC_LTR        0x0028		/* (RW) ADC watchdog lower threshold register */
+#define TOFF_ADC_SQR1       0x002C		/* (RW) ADC regular sequence register 1 */
+  #define ADC_SQR1_SQ13             0x0000001F	/* SQ13 bits (13th conversion in regular sequence) */
+  #define ADC_SQR1_SQ14             0x000003E0	/* SQ14 bits (14th conversion in regular sequence) */
+  #define ADC_SQR1_SQ15             0x00007C00	/* SQ15 bits (15th conversion in regular sequence) */
+  #define ADC_SQR1_SQ16             0x000F8000	/* SQ16 bits (16th conversion in regular sequence) */
+  #define ADC_SQR1_L                0x00F00000	/* L[3:0] bits (Regular channel sequence length) */
+#define TOFF_ADC_SQR2       0x0030		/* (RW) ADC regular sequence register 2 */
+  #define ADC_SQR2_SQ7              0x0000001F	/* SQ7 bits (7th conversion in regular sequence) */
+  #define ADC_SQR2_SQ8              0x000003E0	/* SQ8 bits (8th conversion in regular sequence) */
+  #define ADC_SQR2_SQ9              0x00007C00	/* SQ9 bits (9th conversion in regular sequence) */
+  #define ADC_SQR2_SQ10             0x000F8000	/* SQ10 bits (10th conversion in regular sequence) */
+  #define ADC_SQR2_SQ11             0x01F00000	/* SQ11 bits (11th conversion in regular sequence) */
+  #define ADC_SQR2_SQ12             0x3E000000	/* SQ12 bits (12th conversion in regular sequence) */
+#define TOFF_ADC_SQR3       0x0034		/* (RW) ADC regular sequence register 3 */
+  #define ADC_SQR3_SQ1              0x0000001F	/* SQ1 bits (1st conversion in regular sequence) */
+  #define ADC_SQR3_SQ2              0x000003E0	/* SQ2 bits (2nd conversion in regular sequence) */
+  #define ADC_SQR3_SQ3              0x00007C00	/* SQ3 bits (3rd conversion in regular sequence) */
+  #define ADC_SQR3_SQ4              0x000F8000	/* SQ4 bits (4th conversion in regular sequence) */
+  #define ADC_SQR3_SQ5              0x01F00000	/* SQ5 bits (5th conversion in regular sequence) */
+  #define ADC_SQR3_SQ6              0x3E000000	/* SQ6 bits (6th conversion in regular sequence) */
+#define TOFF_ADC_JSQR       0x0038		/* (RW) ADC injected sequence register */
+#define TOFF_ADC_JDR1       0x003C		/* (RW) ADC injected data register 1 */
+#define TOFF_ADC_JDR2       0x0040		/* (RW) ADC injected data register 2 */
+#define TOFF_ADC_JDR3       0x0044		/* (RW) ADC injected data register 3 */
+#define TOFF_ADC_JDR4       0x0048		/* (RW) ADC injected data register 4 */
+#define TOFF_ADC_DR         0x004C		/* (RW) ADC regular data register */
+
+#define TADR_ADC_BASE       (APB2PERIPH_BASE + 0x2300)
+#define TOFF_ADC_CSR        0x0000		/* (RW) ADC Common status register */
+#define TOFF_ADC_CCR        0x0004		/* (RW) ADC common control register */
+  #define ADC_CCR_MULTI             0x0000001F	/* MULTI[4:0] bits (Multi-ADC mode selection) */  
+  #define ADC_CCR_MULTI_0           0x00000001	/* Bit 0 */
+  #define ADC_CCR_MULTI_1           0x00000002	/* Bit 1 */
+  #define ADC_CCR_MULTI_2           0x00000004	/* Bit 2 */
+  #define ADC_CCR_MULTI_3           0x00000008	/* Bit 3 */
+  #define ADC_CCR_MULTI_4           0x00000010	/* Bit 4 */
+  #define ADC_CCR_DELAY             0x00000F00	/* DELAY[3:0] bits (Delay between 2 sampling phases) */  
+  #define ADC_CCR_DELAY_0           0x00000100	/* Bit 0 */
+  #define ADC_CCR_DELAY_1           0x00000200	/* Bit 1 */
+  #define ADC_CCR_DELAY_2           0x00000400	/* Bit 2 */
+  #define ADC_CCR_DELAY_3           0x00000800	/* Bit 3 */
+  #define ADC_CCR_DDS               0x00002000	/* DMA disable selection (Multi-ADC mode) */
+  #define ADC_CCR_DMA               0x0000C000	/* DMA[1:0] bits (Direct Memory Access mode for multimode) */  
+  #define ADC_CCR_DMA_0             0x00004000	/* Bit 0 */
+  #define ADC_CCR_DMA_1             0x00008000	/* Bit 1 */
+  #define ADC_CCR_ADCPRE            0x00030000	/* ADCPRE[1:0] bits (ADC prescaler) */  
+  #define ADC_CCR_ADCPRE_0          0x00010000	/* Bit 0 */
+  #define ADC_CCR_ADCPRE_1          0x00020000	/* Bit 1 */
+  #define ADC_CCR_VBATE             0x00400000	/* VBAT Enable */
+  #define ADC_CCR_TSVREFE           0x00800000	/* Temperature Sensor and VREFINT Enable */
+#define TOFF_ADC_CDR        0x0008		/* (RW) ADC common regular data register for dual AND triple modes */
+
+/*
+ *  SD HOST INTERFACE
+ */
+#define TADR_SDMMC1_BASE    (APB2PERIPH_BASE + 0x2C00)
+#if defined(TOPPERS_STM32F769_DISCOVERY) || defined(TOPPERS_STM32F767_NUCLEO144)
+#define TADR_SDMMC2_BASE    (APB2PERIPH_BASE + 0x1C00)
+#endif
+#define TOFF_SDIO_POWER     0x0000		/* (RW) SDIO power control register */
+  #define SDMMC_POWER_PWRCTRL   0x00000003	/* PWRCTRL[1:0] bits (Power supply control bits) */
+  #define SDMMC_POWER_PWRCTRL_0 0x00000001	/* Bit 0 */
+  #define SDMMC_POWER_PWRCTRL_1 0x00000002	/* Bit 1 */
+#define TOFF_SDIO_CLKCR     0x0004		/* (RW) SDI clock control register */
+  #define SDMMC_CLKCR_CLKDIV    0x000000FF	/* Clock divide factor             */
+  #define SDMMC_CLKCR_CLKEN     0x00000100	/* Clock enable bit                */
+  #define SDMMC_CLKCR_PWRSAV    0x00000200	/* Power saving configuration bit  */
+  #define SDMMC_CLKCR_BYPASS    0x00000400	/* Clock divider bypass enable bit */
+  #define SDMMC_CLKCR_WIDBUS    0x00001800	/* WIDBUS[1:0] bits (Wide bus mode enable bit) */
+  #define SDMMC_CLKCR_WIDBUS_0  0x00000800	/* Bit 0 */
+  #define SDMMC_CLKCR_WIDBUS_1  0x00001000	/* Bit 1 */
+  #define SDMMC_CLKCR_NEGEDGE   0x00002000	/* SDMMC_CK dephasing selection bit */
+  #define SDMMC_CLKCR_HWFC_EN   0x00004000	/* HW Flow Control enable          */
+#define TOFF_SDIO_ARG       0x0008		/* (RW) SDIO argument register */
+#define TOFF_SDIO_CMD       0x000C		/* (RW) SDIO command register */
+  #define SDMMC_CMD_CMDINDEX    0x0000003F	/* Command Index                               */
+  #define SDMMC_CMD_WAITRESP    0x000000C0	/* WAITRESP[1:0] bits (Wait for response bits) */
+  #define SDMMC_CMD_WAITRESP_0  0x00000040	/* Bit 0 */
+  #define SDMMC_CMD_WAITRESP_1  0x00000080	/* Bit 1 */
+  #define SDMMC_CMD_WAITINT     0x00000100	/* CPSM Waits for Interrupt Request */
+  #define SDMMC_CMD_WAITPEND    0x00000200	/* CPSM Waits for ends of data transfer (CmdPend internal signal) */
+  #define SDMMC_CMD_CPSMEN      0x00000400	/* Command path state machine (CPSM) Enable bit */
+  #define SDMMC_CMD_SDIOSUSPEND 0x00000800	/* SD I/O suspend command */
+#define TOFF_SDIO_RESPCMD   0x0010		/* (R)  SDIO command response register */
+#define TOFF_SDIO_RESP      0x0014		/* (R)  SDIO response 1 register */
+#define TOFF_SDIO_RESP2     0x0018		/* (R)  SDIO response 2 register */
+#define TOFF_SDIO_RESP3     0x001C		/* (R)  SDIO response 3 register */
+#define TOFF_SDIO_RESP4     0x0020		/* (R)  SDIO response 4 register */
+#define TOFF_SDIO_DTIMER    0x0024		/* (RW) SDIO data timer register */
+#define TOFF_SDIO_DLEN      0x0028		/* (RW) SDIO data length register */
+#define TOFF_SDIO_DCTRL     0x002C		/* (RW) SDIO data control register */
+  #define SDMMC_DCTRL_DTEN      0x00000001	/* Data transfer enabled bit */
+  #define SDMMC_DCTRL_DTDIR     0x00000002	/* Data transfer direction selection */
+  #define SDMMC_DCTRL_DTMODE    0x00000004	/* Data transfer mode selection      */
+  #define SDMMC_DCTRL_DMAEN     0x00000008	/* DMA enabled bit                   */
+  #define SDMMC_DCTRL_DBLOCKSIZE    0x00F0	/* DBLOCKSIZE[3:0] bits (Data block size) */
+  #define SDMMC_DCTRL_DBLOCKSIZE_0  0x0010	/* Bit 0 */
+  #define SDMMC_DCTRL_DBLOCKSIZE_1  0x0020	/* Bit 1 */
+  #define SDMMC_DCTRL_DBLOCKSIZE_2  0x0040	/* Bit 2 */
+  #define SDMMC_DCTRL_DBLOCKSIZE_3  0x0080	/* Bit 3 */
+  #define SDMMC_DCTRL_RWSTART   0x00000100	/* Read wait start */
+  #define SDMMC_DCTRL_RWSTOP    0x00000200	/* Read wait stop */
+  #define SDMMC_DCTRL_RWMOD     0x00000400	/* Read wait mode */
+  #define SDMMC_DCTRL_SDIOEN    0x00000800	/* SD I/O enable functions */
+#define TOFF_SDIO_DCOUNT    0x0030		/* (R)  SDIO data counter register */
+#define TOFF_SDIO_STA       0x0034		/* (R)  SDIO status register */
+  #define SDMMC_STA_CCRCFAIL    0x00000001	/* Command response received (CRC check failed)  */
+  #define SDMMC_STA_DCRCFAIL    0x00000002	/* Data block sent/received (CRC check failed)   */
+  #define SDMMC_STA_CTIMEOUT    0x00000004	/* Command response timeout                      */
+  #define SDMMC_STA_DTIMEOUT    0x00000008	/* Data timeout                                  */
+  #define SDMMC_STA_TXUNDERR    0x00000010	/* Transmit FIFO underrun error                  */
+  #define SDMMC_STA_RXOVERR     0x00000020	/* Received FIFO overrun error                   */
+  #define SDMMC_STA_CMDREND     0x00000040	/* Command response received (CRC check passed)  */
+  #define SDMMC_STA_CMDSENT     0x00000080	/* Command sent (no response required)           */
+  #define SDMMC_STA_DATAEND     0x00000100	/* Data end (data counter, SDIDCOUNT, is zero)   */
+  #define SDMMC_STA_DBCKEND     0x00000400	/* Data block sent/received (CRC check passed)   */
+  #define SDMMC_STA_CMDACT      0x00000800	/* Command transfer in progress                  */
+  #define SDMMC_STA_TXACT       0x00001000	/* Data transmit in progress                     */
+  #define SDMMC_STA_RXACT       0x00002000	/* Data receive in progress                      */
+  #define SDMMC_STA_TXFIFOHE    0x00004000	/* Transmit FIFO Half Empty: at least 8 words can be written into the FIFO */
+  #define SDMMC_STA_RXFIFOHF    0x00008000	/* Receive FIFO Half Full: there are at least 8 words in the FIFO */
+  #define SDMMC_STA_TXFIFOF     0x00010000	/* Transmit FIFO full */
+  #define SDMMC_STA_RXFIFOF     0x00020000	/* Receive FIFO full */
+  #define SDMMC_STA_TXFIFOE     0x00040000	/* Transmit FIFO empty */
+  #define SDMMC_STA_RXFIFOE     0x00080000	/* Receive FIFO empty */
+  #define SDMMC_STA_TXDAVL      0x00100000	/* Data available in transmit FIFO */
+  #define SDMMC_STA_RXDAVL      0x00200000	/* Data available in receive FIFO */
+  #define SDMMC_STA_SDIOIT      0x00400000	/* SDMMC interrupt received */
+#define TOFF_SDIO_ICR       0x0038		/* (RW) SDIO interrupt clear register */
+  #define SDMMC_ICR_CCRCFAILC   0x00000001	/* CCRCFAIL flag clear bit */
+  #define SDMMC_ICR_DCRCFAILC   0x00000002	/* DCRCFAIL flag clear bit */
+  #define SDMMC_ICR_CTIMEOUTC   0x00000004	/* CTIMEOUT flag clear bit */
+  #define SDMMC_ICR_DTIMEOUTC   0x00000008	/* DTIMEOUT flag clear bit */
+  #define SDMMC_ICR_TXUNDERRC   0x00000010	/* TXUNDERR flag clear bit */
+  #define SDMMC_ICR_RXOVERRC    0x00000020	/* RXOVERR flag clear bit  */
+  #define SDMMC_ICR_CMDRENDC    0x00000040	/* CMDREND flag clear bit  */
+  #define SDMMC_ICR_CMDSENTC    0x00000080	/* CMDSENT flag clear bit  */
+  #define SDMMC_ICR_DATAENDC    0x00000100	/* DATAEND flag clear bit  */
+  #define SDMMC_ICR_DBCKENDC    0x00000400	/* DBCKEND flag clear bit  */
+  #define SDMMC_ICR_SDIOITC     0x00400000	/* SDMMCIT flag clear bit   */
+#define TOFF_SDIO_MASK      0x003C		/* (RW) SDIO mask register */
+  #define SDMMC_MASK_CCRCFAILIE 0x00000001	/* Command CRC Fail Interrupt Enable */
+  #define SDMMC_MASK_DCRCFAILIE 0x00000002	/* Data CRC Fail Interrupt Enable */
+  #define SDMMC_MASK_CTIMEOUTIE 0x00000004	/* Command TimeOut Interrupt Enable */
+  #define SDMMC_MASK_DTIMEOUTIE 0x00000008	/* Data TimeOut Interrupt Enable */
+  #define SDMMC_MASK_TXUNDERRIE 0x00000010	/* Tx FIFO UnderRun Error Interrupt Enable */
+  #define SDMMC_MASK_RXOVERRIE  0x00000020	/* Rx FIFO OverRun Error Interrupt Enable */
+  #define SDMMC_MASK_CMDRENDIE  0x00000040	/* Command Response Received Interrupt Enable */
+  #define SDMMC_MASK_CMDSENTIE  0x00000080	/* Command Sent Interrupt Enable */
+  #define SDMMC_MASK_DATAENDIE  0x00000100	/* Data End Interrupt Enable */
+  #define SDMMC_MASK_DBCKENDIE  0x00000400	/* Data Block End Interrupt Enable */
+  #define SDMMC_MASK_CMDACTIE   0x00000800	/* CCommand Acting Interrupt Enable */
+  #define SDMMC_MASK_TXACTIE    0x00001000	/* Data Transmit Acting Interrupt Enable */
+  #define SDMMC_MASK_RXACTIE    0x00002000	/* Data receive acting interrupt enabled */
+  #define SDMMC_MASK_TXFIFOHEIE 0x00004000	/* Tx FIFO Half Empty interrupt Enable */
+  #define SDMMC_MASK_RXFIFOHFIE 0x00008000	/* Rx FIFO Half Full interrupt Enable */
+  #define SDMMC_MASK_TXFIFOFIE  0x00010000	/* Tx FIFO Full interrupt Enable */
+  #define SDMMC_MASK_RXFIFOFIE  0x00020000	/* Rx FIFO Full interrupt Enable */
+  #define SDMMC_MASK_TXFIFOEIE  0x00040000	/* Tx FIFO Empty interrupt Enable */
+  #define SDMMC_MASK_RXFIFOEIE  0x00080000	/* Rx FIFO Empty interrupt Enable */
+  #define SDMMC_MASK_TXDAVLIE   0x00100000	/* Data available in Tx FIFO interrupt Enable */
+  #define SDMMC_MASK_RXDAVLIE   0x00200000	/* Data available in Rx FIFO interrupt Enable */
+  #define SDMMC_MASK_SDIOITIE   0x00400000	/* SDMMC Mode Interrupt Received interrupt Enable */
+#define TOFF_SDIO_FIFOCNT   0x0048		/* (R)  SDIO FIFO counter register */
+#define TOFF_SDIO_FIFO      0x0080		/* (RW) SDIO data FIFO register */
+
+/*
+ *  SYSTEM CONFIGURATION CONTROLLER
+ */
+#define TADR_SYSCFG_BASE    (APB2PERIPH_BASE + 0x3800)
+#define TOFF_SYSCFG_MEMRMP  0x0000		/* (RW) SYSCFG memory remap register */
+#define TOFF_SYSCFG_PMC     0x0004		/* (RW) SYSCFG peripheral mode configuration register */
+#define TOFF_SYSCFG_EXTICR0 0x0008		/* (RW) SYSCFG external interrupt configuration registers 0 */
+#define TOFF_SYSCFG_EXTICR1 0x000C		/* (RW) SYSCFG external interrupt configuration registers 1 */
+#define TOFF_SYSCFG_EXTICR2 0x0010		/* (RW) SYSCFG external interrupt configuration registers 2 */
+#define TOFF_SYSCFG_EXTICR3 0x0014		/* (RW) SYSCFG external interrupt configuration registers 3 */
+#define TOFF_SYSCFG_CMPCR   0x0020		/* (RW) SYSCFG Compensation cell control register */
+
+/*
+ *  EXTERNAL INTERRUPT/EVENT CONTROLLER
+ */
+#define TADR_EXTI_BASE      (APB2PERIPH_BASE + 0x3C00)
+#define TOFF_EXTI_IMR       0x0000		/* (RW) EXTI Interrupt mask register */
+  #define EXTI_IMR_MR0       0x00000001	/* Interrupt Mask on line 0 */
+  #define EXTI_IMR_MR1       0x00000002	/* Interrupt Mask on line 1 */
+  #define EXTI_IMR_MR2       0x00000004	/* Interrupt Mask on line 2 */
+  #define EXTI_IMR_MR3       0x00000008	/* Interrupt Mask on line 3 */
+  #define EXTI_IMR_MR4       0x00000010	/* Interrupt Mask on line 4 */
+  #define EXTI_IMR_MR5       0x00000020	/* Interrupt Mask on line 5 */
+  #define EXTI_IMR_MR6       0x00000040	/* Interrupt Mask on line 6 */
+  #define EXTI_IMR_MR7       0x00000080	/* Interrupt Mask on line 7 */
+  #define EXTI_IMR_MR8       0x00000100	/* Interrupt Mask on line 8 */
+  #define EXTI_IMR_MR9       0x00000200	/* Interrupt Mask on line 9 */
+  #define EXTI_IMR_MR10      0x00000400	/* Interrupt Mask on line 10 */
+  #define EXTI_IMR_MR11      0x00000800	/* Interrupt Mask on line 11 */
+  #define EXTI_IMR_MR12      0x00001000	/* Interrupt Mask on line 12 */
+  #define EXTI_IMR_MR13      0x00002000	/* Interrupt Mask on line 13 */
+  #define EXTI_IMR_MR14      0x00004000	/* Interrupt Mask on line 14 */
+  #define EXTI_IMR_MR15      0x00008000	/* Interrupt Mask on line 15 */
+  #define EXTI_IMR_MR16      0x00010000	/* Interrupt Mask on line 16 */
+  #define EXTI_IMR_MR17      0x00020000	/* Interrupt Mask on line 17 */
+  #define EXTI_IMR_MR18      0x00040000	/* Interrupt Mask on line 18 */
+  #define EXTI_IMR_MR19      0x00080000	/* Interrupt Mask on line 19 */
+  #define EXTI_IMR_MR20      0x00100000	/* Interrupt Mask on line 20 */
+  #define EXTI_IMR_MR21      0x00200000	/* Interrupt Mask on line 21 */
+  #define EXTI_IMR_MR22      0x00400000	/* Interrupt Mask on line 22 */
+  #define EXTI_IMR_MR23      0x00800000	/* Interrupt Mask on line 23 */
+#define TOFF_EXTI_EMR       0x0004		/* (RW) EXTI Event mask register */
+  #define EXTI_EMR_MR0       0x00000001	/* Event Mask on line 0 */
+  #define EXTI_EMR_MR1       0x00000002	/* Event Mask on line 1 */
+  #define EXTI_EMR_MR2       0x00000004	/* Event Mask on line 2 */
+  #define EXTI_EMR_MR3       0x00000008	/* Event Mask on line 3 */
+  #define EXTI_EMR_MR4       0x00000010	/* Event Mask on line 4 */
+  #define EXTI_EMR_MR5       0x00000020	/* Event Mask on line 5 */
+  #define EXTI_EMR_MR6       0x00000040	/* Event Mask on line 6 */
+  #define EXTI_EMR_MR7       0x00000080	/* Event Mask on line 7 */
+  #define EXTI_EMR_MR8       0x00000100	/* Event Mask on line 8 */
+  #define EXTI_EMR_MR9       0x00000200	/* Event Mask on line 9 */
+  #define EXTI_EMR_MR10      0x00000400	/* Event Mask on line 10 */
+  #define EXTI_EMR_MR11      0x00000800	/* Event Mask on line 11 */
+  #define EXTI_EMR_MR12      0x00001000	/* Event Mask on line 12 */
+  #define EXTI_EMR_MR13      0x00002000	/* Event Mask on line 13 */
+  #define EXTI_EMR_MR14      0x00004000	/* Event Mask on line 14 */
+  #define EXTI_EMR_MR15      0x00008000	/* Event Mask on line 15 */
+  #define EXTI_EMR_MR16      0x00010000	/* Event Mask on line 16 */
+  #define EXTI_EMR_MR17      0x00020000	/* Event Mask on line 17 */
+  #define EXTI_EMR_MR18      0x00040000	/* Event Mask on line 18 */
+  #define EXTI_EMR_MR19      0x00080000	/* Event Mask on line 19 */
+  #define EXTI_EMR_MR20      0x00100000	/* Event Mask on line 20 */
+  #define EXTI_EMR_MR21      0x00200000	/* Event Mask on line 21 */
+  #define EXTI_EMR_MR22      0x00400000	/* Event Mask on line 22 */
+  #define EXTI_EMR_MR23      0x00800000	/* Event Mask on line 23 */
+#define TOFF_EXTI_RTSR      0x0008		/* (RW) EXTI Rising trigger selection register */
+  #define EXTI_RTSR_TR0      0x00000001	/* Rising trigger event configuration bit of line 0 */
+  #define EXTI_RTSR_TR1      0x00000002	/* Rising trigger event configuration bit of line 1 */
+  #define EXTI_RTSR_TR2      0x00000004	/* Rising trigger event configuration bit of line 2 */
+  #define EXTI_RTSR_TR3      0x00000008	/* Rising trigger event configuration bit of line 3 */
+  #define EXTI_RTSR_TR4      0x00000010	/* Rising trigger event configuration bit of line 4 */
+  #define EXTI_RTSR_TR5      0x00000020	/* Rising trigger event configuration bit of line 5 */
+  #define EXTI_RTSR_TR6      0x00000040	/* Rising trigger event configuration bit of line 6 */
+  #define EXTI_RTSR_TR7      0x00000080	/* Rising trigger event configuration bit of line 7 */
+  #define EXTI_RTSR_TR8      0x00000100	/* Rising trigger event configuration bit of line 8 */
+  #define EXTI_RTSR_TR9      0x00000200	/* Rising trigger event configuration bit of line 9 */
+  #define EXTI_RTSR_TR10     0x00000400	/* Rising trigger event configuration bit of line 10 */
+  #define EXTI_RTSR_TR11     0x00000800	/* Rising trigger event configuration bit of line 11 */
+  #define EXTI_RTSR_TR12     0x00001000	/* Rising trigger event configuration bit of line 12 */
+  #define EXTI_RTSR_TR13     0x00002000	/* Rising trigger event configuration bit of line 13 */
+  #define EXTI_RTSR_TR14     0x00004000	/* Rising trigger event configuration bit of line 14 */
+  #define EXTI_RTSR_TR15     0x00008000	/* Rising trigger event configuration bit of line 15 */
+  #define EXTI_RTSR_TR16     0x00010000	/* Rising trigger event configuration bit of line 16 */
+  #define EXTI_RTSR_TR17     0x00020000	/* Rising trigger event configuration bit of line 17 */
+  #define EXTI_RTSR_TR18     0x00040000	/* Rising trigger event configuration bit of line 18 */
+  #define EXTI_RTSR_TR19     0x00080000	/* Rising trigger event configuration bit of line 19 */
+  #define EXTI_RTSR_TR20     0x00100000	/* Rising trigger event configuration bit of line 20 */
+  #define EXTI_RTSR_TR21     0x00200000	/* Rising trigger event configuration bit of line 21 */
+  #define EXTI_RTSR_TR22     0x00400000	/* Rising trigger event configuration bit of line 22 */
+  #define EXTI_RTSR_TR23     0x00800000	/* Rising trigger event configuration bit of line 23 */
+#define TOFF_EXTI_FTSR      0x000C		/* (RW) EXTI Falling trigger selection register */
+  #define EXTI_FTSR_TR0      0x00000001	/* Falling trigger event configuration bit of line 0 */
+  #define EXTI_FTSR_TR1      0x00000002	/* Falling trigger event configuration bit of line 1 */
+  #define EXTI_FTSR_TR2      0x00000004	/* Falling trigger event configuration bit of line 2 */
+  #define EXTI_FTSR_TR3      0x00000008	/* Falling trigger event configuration bit of line 3 */
+  #define EXTI_FTSR_TR4      0x00000010	/* Falling trigger event configuration bit of line 4 */
+  #define EXTI_FTSR_TR5      0x00000020	/* Falling trigger event configuration bit of line 5 */
+  #define EXTI_FTSR_TR6      0x00000040	/* Falling trigger event configuration bit of line 6 */
+  #define EXTI_FTSR_TR7      0x00000080	/* Falling trigger event configuration bit of line 7 */
+  #define EXTI_FTSR_TR8      0x00000100	/* Falling trigger event configuration bit of line 8 */
+  #define EXTI_FTSR_TR9      0x00000200	/* Falling trigger event configuration bit of line 9 */
+  #define EXTI_FTSR_TR10     0x00000400	/* Falling trigger event configuration bit of line 10 */
+  #define EXTI_FTSR_TR11     0x00000800	/* Falling trigger event configuration bit of line 11 */
+  #define EXTI_FTSR_TR12     0x00001000	/* Falling trigger event configuration bit of line 12 */
+  #define EXTI_FTSR_TR13     0x00002000	/* Falling trigger event configuration bit of line 13 */
+  #define EXTI_FTSR_TR14     0x00004000	/* Falling trigger event configuration bit of line 14 */
+  #define EXTI_FTSR_TR15     0x00008000	/* Falling trigger event configuration bit of line 15 */
+  #define EXTI_FTSR_TR16     0x00010000	/* Falling trigger event configuration bit of line 16 */
+  #define EXTI_FTSR_TR17     0x00020000	/* Falling trigger event configuration bit of line 17 */
+  #define EXTI_FTSR_TR18     0x00040000	/* Falling trigger event configuration bit of line 18 */
+  #define EXTI_FTSR_TR19     0x00080000	/* Falling trigger event configuration bit of line 19 */
+  #define EXTI_FTSR_TR20     0x00100000	/* Falling trigger event configuration bit of line 20 */
+  #define EXTI_FTSR_TR21     0x00200000	/* Falling trigger event configuration bit of line 21 */
+  #define EXTI_FTSR_TR22     0x00400000	/* Falling trigger event configuration bit of line 22 */
+  #define EXTI_FTSR_TR23     0x00800000	/* Falling trigger event configuration bit of line 23 */
+#define TOFF_EXTI_SWIER     0x0010		/* (RW) EXTI Software interrupt event register */
+  #define EXTI_SWIER_SWIER0  0x00000001	/* Software Interrupt on line 0 */
+  #define EXTI_SWIER_SWIER1  0x00000002	/* Software Interrupt on line 1 */
+  #define EXTI_SWIER_SWIER2  0x00000004	/* Software Interrupt on line 2 */
+  #define EXTI_SWIER_SWIER3  0x00000008	/* Software Interrupt on line 3 */
+  #define EXTI_SWIER_SWIER4  0x00000010	/* Software Interrupt on line 4 */
+  #define EXTI_SWIER_SWIER5  0x00000020	/* Software Interrupt on line 5 */
+  #define EXTI_SWIER_SWIER6  0x00000040	/* Software Interrupt on line 6 */
+  #define EXTI_SWIER_SWIER7  0x00000080	/* Software Interrupt on line 7 */
+  #define EXTI_SWIER_SWIER8  0x00000100	/* Software Interrupt on line 8 */
+  #define EXTI_SWIER_SWIER9  0x00000200	/* Software Interrupt on line 9 */
+  #define EXTI_SWIER_SWIER10 0x00000400	/* Software Interrupt on line 10 */
+  #define EXTI_SWIER_SWIER11 0x00000800	/* Software Interrupt on line 11 */
+  #define EXTI_SWIER_SWIER12 0x00001000	/* Software Interrupt on line 12 */
+  #define EXTI_SWIER_SWIER13 0x00002000	/* Software Interrupt on line 13 */
+  #define EXTI_SWIER_SWIER14 0x00004000	/* Software Interrupt on line 14 */
+  #define EXTI_SWIER_SWIER15 0x00008000	/* Software Interrupt on line 15 */
+  #define EXTI_SWIER_SWIER16 0x00010000	/* Software Interrupt on line 16 */
+  #define EXTI_SWIER_SWIER17 0x00020000	/* Software Interrupt on line 17 */
+  #define EXTI_SWIER_SWIER18 0x00040000	/* Software Interrupt on line 18 */
+  #define EXTI_SWIER_SWIER19 0x00080000	/* Software Interrupt on line 19 */
+  #define EXTI_SWIER_SWIER20 0x00100000	/* Software Interrupt on line 20 */
+  #define EXTI_SWIER_SWIER21 0x00200000	/* Software Interrupt on line 21 */
+  #define EXTI_SWIER_SWIER22 0x00400000	/* Software Interrupt on line 22 */
+  #define EXTI_SWIER_SWIER23 0x00800000	/* Software Interrupt on line 23 */
+#define TOFF_EXTI_PR        0x0014		/* (RW) EXTI Pending register */
+  #define EXTI_PR_PR0        0x00000001	/* Pending bit for line 0 */
+  #define EXTI_PR_PR1        0x00000002	/* Pending bit for line 1 */
+  #define EXTI_PR_PR2        0x00000004	/* Pending bit for line 2 */
+  #define EXTI_PR_PR3        0x00000008	/* Pending bit for line 3 */
+  #define EXTI_PR_PR4        0x00000010	/* Pending bit for line 4 */
+  #define EXTI_PR_PR5        0x00000020	/* Pending bit for line 5 */
+  #define EXTI_PR_PR6        0x00000040	/* Pending bit for line 6 */
+  #define EXTI_PR_PR7        0x00000080	/* Pending bit for line 7 */
+  #define EXTI_PR_PR8        0x00000100	/* Pending bit for line 8 */
+  #define EXTI_PR_PR9        0x00000200	/* Pending bit for line 9 */
+  #define EXTI_PR_PR10       0x00000400	/* Pending bit for line 10 */
+  #define EXTI_PR_PR11       0x00000800	/* Pending bit for line 11 */
+  #define EXTI_PR_PR12       0x00001000	/* Pending bit for line 12 */
+  #define EXTI_PR_PR13       0x00002000	/* Pending bit for line 13 */
+  #define EXTI_PR_PR14       0x00004000	/* Pending bit for line 14 */
+  #define EXTI_PR_PR15       0x00008000	/* Pending bit for line 15 */
+  #define EXTI_PR_PR16       0x00010000	/* Pending bit for line 16 */
+  #define EXTI_PR_PR17       0x00020000	/* Pending bit for line 17 */
+  #define EXTI_PR_PR18       0x00040000	/* Pending bit for line 18 */
+  #define EXTI_PR_PR19       0x00080000	/* Pending bit for line 19 */
+  #define EXTI_PR_PR20       0x00100000	/* Pending bit for line 20 */
+  #define EXTI_PR_PR21       0x00200000	/* Pending bit for line 21 */
+  #define EXTI_PR_PR22       0x00400000	/* Pending bit for line 22 */
+  #define EXTI_PR_PR23       0x00800000	/* Pending bit for line 23 */
+
+
+/*
+ *  GENERAL PURPOSE I/O
+ */
+#define TADR_GPIOA_BASE     (AHB1PERIPH_BASE + 0x0000)
+#define TADR_GPIOB_BASE     (AHB1PERIPH_BASE + 0x0400)
+#define TADR_GPIOC_BASE     (AHB1PERIPH_BASE + 0x0800)
+#define TADR_GPIOD_BASE     (AHB1PERIPH_BASE + 0x0C00)
+#define TADR_GPIOE_BASE     (AHB1PERIPH_BASE + 0x1000)
+#define TADR_GPIOF_BASE     (AHB1PERIPH_BASE + 0x1400)
+#define TADR_GPIOG_BASE     (AHB1PERIPH_BASE + 0x1800)
+#define TADR_GPIOH_BASE     (AHB1PERIPH_BASE + 0x1C00)
+#define TADR_GPIOI_BASE     (AHB1PERIPH_BASE + 0x2000)
+#define TADR_GPIOJ_BASE     (AHB1PERIPH_BASE + 0x2400)
+#define TADR_GPIOK_BASE     (AHB1PERIPH_BASE + 0x2800)
+#define TOFF_GPIO_MODER     0x0000		/* (RW) GPIO port mode register */
+  #define GPIO_MODER_MODER0  0x00000003
+  #define GPIO_MODER_MODER1  0x0000000C
+  #define GPIO_MODER_MODER2  0x00000030
+  #define GPIO_MODER_MODER3  0x000000C0
+  #define GPIO_MODER_MODER4  0x00000300
+  #define GPIO_MODER_MODER5  0x00000C00
+  #define GPIO_MODER_MODER6  0x00003000
+  #define GPIO_MODER_MODER7  0x0000C000
+  #define GPIO_MODER_MODER8  0x00030000
+  #define GPIO_MODER_MODER9  0x000C0000
+  #define GPIO_MODER_MODER10 0x00300000
+  #define GPIO_MODER_MODER11 0x00C00000
+  #define GPIO_MODER_MODER12 0x03000000
+  #define GPIO_MODER_MODER13 0x0C000000
+  #define GPIO_MODER_MODER14 0x30000000
+  #define GPIO_MODER_MODER15 0xC0000000
+#define TOFF_GPIO_OTYPER    0x0004		/* (RW) GPIO port output type register */
+  #define GPIO_OTYPER_OT     0x00000001
+  #define GPIO_OTYPER_OT_0   0x00000001
+  #define GPIO_OTYPER_OT_1   0x00000002
+  #define GPIO_OTYPER_OT_2   0x00000004
+  #define GPIO_OTYPER_OT_3   0x00000008
+  #define GPIO_OTYPER_OT_4   0x00000010
+  #define GPIO_OTYPER_OT_5   0x00000020
+  #define GPIO_OTYPER_OT_6   0x00000040
+  #define GPIO_OTYPER_OT_7   0x00000080
+  #define GPIO_OTYPER_OT_8   0x00000100
+  #define GPIO_OTYPER_OT_9   0x00000200
+  #define GPIO_OTYPER_OT_10  0x00000400
+  #define GPIO_OTYPER_OT_11  0x00000800
+  #define GPIO_OTYPER_OT_12  0x00001000
+  #define GPIO_OTYPER_OT_13  0x00002000
+  #define GPIO_OTYPER_OT_14  0x00004000
+  #define GPIO_OTYPER_OT_15  0x00008000
+#define TOFF_GPIO_OSPEEDR   0x0008		/* (RW) GPIO port output speed register */
+  #define GPIO_OSPEEDER_OSPEEDR0 0x00000003
+  #define GPIO_OSPEEDER_OSPEEDR1 0x0000000C
+  #define GPIO_OSPEEDER_OSPEEDR2 0x00000030
+  #define GPIO_OSPEEDER_OSPEEDR3 0x000000C0
+  #define GPIO_OSPEEDER_OSPEEDR4 0x00000300
+  #define GPIO_OSPEEDER_OSPEEDR5 0x00000C00
+  #define GPIO_OSPEEDER_OSPEEDR6 0x00003000
+  #define GPIO_OSPEEDER_OSPEEDR7 0x0000C000
+  #define GPIO_OSPEEDER_OSPEEDR8 0x00030000
+  #define GPIO_OSPEEDER_OSPEEDR9 0x000C0000
+  #define GPIO_OSPEEDER_OSPEEDR10 0x00300000
+  #define GPIO_OSPEEDER_OSPEEDR11 0x00C00000
+  #define GPIO_OSPEEDER_OSPEEDR12 0x03000000
+  #define GPIO_OSPEEDER_OSPEEDR13 0x0C000000
+  #define GPIO_OSPEEDER_OSPEEDR14 0x30000000
+  #define GPIO_OSPEEDER_OSPEEDR15 0xC0000000
+#define TOFF_GPIO_PUPDR     0x000C		/* (RW) GPIO port pull-up/pull-down register */
+  #define GPIO_PUPDR_PUPDR0  0x00000003
+  #define GPIO_PUPDR_PUPDR1  0x0000000C
+  #define GPIO_PUPDR_PUPDR2  0x00000030
+  #define GPIO_PUPDR_PUPDR3  0x000000C0
+  #define GPIO_PUPDR_PUPDR4  0x00000300
+  #define GPIO_PUPDR_PUPDR5  0x00000C00
+  #define GPIO_PUPDR_PUPDR6  0x00003000
+  #define GPIO_PUPDR_PUPDR7  0x0000C000
+  #define GPIO_PUPDR_PUPDR8  0x00030000
+  #define GPIO_PUPDR_PUPDR9  0x000C0000
+  #define GPIO_PUPDR_PUPDR10 0x00300000
+  #define GPIO_PUPDR_PUPDR11 0x00C00000
+  #define GPIO_PUPDR_PUPDR12 0x03000000
+  #define GPIO_PUPDR_PUPDR13 0x0C000000
+  #define GPIO_PUPDR_PUPDR14 0x30000000
+  #define GPIO_PUPDR_PUPDR15 0xC0000000
+#define TOFF_GPIO_IDR       0x0010		/* (R)  GPIO port input data register */
+#define TOFF_GPIO_ODR       0x0014		/* (RW) GPIO port output data register */
+#define TOFF_GPIO_BSRR      0x0018		/* (RW) GPIO port bit set/reset low register */
+#define TOFF_GPIO_LCKR      0x001C		/* (RW) GPIO port configuration lock register */
+#define TOFF_GPIO_AFR0      0x0020		/* (RW) GPIO alternate function registers */
+#define TOFF_GPIO_AFR1      0x0024		/* (RW) GPIO alternate function registers */
+
+/*
+ *  CRC CALCULATION UNIT
+ */
+#define TADR_CRC_BASE       (AHB1PERIPH_BASE + 0x3000)
+#define TOFF_CRC_DR         0x0000		/* (RW) CRC Data register */
+#define TOFF_CRC_IDR        0x0004		/* (RW-8) CRC Independent data register */
+#define TOFF_CRC_CR         0x0008		/* (RW) CRC Control register */
+#define TOFF_CRC_INIT       0x0010		/* (RW) Initial CRC value register */
+#define TOFF_CRC_POL        0x0014		/* (RW) CRC polynomial register */
+
+/*
+ *  RESET AND CLOCK CONTROL
+ */
+#define TADR_RCC_BASE       (AHB1PERIPH_BASE + 0x3800)
+#define TOFF_RCC_CR         0x0000		/* (RW) RCC clock control register */
+  #define RCC_CR_HSION             0x00000001
+  #define RCC_CR_HSIRDY            0x00000002
+  #define RCC_CR_HSITRIM           0x000000F8
+  #define RCC_CR_HSITRIM_0         0x00000008	/* Bit 0 */
+  #define RCC_CR_HSITRIM_1         0x00000010	/* Bit 1 */
+  #define RCC_CR_HSITRIM_2         0x00000020	/* Bit 2 */
+  #define RCC_CR_HSITRIM_3         0x00000040	/* Bit 3 */
+  #define RCC_CR_HSITRIM_4         0x00000080	/* Bit 4 */
+  #define RCC_CR_HSICAL            0x0000FF00
+  #define RCC_CR_HSICAL_0          0x00000100	/* Bit 0 */
+  #define RCC_CR_HSICAL_1          0x00000200	/* Bit 1 */
+  #define RCC_CR_HSICAL_2          0x00000400	/* Bit 2 */
+  #define RCC_CR_HSICAL_3          0x00000800	/* Bit 3 */
+  #define RCC_CR_HSICAL_4          0x00001000	/* Bit 4 */
+  #define RCC_CR_HSICAL_5          0x00002000	/* Bit 5 */
+  #define RCC_CR_HSICAL_6          0x00004000	/* Bit 6 */
+  #define RCC_CR_HSICAL_7          0x00008000	/* Bit 7 */
+  #define RCC_CR_HSEON             0x00010000
+  #define RCC_CR_HSERDY            0x00020000
+  #define RCC_CR_HSEBYP            0x00040000
+  #define RCC_CR_CSSON             0x00080000
+  #define RCC_CR_PLLON             0x01000000
+  #define RCC_CR_PLLRDY            0x02000000
+  #define RCC_CR_PLLI2SON          0x04000000
+  #define RCC_CR_PLLI2SRDY         0x08000000
+  #define RCC_CR_PLLSAION          0x10000000
+  #define RCC_CR_PLLSAIRDY         0x20000000
+#define TOFF_RCC_PLLCFGR    0x0004		/* (RW) RCC PLL configuration register */
+  #define RCC_PLLCFGR_PLLM         0x0000003F
+  #define RCC_PLLCFGR_PLLM_0       0x00000001
+  #define RCC_PLLCFGR_PLLM_1       0x00000002
+  #define RCC_PLLCFGR_PLLM_2       0x00000004
+  #define RCC_PLLCFGR_PLLM_3       0x00000008
+  #define RCC_PLLCFGR_PLLM_4       0x00000010
+  #define RCC_PLLCFGR_PLLM_5       0x00000020
+  #define RCC_PLLCFGR_PLLN         0x00007FC0
+  #define RCC_PLLCFGR_PLLN_0       0x00000040
+  #define RCC_PLLCFGR_PLLN_1       0x00000080
+  #define RCC_PLLCFGR_PLLN_2       0x00000100
+  #define RCC_PLLCFGR_PLLN_3       0x00000200
+  #define RCC_PLLCFGR_PLLN_4       0x00000400
+  #define RCC_PLLCFGR_PLLN_5       0x00000800
+  #define RCC_PLLCFGR_PLLN_6       0x00001000
+  #define RCC_PLLCFGR_PLLN_7       0x00002000
+  #define RCC_PLLCFGR_PLLN_8       0x00004000
+  #define RCC_PLLCFGR_PLLP         0x00030000
+  #define RCC_PLLCFGR_PLLP_0       0x00010000
+  #define RCC_PLLCFGR_PLLP_1       0x00020000
+  #define RCC_PLLCFGR_PLLSRC       0x00400000
+  #define RCC_PLLCFGR_PLLSRC_HSE   0x00400000
+  #define RCC_PLLCFGR_PLLSRC_HSI   0x00000000
+  #define RCC_PLLCFGR_PLLQ         0x0F000000
+  #define RCC_PLLCFGR_PLLQ_0       0x01000000
+  #define RCC_PLLCFGR_PLLQ_1       0x02000000
+  #define RCC_PLLCFGR_PLLQ_2       0x04000000
+  #define RCC_PLLCFGR_PLLQ_3       0x08000000
+#define TOFF_RCC_CFGR       0x0008		/* (RW) RCC clock configuration register */
+  #define RCC_CFGR_SW              0x00000003	/* SW[1:0] bits (System clock Switch) */
+  #define RCC_CFGR_SW_0            0x00000001	/* Bit 0 */
+  #define RCC_CFGR_SW_1            0x00000002	/* Bit 1 */
+  #define RCC_CFGR_SW_HSI          0x00000000	/* HSI selected as system clock */
+  #define RCC_CFGR_SW_HSE          0x00000001	/* HSE selected as system clock */
+  #define RCC_CFGR_SW_PLL          0x00000002	/* PLL selected as system clock */
+  #define RCC_CFGR_SWS             0x0000000C	/* SWS[1:0] bits (System Clock Switch Status) */
+  #define RCC_CFGR_SWS_0           0x00000004	/* Bit 0 */
+  #define RCC_CFGR_SWS_1           0x00000008	/* Bit 1 */
+  #define RCC_CFGR_SWS_HSI         0x00000000	/* HSI oscillator used as system clock */
+  #define RCC_CFGR_SWS_HSE         0x00000004	/* HSE oscillator used as system clock */
+  #define RCC_CFGR_SWS_PLL         0x00000008	/* PLL used as system clock */
+  #define RCC_CFGR_HPRE            0x000000F0	/* HPRE[3:0] bits (AHB prescaler) */
+  #define RCC_CFGR_HPRE_0          0x00000010	/* Bit 0 */
+  #define RCC_CFGR_HPRE_1          0x00000020	/* Bit 1 */
+  #define RCC_CFGR_HPRE_2          0x00000040	/* Bit 2 */
+  #define RCC_CFGR_HPRE_3          0x00000080	/* Bit 3 */
+  #define RCC_CFGR_HPRE_DIV1       0x00000000	/* SYSCLK not divided */
+  #define RCC_CFGR_HPRE_DIV2       0x00000080	/* SYSCLK divided by 2 */
+  #define RCC_CFGR_HPRE_DIV4       0x00000090	/* SYSCLK divided by 4 */
+  #define RCC_CFGR_HPRE_DIV8       0x000000A0	/* SYSCLK divided by 8 */
+  #define RCC_CFGR_HPRE_DIV16      0x000000B0	/* SYSCLK divided by 16 */
+  #define RCC_CFGR_HPRE_DIV64      0x000000C0	/* SYSCLK divided by 64 */
+  #define RCC_CFGR_HPRE_DIV128     0x000000D0	/* SYSCLK divided by 128 */
+  #define RCC_CFGR_HPRE_DIV256     0x000000E0	/* SYSCLK divided by 256 */
+  #define RCC_CFGR_HPRE_DIV512     0x000000F0	/* SYSCLK divided by 512 */
+  #define RCC_CFGR_PPRE1           0x00001C00	/* PRE1[2:0] bits (APB1 prescaler) */
+  #define RCC_CFGR_PPRE1_0         0x00000400	/* Bit 0 */
+  #define RCC_CFGR_PPRE1_1         0x00000800	/* Bit 1 */
+  #define RCC_CFGR_PPRE1_2         0x00001000	/* Bit 2 */
+  #define RCC_CFGR_PPRE1_DIV1      0x00000000	/* HCLK not divided */
+  #define RCC_CFGR_PPRE1_DIV2      0x00001000	/* HCLK divided by 2 */
+  #define RCC_CFGR_PPRE1_DIV4      0x00001400	/* HCLK divided by 4 */
+  #define RCC_CFGR_PPRE1_DIV8      0x00001800	/* HCLK divided by 8 */
+  #define RCC_CFGR_PPRE1_DIV16     0x00001C00	/* HCLK divided by 16 */
+  #define RCC_CFGR_PPRE2           0x0000E000	/* PRE2[2:0] bits (APB2 prescaler) */
+  #define RCC_CFGR_PPRE2_0         0x00002000	/* Bit 0 */
+  #define RCC_CFGR_PPRE2_1         0x00004000	/* Bit 1 */
+  #define RCC_CFGR_PPRE2_2         0x00008000	/* Bit 2 */
+  #define RCC_CFGR_PPRE2_DIV1      0x00000000	/* HCLK not divided */
+  #define RCC_CFGR_PPRE2_DIV2      0x00008000	/* HCLK divided by 2 */
+  #define RCC_CFGR_PPRE2_DIV4      0x0000A000	/* HCLK divided by 4 */
+  #define RCC_CFGR_PPRE2_DIV8      0x0000C000	/* HCLK divided by 8 */
+  #define RCC_CFGR_PPRE2_DIV16     0x0000E000	/* HCLK divided by 16 */
+  #define RCC_CFGR_RTCPRE          0x001F0000
+  #define RCC_CFGR_RTCPRE_0        0x00010000
+  #define RCC_CFGR_RTCPRE_1        0x00020000
+  #define RCC_CFGR_RTCPRE_2        0x00040000
+  #define RCC_CFGR_RTCPRE_3        0x00080000
+  #define RCC_CFGR_RTCPRE_4        0x00100000
+  #define RCC_CFGR_MCO1            0x00600000
+  #define RCC_CFGR_MCO1_0          0x00200000
+  #define RCC_CFGR_MCO1_1          0x00400000
+  #define RCC_CFGR_I2SSRC          0x00800000
+  #define RCC_CFGR_MCO1PRE         0x07000000
+  #define RCC_CFGR_MCO1PRE_0       0x01000000
+  #define RCC_CFGR_MCO1PRE_1       0x02000000
+  #define RCC_CFGR_MCO1PRE_2       0x04000000
+  #define RCC_CFGR_MCO2PRE         0x38000000
+  #define RCC_CFGR_MCO2PRE_0       0x08000000
+  #define RCC_CFGR_MCO2PRE_1       0x10000000
+  #define RCC_CFGR_MCO2PRE_2       0x20000000
+  #define RCC_CFGR_MCO2            0xC0000000
+  #define RCC_CFGR_MCO2_0          0x40000000
+  #define RCC_CFGR_MCO2_1          0x80000000
+#define TOFF_RCC_CIR        0x000C		/* (RW) RCC clock interrupt register */
+  #define RCC_CIR_LSIRDYF          0x00000001
+  #define RCC_CIR_LSERDYF          0x00000002
+  #define RCC_CIR_HSIRDYF          0x00000004
+  #define RCC_CIR_HSERDYF          0x00000008
+  #define RCC_CIR_PLLRDYF          0x00000010
+  #define RCC_CIR_PLLI2SRDYF       0x00000020
+#ifdef TOPPERS_STM32F723_DISCOVERY
+  #define RCC_CIR_PLLSAIRDYF       0x00000040
+#endif
+  #define RCC_CIR_CSSF             0x00000080
+  #define RCC_CIR_LSIRDYIE         0x00000100
+  #define RCC_CIR_LSERDYIE         0x00000200
+  #define RCC_CIR_HSIRDYIE         0x00000400
+  #define RCC_CIR_HSERDYIE         0x00000800
+  #define RCC_CIR_PLLRDYIE         0x00001000
+  #define RCC_CIR_PLLI2SRDYIE      0x00002000
+#ifdef TOPPERS_STM32F723_DISCOVERY
+  #define RCC_CIR_PLLSAIRDYIE      0x00004000
+#endif
+  #define RCC_CIR_LSIRDYC          0x00010000
+  #define RCC_CIR_LSERDYC          0x00020000
+  #define RCC_CIR_HSIRDYC          0x00040000
+  #define RCC_CIR_HSERDYC          0x00080000
+  #define RCC_CIR_PLLRDYC          0x00100000
+  #define RCC_CIR_PLLI2SRDYC       0x00200000
+#ifdef TOPPERS_STM32F723_DISCOVERY
+  #define RCC_CIR_PLLSAIRDYC       0x00400000
+#endif
+  #define RCC_CIR_CSSC             0x00800000
+#define TOFF_RCC_AHB1RSTR   0x0010		/* (RW) RCC AHB1 peripheral reset register */
+  #define RCC_AHB1RSTR_GPIOARST    0x00000001
+  #define RCC_AHB1RSTR_GPIOBRST    0x00000002
+  #define RCC_AHB1RSTR_GPIOCRST    0x00000004
+  #define RCC_AHB1RSTR_GPIODRST    0x00000008
+  #define RCC_AHB1RSTR_GPIOERST    0x00000010
+  #define RCC_AHB1RSTR_GPIOFRST    0x00000020
+  #define RCC_AHB1RSTR_GPIOGRST    0x00000040
+  #define RCC_AHB1RSTR_GPIOHRST    0x00000080
+  #define RCC_AHB1RSTR_GPIOIRST    0x00000100
+  #define RCC_AHB1RSTR_GPIOJRST    0x00000200
+  #define RCC_AHB1RSTR_GPIOKRST    0x00000400
+  #define RCC_AHB1RSTR_CRCRST      0x00001000
+  #define RCC_AHB1RSTR_DMA1RST     0x00200000
+  #define RCC_AHB1RSTR_DMA2RST     0x00400000
+  #define RCC_AHB1RSTR_DMA2DRST    0x00800000
+  #define RCC_AHB1RSTR_ETHMACRST   0x02000000
+  #define RCC_AHB1RSTR_OTGHRST     0x20000000
+#define TOFF_RCC_AHB2RSTR   0x0014		/* (RW) RCC AHB2 peripheral reset register */
+  #define RCC_AHB2RSTR_DCMIRST     0x00000001
+  #define RCC_AHB2RSTR_CRYPRST     0x00000010
+  #define RCC_AHB2RSTR_HSAHRST     0x00000020
+  #define RCC_AHB2RSTR_RNGRST      0x00000040
+  #define RCC_AHB2RSTR_OTGFSRST    0x00000080
+#define TOFF_RCC_AHB3RSTR   0x0018		/* (RW) RCC AHB3 peripheral reset register */
+  #define RCC_AHB3RSTR_FSMCRST     0x00000001
+  #define RCC_AHB3RSTR_FMCRST      RCC_AHB3RSTR_FSMCRST
+  #define RCC_AHB3RSTR_QSPIRST     0x00000002
+#define TOFF_RCC_APB1RSTR   0x0020		/* (RW) RCC APB1 peripheral reset register */
+  #define RCC_APB1RSTR_TIM2RST     0x00000001
+  #define RCC_APB1RSTR_TIM3RST     0x00000002
+  #define RCC_APB1RSTR_TIM4RST     0x00000004
+  #define RCC_APB1RSTR_TIM5RST     0x00000008
+  #define RCC_APB1RSTR_TIM6RST     0x00000010
+  #define RCC_APB1RSTR_TIM7RST     0x00000020
+  #define RCC_APB1RSTR_TIM12RST    0x00000040
+  #define RCC_APB1RSTR_TIM13RST    0x00000080
+  #define RCC_APB1RSTR_TIM14RST    0x00000100
+  #define RCC_APB1RSTR_WWDGRST     0x00000800
+  #define RCC_APB1RSTR_SPI2RST     0x00008000
+  #define RCC_APB1RSTR_SPI3RST     0x00010000
+  #define RCC_APB1RSTR_USART2RST   0x00020000
+  #define RCC_APB1RSTR_USART3RST   0x00040000
+  #define RCC_APB1RSTR_UART4RST    0x00080000
+  #define RCC_APB1RSTR_UART5RST    0x00100000
+  #define RCC_APB1RSTR_I2C1RST     0x00200000
+  #define RCC_APB1RSTR_I2C2RST     0x00400000
+  #define RCC_APB1RSTR_I2C3RST     0x00800000
+  #define RCC_APB1RSTR_I2C4RST     0x01000000
+  #define RCC_APB1RSTR_CAN1RST     0x02000000
+  #define RCC_APB1RSTR_CAN2RST     0x04000000
+  #define RCC_APB1RSTR_PWRRST      0x10000000
+  #define RCC_APB1RSTR_DACRST      0x20000000
+  #define RCC_APB1RSTR_UART7RST    0x40000000
+  #define RCC_APB1RSTR_UART8RST    0x80000000
+#define TOFF_RCC_APB2RSTR   0x0024		/* (RW) RCC APB2 peripheral reset register */
+  #define RCC_APB2RSTR_TIM1RST     0x00000001
+  #define RCC_APB2RSTR_TIM8RST     0x00000002
+  #define RCC_APB2RSTR_USART1RST   0x00000010
+  #define RCC_APB2RSTR_USART6RST   0x00000020
+#ifdef TOPPERS_STM32F723_DISCOVERY
+  #define RCC_APB2RSTR_SDMMC2RST   0x00000080
+#endif
+  #define RCC_APB2RSTR_ADCRST      0x00000100
+  #define RCC_APB2RSTR_SDIORST     0x00000800
+  #define RCC_APB2RSTR_SDMMC1RST   RCC_APB2RSTR_SDIORST
+  #define RCC_APB2RSTR_SPI1RST     0x00001000
+#ifdef TOPPERS_STM32F723_DISCOVERY
+  #define RCC_APB2RSTR_SPI4RST     0x00002000
+#endif
+  #define RCC_APB2RSTR_SYSCFGRST   0x00004000
+  #define RCC_APB2RSTR_TIM9RST     0x00010000
+  #define RCC_APB2RSTR_TIM10RST    0x00020000
+  #define RCC_APB2RSTR_TIM11RST    0x00040000
+  #define RCC_APB2RSTR_SPI5RST     0x00100000
+  #define RCC_APB2RSTR_SPI6RST     0x00200000
+  #define RCC_APB2RSTR_SAI1RST     0x00400000
+  #define RCC_APB2RSTR_SAI2RST     0x00800000
+  #define RCC_APB2RSTR_LTDCRST     0x04000000
+#ifdef TOPPERS_STM32F769_DISCOVERY
+  #define RCC_APB2RSTR_DSIRST      0x08000000
+#endif
+#if defined(TOPPERS_STM32F769_DISCOVERY) || defined(TOPPERS_STM32F767_NUCLEO144)
+  #define RCC_APB2RSTR_DFSDM1RST   0x20000000U
+  #define RCC_APB2RSTR_MDIORST     0x40000000U
+#endif
+#ifdef TOPPERS_STM32F723_DISCOVERY
+  #define RCC_APB2RSTR_OTGPHYCRST  0x80000000
+#endif
+#define TOFF_RCC_AHB1ENR    0x0030		/* (RW) RCC AHB1 peripheral clock register */
+  #define RCC_AHB1ENR_GPIOAEN      0x00000001
+  #define RCC_AHB1ENR_GPIOBEN      0x00000002
+  #define RCC_AHB1ENR_GPIOCEN      0x00000004
+  #define RCC_AHB1ENR_GPIODEN      0x00000008
+  #define RCC_AHB1ENR_GPIOEEN      0x00000010
+  #define RCC_AHB1ENR_GPIOFEN      0x00000020
+  #define RCC_AHB1ENR_GPIOGEN      0x00000040
+  #define RCC_AHB1ENR_GPIOHEN      0x00000080
+  #define RCC_AHB1ENR_GPIOIEN      0x00000100
+  #define RCC_AHB1ENR_GPIOJEN      0x00000200
+  #define RCC_AHB1ENR_GPIOKEN      0x00000400
+  #define RCC_AHB1ENR_CRCEN        0x00001000
+  #define RCC_AHB1ENR_BKPSRAMEN    0x00040000
+#ifdef TOPPERS_STM32F723_DISCOVERY
+  #define RCC_AHB1ENR_DTCMRAMEN    0x00100000
+#else
+  #define RCC_AHB1ENR_CCMDATARAMEN 0x00100000
+#endif
+  #define RCC_AHB1ENR_DMA1EN       0x00200000
+  #define RCC_AHB1ENR_DMA2EN       0x00400000
+  #define RCC_AHB1ENR_DMA2DEN      0x00800000
+  #define RCC_AHB1ENR_ETHMACEN     0x02000000
+  #define RCC_AHB1ENR_ETHMACTXEN   0x04000000
+  #define RCC_AHB1ENR_ETHMACRXEN   0x08000000
+  #define RCC_AHB1ENR_ETHMACPTPEN  0x10000000
+  #define RCC_AHB1ENR_OTGHSEN      0x20000000
+  #define RCC_AHB1ENR_OTGHSULPIEN  0x40000000
+#define TOFF_RCC_AHB2ENR    0x0034		/* (RW) RCC AHB2 peripheral clock register */
+  #define RCC_AHB2ENR_DCMIEN       0x00000001
+  #define RCC_AHB2ENR_CRYPEN       0x00000010
+  #define RCC_AHB2ENR_HASHEN       0x00000020
+  #define RCC_AHB2ENR_RNGEN        0x00000040
+  #define RCC_AHB2ENR_OTGFSEN      0x00000080
+#define TOFF_RCC_AHB3ENR    0x0038		/* (RW) RCC AHB3 peripheral clock register */
+  #define RCC_AHB3ENR_FSMCEN       0x00000001
+  #define RCC_AHB3ENR_FMCEN        RCC_AHB3ENR_FSMCEN
+  #define RCC_AHB3ENR_QSPIEN       0x00000002
+#define TOFF_RCC_APB1ENR    0x0040		/* (RW) RCC APB1 peripheral clock enable register */
+  #define RCC_APB1ENR_TIM2EN       0x00000001
+  #define RCC_APB1ENR_TIM3EN       0x00000002
+  #define RCC_APB1ENR_TIM4EN       0x00000004
+  #define RCC_APB1ENR_TIM5EN       0x00000008
+  #define RCC_APB1ENR_TIM6EN       0x00000010
+  #define RCC_APB1ENR_TIM7EN       0x00000020
+  #define RCC_APB1ENR_TIM12EN      0x00000040
+  #define RCC_APB1ENR_TIM13EN      0x00000080
+  #define RCC_APB1ENR_TIM14EN      0x00000100
+#ifdef TOPPERS_STM32F723_DISCOVERY
+  #define RCC_APB1ENR_LPTIM1EN     0x00000200
+  #define RCC_APB1ENR_RTCEN        0x00000400
+#endif
+  #define RCC_APB1ENR_WWDGEN       0x00000800
+  #define RCC_APB1ENR_SPI2EN       0x00004000
+  #define RCC_APB1ENR_SPI3EN       0x00008000
+  #define RCC_APB1ENR_USART2EN     0x00020000
+  #define RCC_APB1ENR_USART3EN     0x00040000
+  #define RCC_APB1ENR_UART4EN      0x00080000
+  #define RCC_APB1ENR_UART5EN      0x00100000
+  #define RCC_APB1ENR_I2C1EN       0x00200000
+  #define RCC_APB1ENR_I2C2EN       0x00400000
+  #define RCC_APB1ENR_I2C3EN       0x00800000
+  #define RCC_APB1ENR_I2C4EN       0x01000000
+  #define RCC_APB1ENR_CAN1EN       0x02000000
+  #define RCC_APB1ENR_CECEN        0x08000000
+  #define RCC_APB1ENR_CAN2EN       0x04000000
+  #define RCC_APB1ENR_PWREN        0x10000000
+  #define RCC_APB1ENR_DACEN        0x20000000
+  #define RCC_APB1ENR_UART7EN      0x40000000
+  #define RCC_APB1ENR_UART8EN      0x80000000
+#define TOFF_RCC_APB2ENR    0x0044		/* (RW) RCC APB2 peripheral clock enable register */
+  #define RCC_APB2ENR_TIM1EN       0x00000001
+  #define RCC_APB2ENR_TIM8EN       0x00000002
+  #define RCC_APB2ENR_USART1EN     0x00000010
+  #define RCC_APB2ENR_USART6EN     0x00000020
+#if defined(TOPPERS_STM32F769_DISCOVERY) || defined(TOPPERS_STM32F767_NUCLEO144) || defined(TOPPERS_STM32F723_DISCOVERY)
+  #define RCC_APB2ENR_SDMMC2EN     0x00000080
+#endif
+  #define RCC_APB2ENR_ADC1EN       0x00000100
+  #define RCC_APB2ENR_ADC2EN       0x00000200
+  #define RCC_APB2ENR_ADC3EN       0x00000400
+  #define RCC_APB2ENR_SDIOEN       0x00000800
+  #define RCC_APB2ENR_SDMMC1EN     0x00000800
+  #define RCC_APB2ENR_SPI1EN       0x00001000
+#ifdef TOPPERS_STM32F723_DISCOVERY
+  #define RCC_APB2ENR_SPI4EN       0x00002000
+#endif
+  #define RCC_APB2ENR_SYSCFGEN     0x00004000
+  #define RCC_APB2ENR_TIM11EN      0x00040000
+  #define RCC_APB2ENR_TIM10EN      0x00020000
+  #define RCC_APB2ENR_TIM9EN       0x00010000
+  #define RCC_APB2ENR_TIM10EN      0x00020000
+  #define RCC_APB2ENR_TIM11EN      0x00040000
+  #define RCC_APB2ENR_SPI5EN       0x00100000
+  #define RCC_APB2ENR_SPI6EN       0x00200000
+  #define RCC_APB2ENR_SAI1EN       0x00400000
+  #define RCC_APB2ENR_SAI2EN       0x00800000
+  #define RCC_APB2ENR_LTDCEN       0x04000000
+#if defined(TOPPERS_STM32F769_DISCOVERY)
+  #define RCC_APB2ENR_DSIEN        0x08000000
+#endif
+#if defined(TOPPERS_STM32F769_DISCOVERY) || defined(TOPPERS_STM32F767_NUCLEO144)
+  #define RCC_APB2ENR_DFSDM1EN     0x20000000
+  #define RCC_APB2ENR_MDIOEN       0x40000000
+#endif
+#define TOFF_RCC_AHB1LPENR  0x0050		/* (RW) RCC AHB1 peripheral clock enable in low power mode register */
+  #define RCC_AHB1LPENR_GPIOALPEN     0x00000001
+  #define RCC_AHB1LPENR_GPIOBLPEN     0x00000002
+  #define RCC_AHB1LPENR_GPIOCLPEN     0x00000004
+  #define RCC_AHB1LPENR_GPIODLPEN     0x00000008
+  #define RCC_AHB1LPENR_GPIOELPEN     0x00000010
+  #define RCC_AHB1LPENR_GPIOFLPEN     0x00000020
+  #define RCC_AHB1LPENR_GPIOGLPEN     0x00000040
+  #define RCC_AHB1LPENR_GPIOHLPEN     0x00000080
+  #define RCC_AHB1LPENR_GPIOILPEN     0x00000100
+  #define RCC_AHB1LPENR_CRCLPEN       0x00001000
+#ifdef TOPPERS_STM32F723_DISCOVERY
+  #define RCC_AHB1LPENR_AXILPEN       0x00002000
+#endif
+  #define RCC_AHB1LPENR_FLITFLPEN     0x00008000
+  #define RCC_AHB1LPENR_SRAM1LPEN     0x00010000
+  #define RCC_AHB1LPENR_SRAM2LPEN     0x00020000
+  #define RCC_AHB1LPENR_BKPSRAMLPEN   0x00040000
+#ifdef TOPPERS_STM32F723_DISCOVERY
+  #define RCC_AHB1LPENR_DTCMLPEN      0x00100000
+#endif
+  #define RCC_AHB1LPENR_DMA1LPEN      0x00200000
+  #define RCC_AHB1LPENR_DMA2LPEN      0x00400000
+  #define RCC_AHB1LPENR_ETHMACLPEN    0x02000000
+  #define RCC_AHB1LPENR_ETHMACTXLPEN  0x04000000
+  #define RCC_AHB1LPENR_ETHMACRXLPEN  0x08000000
+  #define RCC_AHB1LPENR_ETHMACPTPLPEN 0x10000000
+  #define RCC_AHB1LPENR_OTGHSLPEN     0x20000000
+  #define RCC_AHB1LPENR_OTGHSULPILPEN 0x40000000
+#define TOFF_RCC_AHB2LPENR  0x0054		/* (RW) RCC AHB2 peripheral clock enable in low power mode register */
+  #define RCC_AHB2LPENR_DCMILPEN   0x00000001
+  #define RCC_AHB2LPENR_CRYPLPEN   0x00000010
+  #define RCC_AHB2LPENR_HASHLPEN   0x00000020
+  #define RCC_AHB2LPENR_RNGLPEN    0x00000040
+  #define RCC_AHB2LPENR_OTGFSLPEN  0x00000080
+#define TOFF_RCC_AHB3LPENR  0x0058		/* (RW) RCC AHB3 peripheral clock enable in low power mode register */
+  #define RCC_AHB3LPENR_FSMCLPEN   0x00000001
+  #define RCC_AHB3LPENR_FMCLPEN    RCC_AHB3LPENR_FSMCLPEN
+  #define RCC_AHB3LPENR_QSPILPEN   0x00000002
+#define TOFF_RCC_APB1LPENR  0x0060		/* (RW) RCC APB1 peripheral clock enable in low power mode register */
+  #define RCC_APB1LPENR_TIM2LPEN   0x00000001
+  #define RCC_APB1LPENR_TIM3LPEN   0x00000002
+  #define RCC_APB1LPENR_TIM4LPEN   0x00000004
+  #define RCC_APB1LPENR_TIM5LPEN   0x00000008
+  #define RCC_APB1LPENR_TIM6LPEN   0x00000010
+  #define RCC_APB1LPENR_TIM7LPEN   0x00000020
+  #define RCC_APB1LPENR_TIM12LPEN  0x00000040
+  #define RCC_APB1LPENR_TIM13LPEN  0x00000080
+  #define RCC_APB1LPENR_TIM14LPEN  0x00000100
+#ifdef TOPPERS_STM32F723_DISCOVERY
+  #define RCC_APB1LPENR_LPTIM1LPEN 0x00000200
+  #define RCC_APB1LPENR_RTCLPEN    0x00000400
+#endif
+  #define RCC_APB1LPENR_WWDGLPEN   0x00000800
+  #define RCC_APB1LPENR_SPI2LPEN   0x00004000
+  #define RCC_APB1LPENR_SPI3LPEN   0x00008000
+  #define RCC_APB1LPENR_USART2LPEN 0x00020000
+  #define RCC_APB1LPENR_USART3LPEN 0x00040000
+  #define RCC_APB1LPENR_UART4LPEN  0x00080000
+  #define RCC_APB1LPENR_UART5LPEN  0x00100000
+  #define RCC_APB1LPENR_I2C1LPEN   0x00200000
+  #define RCC_APB1LPENR_I2C2LPEN   0x00400000
+  #define RCC_APB1LPENR_I2C3LPEN   0x00800000
+  #define RCC_APB1LPENR_CAN1LPEN   0x02000000
+  #define RCC_APB1LPENR_CAN2LPEN   0x04000000
+  #define RCC_APB1LPENR_PWRLPEN    0x10000000
+  #define RCC_APB1LPENR_DACLPEN    0x20000000
+  #define RCC_APB1LPENR_UART7LPEN  0x40000000
+  #define RCC_APB1LPENR_UART8LPEN  0x80000000
+#define TOFF_RCC_APB2LPENR  0x0064		/* (RW) RCC APB2 peripheral clock enable in low power mode register */
+  #define RCC_APB2LPENR_TIM1LPEN   0x00000001
+  #define RCC_APB2LPENR_TIM8LPEN   0x00000002
+  #define RCC_APB2LPENR_USART1LPEN 0x00000010
+  #define RCC_APB2LPENR_USART6LPEN 0x00000020
+#ifdef TOPPERS_STM32F723_DISCOVERY
+  #define RCC_APB2LPENR_SDMMC2LPEN 0x00000080
+#endif
+  #define RCC_APB2LPENR_ADC1LPEN   0x00000100
+  #define RCC_APB2LPENR_ADC2LPEN   0x00000200
+  #define RCC_APB2LPENR_ADC3LPEN   0x00000400
+  #define RCC_APB2LPENR_SDIOLPEN   0x00000800
+  #define RCC_APB2LPENR_SDMMC1LPEN RCC_APB2LPENR_SDIOLPEN
+  #define RCC_APB2LPENR_SPI1LPEN   0x00001000
+#ifdef TOPPERS_STM32F723_DISCOVERY
+  #define RCC_APB2LPENR_SPI4LPEN   0x00002000
+#endif
+  #define RCC_APB2LPENR_SYSCFGLPEN 0x00004000
+  #define RCC_APB2LPENR_TIM9LPEN   0x00010000
+  #define RCC_APB2LPENR_TIM10LPEN  0x00020000
+  #define RCC_APB2LPENR_TIM11LPEN  0x00040000
+  #define RCC_APB2LPENR_SPI5LPEN   0x00100000
+  #define RCC_APB2LPENR_SPI6LPEN   0x00200000
+  #define RCC_APB2LPENR_SAI1LPEN   0x00400000
+  #define RCC_APB2LPENR_SAI2LPEN   0x00800000
+#ifndef TOPPERS_STM32F723_DISCOVERY
+  #define RCC_APB2LPENR_LTDCLPEN   0x04000000
+#else
+  #define RCC_APB2ENR_OTGPHYCEN    0x80000000
+#endif
+#define TOFF_RCC_BDCR       0x0070		/* (RW) RCC Backup domain control register */
+  #define RCC_BDCR_LSEON           0x00000001
+  #define RCC_BDCR_LSERDY          0x00000002
+  #define RCC_BDCR_LSEBYP          0x00000004
+#ifdef TOPPERS_STM32F723_DISCOVERY
+  #define RCC_BDCR_LSEDRV          0x00000018
+  #define RCC_BDCR_LSEDRV_0        0x00000008
+  #define RCC_BDCR_LSEDRV_1        0x00000010
+#endif
+  #define RCC_BDCR_RTCSEL          0x00000300
+  #define RCC_BDCR_RTCSEL_0        0x00000100
+  #define RCC_BDCR_RTCSEL_1        0x00000200
+  #define RCC_BDCR_RTCEN           0x00008000
+  #define RCC_BDCR_BDRST           0x00010000
+#define TOFF_RCC_CSR        0x0074		/* (RW) RCC clock control & status register */
+  #define RCC_CSR_LSION            0x00000001
+  #define RCC_CSR_LSIRDY           0x00000002
+  #define RCC_CSR_RMVF             0x01000000
+  #define RCC_CSR_BORRSTF          0x02000000
+  #define RCC_CSR_PADRSTF          0x04000000
+  #define RCC_CSR_PINRSTF          RCC_CSR_PADRSTF
+  #define RCC_CSR_PORRSTF          0x08000000
+  #define RCC_CSR_SFTRSTF          0x10000000
+  #define RCC_CSR_WDGRSTF          0x20000000
+  #define RCC_CSR_IWDGRSTF         RCC_CSR_WDGRSTF
+  #define RCC_CSR_WWDGRSTF         0x40000000
+  #define RCC_CSR_LPWRRSTF         0x80000000
+#define TOFF_RCC_SSCGR      0x0080		/* (RW) RCC spread spectrum clock generation register */
+  #define RCC_SSCGR_MODPER         0x00001FFF
+  #define RCC_SSCGR_INCSTEP        0x0FFFE000
+  #define RCC_SSCGR_SPREADSEL      0x40000000
+  #define RCC_SSCGR_SSCGEN         0x80000000
+#define TOFF_RCC_PLLI2SCFGR 0x0084		/* (RW) RCC PLLI2S configuration register */
+  #define RCC_PLLI2SCFGR_PLLI2SN   0x00007FC0
+  #define RCC_PLLI2SCFGR_PLLI2SP   0x00030000
+  #define RCC_PLLI2SCFGR_PLLI2SQ   0x0F000000
+  #define RCC_PLLI2SCFGR_PLLI2SR   0x70000000
+#define TOFF_RCC_PLLSAICFGR 0x0088		/* (RW) RCC PLLSAI configuration register */
+  #define RCC_PLLSAICFGR_PLLSAIN   0x00007FC0
+  #define RCC_PLLSAICFGR_PLLSAIP   0x00030000
+  #define RCC_PLLSAICFGR_PLLSAIQ   0x0F000000
+  #define RCC_PLLSAICFGR_PLLSAIR   0x70000000
+#define TOFF_RCC_DCKCFGR1   0x008C		/* (RW) RCC Dedicated Clocks configuration register1 */
+  #define RCC_DCKCFGR1_PLLI2SDIVQ  0x0000001F
+  #define RCC_DCKCFGR1_PLLSAIDIVQ  0x00001F00
+  #define RCC_DCKCFGR1_PLLSAIDIVR  0x00030000
+  #define RCC_DCKCFGR1_PLLSAIDIVR_0 0x00010000
+  #define RCC_DCKCFGR1_PLLSAIDIVR_1 0x00020000
+  #define RCC_DCKCFGR1_SAI1SEL     0x00300000
+  #define RCC_DCKCFGR1_SAI1SEL_0   0x00100000
+  #define RCC_DCKCFGR1_SAI1SEL_1   0x00200000
+  #define RCC_DCKCFGR1_SAI2SEL     0x00C00000
+  #define RCC_DCKCFGR1_SAI2SEL_0   0x00400000
+  #define RCC_DCKCFGR1_SAI2SEL_1   0x00800000
+  #define RCC_DCKCFGR1_TIMPRE      0x01000000
+#if defined(TOPPERS_STM32F769_DISCOVERY) || defined(TOPPERS_STM32F767_NUCLEO144)
+  #define RCC_DCKCFGR1_DFSDM1SEL   0x02000000
+  #define RCC_DCKCFGR1_ADFSDM1SEL  0x04000000
+#endif
+#define TOFF_RCC_DCKCFGR2   0x0090		/* (RW) RCC Dedicated Clocks configuration register2 */
+  #define RCC_DCKCFGR2_USART1SEL   0x00000003
+  #define RCC_DCKCFGR2_USART1SEL_0 0x00000001
+  #define RCC_DCKCFGR2_USART1SEL_1 0x00000002
+  #define RCC_DCKCFGR2_USART2SEL   0x0000000C
+  #define RCC_DCKCFGR2_USART3SEL   0x00000030
+  #define RCC_DCKCFGR2_UART4SEL    0x000000C0
+  #define RCC_DCKCFGR2_UART5SEL    0x00000300
+  #define RCC_DCKCFGR2_USART6SEL   0x00000C00
+  #define RCC_DCKCFGR2_USART6SEL_0 0x00000400
+  #define RCC_DCKCFGR2_USART6SEL_1 0x00000800
+  #define RCC_DCKCFGR2_UART7SEL    0x00003000
+  #define RCC_DCKCFGR2_UART8SEL    0x0000C000
+  #define RCC_DCKCFGR2_I2C1SEL     0x00030000
+  #define RCC_DCKCFGR2_I2C2SEL     0x000C0000
+  #define RCC_DCKCFGR2_I2C3SEL     0x00300000
+  #define RCC_DCKCFGR2_I2C4SEL     0x00C00000
+  #define RCC_DCKCFGR2_LPTIM1SEL   0x03000000
+  #define RCC_DCKCFGR2_CECSEL      0x04000000
+  #define RCC_DCKCFGR2_CK48MSEL    0x08000000
+  #define RCC_DCKCFGR2_SDMMC1SEL   0x10000000
+#if defined(TOPPERS_STM32F769_DISCOVERY) || defined(TOPPERS_STM32F767_NUCLEO144)
+  #define RCC_DCKCFGR2_SDMMC2SEL   0x20000000
+  #define RCC_DCKCFGR2_DSISEL      0x40000000
+#elif defined(TOPPERS_STM32F723_DISCOVERY)
+  #define RCC_DCKCFGR2_SDMMC2SEL   0x20000000
+#endif
+
+/*
+ *  FLASH REGISTERS
+ */
+#define TADR_FLASH_R_BASE   (AHB1PERIPH_BASE + 0x3C00)
+#define TOFF_FLASH_ACR      0x0000		/* (RW) FLASH access control register */
+  #define FLASH_ACR_LATENCY        0x0000000F
+  #define FLASH_ACR_LATENCY_0WS    0x00000000
+  #define FLASH_ACR_LATENCY_1WS    0x00000001
+  #define FLASH_ACR_LATENCY_2WS    0x00000002
+  #define FLASH_ACR_LATENCY_3WS    0x00000003
+  #define FLASH_ACR_LATENCY_4WS    0x00000004
+  #define FLASH_ACR_LATENCY_5WS    0x00000005
+  #define FLASH_ACR_LATENCY_6WS    0x00000006
+  #define FLASH_ACR_LATENCY_7WS    0x00000007
+  #define FLASH_ACR_LATENCY_8WS    0x00000008
+  #define FLASH_ACR_LATENCY_9WS    0x00000009
+  #define FLASH_ACR_LATENCY_10WS   0x0000000A
+  #define FLASH_ACR_LATENCY_11WS   0x0000000B
+  #define FLASH_ACR_LATENCY_12WS   0x0000000C
+  #define FLASH_ACR_LATENCY_13WS   0x0000000D
+  #define FLASH_ACR_LATENCY_14WS   0x0000000E
+  #define FLASH_ACR_LATENCY_15WS   0x0000000F
+  #define FLASH_ACR_PRFTEN         0x00000100
+  #define FLASH_ACR_ARTEN          0x00000200
+  #define FLASH_ACR_ARTRST         0x00000800
+#define TOFF_FLASH_KEYR     0x0004		/* (RW) FLASH key register */
+#define TOFF_FLASH_OPTKEYR  0x0008		/* (RW) FLASH option key register */
+#define TOFF_FLASH_SR       0x000C		/* (RW) FLASH status register */
+  #define FLASH_SR_EOP             0x00000001
+  #define FLASH_SR_SOP             0x00000002
+  #define FLASH_SR_WRPERR          0x00000010
+  #define FLASH_SR_PGAERR          0x00000020
+  #define FLASH_SR_PGPERR          0x00000040
+  #define FLASH_SR_PGSERR          0x00000080
+  #define FLASH_SR_BSY             0x00010000
+#define TOFF_FLASH_CR       0x0010		/* (RW) FLASH control register */
+  #define FLASH_CR_PG              0x00000001
+  #define FLASH_CR_SER             0x00000002
+  #define FLASH_CR_MER             0x00000004
+  #define FLASH_CR_SNB_0           0x00000008
+  #define FLASH_CR_SNB_1           0x00000010
+  #define FLASH_CR_SNB_2           0x00000020
+  #define FLASH_CR_SNB_3           0x00000040
+  #define FLASH_CR_PSIZE_0         0x00000100
+  #define FLASH_CR_PSIZE_1         0x00000200
+  #define FLASH_CR_STRT            0x00010000
+  #define FLASH_CR_EOPIE           0x01000000
+  #define FLASH_CR_LOCK            0x80000000
+#define TOFF_FLASH_OPTCR    0x0014		/* (RW) FLASH option control register */
+  #define FLASH_OPTCR_OPTLOCK      0x00000001
+  #define FLASH_OPTCR_OPTSTRT      0x00000002
+  #define FLASH_OPTCR_BOR_LEV_0    0x00000004
+  #define FLASH_OPTCR_BOR_LEV_1    0x00000008
+  #define FLASH_OPTCR_BOR_LEV      0x0000000C
+  #define FLASH_OPTCR_WDG_SW       0x00000020
+  #define FLASH_OPTCR_nRST_STOP    0x00000040
+  #define FLASH_OPTCR_nRST_STDBY   0x00000080
+  #define FLASH_OPTCR_RDP_0        0x00000100
+  #define FLASH_OPTCR_RDP_1        0x00000200
+  #define FLASH_OPTCR_RDP_2        0x00000400
+  #define FLASH_OPTCR_RDP_3        0x00000800
+  #define FLASH_OPTCR_RDP_4        0x00001000
+  #define FLASH_OPTCR_RDP_5        0x00002000
+  #define FLASH_OPTCR_RDP_6        0x00004000
+  #define FLASH_OPTCR_RDP_7        0x00008000
+  #define FLASH_OPTCR_nWRP_0       0x00010000
+  #define FLASH_OPTCR_nWRP_1       0x00020000
+  #define FLASH_OPTCR_nWRP_2       0x00040000
+  #define FLASH_OPTCR_nWRP_3       0x00080000
+  #define FLASH_OPTCR_nWRP_4       0x00100000
+  #define FLASH_OPTCR_nWRP_5       0x00200000
+  #define FLASH_OPTCR_nWRP_6       0x00400000
+  #define FLASH_OPTCR_nWRP_7       0x00800000
+  #define FLASH_OPTCR_IWDG_STDBY   0x40000000
+  #define FLASH_OPTCR_IWDG_STOP    0x80000000
+#define TOFF_FLASH_OPTCR1   0x0018		/* (RW) FLASH option control register 1 */
+
+/* 
+ *  DMA CONTROLLER
+ */
+#define TADR_DMA1_BASE      (AHB1PERIPH_BASE + 0x6000)
+#define TADR_DMA2_BASE      (AHB1PERIPH_BASE + 0x6400)
+#define TOFF_DMAI_LISR      0x0000		/* (RW) DMA low interrupt status register */
+  #define DMA_LISR_TCIF3           0x08000000
+  #define DMA_LISR_HTIF3           0x04000000
+  #define DMA_LISR_TEIF3           0x02000000
+  #define DMA_LISR_DMEIF3          0x01000000
+  #define DMA_LISR_FEIF3           0x00400000
+  #define DMA_LISR_TCIF2           0x00200000
+  #define DMA_LISR_HTIF2           0x00100000
+  #define DMA_LISR_TEIF2           0x00080000
+  #define DMA_LISR_DMEIF2          0x00040000
+  #define DMA_LISR_FEIF2           0x00010000
+  #define DMA_LISR_TCIF1           0x00000800
+  #define DMA_LISR_HTIF1           0x00000400
+  #define DMA_LISR_TEIF1           0x00000200
+  #define DMA_LISR_DMEIF1          0x00000100
+  #define DMA_LISR_FEIF1           0x00000040
+  #define DMA_LISR_TCIF0           0x00000020
+  #define DMA_LISR_HTIF0           0x00000010
+  #define DMA_LISR_TEIF0           0x00000008
+  #define DMA_LISR_DMEIF0          0x00000004
+  #define DMA_LISR_FEIF0           0x00000001
+#define TOFF_DMAI_HISR      0x0004		/* (RW) DMA high interrupt status register */
+  #define DMA_HISR_TCIF7           0x08000000
+  #define DMA_HISR_HTIF7           0x04000000
+  #define DMA_HISR_TEIF7           0x02000000
+  #define DMA_HISR_DMEIF7          0x01000000
+  #define DMA_HISR_FEIF7           0x00400000
+  #define DMA_HISR_TCIF6           0x00200000
+  #define DMA_HISR_HTIF6           0x00100000
+  #define DMA_HISR_TEIF6           0x00080000
+  #define DMA_HISR_DMEIF6          0x00040000
+  #define DMA_HISR_FEIF6           0x00010000
+  #define DMA_HISR_TCIF5           0x00000800
+  #define DMA_HISR_HTIF5           0x00000400
+  #define DMA_HISR_TEIF5           0x00000200
+  #define DMA_HISR_DMEIF5          0x00000100
+  #define DMA_HISR_FEIF5           0x00000040
+  #define DMA_HISR_TCIF4           0x00000020
+  #define DMA_HISR_HTIF4           0x00000010
+  #define DMA_HISR_TEIF4           0x00000008
+  #define DMA_HISR_DMEIF4          0x00000004
+  #define DMA_HISR_FEIF4           0x00000001
+#define TOFF_DMAI_LIFCR     0x0008		/* (RW) DMA low interrupt flag clear register */
+  #define DMA_LIFCR_CTCIF3         0x08000000
+  #define DMA_LIFCR_CHTIF3         0x04000000
+  #define DMA_LIFCR_CTEIF3         0x02000000
+  #define DMA_LIFCR_CDMEIF3        0x01000000
+  #define DMA_LIFCR_CFEIF3         0x00400000
+  #define DMA_LIFCR_CTCIF2         0x00200000
+  #define DMA_LIFCR_CHTIF2         0x00100000
+  #define DMA_LIFCR_CTEIF2         0x00080000
+  #define DMA_LIFCR_CDMEIF2        0x00040000
+  #define DMA_LIFCR_CFEIF2         0x00010000
+  #define DMA_LIFCR_CTCIF1         0x00000800
+  #define DMA_LIFCR_CHTIF1         0x00000400
+  #define DMA_LIFCR_CTEIF1         0x00000200
+  #define DMA_LIFCR_CDMEIF1        0x00000100
+  #define DMA_LIFCR_CFEIF1         0x00000040
+  #define DMA_LIFCR_CTCIF0         0x00000020
+  #define DMA_LIFCR_CHTIF0         0x00000010
+  #define DMA_LIFCR_CTEIF0         0x00000008
+  #define DMA_LIFCR_CDMEIF0        0x00000004
+  #define DMA_LIFCR_CFEIF0         0x00000001
+#define TOFF_DMAI_HIFCR     0x000C		/* (RW) DMA high interrupt flag clear register */
+  #define DMA_HIFCR_CTCIF7         0x08000000
+  #define DMA_HIFCR_CHTIF7         0x04000000
+  #define DMA_HIFCR_CTEIF7         0x02000000
+  #define DMA_HIFCR_CDMEIF7        0x01000000
+  #define DMA_HIFCR_CFEIF7         0x00400000
+  #define DMA_HIFCR_CTCIF6         0x00200000
+  #define DMA_HIFCR_CHTIF6         0x00100000
+  #define DMA_HIFCR_CTEIF6         0x00080000
+  #define DMA_HIFCR_CDMEIF6        0x00040000
+  #define DMA_HIFCR_CFEIF6         0x00010000
+  #define DMA_HIFCR_CTCIF5         0x00000800
+  #define DMA_HIFCR_CHTIF5         0x00000400
+  #define DMA_HIFCR_CTEIF5         0x00000200
+  #define DMA_HIFCR_CDMEIF5        0x00000100
+  #define DMA_HIFCR_CFEIF5         0x00000040
+  #define DMA_HIFCR_CTCIF4         0x00000020
+  #define DMA_HIFCR_CHTIF4         0x00000010
+  #define DMA_HIFCR_CTEIF4         0x00000008
+  #define DMA_HIFCR_CDMEIF4        0x00000004
+  #define DMA_HIFCR_CFEIF4         0x00000001
+
+#define TADR_DMA1_STM0_BASE (TADR_DMA1_BASE + 0x010)
+#define TADR_DMA1_STM1_BASE (TADR_DMA1_BASE + 0x028)
+#define TADR_DMA1_STM2_BASE (TADR_DMA1_BASE + 0x040)
+#define TADR_DMA1_STM3_BASE (TADR_DMA1_BASE + 0x058)
+#define TADR_DMA1_STM4_BASE (TADR_DMA1_BASE + 0x070)
+#define TADR_DMA1_STM5_BASE (TADR_DMA1_BASE + 0x088)
+#define TADR_DMA1_STM6_BASE (TADR_DMA1_BASE + 0x0A0)
+#define TADR_DMA1_STM7_BASE (TADR_DMA1_BASE + 0x0B8)
+#define TADR_DMA2_STM0_BASE (TADR_DMA2_BASE + 0x010)
+#define TADR_DMA2_STM1_BASE (TADR_DMA2_BASE + 0x028)
+#define TADR_DMA2_STM2_BASE (TADR_DMA2_BASE + 0x040)
+#define TADR_DMA2_STM3_BASE (TADR_DMA2_BASE + 0x058)
+#define TADR_DMA2_STM4_BASE (TADR_DMA2_BASE + 0x070)
+#define TADR_DMA2_STM5_BASE (TADR_DMA2_BASE + 0x088)
+#define TADR_DMA2_STM6_BASE (TADR_DMA2_BASE + 0x0A0)
+#define TADR_DMA2_STM7_BASE (TADR_DMA2_BASE + 0x0B8)
+#define TOFF_DMAS_CR        0x0000		/* (RW) DMA stream x configuration register      */
+  #define DMA_SxCR_CHSEL           0x0E000000
+  #define DMA_SxCR_CHSEL_0         0x02000000
+  #define DMA_SxCR_CHSEL_1         0x04000000
+  #define DMA_SxCR_CHSEL_2         0x08000000
+  #define DMA_SxCR_MBURST          0x01800000
+  #define DMA_SxCR_MBURST_0        0x00800000
+  #define DMA_SxCR_MBURST_1        0x01000000
+  #define DMA_SxCR_PBURST          0x00600000
+  #define DMA_SxCR_PBURST_0        0x00200000
+  #define DMA_SxCR_PBURST_1        0x00400000
+  #define DMA_SxCR_ACK             0x00100000
+  #define DMA_SxCR_CT              0x00080000
+  #define DMA_SxCR_DBM             0x00040000
+  #define DMA_SxCR_PL              0x00030000
+  #define DMA_SxCR_PL_0            0x00010000
+  #define DMA_SxCR_PL_1            0x00020000
+  #define DMA_SxCR_PINCOS          0x00008000
+  #define DMA_SxCR_MSIZE           0x00006000
+  #define DMA_SxCR_MSIZE_0         0x00002000
+  #define DMA_SxCR_MSIZE_1         0x00004000
+  #define DMA_SxCR_PSIZE           0x00001800
+  #define DMA_SxCR_PSIZE_0         0x00000800
+  #define DMA_SxCR_PSIZE_1         0x00001000
+  #define DMA_SxCR_MINC            0x00000400
+  #define DMA_SxCR_PINC            0x00000200
+  #define DMA_SxCR_CIRC            0x00000100
+  #define DMA_SxCR_DIR             0x000000C0
+  #define DMA_SxCR_DIR_0           0x00000040
+  #define DMA_SxCR_DIR_1           0x00000080
+  #define DMA_SxCR_PFCTRL          0x00000020
+  #define DMA_SxCR_TCIE            0x00000010
+  #define DMA_SxCR_HTIE            0x00000008
+  #define DMA_SxCR_TEIE            0x00000004
+  #define DMA_SxCR_DMEIE           0x00000002
+  #define DMA_SxCR_EN              0x00000001
+#define TOFF_DMAS_NDTR      0x0004		/* (RW) DMA stream x number of data register     */
+#define TOFF_DMAS_PAR       0x0008		/* (RW) DMA stream x peripheral address register */
+#define TOFF_DMAS_M0AR      0x000C		/* (RW) DMA stream x memory 0 address register   */
+#define TOFF_DMAS_M1AR      0x0010		/* (RW) DMA stream x memory 1 address register   */
+#define TOFF_DMAS_FCR       0x0014		/* (RW) DMA stream x FIFO control register       */
+  #define DMA_SxFCR_FEIE           0x00000080
+  #define DMA_SxFCR_FS             0x00000038
+  #define DMA_SxFCR_FS_0           0x00000008
+  #define DMA_SxFCR_FS_1           0x00000010
+  #define DMA_SxFCR_FS_2           0x00000020
+  #define DMA_SxFCR_DMDIS          0x00000004
+  #define DMA_SxFCR_FTH            0x00000003
+  #define DMA_SxFCR_FTH_0          0x00000001
+  #define DMA_SxFCR_FTH_1          0x00000002
+
+/*
+ *  DMA2D CONTROLLER
+ */
+
+#define TADR_DMA2D_BASE     (AHB1PERIPH_BASE + 0xB000)
+#define TOFF_DMA2D_CR       0x0000	/* (RW) DMA2D Control Register */
+  #define DMA2D_CR_START     0x00000001	/* Start transfer */
+  #define DMA2D_CR_SUSP      0x00000002	/* Suspend transfer */
+  #define DMA2D_CR_ABORT     0x00000004	/* Abort transfer */
+  #define DMA2D_CR_TEIE      0x00000100	/* Transfer Error Interrupt Enable */
+  #define DMA2D_CR_TCIE      0x00000200	/* Transfer Complete Interrupt Enable */
+  #define DMA2D_CR_TWIE      0x00000400	/* Transfer Watermark Interrupt Enable */
+  #define DMA2D_CR_CAEIE     0x00000800	/* CLUT Access Error Interrupt Enable */
+  #define DMA2D_CR_CTCIE     0x00001000	/* CLUT Transfer Complete Interrupt Enable */
+  #define DMA2D_CR_CEIE      0x00002000	/* Configuration Error Interrupt Enable */
+  #define DMA2D_CR_MODE      0x00030000	/* DMA2D Mode */
+#define TOFF_DMA2D_ISR      0x0004	/* (RW) DMA2D Interrupt Status Register */
+  #define DMA2D_ISR_TEIF     0x00000001	/* Transfer Error Interrupt Flag */
+  #define DMA2D_ISR_TCIF     0x00000002	/* Transfer Complete Interrupt Flag */
+  #define DMA2D_ISR_TWIF     0x00000004	/* Transfer Watermark Interrupt Flag */
+  #define DMA2D_ISR_CAEIF    0x00000008	/* CLUT Access Error Interrupt Flag */
+  #define DMA2D_ISR_CTCIF    0x00000010	/* CLUT Transfer Complete Interrupt Flag */
+  #define DMA2D_ISR_CEIF     0x00000020	/* Configuration Error Interrupt Flag */
+#define TOFF_DMA2D_IFCR     0x0008	/* (RW) DMA2D Interrupt Flag Clear Register */
+  #define DMA2D_IFSR_CTEIF   0x00000001	/* Clears Transfer Error Interrupt Flag */
+  #define DMA2D_IFSR_CTCIF   0x00000002	/* Clears Transfer Complete Interrupt Flag */
+  #define DMA2D_IFSR_CTWIF   0x00000004	/* Clears Transfer Watermark Interrupt Flag */
+  #define DMA2D_IFSR_CCAEIF  0x00000008	/* Clears CLUT Access Error Interrupt Flag */
+  #define DMA2D_IFSR_CCTCIF  0x00000010	/* Clears CLUT Transfer Complete Interrupt Flag */
+  #define DMA2D_IFSR_CCEIF   0x00000020	/* Clears Configuration Error Interrupt Flag */
+#define TOFF_DMA2D_FGMAR    0x000C	/* (RW) DMA2D Foreground Memory Address Register */
+#define TOFF_DMA2D_FGOR     0x0010	/* (RW) DMA2D Foreground Offset Register */
+  #define DMA2D_FGOR_LO      0x00003FFF	/* Line Offset */
+#define TOFF_DMA2D_BGMAR    0x0014	/* (RW) DMA2D Background Memory Address Register */
+  #define DMA2D_BGMAR_MA     0xFFFFFFFF	/* Memory Address */
+#define TOFF_DMA2D_BGOR     0x0018	/* (RW) DMA2D Background Offset Register */
+  #define DMA2D_BGOR_LO      0x00003FFF	/* Line Offset */
+#define TOFF_DMA2D_FGPFCCR  0x001C	/* (RW) DMA2D Foreground PFC Control Register */
+  #define DMA2D_FGPFCCR_CM    0x0000000F	/* Color mode */
+  #define DMA2D_FGPFCCR_CCM   0x00000010	/* CLUT Color mode */
+  #define DMA2D_FGPFCCR_START 0x00000020	/* Start */
+  #define DMA2D_FGPFCCR_CS    0x0000FF00	/* CLUT size */
+  #define DMA2D_FGPFCCR_AM    0x00030000	/* Alpha mode */
+  #define DMA2D_FGPFCCR_ALPHA 0xFF000000	/* Alpha value */
+#define TOFF_DMA2D_FGCOLR   0x0020	/* (RW) DMA2D Foreground Color Register */
+  #define DMA2D_FGCOLR_BLUE  0x000000FF	/* Blue Value  */
+  #define DMA2D_FGCOLR_GREEN 0x0000FF00	/* Green Value */
+  #define DMA2D_FGCOLR_RED   0x00FF0000	/* Red Value */
+#define TOFF_DMA2D_BGPFCCR  0x0024	/* (RW) DMA2D Background PFC Control Register */
+  #define DMA2D_BGPFCCR_CM    0x0000000F	/* Color mode */
+  #define DMA2D_BGPFCCR_CCM   0x00000010	/* CLUT Color mode */
+  #define DMA2D_BGPFCCR_START 0x00000020	/* Start */
+  #define DMA2D_BGPFCCR_CS    0x0000FF00	/* CLUT size */
+  #define DMA2D_BGPFCCR_AM    0x00030000	/* Alpha Mode */
+  #define DMA2D_BGPFCCR_ALPHA 0xFF000000	/* Alpha value */
+#define TOFF_DMA2D_BGCOLR   0x0028	/* (RW) DMA2D Background Color Register */
+  #define DMA2D_BGCOLR_BLUE   0x000000FF	/* Blue Value  */
+  #define DMA2D_BGCOLR_GREEN  0x0000FF00	/* Green Value */
+  #define DMA2D_BGCOLR_RED    0x00FF0000	/* Red Value   */
+#define TOFF_DMA2D_FGCMAR   0x002C	/* (RW) DMA2D Foreground CLUT Memory Address Register */
+#define TOFF_DMA2D_BGCMAR   0x0030	/* (RW) DMA2D Background CLUT Memory Address Register */
+#define TOFF_DMA2D_OPFCCR   0x0034	/* (RW) DMA2D Output PFC Control Register */
+  #define DMA2D_OPFCCR_CM    0x00000007	/* Color mode */
+#if defined(TOPPERS_STM32F769_DISCOVERY) || defined(TOPPERS_STM32F767_NUCLEO144)
+  #define DMA2D_OPFCCR_AI    0x00100000	/* Output Alpha Inverted */
+  #define DMA2D_OPFCCR_RBS   0x00200000	/* Output Red Blue Swap */
+#endif
+#define TOFF_DMA2D_OCOLR    0x0038	/* (RW) DMA2D Output Color Register */
+  /* Mode_ARGB8888/RGB888 */
+  #define DMA2D_OCOLR_BLUE_1  0x000000FF	/* BLUE Value          */
+  #define DMA2D_OCOLR_GREEN_1 0x0000FF00	/* GREEN Value         */
+  #define DMA2D_OCOLR_RED_1   0x00FF0000	/* Red Value           */
+  #define DMA2D_OCOLR_ALPHA_1 0xFF000000	/* Alpha Channel Value */
+  /* Mode_RGB565 */
+  #define DMA2D_OCOLR_BLUE_2  0x0000001F	/* BLUE Value   */
+  #define DMA2D_OCOLR_GREEN_2 0x000007E0	/* GREEN Value  */
+  #define DMA2D_OCOLR_RED_2   0x0000F800	/* Red Value    */
+  /* Mode_ARGB1555 */
+  #define DMA2D_OCOLR_BLUE_3  0x0000001F	/* BLUE Value          */
+  #define DMA2D_OCOLR_GREEN_3 0x000003E0	/* GREEN Value         */
+  #define DMA2D_OCOLR_RED_3   0x00007C00	/* Red Value           */
+  #define DMA2D_OCOLR_ALPHA_3 0x00008000	/* Alpha Channel Value */
+  /* Mode_ARGB4444 */
+  #define DMA2D_OCOLR_BLUE_4  0x0000000F	/* BLUE Value          */
+  #define DMA2D_OCOLR_GREEN_4 0x000000F0	/* GREEN Value         */
+  #define DMA2D_OCOLR_RED_4   0x00000F00	/* Red Value           */
+  #define DMA2D_OCOLR_ALPHA_4 0x0000F000	/* Alpha Channel Value */
+#define TOFF_DMA2D_OMAR     0x003C	/* (RW) DMA2D Output Memory Address Register */
+  #define DMA2D_OMAR_MA      0xFFFFFFFF	/* Memory Address */
+#define TOFF_DMA2D_OOR      0x0040	/* (RW) DMA2D Output Offset Register */
+  #define DMA2D_OOR_LO       0x00003FFF	/* Line Offset */
+#define TOFF_DMA2D_NLR      0x0044	/* (RW) DMA2D Number of Line Register */
+#define TOFF_DMA2D_LWR      0x0048	/* (RW) DMA2D Line Watermark Register */
+#define TOFF_DMA2D_AMTCR    0x004C	/* (RW) DMA2D AHB Master Timer Configuration Register */
+#define TOFF_DMA2D_FGCLUT   0x0400	/* (RW) DMA2D Foreground CLUT 400-7FF */
+#define TOFF_DMA2D_BGCLUT   0x0800	/* (RW) DMA2D Background CLUT 800-BFF */
+
+
+
+#define TADR_ETH_BASE       (AHB1PERIPH_BASE + 0x8000)
+#define ETH_MAC_BASE        (ETH_BASE)
+#define TOFF_ETH_MACCR      0x0000		/* (RW) Ethernet MAC configuration register */
+  #define ETH_MACCR_RE          0x00000004	/* Receiver enable */
+  #define ETH_MACCR_TE          0x00000008	/* Transmitter enable */
+  #define ETH_MACCR_DC          0x00000010	/* Defferal check */
+  #define ETH_MACCR_BL          0x00000060	/* Back-off limit: random integer number (r) of slot time delays before rescheduling
+                                          	    a transmission attempt during retries after a collision: 0 =< r <2^k */
+  #define ETH_MACCR_BL_10       0x00000000	/* k = min (n, 10) */
+  #define ETH_MACCR_BL_8        0x00000020	/* k = min (n, 8) */
+  #define ETH_MACCR_BL_4        0x00000040	/* k = min (n, 4) */
+  #define ETH_MACCR_BL_1        0x00000060	/* k = min (n, 1) */
+  #define ETH_MACCR_APCS        0x00000080	/* Automatic Pad/CRC stripping */
+  #define ETH_MACCR_RD          0x00000200	/* Retry disable */
+  #define ETH_MACCR_IPCO        0x00000400	/* IP Checksum offload */
+  #define ETH_MACCR_DM          0x00000800	/* Duplex mode */
+  #define ETH_MACCR_LM          0x00001000	/* loopback mode */
+  #define ETH_MACCR_ROD         0x00002000	/* Receive own disable */
+  #define ETH_MACCR_FES         0x00004000	/* Fast ethernet speed */
+  #define ETH_MACCR_CSD         0x00010000	/* Carrier sense disable (during transmission) */
+  #define ETH_MACCR_IFG         0x000E0000	/* Inter-frame gap */
+  #define ETH_MACCR_IFG_96Bit   0x00000000	/* Minimum IFG between frames during transmission is 96Bit */
+  #define ETH_MACCR_IFG_88Bit   0x00020000	/* Minimum IFG between frames during transmission is 88Bit */
+  #define ETH_MACCR_IFG_80Bit   0x00040000	/* Minimum IFG between frames during transmission is 80Bit */
+  #define ETH_MACCR_IFG_72Bit   0x00060000	/* Minimum IFG between frames during transmission is 72Bit */
+  #define ETH_MACCR_IFG_64Bit   0x00080000	/* Minimum IFG between frames during transmission is 64Bit */
+  #define ETH_MACCR_IFG_56Bit   0x000A0000	/* Minimum IFG between frames during transmission is 56Bit */
+  #define ETH_MACCR_IFG_48Bit   0x000C0000	/* Minimum IFG between frames during transmission is 48Bit */
+  #define ETH_MACCR_IFG_40Bit   0x000E0000	/* Minimum IFG between frames during transmission is 40Bit */
+  #define ETH_MACCR_JD          0x00400000	/* Jabber disable */
+  #define ETH_MACCR_WD          0x00800000	/* Watchdog disable */
+#define TOFF_ETH_MACFFR     0x0004		/* (RW) Ethernet MAC frame filter register */
+  #define ETH_MACFFR_PM         0x00000001	/* Promiscuous mode */
+  #define ETH_MACFFR_HU         0x00000002	/* Hash unicast */
+  #define ETH_MACFFR_HM         0x00000004	/* Hash multicast */
+  #define ETH_MACFFR_DAIF       0x00000008	/* DA Inverse filtering */
+  #define ETH_MACFFR_PAM        0x00000010	/* Pass all mutlicast */
+  #define ETH_MACFFR_BFD        0x00000020	/* Broadcast frame disable */
+  #define ETH_MACFFR_PCF        0x000000C0	/* Pass control frames: 3 cases */
+  #define ETH_MACFFR_PCF_BlockAll                 0x00000040	/* MAC filters all control frames from reaching the application */
+  #define ETH_MACFFR_PCF_ForwardAll               0x00000080	/* MAC forwards all control frames to application even if they fail the Address Filter */
+  #define ETH_MACFFR_PCF_ForwardPassedAddrFilter  0x000000C0	/* MAC forwards control frames that pass the Address Filter. */
+  #define ETH_MACFFR_SAIF       0x00000100	/* SA inverse filtering */
+  #define ETH_MACFFR_SAF        0x00000200	/* Source address filter enable */
+  #define ETH_MACFFR_HPF        0x00000400	/* Hash or perfect filter */
+  #define ETH_MACFFR_RA         0x80000000	/* Receive all */
+#define TOFF_ETH_MACHTHR    0x0008		/* (RW) Ethernet MAC hash table high register */
+#define TOFF_ETH_MACHTLR    0x000C		/* (RW) Ethernet MAC hash table low register */
+#define TOFF_ETH_MACMIIAR   0x0010		/* (RW) Ethernet MAC MII address register */
+  #define ETH_MACMIIAR_MB       0x00000001	/* MII busy */
+  #define ETH_MACMIIAR_MW       0x00000002	/* MII write */
+  #define ETH_MACMIIAR_CR       0x0000001C	/* CR clock range: 6 cases */
+  #define ETH_MACMIIAR_CR_Div42 0x00000000	/* HCLK:60-100 MHz; MDC clock= HCLK/42 */
+  #define ETH_MACMIIAR_CR_Div62 0x00000004	/* HCLK:100-150 MHz; MDC clock= HCLK/62 */
+  #define ETH_MACMIIAR_CR_Div16 0x00000008	/* HCLK:20-35 MHz; MDC clock= HCLK/16 */
+  #define ETH_MACMIIAR_CR_Div26 0x0000000C	/* HCLK:35-60 MHz; MDC clock= HCLK/26 */
+  #define ETH_MACMIIAR_CR_Div102 0x00000010	/* HCLK:150-168 MHz; MDC clock= HCLK/102 */
+  #define ETH_MACMIIAR_MR       0x000007C0	/* MII register in the selected PHY */
+  #define ETH_MACMIIAR_PA       0x0000F800	/* Physical layer address */
+#define TOFF_ETH_MACMIIDR   0x0014		/* (RW) Ethernet MAC MII data register */
+#define TOFF_ETH_MACFCR     0x0018		/* (RW) Ethernet MAC flow control register */
+  #define ETH_MACFCR_FCBBPA     0x00000001	/* Flow control busy/backpressure activate */
+  #define ETH_MACFCR_TFCE       0x00000002	/* Transmit flow control enable */
+  #define ETH_MACFCR_RFCE       0x00000004	/* Receive flow control enable */
+  #define ETH_MACFCR_UPFD       0x00000008	/* Unicast pause frame detect */
+  #define ETH_MACFCR_PLT        0x00000030	/* Pause low threshold: 4 cases */
+  #define ETH_MACFCR_PLT_Minus4   0x00000000	/* Pause time minus 4 slot times */
+  #define ETH_MACFCR_PLT_Minus28  0x00000010	/* Pause time minus 28 slot times */
+  #define ETH_MACFCR_PLT_Minus144 0x00000020	/* Pause time minus 144 slot times */
+  #define ETH_MACFCR_PLT_Minus256 0x00000030	/* Pause time minus 256 slot times */
+  #define ETH_MACFCR_ZQPD       0x00000080	/* Zero-quanta pause disable */
+  #define ETH_MACFCR_PT         0xFFFF0000	/* Pause time */
+#define TOFF_ETH_MACVLANTR  0x001C	/* (RW) Ethernet MAC VLAN tag register */
+  #define ETH_MACVLANTR_VLANTI  0x0000FFFF	/* VLAN tag identifier (for receive frames) */
+  #define ETH_MACVLANTR_VLANTC  0x00010000	/* 12-bit VLAN tag comparison */
+#define TOFF_ETH_MACRWUFFR  0x0028	/* (RW) Ethernet MAC remote wakeup frame filter register */
+#define TOFF_ETH_MACPMTCSR  0x002C	/* (RW) Ethernet MAC PMT control and status register */
+  #define ETH_MACPMTCSR_PD      0x00000001	/* Power Down */
+  #define ETH_MACPMTCSR_MPE     0x00000002	/* Magic Packet Enable */
+  #define ETH_MACPMTCSR_WFE     0x00000004	/* Wake-Up Frame Enable */
+  #define ETH_MACPMTCSR_MPR     0x00000020	/* Magic Packet Received */
+  #define ETH_MACPMTCSR_WFR     0x00000040	/* Wake-Up Frame Received */
+  #define ETH_MACPMTCSR_GU      0x00000200	/* Global Unicast */
+  #define ETH_MACPMTCSR_WFFRPR  0x80000000	/* Wake-Up Frame Filter Register Pointer Reset */
+#define TOFF_ETH_MACDBGR    0x0034	/* (RW) Ethernet MAC debug register */
+  #define ETH_MACDBGR_MMRPEA    0x00000001	/* MAC MII receive protocol engine active */
+  #define ETH_MACDBGR_MSFRWCS   0x00000006	/* MAC small FIFO read / write controllers status  mask */
+  #define ETH_MACDBGR_MSFRWCS_0 0x00000002
+  #define ETH_MACDBGR_MSFRWCS_1 0x00000004
+  #define ETH_MACDBGR_RFWRA     0x00000010	/* Rx FIFO write controller active */
+  #define ETH_MACDBGR_RFRCS     0x00000060	/* Rx FIFO read controller status mask */
+  #define ETH_MACDBGR_RFRCS_FLUSHING      0x00000060	/* Flushing the frame data and status */
+  #define ETH_MACDBGR_RFRCS_STATUSREADING 0x00000040	/* Reading frame status (or time-stamp) */
+  #define ETH_MACDBGR_RFRCS_DATAREADING   0x00000020	/* Reading frame data */
+  #define ETH_MACDBGR_RFRCS_IDLE          0x00000000	/* IDLE state */
+  #define ETH_MACDBGR_RFFL      0x00000300	/* Rx FIFO fill level mask */
+  #define ETH_MACDBGR_RFFL_FULL           0x00000300	/* RxFIFO full */
+  #define ETH_MACDBGR_RFFL_ABOVEFCT       0x00000200	/* RxFIFO fill-level above flow-control activate threshold */
+  #define ETH_MACDBGR_RFFL_BELOWFCT       0x00000100	/* RxFIFO fill-level below flow-control de-activate threshold  */
+  #define ETH_MACDBGR_RFFL_EMPTY          0x00000000	/* RxFIFO empty */
+  #define ETH_MACDBGR_MMTEA     0x00010000	/* MAC MII transmit engine active */
+  #define ETH_MACDBGR_MTFCS     0x00060000	/* MAC transmit frame controller status mask */
+  #define ETH_MACDBGR_MTFCS_TRANSFERRING  0x00060000	/* Transferring input frame for transmission */
+  #define ETH_MACDBGR_MTFCS_GENERATINGPCF 0x00040000	/* Generating and transmitting a Pause control frame (in full duplex mode) */
+  #define ETH_MACDBGR_MTFCS_WAITING       0x00020000	/* Waiting for Status of previous frame or IFG/backoff period to be over   */
+  #define ETH_MACDBGR_MTFCS_IDLE          0x00000000	/* Idle */
+  #define ETH_MACDBGR_MTP       0x00080000	/* MAC transmitter in pause */
+  #define ETH_MACDBGR_TFRS      0x00300000	/* Tx FIFO read status mask */
+  #define ETH_MACDBGR_TFRS_WRITING        0x00300000	/* Writing the received TxStatus or flushing the TxFIFO */
+  #define ETH_MACDBGR_TFRS_WAITING        0x00200000	/* Waiting for TxStatus from MAC transmitter */
+  #define ETH_MACDBGR_TFRS_READ           0x00100000	/* Read state (transferring data to the MAC transmitter) */
+  #define ETH_MACDBGR_TFRS_IDLE           0x00000000	/* Idle state */
+  #define ETH_MACDBGR_TPWA      0x00400000	/* Tx FIFO write active */
+  #define ETH_MACDBGR_TFNE      0x01000000	/* Tx FIFO not empty */
+  #define ETH_MACDBGR_TFF       0x02000000	/* Tx FIFO full */
+#define TOFF_ETH_MACSR      0x0038		/* (R) Ethernet MAC interrupt status register */
+  #define ETH_MACSR_PMTS        0x00000008	/* PMT status */
+  #define ETH_MACSR_MMCS        0x00000010	/* MMC status */
+  #define ETH_MACSR_MMMCRS      0x00000020	/* MMC receive status */
+  #define ETH_MACSR_MMCTS       0x00000040	/* MMC transmit status */
+  #define ETH_MACSR_TSTS        0x00000200	/* Time stamp trigger status */
+#define TOFF_ETH_MACIMR     0x003C		/* (RW) Ethernet MAC interrupt mask register */
+  #define ETH_MACIMR_PMTIM      0x00000008	/* PMT interrupt mask */
+  #define ETH_MACIMR_TSTIM      0x00000200	/* Time stamp trigger interrupt mask */
+#define TOFF_ETH_MACA0HR    0x0040		/* (RW) Ethernet MAC address 0 high register */
+#define TOFF_ETH_MACA0LR    0x0044		/* (RW) Ethernet MAC address 0 low register */
+#define TOFF_ETH_MACA1HR    0x0048		/* (RW) Ethernet MAC address 1 high register */
+  #define ETH_MACA1HR_MACA1H    0x0000FFFF	/* MAC address1 high */
+  #define ETH_MACA1HR_MBC       0x3F000000	/* Mask byte control: bits to mask for comparison of the MAC Address bytes */
+  #define ETH_MACA1HR_MBC_HBits15_8       0x20000000	/* Mask MAC Address high reg bits [15:8] */
+  #define ETH_MACA1HR_MBC_HBits7_0        0x10000000	/* Mask MAC Address high reg bits [7:0] */
+  #define ETH_MACA1HR_MBC_LBits31_24      0x08000000	/* Mask MAC Address low reg bits [31:24] */
+  #define ETH_MACA1HR_MBC_LBits23_16      0x04000000	/* Mask MAC Address low reg bits [23:16] */
+  #define ETH_MACA1HR_MBC_LBits15_8       0x02000000	/* Mask MAC Address low reg bits [15:8] */
+  #define ETH_MACA1HR_MBC_LBits7_0        0x01000000	/* Mask MAC Address low reg bits [7:0] */
+  #define ETH_MACA1HR_SA                  0x40000000	/* Source address */
+  #define ETH_MACA1HR_AE                  0x80000000	/* Address enable */
+#define TOFF_ETH_MACA1LR    0x004C		/* (RW) Ethernet MAC address 1 low register */
+#define TOFF_ETH_MACA2HR    0x0050		/* (RW) Ethernet MAC address 2 high register */
+  #define ETH_MACA2HR_MACA2H    0x0000FFFF	/* MAC address1 high */
+  #define ETH_MACA2HR_MBC       0x3F000000	/* Mask byte control */
+  #define ETH_MACA2HR_MBC_HBits15_8       0x20000000	/* Mask MAC Address high reg bits [15:8] */
+  #define ETH_MACA2HR_MBC_HBits7_0        0x10000000	/* Mask MAC Address high reg bits [7:0] */
+  #define ETH_MACA2HR_MBC_LBits31_24      0x08000000	/* Mask MAC Address low reg bits [31:24] */
+  #define ETH_MACA2HR_MBC_LBits23_16      0x04000000	/* Mask MAC Address low reg bits [23:16] */
+  #define ETH_MACA2HR_MBC_LBits15_8       0x02000000	/* Mask MAC Address low reg bits [15:8] */
+  #define ETH_MACA2HR_MBC_LBits7_0        0x01000000	/* Mask MAC Address low reg bits [70] */
+  #define ETH_MACA2HR_SA        0x40000000	/* Source address */
+  #define ETH_MACA2HR_AE        0x80000000	/* Address enable */
+#define TOFF_ETH_MACA2LR    0x0054		/* (RW) Ethernet MAC address 2 low register */
+#define TOFF_ETH_MACA3HR    0x0058		/* (RW) Ethernet MAC address 3 high register */
+  #define ETH_MACA3HR_MACA3H    0x0000FFFF	/* MAC address3 high */
+  #define ETH_MACA3HR_MBC       0x3F000000	/* Mask byte control */
+  #define ETH_MACA3HR_MBC_HBits15_8       0x20000000	/* Mask MAC Address high reg bits [15:8] */
+  #define ETH_MACA3HR_MBC_HBits7_0        0x10000000	/* Mask MAC Address high reg bits [7:0] */
+  #define ETH_MACA3HR_MBC_LBits31_24      0x08000000	/* Mask MAC Address low reg bits [31:24] */
+  #define ETH_MACA3HR_MBC_LBits23_16      0x04000000	/* Mask MAC Address low reg bits [23:16] */
+  #define ETH_MACA3HR_MBC_LBits15_8       0x02000000	/* Mask MAC Address low reg bits [15:8] */
+  #define ETH_MACA3HR_MBC_LBits7_0        0x01000000	/* Mask MAC Address low reg bits [70] */
+  #define ETH_MACA3HR_SA        0x40000000	/* Source address */
+  #define ETH_MACA3HR_AE        0x80000000	/* Address enable */
+#define TOFF_ETH_MACA3LR    0x005C		/* (RW) Ethernet MAC address 3 low register */
+#define TOFF_ETH_MMCCR      0x0100		/* (RW) Ethernet MMC control register */
+  #define ETH_MMCCR_CR          0x00000001	/* Counters Reset */
+  #define ETH_MMCCR_CSR         0x00000002	/* Counter Stop Rollover */
+  #define ETH_MMCCR_ROR         0x00000004	/* Reset on Read */
+  #define ETH_MMCCR_MCF         0x00000008	/* MMC Counter Freeze */
+  #define ETH_MMCCR_MCP         0x00000010	/* MMC counter preset */
+  #define ETH_MMCCR_MCFHP       0x00000020	/* MMC counter Full-Half preset */
+#define TOFF_ETH_MMCRIR     0x0104		/* (R) Ethernet MMC receive interrupt register */
+  #define ETH_MMCRIR_RFCES      0x00000020	/* Set when Rx crc error counter reaches half the maximum value */
+  #define ETH_MMCRIR_RFAES      0x00000040	/* Set when Rx alignment error counter reaches half the maximum value */
+  #define ETH_MMCRIR_RGUFS      0x00020000	/* Set when Rx good unicast frames counter reaches half the maximum value */
+#define TOFF_ETH_MMCTIR     0x0108		/* (R) Ethernet MMC transmit interrupt register */
+  #define ETH_MMCTIR_TGFSCS     0x00004000	/* Set when Tx good single col counter reaches half the maximum value */
+  #define ETH_MMCTIR_TGFMSCS    0x00008000	/* Set when Tx good multi col counter reaches half the maximum value */
+  #define ETH_MMCTIR_TGFS       0x00200000	/* Set when Tx good frame count counter reaches half the maximum value */
+#define TOFF_ETH_MMCRIMR    0x010C		/* (RW) Ethernet MMC receive interrupt mask register */
+  #define ETH_MMCRIMR_RFCEM     0x00000020	/* Mask the interrupt when Rx crc error counter reaches half the maximum value */
+  #define ETH_MMCRIMR_RFAEM     0x00000040	/* Mask the interrupt when when Rx alignment error counter reaches half the maximum value */
+  #define ETH_MMCRIMR_RGUFM     0x00020000	/* Mask the interrupt when Rx good unicast frames counter reaches half the maximum value */
+#define TOFF_ETH_MMCTIMR    0x0110		/* (RW) Ethernet MMC transmit interrupt mask register */
+  #define ETH_MMCTIMR_TGFSCM    0x00004000	/* Mask the interrupt when Tx good single col counter reaches half the maximum value */
+  #define ETH_MMCTIMR_TGFMSCM   0x00008000	/* Mask the interrupt when Tx good multi col counter reaches half the maximum value */
+  #define ETH_MMCTIMR_TGFM      0x00200000	/* Mask the interrupt when Tx good frame count counter reaches half the maximum value */
+#define TOFF_ETH_MMCTGFSCCR 0x014C		/* (R) Ethernet MMC transmitted good frames after a single collision counter register */
+#define TOFF_ETH_MMCTGFMSCCR 0x0150		/* (R) Ethernet MMC transmitted good frames after more than a single collision counter register */
+#define TOFF_ETH_MMCTGFCR   0x0168		/* (R) Ethernet MMC transmitted good frames counter register */
+#define TOFF_ETH_MMCRFCECR  0x0194		/* (R) Ethernet MMC received frames with CRC error counter register */
+#define TOFF_ETH_MMCRFAECR  0x0198		/* (R) Ethernet MMC received frames with alignment error counter register */
+#define TOFF_ETH_MMCRGUFCR  0x01C4		/* (R) MMC received good unicast frames counter register */
+#define TOFF_ETH_PTPTSCR    0x0700		/* (RW) Ethernet PTP time stamp control register */
+  #define ETH_PTPTSCR_TSE       0x00000001	/* Time stamp enable */
+  #define ETH_PTPTSCR_TSFCU     0x00000002	/* Time stamp fine or coarse update */
+  #define ETH_PTPTSCR_TSSTI     0x00000004	/* Time stamp initialize */
+  #define ETH_PTPTSCR_TSSTU     0x00000008	/* Time stamp update */
+  #define ETH_PTPTSCR_TSITE     0x00000010	/* Time stamp interrupt trigger enable */
+  #define ETH_PTPTSCR_TSARU     0x00000020	/* Addend register update */
+  #define ETH_PTPTSSR_TSSARFE   0x00000100	/* Time stamp snapshot for all received frames enable */
+  #define ETH_PTPTSSR_TSSSR     0x00000200	/* Time stamp Sub-seconds rollover */
+  #define ETH_PTPTSSR_TSPTPPSV2E 0x00000400	/* Time stamp PTP packet snooping for version2 format enable */
+  #define ETH_PTPTSSR_TSSPTPOEFE 0x00000800	/* Time stamp snapshot for PTP over ethernet frames enable */
+  #define ETH_PTPTSSR_TSSIPV6FE 0x00001000	/* Time stamp snapshot for IPv6 frames enable */
+  #define ETH_PTPTSSR_TSSIPV4FE 0x00002000	/* Time stamp snapshot for IPv4 frames enable */
+  #define ETH_PTPTSSR_TSSEME    0x00004000	/* Time stamp snapshot for event message enable */
+  #define ETH_PTPTSSR_TSSMRME   0x00008000	/* Time stamp snapshot for message relevant to master enable */
+  #define ETH_PTPTSCR_TSCNT     0x00030000	/* Time stamp clock node type */
+#define TOFF_ETH_PTPSSIR    0x0704		/* (RW) Ethernet PTP subsecond increment register */
+#define TOFF_ETH_PTPTSHR    0x0708		/* (R) Ethernet PTP time stamp high register */
+#define TOFF_ETH_PTPTSLR    0x070C		/* (R) Ethernet PTP time stamp low register */
+#define TOFF_ETH_PTPTSHUR   0x0710		/* (RW) Ethernet PTP time stamp high update register */
+#define TOFF_ETH_PTPTSLUR   0x0714		/* (RW) Ethernet PTP time stamp low update register */
+#define TOFF_ETH_PTPTSAR    0x0718		/* (RW) Ethernet PTP time stamp addend register */
+#define TOFF_ETH_PTPTTHR    0x071C		/* (RW) Ethernet PTP target time high register */
+#define TOFF_ETH_PTPTTLR    0x0720		/* (RW) Ethernet PTP target time low register */
+#define TOFF_ETH_PTPTSSR    0x0728		/* (R) Ethernet PTP time stamp status register */
+  #define ETH_PTPTSSR_TSSO      0x00000010	/* Time stamp seconds overflow */
+  #define ETH_PTPTSSR_TSTTR     0x00000020	/* Time stamp target time reached */
+#define TOFF_ETH_PTPPPSCR   0x072C		/* (RW) Ethernet PTP PPS control register */
+#define TOFF_ETH_DMABMR     0x1000		/* Ethernet DMA bus mode register */
+  #define ETH_DMABMR_SR         0x00000001	/* Software reset */
+  #define ETH_DMABMR_DA         0x00000002	/* DMA arbitration scheme */
+  #define ETH_DMABMR_DSL        0x0000007C	/* Descriptor Skip Length */
+  #define ETH_DMABMR_EDE        0x00000080	/* Enhanced Descriptor Enable */
+  #define ETH_DMABMR_PBL        0x00003F00	/* Programmable burst length */
+  #define ETH_DMABMR_PBL_1Beat  0x00000100	/* maximum number of beats to be transferred in one TxDMA (or both) transaction is 1 */
+  #define ETH_DMABMR_PBL_2Beat  0x00000200	/* maximum number of beats to be transferred in one TxDMA (or both) transaction is 2 */
+  #define ETH_DMABMR_PBL_4Beat  0x00000400	/* maximum number of beats to be transferred in one TxDMA (or both) transaction is 4 */
+  #define ETH_DMABMR_PBL_8Beat  0x00000800	/* maximum number of beats to be transferred in one TxDMA (or both) transaction is 8 */
+  #define ETH_DMABMR_PBL_16Beat 0x00001000	/* maximum number of beats to be transferred in one TxDMA (or both) transaction is 16 */
+  #define ETH_DMABMR_PBL_32Beat 0x00002000	/* maximum number of beats to be transferred in one TxDMA (or both) transaction is 32 */
+  #define ETH_DMABMR_RTPR       0x0000C000	/* Rx Tx priority ratio */
+  #define ETH_DMABMR_RTPR_1_1   0x00000000	/* Rx Tx priority ratio */
+  #define ETH_DMABMR_RTPR_2_1   0x00004000	/* Rx Tx priority ratio */
+  #define ETH_DMABMR_RTPR_3_1   0x00008000	/* Rx Tx priority ratio */
+  #define ETH_DMABMR_RTPR_4_1   0x0000C000	/* Rx Tx priority ratio */
+  #define ETH_DMABMR_FB         0x00010000	/* Fixed Burst */
+  #define ETH_DMABMR_RDP        0x007E0000	/* RxDMA PBL */
+  #define ETH_DMABMR_RDP_1Beat          0x00020000	/* maximum number of beats to be transferred in one RxDMA transaction is 1 */
+  #define ETH_DMABMR_RDP_2Beat          0x00040000	/* maximum number of beats to be transferred in one RxDMA transaction is 2 */
+  #define ETH_DMABMR_RDP_4Beat          0x00080000	/* maximum number of beats to be transferred in one RxDMA transaction is 4 */
+  #define ETH_DMABMR_RDP_8Beat          0x00100000	/* maximum number of beats to be transferred in one RxDMA transaction is 8 */
+  #define ETH_DMABMR_RDP_16Beat         0x00200000	/* maximum number of beats to be transferred in one RxDMA transaction is 16 */
+  #define ETH_DMABMR_RDP_32Beat         0x00400000	/* maximum number of beats to be transferred in one RxDMA transaction is 32 */
+  #define ETH_DMABMR_USP        0x00800000	/* Use separate PBL */
+  #define ETH_DMABMR_FPM        0x01000000	/* 4xPBL mode */
+  #define ETH_DMABMR_AAB        0x02000000	/* Address-Aligned beats */
+  #define ETH_DMABMR_RDP_4xPBL_4Beat    0x01020000	/* maximum number of beats to be transferred in one RxDMA transaction is 4 */
+  #define ETH_DMABMR_RDP_4xPBL_8Beat    0x01040000	/* maximum number of beats to be transferred in one RxDMA transaction is 8 */
+  #define ETH_DMABMR_RDP_4xPBL_16Beat   0x01080000	/* maximum number of beats to be transferred in one RxDMA transaction is 16 */
+  #define ETH_DMABMR_RDP_4xPBL_32Beat   0x01100000	/* maximum number of beats to be transferred in one RxDMA transaction is 32 */
+  #define ETH_DMABMR_RDP_4xPBL_64Beat   0x01200000	/* maximum number of beats to be transferred in one RxDMA transaction is 64 */
+  #define ETH_DMABMR_RDP_4xPBL_128Beat  0x01400000	/* maximum number of beats to be transferred in one RxDMA transaction is 128 */
+  #define ETH_DMABMR_PBL_4xPBL_4Beat    0x01000100	/* maximum number of beats to be transferred in one TxDMA (or both) transaction is 4 */
+  #define ETH_DMABMR_PBL_4xPBL_8Beat    0x01000200	/* maximum number of beats to be transferred in one TxDMA (or both) transaction is 8 */
+  #define ETH_DMABMR_PBL_4xPBL_16Beat   0x01000400	/* maximum number of beats to be transferred in one TxDMA (or both) transaction is 16 */
+  #define ETH_DMABMR_PBL_4xPBL_32Beat   0x01000800	/* maximum number of beats to be transferred in one TxDMA (or both) transaction is 32 */
+  #define ETH_DMABMR_PBL_4xPBL_64Beat   0x01001000	/* maximum number of beats to be transferred in one TxDMA (or both) transaction is 64 */
+  #define ETH_DMABMR_PBL_4xPBL_128Beat  0x01002000	/* maximum number of beats to be transferred in one TxDMA (or both) transaction is 128 */
+#define TOFF_ETH_DMATPDR    0x1004		/* (RW) Ethernet DMA transmit poll demain register */
+#define TOFF_ETH_DMARPDR    0x1008		/* (RW) Ethernet DMA receive poll demain register */
+#define TOFF_ETH_DMARDLAR   0x100C		/* (RW) Ethernet DMA receive descriptor list address register */
+#define TOFF_ETH_DMATDLAR   0x1010		/* (RW) Ethernet DMA transmit descriptor list address register */
+#define TOFF_ETH_DMASR      0x1014		/* (R) Ethernet DMA status register */
+  #define ETH_DMASR_TS          0x00000001	/* Transmit status */
+  #define ETH_DMASR_TPSS        0x00000002	/* Transmit process stopped status */
+  #define ETH_DMASR_TBUS        0x00000004	/* Transmit buffer unavailable status */
+  #define ETH_DMASR_TJTS        0x00000008	/* Transmit jabber timeout status */
+  #define ETH_DMASR_ROS         0x00000010	/* Receive overflow status */
+  #define ETH_DMASR_TUS         0x00000020	/* Transmit underflow status */
+  #define ETH_DMASR_RS          0x00000040	/* Receive status */
+  #define ETH_DMASR_RBUS        0x00000080	/* Receive buffer unavailable status */
+  #define ETH_DMASR_RPSS        0x00000100	/* Receive process stopped status */
+  #define ETH_DMASR_RWTS        0x00000200	/* Receive watchdog timeout status */
+  #define ETH_DMASR_ETS         0x00000400	/* Early transmit status */
+  #define ETH_DMASR_FBES        0x00002000	/* Fatal bus error status */
+  #define ETH_DMASR_ERS         0x00004000	/* Early receive status */
+  #define ETH_DMASR_AIS         0x00008000	/* Abnormal interrupt summary */
+  #define ETH_DMASR_NIS         0x00010000	/* Normal interrupt summary */
+  #define ETH_DMASR_RPS         0x000E0000	/* Receive process state */
+  #define ETH_DMASR_RPS_Stopped           0x00000000	/* Stopped - Reset or Stop Rx Command issued */
+  #define ETH_DMASR_RPS_Fetching          0x00020000	/* Running - fetching the Rx descriptor */
+  #define ETH_DMASR_RPS_Waiting           0x00060000	/* Running - waiting for packet */
+  #define ETH_DMASR_RPS_Suspended         0x00080000	/* Suspended - Rx Descriptor unavailable */
+  #define ETH_DMASR_RPS_Closing           0x000A0000	/* Running - closing descriptor */
+  #define ETH_DMASR_RPS_Queuing           0x000E0000	/* Running - queuing the recieve frame into host memory */
+  #define ETH_DMASR_TPS         0x00700000	/* Transmit process state */
+  #define ETH_DMASR_TPS_Stopped           0x00000000	/* Stopped - Reset or Stop Tx Command issued  */
+  #define ETH_DMASR_TPS_Fetching          0x00100000	/* Running - fetching the Tx descriptor */
+  #define ETH_DMASR_TPS_Waiting           0x00200000	/* Running - waiting for status */
+  #define ETH_DMASR_TPS_Reading           0x00300000	/* Running - reading the data from host memory */
+  #define ETH_DMASR_TPS_Suspended         0x00600000	/* Suspended - Tx Descriptor unavailabe */
+  #define ETH_DMASR_TPS_Closing           0x00700000	/* Running - closing Rx descriptor */
+  #define ETH_DMASR_EBS         0x03800000	/* Error bits status */
+  #define ETH_DMASR_EBS_DataTransfTx      0x00800000	/* Error bits 0-Rx DMA, 1-Tx DMA */
+  #define ETH_DMASR_EBS_ReadTransf        0x01000000	/* Error bits 0-write trnsf, 1-read transfr */
+  #define ETH_DMASR_EBS_DescAccess        0x02000000	/* Error bits 0-data buffer, 1-desc. access */
+  #define ETH_DMASR_MMCS        0x08000000	/* MMC status */
+  #define ETH_DMASR_PMTS        0x10000000	/* PMT status */
+  #define ETH_DMASR_TSTS        0x20000000	/* Time-stamp trigger status */
+#define TOFF_ETH_DMAOMR     0x1018		/* (RW) Ethernet DMA operation mode register */
+  #define ETH_DMAOMR_SR         0x00000002	/* Start/stop receive */
+  #define ETH_DMAOMR_OSF        0x00000004	/* operate on second frame */
+  #define ETH_DMAOMR_RTC        0x00000018	/* receive threshold control */
+  #define ETH_DMAOMR_RTC_64Bytes          0x00000000	/* threshold level of the MTL Receive FIFO is 64 Bytes */
+  #define ETH_DMAOMR_RTC_32Bytes          0x00000008	/* threshold level of the MTL Receive FIFO is 32 Bytes */
+  #define ETH_DMAOMR_RTC_96Bytes          0x00000010	/* threshold level of the MTL Receive FIFO is 96 Bytes */
+  #define ETH_DMAOMR_RTC_128Bytes         0x00000018	/* threshold level of the MTL Receive FIFO is 128 Bytes */
+  #define ETH_DMAOMR_FUGF       0x00000040	/* Forward undersized good frames */
+  #define ETH_DMAOMR_FEF        0x00000080	/* Forward error frames */
+  #define ETH_DMAOMR_ST         0x00002000	/* Start/stop transmission command */
+  #define ETH_DMAOMR_TTC        0x0001C000	/* Transmit threshold control */
+  #define ETH_DMAOMR_TTC_64Bytes          0x00000000	/* threshold level of the MTL Transmit FIFO is 64 Bytes */
+  #define ETH_DMAOMR_TTC_128Bytes         0x00004000	/* threshold level of the MTL Transmit FIFO is 128 Bytes */
+  #define ETH_DMAOMR_TTC_192Bytes         0x00008000	/* threshold level of the MTL Transmit FIFO is 192 Bytes */
+  #define ETH_DMAOMR_TTC_256Bytes         0x0000C000	/* threshold level of the MTL Transmit FIFO is 256 Bytes */
+  #define ETH_DMAOMR_TTC_40Bytes          0x00010000	/* threshold level of the MTL Transmit FIFO is 40 Bytes */
+  #define ETH_DMAOMR_TTC_32Bytes          0x00014000	/* threshold level of the MTL Transmit FIFO is 32 Bytes */
+  #define ETH_DMAOMR_TTC_24Bytes          0x00018000	/* threshold level of the MTL Transmit FIFO is 24 Bytes */
+  #define ETH_DMAOMR_TTC_16Bytes          0x0001C000	/* threshold level of the MTL Transmit FIFO is 16 Bytes */
+  #define ETH_DMAOMR_FTF        0x00100000	/* Flush transmit FIFO */
+  #define ETH_DMAOMR_TSF        0x00200000	/* Transmit store and forward */
+  #define ETH_DMAOMR_DFRF       0x01000000	/* Disable flushing of received frames */
+  #define ETH_DMAOMR_RSF        0x02000000	/* Receive store and forward */
+  #define ETH_DMAOMR_DTCEFD     0x04000000	/* Disable Dropping of TCP/IP checksum error frames */
+#define TOFF_ETH_DMAIER     0x101C		/* (RW) Ethernet DMA interrupt enable register */
+  #define ETH_DMAIER_TIE        0x00000001	/* Transmit interrupt enable */
+  #define ETH_DMAIER_TPSIE      0x00000002	/* Transmit process stopped interrupt enable */
+  #define ETH_DMAIER_TBUIE      0x00000004	/* Transmit buffer unavailable interrupt enable */
+  #define ETH_DMAIER_TJTIE      0x00000008	/* Transmit jabber timeout interrupt enable */
+  #define ETH_DMAIER_ROIE       0x00000010	/* Receive Overflow interrupt enable */
+  #define ETH_DMAIER_TUIE       0x00000020	/* Transmit Underflow interrupt enable */
+  #define ETH_DMAIER_RIE        0x00000040	/* Receive interrupt enable */
+  #define ETH_DMAIER_RBUIE      0x00000080	/* Receive buffer unavailable interrupt enable */
+  #define ETH_DMAIER_RPSIE      0x00000100	/* Receive process stopped interrupt enable */
+  #define ETH_DMAIER_RWTIE      0x00000200	/* Receive watchdog timeout interrupt enable */
+  #define ETH_DMAIER_ETIE       0x00000400	/* Early transmit interrupt enable */
+  #define ETH_DMAIER_FBEIE      0x00002000	/* Fatal bus error interrupt enable */
+  #define ETH_DMAIER_ERIE       0x00004000	/* Early receive interrupt enable */
+  #define ETH_DMAIER_AISE       0x00008000	/* Abnormal interrupt summary enable */
+  #define ETH_DMAIER_NISE       0x00010000	/* Normal interrupt summary enable */
+#define TOFF_ETH_DMAMFBOCR  0x1020		/* (R) Ethernet DMA messed frame and buffer overflow counter register */
+  #define ETH_DMAMFBOCR_MFC     0x0000FFFF	/* Number of frames missed by the controller */
+  #define ETH_DMAMFBOCR_OMFC    0x00010000	/* Overflow bit for missed frame counter */
+  #define ETH_DMAMFBOCR_MFA     0x0FFE0000	/* Number of frames missed by the application */
+  #define ETH_DMAMFBOCR_OFOC    0x10000000	/* Overflow bit for FIFO overflow counter */
+#define TOFF_ETH_DMARSWTR   0x1024		/* (RW) Ethernet DMA recive status watchdog timer register */
+#define TOFF_ETH_DMACHTDR   0x1048		/* (R) Ethernet DMA current host transmit descriptor register */
+#define TOFF_ETH_DMACHRDR   0x104C		/* (R) Ethernet DMA current host receive descriptor register */
+#define TOFF_ETH_DMACHTBAR  0x1050		/* (R) Ethernet DMA current host transmit buffer address register */
+#define TOFF_ETH_DMACHRBAR  0x1054		/* (R) Ethernet DMA current host receive buffer address register */
+
+
+/*
+ *  SERIAL AUDIO INTERFACE
+ */
+#define TADR_SAI1_BASE      (APB2PERIPH_BASE + 0x5800)
+#define TADR_SAI2_BASE      (APB2PERIPH_BASE + 0x5C00)
+#define TOFF_SAI_GCR        0x0000		/* (RW) SAI global configuration register */
+  #define SAI_GCR_SYNCIN      0x00000003	/* SYNCIN[1:0] bits (Synchronization Inputs)   */
+  #define SAI_GCR_SYNCIN_0    0x00000001	/* Bit 0 */
+  #define SAI_GCR_SYNCIN_1    0x00000002	/* Bit 1 */
+  #define SAI_GCR_SYNCOUT     0x00000030	/* SYNCOUT[1:0] bits (Synchronization Outputs) */
+  #define SAI_GCR_SYNCOUT_0   0x00000010	/* Bit 0 */
+  #define SAI_GCR_SYNCOUT_1   0x00000020	/* Bit 1 */
+#define SAI_WINDOW_SIZE     0x0020
+#define TOFF_SAI_CR1        0x0000		/* (RW) SAI block x configuration register 1 */
+  #define SAI_xCR1_MODE       0x00000003	/* MODE[1:0] bits (Audio Block Mode) */
+  #define SAI_xCR1_MODE_0     0x00000001	/* Bit 0 */
+  #define SAI_xCR1_MODE_1     0x00000002	/* Bit 1 */
+  #define SAI_xCR1_PRTCFG     0x0000000C	/* PRTCFG[1:0] bits (Protocol Configuration)   */
+  #define SAI_xCR1_PRTCFG_0   0x00000004	/* Bit 0 */
+  #define SAI_xCR1_PRTCFG_1   0x00000008	/* Bit 1 */
+  #define SAI_xCR1_DS         0x000000E0	/* DS[1:0] bits (Data Size) */
+  #define SAI_xCR1_DS_0       0x00000020	/* Bit 0 */
+  #define SAI_xCR1_DS_1       0x00000040	/* Bit 1 */
+  #define SAI_xCR1_DS_2       0x00000080	/* Bit 2 */
+  #define SAI_xCR1_LSBFIRST   0x00000100	/* LSB First Configuration  */
+  #define SAI_xCR1_CKSTR      0x00000200	/* ClocK STRobing edge      */
+  #define SAI_xCR1_SYNCEN     0x00000C00	/* SYNCEN[1:0](SYNChronization ENable) */
+  #define SAI_xCR1_SYNCEN_0   0x00000400	/* Bit 0 */
+  #define SAI_xCR1_SYNCEN_1   0x00000800	/* Bit 1 */
+  #define SAI_xCR1_MONO       0x00001000	/* Mono mode */
+  #define SAI_xCR1_OUTDRIV    0x00002000	/* Output Drive */
+  #define SAI_xCR1_SAIEN      0x00010000	/* Audio Block enable */
+  #define SAI_xCR1_DMAEN      0x00020000	/* DMA enable */
+  #define SAI_xCR1_NODIV      0x00080000	/* No Divider Configuration */
+  #define SAI_xCR1_MCKDIV     0x00F00000	/* MCKDIV[3:0] (Master ClocK Divider)  */
+  #define SAI_xCR1_MCKDIV_0   0x00100000	/* Bit 0  */
+  #define SAI_xCR1_MCKDIV_1   0x00200000	/* Bit 1  */
+  #define SAI_xCR1_MCKDIV_2   0x00400000	/* Bit 2  */
+  #define SAI_xCR1_MCKDIV_3   0x00800000	/* Bit 3  */
+#define TOFF_SAI_CR2        0x0004		/* (RW) SAI block x configuration register 2 */
+  #define SAI_xCR2_FTH        0x00000007	/* FTH[2:0](Fifo THreshold)  */
+  #define SAI_xCR2_FTH_0      0x00000001	/* Bit 0 */
+  #define SAI_xCR2_FTH_1      0x00000002	/* Bit 1 */
+  #define SAI_xCR2_FTH_2      0x00000004	/* Bit 2 */
+  #define SAI_xCR2_FFLUSH     0x00000008	/* Fifo FLUSH */
+  #define SAI_xCR2_TRIS       0x00000010	/* TRIState Management on data line */
+  #define SAI_xCR2_MUTE       0x00000020	/* Mute mode */
+  #define SAI_xCR2_MUTEVAL    0x00000040	/* Mute value */
+  #define SAI_xCR2_MUTECNT    0x00001F80	/* MUTECNT[5:0] (MUTE counter) */
+  #define SAI_xCR2_MUTECNT_0  0x00000080	/* Bit 0 */
+  #define SAI_xCR2_MUTECNT_1  0x00000100	/* Bit 1 */
+  #define SAI_xCR2_MUTECNT_2  0x00000200	/* Bit 2 */
+  #define SAI_xCR2_MUTECNT_3  0x00000400	/* Bit 3 */
+  #define SAI_xCR2_MUTECNT_4  0x00000800	/* Bit 4 */
+  #define SAI_xCR2_MUTECNT_5  0x00001000	/* Bit 5 */
+  #define SAI_xCR2_CPL        0x00080000	/* Complement Bit */
+  #define SAI_xCR2_COMP       0x0000C000	/* COMP[1:0] (Companding mode) */
+  #define SAI_xCR2_COMP_0     0x00004000	/* Bit 0 */
+  #define SAI_xCR2_COMP_1     0x00008000	/* Bit 1 */
+#define TOFF_SAI_FRCR       0x0008		/* (RW) SAI block x frame configuration register */
+  #define SAI_xFRCR_FRL       0x000000FF	/* FRL[1:0](Frame length)  */
+  #define SAI_xFRCR_FRL_0     0x00000001	/* Bit 0 */
+  #define SAI_xFRCR_FRL_1     0x00000002	/* Bit 1 */
+  #define SAI_xFRCR_FRL_2     0x00000004	/* Bit 2 */
+  #define SAI_xFRCR_FRL_3     0x00000008	/* Bit 3 */
+  #define SAI_xFRCR_FRL_4     0x00000010	/* Bit 4 */
+  #define SAI_xFRCR_FRL_5     0x00000020	/* Bit 5 */
+  #define SAI_xFRCR_FRL_6     0x00000040	/* Bit 6 */
+  #define SAI_xFRCR_FRL_7     0x00000080	/* Bit 7 */
+  #define SAI_xFRCR_FSALL     0x00007F00	/* FRL[1:0] (Frame synchronization active level length)  */
+  #define SAI_xFRCR_FSALL_0   0x00000100	/* Bit 0 */
+  #define SAI_xFRCR_FSALL_1   0x00000200	/* Bit 1 */
+  #define SAI_xFRCR_FSALL_2   0x00000400	/* Bit 2 */
+  #define SAI_xFRCR_FSALL_3   0x00000800	/* Bit 3 */
+  #define SAI_xFRCR_FSALL_4   0x00001000	/* Bit 4 */
+  #define SAI_xFRCR_FSALL_5   0x00002000	/* Bit 5 */
+  #define SAI_xFRCR_FSALL_6   0x00004000	/* Bit 6 */
+  #define SAI_xFRCR_FSDEF     0x00010000	/* Frame Synchronization Definition */
+  #define SAI_xFRCR_FSPO      0x00020000	/* Frame Synchronization POLarity */
+  #define SAI_xFRCR_FSOFF     0x00040000	/* Frame Synchronization OFFset*/
+#define TOFF_SAI_SLOTR      0x000C		/* (RW) SAI block x slot register */
+  #define SAI_xSLOTR_FBOFF    0x0000001F	/* FRL[4:0](First Bit Offset)  */
+  #define SAI_xSLOTR_FBOFF_0  0x00000001	/* Bit 0 */
+  #define SAI_xSLOTR_FBOFF_1  0x00000002	/* Bit 1 */
+  #define SAI_xSLOTR_FBOFF_2  0x00000004	/* Bit 2 */
+  #define SAI_xSLOTR_FBOFF_3  0x00000008	/* Bit 3 */
+  #define SAI_xSLOTR_FBOFF_4  0x00000010	/* Bit 4 */
+  #define SAI_xSLOTR_SLOTSZ   0x000000C0	/* SLOTSZ[1:0] (Slot size)  */
+  #define SAI_xSLOTR_SLOTSZ_0 0x00000040	/* Bit 0 */
+  #define SAI_xSLOTR_SLOTSZ_1 0x00000080	/* Bit 1 */
+  #define SAI_xSLOTR_NBSLOT   0x00000F00	/* NBSLOT[3:0] (Number of Slot in audio Frame)  */
+  #define SAI_xSLOTR_NBSLOT_0 0x00000100	/* Bit 0 */
+  #define SAI_xSLOTR_NBSLOT_1 0x00000200	/* Bit 1 */
+  #define SAI_xSLOTR_NBSLOT_2 0x00000400	/* Bit 2 */
+  #define SAI_xSLOTR_NBSLOT_3 0x00000800	/* Bit 3 */
+  #define SAI_xSLOTR_SLOTEN   0xFFFF0000	/* SLOTEN[15:0] (Slot Enable)  */
+#define TOFF_SAI_IMR        0x0010		/* (RW) SAI block x interrupt mask register */
+  #define SAI_xIMR_OVRUDRIE   0x00000001	/* Overrun underrun interrupt enable                              */
+  #define SAI_xIMR_MUTEDETIE  0x00000002	/* Mute detection interrupt enable                                */
+  #define SAI_xIMR_WCKCFGIE   0x00000004	/* Wrong Clock Configuration interrupt enable                     */
+  #define SAI_xIMR_FREQIE     0x00000008	/* FIFO request interrupt enable                                  */
+  #define SAI_xIMR_CNRDYIE    0x00000010	/* Codec not ready interrupt enable                               */
+  #define SAI_xIMR_AFSDETIE   0x00000020	/* Anticipated frame synchronization detection interrupt enable   */
+  #define SAI_xIMR_LFSDETIE   0x00000040	/* Late frame synchronization detection interrupt enable          */
+#define TOFF_SAI_SR         0x0014		/* (RW) SAI block x status register */
+  #define SAI_xSR_OVRUDR      0x00000001	/* Overrun underrun */
+  #define SAI_xSR_MUTEDET     0x00000002	/* Mute detection */
+  #define SAI_xSR_WCKCFG      0x00000004	/* Wrong Clock Configuration */
+  #define SAI_xSR_FREQ        0x00000008	/* FIFO request */
+  #define SAI_xSR_CNRDY       0x00000010	/* Codec not ready */
+  #define SAI_xSR_AFSDET      0x00000020	/* Anticipated frame synchronization detection */
+  #define SAI_xSR_LFSDET      0x00000040	/* Late frame synchronization detection */
+  #define SAI_xSR_FLVL        0x00070000	/* FLVL[2:0] (FIFO Level Threshold) */
+  #define SAI_xSR_FLVL_0      0x00010000	/* Bit 0 */
+  #define SAI_xSR_FLVL_1      0x00020000	/* Bit 1 */
+  #define SAI_xSR_FLVL_2      0x00040000	/* Bit 2 */
+#define TOFF_SAI_CLRFR      0x0018		/* (RW) SAI block x clear flag register */
+#define TOFF_SAI_DR         0x001C		/* (RW) SAI block x data register */
+
+
+/*
+ *  LCD-TFT DISPLAY CONTROLLER
+ */
+#define TADR_LTDC_BASE      (APB2PERIPH_BASE + 0x6800)
+#define TADR_LTDC_LAYER1    (TADR_LTDC_BASE + 0x84)
+#define TADR_LTDC_LAYER2    (TADR_LTDC_BASE + 0x104)
+#define TOFF_LTDC_SSCR      0x0008		/* (RW) LTDC Synchronization Size Configuration Register */
+  #define LTDC_SSCR_VSH      0x000007FF	/* Vertical Synchronization Height  */
+  #define LTDC_SSCR_HSW      0x0FFF0000	/* Horizontal Synchronization Width */
+#define TOFF_LTDC_BPCR      0x000C		/* (RW) LTDC Back Porch Configuration Register */
+  #define LTDC_BPCR_AVBP     0x000007FF	/* Accumulated Vertical Back Porch   */
+  #define LTDC_BPCR_AHBP     0x0FFF0000	/* Accumulated Horizontal Back Porch */
+#define TOFF_LTDC_AWCR      0x0010		/* (RW) LTDC Active Width Configuration Register */
+  #define LTDC_AWCR_AAH      0x000007FF	/* Accumulated Active heigh */
+  #define LTDC_AWCR_AAW      0x0FFF0000	/* Accumulated Active Width */
+#define TOFF_LTDC_TWCR      0x0014		/* (RW) LTDC Total Width Configuration Register */
+  #define LTDC_TWCR_TOTALH   0x000007FF	/* Total Heigh */
+  #define LTDC_TWCR_TOTALW   0x0FFF0000	/* Total Width */
+#define TOFF_LTDC_GCR       0x0018		/* (RW) LTDC Global Control Register */
+  #define LTDC_GCR_LTDCEN    0x00000001	/* LCD-TFT controller enable bit */
+  #define LTDC_GCR_DBW       0x00000070	/* Dither Blue Width */
+  #define LTDC_GCR_DGW       0x00000700	/* Dither Green Width */
+  #define LTDC_GCR_DRW       0x00007000	/* Dither Red Width */
+  #define LTDC_GCR_DTEN      0x00010000	/* Dither Enable */
+  #define LTDC_GCR_PCPOL     0x10000000	/* Pixel Clock Polarity */
+  #define LTDC_GCR_DEPOL     0x20000000	/* Data Enable Polarity */
+  #define LTDC_GCR_VSPOL     0x40000000	/* Vertical Synchronization Polarity */
+  #define LTDC_GCR_HSPOL     0x80000000	/* Horizontal Synchronization Polarity */
+#define TOFF_LTDC_SRCR      0x0024		/* (RW) LTDC Shadow Reload Configuration Register */
+  #define LTDC_SRCR_IMR      0x00000001	/* Immediate Reload */
+  #define LTDC_SRCR_VBR      0x00000002	/* Vertical Blanking Reload */
+#define TOFF_LTDC_BCCR      0x002C		/* (RW) LTDC Background Color Configuration Register */
+  #define LTDC_BCCR_BCBLUE   0x000000FF	/* Background Blue value  */
+  #define LTDC_BCCR_BCGREEN  0x0000FF00	/* Background Green value */
+  #define LTDC_BCCR_BCRED    0x00FF0000	/* Background Red value   */
+#define TOFF_LTDC_IER       0x0034		/* (RW) LTDC Interrupt Enable Register */
+  #define LTDC_IER_LIE       0x00000001	/* Line Interrupt Enable            */
+  #define LTDC_IER_FUIE      0x00000002	/* FIFO Underrun Interrupt Enable   */
+  #define LTDC_IER_TERRIE    0x00000004	/* Transfer Error Interrupt Enable  */
+  #define LTDC_IER_RRIE      0x00000008	/* Register Reload interrupt enable */
+#define TOFF_LTDC_ISR       0x0038		/* (RW) LTDC Interrupt Status Register */
+  #define LTDC_ISR_LIF       0x00000001	/* Line Interrupt Flag */
+  #define LTDC_ISR_FUIF      0x00000002	/* FIFO Underrun Interrupt Flag */
+  #define LTDC_ISR_TERRIF    0x00000004	/* Transfer Error Interrupt Flag */
+  #define LTDC_ISR_RRIF      0x00000008	/* Register Reload interrupt Flag */
+#define TOFF_LTDC_ICR       0x003C		/* (RW) LTDC Interrupt Clear Register */
+  #define LTDC_ICR_CLIF      0x00000001	/* Clears the Line Interrupt Flag */
+  #define LTDC_ICR_CFUIF     0x00000002	/* Clears the FIFO Underrun Interrupt Flag */
+  #define LTDC_ICR_CTERRIF   0x00000004	/* Clears the Transfer Error Interrupt Flag */
+  #define LTDC_ICR_CRRIF     0x00000008	/* Clears Register Reload interrupt Flag */
+#define TOFF_LTDC_LIPCR     0x0040		/* (RW) LTDC Line Interrupt Position Configuration Register */
+#define TOFF_LTDC_CPSR      0x0044		/* (RW) LTDC Current Position Status Register */
+#define TOFF_LTDC_CDSR      0x0048		/* (RW) LTDC Current Display Status Register */
+
+/*
+ *  LCD-TFT DISPLAY LAYER X CONTROLLER (WINDOW)
+ */
+#define LTDC_WINDOW_SIZE    128
+#define TOFF_LTDCW_CR       0x0000		/* (RW) LTDC Layerx Control Register :0x84 */
+  #define LTDC_CR_LEN        0x00000001	/* Layer Enable              */
+  #define LTDC_CR_COLKEN     0x00000002	/* Color Keying Enable       */
+  #define LTDC_CR_CLUTEN     0x00000010	/* Color Lockup Table Enable */
+#define TOFF_LTDCW_WHPCR    0x0004		/* (RW) LTDC Layerx Window Horizontal :0x88 */
+  #define LTDC_WHPCR_WHSTPOS 0x00000FFF	/* Window Horizontal Start Position */
+  #define LTDC_WHPCR_WHSPPOS 0xFFFF0000	/* Window Horizontal Stop Position  */
+#define TOFF_LTDCW_WVPCR    0x0008		/* (RW) LTDC Layerx Window Vertical Position Configuration Register :0x8C */
+  #define LTDC_WVPCR_WVSTPOS 0x00000FFF	/* Window Vertical Start Position */
+  #define LTDC_WVPCR_WVSPPOS 0xFFFF0000	/* Window Vertical Stop Position  */
+#define TOFF_LTDCW_CKCR     0x000C		/* (RW) LTDC Layerx Color Keying Configuration Register :0x90 */
+  #define LTDC_CKCR_CKBLUE   0x000000FF	/* Color Key Blue value  */
+  #define LTDC_CKCR_CKGREEN  0x0000FF00	/* Color Key Green value */
+  #define LTDC_CKCR_CKRED    0x00FF0000	/* Color Key Red value   */
+#define TOFF_LTDCW_PFCR     0x0010		/* (RW) LTDC Layerx Pixel Format Configuration Register :0x94 */
+  #define LTDC_PFCR_PF       0x00000007	/* Pixel Format */
+#define TOFF_LTDCW_CACR     0x0014		/* (RW) LTDC Layerx Constant Alpha Configuration Register :0x98 */
+  #define LTDC_CACR_CONSTA   0x000000FF	/* Constant Alpha */
+#define TOFF_LTDCW_DCCR     0x0018		/* (RW) LTDC Layerx Default Color Configuration Register :0x9C */
+  #define LTDC_DCCR_DCBLUE   0x000000FF	/* Default Color Blue  */
+  #define LTDC_DCCR_DCGREEN  0x0000FF00	/* Default Color Green */
+  #define LTDC_DCCR_DCRED    0x00FF0000	/* Default Color Red   */
+  #define LTDC_DCCR_DCALPHA  0xFF000000	/* Default Color Alpha */
+#define TOFF_LTDCW_BFCR     0x001C		/* (RW) LTDC Layerx Blending Factors Configuration Register :0xA0 */
+  #define LTDC_BFCR_BF2      0x00000007	/* Blending Factor 2 */
+  #define LTDC_BFCR_BF1      0x00000700	/* Blending Factor 1 */
+#define TOFF_LTDCW_CFBAR    0x0028		/* (RW) LTDC Layerx Color Frame Buffer Address Register :0xAC */
+  #define LTDC_CFBAR_CFBADD  0xFFFFFFFF	/* Color Frame Buffer Start Address */
+#define TOFF_LTDCW_CFBLR    0x002C		/* (RW) LTDC Layerx Color Frame Buffer Length Register :0xB0 */
+  #define LTDC_CFBLR_CFBLL   0x00001FFF	/* Color Frame Buffer Line Length    */
+  #define LTDC_CFBLR_CFBP    0x1FFF0000	/* Color Frame Buffer Pitch in bytes */
+#define TOFF_LTDCW_CFBLNR   0x0030		/* (RW) LTDC Layerx ColorFrame Buffer Line Number Register :0xB4 */
+  #define LTDC_CFBLNR_CFBLNBR 0x000007FF	/* Frame Buffer Line Number */
+#define TOFF_LTDCW_CLUTWR   0x003C		/* (RW) LTDC Layerx CLUT Write Register :0xC0 */
+
+
+/*
+ *  DCMI
+ */
+#define TADR_DCMI_BASE      (AHB2PERIPH_BASE + 0x50000)
+#define TOFF_DCMI_CR        0x0000		/* (RW) DCMI control register 1 */
+#define TOFF_DCMI_SR        0x0004		/* (R)  DCMI status register */
+#define TOFF_DCMI_RISR      0x0008		/* (R)  DCMI raw interrupt status register */
+#define TOFF_DCMI_IER       0x000C		/* (RW) DCMI interrupt enable register */
+#define TOFF_DCMI_MISR      0x0010		/* (RW) DCMI masked interrupt status register */
+#define TOFF_DCMI_ICR       0x0014		/* (RW) DCMI interrupt clear register */
+#define TOFF_DCMI_ESCR      0x0018		/* (RW) DCMI embedded synchronization code register */
+#define TOFF_DCMI_ESUR      0x001C		/* (RW) DCMI embedded synchronization unmask register */
+#define TOFF_DCMI_CWSTRTR   0x0020		/* (RW) DCMI crop window start */
+#define TOFF_DCMI_CWSIZER   0x0024		/* (RW) DCMI crop window size */
+#define TOFF_DCMI_DR        0x0028		/* (RW) DCMI data register */
+
+/*
+ *  CRYPTO PROCESSER
+ */
+#define TADR_CRYP_BASE      (AHB2PERIPH_BASE + 0x60000)
+#define TOFF_CRYP_CR        0x0000		/* (RW) CRYP control register */
+#define TOFF_CRYP_SR        0x0004		/* (R)  CRYP status register */
+#define TOFF_CRYP_DR        0x0008		/* (RW) CRYP data input register */
+#define TOFF_CRYP_DOUT      0x000C		/* (RW) CRYP data output register */
+#define TOFF_CRYP_DMACR     0x0010		/* (RW) CRYP DMA control register */
+#define TOFF_CRYP_IMSCR     0x0014		/* (RW) CRYP interrupt mask set/clear register */
+#define TOFF_CRYP_RISR      0x0018		/* (RW) CRYP raw interrupt status register */
+#define TOFF_CRYP_MISR      0x001C		/* (RW) CRYP masked interrupt status register */
+#define TOFF_CRYP_K0LR      0x0020		/* (RW) CRYP key left  register 0 */
+#define TOFF_CRYP_K0RR      0x0024		/* (RW) CRYP key right register 0 */
+#define TOFF_CRYP_K1LR      0x0028		/* (RW) CRYP key left  register 1 */
+#define TOFF_CRYP_K1RR      0x002C		/* (RW) CRYP key right register 1 */
+#define TOFF_CRYP_K2LR      0x0030		/* (RW) CRYP key left  register 2 */
+#define TOFF_CRYP_K2RR      0x0034		/* (RW) CRYP key right register 2 */
+#define TOFF_CRYP_K3LR      0x0038		/* (RW) CRYP key left  register 3 */
+#define TOFF_CRYP_K3RR      0x003C		/* (RW) CRYP key right register 3 */
+#define TOFF_CRYP_IV0LR     0x0040		/* (RW) CRYP initialization vector left-word  register 0 */
+#define TOFF_CRYP_IV0RR     0x0044		/* (RW) CRYP initialization vector right-word register 0 */
+#define TOFF_CRYP_IV1LR     0x0048		/* (RW) CRYP initialization vector left-word  register 1 */
+#define TOFF_CRYP_IV1RR     0x004C		/* (RW) CRYP initialization vector right-word register 1 */
+#define TOFF_CSGCMCCM0R     0x0050		/* (RW) CRYP GCM/GMAC or CCM/CMAC context swap register 0 */
+#define TOFF_CSGCMCCM1R     0x0054		/* (RW) CRYP GCM/GMAC or CCM/CMAC context swap register 1 */
+#define TOFF_CSGCMCCM2R     0x0058		/* (RW) CRYP GCM/GMAC or CCM/CMAC context swap register 2 */
+#define TOFF_CSGCMCCM3R     0x005C		/* (RW) CRYP GCM/GMAC or CCM/CMAC context swap register 3 */
+#define TOFF_CSGCMCCM4R     0x0060		/* (RW) CRYP GCM/GMAC or CCM/CMAC context swap register 4 */
+#define TOFF_CSGCMCCM5R     0x0064		/* (RW) CRYP GCM/GMAC or CCM/CMAC context swap register 5 */
+#define TOFF_CSGCMCCM6R     0x0068		/* (RW) CRYP GCM/GMAC or CCM/CMAC context swap register 6 */
+#define TOFF_CSGCMCCM7R     0x006C		/* (RW) CRYP GCM/GMAC or CCM/CMAC context swap register 7 */
+#define TOFF_CSGCM0R        0x0070		/* (RW) CRYP GCM/GMAC context swap register */
+#define TOFF_CSGCM1R        0x0074		/* (RW) CRYP GCM/GMAC context swap register */
+#define TOFF_CSGCM2R        0x0078		/* (RW) CRYP GCM/GMAC context swap register */
+#define TOFF_CSGCM3R        0x007C		/* (RW) CRYP GCM/GMAC context swap register */
+#define TOFF_CSGCM4R        0x0080		/* (RW) CRYP GCM/GMAC context swap register */
+#define TOFF_CSGCM5R        0x0084		/* (RW) CRYP GCM/GMAC context swap register */
+#define TOFF_CSGCM6R        0x0088		/* (RW) CRYP GCM/GMAC context swap register */
+#define TOFF_CSGCM7R        0x008C		/* (RW) CRYP GCM/GMAC context swap register */
+
+/*
+ *  HASH
+ */
+#define TADR_HASH_BASE      (AHB2PERIPH_BASE + 0x60400)
+#define TOFF_HASH_CR        0x0000		/* (RW) HASH control register */
+#define TOFF_HASH_DIN       0x0004		/* (RW) HASH data input register */
+#define TOFF_HASH_STR       0x0008		/* (RW) HASH start register */
+#define TOFF_HASH_HR0       0x000C		/* (RW) HASH digest registers 0 */
+#define TOFF_HASH_HR1       0x0010		/* (RW) HASH digest registers 1 */
+#define TOFF_HASH_HR2       0x0014		/* (RW) HASH digest registers 2 */
+#define TOFF_HASH_HR3       0x0018		/* (RW) HASH digest registers 3 */
+#define TOFF_HASH_HR4       0x001C		/* (RW) HASH digest registers 4 */
+#define TOFF_HASH_IMR       0x0020		/* (RW) HASH interrupt enable register */
+#define TOFF_HASH_SR        0x0024		/* (R)  HASH status register */
+#define TOFF_HASH_CSR0      0x00F8		/* (RW) HASH context swap registers 0 */
+#define TOFF_HASH_CSR1      0x00FC		/* (RW) HASH context swap registers 1 */
+#define TOFF_HASH_CSR2      0x0100		/* (RW) HASH context swap registers 2 */
+#define TOFF_HASH_CSR3      0x0104		/* (RW) HASH context swap registers 3 */
+#define TOFF_HASH_CSR4      0x0108		/* (RW) HASH context swap registers 4 */
+#define TOFF_HASH_CSR5      0x010C		/* (RW) HASH context swap registers 5 */
+#define TOFF_HASH_CSR6      0x0110		/* (RW) HASH context swap registers 6 */
+#define TOFF_HASH_CSR7      0x0114		/* (RW) HASH context swap registers 7 */
+#define TOFF_HASH_CSR8      0x0118		/* (RW) HASH context swap registers 8 */
+#define TOFF_HASH_CSR9      0x011C		/* (RW) HASH context swap registers 9 */
+#define TOFF_HASH_CSR10     0x0120		/* (RW) HASH context swap registers 10 */
+#define TOFF_HASH_CSR11     0x0124		/* (RW) HASH context swap registers 11 */
+#define TOFF_HASH_CSR12     0x0128		/* (RW) HASH context swap registers 12 */
+#define TOFF_HASH_CSR13     0x012C		/* (RW) HASH context swap registers 13 */
+#define TOFF_HASH_CSR14     0x0130		/* (RW) HASH context swap registers 14 */
+#define TOFF_HASH_CSR15     0x0134		/* (RW) HASH context swap registers 15 */
+#define TOFF_HASH_CSR16     0x0138		/* (RW) HASH context swap registers 16 */
+#define TOFF_HASH_CSR17     0x013C		/* (RW) HASH context swap registers 17 */
+#define TOFF_HASH_CSR18     0x0140		/* (RW) HASH context swap registers 18 */
+#define TOFF_HASH_CSR19     0x0144		/* (RW) HASH context swap registers 19 */
+#define TOFF_HASH_CSR20     0x0148		/* (RW) HASH context swap registers 20 */
+#define TOFF_HASH_CSR21     0x014C		/* (RW) HASH context swap registers 21 */
+#define TOFF_HASH_CSR22     0x0150		/* (RW) HASH context swap registers 22 */
+#define TOFF_HASH_CSR23     0x0154		/* (RW) HASH context swap registers 23 */
+#define TOFF_HASH_CSR24     0x0158		/* (RW) HASH context swap registers 24 */
+#define TOFF_HASH_CSR25     0x015C		/* (RW) HASH context swap registers 25 */
+#define TOFF_HASH_CSR26     0x0160		/* (RW) HASH context swap registers 26 */
+#define TOFF_HASH_CSR27     0x0164		/* (RW) HASH context swap registers 27 */
+#define TOFF_HASH_CSR28     0x0168		/* (RW) HASH context swap registers 28 */
+#define TOFF_HASH_CSR29     0x016C		/* (RW) HASH context swap registers 29 */
+#define TOFF_HASH_CSR30     0x0170		/* (RW) HASH context swap registers 30 */
+#define TOFF_HASH_CSR31     0x0174		/* (RW) HASH context swap registers 31 */
+#define TOFF_HASH_CSR32     0x0178		/* (RW) HASH context swap registers 32 */
+#define TOFF_HASH_CSR33     0x017C		/* (RW) HASH context swap registers 33 */
+#define TOFF_HASH_CSR34     0x0180		/* (RW) HASH context swap registers 34 */
+#define TOFF_HASH_CSR35     0x0184		/* (RW) HASH context swap registers 35 */
+#define TOFF_HASH_CSR36     0x0188		/* (RW) HASH context swap registers 36 */
+#define TOFF_HASH_CSR37     0x018C		/* (RW) HASH context swap registers 37 */
+#define TOFF_HASH_CSR38     0x0190		/* (RW) HASH context swap registers 38 */
+#define TOFF_HASH_CSR39     0x0194		/* (RW) HASH context swap registers 39 */
+#define TOFF_HASH_CSR40     0x0198		/* (RW) HASH context swap registers 40 */
+#define TOFF_HASH_CSR41     0x019C		/* (RW) HASH context swap registers 41 */
+#define TOFF_HASH_CSR42     0x01A0		/* (RW) HASH context swap registers 42 */
+#define TOFF_HASH_CSR43     0x01A4		/* (RW) HASH context swap registers 43 */
+#define TOFF_HASH_CSR44     0x01A8		/* (RW) HASH context swap registers 44 */
+#define TOFF_HASH_CSR45     0x01AC		/* (RW) HASH context swap registers 45 */
+#define TOFF_HASH_CSR46     0x01B0		/* (RW) HASH context swap registers 46 */
+#define TOFF_HASH_CSR47     0x01B4		/* (RW) HASH context swap registers 47 */
+#define TOFF_HASH_CSR48     0x01B8		/* (RW) HASH context swap registers 48 */
+#define TOFF_HASH_CSR49     0x01BC		/* (RW) HASH context swap registers 49 */
+#define TOFF_HASH_CSR50     0x01C0		/* (RW) HASH context swap registers 50 */
+
+/*
+ *  HASH DIGEST
+ */
+#define TADR_HASHDIGEST_BASE (AHB2PERIPH_BASE + 0x60710)
+#define TOFF_HASHDIGEST_HR0 0x0000		/* (RW) HASH digest registers, Address offset: 0x310-0x32C */
+
+/*
+ *  RNG
+ */
+#define TADR_RNG_BASE       (AHB2PERIPH_BASE + 0x60800)
+#define TOFF_RNG_CR         0x0000		/* (RW) RNG control register */
+#define TOFF_RNG_SR         0x0004		/* (RW) RNG status register */
+#define TOFF_RNG_DR         0x0008		/* (RW) RNG data register */
+
+/*
+ *  FLEXIBLE STATIC MEMORY
+ */
+#define TADR_FMC_R_BASE    (FMC_R_BASE + 0x0000)
+
+/*
+ *  FLEXIBLE MEMORY CONTROLLER
+ */
+#define TOFF_FMC_R_BTCR0    0x0000		/* (RW) NOR/PSRAM chip-select control register(BCR) and chip-select timing register(BTR) 0 */
+  #define FMC_BCR1_MBKEN     0x00000001	/* Memory bank enable bit */
+  #define FMC_BCR1_MUXEN     0x00000002	/* Address/data multiplexing enable bit */
+  #define FMC_BCR1_MTYP      0x0000000C	/* MTYP[1:0] bits (Memory type) */
+  #define FMC_BCR1_MTYP_0    0x00000004
+  #define FMC_BCR1_MTYP_1    0x00000008
+  #define FMC_BCR1_MWID      0x00000030	/* MWID[1:0] bits (Memory data bus width) */
+  #define FMC_BCR1_MWID_0    0x00000010
+  #define FMC_BCR1_MWID_1    0x00000020
+  #define FMC_BCR1_FACCEN    0x00000040	/* Flash access enable */
+  #define FMC_BCR1_BURSTEN   0x00000100	/* Burst enable bit */
+  #define FMC_BCR1_WAITPOL   0x00000200	/* Wait signal polarity bit */
+  #define FMC_BCR1_WRAPMOD   0x00000400	/* Wrapped burst mode support */
+  #define FMC_BCR1_WAITCFG   0x00000800	/* Wait timing configuration */
+  #define FMC_BCR1_WREN      0x00001000	/* Write enable bit */
+  #define FMC_BCR1_WAITEN    0x00002000	/* Wait enable bit */
+  #define FMC_BCR1_EXTMOD    0x00004000	/* Extended mode enable */
+  #define FMC_BCR1_ASYNCWAIT 0x00008000	/* Asynchronous wait */
+  #define FMC_BCR1_CPSIZE    0x00070000	/* CRAM page size */
+  #define FMC_BCR1_CPSIZE_0  0x00010000
+  #define FMC_BCR1_CPSIZE_1  0x00020000
+  #define FMC_BCR1_CPSIZE_2  0x00040000
+  #define FMC_BCR1_CBURSTRW  0x00080000	/* Write burst enable */
+  #define FMC_BCR1_CCLKEN    0x00100000	/* Continous clock enable */
+  #define FMC_BCR1_WFDIS     0x00200000	/* Write FIFO Disable */
+#define TOFF_FMC_R_BTCR1    0x0004		/* (RW) NOR/PSRAM chip-select control register(BCR) and chip-select timing register(BTR) 1 */
+  #define FMC_BTR1_ADDSET    0x0000000F	/* ADDSET[3:0] bits (Address setup phase duration) */
+  #define FMC_BTR1_ADDSET_0  0x00000001
+  #define FMC_BTR1_ADDSET_1  0x00000002
+  #define FMC_BTR1_ADDSET_2  0x00000004
+  #define FMC_BTR1_ADDSET_3  0x00000008
+  #define FMC_BTR1_ADDHLD    0x000000F0	/* ADDHLD[3:0] bits (Address-hold phase duration) */
+  #define FMC_BTR1_ADDHLD_0  0x00000010
+  #define FMC_BTR1_ADDHLD_1  0x00000020
+  #define FMC_BTR1_ADDHLD_2  0x00000040
+  #define FMC_BTR1_ADDHLD_3  0x00000080
+  #define FMC_BTR1_DATAST    0x0000FF00/* DATAST [3:0] bits (Data-phase duration) */
+  #define FMC_BTR1_DATAST_0  0x00000100
+  #define FMC_BTR1_DATAST_1  0x00000200
+  #define FMC_BTR1_DATAST_2  0x00000400
+  #define FMC_BTR1_DATAST_3  0x00000800
+  #define FMC_BTR1_DATAST_4  0x00001000
+  #define FMC_BTR1_DATAST_5  0x00002000
+  #define FMC_BTR1_DATAST_6  0x00004000
+  #define FMC_BTR1_DATAST_7  0x00008000
+  #define FMC_BTR1_BUSTURN   0x000F0000	/* BUSTURN[3:0] bits (Bus turnaround phase duration) */
+  #define FMC_BTR1_BUSTURN_0 0x00010000
+  #define FMC_BTR1_BUSTURN_1 0x00020000
+  #define FMC_BTR1_BUSTURN_2 0x00040000
+  #define FMC_BTR1_BUSTURN_3 0x00080000
+  #define FMC_BTR1_CLKDIV    0x00F00000	/* CLKDIV[3:0] bits (Clock divide ratio) */
+  #define FMC_BTR1_CLKDIV_0  0x00100000
+  #define FMC_BTR1_CLKDIV_1  0x00200000
+  #define FMC_BTR1_CLKDIV_2  0x00400000
+  #define FMC_BTR1_CLKDIV_3  0x00800000
+  #define FMC_BTR1_DATLAT    0x0F000000	/* DATLA[3:0] bits (Data latency) */
+  #define FMC_BTR1_DATLAT_0  0x01000000
+  #define FMC_BTR1_DATLAT_1  0x02000000
+  #define FMC_BTR1_DATLAT_2  0x04000000
+  #define FMC_BTR1_DATLAT_3  0x08000000
+  #define FMC_BTR1_ACCMOD    0x30000000	/* ACCMOD[1:0] bits (Access mode) */
+  #define FMC_BTR1_ACCMOD_0  0x10000000
+  #define FMC_BTR1_ACCMOD_1  0x20000000
+#define TOFF_FMC_R_BTCR2    0x0008		/* (RW) NOR/PSRAM chip-select control register(BCR) and chip-select timing register(BTR) 2 */
+#define TOFF_FMC_R_BTCR3    0x000C		/* (RW) NOR/PSRAM chip-select control register(BCR) and chip-select timing register(BTR) 3 */
+#define TOFF_FMC_R_BTCR4    0x0010		/* (RW) NOR/PSRAM chip-select control register(BCR) and chip-select timing register(BTR) 4 */
+#define TOFF_FMC_R_BTCR5    0x0014		/* (RW) NOR/PSRAM chip-select control register(BCR) and chip-select timing register(BTR) 5 */
+#define TOFF_FMC_R_BTCR6    0x0018		/* (RW) NOR/PSRAM chip-select control register(BCR) and chip-select timing register(BTR) 6 */
+#define TOFF_FMC_R_BTCR7    0x001C		/* (RW) NOR/PSRAM chip-select control register(BCR) and chip-select timing register(BTR) 7 */
+
+/*
+ *  FLEXIBLE MEMORY CONTROLLER BANK1E
+ */
+#define TOFF_FMC_R_BWTR0    0x0104		/* (RW) NOR/PSRAM write timing registers 0 */
+#define TOFF_FMC_R_BWTR1    0x0108		/* (RW) NOR/PSRAM write timing registers 1 */
+#define TOFF_FMC_R_BWTR2    0x010C		/* (RW) NOR/PSRAM write timing registers 2 */
+#define TOFF_FMC_R_BWTR3    0x0110		/* (RW) NOR/PSRAM write timing registers 3 */
+#define TOFF_FMC_R_BWTR4    0x0114		/* (RW) NOR/PSRAM write timing registers 4 */
+#define TOFF_FMC_R_BWTR5    0x0118		/* (RW) NOR/PSRAM write timing registers 5 */
+#define TOFF_FMC_R_BWTR6    0x011C		/* (RW) NOR/PSRAM write timing registers 6 */
+
+/*
+ *  FLEXIBLE MEMORY CONTROLLER BANK3
+ */
+#define TOFF_FMC_R_PCR      0x0080		/* (RW) NAND Flash control register */
+#define TOFF_FMC_R_SR       0x0084		/* (RW) NAND Flash FIFO status and interrupt register */
+#define TOFF_FMC_R_PMEM     0x0088		/* (RW) NAND Flash Common memory space timing register */
+#define TOFF_FMC_R_PATT     0x008C		/* (RW) NAND Flash Attribute memory space timing register */
+#define TOFF_FMC_R_ECCR     0x0090		/* (RW) NAND Flash ECC result registers */
+
+/*
+ *  FLEXIBLE MEMORY CONTROLLER BANK5 6
+ */
+#define TOFF_FMC_R_SDCR0    0x0140		/* (RW) SDRAM Control registers 0 */
+#define TOFF_FMC_R_SDCR1    0x0144		/* (RW) SDRAM Control registers 1 */
+  #define FMC_SDCR1_NC       0x00000003	/* NC[1:0] bits (Number of column bits) */
+  #define FMC_SDCR1_NC_0     0x00000001	/* Bit 0 */
+  #define FMC_SDCR1_NC_1     0x00000002	/* Bit 1 */
+  #define FMC_SDCR1_NR       0x0000000C	/* NR[1:0] bits (Number of row bits) */
+  #define FMC_SDCR1_NR_0     0x00000004	/* Bit 0 */
+  #define FMC_SDCR1_NR_1     0x00000008	/* Bit 1 */
+  #define FMC_SDCR1_MWID     0x00000030	/* NR[1:0] bits (Number of row bits) */
+  #define FMC_SDCR1_MWID_0   0x00000010	/* Bit 0 */
+  #define FMC_SDCR1_MWID_1   0x00000020	/* Bit 1 */
+  #define FMC_SDCR1_NB       0x00000040	/* Number of internal bank */
+  #define FMC_SDCR1_CAS      0x00000180	/* CAS[1:0] bits (CAS latency) */
+  #define FMC_SDCR1_CAS_0    0x00000080	/* Bit 0 */
+  #define FMC_SDCR1_CAS_1    0x00000100	/* Bit 1 */
+  #define FMC_SDCR1_WP       0x00000200	/* Write protection */
+  #define FMC_SDCR1_SDCLK    0x00000C00	/* SDRAM clock configuration */
+  #define FMC_SDCR1_SDCLK_0  0x00000400	/* Bit 0 */
+  #define FMC_SDCR1_SDCLK_1  0x00000800	/* Bit 1 */
+  #define FMC_SDCR1_RBURST   0x00001000	/* Read burst */
+  #define FMC_SDCR1_RPIPE    0x00006000	/* Write protection */
+  #define FMC_SDCR1_RPIPE_0  0x00002000	/* Bit 0 */
+  #define FMC_SDCR1_RPIPE_1  0x00004000	/* Bit 1 */
+#define TOFF_FMC_R_SDTR0    0x0148		/* (RW) SDRAM Timing registers 0 */
+#define TOFF_FMC_R_SDTR1    0x014C		/* (RW) SDRAM Timing registers 1 */
+  #define FMC_SDTR1_TMRD     0x0000000F	/* TMRD[3:0] bits (Load mode register to active) */
+  #define FMC_SDTR1_TMRD_0   0x00000001	/* Bit 0 */
+  #define FMC_SDTR1_TMRD_1   0x00000002	/* Bit 1 */
+  #define FMC_SDTR1_TMRD_2   0x00000004	/* Bit 2 */
+  #define FMC_SDTR1_TMRD_3   0x00000008	/* Bit 3 */
+  #define FMC_SDTR1_TXSR     0x000000F0	/* TXSR[3:0] bits (Exit self refresh) */
+  #define FMC_SDTR1_TXSR_0   0x00000010	/* Bit 0 */
+  #define FMC_SDTR1_TXSR_1   0x00000020	/* Bit 1 */
+  #define FMC_SDTR1_TXSR_2   0x00000040	/* Bit 2 */
+  #define FMC_SDTR1_TXSR_3   0x00000080	/* Bit 3 */
+  #define FMC_SDTR1_TRAS     0x00000F00	/* TRAS[3:0] bits (Self refresh time) */
+  #define FMC_SDTR1_TRAS_0   0x00000100	/* Bit 0 */
+  #define FMC_SDTR1_TRAS_1   0x00000200	/* Bit 1 */
+  #define FMC_SDTR1_TRAS_2   0x00000400	/* Bit 2 */
+  #define FMC_SDTR1_TRAS_3   0x00000800	/* Bit 3 */
+  #define FMC_SDTR1_TRC      0x0000F000	/* TRC[2:0] bits (Row cycle delay) */
+  #define FMC_SDTR1_TRC_0    0x00001000	/* Bit 0 */
+  #define FMC_SDTR1_TRC_1    0x00002000	/* Bit 1 */
+  #define FMC_SDTR1_TRC_2    0x00004000	/* Bit 2 */
+  #define FMC_SDTR1_TWR      0x000F0000	/* TRC[2:0] bits (Write recovery delay) */
+  #define FMC_SDTR1_TWR_0    0x00010000	/* Bit 0 */
+  #define FMC_SDTR1_TWR_1    0x00020000	/* Bit 1 */
+  #define FMC_SDTR1_TWR_2    0x00040000	/* Bit 2 */
+  #define FMC_SDTR1_TRP      0x00F00000	/* TRP[2:0] bits (Row precharge delay) */
+  #define FMC_SDTR1_TRP_0    0x00100000	/* Bit 0 */
+  #define FMC_SDTR1_TRP_1    0x00200000	/* Bit 1 */
+  #define FMC_SDTR1_TRP_2    0x00400000	/* Bit 2 */
+  #define FMC_SDTR1_TRCD     0x0F000000	/* TRP[2:0] bits (Row to column delay) */
+  #define FMC_SDTR1_TRCD_0   0x01000000	/* Bit 0 */
+  #define FMC_SDTR1_TRCD_1   0x02000000	/* Bit 1 */
+  #define FMC_SDTR1_TRCD_2   0x04000000	/* Bit 2 */
+#define TOFF_FMC_R_SDCMR    0x0150		/* (RW) SDRAM Command Mode register */
+  #define FMC_SDCMR_MODE     0x00000007	/* MODE[2:0] bits (Command mode) */
+  #define FMC_SDCMR_MODE_0   0x00000001	/* Bit 0 */
+  #define FMC_SDCMR_MODE_1   0x00000002	/* Bit 1 */
+  #define FMC_SDCMR_MODE_2   0x00000003	/* Bit 2 */
+  #define FMC_SDCMR_CTB2     0x00000008	/* Command target 2 */
+  #define FMC_SDCMR_CTB1     0x00000010	/* Command target 1 */
+  #define FMC_SDCMR_NRFS     0x000001E0	/* NRFS[3:0] bits (Number of auto-refresh) */
+  #define FMC_SDCMR_NRFS_0   0x00000020	/* Bit 0 */
+  #define FMC_SDCMR_NRFS_1   0x00000040	/* Bit 1 */
+  #define FMC_SDCMR_NRFS_2   0x00000080	/* Bit 2 */
+  #define FMC_SDCMR_NRFS_3   0x00000100	/* Bit 3 */
+  #define FMC_SDCMR_MRD      0x003FFE00	/* MRD[12:0] bits (Mode register definition) */
+#define TOFF_FMC_R_SDRTR    0x0154		/* (RW) SDRAM Refresh Timer register */
+#define TOFF_FMC_R_SDSR     0x0158		/* (RW) SDRAM Status register */
+  #define FMC_SDSR_RE        0x00000001	/* Refresh error flag */
+  #define FMC_SDSR_MODES1    0x00000006	/* MODES1[1:0]bits (Status mode for bank 1) */
+  #define FMC_SDSR_MODES1_0  0x00000002	/* Bit 0 */
+  #define FMC_SDSR_MODES1_1  0x00000004	/* Bit 1 */
+  #define FMC_SDSR_MODES2    0x00000018	/* MODES2[1:0]bits (Status mode for bank 2) */
+  #define FMC_SDSR_MODES2_0  0x00000008	/* Bit 0 */
+  #define FMC_SDSR_MODES2_1  0x00000010	/* Bit 1 */
+  #define FMC_SDSR_BUSY      0x00000020	/* Busy status */
+
+
+/*
+ * QUAD SERIAL PERIPHERAL INTERFACE
+ */
+#define TADR_QSPI_R_BASE    (QSPI_R_BASE)
+#define TOFF_QUADSPI_CR     0x0000		/* (RW) QUADSPI Control register */
+  #define QUADSPI_CR_EN         0x00000001	/* Enable */
+  #define QUADSPI_CR_ABORT      0x00000002	/* Abort request */
+  #define QUADSPI_CR_DMAEN      0x00000004	/* DMA Enable */
+  #define QUADSPI_CR_TCEN       0x00000008	/* Timeout Counter Enable */
+  #define QUADSPI_CR_SSHIFT     0x00000010	/* Sample Shift */
+  #define QUADSPI_CR_DFM        0x00000040	/* Dual Flash Mode */
+  #define QUADSPI_CR_FSEL       0x00000080	/* Flash Select */
+  #define QUADSPI_CR_FTHRES     0x00001F00	/* FTHRES[4:0] FIFO Level */
+  #define QUADSPI_CR_TEIE       0x00010000	/* Transfer Error Interrupt Enable */
+  #define QUADSPI_CR_TCIE       0x00020000	/* Transfer Complete Interrupt Enable */
+  #define QUADSPI_CR_FTIE       0x00040000	/* FIFO Threshold Interrupt Enable */
+  #define QUADSPI_CR_SMIE       0x00080000	/* Status Match Interrupt Enable */
+  #define QUADSPI_CR_TOIE       0x00100000	/* TimeOut Interrupt Enable */
+  #define QUADSPI_CR_APMS       0x00400000	/* Automatic Polling Mode Stop */
+  #define QUADSPI_CR_PMM        0x00800000	/* Polling Match Mode */
+  #define QUADSPI_CR_PRESCALER  0xFF000000	/* PRESCALER[7:0] Clock prescaler */
+#define TOFF_QUADSPI_DCR    0x0004		/* (RW) QUADSPI Device Configuration register */
+  #define QUADSPI_DCR_CKMODE    0x00000001	/* Mode 0 / Mode 3 */
+  #define QUADSPI_DCR_CSHT      0x00000700	/* CSHT[2:0]: ChipSelect High Time */
+  #define QUADSPI_DCR_CSHT_0    0x00000100
+  #define QUADSPI_DCR_CSHT_1    0x00000200
+  #define QUADSPI_DCR_CSHT_2    0x00000400
+  #define QUADSPI_DCR_FSIZE     0x001F0000	/* FSIZE[4:0]: Flash Size */
+#define TOFF_QUADSPI_SR     0x0008		/* (RW) QUADSPI Status register */
+  #define QUADSPI_SR_TEF        0x00000001	/* Transfer Error Flag */
+  #define QUADSPI_SR_TCF        0x00000002	/* Transfer Complete Flag */
+  #define QUADSPI_SR_FTF        0x00000004	/* FIFO Threshlod Flag */
+  #define QUADSPI_SR_SMF        0x00000008	/* Status Match Flag */
+  #define QUADSPI_SR_TOF        0x00000010	/* Timeout Flag */
+  #define QUADSPI_SR_BUSY       0x00000020	/* Busy */
+  #define QUADSPI_SR_FLEVEL     0x00001F00	/* FIFO Threshlod Flag */
+#define TOFF_QUADSPI_FCR    0x000C		/* (W)  QUADSPI Flag Clear register */
+  #define QUADSPI_FCR_CTEF      0x00000001	/* Clear Transfer Error Flag */
+  #define QUADSPI_FCR_CTCF      0x00000002	/* Clear Transfer Complete Flag */
+  #define QUADSPI_FCR_CSMF      0x00000008	/* Clear Status Match Flag */
+  #define QUADSPI_FCR_CTOF      0x00000010	/* Clear Timeout Flag */
+#define TOFF_QUADSPI_DLR    0x0010		/* (RW) QUADSPI Data Length register */
+#define TOFF_QUADSPI_CCR    0x0014		/* (RW) QUADSPI Communication Configuration register */
+  #define QUADSPI_CCR_INSTRUCTION 0x000000FF	/* INSTRUCTION[7:0]: Instruction */
+  #define QUADSPI_CCR_IMODE     0x00000300	/* IMODE[1:0]: Instruction Mode */
+  #define QUADSPI_CCR_IMODE_0   0x00000100
+  #define QUADSPI_CCR_IMODE_1   0x00000200
+  #define QUADSPI_CCR_ADMODE    0x00000C00	/* ADMODE[1:0]: Address Mode */
+  #define QUADSPI_CCR_ADMODE_0  0x00000400
+  #define QUADSPI_CCR_ADMODE_1  0x00000800
+  #define QUADSPI_CCR_ADSIZE    0x00003000	/* ADSIZE[1:0]: Address Size */
+  #define QUADSPI_CCR_ADSIZE_0  0x00001000
+  #define QUADSPI_CCR_ADSIZE_1  0x00002000
+  #define QUADSPI_CCR_ABMODE    0x0000C000	/* ABMODE[1:0]: Alternate Bytes Mode */
+  #define QUADSPI_CCR_ABMODE_0  0x00004000
+  #define QUADSPI_CCR_ABMODE_1  0x00008000
+  #define QUADSPI_CCR_ABSIZE    0x00030000	/* ABSIZE[1:0]: Instruction Mode */
+  #define QUADSPI_CCR_ABSIZE_0  0x00010000
+  #define QUADSPI_CCR_ABSIZE_1  0x00020000
+  #define QUADSPI_CCR_DCYC      0x007C0000	/* DCYC[4:0]: Dummy Cycles */
+  #define QUADSPI_CCR_DMODE     0x03000000	/* DMODE[1:0]: Data Mode */
+  #define QUADSPI_CCR_DMODE_0   0x01000000
+  #define QUADSPI_CCR_DMODE_1   0x02000000
+  #define QUADSPI_CCR_FMODE     0x0C000000	/* FMODE[1:0]: Functional Mode */
+  #define QUADSPI_CCR_FMODE_0   0x04000000
+  #define QUADSPI_CCR_FMODE_1   0x08000000
+  #define QUADSPI_CCR_SIOO      0x10000000	/* SIOO: Send Instruction Only Once Mode */
+  #define QUADSPI_CCR_DHHC      0x40000000	/* DHHC: Delay Half Hclk Cycle           */
+  #define QUADSPI_CCR_DDRM      0x80000000	/* DDRM: Double Data Rate Mode */
+#define TOFF_QUADSPI_AR     0x0018		/* (RW) QUADSPI Address register */
+#define TOFF_QUADSPI_ABR    0x001C		/* (RW) QUADSPI Alternate Bytes register */
+#define TOFF_QUADSPI_DR     0x0020		/* (RW) QUADSPI Data register */
+#define TOFF_QUADSPI_PSMKR  0x0024		/* (RW) QUADSPI Polling Status Mask register */
+#define TOFF_QUADSPI_PSMAR  0x0028		/* (RW) QUADSPI Polling Status Match register */
+#define TOFF_QUADSPI_PIR    0x002C		/* (RW) QUADSPI Polling Interval register */
+  #define QUADSPI_PIR_INTERVAL  0x0000FFFF	/* INTERVAL[15:0]: Polling Interval */
+#define TOFF_QUADSPI_LPTR   0x0030		/* (RW) QUADSPI Low Power Timeout register */
+  #define QUADSPI_LPTR_TIMEOUT  0x0000FFFF	/* TIMEOUT[15:0]: Timeout period */
+
+
+/*
+ *  DEBUG MCU
+ */
+#define TADR_DBGMCU_BASE    0xE0042000
+#define TOFF_DBGMCU_IDCODE  0x0000		/* (RW) MCU device ID code */
+#define TOFF_DBGMCU_CR      0x0004		/* (RW) Debug MCU configuration register */
+#define TOFF_DBGMCU_APB1FZ  0x0008		/* (RW) Debug MCU APB1 freeze register */
+#define TOFF_DBGMCU_APB2FZ  0x000C		/* (RW) Debug MCU APB2 freeze register */
+
+
+/*
+ *  USB OTG REGISTERS BASE ADDRESS
+ */
+#define TADR_USB_OTGHS_BASE     USB_OTG_HS_PERIPH_BASE
+#define TADR_USB_OTGFS_BASE     USB_OTG_FS_PERIPH_BASE
+#define TOFF_USBO_GOTGCTL   0x0000		/* (RW) USB_OTG Control and Status Register */
+  #define USB_OTG_GOTGCTL_SRQSCS    0x00000001	/* Session request success */
+  #define USB_OTG_GOTGCTL_SRQ       0x00000002	/* Session request */
+  #define USB_OTG_GOTGCTL_VBVALOEN  0x00000004	/* VBUS valid override enable */
+  #define USB_OTG_GOTGCTL_VBVALOVAL 0x00000008	/* VBUS valid override value */
+  #define USB_OTG_GOTGCTL_AVALOEN   0x00000010	/* A-peripheral session valid override enable */
+  #define USB_OTG_GOTGCTL_AVALOVAL  0x00000020	/* A-peripheral session valid override value */
+  #define USB_OTG_GOTGCTL_BVALOEN   0x00000040	/* B-peripheral session valid override enable */
+  #define USB_OTG_GOTGCTL_BVALOVAL  0x00000080	/* B-peripheral session valid override value  */
+  #define USB_OTG_GOTGCTL_HNGSCS    0x00000100	/* Host negotiation success */
+  #define USB_OTG_GOTGCTL_HNPRQ     0x00000200	/* HNP request */
+  #define USB_OTG_GOTGCTL_HSHNPEN   0x00000400	/* Host set HNP enable */
+  #define USB_OTG_GOTGCTL_DHNPEN    0x00000800	/* Device HNP enabled */
+  #define USB_OTG_GOTGCTL_EHEN      0x00001000	/* Embedded host enable */
+  #define USB_OTG_GOTGCTL_CIDSTS    0x00010000	/* Connector ID status */
+  #define USB_OTG_GOTGCTL_DBCT      0x00020000	/* Long/short debounce time */
+  #define USB_OTG_GOTGCTL_ASVLD     0x00040000	/* A-session valid */
+  #define USB_OTG_GOTGCTL_BSVLD     0x00080000	/* B-session valid */
+  #define USB_OTG_GOTGCTL_OTGVER    0x00100000	/* OTG version  */
+#define TOFF_USBO_GOTGINT   0x0004		/* (RW) USB_OTG Interrupt Register */
+  #define USB_OTG_GOTGINT_SEDET     0x00000004	/* Session end detected */
+  #define USB_OTG_GOTGINT_SRSSCHG   0x00000100	/* Session request success status change */
+  #define USB_OTG_GOTGINT_HNSSCHG   0x00000200	/* Host negotiation success status change */
+  #define USB_OTG_GOTGINT_HNGDET    0x00020000	/* Host negotiation detected */
+  #define USB_OTG_GOTGINT_ADTOCHG   0x00040000	/* A-device timeout change */
+  #define USB_OTG_GOTGINT_DBCDNE    0x00080000	/* Debounce done */
+  #define USB_OTG_GOTGINT_IDCHNG    0x00100000	/* Change in ID pin input value */
+#define TOFF_USBO_GAHBCFG   0x0008		/* (RW) Core AHB Configuration Register */
+  #define USB_OTG_GAHBCFG_GINT      0x00000001	/* Global interrupt mask */
+  #define USB_OTG_GAHBCFG_HBSTLEN   0x0000001E	/* Burst length/type */
+  #define USB_OTG_GAHBCFG_HBSTLEN_0 0x00000002	/* Bit 0 */
+  #define USB_OTG_GAHBCFG_HBSTLEN_1 0x00000004	/* Bit 1 */
+  #define USB_OTG_GAHBCFG_HBSTLEN_2 0x00000008	/* Bit 2 */
+  #define USB_OTG_GAHBCFG_HBSTLEN_3 0x00000010	/* Bit 3 */
+  #define USB_OTG_GAHBCFG_DMAEN     0x00000020	/* DMA enable */
+  #define USB_OTG_GAHBCFG_TXFELVL   0x00000080	/* TxFIFO empty level */
+  #define USB_OTG_GAHBCFG_PTXFELVL  0x00000100	/* Periodic TxFIFO empty level */
+#define TOFF_USBO_GUSBCFG   0x000C		/* (RW) Core USB Configuration Register */
+  #define USB_OTG_GUSBCFG_TOCAL     0x00000007	/* FS timeout calibration */
+  #define USB_OTG_GUSBCFG_TOCAL_0   0x00000001	/* Bit 0 */
+  #define USB_OTG_GUSBCFG_TOCAL_1   0x00000002	/* Bit 1 */
+  #define USB_OTG_GUSBCFG_TOCAL_2   0x00000004	/* Bit 2 */
+  #define USB_OTG_GUSBCFG_PHYSEL    0x00000040	/* USB 2.0 high-speed ULPI PHY or USB 1.1 full-speed serial transceiver select */
+  #define USB_OTG_GUSBCFG_SRPCAP    0x00000100	/* SRP-capable */
+  #define USB_OTG_GUSBCFG_HNPCAP    0x00000200	/* HNP-capable */
+  #define USB_OTG_GUSBCFG_TRDT      0x00003C00	/* USB turnaround time */
+  #define USB_OTG_GUSBCFG_TRDT_0    0x00000400	/* Bit 0 */
+  #define USB_OTG_GUSBCFG_TRDT_1    0x00000800	/* Bit 1 */
+  #define USB_OTG_GUSBCFG_TRDT_2    0x00001000	/* Bit 2 */
+  #define USB_OTG_GUSBCFG_TRDT_3    0x00002000	/* Bit 3 */
+  #define USB_OTG_GUSBCFG_PHYLPCS   0x00008000	/* PHY Low-power clock select */
+  #define USB_OTG_GUSBCFG_ULPIFSLS  0x00020000	/* ULPI FS/LS select */
+  #define USB_OTG_GUSBCFG_ULPIAR    0x00040000	/* ULPI Auto-resume */
+  #define USB_OTG_GUSBCFG_ULPICSM   0x00080000	/* ULPI Clock SuspendM */
+  #define USB_OTG_GUSBCFG_ULPIEVBUSD 0x00100000	/* ULPI External VBUS Drive */
+  #define USB_OTG_GUSBCFG_ULPIEVBUSI 0x00200000	/* ULPI external VBUS indicator */
+  #define USB_OTG_GUSBCFG_TSDPS     0x00400000	/* TermSel DLine pulsing selection */
+  #define USB_OTG_GUSBCFG_PCCI      0x00800000	/* Indicator complement */
+  #define USB_OTG_GUSBCFG_PTCI      0x01000000	/* Indicator pass through */
+  #define USB_OTG_GUSBCFG_ULPIIPD   0x02000000	/* ULPI interface protect disable */
+  #define USB_OTG_GUSBCFG_FHMOD     0x20000000	/* Forced host mode */
+  #define USB_OTG_GUSBCFG_FDMOD     0x40000000	/* Forced peripheral mode */
+  #define USB_OTG_GUSBCFG_CTXPKT    0x80000000	/* Corrupt Tx packet */
+#define TOFF_USBO_GRSTCTL   0x0010		/* (RW) Core Reset Register */
+  #define USB_OTG_GRSTCTL_CSRST     0x00000001	/* Core soft reset */
+  #define USB_OTG_GRSTCTL_HSRST     0x00000002	/* HCLK soft reset */
+  #define USB_OTG_GRSTCTL_FCRST     0x00000004	/* Host frame counter reset */
+  #define USB_OTG_GRSTCTL_RXFFLSH   0x00000010	/* RxFIFO flush */
+  #define USB_OTG_GRSTCTL_TXFFLSH   0x00000020	/* TxFIFO flush */
+  #define USB_OTG_GRSTCTL_TXFNUM    0x000007C0	/* TxFIFO number */
+  #define USB_OTG_GRSTCTL_TXFNUM_0  0x00000040	/* Bit 0 */
+  #define USB_OTG_GRSTCTL_TXFNUM_1  0x00000080	/* Bit 1 */
+  #define USB_OTG_GRSTCTL_TXFNUM_2  0x00000100	/* Bit 2 */
+  #define USB_OTG_GRSTCTL_TXFNUM_3  0x00000200	/* Bit 3 */
+  #define USB_OTG_GRSTCTL_TXFNUM_4  0x00000400	/* Bit 4 */
+  #define USB_OTG_GRSTCTL_DMAREQ    0x40000000	/* DMA request signal */
+  #define USB_OTG_GRSTCTL_AHBIDL    0x80000000	/* AHB master idle */
+#define TOFF_USBO_GINTSTS   0x0014		/* (RW)  Core Interrupt Register */
+  #define USB_OTG_GINTSTS_CMOD      0x00000001	/* Current mode of operation */
+  #define USB_OTG_GINTSTS_MMIS      0x00000002	/* Mode mismatch interrupt */
+  #define USB_OTG_GINTSTS_OTGINT    0x00000004	/* OTG interrupt */
+  #define USB_OTG_GINTSTS_SOF       0x00000008	/* Start of frame */
+  #define USB_OTG_GINTSTS_RXFLVL    0x00000010	/* RxFIFO nonempty */
+  #define USB_OTG_GINTSTS_NPTXFE    0x00000020	/* Nonperiodic TxFIFO empty */
+  #define USB_OTG_GINTSTS_GINAKEFF  0x00000040	/* Global IN nonperiodic NAK effective */
+  #define USB_OTG_GINTSTS_BOUTNAKEFF 0x00000080	/* Global OUT NAK effective */
+  #define USB_OTG_GINTSTS_ESUSP     0x00000400	/* Early suspend */
+  #define USB_OTG_GINTSTS_USBSUSP   0x00000800	/* USB suspend */
+  #define USB_OTG_GINTSTS_USBRST    0x00001000	/* USB reset */
+  #define USB_OTG_GINTSTS_ENUMDNE   0x00002000	/* Enumeration done */
+  #define USB_OTG_GINTSTS_ISOODRP   0x00004000	/* Isochronous OUT packet dropped interrupt */
+  #define USB_OTG_GINTSTS_EOPF      0x00008000	/* End of periodic frame interrupt */
+  #define USB_OTG_GINTSTS_IEPINT    0x00040000	/* IN endpoint interrupt */
+  #define USB_OTG_GINTSTS_OEPINT    0x00080000	/* OUT endpoint interrupt */
+  #define USB_OTG_GINTSTS_IISOIXFR  0x00100000	/* Incomplete isochronous IN transfer */
+  #define USB_OTG_GINTSTS_PXFR_INCOMPISOOUT 0x00200000	/* Incomplete periodic transfer */
+  #define USB_OTG_GINTSTS_DATAFSUSP 0x00400000	/* Data fetch suspended */
+  #define USB_OTG_GINTSTS_HPRTINT   0x01000000	/* Host port interrupt */
+  #define USB_OTG_GINTSTS_HCINT     0x02000000	/* Host channels interrupt */
+  #define USB_OTG_GINTSTS_PTXFE     0x04000000	/* Periodic TxFIFO empty */
+  #define USB_OTG_GINTSTS_LPMINT    0x08000000	/* LPM interrupt                                  */
+  #define USB_OTG_GINTSTS_CIDSCHG   0x10000000	/* Connector ID status change */
+  #define USB_OTG_GINTSTS_DISCINT   0x20000000	/* Disconnect detected interrupt */
+  #define USB_OTG_GINTSTS_SRQINT    0x40000000	/* Session request/new session detected interrupt */
+  #define USB_OTG_GINTSTS_WKUINT    0x80000000	/* Resume/remote wakeup detected interrupt */
+#define TOFF_USBO_GINTMSK   0x0018		/* (RW)  Core Interrupt Mask Register */
+  #define USB_OTG_GINTMSK_MMISM     0x00000002	/* Mode mismatch interrupt mask */
+  #define USB_OTG_GINTMSK_OTGINT    0x00000004	/* OTG interrupt mask */
+  #define USB_OTG_GINTMSK_SOFM      0x00000008	/* Start of frame mask */
+  #define USB_OTG_GINTMSK_RXFLVLM   0x00000010	/* Receive FIFO nonempty mask */
+  #define USB_OTG_GINTMSK_NPTXFEM   0x00000020	/* Nonperiodic TxFIFO empty mask */
+  #define USB_OTG_GINTMSK_GINAKEFFM 0x00000040	/* Global nonperiodic IN NAK effective mask */
+  #define USB_OTG_GINTMSK_GONAKEFFM 0x00000080	/* Global OUT NAK effective mask */
+  #define USB_OTG_GINTMSK_ESUSPM    0x00000400	/* Early suspend mask */
+  #define USB_OTG_GINTMSK_USBSUSPM  0x00000800	/* USB suspend mask */
+  #define USB_OTG_GINTMSK_USBRST    0x00001000	/* USB reset mask */
+  #define USB_OTG_GINTMSK_ENUMDNEM  0x00002000	/* Enumeration done mask */
+  #define USB_OTG_GINTMSK_ISOODRPM  0x00004000	/* Isochronous OUT packet dropped interrupt mask */
+  #define USB_OTG_GINTMSK_EOPFM     0x00008000	/* End of periodic frame interrupt mask */
+  #define USB_OTG_GINTMSK_EPMISM    0x00020000	/* Endpoint mismatch interrupt mask */
+  #define USB_OTG_GINTMSK_IEPINT    0x00040000	/* IN endpoints interrupt mask */
+  #define USB_OTG_GINTMSK_OEPINT    0x00080000	/* OUT endpoints interrupt mask */
+  #define USB_OTG_GINTMSK_IISOIXFRM 0x00100000	/* Incomplete isochronous IN transfer mask */
+  #define USB_OTG_GINTMSK_PXFRM_IISOOXFRM 0x00200000	/* Incomplete periodic transfer mask */
+  #define USB_OTG_GINTMSK_FSUSPM    0x00400000	/* Data fetch suspended mask */
+  #define USB_OTG_GINTMSK_RSTDEM    0x00800000	/* Reset detected interrupt mask */
+  #define USB_OTG_GINTMSK_PRTIM     0x01000000	/* Host port interrupt mask */
+  #define USB_OTG_GINTMSK_HCIM      0x02000000	/* Host channels interrupt mask */
+  #define USB_OTG_GINTMSK_PTXFEM    0x04000000	/* Periodic TxFIFO empty mask */
+  #define USB_OTG_GINTMSK_LPMINTM   0x08000000	/* LPM interrupt Mask */
+  #define USB_OTG_GINTMSK_CIDSCHGM  0x10000000	/* Connector ID status change mask */
+  #define USB_OTG_GINTMSK_DISCINT   0x20000000	/* Disconnect detected interrupt mask */
+  #define USB_OTG_GINTMSK_SRQIM     0x40000000	/* Session request/new session detected interrupt mask */
+  #define USB_OTG_GINTMSK_WUIM      0x80000000	/* Resume/remote wakeup detected interrupt mask */
+#define TOFF_USBO_GRXSTSR   0x001C		/* (RW) Receive Sts Q Read Register */
+#define TOFF_USBO_GRXSTSP   0x0020		/* (RW) Receive Sts Q Read & POP Register */
+  #define USB_OTG_GRXSTSP_EPNUM     0x0000000F	/* IN EP interrupt mask bits */
+  #define USB_OTG_GRXSTSP_BCNT      0x00007FF0	/* OUT EP interrupt mask bits */
+  #define USB_OTG_GRXSTSP_DPID      0x00018000	/* OUT EP interrupt mask bits */
+  #define USB_OTG_GRXSTSP_PKTSTS    0x001E0000	/* OUT EP interrupt mask bits */
+#define TOFF_USBO_GRXFSIZ   0x0024		/* (RW) Receive FIFO Size Register */
+  #define USB_OTG_GRXFSIZ_RXFD      0x0000FFFF	/* RxFIFO depth */
+#define TOFF_USBO_DIEPTXF0_HNPTXFSIZ 0x0028	/* (RW) EP0 / Non Periodic Tx FIFO Size Register */
+  #define USB_OTG_NPTXFSA           0x0000FFFF	/* Nonperiodic transmit RAM start address */
+  #define USB_OTG_NPTXFD            0xFFFF0000	/* Nonperiodic TxFIFO depth */
+  #define USB_OTG_TX0FSA            0x0000FFFF	/* Endpoint 0 transmit RAM start address */
+  #define USB_OTG_TX0FD             0xFFFF0000	/* Endpoint 0 TxFIFO depth */
+#define TOFF_USBO_HNPTXSTS  0x002C		/* (RW) Non Periodic Tx FIFO/Queue Sts Register */
+#define TOFF_USBO_GCCFG     0x0038		/* (RW) General Purpose IO Register */
+  #define USB_OTG_GCCFG_PWRDWN      0x00010000	/* Power down */
+  #define USB_OTG_GCCFG_VBDEN       0x00200000	/* USB VBUS Detection Enable */
+#define TOFF_USBO_CID       0x003C		/* (RW) User ID Register */
+  #define USB_OTG_CID_PRODUCT_ID    0xFFFFFFFF	/* Product ID field */
+#define TOFF_USBO_GHWCFG3   0x004C		/* (RW) User HW config3 */
+#define TOFF_USBO_GLPMCFG   0x0054		/* (RW) LPM Register */
+  #define USB_OTG_GLPMCFG_LPMEN     0x00000001	/* LPM support enable                                     */
+  #define USB_OTG_GLPMCFG_LPMACK    0x00000002	/* LPM Token acknowledge enable                           */
+  #define USB_OTG_GLPMCFG_BESL      0x0000003C	/* BESL value received with last ACKed LPM Token          */
+  #define USB_OTG_GLPMCFG_REMWAKE   0x00000040	/* bRemoteWake value received with last ACKed LPM Token   */
+  #define USB_OTG_GLPMCFG_L1SSEN    0x00000080	/* L1 shallow sleep enable                                */
+  #define USB_OTG_GLPMCFG_BESLTHRS  0x00000F00	/* BESL threshold                                         */
+  #define USB_OTG_GLPMCFG_L1DSEN    0x00001000	/* L1 deep sleep enable                                   */
+  #define USB_OTG_GLPMCFG_LPMRSP    0x00006000	/* LPM response                                           */
+  #define USB_OTG_GLPMCFG_SLPSTS    0x00008000	/* Port sleep status                                      */
+  #define USB_OTG_GLPMCFG_L1RSMOK   0x00010000	/* Sleep State Resume OK                                  */
+  #define USB_OTG_GLPMCFG_LPMCHIDX  0x001E0000	/* LPM Channel Index                                      */
+  #define USB_OTG_GLPMCFG_LPMRCNT   0x00E00000	/* LPM retry count                                        */
+  #define USB_OTG_GLPMCFG_SNDLPM    0x01000000	/* Send LPM transaction                                   */
+  #define USB_OTG_GLPMCFG_LPMRCNTSTS 0x0E000000	/* LPM retry count status                                 */
+  #define USB_OTG_GLPMCFG_ENBESL    0x10000000	/* Enable best effort service latency                     */
+#define TOFF_USBO_GPWRDN    0x0058		/* (RW) Power Down Register */
+  #define USB_OTG_GPWRDN_ADPMEN     0x00000001	/* ADP module enable */
+  #define USB_OTG_GPWRDN_ADPIF      0x00800000	/* ADP Interrupt flag */
+#define TOFF_USBO_GDFIFOCFG 0x005C		/* (RW) DFIFO Software Config Register */
+#define TOFF_USBO_GADPCTL   0x0060		/* (RW) ADP Timer, Control and Status Register */
+#define TOFF_USBO_HPTXFSIZ  0x0100		/* (RW) Host Periodic Tx FIFO Size Reg */
+  #define USB_OTG_HPTXFSIZ_PTXSA    0x0000FFFF	/* Host periodic TxFIFO start address */
+  #define USB_OTG_HPTXFSIZ_PTXFD    0xFFFF0000	/* Host periodic TxFIFO depth */
+#define TOFF_USBO_DIEPTXF   0x0104		/* (RW) dev Periodic Transmit FIFO x 15 */
+  #define USB_OTG_DIEPTXF_INEPTXSA  0x0000FFFF	/* IN endpoint FIFOx transmit RAM start address */
+  #define USB_OTG_DIEPTXF_INEPTXFD  0xFFFF0000	/* IN endpoint TxFIFO depth */
+
+/*
+ *  USB DEVICE(OTG)
+ */
+#define TADR_USB_DEVICE_BASE (USB_OTG_FS_PERIPH_BASE+USB_OTG_DEVICE_BASE)
+#define TOFF_USBD_DCFG      0x0000		/* (RW) dev Configuration Register */
+  #define USB_OTG_DCFG_DSPD         0x00000003	/* Device speed */
+  #define USB_OTG_DCFG_DSPD_0       0x00000001	/* Bit 0 */
+  #define USB_OTG_DCFG_DSPD_1       0x00000002	/* Bit 1 */
+  #define USB_OTG_DCFG_NZLSOHSK     0x00000004	/* Nonzero-length status OUT handshake */
+  #define USB_OTG_DCFG_DAD          0x000007F0	/* Device address */
+  #define USB_OTG_DCFG_DAD_0        0x00000010	/* Bit 0 */
+  #define USB_OTG_DCFG_DAD_1        0x00000020	/* Bit 1 */
+  #define USB_OTG_DCFG_DAD_2        0x00000040	/* Bit 2 */
+  #define USB_OTG_DCFG_DAD_3        0x00000080	/* Bit 3 */
+  #define USB_OTG_DCFG_DAD_4        0x00000100	/* Bit 4 */
+  #define USB_OTG_DCFG_DAD_5        0x00000200	/* Bit 5 */
+  #define USB_OTG_DCFG_DAD_6        0x00000400	/* Bit 6 */
+  #define USB_OTG_DCFG_PFIVL        0x00001800	/* Periodic (micro)frame interval */
+  #define USB_OTG_DCFG_PFIVL_0      0x00000800	/* Bit 0 */
+  #define USB_OTG_DCFG_PFIVL_1      0x00001000	/* Bit 1 */
+  #define USB_OTG_DCFG_PERSCHIVL    0x03000000	/* Periodic scheduling interval */
+  #define USB_OTG_DCFG_PERSCHIVL_0  0x01000000	/* Bit 0 */
+  #define USB_OTG_DCFG_PERSCHIVL_1  0x02000000	/* Bit 1 */
+#define TOFF_USBD_DCTL      0x0004		/* (RW) dev Control Register */
+  #define USB_OTG_DCTL_RWUSIG       0x00000001	/* Remote wakeup signaling */
+  #define USB_OTG_DCTL_SDIS         0x00000002	/* Soft disconnect */
+  #define USB_OTG_DCTL_GINSTS       0x00000004	/* Global IN NAK status */
+  #define USB_OTG_DCTL_GONSTS       0x00000008	/* Global OUT NAK status */
+  #define USB_OTG_DCTL_TCTL         0x00000070	/* Test control */
+  #define USB_OTG_DCTL_TCTL_0       0x00000010	/* Bit 0 */
+  #define USB_OTG_DCTL_TCTL_1       0x00000020	/* Bit 1 */
+  #define USB_OTG_DCTL_TCTL_2       0x00000040	/* Bit 2 */
+  #define USB_OTG_DCTL_SGINAK       0x00000080	/* Set global IN NAK */
+  #define USB_OTG_DCTL_CGINAK       0x00000100	/* Clear global IN NAK */
+  #define USB_OTG_DCTL_SGONAK       0x00000200	/* Set global OUT NAK */
+  #define USB_OTG_DCTL_CGONAK       0x00000400	/* Clear global OUT NAK */
+  #define USB_OTG_DCTL_POPRGDNE     0x00000800	/* Power-on programming done */
+#define TOFF_USBD_DSTS      0x0008		/* (RO) dev Status Register (RO) */
+  #define USB_OTG_DSTS_SUSPSTS      0x00000001	/* Suspend status */
+  #define USB_OTG_DSTS_ENUMSPD      0x00000006	/* Enumerated speed */
+  #define USB_OTG_DSTS_ENUMSPD_0    0x00000002	/* Bit 0 */
+  #define USB_OTG_DSTS_ENUMSPD_1    0x00000004	/* Bit 1 */
+  #define USB_OTG_DSTS_EERR         0x00000008	/* Erratic error */
+  #define USB_OTG_DSTS_FNSOF        0x003FFF00	/* Frame number of the received SOF */
+#define TOFF_USBD_DIEPMSK   0x0010		/* (RW) dev IN Endpoint Mask */
+  #define USB_OTG_DIEPMSK_XFRCM     0x00000001	/* Transfer completed interrupt mask */
+  #define USB_OTG_DIEPMSK_EPDM      0x00000002	/* Endpoint disabled interrupt mask */
+  #define USB_OTG_DIEPMSK_TOM       0x00000008	/* Timeout condition mask (nonisochronous endpoints) */
+  #define USB_OTG_DIEPMSK_ITTXFEMSK 0x00000010	/* IN token received when TxFIFO empty mask */
+  #define USB_OTG_DIEPMSK_INEPNMM   0x00000020	/* IN token received with EP mismatch mask */
+  #define USB_OTG_DIEPMSK_INEPNEM   0x00000040	/* IN endpoint NAK effective mask */
+  #define USB_OTG_DIEPMSK_TXFURM    0x00000100	/* FIFO underrun mask */
+  #define USB_OTG_DIEPMSK_BIM       0x00000200	/* BNA interrupt mask */
+#define TOFF_USBD_DOEPMSK   0x0014		/* (RW) dev OUT Endpoint Mask */
+  #define USB_OTG_DOEPMSK_XFRCM     0x00000001	/* Transfer completed interrupt mask */
+  #define USB_OTG_DOEPMSK_EPDM      0x00000002	/* Endpoint disabled interrupt mask */
+  #define USB_OTG_DOEPMSK_STUPM     0x00000008	/* SETUP phase done mask */
+  #define USB_OTG_DOEPMSK_OTEPDM    0x00000010	/* OUT token received when endpoint disabled mask */
+  #define USB_OTG_DOEPMSK_B2BSTUP   0x00000040	/* Back-to-back SETUP packets received mask */
+  #define USB_OTG_DOEPMSK_OPEM      0x00000100	/* OUT packet error mask */
+  #define USB_OTG_DOEPMSK_BOIM      0x00000200	/* BNA interrupt mask */
+#define TOFF_USBD_DAINT     0x0018		/* (RW) dev All Endpoints Itr Register */
+  #define USB_OTG_DAINT_IEPINT      0x0000FFFF	/* IN endpoint interrupt bits */
+  #define USB_OTG_DAINT_OEPINT      0xFFFF0000	/* OUT endpoint interrupt bits */
+#define TOFF_USBD_DAINTMSK  0x001C		/* (RW) dev All Endpoints Itr Mask */
+  #define USB_OTG_DAINTMSK_IEPM     0x0000FFFF	/* IN EP interrupt mask bits */
+  #define USB_OTG_DAINTMSK_OEPM     0xFFFF0000	/* OUT EP interrupt mask bits */
+#define TOFF_USBD_DVBUSDIS  0x0028		/* (RW) dev VBUS discharge Register */
+  #define USB_OTG_DVBUSDIS_VBUSDT   0x0000FFFF	/* Device VBUS discharge time */
+#define TOFF_USBD_DVBUSPULSE 0x002C		/* (RW) dev VBUS Pulse Register */
+  #define USB_OTG_DVBUSPULSE_DVBUSP 0x00000FFF	/* Device VBUS pulsing time */
+#define TOFF_USBD_DTHRCTL   0x0030		/* (RW) dev thr */
+  #define USB_OTG_DTHRCTL_NONISOTHREN 0x00000001	/* Nonisochronous IN endpoints threshold enable */
+  #define USB_OTG_DTHRCTL_ISOTHREN    0x00000002	/* ISO IN endpoint threshold enable */
+  #define USB_OTG_DTHRCTL_TXTHRLEN    0x000007FC	/* Transmit threshold length */
+  #define USB_OTG_DTHRCTL_TXTHRLEN_0  0x00000004	/* Bit 0 */
+  #define USB_OTG_DTHRCTL_TXTHRLEN_1  0x00000008	/* Bit 1 */
+  #define USB_OTG_DTHRCTL_TXTHRLEN_2  0x00000010	/* Bit 2 */
+  #define USB_OTG_DTHRCTL_TXTHRLEN_3  0x00000020	/* Bit 3 */
+  #define USB_OTG_DTHRCTL_TXTHRLEN_4  0x00000040	/* Bit 4 */
+  #define USB_OTG_DTHRCTL_TXTHRLEN_5  0x00000080	/* Bit 5 */
+  #define USB_OTG_DTHRCTL_TXTHRLEN_6  0x00000100	/* Bit 6 */
+  #define USB_OTG_DTHRCTL_TXTHRLEN_7  0x00000200	/* Bit 7 */
+  #define USB_OTG_DTHRCTL_TXTHRLEN_8  0x00000400	/* Bit 8 */
+  #define USB_OTG_DTHRCTL_RXTHREN     0x00010000	/* Receive threshold enable */
+  #define USB_OTG_DTHRCTL_RXTHRLEN    0x03FE0000	/* Receive threshold length */
+  #define USB_OTG_DTHRCTL_RXTHRLEN_0  0x00020000	/* Bit 0 */
+  #define USB_OTG_DTHRCTL_RXTHRLEN_1  0x00040000	/* Bit 1 */
+  #define USB_OTG_DTHRCTL_RXTHRLEN_2  0x00080000	/* Bit 2 */
+  #define USB_OTG_DTHRCTL_RXTHRLEN_3  0x00100000	/* Bit 3 */
+  #define USB_OTG_DTHRCTL_RXTHRLEN_4  0x00200000	/* Bit 4 */
+  #define USB_OTG_DTHRCTL_RXTHRLEN_5  0x00400000	/* Bit 5 */
+  #define USB_OTG_DTHRCTL_RXTHRLEN_6  0x00800000	/* Bit 6 */
+  #define USB_OTG_DTHRCTL_RXTHRLEN_7  0x01000000	/* Bit 7 */
+  #define USB_OTG_DTHRCTL_RXTHRLEN_8  0x02000000	/* Bit 8 */
+  #define USB_OTG_DTHRCTL_ARPEN       0x08000000	/* Arbiter parking enable */
+#define TOFF_USBD_DIEPEMPMSK 0x0034		/* (RW) dev empty msk */
+  #define USB_OTG_DIEPEMPMSK_INEPTXFEM 0x0000FFFF	/* IN EP Tx FIFO empty interrupt mask bits */
+#define TOFF_USBD_DEACHINT  0x0038		/* (RW) dedicated EP interrupt */
+  #define USB_OTG_DEACHINT_IEP1INT  0x00000002	/* IN endpoint 1interrupt bit */
+  #define USB_OTG_DEACHINT_OEP1INT  0x00020000	/* OUT endpoint 1 interrupt bit */
+#define TOFF_USBD_DEACHMSK  0x003C		/* (RW) dedicated EP msk */
+#define TOFF_USBD_DINEP1MSK 0x0044		/* (RW) dedicated EP mask */
+#define TOFF_USBD_DOUTEP1MSK 0x0084		/* (RW) dedicated EP msk */
+
+/*
+ *  USB OTG IN ENDPOINT
+ */
+#define TADR_USBO_INEP_BASE     (USB_OTG_FS_PERIPH_BASE+USB_OTG_IN_ENDPOINT_BASE)
+#define USBO_EP_REG_SIZE         0x20
+#define TOFF_USBEI_DIEPCTL  0x0000		/* (RW) dev IN Endpoint Control Register */
+  #define USB_OTG_DIEPCTL_MPSIZ     0x000007FF	/* Maximum packet size */
+  #define USB_OTG_DIEPCTL_USBAEP    0x00008000	/* USB active endpoint */
+  #define USB_OTG_DIEPCTL_EONUM_DPID 0x00010000	/* Even/odd frame */
+  #define USB_OTG_DIEPCTL_NAKSTS    0x00020000	/* NAK status */
+  #define USB_OTG_DIEPCTL_EPTYP     0x000C0000	/* Endpoint type */
+  #define USB_OTG_DIEPCTL_EPTYP_0   0x00040000	/* Bit 0 */
+  #define USB_OTG_DIEPCTL_EPTYP_1   0x00080000	/* Bit 1 */
+  #define USB_OTG_DIEPCTL_STALL     0x00200000	/* STALL handshake */
+  #define USB_OTG_DIEPCTL_TXFNUM    0x03C00000	/* TxFIFO number */
+  #define USB_OTG_DIEPCTL_TXFNUM_0  0x00400000	/* Bit 0 */
+  #define USB_OTG_DIEPCTL_TXFNUM_1  0x00800000	/* Bit 1 */
+  #define USB_OTG_DIEPCTL_TXFNUM_2  0x01000000	/* Bit 2 */
+  #define USB_OTG_DIEPCTL_TXFNUM_3  0x02000000	/* Bit 3 */
+  #define USB_OTG_DIEPCTL_CNAK      0x04000000	/* Clear NAK */
+  #define USB_OTG_DIEPCTL_SNAK      0x08000000	/* Set NAK */
+  #define USB_OTG_DIEPCTL_SD0PID_SEVNFRM 0x10000000	/* Set DATA0 PID */
+  #define USB_OTG_DIEPCTL_SODDFRM   0x20000000	/* Set odd frame */
+  #define USB_OTG_DIEPCTL_EPDIS     0x40000000	/* Endpoint disable */
+  #define USB_OTG_DIEPCTL_EPENA     0x80000000	/* Endpoint enable */
+#define TOFF_USBEI_DIEPINT  0x0008		/* (RW) dev IN Endpoint Itr Register */
+  #define USB_OTG_DIEPINT_XFRC      0x00000001	/* Transfer completed interrupt */
+  #define USB_OTG_DIEPINT_EPDISD    0x00000002	/* Endpoint disabled interrupt */
+  #define USB_OTG_DIEPINT_TOC       0x00000008	/* Timeout condition */
+  #define USB_OTG_DIEPINT_ITTXFE    0x00000010	/* IN token received when TxFIFO is empty */
+  #define USB_OTG_DIEPINT_INEPNE    0x00000040	/* IN endpoint NAK effective */
+  #define USB_OTG_DIEPINT_TXFE      0x00000080	/* Transmit FIFO empty */
+  #define USB_OTG_DIEPINT_TXFIFOUDRN 0x00000100	/* Transmit Fifo Underrun */
+  #define USB_OTG_DIEPINT_BNA       0x00000200	/* Buffer not available interrupt */
+  #define USB_OTG_DIEPINT_PKTDRPSTS 0x00000800	/* Packet dropped status */
+  #define USB_OTG_DIEPINT_BERR      0x00001000	/* Babble error interrupt */
+  #define USB_OTG_DIEPINT_NAK       0x00002000	/* NAK interrupt */
+#define TOFF_USBEI_DIEPTSIZ 0x0010		/* (RW) IN Endpoint Txfer Size */
+  #define USB_OTG_DIEPTSIZ_XFRSIZ   0x0007FFFF	/* Transfer size */
+  #define USB_OTG_DIEPTSIZ_PKTCNT   0x1FF80000	/* Packet count */
+  #define USB_OTG_DIEPTSIZ_MULCNT   0x60000000	/* Packet count */
+#define TOFF_USBEI_DIEPDMA  0x0014		/* (RW) IN Endpoint DMA Address Register */
+  #define USB_OTG_DIEPDMA_DMAADDR   0xFFFFFFFF	/* DMA address */
+#define TOFF_USBEI_DTXFSTS  0x0018		/* (RW) IN Endpoint Tx FIFO Status Register */
+  #define USB_OTG_DTXFSTS_INEPTFSAV 0x0000FFFF	/* IN endpoint TxFIFO space avail */
+
+/*
+ *  USB OTG OUTPUT ENDPOINT
+ */
+#define TADR_USBO_OUTEP_BASE    (USB_OTG_FS_PERIPH_BASE+USB_OTG_OUT_ENDPOINT_BASE)
+#define TOFF_USBEO_DOEPCTL  0x0000		/* (RW) dev OUT Endpoint Control Register */
+  #define USB_OTG_DOEPCTL_MPSIZ     0x000007FF	/* Maximum packet size */
+  #define USB_OTG_DOEPCTL_USBAEP    0x00008000	/* USB active endpoint */
+  #define USB_OTG_DOEPCTL_NAKSTS    0x00020000	/* NAK status */
+  #define USB_OTG_DOEPCTL_SD0PID_SEVNFRM  0x10000000	/* Set DATA0 PID */
+  #define USB_OTG_DOEPCTL_SODDFRM   0x20000000	/* Set odd frame */
+  #define USB_OTG_DOEPCTL_EPTYP     0x000C0000	/* Endpoint type */
+  #define USB_OTG_DOEPCTL_EPTYP_0   0x00040000	/* Bit 0 */
+  #define USB_OTG_DOEPCTL_EPTYP_1   0x00080000	/* Bit 1 */
+  #define USB_OTG_DOEPCTL_SNPM      0x00100000	/* Snoop mode */
+  #define USB_OTG_DOEPCTL_STALL     0x00200000	/* STALL handshake */
+  #define USB_OTG_DOEPCTL_CNAK      0x04000000	/* Clear NAK */
+  #define USB_OTG_DOEPCTL_SNAK      0x08000000	/* Set NAK */
+  #define USB_OTG_DOEPCTL_EPDIS     0x40000000	/* Endpoint disable */
+  #define USB_OTG_DOEPCTL_EPENA     0x80000000	/* Endpoint enable */
+#define TOFF_USBEO_DOEPINT  0x0008		/* (RW) dev OUT Endpoint Itr Register */
+  #define USB_OTG_DOEPINT_XFRC      0x00000001	/* Transfer completed interrupt */
+  #define USB_OTG_DOEPINT_EPDISD    0x00000002	/* Endpoint disabled interrupt */
+  #define USB_OTG_DOEPINT_STUP      0x00000008	/* SETUP phase done */
+  #define USB_OTG_DOEPINT_OTEPDIS   0x00000010	/* OUT token received when endpoint disabled */
+  #define USB_OTG_DOEPINT_B2BSTUP   0x00000040	/* Back-to-back SETUP packets received */
+  #define USB_OTG_DOEPINT_NYET      0x00004000	/* NYET interrupt */
+#define TOFF_USBEO_DOEPTSIZ 0x0010		/* (RW) dev OUT Endpoint Txfer Size */
+  #define USB_OTG_DOEPTSIZ_XFRSIZ   0x0007FFFF	/* Transfer size */
+  #define USB_OTG_DOEPTSIZ_PKTCNT   0x1FF80000	/* Packet count */
+  #define USB_OTG_DOEPTSIZ_STUPCNT  0x60000000	/* SETUP packet count */
+  #define USB_OTG_DOEPTSIZ_STUPCNT_0 0x20000000	/* Bit 0 */
+  #define USB_OTG_DOEPTSIZ_STUPCNT_1 0x40000000	/* Bit 1 */
+#define TOFF_USBEO_DOEPDMA  0x0014		/* (RW) dev OUT Endpoint DMA Address */
+
+/*
+ *  USB OTG HOST
+ */
+#define TADR_USBO_HOST_BASE     (USB_OTG_FS_PERIPH_BASE+USB_OTG_HOST_BASE)
+#define TOFF_USBH_HCFG      0x0000		/* (RW) Host Configuration Register */
+  #define USB_OTG_HCFG_FSLSPCS      0x00000003	/* FS/LS PHY clock select */
+  #define USB_OTG_HCFG_FSLSPCS_0    0x00000001	/* Bit 0 */
+  #define USB_OTG_HCFG_FSLSPCS_1    0x00000002	/* Bit 1 */
+  #define USB_OTG_HCFG_FSLSS        0x00000004	/* FS- and LS-only support */
+#define TOFF_USBH_HFIR      0x0004		/* (RW) Host Frame Interval Register */
+  #define USB_OTG_HFIR_FRIVL        0x0000FFFF	/* Frame interval */
+#define TOFF_USBH_HFNUM     0x0008		/* (RW) Host Frame Nbr/Frame Remaining */
+  #define USB_OTG_HFNUM_FRNUM       0x0000FFFF	/* Frame number */
+  #define USB_OTG_HFNUM_FTREM       0xFFFF0000	/* Frame time remaining */
+#define TOFF_USBH_HPTXSTS   0x0010		/* (RW) Host Periodic Tx FIFO/ Queue Status */
+  #define USB_OTG_HPTXSTS_PTXFSAVL  0x0000FFFF	/* Periodic transmit data FIFO space available */
+  #define USB_OTG_HPTXSTS_PTXQSAV   0x00FF0000	/* Periodic transmit request queue space available */
+  #define USB_OTG_HPTXSTS_PTXQSAV_0 0x00010000	/* Bit 0 */
+  #define USB_OTG_HPTXSTS_PTXQSAV_1 0x00020000	/* Bit 1 */
+  #define USB_OTG_HPTXSTS_PTXQSAV_2 0x00040000	/* Bit 2 */
+  #define USB_OTG_HPTXSTS_PTXQSAV_3 0x00080000	/* Bit 3 */
+  #define USB_OTG_HPTXSTS_PTXQSAV_4 0x00100000	/* Bit 4 */
+  #define USB_OTG_HPTXSTS_PTXQSAV_5 0x00200000	/* Bit 5 */
+  #define USB_OTG_HPTXSTS_PTXQSAV_6 0x00400000	/* Bit 6 */
+  #define USB_OTG_HPTXSTS_PTXQSAV_7 0x00800000	/* Bit 7 */
+  #define USB_OTG_HPTXSTS_PTXQTOP   0xFF000000	/* Top of the periodic transmit request queue */
+  #define USB_OTG_HPTXSTS_PTXQTOP_0 0x01000000	/* Bit 0 */
+  #define USB_OTG_HPTXSTS_PTXQTOP_1 0x02000000	/* Bit 1 */
+  #define USB_OTG_HPTXSTS_PTXQTOP_2 0x04000000	/* Bit 2 */
+  #define USB_OTG_HPTXSTS_PTXQTOP_3 0x08000000	/* Bit 3 */
+  #define USB_OTG_HPTXSTS_PTXQTOP_4 0x10000000	/* Bit 4 */
+  #define USB_OTG_HPTXSTS_PTXQTOP_5 0x20000000	/* Bit 5 */
+  #define USB_OTG_HPTXSTS_PTXQTOP_6 0x40000000	/* Bit 6 */
+  #define USB_OTG_HPTXSTS_PTXQTOP_7 0x80000000	/* Bit 7 */
+#define TOFF_USBH_HAINT     0x0014		/* (RW) Host All Channels Interrupt Register */
+  #define USB_OTG_HAINT_HAINT       0x0000FFFF	/* Channel interrupts */
+#define TOFF_USBH_HAINTMSK  0x0018		/* (RW) Host All Channels Interrupt Mask */
+  #define USB_OTG_HAINTMSK_HAINTM   0x0000FFFF	/* Channel interrupt mask */
+
+/*
+ *  USB HOST CHANNEL SPECIFIC
+ */
+#define TADR_USBH_HC_BASE        (USB_OTG_FS_PERIPH_BASE+USB_OTG_HOST_CHANNEL_BASE)
+#define USBO_HOST_CHANNEL_REG_SIZE    0x20
+#define TOFF_USBHC_HCCHAR   0x0000
+  #define USB_OTG_HCCHAR_MPSIZ      0x000007FF	/* Maximum packet size */
+  #define USB_OTG_HCCHAR_EPNUM      0x00007800	/* Endpoint number */
+  #define USB_OTG_HCCHAR_EPNUM_0    0x00000800	/* Bit 0 */
+  #define USB_OTG_HCCHAR_EPNUM_1    0x00001000	/* Bit 1 */
+  #define USB_OTG_HCCHAR_EPNUM_2    0x00002000	/* Bit 2 */
+  #define USB_OTG_HCCHAR_EPNUM_3    0x00004000	/* Bit 3 */
+  #define USB_OTG_HCCHAR_EPDIR      0x00008000	/* Endpoint direction */
+  #define USB_OTG_HCCHAR_LSDEV      0x00020000	/* Low-speed device */
+  #define USB_OTG_HCCHAR_EPTYP      0x000C0000	/* Endpoint type */
+  #define USB_OTG_HCCHAR_EPTYP_0    0x00040000	/* Bit 0 */
+  #define USB_OTG_HCCHAR_EPTYP_1    0x00080000	/* Bit 1 */
+  #define USB_OTG_HCCHAR_MC         0x00300000	/* Multi Count (MC) / Error Count (EC) */
+  #define USB_OTG_HCCHAR_MC_0       0x00100000	/* Bit 0 */
+  #define USB_OTG_HCCHAR_MC_1       0x00200000	/* Bit 1 */
+  #define USB_OTG_HCCHAR_DAD        0x1FC00000	/* Device address */
+  #define USB_OTG_HCCHAR_DAD_0      0x00400000	/* Bit 0 */
+  #define USB_OTG_HCCHAR_DAD_1      0x00800000	/* Bit 1 */
+  #define USB_OTG_HCCHAR_DAD_2      0x01000000	/* Bit 2 */
+  #define USB_OTG_HCCHAR_DAD_3      0x02000000	/* Bit 3 */
+  #define USB_OTG_HCCHAR_DAD_4      0x04000000	/* Bit 4 */
+  #define USB_OTG_HCCHAR_DAD_5      0x08000000	/* Bit 5 */
+  #define USB_OTG_HCCHAR_DAD_6      0x10000000	/* Bit 6 */
+  #define USB_OTG_HCCHAR_ODDFRM     0x20000000	/* Odd frame */
+  #define USB_OTG_HCCHAR_CHDIS      0x40000000	/* Channel disable */
+  #define USB_OTG_HCCHAR_CHENA      0x80000000	/* Channel enable */
+#define TOFF_USBHC_HCSPLT   0x0004
+  #define USB_OTG_HCSPLT_PRTADDR    0x0000007F	/* Port address */
+  #define USB_OTG_HCSPLT_PRTADDR_0  0x00000001	/* Bit 0 */
+  #define USB_OTG_HCSPLT_PRTADDR_1  0x00000002	/* Bit 1 */
+  #define USB_OTG_HCSPLT_PRTADDR_2  0x00000004	/* Bit 2 */
+  #define USB_OTG_HCSPLT_PRTADDR_3  0x00000008	/* Bit 3 */
+  #define USB_OTG_HCSPLT_PRTADDR_4  0x00000010	/* Bit 4 */
+  #define USB_OTG_HCSPLT_PRTADDR_5  0x00000020	/* Bit 5 */
+  #define USB_OTG_HCSPLT_PRTADDR_6  0x00000040	/* Bit 6 */
+  #define USB_OTG_HCSPLT_HUBADDR    0x00003F80	/* Hub address */
+  #define USB_OTG_HCSPLT_HUBADDR_0  0x00000080	/* Bit 0 */
+  #define USB_OTG_HCSPLT_HUBADDR_1  0x00000100	/* Bit 1 */
+  #define USB_OTG_HCSPLT_HUBADDR_2  0x00000200	/* Bit 2 */
+  #define USB_OTG_HCSPLT_HUBADDR_3  0x00000400	/* Bit 3 */
+  #define USB_OTG_HCSPLT_HUBADDR_4  0x00000800	/* Bit 4 */
+  #define USB_OTG_HCSPLT_HUBADDR_5  0x00001000	/* Bit 5 */
+  #define USB_OTG_HCSPLT_HUBADDR_6  0x00002000	/* Bit 6 */
+  #define USB_OTG_HCSPLT_XACTPOS    0x0000C000	/* XACTPOS */
+  #define USB_OTG_HCSPLT_XACTPOS_0  0x00004000	/* Bit 0 */
+  #define USB_OTG_HCSPLT_XACTPOS_1  0x00008000	/* Bit 1 */
+  #define USB_OTG_HCSPLT_COMPLSPLT  0x00010000	/* Do complete split */
+  #define USB_OTG_HCSPLT_SPLITEN    0x80000000	/* Split enable */
+#define TOFF_USBHC_HCINT    0x0008
+  #define USB_OTG_HCINT_XFRC        0x00000001	/* Transfer completed */
+  #define USB_OTG_HCINT_CHH         0x00000002	/* Channel halted */
+  #define USB_OTG_HCINT_AHBERR      0x00000004	/* AHB error */
+  #define USB_OTG_HCINT_STALL       0x00000008	/* STALL response received interrupt */
+  #define USB_OTG_HCINT_NAK         0x00000010	/* NAK response received interrupt */
+  #define USB_OTG_HCINT_ACK         0x00000020	/* ACK response received/transmitted interrupt */
+  #define USB_OTG_HCINT_NYET        0x00000040	/* Response received interrupt */
+  #define USB_OTG_HCINT_TXERR       0x00000080	/* Transaction error */
+  #define USB_OTG_HCINT_BBERR       0x00000100	/* Babble error */
+  #define USB_OTG_HCINT_FRMOR       0x00000200	/* Frame overrun */
+  #define USB_OTG_HCINT_DTERR       0x00000400	/* Data toggle error */
+#define TOFF_USBHC_HCINTMSK 0x000C
+  #define USB_OTG_HCINTMSK_XFRCM    0x00000001	/* Transfer completed mask */
+  #define USB_OTG_HCINTMSK_CHHM     0x00000002	/* Channel halted mask */
+  #define USB_OTG_HCINTMSK_AHBERR   0x00000004	/* AHB error */
+  #define USB_OTG_HCINTMSK_STALLM   0x00000008	/* STALL response received interrupt mask */
+  #define USB_OTG_HCINTMSK_NAKM     0x00000010	/* NAK response received interrupt mask */
+  #define USB_OTG_HCINTMSK_ACKM     0x00000020	/* ACK response received/transmitted interrupt mask */
+  #define USB_OTG_HCINTMSK_NYET     0x00000040	/* response received interrupt mask */
+  #define USB_OTG_HCINTMSK_TXERRM   0x00000080	/* Transaction error mask */
+  #define USB_OTG_HCINTMSK_BBERRM   0x00000100	/* Babble error mask */
+  #define USB_OTG_HCINTMSK_FRMORM   0x00000200	/* Frame overrun mask */
+  #define USB_OTG_HCINTMSK_DTERRM   0x00000400	/* Data toggle error mask */
+#define TOFF_USBHC_HCTSIZ   0x0010
+  #define USB_OTG_HCTSIZ_XFRSIZ     0x0007FFFF	/* Transfer size */
+  #define USB_OTG_HCTSIZ_PKTCNT     0x1FF80000	/* Packet count */
+  #define USB_OTG_HCTSIZ_DOPING     0x80000000	/* Do PING */
+  #define USB_OTG_HCTSIZ_DPID       0x60000000	/* Data PID */
+  #define USB_OTG_HCTSIZ_DPID_0     0x20000000	/* Bit 0 */
+  #define USB_OTG_HCTSIZ_DPID_1     0x40000000	/* Bit 1 */
+#define TOFF_USBHC_HCDMA    0x0014
+  #define USB_OTG_HCDMA_DMAADDR     0xFFFFFFFF	/* DMA address */
+
+/*
+ *  USB OTG HPRT
+ */
+#define TADR_USBO_HPRT0_BASE         (USB_OTG_FS_PERIPH_BASE+USB_OTG_HOST_PORT_BASE)
+  #define USB_OTG_HPRT_PCSTS        0x00000001	/* Port connect status */
+  #define USB_OTG_HPRT_PCDET        0x00000002	/* Port connect detected */
+  #define USB_OTG_HPRT_PENA         0x00000004	/* Port enable */
+  #define USB_OTG_HPRT_PENCHNG      0x00000008	/* Port enable/disable change */
+  #define USB_OTG_HPRT_POCA         0x00000010	/* Port overcurrent active */
+  #define USB_OTG_HPRT_POCCHNG      0x00000020	/* Port overcurrent change */
+  #define USB_OTG_HPRT_PRES         0x00000040	/* Port resume */
+  #define USB_OTG_HPRT_PSUSP        0x00000080	/* Port suspend */
+  #define USB_OTG_HPRT_PRST         0x00000100	/* Port reset */
+  #define USB_OTG_HPRT_PLSTS        0x00000C00	/* Port line status */
+  #define USB_OTG_HPRT_PLSTS_0      0x00000400	/* Bit 0 */
+  #define USB_OTG_HPRT_PLSTS_1      0x00000800	/* Bit 1 */
+  #define USB_OTG_HPRT_PPWR         0x00001000	/* Port power */
+  #define USB_OTG_HPRT_PTCTL        0x0001E000	/* Port test control */
+  #define USB_OTG_HPRT_PTCTL_0      0x00002000	/* Bit 0 */
+  #define USB_OTG_HPRT_PTCTL_1      0x00004000	/* Bit 1 */
+  #define USB_OTG_HPRT_PTCTL_2      0x00008000	/* Bit 2 */
+  #define USB_OTG_HPRT_PTCTL_3      0x00010000	/* Bit 3 */
+  #define USB_OTG_HPRT_PSPD         0x00060000	/* Port speed */
+  #define USB_OTG_HPRT_PSPD_0       0x00020000	/* Bit 0 */
+  #define USB_OTG_HPRT_PSPD_1       0x00040000	/* Bit 1 */
+
+/*
+ *  PCGCCTL BIT DEFINITIONS
+ */
+#define USB_OTG_PCGCCTL_STOPCLK     0x00000001	/* SETUP packet count */
+#define USB_OTG_PCGCCTL_GATECLK     0x00000002	/* Bit 0 */
+#define USB_OTG_PCGCCTL_PHYSUSP     0x00000010	/* Bit 1 */
+
+#if defined(TOPPERS_STM32F769_DISCOVERY)
+/*
+ *  DSI CONTROLLER REGISTERS BASE ADDRESS
+ */
+#define TADR_DSI_BASE      (APB2PERIPH_BASE + 0x6C00)
+#define TOFF_DSI_VR        0x0000	/* (R)  DSI Host Version Register */
+#define TOFF_DSI_CR        0x0004	/* (RW) DSI Host Control Register */
+  #define DSI_CR_EN            0x00000001	/* DSI Host power up and reset */
+#define TOFF_DSI_CCR       0x0008	/* (RW) DSI HOST Clock Control Register */
+  #define DSI_CCR_TXECKDIV     0x000000FF	/* TX Escape Clock Division */
+  #define DSI_CCR_TXECKDIV0    0x00000001
+  #define DSI_CCR_TXECKDIV1    0x00000002
+  #define DSI_CCR_TXECKDIV2    0x00000004
+  #define DSI_CCR_TXECKDIV3    0x00000008
+  #define DSI_CCR_TXECKDIV4    0x00000010
+  #define DSI_CCR_TXECKDIV5    0x00000020
+  #define DSI_CCR_TXECKDIV6    0x00000040
+  #define DSI_CCR_TXECKDIV7    0x00000080
+  #define DSI_CCR_TOCKDIV      0x0000FF00	/* Timeout Clock Division */
+  #define DSI_CCR_TOCKDIV0     0x00000100
+  #define DSI_CCR_TOCKDIV1     0x00000200
+  #define DSI_CCR_TOCKDIV2     0x00000400
+  #define DSI_CCR_TOCKDIV3     0x00000800
+  #define DSI_CCR_TOCKDIV4     0x00001000
+  #define DSI_CCR_TOCKDIV5     0x00002000
+  #define DSI_CCR_TOCKDIV6     0x00004000
+  #define DSI_CCR_TOCKDIV7     0x00008000
+#define TOFF_DSI_LVCIDR    0x000C	/* (RW) DSI Host LTDC VCID Register */
+  #define DSI_LVCIDR_VCID      0x00000003	/* Virtual Channel ID */
+  #define DSI_LVCIDR_VCID0     0x00000001
+  #define DSI_LVCIDR_VCID1     0x00000002
+#define TOFF_DSI_LCOLCR    0x0010	/* (RW) DSI Host LTDC Color Coding Register */
+  #define DSI_LCOLCR_COLC      0x0000000F	/* Color Coding */
+  #define DSI_LCOLCR_COLC0     0x00000001
+  #define DSI_LCOLCR_COLC1     0x00000020
+  #define DSI_LCOLCR_COLC2     0x00000040
+  #define DSI_LCOLCR_COLC3     0x00000080
+  #define DSI_LCOLCR_LPE       0x00000100	/* Loosly Packet Enable */
+#define TOFF_DSI_LPCR      0x0014	/* (RW) DSI Host LTDC Polarity Configuration Register */
+  #define DSI_LPCR_DEP         0x00000001	/* Data Enable Polarity */
+  #define DSI_LPCR_VSP         0x00000002	/* VSYNC Polarity */
+  #define DSI_LPCR_HSP         0x00000004	/* HSYNC Polarity */
+#define TOFF_DSI_LPMCR     0x0018	/* (RW) DSI Host Low-Power Mode Configuration Register */
+  #define DSI_LPMCR_VLPSIZE    0x000000FF	/* VACT Largest Packet Size */
+  #define DSI_LPMCR_VLPSIZE0   0x00000001
+  #define DSI_LPMCR_VLPSIZE1   0x00000002
+  #define DSI_LPMCR_VLPSIZE2   0x00000004
+  #define DSI_LPMCR_VLPSIZE3   0x00000008
+  #define DSI_LPMCR_VLPSIZE4   0x00000010
+  #define DSI_LPMCR_VLPSIZE5   0x00000020
+  #define DSI_LPMCR_VLPSIZE6   0x00000040
+  #define DSI_LPMCR_VLPSIZE7   0x00000080
+  #define DSI_LPMCR_LPSIZE     0x00FF0000	/* Largest Packet Size */
+  #define DSI_LPMCR_LPSIZE0    0x00010000
+  #define DSI_LPMCR_LPSIZE1    0x00020000
+  #define DSI_LPMCR_LPSIZE2    0x00040000
+  #define DSI_LPMCR_LPSIZE3    0x00080000
+  #define DSI_LPMCR_LPSIZE4    0x00100000
+  #define DSI_LPMCR_LPSIZE5    0x00200000
+  #define DSI_LPMCR_LPSIZE6    0x00400000
+  #define DSI_LPMCR_LPSIZE7    0x00800000
+#define TOFF_DSI_PCR       0x002C	/* (RW) DSI Host Protocol Configuration Register */
+  #define DSI_PCR_ETTXE        0x00000001	/* EoTp Transmission Enable */
+  #define DSI_PCR_ETRXE        0x00000002	/* EoTp Reception Enable */
+  #define DSI_PCR_BTAE         0x00000004	/* Bus Turn Around Enable */
+  #define DSI_PCR_ECCRXE       0x00000008	/* ECC Reception Enable */
+  #define DSI_PCR_CRCRXE       0x00000010	/* CRC Reception Enable */
+#define TOFF_DSI_GVCIDR    0x0030	/* (RW) DSI Host Generic VCID Register */
+  #define DSI_GVCIDR_VCID      0x00000003	/* Virtual Channel ID */
+  #define DSI_GVCIDR_VCID0     0x00000001
+  #define DSI_GVCIDR_VCID1     0x00000002
+#define TOFF_DSI_MCR       0x0034	/* (RW) DSI Host Mode Configuration Register */
+  #define DSI_MCR_CMDM         0x00000001	/* Command Mode */
+#define TOFF_DSI_VMCR      0x0038	/* (RW) DSI Host Video Mode Configuration Register */
+  #define DSI_VMCR_VMT         0x00000003	/* Video Mode Type */
+  #define DSI_VMCR_VMT0        0x00000001
+  #define DSI_VMCR_VMT1        0x00000002
+  #define DSI_VMCR_LPVSAE      0x00000100	/* Low-Power Vertical Sync Active Enable */
+  #define DSI_VMCR_LPVBPE      0x00000200	/* Low-power Vertical Back-Porch Enable */
+  #define DSI_VMCR_LPVFPE      0x00000400	/* Low-power Vertical Front-porch Enable */
+  #define DSI_VMCR_LPVAE       0x00000800	/* Low-Power Vertical Active Enable */
+  #define DSI_VMCR_LPHBPE      0x00001000	/* Low-Power Horizontal Back-Porch Enable */
+  #define DSI_VMCR_LPHFPE      0x00002000	/* Low-Power Horizontal Front-Porch Enable */
+  #define DSI_VMCR_FBTAAE      0x00004000	/* Frame Bus-Turn-Around Acknowledge Enable */
+  #define DSI_VMCR_LPCE        0x00008000	/* Low-Power Command Enable */
+  #define DSI_VMCR_PGE         0x00010000	/* Pattern Generator Enable */
+  #define DSI_VMCR_PGM         0x00100000	/* Pattern Generator Mode */
+  #define DSI_VMCR_PGO         0x01000000	/* Pattern Generator Orientation */
+#define TOFF_DSI_VPCR      0x003C	/* (RW) DSI Host Video Packet Configuration Register */
+  #define DSI_VPCR_VPSIZE      0x00003FFF	/* Video Packet Size */
+  #define DSI_VPCR_VPSIZE0     0x00000001
+  #define DSI_VPCR_VPSIZE1     0x00000002
+  #define DSI_VPCR_VPSIZE2     0x00000004
+  #define DSI_VPCR_VPSIZE3     0x00000008
+  #define DSI_VPCR_VPSIZE4     0x00000010
+  #define DSI_VPCR_VPSIZE5     0x00000020
+  #define DSI_VPCR_VPSIZE6     0x00000040
+  #define DSI_VPCR_VPSIZE7     0x00000080
+  #define DSI_VPCR_VPSIZE8     0x00000100
+  #define DSI_VPCR_VPSIZE9     0x00000200
+  #define DSI_VPCR_VPSIZE10    0x00000400
+  #define DSI_VPCR_VPSIZE11    0x00000800
+  #define DSI_VPCR_VPSIZE12    0x00001000
+  #define DSI_VPCR_VPSIZE13    0x00002000
+#define TOFF_DSI_VCCR      0x0040	/* (RW) DSI Host Video Chunks Configuration Register */
+  #define DSI_VCCR_NUMC        0x00001FFF	/* Number of Chunks */
+  #define DSI_VCCR_NUMC0       0x00000001
+  #define DSI_VCCR_NUMC1       0x00000002
+  #define DSI_VCCR_NUMC2       0x00000004
+  #define DSI_VCCR_NUMC3       0x00000008
+  #define DSI_VCCR_NUMC4       0x00000010
+  #define DSI_VCCR_NUMC5       0x00000020
+  #define DSI_VCCR_NUMC6       0x00000040
+  #define DSI_VCCR_NUMC7       0x00000080
+  #define DSI_VCCR_NUMC8       0x00000100
+  #define DSI_VCCR_NUMC9       0x00000200
+  #define DSI_VCCR_NUMC10      0x00000400
+  #define DSI_VCCR_NUMC11      0x00000800
+  #define DSI_VCCR_NUMC12      0x00001000
+#define TOFF_DSI_VNPCR     0x0044	/* (RW) DSI Host Video Null Packet Configuration Register */
+  #define DSI_VNPCR_NPSIZE     0x00001FFF	/* Null Packet Size */
+  #define DSI_VNPCR_NPSIZE0    0x00000001
+  #define DSI_VNPCR_NPSIZE1    0x00000002
+  #define DSI_VNPCR_NPSIZE2    0x00000004
+  #define DSI_VNPCR_NPSIZE3    0x00000008
+  #define DSI_VNPCR_NPSIZE4    0x00000010
+  #define DSI_VNPCR_NPSIZE5    0x00000020
+  #define DSI_VNPCR_NPSIZE6    0x00000040
+  #define DSI_VNPCR_NPSIZE7    0x00000080
+  #define DSI_VNPCR_NPSIZE8    0x00000100
+  #define DSI_VNPCR_NPSIZE9    0x00000200
+  #define DSI_VNPCR_NPSIZE10   0x00000400
+  #define DSI_VNPCR_NPSIZE11   0x00000800
+  #define DSI_VNPCR_NPSIZE12   0x00001000
+#define TOFF_DSI_VHSACR    0x0048	/* (RW) DSI Host Video HSA Configuration Register */
+  #define DSI_VHSACR_HSA       0x00000FFF	/* Horizontal Synchronism Active duration */
+  #define DSI_VHSACR_HSA0      0x00000001
+  #define DSI_VHSACR_HSA1      0x00000002
+  #define DSI_VHSACR_HSA2      0x00000004
+  #define DSI_VHSACR_HSA3      0x00000008
+  #define DSI_VHSACR_HSA4      0x00000010
+  #define DSI_VHSACR_HSA5      0x00000020
+  #define DSI_VHSACR_HSA6      0x00000040
+  #define DSI_VHSACR_HSA7      0x00000080
+  #define DSI_VHSACR_HSA8      0x00000100
+  #define DSI_VHSACR_HSA9      0x00000200
+  #define DSI_VHSACR_HSA10     0x00000400
+  #define DSI_VHSACR_HSA11     0x00000800
+#define TOFF_DSI_VHBPCR    0x004C	/* (RW) DSI Host Video HBP Configuration Register */
+  #define DSI_VHBPCR_HBP       0x00000FFF	/* Horizontal Back-Porch duration */
+  #define DSI_VHBPCR_HBP0      0x00000001
+  #define DSI_VHBPCR_HBP1      0x00000002
+  #define DSI_VHBPCR_HBP2      0x00000004
+  #define DSI_VHBPCR_HBP3      0x00000008
+  #define DSI_VHBPCR_HBP4      0x00000010
+  #define DSI_VHBPCR_HBP5      0x00000020
+  #define DSI_VHBPCR_HBP6      0x00000040
+  #define DSI_VHBPCR_HBP7      0x00000080
+  #define DSI_VHBPCR_HBP8      0x00000100
+  #define DSI_VHBPCR_HBP9      0x00000200
+  #define DSI_VHBPCR_HBP10     0x00000400
+  #define DSI_VHBPCR_HBP11     0x00000800
+#define TOFF_DSI_VLCR      0x0050	/* (RW) DSI Host Video Line Configuration Register */
+  #define DSI_VLCR_HLINE       0x00007FFF	/* Horizontal Line duration */
+  #define DSI_VLCR_HLINE0      0x00000001
+  #define DSI_VLCR_HLINE1      0x00000002
+  #define DSI_VLCR_HLINE2      0x00000004
+  #define DSI_VLCR_HLINE3      0x00000008
+  #define DSI_VLCR_HLINE4      0x00000010
+  #define DSI_VLCR_HLINE5      0x00000020
+  #define DSI_VLCR_HLINE6      0x00000040
+  #define DSI_VLCR_HLINE7      0x00000080
+  #define DSI_VLCR_HLINE8      0x00000100
+  #define DSI_VLCR_HLINE9      0x00000200
+  #define DSI_VLCR_HLINE10     0x00000400
+  #define DSI_VLCR_HLINE11     0x00000800
+  #define DSI_VLCR_HLINE12     0x00001000
+  #define DSI_VLCR_HLINE13     0x00002000
+  #define DSI_VLCR_HLINE14     0x00004000
+#define TOFF_DSI_VVSACR    0x0054	/* (RW) DSI Host Video VSA Configuration Register */
+  #define DSI_VVSACR_VSA       0x000003FF	/* Vertical Synchronism Active duration */
+  #define DSI_VVSACR_VSA0      0x00000001
+  #define DSI_VVSACR_VSA1      0x00000002
+  #define DSI_VVSACR_VSA2      0x00000004
+  #define DSI_VVSACR_VSA3      0x00000008
+  #define DSI_VVSACR_VSA4      0x00000010
+  #define DSI_VVSACR_VSA5      0x00000020
+  #define DSI_VVSACR_VSA6      0x00000040
+  #define DSI_VVSACR_VSA7      0x00000080
+  #define DSI_VVSACR_VSA8      0x00000100
+  #define DSI_VVSACR_VSA9      0x00000200
+#define TOFF_DSI_VVBPCR    0x0058	/* (RW) DSI Host Video VBP Configuration Register */
+  #define DSI_VVBPCR_VBP       0x000003FF	/* Vertical Back-Porch duration */
+  #define DSI_VVBPCR_VBP0      0x00000001
+  #define DSI_VVBPCR_VBP1      0x00000002
+  #define DSI_VVBPCR_VBP2      0x00000004
+  #define DSI_VVBPCR_VBP3      0x00000008
+  #define DSI_VVBPCR_VBP4      0x00000010
+  #define DSI_VVBPCR_VBP5      0x00000020
+  #define DSI_VVBPCR_VBP6      0x00000040
+  #define DSI_VVBPCR_VBP7      0x00000080
+  #define DSI_VVBPCR_VBP8      0x00000100
+  #define DSI_VVBPCR_VBP9      0x00000200
+#define TOFF_DSI_VVFPCR    0x005C	/* (RW) DSI Host Video VFP Configuration Register */
+  #define DSI_VVFPCR_VFP       0x000003FF	/* Vertical Front-Porch duration */
+  #define DSI_VVFPCR_VFP0      0x00000001
+  #define DSI_VVFPCR_VFP1      0x00000002
+  #define DSI_VVFPCR_VFP2      0x00000004
+  #define DSI_VVFPCR_VFP3      0x00000008
+  #define DSI_VVFPCR_VFP4      0x00000010
+  #define DSI_VVFPCR_VFP5      0x00000020
+  #define DSI_VVFPCR_VFP6      0x00000040
+  #define DSI_VVFPCR_VFP7      0x00000080
+  #define DSI_VVFPCR_VFP8      0x00000100
+  #define DSI_VVFPCR_VFP9      0x00000200
+#define TOFF_DSI_VVACR     0x0060	/* (RW) DSI Host Video VA Configuration Register */
+  #define DSI_VVACR_VA         0x00003FFF	/* Vertical Active duration */
+  #define DSI_VVACR_VA0        0x00000001
+  #define DSI_VVACR_VA1        0x00000002
+  #define DSI_VVACR_VA2        0x00000004
+  #define DSI_VVACR_VA3        0x00000008
+  #define DSI_VVACR_VA4        0x00000010
+  #define DSI_VVACR_VA5        0x00000020
+  #define DSI_VVACR_VA6        0x00000040
+  #define DSI_VVACR_VA7        0x00000080
+  #define DSI_VVACR_VA8        0x00000100
+  #define DSI_VVACR_VA9        0x00000200
+  #define DSI_VVACR_VA10       0x00000400
+  #define DSI_VVACR_VA11       0x00000800
+  #define DSI_VVACR_VA12       0x00001000
+  #define DSI_VVACR_VA13       0x00002000
+#define TOFF_DSI_LCCR      0x0064	/* (RW) DSI Host LTDC Command Configuration Register */
+  #define DSI_LCCR_CMDSIZE     0x0000FFFF	/* Command Size */
+  #define DSI_LCCR_CMDSIZE0    0x00000001
+  #define DSI_LCCR_CMDSIZE1    0x00000002
+  #define DSI_LCCR_CMDSIZE2    0x00000004
+  #define DSI_LCCR_CMDSIZE3    0x00000008
+  #define DSI_LCCR_CMDSIZE4    0x00000010
+  #define DSI_LCCR_CMDSIZE5    0x00000020
+  #define DSI_LCCR_CMDSIZE6    0x00000040
+  #define DSI_LCCR_CMDSIZE7    0x00000080
+  #define DSI_LCCR_CMDSIZE8    0x00000100
+  #define DSI_LCCR_CMDSIZE9    0x00000200
+  #define DSI_LCCR_CMDSIZE10   0x00000400
+  #define DSI_LCCR_CMDSIZE11   0x00000800
+  #define DSI_LCCR_CMDSIZE12   0x00001000
+  #define DSI_LCCR_CMDSIZE13   0x00002000
+  #define DSI_LCCR_CMDSIZE14   0x00004000
+  #define DSI_LCCR_CMDSIZE15   0x00008000
+#define TOFF_DSI_CMCR      0x0068	/* (RW) DSI Host Command Mode Configuration Register */
+  #define DSI_CMCR_TEARE       0x00000001	/* Tearing Effect Acknowledge Request Enable */
+  #define DSI_CMCR_ARE         0x00000002	/* Acknowledge Request Enable */
+  #define DSI_CMCR_GSW0TX      0x00000100	/* Generic Short Write Zero parameters Transmission */
+  #define DSI_CMCR_GSW1TX      0x00000200	/* Generic Short Write One parameters Transmission */
+  #define DSI_CMCR_GSW2TX      0x00000400	/* Generic Short Write Two parameters Transmission */
+  #define DSI_CMCR_GSR0TX      0x00000800	/* Generic Short Read Zero parameters Transmission */
+  #define DSI_CMCR_GSR1TX      0x00001000	/* Generic Short Read One parameters Transmission */
+  #define DSI_CMCR_GSR2TX      0x00002000	/* Generic Short Read Two parameters Transmission */
+  #define DSI_CMCR_GLWTX       0x00004000	/* Generic Long Write Transmission */
+  #define DSI_CMCR_DSW0TX      0x00010000	/* DCS Short Write Zero parameter Transmission */
+  #define DSI_CMCR_DSW1TX      0x00020000	/* DCS Short Read One parameter Transmission */
+  #define DSI_CMCR_DSR0TX      0x00040000	/* DCS Short Read Zero parameter Transmission */
+  #define DSI_CMCR_DLWTX       0x00080000	/* DCS Long Write Transmission */
+  #define DSI_CMCR_MRDPS       0x01000000	/* Maximum Read Packet Size */
+#define TOFF_DSI_GHCR      0x006C	/* (RW) DSI Host Generic Header Configuration Register */
+  #define DSI_GHCR_DT          0x0000003F	/* Type */
+  #define DSI_GHCR_DT0         0x00000001
+  #define DSI_GHCR_DT1         0x00000002
+  #define DSI_GHCR_DT2         0x00000004
+  #define DSI_GHCR_DT3         0x00000008
+  #define DSI_GHCR_DT4         0x00000010
+  #define DSI_GHCR_DT5         0x00000020
+  #define DSI_GHCR_VCID        0x000000C0	/* Channel */
+  #define DSI_GHCR_VCID0       0x00000040
+  #define DSI_GHCR_VCID1       0x00000080
+  #define DSI_GHCR_WCLSB       0x0000FF00	/* WordCount LSB */
+  #define DSI_GHCR_WCLSB0      0x00000100
+  #define DSI_GHCR_WCLSB1      0x00000200
+  #define DSI_GHCR_WCLSB2      0x00000400
+  #define DSI_GHCR_WCLSB3      0x00000800
+  #define DSI_GHCR_WCLSB4      0x00001000
+  #define DSI_GHCR_WCLSB5      0x00002000
+  #define DSI_GHCR_WCLSB6      0x00004000
+  #define DSI_GHCR_WCLSB7      0x00008000
+  #define DSI_GHCR_WCMSB       0x00FF0000	/* WordCount MSB */
+  #define DSI_GHCR_WCMSB0      0x00010000
+  #define DSI_GHCR_WCMSB1      0x00020000
+  #define DSI_GHCR_WCMSB2      0x00040000
+  #define DSI_GHCR_WCMSB3      0x00080000
+  #define DSI_GHCR_WCMSB4      0x00100000
+  #define DSI_GHCR_WCMSB5      0x00200000
+  #define DSI_GHCR_WCMSB6      0x00400000
+  #define DSI_GHCR_WCMSB7      0x00800000
+#define TOFF_DSI_GPDR      0x0070	/* (RW) DSI Host Generic Payload Data Register */
+  #define DSI_GPDR_DATA1       0x000000FF	/* Payload Byte 1 */
+  #define DSI_GPDR_DATA1_0     0x00000001
+  #define DSI_GPDR_DATA1_1     0x00000002
+  #define DSI_GPDR_DATA1_2     0x00000004
+  #define DSI_GPDR_DATA1_3     0x00000008
+  #define DSI_GPDR_DATA1_4     0x00000010
+  #define DSI_GPDR_DATA1_5     0x00000020
+  #define DSI_GPDR_DATA1_6     0x00000040
+  #define DSI_GPDR_DATA1_7     0x00000080
+  #define DSI_GPDR_DATA2       0x0000FF00	/* Payload Byte 2 */
+  #define DSI_GPDR_DATA2_0     0x00000100
+  #define DSI_GPDR_DATA2_1     0x00000200
+  #define DSI_GPDR_DATA2_2     0x00000400
+  #define DSI_GPDR_DATA2_3     0x00000800
+  #define DSI_GPDR_DATA2_4     0x00001000
+  #define DSI_GPDR_DATA2_5     0x00002000
+  #define DSI_GPDR_DATA2_6     0x00004000
+  #define DSI_GPDR_DATA2_7     0x00008000
+  #define DSI_GPDR_DATA3       0x00FF0000	/* Payload Byte 3 */
+  #define DSI_GPDR_DATA3_0     0x00010000
+  #define DSI_GPDR_DATA3_1     0x00020000
+  #define DSI_GPDR_DATA3_2     0x00040000
+  #define DSI_GPDR_DATA3_3     0x00080000
+  #define DSI_GPDR_DATA3_4     0x00100000
+  #define DSI_GPDR_DATA3_5     0x00200000
+  #define DSI_GPDR_DATA3_6     0x00400000
+  #define DSI_GPDR_DATA3_7     0x00800000
+  #define DSI_GPDR_DATA4       0xFF000000	/* Payload Byte 4 */
+  #define DSI_GPDR_DATA4_0     0x01000000
+  #define DSI_GPDR_DATA4_1     0x02000000
+  #define DSI_GPDR_DATA4_2     0x04000000
+  #define DSI_GPDR_DATA4_3     0x08000000
+  #define DSI_GPDR_DATA4_4     0x10000000
+  #define DSI_GPDR_DATA4_5     0x20000000
+  #define DSI_GPDR_DATA4_6     0x40000000
+  #define DSI_GPDR_DATA4_7     0x80000000
+#define TOFF_DSI_GPSR      0x0074	/* (RW) DSI Host Generic Packet Status Register */
+  #define DSI_GPSR_CMDFE       0x00000001	/* Command FIFO Empty */
+  #define DSI_GPSR_CMDFF       0x00000002	/* Command FIFO Full */
+  #define DSI_GPSR_PWRFE       0x00000004	/* Payload Write FIFO Empty */
+  #define DSI_GPSR_PWRFF       0x00000008	/* Payload Write FIFO Full */
+  #define DSI_GPSR_PRDFE       0x00000010	/* Payload Read FIFO Empty */
+  #define DSI_GPSR_PRDFF       0x00000020	/* Payload Read FIFO Full */
+  #define DSI_GPSR_RCB         0x00000040	/* Read Command Busy */
+#define TOFF_DSI_TCCR      0x0078	/* (RW) DSI Host Timeout Counter Configuration Register */
+#define TOFF_DSI_TCCR0     0x0078	/* (RW) DSI Host Timeout Counter Configuration Register0 */
+  #define DSI_TCCR0_LPRX_TOCNT    0x0000FFFF	/* Low-power Reception Timeout Counter */
+  #define DSI_TCCR0_LPRX_TOCNT0   0x00000001
+  #define DSI_TCCR0_LPRX_TOCNT1   0x00000002
+  #define DSI_TCCR0_LPRX_TOCNT2   0x00000004
+  #define DSI_TCCR0_LPRX_TOCNT3   0x00000008
+  #define DSI_TCCR0_LPRX_TOCNT4   0x00000010
+  #define DSI_TCCR0_LPRX_TOCNT5   0x00000020
+  #define DSI_TCCR0_LPRX_TOCNT6   0x00000040
+  #define DSI_TCCR0_LPRX_TOCNT7   0x00000080
+  #define DSI_TCCR0_LPRX_TOCNT8   0x00000100
+  #define DSI_TCCR0_LPRX_TOCNT9   0x00000200
+  #define DSI_TCCR0_LPRX_TOCNT10  0x00000400
+  #define DSI_TCCR0_LPRX_TOCNT11  0x00000800
+  #define DSI_TCCR0_LPRX_TOCNT12  0x00001000
+  #define DSI_TCCR0_LPRX_TOCNT13  0x00002000
+  #define DSI_TCCR0_LPRX_TOCNT14  0x00004000
+  #define DSI_TCCR0_LPRX_TOCNT15  0x00008000
+  #define DSI_TCCR0_HSTX_TOCNT    0xFFFF0000	/* High-Speed Transmission Timeout Counter */
+  #define DSI_TCCR0_HSTX_TOCNT0   0x00010000
+  #define DSI_TCCR0_HSTX_TOCNT1   0x00020000
+  #define DSI_TCCR0_HSTX_TOCNT2   0x00040000
+  #define DSI_TCCR0_HSTX_TOCNT3   0x00080000
+  #define DSI_TCCR0_HSTX_TOCNT4   0x00100000
+  #define DSI_TCCR0_HSTX_TOCNT5   0x00200000
+  #define DSI_TCCR0_HSTX_TOCNT6   0x00400000
+  #define DSI_TCCR0_HSTX_TOCNT7   0x00800000
+  #define DSI_TCCR0_HSTX_TOCNT8   0x01000000
+  #define DSI_TCCR0_HSTX_TOCNT9   0x02000000
+  #define DSI_TCCR0_HSTX_TOCNT10  0x04000000
+  #define DSI_TCCR0_HSTX_TOCNT11  0x08000000
+  #define DSI_TCCR0_HSTX_TOCNT12  0x10000000
+  #define DSI_TCCR0_HSTX_TOCNT13  0x20000000
+  #define DSI_TCCR0_HSTX_TOCNT14  0x40000000
+  #define DSI_TCCR0_HSTX_TOCNT15  0x80000000
+#define TOFF_DSI_TCCR1     0x007C	/* (RW) DSI Host Timeout Counter Configuration Register1 */
+  #define DSI_TCCR1_HSRD_TOCNT    0x0000FFFF	/* High-Speed Read Timeout Counter */
+  #define DSI_TCCR1_HSRD_TOCNT0   0x00000001
+  #define DSI_TCCR1_HSRD_TOCNT1   0x00000002
+  #define DSI_TCCR1_HSRD_TOCNT2   0x00000004
+  #define DSI_TCCR1_HSRD_TOCNT3   0x00000008
+  #define DSI_TCCR1_HSRD_TOCNT4   0x00000010
+  #define DSI_TCCR1_HSRD_TOCNT5   0x00000020
+  #define DSI_TCCR1_HSRD_TOCNT6   0x00000040
+  #define DSI_TCCR1_HSRD_TOCNT7   0x00000080
+  #define DSI_TCCR1_HSRD_TOCNT8   0x00000100
+  #define DSI_TCCR1_HSRD_TOCNT9   0x00000200
+  #define DSI_TCCR1_HSRD_TOCNT10  0x00000400
+  #define DSI_TCCR1_HSRD_TOCNT11  0x00000800
+  #define DSI_TCCR1_HSRD_TOCNT12  0x00001000
+  #define DSI_TCCR1_HSRD_TOCNT13  0x00002000
+  #define DSI_TCCR1_HSRD_TOCNT14  0x00004000
+  #define DSI_TCCR1_HSRD_TOCNT15  0x00008000
+#define TOFF_DSI_TCCR2     0x0080	/* (RW) DSI Host Timeout Counter Configuration Register2 */
+  #define DSI_TCCR2_LPRD_TOCNT    0x0000FFFF	/* Low-Power Read Timeout Counter */
+  #define DSI_TCCR2_LPRD_TOCNT0   0x00000001
+  #define DSI_TCCR2_LPRD_TOCNT1   0x00000002
+  #define DSI_TCCR2_LPRD_TOCNT2   0x00000004
+  #define DSI_TCCR2_LPRD_TOCNT3   0x00000008
+  #define DSI_TCCR2_LPRD_TOCNT4   0x00000010
+  #define DSI_TCCR2_LPRD_TOCNT5   0x00000020
+  #define DSI_TCCR2_LPRD_TOCNT6   0x00000040
+  #define DSI_TCCR2_LPRD_TOCNT7   0x00000080
+  #define DSI_TCCR2_LPRD_TOCNT8   0x00000100
+  #define DSI_TCCR2_LPRD_TOCNT9   0x00000200
+  #define DSI_TCCR2_LPRD_TOCNT10  0x00000400
+  #define DSI_TCCR2_LPRD_TOCNT11  0x00000800
+  #define DSI_TCCR2_LPRD_TOCNT12  0x00001000
+  #define DSI_TCCR2_LPRD_TOCNT13  0x00002000
+  #define DSI_TCCR2_LPRD_TOCNT14  0x00004000
+  #define DSI_TCCR2_LPRD_TOCNT15  0x00008000
+#define TOFF_DSI_TCCR3     0x0084	/* (RW) DSI Host Timeout Counter Configuration Register3 */
+  #define DSI_TCCR3_HSWR_TOCNT    0x0000FFFF	/* High-Speed Write Timeout Counter */
+  #define DSI_TCCR3_HSWR_TOCNT0   0x00000001
+  #define DSI_TCCR3_HSWR_TOCNT1   0x00000002
+  #define DSI_TCCR3_HSWR_TOCNT2   0x00000004
+  #define DSI_TCCR3_HSWR_TOCNT3   0x00000008
+  #define DSI_TCCR3_HSWR_TOCNT4   0x00000010
+  #define DSI_TCCR3_HSWR_TOCNT5   0x00000020
+  #define DSI_TCCR3_HSWR_TOCNT6   0x00000040
+  #define DSI_TCCR3_HSWR_TOCNT7   0x00000080
+  #define DSI_TCCR3_HSWR_TOCNT8   0x00000100
+  #define DSI_TCCR3_HSWR_TOCNT9   0x00000200
+  #define DSI_TCCR3_HSWR_TOCNT10  0x00000400
+  #define DSI_TCCR3_HSWR_TOCNT11  0x00000800
+  #define DSI_TCCR3_HSWR_TOCNT12  0x00001000
+  #define DSI_TCCR3_HSWR_TOCNT13  0x00002000
+  #define DSI_TCCR3_HSWR_TOCNT14  0x00004000
+  #define DSI_TCCR3_HSWR_TOCNT15  0x00008000
+  #define DSI_TCCR3_PM            0x01000000	/* Presp Mode */
+#define TOFF_DSI_TCCR4     0x0088	/* (RW) DSI Host Timeout Counter Configuration Register4 */
+  #define DSI_TCCR4_LPWR_TOCNT    0x0000FFFF	/* Low-Power Write Timeout Counter */
+  #define DSI_TCCR4_LPWR_TOCNT0   0x00000001
+  #define DSI_TCCR4_LPWR_TOCNT1   0x00000002
+  #define DSI_TCCR4_LPWR_TOCNT2   0x00000004
+  #define DSI_TCCR4_LPWR_TOCNT3   0x00000008
+  #define DSI_TCCR4_LPWR_TOCNT4   0x00000010
+  #define DSI_TCCR4_LPWR_TOCNT5   0x00000020
+  #define DSI_TCCR4_LPWR_TOCNT6   0x00000040
+  #define DSI_TCCR4_LPWR_TOCNT7   0x00000080
+  #define DSI_TCCR4_LPWR_TOCNT8   0x00000100
+  #define DSI_TCCR4_LPWR_TOCNT9   0x00000200
+  #define DSI_TCCR4_LPWR_TOCNT10  0x00000400
+  #define DSI_TCCR4_LPWR_TOCNT11  0x00000800
+  #define DSI_TCCR4_LPWR_TOCNT12  0x00001000
+  #define DSI_TCCR4_LPWR_TOCNT13  0x00002000
+  #define DSI_TCCR4_LPWR_TOCNT14  0x00004000
+  #define DSI_TCCR4_LPWR_TOCNT15  0x00008000
+#define TOFF_DSI_TCCR5     0x008C	/* (RW) DSI Host Timeout Counter Configuration Register5 */
+  #define DSI_TCCR5_BTA_TOCNT     0x0000FFFF	/* Bus-Turn-Around Timeout Counter */
+  #define DSI_TCCR5_BTA_TOCNT0    0x00000001
+  #define DSI_TCCR5_BTA_TOCNT1    0x00000002
+  #define DSI_TCCR5_BTA_TOCNT2    0x00000004
+  #define DSI_TCCR5_BTA_TOCNT3    0x00000008
+  #define DSI_TCCR5_BTA_TOCNT4    0x00000010
+  #define DSI_TCCR5_BTA_TOCNT5    0x00000020
+  #define DSI_TCCR5_BTA_TOCNT6    0x00000040
+  #define DSI_TCCR5_BTA_TOCNT7    0x00000080
+  #define DSI_TCCR5_BTA_TOCNT8    0x00000100
+  #define DSI_TCCR5_BTA_TOCNT9    0x00000200
+  #define DSI_TCCR5_BTA_TOCNT10   0x00000400
+  #define DSI_TCCR5_BTA_TOCNT11   0x00000800
+  #define DSI_TCCR5_BTA_TOCNT12   0x00001000
+  #define DSI_TCCR5_BTA_TOCNT13   0x00002000
+  #define DSI_TCCR5_BTA_TOCNT14   0x00004000
+  #define DSI_TCCR5_BTA_TOCNT15   0x00008000
+#define TOFF_DSI_TDCR      0x0090	/* (RW) DSI Host 3D Configuration Register */
+  #define DSI_TDCR_3DM         0x00000003	/* 3D Mode */
+  #define DSI_TDCR_3DM0        0x00000001
+  #define DSI_TDCR_3DM1        0x00000002
+  #define DSI_TDCR_3DF         0x0000000C	/* 3D Format */
+  #define DSI_TDCR_3DF0        0x00000004
+  #define DSI_TDCR_3DF1        0x00000008
+  #define DSI_TDCR_SVS         0x00000010	/* Second VSYNC */
+  #define DSI_TDCR_RF          0x00000020	/* Right First */
+  #define DSI_TDCR_S3DC        0x00010000	/* Send 3D Control */
+#define TOFF_DSI_CLCR      0x0094	/* (RW) DSI Host Clock Lane Configuration Register */
+  #define DSI_CLCR_DPCC        0x00000001	/* D-PHY Clock Control */
+  #define DSI_CLCR_ACR         0x00000002	/* Automatic Clocklane Control */
+#define TOFF_DSI_CLTCR     0x0098	/* (RW) DSI Host Clock Lane Timer Configuration Register */
+  #define DSI_CLTCR_LP2HS_TIME  0x000003FF	/* Low-Power to High-Speed Time */
+  #define DSI_CLTCR_LP2HS_TIME0 0x00000001
+  #define DSI_CLTCR_LP2HS_TIME1 0x00000002
+  #define DSI_CLTCR_LP2HS_TIME2 0x00000004
+  #define DSI_CLTCR_LP2HS_TIME3 0x00000008
+  #define DSI_CLTCR_LP2HS_TIME4 0x00000010
+  #define DSI_CLTCR_LP2HS_TIME5 0x00000020
+  #define DSI_CLTCR_LP2HS_TIME6 0x00000040
+  #define DSI_CLTCR_LP2HS_TIME7 0x00000080
+  #define DSI_CLTCR_LP2HS_TIME8 0x00000100
+  #define DSI_CLTCR_LP2HS_TIME9 0x00000200
+  #define DSI_CLTCR_HS2LP_TIME  0x03FF0000	/* High-Speed to Low-Power Time */
+  #define DSI_CLTCR_HS2LP_TIME0 0x00010000
+  #define DSI_CLTCR_HS2LP_TIME1 0x00020000
+  #define DSI_CLTCR_HS2LP_TIME2 0x00040000
+  #define DSI_CLTCR_HS2LP_TIME3 0x00080000
+  #define DSI_CLTCR_HS2LP_TIME4 0x00100000
+  #define DSI_CLTCR_HS2LP_TIME5 0x00200000
+  #define DSI_CLTCR_HS2LP_TIME6 0x00400000
+  #define DSI_CLTCR_HS2LP_TIME7 0x00800000
+  #define DSI_CLTCR_HS2LP_TIME8 0x01000000
+  #define DSI_CLTCR_HS2LP_TIME9 0x02000000
+#define TOFF_DSI_DLTCR     0x009C	/* (RW) DSI Host Data Lane Timer Configuration Register */
+  #define DSI_DLTCR_MRD_TIME    0x00007FFF	/* Maximum Read Time */
+  #define DSI_DLTCR_MRD_TIME0   0x00000001
+  #define DSI_DLTCR_MRD_TIME1   0x00000002
+  #define DSI_DLTCR_MRD_TIME2   0x00000004
+  #define DSI_DLTCR_MRD_TIME3   0x00000008
+  #define DSI_DLTCR_MRD_TIME4   0x00000010
+  #define DSI_DLTCR_MRD_TIME5   0x00000020
+  #define DSI_DLTCR_MRD_TIME6   0x00000040
+  #define DSI_DLTCR_MRD_TIME7   0x00000080
+  #define DSI_DLTCR_MRD_TIME8   0x00000100
+  #define DSI_DLTCR_MRD_TIME9   0x00000200
+  #define DSI_DLTCR_MRD_TIME10  0x00000400
+  #define DSI_DLTCR_MRD_TIME11  0x00000800
+  #define DSI_DLTCR_MRD_TIME12  0x00001000
+  #define DSI_DLTCR_MRD_TIME13  0x00002000
+  #define DSI_DLTCR_MRD_TIME14  0x00004000
+  #define DSI_DLTCR_LP2HS_TIME  0x00FF0000	/* Low-Power To High-Speed Time */
+  #define DSI_DLTCR_LP2HS_TIME0 0x00010000
+  #define DSI_DLTCR_LP2HS_TIME1 0x00020000
+  #define DSI_DLTCR_LP2HS_TIME2 0x00040000
+  #define DSI_DLTCR_LP2HS_TIME3 0x00080000
+  #define DSI_DLTCR_LP2HS_TIME4 0x00100000
+  #define DSI_DLTCR_LP2HS_TIME5 0x00200000
+  #define DSI_DLTCR_LP2HS_TIME6 0x00400000
+  #define DSI_DLTCR_LP2HS_TIME7 0x00800000
+  #define DSI_DLTCR_HS2LP_TIME  0xFF000000	/* High-Speed To Low-Power Time */
+  #define DSI_DLTCR_HS2LP_TIME0 0x01000000
+  #define DSI_DLTCR_HS2LP_TIME1 0x02000000
+  #define DSI_DLTCR_HS2LP_TIME2 0x04000000
+  #define DSI_DLTCR_HS2LP_TIME3 0x08000000
+  #define DSI_DLTCR_HS2LP_TIME4 0x10000000
+  #define DSI_DLTCR_HS2LP_TIME5 0x20000000
+  #define DSI_DLTCR_HS2LP_TIME6 0x40000000
+  #define DSI_DLTCR_HS2LP_TIME7 0x80000000
+#define TOFF_DSI_PCTLR     0x00A0	/* (RW) DSI Host PHY Control Register */
+  #define DSI_PCTLR_DEN        0x00000002	/* Digital Enable */
+  #define DSI_PCTLR_CKE        0x00000004	/* Clock Enable */
+#define TOFF_DSI_PCONFR    0x00A4	/* (RW) DSI Host PHY Configuration Register */
+  #define DSI_PCONFR_NL        0x00000003	/* Number of Lanes */
+  #define DSI_PCONFR_NL0       0x00000001
+  #define DSI_PCONFR_NL1       0x00000002
+  #define DSI_PCONFR_SW_TIME   0x0000FF00	/* Stop Wait Time */
+  #define DSI_PCONFR_SW_TIME0  0x00000100
+  #define DSI_PCONFR_SW_TIME1  0x00000200
+  #define DSI_PCONFR_SW_TIME2  0x00000400
+  #define DSI_PCONFR_SW_TIME3  0x00000800
+  #define DSI_PCONFR_SW_TIME4  0x00001000
+  #define DSI_PCONFR_SW_TIME5  0x00002000
+  #define DSI_PCONFR_SW_TIME6  0x00004000
+  #define DSI_PCONFR_SW_TIME7  0x00008000
+#define TOFF_DSI_PUCR      0x00A8	/* (RW) DSI Host PHY ULPS Control Register */
+  #define DSI_PUCR_URCL        0x00000001	/* ULPS Request on Clock Lane */
+  #define DSI_PUCR_UECL        0x00000002	/* ULPS Exit on Clock Lane */
+  #define DSI_PUCR_URDL        0x00000004	/* ULPS Request on Data Lane */
+  #define DSI_PUCR_UEDL        0x00000008	/* ULPS Exit on Data Lane */
+#define TOFF_DSI_PTTCR     0x00AC	/* (RW) DSI Host PHY TX Triggers Configuration Register */
+  #define DSI_PTTCR_TX_TRIG    0x0000000F	/* Transmission Trigger */
+  #define DSI_PTTCR_TX_TRIG0   0x00000001
+  #define DSI_PTTCR_TX_TRIG1   0x00000002
+  #define DSI_PTTCR_TX_TRIG2   0x00000004
+  #define DSI_PTTCR_TX_TRIG3   0x00000008
+#define TOFF_DSI_PSR       0x00B0	/* (RW) DSI Host PHY Status Register */
+  #define DSI_PSR_PD           0x00000002	/* PHY Direction */
+  #define DSI_PSR_PSSC         0x00000004	/* PHY Stop State Clock lane */
+  #define DSI_PSR_UANC         0x00000008	/* ULPS Active Not Clock lane */
+  #define DSI_PSR_PSS0         0x00000010	/* PHY Stop State lane 0 */
+  #define DSI_PSR_UAN0         0x00000020	/* ULPS Active Not lane 0 */
+  #define DSI_PSR_RUE0         0x00000040	/* RX ULPS Escape lane 0 */
+  #define DSI_PSR_PSS1         0x00000080	/* PHY Stop State lane 1 */
+  #define DSI_PSR_UAN1         0x00000100	/* ULPS Active Not lane 1 */
+#define TOFF_DSI_ISR       0x00BC	/* (RW) DSI Host Interrupt & Status Register */
+#define TOFF_DSI_ISR0      0x00BC	/* (RW) DSI Host Interrupt & Status Register0 */
+  #define DSI_ISR0_AE0         0x00000001	/* Acknowledge Error 0 */
+  #define DSI_ISR0_AE1         0x00000002	/* Acknowledge Error 1 */
+  #define DSI_ISR0_AE2         0x00000004	/* Acknowledge Error 2 */
+  #define DSI_ISR0_AE3         0x00000008	/* Acknowledge Error 3 */
+  #define DSI_ISR0_AE4         0x00000010	/* Acknowledge Error 4 */
+  #define DSI_ISR0_AE5         0x00000020	/* Acknowledge Error 5 */
+  #define DSI_ISR0_AE6         0x00000040	/* Acknowledge Error 6 */
+  #define DSI_ISR0_AE7         0x00000080	/* Acknowledge Error 7 */
+  #define DSI_ISR0_AE8         0x00000100	/* Acknowledge Error 8 */
+  #define DSI_ISR0_AE9         0x00000200	/* Acknowledge Error 9 */
+  #define DSI_ISR0_AE10        0x00000400	/* Acknowledge Error 10 */
+  #define DSI_ISR0_AE11        0x00000800	/* Acknowledge Error 11 */
+  #define DSI_ISR0_AE12        0x00001000	/* Acknowledge Error 12 */
+  #define DSI_ISR0_AE13        0x00002000	/* Acknowledge Error 13 */
+  #define DSI_ISR0_AE14        0x00004000	/* Acknowledge Error 14 */
+  #define DSI_ISR0_AE15        0x00008000	/* Acknowledge Error 15 */
+  #define DSI_ISR0_PE0         0x00010000	/* PHY Error 0 */
+  #define DSI_ISR0_PE1         0x00020000	/* PHY Error 1 */
+  #define DSI_ISR0_PE2         0x00040000	/* PHY Error 2 */
+  #define DSI_ISR0_PE3         0x00080000	/* PHY Error 3 */
+  #define DSI_ISR0_PE4         0x00100000	/* PHY Error 4 */
+#define TOFF_DSI_ISR1      0x00C0	/* (RW) DSI Host Interrupt & Status Register1 */
+  #define DSI_ISR1_TOHSTX      0x00000001	/* Timeout High-Speed Transmission */
+  #define DSI_ISR1_TOLPRX      0x00000002	/* Timeout Low-Power Reception */
+  #define DSI_ISR1_ECCSE       0x00000004	/* ECC Single-bit Error */
+  #define DSI_ISR1_ECCME       0x00000008	/* ECC Multi-bit Error */
+  #define DSI_ISR1_CRCE        0x00000010	/* CRC Error */
+  #define DSI_ISR1_PSE         0x00000020	/* Packet Size Error */
+  #define DSI_ISR1_EOTPE       0x00000040	/* EoTp Error */
+  #define DSI_ISR1_LPWRE       0x00000080	/* LTDC Payload Write Error */
+  #define DSI_ISR1_GCWRE       0x00000100	/* Generic Command Write Error */
+  #define DSI_ISR1_GPWRE       0x00000200	/* Generic Payload Write Error */
+  #define DSI_ISR1_GPTXE       0x00000400	/* Generic Payload Transmit Error */
+  #define DSI_ISR1_GPRDE       0x00000800	/* Generic Payload Read Error */
+  #define DSI_ISR1_GPRXE       0x00001000	/* Generic Payload Receive Error */
+#define TOFF_DSI_IER       0x00C4	/* (RW) DSI Host Interrupt Enable Register */
+#define TOFF_DSI_IER0      0x00C4	/* (RW) DSI Host Interrupt Enable Register0 */
+  #define DSI_IER0_AE0IE       0x00000001	/* Acknowledge Error 0 Interrupt Enable */
+  #define DSI_IER0_AE1IE       0x00000002	/* Acknowledge Error 1 Interrupt Enable */
+  #define DSI_IER0_AE2IE       0x00000004	/* Acknowledge Error 2 Interrupt Enable */
+  #define DSI_IER0_AE3IE       0x00000008	/* Acknowledge Error 3 Interrupt Enable */
+  #define DSI_IER0_AE4IE       0x00000010	/* Acknowledge Error 4 Interrupt Enable */
+  #define DSI_IER0_AE5IE       0x00000020	/* Acknowledge Error 5 Interrupt Enable */
+  #define DSI_IER0_AE6IE       0x00000040	/* Acknowledge Error 6 Interrupt Enable */
+  #define DSI_IER0_AE7IE       0x00000080	/* Acknowledge Error 7 Interrupt Enable */
+  #define DSI_IER0_AE8IE       0x00000100	/* Acknowledge Error 8 Interrupt Enable */
+  #define DSI_IER0_AE9IE       0x00000200	/* Acknowledge Error 9 Interrupt Enable */
+  #define DSI_IER0_AE10IE      0x00000400	/* Acknowledge Error 10 Interrupt Enable */
+  #define DSI_IER0_AE11IE      0x00000800	/* Acknowledge Error 11 Interrupt Enable */
+  #define DSI_IER0_AE12IE      0x00001000	/* Acknowledge Error 12 Interrupt Enable */
+  #define DSI_IER0_AE13IE      0x00002000	/* Acknowledge Error 13 Interrupt Enable */
+  #define DSI_IER0_AE14IE      0x00004000	/* Acknowledge Error 14 Interrupt Enable */
+  #define DSI_IER0_AE15IE      0x00008000	/* Acknowledge Error 15 Interrupt Enable */
+  #define DSI_IER0_PE0IE       0x00010000	/* PHY Error 0 Interrupt Enable */
+  #define DSI_IER0_PE1IE       0x00020000	/* PHY Error 1 Interrupt Enable */
+  #define DSI_IER0_PE2IE       0x00040000	/* PHY Error 2 Interrupt Enable */
+  #define DSI_IER0_PE3IE       0x00080000	/* PHY Error 3 Interrupt Enable */
+  #define DSI_IER0_PE4IE       0x00100000	/* PHY Error 4 Interrupt Enable */
+#define TOFF_DSI_IER1      0x00C8	/* (RW) DSI Host Interrupt Enable Register1 */
+  #define DSI_IER1_TOHSTXIE    0x00000001	/* Timeout High-Speed Transmission Interrupt Enable */
+  #define DSI_IER1_TOLPRXIE    0x00000002	/* Timeout Low-Power Reception Interrupt Enable */
+  #define DSI_IER1_ECCSEIE     0x00000004	/* ECC Single-bit Error Interrupt Enable */
+  #define DSI_IER1_ECCMEIE     0x00000008	/* ECC Multi-bit Error Interrupt Enable */
+  #define DSI_IER1_CRCEIE      0x00000010	/* CRC Error Interrupt Enable */
+  #define DSI_IER1_PSEIE       0x00000020	/* Packet Size Error Interrupt Enable */
+  #define DSI_IER1_EOTPEIE     0x00000040	/* EoTp Error Interrupt Enable */
+  #define DSI_IER1_LPWREIE     0x00000080	/* LTDC Payload Write Error Interrupt Enable */
+  #define DSI_IER1_GCWREIE     0x00000100	/* Generic Command Write Error Interrupt Enable */
+  #define DSI_IER1_GPWREIE     0x00000200	/* Generic Payload Write Error Interrupt Enable */
+  #define DSI_IER1_GPTXEIE     0x00000400	/* Generic Payload Transmit Error Interrupt Enable */
+  #define DSI_IER1_GPRDEIE     0x00000800	/* Generic Payload Read Error Interrupt Enable */
+  #define DSI_IER1_GPRXEIE     0x00001000	/* Generic Payload Receive Error Interrupt Enable */
+#define TOFF_DSI_FIR       0x00D8	/* (RW) DSI Host Force Interrupt Register */
+#define TOFF_DSI_FIR0      0x00D8	/* (RW) DSI Host Force Interrupt Register0 */
+  #define DSI_FIR0_FAE0        0x00000001	/* Force Acknowledge Error 0 */
+  #define DSI_FIR0_FAE1        0x00000002	/* Force Acknowledge Error 1 */
+  #define DSI_FIR0_FAE2        0x00000004	/* Force Acknowledge Error 2 */
+  #define DSI_FIR0_FAE3        0x00000008	/* Force Acknowledge Error 3 */
+  #define DSI_FIR0_FAE4        0x00000010	/* Force Acknowledge Error 4 */
+  #define DSI_FIR0_FAE5        0x00000020	/* Force Acknowledge Error 5 */
+  #define DSI_FIR0_FAE6        0x00000040	/* Force Acknowledge Error 6 */
+  #define DSI_FIR0_FAE7        0x00000080	/* Force Acknowledge Error 7 */
+  #define DSI_FIR0_FAE8        0x00000100	/* Force Acknowledge Error 8 */
+  #define DSI_FIR0_FAE9        0x00000200	/* Force Acknowledge Error 9 */
+  #define DSI_FIR0_FAE10       0x00000400	/* Force Acknowledge Error 10 */
+  #define DSI_FIR0_FAE11       0x00000800	/* Force Acknowledge Error 11 */
+  #define DSI_FIR0_FAE12       0x00001000	/* Force Acknowledge Error 12 */
+  #define DSI_FIR0_FAE13       0x00002000	/* Force Acknowledge Error 13 */
+  #define DSI_FIR0_FAE14       0x00004000	/* Force Acknowledge Error 14 */
+  #define DSI_FIR0_FAE15       0x00008000	/* Force Acknowledge Error 15 */
+  #define DSI_FIR0_FPE0        0x00010000	/* Force PHY Error 0 */
+  #define DSI_FIR0_FPE1        0x00020000	/* Force PHY Error 1 */
+  #define DSI_FIR0_FPE2        0x00040000	/* Force PHY Error 2 */
+  #define DSI_FIR0_FPE3        0x00080000	/* Force PHY Error 3 */
+  #define DSI_FIR0_FPE4        0x00100000	/* Force PHY Error 4 */
+#define TOFF_DSI_FIR1      0x00DC	/* (RW) DSI Host Force Interrupt Register1 */
+  #define DSI_FIR1_FTOHSTX     0x00000001	/* Force Timeout High-Speed Transmission */
+  #define DSI_FIR1_FTOLPRX     0x00000002	/* Force Timeout Low-Power Reception */
+  #define DSI_FIR1_FECCSE      0x00000004	/* Force ECC Single-bit Error */
+  #define DSI_FIR1_FECCME      0x00000008	/* Force ECC Multi-bit Error */
+  #define DSI_FIR1_FCRCE       0x00000010	/* Force CRC Error */
+  #define DSI_FIR1_FPSE        0x00000020	/* Force Packet Size Error */
+  #define DSI_FIR1_FEOTPE      0x00000040	/* Force EoTp Error */
+  #define DSI_FIR1_FLPWRE      0x00000080	/* Force LTDC Payload Write Error */
+  #define DSI_FIR1_FGCWRE      0x00000100	/* Force Generic Command Write Error */
+  #define DSI_FIR1_FGPWRE      0x00000200	/* Force Generic Payload Write Error */
+  #define DSI_FIR1_FGPTXE      0x00000400	/* Force Generic Payload Transmit Error */
+  #define DSI_FIR1_FGPRDE      0x00000800	/* Force Generic Payload Read Error */
+  #define DSI_FIR1_FGPRXE      0x00001000	/* Force Generic Payload Receive Error */
+#define TOFF_DSI_VSCR      0x0100	/* (RW) DSI Host Video Shadow Control Register */
+  #define DSI_VSCR_EN          0x00000001	/* Enable */
+  #define DSI_VSCR_UR          0x00000100	/* Update Register */
+#define TOFF_DSI_LCVCIDR   0x010C	/* (RW) DSI Host LTDC Current VCID Register */
+  #define DSI_LCVCIDR_VCID     0x00000003	/* Virtual Channel ID */
+  #define DSI_LCVCIDR_VCID0    0x00000001
+  #define DSI_LCVCIDR_VCID1    0x00000002
+#define TOFF_DSI_LCCCR     0x0110	/* (RW) DSI Host LTDC Current Color Coding Register */
+  #define DSI_LCCCR_COLC       0x0000000F	/* Color Coding */
+  #define DSI_LCCCR_COLC0      0x00000001
+  #define DSI_LCCCR_COLC1      0x00000002
+  #define DSI_LCCCR_COLC2      0x00000004
+  #define DSI_LCCCR_COLC3      0x00000008
+  #define DSI_LCCCR_LPE        0x00000100	/* Loosely Packed Enable */
+#define TOFF_DSI_LPMCCR    0x0118	/* (RW) DSI Host Low-power Mode Current Configuration Register */
+  #define DSI_LPMCCR_VLPSIZE   0x000000FF	/* VACT Largest Packet Size */
+  #define DSI_LPMCCR_VLPSIZE0  0x00000001
+  #define DSI_LPMCCR_VLPSIZE1  0x00000002
+  #define DSI_LPMCCR_VLPSIZE2  0x00000004
+  #define DSI_LPMCCR_VLPSIZE3  0x00000008
+  #define DSI_LPMCCR_VLPSIZE4  0x00000010
+  #define DSI_LPMCCR_VLPSIZE5  0x00000020
+  #define DSI_LPMCCR_VLPSIZE6  0x00000040
+  #define DSI_LPMCCR_VLPSIZE7  0x00000080
+  #define DSI_LPMCCR_LPSIZE    0x00FF0000	/* Largest Packet Size */
+  #define DSI_LPMCCR_LPSIZE0   0x00010000
+  #define DSI_LPMCCR_LPSIZE1   0x00020000
+  #define DSI_LPMCCR_LPSIZE2   0x00040000
+  #define DSI_LPMCCR_LPSIZE3   0x00080000
+  #define DSI_LPMCCR_LPSIZE4   0x00100000
+  #define DSI_LPMCCR_LPSIZE5   0x00200000
+  #define DSI_LPMCCR_LPSIZE6   0x00400000
+  #define DSI_LPMCCR_LPSIZE7   0x00800000
+#define TOFF_DSI_VMCCR     0x0138	/* (RW) DSI Host Video Mode Current Configuration Register */
+  #define DSI_VMCCR_VMT        0x00000003	/* Video Mode Type */
+  #define DSI_VMCCR_VMT0       0x00000001
+  #define DSI_VMCCR_VMT1       0x00000002
+  #define DSI_VMCCR_LPVSAE     0x00000100	/* Low-power Vertical Sync time Enable */
+  #define DSI_VMCCR_LPVBPE     0x00000200	/* Low-power Vertical Back-porch Enable */
+  #define DSI_VMCCR_LPVFPE     0x00000400	/* Low-power Vertical Front-porch Enable */
+  #define DSI_VMCCR_LPVAE      0x00000800	/* Low-power Vertical Active Enable */
+  #define DSI_VMCCR_LPHBPE     0x00001000	/* Low-power Horizontal Back-porch Enable */
+  #define DSI_VMCCR_LPHFE      0x00002000	/* Low-power Horizontal Front-porch Enable */
+  #define DSI_VMCCR_FBTAAE     0x00004000	/* Frame BTA Acknowledge Enable */
+  #define DSI_VMCCR_LPCE       0x00008000	/* Low-power Command Enable */
+#define TOFF_DSI_VPCCR     0x013C	/* (RW) DSI Host Video Packet Current Configuration Register */
+  #define DSI_VPCCR_VPSIZE     0x00003FFF	/* Video Packet Size */
+  #define DSI_VPCCR_VPSIZE0    0x00000001
+  #define DSI_VPCCR_VPSIZE1    0x00000002
+  #define DSI_VPCCR_VPSIZE2    0x00000004
+  #define DSI_VPCCR_VPSIZE3    0x00000008
+  #define DSI_VPCCR_VPSIZE4    0x00000010
+  #define DSI_VPCCR_VPSIZE5    0x00000020
+  #define DSI_VPCCR_VPSIZE6    0x00000040
+  #define DSI_VPCCR_VPSIZE7    0x00000080
+  #define DSI_VPCCR_VPSIZE8    0x00000100
+  #define DSI_VPCCR_VPSIZE9    0x00000200
+  #define DSI_VPCCR_VPSIZE10   0x00000400
+  #define DSI_VPCCR_VPSIZE11   0x00000800
+  #define DSI_VPCCR_VPSIZE12   0x00001000
+  #define DSI_VPCCR_VPSIZE13   0x00002000
+#define TOFF_DSI_VCCCR     0x0140	/* (RW) DSI Host Video Chuncks Current Configuration Register */
+  #define DSI_VCCCR_NUMC       0x00001FFF	/* Number of Chunks */
+  #define DSI_VCCCR_NUMC0      0x00000001
+  #define DSI_VCCCR_NUMC1      0x00000002
+  #define DSI_VCCCR_NUMC2      0x00000004
+  #define DSI_VCCCR_NUMC3      0x00000008
+  #define DSI_VCCCR_NUMC4      0x00000010
+  #define DSI_VCCCR_NUMC5      0x00000020
+  #define DSI_VCCCR_NUMC6      0x00000040
+  #define DSI_VCCCR_NUMC7      0x00000080
+  #define DSI_VCCCR_NUMC8      0x00000100
+  #define DSI_VCCCR_NUMC9      0x00000200
+  #define DSI_VCCCR_NUMC10     0x00000400
+  #define DSI_VCCCR_NUMC11     0x00000800
+  #define DSI_VCCCR_NUMC12     0x00001000
+#define TOFF_DSI_VNPCCR    0x0144	/* (RW) DSI Host Video Null Packet Current Configuration Register */
+  #define DSI_VNPCCR_NPSIZE    0x00001FFF	/* Number of Chunks */
+  #define DSI_VNPCCR_NPSIZE0   0x00000001
+  #define DSI_VNPCCR_NPSIZE1   0x00000002
+  #define DSI_VNPCCR_NPSIZE2   0x00000004
+  #define DSI_VNPCCR_NPSIZE3   0x00000008
+  #define DSI_VNPCCR_NPSIZE4   0x00000010
+  #define DSI_VNPCCR_NPSIZE5   0x00000020
+  #define DSI_VNPCCR_NPSIZE6   0x00000040
+  #define DSI_VNPCCR_NPSIZE7   0x00000080
+  #define DSI_VNPCCR_NPSIZE8   0x00000100
+  #define DSI_VNPCCR_NPSIZE9   0x00000200
+  #define DSI_VNPCCR_NPSIZE10  0x00000400
+  #define DSI_VNPCCR_NPSIZE11  0x00000800
+  #define DSI_VNPCCR_NPSIZE12  0x00001000
+#define TOFF_DSI_VHSACCR   0x0148	/* (RW) DSI Host Video HSA Current Configuration Register */
+  #define DSI_VHSACCR_HSA      0x00000FFF	/* Horizontal Synchronism Active duration */
+  #define DSI_VHSACCR_HSA0     0x00000001
+  #define DSI_VHSACCR_HSA1     0x00000002
+  #define DSI_VHSACCR_HSA2     0x00000004
+  #define DSI_VHSACCR_HSA3     0x00000008
+  #define DSI_VHSACCR_HSA4     0x00000010
+  #define DSI_VHSACCR_HSA5     0x00000020
+  #define DSI_VHSACCR_HSA6     0x00000040
+  #define DSI_VHSACCR_HSA7     0x00000080
+  #define DSI_VHSACCR_HSA8     0x00000100
+  #define DSI_VHSACCR_HSA9     0x00000200
+  #define DSI_VHSACCR_HSA10    0x00000400
+  #define DSI_VHSACCR_HSA11    0x00000800
+#define TOFF_DSI_VHBPCCR   0x014C	/* (RW) DSI Host Video HBP Current Configuration Register */
+  #define DSI_VHBPCCR_HBP      0x00000FFF	/* Horizontal Back-Porch duration */
+  #define DSI_VHBPCCR_HBP0     0x00000001
+  #define DSI_VHBPCCR_HBP1     0x00000002
+  #define DSI_VHBPCCR_HBP2     0x00000004
+  #define DSI_VHBPCCR_HBP3     0x00000008
+  #define DSI_VHBPCCR_HBP4     0x00000010
+  #define DSI_VHBPCCR_HBP5     0x00000020
+  #define DSI_VHBPCCR_HBP6     0x00000040
+  #define DSI_VHBPCCR_HBP7     0x00000080
+  #define DSI_VHBPCCR_HBP8     0x00000100
+  #define DSI_VHBPCCR_HBP9     0x00000200
+  #define DSI_VHBPCCR_HBP10    0x00000400
+  #define DSI_VHBPCCR_HBP11    0x00000800
+#define TOFF_DSI_VLCCR     0x0150	/* (RW) DSI Host Video Line Current Configuration Register */
+  #define DSI_VLCCR_HLINE      0x00007FFF	/* Horizontal Line duration */
+  #define DSI_VLCCR_HLINE0     0x00000001
+  #define DSI_VLCCR_HLINE1     0x00000002
+  #define DSI_VLCCR_HLINE2     0x00000004
+  #define DSI_VLCCR_HLINE3     0x00000008
+  #define DSI_VLCCR_HLINE4     0x00000010
+  #define DSI_VLCCR_HLINE5     0x00000020
+  #define DSI_VLCCR_HLINE6     0x00000040
+  #define DSI_VLCCR_HLINE7     0x00000080
+  #define DSI_VLCCR_HLINE8     0x00000100
+  #define DSI_VLCCR_HLINE9     0x00000200
+  #define DSI_VLCCR_HLINE10    0x00000400
+  #define DSI_VLCCR_HLINE11    0x00000800
+  #define DSI_VLCCR_HLINE12    0x00001000
+  #define DSI_VLCCR_HLINE13    0x00002000
+  #define DSI_VLCCR_HLINE14    0x00004000
+#define TOFF_DSI_VVSACCR   0x0154	/* (RW) DSI Host Video VSA Current Configuration Register */
+  #define DSI_VVSACCR_VSA      0x000003FF	/* Vertical Synchronism Active duration */
+  #define DSI_VVSACCR_VSA0     0x00000001
+  #define DSI_VVSACCR_VSA1     0x00000002
+  #define DSI_VVSACCR_VSA2     0x00000004
+  #define DSI_VVSACCR_VSA3     0x00000008
+  #define DSI_VVSACCR_VSA4     0x00000010
+  #define DSI_VVSACCR_VSA5     0x00000020
+  #define DSI_VVSACCR_VSA6     0x00000040
+  #define DSI_VVSACCR_VSA7     0x00000080
+  #define DSI_VVSACCR_VSA8     0x00000100
+  #define DSI_VVSACCR_VSA9     0x00000200
+#define TOFF_DSI_VVBPCCR   0x0158	/* (RW) DSI Host Video VBP Current Configuration Register */
+  #define DSI_VVBPCCR_VBP      0x000003FF	/* Vertical Back-Porch duration */
+  #define DSI_VVBPCCR_VBP0     0x00000001
+  #define DSI_VVBPCCR_VBP1     0x00000002
+  #define DSI_VVBPCCR_VBP2     0x00000004
+  #define DSI_VVBPCCR_VBP3     0x00000008
+  #define DSI_VVBPCCR_VBP4     0x00000010
+  #define DSI_VVBPCCR_VBP5     0x00000020
+  #define DSI_VVBPCCR_VBP6     0x00000040
+  #define DSI_VVBPCCR_VBP7     0x00000080
+  #define DSI_VVBPCCR_VBP8     0x00000100
+  #define DSI_VVBPCCR_VBP9     0x00000200
+#define TOFF_DSI_VVFPCCR   0x015C	/* (RW) DSI Host Video VFP Current Configuration Register */
+  #define DSI_VVFPCCR_VFP      0x000003FF	/* Vertical Front-Porch duration */
+  #define DSI_VVFPCCR_VFP0     0x00000001
+  #define DSI_VVFPCCR_VFP1     0x00000002
+  #define DSI_VVFPCCR_VFP2     0x00000004
+  #define DSI_VVFPCCR_VFP3     0x00000008
+  #define DSI_VVFPCCR_VFP4     0x00000010
+  #define DSI_VVFPCCR_VFP5     0x00000020
+  #define DSI_VVFPCCR_VFP6     0x00000040
+  #define DSI_VVFPCCR_VFP7     0x00000080
+  #define DSI_VVFPCCR_VFP8     0x00000100
+  #define DSI_VVFPCCR_VFP9     0x00000200
+#define TOFF_DSI_VVACCR    0x0160	/* (RW) DSI Host Video VA Current Configuration Register */
+  #define DSI_VVACCR_VA        0x00003FFF	/* Vertical Active duration */
+  #define DSI_VVACCR_VA0       0x00000001
+  #define DSI_VVACCR_VA1       0x00000002
+  #define DSI_VVACCR_VA2       0x00000004
+  #define DSI_VVACCR_VA3       0x00000008
+  #define DSI_VVACCR_VA4       0x00000010
+  #define DSI_VVACCR_VA5       0x00000020
+  #define DSI_VVACCR_VA6       0x00000040
+  #define DSI_VVACCR_VA7       0x00000080
+  #define DSI_VVACCR_VA8       0x00000100
+  #define DSI_VVACCR_VA9       0x00000200
+  #define DSI_VVACCR_VA10      0x00000400
+  #define DSI_VVACCR_VA11      0x00000800
+  #define DSI_VVACCR_VA12      0x00001000
+  #define DSI_VVACCR_VA13      0x00002000
+#define TOFF_DSI_TDCCR     0x0190	/* (RW) DSI Host 3D Current Configuration Register */
+  #define DSI_TDCCR_3DM        0x00000003	/* 3D Mode */
+  #define DSI_TDCCR_3DM0       0x00000001
+  #define DSI_TDCCR_3DM1       0x00000002
+  #define DSI_TDCCR_3DF        0x0000000C	/* 3D Format */
+  #define DSI_TDCCR_3DF0       0x00000004
+  #define DSI_TDCCR_3DF1       0x00000008
+  #define DSI_TDCCR_SVS        0x00000010	/* Second VSYNC */
+  #define DSI_TDCCR_RF         0x00000020	/* Right First */
+  #define DSI_TDCCR_S3DC       0x00010000	/* Send 3D Control */
+#define TOFF_DSI_WCFGR     0x0400	/* (RW) DSI Wrapper Configuration Register */
+  #define DSI_WCFGR_DSIM       0x00000001	/* DSI Mode */
+  #define DSI_WCFGR_COLMUX     0x0000000E	/* Color Multiplexing */
+  #define DSI_WCFGR_COLMUX0    0x00000002
+  #define DSI_WCFGR_COLMUX1    0x00000004
+  #define DSI_WCFGR_COLMUX2    0x00000008
+  #define DSI_WCFGR_TESRC      0x00000010	/* Tearing Effect Source */
+  #define DSI_WCFGR_TEPOL      0x00000020	/* Tearing Effect Polarity */
+  #define DSI_WCFGR_AR         0x00000040	/* Automatic Refresh */
+  #define DSI_WCFGR_VSPOL      0x00000080	/* VSync Polarity */
+#define TOFF_DSI_WCR       0x0404	/* (RW) DSI Wrapper Control Register */
+  #define DSI_WCR_COLM         0x00000001	/* Color Mode */
+  #define DSI_WCR_SHTDN        0x00000002	/* Shutdown */
+  #define DSI_WCR_LTDCEN       0x00000004	/* LTDC Enable */
+  #define DSI_WCR_DSIEN        0x00000008	/* DSI Enable */
+#define TOFF_DSI_WIER      0x0408	/* (RW) DSI Wrapper Interrupt Enable Register */
+  #define DSI_WIER_TEIE        0x00000001	/* Tearing Effect Interrupt Enable */
+  #define DSI_WIER_ERIE        0x00000002	/* End of Refresh Interrupt Enable */
+  #define DSI_WIER_PLLLIE      0x00000200	/* PLL Lock Interrupt Enable */
+  #define DSI_WIER_PLLUIE      0x00000400	/* PLL Unlock Interrupt Enable */
+  #define DSI_WIER_RRIE        0x00002000	/* Regulator Ready Interrupt Enable */
+#define TOFF_DSI_WISR      0x040C	/* (RW) DSI Wrapper Interrupt and Status Register */
+  #define DSI_WISR_TEIF        0x00000001	/* Tearing Effect Interrupt Flag */
+  #define DSI_WISR_ERIF        0x00000002	/* End of Refresh Interrupt Flag */
+  #define DSI_WISR_BUSY        0x00000004	/* Busy Flag */
+  #define DSI_WISR_PLLLS       0x00000100	/* PLL Lock Status */
+  #define DSI_WISR_PLLLIF      0x00000200	/* PLL Lock Interrupt Flag */
+  #define DSI_WISR_PLLUIF      0x00000400	/* PLL Unlock Interrupt Flag */
+  #define DSI_WISR_RRS         0x00001000	/* Regulator Ready Flag */
+  #define DSI_WISR_RRIF        0x00002000	/* Regulator Ready Interrupt Flag */
+#define TOFF_DSI_WIFCR     0x0410	/* (RW) DSI Wrapper Interrupt Flag Clear Register */
+  #define DSI_WIFCR_CTEIF      0x00000001	/* Clear Tearing Effect Interrupt Flag */
+  #define DSI_WIFCR_CERIF      0x00000002	/* Clear End of Refresh Interrupt Flag */
+  #define DSI_WIFCR_CPLLLIF    0x00000200	/* Clear PLL Lock Interrupt Flag */
+  #define DSI_WIFCR_CPLLUIF    0x00000400	/* Clear PLL Unlock Interrupt Flag */
+  #define DSI_WIFCR_CRRIF      0x00002000	/* Clear Regulator Ready Interrupt Flag */
+#define TOFF_DSI_WPCR      0x0418	/* (RW) DSI Wrapper PHY Configuration Register 0-4 */
+#define TOFF_DSI_WPCR0     0x0418	/* (RW) DSI Wrapper PHY Configuration Register0 */
+  #define DSI_WPCR0_UIX4       0x0000003F	/* Unit Interval multiplied by 4 */
+  #define DSI_WPCR0_UIX4_0     0x00000001
+  #define DSI_WPCR0_UIX4_1     0x00000002
+  #define DSI_WPCR0_UIX4_2     0x00000004
+  #define DSI_WPCR0_UIX4_3     0x00000008
+  #define DSI_WPCR0_UIX4_4     0x00000010
+  #define DSI_WPCR0_UIX4_5     0x00000020
+  #define DSI_WPCR0_SWCL       0x00000040	/* Swap pins on clock lane */
+  #define DSI_WPCR0_SWDL0      0x00000080	/* Swap pins on data lane 1 */
+  #define DSI_WPCR0_SWDL1      0x00000100	/* Swap pins on data lane 2 */
+  #define DSI_WPCR0_HSICL      0x00000200	/* Invert the high-speed data signal on clock lane */
+  #define DSI_WPCR0_HSIDL0     0x00000400	/* Invert the high-speed data signal on lane 1 */
+  #define DSI_WPCR0_HSIDL1     0x00000800	/* Invert the high-speed data signal on lane 2 */
+  #define DSI_WPCR0_FTXSMCL    0x00001000	/* Force clock lane in TX stop mode */
+  #define DSI_WPCR0_FTXSMDL    0x00002000	/* Force data lanes in TX stop mode */
+  #define DSI_WPCR0_CDOFFDL    0x00004000	/* Contention detection OFF */
+  #define DSI_WPCR0_TDDL       0x00010000	/* Turn Disable Data Lanes */
+  #define DSI_WPCR0_PDEN       0x00040000	/* Pull-Down Enable */
+  #define DSI_WPCR0_TCLKPREPEN 0x00080000	/* Timer for t-CLKPREP Enable */
+  #define DSI_WPCR0_TCLKZEROEN 0x00100000	/* Timer for t-CLKZERO Enable */
+  #define DSI_WPCR0_THSPREPEN  0x00200000	/* Timer for t-HSPREP Enable */
+  #define DSI_WPCR0_THSTRAILEN 0x00400000	/* Timer for t-HSTRAIL Enable */
+  #define DSI_WPCR0_THSZEROEN  0x00800000	/* Timer for t-HSZERO Enable */
+  #define DSI_WPCR0_TLPXDEN    0x01000000	/* Timer for t-LPXD Enable */
+  #define DSI_WPCR0_THSEXITEN  0x02000000	/* Timer for t-HSEXIT Enable */
+  #define DSI_WPCR0_TLPXCEN    0x04000000	/* Timer for t-LPXC Enable */
+  #define DSI_WPCR0_TCLKPOSTEN 0x08000000	/* Timer for t-CLKPOST Enable */
+#define TOFF_DSI_WPCR1     0x041C	/* (RW)DSI Wrapper PHY Configuration Register1 */
+  #define DSI_WPCR1_HSTXDCL    0x00000003	/* High-Speed Transmission Delay on Clock Lane */
+  #define DSI_WPCR1_HSTXDCL0   0x00000001
+  #define DSI_WPCR1_HSTXDCL1   0x00000002
+  #define DSI_WPCR1_HSTXDDL    0x0000000C	/* High-Speed Transmission Delay on Data Lane */
+  #define DSI_WPCR1_HSTXDDL0   0x00000004
+  #define DSI_WPCR1_HSTXDDL1   0x00000008
+  #define DSI_WPCR1_LPSRCCL    0x000000C0	/* Low-Power transmission Slew Rate Compensation on Clock Lane */
+  #define DSI_WPCR1_LPSRCCL0   0x00000040
+  #define DSI_WPCR1_LPSRCCL1   0x00000080
+  #define DSI_WPCR1_LPSRCDL    0x00000300	/* Low-Power transmission Slew Rate Compensation on Data Lane */
+  #define DSI_WPCR1_LPSRCDL0   0x00000100
+  #define DSI_WPCR1_LPSRCDL1   0x00000200
+  #define DSI_WPCR1_SDDC       0x00001000	/* SDD Control */
+  #define DSI_WPCR1_LPRXVCDL   0x0000C000	/* Low-Power Reception V-IL Compensation on Data Lanes */
+  #define DSI_WPCR1_LPRXVCDL0  0x00004000
+  #define DSI_WPCR1_LPRXVCDL1  0x00008000
+  #define DSI_WPCR1_HSTXSRCCL  0x00030000	/* High-Speed Transmission Delay on Clock Lane */
+  #define DSI_WPCR1_HSTXSRCCL0 0x00010000
+  #define DSI_WPCR1_HSTXSRCCL1 0x00020000
+  #define DSI_WPCR1_HSTXSRCDL  0x000C0000	/* High-Speed Transmission Delay on Data Lane */
+  #define DSI_WPCR1_HSTXSRCDL0 0x00040000
+  #define DSI_WPCR1_HSTXSRCDL1 0x00080000
+  #define DSI_WPCR1_FLPRXLPM   0x00400000	/* Forces LP Receiver in Low-Power Mode */
+  #define DSI_WPCR1_LPRXFT     0x06000000	/* Low-Power RX low-pass Filtering Tuning */
+  #define DSI_WPCR1_LPRXFT0    0x02000000
+  #define DSI_WPCR1_LPRXFT1    0x04000000
+#define TOFF_DSI_WPCR2     0x0420	/* (RW)DSI Wrapper PHY Configuration Register2 */
+  #define DSI_WPCR2_TCLKPREP   0x000000FF	/* t-CLKPREP */
+  #define DSI_WPCR2_TCLKPREP0  0x00000001
+  #define DSI_WPCR2_TCLKPREP1  0x00000002
+  #define DSI_WPCR2_TCLKPREP2  0x00000004
+  #define DSI_WPCR2_TCLKPREP3  0x00000008
+  #define DSI_WPCR2_TCLKPREP4  0x00000010
+  #define DSI_WPCR2_TCLKPREP5  0x00000020
+  #define DSI_WPCR2_TCLKPREP6  0x00000040
+  #define DSI_WPCR2_TCLKPREP7  0x00000080
+  #define DSI_WPCR2_TCLKZERO   0x0000FF00	/* t-CLKZERO */
+  #define DSI_WPCR2_TCLKZERO0  0x00000100
+  #define DSI_WPCR2_TCLKZERO1  0x00000200
+  #define DSI_WPCR2_TCLKZERO2  0x00000400
+  #define DSI_WPCR2_TCLKZERO3  0x00000800
+  #define DSI_WPCR2_TCLKZERO4  0x00001000
+  #define DSI_WPCR2_TCLKZERO5  0x00002000
+  #define DSI_WPCR2_TCLKZERO6  0x00004000
+  #define DSI_WPCR2_TCLKZERO7  0x00008000
+  #define DSI_WPCR2_THSPREP    0x00FF0000	/* t-HSPREP */
+  #define DSI_WPCR2_THSPREP0   0x00010000
+  #define DSI_WPCR2_THSPREP1   0x00020000
+  #define DSI_WPCR2_THSPREP2   0x00040000
+  #define DSI_WPCR2_THSPREP3   0x00080000
+  #define DSI_WPCR2_THSPREP4   0x00100000
+  #define DSI_WPCR2_THSPREP5   0x00200000
+  #define DSI_WPCR2_THSPREP6   0x00400000
+  #define DSI_WPCR2_THSPREP7   0x00800000
+  #define DSI_WPCR2_THSTRAIL   0xFF000000	/* t-HSTRAIL */
+  #define DSI_WPCR2_THSTRAIL0  0x01000000
+  #define DSI_WPCR2_THSTRAIL1  0x02000000
+  #define DSI_WPCR2_THSTRAIL2  0x04000000
+  #define DSI_WPCR2_THSTRAIL3  0x08000000
+  #define DSI_WPCR2_THSTRAIL4  0x10000000
+  #define DSI_WPCR2_THSTRAIL5  0x20000000
+  #define DSI_WPCR2_THSTRAIL6  0x40000000
+  #define DSI_WPCR2_THSTRAIL7  0x80000000
+#define TOFF_DSI_WPCR3     0x0424	/* (RW)DSI Wrapper PHY Configuration Register3 */
+  #define DSI_WPCR3_THSZERO    0x000000FF	/* t-HSZERO */
+  #define DSI_WPCR3_THSZERO0   0x00000001
+  #define DSI_WPCR3_THSZERO1   0x00000002
+  #define DSI_WPCR3_THSZERO2   0x00000004
+  #define DSI_WPCR3_THSZERO3   0x00000008
+  #define DSI_WPCR3_THSZERO4   0x00000010
+  #define DSI_WPCR3_THSZERO5   0x00000020
+  #define DSI_WPCR3_THSZERO6   0x00000040
+  #define DSI_WPCR3_THSZERO7   0x00000080
+  #define DSI_WPCR3_TLPXD      0x0000FF00	/* t-LPXD */
+  #define DSI_WPCR3_TLPXD0     0x00000100
+  #define DSI_WPCR3_TLPXD1     0x00000200
+  #define DSI_WPCR3_TLPXD2     0x00000400
+  #define DSI_WPCR3_TLPXD3     0x00000800
+  #define DSI_WPCR3_TLPXD4     0x00001000
+  #define DSI_WPCR3_TLPXD5     0x00002000
+  #define DSI_WPCR3_TLPXD6     0x00004000
+  #define DSI_WPCR3_TLPXD7     0x00008000
+  #define DSI_WPCR3_THSEXIT    0x00FF0000	/* t-HSEXIT */
+  #define DSI_WPCR3_THSEXIT0   0x00010000
+  #define DSI_WPCR3_THSEXIT1   0x00020000
+  #define DSI_WPCR3_THSEXIT2   0x00040000
+  #define DSI_WPCR3_THSEXIT3   0x00080000
+  #define DSI_WPCR3_THSEXIT4   0x00100000
+  #define DSI_WPCR3_THSEXIT5   0x00200000
+  #define DSI_WPCR3_THSEXIT6   0x00400000
+  #define DSI_WPCR3_THSEXIT7   0x00800000
+  #define DSI_WPCR3_TLPXC      0xFF000000	/* t-LPXC */
+  #define DSI_WPCR3_TLPXC0     0x01000000
+  #define DSI_WPCR3_TLPXC1     0x02000000
+  #define DSI_WPCR3_TLPXC2     0x04000000
+  #define DSI_WPCR3_TLPXC3     0x08000000
+  #define DSI_WPCR3_TLPXC4     0x10000000
+  #define DSI_WPCR3_TLPXC5     0x20000000
+  #define DSI_WPCR3_TLPXC6     0x40000000
+  #define DSI_WPCR3_TLPXC7     0x80000000
+#define TOFF_DSI_WPCR4     0x0428	/* (RW)DSI Wrapper PHY Configuration Register4 */
+  #define DSI_WPCR4_TCLKPOST   0x000000FF	/* t-CLKPOST */
+  #define DSI_WPCR4_TCLKPOST0  0x00000001
+  #define DSI_WPCR4_TCLKPOST1  0x00000002
+  #define DSI_WPCR4_TCLKPOST2  0x00000004
+  #define DSI_WPCR4_TCLKPOST3  0x00000008
+  #define DSI_WPCR4_TCLKPOST4  0x00000010
+  #define DSI_WPCR4_TCLKPOST5  0x00000020
+  #define DSI_WPCR4_TCLKPOST6  0x00000040
+  #define DSI_WPCR4_TCLKPOST7  0x00000080
+#define TOFF_DSI_WRPCR     0x0430	/* (RW) DSI Wrapper Regulator and PLL Control Register */
+  #define DSI_WRPCR_PLLEN      0x00000001	/* PLL Enable */
+  #define DSI_WRPCR_PLL_NDIV   0x000001FC	/* PLL Loop Division Factor */
+  #define DSI_WRPCR_PLL_NDIV0  0x00000004
+  #define DSI_WRPCR_PLL_NDIV1  0x00000008
+  #define DSI_WRPCR_PLL_NDIV2  0x00000010
+  #define DSI_WRPCR_PLL_NDIV3  0x00000020
+  #define DSI_WRPCR_PLL_NDIV4  0x00000040
+  #define DSI_WRPCR_PLL_NDIV5  0x00000080
+  #define DSI_WRPCR_PLL_NDIV6  0x00000100
+  #define DSI_WRPCR_PLL_IDF    0x00007800	/* PLL Input Division Factor */
+  #define DSI_WRPCR_PLL_IDF0   0x00000800
+  #define DSI_WRPCR_PLL_IDF1   0x00001000
+  #define DSI_WRPCR_PLL_IDF2   0x00002000
+  #define DSI_WRPCR_PLL_IDF3   0x00004000
+  #define DSI_WRPCR_PLL_ODF    0x00030000	/* PLL Output Division Factor */
+  #define DSI_WRPCR_PLL_ODF0   0x00010000
+  #define DSI_WRPCR_PLL_ODF1   0x00020000
+  #define DSI_WRPCR_REGEN      0x01000000	/* Regulator Enable */
+
+#endif
+
+#if defined(TOPPERS_STM32F769_DISCOVERY) || defined(TOPPERS_STM32F767_NUCLEO144)
+/*
+ *  DFSDM MODULE REGISTERS
+ */
+#define TADR_DFSDM1_BASE            (APB2PERIPH_BASE + 0x7400)
+#define TADR_DFSDM1_CHANNEL0_BASE   (TADR_DFSDM1_BASE + 0x0000)
+#define TADR_DFSDM1_CHANNEL1_BASE   (TADR_DFSDM1_BASE + 0x0020)
+#define TADR_DFSDM1_CHANNEL2_BASE   (TADR_DFSDM1_BASE + 0x0040)
+#define TADR_DFSDM1_CHANNEL3_BASE   (TADR_DFSDM1_BASE + 0x0060)
+#define TADR_DFSDM1_CHANNEL4_BASE   (TADR_DFSDM1_BASE + 0x0080)
+#define TADR_DFSDM1_CHANNEL5_BASE   (TADR_DFSDM1_BASE + 0x00A0)
+#define TADR_DFSDM1_CHANNEL6_BASE   (TADR_DFSDM1_BASE + 0x00C0)
+#define TADR_DFSDM1_CHANNEL7_BASE   (TADR_DFSDM1_BASE + 0x00E0)
+#define TOFF_DFSDM_CHCFGR1 0x0000	/* (RW) DFSDM channel configuration register1 */
+  #define DFSDM_CHCFGR1_SITP       0x00000003	/* SITP[1:0] Serial interface type for channel y */
+  #define DFSDM_CHCFGR1_SITP_0     0x00000001	/* Serial interface type for channel y, Bit 0 */
+  #define DFSDM_CHCFGR1_SITP_1     0x00000002	/* Serial interface type for channel y, Bit 1 */
+  #define DFSDM_CHCFGR1_SPICKSEL   0x0000000C	/* SPICKSEL[1:0] SPI clock select for channel y */
+  #define DFSDM_CHCFGR1_SPICKSEL_0 0x00000004	/* SPI clock select for channel y, Bit 0 */
+  #define DFSDM_CHCFGR1_SPICKSEL_1 0x00000008	/* SPI clock select for channel y, Bit 1 */
+  #define DFSDM_CHCFGR1_SCDEN      0x00000020	/* Short circuit detector enable on channel y */
+  #define DFSDM_CHCFGR1_CKABEN     0x00000040	/* Clock absence detector enable on channel y */
+  #define DFSDM_CHCFGR1_CHEN       0x00000080	/* Channel y enable */
+  #define DFSDM_CHCFGR1_CHINSEL    0x00000100	/* Serial inputs selection for channel y */
+  #define DFSDM_CHCFGR1_DATMPX_0   0x00001000	/* Input data multiplexer for channel y, Bit 0 */
+  #define DFSDM_CHCFGR1_DATMPX_1   0x00002000	/* Input data multiplexer for channel y, Bit 1 */
+  #define DFSDM_CHCFGR1_DATMPX     0x00003000	/* DATMPX[1:0] Input data multiplexer for channel y */
+  #define DFSDM_CHCFGR1_DATPACK    0x0000C000	/* DATPACK[1:0] Data packing mode */
+  #define DFSDM_CHCFGR1_DATPACK_0  0x00004000	/* Data packing mode, Bit 0 */
+  #define DFSDM_CHCFGR1_DATPACK_1  0x00008000	/* Data packing mode, Bit 1 */
+  #define DFSDM_CHCFGR1_CKOUTDIV   0x00FF0000	/* CKOUTDIV[7:0] output serial clock divider */
+  #define DFSDM_CHCFGR1_CKOUTSRC   0x40000000	/* Output serial clock source selection */
+  #define DFSDM_CHCFGR1_DFSDMEN    0x80000000	/* Global enable for DFSDM interface */
+#define TOFF_DFSDM_CHCFGR2 0x0004	/* (RW) DFSDM channel configuration register2 */
+  #define DFSDM_CHCFGR2_DTRBS      0x000000F8	/* DTRBS[4:0] Data right bit-shift for channel y */
+  #define DFSDM_CHCFGR2_OFFSET     0xFFFFFF00	/* OFFSET[23:0] 24-bit calibration offset for channel y */
+#define TOFF_DFSDM_CHAWSCDR 0x0008	/* (RW) DFSDM channel analog watchdog and short circuit detector register */
+  #define DFSDM_CHAWSCDR_SCDT      0x000000FF	/* SCDT[7:0] Short circuit detector threshold for channel y */
+  #define DFSDM_CHAWSCDR_BKSCD     0x0000F000	/* BKSCD[3:0] Break signal assignment for short circuit detector on channel y */
+  #define DFSDM_CHAWSCDR_AWFOSR    0x001F0000	/* AWFOSR[4:0] Analog watchdog filter oversampling ratio on channel y */
+  #define DFSDM_CHAWSCDR_AWFORD    0x00C00000	/* AWFORD[1:0] Analog watchdog Sinc filter order on channel y */
+  #define DFSDM_CHAWSCDR_AWFORD_0  0x00400000	/* Analog watchdog Sinc filter order on channel y, Bit 0 */
+  #define DFSDM_CHAWSCDR_AWFORD_1  0x00800000	/* Analog watchdog Sinc filter order on channel y, Bit 1 */
+#define TOFF_DFSDM_CHWDATAR 0x000C	/* (RW) DFSDM channel watchdog filter data register */
+  #define DFSDM_CHWDATR_WDATA      0x0000FFFF	/* WDATA[15:0] Input channel y watchdog data */
+#define TOFF_DFSDM_CHDATINR 0x0010	/* (RW) DFSDM channel data input register */
+  #define DFSDM_CHDATINR_INDAT0    0x0000FFFF	/* INDAT0[31:16] Input data for channel y or channel (y+1) */
+  #define DFSDM_CHDATINR_INDAT1    0xFFFF0000	/* INDAT0[15:0] Input data for channel y */
+
+#define TADR_DFSDM1_FILTER0_BASE    (TADR_DFSDM1_BASE + 0x0100)
+#define TADR_DFSDM1_FILTER1_BASE    (TADR_DFSDM1_BASE + 0x0180)
+#define TADR_DFSDM1_FILTER2_BASE    (TADR_DFSDM1_BASE + 0x0200)
+#define TADR_DFSDM1_FILTER3_BASE    (TADR_DFSDM1_BASE + 0x0280)
+#define TOFF_DFSDM_FLTCR1  0x0000	/* (RW) DFSDM control register1 */
+  #define DFSDM_FLTCR1_DFEN      0x00000001	/* DFSDM enable */
+  #define DFSDM_FLTCR1_JSWSTART  0x00000002	/* Start the conversion of the injected group of channels */
+  #define DFSDM_FLTCR1_JSYNC     0x00000008	/* Launch an injected conversion synchronously with DFSDMx JSWSTART trigger */
+  #define DFSDM_FLTCR1_JSCAN     0x00000010	/* Scanning conversion in continuous mode selection for injected conversions */
+  #define DFSDM_FLTCR1_JDMAEN    0x00000020	/* DMA channel enabled to read data for the injected channel group */
+  #define DFSDM_FLTCR1_JEXTSEL   0x00001F00	/* JEXTSEL[4:0]Trigger signal selection for launching injected conversions */
+  #define DFSDM_FLTCR1_JEXTSEL_0 0x00000100	/* Trigger signal selection for launching injected conversions, Bit 0 */
+  #define DFSDM_FLTCR1_JEXTSEL_1 0x00000200	/* Trigger signal selection for launching injected conversions, Bit 1 */
+  #define DFSDM_FLTCR1_JEXTSEL_2 0x00000400	/* Trigger signal selection for launching injected conversions, Bit 2 */
+  #define DFSDM_FLTCR1_JEXTSEL_3 0x00000800	/* Trigger signal selection for launching injected conversions, Bit 3 */
+  #define DFSDM_FLTCR1_JEXTSEL_4 0x00001000	/* Trigger signal selection for launching injected conversions, Bit 4 */
+  #define DFSDM_FLTCR1_JEXTEN    0x00006000	/* JEXTEN[1:0] Trigger enable and trigger edge selection for injected conversions */
+  #define DFSDM_FLTCR1_JEXTEN_1  0x00004000	/* Trigger enable and trigger edge selection for injected conversions, Bit 1 */
+  #define DFSDM_FLTCR1_JEXTEN_0  0x00002000	/* Trigger enable and trigger edge selection for injected conversions, Bit 0 */
+  #define DFSDM_FLTCR1_RSWSTART  0x00020000	/* Software start of a conversion on the regular channel */
+  #define DFSDM_FLTCR1_RCONT     0x00040000	/* Continuous mode selection for regular conversions */
+  #define DFSDM_FLTCR1_RSYNC     0x00080000	/* Launch regular conversion synchronously with DFSDMx */
+  #define DFSDM_FLTCR1_RDMAEN    0x00200000	/* DMA channel enabled to read data for the regular conversion */
+  #define DFSDM_FLTCR1_RCH       0x07000000	/* RCH[2:0] Regular channel selection */
+  #define DFSDM_FLTCR1_FAST      0x20000000	/* Fast conversion mode selection */
+  #define DFSDM_FLTCR1_AWFSEL    0x40000000	/* Analog watchdog fast mode select */
+#define TOFF_DFSDM_FLTCR2  0x0004	/* (RW) DFSDM control register2 */
+  #define DFSDM_FLTCR2_JEOCIE    0x00000001	/* Injected end of conversion interrupt enable */
+  #define DFSDM_FLTCR2_REOCIE    0x00000002	/* Regular end of conversion interrupt enable */
+  #define DFSDM_FLTCR2_JOVRIE    0x00000004	/* Injected data overrun interrupt enable */
+  #define DFSDM_FLTCR2_ROVRIE    0x00000008	/* Regular data overrun interrupt enable */
+  #define DFSDM_FLTCR2_AWDIE     0x00000010	/* Analog watchdog interrupt enable */
+  #define DFSDM_FLTCR2_SCDIE     0x00000020	/* Short circuit detector interrupt enable */
+  #define DFSDM_FLTCR2_CKABIE    0x00000040	/* Clock absence interrupt enable */
+  #define DFSDM_FLTCR2_EXCH      0x0000FF00	/* EXCH[7:0] Extreme detector channel selection */
+  #define DFSDM_FLTCR2_AWDCH     0x00FF0000	/* AWDCH[7:0] Analog watchdog channel selection */
+#define TOFF_DFSDM_FLTISR  0x0008	/* (RW) DFSDM interrupt and status register */
+  #define DFSDM_FLTISR_JEOCF     0x00000001	/* End of injected conversion flag */
+  #define DFSDM_FLTISR_REOCF     0x00000002	/* End of regular conversion flag */
+  #define DFSDM_FLTISR_JOVRF     0x00000004	/* Injected conversion overrun flag */
+  #define DFSDM_FLTISR_ROVRF     0x00000008	/* Regular conversion overrun flag */
+  #define DFSDM_FLTISR_AWDF      0x00000010	/* Analog watchdog */
+  #define DFSDM_FLTISR_JCIP      0x00002000	/* Injected conversion in progress status */
+  #define DFSDM_FLTISR_RCIP      0x00004000	/* Regular conversion in progress status */
+  #define DFSDM_FLTISR_CKABF     0x00FF0000	/* CKABF[7:0] Clock absence flag */
+  #define DFSDM_FLTISR_SCDF      0xFF000000	/* SCDF[7:0] Short circuit detector flag */
+#define TOFF_DFSDM_FLTICR  0x000C	/* (RW) DFSDM interrupt flag clear register */
+  #define DFSDM_FLTICR_CLRJOVRF  0x00000004	/* Clear the injected conversion overrun flag */
+  #define DFSDM_FLTICR_CLRROVRF  0x00000008	/* Clear the regular conversion overrun flag */
+  #define DFSDM_FLTICR_CLRCKABF  0x00FF0000	/* CLRCKABF[7:0] Clear the clock absence flag */
+  #define DFSDM_FLTICR_CLRSCSDF  0xFF000000	/* CLRSCSDF[7:0] Clear the short circuit detector flag */
+#define TOFF_DFSDM_FLTJCHGR 0x0010	/* (RW) DFSDM injected channel group selection register */
+  #define DFSDM_FLTJCHGR_JCHG    0x000000FF	/* JCHG[7:0] Injected channel group selection */
+#define TOFF_DFSDM_FLTFCR  0x0014	/* (RW) DFSDM filter control register */
+  #define DFSDM_FLTFCR_IOSR      0x000000FF	/* IOSR[7:0] Integrator oversampling ratio (averaging length) */
+  #define DFSDM_FLTFCR_FOSR      0x03FF0000	/* FOSR[9:0] Sinc filter oversampling ratio (decimation rate) */
+  #define DFSDM_FLTFCR_FORD      0xE0000000	/* FORD[2:0] Sinc filter order */
+  #define DFSDM_FLTFCR_FORD_2    0x80000000	/* Sinc filter order, Bit 2 */
+  #define DFSDM_FLTFCR_FORD_1    0x40000000	/* Sinc filter order, Bit 1 */
+  #define DFSDM_FLTFCR_FORD_0    0x20000000	/* Sinc filter order, Bit 0 */
+#define TOFF_DFSDM_FLTJDATAR 0x0018	/* (RW) DFSDM data register for injected group */
+  #define DFSDM_FLTJDATAR_JDATACH 0x00000007	/* JDATACH[2:0] Injected channel most recently converted */
+  #define DFSDM_FLTJDATAR_JDATA   0xFFFFFF00	/* JDATA[23:0] Injected group conversion data */
+#define TOFF_DFSDM_FLTRDATAR 0x001C	/* (RW) DFSDM data register for regular group */
+  #define DFSDM_FLTRDATAR_RDATACH 0x00000007	/* RDATACH[2:0] Regular channel most recently converted */
+  #define DFSDM_FLTRDATAR_RPEND   0x00000010	/* RPEND Regular channel pending data */
+  #define DFSDM_FLTRDATAR_RDATA   0xFFFFFF00	/* RDATA[23:0] Regular channel conversion data */
+#define TOFF_DFSDM_FLTAWHTR 0x0020	/* (RW) DFSDM analog watchdog high threshold register */
+  #define DFSDM_FLTAWHTR_BKAWH   0x0000000F	/* BKAWH[3:0] Break signal assignment to analog watchdog high threshold event */
+  #define DFSDM_FLTAWHTR_AWHT    0xFFFFFF00	/* AWHT[23:0] Analog watchdog high threshold */
+#define TOFF_DFSDM_FLTAWLTR 0x0024	/* (RW) DFSDM analog watchdog low threshold register */
+  #define DFSDM_FLTAWLTR_BKAWL   0x0000000F	/* BKAWL[3:0] Break signal assignment to analog watchdog low threshold event */
+  #define DFSDM_FLTAWLTR_AWLT    0xFFFFFF00	/* AWLT[23:0] Analog watchdog low threshold */
+#define TOFF_DFSDM_FLTAWSR  0x0028	/* (RW) DFSDM analog watchdog status register */
+  #define DFSDM_FLTAWSR_AWLTF    0x000000FF	/* AWLTF[7:0] Analog watchdog low threshold error on given channels */
+  #define DFSDM_FLTAWSR_AWHTF    0x0000FF00	/* AWHTF[15:8] Analog watchdog high threshold error on given channels */
+#define TOFF_DFSDM_FLTAWCFR 0x002C	/* (RW) DFSDM analog watchdog clear flag register */
+  #define DFSDM_FLTAWCFR_CLRAWLTF 0x000000FF	/* CLRAWLTF[7:0] Clear the Analog watchdog low threshold flag */
+  #define DFSDM_FLTAWCFR_CLRAWHTF 0x0000FF00	/* CLRAWHTF[15:8] Clear the Analog watchdog high threshold flag */
+#define TOFF_DFSDM_FLTEXMAX 0x0030	/* (RW) DFSDM extreme detector maximum register */
+  #define DFSDM_FLTEXMAX_EXMAXCH 0x00000007	/* EXMAXCH[2:0] Extreme detector maximum data channel */
+  #define DFSDM_FLTEXMAX_EXMAX   0xFFFFFF00	/* EXMAX[23:0] Extreme detector maximum value */
+#define TOFF_DFSDM_FLTEXMIN 0x0034	/* (RW) DFSDM extreme detector minimum register */
+  #define DFSDM_FLTEXMIN_EXMINCH 0x00000007	/* EXMINCH[2:0] Extreme detector minimum data channel */
+  #define DFSDM_FLTEXMIN_EXMIN   0xFFFFFF00	/* EXMIN[23:0] Extreme detector minimum value */
+#define TOFF_DFSDM_FLTCNVTIMR 0x0038/* (RW) DFSDM conversion timer */
+  #define DFSDM_FLTCNVTIMR_CNVCNT 0xFFFFFFF0	/* CNVCNT[27:0]: 28-bit timer counting conversion time */
+
+#endif
+
+#endif  /* _STM32F7XX_H_ */
+
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/arch/gcc/MANIFEST
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/arch/gcc/MANIFEST	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/arch/gcc/MANIFEST	(revision 457)
@@ -0,0 +1,4 @@
+PACKAGE asp
+
+MANIFEST
+tool_stddef.h
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/arch/gcc/tool_stddef.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/arch/gcc/tool_stddef.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/arch/gcc/tool_stddef.h	(revision 457)
@@ -0,0 +1,206 @@
+/*
+ *  TOPPERS Software
+ *      Toyohashi Open Platform for Embedded Real-Time Systems
+ * 
+ *  Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
+ *                              Toyohashi Univ. of Technology, JAPAN
+ *  Copyright (C) 2004-2011 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *		t_stddef.hの開発環境依存部（GCC用）
+ */
+
+#ifndef TOPPERS_TOOL_STDDEF_H
+#define TOPPERS_TOOL_STDDEF_H
+
+/*
+ *  コンパイラの拡張機能のためのマクロ定義
+ */
+#ifndef __cplusplus					/* C++にはinline がある */
+#if !defined(__STDC_VERSION__) || __STDC_VERSION__ < 199901L
+									/* C99にはinline がある */
+#define inline	__inline__			/* インライン関数 */
+#endif /* !defined(__STDC_VERSION__) || __STDC_VERSION__ < 199901L */
+#endif /* __cplusplus */
+
+#define Inline	static __inline__	/* インライン関数 */
+
+#ifndef __cplusplus					/* C++にはasmがある */
+#define asm		__asm__				/* インラインアセンブラ */
+#endif /* __cplusplus */
+
+#define Asm		__asm__ volatile	/* インラインアセンブラ（最適化抑止）*/
+
+#define NoReturn	__attribute__((__noreturn__))
+									/* リターンしない関数 */
+
+/*
+ *  開発環境の標準インクルードファイルの利用
+ *
+ *  NULLの定義をstddef.hから，INT_MAX，INT_MIN，UINT_MAX，LONG_MAX，
+ *  LONG_MIN，ULONG_MAX，CHAR_BITの定義をlimits.hから取り込む．
+ *
+ *  C++/EC++では，標準仕様上はこれらのインクルードファイルが用意されて
+ *  いるとは限らないので注意が必要である（ほとんどの開発環境で用意され
+ *  ている）．
+ */
+#ifndef TOPPERS_MACRO_ONLY
+#include <stddef.h>
+#include <limits.h>
+#endif /* TOPPERS_MACRO_ONLY */
+
+/*
+ *  stdint.hの代用となる定義
+ *
+ *  開発環境にstdint.hが用意されておらず，各整数型のサイズがあるパター
+ *  ンに当てはまる場合に，stdint.hの代用となる定義を与える．
+ *
+ *  TOPPERS_STDINT_TYPE1: char/short/int/long longのビット長がそれぞれ
+ *                        8/16/32/64ビットで，ポインタのビット長がlong
+ *                        のビット長と一致する場合
+ */
+#ifdef TOPPERS_STDINT_TYPE1
+
+/*
+ *  コンパイラ依存のデータ型の定義
+ */
+#ifndef TOPPERS_MACRO_ONLY
+
+typedef signed char			int8_t;		/* 符号付き8ビット整数 */
+typedef unsigned char		uint8_t;	/* 符号無し8ビット整数 */
+
+typedef signed short		int16_t;	/* 符号付き16ビット整数 */
+typedef unsigned short		uint16_t;	/* 符号無し16ビット整数 */
+
+typedef signed int			int32_t;	/* 符号付き32ビット整数 */
+typedef unsigned int		uint32_t;	/* 符号無し32ビット整数 */
+
+typedef signed long long	int64_t;	/* 符号付き64ビット整数 */
+typedef unsigned long long	uint64_t;	/* 符号無し64ビット整数 */
+
+typedef int8_t				int_least8_t;	/* 8ビット以上の符号付き整数 */
+typedef uint8_t				uint_least8_t;	/* 8ビット以上の符号無し整数 */
+
+typedef long				intptr_t;	/* ポインタを格納できる符号付き整数 */
+typedef unsigned long		uintptr_t;	/* ポインタを格納できる符号無し整数 */
+
+#endif /* TOPPERS_MACRO_ONLY */
+
+/*
+ *  コンパイラ依存のデータ型の整数定数を作るマクロ
+ */
+#ifndef INT8_C
+#define INT8_C(val)			(val)
+#endif /* INT8_C */
+
+#ifndef UINT8_C
+#define UINT8_C(val)		(val ## U)
+#endif /* UINT8_C */
+
+#ifndef INT16_C
+#define INT16_C(val)		(val)
+#endif /* INT16_C */
+
+#ifndef UINT16_C
+#define UINT16_C(val)		(val ## U)
+#endif /* UINT16_C */
+
+#ifndef INT32_C
+#define INT32_C(val)		(val)
+#endif /* INT32_C */
+
+#ifndef UINT32_C
+#define UINT32_C(val)		(val ## U)
+#endif /* UINT32_C */
+
+#ifndef INT64_C
+#define INT64_C(val)		(val ## LL)
+#endif /* INT64_C */
+
+#ifndef UINT64_C
+#define UINT64_C(val)		(val ## ULL)
+#endif /* UINT64_C */
+
+/*
+ *  コンパイラ依存のデータ型に格納できる最大値と最小値の定義
+ */
+#define INT8_MAX			SCHAR_MAX
+#define INT8_MIN			SCHAR_MIN
+#define UINT8_MAX			UCHAR_MAX
+
+#define INT16_MAX			SHRT_MAX
+#define INT16_MIN			SHRT_MIN
+#define UINT16_MAX			USHRT_MAX
+
+#define INT32_MAX			INT_MAX
+#define INT32_MIN			INT_MIN
+#define UINT32_MAX			UINT_MAX
+
+#define INT64_MAX			LLONG_MAX
+#define INT64_MIN			LLONG_MIN
+#define UINT64_MAX			ULLONG_MAX
+
+#define INT_LEAST8_MAX		INT8_MAX
+#define INT_LEAST8_MIN		INT8_MIN
+#define UINT_LEAST8_MAX		INT8_MAX
+
+#else
+#ifndef TOPPERS_MACRO_ONLY
+#include <stdint.h>
+#endif /* TOPPERS_MACRO_ONLY */
+#endif /* TOPPERS_STDINT_TYPE1 */
+
+/*
+ *  浮動小数点型に関する定義
+ *
+ *  TOPPERS_STDFLOAT_TYPE1: floatがIEEE754準拠の単精度浮動小数点数，
+ *							doubleが倍精度浮動小数点数の場合
+ */
+#ifdef TOPPERS_STDFLOAT_TYPE1
+#ifndef TOPPERS_MACRO_ONLY
+
+typedef float		float32_t;			/* IEEE754準拠の単精度浮動小数点数 */
+typedef double		double64_t;			/* IEEE754準拠の倍精度浮動小数点数 */
+
+#endif /* TOPPERS_MACRO_ONLY */
+
+#define FLOAT32_MIN		1.17549435e-38F
+#define FLOAT32_MAX		3.40282347e+38F
+#define DOUBLE64_MIN	2.2250738585072014e-308
+#define DOUBLE64_MAX	1.7976931348623157e+308
+
+#endif /* TOPPERS_STDFLOAT_TYPE1 */
+#endif /* TOPPERS_TOOL_STDDEF_H */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/arch/logtrace/MANIFEST
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/arch/logtrace/MANIFEST	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/arch/logtrace/MANIFEST	(revision 457)
@@ -0,0 +1,6 @@
+PACKAGE asp
+
+MANIFEST
+trace_config.c
+trace_config.h
+trace_dump.c
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/arch/logtrace/trace_config.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/arch/logtrace/trace_config.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/arch/logtrace/trace_config.c	(revision 457)
@@ -0,0 +1,249 @@
+/*
+ *  TOPPERS Software
+ *      Toyohashi Open Platform for Embedded Real-Time Systems
+ * 
+ *  Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
+ *                              Toyohashi Univ. of Technology, JAPAN
+ *  Copyright (C) 2005-2011 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  $Id$
+ */
+
+/*
+ *		トレースログ機能
+ */
+
+#include "kernel_impl.h"
+#include "task.h"
+#include "time_event.h"
+#include <sil.h>
+
+/*
+ *  トレースログバッファとそれにアクセスするためのポインタ
+ */
+SYSLOG	trace_buffer[TCNT_TRACE_BUFFER];	/* トレースログバッファ */
+uint_t	trace_count;				/* トレースログバッファ中のログの数 */
+uint_t	trace_head;					/* 先頭のトレースログの格納位置 */
+uint_t	trace_tail;					/* 次のトレースログの格納位置 */
+MODE	trace_mode;					/* トレースモード */
+
+/*
+ *  トレースログ機能の初期化
+ */
+void
+trace_initialize(intptr_t exinf)
+{
+	MODE	mode = ((MODE) exinf);
+
+	trace_count = 0U;
+	trace_head = 0U;
+	trace_tail = 0U;
+	trace_mode = mode;
+}     
+
+/*
+ *  トレースログの開始
+ */
+ER
+trace_sta_log(MODE mode)
+{
+	if ((mode & TRACE_CLEAR) != 0U) {
+		trace_count = 0U;
+		trace_head = 0U;
+		trace_tail = 0U;
+	}
+	trace_mode = mode;
+	return(E_OK);
+}     
+
+/* 
+ *  トレースログの書込み
+ */
+ER
+trace_wri_log(TRACE *p_trace)
+{
+	SIL_PRE_LOC;
+
+	if (trace_mode != TRACE_STOP) {
+		SIL_LOC_INT();
+
+		/*
+		 *  トレース時刻の設定
+		 *
+		 *  LOG_WRI_LOG_ENTERから呼ばれた場合にp_trace->logtimを書き換
+		 *  えてしまうのは気持ちが悪いが，wri_logの方で上書きするため問
+		 *  題はない．
+		 */
+		p_trace->logtim = TRACE_GET_TIM();
+
+		/*
+		 *  トレースバッファに記録
+		 */
+		trace_buffer[trace_tail] = *p_trace;
+		trace_tail++;
+		if (trace_tail >= TCNT_TRACE_BUFFER) {
+			trace_tail = 0U;
+		}
+		if (trace_count < TCNT_TRACE_BUFFER) {
+			trace_count++;
+			if (trace_count >= TCNT_TRACE_BUFFER
+						&& (trace_mode & TRACE_AUTOSTOP) != 0U) {
+				trace_mode = TRACE_STOP;
+			}
+		}
+		else {
+			trace_head = trace_tail;
+		}
+
+		SIL_UNL_INT();
+	}
+	return(E_OK);
+}
+
+/*
+ *  トレースログの読出し
+ */
+ER
+trace_rea_log(TRACE *p_trace)
+{
+	ER_UINT	ercd;
+	SIL_PRE_LOC;
+
+	SIL_LOC_INT();
+
+	/*
+	 *  トレースログバッファからの取出し
+	 */
+	if (trace_count > 0U) {
+		*p_trace = trace_buffer[trace_head];
+		trace_count--;
+		trace_head++;
+		if (trace_head >= TCNT_TRACE_BUFFER) {
+			trace_head = 0U;
+		}
+		ercd = E_OK;
+	}
+	else {
+		ercd = E_OBJ;
+	}
+
+	SIL_UNL_INT();
+	return(ercd);
+}
+
+/*
+ *  トレースログを出力するためのライブラリ関数
+ */
+
+void
+trace_write_0(uint_t type)
+{
+	TRACE	trace;
+
+	trace.logtype = type;
+	(void) trace_wri_log(&trace);
+}
+
+void
+trace_write_1(uint_t type, intptr_t arg1)
+{
+	TRACE	trace;
+
+	trace.logtype = type;
+	trace.loginfo[0] = arg1;
+	(void) trace_wri_log(&trace);
+}
+
+void
+trace_write_2(uint_t type, intptr_t arg1, intptr_t arg2)
+{
+	TRACE	trace;
+
+	trace.logtype = type;
+	trace.loginfo[0] = arg1;
+	trace.loginfo[1] = arg2;
+	(void) trace_wri_log(&trace);
+}
+
+void
+trace_write_3(uint_t type, intptr_t arg1, intptr_t arg2, intptr_t arg3)
+{
+	TRACE	trace;
+
+	trace.logtype = type;
+	trace.loginfo[0] = arg1;
+	trace.loginfo[1] = arg2;
+	trace.loginfo[2] = arg3;
+	(void) trace_wri_log(&trace);
+}
+
+/*
+ *  アセンブリ言語で記述されるコードからトレースログを出力するための関
+ *  数
+ */
+
+void
+log_dsp_enter(TCB *p_tcb)
+{
+	trace_1(LOG_TYPE_DSP|LOG_ENTER, p_tcb);
+}
+
+void
+log_dsp_leave(TCB *p_tcb)
+{
+	trace_1(LOG_TYPE_DSP|LOG_LEAVE, p_tcb);
+}
+
+void
+log_inh_enter(INHNO inhno)
+{
+	trace_1(LOG_TYPE_INH|LOG_ENTER, inhno);
+}
+
+void
+log_inh_leave(INHNO inhno)
+{
+	trace_1(LOG_TYPE_INH|LOG_LEAVE, inhno);
+}
+
+void
+log_exc_enter(EXCNO excno)
+{
+	trace_1(LOG_TYPE_EXC|LOG_ENTER, excno);
+}
+
+void
+log_exc_leave(EXCNO excno)
+{
+	trace_1(LOG_TYPE_EXC|LOG_LEAVE, excno);
+}
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/arch/logtrace/trace_config.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/arch/logtrace/trace_config.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/arch/logtrace/trace_config.h	(revision 457)
@@ -0,0 +1,181 @@
+/*
+ *  TOPPERS Software
+ *      Toyohashi Open Platform for Embedded Real-Time Systems
+ * 
+ *  Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
+ *                              Toyohashi Univ. of Technology, JAPAN
+ *  Copyright (C) 2004-2012 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  $Id$
+ */
+
+/*
+ *		トレースログに関する設定
+ *
+ *  このインクルードファイルは，target_config.hおよびtarget_syssvc.hの
+ *  みからインクルードされる．また，トレースログ機能の初期化や記録の開
+ *  始／停止，トレースログのダンプを行うプログラムからインクルードする
+ *  ことを想定している．
+ */
+
+#ifndef TOPPERS_TRACE_CONFIG_H
+#define TOPPERS_TRACE_CONFIG_H
+
+/*
+ *  トレースログバッファのサイズ
+ */
+#ifndef TCNT_TRACE_BUFFER
+#define TCNT_TRACE_BUFFER	1024
+#endif /* TCNT_TRACE_BUFFER */
+
+/*
+ *  トレース時刻の取得方法
+ */
+#ifndef TRACE_GET_TIM
+#define TRACE_GET_TIM()		(current_time)
+#endif /* TRACE_GET_TIM */
+
+#ifndef TOPPERS_MACRO_ONLY
+
+/*
+ *  トレースログのデータ構造
+ *
+ *  システムログ機能のログ情報のデータ構造と同じものを用いる．
+ */
+#include <t_syslog.h>
+typedef	SYSLOG	TRACE;
+
+/*
+ *  トレースログバッファとそれにアクセスするためのポインタ
+ */
+extern TRACE	trace_buffer[];		/* トレースログバッファ */
+extern uint_t	trace_count;		/* トレースログバッファ中のログの数 */
+extern uint_t	trace_head;			/* 先頭のトレースログの格納位置 */
+extern uint_t	trace_tail;			/* 次のトレースログの格納位置 */
+extern uint_t	trace_lost;			/* 失われたトレースの数 */
+
+#endif /* TOPPERS_MACRO_ONLY */
+
+/*
+ *  トレースモードの定義
+ */
+#define TRACE_STOP			UINT_C(0x00)	/* トレース停止 */
+#define TRACE_RINGBUF		UINT_C(0x01)	/* リングバッファモード */
+#define TRACE_AUTOSTOP		UINT_C(0x02)	/* 自動停止モード */
+#define TRACE_CLEAR			UINT_C(0x04)	/* トレースログのクリア */
+
+#ifndef TOPPERS_MACRO_ONLY
+
+/*
+ *  トレースログ機能の初期化
+ *
+ *  トレースログ機能を初期化する．初期化ルーチンとして登録することを想
+ *  定している．引数により次の動作を行う．
+ *
+ *  TRACE_STOP：初期化のみでトレースは開始しない．
+ *  TRACE_RINGBUF：リングバッファモードでトレースを開始．
+ *  TRACE_AUTOSTOP：自動停止モードでトレースを開始．
+ */
+extern void	trace_initialize(intptr_t exinf);
+
+/*
+ *  トレースログの開始
+ *
+ *  トレースログの記録を開始／停止する．引数により次の動作を行う．
+ *
+ *  TRACE_STOP：トレースを停止．
+ *  TRACE_RINGBUF：リングバッファモードでトレースを開始．
+ *  TRACE_AUTOSTOP：自動停止モードでトレースを開始．
+ *  TRACE_CLEAR：トレースログをクリア．
+ */
+extern ER	trace_sta_log(MODE mode);
+
+/*
+ *  トレースログの書込み
+ */
+extern ER	trace_wri_log(TRACE *p_trace);
+
+/*
+ *  トレースログの読出し
+ */
+extern ER	trace_rea_log(TRACE *p_trace);
+
+/* 
+ *  トレースログのダンプ（trace_dump.c）
+ *
+ *  トレースログをダンプする．終了処理ルーチンとして登録することも想定
+ *  している．引数として，ダンプ先となる文字出力関数へのポインタを渡す．
+ *  ターゲット依存の低レベル文字出力を利用する場合には，target_putcを渡
+ *  す．
+ */
+extern void	trace_dump(intptr_t exinf);
+
+/*
+ *  トレースログを出力するためのライブラリ関数
+ */
+extern void	trace_write_0(uint_t type);
+extern void	trace_write_1(uint_t type, intptr_t arg1);
+extern void	trace_write_2(uint_t type, intptr_t arg1, intptr_t arg2);
+extern void	trace_write_3(uint_t type, intptr_t arg1, intptr_t arg2,
+														intptr_t arg3);
+
+/*
+ *  トレースログを出力するためのマクロ
+ */
+
+#define trace_0(type) \
+				trace_write_0(type)
+
+#define trace_1(type, arg1) \
+				trace_write_1(type, (intptr_t)(arg1))
+
+#define trace_2(type, arg1, arg2) \
+				trace_write_2(type, (intptr_t)(arg1), (intptr_t)(arg2))
+
+#define trace_3(type, arg1, arg2, arg3) \
+				trace_write_3(type, (intptr_t)(arg1), (intptr_t)(arg2), \
+						(intptr_t)(arg3))
+
+#endif /* TOPPERS_MACRO_ONLY */
+
+/*
+ *  トレースログ方法の設定
+ */
+#define LOG_TSKSTAT(p_tcb)		trace_2(LOG_TYPE_TSKSTAT, p_tcb, p_tcb->tstat)
+
+#define LOG_DSP_LEAVE(p_tcb)	trace_1(LOG_TYPE_DSP|LOG_LEAVE, p_tcb)
+
+#define LOG_SYSLOG_WRI_LOG_ENTER(prio, p_syslog) \
+								trace_wri_log((TRACE *) p_syslog)
+
+#endif /* TOPPERS_TRACE_CONFIG_H */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/arch/logtrace/trace_dump.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/arch/logtrace/trace_dump.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/arch/logtrace/trace_dump.c	(revision 457)
@@ -0,0 +1,154 @@
+/*
+ *  TOPPERS Software
+ *      Toyohashi Open Platform for Embedded Real-Time Systems
+ * 
+ *  Copyright (C) 2007-2011 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  $Id$
+ */
+
+/*
+ *		トレースログのダンプ
+ */
+
+#include "kernel_impl.h"
+#include "task.h"
+#include <log_output.h>
+
+/* 
+ *  カーネル情報の取出し
+ */
+static intptr_t
+get_tskid(intptr_t info)
+{
+	TCB		*p_tcb;
+	ID		tskid;
+
+	p_tcb = (TCB *) info;
+	if (p_tcb == NULL) {
+		tskid = 0;
+	}
+	else {
+		tskid = TSKID(p_tcb);
+	}
+	return((intptr_t) tskid);
+}
+
+static intptr_t
+get_tskstat(intptr_t info)
+{
+	uint_t		tstat;
+	const char	*tstatstr;
+
+	tstat = (uint_t) info;
+	switch (tstat & (TS_RUNNABLE|TS_WAITING|TS_SUSPENDED)) {
+	case TS_DORMANT:
+		tstatstr = "DORMANT";
+		break;
+	case TS_RUNNABLE:
+		tstatstr = "RUNNABLE";
+		break;
+	case TS_WAITING:
+		tstatstr = "WAITING";
+		break;
+	case TS_SUSPENDED:
+		tstatstr = "SUSPENDED";
+		break;
+	case TS_WAITING|TS_SUSPENDED:
+		tstatstr = "WAITING-SUSPENDED";
+		break;
+	default:
+		tstatstr = "unknown state";
+		break;
+	}
+	return((intptr_t) tstatstr);
+}
+
+/* 
+ *  トレースログの表示
+ */
+static void
+trace_print(TRACE *p_trace, void (*putc)(char))
+{
+	intptr_t	traceinfo[TMAX_LOGINFO + 1];
+	const char	*tracemsg;
+	int_t		i;
+
+	traceinfo[0] = (intptr_t)(p_trace->logtim);
+	syslog_printf("[%d] ", traceinfo, putc);
+
+	switch (p_trace->logtype) {
+	case LOG_TYPE_TSKSTAT:
+		traceinfo[0] = get_tskid(p_trace->loginfo[0]);
+		traceinfo[1] = get_tskstat(p_trace->loginfo[1]);
+		tracemsg = "task %d becomes %s.";
+		break;
+	case LOG_TYPE_DSP|LOG_LEAVE:
+		traceinfo[0] = get_tskid(p_trace->loginfo[0]);
+		tracemsg = "dispatch to task %d.";
+		break;
+	case LOG_TYPE_COMMENT:
+		for (i = 1; i < TMAX_LOGINFO; i++) {
+			traceinfo[i-1] = p_trace->loginfo[i];
+		}
+		tracemsg = (const char *)(p_trace->loginfo[0]);
+		break;
+	case LOG_TYPE_ASSERT:
+		traceinfo[0] = p_trace->loginfo[0];
+		traceinfo[1] = p_trace->loginfo[1];
+		traceinfo[2] = p_trace->loginfo[2];
+		tracemsg = "%s:%u: Assertion `%s' failed.";
+		break;
+	default:
+		traceinfo[0] = p_trace->logtype;
+		tracemsg = "unknown trace log type: %d.";
+		break;
+	}
+	syslog_printf(tracemsg, traceinfo, putc);
+	(*putc)('\n');
+}
+
+/* 
+ *  トレースログのダンプ
+ */
+void
+trace_dump(intptr_t exinf)
+{
+	TRACE	trace;
+	void	(*putc)(char);
+
+	putc = (void (*)(char)) exinf;
+	while (trace_rea_log(&trace) >= 0) {
+		trace_print(&trace, putc);
+	}
+}
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/cfg/MANIFEST
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/cfg/MANIFEST	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/cfg/MANIFEST	(revision 457)
@@ -0,0 +1,8 @@
+MANIFEST
+cfg.rb
+pass1.rb
+pass2.rb
+GenFile.rb
+SRecord.rb
+
+doc/cfg_user.txt
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/configure
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/configure	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/configure	(revision 457)
@@ -0,0 +1,295 @@
+#! /usr/bin/perl
+#
+#  TOPPERS Software
+#      Toyohashi Open Platform for Embedded Real-Time Systems
+# 
+#  Copyright (C) 2001-2003 by Embedded and Real-Time Systems Laboratory
+#                              Toyohashi Univ. of Technology, JAPAN
+#  Copyright (C) 2006-2012 by Embedded and Real-Time Systems Laboratory
+#              Graduate School of Information Science, Nagoya Univ., JAPAN
+# 
+#  ä¸è¨èä½æ¨©è
+ã¯ï¼ä»¥ä¸ã®(1)ï½(4)ã®æ¡ä»¶ãæºããå ´åã«éãï¼æ¬ã½ããã¦ã§
+#  ã¢ï¼æ¬ã½ããã¦ã§ã¢ãæ¹å¤ãããã®ãå«ãï¼ä»¥ä¸åãï¼ãä½¿ç¨ã»è¤è£½ã»æ¹
+#  å¤ã»åé
+å¸ï¼ä»¥ä¸ï¼å©ç¨ã¨å¼ã¶ï¼ãããã¨ãç¡åã§è¨±è«¾ããï¼
+#  (1) æ¬ã½ããã¦ã§ã¢ãã½ã¼ã¹ã³ã¼ãã®å½¢ã§å©ç¨ããå ´åã«ã¯ï¼ä¸è¨ã®èä½
+#      æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨ã®ç¡ä¿è¨¼è¦å®ãï¼ãã®ã¾ã¾ã®å½¢ã§ã½ã¼
+#      ã¹ã³ã¼ãä¸­ã«å«ã¾ãã¦ãããã¨ï¼
+#  (2) æ¬ã½ããã¦ã§ã¢ãï¼ã©ã¤ãã©ãªå½¢å¼ãªã©ï¼ä»ã®ã½ããã¦ã§ã¢éçºã«ä½¿
+#      ç¨ã§ããå½¢ã§åé
+å¸ããå ´åã«ã¯ï¼åé
+å¸ã«ä¼´ããã­ã¥ã¡ã³ãï¼å©ç¨
+#      è
+ããã¥ã¢ã«ãªã©ï¼ã«ï¼ä¸è¨ã®èä½æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨
+#      ã®ç¡ä¿è¨¼è¦å®ãæ²è¼ãããã¨ï¼
+#  (3) æ¬ã½ããã¦ã§ã¢ãï¼æ©å¨ã«çµã¿è¾¼ããªã©ï¼ä»ã®ã½ããã¦ã§ã¢éçºã«ä½¿
+#      ç¨ã§ããªãå½¢ã§åé
+å¸ããå ´åã«ã¯ï¼æ¬¡ã®ããããã®æ¡ä»¶ãæºããã
+#      ã¨ï¼
+#    (a) åé
+å¸ã«ä¼´ããã­ã¥ã¡ã³ãï¼å©ç¨è
+ããã¥ã¢ã«ãªã©ï¼ã«ï¼ä¸è¨ã®è
+#        ä½æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨ã®ç¡ä¿è¨¼è¦å®ãæ²è¼ãããã¨ï¼
+#    (b) åé
+å¸ã®å½¢æ
+ãï¼å¥ã«å®ããæ¹æ³ã«ãã£ã¦ï¼TOPPERSãã­ã¸ã§ã¯ãã«
+#        å ±åãããã¨ï¼
+#  (4) æ¬ã½ããã¦ã§ã¢ã®å©ç¨ã«ããç´æ¥çã¾ãã¯éæ¥çã«çãããããªãæ
+#      å®³ãããï¼ä¸è¨èä½æ¨©è
+ããã³TOPPERSãã­ã¸ã§ã¯ããå
+è²¬ãããã¨ï¼
+#      ã¾ãï¼æ¬ã½ããã¦ã§ã¢ã®ã¦ã¼ã¶ã¾ãã¯ã¨ã³ãã¦ã¼ã¶ããã®ãããªãç
+#      ç±ã«åºã¥ãè«æ±ãããï¼ä¸è¨èä½æ¨©è
+ããã³TOPPERSãã­ã¸ã§ã¯ãã
+#      å
+è²¬ãããã¨ï¼
+# 
+#  æ¬ã½ããã¦ã§ã¢ã¯ï¼ç¡ä¿è¨¼ã§æä¾ããã¦ãããã®ã§ããï¼ä¸è¨èä½æ¨©è
+ã
+#  ãã³TOPPERSãã­ã¸ã§ã¯ãã¯ï¼æ¬ã½ããã¦ã§ã¢ã«é¢ãã¦ï¼ç¹å®ã®ä½¿ç¨ç®ç
+#  ã«å¯¾ããé©åæ§ãå«ãã¦ï¼ãããªãä¿è¨¼ãè¡ããªãï¼ã¾ãï¼æ¬ã½ããã¦ã§
+#  ã¢ã®å©ç¨ã«ããç´æ¥çã¾ãã¯éæ¥çã«çãããããªãæå®³ã«é¢ãã¦ãï¼ã
+#  ã®è²¬ä»»ãè² ããªãï¼
+# 
+#  @(#) $Id$
+# 
+
+use Getopt::Std;
+
+#  ãªãã·ã§ã³ã®å®ç¾©
+#
+#  -T <target>			ã¿ã¼ã²ããåï¼å¿
+é ï¼
+#  -A <applname>		ã¢ããªã±ã¼ã·ã§ã³ãã­ã°ã©ã åï¼ããã©ã«ãã¯sample1ï¼
+#  -a <appldir>			ã¢ããªã±ã¼ã·ã§ã³ã®ãã£ã¬ã¯ããªå
+#  -U <applobjs>		ä»ã®ã¢ããªã±ã¼ã·ã§ã³ãã­ã°ã©ã ãã¡ã¤ã«
+#						ï¼.oãã¡ã¤ã«åã§æå®ï¼è¤æ°æå®å¯ï¼
+#  -S <syssvcobjs>		ã·ã¹ãã ãµã¼ãã¹ã®ãã­ã°ã©ã ãã¡ã¤ã«
+#						ï¼.oãã¡ã¤ã«åã§æå®ï¼è¤æ°æå®å¯ï¼
+#  -L <kernel_lib>		ã«ã¼ãã«ã©ã¤ãã©ãªï¼libkernel.aï¼ã®ãã£ã¬ã¯ããªå
+#						ï¼çç¥ããå ´åï¼ã«ã¼ãã«ã©ã¤ãã©ãªãmakeããï¼
+#  -f					ã«ã¼ãã«ãé¢æ°åä½ã§ã³ã³ãã¤ã«ãããã©ããã®æå®
+#  -D <srcdir>			ã«ã¼ãã«ç­ã®ã½ã¼ã¹ã®ç½®ããã¦ãããã£ã¬ã¯ããª
+#  -l <srclang>			ãã­ã°ã©ãã³ã°è¨èªï¼ç¾æç¹ã§ã¯cã¨c++ã®ã¿ãµãã¼ãï¼
+#  -t <templatedir>		ãã³ãã¬ã¼ããã£ã¬ã¯ããªã®æå®ï¼ããã©ã«ãã¯sampleï¼
+#  -m <makefile>		ãã³ãã¬ã¼ãMakefileåã®æå®ï¼ããã©ã«ãã¯Makefileï¼
+#  -d <dbgenv>			å®è¡ç°å¢ã®åç§°
+#  -r					ãã¬ã¼ã¹ã­ã°è¨é²ã®ãµã³ãã«ã³ã¼ããä½¿ç¨ãããã©ãã
+#						ã®æå®
+#  -p <perl>			perlã®ãã¹åï¼æç¤ºçã«æå®ããå ´åï¼
+#  -g <cfg>				ã³ã³ãã£ã®ã¥ã¬ã¼ã¿ï¼cfgï¼ã®ãã¹å
+#  -P <num>				ãã­ã»ããµæ°ï¼ãã«ããã­ã»ããµå¯¾å¿ã«ã¼ãã«ã®å ´åï¼
+#  -o <options>			å
+±éã³ã³ãã¤ã«ãªãã·ã§ã³ï¼COPTSã«è¿½å ï¼
+#  -O <options>			å
+±éã·ã³ãã«å®ç¾©ãªãã·ã§ã³ï¼CDEFSã«è¿½å ï¼
+#  -k <options>			å
+±éãªã³ã«ãªãã·ã§ã³ï¼LDFLAGSç­ã«è¿½å ï¼
+
+#  ä½¿ç¨ä¾(1)
+#
+#  % ../configure -T dve68k_gcc -D GDB_STUB -A perf1 -a ../test -U histogram.o
+#
+#  ä½¿ç¨ä¾(2)
+#
+#  % ../configure -T macosx_gcc -L .
+#	ã¢ããªã±ã¼ã·ã§ã³ãã­ã°ã©ã ã¯ sample1 ã«ãªãï¼
+
+#
+#  ãªãã·ã§ã³ã®å¦ç
+#
+getopt("TAaUSLDltmdpgPoOk");
+
+#
+#  å¤æ°ã®åæå
+#
+
+$target = $opt_T;
+$applname = $opt_A ? $opt_A : "sample1";
+$appldir = $opt_a ? $opt_a : "";
+$applobjs = $opt_U ? $opt_U : "";
+$syssvcobjs = $opt_S ? $opt_S : "";
+$kernel_lib = $opt_L ? $opt_L : "";
+$kernel_funcobjs = $opt_f ? "true" : "";
+$srclang = $opt_l ? $opt_l : "c";
+$makefile = $opt_m ? $opt_m : "Makefile";
+$dbgenv = $opt_d ? "TOPPERS_".$opt_d : "";
+$enable_trace = $opt_r ? "true" : "";
+$prc_num = $opt_P ? $opt_P : "";
+$copts = $opt_o ? $opt_o : "";
+$cdefs = $opt_O ? $opt_O : "";
+$ldflags = $opt_k ? $opt_k : "";
+
+#
+#  ãªãã¸ã§ã¯ããã¡ã¤ã«åã®æ¡å¼µå­ãè¿ã
+#
+sub get_objext {
+	if ($^O eq 'cygwin') {
+		return("exe");
+	}
+	elsif ($^O eq 'msys') {
+		return("exe");
+	}
+	else {
+		return("");
+	}
+}
+
+#
+#  ãã­ã°ã©ã ã®å ´æãæ¤ç´¢ãã
+#
+sub get_path {
+	my($progname, @pathlist) = @_;
+	my($path);
+
+	foreach $path (@pathlist) {
+		if (-x $path."/".$progname) {
+			return($path."/".$progname);
+		}
+	}
+	return("");
+}
+
+#
+#  ãã¡ã¤ã«ãå¤æãã
+#
+sub convert {
+	my($infile, $outfile) = @_;
+	my($line);
+
+	print STDERR "configure: Generating $outfile from $infile.\n";
+	if (-f $outfile) {
+		print STDERR "configure: $outfile exists.",
+						"  Save as $outfile.bak.\n";
+		rename($outfile, $outfile.".bak");
+	}
+	unless (open(INFILE, $infile)) {
+		print STDERR "configure: can't open $infile\n";
+		exit(1);
+	}
+	unless (open(OUTFILE, "> ".$outfile)) {
+		print STDERR "configure: can't open $outfile\n";
+		exit(1);
+	}
+
+	while ($line = <INFILE>) {
+		chop $line;
+		while ($line =~ /^(.*)\@\(([A-Za-z_]+)\)(.*)$/) {
+			$line = $1.$vartable{$2}.$3;
+		}
+		print OUTFILE $line,"\n";
+	}
+
+	close(INFILE);
+	close(OUTFILE);
+}
+
+#
+#  ãµã³ãã«ãè¦ã¤ãã¦ãã¡ã¤ã«ãçæãã
+#
+sub generate {
+	my($file, $mandatory) = @_;
+	my($path);
+
+	$path = $templatedir."/".$file.".".$target;
+	if (-f $path) {
+		convert($path, $file);
+		return;
+	}	
+
+	$path = $templatedir."/".$file;
+	if ($mandatory || -f $path) {
+		convert($path, $file);
+	}	
+}
+
+#
+#  ã½ã¼ã¹ãã£ã¬ã¯ããªåãåãåºã
+#
+$pwd = `pwd`; chop $pwd;
+if ($opt_D) {
+	$srcabsdir = $srcdir = $opt_D;
+}
+elsif ($0 =~ /(.*)\/configure/) {
+	$srcdir = $1;
+	if ($srcdir =~ /^\//) {
+		$srcabsdir = $srcdir;
+	}
+	else {
+		$srcabsdir = $pwd."/".$srcdir;
+	}
+}
+else {
+	$srcabsdir = $srcdir = $pwd;
+}
+
+$perl = $opt_p ? $opt_p : get_path("perl", ("/usr/local/bin", "/usr/bin"));
+$cfg = $opt_g ? $opt_g : "\$(SRCDIR)/cfg/cfg/cfg";
+$cfgfile = $opt_g ? $opt_g : $srcdir."/cfg/cfg/cfg";
+$templatedir = $opt_t ? $opt_t : $srcdir."/sample";
+
+#
+#  -Tãªãã·ã§ã³ã®ç¢ºèª
+#
+unless ($opt_T) {
+	print STDERR "configure: -T option is mandatory\n";
+	print STDERR "Installed targets are:\n";
+	foreach $targetname (<$srcdir/target/[a-zA-Z0-9]*>) {
+		$targetname =~ s|$srcdir/target/||;
+		print STDERR "\t$targetname\n";
+	}
+	exit(1);
+}
+
+#
+#  å¤æ°ãã¼ãã«ã®ä½æ
+#
+%vartable = ();
+$vartable{"TARGET"} = $target;
+$vartable{"APPLNAME"} = $applname;
+$vartable{"APPLDIR"} = $appldir;
+$vartable{"APPLOBJS"} = $applobjs;
+$vartable{"SYSSVCOBJS"} = $syssvcobjs;
+$vartable{"KERNEL_LIB"} = $kernel_lib;
+$vartable{"KERNEL_FUNCOBJS"} = $kernel_funcobjs;
+$vartable{"SRCDIR"} = $srcdir;
+$vartable{"SRCABSDIR"} = $srcabsdir;
+$vartable{"SRCLANG"} = $srclang;
+$vartable{"DBGENV"} = $dbgenv;
+$vartable{"ENABLE_TRACE"} = $enable_trace;
+$vartable{"PERL"} = $perl;
+$vartable{"CFG"} = $cfg;
+$objext = get_objext();
+$vartable{"OBJEXT"} = $objext;
+$vartable{"PRC_NUM"} = $prc_num;
+$vartable{"COPTS"} = $copts;
+$vartable{"CDEFS"} = $cdefs;
+$vartable{"LDFLAGS"} = $ldflags;
+
+#
+#  ã¿ã¼ã²ãããã£ã¬ã¯ããªã®ãã§ãã¯
+#
+
+if (! -d $srcdir."/target/".$target) {
+	print STDERR "configure: $srcdir/target/$target not exist\n";
+	exit(1);
+}
+
+#
+#  Makefile ã¨ã¢ããªã±ã¼ã·ã§ã³ãã¡ã¤ã«ã®çæ
+#
+
+generate($makefile, 1);
+generate($applname.".c", 0);
+generate($applname.".cpp", 0);
+generate($applname.".h", 0);
+generate($applname.".cfg", 0);
+
+#
+#  cfg ãã§ãã¦ãããã®ãã§ãã¯
+#
+
+if (!(-x ($objext eq "" ? $cfgfile : $cfgfile.".".$objext))) {
+	print STDERR "Executable file of the configurator (cfg) is not found.\n";
+}
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/files/Makefile.config
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/files/Makefile.config	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/files/Makefile.config	(revision 457)
@@ -0,0 +1,60 @@
+#
+#   TOPPERS/JSP Kernel
+#       Toyohashi Open Platform for Embedded Real-Time Systems/
+#       Just Standard Profile Kernel
+#
+#   Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
+#                               Toyohashi Univ. of Technology, JAPAN
+#   Copyright (C) 2003-2004 by Ryosuke Takeuchi
+#                Platform Development Center RICOH COMPANY,LTD. JAPAN
+#
+#   上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+#   によって公表されている GNU General Public License の Version 2 に記
+#   述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+#   を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+#   利用と呼ぶ）することを無償で許諾する．
+#   (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+#       権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+#       スコード中に含まれていること．
+#   (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+#       用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+#       者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+#       の無保証規定を掲載すること．
+#   (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+#       用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+#       と．
+#     (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+#         作権表示，この利用条件および下記の無保証規定を掲載すること．
+#     (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+#         報告すること．
+#   (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+#       害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+#
+#   本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+#   よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+#   含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+#   接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+#
+#  @(#) $Id$
+#
+
+#
+#  Makefile のプロセッサ依存 (storagedevice用)
+#
+
+#
+#  コンパイルオプション
+#
+INCLUDES := $(INCLUDES) -I$(SRCDIR)/files
+CDEFS := $(CDEFS) -D_STORAGEDEVICEMANAGER_
+LDFLAGS := $(LDFLAGS) \
+	-Wl,--wrap=fseek \
+	-Wl,--wrap=fopen \
+	-Wl,--wrap=fclose
+
+#
+#  ファイルシステムに関する定義
+#
+SYSSVC_DIR := $(SYSSVC_DIR) $(SRCDIR)/files
+SYSSVC_COBJS := $(SYSSVC_COBJS) storagedevice.o stdio.o stdfile.o diskutils.o
+
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/files/diskutils.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/files/diskutils.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/files/diskutils.c	(revision 457)
@@ -0,0 +1,278 @@
+/*
+ *  TOPPERS/JSP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Just Standard Profile Kernel
+ * 
+ *  Copyright (C) 2010-2015 by GJ Designing Center RICOH COMPANY,LTD. JAPAN
+ *  Copyright (C) 2015-2016 by TOPPERS PROJECT Educational Working Group.
+ * 
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include "storagedevice.h"
+#include "monitor.h"
+
+#define NUM_VOLUME_CMD      5
+
+static int_t volume_format(int argc, char **argv);
+static int_t volume_dir(int argc, char **argv);
+static int_t volume_mkdir(int argc, char **argv);
+static int_t volume_rmdir(int argc, char **argv);
+static int_t volume_delete(int argc, char **argv);
+
+/*
+ *  VOLUMEコマンドテーブル
+ */
+static const COMMAND_INFO volume_command_info[] = {
+	{"FORMAT",		volume_format },	/* ボリュームフォーマット */
+	{"DIR",			volume_dir    },	/* ディレクトリ表示 */
+	{"MKDIR",		volume_mkdir  },	/* ディレクトリ作成 */
+	{"RMDIR",		volume_rmdir  },	/* ディレクトリ削除 */
+	{"ERASE",		volume_delete }		/* ファイル削除 */
+};
+
+static const char volume_name[] = "VOLUME";
+static const char volume_help[] =
+"  Volume  FORMAT   [drive]\n"
+"          DIR      [path] \n"
+"          MKDIR    [path] \n"
+"          RMDIR    [path] \n"
+"          ERASE    [path] \n";
+
+static COMMAND_LINK volume_command_link = {
+	NULL,
+	NUM_VOLUME_CMD,
+	volume_name,
+	NULL,
+	volume_help,
+	&volume_command_info[0]
+};
+
+static struct dirent2 finfo;
+
+/*
+ *  RTCコマンド設定関数
+ */
+void volume_info_init(intptr_t exinf)
+{
+	setup_command(&volume_command_link);
+}
+
+/*
+ *  ストレージボリュームフォーマット
+ */
+static int_t
+volume_format(int argc, char **argv)
+{
+	printf("not support !\n");
+	return 0;
+}
+
+/*
+ *  ストレージボリュームディレクトリ
+ */
+static int_t
+volume_dir(int argc, char **argv)
+{
+	StorageDevice_t *psdev;
+	struct statfs2  status;
+	char   *path, *spath, name[16];
+	int    devno, no, count;
+	void   *dir;
+
+	name[0] = 0;
+	if(argc > 1)
+		spath = path = argv[1];
+	else
+		spath = path = &name[1];
+	devno = SDMGetDeviceNo((const char **)&path);
+	psdev = SDMGetStorageDevice(devno);
+	if(psdev == 0){
+		printf("\nno device !\n");
+		return -1;
+	}
+	if(psdev->pdevff == 0 || psdev->pdevff->_sdevff_opendir == 0){
+		printf("\nno function !\n");
+		return -1;
+	}
+	if((psdev->_sdev_attribute & SDEV_EMPLOY) == 0){
+		printf("\nno media !\n");
+		return -1;
+	}
+	count = 0;
+	dir = psdev->pdevff->_sdevff_opendir(spath);
+	if(dir != NULL){
+		if(*spath == 0){
+			name[0] = devno + '0';
+			name[1] = ':';
+			name[2] = '/';
+			name[3] = 0;
+			spath = name;
+		}
+		printf("\nDirectory [%s]\n", spath);
+		while(psdev->pdevff->_sdevff_readdir(dir, &finfo) != 0 && finfo.d_name[0] != 0){
+			count++;
+			printf("%3d %s ", count, finfo.d_name);
+			no = strlen(finfo.d_name);
+			while(no < 24){
+				putchar(' ');
+				no++;
+			}
+			printf("%04d/%02d/%02d ", (finfo.d_date>>9)+1980, (finfo.d_date>>5) & 15, finfo.d_date & 31);
+			printf("%02d:%02d:%02d ", finfo.d_time>>11, (finfo.d_time>>5) & 63, (finfo.d_time & 31)*2);
+			if(finfo.d_type & AM_HID)
+				name[0] = '*';
+			else
+				name[0] = ' ';
+			if(finfo.d_type & AM_SYS)
+				name[1] = 'S';
+			else
+				name[1] = ' ';
+			name[2] = 'R';
+			if(finfo.d_type & AM_RDO)
+				name[3] = ' ';
+			else
+				name[3] = 'W';
+			name[4] = 0;
+			if(finfo.d_type & AM_DIR)
+				printf("<DIR>  \n");
+			else if(finfo.d_type & AM_VOL)
+				printf("<VOL>  \n");
+			else
+				printf("[%s]  %8d\n", name, (int)finfo.d_fsize);
+		}
+		printf("     %d file(s)\n", count);
+		psdev->pdevff->_sdevff_closedir(dir);
+		if(psdev->pdevff->_sdevff_statfs != 0
+			 && psdev->pdevff->_sdevff_statfs(spath, &status) == 0){
+			printf("     %d free blocks %d bytes in a block\n", (int)status.f_bfree, (int)status.f_bsize);
+		}
+	}
+	else{
+		printf("Disk Error !\n");
+	}
+	return 0;
+}
+
+/*
+ *  ストレージボリュームMKDIR
+ */
+static int_t
+volume_mkdir(int argc, char **argv)
+{
+	StorageDevice_t *psdev;
+	char   *path, *spath;
+	int    devno;
+
+	if(argc > 1){
+		spath = path = argv[1];
+		devno = SDMGetDeviceNo((const char **)&path);
+		psdev = SDMGetStorageDevice(devno);
+		if(psdev == 0){
+			printf("\nno device !\n");
+			return -1;
+		}
+		if(psdev->pdevff == 0 || psdev->pdevff->_sdevff_mkdir == 0){
+			printf("\nno function !\n");
+			return -1;
+		}
+		printf(" mkdir[%s]\n", path);
+		if(psdev->pdevff->_sdevff_mkdir(spath) >= 0)
+			printf("   Ok\n");
+		else
+			printf("   Error\n");
+	}
+	return 0;
+}
+
+/*
+ *  ストレージボリュームRMDIR
+ */
+static int_t
+volume_rmdir(int argc, char **argv)
+{
+	StorageDevice_t *psdev;
+	char   *path, *spath;
+	int    devno;
+
+	if(argc > 1){
+		spath = path = argv[1];
+		devno = SDMGetDeviceNo((const char **)&path);
+		psdev = SDMGetStorageDevice(devno);
+		if(psdev == 0){
+			printf("\nno device !\n");
+			return -1;
+		}
+		if(psdev->pdevff == 0 || psdev->pdevff->_sdevff_rmdir == 0){
+			printf("\nno function !\n");
+			return -1;
+		}
+		printf(" rmdir[%s]\n", path);
+		if(psdev->pdevff->_sdevff_rmdir(spath) >= 0)
+			printf("   Ok\n");
+		else
+			printf("   Error\n");
+	}
+	return 0;
+}
+
+/*
+ *  ストレージボリュームファイル削除
+ */
+static int_t
+volume_delete(int argc, char **argv)
+{
+	StorageDevice_t *psdev;
+	char   *path, *spath;
+	int    devno;
+
+	if(argc > 1){
+		spath = path = argv[1];
+		devno = SDMGetDeviceNo((const char **)&path);
+		psdev = SDMGetStorageDevice(devno);
+		if(psdev == 0){
+			printf("\nno device !\n");
+			return -1;
+		}
+		if(psdev->pdevff == 0 || psdev->pdevff->_sdevff_unlink == 0){
+			printf("\nno function !\n");
+			return -1;
+		}
+		printf(" unlink[%s]\n", path);
+		if(psdev->pdevff->_sdevff_unlink(spath) >= 0)
+			printf("   Ok\n");
+		else
+			printf("   Error\n");
+	}
+	return 0;
+}
+
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/files/fcntl.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/files/fcntl.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/files/fcntl.h	(revision 457)
@@ -0,0 +1,229 @@
+/*	$NetBSD: fcntl.h,v 1.10.2.1 1998/01/29 10:38:31 mellon Exp $	*/
+
+/*-
+ * Copyright (c) 1983, 1990, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ * (c) UNIX System Laboratories, Inc.
+ * All or some portions of this file are derived from material licensed
+ * to the University of California by American Telephone and Telegraph
+ * Co. or Unix System Laboratories, Inc. and are reproduced herein with
+ * the permission of UNIX System Laboratories, Inc.
+ *
+ * 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. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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.
+ *
+ *	@(#)fcntl.h	8.3 (Berkeley) 1/21/94
+ */
+
+/*
+ * このプログラムはNetBSD用ヘッダーに
+ * ＲＯＭファイル専用ファイルストレージ専用機能を追加したインクルードファイルである。
+ *
+ * $Modifier:  roi takeuchi
+ * $Date:    2019/12/03
+ * $Version: 1.0.0.1
+ *
+ */
+#ifndef _SYS_FCNTL_H_
+#define	_SYS_FCNTL_H_
+
+/*
+ * This file includes the definitions for open and fcntl
+ * described by POSIX for <fcntl.h>; it also includes
+ * related kernel definitions.
+ */
+#ifndef NOTUSE_TYPES_H	/* types.hは呼ばない */
+#include <sys/types.h>
+#elif defined(__SHC__)	/* SHCの場合off_tは未定義 */
+typedef long long off_t;
+#endif
+
+/*
+ * File status flags: these are used by open(2), fcntl(2).
+ * They are also used (indirectly) in the kernel file structure f_flags,
+ * which is a superset of the open/fcntl flags.  Open flags and f_flags
+ * are inter-convertible using OFLAGS(fflags) and FFLAGS(oflags).
+ * Open/fcntl flags begin with O_; kernel-internal flags begin with F.
+ */
+/* open-only flags */
+#define	O_RDONLY	0x0000		/* open for reading only */
+#define	O_WRONLY	0x0001		/* open for writing only */
+#define	O_RDWR		0x0002		/* open for reading and writing */
+#define	O_ACCMODE	0x0003		/* mask for above modes */
+
+/*
+ * Kernel encoding of open mode; separate read and write bits that are
+ * independently testable: 1 greater than the above.
+ *
+ * XXX
+ * FREAD and FWRITE are excluded from the #ifdef _KERNEL so that TIOCFLUSH,
+ * which was documented to use FREAD/FWRITE, continues to work.
+ */
+#ifndef _POSIX_SOURCE
+#define	FREAD		0x0001
+#define	FWRITE		0x0002
+#endif
+#define	O_NONBLOCK	0x0004		/* no delay */
+#define	O_APPEND	0x0008		/* set append mode */
+#ifndef _POSIX_SOURCE
+#define	O_SHLOCK	0x0010		/* open with shared file lock */
+#define	O_EXLOCK	0x0020		/* open with exclusive file lock */
+#define	O_ASYNC		0x0040		/* signal pgrp when data ready */
+#endif
+#if !defined(_POSIX_SOURCE) || defined(_XOPEN_SOURCE)
+#define	O_SYNC		0x0080		/* synchronous writes */
+#endif
+#define	O_CREAT		0x0200		/* create if nonexistant */
+#define	O_TRUNC		0x0400		/* truncate to zero length */
+#define	O_EXCL		0x0800		/* error if already exists */
+
+/* defined by POSIX 1003.1; BSD default, but required to be distinct */
+#define	O_NOCTTY	0x8000		/* don't assign controlling terminal */
+
+/*
+ * The O_* flags used to have only F* names, which were used in the kernel
+ * and by fcntl.  We retain the F* names for the kernel f_flags field
+ * and for backward compatibility for fcntl.
+ */
+#ifndef _POSIX_SOURCE
+#define	FAPPEND		O_APPEND	/* kernel/compat */
+#define	FASYNC		O_ASYNC		/* kernel/compat */
+#define	FFSYNC		O_SYNC		/* kernel */
+#ifndef _XOPEN_SOURCE
+#define	O_FSYNC		O_SYNC		/* compat */
+#endif
+#define	FNONBLOCK	O_NONBLOCK	/* kernel */
+#define	FNDELAY		O_NONBLOCK	/* compat */
+#define	O_NDELAY	O_NONBLOCK	/* compat */
+#endif
+
+/*
+ * Constants used for fcntl(2)
+ */
+
+/* command values */
+#define	F_DUPFD		0		/* duplicate file descriptor */
+#define	F_GETFD		1		/* get file descriptor flags */
+#define	F_SETFD		2		/* set file descriptor flags */
+#define	F_GETFL		3		/* get file status flags */
+#define	F_SETFL		4		/* set file status flags */
+#ifndef _POSIX_SOURCE
+#define	F_GETOWN	5		/* get SIGIO/SIGURG proc/pgrp */
+#define F_SETOWN	6		/* set SIGIO/SIGURG proc/pgrp */
+#endif
+#define	F_GETLK		7		/* get record locking information */
+#define	F_SETLK		8		/* set record locking information */
+#define	F_SETLKW	9		/* F_SETLK; wait if blocked */
+
+/* file descriptor flags (F_GETFD, F_SETFD) */
+#define	FD_CLOEXEC	1		/* close-on-exec flag */
+
+/* record locking flags (F_GETLK, F_SETLK, F_SETLKW) */
+#define	F_RDLCK		1		/* shared or read lock */
+#define	F_UNLCK		2		/* unlock */
+#define	F_WRLCK		3		/* exclusive or write lock */
+
+#ifndef _POSIX_SOURCE
+/* lock operations for flock(2) */
+#define	LOCK_SH		0x01		/* shared file lock */
+#define	LOCK_EX		0x02		/* exclusive file lock */
+#define	LOCK_NB		0x04		/* don't block when locking */
+#define	LOCK_UN		0x08		/* unlock file */
+#endif
+
+/* fseek parameters */
+#ifndef SEEK_SET
+#define	SEEK_SET	0	/* set file offset to offset */
+#endif
+#ifndef SEEK_CUR
+#define	SEEK_CUR	1	/* set file offset to current plus offset */
+#endif
+#ifndef SEEK_END
+#define	SEEK_END	2	/* set file offset to EOF plus offset */
+#endif
+
+/* struct stat defintion */
+#ifndef	_SYS_STAT_H
+struct stat {
+	unsigned int    st_dev;		/* inode's device */
+	unsigned int    st_ino;		/* inode's number */
+	unsigned int    st_mode;	/* inode protection mode */
+	unsigned int    t_nlink;	/* number of hard links */
+	unsigned int    st_uid;		/* user ID of the file's owner */
+	unsigned int    st_gid;		/* group ID of the file's group */
+	unsigned int    st_rdev;	/* device type */
+	int             st_atime;	/* time of last access */
+	long            st_atimensec;	/* nsec of last access */
+	int             st_mtime;	/* time of last data modification */
+	long            st_mtimensec;	/* nsec of last data modification */
+	int             st_ctime;	/* time of last file status change */
+	long            st_ctimensec;	/* nsec of last file status change */
+	off_t           st_size;	/* file size, in bytes */
+	off_t           st_blocks;	/* blocks allocated for file */
+	unsigned int    st_blksize;	/* optimal blocksize for I/O */
+	unsigned int    st_flags;	/* user defined flags for file */
+	unsigned int    st_gen;		/* file generation number */
+	off_t           st_qspare[2];
+};
+#define _STAT_H_
+#endif	/* _SYS_STAT_H */
+
+/*
+ * Protections are chosen from these bits, or-ed together
+ */
+#define	PROT_NONE	0x00	/* no permissions */
+#define	PROT_READ	0x01	/* pages can be read */
+#define	PROT_WRITE	0x02	/* pages can be written */
+#define	PROT_EXEC	0x04	/* pages can be executed */
+
+/*
+ * Flags contain sharing type and options.
+ * Sharing types; choose one.
+ */
+#define	MAP_SHARED	0x0001	/* share changes */
+#define	MAP_PRIVATE	0x0002	/* changes are private */
+#define	MAP_COPY	0x0004	/* "copy" region at mmap time */
+
+struct StdFileIndex {
+	void            *sdmdev;
+	int             sdmfd;
+};
+
+extern int   open(const char *pathname, int flags);
+extern int   close(int fd);
+extern int   fstat(int fd, struct stat *buf);
+extern off_t lseek(int fd, off_t offset, int whence);
+extern long  read(int fd, void *buf, long count);
+extern long  write(int fd, const void *buf, long count);
+extern void  *mmap(void *start, size_t length, int prot, int flags, int fd, off_t offset);
+extern int   munmap(void *start, size_t length);
+
+
+#endif /* !_SYS_FCNTL_H_ */
+
+
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/files/ff/00readme.txt
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/files/ff/00readme.txt	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/files/ff/00readme.txt	(revision 457)
@@ -0,0 +1,96 @@
+FatFs/Tiny-FatFs Module Source Files R0.07a                 (C)ChaN, 2009
+
+
+FILES
+
+  ff.h       Common include file for FatFs and application module.
+  ff.c       FatFs module.
+  diskio.h   Common include file for FatFs and disk I/O module.
+  diskio.c   Skeleton of low level disk I/O module.
+  integer.h  Alternative type definitions for integer variables.
+  option     Optional external functions.
+
+  Low level disk I/O module is not included in this archive because the FatFs
+  module is only a generic file system layer and not depend on any specific
+  storage device. You have to provide a low level disk I/O module that written
+  to control your storage device.
+
+
+
+AGREEMENTS
+
+ FatFs module is an open source software to implement FAT file system to
+ small embedded systems. This is a free software and is opened for education,
+ research and commercial developments under license policy of following trems.
+
+  Copyright (C) 2009, ChaN, all right reserved.
+
+ * The FatFs module is a free software and there is NO WARRANTY.
+ * No restriction on use. You can use, modify and redistribute it for
+   personal, non-profit or commercial use UNDER YOUR RESPONSIBILITY.
+ * Redistributions of source code must retain the above copyright notice.
+
+
+
+REVISION HISTORY
+
+  Feb 26, 2006  R0.00  Prototype
+
+  Apr 29, 2006  R0.01  First release.
+
+  Jun 01, 2006  R0.02  Added FAT12.
+                       Removed unbuffered mode.
+                       Fixed a problem on small (<32M) patition.
+
+  Jun 10, 2006  R0.02a Added a configuration option _FS_MINIMUM.
+
+  Sep 22, 2006  R0.03  Added f_rename.
+                       Changed option _FS_MINIMUM to _FS_MINIMIZE.
+
+  Dec 11, 2006  R0.03a Improved cluster scan algolithm to write files fast.
+                       Fixed f_mkdir creates incorrect directory on FAT32.
+
+  Feb 04, 2007  R0.04  Supported multiple drive system. (FatFs)
+                       Changed some APIs for multiple drive system.
+                       Added f_mkfs. (FatFs)
+                       Added _USE_FAT32 option. (Tiny-FatFs)
+
+  Apr 01, 2007  R0.04a Supported multiple partitions on a plysical drive. (FatFs)
+                       Fixed an endian sensitive code in f_mkfs. (FatFs)
+                       Added a capability of extending the file size to f_lseek.
+                       Added minimization level 3.
+                       Fixed a problem that can collapse a sector when recreate an
+                       existing file in any sub-directory at non FAT32 cfg. (Tiny-FatFs)
+
+  May 05, 2007  R0.04b Added _USE_NTFLAG option.
+                       Added FSInfo support.
+                       Fixed some problems corresponds to FAT32. (Tiny-FatFs)
+                       Fixed DBCS name can result FR_INVALID_NAME.
+                       Fixed short seek (0 < ofs <= csize) collapses the file object.
+
+  Aug 25, 2007  R0.05  Changed arguments of f_read, f_write.
+                       Changed arguments of f_mkfs. (FatFs)
+                       Fixed f_mkfs on FAT32 creates incorrect FSInfo. (FatFs)
+                       Fixed f_mkdir on FAT32 creates incorrect directory. (FatFs)
+
+  Feb 03, 2008  R0.05a Added f_truncate().
+                       Added f_utime().
+                       Fixed off by one error at FAT sub-type determination.
+                       Fixed btr in f_read() can be mistruncated.
+                       Fixed cached sector is not flushed when create and close without write.
+
+  Apr 01, 2008  R0.06  Added f_forward(). (Tiny-FatFs)
+                       Added string functions: fputc(), fputs(), fprintf() and fgets().
+                       Improved performance of f_lseek() on move to the same or following cluster.
+
+  Apr 01, 2009, R0.07  Merged Tiny-FatFs as a buffer configuration option.
+                       Added long file name support.
+                       Added multiple code page support.
+                       Added re-entrancy for multitask operation.
+                       Added auto cluster size selection to f_mkfs().
+                       Added rewind option to f_readdir().
+                       Changed result code of critical errors.
+                       Renamed string functions to avoid name collision.
+
+  Apr 14, 2009, R0.07a Separated out OS dependent code on reentrant cfg.
+                       Added multiple sector size support.
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/files/ff/Makefile.config
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/files/ff/Makefile.config	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/files/ff/Makefile.config	(revision 457)
@@ -0,0 +1,55 @@
+#
+#   TOPPERS/JSP Kernel
+#       Toyohashi Open Platform for Embedded Real-Time Systems/
+#       Just Standard Profile Kernel
+#
+#   Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
+#                               Toyohashi Univ. of Technology, JAPAN
+#   Copyright (C) 2003-2004 by Ryosuke Takeuchi
+#                Platform Development Center RICOH COMPANY,LTD. JAPAN
+#
+#   上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+#   によって公表されている GNU General Public License の Version 2 に記
+#   述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+#   を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+#   利用と呼ぶ）することを無償で許諾する．
+#   (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+#       権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+#       スコード中に含まれていること．
+#   (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+#       用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+#       者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+#       の無保証規定を掲載すること．
+#   (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+#       用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+#       と．
+#     (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+#         作権表示，この利用条件および下記の無保証規定を掲載すること．
+#     (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+#         報告すること．
+#   (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+#       害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+#
+#   本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+#   よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+#   含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+#   接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+#
+#  @(#) $Id$
+#
+ 
+#
+#  Makefile のプロセッサ依存 (fatfs用)
+#
+
+#
+#  コンパイルオプション
+#
+INCLUDES := $(INCLUDES) -I$(SRCDIR)/files/ff
+
+#
+#  ファイルシステムに関する定義
+#
+SYSSVC_DIR := $(SYSSVC_DIR) $(SRCDIR)/files/ff $(SRCDIR)/files/ff/option
+SYSSVC_COBJS := $(SYSSVC_COBJS) ff.o syncobj.o cc932.o diskio.o sddiskio.o fffcntl.o
+
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/files/ff/Makefile2.config
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/files/ff/Makefile2.config	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/files/ff/Makefile2.config	(revision 457)
@@ -0,0 +1,55 @@
+#
+#   TOPPERS/JSP Kernel
+#       Toyohashi Open Platform for Embedded Real-Time Systems/
+#       Just Standard Profile Kernel
+#
+#   Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
+#                               Toyohashi Univ. of Technology, JAPAN
+#   Copyright (C) 2003-2004 by Ryosuke Takeuchi
+#                Platform Development Center RICOH COMPANY,LTD. JAPAN
+#
+#   上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+#   によって公表されている GNU General Public License の Version 2 に記
+#   述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+#   を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+#   利用と呼ぶ）することを無償で許諾する．
+#   (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+#       権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+#       スコード中に含まれていること．
+#   (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+#       用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+#       者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+#       の無保証規定を掲載すること．
+#   (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+#       用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+#       と．
+#     (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+#         作権表示，この利用条件および下記の無保証規定を掲載すること．
+#     (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+#         報告すること．
+#   (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+#       害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+#
+#   本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+#   よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+#   含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+#   接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+#
+#  @(#) $Id$
+#
+ 
+#
+#  Makefile のプロセッサ依存 (fatfs用)
+#
+
+#
+#  コンパイルオプション
+#
+INCLUDES := $(INCLUDES) -I$(SRCDIR)/files/ff
+
+#
+#  ファイルシステムに関する定義
+#
+SYSSVC_DIR := $(SYSSVC_DIR) $(SRCDIR)/files/ff $(SRCDIR)/files/ff/option
+SYSSVC_COBJS := $(SYSSVC_COBJS) ff.o syncobj.o cc932.o diskio.o fffcntl.o
+
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/files/ff/diskio.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/files/ff/diskio.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/files/ff/diskio.c	(revision 457)
@@ -0,0 +1,157 @@
+/*
+ *  FatFs for TOPPERS
+ *      FAT File system/
+ *      Toyohashi Open Platform for Embedded Real-Time Systems
+ * 
+ *  Copyright (C) 2005- by Industrial Technology Institute,
+ *                          Miyagi Prefectural Government, JAPAN
+ *  Copyright (C) 2007-2010 by 
+ *                     GJ Business Division RICOH COMPANY,LTD. JAPAN
+ *  Copyright (C) 2015-2017 by TOPPERS PROJECT Educational Group.
+ * 
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *  FatFsが規定している下位レイヤI/F
+ *  　本来は複数ドライブに対応すべきだが、このターゲットボードでは
+ *  　ドライブは１つのみサポートしている。
+ */
+
+#include "kernel_impl.h"
+#include <string.h>	/*  memcpy()  */
+#include <t_syslog.h>
+#include <t_stdlib.h>
+#include "storagedevice.h"
+#include "diskio.h"
+
+#define RETRY_COUNT    8
+
+/*
+ *  ディスク・ドライブの初期化
+ *　　引数
+ *　　　 BYTE Drive	物理ドライブ番号
+ */
+DSTATUS
+disk_initialize(BYTE Drive)
+{
+	StorageDevice_t *psdev = SDMGetStorageDevice(Drive);
+
+	if(psdev == NULL || psdev->pdevf == NULL || psdev->pdevf->_sdevf_diskinit == NULL)
+		return STA_NODISK;
+	return psdev->pdevf->_sdevf_diskinit(psdev);
+}
+
+
+/*
+ *  ディスク・ドライブの状態取得
+ *　　引数
+ *　　　 BYTE Drive	物理ドライブ番号
+ */
+DSTATUS
+disk_status(BYTE Drive)
+{
+	StorageDevice_t *psdev = SDMGetStorageDevice(Drive);
+
+	if(psdev == NULL || psdev->pdevf == NULL || psdev->pdevf->_sdevf_diskstatus == NULL)
+		return STA_NODISK;
+	return psdev->pdevf->_sdevf_diskstatus(psdev);
+}
+
+
+/*
+ *  ディスクからの読み込み
+ *　　引数
+ *　　　 BYTE Drive　　　　　物理ドライブ番号
+ *　　　 BYTE* Buffer        読み出しバッファへのポインタ
+ *　　　 DWORD SectorNumber  読み出し開始セクタ番号
+ *　　　 BYTE SectorCount    読み出しセクタ数
+ */
+DRESULT
+disk_read(BYTE Drive, BYTE* Buffer, DWORD SectorNumber, BYTE SectorCount)
+{
+	StorageDevice_t *psdev = SDMGetStorageDevice(Drive);
+
+	if(psdev == NULL || psdev->pdevf == NULL || psdev->pdevf->_sdevf_diskread == NULL)
+		return RES_ERROR;
+	return psdev->pdevf->_sdevf_diskread(psdev, Buffer, SectorNumber, SectorCount);
+}
+
+/*
+ *  ディスクへの書き込み
+ *　　引数
+ *　　　 BYTE Drive　　　　　物理ドライブ番号
+ *　　　 BYTE* Buffer        書き込むデータへのポインタ
+ *　　　 DWORD SectorNumber  書き込み開始セクタ番号
+ *　　　 BYTE SectorCount    書き込みセクタ数
+ */
+DRESULT
+disk_write(BYTE Drive, const BYTE* Buffer, DWORD SectorNumber, BYTE SectorCount)
+{
+	StorageDevice_t *psdev = SDMGetStorageDevice(Drive);
+
+	if(psdev == NULL || psdev->pdevf == NULL || psdev->pdevf->_sdevf_diskwrite == NULL)
+		return RES_ERROR;
+	return psdev->pdevf->_sdevf_diskwrite(psdev, Buffer, SectorNumber, SectorCount);
+}
+
+DRESULT
+disk_ioctl(BYTE Drive, BYTE Func, void* Buffer)
+{
+	StorageDevice_t *psdev = SDMGetStorageDevice(Drive);
+
+	if(psdev == NULL || psdev->pdevf == NULL || psdev->pdevf->_sdevf_diskioctl == NULL)
+		return RES_ERROR;
+	return psdev->pdevf->_sdevf_diskioctl(psdev, Func, Buffer);
+}
+
+/*
+ *  日付・時刻の取得
+ *  　　ToDo：未実装
+ */
+DWORD
+get_fattime(void)
+{
+	SYSTIM systim;
+	DWORD  fdate = ((2017-1980)<<25)+(1<<21)+(1<<16);
+	DWORD  ftime;
+
+	if(SDeviceHead._get_datetime != 0)
+		return (DWORD)SDeviceHead._get_datetime();
+	else{
+		get_tim(&systim);
+		systim = (systim+1000L) /2000L;
+		ftime  = systim % 30;
+		ftime += ((systim/30) % 60)<<5;
+		ftime += ((systim/(60*30))<<11);
+		return (fdate+ftime);
+	}
+}
+
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/files/ff/diskio.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/files/ff/diskio.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/files/ff/diskio.h	(revision 457)
@@ -0,0 +1,70 @@
+/*-----------------------------------------------------------------------
+/  Low level disk interface modlue include file  R0.07   (C)ChaN, 2009
+/-----------------------------------------------------------------------*/
+
+#ifndef _DISKIO
+
+#define _READONLY	0	/* 1: Read-only mode */
+#define _USE_IOCTL	1
+
+#include "integer.h"
+
+
+/* Status of Disk Functions */
+typedef BYTE	DSTATUS;
+
+/* Results of Disk Functions */
+typedef enum {
+	RES_OK = 0,		/* 0: Successful */
+	RES_ERROR,		/* 1: R/W Error */
+	RES_WRPRT,		/* 2: Write Protected */
+	RES_NOTRDY,		/* 3: Not Ready */
+	RES_PARERR		/* 4: Invalid Parameter */
+} DRESULT;
+
+
+/*---------------------------------------*/
+/* Prototypes for disk control functions */
+
+BOOL assign_drives (int argc, char *argv[]);
+DSTATUS disk_initialize (BYTE);
+DSTATUS disk_status (BYTE);
+DRESULT disk_read (BYTE, BYTE*, DWORD, BYTE);
+#if	_READONLY == 0
+DRESULT disk_write (BYTE, const BYTE*, DWORD, BYTE);
+#endif
+DRESULT disk_ioctl (BYTE, BYTE, void*);
+
+
+
+/* Disk Status Bits (DSTATUS) */
+
+#define STA_NOINIT		0x01	/* Drive not initialized */
+#define STA_NODISK		0x02	/* No medium in the drive */
+#define STA_PROTECT		0x04	/* Write protected */
+
+
+/* Command code for disk_ioctrl() */
+
+/* Generic command */
+#define CTRL_SYNC			0	/* Mandatory for write functions */
+#define GET_SECTOR_COUNT	1	/* Mandatory for only f_mkfs() */
+#define GET_SECTOR_SIZE		2
+#define GET_BLOCK_SIZE		3	/* Mandatory for only f_mkfs() */
+#define CTRL_POWER			4
+#define CTRL_LOCK			5
+#define CTRL_EJECT			6
+/* MMC/SDC command */
+#define MMC_GET_TYPE		10
+#define MMC_GET_CSD			11
+#define MMC_GET_CID			12
+#define MMC_GET_OCR			13
+#define MMC_GET_SDSTAT		14
+/* ATA/CF command */
+#define ATA_GET_REV			20
+#define ATA_GET_MODEL		21
+#define ATA_GET_SN			22
+
+
+#define _DISKIO
+#endif
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/files/ff/fatfs.cfg
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/files/ff/fatfs.cfg	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/files/ff/fatfs.cfg	(revision 457)
@@ -0,0 +1,18 @@
+/*
+ *  @(#) $Id$
+ */
+
+/*
+ *  FATFSのコンフィギュレーションファイル
+ */
+
+#include "ff.h"
+#include "sddiskio.h"
+
+ATT_INI({TA_NULL, 0, sd_init});
+
+CRE_SEM(SEMID_FATFS1,{ TA_TPRI, 1, 1 });
+CRE_SEM(SEMID_FATFS2,{ TA_TPRI, 1, 1 });
+CRE_SEM(SEMID_FATFS3,{ TA_TPRI, 1, 1 });
+CRE_SEM(SEMID_FATFS4,{ TA_TPRI, 1, 1 });
+
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/files/ff/ff.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/files/ff/ff.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/files/ff/ff.c	(revision 457)
@@ -0,0 +1,2945 @@
+/*----------------------------------------------------------------------------/
+/  FatFs - FAT file system module  R0.07a                    (C)ChaN, 2009
+/-----------------------------------------------------------------------------/
+/ FatFs module is an open source software to implement FAT file system to
+/ small embedded systems. This is a free software and is opened for education,
+/ research and commercial developments under license policy of following trems.
+/
+/  Copyright (C) 2009, ChaN, all right reserved.
+/
+/ * The FatFs module is a free software and there is NO WARRANTY.
+/ * No restriction on use. You can use, modify and redistribute it for
+/   personal, non-profit or commercial use UNDER YOUR RESPONSIBILITY.
+/ * Redistributions of source code must retain the above copyright notice.
+//-----------------------------------------------------------------------------/
+/ Feb 26,'06 R0.00  Prototype.
+/
+/ Apr 29,'06 R0.01  First stable version.
+/
+/ Jun 01,'06 R0.02  Added FAT12 support.
+/                   Removed unbuffered mode.
+/                   Fixed a problem on small (<32M) patition.
+/ Jun 10,'06 R0.02a Added a configuration option (_FS_MINIMUM).
+/
+/ Sep 22,'06 R0.03  Added f_rename().
+/                   Changed option _FS_MINIMUM to _FS_MINIMIZE.
+/ Dec 11,'06 R0.03a Improved cluster scan algolithm to write files fast.
+/                   Fixed f_mkdir() creates incorrect directory on FAT32.
+/
+/ Feb 04,'07 R0.04  Supported multiple drive system.
+/                   Changed some interfaces for multiple drive system.
+/                   Changed f_mountdrv() to f_mount().
+/                   Added f_mkfs().
+/ Apr 01,'07 R0.04a Supported multiple partitions on a plysical drive.
+/                   Added a capability of extending file size to f_lseek().
+/                   Added minimization level 3.
+/                   Fixed an endian sensitive code in f_mkfs().
+/ May 05,'07 R0.04b Added a configuration option _USE_NTFLAG.
+/                   Added FSInfo support.
+/                   Fixed DBCS name can result FR_INVALID_NAME.
+/                   Fixed short seek (<= csize) collapses the file object.
+/
+/ Aug 25,'07 R0.05  Changed arguments of f_read(), f_write() and f_mkfs().
+/                   Fixed f_mkfs() on FAT32 creates incorrect FSInfo.
+/                   Fixed f_mkdir() on FAT32 creates incorrect directory.
+/ Feb 03,'08 R0.05a Added f_truncate() and f_utime().
+/                   Fixed off by one error at FAT sub-type determination.
+/                   Fixed btr in f_read() can be mistruncated.
+/                   Fixed cached sector is not flushed when create and close
+/                   without write.
+/
+/ Apr 01,'08 R0.06  Added fputc(), fputs(), fprintf() and fgets().
+/                   Improved performance of f_lseek() on moving to the same
+/                   or following cluster.
+/
+/ Apr 01,'09 R0.07  Merged Tiny-FatFs as a buffer configuration option.
+/                   Added long file name support.
+/                   Added multiple code page support.
+/                   Added re-entrancy for multitask operation.
+/                   Added auto cluster size selection to f_mkfs().
+/                   Added rewind option to f_readdir().
+/                   Changed result code of critical errors.
+/                   Renamed string functions to avoid name collision.
+/ Apr 14,'09 R0.07a Separated out OS dependent code on reentrant cfg.
+/                   Added multiple sector size support.
+/---------------------------------------------------------------------------*/
+
+#include "ff.h"			/* FatFs configurations and declarations */
+#include "diskio.h"		/* Declarations of low level disk I/O functions */
+
+
+/*--------------------------------------------------------------------------
+
+   Module Private Definitions
+
+---------------------------------------------------------------------------*/
+
+#if _FS_REENTRANT
+#if _USE_LFN == 1
+#error Static LFN work area must not be used in re-entrant configuration.
+#endif
+#define	ENTER_FF(fs)		{ if (!lock_fs(fs)) return FR_TIMEOUT; }
+#define	LEAVE_FF(fs, res)	{ unlock_fs(fs, res); return res; }
+
+#else
+#define	ENTER_FF(fs)
+#define LEAVE_FF(fs, res)	return res
+
+#endif
+
+#define	ABORT(fs, res)		{ fp->flag |= FA__ERROR; LEAVE_FF(fs, res); }
+
+#ifndef NULL
+#define	NULL	0
+#endif
+
+
+/*--------------------------------------------------------------------------
+
+   Private Work Area
+
+---------------------------------------------------------------------------*/
+
+static
+FATFS *FatFs[_DRIVES];	/* Pointer to the file system objects (logical drives) */
+static
+WORD Fsid;				/* File system mount ID */
+
+
+#if _USE_LFN == 1	/* LFN with static LFN working buffer */
+static
+WORD LfnBuf[_MAX_LFN + 1];
+#define	NAMEBUF(sp,lp)	BYTE sp[12]; WCHAR *lp = LfnBuf
+#define INITBUF(dj,sp,lp)	dj.fn = sp; dj.lfn = lp
+
+#elif _USE_LFN > 1	/* LFN with dynamic LFN working buffer */
+#define	NAMEBUF(sp,lp)	BYTE sp[12]; WCHAR lbuf[_MAX_LFN + 1], *lp = lbuf
+#define INITBUF(dj,sp,lp)	dj.fn = sp; dj.lfn = lp
+#if 1	/* ROI MODIFIED */
+#define INITBUF2(dj,sp)		dj.fn = sp
+#endif	/* ROI MODIFIED */
+
+#else				/* No LFN */
+#define	NAMEBUF(sp,lp)	BYTE sp[12]
+#define INITBUF(dj,sp,lp)	dj.fn = sp
+
+#endif
+
+
+
+
+/*--------------------------------------------------------------------------
+
+   Private Functions
+
+---------------------------------------------------------------------------*/
+
+
+/*-----------------------------------------------------------------------*/
+/* String functions                                                      */
+/*-----------------------------------------------------------------------*/
+
+/* Copy memory to memory */
+static
+void mem_cpy (void* dst, const void* src, int cnt) {
+	char *d = (char*)dst;
+	const char *s = (const char *)src;
+	while (cnt--) *d++ = *s++;
+}
+
+/* Fill memory */
+static
+void mem_set (void* dst, int val, int cnt) {
+	char *d = (char*)dst;
+	while (cnt--) *d++ = (char)val;
+}
+
+/* Compare memory to memory */
+static
+int mem_cmp (const void* dst, const void* src, int cnt) {
+	const char *d = (const char *)dst, *s = (const char *)src;
+	int r = 0;
+	while (cnt-- && (r = *d++ - *s++) == 0) ;
+	return r;
+}
+
+/* Check if chr is contained in the string */
+static
+int chk_chr (const char* str, int chr) {
+	while (*str && *str != chr) str++;
+	return *str;
+}
+
+
+
+/*-----------------------------------------------------------------------*/
+/* Request/Release grant to access the volume                            */
+/*-----------------------------------------------------------------------*/
+#if _FS_REENTRANT
+
+static
+BOOL lock_fs (
+	FATFS *fs		/* File system object */
+)
+{
+	return ff_req_grant(fs->sobj);
+}
+
+
+static
+void unlock_fs (
+	FATFS *fs,		/* File system object */
+	FRESULT res		/* Result code to be returned */
+)
+{
+	if (res != FR_NOT_ENABLED &&
+		res != FR_INVALID_DRIVE &&
+		res != FR_INVALID_OBJECT &&
+		res != FR_TIMEOUT) {
+		ff_rel_grant(fs->sobj);
+	}
+}
+#endif
+
+
+
+/*-----------------------------------------------------------------------*/
+/* Change window offset                                                  */
+/*-----------------------------------------------------------------------*/
+
+static
+FRESULT move_window (
+	FATFS *fs,		/* File system object */
+	DWORD sector	/* Sector number to make apperance in the fs->win[] */
+)					/* Move to zero only writes back dirty window */
+{
+	DWORD wsect;
+
+
+	wsect = fs->winsect;
+	if (wsect != sector) {	/* Changed current window */
+#if !_FS_READONLY
+		if (fs->wflag) {	/* Write back dirty window if needed */
+			if (disk_write(fs->drive, fs->win, wsect, 1) != RES_OK)
+				return FR_DISK_ERR;
+			fs->wflag = 0;
+			if (wsect < (fs->fatbase + fs->sects_fat)) {	/* In FAT area */
+				BYTE nf;
+				for (nf = fs->n_fats; nf >= 2; nf--) {	/* Refrect the change to FAT copy */
+					wsect += fs->sects_fat;
+					disk_write(fs->drive, fs->win, wsect, 1);
+				}
+			}
+		}
+#endif
+		if (sector) {
+			if (disk_read(fs->drive, fs->win, sector, 1) != RES_OK)
+				return FR_DISK_ERR;
+			fs->winsect = sector;
+		}
+	}
+
+	return FR_OK;
+}
+
+
+
+
+/*-----------------------------------------------------------------------*/
+/* Clean-up cached data                                                  */
+/*-----------------------------------------------------------------------*/
+#if !_FS_READONLY
+static
+FRESULT sync (	/* FR_OK: successful, FR_DISK_ERR: failed */
+	FATFS *fs	/* File system object */
+)
+{
+	FRESULT res;
+
+
+	res = move_window(fs, 0);
+	if (res == FR_OK) {
+		/* Update FSInfo sector if needed */
+		if (fs->fs_type == FS_FAT32 && fs->fsi_flag) {
+			fs->winsect = 0;
+			mem_set(fs->win, 0, 512);
+			ST_WORD(fs->win+BS_55AA, 0xAA55);
+			ST_DWORD(fs->win+FSI_LeadSig, 0x41615252);
+			ST_DWORD(fs->win+FSI_StrucSig, 0x61417272);
+			ST_DWORD(fs->win+FSI_Free_Count, fs->free_clust);
+			ST_DWORD(fs->win+FSI_Nxt_Free, fs->last_clust);
+			disk_write(fs->drive, fs->win, fs->fsi_sector, 1);
+			fs->fsi_flag = 0;
+		}
+		/* Make sure that no pending write process in the physical drive */
+		if (disk_ioctl(fs->drive, CTRL_SYNC, (void*)NULL) != RES_OK)
+			res = FR_DISK_ERR;
+	}
+
+	return res;
+}
+#endif
+
+
+
+
+/*-----------------------------------------------------------------------*/
+/* Get a cluster status                                                  */
+/*-----------------------------------------------------------------------*/
+
+static
+DWORD get_cluster (	/* 0xFFFFFFFF:Disk error, 1:Interal error, Else:Cluster status */
+	FATFS *fs,		/* File system object */
+	DWORD clst		/* Cluster# to get the link information */
+)
+{
+	WORD wc, bc;
+	DWORD fsect;
+
+
+	if (clst < 2 || clst >= fs->max_clust)	/* Check cluster address range */
+		return 1;
+
+	fsect = fs->fatbase;
+	switch (fs->fs_type) {
+	case FS_FAT12 :
+		bc = (WORD)clst * 3 / 2;
+		if (move_window(fs, fsect + (bc / SS(fs)))) break;
+		wc = fs->win[bc & (SS(fs) - 1)]; bc++;
+		if (move_window(fs, fsect + (bc / SS(fs)))) break;
+		wc |= (WORD)fs->win[bc & (SS(fs) - 1)] << 8;
+		return (clst & 1) ? (wc >> 4) : (wc & 0xFFF);
+
+	case FS_FAT16 :
+		if (move_window(fs, fsect + (clst / (SS(fs) / 2)))) break;
+		return LD_WORD(&fs->win[((WORD)clst * 2) & (SS(fs) - 1)]);
+
+	case FS_FAT32 :
+		if (move_window(fs, fsect + (clst / (SS(fs) / 4)))) break;
+		return LD_DWORD(&fs->win[((WORD)clst * 4) & (SS(fs) - 1)]) & 0x0FFFFFFF;
+	}
+
+	return 0xFFFFFFFF;	/* An error occured at the disk I/O layer */
+}
+
+
+
+
+/*-----------------------------------------------------------------------*/
+/* Change a cluster status                                               */
+/*-----------------------------------------------------------------------*/
+#if !_FS_READONLY
+static
+FRESULT put_cluster (
+	FATFS *fs,		/* File system object */
+	DWORD clst,		/* Cluster# to be changed (must be 2 to fs->max_clust-1) */
+	DWORD val		/* New value to mark the cluster */
+)
+{
+	WORD bc;
+	BYTE *p;
+	DWORD fsect;
+	FRESULT res;
+
+
+	if (clst < 2 || clst >= fs->max_clust) {	/* Check cluster address range */
+		res = FR_INT_ERR;
+
+	} else {
+		fsect = fs->fatbase;
+		switch (fs->fs_type) {
+		case FS_FAT12 :
+			bc = (WORD)clst * 3 / 2;
+			res = move_window(fs, fsect + (bc / SS(fs)));
+			if (res != FR_OK) break;
+			p = &fs->win[bc & (SS(fs) - 1)];
+			*p = (clst & 1) ? ((*p & 0x0F) | ((BYTE)val << 4)) : (BYTE)val;
+			bc++;
+			fs->wflag = 1;
+			res = move_window(fs, fsect + (bc / SS(fs)));
+			if (res != FR_OK) break;
+			p = &fs->win[bc & (SS(fs) - 1)];
+			*p = (clst & 1) ? (BYTE)(val >> 4) : ((*p & 0xF0) | ((BYTE)(val >> 8) & 0x0F));
+			break;
+
+		case FS_FAT16 :
+			res = move_window(fs, fsect + (clst / (SS(fs) / 2)));
+			if (res != FR_OK) break;
+			ST_WORD(&fs->win[((WORD)clst * 2) & (SS(fs) - 1)], (WORD)val);
+			break;
+
+		case FS_FAT32 :
+			res = move_window(fs, fsect + (clst / (SS(fs) / 4)));
+			if (res != FR_OK) break;
+			ST_DWORD(&fs->win[((WORD)clst * 4) & (SS(fs) - 1)], val);
+			break;
+
+		default :
+			res = FR_INT_ERR;
+		}
+		fs->wflag = 1;
+	}
+
+	return res;
+}
+#endif /* !_FS_READONLY */
+
+
+
+
+/*-----------------------------------------------------------------------*/
+/* Remove a cluster chain                                                */
+/*-----------------------------------------------------------------------*/
+#if !_FS_READONLY
+static
+FRESULT remove_chain (
+	FATFS *fs,			/* File system object */
+	DWORD clst			/* Cluster# to remove chain from */
+)
+{
+	FRESULT res;
+	DWORD nxt;
+
+
+	if (clst < 2 || clst >= fs->max_clust) {	/* Check cluster address range */
+		res = FR_INT_ERR;
+
+	} else {
+		res = FR_OK;
+		while (clst < fs->max_clust) {			/* Not a last link? */
+			nxt = get_cluster(fs, clst);		/* Get cluster status */
+			if (nxt == 0) break;				/* Empty cluster? */
+			if (nxt == 1) { res = FR_INT_ERR; break; }	/* Internal error? */
+			if (nxt == 0xFFFFFFFF) { res = FR_DISK_ERR; break; }	/* Disk error? */
+			res = put_cluster(fs, clst, 0);		/* Mark the cluster "empty" */
+			if (res != FR_OK) break;
+			if (fs->free_clust != 0xFFFFFFFF) {	/* Update FSInfo */
+				fs->free_clust++;
+				fs->fsi_flag = 1;
+			}
+			clst = nxt;	/* Next cluster */
+		}
+	}
+
+	return res;
+}
+#endif
+
+
+
+
+/*-----------------------------------------------------------------------*/
+/* Stretch or create a cluster chain                                     */
+/*-----------------------------------------------------------------------*/
+#if !_FS_READONLY
+static
+DWORD create_chain (	/* 0:No free cluster, 1:Internal error, 0xFFFFFFFF:Disk error, >=2:New cluster# */
+	FATFS *fs,			/* File system object */
+	DWORD clst			/* Cluster# to stretch. 0 means create a new chain. */
+)
+{
+	DWORD cs, ncl, scl, mcl;
+
+
+	mcl = fs->max_clust;
+	if (clst == 0) {		/* Create new chain */
+		scl = fs->last_clust;			/* Get suggested start point */
+		if (scl == 0 || scl >= mcl) scl = 1;
+	}
+	else {					/* Stretch existing chain */
+		cs = get_cluster(fs, clst);		/* Check the cluster status */
+		if (cs < 2) return 1;			/* It is an invalid cluster */
+		if (cs < mcl) return cs;		/* It is already followed by next cluster */
+		scl = clst;
+	}
+
+	ncl = scl;				/* Start cluster */
+	for (;;) {
+		ncl++;							/* Next cluster */
+		if (ncl >= mcl) {				/* Wrap around */
+			ncl = 2;
+			if (ncl > scl) return 0;	/* No free custer */
+		}
+		cs = get_cluster(fs, ncl);		/* Get the cluster status */
+		if (cs == 0) break;				/* Found a free cluster */
+		if (cs == 0xFFFFFFFF || cs == 1)/* An error occured */
+			return cs;
+		if (ncl == scl) return 0;		/* No free custer */
+	}
+
+	if (put_cluster(fs, ncl, 0x0FFFFFFF))	/* Mark the new cluster "in use" */
+		return 0xFFFFFFFF;
+	if (clst != 0) {						/* Link it to previous one if needed */
+		if (put_cluster(fs, clst, ncl))
+			return 0xFFFFFFFF;
+	}
+
+	fs->last_clust = ncl;				/* Update FSINFO */
+	if (fs->free_clust != 0xFFFFFFFF) {
+		fs->free_clust--;
+		fs->fsi_flag = 1;
+	}
+
+	return ncl;		/* Return new cluster number */
+}
+#endif /* !_FS_READONLY */
+
+
+
+
+/*-----------------------------------------------------------------------*/
+/* Get sector# from cluster#                                             */
+/*-----------------------------------------------------------------------*/
+
+static
+DWORD clust2sect (	/* !=0: sector number, 0: failed - invalid cluster# */
+	FATFS *fs,		/* File system object */
+	DWORD clst		/* Cluster# to be converted */
+)
+{
+	clst -= 2;
+	if (clst >= (fs->max_clust - 2)) return 0;		/* Invalid cluster# */
+	return clst * fs->csize + fs->database;
+}
+
+
+
+
+/*-----------------------------------------------------------------------*/
+/* Seek directory index                                                  */
+/*-----------------------------------------------------------------------*/
+
+static
+FRESULT dir_seek (
+	DIR *dj,		/* Pointer to directory object */
+	WORD idx		/* Directory index number */
+)
+{
+	DWORD clst;
+	WORD ic;
+
+
+	dj->index = idx;
+	clst = dj->sclust;
+	if (clst == 1 || clst >= dj->fs->max_clust)	/* Check start cluster range */
+		return FR_INT_ERR;
+
+	if (clst == 0) {	/* Static table */
+		if (idx >= dj->fs->n_rootdir)		/* Index is out of range */
+			return FR_INT_ERR;
+		dj->sect = dj->fs->dirbase + idx / (SS(dj->fs) / 32);
+	}
+	else {				/* Dynamic table */
+		ic = SS(dj->fs) / 32 * dj->fs->csize;	/* Indexes per cluster */
+		while (idx >= ic) {	/* Follow cluster chain */
+			clst = get_cluster(dj->fs, clst);			/* Get next cluster */
+			if (clst == 0xFFFFFFFF) return FR_DISK_ERR;	/* Disk error */
+			if (clst < 2 || clst >= dj->fs->max_clust)	/* Reached to end of table or int error */
+				return FR_INT_ERR;
+			idx -= ic;
+		}
+		dj->clust = clst;
+		dj->sect = clust2sect(dj->fs, clst) + idx / (SS(dj->fs) / 32);
+	}
+	dj->dir = dj->fs->win + (idx % (SS(dj->fs) / 32)) * 32;
+
+	return FR_OK;	/* Seek succeeded */
+}
+
+
+
+
+/*-----------------------------------------------------------------------*/
+/* Move directory index next                                             */
+/*-----------------------------------------------------------------------*/
+
+static
+FRESULT dir_next (	/* FR_OK:Succeeded, FR_NO_FILE:End of table, FR_DENIED:EOT and could not streach */
+	DIR *dj,		/* Pointer to directory object */
+	BOOL streach	/* FALSE: Do not streach table, TRUE: Streach table if needed */
+)
+{
+	DWORD clst;
+	WORD i;
+
+
+	i = dj->index + 1;
+	if (!i || !dj->sect)	/* Report EOT when index has reached 65535 */
+		return FR_NO_FILE;
+
+	if (!(i % (SS(dj->fs) / 32))) {	/* Sector changed? */
+		dj->sect++;					/* Next sector */
+
+		if (dj->sclust == 0) {	/* Static table */
+			if (i >= dj->fs->n_rootdir)	/* Report EOT when end of table */
+				return FR_NO_FILE;
+		}
+		else {					/* Dynamic table */
+			if (((i / (SS(dj->fs) / 32)) & (dj->fs->csize - 1)) == 0) {	/* Cluster changed? */
+				clst = get_cluster(dj->fs, dj->clust);			/* Get next cluster */
+				if (clst <= 1) return FR_INT_ERR;
+				if (clst == 0xFFFFFFFF) return FR_DISK_ERR;
+				if (clst >= dj->fs->max_clust) {				/* When it reached end of dinamic table */
+#if !_FS_READONLY
+					BYTE c;
+					if (!streach) return FR_NO_FILE;			/* When do not streach, report EOT */
+					clst = create_chain(dj->fs, dj->clust);		/* Streach cluster chain */
+					if (clst == 0) return FR_DENIED;			/* No free cluster */
+					if (clst == 1) return FR_INT_ERR;
+					if (clst == 0xFFFFFFFF) return FR_DISK_ERR;
+					/* Clean-up streached table */
+					if (move_window(dj->fs, 0)) return FR_DISK_ERR;	/* Flush active window */
+					mem_set(dj->fs->win, 0, SS(dj->fs));			/* Clear window buffer */
+					dj->fs->winsect = clust2sect(dj->fs, clst);	/* Cluster start sector */
+					for (c = 0; c < dj->fs->csize; c++) {		/* Fill the new cluster with 0 */
+						dj->fs->wflag = 1;
+						if (move_window(dj->fs, 0)) return FR_DISK_ERR;
+						dj->fs->winsect++;
+					}
+					dj->fs->winsect -= c;						/* Rewind window address */
+#else
+					return FR_NO_FILE;			/* Report EOT */
+#endif
+				}
+				dj->clust = clst;				/* Initialize data for new cluster */
+				dj->sect = clust2sect(dj->fs, clst);
+			}
+		}
+	}
+
+	dj->index = i;
+	dj->dir = dj->fs->win + (i % (SS(dj->fs) / 32)) * 32;
+
+	return FR_OK;
+}
+
+
+
+
+/*-----------------------------------------------------------------------*/
+/* Test/Pick/Fit an LFN segment from/to directory entry                  */
+/*-----------------------------------------------------------------------*/
+#if _USE_LFN
+static
+const BYTE LfnOfs[] = {1,3,5,7,9,14,16,18,20,22,24,28,30};	/* Offset of LFN chars in the directory entry */
+
+
+static
+BOOL test_lfn (			/* TRUE:Matched, FALSE:Not matched */
+	WCHAR *lfnbuf,		/* Pointer to the LFN to be compared */
+	BYTE *dir			/* Pointer to the directory entry containing a part of LFN */
+)
+{
+	int i, s;
+	WCHAR wc1, wc2;
+
+
+	i = ((dir[LDIR_Ord] & 0xBF) - 1) * 13;	/* Offset in the LFN buffer */
+	s = 0;
+	do {
+		if (i >= _MAX_LFN) return FALSE;	/* Out of buffer range? */
+		wc1 = LD_WORD(dir+LfnOfs[s]);		/* Get both characters to compare */
+		wc2 = lfnbuf[i++];
+		if (IsLower(wc1)) wc1 -= 0x20;		/* Compare it (ignore case) */
+		if (IsLower(wc2)) wc2 -= 0x20;
+		if (wc1 != wc2) return FALSE;
+	} while (++s < 13 && wc1);				/* Repeat until last char or a NUL char is processed */
+
+	return TRUE;							/* The LFN entry matched */
+}
+
+
+
+static
+BOOL pick_lfn (			/* TRUE:Succeeded, FALSE:Buffer overflow */
+	WCHAR *lfnbuf,		/* Pointer to the Unicode-LFN buffer */
+	BYTE *dir			/* Pointer to the directory entry */
+)
+{
+	int i, s;
+	WCHAR wchr;
+
+
+	i = ((dir[LDIR_Ord] & 0xBF) - 1) * 13;	/* Offset in the LFN buffer */
+	s = 0;
+	do {
+		wchr = LD_WORD(dir+LfnOfs[s]);		/* Get an LFN char */
+		if (!wchr) break;					/* End of LFN? */
+		if (i >= _MAX_LFN) return FALSE;	/* Buffer overflow */
+		lfnbuf[i++] = wchr;					/* Store it */
+	} while (++s < 13);						/* Repeat until last char is copied */
+	if (dir[LDIR_Ord] & 0x40) lfnbuf[i] = 0;	/* Put terminator if last LFN entry */
+
+	return TRUE;
+}
+
+
+#if !_FS_READONLY
+static
+void fit_lfn (
+	const WCHAR *lfnbuf,	/* Pointer to the LFN buffer */
+	BYTE *dir,				/* Pointer to the directory entry */
+	BYTE ord,				/* LFN order (1-20) */
+	BYTE sum				/* SFN sum */
+)
+{
+	int i, s;
+	WCHAR wchr;
+
+
+	dir[LDIR_Chksum] = sum;			/* Set check sum */
+	dir[LDIR_Attr] = AM_LFN;		/* Set attribute. LFN entry */
+	dir[LDIR_Type] = 0;
+	ST_WORD(dir+LDIR_FstClusLO, 0);
+
+	i = (ord - 1) * 13;				/* Offset in the LFN buffer */
+	s = wchr = 0;
+	do {
+		if (wchr != 0xFFFF) wchr = lfnbuf[i++];	/* Get an effective char */
+		ST_WORD(dir+LfnOfs[s], wchr);	/* Put it */
+		if (!wchr) wchr = 0xFFFF;	/* Padding chars following last char */
+	} while (++s < 13);
+	if (wchr == 0xFFFF || !lfnbuf[i]) ord |= 0x40;/* Bottom LFN part is the start of LFN sequence */
+	dir[LDIR_Ord] = ord;			/* Set the LFN order */
+}
+
+#endif
+#endif
+
+
+
+/*-----------------------------------------------------------------------*/
+/* Create numbered name                                                  */
+/*-----------------------------------------------------------------------*/
+#if _USE_LFN
+void gen_numname (
+	BYTE *dst,			/* Pointer to genartated SFN */
+	const BYTE *src,	/* Pointer to source SFN to be modified */
+	const WCHAR *lfn,	/* Pointer to LFN */
+	WORD num			/* Sequense number */
+)
+{
+	char ns[8];
+	int i, j;
+
+
+	mem_cpy(dst, src, 11);
+
+	if (num > 5) {	/* On many collisions, generate a hash number instead of sequencial number */
+		do num = (num >> 1) + (num << 15) + (WORD)*lfn++; while (*lfn);
+	}
+
+	/* itoa */
+	i = 7;
+	do {
+		ns[i--] = (num % 10) + '0';
+		num /= 10;
+	} while (num);
+	ns[i] = '~';
+
+	/* Append the number */
+	for (j = 0; j < i && dst[j] != ' '; j++) {
+		if (IsDBCS1(dst[j])) {
+			if (j == i - 1) break;
+			j++;
+		}
+	}
+	do {
+		dst[j++] = (i < 8) ? ns[i++] : ' ';
+	} while (j < 8);
+}
+#endif
+
+
+
+
+/*-----------------------------------------------------------------------*/
+/* Calculate sum of an SFN                                               */
+/*-----------------------------------------------------------------------*/
+#if _USE_LFN
+static
+BYTE sum_sfn (
+	const BYTE *dir		/* Ptr to directory entry */
+)
+{
+	BYTE sum = 0;
+	int n = 11;
+
+	do sum = (sum >> 1) + (sum << 7) + *dir++; while (--n);
+	return sum;
+}
+#endif
+
+
+
+
+/*-----------------------------------------------------------------------*/
+/* Find an object in the directory                                       */
+/*-----------------------------------------------------------------------*/
+
+static
+FRESULT dir_find (
+	DIR *dj			/* Pointer to the directory object linked to the file name */
+)
+{
+	FRESULT res;
+	BYTE a, c, lfen, ord, sum, *dir;
+
+
+	res = dir_seek(dj, 0);			/* Rewind directory object */
+	if (res != FR_OK) return res;
+
+	ord = sum = 0xFF; lfen = *(dj->fn+11) & 1;
+	do {
+		res = move_window(dj->fs, dj->sect);
+		if (res != FR_OK) break;
+		dir = dj->dir;					/* Ptr to the directory entry of current index */
+		c = dir[DIR_Name];
+		if (c == 0) { res = FR_NO_FILE; break; }	/* Reached to end of table */
+		a = dir[DIR_Attr] & AM_MASK;
+#if _USE_LFN	/* LFN configuration */
+		if (c == 0xE5 || c == '.' || ((a & AM_VOL) && a != AM_LFN)) {	/* An entry without valid data */
+			ord = 0xFF;
+		} else {
+			if (a == AM_LFN) {			/* An LFN entry is found */
+				if (dj->lfn) {
+					if (c & 0x40) {		/* Is it start of LFN sequence? */
+						sum = dir[LDIR_Chksum];
+						c &= 0xBF; ord = c;		/* LFN start order */
+						dj->lfn_idx = dj->index;
+					}
+					/* Check LFN validity. Compare LFN if it is out of 8.3 format */
+					ord = (c == ord && sum == dir[LDIR_Chksum] && (!lfen || test_lfn(dj->lfn, dir))) ? ord - 1 : 0xFF;
+				}
+			} else {					/* An SFN entry is found */
+				if (ord || sum != sum_sfn(dir)) {	/* Did not LFN match? */
+					dj->lfn_idx = 0xFFFF;
+					ord = 0xFF;
+				}
+				if (lfen) {				/* Match LFN if it is out of 8.3 format */
+					if (ord == 0) break;
+				} else {				/* Match SFN if LFN is in 8.3 format */
+					if (!mem_cmp(dir, dj->fn, 11)) break;
+				}
+			}
+		}
+#else	/* Non LFN configuration */
+		if (c != 0xE5 && c != '.' && !(a & AM_VOL) && !mem_cmp(dir, dj->fn, 11)) /* Is it a valid entry? */
+			break;
+#endif
+		res = dir_next(dj, FALSE);				/* Next entry */
+	} while (res == FR_OK);
+
+	return res;
+}
+
+
+
+
+/*-----------------------------------------------------------------------*/
+/* Read an object from the directory                                     */
+/*-----------------------------------------------------------------------*/
+#if _FS_MINIMIZE <= 2
+static
+FRESULT dir_read (
+	DIR *dj			/* Pointer to the directory object to store read object name */
+)
+{
+	FRESULT res;
+	BYTE a, c, ord, sum, *dir;
+
+
+	ord = sum = 0xFF;
+	res = FR_NO_FILE;
+	while (dj->sect) {
+		res = move_window(dj->fs, dj->sect);
+		if (res != FR_OK) break;
+		dir = dj->dir;					/* Ptr to the directory entry of current index */
+		c = dir[DIR_Name];
+		if (c == 0) { res = FR_NO_FILE; break; }	/* Reached to end of table */
+		a = dir[DIR_Attr] & AM_MASK;
+#if _USE_LFN	/* LFN configuration */
+		if (c == 0xE5 || c == '.' || ((a & AM_VOL) && a != AM_LFN)) {	/* An entry without valid data */
+			ord = 0xFF;
+		} else {
+			if (a == AM_LFN) {			/* An LFN entry is found */
+				if (c & 0x40) {			/* Is it start of LFN sequence? */
+					sum = dir[LDIR_Chksum];
+					c &= 0xBF; ord = c;
+					dj->lfn_idx = dj->index;
+				}
+				/* Check LFN validity and capture it */
+				ord = (c == ord && sum == dir[LDIR_Chksum] && pick_lfn(dj->lfn, dir)) ? ord - 1 : 0xFF;
+			} else {					/* An SFN entry is found */
+				if (ord || sum != sum_sfn(dir))	/* Is there a valid LFN entry? */
+					dj->lfn_idx = 0xFFFF;		/* No LFN. */
+				break;
+			}
+		}
+#else	/* Non LFN configuration */
+		if (c != 0xE5 && c != '.' && !(a & AM_VOL))	/* Is it a valid entry? */
+			break;
+#endif
+		res = dir_next(dj, FALSE);				/* Next entry */
+		if (res != FR_OK) break;
+	}
+
+	if (res != FR_OK) dj->sect = 0;
+
+	return res;
+}
+#endif
+
+
+
+/*-----------------------------------------------------------------------*/
+/* Register an object to the directory                                   */
+/*-----------------------------------------------------------------------*/
+#if !_FS_READONLY
+static
+FRESULT dir_register (	/* FR_OK:Successful, FR_DENIED:No free entry or too many SFN collision, FR_DISK_ERR:Disk error */
+	DIR *dj				/* Target directory with object name to be created */
+)
+{
+	FRESULT res;
+	BYTE c, *dir;
+
+#if _USE_LFN	/* LFN configuration */
+	WORD n, ne, is;
+	BYTE sn[12], *fn, sum;
+	WCHAR *lfn;
+
+	fn = dj->fn; lfn = dj->lfn;
+	mem_cpy(sn, fn, 12);
+	if (sn[11] & 1) {		/* When LFN is out of 8.3 format, generate a numbered name */
+		fn[11] = 0; dj->lfn = NULL;			/* Find only SFN */
+		for (n = 1; n < 100; n++) {
+			gen_numname(fn, sn, lfn, n);	/* Generate a numbered name */
+			res = dir_find(dj);				/* Check if the name collides with existing SFN */
+			if (res != FR_OK) break;
+		}
+		if (n == 100) return FR_DENIED;		/* Abort if too many collisions */
+		if (res != FR_NO_FILE) return res;	/* Abort if the result is other than 'not collided' */
+		fn[11] = sn[11]; dj->lfn = lfn;
+	}
+	if (sn[11] & 2) {		/* When eliminate LFN, reserve only an SFN entry. */
+		ne = 1;
+	} else {				/* Otherwise reserve an SFN + LFN entries. */
+		for (ne = 0; lfn[ne]; ne++) ;
+		ne = (ne + 25) / 13;
+	}
+
+	/* Reserve contiguous entries */
+	res = dir_seek(dj, 0);
+	if (res != FR_OK) return res;
+	n = is = 0;
+	do {
+		res = move_window(dj->fs, dj->sect);
+		if (res != FR_OK) break;
+		c = *dj->dir;	/* Check the entry status */
+		if (c == 0xE5 || c == 0) {	/* Is it a blank entry? */
+			if (n == 0) is = dj->index;	/* First index of the contigulus entry */
+			if (++n == ne) break;	/* A contiguous entry that requiered count is found */
+		} else {
+			n = 0;					/* Not a blank entry. Restart to search */
+		}
+		res = dir_next(dj, TRUE);	/* Next entry with table streach */
+	} while (res == FR_OK);
+
+	if (res == FR_OK && ne > 1) {	/* Initialize LFN entry if needed */
+		res = dir_seek(dj, is);
+		if (res == FR_OK) {
+			sum = sum_sfn(dj->fn);	/* Sum of the SFN tied to the LFN */
+			ne--;
+			do {					/* Store LFN entries in bottom first */
+				res = move_window(dj->fs, dj->sect);
+				if (res != FR_OK) break;
+				fit_lfn(dj->lfn, dj->dir, (BYTE)ne, sum);
+				dj->fs->wflag = 1;
+				res = dir_next(dj, FALSE);	/* Next entry */
+			} while (res == FR_OK && --ne);
+		}
+	}
+
+#else	/* Non LFN configuration */
+	res = dir_seek(dj, 0);
+	if (res == FR_OK) {
+		do {	/* Find a blank entry for the SFN */
+			res = move_window(dj->fs, dj->sect);
+			if (res != FR_OK) break;
+			c = *dj->dir;
+			if (c == 0xE5 || c == 0) break;	/* Is it a blank entry? */
+			res = dir_next(dj, TRUE);		/* Next entry with table streach */
+		} while (res == FR_OK);
+	}
+#endif
+
+	if (res == FR_OK) {		/* Initialize the SFN entry */
+		res = move_window(dj->fs, dj->sect);
+		if (res == FR_OK) {
+			dir = dj->dir;
+			mem_set(dir, 0, 32);			/* Clean the entry */
+			mem_cpy(dir, dj->fn, 11);	/* Put SFN */
+			dir[DIR_NTres] = *(dj->fn+11) & 0x18;	/* Put NT flag */
+			dj->fs->wflag = 1;
+		}
+	}
+
+	return res;
+}
+#endif /* !_FS_READONLY */
+
+
+
+
+/*-----------------------------------------------------------------------*/
+/* Remove an object from the directory                                   */
+/*-----------------------------------------------------------------------*/
+#if !_FS_READONLY && !_FS_MINIMIZE
+static
+FRESULT dir_remove (	/* FR_OK: Successful, FR_DISK_ERR: A disk error */
+	DIR *dj				/* Directory object pointing the entry to be removed */
+)
+{
+	FRESULT res;
+
+#if _USE_LFN	/* LFN configuration */
+	WORD i;
+
+	i = dj->index;	/* SFN index */
+	res = dir_seek(dj, (WORD)((dj->lfn_idx == 0xFFFF) ? i : dj->lfn_idx));	/* Goto the SFN or top of the LFN entries */
+	if (res == FR_OK) {
+		do {
+			res = move_window(dj->fs, dj->sect);
+			if (res != FR_OK) break;
+			*dj->dir = 0xE5;				/* Mark the entry "deleted" */
+			dj->fs->wflag = 1;
+			if (dj->index >= i) break;		/* When SFN is deleted, all entries of the object is deleted. */
+			res = dir_next(dj, FALSE);		/* Next entry */
+		} while (res == FR_OK);
+		if (res == FR_NO_FILE) res = FR_INT_ERR;
+	}
+
+#else			/* Non LFN configuration */
+	res = dir_seek(dj, dj->index);
+	if (res == FR_OK) {
+		res = move_window(dj->fs, dj->sect);
+		if (res == FR_OK) {
+			*dj->dir = 0xE5;				/* Mark the entry "deleted" */
+			dj->fs->wflag = 1;
+		}
+	}
+#endif
+
+	return res;
+}
+#endif /* !_FS_READONLY */
+
+
+
+
+/*-----------------------------------------------------------------------*/
+/* Pick a segment and create the object name in directory form           */
+/*-----------------------------------------------------------------------*/
+
+static
+FRESULT create_name (
+	DIR *dj,			/* Pointer to the directory object */
+	const char **path	/* Pointer to pointer to the segment in the path string */
+)
+{
+#if _USE_LFN
+	BYTE c, b, cf, *sfn;
+	WCHAR w, *lfn;
+	int i, ni, si, di;
+	const char *p;
+
+	/* Create LFN in Unicode */
+	si = di = 0;
+	p = *path;
+	lfn = dj->lfn;
+	for (;;) {
+		w = (BYTE)p[si++];				/* Get a character */
+		if (w < ' ' || w == '/' || w == '\\') break;	/* Break on end of segment */
+		if (IsDBCS1(w)) {				/* If it is DBC 1st byte */
+			c = p[si++];				/* Get 2nd byte */
+			if (!IsDBCS2(c))			/* Reject invalid DBC */
+				return FR_INVALID_NAME;
+			w = (w << 8) + c;
+		} else {
+			if (chk_chr("\"*:<>\?|\x7F", w))	/* Reject unallowable chars for LFN */
+				return FR_INVALID_NAME;
+		}
+		w = ff_convert(w, 1);			/* Convert OEM to Unicode, store it */
+		if (!w || di >= _MAX_LFN)		/* Reject invalid code or too long name */
+			return FR_INVALID_NAME;
+		lfn[di++] = w;
+	}
+	*path = &p[si];						/* Rerurn pointer to the next segment */
+	cf = (w < ' ') ? 4 : 0;				/* Set last segment flag if end of path */
+
+	while (di) {						/* Strip trailing spaces and dots */
+		w = lfn[di - 1];
+		if (w != ' ' && w != '.') break;
+		di--;
+	}
+	if (!di) return FR_INVALID_NAME;	/* Reject null string */
+
+	lfn[di] = 0;						/* LFN is created */
+
+	/* Create SFN in directory form */
+	sfn = dj->fn;
+	mem_set(sfn, ' ', 11);
+	for (si = 0; lfn[si] == ' ' || lfn[si] == '.'; si++) ;	/* Strip leading spaces and dots */
+	if (si) cf |= 1;
+	while (di && lfn[di - 1] != '.') di--;	/* Find extension (di<=si: no extension) */
+
+	b = i = 0; ni = 8;
+	for (;;) {
+		w = lfn[si++];					/* Get an LFN char */
+		if (w == 0) break;				/* Break when enf of the LFN */
+		if (w == ' ' || (w == '.' && si != di)) {	/* Remove spaces and dots */
+			cf |= 1; continue;
+		}
+		if (i >= ni || si == di) {		/* Here is extension or end of SFN */
+			if (ni == 11) {				/* Extension is longer than 3 bytes */
+				cf |= 1; break;
+			}
+			if (si != di) cf |= 1;		/* File name is longer than 8 bytes */
+			if (si > di) break;			/* No extension */
+			si = di; i = 8; ni = 11;	/* Enter extension section */
+			b <<= 2; continue;
+		}
+		w = ff_convert(w, 0);			/* Unicode -> OEM code */
+		if (w >= 0x80) cf |= 0x20;		/* If there is any extended char, force create an LFN */
+		if (w >= 0x100) {				/* Double byte char */
+			if (i >= ni - 1) {
+				cf |= 1; i = ni; continue;
+			}
+			sfn[i++] = (BYTE)(w >> 8);
+		} else {						/* Single byte char */
+			if (chk_chr("+,;[=]", w)) {	/* Replace unallowable chars for SFN */
+				w = '_'; cf |= 1;
+			} else {
+				if (IsUpper(w)) {		/* Large capital */
+					b |= 2;
+				} else {
+					if (IsLower(w)) {	/* Small capital */
+						b |= 1; w -= 0x20;
+					}
+				}
+			}
+		}
+		sfn[i++] = (BYTE)w;
+	}
+	if (sfn[0] == 0xE5) sfn[0] = 0x05;	/* When first char collides with 0xE5, replace it with 0x05 */
+
+	if (ni == 8) b <<= 2;
+	if ((cf & 0x21) == 0) {	/* When LFN is in 8.3 format without extended char, NT flags are created */
+		if ((b & 0x03) == 0x01) cf |= 0x10;	/* NT flag (Extension has only small capital) */
+		if ((b & 0x0C) == 0x04) cf |= 0x08;	/* NT flag (Filename has only small capital) */
+		if ((b & 0x0C) != 0x0C && (b & 0x03) != 0x03) cf |= 2;	/* Eliminate LFN when non composite capitals */
+	}
+
+	sfn[11] = cf;		/* SFN is created */
+
+#else
+	BYTE c, d, b, *sfn;
+	int ni, si, i;
+	const char *p;
+
+	/* Create file name in directory form */
+	sfn = dj->fn;
+	mem_set(sfn, ' ', 11);
+	si = i = b = 0; ni = 8;
+	p = *path;
+	for (;;) {
+		c = p[si++];
+		if (c < ' ' || c == '/' || c == '\\') break;	/* Break on end of segment */
+		if (c == '.' || i >= ni) {
+			if (ni != 8 || c != '.') return FR_INVALID_NAME;
+			i = 8; ni = 11;
+			b <<= 2; continue;
+		}
+		if (c >= 0x80) b |= 3;			/* If there is any extended char, eliminate NT flag */
+		if (IsDBCS1(c)) {				/* If it is DBC 1st byte */
+			d = p[si++];				/* Get 2nd byte */
+			if (!IsDBCS2(d) || i >= ni - 1)	/* Reject invalid DBC */
+				return FR_INVALID_NAME;
+			sfn[i++] = c;
+			sfn[i++] = d;
+		} else {
+			if (chk_chr(" +,;[=]\"*:<>\?|\x7F", c))	/* Reject unallowable chrs for SFN */
+				return FR_INVALID_NAME;
+			if (IsUpper(c)) {
+				b |= 2;
+			} else {
+				if (IsLower(c)) {
+					b |= 1; c -= 0x20;
+				}
+			}
+			sfn[i++] = c;
+		}
+	}
+	*path = &p[si];						/* Rerurn pointer to the next segment */
+	c = (c < ' ') ? 4 : 0;				/* Set last segment flag if end of path */
+
+	if (!i) return FR_INVALID_NAME;		/* Reject null string */
+	if (sfn[0] == 0xE5) sfn[0] = 0x05;	/* When first char collides with 0xE5, replace it with 0x05 */
+
+	if (ni == 8) b <<= 2;
+	if ((b & 0x03) == 0x01) c |= 0x10;	/* NT flag (Extension has only small capital) */
+	if ((b & 0x0C) == 0x04) c |= 0x08;	/* NT flag (Filename has only small capital) */
+
+	sfn[11] = c;		/* Store NT flag, File name is created */
+#endif
+
+	return FR_OK;
+}
+
+
+
+
+/*-----------------------------------------------------------------------*/
+/* Get file information from directory entry                             */
+/*-----------------------------------------------------------------------*/
+#if _FS_MINIMIZE <= 1
+static
+void get_fileinfo (		/* No return code */
+	DIR *dj,			/* Pointer to the directory object */
+	FILINFO *fno	 	/* Pointer to store the file information */
+)
+{
+	int i;
+	BYTE c, nt, *dir;
+	char *p;
+
+
+	p = fno->fname;
+	if (dj->sect) {
+		dir = dj->dir;
+		nt = dir[DIR_NTres];		/* NT flag */
+		for (i = 0; i < 8; i++) {	/* Copy file name body */
+			c = dir[i];
+			if (c == ' ') break;
+			if (c == 0x05) c = 0xE5;
+			if ((nt & 0x08) && IsUpper(c)) c += 0x20;
+			*p++ = c;
+		}
+		if (dir[8] != ' ') {		/* Copy file name extension */
+			*p++ = '.';
+			for (i = 8; i < 11; i++) {
+				c = dir[i];
+				if (c == ' ') break;
+				if ((nt & 0x10) && IsUpper(c)) c += 0x20;
+				*p++ = c;
+			}
+		}
+		fno->fattrib = dir[DIR_Attr];				/* Attribute */
+		fno->fsize = LD_DWORD(dir+DIR_FileSize);	/* Size */
+		fno->fdate = LD_WORD(dir+DIR_WrtDate);		/* Date */
+		fno->ftime = LD_WORD(dir+DIR_WrtTime);		/* Time */
+	}
+	*p = 0;
+
+#if _USE_LFN
+	p = fno->lfname;
+	if (p) {
+		WCHAR wchr, *lfn;
+
+		i = 0;
+		if (dj->sect && dj->lfn_idx != 0xFFFF) {/* Get LFN if available */
+			lfn = dj->lfn;
+			while ((wchr = *lfn++) != 0) {		/* Get an LFN char */
+				wchr = ff_convert(wchr, 0);		/* Unicode -> OEM code */
+				if (!wchr) { i = 0; break; }	/* Conversion error, no LFN */
+				if (_DF1S && wchr >= 0x100)		/* Put 1st byte if it is a DBC */
+					p[i++] = (char)(wchr >> 8);
+				p[i++] = (char)wchr;
+				if (i >= fno->lfsize) { i = 0; break; }	/* Buffer overrun, no LFN */
+			}
+		}
+		p[i] = 0;	/* Terminator */
+	}
+#endif
+}
+#endif /* _FS_MINIMIZE <= 1 */
+
+
+
+
+/*-----------------------------------------------------------------------*/
+/* Follow a file path                                                    */
+/*-----------------------------------------------------------------------*/
+
+static
+FRESULT follow_path (	/* FR_OK(0): successful, !=0: error code */
+	DIR *dj,			/* Directory object to return last directory and found object */
+	const char *path	/* Full-path string to find a file or directory */
+)
+{
+	FRESULT res;
+	BYTE *dir, last;
+
+
+	if (*path == '/' || *path == '\\' ) path++;	/* Strip heading separator */
+
+	dj->sclust =						/* Set start directory (root dir) */
+		(dj->fs->fs_type == FS_FAT32) ? dj->fs->dirbase : 0;
+
+	if ((BYTE)*path < ' ') {			/* Null path means the root directory */
+		res = dir_seek(dj, 0);
+		dj->dir = NULL;
+
+	} else {							/* Follow path */
+		for (;;) {
+			res = create_name(dj, &path);	/* Get a segment */
+			if (res != FR_OK) break;
+			res = dir_find(dj);				/* Find it */
+			last = *(dj->fn+11) & 4;
+			if (res != FR_OK) {				/* Could not find the object */
+				if (res == FR_NO_FILE && !last)
+					res = FR_NO_PATH;
+				break;
+			}
+			if (last) break;				/* Last segment match. Function completed. */
+			dir = dj->dir;					/* There is next segment. Follow the sub directory */
+			if (!(dir[DIR_Attr] & AM_DIR)) { /* Cannot follow because it is a file */
+				res = FR_NO_PATH; break;
+			}
+			dj->sclust = ((DWORD)LD_WORD(dir+DIR_FstClusHI) << 16) | LD_WORD(dir+DIR_FstClusLO);
+		}
+	}
+
+	return res;
+}
+
+
+
+
+/*-----------------------------------------------------------------------*/
+/* Load boot record and check if it is an FAT boot record                */
+/*-----------------------------------------------------------------------*/
+
+static
+BYTE check_fs (	/* 0:The FAT boot record, 1:Valid boot record but not an FAT, 2:Not a boot record, 3:Error */
+	FATFS *fs,	/* File system object */
+	DWORD sect	/* Sector# (lba) to check if it is an FAT boot record or not */
+)
+{
+	if (disk_read(fs->drive, fs->win, sect, 1) != RES_OK)	/* Load boot record */
+		return 3;
+	if (LD_WORD(&fs->win[BS_55AA]) != 0xAA55)				/* Check record signature (always placed at offset 510 even if the sector size is >512) */
+		return 2;
+
+	if (!mem_cmp(&fs->win[BS_FilSysType], "FAT", 3))		/* Check FAT signature */
+		return 0;
+	if (!mem_cmp(&fs->win[BS_FilSysType32], "FAT32", 5) && !(fs->win[BPB_ExtFlags] & 0x80))
+		return 0;
+
+	return 1;
+}
+
+
+
+
+/*-----------------------------------------------------------------------*/
+/* Make sure that the file system is valid                               */
+/*-----------------------------------------------------------------------*/
+
+static
+FRESULT auto_mount (	/* FR_OK(0): successful, !=0: any error occured */
+	const char **path,	/* Pointer to pointer to the path name (drive number) */
+	FATFS **rfs,		/* Pointer to pointer to the found file system object */
+	BYTE chk_wp			/* !=0: Check media write protection for write access */
+)
+{
+	FRESULT res;
+	BYTE vol, fmt, *tbl;
+	DSTATUS stat;
+	DWORD bsect, fsize, tsect, mclst;
+	const char *p = *path;
+	FATFS *fs;
+
+
+	/* Get logical drive number from the path name */
+	vol = p[0] - '0';			/* Is there a drive number? */
+	if (vol <= 9 && p[1] == ':') {
+		p += 2;					/* Found a drive number, get and strip it */
+		*path = p;				/* Return pointer to the path name */
+	} else {
+		vol = 0;				/* No drive number is given, use drive number 0 as default */
+	}
+
+	/* Check if the logical drive number is valid or not */
+	if (vol >= _DRIVES) return FR_INVALID_DRIVE;	/* Is the drive number valid? */
+	*rfs = fs = FatFs[vol];					/* Returen pointer to the corresponding file system object */
+	if (!fs) return FR_NOT_ENABLED;			/* Is the file system object registered? */
+
+	ENTER_FF(fs);				/* Lock file system */
+
+	if (fs->fs_type) {						/* If the logical drive has been mounted */
+		stat = disk_status(fs->drive);
+		if (!(stat & STA_NOINIT)) {			/* and physical drive is kept initialized (has not been changed), */
+#if !_FS_READONLY
+			if (chk_wp && (stat & STA_PROTECT))	/* Check write protection if needed */
+				return FR_WRITE_PROTECTED;
+#endif
+			return FR_OK;					/* The file system object is valid */
+		}
+	}
+
+	/* The logical drive must be re-mounted. Following code attempts to mount the volume */
+
+	fs->fs_type = 0;					/* Clear the file system object */
+	fs->drive = LD2PD(vol);				/* Bind the logical drive and a physical drive */
+	stat = disk_initialize(fs->drive);	/* Initialize low level disk I/O layer */
+	if (stat & STA_NOINIT)				/* Check if the drive is ready */
+		return FR_NOT_READY;
+#if _MAX_SS != 512						/* Get disk sector size if needed */
+	if (disk_ioctl(fs->drive, GET_SECTOR_SIZE, &SS(fs)) != RES_OK || SS(fs) > _MAX_SS)
+		return FR_NO_FILESYSTEM;
+#endif
+#if !_FS_READONLY
+	if (chk_wp && (stat & STA_PROTECT))	/* Check write protection if needed */
+		return FR_WRITE_PROTECTED;
+#endif
+	/* Search FAT partition on the drive */
+	fmt = check_fs(fs, bsect = 0);		/* Check sector 0 as an SFD format */
+	if (fmt == 1) {						/* Not an FAT boot record, it may be patitioned */
+		/* Check a partition listed in top of the partition table */
+		tbl = &fs->win[MBR_Table + LD2PT(vol) * 16];	/* Partition table */
+		if (tbl[4]) {									/* Is the partition existing? */
+			bsect = LD_DWORD(&tbl[8]);					/* Partition offset in LBA */
+			fmt = check_fs(fs, bsect);					/* Check the partition */
+		}
+	}
+	if (fmt == 3) return FR_DISK_ERR;
+	if (fmt || LD_WORD(fs->win+BPB_BytsPerSec) != SS(fs))	/* No valid FAT patition is found */
+		return FR_NO_FILESYSTEM;
+
+	/* Initialize the file system object */
+	fsize = LD_WORD(fs->win+BPB_FATSz16);				/* Number of sectors per FAT */
+	if (!fsize) fsize = LD_DWORD(fs->win+BPB_FATSz32);
+	fs->sects_fat = fsize;
+	fs->n_fats = fs->win[BPB_NumFATs];					/* Number of FAT copies */
+	fsize *= fs->n_fats;								/* (Number of sectors in FAT area) */
+	fs->fatbase = bsect + LD_WORD(fs->win+BPB_RsvdSecCnt); /* FAT start sector (lba) */
+	fs->csize = fs->win[BPB_SecPerClus];				/* Number of sectors per cluster */
+	fs->n_rootdir = LD_WORD(fs->win+BPB_RootEntCnt);	/* Nmuber of root directory entries */
+	tsect = LD_WORD(fs->win+BPB_TotSec16);				/* Number of sectors on the file system */
+	if (!tsect) tsect = LD_DWORD(fs->win+BPB_TotSec32);
+	fs->max_clust = mclst = (tsect						/* Last cluster# + 1 */
+		- LD_WORD(fs->win+BPB_RsvdSecCnt) - fsize - fs->n_rootdir / (SS(fs)/32)
+		) / fs->csize + 2;
+
+	fmt = FS_FAT12;										/* Determine the FAT sub type */
+	if (mclst >= 0xFF7) fmt = FS_FAT16;				/* Number of clusters >= 0xFF5 */
+	if (mclst >= 0xFFF7) fmt = FS_FAT32;			/* Number of clusters >= 0xFFF5 */
+
+	if (fmt == FS_FAT32)
+		fs->dirbase = LD_DWORD(fs->win+BPB_RootClus);	/* Root directory start cluster */
+	else
+		fs->dirbase = fs->fatbase + fsize;				/* Root directory start sector (lba) */
+	fs->database = fs->fatbase + fsize + fs->n_rootdir / (SS(fs)/32);	/* Data start sector (lba) */
+
+#if !_FS_READONLY
+	/* Initialize allocation information */
+	fs->free_clust = 0xFFFFFFFF;
+	fs->wflag = 0;
+	/* Get fsinfo if needed */
+	if (fmt == FS_FAT32) {
+		fs->fsi_sector = bsect + LD_WORD(fs->win+BPB_FSInfo);
+		fs->fsi_flag = 0;
+		if (disk_read(fs->drive, fs->win, fs->fsi_sector, 1) == RES_OK &&
+			LD_WORD(fs->win+BS_55AA) == 0xAA55 &&
+			LD_DWORD(fs->win+FSI_LeadSig) == 0x41615252 &&
+			LD_DWORD(fs->win+FSI_StrucSig) == 0x61417272) {
+			fs->last_clust = LD_DWORD(fs->win+FSI_Nxt_Free);
+			fs->free_clust = LD_DWORD(fs->win+FSI_Free_Count);
+		}
+	}
+#endif
+	fs->winsect = 0;
+	fs->fs_type = fmt;			/* FAT syb-type */
+	fs->id = ++Fsid;			/* File system mount ID */
+	res = FR_OK;
+
+	return res;
+}
+
+
+
+
+/*-----------------------------------------------------------------------*/
+/* Check if the file/dir object is valid or not                          */
+/*-----------------------------------------------------------------------*/
+
+static
+FRESULT validate (	/* FR_OK(0): The object is valid, !=0: Invalid */
+	FATFS *fs,		/* Pointer to the file system object */
+	WORD id			/* Member id of the target object to be checked */
+)
+{
+	if (!fs || !fs->fs_type || fs->id != id)
+		return FR_INVALID_OBJECT;
+
+	ENTER_FF(fs);		/* Lock file system */
+
+	if (disk_status(fs->drive) & STA_NOINIT)
+		return FR_NOT_READY;
+
+	return FR_OK;
+}
+
+
+
+
+/*--------------------------------------------------------------------------
+
+   Public Functions
+
+--------------------------------------------------------------------------*/
+
+
+
+/*-----------------------------------------------------------------------*/
+/* Mount/Unmount a Locical Drive                                         */
+/*-----------------------------------------------------------------------*/
+
+FRESULT f_mount (
+	BYTE vol,		/* Logical drive number to be mounted/unmounted */
+	FATFS *fs		/* Pointer to new file system object (NULL for unmount)*/
+)
+{
+	FATFS *rfs;
+
+
+	if (vol >= _DRIVES)				/* Check if the drive number is valid */
+		return FR_INVALID_DRIVE;
+	rfs = FatFs[vol];				/* Get current state */
+
+	if (rfs) {
+#if _FS_REENTRANT					/* Discard sync object of the current volume */
+		if (!ff_del_syncobj(fs->sobj)) return FR_INT_ERR;
+#endif
+		rfs->fs_type = 0;			/* Clear old fs object */
+	}
+
+	if (fs) {
+		fs->fs_type = 0;			/* Clear new fs object */
+#if _FS_REENTRANT					/* Create sync object for the new volume */
+		if (!ff_cre_syncobj(vol, &fs->sobj)) return FR_INT_ERR;
+#endif
+	}
+	FatFs[vol] = fs;				/* Register new fs object */
+
+	return FR_OK;
+}
+
+
+
+
+/*-----------------------------------------------------------------------*/
+/* Open or Create a File                                                 */
+/*-----------------------------------------------------------------------*/
+
+FRESULT f_open (
+	FIL *fp,			/* Pointer to the blank file object */
+	const char *path,	/* Pointer to the file name */
+	BYTE mode			/* Access mode and file open mode flags */
+)
+{
+	FRESULT res;
+	DIR dj;
+	NAMEBUF(sfn, lfn);
+	BYTE *dir;
+
+
+	fp->fs = NULL;		/* Clear file object */
+#if !_FS_READONLY
+	mode &= (FA_READ | FA_WRITE | FA_CREATE_ALWAYS | FA_OPEN_ALWAYS | FA_CREATE_NEW);
+	res = auto_mount(&path, &dj.fs, (BYTE)(mode & (FA_WRITE | FA_CREATE_ALWAYS | FA_OPEN_ALWAYS | FA_CREATE_NEW)));
+#else
+	mode &= FA_READ;
+	res = auto_mount(&path, &dj.fs, 0);
+#endif
+	if (res != FR_OK) LEAVE_FF(dj.fs, res);
+	INITBUF(dj, sfn, lfn);
+	res = follow_path(&dj, path);	/* Follow the file path */
+
+#if !_FS_READONLY
+	/* Create or Open a file */
+	if (mode & (FA_CREATE_ALWAYS | FA_OPEN_ALWAYS | FA_CREATE_NEW)) {
+		DWORD ps, cl;
+
+		if (res != FR_OK) {		/* No file, create new */
+			if (res == FR_NO_FILE)
+				res = dir_register(&dj);
+			if (res != FR_OK) LEAVE_FF(dj.fs, res);
+			mode |= FA_CREATE_ALWAYS;
+			dir = dj.dir;
+		}
+		else {					/* Any object is already existing */
+			if (mode & FA_CREATE_NEW)			/* Cannot create new */
+				LEAVE_FF(dj.fs, FR_EXIST);
+			dir = dj.dir;
+			if (!dir || (dir[DIR_Attr] & (AM_RDO | AM_DIR)))	/* Cannot overwrite it (R/O or DIR) */
+				LEAVE_FF(dj.fs, FR_DENIED);
+			if (mode & FA_CREATE_ALWAYS) {		/* Resize it to zero if needed */
+				cl = ((DWORD)LD_WORD(dir+DIR_FstClusHI) << 16) | LD_WORD(dir+DIR_FstClusLO);	/* Get start cluster */
+				ST_WORD(dir+DIR_FstClusHI, 0);	/* cluster = 0 */
+				ST_WORD(dir+DIR_FstClusLO, 0);
+				ST_DWORD(dir+DIR_FileSize, 0);	/* size = 0 */
+				dj.fs->wflag = 1;
+				ps = dj.fs->winsect;			/* Remove the cluster chain */
+				if (cl) {
+					res = remove_chain(dj.fs, cl);
+					if (res) LEAVE_FF(dj.fs, res);
+					dj.fs->last_clust = cl - 1;	/* Reuse the cluster hole */
+				}
+				res = move_window(dj.fs, ps);
+				if (res != FR_OK) LEAVE_FF(dj.fs, res);
+			}
+		}
+		if (mode & FA_CREATE_ALWAYS) {
+			dir[DIR_Attr] = 0;					/* Reset attribute */
+			ps = get_fattime();
+			ST_DWORD(dir+DIR_CrtTime, ps);		/* Created time */
+			dj.fs->wflag = 1;
+			mode |= FA__WRITTEN;				/* Set file changed flag */
+		}
+	}
+	/* Open an existing file */
+	else {
+#endif /* !_FS_READONLY */
+		if (res != FR_OK) LEAVE_FF(dj.fs, res);	/* Follow failed */
+		dir = dj.dir;
+		if (!dir || (dir[DIR_Attr] & AM_DIR))	/* It is a directory */
+			LEAVE_FF(dj.fs, FR_NO_FILE);
+#if !_FS_READONLY
+		if ((mode & FA_WRITE) && (dir[DIR_Attr] & AM_RDO)) /* R/O violation */
+			LEAVE_FF(dj.fs, FR_DENIED);
+	}
+	fp->dir_sect = dj.fs->winsect;		/* Pointer to the directory entry */
+	fp->dir_ptr = dj.dir;
+#endif
+	fp->flag = mode;					/* File access mode */
+	fp->org_clust =						/* File start cluster */
+		((DWORD)LD_WORD(dir+DIR_FstClusHI) << 16) | LD_WORD(dir+DIR_FstClusLO);
+	fp->fsize = LD_DWORD(dir+DIR_FileSize);	/* File size */
+	fp->fptr = 0; fp->csect = 255;		/* File pointer */
+	fp->dsect = 0;
+	fp->fs = dj.fs; fp->id = dj.fs->id;	/* Owner file system object of the file */
+
+	LEAVE_FF(dj.fs, FR_OK);
+}
+
+
+
+
+/*-----------------------------------------------------------------------*/
+/* Read File                                                             */
+/*-----------------------------------------------------------------------*/
+
+FRESULT f_read (
+	FIL *fp, 		/* Pointer to the file object */
+	void *buff,		/* Pointer to data buffer */
+	UINT btr,		/* Number of bytes to read */
+	UINT *br		/* Pointer to number of bytes read */
+)
+{
+	FRESULT res;
+	DWORD clst, sect, remain;
+	UINT rcnt, cc;
+	BYTE *rbuff = buff;
+
+
+	*br = 0;
+
+	res = validate(fp->fs, fp->id);					/* Check validity of the object */
+	if (res != FR_OK) LEAVE_FF(fp->fs, res);
+	if (fp->flag & FA__ERROR)						/* Check abort flag */
+		LEAVE_FF(fp->fs, FR_INT_ERR);
+	if (!(fp->flag & FA_READ)) 						/* Check access mode */
+		LEAVE_FF(fp->fs, FR_DENIED);
+	remain = fp->fsize - fp->fptr;
+	if (btr > remain) btr = (UINT)remain;			/* Truncate btr by remaining bytes */
+
+	for ( ;  btr;									/* Repeat until all data transferred */
+		rbuff += rcnt, fp->fptr += rcnt, *br += rcnt, btr -= rcnt) {
+		if ((fp->fptr % SS(fp->fs)) == 0) {			/* On the sector boundary? */
+			if (fp->csect >= fp->fs->csize) {		/* On the cluster boundary? */
+				clst = (fp->fptr == 0) ?			/* On the top of the file? */
+					fp->org_clust : get_cluster(fp->fs, fp->curr_clust);
+				if (clst <= 1) ABORT(fp->fs, FR_INT_ERR);
+				if (clst == 0xFFFFFFFF) ABORT(fp->fs, FR_DISK_ERR);
+				fp->curr_clust = clst;				/* Update current cluster */
+				fp->csect = 0;						/* Reset sector offset in the cluster */
+			}
+			sect = clust2sect(fp->fs, fp->curr_clust);	/* Get current sector */
+			if (!sect) ABORT(fp->fs, FR_INT_ERR);
+			sect += fp->csect;
+			cc = btr / SS(fp->fs);					/* When remaining bytes >= sector size, */
+			if (cc) {								/* Read maximum contiguous sectors directly */
+				if (fp->csect + cc > fp->fs->csize)	/* Clip at cluster boundary */
+					cc = fp->fs->csize - fp->csect;
+				if (disk_read(fp->fs->drive, rbuff, sect, (BYTE)cc) != RES_OK)
+					ABORT(fp->fs, FR_DISK_ERR);
+				fp->csect += (BYTE)cc;				/* Next sector address in the cluster */
+				rcnt = SS(fp->fs) * cc;				/* Number of bytes transferred */
+				continue;
+			}
+#if !_FS_TINY
+#if !_FS_READONLY
+			if (fp->flag & FA__DIRTY) {			/* Write sector I/O buffer if needed */
+				if (disk_write(fp->fs->drive, fp->buf, fp->dsect, 1) != RES_OK)
+					ABORT(fp->fs, FR_DISK_ERR);
+				fp->flag &= (BYTE)~FA__DIRTY;
+			}
+#endif
+			if (fp->dsect != sect) {			/* Fill sector buffer with file data */
+				if (disk_read(fp->fs->drive, fp->buf, sect, 1) != RES_OK)
+					ABORT(fp->fs, FR_DISK_ERR);
+			}
+#endif
+			fp->dsect = sect;
+			fp->csect++;							/* Next sector address in the cluster */
+		}
+		rcnt = SS(fp->fs) - (fp->fptr % SS(fp->fs));	/* Get partial sector data from sector buffer */
+		if (rcnt > btr) rcnt = btr;
+#if _FS_TINY
+		if (move_window(fp->fs, fp->dsect))			/* Move sector window */
+			ABORT(fp->fs, FR_DISK_ERR);
+		mem_cpy(rbuff, &fp->fs->win[fp->fptr % SS(fp->fs)], rcnt);	/* Pick partial sector */
+#else
+		mem_cpy(rbuff, &fp->buf[fp->fptr % SS(fp->fs)], rcnt);	/* Pick partial sector */
+#endif
+	}
+
+
+	LEAVE_FF(fp->fs, FR_OK);
+}
+
+
+
+
+#if !_FS_READONLY
+/*-----------------------------------------------------------------------*/
+/* Write File                                                            */
+/*-----------------------------------------------------------------------*/
+
+FRESULT f_write (
+	FIL *fp,			/* Pointer to the file object */
+	const void *buff,	/* Pointer to the data to be written */
+	UINT btw,			/* Number of bytes to write */
+	UINT *bw			/* Pointer to number of bytes written */
+)
+{
+	FRESULT res;
+	DWORD clst, sect;
+	UINT wcnt, cc;
+	const BYTE *wbuff = buff;
+
+
+	*bw = 0;
+
+	res = validate(fp->fs, fp->id);					/* Check validity of the object */
+	if (res != FR_OK) LEAVE_FF(fp->fs, res);
+	if (fp->flag & FA__ERROR)						/* Check abort flag */
+		LEAVE_FF(fp->fs, FR_INT_ERR);
+	if (!(fp->flag & FA_WRITE))						/* Check access mode */
+		LEAVE_FF(fp->fs, FR_DENIED);
+	if (fp->fsize + btw < fp->fsize) btw = 0;		/* File size cannot reach 4GB */
+
+	for ( ;  btw;									/* Repeat until all data transferred */
+		wbuff += wcnt, fp->fptr += wcnt, *bw += wcnt, btw -= wcnt) {
+		if ((fp->fptr % SS(fp->fs)) == 0) {			/* On the sector boundary? */
+			if (fp->csect >= fp->fs->csize) {		/* On the cluster boundary? */
+				if (fp->fptr == 0) {				/* On the top of the file? */
+					clst = fp->org_clust;			/* Follow from the origin */
+					if (clst == 0)					/* When there is no cluster chain, */
+						fp->org_clust = clst = create_chain(fp->fs, 0);	/* Create a new cluster chain */
+				} else {							/* Middle or end of the file */
+					clst = create_chain(fp->fs, fp->curr_clust);			/* Follow or streach cluster chain */
+				}
+				if (clst == 0) break;				/* Could not allocate a new cluster (disk full) */
+				if (clst == 1) ABORT(fp->fs, FR_INT_ERR);
+				if (clst == 0xFFFFFFFF) ABORT(fp->fs, FR_DISK_ERR);
+				fp->curr_clust = clst;				/* Update current cluster */
+				fp->csect = 0;						/* Reset sector address in the cluster */
+			}
+#if _FS_TINY
+			if (fp->fs->winsect == fp->dsect && move_window(fp->fs, 0))	/* Write back data buffer prior to following direct transfer */
+				ABORT(fp->fs, FR_DISK_ERR);
+#else
+			if (fp->flag & FA__DIRTY) {		/* Write back data buffer prior to following direct transfer */
+				if (disk_write(fp->fs->drive, fp->buf, fp->dsect, 1) != RES_OK)
+					ABORT(fp->fs, FR_DISK_ERR);
+				fp->flag &= (BYTE)~FA__DIRTY;
+			}
+#endif
+			sect = clust2sect(fp->fs, fp->curr_clust);	/* Get current sector */
+			if (!sect) ABORT(fp->fs, FR_INT_ERR);
+			sect += fp->csect;
+			cc = btw / SS(fp->fs);					/* When remaining bytes >= sector size, */
+			if (cc) {								/* Write maximum contiguous sectors directly */
+				if (fp->csect + cc > fp->fs->csize)	/* Clip at cluster boundary */
+					cc = fp->fs->csize - fp->csect;
+				if (disk_write(fp->fs->drive, wbuff, sect, (BYTE)cc) != RES_OK)
+					ABORT(fp->fs, FR_DISK_ERR);
+				fp->csect += (BYTE)cc;				/* Next sector address in the cluster */
+				wcnt = SS(fp->fs) * cc;				/* Number of bytes transferred */
+				continue;
+			}
+#if _FS_TINY
+			if (fp->fptr >= fp->fsize) {			/* Avoid silly buffer filling at growing edge */
+				if (move_window(fp->fs, 0)) ABORT(fp->fs, FR_DISK_ERR);
+				fp->fs->winsect = sect;
+			}
+#else
+			if (fp->dsect != sect) {				/* Fill sector buffer with file data */
+				if (fp->fptr < fp->fsize &&
+					disk_read(fp->fs->drive, fp->buf, sect, 1) != RES_OK)
+						ABORT(fp->fs, FR_DISK_ERR);
+			}
+#endif
+			fp->dsect = sect;
+			fp->csect++;							/* Next sector address in the cluster */
+		}
+		wcnt = SS(fp->fs) - (fp->fptr % SS(fp->fs));	/* Put partial sector into file I/O buffer */
+		if (wcnt > btw) wcnt = btw;
+#if _FS_TINY
+		if (move_window(fp->fs, fp->dsect))			/* Move sector window */
+			ABORT(fp->fs, FR_DISK_ERR);
+		mem_cpy(&fp->fs->win[fp->fptr % SS(fp->fs)], wbuff, wcnt);	/* Fit partial sector */
+		fp->fs->wflag = 1;
+#else
+		mem_cpy(&fp->buf[fp->fptr % SS(fp->fs)], wbuff, wcnt);	/* Fit partial sector */
+		fp->flag |= FA__DIRTY;
+#endif
+	}
+
+	if (fp->fptr > fp->fsize) fp->fsize = fp->fptr;	/* Update file size if needed */
+	fp->flag |= FA__WRITTEN;						/* Set file changed flag */
+
+	LEAVE_FF(fp->fs, FR_OK);
+}
+
+
+
+
+/*-----------------------------------------------------------------------*/
+/* Synchronize the File Object                                           */
+/*-----------------------------------------------------------------------*/
+
+FRESULT f_sync (
+	FIL *fp		/* Pointer to the file object */
+)
+{
+	FRESULT res;
+	DWORD tim;
+	BYTE *dir;
+
+
+	res = validate(fp->fs, fp->id);		/* Check validity of the object */
+	if (res == FR_OK) {
+		if (fp->flag & FA__WRITTEN) {	/* Has the file been written? */
+#if !_FS_TINY	/* Write-back dirty buffer */
+			if (fp->flag & FA__DIRTY) {
+				if (disk_write(fp->fs->drive, fp->buf, fp->dsect, 1) != RES_OK)
+					LEAVE_FF(fp->fs, FR_DISK_ERR);
+				fp->flag &= (BYTE)~FA__DIRTY;
+			}
+#endif
+			/* Update the directory entry */
+			res = move_window(fp->fs, fp->dir_sect);
+			if (res == FR_OK) {
+				dir = fp->dir_ptr;
+				dir[DIR_Attr] |= AM_ARC;					/* Set archive bit */
+				ST_DWORD(dir+DIR_FileSize, fp->fsize);		/* Update file size */
+				ST_WORD(dir+DIR_FstClusLO, fp->org_clust);	/* Update start cluster */
+				ST_WORD(dir+DIR_FstClusHI, fp->org_clust >> 16);
+				tim = get_fattime();					/* Updated time */
+				ST_DWORD(dir+DIR_WrtTime, tim);
+				fp->flag &= (BYTE)~FA__WRITTEN;
+				fp->fs->wflag = 1;
+				res = sync(fp->fs);
+			}
+		}
+	}
+
+	LEAVE_FF(fp->fs, res);
+}
+
+#endif /* !_FS_READONLY */
+
+
+
+
+/*-----------------------------------------------------------------------*/
+/* Close File                                                            */
+/*-----------------------------------------------------------------------*/
+
+FRESULT f_close (
+	FIL *fp		/* Pointer to the file object to be closed */
+)
+{
+	FRESULT res;
+
+
+#if _FS_READONLY
+	res = validate(fp->fs, fp->id);
+	if (res == FR_OK) fp->fs = NULL;
+	LEAVE_FF(fp->fs, res);
+#else
+	res = f_sync(fp);
+	if (res == FR_OK) fp->fs = NULL;
+	return res;
+#endif
+}
+
+
+
+
+#if _FS_MINIMIZE <= 2
+/*-----------------------------------------------------------------------*/
+/* Seek File R/W Pointer                                                 */
+/*-----------------------------------------------------------------------*/
+
+FRESULT f_lseek (
+	FIL *fp,		/* Pointer to the file object */
+	DWORD ofs		/* File pointer from top of file */
+)
+{
+	FRESULT res;
+	DWORD clst, bcs, nsect, ifptr;
+
+
+	res = validate(fp->fs, fp->id);		/* Check validity of the object */
+	if (res != FR_OK) LEAVE_FF(fp->fs, res);
+	if (fp->flag & FA__ERROR)			/* Check abort flag */
+		LEAVE_FF(fp->fs, FR_INT_ERR);
+	if (ofs > fp->fsize					/* In read-only mode, clip offset with the file size */
+#if !_FS_READONLY
+		 && !(fp->flag & FA_WRITE)
+#endif
+		) ofs = fp->fsize;
+
+	ifptr = fp->fptr;
+	fp->fptr = 0; fp->csect = 255;
+	nsect = 0;
+	if (ofs > 0) {
+		bcs = (DWORD)fp->fs->csize * SS(fp->fs);	/* Cluster size (byte) */
+		if (ifptr > 0 &&
+			(ofs - 1) / bcs >= (ifptr - 1) / bcs) {	/* When seek to same or following cluster, */
+			fp->fptr = (ifptr - 1) & ~(bcs - 1);	/* start from the current cluster */
+			ofs -= fp->fptr;
+			clst = fp->curr_clust;
+		} else {									/* When seek to back cluster, */
+			clst = fp->org_clust;					/* start from the first cluster */
+#if !_FS_READONLY
+			if (clst == 0) {						/* If no cluster chain, create a new chain */
+				clst = create_chain(fp->fs, 0);
+				if (clst == 1) ABORT(fp->fs, FR_INT_ERR);
+				if (clst == 0xFFFFFFFF) ABORT(fp->fs, FR_DISK_ERR);
+				fp->org_clust = clst;
+			}
+#endif
+			fp->curr_clust = clst;
+		}
+		if (clst != 0) {
+			while (ofs > bcs) {						/* Cluster following loop */
+#if !_FS_READONLY
+				if (fp->flag & FA_WRITE) {			/* Check if in write mode or not */
+					clst = create_chain(fp->fs, clst);	/* Force streached if in write mode */
+					if (clst == 0) {				/* When disk gets full, clip file size */
+						ofs = bcs; break;
+					}
+				} else
+#endif
+					clst = get_cluster(fp->fs, clst);	/* Follow cluster chain if not in write mode */
+				if (clst == 0xFFFFFFFF) ABORT(fp->fs, FR_DISK_ERR);
+				if (clst <= 1 || clst >= fp->fs->max_clust) ABORT(fp->fs, FR_INT_ERR);
+				fp->curr_clust = clst;
+				fp->fptr += bcs;
+				ofs -= bcs;
+			}
+			fp->fptr += ofs;
+			fp->csect = (BYTE)(ofs / SS(fp->fs));	/* Sector offset in the cluster */
+			if (ofs % SS(fp->fs)) {
+				nsect = clust2sect(fp->fs, clst);	/* Current sector */
+				if (!nsect) ABORT(fp->fs, FR_INT_ERR);
+				nsect += fp->csect;
+				fp->csect++;
+			}
+		}
+	}
+	if (nsect && nsect != fp->dsect && fp->fptr % SS(fp->fs)) {
+#if !_FS_TINY
+#if !_FS_READONLY
+		if (fp->flag & FA__DIRTY) {			/* Write-back dirty buffer if needed */
+			if (disk_write(fp->fs->drive, fp->buf, fp->dsect, 1) != RES_OK)
+				ABORT(fp->fs, FR_DISK_ERR);
+			fp->flag &= (BYTE)~FA__DIRTY;
+		}
+#endif
+		if (disk_read(fp->fs->drive, fp->buf, nsect, 1) != RES_OK)
+			ABORT(fp->fs, FR_DISK_ERR);
+#endif
+		fp->dsect = nsect;
+	}
+#if !_FS_READONLY
+	if (fp->fptr > fp->fsize) {			/* Set changed flag if the file size is extended */
+		fp->fsize = fp->fptr;
+		fp->flag |= FA__WRITTEN;
+	}
+#endif
+
+	LEAVE_FF(fp->fs, res);
+}
+
+
+
+
+#if _FS_MINIMIZE <= 1
+/*-----------------------------------------------------------------------*/
+/* Create a Directroy Object                                             */
+/*-----------------------------------------------------------------------*/
+
+FRESULT f_opendir (
+	DIR *dj,			/* Pointer to directory object to create */
+	const char *path	/* Pointer to the directory path */
+)
+{
+	FRESULT res;
+	NAMEBUF(sfn, lfn);
+	BYTE *dir;
+
+
+	res = auto_mount(&path, &dj->fs, 0);
+	if (res == FR_OK) {
+		INITBUF((*dj), sfn, lfn);
+		res = follow_path(dj, path);			/* Follow the path to the directory */
+		if (res == FR_OK) {						/* Follow completed */
+			dir = dj->dir;
+			if (dir) {							/* It is not the root dir */
+				if (dir[DIR_Attr] & AM_DIR) {	/* The object is a directory */
+					dj->sclust = ((DWORD)LD_WORD(dir+DIR_FstClusHI) << 16) | LD_WORD(dir+DIR_FstClusLO);
+				} else {						/* The object is not a directory */
+					res = FR_NO_PATH;
+				}
+			} else {							/* It is the root dir */
+				dj->sclust = (dj->fs->fs_type == FS_FAT32) ? dj->fs->dirbase : 0;
+			}
+			if (res == FR_OK) res = dir_seek(dj, 0);
+			dj->id = dj->fs->id;
+		} else {
+			if (res == FR_NO_FILE) res = FR_NO_PATH;
+		}
+	}
+
+	LEAVE_FF(dj->fs, res);
+}
+
+
+
+
+/*-----------------------------------------------------------------------*/
+/* Read Directory Entry in Sequense                                      */
+/*-----------------------------------------------------------------------*/
+
+FRESULT f_readdir (
+	DIR *dj,			/* Pointer to the open directory object */
+	FILINFO *fno		/* Pointer to file information to return */
+)
+{
+	FRESULT res;
+	NAMEBUF(sfn, lfn);
+
+
+	res = validate(dj->fs, dj->id);			/* Check validity of the object */
+	if (res == FR_OK) {
+#if 0	/* ROI DEBUG */
+		INITBUF((*dj), sfn, lfn);
+#else	/* ROI DEBUG */
+		INITBUF2((*dj), sfn);
+#endif	/* ROI DEBUG */
+		if (!fno) {
+			res = dir_seek(dj, 0);
+		} else {
+			res = dir_read(dj);
+			if (res == FR_NO_FILE) {
+				dj->sect = 0;
+				res = FR_OK;
+			}
+			if (res == FR_OK) {				/* A valid entry is found */
+				get_fileinfo(dj, fno);		/* Get the object information */
+				res = dir_next(dj, FALSE);	/* Increment index for next */
+				if (res == FR_NO_FILE) {
+					dj->sect = 0;
+					res = FR_OK;
+				}
+			}
+		}
+	}
+
+	LEAVE_FF(dj->fs, res);
+}
+
+
+
+#if _FS_MINIMIZE == 0
+/*-----------------------------------------------------------------------*/
+/* Get File Status                                                       */
+/*-----------------------------------------------------------------------*/
+
+FRESULT f_stat (
+	const char *path,	/* Pointer to the file path */
+	FILINFO *fno		/* Pointer to file information to return */
+)
+{
+	FRESULT res;
+	DIR dj;
+	NAMEBUF(sfn, lfn);
+
+
+	res = auto_mount(&path, &dj.fs, 0);
+	if (res == FR_OK) {
+		INITBUF(dj, sfn, lfn);
+		res = follow_path(&dj, path);	/* Follow the file path */
+		if (res == FR_OK) {				/* Follwo completed */
+			if (dj.dir)	/* Found an object */
+				get_fileinfo(&dj, fno);
+			else		/* It is root dir */
+				res = FR_INVALID_NAME;
+		}
+	}
+
+	LEAVE_FF(dj.fs, res);
+}
+
+
+
+#if !_FS_READONLY
+/*-----------------------------------------------------------------------*/
+/* Truncate File                                                         */
+/*-----------------------------------------------------------------------*/
+
+FRESULT f_truncate (
+	FIL *fp		/* Pointer to the file object */
+)
+{
+	FRESULT res;
+	DWORD ncl;
+
+
+	res = validate(fp->fs, fp->id);		/* Check validity of the object */
+	if (res != FR_OK) LEAVE_FF(fp->fs, res);
+	if (fp->flag & FA__ERROR)			/* Check abort flag */
+		LEAVE_FF(fp->fs, FR_INT_ERR);
+	if (!(fp->flag & FA_WRITE))			/* Check access mode */
+		LEAVE_FF(fp->fs, FR_DENIED);
+
+	if (fp->fsize > fp->fptr) {
+		fp->fsize = fp->fptr;	/* Set file size to current R/W point */
+		fp->flag |= FA__WRITTEN;
+		if (fp->fptr == 0) {	/* When set file size to zero, remove entire cluster chain */
+			res = remove_chain(fp->fs, fp->org_clust);
+			fp->org_clust = 0;
+		} else {				/* When truncate a part of the file, remove remaining clusters */
+			ncl = get_cluster(fp->fs, fp->curr_clust);
+			res = FR_OK;
+			if (ncl == 0xFFFFFFFF) res = FR_DISK_ERR;
+			if (ncl == 1) res = FR_INT_ERR;
+			if (res == FR_OK && ncl < fp->fs->max_clust) {
+				res = put_cluster(fp->fs, fp->curr_clust, 0x0FFFFFFF);
+				if (res == FR_OK) res = remove_chain(fp->fs, ncl);
+			}
+		}
+	}
+	if (res != FR_OK) fp->flag |= FA__ERROR;
+
+	LEAVE_FF(fp->fs, res);
+}
+
+
+
+
+/*-----------------------------------------------------------------------*/
+/* Get Number of Free Clusters                                           */
+/*-----------------------------------------------------------------------*/
+
+FRESULT f_getfree (
+	const char *path,	/* Pointer to the logical drive number (root dir) */
+	DWORD *nclst,		/* Pointer to the variable to return number of free clusters */
+	FATFS **fatfs		/* Pointer to pointer to corresponding file system object to return */
+)
+{
+	FRESULT res;
+	DWORD n, clst, sect;
+	BYTE fat, f, *p;
+
+
+	/* Get drive number */
+	res = auto_mount(&path, fatfs, 0);
+	if (res != FR_OK) LEAVE_FF(*fatfs, res);
+
+	/* If number of free cluster is valid, return it without cluster scan. */
+	if ((*fatfs)->free_clust <= (*fatfs)->max_clust - 2) {
+		*nclst = (*fatfs)->free_clust;
+		LEAVE_FF(*fatfs, FR_OK);
+	}
+
+	/* Get number of free clusters */
+	fat = (*fatfs)->fs_type;
+	n = 0;
+	if (fat == FS_FAT12) {
+		clst = 2;
+		do {
+			if ((WORD)get_cluster(*fatfs, clst) == 0) n++;
+		} while (++clst < (*fatfs)->max_clust);
+	} else {
+		clst = (*fatfs)->max_clust;
+		sect = (*fatfs)->fatbase;
+		f = 0; p = 0;
+		do {
+			if (!f) {
+				res = move_window(*fatfs, sect++);
+				if (res != FR_OK)
+					LEAVE_FF(*fatfs, res);
+				p = (*fatfs)->win;
+			}
+			if (fat == FS_FAT16) {
+				if (LD_WORD(p) == 0) n++;
+				p += 2; f += 1;
+			} else {
+				if (LD_DWORD(p) == 0) n++;
+				p += 4; f += 2;
+			}
+		} while (--clst);
+	}
+	(*fatfs)->free_clust = n;
+	if (fat == FS_FAT32) (*fatfs)->fsi_flag = 1;
+	*nclst = n;
+
+	LEAVE_FF(*fatfs, FR_OK);
+}
+
+
+
+
+/*-----------------------------------------------------------------------*/
+/* Delete a File or Directory                                            */
+/*-----------------------------------------------------------------------*/
+
+FRESULT f_unlink (
+	const char *path		/* Pointer to the file or directory path */
+)
+{
+	FRESULT res;
+	DIR dj, sdj;
+	NAMEBUF(sfn, lfn);
+	BYTE *dir;
+	DWORD dclst;
+
+
+	res = auto_mount(&path, &dj.fs, 1);
+	if (res != FR_OK) LEAVE_FF(dj.fs, res);
+
+	INITBUF(dj, sfn, lfn);
+	res = follow_path(&dj, path);			/* Follow the file path */
+	if (res != FR_OK) LEAVE_FF(dj.fs, res); /* Follow failed */
+
+	dir = dj.dir;
+	if (!dir)								/* Is it the root directory? */
+		LEAVE_FF(dj.fs, FR_INVALID_NAME);
+	if (dir[DIR_Attr] & AM_RDO)				/* Is it a R/O object? */
+		LEAVE_FF(dj.fs, FR_DENIED);
+	dclst = ((DWORD)LD_WORD(dir+DIR_FstClusHI) << 16) | LD_WORD(dir+DIR_FstClusLO);
+
+	if (dir[DIR_Attr] & AM_DIR) {			/* It is a sub-directory */
+		if (dclst < 2) LEAVE_FF(dj.fs, FR_INT_ERR);
+		mem_cpy(&sdj, &dj, sizeof(DIR));		/* Check if the sub-dir is empty or not */
+		sdj.sclust = dclst;
+		res = dir_seek(&sdj, 0);
+		if (res != FR_OK) LEAVE_FF(dj.fs, res);
+		res = dir_read(&sdj);
+		if (res == FR_OK) res = FR_DENIED;	/* Not empty sub-dir */
+		if (res != FR_NO_FILE) LEAVE_FF(dj.fs, res);
+	}
+
+	res = dir_remove(&dj);					/* Remove directory entry */
+	if (res == FR_OK) {
+		if (dclst)
+			res = remove_chain(dj.fs, dclst);	/* Remove the cluster chain */
+		if (res == FR_OK) res = sync(dj.fs);
+	}
+
+	LEAVE_FF(dj.fs, FR_OK);
+}
+
+
+
+
+/*-----------------------------------------------------------------------*/
+/* Create a Directory                                                    */
+/*-----------------------------------------------------------------------*/
+
+FRESULT f_mkdir (
+	const char *path		/* Pointer to the directory path */
+)
+{
+	FRESULT res;
+	DIR dj;
+	NAMEBUF(sfn, lfn);
+	BYTE *dir, n;
+	DWORD dsect, dclst, pclst, tim;
+
+
+	res = auto_mount(&path, &dj.fs, 1);
+	if (res != FR_OK) LEAVE_FF(dj.fs, res);
+
+	INITBUF(dj, sfn, lfn);
+	res = follow_path(&dj, path);			/* Follow the file path */
+	if (res == FR_OK) res = FR_EXIST;		/* Any file or directory is already existing */
+	if (res != FR_NO_FILE)					/* Any error occured */
+		LEAVE_FF(dj.fs, res);
+
+	dclst = create_chain(dj.fs, 0);			/* Allocate a new cluster for new directory table */
+	res = FR_OK;
+	if (dclst == 0) res = FR_DENIED;
+	if (dclst == 1) res = FR_INT_ERR;
+	if (dclst == 0xFFFFFFFF) res = FR_DISK_ERR;
+	if (res == FR_OK)
+		res = move_window(dj.fs, 0);
+	if (res != FR_OK) LEAVE_FF(dj.fs, res);
+	dsect = clust2sect(dj.fs, dclst);
+
+	dir = dj.fs->win;						/* Initialize the new directory table */
+	mem_set(dir, 0, SS(dj.fs));
+	mem_set(dir+DIR_Name, ' ', 8+3);		/* Create "." entry */
+	dir[DIR_Name] = '.';
+	dir[DIR_Attr] = AM_DIR;
+	tim = get_fattime();
+	ST_DWORD(dir+DIR_WrtTime, tim);
+	ST_WORD(dir+DIR_FstClusLO, dclst);
+	ST_WORD(dir+DIR_FstClusHI, dclst >> 16);
+	mem_cpy(dir+32, dir, 32); 			/* Create ".." entry */
+	dir[33] = '.';
+	pclst = dj.sclust;
+	if (dj.fs->fs_type == FS_FAT32 && pclst == dj.fs->dirbase)
+		pclst = 0;
+	ST_WORD(dir+32+DIR_FstClusLO, pclst);
+	ST_WORD(dir+32+DIR_FstClusHI, pclst >> 16);
+	for (n = 0; n < dj.fs->csize; n++) {	/* Write dot entries and clear left sectors */
+		dj.fs->winsect = dsect++;
+		dj.fs->wflag = 1;
+		res = move_window(dj.fs, 0);
+		if (res) LEAVE_FF(dj.fs, res);
+		mem_set(dir, 0, SS(dj.fs));
+	}
+
+	res = dir_register(&dj);
+	if (res != FR_OK) {
+		remove_chain(dj.fs, dclst);
+	} else {
+		dir = dj.dir;
+		dir[DIR_Attr] = AM_DIR;					/* Attribute */
+		ST_DWORD(dir+DIR_WrtTime, tim);			/* Crated time */
+		ST_WORD(dir+DIR_FstClusLO, dclst);		/* Table start cluster */
+		ST_WORD(dir+DIR_FstClusHI, dclst >> 16);
+		dj.fs->wflag = 1;
+		res = sync(dj.fs);
+	}
+
+	LEAVE_FF(dj.fs, res);
+}
+
+
+
+
+/*-----------------------------------------------------------------------*/
+/* Change File Attribute                                                 */
+/*-----------------------------------------------------------------------*/
+
+FRESULT f_chmod (
+	const char *path,	/* Pointer to the file path */
+	BYTE value,			/* Attribute bits */
+	BYTE mask			/* Attribute mask to change */
+)
+{
+	FRESULT res;
+	DIR dj;
+	NAMEBUF(sfn, lfn);
+	BYTE *dir;
+
+
+	res = auto_mount(&path, &dj.fs, 1);
+	if (res == FR_OK) {
+		INITBUF(dj, sfn, lfn);
+		res = follow_path(&dj, path);		/* Follow the file path */
+		if (res == FR_OK) {
+			dir = dj.dir;
+			if (!dir) {						/* Is it a root directory? */
+				res = FR_INVALID_NAME;
+			} else {						/* File or sub directory */
+				mask &= AM_RDO|AM_HID|AM_SYS|AM_ARC;	/* Valid attribute mask */
+				dir[DIR_Attr] = (value & mask) | (dir[DIR_Attr] & (BYTE)~mask);	/* Apply attribute change */
+				dj.fs->wflag = 1;
+				res = sync(dj.fs);
+			}
+		}
+	}
+
+	LEAVE_FF(dj.fs, res);
+}
+
+
+
+
+/*-----------------------------------------------------------------------*/
+/* Change Timestamp                                                      */
+/*-----------------------------------------------------------------------*/
+
+FRESULT f_utime (
+	const char *path,	/* Pointer to the file/directory name */
+	const FILINFO *fno	/* Pointer to the timestamp to be set */
+)
+{
+	FRESULT res;
+	DIR dj;
+	NAMEBUF(sfn, lfn);
+	BYTE *dir;
+
+
+	res = auto_mount(&path, &dj.fs, 1);
+	if (res == FR_OK) {
+		INITBUF(dj, sfn, lfn);
+		res = follow_path(&dj, path);	/* Follow the file path */
+		if (res == FR_OK) {
+			dir = dj.dir;
+			if (!dir) {				/* Root directory */
+				res = FR_INVALID_NAME;
+			} else {				/* File or sub-directory */
+				ST_WORD(dir+DIR_WrtTime, fno->ftime);
+				ST_WORD(dir+DIR_WrtDate, fno->fdate);
+				dj.fs->wflag = 1;
+				res = sync(dj.fs);
+			}
+		}
+	}
+
+	LEAVE_FF(dj.fs, res);
+}
+
+
+
+
+/*-----------------------------------------------------------------------*/
+/* Rename File/Directory                                                 */
+/*-----------------------------------------------------------------------*/
+
+FRESULT f_rename (
+	const char *path_old,	/* Pointer to the old name */
+	const char *path_new	/* Pointer to the new name */
+)
+{
+	FRESULT res;
+	DIR dj_old, dj_new;
+	NAMEBUF(sfn, lfn);
+	BYTE buf[21], *dir;
+	DWORD dw;
+
+
+	INITBUF(dj_old, sfn, lfn);
+	res = auto_mount(&path_old, &dj_old.fs, 1);
+	if (res == FR_OK) {
+		dj_new.fs = dj_old.fs;
+		res = follow_path(&dj_old, path_old);	/* Check old object */
+	}
+	if (res != FR_OK) LEAVE_FF(dj_old.fs, res);	/* The old object is not found */
+
+	if (!dj_old.dir) LEAVE_FF(dj_old.fs, FR_NO_FILE);	/* Is root dir? */
+	mem_cpy(buf, dj_old.dir+DIR_Attr, 21);		/* Save the object information */
+
+	mem_cpy(&dj_new, &dj_old, sizeof(DIR));
+	res = follow_path(&dj_new, path_new);		/* Check new object */
+	if (res == FR_OK) res = FR_EXIST;			/* The new object name is already existing */
+	if (res == FR_NO_FILE) { 					/* Is it a valid path and no name collision? */
+		res = dir_register(&dj_new);			/* Register the new object */
+		if (res == FR_OK) {
+			dir = dj_new.dir;					/* Copy object information into new entry */
+			mem_cpy(dir+13, buf+2, 19);
+			dir[DIR_Attr] = buf[0];
+			dj_old.fs->wflag = 1;
+			if (dir[DIR_Attr] & AM_DIR) {		/* Update .. entry in the directory if needed */
+				dw = clust2sect(dj_new.fs, (DWORD)LD_WORD(dir+DIR_FstClusHI) | LD_WORD(dir+DIR_FstClusLO));
+				if (!dw) {
+					res = FR_INT_ERR;
+				} else {
+					res = move_window(dj_new.fs, dw);
+					dir = dj_new.fs->win+32;
+					if (res == FR_OK && dir[1] == '.') {
+						dw = (dj_new.fs->fs_type == FS_FAT32 && dj_new.sclust == dj_new.fs->dirbase) ? 0 : dj_new.sclust;
+						ST_WORD(dir+DIR_FstClusLO, dw);
+						ST_WORD(dir+DIR_FstClusHI, dw >> 16);
+						dj_new.fs->wflag = 1;
+					}
+				}
+			}
+			if (res == FR_OK) {
+				res = dir_remove(&dj_old);			/* Remove old entry */
+				if (res == FR_OK)
+					res = sync(dj_old.fs);
+			}
+		}
+	}
+
+	LEAVE_FF(dj_old.fs, res);
+}
+
+#endif /* !_FS_READONLY */
+#endif /* _FS_MINIMIZE == 0 */
+#endif /* _FS_MINIMIZE <= 1 */
+#endif /* _FS_MINIMIZE <= 2 */
+
+
+
+/*-----------------------------------------------------------------------*/
+/* Forward data to the stream directly (Available on only _FS_TINY cfg)  */
+/*-----------------------------------------------------------------------*/
+#if _USE_FORWARD && _FS_TINY
+
+FRESULT f_forward (
+	FIL *fp, 						/* Pointer to the file object */
+	UINT (*func)(const BYTE*,UINT),	/* Pointer to the streaming function */
+	UINT btr,						/* Number of bytes to forward */
+	UINT *bf						/* Pointer to number of bytes forwarded */
+)
+{
+	FRESULT res;
+	DWORD remain, clst, sect;
+	UINT rcnt;
+
+
+	*bf = 0;
+
+	res = validate(fp->fs, fp->id);					/* Check validity of the object */
+	if (res != FR_OK) LEAVE_FF(fp->fs, res);
+	if (fp->flag & FA__ERROR)						/* Check error flag */
+		LEAVE_FF(fp->fs, FR_INT_ERR);
+	if (!(fp->flag & FA_READ))						/* Check access mode */
+		LEAVE_FF(fp->fs, FR_DENIED);
+
+	remain = fp->fsize - fp->fptr;
+	if (btr > remain) btr = (UINT)remain;			/* Truncate btr by remaining bytes */
+
+	for ( ;  btr && (*func)(NULL, 0);				/* Repeat until all data transferred or stream becomes busy */
+		fp->fptr += rcnt, *bf += rcnt, btr -= rcnt) {
+		if ((fp->fptr % SS(fp->fs)) == 0) {			/* On the sector boundary? */
+			if (fp->csect >= fp->fs->csize) {		/* On the cluster boundary? */
+				clst = (fp->fptr == 0) ?			/* On the top of the file? */
+					fp->org_clust : get_cluster(fp->fs, fp->curr_clust);
+				if (clst <= 1) ABORT(fp->fs, FR_INT_ERR);
+				if (clst == 0xFFFFFFFF) ABORT(fp->fs, FR_DISK_ERR);
+				fp->curr_clust = clst;				/* Update current cluster */
+				fp->csect = 0;						/* Reset sector address in the cluster */
+			}
+			fp->csect++;							/* Next sector address in the cluster */
+		}
+		sect = clust2sect(fp->fs, fp->curr_clust);	/* Get current data sector */
+		if (!sect) ABORT(fp->fs, FR_INT_ERR);
+		sect += fp->csect - 1;
+		if (move_window(fp->fs, sect))				/* Move sector window */
+			ABORT(fp->fs, FR_DISK_ERR);
+		fp->dsect = sect;
+		rcnt = SS(fp->fs) - (WORD)(fp->fptr % SS(fp->fs));	/* Forward data from sector window */
+		if (rcnt > btr) rcnt = btr;
+		rcnt = (*func)(&fp->fs->win[(WORD)fp->fptr % SS(fp->fs)], rcnt);
+		if (!rcnt) ABORT(fp->fs, FR_INT_ERR);
+	}
+
+	LEAVE_FF(fp->fs, FR_OK);
+}
+#endif /* _USE_FORWARD */
+
+
+
+#if _USE_MKFS && !_FS_READONLY
+/*-----------------------------------------------------------------------*/
+/* Create File System on the Drive                                       */
+/*-----------------------------------------------------------------------*/
+#define N_ROOTDIR	512			/* Multiple of 32 and <= 2048 */
+#define N_FATS		1			/* 1 or 2 */
+#define MAX_SECTOR	131072000UL	/* Maximum partition size */
+#ifndef MIN_SECTOR	/* ROI DEBUG */
+#define MIN_SECTOR	2000UL		/* Minimum partition size */
+#endif				/* ROI DEBUG */
+
+
+FRESULT f_mkfs (
+	BYTE drv,			/* Logical drive number */
+	BYTE partition,		/* Partitioning rule 0:FDISK, 1:SFD */
+	WORD allocsize		/* Allocation unit size [bytes] */
+)
+{
+	static const DWORD sstbl[] = { 2048000, 1024000, 512000, 256000, 128000, 64000, 32000, 16000, 8000, 4000,   0 };
+	static const WORD cstbl[] =  {   32768,   16384,   8192,   4096,   2048, 16384,  8192,  4096, 2048, 1024, 512 };
+	BYTE fmt, m, *tbl;
+	DWORD b_part, b_fat, b_dir, b_data;		/* Area offset (LBA) */
+	DWORD n_part, n_rsv, n_fat, n_dir;		/* Area size */
+	DWORD n_clst, n;
+	WORD as;
+	FATFS *fs;
+	DSTATUS stat;
+
+
+	/* Check validity of the parameters */
+	if (drv >= _DRIVES) return FR_INVALID_DRIVE;
+	if (partition >= 2) return FR_MKFS_ABORTED;
+
+	/* Check mounted drive and clear work area */
+	fs = FatFs[drv];
+	if (!fs) return FR_NOT_ENABLED;
+	fs->fs_type = 0;
+	drv = LD2PD(drv);
+
+	/* Get disk statics */
+	stat = disk_initialize(drv);
+	if (stat & STA_NOINIT) return FR_NOT_READY;
+	if (stat & STA_PROTECT) return FR_WRITE_PROTECTED;
+	if (disk_ioctl(drv, GET_SECTOR_COUNT, &n_part) != RES_OK || n_part < MIN_SECTOR)
+		return FR_MKFS_ABORTED;
+	if (n_part > MAX_SECTOR) n_part = MAX_SECTOR;
+	b_part = (!partition) ? 63 : 0;		/* Boot sector */
+	n_part -= b_part;
+#if _MAX_SS == 512
+	if (!allocsize) {					/* Auto selection of cluster size */
+		for (n = 0; n_part < sstbl[n]; n++) ;
+		allocsize = cstbl[n];
+	}
+#endif
+	for (as = 512; as <= 32768U && as != allocsize; as <<= 1);
+	if (as != allocsize) return FR_MKFS_ABORTED;
+#if _MAX_SS != 512						/* Check disk sector size */
+	if (disk_ioctl(drv, GET_SECTOR_SIZE, &SS(fs)) != RES_OK
+		|| SS(fs) > _MAX_SS
+		|| SS(fs) > allocsize)
+		return FR_MKFS_ABORTED;
+#endif
+	allocsize /= SS(fs);		/* Number of sectors per cluster */
+
+	/* Pre-compute number of clusters and FAT type */
+	n_clst = n_part / allocsize;
+	fmt = FS_FAT12;
+	if (n_clst >= 0xFF5) fmt = FS_FAT16;
+	if (n_clst >= 0xFFF5) fmt = FS_FAT32;
+
+	/* Determine offset and size of FAT structure */
+	switch (fmt) {
+	case FS_FAT12:
+		n_fat = ((n_clst * 3 + 1) / 2 + 3 + SS(fs) - 1) / SS(fs);
+		n_rsv = 1 + partition;
+		n_dir = N_ROOTDIR * 32 / SS(fs);
+		break;
+	case FS_FAT16:
+		n_fat = ((n_clst * 2) + 4 + SS(fs) - 1) / SS(fs);
+		n_rsv = 1 + partition;
+		n_dir = N_ROOTDIR * 32 / SS(fs);
+		break;
+	default:
+		n_fat = ((n_clst * 4) + 8 + SS(fs) - 1) / SS(fs);
+		n_rsv = 33 - partition;
+		n_dir = 0;
+	}
+	b_fat = b_part + n_rsv;			/* FATs start sector */
+	b_dir = b_fat + n_fat * N_FATS;	/* Directory start sector */
+	b_data = b_dir + n_dir;			/* Data start sector */
+
+	/* Align data start sector to erase block boundary (for flash memory media) */
+	if (disk_ioctl(drv, GET_BLOCK_SIZE, &n) != RES_OK) return FR_MKFS_ABORTED;
+	n = (b_data + n - 1) & ~(n - 1);
+	n_fat += (n - b_data) / N_FATS;
+	/* b_dir and b_data are no longer used below */
+
+	/* Determine number of cluster and final check of validity of the FAT type */
+	n_clst = (n_part - n_rsv - n_fat * N_FATS - n_dir) / allocsize;
+	if (   (fmt == FS_FAT16 && n_clst < 0xFF5)
+		|| (fmt == FS_FAT32 && n_clst < 0xFFF5))
+		return FR_MKFS_ABORTED;
+
+	/* Create partition table if needed */
+	if (!partition) {
+		DWORD n_disk = b_part + n_part;
+
+		tbl = fs->win+MBR_Table;
+		ST_DWORD(tbl, 0x00010180);		/* Partition start in CHS */
+		if (n_disk < 63UL * 255 * 1024) {	/* Partition end in CHS */
+			n_disk = n_disk / 63 / 255;
+			tbl[7] = (BYTE)n_disk;
+			tbl[6] = (BYTE)((n_disk >> 2) | 63);
+		} else {
+			ST_WORD(&tbl[6], 0xFFFF);
+		}
+		tbl[5] = 254;
+		if (fmt != FS_FAT32)			/* System ID */
+			tbl[4] = (n_part < 0x10000) ? 0x04 : 0x06;
+		else
+			tbl[4] = 0x0c;
+		ST_DWORD(tbl+8, 63);			/* Partition start in LBA */
+		ST_DWORD(tbl+12, n_part);		/* Partition size in LBA */
+		ST_WORD(tbl+64, 0xAA55);		/* Signature */
+		if (disk_write(drv, fs->win, 0, 1) != RES_OK)
+			return FR_DISK_ERR;
+	}
+
+	/* Create boot record */
+	tbl = fs->win;								/* Clear buffer */
+	mem_set(tbl, 0, SS(fs));
+	ST_DWORD(tbl+BS_jmpBoot, 0x90FEEB);			/* Boot code (jmp $, nop) */
+	ST_WORD(tbl+BPB_BytsPerSec, SS(fs));		/* Sector size */
+	tbl[BPB_SecPerClus] = (BYTE)allocsize;		/* Sectors per cluster */
+	ST_WORD(tbl+BPB_RsvdSecCnt, n_rsv);			/* Reserved sectors */
+	tbl[BPB_NumFATs] = N_FATS;					/* Number of FATs */
+	ST_WORD(tbl+BPB_RootEntCnt, SS(fs) / 32 * n_dir); /* Number of rootdir entries */
+	if (n_part < 0x10000) {						/* Number of total sectors */
+		ST_WORD(tbl+BPB_TotSec16, n_part);
+	} else {
+		ST_DWORD(tbl+BPB_TotSec32, n_part);
+	}
+	tbl[BPB_Media] = 0xF8;						/* Media descripter */
+	ST_WORD(tbl+BPB_SecPerTrk, 63);				/* Number of sectors per track */
+	ST_WORD(tbl+BPB_NumHeads, 255);				/* Number of heads */
+	ST_DWORD(tbl+BPB_HiddSec, b_part);			/* Hidden sectors */
+	n = get_fattime();							/* Use current time as a VSN */
+	if (fmt != FS_FAT32) {
+		ST_DWORD(tbl+BS_VolID, n);				/* Volume serial number */
+		ST_WORD(tbl+BPB_FATSz16, n_fat);		/* Number of secters per FAT */
+		tbl[BS_DrvNum] = 0x80;					/* Drive number */
+		tbl[BS_BootSig] = 0x29;					/* Extended boot signature */
+		mem_cpy(tbl+BS_VolLab, "NO NAME    FAT     ", 19);	/* Volume lavel, FAT signature */
+	} else {
+		ST_DWORD(tbl+BS_VolID32, n);			/* Volume serial number */
+		ST_DWORD(tbl+BPB_FATSz32, n_fat);		/* Number of secters per FAT */
+		ST_DWORD(tbl+BPB_RootClus, 2);			/* Root directory cluster (2) */
+		ST_WORD(tbl+BPB_FSInfo, 1);				/* FSInfo record offset (bs+1) */
+		ST_WORD(tbl+BPB_BkBootSec, 6);			/* Backup boot record offset (bs+6) */
+		tbl[BS_DrvNum32] = 0x80;				/* Drive number */
+		tbl[BS_BootSig32] = 0x29;				/* Extended boot signature */
+		mem_cpy(tbl+BS_VolLab32, "NO NAME    FAT32   ", 19);	/* Volume lavel, FAT signature */
+	}
+	ST_WORD(tbl+BS_55AA, 0xAA55);				/* Signature */
+	if (disk_write(drv, tbl, b_part+0, 1) != RES_OK)
+		return FR_DISK_ERR;
+	if (fmt == FS_FAT32)
+		disk_write(drv, tbl, b_part+6, 1);
+
+	/* Initialize FAT area */
+	for (m = 0; m < N_FATS; m++) {
+		mem_set(tbl, 0, SS(fs));		/* 1st sector of the FAT  */
+		if (fmt != FS_FAT32) {
+			n = (fmt == FS_FAT12) ? 0x00FFFFF8 : 0xFFFFFFF8;
+			ST_DWORD(tbl, n);				/* Reserve cluster #0-1 (FAT12/16) */
+		} else {
+			ST_DWORD(tbl+0, 0xFFFFFFF8);	/* Reserve cluster #0-1 (FAT32) */
+			ST_DWORD(tbl+4, 0xFFFFFFFF);
+			ST_DWORD(tbl+8, 0x0FFFFFFF);	/* Reserve cluster #2 for root dir */
+		}
+		if (disk_write(drv, tbl, b_fat++, 1) != RES_OK)
+			return FR_DISK_ERR;
+		mem_set(tbl, 0, SS(fs));		/* Following FAT entries are filled by zero */
+		for (n = 1; n < n_fat; n++) {
+			if (disk_write(drv, tbl, b_fat++, 1) != RES_OK)
+				return FR_DISK_ERR;
+		}
+	}
+
+	/* Initialize Root directory */
+	m = (BYTE)((fmt == FS_FAT32) ? allocsize : n_dir);
+	do {
+		if (disk_write(drv, tbl, b_fat++, 1) != RES_OK)
+			return FR_DISK_ERR;
+	} while (--m);
+
+	/* Create FSInfo record if needed */
+	if (fmt == FS_FAT32) {
+		ST_WORD(tbl+BS_55AA, 0xAA55);
+		ST_DWORD(tbl+FSI_LeadSig, 0x41615252);
+		ST_DWORD(tbl+FSI_StrucSig, 0x61417272);
+		ST_DWORD(tbl+FSI_Free_Count, n_clst - 1);
+		ST_DWORD(tbl+FSI_Nxt_Free, 0xFFFFFFFF);
+		disk_write(drv, tbl, b_part+1, 1);
+		disk_write(drv, tbl, b_part+7, 1);
+	}
+
+	return (disk_ioctl(drv, CTRL_SYNC, (void*)NULL) == RES_OK) ? FR_OK : FR_DISK_ERR;
+}
+
+#endif /* _USE_MKFS && !_FS_READONLY */
+
+
+
+
+#if _USE_STRFUNC
+/*-----------------------------------------------------------------------*/
+/* Get a string from the file                                            */
+/*-----------------------------------------------------------------------*/
+char* f_gets (
+	char* buff,	/* Pointer to the string buffer to read */
+	int len,	/* Size of string buffer */
+	FIL* fil	/* Pointer to the file object */
+)
+{
+	int i = 0;
+	char *p = buff;
+	UINT rc;
+
+
+	while (i < len - 1) {			/* Read bytes until buffer gets filled */
+		f_read(fil, p, 1, &rc);
+		if (rc != 1) break;			/* Break when no data to read */
+#if _USE_STRFUNC >= 2
+		if (*p == '\r') continue;	/* Strip '\r' */
+#endif
+		i++;
+		if (*p++ == '\n') break;	/* Break when reached end of line */
+	}
+	*p = 0;
+	return i ? buff : NULL;			/* When no data read (eof or error), return with error. */
+}
+
+
+
+#if !_FS_READONLY
+#include <stdarg.h>
+/*-----------------------------------------------------------------------*/
+/* Put a character to the file                                           */
+/*-----------------------------------------------------------------------*/
+int f_putc (
+	int chr,	/* A character to be output */
+	FIL* fil	/* Ponter to the file object */
+)
+{
+	UINT bw;
+	char c;
+
+
+#if _USE_STRFUNC >= 2
+	if (chr == '\n') f_putc ('\r', fil);	/* LF -> CRLF conversion */
+#endif
+	if (!fil) {	/* Special value may be used to switch the destination to any other device */
+	/*	put_console(chr);	*/
+		return chr;
+	}
+	c = (char)chr;
+	f_write(fil, &c, 1, &bw);	/* Write a byte to the file */
+	return bw ? chr : EOF;		/* Return the result */
+}
+
+
+
+
+/*-----------------------------------------------------------------------*/
+/* Put a string to the file                                              */
+/*-----------------------------------------------------------------------*/
+int f_puts (
+	const char* str,	/* Pointer to the string to be output */
+	FIL* fil			/* Pointer to the file object */
+)
+{
+	int n;
+
+
+	for (n = 0; *str; str++, n++) {
+		if (f_putc(*str, fil) == EOF) return EOF;
+	}
+	return n;
+}
+
+
+
+
+/*-----------------------------------------------------------------------*/
+/* Put a formatted string to the file                                    */
+/*-----------------------------------------------------------------------*/
+int f_printf (
+	FIL* fil,			/* Pointer to the file object */
+	const char* str,	/* Pointer to the format string */
+	...					/* Optional arguments... */
+)
+{
+	va_list arp;
+	UCHAR c, f, r;
+	ULONG val;
+	char s[16];
+	int i, w, res, cc;
+
+
+	va_start(arp, str);
+
+	for (cc = res = 0; cc != EOF; res += cc) {
+		c = *str++;
+		if (c == 0) break;			/* End of string */
+		if (c != '%') {				/* Non escape cahracter */
+			cc = f_putc(c, fil);
+			if (cc != EOF) cc = 1;
+			continue;
+		}
+		w = f = 0;
+		c = *str++;
+		if (c == '0') {				/* Flag: '0' padding */
+			f = 1; c = *str++;
+		}
+		while (c >= '0' && c <= '9') {	/* Precision */
+			w = w * 10 + (c - '0');
+			c = *str++;
+		}
+		if (c == 'l') {				/* Prefix: Size is long int */
+			f |= 2; c = *str++;
+		}
+		if (c == 's') {				/* Type is string */
+			cc = f_puts(va_arg(arp, char*), fil);
+			continue;
+		}
+		if (c == 'c') {				/* Type is character */
+			cc = f_putc(va_arg(arp, int), fil);
+			if (cc != EOF) cc = 1;
+			continue;
+		}
+		r = 0;
+		if (c == 'd') r = 10;		/* Type is signed decimal */
+		if (c == 'u') r = 10;		/* Type is unsigned decimal */
+		if (c == 'X') r = 16;		/* Type is unsigned hexdecimal */
+		if (r == 0) break;			/* Unknown type */
+		if (f & 2) {				/* Get the value */
+			val = (ULONG)va_arg(arp, long);
+		} else {
+			val = (c == 'd') ? (ULONG)(long)va_arg(arp, int) : (ULONG)va_arg(arp, unsigned int);
+		}
+		/* Put numeral string */
+		if (c == 'd') {
+			if (val & 0x80000000) {
+				val = 0 - val;
+				f |= 4;
+			}
+		}
+		i = sizeof(s) - 1; s[i] = 0;
+		do {
+			c = (UCHAR)(val % r + '0');
+			if (c > '9') c += 7;
+			s[--i] = c;
+			val /= r;
+		} while (i && val);
+		if (i && (f & 4)) s[--i] = '-';
+		w = sizeof(s) - 1 - w;
+		while (i && i > w) s[--i] = (f & 1) ? '0' : ' ';
+		cc = f_puts(&s[i], fil);
+	}
+
+	va_end(arp);
+	return (cc == EOF) ? cc : res;
+}
+
+#endif /* !_FS_READONLY */
+#endif /* _USE_STRFUNC */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/files/ff/ff.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/files/ff/ff.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/files/ff/ff.h	(revision 457)
@@ -0,0 +1,553 @@
+/*---------------------------------------------------------------------------/
+/  FatFs - FAT file system module include file  R0.07a       (C)ChaN, 2009
+/----------------------------------------------------------------------------/
+/ FatFs module is an open source software to implement FAT file system to
+/ small embedded systems. This is a free software and is opened for education,
+/ research and commercial developments under license policy of following trems.
+/
+/  Copyright (C) 2009, ChaN, all right reserved.
+/
+/ * The FatFs module is a free software and there is NO WARRANTY.
+/ * No restriction on use. You can use, modify and redistribute it for
+/   personal, non-profit or commercial use UNDER YOUR RESPONSIBILITY.
+/ * Redistributions of source code must retain the above copyright notice.
+/----------------------------------------------------------------------------*/
+
+#include "integer.h"
+
+/*---------------------------------------------------------------------------/
+/ FatFs Configuration Options
+/
+/ CAUTION! Do not forget to make clean the project after any changes to
+/ the configuration options.
+/
+/----------------------------------------------------------------------------*/
+#ifndef _FATFS
+#define _FATFS
+
+#define _WORD_ACCESS	0
+/* The _WORD_ACCESS option defines which access method is used to the word
+/  data in the FAT structure.
+/
+/   0: Byte-by-byte access. Always compatible with all platforms.
+/   1: Word access. Do not choose this unless following condition is met.
+/
+/  When the byte order on the memory is big-endian or address miss-aligned
+/  word access results incorrect behavior, the _WORD_ACCESS must be set to 0.
+/  If it is not the case, the value can also be set to 1 to improve the
+/  performance and code efficiency. */
+
+
+#define _FS_READONLY	0
+/* Setting _FS_READONLY to 1 defines read only configuration. This removes
+/  writing functions, f_write, f_sync, f_unlink, f_mkdir, f_chmod, f_rename,
+/  f_truncate and useless f_getfree. */
+
+
+#define _FS_MINIMIZE	0
+/* The _FS_MINIMIZE option defines minimization level to remove some functions.
+/
+/   0: Full function.
+/   1: f_stat, f_getfree, f_unlink, f_mkdir, f_chmod, f_truncate and f_rename
+/      are removed.
+/   2: f_opendir and f_readdir are removed in addition to level 1.
+/   3: f_lseek is removed in addition to level 2. */
+
+
+#define	_FS_TINY	0
+/* When _FS_TINY is set to 1, FatFs uses the sector buffer in the file system
+/  object instead of the sector buffer in the individual file object for file
+/  data transfer. This reduces memory consumption 512 bytes each file object. */
+
+
+#define	_USE_STRFUNC	0
+/* To enable string functions, set _USE_STRFUNC to 1 or 2. */
+
+
+#define	_USE_MKFS	1
+/* To enable f_mkfs function, set _USE_MKFS to 1 and set _FS_READONLY to 0 */
+
+
+#define	_USE_FORWARD	0
+/* To enable f_forward function, set _USE_FORWARD to 1 and set _FS_TINY to 1. */
+
+
+#ifndef _DRIVES
+#define _DRIVES		1
+#endif
+/* Number of volumes (logical drives) to be used. */
+
+
+#define	_MAX_SS	512
+/* Maximum sector size to be handled. (512/1024/2048/4096) */
+/* 512 for memroy card and hard disk, 1024 for floppy disk, 2048 for MO disk */
+
+
+#define	_MULTI_PARTITION	0
+/* When _MULTI_PARTITION is set to 0, each volume is bound to the same physical
+/ drive number and can mount only first primaly partition. When it is set to 1,
+/ each volume is tied to the partitions listed in Drives[]. */
+
+
+#define _CODE_PAGE	932
+/* The _CODE_PAGE specifies the OEM code page to be used on the target system.
+/  When it is non LFN configuration, there is no difference between SBCS code
+/  pages. When LFN is enabled, the code page must always be set correctly.
+/   437 - U.S.
+/   720 - Arabic
+/   737 - Greek
+/   775 - Baltic
+/   850 - Multilingual Latin 1
+/   852 - Latin 2
+/   855 - Cyrillic
+/   857 - Turkish
+/   858 - Multilingual Latin 1 + Euro
+/   862 - Hebrew
+/   866 - Russian
+/   874 - Thai
+/   932 - Japanese Shift-JIS       (DBCS)
+/   936 - Simplified Chinese GBK   (DBCS)
+/   949 - Korean                   (DBCS)
+/   950 - Traditional Chinese Big5 (DBCS)
+/   1258 - Vietnam
+*/
+
+
+#define	_USE_LFN	2
+#define	_MAX_LFN	255		/* Maximum LFN length to handle (max:255) */
+/* The _USE_LFN option switches the LFN support.
+/
+/   0: Disable LFN.
+/   1: Enable LFN with static working buffer on the bss. NOT REENTRANT.
+/   2: Enable LFN with dynamic working buffer on the caller's STACK.
+/
+/  The working buffer occupies (_MAX_LFN + 1) * 2 bytes. When enable LFN,
+/  a Unicode - OEM code conversion function ff_convert() must be added to
+/  the project. */
+
+
+#define _FS_REENTRANT	1
+#define _TIMEOUT		1000	/* Timeout period in unit of time ticks */
+#define	_SYNC_t			int		/* Type of sync object used on the OS. */
+								/* e.g. HANDLE, OS_EVENT*, ID and etc.. */
+/* To make the FatFs module re-entrant, set _FS_REENTRANT to 1 and add user
+/  provided synchronization handlers, ff_req_grant, ff_rel_grant,
+/  ff_del_syncobj and ff_cre_syncobj function to the project. */
+
+
+
+
+/* End of configuration options. Do not change followings without care.     */
+/*--------------------------------------------------------------------------*/
+
+
+
+/* Definitions corresponds to multiple sector size */
+
+#if _MAX_SS == 512
+#define	SS(fs)	512
+#else
+#if _MAX_SS == 1024 || _MAX_SS == 2048 || _MAX_SS == 4096
+#define	SS(fs)	((fs)->s_size)
+#else
+#error Sector size must be 512, 1024, 2048 or 4096.
+#endif
+#endif
+
+
+
+/* File system object structure */
+
+typedef struct _FATFS {
+	BYTE	fs_type;	/* FAT sub type */
+	BYTE	drive;		/* Physical drive number */
+	BYTE	csize;		/* Number of sectors per cluster */
+	BYTE	n_fats;		/* Number of FAT copies */
+	BYTE	wflag;		/* win[] dirty flag (1:must be written back) */
+	BYTE	pad1;
+	WORD	id;			/* File system mount ID */
+	WORD	n_rootdir;	/* Number of root directory entries (0 on FAT32) */
+#if _FS_REENTRANT
+	_SYNC_t	sobj;		/* Identifier of sync object */
+#endif
+#if _MAX_SS != 512U
+	WORD	s_size;		/* Sector size */
+#endif
+#if !_FS_READONLY
+	BYTE	fsi_flag;	/* fsinfo dirty flag (1:must be written back) */
+	BYTE	pad2;
+	DWORD	last_clust;	/* Last allocated cluster */
+	DWORD	free_clust;	/* Number of free clusters */
+	DWORD	fsi_sector;	/* fsinfo sector */
+#endif
+	DWORD	sects_fat;	/* Sectors per fat */
+	DWORD	max_clust;	/* Maximum cluster# + 1. Number of clusters is max_clust - 2 */
+	DWORD	fatbase;	/* FAT start sector */
+	DWORD	dirbase;	/* Root directory start sector (Cluster# on FAT32) */
+	DWORD	database;	/* Data start sector */
+	DWORD	winsect;	/* Current sector appearing in the win[] */
+#if 1	/* ROI DEBUG */
+	DWORD   dummy[2];	/* cache aline */
+#endif	/* ROI DEBUG */
+	BYTE	win[_MAX_SS];/* Disk access window for Directory/FAT */
+} FATFS;
+
+
+
+/* Directory object structure */
+
+typedef struct _DIR {
+	WORD	id;			/* Owner file system mount ID */
+	WORD	index;		/* Current index number */
+	FATFS*	fs;			/* Pointer to the owner file system object */
+	DWORD	sclust;		/* Table start cluster (0:Static table) */
+	DWORD	clust;		/* Current cluster */
+	DWORD	sect;		/* Current sector */
+	BYTE*	dir;		/* Pointer to the current SFN entry in the win[] */
+	BYTE*	fn;			/* Pointer to the SFN (in/out) {file[8],ext[3],status[1]} */
+#if _USE_LFN
+	WCHAR*	lfn;		/* Pointer to the LFN working buffer */
+	WORD	lfn_idx;	/* Last matched LFN index (0xFFFF:No LFN) */
+#endif
+} DIR;
+
+
+
+/* File object structure */
+
+typedef struct _FIL {
+	FATFS*	fs;			/* Pointer to the owner file system object */
+	WORD	id;			/* Owner file system mount ID */
+	BYTE	flag;		/* File status flags */
+	BYTE	csect;		/* Sector address in the cluster */
+	DWORD	fptr;		/* File R/W pointer */
+	DWORD	fsize;		/* File size */
+	DWORD	org_clust;	/* File start cluster */
+	DWORD	curr_clust;	/* Current cluster */
+	DWORD	dsect;		/* Current data sector */
+#if !_FS_READONLY
+	DWORD	dir_sect;	/* Sector containing the directory entry */
+	BYTE*	dir_ptr;	/* Ponter to the directory entry in the window */
+#endif
+#if !_FS_TINY
+	BYTE	buf[_MAX_SS];/* File R/W buffer */
+#endif
+} FIL;
+
+
+
+/* File status structure */
+
+typedef struct _FILINFO {
+	DWORD fsize;		/* File size */
+	WORD fdate;			/* Last modified date */
+	WORD ftime;			/* Last modified time */
+	BYTE fattrib;		/* Attribute */
+	char fname[13];		/* Short file name (8.3 format) */
+#if _USE_LFN
+	char *lfname;		/* Pointer to the LFN buffer */
+	int lfsize;			/* Size of LFN buffer [bytes] */
+#endif
+} FILINFO;
+
+
+
+/* DBCS code ranges */
+
+#if _CODE_PAGE == 932	/* CP932 (Japanese Shift-JIS) */
+#define _DF1S	0x81	/* DBC 1st byte range 1 start */
+#define _DF1E	0x9F	/* DBC 1st byte range 1 end */
+#define _DF2S	0xE0	/* DBC 1st byte range 2 start */
+#define _DF2E	0xFC	/* DBC 1st byte range 2 end */
+#define _DS1S	0x40	/* DBC 2nd byte range 1 start */
+#define _DS1E	0x7E	/* DBC 2nd byte range 1 end */
+#define _DS2S	0x80	/* DBC 2nd byte range 2 start */
+#define _DS2E	0xFC	/* DBC 2nd byte range 2 end */
+
+#elif _CODE_PAGE == 936	/* CP936 (Simplified Chinese GBK) */
+#define _DF1S	0x81
+#define _DF1E	0xFE
+#define _DS1S	0x40
+#define _DS1E	0x7E
+#define _DS2S	0x80
+#define _DS2E	0xFE
+
+#elif _CODE_PAGE == 949	/* CP949 (Korean) */
+#define _DF1S	0x81
+#define _DF1E	0xFE
+#define _DS1S	0x41
+#define _DS1E	0x5A
+#define _DS2S	0x61
+#define _DS2E	0x7A
+#define _DS3S	0x81
+#define _DS3E	0xFE
+
+#elif _CODE_PAGE == 950	/* CP950 (Traditional Chinese Big5) */
+#define _DF1S	0x81
+#define _DF1E	0xFE
+#define _DS1S	0x40
+#define _DS1E	0x7E
+#define _DS2S	0xA1
+#define _DS2E	0xFE
+
+#else					/* SBCS code pages */
+#define _DF1S	0
+
+#endif
+
+
+
+/* Character code support macros */
+
+#define IsUpper(c)	(((c)>='A')&&((c)<='Z'))
+#define IsLower(c)	(((c)>='a')&&((c)<='z'))
+#define IsDigit(c)	(((c)>='0')&&((c)<='9'))
+
+#if _DF1S	/* DBCS configuration */
+
+#if _DF2S	/* Two 1st byte areas */
+#define IsDBCS1(c)	(((BYTE)(c) >= _DF1S && (BYTE)(c) <= _DF1E) || ((BYTE)(c) >= _DF2S && (BYTE)(c) <= _DF2E))
+#else		/* One 1st byte area */
+#define IsDBCS1(c)	((BYTE)(c) >= _DF1S && (BYTE)(c) <= _DF1E)
+#endif
+
+#if _DS3S	/* Three 2nd byte areas */
+#define IsDBCS2(c)	(((BYTE)(c) >= _DS1S && (BYTE)(c) <= _DS1E) || ((BYTE)(c) >= _DS2S && (BYTE)(c) <= _DS2E) || ((BYTE)(c) >= _DS3S && (BYTE)(c) <= _DS3E))
+#else		/* Two 2nd byte areas */
+#define IsDBCS2(c)	(((BYTE)(c) >= _DS1S && (BYTE)(c) <= _DS1E) || ((BYTE)(c) >= _DS2S && (BYTE)(c) <= _DS2E))
+#endif
+
+#else		/* SBCS configuration */
+
+#define IsDBCS1(c)	0
+#define IsDBCS2(c)	0
+
+#endif /* _DF1S */
+
+
+
+/* Definitions corresponds to multi partition */
+
+#if _MULTI_PARTITION		/* Multiple partition configuration */
+
+typedef struct _PARTITION {
+	BYTE pd;	/* Physical drive# */
+	BYTE pt;	/* Partition # (0-3) */
+} PARTITION;
+
+extern
+const PARTITION Drives[];			/* Logical drive# to physical location conversion table */
+#define LD2PD(drv) (Drives[drv].pd)	/* Get physical drive# */
+#define LD2PT(drv) (Drives[drv].pt)	/* Get partition# */
+
+#else						/* Single partition configuration */
+
+#define LD2PD(drv) (drv)	/* Physical drive# is equal to the logical drive# */
+#define LD2PT(drv) 0		/* Always mounts the 1st partition */
+
+#endif
+
+
+
+/* File function return code (FRESULT) */
+
+typedef enum {
+	FR_OK = 0,			/* 0 */
+	FR_DISK_ERR,		/* 1 */
+	FR_INT_ERR,			/* 2 */
+	FR_NOT_READY,		/* 3 */
+	FR_NO_FILE,			/* 4 */
+	FR_NO_PATH,			/* 5 */
+	FR_INVALID_NAME,	/* 6 */
+	FR_DENIED,			/* 7 */
+	FR_EXIST,			/* 8 */
+	FR_INVALID_OBJECT,	/* 9 */
+	FR_WRITE_PROTECTED,	/* 10 */
+	FR_INVALID_DRIVE,	/* 11 */
+	FR_NOT_ENABLED,		/* 12 */
+	FR_NO_FILESYSTEM,	/* 13 */
+	FR_MKFS_ABORTED,	/* 14 */
+	FR_TIMEOUT			/* 15 */
+} FRESULT;
+
+
+
+/*--------------------------------------------------------------*/
+/* FatFs module application interface                           */
+
+FRESULT f_mount (BYTE, FATFS*);						/* Mount/Unmount a logical drive */
+FRESULT f_open (FIL*, const char*, BYTE);			/* Open or create a file */
+FRESULT f_read (FIL*, void*, UINT, UINT*);			/* Read data from a file */
+FRESULT f_write (FIL*, const void*, UINT, UINT*);	/* Write data to a file */
+FRESULT f_lseek (FIL*, DWORD);						/* Move file pointer of a file object */
+FRESULT f_close (FIL*);								/* Close an open file object */
+FRESULT f_opendir (DIR*, const char*);				/* Open an existing directory */
+FRESULT f_readdir (DIR*, FILINFO*);					/* Read a directory item */
+FRESULT f_stat (const char*, FILINFO*);				/* Get file status */
+FRESULT f_getfree (const char*, DWORD*, FATFS**);	/* Get number of free clusters on the drive */
+FRESULT f_truncate (FIL*);							/* Truncate file */
+FRESULT f_sync (FIL*);								/* Flush cached data of a writing file */
+FRESULT f_unlink (const char*);						/* Delete an existing file or directory */
+FRESULT	f_mkdir (const char*);						/* Create a new directory */
+FRESULT f_chmod (const char*, BYTE, BYTE);			/* Change attriburte of the file/dir */
+FRESULT f_utime (const char*, const FILINFO*);		/* Change timestamp of the file/dir */
+FRESULT f_rename (const char*, const char*);		/* Rename/Move a file or directory */
+FRESULT f_forward (FIL*, UINT(*)(const BYTE*,UINT), UINT, UINT*);	/* Forward data to the stream */
+FRESULT f_mkfs (BYTE, BYTE, WORD);					/* Create a file system on the drive */
+
+#if _USE_STRFUNC
+int f_putc (int, FIL*);								/* Put a character to the file */
+int f_puts (const char*, FIL*);						/* Put a string to the file */
+int f_printf (FIL*, const char*, ...);				/* Put a formatted string to the file */
+char* f_gets (char*, int, FIL*);					/* Get a string from the file */
+#define f_eof(fp) (((fp)->fptr == (fp)->fsize) ? 1 : 0)
+#define f_error(fp) (((fp)->flag & FA__ERROR) ? 1 : 0)
+#ifndef EOF
+#define EOF -1
+#endif
+#endif
+
+
+
+/*--------------------------------------------------------------*/
+/* User defined functions                                       */
+
+/* Real time clock */
+#if !_FS_READONLY
+DWORD get_fattime (void);	/* 31-25: Year(0-127 org.1980), 24-21: Month(1-12), 20-16: Day(1-31) */
+							/* 15-11: Hour(0-23), 10-5: Minute(0-59), 4-0: Second(0-29 *2) */
+#endif
+
+/* Unicode - OEM code conversion */
+#if _USE_LFN
+WCHAR ff_convert (WCHAR, UINT);
+#endif
+
+/* Sync functions */
+#if _FS_REENTRANT
+BOOL ff_cre_syncobj(BYTE, _SYNC_t*);
+BOOL ff_del_syncobj(_SYNC_t);
+BOOL ff_req_grant(_SYNC_t);
+void ff_rel_grant(_SYNC_t);
+#endif
+
+
+
+/*--------------------------------------------------------------*/
+/* Flags and offset address                                     */
+
+
+/* File access control and file status flags (FIL.flag) */
+
+#define	FA_READ				0x01
+#define	FA_OPEN_EXISTING	0x00
+#if _FS_READONLY == 0
+#define	FA_WRITE			0x02
+#define	FA_CREATE_NEW		0x04
+#define	FA_CREATE_ALWAYS	0x08
+#define	FA_OPEN_ALWAYS		0x10
+#define FA__WRITTEN			0x20
+#define FA__DIRTY			0x40
+#endif
+#define FA__ERROR			0x80
+
+
+/* FAT sub type (FATFS.fs_type) */
+
+#define FS_FAT12	1
+#define FS_FAT16	2
+#define FS_FAT32	3
+
+
+/* File attribute bits for directory entry */
+
+#define	AM_RDO	0x01	/* Read only */
+#define	AM_HID	0x02	/* Hidden */
+#define	AM_SYS	0x04	/* System */
+#define	AM_VOL	0x08	/* Volume label */
+#define AM_LFN	0x0F	/* LFN entry */
+#define AM_DIR	0x10	/* Directory */
+#define AM_ARC	0x20	/* Archive */
+#define AM_MASK	0x3F	/* Mask of defined bits */
+
+
+/* FatFs refers the members in the FAT structures with byte offset instead
+/ of structure member because there are incompatibility of the packing option
+/ between various compilers. */
+
+#define BS_jmpBoot			0
+#define BS_OEMName			3
+#define BPB_BytsPerSec		11
+#define BPB_SecPerClus		13
+#define BPB_RsvdSecCnt		14
+#define BPB_NumFATs			16
+#define BPB_RootEntCnt		17
+#define BPB_TotSec16		19
+#define BPB_Media			21
+#define BPB_FATSz16			22
+#define BPB_SecPerTrk		24
+#define BPB_NumHeads		26
+#define BPB_HiddSec			28
+#define BPB_TotSec32		32
+#define BS_55AA				510
+
+#define BS_DrvNum			36
+#define BS_BootSig			38
+#define BS_VolID			39
+#define BS_VolLab			43
+#define BS_FilSysType		54
+
+#define BPB_FATSz32			36
+#define BPB_ExtFlags		40
+#define BPB_FSVer			42
+#define BPB_RootClus		44
+#define BPB_FSInfo			48
+#define BPB_BkBootSec		50
+#define BS_DrvNum32			64
+#define BS_BootSig32		66
+#define BS_VolID32			67
+#define BS_VolLab32			71
+#define BS_FilSysType32		82
+
+#define	FSI_LeadSig			0
+#define	FSI_StrucSig		484
+#define	FSI_Free_Count		488
+#define	FSI_Nxt_Free		492
+
+#define MBR_Table			446
+
+#define	DIR_Name			0
+#define	DIR_Attr			11
+#define	DIR_NTres			12
+#define	DIR_CrtTime			14
+#define	DIR_CrtDate			16
+#define	DIR_FstClusHI		20
+#define	DIR_WrtTime			22
+#define	DIR_WrtDate			24
+#define	DIR_FstClusLO		26
+#define	DIR_FileSize		28
+#define	LDIR_Ord			0
+#define	LDIR_Attr			11
+#define	LDIR_Type			12
+#define	LDIR_Chksum			13
+#define	LDIR_FstClusLO		26
+
+
+
+/*--------------------------------*/
+/* Multi-byte word access macros  */
+
+#if _WORD_ACCESS == 1	/* Enable word access to the FAT structure */
+#define	LD_WORD(ptr)		(WORD)(*(WORD*)(BYTE*)(ptr))
+#define	LD_DWORD(ptr)		(DWORD)(*(DWORD*)(BYTE*)(ptr))
+#define	ST_WORD(ptr,val)	*(WORD*)(BYTE*)(ptr)=(WORD)(val)
+#define	ST_DWORD(ptr,val)	*(DWORD*)(BYTE*)(ptr)=(DWORD)(val)
+#else					/* Use byte-by-byte access to the FAT structure */
+#define	LD_WORD(ptr)		(WORD)(((WORD)*(BYTE*)((ptr)+1)<<8)|(WORD)*(BYTE*)(ptr))
+#define	LD_DWORD(ptr)		(DWORD)(((DWORD)*(BYTE*)((ptr)+3)<<24)|((DWORD)*(BYTE*)((ptr)+2)<<16)|((WORD)*(BYTE*)((ptr)+1)<<8)|*(BYTE*)(ptr))
+#define	ST_WORD(ptr,val)	*(BYTE*)(ptr)=(BYTE)(val); *(BYTE*)((ptr)+1)=(BYTE)((WORD)(val)>>8)
+#define	ST_DWORD(ptr,val)	*(BYTE*)(ptr)=(BYTE)(val); *(BYTE*)((ptr)+1)=(BYTE)((WORD)(val)>>8); *(BYTE*)((ptr)+2)=(BYTE)((DWORD)(val)>>16); *(BYTE*)((ptr)+3)=(BYTE)((DWORD)(val)>>24)
+#endif
+
+
+#endif /* _FATFS */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/files/ff/fffcntl.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/files/ff/fffcntl.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/files/ff/fffcntl.c	(revision 457)
@@ -0,0 +1,492 @@
+/*
+ *  TOPPERS/ASP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Advanced Standard Profile Kernel
+ * 
+ *  Copyright (C) 2012 by GT Development Center RICOH COMPANY,LTD. JAPAN
+ * 
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ * FatFS用POSIX変換用関数
+ * 1. ff_opendir               FatFSファイルのオープンディレクトリ
+ * 2. ff_closedir              FatFSファイルのクローズディレクトリ
+ * 3. ff_readdir               FatFSファイルのディレクトリエントリ読み出し
+ * 4. ff_mkdir                 FatFSファイルのディレクトリ作成
+ * 5. ff_unlink                FatFSファイルのディレクトリまたはファイル削除
+ * 6. ff_rename                FatFSファイルのリネーム
+ * 7. ff_chmod                 FatFSファイルのチェンジモード
+ * 8. ff_stat                  FatFSファイルのダイレクトステートの取り出し
+ * 9. ff_statfs                FatFSファイルのシステムステータスの取り出し
+ * 10.ff_open                  FatFSファイルのオープン
+ * 11.ff_close                 FatFSファイルのクローズ
+ * 12.ff_fstat                 FatFSファイルのステートの取り出し
+ * 13.ff_fseek                 FatFSファイルのシーク
+ * 14.ff_read                  FatFSファイルからのデータ読み出し
+ * 15.ff_write                 FatFSファイルへのデータ書き込み
+ *
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#include "storagedevice.h"
+#include "ff.h"
+
+#ifndef NUM_DIRNEST
+#define NUM_DIRNEST 4
+#endif
+#ifndef NUM_FIL
+#define NUM_FIL     16
+#endif
+
+#define	S_IRUSR	0000400	/* read permission, owner */
+#define	S_IWUSR	0000200	/* write permission, owner */
+#define	S_IXUSR 0000100/* execute/search permission, owner */
+#define	S_IRGRP	0000040	/* read permission, group */
+#define	S_IWGRP	0000020	/* write permission, grougroup */
+#define	S_IXGRP 0000010/* execute/search permission, group */
+#define	S_IROTH	0000004	/* read permission, other */
+#define	S_IWOTH	0000002	/* write permission, other */
+#define	S_IXOTH 0000001/* execute/search permission, other */
+
+#define	FF_EINVAL 22	/* Invalid argument */
+
+static void *ff_opendir(const char *pathname);
+static int ff_closedir(void *dir);
+static int ff_readdir(void *dir, void *pdirent);
+static int ff_mkdir(const char *pathname);
+static int ff_unlink(const char *pathname);
+static int ff_rename(const char *oname, const char *nname);
+static int ff_chmod(const char *name, int mode);
+static int ff_stat(const char *name, struct stat *buf);
+static int ff_statfs(const char *name, void *status);
+static int ff_open(int devno, const char *pathname, int flags);
+static int ff_close(int fd);
+static int ff_fstat(int fd, struct stat *buf);
+static off_t ff_lseek(int fd, off_t offset, int whence, int *res);
+static long ff_read(int fd, void *buf, long count, int *res);
+static long ff_write(int fd, const void *buf, long count, int *res);
+
+
+const StorageDeviceFileFunc_t fatfsSDeviceFileFunc = {
+	ff_opendir,
+	ff_closedir,
+	ff_readdir,
+	ff_mkdir,
+	ff_unlink,
+	ff_unlink,
+	ff_rename,
+	ff_chmod,
+	ff_stat,
+	ff_statfs,
+	ff_open,
+	ff_close,
+	ff_fstat,
+	ff_lseek,
+	ff_read,
+	ff_write,
+	0
+};
+
+typedef struct DIRPACK {
+	DIR      dir;
+	FILINFO  finfo;
+} DIRP;
+
+static FIL   FileObj[NUM_FIL];
+static DIRP  dirobj[NUM_DIRNEST];
+static UH    long_file_name[128];
+static int   opendircount = 0;
+static char  sddevname[256];
+static int   ff_errno;
+
+/*
+ *  FatFsファイルディレクトリオープン
+ */
+static void *ff_opendir(const char *pathname)
+{
+	DIRP *dirp;
+	FRESULT result;
+
+	if(opendircount >= NUM_DIRNEST)
+		return NULL;
+	dirp = &dirobj[opendircount++];
+	if((result = f_opendir(&dirp->dir, pathname)) != FR_OK){
+		ff_errno = result;
+		opendircount--;
+		return NULL;
+	}
+	else
+		return dirp;
+}
+
+/*
+ *  FatFsファイルディレクトリクローズ
+ */
+static int ff_closedir(void *dir)
+{
+	if(opendircount > 0)
+		opendircount--;
+	return 0;
+}
+
+/*
+ *  FatFsファイルディレクトリ読み込み
+ */
+static int ff_readdir(void *dir, void *pdirent)
+{
+	struct dirent2 *pd = pdirent;
+	DIRP   *dirp = dir;
+	FRESULT result;
+
+#if _USE_LFN != 0
+	dirp->dir.lfn = long_file_name;
+#endif
+	if((result = f_readdir(&dirp->dir, &dirp->finfo)) != FR_OK){
+		ff_errno = result;
+		return 0;
+	}
+	if(dirp->dir.sect == 0)
+		return 0;
+	pd->d_fsize = dirp->finfo.fsize;
+	pd->d_date  = dirp->finfo.fdate;
+	pd->d_time  = dirp->finfo.ftime;
+	pd->d_type  = dirp->finfo.fattrib;
+#if _USE_LFN != 0
+	if(dirp->dir.lfn_idx != 0xffff){
+		UH *pw, data;
+		UB *p, *pe;
+		pw = dirp->dir.lfn;
+		p  = pd->d_name;
+		pe = p+254;
+		while(*pw != 0 && p < pe){
+			data = ff_convert(*pw, 0);
+			if(data <= 0x80)
+				*p++ = (UB)data;
+			else{
+				*p++ = data >> 8;
+				*p++ = (UB)data;
+			}
+			pw++;
+		}
+		*p = 0;
+	}
+	else
+#endif
+	{
+		int     i;
+		for(i = 0 ; i < (8+1+3) && dirp->finfo.fname[i] != 0 ; i++)
+			pd->d_name[i] = dirp->finfo.fname[i];
+		pd->d_name[i] = 0;
+	}
+	return 1;
+}
+
+/*
+ *  FatFsディレクトリ作成
+ */
+static int ff_mkdir(const char *pathname)
+{
+	int result = f_mkdir(pathname);
+	if(result == FR_OK)
+		return 0;
+	else{
+		ff_errno = result;
+		return -1;
+	}
+}
+
+/*
+ *  FatFsディレクトリ/ファイル削除
+ */
+static int ff_unlink(const char *pathname)
+{
+	int result = f_unlink(pathname);
+	if(result == FR_OK)
+		return 0;
+	else{
+		ff_errno = result;
+		return -1;
+	}
+}
+
+/*
+ *  FatFsリネーム
+ */
+static int ff_rename(const char *oname, const char *nname)
+{
+	int result = f_rename(oname, nname);
+	if(result == FR_OK)
+		return 0;
+	else{
+		ff_errno = result;
+		return -1;
+	}
+}
+
+/*
+ *  FatFsモード変更
+ */
+static int ff_chmod(const char *name, int mode)
+{
+	FRESULT result;
+	BYTE value = 0;
+	BYTE mask  = AM_RDO;
+
+	if((mode & (S_IWUSR|S_IWGRP|S_IWOTH)) == 0){
+		value |= AM_RDO;
+	}
+	result = f_chmod(name, value, mask);
+	if(result == FR_OK)
+		return 0;
+	else{
+		ff_errno = result;
+		return -1;
+	}
+}
+
+/*
+ *  FatFs直接ファイルステート取得
+ */
+static int ff_stat(const char *name, struct stat *buf)
+{
+	FILINFO finfo;
+	FRESULT result;
+
+	memset(buf, 0, sizeof(struct stat));
+	finfo.lfname = NULL;
+	result = f_stat(name, &finfo);
+	if(result == FR_OK){
+		buf->st_mode = S_IRUSR|S_IRGRP|S_IROTH;
+		if((finfo.fattrib & AM_RDO) == 0)
+			buf->st_mode |= S_IWUSR|S_IWGRP|S_IWOTH;
+		buf->st_blksize = 512;
+		buf->st_blocks  = (finfo.fsize+buf->st_blksize-1)/buf->st_blksize;
+		buf->st_size = finfo.fsize;
+		return 0;
+	}
+	else{
+		ff_errno = result;
+		return -1;
+	}
+}
+
+/*
+ *  FatFsシステムステータスの取り出し
+ */
+static int ff_statfs(const char *name, void *status)
+{
+	struct statfs2 *p = status;
+	FATFS   *fatfs;
+	DWORD   nclust;
+	FRESULT result;
+
+	result = f_getfree(name, &nclust, &fatfs);
+	if(result == FR_OK){
+		memset(p, 0, sizeof(struct statfs2));
+		p->f_bsize  = fatfs->csize * _MAX_SS;
+		p->f_blocks = fatfs->max_clust-1;
+		p->f_bfree  = nclust;
+		return 0;
+	}
+	else{
+		ff_errno = result;
+		return -1;
+	}
+}
+
+/*
+ *  FatFsファイルオープン
+ */
+static int ff_open(int devno, const char *pathname, int flags)
+{
+	int result, i;
+	unsigned char mode;
+
+	if(devno < 0 || devno >= MAXIMUM_DEVNO){
+		ff_errno = FF_EINVAL;
+		return -1;
+	}
+	sddevname[0] = devno + '0';
+	sddevname[1] = ':';
+	strcpy(&sddevname[2], pathname);
+	mode = (flags+1) & 3;
+	if(flags & O_CREAT)
+		mode |= FA_OPEN_ALWAYS;
+	if(flags & O_EXCL)
+		mode |= FA_CREATE_NEW;
+	result = -1;
+	for(i = 0 ; i < NUM_FIL ; i++){
+		if(FileObj[i].fs == 0){
+			result = f_open(&FileObj[i], sddevname, mode);
+			if(result == 0)
+				return (i);
+			else
+				FileObj[i].fs = 0;
+			break;
+		}
+	}
+	ff_errno = result;
+	return -1;
+}
+
+/*
+ *  FatFsファイルクローズ
+ */
+static int ff_close(int fd)
+{
+	FRESULT result;
+
+	if(fd >= NUM_FIL){
+		ff_errno = FF_EINVAL;
+		return -1;
+	}
+	result = f_close(&FileObj[fd]);
+	if(result == FR_OK)
+		return 0;
+	else{
+		ff_errno = result;
+		return -1;
+	}
+}
+
+/*
+ *  FatFsファイルステート取得
+ */
+static int ff_fstat(int fd, struct stat *buf)
+{
+	if(fd >= NUM_FIL){
+		ff_errno = FF_EINVAL;
+		return -1;
+	}
+	memset(buf, 0, sizeof(struct stat));
+	buf->st_size = FileObj[fd].fsize;
+#ifdef _EXT_RTOS
+	buf->st_mtime = (FileObj[fd.fdate<<16)
+                   | FileObj[fd].ftime;
+#endif
+	buf->st_atime = buf->st_ctime
+                  = buf->st_mtime;
+	buf->st_mode = S_IRUSR|S_IRGRP|S_IROTH;
+	if((FileObj[fd].flag & FA_WRITE) != 0)
+		buf->st_mode |= S_IWUSR|S_IWGRP|S_IWOTH;
+	return 0;
+}
+
+/*
+ *  FatFsファイルシーク
+ */
+static off_t ff_lseek(int fd, off_t offset, int whence, int *res)
+{
+	off_t off = 0;
+	FRESULT result;
+
+	*res = -1;
+	if(fd >= NUM_FIL){
+		ff_errno = FF_EINVAL;
+		return -1;
+	}
+	switch (whence) {
+	case SEEK_SET:
+		off = offset;
+		break;
+	case SEEK_CUR:
+		off = FileObj[fd].fptr + offset;
+		break;
+	case SEEK_END:
+		off = FileObj[fd].fsize + offset;
+		break;
+	default:
+		ff_errno =  FF_EINVAL;
+		return -1;
+	}
+	result = f_lseek(&FileObj[fd], off);
+	if(result != FR_OK){
+		ff_errno = result;
+		off = -1;
+	}
+	else
+		*res = 0;
+	return off;
+}
+
+/*
+ *  FatFsファイル読みだし
+ */
+static long ff_read(int fd, void *buf, long count, int *res)
+{
+	long n;
+	FRESULT result;
+
+	*res = -1;
+	if(fd >= NUM_FIL){
+		ff_errno = FF_EINVAL;
+		return 0;
+	}
+	result =  f_read(&FileObj[fd], buf, count, (unsigned int *)&n);
+	if(result != FR_OK){
+		ff_errno = result;
+		n = 0;
+	}
+	else
+		*res = 0;
+	return n;
+}
+
+/*
+ *  FatFsファイル書き込み
+ */
+static long ff_write(int fd, const void *buf, long count, int *res)
+{
+	long n = 0;
+	FRESULT result;
+
+	*res = -1;
+	if(fd >= NUM_FIL){
+		ff_errno = FF_EINVAL;
+		return 0;
+	}
+	result = f_write(&FileObj[fd], buf, count, (unsigned int *)&n);
+	if(result != FR_OK){
+		ff_errno = result;
+		n = 0;
+	}
+	else
+		*res = 0;
+	return n;
+}
+
+/* This function is called each time errno is evaluated. */
+int *__errno(void)
+{
+	return (int *)&ff_errno;
+}
+
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/files/ff/integer.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/files/ff/integer.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/files/ff/integer.h	(revision 457)
@@ -0,0 +1,42 @@
+/*-------------------------------------------*/
+/* Integer type definitions for FatFs module */
+/*-------------------------------------------*/
+
+#ifndef _INTEGER
+
+#if 0
+#include <windows.h>
+#else
+#include <itron.h>
+
+#if 0	/* ROI DEBUG */
+/* These types must be 16-bit, 32-bit or larger integer */
+typedef int				INT;
+typedef unsigned int	UINT;
+#endif	/* ROI DEBUG */
+
+/* These types must be 8-bit integer */
+typedef signed char		CHAR;
+typedef unsigned char	UCHAR;
+typedef unsigned char	BYTE;
+
+/* These types must be 16-bit integer */
+typedef short			SHORT;
+typedef unsigned short	USHORT;
+typedef unsigned short	WORD;
+typedef unsigned short	WCHAR;
+
+/* These types must be 32-bit integer */
+typedef long			LONG;
+typedef unsigned long	ULONG;
+typedef unsigned long	DWORD;
+
+#if 0	/* ROI DEBUG */
+/* Boolean type */
+typedef enum { FALSE = 0, TRUE } BOOL;
+#endif	/* ROI DEBUG */
+
+#endif
+
+#define _INTEGER
+#endif
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/files/ff/option/cc932.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/files/ff/option/cc932.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/files/ff/option/cc932.c	(revision 457)
@@ -0,0 +1,3784 @@
+/*------------------------------------------------------------------------*/
+/* Unicode - OEM code bidirectional converter  (C)ChaN, 2009              */
+/*                                                                        */
+/* CP932 (Japanese Shift-JIS)                                             */
+/*------------------------------------------------------------------------*/
+
+#include "../ff.h"
+
+#define _TINY_TABLE	0
+
+#if _USE_LFN && _CODE_PAGE == 932
+
+
+static
+const WCHAR uni2sjis[] = {
+/*  Unicode - Sjis, Unicode - Sjis, Unicode - Sjis, Unicode - Sjis, */
+	0x00A7, 0x8198, 0x00A8, 0x814E, 0x00B0, 0x818B, 0x00B1, 0x817D,
+	0x00B4, 0x814C, 0x00B6, 0x81F7, 0x00D7, 0x817E, 0x00F7, 0x8180,
+	0x0391, 0x839F, 0x0392, 0x83A0, 0x0393, 0x83A1, 0x0394, 0x83A2,
+	0x0395, 0x83A3, 0x0396, 0x83A4, 0x0397, 0x83A5, 0x0398, 0x83A6,
+	0x0399, 0x83A7, 0x039A, 0x83A8, 0x039B, 0x83A9, 0x039C, 0x83AA,
+	0x039D, 0x83AB, 0x039E, 0x83AC, 0x039F, 0x83AD, 0x03A0, 0x83AE,
+	0x03A1, 0x83AF, 0x03A3, 0x83B0, 0x03A4, 0x83B1, 0x03A5, 0x83B2,
+	0x03A6, 0x83B3, 0x03A7, 0x83B4, 0x03A8, 0x83B5, 0x03A9, 0x83B6,
+	0x03B1, 0x83BF, 0x03B2, 0x83C0, 0x03B3, 0x83C1, 0x03B4, 0x83C2,
+	0x03B5, 0x83C3, 0x03B6, 0x83C4, 0x03B7, 0x83C5, 0x03B8, 0x83C6,
+	0x03B9, 0x83C7, 0x03BA, 0x83C8, 0x03BB, 0x83C9, 0x03BC, 0x83CA,
+	0x03BD, 0x83CB, 0x03BE, 0x83CC, 0x03BF, 0x83CD, 0x03C0, 0x83CE,
+	0x03C1, 0x83CF, 0x03C3, 0x83D0, 0x03C4, 0x83D1, 0x03C5, 0x83D2,
+	0x03C6, 0x83D3, 0x03C7, 0x83D4, 0x03C8, 0x83D5, 0x03C9, 0x83D6,
+	0x0401, 0x8446, 0x0410, 0x8440, 0x0411, 0x8441, 0x0412, 0x8442,
+	0x0413, 0x8443, 0x0414, 0x8444, 0x0415, 0x8445, 0x0416, 0x8447,
+	0x0417, 0x8448, 0x0418, 0x8449, 0x0419, 0x844A, 0x041A, 0x844B,
+	0x041B, 0x844C, 0x041C, 0x844D, 0x041D, 0x844E, 0x041E, 0x844F,
+	0x041F, 0x8450, 0x0420, 0x8451, 0x0421, 0x8452, 0x0422, 0x8453,
+	0x0423, 0x8454, 0x0424, 0x8455, 0x0425, 0x8456, 0x0426, 0x8457,
+	0x0427, 0x8458, 0x0428, 0x8459, 0x0429, 0x845A, 0x042A, 0x845B,
+	0x042B, 0x845C, 0x042C, 0x845D, 0x042D, 0x845E, 0x042E, 0x845F,
+	0x042F, 0x8460, 0x0430, 0x8470, 0x0431, 0x8471, 0x0432, 0x8472,
+	0x0433, 0x8473, 0x0434, 0x8474, 0x0435, 0x8475, 0x0436, 0x8477,
+	0x0437, 0x8478, 0x0438, 0x8479, 0x0439, 0x847A, 0x043A, 0x847B,
+	0x043B, 0x847C, 0x043C, 0x847D, 0x043D, 0x847E, 0x043E, 0x8480,
+	0x043F, 0x8481, 0x0440, 0x8482, 0x0441, 0x8483, 0x0442, 0x8484,
+	0x0443, 0x8485, 0x0444, 0x8486, 0x0445, 0x8487, 0x0446, 0x8488,
+	0x0447, 0x8489, 0x0448, 0x848A, 0x0449, 0x848B, 0x044A, 0x848C,
+	0x044B, 0x848D, 0x044C, 0x848E, 0x044D, 0x848F, 0x044E, 0x8490,
+	0x044F, 0x8491, 0x0451, 0x8476, 0x2010, 0x815D, 0x2015, 0x815C,
+	0x2018, 0x8165, 0x2019, 0x8166, 0x201C, 0x8167, 0x201D, 0x8168,
+	0x2020, 0x81F5, 0x2021, 0x81F6, 0x2025, 0x8164, 0x2026, 0x8163,
+	0x2030, 0x81F1, 0x2032, 0x818C, 0x2033, 0x818D, 0x203B, 0x81A6,
+	0x2103, 0x818E, 0x2116, 0x8782, 0x2121, 0x8784, 0x212B, 0x81F0,
+	0x2160, 0x8754, 0x2161, 0x8755, 0x2162, 0x8756, 0x2163, 0x8757,
+	0x2164, 0x8758, 0x2165, 0x8759, 0x2166, 0x875A, 0x2167, 0x875B,
+	0x2168, 0x875C, 0x2169, 0x875D, 0x2170, 0xFA40, 0x2171, 0xFA41,
+	0x2172, 0xFA42, 0x2173, 0xFA43, 0x2174, 0xFA44, 0x2175, 0xFA45,
+	0x2176, 0xFA46, 0x2177, 0xFA47, 0x2178, 0xFA48, 0x2179, 0xFA49,
+	0x2190, 0x81A9, 0x2191, 0x81AA, 0x2192, 0x81A8, 0x2193, 0x81AB,
+	0x21D2, 0x81CB, 0x21D4, 0x81CC, 0x2200, 0x81CD, 0x2202, 0x81DD,
+	0x2203, 0x81CE, 0x2207, 0x81DE, 0x2208, 0x81B8, 0x220B, 0x81B9,
+	0x2211, 0x8794, 0x221A, 0x81E3, 0x221D, 0x81E5, 0x221E, 0x8187,
+	0x221F, 0x8798, 0x2220, 0x81DA, 0x2225, 0x8161, 0x2227, 0x81C8,
+	0x2228, 0x81C9, 0x2229, 0x81BF, 0x222A, 0x81BE, 0x222B, 0x81E7,
+	0x222C, 0x81E8, 0x222E, 0x8793, 0x2234, 0x8188, 0x2235, 0x81E6,
+	0x223D, 0x81E4, 0x2252, 0x81E0, 0x2260, 0x8182, 0x2261, 0x81DF,
+	0x2266, 0x8185, 0x2267, 0x8186, 0x226A, 0x81E1, 0x226B, 0x81E2,
+	0x2282, 0x81BC, 0x2283, 0x81BD, 0x2286, 0x81BA, 0x2287, 0x81BB,
+	0x22A5, 0x81DB, 0x22BF, 0x8799, 0x2312, 0x81DC, 0x2460, 0x8740,
+	0x2461, 0x8741, 0x2462, 0x8742, 0x2463, 0x8743, 0x2464, 0x8744,
+	0x2465, 0x8745, 0x2466, 0x8746, 0x2467, 0x8747, 0x2468, 0x8748,
+	0x2469, 0x8749, 0x246A, 0x874A, 0x246B, 0x874B, 0x246C, 0x874C,
+	0x246D, 0x874D, 0x246E, 0x874E, 0x246F, 0x874F, 0x2470, 0x8750,
+	0x2471, 0x8751, 0x2472, 0x8752, 0x2473, 0x8753, 0x2500, 0x849F,
+	0x2501, 0x84AA, 0x2502, 0x84A0, 0x2503, 0x84AB, 0x250C, 0x84A1,
+	0x250F, 0x84AC, 0x2510, 0x84A2, 0x2513, 0x84AD, 0x2514, 0x84A4,
+	0x2517, 0x84AF, 0x2518, 0x84A3, 0x251B, 0x84AE, 0x251C, 0x84A5,
+	0x251D, 0x84BA, 0x2520, 0x84B5, 0x2523, 0x84B0, 0x2524, 0x84A7,
+	0x2525, 0x84BC, 0x2528, 0x84B7, 0x252B, 0x84B2, 0x252C, 0x84A6,
+	0x252F, 0x84B6, 0x2530, 0x84BB, 0x2533, 0x84B1, 0x2534, 0x84A8,
+	0x2537, 0x84B8, 0x2538, 0x84BD, 0x253B, 0x84B3, 0x253C, 0x84A9,
+	0x253F, 0x84B9, 0x2542, 0x84BE, 0x254B, 0x84B4, 0x25A0, 0x81A1,
+	0x25A1, 0x81A0, 0x25B2, 0x81A3, 0x25B3, 0x81A2, 0x25BC, 0x81A5,
+	0x25BD, 0x81A4, 0x25C6, 0x819F, 0x25C7, 0x819E, 0x25CB, 0x819B,
+	0x25CE, 0x819D, 0x25CF, 0x819C, 0x25EF, 0x81FC, 0x2605, 0x819A,
+	0x2606, 0x8199, 0x2640, 0x818A, 0x2642, 0x8189, 0x266A, 0x81F4,
+	0x266D, 0x81F3, 0x266F, 0x81F2, 0x3000, 0x8140, 0x3001, 0x8141,
+	0x3002, 0x8142, 0x3003, 0x8156, 0x3005, 0x8158, 0x3006, 0x8159,
+	0x3007, 0x815A, 0x3008, 0x8171, 0x3009, 0x8172, 0x300A, 0x8173,
+	0x300B, 0x8174, 0x300C, 0x8175, 0x300D, 0x8176, 0x300E, 0x8177,
+	0x300F, 0x8178, 0x3010, 0x8179, 0x3011, 0x817A, 0x3012, 0x81A7,
+	0x3013, 0x81AC, 0x3014, 0x816B, 0x3015, 0x816C, 0x301D, 0x8780,
+	0x301F, 0x8781, 0x3041, 0x829F, 0x3042, 0x82A0, 0x3043, 0x82A1,
+	0x3044, 0x82A2, 0x3045, 0x82A3, 0x3046, 0x82A4, 0x3047, 0x82A5,
+	0x3048, 0x82A6, 0x3049, 0x82A7, 0x304A, 0x82A8, 0x304B, 0x82A9,
+	0x304C, 0x82AA, 0x304D, 0x82AB, 0x304E, 0x82AC, 0x304F, 0x82AD,
+	0x3050, 0x82AE, 0x3051, 0x82AF, 0x3052, 0x82B0, 0x3053, 0x82B1,
+	0x3054, 0x82B2, 0x3055, 0x82B3, 0x3056, 0x82B4, 0x3057, 0x82B5,
+	0x3058, 0x82B6, 0x3059, 0x82B7, 0x305A, 0x82B8, 0x305B, 0x82B9,
+	0x305C, 0x82BA, 0x305D, 0x82BB, 0x305E, 0x82BC, 0x305F, 0x82BD,
+	0x3060, 0x82BE, 0x3061, 0x82BF, 0x3062, 0x82C0, 0x3063, 0x82C1,
+	0x3064, 0x82C2, 0x3065, 0x82C3, 0x3066, 0x82C4, 0x3067, 0x82C5,
+	0x3068, 0x82C6, 0x3069, 0x82C7, 0x306A, 0x82C8, 0x306B, 0x82C9,
+	0x306C, 0x82CA, 0x306D, 0x82CB, 0x306E, 0x82CC, 0x306F, 0x82CD,
+	0x3070, 0x82CE, 0x3071, 0x82CF, 0x3072, 0x82D0, 0x3073, 0x82D1,
+	0x3074, 0x82D2, 0x3075, 0x82D3, 0x3076, 0x82D4, 0x3077, 0x82D5,
+	0x3078, 0x82D6, 0x3079, 0x82D7, 0x307A, 0x82D8, 0x307B, 0x82D9,
+	0x307C, 0x82DA, 0x307D, 0x82DB, 0x307E, 0x82DC, 0x307F, 0x82DD,
+	0x3080, 0x82DE, 0x3081, 0x82DF, 0x3082, 0x82E0, 0x3083, 0x82E1,
+	0x3084, 0x82E2, 0x3085, 0x82E3, 0x3086, 0x82E4, 0x3087, 0x82E5,
+	0x3088, 0x82E6, 0x3089, 0x82E7, 0x308A, 0x82E8, 0x308B, 0x82E9,
+	0x308C, 0x82EA, 0x308D, 0x82EB, 0x308E, 0x82EC, 0x308F, 0x82ED,
+	0x3090, 0x82EE, 0x3091, 0x82EF, 0x3092, 0x82F0, 0x3093, 0x82F1,
+	0x3094, 0x8394, 0x309B, 0x814A, 0x309C, 0x814B, 0x309D, 0x8154,
+	0x309E, 0x8155, 0x30A1, 0x8340, 0x30A2, 0x8341, 0x30A3, 0x8342,
+	0x30A4, 0x8343, 0x30A5, 0x8344, 0x30A6, 0x8345, 0x30A7, 0x8346,
+	0x30A8, 0x8347, 0x30A9, 0x8348, 0x30AA, 0x8349, 0x30AB, 0x834A,
+	0x30AC, 0x834B, 0x30AD, 0x834C, 0x30AE, 0x834D, 0x30AF, 0x834E,
+	0x30B0, 0x834F, 0x30B1, 0x8350, 0x30B2, 0x8351, 0x30B3, 0x8352,
+	0x30B4, 0x8353, 0x30B5, 0x8354, 0x30B6, 0x8355, 0x30B7, 0x8356,
+	0x30B8, 0x8357, 0x30B9, 0x8358, 0x30BA, 0x8359, 0x30BB, 0x835A,
+	0x30BC, 0x835B, 0x30BD, 0x835C, 0x30BE, 0x835D, 0x30BF, 0x835E,
+	0x30C0, 0x835F, 0x30C1, 0x8360, 0x30C2, 0x8361, 0x30C3, 0x8362,
+	0x30C4, 0x8363, 0x30C5, 0x8364, 0x30C6, 0x8365, 0x30C7, 0x8366,
+	0x30C8, 0x8367, 0x30C9, 0x8368, 0x30CA, 0x8369, 0x30CB, 0x836A,
+	0x30CC, 0x836B, 0x30CD, 0x836C, 0x30CE, 0x836D, 0x30CF, 0x836E,
+	0x30D0, 0x836F, 0x30D1, 0x8370, 0x30D2, 0x8371, 0x30D3, 0x8372,
+	0x30D4, 0x8373, 0x30D5, 0x8374, 0x30D6, 0x8375, 0x30D7, 0x8376,
+	0x30D8, 0x8377, 0x30D9, 0x8378, 0x30DA, 0x8379, 0x30DB, 0x837A,
+	0x30DC, 0x837B, 0x30DD, 0x837C, 0x30DE, 0x837D, 0x30DF, 0x837E,
+	0x30E0, 0x8380, 0x30E1, 0x8381, 0x30E2, 0x8382, 0x30E3, 0x8383,
+	0x30E4, 0x8384, 0x30E5, 0x8385, 0x30E6, 0x8386, 0x30E7, 0x8387,
+	0x30E8, 0x8388, 0x30E9, 0x8389, 0x30EA, 0x838A, 0x30EB, 0x838B,
+	0x30EC, 0x838C, 0x30ED, 0x838D, 0x30EE, 0x838E, 0x30EF, 0x838F,
+	0x30F0, 0x8390, 0x30F1, 0x8391, 0x30F2, 0x8392, 0x30F3, 0x8393,
+	0x30F4, 0x8394, 0x30F5, 0x8395, 0x30F6, 0x8396, 0x30FB, 0x8145,
+	0x30FC, 0x815B, 0x30FD, 0x8152, 0x30FE, 0x8153, 0x3231, 0x878A,
+	0x3232, 0x878B, 0x3239, 0x878C, 0x32A4, 0x8785, 0x32A5, 0x8786,
+	0x32A6, 0x8787, 0x32A7, 0x8788, 0x32A8, 0x8789, 0x3303, 0x8765,
+	0x330D, 0x8769, 0x3314, 0x8760, 0x3318, 0x8763, 0x3322, 0x8761,
+	0x3323, 0x876B, 0x3326, 0x876A, 0x3327, 0x8764, 0x332B, 0x876C,
+	0x3336, 0x8766, 0x333B, 0x876E, 0x3349, 0x875F, 0x334A, 0x876D,
+	0x334D, 0x8762, 0x3351, 0x8767, 0x3357, 0x8768, 0x337B, 0x877E,
+	0x337C, 0x878F, 0x337D, 0x878E, 0x337E, 0x878D, 0x338E, 0x8772,
+	0x338F, 0x8773, 0x339C, 0x876F, 0x339D, 0x8770, 0x339E, 0x8771,
+	0x33A1, 0x8775, 0x33C4, 0x8774, 0x33CD, 0x8783, 0x4E00, 0x88EA,
+	0x4E01, 0x929A, 0x4E03, 0x8EB5, 0x4E07, 0x969C, 0x4E08, 0x8FE4,
+	0x4E09, 0x8E4F, 0x4E0A, 0x8FE3, 0x4E0B, 0x89BA, 0x4E0D, 0x9573,
+	0x4E0E, 0x975E, 0x4E10, 0x98A0, 0x4E11, 0x894E, 0x4E14, 0x8A8E,
+	0x4E15, 0x98A1, 0x4E16, 0x90A2, 0x4E17, 0x99C0, 0x4E18, 0x8B75,
+	0x4E19, 0x95B8, 0x4E1E, 0x8FE5, 0x4E21, 0x97BC, 0x4E26, 0x95C0,
+	0x4E28, 0xFA68, 0x4E2A, 0x98A2, 0x4E2D, 0x9286, 0x4E31, 0x98A3,
+	0x4E32, 0x8BF8, 0x4E36, 0x98A4, 0x4E38, 0x8ADB, 0x4E39, 0x924F,
+	0x4E3B, 0x8EE5, 0x4E3C, 0x98A5, 0x4E3F, 0x98A6, 0x4E42, 0x98A7,
+	0x4E43, 0x9454, 0x4E45, 0x8B76, 0x4E4B, 0x9456, 0x4E4D, 0x93E1,
+	0x4E4E, 0x8CC1, 0x4E4F, 0x9652, 0x4E55, 0xE568, 0x4E56, 0x98A8,
+	0x4E57, 0x8FE6, 0x4E58, 0x98A9, 0x4E59, 0x89B3, 0x4E5D, 0x8BE3,
+	0x4E5E, 0x8CEE, 0x4E5F, 0x96E7, 0x4E62, 0x9BA4, 0x4E71, 0x9790,
+	0x4E73, 0x93FB, 0x4E7E, 0x8AA3, 0x4E80, 0x8B54, 0x4E82, 0x98AA,
+	0x4E85, 0x98AB, 0x4E86, 0x97B9, 0x4E88, 0x975C, 0x4E89, 0x9188,
+	0x4E8A, 0x98AD, 0x4E8B, 0x8E96, 0x4E8C, 0x93F1, 0x4E8E, 0x98B0,
+	0x4E91, 0x895D, 0x4E92, 0x8CDD, 0x4E94, 0x8CDC, 0x4E95, 0x88E4,
+	0x4E98, 0x986A, 0x4E99, 0x9869, 0x4E9B, 0x8DB1, 0x4E9C, 0x889F,
+	0x4E9E, 0x98B1, 0x4E9F, 0x98B2, 0x4EA0, 0x98B3, 0x4EA1, 0x9653,
+	0x4EA2, 0x98B4, 0x4EA4, 0x8CF0, 0x4EA5, 0x88E5, 0x4EA6, 0x9692,
+	0x4EA8, 0x8B9C, 0x4EAB, 0x8B9D, 0x4EAC, 0x8B9E, 0x4EAD, 0x92E0,
+	0x4EAE, 0x97BA, 0x4EB0, 0x98B5, 0x4EB3, 0x98B6, 0x4EB6, 0x98B7,
+	0x4EBA, 0x906C, 0x4EC0, 0x8F59, 0x4EC1, 0x906D, 0x4EC2, 0x98BC,
+	0x4EC4, 0x98BA, 0x4EC6, 0x98BB, 0x4EC7, 0x8B77, 0x4ECA, 0x8DA1,
+	0x4ECB, 0x89EE, 0x4ECD, 0x98B9, 0x4ECE, 0x98B8, 0x4ECF, 0x95A7,
+	0x4ED4, 0x8E65, 0x4ED5, 0x8E64, 0x4ED6, 0x91BC, 0x4ED7, 0x98BD,
+	0x4ED8, 0x9574, 0x4ED9, 0x90E5, 0x4EDD, 0x8157, 0x4EDE, 0x98BE,
+	0x4EDF, 0x98C0, 0x4EE1, 0xFA69, 0x4EE3, 0x91E3, 0x4EE4, 0x97DF,
+	0x4EE5, 0x88C8, 0x4EED, 0x98BF, 0x4EEE, 0x89BC, 0x4EF0, 0x8BC2,
+	0x4EF2, 0x9287, 0x4EF6, 0x8C8F, 0x4EF7, 0x98C1, 0x4EFB, 0x9443,
+	0x4EFC, 0xFA6A, 0x4F00, 0xFA6B, 0x4F01, 0x8AE9, 0x4F03, 0xFA6C,
+	0x4F09, 0x98C2, 0x4F0A, 0x88C9, 0x4F0D, 0x8CDE, 0x4F0E, 0x8AEA,
+	0x4F0F, 0x959A, 0x4F10, 0x94B0, 0x4F11, 0x8B78, 0x4F1A, 0x89EF,
+	0x4F1C, 0x98E5, 0x4F1D, 0x9360, 0x4F2F, 0x948C, 0x4F30, 0x98C4,
+	0x4F34, 0x94BA, 0x4F36, 0x97E0, 0x4F38, 0x904C, 0x4F39, 0xFA6D,
+	0x4F3A, 0x8E66, 0x4F3C, 0x8E97, 0x4F3D, 0x89BE, 0x4F43, 0x92CF,
+	0x4F46, 0x9241, 0x4F47, 0x98C8, 0x4F4D, 0x88CA, 0x4F4E, 0x92E1,
+	0x4F4F, 0x8F5A, 0x4F50, 0x8DB2, 0x4F51, 0x9743, 0x4F53, 0x91CC,
+	0x4F55, 0x89BD, 0x4F56, 0xFA6E, 0x4F57, 0x98C7, 0x4F59, 0x975D,
+	0x4F5A, 0x98C3, 0x4F5B, 0x98C5, 0x4F5C, 0x8DEC, 0x4F5D, 0x98C6,
+	0x4F5E, 0x9B43, 0x4F69, 0x98CE, 0x4F6F, 0x98D1, 0x4F70, 0x98CF,
+	0x4F73, 0x89C0, 0x4F75, 0x95B9, 0x4F76, 0x98C9, 0x4F7B, 0x98CD,
+	0x4F7C, 0x8CF1, 0x4F7F, 0x8E67, 0x4F83, 0x8AA4, 0x4F86, 0x98D2,
+	0x4F88, 0x98CA, 0x4F8A, 0xFA70, 0x4F8B, 0x97E1, 0x4F8D, 0x8E98,
+	0x4F8F, 0x98CB, 0x4F91, 0x98D0, 0x4F92, 0xFA6F, 0x4F94, 0xFA72,
+	0x4F96, 0x98D3, 0x4F98, 0x98CC, 0x4F9A, 0xFA71, 0x4F9B, 0x8B9F,
+	0x4F9D, 0x88CB, 0x4FA0, 0x8BA0, 0x4FA1, 0x89BF, 0x4FAB, 0x9B44,
+	0x4FAD, 0x9699, 0x4FAE, 0x958E, 0x4FAF, 0x8CF2, 0x4FB5, 0x904E,
+	0x4FB6, 0x97B5, 0x4FBF, 0x95D6, 0x4FC2, 0x8C57, 0x4FC3, 0x91A3,
+	0x4FC4, 0x89E2, 0x4FC9, 0xFA61, 0x4FCA, 0x8F72, 0x4FCD, 0xFA73,
+	0x4FCE, 0x98D7, 0x4FD0, 0x98DC, 0x4FD1, 0x98DA, 0x4FD4, 0x98D5,
+	0x4FD7, 0x91AD, 0x4FD8, 0x98D8, 0x4FDA, 0x98DB, 0x4FDB, 0x98D9,
+	0x4FDD, 0x95DB, 0x4FDF, 0x98D6, 0x4FE1, 0x904D, 0x4FE3, 0x9693,
+	0x4FE4, 0x98DD, 0x4FE5, 0x98DE, 0x4FEE, 0x8F43, 0x4FEF, 0x98EB,
+	0x4FF3, 0x946F, 0x4FF5, 0x9555, 0x4FF6, 0x98E6, 0x4FF8, 0x95EE,
+	0x4FFA, 0x89B4, 0x4FFE, 0x98EA, 0x4FFF, 0xFA76, 0x5005, 0x98E4,
+	0x5006, 0x98ED, 0x5009, 0x9171, 0x500B, 0x8CC2, 0x500D, 0x947B,
+	0x500F, 0xE0C5, 0x5011, 0x98EC, 0x5012, 0x937C, 0x5014, 0x98E1,
+	0x5016, 0x8CF4, 0x5019, 0x8CF3, 0x501A, 0x98DF, 0x501E, 0xFA77,
+	0x501F, 0x8ED8, 0x5021, 0x98E7, 0x5022, 0xFA75, 0x5023, 0x95ED,
+	0x5024, 0x926C, 0x5025, 0x98E3, 0x5026, 0x8C91, 0x5028, 0x98E0,
+	0x5029, 0x98E8, 0x502A, 0x98E2, 0x502B, 0x97CF, 0x502C, 0x98E9,
+	0x502D, 0x9860, 0x5036, 0x8BE4, 0x5039, 0x8C90, 0x5040, 0xFA74,
+	0x5042, 0xFA7A, 0x5043, 0x98EE, 0x5046, 0xFA78, 0x5047, 0x98EF,
+	0x5048, 0x98F3, 0x5049, 0x88CC, 0x504F, 0x95CE, 0x5050, 0x98F2,
+	0x5055, 0x98F1, 0x5056, 0x98F5, 0x505A, 0x98F4, 0x505C, 0x92E2,
+	0x5065, 0x8C92, 0x506C, 0x98F6, 0x5070, 0xFA79, 0x5072, 0x8EC3,
+	0x5074, 0x91A4, 0x5075, 0x92E3, 0x5076, 0x8BF4, 0x5078, 0x98F7,
+	0x507D, 0x8B55, 0x5080, 0x98F8, 0x5085, 0x98FA, 0x508D, 0x9654,
+	0x5091, 0x8C86, 0x5094, 0xFA7B, 0x5098, 0x8E50, 0x5099, 0x94F5,
+	0x509A, 0x98F9, 0x50AC, 0x8DC3, 0x50AD, 0x9762, 0x50B2, 0x98FC,
+	0x50B3, 0x9942, 0x50B4, 0x98FB, 0x50B5, 0x8DC2, 0x50B7, 0x8F9D,
+	0x50BE, 0x8C58, 0x50C2, 0x9943, 0x50C5, 0x8BCD, 0x50C9, 0x9940,
+	0x50CA, 0x9941, 0x50CD, 0x93AD, 0x50CF, 0x919C, 0x50D1, 0x8BA1,
+	0x50D5, 0x966C, 0x50D6, 0x9944, 0x50D8, 0xFA7D, 0x50DA, 0x97BB,
+	0x50DE, 0x9945, 0x50E3, 0x9948, 0x50E5, 0x9946, 0x50E7, 0x916D,
+	0x50ED, 0x9947, 0x50EE, 0x9949, 0x50F4, 0xFA7C, 0x50F5, 0x994B,
+	0x50F9, 0x994A, 0x50FB, 0x95C6, 0x5100, 0x8B56, 0x5101, 0x994D,
+	0x5102, 0x994E, 0x5104, 0x89AD, 0x5109, 0x994C, 0x5112, 0x8EF2,
+	0x5114, 0x9951, 0x5115, 0x9950, 0x5116, 0x994F, 0x5118, 0x98D4,
+	0x511A, 0x9952, 0x511F, 0x8F9E, 0x5121, 0x9953, 0x512A, 0x9744,
+	0x5132, 0x96D7, 0x5137, 0x9955, 0x513A, 0x9954, 0x513B, 0x9957,
+	0x513C, 0x9956, 0x513F, 0x9958, 0x5140, 0x9959, 0x5141, 0x88F2,
+	0x5143, 0x8CB3, 0x5144, 0x8C5A, 0x5145, 0x8F5B, 0x5146, 0x929B,
+	0x5147, 0x8BA2, 0x5148, 0x90E6, 0x5149, 0x8CF5, 0x514A, 0xFA7E,
+	0x514B, 0x8D8E, 0x514C, 0x995B, 0x514D, 0x96C6, 0x514E, 0x9365,
+	0x5150, 0x8E99, 0x5152, 0x995A, 0x5154, 0x995C, 0x515A, 0x937D,
+	0x515C, 0x8A95, 0x5162, 0x995D, 0x5164, 0xFA80, 0x5165, 0x93FC,
+	0x5168, 0x9153, 0x5169, 0x995F, 0x516A, 0x9960, 0x516B, 0x94AA,
+	0x516C, 0x8CF6, 0x516D, 0x985A, 0x516E, 0x9961, 0x5171, 0x8BA4,
+	0x5175, 0x95BA, 0x5176, 0x91B4, 0x5177, 0x8BEF, 0x5178, 0x9354,
+	0x517C, 0x8C93, 0x5180, 0x9962, 0x5182, 0x9963, 0x5185, 0x93E0,
+	0x5186, 0x897E, 0x5189, 0x9966, 0x518A, 0x8DFB, 0x518C, 0x9965,
+	0x518D, 0x8DC4, 0x518F, 0x9967, 0x5190, 0xE3EC, 0x5191, 0x9968,
+	0x5192, 0x9660, 0x5193, 0x9969, 0x5195, 0x996A, 0x5196, 0x996B,
+	0x5197, 0x8FE7, 0x5199, 0x8ECA, 0x519D, 0xFA81, 0x51A0, 0x8AA5,
+	0x51A2, 0x996E, 0x51A4, 0x996C, 0x51A5, 0x96BB, 0x51A6, 0x996D,
+	0x51A8, 0x9579, 0x51A9, 0x996F, 0x51AA, 0x9970, 0x51AB, 0x9971,
+	0x51AC, 0x937E, 0x51B0, 0x9975, 0x51B1, 0x9973, 0x51B2, 0x9974,
+	0x51B3, 0x9972, 0x51B4, 0x8DE1, 0x51B5, 0x9976, 0x51B6, 0x96E8,
+	0x51B7, 0x97E2, 0x51BD, 0x9977, 0x51BE, 0xFA82, 0x51C4, 0x90A6,
+	0x51C5, 0x9978, 0x51C6, 0x8F79, 0x51C9, 0x9979, 0x51CB, 0x929C,
+	0x51CC, 0x97BD, 0x51CD, 0x9380, 0x51D6, 0x99C3, 0x51DB, 0x997A,
+	0x51DC, 0xEAA3, 0x51DD, 0x8BC3, 0x51E0, 0x997B, 0x51E1, 0x967D,
+	0x51E6, 0x8F88, 0x51E7, 0x91FA, 0x51E9, 0x997D, 0x51EA, 0x93E2,
+	0x51EC, 0xFA83, 0x51ED, 0x997E, 0x51F0, 0x9980, 0x51F1, 0x8A4D,
+	0x51F5, 0x9981, 0x51F6, 0x8BA5, 0x51F8, 0x93CA, 0x51F9, 0x899A,
+	0x51FA, 0x8F6F, 0x51FD, 0x949F, 0x51FE, 0x9982, 0x5200, 0x9381,
+	0x5203, 0x906E, 0x5204, 0x9983, 0x5206, 0x95AA, 0x5207, 0x90D8,
+	0x5208, 0x8AA0, 0x520A, 0x8AA7, 0x520B, 0x9984, 0x520E, 0x9986,
+	0x5211, 0x8C59, 0x5214, 0x9985, 0x5215, 0xFA84, 0x5217, 0x97F1,
+	0x521D, 0x8F89, 0x5224, 0x94BB, 0x5225, 0x95CA, 0x5227, 0x9987,
+	0x5229, 0x9798, 0x522A, 0x9988, 0x522E, 0x9989, 0x5230, 0x939E,
+	0x5233, 0x998A, 0x5236, 0x90A7, 0x5237, 0x8DFC, 0x5238, 0x8C94,
+	0x5239, 0x998B, 0x523A, 0x8E68, 0x523B, 0x8D8F, 0x5243, 0x92E4,
+	0x5244, 0x998D, 0x5247, 0x91A5, 0x524A, 0x8DED, 0x524B, 0x998E,
+	0x524C, 0x998F, 0x524D, 0x914F, 0x524F, 0x998C, 0x5254, 0x9991,
+	0x5256, 0x9655, 0x525B, 0x8D84, 0x525E, 0x9990, 0x5263, 0x8C95,
+	0x5264, 0x8DDC, 0x5265, 0x948D, 0x5269, 0x9994, 0x526A, 0x9992,
+	0x526F, 0x959B, 0x5270, 0x8FE8, 0x5271, 0x999B, 0x5272, 0x8A84,
+	0x5273, 0x9995, 0x5274, 0x9993, 0x5275, 0x916E, 0x527D, 0x9997,
+	0x527F, 0x9996, 0x5283, 0x8A63, 0x5287, 0x8C80, 0x5288, 0x999C,
+	0x5289, 0x97AB, 0x528D, 0x9998, 0x5291, 0x999D, 0x5292, 0x999A,
+	0x5294, 0x9999, 0x529B, 0x97CD, 0x529C, 0xFA85, 0x529F, 0x8CF7,
+	0x52A0, 0x89C1, 0x52A3, 0x97F2, 0x52A6, 0xFA86, 0x52A9, 0x8F95,
+	0x52AA, 0x9377, 0x52AB, 0x8D85, 0x52AC, 0x99A0, 0x52AD, 0x99A1,
+	0x52AF, 0xFB77, 0x52B1, 0x97E3, 0x52B4, 0x984A, 0x52B5, 0x99A3,
+	0x52B9, 0x8CF8, 0x52BC, 0x99A2, 0x52BE, 0x8A4E, 0x52C0, 0xFA87,
+	0x52C1, 0x99A4, 0x52C3, 0x9675, 0x52C5, 0x92BA, 0x52C7, 0x9745,
+	0x52C9, 0x95D7, 0x52CD, 0x99A5, 0x52D2, 0xE8D3, 0x52D5, 0x93AE,
+	0x52D7, 0x99A6, 0x52D8, 0x8AA8, 0x52D9, 0x96B1, 0x52DB, 0xFA88,
+	0x52DD, 0x8F9F, 0x52DE, 0x99A7, 0x52DF, 0x95E5, 0x52E0, 0x99AB,
+	0x52E2, 0x90A8, 0x52E3, 0x99A8, 0x52E4, 0x8BCE, 0x52E6, 0x99A9,
+	0x52E7, 0x8AA9, 0x52F2, 0x8C4D, 0x52F3, 0x99AC, 0x52F5, 0x99AD,
+	0x52F8, 0x99AE, 0x52F9, 0x99AF, 0x52FA, 0x8ED9, 0x52FE, 0x8CF9,
+	0x52FF, 0x96DC, 0x5300, 0xFA89, 0x5301, 0x96E6, 0x5302, 0x93F5,
+	0x5305, 0x95EF, 0x5306, 0x99B0, 0x5307, 0xFA8A, 0x5308, 0x99B1,
+	0x530D, 0x99B3, 0x530F, 0x99B5, 0x5310, 0x99B4, 0x5315, 0x99B6,
+	0x5316, 0x89BB, 0x5317, 0x966B, 0x5319, 0x8DFA, 0x531A, 0x99B7,
+	0x531D, 0x9178, 0x5320, 0x8FA0, 0x5321, 0x8BA7, 0x5323, 0x99B8,
+	0x5324, 0xFA8B, 0x532A, 0x94D9, 0x532F, 0x99B9, 0x5331, 0x99BA,
+	0x5333, 0x99BB, 0x5338, 0x99BC, 0x5339, 0x9543, 0x533A, 0x8BE6,
+	0x533B, 0x88E3, 0x533F, 0x93BD, 0x5340, 0x99BD, 0x5341, 0x8F5C,
+	0x5343, 0x90E7, 0x5345, 0x99BF, 0x5346, 0x99BE, 0x5347, 0x8FA1,
+	0x5348, 0x8CDF, 0x5349, 0x99C1, 0x534A, 0x94BC, 0x534D, 0x99C2,
+	0x5351, 0x94DA, 0x5352, 0x91B2, 0x5353, 0x91EC, 0x5354, 0x8BA6,
+	0x5357, 0x93EC, 0x5358, 0x9250, 0x535A, 0x948E, 0x535C, 0x966D,
+	0x535E, 0x99C4, 0x5360, 0x90E8, 0x5366, 0x8C54, 0x5369, 0x99C5,
+	0x536E, 0x99C6, 0x536F, 0x894B, 0x5370, 0x88F3, 0x5371, 0x8AEB,
+	0x5372, 0xFA8C, 0x5373, 0x91A6, 0x5374, 0x8B70, 0x5375, 0x9791,
+	0x5377, 0x99C9, 0x5378, 0x89B5, 0x537B, 0x99C8, 0x537F, 0x8BA8,
+	0x5382, 0x99CA, 0x5384, 0x96EF, 0x5393, 0xFA8D, 0x5396, 0x99CB,
+	0x5398, 0x97D0, 0x539A, 0x8CFA, 0x539F, 0x8CB4, 0x53A0, 0x99CC,
+	0x53A5, 0x99CE, 0x53A6, 0x99CD, 0x53A8, 0x907E, 0x53A9, 0x8958,
+	0x53AD, 0x897D, 0x53AE, 0x99CF, 0x53B0, 0x99D0, 0x53B2, 0xFA8E,
+	0x53B3, 0x8CB5, 0x53B6, 0x99D1, 0x53BB, 0x8B8E, 0x53C2, 0x8E51,
+	0x53C3, 0x99D2, 0x53C8, 0x9694, 0x53C9, 0x8DB3, 0x53CA, 0x8B79,
+	0x53CB, 0x9746, 0x53CC, 0x916F, 0x53CD, 0x94BD, 0x53CE, 0x8EFB,
+	0x53D4, 0x8F66, 0x53D6, 0x8EE6, 0x53D7, 0x8EF3, 0x53D9, 0x8F96,
+	0x53DB, 0x94BE, 0x53DD, 0xFA8F, 0x53DF, 0x99D5, 0x53E1, 0x8962,
+	0x53E2, 0x9170, 0x53E3, 0x8CFB, 0x53E4, 0x8CC3, 0x53E5, 0x8BE5,
+	0x53E8, 0x99D9, 0x53E9, 0x9240, 0x53EA, 0x91FC, 0x53EB, 0x8BA9,
+	0x53EC, 0x8FA2, 0x53ED, 0x99DA, 0x53EE, 0x99D8, 0x53EF, 0x89C2,
+	0x53F0, 0x91E4, 0x53F1, 0x8EB6, 0x53F2, 0x8E6A, 0x53F3, 0x8945,
+	0x53F6, 0x8A90, 0x53F7, 0x8D86, 0x53F8, 0x8E69, 0x53FA, 0x99DB,
+	0x5401, 0x99DC, 0x5403, 0x8B68, 0x5404, 0x8A65, 0x5408, 0x8D87,
+	0x5409, 0x8B67, 0x540A, 0x92DD, 0x540B, 0x8944, 0x540C, 0x93AF,
+	0x540D, 0x96BC, 0x540E, 0x8D40, 0x540F, 0x9799, 0x5410, 0x9366,
+	0x5411, 0x8CFC, 0x541B, 0x8C4E, 0x541D, 0x99E5, 0x541F, 0x8BE1,
+	0x5420, 0x9669, 0x5426, 0x94DB, 0x5429, 0x99E4, 0x542B, 0x8ADC,
+	0x542C, 0x99DF, 0x542D, 0x99E0, 0x542E, 0x99E2, 0x5436, 0x99E3,
+	0x5438, 0x8B7A, 0x5439, 0x9081, 0x543B, 0x95AB, 0x543C, 0x99E1,
+	0x543D, 0x99DD, 0x543E, 0x8CE1, 0x5440, 0x99DE, 0x5442, 0x9843,
+	0x5446, 0x95F0, 0x5448, 0x92E6, 0x5449, 0x8CE0, 0x544A, 0x8D90,
+	0x544E, 0x99E6, 0x5451, 0x93DB, 0x545F, 0x99EA, 0x5468, 0x8EFC,
+	0x546A, 0x8EF4, 0x5470, 0x99ED, 0x5471, 0x99EB, 0x5473, 0x96A1,
+	0x5475, 0x99E8, 0x5476, 0x99F1, 0x5477, 0x99EC, 0x547B, 0x99EF,
+	0x547C, 0x8CC4, 0x547D, 0x96BD, 0x5480, 0x99F0, 0x5484, 0x99F2,
+	0x5486, 0x99F4, 0x548A, 0xFA92, 0x548B, 0x8DEE, 0x548C, 0x9861,
+	0x548E, 0x99E9, 0x548F, 0x99E7, 0x5490, 0x99F3, 0x5492, 0x99EE,
+	0x549C, 0xFA91, 0x54A2, 0x99F6, 0x54A4, 0x9A42, 0x54A5, 0x99F8,
+	0x54A8, 0x99FC, 0x54A9, 0xFA93, 0x54AB, 0x9A40, 0x54AC, 0x99F9,
+	0x54AF, 0x9A5D, 0x54B2, 0x8DE7, 0x54B3, 0x8A50, 0x54B8, 0x99F7,
+	0x54BC, 0x9A44, 0x54BD, 0x88F4, 0x54BE, 0x9A43, 0x54C0, 0x88A3,
+	0x54C1, 0x9569, 0x54C2, 0x9A41, 0x54C4, 0x99FA, 0x54C7, 0x99F5,
+	0x54C8, 0x99FB, 0x54C9, 0x8DC6, 0x54D8, 0x9A45, 0x54E1, 0x88F5,
+	0x54E2, 0x9A4E, 0x54E5, 0x9A46, 0x54E6, 0x9A47, 0x54E8, 0x8FA3,
+	0x54E9, 0x9689, 0x54ED, 0x9A4C, 0x54EE, 0x9A4B, 0x54F2, 0x934E,
+	0x54FA, 0x9A4D, 0x54FD, 0x9A4A, 0x54FF, 0xFA94, 0x5504, 0x8953,
+	0x5506, 0x8DB4, 0x5507, 0x904F, 0x550F, 0x9A48, 0x5510, 0x9382,
+	0x5514, 0x9A49, 0x5516, 0x88A0, 0x552E, 0x9A53, 0x552F, 0x9742,
+	0x5531, 0x8FA5, 0x5533, 0x9A59, 0x5538, 0x9A58, 0x5539, 0x9A4F,
+	0x553E, 0x91C1, 0x5540, 0x9A50, 0x5544, 0x91ED, 0x5545, 0x9A55,
+	0x5546, 0x8FA4, 0x554C, 0x9A52, 0x554F, 0x96E2, 0x5553, 0x8C5B,
+	0x5556, 0x9A56, 0x5557, 0x9A57, 0x555C, 0x9A54, 0x555D, 0x9A5A,
+	0x5563, 0x9A51, 0x557B, 0x9A60, 0x557C, 0x9A65, 0x557E, 0x9A61,
+	0x5580, 0x9A5C, 0x5583, 0x9A66, 0x5584, 0x9150, 0x5586, 0xFA95,
+	0x5587, 0x9A68, 0x5589, 0x8D41, 0x558A, 0x9A5E, 0x558B, 0x929D,
+	0x5598, 0x9A62, 0x5599, 0x9A5B, 0x559A, 0x8AAB, 0x559C, 0x8AEC,
+	0x559D, 0x8A85, 0x559E, 0x9A63, 0x559F, 0x9A5F, 0x55A7, 0x8C96,
+	0x55A8, 0x9A69, 0x55A9, 0x9A67, 0x55AA, 0x9172, 0x55AB, 0x8B69,
+	0x55AC, 0x8BAA, 0x55AE, 0x9A64, 0x55B0, 0x8BF2, 0x55B6, 0x8963,
+	0x55C4, 0x9A6D, 0x55C5, 0x9A6B, 0x55C7, 0x9AA5, 0x55D4, 0x9A70,
+	0x55DA, 0x9A6A, 0x55DC, 0x9A6E, 0x55DF, 0x9A6C, 0x55E3, 0x8E6B,
+	0x55E4, 0x9A6F, 0x55F7, 0x9A72, 0x55F9, 0x9A77, 0x55FD, 0x9A75,
+	0x55FE, 0x9A74, 0x5606, 0x9251, 0x5609, 0x89C3, 0x5614, 0x9A71,
+	0x5616, 0x9A73, 0x5617, 0x8FA6, 0x5618, 0x8952, 0x561B, 0x9A76,
+	0x5629, 0x89DC, 0x562F, 0x9A82, 0x5631, 0x8FFA, 0x5632, 0x9A7D,
+	0x5634, 0x9A7B, 0x5636, 0x9A7C, 0x5638, 0x9A7E, 0x5642, 0x895C,
+	0x564C, 0x9158, 0x564E, 0x9A78, 0x5650, 0x9A79, 0x565B, 0x8A9A,
+	0x5664, 0x9A81, 0x5668, 0x8AED, 0x566A, 0x9A84, 0x566B, 0x9A80,
+	0x566C, 0x9A83, 0x5674, 0x95AC, 0x5678, 0x93D3, 0x567A, 0x94B6,
+	0x5680, 0x9A86, 0x5686, 0x9A85, 0x5687, 0x8A64, 0x568A, 0x9A87,
+	0x568F, 0x9A8A, 0x5694, 0x9A89, 0x56A0, 0x9A88, 0x56A2, 0x9458,
+	0x56A5, 0x9A8B, 0x56AE, 0x9A8C, 0x56B4, 0x9A8E, 0x56B6, 0x9A8D,
+	0x56BC, 0x9A90, 0x56C0, 0x9A93, 0x56C1, 0x9A91, 0x56C2, 0x9A8F,
+	0x56C3, 0x9A92, 0x56C8, 0x9A94, 0x56CE, 0x9A95, 0x56D1, 0x9A96,
+	0x56D3, 0x9A97, 0x56D7, 0x9A98, 0x56D8, 0x9964, 0x56DA, 0x8EFA,
+	0x56DB, 0x8E6C, 0x56DE, 0x89F1, 0x56E0, 0x88F6, 0x56E3, 0x9263,
+	0x56EE, 0x9A99, 0x56F0, 0x8DA2, 0x56F2, 0x88CD, 0x56F3, 0x907D,
+	0x56F9, 0x9A9A, 0x56FA, 0x8CC5, 0x56FD, 0x8D91, 0x56FF, 0x9A9C,
+	0x5700, 0x9A9B, 0x5703, 0x95DE, 0x5704, 0x9A9D, 0x5708, 0x9A9F,
+	0x5709, 0x9A9E, 0x570B, 0x9AA0, 0x570D, 0x9AA1, 0x570F, 0x8C97,
+	0x5712, 0x8980, 0x5713, 0x9AA2, 0x5716, 0x9AA4, 0x5718, 0x9AA3,
+	0x571C, 0x9AA6, 0x571F, 0x9379, 0x5726, 0x9AA7, 0x5727, 0x88B3,
+	0x5728, 0x8DDD, 0x572D, 0x8C5C, 0x5730, 0x926E, 0x5737, 0x9AA8,
+	0x5738, 0x9AA9, 0x573B, 0x9AAB, 0x5740, 0x9AAC, 0x5742, 0x8DE2,
+	0x5747, 0x8BCF, 0x574A, 0x9656, 0x574E, 0x9AAA, 0x574F, 0x9AAD,
+	0x5750, 0x8DBF, 0x5751, 0x8D42, 0x5759, 0xFA96, 0x5761, 0x9AB1,
+	0x5764, 0x8DA3, 0x5765, 0xFA97, 0x5766, 0x9252, 0x5769, 0x9AAE,
+	0x576A, 0x92D8, 0x577F, 0x9AB2, 0x5782, 0x9082, 0x5788, 0x9AB0,
+	0x5789, 0x9AB3, 0x578B, 0x8C5E, 0x5793, 0x9AB4, 0x57A0, 0x9AB5,
+	0x57A2, 0x8D43, 0x57A3, 0x8A5F, 0x57A4, 0x9AB7, 0x57AA, 0x9AB8,
+	0x57AC, 0xFA98, 0x57B0, 0x9AB9, 0x57B3, 0x9AB6, 0x57C0, 0x9AAF,
+	0x57C3, 0x9ABA, 0x57C6, 0x9ABB, 0x57C7, 0xFA9A, 0x57C8, 0xFA99,
+	0x57CB, 0x9684, 0x57CE, 0x8FE9, 0x57D2, 0x9ABD, 0x57D3, 0x9ABE,
+	0x57D4, 0x9ABC, 0x57D6, 0x9AC0, 0x57DC, 0x9457, 0x57DF, 0x88E6,
+	0x57E0, 0x9575, 0x57E3, 0x9AC1, 0x57F4, 0x8FFB, 0x57F7, 0x8EB7,
+	0x57F9, 0x947C, 0x57FA, 0x8AEE, 0x57FC, 0x8DE9, 0x5800, 0x9678,
+	0x5802, 0x93B0, 0x5805, 0x8C98, 0x5806, 0x91CD, 0x580A, 0x9ABF,
+	0x580B, 0x9AC2, 0x5815, 0x91C2, 0x5819, 0x9AC3, 0x581D, 0x9AC4,
+	0x5821, 0x9AC6, 0x5824, 0x92E7, 0x582A, 0x8AAC, 0x582F, 0xEA9F,
+	0x5830, 0x8981, 0x5831, 0x95F1, 0x5834, 0x8FEA, 0x5835, 0x9367,
+	0x583A, 0x8DE4, 0x583D, 0x9ACC, 0x5840, 0x95BB, 0x5841, 0x97DB,
+	0x584A, 0x89F2, 0x584B, 0x9AC8, 0x5851, 0x9159, 0x5852, 0x9ACB,
+	0x5854, 0x9383, 0x5857, 0x9368, 0x5858, 0x9384, 0x5859, 0x94B7,
+	0x585A, 0x92CB, 0x585E, 0x8DC7, 0x5862, 0x9AC7, 0x5869, 0x8996,
+	0x586B, 0x9355, 0x5870, 0x9AC9, 0x5872, 0x9AC5, 0x5875, 0x906F,
+	0x5879, 0x9ACD, 0x587E, 0x8F6D, 0x5883, 0x8BAB, 0x5885, 0x9ACE,
+	0x5893, 0x95E6, 0x5897, 0x919D, 0x589C, 0x92C4, 0x589E, 0xFA9D,
+	0x589F, 0x9AD0, 0x58A8, 0x966E, 0x58AB, 0x9AD1, 0x58AE, 0x9AD6,
+	0x58B2, 0xFA9E, 0x58B3, 0x95AD, 0x58B8, 0x9AD5, 0x58B9, 0x9ACF,
+	0x58BA, 0x9AD2, 0x58BB, 0x9AD4, 0x58BE, 0x8DA4, 0x58C1, 0x95C7,
+	0x58C5, 0x9AD7, 0x58C7, 0x9264, 0x58CA, 0x89F3, 0x58CC, 0x8FEB,
+	0x58D1, 0x9AD9, 0x58D3, 0x9AD8, 0x58D5, 0x8D88, 0x58D7, 0x9ADA,
+	0x58D8, 0x9ADC, 0x58D9, 0x9ADB, 0x58DC, 0x9ADE, 0x58DE, 0x9AD3,
+	0x58DF, 0x9AE0, 0x58E4, 0x9ADF, 0x58E5, 0x9ADD, 0x58EB, 0x8E6D,
+	0x58EC, 0x9070, 0x58EE, 0x9173, 0x58EF, 0x9AE1, 0x58F0, 0x90BA,
+	0x58F1, 0x88EB, 0x58F2, 0x9484, 0x58F7, 0x92D9, 0x58F9, 0x9AE3,
+	0x58FA, 0x9AE2, 0x58FB, 0x9AE4, 0x58FC, 0x9AE5, 0x58FD, 0x9AE6,
+	0x5902, 0x9AE7, 0x5909, 0x95CF, 0x590A, 0x9AE8, 0x590B, 0xFA9F,
+	0x590F, 0x89C4, 0x5910, 0x9AE9, 0x5915, 0x975B, 0x5916, 0x8A4F,
+	0x5918, 0x99C7, 0x5919, 0x8F67, 0x591A, 0x91BD, 0x591B, 0x9AEA,
+	0x591C, 0x96E9, 0x5922, 0x96B2, 0x5925, 0x9AEC, 0x5927, 0x91E5,
+	0x5929, 0x9356, 0x592A, 0x91BE, 0x592B, 0x9576, 0x592C, 0x9AED,
+	0x592D, 0x9AEE, 0x592E, 0x899B, 0x5931, 0x8EB8, 0x5932, 0x9AEF,
+	0x5937, 0x88CE, 0x5938, 0x9AF0, 0x593E, 0x9AF1, 0x5944, 0x8982,
+	0x5947, 0x8AEF, 0x5948, 0x93DE, 0x5949, 0x95F2, 0x594E, 0x9AF5,
+	0x594F, 0x9174, 0x5950, 0x9AF4, 0x5951, 0x8C5F, 0x5953, 0xFAA0,
+	0x5954, 0x967A, 0x5955, 0x9AF3, 0x5957, 0x9385, 0x5958, 0x9AF7,
+	0x595A, 0x9AF6, 0x595B, 0xFAA1, 0x595D, 0xFAA2, 0x5960, 0x9AF9,
+	0x5962, 0x9AF8, 0x5963, 0xFAA3, 0x5965, 0x899C, 0x5967, 0x9AFA,
+	0x5968, 0x8FA7, 0x5969, 0x9AFC, 0x596A, 0x9244, 0x596C, 0x9AFB,
+	0x596E, 0x95B1, 0x5973, 0x8F97, 0x5974, 0x937A, 0x5978, 0x9B40,
+	0x597D, 0x8D44, 0x5981, 0x9B41, 0x5982, 0x9440, 0x5983, 0x94DC,
+	0x5984, 0x96CF, 0x598A, 0x9444, 0x598D, 0x9B4A, 0x5993, 0x8B57,
+	0x5996, 0x9764, 0x5999, 0x96AD, 0x599B, 0x9BAA, 0x599D, 0x9B42,
+	0x59A3, 0x9B45, 0x59A4, 0xFAA4, 0x59A5, 0x91C3, 0x59A8, 0x9657,
+	0x59AC, 0x9369, 0x59B2, 0x9B46, 0x59B9, 0x9685, 0x59BA, 0xFAA5,
+	0x59BB, 0x8DC8, 0x59BE, 0x8FA8, 0x59C6, 0x9B47, 0x59C9, 0x8E6F,
+	0x59CB, 0x8E6E, 0x59D0, 0x88B7, 0x59D1, 0x8CC6, 0x59D3, 0x90A9,
+	0x59D4, 0x88CF, 0x59D9, 0x9B4B, 0x59DA, 0x9B4C, 0x59DC, 0x9B49,
+	0x59E5, 0x8957, 0x59E6, 0x8AAD, 0x59E8, 0x9B48, 0x59EA, 0x96C3,
+	0x59EB, 0x9550, 0x59F6, 0x88A6, 0x59FB, 0x88F7, 0x59FF, 0x8E70,
+	0x5A01, 0x88D0, 0x5A03, 0x88A1, 0x5A09, 0x9B51, 0x5A11, 0x9B4F,
+	0x5A18, 0x96BA, 0x5A1A, 0x9B52, 0x5A1C, 0x9B50, 0x5A1F, 0x9B4E,
+	0x5A20, 0x9050, 0x5A25, 0x9B4D, 0x5A29, 0x95D8, 0x5A2F, 0x8CE2,
+	0x5A35, 0x9B56, 0x5A36, 0x9B57, 0x5A3C, 0x8FA9, 0x5A40, 0x9B53,
+	0x5A41, 0x984B, 0x5A46, 0x946B, 0x5A49, 0x9B55, 0x5A5A, 0x8DA5,
+	0x5A62, 0x9B58, 0x5A66, 0x9577, 0x5A6A, 0x9B59, 0x5A6C, 0x9B54,
+	0x5A7F, 0x96B9, 0x5A92, 0x947D, 0x5A9A, 0x9B5A, 0x5A9B, 0x9551,
+	0x5ABC, 0x9B5B, 0x5ABD, 0x9B5F, 0x5ABE, 0x9B5C, 0x5AC1, 0x89C5,
+	0x5AC2, 0x9B5E, 0x5AC9, 0x8EB9, 0x5ACB, 0x9B5D, 0x5ACC, 0x8C99,
+	0x5AD0, 0x9B6B, 0x5AD6, 0x9B64, 0x5AD7, 0x9B61, 0x5AE1, 0x9284,
+	0x5AE3, 0x9B60, 0x5AE6, 0x9B62, 0x5AE9, 0x9B63, 0x5AFA, 0x9B65,
+	0x5AFB, 0x9B66, 0x5B09, 0x8AF0, 0x5B0B, 0x9B68, 0x5B0C, 0x9B67,
+	0x5B16, 0x9B69, 0x5B22, 0x8FEC, 0x5B2A, 0x9B6C, 0x5B2C, 0x92DA,
+	0x5B30, 0x8964, 0x5B32, 0x9B6A, 0x5B36, 0x9B6D, 0x5B3E, 0x9B6E,
+	0x5B40, 0x9B71, 0x5B43, 0x9B6F, 0x5B45, 0x9B70, 0x5B50, 0x8E71,
+	0x5B51, 0x9B72, 0x5B54, 0x8D45, 0x5B55, 0x9B73, 0x5B56, 0xFAA6,
+	0x5B57, 0x8E9A, 0x5B58, 0x91B6, 0x5B5A, 0x9B74, 0x5B5B, 0x9B75,
+	0x5B5C, 0x8E79, 0x5B5D, 0x8D46, 0x5B5F, 0x96D0, 0x5B63, 0x8B47,
+	0x5B64, 0x8CC7, 0x5B65, 0x9B76, 0x5B66, 0x8A77, 0x5B69, 0x9B77,
+	0x5B6B, 0x91B7, 0x5B70, 0x9B78, 0x5B71, 0x9BA1, 0x5B73, 0x9B79,
+	0x5B75, 0x9B7A, 0x5B78, 0x9B7B, 0x5B7A, 0x9B7D, 0x5B80, 0x9B7E,
+	0x5B83, 0x9B80, 0x5B85, 0x91EE, 0x5B87, 0x8946, 0x5B88, 0x8EE7,
+	0x5B89, 0x88C0, 0x5B8B, 0x9176, 0x5B8C, 0x8AAE, 0x5B8D, 0x8EB3,
+	0x5B8F, 0x8D47, 0x5B95, 0x9386, 0x5B97, 0x8F40, 0x5B98, 0x8AAF,
+	0x5B99, 0x9288, 0x5B9A, 0x92E8, 0x5B9B, 0x88B6, 0x5B9C, 0x8B58,
+	0x5B9D, 0x95F3, 0x5B9F, 0x8EC0, 0x5BA2, 0x8B71, 0x5BA3, 0x90E9,
+	0x5BA4, 0x8EBA, 0x5BA5, 0x9747, 0x5BA6, 0x9B81, 0x5BAE, 0x8B7B,
+	0x5BB0, 0x8DC9, 0x5BB3, 0x8A51, 0x5BB4, 0x8983, 0x5BB5, 0x8FAA,
+	0x5BB6, 0x89C6, 0x5BB8, 0x9B82, 0x5BB9, 0x9765, 0x5BBF, 0x8F68,
+	0x5BC0, 0xFAA7, 0x5BC2, 0x8EE2, 0x5BC3, 0x9B83, 0x5BC4, 0x8AF1,
+	0x5BC5, 0x93D0, 0x5BC6, 0x96A7, 0x5BC7, 0x9B84, 0x5BC9, 0x9B85,
+	0x5BCC, 0x9578, 0x5BD0, 0x9B87, 0x5BD2, 0x8AA6, 0x5BD3, 0x8BF5,
+	0x5BD4, 0x9B86, 0x5BD8, 0xFAA9, 0x5BDB, 0x8AB0, 0x5BDD, 0x9051,
+	0x5BDE, 0x9B8B, 0x5BDF, 0x8E40, 0x5BE1, 0x89C7, 0x5BE2, 0x9B8A,
+	0x5BE4, 0x9B88, 0x5BE5, 0x9B8C, 0x5BE6, 0x9B89, 0x5BE7, 0x944A,
+	0x5BE8, 0x9ECB, 0x5BE9, 0x9052, 0x5BEB, 0x9B8D, 0x5BEC, 0xFAAA,
+	0x5BEE, 0x97BE, 0x5BF0, 0x9B8E, 0x5BF3, 0x9B90, 0x5BF5, 0x929E,
+	0x5BF6, 0x9B8F, 0x5BF8, 0x90A1, 0x5BFA, 0x8E9B, 0x5BFE, 0x91CE,
+	0x5BFF, 0x8EF5, 0x5C01, 0x9595, 0x5C02, 0x90EA, 0x5C04, 0x8ECB,
+	0x5C05, 0x9B91, 0x5C06, 0x8FAB, 0x5C07, 0x9B92, 0x5C08, 0x9B93,
+	0x5C09, 0x88D1, 0x5C0A, 0x91B8, 0x5C0B, 0x9071, 0x5C0D, 0x9B94,
+	0x5C0E, 0x93B1, 0x5C0F, 0x8FAC, 0x5C11, 0x8FAD, 0x5C13, 0x9B95,
+	0x5C16, 0x90EB, 0x5C1A, 0x8FAE, 0x5C1E, 0xFAAB, 0x5C20, 0x9B96,
+	0x5C22, 0x9B97, 0x5C24, 0x96DE, 0x5C28, 0x9B98, 0x5C2D, 0x8BC4,
+	0x5C31, 0x8F41, 0x5C38, 0x9B99, 0x5C39, 0x9B9A, 0x5C3A, 0x8EDA,
+	0x5C3B, 0x904B, 0x5C3C, 0x93F2, 0x5C3D, 0x9073, 0x5C3E, 0x94F6,
+	0x5C3F, 0x9441, 0x5C40, 0x8BC7, 0x5C41, 0x9B9B, 0x5C45, 0x8B8F,
+	0x5C46, 0x9B9C, 0x5C48, 0x8BFC, 0x5C4A, 0x93CD, 0x5C4B, 0x89AE,
+	0x5C4D, 0x8E72, 0x5C4E, 0x9B9D, 0x5C4F, 0x9BA0, 0x5C50, 0x9B9F,
+	0x5C51, 0x8BFB, 0x5C53, 0x9B9E, 0x5C55, 0x9357, 0x5C5E, 0x91AE,
+	0x5C60, 0x936A, 0x5C61, 0x8EC6, 0x5C64, 0x9177, 0x5C65, 0x979A,
+	0x5C6C, 0x9BA2, 0x5C6E, 0x9BA3, 0x5C6F, 0x93D4, 0x5C71, 0x8E52,
+	0x5C76, 0x9BA5, 0x5C79, 0x9BA6, 0x5C8C, 0x9BA7, 0x5C90, 0x8AF2,
+	0x5C91, 0x9BA8, 0x5C94, 0x9BA9, 0x5CA1, 0x89AA, 0x5CA6, 0xFAAC,
+	0x5CA8, 0x915A, 0x5CA9, 0x8AE2, 0x5CAB, 0x9BAB, 0x5CAC, 0x96A6,
+	0x5CB1, 0x91D0, 0x5CB3, 0x8A78, 0x5CB6, 0x9BAD, 0x5CB7, 0x9BAF,
+	0x5CB8, 0x8ADD, 0x5CBA, 0xFAAD, 0x5CBB, 0x9BAC, 0x5CBC, 0x9BAE,
+	0x5CBE, 0x9BB1, 0x5CC5, 0x9BB0, 0x5CC7, 0x9BB2, 0x5CD9, 0x9BB3,
+	0x5CE0, 0x93BB, 0x5CE1, 0x8BAC, 0x5CE8, 0x89E3, 0x5CE9, 0x9BB4,
+	0x5CEA, 0x9BB9, 0x5CED, 0x9BB7, 0x5CEF, 0x95F5, 0x5CF0, 0x95F4,
+	0x5CF5, 0xFAAE, 0x5CF6, 0x9387, 0x5CFA, 0x9BB6, 0x5CFB, 0x8F73,
+	0x5CFD, 0x9BB5, 0x5D07, 0x9092, 0x5D0B, 0x9BBA, 0x5D0E, 0x8DE8,
+	0x5D11, 0x9BC0, 0x5D14, 0x9BC1, 0x5D15, 0x9BBB, 0x5D16, 0x8A52,
+	0x5D17, 0x9BBC, 0x5D18, 0x9BC5, 0x5D19, 0x9BC4, 0x5D1A, 0x9BC3,
+	0x5D1B, 0x9BBF, 0x5D1F, 0x9BBE, 0x5D22, 0x9BC2, 0x5D27, 0xFAAF,
+	0x5D29, 0x95F6, 0x5D42, 0xFAB2, 0x5D4B, 0x9BC9, 0x5D4C, 0x9BC6,
+	0x5D4E, 0x9BC8, 0x5D50, 0x9792, 0x5D52, 0x9BC7, 0x5D53, 0xFAB0,
+	0x5D5C, 0x9BBD, 0x5D69, 0x9093, 0x5D6C, 0x9BCA, 0x5D6D, 0xFAB3,
+	0x5D6F, 0x8DB5, 0x5D73, 0x9BCB, 0x5D76, 0x9BCC, 0x5D82, 0x9BCF,
+	0x5D84, 0x9BCE, 0x5D87, 0x9BCD, 0x5D8B, 0x9388, 0x5D8C, 0x9BB8,
+	0x5D90, 0x9BD5, 0x5D9D, 0x9BD1, 0x5DA2, 0x9BD0, 0x5DAC, 0x9BD2,
+	0x5DAE, 0x9BD3, 0x5DB7, 0x9BD6, 0x5DB8, 0xFAB4, 0x5DB9, 0xFAB5,
+	0x5DBA, 0x97E4, 0x5DBC, 0x9BD7, 0x5DBD, 0x9BD4, 0x5DC9, 0x9BD8,
+	0x5DCC, 0x8ADE, 0x5DCD, 0x9BD9, 0x5DD0, 0xFAB6, 0x5DD2, 0x9BDB,
+	0x5DD3, 0x9BDA, 0x5DD6, 0x9BDC, 0x5DDB, 0x9BDD, 0x5DDD, 0x90EC,
+	0x5DDE, 0x8F42, 0x5DE1, 0x8F84, 0x5DE3, 0x9183, 0x5DE5, 0x8D48,
+	0x5DE6, 0x8DB6, 0x5DE7, 0x8D49, 0x5DE8, 0x8B90, 0x5DEB, 0x9BDE,
+	0x5DEE, 0x8DB7, 0x5DF1, 0x8CC8, 0x5DF2, 0x9BDF, 0x5DF3, 0x96A4,
+	0x5DF4, 0x9462, 0x5DF5, 0x9BE0, 0x5DF7, 0x8D4A, 0x5DFB, 0x8AAA,
+	0x5DFD, 0x9246, 0x5DFE, 0x8BD0, 0x5E02, 0x8E73, 0x5E03, 0x957A,
+	0x5E06, 0x94BF, 0x5E0B, 0x9BE1, 0x5E0C, 0x8AF3, 0x5E11, 0x9BE4,
+	0x5E16, 0x929F, 0x5E19, 0x9BE3, 0x5E1A, 0x9BE2, 0x5E1B, 0x9BE5,
+	0x5E1D, 0x92E9, 0x5E25, 0x9083, 0x5E2B, 0x8E74, 0x5E2D, 0x90C8,
+	0x5E2F, 0x91D1, 0x5E30, 0x8B41, 0x5E33, 0x92A0, 0x5E36, 0x9BE6,
+	0x5E37, 0x9BE7, 0x5E38, 0x8FED, 0x5E3D, 0x9658, 0x5E40, 0x9BEA,
+	0x5E43, 0x9BE9, 0x5E44, 0x9BE8, 0x5E45, 0x959D, 0x5E47, 0x9BF1,
+	0x5E4C, 0x9679, 0x5E4E, 0x9BEB, 0x5E54, 0x9BED, 0x5E55, 0x968B,
+	0x5E57, 0x9BEC, 0x5E5F, 0x9BEE, 0x5E61, 0x94A6, 0x5E62, 0x9BEF,
+	0x5E63, 0x95BC, 0x5E64, 0x9BF0, 0x5E72, 0x8AB1, 0x5E73, 0x95BD,
+	0x5E74, 0x944E, 0x5E75, 0x9BF2, 0x5E76, 0x9BF3, 0x5E78, 0x8D4B,
+	0x5E79, 0x8AB2, 0x5E7A, 0x9BF4, 0x5E7B, 0x8CB6, 0x5E7C, 0x9763,
+	0x5E7D, 0x9748, 0x5E7E, 0x8AF4, 0x5E7F, 0x9BF6, 0x5E81, 0x92A1,
+	0x5E83, 0x8D4C, 0x5E84, 0x8FAF, 0x5E87, 0x94DD, 0x5E8A, 0x8FB0,
+	0x5E8F, 0x8F98, 0x5E95, 0x92EA, 0x5E96, 0x95F7, 0x5E97, 0x9358,
+	0x5E9A, 0x8D4D, 0x5E9C, 0x957B, 0x5EA0, 0x9BF7, 0x5EA6, 0x9378,
+	0x5EA7, 0x8DC0, 0x5EAB, 0x8CC9, 0x5EAD, 0x92EB, 0x5EB5, 0x88C1,
+	0x5EB6, 0x8F8E, 0x5EB7, 0x8D4E, 0x5EB8, 0x9766, 0x5EC1, 0x9BF8,
+	0x5EC2, 0x9BF9, 0x5EC3, 0x9470, 0x5EC8, 0x9BFA, 0x5EC9, 0x97F5,
+	0x5ECA, 0x984C, 0x5ECF, 0x9BFC, 0x5ED0, 0x9BFB, 0x5ED3, 0x8A66,
+	0x5ED6, 0x9C40, 0x5EDA, 0x9C43, 0x5EDB, 0x9C44, 0x5EDD, 0x9C42,
+	0x5EDF, 0x955F, 0x5EE0, 0x8FB1, 0x5EE1, 0x9C46, 0x5EE2, 0x9C45,
+	0x5EE3, 0x9C41, 0x5EE8, 0x9C47, 0x5EE9, 0x9C48, 0x5EEC, 0x9C49,
+	0x5EF0, 0x9C4C, 0x5EF1, 0x9C4A, 0x5EF3, 0x9C4B, 0x5EF4, 0x9C4D,
+	0x5EF6, 0x8984, 0x5EF7, 0x92EC, 0x5EF8, 0x9C4E, 0x5EFA, 0x8C9A,
+	0x5EFB, 0x89F4, 0x5EFC, 0x9455, 0x5EFE, 0x9C4F, 0x5EFF, 0x93F9,
+	0x5F01, 0x95D9, 0x5F03, 0x9C50, 0x5F04, 0x984D, 0x5F09, 0x9C51,
+	0x5F0A, 0x95BE, 0x5F0B, 0x9C54, 0x5F0C, 0x989F, 0x5F0D, 0x98AF,
+	0x5F0F, 0x8EAE, 0x5F10, 0x93F3, 0x5F11, 0x9C55, 0x5F13, 0x8B7C,
+	0x5F14, 0x92A2, 0x5F15, 0x88F8, 0x5F16, 0x9C56, 0x5F17, 0x95A4,
+	0x5F18, 0x8D4F, 0x5F1B, 0x926F, 0x5F1F, 0x92ED, 0x5F21, 0xFAB7,
+	0x5F25, 0x96ED, 0x5F26, 0x8CB7, 0x5F27, 0x8CCA, 0x5F29, 0x9C57,
+	0x5F2D, 0x9C58, 0x5F2F, 0x9C5E, 0x5F31, 0x8EE3, 0x5F34, 0xFAB8,
+	0x5F35, 0x92A3, 0x5F37, 0x8BAD, 0x5F38, 0x9C59, 0x5F3C, 0x954A,
+	0x5F3E, 0x9265, 0x5F41, 0x9C5A, 0x5F45, 0xFA67, 0x5F48, 0x9C5B,
+	0x5F4A, 0x8BAE, 0x5F4C, 0x9C5C, 0x5F4E, 0x9C5D, 0x5F51, 0x9C5F,
+	0x5F53, 0x9396, 0x5F56, 0x9C60, 0x5F57, 0x9C61, 0x5F59, 0x9C62,
+	0x5F5C, 0x9C53, 0x5F5D, 0x9C52, 0x5F61, 0x9C63, 0x5F62, 0x8C60,
+	0x5F66, 0x9546, 0x5F67, 0xFAB9, 0x5F69, 0x8DCA, 0x5F6A, 0x9556,
+	0x5F6B, 0x92A4, 0x5F6C, 0x956A, 0x5F6D, 0x9C64, 0x5F70, 0x8FB2,
+	0x5F71, 0x8965, 0x5F73, 0x9C65, 0x5F77, 0x9C66, 0x5F79, 0x96F0,
+	0x5F7C, 0x94DE, 0x5F7F, 0x9C69, 0x5F80, 0x899D, 0x5F81, 0x90AA,
+	0x5F82, 0x9C68, 0x5F83, 0x9C67, 0x5F84, 0x8C61, 0x5F85, 0x91D2,
+	0x5F87, 0x9C6D, 0x5F88, 0x9C6B, 0x5F8A, 0x9C6A, 0x5F8B, 0x97A5,
+	0x5F8C, 0x8CE3, 0x5F90, 0x8F99, 0x5F91, 0x9C6C, 0x5F92, 0x936B,
+	0x5F93, 0x8F5D, 0x5F97, 0x93BE, 0x5F98, 0x9C70, 0x5F99, 0x9C6F,
+	0x5F9E, 0x9C6E, 0x5FA0, 0x9C71, 0x5FA1, 0x8CE4, 0x5FA8, 0x9C72,
+	0x5FA9, 0x959C, 0x5FAA, 0x8F7A, 0x5FAD, 0x9C73, 0x5FAE, 0x94F7,
+	0x5FB3, 0x93BF, 0x5FB4, 0x92A5, 0x5FB7, 0xFABA, 0x5FB9, 0x934F,
+	0x5FBC, 0x9C74, 0x5FBD, 0x8B4A, 0x5FC3, 0x9053, 0x5FC5, 0x954B,
+	0x5FCC, 0x8AF5, 0x5FCD, 0x9445, 0x5FD6, 0x9C75, 0x5FD7, 0x8E75,
+	0x5FD8, 0x9659, 0x5FD9, 0x965A, 0x5FDC, 0x899E, 0x5FDD, 0x9C7A,
+	0x5FDE, 0xFABB, 0x5FE0, 0x9289, 0x5FE4, 0x9C77, 0x5FEB, 0x89F5,
+	0x5FF0, 0x9CAB, 0x5FF1, 0x9C79, 0x5FF5, 0x944F, 0x5FF8, 0x9C78,
+	0x5FFB, 0x9C76, 0x5FFD, 0x8D9A, 0x5FFF, 0x9C7C, 0x600E, 0x9C83,
+	0x600F, 0x9C89, 0x6010, 0x9C81, 0x6012, 0x937B, 0x6015, 0x9C86,
+	0x6016, 0x957C, 0x6019, 0x9C80, 0x601B, 0x9C85, 0x601C, 0x97E5,
+	0x601D, 0x8E76, 0x6020, 0x91D3, 0x6021, 0x9C7D, 0x6025, 0x8B7D,
+	0x6026, 0x9C88, 0x6027, 0x90AB, 0x6028, 0x8985, 0x6029, 0x9C82,
+	0x602A, 0x89F6, 0x602B, 0x9C87, 0x602F, 0x8BAF, 0x6031, 0x9C84,
+	0x603A, 0x9C8A, 0x6041, 0x9C8C, 0x6042, 0x9C96, 0x6043, 0x9C94,
+	0x6046, 0x9C91, 0x604A, 0x9C90, 0x604B, 0x97F6, 0x604D, 0x9C92,
+	0x6050, 0x8BB0, 0x6052, 0x8D50, 0x6055, 0x8F9A, 0x6059, 0x9C99,
+	0x605A, 0x9C8B, 0x605D, 0xFABC, 0x605F, 0x9C8F, 0x6060, 0x9C7E,
+	0x6062, 0x89F8, 0x6063, 0x9C93, 0x6064, 0x9C95, 0x6065, 0x9270,
+	0x6068, 0x8DA6, 0x6069, 0x89B6, 0x606A, 0x9C8D, 0x606B, 0x9C98,
+	0x606C, 0x9C97, 0x606D, 0x8BB1, 0x606F, 0x91A7, 0x6070, 0x8A86,
+	0x6075, 0x8C62, 0x6077, 0x9C8E, 0x6081, 0x9C9A, 0x6083, 0x9C9D,
+	0x6084, 0x9C9F, 0x6085, 0xFABD, 0x6089, 0x8EBB, 0x608A, 0xFABE,
+	0x608B, 0x9CA5, 0x608C, 0x92EE, 0x608D, 0x9C9B, 0x6092, 0x9CA3,
+	0x6094, 0x89F7, 0x6096, 0x9CA1, 0x6097, 0x9CA2, 0x609A, 0x9C9E,
+	0x609B, 0x9CA0, 0x609F, 0x8CE5, 0x60A0, 0x9749, 0x60A3, 0x8AB3,
+	0x60A6, 0x8978, 0x60A7, 0x9CA4, 0x60A9, 0x9459, 0x60AA, 0x88AB,
+	0x60B2, 0x94DF, 0x60B3, 0x9C7B, 0x60B4, 0x9CAA, 0x60B5, 0x9CAE,
+	0x60B6, 0x96E3, 0x60B8, 0x9CA7, 0x60BC, 0x9389, 0x60BD, 0x9CAC,
+	0x60C5, 0x8FEE, 0x60C6, 0x9CAD, 0x60C7, 0x93D5, 0x60D1, 0x9866,
+	0x60D3, 0x9CA9, 0x60D5, 0xFAC0, 0x60D8, 0x9CAF, 0x60DA, 0x8D9B,
+	0x60DC, 0x90C9, 0x60DE, 0xFABF, 0x60DF, 0x88D2, 0x60E0, 0x9CA8,
+	0x60E1, 0x9CA6, 0x60E3, 0x9179, 0x60E7, 0x9C9C, 0x60E8, 0x8E53,
+	0x60F0, 0x91C4, 0x60F1, 0x9CBB, 0x60F2, 0xFAC2, 0x60F3, 0x917A,
+	0x60F4, 0x9CB6, 0x60F6, 0x9CB3, 0x60F7, 0x9CB4, 0x60F9, 0x8EE4,
+	0x60FA, 0x9CB7, 0x60FB, 0x9CBA, 0x6100, 0x9CB5, 0x6101, 0x8F44,
+	0x6103, 0x9CB8, 0x6106, 0x9CB2, 0x6108, 0x96FA, 0x6109, 0x96F9,
+	0x610D, 0x9CBC, 0x610E, 0x9CBD, 0x610F, 0x88D3, 0x6111, 0xFAC3,
+	0x6115, 0x9CB1, 0x611A, 0x8BF0, 0x611B, 0x88A4, 0x611F, 0x8AB4,
+	0x6120, 0xFAC1, 0x6121, 0x9CB9, 0x6127, 0x9CC1, 0x6128, 0x9CC0,
+	0x612C, 0x9CC5, 0x6130, 0xFAC5, 0x6134, 0x9CC6, 0x6137, 0xFAC4,
+	0x613C, 0x9CC4, 0x613D, 0x9CC7, 0x613E, 0x9CBF, 0x613F, 0x9CC3,
+	0x6142, 0x9CC8, 0x6144, 0x9CC9, 0x6147, 0x9CBE, 0x6148, 0x8E9C,
+	0x614A, 0x9CC2, 0x614B, 0x91D4, 0x614C, 0x8D51, 0x614D, 0x9CB0,
+	0x614E, 0x9054, 0x6153, 0x9CD6, 0x6155, 0x95E7, 0x6158, 0x9CCC,
+	0x6159, 0x9CCD, 0x615A, 0x9CCE, 0x615D, 0x9CD5, 0x615F, 0x9CD4,
+	0x6162, 0x969D, 0x6163, 0x8AB5, 0x6165, 0x9CD2, 0x6167, 0x8C64,
+	0x6168, 0x8A53, 0x616B, 0x9CCF, 0x616E, 0x97B6, 0x616F, 0x9CD1,
+	0x6170, 0x88D4, 0x6171, 0x9CD3, 0x6173, 0x9CCA, 0x6174, 0x9CD0,
+	0x6175, 0x9CD7, 0x6176, 0x8C63, 0x6177, 0x9CCB, 0x617E, 0x977C,
+	0x6182, 0x974A, 0x6187, 0x9CDA, 0x618A, 0x9CDE, 0x618E, 0x919E,
+	0x6190, 0x97F7, 0x6191, 0x9CDF, 0x6194, 0x9CDC, 0x6196, 0x9CD9,
+	0x6198, 0xFAC6, 0x6199, 0x9CD8, 0x619A, 0x9CDD, 0x61A4, 0x95AE,
+	0x61A7, 0x93B2, 0x61A9, 0x8C65, 0x61AB, 0x9CE0, 0x61AC, 0x9CDB,
+	0x61AE, 0x9CE1, 0x61B2, 0x8C9B, 0x61B6, 0x89AF, 0x61BA, 0x9CE9,
+	0x61BE, 0x8AB6, 0x61C3, 0x9CE7, 0x61C6, 0x9CE8, 0x61C7, 0x8DA7,
+	0x61C8, 0x9CE6, 0x61C9, 0x9CE4, 0x61CA, 0x9CE3, 0x61CB, 0x9CEA,
+	0x61CC, 0x9CE2, 0x61CD, 0x9CEC, 0x61D0, 0x89F9, 0x61E3, 0x9CEE,
+	0x61E6, 0x9CED, 0x61F2, 0x92A6, 0x61F4, 0x9CF1, 0x61F6, 0x9CEF,
+	0x61F7, 0x9CE5, 0x61F8, 0x8C9C, 0x61FA, 0x9CF0, 0x61FC, 0x9CF4,
+	0x61FD, 0x9CF3, 0x61FE, 0x9CF5, 0x61FF, 0x9CF2, 0x6200, 0x9CF6,
+	0x6208, 0x9CF7, 0x6209, 0x9CF8, 0x620A, 0x95E8, 0x620C, 0x9CFA,
+	0x620D, 0x9CF9, 0x620E, 0x8F5E, 0x6210, 0x90AC, 0x6211, 0x89E4,
+	0x6212, 0x89FA, 0x6213, 0xFAC7, 0x6214, 0x9CFB, 0x6216, 0x88BD,
+	0x621A, 0x90CA, 0x621B, 0x9CFC, 0x621D, 0xE6C1, 0x621E, 0x9D40,
+	0x621F, 0x8C81, 0x6221, 0x9D41, 0x6226, 0x90ED, 0x622A, 0x9D42,
+	0x622E, 0x9D43, 0x622F, 0x8B59, 0x6230, 0x9D44, 0x6232, 0x9D45,
+	0x6233, 0x9D46, 0x6234, 0x91D5, 0x6238, 0x8CCB, 0x623B, 0x96DF,
+	0x623F, 0x965B, 0x6240, 0x8F8A, 0x6241, 0x9D47, 0x6247, 0x90EE,
+	0x6248, 0xE7BB, 0x6249, 0x94E0, 0x624B, 0x8EE8, 0x624D, 0x8DCB,
+	0x624E, 0x9D48, 0x6253, 0x91C5, 0x6255, 0x95A5, 0x6258, 0x91EF,
+	0x625B, 0x9D4B, 0x625E, 0x9D49, 0x6260, 0x9D4C, 0x6263, 0x9D4A,
+	0x6268, 0x9D4D, 0x626E, 0x95AF, 0x6271, 0x88B5, 0x6276, 0x957D,
+	0x6279, 0x94E1, 0x627C, 0x9D4E, 0x627E, 0x9D51, 0x627F, 0x8FB3,
+	0x6280, 0x8B5A, 0x6282, 0x9D4F, 0x6283, 0x9D56, 0x6284, 0x8FB4,
+	0x6289, 0x9D50, 0x628A, 0x9463, 0x6291, 0x977D, 0x6292, 0x9D52,
+	0x6293, 0x9D53, 0x6294, 0x9D57, 0x6295, 0x938A, 0x6296, 0x9D54,
+	0x6297, 0x8D52, 0x6298, 0x90DC, 0x629B, 0x9D65, 0x629C, 0x94B2,
+	0x629E, 0x91F0, 0x62A6, 0xFAC8, 0x62AB, 0x94E2, 0x62AC, 0x9DAB,
+	0x62B1, 0x95F8, 0x62B5, 0x92EF, 0x62B9, 0x9695, 0x62BB, 0x9D5A,
+	0x62BC, 0x899F, 0x62BD, 0x928A, 0x62C2, 0x9D63, 0x62C5, 0x9253,
+	0x62C6, 0x9D5D, 0x62C7, 0x9D64, 0x62C8, 0x9D5F, 0x62C9, 0x9D66,
+	0x62CA, 0x9D62, 0x62CC, 0x9D61, 0x62CD, 0x948F, 0x62CF, 0x9D5B,
+	0x62D0, 0x89FB, 0x62D1, 0x9D59, 0x62D2, 0x8B91, 0x62D3, 0x91F1,
+	0x62D4, 0x9D55, 0x62D7, 0x9D58, 0x62D8, 0x8D53, 0x62D9, 0x90D9,
+	0x62DB, 0x8FB5, 0x62DC, 0x9D60, 0x62DD, 0x9471, 0x62E0, 0x8B92,
+	0x62E1, 0x8A67, 0x62EC, 0x8A87, 0x62ED, 0x9040, 0x62EE, 0x9D68,
+	0x62EF, 0x9D6D, 0x62F1, 0x9D69, 0x62F3, 0x8C9D, 0x62F5, 0x9D6E,
+	0x62F6, 0x8E41, 0x62F7, 0x8D89, 0x62FE, 0x8F45, 0x62FF, 0x9D5C,
+	0x6301, 0x8E9D, 0x6302, 0x9D6B, 0x6307, 0x8E77, 0x6308, 0x9D6C,
+	0x6309, 0x88C2, 0x630C, 0x9D67, 0x6311, 0x92A7, 0x6319, 0x8B93,
+	0x631F, 0x8BB2, 0x6327, 0x9D6A, 0x6328, 0x88A5, 0x632B, 0x8DC1,
+	0x632F, 0x9055, 0x633A, 0x92F0, 0x633D, 0x94D2, 0x633E, 0x9D70,
+	0x633F, 0x917D, 0x6349, 0x91A8, 0x634C, 0x8E4A, 0x634D, 0x9D71,
+	0x634F, 0x9D73, 0x6350, 0x9D6F, 0x6355, 0x95DF, 0x6357, 0x92BB,
+	0x635C, 0x917B, 0x6367, 0x95F9, 0x6368, 0x8ECC, 0x6369, 0x9D80,
+	0x636B, 0x9D7E, 0x636E, 0x9098, 0x6372, 0x8C9E, 0x6376, 0x9D78,
+	0x6377, 0x8FB7, 0x637A, 0x93E6, 0x637B, 0x9450, 0x6380, 0x9D76,
+	0x6383, 0x917C, 0x6388, 0x8EF6, 0x6389, 0x9D7B, 0x638C, 0x8FB6,
+	0x638E, 0x9D75, 0x638F, 0x9D7A, 0x6392, 0x9472, 0x6396, 0x9D74,
+	0x6398, 0x8C40, 0x639B, 0x8A7C, 0x639F, 0x9D7C, 0x63A0, 0x97A9,
+	0x63A1, 0x8DCC, 0x63A2, 0x9254, 0x63A3, 0x9D79, 0x63A5, 0x90DA,
+	0x63A7, 0x8D54, 0x63A8, 0x9084, 0x63A9, 0x8986, 0x63AA, 0x915B,
+	0x63AB, 0x9D77, 0x63AC, 0x8B64, 0x63B2, 0x8C66, 0x63B4, 0x92CD,
+	0x63B5, 0x9D7D, 0x63BB, 0x917E, 0x63BE, 0x9D81, 0x63C0, 0x9D83,
+	0x63C3, 0x91B5, 0x63C4, 0x9D89, 0x63C6, 0x9D84, 0x63C9, 0x9D86,
+	0x63CF, 0x9560, 0x63D0, 0x92F1, 0x63D2, 0x9D87, 0x63D6, 0x974B,
+	0x63DA, 0x9767, 0x63DB, 0x8AB7, 0x63E1, 0x88AC, 0x63E3, 0x9D85,
+	0x63E9, 0x9D82, 0x63EE, 0x8AF6, 0x63F4, 0x8987, 0x63F5, 0xFAC9,
+	0x63F6, 0x9D88, 0x63FA, 0x9768, 0x6406, 0x9D8C, 0x640D, 0x91B9,
+	0x640F, 0x9D93, 0x6413, 0x9D8D, 0x6416, 0x9D8A, 0x6417, 0x9D91,
+	0x641C, 0x9D72, 0x6426, 0x9D8E, 0x6428, 0x9D92, 0x642C, 0x94C0,
+	0x642D, 0x938B, 0x6434, 0x9D8B, 0x6436, 0x9D8F, 0x643A, 0x8C67,
+	0x643E, 0x8DEF, 0x6442, 0x90DB, 0x644E, 0x9D97, 0x6458, 0x9345,
+	0x6460, 0xFACA, 0x6467, 0x9D94, 0x6469, 0x9680, 0x646F, 0x9D95,
+	0x6476, 0x9D96, 0x6478, 0x96CC, 0x647A, 0x90A0, 0x6483, 0x8C82,
+	0x6488, 0x9D9D, 0x6492, 0x8E54, 0x6493, 0x9D9A, 0x6495, 0x9D99,
+	0x649A, 0x9451, 0x649D, 0xFACB, 0x649E, 0x93B3, 0x64A4, 0x9350,
+	0x64A5, 0x9D9B, 0x64A9, 0x9D9C, 0x64AB, 0x958F, 0x64AD, 0x9464,
+	0x64AE, 0x8E42, 0x64B0, 0x90EF, 0x64B2, 0x966F, 0x64B9, 0x8A68,
+	0x64BB, 0x9DA3, 0x64BC, 0x9D9E, 0x64C1, 0x9769, 0x64C2, 0x9DA5,
+	0x64C5, 0x9DA1, 0x64C7, 0x9DA2, 0x64CD, 0x9180, 0x64CE, 0xFACC,
+	0x64D2, 0x9DA0, 0x64D4, 0x9D5E, 0x64D8, 0x9DA4, 0x64DA, 0x9D9F,
+	0x64E0, 0x9DA9, 0x64E1, 0x9DAA, 0x64E2, 0x9346, 0x64E3, 0x9DAC,
+	0x64E6, 0x8E43, 0x64E7, 0x9DA7, 0x64EC, 0x8B5B, 0x64EF, 0x9DAD,
+	0x64F1, 0x9DA6, 0x64F2, 0x9DB1, 0x64F4, 0x9DB0, 0x64F6, 0x9DAF,
+	0x64FA, 0x9DB2, 0x64FD, 0x9DB4, 0x64FE, 0x8FEF, 0x6500, 0x9DB3,
+	0x6505, 0x9DB7, 0x6518, 0x9DB5, 0x651C, 0x9DB6, 0x651D, 0x9D90,
+	0x6523, 0x9DB9, 0x6524, 0x9DB8, 0x652A, 0x9D98, 0x652B, 0x9DBA,
+	0x652C, 0x9DAE, 0x652F, 0x8E78, 0x6534, 0x9DBB, 0x6535, 0x9DBC,
+	0x6536, 0x9DBE, 0x6537, 0x9DBD, 0x6538, 0x9DBF, 0x6539, 0x89FC,
+	0x653B, 0x8D55, 0x653E, 0x95FA, 0x653F, 0x90AD, 0x6545, 0x8CCC,
+	0x6548, 0x9DC1, 0x654D, 0x9DC4, 0x654E, 0xFACD, 0x654F, 0x9571,
+	0x6551, 0x8B7E, 0x6555, 0x9DC3, 0x6556, 0x9DC2, 0x6557, 0x9473,
+	0x6558, 0x9DC5, 0x6559, 0x8BB3, 0x655D, 0x9DC7, 0x655E, 0x9DC6,
+	0x6562, 0x8AB8, 0x6563, 0x8E55, 0x6566, 0x93D6, 0x656C, 0x8C68,
+	0x6570, 0x9094, 0x6572, 0x9DC8, 0x6574, 0x90AE, 0x6575, 0x9347,
+	0x6577, 0x957E, 0x6578, 0x9DC9, 0x6582, 0x9DCA, 0x6583, 0x9DCB,
+	0x6587, 0x95B6, 0x6588, 0x9B7C, 0x6589, 0x90C4, 0x658C, 0x956B,
+	0x658E, 0x8DD6, 0x6590, 0x94E3, 0x6591, 0x94C1, 0x6597, 0x936C,
+	0x6599, 0x97BF, 0x659B, 0x9DCD, 0x659C, 0x8ECE, 0x659F, 0x9DCE,
+	0x65A1, 0x88B4, 0x65A4, 0x8BD2, 0x65A5, 0x90CB, 0x65A7, 0x9580,
+	0x65AB, 0x9DCF, 0x65AC, 0x8E61, 0x65AD, 0x9266, 0x65AF, 0x8E7A,
+	0x65B0, 0x9056, 0x65B7, 0x9DD0, 0x65B9, 0x95FB, 0x65BC, 0x8997,
+	0x65BD, 0x8E7B, 0x65C1, 0x9DD3, 0x65C3, 0x9DD1, 0x65C4, 0x9DD4,
+	0x65C5, 0x97B7, 0x65C6, 0x9DD2, 0x65CB, 0x90F9, 0x65CC, 0x9DD5,
+	0x65CF, 0x91B0, 0x65D2, 0x9DD6, 0x65D7, 0x8AF8, 0x65D9, 0x9DD8,
+	0x65DB, 0x9DD7, 0x65E0, 0x9DD9, 0x65E1, 0x9DDA, 0x65E2, 0x8AF9,
+	0x65E5, 0x93FA, 0x65E6, 0x9255, 0x65E7, 0x8B8C, 0x65E8, 0x8E7C,
+	0x65E9, 0x9181, 0x65EC, 0x8F7B, 0x65ED, 0x88AE, 0x65F1, 0x9DDB,
+	0x65FA, 0x89A0, 0x65FB, 0x9DDF, 0x6600, 0xFACE, 0x6602, 0x8D56,
+	0x6603, 0x9DDE, 0x6606, 0x8DA9, 0x6607, 0x8FB8, 0x6609, 0xFAD1,
+	0x660A, 0x9DDD, 0x660C, 0x8FB9, 0x660E, 0x96BE, 0x660F, 0x8DA8,
+	0x6613, 0x88D5, 0x6614, 0x90CC, 0x6615, 0xFACF, 0x661C, 0x9DE4,
+	0x661E, 0xFAD3, 0x661F, 0x90AF, 0x6620, 0x8966, 0x6624, 0xFAD4,
+	0x6625, 0x8F74, 0x6627, 0x9686, 0x6628, 0x8DF0, 0x662D, 0x8FBA,
+	0x662E, 0xFAD2, 0x662F, 0x90A5, 0x6631, 0xFA63, 0x6634, 0x9DE3,
+	0x6635, 0x9DE1, 0x6636, 0x9DE2, 0x663B, 0xFAD0, 0x663C, 0x928B,
+	0x663F, 0x9E45, 0x6641, 0x9DE8, 0x6642, 0x8E9E, 0x6643, 0x8D57,
+	0x6644, 0x9DE6, 0x6649, 0x9DE7, 0x664B, 0x9057, 0x664F, 0x9DE5,
+	0x6652, 0x8E4E, 0x6657, 0xFAD6, 0x6659, 0xFAD7, 0x665D, 0x9DEA,
+	0x665E, 0x9DE9, 0x665F, 0x9DEE, 0x6662, 0x9DEF, 0x6664, 0x9DEB,
+	0x6665, 0xFAD5, 0x6666, 0x8A41, 0x6667, 0x9DEC, 0x6668, 0x9DED,
+	0x6669, 0x94D3, 0x666E, 0x9581, 0x666F, 0x8C69, 0x6670, 0x9DF0,
+	0x6673, 0xFAD9, 0x6674, 0x90B0, 0x6676, 0x8FBB, 0x667A, 0x9271,
+	0x6681, 0x8BC5, 0x6683, 0x9DF1, 0x6684, 0x9DF5, 0x6687, 0x89C9,
+	0x6688, 0x9DF2, 0x6689, 0x9DF4, 0x668E, 0x9DF3, 0x6691, 0x8F8B,
+	0x6696, 0x9267, 0x6697, 0x88C3, 0x6698, 0x9DF6, 0x6699, 0xFADA,
+	0x669D, 0x9DF7, 0x66A0, 0xFADB, 0x66A2, 0x92A8, 0x66A6, 0x97EF,
+	0x66AB, 0x8E62, 0x66AE, 0x95E9, 0x66B2, 0xFADC, 0x66B4, 0x965C,
+	0x66B8, 0x9E41, 0x66B9, 0x9DF9, 0x66BC, 0x9DFC, 0x66BE, 0x9DFB,
+	0x66BF, 0xFADD, 0x66C1, 0x9DF8, 0x66C4, 0x9E40, 0x66C7, 0x93DC,
+	0x66C9, 0x9DFA, 0x66D6, 0x9E42, 0x66D9, 0x8F8C, 0x66DA, 0x9E43,
+	0x66DC, 0x976A, 0x66DD, 0x9498, 0x66E0, 0x9E44, 0x66E6, 0x9E46,
+	0x66E9, 0x9E47, 0x66F0, 0x9E48, 0x66F2, 0x8BC8, 0x66F3, 0x8967,
+	0x66F4, 0x8D58, 0x66F5, 0x9E49, 0x66F7, 0x9E4A, 0x66F8, 0x8F91,
+	0x66F9, 0x9182, 0x66FA, 0xFADE, 0x66FB, 0xFA66, 0x66FC, 0x99D6,
+	0x66FD, 0x915D, 0x66FE, 0x915C, 0x66FF, 0x91D6, 0x6700, 0x8DC5,
+	0x6703, 0x98F0, 0x6708, 0x8C8E, 0x6709, 0x974C, 0x670B, 0x95FC,
+	0x670D, 0x959E, 0x670E, 0xFADF, 0x670F, 0x9E4B, 0x6714, 0x8DF1,
+	0x6715, 0x92BD, 0x6716, 0x9E4C, 0x6717, 0x984E, 0x671B, 0x965D,
+	0x671D, 0x92A9, 0x671E, 0x9E4D, 0x671F, 0x8AFA, 0x6726, 0x9E4E,
+	0x6727, 0x9E4F, 0x6728, 0x96D8, 0x672A, 0x96A2, 0x672B, 0x9696,
+	0x672C, 0x967B, 0x672D, 0x8E44, 0x672E, 0x9E51, 0x6731, 0x8EE9,
+	0x6734, 0x9670, 0x6736, 0x9E53, 0x6737, 0x9E56, 0x6738, 0x9E55,
+	0x673A, 0x8AF7, 0x673D, 0x8B80, 0x673F, 0x9E52, 0x6741, 0x9E54,
+	0x6746, 0x9E57, 0x6749, 0x9099, 0x674E, 0x979B, 0x674F, 0x88C7,
+	0x6750, 0x8DDE, 0x6751, 0x91BA, 0x6753, 0x8EDB, 0x6756, 0x8FF1,
+	0x6759, 0x9E5A, 0x675C, 0x936D, 0x675E, 0x9E58, 0x675F, 0x91A9,
+	0x6760, 0x9E59, 0x6761, 0x8FF0, 0x6762, 0x96DB, 0x6763, 0x9E5B,
+	0x6764, 0x9E5C, 0x6765, 0x9788, 0x6766, 0xFAE1, 0x676A, 0x9E61,
+	0x676D, 0x8D59, 0x676F, 0x9474, 0x6770, 0x9E5E, 0x6771, 0x938C,
+	0x6772, 0x9DDC, 0x6773, 0x9DE0, 0x6775, 0x8B6E, 0x6777, 0x9466,
+	0x677C, 0x9E60, 0x677E, 0x8FBC, 0x677F, 0x94C2, 0x6785, 0x9E66,
+	0x6787, 0x94F8, 0x6789, 0x9E5D, 0x678B, 0x9E63, 0x678C, 0x9E62,
+	0x6790, 0x90CD, 0x6795, 0x968D, 0x6797, 0x97D1, 0x679A, 0x9687,
+	0x679C, 0x89CA, 0x679D, 0x8E7D, 0x67A0, 0x9867, 0x67A1, 0x9E65,
+	0x67A2, 0x9095, 0x67A6, 0x9E64, 0x67A9, 0x9E5F, 0x67AF, 0x8CCD,
+	0x67B3, 0x9E6B, 0x67B4, 0x9E69, 0x67B6, 0x89CB, 0x67B7, 0x9E67,
+	0x67B8, 0x9E6D, 0x67B9, 0x9E73, 0x67BB, 0xFAE2, 0x67C0, 0xFAE4,
+	0x67C1, 0x91C6, 0x67C4, 0x95BF, 0x67C6, 0x9E75, 0x67CA, 0x9541,
+	0x67CE, 0x9E74, 0x67CF, 0x9490, 0x67D0, 0x965E, 0x67D1, 0x8AB9,
+	0x67D3, 0x90F5, 0x67D4, 0x8F5F, 0x67D8, 0x92D1, 0x67DA, 0x974D,
+	0x67DD, 0x9E70, 0x67DE, 0x9E6F, 0x67E2, 0x9E71, 0x67E4, 0x9E6E,
+	0x67E7, 0x9E76, 0x67E9, 0x9E6C, 0x67EC, 0x9E6A, 0x67EE, 0x9E72,
+	0x67EF, 0x9E68, 0x67F1, 0x928C, 0x67F3, 0x96F6, 0x67F4, 0x8EC4,
+	0x67F5, 0x8DF2, 0x67FB, 0x8DB8, 0x67FE, 0x968F, 0x67FF, 0x8A60,
+	0x6801, 0xFAE5, 0x6802, 0x92CC, 0x6803, 0x93C8, 0x6804, 0x8968,
+	0x6813, 0x90F0, 0x6816, 0x90B2, 0x6817, 0x8C49, 0x681E, 0x9E78,
+	0x6821, 0x8D5A, 0x6822, 0x8A9C, 0x6829, 0x9E7A, 0x682A, 0x8A94,
+	0x682B, 0x9E81, 0x6832, 0x9E7D, 0x6834, 0x90F1, 0x6838, 0x8A6A,
+	0x6839, 0x8DAA, 0x683C, 0x8A69, 0x683D, 0x8DCD, 0x6840, 0x9E7B,
+	0x6841, 0x8C85, 0x6842, 0x8C6A, 0x6843, 0x938D, 0x6844, 0xFAE6,
+	0x6846, 0x9E79, 0x6848, 0x88C4, 0x684D, 0x9E7C, 0x684E, 0x9E7E,
+	0x6850, 0x8BCB, 0x6851, 0x8C4B, 0x6852, 0xFAE3, 0x6853, 0x8ABA,
+	0x6854, 0x8B6A, 0x6859, 0x9E82, 0x685C, 0x8DF7, 0x685D, 0x9691,
+	0x685F, 0x8E56, 0x6863, 0x9E83, 0x6867, 0x954F, 0x6874, 0x9E8F,
+	0x6876, 0x89B1, 0x6877, 0x9E84, 0x687E, 0x9E95, 0x687F, 0x9E85,
+	0x6881, 0x97C0, 0x6883, 0x9E8C, 0x6885, 0x947E, 0x688D, 0x9E94,
+	0x688F, 0x9E87, 0x6893, 0x88B2, 0x6894, 0x9E89, 0x6897, 0x8D5B,
+	0x689B, 0x9E8B, 0x689D, 0x9E8A, 0x689F, 0x9E86, 0x68A0, 0x9E91,
+	0x68A2, 0x8FBD, 0x68A6, 0x9AEB, 0x68A7, 0x8CE6, 0x68A8, 0x979C,
+	0x68AD, 0x9E88, 0x68AF, 0x92F2, 0x68B0, 0x8A42, 0x68B1, 0x8DAB,
+	0x68B3, 0x9E80, 0x68B5, 0x9E90, 0x68B6, 0x8A81, 0x68B9, 0x9E8E,
+	0x68BA, 0x9E92, 0x68BC, 0x938E, 0x68C4, 0x8AFC, 0x68C6, 0x9EB0,
+	0x68C8, 0xFA64, 0x68C9, 0x96C7, 0x68CA, 0x9E97, 0x68CB, 0x8AFB,
+	0x68CD, 0x9E9E, 0x68CF, 0xFAE7, 0x68D2, 0x965F, 0x68D4, 0x9E9F,
+	0x68D5, 0x9EA1, 0x68D7, 0x9EA5, 0x68D8, 0x9E99, 0x68DA, 0x9249,
+	0x68DF, 0x938F, 0x68E0, 0x9EA9, 0x68E1, 0x9E9C, 0x68E3, 0x9EA6,
+	0x68E7, 0x9EA0, 0x68EE, 0x9058, 0x68EF, 0x9EAA, 0x68F2, 0x90B1,
+	0x68F9, 0x9EA8, 0x68FA, 0x8ABB, 0x6900, 0x986F, 0x6901, 0x9E96,
+	0x6904, 0x9EA4, 0x6905, 0x88D6, 0x6908, 0x9E98, 0x690B, 0x96B8,
+	0x690C, 0x9E9D, 0x690D, 0x9041, 0x690E, 0x92C5, 0x690F, 0x9E93,
+	0x6912, 0x9EA3, 0x6919, 0x909A, 0x691A, 0x9EAD, 0x691B, 0x8A91,
+	0x691C, 0x8C9F, 0x6921, 0x9EAF, 0x6922, 0x9E9A, 0x6923, 0x9EAE,
+	0x6925, 0x9EA7, 0x6926, 0x9E9B, 0x6928, 0x9EAB, 0x692A, 0x9EAC,
+	0x6930, 0x9EBD, 0x6934, 0x93CC, 0x6936, 0x9EA2, 0x6939, 0x9EB9,
+	0x693D, 0x9EBB, 0x693F, 0x92D6, 0x694A, 0x976B, 0x6953, 0x9596,
+	0x6954, 0x9EB6, 0x6955, 0x91C8, 0x6959, 0x9EBC, 0x695A, 0x915E,
+	0x695C, 0x9EB3, 0x695D, 0x9EC0, 0x695E, 0x9EBF, 0x6960, 0x93ED,
+	0x6961, 0x9EBE, 0x6962, 0x93E8, 0x6968, 0xFAE9, 0x696A, 0x9EC2,
+	0x696B, 0x9EB5, 0x696D, 0x8BC6, 0x696E, 0x9EB8, 0x696F, 0x8F7C,
+	0x6973, 0x9480, 0x6974, 0x9EBA, 0x6975, 0x8BC9, 0x6977, 0x9EB2,
+	0x6978, 0x9EB4, 0x6979, 0x9EB1, 0x697C, 0x984F, 0x697D, 0x8A79,
+	0x697E, 0x9EB7, 0x6981, 0x9EC1, 0x6982, 0x8A54, 0x698A, 0x8DE5,
+	0x698E, 0x897C, 0x6991, 0x9ED2, 0x6994, 0x9850, 0x6995, 0x9ED5,
+	0x6998, 0xFAEB, 0x699B, 0x9059, 0x699C, 0x9ED4, 0x69A0, 0x9ED3,
+	0x69A7, 0x9ED0, 0x69AE, 0x9EC4, 0x69B1, 0x9EE1, 0x69B2, 0x9EC3,
+	0x69B4, 0x9ED6, 0x69BB, 0x9ECE, 0x69BE, 0x9EC9, 0x69BF, 0x9EC6,
+	0x69C1, 0x9EC7, 0x69C3, 0x9ECF, 0x69C7, 0xEAA0, 0x69CA, 0x9ECC,
+	0x69CB, 0x8D5C, 0x69CC, 0x92C6, 0x69CD, 0x9184, 0x69CE, 0x9ECA,
+	0x69D0, 0x9EC5, 0x69D3, 0x9EC8, 0x69D8, 0x976C, 0x69D9, 0x968A,
+	0x69DD, 0x9ECD, 0x69DE, 0x9ED7, 0x69E2, 0xFAEC, 0x69E7, 0x9EDF,
+	0x69E8, 0x9ED8, 0x69EB, 0x9EE5, 0x69ED, 0x9EE3, 0x69F2, 0x9EDE,
+	0x69F9, 0x9EDD, 0x69FB, 0x92CE, 0x69FD, 0x9185, 0x69FF, 0x9EDB,
+	0x6A02, 0x9ED9, 0x6A05, 0x9EE0, 0x6A0A, 0x9EE6, 0x6A0B, 0x94F3,
+	0x6A0C, 0x9EEC, 0x6A12, 0x9EE7, 0x6A13, 0x9EEA, 0x6A14, 0x9EE4,
+	0x6A17, 0x9294, 0x6A19, 0x9557, 0x6A1B, 0x9EDA, 0x6A1E, 0x9EE2,
+	0x6A1F, 0x8FBE, 0x6A21, 0x96CD, 0x6A22, 0x9EF6, 0x6A23, 0x9EE9,
+	0x6A29, 0x8CA0, 0x6A2A, 0x89A1, 0x6A2B, 0x8A7E, 0x6A2E, 0x9ED1,
+	0x6A30, 0xFAED, 0x6A35, 0x8FBF, 0x6A36, 0x9EEE, 0x6A38, 0x9EF5,
+	0x6A39, 0x8EF7, 0x6A3A, 0x8A92, 0x6A3D, 0x924D, 0x6A44, 0x9EEB,
+	0x6A46, 0xFAEF, 0x6A47, 0x9EF0, 0x6A48, 0x9EF4, 0x6A4B, 0x8BB4,
+	0x6A58, 0x8B6B, 0x6A59, 0x9EF2, 0x6A5F, 0x8B40, 0x6A61, 0x93C9,
+	0x6A62, 0x9EF1, 0x6A66, 0x9EF3, 0x6A6B, 0xFAEE, 0x6A72, 0x9EED,
+	0x6A73, 0xFAF0, 0x6A78, 0x9EEF, 0x6A7E, 0xFAF1, 0x6A7F, 0x8A80,
+	0x6A80, 0x9268, 0x6A84, 0x9EFA, 0x6A8D, 0x9EF8, 0x6A8E, 0x8CE7,
+	0x6A90, 0x9EF7, 0x6A97, 0x9F40, 0x6A9C, 0x9E77, 0x6AA0, 0x9EF9,
+	0x6AA2, 0x9EFB, 0x6AA3, 0x9EFC, 0x6AAA, 0x9F4B, 0x6AAC, 0x9F47,
+	0x6AAE, 0x9E8D, 0x6AB3, 0x9F46, 0x6AB8, 0x9F45, 0x6ABB, 0x9F42,
+	0x6AC1, 0x9EE8, 0x6AC2, 0x9F44, 0x6AC3, 0x9F43, 0x6AD1, 0x9F49,
+	0x6AD3, 0x9845, 0x6ADA, 0x9F4C, 0x6ADB, 0x8BF9, 0x6ADE, 0x9F48,
+	0x6ADF, 0x9F4A, 0x6AE2, 0xFAF2, 0x6AE4, 0xFAF3, 0x6AE8, 0x94A5,
+	0x6AEA, 0x9F4D, 0x6AFA, 0x9F51, 0x6AFB, 0x9F4E, 0x6B04, 0x9793,
+	0x6B05, 0x9F4F, 0x6B0A, 0x9EDC, 0x6B12, 0x9F52, 0x6B16, 0x9F53,
+	0x6B1D, 0x8954, 0x6B1F, 0x9F55, 0x6B20, 0x8C87, 0x6B21, 0x8E9F,
+	0x6B23, 0x8BD3, 0x6B27, 0x89A2, 0x6B32, 0x977E, 0x6B37, 0x9F57,
+	0x6B38, 0x9F56, 0x6B39, 0x9F59, 0x6B3A, 0x8B5C, 0x6B3D, 0x8BD4,
+	0x6B3E, 0x8ABC, 0x6B43, 0x9F5C, 0x6B47, 0x9F5B, 0x6B49, 0x9F5D,
+	0x6B4C, 0x89CC, 0x6B4E, 0x9256, 0x6B50, 0x9F5E, 0x6B53, 0x8ABD,
+	0x6B54, 0x9F60, 0x6B59, 0x9F5F, 0x6B5B, 0x9F61, 0x6B5F, 0x9F62,
+	0x6B61, 0x9F63, 0x6B62, 0x8E7E, 0x6B63, 0x90B3, 0x6B64, 0x8D9F,
+	0x6B66, 0x9590, 0x6B69, 0x95E0, 0x6B6A, 0x9863, 0x6B6F, 0x8E95,
+	0x6B73, 0x8DCE, 0x6B74, 0x97F0, 0x6B78, 0x9F64, 0x6B79, 0x9F65,
+	0x6B7B, 0x8E80, 0x6B7F, 0x9F66, 0x6B80, 0x9F67, 0x6B83, 0x9F69,
+	0x6B84, 0x9F68, 0x6B86, 0x9677, 0x6B89, 0x8F7D, 0x6B8A, 0x8EEA,
+	0x6B8B, 0x8E63, 0x6B8D, 0x9F6A, 0x6B95, 0x9F6C, 0x6B96, 0x9042,
+	0x6B98, 0x9F6B, 0x6B9E, 0x9F6D, 0x6BA4, 0x9F6E, 0x6BAA, 0x9F6F,
+	0x6BAB, 0x9F70, 0x6BAF, 0x9F71, 0x6BB1, 0x9F73, 0x6BB2, 0x9F72,
+	0x6BB3, 0x9F74, 0x6BB4, 0x89A3, 0x6BB5, 0x9269, 0x6BB7, 0x9F75,
+	0x6BBA, 0x8E45, 0x6BBB, 0x8A6B, 0x6BBC, 0x9F76, 0x6BBF, 0x9361,
+	0x6BC0, 0x9ACA, 0x6BC5, 0x8B42, 0x6BC6, 0x9F77, 0x6BCB, 0x9F78,
+	0x6BCD, 0x95EA, 0x6BCE, 0x9688, 0x6BD2, 0x93C5, 0x6BD3, 0x9F79,
+	0x6BD4, 0x94E4, 0x6BD6, 0xFAF4, 0x6BD8, 0x94F9, 0x6BDB, 0x96D1,
+	0x6BDF, 0x9F7A, 0x6BEB, 0x9F7C, 0x6BEC, 0x9F7B, 0x6BEF, 0x9F7E,
+	0x6BF3, 0x9F7D, 0x6C08, 0x9F81, 0x6C0F, 0x8E81, 0x6C11, 0x96AF,
+	0x6C13, 0x9F82, 0x6C14, 0x9F83, 0x6C17, 0x8B43, 0x6C1B, 0x9F84,
+	0x6C23, 0x9F86, 0x6C24, 0x9F85, 0x6C34, 0x9085, 0x6C37, 0x9558,
+	0x6C38, 0x8969, 0x6C3E, 0x94C3, 0x6C3F, 0xFAF5, 0x6C40, 0x92F3,
+	0x6C41, 0x8F60, 0x6C42, 0x8B81, 0x6C4E, 0x94C4, 0x6C50, 0x8EAC,
+	0x6C55, 0x9F88, 0x6C57, 0x8ABE, 0x6C5A, 0x8998, 0x6C5C, 0xFAF6,
+	0x6C5D, 0x93F0, 0x6C5E, 0x9F87, 0x6C5F, 0x8D5D, 0x6C60, 0x9272,
+	0x6C62, 0x9F89, 0x6C68, 0x9F91, 0x6C6A, 0x9F8A, 0x6C6F, 0xFAF8,
+	0x6C70, 0x91BF, 0x6C72, 0x8B82, 0x6C73, 0x9F92, 0x6C7A, 0x8C88,
+	0x6C7D, 0x8B44, 0x6C7E, 0x9F90, 0x6C81, 0x9F8E, 0x6C82, 0x9F8B,
+	0x6C83, 0x9780, 0x6C86, 0xFAF7, 0x6C88, 0x92BE, 0x6C8C, 0x93D7,
+	0x6C8D, 0x9F8C, 0x6C90, 0x9F94, 0x6C92, 0x9F93, 0x6C93, 0x8C42,
+	0x6C96, 0x89AB, 0x6C99, 0x8DB9, 0x6C9A, 0x9F8D, 0x6C9B, 0x9F8F,
+	0x6CA1, 0x9676, 0x6CA2, 0x91F2, 0x6CAB, 0x9697, 0x6CAE, 0x9F9C,
+	0x6CB1, 0x9F9D, 0x6CB3, 0x89CD, 0x6CB8, 0x95A6, 0x6CB9, 0x96FB,
+	0x6CBA, 0x9F9F, 0x6CBB, 0x8EA1, 0x6CBC, 0x8FC0, 0x6CBD, 0x9F98,
+	0x6CBE, 0x9F9E, 0x6CBF, 0x8988, 0x6CC1, 0x8BB5, 0x6CC4, 0x9F95,
+	0x6CC5, 0x9F9A, 0x6CC9, 0x90F2, 0x6CCA, 0x9491, 0x6CCC, 0x94E5,
+	0x6CD3, 0x9F97, 0x6CD5, 0x9640, 0x6CD7, 0x9F99, 0x6CD9, 0x9FA2,
+	0x6CDA, 0xFAF9, 0x6CDB, 0x9FA0, 0x6CDD, 0x9F9B, 0x6CE1, 0x9641,
+	0x6CE2, 0x9467, 0x6CE3, 0x8B83, 0x6CE5, 0x9344, 0x6CE8, 0x928D,
+	0x6CEA, 0x9FA3, 0x6CEF, 0x9FA1, 0x6CF0, 0x91D7, 0x6CF1, 0x9F96,
+	0x6CF3, 0x896A, 0x6D04, 0xFAFA, 0x6D0B, 0x976D, 0x6D0C, 0x9FAE,
+	0x6D12, 0x9FAD, 0x6D17, 0x90F4, 0x6D19, 0x9FAA, 0x6D1B, 0x978C,
+	0x6D1E, 0x93B4, 0x6D1F, 0x9FA4, 0x6D25, 0x92C3, 0x6D29, 0x896B,
+	0x6D2A, 0x8D5E, 0x6D2B, 0x9FA7, 0x6D32, 0x8F46, 0x6D33, 0x9FAC,
+	0x6D35, 0x9FAB, 0x6D36, 0x9FA6, 0x6D38, 0x9FA9, 0x6D3B, 0x8A88,
+	0x6D3D, 0x9FA8, 0x6D3E, 0x9468, 0x6D41, 0x97AC, 0x6D44, 0x8FF2,
+	0x6D45, 0x90F3, 0x6D59, 0x9FB4, 0x6D5A, 0x9FB2, 0x6D5C, 0x956C,
+	0x6D63, 0x9FAF, 0x6D64, 0x9FB1, 0x6D66, 0x8959, 0x6D69, 0x8D5F,
+	0x6D6A, 0x9851, 0x6D6C, 0x8A5C, 0x6D6E, 0x9582, 0x6D6F, 0xFAFC,
+	0x6D74, 0x9781, 0x6D77, 0x8A43, 0x6D78, 0x905A, 0x6D79, 0x9FB3,
+	0x6D85, 0x9FB8, 0x6D87, 0xFAFB, 0x6D88, 0x8FC1, 0x6D8C, 0x974F,
+	0x6D8E, 0x9FB5, 0x6D93, 0x9FB0, 0x6D95, 0x9FB6, 0x6D96, 0xFB40,
+	0x6D99, 0x97DC, 0x6D9B, 0x9393, 0x6D9C, 0x93C0, 0x6DAC, 0xFB41,
+	0x6DAF, 0x8A55, 0x6DB2, 0x8974, 0x6DB5, 0x9FBC, 0x6DB8, 0x9FBF,
+	0x6DBC, 0x97C1, 0x6DC0, 0x9784, 0x6DC5, 0x9FC6, 0x6DC6, 0x9FC0,
+	0x6DC7, 0x9FBD, 0x6DCB, 0x97D2, 0x6DCC, 0x9FC3, 0x6DCF, 0xFB42,
+	0x6DD1, 0x8F69, 0x6DD2, 0x9FC5, 0x6DD5, 0x9FCA, 0x6DD8, 0x9391,
+	0x6DD9, 0x9FC8, 0x6DDE, 0x9FC2, 0x6DE1, 0x9257, 0x6DE4, 0x9FC9,
+	0x6DE6, 0x9FBE, 0x6DE8, 0x9FC4, 0x6DEA, 0x9FCB, 0x6DEB, 0x88FA,
+	0x6DEC, 0x9FC1, 0x6DEE, 0x9FCC, 0x6DF1, 0x905B, 0x6DF2, 0xFB44,
+	0x6DF3, 0x8F7E, 0x6DF5, 0x95A3, 0x6DF7, 0x8DAC, 0x6DF8, 0xFB43,
+	0x6DF9, 0x9FB9, 0x6DFA, 0x9FC7, 0x6DFB, 0x9359, 0x6DFC, 0xFB45,
+	0x6E05, 0x90B4, 0x6E07, 0x8A89, 0x6E08, 0x8DCF, 0x6E09, 0x8FC2,
+	0x6E0A, 0x9FBB, 0x6E0B, 0x8F61, 0x6E13, 0x8C6B, 0x6E15, 0x9FBA,
+	0x6E19, 0x9FD0, 0x6E1A, 0x8F8D, 0x6E1B, 0x8CB8, 0x6E1D, 0x9FDF,
+	0x6E1F, 0x9FD9, 0x6E20, 0x8B94, 0x6E21, 0x936E, 0x6E23, 0x9FD4,
+	0x6E24, 0x9FDD, 0x6E25, 0x88AD, 0x6E26, 0x8951, 0x6E27, 0xFB48,
+	0x6E29, 0x89B7, 0x6E2B, 0x9FD6, 0x6E2C, 0x91AA, 0x6E2D, 0x9FCD,
+	0x6E2E, 0x9FCF, 0x6E2F, 0x8D60, 0x6E38, 0x9FE0, 0x6E39, 0xFB46,
+	0x6E3A, 0x9FDB, 0x6E3C, 0xFB49, 0x6E3E, 0x9FD3, 0x6E43, 0x9FDA,
+	0x6E4A, 0x96A9, 0x6E4D, 0x9FD8, 0x6E4E, 0x9FDC, 0x6E56, 0x8CCE,
+	0x6E58, 0x8FC3, 0x6E5B, 0x9258, 0x6E5C, 0xFB47, 0x6E5F, 0x9FD2,
+	0x6E67, 0x974E, 0x6E6B, 0x9FD5, 0x6E6E, 0x9FCE, 0x6E6F, 0x9392,
+	0x6E72, 0x9FD1, 0x6E76, 0x9FD7, 0x6E7E, 0x9870, 0x6E7F, 0x8EBC,
+	0x6E80, 0x969E, 0x6E82, 0x9FE1, 0x6E8C, 0x94AC, 0x6E8F, 0x9FED,
+	0x6E90, 0x8CB9, 0x6E96, 0x8F80, 0x6E98, 0x9FE3, 0x6E9C, 0x97AD,
+	0x6E9D, 0x8D61, 0x6E9F, 0x9FF0, 0x6EA2, 0x88EC, 0x6EA5, 0x9FEE,
+	0x6EAA, 0x9FE2, 0x6EAF, 0x9FE8, 0x6EB2, 0x9FEA, 0x6EB6, 0x976E,
+	0x6EB7, 0x9FE5, 0x6EBA, 0x934D, 0x6EBD, 0x9FE7, 0x6EBF, 0xFB4A,
+	0x6EC2, 0x9FEF, 0x6EC4, 0x9FE9, 0x6EC5, 0x96C5, 0x6EC9, 0x9FE4,
+	0x6ECB, 0x8EA0, 0x6ECC, 0x9FFC, 0x6ED1, 0x8A8A, 0x6ED3, 0x9FE6,
+	0x6ED4, 0x9FEB, 0x6ED5, 0x9FEC, 0x6EDD, 0x91EA, 0x6EDE, 0x91D8,
+	0x6EEC, 0x9FF4, 0x6EEF, 0x9FFA, 0x6EF2, 0x9FF8, 0x6EF4, 0x9348,
+	0x6EF7, 0xE042, 0x6EF8, 0x9FF5, 0x6EFE, 0x9FF6, 0x6EFF, 0x9FDE,
+	0x6F01, 0x8B99, 0x6F02, 0x9559, 0x6F06, 0x8EBD, 0x6F09, 0x8D97,
+	0x6F0F, 0x9852, 0x6F11, 0x9FF2, 0x6F13, 0xE041, 0x6F14, 0x8989,
+	0x6F15, 0x9186, 0x6F20, 0x9499, 0x6F22, 0x8ABF, 0x6F23, 0x97F8,
+	0x6F2B, 0x969F, 0x6F2C, 0x92D0, 0x6F31, 0x9FF9, 0x6F32, 0x9FFB,
+	0x6F38, 0x9151, 0x6F3E, 0xE040, 0x6F3F, 0x9FF7, 0x6F41, 0x9FF1,
+	0x6F45, 0x8AC1, 0x6F54, 0x8C89, 0x6F58, 0xE04E, 0x6F5B, 0xE049,
+	0x6F5C, 0x90F6, 0x6F5F, 0x8A83, 0x6F64, 0x8F81, 0x6F66, 0xE052,
+	0x6F6D, 0xE04B, 0x6F6E, 0x92AA, 0x6F6F, 0xE048, 0x6F70, 0x92D7,
+	0x6F74, 0xE06B, 0x6F78, 0xE045, 0x6F7A, 0xE044, 0x6F7C, 0xE04D,
+	0x6F80, 0xE047, 0x6F81, 0xE046, 0x6F82, 0xE04C, 0x6F84, 0x909F,
+	0x6F86, 0xE043, 0x6F88, 0xFB4B, 0x6F8E, 0xE04F, 0x6F91, 0xE050,
+	0x6F97, 0x8AC0, 0x6FA1, 0xE055, 0x6FA3, 0xE054, 0x6FA4, 0xE056,
+	0x6FAA, 0xE059, 0x6FB1, 0x9362, 0x6FB3, 0xE053, 0x6FB5, 0xFB4C,
+	0x6FB9, 0xE057, 0x6FC0, 0x8C83, 0x6FC1, 0x91F7, 0x6FC2, 0xE051,
+	0x6FC3, 0x945A, 0x6FC6, 0xE058, 0x6FD4, 0xE05D, 0x6FD5, 0xE05B,
+	0x6FD8, 0xE05E, 0x6FDB, 0xE061, 0x6FDF, 0xE05A, 0x6FE0, 0x8D8A,
+	0x6FE1, 0x9447, 0x6FE4, 0x9FB7, 0x6FEB, 0x9794, 0x6FEC, 0xE05C,
+	0x6FEE, 0xE060, 0x6FEF, 0x91F3, 0x6FF1, 0xE05F, 0x6FF3, 0xE04A,
+	0x6FF5, 0xFB4D, 0x6FF6, 0xE889, 0x6FFA, 0xE064, 0x6FFE, 0xE068,
+	0x7001, 0xE066, 0x7005, 0xFB4E, 0x7007, 0xFB4F, 0x7009, 0xE062,
+	0x700B, 0xE063, 0x700F, 0xE067, 0x7011, 0xE065, 0x7015, 0x956D,
+	0x7018, 0xE06D, 0x701A, 0xE06A, 0x701B, 0xE069, 0x701D, 0xE06C,
+	0x701E, 0x93D2, 0x701F, 0xE06E, 0x7026, 0x9295, 0x7027, 0x91EB,
+	0x7028, 0xFB50, 0x702C, 0x90A3, 0x7030, 0xE06F, 0x7032, 0xE071,
+	0x703E, 0xE070, 0x704C, 0x9FF3, 0x7051, 0xE072, 0x7058, 0x93E5,
+	0x7063, 0xE073, 0x706B, 0x89CE, 0x706F, 0x9394, 0x7070, 0x8A44,
+	0x7078, 0x8B84, 0x707C, 0x8EDC, 0x707D, 0x8DD0, 0x7085, 0xFB51,
+	0x7089, 0x9846, 0x708A, 0x9086, 0x708E, 0x898A, 0x7092, 0xE075,
+	0x7099, 0xE074, 0x70AB, 0xFB52, 0x70AC, 0xE078, 0x70AD, 0x9259,
+	0x70AE, 0xE07B, 0x70AF, 0xE076, 0x70B3, 0xE07A, 0x70B8, 0xE079,
+	0x70B9, 0x935F, 0x70BA, 0x88D7, 0x70BB, 0xFA62, 0x70C8, 0x97F3,
+	0x70CB, 0xE07D, 0x70CF, 0x8947, 0x70D9, 0xE080, 0x70DD, 0xE07E,
+	0x70DF, 0xE07C, 0x70F1, 0xE077, 0x70F9, 0x9642, 0x70FD, 0xE082,
+	0x7104, 0xFB54, 0x7109, 0xE081, 0x710F, 0xFB53, 0x7114, 0x898B,
+	0x7119, 0xE084, 0x711A, 0x95B0, 0x711C, 0xE083, 0x7121, 0x96B3,
+	0x7126, 0x8FC5, 0x7136, 0x9152, 0x713C, 0x8FC4, 0x7146, 0xFB56,
+	0x7147, 0xFB57, 0x7149, 0x97F9, 0x714C, 0xE08A, 0x714E, 0x90F7,
+	0x7155, 0xE086, 0x7156, 0xE08B, 0x7159, 0x898C, 0x715C, 0xFB55,
+	0x7162, 0xE089, 0x7164, 0x9481, 0x7165, 0xE085, 0x7166, 0xE088,
+	0x7167, 0x8FC6, 0x7169, 0x94CF, 0x716C, 0xE08C, 0x716E, 0x8ECF,
+	0x717D, 0x90F8, 0x7184, 0xE08F, 0x7188, 0xE087, 0x718A, 0x8C46,
+	0x718F, 0xE08D, 0x7194, 0x976F, 0x7195, 0xE090, 0x7199, 0xEAA4,
+	0x719F, 0x8F6E, 0x71A8, 0xE091, 0x71AC, 0xE092, 0x71B1, 0x944D,
+	0x71B9, 0xE094, 0x71BE, 0xE095, 0x71C1, 0xFB59, 0x71C3, 0x9452,
+	0x71C8, 0x9395, 0x71C9, 0xE097, 0x71CE, 0xE099, 0x71D0, 0x97D3,
+	0x71D2, 0xE096, 0x71D4, 0xE098, 0x71D5, 0x898D, 0x71D7, 0xE093,
+	0x71DF, 0x9A7A, 0x71E0, 0xE09A, 0x71E5, 0x9187, 0x71E6, 0x8E57,
+	0x71E7, 0xE09C, 0x71EC, 0xE09B, 0x71ED, 0x9043, 0x71EE, 0x99D7,
+	0x71F5, 0xE09D, 0x71F9, 0xE09F, 0x71FB, 0xE08E, 0x71FC, 0xE09E,
+	0x71FE, 0xFB5A, 0x71FF, 0xE0A0, 0x7206, 0x949A, 0x720D, 0xE0A1,
+	0x7210, 0xE0A2, 0x721B, 0xE0A3, 0x7228, 0xE0A4, 0x722A, 0x92DC,
+	0x722C, 0xE0A6, 0x722D, 0xE0A5, 0x7230, 0xE0A7, 0x7232, 0xE0A8,
+	0x7235, 0x8EDD, 0x7236, 0x9583, 0x723A, 0x96EA, 0x723B, 0xE0A9,
+	0x723C, 0xE0AA, 0x723D, 0x9175, 0x723E, 0x8EA2, 0x723F, 0xE0AB,
+	0x7240, 0xE0AC, 0x7246, 0xE0AD, 0x7247, 0x95D0, 0x7248, 0x94C5,
+	0x724B, 0xE0AE, 0x724C, 0x9476, 0x7252, 0x92AB, 0x7258, 0xE0AF,
+	0x7259, 0x89E5, 0x725B, 0x8B8D, 0x725D, 0x96C4, 0x725F, 0x96B4,
+	0x7261, 0x89B2, 0x7262, 0x9853, 0x7267, 0x9671, 0x7269, 0x95A8,
+	0x7272, 0x90B5, 0x7274, 0xE0B0, 0x7279, 0x93C1, 0x727D, 0x8CA1,
+	0x727E, 0xE0B1, 0x7280, 0x8DD2, 0x7281, 0xE0B3, 0x7282, 0xE0B2,
+	0x7287, 0xE0B4, 0x7292, 0xE0B5, 0x7296, 0xE0B6, 0x72A0, 0x8B5D,
+	0x72A2, 0xE0B7, 0x72A7, 0xE0B8, 0x72AC, 0x8CA2, 0x72AF, 0x94C6,
+	0x72B1, 0xFB5B, 0x72B2, 0xE0BA, 0x72B6, 0x8FF3, 0x72B9, 0xE0B9,
+	0x72BE, 0xFB5C, 0x72C2, 0x8BB6, 0x72C3, 0xE0BB, 0x72C4, 0xE0BD,
+	0x72C6, 0xE0BC, 0x72CE, 0xE0BE, 0x72D0, 0x8CCF, 0x72D2, 0xE0BF,
+	0x72D7, 0x8BE7, 0x72D9, 0x915F, 0x72DB, 0x8D9D, 0x72E0, 0xE0C1,
+	0x72E1, 0xE0C2, 0x72E2, 0xE0C0, 0x72E9, 0x8EEB, 0x72EC, 0x93C6,
+	0x72ED, 0x8BB7, 0x72F7, 0xE0C4, 0x72F8, 0x924B, 0x72F9, 0xE0C3,
+	0x72FC, 0x9854, 0x72FD, 0x9482, 0x730A, 0xE0C7, 0x7316, 0xE0C9,
+	0x7317, 0xE0C6, 0x731B, 0x96D2, 0x731C, 0xE0C8, 0x731D, 0xE0CA,
+	0x731F, 0x97C2, 0x7324, 0xFB5D, 0x7325, 0xE0CE, 0x7329, 0xE0CD,
+	0x732A, 0x9296, 0x732B, 0x944C, 0x732E, 0x8CA3, 0x732F, 0xE0CC,
+	0x7334, 0xE0CB, 0x7336, 0x9750, 0x7337, 0x9751, 0x733E, 0xE0CF,
+	0x733F, 0x898E, 0x7344, 0x8D96, 0x7345, 0x8E82, 0x734E, 0xE0D0,
+	0x734F, 0xE0D1, 0x7357, 0xE0D3, 0x7363, 0x8F62, 0x7368, 0xE0D5,
+	0x736A, 0xE0D4, 0x7370, 0xE0D6, 0x7372, 0x8A6C, 0x7375, 0xE0D8,
+	0x7377, 0xFB5F, 0x7378, 0xE0D7, 0x737A, 0xE0DA, 0x737B, 0xE0D9,
+	0x7384, 0x8CBA, 0x7387, 0x97A6, 0x7389, 0x8BCA, 0x738B, 0x89A4,
+	0x7396, 0x8BE8, 0x73A9, 0x8ADF, 0x73B2, 0x97E6, 0x73B3, 0xE0DC,
+	0x73BB, 0xE0DE, 0x73BD, 0xFB60, 0x73C0, 0xE0DF, 0x73C2, 0x89CF,
+	0x73C8, 0xE0DB, 0x73C9, 0xFB61, 0x73CA, 0x8E58, 0x73CD, 0x92BF,
+	0x73CE, 0xE0DD, 0x73D2, 0xFB64, 0x73D6, 0xFB62, 0x73DE, 0xE0E2,
+	0x73E0, 0x8EEC, 0x73E3, 0xFB63, 0x73E5, 0xE0E0, 0x73EA, 0x8C5D,
+	0x73ED, 0x94C7, 0x73EE, 0xE0E1, 0x73F1, 0xE0FC, 0x73F5, 0xFB66,
+	0x73F8, 0xE0E7, 0x73FE, 0x8CBB, 0x7403, 0x8B85, 0x7405, 0xE0E4,
+	0x7406, 0x979D, 0x7407, 0xFB65, 0x7409, 0x97AE, 0x7422, 0x91F4,
+	0x7425, 0xE0E6, 0x7426, 0xFB67, 0x7429, 0xFB69, 0x742A, 0xFB68,
+	0x742E, 0xFB6A, 0x7432, 0xE0E8, 0x7433, 0x97D4, 0x7434, 0x8BD5,
+	0x7435, 0x94FA, 0x7436, 0x9469, 0x743A, 0xE0E9, 0x743F, 0xE0EB,
+	0x7441, 0xE0EE, 0x7455, 0xE0EA, 0x7459, 0xE0ED, 0x745A, 0x8CE8,
+	0x745B, 0x896C, 0x745C, 0xE0EF, 0x745E, 0x9090, 0x745F, 0xE0EC,
+	0x7460, 0x97DA, 0x7462, 0xFB6B, 0x7463, 0xE0F2, 0x7464, 0xEAA2,
+	0x7469, 0xE0F0, 0x746A, 0xE0F3, 0x746F, 0xE0E5, 0x7470, 0xE0F1,
+	0x7473, 0x8DBA, 0x7476, 0xE0F4, 0x747E, 0xE0F5, 0x7483, 0x979E,
+	0x7489, 0xFB6C, 0x748B, 0xE0F6, 0x749E, 0xE0F7, 0x749F, 0xFB6D,
+	0x74A2, 0xE0E3, 0x74A7, 0xE0F8, 0x74B0, 0x8AC2, 0x74BD, 0x8EA3,
+	0x74CA, 0xE0F9, 0x74CF, 0xE0FA, 0x74D4, 0xE0FB, 0x74DC, 0x895A,
+	0x74E0, 0xE140, 0x74E2, 0x955A, 0x74E3, 0xE141, 0x74E6, 0x8AA2,
+	0x74E7, 0xE142, 0x74E9, 0xE143, 0x74EE, 0xE144, 0x74F0, 0xE146,
+	0x74F1, 0xE147, 0x74F2, 0xE145, 0x74F6, 0x9572, 0x74F7, 0xE149,
+	0x74F8, 0xE148, 0x7501, 0xFB6E, 0x7503, 0xE14B, 0x7504, 0xE14A,
+	0x7505, 0xE14C, 0x750C, 0xE14D, 0x750D, 0xE14F, 0x750E, 0xE14E,
+	0x7511, 0x8D99, 0x7513, 0xE151, 0x7515, 0xE150, 0x7518, 0x8AC3,
+	0x751A, 0x9072, 0x751C, 0x935B, 0x751E, 0xE152, 0x751F, 0x90B6,
+	0x7523, 0x8E59, 0x7525, 0x8999, 0x7526, 0xE153, 0x7528, 0x9770,
+	0x752B, 0x95E1, 0x752C, 0xE154, 0x752F, 0xFAA8, 0x7530, 0x9363,
+	0x7531, 0x9752, 0x7532, 0x8D62, 0x7533, 0x905C, 0x7537, 0x926A,
+	0x7538, 0x99B2, 0x753A, 0x92AC, 0x753B, 0x89E6, 0x753C, 0xE155,
+	0x7544, 0xE156, 0x7546, 0xE15B, 0x7549, 0xE159, 0x754A, 0xE158,
+	0x754B, 0x9DC0, 0x754C, 0x8A45, 0x754D, 0xE157, 0x754F, 0x88D8,
+	0x7551, 0x94A8, 0x7554, 0x94C8, 0x7559, 0x97AF, 0x755A, 0xE15C,
+	0x755B, 0xE15A, 0x755C, 0x927B, 0x755D, 0x90A4, 0x7560, 0x94A9,
+	0x7562, 0x954C, 0x7564, 0xE15E, 0x7565, 0x97AA, 0x7566, 0x8C6C,
+	0x7567, 0xE15F, 0x7569, 0xE15D, 0x756A, 0x94D4, 0x756B, 0xE160,
+	0x756D, 0xE161, 0x756F, 0xFB6F, 0x7570, 0x88D9, 0x7573, 0x8FF4,
+	0x7574, 0xE166, 0x7576, 0xE163, 0x7577, 0x93EB, 0x7578, 0xE162,
+	0x757F, 0x8B45, 0x7582, 0xE169, 0x7586, 0xE164, 0x7587, 0xE165,
+	0x7589, 0xE168, 0x758A, 0xE167, 0x758B, 0x9544, 0x758E, 0x9161,
+	0x758F, 0x9160, 0x7591, 0x8B5E, 0x7594, 0xE16A, 0x759A, 0xE16B,
+	0x759D, 0xE16C, 0x75A3, 0xE16E, 0x75A5, 0xE16D, 0x75AB, 0x8975,
+	0x75B1, 0xE176, 0x75B2, 0x94E6, 0x75B3, 0xE170, 0x75B5, 0xE172,
+	0x75B8, 0xE174, 0x75B9, 0x905D, 0x75BC, 0xE175, 0x75BD, 0xE173,
+	0x75BE, 0x8EBE, 0x75C2, 0xE16F, 0x75C3, 0xE171, 0x75C5, 0x9561,
+	0x75C7, 0x8FC7, 0x75CA, 0xE178, 0x75CD, 0xE177, 0x75D2, 0xE179,
+	0x75D4, 0x8EA4, 0x75D5, 0x8DAD, 0x75D8, 0x9397, 0x75D9, 0xE17A,
+	0x75DB, 0x92C9, 0x75DE, 0xE17C, 0x75E2, 0x979F, 0x75E3, 0xE17B,
+	0x75E9, 0x9189, 0x75F0, 0xE182, 0x75F2, 0xE184, 0x75F3, 0xE185,
+	0x75F4, 0x9273, 0x75FA, 0xE183, 0x75FC, 0xE180, 0x75FE, 0xE17D,
+	0x75FF, 0xE17E, 0x7601, 0xE181, 0x7609, 0xE188, 0x760B, 0xE186,
+	0x760D, 0xE187, 0x761F, 0xE189, 0x7620, 0xE18B, 0x7621, 0xE18C,
+	0x7622, 0xE18D, 0x7624, 0xE18E, 0x7627, 0xE18A, 0x7630, 0xE190,
+	0x7634, 0xE18F, 0x763B, 0xE191, 0x7642, 0x97C3, 0x7646, 0xE194,
+	0x7647, 0xE192, 0x7648, 0xE193, 0x764C, 0x8AE0, 0x7652, 0x96FC,
+	0x7656, 0x95C8, 0x7658, 0xE196, 0x765C, 0xE195, 0x7661, 0xE197,
+	0x7662, 0xE198, 0x7667, 0xE19C, 0x7668, 0xE199, 0x7669, 0xE19A,
+	0x766A, 0xE19B, 0x766C, 0xE19D, 0x7670, 0xE19E, 0x7672, 0xE19F,
+	0x7676, 0xE1A0, 0x7678, 0xE1A1, 0x767A, 0x94AD, 0x767B, 0x936F,
+	0x767C, 0xE1A2, 0x767D, 0x9492, 0x767E, 0x9553, 0x7680, 0xE1A3,
+	0x7682, 0xFB70, 0x7683, 0xE1A4, 0x7684, 0x9349, 0x7686, 0x8A46,
+	0x7687, 0x8D63, 0x7688, 0xE1A5, 0x768B, 0xE1A6, 0x768E, 0xE1A7,
+	0x7690, 0x8E48, 0x7693, 0xE1A9, 0x7696, 0xE1A8, 0x7699, 0xE1AA,
+	0x769A, 0xE1AB, 0x769B, 0xFB73, 0x769C, 0xFB71, 0x769E, 0xFB72,
+	0x76A6, 0xFB74, 0x76AE, 0x94E7, 0x76B0, 0xE1AC, 0x76B4, 0xE1AD,
+	0x76B7, 0xEA89, 0x76B8, 0xE1AE, 0x76B9, 0xE1AF, 0x76BA, 0xE1B0,
+	0x76BF, 0x8E4D, 0x76C2, 0xE1B1, 0x76C3, 0x9475, 0x76C6, 0x967E,
+	0x76C8, 0x896D, 0x76CA, 0x8976, 0x76CD, 0xE1B2, 0x76D2, 0xE1B4,
+	0x76D6, 0xE1B3, 0x76D7, 0x9390, 0x76DB, 0x90B7, 0x76DC, 0x9F58,
+	0x76DE, 0xE1B5, 0x76DF, 0x96BF, 0x76E1, 0xE1B6, 0x76E3, 0x8AC4,
+	0x76E4, 0x94D5, 0x76E5, 0xE1B7, 0x76E7, 0xE1B8, 0x76EA, 0xE1B9,
+	0x76EE, 0x96DA, 0x76F2, 0x96D3, 0x76F4, 0x92BC, 0x76F8, 0x918A,
+	0x76FB, 0xE1BB, 0x76FE, 0x8F82, 0x7701, 0x8FC8, 0x7704, 0xE1BE,
+	0x7707, 0xE1BD, 0x7708, 0xE1BC, 0x7709, 0x94FB, 0x770B, 0x8AC5,
+	0x770C, 0x8CA7, 0x771B, 0xE1C4, 0x771E, 0xE1C1, 0x771F, 0x905E,
+	0x7720, 0x96B0, 0x7724, 0xE1C0, 0x7725, 0xE1C2, 0x7726, 0xE1C3,
+	0x7729, 0xE1BF, 0x7737, 0xE1C5, 0x7738, 0xE1C6, 0x773A, 0x92AD,
+	0x773C, 0x8AE1, 0x7740, 0x9285, 0x7746, 0xFB76, 0x7747, 0xE1C7,
+	0x775A, 0xE1C8, 0x775B, 0xE1CB, 0x7761, 0x9087, 0x7763, 0x93C2,
+	0x7765, 0xE1CC, 0x7766, 0x9672, 0x7768, 0xE1C9, 0x776B, 0xE1CA,
+	0x7779, 0xE1CF, 0x777E, 0xE1CE, 0x777F, 0xE1CD, 0x778B, 0xE1D1,
+	0x778E, 0xE1D0, 0x7791, 0xE1D2, 0x779E, 0xE1D4, 0x77A0, 0xE1D3,
+	0x77A5, 0x95CB, 0x77AC, 0x8F75, 0x77AD, 0x97C4, 0x77B0, 0xE1D5,
+	0x77B3, 0x93B5, 0x77B6, 0xE1D6, 0x77B9, 0xE1D7, 0x77BB, 0xE1DB,
+	0x77BC, 0xE1D9, 0x77BD, 0xE1DA, 0x77BF, 0xE1D8, 0x77C7, 0xE1DC,
+	0x77CD, 0xE1DD, 0x77D7, 0xE1DE, 0x77DA, 0xE1DF, 0x77DB, 0x96B5,
+	0x77DC, 0xE1E0, 0x77E2, 0x96EE, 0x77E3, 0xE1E1, 0x77E5, 0x926D,
+	0x77E7, 0x948A, 0x77E9, 0x8BE9, 0x77ED, 0x925A, 0x77EE, 0xE1E2,
+	0x77EF, 0x8BB8, 0x77F3, 0x90CE, 0x77FC, 0xE1E3, 0x7802, 0x8DBB,
+	0x780C, 0xE1E4, 0x7812, 0xE1E5, 0x7814, 0x8CA4, 0x7815, 0x8DD3,
+	0x7820, 0xE1E7, 0x7821, 0xFB78, 0x7825, 0x9375, 0x7826, 0x8DD4,
+	0x7827, 0x8B6D, 0x7832, 0x9643, 0x7834, 0x946A, 0x783A, 0x9376,
+	0x783F, 0x8D7B, 0x7845, 0xE1E9, 0x784E, 0xFB79, 0x785D, 0x8FC9,
+	0x7864, 0xFB7A, 0x786B, 0x97B0, 0x786C, 0x8D64, 0x786F, 0x8CA5,
+	0x7872, 0x94A1, 0x7874, 0xE1EB, 0x787A, 0xFB7B, 0x787C, 0xE1ED,
+	0x7881, 0x8CE9, 0x7886, 0xE1EC, 0x7887, 0x92F4, 0x788C, 0xE1EF,
+	0x788D, 0x8A56, 0x788E, 0xE1EA, 0x7891, 0x94E8, 0x7893, 0x894F,
+	0x7895, 0x8DEA, 0x7897, 0x9871, 0x789A, 0xE1EE, 0x78A3, 0xE1F0,
+	0x78A7, 0x95C9, 0x78A9, 0x90D7, 0x78AA, 0xE1F2, 0x78AF, 0xE1F3,
+	0x78B5, 0xE1F1, 0x78BA, 0x8A6D, 0x78BC, 0xE1F9, 0x78BE, 0xE1F8,
+	0x78C1, 0x8EA5, 0x78C5, 0xE1FA, 0x78C6, 0xE1F5, 0x78CA, 0xE1FB,
+	0x78CB, 0xE1F6, 0x78D0, 0x94D6, 0x78D1, 0xE1F4, 0x78D4, 0xE1F7,
+	0x78DA, 0xE241, 0x78E7, 0xE240, 0x78E8, 0x9681, 0x78EC, 0xE1FC,
+	0x78EF, 0x88E9, 0x78F4, 0xE243, 0x78FD, 0xE242, 0x7901, 0x8FCA,
+	0x7907, 0xE244, 0x790E, 0x9162, 0x7911, 0xE246, 0x7912, 0xE245,
+	0x7919, 0xE247, 0x7926, 0xE1E6, 0x792A, 0xE1E8, 0x792B, 0xE249,
+	0x792C, 0xE248, 0x7930, 0xFB7C, 0x793A, 0x8EA6, 0x793C, 0x97E7,
+	0x793E, 0x8ED0, 0x7940, 0xE24A, 0x7941, 0x8C56, 0x7947, 0x8B5F,
+	0x7948, 0x8B46, 0x7949, 0x8E83, 0x7950, 0x9753, 0x7953, 0xE250,
+	0x7955, 0xE24F, 0x7956, 0x9163, 0x7957, 0xE24C, 0x795A, 0xE24E,
+	0x795D, 0x8F6A, 0x795E, 0x905F, 0x795F, 0xE24D, 0x7960, 0xE24B,
+	0x7962, 0x9449, 0x7965, 0x8FCB, 0x7968, 0x955B, 0x796D, 0x8DD5,
+	0x7977, 0x9398, 0x797A, 0xE251, 0x797F, 0xE252, 0x7980, 0xE268,
+	0x7981, 0x8BD6, 0x7984, 0x985C, 0x7985, 0x9154, 0x798A, 0xE253,
+	0x798D, 0x89D0, 0x798E, 0x92F5, 0x798F, 0x959F, 0x7994, 0xFB81,
+	0x799B, 0xFB83, 0x799D, 0xE254, 0x79A6, 0x8B9A, 0x79A7, 0xE255,
+	0x79AA, 0xE257, 0x79AE, 0xE258, 0x79B0, 0x9448, 0x79B3, 0xE259,
+	0x79B9, 0xE25A, 0x79BA, 0xE25B, 0x79BD, 0x8BD7, 0x79BE, 0x89D1,
+	0x79BF, 0x93C3, 0x79C0, 0x8F47, 0x79C1, 0x8E84, 0x79C9, 0xE25C,
+	0x79CB, 0x8F48, 0x79D1, 0x89C8, 0x79D2, 0x9562, 0x79D5, 0xE25D,
+	0x79D8, 0x94E9, 0x79DF, 0x9164, 0x79E1, 0xE260, 0x79E3, 0xE261,
+	0x79E4, 0x9489, 0x79E6, 0x9060, 0x79E7, 0xE25E, 0x79E9, 0x9281,
+	0x79EC, 0xE25F, 0x79F0, 0x8FCC, 0x79FB, 0x88DA, 0x7A00, 0x8B48,
+	0x7A08, 0xE262, 0x7A0B, 0x92F6, 0x7A0D, 0xE263, 0x7A0E, 0x90C5,
+	0x7A14, 0x96AB, 0x7A17, 0x9542, 0x7A18, 0xE264, 0x7A19, 0xE265,
+	0x7A1A, 0x9274, 0x7A1C, 0x97C5, 0x7A1F, 0xE267, 0x7A20, 0xE266,
+	0x7A2E, 0x8EED, 0x7A31, 0xE269, 0x7A32, 0x88EE, 0x7A37, 0xE26C,
+	0x7A3B, 0xE26A, 0x7A3C, 0x89D2, 0x7A3D, 0x8C6D, 0x7A3E, 0xE26B,
+	0x7A3F, 0x8D65, 0x7A40, 0x8D92, 0x7A42, 0x95E4, 0x7A43, 0xE26D,
+	0x7A46, 0x9673, 0x7A49, 0xE26F, 0x7A4D, 0x90CF, 0x7A4E, 0x896E,
+	0x7A4F, 0x89B8, 0x7A50, 0x88AA, 0x7A57, 0xE26E, 0x7A61, 0xE270,
+	0x7A62, 0xE271, 0x7A63, 0x8FF5, 0x7A69, 0xE272, 0x7A6B, 0x8A6E,
+	0x7A70, 0xE274, 0x7A74, 0x8C8A, 0x7A76, 0x8B86, 0x7A79, 0xE275,
+	0x7A7A, 0x8BF3, 0x7A7D, 0xE276, 0x7A7F, 0x90FA, 0x7A81, 0x93CB,
+	0x7A83, 0x90DE, 0x7A84, 0x8DF3, 0x7A88, 0xE277, 0x7A92, 0x9282,
+	0x7A93, 0x918B, 0x7A95, 0xE279, 0x7A96, 0xE27B, 0x7A97, 0xE278,
+	0x7A98, 0xE27A, 0x7A9F, 0x8C41, 0x7AA9, 0xE27C, 0x7AAA, 0x8C45,
+	0x7AAE, 0x8B87, 0x7AAF, 0x9771, 0x7AB0, 0xE27E, 0x7AB6, 0xE280,
+	0x7ABA, 0x894D, 0x7ABF, 0xE283, 0x7AC3, 0x8A96, 0x7AC4, 0xE282,
+	0x7AC5, 0xE281, 0x7AC7, 0xE285, 0x7AC8, 0xE27D, 0x7ACA, 0xE286,
+	0x7ACB, 0x97A7, 0x7ACD, 0xE287, 0x7ACF, 0xE288, 0x7AD1, 0xFB84,
+	0x7AD2, 0x9AF2, 0x7AD3, 0xE28A, 0x7AD5, 0xE289, 0x7AD9, 0xE28B,
+	0x7ADA, 0xE28C, 0x7ADC, 0x97B3, 0x7ADD, 0xE28D, 0x7ADF, 0xE8ED,
+	0x7AE0, 0x8FCD, 0x7AE1, 0xE28E, 0x7AE2, 0xE28F, 0x7AE3, 0x8F76,
+	0x7AE5, 0x93B6, 0x7AE6, 0xE290, 0x7AE7, 0xFB85, 0x7AEA, 0x9247,
+	0x7AEB, 0xFB87, 0x7AED, 0xE291, 0x7AEF, 0x925B, 0x7AF0, 0xE292,
+	0x7AF6, 0x8BA3, 0x7AF8, 0x995E, 0x7AF9, 0x927C, 0x7AFA, 0x8EB1,
+	0x7AFF, 0x8AC6, 0x7B02, 0xE293, 0x7B04, 0xE2A0, 0x7B06, 0xE296,
+	0x7B08, 0x8B88, 0x7B0A, 0xE295, 0x7B0B, 0xE2A2, 0x7B0F, 0xE294,
+	0x7B11, 0x8FCE, 0x7B18, 0xE298, 0x7B19, 0xE299, 0x7B1B, 0x934A,
+	0x7B1E, 0xE29A, 0x7B20, 0x8A7D, 0x7B25, 0x9079, 0x7B26, 0x9584,
+	0x7B28, 0xE29C, 0x7B2C, 0x91E6, 0x7B33, 0xE297, 0x7B35, 0xE29B,
+	0x7B36, 0xE29D, 0x7B39, 0x8DF9, 0x7B45, 0xE2A4, 0x7B46, 0x954D,
+	0x7B48, 0x94A4, 0x7B49, 0x9399, 0x7B4B, 0x8BD8, 0x7B4C, 0xE2A3,
+	0x7B4D, 0xE2A1, 0x7B4F, 0x94B3, 0x7B50, 0xE29E, 0x7B51, 0x927D,
+	0x7B52, 0x939B, 0x7B54, 0x939A, 0x7B56, 0x8DF4, 0x7B5D, 0xE2B6,
+	0x7B65, 0xE2A6, 0x7B67, 0xE2A8, 0x7B6C, 0xE2AB, 0x7B6E, 0xE2AC,
+	0x7B70, 0xE2A9, 0x7B71, 0xE2AA, 0x7B74, 0xE2A7, 0x7B75, 0xE2A5,
+	0x7B7A, 0xE29F, 0x7B86, 0x95CD, 0x7B87, 0x89D3, 0x7B8B, 0xE2B3,
+	0x7B8D, 0xE2B0, 0x7B8F, 0xE2B5, 0x7B92, 0xE2B4, 0x7B94, 0x9493,
+	0x7B95, 0x96A5, 0x7B97, 0x8E5A, 0x7B98, 0xE2AE, 0x7B99, 0xE2B7,
+	0x7B9A, 0xE2B2, 0x7B9C, 0xE2B1, 0x7B9D, 0xE2AD, 0x7B9E, 0xFB88,
+	0x7B9F, 0xE2AF, 0x7BA1, 0x8AC7, 0x7BAA, 0x925C, 0x7BAD, 0x90FB,
+	0x7BB1, 0x94A0, 0x7BB4, 0xE2BC, 0x7BB8, 0x94A2, 0x7BC0, 0x90DF,
+	0x7BC1, 0xE2B9, 0x7BC4, 0x94CD, 0x7BC6, 0xE2BD, 0x7BC7, 0x95D1,
+	0x7BC9, 0x927A, 0x7BCB, 0xE2B8, 0x7BCC, 0xE2BA, 0x7BCF, 0xE2BB,
+	0x7BDD, 0xE2BE, 0x7BE0, 0x8EC2, 0x7BE4, 0x93C4, 0x7BE5, 0xE2C3,
+	0x7BE6, 0xE2C2, 0x7BE9, 0xE2BF, 0x7BED, 0x9855, 0x7BF3, 0xE2C8,
+	0x7BF6, 0xE2CC, 0x7BF7, 0xE2C9, 0x7C00, 0xE2C5, 0x7C07, 0xE2C6,
+	0x7C0D, 0xE2CB, 0x7C11, 0xE2C0, 0x7C12, 0x99D3, 0x7C13, 0xE2C7,
+	0x7C14, 0xE2C1, 0x7C17, 0xE2CA, 0x7C1F, 0xE2D0, 0x7C21, 0x8AC8,
+	0x7C23, 0xE2CD, 0x7C27, 0xE2CE, 0x7C2A, 0xE2CF, 0x7C2B, 0xE2D2,
+	0x7C37, 0xE2D1, 0x7C38, 0x94F4, 0x7C3D, 0xE2D3, 0x7C3E, 0x97FA,
+	0x7C3F, 0x95EB, 0x7C40, 0xE2D8, 0x7C43, 0xE2D5, 0x7C4C, 0xE2D4,
+	0x7C4D, 0x90D0, 0x7C4F, 0xE2D7, 0x7C50, 0xE2D9, 0x7C54, 0xE2D6,
+	0x7C56, 0xE2DD, 0x7C58, 0xE2DA, 0x7C5F, 0xE2DB, 0x7C60, 0xE2C4,
+	0x7C64, 0xE2DC, 0x7C65, 0xE2DE, 0x7C6C, 0xE2DF, 0x7C73, 0x95C4,
+	0x7C75, 0xE2E0, 0x7C7E, 0x96E0, 0x7C81, 0x8BCC, 0x7C82, 0x8C48,
+	0x7C83, 0xE2E1, 0x7C89, 0x95B2, 0x7C8B, 0x9088, 0x7C8D, 0x96AE,
+	0x7C90, 0xE2E2, 0x7C92, 0x97B1, 0x7C95, 0x9494, 0x7C97, 0x9165,
+	0x7C98, 0x9453, 0x7C9B, 0x8F6C, 0x7C9F, 0x88BE, 0x7CA1, 0xE2E7,
+	0x7CA2, 0xE2E5, 0x7CA4, 0xE2E3, 0x7CA5, 0x8A9F, 0x7CA7, 0x8FCF,
+	0x7CA8, 0xE2E8, 0x7CAB, 0xE2E6, 0x7CAD, 0xE2E4, 0x7CAE, 0xE2EC,
+	0x7CB1, 0xE2EB, 0x7CB2, 0xE2EA, 0x7CB3, 0xE2E9, 0x7CB9, 0xE2ED,
+	0x7CBD, 0xE2EE, 0x7CBE, 0x90B8, 0x7CC0, 0xE2EF, 0x7CC2, 0xE2F1,
+	0x7CC5, 0xE2F0, 0x7CCA, 0x8CD0, 0x7CCE, 0x9157, 0x7CD2, 0xE2F3,
+	0x7CD6, 0x939C, 0x7CD8, 0xE2F2, 0x7CDC, 0xE2F4, 0x7CDE, 0x95B3,
+	0x7CDF, 0x918C, 0x7CE0, 0x8D66, 0x7CE2, 0xE2F5, 0x7CE7, 0x97C6,
+	0x7CEF, 0xE2F7, 0x7CF2, 0xE2F8, 0x7CF4, 0xE2F9, 0x7CF6, 0xE2FA,
+	0x7CF8, 0x8E85, 0x7CFA, 0xE2FB, 0x7CFB, 0x8C6E, 0x7CFE, 0x8B8A,
+	0x7D00, 0x8B49, 0x7D02, 0xE340, 0x7D04, 0x96F1, 0x7D05, 0x8D67,
+	0x7D06, 0xE2FC, 0x7D0A, 0xE343, 0x7D0B, 0x96E4, 0x7D0D, 0x945B,
+	0x7D10, 0x9552, 0x7D14, 0x8F83, 0x7D15, 0xE342, 0x7D17, 0x8ED1,
+	0x7D18, 0x8D68, 0x7D19, 0x8E86, 0x7D1A, 0x8B89, 0x7D1B, 0x95B4,
+	0x7D1C, 0xE341, 0x7D20, 0x9166, 0x7D21, 0x9661, 0x7D22, 0x8DF5,
+	0x7D2B, 0x8E87, 0x7D2C, 0x92DB, 0x7D2E, 0xE346, 0x7D2F, 0x97DD,
+	0x7D30, 0x8DD7, 0x7D32, 0xE347, 0x7D33, 0x9061, 0x7D35, 0xE349,
+	0x7D39, 0x8FD0, 0x7D3A, 0x8DAE, 0x7D3F, 0xE348, 0x7D42, 0x8F49,
+	0x7D43, 0x8CBC, 0x7D44, 0x9167, 0x7D45, 0xE344, 0x7D46, 0xE34A,
+	0x7D48, 0xFB8A, 0x7D4B, 0xE345, 0x7D4C, 0x8C6F, 0x7D4E, 0xE34D,
+	0x7D4F, 0xE351, 0x7D50, 0x8C8B, 0x7D56, 0xE34C, 0x7D5B, 0xE355,
+	0x7D5C, 0xFB8B, 0x7D5E, 0x8D69, 0x7D61, 0x978D, 0x7D62, 0x88BA,
+	0x7D63, 0xE352, 0x7D66, 0x8B8B, 0x7D68, 0xE34F, 0x7D6E, 0xE350,
+	0x7D71, 0x939D, 0x7D72, 0xE34E, 0x7D73, 0xE34B, 0x7D75, 0x8A47,
+	0x7D76, 0x90E2, 0x7D79, 0x8CA6, 0x7D7D, 0xE357, 0x7D89, 0xE354,
+	0x7D8F, 0xE356, 0x7D93, 0xE353, 0x7D99, 0x8C70, 0x7D9A, 0x91B1,
+	0x7D9B, 0xE358, 0x7D9C, 0x918E, 0x7D9F, 0xE365, 0x7DA0, 0xFB8D,
+	0x7DA2, 0xE361, 0x7DA3, 0xE35B, 0x7DAB, 0xE35F, 0x7DAC, 0x8EF8,
+	0x7DAD, 0x88DB, 0x7DAE, 0xE35A, 0x7DAF, 0xE362, 0x7DB0, 0xE366,
+	0x7DB1, 0x8D6A, 0x7DB2, 0x96D4, 0x7DB4, 0x92D4, 0x7DB5, 0xE35C,
+	0x7DB7, 0xFB8C, 0x7DB8, 0xE364, 0x7DBA, 0xE359, 0x7DBB, 0x925D,
+	0x7DBD, 0xE35E, 0x7DBE, 0x88BB, 0x7DBF, 0x96C8, 0x7DC7, 0xE35D,
+	0x7DCA, 0x8BD9, 0x7DCB, 0x94EA, 0x7DCF, 0x918D, 0x7DD1, 0x97CE,
+	0x7DD2, 0x8F8F, 0x7DD5, 0xE38E, 0x7DD6, 0xFB8E, 0x7DD8, 0xE367,
+	0x7DDA, 0x90FC, 0x7DDC, 0xE363, 0x7DDD, 0xE368, 0x7DDE, 0xE36A,
+	0x7DE0, 0x92F7, 0x7DE1, 0xE36D, 0x7DE4, 0xE369, 0x7DE8, 0x95D2,
+	0x7DE9, 0x8AC9, 0x7DEC, 0x96C9, 0x7DEF, 0x88DC, 0x7DF2, 0xE36C,
+	0x7DF4, 0x97FB, 0x7DFB, 0xE36B, 0x7E01, 0x898F, 0x7E04, 0x93EA,
+	0x7E05, 0xE36E, 0x7E09, 0xE375, 0x7E0A, 0xE36F, 0x7E0B, 0xE376,
+	0x7E12, 0xE372, 0x7E1B, 0x949B, 0x7E1E, 0x8EC8, 0x7E1F, 0xE374,
+	0x7E21, 0xE371, 0x7E22, 0xE377, 0x7E23, 0xE370, 0x7E26, 0x8F63,
+	0x7E2B, 0x9644, 0x7E2E, 0x8F6B, 0x7E31, 0xE373, 0x7E32, 0xE380,
+	0x7E35, 0xE37B, 0x7E37, 0xE37E, 0x7E39, 0xE37C, 0x7E3A, 0xE381,
+	0x7E3B, 0xE37A, 0x7E3D, 0xE360, 0x7E3E, 0x90D1, 0x7E41, 0x94C9,
+	0x7E43, 0xE37D, 0x7E46, 0xE378, 0x7E4A, 0x9140, 0x7E4B, 0x8C71,
+	0x7E4D, 0x8F4A, 0x7E52, 0xFB8F, 0x7E54, 0x9044, 0x7E55, 0x9155,
+	0x7E56, 0xE384, 0x7E59, 0xE386, 0x7E5A, 0xE387, 0x7E5D, 0xE383,
+	0x7E5E, 0xE385, 0x7E66, 0xE379, 0x7E67, 0xE382, 0x7E69, 0xE38A,
+	0x7E6A, 0xE389, 0x7E6D, 0x969A, 0x7E70, 0x8C4A, 0x7E79, 0xE388,
+	0x7E7B, 0xE38C, 0x7E7C, 0xE38B, 0x7E7D, 0xE38F, 0x7E7F, 0xE391,
+	0x7E82, 0x8E5B, 0x7E83, 0xE38D, 0x7E88, 0xE392, 0x7E89, 0xE393,
+	0x7E8A, 0xFA5C, 0x7E8C, 0xE394, 0x7E8E, 0xE39A, 0x7E8F, 0x935A,
+	0x7E90, 0xE396, 0x7E92, 0xE395, 0x7E93, 0xE397, 0x7E94, 0xE398,
+	0x7E96, 0xE399, 0x7E9B, 0xE39B, 0x7E9C, 0xE39C, 0x7F36, 0x8ACA,
+	0x7F38, 0xE39D, 0x7F3A, 0xE39E, 0x7F45, 0xE39F, 0x7F47, 0xFB90,
+	0x7F4C, 0xE3A0, 0x7F4D, 0xE3A1, 0x7F4E, 0xE3A2, 0x7F50, 0xE3A3,
+	0x7F51, 0xE3A4, 0x7F54, 0xE3A6, 0x7F55, 0xE3A5, 0x7F58, 0xE3A7,
+	0x7F5F, 0xE3A8, 0x7F60, 0xE3A9, 0x7F67, 0xE3AC, 0x7F68, 0xE3AA,
+	0x7F69, 0xE3AB, 0x7F6A, 0x8DDF, 0x7F6B, 0x8C72, 0x7F6E, 0x9275,
+	0x7F70, 0x94B1, 0x7F72, 0x8F90, 0x7F75, 0x946C, 0x7F77, 0x94EB,
+	0x7F78, 0xE3AD, 0x7F79, 0x9CEB, 0x7F82, 0xE3AE, 0x7F83, 0xE3B0,
+	0x7F85, 0x9785, 0x7F86, 0xE3AF, 0x7F87, 0xE3B2, 0x7F88, 0xE3B1,
+	0x7F8A, 0x9772, 0x7F8C, 0xE3B3, 0x7F8E, 0x94FC, 0x7F94, 0xE3B4,
+	0x7F9A, 0xE3B7, 0x7F9D, 0xE3B6, 0x7F9E, 0xE3B5, 0x7FA1, 0xFB91,
+	0x7FA3, 0xE3B8, 0x7FA4, 0x8C51, 0x7FA8, 0x9141, 0x7FA9, 0x8B60,
+	0x7FAE, 0xE3BC, 0x7FAF, 0xE3B9, 0x7FB2, 0xE3BA, 0x7FB6, 0xE3BD,
+	0x7FB8, 0xE3BE, 0x7FB9, 0xE3BB, 0x7FBD, 0x8948, 0x7FC1, 0x89A5,
+	0x7FC5, 0xE3C0, 0x7FC6, 0xE3C1, 0x7FCA, 0xE3C2, 0x7FCC, 0x9782,
+	0x7FD2, 0x8F4B, 0x7FD4, 0xE3C4, 0x7FD5, 0xE3C3, 0x7FE0, 0x9089,
+	0x7FE1, 0xE3C5, 0x7FE6, 0xE3C6, 0x7FE9, 0xE3C7, 0x7FEB, 0x8AE3,
+	0x7FF0, 0x8ACB, 0x7FF3, 0xE3C8, 0x7FF9, 0xE3C9, 0x7FFB, 0x967C,
+	0x7FFC, 0x9783, 0x8000, 0x9773, 0x8001, 0x9856, 0x8003, 0x8D6C,
+	0x8004, 0xE3CC, 0x8005, 0x8ED2, 0x8006, 0xE3CB, 0x800B, 0xE3CD,
+	0x800C, 0x8EA7, 0x8010, 0x91CF, 0x8012, 0xE3CE, 0x8015, 0x8D6B,
+	0x8017, 0x96D5, 0x8018, 0xE3CF, 0x8019, 0xE3D0, 0x801C, 0xE3D1,
+	0x8021, 0xE3D2, 0x8028, 0xE3D3, 0x8033, 0x8EA8, 0x8036, 0x96EB,
+	0x803B, 0xE3D5, 0x803D, 0x925E, 0x803F, 0xE3D4, 0x8046, 0xE3D7,
+	0x804A, 0xE3D6, 0x8052, 0xE3D8, 0x8056, 0x90B9, 0x8058, 0xE3D9,
+	0x805A, 0xE3DA, 0x805E, 0x95B7, 0x805F, 0xE3DB, 0x8061, 0x918F,
+	0x8062, 0xE3DC, 0x8068, 0xE3DD, 0x806F, 0x97FC, 0x8070, 0xE3E0,
+	0x8072, 0xE3DF, 0x8073, 0xE3DE, 0x8074, 0x92AE, 0x8076, 0xE3E1,
+	0x8077, 0x9045, 0x8079, 0xE3E2, 0x807D, 0xE3E3, 0x807E, 0x9857,
+	0x807F, 0xE3E4, 0x8084, 0xE3E5, 0x8085, 0xE3E7, 0x8086, 0xE3E6,
+	0x8087, 0x94A3, 0x8089, 0x93F7, 0x808B, 0x985D, 0x808C, 0x94A7,
+	0x8093, 0xE3E9, 0x8096, 0x8FD1, 0x8098, 0x9549, 0x809A, 0xE3EA,
+	0x809B, 0xE3E8, 0x809D, 0x8ACC, 0x80A1, 0x8CD2, 0x80A2, 0x8E88,
+	0x80A5, 0x94EC, 0x80A9, 0x8CA8, 0x80AA, 0x9662, 0x80AC, 0xE3ED,
+	0x80AD, 0xE3EB, 0x80AF, 0x8D6D, 0x80B1, 0x8D6E, 0x80B2, 0x88E7,
+	0x80B4, 0x8DE6, 0x80BA, 0x9478, 0x80C3, 0x88DD, 0x80C4, 0xE3F2,
+	0x80C6, 0x925F, 0x80CC, 0x9477, 0x80CE, 0x91D9, 0x80D6, 0xE3F4,
+	0x80D9, 0xE3F0, 0x80DA, 0xE3F3, 0x80DB, 0xE3EE, 0x80DD, 0xE3F1,
+	0x80DE, 0x9645, 0x80E1, 0x8CD3, 0x80E4, 0x88FB, 0x80E5, 0xE3EF,
+	0x80EF, 0xE3F6, 0x80F1, 0xE3F7, 0x80F4, 0x93B7, 0x80F8, 0x8BB9,
+	0x80FC, 0xE445, 0x80FD, 0x945C, 0x8102, 0x8E89, 0x8105, 0x8BBA,
+	0x8106, 0x90C6, 0x8107, 0x9865, 0x8108, 0x96AC, 0x8109, 0xE3F5,
+	0x810A, 0x90D2, 0x811A, 0x8B72, 0x811B, 0xE3F8, 0x8123, 0xE3FA,
+	0x8129, 0xE3F9, 0x812F, 0xE3FB, 0x8131, 0x9245, 0x8133, 0x945D,
+	0x8139, 0x92AF, 0x813E, 0xE442, 0x8146, 0xE441, 0x814B, 0xE3FC,
+	0x814E, 0x9074, 0x8150, 0x9585, 0x8151, 0xE444, 0x8153, 0xE443,
+	0x8154, 0x8D6F, 0x8155, 0x9872, 0x815F, 0xE454, 0x8165, 0xE448,
+	0x8166, 0xE449, 0x816B, 0x8EEE, 0x816E, 0xE447, 0x8170, 0x8D98,
+	0x8171, 0xE446, 0x8174, 0xE44A, 0x8178, 0x92B0, 0x8179, 0x95A0,
+	0x817A, 0x9142, 0x817F, 0x91DA, 0x8180, 0xE44E, 0x8182, 0xE44F,
+	0x8183, 0xE44B, 0x8188, 0xE44C, 0x818A, 0xE44D, 0x818F, 0x8D70,
+	0x8193, 0xE455, 0x8195, 0xE451, 0x819A, 0x9586, 0x819C, 0x968C,
+	0x819D, 0x9547, 0x81A0, 0xE450, 0x81A3, 0xE453, 0x81A4, 0xE452,
+	0x81A8, 0x9663, 0x81A9, 0xE456, 0x81B0, 0xE457, 0x81B3, 0x9156,
+	0x81B5, 0xE458, 0x81B8, 0xE45A, 0x81BA, 0xE45E, 0x81BD, 0xE45B,
+	0x81BE, 0xE459, 0x81BF, 0x945E, 0x81C0, 0xE45C, 0x81C2, 0xE45D,
+	0x81C6, 0x89B0, 0x81C8, 0xE464, 0x81C9, 0xE45F, 0x81CD, 0xE460,
+	0x81D1, 0xE461, 0x81D3, 0x919F, 0x81D8, 0xE463, 0x81D9, 0xE462,
+	0x81DA, 0xE465, 0x81DF, 0xE466, 0x81E0, 0xE467, 0x81E3, 0x9062,
+	0x81E5, 0x89E7, 0x81E7, 0xE468, 0x81E8, 0x97D5, 0x81EA, 0x8EA9,
+	0x81ED, 0x8F4C, 0x81F3, 0x8E8A, 0x81F4, 0x9276, 0x81FA, 0xE469,
+	0x81FB, 0xE46A, 0x81FC, 0x8950, 0x81FE, 0xE46B, 0x8201, 0xE46C,
+	0x8202, 0xE46D, 0x8205, 0xE46E, 0x8207, 0xE46F, 0x8208, 0x8BBB,
+	0x8209, 0x9DA8, 0x820A, 0xE470, 0x820C, 0x90E3, 0x820D, 0xE471,
+	0x820E, 0x8EC9, 0x8210, 0xE472, 0x8212, 0x98AE, 0x8216, 0xE473,
+	0x8217, 0x95DC, 0x8218, 0x8ADA, 0x821B, 0x9143, 0x821C, 0x8F77,
+	0x821E, 0x9591, 0x821F, 0x8F4D, 0x8229, 0xE474, 0x822A, 0x8D71,
+	0x822B, 0xE475, 0x822C, 0x94CA, 0x822E, 0xE484, 0x8233, 0xE477,
+	0x8235, 0x91C7, 0x8236, 0x9495, 0x8237, 0x8CBD, 0x8238, 0xE476,
+	0x8239, 0x9144, 0x8240, 0xE478, 0x8247, 0x92F8, 0x8258, 0xE47A,
+	0x8259, 0xE479, 0x825A, 0xE47C, 0x825D, 0xE47B, 0x825F, 0xE47D,
+	0x8262, 0xE480, 0x8264, 0xE47E, 0x8266, 0x8ACD, 0x8268, 0xE481,
+	0x826A, 0xE482, 0x826B, 0xE483, 0x826E, 0x8DAF, 0x826F, 0x97C7,
+	0x8271, 0xE485, 0x8272, 0x9046, 0x8276, 0x8990, 0x8277, 0xE486,
+	0x8278, 0xE487, 0x827E, 0xE488, 0x828B, 0x88F0, 0x828D, 0xE489,
+	0x8292, 0xE48A, 0x8299, 0x9587, 0x829D, 0x8EC5, 0x829F, 0xE48C,
+	0x82A5, 0x8A48, 0x82A6, 0x88B0, 0x82AB, 0xE48B, 0x82AC, 0xE48E,
+	0x82AD, 0x946D, 0x82AF, 0x9063, 0x82B1, 0x89D4, 0x82B3, 0x9646,
+	0x82B8, 0x8C7C, 0x82B9, 0x8BDA, 0x82BB, 0xE48D, 0x82BD, 0x89E8,
+	0x82C5, 0x8AA1, 0x82D1, 0x8991, 0x82D2, 0xE492, 0x82D3, 0x97E8,
+	0x82D4, 0x91DB, 0x82D7, 0x9563, 0x82D9, 0xE49E, 0x82DB, 0x89D5,
+	0x82DC, 0xE49C, 0x82DE, 0xE49A, 0x82DF, 0xE491, 0x82E1, 0xE48F,
+	0x82E3, 0xE490, 0x82E5, 0x8EE1, 0x82E6, 0x8BEA, 0x82E7, 0x9297,
+	0x82EB, 0x93CF, 0x82F1, 0x8970, 0x82F3, 0xE494, 0x82F4, 0xE493,
+	0x82F9, 0xE499, 0x82FA, 0xE495, 0x82FB, 0xE498, 0x8301, 0xFB93,
+	0x8302, 0x96CE, 0x8303, 0xE497, 0x8304, 0x89D6, 0x8305, 0x8A9D,
+	0x8306, 0xE49B, 0x8309, 0xE49D, 0x830E, 0x8C73, 0x8316, 0xE4A1,
+	0x8317, 0xE4AA, 0x8318, 0xE4AB, 0x831C, 0x88A9, 0x8323, 0xE4B2,
+	0x8328, 0x88EF, 0x832B, 0xE4A9, 0x832F, 0xE4A8, 0x8331, 0xE4A3,
+	0x8332, 0xE4A2, 0x8334, 0xE4A0, 0x8335, 0xE49F, 0x8336, 0x9283,
+	0x8338, 0x91F9, 0x8339, 0xE4A5, 0x8340, 0xE4A4, 0x8345, 0xE4A7,
+	0x8349, 0x9190, 0x834A, 0x8C74, 0x834F, 0x8960, 0x8350, 0xE4A6,
+	0x8352, 0x8D72, 0x8358, 0x9191, 0x8362, 0xFB94, 0x8373, 0xE4B8,
+	0x8375, 0xE4B9, 0x8377, 0x89D7, 0x837B, 0x89AC, 0x837C, 0xE4B6,
+	0x837F, 0xFB95, 0x8385, 0xE4AC, 0x8387, 0xE4B4, 0x8389, 0xE4BB,
+	0x838A, 0xE4B5, 0x838E, 0xE4B3, 0x8393, 0xE496, 0x8396, 0xE4B1,
+	0x839A, 0xE4AD, 0x839E, 0x8ACE, 0x839F, 0xE4AF, 0x83A0, 0xE4BA,
+	0x83A2, 0xE4B0, 0x83A8, 0xE4BC, 0x83AA, 0xE4AE, 0x83AB, 0x949C,
+	0x83B1, 0x9789, 0x83B5, 0xE4B7, 0x83BD, 0xE4CD, 0x83C1, 0xE4C5,
+	0x83C5, 0x909B, 0x83C7, 0xFB96, 0x83CA, 0x8B65, 0x83CC, 0x8BDB,
+	0x83CE, 0xE4C0, 0x83D3, 0x89D9, 0x83D6, 0x8FD2, 0x83D8, 0xE4C3,
+	0x83DC, 0x8DD8, 0x83DF, 0x9370, 0x83E0, 0xE4C8, 0x83E9, 0x95EC,
+	0x83EB, 0xE4BF, 0x83EF, 0x89D8, 0x83F0, 0x8CD4, 0x83F1, 0x9548,
+	0x83F2, 0xE4C9, 0x83F4, 0xE4BD, 0x83F6, 0xFB97, 0x83F7, 0xE4C6,
+	0x83FB, 0xE4D0, 0x83FD, 0xE4C1, 0x8403, 0xE4C2, 0x8404, 0x93B8,
+	0x8407, 0xE4C7, 0x840B, 0xE4C4, 0x840C, 0x9647, 0x840D, 0xE4CA,
+	0x840E, 0x88DE, 0x8413, 0xE4BE, 0x8420, 0xE4CC, 0x8422, 0xE4CB,
+	0x8429, 0x948B, 0x842A, 0xE4D2, 0x842C, 0xE4DD, 0x8431, 0x8A9E,
+	0x8435, 0xE4E0, 0x8438, 0xE4CE, 0x843C, 0xE4D3, 0x843D, 0x978E,
+	0x8446, 0xE4DC, 0x8448, 0xFB98, 0x8449, 0x9774, 0x844E, 0x97A8,
+	0x8457, 0x9298, 0x845B, 0x8A8B, 0x8461, 0x9592, 0x8462, 0xE4E2,
+	0x8463, 0x939F, 0x8466, 0x88AF, 0x8469, 0xE4DB, 0x846B, 0xE4D7,
+	0x846C, 0x9192, 0x846D, 0xE4D1, 0x846E, 0xE4D9, 0x846F, 0xE4DE,
+	0x8471, 0x944B, 0x8475, 0x88A8, 0x8477, 0xE4D6, 0x8479, 0xE4DF,
+	0x847A, 0x9598, 0x8482, 0xE4DA, 0x8484, 0xE4D5, 0x848B, 0x8FD3,
+	0x8490, 0x8F4E, 0x8494, 0x8EAA, 0x8499, 0x96D6, 0x849C, 0x9566,
+	0x849F, 0xE4E5, 0x84A1, 0xE4EE, 0x84AD, 0xE4D8, 0x84B2, 0x8A97,
+	0x84B4, 0xFB99, 0x84B8, 0x8FF6, 0x84B9, 0xE4E3, 0x84BB, 0xE4E8,
+	0x84BC, 0x9193, 0x84BF, 0xE4E4, 0x84C1, 0xE4EB, 0x84C4, 0x927E,
+	0x84C6, 0xE4EC, 0x84C9, 0x9775, 0x84CA, 0xE4E1, 0x84CB, 0x8A57,
+	0x84CD, 0xE4E7, 0x84D0, 0xE4EA, 0x84D1, 0x96AA, 0x84D6, 0xE4ED,
+	0x84D9, 0xE4E6, 0x84DA, 0xE4E9, 0x84DC, 0xFA60, 0x84EC, 0x9648,
+	0x84EE, 0x9840, 0x84F4, 0xE4F1, 0x84FC, 0xE4F8, 0x84FF, 0xE4F0,
+	0x8500, 0x8EC1, 0x8506, 0xE4CF, 0x8511, 0x95CC, 0x8513, 0x96A0,
+	0x8514, 0xE4F7, 0x8515, 0xE4F6, 0x8517, 0xE4F2, 0x8518, 0xE4F3,
+	0x851A, 0x8955, 0x851F, 0xE4F5, 0x8521, 0xE4EF, 0x8526, 0x92D3,
+	0x852C, 0xE4F4, 0x852D, 0x88FC, 0x8535, 0x91A0, 0x853D, 0x95C1,
+	0x8540, 0xE4F9, 0x8541, 0xE540, 0x8543, 0x94D7, 0x8548, 0xE4FC,
+	0x8549, 0x8FD4, 0x854A, 0x8EC7, 0x854B, 0xE542, 0x854E, 0x8BBC,
+	0x8553, 0xFB9A, 0x8555, 0xE543, 0x8557, 0x9599, 0x8558, 0xE4FB,
+	0x8559, 0xFB9B, 0x855A, 0xE4D4, 0x8563, 0xE4FA, 0x8568, 0x986E,
+	0x8569, 0x93A0, 0x856A, 0x9593, 0x856B, 0xFB9C, 0x856D, 0xE54A,
+	0x8577, 0xE550, 0x857E, 0xE551, 0x8580, 0xE544, 0x8584, 0x9496,
+	0x8587, 0xE54E, 0x8588, 0xE546, 0x858A, 0xE548, 0x8590, 0xE552,
+	0x8591, 0xE547, 0x8594, 0xE54B, 0x8597, 0x8992, 0x8599, 0x93E3,
+	0x859B, 0xE54C, 0x859C, 0xE54F, 0x85A4, 0xE545, 0x85A6, 0x9145,
+	0x85A8, 0xE549, 0x85A9, 0x8E46, 0x85AA, 0x9064, 0x85AB, 0x8C4F,
+	0x85AC, 0x96F2, 0x85AE, 0x96F7, 0x85AF, 0x8F92, 0x85B0, 0xFB9E,
+	0x85B9, 0xE556, 0x85BA, 0xE554, 0x85C1, 0x986D, 0x85C9, 0xE553,
+	0x85CD, 0x9795, 0x85CF, 0xE555, 0x85D0, 0xE557, 0x85D5, 0xE558,
+	0x85DC, 0xE55B, 0x85DD, 0xE559, 0x85E4, 0x93A1, 0x85E5, 0xE55A,
+	0x85E9, 0x94CB, 0x85EA, 0xE54D, 0x85F7, 0x8F93, 0x85F9, 0xE55C,
+	0x85FA, 0xE561, 0x85FB, 0x9194, 0x85FE, 0xE560, 0x8602, 0xE541,
+	0x8606, 0xE562, 0x8607, 0x9168, 0x860A, 0xE55D, 0x860B, 0xE55F,
+	0x8613, 0xE55E, 0x8616, 0x9F50, 0x8617, 0x9F41, 0x861A, 0xE564,
+	0x8622, 0xE563, 0x862D, 0x9796, 0x862F, 0xE1BA, 0x8630, 0xE565,
+	0x863F, 0xE566, 0x864D, 0xE567, 0x864E, 0x8CD5, 0x8650, 0x8B73,
+	0x8654, 0xE569, 0x8655, 0x997C, 0x865A, 0x8B95, 0x865C, 0x97B8,
+	0x865E, 0x8BF1, 0x865F, 0xE56A, 0x8667, 0xE56B, 0x866B, 0x928E,
+	0x8671, 0xE56C, 0x8679, 0x93F8, 0x867B, 0x88B8, 0x868A, 0x89E1,
+	0x868B, 0xE571, 0x868C, 0xE572, 0x8693, 0xE56D, 0x8695, 0x8E5C,
+	0x86A3, 0xE56E, 0x86A4, 0x9461, 0x86A9, 0xE56F, 0x86AA, 0xE570,
+	0x86AB, 0xE57A, 0x86AF, 0xE574, 0x86B0, 0xE577, 0x86B6, 0xE573,
+	0x86C4, 0xE575, 0x86C6, 0xE576, 0x86C7, 0x8ED6, 0x86C9, 0xE578,
+	0x86CB, 0x9260, 0x86CD, 0x8C75, 0x86CE, 0x8A61, 0x86D4, 0xE57B,
+	0x86D9, 0x8A5E, 0x86DB, 0xE581, 0x86DE, 0xE57C, 0x86DF, 0xE580,
+	0x86E4, 0x94B8, 0x86E9, 0xE57D, 0x86EC, 0xE57E, 0x86ED, 0x9567,
+	0x86EE, 0x94D8, 0x86EF, 0xE582, 0x86F8, 0x91FB, 0x86F9, 0xE58C,
+	0x86FB, 0xE588, 0x86FE, 0x89E9, 0x8700, 0xE586, 0x8702, 0x9649,
+	0x8703, 0xE587, 0x8706, 0xE584, 0x8708, 0xE585, 0x8709, 0xE58A,
+	0x870A, 0xE58D, 0x870D, 0xE58B, 0x8711, 0xE589, 0x8712, 0xE583,
+	0x8718, 0x9277, 0x871A, 0xE594, 0x871C, 0x96A8, 0x8725, 0xE592,
+	0x8729, 0xE593, 0x8734, 0xE58E, 0x8737, 0xE590, 0x873B, 0xE591,
+	0x873F, 0xE58F, 0x8749, 0x90E4, 0x874B, 0x9858, 0x874C, 0xE598,
+	0x874E, 0xE599, 0x8753, 0xE59F, 0x8755, 0x9049, 0x8757, 0xE59B,
+	0x8759, 0xE59E, 0x875F, 0xE596, 0x8760, 0xE595, 0x8763, 0xE5A0,
+	0x8766, 0x89DA, 0x8768, 0xE59C, 0x876A, 0xE5A1, 0x876E, 0xE59D,
+	0x8774, 0xE59A, 0x8776, 0x92B1, 0x8778, 0xE597, 0x877F, 0x9488,
+	0x8782, 0xE5A5, 0x878D, 0x975A, 0x879F, 0xE5A4, 0x87A2, 0xE5A3,
+	0x87AB, 0xE5AC, 0x87AF, 0xE5A6, 0x87B3, 0xE5AE, 0x87BA, 0x9786,
+	0x87BB, 0xE5B1, 0x87BD, 0xE5A8, 0x87C0, 0xE5A9, 0x87C4, 0xE5AD,
+	0x87C6, 0xE5B0, 0x87C7, 0xE5AF, 0x87CB, 0xE5A7, 0x87D0, 0xE5AA,
+	0x87D2, 0xE5BB, 0x87E0, 0xE5B4, 0x87EF, 0xE5B2, 0x87F2, 0xE5B3,
+	0x87F6, 0xE5B8, 0x87F7, 0xE5B9, 0x87F9, 0x8A49, 0x87FB, 0x8B61,
+	0x87FE, 0xE5B7, 0x8805, 0xE5A2, 0x8807, 0xFBA1, 0x880D, 0xE5B6,
+	0x880E, 0xE5BA, 0x880F, 0xE5B5, 0x8811, 0xE5BC, 0x8815, 0xE5BE,
+	0x8816, 0xE5BD, 0x8821, 0xE5C0, 0x8822, 0xE5BF, 0x8823, 0xE579,
+	0x8827, 0xE5C4, 0x8831, 0xE5C1, 0x8836, 0xE5C2, 0x8839, 0xE5C3,
+	0x883B, 0xE5C5, 0x8840, 0x8C8C, 0x8842, 0xE5C7, 0x8844, 0xE5C6,
+	0x8846, 0x8F4F, 0x884C, 0x8D73, 0x884D, 0x9FA5, 0x8852, 0xE5C8,
+	0x8853, 0x8F70, 0x8857, 0x8A58, 0x8859, 0xE5C9, 0x885B, 0x8971,
+	0x885D, 0x8FD5, 0x885E, 0xE5CA, 0x8861, 0x8D74, 0x8862, 0xE5CB,
+	0x8863, 0x88DF, 0x8868, 0x955C, 0x886B, 0xE5CC, 0x8870, 0x908A,
+	0x8872, 0xE5D3, 0x8875, 0xE5D0, 0x8877, 0x928F, 0x887D, 0xE5D1,
+	0x887E, 0xE5CE, 0x887F, 0x8BDC, 0x8881, 0xE5CD, 0x8882, 0xE5D4,
+	0x8888, 0x8C55, 0x888B, 0x91DC, 0x888D, 0xE5DA, 0x8892, 0xE5D6,
+	0x8896, 0x91B3, 0x8897, 0xE5D5, 0x8899, 0xE5D8, 0x889E, 0xE5CF,
+	0x88A2, 0xE5D9, 0x88A4, 0xE5DB, 0x88AB, 0x94ED, 0x88AE, 0xE5D7,
+	0x88B0, 0xE5DC, 0x88B1, 0xE5DE, 0x88B4, 0x8CD1, 0x88B5, 0xE5D2,
+	0x88B7, 0x88BF, 0x88BF, 0xE5DD, 0x88C1, 0x8DD9, 0x88C2, 0x97F4,
+	0x88C3, 0xE5DF, 0x88C4, 0xE5E0, 0x88C5, 0x9195, 0x88CF, 0x97A0,
+	0x88D4, 0xE5E1, 0x88D5, 0x9754, 0x88D8, 0xE5E2, 0x88D9, 0xE5E3,
+	0x88DC, 0x95E2, 0x88DD, 0xE5E4, 0x88DF, 0x8DBE, 0x88E1, 0x97A1,
+	0x88E8, 0xE5E9, 0x88F2, 0xE5EA, 0x88F3, 0x8FD6, 0x88F4, 0xE5E8,
+	0x88F5, 0xFBA2, 0x88F8, 0x9787, 0x88F9, 0xE5E5, 0x88FC, 0xE5E7,
+	0x88FD, 0x90BB, 0x88FE, 0x909E, 0x8902, 0xE5E6, 0x8904, 0xE5EB,
+	0x8907, 0x95A1, 0x890A, 0xE5ED, 0x890C, 0xE5EC, 0x8910, 0x8A8C,
+	0x8912, 0x964A, 0x8913, 0xE5EE, 0x891C, 0xFA5D, 0x891D, 0xE5FA,
+	0x891E, 0xE5F0, 0x8925, 0xE5F1, 0x892A, 0xE5F2, 0x892B, 0xE5F3,
+	0x8936, 0xE5F7, 0x8938, 0xE5F8, 0x893B, 0xE5F6, 0x8941, 0xE5F4,
+	0x8943, 0xE5EF, 0x8944, 0xE5F5, 0x894C, 0xE5F9, 0x894D, 0xE8B5,
+	0x8956, 0x89A6, 0x895E, 0xE5FC, 0x895F, 0x8BDD, 0x8960, 0xE5FB,
+	0x8964, 0xE641, 0x8966, 0xE640, 0x896A, 0xE643, 0x896D, 0xE642,
+	0x896F, 0xE644, 0x8972, 0x8F50, 0x8974, 0xE645, 0x8977, 0xE646,
+	0x897E, 0xE647, 0x897F, 0x90BC, 0x8981, 0x9776, 0x8983, 0xE648,
+	0x8986, 0x95A2, 0x8987, 0x9465, 0x8988, 0xE649, 0x898A, 0xE64A,
+	0x898B, 0x8CA9, 0x898F, 0x8B4B, 0x8993, 0xE64B, 0x8996, 0x8E8B,
+	0x8997, 0x9460, 0x8998, 0xE64C, 0x899A, 0x8A6F, 0x89A1, 0xE64D,
+	0x89A6, 0xE64F, 0x89A7, 0x9797, 0x89A9, 0xE64E, 0x89AA, 0x9065,
+	0x89AC, 0xE650, 0x89AF, 0xE651, 0x89B2, 0xE652, 0x89B3, 0x8ACF,
+	0x89BA, 0xE653, 0x89BD, 0xE654, 0x89BF, 0xE655, 0x89C0, 0xE656,
+	0x89D2, 0x8A70, 0x89DA, 0xE657, 0x89DC, 0xE658, 0x89DD, 0xE659,
+	0x89E3, 0x89F0, 0x89E6, 0x9047, 0x89E7, 0xE65A, 0x89F4, 0xE65B,
+	0x89F8, 0xE65C, 0x8A00, 0x8CBE, 0x8A02, 0x92F9, 0x8A03, 0xE65D,
+	0x8A08, 0x8C76, 0x8A0A, 0x9075, 0x8A0C, 0xE660, 0x8A0E, 0x93A2,
+	0x8A10, 0xE65F, 0x8A12, 0xFBA3, 0x8A13, 0x8C50, 0x8A16, 0xE65E,
+	0x8A17, 0x91F5, 0x8A18, 0x8B4C, 0x8A1B, 0xE661, 0x8A1D, 0xE662,
+	0x8A1F, 0x8FD7, 0x8A23, 0x8C8D, 0x8A25, 0xE663, 0x8A2A, 0x964B,
+	0x8A2D, 0x90DD, 0x8A31, 0x8B96, 0x8A33, 0x96F3, 0x8A34, 0x9169,
+	0x8A36, 0xE664, 0x8A37, 0xFBA4, 0x8A3A, 0x9066, 0x8A3B, 0x9290,
+	0x8A3C, 0x8FD8, 0x8A41, 0xE665, 0x8A46, 0xE668, 0x8A48, 0xE669,
+	0x8A50, 0x8DBC, 0x8A51, 0x91C0, 0x8A52, 0xE667, 0x8A54, 0x8FD9,
+	0x8A55, 0x955D, 0x8A5B, 0xE666, 0x8A5E, 0x8E8C, 0x8A60, 0x8972,
+	0x8A62, 0xE66D, 0x8A63, 0x8C77, 0x8A66, 0x8E8E, 0x8A69, 0x8E8D,
+	0x8A6B, 0x986C, 0x8A6C, 0xE66C, 0x8A6D, 0xE66B, 0x8A6E, 0x9146,
+	0x8A70, 0x8B6C, 0x8A71, 0x9862, 0x8A72, 0x8A59, 0x8A73, 0x8FDA,
+	0x8A79, 0xFBA5, 0x8A7C, 0xE66A, 0x8A82, 0xE66F, 0x8A84, 0xE670,
+	0x8A85, 0xE66E, 0x8A87, 0x8CD6, 0x8A89, 0x975F, 0x8A8C, 0x8E8F,
+	0x8A8D, 0x9446, 0x8A91, 0xE673, 0x8A93, 0x90BE, 0x8A95, 0x9261,
+	0x8A98, 0x9755, 0x8A9A, 0xE676, 0x8A9E, 0x8CEA, 0x8AA0, 0x90BD,
+	0x8AA1, 0xE672, 0x8AA3, 0xE677, 0x8AA4, 0x8CEB, 0x8AA5, 0xE674,
+	0x8AA6, 0xE675, 0x8AA7, 0xFBA6, 0x8AA8, 0xE671, 0x8AAC, 0x90E0,
+	0x8AAD, 0x93C7, 0x8AB0, 0x924E, 0x8AB2, 0x89DB, 0x8AB9, 0x94EE,
+	0x8ABC, 0x8B62, 0x8ABE, 0xFBA7, 0x8ABF, 0x92B2, 0x8AC2, 0xE67A,
+	0x8AC4, 0xE678, 0x8AC7, 0x926B, 0x8ACB, 0x90BF, 0x8ACC, 0x8AD0,
+	0x8ACD, 0xE679, 0x8ACF, 0x907A, 0x8AD2, 0x97C8, 0x8AD6, 0x985F,
+	0x8ADA, 0xE67B, 0x8ADB, 0xE687, 0x8ADC, 0x92B3, 0x8ADE, 0xE686,
+	0x8ADF, 0xFBA8, 0x8AE0, 0xE683, 0x8AE1, 0xE68B, 0x8AE2, 0xE684,
+	0x8AE4, 0xE680, 0x8AE6, 0x92FA, 0x8AE7, 0xE67E, 0x8AEB, 0xE67C,
+	0x8AED, 0x9740, 0x8AEE, 0x8E90, 0x8AF1, 0xE681, 0x8AF3, 0xE67D,
+	0x8AF6, 0xFBAA, 0x8AF7, 0xE685, 0x8AF8, 0x8F94, 0x8AFA, 0x8CBF,
+	0x8AFE, 0x91F8, 0x8B00, 0x9664, 0x8B01, 0x8979, 0x8B02, 0x88E0,
+	0x8B04, 0x93A3, 0x8B07, 0xE689, 0x8B0C, 0xE688, 0x8B0E, 0x93E4,
+	0x8B10, 0xE68D, 0x8B14, 0xE682, 0x8B16, 0xE68C, 0x8B17, 0xE68E,
+	0x8B19, 0x8CAA, 0x8B1A, 0xE68A, 0x8B1B, 0x8D75, 0x8B1D, 0x8ED3,
+	0x8B20, 0xE68F, 0x8B21, 0x9777, 0x8B26, 0xE692, 0x8B28, 0xE695,
+	0x8B2B, 0xE693, 0x8B2C, 0x9554, 0x8B33, 0xE690, 0x8B39, 0x8BDE,
+	0x8B3E, 0xE694, 0x8B41, 0xE696, 0x8B49, 0xE69A, 0x8B4C, 0xE697,
+	0x8B4E, 0xE699, 0x8B4F, 0xE698, 0x8B53, 0xFBAB, 0x8B56, 0xE69B,
+	0x8B58, 0x8EAF, 0x8B5A, 0xE69D, 0x8B5B, 0xE69C, 0x8B5C, 0x9588,
+	0x8B5F, 0xE69F, 0x8B66, 0x8C78, 0x8B6B, 0xE69E, 0x8B6C, 0xE6A0,
+	0x8B6F, 0xE6A1, 0x8B70, 0x8B63, 0x8B71, 0xE3BF, 0x8B72, 0x8FF7,
+	0x8B74, 0xE6A2, 0x8B77, 0x8CEC, 0x8B7D, 0xE6A3, 0x8B7F, 0xFBAC,
+	0x8B80, 0xE6A4, 0x8B83, 0x8E5D, 0x8B8A, 0x9DCC, 0x8B8C, 0xE6A5,
+	0x8B8E, 0xE6A6, 0x8B90, 0x8F51, 0x8B92, 0xE6A7, 0x8B93, 0xE6A8,
+	0x8B96, 0xE6A9, 0x8B99, 0xE6AA, 0x8B9A, 0xE6AB, 0x8C37, 0x924A,
+	0x8C3A, 0xE6AC, 0x8C3F, 0xE6AE, 0x8C41, 0xE6AD, 0x8C46, 0x93A4,
+	0x8C48, 0xE6AF, 0x8C4A, 0x964C, 0x8C4C, 0xE6B0, 0x8C4E, 0xE6B1,
+	0x8C50, 0xE6B2, 0x8C55, 0xE6B3, 0x8C5A, 0x93D8, 0x8C61, 0x8FDB,
+	0x8C62, 0xE6B4, 0x8C6A, 0x8D8B, 0x8C6B, 0x98AC, 0x8C6C, 0xE6B5,
+	0x8C78, 0xE6B6, 0x8C79, 0x955E, 0x8C7A, 0xE6B7, 0x8C7C, 0xE6BF,
+	0x8C82, 0xE6B8, 0x8C85, 0xE6BA, 0x8C89, 0xE6B9, 0x8C8A, 0xE6BB,
+	0x8C8C, 0x9665, 0x8C8D, 0xE6BC, 0x8C8E, 0xE6BD, 0x8C94, 0xE6BE,
+	0x8C98, 0xE6C0, 0x8C9D, 0x8A4C, 0x8C9E, 0x92E5, 0x8CA0, 0x9589,
+	0x8CA1, 0x8DE0, 0x8CA2, 0x8D76, 0x8CA7, 0x956E, 0x8CA8, 0x89DD,
+	0x8CA9, 0x94CC, 0x8CAA, 0xE6C3, 0x8CAB, 0x8AD1, 0x8CAC, 0x90D3,
+	0x8CAD, 0xE6C2, 0x8CAE, 0xE6C7, 0x8CAF, 0x9299, 0x8CB0, 0x96E1,
+	0x8CB2, 0xE6C5, 0x8CB3, 0xE6C6, 0x8CB4, 0x8B4D, 0x8CB6, 0xE6C8,
+	0x8CB7, 0x9483, 0x8CB8, 0x91DD, 0x8CBB, 0x94EF, 0x8CBC, 0x935C,
+	0x8CBD, 0xE6C4, 0x8CBF, 0x9666, 0x8CC0, 0x89EA, 0x8CC1, 0xE6CA,
+	0x8CC2, 0x9847, 0x8CC3, 0x92C0, 0x8CC4, 0x9864, 0x8CC7, 0x8E91,
+	0x8CC8, 0xE6C9, 0x8CCA, 0x91AF, 0x8CCD, 0xE6DA, 0x8CCE, 0x9147,
+	0x8CD1, 0x93F6, 0x8CD3, 0x956F, 0x8CDA, 0xE6CD, 0x8CDB, 0x8E5E,
+	0x8CDC, 0x8E92, 0x8CDE, 0x8FDC, 0x8CE0, 0x9485, 0x8CE2, 0x8CAB,
+	0x8CE3, 0xE6CC, 0x8CE4, 0xE6CB, 0x8CE6, 0x958A, 0x8CEA, 0x8EBF,
+	0x8CED, 0x9371, 0x8CF0, 0xFBAD, 0x8CF4, 0xFBAE, 0x8CFA, 0xE6CF,
+	0x8CFB, 0xE6D0, 0x8CFC, 0x8D77, 0x8CFD, 0xE6CE, 0x8D04, 0xE6D1,
+	0x8D05, 0xE6D2, 0x8D07, 0xE6D4, 0x8D08, 0x91A1, 0x8D0A, 0xE6D3,
+	0x8D0B, 0x8AE4, 0x8D0D, 0xE6D6, 0x8D0F, 0xE6D5, 0x8D10, 0xE6D7,
+	0x8D12, 0xFBAF, 0x8D13, 0xE6D9, 0x8D14, 0xE6DB, 0x8D16, 0xE6DC,
+	0x8D64, 0x90D4, 0x8D66, 0x8ECD, 0x8D67, 0xE6DD, 0x8D6B, 0x8A71,
+	0x8D6D, 0xE6DE, 0x8D70, 0x9196, 0x8D71, 0xE6DF, 0x8D73, 0xE6E0,
+	0x8D74, 0x958B, 0x8D76, 0xFBB0, 0x8D77, 0x8B4E, 0x8D81, 0xE6E1,
+	0x8D85, 0x92B4, 0x8D8A, 0x897A, 0x8D99, 0xE6E2, 0x8DA3, 0x8EEF,
+	0x8DA8, 0x9096, 0x8DB3, 0x91AB, 0x8DBA, 0xE6E5, 0x8DBE, 0xE6E4,
+	0x8DC2, 0xE6E3, 0x8DCB, 0xE6EB, 0x8DCC, 0xE6E9, 0x8DCF, 0xE6E6,
+	0x8DD6, 0xE6E8, 0x8DDA, 0xE6E7, 0x8DDB, 0xE6EA, 0x8DDD, 0x8B97,
+	0x8DDF, 0xE6EE, 0x8DE1, 0x90D5, 0x8DE3, 0xE6EF, 0x8DE8, 0x8CD7,
+	0x8DEA, 0xE6EC, 0x8DEB, 0xE6ED, 0x8DEF, 0x9848, 0x8DF3, 0x92B5,
+	0x8DF5, 0x9148, 0x8DFC, 0xE6F0, 0x8DFF, 0xE6F3, 0x8E08, 0xE6F1,
+	0x8E09, 0xE6F2, 0x8E0A, 0x9778, 0x8E0F, 0x93A5, 0x8E10, 0xE6F6,
+	0x8E1D, 0xE6F4, 0x8E1E, 0xE6F5, 0x8E1F, 0xE6F7, 0x8E2A, 0xE748,
+	0x8E30, 0xE6FA, 0x8E34, 0xE6FB, 0x8E35, 0xE6F9, 0x8E42, 0xE6F8,
+	0x8E44, 0x92FB, 0x8E47, 0xE740, 0x8E48, 0xE744, 0x8E49, 0xE741,
+	0x8E4A, 0xE6FC, 0x8E4C, 0xE742, 0x8E50, 0xE743, 0x8E55, 0xE74A,
+	0x8E59, 0xE745, 0x8E5F, 0x90D6, 0x8E60, 0xE747, 0x8E63, 0xE749,
+	0x8E64, 0xE746, 0x8E72, 0xE74C, 0x8E74, 0x8F52, 0x8E76, 0xE74B,
+	0x8E7C, 0xE74D, 0x8E81, 0xE74E, 0x8E84, 0xE751, 0x8E85, 0xE750,
+	0x8E87, 0xE74F, 0x8E8A, 0xE753, 0x8E8B, 0xE752, 0x8E8D, 0x96F4,
+	0x8E91, 0xE755, 0x8E93, 0xE754, 0x8E94, 0xE756, 0x8E99, 0xE757,
+	0x8EA1, 0xE759, 0x8EAA, 0xE758, 0x8EAB, 0x9067, 0x8EAC, 0xE75A,
+	0x8EAF, 0x8BEB, 0x8EB0, 0xE75B, 0x8EB1, 0xE75D, 0x8EBE, 0xE75E,
+	0x8EC5, 0xE75F, 0x8EC6, 0xE75C, 0x8EC8, 0xE760, 0x8ECA, 0x8ED4,
+	0x8ECB, 0xE761, 0x8ECC, 0x8B4F, 0x8ECD, 0x8C52, 0x8ECF, 0xFBB2,
+	0x8ED2, 0x8CAC, 0x8EDB, 0xE762, 0x8EDF, 0x93EE, 0x8EE2, 0x935D,
+	0x8EE3, 0xE763, 0x8EEB, 0xE766, 0x8EF8, 0x8EB2, 0x8EFB, 0xE765,
+	0x8EFC, 0xE764, 0x8EFD, 0x8C79, 0x8EFE, 0xE767, 0x8F03, 0x8A72,
+	0x8F05, 0xE769, 0x8F09, 0x8DDA, 0x8F0A, 0xE768, 0x8F0C, 0xE771,
+	0x8F12, 0xE76B, 0x8F13, 0xE76D, 0x8F14, 0x95E3, 0x8F15, 0xE76A,
+	0x8F19, 0xE76C, 0x8F1B, 0xE770, 0x8F1C, 0xE76E, 0x8F1D, 0x8B50,
+	0x8F1F, 0xE76F, 0x8F26, 0xE772, 0x8F29, 0x9479, 0x8F2A, 0x97D6,
+	0x8F2F, 0x8F53, 0x8F33, 0xE773, 0x8F38, 0x9741, 0x8F39, 0xE775,
+	0x8F3B, 0xE774, 0x8F3E, 0xE778, 0x8F3F, 0x9760, 0x8F42, 0xE777,
+	0x8F44, 0x8A8D, 0x8F45, 0xE776, 0x8F46, 0xE77B, 0x8F49, 0xE77A,
+	0x8F4C, 0xE779, 0x8F4D, 0x9351, 0x8F4E, 0xE77C, 0x8F57, 0xE77D,
+	0x8F5C, 0xE77E, 0x8F5F, 0x8D8C, 0x8F61, 0x8C44, 0x8F62, 0xE780,
+	0x8F63, 0xE781, 0x8F64, 0xE782, 0x8F9B, 0x9068, 0x8F9C, 0xE783,
+	0x8F9E, 0x8EAB, 0x8F9F, 0xE784, 0x8FA3, 0xE785, 0x8FA7, 0x999F,
+	0x8FA8, 0x999E, 0x8FAD, 0xE786, 0x8FAE, 0xE390, 0x8FAF, 0xE787,
+	0x8FB0, 0x9243, 0x8FB1, 0x904A, 0x8FB2, 0x945F, 0x8FB7, 0xE788,
+	0x8FBA, 0x95D3, 0x8FBB, 0x92D2, 0x8FBC, 0x8D9E, 0x8FBF, 0x9248,
+	0x8FC2, 0x8949, 0x8FC4, 0x9698, 0x8FC5, 0x9076, 0x8FCE, 0x8C7D,
+	0x8FD1, 0x8BDF, 0x8FD4, 0x95D4, 0x8FDA, 0xE789, 0x8FE2, 0xE78B,
+	0x8FE5, 0xE78A, 0x8FE6, 0x89DE, 0x8FE9, 0x93F4, 0x8FEA, 0xE78C,
+	0x8FEB, 0x9497, 0x8FED, 0x9352, 0x8FEF, 0xE78D, 0x8FF0, 0x8F71,
+	0x8FF4, 0xE78F, 0x8FF7, 0x96C0, 0x8FF8, 0xE79E, 0x8FF9, 0xE791,
+	0x8FFA, 0xE792, 0x8FFD, 0x92C7, 0x9000, 0x91DE, 0x9001, 0x9197,
+	0x9003, 0x93A6, 0x9005, 0xE790, 0x9006, 0x8B74, 0x900B, 0xE799,
+	0x900D, 0xE796, 0x900E, 0xE7A3, 0x900F, 0x93A7, 0x9010, 0x9280,
+	0x9011, 0xE793, 0x9013, 0x92FC, 0x9014, 0x9372, 0x9015, 0xE794,
+	0x9016, 0xE798, 0x9017, 0x9080, 0x9019, 0x9487, 0x901A, 0x92CA,
+	0x901D, 0x90C0, 0x901E, 0xE797, 0x901F, 0x91AC, 0x9020, 0x91A2,
+	0x9021, 0xE795, 0x9022, 0x88A7, 0x9023, 0x9841, 0x9027, 0xE79A,
+	0x902E, 0x91DF, 0x9031, 0x8F54, 0x9032, 0x9069, 0x9035, 0xE79C,
+	0x9036, 0xE79B, 0x9038, 0x88ED, 0x9039, 0xE79D, 0x903C, 0x954E,
+	0x903E, 0xE7A5, 0x9041, 0x93D9, 0x9042, 0x908B, 0x9045, 0x9278,
+	0x9047, 0x8BF6, 0x9049, 0xE7A4, 0x904A, 0x9756, 0x904B, 0x895E,
+	0x904D, 0x95D5, 0x904E, 0x89DF, 0x904F, 0xE79F, 0x9050, 0xE7A0,
+	0x9051, 0xE7A1, 0x9052, 0xE7A2, 0x9053, 0x93B9, 0x9054, 0x9242,
+	0x9055, 0x88E1, 0x9056, 0xE7A6, 0x9058, 0xE7A7, 0x9059, 0xEAA1,
+	0x905C, 0x91BB, 0x905E, 0xE7A8, 0x9060, 0x8993, 0x9061, 0x916B,
+	0x9063, 0x8CAD, 0x9065, 0x9779, 0x9067, 0xFBB5, 0x9068, 0xE7A9,
+	0x9069, 0x934B, 0x906D, 0x9198, 0x906E, 0x8ED5, 0x906F, 0xE7AA,
+	0x9072, 0xE7AD, 0x9075, 0x8F85, 0x9076, 0xE7AB, 0x9077, 0x914A,
+	0x9078, 0x9149, 0x907A, 0x88E2, 0x907C, 0x97C9, 0x907D, 0xE7AF,
+	0x907F, 0x94F0, 0x9080, 0xE7B1, 0x9081, 0xE7B0, 0x9082, 0xE7AE,
+	0x9083, 0xE284, 0x9084, 0x8AD2, 0x9087, 0xE78E, 0x9089, 0xE7B3,
+	0x908A, 0xE7B2, 0x908F, 0xE7B4, 0x9091, 0x9757, 0x90A3, 0x93DF,
+	0x90A6, 0x964D, 0x90A8, 0xE7B5, 0x90AA, 0x8ED7, 0x90AF, 0xE7B6,
+	0x90B1, 0xE7B7, 0x90B5, 0xE7B8, 0x90B8, 0x9340, 0x90C1, 0x88E8,
+	0x90CA, 0x8D78, 0x90CE, 0x9859, 0x90DB, 0xE7BC, 0x90DE, 0xFBB6,
+	0x90E1, 0x8C53, 0x90E2, 0xE7B9, 0x90E4, 0xE7BA, 0x90E8, 0x9594,
+	0x90ED, 0x8A73, 0x90F5, 0x9758, 0x90F7, 0x8BBD, 0x90FD, 0x9373,
+	0x9102, 0xE7BD, 0x9112, 0xE7BE, 0x9115, 0xFBB8, 0x9119, 0xE7BF,
+	0x9127, 0xFBB9, 0x912D, 0x9341, 0x9130, 0xE7C1, 0x9132, 0xE7C0,
+	0x9149, 0x93D1, 0x914A, 0xE7C2, 0x914B, 0x8F55, 0x914C, 0x8EDE,
+	0x914D, 0x947A, 0x914E, 0x9291, 0x9152, 0x8EF0, 0x9154, 0x908C,
+	0x9156, 0xE7C3, 0x9158, 0xE7C4, 0x9162, 0x907C, 0x9163, 0xE7C5,
+	0x9165, 0xE7C6, 0x9169, 0xE7C7, 0x916A, 0x978F, 0x916C, 0x8F56,
+	0x9172, 0xE7C9, 0x9173, 0xE7C8, 0x9175, 0x8D79, 0x9177, 0x8D93,
+	0x9178, 0x8E5F, 0x9182, 0xE7CC, 0x9187, 0x8F86, 0x9189, 0xE7CB,
+	0x918B, 0xE7CA, 0x918D, 0x91E7, 0x9190, 0x8CED, 0x9192, 0x90C1,
+	0x9197, 0x94AE, 0x919C, 0x8F58, 0x91A2, 0xE7CD, 0x91A4, 0x8FDD,
+	0x91AA, 0xE7D0, 0x91AB, 0xE7CE, 0x91AF, 0xE7CF, 0x91B4, 0xE7D2,
+	0x91B5, 0xE7D1, 0x91B8, 0x8FF8, 0x91BA, 0xE7D3, 0x91C0, 0xE7D4,
+	0x91C1, 0xE7D5, 0x91C6, 0x94CE, 0x91C7, 0x8DD1, 0x91C8, 0x8EDF,
+	0x91C9, 0xE7D6, 0x91CB, 0xE7D7, 0x91CC, 0x97A2, 0x91CD, 0x8F64,
+	0x91CE, 0x96EC, 0x91CF, 0x97CA, 0x91D0, 0xE7D8, 0x91D1, 0x8BE0,
+	0x91D6, 0xE7D9, 0x91D7, 0xFBBB, 0x91D8, 0x9342, 0x91DA, 0xFBBA,
+	0x91DB, 0xE7DC, 0x91DC, 0x8A98, 0x91DD, 0x906A, 0x91DE, 0xFBBC,
+	0x91DF, 0xE7DA, 0x91E1, 0xE7DB, 0x91E3, 0x92DE, 0x91E4, 0xFBBF,
+	0x91E5, 0xFBC0, 0x91E6, 0x9674, 0x91E7, 0x8BFA, 0x91ED, 0xFBBD,
+	0x91EE, 0xFBBE, 0x91F5, 0xE7DE, 0x91F6, 0xE7DF, 0x91FC, 0xE7DD,
+	0x91FF, 0xE7E1, 0x9206, 0xFBC1, 0x920A, 0xFBC3, 0x920D, 0x93DD,
+	0x920E, 0x8A62, 0x9210, 0xFBC2, 0x9211, 0xE7E5, 0x9214, 0xE7E2,
+	0x9215, 0xE7E4, 0x921E, 0xE7E0, 0x9229, 0xE86E, 0x922C, 0xE7E3,
+	0x9234, 0x97E9, 0x9237, 0x8CD8, 0x9239, 0xFBCA, 0x923A, 0xFBC4,
+	0x923C, 0xFBC6, 0x923F, 0xE7ED, 0x9240, 0xFBC5, 0x9244, 0x9353,
+	0x9245, 0xE7E8, 0x9248, 0xE7EB, 0x9249, 0xE7E9, 0x924B, 0xE7EE,
+	0x924E, 0xFBC7, 0x9250, 0xE7EF, 0x9251, 0xFBC9, 0x9257, 0xE7E7,
+	0x9259, 0xFBC8, 0x925A, 0xE7F4, 0x925B, 0x8994, 0x925E, 0xE7E6,
+	0x9262, 0x94AB, 0x9264, 0xE7EA, 0x9266, 0x8FDE, 0x9267, 0xFBCB,
+	0x9271, 0x8D7A, 0x9277, 0xFBCD, 0x9278, 0xFBCE, 0x927E, 0x9667,
+	0x9280, 0x8BE2, 0x9283, 0x8F65, 0x9285, 0x93BA, 0x9288, 0xFA5F,
+	0x9291, 0x914C, 0x9293, 0xE7F2, 0x9295, 0xE7EC, 0x9296, 0xE7F1,
+	0x9298, 0x96C1, 0x929A, 0x92B6, 0x929B, 0xE7F3, 0x929C, 0xE7F0,
+	0x92A7, 0xFBCC, 0x92AD, 0x914B, 0x92B7, 0xE7F7, 0x92B9, 0xE7F6,
+	0x92CF, 0xE7F5, 0x92D0, 0xFBD2, 0x92D2, 0x964E, 0x92D3, 0xFBD6,
+	0x92D5, 0xFBD4, 0x92D7, 0xFBD0, 0x92D9, 0xFBD1, 0x92E0, 0xFBD5,
+	0x92E4, 0x8F9B, 0x92E7, 0xFBCF, 0x92E9, 0xE7F8, 0x92EA, 0x95DD,
+	0x92ED, 0x8973, 0x92F2, 0x9565, 0x92F3, 0x9292, 0x92F8, 0x8B98,
+	0x92F9, 0xFA65, 0x92FA, 0xE7FA, 0x92FB, 0xFBD9, 0x92FC, 0x8D7C,
+	0x92FF, 0xFBDC, 0x9302, 0xFBDE, 0x9306, 0x8E4B, 0x930F, 0xE7F9,
+	0x9310, 0x908D, 0x9318, 0x908E, 0x9319, 0xE840, 0x931A, 0xE842,
+	0x931D, 0xFBDD, 0x931E, 0xFBDB, 0x9320, 0x8FF9, 0x9321, 0xFBD8,
+	0x9322, 0xE841, 0x9323, 0xE843, 0x9325, 0xFBD7, 0x9326, 0x8BD1,
+	0x9328, 0x9564, 0x932B, 0x8EE0, 0x932C, 0x9842, 0x932E, 0xE7FC,
+	0x932F, 0x8DF6, 0x9332, 0x985E, 0x9335, 0xE845, 0x933A, 0xE844,
+	0x933B, 0xE846, 0x9344, 0xE7FB, 0x9348, 0xFA5E, 0x934B, 0x93E7,
+	0x934D, 0x9374, 0x9354, 0x92D5, 0x9356, 0xE84B, 0x9357, 0xFBE0,
+	0x935B, 0x9262, 0x935C, 0xE847, 0x9360, 0xE848, 0x936C, 0x8C4C,
+	0x936E, 0xE84A, 0x9370, 0xFBDF, 0x9375, 0x8CAE, 0x937C, 0xE849,
+	0x937E, 0x8FDF, 0x938C, 0x8A99, 0x9394, 0xE84F, 0x9396, 0x8DBD,
+	0x9397, 0x9199, 0x939A, 0x92C8, 0x93A4, 0xFBE1, 0x93A7, 0x8A5A,
+	0x93AC, 0xE84D, 0x93AD, 0xE84E, 0x93AE, 0x92C1, 0x93B0, 0xE84C,
+	0x93B9, 0xE850, 0x93C3, 0xE856, 0x93C6, 0xFBE2, 0x93C8, 0xE859,
+	0x93D0, 0xE858, 0x93D1, 0x934C, 0x93D6, 0xE851, 0x93D7, 0xE852,
+	0x93D8, 0xE855, 0x93DD, 0xE857, 0x93DE, 0xFBE3, 0x93E1, 0x8BBE,
+	0x93E4, 0xE85A, 0x93E5, 0xE854, 0x93E8, 0xE853, 0x93F8, 0xFBE4,
+	0x9403, 0xE85E, 0x9407, 0xE85F, 0x9410, 0xE860, 0x9413, 0xE85D,
+	0x9414, 0xE85C, 0x9418, 0x8FE0, 0x9419, 0x93A8, 0x941A, 0xE85B,
+	0x9421, 0xE864, 0x942B, 0xE862, 0x9431, 0xFBE5, 0x9435, 0xE863,
+	0x9436, 0xE861, 0x9438, 0x91F6, 0x943A, 0xE865, 0x9441, 0xE866,
+	0x9444, 0xE868, 0x9445, 0xFBE6, 0x9448, 0xFBE7, 0x9451, 0x8AD3,
+	0x9452, 0xE867, 0x9453, 0x96F8, 0x945A, 0xE873, 0x945B, 0xE869,
+	0x945E, 0xE86C, 0x9460, 0xE86A, 0x9462, 0xE86B, 0x946A, 0xE86D,
+	0x9470, 0xE86F, 0x9475, 0xE870, 0x9477, 0xE871, 0x947C, 0xE874,
+	0x947D, 0xE872, 0x947E, 0xE875, 0x947F, 0xE877, 0x9481, 0xE876,
+	0x9577, 0x92B7, 0x9580, 0x96E5, 0x9582, 0xE878, 0x9583, 0x914D,
+	0x9587, 0xE879, 0x9589, 0x95C2, 0x958A, 0xE87A, 0x958B, 0x8A4A,
+	0x958F, 0x895B, 0x9591, 0x8AD5, 0x9592, 0xFBE8, 0x9593, 0x8AD4,
+	0x9594, 0xE87B, 0x9596, 0xE87C, 0x9598, 0xE87D, 0x9599, 0xE87E,
+	0x95A0, 0xE880, 0x95A2, 0x8AD6, 0x95A3, 0x8A74, 0x95A4, 0x8D7D,
+	0x95A5, 0x94B4, 0x95A7, 0xE882, 0x95A8, 0xE881, 0x95AD, 0xE883,
+	0x95B2, 0x897B, 0x95B9, 0xE886, 0x95BB, 0xE885, 0x95BC, 0xE884,
+	0x95BE, 0xE887, 0x95C3, 0xE88A, 0x95C7, 0x88C5, 0x95CA, 0xE888,
+	0x95CC, 0xE88C, 0x95CD, 0xE88B, 0x95D4, 0xE88E, 0x95D5, 0xE88D,
+	0x95D6, 0xE88F, 0x95D8, 0x93AC, 0x95DC, 0xE890, 0x95E1, 0xE891,
+	0x95E2, 0xE893, 0x95E5, 0xE892, 0x961C, 0x958C, 0x9621, 0xE894,
+	0x9628, 0xE895, 0x962A, 0x8DE3, 0x962E, 0xE896, 0x962F, 0xE897,
+	0x9632, 0x9668, 0x963B, 0x916A, 0x963F, 0x88A2, 0x9640, 0x91C9,
+	0x9642, 0xE898, 0x9644, 0x958D, 0x964B, 0xE89B, 0x964C, 0xE899,
+	0x964D, 0x8D7E, 0x964F, 0xE89A, 0x9650, 0x8CC0, 0x965B, 0x95C3,
+	0x965C, 0xE89D, 0x965D, 0xE89F, 0x965E, 0xE89E, 0x965F, 0xE8A0,
+	0x9662, 0x8940, 0x9663, 0x9077, 0x9664, 0x8F9C, 0x9665, 0x8AD7,
+	0x9666, 0xE8A1, 0x966A, 0x9486, 0x966C, 0xE8A3, 0x9670, 0x8941,
+	0x9672, 0xE8A2, 0x9673, 0x92C2, 0x9675, 0x97CB, 0x9676, 0x93A9,
+	0x9677, 0xE89C, 0x9678, 0x97A4, 0x967A, 0x8CAF, 0x967D, 0x977A,
+	0x9685, 0x8BF7, 0x9686, 0x97B2, 0x9688, 0x8C47, 0x968A, 0x91E0,
+	0x968B, 0xE440, 0x968D, 0xE8A4, 0x968E, 0x8A4B, 0x968F, 0x908F,
+	0x9694, 0x8A75, 0x9695, 0xE8A6, 0x9697, 0xE8A7, 0x9698, 0xE8A5,
+	0x9699, 0x8C84, 0x969B, 0x8DDB, 0x969C, 0x8FE1, 0x969D, 0xFBEB,
+	0x96A0, 0x8942, 0x96A3, 0x97D7, 0x96A7, 0xE8A9, 0x96A8, 0xE7AC,
+	0x96AA, 0xE8A8, 0x96AF, 0xFBEC, 0x96B0, 0xE8AC, 0x96B1, 0xE8AA,
+	0x96B2, 0xE8AB, 0x96B4, 0xE8AD, 0x96B6, 0xE8AE, 0x96B7, 0x97EA,
+	0x96B8, 0xE8AF, 0x96B9, 0xE8B0, 0x96BB, 0x90C7, 0x96BC, 0x94B9,
+	0x96C0, 0x909D, 0x96C1, 0x8AE5, 0x96C4, 0x9759, 0x96C5, 0x89EB,
+	0x96C6, 0x8F57, 0x96C7, 0x8CD9, 0x96C9, 0xE8B3, 0x96CB, 0xE8B2,
+	0x96CC, 0x8E93, 0x96CD, 0xE8B4, 0x96CE, 0xE8B1, 0x96D1, 0x8E47,
+	0x96D5, 0xE8B8, 0x96D6, 0xE5AB, 0x96D9, 0x99D4, 0x96DB, 0x9097,
+	0x96DC, 0xE8B6, 0x96E2, 0x97A3, 0x96E3, 0x93EF, 0x96E8, 0x894A,
+	0x96EA, 0x90E1, 0x96EB, 0x8EB4, 0x96F0, 0x95B5, 0x96F2, 0x895F,
+	0x96F6, 0x97EB, 0x96F7, 0x978B, 0x96F9, 0xE8B9, 0x96FB, 0x9364,
+	0x9700, 0x8EF9, 0x9704, 0xE8BA, 0x9706, 0xE8BB, 0x9707, 0x906B,
+	0x9708, 0xE8BC, 0x970A, 0x97EC, 0x970D, 0xE8B7, 0x970E, 0xE8BE,
+	0x970F, 0xE8C0, 0x9711, 0xE8BF, 0x9713, 0xE8BD, 0x9716, 0xE8C1,
+	0x9719, 0xE8C2, 0x971C, 0x919A, 0x971E, 0x89E0, 0x9724, 0xE8C3,
+	0x9727, 0x96B6, 0x972A, 0xE8C4, 0x9730, 0xE8C5, 0x9732, 0x9849,
+	0x9733, 0xFBED, 0x9738, 0x9E50, 0x9739, 0xE8C6, 0x973B, 0xFBEE,
+	0x973D, 0xE8C7, 0x973E, 0xE8C8, 0x9742, 0xE8CC, 0x9743, 0xFBEF,
+	0x9744, 0xE8C9, 0x9746, 0xE8CA, 0x9748, 0xE8CB, 0x9749, 0xE8CD,
+	0x974D, 0xFBF0, 0x974F, 0xFBF1, 0x9751, 0xFBF2, 0x9752, 0x90C2,
+	0x9755, 0xFBF3, 0x9756, 0x96F5, 0x9759, 0x90C3, 0x975C, 0xE8CE,
+	0x975E, 0x94F1, 0x9760, 0xE8CF, 0x9761, 0xEA72, 0x9762, 0x96CA,
+	0x9764, 0xE8D0, 0x9766, 0xE8D1, 0x9768, 0xE8D2, 0x9769, 0x8A76,
+	0x976B, 0xE8D4, 0x976D, 0x9078, 0x9771, 0xE8D5, 0x9774, 0x8C43,
+	0x9779, 0xE8D6, 0x977A, 0xE8DA, 0x977C, 0xE8D8, 0x9781, 0xE8D9,
+	0x9784, 0x8A93, 0x9785, 0xE8D7, 0x9786, 0xE8DB, 0x978B, 0xE8DC,
+	0x978D, 0x88C6, 0x978F, 0xE8DD, 0x9790, 0xE8DE, 0x9798, 0x8FE2,
+	0x979C, 0xE8DF, 0x97A0, 0x8B66, 0x97A3, 0xE8E2, 0x97A6, 0xE8E1,
+	0x97A8, 0xE8E0, 0x97AB, 0xE691, 0x97AD, 0x95DA, 0x97B3, 0xE8E3,
+	0x97B4, 0xE8E4, 0x97C3, 0xE8E5, 0x97C6, 0xE8E6, 0x97C8, 0xE8E7,
+	0x97CB, 0xE8E8, 0x97D3, 0x8AD8, 0x97DC, 0xE8E9, 0x97ED, 0xE8EA,
+	0x97EE, 0x9442, 0x97F2, 0xE8EC, 0x97F3, 0x89B9, 0x97F5, 0xE8EF,
+	0x97F6, 0xE8EE, 0x97FB, 0x8943, 0x97FF, 0x8BBF, 0x9801, 0x95C5,
+	0x9802, 0x92B8, 0x9803, 0x8DA0, 0x9805, 0x8D80, 0x9806, 0x8F87,
+	0x9808, 0x907B, 0x980C, 0xE8F1, 0x980F, 0xE8F0, 0x9810, 0x9761,
+	0x9811, 0x8AE6, 0x9812, 0x94D0, 0x9813, 0x93DA, 0x9817, 0x909C,
+	0x9818, 0x97CC, 0x981A, 0x8C7A, 0x9821, 0xE8F4, 0x9824, 0xE8F3,
+	0x982C, 0x966A, 0x982D, 0x93AA, 0x9834, 0x896F, 0x9837, 0xE8F5,
+	0x9838, 0xE8F2, 0x983B, 0x9570, 0x983C, 0x978A, 0x983D, 0xE8F6,
+	0x9846, 0xE8F7, 0x984B, 0xE8F9, 0x984C, 0x91E8, 0x984D, 0x8A7A,
+	0x984E, 0x8A7B, 0x984F, 0xE8F8, 0x9854, 0x8AE7, 0x9855, 0x8CB0,
+	0x9857, 0xFBF4, 0x9858, 0x8AE8, 0x985B, 0x935E, 0x985E, 0x97DE,
+	0x9865, 0xFBF5, 0x9867, 0x8CDA, 0x986B, 0xE8FA, 0x986F, 0xE8FB,
+	0x9870, 0xE8FC, 0x9871, 0xE940, 0x9873, 0xE942, 0x9874, 0xE941,
+	0x98A8, 0x9597, 0x98AA, 0xE943, 0x98AF, 0xE944, 0x98B1, 0xE945,
+	0x98B6, 0xE946, 0x98C3, 0xE948, 0x98C4, 0xE947, 0x98C6, 0xE949,
+	0x98DB, 0x94F2, 0x98DC, 0xE3CA, 0x98DF, 0x9048, 0x98E2, 0x8B51,
+	0x98E9, 0xE94A, 0x98EB, 0xE94B, 0x98ED, 0x99AA, 0x98EE, 0x9F5A,
+	0x98EF, 0x94D1, 0x98F2, 0x88F9, 0x98F4, 0x88B9, 0x98FC, 0x8E94,
+	0x98FD, 0x964F, 0x98FE, 0x8FFC, 0x9903, 0xE94C, 0x9905, 0x96DD,
+	0x9909, 0xE94D, 0x990A, 0x977B, 0x990C, 0x8961, 0x9910, 0x8E60,
+	0x9912, 0xE94E, 0x9913, 0x89EC, 0x9914, 0xE94F, 0x9918, 0xE950,
+	0x991D, 0xE952, 0x991E, 0xE953, 0x9920, 0xE955, 0x9921, 0xE951,
+	0x9924, 0xE954, 0x9927, 0xFBF8, 0x9928, 0x8AD9, 0x992C, 0xE956,
+	0x992E, 0xE957, 0x993D, 0xE958, 0x993E, 0xE959, 0x9942, 0xE95A,
+	0x9945, 0xE95C, 0x9949, 0xE95B, 0x994B, 0xE95E, 0x994C, 0xE961,
+	0x9950, 0xE95D, 0x9951, 0xE95F, 0x9952, 0xE960, 0x9955, 0xE962,
+	0x9957, 0x8BC0, 0x9996, 0x8EF1, 0x9997, 0xE963, 0x9998, 0xE964,
+	0x9999, 0x8D81, 0x999E, 0xFBFA, 0x99A5, 0xE965, 0x99A8, 0x8A5D,
+	0x99AC, 0x946E, 0x99AD, 0xE966, 0x99AE, 0xE967, 0x99B3, 0x9279,
+	0x99B4, 0x93E9, 0x99BC, 0xE968, 0x99C1, 0x949D, 0x99C4, 0x91CA,
+	0x99C5, 0x8977, 0x99C6, 0x8BEC, 0x99C8, 0x8BED, 0x99D0, 0x9293,
+	0x99D1, 0xE96D, 0x99D2, 0x8BEE, 0x99D5, 0x89ED, 0x99D8, 0xE96C,
+	0x99DB, 0xE96A, 0x99DD, 0xE96B, 0x99DF, 0xE969, 0x99E2, 0xE977,
+	0x99ED, 0xE96E, 0x99EE, 0xE96F, 0x99F1, 0xE970, 0x99F2, 0xE971,
+	0x99F8, 0xE973, 0x99FB, 0xE972, 0x99FF, 0x8F78, 0x9A01, 0xE974,
+	0x9A05, 0xE976, 0x9A0E, 0x8B52, 0x9A0F, 0xE975, 0x9A12, 0x919B,
+	0x9A13, 0x8CB1, 0x9A19, 0xE978, 0x9A28, 0x91CB, 0x9A2B, 0xE979,
+	0x9A30, 0x93AB, 0x9A37, 0xE97A, 0x9A3E, 0xE980, 0x9A40, 0xE97D,
+	0x9A42, 0xE97C, 0x9A43, 0xE97E, 0x9A45, 0xE97B, 0x9A4D, 0xE982,
+	0x9A4E, 0xFBFB, 0x9A55, 0xE981, 0x9A57, 0xE984, 0x9A5A, 0x8BC1,
+	0x9A5B, 0xE983, 0x9A5F, 0xE985, 0x9A62, 0xE986, 0x9A64, 0xE988,
+	0x9A65, 0xE987, 0x9A69, 0xE989, 0x9A6A, 0xE98B, 0x9A6B, 0xE98A,
+	0x9AA8, 0x8D9C, 0x9AAD, 0xE98C, 0x9AB0, 0xE98D, 0x9AB8, 0x8A5B,
+	0x9ABC, 0xE98E, 0x9AC0, 0xE98F, 0x9AC4, 0x9091, 0x9ACF, 0xE990,
+	0x9AD1, 0xE991, 0x9AD3, 0xE992, 0x9AD4, 0xE993, 0x9AD8, 0x8D82,
+	0x9AD9, 0xFBFC, 0x9ADC, 0xFC40, 0x9ADE, 0xE994, 0x9ADF, 0xE995,
+	0x9AE2, 0xE996, 0x9AE3, 0xE997, 0x9AE6, 0xE998, 0x9AEA, 0x94AF,
+	0x9AEB, 0xE99A, 0x9AED, 0x9545, 0x9AEE, 0xE99B, 0x9AEF, 0xE999,
+	0x9AF1, 0xE99D, 0x9AF4, 0xE99C, 0x9AF7, 0xE99E, 0x9AFB, 0xE99F,
+	0x9B06, 0xE9A0, 0x9B18, 0xE9A1, 0x9B1A, 0xE9A2, 0x9B1F, 0xE9A3,
+	0x9B22, 0xE9A4, 0x9B23, 0xE9A5, 0x9B25, 0xE9A6, 0x9B27, 0xE9A7,
+	0x9B28, 0xE9A8, 0x9B29, 0xE9A9, 0x9B2A, 0xE9AA, 0x9B2E, 0xE9AB,
+	0x9B2F, 0xE9AC, 0x9B31, 0x9F54, 0x9B32, 0xE9AD, 0x9B3B, 0xE2F6,
+	0x9B3C, 0x8B53, 0x9B41, 0x8A40, 0x9B42, 0x8DB0, 0x9B43, 0xE9AF,
+	0x9B44, 0xE9AE, 0x9B45, 0x96A3, 0x9B4D, 0xE9B1, 0x9B4E, 0xE9B2,
+	0x9B4F, 0xE9B0, 0x9B51, 0xE9B3, 0x9B54, 0x9682, 0x9B58, 0xE9B4,
+	0x9B5A, 0x8B9B, 0x9B6F, 0x9844, 0x9B72, 0xFC42, 0x9B74, 0xE9B5,
+	0x9B75, 0xFC41, 0x9B83, 0xE9B7, 0x9B8E, 0x88BC, 0x9B8F, 0xFC43,
+	0x9B91, 0xE9B8, 0x9B92, 0x95A9, 0x9B93, 0xE9B6, 0x9B96, 0xE9B9,
+	0x9B97, 0xE9BA, 0x9B9F, 0xE9BB, 0x9BA0, 0xE9BC, 0x9BA8, 0xE9BD,
+	0x9BAA, 0x968E, 0x9BAB, 0x8E4C, 0x9BAD, 0x8DF8, 0x9BAE, 0x914E,
+	0x9BB1, 0xFC44, 0x9BB4, 0xE9BE, 0x9BB9, 0xE9C1, 0x9BBB, 0xFC45,
+	0x9BC0, 0xE9BF, 0x9BC6, 0xE9C2, 0x9BC9, 0x8CEF, 0x9BCA, 0xE9C0,
+	0x9BCF, 0xE9C3, 0x9BD1, 0xE9C4, 0x9BD2, 0xE9C5, 0x9BD4, 0xE9C9,
+	0x9BD6, 0x8E49, 0x9BDB, 0x91E2, 0x9BE1, 0xE9CA, 0x9BE2, 0xE9C7,
+	0x9BE3, 0xE9C6, 0x9BE4, 0xE9C8, 0x9BE8, 0x8C7E, 0x9BF0, 0xE9CE,
+	0x9BF1, 0xE9CD, 0x9BF2, 0xE9CC, 0x9BF5, 0x88B1, 0x9C00, 0xFC46,
+	0x9C04, 0xE9D8, 0x9C06, 0xE9D4, 0x9C08, 0xE9D5, 0x9C09, 0xE9D1,
+	0x9C0A, 0xE9D7, 0x9C0C, 0xE9D3, 0x9C0D, 0x8A82, 0x9C10, 0x986B,
+	0x9C12, 0xE9D6, 0x9C13, 0xE9D2, 0x9C14, 0xE9D0, 0x9C15, 0xE9CF,
+	0x9C1B, 0xE9DA, 0x9C21, 0xE9DD, 0x9C24, 0xE9DC, 0x9C25, 0xE9DB,
+	0x9C2D, 0x9568, 0x9C2E, 0xE9D9, 0x9C2F, 0x88F1, 0x9C30, 0xE9DE,
+	0x9C32, 0xE9E0, 0x9C39, 0x8A8F, 0x9C3A, 0xE9CB, 0x9C3B, 0x8956,
+	0x9C3E, 0xE9E2, 0x9C46, 0xE9E1, 0x9C47, 0xE9DF, 0x9C48, 0x924C,
+	0x9C52, 0x9690, 0x9C57, 0x97D8, 0x9C5A, 0xE9E3, 0x9C60, 0xE9E4,
+	0x9C67, 0xE9E5, 0x9C76, 0xE9E6, 0x9C78, 0xE9E7, 0x9CE5, 0x92B9,
+	0x9CE7, 0xE9E8, 0x9CE9, 0x94B5, 0x9CEB, 0xE9ED, 0x9CEC, 0xE9E9,
+	0x9CF0, 0xE9EA, 0x9CF3, 0x9650, 0x9CF4, 0x96C2, 0x9CF6, 0x93CE,
+	0x9D03, 0xE9EE, 0x9D06, 0xE9EF, 0x9D07, 0x93BC, 0x9D08, 0xE9EC,
+	0x9D09, 0xE9EB, 0x9D0E, 0x89A8, 0x9D12, 0xE9F7, 0x9D15, 0xE9F6,
+	0x9D1B, 0x8995, 0x9D1F, 0xE9F4, 0x9D23, 0xE9F3, 0x9D26, 0xE9F1,
+	0x9D28, 0x8A9B, 0x9D2A, 0xE9F0, 0x9D2B, 0x8EB0, 0x9D2C, 0x89A7,
+	0x9D3B, 0x8D83, 0x9D3E, 0xE9FA, 0x9D3F, 0xE9F9, 0x9D41, 0xE9F8,
+	0x9D44, 0xE9F5, 0x9D46, 0xE9FB, 0x9D48, 0xE9FC, 0x9D50, 0xEA44,
+	0x9D51, 0xEA43, 0x9D59, 0xEA45, 0x9D5C, 0x894C, 0x9D5D, 0xEA40,
+	0x9D5E, 0xEA41, 0x9D60, 0x8D94, 0x9D61, 0x96B7, 0x9D64, 0xEA42,
+	0x9D6B, 0xFC48, 0x9D6C, 0x9651, 0x9D6F, 0xEA4A, 0x9D70, 0xFC47,
+	0x9D72, 0xEA46, 0x9D7A, 0xEA4B, 0x9D87, 0xEA48, 0x9D89, 0xEA47,
+	0x9D8F, 0x8C7B, 0x9D9A, 0xEA4C, 0x9DA4, 0xEA4D, 0x9DA9, 0xEA4E,
+	0x9DAB, 0xEA49, 0x9DAF, 0xE9F2, 0x9DB2, 0xEA4F, 0x9DB4, 0x92DF,
+	0x9DB8, 0xEA53, 0x9DBA, 0xEA54, 0x9DBB, 0xEA52, 0x9DC1, 0xEA51,
+	0x9DC2, 0xEA57, 0x9DC4, 0xEA50, 0x9DC6, 0xEA55, 0x9DCF, 0xEA56,
+	0x9DD3, 0xEA59, 0x9DD9, 0xEA58, 0x9DE6, 0xEA5B, 0x9DED, 0xEA5C,
+	0x9DEF, 0xEA5D, 0x9DF2, 0x9868, 0x9DF8, 0xEA5A, 0x9DF9, 0x91E9,
+	0x9DFA, 0x8DEB, 0x9DFD, 0xEA5E, 0x9E19, 0xFC4A, 0x9E1A, 0xEA5F,
+	0x9E1B, 0xEA60, 0x9E1E, 0xEA61, 0x9E75, 0xEA62, 0x9E78, 0x8CB2,
+	0x9E79, 0xEA63, 0x9E7D, 0xEA64, 0x9E7F, 0x8EAD, 0x9E81, 0xEA65,
+	0x9E88, 0xEA66, 0x9E8B, 0xEA67, 0x9E8C, 0xEA68, 0x9E91, 0xEA6B,
+	0x9E92, 0xEA69, 0x9E93, 0x985B, 0x9E95, 0xEA6A, 0x9E97, 0x97ED,
+	0x9E9D, 0xEA6C, 0x9E9F, 0x97D9, 0x9EA5, 0xEA6D, 0x9EA6, 0x949E,
+	0x9EA9, 0xEA6E, 0x9EAA, 0xEA70, 0x9EAD, 0xEA71, 0x9EB8, 0xEA6F,
+	0x9EB9, 0x8D8D, 0x9EBA, 0x96CB, 0x9EBB, 0x9683, 0x9EBC, 0x9BF5,
+	0x9EBE, 0x9F80, 0x9EBF, 0x969B, 0x9EC4, 0x89A9, 0x9ECC, 0xEA73,
+	0x9ECD, 0x8B6F, 0x9ECE, 0xEA74, 0x9ECF, 0xEA75, 0x9ED0, 0xEA76,
+	0x9ED1, 0xFC4B, 0x9ED2, 0x8D95, 0x9ED4, 0xEA77, 0x9ED8, 0xE0D2,
+	0x9ED9, 0x96D9, 0x9EDB, 0x91E1, 0x9EDC, 0xEA78, 0x9EDD, 0xEA7A,
+	0x9EDE, 0xEA79, 0x9EE0, 0xEA7B, 0x9EE5, 0xEA7C, 0x9EE8, 0xEA7D,
+	0x9EEF, 0xEA7E, 0x9EF4, 0xEA80, 0x9EF6, 0xEA81, 0x9EF7, 0xEA82,
+	0x9EF9, 0xEA83, 0x9EFB, 0xEA84, 0x9EFC, 0xEA85, 0x9EFD, 0xEA86,
+	0x9F07, 0xEA87, 0x9F08, 0xEA88, 0x9F0E, 0x9343, 0x9F13, 0x8CDB,
+	0x9F15, 0xEA8A, 0x9F20, 0x916C, 0x9F21, 0xEA8B, 0x9F2C, 0xEA8C,
+	0x9F3B, 0x9540, 0x9F3E, 0xEA8D, 0x9F4A, 0xEA8E, 0x9F4B, 0xE256,
+	0x9F4E, 0xE6D8, 0x9F4F, 0xE8EB, 0x9F52, 0xEA8F, 0x9F54, 0xEA90,
+	0x9F5F, 0xEA92, 0x9F60, 0xEA93, 0x9F61, 0xEA94, 0x9F62, 0x97EE,
+	0x9F63, 0xEA91, 0x9F66, 0xEA95, 0x9F67, 0xEA96, 0x9F6A, 0xEA98,
+	0x9F6C, 0xEA97, 0x9F72, 0xEA9A, 0x9F76, 0xEA9B, 0x9F77, 0xEA99,
+	0x9F8D, 0x97B4, 0x9F95, 0xEA9C, 0x9F9C, 0xEA9D, 0x9F9D, 0xE273,
+	0x9FA0, 0xEA9E, 0xF929, 0xFAE0, 0xF9DC, 0xFBE9, 0xFA0E, 0xFA90,
+	0xFA0F, 0xFA9B, 0xFA10, 0xFA9C, 0xFA11, 0xFAB1, 0xFA12, 0xFAD8,
+	0xFA13, 0xFAE8, 0xFA14, 0xFAEA, 0xFA15, 0xFB58, 0xFA16, 0xFB5E,
+	0xFA17, 0xFB75, 0xFA18, 0xFB7D, 0xFA19, 0xFB7E, 0xFA1A, 0xFB80,
+	0xFA1B, 0xFB82, 0xFA1C, 0xFB86, 0xFA1D, 0xFB89, 0xFA1E, 0xFB92,
+	0xFA1F, 0xFB9D, 0xFA20, 0xFB9F, 0xFA21, 0xFBA0, 0xFA22, 0xFBA9,
+	0xFA23, 0xFBB1, 0xFA24, 0xFBB3, 0xFA25, 0xFBB4, 0xFA26, 0xFBB7,
+	0xFA27, 0xFBD3, 0xFA28, 0xFBDA, 0xFA29, 0xFBEA, 0xFA2A, 0xFBF6,
+	0xFA2B, 0xFBF7, 0xFA2C, 0xFBF9, 0xFA2D, 0xFC49, 0xFF01, 0x8149,
+	0xFF02, 0xFA57, 0xFF03, 0x8194, 0xFF04, 0x8190, 0xFF05, 0x8193,
+	0xFF06, 0x8195, 0xFF07, 0xFA56, 0xFF08, 0x8169, 0xFF09, 0x816A,
+	0xFF0A, 0x8196, 0xFF0B, 0x817B, 0xFF0C, 0x8143, 0xFF0D, 0x817C,
+	0xFF0E, 0x8144, 0xFF0F, 0x815E, 0xFF10, 0x824F, 0xFF11, 0x8250,
+	0xFF12, 0x8251, 0xFF13, 0x8252, 0xFF14, 0x8253, 0xFF15, 0x8254,
+	0xFF16, 0x8255, 0xFF17, 0x8256, 0xFF18, 0x8257, 0xFF19, 0x8258,
+	0xFF1A, 0x8146, 0xFF1B, 0x8147, 0xFF1C, 0x8183, 0xFF1D, 0x8181,
+	0xFF1E, 0x8184, 0xFF1F, 0x8148, 0xFF20, 0x8197, 0xFF21, 0x8260,
+	0xFF22, 0x8261, 0xFF23, 0x8262, 0xFF24, 0x8263, 0xFF25, 0x8264,
+	0xFF26, 0x8265, 0xFF27, 0x8266, 0xFF28, 0x8267, 0xFF29, 0x8268,
+	0xFF2A, 0x8269, 0xFF2B, 0x826A, 0xFF2C, 0x826B, 0xFF2D, 0x826C,
+	0xFF2E, 0x826D, 0xFF2F, 0x826E, 0xFF30, 0x826F, 0xFF31, 0x8270,
+	0xFF32, 0x8271, 0xFF33, 0x8272, 0xFF34, 0x8273, 0xFF35, 0x8274,
+	0xFF36, 0x8275, 0xFF37, 0x8276, 0xFF38, 0x8277, 0xFF39, 0x8278,
+	0xFF3A, 0x8279, 0xFF3B, 0x816D, 0xFF3C, 0x815F, 0xFF3D, 0x816E,
+	0xFF3E, 0x814F, 0xFF3F, 0x8151, 0xFF40, 0x814D, 0xFF41, 0x8281,
+	0xFF42, 0x8282, 0xFF43, 0x8283, 0xFF44, 0x8284, 0xFF45, 0x8285,
+	0xFF46, 0x8286, 0xFF47, 0x8287, 0xFF48, 0x8288, 0xFF49, 0x8289,
+	0xFF4A, 0x828A, 0xFF4B, 0x828B, 0xFF4C, 0x828C, 0xFF4D, 0x828D,
+	0xFF4E, 0x828E, 0xFF4F, 0x828F, 0xFF50, 0x8290, 0xFF51, 0x8291,
+	0xFF52, 0x8292, 0xFF53, 0x8293, 0xFF54, 0x8294, 0xFF55, 0x8295,
+	0xFF56, 0x8296, 0xFF57, 0x8297, 0xFF58, 0x8298, 0xFF59, 0x8299,
+	0xFF5A, 0x829A, 0xFF5B, 0x816F, 0xFF5C, 0x8162, 0xFF5D, 0x8170,
+	0xFF5E, 0x8160, 0xFF61, 0x00A1, 0xFF62, 0x00A2, 0xFF63, 0x00A3,
+	0xFF64, 0x00A4, 0xFF65, 0x00A5, 0xFF66, 0x00A6, 0xFF67, 0x00A7,
+	0xFF68, 0x00A8, 0xFF69, 0x00A9, 0xFF6A, 0x00AA, 0xFF6B, 0x00AB,
+	0xFF6C, 0x00AC, 0xFF6D, 0x00AD, 0xFF6E, 0x00AE, 0xFF6F, 0x00AF,
+	0xFF70, 0x00B0, 0xFF71, 0x00B1, 0xFF72, 0x00B2, 0xFF73, 0x00B3,
+	0xFF74, 0x00B4, 0xFF75, 0x00B5, 0xFF76, 0x00B6, 0xFF77, 0x00B7,
+	0xFF78, 0x00B8, 0xFF79, 0x00B9, 0xFF7A, 0x00BA, 0xFF7B, 0x00BB,
+	0xFF7C, 0x00BC, 0xFF7D, 0x00BD, 0xFF7E, 0x00BE, 0xFF7F, 0x00BF,
+	0xFF80, 0x00C0, 0xFF81, 0x00C1, 0xFF82, 0x00C2, 0xFF83, 0x00C3,
+	0xFF84, 0x00C4, 0xFF85, 0x00C5, 0xFF86, 0x00C6, 0xFF87, 0x00C7,
+	0xFF88, 0x00C8, 0xFF89, 0x00C9, 0xFF8A, 0x00CA, 0xFF8B, 0x00CB,
+	0xFF8C, 0x00CC, 0xFF8D, 0x00CD, 0xFF8E, 0x00CE, 0xFF8F, 0x00CF,
+	0xFF90, 0x00D0, 0xFF91, 0x00D1, 0xFF92, 0x00D2, 0xFF93, 0x00D3,
+	0xFF94, 0x00D4, 0xFF95, 0x00D5, 0xFF96, 0x00D6, 0xFF97, 0x00D7,
+	0xFF98, 0x00D8, 0xFF99, 0x00D9, 0xFF9A, 0x00DA, 0xFF9B, 0x00DB,
+	0xFF9C, 0x00DC, 0xFF9D, 0x00DD, 0xFF9E, 0x00DE, 0xFF9F, 0x00DF,
+	0xFFE0, 0x8191, 0xFFE1, 0x8192, 0xFFE2, 0x81CA, 0xFFE3, 0x8150,
+	0xFFE4, 0xFA55, 0xFFE5, 0x818F, 0, 0
+};
+
+#if !_TINY_TABLE
+static
+const WCHAR sjis2uni[] = {
+/*	SJIS - Unicode, SJIS - Unicode, SJIS - Unicode, SJIS - Unicode, */
+	0x00A1, 0xFF61, 0x00A2, 0xFF62, 0x00A3, 0xFF63, 0x00A4, 0xFF64,
+	0x00A5, 0xFF65, 0x00A6, 0xFF66, 0x00A7, 0xFF67, 0x00A8, 0xFF68,
+	0x00A9, 0xFF69, 0x00AA, 0xFF6A, 0x00AB, 0xFF6B, 0x00AC, 0xFF6C,
+	0x00AD, 0xFF6D, 0x00AE, 0xFF6E, 0x00AF, 0xFF6F, 0x00B0, 0xFF70,
+	0x00B1, 0xFF71, 0x00B2, 0xFF72, 0x00B3, 0xFF73, 0x00B4, 0xFF74,
+	0x00B5, 0xFF75, 0x00B6, 0xFF76, 0x00B7, 0xFF77, 0x00B8, 0xFF78,
+	0x00B9, 0xFF79, 0x00BA, 0xFF7A, 0x00BB, 0xFF7B, 0x00BC, 0xFF7C,
+	0x00BD, 0xFF7D, 0x00BE, 0xFF7E, 0x00BF, 0xFF7F, 0x00C0, 0xFF80,
+	0x00C1, 0xFF81, 0x00C2, 0xFF82, 0x00C3, 0xFF83, 0x00C4, 0xFF84,
+	0x00C5, 0xFF85, 0x00C6, 0xFF86, 0x00C7, 0xFF87, 0x00C8, 0xFF88,
+	0x00C9, 0xFF89, 0x00CA, 0xFF8A, 0x00CB, 0xFF8B, 0x00CC, 0xFF8C,
+	0x00CD, 0xFF8D, 0x00CE, 0xFF8E, 0x00CF, 0xFF8F, 0x00D0, 0xFF90,
+	0x00D1, 0xFF91, 0x00D2, 0xFF92, 0x00D3, 0xFF93, 0x00D4, 0xFF94,
+	0x00D5, 0xFF95, 0x00D6, 0xFF96, 0x00D7, 0xFF97, 0x00D8, 0xFF98,
+	0x00D9, 0xFF99, 0x00DA, 0xFF9A, 0x00DB, 0xFF9B, 0x00DC, 0xFF9C,
+	0x00DD, 0xFF9D, 0x00DE, 0xFF9E, 0x00DF, 0xFF9F, 0x8140, 0x3000,
+	0x8141, 0x3001, 0x8142, 0x3002, 0x8143, 0xFF0C, 0x8144, 0xFF0E,
+	0x8145, 0x30FB, 0x8146, 0xFF1A, 0x8147, 0xFF1B, 0x8148, 0xFF1F,
+	0x8149, 0xFF01, 0x814A, 0x309B, 0x814B, 0x309C, 0x814C, 0x00B4,
+	0x814D, 0xFF40, 0x814E, 0x00A8, 0x814F, 0xFF3E, 0x8150, 0xFFE3,
+	0x8151, 0xFF3F, 0x8152, 0x30FD, 0x8153, 0x30FE, 0x8154, 0x309D,
+	0x8155, 0x309E, 0x8156, 0x3003, 0x8157, 0x4EDD, 0x8158, 0x3005,
+	0x8159, 0x3006, 0x815A, 0x3007, 0x815B, 0x30FC, 0x815C, 0x2015,
+	0x815D, 0x2010, 0x815E, 0xFF0F, 0x815F, 0xFF3C, 0x8160, 0xFF5E,
+	0x8161, 0x2225, 0x8162, 0xFF5C, 0x8163, 0x2026, 0x8164, 0x2025,
+	0x8165, 0x2018, 0x8166, 0x2019, 0x8167, 0x201C, 0x8168, 0x201D,
+	0x8169, 0xFF08, 0x816A, 0xFF09, 0x816B, 0x3014, 0x816C, 0x3015,
+	0x816D, 0xFF3B, 0x816E, 0xFF3D, 0x816F, 0xFF5B, 0x8170, 0xFF5D,
+	0x8171, 0x3008, 0x8172, 0x3009, 0x8173, 0x300A, 0x8174, 0x300B,
+	0x8175, 0x300C, 0x8176, 0x300D, 0x8177, 0x300E, 0x8178, 0x300F,
+	0x8179, 0x3010, 0x817A, 0x3011, 0x817B, 0xFF0B, 0x817C, 0xFF0D,
+	0x817D, 0x00B1, 0x817E, 0x00D7, 0x8180, 0x00F7, 0x8181, 0xFF1D,
+	0x8182, 0x2260, 0x8183, 0xFF1C, 0x8184, 0xFF1E, 0x8185, 0x2266,
+	0x8186, 0x2267, 0x8187, 0x221E, 0x8188, 0x2234, 0x8189, 0x2642,
+	0x818A, 0x2640, 0x818B, 0x00B0, 0x818C, 0x2032, 0x818D, 0x2033,
+	0x818E, 0x2103, 0x818F, 0xFFE5, 0x8190, 0xFF04, 0x8191, 0xFFE0,
+	0x8192, 0xFFE1, 0x8193, 0xFF05, 0x8194, 0xFF03, 0x8195, 0xFF06,
+	0x8196, 0xFF0A, 0x8197, 0xFF20, 0x8198, 0x00A7, 0x8199, 0x2606,
+	0x819A, 0x2605, 0x819B, 0x25CB, 0x819C, 0x25CF, 0x819D, 0x25CE,
+	0x819E, 0x25C7, 0x819F, 0x25C6, 0x81A0, 0x25A1, 0x81A1, 0x25A0,
+	0x81A2, 0x25B3, 0x81A3, 0x25B2, 0x81A4, 0x25BD, 0x81A5, 0x25BC,
+	0x81A6, 0x203B, 0x81A7, 0x3012, 0x81A8, 0x2192, 0x81A9, 0x2190,
+	0x81AA, 0x2191, 0x81AB, 0x2193, 0x81AC, 0x3013, 0x81B8, 0x2208,
+	0x81B9, 0x220B, 0x81BA, 0x2286, 0x81BB, 0x2287, 0x81BC, 0x2282,
+	0x81BD, 0x2283, 0x81BE, 0x222A, 0x81BF, 0x2229, 0x81C8, 0x2227,
+	0x81C9, 0x2228, 0x81CA, 0xFFE2, 0x81CB, 0x21D2, 0x81CC, 0x21D4,
+	0x81CD, 0x2200, 0x81CE, 0x2203, 0x81DA, 0x2220, 0x81DB, 0x22A5,
+	0x81DC, 0x2312, 0x81DD, 0x2202, 0x81DE, 0x2207, 0x81DF, 0x2261,
+	0x81E0, 0x2252, 0x81E1, 0x226A, 0x81E2, 0x226B, 0x81E3, 0x221A,
+	0x81E4, 0x223D, 0x81E5, 0x221D, 0x81E6, 0x2235, 0x81E7, 0x222B,
+	0x81E8, 0x222C, 0x81F0, 0x212B, 0x81F1, 0x2030, 0x81F2, 0x266F,
+	0x81F3, 0x266D, 0x81F4, 0x266A, 0x81F5, 0x2020, 0x81F6, 0x2021,
+	0x81F7, 0x00B6, 0x81FC, 0x25EF, 0x824F, 0xFF10, 0x8250, 0xFF11,
+	0x8251, 0xFF12, 0x8252, 0xFF13, 0x8253, 0xFF14, 0x8254, 0xFF15,
+	0x8255, 0xFF16, 0x8256, 0xFF17, 0x8257, 0xFF18, 0x8258, 0xFF19,
+	0x8260, 0xFF21, 0x8261, 0xFF22, 0x8262, 0xFF23, 0x8263, 0xFF24,
+	0x8264, 0xFF25, 0x8265, 0xFF26, 0x8266, 0xFF27, 0x8267, 0xFF28,
+	0x8268, 0xFF29, 0x8269, 0xFF2A, 0x826A, 0xFF2B, 0x826B, 0xFF2C,
+	0x826C, 0xFF2D, 0x826D, 0xFF2E, 0x826E, 0xFF2F, 0x826F, 0xFF30,
+	0x8270, 0xFF31, 0x8271, 0xFF32, 0x8272, 0xFF33, 0x8273, 0xFF34,
+	0x8274, 0xFF35, 0x8275, 0xFF36, 0x8276, 0xFF37, 0x8277, 0xFF38,
+	0x8278, 0xFF39, 0x8279, 0xFF3A, 0x8281, 0xFF41, 0x8282, 0xFF42,
+	0x8283, 0xFF43, 0x8284, 0xFF44, 0x8285, 0xFF45, 0x8286, 0xFF46,
+	0x8287, 0xFF47, 0x8288, 0xFF48, 0x8289, 0xFF49, 0x828A, 0xFF4A,
+	0x828B, 0xFF4B, 0x828C, 0xFF4C, 0x828D, 0xFF4D, 0x828E, 0xFF4E,
+	0x828F, 0xFF4F, 0x8290, 0xFF50, 0x8291, 0xFF51, 0x8292, 0xFF52,
+	0x8293, 0xFF53, 0x8294, 0xFF54, 0x8295, 0xFF55, 0x8296, 0xFF56,
+	0x8297, 0xFF57, 0x8298, 0xFF58, 0x8299, 0xFF59, 0x829A, 0xFF5A,
+	0x829F, 0x3041, 0x82A0, 0x3042, 0x82A1, 0x3043, 0x82A2, 0x3044,
+	0x82A3, 0x3045, 0x82A4, 0x3046, 0x82A5, 0x3047, 0x82A6, 0x3048,
+	0x82A7, 0x3049, 0x82A8, 0x304A, 0x82A9, 0x304B, 0x82AA, 0x304C,
+	0x82AB, 0x304D, 0x82AC, 0x304E, 0x82AD, 0x304F, 0x82AE, 0x3050,
+	0x82AF, 0x3051, 0x82B0, 0x3052, 0x82B1, 0x3053, 0x82B2, 0x3054,
+	0x82B3, 0x3055, 0x82B4, 0x3056, 0x82B5, 0x3057, 0x82B6, 0x3058,
+	0x82B7, 0x3059, 0x82B8, 0x305A, 0x82B9, 0x305B, 0x82BA, 0x305C,
+	0x82BB, 0x305D, 0x82BC, 0x305E, 0x82BD, 0x305F, 0x82BE, 0x3060,
+	0x82BF, 0x3061, 0x82C0, 0x3062, 0x82C1, 0x3063, 0x82C2, 0x3064,
+	0x82C3, 0x3065, 0x82C4, 0x3066, 0x82C5, 0x3067, 0x82C6, 0x3068,
+	0x82C7, 0x3069, 0x82C8, 0x306A, 0x82C9, 0x306B, 0x82CA, 0x306C,
+	0x82CB, 0x306D, 0x82CC, 0x306E, 0x82CD, 0x306F, 0x82CE, 0x3070,
+	0x82CF, 0x3071, 0x82D0, 0x3072, 0x82D1, 0x3073, 0x82D2, 0x3074,
+	0x82D3, 0x3075, 0x82D4, 0x3076, 0x82D5, 0x3077, 0x82D6, 0x3078,
+	0x82D7, 0x3079, 0x82D8, 0x307A, 0x82D9, 0x307B, 0x82DA, 0x307C,
+	0x82DB, 0x307D, 0x82DC, 0x307E, 0x82DD, 0x307F, 0x82DE, 0x3080,
+	0x82DF, 0x3081, 0x82E0, 0x3082, 0x82E1, 0x3083, 0x82E2, 0x3084,
+	0x82E3, 0x3085, 0x82E4, 0x3086, 0x82E5, 0x3087, 0x82E6, 0x3088,
+	0x82E7, 0x3089, 0x82E8, 0x308A, 0x82E9, 0x308B, 0x82EA, 0x308C,
+	0x82EB, 0x308D, 0x82EC, 0x308E, 0x82ED, 0x308F, 0x82EE, 0x3090,
+	0x82EF, 0x3091, 0x82F0, 0x3092, 0x82F1, 0x3093, 0x8340, 0x30A1,
+	0x8341, 0x30A2, 0x8342, 0x30A3, 0x8343, 0x30A4, 0x8344, 0x30A5,
+	0x8345, 0x30A6, 0x8346, 0x30A7, 0x8347, 0x30A8, 0x8348, 0x30A9,
+	0x8349, 0x30AA, 0x834A, 0x30AB, 0x834B, 0x30AC, 0x834C, 0x30AD,
+	0x834D, 0x30AE, 0x834E, 0x30AF, 0x834F, 0x30B0, 0x8350, 0x30B1,
+	0x8351, 0x30B2, 0x8352, 0x30B3, 0x8353, 0x30B4, 0x8354, 0x30B5,
+	0x8355, 0x30B6, 0x8356, 0x30B7, 0x8357, 0x30B8, 0x8358, 0x30B9,
+	0x8359, 0x30BA, 0x835A, 0x30BB, 0x835B, 0x30BC, 0x835C, 0x30BD,
+	0x835D, 0x30BE, 0x835E, 0x30BF, 0x835F, 0x30C0, 0x8360, 0x30C1,
+	0x8361, 0x30C2, 0x8362, 0x30C3, 0x8363, 0x30C4, 0x8364, 0x30C5,
+	0x8365, 0x30C6, 0x8366, 0x30C7, 0x8367, 0x30C8, 0x8368, 0x30C9,
+	0x8369, 0x30CA, 0x836A, 0x30CB, 0x836B, 0x30CC, 0x836C, 0x30CD,
+	0x836D, 0x30CE, 0x836E, 0x30CF, 0x836F, 0x30D0, 0x8370, 0x30D1,
+	0x8371, 0x30D2, 0x8372, 0x30D3, 0x8373, 0x30D4, 0x8374, 0x30D5,
+	0x8375, 0x30D6, 0x8376, 0x30D7, 0x8377, 0x30D8, 0x8378, 0x30D9,
+	0x8379, 0x30DA, 0x837A, 0x30DB, 0x837B, 0x30DC, 0x837C, 0x30DD,
+	0x837D, 0x30DE, 0x837E, 0x30DF, 0x8380, 0x30E0, 0x8381, 0x30E1,
+	0x8382, 0x30E2, 0x8383, 0x30E3, 0x8384, 0x30E4, 0x8385, 0x30E5,
+	0x8386, 0x30E6, 0x8387, 0x30E7, 0x8388, 0x30E8, 0x8389, 0x30E9,
+	0x838A, 0x30EA, 0x838B, 0x30EB, 0x838C, 0x30EC, 0x838D, 0x30ED,
+	0x838E, 0x30EE, 0x838F, 0x30EF, 0x8390, 0x30F0, 0x8391, 0x30F1,
+	0x8392, 0x30F2, 0x8393, 0x30F3, 0x8394, 0x3094, 0x8394, 0x30F4,
+	0x8395, 0x30F5, 0x8396, 0x30F6, 0x839F, 0x0391, 0x83A0, 0x0392,
+	0x83A1, 0x0393, 0x83A2, 0x0394, 0x83A3, 0x0395, 0x83A4, 0x0396,
+	0x83A5, 0x0397, 0x83A6, 0x0398, 0x83A7, 0x0399, 0x83A8, 0x039A,
+	0x83A9, 0x039B, 0x83AA, 0x039C, 0x83AB, 0x039D, 0x83AC, 0x039E,
+	0x83AD, 0x039F, 0x83AE, 0x03A0, 0x83AF, 0x03A1, 0x83B0, 0x03A3,
+	0x83B1, 0x03A4, 0x83B2, 0x03A5, 0x83B3, 0x03A6, 0x83B4, 0x03A7,
+	0x83B5, 0x03A8, 0x83B6, 0x03A9, 0x83BF, 0x03B1, 0x83C0, 0x03B2,
+	0x83C1, 0x03B3, 0x83C2, 0x03B4, 0x83C3, 0x03B5, 0x83C4, 0x03B6,
+	0x83C5, 0x03B7, 0x83C6, 0x03B8, 0x83C7, 0x03B9, 0x83C8, 0x03BA,
+	0x83C9, 0x03BB, 0x83CA, 0x03BC, 0x83CB, 0x03BD, 0x83CC, 0x03BE,
+	0x83CD, 0x03BF, 0x83CE, 0x03C0, 0x83CF, 0x03C1, 0x83D0, 0x03C3,
+	0x83D1, 0x03C4, 0x83D2, 0x03C5, 0x83D3, 0x03C6, 0x83D4, 0x03C7,
+	0x83D5, 0x03C8, 0x83D6, 0x03C9, 0x8440, 0x0410, 0x8441, 0x0411,
+	0x8442, 0x0412, 0x8443, 0x0413, 0x8444, 0x0414, 0x8445, 0x0415,
+	0x8446, 0x0401, 0x8447, 0x0416, 0x8448, 0x0417, 0x8449, 0x0418,
+	0x844A, 0x0419, 0x844B, 0x041A, 0x844C, 0x041B, 0x844D, 0x041C,
+	0x844E, 0x041D, 0x844F, 0x041E, 0x8450, 0x041F, 0x8451, 0x0420,
+	0x8452, 0x0421, 0x8453, 0x0422, 0x8454, 0x0423, 0x8455, 0x0424,
+	0x8456, 0x0425, 0x8457, 0x0426, 0x8458, 0x0427, 0x8459, 0x0428,
+	0x845A, 0x0429, 0x845B, 0x042A, 0x845C, 0x042B, 0x845D, 0x042C,
+	0x845E, 0x042D, 0x845F, 0x042E, 0x8460, 0x042F, 0x8470, 0x0430,
+	0x8471, 0x0431, 0x8472, 0x0432, 0x8473, 0x0433, 0x8474, 0x0434,
+	0x8475, 0x0435, 0x8476, 0x0451, 0x8477, 0x0436, 0x8478, 0x0437,
+	0x8479, 0x0438, 0x847A, 0x0439, 0x847B, 0x043A, 0x847C, 0x043B,
+	0x847D, 0x043C, 0x847E, 0x043D, 0x8480, 0x043E, 0x8481, 0x043F,
+	0x8482, 0x0440, 0x8483, 0x0441, 0x8484, 0x0442, 0x8485, 0x0443,
+	0x8486, 0x0444, 0x8487, 0x0445, 0x8488, 0x0446, 0x8489, 0x0447,
+	0x848A, 0x0448, 0x848B, 0x0449, 0x848C, 0x044A, 0x848D, 0x044B,
+	0x848E, 0x044C, 0x848F, 0x044D, 0x8490, 0x044E, 0x8491, 0x044F,
+	0x849F, 0x2500, 0x84A0, 0x2502, 0x84A1, 0x250C, 0x84A2, 0x2510,
+	0x84A3, 0x2518, 0x84A4, 0x2514, 0x84A5, 0x251C, 0x84A6, 0x252C,
+	0x84A7, 0x2524, 0x84A8, 0x2534, 0x84A9, 0x253C, 0x84AA, 0x2501,
+	0x84AB, 0x2503, 0x84AC, 0x250F, 0x84AD, 0x2513, 0x84AE, 0x251B,
+	0x84AF, 0x2517, 0x84B0, 0x2523, 0x84B1, 0x2533, 0x84B2, 0x252B,
+	0x84B3, 0x253B, 0x84B4, 0x254B, 0x84B5, 0x2520, 0x84B6, 0x252F,
+	0x84B7, 0x2528, 0x84B8, 0x2537, 0x84B9, 0x253F, 0x84BA, 0x251D,
+	0x84BB, 0x2530, 0x84BC, 0x2525, 0x84BD, 0x2538, 0x84BE, 0x2542,
+	0x8740, 0x2460, 0x8741, 0x2461, 0x8742, 0x2462, 0x8743, 0x2463,
+	0x8744, 0x2464, 0x8745, 0x2465, 0x8746, 0x2466, 0x8747, 0x2467,
+	0x8748, 0x2468, 0x8749, 0x2469, 0x874A, 0x246A, 0x874B, 0x246B,
+	0x874C, 0x246C, 0x874D, 0x246D, 0x874E, 0x246E, 0x874F, 0x246F,
+	0x8750, 0x2470, 0x8751, 0x2471, 0x8752, 0x2472, 0x8753, 0x2473,
+	0x8754, 0x2160, 0x8755, 0x2161, 0x8756, 0x2162, 0x8757, 0x2163,
+	0x8758, 0x2164, 0x8759, 0x2165, 0x875A, 0x2166, 0x875B, 0x2167,
+	0x875C, 0x2168, 0x875D, 0x2169, 0x875F, 0x3349, 0x8760, 0x3314,
+	0x8761, 0x3322, 0x8762, 0x334D, 0x8763, 0x3318, 0x8764, 0x3327,
+	0x8765, 0x3303, 0x8766, 0x3336, 0x8767, 0x3351, 0x8768, 0x3357,
+	0x8769, 0x330D, 0x876A, 0x3326, 0x876B, 0x3323, 0x876C, 0x332B,
+	0x876D, 0x334A, 0x876E, 0x333B, 0x876F, 0x339C, 0x8770, 0x339D,
+	0x8771, 0x339E, 0x8772, 0x338E, 0x8773, 0x338F, 0x8774, 0x33C4,
+	0x8775, 0x33A1, 0x877E, 0x337B, 0x8780, 0x301D, 0x8781, 0x301F,
+	0x8782, 0x2116, 0x8783, 0x33CD, 0x8784, 0x2121, 0x8785, 0x32A4,
+	0x8786, 0x32A5, 0x8787, 0x32A6, 0x8788, 0x32A7, 0x8789, 0x32A8,
+	0x878A, 0x3231, 0x878B, 0x3232, 0x878C, 0x3239, 0x878D, 0x337E,
+	0x878E, 0x337D, 0x878F, 0x337C, 0x8793, 0x222E, 0x8794, 0x2211,
+	0x8798, 0x221F, 0x8799, 0x22BF, 0x889F, 0x4E9C, 0x88A0, 0x5516,
+	0x88A1, 0x5A03, 0x88A2, 0x963F, 0x88A3, 0x54C0, 0x88A4, 0x611B,
+	0x88A5, 0x6328, 0x88A6, 0x59F6, 0x88A7, 0x9022, 0x88A8, 0x8475,
+	0x88A9, 0x831C, 0x88AA, 0x7A50, 0x88AB, 0x60AA, 0x88AC, 0x63E1,
+	0x88AD, 0x6E25, 0x88AE, 0x65ED, 0x88AF, 0x8466, 0x88B0, 0x82A6,
+	0x88B1, 0x9BF5, 0x88B2, 0x6893, 0x88B3, 0x5727, 0x88B4, 0x65A1,
+	0x88B5, 0x6271, 0x88B6, 0x5B9B, 0x88B7, 0x59D0, 0x88B8, 0x867B,
+	0x88B9, 0x98F4, 0x88BA, 0x7D62, 0x88BB, 0x7DBE, 0x88BC, 0x9B8E,
+	0x88BD, 0x6216, 0x88BE, 0x7C9F, 0x88BF, 0x88B7, 0x88C0, 0x5B89,
+	0x88C1, 0x5EB5, 0x88C2, 0x6309, 0x88C3, 0x6697, 0x88C4, 0x6848,
+	0x88C5, 0x95C7, 0x88C6, 0x978D, 0x88C7, 0x674F, 0x88C8, 0x4EE5,
+	0x88C9, 0x4F0A, 0x88CA, 0x4F4D, 0x88CB, 0x4F9D, 0x88CC, 0x5049,
+	0x88CD, 0x56F2, 0x88CE, 0x5937, 0x88CF, 0x59D4, 0x88D0, 0x5A01,
+	0x88D1, 0x5C09, 0x88D2, 0x60DF, 0x88D3, 0x610F, 0x88D4, 0x6170,
+	0x88D5, 0x6613, 0x88D6, 0x6905, 0x88D7, 0x70BA, 0x88D8, 0x754F,
+	0x88D9, 0x7570, 0x88DA, 0x79FB, 0x88DB, 0x7DAD, 0x88DC, 0x7DEF,
+	0x88DD, 0x80C3, 0x88DE, 0x840E, 0x88DF, 0x8863, 0x88E0, 0x8B02,
+	0x88E1, 0x9055, 0x88E2, 0x907A, 0x88E3, 0x533B, 0x88E4, 0x4E95,
+	0x88E5, 0x4EA5, 0x88E6, 0x57DF, 0x88E7, 0x80B2, 0x88E8, 0x90C1,
+	0x88E9, 0x78EF, 0x88EA, 0x4E00, 0x88EB, 0x58F1, 0x88EC, 0x6EA2,
+	0x88ED, 0x9038, 0x88EE, 0x7A32, 0x88EF, 0x8328, 0x88F0, 0x828B,
+	0x88F1, 0x9C2F, 0x88F2, 0x5141, 0x88F3, 0x5370, 0x88F4, 0x54BD,
+	0x88F5, 0x54E1, 0x88F6, 0x56E0, 0x88F7, 0x59FB, 0x88F8, 0x5F15,
+	0x88F9, 0x98F2, 0x88FA, 0x6DEB, 0x88FB, 0x80E4, 0x88FC, 0x852D,
+	0x8940, 0x9662, 0x8941, 0x9670, 0x8942, 0x96A0, 0x8943, 0x97FB,
+	0x8944, 0x540B, 0x8945, 0x53F3, 0x8946, 0x5B87, 0x8947, 0x70CF,
+	0x8948, 0x7FBD, 0x8949, 0x8FC2, 0x894A, 0x96E8, 0x894B, 0x536F,
+	0x894C, 0x9D5C, 0x894D, 0x7ABA, 0x894E, 0x4E11, 0x894F, 0x7893,
+	0x8950, 0x81FC, 0x8951, 0x6E26, 0x8952, 0x5618, 0x8953, 0x5504,
+	0x8954, 0x6B1D, 0x8955, 0x851A, 0x8956, 0x9C3B, 0x8957, 0x59E5,
+	0x8958, 0x53A9, 0x8959, 0x6D66, 0x895A, 0x74DC, 0x895B, 0x958F,
+	0x895C, 0x5642, 0x895D, 0x4E91, 0x895E, 0x904B, 0x895F, 0x96F2,
+	0x8960, 0x834F, 0x8961, 0x990C, 0x8962, 0x53E1, 0x8963, 0x55B6,
+	0x8964, 0x5B30, 0x8965, 0x5F71, 0x8966, 0x6620, 0x8967, 0x66F3,
+	0x8968, 0x6804, 0x8969, 0x6C38, 0x896A, 0x6CF3, 0x896B, 0x6D29,
+	0x896C, 0x745B, 0x896D, 0x76C8, 0x896E, 0x7A4E, 0x896F, 0x9834,
+	0x8970, 0x82F1, 0x8971, 0x885B, 0x8972, 0x8A60, 0x8973, 0x92ED,
+	0x8974, 0x6DB2, 0x8975, 0x75AB, 0x8976, 0x76CA, 0x8977, 0x99C5,
+	0x8978, 0x60A6, 0x8979, 0x8B01, 0x897A, 0x8D8A, 0x897B, 0x95B2,
+	0x897C, 0x698E, 0x897D, 0x53AD, 0x897E, 0x5186, 0x8980, 0x5712,
+	0x8981, 0x5830, 0x8982, 0x5944, 0x8983, 0x5BB4, 0x8984, 0x5EF6,
+	0x8985, 0x6028, 0x8986, 0x63A9, 0x8987, 0x63F4, 0x8988, 0x6CBF,
+	0x8989, 0x6F14, 0x898A, 0x708E, 0x898B, 0x7114, 0x898C, 0x7159,
+	0x898D, 0x71D5, 0x898E, 0x733F, 0x898F, 0x7E01, 0x8990, 0x8276,
+	0x8991, 0x82D1, 0x8992, 0x8597, 0x8993, 0x9060, 0x8994, 0x925B,
+	0x8995, 0x9D1B, 0x8996, 0x5869, 0x8997, 0x65BC, 0x8998, 0x6C5A,
+	0x8999, 0x7525, 0x899A, 0x51F9, 0x899B, 0x592E, 0x899C, 0x5965,
+	0x899D, 0x5F80, 0x899E, 0x5FDC, 0x899F, 0x62BC, 0x89A0, 0x65FA,
+	0x89A1, 0x6A2A, 0x89A2, 0x6B27, 0x89A3, 0x6BB4, 0x89A4, 0x738B,
+	0x89A5, 0x7FC1, 0x89A6, 0x8956, 0x89A7, 0x9D2C, 0x89A8, 0x9D0E,
+	0x89A9, 0x9EC4, 0x89AA, 0x5CA1, 0x89AB, 0x6C96, 0x89AC, 0x837B,
+	0x89AD, 0x5104, 0x89AE, 0x5C4B, 0x89AF, 0x61B6, 0x89B0, 0x81C6,
+	0x89B1, 0x6876, 0x89B2, 0x7261, 0x89B3, 0x4E59, 0x89B4, 0x4FFA,
+	0x89B5, 0x5378, 0x89B6, 0x6069, 0x89B7, 0x6E29, 0x89B8, 0x7A4F,
+	0x89B9, 0x97F3, 0x89BA, 0x4E0B, 0x89BB, 0x5316, 0x89BC, 0x4EEE,
+	0x89BD, 0x4F55, 0x89BE, 0x4F3D, 0x89BF, 0x4FA1, 0x89C0, 0x4F73,
+	0x89C1, 0x52A0, 0x89C2, 0x53EF, 0x89C3, 0x5609, 0x89C4, 0x590F,
+	0x89C5, 0x5AC1, 0x89C6, 0x5BB6, 0x89C7, 0x5BE1, 0x89C8, 0x79D1,
+	0x89C9, 0x6687, 0x89CA, 0x679C, 0x89CB, 0x67B6, 0x89CC, 0x6B4C,
+	0x89CD, 0x6CB3, 0x89CE, 0x706B, 0x89CF, 0x73C2, 0x89D0, 0x798D,
+	0x89D1, 0x79BE, 0x89D2, 0x7A3C, 0x89D3, 0x7B87, 0x89D4, 0x82B1,
+	0x89D5, 0x82DB, 0x89D6, 0x8304, 0x89D7, 0x8377, 0x89D8, 0x83EF,
+	0x89D9, 0x83D3, 0x89DA, 0x8766, 0x89DB, 0x8AB2, 0x89DC, 0x5629,
+	0x89DD, 0x8CA8, 0x89DE, 0x8FE6, 0x89DF, 0x904E, 0x89E0, 0x971E,
+	0x89E1, 0x868A, 0x89E2, 0x4FC4, 0x89E3, 0x5CE8, 0x89E4, 0x6211,
+	0x89E5, 0x7259, 0x89E6, 0x753B, 0x89E7, 0x81E5, 0x89E8, 0x82BD,
+	0x89E9, 0x86FE, 0x89EA, 0x8CC0, 0x89EB, 0x96C5, 0x89EC, 0x9913,
+	0x89ED, 0x99D5, 0x89EE, 0x4ECB, 0x89EF, 0x4F1A, 0x89F0, 0x89E3,
+	0x89F1, 0x56DE, 0x89F2, 0x584A, 0x89F3, 0x58CA, 0x89F4, 0x5EFB,
+	0x89F5, 0x5FEB, 0x89F6, 0x602A, 0x89F7, 0x6094, 0x89F8, 0x6062,
+	0x89F9, 0x61D0, 0x89FA, 0x6212, 0x89FB, 0x62D0, 0x89FC, 0x6539,
+	0x8A40, 0x9B41, 0x8A41, 0x6666, 0x8A42, 0x68B0, 0x8A43, 0x6D77,
+	0x8A44, 0x7070, 0x8A45, 0x754C, 0x8A46, 0x7686, 0x8A47, 0x7D75,
+	0x8A48, 0x82A5, 0x8A49, 0x87F9, 0x8A4A, 0x958B, 0x8A4B, 0x968E,
+	0x8A4C, 0x8C9D, 0x8A4D, 0x51F1, 0x8A4E, 0x52BE, 0x8A4F, 0x5916,
+	0x8A50, 0x54B3, 0x8A51, 0x5BB3, 0x8A52, 0x5D16, 0x8A53, 0x6168,
+	0x8A54, 0x6982, 0x8A55, 0x6DAF, 0x8A56, 0x788D, 0x8A57, 0x84CB,
+	0x8A58, 0x8857, 0x8A59, 0x8A72, 0x8A5A, 0x93A7, 0x8A5B, 0x9AB8,
+	0x8A5C, 0x6D6C, 0x8A5D, 0x99A8, 0x8A5E, 0x86D9, 0x8A5F, 0x57A3,
+	0x8A60, 0x67FF, 0x8A61, 0x86CE, 0x8A62, 0x920E, 0x8A63, 0x5283,
+	0x8A64, 0x5687, 0x8A65, 0x5404, 0x8A66, 0x5ED3, 0x8A67, 0x62E1,
+	0x8A68, 0x64B9, 0x8A69, 0x683C, 0x8A6A, 0x6838, 0x8A6B, 0x6BBB,
+	0x8A6C, 0x7372, 0x8A6D, 0x78BA, 0x8A6E, 0x7A6B, 0x8A6F, 0x899A,
+	0x8A70, 0x89D2, 0x8A71, 0x8D6B, 0x8A72, 0x8F03, 0x8A73, 0x90ED,
+	0x8A74, 0x95A3, 0x8A75, 0x9694, 0x8A76, 0x9769, 0x8A77, 0x5B66,
+	0x8A78, 0x5CB3, 0x8A79, 0x697D, 0x8A7A, 0x984D, 0x8A7B, 0x984E,
+	0x8A7C, 0x639B, 0x8A7D, 0x7B20, 0x8A7E, 0x6A2B, 0x8A80, 0x6A7F,
+	0x8A81, 0x68B6, 0x8A82, 0x9C0D, 0x8A83, 0x6F5F, 0x8A84, 0x5272,
+	0x8A85, 0x559D, 0x8A86, 0x6070, 0x8A87, 0x62EC, 0x8A88, 0x6D3B,
+	0x8A89, 0x6E07, 0x8A8A, 0x6ED1, 0x8A8B, 0x845B, 0x8A8C, 0x8910,
+	0x8A8D, 0x8F44, 0x8A8E, 0x4E14, 0x8A8F, 0x9C39, 0x8A90, 0x53F6,
+	0x8A91, 0x691B, 0x8A92, 0x6A3A, 0x8A93, 0x9784, 0x8A94, 0x682A,
+	0x8A95, 0x515C, 0x8A96, 0x7AC3, 0x8A97, 0x84B2, 0x8A98, 0x91DC,
+	0x8A99, 0x938C, 0x8A9A, 0x565B, 0x8A9B, 0x9D28, 0x8A9C, 0x6822,
+	0x8A9D, 0x8305, 0x8A9E, 0x8431, 0x8A9F, 0x7CA5, 0x8AA0, 0x5208,
+	0x8AA1, 0x82C5, 0x8AA2, 0x74E6, 0x8AA3, 0x4E7E, 0x8AA4, 0x4F83,
+	0x8AA5, 0x51A0, 0x8AA6, 0x5BD2, 0x8AA7, 0x520A, 0x8AA8, 0x52D8,
+	0x8AA9, 0x52E7, 0x8AAA, 0x5DFB, 0x8AAB, 0x559A, 0x8AAC, 0x582A,
+	0x8AAD, 0x59E6, 0x8AAE, 0x5B8C, 0x8AAF, 0x5B98, 0x8AB0, 0x5BDB,
+	0x8AB1, 0x5E72, 0x8AB2, 0x5E79, 0x8AB3, 0x60A3, 0x8AB4, 0x611F,
+	0x8AB5, 0x6163, 0x8AB6, 0x61BE, 0x8AB7, 0x63DB, 0x8AB8, 0x6562,
+	0x8AB9, 0x67D1, 0x8ABA, 0x6853, 0x8ABB, 0x68FA, 0x8ABC, 0x6B3E,
+	0x8ABD, 0x6B53, 0x8ABE, 0x6C57, 0x8ABF, 0x6F22, 0x8AC0, 0x6F97,
+	0x8AC1, 0x6F45, 0x8AC2, 0x74B0, 0x8AC3, 0x7518, 0x8AC4, 0x76E3,
+	0x8AC5, 0x770B, 0x8AC6, 0x7AFF, 0x8AC7, 0x7BA1, 0x8AC8, 0x7C21,
+	0x8AC9, 0x7DE9, 0x8ACA, 0x7F36, 0x8ACB, 0x7FF0, 0x8ACC, 0x809D,
+	0x8ACD, 0x8266, 0x8ACE, 0x839E, 0x8ACF, 0x89B3, 0x8AD0, 0x8ACC,
+	0x8AD1, 0x8CAB, 0x8AD2, 0x9084, 0x8AD3, 0x9451, 0x8AD4, 0x9593,
+	0x8AD5, 0x9591, 0x8AD6, 0x95A2, 0x8AD7, 0x9665, 0x8AD8, 0x97D3,
+	0x8AD9, 0x9928, 0x8ADA, 0x8218, 0x8ADB, 0x4E38, 0x8ADC, 0x542B,
+	0x8ADD, 0x5CB8, 0x8ADE, 0x5DCC, 0x8ADF, 0x73A9, 0x8AE0, 0x764C,
+	0x8AE1, 0x773C, 0x8AE2, 0x5CA9, 0x8AE3, 0x7FEB, 0x8AE4, 0x8D0B,
+	0x8AE5, 0x96C1, 0x8AE6, 0x9811, 0x8AE7, 0x9854, 0x8AE8, 0x9858,
+	0x8AE9, 0x4F01, 0x8AEA, 0x4F0E, 0x8AEB, 0x5371, 0x8AEC, 0x559C,
+	0x8AED, 0x5668, 0x8AEE, 0x57FA, 0x8AEF, 0x5947, 0x8AF0, 0x5B09,
+	0x8AF1, 0x5BC4, 0x8AF2, 0x5C90, 0x8AF3, 0x5E0C, 0x8AF4, 0x5E7E,
+	0x8AF5, 0x5FCC, 0x8AF6, 0x63EE, 0x8AF7, 0x673A, 0x8AF8, 0x65D7,
+	0x8AF9, 0x65E2, 0x8AFA, 0x671F, 0x8AFB, 0x68CB, 0x8AFC, 0x68C4,
+	0x8B40, 0x6A5F, 0x8B41, 0x5E30, 0x8B42, 0x6BC5, 0x8B43, 0x6C17,
+	0x8B44, 0x6C7D, 0x8B45, 0x757F, 0x8B46, 0x7948, 0x8B47, 0x5B63,
+	0x8B48, 0x7A00, 0x8B49, 0x7D00, 0x8B4A, 0x5FBD, 0x8B4B, 0x898F,
+	0x8B4C, 0x8A18, 0x8B4D, 0x8CB4, 0x8B4E, 0x8D77, 0x8B4F, 0x8ECC,
+	0x8B50, 0x8F1D, 0x8B51, 0x98E2, 0x8B52, 0x9A0E, 0x8B53, 0x9B3C,
+	0x8B54, 0x4E80, 0x8B55, 0x507D, 0x8B56, 0x5100, 0x8B57, 0x5993,
+	0x8B58, 0x5B9C, 0x8B59, 0x622F, 0x8B5A, 0x6280, 0x8B5B, 0x64EC,
+	0x8B5C, 0x6B3A, 0x8B5D, 0x72A0, 0x8B5E, 0x7591, 0x8B5F, 0x7947,
+	0x8B60, 0x7FA9, 0x8B61, 0x87FB, 0x8B62, 0x8ABC, 0x8B63, 0x8B70,
+	0x8B64, 0x63AC, 0x8B65, 0x83CA, 0x8B66, 0x97A0, 0x8B67, 0x5409,
+	0x8B68, 0x5403, 0x8B69, 0x55AB, 0x8B6A, 0x6854, 0x8B6B, 0x6A58,
+	0x8B6C, 0x8A70, 0x8B6D, 0x7827, 0x8B6E, 0x6775, 0x8B6F, 0x9ECD,
+	0x8B70, 0x5374, 0x8B71, 0x5BA2, 0x8B72, 0x811A, 0x8B73, 0x8650,
+	0x8B74, 0x9006, 0x8B75, 0x4E18, 0x8B76, 0x4E45, 0x8B77, 0x4EC7,
+	0x8B78, 0x4F11, 0x8B79, 0x53CA, 0x8B7A, 0x5438, 0x8B7B, 0x5BAE,
+	0x8B7C, 0x5F13, 0x8B7D, 0x6025, 0x8B7E, 0x6551, 0x8B80, 0x673D,
+	0x8B81, 0x6C42, 0x8B82, 0x6C72, 0x8B83, 0x6CE3, 0x8B84, 0x7078,
+	0x8B85, 0x7403, 0x8B86, 0x7A76, 0x8B87, 0x7AAE, 0x8B88, 0x7B08,
+	0x8B89, 0x7D1A, 0x8B8A, 0x7CFE, 0x8B8B, 0x7D66, 0x8B8C, 0x65E7,
+	0x8B8D, 0x725B, 0x8B8E, 0x53BB, 0x8B8F, 0x5C45, 0x8B90, 0x5DE8,
+	0x8B91, 0x62D2, 0x8B92, 0x62E0, 0x8B93, 0x6319, 0x8B94, 0x6E20,
+	0x8B95, 0x865A, 0x8B96, 0x8A31, 0x8B97, 0x8DDD, 0x8B98, 0x92F8,
+	0x8B99, 0x6F01, 0x8B9A, 0x79A6, 0x8B9B, 0x9B5A, 0x8B9C, 0x4EA8,
+	0x8B9D, 0x4EAB, 0x8B9E, 0x4EAC, 0x8B9F, 0x4F9B, 0x8BA0, 0x4FA0,
+	0x8BA1, 0x50D1, 0x8BA2, 0x5147, 0x8BA3, 0x7AF6, 0x8BA4, 0x5171,
+	0x8BA5, 0x51F6, 0x8BA6, 0x5354, 0x8BA7, 0x5321, 0x8BA8, 0x537F,
+	0x8BA9, 0x53EB, 0x8BAA, 0x55AC, 0x8BAB, 0x5883, 0x8BAC, 0x5CE1,
+	0x8BAD, 0x5F37, 0x8BAE, 0x5F4A, 0x8BAF, 0x602F, 0x8BB0, 0x6050,
+	0x8BB1, 0x606D, 0x8BB2, 0x631F, 0x8BB3, 0x6559, 0x8BB4, 0x6A4B,
+	0x8BB5, 0x6CC1, 0x8BB6, 0x72C2, 0x8BB7, 0x72ED, 0x8BB8, 0x77EF,
+	0x8BB9, 0x80F8, 0x8BBA, 0x8105, 0x8BBB, 0x8208, 0x8BBC, 0x854E,
+	0x8BBD, 0x90F7, 0x8BBE, 0x93E1, 0x8BBF, 0x97FF, 0x8BC0, 0x9957,
+	0x8BC1, 0x9A5A, 0x8BC2, 0x4EF0, 0x8BC3, 0x51DD, 0x8BC4, 0x5C2D,
+	0x8BC5, 0x6681, 0x8BC6, 0x696D, 0x8BC7, 0x5C40, 0x8BC8, 0x66F2,
+	0x8BC9, 0x6975, 0x8BCA, 0x7389, 0x8BCB, 0x6850, 0x8BCC, 0x7C81,
+	0x8BCD, 0x50C5, 0x8BCE, 0x52E4, 0x8BCF, 0x5747, 0x8BD0, 0x5DFE,
+	0x8BD1, 0x9326, 0x8BD2, 0x65A4, 0x8BD3, 0x6B23, 0x8BD4, 0x6B3D,
+	0x8BD5, 0x7434, 0x8BD6, 0x7981, 0x8BD7, 0x79BD, 0x8BD8, 0x7B4B,
+	0x8BD9, 0x7DCA, 0x8BDA, 0x82B9, 0x8BDB, 0x83CC, 0x8BDC, 0x887F,
+	0x8BDD, 0x895F, 0x8BDE, 0x8B39, 0x8BDF, 0x8FD1, 0x8BE0, 0x91D1,
+	0x8BE1, 0x541F, 0x8BE2, 0x9280, 0x8BE3, 0x4E5D, 0x8BE4, 0x5036,
+	0x8BE5, 0x53E5, 0x8BE6, 0x533A, 0x8BE7, 0x72D7, 0x8BE8, 0x7396,
+	0x8BE9, 0x77E9, 0x8BEA, 0x82E6, 0x8BEB, 0x8EAF, 0x8BEC, 0x99C6,
+	0x8BED, 0x99C8, 0x8BEE, 0x99D2, 0x8BEF, 0x5177, 0x8BF0, 0x611A,
+	0x8BF1, 0x865E, 0x8BF2, 0x55B0, 0x8BF3, 0x7A7A, 0x8BF4, 0x5076,
+	0x8BF5, 0x5BD3, 0x8BF6, 0x9047, 0x8BF7, 0x9685, 0x8BF8, 0x4E32,
+	0x8BF9, 0x6ADB, 0x8BFA, 0x91E7, 0x8BFB, 0x5C51, 0x8BFC, 0x5C48,
+	0x8C40, 0x6398, 0x8C41, 0x7A9F, 0x8C42, 0x6C93, 0x8C43, 0x9774,
+	0x8C44, 0x8F61, 0x8C45, 0x7AAA, 0x8C46, 0x718A, 0x8C47, 0x9688,
+	0x8C48, 0x7C82, 0x8C49, 0x6817, 0x8C4A, 0x7E70, 0x8C4B, 0x6851,
+	0x8C4C, 0x936C, 0x8C4D, 0x52F2, 0x8C4E, 0x541B, 0x8C4F, 0x85AB,
+	0x8C50, 0x8A13, 0x8C51, 0x7FA4, 0x8C52, 0x8ECD, 0x8C53, 0x90E1,
+	0x8C54, 0x5366, 0x8C55, 0x8888, 0x8C56, 0x7941, 0x8C57, 0x4FC2,
+	0x8C58, 0x50BE, 0x8C59, 0x5211, 0x8C5A, 0x5144, 0x8C5B, 0x5553,
+	0x8C5C, 0x572D, 0x8C5D, 0x73EA, 0x8C5E, 0x578B, 0x8C5F, 0x5951,
+	0x8C60, 0x5F62, 0x8C61, 0x5F84, 0x8C62, 0x6075, 0x8C63, 0x6176,
+	0x8C64, 0x6167, 0x8C65, 0x61A9, 0x8C66, 0x63B2, 0x8C67, 0x643A,
+	0x8C68, 0x656C, 0x8C69, 0x666F, 0x8C6A, 0x6842, 0x8C6B, 0x6E13,
+	0x8C6C, 0x7566, 0x8C6D, 0x7A3D, 0x8C6E, 0x7CFB, 0x8C6F, 0x7D4C,
+	0x8C70, 0x7D99, 0x8C71, 0x7E4B, 0x8C72, 0x7F6B, 0x8C73, 0x830E,
+	0x8C74, 0x834A, 0x8C75, 0x86CD, 0x8C76, 0x8A08, 0x8C77, 0x8A63,
+	0x8C78, 0x8B66, 0x8C79, 0x8EFD, 0x8C7A, 0x981A, 0x8C7B, 0x9D8F,
+	0x8C7C, 0x82B8, 0x8C7D, 0x8FCE, 0x8C7E, 0x9BE8, 0x8C80, 0x5287,
+	0x8C81, 0x621F, 0x8C82, 0x6483, 0x8C83, 0x6FC0, 0x8C84, 0x9699,
+	0x8C85, 0x6841, 0x8C86, 0x5091, 0x8C87, 0x6B20, 0x8C88, 0x6C7A,
+	0x8C89, 0x6F54, 0x8C8A, 0x7A74, 0x8C8B, 0x7D50, 0x8C8C, 0x8840,
+	0x8C8D, 0x8A23, 0x8C8E, 0x6708, 0x8C8F, 0x4EF6, 0x8C90, 0x5039,
+	0x8C91, 0x5026, 0x8C92, 0x5065, 0x8C93, 0x517C, 0x8C94, 0x5238,
+	0x8C95, 0x5263, 0x8C96, 0x55A7, 0x8C97, 0x570F, 0x8C98, 0x5805,
+	0x8C99, 0x5ACC, 0x8C9A, 0x5EFA, 0x8C9B, 0x61B2, 0x8C9C, 0x61F8,
+	0x8C9D, 0x62F3, 0x8C9E, 0x6372, 0x8C9F, 0x691C, 0x8CA0, 0x6A29,
+	0x8CA1, 0x727D, 0x8CA2, 0x72AC, 0x8CA3, 0x732E, 0x8CA4, 0x7814,
+	0x8CA5, 0x786F, 0x8CA6, 0x7D79, 0x8CA7, 0x770C, 0x8CA8, 0x80A9,
+	0x8CA9, 0x898B, 0x8CAA, 0x8B19, 0x8CAB, 0x8CE2, 0x8CAC, 0x8ED2,
+	0x8CAD, 0x9063, 0x8CAE, 0x9375, 0x8CAF, 0x967A, 0x8CB0, 0x9855,
+	0x8CB1, 0x9A13, 0x8CB2, 0x9E78, 0x8CB3, 0x5143, 0x8CB4, 0x539F,
+	0x8CB5, 0x53B3, 0x8CB6, 0x5E7B, 0x8CB7, 0x5F26, 0x8CB8, 0x6E1B,
+	0x8CB9, 0x6E90, 0x8CBA, 0x7384, 0x8CBB, 0x73FE, 0x8CBC, 0x7D43,
+	0x8CBD, 0x8237, 0x8CBE, 0x8A00, 0x8CBF, 0x8AFA, 0x8CC0, 0x9650,
+	0x8CC1, 0x4E4E, 0x8CC2, 0x500B, 0x8CC3, 0x53E4, 0x8CC4, 0x547C,
+	0x8CC5, 0x56FA, 0x8CC6, 0x59D1, 0x8CC7, 0x5B64, 0x8CC8, 0x5DF1,
+	0x8CC9, 0x5EAB, 0x8CCA, 0x5F27, 0x8CCB, 0x6238, 0x8CCC, 0x6545,
+	0x8CCD, 0x67AF, 0x8CCE, 0x6E56, 0x8CCF, 0x72D0, 0x8CD0, 0x7CCA,
+	0x8CD1, 0x88B4, 0x8CD2, 0x80A1, 0x8CD3, 0x80E1, 0x8CD4, 0x83F0,
+	0x8CD5, 0x864E, 0x8CD6, 0x8A87, 0x8CD7, 0x8DE8, 0x8CD8, 0x9237,
+	0x8CD9, 0x96C7, 0x8CDA, 0x9867, 0x8CDB, 0x9F13, 0x8CDC, 0x4E94,
+	0x8CDD, 0x4E92, 0x8CDE, 0x4F0D, 0x8CDF, 0x5348, 0x8CE0, 0x5449,
+	0x8CE1, 0x543E, 0x8CE2, 0x5A2F, 0x8CE3, 0x5F8C, 0x8CE4, 0x5FA1,
+	0x8CE5, 0x609F, 0x8CE6, 0x68A7, 0x8CE7, 0x6A8E, 0x8CE8, 0x745A,
+	0x8CE9, 0x7881, 0x8CEA, 0x8A9E, 0x8CEB, 0x8AA4, 0x8CEC, 0x8B77,
+	0x8CED, 0x9190, 0x8CEE, 0x4E5E, 0x8CEF, 0x9BC9, 0x8CF0, 0x4EA4,
+	0x8CF1, 0x4F7C, 0x8CF2, 0x4FAF, 0x8CF3, 0x5019, 0x8CF4, 0x5016,
+	0x8CF5, 0x5149, 0x8CF6, 0x516C, 0x8CF7, 0x529F, 0x8CF8, 0x52B9,
+	0x8CF9, 0x52FE, 0x8CFA, 0x539A, 0x8CFB, 0x53E3, 0x8CFC, 0x5411,
+	0x8D40, 0x540E, 0x8D41, 0x5589, 0x8D42, 0x5751, 0x8D43, 0x57A2,
+	0x8D44, 0x597D, 0x8D45, 0x5B54, 0x8D46, 0x5B5D, 0x8D47, 0x5B8F,
+	0x8D48, 0x5DE5, 0x8D49, 0x5DE7, 0x8D4A, 0x5DF7, 0x8D4B, 0x5E78,
+	0x8D4C, 0x5E83, 0x8D4D, 0x5E9A, 0x8D4E, 0x5EB7, 0x8D4F, 0x5F18,
+	0x8D50, 0x6052, 0x8D51, 0x614C, 0x8D52, 0x6297, 0x8D53, 0x62D8,
+	0x8D54, 0x63A7, 0x8D55, 0x653B, 0x8D56, 0x6602, 0x8D57, 0x6643,
+	0x8D58, 0x66F4, 0x8D59, 0x676D, 0x8D5A, 0x6821, 0x8D5B, 0x6897,
+	0x8D5C, 0x69CB, 0x8D5D, 0x6C5F, 0x8D5E, 0x6D2A, 0x8D5F, 0x6D69,
+	0x8D60, 0x6E2F, 0x8D61, 0x6E9D, 0x8D62, 0x7532, 0x8D63, 0x7687,
+	0x8D64, 0x786C, 0x8D65, 0x7A3F, 0x8D66, 0x7CE0, 0x8D67, 0x7D05,
+	0x8D68, 0x7D18, 0x8D69, 0x7D5E, 0x8D6A, 0x7DB1, 0x8D6B, 0x8015,
+	0x8D6C, 0x8003, 0x8D6D, 0x80AF, 0x8D6E, 0x80B1, 0x8D6F, 0x8154,
+	0x8D70, 0x818F, 0x8D71, 0x822A, 0x8D72, 0x8352, 0x8D73, 0x884C,
+	0x8D74, 0x8861, 0x8D75, 0x8B1B, 0x8D76, 0x8CA2, 0x8D77, 0x8CFC,
+	0x8D78, 0x90CA, 0x8D79, 0x9175, 0x8D7A, 0x9271, 0x8D7B, 0x783F,
+	0x8D7C, 0x92FC, 0x8D7D, 0x95A4, 0x8D7E, 0x964D, 0x8D80, 0x9805,
+	0x8D81, 0x9999, 0x8D82, 0x9AD8, 0x8D83, 0x9D3B, 0x8D84, 0x525B,
+	0x8D85, 0x52AB, 0x8D86, 0x53F7, 0x8D87, 0x5408, 0x8D88, 0x58D5,
+	0x8D89, 0x62F7, 0x8D8A, 0x6FE0, 0x8D8B, 0x8C6A, 0x8D8C, 0x8F5F,
+	0x8D8D, 0x9EB9, 0x8D8E, 0x514B, 0x8D8F, 0x523B, 0x8D90, 0x544A,
+	0x8D91, 0x56FD, 0x8D92, 0x7A40, 0x8D93, 0x9177, 0x8D94, 0x9D60,
+	0x8D95, 0x9ED2, 0x8D96, 0x7344, 0x8D97, 0x6F09, 0x8D98, 0x8170,
+	0x8D99, 0x7511, 0x8D9A, 0x5FFD, 0x8D9B, 0x60DA, 0x8D9C, 0x9AA8,
+	0x8D9D, 0x72DB, 0x8D9E, 0x8FBC, 0x8D9F, 0x6B64, 0x8DA0, 0x9803,
+	0x8DA1, 0x4ECA, 0x8DA2, 0x56F0, 0x8DA3, 0x5764, 0x8DA4, 0x58BE,
+	0x8DA5, 0x5A5A, 0x8DA6, 0x6068, 0x8DA7, 0x61C7, 0x8DA8, 0x660F,
+	0x8DA9, 0x6606, 0x8DAA, 0x6839, 0x8DAB, 0x68B1, 0x8DAC, 0x6DF7,
+	0x8DAD, 0x75D5, 0x8DAE, 0x7D3A, 0x8DAF, 0x826E, 0x8DB0, 0x9B42,
+	0x8DB1, 0x4E9B, 0x8DB2, 0x4F50, 0x8DB3, 0x53C9, 0x8DB4, 0x5506,
+	0x8DB5, 0x5D6F, 0x8DB6, 0x5DE6, 0x8DB7, 0x5DEE, 0x8DB8, 0x67FB,
+	0x8DB9, 0x6C99, 0x8DBA, 0x7473, 0x8DBB, 0x7802, 0x8DBC, 0x8A50,
+	0x8DBD, 0x9396, 0x8DBE, 0x88DF, 0x8DBF, 0x5750, 0x8DC0, 0x5EA7,
+	0x8DC1, 0x632B, 0x8DC2, 0x50B5, 0x8DC3, 0x50AC, 0x8DC4, 0x518D,
+	0x8DC5, 0x6700, 0x8DC6, 0x54C9, 0x8DC7, 0x585E, 0x8DC8, 0x59BB,
+	0x8DC9, 0x5BB0, 0x8DCA, 0x5F69, 0x8DCB, 0x624D, 0x8DCC, 0x63A1,
+	0x8DCD, 0x683D, 0x8DCE, 0x6B73, 0x8DCF, 0x6E08, 0x8DD0, 0x707D,
+	0x8DD1, 0x91C7, 0x8DD2, 0x7280, 0x8DD3, 0x7815, 0x8DD4, 0x7826,
+	0x8DD5, 0x796D, 0x8DD6, 0x658E, 0x8DD7, 0x7D30, 0x8DD8, 0x83DC,
+	0x8DD9, 0x88C1, 0x8DDA, 0x8F09, 0x8DDB, 0x969B, 0x8DDC, 0x5264,
+	0x8DDD, 0x5728, 0x8DDE, 0x6750, 0x8DDF, 0x7F6A, 0x8DE0, 0x8CA1,
+	0x8DE1, 0x51B4, 0x8DE2, 0x5742, 0x8DE3, 0x962A, 0x8DE4, 0x583A,
+	0x8DE5, 0x698A, 0x8DE6, 0x80B4, 0x8DE7, 0x54B2, 0x8DE8, 0x5D0E,
+	0x8DE9, 0x57FC, 0x8DEA, 0x7895, 0x8DEB, 0x9DFA, 0x8DEC, 0x4F5C,
+	0x8DED, 0x524A, 0x8DEE, 0x548B, 0x8DEF, 0x643E, 0x8DF0, 0x6628,
+	0x8DF1, 0x6714, 0x8DF2, 0x67F5, 0x8DF3, 0x7A84, 0x8DF4, 0x7B56,
+	0x8DF5, 0x7D22, 0x8DF6, 0x932F, 0x8DF7, 0x685C, 0x8DF8, 0x9BAD,
+	0x8DF9, 0x7B39, 0x8DFA, 0x5319, 0x8DFB, 0x518A, 0x8DFC, 0x5237,
+	0x8E40, 0x5BDF, 0x8E41, 0x62F6, 0x8E42, 0x64AE, 0x8E43, 0x64E6,
+	0x8E44, 0x672D, 0x8E45, 0x6BBA, 0x8E46, 0x85A9, 0x8E47, 0x96D1,
+	0x8E48, 0x7690, 0x8E49, 0x9BD6, 0x8E4A, 0x634C, 0x8E4B, 0x9306,
+	0x8E4C, 0x9BAB, 0x8E4D, 0x76BF, 0x8E4E, 0x6652, 0x8E4F, 0x4E09,
+	0x8E50, 0x5098, 0x8E51, 0x53C2, 0x8E52, 0x5C71, 0x8E53, 0x60E8,
+	0x8E54, 0x6492, 0x8E55, 0x6563, 0x8E56, 0x685F, 0x8E57, 0x71E6,
+	0x8E58, 0x73CA, 0x8E59, 0x7523, 0x8E5A, 0x7B97, 0x8E5B, 0x7E82,
+	0x8E5C, 0x8695, 0x8E5D, 0x8B83, 0x8E5E, 0x8CDB, 0x8E5F, 0x9178,
+	0x8E60, 0x9910, 0x8E61, 0x65AC, 0x8E62, 0x66AB, 0x8E63, 0x6B8B,
+	0x8E64, 0x4ED5, 0x8E65, 0x4ED4, 0x8E66, 0x4F3A, 0x8E67, 0x4F7F,
+	0x8E68, 0x523A, 0x8E69, 0x53F8, 0x8E6A, 0x53F2, 0x8E6B, 0x55E3,
+	0x8E6C, 0x56DB, 0x8E6D, 0x58EB, 0x8E6E, 0x59CB, 0x8E6F, 0x59C9,
+	0x8E70, 0x59FF, 0x8E71, 0x5B50, 0x8E72, 0x5C4D, 0x8E73, 0x5E02,
+	0x8E74, 0x5E2B, 0x8E75, 0x5FD7, 0x8E76, 0x601D, 0x8E77, 0x6307,
+	0x8E78, 0x652F, 0x8E79, 0x5B5C, 0x8E7A, 0x65AF, 0x8E7B, 0x65BD,
+	0x8E7C, 0x65E8, 0x8E7D, 0x679D, 0x8E7E, 0x6B62, 0x8E80, 0x6B7B,
+	0x8E81, 0x6C0F, 0x8E82, 0x7345, 0x8E83, 0x7949, 0x8E84, 0x79C1,
+	0x8E85, 0x7CF8, 0x8E86, 0x7D19, 0x8E87, 0x7D2B, 0x8E88, 0x80A2,
+	0x8E89, 0x8102, 0x8E8A, 0x81F3, 0x8E8B, 0x8996, 0x8E8C, 0x8A5E,
+	0x8E8D, 0x8A69, 0x8E8E, 0x8A66, 0x8E8F, 0x8A8C, 0x8E90, 0x8AEE,
+	0x8E91, 0x8CC7, 0x8E92, 0x8CDC, 0x8E93, 0x96CC, 0x8E94, 0x98FC,
+	0x8E95, 0x6B6F, 0x8E96, 0x4E8B, 0x8E97, 0x4F3C, 0x8E98, 0x4F8D,
+	0x8E99, 0x5150, 0x8E9A, 0x5B57, 0x8E9B, 0x5BFA, 0x8E9C, 0x6148,
+	0x8E9D, 0x6301, 0x8E9E, 0x6642, 0x8E9F, 0x6B21, 0x8EA0, 0x6ECB,
+	0x8EA1, 0x6CBB, 0x8EA2, 0x723E, 0x8EA3, 0x74BD, 0x8EA4, 0x75D4,
+	0x8EA5, 0x78C1, 0x8EA6, 0x793A, 0x8EA7, 0x800C, 0x8EA8, 0x8033,
+	0x8EA9, 0x81EA, 0x8EAA, 0x8494, 0x8EAB, 0x8F9E, 0x8EAC, 0x6C50,
+	0x8EAD, 0x9E7F, 0x8EAE, 0x5F0F, 0x8EAF, 0x8B58, 0x8EB0, 0x9D2B,
+	0x8EB1, 0x7AFA, 0x8EB2, 0x8EF8, 0x8EB3, 0x5B8D, 0x8EB4, 0x96EB,
+	0x8EB5, 0x4E03, 0x8EB6, 0x53F1, 0x8EB7, 0x57F7, 0x8EB8, 0x5931,
+	0x8EB9, 0x5AC9, 0x8EBA, 0x5BA4, 0x8EBB, 0x6089, 0x8EBC, 0x6E7F,
+	0x8EBD, 0x6F06, 0x8EBE, 0x75BE, 0x8EBF, 0x8CEA, 0x8EC0, 0x5B9F,
+	0x8EC1, 0x8500, 0x8EC2, 0x7BE0, 0x8EC3, 0x5072, 0x8EC4, 0x67F4,
+	0x8EC5, 0x829D, 0x8EC6, 0x5C61, 0x8EC7, 0x854A, 0x8EC8, 0x7E1E,
+	0x8EC9, 0x820E, 0x8ECA, 0x5199, 0x8ECB, 0x5C04, 0x8ECC, 0x6368,
+	0x8ECD, 0x8D66, 0x8ECE, 0x659C, 0x8ECF, 0x716E, 0x8ED0, 0x793E,
+	0x8ED1, 0x7D17, 0x8ED2, 0x8005, 0x8ED3, 0x8B1D, 0x8ED4, 0x8ECA,
+	0x8ED5, 0x906E, 0x8ED6, 0x86C7, 0x8ED7, 0x90AA, 0x8ED8, 0x501F,
+	0x8ED9, 0x52FA, 0x8EDA, 0x5C3A, 0x8EDB, 0x6753, 0x8EDC, 0x707C,
+	0x8EDD, 0x7235, 0x8EDE, 0x914C, 0x8EDF, 0x91C8, 0x8EE0, 0x932B,
+	0x8EE1, 0x82E5, 0x8EE2, 0x5BC2, 0x8EE3, 0x5F31, 0x8EE4, 0x60F9,
+	0x8EE5, 0x4E3B, 0x8EE6, 0x53D6, 0x8EE7, 0x5B88, 0x8EE8, 0x624B,
+	0x8EE9, 0x6731, 0x8EEA, 0x6B8A, 0x8EEB, 0x72E9, 0x8EEC, 0x73E0,
+	0x8EED, 0x7A2E, 0x8EEE, 0x816B, 0x8EEF, 0x8DA3, 0x8EF0, 0x9152,
+	0x8EF1, 0x9996, 0x8EF2, 0x5112, 0x8EF3, 0x53D7, 0x8EF4, 0x546A,
+	0x8EF5, 0x5BFF, 0x8EF6, 0x6388, 0x8EF7, 0x6A39, 0x8EF8, 0x7DAC,
+	0x8EF9, 0x9700, 0x8EFA, 0x56DA, 0x8EFB, 0x53CE, 0x8EFC, 0x5468,
+	0x8F40, 0x5B97, 0x8F41, 0x5C31, 0x8F42, 0x5DDE, 0x8F43, 0x4FEE,
+	0x8F44, 0x6101, 0x8F45, 0x62FE, 0x8F46, 0x6D32, 0x8F47, 0x79C0,
+	0x8F48, 0x79CB, 0x8F49, 0x7D42, 0x8F4A, 0x7E4D, 0x8F4B, 0x7FD2,
+	0x8F4C, 0x81ED, 0x8F4D, 0x821F, 0x8F4E, 0x8490, 0x8F4F, 0x8846,
+	0x8F50, 0x8972, 0x8F51, 0x8B90, 0x8F52, 0x8E74, 0x8F53, 0x8F2F,
+	0x8F54, 0x9031, 0x8F55, 0x914B, 0x8F56, 0x916C, 0x8F57, 0x96C6,
+	0x8F58, 0x919C, 0x8F59, 0x4EC0, 0x8F5A, 0x4F4F, 0x8F5B, 0x5145,
+	0x8F5C, 0x5341, 0x8F5D, 0x5F93, 0x8F5E, 0x620E, 0x8F5F, 0x67D4,
+	0x8F60, 0x6C41, 0x8F61, 0x6E0B, 0x8F62, 0x7363, 0x8F63, 0x7E26,
+	0x8F64, 0x91CD, 0x8F65, 0x9283, 0x8F66, 0x53D4, 0x8F67, 0x5919,
+	0x8F68, 0x5BBF, 0x8F69, 0x6DD1, 0x8F6A, 0x795D, 0x8F6B, 0x7E2E,
+	0x8F6C, 0x7C9B, 0x8F6D, 0x587E, 0x8F6E, 0x719F, 0x8F6F, 0x51FA,
+	0x8F70, 0x8853, 0x8F71, 0x8FF0, 0x8F72, 0x4FCA, 0x8F73, 0x5CFB,
+	0x8F74, 0x6625, 0x8F75, 0x77AC, 0x8F76, 0x7AE3, 0x8F77, 0x821C,
+	0x8F78, 0x99FF, 0x8F79, 0x51C6, 0x8F7A, 0x5FAA, 0x8F7B, 0x65EC,
+	0x8F7C, 0x696F, 0x8F7D, 0x6B89, 0x8F7E, 0x6DF3, 0x8F80, 0x6E96,
+	0x8F81, 0x6F64, 0x8F82, 0x76FE, 0x8F83, 0x7D14, 0x8F84, 0x5DE1,
+	0x8F85, 0x9075, 0x8F86, 0x9187, 0x8F87, 0x9806, 0x8F88, 0x51E6,
+	0x8F89, 0x521D, 0x8F8A, 0x6240, 0x8F8B, 0x6691, 0x8F8C, 0x66D9,
+	0x8F8D, 0x6E1A, 0x8F8E, 0x5EB6, 0x8F8F, 0x7DD2, 0x8F90, 0x7F72,
+	0x8F91, 0x66F8, 0x8F92, 0x85AF, 0x8F93, 0x85F7, 0x8F94, 0x8AF8,
+	0x8F95, 0x52A9, 0x8F96, 0x53D9, 0x8F97, 0x5973, 0x8F98, 0x5E8F,
+	0x8F99, 0x5F90, 0x8F9A, 0x6055, 0x8F9B, 0x92E4, 0x8F9C, 0x9664,
+	0x8F9D, 0x50B7, 0x8F9E, 0x511F, 0x8F9F, 0x52DD, 0x8FA0, 0x5320,
+	0x8FA1, 0x5347, 0x8FA2, 0x53EC, 0x8FA3, 0x54E8, 0x8FA4, 0x5546,
+	0x8FA5, 0x5531, 0x8FA6, 0x5617, 0x8FA7, 0x5968, 0x8FA8, 0x59BE,
+	0x8FA9, 0x5A3C, 0x8FAA, 0x5BB5, 0x8FAB, 0x5C06, 0x8FAC, 0x5C0F,
+	0x8FAD, 0x5C11, 0x8FAE, 0x5C1A, 0x8FAF, 0x5E84, 0x8FB0, 0x5E8A,
+	0x8FB1, 0x5EE0, 0x8FB2, 0x5F70, 0x8FB3, 0x627F, 0x8FB4, 0x6284,
+	0x8FB5, 0x62DB, 0x8FB6, 0x638C, 0x8FB7, 0x6377, 0x8FB8, 0x6607,
+	0x8FB9, 0x660C, 0x8FBA, 0x662D, 0x8FBB, 0x6676, 0x8FBC, 0x677E,
+	0x8FBD, 0x68A2, 0x8FBE, 0x6A1F, 0x8FBF, 0x6A35, 0x8FC0, 0x6CBC,
+	0x8FC1, 0x6D88, 0x8FC2, 0x6E09, 0x8FC3, 0x6E58, 0x8FC4, 0x713C,
+	0x8FC5, 0x7126, 0x8FC6, 0x7167, 0x8FC7, 0x75C7, 0x8FC8, 0x7701,
+	0x8FC9, 0x785D, 0x8FCA, 0x7901, 0x8FCB, 0x7965, 0x8FCC, 0x79F0,
+	0x8FCD, 0x7AE0, 0x8FCE, 0x7B11, 0x8FCF, 0x7CA7, 0x8FD0, 0x7D39,
+	0x8FD1, 0x8096, 0x8FD2, 0x83D6, 0x8FD3, 0x848B, 0x8FD4, 0x8549,
+	0x8FD5, 0x885D, 0x8FD6, 0x88F3, 0x8FD7, 0x8A1F, 0x8FD8, 0x8A3C,
+	0x8FD9, 0x8A54, 0x8FDA, 0x8A73, 0x8FDB, 0x8C61, 0x8FDC, 0x8CDE,
+	0x8FDD, 0x91A4, 0x8FDE, 0x9266, 0x8FDF, 0x937E, 0x8FE0, 0x9418,
+	0x8FE1, 0x969C, 0x8FE2, 0x9798, 0x8FE3, 0x4E0A, 0x8FE4, 0x4E08,
+	0x8FE5, 0x4E1E, 0x8FE6, 0x4E57, 0x8FE7, 0x5197, 0x8FE8, 0x5270,
+	0x8FE9, 0x57CE, 0x8FEA, 0x5834, 0x8FEB, 0x58CC, 0x8FEC, 0x5B22,
+	0x8FED, 0x5E38, 0x8FEE, 0x60C5, 0x8FEF, 0x64FE, 0x8FF0, 0x6761,
+	0x8FF1, 0x6756, 0x8FF2, 0x6D44, 0x8FF3, 0x72B6, 0x8FF4, 0x7573,
+	0x8FF5, 0x7A63, 0x8FF6, 0x84B8, 0x8FF7, 0x8B72, 0x8FF8, 0x91B8,
+	0x8FF9, 0x9320, 0x8FFA, 0x5631, 0x8FFB, 0x57F4, 0x8FFC, 0x98FE,
+	0x9040, 0x62ED, 0x9041, 0x690D, 0x9042, 0x6B96, 0x9043, 0x71ED,
+	0x9044, 0x7E54, 0x9045, 0x8077, 0x9046, 0x8272, 0x9047, 0x89E6,
+	0x9048, 0x98DF, 0x9049, 0x8755, 0x904A, 0x8FB1, 0x904B, 0x5C3B,
+	0x904C, 0x4F38, 0x904D, 0x4FE1, 0x904E, 0x4FB5, 0x904F, 0x5507,
+	0x9050, 0x5A20, 0x9051, 0x5BDD, 0x9052, 0x5BE9, 0x9053, 0x5FC3,
+	0x9054, 0x614E, 0x9055, 0x632F, 0x9056, 0x65B0, 0x9057, 0x664B,
+	0x9058, 0x68EE, 0x9059, 0x699B, 0x905A, 0x6D78, 0x905B, 0x6DF1,
+	0x905C, 0x7533, 0x905D, 0x75B9, 0x905E, 0x771F, 0x905F, 0x795E,
+	0x9060, 0x79E6, 0x9061, 0x7D33, 0x9062, 0x81E3, 0x9063, 0x82AF,
+	0x9064, 0x85AA, 0x9065, 0x89AA, 0x9066, 0x8A3A, 0x9067, 0x8EAB,
+	0x9068, 0x8F9B, 0x9069, 0x9032, 0x906A, 0x91DD, 0x906B, 0x9707,
+	0x906C, 0x4EBA, 0x906D, 0x4EC1, 0x906E, 0x5203, 0x906F, 0x5875,
+	0x9070, 0x58EC, 0x9071, 0x5C0B, 0x9072, 0x751A, 0x9073, 0x5C3D,
+	0x9074, 0x814E, 0x9075, 0x8A0A, 0x9076, 0x8FC5, 0x9077, 0x9663,
+	0x9078, 0x976D, 0x9079, 0x7B25, 0x907A, 0x8ACF, 0x907B, 0x9808,
+	0x907C, 0x9162, 0x907D, 0x56F3, 0x907E, 0x53A8, 0x9080, 0x9017,
+	0x9081, 0x5439, 0x9082, 0x5782, 0x9083, 0x5E25, 0x9084, 0x63A8,
+	0x9085, 0x6C34, 0x9086, 0x708A, 0x9087, 0x7761, 0x9088, 0x7C8B,
+	0x9089, 0x7FE0, 0x908A, 0x8870, 0x908B, 0x9042, 0x908C, 0x9154,
+	0x908D, 0x9310, 0x908E, 0x9318, 0x908F, 0x968F, 0x9090, 0x745E,
+	0x9091, 0x9AC4, 0x9092, 0x5D07, 0x9093, 0x5D69, 0x9094, 0x6570,
+	0x9095, 0x67A2, 0x9096, 0x8DA8, 0x9097, 0x96DB, 0x9098, 0x636E,
+	0x9099, 0x6749, 0x909A, 0x6919, 0x909B, 0x83C5, 0x909C, 0x9817,
+	0x909D, 0x96C0, 0x909E, 0x88FE, 0x909F, 0x6F84, 0x90A0, 0x647A,
+	0x90A1, 0x5BF8, 0x90A2, 0x4E16, 0x90A3, 0x702C, 0x90A4, 0x755D,
+	0x90A5, 0x662F, 0x90A6, 0x51C4, 0x90A7, 0x5236, 0x90A8, 0x52E2,
+	0x90A9, 0x59D3, 0x90AA, 0x5F81, 0x90AB, 0x6027, 0x90AC, 0x6210,
+	0x90AD, 0x653F, 0x90AE, 0x6574, 0x90AF, 0x661F, 0x90B0, 0x6674,
+	0x90B1, 0x68F2, 0x90B2, 0x6816, 0x90B3, 0x6B63, 0x90B4, 0x6E05,
+	0x90B5, 0x7272, 0x90B6, 0x751F, 0x90B7, 0x76DB, 0x90B8, 0x7CBE,
+	0x90B9, 0x8056, 0x90BA, 0x58F0, 0x90BB, 0x88FD, 0x90BC, 0x897F,
+	0x90BD, 0x8AA0, 0x90BE, 0x8A93, 0x90BF, 0x8ACB, 0x90C0, 0x901D,
+	0x90C1, 0x9192, 0x90C2, 0x9752, 0x90C3, 0x9759, 0x90C4, 0x6589,
+	0x90C5, 0x7A0E, 0x90C6, 0x8106, 0x90C7, 0x96BB, 0x90C8, 0x5E2D,
+	0x90C9, 0x60DC, 0x90CA, 0x621A, 0x90CB, 0x65A5, 0x90CC, 0x6614,
+	0x90CD, 0x6790, 0x90CE, 0x77F3, 0x90CF, 0x7A4D, 0x90D0, 0x7C4D,
+	0x90D1, 0x7E3E, 0x90D2, 0x810A, 0x90D3, 0x8CAC, 0x90D4, 0x8D64,
+	0x90D5, 0x8DE1, 0x90D6, 0x8E5F, 0x90D7, 0x78A9, 0x90D8, 0x5207,
+	0x90D9, 0x62D9, 0x90DA, 0x63A5, 0x90DB, 0x6442, 0x90DC, 0x6298,
+	0x90DD, 0x8A2D, 0x90DE, 0x7A83, 0x90DF, 0x7BC0, 0x90E0, 0x8AAC,
+	0x90E1, 0x96EA, 0x90E2, 0x7D76, 0x90E3, 0x820C, 0x90E4, 0x8749,
+	0x90E5, 0x4ED9, 0x90E6, 0x5148, 0x90E7, 0x5343, 0x90E8, 0x5360,
+	0x90E9, 0x5BA3, 0x90EA, 0x5C02, 0x90EB, 0x5C16, 0x90EC, 0x5DDD,
+	0x90ED, 0x6226, 0x90EE, 0x6247, 0x90EF, 0x64B0, 0x90F0, 0x6813,
+	0x90F1, 0x6834, 0x90F2, 0x6CC9, 0x90F3, 0x6D45, 0x90F4, 0x6D17,
+	0x90F5, 0x67D3, 0x90F6, 0x6F5C, 0x90F7, 0x714E, 0x90F8, 0x717D,
+	0x90F9, 0x65CB, 0x90FA, 0x7A7F, 0x90FB, 0x7BAD, 0x90FC, 0x7DDA,
+	0x9140, 0x7E4A, 0x9141, 0x7FA8, 0x9142, 0x817A, 0x9143, 0x821B,
+	0x9144, 0x8239, 0x9145, 0x85A6, 0x9146, 0x8A6E, 0x9147, 0x8CCE,
+	0x9148, 0x8DF5, 0x9149, 0x9078, 0x914A, 0x9077, 0x914B, 0x92AD,
+	0x914C, 0x9291, 0x914D, 0x9583, 0x914E, 0x9BAE, 0x914F, 0x524D,
+	0x9150, 0x5584, 0x9151, 0x6F38, 0x9152, 0x7136, 0x9153, 0x5168,
+	0x9154, 0x7985, 0x9155, 0x7E55, 0x9156, 0x81B3, 0x9157, 0x7CCE,
+	0x9158, 0x564C, 0x9159, 0x5851, 0x915A, 0x5CA8, 0x915B, 0x63AA,
+	0x915C, 0x66FE, 0x915D, 0x66FD, 0x915E, 0x695A, 0x915F, 0x72D9,
+	0x9160, 0x758F, 0x9161, 0x758E, 0x9162, 0x790E, 0x9163, 0x7956,
+	0x9164, 0x79DF, 0x9165, 0x7C97, 0x9166, 0x7D20, 0x9167, 0x7D44,
+	0x9168, 0x8607, 0x9169, 0x8A34, 0x916A, 0x963B, 0x916B, 0x9061,
+	0x916C, 0x9F20, 0x916D, 0x50E7, 0x916E, 0x5275, 0x916F, 0x53CC,
+	0x9170, 0x53E2, 0x9171, 0x5009, 0x9172, 0x55AA, 0x9173, 0x58EE,
+	0x9174, 0x594F, 0x9175, 0x723D, 0x9176, 0x5B8B, 0x9177, 0x5C64,
+	0x9178, 0x531D, 0x9179, 0x60E3, 0x917A, 0x60F3, 0x917B, 0x635C,
+	0x917C, 0x6383, 0x917D, 0x633F, 0x917E, 0x63BB, 0x9180, 0x64CD,
+	0x9181, 0x65E9, 0x9182, 0x66F9, 0x9183, 0x5DE3, 0x9184, 0x69CD,
+	0x9185, 0x69FD, 0x9186, 0x6F15, 0x9187, 0x71E5, 0x9188, 0x4E89,
+	0x9189, 0x75E9, 0x918A, 0x76F8, 0x918B, 0x7A93, 0x918C, 0x7CDF,
+	0x918D, 0x7DCF, 0x918E, 0x7D9C, 0x918F, 0x8061, 0x9190, 0x8349,
+	0x9191, 0x8358, 0x9192, 0x846C, 0x9193, 0x84BC, 0x9194, 0x85FB,
+	0x9195, 0x88C5, 0x9196, 0x8D70, 0x9197, 0x9001, 0x9198, 0x906D,
+	0x9199, 0x9397, 0x919A, 0x971C, 0x919B, 0x9A12, 0x919C, 0x50CF,
+	0x919D, 0x5897, 0x919E, 0x618E, 0x919F, 0x81D3, 0x91A0, 0x8535,
+	0x91A1, 0x8D08, 0x91A2, 0x9020, 0x91A3, 0x4FC3, 0x91A4, 0x5074,
+	0x91A5, 0x5247, 0x91A6, 0x5373, 0x91A7, 0x606F, 0x91A8, 0x6349,
+	0x91A9, 0x675F, 0x91AA, 0x6E2C, 0x91AB, 0x8DB3, 0x91AC, 0x901F,
+	0x91AD, 0x4FD7, 0x91AE, 0x5C5E, 0x91AF, 0x8CCA, 0x91B0, 0x65CF,
+	0x91B1, 0x7D9A, 0x91B2, 0x5352, 0x91B3, 0x8896, 0x91B4, 0x5176,
+	0x91B5, 0x63C3, 0x91B6, 0x5B58, 0x91B7, 0x5B6B, 0x91B8, 0x5C0A,
+	0x91B9, 0x640D, 0x91BA, 0x6751, 0x91BB, 0x905C, 0x91BC, 0x4ED6,
+	0x91BD, 0x591A, 0x91BE, 0x592A, 0x91BF, 0x6C70, 0x91C0, 0x8A51,
+	0x91C1, 0x553E, 0x91C2, 0x5815, 0x91C3, 0x59A5, 0x91C4, 0x60F0,
+	0x91C5, 0x6253, 0x91C6, 0x67C1, 0x91C7, 0x8235, 0x91C8, 0x6955,
+	0x91C9, 0x9640, 0x91CA, 0x99C4, 0x91CB, 0x9A28, 0x91CC, 0x4F53,
+	0x91CD, 0x5806, 0x91CE, 0x5BFE, 0x91CF, 0x8010, 0x91D0, 0x5CB1,
+	0x91D1, 0x5E2F, 0x91D2, 0x5F85, 0x91D3, 0x6020, 0x91D4, 0x614B,
+	0x91D5, 0x6234, 0x91D6, 0x66FF, 0x91D7, 0x6CF0, 0x91D8, 0x6EDE,
+	0x91D9, 0x80CE, 0x91DA, 0x817F, 0x91DB, 0x82D4, 0x91DC, 0x888B,
+	0x91DD, 0x8CB8, 0x91DE, 0x9000, 0x91DF, 0x902E, 0x91E0, 0x968A,
+	0x91E1, 0x9EDB, 0x91E2, 0x9BDB, 0x91E3, 0x4EE3, 0x91E4, 0x53F0,
+	0x91E5, 0x5927, 0x91E6, 0x7B2C, 0x91E7, 0x918D, 0x91E8, 0x984C,
+	0x91E9, 0x9DF9, 0x91EA, 0x6EDD, 0x91EB, 0x7027, 0x91EC, 0x5353,
+	0x91ED, 0x5544, 0x91EE, 0x5B85, 0x91EF, 0x6258, 0x91F0, 0x629E,
+	0x91F1, 0x62D3, 0x91F2, 0x6CA2, 0x91F3, 0x6FEF, 0x91F4, 0x7422,
+	0x91F5, 0x8A17, 0x91F6, 0x9438, 0x91F7, 0x6FC1, 0x91F8, 0x8AFE,
+	0x91F9, 0x8338, 0x91FA, 0x51E7, 0x91FB, 0x86F8, 0x91FC, 0x53EA,
+	0x9240, 0x53E9, 0x9241, 0x4F46, 0x9242, 0x9054, 0x9243, 0x8FB0,
+	0x9244, 0x596A, 0x9245, 0x8131, 0x9246, 0x5DFD, 0x9247, 0x7AEA,
+	0x9248, 0x8FBF, 0x9249, 0x68DA, 0x924A, 0x8C37, 0x924B, 0x72F8,
+	0x924C, 0x9C48, 0x924D, 0x6A3D, 0x924E, 0x8AB0, 0x924F, 0x4E39,
+	0x9250, 0x5358, 0x9251, 0x5606, 0x9252, 0x5766, 0x9253, 0x62C5,
+	0x9254, 0x63A2, 0x9255, 0x65E6, 0x9256, 0x6B4E, 0x9257, 0x6DE1,
+	0x9258, 0x6E5B, 0x9259, 0x70AD, 0x925A, 0x77ED, 0x925B, 0x7AEF,
+	0x925C, 0x7BAA, 0x925D, 0x7DBB, 0x925E, 0x803D, 0x925F, 0x80C6,
+	0x9260, 0x86CB, 0x9261, 0x8A95, 0x9262, 0x935B, 0x9263, 0x56E3,
+	0x9264, 0x58C7, 0x9265, 0x5F3E, 0x9266, 0x65AD, 0x9267, 0x6696,
+	0x9268, 0x6A80, 0x9269, 0x6BB5, 0x926A, 0x7537, 0x926B, 0x8AC7,
+	0x926C, 0x5024, 0x926D, 0x77E5, 0x926E, 0x5730, 0x926F, 0x5F1B,
+	0x9270, 0x6065, 0x9271, 0x667A, 0x9272, 0x6C60, 0x9273, 0x75F4,
+	0x9274, 0x7A1A, 0x9275, 0x7F6E, 0x9276, 0x81F4, 0x9277, 0x8718,
+	0x9278, 0x9045, 0x9279, 0x99B3, 0x927A, 0x7BC9, 0x927B, 0x755C,
+	0x927C, 0x7AF9, 0x927D, 0x7B51, 0x927E, 0x84C4, 0x9280, 0x9010,
+	0x9281, 0x79E9, 0x9282, 0x7A92, 0x9283, 0x8336, 0x9284, 0x5AE1,
+	0x9285, 0x7740, 0x9286, 0x4E2D, 0x9287, 0x4EF2, 0x9288, 0x5B99,
+	0x9289, 0x5FE0, 0x928A, 0x62BD, 0x928B, 0x663C, 0x928C, 0x67F1,
+	0x928D, 0x6CE8, 0x928E, 0x866B, 0x928F, 0x8877, 0x9290, 0x8A3B,
+	0x9291, 0x914E, 0x9292, 0x92F3, 0x9293, 0x99D0, 0x9294, 0x6A17,
+	0x9295, 0x7026, 0x9296, 0x732A, 0x9297, 0x82E7, 0x9298, 0x8457,
+	0x9299, 0x8CAF, 0x929A, 0x4E01, 0x929B, 0x5146, 0x929C, 0x51CB,
+	0x929D, 0x558B, 0x929E, 0x5BF5, 0x929F, 0x5E16, 0x92A0, 0x5E33,
+	0x92A1, 0x5E81, 0x92A2, 0x5F14, 0x92A3, 0x5F35, 0x92A4, 0x5F6B,
+	0x92A5, 0x5FB4, 0x92A6, 0x61F2, 0x92A7, 0x6311, 0x92A8, 0x66A2,
+	0x92A9, 0x671D, 0x92AA, 0x6F6E, 0x92AB, 0x7252, 0x92AC, 0x753A,
+	0x92AD, 0x773A, 0x92AE, 0x8074, 0x92AF, 0x8139, 0x92B0, 0x8178,
+	0x92B1, 0x8776, 0x92B2, 0x8ABF, 0x92B3, 0x8ADC, 0x92B4, 0x8D85,
+	0x92B5, 0x8DF3, 0x92B6, 0x929A, 0x92B7, 0x9577, 0x92B8, 0x9802,
+	0x92B9, 0x9CE5, 0x92BA, 0x52C5, 0x92BB, 0x6357, 0x92BC, 0x76F4,
+	0x92BD, 0x6715, 0x92BE, 0x6C88, 0x92BF, 0x73CD, 0x92C0, 0x8CC3,
+	0x92C1, 0x93AE, 0x92C2, 0x9673, 0x92C3, 0x6D25, 0x92C4, 0x589C,
+	0x92C5, 0x690E, 0x92C6, 0x69CC, 0x92C7, 0x8FFD, 0x92C8, 0x939A,
+	0x92C9, 0x75DB, 0x92CA, 0x901A, 0x92CB, 0x585A, 0x92CC, 0x6802,
+	0x92CD, 0x63B4, 0x92CE, 0x69FB, 0x92CF, 0x4F43, 0x92D0, 0x6F2C,
+	0x92D1, 0x67D8, 0x92D2, 0x8FBB, 0x92D3, 0x8526, 0x92D4, 0x7DB4,
+	0x92D5, 0x9354, 0x92D6, 0x693F, 0x92D7, 0x6F70, 0x92D8, 0x576A,
+	0x92D9, 0x58F7, 0x92DA, 0x5B2C, 0x92DB, 0x7D2C, 0x92DC, 0x722A,
+	0x92DD, 0x540A, 0x92DE, 0x91E3, 0x92DF, 0x9DB4, 0x92E0, 0x4EAD,
+	0x92E1, 0x4F4E, 0x92E2, 0x505C, 0x92E3, 0x5075, 0x92E4, 0x5243,
+	0x92E5, 0x8C9E, 0x92E6, 0x5448, 0x92E7, 0x5824, 0x92E8, 0x5B9A,
+	0x92E9, 0x5E1D, 0x92EA, 0x5E95, 0x92EB, 0x5EAD, 0x92EC, 0x5EF7,
+	0x92ED, 0x5F1F, 0x92EE, 0x608C, 0x92EF, 0x62B5, 0x92F0, 0x633A,
+	0x92F1, 0x63D0, 0x92F2, 0x68AF, 0x92F3, 0x6C40, 0x92F4, 0x7887,
+	0x92F5, 0x798E, 0x92F6, 0x7A0B, 0x92F7, 0x7DE0, 0x92F8, 0x8247,
+	0x92F9, 0x8A02, 0x92FA, 0x8AE6, 0x92FB, 0x8E44, 0x92FC, 0x9013,
+	0x9340, 0x90B8, 0x9341, 0x912D, 0x9342, 0x91D8, 0x9343, 0x9F0E,
+	0x9344, 0x6CE5, 0x9345, 0x6458, 0x9346, 0x64E2, 0x9347, 0x6575,
+	0x9348, 0x6EF4, 0x9349, 0x7684, 0x934A, 0x7B1B, 0x934B, 0x9069,
+	0x934C, 0x93D1, 0x934D, 0x6EBA, 0x934E, 0x54F2, 0x934F, 0x5FB9,
+	0x9350, 0x64A4, 0x9351, 0x8F4D, 0x9352, 0x8FED, 0x9353, 0x9244,
+	0x9354, 0x5178, 0x9355, 0x586B, 0x9356, 0x5929, 0x9357, 0x5C55,
+	0x9358, 0x5E97, 0x9359, 0x6DFB, 0x935A, 0x7E8F, 0x935B, 0x751C,
+	0x935C, 0x8CBC, 0x935D, 0x8EE2, 0x935E, 0x985B, 0x935F, 0x70B9,
+	0x9360, 0x4F1D, 0x9361, 0x6BBF, 0x9362, 0x6FB1, 0x9363, 0x7530,
+	0x9364, 0x96FB, 0x9365, 0x514E, 0x9366, 0x5410, 0x9367, 0x5835,
+	0x9368, 0x5857, 0x9369, 0x59AC, 0x936A, 0x5C60, 0x936B, 0x5F92,
+	0x936C, 0x6597, 0x936D, 0x675C, 0x936E, 0x6E21, 0x936F, 0x767B,
+	0x9370, 0x83DF, 0x9371, 0x8CED, 0x9372, 0x9014, 0x9373, 0x90FD,
+	0x9374, 0x934D, 0x9375, 0x7825, 0x9376, 0x783A, 0x9377, 0x52AA,
+	0x9378, 0x5EA6, 0x9379, 0x571F, 0x937A, 0x5974, 0x937B, 0x6012,
+	0x937C, 0x5012, 0x937D, 0x515A, 0x937E, 0x51AC, 0x9380, 0x51CD,
+	0x9381, 0x5200, 0x9382, 0x5510, 0x9383, 0x5854, 0x9384, 0x5858,
+	0x9385, 0x5957, 0x9386, 0x5B95, 0x9387, 0x5CF6, 0x9388, 0x5D8B,
+	0x9389, 0x60BC, 0x938A, 0x6295, 0x938B, 0x642D, 0x938C, 0x6771,
+	0x938D, 0x6843, 0x938E, 0x68BC, 0x938F, 0x68DF, 0x9390, 0x76D7,
+	0x9391, 0x6DD8, 0x9392, 0x6E6F, 0x9393, 0x6D9B, 0x9394, 0x706F,
+	0x9395, 0x71C8, 0x9396, 0x5F53, 0x9397, 0x75D8, 0x9398, 0x7977,
+	0x9399, 0x7B49, 0x939A, 0x7B54, 0x939B, 0x7B52, 0x939C, 0x7CD6,
+	0x939D, 0x7D71, 0x939E, 0x5230, 0x939F, 0x8463, 0x93A0, 0x8569,
+	0x93A1, 0x85E4, 0x93A2, 0x8A0E, 0x93A3, 0x8B04, 0x93A4, 0x8C46,
+	0x93A5, 0x8E0F, 0x93A6, 0x9003, 0x93A7, 0x900F, 0x93A8, 0x9419,
+	0x93A9, 0x9676, 0x93AA, 0x982D, 0x93AB, 0x9A30, 0x93AC, 0x95D8,
+	0x93AD, 0x50CD, 0x93AE, 0x52D5, 0x93AF, 0x540C, 0x93B0, 0x5802,
+	0x93B1, 0x5C0E, 0x93B2, 0x61A7, 0x93B3, 0x649E, 0x93B4, 0x6D1E,
+	0x93B5, 0x77B3, 0x93B6, 0x7AE5, 0x93B7, 0x80F4, 0x93B8, 0x8404,
+	0x93B9, 0x9053, 0x93BA, 0x9285, 0x93BB, 0x5CE0, 0x93BC, 0x9D07,
+	0x93BD, 0x533F, 0x93BE, 0x5F97, 0x93BF, 0x5FB3, 0x93C0, 0x6D9C,
+	0x93C1, 0x7279, 0x93C2, 0x7763, 0x93C3, 0x79BF, 0x93C4, 0x7BE4,
+	0x93C5, 0x6BD2, 0x93C6, 0x72EC, 0x93C7, 0x8AAD, 0x93C8, 0x6803,
+	0x93C9, 0x6A61, 0x93CA, 0x51F8, 0x93CB, 0x7A81, 0x93CC, 0x6934,
+	0x93CD, 0x5C4A, 0x93CE, 0x9CF6, 0x93CF, 0x82EB, 0x93D0, 0x5BC5,
+	0x93D1, 0x9149, 0x93D2, 0x701E, 0x93D3, 0x5678, 0x93D4, 0x5C6F,
+	0x93D5, 0x60C7, 0x93D6, 0x6566, 0x93D7, 0x6C8C, 0x93D8, 0x8C5A,
+	0x93D9, 0x9041, 0x93DA, 0x9813, 0x93DB, 0x5451, 0x93DC, 0x66C7,
+	0x93DD, 0x920D, 0x93DE, 0x5948, 0x93DF, 0x90A3, 0x93E0, 0x5185,
+	0x93E1, 0x4E4D, 0x93E2, 0x51EA, 0x93E3, 0x8599, 0x93E4, 0x8B0E,
+	0x93E5, 0x7058, 0x93E6, 0x637A, 0x93E7, 0x934B, 0x93E8, 0x6962,
+	0x93E9, 0x99B4, 0x93EA, 0x7E04, 0x93EB, 0x7577, 0x93EC, 0x5357,
+	0x93ED, 0x6960, 0x93EE, 0x8EDF, 0x93EF, 0x96E3, 0x93F0, 0x6C5D,
+	0x93F1, 0x4E8C, 0x93F2, 0x5C3C, 0x93F3, 0x5F10, 0x93F4, 0x8FE9,
+	0x93F5, 0x5302, 0x93F6, 0x8CD1, 0x93F7, 0x8089, 0x93F8, 0x8679,
+	0x93F9, 0x5EFF, 0x93FA, 0x65E5, 0x93FB, 0x4E73, 0x93FC, 0x5165,
+	0x9440, 0x5982, 0x9441, 0x5C3F, 0x9442, 0x97EE, 0x9443, 0x4EFB,
+	0x9444, 0x598A, 0x9445, 0x5FCD, 0x9446, 0x8A8D, 0x9447, 0x6FE1,
+	0x9448, 0x79B0, 0x9449, 0x7962, 0x944A, 0x5BE7, 0x944B, 0x8471,
+	0x944C, 0x732B, 0x944D, 0x71B1, 0x944E, 0x5E74, 0x944F, 0x5FF5,
+	0x9450, 0x637B, 0x9451, 0x649A, 0x9452, 0x71C3, 0x9453, 0x7C98,
+	0x9454, 0x4E43, 0x9455, 0x5EFC, 0x9456, 0x4E4B, 0x9457, 0x57DC,
+	0x9458, 0x56A2, 0x9459, 0x60A9, 0x945A, 0x6FC3, 0x945B, 0x7D0D,
+	0x945C, 0x80FD, 0x945D, 0x8133, 0x945E, 0x81BF, 0x945F, 0x8FB2,
+	0x9460, 0x8997, 0x9461, 0x86A4, 0x9462, 0x5DF4, 0x9463, 0x628A,
+	0x9464, 0x64AD, 0x9465, 0x8987, 0x9466, 0x6777, 0x9467, 0x6CE2,
+	0x9468, 0x6D3E, 0x9469, 0x7436, 0x946A, 0x7834, 0x946B, 0x5A46,
+	0x946C, 0x7F75, 0x946D, 0x82AD, 0x946E, 0x99AC, 0x946F, 0x4FF3,
+	0x9470, 0x5EC3, 0x9471, 0x62DD, 0x9472, 0x6392, 0x9473, 0x6557,
+	0x9474, 0x676F, 0x9475, 0x76C3, 0x9476, 0x724C, 0x9477, 0x80CC,
+	0x9478, 0x80BA, 0x9479, 0x8F29, 0x947A, 0x914D, 0x947B, 0x500D,
+	0x947C, 0x57F9, 0x947D, 0x5A92, 0x947E, 0x6885, 0x9480, 0x6973,
+	0x9481, 0x7164, 0x9482, 0x72FD, 0x9483, 0x8CB7, 0x9484, 0x58F2,
+	0x9485, 0x8CE0, 0x9486, 0x966A, 0x9487, 0x9019, 0x9488, 0x877F,
+	0x9489, 0x79E4, 0x948A, 0x77E7, 0x948B, 0x8429, 0x948C, 0x4F2F,
+	0x948D, 0x5265, 0x948E, 0x535A, 0x948F, 0x62CD, 0x9490, 0x67CF,
+	0x9491, 0x6CCA, 0x9492, 0x767D, 0x9493, 0x7B94, 0x9494, 0x7C95,
+	0x9495, 0x8236, 0x9496, 0x8584, 0x9497, 0x8FEB, 0x9498, 0x66DD,
+	0x9499, 0x6F20, 0x949A, 0x7206, 0x949B, 0x7E1B, 0x949C, 0x83AB,
+	0x949D, 0x99C1, 0x949E, 0x9EA6, 0x949F, 0x51FD, 0x94A0, 0x7BB1,
+	0x94A1, 0x7872, 0x94A2, 0x7BB8, 0x94A3, 0x8087, 0x94A4, 0x7B48,
+	0x94A5, 0x6AE8, 0x94A6, 0x5E61, 0x94A7, 0x808C, 0x94A8, 0x7551,
+	0x94A9, 0x7560, 0x94AA, 0x516B, 0x94AB, 0x9262, 0x94AC, 0x6E8C,
+	0x94AD, 0x767A, 0x94AE, 0x9197, 0x94AF, 0x9AEA, 0x94B0, 0x4F10,
+	0x94B1, 0x7F70, 0x94B2, 0x629C, 0x94B3, 0x7B4F, 0x94B4, 0x95A5,
+	0x94B5, 0x9CE9, 0x94B6, 0x567A, 0x94B7, 0x5859, 0x94B8, 0x86E4,
+	0x94B9, 0x96BC, 0x94BA, 0x4F34, 0x94BB, 0x5224, 0x94BC, 0x534A,
+	0x94BD, 0x53CD, 0x94BE, 0x53DB, 0x94BF, 0x5E06, 0x94C0, 0x642C,
+	0x94C1, 0x6591, 0x94C2, 0x677F, 0x94C3, 0x6C3E, 0x94C4, 0x6C4E,
+	0x94C5, 0x7248, 0x94C6, 0x72AF, 0x94C7, 0x73ED, 0x94C8, 0x7554,
+	0x94C9, 0x7E41, 0x94CA, 0x822C, 0x94CB, 0x85E9, 0x94CC, 0x8CA9,
+	0x94CD, 0x7BC4, 0x94CE, 0x91C6, 0x94CF, 0x7169, 0x94D0, 0x9812,
+	0x94D1, 0x98EF, 0x94D2, 0x633D, 0x94D3, 0x6669, 0x94D4, 0x756A,
+	0x94D5, 0x76E4, 0x94D6, 0x78D0, 0x94D7, 0x8543, 0x94D8, 0x86EE,
+	0x94D9, 0x532A, 0x94DA, 0x5351, 0x94DB, 0x5426, 0x94DC, 0x5983,
+	0x94DD, 0x5E87, 0x94DE, 0x5F7C, 0x94DF, 0x60B2, 0x94E0, 0x6249,
+	0x94E1, 0x6279, 0x94E2, 0x62AB, 0x94E3, 0x6590, 0x94E4, 0x6BD4,
+	0x94E5, 0x6CCC, 0x94E6, 0x75B2, 0x94E7, 0x76AE, 0x94E8, 0x7891,
+	0x94E9, 0x79D8, 0x94EA, 0x7DCB, 0x94EB, 0x7F77, 0x94EC, 0x80A5,
+	0x94ED, 0x88AB, 0x94EE, 0x8AB9, 0x94EF, 0x8CBB, 0x94F0, 0x907F,
+	0x94F1, 0x975E, 0x94F2, 0x98DB, 0x94F3, 0x6A0B, 0x94F4, 0x7C38,
+	0x94F5, 0x5099, 0x94F6, 0x5C3E, 0x94F7, 0x5FAE, 0x94F8, 0x6787,
+	0x94F9, 0x6BD8, 0x94FA, 0x7435, 0x94FB, 0x7709, 0x94FC, 0x7F8E,
+	0x9540, 0x9F3B, 0x9541, 0x67CA, 0x9542, 0x7A17, 0x9543, 0x5339,
+	0x9544, 0x758B, 0x9545, 0x9AED, 0x9546, 0x5F66, 0x9547, 0x819D,
+	0x9548, 0x83F1, 0x9549, 0x8098, 0x954A, 0x5F3C, 0x954B, 0x5FC5,
+	0x954C, 0x7562, 0x954D, 0x7B46, 0x954E, 0x903C, 0x954F, 0x6867,
+	0x9550, 0x59EB, 0x9551, 0x5A9B, 0x9552, 0x7D10, 0x9553, 0x767E,
+	0x9554, 0x8B2C, 0x9555, 0x4FF5, 0x9556, 0x5F6A, 0x9557, 0x6A19,
+	0x9558, 0x6C37, 0x9559, 0x6F02, 0x955A, 0x74E2, 0x955B, 0x7968,
+	0x955C, 0x8868, 0x955D, 0x8A55, 0x955E, 0x8C79, 0x955F, 0x5EDF,
+	0x9560, 0x63CF, 0x9561, 0x75C5, 0x9562, 0x79D2, 0x9563, 0x82D7,
+	0x9564, 0x9328, 0x9565, 0x92F2, 0x9566, 0x849C, 0x9567, 0x86ED,
+	0x9568, 0x9C2D, 0x9569, 0x54C1, 0x956A, 0x5F6C, 0x956B, 0x658C,
+	0x956C, 0x6D5C, 0x956D, 0x7015, 0x956E, 0x8CA7, 0x956F, 0x8CD3,
+	0x9570, 0x983B, 0x9571, 0x654F, 0x9572, 0x74F6, 0x9573, 0x4E0D,
+	0x9574, 0x4ED8, 0x9575, 0x57E0, 0x9576, 0x592B, 0x9577, 0x5A66,
+	0x9578, 0x5BCC, 0x9579, 0x51A8, 0x957A, 0x5E03, 0x957B, 0x5E9C,
+	0x957C, 0x6016, 0x957D, 0x6276, 0x957E, 0x6577, 0x9580, 0x65A7,
+	0x9581, 0x666E, 0x9582, 0x6D6E, 0x9583, 0x7236, 0x9584, 0x7B26,
+	0x9585, 0x8150, 0x9586, 0x819A, 0x9587, 0x8299, 0x9588, 0x8B5C,
+	0x9589, 0x8CA0, 0x958A, 0x8CE6, 0x958B, 0x8D74, 0x958C, 0x961C,
+	0x958D, 0x9644, 0x958E, 0x4FAE, 0x958F, 0x64AB, 0x9590, 0x6B66,
+	0x9591, 0x821E, 0x9592, 0x8461, 0x9593, 0x856A, 0x9594, 0x90E8,
+	0x9595, 0x5C01, 0x9596, 0x6953, 0x9597, 0x98A8, 0x9598, 0x847A,
+	0x9599, 0x8557, 0x959A, 0x4F0F, 0x959B, 0x526F, 0x959C, 0x5FA9,
+	0x959D, 0x5E45, 0x959E, 0x670D, 0x959F, 0x798F, 0x95A0, 0x8179,
+	0x95A1, 0x8907, 0x95A2, 0x8986, 0x95A3, 0x6DF5, 0x95A4, 0x5F17,
+	0x95A5, 0x6255, 0x95A6, 0x6CB8, 0x95A7, 0x4ECF, 0x95A8, 0x7269,
+	0x95A9, 0x9B92, 0x95AA, 0x5206, 0x95AB, 0x543B, 0x95AC, 0x5674,
+	0x95AD, 0x58B3, 0x95AE, 0x61A4, 0x95AF, 0x626E, 0x95B0, 0x711A,
+	0x95B1, 0x596E, 0x95B2, 0x7C89, 0x95B3, 0x7CDE, 0x95B4, 0x7D1B,
+	0x95B5, 0x96F0, 0x95B6, 0x6587, 0x95B7, 0x805E, 0x95B8, 0x4E19,
+	0x95B9, 0x4F75, 0x95BA, 0x5175, 0x95BB, 0x5840, 0x95BC, 0x5E63,
+	0x95BD, 0x5E73, 0x95BE, 0x5F0A, 0x95BF, 0x67C4, 0x95C0, 0x4E26,
+	0x95C1, 0x853D, 0x95C2, 0x9589, 0x95C3, 0x965B, 0x95C4, 0x7C73,
+	0x95C5, 0x9801, 0x95C6, 0x50FB, 0x95C7, 0x58C1, 0x95C8, 0x7656,
+	0x95C9, 0x78A7, 0x95CA, 0x5225, 0x95CB, 0x77A5, 0x95CC, 0x8511,
+	0x95CD, 0x7B86, 0x95CE, 0x504F, 0x95CF, 0x5909, 0x95D0, 0x7247,
+	0x95D1, 0x7BC7, 0x95D2, 0x7DE8, 0x95D3, 0x8FBA, 0x95D4, 0x8FD4,
+	0x95D5, 0x904D, 0x95D6, 0x4FBF, 0x95D7, 0x52C9, 0x95D8, 0x5A29,
+	0x95D9, 0x5F01, 0x95DA, 0x97AD, 0x95DB, 0x4FDD, 0x95DC, 0x8217,
+	0x95DD, 0x92EA, 0x95DE, 0x5703, 0x95DF, 0x6355, 0x95E0, 0x6B69,
+	0x95E1, 0x752B, 0x95E2, 0x88DC, 0x95E3, 0x8F14, 0x95E4, 0x7A42,
+	0x95E5, 0x52DF, 0x95E6, 0x5893, 0x95E7, 0x6155, 0x95E8, 0x620A,
+	0x95E9, 0x66AE, 0x95EA, 0x6BCD, 0x95EB, 0x7C3F, 0x95EC, 0x83E9,
+	0x95ED, 0x5023, 0x95EE, 0x4FF8, 0x95EF, 0x5305, 0x95F0, 0x5446,
+	0x95F1, 0x5831, 0x95F2, 0x5949, 0x95F3, 0x5B9D, 0x95F4, 0x5CF0,
+	0x95F5, 0x5CEF, 0x95F6, 0x5D29, 0x95F7, 0x5E96, 0x95F8, 0x62B1,
+	0x95F9, 0x6367, 0x95FA, 0x653E, 0x95FB, 0x65B9, 0x95FC, 0x670B,
+	0x9640, 0x6CD5, 0x9641, 0x6CE1, 0x9642, 0x70F9, 0x9643, 0x7832,
+	0x9644, 0x7E2B, 0x9645, 0x80DE, 0x9646, 0x82B3, 0x9647, 0x840C,
+	0x9648, 0x84EC, 0x9649, 0x8702, 0x964A, 0x8912, 0x964B, 0x8A2A,
+	0x964C, 0x8C4A, 0x964D, 0x90A6, 0x964E, 0x92D2, 0x964F, 0x98FD,
+	0x9650, 0x9CF3, 0x9651, 0x9D6C, 0x9652, 0x4E4F, 0x9653, 0x4EA1,
+	0x9654, 0x508D, 0x9655, 0x5256, 0x9656, 0x574A, 0x9657, 0x59A8,
+	0x9658, 0x5E3D, 0x9659, 0x5FD8, 0x965A, 0x5FD9, 0x965B, 0x623F,
+	0x965C, 0x66B4, 0x965D, 0x671B, 0x965E, 0x67D0, 0x965F, 0x68D2,
+	0x9660, 0x5192, 0x9661, 0x7D21, 0x9662, 0x80AA, 0x9663, 0x81A8,
+	0x9664, 0x8B00, 0x9665, 0x8C8C, 0x9666, 0x8CBF, 0x9667, 0x927E,
+	0x9668, 0x9632, 0x9669, 0x5420, 0x966A, 0x982C, 0x966B, 0x5317,
+	0x966C, 0x50D5, 0x966D, 0x535C, 0x966E, 0x58A8, 0x966F, 0x64B2,
+	0x9670, 0x6734, 0x9671, 0x7267, 0x9672, 0x7766, 0x9673, 0x7A46,
+	0x9674, 0x91E6, 0x9675, 0x52C3, 0x9676, 0x6CA1, 0x9677, 0x6B86,
+	0x9678, 0x5800, 0x9679, 0x5E4C, 0x967A, 0x5954, 0x967B, 0x672C,
+	0x967C, 0x7FFB, 0x967D, 0x51E1, 0x967E, 0x76C6, 0x9680, 0x6469,
+	0x9681, 0x78E8, 0x9682, 0x9B54, 0x9683, 0x9EBB, 0x9684, 0x57CB,
+	0x9685, 0x59B9, 0x9686, 0x6627, 0x9687, 0x679A, 0x9688, 0x6BCE,
+	0x9689, 0x54E9, 0x968A, 0x69D9, 0x968B, 0x5E55, 0x968C, 0x819C,
+	0x968D, 0x6795, 0x968E, 0x9BAA, 0x968F, 0x67FE, 0x9690, 0x9C52,
+	0x9691, 0x685D, 0x9692, 0x4EA6, 0x9693, 0x4FE3, 0x9694, 0x53C8,
+	0x9695, 0x62B9, 0x9696, 0x672B, 0x9697, 0x6CAB, 0x9698, 0x8FC4,
+	0x9699, 0x4FAD, 0x969A, 0x7E6D, 0x969B, 0x9EBF, 0x969C, 0x4E07,
+	0x969D, 0x6162, 0x969E, 0x6E80, 0x969F, 0x6F2B, 0x96A0, 0x8513,
+	0x96A1, 0x5473, 0x96A2, 0x672A, 0x96A3, 0x9B45, 0x96A4, 0x5DF3,
+	0x96A5, 0x7B95, 0x96A6, 0x5CAC, 0x96A7, 0x5BC6, 0x96A8, 0x871C,
+	0x96A9, 0x6E4A, 0x96AA, 0x84D1, 0x96AB, 0x7A14, 0x96AC, 0x8108,
+	0x96AD, 0x5999, 0x96AE, 0x7C8D, 0x96AF, 0x6C11, 0x96B0, 0x7720,
+	0x96B1, 0x52D9, 0x96B2, 0x5922, 0x96B3, 0x7121, 0x96B4, 0x725F,
+	0x96B5, 0x77DB, 0x96B6, 0x9727, 0x96B7, 0x9D61, 0x96B8, 0x690B,
+	0x96B9, 0x5A7F, 0x96BA, 0x5A18, 0x96BB, 0x51A5, 0x96BC, 0x540D,
+	0x96BD, 0x547D, 0x96BE, 0x660E, 0x96BF, 0x76DF, 0x96C0, 0x8FF7,
+	0x96C1, 0x9298, 0x96C2, 0x9CF4, 0x96C3, 0x59EA, 0x96C4, 0x725D,
+	0x96C5, 0x6EC5, 0x96C6, 0x514D, 0x96C7, 0x68C9, 0x96C8, 0x7DBF,
+	0x96C9, 0x7DEC, 0x96CA, 0x9762, 0x96CB, 0x9EBA, 0x96CC, 0x6478,
+	0x96CD, 0x6A21, 0x96CE, 0x8302, 0x96CF, 0x5984, 0x96D0, 0x5B5F,
+	0x96D1, 0x6BDB, 0x96D2, 0x731B, 0x96D3, 0x76F2, 0x96D4, 0x7DB2,
+	0x96D5, 0x8017, 0x96D6, 0x8499, 0x96D7, 0x5132, 0x96D8, 0x6728,
+	0x96D9, 0x9ED9, 0x96DA, 0x76EE, 0x96DB, 0x6762, 0x96DC, 0x52FF,
+	0x96DD, 0x9905, 0x96DE, 0x5C24, 0x96DF, 0x623B, 0x96E0, 0x7C7E,
+	0x96E1, 0x8CB0, 0x96E2, 0x554F, 0x96E3, 0x60B6, 0x96E4, 0x7D0B,
+	0x96E5, 0x9580, 0x96E6, 0x5301, 0x96E7, 0x4E5F, 0x96E8, 0x51B6,
+	0x96E9, 0x591C, 0x96EA, 0x723A, 0x96EB, 0x8036, 0x96EC, 0x91CE,
+	0x96ED, 0x5F25, 0x96EE, 0x77E2, 0x96EF, 0x5384, 0x96F0, 0x5F79,
+	0x96F1, 0x7D04, 0x96F2, 0x85AC, 0x96F3, 0x8A33, 0x96F4, 0x8E8D,
+	0x96F5, 0x9756, 0x96F6, 0x67F3, 0x96F7, 0x85AE, 0x96F8, 0x9453,
+	0x96F9, 0x6109, 0x96FA, 0x6108, 0x96FB, 0x6CB9, 0x96FC, 0x7652,
+	0x9740, 0x8AED, 0x9741, 0x8F38, 0x9742, 0x552F, 0x9743, 0x4F51,
+	0x9744, 0x512A, 0x9745, 0x52C7, 0x9746, 0x53CB, 0x9747, 0x5BA5,
+	0x9748, 0x5E7D, 0x9749, 0x60A0, 0x974A, 0x6182, 0x974B, 0x63D6,
+	0x974C, 0x6709, 0x974D, 0x67DA, 0x974E, 0x6E67, 0x974F, 0x6D8C,
+	0x9750, 0x7336, 0x9751, 0x7337, 0x9752, 0x7531, 0x9753, 0x7950,
+	0x9754, 0x88D5, 0x9755, 0x8A98, 0x9756, 0x904A, 0x9757, 0x9091,
+	0x9758, 0x90F5, 0x9759, 0x96C4, 0x975A, 0x878D, 0x975B, 0x5915,
+	0x975C, 0x4E88, 0x975D, 0x4F59, 0x975E, 0x4E0E, 0x975F, 0x8A89,
+	0x9760, 0x8F3F, 0x9761, 0x9810, 0x9762, 0x50AD, 0x9763, 0x5E7C,
+	0x9764, 0x5996, 0x9765, 0x5BB9, 0x9766, 0x5EB8, 0x9767, 0x63DA,
+	0x9768, 0x63FA, 0x9769, 0x64C1, 0x976A, 0x66DC, 0x976B, 0x694A,
+	0x976C, 0x69D8, 0x976D, 0x6D0B, 0x976E, 0x6EB6, 0x976F, 0x7194,
+	0x9770, 0x7528, 0x9771, 0x7AAF, 0x9772, 0x7F8A, 0x9773, 0x8000,
+	0x9774, 0x8449, 0x9775, 0x84C9, 0x9776, 0x8981, 0x9777, 0x8B21,
+	0x9778, 0x8E0A, 0x9779, 0x9065, 0x977A, 0x967D, 0x977B, 0x990A,
+	0x977C, 0x617E, 0x977D, 0x6291, 0x977E, 0x6B32, 0x9780, 0x6C83,
+	0x9781, 0x6D74, 0x9782, 0x7FCC, 0x9783, 0x7FFC, 0x9784, 0x6DC0,
+	0x9785, 0x7F85, 0x9786, 0x87BA, 0x9787, 0x88F8, 0x9788, 0x6765,
+	0x9789, 0x83B1, 0x978A, 0x983C, 0x978B, 0x96F7, 0x978C, 0x6D1B,
+	0x978D, 0x7D61, 0x978E, 0x843D, 0x978F, 0x916A, 0x9790, 0x4E71,
+	0x9791, 0x5375, 0x9792, 0x5D50, 0x9793, 0x6B04, 0x9794, 0x6FEB,
+	0x9795, 0x85CD, 0x9796, 0x862D, 0x9797, 0x89A7, 0x9798, 0x5229,
+	0x9799, 0x540F, 0x979A, 0x5C65, 0x979B, 0x674E, 0x979C, 0x68A8,
+	0x979D, 0x7406, 0x979E, 0x7483, 0x979F, 0x75E2, 0x97A0, 0x88CF,
+	0x97A1, 0x88E1, 0x97A2, 0x91CC, 0x97A3, 0x96E2, 0x97A4, 0x9678,
+	0x97A5, 0x5F8B, 0x97A6, 0x7387, 0x97A7, 0x7ACB, 0x97A8, 0x844E,
+	0x97A9, 0x63A0, 0x97AA, 0x7565, 0x97AB, 0x5289, 0x97AC, 0x6D41,
+	0x97AD, 0x6E9C, 0x97AE, 0x7409, 0x97AF, 0x7559, 0x97B0, 0x786B,
+	0x97B1, 0x7C92, 0x97B2, 0x9686, 0x97B3, 0x7ADC, 0x97B4, 0x9F8D,
+	0x97B5, 0x4FB6, 0x97B6, 0x616E, 0x97B7, 0x65C5, 0x97B8, 0x865C,
+	0x97B9, 0x4E86, 0x97BA, 0x4EAE, 0x97BB, 0x50DA, 0x97BC, 0x4E21,
+	0x97BD, 0x51CC, 0x97BE, 0x5BEE, 0x97BF, 0x6599, 0x97C0, 0x6881,
+	0x97C1, 0x6DBC, 0x97C2, 0x731F, 0x97C3, 0x7642, 0x97C4, 0x77AD,
+	0x97C5, 0x7A1C, 0x97C6, 0x7CE7, 0x97C7, 0x826F, 0x97C8, 0x8AD2,
+	0x97C9, 0x907C, 0x97CA, 0x91CF, 0x97CB, 0x9675, 0x97CC, 0x9818,
+	0x97CD, 0x529B, 0x97CE, 0x7DD1, 0x97CF, 0x502B, 0x97D0, 0x5398,
+	0x97D1, 0x6797, 0x97D2, 0x6DCB, 0x97D3, 0x71D0, 0x97D4, 0x7433,
+	0x97D5, 0x81E8, 0x97D6, 0x8F2A, 0x97D7, 0x96A3, 0x97D8, 0x9C57,
+	0x97D9, 0x9E9F, 0x97DA, 0x7460, 0x97DB, 0x5841, 0x97DC, 0x6D99,
+	0x97DD, 0x7D2F, 0x97DE, 0x985E, 0x97DF, 0x4EE4, 0x97E0, 0x4F36,
+	0x97E1, 0x4F8B, 0x97E2, 0x51B7, 0x97E3, 0x52B1, 0x97E4, 0x5DBA,
+	0x97E5, 0x601C, 0x97E6, 0x73B2, 0x97E7, 0x793C, 0x97E8, 0x82D3,
+	0x97E9, 0x9234, 0x97EA, 0x96B7, 0x97EB, 0x96F6, 0x97EC, 0x970A,
+	0x97ED, 0x9E97, 0x97EE, 0x9F62, 0x97EF, 0x66A6, 0x97F0, 0x6B74,
+	0x97F1, 0x5217, 0x97F2, 0x52A3, 0x97F3, 0x70C8, 0x97F4, 0x88C2,
+	0x97F5, 0x5EC9, 0x97F6, 0x604B, 0x97F7, 0x6190, 0x97F8, 0x6F23,
+	0x97F9, 0x7149, 0x97FA, 0x7C3E, 0x97FB, 0x7DF4, 0x97FC, 0x806F,
+	0x9840, 0x84EE, 0x9841, 0x9023, 0x9842, 0x932C, 0x9843, 0x5442,
+	0x9844, 0x9B6F, 0x9845, 0x6AD3, 0x9846, 0x7089, 0x9847, 0x8CC2,
+	0x9848, 0x8DEF, 0x9849, 0x9732, 0x984A, 0x52B4, 0x984B, 0x5A41,
+	0x984C, 0x5ECA, 0x984D, 0x5F04, 0x984E, 0x6717, 0x984F, 0x697C,
+	0x9850, 0x6994, 0x9851, 0x6D6A, 0x9852, 0x6F0F, 0x9853, 0x7262,
+	0x9854, 0x72FC, 0x9855, 0x7BED, 0x9856, 0x8001, 0x9857, 0x807E,
+	0x9858, 0x874B, 0x9859, 0x90CE, 0x985A, 0x516D, 0x985B, 0x9E93,
+	0x985C, 0x7984, 0x985D, 0x808B, 0x985E, 0x9332, 0x985F, 0x8AD6,
+	0x9860, 0x502D, 0x9861, 0x548C, 0x9862, 0x8A71, 0x9863, 0x6B6A,
+	0x9864, 0x8CC4, 0x9865, 0x8107, 0x9866, 0x60D1, 0x9867, 0x67A0,
+	0x9868, 0x9DF2, 0x9869, 0x4E99, 0x986A, 0x4E98, 0x986B, 0x9C10,
+	0x986C, 0x8A6B, 0x986D, 0x85C1, 0x986E, 0x8568, 0x986F, 0x6900,
+	0x9870, 0x6E7E, 0x9871, 0x7897, 0x9872, 0x8155, 0x989F, 0x5F0C,
+	0x98A0, 0x4E10, 0x98A1, 0x4E15, 0x98A2, 0x4E2A, 0x98A3, 0x4E31,
+	0x98A4, 0x4E36, 0x98A5, 0x4E3C, 0x98A6, 0x4E3F, 0x98A7, 0x4E42,
+	0x98A8, 0x4E56, 0x98A9, 0x4E58, 0x98AA, 0x4E82, 0x98AB, 0x4E85,
+	0x98AC, 0x8C6B, 0x98AD, 0x4E8A, 0x98AE, 0x8212, 0x98AF, 0x5F0D,
+	0x98B0, 0x4E8E, 0x98B1, 0x4E9E, 0x98B2, 0x4E9F, 0x98B3, 0x4EA0,
+	0x98B4, 0x4EA2, 0x98B5, 0x4EB0, 0x98B6, 0x4EB3, 0x98B7, 0x4EB6,
+	0x98B8, 0x4ECE, 0x98B9, 0x4ECD, 0x98BA, 0x4EC4, 0x98BB, 0x4EC6,
+	0x98BC, 0x4EC2, 0x98BD, 0x4ED7, 0x98BE, 0x4EDE, 0x98BF, 0x4EED,
+	0x98C0, 0x4EDF, 0x98C1, 0x4EF7, 0x98C2, 0x4F09, 0x98C3, 0x4F5A,
+	0x98C4, 0x4F30, 0x98C5, 0x4F5B, 0x98C6, 0x4F5D, 0x98C7, 0x4F57,
+	0x98C8, 0x4F47, 0x98C9, 0x4F76, 0x98CA, 0x4F88, 0x98CB, 0x4F8F,
+	0x98CC, 0x4F98, 0x98CD, 0x4F7B, 0x98CE, 0x4F69, 0x98CF, 0x4F70,
+	0x98D0, 0x4F91, 0x98D1, 0x4F6F, 0x98D2, 0x4F86, 0x98D3, 0x4F96,
+	0x98D4, 0x5118, 0x98D5, 0x4FD4, 0x98D6, 0x4FDF, 0x98D7, 0x4FCE,
+	0x98D8, 0x4FD8, 0x98D9, 0x4FDB, 0x98DA, 0x4FD1, 0x98DB, 0x4FDA,
+	0x98DC, 0x4FD0, 0x98DD, 0x4FE4, 0x98DE, 0x4FE5, 0x98DF, 0x501A,
+	0x98E0, 0x5028, 0x98E1, 0x5014, 0x98E2, 0x502A, 0x98E3, 0x5025,
+	0x98E4, 0x5005, 0x98E5, 0x4F1C, 0x98E6, 0x4FF6, 0x98E7, 0x5021,
+	0x98E8, 0x5029, 0x98E9, 0x502C, 0x98EA, 0x4FFE, 0x98EB, 0x4FEF,
+	0x98EC, 0x5011, 0x98ED, 0x5006, 0x98EE, 0x5043, 0x98EF, 0x5047,
+	0x98F0, 0x6703, 0x98F1, 0x5055, 0x98F2, 0x5050, 0x98F3, 0x5048,
+	0x98F4, 0x505A, 0x98F5, 0x5056, 0x98F6, 0x506C, 0x98F7, 0x5078,
+	0x98F8, 0x5080, 0x98F9, 0x509A, 0x98FA, 0x5085, 0x98FB, 0x50B4,
+	0x98FC, 0x50B2, 0x9940, 0x50C9, 0x9941, 0x50CA, 0x9942, 0x50B3,
+	0x9943, 0x50C2, 0x9944, 0x50D6, 0x9945, 0x50DE, 0x9946, 0x50E5,
+	0x9947, 0x50ED, 0x9948, 0x50E3, 0x9949, 0x50EE, 0x994A, 0x50F9,
+	0x994B, 0x50F5, 0x994C, 0x5109, 0x994D, 0x5101, 0x994E, 0x5102,
+	0x994F, 0x5116, 0x9950, 0x5115, 0x9951, 0x5114, 0x9952, 0x511A,
+	0x9953, 0x5121, 0x9954, 0x513A, 0x9955, 0x5137, 0x9956, 0x513C,
+	0x9957, 0x513B, 0x9958, 0x513F, 0x9959, 0x5140, 0x995A, 0x5152,
+	0x995B, 0x514C, 0x995C, 0x5154, 0x995D, 0x5162, 0x995E, 0x7AF8,
+	0x995F, 0x5169, 0x9960, 0x516A, 0x9961, 0x516E, 0x9962, 0x5180,
+	0x9963, 0x5182, 0x9964, 0x56D8, 0x9965, 0x518C, 0x9966, 0x5189,
+	0x9967, 0x518F, 0x9968, 0x5191, 0x9969, 0x5193, 0x996A, 0x5195,
+	0x996B, 0x5196, 0x996C, 0x51A4, 0x996D, 0x51A6, 0x996E, 0x51A2,
+	0x996F, 0x51A9, 0x9970, 0x51AA, 0x9971, 0x51AB, 0x9972, 0x51B3,
+	0x9973, 0x51B1, 0x9974, 0x51B2, 0x9975, 0x51B0, 0x9976, 0x51B5,
+	0x9977, 0x51BD, 0x9978, 0x51C5, 0x9979, 0x51C9, 0x997A, 0x51DB,
+	0x997B, 0x51E0, 0x997C, 0x8655, 0x997D, 0x51E9, 0x997E, 0x51ED,
+	0x9980, 0x51F0, 0x9981, 0x51F5, 0x9982, 0x51FE, 0x9983, 0x5204,
+	0x9984, 0x520B, 0x9985, 0x5214, 0x9986, 0x520E, 0x9987, 0x5227,
+	0x9988, 0x522A, 0x9989, 0x522E, 0x998A, 0x5233, 0x998B, 0x5239,
+	0x998C, 0x524F, 0x998D, 0x5244, 0x998E, 0x524B, 0x998F, 0x524C,
+	0x9990, 0x525E, 0x9991, 0x5254, 0x9992, 0x526A, 0x9993, 0x5274,
+	0x9994, 0x5269, 0x9995, 0x5273, 0x9996, 0x527F, 0x9997, 0x527D,
+	0x9998, 0x528D, 0x9999, 0x5294, 0x999A, 0x5292, 0x999B, 0x5271,
+	0x999C, 0x5288, 0x999D, 0x5291, 0x999E, 0x8FA8, 0x999F, 0x8FA7,
+	0x99A0, 0x52AC, 0x99A1, 0x52AD, 0x99A2, 0x52BC, 0x99A3, 0x52B5,
+	0x99A4, 0x52C1, 0x99A5, 0x52CD, 0x99A6, 0x52D7, 0x99A7, 0x52DE,
+	0x99A8, 0x52E3, 0x99A9, 0x52E6, 0x99AA, 0x98ED, 0x99AB, 0x52E0,
+	0x99AC, 0x52F3, 0x99AD, 0x52F5, 0x99AE, 0x52F8, 0x99AF, 0x52F9,
+	0x99B0, 0x5306, 0x99B1, 0x5308, 0x99B2, 0x7538, 0x99B3, 0x530D,
+	0x99B4, 0x5310, 0x99B5, 0x530F, 0x99B6, 0x5315, 0x99B7, 0x531A,
+	0x99B8, 0x5323, 0x99B9, 0x532F, 0x99BA, 0x5331, 0x99BB, 0x5333,
+	0x99BC, 0x5338, 0x99BD, 0x5340, 0x99BE, 0x5346, 0x99BF, 0x5345,
+	0x99C0, 0x4E17, 0x99C1, 0x5349, 0x99C2, 0x534D, 0x99C3, 0x51D6,
+	0x99C4, 0x535E, 0x99C5, 0x5369, 0x99C6, 0x536E, 0x99C7, 0x5918,
+	0x99C8, 0x537B, 0x99C9, 0x5377, 0x99CA, 0x5382, 0x99CB, 0x5396,
+	0x99CC, 0x53A0, 0x99CD, 0x53A6, 0x99CE, 0x53A5, 0x99CF, 0x53AE,
+	0x99D0, 0x53B0, 0x99D1, 0x53B6, 0x99D2, 0x53C3, 0x99D3, 0x7C12,
+	0x99D4, 0x96D9, 0x99D5, 0x53DF, 0x99D6, 0x66FC, 0x99D7, 0x71EE,
+	0x99D8, 0x53EE, 0x99D9, 0x53E8, 0x99DA, 0x53ED, 0x99DB, 0x53FA,
+	0x99DC, 0x5401, 0x99DD, 0x543D, 0x99DE, 0x5440, 0x99DF, 0x542C,
+	0x99E0, 0x542D, 0x99E1, 0x543C, 0x99E2, 0x542E, 0x99E3, 0x5436,
+	0x99E4, 0x5429, 0x99E5, 0x541D, 0x99E6, 0x544E, 0x99E7, 0x548F,
+	0x99E8, 0x5475, 0x99E9, 0x548E, 0x99EA, 0x545F, 0x99EB, 0x5471,
+	0x99EC, 0x5477, 0x99ED, 0x5470, 0x99EE, 0x5492, 0x99EF, 0x547B,
+	0x99F0, 0x5480, 0x99F1, 0x5476, 0x99F2, 0x5484, 0x99F3, 0x5490,
+	0x99F4, 0x5486, 0x99F5, 0x54C7, 0x99F6, 0x54A2, 0x99F7, 0x54B8,
+	0x99F8, 0x54A5, 0x99F9, 0x54AC, 0x99FA, 0x54C4, 0x99FB, 0x54C8,
+	0x99FC, 0x54A8, 0x9A40, 0x54AB, 0x9A41, 0x54C2, 0x9A42, 0x54A4,
+	0x9A43, 0x54BE, 0x9A44, 0x54BC, 0x9A45, 0x54D8, 0x9A46, 0x54E5,
+	0x9A47, 0x54E6, 0x9A48, 0x550F, 0x9A49, 0x5514, 0x9A4A, 0x54FD,
+	0x9A4B, 0x54EE, 0x9A4C, 0x54ED, 0x9A4D, 0x54FA, 0x9A4E, 0x54E2,
+	0x9A4F, 0x5539, 0x9A50, 0x5540, 0x9A51, 0x5563, 0x9A52, 0x554C,
+	0x9A53, 0x552E, 0x9A54, 0x555C, 0x9A55, 0x5545, 0x9A56, 0x5556,
+	0x9A57, 0x5557, 0x9A58, 0x5538, 0x9A59, 0x5533, 0x9A5A, 0x555D,
+	0x9A5B, 0x5599, 0x9A5C, 0x5580, 0x9A5D, 0x54AF, 0x9A5E, 0x558A,
+	0x9A5F, 0x559F, 0x9A60, 0x557B, 0x9A61, 0x557E, 0x9A62, 0x5598,
+	0x9A63, 0x559E, 0x9A64, 0x55AE, 0x9A65, 0x557C, 0x9A66, 0x5583,
+	0x9A67, 0x55A9, 0x9A68, 0x5587, 0x9A69, 0x55A8, 0x9A6A, 0x55DA,
+	0x9A6B, 0x55C5, 0x9A6C, 0x55DF, 0x9A6D, 0x55C4, 0x9A6E, 0x55DC,
+	0x9A6F, 0x55E4, 0x9A70, 0x55D4, 0x9A71, 0x5614, 0x9A72, 0x55F7,
+	0x9A73, 0x5616, 0x9A74, 0x55FE, 0x9A75, 0x55FD, 0x9A76, 0x561B,
+	0x9A77, 0x55F9, 0x9A78, 0x564E, 0x9A79, 0x5650, 0x9A7A, 0x71DF,
+	0x9A7B, 0x5634, 0x9A7C, 0x5636, 0x9A7D, 0x5632, 0x9A7E, 0x5638,
+	0x9A80, 0x566B, 0x9A81, 0x5664, 0x9A82, 0x562F, 0x9A83, 0x566C,
+	0x9A84, 0x566A, 0x9A85, 0x5686, 0x9A86, 0x5680, 0x9A87, 0x568A,
+	0x9A88, 0x56A0, 0x9A89, 0x5694, 0x9A8A, 0x568F, 0x9A8B, 0x56A5,
+	0x9A8C, 0x56AE, 0x9A8D, 0x56B6, 0x9A8E, 0x56B4, 0x9A8F, 0x56C2,
+	0x9A90, 0x56BC, 0x9A91, 0x56C1, 0x9A92, 0x56C3, 0x9A93, 0x56C0,
+	0x9A94, 0x56C8, 0x9A95, 0x56CE, 0x9A96, 0x56D1, 0x9A97, 0x56D3,
+	0x9A98, 0x56D7, 0x9A99, 0x56EE, 0x9A9A, 0x56F9, 0x9A9B, 0x5700,
+	0x9A9C, 0x56FF, 0x9A9D, 0x5704, 0x9A9E, 0x5709, 0x9A9F, 0x5708,
+	0x9AA0, 0x570B, 0x9AA1, 0x570D, 0x9AA2, 0x5713, 0x9AA3, 0x5718,
+	0x9AA4, 0x5716, 0x9AA5, 0x55C7, 0x9AA6, 0x571C, 0x9AA7, 0x5726,
+	0x9AA8, 0x5737, 0x9AA9, 0x5738, 0x9AAA, 0x574E, 0x9AAB, 0x573B,
+	0x9AAC, 0x5740, 0x9AAD, 0x574F, 0x9AAE, 0x5769, 0x9AAF, 0x57C0,
+	0x9AB0, 0x5788, 0x9AB1, 0x5761, 0x9AB2, 0x577F, 0x9AB3, 0x5789,
+	0x9AB4, 0x5793, 0x9AB5, 0x57A0, 0x9AB6, 0x57B3, 0x9AB7, 0x57A4,
+	0x9AB8, 0x57AA, 0x9AB9, 0x57B0, 0x9ABA, 0x57C3, 0x9ABB, 0x57C6,
+	0x9ABC, 0x57D4, 0x9ABD, 0x57D2, 0x9ABE, 0x57D3, 0x9ABF, 0x580A,
+	0x9AC0, 0x57D6, 0x9AC1, 0x57E3, 0x9AC2, 0x580B, 0x9AC3, 0x5819,
+	0x9AC4, 0x581D, 0x9AC5, 0x5872, 0x9AC6, 0x5821, 0x9AC7, 0x5862,
+	0x9AC8, 0x584B, 0x9AC9, 0x5870, 0x9ACA, 0x6BC0, 0x9ACB, 0x5852,
+	0x9ACC, 0x583D, 0x9ACD, 0x5879, 0x9ACE, 0x5885, 0x9ACF, 0x58B9,
+	0x9AD0, 0x589F, 0x9AD1, 0x58AB, 0x9AD2, 0x58BA, 0x9AD3, 0x58DE,
+	0x9AD4, 0x58BB, 0x9AD5, 0x58B8, 0x9AD6, 0x58AE, 0x9AD7, 0x58C5,
+	0x9AD8, 0x58D3, 0x9AD9, 0x58D1, 0x9ADA, 0x58D7, 0x9ADB, 0x58D9,
+	0x9ADC, 0x58D8, 0x9ADD, 0x58E5, 0x9ADE, 0x58DC, 0x9ADF, 0x58E4,
+	0x9AE0, 0x58DF, 0x9AE1, 0x58EF, 0x9AE2, 0x58FA, 0x9AE3, 0x58F9,
+	0x9AE4, 0x58FB, 0x9AE5, 0x58FC, 0x9AE6, 0x58FD, 0x9AE7, 0x5902,
+	0x9AE8, 0x590A, 0x9AE9, 0x5910, 0x9AEA, 0x591B, 0x9AEB, 0x68A6,
+	0x9AEC, 0x5925, 0x9AED, 0x592C, 0x9AEE, 0x592D, 0x9AEF, 0x5932,
+	0x9AF0, 0x5938, 0x9AF1, 0x593E, 0x9AF2, 0x7AD2, 0x9AF3, 0x5955,
+	0x9AF4, 0x5950, 0x9AF5, 0x594E, 0x9AF6, 0x595A, 0x9AF7, 0x5958,
+	0x9AF8, 0x5962, 0x9AF9, 0x5960, 0x9AFA, 0x5967, 0x9AFB, 0x596C,
+	0x9AFC, 0x5969, 0x9B40, 0x5978, 0x9B41, 0x5981, 0x9B42, 0x599D,
+	0x9B43, 0x4F5E, 0x9B44, 0x4FAB, 0x9B45, 0x59A3, 0x9B46, 0x59B2,
+	0x9B47, 0x59C6, 0x9B48, 0x59E8, 0x9B49, 0x59DC, 0x9B4A, 0x598D,
+	0x9B4B, 0x59D9, 0x9B4C, 0x59DA, 0x9B4D, 0x5A25, 0x9B4E, 0x5A1F,
+	0x9B4F, 0x5A11, 0x9B50, 0x5A1C, 0x9B51, 0x5A09, 0x9B52, 0x5A1A,
+	0x9B53, 0x5A40, 0x9B54, 0x5A6C, 0x9B55, 0x5A49, 0x9B56, 0x5A35,
+	0x9B57, 0x5A36, 0x9B58, 0x5A62, 0x9B59, 0x5A6A, 0x9B5A, 0x5A9A,
+	0x9B5B, 0x5ABC, 0x9B5C, 0x5ABE, 0x9B5D, 0x5ACB, 0x9B5E, 0x5AC2,
+	0x9B5F, 0x5ABD, 0x9B60, 0x5AE3, 0x9B61, 0x5AD7, 0x9B62, 0x5AE6,
+	0x9B63, 0x5AE9, 0x9B64, 0x5AD6, 0x9B65, 0x5AFA, 0x9B66, 0x5AFB,
+	0x9B67, 0x5B0C, 0x9B68, 0x5B0B, 0x9B69, 0x5B16, 0x9B6A, 0x5B32,
+	0x9B6B, 0x5AD0, 0x9B6C, 0x5B2A, 0x9B6D, 0x5B36, 0x9B6E, 0x5B3E,
+	0x9B6F, 0x5B43, 0x9B70, 0x5B45, 0x9B71, 0x5B40, 0x9B72, 0x5B51,
+	0x9B73, 0x5B55, 0x9B74, 0x5B5A, 0x9B75, 0x5B5B, 0x9B76, 0x5B65,
+	0x9B77, 0x5B69, 0x9B78, 0x5B70, 0x9B79, 0x5B73, 0x9B7A, 0x5B75,
+	0x9B7B, 0x5B78, 0x9B7C, 0x6588, 0x9B7D, 0x5B7A, 0x9B7E, 0x5B80,
+	0x9B80, 0x5B83, 0x9B81, 0x5BA6, 0x9B82, 0x5BB8, 0x9B83, 0x5BC3,
+	0x9B84, 0x5BC7, 0x9B85, 0x5BC9, 0x9B86, 0x5BD4, 0x9B87, 0x5BD0,
+	0x9B88, 0x5BE4, 0x9B89, 0x5BE6, 0x9B8A, 0x5BE2, 0x9B8B, 0x5BDE,
+	0x9B8C, 0x5BE5, 0x9B8D, 0x5BEB, 0x9B8E, 0x5BF0, 0x9B8F, 0x5BF6,
+	0x9B90, 0x5BF3, 0x9B91, 0x5C05, 0x9B92, 0x5C07, 0x9B93, 0x5C08,
+	0x9B94, 0x5C0D, 0x9B95, 0x5C13, 0x9B96, 0x5C20, 0x9B97, 0x5C22,
+	0x9B98, 0x5C28, 0x9B99, 0x5C38, 0x9B9A, 0x5C39, 0x9B9B, 0x5C41,
+	0x9B9C, 0x5C46, 0x9B9D, 0x5C4E, 0x9B9E, 0x5C53, 0x9B9F, 0x5C50,
+	0x9BA0, 0x5C4F, 0x9BA1, 0x5B71, 0x9BA2, 0x5C6C, 0x9BA3, 0x5C6E,
+	0x9BA4, 0x4E62, 0x9BA5, 0x5C76, 0x9BA6, 0x5C79, 0x9BA7, 0x5C8C,
+	0x9BA8, 0x5C91, 0x9BA9, 0x5C94, 0x9BAA, 0x599B, 0x9BAB, 0x5CAB,
+	0x9BAC, 0x5CBB, 0x9BAD, 0x5CB6, 0x9BAE, 0x5CBC, 0x9BAF, 0x5CB7,
+	0x9BB0, 0x5CC5, 0x9BB1, 0x5CBE, 0x9BB2, 0x5CC7, 0x9BB3, 0x5CD9,
+	0x9BB4, 0x5CE9, 0x9BB5, 0x5CFD, 0x9BB6, 0x5CFA, 0x9BB7, 0x5CED,
+	0x9BB8, 0x5D8C, 0x9BB9, 0x5CEA, 0x9BBA, 0x5D0B, 0x9BBB, 0x5D15,
+	0x9BBC, 0x5D17, 0x9BBD, 0x5D5C, 0x9BBE, 0x5D1F, 0x9BBF, 0x5D1B,
+	0x9BC0, 0x5D11, 0x9BC1, 0x5D14, 0x9BC2, 0x5D22, 0x9BC3, 0x5D1A,
+	0x9BC4, 0x5D19, 0x9BC5, 0x5D18, 0x9BC6, 0x5D4C, 0x9BC7, 0x5D52,
+	0x9BC8, 0x5D4E, 0x9BC9, 0x5D4B, 0x9BCA, 0x5D6C, 0x9BCB, 0x5D73,
+	0x9BCC, 0x5D76, 0x9BCD, 0x5D87, 0x9BCE, 0x5D84, 0x9BCF, 0x5D82,
+	0x9BD0, 0x5DA2, 0x9BD1, 0x5D9D, 0x9BD2, 0x5DAC, 0x9BD3, 0x5DAE,
+	0x9BD4, 0x5DBD, 0x9BD5, 0x5D90, 0x9BD6, 0x5DB7, 0x9BD7, 0x5DBC,
+	0x9BD8, 0x5DC9, 0x9BD9, 0x5DCD, 0x9BDA, 0x5DD3, 0x9BDB, 0x5DD2,
+	0x9BDC, 0x5DD6, 0x9BDD, 0x5DDB, 0x9BDE, 0x5DEB, 0x9BDF, 0x5DF2,
+	0x9BE0, 0x5DF5, 0x9BE1, 0x5E0B, 0x9BE2, 0x5E1A, 0x9BE3, 0x5E19,
+	0x9BE4, 0x5E11, 0x9BE5, 0x5E1B, 0x9BE6, 0x5E36, 0x9BE7, 0x5E37,
+	0x9BE8, 0x5E44, 0x9BE9, 0x5E43, 0x9BEA, 0x5E40, 0x9BEB, 0x5E4E,
+	0x9BEC, 0x5E57, 0x9BED, 0x5E54, 0x9BEE, 0x5E5F, 0x9BEF, 0x5E62,
+	0x9BF0, 0x5E64, 0x9BF1, 0x5E47, 0x9BF2, 0x5E75, 0x9BF3, 0x5E76,
+	0x9BF4, 0x5E7A, 0x9BF5, 0x9EBC, 0x9BF6, 0x5E7F, 0x9BF7, 0x5EA0,
+	0x9BF8, 0x5EC1, 0x9BF9, 0x5EC2, 0x9BFA, 0x5EC8, 0x9BFB, 0x5ED0,
+	0x9BFC, 0x5ECF, 0x9C40, 0x5ED6, 0x9C41, 0x5EE3, 0x9C42, 0x5EDD,
+	0x9C43, 0x5EDA, 0x9C44, 0x5EDB, 0x9C45, 0x5EE2, 0x9C46, 0x5EE1,
+	0x9C47, 0x5EE8, 0x9C48, 0x5EE9, 0x9C49, 0x5EEC, 0x9C4A, 0x5EF1,
+	0x9C4B, 0x5EF3, 0x9C4C, 0x5EF0, 0x9C4D, 0x5EF4, 0x9C4E, 0x5EF8,
+	0x9C4F, 0x5EFE, 0x9C50, 0x5F03, 0x9C51, 0x5F09, 0x9C52, 0x5F5D,
+	0x9C53, 0x5F5C, 0x9C54, 0x5F0B, 0x9C55, 0x5F11, 0x9C56, 0x5F16,
+	0x9C57, 0x5F29, 0x9C58, 0x5F2D, 0x9C59, 0x5F38, 0x9C5A, 0x5F41,
+	0x9C5B, 0x5F48, 0x9C5C, 0x5F4C, 0x9C5D, 0x5F4E, 0x9C5E, 0x5F2F,
+	0x9C5F, 0x5F51, 0x9C60, 0x5F56, 0x9C61, 0x5F57, 0x9C62, 0x5F59,
+	0x9C63, 0x5F61, 0x9C64, 0x5F6D, 0x9C65, 0x5F73, 0x9C66, 0x5F77,
+	0x9C67, 0x5F83, 0x9C68, 0x5F82, 0x9C69, 0x5F7F, 0x9C6A, 0x5F8A,
+	0x9C6B, 0x5F88, 0x9C6C, 0x5F91, 0x9C6D, 0x5F87, 0x9C6E, 0x5F9E,
+	0x9C6F, 0x5F99, 0x9C70, 0x5F98, 0x9C71, 0x5FA0, 0x9C72, 0x5FA8,
+	0x9C73, 0x5FAD, 0x9C74, 0x5FBC, 0x9C75, 0x5FD6, 0x9C76, 0x5FFB,
+	0x9C77, 0x5FE4, 0x9C78, 0x5FF8, 0x9C79, 0x5FF1, 0x9C7A, 0x5FDD,
+	0x9C7B, 0x60B3, 0x9C7C, 0x5FFF, 0x9C7D, 0x6021, 0x9C7E, 0x6060,
+	0x9C80, 0x6019, 0x9C81, 0x6010, 0x9C82, 0x6029, 0x9C83, 0x600E,
+	0x9C84, 0x6031, 0x9C85, 0x601B, 0x9C86, 0x6015, 0x9C87, 0x602B,
+	0x9C88, 0x6026, 0x9C89, 0x600F, 0x9C8A, 0x603A, 0x9C8B, 0x605A,
+	0x9C8C, 0x6041, 0x9C8D, 0x606A, 0x9C8E, 0x6077, 0x9C8F, 0x605F,
+	0x9C90, 0x604A, 0x9C91, 0x6046, 0x9C92, 0x604D, 0x9C93, 0x6063,
+	0x9C94, 0x6043, 0x9C95, 0x6064, 0x9C96, 0x6042, 0x9C97, 0x606C,
+	0x9C98, 0x606B, 0x9C99, 0x6059, 0x9C9A, 0x6081, 0x9C9B, 0x608D,
+	0x9C9C, 0x60E7, 0x9C9D, 0x6083, 0x9C9E, 0x609A, 0x9C9F, 0x6084,
+	0x9CA0, 0x609B, 0x9CA1, 0x6096, 0x9CA2, 0x6097, 0x9CA3, 0x6092,
+	0x9CA4, 0x60A7, 0x9CA5, 0x608B, 0x9CA6, 0x60E1, 0x9CA7, 0x60B8,
+	0x9CA8, 0x60E0, 0x9CA9, 0x60D3, 0x9CAA, 0x60B4, 0x9CAB, 0x5FF0,
+	0x9CAC, 0x60BD, 0x9CAD, 0x60C6, 0x9CAE, 0x60B5, 0x9CAF, 0x60D8,
+	0x9CB0, 0x614D, 0x9CB1, 0x6115, 0x9CB2, 0x6106, 0x9CB3, 0x60F6,
+	0x9CB4, 0x60F7, 0x9CB5, 0x6100, 0x9CB6, 0x60F4, 0x9CB7, 0x60FA,
+	0x9CB8, 0x6103, 0x9CB9, 0x6121, 0x9CBA, 0x60FB, 0x9CBB, 0x60F1,
+	0x9CBC, 0x610D, 0x9CBD, 0x610E, 0x9CBE, 0x6147, 0x9CBF, 0x613E,
+	0x9CC0, 0x6128, 0x9CC1, 0x6127, 0x9CC2, 0x614A, 0x9CC3, 0x613F,
+	0x9CC4, 0x613C, 0x9CC5, 0x612C, 0x9CC6, 0x6134, 0x9CC7, 0x613D,
+	0x9CC8, 0x6142, 0x9CC9, 0x6144, 0x9CCA, 0x6173, 0x9CCB, 0x6177,
+	0x9CCC, 0x6158, 0x9CCD, 0x6159, 0x9CCE, 0x615A, 0x9CCF, 0x616B,
+	0x9CD0, 0x6174, 0x9CD1, 0x616F, 0x9CD2, 0x6165, 0x9CD3, 0x6171,
+	0x9CD4, 0x615F, 0x9CD5, 0x615D, 0x9CD6, 0x6153, 0x9CD7, 0x6175,
+	0x9CD8, 0x6199, 0x9CD9, 0x6196, 0x9CDA, 0x6187, 0x9CDB, 0x61AC,
+	0x9CDC, 0x6194, 0x9CDD, 0x619A, 0x9CDE, 0x618A, 0x9CDF, 0x6191,
+	0x9CE0, 0x61AB, 0x9CE1, 0x61AE, 0x9CE2, 0x61CC, 0x9CE3, 0x61CA,
+	0x9CE4, 0x61C9, 0x9CE5, 0x61F7, 0x9CE6, 0x61C8, 0x9CE7, 0x61C3,
+	0x9CE8, 0x61C6, 0x9CE9, 0x61BA, 0x9CEA, 0x61CB, 0x9CEB, 0x7F79,
+	0x9CEC, 0x61CD, 0x9CED, 0x61E6, 0x9CEE, 0x61E3, 0x9CEF, 0x61F6,
+	0x9CF0, 0x61FA, 0x9CF1, 0x61F4, 0x9CF2, 0x61FF, 0x9CF3, 0x61FD,
+	0x9CF4, 0x61FC, 0x9CF5, 0x61FE, 0x9CF6, 0x6200, 0x9CF7, 0x6208,
+	0x9CF8, 0x6209, 0x9CF9, 0x620D, 0x9CFA, 0x620C, 0x9CFB, 0x6214,
+	0x9CFC, 0x621B, 0x9D40, 0x621E, 0x9D41, 0x6221, 0x9D42, 0x622A,
+	0x9D43, 0x622E, 0x9D44, 0x6230, 0x9D45, 0x6232, 0x9D46, 0x6233,
+	0x9D47, 0x6241, 0x9D48, 0x624E, 0x9D49, 0x625E, 0x9D4A, 0x6263,
+	0x9D4B, 0x625B, 0x9D4C, 0x6260, 0x9D4D, 0x6268, 0x9D4E, 0x627C,
+	0x9D4F, 0x6282, 0x9D50, 0x6289, 0x9D51, 0x627E, 0x9D52, 0x6292,
+	0x9D53, 0x6293, 0x9D54, 0x6296, 0x9D55, 0x62D4, 0x9D56, 0x6283,
+	0x9D57, 0x6294, 0x9D58, 0x62D7, 0x9D59, 0x62D1, 0x9D5A, 0x62BB,
+	0x9D5B, 0x62CF, 0x9D5C, 0x62FF, 0x9D5D, 0x62C6, 0x9D5E, 0x64D4,
+	0x9D5F, 0x62C8, 0x9D60, 0x62DC, 0x9D61, 0x62CC, 0x9D62, 0x62CA,
+	0x9D63, 0x62C2, 0x9D64, 0x62C7, 0x9D65, 0x629B, 0x9D66, 0x62C9,
+	0x9D67, 0x630C, 0x9D68, 0x62EE, 0x9D69, 0x62F1, 0x9D6A, 0x6327,
+	0x9D6B, 0x6302, 0x9D6C, 0x6308, 0x9D6D, 0x62EF, 0x9D6E, 0x62F5,
+	0x9D6F, 0x6350, 0x9D70, 0x633E, 0x9D71, 0x634D, 0x9D72, 0x641C,
+	0x9D73, 0x634F, 0x9D74, 0x6396, 0x9D75, 0x638E, 0x9D76, 0x6380,
+	0x9D77, 0x63AB, 0x9D78, 0x6376, 0x9D79, 0x63A3, 0x9D7A, 0x638F,
+	0x9D7B, 0x6389, 0x9D7C, 0x639F, 0x9D7D, 0x63B5, 0x9D7E, 0x636B,
+	0x9D80, 0x6369, 0x9D81, 0x63BE, 0x9D82, 0x63E9, 0x9D83, 0x63C0,
+	0x9D84, 0x63C6, 0x9D85, 0x63E3, 0x9D86, 0x63C9, 0x9D87, 0x63D2,
+	0x9D88, 0x63F6, 0x9D89, 0x63C4, 0x9D8A, 0x6416, 0x9D8B, 0x6434,
+	0x9D8C, 0x6406, 0x9D8D, 0x6413, 0x9D8E, 0x6426, 0x9D8F, 0x6436,
+	0x9D90, 0x651D, 0x9D91, 0x6417, 0x9D92, 0x6428, 0x9D93, 0x640F,
+	0x9D94, 0x6467, 0x9D95, 0x646F, 0x9D96, 0x6476, 0x9D97, 0x644E,
+	0x9D98, 0x652A, 0x9D99, 0x6495, 0x9D9A, 0x6493, 0x9D9B, 0x64A5,
+	0x9D9C, 0x64A9, 0x9D9D, 0x6488, 0x9D9E, 0x64BC, 0x9D9F, 0x64DA,
+	0x9DA0, 0x64D2, 0x9DA1, 0x64C5, 0x9DA2, 0x64C7, 0x9DA3, 0x64BB,
+	0x9DA4, 0x64D8, 0x9DA5, 0x64C2, 0x9DA6, 0x64F1, 0x9DA7, 0x64E7,
+	0x9DA8, 0x8209, 0x9DA9, 0x64E0, 0x9DAA, 0x64E1, 0x9DAB, 0x62AC,
+	0x9DAC, 0x64E3, 0x9DAD, 0x64EF, 0x9DAE, 0x652C, 0x9DAF, 0x64F6,
+	0x9DB0, 0x64F4, 0x9DB1, 0x64F2, 0x9DB2, 0x64FA, 0x9DB3, 0x6500,
+	0x9DB4, 0x64FD, 0x9DB5, 0x6518, 0x9DB6, 0x651C, 0x9DB7, 0x6505,
+	0x9DB8, 0x6524, 0x9DB9, 0x6523, 0x9DBA, 0x652B, 0x9DBB, 0x6534,
+	0x9DBC, 0x6535, 0x9DBD, 0x6537, 0x9DBE, 0x6536, 0x9DBF, 0x6538,
+	0x9DC0, 0x754B, 0x9DC1, 0x6548, 0x9DC2, 0x6556, 0x9DC3, 0x6555,
+	0x9DC4, 0x654D, 0x9DC5, 0x6558, 0x9DC6, 0x655E, 0x9DC7, 0x655D,
+	0x9DC8, 0x6572, 0x9DC9, 0x6578, 0x9DCA, 0x6582, 0x9DCB, 0x6583,
+	0x9DCC, 0x8B8A, 0x9DCD, 0x659B, 0x9DCE, 0x659F, 0x9DCF, 0x65AB,
+	0x9DD0, 0x65B7, 0x9DD1, 0x65C3, 0x9DD2, 0x65C6, 0x9DD3, 0x65C1,
+	0x9DD4, 0x65C4, 0x9DD5, 0x65CC, 0x9DD6, 0x65D2, 0x9DD7, 0x65DB,
+	0x9DD8, 0x65D9, 0x9DD9, 0x65E0, 0x9DDA, 0x65E1, 0x9DDB, 0x65F1,
+	0x9DDC, 0x6772, 0x9DDD, 0x660A, 0x9DDE, 0x6603, 0x9DDF, 0x65FB,
+	0x9DE0, 0x6773, 0x9DE1, 0x6635, 0x9DE2, 0x6636, 0x9DE3, 0x6634,
+	0x9DE4, 0x661C, 0x9DE5, 0x664F, 0x9DE6, 0x6644, 0x9DE7, 0x6649,
+	0x9DE8, 0x6641, 0x9DE9, 0x665E, 0x9DEA, 0x665D, 0x9DEB, 0x6664,
+	0x9DEC, 0x6667, 0x9DED, 0x6668, 0x9DEE, 0x665F, 0x9DEF, 0x6662,
+	0x9DF0, 0x6670, 0x9DF1, 0x6683, 0x9DF2, 0x6688, 0x9DF3, 0x668E,
+	0x9DF4, 0x6689, 0x9DF5, 0x6684, 0x9DF6, 0x6698, 0x9DF7, 0x669D,
+	0x9DF8, 0x66C1, 0x9DF9, 0x66B9, 0x9DFA, 0x66C9, 0x9DFB, 0x66BE,
+	0x9DFC, 0x66BC, 0x9E40, 0x66C4, 0x9E41, 0x66B8, 0x9E42, 0x66D6,
+	0x9E43, 0x66DA, 0x9E44, 0x66E0, 0x9E45, 0x663F, 0x9E46, 0x66E6,
+	0x9E47, 0x66E9, 0x9E48, 0x66F0, 0x9E49, 0x66F5, 0x9E4A, 0x66F7,
+	0x9E4B, 0x670F, 0x9E4C, 0x6716, 0x9E4D, 0x671E, 0x9E4E, 0x6726,
+	0x9E4F, 0x6727, 0x9E50, 0x9738, 0x9E51, 0x672E, 0x9E52, 0x673F,
+	0x9E53, 0x6736, 0x9E54, 0x6741, 0x9E55, 0x6738, 0x9E56, 0x6737,
+	0x9E57, 0x6746, 0x9E58, 0x675E, 0x9E59, 0x6760, 0x9E5A, 0x6759,
+	0x9E5B, 0x6763, 0x9E5C, 0x6764, 0x9E5D, 0x6789, 0x9E5E, 0x6770,
+	0x9E5F, 0x67A9, 0x9E60, 0x677C, 0x9E61, 0x676A, 0x9E62, 0x678C,
+	0x9E63, 0x678B, 0x9E64, 0x67A6, 0x9E65, 0x67A1, 0x9E66, 0x6785,
+	0x9E67, 0x67B7, 0x9E68, 0x67EF, 0x9E69, 0x67B4, 0x9E6A, 0x67EC,
+	0x9E6B, 0x67B3, 0x9E6C, 0x67E9, 0x9E6D, 0x67B8, 0x9E6E, 0x67E4,
+	0x9E6F, 0x67DE, 0x9E70, 0x67DD, 0x9E71, 0x67E2, 0x9E72, 0x67EE,
+	0x9E73, 0x67B9, 0x9E74, 0x67CE, 0x9E75, 0x67C6, 0x9E76, 0x67E7,
+	0x9E77, 0x6A9C, 0x9E78, 0x681E, 0x9E79, 0x6846, 0x9E7A, 0x6829,
+	0x9E7B, 0x6840, 0x9E7C, 0x684D, 0x9E7D, 0x6832, 0x9E7E, 0x684E,
+	0x9E80, 0x68B3, 0x9E81, 0x682B, 0x9E82, 0x6859, 0x9E83, 0x6863,
+	0x9E84, 0x6877, 0x9E85, 0x687F, 0x9E86, 0x689F, 0x9E87, 0x688F,
+	0x9E88, 0x68AD, 0x9E89, 0x6894, 0x9E8A, 0x689D, 0x9E8B, 0x689B,
+	0x9E8C, 0x6883, 0x9E8D, 0x6AAE, 0x9E8E, 0x68B9, 0x9E8F, 0x6874,
+	0x9E90, 0x68B5, 0x9E91, 0x68A0, 0x9E92, 0x68BA, 0x9E93, 0x690F,
+	0x9E94, 0x688D, 0x9E95, 0x687E, 0x9E96, 0x6901, 0x9E97, 0x68CA,
+	0x9E98, 0x6908, 0x9E99, 0x68D8, 0x9E9A, 0x6922, 0x9E9B, 0x6926,
+	0x9E9C, 0x68E1, 0x9E9D, 0x690C, 0x9E9E, 0x68CD, 0x9E9F, 0x68D4,
+	0x9EA0, 0x68E7, 0x9EA1, 0x68D5, 0x9EA2, 0x6936, 0x9EA3, 0x6912,
+	0x9EA4, 0x6904, 0x9EA5, 0x68D7, 0x9EA6, 0x68E3, 0x9EA7, 0x6925,
+	0x9EA8, 0x68F9, 0x9EA9, 0x68E0, 0x9EAA, 0x68EF, 0x9EAB, 0x6928,
+	0x9EAC, 0x692A, 0x9EAD, 0x691A, 0x9EAE, 0x6923, 0x9EAF, 0x6921,
+	0x9EB0, 0x68C6, 0x9EB1, 0x6979, 0x9EB2, 0x6977, 0x9EB3, 0x695C,
+	0x9EB4, 0x6978, 0x9EB5, 0x696B, 0x9EB6, 0x6954, 0x9EB7, 0x697E,
+	0x9EB8, 0x696E, 0x9EB9, 0x6939, 0x9EBA, 0x6974, 0x9EBB, 0x693D,
+	0x9EBC, 0x6959, 0x9EBD, 0x6930, 0x9EBE, 0x6961, 0x9EBF, 0x695E,
+	0x9EC0, 0x695D, 0x9EC1, 0x6981, 0x9EC2, 0x696A, 0x9EC3, 0x69B2,
+	0x9EC4, 0x69AE, 0x9EC5, 0x69D0, 0x9EC6, 0x69BF, 0x9EC7, 0x69C1,
+	0x9EC8, 0x69D3, 0x9EC9, 0x69BE, 0x9ECA, 0x69CE, 0x9ECB, 0x5BE8,
+	0x9ECC, 0x69CA, 0x9ECD, 0x69DD, 0x9ECE, 0x69BB, 0x9ECF, 0x69C3,
+	0x9ED0, 0x69A7, 0x9ED1, 0x6A2E, 0x9ED2, 0x6991, 0x9ED3, 0x69A0,
+	0x9ED4, 0x699C, 0x9ED5, 0x6995, 0x9ED6, 0x69B4, 0x9ED7, 0x69DE,
+	0x9ED8, 0x69E8, 0x9ED9, 0x6A02, 0x9EDA, 0x6A1B, 0x9EDB, 0x69FF,
+	0x9EDC, 0x6B0A, 0x9EDD, 0x69F9, 0x9EDE, 0x69F2, 0x9EDF, 0x69E7,
+	0x9EE0, 0x6A05, 0x9EE1, 0x69B1, 0x9EE2, 0x6A1E, 0x9EE3, 0x69ED,
+	0x9EE4, 0x6A14, 0x9EE5, 0x69EB, 0x9EE6, 0x6A0A, 0x9EE7, 0x6A12,
+	0x9EE8, 0x6AC1, 0x9EE9, 0x6A23, 0x9EEA, 0x6A13, 0x9EEB, 0x6A44,
+	0x9EEC, 0x6A0C, 0x9EED, 0x6A72, 0x9EEE, 0x6A36, 0x9EEF, 0x6A78,
+	0x9EF0, 0x6A47, 0x9EF1, 0x6A62, 0x9EF2, 0x6A59, 0x9EF3, 0x6A66,
+	0x9EF4, 0x6A48, 0x9EF5, 0x6A38, 0x9EF6, 0x6A22, 0x9EF7, 0x6A90,
+	0x9EF8, 0x6A8D, 0x9EF9, 0x6AA0, 0x9EFA, 0x6A84, 0x9EFB, 0x6AA2,
+	0x9EFC, 0x6AA3, 0x9F40, 0x6A97, 0x9F41, 0x8617, 0x9F42, 0x6ABB,
+	0x9F43, 0x6AC3, 0x9F44, 0x6AC2, 0x9F45, 0x6AB8, 0x9F46, 0x6AB3,
+	0x9F47, 0x6AAC, 0x9F48, 0x6ADE, 0x9F49, 0x6AD1, 0x9F4A, 0x6ADF,
+	0x9F4B, 0x6AAA, 0x9F4C, 0x6ADA, 0x9F4D, 0x6AEA, 0x9F4E, 0x6AFB,
+	0x9F4F, 0x6B05, 0x9F50, 0x8616, 0x9F51, 0x6AFA, 0x9F52, 0x6B12,
+	0x9F53, 0x6B16, 0x9F54, 0x9B31, 0x9F55, 0x6B1F, 0x9F56, 0x6B38,
+	0x9F57, 0x6B37, 0x9F58, 0x76DC, 0x9F59, 0x6B39, 0x9F5A, 0x98EE,
+	0x9F5B, 0x6B47, 0x9F5C, 0x6B43, 0x9F5D, 0x6B49, 0x9F5E, 0x6B50,
+	0x9F5F, 0x6B59, 0x9F60, 0x6B54, 0x9F61, 0x6B5B, 0x9F62, 0x6B5F,
+	0x9F63, 0x6B61, 0x9F64, 0x6B78, 0x9F65, 0x6B79, 0x9F66, 0x6B7F,
+	0x9F67, 0x6B80, 0x9F68, 0x6B84, 0x9F69, 0x6B83, 0x9F6A, 0x6B8D,
+	0x9F6B, 0x6B98, 0x9F6C, 0x6B95, 0x9F6D, 0x6B9E, 0x9F6E, 0x6BA4,
+	0x9F6F, 0x6BAA, 0x9F70, 0x6BAB, 0x9F71, 0x6BAF, 0x9F72, 0x6BB2,
+	0x9F73, 0x6BB1, 0x9F74, 0x6BB3, 0x9F75, 0x6BB7, 0x9F76, 0x6BBC,
+	0x9F77, 0x6BC6, 0x9F78, 0x6BCB, 0x9F79, 0x6BD3, 0x9F7A, 0x6BDF,
+	0x9F7B, 0x6BEC, 0x9F7C, 0x6BEB, 0x9F7D, 0x6BF3, 0x9F7E, 0x6BEF,
+	0x9F80, 0x9EBE, 0x9F81, 0x6C08, 0x9F82, 0x6C13, 0x9F83, 0x6C14,
+	0x9F84, 0x6C1B, 0x9F85, 0x6C24, 0x9F86, 0x6C23, 0x9F87, 0x6C5E,
+	0x9F88, 0x6C55, 0x9F89, 0x6C62, 0x9F8A, 0x6C6A, 0x9F8B, 0x6C82,
+	0x9F8C, 0x6C8D, 0x9F8D, 0x6C9A, 0x9F8E, 0x6C81, 0x9F8F, 0x6C9B,
+	0x9F90, 0x6C7E, 0x9F91, 0x6C68, 0x9F92, 0x6C73, 0x9F93, 0x6C92,
+	0x9F94, 0x6C90, 0x9F95, 0x6CC4, 0x9F96, 0x6CF1, 0x9F97, 0x6CD3,
+	0x9F98, 0x6CBD, 0x9F99, 0x6CD7, 0x9F9A, 0x6CC5, 0x9F9B, 0x6CDD,
+	0x9F9C, 0x6CAE, 0x9F9D, 0x6CB1, 0x9F9E, 0x6CBE, 0x9F9F, 0x6CBA,
+	0x9FA0, 0x6CDB, 0x9FA1, 0x6CEF, 0x9FA2, 0x6CD9, 0x9FA3, 0x6CEA,
+	0x9FA4, 0x6D1F, 0x9FA5, 0x884D, 0x9FA6, 0x6D36, 0x9FA7, 0x6D2B,
+	0x9FA8, 0x6D3D, 0x9FA9, 0x6D38, 0x9FAA, 0x6D19, 0x9FAB, 0x6D35,
+	0x9FAC, 0x6D33, 0x9FAD, 0x6D12, 0x9FAE, 0x6D0C, 0x9FAF, 0x6D63,
+	0x9FB0, 0x6D93, 0x9FB1, 0x6D64, 0x9FB2, 0x6D5A, 0x9FB3, 0x6D79,
+	0x9FB4, 0x6D59, 0x9FB5, 0x6D8E, 0x9FB6, 0x6D95, 0x9FB7, 0x6FE4,
+	0x9FB8, 0x6D85, 0x9FB9, 0x6DF9, 0x9FBA, 0x6E15, 0x9FBB, 0x6E0A,
+	0x9FBC, 0x6DB5, 0x9FBD, 0x6DC7, 0x9FBE, 0x6DE6, 0x9FBF, 0x6DB8,
+	0x9FC0, 0x6DC6, 0x9FC1, 0x6DEC, 0x9FC2, 0x6DDE, 0x9FC3, 0x6DCC,
+	0x9FC4, 0x6DE8, 0x9FC5, 0x6DD2, 0x9FC6, 0x6DC5, 0x9FC7, 0x6DFA,
+	0x9FC8, 0x6DD9, 0x9FC9, 0x6DE4, 0x9FCA, 0x6DD5, 0x9FCB, 0x6DEA,
+	0x9FCC, 0x6DEE, 0x9FCD, 0x6E2D, 0x9FCE, 0x6E6E, 0x9FCF, 0x6E2E,
+	0x9FD0, 0x6E19, 0x9FD1, 0x6E72, 0x9FD2, 0x6E5F, 0x9FD3, 0x6E3E,
+	0x9FD4, 0x6E23, 0x9FD5, 0x6E6B, 0x9FD6, 0x6E2B, 0x9FD7, 0x6E76,
+	0x9FD8, 0x6E4D, 0x9FD9, 0x6E1F, 0x9FDA, 0x6E43, 0x9FDB, 0x6E3A,
+	0x9FDC, 0x6E4E, 0x9FDD, 0x6E24, 0x9FDE, 0x6EFF, 0x9FDF, 0x6E1D,
+	0x9FE0, 0x6E38, 0x9FE1, 0x6E82, 0x9FE2, 0x6EAA, 0x9FE3, 0x6E98,
+	0x9FE4, 0x6EC9, 0x9FE5, 0x6EB7, 0x9FE6, 0x6ED3, 0x9FE7, 0x6EBD,
+	0x9FE8, 0x6EAF, 0x9FE9, 0x6EC4, 0x9FEA, 0x6EB2, 0x9FEB, 0x6ED4,
+	0x9FEC, 0x6ED5, 0x9FED, 0x6E8F, 0x9FEE, 0x6EA5, 0x9FEF, 0x6EC2,
+	0x9FF0, 0x6E9F, 0x9FF1, 0x6F41, 0x9FF2, 0x6F11, 0x9FF3, 0x704C,
+	0x9FF4, 0x6EEC, 0x9FF5, 0x6EF8, 0x9FF6, 0x6EFE, 0x9FF7, 0x6F3F,
+	0x9FF8, 0x6EF2, 0x9FF9, 0x6F31, 0x9FFA, 0x6EEF, 0x9FFB, 0x6F32,
+	0x9FFC, 0x6ECC, 0xE040, 0x6F3E, 0xE041, 0x6F13, 0xE042, 0x6EF7,
+	0xE043, 0x6F86, 0xE044, 0x6F7A, 0xE045, 0x6F78, 0xE046, 0x6F81,
+	0xE047, 0x6F80, 0xE048, 0x6F6F, 0xE049, 0x6F5B, 0xE04A, 0x6FF3,
+	0xE04B, 0x6F6D, 0xE04C, 0x6F82, 0xE04D, 0x6F7C, 0xE04E, 0x6F58,
+	0xE04F, 0x6F8E, 0xE050, 0x6F91, 0xE051, 0x6FC2, 0xE052, 0x6F66,
+	0xE053, 0x6FB3, 0xE054, 0x6FA3, 0xE055, 0x6FA1, 0xE056, 0x6FA4,
+	0xE057, 0x6FB9, 0xE058, 0x6FC6, 0xE059, 0x6FAA, 0xE05A, 0x6FDF,
+	0xE05B, 0x6FD5, 0xE05C, 0x6FEC, 0xE05D, 0x6FD4, 0xE05E, 0x6FD8,
+	0xE05F, 0x6FF1, 0xE060, 0x6FEE, 0xE061, 0x6FDB, 0xE062, 0x7009,
+	0xE063, 0x700B, 0xE064, 0x6FFA, 0xE065, 0x7011, 0xE066, 0x7001,
+	0xE067, 0x700F, 0xE068, 0x6FFE, 0xE069, 0x701B, 0xE06A, 0x701A,
+	0xE06B, 0x6F74, 0xE06C, 0x701D, 0xE06D, 0x7018, 0xE06E, 0x701F,
+	0xE06F, 0x7030, 0xE070, 0x703E, 0xE071, 0x7032, 0xE072, 0x7051,
+	0xE073, 0x7063, 0xE074, 0x7099, 0xE075, 0x7092, 0xE076, 0x70AF,
+	0xE077, 0x70F1, 0xE078, 0x70AC, 0xE079, 0x70B8, 0xE07A, 0x70B3,
+	0xE07B, 0x70AE, 0xE07C, 0x70DF, 0xE07D, 0x70CB, 0xE07E, 0x70DD,
+	0xE080, 0x70D9, 0xE081, 0x7109, 0xE082, 0x70FD, 0xE083, 0x711C,
+	0xE084, 0x7119, 0xE085, 0x7165, 0xE086, 0x7155, 0xE087, 0x7188,
+	0xE088, 0x7166, 0xE089, 0x7162, 0xE08A, 0x714C, 0xE08B, 0x7156,
+	0xE08C, 0x716C, 0xE08D, 0x718F, 0xE08E, 0x71FB, 0xE08F, 0x7184,
+	0xE090, 0x7195, 0xE091, 0x71A8, 0xE092, 0x71AC, 0xE093, 0x71D7,
+	0xE094, 0x71B9, 0xE095, 0x71BE, 0xE096, 0x71D2, 0xE097, 0x71C9,
+	0xE098, 0x71D4, 0xE099, 0x71CE, 0xE09A, 0x71E0, 0xE09B, 0x71EC,
+	0xE09C, 0x71E7, 0xE09D, 0x71F5, 0xE09E, 0x71FC, 0xE09F, 0x71F9,
+	0xE0A0, 0x71FF, 0xE0A1, 0x720D, 0xE0A2, 0x7210, 0xE0A3, 0x721B,
+	0xE0A4, 0x7228, 0xE0A5, 0x722D, 0xE0A6, 0x722C, 0xE0A7, 0x7230,
+	0xE0A8, 0x7232, 0xE0A9, 0x723B, 0xE0AA, 0x723C, 0xE0AB, 0x723F,
+	0xE0AC, 0x7240, 0xE0AD, 0x7246, 0xE0AE, 0x724B, 0xE0AF, 0x7258,
+	0xE0B0, 0x7274, 0xE0B1, 0x727E, 0xE0B2, 0x7282, 0xE0B3, 0x7281,
+	0xE0B4, 0x7287, 0xE0B5, 0x7292, 0xE0B6, 0x7296, 0xE0B7, 0x72A2,
+	0xE0B8, 0x72A7, 0xE0B9, 0x72B9, 0xE0BA, 0x72B2, 0xE0BB, 0x72C3,
+	0xE0BC, 0x72C6, 0xE0BD, 0x72C4, 0xE0BE, 0x72CE, 0xE0BF, 0x72D2,
+	0xE0C0, 0x72E2, 0xE0C1, 0x72E0, 0xE0C2, 0x72E1, 0xE0C3, 0x72F9,
+	0xE0C4, 0x72F7, 0xE0C5, 0x500F, 0xE0C6, 0x7317, 0xE0C7, 0x730A,
+	0xE0C8, 0x731C, 0xE0C9, 0x7316, 0xE0CA, 0x731D, 0xE0CB, 0x7334,
+	0xE0CC, 0x732F, 0xE0CD, 0x7329, 0xE0CE, 0x7325, 0xE0CF, 0x733E,
+	0xE0D0, 0x734E, 0xE0D1, 0x734F, 0xE0D2, 0x9ED8, 0xE0D3, 0x7357,
+	0xE0D4, 0x736A, 0xE0D5, 0x7368, 0xE0D6, 0x7370, 0xE0D7, 0x7378,
+	0xE0D8, 0x7375, 0xE0D9, 0x737B, 0xE0DA, 0x737A, 0xE0DB, 0x73C8,
+	0xE0DC, 0x73B3, 0xE0DD, 0x73CE, 0xE0DE, 0x73BB, 0xE0DF, 0x73C0,
+	0xE0E0, 0x73E5, 0xE0E1, 0x73EE, 0xE0E2, 0x73DE, 0xE0E3, 0x74A2,
+	0xE0E4, 0x7405, 0xE0E5, 0x746F, 0xE0E6, 0x7425, 0xE0E7, 0x73F8,
+	0xE0E8, 0x7432, 0xE0E9, 0x743A, 0xE0EA, 0x7455, 0xE0EB, 0x743F,
+	0xE0EC, 0x745F, 0xE0ED, 0x7459, 0xE0EE, 0x7441, 0xE0EF, 0x745C,
+	0xE0F0, 0x7469, 0xE0F1, 0x7470, 0xE0F2, 0x7463, 0xE0F3, 0x746A,
+	0xE0F4, 0x7476, 0xE0F5, 0x747E, 0xE0F6, 0x748B, 0xE0F7, 0x749E,
+	0xE0F8, 0x74A7, 0xE0F9, 0x74CA, 0xE0FA, 0x74CF, 0xE0FB, 0x74D4,
+	0xE0FC, 0x73F1, 0xE140, 0x74E0, 0xE141, 0x74E3, 0xE142, 0x74E7,
+	0xE143, 0x74E9, 0xE144, 0x74EE, 0xE145, 0x74F2, 0xE146, 0x74F0,
+	0xE147, 0x74F1, 0xE148, 0x74F8, 0xE149, 0x74F7, 0xE14A, 0x7504,
+	0xE14B, 0x7503, 0xE14C, 0x7505, 0xE14D, 0x750C, 0xE14E, 0x750E,
+	0xE14F, 0x750D, 0xE150, 0x7515, 0xE151, 0x7513, 0xE152, 0x751E,
+	0xE153, 0x7526, 0xE154, 0x752C, 0xE155, 0x753C, 0xE156, 0x7544,
+	0xE157, 0x754D, 0xE158, 0x754A, 0xE159, 0x7549, 0xE15A, 0x755B,
+	0xE15B, 0x7546, 0xE15C, 0x755A, 0xE15D, 0x7569, 0xE15E, 0x7564,
+	0xE15F, 0x7567, 0xE160, 0x756B, 0xE161, 0x756D, 0xE162, 0x7578,
+	0xE163, 0x7576, 0xE164, 0x7586, 0xE165, 0x7587, 0xE166, 0x7574,
+	0xE167, 0x758A, 0xE168, 0x7589, 0xE169, 0x7582, 0xE16A, 0x7594,
+	0xE16B, 0x759A, 0xE16C, 0x759D, 0xE16D, 0x75A5, 0xE16E, 0x75A3,
+	0xE16F, 0x75C2, 0xE170, 0x75B3, 0xE171, 0x75C3, 0xE172, 0x75B5,
+	0xE173, 0x75BD, 0xE174, 0x75B8, 0xE175, 0x75BC, 0xE176, 0x75B1,
+	0xE177, 0x75CD, 0xE178, 0x75CA, 0xE179, 0x75D2, 0xE17A, 0x75D9,
+	0xE17B, 0x75E3, 0xE17C, 0x75DE, 0xE17D, 0x75FE, 0xE17E, 0x75FF,
+	0xE180, 0x75FC, 0xE181, 0x7601, 0xE182, 0x75F0, 0xE183, 0x75FA,
+	0xE184, 0x75F2, 0xE185, 0x75F3, 0xE186, 0x760B, 0xE187, 0x760D,
+	0xE188, 0x7609, 0xE189, 0x761F, 0xE18A, 0x7627, 0xE18B, 0x7620,
+	0xE18C, 0x7621, 0xE18D, 0x7622, 0xE18E, 0x7624, 0xE18F, 0x7634,
+	0xE190, 0x7630, 0xE191, 0x763B, 0xE192, 0x7647, 0xE193, 0x7648,
+	0xE194, 0x7646, 0xE195, 0x765C, 0xE196, 0x7658, 0xE197, 0x7661,
+	0xE198, 0x7662, 0xE199, 0x7668, 0xE19A, 0x7669, 0xE19B, 0x766A,
+	0xE19C, 0x7667, 0xE19D, 0x766C, 0xE19E, 0x7670, 0xE19F, 0x7672,
+	0xE1A0, 0x7676, 0xE1A1, 0x7678, 0xE1A2, 0x767C, 0xE1A3, 0x7680,
+	0xE1A4, 0x7683, 0xE1A5, 0x7688, 0xE1A6, 0x768B, 0xE1A7, 0x768E,
+	0xE1A8, 0x7696, 0xE1A9, 0x7693, 0xE1AA, 0x7699, 0xE1AB, 0x769A,
+	0xE1AC, 0x76B0, 0xE1AD, 0x76B4, 0xE1AE, 0x76B8, 0xE1AF, 0x76B9,
+	0xE1B0, 0x76BA, 0xE1B1, 0x76C2, 0xE1B2, 0x76CD, 0xE1B3, 0x76D6,
+	0xE1B4, 0x76D2, 0xE1B5, 0x76DE, 0xE1B6, 0x76E1, 0xE1B7, 0x76E5,
+	0xE1B8, 0x76E7, 0xE1B9, 0x76EA, 0xE1BA, 0x862F, 0xE1BB, 0x76FB,
+	0xE1BC, 0x7708, 0xE1BD, 0x7707, 0xE1BE, 0x7704, 0xE1BF, 0x7729,
+	0xE1C0, 0x7724, 0xE1C1, 0x771E, 0xE1C2, 0x7725, 0xE1C3, 0x7726,
+	0xE1C4, 0x771B, 0xE1C5, 0x7737, 0xE1C6, 0x7738, 0xE1C7, 0x7747,
+	0xE1C8, 0x775A, 0xE1C9, 0x7768, 0xE1CA, 0x776B, 0xE1CB, 0x775B,
+	0xE1CC, 0x7765, 0xE1CD, 0x777F, 0xE1CE, 0x777E, 0xE1CF, 0x7779,
+	0xE1D0, 0x778E, 0xE1D1, 0x778B, 0xE1D2, 0x7791, 0xE1D3, 0x77A0,
+	0xE1D4, 0x779E, 0xE1D5, 0x77B0, 0xE1D6, 0x77B6, 0xE1D7, 0x77B9,
+	0xE1D8, 0x77BF, 0xE1D9, 0x77BC, 0xE1DA, 0x77BD, 0xE1DB, 0x77BB,
+	0xE1DC, 0x77C7, 0xE1DD, 0x77CD, 0xE1DE, 0x77D7, 0xE1DF, 0x77DA,
+	0xE1E0, 0x77DC, 0xE1E1, 0x77E3, 0xE1E2, 0x77EE, 0xE1E3, 0x77FC,
+	0xE1E4, 0x780C, 0xE1E5, 0x7812, 0xE1E6, 0x7926, 0xE1E7, 0x7820,
+	0xE1E8, 0x792A, 0xE1E9, 0x7845, 0xE1EA, 0x788E, 0xE1EB, 0x7874,
+	0xE1EC, 0x7886, 0xE1ED, 0x787C, 0xE1EE, 0x789A, 0xE1EF, 0x788C,
+	0xE1F0, 0x78A3, 0xE1F1, 0x78B5, 0xE1F2, 0x78AA, 0xE1F3, 0x78AF,
+	0xE1F4, 0x78D1, 0xE1F5, 0x78C6, 0xE1F6, 0x78CB, 0xE1F7, 0x78D4,
+	0xE1F8, 0x78BE, 0xE1F9, 0x78BC, 0xE1FA, 0x78C5, 0xE1FB, 0x78CA,
+	0xE1FC, 0x78EC, 0xE240, 0x78E7, 0xE241, 0x78DA, 0xE242, 0x78FD,
+	0xE243, 0x78F4, 0xE244, 0x7907, 0xE245, 0x7912, 0xE246, 0x7911,
+	0xE247, 0x7919, 0xE248, 0x792C, 0xE249, 0x792B, 0xE24A, 0x7940,
+	0xE24B, 0x7960, 0xE24C, 0x7957, 0xE24D, 0x795F, 0xE24E, 0x795A,
+	0xE24F, 0x7955, 0xE250, 0x7953, 0xE251, 0x797A, 0xE252, 0x797F,
+	0xE253, 0x798A, 0xE254, 0x799D, 0xE255, 0x79A7, 0xE256, 0x9F4B,
+	0xE257, 0x79AA, 0xE258, 0x79AE, 0xE259, 0x79B3, 0xE25A, 0x79B9,
+	0xE25B, 0x79BA, 0xE25C, 0x79C9, 0xE25D, 0x79D5, 0xE25E, 0x79E7,
+	0xE25F, 0x79EC, 0xE260, 0x79E1, 0xE261, 0x79E3, 0xE262, 0x7A08,
+	0xE263, 0x7A0D, 0xE264, 0x7A18, 0xE265, 0x7A19, 0xE266, 0x7A20,
+	0xE267, 0x7A1F, 0xE268, 0x7980, 0xE269, 0x7A31, 0xE26A, 0x7A3B,
+	0xE26B, 0x7A3E, 0xE26C, 0x7A37, 0xE26D, 0x7A43, 0xE26E, 0x7A57,
+	0xE26F, 0x7A49, 0xE270, 0x7A61, 0xE271, 0x7A62, 0xE272, 0x7A69,
+	0xE273, 0x9F9D, 0xE274, 0x7A70, 0xE275, 0x7A79, 0xE276, 0x7A7D,
+	0xE277, 0x7A88, 0xE278, 0x7A97, 0xE279, 0x7A95, 0xE27A, 0x7A98,
+	0xE27B, 0x7A96, 0xE27C, 0x7AA9, 0xE27D, 0x7AC8, 0xE27E, 0x7AB0,
+	0xE280, 0x7AB6, 0xE281, 0x7AC5, 0xE282, 0x7AC4, 0xE283, 0x7ABF,
+	0xE284, 0x9083, 0xE285, 0x7AC7, 0xE286, 0x7ACA, 0xE287, 0x7ACD,
+	0xE288, 0x7ACF, 0xE289, 0x7AD5, 0xE28A, 0x7AD3, 0xE28B, 0x7AD9,
+	0xE28C, 0x7ADA, 0xE28D, 0x7ADD, 0xE28E, 0x7AE1, 0xE28F, 0x7AE2,
+	0xE290, 0x7AE6, 0xE291, 0x7AED, 0xE292, 0x7AF0, 0xE293, 0x7B02,
+	0xE294, 0x7B0F, 0xE295, 0x7B0A, 0xE296, 0x7B06, 0xE297, 0x7B33,
+	0xE298, 0x7B18, 0xE299, 0x7B19, 0xE29A, 0x7B1E, 0xE29B, 0x7B35,
+	0xE29C, 0x7B28, 0xE29D, 0x7B36, 0xE29E, 0x7B50, 0xE29F, 0x7B7A,
+	0xE2A0, 0x7B04, 0xE2A1, 0x7B4D, 0xE2A2, 0x7B0B, 0xE2A3, 0x7B4C,
+	0xE2A4, 0x7B45, 0xE2A5, 0x7B75, 0xE2A6, 0x7B65, 0xE2A7, 0x7B74,
+	0xE2A8, 0x7B67, 0xE2A9, 0x7B70, 0xE2AA, 0x7B71, 0xE2AB, 0x7B6C,
+	0xE2AC, 0x7B6E, 0xE2AD, 0x7B9D, 0xE2AE, 0x7B98, 0xE2AF, 0x7B9F,
+	0xE2B0, 0x7B8D, 0xE2B1, 0x7B9C, 0xE2B2, 0x7B9A, 0xE2B3, 0x7B8B,
+	0xE2B4, 0x7B92, 0xE2B5, 0x7B8F, 0xE2B6, 0x7B5D, 0xE2B7, 0x7B99,
+	0xE2B8, 0x7BCB, 0xE2B9, 0x7BC1, 0xE2BA, 0x7BCC, 0xE2BB, 0x7BCF,
+	0xE2BC, 0x7BB4, 0xE2BD, 0x7BC6, 0xE2BE, 0x7BDD, 0xE2BF, 0x7BE9,
+	0xE2C0, 0x7C11, 0xE2C1, 0x7C14, 0xE2C2, 0x7BE6, 0xE2C3, 0x7BE5,
+	0xE2C4, 0x7C60, 0xE2C5, 0x7C00, 0xE2C6, 0x7C07, 0xE2C7, 0x7C13,
+	0xE2C8, 0x7BF3, 0xE2C9, 0x7BF7, 0xE2CA, 0x7C17, 0xE2CB, 0x7C0D,
+	0xE2CC, 0x7BF6, 0xE2CD, 0x7C23, 0xE2CE, 0x7C27, 0xE2CF, 0x7C2A,
+	0xE2D0, 0x7C1F, 0xE2D1, 0x7C37, 0xE2D2, 0x7C2B, 0xE2D3, 0x7C3D,
+	0xE2D4, 0x7C4C, 0xE2D5, 0x7C43, 0xE2D6, 0x7C54, 0xE2D7, 0x7C4F,
+	0xE2D8, 0x7C40, 0xE2D9, 0x7C50, 0xE2DA, 0x7C58, 0xE2DB, 0x7C5F,
+	0xE2DC, 0x7C64, 0xE2DD, 0x7C56, 0xE2DE, 0x7C65, 0xE2DF, 0x7C6C,
+	0xE2E0, 0x7C75, 0xE2E1, 0x7C83, 0xE2E2, 0x7C90, 0xE2E3, 0x7CA4,
+	0xE2E4, 0x7CAD, 0xE2E5, 0x7CA2, 0xE2E6, 0x7CAB, 0xE2E7, 0x7CA1,
+	0xE2E8, 0x7CA8, 0xE2E9, 0x7CB3, 0xE2EA, 0x7CB2, 0xE2EB, 0x7CB1,
+	0xE2EC, 0x7CAE, 0xE2ED, 0x7CB9, 0xE2EE, 0x7CBD, 0xE2EF, 0x7CC0,
+	0xE2F0, 0x7CC5, 0xE2F1, 0x7CC2, 0xE2F2, 0x7CD8, 0xE2F3, 0x7CD2,
+	0xE2F4, 0x7CDC, 0xE2F5, 0x7CE2, 0xE2F6, 0x9B3B, 0xE2F7, 0x7CEF,
+	0xE2F8, 0x7CF2, 0xE2F9, 0x7CF4, 0xE2FA, 0x7CF6, 0xE2FB, 0x7CFA,
+	0xE2FC, 0x7D06, 0xE340, 0x7D02, 0xE341, 0x7D1C, 0xE342, 0x7D15,
+	0xE343, 0x7D0A, 0xE344, 0x7D45, 0xE345, 0x7D4B, 0xE346, 0x7D2E,
+	0xE347, 0x7D32, 0xE348, 0x7D3F, 0xE349, 0x7D35, 0xE34A, 0x7D46,
+	0xE34B, 0x7D73, 0xE34C, 0x7D56, 0xE34D, 0x7D4E, 0xE34E, 0x7D72,
+	0xE34F, 0x7D68, 0xE350, 0x7D6E, 0xE351, 0x7D4F, 0xE352, 0x7D63,
+	0xE353, 0x7D93, 0xE354, 0x7D89, 0xE355, 0x7D5B, 0xE356, 0x7D8F,
+	0xE357, 0x7D7D, 0xE358, 0x7D9B, 0xE359, 0x7DBA, 0xE35A, 0x7DAE,
+	0xE35B, 0x7DA3, 0xE35C, 0x7DB5, 0xE35D, 0x7DC7, 0xE35E, 0x7DBD,
+	0xE35F, 0x7DAB, 0xE360, 0x7E3D, 0xE361, 0x7DA2, 0xE362, 0x7DAF,
+	0xE363, 0x7DDC, 0xE364, 0x7DB8, 0xE365, 0x7D9F, 0xE366, 0x7DB0,
+	0xE367, 0x7DD8, 0xE368, 0x7DDD, 0xE369, 0x7DE4, 0xE36A, 0x7DDE,
+	0xE36B, 0x7DFB, 0xE36C, 0x7DF2, 0xE36D, 0x7DE1, 0xE36E, 0x7E05,
+	0xE36F, 0x7E0A, 0xE370, 0x7E23, 0xE371, 0x7E21, 0xE372, 0x7E12,
+	0xE373, 0x7E31, 0xE374, 0x7E1F, 0xE375, 0x7E09, 0xE376, 0x7E0B,
+	0xE377, 0x7E22, 0xE378, 0x7E46, 0xE379, 0x7E66, 0xE37A, 0x7E3B,
+	0xE37B, 0x7E35, 0xE37C, 0x7E39, 0xE37D, 0x7E43, 0xE37E, 0x7E37,
+	0xE380, 0x7E32, 0xE381, 0x7E3A, 0xE382, 0x7E67, 0xE383, 0x7E5D,
+	0xE384, 0x7E56, 0xE385, 0x7E5E, 0xE386, 0x7E59, 0xE387, 0x7E5A,
+	0xE388, 0x7E79, 0xE389, 0x7E6A, 0xE38A, 0x7E69, 0xE38B, 0x7E7C,
+	0xE38C, 0x7E7B, 0xE38D, 0x7E83, 0xE38E, 0x7DD5, 0xE38F, 0x7E7D,
+	0xE390, 0x8FAE, 0xE391, 0x7E7F, 0xE392, 0x7E88, 0xE393, 0x7E89,
+	0xE394, 0x7E8C, 0xE395, 0x7E92, 0xE396, 0x7E90, 0xE397, 0x7E93,
+	0xE398, 0x7E94, 0xE399, 0x7E96, 0xE39A, 0x7E8E, 0xE39B, 0x7E9B,
+	0xE39C, 0x7E9C, 0xE39D, 0x7F38, 0xE39E, 0x7F3A, 0xE39F, 0x7F45,
+	0xE3A0, 0x7F4C, 0xE3A1, 0x7F4D, 0xE3A2, 0x7F4E, 0xE3A3, 0x7F50,
+	0xE3A4, 0x7F51, 0xE3A5, 0x7F55, 0xE3A6, 0x7F54, 0xE3A7, 0x7F58,
+	0xE3A8, 0x7F5F, 0xE3A9, 0x7F60, 0xE3AA, 0x7F68, 0xE3AB, 0x7F69,
+	0xE3AC, 0x7F67, 0xE3AD, 0x7F78, 0xE3AE, 0x7F82, 0xE3AF, 0x7F86,
+	0xE3B0, 0x7F83, 0xE3B1, 0x7F88, 0xE3B2, 0x7F87, 0xE3B3, 0x7F8C,
+	0xE3B4, 0x7F94, 0xE3B5, 0x7F9E, 0xE3B6, 0x7F9D, 0xE3B7, 0x7F9A,
+	0xE3B8, 0x7FA3, 0xE3B9, 0x7FAF, 0xE3BA, 0x7FB2, 0xE3BB, 0x7FB9,
+	0xE3BC, 0x7FAE, 0xE3BD, 0x7FB6, 0xE3BE, 0x7FB8, 0xE3BF, 0x8B71,
+	0xE3C0, 0x7FC5, 0xE3C1, 0x7FC6, 0xE3C2, 0x7FCA, 0xE3C3, 0x7FD5,
+	0xE3C4, 0x7FD4, 0xE3C5, 0x7FE1, 0xE3C6, 0x7FE6, 0xE3C7, 0x7FE9,
+	0xE3C8, 0x7FF3, 0xE3C9, 0x7FF9, 0xE3CA, 0x98DC, 0xE3CB, 0x8006,
+	0xE3CC, 0x8004, 0xE3CD, 0x800B, 0xE3CE, 0x8012, 0xE3CF, 0x8018,
+	0xE3D0, 0x8019, 0xE3D1, 0x801C, 0xE3D2, 0x8021, 0xE3D3, 0x8028,
+	0xE3D4, 0x803F, 0xE3D5, 0x803B, 0xE3D6, 0x804A, 0xE3D7, 0x8046,
+	0xE3D8, 0x8052, 0xE3D9, 0x8058, 0xE3DA, 0x805A, 0xE3DB, 0x805F,
+	0xE3DC, 0x8062, 0xE3DD, 0x8068, 0xE3DE, 0x8073, 0xE3DF, 0x8072,
+	0xE3E0, 0x8070, 0xE3E1, 0x8076, 0xE3E2, 0x8079, 0xE3E3, 0x807D,
+	0xE3E4, 0x807F, 0xE3E5, 0x8084, 0xE3E6, 0x8086, 0xE3E7, 0x8085,
+	0xE3E8, 0x809B, 0xE3E9, 0x8093, 0xE3EA, 0x809A, 0xE3EB, 0x80AD,
+	0xE3EC, 0x5190, 0xE3ED, 0x80AC, 0xE3EE, 0x80DB, 0xE3EF, 0x80E5,
+	0xE3F0, 0x80D9, 0xE3F1, 0x80DD, 0xE3F2, 0x80C4, 0xE3F3, 0x80DA,
+	0xE3F4, 0x80D6, 0xE3F5, 0x8109, 0xE3F6, 0x80EF, 0xE3F7, 0x80F1,
+	0xE3F8, 0x811B, 0xE3F9, 0x8129, 0xE3FA, 0x8123, 0xE3FB, 0x812F,
+	0xE3FC, 0x814B, 0xE440, 0x968B, 0xE441, 0x8146, 0xE442, 0x813E,
+	0xE443, 0x8153, 0xE444, 0x8151, 0xE445, 0x80FC, 0xE446, 0x8171,
+	0xE447, 0x816E, 0xE448, 0x8165, 0xE449, 0x8166, 0xE44A, 0x8174,
+	0xE44B, 0x8183, 0xE44C, 0x8188, 0xE44D, 0x818A, 0xE44E, 0x8180,
+	0xE44F, 0x8182, 0xE450, 0x81A0, 0xE451, 0x8195, 0xE452, 0x81A4,
+	0xE453, 0x81A3, 0xE454, 0x815F, 0xE455, 0x8193, 0xE456, 0x81A9,
+	0xE457, 0x81B0, 0xE458, 0x81B5, 0xE459, 0x81BE, 0xE45A, 0x81B8,
+	0xE45B, 0x81BD, 0xE45C, 0x81C0, 0xE45D, 0x81C2, 0xE45E, 0x81BA,
+	0xE45F, 0x81C9, 0xE460, 0x81CD, 0xE461, 0x81D1, 0xE462, 0x81D9,
+	0xE463, 0x81D8, 0xE464, 0x81C8, 0xE465, 0x81DA, 0xE466, 0x81DF,
+	0xE467, 0x81E0, 0xE468, 0x81E7, 0xE469, 0x81FA, 0xE46A, 0x81FB,
+	0xE46B, 0x81FE, 0xE46C, 0x8201, 0xE46D, 0x8202, 0xE46E, 0x8205,
+	0xE46F, 0x8207, 0xE470, 0x820A, 0xE471, 0x820D, 0xE472, 0x8210,
+	0xE473, 0x8216, 0xE474, 0x8229, 0xE475, 0x822B, 0xE476, 0x8238,
+	0xE477, 0x8233, 0xE478, 0x8240, 0xE479, 0x8259, 0xE47A, 0x8258,
+	0xE47B, 0x825D, 0xE47C, 0x825A, 0xE47D, 0x825F, 0xE47E, 0x8264,
+	0xE480, 0x8262, 0xE481, 0x8268, 0xE482, 0x826A, 0xE483, 0x826B,
+	0xE484, 0x822E, 0xE485, 0x8271, 0xE486, 0x8277, 0xE487, 0x8278,
+	0xE488, 0x827E, 0xE489, 0x828D, 0xE48A, 0x8292, 0xE48B, 0x82AB,
+	0xE48C, 0x829F, 0xE48D, 0x82BB, 0xE48E, 0x82AC, 0xE48F, 0x82E1,
+	0xE490, 0x82E3, 0xE491, 0x82DF, 0xE492, 0x82D2, 0xE493, 0x82F4,
+	0xE494, 0x82F3, 0xE495, 0x82FA, 0xE496, 0x8393, 0xE497, 0x8303,
+	0xE498, 0x82FB, 0xE499, 0x82F9, 0xE49A, 0x82DE, 0xE49B, 0x8306,
+	0xE49C, 0x82DC, 0xE49D, 0x8309, 0xE49E, 0x82D9, 0xE49F, 0x8335,
+	0xE4A0, 0x8334, 0xE4A1, 0x8316, 0xE4A2, 0x8332, 0xE4A3, 0x8331,
+	0xE4A4, 0x8340, 0xE4A5, 0x8339, 0xE4A6, 0x8350, 0xE4A7, 0x8345,
+	0xE4A8, 0x832F, 0xE4A9, 0x832B, 0xE4AA, 0x8317, 0xE4AB, 0x8318,
+	0xE4AC, 0x8385, 0xE4AD, 0x839A, 0xE4AE, 0x83AA, 0xE4AF, 0x839F,
+	0xE4B0, 0x83A2, 0xE4B1, 0x8396, 0xE4B2, 0x8323, 0xE4B3, 0x838E,
+	0xE4B4, 0x8387, 0xE4B5, 0x838A, 0xE4B6, 0x837C, 0xE4B7, 0x83B5,
+	0xE4B8, 0x8373, 0xE4B9, 0x8375, 0xE4BA, 0x83A0, 0xE4BB, 0x8389,
+	0xE4BC, 0x83A8, 0xE4BD, 0x83F4, 0xE4BE, 0x8413, 0xE4BF, 0x83EB,
+	0xE4C0, 0x83CE, 0xE4C1, 0x83FD, 0xE4C2, 0x8403, 0xE4C3, 0x83D8,
+	0xE4C4, 0x840B, 0xE4C5, 0x83C1, 0xE4C6, 0x83F7, 0xE4C7, 0x8407,
+	0xE4C8, 0x83E0, 0xE4C9, 0x83F2, 0xE4CA, 0x840D, 0xE4CB, 0x8422,
+	0xE4CC, 0x8420, 0xE4CD, 0x83BD, 0xE4CE, 0x8438, 0xE4CF, 0x8506,
+	0xE4D0, 0x83FB, 0xE4D1, 0x846D, 0xE4D2, 0x842A, 0xE4D3, 0x843C,
+	0xE4D4, 0x855A, 0xE4D5, 0x8484, 0xE4D6, 0x8477, 0xE4D7, 0x846B,
+	0xE4D8, 0x84AD, 0xE4D9, 0x846E, 0xE4DA, 0x8482, 0xE4DB, 0x8469,
+	0xE4DC, 0x8446, 0xE4DD, 0x842C, 0xE4DE, 0x846F, 0xE4DF, 0x8479,
+	0xE4E0, 0x8435, 0xE4E1, 0x84CA, 0xE4E2, 0x8462, 0xE4E3, 0x84B9,
+	0xE4E4, 0x84BF, 0xE4E5, 0x849F, 0xE4E6, 0x84D9, 0xE4E7, 0x84CD,
+	0xE4E8, 0x84BB, 0xE4E9, 0x84DA, 0xE4EA, 0x84D0, 0xE4EB, 0x84C1,
+	0xE4EC, 0x84C6, 0xE4ED, 0x84D6, 0xE4EE, 0x84A1, 0xE4EF, 0x8521,
+	0xE4F0, 0x84FF, 0xE4F1, 0x84F4, 0xE4F2, 0x8517, 0xE4F3, 0x8518,
+	0xE4F4, 0x852C, 0xE4F5, 0x851F, 0xE4F6, 0x8515, 0xE4F7, 0x8514,
+	0xE4F8, 0x84FC, 0xE4F9, 0x8540, 0xE4FA, 0x8563, 0xE4FB, 0x8558,
+	0xE4FC, 0x8548, 0xE540, 0x8541, 0xE541, 0x8602, 0xE542, 0x854B,
+	0xE543, 0x8555, 0xE544, 0x8580, 0xE545, 0x85A4, 0xE546, 0x8588,
+	0xE547, 0x8591, 0xE548, 0x858A, 0xE549, 0x85A8, 0xE54A, 0x856D,
+	0xE54B, 0x8594, 0xE54C, 0x859B, 0xE54D, 0x85EA, 0xE54E, 0x8587,
+	0xE54F, 0x859C, 0xE550, 0x8577, 0xE551, 0x857E, 0xE552, 0x8590,
+	0xE553, 0x85C9, 0xE554, 0x85BA, 0xE555, 0x85CF, 0xE556, 0x85B9,
+	0xE557, 0x85D0, 0xE558, 0x85D5, 0xE559, 0x85DD, 0xE55A, 0x85E5,
+	0xE55B, 0x85DC, 0xE55C, 0x85F9, 0xE55D, 0x860A, 0xE55E, 0x8613,
+	0xE55F, 0x860B, 0xE560, 0x85FE, 0xE561, 0x85FA, 0xE562, 0x8606,
+	0xE563, 0x8622, 0xE564, 0x861A, 0xE565, 0x8630, 0xE566, 0x863F,
+	0xE567, 0x864D, 0xE568, 0x4E55, 0xE569, 0x8654, 0xE56A, 0x865F,
+	0xE56B, 0x8667, 0xE56C, 0x8671, 0xE56D, 0x8693, 0xE56E, 0x86A3,
+	0xE56F, 0x86A9, 0xE570, 0x86AA, 0xE571, 0x868B, 0xE572, 0x868C,
+	0xE573, 0x86B6, 0xE574, 0x86AF, 0xE575, 0x86C4, 0xE576, 0x86C6,
+	0xE577, 0x86B0, 0xE578, 0x86C9, 0xE579, 0x8823, 0xE57A, 0x86AB,
+	0xE57B, 0x86D4, 0xE57C, 0x86DE, 0xE57D, 0x86E9, 0xE57E, 0x86EC,
+	0xE580, 0x86DF, 0xE581, 0x86DB, 0xE582, 0x86EF, 0xE583, 0x8712,
+	0xE584, 0x8706, 0xE585, 0x8708, 0xE586, 0x8700, 0xE587, 0x8703,
+	0xE588, 0x86FB, 0xE589, 0x8711, 0xE58A, 0x8709, 0xE58B, 0x870D,
+	0xE58C, 0x86F9, 0xE58D, 0x870A, 0xE58E, 0x8734, 0xE58F, 0x873F,
+	0xE590, 0x8737, 0xE591, 0x873B, 0xE592, 0x8725, 0xE593, 0x8729,
+	0xE594, 0x871A, 0xE595, 0x8760, 0xE596, 0x875F, 0xE597, 0x8778,
+	0xE598, 0x874C, 0xE599, 0x874E, 0xE59A, 0x8774, 0xE59B, 0x8757,
+	0xE59C, 0x8768, 0xE59D, 0x876E, 0xE59E, 0x8759, 0xE59F, 0x8753,
+	0xE5A0, 0x8763, 0xE5A1, 0x876A, 0xE5A2, 0x8805, 0xE5A3, 0x87A2,
+	0xE5A4, 0x879F, 0xE5A5, 0x8782, 0xE5A6, 0x87AF, 0xE5A7, 0x87CB,
+	0xE5A8, 0x87BD, 0xE5A9, 0x87C0, 0xE5AA, 0x87D0, 0xE5AB, 0x96D6,
+	0xE5AC, 0x87AB, 0xE5AD, 0x87C4, 0xE5AE, 0x87B3, 0xE5AF, 0x87C7,
+	0xE5B0, 0x87C6, 0xE5B1, 0x87BB, 0xE5B2, 0x87EF, 0xE5B3, 0x87F2,
+	0xE5B4, 0x87E0, 0xE5B5, 0x880F, 0xE5B6, 0x880D, 0xE5B7, 0x87FE,
+	0xE5B8, 0x87F6, 0xE5B9, 0x87F7, 0xE5BA, 0x880E, 0xE5BB, 0x87D2,
+	0xE5BC, 0x8811, 0xE5BD, 0x8816, 0xE5BE, 0x8815, 0xE5BF, 0x8822,
+	0xE5C0, 0x8821, 0xE5C1, 0x8831, 0xE5C2, 0x8836, 0xE5C3, 0x8839,
+	0xE5C4, 0x8827, 0xE5C5, 0x883B, 0xE5C6, 0x8844, 0xE5C7, 0x8842,
+	0xE5C8, 0x8852, 0xE5C9, 0x8859, 0xE5CA, 0x885E, 0xE5CB, 0x8862,
+	0xE5CC, 0x886B, 0xE5CD, 0x8881, 0xE5CE, 0x887E, 0xE5CF, 0x889E,
+	0xE5D0, 0x8875, 0xE5D1, 0x887D, 0xE5D2, 0x88B5, 0xE5D3, 0x8872,
+	0xE5D4, 0x8882, 0xE5D5, 0x8897, 0xE5D6, 0x8892, 0xE5D7, 0x88AE,
+	0xE5D8, 0x8899, 0xE5D9, 0x88A2, 0xE5DA, 0x888D, 0xE5DB, 0x88A4,
+	0xE5DC, 0x88B0, 0xE5DD, 0x88BF, 0xE5DE, 0x88B1, 0xE5DF, 0x88C3,
+	0xE5E0, 0x88C4, 0xE5E1, 0x88D4, 0xE5E2, 0x88D8, 0xE5E3, 0x88D9,
+	0xE5E4, 0x88DD, 0xE5E5, 0x88F9, 0xE5E6, 0x8902, 0xE5E7, 0x88FC,
+	0xE5E8, 0x88F4, 0xE5E9, 0x88E8, 0xE5EA, 0x88F2, 0xE5EB, 0x8904,
+	0xE5EC, 0x890C, 0xE5ED, 0x890A, 0xE5EE, 0x8913, 0xE5EF, 0x8943,
+	0xE5F0, 0x891E, 0xE5F1, 0x8925, 0xE5F2, 0x892A, 0xE5F3, 0x892B,
+	0xE5F4, 0x8941, 0xE5F5, 0x8944, 0xE5F6, 0x893B, 0xE5F7, 0x8936,
+	0xE5F8, 0x8938, 0xE5F9, 0x894C, 0xE5FA, 0x891D, 0xE5FB, 0x8960,
+	0xE5FC, 0x895E, 0xE640, 0x8966, 0xE641, 0x8964, 0xE642, 0x896D,
+	0xE643, 0x896A, 0xE644, 0x896F, 0xE645, 0x8974, 0xE646, 0x8977,
+	0xE647, 0x897E, 0xE648, 0x8983, 0xE649, 0x8988, 0xE64A, 0x898A,
+	0xE64B, 0x8993, 0xE64C, 0x8998, 0xE64D, 0x89A1, 0xE64E, 0x89A9,
+	0xE64F, 0x89A6, 0xE650, 0x89AC, 0xE651, 0x89AF, 0xE652, 0x89B2,
+	0xE653, 0x89BA, 0xE654, 0x89BD, 0xE655, 0x89BF, 0xE656, 0x89C0,
+	0xE657, 0x89DA, 0xE658, 0x89DC, 0xE659, 0x89DD, 0xE65A, 0x89E7,
+	0xE65B, 0x89F4, 0xE65C, 0x89F8, 0xE65D, 0x8A03, 0xE65E, 0x8A16,
+	0xE65F, 0x8A10, 0xE660, 0x8A0C, 0xE661, 0x8A1B, 0xE662, 0x8A1D,
+	0xE663, 0x8A25, 0xE664, 0x8A36, 0xE665, 0x8A41, 0xE666, 0x8A5B,
+	0xE667, 0x8A52, 0xE668, 0x8A46, 0xE669, 0x8A48, 0xE66A, 0x8A7C,
+	0xE66B, 0x8A6D, 0xE66C, 0x8A6C, 0xE66D, 0x8A62, 0xE66E, 0x8A85,
+	0xE66F, 0x8A82, 0xE670, 0x8A84, 0xE671, 0x8AA8, 0xE672, 0x8AA1,
+	0xE673, 0x8A91, 0xE674, 0x8AA5, 0xE675, 0x8AA6, 0xE676, 0x8A9A,
+	0xE677, 0x8AA3, 0xE678, 0x8AC4, 0xE679, 0x8ACD, 0xE67A, 0x8AC2,
+	0xE67B, 0x8ADA, 0xE67C, 0x8AEB, 0xE67D, 0x8AF3, 0xE67E, 0x8AE7,
+	0xE680, 0x8AE4, 0xE681, 0x8AF1, 0xE682, 0x8B14, 0xE683, 0x8AE0,
+	0xE684, 0x8AE2, 0xE685, 0x8AF7, 0xE686, 0x8ADE, 0xE687, 0x8ADB,
+	0xE688, 0x8B0C, 0xE689, 0x8B07, 0xE68A, 0x8B1A, 0xE68B, 0x8AE1,
+	0xE68C, 0x8B16, 0xE68D, 0x8B10, 0xE68E, 0x8B17, 0xE68F, 0x8B20,
+	0xE690, 0x8B33, 0xE691, 0x97AB, 0xE692, 0x8B26, 0xE693, 0x8B2B,
+	0xE694, 0x8B3E, 0xE695, 0x8B28, 0xE696, 0x8B41, 0xE697, 0x8B4C,
+	0xE698, 0x8B4F, 0xE699, 0x8B4E, 0xE69A, 0x8B49, 0xE69B, 0x8B56,
+	0xE69C, 0x8B5B, 0xE69D, 0x8B5A, 0xE69E, 0x8B6B, 0xE69F, 0x8B5F,
+	0xE6A0, 0x8B6C, 0xE6A1, 0x8B6F, 0xE6A2, 0x8B74, 0xE6A3, 0x8B7D,
+	0xE6A4, 0x8B80, 0xE6A5, 0x8B8C, 0xE6A6, 0x8B8E, 0xE6A7, 0x8B92,
+	0xE6A8, 0x8B93, 0xE6A9, 0x8B96, 0xE6AA, 0x8B99, 0xE6AB, 0x8B9A,
+	0xE6AC, 0x8C3A, 0xE6AD, 0x8C41, 0xE6AE, 0x8C3F, 0xE6AF, 0x8C48,
+	0xE6B0, 0x8C4C, 0xE6B1, 0x8C4E, 0xE6B2, 0x8C50, 0xE6B3, 0x8C55,
+	0xE6B4, 0x8C62, 0xE6B5, 0x8C6C, 0xE6B6, 0x8C78, 0xE6B7, 0x8C7A,
+	0xE6B8, 0x8C82, 0xE6B9, 0x8C89, 0xE6BA, 0x8C85, 0xE6BB, 0x8C8A,
+	0xE6BC, 0x8C8D, 0xE6BD, 0x8C8E, 0xE6BE, 0x8C94, 0xE6BF, 0x8C7C,
+	0xE6C0, 0x8C98, 0xE6C1, 0x621D, 0xE6C2, 0x8CAD, 0xE6C3, 0x8CAA,
+	0xE6C4, 0x8CBD, 0xE6C5, 0x8CB2, 0xE6C6, 0x8CB3, 0xE6C7, 0x8CAE,
+	0xE6C8, 0x8CB6, 0xE6C9, 0x8CC8, 0xE6CA, 0x8CC1, 0xE6CB, 0x8CE4,
+	0xE6CC, 0x8CE3, 0xE6CD, 0x8CDA, 0xE6CE, 0x8CFD, 0xE6CF, 0x8CFA,
+	0xE6D0, 0x8CFB, 0xE6D1, 0x8D04, 0xE6D2, 0x8D05, 0xE6D3, 0x8D0A,
+	0xE6D4, 0x8D07, 0xE6D5, 0x8D0F, 0xE6D6, 0x8D0D, 0xE6D7, 0x8D10,
+	0xE6D8, 0x9F4E, 0xE6D9, 0x8D13, 0xE6DA, 0x8CCD, 0xE6DB, 0x8D14,
+	0xE6DC, 0x8D16, 0xE6DD, 0x8D67, 0xE6DE, 0x8D6D, 0xE6DF, 0x8D71,
+	0xE6E0, 0x8D73, 0xE6E1, 0x8D81, 0xE6E2, 0x8D99, 0xE6E3, 0x8DC2,
+	0xE6E4, 0x8DBE, 0xE6E5, 0x8DBA, 0xE6E6, 0x8DCF, 0xE6E7, 0x8DDA,
+	0xE6E8, 0x8DD6, 0xE6E9, 0x8DCC, 0xE6EA, 0x8DDB, 0xE6EB, 0x8DCB,
+	0xE6EC, 0x8DEA, 0xE6ED, 0x8DEB, 0xE6EE, 0x8DDF, 0xE6EF, 0x8DE3,
+	0xE6F0, 0x8DFC, 0xE6F1, 0x8E08, 0xE6F2, 0x8E09, 0xE6F3, 0x8DFF,
+	0xE6F4, 0x8E1D, 0xE6F5, 0x8E1E, 0xE6F6, 0x8E10, 0xE6F7, 0x8E1F,
+	0xE6F8, 0x8E42, 0xE6F9, 0x8E35, 0xE6FA, 0x8E30, 0xE6FB, 0x8E34,
+	0xE6FC, 0x8E4A, 0xE740, 0x8E47, 0xE741, 0x8E49, 0xE742, 0x8E4C,
+	0xE743, 0x8E50, 0xE744, 0x8E48, 0xE745, 0x8E59, 0xE746, 0x8E64,
+	0xE747, 0x8E60, 0xE748, 0x8E2A, 0xE749, 0x8E63, 0xE74A, 0x8E55,
+	0xE74B, 0x8E76, 0xE74C, 0x8E72, 0xE74D, 0x8E7C, 0xE74E, 0x8E81,
+	0xE74F, 0x8E87, 0xE750, 0x8E85, 0xE751, 0x8E84, 0xE752, 0x8E8B,
+	0xE753, 0x8E8A, 0xE754, 0x8E93, 0xE755, 0x8E91, 0xE756, 0x8E94,
+	0xE757, 0x8E99, 0xE758, 0x8EAA, 0xE759, 0x8EA1, 0xE75A, 0x8EAC,
+	0xE75B, 0x8EB0, 0xE75C, 0x8EC6, 0xE75D, 0x8EB1, 0xE75E, 0x8EBE,
+	0xE75F, 0x8EC5, 0xE760, 0x8EC8, 0xE761, 0x8ECB, 0xE762, 0x8EDB,
+	0xE763, 0x8EE3, 0xE764, 0x8EFC, 0xE765, 0x8EFB, 0xE766, 0x8EEB,
+	0xE767, 0x8EFE, 0xE768, 0x8F0A, 0xE769, 0x8F05, 0xE76A, 0x8F15,
+	0xE76B, 0x8F12, 0xE76C, 0x8F19, 0xE76D, 0x8F13, 0xE76E, 0x8F1C,
+	0xE76F, 0x8F1F, 0xE770, 0x8F1B, 0xE771, 0x8F0C, 0xE772, 0x8F26,
+	0xE773, 0x8F33, 0xE774, 0x8F3B, 0xE775, 0x8F39, 0xE776, 0x8F45,
+	0xE777, 0x8F42, 0xE778, 0x8F3E, 0xE779, 0x8F4C, 0xE77A, 0x8F49,
+	0xE77B, 0x8F46, 0xE77C, 0x8F4E, 0xE77D, 0x8F57, 0xE77E, 0x8F5C,
+	0xE780, 0x8F62, 0xE781, 0x8F63, 0xE782, 0x8F64, 0xE783, 0x8F9C,
+	0xE784, 0x8F9F, 0xE785, 0x8FA3, 0xE786, 0x8FAD, 0xE787, 0x8FAF,
+	0xE788, 0x8FB7, 0xE789, 0x8FDA, 0xE78A, 0x8FE5, 0xE78B, 0x8FE2,
+	0xE78C, 0x8FEA, 0xE78D, 0x8FEF, 0xE78E, 0x9087, 0xE78F, 0x8FF4,
+	0xE790, 0x9005, 0xE791, 0x8FF9, 0xE792, 0x8FFA, 0xE793, 0x9011,
+	0xE794, 0x9015, 0xE795, 0x9021, 0xE796, 0x900D, 0xE797, 0x901E,
+	0xE798, 0x9016, 0xE799, 0x900B, 0xE79A, 0x9027, 0xE79B, 0x9036,
+	0xE79C, 0x9035, 0xE79D, 0x9039, 0xE79E, 0x8FF8, 0xE79F, 0x904F,
+	0xE7A0, 0x9050, 0xE7A1, 0x9051, 0xE7A2, 0x9052, 0xE7A3, 0x900E,
+	0xE7A4, 0x9049, 0xE7A5, 0x903E, 0xE7A6, 0x9056, 0xE7A7, 0x9058,
+	0xE7A8, 0x905E, 0xE7A9, 0x9068, 0xE7AA, 0x906F, 0xE7AB, 0x9076,
+	0xE7AC, 0x96A8, 0xE7AD, 0x9072, 0xE7AE, 0x9082, 0xE7AF, 0x907D,
+	0xE7B0, 0x9081, 0xE7B1, 0x9080, 0xE7B2, 0x908A, 0xE7B3, 0x9089,
+	0xE7B4, 0x908F, 0xE7B5, 0x90A8, 0xE7B6, 0x90AF, 0xE7B7, 0x90B1,
+	0xE7B8, 0x90B5, 0xE7B9, 0x90E2, 0xE7BA, 0x90E4, 0xE7BB, 0x6248,
+	0xE7BC, 0x90DB, 0xE7BD, 0x9102, 0xE7BE, 0x9112, 0xE7BF, 0x9119,
+	0xE7C0, 0x9132, 0xE7C1, 0x9130, 0xE7C2, 0x914A, 0xE7C3, 0x9156,
+	0xE7C4, 0x9158, 0xE7C5, 0x9163, 0xE7C6, 0x9165, 0xE7C7, 0x9169,
+	0xE7C8, 0x9173, 0xE7C9, 0x9172, 0xE7CA, 0x918B, 0xE7CB, 0x9189,
+	0xE7CC, 0x9182, 0xE7CD, 0x91A2, 0xE7CE, 0x91AB, 0xE7CF, 0x91AF,
+	0xE7D0, 0x91AA, 0xE7D1, 0x91B5, 0xE7D2, 0x91B4, 0xE7D3, 0x91BA,
+	0xE7D4, 0x91C0, 0xE7D5, 0x91C1, 0xE7D6, 0x91C9, 0xE7D7, 0x91CB,
+	0xE7D8, 0x91D0, 0xE7D9, 0x91D6, 0xE7DA, 0x91DF, 0xE7DB, 0x91E1,
+	0xE7DC, 0x91DB, 0xE7DD, 0x91FC, 0xE7DE, 0x91F5, 0xE7DF, 0x91F6,
+	0xE7E0, 0x921E, 0xE7E1, 0x91FF, 0xE7E2, 0x9214, 0xE7E3, 0x922C,
+	0xE7E4, 0x9215, 0xE7E5, 0x9211, 0xE7E6, 0x925E, 0xE7E7, 0x9257,
+	0xE7E8, 0x9245, 0xE7E9, 0x9249, 0xE7EA, 0x9264, 0xE7EB, 0x9248,
+	0xE7EC, 0x9295, 0xE7ED, 0x923F, 0xE7EE, 0x924B, 0xE7EF, 0x9250,
+	0xE7F0, 0x929C, 0xE7F1, 0x9296, 0xE7F2, 0x9293, 0xE7F3, 0x929B,
+	0xE7F4, 0x925A, 0xE7F5, 0x92CF, 0xE7F6, 0x92B9, 0xE7F7, 0x92B7,
+	0xE7F8, 0x92E9, 0xE7F9, 0x930F, 0xE7FA, 0x92FA, 0xE7FB, 0x9344,
+	0xE7FC, 0x932E, 0xE840, 0x9319, 0xE841, 0x9322, 0xE842, 0x931A,
+	0xE843, 0x9323, 0xE844, 0x933A, 0xE845, 0x9335, 0xE846, 0x933B,
+	0xE847, 0x935C, 0xE848, 0x9360, 0xE849, 0x937C, 0xE84A, 0x936E,
+	0xE84B, 0x9356, 0xE84C, 0x93B0, 0xE84D, 0x93AC, 0xE84E, 0x93AD,
+	0xE84F, 0x9394, 0xE850, 0x93B9, 0xE851, 0x93D6, 0xE852, 0x93D7,
+	0xE853, 0x93E8, 0xE854, 0x93E5, 0xE855, 0x93D8, 0xE856, 0x93C3,
+	0xE857, 0x93DD, 0xE858, 0x93D0, 0xE859, 0x93C8, 0xE85A, 0x93E4,
+	0xE85B, 0x941A, 0xE85C, 0x9414, 0xE85D, 0x9413, 0xE85E, 0x9403,
+	0xE85F, 0x9407, 0xE860, 0x9410, 0xE861, 0x9436, 0xE862, 0x942B,
+	0xE863, 0x9435, 0xE864, 0x9421, 0xE865, 0x943A, 0xE866, 0x9441,
+	0xE867, 0x9452, 0xE868, 0x9444, 0xE869, 0x945B, 0xE86A, 0x9460,
+	0xE86B, 0x9462, 0xE86C, 0x945E, 0xE86D, 0x946A, 0xE86E, 0x9229,
+	0xE86F, 0x9470, 0xE870, 0x9475, 0xE871, 0x9477, 0xE872, 0x947D,
+	0xE873, 0x945A, 0xE874, 0x947C, 0xE875, 0x947E, 0xE876, 0x9481,
+	0xE877, 0x947F, 0xE878, 0x9582, 0xE879, 0x9587, 0xE87A, 0x958A,
+	0xE87B, 0x9594, 0xE87C, 0x9596, 0xE87D, 0x9598, 0xE87E, 0x9599,
+	0xE880, 0x95A0, 0xE881, 0x95A8, 0xE882, 0x95A7, 0xE883, 0x95AD,
+	0xE884, 0x95BC, 0xE885, 0x95BB, 0xE886, 0x95B9, 0xE887, 0x95BE,
+	0xE888, 0x95CA, 0xE889, 0x6FF6, 0xE88A, 0x95C3, 0xE88B, 0x95CD,
+	0xE88C, 0x95CC, 0xE88D, 0x95D5, 0xE88E, 0x95D4, 0xE88F, 0x95D6,
+	0xE890, 0x95DC, 0xE891, 0x95E1, 0xE892, 0x95E5, 0xE893, 0x95E2,
+	0xE894, 0x9621, 0xE895, 0x9628, 0xE896, 0x962E, 0xE897, 0x962F,
+	0xE898, 0x9642, 0xE899, 0x964C, 0xE89A, 0x964F, 0xE89B, 0x964B,
+	0xE89C, 0x9677, 0xE89D, 0x965C, 0xE89E, 0x965E, 0xE89F, 0x965D,
+	0xE8A0, 0x965F, 0xE8A1, 0x9666, 0xE8A2, 0x9672, 0xE8A3, 0x966C,
+	0xE8A4, 0x968D, 0xE8A5, 0x9698, 0xE8A6, 0x9695, 0xE8A7, 0x9697,
+	0xE8A8, 0x96AA, 0xE8A9, 0x96A7, 0xE8AA, 0x96B1, 0xE8AB, 0x96B2,
+	0xE8AC, 0x96B0, 0xE8AD, 0x96B4, 0xE8AE, 0x96B6, 0xE8AF, 0x96B8,
+	0xE8B0, 0x96B9, 0xE8B1, 0x96CE, 0xE8B2, 0x96CB, 0xE8B3, 0x96C9,
+	0xE8B4, 0x96CD, 0xE8B5, 0x894D, 0xE8B6, 0x96DC, 0xE8B7, 0x970D,
+	0xE8B8, 0x96D5, 0xE8B9, 0x96F9, 0xE8BA, 0x9704, 0xE8BB, 0x9706,
+	0xE8BC, 0x9708, 0xE8BD, 0x9713, 0xE8BE, 0x970E, 0xE8BF, 0x9711,
+	0xE8C0, 0x970F, 0xE8C1, 0x9716, 0xE8C2, 0x9719, 0xE8C3, 0x9724,
+	0xE8C4, 0x972A, 0xE8C5, 0x9730, 0xE8C6, 0x9739, 0xE8C7, 0x973D,
+	0xE8C8, 0x973E, 0xE8C9, 0x9744, 0xE8CA, 0x9746, 0xE8CB, 0x9748,
+	0xE8CC, 0x9742, 0xE8CD, 0x9749, 0xE8CE, 0x975C, 0xE8CF, 0x9760,
+	0xE8D0, 0x9764, 0xE8D1, 0x9766, 0xE8D2, 0x9768, 0xE8D3, 0x52D2,
+	0xE8D4, 0x976B, 0xE8D5, 0x9771, 0xE8D6, 0x9779, 0xE8D7, 0x9785,
+	0xE8D8, 0x977C, 0xE8D9, 0x9781, 0xE8DA, 0x977A, 0xE8DB, 0x9786,
+	0xE8DC, 0x978B, 0xE8DD, 0x978F, 0xE8DE, 0x9790, 0xE8DF, 0x979C,
+	0xE8E0, 0x97A8, 0xE8E1, 0x97A6, 0xE8E2, 0x97A3, 0xE8E3, 0x97B3,
+	0xE8E4, 0x97B4, 0xE8E5, 0x97C3, 0xE8E6, 0x97C6, 0xE8E7, 0x97C8,
+	0xE8E8, 0x97CB, 0xE8E9, 0x97DC, 0xE8EA, 0x97ED, 0xE8EB, 0x9F4F,
+	0xE8EC, 0x97F2, 0xE8ED, 0x7ADF, 0xE8EE, 0x97F6, 0xE8EF, 0x97F5,
+	0xE8F0, 0x980F, 0xE8F1, 0x980C, 0xE8F2, 0x9838, 0xE8F3, 0x9824,
+	0xE8F4, 0x9821, 0xE8F5, 0x9837, 0xE8F6, 0x983D, 0xE8F7, 0x9846,
+	0xE8F8, 0x984F, 0xE8F9, 0x984B, 0xE8FA, 0x986B, 0xE8FB, 0x986F,
+	0xE8FC, 0x9870, 0xE940, 0x9871, 0xE941, 0x9874, 0xE942, 0x9873,
+	0xE943, 0x98AA, 0xE944, 0x98AF, 0xE945, 0x98B1, 0xE946, 0x98B6,
+	0xE947, 0x98C4, 0xE948, 0x98C3, 0xE949, 0x98C6, 0xE94A, 0x98E9,
+	0xE94B, 0x98EB, 0xE94C, 0x9903, 0xE94D, 0x9909, 0xE94E, 0x9912,
+	0xE94F, 0x9914, 0xE950, 0x9918, 0xE951, 0x9921, 0xE952, 0x991D,
+	0xE953, 0x991E, 0xE954, 0x9924, 0xE955, 0x9920, 0xE956, 0x992C,
+	0xE957, 0x992E, 0xE958, 0x993D, 0xE959, 0x993E, 0xE95A, 0x9942,
+	0xE95B, 0x9949, 0xE95C, 0x9945, 0xE95D, 0x9950, 0xE95E, 0x994B,
+	0xE95F, 0x9951, 0xE960, 0x9952, 0xE961, 0x994C, 0xE962, 0x9955,
+	0xE963, 0x9997, 0xE964, 0x9998, 0xE965, 0x99A5, 0xE966, 0x99AD,
+	0xE967, 0x99AE, 0xE968, 0x99BC, 0xE969, 0x99DF, 0xE96A, 0x99DB,
+	0xE96B, 0x99DD, 0xE96C, 0x99D8, 0xE96D, 0x99D1, 0xE96E, 0x99ED,
+	0xE96F, 0x99EE, 0xE970, 0x99F1, 0xE971, 0x99F2, 0xE972, 0x99FB,
+	0xE973, 0x99F8, 0xE974, 0x9A01, 0xE975, 0x9A0F, 0xE976, 0x9A05,
+	0xE977, 0x99E2, 0xE978, 0x9A19, 0xE979, 0x9A2B, 0xE97A, 0x9A37,
+	0xE97B, 0x9A45, 0xE97C, 0x9A42, 0xE97D, 0x9A40, 0xE97E, 0x9A43,
+	0xE980, 0x9A3E, 0xE981, 0x9A55, 0xE982, 0x9A4D, 0xE983, 0x9A5B,
+	0xE984, 0x9A57, 0xE985, 0x9A5F, 0xE986, 0x9A62, 0xE987, 0x9A65,
+	0xE988, 0x9A64, 0xE989, 0x9A69, 0xE98A, 0x9A6B, 0xE98B, 0x9A6A,
+	0xE98C, 0x9AAD, 0xE98D, 0x9AB0, 0xE98E, 0x9ABC, 0xE98F, 0x9AC0,
+	0xE990, 0x9ACF, 0xE991, 0x9AD1, 0xE992, 0x9AD3, 0xE993, 0x9AD4,
+	0xE994, 0x9ADE, 0xE995, 0x9ADF, 0xE996, 0x9AE2, 0xE997, 0x9AE3,
+	0xE998, 0x9AE6, 0xE999, 0x9AEF, 0xE99A, 0x9AEB, 0xE99B, 0x9AEE,
+	0xE99C, 0x9AF4, 0xE99D, 0x9AF1, 0xE99E, 0x9AF7, 0xE99F, 0x9AFB,
+	0xE9A0, 0x9B06, 0xE9A1, 0x9B18, 0xE9A2, 0x9B1A, 0xE9A3, 0x9B1F,
+	0xE9A4, 0x9B22, 0xE9A5, 0x9B23, 0xE9A6, 0x9B25, 0xE9A7, 0x9B27,
+	0xE9A8, 0x9B28, 0xE9A9, 0x9B29, 0xE9AA, 0x9B2A, 0xE9AB, 0x9B2E,
+	0xE9AC, 0x9B2F, 0xE9AD, 0x9B32, 0xE9AE, 0x9B44, 0xE9AF, 0x9B43,
+	0xE9B0, 0x9B4F, 0xE9B1, 0x9B4D, 0xE9B2, 0x9B4E, 0xE9B3, 0x9B51,
+	0xE9B4, 0x9B58, 0xE9B5, 0x9B74, 0xE9B6, 0x9B93, 0xE9B7, 0x9B83,
+	0xE9B8, 0x9B91, 0xE9B9, 0x9B96, 0xE9BA, 0x9B97, 0xE9BB, 0x9B9F,
+	0xE9BC, 0x9BA0, 0xE9BD, 0x9BA8, 0xE9BE, 0x9BB4, 0xE9BF, 0x9BC0,
+	0xE9C0, 0x9BCA, 0xE9C1, 0x9BB9, 0xE9C2, 0x9BC6, 0xE9C3, 0x9BCF,
+	0xE9C4, 0x9BD1, 0xE9C5, 0x9BD2, 0xE9C6, 0x9BE3, 0xE9C7, 0x9BE2,
+	0xE9C8, 0x9BE4, 0xE9C9, 0x9BD4, 0xE9CA, 0x9BE1, 0xE9CB, 0x9C3A,
+	0xE9CC, 0x9BF2, 0xE9CD, 0x9BF1, 0xE9CE, 0x9BF0, 0xE9CF, 0x9C15,
+	0xE9D0, 0x9C14, 0xE9D1, 0x9C09, 0xE9D2, 0x9C13, 0xE9D3, 0x9C0C,
+	0xE9D4, 0x9C06, 0xE9D5, 0x9C08, 0xE9D6, 0x9C12, 0xE9D7, 0x9C0A,
+	0xE9D8, 0x9C04, 0xE9D9, 0x9C2E, 0xE9DA, 0x9C1B, 0xE9DB, 0x9C25,
+	0xE9DC, 0x9C24, 0xE9DD, 0x9C21, 0xE9DE, 0x9C30, 0xE9DF, 0x9C47,
+	0xE9E0, 0x9C32, 0xE9E1, 0x9C46, 0xE9E2, 0x9C3E, 0xE9E3, 0x9C5A,
+	0xE9E4, 0x9C60, 0xE9E5, 0x9C67, 0xE9E6, 0x9C76, 0xE9E7, 0x9C78,
+	0xE9E8, 0x9CE7, 0xE9E9, 0x9CEC, 0xE9EA, 0x9CF0, 0xE9EB, 0x9D09,
+	0xE9EC, 0x9D08, 0xE9ED, 0x9CEB, 0xE9EE, 0x9D03, 0xE9EF, 0x9D06,
+	0xE9F0, 0x9D2A, 0xE9F1, 0x9D26, 0xE9F2, 0x9DAF, 0xE9F3, 0x9D23,
+	0xE9F4, 0x9D1F, 0xE9F5, 0x9D44, 0xE9F6, 0x9D15, 0xE9F7, 0x9D12,
+	0xE9F8, 0x9D41, 0xE9F9, 0x9D3F, 0xE9FA, 0x9D3E, 0xE9FB, 0x9D46,
+	0xE9FC, 0x9D48, 0xEA40, 0x9D5D, 0xEA41, 0x9D5E, 0xEA42, 0x9D64,
+	0xEA43, 0x9D51, 0xEA44, 0x9D50, 0xEA45, 0x9D59, 0xEA46, 0x9D72,
+	0xEA47, 0x9D89, 0xEA48, 0x9D87, 0xEA49, 0x9DAB, 0xEA4A, 0x9D6F,
+	0xEA4B, 0x9D7A, 0xEA4C, 0x9D9A, 0xEA4D, 0x9DA4, 0xEA4E, 0x9DA9,
+	0xEA4F, 0x9DB2, 0xEA50, 0x9DC4, 0xEA51, 0x9DC1, 0xEA52, 0x9DBB,
+	0xEA53, 0x9DB8, 0xEA54, 0x9DBA, 0xEA55, 0x9DC6, 0xEA56, 0x9DCF,
+	0xEA57, 0x9DC2, 0xEA58, 0x9DD9, 0xEA59, 0x9DD3, 0xEA5A, 0x9DF8,
+	0xEA5B, 0x9DE6, 0xEA5C, 0x9DED, 0xEA5D, 0x9DEF, 0xEA5E, 0x9DFD,
+	0xEA5F, 0x9E1A, 0xEA60, 0x9E1B, 0xEA61, 0x9E1E, 0xEA62, 0x9E75,
+	0xEA63, 0x9E79, 0xEA64, 0x9E7D, 0xEA65, 0x9E81, 0xEA66, 0x9E88,
+	0xEA67, 0x9E8B, 0xEA68, 0x9E8C, 0xEA69, 0x9E92, 0xEA6A, 0x9E95,
+	0xEA6B, 0x9E91, 0xEA6C, 0x9E9D, 0xEA6D, 0x9EA5, 0xEA6E, 0x9EA9,
+	0xEA6F, 0x9EB8, 0xEA70, 0x9EAA, 0xEA71, 0x9EAD, 0xEA72, 0x9761,
+	0xEA73, 0x9ECC, 0xEA74, 0x9ECE, 0xEA75, 0x9ECF, 0xEA76, 0x9ED0,
+	0xEA77, 0x9ED4, 0xEA78, 0x9EDC, 0xEA79, 0x9EDE, 0xEA7A, 0x9EDD,
+	0xEA7B, 0x9EE0, 0xEA7C, 0x9EE5, 0xEA7D, 0x9EE8, 0xEA7E, 0x9EEF,
+	0xEA80, 0x9EF4, 0xEA81, 0x9EF6, 0xEA82, 0x9EF7, 0xEA83, 0x9EF9,
+	0xEA84, 0x9EFB, 0xEA85, 0x9EFC, 0xEA86, 0x9EFD, 0xEA87, 0x9F07,
+	0xEA88, 0x9F08, 0xEA89, 0x76B7, 0xEA8A, 0x9F15, 0xEA8B, 0x9F21,
+	0xEA8C, 0x9F2C, 0xEA8D, 0x9F3E, 0xEA8E, 0x9F4A, 0xEA8F, 0x9F52,
+	0xEA90, 0x9F54, 0xEA91, 0x9F63, 0xEA92, 0x9F5F, 0xEA93, 0x9F60,
+	0xEA94, 0x9F61, 0xEA95, 0x9F66, 0xEA96, 0x9F67, 0xEA97, 0x9F6C,
+	0xEA98, 0x9F6A, 0xEA99, 0x9F77, 0xEA9A, 0x9F72, 0xEA9B, 0x9F76,
+	0xEA9C, 0x9F95, 0xEA9D, 0x9F9C, 0xEA9E, 0x9FA0, 0xEA9F, 0x582F,
+	0xEAA0, 0x69C7, 0xEAA1, 0x9059, 0xEAA2, 0x7464, 0xEAA3, 0x51DC,
+	0xEAA4, 0x7199, 0xFA40, 0x2170, 0xFA41, 0x2171, 0xFA42, 0x2172,
+	0xFA43, 0x2173, 0xFA44, 0x2174, 0xFA45, 0x2175, 0xFA46, 0x2176,
+	0xFA47, 0x2177, 0xFA48, 0x2178, 0xFA49, 0x2179, 0xFA55, 0xFFE4,
+	0xFA56, 0xFF07, 0xFA57, 0xFF02, 0xFA5C, 0x7E8A, 0xFA5D, 0x891C,
+	0xFA5E, 0x9348, 0xFA5F, 0x9288, 0xFA60, 0x84DC, 0xFA61, 0x4FC9,
+	0xFA62, 0x70BB, 0xFA63, 0x6631, 0xFA64, 0x68C8, 0xFA65, 0x92F9,
+	0xFA66, 0x66FB, 0xFA67, 0x5F45, 0xFA68, 0x4E28, 0xFA69, 0x4EE1,
+	0xFA6A, 0x4EFC, 0xFA6B, 0x4F00, 0xFA6C, 0x4F03, 0xFA6D, 0x4F39,
+	0xFA6E, 0x4F56, 0xFA6F, 0x4F92, 0xFA70, 0x4F8A, 0xFA71, 0x4F9A,
+	0xFA72, 0x4F94, 0xFA73, 0x4FCD, 0xFA74, 0x5040, 0xFA75, 0x5022,
+	0xFA76, 0x4FFF, 0xFA77, 0x501E, 0xFA78, 0x5046, 0xFA79, 0x5070,
+	0xFA7A, 0x5042, 0xFA7B, 0x5094, 0xFA7C, 0x50F4, 0xFA7D, 0x50D8,
+	0xFA7E, 0x514A, 0xFA80, 0x5164, 0xFA81, 0x519D, 0xFA82, 0x51BE,
+	0xFA83, 0x51EC, 0xFA84, 0x5215, 0xFA85, 0x529C, 0xFA86, 0x52A6,
+	0xFA87, 0x52C0, 0xFA88, 0x52DB, 0xFA89, 0x5300, 0xFA8A, 0x5307,
+	0xFA8B, 0x5324, 0xFA8C, 0x5372, 0xFA8D, 0x5393, 0xFA8E, 0x53B2,
+	0xFA8F, 0x53DD, 0xFA90, 0xFA0E, 0xFA91, 0x549C, 0xFA92, 0x548A,
+	0xFA93, 0x54A9, 0xFA94, 0x54FF, 0xFA95, 0x5586, 0xFA96, 0x5759,
+	0xFA97, 0x5765, 0xFA98, 0x57AC, 0xFA99, 0x57C8, 0xFA9A, 0x57C7,
+	0xFA9B, 0xFA0F, 0xFA9C, 0xFA10, 0xFA9D, 0x589E, 0xFA9E, 0x58B2,
+	0xFA9F, 0x590B, 0xFAA0, 0x5953, 0xFAA1, 0x595B, 0xFAA2, 0x595D,
+	0xFAA3, 0x5963, 0xFAA4, 0x59A4, 0xFAA5, 0x59BA, 0xFAA6, 0x5B56,
+	0xFAA7, 0x5BC0, 0xFAA8, 0x752F, 0xFAA9, 0x5BD8, 0xFAAA, 0x5BEC,
+	0xFAAB, 0x5C1E, 0xFAAC, 0x5CA6, 0xFAAD, 0x5CBA, 0xFAAE, 0x5CF5,
+	0xFAAF, 0x5D27, 0xFAB0, 0x5D53, 0xFAB1, 0xFA11, 0xFAB2, 0x5D42,
+	0xFAB3, 0x5D6D, 0xFAB4, 0x5DB8, 0xFAB5, 0x5DB9, 0xFAB6, 0x5DD0,
+	0xFAB7, 0x5F21, 0xFAB8, 0x5F34, 0xFAB9, 0x5F67, 0xFABA, 0x5FB7,
+	0xFABB, 0x5FDE, 0xFABC, 0x605D, 0xFABD, 0x6085, 0xFABE, 0x608A,
+	0xFABF, 0x60DE, 0xFAC0, 0x60D5, 0xFAC1, 0x6120, 0xFAC2, 0x60F2,
+	0xFAC3, 0x6111, 0xFAC4, 0x6137, 0xFAC5, 0x6130, 0xFAC6, 0x6198,
+	0xFAC7, 0x6213, 0xFAC8, 0x62A6, 0xFAC9, 0x63F5, 0xFACA, 0x6460,
+	0xFACB, 0x649D, 0xFACC, 0x64CE, 0xFACD, 0x654E, 0xFACE, 0x6600,
+	0xFACF, 0x6615, 0xFAD0, 0x663B, 0xFAD1, 0x6609, 0xFAD2, 0x662E,
+	0xFAD3, 0x661E, 0xFAD4, 0x6624, 0xFAD5, 0x6665, 0xFAD6, 0x6657,
+	0xFAD7, 0x6659, 0xFAD8, 0xFA12, 0xFAD9, 0x6673, 0xFADA, 0x6699,
+	0xFADB, 0x66A0, 0xFADC, 0x66B2, 0xFADD, 0x66BF, 0xFADE, 0x66FA,
+	0xFADF, 0x670E, 0xFAE0, 0xF929, 0xFAE1, 0x6766, 0xFAE2, 0x67BB,
+	0xFAE3, 0x6852, 0xFAE4, 0x67C0, 0xFAE5, 0x6801, 0xFAE6, 0x6844,
+	0xFAE7, 0x68CF, 0xFAE8, 0xFA13, 0xFAE9, 0x6968, 0xFAEA, 0xFA14,
+	0xFAEB, 0x6998, 0xFAEC, 0x69E2, 0xFAED, 0x6A30, 0xFAEE, 0x6A6B,
+	0xFAEF, 0x6A46, 0xFAF0, 0x6A73, 0xFAF1, 0x6A7E, 0xFAF2, 0x6AE2,
+	0xFAF3, 0x6AE4, 0xFAF4, 0x6BD6, 0xFAF5, 0x6C3F, 0xFAF6, 0x6C5C,
+	0xFAF7, 0x6C86, 0xFAF8, 0x6C6F, 0xFAF9, 0x6CDA, 0xFAFA, 0x6D04,
+	0xFAFB, 0x6D87, 0xFAFC, 0x6D6F, 0xFB40, 0x6D96, 0xFB41, 0x6DAC,
+	0xFB42, 0x6DCF, 0xFB43, 0x6DF8, 0xFB44, 0x6DF2, 0xFB45, 0x6DFC,
+	0xFB46, 0x6E39, 0xFB47, 0x6E5C, 0xFB48, 0x6E27, 0xFB49, 0x6E3C,
+	0xFB4A, 0x6EBF, 0xFB4B, 0x6F88, 0xFB4C, 0x6FB5, 0xFB4D, 0x6FF5,
+	0xFB4E, 0x7005, 0xFB4F, 0x7007, 0xFB50, 0x7028, 0xFB51, 0x7085,
+	0xFB52, 0x70AB, 0xFB53, 0x710F, 0xFB54, 0x7104, 0xFB55, 0x715C,
+	0xFB56, 0x7146, 0xFB57, 0x7147, 0xFB58, 0xFA15, 0xFB59, 0x71C1,
+	0xFB5A, 0x71FE, 0xFB5B, 0x72B1, 0xFB5C, 0x72BE, 0xFB5D, 0x7324,
+	0xFB5E, 0xFA16, 0xFB5F, 0x7377, 0xFB60, 0x73BD, 0xFB61, 0x73C9,
+	0xFB62, 0x73D6, 0xFB63, 0x73E3, 0xFB64, 0x73D2, 0xFB65, 0x7407,
+	0xFB66, 0x73F5, 0xFB67, 0x7426, 0xFB68, 0x742A, 0xFB69, 0x7429,
+	0xFB6A, 0x742E, 0xFB6B, 0x7462, 0xFB6C, 0x7489, 0xFB6D, 0x749F,
+	0xFB6E, 0x7501, 0xFB6F, 0x756F, 0xFB70, 0x7682, 0xFB71, 0x769C,
+	0xFB72, 0x769E, 0xFB73, 0x769B, 0xFB74, 0x76A6, 0xFB75, 0xFA17,
+	0xFB76, 0x7746, 0xFB77, 0x52AF, 0xFB78, 0x7821, 0xFB79, 0x784E,
+	0xFB7A, 0x7864, 0xFB7B, 0x787A, 0xFB7C, 0x7930, 0xFB7D, 0xFA18,
+	0xFB7E, 0xFA19, 0xFB80, 0xFA1A, 0xFB81, 0x7994, 0xFB82, 0xFA1B,
+	0xFB83, 0x799B, 0xFB84, 0x7AD1, 0xFB85, 0x7AE7, 0xFB86, 0xFA1C,
+	0xFB87, 0x7AEB, 0xFB88, 0x7B9E, 0xFB89, 0xFA1D, 0xFB8A, 0x7D48,
+	0xFB8B, 0x7D5C, 0xFB8C, 0x7DB7, 0xFB8D, 0x7DA0, 0xFB8E, 0x7DD6,
+	0xFB8F, 0x7E52, 0xFB90, 0x7F47, 0xFB91, 0x7FA1, 0xFB92, 0xFA1E,
+	0xFB93, 0x8301, 0xFB94, 0x8362, 0xFB95, 0x837F, 0xFB96, 0x83C7,
+	0xFB97, 0x83F6, 0xFB98, 0x8448, 0xFB99, 0x84B4, 0xFB9A, 0x8553,
+	0xFB9B, 0x8559, 0xFB9C, 0x856B, 0xFB9D, 0xFA1F, 0xFB9E, 0x85B0,
+	0xFB9F, 0xFA20, 0xFBA0, 0xFA21, 0xFBA1, 0x8807, 0xFBA2, 0x88F5,
+	0xFBA3, 0x8A12, 0xFBA4, 0x8A37, 0xFBA5, 0x8A79, 0xFBA6, 0x8AA7,
+	0xFBA7, 0x8ABE, 0xFBA8, 0x8ADF, 0xFBA9, 0xFA22, 0xFBAA, 0x8AF6,
+	0xFBAB, 0x8B53, 0xFBAC, 0x8B7F, 0xFBAD, 0x8CF0, 0xFBAE, 0x8CF4,
+	0xFBAF, 0x8D12, 0xFBB0, 0x8D76, 0xFBB1, 0xFA23, 0xFBB2, 0x8ECF,
+	0xFBB3, 0xFA24, 0xFBB4, 0xFA25, 0xFBB5, 0x9067, 0xFBB6, 0x90DE,
+	0xFBB7, 0xFA26, 0xFBB8, 0x9115, 0xFBB9, 0x9127, 0xFBBA, 0x91DA,
+	0xFBBB, 0x91D7, 0xFBBC, 0x91DE, 0xFBBD, 0x91ED, 0xFBBE, 0x91EE,
+	0xFBBF, 0x91E4, 0xFBC0, 0x91E5, 0xFBC1, 0x9206, 0xFBC2, 0x9210,
+	0xFBC3, 0x920A, 0xFBC4, 0x923A, 0xFBC5, 0x9240, 0xFBC6, 0x923C,
+	0xFBC7, 0x924E, 0xFBC8, 0x9259, 0xFBC9, 0x9251, 0xFBCA, 0x9239,
+	0xFBCB, 0x9267, 0xFBCC, 0x92A7, 0xFBCD, 0x9277, 0xFBCE, 0x9278,
+	0xFBCF, 0x92E7, 0xFBD0, 0x92D7, 0xFBD1, 0x92D9, 0xFBD2, 0x92D0,
+	0xFBD3, 0xFA27, 0xFBD4, 0x92D5, 0xFBD5, 0x92E0, 0xFBD6, 0x92D3,
+	0xFBD7, 0x9325, 0xFBD8, 0x9321, 0xFBD9, 0x92FB, 0xFBDA, 0xFA28,
+	0xFBDB, 0x931E, 0xFBDC, 0x92FF, 0xFBDD, 0x931D, 0xFBDE, 0x9302,
+	0xFBDF, 0x9370, 0xFBE0, 0x9357, 0xFBE1, 0x93A4, 0xFBE2, 0x93C6,
+	0xFBE3, 0x93DE, 0xFBE4, 0x93F8, 0xFBE5, 0x9431, 0xFBE6, 0x9445,
+	0xFBE7, 0x9448, 0xFBE8, 0x9592, 0xFBE9, 0xF9DC, 0xFBEA, 0xFA29,
+	0xFBEB, 0x969D, 0xFBEC, 0x96AF, 0xFBED, 0x9733, 0xFBEE, 0x973B,
+	0xFBEF, 0x9743, 0xFBF0, 0x974D, 0xFBF1, 0x974F, 0xFBF2, 0x9751,
+	0xFBF3, 0x9755, 0xFBF4, 0x9857, 0xFBF5, 0x9865, 0xFBF6, 0xFA2A,
+	0xFBF7, 0xFA2B, 0xFBF8, 0x9927, 0xFBF9, 0xFA2C, 0xFBFA, 0x999E,
+	0xFBFB, 0x9A4E, 0xFBFC, 0x9AD9, 0xFC40, 0x9ADC, 0xFC41, 0x9B75,
+	0xFC42, 0x9B72, 0xFC43, 0x9B8F, 0xFC44, 0x9BB1, 0xFC45, 0x9BBB,
+	0xFC46, 0x9C00, 0xFC47, 0x9D70, 0xFC48, 0x9D6B, 0xFC49, 0xFA2D,
+	0xFC4A, 0x9E19, 0xFC4B, 0x9ED1, 0, 0
+};
+#endif
+
+
+
+WCHAR ff_convert (	/* Converted code, 0 means conversion error */
+	WCHAR	src,	/* Character code to be converted */
+	UINT	dir		/* 0: Unicode to OEMCP, 1: OEMCP to Unicode */
+)
+{
+	const WCHAR *p;
+	WCHAR c;
+	int i, n, li, hi;
+
+
+	if (src <= 0x80) {	/* ASCII */
+		c = src;
+	} else {
+#if !_TINY_TABLE
+		if (dir) {		/* OEMCP to unicode */
+			p = sjis2uni;
+			hi = sizeof(sjis2uni) / 4 - 1;
+		} else {		/* Unicode to OEMCP */
+			p = uni2sjis;
+			hi = sizeof(uni2sjis) / 4 - 1;
+		}
+		li = 0;
+		for (n = 16; n; n--) {
+			i = li + (hi - li) / 2;
+			if (src == p[i * 2]) break;
+			if (src > p[i * 2])
+				li = i;
+			else
+				hi = i;
+		}
+		c = n ? p[i * 2 + 1] : 0;
+#else
+		if (dir) {		/* OEMCP to unicode (Incremental search)*/
+			p = &uni2sjis[1];
+			do {
+				c = *p;
+				p += 2;
+			p -= 3;
+			c = *p;
+			} while (c && c != src);
+		} else {		/* Unicode to OEMCP */
+			li = 0; hi = sizeof(uni2sjis) / 4 - 1;
+			for (n = 16; n; n--) {
+				i = li + (hi - li) / 2;
+				if (src == uni2sjis[i * 2]) break;
+				if (src > uni2sjis[i * 2])
+					li = i;
+				else
+					hi = i;
+			}
+			c = n ? uni2sjis[i * 2 + 1] : 0;
+		}
+#endif
+	}
+
+	return c;
+}
+#else
+#error This file is not needed in current configuration.
+
+#endif
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/files/ff/option/cc936.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/files/ff/option/cc936.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/files/ff/option/cc936.c	(revision 457)
@@ -0,0 +1,10960 @@
+/*------------------------------------------------------------------------*/
+/* Unicode - OEM code bidirectional converter  (C)ChaN, 2009              */
+/*                                                                        */
+/* CP936 (Simplified Chinese GBK)                                         */
+/*------------------------------------------------------------------------*/
+
+#include "../ff.h"
+
+
+#if _USE_LFN && _CODE_PAGE == 936
+
+
+static
+const WCHAR uni2oem[] = {
+/*  Unicode - OEM,  Unicode - OEM,  Unicode - OEM,  Unicode - OEM */
+	0x00A4, 0xA1E8, 0x00A7, 0xA1EC, 0x00A8, 0xA1A7, 0x00B0, 0xA1E3,
+	0x00B1, 0xA1C0, 0x00B7, 0xA1A4, 0x00D7, 0xA1C1, 0x00E0, 0xA8A4,
+	0x00E1, 0xA8A2, 0x00E8, 0xA8A8, 0x00E9, 0xA8A6, 0x00EA, 0xA8BA,
+	0x00EC, 0xA8AC, 0x00ED, 0xA8AA, 0x00F2, 0xA8B0, 0x00F3, 0xA8AE,
+	0x00F7, 0xA1C2, 0x00F9, 0xA8B4, 0x00FA, 0xA8B2, 0x00FC, 0xA8B9,
+	0x0101, 0xA8A1, 0x0113, 0xA8A5, 0x011B, 0xA8A7, 0x012B, 0xA8A9,
+	0x0144, 0xA8BD, 0x0148, 0xA8BE, 0x014D, 0xA8AD, 0x016B, 0xA8B1,
+	0x01CE, 0xA8A3, 0x01D0, 0xA8AB, 0x01D2, 0xA8AF, 0x01D4, 0xA8B3,
+	0x01D6, 0xA8B5, 0x01D8, 0xA8B6, 0x01DA, 0xA8B7, 0x01DC, 0xA8B8,
+	0x0251, 0xA8BB, 0x0261, 0xA8C0, 0x02C7, 0xA1A6, 0x02C9, 0xA1A5,
+	0x02CA, 0xA840, 0x02CB, 0xA841, 0x02D9, 0xA842, 0x0391, 0xA6A1,
+	0x0392, 0xA6A2, 0x0393, 0xA6A3, 0x0394, 0xA6A4, 0x0395, 0xA6A5,
+	0x0396, 0xA6A6, 0x0397, 0xA6A7, 0x0398, 0xA6A8, 0x0399, 0xA6A9,
+	0x039A, 0xA6AA, 0x039B, 0xA6AB, 0x039C, 0xA6AC, 0x039D, 0xA6AD,
+	0x039E, 0xA6AE, 0x039F, 0xA6AF, 0x03A0, 0xA6B0, 0x03A1, 0xA6B1,
+	0x03A3, 0xA6B2, 0x03A4, 0xA6B3, 0x03A5, 0xA6B4, 0x03A6, 0xA6B5,
+	0x03A7, 0xA6B6, 0x03A8, 0xA6B7, 0x03A9, 0xA6B8, 0x03B1, 0xA6C1,
+	0x03B2, 0xA6C2, 0x03B3, 0xA6C3, 0x03B4, 0xA6C4, 0x03B5, 0xA6C5,
+	0x03B6, 0xA6C6, 0x03B7, 0xA6C7, 0x03B8, 0xA6C8, 0x03B9, 0xA6C9,
+	0x03BA, 0xA6CA, 0x03BB, 0xA6CB, 0x03BC, 0xA6CC, 0x03BD, 0xA6CD,
+	0x03BE, 0xA6CE, 0x03BF, 0xA6CF, 0x03C0, 0xA6D0, 0x03C1, 0xA6D1,
+	0x03C3, 0xA6D2, 0x03C4, 0xA6D3, 0x03C5, 0xA6D4, 0x03C6, 0xA6D5,
+	0x03C7, 0xA6D6, 0x03C8, 0xA6D7, 0x03C9, 0xA6D8, 0x0401, 0xA7A7,
+	0x0410, 0xA7A1, 0x0411, 0xA7A2, 0x0412, 0xA7A3, 0x0413, 0xA7A4,
+	0x0414, 0xA7A5, 0x0415, 0xA7A6, 0x0416, 0xA7A8, 0x0417, 0xA7A9,
+	0x0418, 0xA7AA, 0x0419, 0xA7AB, 0x041A, 0xA7AC, 0x041B, 0xA7AD,
+	0x041C, 0xA7AE, 0x041D, 0xA7AF, 0x041E, 0xA7B0, 0x041F, 0xA7B1,
+	0x0420, 0xA7B2, 0x0421, 0xA7B3, 0x0422, 0xA7B4, 0x0423, 0xA7B5,
+	0x0424, 0xA7B6, 0x0425, 0xA7B7, 0x0426, 0xA7B8, 0x0427, 0xA7B9,
+	0x0428, 0xA7BA, 0x0429, 0xA7BB, 0x042A, 0xA7BC, 0x042B, 0xA7BD,
+	0x042C, 0xA7BE, 0x042D, 0xA7BF, 0x042E, 0xA7C0, 0x042F, 0xA7C1,
+	0x0430, 0xA7D1, 0x0431, 0xA7D2, 0x0432, 0xA7D3, 0x0433, 0xA7D4,
+	0x0434, 0xA7D5, 0x0435, 0xA7D6, 0x0436, 0xA7D8, 0x0437, 0xA7D9,
+	0x0438, 0xA7DA, 0x0439, 0xA7DB, 0x043A, 0xA7DC, 0x043B, 0xA7DD,
+	0x043C, 0xA7DE, 0x043D, 0xA7DF, 0x043E, 0xA7E0, 0x043F, 0xA7E1,
+	0x0440, 0xA7E2, 0x0441, 0xA7E3, 0x0442, 0xA7E4, 0x0443, 0xA7E5,
+	0x0444, 0xA7E6, 0x0445, 0xA7E7, 0x0446, 0xA7E8, 0x0447, 0xA7E9,
+	0x0448, 0xA7EA, 0x0449, 0xA7EB, 0x044A, 0xA7EC, 0x044B, 0xA7ED,
+	0x044C, 0xA7EE, 0x044D, 0xA7EF, 0x044E, 0xA7F0, 0x044F, 0xA7F1,
+	0x0451, 0xA7D7, 0x2010, 0xA95C, 0x2013, 0xA843, 0x2014, 0xA1AA,
+	0x2015, 0xA844, 0x2016, 0xA1AC, 0x2018, 0xA1AE, 0x2019, 0xA1AF,
+	0x201C, 0xA1B0, 0x201D, 0xA1B1, 0x2025, 0xA845, 0x2026, 0xA1AD,
+	0x2030, 0xA1EB, 0x2032, 0xA1E4, 0x2033, 0xA1E5, 0x2035, 0xA846,
+	0x203B, 0xA1F9, 0x20AC, 0x0080, 0x2103, 0xA1E6, 0x2105, 0xA847,
+	0x2109, 0xA848, 0x2116, 0xA1ED, 0x2121, 0xA959, 0x2160, 0xA2F1,
+	0x2161, 0xA2F2, 0x2162, 0xA2F3, 0x2163, 0xA2F4, 0x2164, 0xA2F5,
+	0x2165, 0xA2F6, 0x2166, 0xA2F7, 0x2167, 0xA2F8, 0x2168, 0xA2F9,
+	0x2169, 0xA2FA, 0x216A, 0xA2FB, 0x216B, 0xA2FC, 0x2170, 0xA2A1,
+	0x2171, 0xA2A2, 0x2172, 0xA2A3, 0x2173, 0xA2A4, 0x2174, 0xA2A5,
+	0x2175, 0xA2A6, 0x2176, 0xA2A7, 0x2177, 0xA2A8, 0x2178, 0xA2A9,
+	0x2179, 0xA2AA, 0x2190, 0xA1FB, 0x2191, 0xA1FC, 0x2192, 0xA1FA,
+	0x2193, 0xA1FD, 0x2196, 0xA849, 0x2197, 0xA84A, 0x2198, 0xA84B,
+	0x2199, 0xA84C, 0x2208, 0xA1CA, 0x220F, 0xA1C7, 0x2211, 0xA1C6,
+	0x2215, 0xA84D, 0x221A, 0xA1CC, 0x221D, 0xA1D8, 0x221E, 0xA1DE,
+	0x221F, 0xA84E, 0x2220, 0xA1CF, 0x2223, 0xA84F, 0x2225, 0xA1CE,
+	0x2227, 0xA1C4, 0x2228, 0xA1C5, 0x2229, 0xA1C9, 0x222A, 0xA1C8,
+	0x222B, 0xA1D2, 0x222E, 0xA1D3, 0x2234, 0xA1E0, 0x2235, 0xA1DF,
+	0x2236, 0xA1C3, 0x2237, 0xA1CB, 0x223D, 0xA1D7, 0x2248, 0xA1D6,
+	0x224C, 0xA1D5, 0x2252, 0xA850, 0x2260, 0xA1D9, 0x2261, 0xA1D4,
+	0x2264, 0xA1DC, 0x2265, 0xA1DD, 0x2266, 0xA851, 0x2267, 0xA852,
+	0x226E, 0xA1DA, 0x226F, 0xA1DB, 0x2295, 0xA892, 0x2299, 0xA1D1,
+	0x22A5, 0xA1CD, 0x22BF, 0xA853, 0x2312, 0xA1D0, 0x2460, 0xA2D9,
+	0x2461, 0xA2DA, 0x2462, 0xA2DB, 0x2463, 0xA2DC, 0x2464, 0xA2DD,
+	0x2465, 0xA2DE, 0x2466, 0xA2DF, 0x2467, 0xA2E0, 0x2468, 0xA2E1,
+	0x2469, 0xA2E2, 0x2474, 0xA2C5, 0x2475, 0xA2C6, 0x2476, 0xA2C7,
+	0x2477, 0xA2C8, 0x2478, 0xA2C9, 0x2479, 0xA2CA, 0x247A, 0xA2CB,
+	0x247B, 0xA2CC, 0x247C, 0xA2CD, 0x247D, 0xA2CE, 0x247E, 0xA2CF,
+	0x247F, 0xA2D0, 0x2480, 0xA2D1, 0x2481, 0xA2D2, 0x2482, 0xA2D3,
+	0x2483, 0xA2D4, 0x2484, 0xA2D5, 0x2485, 0xA2D6, 0x2486, 0xA2D7,
+	0x2487, 0xA2D8, 0x2488, 0xA2B1, 0x2489, 0xA2B2, 0x248A, 0xA2B3,
+	0x248B, 0xA2B4, 0x248C, 0xA2B5, 0x248D, 0xA2B6, 0x248E, 0xA2B7,
+	0x248F, 0xA2B8, 0x2490, 0xA2B9, 0x2491, 0xA2BA, 0x2492, 0xA2BB,
+	0x2493, 0xA2BC, 0x2494, 0xA2BD, 0x2495, 0xA2BE, 0x2496, 0xA2BF,
+	0x2497, 0xA2C0, 0x2498, 0xA2C1, 0x2499, 0xA2C2, 0x249A, 0xA2C3,
+	0x249B, 0xA2C4, 0x2500, 0xA9A4, 0x2501, 0xA9A5, 0x2502, 0xA9A6,
+	0x2503, 0xA9A7, 0x2504, 0xA9A8, 0x2505, 0xA9A9, 0x2506, 0xA9AA,
+	0x2507, 0xA9AB, 0x2508, 0xA9AC, 0x2509, 0xA9AD, 0x250A, 0xA9AE,
+	0x250B, 0xA9AF, 0x250C, 0xA9B0, 0x250D, 0xA9B1, 0x250E, 0xA9B2,
+	0x250F, 0xA9B3, 0x2510, 0xA9B4, 0x2511, 0xA9B5, 0x2512, 0xA9B6,
+	0x2513, 0xA9B7, 0x2514, 0xA9B8, 0x2515, 0xA9B9, 0x2516, 0xA9BA,
+	0x2517, 0xA9BB, 0x2518, 0xA9BC, 0x2519, 0xA9BD, 0x251A, 0xA9BE,
+	0x251B, 0xA9BF, 0x251C, 0xA9C0, 0x251D, 0xA9C1, 0x251E, 0xA9C2,
+	0x251F, 0xA9C3, 0x2520, 0xA9C4, 0x2521, 0xA9C5, 0x2522, 0xA9C6,
+	0x2523, 0xA9C7, 0x2524, 0xA9C8, 0x2525, 0xA9C9, 0x2526, 0xA9CA,
+	0x2527, 0xA9CB, 0x2528, 0xA9CC, 0x2529, 0xA9CD, 0x252A, 0xA9CE,
+	0x252B, 0xA9CF, 0x252C, 0xA9D0, 0x252D, 0xA9D1, 0x252E, 0xA9D2,
+	0x252F, 0xA9D3, 0x2530, 0xA9D4, 0x2531, 0xA9D5, 0x2532, 0xA9D6,
+	0x2533, 0xA9D7, 0x2534, 0xA9D8, 0x2535, 0xA9D9, 0x2536, 0xA9DA,
+	0x2537, 0xA9DB, 0x2538, 0xA9DC, 0x2539, 0xA9DD, 0x253A, 0xA9DE,
+	0x253B, 0xA9DF, 0x253C, 0xA9E0, 0x253D, 0xA9E1, 0x253E, 0xA9E2,
+	0x253F, 0xA9E3, 0x2540, 0xA9E4, 0x2541, 0xA9E5, 0x2542, 0xA9E6,
+	0x2543, 0xA9E7, 0x2544, 0xA9E8, 0x2545, 0xA9E9, 0x2546, 0xA9EA,
+	0x2547, 0xA9EB, 0x2548, 0xA9EC, 0x2549, 0xA9ED, 0x254A, 0xA9EE,
+	0x254B, 0xA9EF, 0x2550, 0xA854, 0x2551, 0xA855, 0x2552, 0xA856,
+	0x2553, 0xA857, 0x2554, 0xA858, 0x2555, 0xA859, 0x2556, 0xA85A,
+	0x2557, 0xA85B, 0x2558, 0xA85C, 0x2559, 0xA85D, 0x255A, 0xA85E,
+	0x255B, 0xA85F, 0x255C, 0xA860, 0x255D, 0xA861, 0x255E, 0xA862,
+	0x255F, 0xA863, 0x2560, 0xA864, 0x2561, 0xA865, 0x2562, 0xA866,
+	0x2563, 0xA867, 0x2564, 0xA868, 0x2565, 0xA869, 0x2566, 0xA86A,
+	0x2567, 0xA86B, 0x2568, 0xA86C, 0x2569, 0xA86D, 0x256A, 0xA86E,
+	0x256B, 0xA86F, 0x256C, 0xA870, 0x256D, 0xA871, 0x256E, 0xA872,
+	0x256F, 0xA873, 0x2570, 0xA874, 0x2571, 0xA875, 0x2572, 0xA876,
+	0x2573, 0xA877, 0x2581, 0xA878, 0x2582, 0xA879, 0x2583, 0xA87A,
+	0x2584, 0xA87B, 0x2585, 0xA87C, 0x2586, 0xA87D, 0x2587, 0xA87E,
+	0x2588, 0xA880, 0x2589, 0xA881, 0x258A, 0xA882, 0x258B, 0xA883,
+	0x258C, 0xA884, 0x258D, 0xA885, 0x258E, 0xA886, 0x258F, 0xA887,
+	0x2593, 0xA888, 0x2594, 0xA889, 0x2595, 0xA88A, 0x25A0, 0xA1F6,
+	0x25A1, 0xA1F5, 0x25B2, 0xA1F8, 0x25B3, 0xA1F7, 0x25BC, 0xA88B,
+	0x25BD, 0xA88C, 0x25C6, 0xA1F4, 0x25C7, 0xA1F3, 0x25CB, 0xA1F0,
+	0x25CE, 0xA1F2, 0x25CF, 0xA1F1, 0x25E2, 0xA88D, 0x25E3, 0xA88E,
+	0x25E4, 0xA88F, 0x25E5, 0xA890, 0x2605, 0xA1EF, 0x2606, 0xA1EE,
+	0x2609, 0xA891, 0x2640, 0xA1E2, 0x2642, 0xA1E1, 0x3000, 0xA1A1,
+	0x3001, 0xA1A2, 0x3002, 0xA1A3, 0x3003, 0xA1A8, 0x3005, 0xA1A9,
+	0x3006, 0xA965, 0x3007, 0xA996, 0x3008, 0xA1B4, 0x3009, 0xA1B5,
+	0x300A, 0xA1B6, 0x300B, 0xA1B7, 0x300C, 0xA1B8, 0x300D, 0xA1B9,
+	0x300E, 0xA1BA, 0x300F, 0xA1BB, 0x3010, 0xA1BE, 0x3011, 0xA1BF,
+	0x3012, 0xA893, 0x3013, 0xA1FE, 0x3014, 0xA1B2, 0x3015, 0xA1B3,
+	0x3016, 0xA1BC, 0x3017, 0xA1BD, 0x301D, 0xA894, 0x301E, 0xA895,
+	0x3021, 0xA940, 0x3022, 0xA941, 0x3023, 0xA942, 0x3024, 0xA943,
+	0x3025, 0xA944, 0x3026, 0xA945, 0x3027, 0xA946, 0x3028, 0xA947,
+	0x3029, 0xA948, 0x3041, 0xA4A1, 0x3042, 0xA4A2, 0x3043, 0xA4A3,
+	0x3044, 0xA4A4, 0x3045, 0xA4A5, 0x3046, 0xA4A6, 0x3047, 0xA4A7,
+	0x3048, 0xA4A8, 0x3049, 0xA4A9, 0x304A, 0xA4AA, 0x304B, 0xA4AB,
+	0x304C, 0xA4AC, 0x304D, 0xA4AD, 0x304E, 0xA4AE, 0x304F, 0xA4AF,
+	0x3050, 0xA4B0, 0x3051, 0xA4B1, 0x3052, 0xA4B2, 0x3053, 0xA4B3,
+	0x3054, 0xA4B4, 0x3055, 0xA4B5, 0x3056, 0xA4B6, 0x3057, 0xA4B7,
+	0x3058, 0xA4B8, 0x3059, 0xA4B9, 0x305A, 0xA4BA, 0x305B, 0xA4BB,
+	0x305C, 0xA4BC, 0x305D, 0xA4BD, 0x305E, 0xA4BE, 0x305F, 0xA4BF,
+	0x3060, 0xA4C0, 0x3061, 0xA4C1, 0x3062, 0xA4C2, 0x3063, 0xA4C3,
+	0x3064, 0xA4C4, 0x3065, 0xA4C5, 0x3066, 0xA4C6, 0x3067, 0xA4C7,
+	0x3068, 0xA4C8, 0x3069, 0xA4C9, 0x306A, 0xA4CA, 0x306B, 0xA4CB,
+	0x306C, 0xA4CC, 0x306D, 0xA4CD, 0x306E, 0xA4CE, 0x306F, 0xA4CF,
+	0x3070, 0xA4D0, 0x3071, 0xA4D1, 0x3072, 0xA4D2, 0x3073, 0xA4D3,
+	0x3074, 0xA4D4, 0x3075, 0xA4D5, 0x3076, 0xA4D6, 0x3077, 0xA4D7,
+	0x3078, 0xA4D8, 0x3079, 0xA4D9, 0x307A, 0xA4DA, 0x307B, 0xA4DB,
+	0x307C, 0xA4DC, 0x307D, 0xA4DD, 0x307E, 0xA4DE, 0x307F, 0xA4DF,
+	0x3080, 0xA4E0, 0x3081, 0xA4E1, 0x3082, 0xA4E2, 0x3083, 0xA4E3,
+	0x3084, 0xA4E4, 0x3085, 0xA4E5, 0x3086, 0xA4E6, 0x3087, 0xA4E7,
+	0x3088, 0xA4E8, 0x3089, 0xA4E9, 0x308A, 0xA4EA, 0x308B, 0xA4EB,
+	0x308C, 0xA4EC, 0x308D, 0xA4ED, 0x308E, 0xA4EE, 0x308F, 0xA4EF,
+	0x3090, 0xA4F0, 0x3091, 0xA4F1, 0x3092, 0xA4F2, 0x3093, 0xA4F3,
+	0x309B, 0xA961, 0x309C, 0xA962, 0x309D, 0xA966, 0x309E, 0xA967,
+	0x30A1, 0xA5A1, 0x30A2, 0xA5A2, 0x30A3, 0xA5A3, 0x30A4, 0xA5A4,
+	0x30A5, 0xA5A5, 0x30A6, 0xA5A6, 0x30A7, 0xA5A7, 0x30A8, 0xA5A8,
+	0x30A9, 0xA5A9, 0x30AA, 0xA5AA, 0x30AB, 0xA5AB, 0x30AC, 0xA5AC,
+	0x30AD, 0xA5AD, 0x30AE, 0xA5AE, 0x30AF, 0xA5AF, 0x30B0, 0xA5B0,
+	0x30B1, 0xA5B1, 0x30B2, 0xA5B2, 0x30B3, 0xA5B3, 0x30B4, 0xA5B4,
+	0x30B5, 0xA5B5, 0x30B6, 0xA5B6, 0x30B7, 0xA5B7, 0x30B8, 0xA5B8,
+	0x30B9, 0xA5B9, 0x30BA, 0xA5BA, 0x30BB, 0xA5BB, 0x30BC, 0xA5BC,
+	0x30BD, 0xA5BD, 0x30BE, 0xA5BE, 0x30BF, 0xA5BF, 0x30C0, 0xA5C0,
+	0x30C1, 0xA5C1, 0x30C2, 0xA5C2, 0x30C3, 0xA5C3, 0x30C4, 0xA5C4,
+	0x30C5, 0xA5C5, 0x30C6, 0xA5C6, 0x30C7, 0xA5C7, 0x30C8, 0xA5C8,
+	0x30C9, 0xA5C9, 0x30CA, 0xA5CA, 0x30CB, 0xA5CB, 0x30CC, 0xA5CC,
+	0x30CD, 0xA5CD, 0x30CE, 0xA5CE, 0x30CF, 0xA5CF, 0x30D0, 0xA5D0,
+	0x30D1, 0xA5D1, 0x30D2, 0xA5D2, 0x30D3, 0xA5D3, 0x30D4, 0xA5D4,
+	0x30D5, 0xA5D5, 0x30D6, 0xA5D6, 0x30D7, 0xA5D7, 0x30D8, 0xA5D8,
+	0x30D9, 0xA5D9, 0x30DA, 0xA5DA, 0x30DB, 0xA5DB, 0x30DC, 0xA5DC,
+	0x30DD, 0xA5DD, 0x30DE, 0xA5DE, 0x30DF, 0xA5DF, 0x30E0, 0xA5E0,
+	0x30E1, 0xA5E1, 0x30E2, 0xA5E2, 0x30E3, 0xA5E3, 0x30E4, 0xA5E4,
+	0x30E5, 0xA5E5, 0x30E6, 0xA5E6, 0x30E7, 0xA5E7, 0x30E8, 0xA5E8,
+	0x30E9, 0xA5E9, 0x30EA, 0xA5EA, 0x30EB, 0xA5EB, 0x30EC, 0xA5EC,
+	0x30ED, 0xA5ED, 0x30EE, 0xA5EE, 0x30EF, 0xA5EF, 0x30F0, 0xA5F0,
+	0x30F1, 0xA5F1, 0x30F2, 0xA5F2, 0x30F3, 0xA5F3, 0x30F4, 0xA5F4,
+	0x30F5, 0xA5F5, 0x30F6, 0xA5F6, 0x30FC, 0xA960, 0x30FD, 0xA963,
+	0x30FE, 0xA964, 0x3105, 0xA8C5, 0x3106, 0xA8C6, 0x3107, 0xA8C7,
+	0x3108, 0xA8C8, 0x3109, 0xA8C9, 0x310A, 0xA8CA, 0x310B, 0xA8CB,
+	0x310C, 0xA8CC, 0x310D, 0xA8CD, 0x310E, 0xA8CE, 0x310F, 0xA8CF,
+	0x3110, 0xA8D0, 0x3111, 0xA8D1, 0x3112, 0xA8D2, 0x3113, 0xA8D3,
+	0x3114, 0xA8D4, 0x3115, 0xA8D5, 0x3116, 0xA8D6, 0x3117, 0xA8D7,
+	0x3118, 0xA8D8, 0x3119, 0xA8D9, 0x311A, 0xA8DA, 0x311B, 0xA8DB,
+	0x311C, 0xA8DC, 0x311D, 0xA8DD, 0x311E, 0xA8DE, 0x311F, 0xA8DF,
+	0x3120, 0xA8E0, 0x3121, 0xA8E1, 0x3122, 0xA8E2, 0x3123, 0xA8E3,
+	0x3124, 0xA8E4, 0x3125, 0xA8E5, 0x3126, 0xA8E6, 0x3127, 0xA8E7,
+	0x3128, 0xA8E8, 0x3129, 0xA8E9, 0x3220, 0xA2E5, 0x3221, 0xA2E6,
+	0x3222, 0xA2E7, 0x3223, 0xA2E8, 0x3224, 0xA2E9, 0x3225, 0xA2EA,
+	0x3226, 0xA2EB, 0x3227, 0xA2EC, 0x3228, 0xA2ED, 0x3229, 0xA2EE,
+	0x3231, 0xA95A, 0x32A3, 0xA949, 0x338E, 0xA94A, 0x338F, 0xA94B,
+	0x339C, 0xA94C, 0x339D, 0xA94D, 0x339E, 0xA94E, 0x33A1, 0xA94F,
+	0x33C4, 0xA950, 0x33CE, 0xA951, 0x33D1, 0xA952, 0x33D2, 0xA953,
+	0x33D5, 0xA954, 0x4E00, 0xD2BB, 0x4E01, 0xB6A1, 0x4E02, 0x8140,
+	0x4E03, 0xC6DF, 0x4E04, 0x8141, 0x4E05, 0x8142, 0x4E06, 0x8143,
+	0x4E07, 0xCDF2, 0x4E08, 0xD5C9, 0x4E09, 0xC8FD, 0x4E0A, 0xC9CF,
+	0x4E0B, 0xCFC2, 0x4E0C, 0xD8A2, 0x4E0D, 0xB2BB, 0x4E0E, 0xD3EB,
+	0x4E0F, 0x8144, 0x4E10, 0xD8A4, 0x4E11, 0xB3F3, 0x4E12, 0x8145,
+	0x4E13, 0xD7A8, 0x4E14, 0xC7D2, 0x4E15, 0xD8A7, 0x4E16, 0xCAC0,
+	0x4E17, 0x8146, 0x4E18, 0xC7F0, 0x4E19, 0xB1FB, 0x4E1A, 0xD2B5,
+	0x4E1B, 0xB4D4, 0x4E1C, 0xB6AB, 0x4E1D, 0xCBBF, 0x4E1E, 0xD8A9,
+	0x4E1F, 0x8147, 0x4E20, 0x8148, 0x4E21, 0x8149, 0x4E22, 0xB6AA,
+	0x4E23, 0x814A, 0x4E24, 0xC1BD, 0x4E25, 0xD1CF, 0x4E26, 0x814B,
+	0x4E27, 0xC9A5, 0x4E28, 0xD8AD, 0x4E29, 0x814C, 0x4E2A, 0xB8F6,
+	0x4E2B, 0xD1BE, 0x4E2C, 0xE3DC, 0x4E2D, 0xD6D0, 0x4E2E, 0x814D,
+	0x4E2F, 0x814E, 0x4E30, 0xB7E1, 0x4E31, 0x814F, 0x4E32, 0xB4AE,
+	0x4E33, 0x8150, 0x4E34, 0xC1D9, 0x4E35, 0x8151, 0x4E36, 0xD8BC,
+	0x4E37, 0x8152, 0x4E38, 0xCDE8, 0x4E39, 0xB5A4, 0x4E3A, 0xCEAA,
+	0x4E3B, 0xD6F7, 0x4E3C, 0x8153, 0x4E3D, 0xC0F6, 0x4E3E, 0xBED9,
+	0x4E3F, 0xD8AF, 0x4E40, 0x8154, 0x4E41, 0x8155, 0x4E42, 0x8156,
+	0x4E43, 0xC4CB, 0x4E44, 0x8157, 0x4E45, 0xBEC3, 0x4E46, 0x8158,
+	0x4E47, 0xD8B1, 0x4E48, 0xC3B4, 0x4E49, 0xD2E5, 0x4E4A, 0x8159,
+	0x4E4B, 0xD6AE, 0x4E4C, 0xCEDA, 0x4E4D, 0xD5A7, 0x4E4E, 0xBAF5,
+	0x4E4F, 0xB7A6, 0x4E50, 0xC0D6, 0x4E51, 0x815A, 0x4E52, 0xC6B9,
+	0x4E53, 0xC5D2, 0x4E54, 0xC7C7, 0x4E55, 0x815B, 0x4E56, 0xB9D4,
+	0x4E57, 0x815C, 0x4E58, 0xB3CB, 0x4E59, 0xD2D2, 0x4E5A, 0x815D,
+	0x4E5B, 0x815E, 0x4E5C, 0xD8BF, 0x4E5D, 0xBEC5, 0x4E5E, 0xC6F2,
+	0x4E5F, 0xD2B2, 0x4E60, 0xCFB0, 0x4E61, 0xCFE7, 0x4E62, 0x815F,
+	0x4E63, 0x8160, 0x4E64, 0x8161, 0x4E65, 0x8162, 0x4E66, 0xCAE9,
+	0x4E67, 0x8163, 0x4E68, 0x8164, 0x4E69, 0xD8C0, 0x4E6A, 0x8165,
+	0x4E6B, 0x8166, 0x4E6C, 0x8167, 0x4E6D, 0x8168, 0x4E6E, 0x8169,
+	0x4E6F, 0x816A, 0x4E70, 0xC2F2, 0x4E71, 0xC2D2, 0x4E72, 0x816B,
+	0x4E73, 0xC8E9, 0x4E74, 0x816C, 0x4E75, 0x816D, 0x4E76, 0x816E,
+	0x4E77, 0x816F, 0x4E78, 0x8170, 0x4E79, 0x8171, 0x4E7A, 0x8172,
+	0x4E7B, 0x8173, 0x4E7C, 0x8174, 0x4E7D, 0x8175, 0x4E7E, 0xC7AC,
+	0x4E7F, 0x8176, 0x4E80, 0x8177, 0x4E81, 0x8178, 0x4E82, 0x8179,
+	0x4E83, 0x817A, 0x4E84, 0x817B, 0x4E85, 0x817C, 0x4E86, 0xC1CB,
+	0x4E87, 0x817D, 0x4E88, 0xD3E8, 0x4E89, 0xD5F9, 0x4E8A, 0x817E,
+	0x4E8B, 0xCAC2, 0x4E8C, 0xB6FE, 0x4E8D, 0xD8A1, 0x4E8E, 0xD3DA,
+	0x4E8F, 0xBFF7, 0x4E90, 0x8180, 0x4E91, 0xD4C6, 0x4E92, 0xBBA5,
+	0x4E93, 0xD8C1, 0x4E94, 0xCEE5, 0x4E95, 0xBEAE, 0x4E96, 0x8181,
+	0x4E97, 0x8182, 0x4E98, 0xD8A8, 0x4E99, 0x8183, 0x4E9A, 0xD1C7,
+	0x4E9B, 0xD0A9, 0x4E9C, 0x8184, 0x4E9D, 0x8185, 0x4E9E, 0x8186,
+	0x4E9F, 0xD8BD, 0x4EA0, 0xD9EF, 0x4EA1, 0xCDF6, 0x4EA2, 0xBFBA,
+	0x4EA3, 0x8187, 0x4EA4, 0xBDBB, 0x4EA5, 0xBAA5, 0x4EA6, 0xD2E0,
+	0x4EA7, 0xB2FA, 0x4EA8, 0xBAE0, 0x4EA9, 0xC4B6, 0x4EAA, 0x8188,
+	0x4EAB, 0xCFED, 0x4EAC, 0xBEA9, 0x4EAD, 0xCDA4, 0x4EAE, 0xC1C1,
+	0x4EAF, 0x8189, 0x4EB0, 0x818A, 0x4EB1, 0x818B, 0x4EB2, 0xC7D7,
+	0x4EB3, 0xD9F1, 0x4EB4, 0x818C, 0x4EB5, 0xD9F4, 0x4EB6, 0x818D,
+	0x4EB7, 0x818E, 0x4EB8, 0x818F, 0x4EB9, 0x8190, 0x4EBA, 0xC8CB,
+	0x4EBB, 0xD8E9, 0x4EBC, 0x8191, 0x4EBD, 0x8192, 0x4EBE, 0x8193,
+	0x4EBF, 0xD2DA, 0x4EC0, 0xCAB2, 0x4EC1, 0xC8CA, 0x4EC2, 0xD8EC,
+	0x4EC3, 0xD8EA, 0x4EC4, 0xD8C6, 0x4EC5, 0xBDF6, 0x4EC6, 0xC6CD,
+	0x4EC7, 0xB3F0, 0x4EC8, 0x8194, 0x4EC9, 0xD8EB, 0x4ECA, 0xBDF1,
+	0x4ECB, 0xBDE9, 0x4ECC, 0x8195, 0x4ECD, 0xC8D4, 0x4ECE, 0xB4D3,
+	0x4ECF, 0x8196, 0x4ED0, 0x8197, 0x4ED1, 0xC2D8, 0x4ED2, 0x8198,
+	0x4ED3, 0xB2D6, 0x4ED4, 0xD7D0, 0x4ED5, 0xCACB, 0x4ED6, 0xCBFB,
+	0x4ED7, 0xD5CC, 0x4ED8, 0xB8B6, 0x4ED9, 0xCFC9, 0x4EDA, 0x8199,
+	0x4EDB, 0x819A, 0x4EDC, 0x819B, 0x4EDD, 0xD9DA, 0x4EDE, 0xD8F0,
+	0x4EDF, 0xC7AA, 0x4EE0, 0x819C, 0x4EE1, 0xD8EE, 0x4EE2, 0x819D,
+	0x4EE3, 0xB4FA, 0x4EE4, 0xC1EE, 0x4EE5, 0xD2D4, 0x4EE6, 0x819E,
+	0x4EE7, 0x819F, 0x4EE8, 0xD8ED, 0x4EE9, 0x81A0, 0x4EEA, 0xD2C7,
+	0x4EEB, 0xD8EF, 0x4EEC, 0xC3C7, 0x4EED, 0x81A1, 0x4EEE, 0x81A2,
+	0x4EEF, 0x81A3, 0x4EF0, 0xD1F6, 0x4EF1, 0x81A4, 0x4EF2, 0xD6D9,
+	0x4EF3, 0xD8F2, 0x4EF4, 0x81A5, 0x4EF5, 0xD8F5, 0x4EF6, 0xBCFE,
+	0x4EF7, 0xBCDB, 0x4EF8, 0x81A6, 0x4EF9, 0x81A7, 0x4EFA, 0x81A8,
+	0x4EFB, 0xC8CE, 0x4EFC, 0x81A9, 0x4EFD, 0xB7DD, 0x4EFE, 0x81AA,
+	0x4EFF, 0xB7C2, 0x4F00, 0x81AB, 0x4F01, 0xC6F3, 0x4F02, 0x81AC,
+	0x4F03, 0x81AD, 0x4F04, 0x81AE, 0x4F05, 0x81AF, 0x4F06, 0x81B0,
+	0x4F07, 0x81B1, 0x4F08, 0x81B2, 0x4F09, 0xD8F8, 0x4F0A, 0xD2C1,
+	0x4F0B, 0x81B3, 0x4F0C, 0x81B4, 0x4F0D, 0xCEE9, 0x4F0E, 0xBCBF,
+	0x4F0F, 0xB7FC, 0x4F10, 0xB7A5, 0x4F11, 0xD0DD, 0x4F12, 0x81B5,
+	0x4F13, 0x81B6, 0x4F14, 0x81B7, 0x4F15, 0x81B8, 0x4F16, 0x81B9,
+	0x4F17, 0xD6DA, 0x4F18, 0xD3C5, 0x4F19, 0xBBEF, 0x4F1A, 0xBBE1,
+	0x4F1B, 0xD8F1, 0x4F1C, 0x81BA, 0x4F1D, 0x81BB, 0x4F1E, 0xC9A1,
+	0x4F1F, 0xCEB0, 0x4F20, 0xB4AB, 0x4F21, 0x81BC, 0x4F22, 0xD8F3,
+	0x4F23, 0x81BD, 0x4F24, 0xC9CB, 0x4F25, 0xD8F6, 0x4F26, 0xC2D7,
+	0x4F27, 0xD8F7, 0x4F28, 0x81BE, 0x4F29, 0x81BF, 0x4F2A, 0xCEB1,
+	0x4F2B, 0xD8F9, 0x4F2C, 0x81C0, 0x4F2D, 0x81C1, 0x4F2E, 0x81C2,
+	0x4F2F, 0xB2AE, 0x4F30, 0xB9C0, 0x4F31, 0x81C3, 0x4F32, 0xD9A3,
+	0x4F33, 0x81C4, 0x4F34, 0xB0E9, 0x4F35, 0x81C5, 0x4F36, 0xC1E6,
+	0x4F37, 0x81C6, 0x4F38, 0xC9EC, 0x4F39, 0x81C7, 0x4F3A, 0xCBC5,
+	0x4F3B, 0x81C8, 0x4F3C, 0xCBC6, 0x4F3D, 0xD9A4, 0x4F3E, 0x81C9,
+	0x4F3F, 0x81CA, 0x4F40, 0x81CB, 0x4F41, 0x81CC, 0x4F42, 0x81CD,
+	0x4F43, 0xB5E8, 0x4F44, 0x81CE, 0x4F45, 0x81CF, 0x4F46, 0xB5AB,
+	0x4F47, 0x81D0, 0x4F48, 0x81D1, 0x4F49, 0x81D2, 0x4F4A, 0x81D3,
+	0x4F4B, 0x81D4, 0x4F4C, 0x81D5, 0x4F4D, 0xCEBB, 0x4F4E, 0xB5CD,
+	0x4F4F, 0xD7A1, 0x4F50, 0xD7F4, 0x4F51, 0xD3D3, 0x4F52, 0x81D6,
+	0x4F53, 0xCCE5, 0x4F54, 0x81D7, 0x4F55, 0xBACE, 0x4F56, 0x81D8,
+	0x4F57, 0xD9A2, 0x4F58, 0xD9DC, 0x4F59, 0xD3E0, 0x4F5A, 0xD8FD,
+	0x4F5B, 0xB7F0, 0x4F5C, 0xD7F7, 0x4F5D, 0xD8FE, 0x4F5E, 0xD8FA,
+	0x4F5F, 0xD9A1, 0x4F60, 0xC4E3, 0x4F61, 0x81D9, 0x4F62, 0x81DA,
+	0x4F63, 0xD3B6, 0x4F64, 0xD8F4, 0x4F65, 0xD9DD, 0x4F66, 0x81DB,
+	0x4F67, 0xD8FB, 0x4F68, 0x81DC, 0x4F69, 0xC5E5, 0x4F6A, 0x81DD,
+	0x4F6B, 0x81DE, 0x4F6C, 0xC0D0, 0x4F6D, 0x81DF, 0x4F6E, 0x81E0,
+	0x4F6F, 0xD1F0, 0x4F70, 0xB0DB, 0x4F71, 0x81E1, 0x4F72, 0x81E2,
+	0x4F73, 0xBCD1, 0x4F74, 0xD9A6, 0x4F75, 0x81E3, 0x4F76, 0xD9A5,
+	0x4F77, 0x81E4, 0x4F78, 0x81E5, 0x4F79, 0x81E6, 0x4F7A, 0x81E7,
+	0x4F7B, 0xD9AC, 0x4F7C, 0xD9AE, 0x4F7D, 0x81E8, 0x4F7E, 0xD9AB,
+	0x4F7F, 0xCAB9, 0x4F80, 0x81E9, 0x4F81, 0x81EA, 0x4F82, 0x81EB,
+	0x4F83, 0xD9A9, 0x4F84, 0xD6B6, 0x4F85, 0x81EC, 0x4F86, 0x81ED,
+	0x4F87, 0x81EE, 0x4F88, 0xB3DE, 0x4F89, 0xD9A8, 0x4F8A, 0x81EF,
+	0x4F8B, 0xC0FD, 0x4F8C, 0x81F0, 0x4F8D, 0xCACC, 0x4F8E, 0x81F1,
+	0x4F8F, 0xD9AA, 0x4F90, 0x81F2, 0x4F91, 0xD9A7, 0x4F92, 0x81F3,
+	0x4F93, 0x81F4, 0x4F94, 0xD9B0, 0x4F95, 0x81F5, 0x4F96, 0x81F6,
+	0x4F97, 0xB6B1, 0x4F98, 0x81F7, 0x4F99, 0x81F8, 0x4F9A, 0x81F9,
+	0x4F9B, 0xB9A9, 0x4F9C, 0x81FA, 0x4F9D, 0xD2C0, 0x4F9E, 0x81FB,
+	0x4F9F, 0x81FC, 0x4FA0, 0xCFC0, 0x4FA1, 0x81FD, 0x4FA2, 0x81FE,
+	0x4FA3, 0xC2C2, 0x4FA4, 0x8240, 0x4FA5, 0xBDC4, 0x4FA6, 0xD5EC,
+	0x4FA7, 0xB2E0, 0x4FA8, 0xC7C8, 0x4FA9, 0xBFEB, 0x4FAA, 0xD9AD,
+	0x4FAB, 0x8241, 0x4FAC, 0xD9AF, 0x4FAD, 0x8242, 0x4FAE, 0xCEEA,
+	0x4FAF, 0xBAEE, 0x4FB0, 0x8243, 0x4FB1, 0x8244, 0x4FB2, 0x8245,
+	0x4FB3, 0x8246, 0x4FB4, 0x8247, 0x4FB5, 0xC7D6, 0x4FB6, 0x8248,
+	0x4FB7, 0x8249, 0x4FB8, 0x824A, 0x4FB9, 0x824B, 0x4FBA, 0x824C,
+	0x4FBB, 0x824D, 0x4FBC, 0x824E, 0x4FBD, 0x824F, 0x4FBE, 0x8250,
+	0x4FBF, 0xB1E3, 0x4FC0, 0x8251, 0x4FC1, 0x8252, 0x4FC2, 0x8253,
+	0x4FC3, 0xB4D9, 0x4FC4, 0xB6ED, 0x4FC5, 0xD9B4, 0x4FC6, 0x8254,
+	0x4FC7, 0x8255, 0x4FC8, 0x8256, 0x4FC9, 0x8257, 0x4FCA, 0xBFA1,
+	0x4FCB, 0x8258, 0x4FCC, 0x8259, 0x4FCD, 0x825A, 0x4FCE, 0xD9DE,
+	0x4FCF, 0xC7CE, 0x4FD0, 0xC0FE, 0x4FD1, 0xD9B8, 0x4FD2, 0x825B,
+	0x4FD3, 0x825C, 0x4FD4, 0x825D, 0x4FD5, 0x825E, 0x4FD6, 0x825F,
+	0x4FD7, 0xCBD7, 0x4FD8, 0xB7FD, 0x4FD9, 0x8260, 0x4FDA, 0xD9B5,
+	0x4FDB, 0x8261, 0x4FDC, 0xD9B7, 0x4FDD, 0xB1A3, 0x4FDE, 0xD3E1,
+	0x4FDF, 0xD9B9, 0x4FE0, 0x8262, 0x4FE1, 0xD0C5, 0x4FE2, 0x8263,
+	0x4FE3, 0xD9B6, 0x4FE4, 0x8264, 0x4FE5, 0x8265, 0x4FE6, 0xD9B1,
+	0x4FE7, 0x8266, 0x4FE8, 0xD9B2, 0x4FE9, 0xC1A9, 0x4FEA, 0xD9B3,
+	0x4FEB, 0x8267, 0x4FEC, 0x8268, 0x4FED, 0xBCF3, 0x4FEE, 0xD0DE,
+	0x4FEF, 0xB8A9, 0x4FF0, 0x8269, 0x4FF1, 0xBEE3, 0x4FF2, 0x826A,
+	0x4FF3, 0xD9BD, 0x4FF4, 0x826B, 0x4FF5, 0x826C, 0x4FF6, 0x826D,
+	0x4FF7, 0x826E, 0x4FF8, 0xD9BA, 0x4FF9, 0x826F, 0x4FFA, 0xB0B3,
+	0x4FFB, 0x8270, 0x4FFC, 0x8271, 0x4FFD, 0x8272, 0x4FFE, 0xD9C2,
+	0x4FFF, 0x8273, 0x5000, 0x8274, 0x5001, 0x8275, 0x5002, 0x8276,
+	0x5003, 0x8277, 0x5004, 0x8278, 0x5005, 0x8279, 0x5006, 0x827A,
+	0x5007, 0x827B, 0x5008, 0x827C, 0x5009, 0x827D, 0x500A, 0x827E,
+	0x500B, 0x8280, 0x500C, 0xD9C4, 0x500D, 0xB1B6, 0x500E, 0x8281,
+	0x500F, 0xD9BF, 0x5010, 0x8282, 0x5011, 0x8283, 0x5012, 0xB5B9,
+	0x5013, 0x8284, 0x5014, 0xBEF3, 0x5015, 0x8285, 0x5016, 0x8286,
+	0x5017, 0x8287, 0x5018, 0xCCC8, 0x5019, 0xBAF2, 0x501A, 0xD2D0,
+	0x501B, 0x8288, 0x501C, 0xD9C3, 0x501D, 0x8289, 0x501E, 0x828A,
+	0x501F, 0xBDE8, 0x5020, 0x828B, 0x5021, 0xB3AB, 0x5022, 0x828C,
+	0x5023, 0x828D, 0x5024, 0x828E, 0x5025, 0xD9C5, 0x5026, 0xBEEB,
+	0x5027, 0x828F, 0x5028, 0xD9C6, 0x5029, 0xD9BB, 0x502A, 0xC4DF,
+	0x502B, 0x8290, 0x502C, 0xD9BE, 0x502D, 0xD9C1, 0x502E, 0xD9C0,
+	0x502F, 0x8291, 0x5030, 0x8292, 0x5031, 0x8293, 0x5032, 0x8294,
+	0x5033, 0x8295, 0x5034, 0x8296, 0x5035, 0x8297, 0x5036, 0x8298,
+	0x5037, 0x8299, 0x5038, 0x829A, 0x5039, 0x829B, 0x503A, 0xD5AE,
+	0x503B, 0x829C, 0x503C, 0xD6B5, 0x503D, 0x829D, 0x503E, 0xC7E3,
+	0x503F, 0x829E, 0x5040, 0x829F, 0x5041, 0x82A0, 0x5042, 0x82A1,
+	0x5043, 0xD9C8, 0x5044, 0x82A2, 0x5045, 0x82A3, 0x5046, 0x82A4,
+	0x5047, 0xBCD9, 0x5048, 0xD9CA, 0x5049, 0x82A5, 0x504A, 0x82A6,
+	0x504B, 0x82A7, 0x504C, 0xD9BC, 0x504D, 0x82A8, 0x504E, 0xD9CB,
+	0x504F, 0xC6AB, 0x5050, 0x82A9, 0x5051, 0x82AA, 0x5052, 0x82AB,
+	0x5053, 0x82AC, 0x5054, 0x82AD, 0x5055, 0xD9C9, 0x5056, 0x82AE,
+	0x5057, 0x82AF, 0x5058, 0x82B0, 0x5059, 0x82B1, 0x505A, 0xD7F6,
+	0x505B, 0x82B2, 0x505C, 0xCDA3, 0x505D, 0x82B3, 0x505E, 0x82B4,
+	0x505F, 0x82B5, 0x5060, 0x82B6, 0x5061, 0x82B7, 0x5062, 0x82B8,
+	0x5063, 0x82B9, 0x5064, 0x82BA, 0x5065, 0xBDA1, 0x5066, 0x82BB,
+	0x5067, 0x82BC, 0x5068, 0x82BD, 0x5069, 0x82BE, 0x506A, 0x82BF,
+	0x506B, 0x82C0, 0x506C, 0xD9CC, 0x506D, 0x82C1, 0x506E, 0x82C2,
+	0x506F, 0x82C3, 0x5070, 0x82C4, 0x5071, 0x82C5, 0x5072, 0x82C6,
+	0x5073, 0x82C7, 0x5074, 0x82C8, 0x5075, 0x82C9, 0x5076, 0xC5BC,
+	0x5077, 0xCDB5, 0x5078, 0x82CA, 0x5079, 0x82CB, 0x507A, 0x82CC,
+	0x507B, 0xD9CD, 0x507C, 0x82CD, 0x507D, 0x82CE, 0x507E, 0xD9C7,
+	0x507F, 0xB3A5, 0x5080, 0xBFFE, 0x5081, 0x82CF, 0x5082, 0x82D0,
+	0x5083, 0x82D1, 0x5084, 0x82D2, 0x5085, 0xB8B5, 0x5086, 0x82D3,
+	0x5087, 0x82D4, 0x5088, 0xC0FC, 0x5089, 0x82D5, 0x508A, 0x82D6,
+	0x508B, 0x82D7, 0x508C, 0x82D8, 0x508D, 0xB0F8, 0x508E, 0x82D9,
+	0x508F, 0x82DA, 0x5090, 0x82DB, 0x5091, 0x82DC, 0x5092, 0x82DD,
+	0x5093, 0x82DE, 0x5094, 0x82DF, 0x5095, 0x82E0, 0x5096, 0x82E1,
+	0x5097, 0x82E2, 0x5098, 0x82E3, 0x5099, 0x82E4, 0x509A, 0x82E5,
+	0x509B, 0x82E6, 0x509C, 0x82E7, 0x509D, 0x82E8, 0x509E, 0x82E9,
+	0x509F, 0x82EA, 0x50A0, 0x82EB, 0x50A1, 0x82EC, 0x50A2, 0x82ED,
+	0x50A3, 0xB4F6, 0x50A4, 0x82EE, 0x50A5, 0xD9CE, 0x50A6, 0x82EF,
+	0x50A7, 0xD9CF, 0x50A8, 0xB4A2, 0x50A9, 0xD9D0, 0x50AA, 0x82F0,
+	0x50AB, 0x82F1, 0x50AC, 0xB4DF, 0x50AD, 0x82F2, 0x50AE, 0x82F3,
+	0x50AF, 0x82F4, 0x50B0, 0x82F5, 0x50B1, 0x82F6, 0x50B2, 0xB0C1,
+	0x50B3, 0x82F7, 0x50B4, 0x82F8, 0x50B5, 0x82F9, 0x50B6, 0x82FA,
+	0x50B7, 0x82FB, 0x50B8, 0x82FC, 0x50B9, 0x82FD, 0x50BA, 0xD9D1,
+	0x50BB, 0xC9B5, 0x50BC, 0x82FE, 0x50BD, 0x8340, 0x50BE, 0x8341,
+	0x50BF, 0x8342, 0x50C0, 0x8343, 0x50C1, 0x8344, 0x50C2, 0x8345,
+	0x50C3, 0x8346, 0x50C4, 0x8347, 0x50C5, 0x8348, 0x50C6, 0x8349,
+	0x50C7, 0x834A, 0x50C8, 0x834B, 0x50C9, 0x834C, 0x50CA, 0x834D,
+	0x50CB, 0x834E, 0x50CC, 0x834F, 0x50CD, 0x8350, 0x50CE, 0x8351,
+	0x50CF, 0xCFF1, 0x50D0, 0x8352, 0x50D1, 0x8353, 0x50D2, 0x8354,
+	0x50D3, 0x8355, 0x50D4, 0x8356, 0x50D5, 0x8357, 0x50D6, 0xD9D2,
+	0x50D7, 0x8358, 0x50D8, 0x8359, 0x50D9, 0x835A, 0x50DA, 0xC1C5,
+	0x50DB, 0x835B, 0x50DC, 0x835C, 0x50DD, 0x835D, 0x50DE, 0x835E,
+	0x50DF, 0x835F, 0x50E0, 0x8360, 0x50E1, 0x8361, 0x50E2, 0x8362,
+	0x50E3, 0x8363, 0x50E4, 0x8364, 0x50E5, 0x8365, 0x50E6, 0xD9D6,
+	0x50E7, 0xC9AE, 0x50E8, 0x8366, 0x50E9, 0x8367, 0x50EA, 0x8368,
+	0x50EB, 0x8369, 0x50EC, 0xD9D5, 0x50ED, 0xD9D4, 0x50EE, 0xD9D7,
+	0x50EF, 0x836A, 0x50F0, 0x836B, 0x50F1, 0x836C, 0x50F2, 0x836D,
+	0x50F3, 0xCBDB, 0x50F4, 0x836E, 0x50F5, 0xBDA9, 0x50F6, 0x836F,
+	0x50F7, 0x8370, 0x50F8, 0x8371, 0x50F9, 0x8372, 0x50FA, 0x8373,
+	0x50FB, 0xC6A7, 0x50FC, 0x8374, 0x50FD, 0x8375, 0x50FE, 0x8376,
+	0x50FF, 0x8377, 0x5100, 0x8378, 0x5101, 0x8379, 0x5102, 0x837A,
+	0x5103, 0x837B, 0x5104, 0x837C, 0x5105, 0x837D, 0x5106, 0xD9D3,
+	0x5107, 0xD9D8, 0x5108, 0x837E, 0x5109, 0x8380, 0x510A, 0x8381,
+	0x510B, 0xD9D9, 0x510C, 0x8382, 0x510D, 0x8383, 0x510E, 0x8384,
+	0x510F, 0x8385, 0x5110, 0x8386, 0x5111, 0x8387, 0x5112, 0xC8E5,
+	0x5113, 0x8388, 0x5114, 0x8389, 0x5115, 0x838A, 0x5116, 0x838B,
+	0x5117, 0x838C, 0x5118, 0x838D, 0x5119, 0x838E, 0x511A, 0x838F,
+	0x511B, 0x8390, 0x511C, 0x8391, 0x511D, 0x8392, 0x511E, 0x8393,
+	0x511F, 0x8394, 0x5120, 0x8395, 0x5121, 0xC0DC, 0x5122, 0x8396,
+	0x5123, 0x8397, 0x5124, 0x8398, 0x5125, 0x8399, 0x5126, 0x839A,
+	0x5127, 0x839B, 0x5128, 0x839C, 0x5129, 0x839D, 0x512A, 0x839E,
+	0x512B, 0x839F, 0x512C, 0x83A0, 0x512D, 0x83A1, 0x512E, 0x83A2,
+	0x512F, 0x83A3, 0x5130, 0x83A4, 0x5131, 0x83A5, 0x5132, 0x83A6,
+	0x5133, 0x83A7, 0x5134, 0x83A8, 0x5135, 0x83A9, 0x5136, 0x83AA,
+	0x5137, 0x83AB, 0x5138, 0x83AC, 0x5139, 0x83AD, 0x513A, 0x83AE,
+	0x513B, 0x83AF, 0x513C, 0x83B0, 0x513D, 0x83B1, 0x513E, 0x83B2,
+	0x513F, 0xB6F9, 0x5140, 0xD8A3, 0x5141, 0xD4CA, 0x5142, 0x83B3,
+	0x5143, 0xD4AA, 0x5144, 0xD0D6, 0x5145, 0xB3E4, 0x5146, 0xD5D7,
+	0x5147, 0x83B4, 0x5148, 0xCFC8, 0x5149, 0xB9E2, 0x514A, 0x83B5,
+	0x514B, 0xBFCB, 0x514C, 0x83B6, 0x514D, 0xC3E2, 0x514E, 0x83B7,
+	0x514F, 0x83B8, 0x5150, 0x83B9, 0x5151, 0xB6D2, 0x5152, 0x83BA,
+	0x5153, 0x83BB, 0x5154, 0xCDC3, 0x5155, 0xD9EE, 0x5156, 0xD9F0,
+	0x5157, 0x83BC, 0x5158, 0x83BD, 0x5159, 0x83BE, 0x515A, 0xB5B3,
+	0x515B, 0x83BF, 0x515C, 0xB6B5, 0x515D, 0x83C0, 0x515E, 0x83C1,
+	0x515F, 0x83C2, 0x5160, 0x83C3, 0x5161, 0x83C4, 0x5162, 0xBEA4,
+	0x5163, 0x83C5, 0x5164, 0x83C6, 0x5165, 0xC8EB, 0x5166, 0x83C7,
+	0x5167, 0x83C8, 0x5168, 0xC8AB, 0x5169, 0x83C9, 0x516A, 0x83CA,
+	0x516B, 0xB0CB, 0x516C, 0xB9AB, 0x516D, 0xC1F9, 0x516E, 0xD9E2,
+	0x516F, 0x83CB, 0x5170, 0xC0BC, 0x5171, 0xB9B2, 0x5172, 0x83CC,
+	0x5173, 0xB9D8, 0x5174, 0xD0CB, 0x5175, 0xB1F8, 0x5176, 0xC6E4,
+	0x5177, 0xBEDF, 0x5178, 0xB5E4, 0x5179, 0xD7C8, 0x517A, 0x83CD,
+	0x517B, 0xD1F8, 0x517C, 0xBCE6, 0x517D, 0xCADE, 0x517E, 0x83CE,
+	0x517F, 0x83CF, 0x5180, 0xBCBD, 0x5181, 0xD9E6, 0x5182, 0xD8E7,
+	0x5183, 0x83D0, 0x5184, 0x83D1, 0x5185, 0xC4DA, 0x5186, 0x83D2,
+	0x5187, 0x83D3, 0x5188, 0xB8D4, 0x5189, 0xC8BD, 0x518A, 0x83D4,
+	0x518B, 0x83D5, 0x518C, 0xB2E1, 0x518D, 0xD4D9, 0x518E, 0x83D6,
+	0x518F, 0x83D7, 0x5190, 0x83D8, 0x5191, 0x83D9, 0x5192, 0xC3B0,
+	0x5193, 0x83DA, 0x5194, 0x83DB, 0x5195, 0xC3E1, 0x5196, 0xDAA2,
+	0x5197, 0xC8DF, 0x5198, 0x83DC, 0x5199, 0xD0B4, 0x519A, 0x83DD,
+	0x519B, 0xBEFC, 0x519C, 0xC5A9, 0x519D, 0x83DE, 0x519E, 0x83DF,
+	0x519F, 0x83E0, 0x51A0, 0xB9DA, 0x51A1, 0x83E1, 0x51A2, 0xDAA3,
+	0x51A3, 0x83E2, 0x51A4, 0xD4A9, 0x51A5, 0xDAA4, 0x51A6, 0x83E3,
+	0x51A7, 0x83E4, 0x51A8, 0x83E5, 0x51A9, 0x83E6, 0x51AA, 0x83E7,
+	0x51AB, 0xD9FB, 0x51AC, 0xB6AC, 0x51AD, 0x83E8, 0x51AE, 0x83E9,
+	0x51AF, 0xB7EB, 0x51B0, 0xB1F9, 0x51B1, 0xD9FC, 0x51B2, 0xB3E5,
+	0x51B3, 0xBEF6, 0x51B4, 0x83EA, 0x51B5, 0xBFF6, 0x51B6, 0xD2B1,
+	0x51B7, 0xC0E4, 0x51B8, 0x83EB, 0x51B9, 0x83EC, 0x51BA, 0x83ED,
+	0x51BB, 0xB6B3, 0x51BC, 0xD9FE, 0x51BD, 0xD9FD, 0x51BE, 0x83EE,
+	0x51BF, 0x83EF, 0x51C0, 0xBEBB, 0x51C1, 0x83F0, 0x51C2, 0x83F1,
+	0x51C3, 0x83F2, 0x51C4, 0xC6E0, 0x51C5, 0x83F3, 0x51C6, 0xD7BC,
+	0x51C7, 0xDAA1, 0x51C8, 0x83F4, 0x51C9, 0xC1B9, 0x51CA, 0x83F5,
+	0x51CB, 0xB5F2, 0x51CC, 0xC1E8, 0x51CD, 0x83F6, 0x51CE, 0x83F7,
+	0x51CF, 0xBCF5, 0x51D0, 0x83F8, 0x51D1, 0xB4D5, 0x51D2, 0x83F9,
+	0x51D3, 0x83FA, 0x51D4, 0x83FB, 0x51D5, 0x83FC, 0x51D6, 0x83FD,
+	0x51D7, 0x83FE, 0x51D8, 0x8440, 0x51D9, 0x8441, 0x51DA, 0x8442,
+	0x51DB, 0xC1DD, 0x51DC, 0x8443, 0x51DD, 0xC4FD, 0x51DE, 0x8444,
+	0x51DF, 0x8445, 0x51E0, 0xBCB8, 0x51E1, 0xB7B2, 0x51E2, 0x8446,
+	0x51E3, 0x8447, 0x51E4, 0xB7EF, 0x51E5, 0x8448, 0x51E6, 0x8449,
+	0x51E7, 0x844A, 0x51E8, 0x844B, 0x51E9, 0x844C, 0x51EA, 0x844D,
+	0x51EB, 0xD9EC, 0x51EC, 0x844E, 0x51ED, 0xC6BE, 0x51EE, 0x844F,
+	0x51EF, 0xBFAD, 0x51F0, 0xBBCB, 0x51F1, 0x8450, 0x51F2, 0x8451,
+	0x51F3, 0xB5CA, 0x51F4, 0x8452, 0x51F5, 0xDBC9, 0x51F6, 0xD0D7,
+	0x51F7, 0x8453, 0x51F8, 0xCDB9, 0x51F9, 0xB0BC, 0x51FA, 0xB3F6,
+	0x51FB, 0xBBF7, 0x51FC, 0xDBCA, 0x51FD, 0xBAAF, 0x51FE, 0x8454,
+	0x51FF, 0xD4E4, 0x5200, 0xB5B6, 0x5201, 0xB5F3, 0x5202, 0xD8D6,
+	0x5203, 0xC8D0, 0x5204, 0x8455, 0x5205, 0x8456, 0x5206, 0xB7D6,
+	0x5207, 0xC7D0, 0x5208, 0xD8D7, 0x5209, 0x8457, 0x520A, 0xBFAF,
+	0x520B, 0x8458, 0x520C, 0x8459, 0x520D, 0xDBBB, 0x520E, 0xD8D8,
+	0x520F, 0x845A, 0x5210, 0x845B, 0x5211, 0xD0CC, 0x5212, 0xBBAE,
+	0x5213, 0x845C, 0x5214, 0x845D, 0x5215, 0x845E, 0x5216, 0xEBBE,
+	0x5217, 0xC1D0, 0x5218, 0xC1F5, 0x5219, 0xD4F2, 0x521A, 0xB8D5,
+	0x521B, 0xB4B4, 0x521C, 0x845F, 0x521D, 0xB3F5, 0x521E, 0x8460,
+	0x521F, 0x8461, 0x5220, 0xC9BE, 0x5221, 0x8462, 0x5222, 0x8463,
+	0x5223, 0x8464, 0x5224, 0xC5D0, 0x5225, 0x8465, 0x5226, 0x8466,
+	0x5227, 0x8467, 0x5228, 0xC5D9, 0x5229, 0xC0FB, 0x522A, 0x8468,
+	0x522B, 0xB1F0, 0x522C, 0x8469, 0x522D, 0xD8D9, 0x522E, 0xB9CE,
+	0x522F, 0x846A, 0x5230, 0xB5BD, 0x5231, 0x846B, 0x5232, 0x846C,
+	0x5233, 0xD8DA, 0x5234, 0x846D, 0x5235, 0x846E, 0x5236, 0xD6C6,
+	0x5237, 0xCBA2, 0x5238, 0xC8AF, 0x5239, 0xC9B2, 0x523A, 0xB4CC,
+	0x523B, 0xBFCC, 0x523C, 0x846F, 0x523D, 0xB9F4, 0x523E, 0x8470,
+	0x523F, 0xD8DB, 0x5240, 0xD8DC, 0x5241, 0xB6E7, 0x5242, 0xBCC1,
+	0x5243, 0xCCEA, 0x5244, 0x8471, 0x5245, 0x8472, 0x5246, 0x8473,
+	0x5247, 0x8474, 0x5248, 0x8475, 0x5249, 0x8476, 0x524A, 0xCFF7,
+	0x524B, 0x8477, 0x524C, 0xD8DD, 0x524D, 0xC7B0, 0x524E, 0x8478,
+	0x524F, 0x8479, 0x5250, 0xB9D0, 0x5251, 0xBDA3, 0x5252, 0x847A,
+	0x5253, 0x847B, 0x5254, 0xCCDE, 0x5255, 0x847C, 0x5256, 0xC6CA,
+	0x5257, 0x847D, 0x5258, 0x847E, 0x5259, 0x8480, 0x525A, 0x8481,
+	0x525B, 0x8482, 0x525C, 0xD8E0, 0x525D, 0x8483, 0x525E, 0xD8DE,
+	0x525F, 0x8484, 0x5260, 0x8485, 0x5261, 0xD8DF, 0x5262, 0x8486,
+	0x5263, 0x8487, 0x5264, 0x8488, 0x5265, 0xB0FE, 0x5266, 0x8489,
+	0x5267, 0xBEE7, 0x5268, 0x848A, 0x5269, 0xCAA3, 0x526A, 0xBCF4,
+	0x526B, 0x848B, 0x526C, 0x848C, 0x526D, 0x848D, 0x526E, 0x848E,
+	0x526F, 0xB8B1, 0x5270, 0x848F, 0x5271, 0x8490, 0x5272, 0xB8EE,
+	0x5273, 0x8491, 0x5274, 0x8492, 0x5275, 0x8493, 0x5276, 0x8494,
+	0x5277, 0x8495, 0x5278, 0x8496, 0x5279, 0x8497, 0x527A, 0x8498,
+	0x527B, 0x8499, 0x527C, 0x849A, 0x527D, 0xD8E2, 0x527E, 0x849B,
+	0x527F, 0xBDCB, 0x5280, 0x849C, 0x5281, 0xD8E4, 0x5282, 0xD8E3,
+	0x5283, 0x849D, 0x5284, 0x849E, 0x5285, 0x849F, 0x5286, 0x84A0,
+	0x5287, 0x84A1, 0x5288, 0xC5FC, 0x5289, 0x84A2, 0x528A, 0x84A3,
+	0x528B, 0x84A4, 0x528C, 0x84A5, 0x528D, 0x84A6, 0x528E, 0x84A7,
+	0x528F, 0x84A8, 0x5290, 0xD8E5, 0x5291, 0x84A9, 0x5292, 0x84AA,
+	0x5293, 0xD8E6, 0x5294, 0x84AB, 0x5295, 0x84AC, 0x5296, 0x84AD,
+	0x5297, 0x84AE, 0x5298, 0x84AF, 0x5299, 0x84B0, 0x529A, 0x84B1,
+	0x529B, 0xC1A6, 0x529C, 0x84B2, 0x529D, 0xC8B0, 0x529E, 0xB0EC,
+	0x529F, 0xB9A6, 0x52A0, 0xBCD3, 0x52A1, 0xCEF1, 0x52A2, 0xDBBD,
+	0x52A3, 0xC1D3, 0x52A4, 0x84B3, 0x52A5, 0x84B4, 0x52A6, 0x84B5,
+	0x52A7, 0x84B6, 0x52A8, 0xB6AF, 0x52A9, 0xD6FA, 0x52AA, 0xC5AC,
+	0x52AB, 0xBDD9, 0x52AC, 0xDBBE, 0x52AD, 0xDBBF, 0x52AE, 0x84B7,
+	0x52AF, 0x84B8, 0x52B0, 0x84B9, 0x52B1, 0xC0F8, 0x52B2, 0xBEA2,
+	0x52B3, 0xC0CD, 0x52B4, 0x84BA, 0x52B5, 0x84BB, 0x52B6, 0x84BC,
+	0x52B7, 0x84BD, 0x52B8, 0x84BE, 0x52B9, 0x84BF, 0x52BA, 0x84C0,
+	0x52BB, 0x84C1, 0x52BC, 0x84C2, 0x52BD, 0x84C3, 0x52BE, 0xDBC0,
+	0x52BF, 0xCAC6, 0x52C0, 0x84C4, 0x52C1, 0x84C5, 0x52C2, 0x84C6,
+	0x52C3, 0xB2AA, 0x52C4, 0x84C7, 0x52C5, 0x84C8, 0x52C6, 0x84C9,
+	0x52C7, 0xD3C2, 0x52C8, 0x84CA, 0x52C9, 0xC3E3, 0x52CA, 0x84CB,
+	0x52CB, 0xD1AB, 0x52CC, 0x84CC, 0x52CD, 0x84CD, 0x52CE, 0x84CE,
+	0x52CF, 0x84CF, 0x52D0, 0xDBC2, 0x52D1, 0x84D0, 0x52D2, 0xC0D5,
+	0x52D3, 0x84D1, 0x52D4, 0x84D2, 0x52D5, 0x84D3, 0x52D6, 0xDBC3,
+	0x52D7, 0x84D4, 0x52D8, 0xBFB1, 0x52D9, 0x84D5, 0x52DA, 0x84D6,
+	0x52DB, 0x84D7, 0x52DC, 0x84D8, 0x52DD, 0x84D9, 0x52DE, 0x84DA,
+	0x52DF, 0xC4BC, 0x52E0, 0x84DB, 0x52E1, 0x84DC, 0x52E2, 0x84DD,
+	0x52E3, 0x84DE, 0x52E4, 0xC7DA, 0x52E5, 0x84DF, 0x52E6, 0x84E0,
+	0x52E7, 0x84E1, 0x52E8, 0x84E2, 0x52E9, 0x84E3, 0x52EA, 0x84E4,
+	0x52EB, 0x84E5, 0x52EC, 0x84E6, 0x52ED, 0x84E7, 0x52EE, 0x84E8,
+	0x52EF, 0x84E9, 0x52F0, 0xDBC4, 0x52F1, 0x84EA, 0x52F2, 0x84EB,
+	0x52F3, 0x84EC, 0x52F4, 0x84ED, 0x52F5, 0x84EE, 0x52F6, 0x84EF,
+	0x52F7, 0x84F0, 0x52F8, 0x84F1, 0x52F9, 0xD9E8, 0x52FA, 0xC9D7,
+	0x52FB, 0x84F2, 0x52FC, 0x84F3, 0x52FD, 0x84F4, 0x52FE, 0xB9B4,
+	0x52FF, 0xCEF0, 0x5300, 0xD4C8, 0x5301, 0x84F5, 0x5302, 0x84F6,
+	0x5303, 0x84F7, 0x5304, 0x84F8, 0x5305, 0xB0FC, 0x5306, 0xB4D2,
+	0x5307, 0x84F9, 0x5308, 0xD0D9, 0x5309, 0x84FA, 0x530A, 0x84FB,
+	0x530B, 0x84FC, 0x530C, 0x84FD, 0x530D, 0xD9E9, 0x530E, 0x84FE,
+	0x530F, 0xDECB, 0x5310, 0xD9EB, 0x5311, 0x8540, 0x5312, 0x8541,
+	0x5313, 0x8542, 0x5314, 0x8543, 0x5315, 0xD8B0, 0x5316, 0xBBAF,
+	0x5317, 0xB1B1, 0x5318, 0x8544, 0x5319, 0xB3D7, 0x531A, 0xD8CE,
+	0x531B, 0x8545, 0x531C, 0x8546, 0x531D, 0xD4D1, 0x531E, 0x8547,
+	0x531F, 0x8548, 0x5320, 0xBDB3, 0x5321, 0xBFEF, 0x5322, 0x8549,
+	0x5323, 0xCFBB, 0x5324, 0x854A, 0x5325, 0x854B, 0x5326, 0xD8D0,
+	0x5327, 0x854C, 0x5328, 0x854D, 0x5329, 0x854E, 0x532A, 0xB7CB,
+	0x532B, 0x854F, 0x532C, 0x8550, 0x532D, 0x8551, 0x532E, 0xD8D1,
+	0x532F, 0x8552, 0x5330, 0x8553, 0x5331, 0x8554, 0x5332, 0x8555,
+	0x5333, 0x8556, 0x5334, 0x8557, 0x5335, 0x8558, 0x5336, 0x8559,
+	0x5337, 0x855A, 0x5338, 0x855B, 0x5339, 0xC6A5, 0x533A, 0xC7F8,
+	0x533B, 0xD2BD, 0x533C, 0x855C, 0x533D, 0x855D, 0x533E, 0xD8D2,
+	0x533F, 0xC4E4, 0x5340, 0x855E, 0x5341, 0xCAAE, 0x5342, 0x855F,
+	0x5343, 0xC7A7, 0x5344, 0x8560, 0x5345, 0xD8A6, 0x5346, 0x8561,
+	0x5347, 0xC9FD, 0x5348, 0xCEE7, 0x5349, 0xBBDC, 0x534A, 0xB0EB,
+	0x534B, 0x8562, 0x534C, 0x8563, 0x534D, 0x8564, 0x534E, 0xBBAA,
+	0x534F, 0xD0AD, 0x5350, 0x8565, 0x5351, 0xB1B0, 0x5352, 0xD7E4,
+	0x5353, 0xD7BF, 0x5354, 0x8566, 0x5355, 0xB5A5, 0x5356, 0xC2F4,
+	0x5357, 0xC4CF, 0x5358, 0x8567, 0x5359, 0x8568, 0x535A, 0xB2A9,
+	0x535B, 0x8569, 0x535C, 0xB2B7, 0x535D, 0x856A, 0x535E, 0xB1E5,
+	0x535F, 0xDFB2, 0x5360, 0xD5BC, 0x5361, 0xBFA8, 0x5362, 0xC2AC,
+	0x5363, 0xD8D5, 0x5364, 0xC2B1, 0x5365, 0x856B, 0x5366, 0xD8D4,
+	0x5367, 0xCED4, 0x5368, 0x856C, 0x5369, 0xDAE0, 0x536A, 0x856D,
+	0x536B, 0xCEC0, 0x536C, 0x856E, 0x536D, 0x856F, 0x536E, 0xD8B4,
+	0x536F, 0xC3AE, 0x5370, 0xD3A1, 0x5371, 0xCEA3, 0x5372, 0x8570,
+	0x5373, 0xBCB4, 0x5374, 0xC8B4, 0x5375, 0xC2D1, 0x5376, 0x8571,
+	0x5377, 0xBEED, 0x5378, 0xD0B6, 0x5379, 0x8572, 0x537A, 0xDAE1,
+	0x537B, 0x8573, 0x537C, 0x8574, 0x537D, 0x8575, 0x537E, 0x8576,
+	0x537F, 0xC7E4, 0x5380, 0x8577, 0x5381, 0x8578, 0x5382, 0xB3A7,
+	0x5383, 0x8579, 0x5384, 0xB6F2, 0x5385, 0xCCFC, 0x5386, 0xC0FA,
+	0x5387, 0x857A, 0x5388, 0x857B, 0x5389, 0xC0F7, 0x538A, 0x857C,
+	0x538B, 0xD1B9, 0x538C, 0xD1E1, 0x538D, 0xD8C7, 0x538E, 0x857D,
+	0x538F, 0x857E, 0x5390, 0x8580, 0x5391, 0x8581, 0x5392, 0x8582,
+	0x5393, 0x8583, 0x5394, 0x8584, 0x5395, 0xB2DE, 0x5396, 0x8585,
+	0x5397, 0x8586, 0x5398, 0xC0E5, 0x5399, 0x8587, 0x539A, 0xBAF1,
+	0x539B, 0x8588, 0x539C, 0x8589, 0x539D, 0xD8C8, 0x539E, 0x858A,
+	0x539F, 0xD4AD, 0x53A0, 0x858B, 0x53A1, 0x858C, 0x53A2, 0xCFE1,
+	0x53A3, 0xD8C9, 0x53A4, 0x858D, 0x53A5, 0xD8CA, 0x53A6, 0xCFC3,
+	0x53A7, 0x858E, 0x53A8, 0xB3F8, 0x53A9, 0xBEC7, 0x53AA, 0x858F,
+	0x53AB, 0x8590, 0x53AC, 0x8591, 0x53AD, 0x8592, 0x53AE, 0xD8CB,
+	0x53AF, 0x8593, 0x53B0, 0x8594, 0x53B1, 0x8595, 0x53B2, 0x8596,
+	0x53B3, 0x8597, 0x53B4, 0x8598, 0x53B5, 0x8599, 0x53B6, 0xDBCC,
+	0x53B7, 0x859A, 0x53B8, 0x859B, 0x53B9, 0x859C, 0x53BA, 0x859D,
+	0x53BB, 0xC8A5, 0x53BC, 0x859E, 0x53BD, 0x859F, 0x53BE, 0x85A0,
+	0x53BF, 0xCFD8, 0x53C0, 0x85A1, 0x53C1, 0xC8FE, 0x53C2, 0xB2CE,
+	0x53C3, 0x85A2, 0x53C4, 0x85A3, 0x53C5, 0x85A4, 0x53C6, 0x85A5,
+	0x53C7, 0x85A6, 0x53C8, 0xD3D6, 0x53C9, 0xB2E6, 0x53CA, 0xBCB0,
+	0x53CB, 0xD3D1, 0x53CC, 0xCBAB, 0x53CD, 0xB7B4, 0x53CE, 0x85A7,
+	0x53CF, 0x85A8, 0x53D0, 0x85A9, 0x53D1, 0xB7A2, 0x53D2, 0x85AA,
+	0x53D3, 0x85AB, 0x53D4, 0xCAE5, 0x53D5, 0x85AC, 0x53D6, 0xC8A1,
+	0x53D7, 0xCADC, 0x53D8, 0xB1E4, 0x53D9, 0xD0F0, 0x53DA, 0x85AD,
+	0x53DB, 0xC5D1, 0x53DC, 0x85AE, 0x53DD, 0x85AF, 0x53DE, 0x85B0,
+	0x53DF, 0xDBC5, 0x53E0, 0xB5FE, 0x53E1, 0x85B1, 0x53E2, 0x85B2,
+	0x53E3, 0xBFDA, 0x53E4, 0xB9C5, 0x53E5, 0xBEE4, 0x53E6, 0xC1ED,
+	0x53E7, 0x85B3, 0x53E8, 0xDFB6, 0x53E9, 0xDFB5, 0x53EA, 0xD6BB,
+	0x53EB, 0xBDD0, 0x53EC, 0xD5D9, 0x53ED, 0xB0C8, 0x53EE, 0xB6A3,
+	0x53EF, 0xBFC9, 0x53F0, 0xCCA8, 0x53F1, 0xDFB3, 0x53F2, 0xCAB7,
+	0x53F3, 0xD3D2, 0x53F4, 0x85B4, 0x53F5, 0xD8CF, 0x53F6, 0xD2B6,
+	0x53F7, 0xBAC5, 0x53F8, 0xCBBE, 0x53F9, 0xCCBE, 0x53FA, 0x85B5,
+	0x53FB, 0xDFB7, 0x53FC, 0xB5F0, 0x53FD, 0xDFB4, 0x53FE, 0x85B6,
+	0x53FF, 0x85B7, 0x5400, 0x85B8, 0x5401, 0xD3F5, 0x5402, 0x85B9,
+	0x5403, 0xB3D4, 0x5404, 0xB8F7, 0x5405, 0x85BA, 0x5406, 0xDFBA,
+	0x5407, 0x85BB, 0x5408, 0xBACF, 0x5409, 0xBCAA, 0x540A, 0xB5F5,
+	0x540B, 0x85BC, 0x540C, 0xCDAC, 0x540D, 0xC3FB, 0x540E, 0xBAF3,
+	0x540F, 0xC0F4, 0x5410, 0xCDC2, 0x5411, 0xCFF2, 0x5412, 0xDFB8,
+	0x5413, 0xCFC5, 0x5414, 0x85BD, 0x5415, 0xC2C0, 0x5416, 0xDFB9,
+	0x5417, 0xC2F0, 0x5418, 0x85BE, 0x5419, 0x85BF, 0x541A, 0x85C0,
+	0x541B, 0xBEFD, 0x541C, 0x85C1, 0x541D, 0xC1DF, 0x541E, 0xCDCC,
+	0x541F, 0xD2F7, 0x5420, 0xB7CD, 0x5421, 0xDFC1, 0x5422, 0x85C2,
+	0x5423, 0xDFC4, 0x5424, 0x85C3, 0x5425, 0x85C4, 0x5426, 0xB7F1,
+	0x5427, 0xB0C9, 0x5428, 0xB6D6, 0x5429, 0xB7D4, 0x542A, 0x85C5,
+	0x542B, 0xBAAC, 0x542C, 0xCCFD, 0x542D, 0xBFD4, 0x542E, 0xCBB1,
+	0x542F, 0xC6F4, 0x5430, 0x85C6, 0x5431, 0xD6A8, 0x5432, 0xDFC5,
+	0x5433, 0x85C7, 0x5434, 0xCEE2, 0x5435, 0xB3B3, 0x5436, 0x85C8,
+	0x5437, 0x85C9, 0x5438, 0xCEFC, 0x5439, 0xB4B5, 0x543A, 0x85CA,
+	0x543B, 0xCEC7, 0x543C, 0xBAF0, 0x543D, 0x85CB, 0x543E, 0xCEE1,
+	0x543F, 0x85CC, 0x5440, 0xD1BD, 0x5441, 0x85CD, 0x5442, 0x85CE,
+	0x5443, 0xDFC0, 0x5444, 0x85CF, 0x5445, 0x85D0, 0x5446, 0xB4F4,
+	0x5447, 0x85D1, 0x5448, 0xB3CA, 0x5449, 0x85D2, 0x544A, 0xB8E6,
+	0x544B, 0xDFBB, 0x544C, 0x85D3, 0x544D, 0x85D4, 0x544E, 0x85D5,
+	0x544F, 0x85D6, 0x5450, 0xC4C5, 0x5451, 0x85D7, 0x5452, 0xDFBC,
+	0x5453, 0xDFBD, 0x5454, 0xDFBE, 0x5455, 0xC5BB, 0x5456, 0xDFBF,
+	0x5457, 0xDFC2, 0x5458, 0xD4B1, 0x5459, 0xDFC3, 0x545A, 0x85D8,
+	0x545B, 0xC7BA, 0x545C, 0xCED8, 0x545D, 0x85D9, 0x545E, 0x85DA,
+	0x545F, 0x85DB, 0x5460, 0x85DC, 0x5461, 0x85DD, 0x5462, 0xC4D8,
+	0x5463, 0x85DE, 0x5464, 0xDFCA, 0x5465, 0x85DF, 0x5466, 0xDFCF,
+	0x5467, 0x85E0, 0x5468, 0xD6DC, 0x5469, 0x85E1, 0x546A, 0x85E2,
+	0x546B, 0x85E3, 0x546C, 0x85E4, 0x546D, 0x85E5, 0x546E, 0x85E6,
+	0x546F, 0x85E7, 0x5470, 0x85E8, 0x5471, 0xDFC9, 0x5472, 0xDFDA,
+	0x5473, 0xCEB6, 0x5474, 0x85E9, 0x5475, 0xBAC7, 0x5476, 0xDFCE,
+	0x5477, 0xDFC8, 0x5478, 0xC5DE, 0x5479, 0x85EA, 0x547A, 0x85EB,
+	0x547B, 0xC9EB, 0x547C, 0xBAF4, 0x547D, 0xC3FC, 0x547E, 0x85EC,
+	0x547F, 0x85ED, 0x5480, 0xBED7, 0x5481, 0x85EE, 0x5482, 0xDFC6,
+	0x5483, 0x85EF, 0x5484, 0xDFCD, 0x5485, 0x85F0, 0x5486, 0xC5D8,
+	0x5487, 0x85F1, 0x5488, 0x85F2, 0x5489, 0x85F3, 0x548A, 0x85F4,
+	0x548B, 0xD5A6, 0x548C, 0xBACD, 0x548D, 0x85F5, 0x548E, 0xBECC,
+	0x548F, 0xD3BD, 0x5490, 0xB8C0, 0x5491, 0x85F6, 0x5492, 0xD6E4,
+	0x5493, 0x85F7, 0x5494, 0xDFC7, 0x5495, 0xB9BE, 0x5496, 0xBFA7,
+	0x5497, 0x85F8, 0x5498, 0x85F9, 0x5499, 0xC1FC, 0x549A, 0xDFCB,
+	0x549B, 0xDFCC, 0x549C, 0x85FA, 0x549D, 0xDFD0, 0x549E, 0x85FB,
+	0x549F, 0x85FC, 0x54A0, 0x85FD, 0x54A1, 0x85FE, 0x54A2, 0x8640,
+	0x54A3, 0xDFDB, 0x54A4, 0xDFE5, 0x54A5, 0x8641, 0x54A6, 0xDFD7,
+	0x54A7, 0xDFD6, 0x54A8, 0xD7C9, 0x54A9, 0xDFE3, 0x54AA, 0xDFE4,
+	0x54AB, 0xE5EB, 0x54AC, 0xD2A7, 0x54AD, 0xDFD2, 0x54AE, 0x8642,
+	0x54AF, 0xBFA9, 0x54B0, 0x8643, 0x54B1, 0xD4DB, 0x54B2, 0x8644,
+	0x54B3, 0xBFC8, 0x54B4, 0xDFD4, 0x54B5, 0x8645, 0x54B6, 0x8646,
+	0x54B7, 0x8647, 0x54B8, 0xCFCC, 0x54B9, 0x8648, 0x54BA, 0x8649,
+	0x54BB, 0xDFDD, 0x54BC, 0x864A, 0x54BD, 0xD1CA, 0x54BE, 0x864B,
+	0x54BF, 0xDFDE, 0x54C0, 0xB0A7, 0x54C1, 0xC6B7, 0x54C2, 0xDFD3,
+	0x54C3, 0x864C, 0x54C4, 0xBAE5, 0x54C5, 0x864D, 0x54C6, 0xB6DF,
+	0x54C7, 0xCDDB, 0x54C8, 0xB9FE, 0x54C9, 0xD4D5, 0x54CA, 0x864E,
+	0x54CB, 0x864F, 0x54CC, 0xDFDF, 0x54CD, 0xCFEC, 0x54CE, 0xB0A5,
+	0x54CF, 0xDFE7, 0x54D0, 0xDFD1, 0x54D1, 0xD1C6, 0x54D2, 0xDFD5,
+	0x54D3, 0xDFD8, 0x54D4, 0xDFD9, 0x54D5, 0xDFDC, 0x54D6, 0x8650,
+	0x54D7, 0xBBA9, 0x54D8, 0x8651, 0x54D9, 0xDFE0, 0x54DA, 0xDFE1,
+	0x54DB, 0x8652, 0x54DC, 0xDFE2, 0x54DD, 0xDFE6, 0x54DE, 0xDFE8,
+	0x54DF, 0xD3B4, 0x54E0, 0x8653, 0x54E1, 0x8654, 0x54E2, 0x8655,
+	0x54E3, 0x8656, 0x54E4, 0x8657, 0x54E5, 0xB8E7, 0x54E6, 0xC5B6,
+	0x54E7, 0xDFEA, 0x54E8, 0xC9DA, 0x54E9, 0xC1A8, 0x54EA, 0xC4C4,
+	0x54EB, 0x8658, 0x54EC, 0x8659, 0x54ED, 0xBFDE, 0x54EE, 0xCFF8,
+	0x54EF, 0x865A, 0x54F0, 0x865B, 0x54F1, 0x865C, 0x54F2, 0xD5DC,
+	0x54F3, 0xDFEE, 0x54F4, 0x865D, 0x54F5, 0x865E, 0x54F6, 0x865F,
+	0x54F7, 0x8660, 0x54F8, 0x8661, 0x54F9, 0x8662, 0x54FA, 0xB2B8,
+	0x54FB, 0x8663, 0x54FC, 0xBADF, 0x54FD, 0xDFEC, 0x54FE, 0x8664,
+	0x54FF, 0xDBC1, 0x5500, 0x8665, 0x5501, 0xD1E4, 0x5502, 0x8666,
+	0x5503, 0x8667, 0x5504, 0x8668, 0x5505, 0x8669, 0x5506, 0xCBF4,
+	0x5507, 0xB4BD, 0x5508, 0x866A, 0x5509, 0xB0A6, 0x550A, 0x866B,
+	0x550B, 0x866C, 0x550C, 0x866D, 0x550D, 0x866E, 0x550E, 0x866F,
+	0x550F, 0xDFF1, 0x5510, 0xCCC6, 0x5511, 0xDFF2, 0x5512, 0x8670,
+	0x5513, 0x8671, 0x5514, 0xDFED, 0x5515, 0x8672, 0x5516, 0x8673,
+	0x5517, 0x8674, 0x5518, 0x8675, 0x5519, 0x8676, 0x551A, 0x8677,
+	0x551B, 0xDFE9, 0x551C, 0x8678, 0x551D, 0x8679, 0x551E, 0x867A,
+	0x551F, 0x867B, 0x5520, 0xDFEB, 0x5521, 0x867C, 0x5522, 0xDFEF,
+	0x5523, 0xDFF0, 0x5524, 0xBBBD, 0x5525, 0x867D, 0x5526, 0x867E,
+	0x5527, 0xDFF3, 0x5528, 0x8680, 0x5529, 0x8681, 0x552A, 0xDFF4,
+	0x552B, 0x8682, 0x552C, 0xBBA3, 0x552D, 0x8683, 0x552E, 0xCADB,
+	0x552F, 0xCEA8, 0x5530, 0xE0A7, 0x5531, 0xB3AA, 0x5532, 0x8684,
+	0x5533, 0xE0A6, 0x5534, 0x8685, 0x5535, 0x8686, 0x5536, 0x8687,
+	0x5537, 0xE0A1, 0x5538, 0x8688, 0x5539, 0x8689, 0x553A, 0x868A,
+	0x553B, 0x868B, 0x553C, 0xDFFE, 0x553D, 0x868C, 0x553E, 0xCDD9,
+	0x553F, 0xDFFC, 0x5540, 0x868D, 0x5541, 0xDFFA, 0x5542, 0x868E,
+	0x5543, 0xBFD0, 0x5544, 0xD7C4, 0x5545, 0x868F, 0x5546, 0xC9CC,
+	0x5547, 0x8690, 0x5548, 0x8691, 0x5549, 0xDFF8, 0x554A, 0xB0A1,
+	0x554B, 0x8692, 0x554C, 0x8693, 0x554D, 0x8694, 0x554E, 0x8695,
+	0x554F, 0x8696, 0x5550, 0xDFFD, 0x5551, 0x8697, 0x5552, 0x8698,
+	0x5553, 0x8699, 0x5554, 0x869A, 0x5555, 0xDFFB, 0x5556, 0xE0A2,
+	0x5557, 0x869B, 0x5558, 0x869C, 0x5559, 0x869D, 0x555A, 0x869E,
+	0x555B, 0x869F, 0x555C, 0xE0A8, 0x555D, 0x86A0, 0x555E, 0x86A1,
+	0x555F, 0x86A2, 0x5560, 0x86A3, 0x5561, 0xB7C8, 0x5562, 0x86A4,
+	0x5563, 0x86A5, 0x5564, 0xC6A1, 0x5565, 0xC9B6, 0x5566, 0xC0B2,
+	0x5567, 0xDFF5, 0x5568, 0x86A6, 0x5569, 0x86A7, 0x556A, 0xC5BE,
+	0x556B, 0x86A8, 0x556C, 0xD8C4, 0x556D, 0xDFF9, 0x556E, 0xC4F6,
+	0x556F, 0x86A9, 0x5570, 0x86AA, 0x5571, 0x86AB, 0x5572, 0x86AC,
+	0x5573, 0x86AD, 0x5574, 0x86AE, 0x5575, 0xE0A3, 0x5576, 0xE0A4,
+	0x5577, 0xE0A5, 0x5578, 0xD0A5, 0x5579, 0x86AF, 0x557A, 0x86B0,
+	0x557B, 0xE0B4, 0x557C, 0xCCE4, 0x557D, 0x86B1, 0x557E, 0xE0B1,
+	0x557F, 0x86B2, 0x5580, 0xBFA6, 0x5581, 0xE0AF, 0x5582, 0xCEB9,
+	0x5583, 0xE0AB, 0x5584, 0xC9C6, 0x5585, 0x86B3, 0x5586, 0x86B4,
+	0x5587, 0xC0AE, 0x5588, 0xE0AE, 0x5589, 0xBAED, 0x558A, 0xBAB0,
+	0x558B, 0xE0A9, 0x558C, 0x86B5, 0x558D, 0x86B6, 0x558E, 0x86B7,
+	0x558F, 0xDFF6, 0x5590, 0x86B8, 0x5591, 0xE0B3, 0x5592, 0x86B9,
+	0x5593, 0x86BA, 0x5594, 0xE0B8, 0x5595, 0x86BB, 0x5596, 0x86BC,
+	0x5597, 0x86BD, 0x5598, 0xB4AD, 0x5599, 0xE0B9, 0x559A, 0x86BE,
+	0x559B, 0x86BF, 0x559C, 0xCFB2, 0x559D, 0xBAC8, 0x559E, 0x86C0,
+	0x559F, 0xE0B0, 0x55A0, 0x86C1, 0x55A1, 0x86C2, 0x55A2, 0x86C3,
+	0x55A3, 0x86C4, 0x55A4, 0x86C5, 0x55A5, 0x86C6, 0x55A6, 0x86C7,
+	0x55A7, 0xD0FA, 0x55A8, 0x86C8, 0x55A9, 0x86C9, 0x55AA, 0x86CA,
+	0x55AB, 0x86CB, 0x55AC, 0x86CC, 0x55AD, 0x86CD, 0x55AE, 0x86CE,
+	0x55AF, 0x86CF, 0x55B0, 0x86D0, 0x55B1, 0xE0AC, 0x55B2, 0x86D1,
+	0x55B3, 0xD4FB, 0x55B4, 0x86D2, 0x55B5, 0xDFF7, 0x55B6, 0x86D3,
+	0x55B7, 0xC5E7, 0x55B8, 0x86D4, 0x55B9, 0xE0AD, 0x55BA, 0x86D5,
+	0x55BB, 0xD3F7, 0x55BC, 0x86D6, 0x55BD, 0xE0B6, 0x55BE, 0xE0B7,
+	0x55BF, 0x86D7, 0x55C0, 0x86D8, 0x55C1, 0x86D9, 0x55C2, 0x86DA,
+	0x55C3, 0x86DB, 0x55C4, 0xE0C4, 0x55C5, 0xD0E1, 0x55C6, 0x86DC,
+	0x55C7, 0x86DD, 0x55C8, 0x86DE, 0x55C9, 0xE0BC, 0x55CA, 0x86DF,
+	0x55CB, 0x86E0, 0x55CC, 0xE0C9, 0x55CD, 0xE0CA, 0x55CE, 0x86E1,
+	0x55CF, 0x86E2, 0x55D0, 0x86E3, 0x55D1, 0xE0BE, 0x55D2, 0xE0AA,
+	0x55D3, 0xC9A4, 0x55D4, 0xE0C1, 0x55D5, 0x86E4, 0x55D6, 0xE0B2,
+	0x55D7, 0x86E5, 0x55D8, 0x86E6, 0x55D9, 0x86E7, 0x55DA, 0x86E8,
+	0x55DB, 0x86E9, 0x55DC, 0xCAC8, 0x55DD, 0xE0C3, 0x55DE, 0x86EA,
+	0x55DF, 0xE0B5, 0x55E0, 0x86EB, 0x55E1, 0xCECB, 0x55E2, 0x86EC,
+	0x55E3, 0xCBC3, 0x55E4, 0xE0CD, 0x55E5, 0xE0C6, 0x55E6, 0xE0C2,
+	0x55E7, 0x86ED, 0x55E8, 0xE0CB, 0x55E9, 0x86EE, 0x55EA, 0xE0BA,
+	0x55EB, 0xE0BF, 0x55EC, 0xE0C0, 0x55ED, 0x86EF, 0x55EE, 0x86F0,
+	0x55EF, 0xE0C5, 0x55F0, 0x86F1, 0x55F1, 0x86F2, 0x55F2, 0xE0C7,
+	0x55F3, 0xE0C8, 0x55F4, 0x86F3, 0x55F5, 0xE0CC, 0x55F6, 0x86F4,
+	0x55F7, 0xE0BB, 0x55F8, 0x86F5, 0x55F9, 0x86F6, 0x55FA, 0x86F7,
+	0x55FB, 0x86F8, 0x55FC, 0x86F9, 0x55FD, 0xCBD4, 0x55FE, 0xE0D5,
+	0x55FF, 0x86FA, 0x5600, 0xE0D6, 0x5601, 0xE0D2, 0x5602, 0x86FB,
+	0x5603, 0x86FC, 0x5604, 0x86FD, 0x5605, 0x86FE, 0x5606, 0x8740,
+	0x5607, 0x8741, 0x5608, 0xE0D0, 0x5609, 0xBCCE, 0x560A, 0x8742,
+	0x560B, 0x8743, 0x560C, 0xE0D1, 0x560D, 0x8744, 0x560E, 0xB8C2,
+	0x560F, 0xD8C5, 0x5610, 0x8745, 0x5611, 0x8746, 0x5612, 0x8747,
+	0x5613, 0x8748, 0x5614, 0x8749, 0x5615, 0x874A, 0x5616, 0x874B,
+	0x5617, 0x874C, 0x5618, 0xD0EA, 0x5619, 0x874D, 0x561A, 0x874E,
+	0x561B, 0xC2EF, 0x561C, 0x874F, 0x561D, 0x8750, 0x561E, 0xE0CF,
+	0x561F, 0xE0BD, 0x5620, 0x8751, 0x5621, 0x8752, 0x5622, 0x8753,
+	0x5623, 0xE0D4, 0x5624, 0xE0D3, 0x5625, 0x8754, 0x5626, 0x8755,
+	0x5627, 0xE0D7, 0x5628, 0x8756, 0x5629, 0x8757, 0x562A, 0x8758,
+	0x562B, 0x8759, 0x562C, 0xE0DC, 0x562D, 0xE0D8, 0x562E, 0x875A,
+	0x562F, 0x875B, 0x5630, 0x875C, 0x5631, 0xD6F6, 0x5632, 0xB3B0,
+	0x5633, 0x875D, 0x5634, 0xD7EC, 0x5635, 0x875E, 0x5636, 0xCBBB,
+	0x5637, 0x875F, 0x5638, 0x8760, 0x5639, 0xE0DA, 0x563A, 0x8761,
+	0x563B, 0xCEFB, 0x563C, 0x8762, 0x563D, 0x8763, 0x563E, 0x8764,
+	0x563F, 0xBAD9, 0x5640, 0x8765, 0x5641, 0x8766, 0x5642, 0x8767,
+	0x5643, 0x8768, 0x5644, 0x8769, 0x5645, 0x876A, 0x5646, 0x876B,
+	0x5647, 0x876C, 0x5648, 0x876D, 0x5649, 0x876E, 0x564A, 0x876F,
+	0x564B, 0x8770, 0x564C, 0xE0E1, 0x564D, 0xE0DD, 0x564E, 0xD2AD,
+	0x564F, 0x8771, 0x5650, 0x8772, 0x5651, 0x8773, 0x5652, 0x8774,
+	0x5653, 0x8775, 0x5654, 0xE0E2, 0x5655, 0x8776, 0x5656, 0x8777,
+	0x5657, 0xE0DB, 0x5658, 0xE0D9, 0x5659, 0xE0DF, 0x565A, 0x8778,
+	0x565B, 0x8779, 0x565C, 0xE0E0, 0x565D, 0x877A, 0x565E, 0x877B,
+	0x565F, 0x877C, 0x5660, 0x877D, 0x5661, 0x877E, 0x5662, 0xE0DE,
+	0x5663, 0x8780, 0x5664, 0xE0E4, 0x5665, 0x8781, 0x5666, 0x8782,
+	0x5667, 0x8783, 0x5668, 0xC6F7, 0x5669, 0xD8AC, 0x566A, 0xD4EB,
+	0x566B, 0xE0E6, 0x566C, 0xCAC9, 0x566D, 0x8784, 0x566E, 0x8785,
+	0x566F, 0x8786, 0x5670, 0x8787, 0x5671, 0xE0E5, 0x5672, 0x8788,
+	0x5673, 0x8789, 0x5674, 0x878A, 0x5675, 0x878B, 0x5676, 0xB8C1,
+	0x5677, 0x878C, 0x5678, 0x878D, 0x5679, 0x878E, 0x567A, 0x878F,
+	0x567B, 0xE0E7, 0x567C, 0xE0E8, 0x567D, 0x8790, 0x567E, 0x8791,
+	0x567F, 0x8792, 0x5680, 0x8793, 0x5681, 0x8794, 0x5682, 0x8795,
+	0x5683, 0x8796, 0x5684, 0x8797, 0x5685, 0xE0E9, 0x5686, 0xE0E3,
+	0x5687, 0x8798, 0x5688, 0x8799, 0x5689, 0x879A, 0x568A, 0x879B,
+	0x568B, 0x879C, 0x568C, 0x879D, 0x568D, 0x879E, 0x568E, 0xBABF,
+	0x568F, 0xCCE7, 0x5690, 0x879F, 0x5691, 0x87A0, 0x5692, 0x87A1,
+	0x5693, 0xE0EA, 0x5694, 0x87A2, 0x5695, 0x87A3, 0x5696, 0x87A4,
+	0x5697, 0x87A5, 0x5698, 0x87A6, 0x5699, 0x87A7, 0x569A, 0x87A8,
+	0x569B, 0x87A9, 0x569C, 0x87AA, 0x569D, 0x87AB, 0x569E, 0x87AC,
+	0x569F, 0x87AD, 0x56A0, 0x87AE, 0x56A1, 0x87AF, 0x56A2, 0x87B0,
+	0x56A3, 0xCFF9, 0x56A4, 0x87B1, 0x56A5, 0x87B2, 0x56A6, 0x87B3,
+	0x56A7, 0x87B4, 0x56A8, 0x87B5, 0x56A9, 0x87B6, 0x56AA, 0x87B7,
+	0x56AB, 0x87B8, 0x56AC, 0x87B9, 0x56AD, 0x87BA, 0x56AE, 0x87BB,
+	0x56AF, 0xE0EB, 0x56B0, 0x87BC, 0x56B1, 0x87BD, 0x56B2, 0x87BE,
+	0x56B3, 0x87BF, 0x56B4, 0x87C0, 0x56B5, 0x87C1, 0x56B6, 0x87C2,
+	0x56B7, 0xC8C2, 0x56B8, 0x87C3, 0x56B9, 0x87C4, 0x56BA, 0x87C5,
+	0x56BB, 0x87C6, 0x56BC, 0xBDC0, 0x56BD, 0x87C7, 0x56BE, 0x87C8,
+	0x56BF, 0x87C9, 0x56C0, 0x87CA, 0x56C1, 0x87CB, 0x56C2, 0x87CC,
+	0x56C3, 0x87CD, 0x56C4, 0x87CE, 0x56C5, 0x87CF, 0x56C6, 0x87D0,
+	0x56C7, 0x87D1, 0x56C8, 0x87D2, 0x56C9, 0x87D3, 0x56CA, 0xC4D2,
+	0x56CB, 0x87D4, 0x56CC, 0x87D5, 0x56CD, 0x87D6, 0x56CE, 0x87D7,
+	0x56CF, 0x87D8, 0x56D0, 0x87D9, 0x56D1, 0x87DA, 0x56D2, 0x87DB,
+	0x56D3, 0x87DC, 0x56D4, 0xE0EC, 0x56D5, 0x87DD, 0x56D6, 0x87DE,
+	0x56D7, 0xE0ED, 0x56D8, 0x87DF, 0x56D9, 0x87E0, 0x56DA, 0xC7F4,
+	0x56DB, 0xCBC4, 0x56DC, 0x87E1, 0x56DD, 0xE0EE, 0x56DE, 0xBBD8,
+	0x56DF, 0xD8B6, 0x56E0, 0xD2F2, 0x56E1, 0xE0EF, 0x56E2, 0xCDC5,
+	0x56E3, 0x87E2, 0x56E4, 0xB6DA, 0x56E5, 0x87E3, 0x56E6, 0x87E4,
+	0x56E7, 0x87E5, 0x56E8, 0x87E6, 0x56E9, 0x87E7, 0x56EA, 0x87E8,
+	0x56EB, 0xE0F1, 0x56EC, 0x87E9, 0x56ED, 0xD4B0, 0x56EE, 0x87EA,
+	0x56EF, 0x87EB, 0x56F0, 0xC0A7, 0x56F1, 0xB4D1, 0x56F2, 0x87EC,
+	0x56F3, 0x87ED, 0x56F4, 0xCEA7, 0x56F5, 0xE0F0, 0x56F6, 0x87EE,
+	0x56F7, 0x87EF, 0x56F8, 0x87F0, 0x56F9, 0xE0F2, 0x56FA, 0xB9CC,
+	0x56FB, 0x87F1, 0x56FC, 0x87F2, 0x56FD, 0xB9FA, 0x56FE, 0xCDBC,
+	0x56FF, 0xE0F3, 0x5700, 0x87F3, 0x5701, 0x87F4, 0x5702, 0x87F5,
+	0x5703, 0xC6D4, 0x5704, 0xE0F4, 0x5705, 0x87F6, 0x5706, 0xD4B2,
+	0x5707, 0x87F7, 0x5708, 0xC8A6, 0x5709, 0xE0F6, 0x570A, 0xE0F5,
+	0x570B, 0x87F8, 0x570C, 0x87F9, 0x570D, 0x87FA, 0x570E, 0x87FB,
+	0x570F, 0x87FC, 0x5710, 0x87FD, 0x5711, 0x87FE, 0x5712, 0x8840,
+	0x5713, 0x8841, 0x5714, 0x8842, 0x5715, 0x8843, 0x5716, 0x8844,
+	0x5717, 0x8845, 0x5718, 0x8846, 0x5719, 0x8847, 0x571A, 0x8848,
+	0x571B, 0x8849, 0x571C, 0xE0F7, 0x571D, 0x884A, 0x571E, 0x884B,
+	0x571F, 0xCDC1, 0x5720, 0x884C, 0x5721, 0x884D, 0x5722, 0x884E,
+	0x5723, 0xCAA5, 0x5724, 0x884F, 0x5725, 0x8850, 0x5726, 0x8851,
+	0x5727, 0x8852, 0x5728, 0xD4DA, 0x5729, 0xDBD7, 0x572A, 0xDBD9,
+	0x572B, 0x8853, 0x572C, 0xDBD8, 0x572D, 0xB9E7, 0x572E, 0xDBDC,
+	0x572F, 0xDBDD, 0x5730, 0xB5D8, 0x5731, 0x8854, 0x5732, 0x8855,
+	0x5733, 0xDBDA, 0x5734, 0x8856, 0x5735, 0x8857, 0x5736, 0x8858,
+	0x5737, 0x8859, 0x5738, 0x885A, 0x5739, 0xDBDB, 0x573A, 0xB3A1,
+	0x573B, 0xDBDF, 0x573C, 0x885B, 0x573D, 0x885C, 0x573E, 0xBBF8,
+	0x573F, 0x885D, 0x5740, 0xD6B7, 0x5741, 0x885E, 0x5742, 0xDBE0,
+	0x5743, 0x885F, 0x5744, 0x8860, 0x5745, 0x8861, 0x5746, 0x8862,
+	0x5747, 0xBEF9, 0x5748, 0x8863, 0x5749, 0x8864, 0x574A, 0xB7BB,
+	0x574B, 0x8865, 0x574C, 0xDBD0, 0x574D, 0xCCAE, 0x574E, 0xBFB2,
+	0x574F, 0xBBB5, 0x5750, 0xD7F8, 0x5751, 0xBFD3, 0x5752, 0x8866,
+	0x5753, 0x8867, 0x5754, 0x8868, 0x5755, 0x8869, 0x5756, 0x886A,
+	0x5757, 0xBFE9, 0x5758, 0x886B, 0x5759, 0x886C, 0x575A, 0xBCE1,
+	0x575B, 0xCCB3, 0x575C, 0xDBDE, 0x575D, 0xB0D3, 0x575E, 0xCEEB,
+	0x575F, 0xB7D8, 0x5760, 0xD7B9, 0x5761, 0xC6C2, 0x5762, 0x886D,
+	0x5763, 0x886E, 0x5764, 0xC0A4, 0x5765, 0x886F, 0x5766, 0xCCB9,
+	0x5767, 0x8870, 0x5768, 0xDBE7, 0x5769, 0xDBE1, 0x576A, 0xC6BA,
+	0x576B, 0xDBE3, 0x576C, 0x8871, 0x576D, 0xDBE8, 0x576E, 0x8872,
+	0x576F, 0xC5F7, 0x5770, 0x8873, 0x5771, 0x8874, 0x5772, 0x8875,
+	0x5773, 0xDBEA, 0x5774, 0x8876, 0x5775, 0x8877, 0x5776, 0xDBE9,
+	0x5777, 0xBFC0, 0x5778, 0x8878, 0x5779, 0x8879, 0x577A, 0x887A,
+	0x577B, 0xDBE6, 0x577C, 0xDBE5, 0x577D, 0x887B, 0x577E, 0x887C,
+	0x577F, 0x887D, 0x5780, 0x887E, 0x5781, 0x8880, 0x5782, 0xB4B9,
+	0x5783, 0xC0AC, 0x5784, 0xC2A2, 0x5785, 0xDBE2, 0x5786, 0xDBE4,
+	0x5787, 0x8881, 0x5788, 0x8882, 0x5789, 0x8883, 0x578A, 0x8884,
+	0x578B, 0xD0CD, 0x578C, 0xDBED, 0x578D, 0x8885, 0x578E, 0x8886,
+	0x578F, 0x8887, 0x5790, 0x8888, 0x5791, 0x8889, 0x5792, 0xC0DD,
+	0x5793, 0xDBF2, 0x5794, 0x888A, 0x5795, 0x888B, 0x5796, 0x888C,
+	0x5797, 0x888D, 0x5798, 0x888E, 0x5799, 0x888F, 0x579A, 0x8890,
+	0x579B, 0xB6E2, 0x579C, 0x8891, 0x579D, 0x8892, 0x579E, 0x8893,
+	0x579F, 0x8894, 0x57A0, 0xDBF3, 0x57A1, 0xDBD2, 0x57A2, 0xB9B8,
+	0x57A3, 0xD4AB, 0x57A4, 0xDBEC, 0x57A5, 0x8895, 0x57A6, 0xBFD1,
+	0x57A7, 0xDBF0, 0x57A8, 0x8896, 0x57A9, 0xDBD1, 0x57AA, 0x8897,
+	0x57AB, 0xB5E6, 0x57AC, 0x8898, 0x57AD, 0xDBEB, 0x57AE, 0xBFE5,
+	0x57AF, 0x8899, 0x57B0, 0x889A, 0x57B1, 0x889B, 0x57B2, 0xDBEE,
+	0x57B3, 0x889C, 0x57B4, 0xDBF1, 0x57B5, 0x889D, 0x57B6, 0x889E,
+	0x57B7, 0x889F, 0x57B8, 0xDBF9, 0x57B9, 0x88A0, 0x57BA, 0x88A1,
+	0x57BB, 0x88A2, 0x57BC, 0x88A3, 0x57BD, 0x88A4, 0x57BE, 0x88A5,
+	0x57BF, 0x88A6, 0x57C0, 0x88A7, 0x57C1, 0x88A8, 0x57C2, 0xB9A1,
+	0x57C3, 0xB0A3, 0x57C4, 0x88A9, 0x57C5, 0x88AA, 0x57C6, 0x88AB,
+	0x57C7, 0x88AC, 0x57C8, 0x88AD, 0x57C9, 0x88AE, 0x57CA, 0x88AF,
+	0x57CB, 0xC2F1, 0x57CC, 0x88B0, 0x57CD, 0x88B1, 0x57CE, 0xB3C7,
+	0x57CF, 0xDBEF, 0x57D0, 0x88B2, 0x57D1, 0x88B3, 0x57D2, 0xDBF8,
+	0x57D3, 0x88B4, 0x57D4, 0xC6D2, 0x57D5, 0xDBF4, 0x57D6, 0x88B5,
+	0x57D7, 0x88B6, 0x57D8, 0xDBF5, 0x57D9, 0xDBF7, 0x57DA, 0xDBF6,
+	0x57DB, 0x88B7, 0x57DC, 0x88B8, 0x57DD, 0xDBFE, 0x57DE, 0x88B9,
+	0x57DF, 0xD3F2, 0x57E0, 0xB2BA, 0x57E1, 0x88BA, 0x57E2, 0x88BB,
+	0x57E3, 0x88BC, 0x57E4, 0xDBFD, 0x57E5, 0x88BD, 0x57E6, 0x88BE,
+	0x57E7, 0x88BF, 0x57E8, 0x88C0, 0x57E9, 0x88C1, 0x57EA, 0x88C2,
+	0x57EB, 0x88C3, 0x57EC, 0x88C4, 0x57ED, 0xDCA4, 0x57EE, 0x88C5,
+	0x57EF, 0xDBFB, 0x57F0, 0x88C6, 0x57F1, 0x88C7, 0x57F2, 0x88C8,
+	0x57F3, 0x88C9, 0x57F4, 0xDBFA, 0x57F5, 0x88CA, 0x57F6, 0x88CB,
+	0x57F7, 0x88CC, 0x57F8, 0xDBFC, 0x57F9, 0xC5E0, 0x57FA, 0xBBF9,
+	0x57FB, 0x88CD, 0x57FC, 0x88CE, 0x57FD, 0xDCA3, 0x57FE, 0x88CF,
+	0x57FF, 0x88D0, 0x5800, 0xDCA5, 0x5801, 0x88D1, 0x5802, 0xCCC3,
+	0x5803, 0x88D2, 0x5804, 0x88D3, 0x5805, 0x88D4, 0x5806, 0xB6D1,
+	0x5807, 0xDDC0, 0x5808, 0x88D5, 0x5809, 0x88D6, 0x580A, 0x88D7,
+	0x580B, 0xDCA1, 0x580C, 0x88D8, 0x580D, 0xDCA2, 0x580E, 0x88D9,
+	0x580F, 0x88DA, 0x5810, 0x88DB, 0x5811, 0xC7B5, 0x5812, 0x88DC,
+	0x5813, 0x88DD, 0x5814, 0x88DE, 0x5815, 0xB6E9, 0x5816, 0x88DF,
+	0x5817, 0x88E0, 0x5818, 0x88E1, 0x5819, 0xDCA7, 0x581A, 0x88E2,
+	0x581B, 0x88E3, 0x581C, 0x88E4, 0x581D, 0x88E5, 0x581E, 0xDCA6,
+	0x581F, 0x88E6, 0x5820, 0xDCA9, 0x5821, 0xB1A4, 0x5822, 0x88E7,
+	0x5823, 0x88E8, 0x5824, 0xB5CC, 0x5825, 0x88E9, 0x5826, 0x88EA,
+	0x5827, 0x88EB, 0x5828, 0x88EC, 0x5829, 0x88ED, 0x582A, 0xBFB0,
+	0x582B, 0x88EE, 0x582C, 0x88EF, 0x582D, 0x88F0, 0x582E, 0x88F1,
+	0x582F, 0x88F2, 0x5830, 0xD1DF, 0x5831, 0x88F3, 0x5832, 0x88F4,
+	0x5833, 0x88F5, 0x5834, 0x88F6, 0x5835, 0xB6C2, 0x5836, 0x88F7,
+	0x5837, 0x88F8, 0x5838, 0x88F9, 0x5839, 0x88FA, 0x583A, 0x88FB,
+	0x583B, 0x88FC, 0x583C, 0x88FD, 0x583D, 0x88FE, 0x583E, 0x8940,
+	0x583F, 0x8941, 0x5840, 0x8942, 0x5841, 0x8943, 0x5842, 0x8944,
+	0x5843, 0x8945, 0x5844, 0xDCA8, 0x5845, 0x8946, 0x5846, 0x8947,
+	0x5847, 0x8948, 0x5848, 0x8949, 0x5849, 0x894A, 0x584A, 0x894B,
+	0x584B, 0x894C, 0x584C, 0xCBFA, 0x584D, 0xEBF3, 0x584E, 0x894D,
+	0x584F, 0x894E, 0x5850, 0x894F, 0x5851, 0xCBDC, 0x5852, 0x8950,
+	0x5853, 0x8951, 0x5854, 0xCBFE, 0x5855, 0x8952, 0x5856, 0x8953,
+	0x5857, 0x8954, 0x5858, 0xCCC1, 0x5859, 0x8955, 0x585A, 0x8956,
+	0x585B, 0x8957, 0x585C, 0x8958, 0x585D, 0x8959, 0x585E, 0xC8FB,
+	0x585F, 0x895A, 0x5860, 0x895B, 0x5861, 0x895C, 0x5862, 0x895D,
+	0x5863, 0x895E, 0x5864, 0x895F, 0x5865, 0xDCAA, 0x5866, 0x8960,
+	0x5867, 0x8961, 0x5868, 0x8962, 0x5869, 0x8963, 0x586A, 0x8964,
+	0x586B, 0xCCEE, 0x586C, 0xDCAB, 0x586D, 0x8965, 0x586E, 0x8966,
+	0x586F, 0x8967, 0x5870, 0x8968, 0x5871, 0x8969, 0x5872, 0x896A,
+	0x5873, 0x896B, 0x5874, 0x896C, 0x5875, 0x896D, 0x5876, 0x896E,
+	0x5877, 0x896F, 0x5878, 0x8970, 0x5879, 0x8971, 0x587A, 0x8972,
+	0x587B, 0x8973, 0x587C, 0x8974, 0x587D, 0x8975, 0x587E, 0xDBD3,
+	0x587F, 0x8976, 0x5880, 0xDCAF, 0x5881, 0xDCAC, 0x5882, 0x8977,
+	0x5883, 0xBEB3, 0x5884, 0x8978, 0x5885, 0xCAFB, 0x5886, 0x8979,
+	0x5887, 0x897A, 0x5888, 0x897B, 0x5889, 0xDCAD, 0x588A, 0x897C,
+	0x588B, 0x897D, 0x588C, 0x897E, 0x588D, 0x8980, 0x588E, 0x8981,
+	0x588F, 0x8982, 0x5890, 0x8983, 0x5891, 0x8984, 0x5892, 0xC9CA,
+	0x5893, 0xC4B9, 0x5894, 0x8985, 0x5895, 0x8986, 0x5896, 0x8987,
+	0x5897, 0x8988, 0x5898, 0x8989, 0x5899, 0xC7BD, 0x589A, 0xDCAE,
+	0x589B, 0x898A, 0x589C, 0x898B, 0x589D, 0x898C, 0x589E, 0xD4F6,
+	0x589F, 0xD0E6, 0x58A0, 0x898D, 0x58A1, 0x898E, 0x58A2, 0x898F,
+	0x58A3, 0x8990, 0x58A4, 0x8991, 0x58A5, 0x8992, 0x58A6, 0x8993,
+	0x58A7, 0x8994, 0x58A8, 0xC4AB, 0x58A9, 0xB6D5, 0x58AA, 0x8995,
+	0x58AB, 0x8996, 0x58AC, 0x8997, 0x58AD, 0x8998, 0x58AE, 0x8999,
+	0x58AF, 0x899A, 0x58B0, 0x899B, 0x58B1, 0x899C, 0x58B2, 0x899D,
+	0x58B3, 0x899E, 0x58B4, 0x899F, 0x58B5, 0x89A0, 0x58B6, 0x89A1,
+	0x58B7, 0x89A2, 0x58B8, 0x89A3, 0x58B9, 0x89A4, 0x58BA, 0x89A5,
+	0x58BB, 0x89A6, 0x58BC, 0xDBD4, 0x58BD, 0x89A7, 0x58BE, 0x89A8,
+	0x58BF, 0x89A9, 0x58C0, 0x89AA, 0x58C1, 0xB1DA, 0x58C2, 0x89AB,
+	0x58C3, 0x89AC, 0x58C4, 0x89AD, 0x58C5, 0xDBD5, 0x58C6, 0x89AE,
+	0x58C7, 0x89AF, 0x58C8, 0x89B0, 0x58C9, 0x89B1, 0x58CA, 0x89B2,
+	0x58CB, 0x89B3, 0x58CC, 0x89B4, 0x58CD, 0x89B5, 0x58CE, 0x89B6,
+	0x58CF, 0x89B7, 0x58D0, 0x89B8, 0x58D1, 0xDBD6, 0x58D2, 0x89B9,
+	0x58D3, 0x89BA, 0x58D4, 0x89BB, 0x58D5, 0xBABE, 0x58D6, 0x89BC,
+	0x58D7, 0x89BD, 0x58D8, 0x89BE, 0x58D9, 0x89BF, 0x58DA, 0x89C0,
+	0x58DB, 0x89C1, 0x58DC, 0x89C2, 0x58DD, 0x89C3, 0x58DE, 0x89C4,
+	0x58DF, 0x89C5, 0x58E0, 0x89C6, 0x58E1, 0x89C7, 0x58E2, 0x89C8,
+	0x58E3, 0x89C9, 0x58E4, 0xC8C0, 0x58E5, 0x89CA, 0x58E6, 0x89CB,
+	0x58E7, 0x89CC, 0x58E8, 0x89CD, 0x58E9, 0x89CE, 0x58EA, 0x89CF,
+	0x58EB, 0xCABF, 0x58EC, 0xC8C9, 0x58ED, 0x89D0, 0x58EE, 0xD7B3,
+	0x58EF, 0x89D1, 0x58F0, 0xC9F9, 0x58F1, 0x89D2, 0x58F2, 0x89D3,
+	0x58F3, 0xBFC7, 0x58F4, 0x89D4, 0x58F5, 0x89D5, 0x58F6, 0xBAF8,
+	0x58F7, 0x89D6, 0x58F8, 0x89D7, 0x58F9, 0xD2BC, 0x58FA, 0x89D8,
+	0x58FB, 0x89D9, 0x58FC, 0x89DA, 0x58FD, 0x89DB, 0x58FE, 0x89DC,
+	0x58FF, 0x89DD, 0x5900, 0x89DE, 0x5901, 0x89DF, 0x5902, 0xE2BA,
+	0x5903, 0x89E0, 0x5904, 0xB4A6, 0x5905, 0x89E1, 0x5906, 0x89E2,
+	0x5907, 0xB1B8, 0x5908, 0x89E3, 0x5909, 0x89E4, 0x590A, 0x89E5,
+	0x590B, 0x89E6, 0x590C, 0x89E7, 0x590D, 0xB8B4, 0x590E, 0x89E8,
+	0x590F, 0xCFC4, 0x5910, 0x89E9, 0x5911, 0x89EA, 0x5912, 0x89EB,
+	0x5913, 0x89EC, 0x5914, 0xD9E7, 0x5915, 0xCFA6, 0x5916, 0xCDE2,
+	0x5917, 0x89ED, 0x5918, 0x89EE, 0x5919, 0xD9ED, 0x591A, 0xB6E0,
+	0x591B, 0x89EF, 0x591C, 0xD2B9, 0x591D, 0x89F0, 0x591E, 0x89F1,
+	0x591F, 0xB9BB, 0x5920, 0x89F2, 0x5921, 0x89F3, 0x5922, 0x89F4,
+	0x5923, 0x89F5, 0x5924, 0xE2B9, 0x5925, 0xE2B7, 0x5926, 0x89F6,
+	0x5927, 0xB4F3, 0x5928, 0x89F7, 0x5929, 0xCCEC, 0x592A, 0xCCAB,
+	0x592B, 0xB7F2, 0x592C, 0x89F8, 0x592D, 0xD8B2, 0x592E, 0xD1EB,
+	0x592F, 0xBABB, 0x5930, 0x89F9, 0x5931, 0xCAA7, 0x5932, 0x89FA,
+	0x5933, 0x89FB, 0x5934, 0xCDB7, 0x5935, 0x89FC, 0x5936, 0x89FD,
+	0x5937, 0xD2C4, 0x5938, 0xBFE4, 0x5939, 0xBCD0, 0x593A, 0xB6E1,
+	0x593B, 0x89FE, 0x593C, 0xDEC5, 0x593D, 0x8A40, 0x593E, 0x8A41,
+	0x593F, 0x8A42, 0x5940, 0x8A43, 0x5941, 0xDEC6, 0x5942, 0xDBBC,
+	0x5943, 0x8A44, 0x5944, 0xD1D9, 0x5945, 0x8A45, 0x5946, 0x8A46,
+	0x5947, 0xC6E6, 0x5948, 0xC4CE, 0x5949, 0xB7EE, 0x594A, 0x8A47,
+	0x594B, 0xB7DC, 0x594C, 0x8A48, 0x594D, 0x8A49, 0x594E, 0xBFFC,
+	0x594F, 0xD7E0, 0x5950, 0x8A4A, 0x5951, 0xC6F5, 0x5952, 0x8A4B,
+	0x5953, 0x8A4C, 0x5954, 0xB1BC, 0x5955, 0xDEC8, 0x5956, 0xBDB1,
+	0x5957, 0xCCD7, 0x5958, 0xDECA, 0x5959, 0x8A4D, 0x595A, 0xDEC9,
+	0x595B, 0x8A4E, 0x595C, 0x8A4F, 0x595D, 0x8A50, 0x595E, 0x8A51,
+	0x595F, 0x8A52, 0x5960, 0xB5EC, 0x5961, 0x8A53, 0x5962, 0xC9DD,
+	0x5963, 0x8A54, 0x5964, 0x8A55, 0x5965, 0xB0C2, 0x5966, 0x8A56,
+	0x5967, 0x8A57, 0x5968, 0x8A58, 0x5969, 0x8A59, 0x596A, 0x8A5A,
+	0x596B, 0x8A5B, 0x596C, 0x8A5C, 0x596D, 0x8A5D, 0x596E, 0x8A5E,
+	0x596F, 0x8A5F, 0x5970, 0x8A60, 0x5971, 0x8A61, 0x5972, 0x8A62,
+	0x5973, 0xC5AE, 0x5974, 0xC5AB, 0x5975, 0x8A63, 0x5976, 0xC4CC,
+	0x5977, 0x8A64, 0x5978, 0xBCE9, 0x5979, 0xCBFD, 0x597A, 0x8A65,
+	0x597B, 0x8A66, 0x597C, 0x8A67, 0x597D, 0xBAC3, 0x597E, 0x8A68,
+	0x597F, 0x8A69, 0x5980, 0x8A6A, 0x5981, 0xE5F9, 0x5982, 0xC8E7,
+	0x5983, 0xE5FA, 0x5984, 0xCDFD, 0x5985, 0x8A6B, 0x5986, 0xD7B1,
+	0x5987, 0xB8BE, 0x5988, 0xC2E8, 0x5989, 0x8A6C, 0x598A, 0xC8D1,
+	0x598B, 0x8A6D, 0x598C, 0x8A6E, 0x598D, 0xE5FB, 0x598E, 0x8A6F,
+	0x598F, 0x8A70, 0x5990, 0x8A71, 0x5991, 0x8A72, 0x5992, 0xB6CA,
+	0x5993, 0xBCCB, 0x5994, 0x8A73, 0x5995, 0x8A74, 0x5996, 0xD1FD,
+	0x5997, 0xE6A1, 0x5998, 0x8A75, 0x5999, 0xC3EE, 0x599A, 0x8A76,
+	0x599B, 0x8A77, 0x599C, 0x8A78, 0x599D, 0x8A79, 0x599E, 0xE6A4,
+	0x599F, 0x8A7A, 0x59A0, 0x8A7B, 0x59A1, 0x8A7C, 0x59A2, 0x8A7D,
+	0x59A3, 0xE5FE, 0x59A4, 0xE6A5, 0x59A5, 0xCDD7, 0x59A6, 0x8A7E,
+	0x59A7, 0x8A80, 0x59A8, 0xB7C1, 0x59A9, 0xE5FC, 0x59AA, 0xE5FD,
+	0x59AB, 0xE6A3, 0x59AC, 0x8A81, 0x59AD, 0x8A82, 0x59AE, 0xC4DD,
+	0x59AF, 0xE6A8, 0x59B0, 0x8A83, 0x59B1, 0x8A84, 0x59B2, 0xE6A7,
+	0x59B3, 0x8A85, 0x59B4, 0x8A86, 0x59B5, 0x8A87, 0x59B6, 0x8A88,
+	0x59B7, 0x8A89, 0x59B8, 0x8A8A, 0x59B9, 0xC3C3, 0x59BA, 0x8A8B,
+	0x59BB, 0xC6DE, 0x59BC, 0x8A8C, 0x59BD, 0x8A8D, 0x59BE, 0xE6AA,
+	0x59BF, 0x8A8E, 0x59C0, 0x8A8F, 0x59C1, 0x8A90, 0x59C2, 0x8A91,
+	0x59C3, 0x8A92, 0x59C4, 0x8A93, 0x59C5, 0x8A94, 0x59C6, 0xC4B7,
+	0x59C7, 0x8A95, 0x59C8, 0x8A96, 0x59C9, 0x8A97, 0x59CA, 0xE6A2,
+	0x59CB, 0xCABC, 0x59CC, 0x8A98, 0x59CD, 0x8A99, 0x59CE, 0x8A9A,
+	0x59CF, 0x8A9B, 0x59D0, 0xBDE3, 0x59D1, 0xB9C3, 0x59D2, 0xE6A6,
+	0x59D3, 0xD0D5, 0x59D4, 0xCEAF, 0x59D5, 0x8A9C, 0x59D6, 0x8A9D,
+	0x59D7, 0xE6A9, 0x59D8, 0xE6B0, 0x59D9, 0x8A9E, 0x59DA, 0xD2A6,
+	0x59DB, 0x8A9F, 0x59DC, 0xBDAA, 0x59DD, 0xE6AD, 0x59DE, 0x8AA0,
+	0x59DF, 0x8AA1, 0x59E0, 0x8AA2, 0x59E1, 0x8AA3, 0x59E2, 0x8AA4,
+	0x59E3, 0xE6AF, 0x59E4, 0x8AA5, 0x59E5, 0xC0D1, 0x59E6, 0x8AA6,
+	0x59E7, 0x8AA7, 0x59E8, 0xD2CC, 0x59E9, 0x8AA8, 0x59EA, 0x8AA9,
+	0x59EB, 0x8AAA, 0x59EC, 0xBCA7, 0x59ED, 0x8AAB, 0x59EE, 0x8AAC,
+	0x59EF, 0x8AAD, 0x59F0, 0x8AAE, 0x59F1, 0x8AAF, 0x59F2, 0x8AB0,
+	0x59F3, 0x8AB1, 0x59F4, 0x8AB2, 0x59F5, 0x8AB3, 0x59F6, 0x8AB4,
+	0x59F7, 0x8AB5, 0x59F8, 0x8AB6, 0x59F9, 0xE6B1, 0x59FA, 0x8AB7,
+	0x59FB, 0xD2F6, 0x59FC, 0x8AB8, 0x59FD, 0x8AB9, 0x59FE, 0x8ABA,
+	0x59FF, 0xD7CB, 0x5A00, 0x8ABB, 0x5A01, 0xCDFE, 0x5A02, 0x8ABC,
+	0x5A03, 0xCDDE, 0x5A04, 0xC2A6, 0x5A05, 0xE6AB, 0x5A06, 0xE6AC,
+	0x5A07, 0xBDBF, 0x5A08, 0xE6AE, 0x5A09, 0xE6B3, 0x5A0A, 0x8ABD,
+	0x5A0B, 0x8ABE, 0x5A0C, 0xE6B2, 0x5A0D, 0x8ABF, 0x5A0E, 0x8AC0,
+	0x5A0F, 0x8AC1, 0x5A10, 0x8AC2, 0x5A11, 0xE6B6, 0x5A12, 0x8AC3,
+	0x5A13, 0xE6B8, 0x5A14, 0x8AC4, 0x5A15, 0x8AC5, 0x5A16, 0x8AC6,
+	0x5A17, 0x8AC7, 0x5A18, 0xC4EF, 0x5A19, 0x8AC8, 0x5A1A, 0x8AC9,
+	0x5A1B, 0x8ACA, 0x5A1C, 0xC4C8, 0x5A1D, 0x8ACB, 0x5A1E, 0x8ACC,
+	0x5A1F, 0xBEEA, 0x5A20, 0xC9EF, 0x5A21, 0x8ACD, 0x5A22, 0x8ACE,
+	0x5A23, 0xE6B7, 0x5A24, 0x8ACF, 0x5A25, 0xB6F0, 0x5A26, 0x8AD0,
+	0x5A27, 0x8AD1, 0x5A28, 0x8AD2, 0x5A29, 0xC3E4, 0x5A2A, 0x8AD3,
+	0x5A2B, 0x8AD4, 0x5A2C, 0x8AD5, 0x5A2D, 0x8AD6, 0x5A2E, 0x8AD7,
+	0x5A2F, 0x8AD8, 0x5A30, 0x8AD9, 0x5A31, 0xD3E9, 0x5A32, 0xE6B4,
+	0x5A33, 0x8ADA, 0x5A34, 0xE6B5, 0x5A35, 0x8ADB, 0x5A36, 0xC8A2,
+	0x5A37, 0x8ADC, 0x5A38, 0x8ADD, 0x5A39, 0x8ADE, 0x5A3A, 0x8ADF,
+	0x5A3B, 0x8AE0, 0x5A3C, 0xE6BD, 0x5A3D, 0x8AE1, 0x5A3E, 0x8AE2,
+	0x5A3F, 0x8AE3, 0x5A40, 0xE6B9, 0x5A41, 0x8AE4, 0x5A42, 0x8AE5,
+	0x5A43, 0x8AE6, 0x5A44, 0x8AE7, 0x5A45, 0x8AE8, 0x5A46, 0xC6C5,
+	0x5A47, 0x8AE9, 0x5A48, 0x8AEA, 0x5A49, 0xCDF1, 0x5A4A, 0xE6BB,
+	0x5A4B, 0x8AEB, 0x5A4C, 0x8AEC, 0x5A4D, 0x8AED, 0x5A4E, 0x8AEE,
+	0x5A4F, 0x8AEF, 0x5A50, 0x8AF0, 0x5A51, 0x8AF1, 0x5A52, 0x8AF2,
+	0x5A53, 0x8AF3, 0x5A54, 0x8AF4, 0x5A55, 0xE6BC, 0x5A56, 0x8AF5,
+	0x5A57, 0x8AF6, 0x5A58, 0x8AF7, 0x5A59, 0x8AF8, 0x5A5A, 0xBBE9,
+	0x5A5B, 0x8AF9, 0x5A5C, 0x8AFA, 0x5A5D, 0x8AFB, 0x5A5E, 0x8AFC,
+	0x5A5F, 0x8AFD, 0x5A60, 0x8AFE, 0x5A61, 0x8B40, 0x5A62, 0xE6BE,
+	0x5A63, 0x8B41, 0x5A64, 0x8B42, 0x5A65, 0x8B43, 0x5A66, 0x8B44,
+	0x5A67, 0xE6BA, 0x5A68, 0x8B45, 0x5A69, 0x8B46, 0x5A6A, 0xC0B7,
+	0x5A6B, 0x8B47, 0x5A6C, 0x8B48, 0x5A6D, 0x8B49, 0x5A6E, 0x8B4A,
+	0x5A6F, 0x8B4B, 0x5A70, 0x8B4C, 0x5A71, 0x8B4D, 0x5A72, 0x8B4E,
+	0x5A73, 0x8B4F, 0x5A74, 0xD3A4, 0x5A75, 0xE6BF, 0x5A76, 0xC9F4,
+	0x5A77, 0xE6C3, 0x5A78, 0x8B50, 0x5A79, 0x8B51, 0x5A7A, 0xE6C4,
+	0x5A7B, 0x8B52, 0x5A7C, 0x8B53, 0x5A7D, 0x8B54, 0x5A7E, 0x8B55,
+	0x5A7F, 0xD0F6, 0x5A80, 0x8B56, 0x5A81, 0x8B57, 0x5A82, 0x8B58,
+	0x5A83, 0x8B59, 0x5A84, 0x8B5A, 0x5A85, 0x8B5B, 0x5A86, 0x8B5C,
+	0x5A87, 0x8B5D, 0x5A88, 0x8B5E, 0x5A89, 0x8B5F, 0x5A8A, 0x8B60,
+	0x5A8B, 0x8B61, 0x5A8C, 0x8B62, 0x5A8D, 0x8B63, 0x5A8E, 0x8B64,
+	0x5A8F, 0x8B65, 0x5A90, 0x8B66, 0x5A91, 0x8B67, 0x5A92, 0xC3BD,
+	0x5A93, 0x8B68, 0x5A94, 0x8B69, 0x5A95, 0x8B6A, 0x5A96, 0x8B6B,
+	0x5A97, 0x8B6C, 0x5A98, 0x8B6D, 0x5A99, 0x8B6E, 0x5A9A, 0xC3C4,
+	0x5A9B, 0xE6C2, 0x5A9C, 0x8B6F, 0x5A9D, 0x8B70, 0x5A9E, 0x8B71,
+	0x5A9F, 0x8B72, 0x5AA0, 0x8B73, 0x5AA1, 0x8B74, 0x5AA2, 0x8B75,
+	0x5AA3, 0x8B76, 0x5AA4, 0x8B77, 0x5AA5, 0x8B78, 0x5AA6, 0x8B79,
+	0x5AA7, 0x8B7A, 0x5AA8, 0x8B7B, 0x5AA9, 0x8B7C, 0x5AAA, 0xE6C1,
+	0x5AAB, 0x8B7D, 0x5AAC, 0x8B7E, 0x5AAD, 0x8B80, 0x5AAE, 0x8B81,
+	0x5AAF, 0x8B82, 0x5AB0, 0x8B83, 0x5AB1, 0x8B84, 0x5AB2, 0xE6C7,
+	0x5AB3, 0xCFB1, 0x5AB4, 0x8B85, 0x5AB5, 0xEBF4, 0x5AB6, 0x8B86,
+	0x5AB7, 0x8B87, 0x5AB8, 0xE6CA, 0x5AB9, 0x8B88, 0x5ABA, 0x8B89,
+	0x5ABB, 0x8B8A, 0x5ABC, 0x8B8B, 0x5ABD, 0x8B8C, 0x5ABE, 0xE6C5,
+	0x5ABF, 0x8B8D, 0x5AC0, 0x8B8E, 0x5AC1, 0xBCDE, 0x5AC2, 0xC9A9,
+	0x5AC3, 0x8B8F, 0x5AC4, 0x8B90, 0x5AC5, 0x8B91, 0x5AC6, 0x8B92,
+	0x5AC7, 0x8B93, 0x5AC8, 0x8B94, 0x5AC9, 0xBCB5, 0x5ACA, 0x8B95,
+	0x5ACB, 0x8B96, 0x5ACC, 0xCFD3, 0x5ACD, 0x8B97, 0x5ACE, 0x8B98,
+	0x5ACF, 0x8B99, 0x5AD0, 0x8B9A, 0x5AD1, 0x8B9B, 0x5AD2, 0xE6C8,
+	0x5AD3, 0x8B9C, 0x5AD4, 0xE6C9, 0x5AD5, 0x8B9D, 0x5AD6, 0xE6CE,
+	0x5AD7, 0x8B9E, 0x5AD8, 0xE6D0, 0x5AD9, 0x8B9F, 0x5ADA, 0x8BA0,
+	0x5ADB, 0x8BA1, 0x5ADC, 0xE6D1, 0x5ADD, 0x8BA2, 0x5ADE, 0x8BA3,
+	0x5ADF, 0x8BA4, 0x5AE0, 0xE6CB, 0x5AE1, 0xB5D5, 0x5AE2, 0x8BA5,
+	0x5AE3, 0xE6CC, 0x5AE4, 0x8BA6, 0x5AE5, 0x8BA7, 0x5AE6, 0xE6CF,
+	0x5AE7, 0x8BA8, 0x5AE8, 0x8BA9, 0x5AE9, 0xC4DB, 0x5AEA, 0x8BAA,
+	0x5AEB, 0xE6C6, 0x5AEC, 0x8BAB, 0x5AED, 0x8BAC, 0x5AEE, 0x8BAD,
+	0x5AEF, 0x8BAE, 0x5AF0, 0x8BAF, 0x5AF1, 0xE6CD, 0x5AF2, 0x8BB0,
+	0x5AF3, 0x8BB1, 0x5AF4, 0x8BB2, 0x5AF5, 0x8BB3, 0x5AF6, 0x8BB4,
+	0x5AF7, 0x8BB5, 0x5AF8, 0x8BB6, 0x5AF9, 0x8BB7, 0x5AFA, 0x8BB8,
+	0x5AFB, 0x8BB9, 0x5AFC, 0x8BBA, 0x5AFD, 0x8BBB, 0x5AFE, 0x8BBC,
+	0x5AFF, 0x8BBD, 0x5B00, 0x8BBE, 0x5B01, 0x8BBF, 0x5B02, 0x8BC0,
+	0x5B03, 0x8BC1, 0x5B04, 0x8BC2, 0x5B05, 0x8BC3, 0x5B06, 0x8BC4,
+	0x5B07, 0x8BC5, 0x5B08, 0x8BC6, 0x5B09, 0xE6D2, 0x5B0A, 0x8BC7,
+	0x5B0B, 0x8BC8, 0x5B0C, 0x8BC9, 0x5B0D, 0x8BCA, 0x5B0E, 0x8BCB,
+	0x5B0F, 0x8BCC, 0x5B10, 0x8BCD, 0x5B11, 0x8BCE, 0x5B12, 0x8BCF,
+	0x5B13, 0x8BD0, 0x5B14, 0x8BD1, 0x5B15, 0x8BD2, 0x5B16, 0xE6D4,
+	0x5B17, 0xE6D3, 0x5B18, 0x8BD3, 0x5B19, 0x8BD4, 0x5B1A, 0x8BD5,
+	0x5B1B, 0x8BD6, 0x5B1C, 0x8BD7, 0x5B1D, 0x8BD8, 0x5B1E, 0x8BD9,
+	0x5B1F, 0x8BDA, 0x5B20, 0x8BDB, 0x5B21, 0x8BDC, 0x5B22, 0x8BDD,
+	0x5B23, 0x8BDE, 0x5B24, 0x8BDF, 0x5B25, 0x8BE0, 0x5B26, 0x8BE1,
+	0x5B27, 0x8BE2, 0x5B28, 0x8BE3, 0x5B29, 0x8BE4, 0x5B2A, 0x8BE5,
+	0x5B2B, 0x8BE6, 0x5B2C, 0x8BE7, 0x5B2D, 0x8BE8, 0x5B2E, 0x8BE9,
+	0x5B2F, 0x8BEA, 0x5B30, 0x8BEB, 0x5B31, 0x8BEC, 0x5B32, 0xE6D5,
+	0x5B33, 0x8BED, 0x5B34, 0xD9F8, 0x5B35, 0x8BEE, 0x5B36, 0x8BEF,
+	0x5B37, 0xE6D6, 0x5B38, 0x8BF0, 0x5B39, 0x8BF1, 0x5B3A, 0x8BF2,
+	0x5B3B, 0x8BF3, 0x5B3C, 0x8BF4, 0x5B3D, 0x8BF5, 0x5B3E, 0x8BF6,
+	0x5B3F, 0x8BF7, 0x5B40, 0xE6D7, 0x5B41, 0x8BF8, 0x5B42, 0x8BF9,
+	0x5B43, 0x8BFA, 0x5B44, 0x8BFB, 0x5B45, 0x8BFC, 0x5B46, 0x8BFD,
+	0x5B47, 0x8BFE, 0x5B48, 0x8C40, 0x5B49, 0x8C41, 0x5B4A, 0x8C42,
+	0x5B4B, 0x8C43, 0x5B4C, 0x8C44, 0x5B4D, 0x8C45, 0x5B4E, 0x8C46,
+	0x5B4F, 0x8C47, 0x5B50, 0xD7D3, 0x5B51, 0xE6DD, 0x5B52, 0x8C48,
+	0x5B53, 0xE6DE, 0x5B54, 0xBFD7, 0x5B55, 0xD4D0, 0x5B56, 0x8C49,
+	0x5B57, 0xD7D6, 0x5B58, 0xB4E6, 0x5B59, 0xCBEF, 0x5B5A, 0xE6DA,
+	0x5B5B, 0xD8C3, 0x5B5C, 0xD7CE, 0x5B5D, 0xD0A2, 0x5B5E, 0x8C4A,
+	0x5B5F, 0xC3CF, 0x5B60, 0x8C4B, 0x5B61, 0x8C4C, 0x5B62, 0xE6DF,
+	0x5B63, 0xBCBE, 0x5B64, 0xB9C2, 0x5B65, 0xE6DB, 0x5B66, 0xD1A7,
+	0x5B67, 0x8C4D, 0x5B68, 0x8C4E, 0x5B69, 0xBAA2, 0x5B6A, 0xC2CF,
+	0x5B6B, 0x8C4F, 0x5B6C, 0xD8AB, 0x5B6D, 0x8C50, 0x5B6E, 0x8C51,
+	0x5B6F, 0x8C52, 0x5B70, 0xCAEB, 0x5B71, 0xE5EE, 0x5B72, 0x8C53,
+	0x5B73, 0xE6DC, 0x5B74, 0x8C54, 0x5B75, 0xB7F5, 0x5B76, 0x8C55,
+	0x5B77, 0x8C56, 0x5B78, 0x8C57, 0x5B79, 0x8C58, 0x5B7A, 0xC8E6,
+	0x5B7B, 0x8C59, 0x5B7C, 0x8C5A, 0x5B7D, 0xC4F5, 0x5B7E, 0x8C5B,
+	0x5B7F, 0x8C5C, 0x5B80, 0xE5B2, 0x5B81, 0xC4FE, 0x5B82, 0x8C5D,
+	0x5B83, 0xCBFC, 0x5B84, 0xE5B3, 0x5B85, 0xD5AC, 0x5B86, 0x8C5E,
+	0x5B87, 0xD3EE, 0x5B88, 0xCAD8, 0x5B89, 0xB0B2, 0x5B8A, 0x8C5F,
+	0x5B8B, 0xCBCE, 0x5B8C, 0xCDEA, 0x5B8D, 0x8C60, 0x5B8E, 0x8C61,
+	0x5B8F, 0xBAEA, 0x5B90, 0x8C62, 0x5B91, 0x8C63, 0x5B92, 0x8C64,
+	0x5B93, 0xE5B5, 0x5B94, 0x8C65, 0x5B95, 0xE5B4, 0x5B96, 0x8C66,
+	0x5B97, 0xD7DA, 0x5B98, 0xB9D9, 0x5B99, 0xD6E6, 0x5B9A, 0xB6A8,
+	0x5B9B, 0xCDF0, 0x5B9C, 0xD2CB, 0x5B9D, 0xB1A6, 0x5B9E, 0xCAB5,
+	0x5B9F, 0x8C67, 0x5BA0, 0xB3E8, 0x5BA1, 0xC9F3, 0x5BA2, 0xBFCD,
+	0x5BA3, 0xD0FB, 0x5BA4, 0xCAD2, 0x5BA5, 0xE5B6, 0x5BA6, 0xBBC2,
+	0x5BA7, 0x8C68, 0x5BA8, 0x8C69, 0x5BA9, 0x8C6A, 0x5BAA, 0xCFDC,
+	0x5BAB, 0xB9AC, 0x5BAC, 0x8C6B, 0x5BAD, 0x8C6C, 0x5BAE, 0x8C6D,
+	0x5BAF, 0x8C6E, 0x5BB0, 0xD4D7, 0x5BB1, 0x8C6F, 0x5BB2, 0x8C70,
+	0x5BB3, 0xBAA6, 0x5BB4, 0xD1E7, 0x5BB5, 0xCFFC, 0x5BB6, 0xBCD2,
+	0x5BB7, 0x8C71, 0x5BB8, 0xE5B7, 0x5BB9, 0xC8DD, 0x5BBA, 0x8C72,
+	0x5BBB, 0x8C73, 0x5BBC, 0x8C74, 0x5BBD, 0xBFED, 0x5BBE, 0xB1F6,
+	0x5BBF, 0xCBDE, 0x5BC0, 0x8C75, 0x5BC1, 0x8C76, 0x5BC2, 0xBCC5,
+	0x5BC3, 0x8C77, 0x5BC4, 0xBCC4, 0x5BC5, 0xD2FA, 0x5BC6, 0xC3DC,
+	0x5BC7, 0xBFDC, 0x5BC8, 0x8C78, 0x5BC9, 0x8C79, 0x5BCA, 0x8C7A,
+	0x5BCB, 0x8C7B, 0x5BCC, 0xB8BB, 0x5BCD, 0x8C7C, 0x5BCE, 0x8C7D,
+	0x5BCF, 0x8C7E, 0x5BD0, 0xC3C2, 0x5BD1, 0x8C80, 0x5BD2, 0xBAAE,
+	0x5BD3, 0xD4A2, 0x5BD4, 0x8C81, 0x5BD5, 0x8C82, 0x5BD6, 0x8C83,
+	0x5BD7, 0x8C84, 0x5BD8, 0x8C85, 0x5BD9, 0x8C86, 0x5BDA, 0x8C87,
+	0x5BDB, 0x8C88, 0x5BDC, 0x8C89, 0x5BDD, 0xC7DE, 0x5BDE, 0xC4AF,
+	0x5BDF, 0xB2EC, 0x5BE0, 0x8C8A, 0x5BE1, 0xB9D1, 0x5BE2, 0x8C8B,
+	0x5BE3, 0x8C8C, 0x5BE4, 0xE5BB, 0x5BE5, 0xC1C8, 0x5BE6, 0x8C8D,
+	0x5BE7, 0x8C8E, 0x5BE8, 0xD5AF, 0x5BE9, 0x8C8F, 0x5BEA, 0x8C90,
+	0x5BEB, 0x8C91, 0x5BEC, 0x8C92, 0x5BED, 0x8C93, 0x5BEE, 0xE5BC,
+	0x5BEF, 0x8C94, 0x5BF0, 0xE5BE, 0x5BF1, 0x8C95, 0x5BF2, 0x8C96,
+	0x5BF3, 0x8C97, 0x5BF4, 0x8C98, 0x5BF5, 0x8C99, 0x5BF6, 0x8C9A,
+	0x5BF7, 0x8C9B, 0x5BF8, 0xB4E7, 0x5BF9, 0xB6D4, 0x5BFA, 0xCBC2,
+	0x5BFB, 0xD1B0, 0x5BFC, 0xB5BC, 0x5BFD, 0x8C9C, 0x5BFE, 0x8C9D,
+	0x5BFF, 0xCAD9, 0x5C00, 0x8C9E, 0x5C01, 0xB7E2, 0x5C02, 0x8C9F,
+	0x5C03, 0x8CA0, 0x5C04, 0xC9E4, 0x5C05, 0x8CA1, 0x5C06, 0xBDAB,
+	0x5C07, 0x8CA2, 0x5C08, 0x8CA3, 0x5C09, 0xCEBE, 0x5C0A, 0xD7F0,
+	0x5C0B, 0x8CA4, 0x5C0C, 0x8CA5, 0x5C0D, 0x8CA6, 0x5C0E, 0x8CA7,
+	0x5C0F, 0xD0A1, 0x5C10, 0x8CA8, 0x5C11, 0xC9D9, 0x5C12, 0x8CA9,
+	0x5C13, 0x8CAA, 0x5C14, 0xB6FB, 0x5C15, 0xE6D8, 0x5C16, 0xBCE2,
+	0x5C17, 0x8CAB, 0x5C18, 0xB3BE, 0x5C19, 0x8CAC, 0x5C1A, 0xC9D0,
+	0x5C1B, 0x8CAD, 0x5C1C, 0xE6D9, 0x5C1D, 0xB3A2, 0x5C1E, 0x8CAE,
+	0x5C1F, 0x8CAF, 0x5C20, 0x8CB0, 0x5C21, 0x8CB1, 0x5C22, 0xDECC,
+	0x5C23, 0x8CB2, 0x5C24, 0xD3C8, 0x5C25, 0xDECD, 0x5C26, 0x8CB3,
+	0x5C27, 0xD2A2, 0x5C28, 0x8CB4, 0x5C29, 0x8CB5, 0x5C2A, 0x8CB6,
+	0x5C2B, 0x8CB7, 0x5C2C, 0xDECE, 0x5C2D, 0x8CB8, 0x5C2E, 0x8CB9,
+	0x5C2F, 0x8CBA, 0x5C30, 0x8CBB, 0x5C31, 0xBECD, 0x5C32, 0x8CBC,
+	0x5C33, 0x8CBD, 0x5C34, 0xDECF, 0x5C35, 0x8CBE, 0x5C36, 0x8CBF,
+	0x5C37, 0x8CC0, 0x5C38, 0xCAAC, 0x5C39, 0xD2FC, 0x5C3A, 0xB3DF,
+	0x5C3B, 0xE5EA, 0x5C3C, 0xC4E1, 0x5C3D, 0xBEA1, 0x5C3E, 0xCEB2,
+	0x5C3F, 0xC4F2, 0x5C40, 0xBED6, 0x5C41, 0xC6A8, 0x5C42, 0xB2E3,
+	0x5C43, 0x8CC1, 0x5C44, 0x8CC2, 0x5C45, 0xBED3, 0x5C46, 0x8CC3,
+	0x5C47, 0x8CC4, 0x5C48, 0xC7FC, 0x5C49, 0xCCEB, 0x5C4A, 0xBDEC,
+	0x5C4B, 0xCEDD, 0x5C4C, 0x8CC5, 0x5C4D, 0x8CC6, 0x5C4E, 0xCABA,
+	0x5C4F, 0xC6C1, 0x5C50, 0xE5EC, 0x5C51, 0xD0BC, 0x5C52, 0x8CC7,
+	0x5C53, 0x8CC8, 0x5C54, 0x8CC9, 0x5C55, 0xD5B9, 0x5C56, 0x8CCA,
+	0x5C57, 0x8CCB, 0x5C58, 0x8CCC, 0x5C59, 0xE5ED, 0x5C5A, 0x8CCD,
+	0x5C5B, 0x8CCE, 0x5C5C, 0x8CCF, 0x5C5D, 0x8CD0, 0x5C5E, 0xCAF4,
+	0x5C5F, 0x8CD1, 0x5C60, 0xCDC0, 0x5C61, 0xC2C5, 0x5C62, 0x8CD2,
+	0x5C63, 0xE5EF, 0x5C64, 0x8CD3, 0x5C65, 0xC2C4, 0x5C66, 0xE5F0,
+	0x5C67, 0x8CD4, 0x5C68, 0x8CD5, 0x5C69, 0x8CD6, 0x5C6A, 0x8CD7,
+	0x5C6B, 0x8CD8, 0x5C6C, 0x8CD9, 0x5C6D, 0x8CDA, 0x5C6E, 0xE5F8,
+	0x5C6F, 0xCDCD, 0x5C70, 0x8CDB, 0x5C71, 0xC9BD, 0x5C72, 0x8CDC,
+	0x5C73, 0x8CDD, 0x5C74, 0x8CDE, 0x5C75, 0x8CDF, 0x5C76, 0x8CE0,
+	0x5C77, 0x8CE1, 0x5C78, 0x8CE2, 0x5C79, 0xD2D9, 0x5C7A, 0xE1A8,
+	0x5C7B, 0x8CE3, 0x5C7C, 0x8CE4, 0x5C7D, 0x8CE5, 0x5C7E, 0x8CE6,
+	0x5C7F, 0xD3EC, 0x5C80, 0x8CE7, 0x5C81, 0xCBEA, 0x5C82, 0xC6F1,
+	0x5C83, 0x8CE8, 0x5C84, 0x8CE9, 0x5C85, 0x8CEA, 0x5C86, 0x8CEB,
+	0x5C87, 0x8CEC, 0x5C88, 0xE1AC, 0x5C89, 0x8CED, 0x5C8A, 0x8CEE,
+	0x5C8B, 0x8CEF, 0x5C8C, 0xE1A7, 0x5C8D, 0xE1A9, 0x5C8E, 0x8CF0,
+	0x5C8F, 0x8CF1, 0x5C90, 0xE1AA, 0x5C91, 0xE1AF, 0x5C92, 0x8CF2,
+	0x5C93, 0x8CF3, 0x5C94, 0xB2ED, 0x5C95, 0x8CF4, 0x5C96, 0xE1AB,
+	0x5C97, 0xB8DA, 0x5C98, 0xE1AD, 0x5C99, 0xE1AE, 0x5C9A, 0xE1B0,
+	0x5C9B, 0xB5BA, 0x5C9C, 0xE1B1, 0x5C9D, 0x8CF5, 0x5C9E, 0x8CF6,
+	0x5C9F, 0x8CF7, 0x5CA0, 0x8CF8, 0x5CA1, 0x8CF9, 0x5CA2, 0xE1B3,
+	0x5CA3, 0xE1B8, 0x5CA4, 0x8CFA, 0x5CA5, 0x8CFB, 0x5CA6, 0x8CFC,
+	0x5CA7, 0x8CFD, 0x5CA8, 0x8CFE, 0x5CA9, 0xD1D2, 0x5CAA, 0x8D40,
+	0x5CAB, 0xE1B6, 0x5CAC, 0xE1B5, 0x5CAD, 0xC1EB, 0x5CAE, 0x8D41,
+	0x5CAF, 0x8D42, 0x5CB0, 0x8D43, 0x5CB1, 0xE1B7, 0x5CB2, 0x8D44,
+	0x5CB3, 0xD4C0, 0x5CB4, 0x8D45, 0x5CB5, 0xE1B2, 0x5CB6, 0x8D46,
+	0x5CB7, 0xE1BA, 0x5CB8, 0xB0B6, 0x5CB9, 0x8D47, 0x5CBA, 0x8D48,
+	0x5CBB, 0x8D49, 0x5CBC, 0x8D4A, 0x5CBD, 0xE1B4, 0x5CBE, 0x8D4B,
+	0x5CBF, 0xBFF9, 0x5CC0, 0x8D4C, 0x5CC1, 0xE1B9, 0x5CC2, 0x8D4D,
+	0x5CC3, 0x8D4E, 0x5CC4, 0xE1BB, 0x5CC5, 0x8D4F, 0x5CC6, 0x8D50,
+	0x5CC7, 0x8D51, 0x5CC8, 0x8D52, 0x5CC9, 0x8D53, 0x5CCA, 0x8D54,
+	0x5CCB, 0xE1BE, 0x5CCC, 0x8D55, 0x5CCD, 0x8D56, 0x5CCE, 0x8D57,
+	0x5CCF, 0x8D58, 0x5CD0, 0x8D59, 0x5CD1, 0x8D5A, 0x5CD2, 0xE1BC,
+	0x5CD3, 0x8D5B, 0x5CD4, 0x8D5C, 0x5CD5, 0x8D5D, 0x5CD6, 0x8D5E,
+	0x5CD7, 0x8D5F, 0x5CD8, 0x8D60, 0x5CD9, 0xD6C5, 0x5CDA, 0x8D61,
+	0x5CDB, 0x8D62, 0x5CDC, 0x8D63, 0x5CDD, 0x8D64, 0x5CDE, 0x8D65,
+	0x5CDF, 0x8D66, 0x5CE0, 0x8D67, 0x5CE1, 0xCFBF, 0x5CE2, 0x8D68,
+	0x5CE3, 0x8D69, 0x5CE4, 0xE1BD, 0x5CE5, 0xE1BF, 0x5CE6, 0xC2CD,
+	0x5CE7, 0x8D6A, 0x5CE8, 0xB6EB, 0x5CE9, 0x8D6B, 0x5CEA, 0xD3F8,
+	0x5CEB, 0x8D6C, 0x5CEC, 0x8D6D, 0x5CED, 0xC7CD, 0x5CEE, 0x8D6E,
+	0x5CEF, 0x8D6F, 0x5CF0, 0xB7E5, 0x5CF1, 0x8D70, 0x5CF2, 0x8D71,
+	0x5CF3, 0x8D72, 0x5CF4, 0x8D73, 0x5CF5, 0x8D74, 0x5CF6, 0x8D75,
+	0x5CF7, 0x8D76, 0x5CF8, 0x8D77, 0x5CF9, 0x8D78, 0x5CFA, 0x8D79,
+	0x5CFB, 0xBEFE, 0x5CFC, 0x8D7A, 0x5CFD, 0x8D7B, 0x5CFE, 0x8D7C,
+	0x5CFF, 0x8D7D, 0x5D00, 0x8D7E, 0x5D01, 0x8D80, 0x5D02, 0xE1C0,
+	0x5D03, 0xE1C1, 0x5D04, 0x8D81, 0x5D05, 0x8D82, 0x5D06, 0xE1C7,
+	0x5D07, 0xB3E7, 0x5D08, 0x8D83, 0x5D09, 0x8D84, 0x5D0A, 0x8D85,
+	0x5D0B, 0x8D86, 0x5D0C, 0x8D87, 0x5D0D, 0x8D88, 0x5D0E, 0xC6E9,
+	0x5D0F, 0x8D89, 0x5D10, 0x8D8A, 0x5D11, 0x8D8B, 0x5D12, 0x8D8C,
+	0x5D13, 0x8D8D, 0x5D14, 0xB4DE, 0x5D15, 0x8D8E, 0x5D16, 0xD1C2,
+	0x5D17, 0x8D8F, 0x5D18, 0x8D90, 0x5D19, 0x8D91, 0x5D1A, 0x8D92,
+	0x5D1B, 0xE1C8, 0x5D1C, 0x8D93, 0x5D1D, 0x8D94, 0x5D1E, 0xE1C6,
+	0x5D1F, 0x8D95, 0x5D20, 0x8D96, 0x5D21, 0x8D97, 0x5D22, 0x8D98,
+	0x5D23, 0x8D99, 0x5D24, 0xE1C5, 0x5D25, 0x8D9A, 0x5D26, 0xE1C3,
+	0x5D27, 0xE1C2, 0x5D28, 0x8D9B, 0x5D29, 0xB1C0, 0x5D2A, 0x8D9C,
+	0x5D2B, 0x8D9D, 0x5D2C, 0x8D9E, 0x5D2D, 0xD5B8, 0x5D2E, 0xE1C4,
+	0x5D2F, 0x8D9F, 0x5D30, 0x8DA0, 0x5D31, 0x8DA1, 0x5D32, 0x8DA2,
+	0x5D33, 0x8DA3, 0x5D34, 0xE1CB, 0x5D35, 0x8DA4, 0x5D36, 0x8DA5,
+	0x5D37, 0x8DA6, 0x5D38, 0x8DA7, 0x5D39, 0x8DA8, 0x5D3A, 0x8DA9,
+	0x5D3B, 0x8DAA, 0x5D3C, 0x8DAB, 0x5D3D, 0xE1CC, 0x5D3E, 0xE1CA,
+	0x5D3F, 0x8DAC, 0x5D40, 0x8DAD, 0x5D41, 0x8DAE, 0x5D42, 0x8DAF,
+	0x5D43, 0x8DB0, 0x5D44, 0x8DB1, 0x5D45, 0x8DB2, 0x5D46, 0x8DB3,
+	0x5D47, 0xEFFA, 0x5D48, 0x8DB4, 0x5D49, 0x8DB5, 0x5D4A, 0xE1D3,
+	0x5D4B, 0xE1D2, 0x5D4C, 0xC7B6, 0x5D4D, 0x8DB6, 0x5D4E, 0x8DB7,
+	0x5D4F, 0x8DB8, 0x5D50, 0x8DB9, 0x5D51, 0x8DBA, 0x5D52, 0x8DBB,
+	0x5D53, 0x8DBC, 0x5D54, 0x8DBD, 0x5D55, 0x8DBE, 0x5D56, 0x8DBF,
+	0x5D57, 0x8DC0, 0x5D58, 0xE1C9, 0x5D59, 0x8DC1, 0x5D5A, 0x8DC2,
+	0x5D5B, 0xE1CE, 0x5D5C, 0x8DC3, 0x5D5D, 0xE1D0, 0x5D5E, 0x8DC4,
+	0x5D5F, 0x8DC5, 0x5D60, 0x8DC6, 0x5D61, 0x8DC7, 0x5D62, 0x8DC8,
+	0x5D63, 0x8DC9, 0x5D64, 0x8DCA, 0x5D65, 0x8DCB, 0x5D66, 0x8DCC,
+	0x5D67, 0x8DCD, 0x5D68, 0x8DCE, 0x5D69, 0xE1D4, 0x5D6A, 0x8DCF,
+	0x5D6B, 0xE1D1, 0x5D6C, 0xE1CD, 0x5D6D, 0x8DD0, 0x5D6E, 0x8DD1,
+	0x5D6F, 0xE1CF, 0x5D70, 0x8DD2, 0x5D71, 0x8DD3, 0x5D72, 0x8DD4,
+	0x5D73, 0x8DD5, 0x5D74, 0xE1D5, 0x5D75, 0x8DD6, 0x5D76, 0x8DD7,
+	0x5D77, 0x8DD8, 0x5D78, 0x8DD9, 0x5D79, 0x8DDA, 0x5D7A, 0x8DDB,
+	0x5D7B, 0x8DDC, 0x5D7C, 0x8DDD, 0x5D7D, 0x8DDE, 0x5D7E, 0x8DDF,
+	0x5D7F, 0x8DE0, 0x5D80, 0x8DE1, 0x5D81, 0x8DE2, 0x5D82, 0xE1D6,
+	0x5D83, 0x8DE3, 0x5D84, 0x8DE4, 0x5D85, 0x8DE5, 0x5D86, 0x8DE6,
+	0x5D87, 0x8DE7, 0x5D88, 0x8DE8, 0x5D89, 0x8DE9, 0x5D8A, 0x8DEA,
+	0x5D8B, 0x8DEB, 0x5D8C, 0x8DEC, 0x5D8D, 0x8DED, 0x5D8E, 0x8DEE,
+	0x5D8F, 0x8DEF, 0x5D90, 0x8DF0, 0x5D91, 0x8DF1, 0x5D92, 0x8DF2,
+	0x5D93, 0x8DF3, 0x5D94, 0x8DF4, 0x5D95, 0x8DF5, 0x5D96, 0x8DF6,
+	0x5D97, 0x8DF7, 0x5D98, 0x8DF8, 0x5D99, 0xE1D7, 0x5D9A, 0x8DF9,
+	0x5D9B, 0x8DFA, 0x5D9C, 0x8DFB, 0x5D9D, 0xE1D8, 0x5D9E, 0x8DFC,
+	0x5D9F, 0x8DFD, 0x5DA0, 0x8DFE, 0x5DA1, 0x8E40, 0x5DA2, 0x8E41,
+	0x5DA3, 0x8E42, 0x5DA4, 0x8E43, 0x5DA5, 0x8E44, 0x5DA6, 0x8E45,
+	0x5DA7, 0x8E46, 0x5DA8, 0x8E47, 0x5DA9, 0x8E48, 0x5DAA, 0x8E49,
+	0x5DAB, 0x8E4A, 0x5DAC, 0x8E4B, 0x5DAD, 0x8E4C, 0x5DAE, 0x8E4D,
+	0x5DAF, 0x8E4E, 0x5DB0, 0x8E4F, 0x5DB1, 0x8E50, 0x5DB2, 0x8E51,
+	0x5DB3, 0x8E52, 0x5DB4, 0x8E53, 0x5DB5, 0x8E54, 0x5DB6, 0x8E55,
+	0x5DB7, 0xE1DA, 0x5DB8, 0x8E56, 0x5DB9, 0x8E57, 0x5DBA, 0x8E58,
+	0x5DBB, 0x8E59, 0x5DBC, 0x8E5A, 0x5DBD, 0x8E5B, 0x5DBE, 0x8E5C,
+	0x5DBF, 0x8E5D, 0x5DC0, 0x8E5E, 0x5DC1, 0x8E5F, 0x5DC2, 0x8E60,
+	0x5DC3, 0x8E61, 0x5DC4, 0x8E62, 0x5DC5, 0xE1DB, 0x5DC6, 0x8E63,
+	0x5DC7, 0x8E64, 0x5DC8, 0x8E65, 0x5DC9, 0x8E66, 0x5DCA, 0x8E67,
+	0x5DCB, 0x8E68, 0x5DCC, 0x8E69, 0x5DCD, 0xCEA1, 0x5DCE, 0x8E6A,
+	0x5DCF, 0x8E6B, 0x5DD0, 0x8E6C, 0x5DD1, 0x8E6D, 0x5DD2, 0x8E6E,
+	0x5DD3, 0x8E6F, 0x5DD4, 0x8E70, 0x5DD5, 0x8E71, 0x5DD6, 0x8E72,
+	0x5DD7, 0x8E73, 0x5DD8, 0x8E74, 0x5DD9, 0x8E75, 0x5DDA, 0x8E76,
+	0x5DDB, 0xE7DD, 0x5DDC, 0x8E77, 0x5DDD, 0xB4A8, 0x5DDE, 0xD6DD,
+	0x5DDF, 0x8E78, 0x5DE0, 0x8E79, 0x5DE1, 0xD1B2, 0x5DE2, 0xB3B2,
+	0x5DE3, 0x8E7A, 0x5DE4, 0x8E7B, 0x5DE5, 0xB9A4, 0x5DE6, 0xD7F3,
+	0x5DE7, 0xC7C9, 0x5DE8, 0xBEDE, 0x5DE9, 0xB9AE, 0x5DEA, 0x8E7C,
+	0x5DEB, 0xCED7, 0x5DEC, 0x8E7D, 0x5DED, 0x8E7E, 0x5DEE, 0xB2EE,
+	0x5DEF, 0xDBCF, 0x5DF0, 0x8E80, 0x5DF1, 0xBCBA, 0x5DF2, 0xD2D1,
+	0x5DF3, 0xCBC8, 0x5DF4, 0xB0CD, 0x5DF5, 0x8E81, 0x5DF6, 0x8E82,
+	0x5DF7, 0xCFEF, 0x5DF8, 0x8E83, 0x5DF9, 0x8E84, 0x5DFA, 0x8E85,
+	0x5DFB, 0x8E86, 0x5DFC, 0x8E87, 0x5DFD, 0xD9E3, 0x5DFE, 0xBDED,
+	0x5DFF, 0x8E88, 0x5E00, 0x8E89, 0x5E01, 0xB1D2, 0x5E02, 0xCAD0,
+	0x5E03, 0xB2BC, 0x5E04, 0x8E8A, 0x5E05, 0xCBA7, 0x5E06, 0xB7AB,
+	0x5E07, 0x8E8B, 0x5E08, 0xCAA6, 0x5E09, 0x8E8C, 0x5E0A, 0x8E8D,
+	0x5E0B, 0x8E8E, 0x5E0C, 0xCFA3, 0x5E0D, 0x8E8F, 0x5E0E, 0x8E90,
+	0x5E0F, 0xE0F8, 0x5E10, 0xD5CA, 0x5E11, 0xE0FB, 0x5E12, 0x8E91,
+	0x5E13, 0x8E92, 0x5E14, 0xE0FA, 0x5E15, 0xC5C1, 0x5E16, 0xCCFB,
+	0x5E17, 0x8E93, 0x5E18, 0xC1B1, 0x5E19, 0xE0F9, 0x5E1A, 0xD6E3,
+	0x5E1B, 0xB2AF, 0x5E1C, 0xD6C4, 0x5E1D, 0xB5DB, 0x5E1E, 0x8E94,
+	0x5E1F, 0x8E95, 0x5E20, 0x8E96, 0x5E21, 0x8E97, 0x5E22, 0x8E98,
+	0x5E23, 0x8E99, 0x5E24, 0x8E9A, 0x5E25, 0x8E9B, 0x5E26, 0xB4F8,
+	0x5E27, 0xD6A1, 0x5E28, 0x8E9C, 0x5E29, 0x8E9D, 0x5E2A, 0x8E9E,
+	0x5E2B, 0x8E9F, 0x5E2C, 0x8EA0, 0x5E2D, 0xCFAF, 0x5E2E, 0xB0EF,
+	0x5E2F, 0x8EA1, 0x5E30, 0x8EA2, 0x5E31, 0xE0FC, 0x5E32, 0x8EA3,
+	0x5E33, 0x8EA4, 0x5E34, 0x8EA5, 0x5E35, 0x8EA6, 0x5E36, 0x8EA7,
+	0x5E37, 0xE1A1, 0x5E38, 0xB3A3, 0x5E39, 0x8EA8, 0x5E3A, 0x8EA9,
+	0x5E3B, 0xE0FD, 0x5E3C, 0xE0FE, 0x5E3D, 0xC3B1, 0x5E3E, 0x8EAA,
+	0x5E3F, 0x8EAB, 0x5E40, 0x8EAC, 0x5E41, 0x8EAD, 0x5E42, 0xC3DD,
+	0x5E43, 0x8EAE, 0x5E44, 0xE1A2, 0x5E45, 0xB7F9, 0x5E46, 0x8EAF,
+	0x5E47, 0x8EB0, 0x5E48, 0x8EB1, 0x5E49, 0x8EB2, 0x5E4A, 0x8EB3,
+	0x5E4B, 0x8EB4, 0x5E4C, 0xBBCF, 0x5E4D, 0x8EB5, 0x5E4E, 0x8EB6,
+	0x5E4F, 0x8EB7, 0x5E50, 0x8EB8, 0x5E51, 0x8EB9, 0x5E52, 0x8EBA,
+	0x5E53, 0x8EBB, 0x5E54, 0xE1A3, 0x5E55, 0xC4BB, 0x5E56, 0x8EBC,
+	0x5E57, 0x8EBD, 0x5E58, 0x8EBE, 0x5E59, 0x8EBF, 0x5E5A, 0x8EC0,
+	0x5E5B, 0xE1A4, 0x5E5C, 0x8EC1, 0x5E5D, 0x8EC2, 0x5E5E, 0xE1A5,
+	0x5E5F, 0x8EC3, 0x5E60, 0x8EC4, 0x5E61, 0xE1A6, 0x5E62, 0xB4B1,
+	0x5E63, 0x8EC5, 0x5E64, 0x8EC6, 0x5E65, 0x8EC7, 0x5E66, 0x8EC8,
+	0x5E67, 0x8EC9, 0x5E68, 0x8ECA, 0x5E69, 0x8ECB, 0x5E6A, 0x8ECC,
+	0x5E6B, 0x8ECD, 0x5E6C, 0x8ECE, 0x5E6D, 0x8ECF, 0x5E6E, 0x8ED0,
+	0x5E6F, 0x8ED1, 0x5E70, 0x8ED2, 0x5E71, 0x8ED3, 0x5E72, 0xB8C9,
+	0x5E73, 0xC6BD, 0x5E74, 0xC4EA, 0x5E75, 0x8ED4, 0x5E76, 0xB2A2,
+	0x5E77, 0x8ED5, 0x5E78, 0xD0D2, 0x5E79, 0x8ED6, 0x5E7A, 0xE7DB,
+	0x5E7B, 0xBBC3, 0x5E7C, 0xD3D7, 0x5E7D, 0xD3C4, 0x5E7E, 0x8ED7,
+	0x5E7F, 0xB9E3, 0x5E80, 0xE2CF, 0x5E81, 0x8ED8, 0x5E82, 0x8ED9,
+	0x5E83, 0x8EDA, 0x5E84, 0xD7AF, 0x5E85, 0x8EDB, 0x5E86, 0xC7EC,
+	0x5E87, 0xB1D3, 0x5E88, 0x8EDC, 0x5E89, 0x8EDD, 0x5E8A, 0xB4B2,
+	0x5E8B, 0xE2D1, 0x5E8C, 0x8EDE, 0x5E8D, 0x8EDF, 0x5E8E, 0x8EE0,
+	0x5E8F, 0xD0F2, 0x5E90, 0xC2AE, 0x5E91, 0xE2D0, 0x5E92, 0x8EE1,
+	0x5E93, 0xBFE2, 0x5E94, 0xD3A6, 0x5E95, 0xB5D7, 0x5E96, 0xE2D2,
+	0x5E97, 0xB5EA, 0x5E98, 0x8EE2, 0x5E99, 0xC3ED, 0x5E9A, 0xB8FD,
+	0x5E9B, 0x8EE3, 0x5E9C, 0xB8AE, 0x5E9D, 0x8EE4, 0x5E9E, 0xC5D3,
+	0x5E9F, 0xB7CF, 0x5EA0, 0xE2D4, 0x5EA1, 0x8EE5, 0x5EA2, 0x8EE6,
+	0x5EA3, 0x8EE7, 0x5EA4, 0x8EE8, 0x5EA5, 0xE2D3, 0x5EA6, 0xB6C8,
+	0x5EA7, 0xD7F9, 0x5EA8, 0x8EE9, 0x5EA9, 0x8EEA, 0x5EAA, 0x8EEB,
+	0x5EAB, 0x8EEC, 0x5EAC, 0x8EED, 0x5EAD, 0xCDA5, 0x5EAE, 0x8EEE,
+	0x5EAF, 0x8EEF, 0x5EB0, 0x8EF0, 0x5EB1, 0x8EF1, 0x5EB2, 0x8EF2,
+	0x5EB3, 0xE2D8, 0x5EB4, 0x8EF3, 0x5EB5, 0xE2D6, 0x5EB6, 0xCAFC,
+	0x5EB7, 0xBFB5, 0x5EB8, 0xD3B9, 0x5EB9, 0xE2D5, 0x5EBA, 0x8EF4,
+	0x5EBB, 0x8EF5, 0x5EBC, 0x8EF6, 0x5EBD, 0x8EF7, 0x5EBE, 0xE2D7,
+	0x5EBF, 0x8EF8, 0x5EC0, 0x8EF9, 0x5EC1, 0x8EFA, 0x5EC2, 0x8EFB,
+	0x5EC3, 0x8EFC, 0x5EC4, 0x8EFD, 0x5EC5, 0x8EFE, 0x5EC6, 0x8F40,
+	0x5EC7, 0x8F41, 0x5EC8, 0x8F42, 0x5EC9, 0xC1AE, 0x5ECA, 0xC0C8,
+	0x5ECB, 0x8F43, 0x5ECC, 0x8F44, 0x5ECD, 0x8F45, 0x5ECE, 0x8F46,
+	0x5ECF, 0x8F47, 0x5ED0, 0x8F48, 0x5ED1, 0xE2DB, 0x5ED2, 0xE2DA,
+	0x5ED3, 0xC0AA, 0x5ED4, 0x8F49, 0x5ED5, 0x8F4A, 0x5ED6, 0xC1CE,
+	0x5ED7, 0x8F4B, 0x5ED8, 0x8F4C, 0x5ED9, 0x8F4D, 0x5EDA, 0x8F4E,
+	0x5EDB, 0xE2DC, 0x5EDC, 0x8F4F, 0x5EDD, 0x8F50, 0x5EDE, 0x8F51,
+	0x5EDF, 0x8F52, 0x5EE0, 0x8F53, 0x5EE1, 0x8F54, 0x5EE2, 0x8F55,
+	0x5EE3, 0x8F56, 0x5EE4, 0x8F57, 0x5EE5, 0x8F58, 0x5EE6, 0x8F59,
+	0x5EE7, 0x8F5A, 0x5EE8, 0xE2DD, 0x5EE9, 0x8F5B, 0x5EEA, 0xE2DE,
+	0x5EEB, 0x8F5C, 0x5EEC, 0x8F5D, 0x5EED, 0x8F5E, 0x5EEE, 0x8F5F,
+	0x5EEF, 0x8F60, 0x5EF0, 0x8F61, 0x5EF1, 0x8F62, 0x5EF2, 0x8F63,
+	0x5EF3, 0x8F64, 0x5EF4, 0xDBC8, 0x5EF5, 0x8F65, 0x5EF6, 0xD1D3,
+	0x5EF7, 0xCDA2, 0x5EF8, 0x8F66, 0x5EF9, 0x8F67, 0x5EFA, 0xBDA8,
+	0x5EFB, 0x8F68, 0x5EFC, 0x8F69, 0x5EFD, 0x8F6A, 0x5EFE, 0xDEC3,
+	0x5EFF, 0xD8A5, 0x5F00, 0xBFAA, 0x5F01, 0xDBCD, 0x5F02, 0xD2EC,
+	0x5F03, 0xC6FA, 0x5F04, 0xC5AA, 0x5F05, 0x8F6B, 0x5F06, 0x8F6C,
+	0x5F07, 0x8F6D, 0x5F08, 0xDEC4, 0x5F09, 0x8F6E, 0x5F0A, 0xB1D7,
+	0x5F0B, 0xDFAE, 0x5F0C, 0x8F6F, 0x5F0D, 0x8F70, 0x5F0E, 0x8F71,
+	0x5F0F, 0xCABD, 0x5F10, 0x8F72, 0x5F11, 0xDFB1, 0x5F12, 0x8F73,
+	0x5F13, 0xB9AD, 0x5F14, 0x8F74, 0x5F15, 0xD2FD, 0x5F16, 0x8F75,
+	0x5F17, 0xB8A5, 0x5F18, 0xBAEB, 0x5F19, 0x8F76, 0x5F1A, 0x8F77,
+	0x5F1B, 0xB3DA, 0x5F1C, 0x8F78, 0x5F1D, 0x8F79, 0x5F1E, 0x8F7A,
+	0x5F1F, 0xB5DC, 0x5F20, 0xD5C5, 0x5F21, 0x8F7B, 0x5F22, 0x8F7C,
+	0x5F23, 0x8F7D, 0x5F24, 0x8F7E, 0x5F25, 0xC3D6, 0x5F26, 0xCFD2,
+	0x5F27, 0xBBA1, 0x5F28, 0x8F80, 0x5F29, 0xE5F3, 0x5F2A, 0xE5F2,
+	0x5F2B, 0x8F81, 0x5F2C, 0x8F82, 0x5F2D, 0xE5F4, 0x5F2E, 0x8F83,
+	0x5F2F, 0xCDE4, 0x5F30, 0x8F84, 0x5F31, 0xC8F5, 0x5F32, 0x8F85,
+	0x5F33, 0x8F86, 0x5F34, 0x8F87, 0x5F35, 0x8F88, 0x5F36, 0x8F89,
+	0x5F37, 0x8F8A, 0x5F38, 0x8F8B, 0x5F39, 0xB5AF, 0x5F3A, 0xC7BF,
+	0x5F3B, 0x8F8C, 0x5F3C, 0xE5F6, 0x5F3D, 0x8F8D, 0x5F3E, 0x8F8E,
+	0x5F3F, 0x8F8F, 0x5F40, 0xECB0, 0x5F41, 0x8F90, 0x5F42, 0x8F91,
+	0x5F43, 0x8F92, 0x5F44, 0x8F93, 0x5F45, 0x8F94, 0x5F46, 0x8F95,
+	0x5F47, 0x8F96, 0x5F48, 0x8F97, 0x5F49, 0x8F98, 0x5F4A, 0x8F99,
+	0x5F4B, 0x8F9A, 0x5F4C, 0x8F9B, 0x5F4D, 0x8F9C, 0x5F4E, 0x8F9D,
+	0x5F4F, 0x8F9E, 0x5F50, 0xE5E6, 0x5F51, 0x8F9F, 0x5F52, 0xB9E9,
+	0x5F53, 0xB5B1, 0x5F54, 0x8FA0, 0x5F55, 0xC2BC, 0x5F56, 0xE5E8,
+	0x5F57, 0xE5E7, 0x5F58, 0xE5E9, 0x5F59, 0x8FA1, 0x5F5A, 0x8FA2,
+	0x5F5B, 0x8FA3, 0x5F5C, 0x8FA4, 0x5F5D, 0xD2CD, 0x5F5E, 0x8FA5,
+	0x5F5F, 0x8FA6, 0x5F60, 0x8FA7, 0x5F61, 0xE1EA, 0x5F62, 0xD0CE,
+	0x5F63, 0x8FA8, 0x5F64, 0xCDAE, 0x5F65, 0x8FA9, 0x5F66, 0xD1E5,
+	0x5F67, 0x8FAA, 0x5F68, 0x8FAB, 0x5F69, 0xB2CA, 0x5F6A, 0xB1EB,
+	0x5F6B, 0x8FAC, 0x5F6C, 0xB1F2, 0x5F6D, 0xC5ED, 0x5F6E, 0x8FAD,
+	0x5F6F, 0x8FAE, 0x5F70, 0xD5C3, 0x5F71, 0xD3B0, 0x5F72, 0x8FAF,
+	0x5F73, 0xE1DC, 0x5F74, 0x8FB0, 0x5F75, 0x8FB1, 0x5F76, 0x8FB2,
+	0x5F77, 0xE1DD, 0x5F78, 0x8FB3, 0x5F79, 0xD2DB, 0x5F7A, 0x8FB4,
+	0x5F7B, 0xB3B9, 0x5F7C, 0xB1CB, 0x5F7D, 0x8FB5, 0x5F7E, 0x8FB6,
+	0x5F7F, 0x8FB7, 0x5F80, 0xCDF9, 0x5F81, 0xD5F7, 0x5F82, 0xE1DE,
+	0x5F83, 0x8FB8, 0x5F84, 0xBEB6, 0x5F85, 0xB4FD, 0x5F86, 0x8FB9,
+	0x5F87, 0xE1DF, 0x5F88, 0xBADC, 0x5F89, 0xE1E0, 0x5F8A, 0xBBB2,
+	0x5F8B, 0xC2C9, 0x5F8C, 0xE1E1, 0x5F8D, 0x8FBA, 0x5F8E, 0x8FBB,
+	0x5F8F, 0x8FBC, 0x5F90, 0xD0EC, 0x5F91, 0x8FBD, 0x5F92, 0xCDBD,
+	0x5F93, 0x8FBE, 0x5F94, 0x8FBF, 0x5F95, 0xE1E2, 0x5F96, 0x8FC0,
+	0x5F97, 0xB5C3, 0x5F98, 0xC5C7, 0x5F99, 0xE1E3, 0x5F9A, 0x8FC1,
+	0x5F9B, 0x8FC2, 0x5F9C, 0xE1E4, 0x5F9D, 0x8FC3, 0x5F9E, 0x8FC4,
+	0x5F9F, 0x8FC5, 0x5FA0, 0x8FC6, 0x5FA1, 0xD3F9, 0x5FA2, 0x8FC7,
+	0x5FA3, 0x8FC8, 0x5FA4, 0x8FC9, 0x5FA5, 0x8FCA, 0x5FA6, 0x8FCB,
+	0x5FA7, 0x8FCC, 0x5FA8, 0xE1E5, 0x5FA9, 0x8FCD, 0x5FAA, 0xD1AD,
+	0x5FAB, 0x8FCE, 0x5FAC, 0x8FCF, 0x5FAD, 0xE1E6, 0x5FAE, 0xCEA2,
+	0x5FAF, 0x8FD0, 0x5FB0, 0x8FD1, 0x5FB1, 0x8FD2, 0x5FB2, 0x8FD3,
+	0x5FB3, 0x8FD4, 0x5FB4, 0x8FD5, 0x5FB5, 0xE1E7, 0x5FB6, 0x8FD6,
+	0x5FB7, 0xB5C2, 0x5FB8, 0x8FD7, 0x5FB9, 0x8FD8, 0x5FBA, 0x8FD9,
+	0x5FBB, 0x8FDA, 0x5FBC, 0xE1E8, 0x5FBD, 0xBBD5, 0x5FBE, 0x8FDB,
+	0x5FBF, 0x8FDC, 0x5FC0, 0x8FDD, 0x5FC1, 0x8FDE, 0x5FC2, 0x8FDF,
+	0x5FC3, 0xD0C4, 0x5FC4, 0xE2E0, 0x5FC5, 0xB1D8, 0x5FC6, 0xD2E4,
+	0x5FC7, 0x8FE0, 0x5FC8, 0x8FE1, 0x5FC9, 0xE2E1, 0x5FCA, 0x8FE2,
+	0x5FCB, 0x8FE3, 0x5FCC, 0xBCC9, 0x5FCD, 0xC8CC, 0x5FCE, 0x8FE4,
+	0x5FCF, 0xE2E3, 0x5FD0, 0xECFE, 0x5FD1, 0xECFD, 0x5FD2, 0xDFAF,
+	0x5FD3, 0x8FE5, 0x5FD4, 0x8FE6, 0x5FD5, 0x8FE7, 0x5FD6, 0xE2E2,
+	0x5FD7, 0xD6BE, 0x5FD8, 0xCDFC, 0x5FD9, 0xC3A6, 0x5FDA, 0x8FE8,
+	0x5FDB, 0x8FE9, 0x5FDC, 0x8FEA, 0x5FDD, 0xE3C3, 0x5FDE, 0x8FEB,
+	0x5FDF, 0x8FEC, 0x5FE0, 0xD6D2, 0x5FE1, 0xE2E7, 0x5FE2, 0x8FED,
+	0x5FE3, 0x8FEE, 0x5FE4, 0xE2E8, 0x5FE5, 0x8FEF, 0x5FE6, 0x8FF0,
+	0x5FE7, 0xD3C7, 0x5FE8, 0x8FF1, 0x5FE9, 0x8FF2, 0x5FEA, 0xE2EC,
+	0x5FEB, 0xBFEC, 0x5FEC, 0x8FF3, 0x5FED, 0xE2ED, 0x5FEE, 0xE2E5,
+	0x5FEF, 0x8FF4, 0x5FF0, 0x8FF5, 0x5FF1, 0xB3C0, 0x5FF2, 0x8FF6,
+	0x5FF3, 0x8FF7, 0x5FF4, 0x8FF8, 0x5FF5, 0xC4EE, 0x5FF6, 0x8FF9,
+	0x5FF7, 0x8FFA, 0x5FF8, 0xE2EE, 0x5FF9, 0x8FFB, 0x5FFA, 0x8FFC,
+	0x5FFB, 0xD0C3, 0x5FFC, 0x8FFD, 0x5FFD, 0xBAF6, 0x5FFE, 0xE2E9,
+	0x5FFF, 0xB7DE, 0x6000, 0xBBB3, 0x6001, 0xCCAC, 0x6002, 0xCBCB,
+	0x6003, 0xE2E4, 0x6004, 0xE2E6, 0x6005, 0xE2EA, 0x6006, 0xE2EB,
+	0x6007, 0x8FFE, 0x6008, 0x9040, 0x6009, 0x9041, 0x600A, 0xE2F7,
+	0x600B, 0x9042, 0x600C, 0x9043, 0x600D, 0xE2F4, 0x600E, 0xD4F5,
+	0x600F, 0xE2F3, 0x6010, 0x9044, 0x6011, 0x9045, 0x6012, 0xC5AD,
+	0x6013, 0x9046, 0x6014, 0xD5FA, 0x6015, 0xC5C2, 0x6016, 0xB2C0,
+	0x6017, 0x9047, 0x6018, 0x9048, 0x6019, 0xE2EF, 0x601A, 0x9049,
+	0x601B, 0xE2F2, 0x601C, 0xC1AF, 0x601D, 0xCBBC, 0x601E, 0x904A,
+	0x601F, 0x904B, 0x6020, 0xB5A1, 0x6021, 0xE2F9, 0x6022, 0x904C,
+	0x6023, 0x904D, 0x6024, 0x904E, 0x6025, 0xBCB1, 0x6026, 0xE2F1,
+	0x6027, 0xD0D4, 0x6028, 0xD4B9, 0x6029, 0xE2F5, 0x602A, 0xB9D6,
+	0x602B, 0xE2F6, 0x602C, 0x904F, 0x602D, 0x9050, 0x602E, 0x9051,
+	0x602F, 0xC7D3, 0x6030, 0x9052, 0x6031, 0x9053, 0x6032, 0x9054,
+	0x6033, 0x9055, 0x6034, 0x9056, 0x6035, 0xE2F0, 0x6036, 0x9057,
+	0x6037, 0x9058, 0x6038, 0x9059, 0x6039, 0x905A, 0x603A, 0x905B,
+	0x603B, 0xD7DC, 0x603C, 0xEDA1, 0x603D, 0x905C, 0x603E, 0x905D,
+	0x603F, 0xE2F8, 0x6040, 0x905E, 0x6041, 0xEDA5, 0x6042, 0xE2FE,
+	0x6043, 0xCAD1, 0x6044, 0x905F, 0x6045, 0x9060, 0x6046, 0x9061,
+	0x6047, 0x9062, 0x6048, 0x9063, 0x6049, 0x9064, 0x604A, 0x9065,
+	0x604B, 0xC1B5, 0x604C, 0x9066, 0x604D, 0xBBD0, 0x604E, 0x9067,
+	0x604F, 0x9068, 0x6050, 0xBFD6, 0x6051, 0x9069, 0x6052, 0xBAE3,
+	0x6053, 0x906A, 0x6054, 0x906B, 0x6055, 0xCBA1, 0x6056, 0x906C,
+	0x6057, 0x906D, 0x6058, 0x906E, 0x6059, 0xEDA6, 0x605A, 0xEDA3,
+	0x605B, 0x906F, 0x605C, 0x9070, 0x605D, 0xEDA2, 0x605E, 0x9071,
+	0x605F, 0x9072, 0x6060, 0x9073, 0x6061, 0x9074, 0x6062, 0xBBD6,
+	0x6063, 0xEDA7, 0x6064, 0xD0F4, 0x6065, 0x9075, 0x6066, 0x9076,
+	0x6067, 0xEDA4, 0x6068, 0xBADE, 0x6069, 0xB6F7, 0x606A, 0xE3A1,
+	0x606B, 0xB6B2, 0x606C, 0xCCF1, 0x606D, 0xB9A7, 0x606E, 0x9077,
+	0x606F, 0xCFA2, 0x6070, 0xC7A1, 0x6071, 0x9078, 0x6072, 0x9079,
+	0x6073, 0xBFD2, 0x6074, 0x907A, 0x6075, 0x907B, 0x6076, 0xB6F1,
+	0x6077, 0x907C, 0x6078, 0xE2FA, 0x6079, 0xE2FB, 0x607A, 0xE2FD,
+	0x607B, 0xE2FC, 0x607C, 0xC4D5, 0x607D, 0xE3A2, 0x607E, 0x907D,
+	0x607F, 0xD3C1, 0x6080, 0x907E, 0x6081, 0x9080, 0x6082, 0x9081,
+	0x6083, 0xE3A7, 0x6084, 0xC7C4, 0x6085, 0x9082, 0x6086, 0x9083,
+	0x6087, 0x9084, 0x6088, 0x9085, 0x6089, 0xCFA4, 0x608A, 0x9086,
+	0x608B, 0x9087, 0x608C, 0xE3A9, 0x608D, 0xBAB7, 0x608E, 0x9088,
+	0x608F, 0x9089, 0x6090, 0x908A, 0x6091, 0x908B, 0x6092, 0xE3A8,
+	0x6093, 0x908C, 0x6094, 0xBBDA, 0x6095, 0x908D, 0x6096, 0xE3A3,
+	0x6097, 0x908E, 0x6098, 0x908F, 0x6099, 0x9090, 0x609A, 0xE3A4,
+	0x609B, 0xE3AA, 0x609C, 0x9091, 0x609D, 0xE3A6, 0x609E, 0x9092,
+	0x609F, 0xCEF2, 0x60A0, 0xD3C6, 0x60A1, 0x9093, 0x60A2, 0x9094,
+	0x60A3, 0xBBBC, 0x60A4, 0x9095, 0x60A5, 0x9096, 0x60A6, 0xD4C3,
+	0x60A7, 0x9097, 0x60A8, 0xC4FA, 0x60A9, 0x9098, 0x60AA, 0x9099,
+	0x60AB, 0xEDA8, 0x60AC, 0xD0FC, 0x60AD, 0xE3A5, 0x60AE, 0x909A,
+	0x60AF, 0xC3F5, 0x60B0, 0x909B, 0x60B1, 0xE3AD, 0x60B2, 0xB1AF,
+	0x60B3, 0x909C, 0x60B4, 0xE3B2, 0x60B5, 0x909D, 0x60B6, 0x909E,
+	0x60B7, 0x909F, 0x60B8, 0xBCC2, 0x60B9, 0x90A0, 0x60BA, 0x90A1,
+	0x60BB, 0xE3AC, 0x60BC, 0xB5BF, 0x60BD, 0x90A2, 0x60BE, 0x90A3,
+	0x60BF, 0x90A4, 0x60C0, 0x90A5, 0x60C1, 0x90A6, 0x60C2, 0x90A7,
+	0x60C3, 0x90A8, 0x60C4, 0x90A9, 0x60C5, 0xC7E9, 0x60C6, 0xE3B0,
+	0x60C7, 0x90AA, 0x60C8, 0x90AB, 0x60C9, 0x90AC, 0x60CA, 0xBEAA,
+	0x60CB, 0xCDEF, 0x60CC, 0x90AD, 0x60CD, 0x90AE, 0x60CE, 0x90AF,
+	0x60CF, 0x90B0, 0x60D0, 0x90B1, 0x60D1, 0xBBF3, 0x60D2, 0x90B2,
+	0x60D3, 0x90B3, 0x60D4, 0x90B4, 0x60D5, 0xCCE8, 0x60D6, 0x90B5,
+	0x60D7, 0x90B6, 0x60D8, 0xE3AF, 0x60D9, 0x90B7, 0x60DA, 0xE3B1,
+	0x60DB, 0x90B8, 0x60DC, 0xCFA7, 0x60DD, 0xE3AE, 0x60DE, 0x90B9,
+	0x60DF, 0xCEA9, 0x60E0, 0xBBDD, 0x60E1, 0x90BA, 0x60E2, 0x90BB,
+	0x60E3, 0x90BC, 0x60E4, 0x90BD, 0x60E5, 0x90BE, 0x60E6, 0xB5EB,
+	0x60E7, 0xBEE5, 0x60E8, 0xB2D2, 0x60E9, 0xB3CD, 0x60EA, 0x90BF,
+	0x60EB, 0xB1B9, 0x60EC, 0xE3AB, 0x60ED, 0xB2D1, 0x60EE, 0xB5AC,
+	0x60EF, 0xB9DF, 0x60F0, 0xB6E8, 0x60F1, 0x90C0, 0x60F2, 0x90C1,
+	0x60F3, 0xCFEB, 0x60F4, 0xE3B7, 0x60F5, 0x90C2, 0x60F6, 0xBBCC,
+	0x60F7, 0x90C3, 0x60F8, 0x90C4, 0x60F9, 0xC8C7, 0x60FA, 0xD0CA,
+	0x60FB, 0x90C5, 0x60FC, 0x90C6, 0x60FD, 0x90C7, 0x60FE, 0x90C8,
+	0x60FF, 0x90C9, 0x6100, 0xE3B8, 0x6101, 0xB3EE, 0x6102, 0x90CA,
+	0x6103, 0x90CB, 0x6104, 0x90CC, 0x6105, 0x90CD, 0x6106, 0xEDA9,
+	0x6107, 0x90CE, 0x6108, 0xD3FA, 0x6109, 0xD3E4, 0x610A, 0x90CF,
+	0x610B, 0x90D0, 0x610C, 0x90D1, 0x610D, 0xEDAA, 0x610E, 0xE3B9,
+	0x610F, 0xD2E2, 0x6110, 0x90D2, 0x6111, 0x90D3, 0x6112, 0x90D4,
+	0x6113, 0x90D5, 0x6114, 0x90D6, 0x6115, 0xE3B5, 0x6116, 0x90D7,
+	0x6117, 0x90D8, 0x6118, 0x90D9, 0x6119, 0x90DA, 0x611A, 0xD3DE,
+	0x611B, 0x90DB, 0x611C, 0x90DC, 0x611D, 0x90DD, 0x611E, 0x90DE,
+	0x611F, 0xB8D0, 0x6120, 0xE3B3, 0x6121, 0x90DF, 0x6122, 0x90E0,
+	0x6123, 0xE3B6, 0x6124, 0xB7DF, 0x6125, 0x90E1, 0x6126, 0xE3B4,
+	0x6127, 0xC0A2, 0x6128, 0x90E2, 0x6129, 0x90E3, 0x612A, 0x90E4,
+	0x612B, 0xE3BA, 0x612C, 0x90E5, 0x612D, 0x90E6, 0x612E, 0x90E7,
+	0x612F, 0x90E8, 0x6130, 0x90E9, 0x6131, 0x90EA, 0x6132, 0x90EB,
+	0x6133, 0x90EC, 0x6134, 0x90ED, 0x6135, 0x90EE, 0x6136, 0x90EF,
+	0x6137, 0x90F0, 0x6138, 0x90F1, 0x6139, 0x90F2, 0x613A, 0x90F3,
+	0x613B, 0x90F4, 0x613C, 0x90F5, 0x613D, 0x90F6, 0x613E, 0x90F7,
+	0x613F, 0xD4B8, 0x6140, 0x90F8, 0x6141, 0x90F9, 0x6142, 0x90FA,
+	0x6143, 0x90FB, 0x6144, 0x90FC, 0x6145, 0x90FD, 0x6146, 0x90FE,
+	0x6147, 0x9140, 0x6148, 0xB4C8, 0x6149, 0x9141, 0x614A, 0xE3BB,
+	0x614B, 0x9142, 0x614C, 0xBBC5, 0x614D, 0x9143, 0x614E, 0xC9F7,
+	0x614F, 0x9144, 0x6150, 0x9145, 0x6151, 0xC9E5, 0x6152, 0x9146,
+	0x6153, 0x9147, 0x6154, 0x9148, 0x6155, 0xC4BD, 0x6156, 0x9149,
+	0x6157, 0x914A, 0x6158, 0x914B, 0x6159, 0x914C, 0x615A, 0x914D,
+	0x615B, 0x914E, 0x615C, 0x914F, 0x615D, 0xEDAB, 0x615E, 0x9150,
+	0x615F, 0x9151, 0x6160, 0x9152, 0x6161, 0x9153, 0x6162, 0xC2FD,
+	0x6163, 0x9154, 0x6164, 0x9155, 0x6165, 0x9156, 0x6166, 0x9157,
+	0x6167, 0xBBDB, 0x6168, 0xBFAE, 0x6169, 0x9158, 0x616A, 0x9159,
+	0x616B, 0x915A, 0x616C, 0x915B, 0x616D, 0x915C, 0x616E, 0x915D,
+	0x616F, 0x915E, 0x6170, 0xCEBF, 0x6171, 0x915F, 0x6172, 0x9160,
+	0x6173, 0x9161, 0x6174, 0x9162, 0x6175, 0xE3BC, 0x6176, 0x9163,
+	0x6177, 0xBFB6, 0x6178, 0x9164, 0x6179, 0x9165, 0x617A, 0x9166,
+	0x617B, 0x9167, 0x617C, 0x9168, 0x617D, 0x9169, 0x617E, 0x916A,
+	0x617F, 0x916B, 0x6180, 0x916C, 0x6181, 0x916D, 0x6182, 0x916E,
+	0x6183, 0x916F, 0x6184, 0x9170, 0x6185, 0x9171, 0x6186, 0x9172,
+	0x6187, 0x9173, 0x6188, 0x9174, 0x6189, 0x9175, 0x618A, 0x9176,
+	0x618B, 0xB1EF, 0x618C, 0x9177, 0x618D, 0x9178, 0x618E, 0xD4F7,
+	0x618F, 0x9179, 0x6190, 0x917A, 0x6191, 0x917B, 0x6192, 0x917C,
+	0x6193, 0x917D, 0x6194, 0xE3BE, 0x6195, 0x917E, 0x6196, 0x9180,
+	0x6197, 0x9181, 0x6198, 0x9182, 0x6199, 0x9183, 0x619A, 0x9184,
+	0x619B, 0x9185, 0x619C, 0x9186, 0x619D, 0xEDAD, 0x619E, 0x9187,
+	0x619F, 0x9188, 0x61A0, 0x9189, 0x61A1, 0x918A, 0x61A2, 0x918B,
+	0x61A3, 0x918C, 0x61A4, 0x918D, 0x61A5, 0x918E, 0x61A6, 0x918F,
+	0x61A7, 0xE3BF, 0x61A8, 0xBAA9, 0x61A9, 0xEDAC, 0x61AA, 0x9190,
+	0x61AB, 0x9191, 0x61AC, 0xE3BD, 0x61AD, 0x9192, 0x61AE, 0x9193,
+	0x61AF, 0x9194, 0x61B0, 0x9195, 0x61B1, 0x9196, 0x61B2, 0x9197,
+	0x61B3, 0x9198, 0x61B4, 0x9199, 0x61B5, 0x919A, 0x61B6, 0x919B,
+	0x61B7, 0xE3C0, 0x61B8, 0x919C, 0x61B9, 0x919D, 0x61BA, 0x919E,
+	0x61BB, 0x919F, 0x61BC, 0x91A0, 0x61BD, 0x91A1, 0x61BE, 0xBAB6,
+	0x61BF, 0x91A2, 0x61C0, 0x91A3, 0x61C1, 0x91A4, 0x61C2, 0xB6AE,
+	0x61C3, 0x91A5, 0x61C4, 0x91A6, 0x61C5, 0x91A7, 0x61C6, 0x91A8,
+	0x61C7, 0x91A9, 0x61C8, 0xD0B8, 0x61C9, 0x91AA, 0x61CA, 0xB0C3,
+	0x61CB, 0xEDAE, 0x61CC, 0x91AB, 0x61CD, 0x91AC, 0x61CE, 0x91AD,
+	0x61CF, 0x91AE, 0x61D0, 0x91AF, 0x61D1, 0xEDAF, 0x61D2, 0xC0C1,
+	0x61D3, 0x91B0, 0x61D4, 0xE3C1, 0x61D5, 0x91B1, 0x61D6, 0x91B2,
+	0x61D7, 0x91B3, 0x61D8, 0x91B4, 0x61D9, 0x91B5, 0x61DA, 0x91B6,
+	0x61DB, 0x91B7, 0x61DC, 0x91B8, 0x61DD, 0x91B9, 0x61DE, 0x91BA,
+	0x61DF, 0x91BB, 0x61E0, 0x91BC, 0x61E1, 0x91BD, 0x61E2, 0x91BE,
+	0x61E3, 0x91BF, 0x61E4, 0x91C0, 0x61E5, 0x91C1, 0x61E6, 0xC5B3,
+	0x61E7, 0x91C2, 0x61E8, 0x91C3, 0x61E9, 0x91C4, 0x61EA, 0x91C5,
+	0x61EB, 0x91C6, 0x61EC, 0x91C7, 0x61ED, 0x91C8, 0x61EE, 0x91C9,
+	0x61EF, 0x91CA, 0x61F0, 0x91CB, 0x61F1, 0x91CC, 0x61F2, 0x91CD,
+	0x61F3, 0x91CE, 0x61F4, 0x91CF, 0x61F5, 0xE3C2, 0x61F6, 0x91D0,
+	0x61F7, 0x91D1, 0x61F8, 0x91D2, 0x61F9, 0x91D3, 0x61FA, 0x91D4,
+	0x61FB, 0x91D5, 0x61FC, 0x91D6, 0x61FD, 0x91D7, 0x61FE, 0x91D8,
+	0x61FF, 0xDCB2, 0x6200, 0x91D9, 0x6201, 0x91DA, 0x6202, 0x91DB,
+	0x6203, 0x91DC, 0x6204, 0x91DD, 0x6205, 0x91DE, 0x6206, 0xEDB0,
+	0x6207, 0x91DF, 0x6208, 0xB8EA, 0x6209, 0x91E0, 0x620A, 0xCEEC,
+	0x620B, 0xEAA7, 0x620C, 0xD0E7, 0x620D, 0xCAF9, 0x620E, 0xC8D6,
+	0x620F, 0xCFB7, 0x6210, 0xB3C9, 0x6211, 0xCED2, 0x6212, 0xBDE4,
+	0x6213, 0x91E1, 0x6214, 0x91E2, 0x6215, 0xE3DE, 0x6216, 0xBBF2,
+	0x6217, 0xEAA8, 0x6218, 0xD5BD, 0x6219, 0x91E3, 0x621A, 0xC6DD,
+	0x621B, 0xEAA9, 0x621C, 0x91E4, 0x621D, 0x91E5, 0x621E, 0x91E6,
+	0x621F, 0xEAAA, 0x6220, 0x91E7, 0x6221, 0xEAAC, 0x6222, 0xEAAB,
+	0x6223, 0x91E8, 0x6224, 0xEAAE, 0x6225, 0xEAAD, 0x6226, 0x91E9,
+	0x6227, 0x91EA, 0x6228, 0x91EB, 0x6229, 0x91EC, 0x622A, 0xBDD8,
+	0x622B, 0x91ED, 0x622C, 0xEAAF, 0x622D, 0x91EE, 0x622E, 0xC2BE,
+	0x622F, 0x91EF, 0x6230, 0x91F0, 0x6231, 0x91F1, 0x6232, 0x91F2,
+	0x6233, 0xB4C1, 0x6234, 0xB4F7, 0x6235, 0x91F3, 0x6236, 0x91F4,
+	0x6237, 0xBBA7, 0x6238, 0x91F5, 0x6239, 0x91F6, 0x623A, 0x91F7,
+	0x623B, 0x91F8, 0x623C, 0x91F9, 0x623D, 0xECE6, 0x623E, 0xECE5,
+	0x623F, 0xB7BF, 0x6240, 0xCBF9, 0x6241, 0xB1E2, 0x6242, 0x91FA,
+	0x6243, 0xECE7, 0x6244, 0x91FB, 0x6245, 0x91FC, 0x6246, 0x91FD,
+	0x6247, 0xC9C8, 0x6248, 0xECE8, 0x6249, 0xECE9, 0x624A, 0x91FE,
+	0x624B, 0xCAD6, 0x624C, 0xDED0, 0x624D, 0xB2C5, 0x624E, 0xD4FA,
+	0x624F, 0x9240, 0x6250, 0x9241, 0x6251, 0xC6CB, 0x6252, 0xB0C7,
+	0x6253, 0xB4F2, 0x6254, 0xC8D3, 0x6255, 0x9242, 0x6256, 0x9243,
+	0x6257, 0x9244, 0x6258, 0xCDD0, 0x6259, 0x9245, 0x625A, 0x9246,
+	0x625B, 0xBFB8, 0x625C, 0x9247, 0x625D, 0x9248, 0x625E, 0x9249,
+	0x625F, 0x924A, 0x6260, 0x924B, 0x6261, 0x924C, 0x6262, 0x924D,
+	0x6263, 0xBFDB, 0x6264, 0x924E, 0x6265, 0x924F, 0x6266, 0xC7A4,
+	0x6267, 0xD6B4, 0x6268, 0x9250, 0x6269, 0xC0A9, 0x626A, 0xDED1,
+	0x626B, 0xC9A8, 0x626C, 0xD1EF, 0x626D, 0xC5A4, 0x626E, 0xB0E7,
+	0x626F, 0xB3B6, 0x6270, 0xC8C5, 0x6271, 0x9251, 0x6272, 0x9252,
+	0x6273, 0xB0E2, 0x6274, 0x9253, 0x6275, 0x9254, 0x6276, 0xB7F6,
+	0x6277, 0x9255, 0x6278, 0x9256, 0x6279, 0xC5FA, 0x627A, 0x9257,
+	0x627B, 0x9258, 0x627C, 0xB6F3, 0x627D, 0x9259, 0x627E, 0xD5D2,
+	0x627F, 0xB3D0, 0x6280, 0xBCBC, 0x6281, 0x925A, 0x6282, 0x925B,
+	0x6283, 0x925C, 0x6284, 0xB3AD, 0x6285, 0x925D, 0x6286, 0x925E,
+	0x6287, 0x925F, 0x6288, 0x9260, 0x6289, 0xBEF1, 0x628A, 0xB0D1,
+	0x628B, 0x9261, 0x628C, 0x9262, 0x628D, 0x9263, 0x628E, 0x9264,
+	0x628F, 0x9265, 0x6290, 0x9266, 0x6291, 0xD2D6, 0x6292, 0xCAE3,
+	0x6293, 0xD7A5, 0x6294, 0x9267, 0x6295, 0xCDB6, 0x6296, 0xB6B6,
+	0x6297, 0xBFB9, 0x6298, 0xD5DB, 0x6299, 0x9268, 0x629A, 0xB8A7,
+	0x629B, 0xC5D7, 0x629C, 0x9269, 0x629D, 0x926A, 0x629E, 0x926B,
+	0x629F, 0xDED2, 0x62A0, 0xBFD9, 0x62A1, 0xC2D5, 0x62A2, 0xC7C0,
+	0x62A3, 0x926C, 0x62A4, 0xBBA4, 0x62A5, 0xB1A8, 0x62A6, 0x926D,
+	0x62A7, 0x926E, 0x62A8, 0xC5EA, 0x62A9, 0x926F, 0x62AA, 0x9270,
+	0x62AB, 0xC5FB, 0x62AC, 0xCCA7, 0x62AD, 0x9271, 0x62AE, 0x9272,
+	0x62AF, 0x9273, 0x62B0, 0x9274, 0x62B1, 0xB1A7, 0x62B2, 0x9275,
+	0x62B3, 0x9276, 0x62B4, 0x9277, 0x62B5, 0xB5D6, 0x62B6, 0x9278,
+	0x62B7, 0x9279, 0x62B8, 0x927A, 0x62B9, 0xC4A8, 0x62BA, 0x927B,
+	0x62BB, 0xDED3, 0x62BC, 0xD1BA, 0x62BD, 0xB3E9, 0x62BE, 0x927C,
+	0x62BF, 0xC3F2, 0x62C0, 0x927D, 0x62C1, 0x927E, 0x62C2, 0xB7F7,
+	0x62C3, 0x9280, 0x62C4, 0xD6F4, 0x62C5, 0xB5A3, 0x62C6, 0xB2F0,
+	0x62C7, 0xC4B4, 0x62C8, 0xC4E9, 0x62C9, 0xC0AD, 0x62CA, 0xDED4,
+	0x62CB, 0x9281, 0x62CC, 0xB0E8, 0x62CD, 0xC5C4, 0x62CE, 0xC1E0,
+	0x62CF, 0x9282, 0x62D0, 0xB9D5, 0x62D1, 0x9283, 0x62D2, 0xBEDC,
+	0x62D3, 0xCDD8, 0x62D4, 0xB0CE, 0x62D5, 0x9284, 0x62D6, 0xCDCF,
+	0x62D7, 0xDED6, 0x62D8, 0xBED0, 0x62D9, 0xD7BE, 0x62DA, 0xDED5,
+	0x62DB, 0xD5D0, 0x62DC, 0xB0DD, 0x62DD, 0x9285, 0x62DE, 0x9286,
+	0x62DF, 0xC4E2, 0x62E0, 0x9287, 0x62E1, 0x9288, 0x62E2, 0xC2A3,
+	0x62E3, 0xBCF0, 0x62E4, 0x9289, 0x62E5, 0xD3B5, 0x62E6, 0xC0B9,
+	0x62E7, 0xC5A1, 0x62E8, 0xB2A6, 0x62E9, 0xD4F1, 0x62EA, 0x928A,
+	0x62EB, 0x928B, 0x62EC, 0xC0A8, 0x62ED, 0xCAC3, 0x62EE, 0xDED7,
+	0x62EF, 0xD5FC, 0x62F0, 0x928C, 0x62F1, 0xB9B0, 0x62F2, 0x928D,
+	0x62F3, 0xC8AD, 0x62F4, 0xCBA9, 0x62F5, 0x928E, 0x62F6, 0xDED9,
+	0x62F7, 0xBFBD, 0x62F8, 0x928F, 0x62F9, 0x9290, 0x62FA, 0x9291,
+	0x62FB, 0x9292, 0x62FC, 0xC6B4, 0x62FD, 0xD7A7, 0x62FE, 0xCAB0,
+	0x62FF, 0xC4C3, 0x6300, 0x9293, 0x6301, 0xB3D6, 0x6302, 0xB9D2,
+	0x6303, 0x9294, 0x6304, 0x9295, 0x6305, 0x9296, 0x6306, 0x9297,
+	0x6307, 0xD6B8, 0x6308, 0xEAFC, 0x6309, 0xB0B4, 0x630A, 0x9298,
+	0x630B, 0x9299, 0x630C, 0x929A, 0x630D, 0x929B, 0x630E, 0xBFE6,
+	0x630F, 0x929C, 0x6310, 0x929D, 0x6311, 0xCCF4, 0x6312, 0x929E,
+	0x6313, 0x929F, 0x6314, 0x92A0, 0x6315, 0x92A1, 0x6316, 0xCDDA,
+	0x6317, 0x92A2, 0x6318, 0x92A3, 0x6319, 0x92A4, 0x631A, 0xD6BF,
+	0x631B, 0xC2CE, 0x631C, 0x92A5, 0x631D, 0xCECE, 0x631E, 0xCCA2,
+	0x631F, 0xD0AE, 0x6320, 0xC4D3, 0x6321, 0xB5B2, 0x6322, 0xDED8,
+	0x6323, 0xD5F5, 0x6324, 0xBCB7, 0x6325, 0xBBD3, 0x6326, 0x92A6,
+	0x6327, 0x92A7, 0x6328, 0xB0A4, 0x6329, 0x92A8, 0x632A, 0xC5B2,
+	0x632B, 0xB4EC, 0x632C, 0x92A9, 0x632D, 0x92AA, 0x632E, 0x92AB,
+	0x632F, 0xD5F1, 0x6330, 0x92AC, 0x6331, 0x92AD, 0x6332, 0xEAFD,
+	0x6333, 0x92AE, 0x6334, 0x92AF, 0x6335, 0x92B0, 0x6336, 0x92B1,
+	0x6337, 0x92B2, 0x6338, 0x92B3, 0x6339, 0xDEDA, 0x633A, 0xCDA6,
+	0x633B, 0x92B4, 0x633C, 0x92B5, 0x633D, 0xCDEC, 0x633E, 0x92B6,
+	0x633F, 0x92B7, 0x6340, 0x92B8, 0x6341, 0x92B9, 0x6342, 0xCEE6,
+	0x6343, 0xDEDC, 0x6344, 0x92BA, 0x6345, 0xCDB1, 0x6346, 0xC0A6,
+	0x6347, 0x92BB, 0x6348, 0x92BC, 0x6349, 0xD7BD, 0x634A, 0x92BD,
+	0x634B, 0xDEDB, 0x634C, 0xB0C6, 0x634D, 0xBAB4, 0x634E, 0xC9D3,
+	0x634F, 0xC4F3, 0x6350, 0xBEE8, 0x6351, 0x92BE, 0x6352, 0x92BF,
+	0x6353, 0x92C0, 0x6354, 0x92C1, 0x6355, 0xB2B6, 0x6356, 0x92C2,
+	0x6357, 0x92C3, 0x6358, 0x92C4, 0x6359, 0x92C5, 0x635A, 0x92C6,
+	0x635B, 0x92C7, 0x635C, 0x92C8, 0x635D, 0x92C9, 0x635E, 0xC0CC,
+	0x635F, 0xCBF0, 0x6360, 0x92CA, 0x6361, 0xBCF1, 0x6362, 0xBBBB,
+	0x6363, 0xB5B7, 0x6364, 0x92CB, 0x6365, 0x92CC, 0x6366, 0x92CD,
+	0x6367, 0xC5F5, 0x6368, 0x92CE, 0x6369, 0xDEE6, 0x636A, 0x92CF,
+	0x636B, 0x92D0, 0x636C, 0x92D1, 0x636D, 0xDEE3, 0x636E, 0xBEDD,
+	0x636F, 0x92D2, 0x6370, 0x92D3, 0x6371, 0xDEDF, 0x6372, 0x92D4,
+	0x6373, 0x92D5, 0x6374, 0x92D6, 0x6375, 0x92D7, 0x6376, 0xB4B7,
+	0x6377, 0xBDDD, 0x6378, 0x92D8, 0x6379, 0x92D9, 0x637A, 0xDEE0,
+	0x637B, 0xC4ED, 0x637C, 0x92DA, 0x637D, 0x92DB, 0x637E, 0x92DC,
+	0x637F, 0x92DD, 0x6380, 0xCFC6, 0x6381, 0x92DE, 0x6382, 0xB5E0,
+	0x6383, 0x92DF, 0x6384, 0x92E0, 0x6385, 0x92E1, 0x6386, 0x92E2,
+	0x6387, 0xB6DE, 0x6388, 0xCADA, 0x6389, 0xB5F4, 0x638A, 0xDEE5,
+	0x638B, 0x92E3, 0x638C, 0xD5C6, 0x638D, 0x92E4, 0x638E, 0xDEE1,
+	0x638F, 0xCCCD, 0x6390, 0xC6FE, 0x6391, 0x92E5, 0x6392, 0xC5C5,
+	0x6393, 0x92E6, 0x6394, 0x92E7, 0x6395, 0x92E8, 0x6396, 0xD2B4,
+	0x6397, 0x92E9, 0x6398, 0xBEF2, 0x6399, 0x92EA, 0x639A, 0x92EB,
+	0x639B, 0x92EC, 0x639C, 0x92ED, 0x639D, 0x92EE, 0x639E, 0x92EF,
+	0x639F, 0x92F0, 0x63A0, 0xC2D3, 0x63A1, 0x92F1, 0x63A2, 0xCCBD,
+	0x63A3, 0xB3B8, 0x63A4, 0x92F2, 0x63A5, 0xBDD3, 0x63A6, 0x92F3,
+	0x63A7, 0xBFD8, 0x63A8, 0xCDC6, 0x63A9, 0xD1DA, 0x63AA, 0xB4EB,
+	0x63AB, 0x92F4, 0x63AC, 0xDEE4, 0x63AD, 0xDEDD, 0x63AE, 0xDEE7,
+	0x63AF, 0x92F5, 0x63B0, 0xEAFE, 0x63B1, 0x92F6, 0x63B2, 0x92F7,
+	0x63B3, 0xC2B0, 0x63B4, 0xDEE2, 0x63B5, 0x92F8, 0x63B6, 0x92F9,
+	0x63B7, 0xD6C0, 0x63B8, 0xB5A7, 0x63B9, 0x92FA, 0x63BA, 0xB2F4,
+	0x63BB, 0x92FB, 0x63BC, 0xDEE8, 0x63BD, 0x92FC, 0x63BE, 0xDEF2,
+	0x63BF, 0x92FD, 0x63C0, 0x92FE, 0x63C1, 0x9340, 0x63C2, 0x9341,
+	0x63C3, 0x9342, 0x63C4, 0xDEED, 0x63C5, 0x9343, 0x63C6, 0xDEF1,
+	0x63C7, 0x9344, 0x63C8, 0x9345, 0x63C9, 0xC8E0, 0x63CA, 0x9346,
+	0x63CB, 0x9347, 0x63CC, 0x9348, 0x63CD, 0xD7E1, 0x63CE, 0xDEEF,
+	0x63CF, 0xC3E8, 0x63D0, 0xCCE1, 0x63D1, 0x9349, 0x63D2, 0xB2E5,
+	0x63D3, 0x934A, 0x63D4, 0x934B, 0x63D5, 0x934C, 0x63D6, 0xD2BE,
+	0x63D7, 0x934D, 0x63D8, 0x934E, 0x63D9, 0x934F, 0x63DA, 0x9350,
+	0x63DB, 0x9351, 0x63DC, 0x9352, 0x63DD, 0x9353, 0x63DE, 0xDEEE,
+	0x63DF, 0x9354, 0x63E0, 0xDEEB, 0x63E1, 0xCED5, 0x63E2, 0x9355,
+	0x63E3, 0xB4A7, 0x63E4, 0x9356, 0x63E5, 0x9357, 0x63E6, 0x9358,
+	0x63E7, 0x9359, 0x63E8, 0x935A, 0x63E9, 0xBFAB, 0x63EA, 0xBEBE,
+	0x63EB, 0x935B, 0x63EC, 0x935C, 0x63ED, 0xBDD2, 0x63EE, 0x935D,
+	0x63EF, 0x935E, 0x63F0, 0x935F, 0x63F1, 0x9360, 0x63F2, 0xDEE9,
+	0x63F3, 0x9361, 0x63F4, 0xD4AE, 0x63F5, 0x9362, 0x63F6, 0xDEDE,
+	0x63F7, 0x9363, 0x63F8, 0xDEEA, 0x63F9, 0x9364, 0x63FA, 0x9365,
+	0x63FB, 0x9366, 0x63FC, 0x9367, 0x63FD, 0xC0BF, 0x63FE, 0x9368,
+	0x63FF, 0xDEEC, 0x6400, 0xB2F3, 0x6401, 0xB8E9, 0x6402, 0xC2A7,
+	0x6403, 0x9369, 0x6404, 0x936A, 0x6405, 0xBDC1, 0x6406, 0x936B,
+	0x6407, 0x936C, 0x6408, 0x936D, 0x6409, 0x936E, 0x640A, 0x936F,
+	0x640B, 0xDEF5, 0x640C, 0xDEF8, 0x640D, 0x9370, 0x640E, 0x9371,
+	0x640F, 0xB2AB, 0x6410, 0xB4A4, 0x6411, 0x9372, 0x6412, 0x9373,
+	0x6413, 0xB4EA, 0x6414, 0xC9A6, 0x6415, 0x9374, 0x6416, 0x9375,
+	0x6417, 0x9376, 0x6418, 0x9377, 0x6419, 0x9378, 0x641A, 0x9379,
+	0x641B, 0xDEF6, 0x641C, 0xCBD1, 0x641D, 0x937A, 0x641E, 0xB8E3,
+	0x641F, 0x937B, 0x6420, 0xDEF7, 0x6421, 0xDEFA, 0x6422, 0x937C,
+	0x6423, 0x937D, 0x6424, 0x937E, 0x6425, 0x9380, 0x6426, 0xDEF9,
+	0x6427, 0x9381, 0x6428, 0x9382, 0x6429, 0x9383, 0x642A, 0xCCC2,
+	0x642B, 0x9384, 0x642C, 0xB0E1, 0x642D, 0xB4EE, 0x642E, 0x9385,
+	0x642F, 0x9386, 0x6430, 0x9387, 0x6431, 0x9388, 0x6432, 0x9389,
+	0x6433, 0x938A, 0x6434, 0xE5BA, 0x6435, 0x938B, 0x6436, 0x938C,
+	0x6437, 0x938D, 0x6438, 0x938E, 0x6439, 0x938F, 0x643A, 0xD0AF,
+	0x643B, 0x9390, 0x643C, 0x9391, 0x643D, 0xB2EB, 0x643E, 0x9392,
+	0x643F, 0xEBA1, 0x6440, 0x9393, 0x6441, 0xDEF4, 0x6442, 0x9394,
+	0x6443, 0x9395, 0x6444, 0xC9E3, 0x6445, 0xDEF3, 0x6446, 0xB0DA,
+	0x6447, 0xD2A1, 0x6448, 0xB1F7, 0x6449, 0x9396, 0x644A, 0xCCAF,
+	0x644B, 0x9397, 0x644C, 0x9398, 0x644D, 0x9399, 0x644E, 0x939A,
+	0x644F, 0x939B, 0x6450, 0x939C, 0x6451, 0x939D, 0x6452, 0xDEF0,
+	0x6453, 0x939E, 0x6454, 0xCBA4, 0x6455, 0x939F, 0x6456, 0x93A0,
+	0x6457, 0x93A1, 0x6458, 0xD5AA, 0x6459, 0x93A2, 0x645A, 0x93A3,
+	0x645B, 0x93A4, 0x645C, 0x93A5, 0x645D, 0x93A6, 0x645E, 0xDEFB,
+	0x645F, 0x93A7, 0x6460, 0x93A8, 0x6461, 0x93A9, 0x6462, 0x93AA,
+	0x6463, 0x93AB, 0x6464, 0x93AC, 0x6465, 0x93AD, 0x6466, 0x93AE,
+	0x6467, 0xB4DD, 0x6468, 0x93AF, 0x6469, 0xC4A6, 0x646A, 0x93B0,
+	0x646B, 0x93B1, 0x646C, 0x93B2, 0x646D, 0xDEFD, 0x646E, 0x93B3,
+	0x646F, 0x93B4, 0x6470, 0x93B5, 0x6471, 0x93B6, 0x6472, 0x93B7,
+	0x6473, 0x93B8, 0x6474, 0x93B9, 0x6475, 0x93BA, 0x6476, 0x93BB,
+	0x6477, 0x93BC, 0x6478, 0xC3FE, 0x6479, 0xC4A1, 0x647A, 0xDFA1,
+	0x647B, 0x93BD, 0x647C, 0x93BE, 0x647D, 0x93BF, 0x647E, 0x93C0,
+	0x647F, 0x93C1, 0x6480, 0x93C2, 0x6481, 0x93C3, 0x6482, 0xC1CC,
+	0x6483, 0x93C4, 0x6484, 0xDEFC, 0x6485, 0xBEEF, 0x6486, 0x93C5,
+	0x6487, 0xC6B2, 0x6488, 0x93C6, 0x6489, 0x93C7, 0x648A, 0x93C8,
+	0x648B, 0x93C9, 0x648C, 0x93CA, 0x648D, 0x93CB, 0x648E, 0x93CC,
+	0x648F, 0x93CD, 0x6490, 0x93CE, 0x6491, 0xB3C5, 0x6492, 0xC8F6,
+	0x6493, 0x93CF, 0x6494, 0x93D0, 0x6495, 0xCBBA, 0x6496, 0xDEFE,
+	0x6497, 0x93D1, 0x6498, 0x93D2, 0x6499, 0xDFA4, 0x649A, 0x93D3,
+	0x649B, 0x93D4, 0x649C, 0x93D5, 0x649D, 0x93D6, 0x649E, 0xD7B2,
+	0x649F, 0x93D7, 0x64A0, 0x93D8, 0x64A1, 0x93D9, 0x64A2, 0x93DA,
+	0x64A3, 0x93DB, 0x64A4, 0xB3B7, 0x64A5, 0x93DC, 0x64A6, 0x93DD,
+	0x64A7, 0x93DE, 0x64A8, 0x93DF, 0x64A9, 0xC1C3, 0x64AA, 0x93E0,
+	0x64AB, 0x93E1, 0x64AC, 0xC7CB, 0x64AD, 0xB2A5, 0x64AE, 0xB4E9,
+	0x64AF, 0x93E2, 0x64B0, 0xD7AB, 0x64B1, 0x93E3, 0x64B2, 0x93E4,
+	0x64B3, 0x93E5, 0x64B4, 0x93E6, 0x64B5, 0xC4EC, 0x64B6, 0x93E7,
+	0x64B7, 0xDFA2, 0x64B8, 0xDFA3, 0x64B9, 0x93E8, 0x64BA, 0xDFA5,
+	0x64BB, 0x93E9, 0x64BC, 0xBAB3, 0x64BD, 0x93EA, 0x64BE, 0x93EB,
+	0x64BF, 0x93EC, 0x64C0, 0xDFA6, 0x64C1, 0x93ED, 0x64C2, 0xC0DE,
+	0x64C3, 0x93EE, 0x64C4, 0x93EF, 0x64C5, 0xC9C3, 0x64C6, 0x93F0,
+	0x64C7, 0x93F1, 0x64C8, 0x93F2, 0x64C9, 0x93F3, 0x64CA, 0x93F4,
+	0x64CB, 0x93F5, 0x64CC, 0x93F6, 0x64CD, 0xB2D9, 0x64CE, 0xC7E6,
+	0x64CF, 0x93F7, 0x64D0, 0xDFA7, 0x64D1, 0x93F8, 0x64D2, 0xC7DC,
+	0x64D3, 0x93F9, 0x64D4, 0x93FA, 0x64D5, 0x93FB, 0x64D6, 0x93FC,
+	0x64D7, 0xDFA8, 0x64D8, 0xEBA2, 0x64D9, 0x93FD, 0x64DA, 0x93FE,
+	0x64DB, 0x9440, 0x64DC, 0x9441, 0x64DD, 0x9442, 0x64DE, 0xCBD3,
+	0x64DF, 0x9443, 0x64E0, 0x9444, 0x64E1, 0x9445, 0x64E2, 0xDFAA,
+	0x64E3, 0x9446, 0x64E4, 0xDFA9, 0x64E5, 0x9447, 0x64E6, 0xB2C1,
+	0x64E7, 0x9448, 0x64E8, 0x9449, 0x64E9, 0x944A, 0x64EA, 0x944B,
+	0x64EB, 0x944C, 0x64EC, 0x944D, 0x64ED, 0x944E, 0x64EE, 0x944F,
+	0x64EF, 0x9450, 0x64F0, 0x9451, 0x64F1, 0x9452, 0x64F2, 0x9453,
+	0x64F3, 0x9454, 0x64F4, 0x9455, 0x64F5, 0x9456, 0x64F6, 0x9457,
+	0x64F7, 0x9458, 0x64F8, 0x9459, 0x64F9, 0x945A, 0x64FA, 0x945B,
+	0x64FB, 0x945C, 0x64FC, 0x945D, 0x64FD, 0x945E, 0x64FE, 0x945F,
+	0x64FF, 0x9460, 0x6500, 0xC5CA, 0x6501, 0x9461, 0x6502, 0x9462,
+	0x6503, 0x9463, 0x6504, 0x9464, 0x6505, 0x9465, 0x6506, 0x9466,
+	0x6507, 0x9467, 0x6508, 0x9468, 0x6509, 0xDFAB, 0x650A, 0x9469,
+	0x650B, 0x946A, 0x650C, 0x946B, 0x650D, 0x946C, 0x650E, 0x946D,
+	0x650F, 0x946E, 0x6510, 0x946F, 0x6511, 0x9470, 0x6512, 0xD4DC,
+	0x6513, 0x9471, 0x6514, 0x9472, 0x6515, 0x9473, 0x6516, 0x9474,
+	0x6517, 0x9475, 0x6518, 0xC8C1, 0x6519, 0x9476, 0x651A, 0x9477,
+	0x651B, 0x9478, 0x651C, 0x9479, 0x651D, 0x947A, 0x651E, 0x947B,
+	0x651F, 0x947C, 0x6520, 0x947D, 0x6521, 0x947E, 0x6522, 0x9480,
+	0x6523, 0x9481, 0x6524, 0x9482, 0x6525, 0xDFAC, 0x6526, 0x9483,
+	0x6527, 0x9484, 0x6528, 0x9485, 0x6529, 0x9486, 0x652A, 0x9487,
+	0x652B, 0xBEF0, 0x652C, 0x9488, 0x652D, 0x9489, 0x652E, 0xDFAD,
+	0x652F, 0xD6A7, 0x6530, 0x948A, 0x6531, 0x948B, 0x6532, 0x948C,
+	0x6533, 0x948D, 0x6534, 0xEAB7, 0x6535, 0xEBB6, 0x6536, 0xCAD5,
+	0x6537, 0x948E, 0x6538, 0xD8FC, 0x6539, 0xB8C4, 0x653A, 0x948F,
+	0x653B, 0xB9A5, 0x653C, 0x9490, 0x653D, 0x9491, 0x653E, 0xB7C5,
+	0x653F, 0xD5FE, 0x6540, 0x9492, 0x6541, 0x9493, 0x6542, 0x9494,
+	0x6543, 0x9495, 0x6544, 0x9496, 0x6545, 0xB9CA, 0x6546, 0x9497,
+	0x6547, 0x9498, 0x6548, 0xD0A7, 0x6549, 0xF4CD, 0x654A, 0x9499,
+	0x654B, 0x949A, 0x654C, 0xB5D0, 0x654D, 0x949B, 0x654E, 0x949C,
+	0x654F, 0xC3F4, 0x6550, 0x949D, 0x6551, 0xBEC8, 0x6552, 0x949E,
+	0x6553, 0x949F, 0x6554, 0x94A0, 0x6555, 0xEBB7, 0x6556, 0xB0BD,
+	0x6557, 0x94A1, 0x6558, 0x94A2, 0x6559, 0xBDCC, 0x655A, 0x94A3,
+	0x655B, 0xC1B2, 0x655C, 0x94A4, 0x655D, 0xB1D6, 0x655E, 0xB3A8,
+	0x655F, 0x94A5, 0x6560, 0x94A6, 0x6561, 0x94A7, 0x6562, 0xB8D2,
+	0x6563, 0xC9A2, 0x6564, 0x94A8, 0x6565, 0x94A9, 0x6566, 0xB6D8,
+	0x6567, 0x94AA, 0x6568, 0x94AB, 0x6569, 0x94AC, 0x656A, 0x94AD,
+	0x656B, 0xEBB8, 0x656C, 0xBEB4, 0x656D, 0x94AE, 0x656E, 0x94AF,
+	0x656F, 0x94B0, 0x6570, 0xCAFD, 0x6571, 0x94B1, 0x6572, 0xC7C3,
+	0x6573, 0x94B2, 0x6574, 0xD5FB, 0x6575, 0x94B3, 0x6576, 0x94B4,
+	0x6577, 0xB7F3, 0x6578, 0x94B5, 0x6579, 0x94B6, 0x657A, 0x94B7,
+	0x657B, 0x94B8, 0x657C, 0x94B9, 0x657D, 0x94BA, 0x657E, 0x94BB,
+	0x657F, 0x94BC, 0x6580, 0x94BD, 0x6581, 0x94BE, 0x6582, 0x94BF,
+	0x6583, 0x94C0, 0x6584, 0x94C1, 0x6585, 0x94C2, 0x6586, 0x94C3,
+	0x6587, 0xCEC4, 0x6588, 0x94C4, 0x6589, 0x94C5, 0x658A, 0x94C6,
+	0x658B, 0xD5AB, 0x658C, 0xB1F3, 0x658D, 0x94C7, 0x658E, 0x94C8,
+	0x658F, 0x94C9, 0x6590, 0xECB3, 0x6591, 0xB0DF, 0x6592, 0x94CA,
+	0x6593, 0xECB5, 0x6594, 0x94CB, 0x6595, 0x94CC, 0x6596, 0x94CD,
+	0x6597, 0xB6B7, 0x6598, 0x94CE, 0x6599, 0xC1CF, 0x659A, 0x94CF,
+	0x659B, 0xF5FA, 0x659C, 0xD0B1, 0x659D, 0x94D0, 0x659E, 0x94D1,
+	0x659F, 0xD5E5, 0x65A0, 0x94D2, 0x65A1, 0xCED3, 0x65A2, 0x94D3,
+	0x65A3, 0x94D4, 0x65A4, 0xBDEF, 0x65A5, 0xB3E2, 0x65A6, 0x94D5,
+	0x65A7, 0xB8AB, 0x65A8, 0x94D6, 0x65A9, 0xD5B6, 0x65AA, 0x94D7,
+	0x65AB, 0xEDBD, 0x65AC, 0x94D8, 0x65AD, 0xB6CF, 0x65AE, 0x94D9,
+	0x65AF, 0xCBB9, 0x65B0, 0xD0C2, 0x65B1, 0x94DA, 0x65B2, 0x94DB,
+	0x65B3, 0x94DC, 0x65B4, 0x94DD, 0x65B5, 0x94DE, 0x65B6, 0x94DF,
+	0x65B7, 0x94E0, 0x65B8, 0x94E1, 0x65B9, 0xB7BD, 0x65BA, 0x94E2,
+	0x65BB, 0x94E3, 0x65BC, 0xECB6, 0x65BD, 0xCAA9, 0x65BE, 0x94E4,
+	0x65BF, 0x94E5, 0x65C0, 0x94E6, 0x65C1, 0xC5D4, 0x65C2, 0x94E7,
+	0x65C3, 0xECB9, 0x65C4, 0xECB8, 0x65C5, 0xC2C3, 0x65C6, 0xECB7,
+	0x65C7, 0x94E8, 0x65C8, 0x94E9, 0x65C9, 0x94EA, 0x65CA, 0x94EB,
+	0x65CB, 0xD0FD, 0x65CC, 0xECBA, 0x65CD, 0x94EC, 0x65CE, 0xECBB,
+	0x65CF, 0xD7E5, 0x65D0, 0x94ED, 0x65D1, 0x94EE, 0x65D2, 0xECBC,
+	0x65D3, 0x94EF, 0x65D4, 0x94F0, 0x65D5, 0x94F1, 0x65D6, 0xECBD,
+	0x65D7, 0xC6EC, 0x65D8, 0x94F2, 0x65D9, 0x94F3, 0x65DA, 0x94F4,
+	0x65DB, 0x94F5, 0x65DC, 0x94F6, 0x65DD, 0x94F7, 0x65DE, 0x94F8,
+	0x65DF, 0x94F9, 0x65E0, 0xCEDE, 0x65E1, 0x94FA, 0x65E2, 0xBCC8,
+	0x65E3, 0x94FB, 0x65E4, 0x94FC, 0x65E5, 0xC8D5, 0x65E6, 0xB5A9,
+	0x65E7, 0xBEC9, 0x65E8, 0xD6BC, 0x65E9, 0xD4E7, 0x65EA, 0x94FD,
+	0x65EB, 0x94FE, 0x65EC, 0xD1AE, 0x65ED, 0xD0F1, 0x65EE, 0xEAB8,
+	0x65EF, 0xEAB9, 0x65F0, 0xEABA, 0x65F1, 0xBAB5, 0x65F2, 0x9540,
+	0x65F3, 0x9541, 0x65F4, 0x9542, 0x65F5, 0x9543, 0x65F6, 0xCAB1,
+	0x65F7, 0xBFF5, 0x65F8, 0x9544, 0x65F9, 0x9545, 0x65FA, 0xCDFA,
+	0x65FB, 0x9546, 0x65FC, 0x9547, 0x65FD, 0x9548, 0x65FE, 0x9549,
+	0x65FF, 0x954A, 0x6600, 0xEAC0, 0x6601, 0x954B, 0x6602, 0xB0BA,
+	0x6603, 0xEABE, 0x6604, 0x954C, 0x6605, 0x954D, 0x6606, 0xC0A5,
+	0x6607, 0x954E, 0x6608, 0x954F, 0x6609, 0x9550, 0x660A, 0xEABB,
+	0x660B, 0x9551, 0x660C, 0xB2FD, 0x660D, 0x9552, 0x660E, 0xC3F7,
+	0x660F, 0xBBE8, 0x6610, 0x9553, 0x6611, 0x9554, 0x6612, 0x9555,
+	0x6613, 0xD2D7, 0x6614, 0xCEF4, 0x6615, 0xEABF, 0x6616, 0x9556,
+	0x6617, 0x9557, 0x6618, 0x9558, 0x6619, 0xEABC, 0x661A, 0x9559,
+	0x661B, 0x955A, 0x661C, 0x955B, 0x661D, 0xEAC3, 0x661E, 0x955C,
+	0x661F, 0xD0C7, 0x6620, 0xD3B3, 0x6621, 0x955D, 0x6622, 0x955E,
+	0x6623, 0x955F, 0x6624, 0x9560, 0x6625, 0xB4BA, 0x6626, 0x9561,
+	0x6627, 0xC3C1, 0x6628, 0xD7F2, 0x6629, 0x9562, 0x662A, 0x9563,
+	0x662B, 0x9564, 0x662C, 0x9565, 0x662D, 0xD5D1, 0x662E, 0x9566,
+	0x662F, 0xCAC7, 0x6630, 0x9567, 0x6631, 0xEAC5, 0x6632, 0x9568,
+	0x6633, 0x9569, 0x6634, 0xEAC4, 0x6635, 0xEAC7, 0x6636, 0xEAC6,
+	0x6637, 0x956A, 0x6638, 0x956B, 0x6639, 0x956C, 0x663A, 0x956D,
+	0x663B, 0x956E, 0x663C, 0xD6E7, 0x663D, 0x956F, 0x663E, 0xCFD4,
+	0x663F, 0x9570, 0x6640, 0x9571, 0x6641, 0xEACB, 0x6642, 0x9572,
+	0x6643, 0xBBCE, 0x6644, 0x9573, 0x6645, 0x9574, 0x6646, 0x9575,
+	0x6647, 0x9576, 0x6648, 0x9577, 0x6649, 0x9578, 0x664A, 0x9579,
+	0x664B, 0xBDFA, 0x664C, 0xC9CE, 0x664D, 0x957A, 0x664E, 0x957B,
+	0x664F, 0xEACC, 0x6650, 0x957C, 0x6651, 0x957D, 0x6652, 0xC9B9,
+	0x6653, 0xCFFE, 0x6654, 0xEACA, 0x6655, 0xD4CE, 0x6656, 0xEACD,
+	0x6657, 0xEACF, 0x6658, 0x957E, 0x6659, 0x9580, 0x665A, 0xCDED,
+	0x665B, 0x9581, 0x665C, 0x9582, 0x665D, 0x9583, 0x665E, 0x9584,
+	0x665F, 0xEAC9, 0x6660, 0x9585, 0x6661, 0xEACE, 0x6662, 0x9586,
+	0x6663, 0x9587, 0x6664, 0xCEEE, 0x6665, 0x9588, 0x6666, 0xBBDE,
+	0x6667, 0x9589, 0x6668, 0xB3BF, 0x6669, 0x958A, 0x666A, 0x958B,
+	0x666B, 0x958C, 0x666C, 0x958D, 0x666D, 0x958E, 0x666E, 0xC6D5,
+	0x666F, 0xBEB0, 0x6670, 0xCEFA, 0x6671, 0x958F, 0x6672, 0x9590,
+	0x6673, 0x9591, 0x6674, 0xC7E7, 0x6675, 0x9592, 0x6676, 0xBEA7,
+	0x6677, 0xEAD0, 0x6678, 0x9593, 0x6679, 0x9594, 0x667A, 0xD6C7,
+	0x667B, 0x9595, 0x667C, 0x9596, 0x667D, 0x9597, 0x667E, 0xC1C0,
+	0x667F, 0x9598, 0x6680, 0x9599, 0x6681, 0x959A, 0x6682, 0xD4DD,
+	0x6683, 0x959B, 0x6684, 0xEAD1, 0x6685, 0x959C, 0x6686, 0x959D,
+	0x6687, 0xCFBE, 0x6688, 0x959E, 0x6689, 0x959F, 0x668A, 0x95A0,
+	0x668B, 0x95A1, 0x668C, 0xEAD2, 0x668D, 0x95A2, 0x668E, 0x95A3,
+	0x668F, 0x95A4, 0x6690, 0x95A5, 0x6691, 0xCAEE, 0x6692, 0x95A6,
+	0x6693, 0x95A7, 0x6694, 0x95A8, 0x6695, 0x95A9, 0x6696, 0xC5AF,
+	0x6697, 0xB0B5, 0x6698, 0x95AA, 0x6699, 0x95AB, 0x669A, 0x95AC,
+	0x669B, 0x95AD, 0x669C, 0x95AE, 0x669D, 0xEAD4, 0x669E, 0x95AF,
+	0x669F, 0x95B0, 0x66A0, 0x95B1, 0x66A1, 0x95B2, 0x66A2, 0x95B3,
+	0x66A3, 0x95B4, 0x66A4, 0x95B5, 0x66A5, 0x95B6, 0x66A6, 0x95B7,
+	0x66A7, 0xEAD3, 0x66A8, 0xF4DF, 0x66A9, 0x95B8, 0x66AA, 0x95B9,
+	0x66AB, 0x95BA, 0x66AC, 0x95BB, 0x66AD, 0x95BC, 0x66AE, 0xC4BA,
+	0x66AF, 0x95BD, 0x66B0, 0x95BE, 0x66B1, 0x95BF, 0x66B2, 0x95C0,
+	0x66B3, 0x95C1, 0x66B4, 0xB1A9, 0x66B5, 0x95C2, 0x66B6, 0x95C3,
+	0x66B7, 0x95C4, 0x66B8, 0x95C5, 0x66B9, 0xE5DF, 0x66BA, 0x95C6,
+	0x66BB, 0x95C7, 0x66BC, 0x95C8, 0x66BD, 0x95C9, 0x66BE, 0xEAD5,
+	0x66BF, 0x95CA, 0x66C0, 0x95CB, 0x66C1, 0x95CC, 0x66C2, 0x95CD,
+	0x66C3, 0x95CE, 0x66C4, 0x95CF, 0x66C5, 0x95D0, 0x66C6, 0x95D1,
+	0x66C7, 0x95D2, 0x66C8, 0x95D3, 0x66C9, 0x95D4, 0x66CA, 0x95D5,
+	0x66CB, 0x95D6, 0x66CC, 0x95D7, 0x66CD, 0x95D8, 0x66CE, 0x95D9,
+	0x66CF, 0x95DA, 0x66D0, 0x95DB, 0x66D1, 0x95DC, 0x66D2, 0x95DD,
+	0x66D3, 0x95DE, 0x66D4, 0x95DF, 0x66D5, 0x95E0, 0x66D6, 0x95E1,
+	0x66D7, 0x95E2, 0x66D8, 0x95E3, 0x66D9, 0xCAEF, 0x66DA, 0x95E4,
+	0x66DB, 0xEAD6, 0x66DC, 0xEAD7, 0x66DD, 0xC6D8, 0x66DE, 0x95E5,
+	0x66DF, 0x95E6, 0x66E0, 0x95E7, 0x66E1, 0x95E8, 0x66E2, 0x95E9,
+	0x66E3, 0x95EA, 0x66E4, 0x95EB, 0x66E5, 0x95EC, 0x66E6, 0xEAD8,
+	0x66E7, 0x95ED, 0x66E8, 0x95EE, 0x66E9, 0xEAD9, 0x66EA, 0x95EF,
+	0x66EB, 0x95F0, 0x66EC, 0x95F1, 0x66ED, 0x95F2, 0x66EE, 0x95F3,
+	0x66EF, 0x95F4, 0x66F0, 0xD4BB, 0x66F1, 0x95F5, 0x66F2, 0xC7FA,
+	0x66F3, 0xD2B7, 0x66F4, 0xB8FC, 0x66F5, 0x95F6, 0x66F6, 0x95F7,
+	0x66F7, 0xEAC2, 0x66F8, 0x95F8, 0x66F9, 0xB2DC, 0x66FA, 0x95F9,
+	0x66FB, 0x95FA, 0x66FC, 0xC2FC, 0x66FD, 0x95FB, 0x66FE, 0xD4F8,
+	0x66FF, 0xCCE6, 0x6700, 0xD7EE, 0x6701, 0x95FC, 0x6702, 0x95FD,
+	0x6703, 0x95FE, 0x6704, 0x9640, 0x6705, 0x9641, 0x6706, 0x9642,
+	0x6707, 0x9643, 0x6708, 0xD4C2, 0x6709, 0xD3D0, 0x670A, 0xEBC3,
+	0x670B, 0xC5F3, 0x670C, 0x9644, 0x670D, 0xB7FE, 0x670E, 0x9645,
+	0x670F, 0x9646, 0x6710, 0xEBD4, 0x6711, 0x9647, 0x6712, 0x9648,
+	0x6713, 0x9649, 0x6714, 0xCBB7, 0x6715, 0xEBDE, 0x6716, 0x964A,
+	0x6717, 0xC0CA, 0x6718, 0x964B, 0x6719, 0x964C, 0x671A, 0x964D,
+	0x671B, 0xCDFB, 0x671C, 0x964E, 0x671D, 0xB3AF, 0x671E, 0x964F,
+	0x671F, 0xC6DA, 0x6720, 0x9650, 0x6721, 0x9651, 0x6722, 0x9652,
+	0x6723, 0x9653, 0x6724, 0x9654, 0x6725, 0x9655, 0x6726, 0xEBFC,
+	0x6727, 0x9656, 0x6728, 0xC4BE, 0x6729, 0x9657, 0x672A, 0xCEB4,
+	0x672B, 0xC4A9, 0x672C, 0xB1BE, 0x672D, 0xD4FD, 0x672E, 0x9658,
+	0x672F, 0xCAF5, 0x6730, 0x9659, 0x6731, 0xD6EC, 0x6732, 0x965A,
+	0x6733, 0x965B, 0x6734, 0xC6D3, 0x6735, 0xB6E4, 0x6736, 0x965C,
+	0x6737, 0x965D, 0x6738, 0x965E, 0x6739, 0x965F, 0x673A, 0xBBFA,
+	0x673B, 0x9660, 0x673C, 0x9661, 0x673D, 0xD0E0, 0x673E, 0x9662,
+	0x673F, 0x9663, 0x6740, 0xC9B1, 0x6741, 0x9664, 0x6742, 0xD4D3,
+	0x6743, 0xC8A8, 0x6744, 0x9665, 0x6745, 0x9666, 0x6746, 0xB8CB,
+	0x6747, 0x9667, 0x6748, 0xE8BE, 0x6749, 0xC9BC, 0x674A, 0x9668,
+	0x674B, 0x9669, 0x674C, 0xE8BB, 0x674D, 0x966A, 0x674E, 0xC0EE,
+	0x674F, 0xD0D3, 0x6750, 0xB2C4, 0x6751, 0xB4E5, 0x6752, 0x966B,
+	0x6753, 0xE8BC, 0x6754, 0x966C, 0x6755, 0x966D, 0x6756, 0xD5C8,
+	0x6757, 0x966E, 0x6758, 0x966F, 0x6759, 0x9670, 0x675A, 0x9671,
+	0x675B, 0x9672, 0x675C, 0xB6C5, 0x675D, 0x9673, 0x675E, 0xE8BD,
+	0x675F, 0xCAF8, 0x6760, 0xB8DC, 0x6761, 0xCCF5, 0x6762, 0x9674,
+	0x6763, 0x9675, 0x6764, 0x9676, 0x6765, 0xC0B4, 0x6766, 0x9677,
+	0x6767, 0x9678, 0x6768, 0xD1EE, 0x6769, 0xE8BF, 0x676A, 0xE8C2,
+	0x676B, 0x9679, 0x676C, 0x967A, 0x676D, 0xBABC, 0x676E, 0x967B,
+	0x676F, 0xB1AD, 0x6770, 0xBDDC, 0x6771, 0x967C, 0x6772, 0xEABD,
+	0x6773, 0xE8C3, 0x6774, 0x967D, 0x6775, 0xE8C6, 0x6776, 0x967E,
+	0x6777, 0xE8CB, 0x6778, 0x9680, 0x6779, 0x9681, 0x677A, 0x9682,
+	0x677B, 0x9683, 0x677C, 0xE8CC, 0x677D, 0x9684, 0x677E, 0xCBC9,
+	0x677F, 0xB0E5, 0x6780, 0x9685, 0x6781, 0xBCAB, 0x6782, 0x9686,
+	0x6783, 0x9687, 0x6784, 0xB9B9, 0x6785, 0x9688, 0x6786, 0x9689,
+	0x6787, 0xE8C1, 0x6788, 0x968A, 0x6789, 0xCDF7, 0x678A, 0x968B,
+	0x678B, 0xE8CA, 0x678C, 0x968C, 0x678D, 0x968D, 0x678E, 0x968E,
+	0x678F, 0x968F, 0x6790, 0xCEF6, 0x6791, 0x9690, 0x6792, 0x9691,
+	0x6793, 0x9692, 0x6794, 0x9693, 0x6795, 0xD5ED, 0x6796, 0x9694,
+	0x6797, 0xC1D6, 0x6798, 0xE8C4, 0x6799, 0x9695, 0x679A, 0xC3B6,
+	0x679B, 0x9696, 0x679C, 0xB9FB, 0x679D, 0xD6A6, 0x679E, 0xE8C8,
+	0x679F, 0x9697, 0x67A0, 0x9698, 0x67A1, 0x9699, 0x67A2, 0xCAE0,
+	0x67A3, 0xD4E6, 0x67A4, 0x969A, 0x67A5, 0xE8C0, 0x67A6, 0x969B,
+	0x67A7, 0xE8C5, 0x67A8, 0xE8C7, 0x67A9, 0x969C, 0x67AA, 0xC7B9,
+	0x67AB, 0xB7E3, 0x67AC, 0x969D, 0x67AD, 0xE8C9, 0x67AE, 0x969E,
+	0x67AF, 0xBFDD, 0x67B0, 0xE8D2, 0x67B1, 0x969F, 0x67B2, 0x96A0,
+	0x67B3, 0xE8D7, 0x67B4, 0x96A1, 0x67B5, 0xE8D5, 0x67B6, 0xBCDC,
+	0x67B7, 0xBCCF, 0x67B8, 0xE8DB, 0x67B9, 0x96A2, 0x67BA, 0x96A3,
+	0x67BB, 0x96A4, 0x67BC, 0x96A5, 0x67BD, 0x96A6, 0x67BE, 0x96A7,
+	0x67BF, 0x96A8, 0x67C0, 0x96A9, 0x67C1, 0xE8DE, 0x67C2, 0x96AA,
+	0x67C3, 0xE8DA, 0x67C4, 0xB1FA, 0x67C5, 0x96AB, 0x67C6, 0x96AC,
+	0x67C7, 0x96AD, 0x67C8, 0x96AE, 0x67C9, 0x96AF, 0x67CA, 0x96B0,
+	0x67CB, 0x96B1, 0x67CC, 0x96B2, 0x67CD, 0x96B3, 0x67CE, 0x96B4,
+	0x67CF, 0xB0D8, 0x67D0, 0xC4B3, 0x67D1, 0xB8CC, 0x67D2, 0xC6E2,
+	0x67D3, 0xC8BE, 0x67D4, 0xC8E1, 0x67D5, 0x96B5, 0x67D6, 0x96B6,
+	0x67D7, 0x96B7, 0x67D8, 0xE8CF, 0x67D9, 0xE8D4, 0x67DA, 0xE8D6,
+	0x67DB, 0x96B8, 0x67DC, 0xB9F1, 0x67DD, 0xE8D8, 0x67DE, 0xD7F5,
+	0x67DF, 0x96B9, 0x67E0, 0xC4FB, 0x67E1, 0x96BA, 0x67E2, 0xE8DC,
+	0x67E3, 0x96BB, 0x67E4, 0x96BC, 0x67E5, 0xB2E9, 0x67E6, 0x96BD,
+	0x67E7, 0x96BE, 0x67E8, 0x96BF, 0x67E9, 0xE8D1, 0x67EA, 0x96C0,
+	0x67EB, 0x96C1, 0x67EC, 0xBCED, 0x67ED, 0x96C2, 0x67EE, 0x96C3,
+	0x67EF, 0xBFC2, 0x67F0, 0xE8CD, 0x67F1, 0xD6F9, 0x67F2, 0x96C4,
+	0x67F3, 0xC1F8, 0x67F4, 0xB2F1, 0x67F5, 0x96C5, 0x67F6, 0x96C6,
+	0x67F7, 0x96C7, 0x67F8, 0x96C8, 0x67F9, 0x96C9, 0x67FA, 0x96CA,
+	0x67FB, 0x96CB, 0x67FC, 0x96CC, 0x67FD, 0xE8DF, 0x67FE, 0x96CD,
+	0x67FF, 0xCAC1, 0x6800, 0xE8D9, 0x6801, 0x96CE, 0x6802, 0x96CF,
+	0x6803, 0x96D0, 0x6804, 0x96D1, 0x6805, 0xD5A4, 0x6806, 0x96D2,
+	0x6807, 0xB1EA, 0x6808, 0xD5BB, 0x6809, 0xE8CE, 0x680A, 0xE8D0,
+	0x680B, 0xB6B0, 0x680C, 0xE8D3, 0x680D, 0x96D3, 0x680E, 0xE8DD,
+	0x680F, 0xC0B8, 0x6810, 0x96D4, 0x6811, 0xCAF7, 0x6812, 0x96D5,
+	0x6813, 0xCBA8, 0x6814, 0x96D6, 0x6815, 0x96D7, 0x6816, 0xC6DC,
+	0x6817, 0xC0F5, 0x6818, 0x96D8, 0x6819, 0x96D9, 0x681A, 0x96DA,
+	0x681B, 0x96DB, 0x681C, 0x96DC, 0x681D, 0xE8E9, 0x681E, 0x96DD,
+	0x681F, 0x96DE, 0x6820, 0x96DF, 0x6821, 0xD0A3, 0x6822, 0x96E0,
+	0x6823, 0x96E1, 0x6824, 0x96E2, 0x6825, 0x96E3, 0x6826, 0x96E4,
+	0x6827, 0x96E5, 0x6828, 0x96E6, 0x6829, 0xE8F2, 0x682A, 0xD6EA,
+	0x682B, 0x96E7, 0x682C, 0x96E8, 0x682D, 0x96E9, 0x682E, 0x96EA,
+	0x682F, 0x96EB, 0x6830, 0x96EC, 0x6831, 0x96ED, 0x6832, 0xE8E0,
+	0x6833, 0xE8E1, 0x6834, 0x96EE, 0x6835, 0x96EF, 0x6836, 0x96F0,
+	0x6837, 0xD1F9, 0x6838, 0xBACB, 0x6839, 0xB8F9, 0x683A, 0x96F1,
+	0x683B, 0x96F2, 0x683C, 0xB8F1, 0x683D, 0xD4D4, 0x683E, 0xE8EF,
+	0x683F, 0x96F3, 0x6840, 0xE8EE, 0x6841, 0xE8EC, 0x6842, 0xB9F0,
+	0x6843, 0xCCD2, 0x6844, 0xE8E6, 0x6845, 0xCEA6, 0x6846, 0xBFF2,
+	0x6847, 0x96F4, 0x6848, 0xB0B8, 0x6849, 0xE8F1, 0x684A, 0xE8F0,
+	0x684B, 0x96F5, 0x684C, 0xD7C0, 0x684D, 0x96F6, 0x684E, 0xE8E4,
+	0x684F, 0x96F7, 0x6850, 0xCDA9, 0x6851, 0xC9A3, 0x6852, 0x96F8,
+	0x6853, 0xBBB8, 0x6854, 0xBDDB, 0x6855, 0xE8EA, 0x6856, 0x96F9,
+	0x6857, 0x96FA, 0x6858, 0x96FB, 0x6859, 0x96FC, 0x685A, 0x96FD,
+	0x685B, 0x96FE, 0x685C, 0x9740, 0x685D, 0x9741, 0x685E, 0x9742,
+	0x685F, 0x9743, 0x6860, 0xE8E2, 0x6861, 0xE8E3, 0x6862, 0xE8E5,
+	0x6863, 0xB5B5, 0x6864, 0xE8E7, 0x6865, 0xC7C5, 0x6866, 0xE8EB,
+	0x6867, 0xE8ED, 0x6868, 0xBDB0, 0x6869, 0xD7AE, 0x686A, 0x9744,
+	0x686B, 0xE8F8, 0x686C, 0x9745, 0x686D, 0x9746, 0x686E, 0x9747,
+	0x686F, 0x9748, 0x6870, 0x9749, 0x6871, 0x974A, 0x6872, 0x974B,
+	0x6873, 0x974C, 0x6874, 0xE8F5, 0x6875, 0x974D, 0x6876, 0xCDB0,
+	0x6877, 0xE8F6, 0x6878, 0x974E, 0x6879, 0x974F, 0x687A, 0x9750,
+	0x687B, 0x9751, 0x687C, 0x9752, 0x687D, 0x9753, 0x687E, 0x9754,
+	0x687F, 0x9755, 0x6880, 0x9756, 0x6881, 0xC1BA, 0x6882, 0x9757,
+	0x6883, 0xE8E8, 0x6884, 0x9758, 0x6885, 0xC3B7, 0x6886, 0xB0F0,
+	0x6887, 0x9759, 0x6888, 0x975A, 0x6889, 0x975B, 0x688A, 0x975C,
+	0x688B, 0x975D, 0x688C, 0x975E, 0x688D, 0x975F, 0x688E, 0x9760,
+	0x688F, 0xE8F4, 0x6890, 0x9761, 0x6891, 0x9762, 0x6892, 0x9763,
+	0x6893, 0xE8F7, 0x6894, 0x9764, 0x6895, 0x9765, 0x6896, 0x9766,
+	0x6897, 0xB9A3, 0x6898, 0x9767, 0x6899, 0x9768, 0x689A, 0x9769,
+	0x689B, 0x976A, 0x689C, 0x976B, 0x689D, 0x976C, 0x689E, 0x976D,
+	0x689F, 0x976E, 0x68A0, 0x976F, 0x68A1, 0x9770, 0x68A2, 0xC9D2,
+	0x68A3, 0x9771, 0x68A4, 0x9772, 0x68A5, 0x9773, 0x68A6, 0xC3CE,
+	0x68A7, 0xCEE0, 0x68A8, 0xC0E6, 0x68A9, 0x9774, 0x68AA, 0x9775,
+	0x68AB, 0x9776, 0x68AC, 0x9777, 0x68AD, 0xCBF3, 0x68AE, 0x9778,
+	0x68AF, 0xCCDD, 0x68B0, 0xD0B5, 0x68B1, 0x9779, 0x68B2, 0x977A,
+	0x68B3, 0xCAE1, 0x68B4, 0x977B, 0x68B5, 0xE8F3, 0x68B6, 0x977C,
+	0x68B7, 0x977D, 0x68B8, 0x977E, 0x68B9, 0x9780, 0x68BA, 0x9781,
+	0x68BB, 0x9782, 0x68BC, 0x9783, 0x68BD, 0x9784, 0x68BE, 0x9785,
+	0x68BF, 0x9786, 0x68C0, 0xBCEC, 0x68C1, 0x9787, 0x68C2, 0xE8F9,
+	0x68C3, 0x9788, 0x68C4, 0x9789, 0x68C5, 0x978A, 0x68C6, 0x978B,
+	0x68C7, 0x978C, 0x68C8, 0x978D, 0x68C9, 0xC3DE, 0x68CA, 0x978E,
+	0x68CB, 0xC6E5, 0x68CC, 0x978F, 0x68CD, 0xB9F7, 0x68CE, 0x9790,
+	0x68CF, 0x9791, 0x68D0, 0x9792, 0x68D1, 0x9793, 0x68D2, 0xB0F4,
+	0x68D3, 0x9794, 0x68D4, 0x9795, 0x68D5, 0xD7D8, 0x68D6, 0x9796,
+	0x68D7, 0x9797, 0x68D8, 0xBCAC, 0x68D9, 0x9798, 0x68DA, 0xC5EF,
+	0x68DB, 0x9799, 0x68DC, 0x979A, 0x68DD, 0x979B, 0x68DE, 0x979C,
+	0x68DF, 0x979D, 0x68E0, 0xCCC4, 0x68E1, 0x979E, 0x68E2, 0x979F,
+	0x68E3, 0xE9A6, 0x68E4, 0x97A0, 0x68E5, 0x97A1, 0x68E6, 0x97A2,
+	0x68E7, 0x97A3, 0x68E8, 0x97A4, 0x68E9, 0x97A5, 0x68EA, 0x97A6,
+	0x68EB, 0x97A7, 0x68EC, 0x97A8, 0x68ED, 0x97A9, 0x68EE, 0xC9AD,
+	0x68EF, 0x97AA, 0x68F0, 0xE9A2, 0x68F1, 0xC0E2, 0x68F2, 0x97AB,
+	0x68F3, 0x97AC, 0x68F4, 0x97AD, 0x68F5, 0xBFC3, 0x68F6, 0x97AE,
+	0x68F7, 0x97AF, 0x68F8, 0x97B0, 0x68F9, 0xE8FE, 0x68FA, 0xB9D7,
+	0x68FB, 0x97B1, 0x68FC, 0xE8FB, 0x68FD, 0x97B2, 0x68FE, 0x97B3,
+	0x68FF, 0x97B4, 0x6900, 0x97B5, 0x6901, 0xE9A4, 0x6902, 0x97B6,
+	0x6903, 0x97B7, 0x6904, 0x97B8, 0x6905, 0xD2CE, 0x6906, 0x97B9,
+	0x6907, 0x97BA, 0x6908, 0x97BB, 0x6909, 0x97BC, 0x690A, 0x97BD,
+	0x690B, 0xE9A3, 0x690C, 0x97BE, 0x690D, 0xD6B2, 0x690E, 0xD7B5,
+	0x690F, 0x97BF, 0x6910, 0xE9A7, 0x6911, 0x97C0, 0x6912, 0xBDB7,
+	0x6913, 0x97C1, 0x6914, 0x97C2, 0x6915, 0x97C3, 0x6916, 0x97C4,
+	0x6917, 0x97C5, 0x6918, 0x97C6, 0x6919, 0x97C7, 0x691A, 0x97C8,
+	0x691B, 0x97C9, 0x691C, 0x97CA, 0x691D, 0x97CB, 0x691E, 0x97CC,
+	0x691F, 0xE8FC, 0x6920, 0xE8FD, 0x6921, 0x97CD, 0x6922, 0x97CE,
+	0x6923, 0x97CF, 0x6924, 0xE9A1, 0x6925, 0x97D0, 0x6926, 0x97D1,
+	0x6927, 0x97D2, 0x6928, 0x97D3, 0x6929, 0x97D4, 0x692A, 0x97D5,
+	0x692B, 0x97D6, 0x692C, 0x97D7, 0x692D, 0xCDD6, 0x692E, 0x97D8,
+	0x692F, 0x97D9, 0x6930, 0xD2AC, 0x6931, 0x97DA, 0x6932, 0x97DB,
+	0x6933, 0x97DC, 0x6934, 0xE9B2, 0x6935, 0x97DD, 0x6936, 0x97DE,
+	0x6937, 0x97DF, 0x6938, 0x97E0, 0x6939, 0xE9A9, 0x693A, 0x97E1,
+	0x693B, 0x97E2, 0x693C, 0x97E3, 0x693D, 0xB4AA, 0x693E, 0x97E4,
+	0x693F, 0xB4BB, 0x6940, 0x97E5, 0x6941, 0x97E6, 0x6942, 0xE9AB,
+	0x6943, 0x97E7, 0x6944, 0x97E8, 0x6945, 0x97E9, 0x6946, 0x97EA,
+	0x6947, 0x97EB, 0x6948, 0x97EC, 0x6949, 0x97ED, 0x694A, 0x97EE,
+	0x694B, 0x97EF, 0x694C, 0x97F0, 0x694D, 0x97F1, 0x694E, 0x97F2,
+	0x694F, 0x97F3, 0x6950, 0x97F4, 0x6951, 0x97F5, 0x6952, 0x97F6,
+	0x6953, 0x97F7, 0x6954, 0xD0A8, 0x6955, 0x97F8, 0x6956, 0x97F9,
+	0x6957, 0xE9A5, 0x6958, 0x97FA, 0x6959, 0x97FB, 0x695A, 0xB3FE,
+	0x695B, 0x97FC, 0x695C, 0x97FD, 0x695D, 0xE9AC, 0x695E, 0xC0E3,
+	0x695F, 0x97FE, 0x6960, 0xE9AA, 0x6961, 0x9840, 0x6962, 0x9841,
+	0x6963, 0xE9B9, 0x6964, 0x9842, 0x6965, 0x9843, 0x6966, 0xE9B8,
+	0x6967, 0x9844, 0x6968, 0x9845, 0x6969, 0x9846, 0x696A, 0x9847,
+	0x696B, 0xE9AE, 0x696C, 0x9848, 0x696D, 0x9849, 0x696E, 0xE8FA,
+	0x696F, 0x984A, 0x6970, 0x984B, 0x6971, 0xE9A8, 0x6972, 0x984C,
+	0x6973, 0x984D, 0x6974, 0x984E, 0x6975, 0x984F, 0x6976, 0x9850,
+	0x6977, 0xBFAC, 0x6978, 0xE9B1, 0x6979, 0xE9BA, 0x697A, 0x9851,
+	0x697B, 0x9852, 0x697C, 0xC2A5, 0x697D, 0x9853, 0x697E, 0x9854,
+	0x697F, 0x9855, 0x6980, 0xE9AF, 0x6981, 0x9856, 0x6982, 0xB8C5,
+	0x6983, 0x9857, 0x6984, 0xE9AD, 0x6985, 0x9858, 0x6986, 0xD3DC,
+	0x6987, 0xE9B4, 0x6988, 0xE9B5, 0x6989, 0xE9B7, 0x698A, 0x9859,
+	0x698B, 0x985A, 0x698C, 0x985B, 0x698D, 0xE9C7, 0x698E, 0x985C,
+	0x698F, 0x985D, 0x6990, 0x985E, 0x6991, 0x985F, 0x6992, 0x9860,
+	0x6993, 0x9861, 0x6994, 0xC0C6, 0x6995, 0xE9C5, 0x6996, 0x9862,
+	0x6997, 0x9863, 0x6998, 0xE9B0, 0x6999, 0x9864, 0x699A, 0x9865,
+	0x699B, 0xE9BB, 0x699C, 0xB0F1, 0x699D, 0x9866, 0x699E, 0x9867,
+	0x699F, 0x9868, 0x69A0, 0x9869, 0x69A1, 0x986A, 0x69A2, 0x986B,
+	0x69A3, 0x986C, 0x69A4, 0x986D, 0x69A5, 0x986E, 0x69A6, 0x986F,
+	0x69A7, 0xE9BC, 0x69A8, 0xD5A5, 0x69A9, 0x9870, 0x69AA, 0x9871,
+	0x69AB, 0xE9BE, 0x69AC, 0x9872, 0x69AD, 0xE9BF, 0x69AE, 0x9873,
+	0x69AF, 0x9874, 0x69B0, 0x9875, 0x69B1, 0xE9C1, 0x69B2, 0x9876,
+	0x69B3, 0x9877, 0x69B4, 0xC1F1, 0x69B5, 0x9878, 0x69B6, 0x9879,
+	0x69B7, 0xC8B6, 0x69B8, 0x987A, 0x69B9, 0x987B, 0x69BA, 0x987C,
+	0x69BB, 0xE9BD, 0x69BC, 0x987D, 0x69BD, 0x987E, 0x69BE, 0x9880,
+	0x69BF, 0x9881, 0x69C0, 0x9882, 0x69C1, 0xE9C2, 0x69C2, 0x9883,
+	0x69C3, 0x9884, 0x69C4, 0x9885, 0x69C5, 0x9886, 0x69C6, 0x9887,
+	0x69C7, 0x9888, 0x69C8, 0x9889, 0x69C9, 0x988A, 0x69CA, 0xE9C3,
+	0x69CB, 0x988B, 0x69CC, 0xE9B3, 0x69CD, 0x988C, 0x69CE, 0xE9B6,
+	0x69CF, 0x988D, 0x69D0, 0xBBB1, 0x69D1, 0x988E, 0x69D2, 0x988F,
+	0x69D3, 0x9890, 0x69D4, 0xE9C0, 0x69D5, 0x9891, 0x69D6, 0x9892,
+	0x69D7, 0x9893, 0x69D8, 0x9894, 0x69D9, 0x9895, 0x69DA, 0x9896,
+	0x69DB, 0xBCF7, 0x69DC, 0x9897, 0x69DD, 0x9898, 0x69DE, 0x9899,
+	0x69DF, 0xE9C4, 0x69E0, 0xE9C6, 0x69E1, 0x989A, 0x69E2, 0x989B,
+	0x69E3, 0x989C, 0x69E4, 0x989D, 0x69E5, 0x989E, 0x69E6, 0x989F,
+	0x69E7, 0x98A0, 0x69E8, 0x98A1, 0x69E9, 0x98A2, 0x69EA, 0x98A3,
+	0x69EB, 0x98A4, 0x69EC, 0x98A5, 0x69ED, 0xE9CA, 0x69EE, 0x98A6,
+	0x69EF, 0x98A7, 0x69F0, 0x98A8, 0x69F1, 0x98A9, 0x69F2, 0xE9CE,
+	0x69F3, 0x98AA, 0x69F4, 0x98AB, 0x69F5, 0x98AC, 0x69F6, 0x98AD,
+	0x69F7, 0x98AE, 0x69F8, 0x98AF, 0x69F9, 0x98B0, 0x69FA, 0x98B1,
+	0x69FB, 0x98B2, 0x69FC, 0x98B3, 0x69FD, 0xB2DB, 0x69FE, 0x98B4,
+	0x69FF, 0xE9C8, 0x6A00, 0x98B5, 0x6A01, 0x98B6, 0x6A02, 0x98B7,
+	0x6A03, 0x98B8, 0x6A04, 0x98B9, 0x6A05, 0x98BA, 0x6A06, 0x98BB,
+	0x6A07, 0x98BC, 0x6A08, 0x98BD, 0x6A09, 0x98BE, 0x6A0A, 0xB7AE,
+	0x6A0B, 0x98BF, 0x6A0C, 0x98C0, 0x6A0D, 0x98C1, 0x6A0E, 0x98C2,
+	0x6A0F, 0x98C3, 0x6A10, 0x98C4, 0x6A11, 0x98C5, 0x6A12, 0x98C6,
+	0x6A13, 0x98C7, 0x6A14, 0x98C8, 0x6A15, 0x98C9, 0x6A16, 0x98CA,
+	0x6A17, 0xE9CB, 0x6A18, 0xE9CC, 0x6A19, 0x98CB, 0x6A1A, 0x98CC,
+	0x6A1B, 0x98CD, 0x6A1C, 0x98CE, 0x6A1D, 0x98CF, 0x6A1E, 0x98D0,
+	0x6A1F, 0xD5C1, 0x6A20, 0x98D1, 0x6A21, 0xC4A3, 0x6A22, 0x98D2,
+	0x6A23, 0x98D3, 0x6A24, 0x98D4, 0x6A25, 0x98D5, 0x6A26, 0x98D6,
+	0x6A27, 0x98D7, 0x6A28, 0xE9D8, 0x6A29, 0x98D8, 0x6A2A, 0xBAE1,
+	0x6A2B, 0x98D9, 0x6A2C, 0x98DA, 0x6A2D, 0x98DB, 0x6A2E, 0x98DC,
+	0x6A2F, 0xE9C9, 0x6A30, 0x98DD, 0x6A31, 0xD3A3, 0x6A32, 0x98DE,
+	0x6A33, 0x98DF, 0x6A34, 0x98E0, 0x6A35, 0xE9D4, 0x6A36, 0x98E1,
+	0x6A37, 0x98E2, 0x6A38, 0x98E3, 0x6A39, 0x98E4, 0x6A3A, 0x98E5,
+	0x6A3B, 0x98E6, 0x6A3C, 0x98E7, 0x6A3D, 0xE9D7, 0x6A3E, 0xE9D0,
+	0x6A3F, 0x98E8, 0x6A40, 0x98E9, 0x6A41, 0x98EA, 0x6A42, 0x98EB,
+	0x6A43, 0x98EC, 0x6A44, 0xE9CF, 0x6A45, 0x98ED, 0x6A46, 0x98EE,
+	0x6A47, 0xC7C1, 0x6A48, 0x98EF, 0x6A49, 0x98F0, 0x6A4A, 0x98F1,
+	0x6A4B, 0x98F2, 0x6A4C, 0x98F3, 0x6A4D, 0x98F4, 0x6A4E, 0x98F5,
+	0x6A4F, 0x98F6, 0x6A50, 0xE9D2, 0x6A51, 0x98F7, 0x6A52, 0x98F8,
+	0x6A53, 0x98F9, 0x6A54, 0x98FA, 0x6A55, 0x98FB, 0x6A56, 0x98FC,
+	0x6A57, 0x98FD, 0x6A58, 0xE9D9, 0x6A59, 0xB3C8, 0x6A5A, 0x98FE,
+	0x6A5B, 0xE9D3, 0x6A5C, 0x9940, 0x6A5D, 0x9941, 0x6A5E, 0x9942,
+	0x6A5F, 0x9943, 0x6A60, 0x9944, 0x6A61, 0xCFF0, 0x6A62, 0x9945,
+	0x6A63, 0x9946, 0x6A64, 0x9947, 0x6A65, 0xE9CD, 0x6A66, 0x9948,
+	0x6A67, 0x9949, 0x6A68, 0x994A, 0x6A69, 0x994B, 0x6A6A, 0x994C,
+	0x6A6B, 0x994D, 0x6A6C, 0x994E, 0x6A6D, 0x994F, 0x6A6E, 0x9950,
+	0x6A6F, 0x9951, 0x6A70, 0x9952, 0x6A71, 0xB3F7, 0x6A72, 0x9953,
+	0x6A73, 0x9954, 0x6A74, 0x9955, 0x6A75, 0x9956, 0x6A76, 0x9957,
+	0x6A77, 0x9958, 0x6A78, 0x9959, 0x6A79, 0xE9D6, 0x6A7A, 0x995A,
+	0x6A7B, 0x995B, 0x6A7C, 0xE9DA, 0x6A7D, 0x995C, 0x6A7E, 0x995D,
+	0x6A7F, 0x995E, 0x6A80, 0xCCB4, 0x6A81, 0x995F, 0x6A82, 0x9960,
+	0x6A83, 0x9961, 0x6A84, 0xCFAD, 0x6A85, 0x9962, 0x6A86, 0x9963,
+	0x6A87, 0x9964, 0x6A88, 0x9965, 0x6A89, 0x9966, 0x6A8A, 0x9967,
+	0x6A8B, 0x9968, 0x6A8C, 0x9969, 0x6A8D, 0x996A, 0x6A8E, 0xE9D5,
+	0x6A8F, 0x996B, 0x6A90, 0xE9DC, 0x6A91, 0xE9DB, 0x6A92, 0x996C,
+	0x6A93, 0x996D, 0x6A94, 0x996E, 0x6A95, 0x996F, 0x6A96, 0x9970,
+	0x6A97, 0xE9DE, 0x6A98, 0x9971, 0x6A99, 0x9972, 0x6A9A, 0x9973,
+	0x6A9B, 0x9974, 0x6A9C, 0x9975, 0x6A9D, 0x9976, 0x6A9E, 0x9977,
+	0x6A9F, 0x9978, 0x6AA0, 0xE9D1, 0x6AA1, 0x9979, 0x6AA2, 0x997A,
+	0x6AA3, 0x997B, 0x6AA4, 0x997C, 0x6AA5, 0x997D, 0x6AA6, 0x997E,
+	0x6AA7, 0x9980, 0x6AA8, 0x9981, 0x6AA9, 0xE9DD, 0x6AAA, 0x9982,
+	0x6AAB, 0xE9DF, 0x6AAC, 0xC3CA, 0x6AAD, 0x9983, 0x6AAE, 0x9984,
+	0x6AAF, 0x9985, 0x6AB0, 0x9986, 0x6AB1, 0x9987, 0x6AB2, 0x9988,
+	0x6AB3, 0x9989, 0x6AB4, 0x998A, 0x6AB5, 0x998B, 0x6AB6, 0x998C,
+	0x6AB7, 0x998D, 0x6AB8, 0x998E, 0x6AB9, 0x998F, 0x6ABA, 0x9990,
+	0x6ABB, 0x9991, 0x6ABC, 0x9992, 0x6ABD, 0x9993, 0x6ABE, 0x9994,
+	0x6ABF, 0x9995, 0x6AC0, 0x9996, 0x6AC1, 0x9997, 0x6AC2, 0x9998,
+	0x6AC3, 0x9999, 0x6AC4, 0x999A, 0x6AC5, 0x999B, 0x6AC6, 0x999C,
+	0x6AC7, 0x999D, 0x6AC8, 0x999E, 0x6AC9, 0x999F, 0x6ACA, 0x99A0,
+	0x6ACB, 0x99A1, 0x6ACC, 0x99A2, 0x6ACD, 0x99A3, 0x6ACE, 0x99A4,
+	0x6ACF, 0x99A5, 0x6AD0, 0x99A6, 0x6AD1, 0x99A7, 0x6AD2, 0x99A8,
+	0x6AD3, 0x99A9, 0x6AD4, 0x99AA, 0x6AD5, 0x99AB, 0x6AD6, 0x99AC,
+	0x6AD7, 0x99AD, 0x6AD8, 0x99AE, 0x6AD9, 0x99AF, 0x6ADA, 0x99B0,
+	0x6ADB, 0x99B1, 0x6ADC, 0x99B2, 0x6ADD, 0x99B3, 0x6ADE, 0x99B4,
+	0x6ADF, 0x99B5, 0x6AE0, 0x99B6, 0x6AE1, 0x99B7, 0x6AE2, 0x99B8,
+	0x6AE3, 0x99B9, 0x6AE4, 0x99BA, 0x6AE5, 0x99BB, 0x6AE6, 0x99BC,
+	0x6AE7, 0x99BD, 0x6AE8, 0x99BE, 0x6AE9, 0x99BF, 0x6AEA, 0x99C0,
+	0x6AEB, 0x99C1, 0x6AEC, 0x99C2, 0x6AED, 0x99C3, 0x6AEE, 0x99C4,
+	0x6AEF, 0x99C5, 0x6AF0, 0x99C6, 0x6AF1, 0x99C7, 0x6AF2, 0x99C8,
+	0x6AF3, 0x99C9, 0x6AF4, 0x99CA, 0x6AF5, 0x99CB, 0x6AF6, 0x99CC,
+	0x6AF7, 0x99CD, 0x6AF8, 0x99CE, 0x6AF9, 0x99CF, 0x6AFA, 0x99D0,
+	0x6AFB, 0x99D1, 0x6AFC, 0x99D2, 0x6AFD, 0x99D3, 0x6AFE, 0x99D4,
+	0x6AFF, 0x99D5, 0x6B00, 0x99D6, 0x6B01, 0x99D7, 0x6B02, 0x99D8,
+	0x6B03, 0x99D9, 0x6B04, 0x99DA, 0x6B05, 0x99DB, 0x6B06, 0x99DC,
+	0x6B07, 0x99DD, 0x6B08, 0x99DE, 0x6B09, 0x99DF, 0x6B0A, 0x99E0,
+	0x6B0B, 0x99E1, 0x6B0C, 0x99E2, 0x6B0D, 0x99E3, 0x6B0E, 0x99E4,
+	0x6B0F, 0x99E5, 0x6B10, 0x99E6, 0x6B11, 0x99E7, 0x6B12, 0x99E8,
+	0x6B13, 0x99E9, 0x6B14, 0x99EA, 0x6B15, 0x99EB, 0x6B16, 0x99EC,
+	0x6B17, 0x99ED, 0x6B18, 0x99EE, 0x6B19, 0x99EF, 0x6B1A, 0x99F0,
+	0x6B1B, 0x99F1, 0x6B1C, 0x99F2, 0x6B1D, 0x99F3, 0x6B1E, 0x99F4,
+	0x6B1F, 0x99F5, 0x6B20, 0xC7B7, 0x6B21, 0xB4CE, 0x6B22, 0xBBB6,
+	0x6B23, 0xD0C0, 0x6B24, 0xECA3, 0x6B25, 0x99F6, 0x6B26, 0x99F7,
+	0x6B27, 0xC5B7, 0x6B28, 0x99F8, 0x6B29, 0x99F9, 0x6B2A, 0x99FA,
+	0x6B2B, 0x99FB, 0x6B2C, 0x99FC, 0x6B2D, 0x99FD, 0x6B2E, 0x99FE,
+	0x6B2F, 0x9A40, 0x6B30, 0x9A41, 0x6B31, 0x9A42, 0x6B32, 0xD3FB,
+	0x6B33, 0x9A43, 0x6B34, 0x9A44, 0x6B35, 0x9A45, 0x6B36, 0x9A46,
+	0x6B37, 0xECA4, 0x6B38, 0x9A47, 0x6B39, 0xECA5, 0x6B3A, 0xC6DB,
+	0x6B3B, 0x9A48, 0x6B3C, 0x9A49, 0x6B3D, 0x9A4A, 0x6B3E, 0xBFEE,
+	0x6B3F, 0x9A4B, 0x6B40, 0x9A4C, 0x6B41, 0x9A4D, 0x6B42, 0x9A4E,
+	0x6B43, 0xECA6, 0x6B44, 0x9A4F, 0x6B45, 0x9A50, 0x6B46, 0xECA7,
+	0x6B47, 0xD0AA, 0x6B48, 0x9A51, 0x6B49, 0xC7B8, 0x6B4A, 0x9A52,
+	0x6B4B, 0x9A53, 0x6B4C, 0xB8E8, 0x6B4D, 0x9A54, 0x6B4E, 0x9A55,
+	0x6B4F, 0x9A56, 0x6B50, 0x9A57, 0x6B51, 0x9A58, 0x6B52, 0x9A59,
+	0x6B53, 0x9A5A, 0x6B54, 0x9A5B, 0x6B55, 0x9A5C, 0x6B56, 0x9A5D,
+	0x6B57, 0x9A5E, 0x6B58, 0x9A5F, 0x6B59, 0xECA8, 0x6B5A, 0x9A60,
+	0x6B5B, 0x9A61, 0x6B5C, 0x9A62, 0x6B5D, 0x9A63, 0x6B5E, 0x9A64,
+	0x6B5F, 0x9A65, 0x6B60, 0x9A66, 0x6B61, 0x9A67, 0x6B62, 0xD6B9,
+	0x6B63, 0xD5FD, 0x6B64, 0xB4CB, 0x6B65, 0xB2BD, 0x6B66, 0xCEE4,
+	0x6B67, 0xC6E7, 0x6B68, 0x9A68, 0x6B69, 0x9A69, 0x6B6A, 0xCDE1,
+	0x6B6B, 0x9A6A, 0x6B6C, 0x9A6B, 0x6B6D, 0x9A6C, 0x6B6E, 0x9A6D,
+	0x6B6F, 0x9A6E, 0x6B70, 0x9A6F, 0x6B71, 0x9A70, 0x6B72, 0x9A71,
+	0x6B73, 0x9A72, 0x6B74, 0x9A73, 0x6B75, 0x9A74, 0x6B76, 0x9A75,
+	0x6B77, 0x9A76, 0x6B78, 0x9A77, 0x6B79, 0xB4F5, 0x6B7A, 0x9A78,
+	0x6B7B, 0xCBC0, 0x6B7C, 0xBCDF, 0x6B7D, 0x9A79, 0x6B7E, 0x9A7A,
+	0x6B7F, 0x9A7B, 0x6B80, 0x9A7C, 0x6B81, 0xE9E2, 0x6B82, 0xE9E3,
+	0x6B83, 0xD1EA, 0x6B84, 0xE9E5, 0x6B85, 0x9A7D, 0x6B86, 0xB4F9,
+	0x6B87, 0xE9E4, 0x6B88, 0x9A7E, 0x6B89, 0xD1B3, 0x6B8A, 0xCAE2,
+	0x6B8B, 0xB2D0, 0x6B8C, 0x9A80, 0x6B8D, 0xE9E8, 0x6B8E, 0x9A81,
+	0x6B8F, 0x9A82, 0x6B90, 0x9A83, 0x6B91, 0x9A84, 0x6B92, 0xE9E6,
+	0x6B93, 0xE9E7, 0x6B94, 0x9A85, 0x6B95, 0x9A86, 0x6B96, 0xD6B3,
+	0x6B97, 0x9A87, 0x6B98, 0x9A88, 0x6B99, 0x9A89, 0x6B9A, 0xE9E9,
+	0x6B9B, 0xE9EA, 0x6B9C, 0x9A8A, 0x6B9D, 0x9A8B, 0x6B9E, 0x9A8C,
+	0x6B9F, 0x9A8D, 0x6BA0, 0x9A8E, 0x6BA1, 0xE9EB, 0x6BA2, 0x9A8F,
+	0x6BA3, 0x9A90, 0x6BA4, 0x9A91, 0x6BA5, 0x9A92, 0x6BA6, 0x9A93,
+	0x6BA7, 0x9A94, 0x6BA8, 0x9A95, 0x6BA9, 0x9A96, 0x6BAA, 0xE9EC,
+	0x6BAB, 0x9A97, 0x6BAC, 0x9A98, 0x6BAD, 0x9A99, 0x6BAE, 0x9A9A,
+	0x6BAF, 0x9A9B, 0x6BB0, 0x9A9C, 0x6BB1, 0x9A9D, 0x6BB2, 0x9A9E,
+	0x6BB3, 0xECAF, 0x6BB4, 0xC5B9, 0x6BB5, 0xB6CE, 0x6BB6, 0x9A9F,
+	0x6BB7, 0xD2F3, 0x6BB8, 0x9AA0, 0x6BB9, 0x9AA1, 0x6BBA, 0x9AA2,
+	0x6BBB, 0x9AA3, 0x6BBC, 0x9AA4, 0x6BBD, 0x9AA5, 0x6BBE, 0x9AA6,
+	0x6BBF, 0xB5EE, 0x6BC0, 0x9AA7, 0x6BC1, 0xBBD9, 0x6BC2, 0xECB1,
+	0x6BC3, 0x9AA8, 0x6BC4, 0x9AA9, 0x6BC5, 0xD2E3, 0x6BC6, 0x9AAA,
+	0x6BC7, 0x9AAB, 0x6BC8, 0x9AAC, 0x6BC9, 0x9AAD, 0x6BCA, 0x9AAE,
+	0x6BCB, 0xCEE3, 0x6BCC, 0x9AAF, 0x6BCD, 0xC4B8, 0x6BCE, 0x9AB0,
+	0x6BCF, 0xC3BF, 0x6BD0, 0x9AB1, 0x6BD1, 0x9AB2, 0x6BD2, 0xB6BE,
+	0x6BD3, 0xD8B9, 0x6BD4, 0xB1C8, 0x6BD5, 0xB1CF, 0x6BD6, 0xB1D1,
+	0x6BD7, 0xC5FE, 0x6BD8, 0x9AB3, 0x6BD9, 0xB1D0, 0x6BDA, 0x9AB4,
+	0x6BDB, 0xC3AB, 0x6BDC, 0x9AB5, 0x6BDD, 0x9AB6, 0x6BDE, 0x9AB7,
+	0x6BDF, 0x9AB8, 0x6BE0, 0x9AB9, 0x6BE1, 0xD5B1, 0x6BE2, 0x9ABA,
+	0x6BE3, 0x9ABB, 0x6BE4, 0x9ABC, 0x6BE5, 0x9ABD, 0x6BE6, 0x9ABE,
+	0x6BE7, 0x9ABF, 0x6BE8, 0x9AC0, 0x6BE9, 0x9AC1, 0x6BEA, 0xEBA4,
+	0x6BEB, 0xBAC1, 0x6BEC, 0x9AC2, 0x6BED, 0x9AC3, 0x6BEE, 0x9AC4,
+	0x6BEF, 0xCCBA, 0x6BF0, 0x9AC5, 0x6BF1, 0x9AC6, 0x6BF2, 0x9AC7,
+	0x6BF3, 0xEBA5, 0x6BF4, 0x9AC8, 0x6BF5, 0xEBA7, 0x6BF6, 0x9AC9,
+	0x6BF7, 0x9ACA, 0x6BF8, 0x9ACB, 0x6BF9, 0xEBA8, 0x6BFA, 0x9ACC,
+	0x6BFB, 0x9ACD, 0x6BFC, 0x9ACE, 0x6BFD, 0xEBA6, 0x6BFE, 0x9ACF,
+	0x6BFF, 0x9AD0, 0x6C00, 0x9AD1, 0x6C01, 0x9AD2, 0x6C02, 0x9AD3,
+	0x6C03, 0x9AD4, 0x6C04, 0x9AD5, 0x6C05, 0xEBA9, 0x6C06, 0xEBAB,
+	0x6C07, 0xEBAA, 0x6C08, 0x9AD6, 0x6C09, 0x9AD7, 0x6C0A, 0x9AD8,
+	0x6C0B, 0x9AD9, 0x6C0C, 0x9ADA, 0x6C0D, 0xEBAC, 0x6C0E, 0x9ADB,
+	0x6C0F, 0xCACF, 0x6C10, 0xD8B5, 0x6C11, 0xC3F1, 0x6C12, 0x9ADC,
+	0x6C13, 0xC3A5, 0x6C14, 0xC6F8, 0x6C15, 0xEBAD, 0x6C16, 0xC4CA,
+	0x6C17, 0x9ADD, 0x6C18, 0xEBAE, 0x6C19, 0xEBAF, 0x6C1A, 0xEBB0,
+	0x6C1B, 0xB7D5, 0x6C1C, 0x9ADE, 0x6C1D, 0x9ADF, 0x6C1E, 0x9AE0,
+	0x6C1F, 0xB7FA, 0x6C20, 0x9AE1, 0x6C21, 0xEBB1, 0x6C22, 0xC7E2,
+	0x6C23, 0x9AE2, 0x6C24, 0xEBB3, 0x6C25, 0x9AE3, 0x6C26, 0xBAA4,
+	0x6C27, 0xD1F5, 0x6C28, 0xB0B1, 0x6C29, 0xEBB2, 0x6C2A, 0xEBB4,
+	0x6C2B, 0x9AE4, 0x6C2C, 0x9AE5, 0x6C2D, 0x9AE6, 0x6C2E, 0xB5AA,
+	0x6C2F, 0xC2C8, 0x6C30, 0xC7E8, 0x6C31, 0x9AE7, 0x6C32, 0xEBB5,
+	0x6C33, 0x9AE8, 0x6C34, 0xCBAE, 0x6C35, 0xE3DF, 0x6C36, 0x9AE9,
+	0x6C37, 0x9AEA, 0x6C38, 0xD3C0, 0x6C39, 0x9AEB, 0x6C3A, 0x9AEC,
+	0x6C3B, 0x9AED, 0x6C3C, 0x9AEE, 0x6C3D, 0xD9DB, 0x6C3E, 0x9AEF,
+	0x6C3F, 0x9AF0, 0x6C40, 0xCDA1, 0x6C41, 0xD6AD, 0x6C42, 0xC7F3,
+	0x6C43, 0x9AF1, 0x6C44, 0x9AF2, 0x6C45, 0x9AF3, 0x6C46, 0xD9E0,
+	0x6C47, 0xBBE3, 0x6C48, 0x9AF4, 0x6C49, 0xBABA, 0x6C4A, 0xE3E2,
+	0x6C4B, 0x9AF5, 0x6C4C, 0x9AF6, 0x6C4D, 0x9AF7, 0x6C4E, 0x9AF8,
+	0x6C4F, 0x9AF9, 0x6C50, 0xCFAB, 0x6C51, 0x9AFA, 0x6C52, 0x9AFB,
+	0x6C53, 0x9AFC, 0x6C54, 0xE3E0, 0x6C55, 0xC9C7, 0x6C56, 0x9AFD,
+	0x6C57, 0xBAB9, 0x6C58, 0x9AFE, 0x6C59, 0x9B40, 0x6C5A, 0x9B41,
+	0x6C5B, 0xD1B4, 0x6C5C, 0xE3E1, 0x6C5D, 0xC8EA, 0x6C5E, 0xB9AF,
+	0x6C5F, 0xBDAD, 0x6C60, 0xB3D8, 0x6C61, 0xCEDB, 0x6C62, 0x9B42,
+	0x6C63, 0x9B43, 0x6C64, 0xCCC0, 0x6C65, 0x9B44, 0x6C66, 0x9B45,
+	0x6C67, 0x9B46, 0x6C68, 0xE3E8, 0x6C69, 0xE3E9, 0x6C6A, 0xCDF4,
+	0x6C6B, 0x9B47, 0x6C6C, 0x9B48, 0x6C6D, 0x9B49, 0x6C6E, 0x9B4A,
+	0x6C6F, 0x9B4B, 0x6C70, 0xCCAD, 0x6C71, 0x9B4C, 0x6C72, 0xBCB3,
+	0x6C73, 0x9B4D, 0x6C74, 0xE3EA, 0x6C75, 0x9B4E, 0x6C76, 0xE3EB,
+	0x6C77, 0x9B4F, 0x6C78, 0x9B50, 0x6C79, 0xD0DA, 0x6C7A, 0x9B51,
+	0x6C7B, 0x9B52, 0x6C7C, 0x9B53, 0x6C7D, 0xC6FB, 0x6C7E, 0xB7DA,
+	0x6C7F, 0x9B54, 0x6C80, 0x9B55, 0x6C81, 0xC7DF, 0x6C82, 0xD2CA,
+	0x6C83, 0xCED6, 0x6C84, 0x9B56, 0x6C85, 0xE3E4, 0x6C86, 0xE3EC,
+	0x6C87, 0x9B57, 0x6C88, 0xC9F2, 0x6C89, 0xB3C1, 0x6C8A, 0x9B58,
+	0x6C8B, 0x9B59, 0x6C8C, 0xE3E7, 0x6C8D, 0x9B5A, 0x6C8E, 0x9B5B,
+	0x6C8F, 0xC6E3, 0x6C90, 0xE3E5, 0x6C91, 0x9B5C, 0x6C92, 0x9B5D,
+	0x6C93, 0xEDB3, 0x6C94, 0xE3E6, 0x6C95, 0x9B5E, 0x6C96, 0x9B5F,
+	0x6C97, 0x9B60, 0x6C98, 0x9B61, 0x6C99, 0xC9B3, 0x6C9A, 0x9B62,
+	0x6C9B, 0xC5E6, 0x6C9C, 0x9B63, 0x6C9D, 0x9B64, 0x6C9E, 0x9B65,
+	0x6C9F, 0xB9B5, 0x6CA0, 0x9B66, 0x6CA1, 0xC3BB, 0x6CA2, 0x9B67,
+	0x6CA3, 0xE3E3, 0x6CA4, 0xC5BD, 0x6CA5, 0xC1A4, 0x6CA6, 0xC2D9,
+	0x6CA7, 0xB2D7, 0x6CA8, 0x9B68, 0x6CA9, 0xE3ED, 0x6CAA, 0xBBA6,
+	0x6CAB, 0xC4AD, 0x6CAC, 0x9B69, 0x6CAD, 0xE3F0, 0x6CAE, 0xBEDA,
+	0x6CAF, 0x9B6A, 0x6CB0, 0x9B6B, 0x6CB1, 0xE3FB, 0x6CB2, 0xE3F5,
+	0x6CB3, 0xBAD3, 0x6CB4, 0x9B6C, 0x6CB5, 0x9B6D, 0x6CB6, 0x9B6E,
+	0x6CB7, 0x9B6F, 0x6CB8, 0xB7D0, 0x6CB9, 0xD3CD, 0x6CBA, 0x9B70,
+	0x6CBB, 0xD6CE, 0x6CBC, 0xD5D3, 0x6CBD, 0xB9C1, 0x6CBE, 0xD5B4,
+	0x6CBF, 0xD1D8, 0x6CC0, 0x9B71, 0x6CC1, 0x9B72, 0x6CC2, 0x9B73,
+	0x6CC3, 0x9B74, 0x6CC4, 0xD0B9, 0x6CC5, 0xC7F6, 0x6CC6, 0x9B75,
+	0x6CC7, 0x9B76, 0x6CC8, 0x9B77, 0x6CC9, 0xC8AA, 0x6CCA, 0xB2B4,
+	0x6CCB, 0x9B78, 0x6CCC, 0xC3DA, 0x6CCD, 0x9B79, 0x6CCE, 0x9B7A,
+	0x6CCF, 0x9B7B, 0x6CD0, 0xE3EE, 0x6CD1, 0x9B7C, 0x6CD2, 0x9B7D,
+	0x6CD3, 0xE3FC, 0x6CD4, 0xE3EF, 0x6CD5, 0xB7A8, 0x6CD6, 0xE3F7,
+	0x6CD7, 0xE3F4, 0x6CD8, 0x9B7E, 0x6CD9, 0x9B80, 0x6CDA, 0x9B81,
+	0x6CDB, 0xB7BA, 0x6CDC, 0x9B82, 0x6CDD, 0x9B83, 0x6CDE, 0xC5A2,
+	0x6CDF, 0x9B84, 0x6CE0, 0xE3F6, 0x6CE1, 0xC5DD, 0x6CE2, 0xB2A8,
+	0x6CE3, 0xC6FC, 0x6CE4, 0x9B85, 0x6CE5, 0xC4E0, 0x6CE6, 0x9B86,
+	0x6CE7, 0x9B87, 0x6CE8, 0xD7A2, 0x6CE9, 0x9B88, 0x6CEA, 0xC0E1,
+	0x6CEB, 0xE3F9, 0x6CEC, 0x9B89, 0x6CED, 0x9B8A, 0x6CEE, 0xE3FA,
+	0x6CEF, 0xE3FD, 0x6CF0, 0xCCA9, 0x6CF1, 0xE3F3, 0x6CF2, 0x9B8B,
+	0x6CF3, 0xD3BE, 0x6CF4, 0x9B8C, 0x6CF5, 0xB1C3, 0x6CF6, 0xEDB4,
+	0x6CF7, 0xE3F1, 0x6CF8, 0xE3F2, 0x6CF9, 0x9B8D, 0x6CFA, 0xE3F8,
+	0x6CFB, 0xD0BA, 0x6CFC, 0xC6C3, 0x6CFD, 0xD4F3, 0x6CFE, 0xE3FE,
+	0x6CFF, 0x9B8E, 0x6D00, 0x9B8F, 0x6D01, 0xBDE0, 0x6D02, 0x9B90,
+	0x6D03, 0x9B91, 0x6D04, 0xE4A7, 0x6D05, 0x9B92, 0x6D06, 0x9B93,
+	0x6D07, 0xE4A6, 0x6D08, 0x9B94, 0x6D09, 0x9B95, 0x6D0A, 0x9B96,
+	0x6D0B, 0xD1F3, 0x6D0C, 0xE4A3, 0x6D0D, 0x9B97, 0x6D0E, 0xE4A9,
+	0x6D0F, 0x9B98, 0x6D10, 0x9B99, 0x6D11, 0x9B9A, 0x6D12, 0xC8F7,
+	0x6D13, 0x9B9B, 0x6D14, 0x9B9C, 0x6D15, 0x9B9D, 0x6D16, 0x9B9E,
+	0x6D17, 0xCFB4, 0x6D18, 0x9B9F, 0x6D19, 0xE4A8, 0x6D1A, 0xE4AE,
+	0x6D1B, 0xC2E5, 0x6D1C, 0x9BA0, 0x6D1D, 0x9BA1, 0x6D1E, 0xB6B4,
+	0x6D1F, 0x9BA2, 0x6D20, 0x9BA3, 0x6D21, 0x9BA4, 0x6D22, 0x9BA5,
+	0x6D23, 0x9BA6, 0x6D24, 0x9BA7, 0x6D25, 0xBDF2, 0x6D26, 0x9BA8,
+	0x6D27, 0xE4A2, 0x6D28, 0x9BA9, 0x6D29, 0x9BAA, 0x6D2A, 0xBAE9,
+	0x6D2B, 0xE4AA, 0x6D2C, 0x9BAB, 0x6D2D, 0x9BAC, 0x6D2E, 0xE4AC,
+	0x6D2F, 0x9BAD, 0x6D30, 0x9BAE, 0x6D31, 0xB6FD, 0x6D32, 0xD6DE,
+	0x6D33, 0xE4B2, 0x6D34, 0x9BAF, 0x6D35, 0xE4AD, 0x6D36, 0x9BB0,
+	0x6D37, 0x9BB1, 0x6D38, 0x9BB2, 0x6D39, 0xE4A1, 0x6D3A, 0x9BB3,
+	0x6D3B, 0xBBEE, 0x6D3C, 0xCDDD, 0x6D3D, 0xC7A2, 0x6D3E, 0xC5C9,
+	0x6D3F, 0x9BB4, 0x6D40, 0x9BB5, 0x6D41, 0xC1F7, 0x6D42, 0x9BB6,
+	0x6D43, 0xE4A4, 0x6D44, 0x9BB7, 0x6D45, 0xC7B3, 0x6D46, 0xBDAC,
+	0x6D47, 0xBDBD, 0x6D48, 0xE4A5, 0x6D49, 0x9BB8, 0x6D4A, 0xD7C7,
+	0x6D4B, 0xB2E2, 0x6D4C, 0x9BB9, 0x6D4D, 0xE4AB, 0x6D4E, 0xBCC3,
+	0x6D4F, 0xE4AF, 0x6D50, 0x9BBA, 0x6D51, 0xBBEB, 0x6D52, 0xE4B0,
+	0x6D53, 0xC5A8, 0x6D54, 0xE4B1, 0x6D55, 0x9BBB, 0x6D56, 0x9BBC,
+	0x6D57, 0x9BBD, 0x6D58, 0x9BBE, 0x6D59, 0xD5E3, 0x6D5A, 0xBFA3,
+	0x6D5B, 0x9BBF, 0x6D5C, 0xE4BA, 0x6D5D, 0x9BC0, 0x6D5E, 0xE4B7,
+	0x6D5F, 0x9BC1, 0x6D60, 0xE4BB, 0x6D61, 0x9BC2, 0x6D62, 0x9BC3,
+	0x6D63, 0xE4BD, 0x6D64, 0x9BC4, 0x6D65, 0x9BC5, 0x6D66, 0xC6D6,
+	0x6D67, 0x9BC6, 0x6D68, 0x9BC7, 0x6D69, 0xBAC6, 0x6D6A, 0xC0CB,
+	0x6D6B, 0x9BC8, 0x6D6C, 0x9BC9, 0x6D6D, 0x9BCA, 0x6D6E, 0xB8A1,
+	0x6D6F, 0xE4B4, 0x6D70, 0x9BCB, 0x6D71, 0x9BCC, 0x6D72, 0x9BCD,
+	0x6D73, 0x9BCE, 0x6D74, 0xD4A1, 0x6D75, 0x9BCF, 0x6D76, 0x9BD0,
+	0x6D77, 0xBAA3, 0x6D78, 0xBDFE, 0x6D79, 0x9BD1, 0x6D7A, 0x9BD2,
+	0x6D7B, 0x9BD3, 0x6D7C, 0xE4BC, 0x6D7D, 0x9BD4, 0x6D7E, 0x9BD5,
+	0x6D7F, 0x9BD6, 0x6D80, 0x9BD7, 0x6D81, 0x9BD8, 0x6D82, 0xCDBF,
+	0x6D83, 0x9BD9, 0x6D84, 0x9BDA, 0x6D85, 0xC4F9, 0x6D86, 0x9BDB,
+	0x6D87, 0x9BDC, 0x6D88, 0xCFFB, 0x6D89, 0xC9E6, 0x6D8A, 0x9BDD,
+	0x6D8B, 0x9BDE, 0x6D8C, 0xD3BF, 0x6D8D, 0x9BDF, 0x6D8E, 0xCFD1,
+	0x6D8F, 0x9BE0, 0x6D90, 0x9BE1, 0x6D91, 0xE4B3, 0x6D92, 0x9BE2,
+	0x6D93, 0xE4B8, 0x6D94, 0xE4B9, 0x6D95, 0xCCE9, 0x6D96, 0x9BE3,
+	0x6D97, 0x9BE4, 0x6D98, 0x9BE5, 0x6D99, 0x9BE6, 0x6D9A, 0x9BE7,
+	0x6D9B, 0xCCCE, 0x6D9C, 0x9BE8, 0x6D9D, 0xC0D4, 0x6D9E, 0xE4B5,
+	0x6D9F, 0xC1B0, 0x6DA0, 0xE4B6, 0x6DA1, 0xCED0, 0x6DA2, 0x9BE9,
+	0x6DA3, 0xBBC1, 0x6DA4, 0xB5D3, 0x6DA5, 0x9BEA, 0x6DA6, 0xC8F3,
+	0x6DA7, 0xBDA7, 0x6DA8, 0xD5C7, 0x6DA9, 0xC9AC, 0x6DAA, 0xB8A2,
+	0x6DAB, 0xE4CA, 0x6DAC, 0x9BEB, 0x6DAD, 0x9BEC, 0x6DAE, 0xE4CC,
+	0x6DAF, 0xD1C4, 0x6DB0, 0x9BED, 0x6DB1, 0x9BEE, 0x6DB2, 0xD2BA,
+	0x6DB3, 0x9BEF, 0x6DB4, 0x9BF0, 0x6DB5, 0xBAAD, 0x6DB6, 0x9BF1,
+	0x6DB7, 0x9BF2, 0x6DB8, 0xBAD4, 0x6DB9, 0x9BF3, 0x6DBA, 0x9BF4,
+	0x6DBB, 0x9BF5, 0x6DBC, 0x9BF6, 0x6DBD, 0x9BF7, 0x6DBE, 0x9BF8,
+	0x6DBF, 0xE4C3, 0x6DC0, 0xB5ED, 0x6DC1, 0x9BF9, 0x6DC2, 0x9BFA,
+	0x6DC3, 0x9BFB, 0x6DC4, 0xD7CD, 0x6DC5, 0xE4C0, 0x6DC6, 0xCFFD,
+	0x6DC7, 0xE4BF, 0x6DC8, 0x9BFC, 0x6DC9, 0x9BFD, 0x6DCA, 0x9BFE,
+	0x6DCB, 0xC1DC, 0x6DCC, 0xCCCA, 0x6DCD, 0x9C40, 0x6DCE, 0x9C41,
+	0x6DCF, 0x9C42, 0x6DD0, 0x9C43, 0x6DD1, 0xCAE7, 0x6DD2, 0x9C44,
+	0x6DD3, 0x9C45, 0x6DD4, 0x9C46, 0x6DD5, 0x9C47, 0x6DD6, 0xC4D7,
+	0x6DD7, 0x9C48, 0x6DD8, 0xCCD4, 0x6DD9, 0xE4C8, 0x6DDA, 0x9C49,
+	0x6DDB, 0x9C4A, 0x6DDC, 0x9C4B, 0x6DDD, 0xE4C7, 0x6DDE, 0xE4C1,
+	0x6DDF, 0x9C4C, 0x6DE0, 0xE4C4, 0x6DE1, 0xB5AD, 0x6DE2, 0x9C4D,
+	0x6DE3, 0x9C4E, 0x6DE4, 0xD3D9, 0x6DE5, 0x9C4F, 0x6DE6, 0xE4C6,
+	0x6DE7, 0x9C50, 0x6DE8, 0x9C51, 0x6DE9, 0x9C52, 0x6DEA, 0x9C53,
+	0x6DEB, 0xD2F9, 0x6DEC, 0xB4E3, 0x6DED, 0x9C54, 0x6DEE, 0xBBB4,
+	0x6DEF, 0x9C55, 0x6DF0, 0x9C56, 0x6DF1, 0xC9EE, 0x6DF2, 0x9C57,
+	0x6DF3, 0xB4BE, 0x6DF4, 0x9C58, 0x6DF5, 0x9C59, 0x6DF6, 0x9C5A,
+	0x6DF7, 0xBBEC, 0x6DF8, 0x9C5B, 0x6DF9, 0xD1CD, 0x6DFA, 0x9C5C,
+	0x6DFB, 0xCCED, 0x6DFC, 0xEDB5, 0x6DFD, 0x9C5D, 0x6DFE, 0x9C5E,
+	0x6DFF, 0x9C5F, 0x6E00, 0x9C60, 0x6E01, 0x9C61, 0x6E02, 0x9C62,
+	0x6E03, 0x9C63, 0x6E04, 0x9C64, 0x6E05, 0xC7E5, 0x6E06, 0x9C65,
+	0x6E07, 0x9C66, 0x6E08, 0x9C67, 0x6E09, 0x9C68, 0x6E0A, 0xD4A8,
+	0x6E0B, 0x9C69, 0x6E0C, 0xE4CB, 0x6E0D, 0xD7D5, 0x6E0E, 0xE4C2,
+	0x6E0F, 0x9C6A, 0x6E10, 0xBDA5, 0x6E11, 0xE4C5, 0x6E12, 0x9C6B,
+	0x6E13, 0x9C6C, 0x6E14, 0xD3E6, 0x6E15, 0x9C6D, 0x6E16, 0xE4C9,
+	0x6E17, 0xC9F8, 0x6E18, 0x9C6E, 0x6E19, 0x9C6F, 0x6E1A, 0xE4BE,
+	0x6E1B, 0x9C70, 0x6E1C, 0x9C71, 0x6E1D, 0xD3E5, 0x6E1E, 0x9C72,
+	0x6E1F, 0x9C73, 0x6E20, 0xC7FE, 0x6E21, 0xB6C9, 0x6E22, 0x9C74,
+	0x6E23, 0xD4FC, 0x6E24, 0xB2B3, 0x6E25, 0xE4D7, 0x6E26, 0x9C75,
+	0x6E27, 0x9C76, 0x6E28, 0x9C77, 0x6E29, 0xCEC2, 0x6E2A, 0x9C78,
+	0x6E2B, 0xE4CD, 0x6E2C, 0x9C79, 0x6E2D, 0xCEBC, 0x6E2E, 0x9C7A,
+	0x6E2F, 0xB8DB, 0x6E30, 0x9C7B, 0x6E31, 0x9C7C, 0x6E32, 0xE4D6,
+	0x6E33, 0x9C7D, 0x6E34, 0xBFCA, 0x6E35, 0x9C7E, 0x6E36, 0x9C80,
+	0x6E37, 0x9C81, 0x6E38, 0xD3CE, 0x6E39, 0x9C82, 0x6E3A, 0xC3EC,
+	0x6E3B, 0x9C83, 0x6E3C, 0x9C84, 0x6E3D, 0x9C85, 0x6E3E, 0x9C86,
+	0x6E3F, 0x9C87, 0x6E40, 0x9C88, 0x6E41, 0x9C89, 0x6E42, 0x9C8A,
+	0x6E43, 0xC5C8, 0x6E44, 0xE4D8, 0x6E45, 0x9C8B, 0x6E46, 0x9C8C,
+	0x6E47, 0x9C8D, 0x6E48, 0x9C8E, 0x6E49, 0x9C8F, 0x6E4A, 0x9C90,
+	0x6E4B, 0x9C91, 0x6E4C, 0x9C92, 0x6E4D, 0xCDC4, 0x6E4E, 0xE4CF,
+	0x6E4F, 0x9C93, 0x6E50, 0x9C94, 0x6E51, 0x9C95, 0x6E52, 0x9C96,
+	0x6E53, 0xE4D4, 0x6E54, 0xE4D5, 0x6E55, 0x9C97, 0x6E56, 0xBAFE,
+	0x6E57, 0x9C98, 0x6E58, 0xCFE6, 0x6E59, 0x9C99, 0x6E5A, 0x9C9A,
+	0x6E5B, 0xD5BF, 0x6E5C, 0x9C9B, 0x6E5D, 0x9C9C, 0x6E5E, 0x9C9D,
+	0x6E5F, 0xE4D2, 0x6E60, 0x9C9E, 0x6E61, 0x9C9F, 0x6E62, 0x9CA0,
+	0x6E63, 0x9CA1, 0x6E64, 0x9CA2, 0x6E65, 0x9CA3, 0x6E66, 0x9CA4,
+	0x6E67, 0x9CA5, 0x6E68, 0x9CA6, 0x6E69, 0x9CA7, 0x6E6A, 0x9CA8,
+	0x6E6B, 0xE4D0, 0x6E6C, 0x9CA9, 0x6E6D, 0x9CAA, 0x6E6E, 0xE4CE,
+	0x6E6F, 0x9CAB, 0x6E70, 0x9CAC, 0x6E71, 0x9CAD, 0x6E72, 0x9CAE,
+	0x6E73, 0x9CAF, 0x6E74, 0x9CB0, 0x6E75, 0x9CB1, 0x6E76, 0x9CB2,
+	0x6E77, 0x9CB3, 0x6E78, 0x9CB4, 0x6E79, 0x9CB5, 0x6E7A, 0x9CB6,
+	0x6E7B, 0x9CB7, 0x6E7C, 0x9CB8, 0x6E7D, 0x9CB9, 0x6E7E, 0xCDE5,
+	0x6E7F, 0xCAAA, 0x6E80, 0x9CBA, 0x6E81, 0x9CBB, 0x6E82, 0x9CBC,
+	0x6E83, 0xC0A3, 0x6E84, 0x9CBD, 0x6E85, 0xBDA6, 0x6E86, 0xE4D3,
+	0x6E87, 0x9CBE, 0x6E88, 0x9CBF, 0x6E89, 0xB8C8, 0x6E8A, 0x9CC0,
+	0x6E8B, 0x9CC1, 0x6E8C, 0x9CC2, 0x6E8D, 0x9CC3, 0x6E8E, 0x9CC4,
+	0x6E8F, 0xE4E7, 0x6E90, 0xD4B4, 0x6E91, 0x9CC5, 0x6E92, 0x9CC6,
+	0x6E93, 0x9CC7, 0x6E94, 0x9CC8, 0x6E95, 0x9CC9, 0x6E96, 0x9CCA,
+	0x6E97, 0x9CCB, 0x6E98, 0xE4DB, 0x6E99, 0x9CCC, 0x6E9A, 0x9CCD,
+	0x6E9B, 0x9CCE, 0x6E9C, 0xC1EF, 0x6E9D, 0x9CCF, 0x6E9E, 0x9CD0,
+	0x6E9F, 0xE4E9, 0x6EA0, 0x9CD1, 0x6EA1, 0x9CD2, 0x6EA2, 0xD2E7,
+	0x6EA3, 0x9CD3, 0x6EA4, 0x9CD4, 0x6EA5, 0xE4DF, 0x6EA6, 0x9CD5,
+	0x6EA7, 0xE4E0, 0x6EA8, 0x9CD6, 0x6EA9, 0x9CD7, 0x6EAA, 0xCFAA,
+	0x6EAB, 0x9CD8, 0x6EAC, 0x9CD9, 0x6EAD, 0x9CDA, 0x6EAE, 0x9CDB,
+	0x6EAF, 0xCBDD, 0x6EB0, 0x9CDC, 0x6EB1, 0xE4DA, 0x6EB2, 0xE4D1,
+	0x6EB3, 0x9CDD, 0x6EB4, 0xE4E5, 0x6EB5, 0x9CDE, 0x6EB6, 0xC8DC,
+	0x6EB7, 0xE4E3, 0x6EB8, 0x9CDF, 0x6EB9, 0x9CE0, 0x6EBA, 0xC4E7,
+	0x6EBB, 0xE4E2, 0x6EBC, 0x9CE1, 0x6EBD, 0xE4E1, 0x6EBE, 0x9CE2,
+	0x6EBF, 0x9CE3, 0x6EC0, 0x9CE4, 0x6EC1, 0xB3FC, 0x6EC2, 0xE4E8,
+	0x6EC3, 0x9CE5, 0x6EC4, 0x9CE6, 0x6EC5, 0x9CE7, 0x6EC6, 0x9CE8,
+	0x6EC7, 0xB5E1, 0x6EC8, 0x9CE9, 0x6EC9, 0x9CEA, 0x6ECA, 0x9CEB,
+	0x6ECB, 0xD7CC, 0x6ECC, 0x9CEC, 0x6ECD, 0x9CED, 0x6ECE, 0x9CEE,
+	0x6ECF, 0xE4E6, 0x6ED0, 0x9CEF, 0x6ED1, 0xBBAC, 0x6ED2, 0x9CF0,
+	0x6ED3, 0xD7D2, 0x6ED4, 0xCCCF, 0x6ED5, 0xEBF8, 0x6ED6, 0x9CF1,
+	0x6ED7, 0xE4E4, 0x6ED8, 0x9CF2, 0x6ED9, 0x9CF3, 0x6EDA, 0xB9F6,
+	0x6EDB, 0x9CF4, 0x6EDC, 0x9CF5, 0x6EDD, 0x9CF6, 0x6EDE, 0xD6CD,
+	0x6EDF, 0xE4D9, 0x6EE0, 0xE4DC, 0x6EE1, 0xC2FA, 0x6EE2, 0xE4DE,
+	0x6EE3, 0x9CF7, 0x6EE4, 0xC2CB, 0x6EE5, 0xC0C4, 0x6EE6, 0xC2D0,
+	0x6EE7, 0x9CF8, 0x6EE8, 0xB1F5, 0x6EE9, 0xCCB2, 0x6EEA, 0x9CF9,
+	0x6EEB, 0x9CFA, 0x6EEC, 0x9CFB, 0x6EED, 0x9CFC, 0x6EEE, 0x9CFD,
+	0x6EEF, 0x9CFE, 0x6EF0, 0x9D40, 0x6EF1, 0x9D41, 0x6EF2, 0x9D42,
+	0x6EF3, 0x9D43, 0x6EF4, 0xB5CE, 0x6EF5, 0x9D44, 0x6EF6, 0x9D45,
+	0x6EF7, 0x9D46, 0x6EF8, 0x9D47, 0x6EF9, 0xE4EF, 0x6EFA, 0x9D48,
+	0x6EFB, 0x9D49, 0x6EFC, 0x9D4A, 0x6EFD, 0x9D4B, 0x6EFE, 0x9D4C,
+	0x6EFF, 0x9D4D, 0x6F00, 0x9D4E, 0x6F01, 0x9D4F, 0x6F02, 0xC6AF,
+	0x6F03, 0x9D50, 0x6F04, 0x9D51, 0x6F05, 0x9D52, 0x6F06, 0xC6E1,
+	0x6F07, 0x9D53, 0x6F08, 0x9D54, 0x6F09, 0xE4F5, 0x6F0A, 0x9D55,
+	0x6F0B, 0x9D56, 0x6F0C, 0x9D57, 0x6F0D, 0x9D58, 0x6F0E, 0x9D59,
+	0x6F0F, 0xC2A9, 0x6F10, 0x9D5A, 0x6F11, 0x9D5B, 0x6F12, 0x9D5C,
+	0x6F13, 0xC0EC, 0x6F14, 0xD1DD, 0x6F15, 0xE4EE, 0x6F16, 0x9D5D,
+	0x6F17, 0x9D5E, 0x6F18, 0x9D5F, 0x6F19, 0x9D60, 0x6F1A, 0x9D61,
+	0x6F1B, 0x9D62, 0x6F1C, 0x9D63, 0x6F1D, 0x9D64, 0x6F1E, 0x9D65,
+	0x6F1F, 0x9D66, 0x6F20, 0xC4AE, 0x6F21, 0x9D67, 0x6F22, 0x9D68,
+	0x6F23, 0x9D69, 0x6F24, 0xE4ED, 0x6F25, 0x9D6A, 0x6F26, 0x9D6B,
+	0x6F27, 0x9D6C, 0x6F28, 0x9D6D, 0x6F29, 0xE4F6, 0x6F2A, 0xE4F4,
+	0x6F2B, 0xC2FE, 0x6F2C, 0x9D6E, 0x6F2D, 0xE4DD, 0x6F2E, 0x9D6F,
+	0x6F2F, 0xE4F0, 0x6F30, 0x9D70, 0x6F31, 0xCAFE, 0x6F32, 0x9D71,
+	0x6F33, 0xD5C4, 0x6F34, 0x9D72, 0x6F35, 0x9D73, 0x6F36, 0xE4F1,
+	0x6F37, 0x9D74, 0x6F38, 0x9D75, 0x6F39, 0x9D76, 0x6F3A, 0x9D77,
+	0x6F3B, 0x9D78, 0x6F3C, 0x9D79, 0x6F3D, 0x9D7A, 0x6F3E, 0xD1FA,
+	0x6F3F, 0x9D7B, 0x6F40, 0x9D7C, 0x6F41, 0x9D7D, 0x6F42, 0x9D7E,
+	0x6F43, 0x9D80, 0x6F44, 0x9D81, 0x6F45, 0x9D82, 0x6F46, 0xE4EB,
+	0x6F47, 0xE4EC, 0x6F48, 0x9D83, 0x6F49, 0x9D84, 0x6F4A, 0x9D85,
+	0x6F4B, 0xE4F2, 0x6F4C, 0x9D86, 0x6F4D, 0xCEAB, 0x6F4E, 0x9D87,
+	0x6F4F, 0x9D88, 0x6F50, 0x9D89, 0x6F51, 0x9D8A, 0x6F52, 0x9D8B,
+	0x6F53, 0x9D8C, 0x6F54, 0x9D8D, 0x6F55, 0x9D8E, 0x6F56, 0x9D8F,
+	0x6F57, 0x9D90, 0x6F58, 0xC5CB, 0x6F59, 0x9D91, 0x6F5A, 0x9D92,
+	0x6F5B, 0x9D93, 0x6F5C, 0xC7B1, 0x6F5D, 0x9D94, 0x6F5E, 0xC2BA,
+	0x6F5F, 0x9D95, 0x6F60, 0x9D96, 0x6F61, 0x9D97, 0x6F62, 0xE4EA,
+	0x6F63, 0x9D98, 0x6F64, 0x9D99, 0x6F65, 0x9D9A, 0x6F66, 0xC1CA,
+	0x6F67, 0x9D9B, 0x6F68, 0x9D9C, 0x6F69, 0x9D9D, 0x6F6A, 0x9D9E,
+	0x6F6B, 0x9D9F, 0x6F6C, 0x9DA0, 0x6F6D, 0xCCB6, 0x6F6E, 0xB3B1,
+	0x6F6F, 0x9DA1, 0x6F70, 0x9DA2, 0x6F71, 0x9DA3, 0x6F72, 0xE4FB,
+	0x6F73, 0x9DA4, 0x6F74, 0xE4F3, 0x6F75, 0x9DA5, 0x6F76, 0x9DA6,
+	0x6F77, 0x9DA7, 0x6F78, 0xE4FA, 0x6F79, 0x9DA8, 0x6F7A, 0xE4FD,
+	0x6F7B, 0x9DA9, 0x6F7C, 0xE4FC, 0x6F7D, 0x9DAA, 0x6F7E, 0x9DAB,
+	0x6F7F, 0x9DAC, 0x6F80, 0x9DAD, 0x6F81, 0x9DAE, 0x6F82, 0x9DAF,
+	0x6F83, 0x9DB0, 0x6F84, 0xB3CE, 0x6F85, 0x9DB1, 0x6F86, 0x9DB2,
+	0x6F87, 0x9DB3, 0x6F88, 0xB3BA, 0x6F89, 0xE4F7, 0x6F8A, 0x9DB4,
+	0x6F8B, 0x9DB5, 0x6F8C, 0xE4F9, 0x6F8D, 0xE4F8, 0x6F8E, 0xC5EC,
+	0x6F8F, 0x9DB6, 0x6F90, 0x9DB7, 0x6F91, 0x9DB8, 0x6F92, 0x9DB9,
+	0x6F93, 0x9DBA, 0x6F94, 0x9DBB, 0x6F95, 0x9DBC, 0x6F96, 0x9DBD,
+	0x6F97, 0x9DBE, 0x6F98, 0x9DBF, 0x6F99, 0x9DC0, 0x6F9A, 0x9DC1,
+	0x6F9B, 0x9DC2, 0x6F9C, 0xC0BD, 0x6F9D, 0x9DC3, 0x6F9E, 0x9DC4,
+	0x6F9F, 0x9DC5, 0x6FA0, 0x9DC6, 0x6FA1, 0xD4E8, 0x6FA2, 0x9DC7,
+	0x6FA3, 0x9DC8, 0x6FA4, 0x9DC9, 0x6FA5, 0x9DCA, 0x6FA6, 0x9DCB,
+	0x6FA7, 0xE5A2, 0x6FA8, 0x9DCC, 0x6FA9, 0x9DCD, 0x6FAA, 0x9DCE,
+	0x6FAB, 0x9DCF, 0x6FAC, 0x9DD0, 0x6FAD, 0x9DD1, 0x6FAE, 0x9DD2,
+	0x6FAF, 0x9DD3, 0x6FB0, 0x9DD4, 0x6FB1, 0x9DD5, 0x6FB2, 0x9DD6,
+	0x6FB3, 0xB0C4, 0x6FB4, 0x9DD7, 0x6FB5, 0x9DD8, 0x6FB6, 0xE5A4,
+	0x6FB7, 0x9DD9, 0x6FB8, 0x9DDA, 0x6FB9, 0xE5A3, 0x6FBA, 0x9DDB,
+	0x6FBB, 0x9DDC, 0x6FBC, 0x9DDD, 0x6FBD, 0x9DDE, 0x6FBE, 0x9DDF,
+	0x6FBF, 0x9DE0, 0x6FC0, 0xBCA4, 0x6FC1, 0x9DE1, 0x6FC2, 0xE5A5,
+	0x6FC3, 0x9DE2, 0x6FC4, 0x9DE3, 0x6FC5, 0x9DE4, 0x6FC6, 0x9DE5,
+	0x6FC7, 0x9DE6, 0x6FC8, 0x9DE7, 0x6FC9, 0xE5A1, 0x6FCA, 0x9DE8,
+	0x6FCB, 0x9DE9, 0x6FCC, 0x9DEA, 0x6FCD, 0x9DEB, 0x6FCE, 0x9DEC,
+	0x6FCF, 0x9DED, 0x6FD0, 0x9DEE, 0x6FD1, 0xE4FE, 0x6FD2, 0xB1F4,
+	0x6FD3, 0x9DEF, 0x6FD4, 0x9DF0, 0x6FD5, 0x9DF1, 0x6FD6, 0x9DF2,
+	0x6FD7, 0x9DF3, 0x6FD8, 0x9DF4, 0x6FD9, 0x9DF5, 0x6FDA, 0x9DF6,
+	0x6FDB, 0x9DF7, 0x6FDC, 0x9DF8, 0x6FDD, 0x9DF9, 0x6FDE, 0xE5A8,
+	0x6FDF, 0x9DFA, 0x6FE0, 0xE5A9, 0x6FE1, 0xE5A6, 0x6FE2, 0x9DFB,
+	0x6FE3, 0x9DFC, 0x6FE4, 0x9DFD, 0x6FE5, 0x9DFE, 0x6FE6, 0x9E40,
+	0x6FE7, 0x9E41, 0x6FE8, 0x9E42, 0x6FE9, 0x9E43, 0x6FEA, 0x9E44,
+	0x6FEB, 0x9E45, 0x6FEC, 0x9E46, 0x6FED, 0x9E47, 0x6FEE, 0xE5A7,
+	0x6FEF, 0xE5AA, 0x6FF0, 0x9E48, 0x6FF1, 0x9E49, 0x6FF2, 0x9E4A,
+	0x6FF3, 0x9E4B, 0x6FF4, 0x9E4C, 0x6FF5, 0x9E4D, 0x6FF6, 0x9E4E,
+	0x6FF7, 0x9E4F, 0x6FF8, 0x9E50, 0x6FF9, 0x9E51, 0x6FFA, 0x9E52,
+	0x6FFB, 0x9E53, 0x6FFC, 0x9E54, 0x6FFD, 0x9E55, 0x6FFE, 0x9E56,
+	0x6FFF, 0x9E57, 0x7000, 0x9E58, 0x7001, 0x9E59, 0x7002, 0x9E5A,
+	0x7003, 0x9E5B, 0x7004, 0x9E5C, 0x7005, 0x9E5D, 0x7006, 0x9E5E,
+	0x7007, 0x9E5F, 0x7008, 0x9E60, 0x7009, 0x9E61, 0x700A, 0x9E62,
+	0x700B, 0x9E63, 0x700C, 0x9E64, 0x700D, 0x9E65, 0x700E, 0x9E66,
+	0x700F, 0x9E67, 0x7010, 0x9E68, 0x7011, 0xC6D9, 0x7012, 0x9E69,
+	0x7013, 0x9E6A, 0x7014, 0x9E6B, 0x7015, 0x9E6C, 0x7016, 0x9E6D,
+	0x7017, 0x9E6E, 0x7018, 0x9E6F, 0x7019, 0x9E70, 0x701A, 0xE5AB,
+	0x701B, 0xE5AD, 0x701C, 0x9E71, 0x701D, 0x9E72, 0x701E, 0x9E73,
+	0x701F, 0x9E74, 0x7020, 0x9E75, 0x7021, 0x9E76, 0x7022, 0x9E77,
+	0x7023, 0xE5AC, 0x7024, 0x9E78, 0x7025, 0x9E79, 0x7026, 0x9E7A,
+	0x7027, 0x9E7B, 0x7028, 0x9E7C, 0x7029, 0x9E7D, 0x702A, 0x9E7E,
+	0x702B, 0x9E80, 0x702C, 0x9E81, 0x702D, 0x9E82, 0x702E, 0x9E83,
+	0x702F, 0x9E84, 0x7030, 0x9E85, 0x7031, 0x9E86, 0x7032, 0x9E87,
+	0x7033, 0x9E88, 0x7034, 0x9E89, 0x7035, 0xE5AF, 0x7036, 0x9E8A,
+	0x7037, 0x9E8B, 0x7038, 0x9E8C, 0x7039, 0xE5AE, 0x703A, 0x9E8D,
+	0x703B, 0x9E8E, 0x703C, 0x9E8F, 0x703D, 0x9E90, 0x703E, 0x9E91,
+	0x703F, 0x9E92, 0x7040, 0x9E93, 0x7041, 0x9E94, 0x7042, 0x9E95,
+	0x7043, 0x9E96, 0x7044, 0x9E97, 0x7045, 0x9E98, 0x7046, 0x9E99,
+	0x7047, 0x9E9A, 0x7048, 0x9E9B, 0x7049, 0x9E9C, 0x704A, 0x9E9D,
+	0x704B, 0x9E9E, 0x704C, 0xB9E0, 0x704D, 0x9E9F, 0x704E, 0x9EA0,
+	0x704F, 0xE5B0, 0x7050, 0x9EA1, 0x7051, 0x9EA2, 0x7052, 0x9EA3,
+	0x7053, 0x9EA4, 0x7054, 0x9EA5, 0x7055, 0x9EA6, 0x7056, 0x9EA7,
+	0x7057, 0x9EA8, 0x7058, 0x9EA9, 0x7059, 0x9EAA, 0x705A, 0x9EAB,
+	0x705B, 0x9EAC, 0x705C, 0x9EAD, 0x705D, 0x9EAE, 0x705E, 0xE5B1,
+	0x705F, 0x9EAF, 0x7060, 0x9EB0, 0x7061, 0x9EB1, 0x7062, 0x9EB2,
+	0x7063, 0x9EB3, 0x7064, 0x9EB4, 0x7065, 0x9EB5, 0x7066, 0x9EB6,
+	0x7067, 0x9EB7, 0x7068, 0x9EB8, 0x7069, 0x9EB9, 0x706A, 0x9EBA,
+	0x706B, 0xBBF0, 0x706C, 0xECE1, 0x706D, 0xC3F0, 0x706E, 0x9EBB,
+	0x706F, 0xB5C6, 0x7070, 0xBBD2, 0x7071, 0x9EBC, 0x7072, 0x9EBD,
+	0x7073, 0x9EBE, 0x7074, 0x9EBF, 0x7075, 0xC1E9, 0x7076, 0xD4EE,
+	0x7077, 0x9EC0, 0x7078, 0xBEC4, 0x7079, 0x9EC1, 0x707A, 0x9EC2,
+	0x707B, 0x9EC3, 0x707C, 0xD7C6, 0x707D, 0x9EC4, 0x707E, 0xD4D6,
+	0x707F, 0xB2D3, 0x7080, 0xECBE, 0x7081, 0x9EC5, 0x7082, 0x9EC6,
+	0x7083, 0x9EC7, 0x7084, 0x9EC8, 0x7085, 0xEAC1, 0x7086, 0x9EC9,
+	0x7087, 0x9ECA, 0x7088, 0x9ECB, 0x7089, 0xC2AF, 0x708A, 0xB4B6,
+	0x708B, 0x9ECC, 0x708C, 0x9ECD, 0x708D, 0x9ECE, 0x708E, 0xD1D7,
+	0x708F, 0x9ECF, 0x7090, 0x9ED0, 0x7091, 0x9ED1, 0x7092, 0xB3B4,
+	0x7093, 0x9ED2, 0x7094, 0xC8B2, 0x7095, 0xBFBB, 0x7096, 0xECC0,
+	0x7097, 0x9ED3, 0x7098, 0x9ED4, 0x7099, 0xD6CB, 0x709A, 0x9ED5,
+	0x709B, 0x9ED6, 0x709C, 0xECBF, 0x709D, 0xECC1, 0x709E, 0x9ED7,
+	0x709F, 0x9ED8, 0x70A0, 0x9ED9, 0x70A1, 0x9EDA, 0x70A2, 0x9EDB,
+	0x70A3, 0x9EDC, 0x70A4, 0x9EDD, 0x70A5, 0x9EDE, 0x70A6, 0x9EDF,
+	0x70A7, 0x9EE0, 0x70A8, 0x9EE1, 0x70A9, 0x9EE2, 0x70AA, 0x9EE3,
+	0x70AB, 0xECC5, 0x70AC, 0xBEE6, 0x70AD, 0xCCBF, 0x70AE, 0xC5DA,
+	0x70AF, 0xBEBC, 0x70B0, 0x9EE4, 0x70B1, 0xECC6, 0x70B2, 0x9EE5,
+	0x70B3, 0xB1FE, 0x70B4, 0x9EE6, 0x70B5, 0x9EE7, 0x70B6, 0x9EE8,
+	0x70B7, 0xECC4, 0x70B8, 0xD5A8, 0x70B9, 0xB5E3, 0x70BA, 0x9EE9,
+	0x70BB, 0xECC2, 0x70BC, 0xC1B6, 0x70BD, 0xB3E3, 0x70BE, 0x9EEA,
+	0x70BF, 0x9EEB, 0x70C0, 0xECC3, 0x70C1, 0xCBB8, 0x70C2, 0xC0C3,
+	0x70C3, 0xCCFE, 0x70C4, 0x9EEC, 0x70C5, 0x9EED, 0x70C6, 0x9EEE,
+	0x70C7, 0x9EEF, 0x70C8, 0xC1D2, 0x70C9, 0x9EF0, 0x70CA, 0xECC8,
+	0x70CB, 0x9EF1, 0x70CC, 0x9EF2, 0x70CD, 0x9EF3, 0x70CE, 0x9EF4,
+	0x70CF, 0x9EF5, 0x70D0, 0x9EF6, 0x70D1, 0x9EF7, 0x70D2, 0x9EF8,
+	0x70D3, 0x9EF9, 0x70D4, 0x9EFA, 0x70D5, 0x9EFB, 0x70D6, 0x9EFC,
+	0x70D7, 0x9EFD, 0x70D8, 0xBAE6, 0x70D9, 0xC0D3, 0x70DA, 0x9EFE,
+	0x70DB, 0xD6F2, 0x70DC, 0x9F40, 0x70DD, 0x9F41, 0x70DE, 0x9F42,
+	0x70DF, 0xD1CC, 0x70E0, 0x9F43, 0x70E1, 0x9F44, 0x70E2, 0x9F45,
+	0x70E3, 0x9F46, 0x70E4, 0xBFBE, 0x70E5, 0x9F47, 0x70E6, 0xB7B3,
+	0x70E7, 0xC9D5, 0x70E8, 0xECC7, 0x70E9, 0xBBE2, 0x70EA, 0x9F48,
+	0x70EB, 0xCCCC, 0x70EC, 0xBDFD, 0x70ED, 0xC8C8, 0x70EE, 0x9F49,
+	0x70EF, 0xCFA9, 0x70F0, 0x9F4A, 0x70F1, 0x9F4B, 0x70F2, 0x9F4C,
+	0x70F3, 0x9F4D, 0x70F4, 0x9F4E, 0x70F5, 0x9F4F, 0x70F6, 0x9F50,
+	0x70F7, 0xCDE9, 0x70F8, 0x9F51, 0x70F9, 0xC5EB, 0x70FA, 0x9F52,
+	0x70FB, 0x9F53, 0x70FC, 0x9F54, 0x70FD, 0xB7E9, 0x70FE, 0x9F55,
+	0x70FF, 0x9F56, 0x7100, 0x9F57, 0x7101, 0x9F58, 0x7102, 0x9F59,
+	0x7103, 0x9F5A, 0x7104, 0x9F5B, 0x7105, 0x9F5C, 0x7106, 0x9F5D,
+	0x7107, 0x9F5E, 0x7108, 0x9F5F, 0x7109, 0xD1C9, 0x710A, 0xBAB8,
+	0x710B, 0x9F60, 0x710C, 0x9F61, 0x710D, 0x9F62, 0x710E, 0x9F63,
+	0x710F, 0x9F64, 0x7110, 0xECC9, 0x7111, 0x9F65, 0x7112, 0x9F66,
+	0x7113, 0xECCA, 0x7114, 0x9F67, 0x7115, 0xBBC0, 0x7116, 0xECCB,
+	0x7117, 0x9F68, 0x7118, 0xECE2, 0x7119, 0xB1BA, 0x711A, 0xB7D9,
+	0x711B, 0x9F69, 0x711C, 0x9F6A, 0x711D, 0x9F6B, 0x711E, 0x9F6C,
+	0x711F, 0x9F6D, 0x7120, 0x9F6E, 0x7121, 0x9F6F, 0x7122, 0x9F70,
+	0x7123, 0x9F71, 0x7124, 0x9F72, 0x7125, 0x9F73, 0x7126, 0xBDB9,
+	0x7127, 0x9F74, 0x7128, 0x9F75, 0x7129, 0x9F76, 0x712A, 0x9F77,
+	0x712B, 0x9F78, 0x712C, 0x9F79, 0x712D, 0x9F7A, 0x712E, 0x9F7B,
+	0x712F, 0xECCC, 0x7130, 0xD1E6, 0x7131, 0xECCD, 0x7132, 0x9F7C,
+	0x7133, 0x9F7D, 0x7134, 0x9F7E, 0x7135, 0x9F80, 0x7136, 0xC8BB,
+	0x7137, 0x9F81, 0x7138, 0x9F82, 0x7139, 0x9F83, 0x713A, 0x9F84,
+	0x713B, 0x9F85, 0x713C, 0x9F86, 0x713D, 0x9F87, 0x713E, 0x9F88,
+	0x713F, 0x9F89, 0x7140, 0x9F8A, 0x7141, 0x9F8B, 0x7142, 0x9F8C,
+	0x7143, 0x9F8D, 0x7144, 0x9F8E, 0x7145, 0xECD1, 0x7146, 0x9F8F,
+	0x7147, 0x9F90, 0x7148, 0x9F91, 0x7149, 0x9F92, 0x714A, 0xECD3,
+	0x714B, 0x9F93, 0x714C, 0xBBCD, 0x714D, 0x9F94, 0x714E, 0xBCE5,
+	0x714F, 0x9F95, 0x7150, 0x9F96, 0x7151, 0x9F97, 0x7152, 0x9F98,
+	0x7153, 0x9F99, 0x7154, 0x9F9A, 0x7155, 0x9F9B, 0x7156, 0x9F9C,
+	0x7157, 0x9F9D, 0x7158, 0x9F9E, 0x7159, 0x9F9F, 0x715A, 0x9FA0,
+	0x715B, 0x9FA1, 0x715C, 0xECCF, 0x715D, 0x9FA2, 0x715E, 0xC9B7,
+	0x715F, 0x9FA3, 0x7160, 0x9FA4, 0x7161, 0x9FA5, 0x7162, 0x9FA6,
+	0x7163, 0x9FA7, 0x7164, 0xC3BA, 0x7165, 0x9FA8, 0x7166, 0xECE3,
+	0x7167, 0xD5D5, 0x7168, 0xECD0, 0x7169, 0x9FA9, 0x716A, 0x9FAA,
+	0x716B, 0x9FAB, 0x716C, 0x9FAC, 0x716D, 0x9FAD, 0x716E, 0xD6F3,
+	0x716F, 0x9FAE, 0x7170, 0x9FAF, 0x7171, 0x9FB0, 0x7172, 0xECD2,
+	0x7173, 0xECCE, 0x7174, 0x9FB1, 0x7175, 0x9FB2, 0x7176, 0x9FB3,
+	0x7177, 0x9FB4, 0x7178, 0xECD4, 0x7179, 0x9FB5, 0x717A, 0xECD5,
+	0x717B, 0x9FB6, 0x717C, 0x9FB7, 0x717D, 0xC9BF, 0x717E, 0x9FB8,
+	0x717F, 0x9FB9, 0x7180, 0x9FBA, 0x7181, 0x9FBB, 0x7182, 0x9FBC,
+	0x7183, 0x9FBD, 0x7184, 0xCFA8, 0x7185, 0x9FBE, 0x7186, 0x9FBF,
+	0x7187, 0x9FC0, 0x7188, 0x9FC1, 0x7189, 0x9FC2, 0x718A, 0xD0DC,
+	0x718B, 0x9FC3, 0x718C, 0x9FC4, 0x718D, 0x9FC5, 0x718E, 0x9FC6,
+	0x718F, 0xD1AC, 0x7190, 0x9FC7, 0x7191, 0x9FC8, 0x7192, 0x9FC9,
+	0x7193, 0x9FCA, 0x7194, 0xC8DB, 0x7195, 0x9FCB, 0x7196, 0x9FCC,
+	0x7197, 0x9FCD, 0x7198, 0xECD6, 0x7199, 0xCEF5, 0x719A, 0x9FCE,
+	0x719B, 0x9FCF, 0x719C, 0x9FD0, 0x719D, 0x9FD1, 0x719E, 0x9FD2,
+	0x719F, 0xCAEC, 0x71A0, 0xECDA, 0x71A1, 0x9FD3, 0x71A2, 0x9FD4,
+	0x71A3, 0x9FD5, 0x71A4, 0x9FD6, 0x71A5, 0x9FD7, 0x71A6, 0x9FD8,
+	0x71A7, 0x9FD9, 0x71A8, 0xECD9, 0x71A9, 0x9FDA, 0x71AA, 0x9FDB,
+	0x71AB, 0x9FDC, 0x71AC, 0xB0BE, 0x71AD, 0x9FDD, 0x71AE, 0x9FDE,
+	0x71AF, 0x9FDF, 0x71B0, 0x9FE0, 0x71B1, 0x9FE1, 0x71B2, 0x9FE2,
+	0x71B3, 0xECD7, 0x71B4, 0x9FE3, 0x71B5, 0xECD8, 0x71B6, 0x9FE4,
+	0x71B7, 0x9FE5, 0x71B8, 0x9FE6, 0x71B9, 0xECE4, 0x71BA, 0x9FE7,
+	0x71BB, 0x9FE8, 0x71BC, 0x9FE9, 0x71BD, 0x9FEA, 0x71BE, 0x9FEB,
+	0x71BF, 0x9FEC, 0x71C0, 0x9FED, 0x71C1, 0x9FEE, 0x71C2, 0x9FEF,
+	0x71C3, 0xC8BC, 0x71C4, 0x9FF0, 0x71C5, 0x9FF1, 0x71C6, 0x9FF2,
+	0x71C7, 0x9FF3, 0x71C8, 0x9FF4, 0x71C9, 0x9FF5, 0x71CA, 0x9FF6,
+	0x71CB, 0x9FF7, 0x71CC, 0x9FF8, 0x71CD, 0x9FF9, 0x71CE, 0xC1C7,
+	0x71CF, 0x9FFA, 0x71D0, 0x9FFB, 0x71D1, 0x9FFC, 0x71D2, 0x9FFD,
+	0x71D3, 0x9FFE, 0x71D4, 0xECDC, 0x71D5, 0xD1E0, 0x71D6, 0xA040,
+	0x71D7, 0xA041, 0x71D8, 0xA042, 0x71D9, 0xA043, 0x71DA, 0xA044,
+	0x71DB, 0xA045, 0x71DC, 0xA046, 0x71DD, 0xA047, 0x71DE, 0xA048,
+	0x71DF, 0xA049, 0x71E0, 0xECDB, 0x71E1, 0xA04A, 0x71E2, 0xA04B,
+	0x71E3, 0xA04C, 0x71E4, 0xA04D, 0x71E5, 0xD4EF, 0x71E6, 0xA04E,
+	0x71E7, 0xECDD, 0x71E8, 0xA04F, 0x71E9, 0xA050, 0x71EA, 0xA051,
+	0x71EB, 0xA052, 0x71EC, 0xA053, 0x71ED, 0xA054, 0x71EE, 0xDBC6,
+	0x71EF, 0xA055, 0x71F0, 0xA056, 0x71F1, 0xA057, 0x71F2, 0xA058,
+	0x71F3, 0xA059, 0x71F4, 0xA05A, 0x71F5, 0xA05B, 0x71F6, 0xA05C,
+	0x71F7, 0xA05D, 0x71F8, 0xA05E, 0x71F9, 0xECDE, 0x71FA, 0xA05F,
+	0x71FB, 0xA060, 0x71FC, 0xA061, 0x71FD, 0xA062, 0x71FE, 0xA063,
+	0x71FF, 0xA064, 0x7200, 0xA065, 0x7201, 0xA066, 0x7202, 0xA067,
+	0x7203, 0xA068, 0x7204, 0xA069, 0x7205, 0xA06A, 0x7206, 0xB1AC,
+	0x7207, 0xA06B, 0x7208, 0xA06C, 0x7209, 0xA06D, 0x720A, 0xA06E,
+	0x720B, 0xA06F, 0x720C, 0xA070, 0x720D, 0xA071, 0x720E, 0xA072,
+	0x720F, 0xA073, 0x7210, 0xA074, 0x7211, 0xA075, 0x7212, 0xA076,
+	0x7213, 0xA077, 0x7214, 0xA078, 0x7215, 0xA079, 0x7216, 0xA07A,
+	0x7217, 0xA07B, 0x7218, 0xA07C, 0x7219, 0xA07D, 0x721A, 0xA07E,
+	0x721B, 0xA080, 0x721C, 0xA081, 0x721D, 0xECDF, 0x721E, 0xA082,
+	0x721F, 0xA083, 0x7220, 0xA084, 0x7221, 0xA085, 0x7222, 0xA086,
+	0x7223, 0xA087, 0x7224, 0xA088, 0x7225, 0xA089, 0x7226, 0xA08A,
+	0x7227, 0xA08B, 0x7228, 0xECE0, 0x7229, 0xA08C, 0x722A, 0xD7A6,
+	0x722B, 0xA08D, 0x722C, 0xC5C0, 0x722D, 0xA08E, 0x722E, 0xA08F,
+	0x722F, 0xA090, 0x7230, 0xEBBC, 0x7231, 0xB0AE, 0x7232, 0xA091,
+	0x7233, 0xA092, 0x7234, 0xA093, 0x7235, 0xBEF4, 0x7236, 0xB8B8,
+	0x7237, 0xD2AF, 0x7238, 0xB0D6, 0x7239, 0xB5F9, 0x723A, 0xA094,
+	0x723B, 0xD8B3, 0x723C, 0xA095, 0x723D, 0xCBAC, 0x723E, 0xA096,
+	0x723F, 0xE3DD, 0x7240, 0xA097, 0x7241, 0xA098, 0x7242, 0xA099,
+	0x7243, 0xA09A, 0x7244, 0xA09B, 0x7245, 0xA09C, 0x7246, 0xA09D,
+	0x7247, 0xC6AC, 0x7248, 0xB0E6, 0x7249, 0xA09E, 0x724A, 0xA09F,
+	0x724B, 0xA0A0, 0x724C, 0xC5C6, 0x724D, 0xEBB9, 0x724E, 0xA0A1,
+	0x724F, 0xA0A2, 0x7250, 0xA0A3, 0x7251, 0xA0A4, 0x7252, 0xEBBA,
+	0x7253, 0xA0A5, 0x7254, 0xA0A6, 0x7255, 0xA0A7, 0x7256, 0xEBBB,
+	0x7257, 0xA0A8, 0x7258, 0xA0A9, 0x7259, 0xD1C0, 0x725A, 0xA0AA,
+	0x725B, 0xC5A3, 0x725C, 0xA0AB, 0x725D, 0xEAF2, 0x725E, 0xA0AC,
+	0x725F, 0xC4B2, 0x7260, 0xA0AD, 0x7261, 0xC4B5, 0x7262, 0xC0CE,
+	0x7263, 0xA0AE, 0x7264, 0xA0AF, 0x7265, 0xA0B0, 0x7266, 0xEAF3,
+	0x7267, 0xC4C1, 0x7268, 0xA0B1, 0x7269, 0xCEEF, 0x726A, 0xA0B2,
+	0x726B, 0xA0B3, 0x726C, 0xA0B4, 0x726D, 0xA0B5, 0x726E, 0xEAF0,
+	0x726F, 0xEAF4, 0x7270, 0xA0B6, 0x7271, 0xA0B7, 0x7272, 0xC9FC,
+	0x7273, 0xA0B8, 0x7274, 0xA0B9, 0x7275, 0xC7A3, 0x7276, 0xA0BA,
+	0x7277, 0xA0BB, 0x7278, 0xA0BC, 0x7279, 0xCCD8, 0x727A, 0xCEFE,
+	0x727B, 0xA0BD, 0x727C, 0xA0BE, 0x727D, 0xA0BF, 0x727E, 0xEAF5,
+	0x727F, 0xEAF6, 0x7280, 0xCFAC, 0x7281, 0xC0E7, 0x7282, 0xA0C0,
+	0x7283, 0xA0C1, 0x7284, 0xEAF7, 0x7285, 0xA0C2, 0x7286, 0xA0C3,
+	0x7287, 0xA0C4, 0x7288, 0xA0C5, 0x7289, 0xA0C6, 0x728A, 0xB6BF,
+	0x728B, 0xEAF8, 0x728C, 0xA0C7, 0x728D, 0xEAF9, 0x728E, 0xA0C8,
+	0x728F, 0xEAFA, 0x7290, 0xA0C9, 0x7291, 0xA0CA, 0x7292, 0xEAFB,
+	0x7293, 0xA0CB, 0x7294, 0xA0CC, 0x7295, 0xA0CD, 0x7296, 0xA0CE,
+	0x7297, 0xA0CF, 0x7298, 0xA0D0, 0x7299, 0xA0D1, 0x729A, 0xA0D2,
+	0x729B, 0xA0D3, 0x729C, 0xA0D4, 0x729D, 0xA0D5, 0x729E, 0xA0D6,
+	0x729F, 0xEAF1, 0x72A0, 0xA0D7, 0x72A1, 0xA0D8, 0x72A2, 0xA0D9,
+	0x72A3, 0xA0DA, 0x72A4, 0xA0DB, 0x72A5, 0xA0DC, 0x72A6, 0xA0DD,
+	0x72A7, 0xA0DE, 0x72A8, 0xA0DF, 0x72A9, 0xA0E0, 0x72AA, 0xA0E1,
+	0x72AB, 0xA0E2, 0x72AC, 0xC8AE, 0x72AD, 0xE1EB, 0x72AE, 0xA0E3,
+	0x72AF, 0xB7B8, 0x72B0, 0xE1EC, 0x72B1, 0xA0E4, 0x72B2, 0xA0E5,
+	0x72B3, 0xA0E6, 0x72B4, 0xE1ED, 0x72B5, 0xA0E7, 0x72B6, 0xD7B4,
+	0x72B7, 0xE1EE, 0x72B8, 0xE1EF, 0x72B9, 0xD3CC, 0x72BA, 0xA0E8,
+	0x72BB, 0xA0E9, 0x72BC, 0xA0EA, 0x72BD, 0xA0EB, 0x72BE, 0xA0EC,
+	0x72BF, 0xA0ED, 0x72C0, 0xA0EE, 0x72C1, 0xE1F1, 0x72C2, 0xBFF1,
+	0x72C3, 0xE1F0, 0x72C4, 0xB5D2, 0x72C5, 0xA0EF, 0x72C6, 0xA0F0,
+	0x72C7, 0xA0F1, 0x72C8, 0xB1B7, 0x72C9, 0xA0F2, 0x72CA, 0xA0F3,
+	0x72CB, 0xA0F4, 0x72CC, 0xA0F5, 0x72CD, 0xE1F3, 0x72CE, 0xE1F2,
+	0x72CF, 0xA0F6, 0x72D0, 0xBAFC, 0x72D1, 0xA0F7, 0x72D2, 0xE1F4,
+	0x72D3, 0xA0F8, 0x72D4, 0xA0F9, 0x72D5, 0xA0FA, 0x72D6, 0xA0FB,
+	0x72D7, 0xB9B7, 0x72D8, 0xA0FC, 0x72D9, 0xBED1, 0x72DA, 0xA0FD,
+	0x72DB, 0xA0FE, 0x72DC, 0xAA40, 0x72DD, 0xAA41, 0x72DE, 0xC4FC,
+	0x72DF, 0xAA42, 0x72E0, 0xBADD, 0x72E1, 0xBDC6, 0x72E2, 0xAA43,
+	0x72E3, 0xAA44, 0x72E4, 0xAA45, 0x72E5, 0xAA46, 0x72E6, 0xAA47,
+	0x72E7, 0xAA48, 0x72E8, 0xE1F5, 0x72E9, 0xE1F7, 0x72EA, 0xAA49,
+	0x72EB, 0xAA4A, 0x72EC, 0xB6C0, 0x72ED, 0xCFC1, 0x72EE, 0xCAA8,
+	0x72EF, 0xE1F6, 0x72F0, 0xD5F8, 0x72F1, 0xD3FC, 0x72F2, 0xE1F8,
+	0x72F3, 0xE1FC, 0x72F4, 0xE1F9, 0x72F5, 0xAA4B, 0x72F6, 0xAA4C,
+	0x72F7, 0xE1FA, 0x72F8, 0xC0EA, 0x72F9, 0xAA4D, 0x72FA, 0xE1FE,
+	0x72FB, 0xE2A1, 0x72FC, 0xC0C7, 0x72FD, 0xAA4E, 0x72FE, 0xAA4F,
+	0x72FF, 0xAA50, 0x7300, 0xAA51, 0x7301, 0xE1FB, 0x7302, 0xAA52,
+	0x7303, 0xE1FD, 0x7304, 0xAA53, 0x7305, 0xAA54, 0x7306, 0xAA55,
+	0x7307, 0xAA56, 0x7308, 0xAA57, 0x7309, 0xAA58, 0x730A, 0xE2A5,
+	0x730B, 0xAA59, 0x730C, 0xAA5A, 0x730D, 0xAA5B, 0x730E, 0xC1D4,
+	0x730F, 0xAA5C, 0x7310, 0xAA5D, 0x7311, 0xAA5E, 0x7312, 0xAA5F,
+	0x7313, 0xE2A3, 0x7314, 0xAA60, 0x7315, 0xE2A8, 0x7316, 0xB2FE,
+	0x7317, 0xE2A2, 0x7318, 0xAA61, 0x7319, 0xAA62, 0x731A, 0xAA63,
+	0x731B, 0xC3CD, 0x731C, 0xB2C2, 0x731D, 0xE2A7, 0x731E, 0xE2A6,
+	0x731F, 0xAA64, 0x7320, 0xAA65, 0x7321, 0xE2A4, 0x7322, 0xE2A9,
+	0x7323, 0xAA66, 0x7324, 0xAA67, 0x7325, 0xE2AB, 0x7326, 0xAA68,
+	0x7327, 0xAA69, 0x7328, 0xAA6A, 0x7329, 0xD0C9, 0x732A, 0xD6ED,
+	0x732B, 0xC3A8, 0x732C, 0xE2AC, 0x732D, 0xAA6B, 0x732E, 0xCFD7,
+	0x732F, 0xAA6C, 0x7330, 0xAA6D, 0x7331, 0xE2AE, 0x7332, 0xAA6E,
+	0x7333, 0xAA6F, 0x7334, 0xBAEF, 0x7335, 0xAA70, 0x7336, 0xAA71,
+	0x7337, 0xE9E0, 0x7338, 0xE2AD, 0x7339, 0xE2AA, 0x733A, 0xAA72,
+	0x733B, 0xAA73, 0x733C, 0xAA74, 0x733D, 0xAA75, 0x733E, 0xBBAB,
+	0x733F, 0xD4B3, 0x7340, 0xAA76, 0x7341, 0xAA77, 0x7342, 0xAA78,
+	0x7343, 0xAA79, 0x7344, 0xAA7A, 0x7345, 0xAA7B, 0x7346, 0xAA7C,
+	0x7347, 0xAA7D, 0x7348, 0xAA7E, 0x7349, 0xAA80, 0x734A, 0xAA81,
+	0x734B, 0xAA82, 0x734C, 0xAA83, 0x734D, 0xE2B0, 0x734E, 0xAA84,
+	0x734F, 0xAA85, 0x7350, 0xE2AF, 0x7351, 0xAA86, 0x7352, 0xE9E1,
+	0x7353, 0xAA87, 0x7354, 0xAA88, 0x7355, 0xAA89, 0x7356, 0xAA8A,
+	0x7357, 0xE2B1, 0x7358, 0xAA8B, 0x7359, 0xAA8C, 0x735A, 0xAA8D,
+	0x735B, 0xAA8E, 0x735C, 0xAA8F, 0x735D, 0xAA90, 0x735E, 0xAA91,
+	0x735F, 0xAA92, 0x7360, 0xE2B2, 0x7361, 0xAA93, 0x7362, 0xAA94,
+	0x7363, 0xAA95, 0x7364, 0xAA96, 0x7365, 0xAA97, 0x7366, 0xAA98,
+	0x7367, 0xAA99, 0x7368, 0xAA9A, 0x7369, 0xAA9B, 0x736A, 0xAA9C,
+	0x736B, 0xAA9D, 0x736C, 0xE2B3, 0x736D, 0xCCA1, 0x736E, 0xAA9E,
+	0x736F, 0xE2B4, 0x7370, 0xAA9F, 0x7371, 0xAAA0, 0x7372, 0xAB40,
+	0x7373, 0xAB41, 0x7374, 0xAB42, 0x7375, 0xAB43, 0x7376, 0xAB44,
+	0x7377, 0xAB45, 0x7378, 0xAB46, 0x7379, 0xAB47, 0x737A, 0xAB48,
+	0x737B, 0xAB49, 0x737C, 0xAB4A, 0x737D, 0xAB4B, 0x737E, 0xE2B5,
+	0x737F, 0xAB4C, 0x7380, 0xAB4D, 0x7381, 0xAB4E, 0x7382, 0xAB4F,
+	0x7383, 0xAB50, 0x7384, 0xD0FE, 0x7385, 0xAB51, 0x7386, 0xAB52,
+	0x7387, 0xC2CA, 0x7388, 0xAB53, 0x7389, 0xD3F1, 0x738A, 0xAB54,
+	0x738B, 0xCDF5, 0x738C, 0xAB55, 0x738D, 0xAB56, 0x738E, 0xE7E0,
+	0x738F, 0xAB57, 0x7390, 0xAB58, 0x7391, 0xE7E1, 0x7392, 0xAB59,
+	0x7393, 0xAB5A, 0x7394, 0xAB5B, 0x7395, 0xAB5C, 0x7396, 0xBEC1,
+	0x7397, 0xAB5D, 0x7398, 0xAB5E, 0x7399, 0xAB5F, 0x739A, 0xAB60,
+	0x739B, 0xC2EA, 0x739C, 0xAB61, 0x739D, 0xAB62, 0x739E, 0xAB63,
+	0x739F, 0xE7E4, 0x73A0, 0xAB64, 0x73A1, 0xAB65, 0x73A2, 0xE7E3,
+	0x73A3, 0xAB66, 0x73A4, 0xAB67, 0x73A5, 0xAB68, 0x73A6, 0xAB69,
+	0x73A7, 0xAB6A, 0x73A8, 0xAB6B, 0x73A9, 0xCDE6, 0x73AA, 0xAB6C,
+	0x73AB, 0xC3B5, 0x73AC, 0xAB6D, 0x73AD, 0xAB6E, 0x73AE, 0xE7E2,
+	0x73AF, 0xBBB7, 0x73B0, 0xCFD6, 0x73B1, 0xAB6F, 0x73B2, 0xC1E1,
+	0x73B3, 0xE7E9, 0x73B4, 0xAB70, 0x73B5, 0xAB71, 0x73B6, 0xAB72,
+	0x73B7, 0xE7E8, 0x73B8, 0xAB73, 0x73B9, 0xAB74, 0x73BA, 0xE7F4,
+	0x73BB, 0xB2A3, 0x73BC, 0xAB75, 0x73BD, 0xAB76, 0x73BE, 0xAB77,
+	0x73BF, 0xAB78, 0x73C0, 0xE7EA, 0x73C1, 0xAB79, 0x73C2, 0xE7E6,
+	0x73C3, 0xAB7A, 0x73C4, 0xAB7B, 0x73C5, 0xAB7C, 0x73C6, 0xAB7D,
+	0x73C7, 0xAB7E, 0x73C8, 0xE7EC, 0x73C9, 0xE7EB, 0x73CA, 0xC9BA,
+	0x73CB, 0xAB80, 0x73CC, 0xAB81, 0x73CD, 0xD5E4, 0x73CE, 0xAB82,
+	0x73CF, 0xE7E5, 0x73D0, 0xB7A9, 0x73D1, 0xE7E7, 0x73D2, 0xAB83,
+	0x73D3, 0xAB84, 0x73D4, 0xAB85, 0x73D5, 0xAB86, 0x73D6, 0xAB87,
+	0x73D7, 0xAB88, 0x73D8, 0xAB89, 0x73D9, 0xE7EE, 0x73DA, 0xAB8A,
+	0x73DB, 0xAB8B, 0x73DC, 0xAB8C, 0x73DD, 0xAB8D, 0x73DE, 0xE7F3,
+	0x73DF, 0xAB8E, 0x73E0, 0xD6E9, 0x73E1, 0xAB8F, 0x73E2, 0xAB90,
+	0x73E3, 0xAB91, 0x73E4, 0xAB92, 0x73E5, 0xE7ED, 0x73E6, 0xAB93,
+	0x73E7, 0xE7F2, 0x73E8, 0xAB94, 0x73E9, 0xE7F1, 0x73EA, 0xAB95,
+	0x73EB, 0xAB96, 0x73EC, 0xAB97, 0x73ED, 0xB0E0, 0x73EE, 0xAB98,
+	0x73EF, 0xAB99, 0x73F0, 0xAB9A, 0x73F1, 0xAB9B, 0x73F2, 0xE7F5,
+	0x73F3, 0xAB9C, 0x73F4, 0xAB9D, 0x73F5, 0xAB9E, 0x73F6, 0xAB9F,
+	0x73F7, 0xABA0, 0x73F8, 0xAC40, 0x73F9, 0xAC41, 0x73FA, 0xAC42,
+	0x73FB, 0xAC43, 0x73FC, 0xAC44, 0x73FD, 0xAC45, 0x73FE, 0xAC46,
+	0x73FF, 0xAC47, 0x7400, 0xAC48, 0x7401, 0xAC49, 0x7402, 0xAC4A,
+	0x7403, 0xC7F2, 0x7404, 0xAC4B, 0x7405, 0xC0C5, 0x7406, 0xC0ED,
+	0x7407, 0xAC4C, 0x7408, 0xAC4D, 0x7409, 0xC1F0, 0x740A, 0xE7F0,
+	0x740B, 0xAC4E, 0x740C, 0xAC4F, 0x740D, 0xAC50, 0x740E, 0xAC51,
+	0x740F, 0xE7F6, 0x7410, 0xCBF6, 0x7411, 0xAC52, 0x7412, 0xAC53,
+	0x7413, 0xAC54, 0x7414, 0xAC55, 0x7415, 0xAC56, 0x7416, 0xAC57,
+	0x7417, 0xAC58, 0x7418, 0xAC59, 0x7419, 0xAC5A, 0x741A, 0xE8A2,
+	0x741B, 0xE8A1, 0x741C, 0xAC5B, 0x741D, 0xAC5C, 0x741E, 0xAC5D,
+	0x741F, 0xAC5E, 0x7420, 0xAC5F, 0x7421, 0xAC60, 0x7422, 0xD7C1,
+	0x7423, 0xAC61, 0x7424, 0xAC62, 0x7425, 0xE7FA, 0x7426, 0xE7F9,
+	0x7427, 0xAC63, 0x7428, 0xE7FB, 0x7429, 0xAC64, 0x742A, 0xE7F7,
+	0x742B, 0xAC65, 0x742C, 0xE7FE, 0x742D, 0xAC66, 0x742E, 0xE7FD,
+	0x742F, 0xAC67, 0x7430, 0xE7FC, 0x7431, 0xAC68, 0x7432, 0xAC69,
+	0x7433, 0xC1D5, 0x7434, 0xC7D9, 0x7435, 0xC5FD, 0x7436, 0xC5C3,
+	0x7437, 0xAC6A, 0x7438, 0xAC6B, 0x7439, 0xAC6C, 0x743A, 0xAC6D,
+	0x743B, 0xAC6E, 0x743C, 0xC7ED, 0x743D, 0xAC6F, 0x743E, 0xAC70,
+	0x743F, 0xAC71, 0x7440, 0xAC72, 0x7441, 0xE8A3, 0x7442, 0xAC73,
+	0x7443, 0xAC74, 0x7444, 0xAC75, 0x7445, 0xAC76, 0x7446, 0xAC77,
+	0x7447, 0xAC78, 0x7448, 0xAC79, 0x7449, 0xAC7A, 0x744A, 0xAC7B,
+	0x744B, 0xAC7C, 0x744C, 0xAC7D, 0x744D, 0xAC7E, 0x744E, 0xAC80,
+	0x744F, 0xAC81, 0x7450, 0xAC82, 0x7451, 0xAC83, 0x7452, 0xAC84,
+	0x7453, 0xAC85, 0x7454, 0xAC86, 0x7455, 0xE8A6, 0x7456, 0xAC87,
+	0x7457, 0xE8A5, 0x7458, 0xAC88, 0x7459, 0xE8A7, 0x745A, 0xBAF7,
+	0x745B, 0xE7F8, 0x745C, 0xE8A4, 0x745D, 0xAC89, 0x745E, 0xC8F0,
+	0x745F, 0xC9AA, 0x7460, 0xAC8A, 0x7461, 0xAC8B, 0x7462, 0xAC8C,
+	0x7463, 0xAC8D, 0x7464, 0xAC8E, 0x7465, 0xAC8F, 0x7466, 0xAC90,
+	0x7467, 0xAC91, 0x7468, 0xAC92, 0x7469, 0xAC93, 0x746A, 0xAC94,
+	0x746B, 0xAC95, 0x746C, 0xAC96, 0x746D, 0xE8A9, 0x746E, 0xAC97,
+	0x746F, 0xAC98, 0x7470, 0xB9E5, 0x7471, 0xAC99, 0x7472, 0xAC9A,
+	0x7473, 0xAC9B, 0x7474, 0xAC9C, 0x7475, 0xAC9D, 0x7476, 0xD1FE,
+	0x7477, 0xE8A8, 0x7478, 0xAC9E, 0x7479, 0xAC9F, 0x747A, 0xACA0,
+	0x747B, 0xAD40, 0x747C, 0xAD41, 0x747D, 0xAD42, 0x747E, 0xE8AA,
+	0x747F, 0xAD43, 0x7480, 0xE8AD, 0x7481, 0xE8AE, 0x7482, 0xAD44,
+	0x7483, 0xC1A7, 0x7484, 0xAD45, 0x7485, 0xAD46, 0x7486, 0xAD47,
+	0x7487, 0xE8AF, 0x7488, 0xAD48, 0x7489, 0xAD49, 0x748A, 0xAD4A,
+	0x748B, 0xE8B0, 0x748C, 0xAD4B, 0x748D, 0xAD4C, 0x748E, 0xE8AC,
+	0x748F, 0xAD4D, 0x7490, 0xE8B4, 0x7491, 0xAD4E, 0x7492, 0xAD4F,
+	0x7493, 0xAD50, 0x7494, 0xAD51, 0x7495, 0xAD52, 0x7496, 0xAD53,
+	0x7497, 0xAD54, 0x7498, 0xAD55, 0x7499, 0xAD56, 0x749A, 0xAD57,
+	0x749B, 0xAD58, 0x749C, 0xE8AB, 0x749D, 0xAD59, 0x749E, 0xE8B1,
+	0x749F, 0xAD5A, 0x74A0, 0xAD5B, 0x74A1, 0xAD5C, 0x74A2, 0xAD5D,
+	0x74A3, 0xAD5E, 0x74A4, 0xAD5F, 0x74A5, 0xAD60, 0x74A6, 0xAD61,
+	0x74A7, 0xE8B5, 0x74A8, 0xE8B2, 0x74A9, 0xE8B3, 0x74AA, 0xAD62,
+	0x74AB, 0xAD63, 0x74AC, 0xAD64, 0x74AD, 0xAD65, 0x74AE, 0xAD66,
+	0x74AF, 0xAD67, 0x74B0, 0xAD68, 0x74B1, 0xAD69, 0x74B2, 0xAD6A,
+	0x74B3, 0xAD6B, 0x74B4, 0xAD6C, 0x74B5, 0xAD6D, 0x74B6, 0xAD6E,
+	0x74B7, 0xAD6F, 0x74B8, 0xAD70, 0x74B9, 0xAD71, 0x74BA, 0xE8B7,
+	0x74BB, 0xAD72, 0x74BC, 0xAD73, 0x74BD, 0xAD74, 0x74BE, 0xAD75,
+	0x74BF, 0xAD76, 0x74C0, 0xAD77, 0x74C1, 0xAD78, 0x74C2, 0xAD79,
+	0x74C3, 0xAD7A, 0x74C4, 0xAD7B, 0x74C5, 0xAD7C, 0x74C6, 0xAD7D,
+	0x74C7, 0xAD7E, 0x74C8, 0xAD80, 0x74C9, 0xAD81, 0x74CA, 0xAD82,
+	0x74CB, 0xAD83, 0x74CC, 0xAD84, 0x74CD, 0xAD85, 0x74CE, 0xAD86,
+	0x74CF, 0xAD87, 0x74D0, 0xAD88, 0x74D1, 0xAD89, 0x74D2, 0xE8B6,
+	0x74D3, 0xAD8A, 0x74D4, 0xAD8B, 0x74D5, 0xAD8C, 0x74D6, 0xAD8D,
+	0x74D7, 0xAD8E, 0x74D8, 0xAD8F, 0x74D9, 0xAD90, 0x74DA, 0xAD91,
+	0x74DB, 0xAD92, 0x74DC, 0xB9CF, 0x74DD, 0xAD93, 0x74DE, 0xF0AC,
+	0x74DF, 0xAD94, 0x74E0, 0xF0AD, 0x74E1, 0xAD95, 0x74E2, 0xC6B0,
+	0x74E3, 0xB0EA, 0x74E4, 0xC8BF, 0x74E5, 0xAD96, 0x74E6, 0xCDDF,
+	0x74E7, 0xAD97, 0x74E8, 0xAD98, 0x74E9, 0xAD99, 0x74EA, 0xAD9A,
+	0x74EB, 0xAD9B, 0x74EC, 0xAD9C, 0x74ED, 0xAD9D, 0x74EE, 0xCECD,
+	0x74EF, 0xEAB1, 0x74F0, 0xAD9E, 0x74F1, 0xAD9F, 0x74F2, 0xADA0,
+	0x74F3, 0xAE40, 0x74F4, 0xEAB2, 0x74F5, 0xAE41, 0x74F6, 0xC6BF,
+	0x74F7, 0xB4C9, 0x74F8, 0xAE42, 0x74F9, 0xAE43, 0x74FA, 0xAE44,
+	0x74FB, 0xAE45, 0x74FC, 0xAE46, 0x74FD, 0xAE47, 0x74FE, 0xAE48,
+	0x74FF, 0xEAB3, 0x7500, 0xAE49, 0x7501, 0xAE4A, 0x7502, 0xAE4B,
+	0x7503, 0xAE4C, 0x7504, 0xD5E7, 0x7505, 0xAE4D, 0x7506, 0xAE4E,
+	0x7507, 0xAE4F, 0x7508, 0xAE50, 0x7509, 0xAE51, 0x750A, 0xAE52,
+	0x750B, 0xAE53, 0x750C, 0xAE54, 0x750D, 0xDDF9, 0x750E, 0xAE55,
+	0x750F, 0xEAB4, 0x7510, 0xAE56, 0x7511, 0xEAB5, 0x7512, 0xAE57,
+	0x7513, 0xEAB6, 0x7514, 0xAE58, 0x7515, 0xAE59, 0x7516, 0xAE5A,
+	0x7517, 0xAE5B, 0x7518, 0xB8CA, 0x7519, 0xDFB0, 0x751A, 0xC9F5,
+	0x751B, 0xAE5C, 0x751C, 0xCCF0, 0x751D, 0xAE5D, 0x751E, 0xAE5E,
+	0x751F, 0xC9FA, 0x7520, 0xAE5F, 0x7521, 0xAE60, 0x7522, 0xAE61,
+	0x7523, 0xAE62, 0x7524, 0xAE63, 0x7525, 0xC9FB, 0x7526, 0xAE64,
+	0x7527, 0xAE65, 0x7528, 0xD3C3, 0x7529, 0xCBA6, 0x752A, 0xAE66,
+	0x752B, 0xB8A6, 0x752C, 0xF0AE, 0x752D, 0xB1C2, 0x752E, 0xAE67,
+	0x752F, 0xE5B8, 0x7530, 0xCCEF, 0x7531, 0xD3C9, 0x7532, 0xBCD7,
+	0x7533, 0xC9EA, 0x7534, 0xAE68, 0x7535, 0xB5E7, 0x7536, 0xAE69,
+	0x7537, 0xC4D0, 0x7538, 0xB5E9, 0x7539, 0xAE6A, 0x753A, 0xEEAE,
+	0x753B, 0xBBAD, 0x753C, 0xAE6B, 0x753D, 0xAE6C, 0x753E, 0xE7DE,
+	0x753F, 0xAE6D, 0x7540, 0xEEAF, 0x7541, 0xAE6E, 0x7542, 0xAE6F,
+	0x7543, 0xAE70, 0x7544, 0xAE71, 0x7545, 0xB3A9, 0x7546, 0xAE72,
+	0x7547, 0xAE73, 0x7548, 0xEEB2, 0x7549, 0xAE74, 0x754A, 0xAE75,
+	0x754B, 0xEEB1, 0x754C, 0xBDE7, 0x754D, 0xAE76, 0x754E, 0xEEB0,
+	0x754F, 0xCEB7, 0x7550, 0xAE77, 0x7551, 0xAE78, 0x7552, 0xAE79,
+	0x7553, 0xAE7A, 0x7554, 0xC5CF, 0x7555, 0xAE7B, 0x7556, 0xAE7C,
+	0x7557, 0xAE7D, 0x7558, 0xAE7E, 0x7559, 0xC1F4, 0x755A, 0xDBCE,
+	0x755B, 0xEEB3, 0x755C, 0xD0F3, 0x755D, 0xAE80, 0x755E, 0xAE81,
+	0x755F, 0xAE82, 0x7560, 0xAE83, 0x7561, 0xAE84, 0x7562, 0xAE85,
+	0x7563, 0xAE86, 0x7564, 0xAE87, 0x7565, 0xC2D4, 0x7566, 0xC6E8,
+	0x7567, 0xAE88, 0x7568, 0xAE89, 0x7569, 0xAE8A, 0x756A, 0xB7AC,
+	0x756B, 0xAE8B, 0x756C, 0xAE8C, 0x756D, 0xAE8D, 0x756E, 0xAE8E,
+	0x756F, 0xAE8F, 0x7570, 0xAE90, 0x7571, 0xAE91, 0x7572, 0xEEB4,
+	0x7573, 0xAE92, 0x7574, 0xB3EB, 0x7575, 0xAE93, 0x7576, 0xAE94,
+	0x7577, 0xAE95, 0x7578, 0xBBFB, 0x7579, 0xEEB5, 0x757A, 0xAE96,
+	0x757B, 0xAE97, 0x757C, 0xAE98, 0x757D, 0xAE99, 0x757E, 0xAE9A,
+	0x757F, 0xE7DC, 0x7580, 0xAE9B, 0x7581, 0xAE9C, 0x7582, 0xAE9D,
+	0x7583, 0xEEB6, 0x7584, 0xAE9E, 0x7585, 0xAE9F, 0x7586, 0xBDAE,
+	0x7587, 0xAEA0, 0x7588, 0xAF40, 0x7589, 0xAF41, 0x758A, 0xAF42,
+	0x758B, 0xF1E2, 0x758C, 0xAF43, 0x758D, 0xAF44, 0x758E, 0xAF45,
+	0x758F, 0xCAE8, 0x7590, 0xAF46, 0x7591, 0xD2C9, 0x7592, 0xF0DA,
+	0x7593, 0xAF47, 0x7594, 0xF0DB, 0x7595, 0xAF48, 0x7596, 0xF0DC,
+	0x7597, 0xC1C6, 0x7598, 0xAF49, 0x7599, 0xB8ED, 0x759A, 0xBECE,
+	0x759B, 0xAF4A, 0x759C, 0xAF4B, 0x759D, 0xF0DE, 0x759E, 0xAF4C,
+	0x759F, 0xC5B1, 0x75A0, 0xF0DD, 0x75A1, 0xD1F1, 0x75A2, 0xAF4D,
+	0x75A3, 0xF0E0, 0x75A4, 0xB0CC, 0x75A5, 0xBDEA, 0x75A6, 0xAF4E,
+	0x75A7, 0xAF4F, 0x75A8, 0xAF50, 0x75A9, 0xAF51, 0x75AA, 0xAF52,
+	0x75AB, 0xD2DF, 0x75AC, 0xF0DF, 0x75AD, 0xAF53, 0x75AE, 0xB4AF,
+	0x75AF, 0xB7E8, 0x75B0, 0xF0E6, 0x75B1, 0xF0E5, 0x75B2, 0xC6A3,
+	0x75B3, 0xF0E1, 0x75B4, 0xF0E2, 0x75B5, 0xB4C3, 0x75B6, 0xAF54,
+	0x75B7, 0xAF55, 0x75B8, 0xF0E3, 0x75B9, 0xD5EE, 0x75BA, 0xAF56,
+	0x75BB, 0xAF57, 0x75BC, 0xCCDB, 0x75BD, 0xBED2, 0x75BE, 0xBCB2,
+	0x75BF, 0xAF58, 0x75C0, 0xAF59, 0x75C1, 0xAF5A, 0x75C2, 0xF0E8,
+	0x75C3, 0xF0E7, 0x75C4, 0xF0E4, 0x75C5, 0xB2A1, 0x75C6, 0xAF5B,
+	0x75C7, 0xD6A2, 0x75C8, 0xD3B8, 0x75C9, 0xBEB7, 0x75CA, 0xC8AC,
+	0x75CB, 0xAF5C, 0x75CC, 0xAF5D, 0x75CD, 0xF0EA, 0x75CE, 0xAF5E,
+	0x75CF, 0xAF5F, 0x75D0, 0xAF60, 0x75D1, 0xAF61, 0x75D2, 0xD1F7,
+	0x75D3, 0xAF62, 0x75D4, 0xD6CC, 0x75D5, 0xBADB, 0x75D6, 0xF0E9,
+	0x75D7, 0xAF63, 0x75D8, 0xB6BB, 0x75D9, 0xAF64, 0x75DA, 0xAF65,
+	0x75DB, 0xCDB4, 0x75DC, 0xAF66, 0x75DD, 0xAF67, 0x75DE, 0xC6A6,
+	0x75DF, 0xAF68, 0x75E0, 0xAF69, 0x75E1, 0xAF6A, 0x75E2, 0xC1A1,
+	0x75E3, 0xF0EB, 0x75E4, 0xF0EE, 0x75E5, 0xAF6B, 0x75E6, 0xF0ED,
+	0x75E7, 0xF0F0, 0x75E8, 0xF0EC, 0x75E9, 0xAF6C, 0x75EA, 0xBBBE,
+	0x75EB, 0xF0EF, 0x75EC, 0xAF6D, 0x75ED, 0xAF6E, 0x75EE, 0xAF6F,
+	0x75EF, 0xAF70, 0x75F0, 0xCCB5, 0x75F1, 0xF0F2, 0x75F2, 0xAF71,
+	0x75F3, 0xAF72, 0x75F4, 0xB3D5, 0x75F5, 0xAF73, 0x75F6, 0xAF74,
+	0x75F7, 0xAF75, 0x75F8, 0xAF76, 0x75F9, 0xB1D4, 0x75FA, 0xAF77,
+	0x75FB, 0xAF78, 0x75FC, 0xF0F3, 0x75FD, 0xAF79, 0x75FE, 0xAF7A,
+	0x75FF, 0xF0F4, 0x7600, 0xF0F6, 0x7601, 0xB4E1, 0x7602, 0xAF7B,
+	0x7603, 0xF0F1, 0x7604, 0xAF7C, 0x7605, 0xF0F7, 0x7606, 0xAF7D,
+	0x7607, 0xAF7E, 0x7608, 0xAF80, 0x7609, 0xAF81, 0x760A, 0xF0FA,
+	0x760B, 0xAF82, 0x760C, 0xF0F8, 0x760D, 0xAF83, 0x760E, 0xAF84,
+	0x760F, 0xAF85, 0x7610, 0xF0F5, 0x7611, 0xAF86, 0x7612, 0xAF87,
+	0x7613, 0xAF88, 0x7614, 0xAF89, 0x7615, 0xF0FD, 0x7616, 0xAF8A,
+	0x7617, 0xF0F9, 0x7618, 0xF0FC, 0x7619, 0xF0FE, 0x761A, 0xAF8B,
+	0x761B, 0xF1A1, 0x761C, 0xAF8C, 0x761D, 0xAF8D, 0x761E, 0xAF8E,
+	0x761F, 0xCEC1, 0x7620, 0xF1A4, 0x7621, 0xAF8F, 0x7622, 0xF1A3,
+	0x7623, 0xAF90, 0x7624, 0xC1F6, 0x7625, 0xF0FB, 0x7626, 0xCADD,
+	0x7627, 0xAF91, 0x7628, 0xAF92, 0x7629, 0xB4F1, 0x762A, 0xB1F1,
+	0x762B, 0xCCB1, 0x762C, 0xAF93, 0x762D, 0xF1A6, 0x762E, 0xAF94,
+	0x762F, 0xAF95, 0x7630, 0xF1A7, 0x7631, 0xAF96, 0x7632, 0xAF97,
+	0x7633, 0xF1AC, 0x7634, 0xD5CE, 0x7635, 0xF1A9, 0x7636, 0xAF98,
+	0x7637, 0xAF99, 0x7638, 0xC8B3, 0x7639, 0xAF9A, 0x763A, 0xAF9B,
+	0x763B, 0xAF9C, 0x763C, 0xF1A2, 0x763D, 0xAF9D, 0x763E, 0xF1AB,
+	0x763F, 0xF1A8, 0x7640, 0xF1A5, 0x7641, 0xAF9E, 0x7642, 0xAF9F,
+	0x7643, 0xF1AA, 0x7644, 0xAFA0, 0x7645, 0xB040, 0x7646, 0xB041,
+	0x7647, 0xB042, 0x7648, 0xB043, 0x7649, 0xB044, 0x764A, 0xB045,
+	0x764B, 0xB046, 0x764C, 0xB0A9, 0x764D, 0xF1AD, 0x764E, 0xB047,
+	0x764F, 0xB048, 0x7650, 0xB049, 0x7651, 0xB04A, 0x7652, 0xB04B,
+	0x7653, 0xB04C, 0x7654, 0xF1AF, 0x7655, 0xB04D, 0x7656, 0xF1B1,
+	0x7657, 0xB04E, 0x7658, 0xB04F, 0x7659, 0xB050, 0x765A, 0xB051,
+	0x765B, 0xB052, 0x765C, 0xF1B0, 0x765D, 0xB053, 0x765E, 0xF1AE,
+	0x765F, 0xB054, 0x7660, 0xB055, 0x7661, 0xB056, 0x7662, 0xB057,
+	0x7663, 0xD1A2, 0x7664, 0xB058, 0x7665, 0xB059, 0x7666, 0xB05A,
+	0x7667, 0xB05B, 0x7668, 0xB05C, 0x7669, 0xB05D, 0x766A, 0xB05E,
+	0x766B, 0xF1B2, 0x766C, 0xB05F, 0x766D, 0xB060, 0x766E, 0xB061,
+	0x766F, 0xF1B3, 0x7670, 0xB062, 0x7671, 0xB063, 0x7672, 0xB064,
+	0x7673, 0xB065, 0x7674, 0xB066, 0x7675, 0xB067, 0x7676, 0xB068,
+	0x7677, 0xB069, 0x7678, 0xB9EF, 0x7679, 0xB06A, 0x767A, 0xB06B,
+	0x767B, 0xB5C7, 0x767C, 0xB06C, 0x767D, 0xB0D7, 0x767E, 0xB0D9,
+	0x767F, 0xB06D, 0x7680, 0xB06E, 0x7681, 0xB06F, 0x7682, 0xD4ED,
+	0x7683, 0xB070, 0x7684, 0xB5C4, 0x7685, 0xB071, 0x7686, 0xBDD4,
+	0x7687, 0xBBCA, 0x7688, 0xF0A7, 0x7689, 0xB072, 0x768A, 0xB073,
+	0x768B, 0xB8DE, 0x768C, 0xB074, 0x768D, 0xB075, 0x768E, 0xF0A8,
+	0x768F, 0xB076, 0x7690, 0xB077, 0x7691, 0xB0A8, 0x7692, 0xB078,
+	0x7693, 0xF0A9, 0x7694, 0xB079, 0x7695, 0xB07A, 0x7696, 0xCDEE,
+	0x7697, 0xB07B, 0x7698, 0xB07C, 0x7699, 0xF0AA, 0x769A, 0xB07D,
+	0x769B, 0xB07E, 0x769C, 0xB080, 0x769D, 0xB081, 0x769E, 0xB082,
+	0x769F, 0xB083, 0x76A0, 0xB084, 0x76A1, 0xB085, 0x76A2, 0xB086,
+	0x76A3, 0xB087, 0x76A4, 0xF0AB, 0x76A5, 0xB088, 0x76A6, 0xB089,
+	0x76A7, 0xB08A, 0x76A8, 0xB08B, 0x76A9, 0xB08C, 0x76AA, 0xB08D,
+	0x76AB, 0xB08E, 0x76AC, 0xB08F, 0x76AD, 0xB090, 0x76AE, 0xC6A4,
+	0x76AF, 0xB091, 0x76B0, 0xB092, 0x76B1, 0xD6E5, 0x76B2, 0xF1E4,
+	0x76B3, 0xB093, 0x76B4, 0xF1E5, 0x76B5, 0xB094, 0x76B6, 0xB095,
+	0x76B7, 0xB096, 0x76B8, 0xB097, 0x76B9, 0xB098, 0x76BA, 0xB099,
+	0x76BB, 0xB09A, 0x76BC, 0xB09B, 0x76BD, 0xB09C, 0x76BE, 0xB09D,
+	0x76BF, 0xC3F3, 0x76C0, 0xB09E, 0x76C1, 0xB09F, 0x76C2, 0xD3DB,
+	0x76C3, 0xB0A0, 0x76C4, 0xB140, 0x76C5, 0xD6D1, 0x76C6, 0xC5E8,
+	0x76C7, 0xB141, 0x76C8, 0xD3AF, 0x76C9, 0xB142, 0x76CA, 0xD2E6,
+	0x76CB, 0xB143, 0x76CC, 0xB144, 0x76CD, 0xEEC1, 0x76CE, 0xB0BB,
+	0x76CF, 0xD5B5, 0x76D0, 0xD1CE, 0x76D1, 0xBCE0, 0x76D2, 0xBAD0,
+	0x76D3, 0xB145, 0x76D4, 0xBFF8, 0x76D5, 0xB146, 0x76D6, 0xB8C7,
+	0x76D7, 0xB5C1, 0x76D8, 0xC5CC, 0x76D9, 0xB147, 0x76DA, 0xB148,
+	0x76DB, 0xCAA2, 0x76DC, 0xB149, 0x76DD, 0xB14A, 0x76DE, 0xB14B,
+	0x76DF, 0xC3CB, 0x76E0, 0xB14C, 0x76E1, 0xB14D, 0x76E2, 0xB14E,
+	0x76E3, 0xB14F, 0x76E4, 0xB150, 0x76E5, 0xEEC2, 0x76E6, 0xB151,
+	0x76E7, 0xB152, 0x76E8, 0xB153, 0x76E9, 0xB154, 0x76EA, 0xB155,
+	0x76EB, 0xB156, 0x76EC, 0xB157, 0x76ED, 0xB158, 0x76EE, 0xC4BF,
+	0x76EF, 0xB6A2, 0x76F0, 0xB159, 0x76F1, 0xEDEC, 0x76F2, 0xC3A4,
+	0x76F3, 0xB15A, 0x76F4, 0xD6B1, 0x76F5, 0xB15B, 0x76F6, 0xB15C,
+	0x76F7, 0xB15D, 0x76F8, 0xCFE0, 0x76F9, 0xEDEF, 0x76FA, 0xB15E,
+	0x76FB, 0xB15F, 0x76FC, 0xC5CE, 0x76FD, 0xB160, 0x76FE, 0xB6DC,
+	0x76FF, 0xB161, 0x7700, 0xB162, 0x7701, 0xCAA1, 0x7702, 0xB163,
+	0x7703, 0xB164, 0x7704, 0xEDED, 0x7705, 0xB165, 0x7706, 0xB166,
+	0x7707, 0xEDF0, 0x7708, 0xEDF1, 0x7709, 0xC3BC, 0x770A, 0xB167,
+	0x770B, 0xBFB4, 0x770C, 0xB168, 0x770D, 0xEDEE, 0x770E, 0xB169,
+	0x770F, 0xB16A, 0x7710, 0xB16B, 0x7711, 0xB16C, 0x7712, 0xB16D,
+	0x7713, 0xB16E, 0x7714, 0xB16F, 0x7715, 0xB170, 0x7716, 0xB171,
+	0x7717, 0xB172, 0x7718, 0xB173, 0x7719, 0xEDF4, 0x771A, 0xEDF2,
+	0x771B, 0xB174, 0x771C, 0xB175, 0x771D, 0xB176, 0x771E, 0xB177,
+	0x771F, 0xD5E6, 0x7720, 0xC3DF, 0x7721, 0xB178, 0x7722, 0xEDF3,
+	0x7723, 0xB179, 0x7724, 0xB17A, 0x7725, 0xB17B, 0x7726, 0xEDF6,
+	0x7727, 0xB17C, 0x7728, 0xD5A3, 0x7729, 0xD1A3, 0x772A, 0xB17D,
+	0x772B, 0xB17E, 0x772C, 0xB180, 0x772D, 0xEDF5, 0x772E, 0xB181,
+	0x772F, 0xC3D0, 0x7730, 0xB182, 0x7731, 0xB183, 0x7732, 0xB184,
+	0x7733, 0xB185, 0x7734, 0xB186, 0x7735, 0xEDF7, 0x7736, 0xBFF4,
+	0x7737, 0xBEEC, 0x7738, 0xEDF8, 0x7739, 0xB187, 0x773A, 0xCCF7,
+	0x773B, 0xB188, 0x773C, 0xD1DB, 0x773D, 0xB189, 0x773E, 0xB18A,
+	0x773F, 0xB18B, 0x7740, 0xD7C5, 0x7741, 0xD5F6, 0x7742, 0xB18C,
+	0x7743, 0xEDFC, 0x7744, 0xB18D, 0x7745, 0xB18E, 0x7746, 0xB18F,
+	0x7747, 0xEDFB, 0x7748, 0xB190, 0x7749, 0xB191, 0x774A, 0xB192,
+	0x774B, 0xB193, 0x774C, 0xB194, 0x774D, 0xB195, 0x774E, 0xB196,
+	0x774F, 0xB197, 0x7750, 0xEDF9, 0x7751, 0xEDFA, 0x7752, 0xB198,
+	0x7753, 0xB199, 0x7754, 0xB19A, 0x7755, 0xB19B, 0x7756, 0xB19C,
+	0x7757, 0xB19D, 0x7758, 0xB19E, 0x7759, 0xB19F, 0x775A, 0xEDFD,
+	0x775B, 0xBEA6, 0x775C, 0xB1A0, 0x775D, 0xB240, 0x775E, 0xB241,
+	0x775F, 0xB242, 0x7760, 0xB243, 0x7761, 0xCBAF, 0x7762, 0xEEA1,
+	0x7763, 0xB6BD, 0x7764, 0xB244, 0x7765, 0xEEA2, 0x7766, 0xC4C0,
+	0x7767, 0xB245, 0x7768, 0xEDFE, 0x7769, 0xB246, 0x776A, 0xB247,
+	0x776B, 0xBDDE, 0x776C, 0xB2C7, 0x776D, 0xB248, 0x776E, 0xB249,
+	0x776F, 0xB24A, 0x7770, 0xB24B, 0x7771, 0xB24C, 0x7772, 0xB24D,
+	0x7773, 0xB24E, 0x7774, 0xB24F, 0x7775, 0xB250, 0x7776, 0xB251,
+	0x7777, 0xB252, 0x7778, 0xB253, 0x7779, 0xB6C3, 0x777A, 0xB254,
+	0x777B, 0xB255, 0x777C, 0xB256, 0x777D, 0xEEA5, 0x777E, 0xD8BA,
+	0x777F, 0xEEA3, 0x7780, 0xEEA6, 0x7781, 0xB257, 0x7782, 0xB258,
+	0x7783, 0xB259, 0x7784, 0xC3E9, 0x7785, 0xB3F2, 0x7786, 0xB25A,
+	0x7787, 0xB25B, 0x7788, 0xB25C, 0x7789, 0xB25D, 0x778A, 0xB25E,
+	0x778B, 0xB25F, 0x778C, 0xEEA7, 0x778D, 0xEEA4, 0x778E, 0xCFB9,
+	0x778F, 0xB260, 0x7790, 0xB261, 0x7791, 0xEEA8, 0x7792, 0xC2F7,
+	0x7793, 0xB262, 0x7794, 0xB263, 0x7795, 0xB264, 0x7796, 0xB265,
+	0x7797, 0xB266, 0x7798, 0xB267, 0x7799, 0xB268, 0x779A, 0xB269,
+	0x779B, 0xB26A, 0x779C, 0xB26B, 0x779D, 0xB26C, 0x779E, 0xB26D,
+	0x779F, 0xEEA9, 0x77A0, 0xEEAA, 0x77A1, 0xB26E, 0x77A2, 0xDEAB,
+	0x77A3, 0xB26F, 0x77A4, 0xB270, 0x77A5, 0xC6B3, 0x77A6, 0xB271,
+	0x77A7, 0xC7C6, 0x77A8, 0xB272, 0x77A9, 0xD6F5, 0x77AA, 0xB5C9,
+	0x77AB, 0xB273, 0x77AC, 0xCBB2, 0x77AD, 0xB274, 0x77AE, 0xB275,
+	0x77AF, 0xB276, 0x77B0, 0xEEAB, 0x77B1, 0xB277, 0x77B2, 0xB278,
+	0x77B3, 0xCDAB, 0x77B4, 0xB279, 0x77B5, 0xEEAC, 0x77B6, 0xB27A,
+	0x77B7, 0xB27B, 0x77B8, 0xB27C, 0x77B9, 0xB27D, 0x77BA, 0xB27E,
+	0x77BB, 0xD5B0, 0x77BC, 0xB280, 0x77BD, 0xEEAD, 0x77BE, 0xB281,
+	0x77BF, 0xF6C4, 0x77C0, 0xB282, 0x77C1, 0xB283, 0x77C2, 0xB284,
+	0x77C3, 0xB285, 0x77C4, 0xB286, 0x77C5, 0xB287, 0x77C6, 0xB288,
+	0x77C7, 0xB289, 0x77C8, 0xB28A, 0x77C9, 0xB28B, 0x77CA, 0xB28C,
+	0x77CB, 0xB28D, 0x77CC, 0xB28E, 0x77CD, 0xDBC7, 0x77CE, 0xB28F,
+	0x77CF, 0xB290, 0x77D0, 0xB291, 0x77D1, 0xB292, 0x77D2, 0xB293,
+	0x77D3, 0xB294, 0x77D4, 0xB295, 0x77D5, 0xB296, 0x77D6, 0xB297,
+	0x77D7, 0xB4A3, 0x77D8, 0xB298, 0x77D9, 0xB299, 0x77DA, 0xB29A,
+	0x77DB, 0xC3AC, 0x77DC, 0xF1E6, 0x77DD, 0xB29B, 0x77DE, 0xB29C,
+	0x77DF, 0xB29D, 0x77E0, 0xB29E, 0x77E1, 0xB29F, 0x77E2, 0xCAB8,
+	0x77E3, 0xD2D3, 0x77E4, 0xB2A0, 0x77E5, 0xD6AA, 0x77E6, 0xB340,
+	0x77E7, 0xEFF2, 0x77E8, 0xB341, 0x77E9, 0xBED8, 0x77EA, 0xB342,
+	0x77EB, 0xBDC3, 0x77EC, 0xEFF3, 0x77ED, 0xB6CC, 0x77EE, 0xB0AB,
+	0x77EF, 0xB343, 0x77F0, 0xB344, 0x77F1, 0xB345, 0x77F2, 0xB346,
+	0x77F3, 0xCAAF, 0x77F4, 0xB347, 0x77F5, 0xB348, 0x77F6, 0xEDB6,
+	0x77F7, 0xB349, 0x77F8, 0xEDB7, 0x77F9, 0xB34A, 0x77FA, 0xB34B,
+	0x77FB, 0xB34C, 0x77FC, 0xB34D, 0x77FD, 0xCEF9, 0x77FE, 0xB7AF,
+	0x77FF, 0xBFF3, 0x7800, 0xEDB8, 0x7801, 0xC2EB, 0x7802, 0xC9B0,
+	0x7803, 0xB34E, 0x7804, 0xB34F, 0x7805, 0xB350, 0x7806, 0xB351,
+	0x7807, 0xB352, 0x7808, 0xB353, 0x7809, 0xEDB9, 0x780A, 0xB354,
+	0x780B, 0xB355, 0x780C, 0xC6F6, 0x780D, 0xBFB3, 0x780E, 0xB356,
+	0x780F, 0xB357, 0x7810, 0xB358, 0x7811, 0xEDBC, 0x7812, 0xC5F8,
+	0x7813, 0xB359, 0x7814, 0xD1D0, 0x7815, 0xB35A, 0x7816, 0xD7A9,
+	0x7817, 0xEDBA, 0x7818, 0xEDBB, 0x7819, 0xB35B, 0x781A, 0xD1E2,
+	0x781B, 0xB35C, 0x781C, 0xEDBF, 0x781D, 0xEDC0, 0x781E, 0xB35D,
+	0x781F, 0xEDC4, 0x7820, 0xB35E, 0x7821, 0xB35F, 0x7822, 0xB360,
+	0x7823, 0xEDC8, 0x7824, 0xB361, 0x7825, 0xEDC6, 0x7826, 0xEDCE,
+	0x7827, 0xD5E8, 0x7828, 0xB362, 0x7829, 0xEDC9, 0x782A, 0xB363,
+	0x782B, 0xB364, 0x782C, 0xEDC7, 0x782D, 0xEDBE, 0x782E, 0xB365,
+	0x782F, 0xB366, 0x7830, 0xC5E9, 0x7831, 0xB367, 0x7832, 0xB368,
+	0x7833, 0xB369, 0x7834, 0xC6C6, 0x7835, 0xB36A, 0x7836, 0xB36B,
+	0x7837, 0xC9E9, 0x7838, 0xD4D2, 0x7839, 0xEDC1, 0x783A, 0xEDC2,
+	0x783B, 0xEDC3, 0x783C, 0xEDC5, 0x783D, 0xB36C, 0x783E, 0xC0F9,
+	0x783F, 0xB36D, 0x7840, 0xB4A1, 0x7841, 0xB36E, 0x7842, 0xB36F,
+	0x7843, 0xB370, 0x7844, 0xB371, 0x7845, 0xB9E8, 0x7846, 0xB372,
+	0x7847, 0xEDD0, 0x7848, 0xB373, 0x7849, 0xB374, 0x784A, 0xB375,
+	0x784B, 0xB376, 0x784C, 0xEDD1, 0x784D, 0xB377, 0x784E, 0xEDCA,
+	0x784F, 0xB378, 0x7850, 0xEDCF, 0x7851, 0xB379, 0x7852, 0xCEF8,
+	0x7853, 0xB37A, 0x7854, 0xB37B, 0x7855, 0xCBB6, 0x7856, 0xEDCC,
+	0x7857, 0xEDCD, 0x7858, 0xB37C, 0x7859, 0xB37D, 0x785A, 0xB37E,
+	0x785B, 0xB380, 0x785C, 0xB381, 0x785D, 0xCFF5, 0x785E, 0xB382,
+	0x785F, 0xB383, 0x7860, 0xB384, 0x7861, 0xB385, 0x7862, 0xB386,
+	0x7863, 0xB387, 0x7864, 0xB388, 0x7865, 0xB389, 0x7866, 0xB38A,
+	0x7867, 0xB38B, 0x7868, 0xB38C, 0x7869, 0xB38D, 0x786A, 0xEDD2,
+	0x786B, 0xC1F2, 0x786C, 0xD3B2, 0x786D, 0xEDCB, 0x786E, 0xC8B7,
+	0x786F, 0xB38E, 0x7870, 0xB38F, 0x7871, 0xB390, 0x7872, 0xB391,
+	0x7873, 0xB392, 0x7874, 0xB393, 0x7875, 0xB394, 0x7876, 0xB395,
+	0x7877, 0xBCEF, 0x7878, 0xB396, 0x7879, 0xB397, 0x787A, 0xB398,
+	0x787B, 0xB399, 0x787C, 0xC5F0, 0x787D, 0xB39A, 0x787E, 0xB39B,
+	0x787F, 0xB39C, 0x7880, 0xB39D, 0x7881, 0xB39E, 0x7882, 0xB39F,
+	0x7883, 0xB3A0, 0x7884, 0xB440, 0x7885, 0xB441, 0x7886, 0xB442,
+	0x7887, 0xEDD6, 0x7888, 0xB443, 0x7889, 0xB5EF, 0x788A, 0xB444,
+	0x788B, 0xB445, 0x788C, 0xC2B5, 0x788D, 0xB0AD, 0x788E, 0xCBE9,
+	0x788F, 0xB446, 0x7890, 0xB447, 0x7891, 0xB1AE, 0x7892, 0xB448,
+	0x7893, 0xEDD4, 0x7894, 0xB449, 0x7895, 0xB44A, 0x7896, 0xB44B,
+	0x7897, 0xCDEB, 0x7898, 0xB5E2, 0x7899, 0xB44C, 0x789A, 0xEDD5,
+	0x789B, 0xEDD3, 0x789C, 0xEDD7, 0x789D, 0xB44D, 0x789E, 0xB44E,
+	0x789F, 0xB5FA, 0x78A0, 0xB44F, 0x78A1, 0xEDD8, 0x78A2, 0xB450,
+	0x78A3, 0xEDD9, 0x78A4, 0xB451, 0x78A5, 0xEDDC, 0x78A6, 0xB452,
+	0x78A7, 0xB1CC, 0x78A8, 0xB453, 0x78A9, 0xB454, 0x78AA, 0xB455,
+	0x78AB, 0xB456, 0x78AC, 0xB457, 0x78AD, 0xB458, 0x78AE, 0xB459,
+	0x78AF, 0xB45A, 0x78B0, 0xC5F6, 0x78B1, 0xBCEE, 0x78B2, 0xEDDA,
+	0x78B3, 0xCCBC, 0x78B4, 0xB2EA, 0x78B5, 0xB45B, 0x78B6, 0xB45C,
+	0x78B7, 0xB45D, 0x78B8, 0xB45E, 0x78B9, 0xEDDB, 0x78BA, 0xB45F,
+	0x78BB, 0xB460, 0x78BC, 0xB461, 0x78BD, 0xB462, 0x78BE, 0xC4EB,
+	0x78BF, 0xB463, 0x78C0, 0xB464, 0x78C1, 0xB4C5, 0x78C2, 0xB465,
+	0x78C3, 0xB466, 0x78C4, 0xB467, 0x78C5, 0xB0F5, 0x78C6, 0xB468,
+	0x78C7, 0xB469, 0x78C8, 0xB46A, 0x78C9, 0xEDDF, 0x78CA, 0xC0DA,
+	0x78CB, 0xB4E8, 0x78CC, 0xB46B, 0x78CD, 0xB46C, 0x78CE, 0xB46D,
+	0x78CF, 0xB46E, 0x78D0, 0xC5CD, 0x78D1, 0xB46F, 0x78D2, 0xB470,
+	0x78D3, 0xB471, 0x78D4, 0xEDDD, 0x78D5, 0xBFC4, 0x78D6, 0xB472,
+	0x78D7, 0xB473, 0x78D8, 0xB474, 0x78D9, 0xEDDE, 0x78DA, 0xB475,
+	0x78DB, 0xB476, 0x78DC, 0xB477, 0x78DD, 0xB478, 0x78DE, 0xB479,
+	0x78DF, 0xB47A, 0x78E0, 0xB47B, 0x78E1, 0xB47C, 0x78E2, 0xB47D,
+	0x78E3, 0xB47E, 0x78E4, 0xB480, 0x78E5, 0xB481, 0x78E6, 0xB482,
+	0x78E7, 0xB483, 0x78E8, 0xC4A5, 0x78E9, 0xB484, 0x78EA, 0xB485,
+	0x78EB, 0xB486, 0x78EC, 0xEDE0, 0x78ED, 0xB487, 0x78EE, 0xB488,
+	0x78EF, 0xB489, 0x78F0, 0xB48A, 0x78F1, 0xB48B, 0x78F2, 0xEDE1,
+	0x78F3, 0xB48C, 0x78F4, 0xEDE3, 0x78F5, 0xB48D, 0x78F6, 0xB48E,
+	0x78F7, 0xC1D7, 0x78F8, 0xB48F, 0x78F9, 0xB490, 0x78FA, 0xBBC7,
+	0x78FB, 0xB491, 0x78FC, 0xB492, 0x78FD, 0xB493, 0x78FE, 0xB494,
+	0x78FF, 0xB495, 0x7900, 0xB496, 0x7901, 0xBDB8, 0x7902, 0xB497,
+	0x7903, 0xB498, 0x7904, 0xB499, 0x7905, 0xEDE2, 0x7906, 0xB49A,
+	0x7907, 0xB49B, 0x7908, 0xB49C, 0x7909, 0xB49D, 0x790A, 0xB49E,
+	0x790B, 0xB49F, 0x790C, 0xB4A0, 0x790D, 0xB540, 0x790E, 0xB541,
+	0x790F, 0xB542, 0x7910, 0xB543, 0x7911, 0xB544, 0x7912, 0xB545,
+	0x7913, 0xEDE4, 0x7914, 0xB546, 0x7915, 0xB547, 0x7916, 0xB548,
+	0x7917, 0xB549, 0x7918, 0xB54A, 0x7919, 0xB54B, 0x791A, 0xB54C,
+	0x791B, 0xB54D, 0x791C, 0xB54E, 0x791D, 0xB54F, 0x791E, 0xEDE6,
+	0x791F, 0xB550, 0x7920, 0xB551, 0x7921, 0xB552, 0x7922, 0xB553,
+	0x7923, 0xB554, 0x7924, 0xEDE5, 0x7925, 0xB555, 0x7926, 0xB556,
+	0x7927, 0xB557, 0x7928, 0xB558, 0x7929, 0xB559, 0x792A, 0xB55A,
+	0x792B, 0xB55B, 0x792C, 0xB55C, 0x792D, 0xB55D, 0x792E, 0xB55E,
+	0x792F, 0xB55F, 0x7930, 0xB560, 0x7931, 0xB561, 0x7932, 0xB562,
+	0x7933, 0xB563, 0x7934, 0xEDE7, 0x7935, 0xB564, 0x7936, 0xB565,
+	0x7937, 0xB566, 0x7938, 0xB567, 0x7939, 0xB568, 0x793A, 0xCABE,
+	0x793B, 0xECEA, 0x793C, 0xC0F1, 0x793D, 0xB569, 0x793E, 0xC9E7,
+	0x793F, 0xB56A, 0x7940, 0xECEB, 0x7941, 0xC6EE, 0x7942, 0xB56B,
+	0x7943, 0xB56C, 0x7944, 0xB56D, 0x7945, 0xB56E, 0x7946, 0xECEC,
+	0x7947, 0xB56F, 0x7948, 0xC6ED, 0x7949, 0xECED, 0x794A, 0xB570,
+	0x794B, 0xB571, 0x794C, 0xB572, 0x794D, 0xB573, 0x794E, 0xB574,
+	0x794F, 0xB575, 0x7950, 0xB576, 0x7951, 0xB577, 0x7952, 0xB578,
+	0x7953, 0xECF0, 0x7954, 0xB579, 0x7955, 0xB57A, 0x7956, 0xD7E6,
+	0x7957, 0xECF3, 0x7958, 0xB57B, 0x7959, 0xB57C, 0x795A, 0xECF1,
+	0x795B, 0xECEE, 0x795C, 0xECEF, 0x795D, 0xD7A3, 0x795E, 0xC9F1,
+	0x795F, 0xCBEE, 0x7960, 0xECF4, 0x7961, 0xB57D, 0x7962, 0xECF2,
+	0x7963, 0xB57E, 0x7964, 0xB580, 0x7965, 0xCFE9, 0x7966, 0xB581,
+	0x7967, 0xECF6, 0x7968, 0xC6B1, 0x7969, 0xB582, 0x796A, 0xB583,
+	0x796B, 0xB584, 0x796C, 0xB585, 0x796D, 0xBCC0, 0x796E, 0xB586,
+	0x796F, 0xECF5, 0x7970, 0xB587, 0x7971, 0xB588, 0x7972, 0xB589,
+	0x7973, 0xB58A, 0x7974, 0xB58B, 0x7975, 0xB58C, 0x7976, 0xB58D,
+	0x7977, 0xB5BB, 0x7978, 0xBBF6, 0x7979, 0xB58E, 0x797A, 0xECF7,
+	0x797B, 0xB58F, 0x797C, 0xB590, 0x797D, 0xB591, 0x797E, 0xB592,
+	0x797F, 0xB593, 0x7980, 0xD9F7, 0x7981, 0xBDFB, 0x7982, 0xB594,
+	0x7983, 0xB595, 0x7984, 0xC2BB, 0x7985, 0xECF8, 0x7986, 0xB596,
+	0x7987, 0xB597, 0x7988, 0xB598, 0x7989, 0xB599, 0x798A, 0xECF9,
+	0x798B, 0xB59A, 0x798C, 0xB59B, 0x798D, 0xB59C, 0x798E, 0xB59D,
+	0x798F, 0xB8A3, 0x7990, 0xB59E, 0x7991, 0xB59F, 0x7992, 0xB5A0,
+	0x7993, 0xB640, 0x7994, 0xB641, 0x7995, 0xB642, 0x7996, 0xB643,
+	0x7997, 0xB644, 0x7998, 0xB645, 0x7999, 0xB646, 0x799A, 0xECFA,
+	0x799B, 0xB647, 0x799C, 0xB648, 0x799D, 0xB649, 0x799E, 0xB64A,
+	0x799F, 0xB64B, 0x79A0, 0xB64C, 0x79A1, 0xB64D, 0x79A2, 0xB64E,
+	0x79A3, 0xB64F, 0x79A4, 0xB650, 0x79A5, 0xB651, 0x79A6, 0xB652,
+	0x79A7, 0xECFB, 0x79A8, 0xB653, 0x79A9, 0xB654, 0x79AA, 0xB655,
+	0x79AB, 0xB656, 0x79AC, 0xB657, 0x79AD, 0xB658, 0x79AE, 0xB659,
+	0x79AF, 0xB65A, 0x79B0, 0xB65B, 0x79B1, 0xB65C, 0x79B2, 0xB65D,
+	0x79B3, 0xECFC, 0x79B4, 0xB65E, 0x79B5, 0xB65F, 0x79B6, 0xB660,
+	0x79B7, 0xB661, 0x79B8, 0xB662, 0x79B9, 0xD3ED, 0x79BA, 0xD8AE,
+	0x79BB, 0xC0EB, 0x79BC, 0xB663, 0x79BD, 0xC7DD, 0x79BE, 0xBACC,
+	0x79BF, 0xB664, 0x79C0, 0xD0E3, 0x79C1, 0xCBBD, 0x79C2, 0xB665,
+	0x79C3, 0xCDBA, 0x79C4, 0xB666, 0x79C5, 0xB667, 0x79C6, 0xB8D1,
+	0x79C7, 0xB668, 0x79C8, 0xB669, 0x79C9, 0xB1FC, 0x79CA, 0xB66A,
+	0x79CB, 0xC7EF, 0x79CC, 0xB66B, 0x79CD, 0xD6D6, 0x79CE, 0xB66C,
+	0x79CF, 0xB66D, 0x79D0, 0xB66E, 0x79D1, 0xBFC6, 0x79D2, 0xC3EB,
+	0x79D3, 0xB66F, 0x79D4, 0xB670, 0x79D5, 0xEFF5, 0x79D6, 0xB671,
+	0x79D7, 0xB672, 0x79D8, 0xC3D8, 0x79D9, 0xB673, 0x79DA, 0xB674,
+	0x79DB, 0xB675, 0x79DC, 0xB676, 0x79DD, 0xB677, 0x79DE, 0xB678,
+	0x79DF, 0xD7E2, 0x79E0, 0xB679, 0x79E1, 0xB67A, 0x79E2, 0xB67B,
+	0x79E3, 0xEFF7, 0x79E4, 0xB3D3, 0x79E5, 0xB67C, 0x79E6, 0xC7D8,
+	0x79E7, 0xD1ED, 0x79E8, 0xB67D, 0x79E9, 0xD6C8, 0x79EA, 0xB67E,
+	0x79EB, 0xEFF8, 0x79EC, 0xB680, 0x79ED, 0xEFF6, 0x79EE, 0xB681,
+	0x79EF, 0xBBFD, 0x79F0, 0xB3C6, 0x79F1, 0xB682, 0x79F2, 0xB683,
+	0x79F3, 0xB684, 0x79F4, 0xB685, 0x79F5, 0xB686, 0x79F6, 0xB687,
+	0x79F7, 0xB688, 0x79F8, 0xBDD5, 0x79F9, 0xB689, 0x79FA, 0xB68A,
+	0x79FB, 0xD2C6, 0x79FC, 0xB68B, 0x79FD, 0xBBE0, 0x79FE, 0xB68C,
+	0x79FF, 0xB68D, 0x7A00, 0xCFA1, 0x7A01, 0xB68E, 0x7A02, 0xEFFC,
+	0x7A03, 0xEFFB, 0x7A04, 0xB68F, 0x7A05, 0xB690, 0x7A06, 0xEFF9,
+	0x7A07, 0xB691, 0x7A08, 0xB692, 0x7A09, 0xB693, 0x7A0A, 0xB694,
+	0x7A0B, 0xB3CC, 0x7A0C, 0xB695, 0x7A0D, 0xC9D4, 0x7A0E, 0xCBB0,
+	0x7A0F, 0xB696, 0x7A10, 0xB697, 0x7A11, 0xB698, 0x7A12, 0xB699,
+	0x7A13, 0xB69A, 0x7A14, 0xEFFE, 0x7A15, 0xB69B, 0x7A16, 0xB69C,
+	0x7A17, 0xB0DE, 0x7A18, 0xB69D, 0x7A19, 0xB69E, 0x7A1A, 0xD6C9,
+	0x7A1B, 0xB69F, 0x7A1C, 0xB6A0, 0x7A1D, 0xB740, 0x7A1E, 0xEFFD,
+	0x7A1F, 0xB741, 0x7A20, 0xB3ED, 0x7A21, 0xB742, 0x7A22, 0xB743,
+	0x7A23, 0xF6D5, 0x7A24, 0xB744, 0x7A25, 0xB745, 0x7A26, 0xB746,
+	0x7A27, 0xB747, 0x7A28, 0xB748, 0x7A29, 0xB749, 0x7A2A, 0xB74A,
+	0x7A2B, 0xB74B, 0x7A2C, 0xB74C, 0x7A2D, 0xB74D, 0x7A2E, 0xB74E,
+	0x7A2F, 0xB74F, 0x7A30, 0xB750, 0x7A31, 0xB751, 0x7A32, 0xB752,
+	0x7A33, 0xCEC8, 0x7A34, 0xB753, 0x7A35, 0xB754, 0x7A36, 0xB755,
+	0x7A37, 0xF0A2, 0x7A38, 0xB756, 0x7A39, 0xF0A1, 0x7A3A, 0xB757,
+	0x7A3B, 0xB5BE, 0x7A3C, 0xBCDA, 0x7A3D, 0xBBFC, 0x7A3E, 0xB758,
+	0x7A3F, 0xB8E5, 0x7A40, 0xB759, 0x7A41, 0xB75A, 0x7A42, 0xB75B,
+	0x7A43, 0xB75C, 0x7A44, 0xB75D, 0x7A45, 0xB75E, 0x7A46, 0xC4C2,
+	0x7A47, 0xB75F, 0x7A48, 0xB760, 0x7A49, 0xB761, 0x7A4A, 0xB762,
+	0x7A4B, 0xB763, 0x7A4C, 0xB764, 0x7A4D, 0xB765, 0x7A4E, 0xB766,
+	0x7A4F, 0xB767, 0x7A50, 0xB768, 0x7A51, 0xF0A3, 0x7A52, 0xB769,
+	0x7A53, 0xB76A, 0x7A54, 0xB76B, 0x7A55, 0xB76C, 0x7A56, 0xB76D,
+	0x7A57, 0xCBEB, 0x7A58, 0xB76E, 0x7A59, 0xB76F, 0x7A5A, 0xB770,
+	0x7A5B, 0xB771, 0x7A5C, 0xB772, 0x7A5D, 0xB773, 0x7A5E, 0xB774,
+	0x7A5F, 0xB775, 0x7A60, 0xB776, 0x7A61, 0xB777, 0x7A62, 0xB778,
+	0x7A63, 0xB779, 0x7A64, 0xB77A, 0x7A65, 0xB77B, 0x7A66, 0xB77C,
+	0x7A67, 0xB77D, 0x7A68, 0xB77E, 0x7A69, 0xB780, 0x7A6A, 0xB781,
+	0x7A6B, 0xB782, 0x7A6C, 0xB783, 0x7A6D, 0xB784, 0x7A6E, 0xB785,
+	0x7A6F, 0xB786, 0x7A70, 0xF0A6, 0x7A71, 0xB787, 0x7A72, 0xB788,
+	0x7A73, 0xB789, 0x7A74, 0xD1A8, 0x7A75, 0xB78A, 0x7A76, 0xBEBF,
+	0x7A77, 0xC7EE, 0x7A78, 0xF1B6, 0x7A79, 0xF1B7, 0x7A7A, 0xBFD5,
+	0x7A7B, 0xB78B, 0x7A7C, 0xB78C, 0x7A7D, 0xB78D, 0x7A7E, 0xB78E,
+	0x7A7F, 0xB4A9, 0x7A80, 0xF1B8, 0x7A81, 0xCDBB, 0x7A82, 0xB78F,
+	0x7A83, 0xC7D4, 0x7A84, 0xD5AD, 0x7A85, 0xB790, 0x7A86, 0xF1B9,
+	0x7A87, 0xB791, 0x7A88, 0xF1BA, 0x7A89, 0xB792, 0x7A8A, 0xB793,
+	0x7A8B, 0xB794, 0x7A8C, 0xB795, 0x7A8D, 0xC7CF, 0x7A8E, 0xB796,
+	0x7A8F, 0xB797, 0x7A90, 0xB798, 0x7A91, 0xD2A4, 0x7A92, 0xD6CF,
+	0x7A93, 0xB799, 0x7A94, 0xB79A, 0x7A95, 0xF1BB, 0x7A96, 0xBDD1,
+	0x7A97, 0xB4B0, 0x7A98, 0xBEBD, 0x7A99, 0xB79B, 0x7A9A, 0xB79C,
+	0x7A9B, 0xB79D, 0x7A9C, 0xB4DC, 0x7A9D, 0xCED1, 0x7A9E, 0xB79E,
+	0x7A9F, 0xBFDF, 0x7AA0, 0xF1BD, 0x7AA1, 0xB79F, 0x7AA2, 0xB7A0,
+	0x7AA3, 0xB840, 0x7AA4, 0xB841, 0x7AA5, 0xBFFA, 0x7AA6, 0xF1BC,
+	0x7AA7, 0xB842, 0x7AA8, 0xF1BF, 0x7AA9, 0xB843, 0x7AAA, 0xB844,
+	0x7AAB, 0xB845, 0x7AAC, 0xF1BE, 0x7AAD, 0xF1C0, 0x7AAE, 0xB846,
+	0x7AAF, 0xB847, 0x7AB0, 0xB848, 0x7AB1, 0xB849, 0x7AB2, 0xB84A,
+	0x7AB3, 0xF1C1, 0x7AB4, 0xB84B, 0x7AB5, 0xB84C, 0x7AB6, 0xB84D,
+	0x7AB7, 0xB84E, 0x7AB8, 0xB84F, 0x7AB9, 0xB850, 0x7ABA, 0xB851,
+	0x7ABB, 0xB852, 0x7ABC, 0xB853, 0x7ABD, 0xB854, 0x7ABE, 0xB855,
+	0x7ABF, 0xC1FE, 0x7AC0, 0xB856, 0x7AC1, 0xB857, 0x7AC2, 0xB858,
+	0x7AC3, 0xB859, 0x7AC4, 0xB85A, 0x7AC5, 0xB85B, 0x7AC6, 0xB85C,
+	0x7AC7, 0xB85D, 0x7AC8, 0xB85E, 0x7AC9, 0xB85F, 0x7ACA, 0xB860,
+	0x7ACB, 0xC1A2, 0x7ACC, 0xB861, 0x7ACD, 0xB862, 0x7ACE, 0xB863,
+	0x7ACF, 0xB864, 0x7AD0, 0xB865, 0x7AD1, 0xB866, 0x7AD2, 0xB867,
+	0x7AD3, 0xB868, 0x7AD4, 0xB869, 0x7AD5, 0xB86A, 0x7AD6, 0xCAFA,
+	0x7AD7, 0xB86B, 0x7AD8, 0xB86C, 0x7AD9, 0xD5BE, 0x7ADA, 0xB86D,
+	0x7ADB, 0xB86E, 0x7ADC, 0xB86F, 0x7ADD, 0xB870, 0x7ADE, 0xBEBA,
+	0x7ADF, 0xBEB9, 0x7AE0, 0xD5C2, 0x7AE1, 0xB871, 0x7AE2, 0xB872,
+	0x7AE3, 0xBFA2, 0x7AE4, 0xB873, 0x7AE5, 0xCDAF, 0x7AE6, 0xF1B5,
+	0x7AE7, 0xB874, 0x7AE8, 0xB875, 0x7AE9, 0xB876, 0x7AEA, 0xB877,
+	0x7AEB, 0xB878, 0x7AEC, 0xB879, 0x7AED, 0xBDDF, 0x7AEE, 0xB87A,
+	0x7AEF, 0xB6CB, 0x7AF0, 0xB87B, 0x7AF1, 0xB87C, 0x7AF2, 0xB87D,
+	0x7AF3, 0xB87E, 0x7AF4, 0xB880, 0x7AF5, 0xB881, 0x7AF6, 0xB882,
+	0x7AF7, 0xB883, 0x7AF8, 0xB884, 0x7AF9, 0xD6F1, 0x7AFA, 0xF3C3,
+	0x7AFB, 0xB885, 0x7AFC, 0xB886, 0x7AFD, 0xF3C4, 0x7AFE, 0xB887,
+	0x7AFF, 0xB8CD, 0x7B00, 0xB888, 0x7B01, 0xB889, 0x7B02, 0xB88A,
+	0x7B03, 0xF3C6, 0x7B04, 0xF3C7, 0x7B05, 0xB88B, 0x7B06, 0xB0CA,
+	0x7B07, 0xB88C, 0x7B08, 0xF3C5, 0x7B09, 0xB88D, 0x7B0A, 0xF3C9,
+	0x7B0B, 0xCBF1, 0x7B0C, 0xB88E, 0x7B0D, 0xB88F, 0x7B0E, 0xB890,
+	0x7B0F, 0xF3CB, 0x7B10, 0xB891, 0x7B11, 0xD0A6, 0x7B12, 0xB892,
+	0x7B13, 0xB893, 0x7B14, 0xB1CA, 0x7B15, 0xF3C8, 0x7B16, 0xB894,
+	0x7B17, 0xB895, 0x7B18, 0xB896, 0x7B19, 0xF3CF, 0x7B1A, 0xB897,
+	0x7B1B, 0xB5D1, 0x7B1C, 0xB898, 0x7B1D, 0xB899, 0x7B1E, 0xF3D7,
+	0x7B1F, 0xB89A, 0x7B20, 0xF3D2, 0x7B21, 0xB89B, 0x7B22, 0xB89C,
+	0x7B23, 0xB89D, 0x7B24, 0xF3D4, 0x7B25, 0xF3D3, 0x7B26, 0xB7FB,
+	0x7B27, 0xB89E, 0x7B28, 0xB1BF, 0x7B29, 0xB89F, 0x7B2A, 0xF3CE,
+	0x7B2B, 0xF3CA, 0x7B2C, 0xB5DA, 0x7B2D, 0xB8A0, 0x7B2E, 0xF3D0,
+	0x7B2F, 0xB940, 0x7B30, 0xB941, 0x7B31, 0xF3D1, 0x7B32, 0xB942,
+	0x7B33, 0xF3D5, 0x7B34, 0xB943, 0x7B35, 0xB944, 0x7B36, 0xB945,
+	0x7B37, 0xB946, 0x7B38, 0xF3CD, 0x7B39, 0xB947, 0x7B3A, 0xBCE3,
+	0x7B3B, 0xB948, 0x7B3C, 0xC1FD, 0x7B3D, 0xB949, 0x7B3E, 0xF3D6,
+	0x7B3F, 0xB94A, 0x7B40, 0xB94B, 0x7B41, 0xB94C, 0x7B42, 0xB94D,
+	0x7B43, 0xB94E, 0x7B44, 0xB94F, 0x7B45, 0xF3DA, 0x7B46, 0xB950,
+	0x7B47, 0xF3CC, 0x7B48, 0xB951, 0x7B49, 0xB5C8, 0x7B4A, 0xB952,
+	0x7B4B, 0xBDEE, 0x7B4C, 0xF3DC, 0x7B4D, 0xB953, 0x7B4E, 0xB954,
+	0x7B4F, 0xB7A4, 0x7B50, 0xBFF0, 0x7B51, 0xD6FE, 0x7B52, 0xCDB2,
+	0x7B53, 0xB955, 0x7B54, 0xB4F0, 0x7B55, 0xB956, 0x7B56, 0xB2DF,
+	0x7B57, 0xB957, 0x7B58, 0xF3D8, 0x7B59, 0xB958, 0x7B5A, 0xF3D9,
+	0x7B5B, 0xC9B8, 0x7B5C, 0xB959, 0x7B5D, 0xF3DD, 0x7B5E, 0xB95A,
+	0x7B5F, 0xB95B, 0x7B60, 0xF3DE, 0x7B61, 0xB95C, 0x7B62, 0xF3E1,
+	0x7B63, 0xB95D, 0x7B64, 0xB95E, 0x7B65, 0xB95F, 0x7B66, 0xB960,
+	0x7B67, 0xB961, 0x7B68, 0xB962, 0x7B69, 0xB963, 0x7B6A, 0xB964,
+	0x7B6B, 0xB965, 0x7B6C, 0xB966, 0x7B6D, 0xB967, 0x7B6E, 0xF3DF,
+	0x7B6F, 0xB968, 0x7B70, 0xB969, 0x7B71, 0xF3E3, 0x7B72, 0xF3E2,
+	0x7B73, 0xB96A, 0x7B74, 0xB96B, 0x7B75, 0xF3DB, 0x7B76, 0xB96C,
+	0x7B77, 0xBFEA, 0x7B78, 0xB96D, 0x7B79, 0xB3EF, 0x7B7A, 0xB96E,
+	0x7B7B, 0xF3E0, 0x7B7C, 0xB96F, 0x7B7D, 0xB970, 0x7B7E, 0xC7A9,
+	0x7B7F, 0xB971, 0x7B80, 0xBCF2, 0x7B81, 0xB972, 0x7B82, 0xB973,
+	0x7B83, 0xB974, 0x7B84, 0xB975, 0x7B85, 0xF3EB, 0x7B86, 0xB976,
+	0x7B87, 0xB977, 0x7B88, 0xB978, 0x7B89, 0xB979, 0x7B8A, 0xB97A,
+	0x7B8B, 0xB97B, 0x7B8C, 0xB97C, 0x7B8D, 0xB9BF, 0x7B8E, 0xB97D,
+	0x7B8F, 0xB97E, 0x7B90, 0xF3E4, 0x7B91, 0xB980, 0x7B92, 0xB981,
+	0x7B93, 0xB982, 0x7B94, 0xB2AD, 0x7B95, 0xBBFE, 0x7B96, 0xB983,
+	0x7B97, 0xCBE3, 0x7B98, 0xB984, 0x7B99, 0xB985, 0x7B9A, 0xB986,
+	0x7B9B, 0xB987, 0x7B9C, 0xF3ED, 0x7B9D, 0xF3E9, 0x7B9E, 0xB988,
+	0x7B9F, 0xB989, 0x7BA0, 0xB98A, 0x7BA1, 0xB9DC, 0x7BA2, 0xF3EE,
+	0x7BA3, 0xB98B, 0x7BA4, 0xB98C, 0x7BA5, 0xB98D, 0x7BA6, 0xF3E5,
+	0x7BA7, 0xF3E6, 0x7BA8, 0xF3EA, 0x7BA9, 0xC2E1, 0x7BAA, 0xF3EC,
+	0x7BAB, 0xF3EF, 0x7BAC, 0xF3E8, 0x7BAD, 0xBCFD, 0x7BAE, 0xB98E,
+	0x7BAF, 0xB98F, 0x7BB0, 0xB990, 0x7BB1, 0xCFE4, 0x7BB2, 0xB991,
+	0x7BB3, 0xB992, 0x7BB4, 0xF3F0, 0x7BB5, 0xB993, 0x7BB6, 0xB994,
+	0x7BB7, 0xB995, 0x7BB8, 0xF3E7, 0x7BB9, 0xB996, 0x7BBA, 0xB997,
+	0x7BBB, 0xB998, 0x7BBC, 0xB999, 0x7BBD, 0xB99A, 0x7BBE, 0xB99B,
+	0x7BBF, 0xB99C, 0x7BC0, 0xB99D, 0x7BC1, 0xF3F2, 0x7BC2, 0xB99E,
+	0x7BC3, 0xB99F, 0x7BC4, 0xB9A0, 0x7BC5, 0xBA40, 0x7BC6, 0xD7AD,
+	0x7BC7, 0xC6AA, 0x7BC8, 0xBA41, 0x7BC9, 0xBA42, 0x7BCA, 0xBA43,
+	0x7BCB, 0xBA44, 0x7BCC, 0xF3F3, 0x7BCD, 0xBA45, 0x7BCE, 0xBA46,
+	0x7BCF, 0xBA47, 0x7BD0, 0xBA48, 0x7BD1, 0xF3F1, 0x7BD2, 0xBA49,
+	0x7BD3, 0xC2A8, 0x7BD4, 0xBA4A, 0x7BD5, 0xBA4B, 0x7BD6, 0xBA4C,
+	0x7BD7, 0xBA4D, 0x7BD8, 0xBA4E, 0x7BD9, 0xB8DD, 0x7BDA, 0xF3F5,
+	0x7BDB, 0xBA4F, 0x7BDC, 0xBA50, 0x7BDD, 0xF3F4, 0x7BDE, 0xBA51,
+	0x7BDF, 0xBA52, 0x7BE0, 0xBA53, 0x7BE1, 0xB4DB, 0x7BE2, 0xBA54,
+	0x7BE3, 0xBA55, 0x7BE4, 0xBA56, 0x7BE5, 0xF3F6, 0x7BE6, 0xF3F7,
+	0x7BE7, 0xBA57, 0x7BE8, 0xBA58, 0x7BE9, 0xBA59, 0x7BEA, 0xF3F8,
+	0x7BEB, 0xBA5A, 0x7BEC, 0xBA5B, 0x7BED, 0xBA5C, 0x7BEE, 0xC0BA,
+	0x7BEF, 0xBA5D, 0x7BF0, 0xBA5E, 0x7BF1, 0xC0E9, 0x7BF2, 0xBA5F,
+	0x7BF3, 0xBA60, 0x7BF4, 0xBA61, 0x7BF5, 0xBA62, 0x7BF6, 0xBA63,
+	0x7BF7, 0xC5F1, 0x7BF8, 0xBA64, 0x7BF9, 0xBA65, 0x7BFA, 0xBA66,
+	0x7BFB, 0xBA67, 0x7BFC, 0xF3FB, 0x7BFD, 0xBA68, 0x7BFE, 0xF3FA,
+	0x7BFF, 0xBA69, 0x7C00, 0xBA6A, 0x7C01, 0xBA6B, 0x7C02, 0xBA6C,
+	0x7C03, 0xBA6D, 0x7C04, 0xBA6E, 0x7C05, 0xBA6F, 0x7C06, 0xBA70,
+	0x7C07, 0xB4D8, 0x7C08, 0xBA71, 0x7C09, 0xBA72, 0x7C0A, 0xBA73,
+	0x7C0B, 0xF3FE, 0x7C0C, 0xF3F9, 0x7C0D, 0xBA74, 0x7C0E, 0xBA75,
+	0x7C0F, 0xF3FC, 0x7C10, 0xBA76, 0x7C11, 0xBA77, 0x7C12, 0xBA78,
+	0x7C13, 0xBA79, 0x7C14, 0xBA7A, 0x7C15, 0xBA7B, 0x7C16, 0xF3FD,
+	0x7C17, 0xBA7C, 0x7C18, 0xBA7D, 0x7C19, 0xBA7E, 0x7C1A, 0xBA80,
+	0x7C1B, 0xBA81, 0x7C1C, 0xBA82, 0x7C1D, 0xBA83, 0x7C1E, 0xBA84,
+	0x7C1F, 0xF4A1, 0x7C20, 0xBA85, 0x7C21, 0xBA86, 0x7C22, 0xBA87,
+	0x7C23, 0xBA88, 0x7C24, 0xBA89, 0x7C25, 0xBA8A, 0x7C26, 0xF4A3,
+	0x7C27, 0xBBC9, 0x7C28, 0xBA8B, 0x7C29, 0xBA8C, 0x7C2A, 0xF4A2,
+	0x7C2B, 0xBA8D, 0x7C2C, 0xBA8E, 0x7C2D, 0xBA8F, 0x7C2E, 0xBA90,
+	0x7C2F, 0xBA91, 0x7C30, 0xBA92, 0x7C31, 0xBA93, 0x7C32, 0xBA94,
+	0x7C33, 0xBA95, 0x7C34, 0xBA96, 0x7C35, 0xBA97, 0x7C36, 0xBA98,
+	0x7C37, 0xBA99, 0x7C38, 0xF4A4, 0x7C39, 0xBA9A, 0x7C3A, 0xBA9B,
+	0x7C3B, 0xBA9C, 0x7C3C, 0xBA9D, 0x7C3D, 0xBA9E, 0x7C3E, 0xBA9F,
+	0x7C3F, 0xB2BE, 0x7C40, 0xF4A6, 0x7C41, 0xF4A5, 0x7C42, 0xBAA0,
+	0x7C43, 0xBB40, 0x7C44, 0xBB41, 0x7C45, 0xBB42, 0x7C46, 0xBB43,
+	0x7C47, 0xBB44, 0x7C48, 0xBB45, 0x7C49, 0xBB46, 0x7C4A, 0xBB47,
+	0x7C4B, 0xBB48, 0x7C4C, 0xBB49, 0x7C4D, 0xBCAE, 0x7C4E, 0xBB4A,
+	0x7C4F, 0xBB4B, 0x7C50, 0xBB4C, 0x7C51, 0xBB4D, 0x7C52, 0xBB4E,
+	0x7C53, 0xBB4F, 0x7C54, 0xBB50, 0x7C55, 0xBB51, 0x7C56, 0xBB52,
+	0x7C57, 0xBB53, 0x7C58, 0xBB54, 0x7C59, 0xBB55, 0x7C5A, 0xBB56,
+	0x7C5B, 0xBB57, 0x7C5C, 0xBB58, 0x7C5D, 0xBB59, 0x7C5E, 0xBB5A,
+	0x7C5F, 0xBB5B, 0x7C60, 0xBB5C, 0x7C61, 0xBB5D, 0x7C62, 0xBB5E,
+	0x7C63, 0xBB5F, 0x7C64, 0xBB60, 0x7C65, 0xBB61, 0x7C66, 0xBB62,
+	0x7C67, 0xBB63, 0x7C68, 0xBB64, 0x7C69, 0xBB65, 0x7C6A, 0xBB66,
+	0x7C6B, 0xBB67, 0x7C6C, 0xBB68, 0x7C6D, 0xBB69, 0x7C6E, 0xBB6A,
+	0x7C6F, 0xBB6B, 0x7C70, 0xBB6C, 0x7C71, 0xBB6D, 0x7C72, 0xBB6E,
+	0x7C73, 0xC3D7, 0x7C74, 0xD9E1, 0x7C75, 0xBB6F, 0x7C76, 0xBB70,
+	0x7C77, 0xBB71, 0x7C78, 0xBB72, 0x7C79, 0xBB73, 0x7C7A, 0xBB74,
+	0x7C7B, 0xC0E0, 0x7C7C, 0xF4CC, 0x7C7D, 0xD7D1, 0x7C7E, 0xBB75,
+	0x7C7F, 0xBB76, 0x7C80, 0xBB77, 0x7C81, 0xBB78, 0x7C82, 0xBB79,
+	0x7C83, 0xBB7A, 0x7C84, 0xBB7B, 0x7C85, 0xBB7C, 0x7C86, 0xBB7D,
+	0x7C87, 0xBB7E, 0x7C88, 0xBB80, 0x7C89, 0xB7DB, 0x7C8A, 0xBB81,
+	0x7C8B, 0xBB82, 0x7C8C, 0xBB83, 0x7C8D, 0xBB84, 0x7C8E, 0xBB85,
+	0x7C8F, 0xBB86, 0x7C90, 0xBB87, 0x7C91, 0xF4CE, 0x7C92, 0xC1A3,
+	0x7C93, 0xBB88, 0x7C94, 0xBB89, 0x7C95, 0xC6C9, 0x7C96, 0xBB8A,
+	0x7C97, 0xB4D6, 0x7C98, 0xD5B3, 0x7C99, 0xBB8B, 0x7C9A, 0xBB8C,
+	0x7C9B, 0xBB8D, 0x7C9C, 0xF4D0, 0x7C9D, 0xF4CF, 0x7C9E, 0xF4D1,
+	0x7C9F, 0xCBDA, 0x7CA0, 0xBB8E, 0x7CA1, 0xBB8F, 0x7CA2, 0xF4D2,
+	0x7CA3, 0xBB90, 0x7CA4, 0xD4C1, 0x7CA5, 0xD6E0, 0x7CA6, 0xBB91,
+	0x7CA7, 0xBB92, 0x7CA8, 0xBB93, 0x7CA9, 0xBB94, 0x7CAA, 0xB7E0,
+	0x7CAB, 0xBB95, 0x7CAC, 0xBB96, 0x7CAD, 0xBB97, 0x7CAE, 0xC1B8,
+	0x7CAF, 0xBB98, 0x7CB0, 0xBB99, 0x7CB1, 0xC1BB, 0x7CB2, 0xF4D3,
+	0x7CB3, 0xBEAC, 0x7CB4, 0xBB9A, 0x7CB5, 0xBB9B, 0x7CB6, 0xBB9C,
+	0x7CB7, 0xBB9D, 0x7CB8, 0xBB9E, 0x7CB9, 0xB4E2, 0x7CBA, 0xBB9F,
+	0x7CBB, 0xBBA0, 0x7CBC, 0xF4D4, 0x7CBD, 0xF4D5, 0x7CBE, 0xBEAB,
+	0x7CBF, 0xBC40, 0x7CC0, 0xBC41, 0x7CC1, 0xF4D6, 0x7CC2, 0xBC42,
+	0x7CC3, 0xBC43, 0x7CC4, 0xBC44, 0x7CC5, 0xF4DB, 0x7CC6, 0xBC45,
+	0x7CC7, 0xF4D7, 0x7CC8, 0xF4DA, 0x7CC9, 0xBC46, 0x7CCA, 0xBAFD,
+	0x7CCB, 0xBC47, 0x7CCC, 0xF4D8, 0x7CCD, 0xF4D9, 0x7CCE, 0xBC48,
+	0x7CCF, 0xBC49, 0x7CD0, 0xBC4A, 0x7CD1, 0xBC4B, 0x7CD2, 0xBC4C,
+	0x7CD3, 0xBC4D, 0x7CD4, 0xBC4E, 0x7CD5, 0xB8E2, 0x7CD6, 0xCCC7,
+	0x7CD7, 0xF4DC, 0x7CD8, 0xBC4F, 0x7CD9, 0xB2DA, 0x7CDA, 0xBC50,
+	0x7CDB, 0xBC51, 0x7CDC, 0xC3D3, 0x7CDD, 0xBC52, 0x7CDE, 0xBC53,
+	0x7CDF, 0xD4E3, 0x7CE0, 0xBFB7, 0x7CE1, 0xBC54, 0x7CE2, 0xBC55,
+	0x7CE3, 0xBC56, 0x7CE4, 0xBC57, 0x7CE5, 0xBC58, 0x7CE6, 0xBC59,
+	0x7CE7, 0xBC5A, 0x7CE8, 0xF4DD, 0x7CE9, 0xBC5B, 0x7CEA, 0xBC5C,
+	0x7CEB, 0xBC5D, 0x7CEC, 0xBC5E, 0x7CED, 0xBC5F, 0x7CEE, 0xBC60,
+	0x7CEF, 0xC5B4, 0x7CF0, 0xBC61, 0x7CF1, 0xBC62, 0x7CF2, 0xBC63,
+	0x7CF3, 0xBC64, 0x7CF4, 0xBC65, 0x7CF5, 0xBC66, 0x7CF6, 0xBC67,
+	0x7CF7, 0xBC68, 0x7CF8, 0xF4E9, 0x7CF9, 0xBC69, 0x7CFA, 0xBC6A,
+	0x7CFB, 0xCFB5, 0x7CFC, 0xBC6B, 0x7CFD, 0xBC6C, 0x7CFE, 0xBC6D,
+	0x7CFF, 0xBC6E, 0x7D00, 0xBC6F, 0x7D01, 0xBC70, 0x7D02, 0xBC71,
+	0x7D03, 0xBC72, 0x7D04, 0xBC73, 0x7D05, 0xBC74, 0x7D06, 0xBC75,
+	0x7D07, 0xBC76, 0x7D08, 0xBC77, 0x7D09, 0xBC78, 0x7D0A, 0xCEC9,
+	0x7D0B, 0xBC79, 0x7D0C, 0xBC7A, 0x7D0D, 0xBC7B, 0x7D0E, 0xBC7C,
+	0x7D0F, 0xBC7D, 0x7D10, 0xBC7E, 0x7D11, 0xBC80, 0x7D12, 0xBC81,
+	0x7D13, 0xBC82, 0x7D14, 0xBC83, 0x7D15, 0xBC84, 0x7D16, 0xBC85,
+	0x7D17, 0xBC86, 0x7D18, 0xBC87, 0x7D19, 0xBC88, 0x7D1A, 0xBC89,
+	0x7D1B, 0xBC8A, 0x7D1C, 0xBC8B, 0x7D1D, 0xBC8C, 0x7D1E, 0xBC8D,
+	0x7D1F, 0xBC8E, 0x7D20, 0xCBD8, 0x7D21, 0xBC8F, 0x7D22, 0xCBF7,
+	0x7D23, 0xBC90, 0x7D24, 0xBC91, 0x7D25, 0xBC92, 0x7D26, 0xBC93,
+	0x7D27, 0xBDF4, 0x7D28, 0xBC94, 0x7D29, 0xBC95, 0x7D2A, 0xBC96,
+	0x7D2B, 0xD7CF, 0x7D2C, 0xBC97, 0x7D2D, 0xBC98, 0x7D2E, 0xBC99,
+	0x7D2F, 0xC0DB, 0x7D30, 0xBC9A, 0x7D31, 0xBC9B, 0x7D32, 0xBC9C,
+	0x7D33, 0xBC9D, 0x7D34, 0xBC9E, 0x7D35, 0xBC9F, 0x7D36, 0xBCA0,
+	0x7D37, 0xBD40, 0x7D38, 0xBD41, 0x7D39, 0xBD42, 0x7D3A, 0xBD43,
+	0x7D3B, 0xBD44, 0x7D3C, 0xBD45, 0x7D3D, 0xBD46, 0x7D3E, 0xBD47,
+	0x7D3F, 0xBD48, 0x7D40, 0xBD49, 0x7D41, 0xBD4A, 0x7D42, 0xBD4B,
+	0x7D43, 0xBD4C, 0x7D44, 0xBD4D, 0x7D45, 0xBD4E, 0x7D46, 0xBD4F,
+	0x7D47, 0xBD50, 0x7D48, 0xBD51, 0x7D49, 0xBD52, 0x7D4A, 0xBD53,
+	0x7D4B, 0xBD54, 0x7D4C, 0xBD55, 0x7D4D, 0xBD56, 0x7D4E, 0xBD57,
+	0x7D4F, 0xBD58, 0x7D50, 0xBD59, 0x7D51, 0xBD5A, 0x7D52, 0xBD5B,
+	0x7D53, 0xBD5C, 0x7D54, 0xBD5D, 0x7D55, 0xBD5E, 0x7D56, 0xBD5F,
+	0x7D57, 0xBD60, 0x7D58, 0xBD61, 0x7D59, 0xBD62, 0x7D5A, 0xBD63,
+	0x7D5B, 0xBD64, 0x7D5C, 0xBD65, 0x7D5D, 0xBD66, 0x7D5E, 0xBD67,
+	0x7D5F, 0xBD68, 0x7D60, 0xBD69, 0x7D61, 0xBD6A, 0x7D62, 0xBD6B,
+	0x7D63, 0xBD6C, 0x7D64, 0xBD6D, 0x7D65, 0xBD6E, 0x7D66, 0xBD6F,
+	0x7D67, 0xBD70, 0x7D68, 0xBD71, 0x7D69, 0xBD72, 0x7D6A, 0xBD73,
+	0x7D6B, 0xBD74, 0x7D6C, 0xBD75, 0x7D6D, 0xBD76, 0x7D6E, 0xD0F5,
+	0x7D6F, 0xBD77, 0x7D70, 0xBD78, 0x7D71, 0xBD79, 0x7D72, 0xBD7A,
+	0x7D73, 0xBD7B, 0x7D74, 0xBD7C, 0x7D75, 0xBD7D, 0x7D76, 0xBD7E,
+	0x7D77, 0xF4EA, 0x7D78, 0xBD80, 0x7D79, 0xBD81, 0x7D7A, 0xBD82,
+	0x7D7B, 0xBD83, 0x7D7C, 0xBD84, 0x7D7D, 0xBD85, 0x7D7E, 0xBD86,
+	0x7D7F, 0xBD87, 0x7D80, 0xBD88, 0x7D81, 0xBD89, 0x7D82, 0xBD8A,
+	0x7D83, 0xBD8B, 0x7D84, 0xBD8C, 0x7D85, 0xBD8D, 0x7D86, 0xBD8E,
+	0x7D87, 0xBD8F, 0x7D88, 0xBD90, 0x7D89, 0xBD91, 0x7D8A, 0xBD92,
+	0x7D8B, 0xBD93, 0x7D8C, 0xBD94, 0x7D8D, 0xBD95, 0x7D8E, 0xBD96,
+	0x7D8F, 0xBD97, 0x7D90, 0xBD98, 0x7D91, 0xBD99, 0x7D92, 0xBD9A,
+	0x7D93, 0xBD9B, 0x7D94, 0xBD9C, 0x7D95, 0xBD9D, 0x7D96, 0xBD9E,
+	0x7D97, 0xBD9F, 0x7D98, 0xBDA0, 0x7D99, 0xBE40, 0x7D9A, 0xBE41,
+	0x7D9B, 0xBE42, 0x7D9C, 0xBE43, 0x7D9D, 0xBE44, 0x7D9E, 0xBE45,
+	0x7D9F, 0xBE46, 0x7DA0, 0xBE47, 0x7DA1, 0xBE48, 0x7DA2, 0xBE49,
+	0x7DA3, 0xBE4A, 0x7DA4, 0xBE4B, 0x7DA5, 0xBE4C, 0x7DA6, 0xF4EB,
+	0x7DA7, 0xBE4D, 0x7DA8, 0xBE4E, 0x7DA9, 0xBE4F, 0x7DAA, 0xBE50,
+	0x7DAB, 0xBE51, 0x7DAC, 0xBE52, 0x7DAD, 0xBE53, 0x7DAE, 0xF4EC,
+	0x7DAF, 0xBE54, 0x7DB0, 0xBE55, 0x7DB1, 0xBE56, 0x7DB2, 0xBE57,
+	0x7DB3, 0xBE58, 0x7DB4, 0xBE59, 0x7DB5, 0xBE5A, 0x7DB6, 0xBE5B,
+	0x7DB7, 0xBE5C, 0x7DB8, 0xBE5D, 0x7DB9, 0xBE5E, 0x7DBA, 0xBE5F,
+	0x7DBB, 0xBE60, 0x7DBC, 0xBE61, 0x7DBD, 0xBE62, 0x7DBE, 0xBE63,
+	0x7DBF, 0xBE64, 0x7DC0, 0xBE65, 0x7DC1, 0xBE66, 0x7DC2, 0xBE67,
+	0x7DC3, 0xBE68, 0x7DC4, 0xBE69, 0x7DC5, 0xBE6A, 0x7DC6, 0xBE6B,
+	0x7DC7, 0xBE6C, 0x7DC8, 0xBE6D, 0x7DC9, 0xBE6E, 0x7DCA, 0xBE6F,
+	0x7DCB, 0xBE70, 0x7DCC, 0xBE71, 0x7DCD, 0xBE72, 0x7DCE, 0xBE73,
+	0x7DCF, 0xBE74, 0x7DD0, 0xBE75, 0x7DD1, 0xBE76, 0x7DD2, 0xBE77,
+	0x7DD3, 0xBE78, 0x7DD4, 0xBE79, 0x7DD5, 0xBE7A, 0x7DD6, 0xBE7B,
+	0x7DD7, 0xBE7C, 0x7DD8, 0xBE7D, 0x7DD9, 0xBE7E, 0x7DDA, 0xBE80,
+	0x7DDB, 0xBE81, 0x7DDC, 0xBE82, 0x7DDD, 0xBE83, 0x7DDE, 0xBE84,
+	0x7DDF, 0xBE85, 0x7DE0, 0xBE86, 0x7DE1, 0xBE87, 0x7DE2, 0xBE88,
+	0x7DE3, 0xBE89, 0x7DE4, 0xBE8A, 0x7DE5, 0xBE8B, 0x7DE6, 0xBE8C,
+	0x7DE7, 0xBE8D, 0x7DE8, 0xBE8E, 0x7DE9, 0xBE8F, 0x7DEA, 0xBE90,
+	0x7DEB, 0xBE91, 0x7DEC, 0xBE92, 0x7DED, 0xBE93, 0x7DEE, 0xBE94,
+	0x7DEF, 0xBE95, 0x7DF0, 0xBE96, 0x7DF1, 0xBE97, 0x7DF2, 0xBE98,
+	0x7DF3, 0xBE99, 0x7DF4, 0xBE9A, 0x7DF5, 0xBE9B, 0x7DF6, 0xBE9C,
+	0x7DF7, 0xBE9D, 0x7DF8, 0xBE9E, 0x7DF9, 0xBE9F, 0x7DFA, 0xBEA0,
+	0x7DFB, 0xBF40, 0x7DFC, 0xBF41, 0x7DFD, 0xBF42, 0x7DFE, 0xBF43,
+	0x7DFF, 0xBF44, 0x7E00, 0xBF45, 0x7E01, 0xBF46, 0x7E02, 0xBF47,
+	0x7E03, 0xBF48, 0x7E04, 0xBF49, 0x7E05, 0xBF4A, 0x7E06, 0xBF4B,
+	0x7E07, 0xBF4C, 0x7E08, 0xBF4D, 0x7E09, 0xBF4E, 0x7E0A, 0xBF4F,
+	0x7E0B, 0xBF50, 0x7E0C, 0xBF51, 0x7E0D, 0xBF52, 0x7E0E, 0xBF53,
+	0x7E0F, 0xBF54, 0x7E10, 0xBF55, 0x7E11, 0xBF56, 0x7E12, 0xBF57,
+	0x7E13, 0xBF58, 0x7E14, 0xBF59, 0x7E15, 0xBF5A, 0x7E16, 0xBF5B,
+	0x7E17, 0xBF5C, 0x7E18, 0xBF5D, 0x7E19, 0xBF5E, 0x7E1A, 0xBF5F,
+	0x7E1B, 0xBF60, 0x7E1C, 0xBF61, 0x7E1D, 0xBF62, 0x7E1E, 0xBF63,
+	0x7E1F, 0xBF64, 0x7E20, 0xBF65, 0x7E21, 0xBF66, 0x7E22, 0xBF67,
+	0x7E23, 0xBF68, 0x7E24, 0xBF69, 0x7E25, 0xBF6A, 0x7E26, 0xBF6B,
+	0x7E27, 0xBF6C, 0x7E28, 0xBF6D, 0x7E29, 0xBF6E, 0x7E2A, 0xBF6F,
+	0x7E2B, 0xBF70, 0x7E2C, 0xBF71, 0x7E2D, 0xBF72, 0x7E2E, 0xBF73,
+	0x7E2F, 0xBF74, 0x7E30, 0xBF75, 0x7E31, 0xBF76, 0x7E32, 0xBF77,
+	0x7E33, 0xBF78, 0x7E34, 0xBF79, 0x7E35, 0xBF7A, 0x7E36, 0xBF7B,
+	0x7E37, 0xBF7C, 0x7E38, 0xBF7D, 0x7E39, 0xBF7E, 0x7E3A, 0xBF80,
+	0x7E3B, 0xF7E3, 0x7E3C, 0xBF81, 0x7E3D, 0xBF82, 0x7E3E, 0xBF83,
+	0x7E3F, 0xBF84, 0x7E40, 0xBF85, 0x7E41, 0xB7B1, 0x7E42, 0xBF86,
+	0x7E43, 0xBF87, 0x7E44, 0xBF88, 0x7E45, 0xBF89, 0x7E46, 0xBF8A,
+	0x7E47, 0xF4ED, 0x7E48, 0xBF8B, 0x7E49, 0xBF8C, 0x7E4A, 0xBF8D,
+	0x7E4B, 0xBF8E, 0x7E4C, 0xBF8F, 0x7E4D, 0xBF90, 0x7E4E, 0xBF91,
+	0x7E4F, 0xBF92, 0x7E50, 0xBF93, 0x7E51, 0xBF94, 0x7E52, 0xBF95,
+	0x7E53, 0xBF96, 0x7E54, 0xBF97, 0x7E55, 0xBF98, 0x7E56, 0xBF99,
+	0x7E57, 0xBF9A, 0x7E58, 0xBF9B, 0x7E59, 0xBF9C, 0x7E5A, 0xBF9D,
+	0x7E5B, 0xBF9E, 0x7E5C, 0xBF9F, 0x7E5D, 0xBFA0, 0x7E5E, 0xC040,
+	0x7E5F, 0xC041, 0x7E60, 0xC042, 0x7E61, 0xC043, 0x7E62, 0xC044,
+	0x7E63, 0xC045, 0x7E64, 0xC046, 0x7E65, 0xC047, 0x7E66, 0xC048,
+	0x7E67, 0xC049, 0x7E68, 0xC04A, 0x7E69, 0xC04B, 0x7E6A, 0xC04C,
+	0x7E6B, 0xC04D, 0x7E6C, 0xC04E, 0x7E6D, 0xC04F, 0x7E6E, 0xC050,
+	0x7E6F, 0xC051, 0x7E70, 0xC052, 0x7E71, 0xC053, 0x7E72, 0xC054,
+	0x7E73, 0xC055, 0x7E74, 0xC056, 0x7E75, 0xC057, 0x7E76, 0xC058,
+	0x7E77, 0xC059, 0x7E78, 0xC05A, 0x7E79, 0xC05B, 0x7E7A, 0xC05C,
+	0x7E7B, 0xC05D, 0x7E7C, 0xC05E, 0x7E7D, 0xC05F, 0x7E7E, 0xC060,
+	0x7E7F, 0xC061, 0x7E80, 0xC062, 0x7E81, 0xC063, 0x7E82, 0xD7EB,
+	0x7E83, 0xC064, 0x7E84, 0xC065, 0x7E85, 0xC066, 0x7E86, 0xC067,
+	0x7E87, 0xC068, 0x7E88, 0xC069, 0x7E89, 0xC06A, 0x7E8A, 0xC06B,
+	0x7E8B, 0xC06C, 0x7E8C, 0xC06D, 0x7E8D, 0xC06E, 0x7E8E, 0xC06F,
+	0x7E8F, 0xC070, 0x7E90, 0xC071, 0x7E91, 0xC072, 0x7E92, 0xC073,
+	0x7E93, 0xC074, 0x7E94, 0xC075, 0x7E95, 0xC076, 0x7E96, 0xC077,
+	0x7E97, 0xC078, 0x7E98, 0xC079, 0x7E99, 0xC07A, 0x7E9A, 0xC07B,
+	0x7E9B, 0xF4EE, 0x7E9C, 0xC07C, 0x7E9D, 0xC07D, 0x7E9E, 0xC07E,
+	0x7E9F, 0xE6F9, 0x7EA0, 0xBEC0, 0x7EA1, 0xE6FA, 0x7EA2, 0xBAEC,
+	0x7EA3, 0xE6FB, 0x7EA4, 0xCFCB, 0x7EA5, 0xE6FC, 0x7EA6, 0xD4BC,
+	0x7EA7, 0xBCB6, 0x7EA8, 0xE6FD, 0x7EA9, 0xE6FE, 0x7EAA, 0xBCCD,
+	0x7EAB, 0xC8D2, 0x7EAC, 0xCEB3, 0x7EAD, 0xE7A1, 0x7EAE, 0xC080,
+	0x7EAF, 0xB4BF, 0x7EB0, 0xE7A2, 0x7EB1, 0xC9B4, 0x7EB2, 0xB8D9,
+	0x7EB3, 0xC4C9, 0x7EB4, 0xC081, 0x7EB5, 0xD7DD, 0x7EB6, 0xC2DA,
+	0x7EB7, 0xB7D7, 0x7EB8, 0xD6BD, 0x7EB9, 0xCEC6, 0x7EBA, 0xB7C4,
+	0x7EBB, 0xC082, 0x7EBC, 0xC083, 0x7EBD, 0xC5A6, 0x7EBE, 0xE7A3,
+	0x7EBF, 0xCFDF, 0x7EC0, 0xE7A4, 0x7EC1, 0xE7A5, 0x7EC2, 0xE7A6,
+	0x7EC3, 0xC1B7, 0x7EC4, 0xD7E9, 0x7EC5, 0xC9F0, 0x7EC6, 0xCFB8,
+	0x7EC7, 0xD6AF, 0x7EC8, 0xD6D5, 0x7EC9, 0xE7A7, 0x7ECA, 0xB0ED,
+	0x7ECB, 0xE7A8, 0x7ECC, 0xE7A9, 0x7ECD, 0xC9DC, 0x7ECE, 0xD2EF,
+	0x7ECF, 0xBEAD, 0x7ED0, 0xE7AA, 0x7ED1, 0xB0F3, 0x7ED2, 0xC8DE,
+	0x7ED3, 0xBDE1, 0x7ED4, 0xE7AB, 0x7ED5, 0xC8C6, 0x7ED6, 0xC084,
+	0x7ED7, 0xE7AC, 0x7ED8, 0xBBE6, 0x7ED9, 0xB8F8, 0x7EDA, 0xD1A4,
+	0x7EDB, 0xE7AD, 0x7EDC, 0xC2E7, 0x7EDD, 0xBEF8, 0x7EDE, 0xBDCA,
+	0x7EDF, 0xCDB3, 0x7EE0, 0xE7AE, 0x7EE1, 0xE7AF, 0x7EE2, 0xBEEE,
+	0x7EE3, 0xD0E5, 0x7EE4, 0xC085, 0x7EE5, 0xCBE7, 0x7EE6, 0xCCD0,
+	0x7EE7, 0xBCCC, 0x7EE8, 0xE7B0, 0x7EE9, 0xBCA8, 0x7EEA, 0xD0F7,
+	0x7EEB, 0xE7B1, 0x7EEC, 0xC086, 0x7EED, 0xD0F8, 0x7EEE, 0xE7B2,
+	0x7EEF, 0xE7B3, 0x7EF0, 0xB4C2, 0x7EF1, 0xE7B4, 0x7EF2, 0xE7B5,
+	0x7EF3, 0xC9FE, 0x7EF4, 0xCEAC, 0x7EF5, 0xC3E0, 0x7EF6, 0xE7B7,
+	0x7EF7, 0xB1C1, 0x7EF8, 0xB3F1, 0x7EF9, 0xC087, 0x7EFA, 0xE7B8,
+	0x7EFB, 0xE7B9, 0x7EFC, 0xD7DB, 0x7EFD, 0xD5C0, 0x7EFE, 0xE7BA,
+	0x7EFF, 0xC2CC, 0x7F00, 0xD7BA, 0x7F01, 0xE7BB, 0x7F02, 0xE7BC,
+	0x7F03, 0xE7BD, 0x7F04, 0xBCEA, 0x7F05, 0xC3E5, 0x7F06, 0xC0C2,
+	0x7F07, 0xE7BE, 0x7F08, 0xE7BF, 0x7F09, 0xBCA9, 0x7F0A, 0xC088,
+	0x7F0B, 0xE7C0, 0x7F0C, 0xE7C1, 0x7F0D, 0xE7B6, 0x7F0E, 0xB6D0,
+	0x7F0F, 0xE7C2, 0x7F10, 0xC089, 0x7F11, 0xE7C3, 0x7F12, 0xE7C4,
+	0x7F13, 0xBBBA, 0x7F14, 0xB5DE, 0x7F15, 0xC2C6, 0x7F16, 0xB1E0,
+	0x7F17, 0xE7C5, 0x7F18, 0xD4B5, 0x7F19, 0xE7C6, 0x7F1A, 0xB8BF,
+	0x7F1B, 0xE7C8, 0x7F1C, 0xE7C7, 0x7F1D, 0xB7EC, 0x7F1E, 0xC08A,
+	0x7F1F, 0xE7C9, 0x7F20, 0xB2F8, 0x7F21, 0xE7CA, 0x7F22, 0xE7CB,
+	0x7F23, 0xE7CC, 0x7F24, 0xE7CD, 0x7F25, 0xE7CE, 0x7F26, 0xE7CF,
+	0x7F27, 0xE7D0, 0x7F28, 0xD3A7, 0x7F29, 0xCBF5, 0x7F2A, 0xE7D1,
+	0x7F2B, 0xE7D2, 0x7F2C, 0xE7D3, 0x7F2D, 0xE7D4, 0x7F2E, 0xC9C9,
+	0x7F2F, 0xE7D5, 0x7F30, 0xE7D6, 0x7F31, 0xE7D7, 0x7F32, 0xE7D8,
+	0x7F33, 0xE7D9, 0x7F34, 0xBDC9, 0x7F35, 0xE7DA, 0x7F36, 0xF3BE,
+	0x7F37, 0xC08B, 0x7F38, 0xB8D7, 0x7F39, 0xC08C, 0x7F3A, 0xC8B1,
+	0x7F3B, 0xC08D, 0x7F3C, 0xC08E, 0x7F3D, 0xC08F, 0x7F3E, 0xC090,
+	0x7F3F, 0xC091, 0x7F40, 0xC092, 0x7F41, 0xC093, 0x7F42, 0xF3BF,
+	0x7F43, 0xC094, 0x7F44, 0xF3C0, 0x7F45, 0xF3C1, 0x7F46, 0xC095,
+	0x7F47, 0xC096, 0x7F48, 0xC097, 0x7F49, 0xC098, 0x7F4A, 0xC099,
+	0x7F4B, 0xC09A, 0x7F4C, 0xC09B, 0x7F4D, 0xC09C, 0x7F4E, 0xC09D,
+	0x7F4F, 0xC09E, 0x7F50, 0xB9DE, 0x7F51, 0xCDF8, 0x7F52, 0xC09F,
+	0x7F53, 0xC0A0, 0x7F54, 0xD8E8, 0x7F55, 0xBAB1, 0x7F56, 0xC140,
+	0x7F57, 0xC2DE, 0x7F58, 0xEEB7, 0x7F59, 0xC141, 0x7F5A, 0xB7A3,
+	0x7F5B, 0xC142, 0x7F5C, 0xC143, 0x7F5D, 0xC144, 0x7F5E, 0xC145,
+	0x7F5F, 0xEEB9, 0x7F60, 0xC146, 0x7F61, 0xEEB8, 0x7F62, 0xB0D5,
+	0x7F63, 0xC147, 0x7F64, 0xC148, 0x7F65, 0xC149, 0x7F66, 0xC14A,
+	0x7F67, 0xC14B, 0x7F68, 0xEEBB, 0x7F69, 0xD5D6, 0x7F6A, 0xD7EF,
+	0x7F6B, 0xC14C, 0x7F6C, 0xC14D, 0x7F6D, 0xC14E, 0x7F6E, 0xD6C3,
+	0x7F6F, 0xC14F, 0x7F70, 0xC150, 0x7F71, 0xEEBD, 0x7F72, 0xCAF0,
+	0x7F73, 0xC151, 0x7F74, 0xEEBC, 0x7F75, 0xC152, 0x7F76, 0xC153,
+	0x7F77, 0xC154, 0x7F78, 0xC155, 0x7F79, 0xEEBE, 0x7F7A, 0xC156,
+	0x7F7B, 0xC157, 0x7F7C, 0xC158, 0x7F7D, 0xC159, 0x7F7E, 0xEEC0,
+	0x7F7F, 0xC15A, 0x7F80, 0xC15B, 0x7F81, 0xEEBF, 0x7F82, 0xC15C,
+	0x7F83, 0xC15D, 0x7F84, 0xC15E, 0x7F85, 0xC15F, 0x7F86, 0xC160,
+	0x7F87, 0xC161, 0x7F88, 0xC162, 0x7F89, 0xC163, 0x7F8A, 0xD1F2,
+	0x7F8B, 0xC164, 0x7F8C, 0xC7BC, 0x7F8D, 0xC165, 0x7F8E, 0xC3C0,
+	0x7F8F, 0xC166, 0x7F90, 0xC167, 0x7F91, 0xC168, 0x7F92, 0xC169,
+	0x7F93, 0xC16A, 0x7F94, 0xB8E1, 0x7F95, 0xC16B, 0x7F96, 0xC16C,
+	0x7F97, 0xC16D, 0x7F98, 0xC16E, 0x7F99, 0xC16F, 0x7F9A, 0xC1E7,
+	0x7F9B, 0xC170, 0x7F9C, 0xC171, 0x7F9D, 0xF4C6, 0x7F9E, 0xD0DF,
+	0x7F9F, 0xF4C7, 0x7FA0, 0xC172, 0x7FA1, 0xCFDB, 0x7FA2, 0xC173,
+	0x7FA3, 0xC174, 0x7FA4, 0xC8BA, 0x7FA5, 0xC175, 0x7FA6, 0xC176,
+	0x7FA7, 0xF4C8, 0x7FA8, 0xC177, 0x7FA9, 0xC178, 0x7FAA, 0xC179,
+	0x7FAB, 0xC17A, 0x7FAC, 0xC17B, 0x7FAD, 0xC17C, 0x7FAE, 0xC17D,
+	0x7FAF, 0xF4C9, 0x7FB0, 0xF4CA, 0x7FB1, 0xC17E, 0x7FB2, 0xF4CB,
+	0x7FB3, 0xC180, 0x7FB4, 0xC181, 0x7FB5, 0xC182, 0x7FB6, 0xC183,
+	0x7FB7, 0xC184, 0x7FB8, 0xD9FA, 0x7FB9, 0xB8FE, 0x7FBA, 0xC185,
+	0x7FBB, 0xC186, 0x7FBC, 0xE5F1, 0x7FBD, 0xD3F0, 0x7FBE, 0xC187,
+	0x7FBF, 0xF4E0, 0x7FC0, 0xC188, 0x7FC1, 0xCECC, 0x7FC2, 0xC189,
+	0x7FC3, 0xC18A, 0x7FC4, 0xC18B, 0x7FC5, 0xB3E1, 0x7FC6, 0xC18C,
+	0x7FC7, 0xC18D, 0x7FC8, 0xC18E, 0x7FC9, 0xC18F, 0x7FCA, 0xF1B4,
+	0x7FCB, 0xC190, 0x7FCC, 0xD2EE, 0x7FCD, 0xC191, 0x7FCE, 0xF4E1,
+	0x7FCF, 0xC192, 0x7FD0, 0xC193, 0x7FD1, 0xC194, 0x7FD2, 0xC195,
+	0x7FD3, 0xC196, 0x7FD4, 0xCFE8, 0x7FD5, 0xF4E2, 0x7FD6, 0xC197,
+	0x7FD7, 0xC198, 0x7FD8, 0xC7CC, 0x7FD9, 0xC199, 0x7FDA, 0xC19A,
+	0x7FDB, 0xC19B, 0x7FDC, 0xC19C, 0x7FDD, 0xC19D, 0x7FDE, 0xC19E,
+	0x7FDF, 0xB5D4, 0x7FE0, 0xB4E4, 0x7FE1, 0xF4E4, 0x7FE2, 0xC19F,
+	0x7FE3, 0xC1A0, 0x7FE4, 0xC240, 0x7FE5, 0xF4E3, 0x7FE6, 0xF4E5,
+	0x7FE7, 0xC241, 0x7FE8, 0xC242, 0x7FE9, 0xF4E6, 0x7FEA, 0xC243,
+	0x7FEB, 0xC244, 0x7FEC, 0xC245, 0x7FED, 0xC246, 0x7FEE, 0xF4E7,
+	0x7FEF, 0xC247, 0x7FF0, 0xBAB2, 0x7FF1, 0xB0BF, 0x7FF2, 0xC248,
+	0x7FF3, 0xF4E8, 0x7FF4, 0xC249, 0x7FF5, 0xC24A, 0x7FF6, 0xC24B,
+	0x7FF7, 0xC24C, 0x7FF8, 0xC24D, 0x7FF9, 0xC24E, 0x7FFA, 0xC24F,
+	0x7FFB, 0xB7AD, 0x7FFC, 0xD2ED, 0x7FFD, 0xC250, 0x7FFE, 0xC251,
+	0x7FFF, 0xC252, 0x8000, 0xD2AB, 0x8001, 0xC0CF, 0x8002, 0xC253,
+	0x8003, 0xBFBC, 0x8004, 0xEBA3, 0x8005, 0xD5DF, 0x8006, 0xEAC8,
+	0x8007, 0xC254, 0x8008, 0xC255, 0x8009, 0xC256, 0x800A, 0xC257,
+	0x800B, 0xF1F3, 0x800C, 0xB6F8, 0x800D, 0xCBA3, 0x800E, 0xC258,
+	0x800F, 0xC259, 0x8010, 0xC4CD, 0x8011, 0xC25A, 0x8012, 0xF1E7,
+	0x8013, 0xC25B, 0x8014, 0xF1E8, 0x8015, 0xB8FB, 0x8016, 0xF1E9,
+	0x8017, 0xBAC4, 0x8018, 0xD4C5, 0x8019, 0xB0D2, 0x801A, 0xC25C,
+	0x801B, 0xC25D, 0x801C, 0xF1EA, 0x801D, 0xC25E, 0x801E, 0xC25F,
+	0x801F, 0xC260, 0x8020, 0xF1EB, 0x8021, 0xC261, 0x8022, 0xF1EC,
+	0x8023, 0xC262, 0x8024, 0xC263, 0x8025, 0xF1ED, 0x8026, 0xF1EE,
+	0x8027, 0xF1EF, 0x8028, 0xF1F1, 0x8029, 0xF1F0, 0x802A, 0xC5D5,
+	0x802B, 0xC264, 0x802C, 0xC265, 0x802D, 0xC266, 0x802E, 0xC267,
+	0x802F, 0xC268, 0x8030, 0xC269, 0x8031, 0xF1F2, 0x8032, 0xC26A,
+	0x8033, 0xB6FA, 0x8034, 0xC26B, 0x8035, 0xF1F4, 0x8036, 0xD2AE,
+	0x8037, 0xDEC7, 0x8038, 0xCBCA, 0x8039, 0xC26C, 0x803A, 0xC26D,
+	0x803B, 0xB3DC, 0x803C, 0xC26E, 0x803D, 0xB5A2, 0x803E, 0xC26F,
+	0x803F, 0xB9A2, 0x8040, 0xC270, 0x8041, 0xC271, 0x8042, 0xC4F4,
+	0x8043, 0xF1F5, 0x8044, 0xC272, 0x8045, 0xC273, 0x8046, 0xF1F6,
+	0x8047, 0xC274, 0x8048, 0xC275, 0x8049, 0xC276, 0x804A, 0xC1C4,
+	0x804B, 0xC1FB, 0x804C, 0xD6B0, 0x804D, 0xF1F7, 0x804E, 0xC277,
+	0x804F, 0xC278, 0x8050, 0xC279, 0x8051, 0xC27A, 0x8052, 0xF1F8,
+	0x8053, 0xC27B, 0x8054, 0xC1AA, 0x8055, 0xC27C, 0x8056, 0xC27D,
+	0x8057, 0xC27E, 0x8058, 0xC6B8, 0x8059, 0xC280, 0x805A, 0xBEDB,
+	0x805B, 0xC281, 0x805C, 0xC282, 0x805D, 0xC283, 0x805E, 0xC284,
+	0x805F, 0xC285, 0x8060, 0xC286, 0x8061, 0xC287, 0x8062, 0xC288,
+	0x8063, 0xC289, 0x8064, 0xC28A, 0x8065, 0xC28B, 0x8066, 0xC28C,
+	0x8067, 0xC28D, 0x8068, 0xC28E, 0x8069, 0xF1F9, 0x806A, 0xB4CF,
+	0x806B, 0xC28F, 0x806C, 0xC290, 0x806D, 0xC291, 0x806E, 0xC292,
+	0x806F, 0xC293, 0x8070, 0xC294, 0x8071, 0xF1FA, 0x8072, 0xC295,
+	0x8073, 0xC296, 0x8074, 0xC297, 0x8075, 0xC298, 0x8076, 0xC299,
+	0x8077, 0xC29A, 0x8078, 0xC29B, 0x8079, 0xC29C, 0x807A, 0xC29D,
+	0x807B, 0xC29E, 0x807C, 0xC29F, 0x807D, 0xC2A0, 0x807E, 0xC340,
+	0x807F, 0xEDB2, 0x8080, 0xEDB1, 0x8081, 0xC341, 0x8082, 0xC342,
+	0x8083, 0xCBE0, 0x8084, 0xD2DE, 0x8085, 0xC343, 0x8086, 0xCBC1,
+	0x8087, 0xD5D8, 0x8088, 0xC344, 0x8089, 0xC8E2, 0x808A, 0xC345,
+	0x808B, 0xC0DF, 0x808C, 0xBCA1, 0x808D, 0xC346, 0x808E, 0xC347,
+	0x808F, 0xC348, 0x8090, 0xC349, 0x8091, 0xC34A, 0x8092, 0xC34B,
+	0x8093, 0xEBC1, 0x8094, 0xC34C, 0x8095, 0xC34D, 0x8096, 0xD0A4,
+	0x8097, 0xC34E, 0x8098, 0xD6E2, 0x8099, 0xC34F, 0x809A, 0xB6C7,
+	0x809B, 0xB8D8, 0x809C, 0xEBC0, 0x809D, 0xB8CE, 0x809E, 0xC350,
+	0x809F, 0xEBBF, 0x80A0, 0xB3A6, 0x80A1, 0xB9C9, 0x80A2, 0xD6AB,
+	0x80A3, 0xC351, 0x80A4, 0xB7F4, 0x80A5, 0xB7CA, 0x80A6, 0xC352,
+	0x80A7, 0xC353, 0x80A8, 0xC354, 0x80A9, 0xBCE7, 0x80AA, 0xB7BE,
+	0x80AB, 0xEBC6, 0x80AC, 0xC355, 0x80AD, 0xEBC7, 0x80AE, 0xB0B9,
+	0x80AF, 0xBFCF, 0x80B0, 0xC356, 0x80B1, 0xEBC5, 0x80B2, 0xD3FD,
+	0x80B3, 0xC357, 0x80B4, 0xEBC8, 0x80B5, 0xC358, 0x80B6, 0xC359,
+	0x80B7, 0xEBC9, 0x80B8, 0xC35A, 0x80B9, 0xC35B, 0x80BA, 0xB7CE,
+	0x80BB, 0xC35C, 0x80BC, 0xEBC2, 0x80BD, 0xEBC4, 0x80BE, 0xC9F6,
+	0x80BF, 0xD6D7, 0x80C0, 0xD5CD, 0x80C1, 0xD0B2, 0x80C2, 0xEBCF,
+	0x80C3, 0xCEB8, 0x80C4, 0xEBD0, 0x80C5, 0xC35D, 0x80C6, 0xB5A8,
+	0x80C7, 0xC35E, 0x80C8, 0xC35F, 0x80C9, 0xC360, 0x80CA, 0xC361,
+	0x80CB, 0xC362, 0x80CC, 0xB1B3, 0x80CD, 0xEBD2, 0x80CE, 0xCCA5,
+	0x80CF, 0xC363, 0x80D0, 0xC364, 0x80D1, 0xC365, 0x80D2, 0xC366,
+	0x80D3, 0xC367, 0x80D4, 0xC368, 0x80D5, 0xC369, 0x80D6, 0xC5D6,
+	0x80D7, 0xEBD3, 0x80D8, 0xC36A, 0x80D9, 0xEBD1, 0x80DA, 0xC5DF,
+	0x80DB, 0xEBCE, 0x80DC, 0xCAA4, 0x80DD, 0xEBD5, 0x80DE, 0xB0FB,
+	0x80DF, 0xC36B, 0x80E0, 0xC36C, 0x80E1, 0xBAFA, 0x80E2, 0xC36D,
+	0x80E3, 0xC36E, 0x80E4, 0xD8B7, 0x80E5, 0xF1E3, 0x80E6, 0xC36F,
+	0x80E7, 0xEBCA, 0x80E8, 0xEBCB, 0x80E9, 0xEBCC, 0x80EA, 0xEBCD,
+	0x80EB, 0xEBD6, 0x80EC, 0xE6C0, 0x80ED, 0xEBD9, 0x80EE, 0xC370,
+	0x80EF, 0xBFE8, 0x80F0, 0xD2C8, 0x80F1, 0xEBD7, 0x80F2, 0xEBDC,
+	0x80F3, 0xB8EC, 0x80F4, 0xEBD8, 0x80F5, 0xC371, 0x80F6, 0xBDBA,
+	0x80F7, 0xC372, 0x80F8, 0xD0D8, 0x80F9, 0xC373, 0x80FA, 0xB0B7,
+	0x80FB, 0xC374, 0x80FC, 0xEBDD, 0x80FD, 0xC4DC, 0x80FE, 0xC375,
+	0x80FF, 0xC376, 0x8100, 0xC377, 0x8101, 0xC378, 0x8102, 0xD6AC,
+	0x8103, 0xC379, 0x8104, 0xC37A, 0x8105, 0xC37B, 0x8106, 0xB4E0,
+	0x8107, 0xC37C, 0x8108, 0xC37D, 0x8109, 0xC2F6, 0x810A, 0xBCB9,
+	0x810B, 0xC37E, 0x810C, 0xC380, 0x810D, 0xEBDA, 0x810E, 0xEBDB,
+	0x810F, 0xD4E0, 0x8110, 0xC6EA, 0x8111, 0xC4D4, 0x8112, 0xEBDF,
+	0x8113, 0xC5A7, 0x8114, 0xD9F5, 0x8115, 0xC381, 0x8116, 0xB2B1,
+	0x8117, 0xC382, 0x8118, 0xEBE4, 0x8119, 0xC383, 0x811A, 0xBDC5,
+	0x811B, 0xC384, 0x811C, 0xC385, 0x811D, 0xC386, 0x811E, 0xEBE2,
+	0x811F, 0xC387, 0x8120, 0xC388, 0x8121, 0xC389, 0x8122, 0xC38A,
+	0x8123, 0xC38B, 0x8124, 0xC38C, 0x8125, 0xC38D, 0x8126, 0xC38E,
+	0x8127, 0xC38F, 0x8128, 0xC390, 0x8129, 0xC391, 0x812A, 0xC392,
+	0x812B, 0xC393, 0x812C, 0xEBE3, 0x812D, 0xC394, 0x812E, 0xC395,
+	0x812F, 0xB8AC, 0x8130, 0xC396, 0x8131, 0xCDD1, 0x8132, 0xEBE5,
+	0x8133, 0xC397, 0x8134, 0xC398, 0x8135, 0xC399, 0x8136, 0xEBE1,
+	0x8137, 0xC39A, 0x8138, 0xC1B3, 0x8139, 0xC39B, 0x813A, 0xC39C,
+	0x813B, 0xC39D, 0x813C, 0xC39E, 0x813D, 0xC39F, 0x813E, 0xC6A2,
+	0x813F, 0xC3A0, 0x8140, 0xC440, 0x8141, 0xC441, 0x8142, 0xC442,
+	0x8143, 0xC443, 0x8144, 0xC444, 0x8145, 0xC445, 0x8146, 0xCCF3,
+	0x8147, 0xC446, 0x8148, 0xEBE6, 0x8149, 0xC447, 0x814A, 0xC0B0,
+	0x814B, 0xD2B8, 0x814C, 0xEBE7, 0x814D, 0xC448, 0x814E, 0xC449,
+	0x814F, 0xC44A, 0x8150, 0xB8AF, 0x8151, 0xB8AD, 0x8152, 0xC44B,
+	0x8153, 0xEBE8, 0x8154, 0xC7BB, 0x8155, 0xCDF3, 0x8156, 0xC44C,
+	0x8157, 0xC44D, 0x8158, 0xC44E, 0x8159, 0xEBEA, 0x815A, 0xEBEB,
+	0x815B, 0xC44F, 0x815C, 0xC450, 0x815D, 0xC451, 0x815E, 0xC452,
+	0x815F, 0xC453, 0x8160, 0xEBED, 0x8161, 0xC454, 0x8162, 0xC455,
+	0x8163, 0xC456, 0x8164, 0xC457, 0x8165, 0xD0C8, 0x8166, 0xC458,
+	0x8167, 0xEBF2, 0x8168, 0xC459, 0x8169, 0xEBEE, 0x816A, 0xC45A,
+	0x816B, 0xC45B, 0x816C, 0xC45C, 0x816D, 0xEBF1, 0x816E, 0xC8F9,
+	0x816F, 0xC45D, 0x8170, 0xD1FC, 0x8171, 0xEBEC, 0x8172, 0xC45E,
+	0x8173, 0xC45F, 0x8174, 0xEBE9, 0x8175, 0xC460, 0x8176, 0xC461,
+	0x8177, 0xC462, 0x8178, 0xC463, 0x8179, 0xB8B9, 0x817A, 0xCFD9,
+	0x817B, 0xC4E5, 0x817C, 0xEBEF, 0x817D, 0xEBF0, 0x817E, 0xCCDA,
+	0x817F, 0xCDC8, 0x8180, 0xB0F2, 0x8181, 0xC464, 0x8182, 0xEBF6,
+	0x8183, 0xC465, 0x8184, 0xC466, 0x8185, 0xC467, 0x8186, 0xC468,
+	0x8187, 0xC469, 0x8188, 0xEBF5, 0x8189, 0xC46A, 0x818A, 0xB2B2,
+	0x818B, 0xC46B, 0x818C, 0xC46C, 0x818D, 0xC46D, 0x818E, 0xC46E,
+	0x818F, 0xB8E0, 0x8190, 0xC46F, 0x8191, 0xEBF7, 0x8192, 0xC470,
+	0x8193, 0xC471, 0x8194, 0xC472, 0x8195, 0xC473, 0x8196, 0xC474,
+	0x8197, 0xC475, 0x8198, 0xB1EC, 0x8199, 0xC476, 0x819A, 0xC477,
+	0x819B, 0xCCC5, 0x819C, 0xC4A4, 0x819D, 0xCFA5, 0x819E, 0xC478,
+	0x819F, 0xC479, 0x81A0, 0xC47A, 0x81A1, 0xC47B, 0x81A2, 0xC47C,
+	0x81A3, 0xEBF9, 0x81A4, 0xC47D, 0x81A5, 0xC47E, 0x81A6, 0xECA2,
+	0x81A7, 0xC480, 0x81A8, 0xC5F2, 0x81A9, 0xC481, 0x81AA, 0xEBFA,
+	0x81AB, 0xC482, 0x81AC, 0xC483, 0x81AD, 0xC484, 0x81AE, 0xC485,
+	0x81AF, 0xC486, 0x81B0, 0xC487, 0x81B1, 0xC488, 0x81B2, 0xC489,
+	0x81B3, 0xC9C5, 0x81B4, 0xC48A, 0x81B5, 0xC48B, 0x81B6, 0xC48C,
+	0x81B7, 0xC48D, 0x81B8, 0xC48E, 0x81B9, 0xC48F, 0x81BA, 0xE2DF,
+	0x81BB, 0xEBFE, 0x81BC, 0xC490, 0x81BD, 0xC491, 0x81BE, 0xC492,
+	0x81BF, 0xC493, 0x81C0, 0xCDCE, 0x81C1, 0xECA1, 0x81C2, 0xB1DB,
+	0x81C3, 0xD3B7, 0x81C4, 0xC494, 0x81C5, 0xC495, 0x81C6, 0xD2DC,
+	0x81C7, 0xC496, 0x81C8, 0xC497, 0x81C9, 0xC498, 0x81CA, 0xEBFD,
+	0x81CB, 0xC499, 0x81CC, 0xEBFB, 0x81CD, 0xC49A, 0x81CE, 0xC49B,
+	0x81CF, 0xC49C, 0x81D0, 0xC49D, 0x81D1, 0xC49E, 0x81D2, 0xC49F,
+	0x81D3, 0xC4A0, 0x81D4, 0xC540, 0x81D5, 0xC541, 0x81D6, 0xC542,
+	0x81D7, 0xC543, 0x81D8, 0xC544, 0x81D9, 0xC545, 0x81DA, 0xC546,
+	0x81DB, 0xC547, 0x81DC, 0xC548, 0x81DD, 0xC549, 0x81DE, 0xC54A,
+	0x81DF, 0xC54B, 0x81E0, 0xC54C, 0x81E1, 0xC54D, 0x81E2, 0xC54E,
+	0x81E3, 0xB3BC, 0x81E4, 0xC54F, 0x81E5, 0xC550, 0x81E6, 0xC551,
+	0x81E7, 0xEAB0, 0x81E8, 0xC552, 0x81E9, 0xC553, 0x81EA, 0xD7D4,
+	0x81EB, 0xC554, 0x81EC, 0xF4AB, 0x81ED, 0xB3F4, 0x81EE, 0xC555,
+	0x81EF, 0xC556, 0x81F0, 0xC557, 0x81F1, 0xC558, 0x81F2, 0xC559,
+	0x81F3, 0xD6C1, 0x81F4, 0xD6C2, 0x81F5, 0xC55A, 0x81F6, 0xC55B,
+	0x81F7, 0xC55C, 0x81F8, 0xC55D, 0x81F9, 0xC55E, 0x81FA, 0xC55F,
+	0x81FB, 0xD5E9, 0x81FC, 0xBECA, 0x81FD, 0xC560, 0x81FE, 0xF4A7,
+	0x81FF, 0xC561, 0x8200, 0xD2A8, 0x8201, 0xF4A8, 0x8202, 0xF4A9,
+	0x8203, 0xC562, 0x8204, 0xF4AA, 0x8205, 0xBECB, 0x8206, 0xD3DF,
+	0x8207, 0xC563, 0x8208, 0xC564, 0x8209, 0xC565, 0x820A, 0xC566,
+	0x820B, 0xC567, 0x820C, 0xC9E0, 0x820D, 0xC9E1, 0x820E, 0xC568,
+	0x820F, 0xC569, 0x8210, 0xF3C2, 0x8211, 0xC56A, 0x8212, 0xCAE6,
+	0x8213, 0xC56B, 0x8214, 0xCCF2, 0x8215, 0xC56C, 0x8216, 0xC56D,
+	0x8217, 0xC56E, 0x8218, 0xC56F, 0x8219, 0xC570, 0x821A, 0xC571,
+	0x821B, 0xE2B6, 0x821C, 0xCBB4, 0x821D, 0xC572, 0x821E, 0xCEE8,
+	0x821F, 0xD6DB, 0x8220, 0xC573, 0x8221, 0xF4AD, 0x8222, 0xF4AE,
+	0x8223, 0xF4AF, 0x8224, 0xC574, 0x8225, 0xC575, 0x8226, 0xC576,
+	0x8227, 0xC577, 0x8228, 0xF4B2, 0x8229, 0xC578, 0x822A, 0xBABD,
+	0x822B, 0xF4B3, 0x822C, 0xB0E3, 0x822D, 0xF4B0, 0x822E, 0xC579,
+	0x822F, 0xF4B1, 0x8230, 0xBDA2, 0x8231, 0xB2D5, 0x8232, 0xC57A,
+	0x8233, 0xF4B6, 0x8234, 0xF4B7, 0x8235, 0xB6E6, 0x8236, 0xB2B0,
+	0x8237, 0xCFCF, 0x8238, 0xF4B4, 0x8239, 0xB4AC, 0x823A, 0xC57B,
+	0x823B, 0xF4B5, 0x823C, 0xC57C, 0x823D, 0xC57D, 0x823E, 0xF4B8,
+	0x823F, 0xC57E, 0x8240, 0xC580, 0x8241, 0xC581, 0x8242, 0xC582,
+	0x8243, 0xC583, 0x8244, 0xF4B9, 0x8245, 0xC584, 0x8246, 0xC585,
+	0x8247, 0xCDA7, 0x8248, 0xC586, 0x8249, 0xF4BA, 0x824A, 0xC587,
+	0x824B, 0xF4BB, 0x824C, 0xC588, 0x824D, 0xC589, 0x824E, 0xC58A,
+	0x824F, 0xF4BC, 0x8250, 0xC58B, 0x8251, 0xC58C, 0x8252, 0xC58D,
+	0x8253, 0xC58E, 0x8254, 0xC58F, 0x8255, 0xC590, 0x8256, 0xC591,
+	0x8257, 0xC592, 0x8258, 0xCBD2, 0x8259, 0xC593, 0x825A, 0xF4BD,
+	0x825B, 0xC594, 0x825C, 0xC595, 0x825D, 0xC596, 0x825E, 0xC597,
+	0x825F, 0xF4BE, 0x8260, 0xC598, 0x8261, 0xC599, 0x8262, 0xC59A,
+	0x8263, 0xC59B, 0x8264, 0xC59C, 0x8265, 0xC59D, 0x8266, 0xC59E,
+	0x8267, 0xC59F, 0x8268, 0xF4BF, 0x8269, 0xC5A0, 0x826A, 0xC640,
+	0x826B, 0xC641, 0x826C, 0xC642, 0x826D, 0xC643, 0x826E, 0xF4DE,
+	0x826F, 0xC1BC, 0x8270, 0xBCE8, 0x8271, 0xC644, 0x8272, 0xC9AB,
+	0x8273, 0xD1DE, 0x8274, 0xE5F5, 0x8275, 0xC645, 0x8276, 0xC646,
+	0x8277, 0xC647, 0x8278, 0xC648, 0x8279, 0xDCB3, 0x827A, 0xD2D5,
+	0x827B, 0xC649, 0x827C, 0xC64A, 0x827D, 0xDCB4, 0x827E, 0xB0AC,
+	0x827F, 0xDCB5, 0x8280, 0xC64B, 0x8281, 0xC64C, 0x8282, 0xBDDA,
+	0x8283, 0xC64D, 0x8284, 0xDCB9, 0x8285, 0xC64E, 0x8286, 0xC64F,
+	0x8287, 0xC650, 0x8288, 0xD8C2, 0x8289, 0xC651, 0x828A, 0xDCB7,
+	0x828B, 0xD3F3, 0x828C, 0xC652, 0x828D, 0xC9D6, 0x828E, 0xDCBA,
+	0x828F, 0xDCB6, 0x8290, 0xC653, 0x8291, 0xDCBB, 0x8292, 0xC3A2,
+	0x8293, 0xC654, 0x8294, 0xC655, 0x8295, 0xC656, 0x8296, 0xC657,
+	0x8297, 0xDCBC, 0x8298, 0xDCC5, 0x8299, 0xDCBD, 0x829A, 0xC658,
+	0x829B, 0xC659, 0x829C, 0xCEDF, 0x829D, 0xD6A5, 0x829E, 0xC65A,
+	0x829F, 0xDCCF, 0x82A0, 0xC65B, 0x82A1, 0xDCCD, 0x82A2, 0xC65C,
+	0x82A3, 0xC65D, 0x82A4, 0xDCD2, 0x82A5, 0xBDE6, 0x82A6, 0xC2AB,
+	0x82A7, 0xC65E, 0x82A8, 0xDCB8, 0x82A9, 0xDCCB, 0x82AA, 0xDCCE,
+	0x82AB, 0xDCBE, 0x82AC, 0xB7D2, 0x82AD, 0xB0C5, 0x82AE, 0xDCC7,
+	0x82AF, 0xD0BE, 0x82B0, 0xDCC1, 0x82B1, 0xBBA8, 0x82B2, 0xC65F,
+	0x82B3, 0xB7BC, 0x82B4, 0xDCCC, 0x82B5, 0xC660, 0x82B6, 0xC661,
+	0x82B7, 0xDCC6, 0x82B8, 0xDCBF, 0x82B9, 0xC7DB, 0x82BA, 0xC662,
+	0x82BB, 0xC663, 0x82BC, 0xC664, 0x82BD, 0xD1BF, 0x82BE, 0xDCC0,
+	0x82BF, 0xC665, 0x82C0, 0xC666, 0x82C1, 0xDCCA, 0x82C2, 0xC667,
+	0x82C3, 0xC668, 0x82C4, 0xDCD0, 0x82C5, 0xC669, 0x82C6, 0xC66A,
+	0x82C7, 0xCEAD, 0x82C8, 0xDCC2, 0x82C9, 0xC66B, 0x82CA, 0xDCC3,
+	0x82CB, 0xDCC8, 0x82CC, 0xDCC9, 0x82CD, 0xB2D4, 0x82CE, 0xDCD1,
+	0x82CF, 0xCBD5, 0x82D0, 0xC66C, 0x82D1, 0xD4B7, 0x82D2, 0xDCDB,
+	0x82D3, 0xDCDF, 0x82D4, 0xCCA6, 0x82D5, 0xDCE6, 0x82D6, 0xC66D,
+	0x82D7, 0xC3E7, 0x82D8, 0xDCDC, 0x82D9, 0xC66E, 0x82DA, 0xC66F,
+	0x82DB, 0xBFC1, 0x82DC, 0xDCD9, 0x82DD, 0xC670, 0x82DE, 0xB0FA,
+	0x82DF, 0xB9B6, 0x82E0, 0xDCE5, 0x82E1, 0xDCD3, 0x82E2, 0xC671,
+	0x82E3, 0xDCC4, 0x82E4, 0xDCD6, 0x82E5, 0xC8F4, 0x82E6, 0xBFE0,
+	0x82E7, 0xC672, 0x82E8, 0xC673, 0x82E9, 0xC674, 0x82EA, 0xC675,
+	0x82EB, 0xC9BB, 0x82EC, 0xC676, 0x82ED, 0xC677, 0x82EE, 0xC678,
+	0x82EF, 0xB1BD, 0x82F0, 0xC679, 0x82F1, 0xD3A2, 0x82F2, 0xC67A,
+	0x82F3, 0xC67B, 0x82F4, 0xDCDA, 0x82F5, 0xC67C, 0x82F6, 0xC67D,
+	0x82F7, 0xDCD5, 0x82F8, 0xC67E, 0x82F9, 0xC6BB, 0x82FA, 0xC680,
+	0x82FB, 0xDCDE, 0x82FC, 0xC681, 0x82FD, 0xC682, 0x82FE, 0xC683,
+	0x82FF, 0xC684, 0x8300, 0xC685, 0x8301, 0xD7C2, 0x8302, 0xC3AF,
+	0x8303, 0xB7B6, 0x8304, 0xC7D1, 0x8305, 0xC3A9, 0x8306, 0xDCE2,
+	0x8307, 0xDCD8, 0x8308, 0xDCEB, 0x8309, 0xDCD4, 0x830A, 0xC686,
+	0x830B, 0xC687, 0x830C, 0xDCDD, 0x830D, 0xC688, 0x830E, 0xBEA5,
+	0x830F, 0xDCD7, 0x8310, 0xC689, 0x8311, 0xDCE0, 0x8312, 0xC68A,
+	0x8313, 0xC68B, 0x8314, 0xDCE3, 0x8315, 0xDCE4, 0x8316, 0xC68C,
+	0x8317, 0xDCF8, 0x8318, 0xC68D, 0x8319, 0xC68E, 0x831A, 0xDCE1,
+	0x831B, 0xDDA2, 0x831C, 0xDCE7, 0x831D, 0xC68F, 0x831E, 0xC690,
+	0x831F, 0xC691, 0x8320, 0xC692, 0x8321, 0xC693, 0x8322, 0xC694,
+	0x8323, 0xC695, 0x8324, 0xC696, 0x8325, 0xC697, 0x8326, 0xC698,
+	0x8327, 0xBCEB, 0x8328, 0xB4C4, 0x8329, 0xC699, 0x832A, 0xC69A,
+	0x832B, 0xC3A3, 0x832C, 0xB2E7, 0x832D, 0xDCFA, 0x832E, 0xC69B,
+	0x832F, 0xDCF2, 0x8330, 0xC69C, 0x8331, 0xDCEF, 0x8332, 0xC69D,
+	0x8333, 0xDCFC, 0x8334, 0xDCEE, 0x8335, 0xD2F0, 0x8336, 0xB2E8,
+	0x8337, 0xC69E, 0x8338, 0xC8D7, 0x8339, 0xC8E3, 0x833A, 0xDCFB,
+	0x833B, 0xC69F, 0x833C, 0xDCED, 0x833D, 0xC6A0, 0x833E, 0xC740,
+	0x833F, 0xC741, 0x8340, 0xDCF7, 0x8341, 0xC742, 0x8342, 0xC743,
+	0x8343, 0xDCF5, 0x8344, 0xC744, 0x8345, 0xC745, 0x8346, 0xBEA3,
+	0x8347, 0xDCF4, 0x8348, 0xC746, 0x8349, 0xB2DD, 0x834A, 0xC747,
+	0x834B, 0xC748, 0x834C, 0xC749, 0x834D, 0xC74A, 0x834E, 0xC74B,
+	0x834F, 0xDCF3, 0x8350, 0xBCF6, 0x8351, 0xDCE8, 0x8352, 0xBBC4,
+	0x8353, 0xC74C, 0x8354, 0xC0F3, 0x8355, 0xC74D, 0x8356, 0xC74E,
+	0x8357, 0xC74F, 0x8358, 0xC750, 0x8359, 0xC751, 0x835A, 0xBCD4,
+	0x835B, 0xDCE9, 0x835C, 0xDCEA, 0x835D, 0xC752, 0x835E, 0xDCF1,
+	0x835F, 0xDCF6, 0x8360, 0xDCF9, 0x8361, 0xB5B4, 0x8362, 0xC753,
+	0x8363, 0xC8D9, 0x8364, 0xBBE7, 0x8365, 0xDCFE, 0x8366, 0xDCFD,
+	0x8367, 0xD3AB, 0x8368, 0xDDA1, 0x8369, 0xDDA3, 0x836A, 0xDDA5,
+	0x836B, 0xD2F1, 0x836C, 0xDDA4, 0x836D, 0xDDA6, 0x836E, 0xDDA7,
+	0x836F, 0xD2A9, 0x8370, 0xC754, 0x8371, 0xC755, 0x8372, 0xC756,
+	0x8373, 0xC757, 0x8374, 0xC758, 0x8375, 0xC759, 0x8376, 0xC75A,
+	0x8377, 0xBAC9, 0x8378, 0xDDA9, 0x8379, 0xC75B, 0x837A, 0xC75C,
+	0x837B, 0xDDB6, 0x837C, 0xDDB1, 0x837D, 0xDDB4, 0x837E, 0xC75D,
+	0x837F, 0xC75E, 0x8380, 0xC75F, 0x8381, 0xC760, 0x8382, 0xC761,
+	0x8383, 0xC762, 0x8384, 0xC763, 0x8385, 0xDDB0, 0x8386, 0xC6CE,
+	0x8387, 0xC764, 0x8388, 0xC765, 0x8389, 0xC0F2, 0x838A, 0xC766,
+	0x838B, 0xC767, 0x838C, 0xC768, 0x838D, 0xC769, 0x838E, 0xC9AF,
+	0x838F, 0xC76A, 0x8390, 0xC76B, 0x8391, 0xC76C, 0x8392, 0xDCEC,
+	0x8393, 0xDDAE, 0x8394, 0xC76D, 0x8395, 0xC76E, 0x8396, 0xC76F,
+	0x8397, 0xC770, 0x8398, 0xDDB7, 0x8399, 0xC771, 0x839A, 0xC772,
+	0x839B, 0xDCF0, 0x839C, 0xDDAF, 0x839D, 0xC773, 0x839E, 0xDDB8,
+	0x839F, 0xC774, 0x83A0, 0xDDAC, 0x83A1, 0xC775, 0x83A2, 0xC776,
+	0x83A3, 0xC777, 0x83A4, 0xC778, 0x83A5, 0xC779, 0x83A6, 0xC77A,
+	0x83A7, 0xC77B, 0x83A8, 0xDDB9, 0x83A9, 0xDDB3, 0x83AA, 0xDDAD,
+	0x83AB, 0xC4AA, 0x83AC, 0xC77C, 0x83AD, 0xC77D, 0x83AE, 0xC77E,
+	0x83AF, 0xC780, 0x83B0, 0xDDA8, 0x83B1, 0xC0B3, 0x83B2, 0xC1AB,
+	0x83B3, 0xDDAA, 0x83B4, 0xDDAB, 0x83B5, 0xC781, 0x83B6, 0xDDB2,
+	0x83B7, 0xBBF1, 0x83B8, 0xDDB5, 0x83B9, 0xD3A8, 0x83BA, 0xDDBA,
+	0x83BB, 0xC782, 0x83BC, 0xDDBB, 0x83BD, 0xC3A7, 0x83BE, 0xC783,
+	0x83BF, 0xC784, 0x83C0, 0xDDD2, 0x83C1, 0xDDBC, 0x83C2, 0xC785,
+	0x83C3, 0xC786, 0x83C4, 0xC787, 0x83C5, 0xDDD1, 0x83C6, 0xC788,
+	0x83C7, 0xB9BD, 0x83C8, 0xC789, 0x83C9, 0xC78A, 0x83CA, 0xBED5,
+	0x83CB, 0xC78B, 0x83CC, 0xBEFA, 0x83CD, 0xC78C, 0x83CE, 0xC78D,
+	0x83CF, 0xBACA, 0x83D0, 0xC78E, 0x83D1, 0xC78F, 0x83D2, 0xC790,
+	0x83D3, 0xC791, 0x83D4, 0xDDCA, 0x83D5, 0xC792, 0x83D6, 0xDDC5,
+	0x83D7, 0xC793, 0x83D8, 0xDDBF, 0x83D9, 0xC794, 0x83DA, 0xC795,
+	0x83DB, 0xC796, 0x83DC, 0xB2CB, 0x83DD, 0xDDC3, 0x83DE, 0xC797,
+	0x83DF, 0xDDCB, 0x83E0, 0xB2A4, 0x83E1, 0xDDD5, 0x83E2, 0xC798,
+	0x83E3, 0xC799, 0x83E4, 0xC79A, 0x83E5, 0xDDBE, 0x83E6, 0xC79B,
+	0x83E7, 0xC79C, 0x83E8, 0xC79D, 0x83E9, 0xC6D0, 0x83EA, 0xDDD0,
+	0x83EB, 0xC79E, 0x83EC, 0xC79F, 0x83ED, 0xC7A0, 0x83EE, 0xC840,
+	0x83EF, 0xC841, 0x83F0, 0xDDD4, 0x83F1, 0xC1E2, 0x83F2, 0xB7C6,
+	0x83F3, 0xC842, 0x83F4, 0xC843, 0x83F5, 0xC844, 0x83F6, 0xC845,
+	0x83F7, 0xC846, 0x83F8, 0xDDCE, 0x83F9, 0xDDCF, 0x83FA, 0xC847,
+	0x83FB, 0xC848, 0x83FC, 0xC849, 0x83FD, 0xDDC4, 0x83FE, 0xC84A,
+	0x83FF, 0xC84B, 0x8400, 0xC84C, 0x8401, 0xDDBD, 0x8402, 0xC84D,
+	0x8403, 0xDDCD, 0x8404, 0xCCD1, 0x8405, 0xC84E, 0x8406, 0xDDC9,
+	0x8407, 0xC84F, 0x8408, 0xC850, 0x8409, 0xC851, 0x840A, 0xC852,
+	0x840B, 0xDDC2, 0x840C, 0xC3C8, 0x840D, 0xC6BC, 0x840E, 0xCEAE,
+	0x840F, 0xDDCC, 0x8410, 0xC853, 0x8411, 0xDDC8, 0x8412, 0xC854,
+	0x8413, 0xC855, 0x8414, 0xC856, 0x8415, 0xC857, 0x8416, 0xC858,
+	0x8417, 0xC859, 0x8418, 0xDDC1, 0x8419, 0xC85A, 0x841A, 0xC85B,
+	0x841B, 0xC85C, 0x841C, 0xDDC6, 0x841D, 0xC2DC, 0x841E, 0xC85D,
+	0x841F, 0xC85E, 0x8420, 0xC85F, 0x8421, 0xC860, 0x8422, 0xC861,
+	0x8423, 0xC862, 0x8424, 0xD3A9, 0x8425, 0xD3AA, 0x8426, 0xDDD3,
+	0x8427, 0xCFF4, 0x8428, 0xC8F8, 0x8429, 0xC863, 0x842A, 0xC864,
+	0x842B, 0xC865, 0x842C, 0xC866, 0x842D, 0xC867, 0x842E, 0xC868,
+	0x842F, 0xC869, 0x8430, 0xC86A, 0x8431, 0xDDE6, 0x8432, 0xC86B,
+	0x8433, 0xC86C, 0x8434, 0xC86D, 0x8435, 0xC86E, 0x8436, 0xC86F,
+	0x8437, 0xC870, 0x8438, 0xDDC7, 0x8439, 0xC871, 0x843A, 0xC872,
+	0x843B, 0xC873, 0x843C, 0xDDE0, 0x843D, 0xC2E4, 0x843E, 0xC874,
+	0x843F, 0xC875, 0x8440, 0xC876, 0x8441, 0xC877, 0x8442, 0xC878,
+	0x8443, 0xC879, 0x8444, 0xC87A, 0x8445, 0xC87B, 0x8446, 0xDDE1,
+	0x8447, 0xC87C, 0x8448, 0xC87D, 0x8449, 0xC87E, 0x844A, 0xC880,
+	0x844B, 0xC881, 0x844C, 0xC882, 0x844D, 0xC883, 0x844E, 0xC884,
+	0x844F, 0xC885, 0x8450, 0xC886, 0x8451, 0xDDD7, 0x8452, 0xC887,
+	0x8453, 0xC888, 0x8454, 0xC889, 0x8455, 0xC88A, 0x8456, 0xC88B,
+	0x8457, 0xD6F8, 0x8458, 0xC88C, 0x8459, 0xDDD9, 0x845A, 0xDDD8,
+	0x845B, 0xB8F0, 0x845C, 0xDDD6, 0x845D, 0xC88D, 0x845E, 0xC88E,
+	0x845F, 0xC88F, 0x8460, 0xC890, 0x8461, 0xC6CF, 0x8462, 0xC891,
+	0x8463, 0xB6AD, 0x8464, 0xC892, 0x8465, 0xC893, 0x8466, 0xC894,
+	0x8467, 0xC895, 0x8468, 0xC896, 0x8469, 0xDDE2, 0x846A, 0xC897,
+	0x846B, 0xBAF9, 0x846C, 0xD4E1, 0x846D, 0xDDE7, 0x846E, 0xC898,
+	0x846F, 0xC899, 0x8470, 0xC89A, 0x8471, 0xB4D0, 0x8472, 0xC89B,
+	0x8473, 0xDDDA, 0x8474, 0xC89C, 0x8475, 0xBFFB, 0x8476, 0xDDE3,
+	0x8477, 0xC89D, 0x8478, 0xDDDF, 0x8479, 0xC89E, 0x847A, 0xDDDD,
+	0x847B, 0xC89F, 0x847C, 0xC8A0, 0x847D, 0xC940, 0x847E, 0xC941,
+	0x847F, 0xC942, 0x8480, 0xC943, 0x8481, 0xC944, 0x8482, 0xB5D9,
+	0x8483, 0xC945, 0x8484, 0xC946, 0x8485, 0xC947, 0x8486, 0xC948,
+	0x8487, 0xDDDB, 0x8488, 0xDDDC, 0x8489, 0xDDDE, 0x848A, 0xC949,
+	0x848B, 0xBDAF, 0x848C, 0xDDE4, 0x848D, 0xC94A, 0x848E, 0xDDE5,
+	0x848F, 0xC94B, 0x8490, 0xC94C, 0x8491, 0xC94D, 0x8492, 0xC94E,
+	0x8493, 0xC94F, 0x8494, 0xC950, 0x8495, 0xC951, 0x8496, 0xC952,
+	0x8497, 0xDDF5, 0x8498, 0xC953, 0x8499, 0xC3C9, 0x849A, 0xC954,
+	0x849B, 0xC955, 0x849C, 0xCBE2, 0x849D, 0xC956, 0x849E, 0xC957,
+	0x849F, 0xC958, 0x84A0, 0xC959, 0x84A1, 0xDDF2, 0x84A2, 0xC95A,
+	0x84A3, 0xC95B, 0x84A4, 0xC95C, 0x84A5, 0xC95D, 0x84A6, 0xC95E,
+	0x84A7, 0xC95F, 0x84A8, 0xC960, 0x84A9, 0xC961, 0x84AA, 0xC962,
+	0x84AB, 0xC963, 0x84AC, 0xC964, 0x84AD, 0xC965, 0x84AE, 0xC966,
+	0x84AF, 0xD8E1, 0x84B0, 0xC967, 0x84B1, 0xC968, 0x84B2, 0xC6D1,
+	0x84B3, 0xC969, 0x84B4, 0xDDF4, 0x84B5, 0xC96A, 0x84B6, 0xC96B,
+	0x84B7, 0xC96C, 0x84B8, 0xD5F4, 0x84B9, 0xDDF3, 0x84BA, 0xDDF0,
+	0x84BB, 0xC96D, 0x84BC, 0xC96E, 0x84BD, 0xDDEC, 0x84BE, 0xC96F,
+	0x84BF, 0xDDEF, 0x84C0, 0xC970, 0x84C1, 0xDDE8, 0x84C2, 0xC971,
+	0x84C3, 0xC972, 0x84C4, 0xD0EE, 0x84C5, 0xC973, 0x84C6, 0xC974,
+	0x84C7, 0xC975, 0x84C8, 0xC976, 0x84C9, 0xC8D8, 0x84CA, 0xDDEE,
+	0x84CB, 0xC977, 0x84CC, 0xC978, 0x84CD, 0xDDE9, 0x84CE, 0xC979,
+	0x84CF, 0xC97A, 0x84D0, 0xDDEA, 0x84D1, 0xCBF2, 0x84D2, 0xC97B,
+	0x84D3, 0xDDED, 0x84D4, 0xC97C, 0x84D5, 0xC97D, 0x84D6, 0xB1CD,
+	0x84D7, 0xC97E, 0x84D8, 0xC980, 0x84D9, 0xC981, 0x84DA, 0xC982,
+	0x84DB, 0xC983, 0x84DC, 0xC984, 0x84DD, 0xC0B6, 0x84DE, 0xC985,
+	0x84DF, 0xBCBB, 0x84E0, 0xDDF1, 0x84E1, 0xC986, 0x84E2, 0xC987,
+	0x84E3, 0xDDF7, 0x84E4, 0xC988, 0x84E5, 0xDDF6, 0x84E6, 0xDDEB,
+	0x84E7, 0xC989, 0x84E8, 0xC98A, 0x84E9, 0xC98B, 0x84EA, 0xC98C,
+	0x84EB, 0xC98D, 0x84EC, 0xC5EE, 0x84ED, 0xC98E, 0x84EE, 0xC98F,
+	0x84EF, 0xC990, 0x84F0, 0xDDFB, 0x84F1, 0xC991, 0x84F2, 0xC992,
+	0x84F3, 0xC993, 0x84F4, 0xC994, 0x84F5, 0xC995, 0x84F6, 0xC996,
+	0x84F7, 0xC997, 0x84F8, 0xC998, 0x84F9, 0xC999, 0x84FA, 0xC99A,
+	0x84FB, 0xC99B, 0x84FC, 0xDEA4, 0x84FD, 0xC99C, 0x84FE, 0xC99D,
+	0x84FF, 0xDEA3, 0x8500, 0xC99E, 0x8501, 0xC99F, 0x8502, 0xC9A0,
+	0x8503, 0xCA40, 0x8504, 0xCA41, 0x8505, 0xCA42, 0x8506, 0xCA43,
+	0x8507, 0xCA44, 0x8508, 0xCA45, 0x8509, 0xCA46, 0x850A, 0xCA47,
+	0x850B, 0xCA48, 0x850C, 0xDDF8, 0x850D, 0xCA49, 0x850E, 0xCA4A,
+	0x850F, 0xCA4B, 0x8510, 0xCA4C, 0x8511, 0xC3EF, 0x8512, 0xCA4D,
+	0x8513, 0xC2FB, 0x8514, 0xCA4E, 0x8515, 0xCA4F, 0x8516, 0xCA50,
+	0x8517, 0xD5E1, 0x8518, 0xCA51, 0x8519, 0xCA52, 0x851A, 0xCEB5,
+	0x851B, 0xCA53, 0x851C, 0xCA54, 0x851D, 0xCA55, 0x851E, 0xCA56,
+	0x851F, 0xDDFD, 0x8520, 0xCA57, 0x8521, 0xB2CC, 0x8522, 0xCA58,
+	0x8523, 0xCA59, 0x8524, 0xCA5A, 0x8525, 0xCA5B, 0x8526, 0xCA5C,
+	0x8527, 0xCA5D, 0x8528, 0xCA5E, 0x8529, 0xCA5F, 0x852A, 0xCA60,
+	0x852B, 0xC4E8, 0x852C, 0xCADF, 0x852D, 0xCA61, 0x852E, 0xCA62,
+	0x852F, 0xCA63, 0x8530, 0xCA64, 0x8531, 0xCA65, 0x8532, 0xCA66,
+	0x8533, 0xCA67, 0x8534, 0xCA68, 0x8535, 0xCA69, 0x8536, 0xCA6A,
+	0x8537, 0xC7BE, 0x8538, 0xDDFA, 0x8539, 0xDDFC, 0x853A, 0xDDFE,
+	0x853B, 0xDEA2, 0x853C, 0xB0AA, 0x853D, 0xB1CE, 0x853E, 0xCA6B,
+	0x853F, 0xCA6C, 0x8540, 0xCA6D, 0x8541, 0xCA6E, 0x8542, 0xCA6F,
+	0x8543, 0xDEAC, 0x8544, 0xCA70, 0x8545, 0xCA71, 0x8546, 0xCA72,
+	0x8547, 0xCA73, 0x8548, 0xDEA6, 0x8549, 0xBDB6, 0x854A, 0xC8EF,
+	0x854B, 0xCA74, 0x854C, 0xCA75, 0x854D, 0xCA76, 0x854E, 0xCA77,
+	0x854F, 0xCA78, 0x8550, 0xCA79, 0x8551, 0xCA7A, 0x8552, 0xCA7B,
+	0x8553, 0xCA7C, 0x8554, 0xCA7D, 0x8555, 0xCA7E, 0x8556, 0xDEA1,
+	0x8557, 0xCA80, 0x8558, 0xCA81, 0x8559, 0xDEA5, 0x855A, 0xCA82,
+	0x855B, 0xCA83, 0x855C, 0xCA84, 0x855D, 0xCA85, 0x855E, 0xDEA9,
+	0x855F, 0xCA86, 0x8560, 0xCA87, 0x8561, 0xCA88, 0x8562, 0xCA89,
+	0x8563, 0xCA8A, 0x8564, 0xDEA8, 0x8565, 0xCA8B, 0x8566, 0xCA8C,
+	0x8567, 0xCA8D, 0x8568, 0xDEA7, 0x8569, 0xCA8E, 0x856A, 0xCA8F,
+	0x856B, 0xCA90, 0x856C, 0xCA91, 0x856D, 0xCA92, 0x856E, 0xCA93,
+	0x856F, 0xCA94, 0x8570, 0xCA95, 0x8571, 0xCA96, 0x8572, 0xDEAD,
+	0x8573, 0xCA97, 0x8574, 0xD4CC, 0x8575, 0xCA98, 0x8576, 0xCA99,
+	0x8577, 0xCA9A, 0x8578, 0xCA9B, 0x8579, 0xDEB3, 0x857A, 0xDEAA,
+	0x857B, 0xDEAE, 0x857C, 0xCA9C, 0x857D, 0xCA9D, 0x857E, 0xC0D9,
+	0x857F, 0xCA9E, 0x8580, 0xCA9F, 0x8581, 0xCAA0, 0x8582, 0xCB40,
+	0x8583, 0xCB41, 0x8584, 0xB1A1, 0x8585, 0xDEB6, 0x8586, 0xCB42,
+	0x8587, 0xDEB1, 0x8588, 0xCB43, 0x8589, 0xCB44, 0x858A, 0xCB45,
+	0x858B, 0xCB46, 0x858C, 0xCB47, 0x858D, 0xCB48, 0x858E, 0xCB49,
+	0x858F, 0xDEB2, 0x8590, 0xCB4A, 0x8591, 0xCB4B, 0x8592, 0xCB4C,
+	0x8593, 0xCB4D, 0x8594, 0xCB4E, 0x8595, 0xCB4F, 0x8596, 0xCB50,
+	0x8597, 0xCB51, 0x8598, 0xCB52, 0x8599, 0xCB53, 0x859A, 0xCB54,
+	0x859B, 0xD1A6, 0x859C, 0xDEB5, 0x859D, 0xCB55, 0x859E, 0xCB56,
+	0x859F, 0xCB57, 0x85A0, 0xCB58, 0x85A1, 0xCB59, 0x85A2, 0xCB5A,
+	0x85A3, 0xCB5B, 0x85A4, 0xDEAF, 0x85A5, 0xCB5C, 0x85A6, 0xCB5D,
+	0x85A7, 0xCB5E, 0x85A8, 0xDEB0, 0x85A9, 0xCB5F, 0x85AA, 0xD0BD,
+	0x85AB, 0xCB60, 0x85AC, 0xCB61, 0x85AD, 0xCB62, 0x85AE, 0xDEB4,
+	0x85AF, 0xCAED, 0x85B0, 0xDEB9, 0x85B1, 0xCB63, 0x85B2, 0xCB64,
+	0x85B3, 0xCB65, 0x85B4, 0xCB66, 0x85B5, 0xCB67, 0x85B6, 0xCB68,
+	0x85B7, 0xDEB8, 0x85B8, 0xCB69, 0x85B9, 0xDEB7, 0x85BA, 0xCB6A,
+	0x85BB, 0xCB6B, 0x85BC, 0xCB6C, 0x85BD, 0xCB6D, 0x85BE, 0xCB6E,
+	0x85BF, 0xCB6F, 0x85C0, 0xCB70, 0x85C1, 0xDEBB, 0x85C2, 0xCB71,
+	0x85C3, 0xCB72, 0x85C4, 0xCB73, 0x85C5, 0xCB74, 0x85C6, 0xCB75,
+	0x85C7, 0xCB76, 0x85C8, 0xCB77, 0x85C9, 0xBDE5, 0x85CA, 0xCB78,
+	0x85CB, 0xCB79, 0x85CC, 0xCB7A, 0x85CD, 0xCB7B, 0x85CE, 0xCB7C,
+	0x85CF, 0xB2D8, 0x85D0, 0xC3EA, 0x85D1, 0xCB7D, 0x85D2, 0xCB7E,
+	0x85D3, 0xDEBA, 0x85D4, 0xCB80, 0x85D5, 0xC5BA, 0x85D6, 0xCB81,
+	0x85D7, 0xCB82, 0x85D8, 0xCB83, 0x85D9, 0xCB84, 0x85DA, 0xCB85,
+	0x85DB, 0xCB86, 0x85DC, 0xDEBC, 0x85DD, 0xCB87, 0x85DE, 0xCB88,
+	0x85DF, 0xCB89, 0x85E0, 0xCB8A, 0x85E1, 0xCB8B, 0x85E2, 0xCB8C,
+	0x85E3, 0xCB8D, 0x85E4, 0xCCD9, 0x85E5, 0xCB8E, 0x85E6, 0xCB8F,
+	0x85E7, 0xCB90, 0x85E8, 0xCB91, 0x85E9, 0xB7AA, 0x85EA, 0xCB92,
+	0x85EB, 0xCB93, 0x85EC, 0xCB94, 0x85ED, 0xCB95, 0x85EE, 0xCB96,
+	0x85EF, 0xCB97, 0x85F0, 0xCB98, 0x85F1, 0xCB99, 0x85F2, 0xCB9A,
+	0x85F3, 0xCB9B, 0x85F4, 0xCB9C, 0x85F5, 0xCB9D, 0x85F6, 0xCB9E,
+	0x85F7, 0xCB9F, 0x85F8, 0xCBA0, 0x85F9, 0xCC40, 0x85FA, 0xCC41,
+	0x85FB, 0xD4E5, 0x85FC, 0xCC42, 0x85FD, 0xCC43, 0x85FE, 0xCC44,
+	0x85FF, 0xDEBD, 0x8600, 0xCC45, 0x8601, 0xCC46, 0x8602, 0xCC47,
+	0x8603, 0xCC48, 0x8604, 0xCC49, 0x8605, 0xDEBF, 0x8606, 0xCC4A,
+	0x8607, 0xCC4B, 0x8608, 0xCC4C, 0x8609, 0xCC4D, 0x860A, 0xCC4E,
+	0x860B, 0xCC4F, 0x860C, 0xCC50, 0x860D, 0xCC51, 0x860E, 0xCC52,
+	0x860F, 0xCC53, 0x8610, 0xCC54, 0x8611, 0xC4A2, 0x8612, 0xCC55,
+	0x8613, 0xCC56, 0x8614, 0xCC57, 0x8615, 0xCC58, 0x8616, 0xDEC1,
+	0x8617, 0xCC59, 0x8618, 0xCC5A, 0x8619, 0xCC5B, 0x861A, 0xCC5C,
+	0x861B, 0xCC5D, 0x861C, 0xCC5E, 0x861D, 0xCC5F, 0x861E, 0xCC60,
+	0x861F, 0xCC61, 0x8620, 0xCC62, 0x8621, 0xCC63, 0x8622, 0xCC64,
+	0x8623, 0xCC65, 0x8624, 0xCC66, 0x8625, 0xCC67, 0x8626, 0xCC68,
+	0x8627, 0xDEBE, 0x8628, 0xCC69, 0x8629, 0xDEC0, 0x862A, 0xCC6A,
+	0x862B, 0xCC6B, 0x862C, 0xCC6C, 0x862D, 0xCC6D, 0x862E, 0xCC6E,
+	0x862F, 0xCC6F, 0x8630, 0xCC70, 0x8631, 0xCC71, 0x8632, 0xCC72,
+	0x8633, 0xCC73, 0x8634, 0xCC74, 0x8635, 0xCC75, 0x8636, 0xCC76,
+	0x8637, 0xCC77, 0x8638, 0xD5BA, 0x8639, 0xCC78, 0x863A, 0xCC79,
+	0x863B, 0xCC7A, 0x863C, 0xDEC2, 0x863D, 0xCC7B, 0x863E, 0xCC7C,
+	0x863F, 0xCC7D, 0x8640, 0xCC7E, 0x8641, 0xCC80, 0x8642, 0xCC81,
+	0x8643, 0xCC82, 0x8644, 0xCC83, 0x8645, 0xCC84, 0x8646, 0xCC85,
+	0x8647, 0xCC86, 0x8648, 0xCC87, 0x8649, 0xCC88, 0x864A, 0xCC89,
+	0x864B, 0xCC8A, 0x864C, 0xCC8B, 0x864D, 0xF2AE, 0x864E, 0xBBA2,
+	0x864F, 0xC2B2, 0x8650, 0xC5B0, 0x8651, 0xC2C7, 0x8652, 0xCC8C,
+	0x8653, 0xCC8D, 0x8654, 0xF2AF, 0x8655, 0xCC8E, 0x8656, 0xCC8F,
+	0x8657, 0xCC90, 0x8658, 0xCC91, 0x8659, 0xCC92, 0x865A, 0xD0E9,
+	0x865B, 0xCC93, 0x865C, 0xCC94, 0x865D, 0xCC95, 0x865E, 0xD3DD,
+	0x865F, 0xCC96, 0x8660, 0xCC97, 0x8661, 0xCC98, 0x8662, 0xEBBD,
+	0x8663, 0xCC99, 0x8664, 0xCC9A, 0x8665, 0xCC9B, 0x8666, 0xCC9C,
+	0x8667, 0xCC9D, 0x8668, 0xCC9E, 0x8669, 0xCC9F, 0x866A, 0xCCA0,
+	0x866B, 0xB3E6, 0x866C, 0xF2B0, 0x866D, 0xCD40, 0x866E, 0xF2B1,
+	0x866F, 0xCD41, 0x8670, 0xCD42, 0x8671, 0xCAAD, 0x8672, 0xCD43,
+	0x8673, 0xCD44, 0x8674, 0xCD45, 0x8675, 0xCD46, 0x8676, 0xCD47,
+	0x8677, 0xCD48, 0x8678, 0xCD49, 0x8679, 0xBAE7, 0x867A, 0xF2B3,
+	0x867B, 0xF2B5, 0x867C, 0xF2B4, 0x867D, 0xCBE4, 0x867E, 0xCFBA,
+	0x867F, 0xF2B2, 0x8680, 0xCAB4, 0x8681, 0xD2CF, 0x8682, 0xC2EC,
+	0x8683, 0xCD4A, 0x8684, 0xCD4B, 0x8685, 0xCD4C, 0x8686, 0xCD4D,
+	0x8687, 0xCD4E, 0x8688, 0xCD4F, 0x8689, 0xCD50, 0x868A, 0xCEC3,
+	0x868B, 0xF2B8, 0x868C, 0xB0F6, 0x868D, 0xF2B7, 0x868E, 0xCD51,
+	0x868F, 0xCD52, 0x8690, 0xCD53, 0x8691, 0xCD54, 0x8692, 0xCD55,
+	0x8693, 0xF2BE, 0x8694, 0xCD56, 0x8695, 0xB2CF, 0x8696, 0xCD57,
+	0x8697, 0xCD58, 0x8698, 0xCD59, 0x8699, 0xCD5A, 0x869A, 0xCD5B,
+	0x869B, 0xCD5C, 0x869C, 0xD1C1, 0x869D, 0xF2BA, 0x869E, 0xCD5D,
+	0x869F, 0xCD5E, 0x86A0, 0xCD5F, 0x86A1, 0xCD60, 0x86A2, 0xCD61,
+	0x86A3, 0xF2BC, 0x86A4, 0xD4E9, 0x86A5, 0xCD62, 0x86A6, 0xCD63,
+	0x86A7, 0xF2BB, 0x86A8, 0xF2B6, 0x86A9, 0xF2BF, 0x86AA, 0xF2BD,
+	0x86AB, 0xCD64, 0x86AC, 0xF2B9, 0x86AD, 0xCD65, 0x86AE, 0xCD66,
+	0x86AF, 0xF2C7, 0x86B0, 0xF2C4, 0x86B1, 0xF2C6, 0x86B2, 0xCD67,
+	0x86B3, 0xCD68, 0x86B4, 0xF2CA, 0x86B5, 0xF2C2, 0x86B6, 0xF2C0,
+	0x86B7, 0xCD69, 0x86B8, 0xCD6A, 0x86B9, 0xCD6B, 0x86BA, 0xF2C5,
+	0x86BB, 0xCD6C, 0x86BC, 0xCD6D, 0x86BD, 0xCD6E, 0x86BE, 0xCD6F,
+	0x86BF, 0xCD70, 0x86C0, 0xD6FB, 0x86C1, 0xCD71, 0x86C2, 0xCD72,
+	0x86C3, 0xCD73, 0x86C4, 0xF2C1, 0x86C5, 0xCD74, 0x86C6, 0xC7F9,
+	0x86C7, 0xC9DF, 0x86C8, 0xCD75, 0x86C9, 0xF2C8, 0x86CA, 0xB9C6,
+	0x86CB, 0xB5B0, 0x86CC, 0xCD76, 0x86CD, 0xCD77, 0x86CE, 0xF2C3,
+	0x86CF, 0xF2C9, 0x86D0, 0xF2D0, 0x86D1, 0xF2D6, 0x86D2, 0xCD78,
+	0x86D3, 0xCD79, 0x86D4, 0xBBD7, 0x86D5, 0xCD7A, 0x86D6, 0xCD7B,
+	0x86D7, 0xCD7C, 0x86D8, 0xF2D5, 0x86D9, 0xCDDC, 0x86DA, 0xCD7D,
+	0x86DB, 0xD6EB, 0x86DC, 0xCD7E, 0x86DD, 0xCD80, 0x86DE, 0xF2D2,
+	0x86DF, 0xF2D4, 0x86E0, 0xCD81, 0x86E1, 0xCD82, 0x86E2, 0xCD83,
+	0x86E3, 0xCD84, 0x86E4, 0xB8F2, 0x86E5, 0xCD85, 0x86E6, 0xCD86,
+	0x86E7, 0xCD87, 0x86E8, 0xCD88, 0x86E9, 0xF2CB, 0x86EA, 0xCD89,
+	0x86EB, 0xCD8A, 0x86EC, 0xCD8B, 0x86ED, 0xF2CE, 0x86EE, 0xC2F9,
+	0x86EF, 0xCD8C, 0x86F0, 0xD5DD, 0x86F1, 0xF2CC, 0x86F2, 0xF2CD,
+	0x86F3, 0xF2CF, 0x86F4, 0xF2D3, 0x86F5, 0xCD8D, 0x86F6, 0xCD8E,
+	0x86F7, 0xCD8F, 0x86F8, 0xF2D9, 0x86F9, 0xD3BC, 0x86FA, 0xCD90,
+	0x86FB, 0xCD91, 0x86FC, 0xCD92, 0x86FD, 0xCD93, 0x86FE, 0xB6EA,
+	0x86FF, 0xCD94, 0x8700, 0xCAF1, 0x8701, 0xCD95, 0x8702, 0xB7E4,
+	0x8703, 0xF2D7, 0x8704, 0xCD96, 0x8705, 0xCD97, 0x8706, 0xCD98,
+	0x8707, 0xF2D8, 0x8708, 0xF2DA, 0x8709, 0xF2DD, 0x870A, 0xF2DB,
+	0x870B, 0xCD99, 0x870C, 0xCD9A, 0x870D, 0xF2DC, 0x870E, 0xCD9B,
+	0x870F, 0xCD9C, 0x8710, 0xCD9D, 0x8711, 0xCD9E, 0x8712, 0xD1D1,
+	0x8713, 0xF2D1, 0x8714, 0xCD9F, 0x8715, 0xCDC9, 0x8716, 0xCDA0,
+	0x8717, 0xCECF, 0x8718, 0xD6A9, 0x8719, 0xCE40, 0x871A, 0xF2E3,
+	0x871B, 0xCE41, 0x871C, 0xC3DB, 0x871D, 0xCE42, 0x871E, 0xF2E0,
+	0x871F, 0xCE43, 0x8720, 0xCE44, 0x8721, 0xC0AF, 0x8722, 0xF2EC,
+	0x8723, 0xF2DE, 0x8724, 0xCE45, 0x8725, 0xF2E1, 0x8726, 0xCE46,
+	0x8727, 0xCE47, 0x8728, 0xCE48, 0x8729, 0xF2E8, 0x872A, 0xCE49,
+	0x872B, 0xCE4A, 0x872C, 0xCE4B, 0x872D, 0xCE4C, 0x872E, 0xF2E2,
+	0x872F, 0xCE4D, 0x8730, 0xCE4E, 0x8731, 0xF2E7, 0x8732, 0xCE4F,
+	0x8733, 0xCE50, 0x8734, 0xF2E6, 0x8735, 0xCE51, 0x8736, 0xCE52,
+	0x8737, 0xF2E9, 0x8738, 0xCE53, 0x8739, 0xCE54, 0x873A, 0xCE55,
+	0x873B, 0xF2DF, 0x873C, 0xCE56, 0x873D, 0xCE57, 0x873E, 0xF2E4,
+	0x873F, 0xF2EA, 0x8740, 0xCE58, 0x8741, 0xCE59, 0x8742, 0xCE5A,
+	0x8743, 0xCE5B, 0x8744, 0xCE5C, 0x8745, 0xCE5D, 0x8746, 0xCE5E,
+	0x8747, 0xD3AC, 0x8748, 0xF2E5, 0x8749, 0xB2F5, 0x874A, 0xCE5F,
+	0x874B, 0xCE60, 0x874C, 0xF2F2, 0x874D, 0xCE61, 0x874E, 0xD0AB,
+	0x874F, 0xCE62, 0x8750, 0xCE63, 0x8751, 0xCE64, 0x8752, 0xCE65,
+	0x8753, 0xF2F5, 0x8754, 0xCE66, 0x8755, 0xCE67, 0x8756, 0xCE68,
+	0x8757, 0xBBC8, 0x8758, 0xCE69, 0x8759, 0xF2F9, 0x875A, 0xCE6A,
+	0x875B, 0xCE6B, 0x875C, 0xCE6C, 0x875D, 0xCE6D, 0x875E, 0xCE6E,
+	0x875F, 0xCE6F, 0x8760, 0xF2F0, 0x8761, 0xCE70, 0x8762, 0xCE71,
+	0x8763, 0xF2F6, 0x8764, 0xF2F8, 0x8765, 0xF2FA, 0x8766, 0xCE72,
+	0x8767, 0xCE73, 0x8768, 0xCE74, 0x8769, 0xCE75, 0x876A, 0xCE76,
+	0x876B, 0xCE77, 0x876C, 0xCE78, 0x876D, 0xCE79, 0x876E, 0xF2F3,
+	0x876F, 0xCE7A, 0x8770, 0xF2F1, 0x8771, 0xCE7B, 0x8772, 0xCE7C,
+	0x8773, 0xCE7D, 0x8774, 0xBAFB, 0x8775, 0xCE7E, 0x8776, 0xB5FB,
+	0x8777, 0xCE80, 0x8778, 0xCE81, 0x8779, 0xCE82, 0x877A, 0xCE83,
+	0x877B, 0xF2EF, 0x877C, 0xF2F7, 0x877D, 0xF2ED, 0x877E, 0xF2EE,
+	0x877F, 0xCE84, 0x8780, 0xCE85, 0x8781, 0xCE86, 0x8782, 0xF2EB,
+	0x8783, 0xF3A6, 0x8784, 0xCE87, 0x8785, 0xF3A3, 0x8786, 0xCE88,
+	0x8787, 0xCE89, 0x8788, 0xF3A2, 0x8789, 0xCE8A, 0x878A, 0xCE8B,
+	0x878B, 0xF2F4, 0x878C, 0xCE8C, 0x878D, 0xC8DA, 0x878E, 0xCE8D,
+	0x878F, 0xCE8E, 0x8790, 0xCE8F, 0x8791, 0xCE90, 0x8792, 0xCE91,
+	0x8793, 0xF2FB, 0x8794, 0xCE92, 0x8795, 0xCE93, 0x8796, 0xCE94,
+	0x8797, 0xF3A5, 0x8798, 0xCE95, 0x8799, 0xCE96, 0x879A, 0xCE97,
+	0x879B, 0xCE98, 0x879C, 0xCE99, 0x879D, 0xCE9A, 0x879E, 0xCE9B,
+	0x879F, 0xC3F8, 0x87A0, 0xCE9C, 0x87A1, 0xCE9D, 0x87A2, 0xCE9E,
+	0x87A3, 0xCE9F, 0x87A4, 0xCEA0, 0x87A5, 0xCF40, 0x87A6, 0xCF41,
+	0x87A7, 0xCF42, 0x87A8, 0xF2FD, 0x87A9, 0xCF43, 0x87AA, 0xCF44,
+	0x87AB, 0xF3A7, 0x87AC, 0xF3A9, 0x87AD, 0xF3A4, 0x87AE, 0xCF45,
+	0x87AF, 0xF2FC, 0x87B0, 0xCF46, 0x87B1, 0xCF47, 0x87B2, 0xCF48,
+	0x87B3, 0xF3AB, 0x87B4, 0xCF49, 0x87B5, 0xF3AA, 0x87B6, 0xCF4A,
+	0x87B7, 0xCF4B, 0x87B8, 0xCF4C, 0x87B9, 0xCF4D, 0x87BA, 0xC2DD,
+	0x87BB, 0xCF4E, 0x87BC, 0xCF4F, 0x87BD, 0xF3AE, 0x87BE, 0xCF50,
+	0x87BF, 0xCF51, 0x87C0, 0xF3B0, 0x87C1, 0xCF52, 0x87C2, 0xCF53,
+	0x87C3, 0xCF54, 0x87C4, 0xCF55, 0x87C5, 0xCF56, 0x87C6, 0xF3A1,
+	0x87C7, 0xCF57, 0x87C8, 0xCF58, 0x87C9, 0xCF59, 0x87CA, 0xF3B1,
+	0x87CB, 0xF3AC, 0x87CC, 0xCF5A, 0x87CD, 0xCF5B, 0x87CE, 0xCF5C,
+	0x87CF, 0xCF5D, 0x87D0, 0xCF5E, 0x87D1, 0xF3AF, 0x87D2, 0xF2FE,
+	0x87D3, 0xF3AD, 0x87D4, 0xCF5F, 0x87D5, 0xCF60, 0x87D6, 0xCF61,
+	0x87D7, 0xCF62, 0x87D8, 0xCF63, 0x87D9, 0xCF64, 0x87DA, 0xCF65,
+	0x87DB, 0xF3B2, 0x87DC, 0xCF66, 0x87DD, 0xCF67, 0x87DE, 0xCF68,
+	0x87DF, 0xCF69, 0x87E0, 0xF3B4, 0x87E1, 0xCF6A, 0x87E2, 0xCF6B,
+	0x87E3, 0xCF6C, 0x87E4, 0xCF6D, 0x87E5, 0xF3A8, 0x87E6, 0xCF6E,
+	0x87E7, 0xCF6F, 0x87E8, 0xCF70, 0x87E9, 0xCF71, 0x87EA, 0xF3B3,
+	0x87EB, 0xCF72, 0x87EC, 0xCF73, 0x87ED, 0xCF74, 0x87EE, 0xF3B5,
+	0x87EF, 0xCF75, 0x87F0, 0xCF76, 0x87F1, 0xCF77, 0x87F2, 0xCF78,
+	0x87F3, 0xCF79, 0x87F4, 0xCF7A, 0x87F5, 0xCF7B, 0x87F6, 0xCF7C,
+	0x87F7, 0xCF7D, 0x87F8, 0xCF7E, 0x87F9, 0xD0B7, 0x87FA, 0xCF80,
+	0x87FB, 0xCF81, 0x87FC, 0xCF82, 0x87FD, 0xCF83, 0x87FE, 0xF3B8,
+	0x87FF, 0xCF84, 0x8800, 0xCF85, 0x8801, 0xCF86, 0x8802, 0xCF87,
+	0x8803, 0xD9F9, 0x8804, 0xCF88, 0x8805, 0xCF89, 0x8806, 0xCF8A,
+	0x8807, 0xCF8B, 0x8808, 0xCF8C, 0x8809, 0xCF8D, 0x880A, 0xF3B9,
+	0x880B, 0xCF8E, 0x880C, 0xCF8F, 0x880D, 0xCF90, 0x880E, 0xCF91,
+	0x880F, 0xCF92, 0x8810, 0xCF93, 0x8811, 0xCF94, 0x8812, 0xCF95,
+	0x8813, 0xF3B7, 0x8814, 0xCF96, 0x8815, 0xC8E4, 0x8816, 0xF3B6,
+	0x8817, 0xCF97, 0x8818, 0xCF98, 0x8819, 0xCF99, 0x881A, 0xCF9A,
+	0x881B, 0xF3BA, 0x881C, 0xCF9B, 0x881D, 0xCF9C, 0x881E, 0xCF9D,
+	0x881F, 0xCF9E, 0x8820, 0xCF9F, 0x8821, 0xF3BB, 0x8822, 0xB4C0,
+	0x8823, 0xCFA0, 0x8824, 0xD040, 0x8825, 0xD041, 0x8826, 0xD042,
+	0x8827, 0xD043, 0x8828, 0xD044, 0x8829, 0xD045, 0x882A, 0xD046,
+	0x882B, 0xD047, 0x882C, 0xD048, 0x882D, 0xD049, 0x882E, 0xD04A,
+	0x882F, 0xD04B, 0x8830, 0xD04C, 0x8831, 0xD04D, 0x8832, 0xEEC3,
+	0x8833, 0xD04E, 0x8834, 0xD04F, 0x8835, 0xD050, 0x8836, 0xD051,
+	0x8837, 0xD052, 0x8838, 0xD053, 0x8839, 0xF3BC, 0x883A, 0xD054,
+	0x883B, 0xD055, 0x883C, 0xF3BD, 0x883D, 0xD056, 0x883E, 0xD057,
+	0x883F, 0xD058, 0x8840, 0xD1AA, 0x8841, 0xD059, 0x8842, 0xD05A,
+	0x8843, 0xD05B, 0x8844, 0xF4AC, 0x8845, 0xD0C6, 0x8846, 0xD05C,
+	0x8847, 0xD05D, 0x8848, 0xD05E, 0x8849, 0xD05F, 0x884A, 0xD060,
+	0x884B, 0xD061, 0x884C, 0xD0D0, 0x884D, 0xD1DC, 0x884E, 0xD062,
+	0x884F, 0xD063, 0x8850, 0xD064, 0x8851, 0xD065, 0x8852, 0xD066,
+	0x8853, 0xD067, 0x8854, 0xCFCE, 0x8855, 0xD068, 0x8856, 0xD069,
+	0x8857, 0xBDD6, 0x8858, 0xD06A, 0x8859, 0xD1C3, 0x885A, 0xD06B,
+	0x885B, 0xD06C, 0x885C, 0xD06D, 0x885D, 0xD06E, 0x885E, 0xD06F,
+	0x885F, 0xD070, 0x8860, 0xD071, 0x8861, 0xBAE2, 0x8862, 0xE1E9,
+	0x8863, 0xD2C2, 0x8864, 0xF1C2, 0x8865, 0xB2B9, 0x8866, 0xD072,
+	0x8867, 0xD073, 0x8868, 0xB1ED, 0x8869, 0xF1C3, 0x886A, 0xD074,
+	0x886B, 0xC9C0, 0x886C, 0xB3C4, 0x886D, 0xD075, 0x886E, 0xD9F2,
+	0x886F, 0xD076, 0x8870, 0xCBA5, 0x8871, 0xD077, 0x8872, 0xF1C4,
+	0x8873, 0xD078, 0x8874, 0xD079, 0x8875, 0xD07A, 0x8876, 0xD07B,
+	0x8877, 0xD6D4, 0x8878, 0xD07C, 0x8879, 0xD07D, 0x887A, 0xD07E,
+	0x887B, 0xD080, 0x887C, 0xD081, 0x887D, 0xF1C5, 0x887E, 0xF4C0,
+	0x887F, 0xF1C6, 0x8880, 0xD082, 0x8881, 0xD4AC, 0x8882, 0xF1C7,
+	0x8883, 0xD083, 0x8884, 0xB0C0, 0x8885, 0xF4C1, 0x8886, 0xD084,
+	0x8887, 0xD085, 0x8888, 0xF4C2, 0x8889, 0xD086, 0x888A, 0xD087,
+	0x888B, 0xB4FC, 0x888C, 0xD088, 0x888D, 0xC5DB, 0x888E, 0xD089,
+	0x888F, 0xD08A, 0x8890, 0xD08B, 0x8891, 0xD08C, 0x8892, 0xCCBB,
+	0x8893, 0xD08D, 0x8894, 0xD08E, 0x8895, 0xD08F, 0x8896, 0xD0E4,
+	0x8897, 0xD090, 0x8898, 0xD091, 0x8899, 0xD092, 0x889A, 0xD093,
+	0x889B, 0xD094, 0x889C, 0xCDE0, 0x889D, 0xD095, 0x889E, 0xD096,
+	0x889F, 0xD097, 0x88A0, 0xD098, 0x88A1, 0xD099, 0x88A2, 0xF1C8,
+	0x88A3, 0xD09A, 0x88A4, 0xD9F3, 0x88A5, 0xD09B, 0x88A6, 0xD09C,
+	0x88A7, 0xD09D, 0x88A8, 0xD09E, 0x88A9, 0xD09F, 0x88AA, 0xD0A0,
+	0x88AB, 0xB1BB, 0x88AC, 0xD140, 0x88AD, 0xCFAE, 0x88AE, 0xD141,
+	0x88AF, 0xD142, 0x88B0, 0xD143, 0x88B1, 0xB8A4, 0x88B2, 0xD144,
+	0x88B3, 0xD145, 0x88B4, 0xD146, 0x88B5, 0xD147, 0x88B6, 0xD148,
+	0x88B7, 0xF1CA, 0x88B8, 0xD149, 0x88B9, 0xD14A, 0x88BA, 0xD14B,
+	0x88BB, 0xD14C, 0x88BC, 0xF1CB, 0x88BD, 0xD14D, 0x88BE, 0xD14E,
+	0x88BF, 0xD14F, 0x88C0, 0xD150, 0x88C1, 0xB2C3, 0x88C2, 0xC1D1,
+	0x88C3, 0xD151, 0x88C4, 0xD152, 0x88C5, 0xD7B0, 0x88C6, 0xF1C9,
+	0x88C7, 0xD153, 0x88C8, 0xD154, 0x88C9, 0xF1CC, 0x88CA, 0xD155,
+	0x88CB, 0xD156, 0x88CC, 0xD157, 0x88CD, 0xD158, 0x88CE, 0xF1CE,
+	0x88CF, 0xD159, 0x88D0, 0xD15A, 0x88D1, 0xD15B, 0x88D2, 0xD9F6,
+	0x88D3, 0xD15C, 0x88D4, 0xD2E1, 0x88D5, 0xD4A3, 0x88D6, 0xD15D,
+	0x88D7, 0xD15E, 0x88D8, 0xF4C3, 0x88D9, 0xC8B9, 0x88DA, 0xD15F,
+	0x88DB, 0xD160, 0x88DC, 0xD161, 0x88DD, 0xD162, 0x88DE, 0xD163,
+	0x88DF, 0xF4C4, 0x88E0, 0xD164, 0x88E1, 0xD165, 0x88E2, 0xF1CD,
+	0x88E3, 0xF1CF, 0x88E4, 0xBFE3, 0x88E5, 0xF1D0, 0x88E6, 0xD166,
+	0x88E7, 0xD167, 0x88E8, 0xF1D4, 0x88E9, 0xD168, 0x88EA, 0xD169,
+	0x88EB, 0xD16A, 0x88EC, 0xD16B, 0x88ED, 0xD16C, 0x88EE, 0xD16D,
+	0x88EF, 0xD16E, 0x88F0, 0xF1D6, 0x88F1, 0xF1D1, 0x88F2, 0xD16F,
+	0x88F3, 0xC9D1, 0x88F4, 0xC5E1, 0x88F5, 0xD170, 0x88F6, 0xD171,
+	0x88F7, 0xD172, 0x88F8, 0xC2E3, 0x88F9, 0xB9FC, 0x88FA, 0xD173,
+	0x88FB, 0xD174, 0x88FC, 0xF1D3, 0x88FD, 0xD175, 0x88FE, 0xF1D5,
+	0x88FF, 0xD176, 0x8900, 0xD177, 0x8901, 0xD178, 0x8902, 0xB9D3,
+	0x8903, 0xD179, 0x8904, 0xD17A, 0x8905, 0xD17B, 0x8906, 0xD17C,
+	0x8907, 0xD17D, 0x8908, 0xD17E, 0x8909, 0xD180, 0x890A, 0xF1DB,
+	0x890B, 0xD181, 0x890C, 0xD182, 0x890D, 0xD183, 0x890E, 0xD184,
+	0x890F, 0xD185, 0x8910, 0xBAD6, 0x8911, 0xD186, 0x8912, 0xB0FD,
+	0x8913, 0xF1D9, 0x8914, 0xD187, 0x8915, 0xD188, 0x8916, 0xD189,
+	0x8917, 0xD18A, 0x8918, 0xD18B, 0x8919, 0xF1D8, 0x891A, 0xF1D2,
+	0x891B, 0xF1DA, 0x891C, 0xD18C, 0x891D, 0xD18D, 0x891E, 0xD18E,
+	0x891F, 0xD18F, 0x8920, 0xD190, 0x8921, 0xF1D7, 0x8922, 0xD191,
+	0x8923, 0xD192, 0x8924, 0xD193, 0x8925, 0xC8EC, 0x8926, 0xD194,
+	0x8927, 0xD195, 0x8928, 0xD196, 0x8929, 0xD197, 0x892A, 0xCDCA,
+	0x892B, 0xF1DD, 0x892C, 0xD198, 0x892D, 0xD199, 0x892E, 0xD19A,
+	0x892F, 0xD19B, 0x8930, 0xE5BD, 0x8931, 0xD19C, 0x8932, 0xD19D,
+	0x8933, 0xD19E, 0x8934, 0xF1DC, 0x8935, 0xD19F, 0x8936, 0xF1DE,
+	0x8937, 0xD1A0, 0x8938, 0xD240, 0x8939, 0xD241, 0x893A, 0xD242,
+	0x893B, 0xD243, 0x893C, 0xD244, 0x893D, 0xD245, 0x893E, 0xD246,
+	0x893F, 0xD247, 0x8940, 0xD248, 0x8941, 0xF1DF, 0x8942, 0xD249,
+	0x8943, 0xD24A, 0x8944, 0xCFE5, 0x8945, 0xD24B, 0x8946, 0xD24C,
+	0x8947, 0xD24D, 0x8948, 0xD24E, 0x8949, 0xD24F, 0x894A, 0xD250,
+	0x894B, 0xD251, 0x894C, 0xD252, 0x894D, 0xD253, 0x894E, 0xD254,
+	0x894F, 0xD255, 0x8950, 0xD256, 0x8951, 0xD257, 0x8952, 0xD258,
+	0x8953, 0xD259, 0x8954, 0xD25A, 0x8955, 0xD25B, 0x8956, 0xD25C,
+	0x8957, 0xD25D, 0x8958, 0xD25E, 0x8959, 0xD25F, 0x895A, 0xD260,
+	0x895B, 0xD261, 0x895C, 0xD262, 0x895D, 0xD263, 0x895E, 0xF4C5,
+	0x895F, 0xBDF3, 0x8960, 0xD264, 0x8961, 0xD265, 0x8962, 0xD266,
+	0x8963, 0xD267, 0x8964, 0xD268, 0x8965, 0xD269, 0x8966, 0xF1E0,
+	0x8967, 0xD26A, 0x8968, 0xD26B, 0x8969, 0xD26C, 0x896A, 0xD26D,
+	0x896B, 0xD26E, 0x896C, 0xD26F, 0x896D, 0xD270, 0x896E, 0xD271,
+	0x896F, 0xD272, 0x8970, 0xD273, 0x8971, 0xD274, 0x8972, 0xD275,
+	0x8973, 0xD276, 0x8974, 0xD277, 0x8975, 0xD278, 0x8976, 0xD279,
+	0x8977, 0xD27A, 0x8978, 0xD27B, 0x8979, 0xD27C, 0x897A, 0xD27D,
+	0x897B, 0xF1E1, 0x897C, 0xD27E, 0x897D, 0xD280, 0x897E, 0xD281,
+	0x897F, 0xCEF7, 0x8980, 0xD282, 0x8981, 0xD2AA, 0x8982, 0xD283,
+	0x8983, 0xF1FB, 0x8984, 0xD284, 0x8985, 0xD285, 0x8986, 0xB8B2,
+	0x8987, 0xD286, 0x8988, 0xD287, 0x8989, 0xD288, 0x898A, 0xD289,
+	0x898B, 0xD28A, 0x898C, 0xD28B, 0x898D, 0xD28C, 0x898E, 0xD28D,
+	0x898F, 0xD28E, 0x8990, 0xD28F, 0x8991, 0xD290, 0x8992, 0xD291,
+	0x8993, 0xD292, 0x8994, 0xD293, 0x8995, 0xD294, 0x8996, 0xD295,
+	0x8997, 0xD296, 0x8998, 0xD297, 0x8999, 0xD298, 0x899A, 0xD299,
+	0x899B, 0xD29A, 0x899C, 0xD29B, 0x899D, 0xD29C, 0x899E, 0xD29D,
+	0x899F, 0xD29E, 0x89A0, 0xD29F, 0x89A1, 0xD2A0, 0x89A2, 0xD340,
+	0x89A3, 0xD341, 0x89A4, 0xD342, 0x89A5, 0xD343, 0x89A6, 0xD344,
+	0x89A7, 0xD345, 0x89A8, 0xD346, 0x89A9, 0xD347, 0x89AA, 0xD348,
+	0x89AB, 0xD349, 0x89AC, 0xD34A, 0x89AD, 0xD34B, 0x89AE, 0xD34C,
+	0x89AF, 0xD34D, 0x89B0, 0xD34E, 0x89B1, 0xD34F, 0x89B2, 0xD350,
+	0x89B3, 0xD351, 0x89B4, 0xD352, 0x89B5, 0xD353, 0x89B6, 0xD354,
+	0x89B7, 0xD355, 0x89B8, 0xD356, 0x89B9, 0xD357, 0x89BA, 0xD358,
+	0x89BB, 0xD359, 0x89BC, 0xD35A, 0x89BD, 0xD35B, 0x89BE, 0xD35C,
+	0x89BF, 0xD35D, 0x89C0, 0xD35E, 0x89C1, 0xBCFB, 0x89C2, 0xB9DB,
+	0x89C3, 0xD35F, 0x89C4, 0xB9E6, 0x89C5, 0xC3D9, 0x89C6, 0xCAD3,
+	0x89C7, 0xEAE8, 0x89C8, 0xC0C0, 0x89C9, 0xBEF5, 0x89CA, 0xEAE9,
+	0x89CB, 0xEAEA, 0x89CC, 0xEAEB, 0x89CD, 0xD360, 0x89CE, 0xEAEC,
+	0x89CF, 0xEAED, 0x89D0, 0xEAEE, 0x89D1, 0xEAEF, 0x89D2, 0xBDC7,
+	0x89D3, 0xD361, 0x89D4, 0xD362, 0x89D5, 0xD363, 0x89D6, 0xF5FB,
+	0x89D7, 0xD364, 0x89D8, 0xD365, 0x89D9, 0xD366, 0x89DA, 0xF5FD,
+	0x89DB, 0xD367, 0x89DC, 0xF5FE, 0x89DD, 0xD368, 0x89DE, 0xF5FC,
+	0x89DF, 0xD369, 0x89E0, 0xD36A, 0x89E1, 0xD36B, 0x89E2, 0xD36C,
+	0x89E3, 0xBDE2, 0x89E4, 0xD36D, 0x89E5, 0xF6A1, 0x89E6, 0xB4A5,
+	0x89E7, 0xD36E, 0x89E8, 0xD36F, 0x89E9, 0xD370, 0x89EA, 0xD371,
+	0x89EB, 0xF6A2, 0x89EC, 0xD372, 0x89ED, 0xD373, 0x89EE, 0xD374,
+	0x89EF, 0xF6A3, 0x89F0, 0xD375, 0x89F1, 0xD376, 0x89F2, 0xD377,
+	0x89F3, 0xECB2, 0x89F4, 0xD378, 0x89F5, 0xD379, 0x89F6, 0xD37A,
+	0x89F7, 0xD37B, 0x89F8, 0xD37C, 0x89F9, 0xD37D, 0x89FA, 0xD37E,
+	0x89FB, 0xD380, 0x89FC, 0xD381, 0x89FD, 0xD382, 0x89FE, 0xD383,
+	0x89FF, 0xD384, 0x8A00, 0xD1D4, 0x8A01, 0xD385, 0x8A02, 0xD386,
+	0x8A03, 0xD387, 0x8A04, 0xD388, 0x8A05, 0xD389, 0x8A06, 0xD38A,
+	0x8A07, 0xD9EA, 0x8A08, 0xD38B, 0x8A09, 0xD38C, 0x8A0A, 0xD38D,
+	0x8A0B, 0xD38E, 0x8A0C, 0xD38F, 0x8A0D, 0xD390, 0x8A0E, 0xD391,
+	0x8A0F, 0xD392, 0x8A10, 0xD393, 0x8A11, 0xD394, 0x8A12, 0xD395,
+	0x8A13, 0xD396, 0x8A14, 0xD397, 0x8A15, 0xD398, 0x8A16, 0xD399,
+	0x8A17, 0xD39A, 0x8A18, 0xD39B, 0x8A19, 0xD39C, 0x8A1A, 0xD39D,
+	0x8A1B, 0xD39E, 0x8A1C, 0xD39F, 0x8A1D, 0xD3A0, 0x8A1E, 0xD440,
+	0x8A1F, 0xD441, 0x8A20, 0xD442, 0x8A21, 0xD443, 0x8A22, 0xD444,
+	0x8A23, 0xD445, 0x8A24, 0xD446, 0x8A25, 0xD447, 0x8A26, 0xD448,
+	0x8A27, 0xD449, 0x8A28, 0xD44A, 0x8A29, 0xD44B, 0x8A2A, 0xD44C,
+	0x8A2B, 0xD44D, 0x8A2C, 0xD44E, 0x8A2D, 0xD44F, 0x8A2E, 0xD450,
+	0x8A2F, 0xD451, 0x8A30, 0xD452, 0x8A31, 0xD453, 0x8A32, 0xD454,
+	0x8A33, 0xD455, 0x8A34, 0xD456, 0x8A35, 0xD457, 0x8A36, 0xD458,
+	0x8A37, 0xD459, 0x8A38, 0xD45A, 0x8A39, 0xD45B, 0x8A3A, 0xD45C,
+	0x8A3B, 0xD45D, 0x8A3C, 0xD45E, 0x8A3D, 0xD45F, 0x8A3E, 0xF6A4,
+	0x8A3F, 0xD460, 0x8A40, 0xD461, 0x8A41, 0xD462, 0x8A42, 0xD463,
+	0x8A43, 0xD464, 0x8A44, 0xD465, 0x8A45, 0xD466, 0x8A46, 0xD467,
+	0x8A47, 0xD468, 0x8A48, 0xEEBA, 0x8A49, 0xD469, 0x8A4A, 0xD46A,
+	0x8A4B, 0xD46B, 0x8A4C, 0xD46C, 0x8A4D, 0xD46D, 0x8A4E, 0xD46E,
+	0x8A4F, 0xD46F, 0x8A50, 0xD470, 0x8A51, 0xD471, 0x8A52, 0xD472,
+	0x8A53, 0xD473, 0x8A54, 0xD474, 0x8A55, 0xD475, 0x8A56, 0xD476,
+	0x8A57, 0xD477, 0x8A58, 0xD478, 0x8A59, 0xD479, 0x8A5A, 0xD47A,
+	0x8A5B, 0xD47B, 0x8A5C, 0xD47C, 0x8A5D, 0xD47D, 0x8A5E, 0xD47E,
+	0x8A5F, 0xD480, 0x8A60, 0xD481, 0x8A61, 0xD482, 0x8A62, 0xD483,
+	0x8A63, 0xD484, 0x8A64, 0xD485, 0x8A65, 0xD486, 0x8A66, 0xD487,
+	0x8A67, 0xD488, 0x8A68, 0xD489, 0x8A69, 0xD48A, 0x8A6A, 0xD48B,
+	0x8A6B, 0xD48C, 0x8A6C, 0xD48D, 0x8A6D, 0xD48E, 0x8A6E, 0xD48F,
+	0x8A6F, 0xD490, 0x8A70, 0xD491, 0x8A71, 0xD492, 0x8A72, 0xD493,
+	0x8A73, 0xD494, 0x8A74, 0xD495, 0x8A75, 0xD496, 0x8A76, 0xD497,
+	0x8A77, 0xD498, 0x8A78, 0xD499, 0x8A79, 0xD5B2, 0x8A7A, 0xD49A,
+	0x8A7B, 0xD49B, 0x8A7C, 0xD49C, 0x8A7D, 0xD49D, 0x8A7E, 0xD49E,
+	0x8A7F, 0xD49F, 0x8A80, 0xD4A0, 0x8A81, 0xD540, 0x8A82, 0xD541,
+	0x8A83, 0xD542, 0x8A84, 0xD543, 0x8A85, 0xD544, 0x8A86, 0xD545,
+	0x8A87, 0xD546, 0x8A88, 0xD547, 0x8A89, 0xD3FE, 0x8A8A, 0xCCDC,
+	0x8A8B, 0xD548, 0x8A8C, 0xD549, 0x8A8D, 0xD54A, 0x8A8E, 0xD54B,
+	0x8A8F, 0xD54C, 0x8A90, 0xD54D, 0x8A91, 0xD54E, 0x8A92, 0xD54F,
+	0x8A93, 0xCAC4, 0x8A94, 0xD550, 0x8A95, 0xD551, 0x8A96, 0xD552,
+	0x8A97, 0xD553, 0x8A98, 0xD554, 0x8A99, 0xD555, 0x8A9A, 0xD556,
+	0x8A9B, 0xD557, 0x8A9C, 0xD558, 0x8A9D, 0xD559, 0x8A9E, 0xD55A,
+	0x8A9F, 0xD55B, 0x8AA0, 0xD55C, 0x8AA1, 0xD55D, 0x8AA2, 0xD55E,
+	0x8AA3, 0xD55F, 0x8AA4, 0xD560, 0x8AA5, 0xD561, 0x8AA6, 0xD562,
+	0x8AA7, 0xD563, 0x8AA8, 0xD564, 0x8AA9, 0xD565, 0x8AAA, 0xD566,
+	0x8AAB, 0xD567, 0x8AAC, 0xD568, 0x8AAD, 0xD569, 0x8AAE, 0xD56A,
+	0x8AAF, 0xD56B, 0x8AB0, 0xD56C, 0x8AB1, 0xD56D, 0x8AB2, 0xD56E,
+	0x8AB3, 0xD56F, 0x8AB4, 0xD570, 0x8AB5, 0xD571, 0x8AB6, 0xD572,
+	0x8AB7, 0xD573, 0x8AB8, 0xD574, 0x8AB9, 0xD575, 0x8ABA, 0xD576,
+	0x8ABB, 0xD577, 0x8ABC, 0xD578, 0x8ABD, 0xD579, 0x8ABE, 0xD57A,
+	0x8ABF, 0xD57B, 0x8AC0, 0xD57C, 0x8AC1, 0xD57D, 0x8AC2, 0xD57E,
+	0x8AC3, 0xD580, 0x8AC4, 0xD581, 0x8AC5, 0xD582, 0x8AC6, 0xD583,
+	0x8AC7, 0xD584, 0x8AC8, 0xD585, 0x8AC9, 0xD586, 0x8ACA, 0xD587,
+	0x8ACB, 0xD588, 0x8ACC, 0xD589, 0x8ACD, 0xD58A, 0x8ACE, 0xD58B,
+	0x8ACF, 0xD58C, 0x8AD0, 0xD58D, 0x8AD1, 0xD58E, 0x8AD2, 0xD58F,
+	0x8AD3, 0xD590, 0x8AD4, 0xD591, 0x8AD5, 0xD592, 0x8AD6, 0xD593,
+	0x8AD7, 0xD594, 0x8AD8, 0xD595, 0x8AD9, 0xD596, 0x8ADA, 0xD597,
+	0x8ADB, 0xD598, 0x8ADC, 0xD599, 0x8ADD, 0xD59A, 0x8ADE, 0xD59B,
+	0x8ADF, 0xD59C, 0x8AE0, 0xD59D, 0x8AE1, 0xD59E, 0x8AE2, 0xD59F,
+	0x8AE3, 0xD5A0, 0x8AE4, 0xD640, 0x8AE5, 0xD641, 0x8AE6, 0xD642,
+	0x8AE7, 0xD643, 0x8AE8, 0xD644, 0x8AE9, 0xD645, 0x8AEA, 0xD646,
+	0x8AEB, 0xD647, 0x8AEC, 0xD648, 0x8AED, 0xD649, 0x8AEE, 0xD64A,
+	0x8AEF, 0xD64B, 0x8AF0, 0xD64C, 0x8AF1, 0xD64D, 0x8AF2, 0xD64E,
+	0x8AF3, 0xD64F, 0x8AF4, 0xD650, 0x8AF5, 0xD651, 0x8AF6, 0xD652,
+	0x8AF7, 0xD653, 0x8AF8, 0xD654, 0x8AF9, 0xD655, 0x8AFA, 0xD656,
+	0x8AFB, 0xD657, 0x8AFC, 0xD658, 0x8AFD, 0xD659, 0x8AFE, 0xD65A,
+	0x8AFF, 0xD65B, 0x8B00, 0xD65C, 0x8B01, 0xD65D, 0x8B02, 0xD65E,
+	0x8B03, 0xD65F, 0x8B04, 0xD660, 0x8B05, 0xD661, 0x8B06, 0xD662,
+	0x8B07, 0xE5C0, 0x8B08, 0xD663, 0x8B09, 0xD664, 0x8B0A, 0xD665,
+	0x8B0B, 0xD666, 0x8B0C, 0xD667, 0x8B0D, 0xD668, 0x8B0E, 0xD669,
+	0x8B0F, 0xD66A, 0x8B10, 0xD66B, 0x8B11, 0xD66C, 0x8B12, 0xD66D,
+	0x8B13, 0xD66E, 0x8B14, 0xD66F, 0x8B15, 0xD670, 0x8B16, 0xD671,
+	0x8B17, 0xD672, 0x8B18, 0xD673, 0x8B19, 0xD674, 0x8B1A, 0xD675,
+	0x8B1B, 0xD676, 0x8B1C, 0xD677, 0x8B1D, 0xD678, 0x8B1E, 0xD679,
+	0x8B1F, 0xD67A, 0x8B20, 0xD67B, 0x8B21, 0xD67C, 0x8B22, 0xD67D,
+	0x8B23, 0xD67E, 0x8B24, 0xD680, 0x8B25, 0xD681, 0x8B26, 0xF6A5,
+	0x8B27, 0xD682, 0x8B28, 0xD683, 0x8B29, 0xD684, 0x8B2A, 0xD685,
+	0x8B2B, 0xD686, 0x8B2C, 0xD687, 0x8B2D, 0xD688, 0x8B2E, 0xD689,
+	0x8B2F, 0xD68A, 0x8B30, 0xD68B, 0x8B31, 0xD68C, 0x8B32, 0xD68D,
+	0x8B33, 0xD68E, 0x8B34, 0xD68F, 0x8B35, 0xD690, 0x8B36, 0xD691,
+	0x8B37, 0xD692, 0x8B38, 0xD693, 0x8B39, 0xD694, 0x8B3A, 0xD695,
+	0x8B3B, 0xD696, 0x8B3C, 0xD697, 0x8B3D, 0xD698, 0x8B3E, 0xD699,
+	0x8B3F, 0xD69A, 0x8B40, 0xD69B, 0x8B41, 0xD69C, 0x8B42, 0xD69D,
+	0x8B43, 0xD69E, 0x8B44, 0xD69F, 0x8B45, 0xD6A0, 0x8B46, 0xD740,
+	0x8B47, 0xD741, 0x8B48, 0xD742, 0x8B49, 0xD743, 0x8B4A, 0xD744,
+	0x8B4B, 0xD745, 0x8B4C, 0xD746, 0x8B4D, 0xD747, 0x8B4E, 0xD748,
+	0x8B4F, 0xD749, 0x8B50, 0xD74A, 0x8B51, 0xD74B, 0x8B52, 0xD74C,
+	0x8B53, 0xD74D, 0x8B54, 0xD74E, 0x8B55, 0xD74F, 0x8B56, 0xD750,
+	0x8B57, 0xD751, 0x8B58, 0xD752, 0x8B59, 0xD753, 0x8B5A, 0xD754,
+	0x8B5B, 0xD755, 0x8B5C, 0xD756, 0x8B5D, 0xD757, 0x8B5E, 0xD758,
+	0x8B5F, 0xD759, 0x8B60, 0xD75A, 0x8B61, 0xD75B, 0x8B62, 0xD75C,
+	0x8B63, 0xD75D, 0x8B64, 0xD75E, 0x8B65, 0xD75F, 0x8B66, 0xBEAF,
+	0x8B67, 0xD760, 0x8B68, 0xD761, 0x8B69, 0xD762, 0x8B6A, 0xD763,
+	0x8B6B, 0xD764, 0x8B6C, 0xC6A9, 0x8B6D, 0xD765, 0x8B6E, 0xD766,
+	0x8B6F, 0xD767, 0x8B70, 0xD768, 0x8B71, 0xD769, 0x8B72, 0xD76A,
+	0x8B73, 0xD76B, 0x8B74, 0xD76C, 0x8B75, 0xD76D, 0x8B76, 0xD76E,
+	0x8B77, 0xD76F, 0x8B78, 0xD770, 0x8B79, 0xD771, 0x8B7A, 0xD772,
+	0x8B7B, 0xD773, 0x8B7C, 0xD774, 0x8B7D, 0xD775, 0x8B7E, 0xD776,
+	0x8B7F, 0xD777, 0x8B80, 0xD778, 0x8B81, 0xD779, 0x8B82, 0xD77A,
+	0x8B83, 0xD77B, 0x8B84, 0xD77C, 0x8B85, 0xD77D, 0x8B86, 0xD77E,
+	0x8B87, 0xD780, 0x8B88, 0xD781, 0x8B89, 0xD782, 0x8B8A, 0xD783,
+	0x8B8B, 0xD784, 0x8B8C, 0xD785, 0x8B8D, 0xD786, 0x8B8E, 0xD787,
+	0x8B8F, 0xD788, 0x8B90, 0xD789, 0x8B91, 0xD78A, 0x8B92, 0xD78B,
+	0x8B93, 0xD78C, 0x8B94, 0xD78D, 0x8B95, 0xD78E, 0x8B96, 0xD78F,
+	0x8B97, 0xD790, 0x8B98, 0xD791, 0x8B99, 0xD792, 0x8B9A, 0xD793,
+	0x8B9B, 0xD794, 0x8B9C, 0xD795, 0x8B9D, 0xD796, 0x8B9E, 0xD797,
+	0x8B9F, 0xD798, 0x8BA0, 0xDAA5, 0x8BA1, 0xBCC6, 0x8BA2, 0xB6A9,
+	0x8BA3, 0xB8BC, 0x8BA4, 0xC8CF, 0x8BA5, 0xBCA5, 0x8BA6, 0xDAA6,
+	0x8BA7, 0xDAA7, 0x8BA8, 0xCCD6, 0x8BA9, 0xC8C3, 0x8BAA, 0xDAA8,
+	0x8BAB, 0xC6FD, 0x8BAC, 0xD799, 0x8BAD, 0xD1B5, 0x8BAE, 0xD2E9,
+	0x8BAF, 0xD1B6, 0x8BB0, 0xBCC7, 0x8BB1, 0xD79A, 0x8BB2, 0xBDB2,
+	0x8BB3, 0xBBE4, 0x8BB4, 0xDAA9, 0x8BB5, 0xDAAA, 0x8BB6, 0xD1C8,
+	0x8BB7, 0xDAAB, 0x8BB8, 0xD0ED, 0x8BB9, 0xB6EF, 0x8BBA, 0xC2DB,
+	0x8BBB, 0xD79B, 0x8BBC, 0xCBCF, 0x8BBD, 0xB7ED, 0x8BBE, 0xC9E8,
+	0x8BBF, 0xB7C3, 0x8BC0, 0xBEF7, 0x8BC1, 0xD6A4, 0x8BC2, 0xDAAC,
+	0x8BC3, 0xDAAD, 0x8BC4, 0xC6C0, 0x8BC5, 0xD7E7, 0x8BC6, 0xCAB6,
+	0x8BC7, 0xD79C, 0x8BC8, 0xD5A9, 0x8BC9, 0xCBDF, 0x8BCA, 0xD5EF,
+	0x8BCB, 0xDAAE, 0x8BCC, 0xD6DF, 0x8BCD, 0xB4CA, 0x8BCE, 0xDAB0,
+	0x8BCF, 0xDAAF, 0x8BD0, 0xD79D, 0x8BD1, 0xD2EB, 0x8BD2, 0xDAB1,
+	0x8BD3, 0xDAB2, 0x8BD4, 0xDAB3, 0x8BD5, 0xCAD4, 0x8BD6, 0xDAB4,
+	0x8BD7, 0xCAAB, 0x8BD8, 0xDAB5, 0x8BD9, 0xDAB6, 0x8BDA, 0xB3CF,
+	0x8BDB, 0xD6EF, 0x8BDC, 0xDAB7, 0x8BDD, 0xBBB0, 0x8BDE, 0xB5AE,
+	0x8BDF, 0xDAB8, 0x8BE0, 0xDAB9, 0x8BE1, 0xB9EE, 0x8BE2, 0xD1AF,
+	0x8BE3, 0xD2E8, 0x8BE4, 0xDABA, 0x8BE5, 0xB8C3, 0x8BE6, 0xCFEA,
+	0x8BE7, 0xB2EF, 0x8BE8, 0xDABB, 0x8BE9, 0xDABC, 0x8BEA, 0xD79E,
+	0x8BEB, 0xBDEB, 0x8BEC, 0xCEDC, 0x8BED, 0xD3EF, 0x8BEE, 0xDABD,
+	0x8BEF, 0xCEF3, 0x8BF0, 0xDABE, 0x8BF1, 0xD3D5, 0x8BF2, 0xBBE5,
+	0x8BF3, 0xDABF, 0x8BF4, 0xCBB5, 0x8BF5, 0xCBD0, 0x8BF6, 0xDAC0,
+	0x8BF7, 0xC7EB, 0x8BF8, 0xD6EE, 0x8BF9, 0xDAC1, 0x8BFA, 0xC5B5,
+	0x8BFB, 0xB6C1, 0x8BFC, 0xDAC2, 0x8BFD, 0xB7CC, 0x8BFE, 0xBFCE,
+	0x8BFF, 0xDAC3, 0x8C00, 0xDAC4, 0x8C01, 0xCBAD, 0x8C02, 0xDAC5,
+	0x8C03, 0xB5F7, 0x8C04, 0xDAC6, 0x8C05, 0xC1C2, 0x8C06, 0xD7BB,
+	0x8C07, 0xDAC7, 0x8C08, 0xCCB8, 0x8C09, 0xD79F, 0x8C0A, 0xD2EA,
+	0x8C0B, 0xC4B1, 0x8C0C, 0xDAC8, 0x8C0D, 0xB5FD, 0x8C0E, 0xBBD1,
+	0x8C0F, 0xDAC9, 0x8C10, 0xD0B3, 0x8C11, 0xDACA, 0x8C12, 0xDACB,
+	0x8C13, 0xCEBD, 0x8C14, 0xDACC, 0x8C15, 0xDACD, 0x8C16, 0xDACE,
+	0x8C17, 0xB2F7, 0x8C18, 0xDAD1, 0x8C19, 0xDACF, 0x8C1A, 0xD1E8,
+	0x8C1B, 0xDAD0, 0x8C1C, 0xC3D5, 0x8C1D, 0xDAD2, 0x8C1E, 0xD7A0,
+	0x8C1F, 0xDAD3, 0x8C20, 0xDAD4, 0x8C21, 0xDAD5, 0x8C22, 0xD0BB,
+	0x8C23, 0xD2A5, 0x8C24, 0xB0F9, 0x8C25, 0xDAD6, 0x8C26, 0xC7AB,
+	0x8C27, 0xDAD7, 0x8C28, 0xBDF7, 0x8C29, 0xC3A1, 0x8C2A, 0xDAD8,
+	0x8C2B, 0xDAD9, 0x8C2C, 0xC3FD, 0x8C2D, 0xCCB7, 0x8C2E, 0xDADA,
+	0x8C2F, 0xDADB, 0x8C30, 0xC0BE, 0x8C31, 0xC6D7, 0x8C32, 0xDADC,
+	0x8C33, 0xDADD, 0x8C34, 0xC7B4, 0x8C35, 0xDADE, 0x8C36, 0xDADF,
+	0x8C37, 0xB9C8, 0x8C38, 0xD840, 0x8C39, 0xD841, 0x8C3A, 0xD842,
+	0x8C3B, 0xD843, 0x8C3C, 0xD844, 0x8C3D, 0xD845, 0x8C3E, 0xD846,
+	0x8C3F, 0xD847, 0x8C40, 0xD848, 0x8C41, 0xBBED, 0x8C42, 0xD849,
+	0x8C43, 0xD84A, 0x8C44, 0xD84B, 0x8C45, 0xD84C, 0x8C46, 0xB6B9,
+	0x8C47, 0xF4F8, 0x8C48, 0xD84D, 0x8C49, 0xF4F9, 0x8C4A, 0xD84E,
+	0x8C4B, 0xD84F, 0x8C4C, 0xCDE3, 0x8C4D, 0xD850, 0x8C4E, 0xD851,
+	0x8C4F, 0xD852, 0x8C50, 0xD853, 0x8C51, 0xD854, 0x8C52, 0xD855,
+	0x8C53, 0xD856, 0x8C54, 0xD857, 0x8C55, 0xF5B9, 0x8C56, 0xD858,
+	0x8C57, 0xD859, 0x8C58, 0xD85A, 0x8C59, 0xD85B, 0x8C5A, 0xEBE0,
+	0x8C5B, 0xD85C, 0x8C5C, 0xD85D, 0x8C5D, 0xD85E, 0x8C5E, 0xD85F,
+	0x8C5F, 0xD860, 0x8C60, 0xD861, 0x8C61, 0xCFF3, 0x8C62, 0xBBBF,
+	0x8C63, 0xD862, 0x8C64, 0xD863, 0x8C65, 0xD864, 0x8C66, 0xD865,
+	0x8C67, 0xD866, 0x8C68, 0xD867, 0x8C69, 0xD868, 0x8C6A, 0xBAC0,
+	0x8C6B, 0xD4A5, 0x8C6C, 0xD869, 0x8C6D, 0xD86A, 0x8C6E, 0xD86B,
+	0x8C6F, 0xD86C, 0x8C70, 0xD86D, 0x8C71, 0xD86E, 0x8C72, 0xD86F,
+	0x8C73, 0xE1D9, 0x8C74, 0xD870, 0x8C75, 0xD871, 0x8C76, 0xD872,
+	0x8C77, 0xD873, 0x8C78, 0xF5F4, 0x8C79, 0xB1AA, 0x8C7A, 0xB2F2,
+	0x8C7B, 0xD874, 0x8C7C, 0xD875, 0x8C7D, 0xD876, 0x8C7E, 0xD877,
+	0x8C7F, 0xD878, 0x8C80, 0xD879, 0x8C81, 0xD87A, 0x8C82, 0xF5F5,
+	0x8C83, 0xD87B, 0x8C84, 0xD87C, 0x8C85, 0xF5F7, 0x8C86, 0xD87D,
+	0x8C87, 0xD87E, 0x8C88, 0xD880, 0x8C89, 0xBAD1, 0x8C8A, 0xF5F6,
+	0x8C8B, 0xD881, 0x8C8C, 0xC3B2, 0x8C8D, 0xD882, 0x8C8E, 0xD883,
+	0x8C8F, 0xD884, 0x8C90, 0xD885, 0x8C91, 0xD886, 0x8C92, 0xD887,
+	0x8C93, 0xD888, 0x8C94, 0xF5F9, 0x8C95, 0xD889, 0x8C96, 0xD88A,
+	0x8C97, 0xD88B, 0x8C98, 0xF5F8, 0x8C99, 0xD88C, 0x8C9A, 0xD88D,
+	0x8C9B, 0xD88E, 0x8C9C, 0xD88F, 0x8C9D, 0xD890, 0x8C9E, 0xD891,
+	0x8C9F, 0xD892, 0x8CA0, 0xD893, 0x8CA1, 0xD894, 0x8CA2, 0xD895,
+	0x8CA3, 0xD896, 0x8CA4, 0xD897, 0x8CA5, 0xD898, 0x8CA6, 0xD899,
+	0x8CA7, 0xD89A, 0x8CA8, 0xD89B, 0x8CA9, 0xD89C, 0x8CAA, 0xD89D,
+	0x8CAB, 0xD89E, 0x8CAC, 0xD89F, 0x8CAD, 0xD8A0, 0x8CAE, 0xD940,
+	0x8CAF, 0xD941, 0x8CB0, 0xD942, 0x8CB1, 0xD943, 0x8CB2, 0xD944,
+	0x8CB3, 0xD945, 0x8CB4, 0xD946, 0x8CB5, 0xD947, 0x8CB6, 0xD948,
+	0x8CB7, 0xD949, 0x8CB8, 0xD94A, 0x8CB9, 0xD94B, 0x8CBA, 0xD94C,
+	0x8CBB, 0xD94D, 0x8CBC, 0xD94E, 0x8CBD, 0xD94F, 0x8CBE, 0xD950,
+	0x8CBF, 0xD951, 0x8CC0, 0xD952, 0x8CC1, 0xD953, 0x8CC2, 0xD954,
+	0x8CC3, 0xD955, 0x8CC4, 0xD956, 0x8CC5, 0xD957, 0x8CC6, 0xD958,
+	0x8CC7, 0xD959, 0x8CC8, 0xD95A, 0x8CC9, 0xD95B, 0x8CCA, 0xD95C,
+	0x8CCB, 0xD95D, 0x8CCC, 0xD95E, 0x8CCD, 0xD95F, 0x8CCE, 0xD960,
+	0x8CCF, 0xD961, 0x8CD0, 0xD962, 0x8CD1, 0xD963, 0x8CD2, 0xD964,
+	0x8CD3, 0xD965, 0x8CD4, 0xD966, 0x8CD5, 0xD967, 0x8CD6, 0xD968,
+	0x8CD7, 0xD969, 0x8CD8, 0xD96A, 0x8CD9, 0xD96B, 0x8CDA, 0xD96C,
+	0x8CDB, 0xD96D, 0x8CDC, 0xD96E, 0x8CDD, 0xD96F, 0x8CDE, 0xD970,
+	0x8CDF, 0xD971, 0x8CE0, 0xD972, 0x8CE1, 0xD973, 0x8CE2, 0xD974,
+	0x8CE3, 0xD975, 0x8CE4, 0xD976, 0x8CE5, 0xD977, 0x8CE6, 0xD978,
+	0x8CE7, 0xD979, 0x8CE8, 0xD97A, 0x8CE9, 0xD97B, 0x8CEA, 0xD97C,
+	0x8CEB, 0xD97D, 0x8CEC, 0xD97E, 0x8CED, 0xD980, 0x8CEE, 0xD981,
+	0x8CEF, 0xD982, 0x8CF0, 0xD983, 0x8CF1, 0xD984, 0x8CF2, 0xD985,
+	0x8CF3, 0xD986, 0x8CF4, 0xD987, 0x8CF5, 0xD988, 0x8CF6, 0xD989,
+	0x8CF7, 0xD98A, 0x8CF8, 0xD98B, 0x8CF9, 0xD98C, 0x8CFA, 0xD98D,
+	0x8CFB, 0xD98E, 0x8CFC, 0xD98F, 0x8CFD, 0xD990, 0x8CFE, 0xD991,
+	0x8CFF, 0xD992, 0x8D00, 0xD993, 0x8D01, 0xD994, 0x8D02, 0xD995,
+	0x8D03, 0xD996, 0x8D04, 0xD997, 0x8D05, 0xD998, 0x8D06, 0xD999,
+	0x8D07, 0xD99A, 0x8D08, 0xD99B, 0x8D09, 0xD99C, 0x8D0A, 0xD99D,
+	0x8D0B, 0xD99E, 0x8D0C, 0xD99F, 0x8D0D, 0xD9A0, 0x8D0E, 0xDA40,
+	0x8D0F, 0xDA41, 0x8D10, 0xDA42, 0x8D11, 0xDA43, 0x8D12, 0xDA44,
+	0x8D13, 0xDA45, 0x8D14, 0xDA46, 0x8D15, 0xDA47, 0x8D16, 0xDA48,
+	0x8D17, 0xDA49, 0x8D18, 0xDA4A, 0x8D19, 0xDA4B, 0x8D1A, 0xDA4C,
+	0x8D1B, 0xDA4D, 0x8D1C, 0xDA4E, 0x8D1D, 0xB1B4, 0x8D1E, 0xD5EA,
+	0x8D1F, 0xB8BA, 0x8D20, 0xDA4F, 0x8D21, 0xB9B1, 0x8D22, 0xB2C6,
+	0x8D23, 0xD4F0, 0x8D24, 0xCFCD, 0x8D25, 0xB0DC, 0x8D26, 0xD5CB,
+	0x8D27, 0xBBF5, 0x8D28, 0xD6CA, 0x8D29, 0xB7B7, 0x8D2A, 0xCCB0,
+	0x8D2B, 0xC6B6, 0x8D2C, 0xB1E1, 0x8D2D, 0xB9BA, 0x8D2E, 0xD6FC,
+	0x8D2F, 0xB9E1, 0x8D30, 0xB7A1, 0x8D31, 0xBCFA, 0x8D32, 0xEADA,
+	0x8D33, 0xEADB, 0x8D34, 0xCCF9, 0x8D35, 0xB9F3, 0x8D36, 0xEADC,
+	0x8D37, 0xB4FB, 0x8D38, 0xC3B3, 0x8D39, 0xB7D1, 0x8D3A, 0xBAD8,
+	0x8D3B, 0xEADD, 0x8D3C, 0xD4F4, 0x8D3D, 0xEADE, 0x8D3E, 0xBCD6,
+	0x8D3F, 0xBBDF, 0x8D40, 0xEADF, 0x8D41, 0xC1DE, 0x8D42, 0xC2B8,
+	0x8D43, 0xD4DF, 0x8D44, 0xD7CA, 0x8D45, 0xEAE0, 0x8D46, 0xEAE1,
+	0x8D47, 0xEAE4, 0x8D48, 0xEAE2, 0x8D49, 0xEAE3, 0x8D4A, 0xC9DE,
+	0x8D4B, 0xB8B3, 0x8D4C, 0xB6C4, 0x8D4D, 0xEAE5, 0x8D4E, 0xCAEA,
+	0x8D4F, 0xC9CD, 0x8D50, 0xB4CD, 0x8D51, 0xDA50, 0x8D52, 0xDA51,
+	0x8D53, 0xE2D9, 0x8D54, 0xC5E2, 0x8D55, 0xEAE6, 0x8D56, 0xC0B5,
+	0x8D57, 0xDA52, 0x8D58, 0xD7B8, 0x8D59, 0xEAE7, 0x8D5A, 0xD7AC,
+	0x8D5B, 0xC8FC, 0x8D5C, 0xD8D3, 0x8D5D, 0xD8CD, 0x8D5E, 0xD4DE,
+	0x8D5F, 0xDA53, 0x8D60, 0xD4F9, 0x8D61, 0xC9C4, 0x8D62, 0xD3AE,
+	0x8D63, 0xB8D3, 0x8D64, 0xB3E0, 0x8D65, 0xDA54, 0x8D66, 0xC9E2,
+	0x8D67, 0xF4F6, 0x8D68, 0xDA55, 0x8D69, 0xDA56, 0x8D6A, 0xDA57,
+	0x8D6B, 0xBAD5, 0x8D6C, 0xDA58, 0x8D6D, 0xF4F7, 0x8D6E, 0xDA59,
+	0x8D6F, 0xDA5A, 0x8D70, 0xD7DF, 0x8D71, 0xDA5B, 0x8D72, 0xDA5C,
+	0x8D73, 0xF4F1, 0x8D74, 0xB8B0, 0x8D75, 0xD5D4, 0x8D76, 0xB8CF,
+	0x8D77, 0xC6F0, 0x8D78, 0xDA5D, 0x8D79, 0xDA5E, 0x8D7A, 0xDA5F,
+	0x8D7B, 0xDA60, 0x8D7C, 0xDA61, 0x8D7D, 0xDA62, 0x8D7E, 0xDA63,
+	0x8D7F, 0xDA64, 0x8D80, 0xDA65, 0x8D81, 0xB3C3, 0x8D82, 0xDA66,
+	0x8D83, 0xDA67, 0x8D84, 0xF4F2, 0x8D85, 0xB3AC, 0x8D86, 0xDA68,
+	0x8D87, 0xDA69, 0x8D88, 0xDA6A, 0x8D89, 0xDA6B, 0x8D8A, 0xD4BD,
+	0x8D8B, 0xC7F7, 0x8D8C, 0xDA6C, 0x8D8D, 0xDA6D, 0x8D8E, 0xDA6E,
+	0x8D8F, 0xDA6F, 0x8D90, 0xDA70, 0x8D91, 0xF4F4, 0x8D92, 0xDA71,
+	0x8D93, 0xDA72, 0x8D94, 0xF4F3, 0x8D95, 0xDA73, 0x8D96, 0xDA74,
+	0x8D97, 0xDA75, 0x8D98, 0xDA76, 0x8D99, 0xDA77, 0x8D9A, 0xDA78,
+	0x8D9B, 0xDA79, 0x8D9C, 0xDA7A, 0x8D9D, 0xDA7B, 0x8D9E, 0xDA7C,
+	0x8D9F, 0xCCCB, 0x8DA0, 0xDA7D, 0x8DA1, 0xDA7E, 0x8DA2, 0xDA80,
+	0x8DA3, 0xC8A4, 0x8DA4, 0xDA81, 0x8DA5, 0xDA82, 0x8DA6, 0xDA83,
+	0x8DA7, 0xDA84, 0x8DA8, 0xDA85, 0x8DA9, 0xDA86, 0x8DAA, 0xDA87,
+	0x8DAB, 0xDA88, 0x8DAC, 0xDA89, 0x8DAD, 0xDA8A, 0x8DAE, 0xDA8B,
+	0x8DAF, 0xDA8C, 0x8DB0, 0xDA8D, 0x8DB1, 0xF4F5, 0x8DB2, 0xDA8E,
+	0x8DB3, 0xD7E3, 0x8DB4, 0xC5BF, 0x8DB5, 0xF5C0, 0x8DB6, 0xDA8F,
+	0x8DB7, 0xDA90, 0x8DB8, 0xF5BB, 0x8DB9, 0xDA91, 0x8DBA, 0xF5C3,
+	0x8DBB, 0xDA92, 0x8DBC, 0xF5C2, 0x8DBD, 0xDA93, 0x8DBE, 0xD6BA,
+	0x8DBF, 0xF5C1, 0x8DC0, 0xDA94, 0x8DC1, 0xDA95, 0x8DC2, 0xDA96,
+	0x8DC3, 0xD4BE, 0x8DC4, 0xF5C4, 0x8DC5, 0xDA97, 0x8DC6, 0xF5CC,
+	0x8DC7, 0xDA98, 0x8DC8, 0xDA99, 0x8DC9, 0xDA9A, 0x8DCA, 0xDA9B,
+	0x8DCB, 0xB0CF, 0x8DCC, 0xB5F8, 0x8DCD, 0xDA9C, 0x8DCE, 0xF5C9,
+	0x8DCF, 0xF5CA, 0x8DD0, 0xDA9D, 0x8DD1, 0xC5DC, 0x8DD2, 0xDA9E,
+	0x8DD3, 0xDA9F, 0x8DD4, 0xDAA0, 0x8DD5, 0xDB40, 0x8DD6, 0xF5C5,
+	0x8DD7, 0xF5C6, 0x8DD8, 0xDB41, 0x8DD9, 0xDB42, 0x8DDA, 0xF5C7,
+	0x8DDB, 0xF5CB, 0x8DDC, 0xDB43, 0x8DDD, 0xBEE0, 0x8DDE, 0xF5C8,
+	0x8DDF, 0xB8FA, 0x8DE0, 0xDB44, 0x8DE1, 0xDB45, 0x8DE2, 0xDB46,
+	0x8DE3, 0xF5D0, 0x8DE4, 0xF5D3, 0x8DE5, 0xDB47, 0x8DE6, 0xDB48,
+	0x8DE7, 0xDB49, 0x8DE8, 0xBFE7, 0x8DE9, 0xDB4A, 0x8DEA, 0xB9F2,
+	0x8DEB, 0xF5BC, 0x8DEC, 0xF5CD, 0x8DED, 0xDB4B, 0x8DEE, 0xDB4C,
+	0x8DEF, 0xC2B7, 0x8DF0, 0xDB4D, 0x8DF1, 0xDB4E, 0x8DF2, 0xDB4F,
+	0x8DF3, 0xCCF8, 0x8DF4, 0xDB50, 0x8DF5, 0xBCF9, 0x8DF6, 0xDB51,
+	0x8DF7, 0xF5CE, 0x8DF8, 0xF5CF, 0x8DF9, 0xF5D1, 0x8DFA, 0xB6E5,
+	0x8DFB, 0xF5D2, 0x8DFC, 0xDB52, 0x8DFD, 0xF5D5, 0x8DFE, 0xDB53,
+	0x8DFF, 0xDB54, 0x8E00, 0xDB55, 0x8E01, 0xDB56, 0x8E02, 0xDB57,
+	0x8E03, 0xDB58, 0x8E04, 0xDB59, 0x8E05, 0xF5BD, 0x8E06, 0xDB5A,
+	0x8E07, 0xDB5B, 0x8E08, 0xDB5C, 0x8E09, 0xF5D4, 0x8E0A, 0xD3BB,
+	0x8E0B, 0xDB5D, 0x8E0C, 0xB3EC, 0x8E0D, 0xDB5E, 0x8E0E, 0xDB5F,
+	0x8E0F, 0xCCA4, 0x8E10, 0xDB60, 0x8E11, 0xDB61, 0x8E12, 0xDB62,
+	0x8E13, 0xDB63, 0x8E14, 0xF5D6, 0x8E15, 0xDB64, 0x8E16, 0xDB65,
+	0x8E17, 0xDB66, 0x8E18, 0xDB67, 0x8E19, 0xDB68, 0x8E1A, 0xDB69,
+	0x8E1B, 0xDB6A, 0x8E1C, 0xDB6B, 0x8E1D, 0xF5D7, 0x8E1E, 0xBEE1,
+	0x8E1F, 0xF5D8, 0x8E20, 0xDB6C, 0x8E21, 0xDB6D, 0x8E22, 0xCCDF,
+	0x8E23, 0xF5DB, 0x8E24, 0xDB6E, 0x8E25, 0xDB6F, 0x8E26, 0xDB70,
+	0x8E27, 0xDB71, 0x8E28, 0xDB72, 0x8E29, 0xB2C8, 0x8E2A, 0xD7D9,
+	0x8E2B, 0xDB73, 0x8E2C, 0xF5D9, 0x8E2D, 0xDB74, 0x8E2E, 0xF5DA,
+	0x8E2F, 0xF5DC, 0x8E30, 0xDB75, 0x8E31, 0xF5E2, 0x8E32, 0xDB76,
+	0x8E33, 0xDB77, 0x8E34, 0xDB78, 0x8E35, 0xF5E0, 0x8E36, 0xDB79,
+	0x8E37, 0xDB7A, 0x8E38, 0xDB7B, 0x8E39, 0xF5DF, 0x8E3A, 0xF5DD,
+	0x8E3B, 0xDB7C, 0x8E3C, 0xDB7D, 0x8E3D, 0xF5E1, 0x8E3E, 0xDB7E,
+	0x8E3F, 0xDB80, 0x8E40, 0xF5DE, 0x8E41, 0xF5E4, 0x8E42, 0xF5E5,
+	0x8E43, 0xDB81, 0x8E44, 0xCCE3, 0x8E45, 0xDB82, 0x8E46, 0xDB83,
+	0x8E47, 0xE5BF, 0x8E48, 0xB5B8, 0x8E49, 0xF5E3, 0x8E4A, 0xF5E8,
+	0x8E4B, 0xCCA3, 0x8E4C, 0xDB84, 0x8E4D, 0xDB85, 0x8E4E, 0xDB86,
+	0x8E4F, 0xDB87, 0x8E50, 0xDB88, 0x8E51, 0xF5E6, 0x8E52, 0xF5E7,
+	0x8E53, 0xDB89, 0x8E54, 0xDB8A, 0x8E55, 0xDB8B, 0x8E56, 0xDB8C,
+	0x8E57, 0xDB8D, 0x8E58, 0xDB8E, 0x8E59, 0xF5BE, 0x8E5A, 0xDB8F,
+	0x8E5B, 0xDB90, 0x8E5C, 0xDB91, 0x8E5D, 0xDB92, 0x8E5E, 0xDB93,
+	0x8E5F, 0xDB94, 0x8E60, 0xDB95, 0x8E61, 0xDB96, 0x8E62, 0xDB97,
+	0x8E63, 0xDB98, 0x8E64, 0xDB99, 0x8E65, 0xDB9A, 0x8E66, 0xB1C4,
+	0x8E67, 0xDB9B, 0x8E68, 0xDB9C, 0x8E69, 0xF5BF, 0x8E6A, 0xDB9D,
+	0x8E6B, 0xDB9E, 0x8E6C, 0xB5C5, 0x8E6D, 0xB2E4, 0x8E6E, 0xDB9F,
+	0x8E6F, 0xF5EC, 0x8E70, 0xF5E9, 0x8E71, 0xDBA0, 0x8E72, 0xB6D7,
+	0x8E73, 0xDC40, 0x8E74, 0xF5ED, 0x8E75, 0xDC41, 0x8E76, 0xF5EA,
+	0x8E77, 0xDC42, 0x8E78, 0xDC43, 0x8E79, 0xDC44, 0x8E7A, 0xDC45,
+	0x8E7B, 0xDC46, 0x8E7C, 0xF5EB, 0x8E7D, 0xDC47, 0x8E7E, 0xDC48,
+	0x8E7F, 0xB4DA, 0x8E80, 0xDC49, 0x8E81, 0xD4EA, 0x8E82, 0xDC4A,
+	0x8E83, 0xDC4B, 0x8E84, 0xDC4C, 0x8E85, 0xF5EE, 0x8E86, 0xDC4D,
+	0x8E87, 0xB3F9, 0x8E88, 0xDC4E, 0x8E89, 0xDC4F, 0x8E8A, 0xDC50,
+	0x8E8B, 0xDC51, 0x8E8C, 0xDC52, 0x8E8D, 0xDC53, 0x8E8E, 0xDC54,
+	0x8E8F, 0xF5EF, 0x8E90, 0xF5F1, 0x8E91, 0xDC55, 0x8E92, 0xDC56,
+	0x8E93, 0xDC57, 0x8E94, 0xF5F0, 0x8E95, 0xDC58, 0x8E96, 0xDC59,
+	0x8E97, 0xDC5A, 0x8E98, 0xDC5B, 0x8E99, 0xDC5C, 0x8E9A, 0xDC5D,
+	0x8E9B, 0xDC5E, 0x8E9C, 0xF5F2, 0x8E9D, 0xDC5F, 0x8E9E, 0xF5F3,
+	0x8E9F, 0xDC60, 0x8EA0, 0xDC61, 0x8EA1, 0xDC62, 0x8EA2, 0xDC63,
+	0x8EA3, 0xDC64, 0x8EA4, 0xDC65, 0x8EA5, 0xDC66, 0x8EA6, 0xDC67,
+	0x8EA7, 0xDC68, 0x8EA8, 0xDC69, 0x8EA9, 0xDC6A, 0x8EAA, 0xDC6B,
+	0x8EAB, 0xC9ED, 0x8EAC, 0xB9AA, 0x8EAD, 0xDC6C, 0x8EAE, 0xDC6D,
+	0x8EAF, 0xC7FB, 0x8EB0, 0xDC6E, 0x8EB1, 0xDC6F, 0x8EB2, 0xB6E3,
+	0x8EB3, 0xDC70, 0x8EB4, 0xDC71, 0x8EB5, 0xDC72, 0x8EB6, 0xDC73,
+	0x8EB7, 0xDC74, 0x8EB8, 0xDC75, 0x8EB9, 0xDC76, 0x8EBA, 0xCCC9,
+	0x8EBB, 0xDC77, 0x8EBC, 0xDC78, 0x8EBD, 0xDC79, 0x8EBE, 0xDC7A,
+	0x8EBF, 0xDC7B, 0x8EC0, 0xDC7C, 0x8EC1, 0xDC7D, 0x8EC2, 0xDC7E,
+	0x8EC3, 0xDC80, 0x8EC4, 0xDC81, 0x8EC5, 0xDC82, 0x8EC6, 0xDC83,
+	0x8EC7, 0xDC84, 0x8EC8, 0xDC85, 0x8EC9, 0xDC86, 0x8ECA, 0xDC87,
+	0x8ECB, 0xDC88, 0x8ECC, 0xDC89, 0x8ECD, 0xDC8A, 0x8ECE, 0xEAA6,
+	0x8ECF, 0xDC8B, 0x8ED0, 0xDC8C, 0x8ED1, 0xDC8D, 0x8ED2, 0xDC8E,
+	0x8ED3, 0xDC8F, 0x8ED4, 0xDC90, 0x8ED5, 0xDC91, 0x8ED6, 0xDC92,
+	0x8ED7, 0xDC93, 0x8ED8, 0xDC94, 0x8ED9, 0xDC95, 0x8EDA, 0xDC96,
+	0x8EDB, 0xDC97, 0x8EDC, 0xDC98, 0x8EDD, 0xDC99, 0x8EDE, 0xDC9A,
+	0x8EDF, 0xDC9B, 0x8EE0, 0xDC9C, 0x8EE1, 0xDC9D, 0x8EE2, 0xDC9E,
+	0x8EE3, 0xDC9F, 0x8EE4, 0xDCA0, 0x8EE5, 0xDD40, 0x8EE6, 0xDD41,
+	0x8EE7, 0xDD42, 0x8EE8, 0xDD43, 0x8EE9, 0xDD44, 0x8EEA, 0xDD45,
+	0x8EEB, 0xDD46, 0x8EEC, 0xDD47, 0x8EED, 0xDD48, 0x8EEE, 0xDD49,
+	0x8EEF, 0xDD4A, 0x8EF0, 0xDD4B, 0x8EF1, 0xDD4C, 0x8EF2, 0xDD4D,
+	0x8EF3, 0xDD4E, 0x8EF4, 0xDD4F, 0x8EF5, 0xDD50, 0x8EF6, 0xDD51,
+	0x8EF7, 0xDD52, 0x8EF8, 0xDD53, 0x8EF9, 0xDD54, 0x8EFA, 0xDD55,
+	0x8EFB, 0xDD56, 0x8EFC, 0xDD57, 0x8EFD, 0xDD58, 0x8EFE, 0xDD59,
+	0x8EFF, 0xDD5A, 0x8F00, 0xDD5B, 0x8F01, 0xDD5C, 0x8F02, 0xDD5D,
+	0x8F03, 0xDD5E, 0x8F04, 0xDD5F, 0x8F05, 0xDD60, 0x8F06, 0xDD61,
+	0x8F07, 0xDD62, 0x8F08, 0xDD63, 0x8F09, 0xDD64, 0x8F0A, 0xDD65,
+	0x8F0B, 0xDD66, 0x8F0C, 0xDD67, 0x8F0D, 0xDD68, 0x8F0E, 0xDD69,
+	0x8F0F, 0xDD6A, 0x8F10, 0xDD6B, 0x8F11, 0xDD6C, 0x8F12, 0xDD6D,
+	0x8F13, 0xDD6E, 0x8F14, 0xDD6F, 0x8F15, 0xDD70, 0x8F16, 0xDD71,
+	0x8F17, 0xDD72, 0x8F18, 0xDD73, 0x8F19, 0xDD74, 0x8F1A, 0xDD75,
+	0x8F1B, 0xDD76, 0x8F1C, 0xDD77, 0x8F1D, 0xDD78, 0x8F1E, 0xDD79,
+	0x8F1F, 0xDD7A, 0x8F20, 0xDD7B, 0x8F21, 0xDD7C, 0x8F22, 0xDD7D,
+	0x8F23, 0xDD7E, 0x8F24, 0xDD80, 0x8F25, 0xDD81, 0x8F26, 0xDD82,
+	0x8F27, 0xDD83, 0x8F28, 0xDD84, 0x8F29, 0xDD85, 0x8F2A, 0xDD86,
+	0x8F2B, 0xDD87, 0x8F2C, 0xDD88, 0x8F2D, 0xDD89, 0x8F2E, 0xDD8A,
+	0x8F2F, 0xDD8B, 0x8F30, 0xDD8C, 0x8F31, 0xDD8D, 0x8F32, 0xDD8E,
+	0x8F33, 0xDD8F, 0x8F34, 0xDD90, 0x8F35, 0xDD91, 0x8F36, 0xDD92,
+	0x8F37, 0xDD93, 0x8F38, 0xDD94, 0x8F39, 0xDD95, 0x8F3A, 0xDD96,
+	0x8F3B, 0xDD97, 0x8F3C, 0xDD98, 0x8F3D, 0xDD99, 0x8F3E, 0xDD9A,
+	0x8F3F, 0xDD9B, 0x8F40, 0xDD9C, 0x8F41, 0xDD9D, 0x8F42, 0xDD9E,
+	0x8F43, 0xDD9F, 0x8F44, 0xDDA0, 0x8F45, 0xDE40, 0x8F46, 0xDE41,
+	0x8F47, 0xDE42, 0x8F48, 0xDE43, 0x8F49, 0xDE44, 0x8F4A, 0xDE45,
+	0x8F4B, 0xDE46, 0x8F4C, 0xDE47, 0x8F4D, 0xDE48, 0x8F4E, 0xDE49,
+	0x8F4F, 0xDE4A, 0x8F50, 0xDE4B, 0x8F51, 0xDE4C, 0x8F52, 0xDE4D,
+	0x8F53, 0xDE4E, 0x8F54, 0xDE4F, 0x8F55, 0xDE50, 0x8F56, 0xDE51,
+	0x8F57, 0xDE52, 0x8F58, 0xDE53, 0x8F59, 0xDE54, 0x8F5A, 0xDE55,
+	0x8F5B, 0xDE56, 0x8F5C, 0xDE57, 0x8F5D, 0xDE58, 0x8F5E, 0xDE59,
+	0x8F5F, 0xDE5A, 0x8F60, 0xDE5B, 0x8F61, 0xDE5C, 0x8F62, 0xDE5D,
+	0x8F63, 0xDE5E, 0x8F64, 0xDE5F, 0x8F65, 0xDE60, 0x8F66, 0xB3B5,
+	0x8F67, 0xD4FE, 0x8F68, 0xB9EC, 0x8F69, 0xD0F9, 0x8F6A, 0xDE61,
+	0x8F6B, 0xE9ED, 0x8F6C, 0xD7AA, 0x8F6D, 0xE9EE, 0x8F6E, 0xC2D6,
+	0x8F6F, 0xC8ED, 0x8F70, 0xBAE4, 0x8F71, 0xE9EF, 0x8F72, 0xE9F0,
+	0x8F73, 0xE9F1, 0x8F74, 0xD6E1, 0x8F75, 0xE9F2, 0x8F76, 0xE9F3,
+	0x8F77, 0xE9F5, 0x8F78, 0xE9F4, 0x8F79, 0xE9F6, 0x8F7A, 0xE9F7,
+	0x8F7B, 0xC7E1, 0x8F7C, 0xE9F8, 0x8F7D, 0xD4D8, 0x8F7E, 0xE9F9,
+	0x8F7F, 0xBDCE, 0x8F80, 0xDE62, 0x8F81, 0xE9FA, 0x8F82, 0xE9FB,
+	0x8F83, 0xBDCF, 0x8F84, 0xE9FC, 0x8F85, 0xB8A8, 0x8F86, 0xC1BE,
+	0x8F87, 0xE9FD, 0x8F88, 0xB1B2, 0x8F89, 0xBBD4, 0x8F8A, 0xB9F5,
+	0x8F8B, 0xE9FE, 0x8F8C, 0xDE63, 0x8F8D, 0xEAA1, 0x8F8E, 0xEAA2,
+	0x8F8F, 0xEAA3, 0x8F90, 0xB7F8, 0x8F91, 0xBCAD, 0x8F92, 0xDE64,
+	0x8F93, 0xCAE4, 0x8F94, 0xE0CE, 0x8F95, 0xD4AF, 0x8F96, 0xCFBD,
+	0x8F97, 0xD5B7, 0x8F98, 0xEAA4, 0x8F99, 0xD5DE, 0x8F9A, 0xEAA5,
+	0x8F9B, 0xD0C1, 0x8F9C, 0xB9BC, 0x8F9D, 0xDE65, 0x8F9E, 0xB4C7,
+	0x8F9F, 0xB1D9, 0x8FA0, 0xDE66, 0x8FA1, 0xDE67, 0x8FA2, 0xDE68,
+	0x8FA3, 0xC0B1, 0x8FA4, 0xDE69, 0x8FA5, 0xDE6A, 0x8FA6, 0xDE6B,
+	0x8FA7, 0xDE6C, 0x8FA8, 0xB1E6, 0x8FA9, 0xB1E7, 0x8FAA, 0xDE6D,
+	0x8FAB, 0xB1E8, 0x8FAC, 0xDE6E, 0x8FAD, 0xDE6F, 0x8FAE, 0xDE70,
+	0x8FAF, 0xDE71, 0x8FB0, 0xB3BD, 0x8FB1, 0xC8E8, 0x8FB2, 0xDE72,
+	0x8FB3, 0xDE73, 0x8FB4, 0xDE74, 0x8FB5, 0xDE75, 0x8FB6, 0xE5C1,
+	0x8FB7, 0xDE76, 0x8FB8, 0xDE77, 0x8FB9, 0xB1DF, 0x8FBA, 0xDE78,
+	0x8FBB, 0xDE79, 0x8FBC, 0xDE7A, 0x8FBD, 0xC1C9, 0x8FBE, 0xB4EF,
+	0x8FBF, 0xDE7B, 0x8FC0, 0xDE7C, 0x8FC1, 0xC7A8, 0x8FC2, 0xD3D8,
+	0x8FC3, 0xDE7D, 0x8FC4, 0xC6F9, 0x8FC5, 0xD1B8, 0x8FC6, 0xDE7E,
+	0x8FC7, 0xB9FD, 0x8FC8, 0xC2F5, 0x8FC9, 0xDE80, 0x8FCA, 0xDE81,
+	0x8FCB, 0xDE82, 0x8FCC, 0xDE83, 0x8FCD, 0xDE84, 0x8FCE, 0xD3AD,
+	0x8FCF, 0xDE85, 0x8FD0, 0xD4CB, 0x8FD1, 0xBDFC, 0x8FD2, 0xDE86,
+	0x8FD3, 0xE5C2, 0x8FD4, 0xB7B5, 0x8FD5, 0xE5C3, 0x8FD6, 0xDE87,
+	0x8FD7, 0xDE88, 0x8FD8, 0xBBB9, 0x8FD9, 0xD5E2, 0x8FDA, 0xDE89,
+	0x8FDB, 0xBDF8, 0x8FDC, 0xD4B6, 0x8FDD, 0xCEA5, 0x8FDE, 0xC1AC,
+	0x8FDF, 0xB3D9, 0x8FE0, 0xDE8A, 0x8FE1, 0xDE8B, 0x8FE2, 0xCCF6,
+	0x8FE3, 0xDE8C, 0x8FE4, 0xE5C6, 0x8FE5, 0xE5C4, 0x8FE6, 0xE5C8,
+	0x8FE7, 0xDE8D, 0x8FE8, 0xE5CA, 0x8FE9, 0xE5C7, 0x8FEA, 0xB5CF,
+	0x8FEB, 0xC6C8, 0x8FEC, 0xDE8E, 0x8FED, 0xB5FC, 0x8FEE, 0xE5C5,
+	0x8FEF, 0xDE8F, 0x8FF0, 0xCAF6, 0x8FF1, 0xDE90, 0x8FF2, 0xDE91,
+	0x8FF3, 0xE5C9, 0x8FF4, 0xDE92, 0x8FF5, 0xDE93, 0x8FF6, 0xDE94,
+	0x8FF7, 0xC3D4, 0x8FF8, 0xB1C5, 0x8FF9, 0xBCA3, 0x8FFA, 0xDE95,
+	0x8FFB, 0xDE96, 0x8FFC, 0xDE97, 0x8FFD, 0xD7B7, 0x8FFE, 0xDE98,
+	0x8FFF, 0xDE99, 0x9000, 0xCDCB, 0x9001, 0xCBCD, 0x9002, 0xCACA,
+	0x9003, 0xCCD3, 0x9004, 0xE5CC, 0x9005, 0xE5CB, 0x9006, 0xC4E6,
+	0x9007, 0xDE9A, 0x9008, 0xDE9B, 0x9009, 0xD1A1, 0x900A, 0xD1B7,
+	0x900B, 0xE5CD, 0x900C, 0xDE9C, 0x900D, 0xE5D0, 0x900E, 0xDE9D,
+	0x900F, 0xCDB8, 0x9010, 0xD6F0, 0x9011, 0xE5CF, 0x9012, 0xB5DD,
+	0x9013, 0xDE9E, 0x9014, 0xCDBE, 0x9015, 0xDE9F, 0x9016, 0xE5D1,
+	0x9017, 0xB6BA, 0x9018, 0xDEA0, 0x9019, 0xDF40, 0x901A, 0xCDA8,
+	0x901B, 0xB9E4, 0x901C, 0xDF41, 0x901D, 0xCAC5, 0x901E, 0xB3D1,
+	0x901F, 0xCBD9, 0x9020, 0xD4EC, 0x9021, 0xE5D2, 0x9022, 0xB7EA,
+	0x9023, 0xDF42, 0x9024, 0xDF43, 0x9025, 0xDF44, 0x9026, 0xE5CE,
+	0x9027, 0xDF45, 0x9028, 0xDF46, 0x9029, 0xDF47, 0x902A, 0xDF48,
+	0x902B, 0xDF49, 0x902C, 0xDF4A, 0x902D, 0xE5D5, 0x902E, 0xB4FE,
+	0x902F, 0xE5D6, 0x9030, 0xDF4B, 0x9031, 0xDF4C, 0x9032, 0xDF4D,
+	0x9033, 0xDF4E, 0x9034, 0xDF4F, 0x9035, 0xE5D3, 0x9036, 0xE5D4,
+	0x9037, 0xDF50, 0x9038, 0xD2DD, 0x9039, 0xDF51, 0x903A, 0xDF52,
+	0x903B, 0xC2DF, 0x903C, 0xB1C6, 0x903D, 0xDF53, 0x903E, 0xD3E2,
+	0x903F, 0xDF54, 0x9040, 0xDF55, 0x9041, 0xB6DD, 0x9042, 0xCBEC,
+	0x9043, 0xDF56, 0x9044, 0xE5D7, 0x9045, 0xDF57, 0x9046, 0xDF58,
+	0x9047, 0xD3F6, 0x9048, 0xDF59, 0x9049, 0xDF5A, 0x904A, 0xDF5B,
+	0x904B, 0xDF5C, 0x904C, 0xDF5D, 0x904D, 0xB1E9, 0x904E, 0xDF5E,
+	0x904F, 0xB6F4, 0x9050, 0xE5DA, 0x9051, 0xE5D8, 0x9052, 0xE5D9,
+	0x9053, 0xB5C0, 0x9054, 0xDF5F, 0x9055, 0xDF60, 0x9056, 0xDF61,
+	0x9057, 0xD2C5, 0x9058, 0xE5DC, 0x9059, 0xDF62, 0x905A, 0xDF63,
+	0x905B, 0xE5DE, 0x905C, 0xDF64, 0x905D, 0xDF65, 0x905E, 0xDF66,
+	0x905F, 0xDF67, 0x9060, 0xDF68, 0x9061, 0xDF69, 0x9062, 0xE5DD,
+	0x9063, 0xC7B2, 0x9064, 0xDF6A, 0x9065, 0xD2A3, 0x9066, 0xDF6B,
+	0x9067, 0xDF6C, 0x9068, 0xE5DB, 0x9069, 0xDF6D, 0x906A, 0xDF6E,
+	0x906B, 0xDF6F, 0x906C, 0xDF70, 0x906D, 0xD4E2, 0x906E, 0xD5DA,
+	0x906F, 0xDF71, 0x9070, 0xDF72, 0x9071, 0xDF73, 0x9072, 0xDF74,
+	0x9073, 0xDF75, 0x9074, 0xE5E0, 0x9075, 0xD7F1, 0x9076, 0xDF76,
+	0x9077, 0xDF77, 0x9078, 0xDF78, 0x9079, 0xDF79, 0x907A, 0xDF7A,
+	0x907B, 0xDF7B, 0x907C, 0xDF7C, 0x907D, 0xE5E1, 0x907E, 0xDF7D,
+	0x907F, 0xB1DC, 0x9080, 0xD1FB, 0x9081, 0xDF7E, 0x9082, 0xE5E2,
+	0x9083, 0xE5E4, 0x9084, 0xDF80, 0x9085, 0xDF81, 0x9086, 0xDF82,
+	0x9087, 0xDF83, 0x9088, 0xE5E3, 0x9089, 0xDF84, 0x908A, 0xDF85,
+	0x908B, 0xE5E5, 0x908C, 0xDF86, 0x908D, 0xDF87, 0x908E, 0xDF88,
+	0x908F, 0xDF89, 0x9090, 0xDF8A, 0x9091, 0xD2D8, 0x9092, 0xDF8B,
+	0x9093, 0xB5CB, 0x9094, 0xDF8C, 0x9095, 0xE7DF, 0x9096, 0xDF8D,
+	0x9097, 0xDAF5, 0x9098, 0xDF8E, 0x9099, 0xDAF8, 0x909A, 0xDF8F,
+	0x909B, 0xDAF6, 0x909C, 0xDF90, 0x909D, 0xDAF7, 0x909E, 0xDF91,
+	0x909F, 0xDF92, 0x90A0, 0xDF93, 0x90A1, 0xDAFA, 0x90A2, 0xD0CF,
+	0x90A3, 0xC4C7, 0x90A4, 0xDF94, 0x90A5, 0xDF95, 0x90A6, 0xB0EE,
+	0x90A7, 0xDF96, 0x90A8, 0xDF97, 0x90A9, 0xDF98, 0x90AA, 0xD0B0,
+	0x90AB, 0xDF99, 0x90AC, 0xDAF9, 0x90AD, 0xDF9A, 0x90AE, 0xD3CA,
+	0x90AF, 0xBAAA, 0x90B0, 0xDBA2, 0x90B1, 0xC7F1, 0x90B2, 0xDF9B,
+	0x90B3, 0xDAFC, 0x90B4, 0xDAFB, 0x90B5, 0xC9DB, 0x90B6, 0xDAFD,
+	0x90B7, 0xDF9C, 0x90B8, 0xDBA1, 0x90B9, 0xD7DE, 0x90BA, 0xDAFE,
+	0x90BB, 0xC1DA, 0x90BC, 0xDF9D, 0x90BD, 0xDF9E, 0x90BE, 0xDBA5,
+	0x90BF, 0xDF9F, 0x90C0, 0xDFA0, 0x90C1, 0xD3F4, 0x90C2, 0xE040,
+	0x90C3, 0xE041, 0x90C4, 0xDBA7, 0x90C5, 0xDBA4, 0x90C6, 0xE042,
+	0x90C7, 0xDBA8, 0x90C8, 0xE043, 0x90C9, 0xE044, 0x90CA, 0xBDBC,
+	0x90CB, 0xE045, 0x90CC, 0xE046, 0x90CD, 0xE047, 0x90CE, 0xC0C9,
+	0x90CF, 0xDBA3, 0x90D0, 0xDBA6, 0x90D1, 0xD6A3, 0x90D2, 0xE048,
+	0x90D3, 0xDBA9, 0x90D4, 0xE049, 0x90D5, 0xE04A, 0x90D6, 0xE04B,
+	0x90D7, 0xDBAD, 0x90D8, 0xE04C, 0x90D9, 0xE04D, 0x90DA, 0xE04E,
+	0x90DB, 0xDBAE, 0x90DC, 0xDBAC, 0x90DD, 0xBAC2, 0x90DE, 0xE04F,
+	0x90DF, 0xE050, 0x90E0, 0xE051, 0x90E1, 0xBFA4, 0x90E2, 0xDBAB,
+	0x90E3, 0xE052, 0x90E4, 0xE053, 0x90E5, 0xE054, 0x90E6, 0xDBAA,
+	0x90E7, 0xD4C7, 0x90E8, 0xB2BF, 0x90E9, 0xE055, 0x90EA, 0xE056,
+	0x90EB, 0xDBAF, 0x90EC, 0xE057, 0x90ED, 0xB9F9, 0x90EE, 0xE058,
+	0x90EF, 0xDBB0, 0x90F0, 0xE059, 0x90F1, 0xE05A, 0x90F2, 0xE05B,
+	0x90F3, 0xE05C, 0x90F4, 0xB3BB, 0x90F5, 0xE05D, 0x90F6, 0xE05E,
+	0x90F7, 0xE05F, 0x90F8, 0xB5A6, 0x90F9, 0xE060, 0x90FA, 0xE061,
+	0x90FB, 0xE062, 0x90FC, 0xE063, 0x90FD, 0xB6BC, 0x90FE, 0xDBB1,
+	0x90FF, 0xE064, 0x9100, 0xE065, 0x9101, 0xE066, 0x9102, 0xB6F5,
+	0x9103, 0xE067, 0x9104, 0xDBB2, 0x9105, 0xE068, 0x9106, 0xE069,
+	0x9107, 0xE06A, 0x9108, 0xE06B, 0x9109, 0xE06C, 0x910A, 0xE06D,
+	0x910B, 0xE06E, 0x910C, 0xE06F, 0x910D, 0xE070, 0x910E, 0xE071,
+	0x910F, 0xE072, 0x9110, 0xE073, 0x9111, 0xE074, 0x9112, 0xE075,
+	0x9113, 0xE076, 0x9114, 0xE077, 0x9115, 0xE078, 0x9116, 0xE079,
+	0x9117, 0xE07A, 0x9118, 0xE07B, 0x9119, 0xB1C9, 0x911A, 0xE07C,
+	0x911B, 0xE07D, 0x911C, 0xE07E, 0x911D, 0xE080, 0x911E, 0xDBB4,
+	0x911F, 0xE081, 0x9120, 0xE082, 0x9121, 0xE083, 0x9122, 0xDBB3,
+	0x9123, 0xDBB5, 0x9124, 0xE084, 0x9125, 0xE085, 0x9126, 0xE086,
+	0x9127, 0xE087, 0x9128, 0xE088, 0x9129, 0xE089, 0x912A, 0xE08A,
+	0x912B, 0xE08B, 0x912C, 0xE08C, 0x912D, 0xE08D, 0x912E, 0xE08E,
+	0x912F, 0xDBB7, 0x9130, 0xE08F, 0x9131, 0xDBB6, 0x9132, 0xE090,
+	0x9133, 0xE091, 0x9134, 0xE092, 0x9135, 0xE093, 0x9136, 0xE094,
+	0x9137, 0xE095, 0x9138, 0xE096, 0x9139, 0xDBB8, 0x913A, 0xE097,
+	0x913B, 0xE098, 0x913C, 0xE099, 0x913D, 0xE09A, 0x913E, 0xE09B,
+	0x913F, 0xE09C, 0x9140, 0xE09D, 0x9141, 0xE09E, 0x9142, 0xE09F,
+	0x9143, 0xDBB9, 0x9144, 0xE0A0, 0x9145, 0xE140, 0x9146, 0xDBBA,
+	0x9147, 0xE141, 0x9148, 0xE142, 0x9149, 0xD3CF, 0x914A, 0xF4FA,
+	0x914B, 0xC7F5, 0x914C, 0xD7C3, 0x914D, 0xC5E4, 0x914E, 0xF4FC,
+	0x914F, 0xF4FD, 0x9150, 0xF4FB, 0x9151, 0xE143, 0x9152, 0xBEC6,
+	0x9153, 0xE144, 0x9154, 0xE145, 0x9155, 0xE146, 0x9156, 0xE147,
+	0x9157, 0xD0EF, 0x9158, 0xE148, 0x9159, 0xE149, 0x915A, 0xB7D3,
+	0x915B, 0xE14A, 0x915C, 0xE14B, 0x915D, 0xD4CD, 0x915E, 0xCCAA,
+	0x915F, 0xE14C, 0x9160, 0xE14D, 0x9161, 0xF5A2, 0x9162, 0xF5A1,
+	0x9163, 0xBAA8, 0x9164, 0xF4FE, 0x9165, 0xCBD6, 0x9166, 0xE14E,
+	0x9167, 0xE14F, 0x9168, 0xE150, 0x9169, 0xF5A4, 0x916A, 0xC0D2,
+	0x916B, 0xE151, 0x916C, 0xB3EA, 0x916D, 0xE152, 0x916E, 0xCDAA,
+	0x916F, 0xF5A5, 0x9170, 0xF5A3, 0x9171, 0xBDB4, 0x9172, 0xF5A8,
+	0x9173, 0xE153, 0x9174, 0xF5A9, 0x9175, 0xBDCD, 0x9176, 0xC3B8,
+	0x9177, 0xBFE1, 0x9178, 0xCBE1, 0x9179, 0xF5AA, 0x917A, 0xE154,
+	0x917B, 0xE155, 0x917C, 0xE156, 0x917D, 0xF5A6, 0x917E, 0xF5A7,
+	0x917F, 0xC4F0, 0x9180, 0xE157, 0x9181, 0xE158, 0x9182, 0xE159,
+	0x9183, 0xE15A, 0x9184, 0xE15B, 0x9185, 0xF5AC, 0x9186, 0xE15C,
+	0x9187, 0xB4BC, 0x9188, 0xE15D, 0x9189, 0xD7ED, 0x918A, 0xE15E,
+	0x918B, 0xB4D7, 0x918C, 0xF5AB, 0x918D, 0xF5AE, 0x918E, 0xE15F,
+	0x918F, 0xE160, 0x9190, 0xF5AD, 0x9191, 0xF5AF, 0x9192, 0xD0D1,
+	0x9193, 0xE161, 0x9194, 0xE162, 0x9195, 0xE163, 0x9196, 0xE164,
+	0x9197, 0xE165, 0x9198, 0xE166, 0x9199, 0xE167, 0x919A, 0xC3D1,
+	0x919B, 0xC8A9, 0x919C, 0xE168, 0x919D, 0xE169, 0x919E, 0xE16A,
+	0x919F, 0xE16B, 0x91A0, 0xE16C, 0x91A1, 0xE16D, 0x91A2, 0xF5B0,
+	0x91A3, 0xF5B1, 0x91A4, 0xE16E, 0x91A5, 0xE16F, 0x91A6, 0xE170,
+	0x91A7, 0xE171, 0x91A8, 0xE172, 0x91A9, 0xE173, 0x91AA, 0xF5B2,
+	0x91AB, 0xE174, 0x91AC, 0xE175, 0x91AD, 0xF5B3, 0x91AE, 0xF5B4,
+	0x91AF, 0xF5B5, 0x91B0, 0xE176, 0x91B1, 0xE177, 0x91B2, 0xE178,
+	0x91B3, 0xE179, 0x91B4, 0xF5B7, 0x91B5, 0xF5B6, 0x91B6, 0xE17A,
+	0x91B7, 0xE17B, 0x91B8, 0xE17C, 0x91B9, 0xE17D, 0x91BA, 0xF5B8,
+	0x91BB, 0xE17E, 0x91BC, 0xE180, 0x91BD, 0xE181, 0x91BE, 0xE182,
+	0x91BF, 0xE183, 0x91C0, 0xE184, 0x91C1, 0xE185, 0x91C2, 0xE186,
+	0x91C3, 0xE187, 0x91C4, 0xE188, 0x91C5, 0xE189, 0x91C6, 0xE18A,
+	0x91C7, 0xB2C9, 0x91C8, 0xE18B, 0x91C9, 0xD3D4, 0x91CA, 0xCACD,
+	0x91CB, 0xE18C, 0x91CC, 0xC0EF, 0x91CD, 0xD6D8, 0x91CE, 0xD2B0,
+	0x91CF, 0xC1BF, 0x91D0, 0xE18D, 0x91D1, 0xBDF0, 0x91D2, 0xE18E,
+	0x91D3, 0xE18F, 0x91D4, 0xE190, 0x91D5, 0xE191, 0x91D6, 0xE192,
+	0x91D7, 0xE193, 0x91D8, 0xE194, 0x91D9, 0xE195, 0x91DA, 0xE196,
+	0x91DB, 0xE197, 0x91DC, 0xB8AA, 0x91DD, 0xE198, 0x91DE, 0xE199,
+	0x91DF, 0xE19A, 0x91E0, 0xE19B, 0x91E1, 0xE19C, 0x91E2, 0xE19D,
+	0x91E3, 0xE19E, 0x91E4, 0xE19F, 0x91E5, 0xE1A0, 0x91E6, 0xE240,
+	0x91E7, 0xE241, 0x91E8, 0xE242, 0x91E9, 0xE243, 0x91EA, 0xE244,
+	0x91EB, 0xE245, 0x91EC, 0xE246, 0x91ED, 0xE247, 0x91EE, 0xE248,
+	0x91EF, 0xE249, 0x91F0, 0xE24A, 0x91F1, 0xE24B, 0x91F2, 0xE24C,
+	0x91F3, 0xE24D, 0x91F4, 0xE24E, 0x91F5, 0xE24F, 0x91F6, 0xE250,
+	0x91F7, 0xE251, 0x91F8, 0xE252, 0x91F9, 0xE253, 0x91FA, 0xE254,
+	0x91FB, 0xE255, 0x91FC, 0xE256, 0x91FD, 0xE257, 0x91FE, 0xE258,
+	0x91FF, 0xE259, 0x9200, 0xE25A, 0x9201, 0xE25B, 0x9202, 0xE25C,
+	0x9203, 0xE25D, 0x9204, 0xE25E, 0x9205, 0xE25F, 0x9206, 0xE260,
+	0x9207, 0xE261, 0x9208, 0xE262, 0x9209, 0xE263, 0x920A, 0xE264,
+	0x920B, 0xE265, 0x920C, 0xE266, 0x920D, 0xE267, 0x920E, 0xE268,
+	0x920F, 0xE269, 0x9210, 0xE26A, 0x9211, 0xE26B, 0x9212, 0xE26C,
+	0x9213, 0xE26D, 0x9214, 0xE26E, 0x9215, 0xE26F, 0x9216, 0xE270,
+	0x9217, 0xE271, 0x9218, 0xE272, 0x9219, 0xE273, 0x921A, 0xE274,
+	0x921B, 0xE275, 0x921C, 0xE276, 0x921D, 0xE277, 0x921E, 0xE278,
+	0x921F, 0xE279, 0x9220, 0xE27A, 0x9221, 0xE27B, 0x9222, 0xE27C,
+	0x9223, 0xE27D, 0x9224, 0xE27E, 0x9225, 0xE280, 0x9226, 0xE281,
+	0x9227, 0xE282, 0x9228, 0xE283, 0x9229, 0xE284, 0x922A, 0xE285,
+	0x922B, 0xE286, 0x922C, 0xE287, 0x922D, 0xE288, 0x922E, 0xE289,
+	0x922F, 0xE28A, 0x9230, 0xE28B, 0x9231, 0xE28C, 0x9232, 0xE28D,
+	0x9233, 0xE28E, 0x9234, 0xE28F, 0x9235, 0xE290, 0x9236, 0xE291,
+	0x9237, 0xE292, 0x9238, 0xE293, 0x9239, 0xE294, 0x923A, 0xE295,
+	0x923B, 0xE296, 0x923C, 0xE297, 0x923D, 0xE298, 0x923E, 0xE299,
+	0x923F, 0xE29A, 0x9240, 0xE29B, 0x9241, 0xE29C, 0x9242, 0xE29D,
+	0x9243, 0xE29E, 0x9244, 0xE29F, 0x9245, 0xE2A0, 0x9246, 0xE340,
+	0x9247, 0xE341, 0x9248, 0xE342, 0x9249, 0xE343, 0x924A, 0xE344,
+	0x924B, 0xE345, 0x924C, 0xE346, 0x924D, 0xE347, 0x924E, 0xE348,
+	0x924F, 0xE349, 0x9250, 0xE34A, 0x9251, 0xE34B, 0x9252, 0xE34C,
+	0x9253, 0xE34D, 0x9254, 0xE34E, 0x9255, 0xE34F, 0x9256, 0xE350,
+	0x9257, 0xE351, 0x9258, 0xE352, 0x9259, 0xE353, 0x925A, 0xE354,
+	0x925B, 0xE355, 0x925C, 0xE356, 0x925D, 0xE357, 0x925E, 0xE358,
+	0x925F, 0xE359, 0x9260, 0xE35A, 0x9261, 0xE35B, 0x9262, 0xE35C,
+	0x9263, 0xE35D, 0x9264, 0xE35E, 0x9265, 0xE35F, 0x9266, 0xE360,
+	0x9267, 0xE361, 0x9268, 0xE362, 0x9269, 0xE363, 0x926A, 0xE364,
+	0x926B, 0xE365, 0x926C, 0xE366, 0x926D, 0xE367, 0x926E, 0xE368,
+	0x926F, 0xE369, 0x9270, 0xE36A, 0x9271, 0xE36B, 0x9272, 0xE36C,
+	0x9273, 0xE36D, 0x9274, 0xBCF8, 0x9275, 0xE36E, 0x9276, 0xE36F,
+	0x9277, 0xE370, 0x9278, 0xE371, 0x9279, 0xE372, 0x927A, 0xE373,
+	0x927B, 0xE374, 0x927C, 0xE375, 0x927D, 0xE376, 0x927E, 0xE377,
+	0x927F, 0xE378, 0x9280, 0xE379, 0x9281, 0xE37A, 0x9282, 0xE37B,
+	0x9283, 0xE37C, 0x9284, 0xE37D, 0x9285, 0xE37E, 0x9286, 0xE380,
+	0x9287, 0xE381, 0x9288, 0xE382, 0x9289, 0xE383, 0x928A, 0xE384,
+	0x928B, 0xE385, 0x928C, 0xE386, 0x928D, 0xE387, 0x928E, 0xF6C6,
+	0x928F, 0xE388, 0x9290, 0xE389, 0x9291, 0xE38A, 0x9292, 0xE38B,
+	0x9293, 0xE38C, 0x9294, 0xE38D, 0x9295, 0xE38E, 0x9296, 0xE38F,
+	0x9297, 0xE390, 0x9298, 0xE391, 0x9299, 0xE392, 0x929A, 0xE393,
+	0x929B, 0xE394, 0x929C, 0xE395, 0x929D, 0xE396, 0x929E, 0xE397,
+	0x929F, 0xE398, 0x92A0, 0xE399, 0x92A1, 0xE39A, 0x92A2, 0xE39B,
+	0x92A3, 0xE39C, 0x92A4, 0xE39D, 0x92A5, 0xE39E, 0x92A6, 0xE39F,
+	0x92A7, 0xE3A0, 0x92A8, 0xE440, 0x92A9, 0xE441, 0x92AA, 0xE442,
+	0x92AB, 0xE443, 0x92AC, 0xE444, 0x92AD, 0xE445, 0x92AE, 0xF6C7,
+	0x92AF, 0xE446, 0x92B0, 0xE447, 0x92B1, 0xE448, 0x92B2, 0xE449,
+	0x92B3, 0xE44A, 0x92B4, 0xE44B, 0x92B5, 0xE44C, 0x92B6, 0xE44D,
+	0x92B7, 0xE44E, 0x92B8, 0xE44F, 0x92B9, 0xE450, 0x92BA, 0xE451,
+	0x92BB, 0xE452, 0x92BC, 0xE453, 0x92BD, 0xE454, 0x92BE, 0xE455,
+	0x92BF, 0xE456, 0x92C0, 0xE457, 0x92C1, 0xE458, 0x92C2, 0xE459,
+	0x92C3, 0xE45A, 0x92C4, 0xE45B, 0x92C5, 0xE45C, 0x92C6, 0xE45D,
+	0x92C7, 0xE45E, 0x92C8, 0xF6C8, 0x92C9, 0xE45F, 0x92CA, 0xE460,
+	0x92CB, 0xE461, 0x92CC, 0xE462, 0x92CD, 0xE463, 0x92CE, 0xE464,
+	0x92CF, 0xE465, 0x92D0, 0xE466, 0x92D1, 0xE467, 0x92D2, 0xE468,
+	0x92D3, 0xE469, 0x92D4, 0xE46A, 0x92D5, 0xE46B, 0x92D6, 0xE46C,
+	0x92D7, 0xE46D, 0x92D8, 0xE46E, 0x92D9, 0xE46F, 0x92DA, 0xE470,
+	0x92DB, 0xE471, 0x92DC, 0xE472, 0x92DD, 0xE473, 0x92DE, 0xE474,
+	0x92DF, 0xE475, 0x92E0, 0xE476, 0x92E1, 0xE477, 0x92E2, 0xE478,
+	0x92E3, 0xE479, 0x92E4, 0xE47A, 0x92E5, 0xE47B, 0x92E6, 0xE47C,
+	0x92E7, 0xE47D, 0x92E8, 0xE47E, 0x92E9, 0xE480, 0x92EA, 0xE481,
+	0x92EB, 0xE482, 0x92EC, 0xE483, 0x92ED, 0xE484, 0x92EE, 0xE485,
+	0x92EF, 0xE486, 0x92F0, 0xE487, 0x92F1, 0xE488, 0x92F2, 0xE489,
+	0x92F3, 0xE48A, 0x92F4, 0xE48B, 0x92F5, 0xE48C, 0x92F6, 0xE48D,
+	0x92F7, 0xE48E, 0x92F8, 0xE48F, 0x92F9, 0xE490, 0x92FA, 0xE491,
+	0x92FB, 0xE492, 0x92FC, 0xE493, 0x92FD, 0xE494, 0x92FE, 0xE495,
+	0x92FF, 0xE496, 0x9300, 0xE497, 0x9301, 0xE498, 0x9302, 0xE499,
+	0x9303, 0xE49A, 0x9304, 0xE49B, 0x9305, 0xE49C, 0x9306, 0xE49D,
+	0x9307, 0xE49E, 0x9308, 0xE49F, 0x9309, 0xE4A0, 0x930A, 0xE540,
+	0x930B, 0xE541, 0x930C, 0xE542, 0x930D, 0xE543, 0x930E, 0xE544,
+	0x930F, 0xE545, 0x9310, 0xE546, 0x9311, 0xE547, 0x9312, 0xE548,
+	0x9313, 0xE549, 0x9314, 0xE54A, 0x9315, 0xE54B, 0x9316, 0xE54C,
+	0x9317, 0xE54D, 0x9318, 0xE54E, 0x9319, 0xE54F, 0x931A, 0xE550,
+	0x931B, 0xE551, 0x931C, 0xE552, 0x931D, 0xE553, 0x931E, 0xE554,
+	0x931F, 0xE555, 0x9320, 0xE556, 0x9321, 0xE557, 0x9322, 0xE558,
+	0x9323, 0xE559, 0x9324, 0xE55A, 0x9325, 0xE55B, 0x9326, 0xE55C,
+	0x9327, 0xE55D, 0x9328, 0xE55E, 0x9329, 0xE55F, 0x932A, 0xE560,
+	0x932B, 0xE561, 0x932C, 0xE562, 0x932D, 0xE563, 0x932E, 0xE564,
+	0x932F, 0xE565, 0x9330, 0xE566, 0x9331, 0xE567, 0x9332, 0xE568,
+	0x9333, 0xE569, 0x9334, 0xE56A, 0x9335, 0xE56B, 0x9336, 0xE56C,
+	0x9337, 0xE56D, 0x9338, 0xE56E, 0x9339, 0xE56F, 0x933A, 0xE570,
+	0x933B, 0xE571, 0x933C, 0xE572, 0x933D, 0xE573, 0x933E, 0xF6C9,
+	0x933F, 0xE574, 0x9340, 0xE575, 0x9341, 0xE576, 0x9342, 0xE577,
+	0x9343, 0xE578, 0x9344, 0xE579, 0x9345, 0xE57A, 0x9346, 0xE57B,
+	0x9347, 0xE57C, 0x9348, 0xE57D, 0x9349, 0xE57E, 0x934A, 0xE580,
+	0x934B, 0xE581, 0x934C, 0xE582, 0x934D, 0xE583, 0x934E, 0xE584,
+	0x934F, 0xE585, 0x9350, 0xE586, 0x9351, 0xE587, 0x9352, 0xE588,
+	0x9353, 0xE589, 0x9354, 0xE58A, 0x9355, 0xE58B, 0x9356, 0xE58C,
+	0x9357, 0xE58D, 0x9358, 0xE58E, 0x9359, 0xE58F, 0x935A, 0xE590,
+	0x935B, 0xE591, 0x935C, 0xE592, 0x935D, 0xE593, 0x935E, 0xE594,
+	0x935F, 0xE595, 0x9360, 0xE596, 0x9361, 0xE597, 0x9362, 0xE598,
+	0x9363, 0xE599, 0x9364, 0xE59A, 0x9365, 0xE59B, 0x9366, 0xE59C,
+	0x9367, 0xE59D, 0x9368, 0xE59E, 0x9369, 0xE59F, 0x936A, 0xF6CA,
+	0x936B, 0xE5A0, 0x936C, 0xE640, 0x936D, 0xE641, 0x936E, 0xE642,
+	0x936F, 0xE643, 0x9370, 0xE644, 0x9371, 0xE645, 0x9372, 0xE646,
+	0x9373, 0xE647, 0x9374, 0xE648, 0x9375, 0xE649, 0x9376, 0xE64A,
+	0x9377, 0xE64B, 0x9378, 0xE64C, 0x9379, 0xE64D, 0x937A, 0xE64E,
+	0x937B, 0xE64F, 0x937C, 0xE650, 0x937D, 0xE651, 0x937E, 0xE652,
+	0x937F, 0xE653, 0x9380, 0xE654, 0x9381, 0xE655, 0x9382, 0xE656,
+	0x9383, 0xE657, 0x9384, 0xE658, 0x9385, 0xE659, 0x9386, 0xE65A,
+	0x9387, 0xE65B, 0x9388, 0xE65C, 0x9389, 0xE65D, 0x938A, 0xE65E,
+	0x938B, 0xE65F, 0x938C, 0xE660, 0x938D, 0xE661, 0x938E, 0xE662,
+	0x938F, 0xF6CC, 0x9390, 0xE663, 0x9391, 0xE664, 0x9392, 0xE665,
+	0x9393, 0xE666, 0x9394, 0xE667, 0x9395, 0xE668, 0x9396, 0xE669,
+	0x9397, 0xE66A, 0x9398, 0xE66B, 0x9399, 0xE66C, 0x939A, 0xE66D,
+	0x939B, 0xE66E, 0x939C, 0xE66F, 0x939D, 0xE670, 0x939E, 0xE671,
+	0x939F, 0xE672, 0x93A0, 0xE673, 0x93A1, 0xE674, 0x93A2, 0xE675,
+	0x93A3, 0xE676, 0x93A4, 0xE677, 0x93A5, 0xE678, 0x93A6, 0xE679,
+	0x93A7, 0xE67A, 0x93A8, 0xE67B, 0x93A9, 0xE67C, 0x93AA, 0xE67D,
+	0x93AB, 0xE67E, 0x93AC, 0xE680, 0x93AD, 0xE681, 0x93AE, 0xE682,
+	0x93AF, 0xE683, 0x93B0, 0xE684, 0x93B1, 0xE685, 0x93B2, 0xE686,
+	0x93B3, 0xE687, 0x93B4, 0xE688, 0x93B5, 0xE689, 0x93B6, 0xE68A,
+	0x93B7, 0xE68B, 0x93B8, 0xE68C, 0x93B9, 0xE68D, 0x93BA, 0xE68E,
+	0x93BB, 0xE68F, 0x93BC, 0xE690, 0x93BD, 0xE691, 0x93BE, 0xE692,
+	0x93BF, 0xE693, 0x93C0, 0xE694, 0x93C1, 0xE695, 0x93C2, 0xE696,
+	0x93C3, 0xE697, 0x93C4, 0xE698, 0x93C5, 0xE699, 0x93C6, 0xE69A,
+	0x93C7, 0xE69B, 0x93C8, 0xE69C, 0x93C9, 0xE69D, 0x93CA, 0xF6CB,
+	0x93CB, 0xE69E, 0x93CC, 0xE69F, 0x93CD, 0xE6A0, 0x93CE, 0xE740,
+	0x93CF, 0xE741, 0x93D0, 0xE742, 0x93D1, 0xE743, 0x93D2, 0xE744,
+	0x93D3, 0xE745, 0x93D4, 0xE746, 0x93D5, 0xE747, 0x93D6, 0xF7E9,
+	0x93D7, 0xE748, 0x93D8, 0xE749, 0x93D9, 0xE74A, 0x93DA, 0xE74B,
+	0x93DB, 0xE74C, 0x93DC, 0xE74D, 0x93DD, 0xE74E, 0x93DE, 0xE74F,
+	0x93DF, 0xE750, 0x93E0, 0xE751, 0x93E1, 0xE752, 0x93E2, 0xE753,
+	0x93E3, 0xE754, 0x93E4, 0xE755, 0x93E5, 0xE756, 0x93E6, 0xE757,
+	0x93E7, 0xE758, 0x93E8, 0xE759, 0x93E9, 0xE75A, 0x93EA, 0xE75B,
+	0x93EB, 0xE75C, 0x93EC, 0xE75D, 0x93ED, 0xE75E, 0x93EE, 0xE75F,
+	0x93EF, 0xE760, 0x93F0, 0xE761, 0x93F1, 0xE762, 0x93F2, 0xE763,
+	0x93F3, 0xE764, 0x93F4, 0xE765, 0x93F5, 0xE766, 0x93F6, 0xE767,
+	0x93F7, 0xE768, 0x93F8, 0xE769, 0x93F9, 0xE76A, 0x93FA, 0xE76B,
+	0x93FB, 0xE76C, 0x93FC, 0xE76D, 0x93FD, 0xE76E, 0x93FE, 0xE76F,
+	0x93FF, 0xE770, 0x9400, 0xE771, 0x9401, 0xE772, 0x9402, 0xE773,
+	0x9403, 0xE774, 0x9404, 0xE775, 0x9405, 0xE776, 0x9406, 0xE777,
+	0x9407, 0xE778, 0x9408, 0xE779, 0x9409, 0xE77A, 0x940A, 0xE77B,
+	0x940B, 0xE77C, 0x940C, 0xE77D, 0x940D, 0xE77E, 0x940E, 0xE780,
+	0x940F, 0xE781, 0x9410, 0xE782, 0x9411, 0xE783, 0x9412, 0xE784,
+	0x9413, 0xE785, 0x9414, 0xE786, 0x9415, 0xE787, 0x9416, 0xE788,
+	0x9417, 0xE789, 0x9418, 0xE78A, 0x9419, 0xE78B, 0x941A, 0xE78C,
+	0x941B, 0xE78D, 0x941C, 0xE78E, 0x941D, 0xE78F, 0x941E, 0xE790,
+	0x941F, 0xE791, 0x9420, 0xE792, 0x9421, 0xE793, 0x9422, 0xE794,
+	0x9423, 0xE795, 0x9424, 0xE796, 0x9425, 0xE797, 0x9426, 0xE798,
+	0x9427, 0xE799, 0x9428, 0xE79A, 0x9429, 0xE79B, 0x942A, 0xE79C,
+	0x942B, 0xE79D, 0x942C, 0xE79E, 0x942D, 0xE79F, 0x942E, 0xE7A0,
+	0x942F, 0xE840, 0x9430, 0xE841, 0x9431, 0xE842, 0x9432, 0xE843,
+	0x9433, 0xE844, 0x9434, 0xE845, 0x9435, 0xE846, 0x9436, 0xE847,
+	0x9437, 0xE848, 0x9438, 0xE849, 0x9439, 0xE84A, 0x943A, 0xE84B,
+	0x943B, 0xE84C, 0x943C, 0xE84D, 0x943D, 0xE84E, 0x943E, 0xF6CD,
+	0x943F, 0xE84F, 0x9440, 0xE850, 0x9441, 0xE851, 0x9442, 0xE852,
+	0x9443, 0xE853, 0x9444, 0xE854, 0x9445, 0xE855, 0x9446, 0xE856,
+	0x9447, 0xE857, 0x9448, 0xE858, 0x9449, 0xE859, 0x944A, 0xE85A,
+	0x944B, 0xE85B, 0x944C, 0xE85C, 0x944D, 0xE85D, 0x944E, 0xE85E,
+	0x944F, 0xE85F, 0x9450, 0xE860, 0x9451, 0xE861, 0x9452, 0xE862,
+	0x9453, 0xE863, 0x9454, 0xE864, 0x9455, 0xE865, 0x9456, 0xE866,
+	0x9457, 0xE867, 0x9458, 0xE868, 0x9459, 0xE869, 0x945A, 0xE86A,
+	0x945B, 0xE86B, 0x945C, 0xE86C, 0x945D, 0xE86D, 0x945E, 0xE86E,
+	0x945F, 0xE86F, 0x9460, 0xE870, 0x9461, 0xE871, 0x9462, 0xE872,
+	0x9463, 0xE873, 0x9464, 0xE874, 0x9465, 0xE875, 0x9466, 0xE876,
+	0x9467, 0xE877, 0x9468, 0xE878, 0x9469, 0xE879, 0x946A, 0xE87A,
+	0x946B, 0xF6CE, 0x946C, 0xE87B, 0x946D, 0xE87C, 0x946E, 0xE87D,
+	0x946F, 0xE87E, 0x9470, 0xE880, 0x9471, 0xE881, 0x9472, 0xE882,
+	0x9473, 0xE883, 0x9474, 0xE884, 0x9475, 0xE885, 0x9476, 0xE886,
+	0x9477, 0xE887, 0x9478, 0xE888, 0x9479, 0xE889, 0x947A, 0xE88A,
+	0x947B, 0xE88B, 0x947C, 0xE88C, 0x947D, 0xE88D, 0x947E, 0xE88E,
+	0x947F, 0xE88F, 0x9480, 0xE890, 0x9481, 0xE891, 0x9482, 0xE892,
+	0x9483, 0xE893, 0x9484, 0xE894, 0x9485, 0xEEC4, 0x9486, 0xEEC5,
+	0x9487, 0xEEC6, 0x9488, 0xD5EB, 0x9489, 0xB6A4, 0x948A, 0xEEC8,
+	0x948B, 0xEEC7, 0x948C, 0xEEC9, 0x948D, 0xEECA, 0x948E, 0xC7A5,
+	0x948F, 0xEECB, 0x9490, 0xEECC, 0x9491, 0xE895, 0x9492, 0xB7B0,
+	0x9493, 0xB5F6, 0x9494, 0xEECD, 0x9495, 0xEECF, 0x9496, 0xE896,
+	0x9497, 0xEECE, 0x9498, 0xE897, 0x9499, 0xB8C6, 0x949A, 0xEED0,
+	0x949B, 0xEED1, 0x949C, 0xEED2, 0x949D, 0xB6DB, 0x949E, 0xB3AE,
+	0x949F, 0xD6D3, 0x94A0, 0xC4C6, 0x94A1, 0xB1B5, 0x94A2, 0xB8D6,
+	0x94A3, 0xEED3, 0x94A4, 0xEED4, 0x94A5, 0xD4BF, 0x94A6, 0xC7D5,
+	0x94A7, 0xBEFB, 0x94A8, 0xCED9, 0x94A9, 0xB9B3, 0x94AA, 0xEED6,
+	0x94AB, 0xEED5, 0x94AC, 0xEED8, 0x94AD, 0xEED7, 0x94AE, 0xC5A5,
+	0x94AF, 0xEED9, 0x94B0, 0xEEDA, 0x94B1, 0xC7AE, 0x94B2, 0xEEDB,
+	0x94B3, 0xC7AF, 0x94B4, 0xEEDC, 0x94B5, 0xB2A7, 0x94B6, 0xEEDD,
+	0x94B7, 0xEEDE, 0x94B8, 0xEEDF, 0x94B9, 0xEEE0, 0x94BA, 0xEEE1,
+	0x94BB, 0xD7EA, 0x94BC, 0xEEE2, 0x94BD, 0xEEE3, 0x94BE, 0xBCD8,
+	0x94BF, 0xEEE4, 0x94C0, 0xD3CB, 0x94C1, 0xCCFA, 0x94C2, 0xB2AC,
+	0x94C3, 0xC1E5, 0x94C4, 0xEEE5, 0x94C5, 0xC7A6, 0x94C6, 0xC3AD,
+	0x94C7, 0xE898, 0x94C8, 0xEEE6, 0x94C9, 0xEEE7, 0x94CA, 0xEEE8,
+	0x94CB, 0xEEE9, 0x94CC, 0xEEEA, 0x94CD, 0xEEEB, 0x94CE, 0xEEEC,
+	0x94CF, 0xE899, 0x94D0, 0xEEED, 0x94D1, 0xEEEE, 0x94D2, 0xEEEF,
+	0x94D3, 0xE89A, 0x94D4, 0xE89B, 0x94D5, 0xEEF0, 0x94D6, 0xEEF1,
+	0x94D7, 0xEEF2, 0x94D8, 0xEEF4, 0x94D9, 0xEEF3, 0x94DA, 0xE89C,
+	0x94DB, 0xEEF5, 0x94DC, 0xCDAD, 0x94DD, 0xC2C1, 0x94DE, 0xEEF6,
+	0x94DF, 0xEEF7, 0x94E0, 0xEEF8, 0x94E1, 0xD5A1, 0x94E2, 0xEEF9,
+	0x94E3, 0xCFB3, 0x94E4, 0xEEFA, 0x94E5, 0xEEFB, 0x94E6, 0xE89D,
+	0x94E7, 0xEEFC, 0x94E8, 0xEEFD, 0x94E9, 0xEFA1, 0x94EA, 0xEEFE,
+	0x94EB, 0xEFA2, 0x94EC, 0xB8F5, 0x94ED, 0xC3FA, 0x94EE, 0xEFA3,
+	0x94EF, 0xEFA4, 0x94F0, 0xBDC2, 0x94F1, 0xD2BF, 0x94F2, 0xB2F9,
+	0x94F3, 0xEFA5, 0x94F4, 0xEFA6, 0x94F5, 0xEFA7, 0x94F6, 0xD2F8,
+	0x94F7, 0xEFA8, 0x94F8, 0xD6FD, 0x94F9, 0xEFA9, 0x94FA, 0xC6CC,
+	0x94FB, 0xE89E, 0x94FC, 0xEFAA, 0x94FD, 0xEFAB, 0x94FE, 0xC1B4,
+	0x94FF, 0xEFAC, 0x9500, 0xCFFA, 0x9501, 0xCBF8, 0x9502, 0xEFAE,
+	0x9503, 0xEFAD, 0x9504, 0xB3FA, 0x9505, 0xB9F8, 0x9506, 0xEFAF,
+	0x9507, 0xEFB0, 0x9508, 0xD0E2, 0x9509, 0xEFB1, 0x950A, 0xEFB2,
+	0x950B, 0xB7E6, 0x950C, 0xD0BF, 0x950D, 0xEFB3, 0x950E, 0xEFB4,
+	0x950F, 0xEFB5, 0x9510, 0xC8F1, 0x9511, 0xCCE0, 0x9512, 0xEFB6,
+	0x9513, 0xEFB7, 0x9514, 0xEFB8, 0x9515, 0xEFB9, 0x9516, 0xEFBA,
+	0x9517, 0xD5E0, 0x9518, 0xEFBB, 0x9519, 0xB4ED, 0x951A, 0xC3AA,
+	0x951B, 0xEFBC, 0x951C, 0xE89F, 0x951D, 0xEFBD, 0x951E, 0xEFBE,
+	0x951F, 0xEFBF, 0x9520, 0xE8A0, 0x9521, 0xCEFD, 0x9522, 0xEFC0,
+	0x9523, 0xC2E0, 0x9524, 0xB4B8, 0x9525, 0xD7B6, 0x9526, 0xBDF5,
+	0x9527, 0xE940, 0x9528, 0xCFC7, 0x9529, 0xEFC3, 0x952A, 0xEFC1,
+	0x952B, 0xEFC2, 0x952C, 0xEFC4, 0x952D, 0xB6A7, 0x952E, 0xBCFC,
+	0x952F, 0xBEE2, 0x9530, 0xC3CC, 0x9531, 0xEFC5, 0x9532, 0xEFC6,
+	0x9533, 0xE941, 0x9534, 0xEFC7, 0x9535, 0xEFCF, 0x9536, 0xEFC8,
+	0x9537, 0xEFC9, 0x9538, 0xEFCA, 0x9539, 0xC7C2, 0x953A, 0xEFF1,
+	0x953B, 0xB6CD, 0x953C, 0xEFCB, 0x953D, 0xE942, 0x953E, 0xEFCC,
+	0x953F, 0xEFCD, 0x9540, 0xB6C6, 0x9541, 0xC3BE, 0x9542, 0xEFCE,
+	0x9543, 0xE943, 0x9544, 0xEFD0, 0x9545, 0xEFD1, 0x9546, 0xEFD2,
+	0x9547, 0xD5F2, 0x9548, 0xE944, 0x9549, 0xEFD3, 0x954A, 0xC4F7,
+	0x954B, 0xE945, 0x954C, 0xEFD4, 0x954D, 0xC4F8, 0x954E, 0xEFD5,
+	0x954F, 0xEFD6, 0x9550, 0xB8E4, 0x9551, 0xB0F7, 0x9552, 0xEFD7,
+	0x9553, 0xEFD8, 0x9554, 0xEFD9, 0x9555, 0xE946, 0x9556, 0xEFDA,
+	0x9557, 0xEFDB, 0x9558, 0xEFDC, 0x9559, 0xEFDD, 0x955A, 0xE947,
+	0x955B, 0xEFDE, 0x955C, 0xBEB5, 0x955D, 0xEFE1, 0x955E, 0xEFDF,
+	0x955F, 0xEFE0, 0x9560, 0xE948, 0x9561, 0xEFE2, 0x9562, 0xEFE3,
+	0x9563, 0xC1CD, 0x9564, 0xEFE4, 0x9565, 0xEFE5, 0x9566, 0xEFE6,
+	0x9567, 0xEFE7, 0x9568, 0xEFE8, 0x9569, 0xEFE9, 0x956A, 0xEFEA,
+	0x956B, 0xEFEB, 0x956C, 0xEFEC, 0x956D, 0xC0D8, 0x956E, 0xE949,
+	0x956F, 0xEFED, 0x9570, 0xC1AD, 0x9571, 0xEFEE, 0x9572, 0xEFEF,
+	0x9573, 0xEFF0, 0x9574, 0xE94A, 0x9575, 0xE94B, 0x9576, 0xCFE2,
+	0x9577, 0xE94C, 0x9578, 0xE94D, 0x9579, 0xE94E, 0x957A, 0xE94F,
+	0x957B, 0xE950, 0x957C, 0xE951, 0x957D, 0xE952, 0x957E, 0xE953,
+	0x957F, 0xB3A4, 0x9580, 0xE954, 0x9581, 0xE955, 0x9582, 0xE956,
+	0x9583, 0xE957, 0x9584, 0xE958, 0x9585, 0xE959, 0x9586, 0xE95A,
+	0x9587, 0xE95B, 0x9588, 0xE95C, 0x9589, 0xE95D, 0x958A, 0xE95E,
+	0x958B, 0xE95F, 0x958C, 0xE960, 0x958D, 0xE961, 0x958E, 0xE962,
+	0x958F, 0xE963, 0x9590, 0xE964, 0x9591, 0xE965, 0x9592, 0xE966,
+	0x9593, 0xE967, 0x9594, 0xE968, 0x9595, 0xE969, 0x9596, 0xE96A,
+	0x9597, 0xE96B, 0x9598, 0xE96C, 0x9599, 0xE96D, 0x959A, 0xE96E,
+	0x959B, 0xE96F, 0x959C, 0xE970, 0x959D, 0xE971, 0x959E, 0xE972,
+	0x959F, 0xE973, 0x95A0, 0xE974, 0x95A1, 0xE975, 0x95A2, 0xE976,
+	0x95A3, 0xE977, 0x95A4, 0xE978, 0x95A5, 0xE979, 0x95A6, 0xE97A,
+	0x95A7, 0xE97B, 0x95A8, 0xE97C, 0x95A9, 0xE97D, 0x95AA, 0xE97E,
+	0x95AB, 0xE980, 0x95AC, 0xE981, 0x95AD, 0xE982, 0x95AE, 0xE983,
+	0x95AF, 0xE984, 0x95B0, 0xE985, 0x95B1, 0xE986, 0x95B2, 0xE987,
+	0x95B3, 0xE988, 0x95B4, 0xE989, 0x95B5, 0xE98A, 0x95B6, 0xE98B,
+	0x95B7, 0xE98C, 0x95B8, 0xE98D, 0x95B9, 0xE98E, 0x95BA, 0xE98F,
+	0x95BB, 0xE990, 0x95BC, 0xE991, 0x95BD, 0xE992, 0x95BE, 0xE993,
+	0x95BF, 0xE994, 0x95C0, 0xE995, 0x95C1, 0xE996, 0x95C2, 0xE997,
+	0x95C3, 0xE998, 0x95C4, 0xE999, 0x95C5, 0xE99A, 0x95C6, 0xE99B,
+	0x95C7, 0xE99C, 0x95C8, 0xE99D, 0x95C9, 0xE99E, 0x95CA, 0xE99F,
+	0x95CB, 0xE9A0, 0x95CC, 0xEA40, 0x95CD, 0xEA41, 0x95CE, 0xEA42,
+	0x95CF, 0xEA43, 0x95D0, 0xEA44, 0x95D1, 0xEA45, 0x95D2, 0xEA46,
+	0x95D3, 0xEA47, 0x95D4, 0xEA48, 0x95D5, 0xEA49, 0x95D6, 0xEA4A,
+	0x95D7, 0xEA4B, 0x95D8, 0xEA4C, 0x95D9, 0xEA4D, 0x95DA, 0xEA4E,
+	0x95DB, 0xEA4F, 0x95DC, 0xEA50, 0x95DD, 0xEA51, 0x95DE, 0xEA52,
+	0x95DF, 0xEA53, 0x95E0, 0xEA54, 0x95E1, 0xEA55, 0x95E2, 0xEA56,
+	0x95E3, 0xEA57, 0x95E4, 0xEA58, 0x95E5, 0xEA59, 0x95E6, 0xEA5A,
+	0x95E7, 0xEA5B, 0x95E8, 0xC3C5, 0x95E9, 0xE3C5, 0x95EA, 0xC9C1,
+	0x95EB, 0xE3C6, 0x95EC, 0xEA5C, 0x95ED, 0xB1D5, 0x95EE, 0xCECA,
+	0x95EF, 0xB4B3, 0x95F0, 0xC8F2, 0x95F1, 0xE3C7, 0x95F2, 0xCFD0,
+	0x95F3, 0xE3C8, 0x95F4, 0xBCE4, 0x95F5, 0xE3C9, 0x95F6, 0xE3CA,
+	0x95F7, 0xC3C6, 0x95F8, 0xD5A2, 0x95F9, 0xC4D6, 0x95FA, 0xB9EB,
+	0x95FB, 0xCEC5, 0x95FC, 0xE3CB, 0x95FD, 0xC3F6, 0x95FE, 0xE3CC,
+	0x95FF, 0xEA5D, 0x9600, 0xB7A7, 0x9601, 0xB8F3, 0x9602, 0xBAD2,
+	0x9603, 0xE3CD, 0x9604, 0xE3CE, 0x9605, 0xD4C4, 0x9606, 0xE3CF,
+	0x9607, 0xEA5E, 0x9608, 0xE3D0, 0x9609, 0xD1CB, 0x960A, 0xE3D1,
+	0x960B, 0xE3D2, 0x960C, 0xE3D3, 0x960D, 0xE3D4, 0x960E, 0xD1D6,
+	0x960F, 0xE3D5, 0x9610, 0xB2FB, 0x9611, 0xC0BB, 0x9612, 0xE3D6,
+	0x9613, 0xEA5F, 0x9614, 0xC0AB, 0x9615, 0xE3D7, 0x9616, 0xE3D8,
+	0x9617, 0xE3D9, 0x9618, 0xEA60, 0x9619, 0xE3DA, 0x961A, 0xE3DB,
+	0x961B, 0xEA61, 0x961C, 0xB8B7, 0x961D, 0xDAE2, 0x961E, 0xEA62,
+	0x961F, 0xB6D3, 0x9620, 0xEA63, 0x9621, 0xDAE4, 0x9622, 0xDAE3,
+	0x9623, 0xEA64, 0x9624, 0xEA65, 0x9625, 0xEA66, 0x9626, 0xEA67,
+	0x9627, 0xEA68, 0x9628, 0xEA69, 0x9629, 0xEA6A, 0x962A, 0xDAE6,
+	0x962B, 0xEA6B, 0x962C, 0xEA6C, 0x962D, 0xEA6D, 0x962E, 0xC8EE,
+	0x962F, 0xEA6E, 0x9630, 0xEA6F, 0x9631, 0xDAE5, 0x9632, 0xB7C0,
+	0x9633, 0xD1F4, 0x9634, 0xD2F5, 0x9635, 0xD5F3, 0x9636, 0xBDD7,
+	0x9637, 0xEA70, 0x9638, 0xEA71, 0x9639, 0xEA72, 0x963A, 0xEA73,
+	0x963B, 0xD7E8, 0x963C, 0xDAE8, 0x963D, 0xDAE7, 0x963E, 0xEA74,
+	0x963F, 0xB0A2, 0x9640, 0xCDD3, 0x9641, 0xEA75, 0x9642, 0xDAE9,
+	0x9643, 0xEA76, 0x9644, 0xB8BD, 0x9645, 0xBCCA, 0x9646, 0xC2BD,
+	0x9647, 0xC2A4, 0x9648, 0xB3C2, 0x9649, 0xDAEA, 0x964A, 0xEA77,
+	0x964B, 0xC2AA, 0x964C, 0xC4B0, 0x964D, 0xBDB5, 0x964E, 0xEA78,
+	0x964F, 0xEA79, 0x9650, 0xCFDE, 0x9651, 0xEA7A, 0x9652, 0xEA7B,
+	0x9653, 0xEA7C, 0x9654, 0xDAEB, 0x9655, 0xC9C2, 0x9656, 0xEA7D,
+	0x9657, 0xEA7E, 0x9658, 0xEA80, 0x9659, 0xEA81, 0x965A, 0xEA82,
+	0x965B, 0xB1DD, 0x965C, 0xEA83, 0x965D, 0xEA84, 0x965E, 0xEA85,
+	0x965F, 0xDAEC, 0x9660, 0xEA86, 0x9661, 0xB6B8, 0x9662, 0xD4BA,
+	0x9663, 0xEA87, 0x9664, 0xB3FD, 0x9665, 0xEA88, 0x9666, 0xEA89,
+	0x9667, 0xDAED, 0x9668, 0xD4C9, 0x9669, 0xCFD5, 0x966A, 0xC5E3,
+	0x966B, 0xEA8A, 0x966C, 0xDAEE, 0x966D, 0xEA8B, 0x966E, 0xEA8C,
+	0x966F, 0xEA8D, 0x9670, 0xEA8E, 0x9671, 0xEA8F, 0x9672, 0xDAEF,
+	0x9673, 0xEA90, 0x9674, 0xDAF0, 0x9675, 0xC1EA, 0x9676, 0xCCD5,
+	0x9677, 0xCFDD, 0x9678, 0xEA91, 0x9679, 0xEA92, 0x967A, 0xEA93,
+	0x967B, 0xEA94, 0x967C, 0xEA95, 0x967D, 0xEA96, 0x967E, 0xEA97,
+	0x967F, 0xEA98, 0x9680, 0xEA99, 0x9681, 0xEA9A, 0x9682, 0xEA9B,
+	0x9683, 0xEA9C, 0x9684, 0xEA9D, 0x9685, 0xD3E7, 0x9686, 0xC2A1,
+	0x9687, 0xEA9E, 0x9688, 0xDAF1, 0x9689, 0xEA9F, 0x968A, 0xEAA0,
+	0x968B, 0xCBE5, 0x968C, 0xEB40, 0x968D, 0xDAF2, 0x968E, 0xEB41,
+	0x968F, 0xCBE6, 0x9690, 0xD2FE, 0x9691, 0xEB42, 0x9692, 0xEB43,
+	0x9693, 0xEB44, 0x9694, 0xB8F4, 0x9695, 0xEB45, 0x9696, 0xEB46,
+	0x9697, 0xDAF3, 0x9698, 0xB0AF, 0x9699, 0xCFB6, 0x969A, 0xEB47,
+	0x969B, 0xEB48, 0x969C, 0xD5CF, 0x969D, 0xEB49, 0x969E, 0xEB4A,
+	0x969F, 0xEB4B, 0x96A0, 0xEB4C, 0x96A1, 0xEB4D, 0x96A2, 0xEB4E,
+	0x96A3, 0xEB4F, 0x96A4, 0xEB50, 0x96A5, 0xEB51, 0x96A6, 0xEB52,
+	0x96A7, 0xCBED, 0x96A8, 0xEB53, 0x96A9, 0xEB54, 0x96AA, 0xEB55,
+	0x96AB, 0xEB56, 0x96AC, 0xEB57, 0x96AD, 0xEB58, 0x96AE, 0xEB59,
+	0x96AF, 0xEB5A, 0x96B0, 0xDAF4, 0x96B1, 0xEB5B, 0x96B2, 0xEB5C,
+	0x96B3, 0xE3C4, 0x96B4, 0xEB5D, 0x96B5, 0xEB5E, 0x96B6, 0xC1A5,
+	0x96B7, 0xEB5F, 0x96B8, 0xEB60, 0x96B9, 0xF6BF, 0x96BA, 0xEB61,
+	0x96BB, 0xEB62, 0x96BC, 0xF6C0, 0x96BD, 0xF6C1, 0x96BE, 0xC4D1,
+	0x96BF, 0xEB63, 0x96C0, 0xC8B8, 0x96C1, 0xD1E3, 0x96C2, 0xEB64,
+	0x96C3, 0xEB65, 0x96C4, 0xD0DB, 0x96C5, 0xD1C5, 0x96C6, 0xBCAF,
+	0x96C7, 0xB9CD, 0x96C8, 0xEB66, 0x96C9, 0xEFF4, 0x96CA, 0xEB67,
+	0x96CB, 0xEB68, 0x96CC, 0xB4C6, 0x96CD, 0xD3BA, 0x96CE, 0xF6C2,
+	0x96CF, 0xB3FB, 0x96D0, 0xEB69, 0x96D1, 0xEB6A, 0x96D2, 0xF6C3,
+	0x96D3, 0xEB6B, 0x96D4, 0xEB6C, 0x96D5, 0xB5F1, 0x96D6, 0xEB6D,
+	0x96D7, 0xEB6E, 0x96D8, 0xEB6F, 0x96D9, 0xEB70, 0x96DA, 0xEB71,
+	0x96DB, 0xEB72, 0x96DC, 0xEB73, 0x96DD, 0xEB74, 0x96DE, 0xEB75,
+	0x96DF, 0xEB76, 0x96E0, 0xF6C5, 0x96E1, 0xEB77, 0x96E2, 0xEB78,
+	0x96E3, 0xEB79, 0x96E4, 0xEB7A, 0x96E5, 0xEB7B, 0x96E6, 0xEB7C,
+	0x96E7, 0xEB7D, 0x96E8, 0xD3EA, 0x96E9, 0xF6A7, 0x96EA, 0xD1A9,
+	0x96EB, 0xEB7E, 0x96EC, 0xEB80, 0x96ED, 0xEB81, 0x96EE, 0xEB82,
+	0x96EF, 0xF6A9, 0x96F0, 0xEB83, 0x96F1, 0xEB84, 0x96F2, 0xEB85,
+	0x96F3, 0xF6A8, 0x96F4, 0xEB86, 0x96F5, 0xEB87, 0x96F6, 0xC1E3,
+	0x96F7, 0xC0D7, 0x96F8, 0xEB88, 0x96F9, 0xB1A2, 0x96FA, 0xEB89,
+	0x96FB, 0xEB8A, 0x96FC, 0xEB8B, 0x96FD, 0xEB8C, 0x96FE, 0xCEED,
+	0x96FF, 0xEB8D, 0x9700, 0xD0E8, 0x9701, 0xF6AB, 0x9702, 0xEB8E,
+	0x9703, 0xEB8F, 0x9704, 0xCFF6, 0x9705, 0xEB90, 0x9706, 0xF6AA,
+	0x9707, 0xD5F0, 0x9708, 0xF6AC, 0x9709, 0xC3B9, 0x970A, 0xEB91,
+	0x970B, 0xEB92, 0x970C, 0xEB93, 0x970D, 0xBBF4, 0x970E, 0xF6AE,
+	0x970F, 0xF6AD, 0x9710, 0xEB94, 0x9711, 0xEB95, 0x9712, 0xEB96,
+	0x9713, 0xC4DE, 0x9714, 0xEB97, 0x9715, 0xEB98, 0x9716, 0xC1D8,
+	0x9717, 0xEB99, 0x9718, 0xEB9A, 0x9719, 0xEB9B, 0x971A, 0xEB9C,
+	0x971B, 0xEB9D, 0x971C, 0xCBAA, 0x971D, 0xEB9E, 0x971E, 0xCFBC,
+	0x971F, 0xEB9F, 0x9720, 0xEBA0, 0x9721, 0xEC40, 0x9722, 0xEC41,
+	0x9723, 0xEC42, 0x9724, 0xEC43, 0x9725, 0xEC44, 0x9726, 0xEC45,
+	0x9727, 0xEC46, 0x9728, 0xEC47, 0x9729, 0xEC48, 0x972A, 0xF6AF,
+	0x972B, 0xEC49, 0x972C, 0xEC4A, 0x972D, 0xF6B0, 0x972E, 0xEC4B,
+	0x972F, 0xEC4C, 0x9730, 0xF6B1, 0x9731, 0xEC4D, 0x9732, 0xC2B6,
+	0x9733, 0xEC4E, 0x9734, 0xEC4F, 0x9735, 0xEC50, 0x9736, 0xEC51,
+	0x9737, 0xEC52, 0x9738, 0xB0D4, 0x9739, 0xC5F9, 0x973A, 0xEC53,
+	0x973B, 0xEC54, 0x973C, 0xEC55, 0x973D, 0xEC56, 0x973E, 0xF6B2,
+	0x973F, 0xEC57, 0x9740, 0xEC58, 0x9741, 0xEC59, 0x9742, 0xEC5A,
+	0x9743, 0xEC5B, 0x9744, 0xEC5C, 0x9745, 0xEC5D, 0x9746, 0xEC5E,
+	0x9747, 0xEC5F, 0x9748, 0xEC60, 0x9749, 0xEC61, 0x974A, 0xEC62,
+	0x974B, 0xEC63, 0x974C, 0xEC64, 0x974D, 0xEC65, 0x974E, 0xEC66,
+	0x974F, 0xEC67, 0x9750, 0xEC68, 0x9751, 0xEC69, 0x9752, 0xC7E0,
+	0x9753, 0xF6A6, 0x9754, 0xEC6A, 0x9755, 0xEC6B, 0x9756, 0xBEB8,
+	0x9757, 0xEC6C, 0x9758, 0xEC6D, 0x9759, 0xBEB2, 0x975A, 0xEC6E,
+	0x975B, 0xB5E5, 0x975C, 0xEC6F, 0x975D, 0xEC70, 0x975E, 0xB7C7,
+	0x975F, 0xEC71, 0x9760, 0xBFBF, 0x9761, 0xC3D2, 0x9762, 0xC3E6,
+	0x9763, 0xEC72, 0x9764, 0xEC73, 0x9765, 0xD8CC, 0x9766, 0xEC74,
+	0x9767, 0xEC75, 0x9768, 0xEC76, 0x9769, 0xB8EF, 0x976A, 0xEC77,
+	0x976B, 0xEC78, 0x976C, 0xEC79, 0x976D, 0xEC7A, 0x976E, 0xEC7B,
+	0x976F, 0xEC7C, 0x9770, 0xEC7D, 0x9771, 0xEC7E, 0x9772, 0xEC80,
+	0x9773, 0xBDF9, 0x9774, 0xD1A5, 0x9775, 0xEC81, 0x9776, 0xB0D0,
+	0x9777, 0xEC82, 0x9778, 0xEC83, 0x9779, 0xEC84, 0x977A, 0xEC85,
+	0x977B, 0xEC86, 0x977C, 0xF7B0, 0x977D, 0xEC87, 0x977E, 0xEC88,
+	0x977F, 0xEC89, 0x9780, 0xEC8A, 0x9781, 0xEC8B, 0x9782, 0xEC8C,
+	0x9783, 0xEC8D, 0x9784, 0xEC8E, 0x9785, 0xF7B1, 0x9786, 0xEC8F,
+	0x9787, 0xEC90, 0x9788, 0xEC91, 0x9789, 0xEC92, 0x978A, 0xEC93,
+	0x978B, 0xD0AC, 0x978C, 0xEC94, 0x978D, 0xB0B0, 0x978E, 0xEC95,
+	0x978F, 0xEC96, 0x9790, 0xEC97, 0x9791, 0xF7B2, 0x9792, 0xF7B3,
+	0x9793, 0xEC98, 0x9794, 0xF7B4, 0x9795, 0xEC99, 0x9796, 0xEC9A,
+	0x9797, 0xEC9B, 0x9798, 0xC7CA, 0x9799, 0xEC9C, 0x979A, 0xEC9D,
+	0x979B, 0xEC9E, 0x979C, 0xEC9F, 0x979D, 0xECA0, 0x979E, 0xED40,
+	0x979F, 0xED41, 0x97A0, 0xBECF, 0x97A1, 0xED42, 0x97A2, 0xED43,
+	0x97A3, 0xF7B7, 0x97A4, 0xED44, 0x97A5, 0xED45, 0x97A6, 0xED46,
+	0x97A7, 0xED47, 0x97A8, 0xED48, 0x97A9, 0xED49, 0x97AA, 0xED4A,
+	0x97AB, 0xF7B6, 0x97AC, 0xED4B, 0x97AD, 0xB1DE, 0x97AE, 0xED4C,
+	0x97AF, 0xF7B5, 0x97B0, 0xED4D, 0x97B1, 0xED4E, 0x97B2, 0xF7B8,
+	0x97B3, 0xED4F, 0x97B4, 0xF7B9, 0x97B5, 0xED50, 0x97B6, 0xED51,
+	0x97B7, 0xED52, 0x97B8, 0xED53, 0x97B9, 0xED54, 0x97BA, 0xED55,
+	0x97BB, 0xED56, 0x97BC, 0xED57, 0x97BD, 0xED58, 0x97BE, 0xED59,
+	0x97BF, 0xED5A, 0x97C0, 0xED5B, 0x97C1, 0xED5C, 0x97C2, 0xED5D,
+	0x97C3, 0xED5E, 0x97C4, 0xED5F, 0x97C5, 0xED60, 0x97C6, 0xED61,
+	0x97C7, 0xED62, 0x97C8, 0xED63, 0x97C9, 0xED64, 0x97CA, 0xED65,
+	0x97CB, 0xED66, 0x97CC, 0xED67, 0x97CD, 0xED68, 0x97CE, 0xED69,
+	0x97CF, 0xED6A, 0x97D0, 0xED6B, 0x97D1, 0xED6C, 0x97D2, 0xED6D,
+	0x97D3, 0xED6E, 0x97D4, 0xED6F, 0x97D5, 0xED70, 0x97D6, 0xED71,
+	0x97D7, 0xED72, 0x97D8, 0xED73, 0x97D9, 0xED74, 0x97DA, 0xED75,
+	0x97DB, 0xED76, 0x97DC, 0xED77, 0x97DD, 0xED78, 0x97DE, 0xED79,
+	0x97DF, 0xED7A, 0x97E0, 0xED7B, 0x97E1, 0xED7C, 0x97E2, 0xED7D,
+	0x97E3, 0xED7E, 0x97E4, 0xED80, 0x97E5, 0xED81, 0x97E6, 0xCEA4,
+	0x97E7, 0xC8CD, 0x97E8, 0xED82, 0x97E9, 0xBAAB, 0x97EA, 0xE8B8,
+	0x97EB, 0xE8B9, 0x97EC, 0xE8BA, 0x97ED, 0xBEC2, 0x97EE, 0xED83,
+	0x97EF, 0xED84, 0x97F0, 0xED85, 0x97F1, 0xED86, 0x97F2, 0xED87,
+	0x97F3, 0xD2F4, 0x97F4, 0xED88, 0x97F5, 0xD4CF, 0x97F6, 0xC9D8,
+	0x97F7, 0xED89, 0x97F8, 0xED8A, 0x97F9, 0xED8B, 0x97FA, 0xED8C,
+	0x97FB, 0xED8D, 0x97FC, 0xED8E, 0x97FD, 0xED8F, 0x97FE, 0xED90,
+	0x97FF, 0xED91, 0x9800, 0xED92, 0x9801, 0xED93, 0x9802, 0xED94,
+	0x9803, 0xED95, 0x9804, 0xED96, 0x9805, 0xED97, 0x9806, 0xED98,
+	0x9807, 0xED99, 0x9808, 0xED9A, 0x9809, 0xED9B, 0x980A, 0xED9C,
+	0x980B, 0xED9D, 0x980C, 0xED9E, 0x980D, 0xED9F, 0x980E, 0xEDA0,
+	0x980F, 0xEE40, 0x9810, 0xEE41, 0x9811, 0xEE42, 0x9812, 0xEE43,
+	0x9813, 0xEE44, 0x9814, 0xEE45, 0x9815, 0xEE46, 0x9816, 0xEE47,
+	0x9817, 0xEE48, 0x9818, 0xEE49, 0x9819, 0xEE4A, 0x981A, 0xEE4B,
+	0x981B, 0xEE4C, 0x981C, 0xEE4D, 0x981D, 0xEE4E, 0x981E, 0xEE4F,
+	0x981F, 0xEE50, 0x9820, 0xEE51, 0x9821, 0xEE52, 0x9822, 0xEE53,
+	0x9823, 0xEE54, 0x9824, 0xEE55, 0x9825, 0xEE56, 0x9826, 0xEE57,
+	0x9827, 0xEE58, 0x9828, 0xEE59, 0x9829, 0xEE5A, 0x982A, 0xEE5B,
+	0x982B, 0xEE5C, 0x982C, 0xEE5D, 0x982D, 0xEE5E, 0x982E, 0xEE5F,
+	0x982F, 0xEE60, 0x9830, 0xEE61, 0x9831, 0xEE62, 0x9832, 0xEE63,
+	0x9833, 0xEE64, 0x9834, 0xEE65, 0x9835, 0xEE66, 0x9836, 0xEE67,
+	0x9837, 0xEE68, 0x9838, 0xEE69, 0x9839, 0xEE6A, 0x983A, 0xEE6B,
+	0x983B, 0xEE6C, 0x983C, 0xEE6D, 0x983D, 0xEE6E, 0x983E, 0xEE6F,
+	0x983F, 0xEE70, 0x9840, 0xEE71, 0x9841, 0xEE72, 0x9842, 0xEE73,
+	0x9843, 0xEE74, 0x9844, 0xEE75, 0x9845, 0xEE76, 0x9846, 0xEE77,
+	0x9847, 0xEE78, 0x9848, 0xEE79, 0x9849, 0xEE7A, 0x984A, 0xEE7B,
+	0x984B, 0xEE7C, 0x984C, 0xEE7D, 0x984D, 0xEE7E, 0x984E, 0xEE80,
+	0x984F, 0xEE81, 0x9850, 0xEE82, 0x9851, 0xEE83, 0x9852, 0xEE84,
+	0x9853, 0xEE85, 0x9854, 0xEE86, 0x9855, 0xEE87, 0x9856, 0xEE88,
+	0x9857, 0xEE89, 0x9858, 0xEE8A, 0x9859, 0xEE8B, 0x985A, 0xEE8C,
+	0x985B, 0xEE8D, 0x985C, 0xEE8E, 0x985D, 0xEE8F, 0x985E, 0xEE90,
+	0x985F, 0xEE91, 0x9860, 0xEE92, 0x9861, 0xEE93, 0x9862, 0xEE94,
+	0x9863, 0xEE95, 0x9864, 0xEE96, 0x9865, 0xEE97, 0x9866, 0xEE98,
+	0x9867, 0xEE99, 0x9868, 0xEE9A, 0x9869, 0xEE9B, 0x986A, 0xEE9C,
+	0x986B, 0xEE9D, 0x986C, 0xEE9E, 0x986D, 0xEE9F, 0x986E, 0xEEA0,
+	0x986F, 0xEF40, 0x9870, 0xEF41, 0x9871, 0xEF42, 0x9872, 0xEF43,
+	0x9873, 0xEF44, 0x9874, 0xEF45, 0x9875, 0xD2B3, 0x9876, 0xB6A5,
+	0x9877, 0xC7EA, 0x9878, 0xF1FC, 0x9879, 0xCFEE, 0x987A, 0xCBB3,
+	0x987B, 0xD0EB, 0x987C, 0xE7EF, 0x987D, 0xCDE7, 0x987E, 0xB9CB,
+	0x987F, 0xB6D9, 0x9880, 0xF1FD, 0x9881, 0xB0E4, 0x9882, 0xCBCC,
+	0x9883, 0xF1FE, 0x9884, 0xD4A4, 0x9885, 0xC2AD, 0x9886, 0xC1EC,
+	0x9887, 0xC6C4, 0x9888, 0xBEB1, 0x9889, 0xF2A1, 0x988A, 0xBCD5,
+	0x988B, 0xEF46, 0x988C, 0xF2A2, 0x988D, 0xF2A3, 0x988E, 0xEF47,
+	0x988F, 0xF2A4, 0x9890, 0xD2C3, 0x9891, 0xC6B5, 0x9892, 0xEF48,
+	0x9893, 0xCDC7, 0x9894, 0xF2A5, 0x9895, 0xEF49, 0x9896, 0xD3B1,
+	0x9897, 0xBFC5, 0x9898, 0xCCE2, 0x9899, 0xEF4A, 0x989A, 0xF2A6,
+	0x989B, 0xF2A7, 0x989C, 0xD1D5, 0x989D, 0xB6EE, 0x989E, 0xF2A8,
+	0x989F, 0xF2A9, 0x98A0, 0xB5DF, 0x98A1, 0xF2AA, 0x98A2, 0xF2AB,
+	0x98A3, 0xEF4B, 0x98A4, 0xB2FC, 0x98A5, 0xF2AC, 0x98A6, 0xF2AD,
+	0x98A7, 0xC8A7, 0x98A8, 0xEF4C, 0x98A9, 0xEF4D, 0x98AA, 0xEF4E,
+	0x98AB, 0xEF4F, 0x98AC, 0xEF50, 0x98AD, 0xEF51, 0x98AE, 0xEF52,
+	0x98AF, 0xEF53, 0x98B0, 0xEF54, 0x98B1, 0xEF55, 0x98B2, 0xEF56,
+	0x98B3, 0xEF57, 0x98B4, 0xEF58, 0x98B5, 0xEF59, 0x98B6, 0xEF5A,
+	0x98B7, 0xEF5B, 0x98B8, 0xEF5C, 0x98B9, 0xEF5D, 0x98BA, 0xEF5E,
+	0x98BB, 0xEF5F, 0x98BC, 0xEF60, 0x98BD, 0xEF61, 0x98BE, 0xEF62,
+	0x98BF, 0xEF63, 0x98C0, 0xEF64, 0x98C1, 0xEF65, 0x98C2, 0xEF66,
+	0x98C3, 0xEF67, 0x98C4, 0xEF68, 0x98C5, 0xEF69, 0x98C6, 0xEF6A,
+	0x98C7, 0xEF6B, 0x98C8, 0xEF6C, 0x98C9, 0xEF6D, 0x98CA, 0xEF6E,
+	0x98CB, 0xEF6F, 0x98CC, 0xEF70, 0x98CD, 0xEF71, 0x98CE, 0xB7E7,
+	0x98CF, 0xEF72, 0x98D0, 0xEF73, 0x98D1, 0xECA9, 0x98D2, 0xECAA,
+	0x98D3, 0xECAB, 0x98D4, 0xEF74, 0x98D5, 0xECAC, 0x98D6, 0xEF75,
+	0x98D7, 0xEF76, 0x98D8, 0xC6AE, 0x98D9, 0xECAD, 0x98DA, 0xECAE,
+	0x98DB, 0xEF77, 0x98DC, 0xEF78, 0x98DD, 0xEF79, 0x98DE, 0xB7C9,
+	0x98DF, 0xCAB3, 0x98E0, 0xEF7A, 0x98E1, 0xEF7B, 0x98E2, 0xEF7C,
+	0x98E3, 0xEF7D, 0x98E4, 0xEF7E, 0x98E5, 0xEF80, 0x98E6, 0xEF81,
+	0x98E7, 0xE2B8, 0x98E8, 0xF7CF, 0x98E9, 0xEF82, 0x98EA, 0xEF83,
+	0x98EB, 0xEF84, 0x98EC, 0xEF85, 0x98ED, 0xEF86, 0x98EE, 0xEF87,
+	0x98EF, 0xEF88, 0x98F0, 0xEF89, 0x98F1, 0xEF8A, 0x98F2, 0xEF8B,
+	0x98F3, 0xEF8C, 0x98F4, 0xEF8D, 0x98F5, 0xEF8E, 0x98F6, 0xEF8F,
+	0x98F7, 0xEF90, 0x98F8, 0xEF91, 0x98F9, 0xEF92, 0x98FA, 0xEF93,
+	0x98FB, 0xEF94, 0x98FC, 0xEF95, 0x98FD, 0xEF96, 0x98FE, 0xEF97,
+	0x98FF, 0xEF98, 0x9900, 0xEF99, 0x9901, 0xEF9A, 0x9902, 0xEF9B,
+	0x9903, 0xEF9C, 0x9904, 0xEF9D, 0x9905, 0xEF9E, 0x9906, 0xEF9F,
+	0x9907, 0xEFA0, 0x9908, 0xF040, 0x9909, 0xF041, 0x990A, 0xF042,
+	0x990B, 0xF043, 0x990C, 0xF044, 0x990D, 0xF7D0, 0x990E, 0xF045,
+	0x990F, 0xF046, 0x9910, 0xB2CD, 0x9911, 0xF047, 0x9912, 0xF048,
+	0x9913, 0xF049, 0x9914, 0xF04A, 0x9915, 0xF04B, 0x9916, 0xF04C,
+	0x9917, 0xF04D, 0x9918, 0xF04E, 0x9919, 0xF04F, 0x991A, 0xF050,
+	0x991B, 0xF051, 0x991C, 0xF052, 0x991D, 0xF053, 0x991E, 0xF054,
+	0x991F, 0xF055, 0x9920, 0xF056, 0x9921, 0xF057, 0x9922, 0xF058,
+	0x9923, 0xF059, 0x9924, 0xF05A, 0x9925, 0xF05B, 0x9926, 0xF05C,
+	0x9927, 0xF05D, 0x9928, 0xF05E, 0x9929, 0xF05F, 0x992A, 0xF060,
+	0x992B, 0xF061, 0x992C, 0xF062, 0x992D, 0xF063, 0x992E, 0xF7D1,
+	0x992F, 0xF064, 0x9930, 0xF065, 0x9931, 0xF066, 0x9932, 0xF067,
+	0x9933, 0xF068, 0x9934, 0xF069, 0x9935, 0xF06A, 0x9936, 0xF06B,
+	0x9937, 0xF06C, 0x9938, 0xF06D, 0x9939, 0xF06E, 0x993A, 0xF06F,
+	0x993B, 0xF070, 0x993C, 0xF071, 0x993D, 0xF072, 0x993E, 0xF073,
+	0x993F, 0xF074, 0x9940, 0xF075, 0x9941, 0xF076, 0x9942, 0xF077,
+	0x9943, 0xF078, 0x9944, 0xF079, 0x9945, 0xF07A, 0x9946, 0xF07B,
+	0x9947, 0xF07C, 0x9948, 0xF07D, 0x9949, 0xF07E, 0x994A, 0xF080,
+	0x994B, 0xF081, 0x994C, 0xF082, 0x994D, 0xF083, 0x994E, 0xF084,
+	0x994F, 0xF085, 0x9950, 0xF086, 0x9951, 0xF087, 0x9952, 0xF088,
+	0x9953, 0xF089, 0x9954, 0xF7D3, 0x9955, 0xF7D2, 0x9956, 0xF08A,
+	0x9957, 0xF08B, 0x9958, 0xF08C, 0x9959, 0xF08D, 0x995A, 0xF08E,
+	0x995B, 0xF08F, 0x995C, 0xF090, 0x995D, 0xF091, 0x995E, 0xF092,
+	0x995F, 0xF093, 0x9960, 0xF094, 0x9961, 0xF095, 0x9962, 0xF096,
+	0x9963, 0xE2BB, 0x9964, 0xF097, 0x9965, 0xBCA2, 0x9966, 0xF098,
+	0x9967, 0xE2BC, 0x9968, 0xE2BD, 0x9969, 0xE2BE, 0x996A, 0xE2BF,
+	0x996B, 0xE2C0, 0x996C, 0xE2C1, 0x996D, 0xB7B9, 0x996E, 0xD2FB,
+	0x996F, 0xBDA4, 0x9970, 0xCACE, 0x9971, 0xB1A5, 0x9972, 0xCBC7,
+	0x9973, 0xF099, 0x9974, 0xE2C2, 0x9975, 0xB6FC, 0x9976, 0xC8C4,
+	0x9977, 0xE2C3, 0x9978, 0xF09A, 0x9979, 0xF09B, 0x997A, 0xBDC8,
+	0x997B, 0xF09C, 0x997C, 0xB1FD, 0x997D, 0xE2C4, 0x997E, 0xF09D,
+	0x997F, 0xB6F6, 0x9980, 0xE2C5, 0x9981, 0xC4D9, 0x9982, 0xF09E,
+	0x9983, 0xF09F, 0x9984, 0xE2C6, 0x9985, 0xCFDA, 0x9986, 0xB9DD,
+	0x9987, 0xE2C7, 0x9988, 0xC0A1, 0x9989, 0xF0A0, 0x998A, 0xE2C8,
+	0x998B, 0xB2F6, 0x998C, 0xF140, 0x998D, 0xE2C9, 0x998E, 0xF141,
+	0x998F, 0xC1F3, 0x9990, 0xE2CA, 0x9991, 0xE2CB, 0x9992, 0xC2F8,
+	0x9993, 0xE2CC, 0x9994, 0xE2CD, 0x9995, 0xE2CE, 0x9996, 0xCAD7,
+	0x9997, 0xD8B8, 0x9998, 0xD9E5, 0x9999, 0xCFE3, 0x999A, 0xF142,
+	0x999B, 0xF143, 0x999C, 0xF144, 0x999D, 0xF145, 0x999E, 0xF146,
+	0x999F, 0xF147, 0x99A0, 0xF148, 0x99A1, 0xF149, 0x99A2, 0xF14A,
+	0x99A3, 0xF14B, 0x99A4, 0xF14C, 0x99A5, 0xF0A5, 0x99A6, 0xF14D,
+	0x99A7, 0xF14E, 0x99A8, 0xDCB0, 0x99A9, 0xF14F, 0x99AA, 0xF150,
+	0x99AB, 0xF151, 0x99AC, 0xF152, 0x99AD, 0xF153, 0x99AE, 0xF154,
+	0x99AF, 0xF155, 0x99B0, 0xF156, 0x99B1, 0xF157, 0x99B2, 0xF158,
+	0x99B3, 0xF159, 0x99B4, 0xF15A, 0x99B5, 0xF15B, 0x99B6, 0xF15C,
+	0x99B7, 0xF15D, 0x99B8, 0xF15E, 0x99B9, 0xF15F, 0x99BA, 0xF160,
+	0x99BB, 0xF161, 0x99BC, 0xF162, 0x99BD, 0xF163, 0x99BE, 0xF164,
+	0x99BF, 0xF165, 0x99C0, 0xF166, 0x99C1, 0xF167, 0x99C2, 0xF168,
+	0x99C3, 0xF169, 0x99C4, 0xF16A, 0x99C5, 0xF16B, 0x99C6, 0xF16C,
+	0x99C7, 0xF16D, 0x99C8, 0xF16E, 0x99C9, 0xF16F, 0x99CA, 0xF170,
+	0x99CB, 0xF171, 0x99CC, 0xF172, 0x99CD, 0xF173, 0x99CE, 0xF174,
+	0x99CF, 0xF175, 0x99D0, 0xF176, 0x99D1, 0xF177, 0x99D2, 0xF178,
+	0x99D3, 0xF179, 0x99D4, 0xF17A, 0x99D5, 0xF17B, 0x99D6, 0xF17C,
+	0x99D7, 0xF17D, 0x99D8, 0xF17E, 0x99D9, 0xF180, 0x99DA, 0xF181,
+	0x99DB, 0xF182, 0x99DC, 0xF183, 0x99DD, 0xF184, 0x99DE, 0xF185,
+	0x99DF, 0xF186, 0x99E0, 0xF187, 0x99E1, 0xF188, 0x99E2, 0xF189,
+	0x99E3, 0xF18A, 0x99E4, 0xF18B, 0x99E5, 0xF18C, 0x99E6, 0xF18D,
+	0x99E7, 0xF18E, 0x99E8, 0xF18F, 0x99E9, 0xF190, 0x99EA, 0xF191,
+	0x99EB, 0xF192, 0x99EC, 0xF193, 0x99ED, 0xF194, 0x99EE, 0xF195,
+	0x99EF, 0xF196, 0x99F0, 0xF197, 0x99F1, 0xF198, 0x99F2, 0xF199,
+	0x99F3, 0xF19A, 0x99F4, 0xF19B, 0x99F5, 0xF19C, 0x99F6, 0xF19D,
+	0x99F7, 0xF19E, 0x99F8, 0xF19F, 0x99F9, 0xF1A0, 0x99FA, 0xF240,
+	0x99FB, 0xF241, 0x99FC, 0xF242, 0x99FD, 0xF243, 0x99FE, 0xF244,
+	0x99FF, 0xF245, 0x9A00, 0xF246, 0x9A01, 0xF247, 0x9A02, 0xF248,
+	0x9A03, 0xF249, 0x9A04, 0xF24A, 0x9A05, 0xF24B, 0x9A06, 0xF24C,
+	0x9A07, 0xF24D, 0x9A08, 0xF24E, 0x9A09, 0xF24F, 0x9A0A, 0xF250,
+	0x9A0B, 0xF251, 0x9A0C, 0xF252, 0x9A0D, 0xF253, 0x9A0E, 0xF254,
+	0x9A0F, 0xF255, 0x9A10, 0xF256, 0x9A11, 0xF257, 0x9A12, 0xF258,
+	0x9A13, 0xF259, 0x9A14, 0xF25A, 0x9A15, 0xF25B, 0x9A16, 0xF25C,
+	0x9A17, 0xF25D, 0x9A18, 0xF25E, 0x9A19, 0xF25F, 0x9A1A, 0xF260,
+	0x9A1B, 0xF261, 0x9A1C, 0xF262, 0x9A1D, 0xF263, 0x9A1E, 0xF264,
+	0x9A1F, 0xF265, 0x9A20, 0xF266, 0x9A21, 0xF267, 0x9A22, 0xF268,
+	0x9A23, 0xF269, 0x9A24, 0xF26A, 0x9A25, 0xF26B, 0x9A26, 0xF26C,
+	0x9A27, 0xF26D, 0x9A28, 0xF26E, 0x9A29, 0xF26F, 0x9A2A, 0xF270,
+	0x9A2B, 0xF271, 0x9A2C, 0xF272, 0x9A2D, 0xF273, 0x9A2E, 0xF274,
+	0x9A2F, 0xF275, 0x9A30, 0xF276, 0x9A31, 0xF277, 0x9A32, 0xF278,
+	0x9A33, 0xF279, 0x9A34, 0xF27A, 0x9A35, 0xF27B, 0x9A36, 0xF27C,
+	0x9A37, 0xF27D, 0x9A38, 0xF27E, 0x9A39, 0xF280, 0x9A3A, 0xF281,
+	0x9A3B, 0xF282, 0x9A3C, 0xF283, 0x9A3D, 0xF284, 0x9A3E, 0xF285,
+	0x9A3F, 0xF286, 0x9A40, 0xF287, 0x9A41, 0xF288, 0x9A42, 0xF289,
+	0x9A43, 0xF28A, 0x9A44, 0xF28B, 0x9A45, 0xF28C, 0x9A46, 0xF28D,
+	0x9A47, 0xF28E, 0x9A48, 0xF28F, 0x9A49, 0xF290, 0x9A4A, 0xF291,
+	0x9A4B, 0xF292, 0x9A4C, 0xF293, 0x9A4D, 0xF294, 0x9A4E, 0xF295,
+	0x9A4F, 0xF296, 0x9A50, 0xF297, 0x9A51, 0xF298, 0x9A52, 0xF299,
+	0x9A53, 0xF29A, 0x9A54, 0xF29B, 0x9A55, 0xF29C, 0x9A56, 0xF29D,
+	0x9A57, 0xF29E, 0x9A58, 0xF29F, 0x9A59, 0xF2A0, 0x9A5A, 0xF340,
+	0x9A5B, 0xF341, 0x9A5C, 0xF342, 0x9A5D, 0xF343, 0x9A5E, 0xF344,
+	0x9A5F, 0xF345, 0x9A60, 0xF346, 0x9A61, 0xF347, 0x9A62, 0xF348,
+	0x9A63, 0xF349, 0x9A64, 0xF34A, 0x9A65, 0xF34B, 0x9A66, 0xF34C,
+	0x9A67, 0xF34D, 0x9A68, 0xF34E, 0x9A69, 0xF34F, 0x9A6A, 0xF350,
+	0x9A6B, 0xF351, 0x9A6C, 0xC2ED, 0x9A6D, 0xD4A6, 0x9A6E, 0xCDD4,
+	0x9A6F, 0xD1B1, 0x9A70, 0xB3DB, 0x9A71, 0xC7FD, 0x9A72, 0xF352,
+	0x9A73, 0xB2B5, 0x9A74, 0xC2BF, 0x9A75, 0xE6E0, 0x9A76, 0xCABB,
+	0x9A77, 0xE6E1, 0x9A78, 0xE6E2, 0x9A79, 0xBED4, 0x9A7A, 0xE6E3,
+	0x9A7B, 0xD7A4, 0x9A7C, 0xCDD5, 0x9A7D, 0xE6E5, 0x9A7E, 0xBCDD,
+	0x9A7F, 0xE6E4, 0x9A80, 0xE6E6, 0x9A81, 0xE6E7, 0x9A82, 0xC2EE,
+	0x9A83, 0xF353, 0x9A84, 0xBDBE, 0x9A85, 0xE6E8, 0x9A86, 0xC2E6,
+	0x9A87, 0xBAA7, 0x9A88, 0xE6E9, 0x9A89, 0xF354, 0x9A8A, 0xE6EA,
+	0x9A8B, 0xB3D2, 0x9A8C, 0xD1E9, 0x9A8D, 0xF355, 0x9A8E, 0xF356,
+	0x9A8F, 0xBFA5, 0x9A90, 0xE6EB, 0x9A91, 0xC6EF, 0x9A92, 0xE6EC,
+	0x9A93, 0xE6ED, 0x9A94, 0xF357, 0x9A95, 0xF358, 0x9A96, 0xE6EE,
+	0x9A97, 0xC6AD, 0x9A98, 0xE6EF, 0x9A99, 0xF359, 0x9A9A, 0xC9A7,
+	0x9A9B, 0xE6F0, 0x9A9C, 0xE6F1, 0x9A9D, 0xE6F2, 0x9A9E, 0xE5B9,
+	0x9A9F, 0xE6F3, 0x9AA0, 0xE6F4, 0x9AA1, 0xC2E2, 0x9AA2, 0xE6F5,
+	0x9AA3, 0xE6F6, 0x9AA4, 0xD6E8, 0x9AA5, 0xE6F7, 0x9AA6, 0xF35A,
+	0x9AA7, 0xE6F8, 0x9AA8, 0xB9C7, 0x9AA9, 0xF35B, 0x9AAA, 0xF35C,
+	0x9AAB, 0xF35D, 0x9AAC, 0xF35E, 0x9AAD, 0xF35F, 0x9AAE, 0xF360,
+	0x9AAF, 0xF361, 0x9AB0, 0xF7BB, 0x9AB1, 0xF7BA, 0x9AB2, 0xF362,
+	0x9AB3, 0xF363, 0x9AB4, 0xF364, 0x9AB5, 0xF365, 0x9AB6, 0xF7BE,
+	0x9AB7, 0xF7BC, 0x9AB8, 0xBAA1, 0x9AB9, 0xF366, 0x9ABA, 0xF7BF,
+	0x9ABB, 0xF367, 0x9ABC, 0xF7C0, 0x9ABD, 0xF368, 0x9ABE, 0xF369,
+	0x9ABF, 0xF36A, 0x9AC0, 0xF7C2, 0x9AC1, 0xF7C1, 0x9AC2, 0xF7C4,
+	0x9AC3, 0xF36B, 0x9AC4, 0xF36C, 0x9AC5, 0xF7C3, 0x9AC6, 0xF36D,
+	0x9AC7, 0xF36E, 0x9AC8, 0xF36F, 0x9AC9, 0xF370, 0x9ACA, 0xF371,
+	0x9ACB, 0xF7C5, 0x9ACC, 0xF7C6, 0x9ACD, 0xF372, 0x9ACE, 0xF373,
+	0x9ACF, 0xF374, 0x9AD0, 0xF375, 0x9AD1, 0xF7C7, 0x9AD2, 0xF376,
+	0x9AD3, 0xCBE8, 0x9AD4, 0xF377, 0x9AD5, 0xF378, 0x9AD6, 0xF379,
+	0x9AD7, 0xF37A, 0x9AD8, 0xB8DF, 0x9AD9, 0xF37B, 0x9ADA, 0xF37C,
+	0x9ADB, 0xF37D, 0x9ADC, 0xF37E, 0x9ADD, 0xF380, 0x9ADE, 0xF381,
+	0x9ADF, 0xF7D4, 0x9AE0, 0xF382, 0x9AE1, 0xF7D5, 0x9AE2, 0xF383,
+	0x9AE3, 0xF384, 0x9AE4, 0xF385, 0x9AE5, 0xF386, 0x9AE6, 0xF7D6,
+	0x9AE7, 0xF387, 0x9AE8, 0xF388, 0x9AE9, 0xF389, 0x9AEA, 0xF38A,
+	0x9AEB, 0xF7D8, 0x9AEC, 0xF38B, 0x9AED, 0xF7DA, 0x9AEE, 0xF38C,
+	0x9AEF, 0xF7D7, 0x9AF0, 0xF38D, 0x9AF1, 0xF38E, 0x9AF2, 0xF38F,
+	0x9AF3, 0xF390, 0x9AF4, 0xF391, 0x9AF5, 0xF392, 0x9AF6, 0xF393,
+	0x9AF7, 0xF394, 0x9AF8, 0xF395, 0x9AF9, 0xF7DB, 0x9AFA, 0xF396,
+	0x9AFB, 0xF7D9, 0x9AFC, 0xF397, 0x9AFD, 0xF398, 0x9AFE, 0xF399,
+	0x9AFF, 0xF39A, 0x9B00, 0xF39B, 0x9B01, 0xF39C, 0x9B02, 0xF39D,
+	0x9B03, 0xD7D7, 0x9B04, 0xF39E, 0x9B05, 0xF39F, 0x9B06, 0xF3A0,
+	0x9B07, 0xF440, 0x9B08, 0xF7DC, 0x9B09, 0xF441, 0x9B0A, 0xF442,
+	0x9B0B, 0xF443, 0x9B0C, 0xF444, 0x9B0D, 0xF445, 0x9B0E, 0xF446,
+	0x9B0F, 0xF7DD, 0x9B10, 0xF447, 0x9B11, 0xF448, 0x9B12, 0xF449,
+	0x9B13, 0xF7DE, 0x9B14, 0xF44A, 0x9B15, 0xF44B, 0x9B16, 0xF44C,
+	0x9B17, 0xF44D, 0x9B18, 0xF44E, 0x9B19, 0xF44F, 0x9B1A, 0xF450,
+	0x9B1B, 0xF451, 0x9B1C, 0xF452, 0x9B1D, 0xF453, 0x9B1E, 0xF454,
+	0x9B1F, 0xF7DF, 0x9B20, 0xF455, 0x9B21, 0xF456, 0x9B22, 0xF457,
+	0x9B23, 0xF7E0, 0x9B24, 0xF458, 0x9B25, 0xF459, 0x9B26, 0xF45A,
+	0x9B27, 0xF45B, 0x9B28, 0xF45C, 0x9B29, 0xF45D, 0x9B2A, 0xF45E,
+	0x9B2B, 0xF45F, 0x9B2C, 0xF460, 0x9B2D, 0xF461, 0x9B2E, 0xF462,
+	0x9B2F, 0xDBCB, 0x9B30, 0xF463, 0x9B31, 0xF464, 0x9B32, 0xD8AA,
+	0x9B33, 0xF465, 0x9B34, 0xF466, 0x9B35, 0xF467, 0x9B36, 0xF468,
+	0x9B37, 0xF469, 0x9B38, 0xF46A, 0x9B39, 0xF46B, 0x9B3A, 0xF46C,
+	0x9B3B, 0xE5F7, 0x9B3C, 0xB9ED, 0x9B3D, 0xF46D, 0x9B3E, 0xF46E,
+	0x9B3F, 0xF46F, 0x9B40, 0xF470, 0x9B41, 0xBFFD, 0x9B42, 0xBBEA,
+	0x9B43, 0xF7C9, 0x9B44, 0xC6C7, 0x9B45, 0xF7C8, 0x9B46, 0xF471,
+	0x9B47, 0xF7CA, 0x9B48, 0xF7CC, 0x9B49, 0xF7CB, 0x9B4A, 0xF472,
+	0x9B4B, 0xF473, 0x9B4C, 0xF474, 0x9B4D, 0xF7CD, 0x9B4E, 0xF475,
+	0x9B4F, 0xCEBA, 0x9B50, 0xF476, 0x9B51, 0xF7CE, 0x9B52, 0xF477,
+	0x9B53, 0xF478, 0x9B54, 0xC4A7, 0x9B55, 0xF479, 0x9B56, 0xF47A,
+	0x9B57, 0xF47B, 0x9B58, 0xF47C, 0x9B59, 0xF47D, 0x9B5A, 0xF47E,
+	0x9B5B, 0xF480, 0x9B5C, 0xF481, 0x9B5D, 0xF482, 0x9B5E, 0xF483,
+	0x9B5F, 0xF484, 0x9B60, 0xF485, 0x9B61, 0xF486, 0x9B62, 0xF487,
+	0x9B63, 0xF488, 0x9B64, 0xF489, 0x9B65, 0xF48A, 0x9B66, 0xF48B,
+	0x9B67, 0xF48C, 0x9B68, 0xF48D, 0x9B69, 0xF48E, 0x9B6A, 0xF48F,
+	0x9B6B, 0xF490, 0x9B6C, 0xF491, 0x9B6D, 0xF492, 0x9B6E, 0xF493,
+	0x9B6F, 0xF494, 0x9B70, 0xF495, 0x9B71, 0xF496, 0x9B72, 0xF497,
+	0x9B73, 0xF498, 0x9B74, 0xF499, 0x9B75, 0xF49A, 0x9B76, 0xF49B,
+	0x9B77, 0xF49C, 0x9B78, 0xF49D, 0x9B79, 0xF49E, 0x9B7A, 0xF49F,
+	0x9B7B, 0xF4A0, 0x9B7C, 0xF540, 0x9B7D, 0xF541, 0x9B7E, 0xF542,
+	0x9B7F, 0xF543, 0x9B80, 0xF544, 0x9B81, 0xF545, 0x9B82, 0xF546,
+	0x9B83, 0xF547, 0x9B84, 0xF548, 0x9B85, 0xF549, 0x9B86, 0xF54A,
+	0x9B87, 0xF54B, 0x9B88, 0xF54C, 0x9B89, 0xF54D, 0x9B8A, 0xF54E,
+	0x9B8B, 0xF54F, 0x9B8C, 0xF550, 0x9B8D, 0xF551, 0x9B8E, 0xF552,
+	0x9B8F, 0xF553, 0x9B90, 0xF554, 0x9B91, 0xF555, 0x9B92, 0xF556,
+	0x9B93, 0xF557, 0x9B94, 0xF558, 0x9B95, 0xF559, 0x9B96, 0xF55A,
+	0x9B97, 0xF55B, 0x9B98, 0xF55C, 0x9B99, 0xF55D, 0x9B9A, 0xF55E,
+	0x9B9B, 0xF55F, 0x9B9C, 0xF560, 0x9B9D, 0xF561, 0x9B9E, 0xF562,
+	0x9B9F, 0xF563, 0x9BA0, 0xF564, 0x9BA1, 0xF565, 0x9BA2, 0xF566,
+	0x9BA3, 0xF567, 0x9BA4, 0xF568, 0x9BA5, 0xF569, 0x9BA6, 0xF56A,
+	0x9BA7, 0xF56B, 0x9BA8, 0xF56C, 0x9BA9, 0xF56D, 0x9BAA, 0xF56E,
+	0x9BAB, 0xF56F, 0x9BAC, 0xF570, 0x9BAD, 0xF571, 0x9BAE, 0xF572,
+	0x9BAF, 0xF573, 0x9BB0, 0xF574, 0x9BB1, 0xF575, 0x9BB2, 0xF576,
+	0x9BB3, 0xF577, 0x9BB4, 0xF578, 0x9BB5, 0xF579, 0x9BB6, 0xF57A,
+	0x9BB7, 0xF57B, 0x9BB8, 0xF57C, 0x9BB9, 0xF57D, 0x9BBA, 0xF57E,
+	0x9BBB, 0xF580, 0x9BBC, 0xF581, 0x9BBD, 0xF582, 0x9BBE, 0xF583,
+	0x9BBF, 0xF584, 0x9BC0, 0xF585, 0x9BC1, 0xF586, 0x9BC2, 0xF587,
+	0x9BC3, 0xF588, 0x9BC4, 0xF589, 0x9BC5, 0xF58A, 0x9BC6, 0xF58B,
+	0x9BC7, 0xF58C, 0x9BC8, 0xF58D, 0x9BC9, 0xF58E, 0x9BCA, 0xF58F,
+	0x9BCB, 0xF590, 0x9BCC, 0xF591, 0x9BCD, 0xF592, 0x9BCE, 0xF593,
+	0x9BCF, 0xF594, 0x9BD0, 0xF595, 0x9BD1, 0xF596, 0x9BD2, 0xF597,
+	0x9BD3, 0xF598, 0x9BD4, 0xF599, 0x9BD5, 0xF59A, 0x9BD6, 0xF59B,
+	0x9BD7, 0xF59C, 0x9BD8, 0xF59D, 0x9BD9, 0xF59E, 0x9BDA, 0xF59F,
+	0x9BDB, 0xF5A0, 0x9BDC, 0xF640, 0x9BDD, 0xF641, 0x9BDE, 0xF642,
+	0x9BDF, 0xF643, 0x9BE0, 0xF644, 0x9BE1, 0xF645, 0x9BE2, 0xF646,
+	0x9BE3, 0xF647, 0x9BE4, 0xF648, 0x9BE5, 0xF649, 0x9BE6, 0xF64A,
+	0x9BE7, 0xF64B, 0x9BE8, 0xF64C, 0x9BE9, 0xF64D, 0x9BEA, 0xF64E,
+	0x9BEB, 0xF64F, 0x9BEC, 0xF650, 0x9BED, 0xF651, 0x9BEE, 0xF652,
+	0x9BEF, 0xF653, 0x9BF0, 0xF654, 0x9BF1, 0xF655, 0x9BF2, 0xF656,
+	0x9BF3, 0xF657, 0x9BF4, 0xF658, 0x9BF5, 0xF659, 0x9BF6, 0xF65A,
+	0x9BF7, 0xF65B, 0x9BF8, 0xF65C, 0x9BF9, 0xF65D, 0x9BFA, 0xF65E,
+	0x9BFB, 0xF65F, 0x9BFC, 0xF660, 0x9BFD, 0xF661, 0x9BFE, 0xF662,
+	0x9BFF, 0xF663, 0x9C00, 0xF664, 0x9C01, 0xF665, 0x9C02, 0xF666,
+	0x9C03, 0xF667, 0x9C04, 0xF668, 0x9C05, 0xF669, 0x9C06, 0xF66A,
+	0x9C07, 0xF66B, 0x9C08, 0xF66C, 0x9C09, 0xF66D, 0x9C0A, 0xF66E,
+	0x9C0B, 0xF66F, 0x9C0C, 0xF670, 0x9C0D, 0xF671, 0x9C0E, 0xF672,
+	0x9C0F, 0xF673, 0x9C10, 0xF674, 0x9C11, 0xF675, 0x9C12, 0xF676,
+	0x9C13, 0xF677, 0x9C14, 0xF678, 0x9C15, 0xF679, 0x9C16, 0xF67A,
+	0x9C17, 0xF67B, 0x9C18, 0xF67C, 0x9C19, 0xF67D, 0x9C1A, 0xF67E,
+	0x9C1B, 0xF680, 0x9C1C, 0xF681, 0x9C1D, 0xF682, 0x9C1E, 0xF683,
+	0x9C1F, 0xF684, 0x9C20, 0xF685, 0x9C21, 0xF686, 0x9C22, 0xF687,
+	0x9C23, 0xF688, 0x9C24, 0xF689, 0x9C25, 0xF68A, 0x9C26, 0xF68B,
+	0x9C27, 0xF68C, 0x9C28, 0xF68D, 0x9C29, 0xF68E, 0x9C2A, 0xF68F,
+	0x9C2B, 0xF690, 0x9C2C, 0xF691, 0x9C2D, 0xF692, 0x9C2E, 0xF693,
+	0x9C2F, 0xF694, 0x9C30, 0xF695, 0x9C31, 0xF696, 0x9C32, 0xF697,
+	0x9C33, 0xF698, 0x9C34, 0xF699, 0x9C35, 0xF69A, 0x9C36, 0xF69B,
+	0x9C37, 0xF69C, 0x9C38, 0xF69D, 0x9C39, 0xF69E, 0x9C3A, 0xF69F,
+	0x9C3B, 0xF6A0, 0x9C3C, 0xF740, 0x9C3D, 0xF741, 0x9C3E, 0xF742,
+	0x9C3F, 0xF743, 0x9C40, 0xF744, 0x9C41, 0xF745, 0x9C42, 0xF746,
+	0x9C43, 0xF747, 0x9C44, 0xF748, 0x9C45, 0xF749, 0x9C46, 0xF74A,
+	0x9C47, 0xF74B, 0x9C48, 0xF74C, 0x9C49, 0xF74D, 0x9C4A, 0xF74E,
+	0x9C4B, 0xF74F, 0x9C4C, 0xF750, 0x9C4D, 0xF751, 0x9C4E, 0xF752,
+	0x9C4F, 0xF753, 0x9C50, 0xF754, 0x9C51, 0xF755, 0x9C52, 0xF756,
+	0x9C53, 0xF757, 0x9C54, 0xF758, 0x9C55, 0xF759, 0x9C56, 0xF75A,
+	0x9C57, 0xF75B, 0x9C58, 0xF75C, 0x9C59, 0xF75D, 0x9C5A, 0xF75E,
+	0x9C5B, 0xF75F, 0x9C5C, 0xF760, 0x9C5D, 0xF761, 0x9C5E, 0xF762,
+	0x9C5F, 0xF763, 0x9C60, 0xF764, 0x9C61, 0xF765, 0x9C62, 0xF766,
+	0x9C63, 0xF767, 0x9C64, 0xF768, 0x9C65, 0xF769, 0x9C66, 0xF76A,
+	0x9C67, 0xF76B, 0x9C68, 0xF76C, 0x9C69, 0xF76D, 0x9C6A, 0xF76E,
+	0x9C6B, 0xF76F, 0x9C6C, 0xF770, 0x9C6D, 0xF771, 0x9C6E, 0xF772,
+	0x9C6F, 0xF773, 0x9C70, 0xF774, 0x9C71, 0xF775, 0x9C72, 0xF776,
+	0x9C73, 0xF777, 0x9C74, 0xF778, 0x9C75, 0xF779, 0x9C76, 0xF77A,
+	0x9C77, 0xF77B, 0x9C78, 0xF77C, 0x9C79, 0xF77D, 0x9C7A, 0xF77E,
+	0x9C7B, 0xF780, 0x9C7C, 0xD3E3, 0x9C7D, 0xF781, 0x9C7E, 0xF782,
+	0x9C7F, 0xF6CF, 0x9C80, 0xF783, 0x9C81, 0xC2B3, 0x9C82, 0xF6D0,
+	0x9C83, 0xF784, 0x9C84, 0xF785, 0x9C85, 0xF6D1, 0x9C86, 0xF6D2,
+	0x9C87, 0xF6D3, 0x9C88, 0xF6D4, 0x9C89, 0xF786, 0x9C8A, 0xF787,
+	0x9C8B, 0xF6D6, 0x9C8C, 0xF788, 0x9C8D, 0xB1AB, 0x9C8E, 0xF6D7,
+	0x9C8F, 0xF789, 0x9C90, 0xF6D8, 0x9C91, 0xF6D9, 0x9C92, 0xF6DA,
+	0x9C93, 0xF78A, 0x9C94, 0xF6DB, 0x9C95, 0xF6DC, 0x9C96, 0xF78B,
+	0x9C97, 0xF78C, 0x9C98, 0xF78D, 0x9C99, 0xF78E, 0x9C9A, 0xF6DD,
+	0x9C9B, 0xF6DE, 0x9C9C, 0xCFCA, 0x9C9D, 0xF78F, 0x9C9E, 0xF6DF,
+	0x9C9F, 0xF6E0, 0x9CA0, 0xF6E1, 0x9CA1, 0xF6E2, 0x9CA2, 0xF6E3,
+	0x9CA3, 0xF6E4, 0x9CA4, 0xC0F0, 0x9CA5, 0xF6E5, 0x9CA6, 0xF6E6,
+	0x9CA7, 0xF6E7, 0x9CA8, 0xF6E8, 0x9CA9, 0xF6E9, 0x9CAA, 0xF790,
+	0x9CAB, 0xF6EA, 0x9CAC, 0xF791, 0x9CAD, 0xF6EB, 0x9CAE, 0xF6EC,
+	0x9CAF, 0xF792, 0x9CB0, 0xF6ED, 0x9CB1, 0xF6EE, 0x9CB2, 0xF6EF,
+	0x9CB3, 0xF6F0, 0x9CB4, 0xF6F1, 0x9CB5, 0xF6F2, 0x9CB6, 0xF6F3,
+	0x9CB7, 0xF6F4, 0x9CB8, 0xBEA8, 0x9CB9, 0xF793, 0x9CBA, 0xF6F5,
+	0x9CBB, 0xF6F6, 0x9CBC, 0xF6F7, 0x9CBD, 0xF6F8, 0x9CBE, 0xF794,
+	0x9CBF, 0xF795, 0x9CC0, 0xF796, 0x9CC1, 0xF797, 0x9CC2, 0xF798,
+	0x9CC3, 0xC8FA, 0x9CC4, 0xF6F9, 0x9CC5, 0xF6FA, 0x9CC6, 0xF6FB,
+	0x9CC7, 0xF6FC, 0x9CC8, 0xF799, 0x9CC9, 0xF79A, 0x9CCA, 0xF6FD,
+	0x9CCB, 0xF6FE, 0x9CCC, 0xF7A1, 0x9CCD, 0xF7A2, 0x9CCE, 0xF7A3,
+	0x9CCF, 0xF7A4, 0x9CD0, 0xF7A5, 0x9CD1, 0xF79B, 0x9CD2, 0xF79C,
+	0x9CD3, 0xF7A6, 0x9CD4, 0xF7A7, 0x9CD5, 0xF7A8, 0x9CD6, 0xB1EE,
+	0x9CD7, 0xF7A9, 0x9CD8, 0xF7AA, 0x9CD9, 0xF7AB, 0x9CDA, 0xF79D,
+	0x9CDB, 0xF79E, 0x9CDC, 0xF7AC, 0x9CDD, 0xF7AD, 0x9CDE, 0xC1DB,
+	0x9CDF, 0xF7AE, 0x9CE0, 0xF79F, 0x9CE1, 0xF7A0, 0x9CE2, 0xF7AF,
+	0x9CE3, 0xF840, 0x9CE4, 0xF841, 0x9CE5, 0xF842, 0x9CE6, 0xF843,
+	0x9CE7, 0xF844, 0x9CE8, 0xF845, 0x9CE9, 0xF846, 0x9CEA, 0xF847,
+	0x9CEB, 0xF848, 0x9CEC, 0xF849, 0x9CED, 0xF84A, 0x9CEE, 0xF84B,
+	0x9CEF, 0xF84C, 0x9CF0, 0xF84D, 0x9CF1, 0xF84E, 0x9CF2, 0xF84F,
+	0x9CF3, 0xF850, 0x9CF4, 0xF851, 0x9CF5, 0xF852, 0x9CF6, 0xF853,
+	0x9CF7, 0xF854, 0x9CF8, 0xF855, 0x9CF9, 0xF856, 0x9CFA, 0xF857,
+	0x9CFB, 0xF858, 0x9CFC, 0xF859, 0x9CFD, 0xF85A, 0x9CFE, 0xF85B,
+	0x9CFF, 0xF85C, 0x9D00, 0xF85D, 0x9D01, 0xF85E, 0x9D02, 0xF85F,
+	0x9D03, 0xF860, 0x9D04, 0xF861, 0x9D05, 0xF862, 0x9D06, 0xF863,
+	0x9D07, 0xF864, 0x9D08, 0xF865, 0x9D09, 0xF866, 0x9D0A, 0xF867,
+	0x9D0B, 0xF868, 0x9D0C, 0xF869, 0x9D0D, 0xF86A, 0x9D0E, 0xF86B,
+	0x9D0F, 0xF86C, 0x9D10, 0xF86D, 0x9D11, 0xF86E, 0x9D12, 0xF86F,
+	0x9D13, 0xF870, 0x9D14, 0xF871, 0x9D15, 0xF872, 0x9D16, 0xF873,
+	0x9D17, 0xF874, 0x9D18, 0xF875, 0x9D19, 0xF876, 0x9D1A, 0xF877,
+	0x9D1B, 0xF878, 0x9D1C, 0xF879, 0x9D1D, 0xF87A, 0x9D1E, 0xF87B,
+	0x9D1F, 0xF87C, 0x9D20, 0xF87D, 0x9D21, 0xF87E, 0x9D22, 0xF880,
+	0x9D23, 0xF881, 0x9D24, 0xF882, 0x9D25, 0xF883, 0x9D26, 0xF884,
+	0x9D27, 0xF885, 0x9D28, 0xF886, 0x9D29, 0xF887, 0x9D2A, 0xF888,
+	0x9D2B, 0xF889, 0x9D2C, 0xF88A, 0x9D2D, 0xF88B, 0x9D2E, 0xF88C,
+	0x9D2F, 0xF88D, 0x9D30, 0xF88E, 0x9D31, 0xF88F, 0x9D32, 0xF890,
+	0x9D33, 0xF891, 0x9D34, 0xF892, 0x9D35, 0xF893, 0x9D36, 0xF894,
+	0x9D37, 0xF895, 0x9D38, 0xF896, 0x9D39, 0xF897, 0x9D3A, 0xF898,
+	0x9D3B, 0xF899, 0x9D3C, 0xF89A, 0x9D3D, 0xF89B, 0x9D3E, 0xF89C,
+	0x9D3F, 0xF89D, 0x9D40, 0xF89E, 0x9D41, 0xF89F, 0x9D42, 0xF8A0,
+	0x9D43, 0xF940, 0x9D44, 0xF941, 0x9D45, 0xF942, 0x9D46, 0xF943,
+	0x9D47, 0xF944, 0x9D48, 0xF945, 0x9D49, 0xF946, 0x9D4A, 0xF947,
+	0x9D4B, 0xF948, 0x9D4C, 0xF949, 0x9D4D, 0xF94A, 0x9D4E, 0xF94B,
+	0x9D4F, 0xF94C, 0x9D50, 0xF94D, 0x9D51, 0xF94E, 0x9D52, 0xF94F,
+	0x9D53, 0xF950, 0x9D54, 0xF951, 0x9D55, 0xF952, 0x9D56, 0xF953,
+	0x9D57, 0xF954, 0x9D58, 0xF955, 0x9D59, 0xF956, 0x9D5A, 0xF957,
+	0x9D5B, 0xF958, 0x9D5C, 0xF959, 0x9D5D, 0xF95A, 0x9D5E, 0xF95B,
+	0x9D5F, 0xF95C, 0x9D60, 0xF95D, 0x9D61, 0xF95E, 0x9D62, 0xF95F,
+	0x9D63, 0xF960, 0x9D64, 0xF961, 0x9D65, 0xF962, 0x9D66, 0xF963,
+	0x9D67, 0xF964, 0x9D68, 0xF965, 0x9D69, 0xF966, 0x9D6A, 0xF967,
+	0x9D6B, 0xF968, 0x9D6C, 0xF969, 0x9D6D, 0xF96A, 0x9D6E, 0xF96B,
+	0x9D6F, 0xF96C, 0x9D70, 0xF96D, 0x9D71, 0xF96E, 0x9D72, 0xF96F,
+	0x9D73, 0xF970, 0x9D74, 0xF971, 0x9D75, 0xF972, 0x9D76, 0xF973,
+	0x9D77, 0xF974, 0x9D78, 0xF975, 0x9D79, 0xF976, 0x9D7A, 0xF977,
+	0x9D7B, 0xF978, 0x9D7C, 0xF979, 0x9D7D, 0xF97A, 0x9D7E, 0xF97B,
+	0x9D7F, 0xF97C, 0x9D80, 0xF97D, 0x9D81, 0xF97E, 0x9D82, 0xF980,
+	0x9D83, 0xF981, 0x9D84, 0xF982, 0x9D85, 0xF983, 0x9D86, 0xF984,
+	0x9D87, 0xF985, 0x9D88, 0xF986, 0x9D89, 0xF987, 0x9D8A, 0xF988,
+	0x9D8B, 0xF989, 0x9D8C, 0xF98A, 0x9D8D, 0xF98B, 0x9D8E, 0xF98C,
+	0x9D8F, 0xF98D, 0x9D90, 0xF98E, 0x9D91, 0xF98F, 0x9D92, 0xF990,
+	0x9D93, 0xF991, 0x9D94, 0xF992, 0x9D95, 0xF993, 0x9D96, 0xF994,
+	0x9D97, 0xF995, 0x9D98, 0xF996, 0x9D99, 0xF997, 0x9D9A, 0xF998,
+	0x9D9B, 0xF999, 0x9D9C, 0xF99A, 0x9D9D, 0xF99B, 0x9D9E, 0xF99C,
+	0x9D9F, 0xF99D, 0x9DA0, 0xF99E, 0x9DA1, 0xF99F, 0x9DA2, 0xF9A0,
+	0x9DA3, 0xFA40, 0x9DA4, 0xFA41, 0x9DA5, 0xFA42, 0x9DA6, 0xFA43,
+	0x9DA7, 0xFA44, 0x9DA8, 0xFA45, 0x9DA9, 0xFA46, 0x9DAA, 0xFA47,
+	0x9DAB, 0xFA48, 0x9DAC, 0xFA49, 0x9DAD, 0xFA4A, 0x9DAE, 0xFA4B,
+	0x9DAF, 0xFA4C, 0x9DB0, 0xFA4D, 0x9DB1, 0xFA4E, 0x9DB2, 0xFA4F,
+	0x9DB3, 0xFA50, 0x9DB4, 0xFA51, 0x9DB5, 0xFA52, 0x9DB6, 0xFA53,
+	0x9DB7, 0xFA54, 0x9DB8, 0xFA55, 0x9DB9, 0xFA56, 0x9DBA, 0xFA57,
+	0x9DBB, 0xFA58, 0x9DBC, 0xFA59, 0x9DBD, 0xFA5A, 0x9DBE, 0xFA5B,
+	0x9DBF, 0xFA5C, 0x9DC0, 0xFA5D, 0x9DC1, 0xFA5E, 0x9DC2, 0xFA5F,
+	0x9DC3, 0xFA60, 0x9DC4, 0xFA61, 0x9DC5, 0xFA62, 0x9DC6, 0xFA63,
+	0x9DC7, 0xFA64, 0x9DC8, 0xFA65, 0x9DC9, 0xFA66, 0x9DCA, 0xFA67,
+	0x9DCB, 0xFA68, 0x9DCC, 0xFA69, 0x9DCD, 0xFA6A, 0x9DCE, 0xFA6B,
+	0x9DCF, 0xFA6C, 0x9DD0, 0xFA6D, 0x9DD1, 0xFA6E, 0x9DD2, 0xFA6F,
+	0x9DD3, 0xFA70, 0x9DD4, 0xFA71, 0x9DD5, 0xFA72, 0x9DD6, 0xFA73,
+	0x9DD7, 0xFA74, 0x9DD8, 0xFA75, 0x9DD9, 0xFA76, 0x9DDA, 0xFA77,
+	0x9DDB, 0xFA78, 0x9DDC, 0xFA79, 0x9DDD, 0xFA7A, 0x9DDE, 0xFA7B,
+	0x9DDF, 0xFA7C, 0x9DE0, 0xFA7D, 0x9DE1, 0xFA7E, 0x9DE2, 0xFA80,
+	0x9DE3, 0xFA81, 0x9DE4, 0xFA82, 0x9DE5, 0xFA83, 0x9DE6, 0xFA84,
+	0x9DE7, 0xFA85, 0x9DE8, 0xFA86, 0x9DE9, 0xFA87, 0x9DEA, 0xFA88,
+	0x9DEB, 0xFA89, 0x9DEC, 0xFA8A, 0x9DED, 0xFA8B, 0x9DEE, 0xFA8C,
+	0x9DEF, 0xFA8D, 0x9DF0, 0xFA8E, 0x9DF1, 0xFA8F, 0x9DF2, 0xFA90,
+	0x9DF3, 0xFA91, 0x9DF4, 0xFA92, 0x9DF5, 0xFA93, 0x9DF6, 0xFA94,
+	0x9DF7, 0xFA95, 0x9DF8, 0xFA96, 0x9DF9, 0xFA97, 0x9DFA, 0xFA98,
+	0x9DFB, 0xFA99, 0x9DFC, 0xFA9A, 0x9DFD, 0xFA9B, 0x9DFE, 0xFA9C,
+	0x9DFF, 0xFA9D, 0x9E00, 0xFA9E, 0x9E01, 0xFA9F, 0x9E02, 0xFAA0,
+	0x9E03, 0xFB40, 0x9E04, 0xFB41, 0x9E05, 0xFB42, 0x9E06, 0xFB43,
+	0x9E07, 0xFB44, 0x9E08, 0xFB45, 0x9E09, 0xFB46, 0x9E0A, 0xFB47,
+	0x9E0B, 0xFB48, 0x9E0C, 0xFB49, 0x9E0D, 0xFB4A, 0x9E0E, 0xFB4B,
+	0x9E0F, 0xFB4C, 0x9E10, 0xFB4D, 0x9E11, 0xFB4E, 0x9E12, 0xFB4F,
+	0x9E13, 0xFB50, 0x9E14, 0xFB51, 0x9E15, 0xFB52, 0x9E16, 0xFB53,
+	0x9E17, 0xFB54, 0x9E18, 0xFB55, 0x9E19, 0xFB56, 0x9E1A, 0xFB57,
+	0x9E1B, 0xFB58, 0x9E1C, 0xFB59, 0x9E1D, 0xFB5A, 0x9E1E, 0xFB5B,
+	0x9E1F, 0xC4F1, 0x9E20, 0xF0AF, 0x9E21, 0xBCA6, 0x9E22, 0xF0B0,
+	0x9E23, 0xC3F9, 0x9E24, 0xFB5C, 0x9E25, 0xC5B8, 0x9E26, 0xD1BB,
+	0x9E27, 0xFB5D, 0x9E28, 0xF0B1, 0x9E29, 0xF0B2, 0x9E2A, 0xF0B3,
+	0x9E2B, 0xF0B4, 0x9E2C, 0xF0B5, 0x9E2D, 0xD1BC, 0x9E2E, 0xFB5E,
+	0x9E2F, 0xD1EC, 0x9E30, 0xFB5F, 0x9E31, 0xF0B7, 0x9E32, 0xF0B6,
+	0x9E33, 0xD4A7, 0x9E34, 0xFB60, 0x9E35, 0xCDD2, 0x9E36, 0xF0B8,
+	0x9E37, 0xF0BA, 0x9E38, 0xF0B9, 0x9E39, 0xF0BB, 0x9E3A, 0xF0BC,
+	0x9E3B, 0xFB61, 0x9E3C, 0xFB62, 0x9E3D, 0xB8EB, 0x9E3E, 0xF0BD,
+	0x9E3F, 0xBAE8, 0x9E40, 0xFB63, 0x9E41, 0xF0BE, 0x9E42, 0xF0BF,
+	0x9E43, 0xBEE9, 0x9E44, 0xF0C0, 0x9E45, 0xB6EC, 0x9E46, 0xF0C1,
+	0x9E47, 0xF0C2, 0x9E48, 0xF0C3, 0x9E49, 0xF0C4, 0x9E4A, 0xC8B5,
+	0x9E4B, 0xF0C5, 0x9E4C, 0xF0C6, 0x9E4D, 0xFB64, 0x9E4E, 0xF0C7,
+	0x9E4F, 0xC5F4, 0x9E50, 0xFB65, 0x9E51, 0xF0C8, 0x9E52, 0xFB66,
+	0x9E53, 0xFB67, 0x9E54, 0xFB68, 0x9E55, 0xF0C9, 0x9E56, 0xFB69,
+	0x9E57, 0xF0CA, 0x9E58, 0xF7BD, 0x9E59, 0xFB6A, 0x9E5A, 0xF0CB,
+	0x9E5B, 0xF0CC, 0x9E5C, 0xF0CD, 0x9E5D, 0xFB6B, 0x9E5E, 0xF0CE,
+	0x9E5F, 0xFB6C, 0x9E60, 0xFB6D, 0x9E61, 0xFB6E, 0x9E62, 0xFB6F,
+	0x9E63, 0xF0CF, 0x9E64, 0xBAD7, 0x9E65, 0xFB70, 0x9E66, 0xF0D0,
+	0x9E67, 0xF0D1, 0x9E68, 0xF0D2, 0x9E69, 0xF0D3, 0x9E6A, 0xF0D4,
+	0x9E6B, 0xF0D5, 0x9E6C, 0xF0D6, 0x9E6D, 0xF0D8, 0x9E6E, 0xFB71,
+	0x9E6F, 0xFB72, 0x9E70, 0xD3A5, 0x9E71, 0xF0D7, 0x9E72, 0xFB73,
+	0x9E73, 0xF0D9, 0x9E74, 0xFB74, 0x9E75, 0xFB75, 0x9E76, 0xFB76,
+	0x9E77, 0xFB77, 0x9E78, 0xFB78, 0x9E79, 0xFB79, 0x9E7A, 0xFB7A,
+	0x9E7B, 0xFB7B, 0x9E7C, 0xFB7C, 0x9E7D, 0xFB7D, 0x9E7E, 0xF5BA,
+	0x9E7F, 0xC2B9, 0x9E80, 0xFB7E, 0x9E81, 0xFB80, 0x9E82, 0xF7E4,
+	0x9E83, 0xFB81, 0x9E84, 0xFB82, 0x9E85, 0xFB83, 0x9E86, 0xFB84,
+	0x9E87, 0xF7E5, 0x9E88, 0xF7E6, 0x9E89, 0xFB85, 0x9E8A, 0xFB86,
+	0x9E8B, 0xF7E7, 0x9E8C, 0xFB87, 0x9E8D, 0xFB88, 0x9E8E, 0xFB89,
+	0x9E8F, 0xFB8A, 0x9E90, 0xFB8B, 0x9E91, 0xFB8C, 0x9E92, 0xF7E8,
+	0x9E93, 0xC2B4, 0x9E94, 0xFB8D, 0x9E95, 0xFB8E, 0x9E96, 0xFB8F,
+	0x9E97, 0xFB90, 0x9E98, 0xFB91, 0x9E99, 0xFB92, 0x9E9A, 0xFB93,
+	0x9E9B, 0xFB94, 0x9E9C, 0xFB95, 0x9E9D, 0xF7EA, 0x9E9E, 0xFB96,
+	0x9E9F, 0xF7EB, 0x9EA0, 0xFB97, 0x9EA1, 0xFB98, 0x9EA2, 0xFB99,
+	0x9EA3, 0xFB9A, 0x9EA4, 0xFB9B, 0x9EA5, 0xFB9C, 0x9EA6, 0xC2F3,
+	0x9EA7, 0xFB9D, 0x9EA8, 0xFB9E, 0x9EA9, 0xFB9F, 0x9EAA, 0xFBA0,
+	0x9EAB, 0xFC40, 0x9EAC, 0xFC41, 0x9EAD, 0xFC42, 0x9EAE, 0xFC43,
+	0x9EAF, 0xFC44, 0x9EB0, 0xFC45, 0x9EB1, 0xFC46, 0x9EB2, 0xFC47,
+	0x9EB3, 0xFC48, 0x9EB4, 0xF4F0, 0x9EB5, 0xFC49, 0x9EB6, 0xFC4A,
+	0x9EB7, 0xFC4B, 0x9EB8, 0xF4EF, 0x9EB9, 0xFC4C, 0x9EBA, 0xFC4D,
+	0x9EBB, 0xC2E9, 0x9EBC, 0xFC4E, 0x9EBD, 0xF7E1, 0x9EBE, 0xF7E2,
+	0x9EBF, 0xFC4F, 0x9EC0, 0xFC50, 0x9EC1, 0xFC51, 0x9EC2, 0xFC52,
+	0x9EC3, 0xFC53, 0x9EC4, 0xBBC6, 0x9EC5, 0xFC54, 0x9EC6, 0xFC55,
+	0x9EC7, 0xFC56, 0x9EC8, 0xFC57, 0x9EC9, 0xD9E4, 0x9ECA, 0xFC58,
+	0x9ECB, 0xFC59, 0x9ECC, 0xFC5A, 0x9ECD, 0xCAF2, 0x9ECE, 0xC0E8,
+	0x9ECF, 0xF0A4, 0x9ED0, 0xFC5B, 0x9ED1, 0xBADA, 0x9ED2, 0xFC5C,
+	0x9ED3, 0xFC5D, 0x9ED4, 0xC7AD, 0x9ED5, 0xFC5E, 0x9ED6, 0xFC5F,
+	0x9ED7, 0xFC60, 0x9ED8, 0xC4AC, 0x9ED9, 0xFC61, 0x9EDA, 0xFC62,
+	0x9EDB, 0xF7EC, 0x9EDC, 0xF7ED, 0x9EDD, 0xF7EE, 0x9EDE, 0xFC63,
+	0x9EDF, 0xF7F0, 0x9EE0, 0xF7EF, 0x9EE1, 0xFC64, 0x9EE2, 0xF7F1,
+	0x9EE3, 0xFC65, 0x9EE4, 0xFC66, 0x9EE5, 0xF7F4, 0x9EE6, 0xFC67,
+	0x9EE7, 0xF7F3, 0x9EE8, 0xFC68, 0x9EE9, 0xF7F2, 0x9EEA, 0xF7F5,
+	0x9EEB, 0xFC69, 0x9EEC, 0xFC6A, 0x9EED, 0xFC6B, 0x9EEE, 0xFC6C,
+	0x9EEF, 0xF7F6, 0x9EF0, 0xFC6D, 0x9EF1, 0xFC6E, 0x9EF2, 0xFC6F,
+	0x9EF3, 0xFC70, 0x9EF4, 0xFC71, 0x9EF5, 0xFC72, 0x9EF6, 0xFC73,
+	0x9EF7, 0xFC74, 0x9EF8, 0xFC75, 0x9EF9, 0xEDE9, 0x9EFA, 0xFC76,
+	0x9EFB, 0xEDEA, 0x9EFC, 0xEDEB, 0x9EFD, 0xFC77, 0x9EFE, 0xF6BC,
+	0x9EFF, 0xFC78, 0x9F00, 0xFC79, 0x9F01, 0xFC7A, 0x9F02, 0xFC7B,
+	0x9F03, 0xFC7C, 0x9F04, 0xFC7D, 0x9F05, 0xFC7E, 0x9F06, 0xFC80,
+	0x9F07, 0xFC81, 0x9F08, 0xFC82, 0x9F09, 0xFC83, 0x9F0A, 0xFC84,
+	0x9F0B, 0xF6BD, 0x9F0C, 0xFC85, 0x9F0D, 0xF6BE, 0x9F0E, 0xB6A6,
+	0x9F0F, 0xFC86, 0x9F10, 0xD8BE, 0x9F11, 0xFC87, 0x9F12, 0xFC88,
+	0x9F13, 0xB9C4, 0x9F14, 0xFC89, 0x9F15, 0xFC8A, 0x9F16, 0xFC8B,
+	0x9F17, 0xD8BB, 0x9F18, 0xFC8C, 0x9F19, 0xDCB1, 0x9F1A, 0xFC8D,
+	0x9F1B, 0xFC8E, 0x9F1C, 0xFC8F, 0x9F1D, 0xFC90, 0x9F1E, 0xFC91,
+	0x9F1F, 0xFC92, 0x9F20, 0xCAF3, 0x9F21, 0xFC93, 0x9F22, 0xF7F7,
+	0x9F23, 0xFC94, 0x9F24, 0xFC95, 0x9F25, 0xFC96, 0x9F26, 0xFC97,
+	0x9F27, 0xFC98, 0x9F28, 0xFC99, 0x9F29, 0xFC9A, 0x9F2A, 0xFC9B,
+	0x9F2B, 0xFC9C, 0x9F2C, 0xF7F8, 0x9F2D, 0xFC9D, 0x9F2E, 0xFC9E,
+	0x9F2F, 0xF7F9, 0x9F30, 0xFC9F, 0x9F31, 0xFCA0, 0x9F32, 0xFD40,
+	0x9F33, 0xFD41, 0x9F34, 0xFD42, 0x9F35, 0xFD43, 0x9F36, 0xFD44,
+	0x9F37, 0xF7FB, 0x9F38, 0xFD45, 0x9F39, 0xF7FA, 0x9F3A, 0xFD46,
+	0x9F3B, 0xB1C7, 0x9F3C, 0xFD47, 0x9F3D, 0xF7FC, 0x9F3E, 0xF7FD,
+	0x9F3F, 0xFD48, 0x9F40, 0xFD49, 0x9F41, 0xFD4A, 0x9F42, 0xFD4B,
+	0x9F43, 0xFD4C, 0x9F44, 0xF7FE, 0x9F45, 0xFD4D, 0x9F46, 0xFD4E,
+	0x9F47, 0xFD4F, 0x9F48, 0xFD50, 0x9F49, 0xFD51, 0x9F4A, 0xFD52,
+	0x9F4B, 0xFD53, 0x9F4C, 0xFD54, 0x9F4D, 0xFD55, 0x9F4E, 0xFD56,
+	0x9F4F, 0xFD57, 0x9F50, 0xC6EB, 0x9F51, 0xECB4, 0x9F52, 0xFD58,
+	0x9F53, 0xFD59, 0x9F54, 0xFD5A, 0x9F55, 0xFD5B, 0x9F56, 0xFD5C,
+	0x9F57, 0xFD5D, 0x9F58, 0xFD5E, 0x9F59, 0xFD5F, 0x9F5A, 0xFD60,
+	0x9F5B, 0xFD61, 0x9F5C, 0xFD62, 0x9F5D, 0xFD63, 0x9F5E, 0xFD64,
+	0x9F5F, 0xFD65, 0x9F60, 0xFD66, 0x9F61, 0xFD67, 0x9F62, 0xFD68,
+	0x9F63, 0xFD69, 0x9F64, 0xFD6A, 0x9F65, 0xFD6B, 0x9F66, 0xFD6C,
+	0x9F67, 0xFD6D, 0x9F68, 0xFD6E, 0x9F69, 0xFD6F, 0x9F6A, 0xFD70,
+	0x9F6B, 0xFD71, 0x9F6C, 0xFD72, 0x9F6D, 0xFD73, 0x9F6E, 0xFD74,
+	0x9F6F, 0xFD75, 0x9F70, 0xFD76, 0x9F71, 0xFD77, 0x9F72, 0xFD78,
+	0x9F73, 0xFD79, 0x9F74, 0xFD7A, 0x9F75, 0xFD7B, 0x9F76, 0xFD7C,
+	0x9F77, 0xFD7D, 0x9F78, 0xFD7E, 0x9F79, 0xFD80, 0x9F7A, 0xFD81,
+	0x9F7B, 0xFD82, 0x9F7C, 0xFD83, 0x9F7D, 0xFD84, 0x9F7E, 0xFD85,
+	0x9F7F, 0xB3DD, 0x9F80, 0xF6B3, 0x9F81, 0xFD86, 0x9F82, 0xFD87,
+	0x9F83, 0xF6B4, 0x9F84, 0xC1E4, 0x9F85, 0xF6B5, 0x9F86, 0xF6B6,
+	0x9F87, 0xF6B7, 0x9F88, 0xF6B8, 0x9F89, 0xF6B9, 0x9F8A, 0xF6BA,
+	0x9F8B, 0xC8A3, 0x9F8C, 0xF6BB, 0x9F8D, 0xFD88, 0x9F8E, 0xFD89,
+	0x9F8F, 0xFD8A, 0x9F90, 0xFD8B, 0x9F91, 0xFD8C, 0x9F92, 0xFD8D,
+	0x9F93, 0xFD8E, 0x9F94, 0xFD8F, 0x9F95, 0xFD90, 0x9F96, 0xFD91,
+	0x9F97, 0xFD92, 0x9F98, 0xFD93, 0x9F99, 0xC1FA, 0x9F9A, 0xB9A8,
+	0x9F9B, 0xEDE8, 0x9F9C, 0xFD94, 0x9F9D, 0xFD95, 0x9F9E, 0xFD96,
+	0x9F9F, 0xB9EA, 0x9FA0, 0xD9DF, 0x9FA1, 0xFD97, 0x9FA2, 0xFD98,
+	0x9FA3, 0xFD99, 0x9FA4, 0xFD9A, 0x9FA5, 0xFD9B, 0xF92C, 0xFD9C,
+	0xF979, 0xFD9D, 0xF995, 0xFD9E, 0xF9E7, 0xFD9F, 0xF9F1, 0xFDA0,
+	0xFA0C, 0xFE40, 0xFA0D, 0xFE41, 0xFA0E, 0xFE42, 0xFA0F, 0xFE43,
+	0xFA11, 0xFE44, 0xFA13, 0xFE45, 0xFA14, 0xFE46, 0xFA18, 0xFE47,
+	0xFA1F, 0xFE48, 0xFA20, 0xFE49, 0xFA21, 0xFE4A, 0xFA23, 0xFE4B,
+	0xFA24, 0xFE4C, 0xFA27, 0xFE4D, 0xFA28, 0xFE4E, 0xFA29, 0xFE4F,
+	0xFE30, 0xA955, 0xFE31, 0xA6F2, 0xFE33, 0xA6F4, 0xFE34, 0xA6F5,
+	0xFE35, 0xA6E0, 0xFE36, 0xA6E1, 0xFE37, 0xA6F0, 0xFE38, 0xA6F1,
+	0xFE39, 0xA6E2, 0xFE3A, 0xA6E3, 0xFE3B, 0xA6EE, 0xFE3C, 0xA6EF,
+	0xFE3D, 0xA6E6, 0xFE3E, 0xA6E7, 0xFE3F, 0xA6E4, 0xFE40, 0xA6E5,
+	0xFE41, 0xA6E8, 0xFE42, 0xA6E9, 0xFE43, 0xA6EA, 0xFE44, 0xA6EB,
+	0xFE49, 0xA968, 0xFE4A, 0xA969, 0xFE4B, 0xA96A, 0xFE4C, 0xA96B,
+	0xFE4D, 0xA96C, 0xFE4E, 0xA96D, 0xFE4F, 0xA96E, 0xFE50, 0xA96F,
+	0xFE51, 0xA970, 0xFE52, 0xA971, 0xFE54, 0xA972, 0xFE55, 0xA973,
+	0xFE56, 0xA974, 0xFE57, 0xA975, 0xFE59, 0xA976, 0xFE5A, 0xA977,
+	0xFE5B, 0xA978, 0xFE5C, 0xA979, 0xFE5D, 0xA97A, 0xFE5E, 0xA97B,
+	0xFE5F, 0xA97C, 0xFE60, 0xA97D, 0xFE61, 0xA97E, 0xFE62, 0xA980,
+	0xFE63, 0xA981, 0xFE64, 0xA982, 0xFE65, 0xA983, 0xFE66, 0xA984,
+	0xFE68, 0xA985, 0xFE69, 0xA986, 0xFE6A, 0xA987, 0xFE6B, 0xA988,
+	0xFF01, 0xA3A1, 0xFF02, 0xA3A2, 0xFF03, 0xA3A3, 0xFF04, 0xA1E7,
+	0xFF05, 0xA3A5, 0xFF06, 0xA3A6, 0xFF07, 0xA3A7, 0xFF08, 0xA3A8,
+	0xFF09, 0xA3A9, 0xFF0A, 0xA3AA, 0xFF0B, 0xA3AB, 0xFF0C, 0xA3AC,
+	0xFF0D, 0xA3AD, 0xFF0E, 0xA3AE, 0xFF0F, 0xA3AF, 0xFF10, 0xA3B0,
+	0xFF11, 0xA3B1, 0xFF12, 0xA3B2, 0xFF13, 0xA3B3, 0xFF14, 0xA3B4,
+	0xFF15, 0xA3B5, 0xFF16, 0xA3B6, 0xFF17, 0xA3B7, 0xFF18, 0xA3B8,
+	0xFF19, 0xA3B9, 0xFF1A, 0xA3BA, 0xFF1B, 0xA3BB, 0xFF1C, 0xA3BC,
+	0xFF1D, 0xA3BD, 0xFF1E, 0xA3BE, 0xFF1F, 0xA3BF, 0xFF20, 0xA3C0,
+	0xFF21, 0xA3C1, 0xFF22, 0xA3C2, 0xFF23, 0xA3C3, 0xFF24, 0xA3C4,
+	0xFF25, 0xA3C5, 0xFF26, 0xA3C6, 0xFF27, 0xA3C7, 0xFF28, 0xA3C8,
+	0xFF29, 0xA3C9, 0xFF2A, 0xA3CA, 0xFF2B, 0xA3CB, 0xFF2C, 0xA3CC,
+	0xFF2D, 0xA3CD, 0xFF2E, 0xA3CE, 0xFF2F, 0xA3CF, 0xFF30, 0xA3D0,
+	0xFF31, 0xA3D1, 0xFF32, 0xA3D2, 0xFF33, 0xA3D3, 0xFF34, 0xA3D4,
+	0xFF35, 0xA3D5, 0xFF36, 0xA3D6, 0xFF37, 0xA3D7, 0xFF38, 0xA3D8,
+	0xFF39, 0xA3D9, 0xFF3A, 0xA3DA, 0xFF3B, 0xA3DB, 0xFF3C, 0xA3DC,
+	0xFF3D, 0xA3DD, 0xFF3E, 0xA3DE, 0xFF3F, 0xA3DF, 0xFF40, 0xA3E0,
+	0xFF41, 0xA3E1, 0xFF42, 0xA3E2, 0xFF43, 0xA3E3, 0xFF44, 0xA3E4,
+	0xFF45, 0xA3E5, 0xFF46, 0xA3E6, 0xFF47, 0xA3E7, 0xFF48, 0xA3E8,
+	0xFF49, 0xA3E9, 0xFF4A, 0xA3EA, 0xFF4B, 0xA3EB, 0xFF4C, 0xA3EC,
+	0xFF4D, 0xA3ED, 0xFF4E, 0xA3EE, 0xFF4F, 0xA3EF, 0xFF50, 0xA3F0,
+	0xFF51, 0xA3F1, 0xFF52, 0xA3F2, 0xFF53, 0xA3F3, 0xFF54, 0xA3F4,
+	0xFF55, 0xA3F5, 0xFF56, 0xA3F6, 0xFF57, 0xA3F7, 0xFF58, 0xA3F8,
+	0xFF59, 0xA3F9, 0xFF5A, 0xA3FA, 0xFF5B, 0xA3FB, 0xFF5C, 0xA3FC,
+	0xFF5D, 0xA3FD, 0xFF5E, 0xA1AB, 0xFFE0, 0xA1E9, 0xFFE1, 0xA1EA,
+	0xFFE2, 0xA956, 0xFFE3, 0xA3FE, 0xFFE4, 0xA957, 0xFFE5, 0xA3A4,
+	0, 0
+};
+
+static
+const WCHAR oem2uni[] = {
+/*	OEM - Unicode,  OEM - Unicode,  OEM - Unicode,  OEM - Unicode */
+	0x0080, 0x20AC, 0x8140, 0x4E02, 0x8141, 0x4E04, 0x8142, 0x4E05,
+	0x8143, 0x4E06, 0x8144, 0x4E0F, 0x8145, 0x4E12, 0x8146, 0x4E17,
+	0x8147, 0x4E1F, 0x8148, 0x4E20, 0x8149, 0x4E21, 0x814A, 0x4E23,
+	0x814B, 0x4E26, 0x814C, 0x4E29, 0x814D, 0x4E2E, 0x814E, 0x4E2F,
+	0x814F, 0x4E31, 0x8150, 0x4E33, 0x8151, 0x4E35, 0x8152, 0x4E37,
+	0x8153, 0x4E3C, 0x8154, 0x4E40, 0x8155, 0x4E41, 0x8156, 0x4E42,
+	0x8157, 0x4E44, 0x8158, 0x4E46, 0x8159, 0x4E4A, 0x815A, 0x4E51,
+	0x815B, 0x4E55, 0x815C, 0x4E57, 0x815D, 0x4E5A, 0x815E, 0x4E5B,
+	0x815F, 0x4E62, 0x8160, 0x4E63, 0x8161, 0x4E64, 0x8162, 0x4E65,
+	0x8163, 0x4E67, 0x8164, 0x4E68, 0x8165, 0x4E6A, 0x8166, 0x4E6B,
+	0x8167, 0x4E6C, 0x8168, 0x4E6D, 0x8169, 0x4E6E, 0x816A, 0x4E6F,
+	0x816B, 0x4E72, 0x816C, 0x4E74, 0x816D, 0x4E75, 0x816E, 0x4E76,
+	0x816F, 0x4E77, 0x8170, 0x4E78, 0x8171, 0x4E79, 0x8172, 0x4E7A,
+	0x8173, 0x4E7B, 0x8174, 0x4E7C, 0x8175, 0x4E7D, 0x8176, 0x4E7F,
+	0x8177, 0x4E80, 0x8178, 0x4E81, 0x8179, 0x4E82, 0x817A, 0x4E83,
+	0x817B, 0x4E84, 0x817C, 0x4E85, 0x817D, 0x4E87, 0x817E, 0x4E8A,
+	0x8180, 0x4E90, 0x8181, 0x4E96, 0x8182, 0x4E97, 0x8183, 0x4E99,
+	0x8184, 0x4E9C, 0x8185, 0x4E9D, 0x8186, 0x4E9E, 0x8187, 0x4EA3,
+	0x8188, 0x4EAA, 0x8189, 0x4EAF, 0x818A, 0x4EB0, 0x818B, 0x4EB1,
+	0x818C, 0x4EB4, 0x818D, 0x4EB6, 0x818E, 0x4EB7, 0x818F, 0x4EB8,
+	0x8190, 0x4EB9, 0x8191, 0x4EBC, 0x8192, 0x4EBD, 0x8193, 0x4EBE,
+	0x8194, 0x4EC8, 0x8195, 0x4ECC, 0x8196, 0x4ECF, 0x8197, 0x4ED0,
+	0x8198, 0x4ED2, 0x8199, 0x4EDA, 0x819A, 0x4EDB, 0x819B, 0x4EDC,
+	0x819C, 0x4EE0, 0x819D, 0x4EE2, 0x819E, 0x4EE6, 0x819F, 0x4EE7,
+	0x81A0, 0x4EE9, 0x81A1, 0x4EED, 0x81A2, 0x4EEE, 0x81A3, 0x4EEF,
+	0x81A4, 0x4EF1, 0x81A5, 0x4EF4, 0x81A6, 0x4EF8, 0x81A7, 0x4EF9,
+	0x81A8, 0x4EFA, 0x81A9, 0x4EFC, 0x81AA, 0x4EFE, 0x81AB, 0x4F00,
+	0x81AC, 0x4F02, 0x81AD, 0x4F03, 0x81AE, 0x4F04, 0x81AF, 0x4F05,
+	0x81B0, 0x4F06, 0x81B1, 0x4F07, 0x81B2, 0x4F08, 0x81B3, 0x4F0B,
+	0x81B4, 0x4F0C, 0x81B5, 0x4F12, 0x81B6, 0x4F13, 0x81B7, 0x4F14,
+	0x81B8, 0x4F15, 0x81B9, 0x4F16, 0x81BA, 0x4F1C, 0x81BB, 0x4F1D,
+	0x81BC, 0x4F21, 0x81BD, 0x4F23, 0x81BE, 0x4F28, 0x81BF, 0x4F29,
+	0x81C0, 0x4F2C, 0x81C1, 0x4F2D, 0x81C2, 0x4F2E, 0x81C3, 0x4F31,
+	0x81C4, 0x4F33, 0x81C5, 0x4F35, 0x81C6, 0x4F37, 0x81C7, 0x4F39,
+	0x81C8, 0x4F3B, 0x81C9, 0x4F3E, 0x81CA, 0x4F3F, 0x81CB, 0x4F40,
+	0x81CC, 0x4F41, 0x81CD, 0x4F42, 0x81CE, 0x4F44, 0x81CF, 0x4F45,
+	0x81D0, 0x4F47, 0x81D1, 0x4F48, 0x81D2, 0x4F49, 0x81D3, 0x4F4A,
+	0x81D4, 0x4F4B, 0x81D5, 0x4F4C, 0x81D6, 0x4F52, 0x81D7, 0x4F54,
+	0x81D8, 0x4F56, 0x81D9, 0x4F61, 0x81DA, 0x4F62, 0x81DB, 0x4F66,
+	0x81DC, 0x4F68, 0x81DD, 0x4F6A, 0x81DE, 0x4F6B, 0x81DF, 0x4F6D,
+	0x81E0, 0x4F6E, 0x81E1, 0x4F71, 0x81E2, 0x4F72, 0x81E3, 0x4F75,
+	0x81E4, 0x4F77, 0x81E5, 0x4F78, 0x81E6, 0x4F79, 0x81E7, 0x4F7A,
+	0x81E8, 0x4F7D, 0x81E9, 0x4F80, 0x81EA, 0x4F81, 0x81EB, 0x4F82,
+	0x81EC, 0x4F85, 0x81ED, 0x4F86, 0x81EE, 0x4F87, 0x81EF, 0x4F8A,
+	0x81F0, 0x4F8C, 0x81F1, 0x4F8E, 0x81F2, 0x4F90, 0x81F3, 0x4F92,
+	0x81F4, 0x4F93, 0x81F5, 0x4F95, 0x81F6, 0x4F96, 0x81F7, 0x4F98,
+	0x81F8, 0x4F99, 0x81F9, 0x4F9A, 0x81FA, 0x4F9C, 0x81FB, 0x4F9E,
+	0x81FC, 0x4F9F, 0x81FD, 0x4FA1, 0x81FE, 0x4FA2, 0x8240, 0x4FA4,
+	0x8241, 0x4FAB, 0x8242, 0x4FAD, 0x8243, 0x4FB0, 0x8244, 0x4FB1,
+	0x8245, 0x4FB2, 0x8246, 0x4FB3, 0x8247, 0x4FB4, 0x8248, 0x4FB6,
+	0x8249, 0x4FB7, 0x824A, 0x4FB8, 0x824B, 0x4FB9, 0x824C, 0x4FBA,
+	0x824D, 0x4FBB, 0x824E, 0x4FBC, 0x824F, 0x4FBD, 0x8250, 0x4FBE,
+	0x8251, 0x4FC0, 0x8252, 0x4FC1, 0x8253, 0x4FC2, 0x8254, 0x4FC6,
+	0x8255, 0x4FC7, 0x8256, 0x4FC8, 0x8257, 0x4FC9, 0x8258, 0x4FCB,
+	0x8259, 0x4FCC, 0x825A, 0x4FCD, 0x825B, 0x4FD2, 0x825C, 0x4FD3,
+	0x825D, 0x4FD4, 0x825E, 0x4FD5, 0x825F, 0x4FD6, 0x8260, 0x4FD9,
+	0x8261, 0x4FDB, 0x8262, 0x4FE0, 0x8263, 0x4FE2, 0x8264, 0x4FE4,
+	0x8265, 0x4FE5, 0x8266, 0x4FE7, 0x8267, 0x4FEB, 0x8268, 0x4FEC,
+	0x8269, 0x4FF0, 0x826A, 0x4FF2, 0x826B, 0x4FF4, 0x826C, 0x4FF5,
+	0x826D, 0x4FF6, 0x826E, 0x4FF7, 0x826F, 0x4FF9, 0x8270, 0x4FFB,
+	0x8271, 0x4FFC, 0x8272, 0x4FFD, 0x8273, 0x4FFF, 0x8274, 0x5000,
+	0x8275, 0x5001, 0x8276, 0x5002, 0x8277, 0x5003, 0x8278, 0x5004,
+	0x8279, 0x5005, 0x827A, 0x5006, 0x827B, 0x5007, 0x827C, 0x5008,
+	0x827D, 0x5009, 0x827E, 0x500A, 0x8280, 0x500B, 0x8281, 0x500E,
+	0x8282, 0x5010, 0x8283, 0x5011, 0x8284, 0x5013, 0x8285, 0x5015,
+	0x8286, 0x5016, 0x8287, 0x5017, 0x8288, 0x501B, 0x8289, 0x501D,
+	0x828A, 0x501E, 0x828B, 0x5020, 0x828C, 0x5022, 0x828D, 0x5023,
+	0x828E, 0x5024, 0x828F, 0x5027, 0x8290, 0x502B, 0x8291, 0x502F,
+	0x8292, 0x5030, 0x8293, 0x5031, 0x8294, 0x5032, 0x8295, 0x5033,
+	0x8296, 0x5034, 0x8297, 0x5035, 0x8298, 0x5036, 0x8299, 0x5037,
+	0x829A, 0x5038, 0x829B, 0x5039, 0x829C, 0x503B, 0x829D, 0x503D,
+	0x829E, 0x503F, 0x829F, 0x5040, 0x82A0, 0x5041, 0x82A1, 0x5042,
+	0x82A2, 0x5044, 0x82A3, 0x5045, 0x82A4, 0x5046, 0x82A5, 0x5049,
+	0x82A6, 0x504A, 0x82A7, 0x504B, 0x82A8, 0x504D, 0x82A9, 0x5050,
+	0x82AA, 0x5051, 0x82AB, 0x5052, 0x82AC, 0x5053, 0x82AD, 0x5054,
+	0x82AE, 0x5056, 0x82AF, 0x5057, 0x82B0, 0x5058, 0x82B1, 0x5059,
+	0x82B2, 0x505B, 0x82B3, 0x505D, 0x82B4, 0x505E, 0x82B5, 0x505F,
+	0x82B6, 0x5060, 0x82B7, 0x5061, 0x82B8, 0x5062, 0x82B9, 0x5063,
+	0x82BA, 0x5064, 0x82BB, 0x5066, 0x82BC, 0x5067, 0x82BD, 0x5068,
+	0x82BE, 0x5069, 0x82BF, 0x506A, 0x82C0, 0x506B, 0x82C1, 0x506D,
+	0x82C2, 0x506E, 0x82C3, 0x506F, 0x82C4, 0x5070, 0x82C5, 0x5071,
+	0x82C6, 0x5072, 0x82C7, 0x5073, 0x82C8, 0x5074, 0x82C9, 0x5075,
+	0x82CA, 0x5078, 0x82CB, 0x5079, 0x82CC, 0x507A, 0x82CD, 0x507C,
+	0x82CE, 0x507D, 0x82CF, 0x5081, 0x82D0, 0x5082, 0x82D1, 0x5083,
+	0x82D2, 0x5084, 0x82D3, 0x5086, 0x82D4, 0x5087, 0x82D5, 0x5089,
+	0x82D6, 0x508A, 0x82D7, 0x508B, 0x82D8, 0x508C, 0x82D9, 0x508E,
+	0x82DA, 0x508F, 0x82DB, 0x5090, 0x82DC, 0x5091, 0x82DD, 0x5092,
+	0x82DE, 0x5093, 0x82DF, 0x5094, 0x82E0, 0x5095, 0x82E1, 0x5096,
+	0x82E2, 0x5097, 0x82E3, 0x5098, 0x82E4, 0x5099, 0x82E5, 0x509A,
+	0x82E6, 0x509B, 0x82E7, 0x509C, 0x82E8, 0x509D, 0x82E9, 0x509E,
+	0x82EA, 0x509F, 0x82EB, 0x50A0, 0x82EC, 0x50A1, 0x82ED, 0x50A2,
+	0x82EE, 0x50A4, 0x82EF, 0x50A6, 0x82F0, 0x50AA, 0x82F1, 0x50AB,
+	0x82F2, 0x50AD, 0x82F3, 0x50AE, 0x82F4, 0x50AF, 0x82F5, 0x50B0,
+	0x82F6, 0x50B1, 0x82F7, 0x50B3, 0x82F8, 0x50B4, 0x82F9, 0x50B5,
+	0x82FA, 0x50B6, 0x82FB, 0x50B7, 0x82FC, 0x50B8, 0x82FD, 0x50B9,
+	0x82FE, 0x50BC, 0x8340, 0x50BD, 0x8341, 0x50BE, 0x8342, 0x50BF,
+	0x8343, 0x50C0, 0x8344, 0x50C1, 0x8345, 0x50C2, 0x8346, 0x50C3,
+	0x8347, 0x50C4, 0x8348, 0x50C5, 0x8349, 0x50C6, 0x834A, 0x50C7,
+	0x834B, 0x50C8, 0x834C, 0x50C9, 0x834D, 0x50CA, 0x834E, 0x50CB,
+	0x834F, 0x50CC, 0x8350, 0x50CD, 0x8351, 0x50CE, 0x8352, 0x50D0,
+	0x8353, 0x50D1, 0x8354, 0x50D2, 0x8355, 0x50D3, 0x8356, 0x50D4,
+	0x8357, 0x50D5, 0x8358, 0x50D7, 0x8359, 0x50D8, 0x835A, 0x50D9,
+	0x835B, 0x50DB, 0x835C, 0x50DC, 0x835D, 0x50DD, 0x835E, 0x50DE,
+	0x835F, 0x50DF, 0x8360, 0x50E0, 0x8361, 0x50E1, 0x8362, 0x50E2,
+	0x8363, 0x50E3, 0x8364, 0x50E4, 0x8365, 0x50E5, 0x8366, 0x50E8,
+	0x8367, 0x50E9, 0x8368, 0x50EA, 0x8369, 0x50EB, 0x836A, 0x50EF,
+	0x836B, 0x50F0, 0x836C, 0x50F1, 0x836D, 0x50F2, 0x836E, 0x50F4,
+	0x836F, 0x50F6, 0x8370, 0x50F7, 0x8371, 0x50F8, 0x8372, 0x50F9,
+	0x8373, 0x50FA, 0x8374, 0x50FC, 0x8375, 0x50FD, 0x8376, 0x50FE,
+	0x8377, 0x50FF, 0x8378, 0x5100, 0x8379, 0x5101, 0x837A, 0x5102,
+	0x837B, 0x5103, 0x837C, 0x5104, 0x837D, 0x5105, 0x837E, 0x5108,
+	0x8380, 0x5109, 0x8381, 0x510A, 0x8382, 0x510C, 0x8383, 0x510D,
+	0x8384, 0x510E, 0x8385, 0x510F, 0x8386, 0x5110, 0x8387, 0x5111,
+	0x8388, 0x5113, 0x8389, 0x5114, 0x838A, 0x5115, 0x838B, 0x5116,
+	0x838C, 0x5117, 0x838D, 0x5118, 0x838E, 0x5119, 0x838F, 0x511A,
+	0x8390, 0x511B, 0x8391, 0x511C, 0x8392, 0x511D, 0x8393, 0x511E,
+	0x8394, 0x511F, 0x8395, 0x5120, 0x8396, 0x5122, 0x8397, 0x5123,
+	0x8398, 0x5124, 0x8399, 0x5125, 0x839A, 0x5126, 0x839B, 0x5127,
+	0x839C, 0x5128, 0x839D, 0x5129, 0x839E, 0x512A, 0x839F, 0x512B,
+	0x83A0, 0x512C, 0x83A1, 0x512D, 0x83A2, 0x512E, 0x83A3, 0x512F,
+	0x83A4, 0x5130, 0x83A5, 0x5131, 0x83A6, 0x5132, 0x83A7, 0x5133,
+	0x83A8, 0x5134, 0x83A9, 0x5135, 0x83AA, 0x5136, 0x83AB, 0x5137,
+	0x83AC, 0x5138, 0x83AD, 0x5139, 0x83AE, 0x513A, 0x83AF, 0x513B,
+	0x83B0, 0x513C, 0x83B1, 0x513D, 0x83B2, 0x513E, 0x83B3, 0x5142,
+	0x83B4, 0x5147, 0x83B5, 0x514A, 0x83B6, 0x514C, 0x83B7, 0x514E,
+	0x83B8, 0x514F, 0x83B9, 0x5150, 0x83BA, 0x5152, 0x83BB, 0x5153,
+	0x83BC, 0x5157, 0x83BD, 0x5158, 0x83BE, 0x5159, 0x83BF, 0x515B,
+	0x83C0, 0x515D, 0x83C1, 0x515E, 0x83C2, 0x515F, 0x83C3, 0x5160,
+	0x83C4, 0x5161, 0x83C5, 0x5163, 0x83C6, 0x5164, 0x83C7, 0x5166,
+	0x83C8, 0x5167, 0x83C9, 0x5169, 0x83CA, 0x516A, 0x83CB, 0x516F,
+	0x83CC, 0x5172, 0x83CD, 0x517A, 0x83CE, 0x517E, 0x83CF, 0x517F,
+	0x83D0, 0x5183, 0x83D1, 0x5184, 0x83D2, 0x5186, 0x83D3, 0x5187,
+	0x83D4, 0x518A, 0x83D5, 0x518B, 0x83D6, 0x518E, 0x83D7, 0x518F,
+	0x83D8, 0x5190, 0x83D9, 0x5191, 0x83DA, 0x5193, 0x83DB, 0x5194,
+	0x83DC, 0x5198, 0x83DD, 0x519A, 0x83DE, 0x519D, 0x83DF, 0x519E,
+	0x83E0, 0x519F, 0x83E1, 0x51A1, 0x83E2, 0x51A3, 0x83E3, 0x51A6,
+	0x83E4, 0x51A7, 0x83E5, 0x51A8, 0x83E6, 0x51A9, 0x83E7, 0x51AA,
+	0x83E8, 0x51AD, 0x83E9, 0x51AE, 0x83EA, 0x51B4, 0x83EB, 0x51B8,
+	0x83EC, 0x51B9, 0x83ED, 0x51BA, 0x83EE, 0x51BE, 0x83EF, 0x51BF,
+	0x83F0, 0x51C1, 0x83F1, 0x51C2, 0x83F2, 0x51C3, 0x83F3, 0x51C5,
+	0x83F4, 0x51C8, 0x83F5, 0x51CA, 0x83F6, 0x51CD, 0x83F7, 0x51CE,
+	0x83F8, 0x51D0, 0x83F9, 0x51D2, 0x83FA, 0x51D3, 0x83FB, 0x51D4,
+	0x83FC, 0x51D5, 0x83FD, 0x51D6, 0x83FE, 0x51D7, 0x8440, 0x51D8,
+	0x8441, 0x51D9, 0x8442, 0x51DA, 0x8443, 0x51DC, 0x8444, 0x51DE,
+	0x8445, 0x51DF, 0x8446, 0x51E2, 0x8447, 0x51E3, 0x8448, 0x51E5,
+	0x8449, 0x51E6, 0x844A, 0x51E7, 0x844B, 0x51E8, 0x844C, 0x51E9,
+	0x844D, 0x51EA, 0x844E, 0x51EC, 0x844F, 0x51EE, 0x8450, 0x51F1,
+	0x8451, 0x51F2, 0x8452, 0x51F4, 0x8453, 0x51F7, 0x8454, 0x51FE,
+	0x8455, 0x5204, 0x8456, 0x5205, 0x8457, 0x5209, 0x8458, 0x520B,
+	0x8459, 0x520C, 0x845A, 0x520F, 0x845B, 0x5210, 0x845C, 0x5213,
+	0x845D, 0x5214, 0x845E, 0x5215, 0x845F, 0x521C, 0x8460, 0x521E,
+	0x8461, 0x521F, 0x8462, 0x5221, 0x8463, 0x5222, 0x8464, 0x5223,
+	0x8465, 0x5225, 0x8466, 0x5226, 0x8467, 0x5227, 0x8468, 0x522A,
+	0x8469, 0x522C, 0x846A, 0x522F, 0x846B, 0x5231, 0x846C, 0x5232,
+	0x846D, 0x5234, 0x846E, 0x5235, 0x846F, 0x523C, 0x8470, 0x523E,
+	0x8471, 0x5244, 0x8472, 0x5245, 0x8473, 0x5246, 0x8474, 0x5247,
+	0x8475, 0x5248, 0x8476, 0x5249, 0x8477, 0x524B, 0x8478, 0x524E,
+	0x8479, 0x524F, 0x847A, 0x5252, 0x847B, 0x5253, 0x847C, 0x5255,
+	0x847D, 0x5257, 0x847E, 0x5258, 0x8480, 0x5259, 0x8481, 0x525A,
+	0x8482, 0x525B, 0x8483, 0x525D, 0x8484, 0x525F, 0x8485, 0x5260,
+	0x8486, 0x5262, 0x8487, 0x5263, 0x8488, 0x5264, 0x8489, 0x5266,
+	0x848A, 0x5268, 0x848B, 0x526B, 0x848C, 0x526C, 0x848D, 0x526D,
+	0x848E, 0x526E, 0x848F, 0x5270, 0x8490, 0x5271, 0x8491, 0x5273,
+	0x8492, 0x5274, 0x8493, 0x5275, 0x8494, 0x5276, 0x8495, 0x5277,
+	0x8496, 0x5278, 0x8497, 0x5279, 0x8498, 0x527A, 0x8499, 0x527B,
+	0x849A, 0x527C, 0x849B, 0x527E, 0x849C, 0x5280, 0x849D, 0x5283,
+	0x849E, 0x5284, 0x849F, 0x5285, 0x84A0, 0x5286, 0x84A1, 0x5287,
+	0x84A2, 0x5289, 0x84A3, 0x528A, 0x84A4, 0x528B, 0x84A5, 0x528C,
+	0x84A6, 0x528D, 0x84A7, 0x528E, 0x84A8, 0x528F, 0x84A9, 0x5291,
+	0x84AA, 0x5292, 0x84AB, 0x5294, 0x84AC, 0x5295, 0x84AD, 0x5296,
+	0x84AE, 0x5297, 0x84AF, 0x5298, 0x84B0, 0x5299, 0x84B1, 0x529A,
+	0x84B2, 0x529C, 0x84B3, 0x52A4, 0x84B4, 0x52A5, 0x84B5, 0x52A6,
+	0x84B6, 0x52A7, 0x84B7, 0x52AE, 0x84B8, 0x52AF, 0x84B9, 0x52B0,
+	0x84BA, 0x52B4, 0x84BB, 0x52B5, 0x84BC, 0x52B6, 0x84BD, 0x52B7,
+	0x84BE, 0x52B8, 0x84BF, 0x52B9, 0x84C0, 0x52BA, 0x84C1, 0x52BB,
+	0x84C2, 0x52BC, 0x84C3, 0x52BD, 0x84C4, 0x52C0, 0x84C5, 0x52C1,
+	0x84C6, 0x52C2, 0x84C7, 0x52C4, 0x84C8, 0x52C5, 0x84C9, 0x52C6,
+	0x84CA, 0x52C8, 0x84CB, 0x52CA, 0x84CC, 0x52CC, 0x84CD, 0x52CD,
+	0x84CE, 0x52CE, 0x84CF, 0x52CF, 0x84D0, 0x52D1, 0x84D1, 0x52D3,
+	0x84D2, 0x52D4, 0x84D3, 0x52D5, 0x84D4, 0x52D7, 0x84D5, 0x52D9,
+	0x84D6, 0x52DA, 0x84D7, 0x52DB, 0x84D8, 0x52DC, 0x84D9, 0x52DD,
+	0x84DA, 0x52DE, 0x84DB, 0x52E0, 0x84DC, 0x52E1, 0x84DD, 0x52E2,
+	0x84DE, 0x52E3, 0x84DF, 0x52E5, 0x84E0, 0x52E6, 0x84E1, 0x52E7,
+	0x84E2, 0x52E8, 0x84E3, 0x52E9, 0x84E4, 0x52EA, 0x84E5, 0x52EB,
+	0x84E6, 0x52EC, 0x84E7, 0x52ED, 0x84E8, 0x52EE, 0x84E9, 0x52EF,
+	0x84EA, 0x52F1, 0x84EB, 0x52F2, 0x84EC, 0x52F3, 0x84ED, 0x52F4,
+	0x84EE, 0x52F5, 0x84EF, 0x52F6, 0x84F0, 0x52F7, 0x84F1, 0x52F8,
+	0x84F2, 0x52FB, 0x84F3, 0x52FC, 0x84F4, 0x52FD, 0x84F5, 0x5301,
+	0x84F6, 0x5302, 0x84F7, 0x5303, 0x84F8, 0x5304, 0x84F9, 0x5307,
+	0x84FA, 0x5309, 0x84FB, 0x530A, 0x84FC, 0x530B, 0x84FD, 0x530C,
+	0x84FE, 0x530E, 0x8540, 0x5311, 0x8541, 0x5312, 0x8542, 0x5313,
+	0x8543, 0x5314, 0x8544, 0x5318, 0x8545, 0x531B, 0x8546, 0x531C,
+	0x8547, 0x531E, 0x8548, 0x531F, 0x8549, 0x5322, 0x854A, 0x5324,
+	0x854B, 0x5325, 0x854C, 0x5327, 0x854D, 0x5328, 0x854E, 0x5329,
+	0x854F, 0x532B, 0x8550, 0x532C, 0x8551, 0x532D, 0x8552, 0x532F,
+	0x8553, 0x5330, 0x8554, 0x5331, 0x8555, 0x5332, 0x8556, 0x5333,
+	0x8557, 0x5334, 0x8558, 0x5335, 0x8559, 0x5336, 0x855A, 0x5337,
+	0x855B, 0x5338, 0x855C, 0x533C, 0x855D, 0x533D, 0x855E, 0x5340,
+	0x855F, 0x5342, 0x8560, 0x5344, 0x8561, 0x5346, 0x8562, 0x534B,
+	0x8563, 0x534C, 0x8564, 0x534D, 0x8565, 0x5350, 0x8566, 0x5354,
+	0x8567, 0x5358, 0x8568, 0x5359, 0x8569, 0x535B, 0x856A, 0x535D,
+	0x856B, 0x5365, 0x856C, 0x5368, 0x856D, 0x536A, 0x856E, 0x536C,
+	0x856F, 0x536D, 0x8570, 0x5372, 0x8571, 0x5376, 0x8572, 0x5379,
+	0x8573, 0x537B, 0x8574, 0x537C, 0x8575, 0x537D, 0x8576, 0x537E,
+	0x8577, 0x5380, 0x8578, 0x5381, 0x8579, 0x5383, 0x857A, 0x5387,
+	0x857B, 0x5388, 0x857C, 0x538A, 0x857D, 0x538E, 0x857E, 0x538F,
+	0x8580, 0x5390, 0x8581, 0x5391, 0x8582, 0x5392, 0x8583, 0x5393,
+	0x8584, 0x5394, 0x8585, 0x5396, 0x8586, 0x5397, 0x8587, 0x5399,
+	0x8588, 0x539B, 0x8589, 0x539C, 0x858A, 0x539E, 0x858B, 0x53A0,
+	0x858C, 0x53A1, 0x858D, 0x53A4, 0x858E, 0x53A7, 0x858F, 0x53AA,
+	0x8590, 0x53AB, 0x8591, 0x53AC, 0x8592, 0x53AD, 0x8593, 0x53AF,
+	0x8594, 0x53B0, 0x8595, 0x53B1, 0x8596, 0x53B2, 0x8597, 0x53B3,
+	0x8598, 0x53B4, 0x8599, 0x53B5, 0x859A, 0x53B7, 0x859B, 0x53B8,
+	0x859C, 0x53B9, 0x859D, 0x53BA, 0x859E, 0x53BC, 0x859F, 0x53BD,
+	0x85A0, 0x53BE, 0x85A1, 0x53C0, 0x85A2, 0x53C3, 0x85A3, 0x53C4,
+	0x85A4, 0x53C5, 0x85A5, 0x53C6, 0x85A6, 0x53C7, 0x85A7, 0x53CE,
+	0x85A8, 0x53CF, 0x85A9, 0x53D0, 0x85AA, 0x53D2, 0x85AB, 0x53D3,
+	0x85AC, 0x53D5, 0x85AD, 0x53DA, 0x85AE, 0x53DC, 0x85AF, 0x53DD,
+	0x85B0, 0x53DE, 0x85B1, 0x53E1, 0x85B2, 0x53E2, 0x85B3, 0x53E7,
+	0x85B4, 0x53F4, 0x85B5, 0x53FA, 0x85B6, 0x53FE, 0x85B7, 0x53FF,
+	0x85B8, 0x5400, 0x85B9, 0x5402, 0x85BA, 0x5405, 0x85BB, 0x5407,
+	0x85BC, 0x540B, 0x85BD, 0x5414, 0x85BE, 0x5418, 0x85BF, 0x5419,
+	0x85C0, 0x541A, 0x85C1, 0x541C, 0x85C2, 0x5422, 0x85C3, 0x5424,
+	0x85C4, 0x5425, 0x85C5, 0x542A, 0x85C6, 0x5430, 0x85C7, 0x5433,
+	0x85C8, 0x5436, 0x85C9, 0x5437, 0x85CA, 0x543A, 0x85CB, 0x543D,
+	0x85CC, 0x543F, 0x85CD, 0x5441, 0x85CE, 0x5442, 0x85CF, 0x5444,
+	0x85D0, 0x5445, 0x85D1, 0x5447, 0x85D2, 0x5449, 0x85D3, 0x544C,
+	0x85D4, 0x544D, 0x85D5, 0x544E, 0x85D6, 0x544F, 0x85D7, 0x5451,
+	0x85D8, 0x545A, 0x85D9, 0x545D, 0x85DA, 0x545E, 0x85DB, 0x545F,
+	0x85DC, 0x5460, 0x85DD, 0x5461, 0x85DE, 0x5463, 0x85DF, 0x5465,
+	0x85E0, 0x5467, 0x85E1, 0x5469, 0x85E2, 0x546A, 0x85E3, 0x546B,
+	0x85E4, 0x546C, 0x85E5, 0x546D, 0x85E6, 0x546E, 0x85E7, 0x546F,
+	0x85E8, 0x5470, 0x85E9, 0x5474, 0x85EA, 0x5479, 0x85EB, 0x547A,
+	0x85EC, 0x547E, 0x85ED, 0x547F, 0x85EE, 0x5481, 0x85EF, 0x5483,
+	0x85F0, 0x5485, 0x85F1, 0x5487, 0x85F2, 0x5488, 0x85F3, 0x5489,
+	0x85F4, 0x548A, 0x85F5, 0x548D, 0x85F6, 0x5491, 0x85F7, 0x5493,
+	0x85F8, 0x5497, 0x85F9, 0x5498, 0x85FA, 0x549C, 0x85FB, 0x549E,
+	0x85FC, 0x549F, 0x85FD, 0x54A0, 0x85FE, 0x54A1, 0x8640, 0x54A2,
+	0x8641, 0x54A5, 0x8642, 0x54AE, 0x8643, 0x54B0, 0x8644, 0x54B2,
+	0x8645, 0x54B5, 0x8646, 0x54B6, 0x8647, 0x54B7, 0x8648, 0x54B9,
+	0x8649, 0x54BA, 0x864A, 0x54BC, 0x864B, 0x54BE, 0x864C, 0x54C3,
+	0x864D, 0x54C5, 0x864E, 0x54CA, 0x864F, 0x54CB, 0x8650, 0x54D6,
+	0x8651, 0x54D8, 0x8652, 0x54DB, 0x8653, 0x54E0, 0x8654, 0x54E1,
+	0x8655, 0x54E2, 0x8656, 0x54E3, 0x8657, 0x54E4, 0x8658, 0x54EB,
+	0x8659, 0x54EC, 0x865A, 0x54EF, 0x865B, 0x54F0, 0x865C, 0x54F1,
+	0x865D, 0x54F4, 0x865E, 0x54F5, 0x865F, 0x54F6, 0x8660, 0x54F7,
+	0x8661, 0x54F8, 0x8662, 0x54F9, 0x8663, 0x54FB, 0x8664, 0x54FE,
+	0x8665, 0x5500, 0x8666, 0x5502, 0x8667, 0x5503, 0x8668, 0x5504,
+	0x8669, 0x5505, 0x866A, 0x5508, 0x866B, 0x550A, 0x866C, 0x550B,
+	0x866D, 0x550C, 0x866E, 0x550D, 0x866F, 0x550E, 0x8670, 0x5512,
+	0x8671, 0x5513, 0x8672, 0x5515, 0x8673, 0x5516, 0x8674, 0x5517,
+	0x8675, 0x5518, 0x8676, 0x5519, 0x8677, 0x551A, 0x8678, 0x551C,
+	0x8679, 0x551D, 0x867A, 0x551E, 0x867B, 0x551F, 0x867C, 0x5521,
+	0x867D, 0x5525, 0x867E, 0x5526, 0x8680, 0x5528, 0x8681, 0x5529,
+	0x8682, 0x552B, 0x8683, 0x552D, 0x8684, 0x5532, 0x8685, 0x5534,
+	0x8686, 0x5535, 0x8687, 0x5536, 0x8688, 0x5538, 0x8689, 0x5539,
+	0x868A, 0x553A, 0x868B, 0x553B, 0x868C, 0x553D, 0x868D, 0x5540,
+	0x868E, 0x5542, 0x868F, 0x5545, 0x8690, 0x5547, 0x8691, 0x5548,
+	0x8692, 0x554B, 0x8693, 0x554C, 0x8694, 0x554D, 0x8695, 0x554E,
+	0x8696, 0x554F, 0x8697, 0x5551, 0x8698, 0x5552, 0x8699, 0x5553,
+	0x869A, 0x5554, 0x869B, 0x5557, 0x869C, 0x5558, 0x869D, 0x5559,
+	0x869E, 0x555A, 0x869F, 0x555B, 0x86A0, 0x555D, 0x86A1, 0x555E,
+	0x86A2, 0x555F, 0x86A3, 0x5560, 0x86A4, 0x5562, 0x86A5, 0x5563,
+	0x86A6, 0x5568, 0x86A7, 0x5569, 0x86A8, 0x556B, 0x86A9, 0x556F,
+	0x86AA, 0x5570, 0x86AB, 0x5571, 0x86AC, 0x5572, 0x86AD, 0x5573,
+	0x86AE, 0x5574, 0x86AF, 0x5579, 0x86B0, 0x557A, 0x86B1, 0x557D,
+	0x86B2, 0x557F, 0x86B3, 0x5585, 0x86B4, 0x5586, 0x86B5, 0x558C,
+	0x86B6, 0x558D, 0x86B7, 0x558E, 0x86B8, 0x5590, 0x86B9, 0x5592,
+	0x86BA, 0x5593, 0x86BB, 0x5595, 0x86BC, 0x5596, 0x86BD, 0x5597,
+	0x86BE, 0x559A, 0x86BF, 0x559B, 0x86C0, 0x559E, 0x86C1, 0x55A0,
+	0x86C2, 0x55A1, 0x86C3, 0x55A2, 0x86C4, 0x55A3, 0x86C5, 0x55A4,
+	0x86C6, 0x55A5, 0x86C7, 0x55A6, 0x86C8, 0x55A8, 0x86C9, 0x55A9,
+	0x86CA, 0x55AA, 0x86CB, 0x55AB, 0x86CC, 0x55AC, 0x86CD, 0x55AD,
+	0x86CE, 0x55AE, 0x86CF, 0x55AF, 0x86D0, 0x55B0, 0x86D1, 0x55B2,
+	0x86D2, 0x55B4, 0x86D3, 0x55B6, 0x86D4, 0x55B8, 0x86D5, 0x55BA,
+	0x86D6, 0x55BC, 0x86D7, 0x55BF, 0x86D8, 0x55C0, 0x86D9, 0x55C1,
+	0x86DA, 0x55C2, 0x86DB, 0x55C3, 0x86DC, 0x55C6, 0x86DD, 0x55C7,
+	0x86DE, 0x55C8, 0x86DF, 0x55CA, 0x86E0, 0x55CB, 0x86E1, 0x55CE,
+	0x86E2, 0x55CF, 0x86E3, 0x55D0, 0x86E4, 0x55D5, 0x86E5, 0x55D7,
+	0x86E6, 0x55D8, 0x86E7, 0x55D9, 0x86E8, 0x55DA, 0x86E9, 0x55DB,
+	0x86EA, 0x55DE, 0x86EB, 0x55E0, 0x86EC, 0x55E2, 0x86ED, 0x55E7,
+	0x86EE, 0x55E9, 0x86EF, 0x55ED, 0x86F0, 0x55EE, 0x86F1, 0x55F0,
+	0x86F2, 0x55F1, 0x86F3, 0x55F4, 0x86F4, 0x55F6, 0x86F5, 0x55F8,
+	0x86F6, 0x55F9, 0x86F7, 0x55FA, 0x86F8, 0x55FB, 0x86F9, 0x55FC,
+	0x86FA, 0x55FF, 0x86FB, 0x5602, 0x86FC, 0x5603, 0x86FD, 0x5604,
+	0x86FE, 0x5605, 0x8740, 0x5606, 0x8741, 0x5607, 0x8742, 0x560A,
+	0x8743, 0x560B, 0x8744, 0x560D, 0x8745, 0x5610, 0x8746, 0x5611,
+	0x8747, 0x5612, 0x8748, 0x5613, 0x8749, 0x5614, 0x874A, 0x5615,
+	0x874B, 0x5616, 0x874C, 0x5617, 0x874D, 0x5619, 0x874E, 0x561A,
+	0x874F, 0x561C, 0x8750, 0x561D, 0x8751, 0x5620, 0x8752, 0x5621,
+	0x8753, 0x5622, 0x8754, 0x5625, 0x8755, 0x5626, 0x8756, 0x5628,
+	0x8757, 0x5629, 0x8758, 0x562A, 0x8759, 0x562B, 0x875A, 0x562E,
+	0x875B, 0x562F, 0x875C, 0x5630, 0x875D, 0x5633, 0x875E, 0x5635,
+	0x875F, 0x5637, 0x8760, 0x5638, 0x8761, 0x563A, 0x8762, 0x563C,
+	0x8763, 0x563D, 0x8764, 0x563E, 0x8765, 0x5640, 0x8766, 0x5641,
+	0x8767, 0x5642, 0x8768, 0x5643, 0x8769, 0x5644, 0x876A, 0x5645,
+	0x876B, 0x5646, 0x876C, 0x5647, 0x876D, 0x5648, 0x876E, 0x5649,
+	0x876F, 0x564A, 0x8770, 0x564B, 0x8771, 0x564F, 0x8772, 0x5650,
+	0x8773, 0x5651, 0x8774, 0x5652, 0x8775, 0x5653, 0x8776, 0x5655,
+	0x8777, 0x5656, 0x8778, 0x565A, 0x8779, 0x565B, 0x877A, 0x565D,
+	0x877B, 0x565E, 0x877C, 0x565F, 0x877D, 0x5660, 0x877E, 0x5661,
+	0x8780, 0x5663, 0x8781, 0x5665, 0x8782, 0x5666, 0x8783, 0x5667,
+	0x8784, 0x566D, 0x8785, 0x566E, 0x8786, 0x566F, 0x8787, 0x5670,
+	0x8788, 0x5672, 0x8789, 0x5673, 0x878A, 0x5674, 0x878B, 0x5675,
+	0x878C, 0x5677, 0x878D, 0x5678, 0x878E, 0x5679, 0x878F, 0x567A,
+	0x8790, 0x567D, 0x8791, 0x567E, 0x8792, 0x567F, 0x8793, 0x5680,
+	0x8794, 0x5681, 0x8795, 0x5682, 0x8796, 0x5683, 0x8797, 0x5684,
+	0x8798, 0x5687, 0x8799, 0x5688, 0x879A, 0x5689, 0x879B, 0x568A,
+	0x879C, 0x568B, 0x879D, 0x568C, 0x879E, 0x568D, 0x879F, 0x5690,
+	0x87A0, 0x5691, 0x87A1, 0x5692, 0x87A2, 0x5694, 0x87A3, 0x5695,
+	0x87A4, 0x5696, 0x87A5, 0x5697, 0x87A6, 0x5698, 0x87A7, 0x5699,
+	0x87A8, 0x569A, 0x87A9, 0x569B, 0x87AA, 0x569C, 0x87AB, 0x569D,
+	0x87AC, 0x569E, 0x87AD, 0x569F, 0x87AE, 0x56A0, 0x87AF, 0x56A1,
+	0x87B0, 0x56A2, 0x87B1, 0x56A4, 0x87B2, 0x56A5, 0x87B3, 0x56A6,
+	0x87B4, 0x56A7, 0x87B5, 0x56A8, 0x87B6, 0x56A9, 0x87B7, 0x56AA,
+	0x87B8, 0x56AB, 0x87B9, 0x56AC, 0x87BA, 0x56AD, 0x87BB, 0x56AE,
+	0x87BC, 0x56B0, 0x87BD, 0x56B1, 0x87BE, 0x56B2, 0x87BF, 0x56B3,
+	0x87C0, 0x56B4, 0x87C1, 0x56B5, 0x87C2, 0x56B6, 0x87C3, 0x56B8,
+	0x87C4, 0x56B9, 0x87C5, 0x56BA, 0x87C6, 0x56BB, 0x87C7, 0x56BD,
+	0x87C8, 0x56BE, 0x87C9, 0x56BF, 0x87CA, 0x56C0, 0x87CB, 0x56C1,
+	0x87CC, 0x56C2, 0x87CD, 0x56C3, 0x87CE, 0x56C4, 0x87CF, 0x56C5,
+	0x87D0, 0x56C6, 0x87D1, 0x56C7, 0x87D2, 0x56C8, 0x87D3, 0x56C9,
+	0x87D4, 0x56CB, 0x87D5, 0x56CC, 0x87D6, 0x56CD, 0x87D7, 0x56CE,
+	0x87D8, 0x56CF, 0x87D9, 0x56D0, 0x87DA, 0x56D1, 0x87DB, 0x56D2,
+	0x87DC, 0x56D3, 0x87DD, 0x56D5, 0x87DE, 0x56D6, 0x87DF, 0x56D8,
+	0x87E0, 0x56D9, 0x87E1, 0x56DC, 0x87E2, 0x56E3, 0x87E3, 0x56E5,
+	0x87E4, 0x56E6, 0x87E5, 0x56E7, 0x87E6, 0x56E8, 0x87E7, 0x56E9,
+	0x87E8, 0x56EA, 0x87E9, 0x56EC, 0x87EA, 0x56EE, 0x87EB, 0x56EF,
+	0x87EC, 0x56F2, 0x87ED, 0x56F3, 0x87EE, 0x56F6, 0x87EF, 0x56F7,
+	0x87F0, 0x56F8, 0x87F1, 0x56FB, 0x87F2, 0x56FC, 0x87F3, 0x5700,
+	0x87F4, 0x5701, 0x87F5, 0x5702, 0x87F6, 0x5705, 0x87F7, 0x5707,
+	0x87F8, 0x570B, 0x87F9, 0x570C, 0x87FA, 0x570D, 0x87FB, 0x570E,
+	0x87FC, 0x570F, 0x87FD, 0x5710, 0x87FE, 0x5711, 0x8840, 0x5712,
+	0x8841, 0x5713, 0x8842, 0x5714, 0x8843, 0x5715, 0x8844, 0x5716,
+	0x8845, 0x5717, 0x8846, 0x5718, 0x8847, 0x5719, 0x8848, 0x571A,
+	0x8849, 0x571B, 0x884A, 0x571D, 0x884B, 0x571E, 0x884C, 0x5720,
+	0x884D, 0x5721, 0x884E, 0x5722, 0x884F, 0x5724, 0x8850, 0x5725,
+	0x8851, 0x5726, 0x8852, 0x5727, 0x8853, 0x572B, 0x8854, 0x5731,
+	0x8855, 0x5732, 0x8856, 0x5734, 0x8857, 0x5735, 0x8858, 0x5736,
+	0x8859, 0x5737, 0x885A, 0x5738, 0x885B, 0x573C, 0x885C, 0x573D,
+	0x885D, 0x573F, 0x885E, 0x5741, 0x885F, 0x5743, 0x8860, 0x5744,
+	0x8861, 0x5745, 0x8862, 0x5746, 0x8863, 0x5748, 0x8864, 0x5749,
+	0x8865, 0x574B, 0x8866, 0x5752, 0x8867, 0x5753, 0x8868, 0x5754,
+	0x8869, 0x5755, 0x886A, 0x5756, 0x886B, 0x5758, 0x886C, 0x5759,
+	0x886D, 0x5762, 0x886E, 0x5763, 0x886F, 0x5765, 0x8870, 0x5767,
+	0x8871, 0x576C, 0x8872, 0x576E, 0x8873, 0x5770, 0x8874, 0x5771,
+	0x8875, 0x5772, 0x8876, 0x5774, 0x8877, 0x5775, 0x8878, 0x5778,
+	0x8879, 0x5779, 0x887A, 0x577A, 0x887B, 0x577D, 0x887C, 0x577E,
+	0x887D, 0x577F, 0x887E, 0x5780, 0x8880, 0x5781, 0x8881, 0x5787,
+	0x8882, 0x5788, 0x8883, 0x5789, 0x8884, 0x578A, 0x8885, 0x578D,
+	0x8886, 0x578E, 0x8887, 0x578F, 0x8888, 0x5790, 0x8889, 0x5791,
+	0x888A, 0x5794, 0x888B, 0x5795, 0x888C, 0x5796, 0x888D, 0x5797,
+	0x888E, 0x5798, 0x888F, 0x5799, 0x8890, 0x579A, 0x8891, 0x579C,
+	0x8892, 0x579D, 0x8893, 0x579E, 0x8894, 0x579F, 0x8895, 0x57A5,
+	0x8896, 0x57A8, 0x8897, 0x57AA, 0x8898, 0x57AC, 0x8899, 0x57AF,
+	0x889A, 0x57B0, 0x889B, 0x57B1, 0x889C, 0x57B3, 0x889D, 0x57B5,
+	0x889E, 0x57B6, 0x889F, 0x57B7, 0x88A0, 0x57B9, 0x88A1, 0x57BA,
+	0x88A2, 0x57BB, 0x88A3, 0x57BC, 0x88A4, 0x57BD, 0x88A5, 0x57BE,
+	0x88A6, 0x57BF, 0x88A7, 0x57C0, 0x88A8, 0x57C1, 0x88A9, 0x57C4,
+	0x88AA, 0x57C5, 0x88AB, 0x57C6, 0x88AC, 0x57C7, 0x88AD, 0x57C8,
+	0x88AE, 0x57C9, 0x88AF, 0x57CA, 0x88B0, 0x57CC, 0x88B1, 0x57CD,
+	0x88B2, 0x57D0, 0x88B3, 0x57D1, 0x88B4, 0x57D3, 0x88B5, 0x57D6,
+	0x88B6, 0x57D7, 0x88B7, 0x57DB, 0x88B8, 0x57DC, 0x88B9, 0x57DE,
+	0x88BA, 0x57E1, 0x88BB, 0x57E2, 0x88BC, 0x57E3, 0x88BD, 0x57E5,
+	0x88BE, 0x57E6, 0x88BF, 0x57E7, 0x88C0, 0x57E8, 0x88C1, 0x57E9,
+	0x88C2, 0x57EA, 0x88C3, 0x57EB, 0x88C4, 0x57EC, 0x88C5, 0x57EE,
+	0x88C6, 0x57F0, 0x88C7, 0x57F1, 0x88C8, 0x57F2, 0x88C9, 0x57F3,
+	0x88CA, 0x57F5, 0x88CB, 0x57F6, 0x88CC, 0x57F7, 0x88CD, 0x57FB,
+	0x88CE, 0x57FC, 0x88CF, 0x57FE, 0x88D0, 0x57FF, 0x88D1, 0x5801,
+	0x88D2, 0x5803, 0x88D3, 0x5804, 0x88D4, 0x5805, 0x88D5, 0x5808,
+	0x88D6, 0x5809, 0x88D7, 0x580A, 0x88D8, 0x580C, 0x88D9, 0x580E,
+	0x88DA, 0x580F, 0x88DB, 0x5810, 0x88DC, 0x5812, 0x88DD, 0x5813,
+	0x88DE, 0x5814, 0x88DF, 0x5816, 0x88E0, 0x5817, 0x88E1, 0x5818,
+	0x88E2, 0x581A, 0x88E3, 0x581B, 0x88E4, 0x581C, 0x88E5, 0x581D,
+	0x88E6, 0x581F, 0x88E7, 0x5822, 0x88E8, 0x5823, 0x88E9, 0x5825,
+	0x88EA, 0x5826, 0x88EB, 0x5827, 0x88EC, 0x5828, 0x88ED, 0x5829,
+	0x88EE, 0x582B, 0x88EF, 0x582C, 0x88F0, 0x582D, 0x88F1, 0x582E,
+	0x88F2, 0x582F, 0x88F3, 0x5831, 0x88F4, 0x5832, 0x88F5, 0x5833,
+	0x88F6, 0x5834, 0x88F7, 0x5836, 0x88F8, 0x5837, 0x88F9, 0x5838,
+	0x88FA, 0x5839, 0x88FB, 0x583A, 0x88FC, 0x583B, 0x88FD, 0x583C,
+	0x88FE, 0x583D, 0x8940, 0x583E, 0x8941, 0x583F, 0x8942, 0x5840,
+	0x8943, 0x5841, 0x8944, 0x5842, 0x8945, 0x5843, 0x8946, 0x5845,
+	0x8947, 0x5846, 0x8948, 0x5847, 0x8949, 0x5848, 0x894A, 0x5849,
+	0x894B, 0x584A, 0x894C, 0x584B, 0x894D, 0x584E, 0x894E, 0x584F,
+	0x894F, 0x5850, 0x8950, 0x5852, 0x8951, 0x5853, 0x8952, 0x5855,
+	0x8953, 0x5856, 0x8954, 0x5857, 0x8955, 0x5859, 0x8956, 0x585A,
+	0x8957, 0x585B, 0x8958, 0x585C, 0x8959, 0x585D, 0x895A, 0x585F,
+	0x895B, 0x5860, 0x895C, 0x5861, 0x895D, 0x5862, 0x895E, 0x5863,
+	0x895F, 0x5864, 0x8960, 0x5866, 0x8961, 0x5867, 0x8962, 0x5868,
+	0x8963, 0x5869, 0x8964, 0x586A, 0x8965, 0x586D, 0x8966, 0x586E,
+	0x8967, 0x586F, 0x8968, 0x5870, 0x8969, 0x5871, 0x896A, 0x5872,
+	0x896B, 0x5873, 0x896C, 0x5874, 0x896D, 0x5875, 0x896E, 0x5876,
+	0x896F, 0x5877, 0x8970, 0x5878, 0x8971, 0x5879, 0x8972, 0x587A,
+	0x8973, 0x587B, 0x8974, 0x587C, 0x8975, 0x587D, 0x8976, 0x587F,
+	0x8977, 0x5882, 0x8978, 0x5884, 0x8979, 0x5886, 0x897A, 0x5887,
+	0x897B, 0x5888, 0x897C, 0x588A, 0x897D, 0x588B, 0x897E, 0x588C,
+	0x8980, 0x588D, 0x8981, 0x588E, 0x8982, 0x588F, 0x8983, 0x5890,
+	0x8984, 0x5891, 0x8985, 0x5894, 0x8986, 0x5895, 0x8987, 0x5896,
+	0x8988, 0x5897, 0x8989, 0x5898, 0x898A, 0x589B, 0x898B, 0x589C,
+	0x898C, 0x589D, 0x898D, 0x58A0, 0x898E, 0x58A1, 0x898F, 0x58A2,
+	0x8990, 0x58A3, 0x8991, 0x58A4, 0x8992, 0x58A5, 0x8993, 0x58A6,
+	0x8994, 0x58A7, 0x8995, 0x58AA, 0x8996, 0x58AB, 0x8997, 0x58AC,
+	0x8998, 0x58AD, 0x8999, 0x58AE, 0x899A, 0x58AF, 0x899B, 0x58B0,
+	0x899C, 0x58B1, 0x899D, 0x58B2, 0x899E, 0x58B3, 0x899F, 0x58B4,
+	0x89A0, 0x58B5, 0x89A1, 0x58B6, 0x89A2, 0x58B7, 0x89A3, 0x58B8,
+	0x89A4, 0x58B9, 0x89A5, 0x58BA, 0x89A6, 0x58BB, 0x89A7, 0x58BD,
+	0x89A8, 0x58BE, 0x89A9, 0x58BF, 0x89AA, 0x58C0, 0x89AB, 0x58C2,
+	0x89AC, 0x58C3, 0x89AD, 0x58C4, 0x89AE, 0x58C6, 0x89AF, 0x58C7,
+	0x89B0, 0x58C8, 0x89B1, 0x58C9, 0x89B2, 0x58CA, 0x89B3, 0x58CB,
+	0x89B4, 0x58CC, 0x89B5, 0x58CD, 0x89B6, 0x58CE, 0x89B7, 0x58CF,
+	0x89B8, 0x58D0, 0x89B9, 0x58D2, 0x89BA, 0x58D3, 0x89BB, 0x58D4,
+	0x89BC, 0x58D6, 0x89BD, 0x58D7, 0x89BE, 0x58D8, 0x89BF, 0x58D9,
+	0x89C0, 0x58DA, 0x89C1, 0x58DB, 0x89C2, 0x58DC, 0x89C3, 0x58DD,
+	0x89C4, 0x58DE, 0x89C5, 0x58DF, 0x89C6, 0x58E0, 0x89C7, 0x58E1,
+	0x89C8, 0x58E2, 0x89C9, 0x58E3, 0x89CA, 0x58E5, 0x89CB, 0x58E6,
+	0x89CC, 0x58E7, 0x89CD, 0x58E8, 0x89CE, 0x58E9, 0x89CF, 0x58EA,
+	0x89D0, 0x58ED, 0x89D1, 0x58EF, 0x89D2, 0x58F1, 0x89D3, 0x58F2,
+	0x89D4, 0x58F4, 0x89D5, 0x58F5, 0x89D6, 0x58F7, 0x89D7, 0x58F8,
+	0x89D8, 0x58FA, 0x89D9, 0x58FB, 0x89DA, 0x58FC, 0x89DB, 0x58FD,
+	0x89DC, 0x58FE, 0x89DD, 0x58FF, 0x89DE, 0x5900, 0x89DF, 0x5901,
+	0x89E0, 0x5903, 0x89E1, 0x5905, 0x89E2, 0x5906, 0x89E3, 0x5908,
+	0x89E4, 0x5909, 0x89E5, 0x590A, 0x89E6, 0x590B, 0x89E7, 0x590C,
+	0x89E8, 0x590E, 0x89E9, 0x5910, 0x89EA, 0x5911, 0x89EB, 0x5912,
+	0x89EC, 0x5913, 0x89ED, 0x5917, 0x89EE, 0x5918, 0x89EF, 0x591B,
+	0x89F0, 0x591D, 0x89F1, 0x591E, 0x89F2, 0x5920, 0x89F3, 0x5921,
+	0x89F4, 0x5922, 0x89F5, 0x5923, 0x89F6, 0x5926, 0x89F7, 0x5928,
+	0x89F8, 0x592C, 0x89F9, 0x5930, 0x89FA, 0x5932, 0x89FB, 0x5933,
+	0x89FC, 0x5935, 0x89FD, 0x5936, 0x89FE, 0x593B, 0x8A40, 0x593D,
+	0x8A41, 0x593E, 0x8A42, 0x593F, 0x8A43, 0x5940, 0x8A44, 0x5943,
+	0x8A45, 0x5945, 0x8A46, 0x5946, 0x8A47, 0x594A, 0x8A48, 0x594C,
+	0x8A49, 0x594D, 0x8A4A, 0x5950, 0x8A4B, 0x5952, 0x8A4C, 0x5953,
+	0x8A4D, 0x5959, 0x8A4E, 0x595B, 0x8A4F, 0x595C, 0x8A50, 0x595D,
+	0x8A51, 0x595E, 0x8A52, 0x595F, 0x8A53, 0x5961, 0x8A54, 0x5963,
+	0x8A55, 0x5964, 0x8A56, 0x5966, 0x8A57, 0x5967, 0x8A58, 0x5968,
+	0x8A59, 0x5969, 0x8A5A, 0x596A, 0x8A5B, 0x596B, 0x8A5C, 0x596C,
+	0x8A5D, 0x596D, 0x8A5E, 0x596E, 0x8A5F, 0x596F, 0x8A60, 0x5970,
+	0x8A61, 0x5971, 0x8A62, 0x5972, 0x8A63, 0x5975, 0x8A64, 0x5977,
+	0x8A65, 0x597A, 0x8A66, 0x597B, 0x8A67, 0x597C, 0x8A68, 0x597E,
+	0x8A69, 0x597F, 0x8A6A, 0x5980, 0x8A6B, 0x5985, 0x8A6C, 0x5989,
+	0x8A6D, 0x598B, 0x8A6E, 0x598C, 0x8A6F, 0x598E, 0x8A70, 0x598F,
+	0x8A71, 0x5990, 0x8A72, 0x5991, 0x8A73, 0x5994, 0x8A74, 0x5995,
+	0x8A75, 0x5998, 0x8A76, 0x599A, 0x8A77, 0x599B, 0x8A78, 0x599C,
+	0x8A79, 0x599D, 0x8A7A, 0x599F, 0x8A7B, 0x59A0, 0x8A7C, 0x59A1,
+	0x8A7D, 0x59A2, 0x8A7E, 0x59A6, 0x8A80, 0x59A7, 0x8A81, 0x59AC,
+	0x8A82, 0x59AD, 0x8A83, 0x59B0, 0x8A84, 0x59B1, 0x8A85, 0x59B3,
+	0x8A86, 0x59B4, 0x8A87, 0x59B5, 0x8A88, 0x59B6, 0x8A89, 0x59B7,
+	0x8A8A, 0x59B8, 0x8A8B, 0x59BA, 0x8A8C, 0x59BC, 0x8A8D, 0x59BD,
+	0x8A8E, 0x59BF, 0x8A8F, 0x59C0, 0x8A90, 0x59C1, 0x8A91, 0x59C2,
+	0x8A92, 0x59C3, 0x8A93, 0x59C4, 0x8A94, 0x59C5, 0x8A95, 0x59C7,
+	0x8A96, 0x59C8, 0x8A97, 0x59C9, 0x8A98, 0x59CC, 0x8A99, 0x59CD,
+	0x8A9A, 0x59CE, 0x8A9B, 0x59CF, 0x8A9C, 0x59D5, 0x8A9D, 0x59D6,
+	0x8A9E, 0x59D9, 0x8A9F, 0x59DB, 0x8AA0, 0x59DE, 0x8AA1, 0x59DF,
+	0x8AA2, 0x59E0, 0x8AA3, 0x59E1, 0x8AA4, 0x59E2, 0x8AA5, 0x59E4,
+	0x8AA6, 0x59E6, 0x8AA7, 0x59E7, 0x8AA8, 0x59E9, 0x8AA9, 0x59EA,
+	0x8AAA, 0x59EB, 0x8AAB, 0x59ED, 0x8AAC, 0x59EE, 0x8AAD, 0x59EF,
+	0x8AAE, 0x59F0, 0x8AAF, 0x59F1, 0x8AB0, 0x59F2, 0x8AB1, 0x59F3,
+	0x8AB2, 0x59F4, 0x8AB3, 0x59F5, 0x8AB4, 0x59F6, 0x8AB5, 0x59F7,
+	0x8AB6, 0x59F8, 0x8AB7, 0x59FA, 0x8AB8, 0x59FC, 0x8AB9, 0x59FD,
+	0x8ABA, 0x59FE, 0x8ABB, 0x5A00, 0x8ABC, 0x5A02, 0x8ABD, 0x5A0A,
+	0x8ABE, 0x5A0B, 0x8ABF, 0x5A0D, 0x8AC0, 0x5A0E, 0x8AC1, 0x5A0F,
+	0x8AC2, 0x5A10, 0x8AC3, 0x5A12, 0x8AC4, 0x5A14, 0x8AC5, 0x5A15,
+	0x8AC6, 0x5A16, 0x8AC7, 0x5A17, 0x8AC8, 0x5A19, 0x8AC9, 0x5A1A,
+	0x8ACA, 0x5A1B, 0x8ACB, 0x5A1D, 0x8ACC, 0x5A1E, 0x8ACD, 0x5A21,
+	0x8ACE, 0x5A22, 0x8ACF, 0x5A24, 0x8AD0, 0x5A26, 0x8AD1, 0x5A27,
+	0x8AD2, 0x5A28, 0x8AD3, 0x5A2A, 0x8AD4, 0x5A2B, 0x8AD5, 0x5A2C,
+	0x8AD6, 0x5A2D, 0x8AD7, 0x5A2E, 0x8AD8, 0x5A2F, 0x8AD9, 0x5A30,
+	0x8ADA, 0x5A33, 0x8ADB, 0x5A35, 0x8ADC, 0x5A37, 0x8ADD, 0x5A38,
+	0x8ADE, 0x5A39, 0x8ADF, 0x5A3A, 0x8AE0, 0x5A3B, 0x8AE1, 0x5A3D,
+	0x8AE2, 0x5A3E, 0x8AE3, 0x5A3F, 0x8AE4, 0x5A41, 0x8AE5, 0x5A42,
+	0x8AE6, 0x5A43, 0x8AE7, 0x5A44, 0x8AE8, 0x5A45, 0x8AE9, 0x5A47,
+	0x8AEA, 0x5A48, 0x8AEB, 0x5A4B, 0x8AEC, 0x5A4C, 0x8AED, 0x5A4D,
+	0x8AEE, 0x5A4E, 0x8AEF, 0x5A4F, 0x8AF0, 0x5A50, 0x8AF1, 0x5A51,
+	0x8AF2, 0x5A52, 0x8AF3, 0x5A53, 0x8AF4, 0x5A54, 0x8AF5, 0x5A56,
+	0x8AF6, 0x5A57, 0x8AF7, 0x5A58, 0x8AF8, 0x5A59, 0x8AF9, 0x5A5B,
+	0x8AFA, 0x5A5C, 0x8AFB, 0x5A5D, 0x8AFC, 0x5A5E, 0x8AFD, 0x5A5F,
+	0x8AFE, 0x5A60, 0x8B40, 0x5A61, 0x8B41, 0x5A63, 0x8B42, 0x5A64,
+	0x8B43, 0x5A65, 0x8B44, 0x5A66, 0x8B45, 0x5A68, 0x8B46, 0x5A69,
+	0x8B47, 0x5A6B, 0x8B48, 0x5A6C, 0x8B49, 0x5A6D, 0x8B4A, 0x5A6E,
+	0x8B4B, 0x5A6F, 0x8B4C, 0x5A70, 0x8B4D, 0x5A71, 0x8B4E, 0x5A72,
+	0x8B4F, 0x5A73, 0x8B50, 0x5A78, 0x8B51, 0x5A79, 0x8B52, 0x5A7B,
+	0x8B53, 0x5A7C, 0x8B54, 0x5A7D, 0x8B55, 0x5A7E, 0x8B56, 0x5A80,
+	0x8B57, 0x5A81, 0x8B58, 0x5A82, 0x8B59, 0x5A83, 0x8B5A, 0x5A84,
+	0x8B5B, 0x5A85, 0x8B5C, 0x5A86, 0x8B5D, 0x5A87, 0x8B5E, 0x5A88,
+	0x8B5F, 0x5A89, 0x8B60, 0x5A8A, 0x8B61, 0x5A8B, 0x8B62, 0x5A8C,
+	0x8B63, 0x5A8D, 0x8B64, 0x5A8E, 0x8B65, 0x5A8F, 0x8B66, 0x5A90,
+	0x8B67, 0x5A91, 0x8B68, 0x5A93, 0x8B69, 0x5A94, 0x8B6A, 0x5A95,
+	0x8B6B, 0x5A96, 0x8B6C, 0x5A97, 0x8B6D, 0x5A98, 0x8B6E, 0x5A99,
+	0x8B6F, 0x5A9C, 0x8B70, 0x5A9D, 0x8B71, 0x5A9E, 0x8B72, 0x5A9F,
+	0x8B73, 0x5AA0, 0x8B74, 0x5AA1, 0x8B75, 0x5AA2, 0x8B76, 0x5AA3,
+	0x8B77, 0x5AA4, 0x8B78, 0x5AA5, 0x8B79, 0x5AA6, 0x8B7A, 0x5AA7,
+	0x8B7B, 0x5AA8, 0x8B7C, 0x5AA9, 0x8B7D, 0x5AAB, 0x8B7E, 0x5AAC,
+	0x8B80, 0x5AAD, 0x8B81, 0x5AAE, 0x8B82, 0x5AAF, 0x8B83, 0x5AB0,
+	0x8B84, 0x5AB1, 0x8B85, 0x5AB4, 0x8B86, 0x5AB6, 0x8B87, 0x5AB7,
+	0x8B88, 0x5AB9, 0x8B89, 0x5ABA, 0x8B8A, 0x5ABB, 0x8B8B, 0x5ABC,
+	0x8B8C, 0x5ABD, 0x8B8D, 0x5ABF, 0x8B8E, 0x5AC0, 0x8B8F, 0x5AC3,
+	0x8B90, 0x5AC4, 0x8B91, 0x5AC5, 0x8B92, 0x5AC6, 0x8B93, 0x5AC7,
+	0x8B94, 0x5AC8, 0x8B95, 0x5ACA, 0x8B96, 0x5ACB, 0x8B97, 0x5ACD,
+	0x8B98, 0x5ACE, 0x8B99, 0x5ACF, 0x8B9A, 0x5AD0, 0x8B9B, 0x5AD1,
+	0x8B9C, 0x5AD3, 0x8B9D, 0x5AD5, 0x8B9E, 0x5AD7, 0x8B9F, 0x5AD9,
+	0x8BA0, 0x5ADA, 0x8BA1, 0x5ADB, 0x8BA2, 0x5ADD, 0x8BA3, 0x5ADE,
+	0x8BA4, 0x5ADF, 0x8BA5, 0x5AE2, 0x8BA6, 0x5AE4, 0x8BA7, 0x5AE5,
+	0x8BA8, 0x5AE7, 0x8BA9, 0x5AE8, 0x8BAA, 0x5AEA, 0x8BAB, 0x5AEC,
+	0x8BAC, 0x5AED, 0x8BAD, 0x5AEE, 0x8BAE, 0x5AEF, 0x8BAF, 0x5AF0,
+	0x8BB0, 0x5AF2, 0x8BB1, 0x5AF3, 0x8BB2, 0x5AF4, 0x8BB3, 0x5AF5,
+	0x8BB4, 0x5AF6, 0x8BB5, 0x5AF7, 0x8BB6, 0x5AF8, 0x8BB7, 0x5AF9,
+	0x8BB8, 0x5AFA, 0x8BB9, 0x5AFB, 0x8BBA, 0x5AFC, 0x8BBB, 0x5AFD,
+	0x8BBC, 0x5AFE, 0x8BBD, 0x5AFF, 0x8BBE, 0x5B00, 0x8BBF, 0x5B01,
+	0x8BC0, 0x5B02, 0x8BC1, 0x5B03, 0x8BC2, 0x5B04, 0x8BC3, 0x5B05,
+	0x8BC4, 0x5B06, 0x8BC5, 0x5B07, 0x8BC6, 0x5B08, 0x8BC7, 0x5B0A,
+	0x8BC8, 0x5B0B, 0x8BC9, 0x5B0C, 0x8BCA, 0x5B0D, 0x8BCB, 0x5B0E,
+	0x8BCC, 0x5B0F, 0x8BCD, 0x5B10, 0x8BCE, 0x5B11, 0x8BCF, 0x5B12,
+	0x8BD0, 0x5B13, 0x8BD1, 0x5B14, 0x8BD2, 0x5B15, 0x8BD3, 0x5B18,
+	0x8BD4, 0x5B19, 0x8BD5, 0x5B1A, 0x8BD6, 0x5B1B, 0x8BD7, 0x5B1C,
+	0x8BD8, 0x5B1D, 0x8BD9, 0x5B1E, 0x8BDA, 0x5B1F, 0x8BDB, 0x5B20,
+	0x8BDC, 0x5B21, 0x8BDD, 0x5B22, 0x8BDE, 0x5B23, 0x8BDF, 0x5B24,
+	0x8BE0, 0x5B25, 0x8BE1, 0x5B26, 0x8BE2, 0x5B27, 0x8BE3, 0x5B28,
+	0x8BE4, 0x5B29, 0x8BE5, 0x5B2A, 0x8BE6, 0x5B2B, 0x8BE7, 0x5B2C,
+	0x8BE8, 0x5B2D, 0x8BE9, 0x5B2E, 0x8BEA, 0x5B2F, 0x8BEB, 0x5B30,
+	0x8BEC, 0x5B31, 0x8BED, 0x5B33, 0x8BEE, 0x5B35, 0x8BEF, 0x5B36,
+	0x8BF0, 0x5B38, 0x8BF1, 0x5B39, 0x8BF2, 0x5B3A, 0x8BF3, 0x5B3B,
+	0x8BF4, 0x5B3C, 0x8BF5, 0x5B3D, 0x8BF6, 0x5B3E, 0x8BF7, 0x5B3F,
+	0x8BF8, 0x5B41, 0x8BF9, 0x5B42, 0x8BFA, 0x5B43, 0x8BFB, 0x5B44,
+	0x8BFC, 0x5B45, 0x8BFD, 0x5B46, 0x8BFE, 0x5B47, 0x8C40, 0x5B48,
+	0x8C41, 0x5B49, 0x8C42, 0x5B4A, 0x8C43, 0x5B4B, 0x8C44, 0x5B4C,
+	0x8C45, 0x5B4D, 0x8C46, 0x5B4E, 0x8C47, 0x5B4F, 0x8C48, 0x5B52,
+	0x8C49, 0x5B56, 0x8C4A, 0x5B5E, 0x8C4B, 0x5B60, 0x8C4C, 0x5B61,
+	0x8C4D, 0x5B67, 0x8C4E, 0x5B68, 0x8C4F, 0x5B6B, 0x8C50, 0x5B6D,
+	0x8C51, 0x5B6E, 0x8C52, 0x5B6F, 0x8C53, 0x5B72, 0x8C54, 0x5B74,
+	0x8C55, 0x5B76, 0x8C56, 0x5B77, 0x8C57, 0x5B78, 0x8C58, 0x5B79,
+	0x8C59, 0x5B7B, 0x8C5A, 0x5B7C, 0x8C5B, 0x5B7E, 0x8C5C, 0x5B7F,
+	0x8C5D, 0x5B82, 0x8C5E, 0x5B86, 0x8C5F, 0x5B8A, 0x8C60, 0x5B8D,
+	0x8C61, 0x5B8E, 0x8C62, 0x5B90, 0x8C63, 0x5B91, 0x8C64, 0x5B92,
+	0x8C65, 0x5B94, 0x8C66, 0x5B96, 0x8C67, 0x5B9F, 0x8C68, 0x5BA7,
+	0x8C69, 0x5BA8, 0x8C6A, 0x5BA9, 0x8C6B, 0x5BAC, 0x8C6C, 0x5BAD,
+	0x8C6D, 0x5BAE, 0x8C6E, 0x5BAF, 0x8C6F, 0x5BB1, 0x8C70, 0x5BB2,
+	0x8C71, 0x5BB7, 0x8C72, 0x5BBA, 0x8C73, 0x5BBB, 0x8C74, 0x5BBC,
+	0x8C75, 0x5BC0, 0x8C76, 0x5BC1, 0x8C77, 0x5BC3, 0x8C78, 0x5BC8,
+	0x8C79, 0x5BC9, 0x8C7A, 0x5BCA, 0x8C7B, 0x5BCB, 0x8C7C, 0x5BCD,
+	0x8C7D, 0x5BCE, 0x8C7E, 0x5BCF, 0x8C80, 0x5BD1, 0x8C81, 0x5BD4,
+	0x8C82, 0x5BD5, 0x8C83, 0x5BD6, 0x8C84, 0x5BD7, 0x8C85, 0x5BD8,
+	0x8C86, 0x5BD9, 0x8C87, 0x5BDA, 0x8C88, 0x5BDB, 0x8C89, 0x5BDC,
+	0x8C8A, 0x5BE0, 0x8C8B, 0x5BE2, 0x8C8C, 0x5BE3, 0x8C8D, 0x5BE6,
+	0x8C8E, 0x5BE7, 0x8C8F, 0x5BE9, 0x8C90, 0x5BEA, 0x8C91, 0x5BEB,
+	0x8C92, 0x5BEC, 0x8C93, 0x5BED, 0x8C94, 0x5BEF, 0x8C95, 0x5BF1,
+	0x8C96, 0x5BF2, 0x8C97, 0x5BF3, 0x8C98, 0x5BF4, 0x8C99, 0x5BF5,
+	0x8C9A, 0x5BF6, 0x8C9B, 0x5BF7, 0x8C9C, 0x5BFD, 0x8C9D, 0x5BFE,
+	0x8C9E, 0x5C00, 0x8C9F, 0x5C02, 0x8CA0, 0x5C03, 0x8CA1, 0x5C05,
+	0x8CA2, 0x5C07, 0x8CA3, 0x5C08, 0x8CA4, 0x5C0B, 0x8CA5, 0x5C0C,
+	0x8CA6, 0x5C0D, 0x8CA7, 0x5C0E, 0x8CA8, 0x5C10, 0x8CA9, 0x5C12,
+	0x8CAA, 0x5C13, 0x8CAB, 0x5C17, 0x8CAC, 0x5C19, 0x8CAD, 0x5C1B,
+	0x8CAE, 0x5C1E, 0x8CAF, 0x5C1F, 0x8CB0, 0x5C20, 0x8CB1, 0x5C21,
+	0x8CB2, 0x5C23, 0x8CB3, 0x5C26, 0x8CB4, 0x5C28, 0x8CB5, 0x5C29,
+	0x8CB6, 0x5C2A, 0x8CB7, 0x5C2B, 0x8CB8, 0x5C2D, 0x8CB9, 0x5C2E,
+	0x8CBA, 0x5C2F, 0x8CBB, 0x5C30, 0x8CBC, 0x5C32, 0x8CBD, 0x5C33,
+	0x8CBE, 0x5C35, 0x8CBF, 0x5C36, 0x8CC0, 0x5C37, 0x8CC1, 0x5C43,
+	0x8CC2, 0x5C44, 0x8CC3, 0x5C46, 0x8CC4, 0x5C47, 0x8CC5, 0x5C4C,
+	0x8CC6, 0x5C4D, 0x8CC7, 0x5C52, 0x8CC8, 0x5C53, 0x8CC9, 0x5C54,
+	0x8CCA, 0x5C56, 0x8CCB, 0x5C57, 0x8CCC, 0x5C58, 0x8CCD, 0x5C5A,
+	0x8CCE, 0x5C5B, 0x8CCF, 0x5C5C, 0x8CD0, 0x5C5D, 0x8CD1, 0x5C5F,
+	0x8CD2, 0x5C62, 0x8CD3, 0x5C64, 0x8CD4, 0x5C67, 0x8CD5, 0x5C68,
+	0x8CD6, 0x5C69, 0x8CD7, 0x5C6A, 0x8CD8, 0x5C6B, 0x8CD9, 0x5C6C,
+	0x8CDA, 0x5C6D, 0x8CDB, 0x5C70, 0x8CDC, 0x5C72, 0x8CDD, 0x5C73,
+	0x8CDE, 0x5C74, 0x8CDF, 0x5C75, 0x8CE0, 0x5C76, 0x8CE1, 0x5C77,
+	0x8CE2, 0x5C78, 0x8CE3, 0x5C7B, 0x8CE4, 0x5C7C, 0x8CE5, 0x5C7D,
+	0x8CE6, 0x5C7E, 0x8CE7, 0x5C80, 0x8CE8, 0x5C83, 0x8CE9, 0x5C84,
+	0x8CEA, 0x5C85, 0x8CEB, 0x5C86, 0x8CEC, 0x5C87, 0x8CED, 0x5C89,
+	0x8CEE, 0x5C8A, 0x8CEF, 0x5C8B, 0x8CF0, 0x5C8E, 0x8CF1, 0x5C8F,
+	0x8CF2, 0x5C92, 0x8CF3, 0x5C93, 0x8CF4, 0x5C95, 0x8CF5, 0x5C9D,
+	0x8CF6, 0x5C9E, 0x8CF7, 0x5C9F, 0x8CF8, 0x5CA0, 0x8CF9, 0x5CA1,
+	0x8CFA, 0x5CA4, 0x8CFB, 0x5CA5, 0x8CFC, 0x5CA6, 0x8CFD, 0x5CA7,
+	0x8CFE, 0x5CA8, 0x8D40, 0x5CAA, 0x8D41, 0x5CAE, 0x8D42, 0x5CAF,
+	0x8D43, 0x5CB0, 0x8D44, 0x5CB2, 0x8D45, 0x5CB4, 0x8D46, 0x5CB6,
+	0x8D47, 0x5CB9, 0x8D48, 0x5CBA, 0x8D49, 0x5CBB, 0x8D4A, 0x5CBC,
+	0x8D4B, 0x5CBE, 0x8D4C, 0x5CC0, 0x8D4D, 0x5CC2, 0x8D4E, 0x5CC3,
+	0x8D4F, 0x5CC5, 0x8D50, 0x5CC6, 0x8D51, 0x5CC7, 0x8D52, 0x5CC8,
+	0x8D53, 0x5CC9, 0x8D54, 0x5CCA, 0x8D55, 0x5CCC, 0x8D56, 0x5CCD,
+	0x8D57, 0x5CCE, 0x8D58, 0x5CCF, 0x8D59, 0x5CD0, 0x8D5A, 0x5CD1,
+	0x8D5B, 0x5CD3, 0x8D5C, 0x5CD4, 0x8D5D, 0x5CD5, 0x8D5E, 0x5CD6,
+	0x8D5F, 0x5CD7, 0x8D60, 0x5CD8, 0x8D61, 0x5CDA, 0x8D62, 0x5CDB,
+	0x8D63, 0x5CDC, 0x8D64, 0x5CDD, 0x8D65, 0x5CDE, 0x8D66, 0x5CDF,
+	0x8D67, 0x5CE0, 0x8D68, 0x5CE2, 0x8D69, 0x5CE3, 0x8D6A, 0x5CE7,
+	0x8D6B, 0x5CE9, 0x8D6C, 0x5CEB, 0x8D6D, 0x5CEC, 0x8D6E, 0x5CEE,
+	0x8D6F, 0x5CEF, 0x8D70, 0x5CF1, 0x8D71, 0x5CF2, 0x8D72, 0x5CF3,
+	0x8D73, 0x5CF4, 0x8D74, 0x5CF5, 0x8D75, 0x5CF6, 0x8D76, 0x5CF7,
+	0x8D77, 0x5CF8, 0x8D78, 0x5CF9, 0x8D79, 0x5CFA, 0x8D7A, 0x5CFC,
+	0x8D7B, 0x5CFD, 0x8D7C, 0x5CFE, 0x8D7D, 0x5CFF, 0x8D7E, 0x5D00,
+	0x8D80, 0x5D01, 0x8D81, 0x5D04, 0x8D82, 0x5D05, 0x8D83, 0x5D08,
+	0x8D84, 0x5D09, 0x8D85, 0x5D0A, 0x8D86, 0x5D0B, 0x8D87, 0x5D0C,
+	0x8D88, 0x5D0D, 0x8D89, 0x5D0F, 0x8D8A, 0x5D10, 0x8D8B, 0x5D11,
+	0x8D8C, 0x5D12, 0x8D8D, 0x5D13, 0x8D8E, 0x5D15, 0x8D8F, 0x5D17,
+	0x8D90, 0x5D18, 0x8D91, 0x5D19, 0x8D92, 0x5D1A, 0x8D93, 0x5D1C,
+	0x8D94, 0x5D1D, 0x8D95, 0x5D1F, 0x8D96, 0x5D20, 0x8D97, 0x5D21,
+	0x8D98, 0x5D22, 0x8D99, 0x5D23, 0x8D9A, 0x5D25, 0x8D9B, 0x5D28,
+	0x8D9C, 0x5D2A, 0x8D9D, 0x5D2B, 0x8D9E, 0x5D2C, 0x8D9F, 0x5D2F,
+	0x8DA0, 0x5D30, 0x8DA1, 0x5D31, 0x8DA2, 0x5D32, 0x8DA3, 0x5D33,
+	0x8DA4, 0x5D35, 0x8DA5, 0x5D36, 0x8DA6, 0x5D37, 0x8DA7, 0x5D38,
+	0x8DA8, 0x5D39, 0x8DA9, 0x5D3A, 0x8DAA, 0x5D3B, 0x8DAB, 0x5D3C,
+	0x8DAC, 0x5D3F, 0x8DAD, 0x5D40, 0x8DAE, 0x5D41, 0x8DAF, 0x5D42,
+	0x8DB0, 0x5D43, 0x8DB1, 0x5D44, 0x8DB2, 0x5D45, 0x8DB3, 0x5D46,
+	0x8DB4, 0x5D48, 0x8DB5, 0x5D49, 0x8DB6, 0x5D4D, 0x8DB7, 0x5D4E,
+	0x8DB8, 0x5D4F, 0x8DB9, 0x5D50, 0x8DBA, 0x5D51, 0x8DBB, 0x5D52,
+	0x8DBC, 0x5D53, 0x8DBD, 0x5D54, 0x8DBE, 0x5D55, 0x8DBF, 0x5D56,
+	0x8DC0, 0x5D57, 0x8DC1, 0x5D59, 0x8DC2, 0x5D5A, 0x8DC3, 0x5D5C,
+	0x8DC4, 0x5D5E, 0x8DC5, 0x5D5F, 0x8DC6, 0x5D60, 0x8DC7, 0x5D61,
+	0x8DC8, 0x5D62, 0x8DC9, 0x5D63, 0x8DCA, 0x5D64, 0x8DCB, 0x5D65,
+	0x8DCC, 0x5D66, 0x8DCD, 0x5D67, 0x8DCE, 0x5D68, 0x8DCF, 0x5D6A,
+	0x8DD0, 0x5D6D, 0x8DD1, 0x5D6E, 0x8DD2, 0x5D70, 0x8DD3, 0x5D71,
+	0x8DD4, 0x5D72, 0x8DD5, 0x5D73, 0x8DD6, 0x5D75, 0x8DD7, 0x5D76,
+	0x8DD8, 0x5D77, 0x8DD9, 0x5D78, 0x8DDA, 0x5D79, 0x8DDB, 0x5D7A,
+	0x8DDC, 0x5D7B, 0x8DDD, 0x5D7C, 0x8DDE, 0x5D7D, 0x8DDF, 0x5D7E,
+	0x8DE0, 0x5D7F, 0x8DE1, 0x5D80, 0x8DE2, 0x5D81, 0x8DE3, 0x5D83,
+	0x8DE4, 0x5D84, 0x8DE5, 0x5D85, 0x8DE6, 0x5D86, 0x8DE7, 0x5D87,
+	0x8DE8, 0x5D88, 0x8DE9, 0x5D89, 0x8DEA, 0x5D8A, 0x8DEB, 0x5D8B,
+	0x8DEC, 0x5D8C, 0x8DED, 0x5D8D, 0x8DEE, 0x5D8E, 0x8DEF, 0x5D8F,
+	0x8DF0, 0x5D90, 0x8DF1, 0x5D91, 0x8DF2, 0x5D92, 0x8DF3, 0x5D93,
+	0x8DF4, 0x5D94, 0x8DF5, 0x5D95, 0x8DF6, 0x5D96, 0x8DF7, 0x5D97,
+	0x8DF8, 0x5D98, 0x8DF9, 0x5D9A, 0x8DFA, 0x5D9B, 0x8DFB, 0x5D9C,
+	0x8DFC, 0x5D9E, 0x8DFD, 0x5D9F, 0x8DFE, 0x5DA0, 0x8E40, 0x5DA1,
+	0x8E41, 0x5DA2, 0x8E42, 0x5DA3, 0x8E43, 0x5DA4, 0x8E44, 0x5DA5,
+	0x8E45, 0x5DA6, 0x8E46, 0x5DA7, 0x8E47, 0x5DA8, 0x8E48, 0x5DA9,
+	0x8E49, 0x5DAA, 0x8E4A, 0x5DAB, 0x8E4B, 0x5DAC, 0x8E4C, 0x5DAD,
+	0x8E4D, 0x5DAE, 0x8E4E, 0x5DAF, 0x8E4F, 0x5DB0, 0x8E50, 0x5DB1,
+	0x8E51, 0x5DB2, 0x8E52, 0x5DB3, 0x8E53, 0x5DB4, 0x8E54, 0x5DB5,
+	0x8E55, 0x5DB6, 0x8E56, 0x5DB8, 0x8E57, 0x5DB9, 0x8E58, 0x5DBA,
+	0x8E59, 0x5DBB, 0x8E5A, 0x5DBC, 0x8E5B, 0x5DBD, 0x8E5C, 0x5DBE,
+	0x8E5D, 0x5DBF, 0x8E5E, 0x5DC0, 0x8E5F, 0x5DC1, 0x8E60, 0x5DC2,
+	0x8E61, 0x5DC3, 0x8E62, 0x5DC4, 0x8E63, 0x5DC6, 0x8E64, 0x5DC7,
+	0x8E65, 0x5DC8, 0x8E66, 0x5DC9, 0x8E67, 0x5DCA, 0x8E68, 0x5DCB,
+	0x8E69, 0x5DCC, 0x8E6A, 0x5DCE, 0x8E6B, 0x5DCF, 0x8E6C, 0x5DD0,
+	0x8E6D, 0x5DD1, 0x8E6E, 0x5DD2, 0x8E6F, 0x5DD3, 0x8E70, 0x5DD4,
+	0x8E71, 0x5DD5, 0x8E72, 0x5DD6, 0x8E73, 0x5DD7, 0x8E74, 0x5DD8,
+	0x8E75, 0x5DD9, 0x8E76, 0x5DDA, 0x8E77, 0x5DDC, 0x8E78, 0x5DDF,
+	0x8E79, 0x5DE0, 0x8E7A, 0x5DE3, 0x8E7B, 0x5DE4, 0x8E7C, 0x5DEA,
+	0x8E7D, 0x5DEC, 0x8E7E, 0x5DED, 0x8E80, 0x5DF0, 0x8E81, 0x5DF5,
+	0x8E82, 0x5DF6, 0x8E83, 0x5DF8, 0x8E84, 0x5DF9, 0x8E85, 0x5DFA,
+	0x8E86, 0x5DFB, 0x8E87, 0x5DFC, 0x8E88, 0x5DFF, 0x8E89, 0x5E00,
+	0x8E8A, 0x5E04, 0x8E8B, 0x5E07, 0x8E8C, 0x5E09, 0x8E8D, 0x5E0A,
+	0x8E8E, 0x5E0B, 0x8E8F, 0x5E0D, 0x8E90, 0x5E0E, 0x8E91, 0x5E12,
+	0x8E92, 0x5E13, 0x8E93, 0x5E17, 0x8E94, 0x5E1E, 0x8E95, 0x5E1F,
+	0x8E96, 0x5E20, 0x8E97, 0x5E21, 0x8E98, 0x5E22, 0x8E99, 0x5E23,
+	0x8E9A, 0x5E24, 0x8E9B, 0x5E25, 0x8E9C, 0x5E28, 0x8E9D, 0x5E29,
+	0x8E9E, 0x5E2A, 0x8E9F, 0x5E2B, 0x8EA0, 0x5E2C, 0x8EA1, 0x5E2F,
+	0x8EA2, 0x5E30, 0x8EA3, 0x5E32, 0x8EA4, 0x5E33, 0x8EA5, 0x5E34,
+	0x8EA6, 0x5E35, 0x8EA7, 0x5E36, 0x8EA8, 0x5E39, 0x8EA9, 0x5E3A,
+	0x8EAA, 0x5E3E, 0x8EAB, 0x5E3F, 0x8EAC, 0x5E40, 0x8EAD, 0x5E41,
+	0x8EAE, 0x5E43, 0x8EAF, 0x5E46, 0x8EB0, 0x5E47, 0x8EB1, 0x5E48,
+	0x8EB2, 0x5E49, 0x8EB3, 0x5E4A, 0x8EB4, 0x5E4B, 0x8EB5, 0x5E4D,
+	0x8EB6, 0x5E4E, 0x8EB7, 0x5E4F, 0x8EB8, 0x5E50, 0x8EB9, 0x5E51,
+	0x8EBA, 0x5E52, 0x8EBB, 0x5E53, 0x8EBC, 0x5E56, 0x8EBD, 0x5E57,
+	0x8EBE, 0x5E58, 0x8EBF, 0x5E59, 0x8EC0, 0x5E5A, 0x8EC1, 0x5E5C,
+	0x8EC2, 0x5E5D, 0x8EC3, 0x5E5F, 0x8EC4, 0x5E60, 0x8EC5, 0x5E63,
+	0x8EC6, 0x5E64, 0x8EC7, 0x5E65, 0x8EC8, 0x5E66, 0x8EC9, 0x5E67,
+	0x8ECA, 0x5E68, 0x8ECB, 0x5E69, 0x8ECC, 0x5E6A, 0x8ECD, 0x5E6B,
+	0x8ECE, 0x5E6C, 0x8ECF, 0x5E6D, 0x8ED0, 0x5E6E, 0x8ED1, 0x5E6F,
+	0x8ED2, 0x5E70, 0x8ED3, 0x5E71, 0x8ED4, 0x5E75, 0x8ED5, 0x5E77,
+	0x8ED6, 0x5E79, 0x8ED7, 0x5E7E, 0x8ED8, 0x5E81, 0x8ED9, 0x5E82,
+	0x8EDA, 0x5E83, 0x8EDB, 0x5E85, 0x8EDC, 0x5E88, 0x8EDD, 0x5E89,
+	0x8EDE, 0x5E8C, 0x8EDF, 0x5E8D, 0x8EE0, 0x5E8E, 0x8EE1, 0x5E92,
+	0x8EE2, 0x5E98, 0x8EE3, 0x5E9B, 0x8EE4, 0x5E9D, 0x8EE5, 0x5EA1,
+	0x8EE6, 0x5EA2, 0x8EE7, 0x5EA3, 0x8EE8, 0x5EA4, 0x8EE9, 0x5EA8,
+	0x8EEA, 0x5EA9, 0x8EEB, 0x5EAA, 0x8EEC, 0x5EAB, 0x8EED, 0x5EAC,
+	0x8EEE, 0x5EAE, 0x8EEF, 0x5EAF, 0x8EF0, 0x5EB0, 0x8EF1, 0x5EB1,
+	0x8EF2, 0x5EB2, 0x8EF3, 0x5EB4, 0x8EF4, 0x5EBA, 0x8EF5, 0x5EBB,
+	0x8EF6, 0x5EBC, 0x8EF7, 0x5EBD, 0x8EF8, 0x5EBF, 0x8EF9, 0x5EC0,
+	0x8EFA, 0x5EC1, 0x8EFB, 0x5EC2, 0x8EFC, 0x5EC3, 0x8EFD, 0x5EC4,
+	0x8EFE, 0x5EC5, 0x8F40, 0x5EC6, 0x8F41, 0x5EC7, 0x8F42, 0x5EC8,
+	0x8F43, 0x5ECB, 0x8F44, 0x5ECC, 0x8F45, 0x5ECD, 0x8F46, 0x5ECE,
+	0x8F47, 0x5ECF, 0x8F48, 0x5ED0, 0x8F49, 0x5ED4, 0x8F4A, 0x5ED5,
+	0x8F4B, 0x5ED7, 0x8F4C, 0x5ED8, 0x8F4D, 0x5ED9, 0x8F4E, 0x5EDA,
+	0x8F4F, 0x5EDC, 0x8F50, 0x5EDD, 0x8F51, 0x5EDE, 0x8F52, 0x5EDF,
+	0x8F53, 0x5EE0, 0x8F54, 0x5EE1, 0x8F55, 0x5EE2, 0x8F56, 0x5EE3,
+	0x8F57, 0x5EE4, 0x8F58, 0x5EE5, 0x8F59, 0x5EE6, 0x8F5A, 0x5EE7,
+	0x8F5B, 0x5EE9, 0x8F5C, 0x5EEB, 0x8F5D, 0x5EEC, 0x8F5E, 0x5EED,
+	0x8F5F, 0x5EEE, 0x8F60, 0x5EEF, 0x8F61, 0x5EF0, 0x8F62, 0x5EF1,
+	0x8F63, 0x5EF2, 0x8F64, 0x5EF3, 0x8F65, 0x5EF5, 0x8F66, 0x5EF8,
+	0x8F67, 0x5EF9, 0x8F68, 0x5EFB, 0x8F69, 0x5EFC, 0x8F6A, 0x5EFD,
+	0x8F6B, 0x5F05, 0x8F6C, 0x5F06, 0x8F6D, 0x5F07, 0x8F6E, 0x5F09,
+	0x8F6F, 0x5F0C, 0x8F70, 0x5F0D, 0x8F71, 0x5F0E, 0x8F72, 0x5F10,
+	0x8F73, 0x5F12, 0x8F74, 0x5F14, 0x8F75, 0x5F16, 0x8F76, 0x5F19,
+	0x8F77, 0x5F1A, 0x8F78, 0x5F1C, 0x8F79, 0x5F1D, 0x8F7A, 0x5F1E,
+	0x8F7B, 0x5F21, 0x8F7C, 0x5F22, 0x8F7D, 0x5F23, 0x8F7E, 0x5F24,
+	0x8F80, 0x5F28, 0x8F81, 0x5F2B, 0x8F82, 0x5F2C, 0x8F83, 0x5F2E,
+	0x8F84, 0x5F30, 0x8F85, 0x5F32, 0x8F86, 0x5F33, 0x8F87, 0x5F34,
+	0x8F88, 0x5F35, 0x8F89, 0x5F36, 0x8F8A, 0x5F37, 0x8F8B, 0x5F38,
+	0x8F8C, 0x5F3B, 0x8F8D, 0x5F3D, 0x8F8E, 0x5F3E, 0x8F8F, 0x5F3F,
+	0x8F90, 0x5F41, 0x8F91, 0x5F42, 0x8F92, 0x5F43, 0x8F93, 0x5F44,
+	0x8F94, 0x5F45, 0x8F95, 0x5F46, 0x8F96, 0x5F47, 0x8F97, 0x5F48,
+	0x8F98, 0x5F49, 0x8F99, 0x5F4A, 0x8F9A, 0x5F4B, 0x8F9B, 0x5F4C,
+	0x8F9C, 0x5F4D, 0x8F9D, 0x5F4E, 0x8F9E, 0x5F4F, 0x8F9F, 0x5F51,
+	0x8FA0, 0x5F54, 0x8FA1, 0x5F59, 0x8FA2, 0x5F5A, 0x8FA3, 0x5F5B,
+	0x8FA4, 0x5F5C, 0x8FA5, 0x5F5E, 0x8FA6, 0x5F5F, 0x8FA7, 0x5F60,
+	0x8FA8, 0x5F63, 0x8FA9, 0x5F65, 0x8FAA, 0x5F67, 0x8FAB, 0x5F68,
+	0x8FAC, 0x5F6B, 0x8FAD, 0x5F6E, 0x8FAE, 0x5F6F, 0x8FAF, 0x5F72,
+	0x8FB0, 0x5F74, 0x8FB1, 0x5F75, 0x8FB2, 0x5F76, 0x8FB3, 0x5F78,
+	0x8FB4, 0x5F7A, 0x8FB5, 0x5F7D, 0x8FB6, 0x5F7E, 0x8FB7, 0x5F7F,
+	0x8FB8, 0x5F83, 0x8FB9, 0x5F86, 0x8FBA, 0x5F8D, 0x8FBB, 0x5F8E,
+	0x8FBC, 0x5F8F, 0x8FBD, 0x5F91, 0x8FBE, 0x5F93, 0x8FBF, 0x5F94,
+	0x8FC0, 0x5F96, 0x8FC1, 0x5F9A, 0x8FC2, 0x5F9B, 0x8FC3, 0x5F9D,
+	0x8FC4, 0x5F9E, 0x8FC5, 0x5F9F, 0x8FC6, 0x5FA0, 0x8FC7, 0x5FA2,
+	0x8FC8, 0x5FA3, 0x8FC9, 0x5FA4, 0x8FCA, 0x5FA5, 0x8FCB, 0x5FA6,
+	0x8FCC, 0x5FA7, 0x8FCD, 0x5FA9, 0x8FCE, 0x5FAB, 0x8FCF, 0x5FAC,
+	0x8FD0, 0x5FAF, 0x8FD1, 0x5FB0, 0x8FD2, 0x5FB1, 0x8FD3, 0x5FB2,
+	0x8FD4, 0x5FB3, 0x8FD5, 0x5FB4, 0x8FD6, 0x5FB6, 0x8FD7, 0x5FB8,
+	0x8FD8, 0x5FB9, 0x8FD9, 0x5FBA, 0x8FDA, 0x5FBB, 0x8FDB, 0x5FBE,
+	0x8FDC, 0x5FBF, 0x8FDD, 0x5FC0, 0x8FDE, 0x5FC1, 0x8FDF, 0x5FC2,
+	0x8FE0, 0x5FC7, 0x8FE1, 0x5FC8, 0x8FE2, 0x5FCA, 0x8FE3, 0x5FCB,
+	0x8FE4, 0x5FCE, 0x8FE5, 0x5FD3, 0x8FE6, 0x5FD4, 0x8FE7, 0x5FD5,
+	0x8FE8, 0x5FDA, 0x8FE9, 0x5FDB, 0x8FEA, 0x5FDC, 0x8FEB, 0x5FDE,
+	0x8FEC, 0x5FDF, 0x8FED, 0x5FE2, 0x8FEE, 0x5FE3, 0x8FEF, 0x5FE5,
+	0x8FF0, 0x5FE6, 0x8FF1, 0x5FE8, 0x8FF2, 0x5FE9, 0x8FF3, 0x5FEC,
+	0x8FF4, 0x5FEF, 0x8FF5, 0x5FF0, 0x8FF6, 0x5FF2, 0x8FF7, 0x5FF3,
+	0x8FF8, 0x5FF4, 0x8FF9, 0x5FF6, 0x8FFA, 0x5FF7, 0x8FFB, 0x5FF9,
+	0x8FFC, 0x5FFA, 0x8FFD, 0x5FFC, 0x8FFE, 0x6007, 0x9040, 0x6008,
+	0x9041, 0x6009, 0x9042, 0x600B, 0x9043, 0x600C, 0x9044, 0x6010,
+	0x9045, 0x6011, 0x9046, 0x6013, 0x9047, 0x6017, 0x9048, 0x6018,
+	0x9049, 0x601A, 0x904A, 0x601E, 0x904B, 0x601F, 0x904C, 0x6022,
+	0x904D, 0x6023, 0x904E, 0x6024, 0x904F, 0x602C, 0x9050, 0x602D,
+	0x9051, 0x602E, 0x9052, 0x6030, 0x9053, 0x6031, 0x9054, 0x6032,
+	0x9055, 0x6033, 0x9056, 0x6034, 0x9057, 0x6036, 0x9058, 0x6037,
+	0x9059, 0x6038, 0x905A, 0x6039, 0x905B, 0x603A, 0x905C, 0x603D,
+	0x905D, 0x603E, 0x905E, 0x6040, 0x905F, 0x6044, 0x9060, 0x6045,
+	0x9061, 0x6046, 0x9062, 0x6047, 0x9063, 0x6048, 0x9064, 0x6049,
+	0x9065, 0x604A, 0x9066, 0x604C, 0x9067, 0x604E, 0x9068, 0x604F,
+	0x9069, 0x6051, 0x906A, 0x6053, 0x906B, 0x6054, 0x906C, 0x6056,
+	0x906D, 0x6057, 0x906E, 0x6058, 0x906F, 0x605B, 0x9070, 0x605C,
+	0x9071, 0x605E, 0x9072, 0x605F, 0x9073, 0x6060, 0x9074, 0x6061,
+	0x9075, 0x6065, 0x9076, 0x6066, 0x9077, 0x606E, 0x9078, 0x6071,
+	0x9079, 0x6072, 0x907A, 0x6074, 0x907B, 0x6075, 0x907C, 0x6077,
+	0x907D, 0x607E, 0x907E, 0x6080, 0x9080, 0x6081, 0x9081, 0x6082,
+	0x9082, 0x6085, 0x9083, 0x6086, 0x9084, 0x6087, 0x9085, 0x6088,
+	0x9086, 0x608A, 0x9087, 0x608B, 0x9088, 0x608E, 0x9089, 0x608F,
+	0x908A, 0x6090, 0x908B, 0x6091, 0x908C, 0x6093, 0x908D, 0x6095,
+	0x908E, 0x6097, 0x908F, 0x6098, 0x9090, 0x6099, 0x9091, 0x609C,
+	0x9092, 0x609E, 0x9093, 0x60A1, 0x9094, 0x60A2, 0x9095, 0x60A4,
+	0x9096, 0x60A5, 0x9097, 0x60A7, 0x9098, 0x60A9, 0x9099, 0x60AA,
+	0x909A, 0x60AE, 0x909B, 0x60B0, 0x909C, 0x60B3, 0x909D, 0x60B5,
+	0x909E, 0x60B6, 0x909F, 0x60B7, 0x90A0, 0x60B9, 0x90A1, 0x60BA,
+	0x90A2, 0x60BD, 0x90A3, 0x60BE, 0x90A4, 0x60BF, 0x90A5, 0x60C0,
+	0x90A6, 0x60C1, 0x90A7, 0x60C2, 0x90A8, 0x60C3, 0x90A9, 0x60C4,
+	0x90AA, 0x60C7, 0x90AB, 0x60C8, 0x90AC, 0x60C9, 0x90AD, 0x60CC,
+	0x90AE, 0x60CD, 0x90AF, 0x60CE, 0x90B0, 0x60CF, 0x90B1, 0x60D0,
+	0x90B2, 0x60D2, 0x90B3, 0x60D3, 0x90B4, 0x60D4, 0x90B5, 0x60D6,
+	0x90B6, 0x60D7, 0x90B7, 0x60D9, 0x90B8, 0x60DB, 0x90B9, 0x60DE,
+	0x90BA, 0x60E1, 0x90BB, 0x60E2, 0x90BC, 0x60E3, 0x90BD, 0x60E4,
+	0x90BE, 0x60E5, 0x90BF, 0x60EA, 0x90C0, 0x60F1, 0x90C1, 0x60F2,
+	0x90C2, 0x60F5, 0x90C3, 0x60F7, 0x90C4, 0x60F8, 0x90C5, 0x60FB,
+	0x90C6, 0x60FC, 0x90C7, 0x60FD, 0x90C8, 0x60FE, 0x90C9, 0x60FF,
+	0x90CA, 0x6102, 0x90CB, 0x6103, 0x90CC, 0x6104, 0x90CD, 0x6105,
+	0x90CE, 0x6107, 0x90CF, 0x610A, 0x90D0, 0x610B, 0x90D1, 0x610C,
+	0x90D2, 0x6110, 0x90D3, 0x6111, 0x90D4, 0x6112, 0x90D5, 0x6113,
+	0x90D6, 0x6114, 0x90D7, 0x6116, 0x90D8, 0x6117, 0x90D9, 0x6118,
+	0x90DA, 0x6119, 0x90DB, 0x611B, 0x90DC, 0x611C, 0x90DD, 0x611D,
+	0x90DE, 0x611E, 0x90DF, 0x6121, 0x90E0, 0x6122, 0x90E1, 0x6125,
+	0x90E2, 0x6128, 0x90E3, 0x6129, 0x90E4, 0x612A, 0x90E5, 0x612C,
+	0x90E6, 0x612D, 0x90E7, 0x612E, 0x90E8, 0x612F, 0x90E9, 0x6130,
+	0x90EA, 0x6131, 0x90EB, 0x6132, 0x90EC, 0x6133, 0x90ED, 0x6134,
+	0x90EE, 0x6135, 0x90EF, 0x6136, 0x90F0, 0x6137, 0x90F1, 0x6138,
+	0x90F2, 0x6139, 0x90F3, 0x613A, 0x90F4, 0x613B, 0x90F5, 0x613C,
+	0x90F6, 0x613D, 0x90F7, 0x613E, 0x90F8, 0x6140, 0x90F9, 0x6141,
+	0x90FA, 0x6142, 0x90FB, 0x6143, 0x90FC, 0x6144, 0x90FD, 0x6145,
+	0x90FE, 0x6146, 0x9140, 0x6147, 0x9141, 0x6149, 0x9142, 0x614B,
+	0x9143, 0x614D, 0x9144, 0x614F, 0x9145, 0x6150, 0x9146, 0x6152,
+	0x9147, 0x6153, 0x9148, 0x6154, 0x9149, 0x6156, 0x914A, 0x6157,
+	0x914B, 0x6158, 0x914C, 0x6159, 0x914D, 0x615A, 0x914E, 0x615B,
+	0x914F, 0x615C, 0x9150, 0x615E, 0x9151, 0x615F, 0x9152, 0x6160,
+	0x9153, 0x6161, 0x9154, 0x6163, 0x9155, 0x6164, 0x9156, 0x6165,
+	0x9157, 0x6166, 0x9158, 0x6169, 0x9159, 0x616A, 0x915A, 0x616B,
+	0x915B, 0x616C, 0x915C, 0x616D, 0x915D, 0x616E, 0x915E, 0x616F,
+	0x915F, 0x6171, 0x9160, 0x6172, 0x9161, 0x6173, 0x9162, 0x6174,
+	0x9163, 0x6176, 0x9164, 0x6178, 0x9165, 0x6179, 0x9166, 0x617A,
+	0x9167, 0x617B, 0x9168, 0x617C, 0x9169, 0x617D, 0x916A, 0x617E,
+	0x916B, 0x617F, 0x916C, 0x6180, 0x916D, 0x6181, 0x916E, 0x6182,
+	0x916F, 0x6183, 0x9170, 0x6184, 0x9171, 0x6185, 0x9172, 0x6186,
+	0x9173, 0x6187, 0x9174, 0x6188, 0x9175, 0x6189, 0x9176, 0x618A,
+	0x9177, 0x618C, 0x9178, 0x618D, 0x9179, 0x618F, 0x917A, 0x6190,
+	0x917B, 0x6191, 0x917C, 0x6192, 0x917D, 0x6193, 0x917E, 0x6195,
+	0x9180, 0x6196, 0x9181, 0x6197, 0x9182, 0x6198, 0x9183, 0x6199,
+	0x9184, 0x619A, 0x9185, 0x619B, 0x9186, 0x619C, 0x9187, 0x619E,
+	0x9188, 0x619F, 0x9189, 0x61A0, 0x918A, 0x61A1, 0x918B, 0x61A2,
+	0x918C, 0x61A3, 0x918D, 0x61A4, 0x918E, 0x61A5, 0x918F, 0x61A6,
+	0x9190, 0x61AA, 0x9191, 0x61AB, 0x9192, 0x61AD, 0x9193, 0x61AE,
+	0x9194, 0x61AF, 0x9195, 0x61B0, 0x9196, 0x61B1, 0x9197, 0x61B2,
+	0x9198, 0x61B3, 0x9199, 0x61B4, 0x919A, 0x61B5, 0x919B, 0x61B6,
+	0x919C, 0x61B8, 0x919D, 0x61B9, 0x919E, 0x61BA, 0x919F, 0x61BB,
+	0x91A0, 0x61BC, 0x91A1, 0x61BD, 0x91A2, 0x61BF, 0x91A3, 0x61C0,
+	0x91A4, 0x61C1, 0x91A5, 0x61C3, 0x91A6, 0x61C4, 0x91A7, 0x61C5,
+	0x91A8, 0x61C6, 0x91A9, 0x61C7, 0x91AA, 0x61C9, 0x91AB, 0x61CC,
+	0x91AC, 0x61CD, 0x91AD, 0x61CE, 0x91AE, 0x61CF, 0x91AF, 0x61D0,
+	0x91B0, 0x61D3, 0x91B1, 0x61D5, 0x91B2, 0x61D6, 0x91B3, 0x61D7,
+	0x91B4, 0x61D8, 0x91B5, 0x61D9, 0x91B6, 0x61DA, 0x91B7, 0x61DB,
+	0x91B8, 0x61DC, 0x91B9, 0x61DD, 0x91BA, 0x61DE, 0x91BB, 0x61DF,
+	0x91BC, 0x61E0, 0x91BD, 0x61E1, 0x91BE, 0x61E2, 0x91BF, 0x61E3,
+	0x91C0, 0x61E4, 0x91C1, 0x61E5, 0x91C2, 0x61E7, 0x91C3, 0x61E8,
+	0x91C4, 0x61E9, 0x91C5, 0x61EA, 0x91C6, 0x61EB, 0x91C7, 0x61EC,
+	0x91C8, 0x61ED, 0x91C9, 0x61EE, 0x91CA, 0x61EF, 0x91CB, 0x61F0,
+	0x91CC, 0x61F1, 0x91CD, 0x61F2, 0x91CE, 0x61F3, 0x91CF, 0x61F4,
+	0x91D0, 0x61F6, 0x91D1, 0x61F7, 0x91D2, 0x61F8, 0x91D3, 0x61F9,
+	0x91D4, 0x61FA, 0x91D5, 0x61FB, 0x91D6, 0x61FC, 0x91D7, 0x61FD,
+	0x91D8, 0x61FE, 0x91D9, 0x6200, 0x91DA, 0x6201, 0x91DB, 0x6202,
+	0x91DC, 0x6203, 0x91DD, 0x6204, 0x91DE, 0x6205, 0x91DF, 0x6207,
+	0x91E0, 0x6209, 0x91E1, 0x6213, 0x91E2, 0x6214, 0x91E3, 0x6219,
+	0x91E4, 0x621C, 0x91E5, 0x621D, 0x91E6, 0x621E, 0x91E7, 0x6220,
+	0x91E8, 0x6223, 0x91E9, 0x6226, 0x91EA, 0x6227, 0x91EB, 0x6228,
+	0x91EC, 0x6229, 0x91ED, 0x622B, 0x91EE, 0x622D, 0x91EF, 0x622F,
+	0x91F0, 0x6230, 0x91F1, 0x6231, 0x91F2, 0x6232, 0x91F3, 0x6235,
+	0x91F4, 0x6236, 0x91F5, 0x6238, 0x91F6, 0x6239, 0x91F7, 0x623A,
+	0x91F8, 0x623B, 0x91F9, 0x623C, 0x91FA, 0x6242, 0x91FB, 0x6244,
+	0x91FC, 0x6245, 0x91FD, 0x6246, 0x91FE, 0x624A, 0x9240, 0x624F,
+	0x9241, 0x6250, 0x9242, 0x6255, 0x9243, 0x6256, 0x9244, 0x6257,
+	0x9245, 0x6259, 0x9246, 0x625A, 0x9247, 0x625C, 0x9248, 0x625D,
+	0x9249, 0x625E, 0x924A, 0x625F, 0x924B, 0x6260, 0x924C, 0x6261,
+	0x924D, 0x6262, 0x924E, 0x6264, 0x924F, 0x6265, 0x9250, 0x6268,
+	0x9251, 0x6271, 0x9252, 0x6272, 0x9253, 0x6274, 0x9254, 0x6275,
+	0x9255, 0x6277, 0x9256, 0x6278, 0x9257, 0x627A, 0x9258, 0x627B,
+	0x9259, 0x627D, 0x925A, 0x6281, 0x925B, 0x6282, 0x925C, 0x6283,
+	0x925D, 0x6285, 0x925E, 0x6286, 0x925F, 0x6287, 0x9260, 0x6288,
+	0x9261, 0x628B, 0x9262, 0x628C, 0x9263, 0x628D, 0x9264, 0x628E,
+	0x9265, 0x628F, 0x9266, 0x6290, 0x9267, 0x6294, 0x9268, 0x6299,
+	0x9269, 0x629C, 0x926A, 0x629D, 0x926B, 0x629E, 0x926C, 0x62A3,
+	0x926D, 0x62A6, 0x926E, 0x62A7, 0x926F, 0x62A9, 0x9270, 0x62AA,
+	0x9271, 0x62AD, 0x9272, 0x62AE, 0x9273, 0x62AF, 0x9274, 0x62B0,
+	0x9275, 0x62B2, 0x9276, 0x62B3, 0x9277, 0x62B4, 0x9278, 0x62B6,
+	0x9279, 0x62B7, 0x927A, 0x62B8, 0x927B, 0x62BA, 0x927C, 0x62BE,
+	0x927D, 0x62C0, 0x927E, 0x62C1, 0x9280, 0x62C3, 0x9281, 0x62CB,
+	0x9282, 0x62CF, 0x9283, 0x62D1, 0x9284, 0x62D5, 0x9285, 0x62DD,
+	0x9286, 0x62DE, 0x9287, 0x62E0, 0x9288, 0x62E1, 0x9289, 0x62E4,
+	0x928A, 0x62EA, 0x928B, 0x62EB, 0x928C, 0x62F0, 0x928D, 0x62F2,
+	0x928E, 0x62F5, 0x928F, 0x62F8, 0x9290, 0x62F9, 0x9291, 0x62FA,
+	0x9292, 0x62FB, 0x9293, 0x6300, 0x9294, 0x6303, 0x9295, 0x6304,
+	0x9296, 0x6305, 0x9297, 0x6306, 0x9298, 0x630A, 0x9299, 0x630B,
+	0x929A, 0x630C, 0x929B, 0x630D, 0x929C, 0x630F, 0x929D, 0x6310,
+	0x929E, 0x6312, 0x929F, 0x6313, 0x92A0, 0x6314, 0x92A1, 0x6315,
+	0x92A2, 0x6317, 0x92A3, 0x6318, 0x92A4, 0x6319, 0x92A5, 0x631C,
+	0x92A6, 0x6326, 0x92A7, 0x6327, 0x92A8, 0x6329, 0x92A9, 0x632C,
+	0x92AA, 0x632D, 0x92AB, 0x632E, 0x92AC, 0x6330, 0x92AD, 0x6331,
+	0x92AE, 0x6333, 0x92AF, 0x6334, 0x92B0, 0x6335, 0x92B1, 0x6336,
+	0x92B2, 0x6337, 0x92B3, 0x6338, 0x92B4, 0x633B, 0x92B5, 0x633C,
+	0x92B6, 0x633E, 0x92B7, 0x633F, 0x92B8, 0x6340, 0x92B9, 0x6341,
+	0x92BA, 0x6344, 0x92BB, 0x6347, 0x92BC, 0x6348, 0x92BD, 0x634A,
+	0x92BE, 0x6351, 0x92BF, 0x6352, 0x92C0, 0x6353, 0x92C1, 0x6354,
+	0x92C2, 0x6356, 0x92C3, 0x6357, 0x92C4, 0x6358, 0x92C5, 0x6359,
+	0x92C6, 0x635A, 0x92C7, 0x635B, 0x92C8, 0x635C, 0x92C9, 0x635D,
+	0x92CA, 0x6360, 0x92CB, 0x6364, 0x92CC, 0x6365, 0x92CD, 0x6366,
+	0x92CE, 0x6368, 0x92CF, 0x636A, 0x92D0, 0x636B, 0x92D1, 0x636C,
+	0x92D2, 0x636F, 0x92D3, 0x6370, 0x92D4, 0x6372, 0x92D5, 0x6373,
+	0x92D6, 0x6374, 0x92D7, 0x6375, 0x92D8, 0x6378, 0x92D9, 0x6379,
+	0x92DA, 0x637C, 0x92DB, 0x637D, 0x92DC, 0x637E, 0x92DD, 0x637F,
+	0x92DE, 0x6381, 0x92DF, 0x6383, 0x92E0, 0x6384, 0x92E1, 0x6385,
+	0x92E2, 0x6386, 0x92E3, 0x638B, 0x92E4, 0x638D, 0x92E5, 0x6391,
+	0x92E6, 0x6393, 0x92E7, 0x6394, 0x92E8, 0x6395, 0x92E9, 0x6397,
+	0x92EA, 0x6399, 0x92EB, 0x639A, 0x92EC, 0x639B, 0x92ED, 0x639C,
+	0x92EE, 0x639D, 0x92EF, 0x639E, 0x92F0, 0x639F, 0x92F1, 0x63A1,
+	0x92F2, 0x63A4, 0x92F3, 0x63A6, 0x92F4, 0x63AB, 0x92F5, 0x63AF,
+	0x92F6, 0x63B1, 0x92F7, 0x63B2, 0x92F8, 0x63B5, 0x92F9, 0x63B6,
+	0x92FA, 0x63B9, 0x92FB, 0x63BB, 0x92FC, 0x63BD, 0x92FD, 0x63BF,
+	0x92FE, 0x63C0, 0x9340, 0x63C1, 0x9341, 0x63C2, 0x9342, 0x63C3,
+	0x9343, 0x63C5, 0x9344, 0x63C7, 0x9345, 0x63C8, 0x9346, 0x63CA,
+	0x9347, 0x63CB, 0x9348, 0x63CC, 0x9349, 0x63D1, 0x934A, 0x63D3,
+	0x934B, 0x63D4, 0x934C, 0x63D5, 0x934D, 0x63D7, 0x934E, 0x63D8,
+	0x934F, 0x63D9, 0x9350, 0x63DA, 0x9351, 0x63DB, 0x9352, 0x63DC,
+	0x9353, 0x63DD, 0x9354, 0x63DF, 0x9355, 0x63E2, 0x9356, 0x63E4,
+	0x9357, 0x63E5, 0x9358, 0x63E6, 0x9359, 0x63E7, 0x935A, 0x63E8,
+	0x935B, 0x63EB, 0x935C, 0x63EC, 0x935D, 0x63EE, 0x935E, 0x63EF,
+	0x935F, 0x63F0, 0x9360, 0x63F1, 0x9361, 0x63F3, 0x9362, 0x63F5,
+	0x9363, 0x63F7, 0x9364, 0x63F9, 0x9365, 0x63FA, 0x9366, 0x63FB,
+	0x9367, 0x63FC, 0x9368, 0x63FE, 0x9369, 0x6403, 0x936A, 0x6404,
+	0x936B, 0x6406, 0x936C, 0x6407, 0x936D, 0x6408, 0x936E, 0x6409,
+	0x936F, 0x640A, 0x9370, 0x640D, 0x9371, 0x640E, 0x9372, 0x6411,
+	0x9373, 0x6412, 0x9374, 0x6415, 0x9375, 0x6416, 0x9376, 0x6417,
+	0x9377, 0x6418, 0x9378, 0x6419, 0x9379, 0x641A, 0x937A, 0x641D,
+	0x937B, 0x641F, 0x937C, 0x6422, 0x937D, 0x6423, 0x937E, 0x6424,
+	0x9380, 0x6425, 0x9381, 0x6427, 0x9382, 0x6428, 0x9383, 0x6429,
+	0x9384, 0x642B, 0x9385, 0x642E, 0x9386, 0x642F, 0x9387, 0x6430,
+	0x9388, 0x6431, 0x9389, 0x6432, 0x938A, 0x6433, 0x938B, 0x6435,
+	0x938C, 0x6436, 0x938D, 0x6437, 0x938E, 0x6438, 0x938F, 0x6439,
+	0x9390, 0x643B, 0x9391, 0x643C, 0x9392, 0x643E, 0x9393, 0x6440,
+	0x9394, 0x6442, 0x9395, 0x6443, 0x9396, 0x6449, 0x9397, 0x644B,
+	0x9398, 0x644C, 0x9399, 0x644D, 0x939A, 0x644E, 0x939B, 0x644F,
+	0x939C, 0x6450, 0x939D, 0x6451, 0x939E, 0x6453, 0x939F, 0x6455,
+	0x93A0, 0x6456, 0x93A1, 0x6457, 0x93A2, 0x6459, 0x93A3, 0x645A,
+	0x93A4, 0x645B, 0x93A5, 0x645C, 0x93A6, 0x645D, 0x93A7, 0x645F,
+	0x93A8, 0x6460, 0x93A9, 0x6461, 0x93AA, 0x6462, 0x93AB, 0x6463,
+	0x93AC, 0x6464, 0x93AD, 0x6465, 0x93AE, 0x6466, 0x93AF, 0x6468,
+	0x93B0, 0x646A, 0x93B1, 0x646B, 0x93B2, 0x646C, 0x93B3, 0x646E,
+	0x93B4, 0x646F, 0x93B5, 0x6470, 0x93B6, 0x6471, 0x93B7, 0x6472,
+	0x93B8, 0x6473, 0x93B9, 0x6474, 0x93BA, 0x6475, 0x93BB, 0x6476,
+	0x93BC, 0x6477, 0x93BD, 0x647B, 0x93BE, 0x647C, 0x93BF, 0x647D,
+	0x93C0, 0x647E, 0x93C1, 0x647F, 0x93C2, 0x6480, 0x93C3, 0x6481,
+	0x93C4, 0x6483, 0x93C5, 0x6486, 0x93C6, 0x6488, 0x93C7, 0x6489,
+	0x93C8, 0x648A, 0x93C9, 0x648B, 0x93CA, 0x648C, 0x93CB, 0x648D,
+	0x93CC, 0x648E, 0x93CD, 0x648F, 0x93CE, 0x6490, 0x93CF, 0x6493,
+	0x93D0, 0x6494, 0x93D1, 0x6497, 0x93D2, 0x6498, 0x93D3, 0x649A,
+	0x93D4, 0x649B, 0x93D5, 0x649C, 0x93D6, 0x649D, 0x93D7, 0x649F,
+	0x93D8, 0x64A0, 0x93D9, 0x64A1, 0x93DA, 0x64A2, 0x93DB, 0x64A3,
+	0x93DC, 0x64A5, 0x93DD, 0x64A6, 0x93DE, 0x64A7, 0x93DF, 0x64A8,
+	0x93E0, 0x64AA, 0x93E1, 0x64AB, 0x93E2, 0x64AF, 0x93E3, 0x64B1,
+	0x93E4, 0x64B2, 0x93E5, 0x64B3, 0x93E6, 0x64B4, 0x93E7, 0x64B6,
+	0x93E8, 0x64B9, 0x93E9, 0x64BB, 0x93EA, 0x64BD, 0x93EB, 0x64BE,
+	0x93EC, 0x64BF, 0x93ED, 0x64C1, 0x93EE, 0x64C3, 0x93EF, 0x64C4,
+	0x93F0, 0x64C6, 0x93F1, 0x64C7, 0x93F2, 0x64C8, 0x93F3, 0x64C9,
+	0x93F4, 0x64CA, 0x93F5, 0x64CB, 0x93F6, 0x64CC, 0x93F7, 0x64CF,
+	0x93F8, 0x64D1, 0x93F9, 0x64D3, 0x93FA, 0x64D4, 0x93FB, 0x64D5,
+	0x93FC, 0x64D6, 0x93FD, 0x64D9, 0x93FE, 0x64DA, 0x9440, 0x64DB,
+	0x9441, 0x64DC, 0x9442, 0x64DD, 0x9443, 0x64DF, 0x9444, 0x64E0,
+	0x9445, 0x64E1, 0x9446, 0x64E3, 0x9447, 0x64E5, 0x9448, 0x64E7,
+	0x9449, 0x64E8, 0x944A, 0x64E9, 0x944B, 0x64EA, 0x944C, 0x64EB,
+	0x944D, 0x64EC, 0x944E, 0x64ED, 0x944F, 0x64EE, 0x9450, 0x64EF,
+	0x9451, 0x64F0, 0x9452, 0x64F1, 0x9453, 0x64F2, 0x9454, 0x64F3,
+	0x9455, 0x64F4, 0x9456, 0x64F5, 0x9457, 0x64F6, 0x9458, 0x64F7,
+	0x9459, 0x64F8, 0x945A, 0x64F9, 0x945B, 0x64FA, 0x945C, 0x64FB,
+	0x945D, 0x64FC, 0x945E, 0x64FD, 0x945F, 0x64FE, 0x9460, 0x64FF,
+	0x9461, 0x6501, 0x9462, 0x6502, 0x9463, 0x6503, 0x9464, 0x6504,
+	0x9465, 0x6505, 0x9466, 0x6506, 0x9467, 0x6507, 0x9468, 0x6508,
+	0x9469, 0x650A, 0x946A, 0x650B, 0x946B, 0x650C, 0x946C, 0x650D,
+	0x946D, 0x650E, 0x946E, 0x650F, 0x946F, 0x6510, 0x9470, 0x6511,
+	0x9471, 0x6513, 0x9472, 0x6514, 0x9473, 0x6515, 0x9474, 0x6516,
+	0x9475, 0x6517, 0x9476, 0x6519, 0x9477, 0x651A, 0x9478, 0x651B,
+	0x9479, 0x651C, 0x947A, 0x651D, 0x947B, 0x651E, 0x947C, 0x651F,
+	0x947D, 0x6520, 0x947E, 0x6521, 0x9480, 0x6522, 0x9481, 0x6523,
+	0x9482, 0x6524, 0x9483, 0x6526, 0x9484, 0x6527, 0x9485, 0x6528,
+	0x9486, 0x6529, 0x9487, 0x652A, 0x9488, 0x652C, 0x9489, 0x652D,
+	0x948A, 0x6530, 0x948B, 0x6531, 0x948C, 0x6532, 0x948D, 0x6533,
+	0x948E, 0x6537, 0x948F, 0x653A, 0x9490, 0x653C, 0x9491, 0x653D,
+	0x9492, 0x6540, 0x9493, 0x6541, 0x9494, 0x6542, 0x9495, 0x6543,
+	0x9496, 0x6544, 0x9497, 0x6546, 0x9498, 0x6547, 0x9499, 0x654A,
+	0x949A, 0x654B, 0x949B, 0x654D, 0x949C, 0x654E, 0x949D, 0x6550,
+	0x949E, 0x6552, 0x949F, 0x6553, 0x94A0, 0x6554, 0x94A1, 0x6557,
+	0x94A2, 0x6558, 0x94A3, 0x655A, 0x94A4, 0x655C, 0x94A5, 0x655F,
+	0x94A6, 0x6560, 0x94A7, 0x6561, 0x94A8, 0x6564, 0x94A9, 0x6565,
+	0x94AA, 0x6567, 0x94AB, 0x6568, 0x94AC, 0x6569, 0x94AD, 0x656A,
+	0x94AE, 0x656D, 0x94AF, 0x656E, 0x94B0, 0x656F, 0x94B1, 0x6571,
+	0x94B2, 0x6573, 0x94B3, 0x6575, 0x94B4, 0x6576, 0x94B5, 0x6578,
+	0x94B6, 0x6579, 0x94B7, 0x657A, 0x94B8, 0x657B, 0x94B9, 0x657C,
+	0x94BA, 0x657D, 0x94BB, 0x657E, 0x94BC, 0x657F, 0x94BD, 0x6580,
+	0x94BE, 0x6581, 0x94BF, 0x6582, 0x94C0, 0x6583, 0x94C1, 0x6584,
+	0x94C2, 0x6585, 0x94C3, 0x6586, 0x94C4, 0x6588, 0x94C5, 0x6589,
+	0x94C6, 0x658A, 0x94C7, 0x658D, 0x94C8, 0x658E, 0x94C9, 0x658F,
+	0x94CA, 0x6592, 0x94CB, 0x6594, 0x94CC, 0x6595, 0x94CD, 0x6596,
+	0x94CE, 0x6598, 0x94CF, 0x659A, 0x94D0, 0x659D, 0x94D1, 0x659E,
+	0x94D2, 0x65A0, 0x94D3, 0x65A2, 0x94D4, 0x65A3, 0x94D5, 0x65A6,
+	0x94D6, 0x65A8, 0x94D7, 0x65AA, 0x94D8, 0x65AC, 0x94D9, 0x65AE,
+	0x94DA, 0x65B1, 0x94DB, 0x65B2, 0x94DC, 0x65B3, 0x94DD, 0x65B4,
+	0x94DE, 0x65B5, 0x94DF, 0x65B6, 0x94E0, 0x65B7, 0x94E1, 0x65B8,
+	0x94E2, 0x65BA, 0x94E3, 0x65BB, 0x94E4, 0x65BE, 0x94E5, 0x65BF,
+	0x94E6, 0x65C0, 0x94E7, 0x65C2, 0x94E8, 0x65C7, 0x94E9, 0x65C8,
+	0x94EA, 0x65C9, 0x94EB, 0x65CA, 0x94EC, 0x65CD, 0x94ED, 0x65D0,
+	0x94EE, 0x65D1, 0x94EF, 0x65D3, 0x94F0, 0x65D4, 0x94F1, 0x65D5,
+	0x94F2, 0x65D8, 0x94F3, 0x65D9, 0x94F4, 0x65DA, 0x94F5, 0x65DB,
+	0x94F6, 0x65DC, 0x94F7, 0x65DD, 0x94F8, 0x65DE, 0x94F9, 0x65DF,
+	0x94FA, 0x65E1, 0x94FB, 0x65E3, 0x94FC, 0x65E4, 0x94FD, 0x65EA,
+	0x94FE, 0x65EB, 0x9540, 0x65F2, 0x9541, 0x65F3, 0x9542, 0x65F4,
+	0x9543, 0x65F5, 0x9544, 0x65F8, 0x9545, 0x65F9, 0x9546, 0x65FB,
+	0x9547, 0x65FC, 0x9548, 0x65FD, 0x9549, 0x65FE, 0x954A, 0x65FF,
+	0x954B, 0x6601, 0x954C, 0x6604, 0x954D, 0x6605, 0x954E, 0x6607,
+	0x954F, 0x6608, 0x9550, 0x6609, 0x9551, 0x660B, 0x9552, 0x660D,
+	0x9553, 0x6610, 0x9554, 0x6611, 0x9555, 0x6612, 0x9556, 0x6616,
+	0x9557, 0x6617, 0x9558, 0x6618, 0x9559, 0x661A, 0x955A, 0x661B,
+	0x955B, 0x661C, 0x955C, 0x661E, 0x955D, 0x6621, 0x955E, 0x6622,
+	0x955F, 0x6623, 0x9560, 0x6624, 0x9561, 0x6626, 0x9562, 0x6629,
+	0x9563, 0x662A, 0x9564, 0x662B, 0x9565, 0x662C, 0x9566, 0x662E,
+	0x9567, 0x6630, 0x9568, 0x6632, 0x9569, 0x6633, 0x956A, 0x6637,
+	0x956B, 0x6638, 0x956C, 0x6639, 0x956D, 0x663A, 0x956E, 0x663B,
+	0x956F, 0x663D, 0x9570, 0x663F, 0x9571, 0x6640, 0x9572, 0x6642,
+	0x9573, 0x6644, 0x9574, 0x6645, 0x9575, 0x6646, 0x9576, 0x6647,
+	0x9577, 0x6648, 0x9578, 0x6649, 0x9579, 0x664A, 0x957A, 0x664D,
+	0x957B, 0x664E, 0x957C, 0x6650, 0x957D, 0x6651, 0x957E, 0x6658,
+	0x9580, 0x6659, 0x9581, 0x665B, 0x9582, 0x665C, 0x9583, 0x665D,
+	0x9584, 0x665E, 0x9585, 0x6660, 0x9586, 0x6662, 0x9587, 0x6663,
+	0x9588, 0x6665, 0x9589, 0x6667, 0x958A, 0x6669, 0x958B, 0x666A,
+	0x958C, 0x666B, 0x958D, 0x666C, 0x958E, 0x666D, 0x958F, 0x6671,
+	0x9590, 0x6672, 0x9591, 0x6673, 0x9592, 0x6675, 0x9593, 0x6678,
+	0x9594, 0x6679, 0x9595, 0x667B, 0x9596, 0x667C, 0x9597, 0x667D,
+	0x9598, 0x667F, 0x9599, 0x6680, 0x959A, 0x6681, 0x959B, 0x6683,
+	0x959C, 0x6685, 0x959D, 0x6686, 0x959E, 0x6688, 0x959F, 0x6689,
+	0x95A0, 0x668A, 0x95A1, 0x668B, 0x95A2, 0x668D, 0x95A3, 0x668E,
+	0x95A4, 0x668F, 0x95A5, 0x6690, 0x95A6, 0x6692, 0x95A7, 0x6693,
+	0x95A8, 0x6694, 0x95A9, 0x6695, 0x95AA, 0x6698, 0x95AB, 0x6699,
+	0x95AC, 0x669A, 0x95AD, 0x669B, 0x95AE, 0x669C, 0x95AF, 0x669E,
+	0x95B0, 0x669F, 0x95B1, 0x66A0, 0x95B2, 0x66A1, 0x95B3, 0x66A2,
+	0x95B4, 0x66A3, 0x95B5, 0x66A4, 0x95B6, 0x66A5, 0x95B7, 0x66A6,
+	0x95B8, 0x66A9, 0x95B9, 0x66AA, 0x95BA, 0x66AB, 0x95BB, 0x66AC,
+	0x95BC, 0x66AD, 0x95BD, 0x66AF, 0x95BE, 0x66B0, 0x95BF, 0x66B1,
+	0x95C0, 0x66B2, 0x95C1, 0x66B3, 0x95C2, 0x66B5, 0x95C3, 0x66B6,
+	0x95C4, 0x66B7, 0x95C5, 0x66B8, 0x95C6, 0x66BA, 0x95C7, 0x66BB,
+	0x95C8, 0x66BC, 0x95C9, 0x66BD, 0x95CA, 0x66BF, 0x95CB, 0x66C0,
+	0x95CC, 0x66C1, 0x95CD, 0x66C2, 0x95CE, 0x66C3, 0x95CF, 0x66C4,
+	0x95D0, 0x66C5, 0x95D1, 0x66C6, 0x95D2, 0x66C7, 0x95D3, 0x66C8,
+	0x95D4, 0x66C9, 0x95D5, 0x66CA, 0x95D6, 0x66CB, 0x95D7, 0x66CC,
+	0x95D8, 0x66CD, 0x95D9, 0x66CE, 0x95DA, 0x66CF, 0x95DB, 0x66D0,
+	0x95DC, 0x66D1, 0x95DD, 0x66D2, 0x95DE, 0x66D3, 0x95DF, 0x66D4,
+	0x95E0, 0x66D5, 0x95E1, 0x66D6, 0x95E2, 0x66D7, 0x95E3, 0x66D8,
+	0x95E4, 0x66DA, 0x95E5, 0x66DE, 0x95E6, 0x66DF, 0x95E7, 0x66E0,
+	0x95E8, 0x66E1, 0x95E9, 0x66E2, 0x95EA, 0x66E3, 0x95EB, 0x66E4,
+	0x95EC, 0x66E5, 0x95ED, 0x66E7, 0x95EE, 0x66E8, 0x95EF, 0x66EA,
+	0x95F0, 0x66EB, 0x95F1, 0x66EC, 0x95F2, 0x66ED, 0x95F3, 0x66EE,
+	0x95F4, 0x66EF, 0x95F5, 0x66F1, 0x95F6, 0x66F5, 0x95F7, 0x66F6,
+	0x95F8, 0x66F8, 0x95F9, 0x66FA, 0x95FA, 0x66FB, 0x95FB, 0x66FD,
+	0x95FC, 0x6701, 0x95FD, 0x6702, 0x95FE, 0x6703, 0x9640, 0x6704,
+	0x9641, 0x6705, 0x9642, 0x6706, 0x9643, 0x6707, 0x9644, 0x670C,
+	0x9645, 0x670E, 0x9646, 0x670F, 0x9647, 0x6711, 0x9648, 0x6712,
+	0x9649, 0x6713, 0x964A, 0x6716, 0x964B, 0x6718, 0x964C, 0x6719,
+	0x964D, 0x671A, 0x964E, 0x671C, 0x964F, 0x671E, 0x9650, 0x6720,
+	0x9651, 0x6721, 0x9652, 0x6722, 0x9653, 0x6723, 0x9654, 0x6724,
+	0x9655, 0x6725, 0x9656, 0x6727, 0x9657, 0x6729, 0x9658, 0x672E,
+	0x9659, 0x6730, 0x965A, 0x6732, 0x965B, 0x6733, 0x965C, 0x6736,
+	0x965D, 0x6737, 0x965E, 0x6738, 0x965F, 0x6739, 0x9660, 0x673B,
+	0x9661, 0x673C, 0x9662, 0x673E, 0x9663, 0x673F, 0x9664, 0x6741,
+	0x9665, 0x6744, 0x9666, 0x6745, 0x9667, 0x6747, 0x9668, 0x674A,
+	0x9669, 0x674B, 0x966A, 0x674D, 0x966B, 0x6752, 0x966C, 0x6754,
+	0x966D, 0x6755, 0x966E, 0x6757, 0x966F, 0x6758, 0x9670, 0x6759,
+	0x9671, 0x675A, 0x9672, 0x675B, 0x9673, 0x675D, 0x9674, 0x6762,
+	0x9675, 0x6763, 0x9676, 0x6764, 0x9677, 0x6766, 0x9678, 0x6767,
+	0x9679, 0x676B, 0x967A, 0x676C, 0x967B, 0x676E, 0x967C, 0x6771,
+	0x967D, 0x6774, 0x967E, 0x6776, 0x9680, 0x6778, 0x9681, 0x6779,
+	0x9682, 0x677A, 0x9683, 0x677B, 0x9684, 0x677D, 0x9685, 0x6780,
+	0x9686, 0x6782, 0x9687, 0x6783, 0x9688, 0x6785, 0x9689, 0x6786,
+	0x968A, 0x6788, 0x968B, 0x678A, 0x968C, 0x678C, 0x968D, 0x678D,
+	0x968E, 0x678E, 0x968F, 0x678F, 0x9690, 0x6791, 0x9691, 0x6792,
+	0x9692, 0x6793, 0x9693, 0x6794, 0x9694, 0x6796, 0x9695, 0x6799,
+	0x9696, 0x679B, 0x9697, 0x679F, 0x9698, 0x67A0, 0x9699, 0x67A1,
+	0x969A, 0x67A4, 0x969B, 0x67A6, 0x969C, 0x67A9, 0x969D, 0x67AC,
+	0x969E, 0x67AE, 0x969F, 0x67B1, 0x96A0, 0x67B2, 0x96A1, 0x67B4,
+	0x96A2, 0x67B9, 0x96A3, 0x67BA, 0x96A4, 0x67BB, 0x96A5, 0x67BC,
+	0x96A6, 0x67BD, 0x96A7, 0x67BE, 0x96A8, 0x67BF, 0x96A9, 0x67C0,
+	0x96AA, 0x67C2, 0x96AB, 0x67C5, 0x96AC, 0x67C6, 0x96AD, 0x67C7,
+	0x96AE, 0x67C8, 0x96AF, 0x67C9, 0x96B0, 0x67CA, 0x96B1, 0x67CB,
+	0x96B2, 0x67CC, 0x96B3, 0x67CD, 0x96B4, 0x67CE, 0x96B5, 0x67D5,
+	0x96B6, 0x67D6, 0x96B7, 0x67D7, 0x96B8, 0x67DB, 0x96B9, 0x67DF,
+	0x96BA, 0x67E1, 0x96BB, 0x67E3, 0x96BC, 0x67E4, 0x96BD, 0x67E6,
+	0x96BE, 0x67E7, 0x96BF, 0x67E8, 0x96C0, 0x67EA, 0x96C1, 0x67EB,
+	0x96C2, 0x67ED, 0x96C3, 0x67EE, 0x96C4, 0x67F2, 0x96C5, 0x67F5,
+	0x96C6, 0x67F6, 0x96C7, 0x67F7, 0x96C8, 0x67F8, 0x96C9, 0x67F9,
+	0x96CA, 0x67FA, 0x96CB, 0x67FB, 0x96CC, 0x67FC, 0x96CD, 0x67FE,
+	0x96CE, 0x6801, 0x96CF, 0x6802, 0x96D0, 0x6803, 0x96D1, 0x6804,
+	0x96D2, 0x6806, 0x96D3, 0x680D, 0x96D4, 0x6810, 0x96D5, 0x6812,
+	0x96D6, 0x6814, 0x96D7, 0x6815, 0x96D8, 0x6818, 0x96D9, 0x6819,
+	0x96DA, 0x681A, 0x96DB, 0x681B, 0x96DC, 0x681C, 0x96DD, 0x681E,
+	0x96DE, 0x681F, 0x96DF, 0x6820, 0x96E0, 0x6822, 0x96E1, 0x6823,
+	0x96E2, 0x6824, 0x96E3, 0x6825, 0x96E4, 0x6826, 0x96E5, 0x6827,
+	0x96E6, 0x6828, 0x96E7, 0x682B, 0x96E8, 0x682C, 0x96E9, 0x682D,
+	0x96EA, 0x682E, 0x96EB, 0x682F, 0x96EC, 0x6830, 0x96ED, 0x6831,
+	0x96EE, 0x6834, 0x96EF, 0x6835, 0x96F0, 0x6836, 0x96F1, 0x683A,
+	0x96F2, 0x683B, 0x96F3, 0x683F, 0x96F4, 0x6847, 0x96F5, 0x684B,
+	0x96F6, 0x684D, 0x96F7, 0x684F, 0x96F8, 0x6852, 0x96F9, 0x6856,
+	0x96FA, 0x6857, 0x96FB, 0x6858, 0x96FC, 0x6859, 0x96FD, 0x685A,
+	0x96FE, 0x685B, 0x9740, 0x685C, 0x9741, 0x685D, 0x9742, 0x685E,
+	0x9743, 0x685F, 0x9744, 0x686A, 0x9745, 0x686C, 0x9746, 0x686D,
+	0x9747, 0x686E, 0x9748, 0x686F, 0x9749, 0x6870, 0x974A, 0x6871,
+	0x974B, 0x6872, 0x974C, 0x6873, 0x974D, 0x6875, 0x974E, 0x6878,
+	0x974F, 0x6879, 0x9750, 0x687A, 0x9751, 0x687B, 0x9752, 0x687C,
+	0x9753, 0x687D, 0x9754, 0x687E, 0x9755, 0x687F, 0x9756, 0x6880,
+	0x9757, 0x6882, 0x9758, 0x6884, 0x9759, 0x6887, 0x975A, 0x6888,
+	0x975B, 0x6889, 0x975C, 0x688A, 0x975D, 0x688B, 0x975E, 0x688C,
+	0x975F, 0x688D, 0x9760, 0x688E, 0x9761, 0x6890, 0x9762, 0x6891,
+	0x9763, 0x6892, 0x9764, 0x6894, 0x9765, 0x6895, 0x9766, 0x6896,
+	0x9767, 0x6898, 0x9768, 0x6899, 0x9769, 0x689A, 0x976A, 0x689B,
+	0x976B, 0x689C, 0x976C, 0x689D, 0x976D, 0x689E, 0x976E, 0x689F,
+	0x976F, 0x68A0, 0x9770, 0x68A1, 0x9771, 0x68A3, 0x9772, 0x68A4,
+	0x9773, 0x68A5, 0x9774, 0x68A9, 0x9775, 0x68AA, 0x9776, 0x68AB,
+	0x9777, 0x68AC, 0x9778, 0x68AE, 0x9779, 0x68B1, 0x977A, 0x68B2,
+	0x977B, 0x68B4, 0x977C, 0x68B6, 0x977D, 0x68B7, 0x977E, 0x68B8,
+	0x9780, 0x68B9, 0x9781, 0x68BA, 0x9782, 0x68BB, 0x9783, 0x68BC,
+	0x9784, 0x68BD, 0x9785, 0x68BE, 0x9786, 0x68BF, 0x9787, 0x68C1,
+	0x9788, 0x68C3, 0x9789, 0x68C4, 0x978A, 0x68C5, 0x978B, 0x68C6,
+	0x978C, 0x68C7, 0x978D, 0x68C8, 0x978E, 0x68CA, 0x978F, 0x68CC,
+	0x9790, 0x68CE, 0x9791, 0x68CF, 0x9792, 0x68D0, 0x9793, 0x68D1,
+	0x9794, 0x68D3, 0x9795, 0x68D4, 0x9796, 0x68D6, 0x9797, 0x68D7,
+	0x9798, 0x68D9, 0x9799, 0x68DB, 0x979A, 0x68DC, 0x979B, 0x68DD,
+	0x979C, 0x68DE, 0x979D, 0x68DF, 0x979E, 0x68E1, 0x979F, 0x68E2,
+	0x97A0, 0x68E4, 0x97A1, 0x68E5, 0x97A2, 0x68E6, 0x97A3, 0x68E7,
+	0x97A4, 0x68E8, 0x97A5, 0x68E9, 0x97A6, 0x68EA, 0x97A7, 0x68EB,
+	0x97A8, 0x68EC, 0x97A9, 0x68ED, 0x97AA, 0x68EF, 0x97AB, 0x68F2,
+	0x97AC, 0x68F3, 0x97AD, 0x68F4, 0x97AE, 0x68F6, 0x97AF, 0x68F7,
+	0x97B0, 0x68F8, 0x97B1, 0x68FB, 0x97B2, 0x68FD, 0x97B3, 0x68FE,
+	0x97B4, 0x68FF, 0x97B5, 0x6900, 0x97B6, 0x6902, 0x97B7, 0x6903,
+	0x97B8, 0x6904, 0x97B9, 0x6906, 0x97BA, 0x6907, 0x97BB, 0x6908,
+	0x97BC, 0x6909, 0x97BD, 0x690A, 0x97BE, 0x690C, 0x97BF, 0x690F,
+	0x97C0, 0x6911, 0x97C1, 0x6913, 0x97C2, 0x6914, 0x97C3, 0x6915,
+	0x97C4, 0x6916, 0x97C5, 0x6917, 0x97C6, 0x6918, 0x97C7, 0x6919,
+	0x97C8, 0x691A, 0x97C9, 0x691B, 0x97CA, 0x691C, 0x97CB, 0x691D,
+	0x97CC, 0x691E, 0x97CD, 0x6921, 0x97CE, 0x6922, 0x97CF, 0x6923,
+	0x97D0, 0x6925, 0x97D1, 0x6926, 0x97D2, 0x6927, 0x97D3, 0x6928,
+	0x97D4, 0x6929, 0x97D5, 0x692A, 0x97D6, 0x692B, 0x97D7, 0x692C,
+	0x97D8, 0x692E, 0x97D9, 0x692F, 0x97DA, 0x6931, 0x97DB, 0x6932,
+	0x97DC, 0x6933, 0x97DD, 0x6935, 0x97DE, 0x6936, 0x97DF, 0x6937,
+	0x97E0, 0x6938, 0x97E1, 0x693A, 0x97E2, 0x693B, 0x97E3, 0x693C,
+	0x97E4, 0x693E, 0x97E5, 0x6940, 0x97E6, 0x6941, 0x97E7, 0x6943,
+	0x97E8, 0x6944, 0x97E9, 0x6945, 0x97EA, 0x6946, 0x97EB, 0x6947,
+	0x97EC, 0x6948, 0x97ED, 0x6949, 0x97EE, 0x694A, 0x97EF, 0x694B,
+	0x97F0, 0x694C, 0x97F1, 0x694D, 0x97F2, 0x694E, 0x97F3, 0x694F,
+	0x97F4, 0x6950, 0x97F5, 0x6951, 0x97F6, 0x6952, 0x97F7, 0x6953,
+	0x97F8, 0x6955, 0x97F9, 0x6956, 0x97FA, 0x6958, 0x97FB, 0x6959,
+	0x97FC, 0x695B, 0x97FD, 0x695C, 0x97FE, 0x695F, 0x9840, 0x6961,
+	0x9841, 0x6962, 0x9842, 0x6964, 0x9843, 0x6965, 0x9844, 0x6967,
+	0x9845, 0x6968, 0x9846, 0x6969, 0x9847, 0x696A, 0x9848, 0x696C,
+	0x9849, 0x696D, 0x984A, 0x696F, 0x984B, 0x6970, 0x984C, 0x6972,
+	0x984D, 0x6973, 0x984E, 0x6974, 0x984F, 0x6975, 0x9850, 0x6976,
+	0x9851, 0x697A, 0x9852, 0x697B, 0x9853, 0x697D, 0x9854, 0x697E,
+	0x9855, 0x697F, 0x9856, 0x6981, 0x9857, 0x6983, 0x9858, 0x6985,
+	0x9859, 0x698A, 0x985A, 0x698B, 0x985B, 0x698C, 0x985C, 0x698E,
+	0x985D, 0x698F, 0x985E, 0x6990, 0x985F, 0x6991, 0x9860, 0x6992,
+	0x9861, 0x6993, 0x9862, 0x6996, 0x9863, 0x6997, 0x9864, 0x6999,
+	0x9865, 0x699A, 0x9866, 0x699D, 0x9867, 0x699E, 0x9868, 0x699F,
+	0x9869, 0x69A0, 0x986A, 0x69A1, 0x986B, 0x69A2, 0x986C, 0x69A3,
+	0x986D, 0x69A4, 0x986E, 0x69A5, 0x986F, 0x69A6, 0x9870, 0x69A9,
+	0x9871, 0x69AA, 0x9872, 0x69AC, 0x9873, 0x69AE, 0x9874, 0x69AF,
+	0x9875, 0x69B0, 0x9876, 0x69B2, 0x9877, 0x69B3, 0x9878, 0x69B5,
+	0x9879, 0x69B6, 0x987A, 0x69B8, 0x987B, 0x69B9, 0x987C, 0x69BA,
+	0x987D, 0x69BC, 0x987E, 0x69BD, 0x9880, 0x69BE, 0x9881, 0x69BF,
+	0x9882, 0x69C0, 0x9883, 0x69C2, 0x9884, 0x69C3, 0x9885, 0x69C4,
+	0x9886, 0x69C5, 0x9887, 0x69C6, 0x9888, 0x69C7, 0x9889, 0x69C8,
+	0x988A, 0x69C9, 0x988B, 0x69CB, 0x988C, 0x69CD, 0x988D, 0x69CF,
+	0x988E, 0x69D1, 0x988F, 0x69D2, 0x9890, 0x69D3, 0x9891, 0x69D5,
+	0x9892, 0x69D6, 0x9893, 0x69D7, 0x9894, 0x69D8, 0x9895, 0x69D9,
+	0x9896, 0x69DA, 0x9897, 0x69DC, 0x9898, 0x69DD, 0x9899, 0x69DE,
+	0x989A, 0x69E1, 0x989B, 0x69E2, 0x989C, 0x69E3, 0x989D, 0x69E4,
+	0x989E, 0x69E5, 0x989F, 0x69E6, 0x98A0, 0x69E7, 0x98A1, 0x69E8,
+	0x98A2, 0x69E9, 0x98A3, 0x69EA, 0x98A4, 0x69EB, 0x98A5, 0x69EC,
+	0x98A6, 0x69EE, 0x98A7, 0x69EF, 0x98A8, 0x69F0, 0x98A9, 0x69F1,
+	0x98AA, 0x69F3, 0x98AB, 0x69F4, 0x98AC, 0x69F5, 0x98AD, 0x69F6,
+	0x98AE, 0x69F7, 0x98AF, 0x69F8, 0x98B0, 0x69F9, 0x98B1, 0x69FA,
+	0x98B2, 0x69FB, 0x98B3, 0x69FC, 0x98B4, 0x69FE, 0x98B5, 0x6A00,
+	0x98B6, 0x6A01, 0x98B7, 0x6A02, 0x98B8, 0x6A03, 0x98B9, 0x6A04,
+	0x98BA, 0x6A05, 0x98BB, 0x6A06, 0x98BC, 0x6A07, 0x98BD, 0x6A08,
+	0x98BE, 0x6A09, 0x98BF, 0x6A0B, 0x98C0, 0x6A0C, 0x98C1, 0x6A0D,
+	0x98C2, 0x6A0E, 0x98C3, 0x6A0F, 0x98C4, 0x6A10, 0x98C5, 0x6A11,
+	0x98C6, 0x6A12, 0x98C7, 0x6A13, 0x98C8, 0x6A14, 0x98C9, 0x6A15,
+	0x98CA, 0x6A16, 0x98CB, 0x6A19, 0x98CC, 0x6A1A, 0x98CD, 0x6A1B,
+	0x98CE, 0x6A1C, 0x98CF, 0x6A1D, 0x98D0, 0x6A1E, 0x98D1, 0x6A20,
+	0x98D2, 0x6A22, 0x98D3, 0x6A23, 0x98D4, 0x6A24, 0x98D5, 0x6A25,
+	0x98D6, 0x6A26, 0x98D7, 0x6A27, 0x98D8, 0x6A29, 0x98D9, 0x6A2B,
+	0x98DA, 0x6A2C, 0x98DB, 0x6A2D, 0x98DC, 0x6A2E, 0x98DD, 0x6A30,
+	0x98DE, 0x6A32, 0x98DF, 0x6A33, 0x98E0, 0x6A34, 0x98E1, 0x6A36,
+	0x98E2, 0x6A37, 0x98E3, 0x6A38, 0x98E4, 0x6A39, 0x98E5, 0x6A3A,
+	0x98E6, 0x6A3B, 0x98E7, 0x6A3C, 0x98E8, 0x6A3F, 0x98E9, 0x6A40,
+	0x98EA, 0x6A41, 0x98EB, 0x6A42, 0x98EC, 0x6A43, 0x98ED, 0x6A45,
+	0x98EE, 0x6A46, 0x98EF, 0x6A48, 0x98F0, 0x6A49, 0x98F1, 0x6A4A,
+	0x98F2, 0x6A4B, 0x98F3, 0x6A4C, 0x98F4, 0x6A4D, 0x98F5, 0x6A4E,
+	0x98F6, 0x6A4F, 0x98F7, 0x6A51, 0x98F8, 0x6A52, 0x98F9, 0x6A53,
+	0x98FA, 0x6A54, 0x98FB, 0x6A55, 0x98FC, 0x6A56, 0x98FD, 0x6A57,
+	0x98FE, 0x6A5A, 0x9940, 0x6A5C, 0x9941, 0x6A5D, 0x9942, 0x6A5E,
+	0x9943, 0x6A5F, 0x9944, 0x6A60, 0x9945, 0x6A62, 0x9946, 0x6A63,
+	0x9947, 0x6A64, 0x9948, 0x6A66, 0x9949, 0x6A67, 0x994A, 0x6A68,
+	0x994B, 0x6A69, 0x994C, 0x6A6A, 0x994D, 0x6A6B, 0x994E, 0x6A6C,
+	0x994F, 0x6A6D, 0x9950, 0x6A6E, 0x9951, 0x6A6F, 0x9952, 0x6A70,
+	0x9953, 0x6A72, 0x9954, 0x6A73, 0x9955, 0x6A74, 0x9956, 0x6A75,
+	0x9957, 0x6A76, 0x9958, 0x6A77, 0x9959, 0x6A78, 0x995A, 0x6A7A,
+	0x995B, 0x6A7B, 0x995C, 0x6A7D, 0x995D, 0x6A7E, 0x995E, 0x6A7F,
+	0x995F, 0x6A81, 0x9960, 0x6A82, 0x9961, 0x6A83, 0x9962, 0x6A85,
+	0x9963, 0x6A86, 0x9964, 0x6A87, 0x9965, 0x6A88, 0x9966, 0x6A89,
+	0x9967, 0x6A8A, 0x9968, 0x6A8B, 0x9969, 0x6A8C, 0x996A, 0x6A8D,
+	0x996B, 0x6A8F, 0x996C, 0x6A92, 0x996D, 0x6A93, 0x996E, 0x6A94,
+	0x996F, 0x6A95, 0x9970, 0x6A96, 0x9971, 0x6A98, 0x9972, 0x6A99,
+	0x9973, 0x6A9A, 0x9974, 0x6A9B, 0x9975, 0x6A9C, 0x9976, 0x6A9D,
+	0x9977, 0x6A9E, 0x9978, 0x6A9F, 0x9979, 0x6AA1, 0x997A, 0x6AA2,
+	0x997B, 0x6AA3, 0x997C, 0x6AA4, 0x997D, 0x6AA5, 0x997E, 0x6AA6,
+	0x9980, 0x6AA7, 0x9981, 0x6AA8, 0x9982, 0x6AAA, 0x9983, 0x6AAD,
+	0x9984, 0x6AAE, 0x9985, 0x6AAF, 0x9986, 0x6AB0, 0x9987, 0x6AB1,
+	0x9988, 0x6AB2, 0x9989, 0x6AB3, 0x998A, 0x6AB4, 0x998B, 0x6AB5,
+	0x998C, 0x6AB6, 0x998D, 0x6AB7, 0x998E, 0x6AB8, 0x998F, 0x6AB9,
+	0x9990, 0x6ABA, 0x9991, 0x6ABB, 0x9992, 0x6ABC, 0x9993, 0x6ABD,
+	0x9994, 0x6ABE, 0x9995, 0x6ABF, 0x9996, 0x6AC0, 0x9997, 0x6AC1,
+	0x9998, 0x6AC2, 0x9999, 0x6AC3, 0x999A, 0x6AC4, 0x999B, 0x6AC5,
+	0x999C, 0x6AC6, 0x999D, 0x6AC7, 0x999E, 0x6AC8, 0x999F, 0x6AC9,
+	0x99A0, 0x6ACA, 0x99A1, 0x6ACB, 0x99A2, 0x6ACC, 0x99A3, 0x6ACD,
+	0x99A4, 0x6ACE, 0x99A5, 0x6ACF, 0x99A6, 0x6AD0, 0x99A7, 0x6AD1,
+	0x99A8, 0x6AD2, 0x99A9, 0x6AD3, 0x99AA, 0x6AD4, 0x99AB, 0x6AD5,
+	0x99AC, 0x6AD6, 0x99AD, 0x6AD7, 0x99AE, 0x6AD8, 0x99AF, 0x6AD9,
+	0x99B0, 0x6ADA, 0x99B1, 0x6ADB, 0x99B2, 0x6ADC, 0x99B3, 0x6ADD,
+	0x99B4, 0x6ADE, 0x99B5, 0x6ADF, 0x99B6, 0x6AE0, 0x99B7, 0x6AE1,
+	0x99B8, 0x6AE2, 0x99B9, 0x6AE3, 0x99BA, 0x6AE4, 0x99BB, 0x6AE5,
+	0x99BC, 0x6AE6, 0x99BD, 0x6AE7, 0x99BE, 0x6AE8, 0x99BF, 0x6AE9,
+	0x99C0, 0x6AEA, 0x99C1, 0x6AEB, 0x99C2, 0x6AEC, 0x99C3, 0x6AED,
+	0x99C4, 0x6AEE, 0x99C5, 0x6AEF, 0x99C6, 0x6AF0, 0x99C7, 0x6AF1,
+	0x99C8, 0x6AF2, 0x99C9, 0x6AF3, 0x99CA, 0x6AF4, 0x99CB, 0x6AF5,
+	0x99CC, 0x6AF6, 0x99CD, 0x6AF7, 0x99CE, 0x6AF8, 0x99CF, 0x6AF9,
+	0x99D0, 0x6AFA, 0x99D1, 0x6AFB, 0x99D2, 0x6AFC, 0x99D3, 0x6AFD,
+	0x99D4, 0x6AFE, 0x99D5, 0x6AFF, 0x99D6, 0x6B00, 0x99D7, 0x6B01,
+	0x99D8, 0x6B02, 0x99D9, 0x6B03, 0x99DA, 0x6B04, 0x99DB, 0x6B05,
+	0x99DC, 0x6B06, 0x99DD, 0x6B07, 0x99DE, 0x6B08, 0x99DF, 0x6B09,
+	0x99E0, 0x6B0A, 0x99E1, 0x6B0B, 0x99E2, 0x6B0C, 0x99E3, 0x6B0D,
+	0x99E4, 0x6B0E, 0x99E5, 0x6B0F, 0x99E6, 0x6B10, 0x99E7, 0x6B11,
+	0x99E8, 0x6B12, 0x99E9, 0x6B13, 0x99EA, 0x6B14, 0x99EB, 0x6B15,
+	0x99EC, 0x6B16, 0x99ED, 0x6B17, 0x99EE, 0x6B18, 0x99EF, 0x6B19,
+	0x99F0, 0x6B1A, 0x99F1, 0x6B1B, 0x99F2, 0x6B1C, 0x99F3, 0x6B1D,
+	0x99F4, 0x6B1E, 0x99F5, 0x6B1F, 0x99F6, 0x6B25, 0x99F7, 0x6B26,
+	0x99F8, 0x6B28, 0x99F9, 0x6B29, 0x99FA, 0x6B2A, 0x99FB, 0x6B2B,
+	0x99FC, 0x6B2C, 0x99FD, 0x6B2D, 0x99FE, 0x6B2E, 0x9A40, 0x6B2F,
+	0x9A41, 0x6B30, 0x9A42, 0x6B31, 0x9A43, 0x6B33, 0x9A44, 0x6B34,
+	0x9A45, 0x6B35, 0x9A46, 0x6B36, 0x9A47, 0x6B38, 0x9A48, 0x6B3B,
+	0x9A49, 0x6B3C, 0x9A4A, 0x6B3D, 0x9A4B, 0x6B3F, 0x9A4C, 0x6B40,
+	0x9A4D, 0x6B41, 0x9A4E, 0x6B42, 0x9A4F, 0x6B44, 0x9A50, 0x6B45,
+	0x9A51, 0x6B48, 0x9A52, 0x6B4A, 0x9A53, 0x6B4B, 0x9A54, 0x6B4D,
+	0x9A55, 0x6B4E, 0x9A56, 0x6B4F, 0x9A57, 0x6B50, 0x9A58, 0x6B51,
+	0x9A59, 0x6B52, 0x9A5A, 0x6B53, 0x9A5B, 0x6B54, 0x9A5C, 0x6B55,
+	0x9A5D, 0x6B56, 0x9A5E, 0x6B57, 0x9A5F, 0x6B58, 0x9A60, 0x6B5A,
+	0x9A61, 0x6B5B, 0x9A62, 0x6B5C, 0x9A63, 0x6B5D, 0x9A64, 0x6B5E,
+	0x9A65, 0x6B5F, 0x9A66, 0x6B60, 0x9A67, 0x6B61, 0x9A68, 0x6B68,
+	0x9A69, 0x6B69, 0x9A6A, 0x6B6B, 0x9A6B, 0x6B6C, 0x9A6C, 0x6B6D,
+	0x9A6D, 0x6B6E, 0x9A6E, 0x6B6F, 0x9A6F, 0x6B70, 0x9A70, 0x6B71,
+	0x9A71, 0x6B72, 0x9A72, 0x6B73, 0x9A73, 0x6B74, 0x9A74, 0x6B75,
+	0x9A75, 0x6B76, 0x9A76, 0x6B77, 0x9A77, 0x6B78, 0x9A78, 0x6B7A,
+	0x9A79, 0x6B7D, 0x9A7A, 0x6B7E, 0x9A7B, 0x6B7F, 0x9A7C, 0x6B80,
+	0x9A7D, 0x6B85, 0x9A7E, 0x6B88, 0x9A80, 0x6B8C, 0x9A81, 0x6B8E,
+	0x9A82, 0x6B8F, 0x9A83, 0x6B90, 0x9A84, 0x6B91, 0x9A85, 0x6B94,
+	0x9A86, 0x6B95, 0x9A87, 0x6B97, 0x9A88, 0x6B98, 0x9A89, 0x6B99,
+	0x9A8A, 0x6B9C, 0x9A8B, 0x6B9D, 0x9A8C, 0x6B9E, 0x9A8D, 0x6B9F,
+	0x9A8E, 0x6BA0, 0x9A8F, 0x6BA2, 0x9A90, 0x6BA3, 0x9A91, 0x6BA4,
+	0x9A92, 0x6BA5, 0x9A93, 0x6BA6, 0x9A94, 0x6BA7, 0x9A95, 0x6BA8,
+	0x9A96, 0x6BA9, 0x9A97, 0x6BAB, 0x9A98, 0x6BAC, 0x9A99, 0x6BAD,
+	0x9A9A, 0x6BAE, 0x9A9B, 0x6BAF, 0x9A9C, 0x6BB0, 0x9A9D, 0x6BB1,
+	0x9A9E, 0x6BB2, 0x9A9F, 0x6BB6, 0x9AA0, 0x6BB8, 0x9AA1, 0x6BB9,
+	0x9AA2, 0x6BBA, 0x9AA3, 0x6BBB, 0x9AA4, 0x6BBC, 0x9AA5, 0x6BBD,
+	0x9AA6, 0x6BBE, 0x9AA7, 0x6BC0, 0x9AA8, 0x6BC3, 0x9AA9, 0x6BC4,
+	0x9AAA, 0x6BC6, 0x9AAB, 0x6BC7, 0x9AAC, 0x6BC8, 0x9AAD, 0x6BC9,
+	0x9AAE, 0x6BCA, 0x9AAF, 0x6BCC, 0x9AB0, 0x6BCE, 0x9AB1, 0x6BD0,
+	0x9AB2, 0x6BD1, 0x9AB3, 0x6BD8, 0x9AB4, 0x6BDA, 0x9AB5, 0x6BDC,
+	0x9AB6, 0x6BDD, 0x9AB7, 0x6BDE, 0x9AB8, 0x6BDF, 0x9AB9, 0x6BE0,
+	0x9ABA, 0x6BE2, 0x9ABB, 0x6BE3, 0x9ABC, 0x6BE4, 0x9ABD, 0x6BE5,
+	0x9ABE, 0x6BE6, 0x9ABF, 0x6BE7, 0x9AC0, 0x6BE8, 0x9AC1, 0x6BE9,
+	0x9AC2, 0x6BEC, 0x9AC3, 0x6BED, 0x9AC4, 0x6BEE, 0x9AC5, 0x6BF0,
+	0x9AC6, 0x6BF1, 0x9AC7, 0x6BF2, 0x9AC8, 0x6BF4, 0x9AC9, 0x6BF6,
+	0x9ACA, 0x6BF7, 0x9ACB, 0x6BF8, 0x9ACC, 0x6BFA, 0x9ACD, 0x6BFB,
+	0x9ACE, 0x6BFC, 0x9ACF, 0x6BFE, 0x9AD0, 0x6BFF, 0x9AD1, 0x6C00,
+	0x9AD2, 0x6C01, 0x9AD3, 0x6C02, 0x9AD4, 0x6C03, 0x9AD5, 0x6C04,
+	0x9AD6, 0x6C08, 0x9AD7, 0x6C09, 0x9AD8, 0x6C0A, 0x9AD9, 0x6C0B,
+	0x9ADA, 0x6C0C, 0x9ADB, 0x6C0E, 0x9ADC, 0x6C12, 0x9ADD, 0x6C17,
+	0x9ADE, 0x6C1C, 0x9ADF, 0x6C1D, 0x9AE0, 0x6C1E, 0x9AE1, 0x6C20,
+	0x9AE2, 0x6C23, 0x9AE3, 0x6C25, 0x9AE4, 0x6C2B, 0x9AE5, 0x6C2C,
+	0x9AE6, 0x6C2D, 0x9AE7, 0x6C31, 0x9AE8, 0x6C33, 0x9AE9, 0x6C36,
+	0x9AEA, 0x6C37, 0x9AEB, 0x6C39, 0x9AEC, 0x6C3A, 0x9AED, 0x6C3B,
+	0x9AEE, 0x6C3C, 0x9AEF, 0x6C3E, 0x9AF0, 0x6C3F, 0x9AF1, 0x6C43,
+	0x9AF2, 0x6C44, 0x9AF3, 0x6C45, 0x9AF4, 0x6C48, 0x9AF5, 0x6C4B,
+	0x9AF6, 0x6C4C, 0x9AF7, 0x6C4D, 0x9AF8, 0x6C4E, 0x9AF9, 0x6C4F,
+	0x9AFA, 0x6C51, 0x9AFB, 0x6C52, 0x9AFC, 0x6C53, 0x9AFD, 0x6C56,
+	0x9AFE, 0x6C58, 0x9B40, 0x6C59, 0x9B41, 0x6C5A, 0x9B42, 0x6C62,
+	0x9B43, 0x6C63, 0x9B44, 0x6C65, 0x9B45, 0x6C66, 0x9B46, 0x6C67,
+	0x9B47, 0x6C6B, 0x9B48, 0x6C6C, 0x9B49, 0x6C6D, 0x9B4A, 0x6C6E,
+	0x9B4B, 0x6C6F, 0x9B4C, 0x6C71, 0x9B4D, 0x6C73, 0x9B4E, 0x6C75,
+	0x9B4F, 0x6C77, 0x9B50, 0x6C78, 0x9B51, 0x6C7A, 0x9B52, 0x6C7B,
+	0x9B53, 0x6C7C, 0x9B54, 0x6C7F, 0x9B55, 0x6C80, 0x9B56, 0x6C84,
+	0x9B57, 0x6C87, 0x9B58, 0x6C8A, 0x9B59, 0x6C8B, 0x9B5A, 0x6C8D,
+	0x9B5B, 0x6C8E, 0x9B5C, 0x6C91, 0x9B5D, 0x6C92, 0x9B5E, 0x6C95,
+	0x9B5F, 0x6C96, 0x9B60, 0x6C97, 0x9B61, 0x6C98, 0x9B62, 0x6C9A,
+	0x9B63, 0x6C9C, 0x9B64, 0x6C9D, 0x9B65, 0x6C9E, 0x9B66, 0x6CA0,
+	0x9B67, 0x6CA2, 0x9B68, 0x6CA8, 0x9B69, 0x6CAC, 0x9B6A, 0x6CAF,
+	0x9B6B, 0x6CB0, 0x9B6C, 0x6CB4, 0x9B6D, 0x6CB5, 0x9B6E, 0x6CB6,
+	0x9B6F, 0x6CB7, 0x9B70, 0x6CBA, 0x9B71, 0x6CC0, 0x9B72, 0x6CC1,
+	0x9B73, 0x6CC2, 0x9B74, 0x6CC3, 0x9B75, 0x6CC6, 0x9B76, 0x6CC7,
+	0x9B77, 0x6CC8, 0x9B78, 0x6CCB, 0x9B79, 0x6CCD, 0x9B7A, 0x6CCE,
+	0x9B7B, 0x6CCF, 0x9B7C, 0x6CD1, 0x9B7D, 0x6CD2, 0x9B7E, 0x6CD8,
+	0x9B80, 0x6CD9, 0x9B81, 0x6CDA, 0x9B82, 0x6CDC, 0x9B83, 0x6CDD,
+	0x9B84, 0x6CDF, 0x9B85, 0x6CE4, 0x9B86, 0x6CE6, 0x9B87, 0x6CE7,
+	0x9B88, 0x6CE9, 0x9B89, 0x6CEC, 0x9B8A, 0x6CED, 0x9B8B, 0x6CF2,
+	0x9B8C, 0x6CF4, 0x9B8D, 0x6CF9, 0x9B8E, 0x6CFF, 0x9B8F, 0x6D00,
+	0x9B90, 0x6D02, 0x9B91, 0x6D03, 0x9B92, 0x6D05, 0x9B93, 0x6D06,
+	0x9B94, 0x6D08, 0x9B95, 0x6D09, 0x9B96, 0x6D0A, 0x9B97, 0x6D0D,
+	0x9B98, 0x6D0F, 0x9B99, 0x6D10, 0x9B9A, 0x6D11, 0x9B9B, 0x6D13,
+	0x9B9C, 0x6D14, 0x9B9D, 0x6D15, 0x9B9E, 0x6D16, 0x9B9F, 0x6D18,
+	0x9BA0, 0x6D1C, 0x9BA1, 0x6D1D, 0x9BA2, 0x6D1F, 0x9BA3, 0x6D20,
+	0x9BA4, 0x6D21, 0x9BA5, 0x6D22, 0x9BA6, 0x6D23, 0x9BA7, 0x6D24,
+	0x9BA8, 0x6D26, 0x9BA9, 0x6D28, 0x9BAA, 0x6D29, 0x9BAB, 0x6D2C,
+	0x9BAC, 0x6D2D, 0x9BAD, 0x6D2F, 0x9BAE, 0x6D30, 0x9BAF, 0x6D34,
+	0x9BB0, 0x6D36, 0x9BB1, 0x6D37, 0x9BB2, 0x6D38, 0x9BB3, 0x6D3A,
+	0x9BB4, 0x6D3F, 0x9BB5, 0x6D40, 0x9BB6, 0x6D42, 0x9BB7, 0x6D44,
+	0x9BB8, 0x6D49, 0x9BB9, 0x6D4C, 0x9BBA, 0x6D50, 0x9BBB, 0x6D55,
+	0x9BBC, 0x6D56, 0x9BBD, 0x6D57, 0x9BBE, 0x6D58, 0x9BBF, 0x6D5B,
+	0x9BC0, 0x6D5D, 0x9BC1, 0x6D5F, 0x9BC2, 0x6D61, 0x9BC3, 0x6D62,
+	0x9BC4, 0x6D64, 0x9BC5, 0x6D65, 0x9BC6, 0x6D67, 0x9BC7, 0x6D68,
+	0x9BC8, 0x6D6B, 0x9BC9, 0x6D6C, 0x9BCA, 0x6D6D, 0x9BCB, 0x6D70,
+	0x9BCC, 0x6D71, 0x9BCD, 0x6D72, 0x9BCE, 0x6D73, 0x9BCF, 0x6D75,
+	0x9BD0, 0x6D76, 0x9BD1, 0x6D79, 0x9BD2, 0x6D7A, 0x9BD3, 0x6D7B,
+	0x9BD4, 0x6D7D, 0x9BD5, 0x6D7E, 0x9BD6, 0x6D7F, 0x9BD7, 0x6D80,
+	0x9BD8, 0x6D81, 0x9BD9, 0x6D83, 0x9BDA, 0x6D84, 0x9BDB, 0x6D86,
+	0x9BDC, 0x6D87, 0x9BDD, 0x6D8A, 0x9BDE, 0x6D8B, 0x9BDF, 0x6D8D,
+	0x9BE0, 0x6D8F, 0x9BE1, 0x6D90, 0x9BE2, 0x6D92, 0x9BE3, 0x6D96,
+	0x9BE4, 0x6D97, 0x9BE5, 0x6D98, 0x9BE6, 0x6D99, 0x9BE7, 0x6D9A,
+	0x9BE8, 0x6D9C, 0x9BE9, 0x6DA2, 0x9BEA, 0x6DA5, 0x9BEB, 0x6DAC,
+	0x9BEC, 0x6DAD, 0x9BED, 0x6DB0, 0x9BEE, 0x6DB1, 0x9BEF, 0x6DB3,
+	0x9BF0, 0x6DB4, 0x9BF1, 0x6DB6, 0x9BF2, 0x6DB7, 0x9BF3, 0x6DB9,
+	0x9BF4, 0x6DBA, 0x9BF5, 0x6DBB, 0x9BF6, 0x6DBC, 0x9BF7, 0x6DBD,
+	0x9BF8, 0x6DBE, 0x9BF9, 0x6DC1, 0x9BFA, 0x6DC2, 0x9BFB, 0x6DC3,
+	0x9BFC, 0x6DC8, 0x9BFD, 0x6DC9, 0x9BFE, 0x6DCA, 0x9C40, 0x6DCD,
+	0x9C41, 0x6DCE, 0x9C42, 0x6DCF, 0x9C43, 0x6DD0, 0x9C44, 0x6DD2,
+	0x9C45, 0x6DD3, 0x9C46, 0x6DD4, 0x9C47, 0x6DD5, 0x9C48, 0x6DD7,
+	0x9C49, 0x6DDA, 0x9C4A, 0x6DDB, 0x9C4B, 0x6DDC, 0x9C4C, 0x6DDF,
+	0x9C4D, 0x6DE2, 0x9C4E, 0x6DE3, 0x9C4F, 0x6DE5, 0x9C50, 0x6DE7,
+	0x9C51, 0x6DE8, 0x9C52, 0x6DE9, 0x9C53, 0x6DEA, 0x9C54, 0x6DED,
+	0x9C55, 0x6DEF, 0x9C56, 0x6DF0, 0x9C57, 0x6DF2, 0x9C58, 0x6DF4,
+	0x9C59, 0x6DF5, 0x9C5A, 0x6DF6, 0x9C5B, 0x6DF8, 0x9C5C, 0x6DFA,
+	0x9C5D, 0x6DFD, 0x9C5E, 0x6DFE, 0x9C5F, 0x6DFF, 0x9C60, 0x6E00,
+	0x9C61, 0x6E01, 0x9C62, 0x6E02, 0x9C63, 0x6E03, 0x9C64, 0x6E04,
+	0x9C65, 0x6E06, 0x9C66, 0x6E07, 0x9C67, 0x6E08, 0x9C68, 0x6E09,
+	0x9C69, 0x6E0B, 0x9C6A, 0x6E0F, 0x9C6B, 0x6E12, 0x9C6C, 0x6E13,
+	0x9C6D, 0x6E15, 0x9C6E, 0x6E18, 0x9C6F, 0x6E19, 0x9C70, 0x6E1B,
+	0x9C71, 0x6E1C, 0x9C72, 0x6E1E, 0x9C73, 0x6E1F, 0x9C74, 0x6E22,
+	0x9C75, 0x6E26, 0x9C76, 0x6E27, 0x9C77, 0x6E28, 0x9C78, 0x6E2A,
+	0x9C79, 0x6E2C, 0x9C7A, 0x6E2E, 0x9C7B, 0x6E30, 0x9C7C, 0x6E31,
+	0x9C7D, 0x6E33, 0x9C7E, 0x6E35, 0x9C80, 0x6E36, 0x9C81, 0x6E37,
+	0x9C82, 0x6E39, 0x9C83, 0x6E3B, 0x9C84, 0x6E3C, 0x9C85, 0x6E3D,
+	0x9C86, 0x6E3E, 0x9C87, 0x6E3F, 0x9C88, 0x6E40, 0x9C89, 0x6E41,
+	0x9C8A, 0x6E42, 0x9C8B, 0x6E45, 0x9C8C, 0x6E46, 0x9C8D, 0x6E47,
+	0x9C8E, 0x6E48, 0x9C8F, 0x6E49, 0x9C90, 0x6E4A, 0x9C91, 0x6E4B,
+	0x9C92, 0x6E4C, 0x9C93, 0x6E4F, 0x9C94, 0x6E50, 0x9C95, 0x6E51,
+	0x9C96, 0x6E52, 0x9C97, 0x6E55, 0x9C98, 0x6E57, 0x9C99, 0x6E59,
+	0x9C9A, 0x6E5A, 0x9C9B, 0x6E5C, 0x9C9C, 0x6E5D, 0x9C9D, 0x6E5E,
+	0x9C9E, 0x6E60, 0x9C9F, 0x6E61, 0x9CA0, 0x6E62, 0x9CA1, 0x6E63,
+	0x9CA2, 0x6E64, 0x9CA3, 0x6E65, 0x9CA4, 0x6E66, 0x9CA5, 0x6E67,
+	0x9CA6, 0x6E68, 0x9CA7, 0x6E69, 0x9CA8, 0x6E6A, 0x9CA9, 0x6E6C,
+	0x9CAA, 0x6E6D, 0x9CAB, 0x6E6F, 0x9CAC, 0x6E70, 0x9CAD, 0x6E71,
+	0x9CAE, 0x6E72, 0x9CAF, 0x6E73, 0x9CB0, 0x6E74, 0x9CB1, 0x6E75,
+	0x9CB2, 0x6E76, 0x9CB3, 0x6E77, 0x9CB4, 0x6E78, 0x9CB5, 0x6E79,
+	0x9CB6, 0x6E7A, 0x9CB7, 0x6E7B, 0x9CB8, 0x6E7C, 0x9CB9, 0x6E7D,
+	0x9CBA, 0x6E80, 0x9CBB, 0x6E81, 0x9CBC, 0x6E82, 0x9CBD, 0x6E84,
+	0x9CBE, 0x6E87, 0x9CBF, 0x6E88, 0x9CC0, 0x6E8A, 0x9CC1, 0x6E8B,
+	0x9CC2, 0x6E8C, 0x9CC3, 0x6E8D, 0x9CC4, 0x6E8E, 0x9CC5, 0x6E91,
+	0x9CC6, 0x6E92, 0x9CC7, 0x6E93, 0x9CC8, 0x6E94, 0x9CC9, 0x6E95,
+	0x9CCA, 0x6E96, 0x9CCB, 0x6E97, 0x9CCC, 0x6E99, 0x9CCD, 0x6E9A,
+	0x9CCE, 0x6E9B, 0x9CCF, 0x6E9D, 0x9CD0, 0x6E9E, 0x9CD1, 0x6EA0,
+	0x9CD2, 0x6EA1, 0x9CD3, 0x6EA3, 0x9CD4, 0x6EA4, 0x9CD5, 0x6EA6,
+	0x9CD6, 0x6EA8, 0x9CD7, 0x6EA9, 0x9CD8, 0x6EAB, 0x9CD9, 0x6EAC,
+	0x9CDA, 0x6EAD, 0x9CDB, 0x6EAE, 0x9CDC, 0x6EB0, 0x9CDD, 0x6EB3,
+	0x9CDE, 0x6EB5, 0x9CDF, 0x6EB8, 0x9CE0, 0x6EB9, 0x9CE1, 0x6EBC,
+	0x9CE2, 0x6EBE, 0x9CE3, 0x6EBF, 0x9CE4, 0x6EC0, 0x9CE5, 0x6EC3,
+	0x9CE6, 0x6EC4, 0x9CE7, 0x6EC5, 0x9CE8, 0x6EC6, 0x9CE9, 0x6EC8,
+	0x9CEA, 0x6EC9, 0x9CEB, 0x6ECA, 0x9CEC, 0x6ECC, 0x9CED, 0x6ECD,
+	0x9CEE, 0x6ECE, 0x9CEF, 0x6ED0, 0x9CF0, 0x6ED2, 0x9CF1, 0x6ED6,
+	0x9CF2, 0x6ED8, 0x9CF3, 0x6ED9, 0x9CF4, 0x6EDB, 0x9CF5, 0x6EDC,
+	0x9CF6, 0x6EDD, 0x9CF7, 0x6EE3, 0x9CF8, 0x6EE7, 0x9CF9, 0x6EEA,
+	0x9CFA, 0x6EEB, 0x9CFB, 0x6EEC, 0x9CFC, 0x6EED, 0x9CFD, 0x6EEE,
+	0x9CFE, 0x6EEF, 0x9D40, 0x6EF0, 0x9D41, 0x6EF1, 0x9D42, 0x6EF2,
+	0x9D43, 0x6EF3, 0x9D44, 0x6EF5, 0x9D45, 0x6EF6, 0x9D46, 0x6EF7,
+	0x9D47, 0x6EF8, 0x9D48, 0x6EFA, 0x9D49, 0x6EFB, 0x9D4A, 0x6EFC,
+	0x9D4B, 0x6EFD, 0x9D4C, 0x6EFE, 0x9D4D, 0x6EFF, 0x9D4E, 0x6F00,
+	0x9D4F, 0x6F01, 0x9D50, 0x6F03, 0x9D51, 0x6F04, 0x9D52, 0x6F05,
+	0x9D53, 0x6F07, 0x9D54, 0x6F08, 0x9D55, 0x6F0A, 0x9D56, 0x6F0B,
+	0x9D57, 0x6F0C, 0x9D58, 0x6F0D, 0x9D59, 0x6F0E, 0x9D5A, 0x6F10,
+	0x9D5B, 0x6F11, 0x9D5C, 0x6F12, 0x9D5D, 0x6F16, 0x9D5E, 0x6F17,
+	0x9D5F, 0x6F18, 0x9D60, 0x6F19, 0x9D61, 0x6F1A, 0x9D62, 0x6F1B,
+	0x9D63, 0x6F1C, 0x9D64, 0x6F1D, 0x9D65, 0x6F1E, 0x9D66, 0x6F1F,
+	0x9D67, 0x6F21, 0x9D68, 0x6F22, 0x9D69, 0x6F23, 0x9D6A, 0x6F25,
+	0x9D6B, 0x6F26, 0x9D6C, 0x6F27, 0x9D6D, 0x6F28, 0x9D6E, 0x6F2C,
+	0x9D6F, 0x6F2E, 0x9D70, 0x6F30, 0x9D71, 0x6F32, 0x9D72, 0x6F34,
+	0x9D73, 0x6F35, 0x9D74, 0x6F37, 0x9D75, 0x6F38, 0x9D76, 0x6F39,
+	0x9D77, 0x6F3A, 0x9D78, 0x6F3B, 0x9D79, 0x6F3C, 0x9D7A, 0x6F3D,
+	0x9D7B, 0x6F3F, 0x9D7C, 0x6F40, 0x9D7D, 0x6F41, 0x9D7E, 0x6F42,
+	0x9D80, 0x6F43, 0x9D81, 0x6F44, 0x9D82, 0x6F45, 0x9D83, 0x6F48,
+	0x9D84, 0x6F49, 0x9D85, 0x6F4A, 0x9D86, 0x6F4C, 0x9D87, 0x6F4E,
+	0x9D88, 0x6F4F, 0x9D89, 0x6F50, 0x9D8A, 0x6F51, 0x9D8B, 0x6F52,
+	0x9D8C, 0x6F53, 0x9D8D, 0x6F54, 0x9D8E, 0x6F55, 0x9D8F, 0x6F56,
+	0x9D90, 0x6F57, 0x9D91, 0x6F59, 0x9D92, 0x6F5A, 0x9D93, 0x6F5B,
+	0x9D94, 0x6F5D, 0x9D95, 0x6F5F, 0x9D96, 0x6F60, 0x9D97, 0x6F61,
+	0x9D98, 0x6F63, 0x9D99, 0x6F64, 0x9D9A, 0x6F65, 0x9D9B, 0x6F67,
+	0x9D9C, 0x6F68, 0x9D9D, 0x6F69, 0x9D9E, 0x6F6A, 0x9D9F, 0x6F6B,
+	0x9DA0, 0x6F6C, 0x9DA1, 0x6F6F, 0x9DA2, 0x6F70, 0x9DA3, 0x6F71,
+	0x9DA4, 0x6F73, 0x9DA5, 0x6F75, 0x9DA6, 0x6F76, 0x9DA7, 0x6F77,
+	0x9DA8, 0x6F79, 0x9DA9, 0x6F7B, 0x9DAA, 0x6F7D, 0x9DAB, 0x6F7E,
+	0x9DAC, 0x6F7F, 0x9DAD, 0x6F80, 0x9DAE, 0x6F81, 0x9DAF, 0x6F82,
+	0x9DB0, 0x6F83, 0x9DB1, 0x6F85, 0x9DB2, 0x6F86, 0x9DB3, 0x6F87,
+	0x9DB4, 0x6F8A, 0x9DB5, 0x6F8B, 0x9DB6, 0x6F8F, 0x9DB7, 0x6F90,
+	0x9DB8, 0x6F91, 0x9DB9, 0x6F92, 0x9DBA, 0x6F93, 0x9DBB, 0x6F94,
+	0x9DBC, 0x6F95, 0x9DBD, 0x6F96, 0x9DBE, 0x6F97, 0x9DBF, 0x6F98,
+	0x9DC0, 0x6F99, 0x9DC1, 0x6F9A, 0x9DC2, 0x6F9B, 0x9DC3, 0x6F9D,
+	0x9DC4, 0x6F9E, 0x9DC5, 0x6F9F, 0x9DC6, 0x6FA0, 0x9DC7, 0x6FA2,
+	0x9DC8, 0x6FA3, 0x9DC9, 0x6FA4, 0x9DCA, 0x6FA5, 0x9DCB, 0x6FA6,
+	0x9DCC, 0x6FA8, 0x9DCD, 0x6FA9, 0x9DCE, 0x6FAA, 0x9DCF, 0x6FAB,
+	0x9DD0, 0x6FAC, 0x9DD1, 0x6FAD, 0x9DD2, 0x6FAE, 0x9DD3, 0x6FAF,
+	0x9DD4, 0x6FB0, 0x9DD5, 0x6FB1, 0x9DD6, 0x6FB2, 0x9DD7, 0x6FB4,
+	0x9DD8, 0x6FB5, 0x9DD9, 0x6FB7, 0x9DDA, 0x6FB8, 0x9DDB, 0x6FBA,
+	0x9DDC, 0x6FBB, 0x9DDD, 0x6FBC, 0x9DDE, 0x6FBD, 0x9DDF, 0x6FBE,
+	0x9DE0, 0x6FBF, 0x9DE1, 0x6FC1, 0x9DE2, 0x6FC3, 0x9DE3, 0x6FC4,
+	0x9DE4, 0x6FC5, 0x9DE5, 0x6FC6, 0x9DE6, 0x6FC7, 0x9DE7, 0x6FC8,
+	0x9DE8, 0x6FCA, 0x9DE9, 0x6FCB, 0x9DEA, 0x6FCC, 0x9DEB, 0x6FCD,
+	0x9DEC, 0x6FCE, 0x9DED, 0x6FCF, 0x9DEE, 0x6FD0, 0x9DEF, 0x6FD3,
+	0x9DF0, 0x6FD4, 0x9DF1, 0x6FD5, 0x9DF2, 0x6FD6, 0x9DF3, 0x6FD7,
+	0x9DF4, 0x6FD8, 0x9DF5, 0x6FD9, 0x9DF6, 0x6FDA, 0x9DF7, 0x6FDB,
+	0x9DF8, 0x6FDC, 0x9DF9, 0x6FDD, 0x9DFA, 0x6FDF, 0x9DFB, 0x6FE2,
+	0x9DFC, 0x6FE3, 0x9DFD, 0x6FE4, 0x9DFE, 0x6FE5, 0x9E40, 0x6FE6,
+	0x9E41, 0x6FE7, 0x9E42, 0x6FE8, 0x9E43, 0x6FE9, 0x9E44, 0x6FEA,
+	0x9E45, 0x6FEB, 0x9E46, 0x6FEC, 0x9E47, 0x6FED, 0x9E48, 0x6FF0,
+	0x9E49, 0x6FF1, 0x9E4A, 0x6FF2, 0x9E4B, 0x6FF3, 0x9E4C, 0x6FF4,
+	0x9E4D, 0x6FF5, 0x9E4E, 0x6FF6, 0x9E4F, 0x6FF7, 0x9E50, 0x6FF8,
+	0x9E51, 0x6FF9, 0x9E52, 0x6FFA, 0x9E53, 0x6FFB, 0x9E54, 0x6FFC,
+	0x9E55, 0x6FFD, 0x9E56, 0x6FFE, 0x9E57, 0x6FFF, 0x9E58, 0x7000,
+	0x9E59, 0x7001, 0x9E5A, 0x7002, 0x9E5B, 0x7003, 0x9E5C, 0x7004,
+	0x9E5D, 0x7005, 0x9E5E, 0x7006, 0x9E5F, 0x7007, 0x9E60, 0x7008,
+	0x9E61, 0x7009, 0x9E62, 0x700A, 0x9E63, 0x700B, 0x9E64, 0x700C,
+	0x9E65, 0x700D, 0x9E66, 0x700E, 0x9E67, 0x700F, 0x9E68, 0x7010,
+	0x9E69, 0x7012, 0x9E6A, 0x7013, 0x9E6B, 0x7014, 0x9E6C, 0x7015,
+	0x9E6D, 0x7016, 0x9E6E, 0x7017, 0x9E6F, 0x7018, 0x9E70, 0x7019,
+	0x9E71, 0x701C, 0x9E72, 0x701D, 0x9E73, 0x701E, 0x9E74, 0x701F,
+	0x9E75, 0x7020, 0x9E76, 0x7021, 0x9E77, 0x7022, 0x9E78, 0x7024,
+	0x9E79, 0x7025, 0x9E7A, 0x7026, 0x9E7B, 0x7027, 0x9E7C, 0x7028,
+	0x9E7D, 0x7029, 0x9E7E, 0x702A, 0x9E80, 0x702B, 0x9E81, 0x702C,
+	0x9E82, 0x702D, 0x9E83, 0x702E, 0x9E84, 0x702F, 0x9E85, 0x7030,
+	0x9E86, 0x7031, 0x9E87, 0x7032, 0x9E88, 0x7033, 0x9E89, 0x7034,
+	0x9E8A, 0x7036, 0x9E8B, 0x7037, 0x9E8C, 0x7038, 0x9E8D, 0x703A,
+	0x9E8E, 0x703B, 0x9E8F, 0x703C, 0x9E90, 0x703D, 0x9E91, 0x703E,
+	0x9E92, 0x703F, 0x9E93, 0x7040, 0x9E94, 0x7041, 0x9E95, 0x7042,
+	0x9E96, 0x7043, 0x9E97, 0x7044, 0x9E98, 0x7045, 0x9E99, 0x7046,
+	0x9E9A, 0x7047, 0x9E9B, 0x7048, 0x9E9C, 0x7049, 0x9E9D, 0x704A,
+	0x9E9E, 0x704B, 0x9E9F, 0x704D, 0x9EA0, 0x704E, 0x9EA1, 0x7050,
+	0x9EA2, 0x7051, 0x9EA3, 0x7052, 0x9EA4, 0x7053, 0x9EA5, 0x7054,
+	0x9EA6, 0x7055, 0x9EA7, 0x7056, 0x9EA8, 0x7057, 0x9EA9, 0x7058,
+	0x9EAA, 0x7059, 0x9EAB, 0x705A, 0x9EAC, 0x705B, 0x9EAD, 0x705C,
+	0x9EAE, 0x705D, 0x9EAF, 0x705F, 0x9EB0, 0x7060, 0x9EB1, 0x7061,
+	0x9EB2, 0x7062, 0x9EB3, 0x7063, 0x9EB4, 0x7064, 0x9EB5, 0x7065,
+	0x9EB6, 0x7066, 0x9EB7, 0x7067, 0x9EB8, 0x7068, 0x9EB9, 0x7069,
+	0x9EBA, 0x706A, 0x9EBB, 0x706E, 0x9EBC, 0x7071, 0x9EBD, 0x7072,
+	0x9EBE, 0x7073, 0x9EBF, 0x7074, 0x9EC0, 0x7077, 0x9EC1, 0x7079,
+	0x9EC2, 0x707A, 0x9EC3, 0x707B, 0x9EC4, 0x707D, 0x9EC5, 0x7081,
+	0x9EC6, 0x7082, 0x9EC7, 0x7083, 0x9EC8, 0x7084, 0x9EC9, 0x7086,
+	0x9ECA, 0x7087, 0x9ECB, 0x7088, 0x9ECC, 0x708B, 0x9ECD, 0x708C,
+	0x9ECE, 0x708D, 0x9ECF, 0x708F, 0x9ED0, 0x7090, 0x9ED1, 0x7091,
+	0x9ED2, 0x7093, 0x9ED3, 0x7097, 0x9ED4, 0x7098, 0x9ED5, 0x709A,
+	0x9ED6, 0x709B, 0x9ED7, 0x709E, 0x9ED8, 0x709F, 0x9ED9, 0x70A0,
+	0x9EDA, 0x70A1, 0x9EDB, 0x70A2, 0x9EDC, 0x70A3, 0x9EDD, 0x70A4,
+	0x9EDE, 0x70A5, 0x9EDF, 0x70A6, 0x9EE0, 0x70A7, 0x9EE1, 0x70A8,
+	0x9EE2, 0x70A9, 0x9EE3, 0x70AA, 0x9EE4, 0x70B0, 0x9EE5, 0x70B2,
+	0x9EE6, 0x70B4, 0x9EE7, 0x70B5, 0x9EE8, 0x70B6, 0x9EE9, 0x70BA,
+	0x9EEA, 0x70BE, 0x9EEB, 0x70BF, 0x9EEC, 0x70C4, 0x9EED, 0x70C5,
+	0x9EEE, 0x70C6, 0x9EEF, 0x70C7, 0x9EF0, 0x70C9, 0x9EF1, 0x70CB,
+	0x9EF2, 0x70CC, 0x9EF3, 0x70CD, 0x9EF4, 0x70CE, 0x9EF5, 0x70CF,
+	0x9EF6, 0x70D0, 0x9EF7, 0x70D1, 0x9EF8, 0x70D2, 0x9EF9, 0x70D3,
+	0x9EFA, 0x70D4, 0x9EFB, 0x70D5, 0x9EFC, 0x70D6, 0x9EFD, 0x70D7,
+	0x9EFE, 0x70DA, 0x9F40, 0x70DC, 0x9F41, 0x70DD, 0x9F42, 0x70DE,
+	0x9F43, 0x70E0, 0x9F44, 0x70E1, 0x9F45, 0x70E2, 0x9F46, 0x70E3,
+	0x9F47, 0x70E5, 0x9F48, 0x70EA, 0x9F49, 0x70EE, 0x9F4A, 0x70F0,
+	0x9F4B, 0x70F1, 0x9F4C, 0x70F2, 0x9F4D, 0x70F3, 0x9F4E, 0x70F4,
+	0x9F4F, 0x70F5, 0x9F50, 0x70F6, 0x9F51, 0x70F8, 0x9F52, 0x70FA,
+	0x9F53, 0x70FB, 0x9F54, 0x70FC, 0x9F55, 0x70FE, 0x9F56, 0x70FF,
+	0x9F57, 0x7100, 0x9F58, 0x7101, 0x9F59, 0x7102, 0x9F5A, 0x7103,
+	0x9F5B, 0x7104, 0x9F5C, 0x7105, 0x9F5D, 0x7106, 0x9F5E, 0x7107,
+	0x9F5F, 0x7108, 0x9F60, 0x710B, 0x9F61, 0x710C, 0x9F62, 0x710D,
+	0x9F63, 0x710E, 0x9F64, 0x710F, 0x9F65, 0x7111, 0x9F66, 0x7112,
+	0x9F67, 0x7114, 0x9F68, 0x7117, 0x9F69, 0x711B, 0x9F6A, 0x711C,
+	0x9F6B, 0x711D, 0x9F6C, 0x711E, 0x9F6D, 0x711F, 0x9F6E, 0x7120,
+	0x9F6F, 0x7121, 0x9F70, 0x7122, 0x9F71, 0x7123, 0x9F72, 0x7124,
+	0x9F73, 0x7125, 0x9F74, 0x7127, 0x9F75, 0x7128, 0x9F76, 0x7129,
+	0x9F77, 0x712A, 0x9F78, 0x712B, 0x9F79, 0x712C, 0x9F7A, 0x712D,
+	0x9F7B, 0x712E, 0x9F7C, 0x7132, 0x9F7D, 0x7133, 0x9F7E, 0x7134,
+	0x9F80, 0x7135, 0x9F81, 0x7137, 0x9F82, 0x7138, 0x9F83, 0x7139,
+	0x9F84, 0x713A, 0x9F85, 0x713B, 0x9F86, 0x713C, 0x9F87, 0x713D,
+	0x9F88, 0x713E, 0x9F89, 0x713F, 0x9F8A, 0x7140, 0x9F8B, 0x7141,
+	0x9F8C, 0x7142, 0x9F8D, 0x7143, 0x9F8E, 0x7144, 0x9F8F, 0x7146,
+	0x9F90, 0x7147, 0x9F91, 0x7148, 0x9F92, 0x7149, 0x9F93, 0x714B,
+	0x9F94, 0x714D, 0x9F95, 0x714F, 0x9F96, 0x7150, 0x9F97, 0x7151,
+	0x9F98, 0x7152, 0x9F99, 0x7153, 0x9F9A, 0x7154, 0x9F9B, 0x7155,
+	0x9F9C, 0x7156, 0x9F9D, 0x7157, 0x9F9E, 0x7158, 0x9F9F, 0x7159,
+	0x9FA0, 0x715A, 0x9FA1, 0x715B, 0x9FA2, 0x715D, 0x9FA3, 0x715F,
+	0x9FA4, 0x7160, 0x9FA5, 0x7161, 0x9FA6, 0x7162, 0x9FA7, 0x7163,
+	0x9FA8, 0x7165, 0x9FA9, 0x7169, 0x9FAA, 0x716A, 0x9FAB, 0x716B,
+	0x9FAC, 0x716C, 0x9FAD, 0x716D, 0x9FAE, 0x716F, 0x9FAF, 0x7170,
+	0x9FB0, 0x7171, 0x9FB1, 0x7174, 0x9FB2, 0x7175, 0x9FB3, 0x7176,
+	0x9FB4, 0x7177, 0x9FB5, 0x7179, 0x9FB6, 0x717B, 0x9FB7, 0x717C,
+	0x9FB8, 0x717E, 0x9FB9, 0x717F, 0x9FBA, 0x7180, 0x9FBB, 0x7181,
+	0x9FBC, 0x7182, 0x9FBD, 0x7183, 0x9FBE, 0x7185, 0x9FBF, 0x7186,
+	0x9FC0, 0x7187, 0x9FC1, 0x7188, 0x9FC2, 0x7189, 0x9FC3, 0x718B,
+	0x9FC4, 0x718C, 0x9FC5, 0x718D, 0x9FC6, 0x718E, 0x9FC7, 0x7190,
+	0x9FC8, 0x7191, 0x9FC9, 0x7192, 0x9FCA, 0x7193, 0x9FCB, 0x7195,
+	0x9FCC, 0x7196, 0x9FCD, 0x7197, 0x9FCE, 0x719A, 0x9FCF, 0x719B,
+	0x9FD0, 0x719C, 0x9FD1, 0x719D, 0x9FD2, 0x719E, 0x9FD3, 0x71A1,
+	0x9FD4, 0x71A2, 0x9FD5, 0x71A3, 0x9FD6, 0x71A4, 0x9FD7, 0x71A5,
+	0x9FD8, 0x71A6, 0x9FD9, 0x71A7, 0x9FDA, 0x71A9, 0x9FDB, 0x71AA,
+	0x9FDC, 0x71AB, 0x9FDD, 0x71AD, 0x9FDE, 0x71AE, 0x9FDF, 0x71AF,
+	0x9FE0, 0x71B0, 0x9FE1, 0x71B1, 0x9FE2, 0x71B2, 0x9FE3, 0x71B4,
+	0x9FE4, 0x71B6, 0x9FE5, 0x71B7, 0x9FE6, 0x71B8, 0x9FE7, 0x71BA,
+	0x9FE8, 0x71BB, 0x9FE9, 0x71BC, 0x9FEA, 0x71BD, 0x9FEB, 0x71BE,
+	0x9FEC, 0x71BF, 0x9FED, 0x71C0, 0x9FEE, 0x71C1, 0x9FEF, 0x71C2,
+	0x9FF0, 0x71C4, 0x9FF1, 0x71C5, 0x9FF2, 0x71C6, 0x9FF3, 0x71C7,
+	0x9FF4, 0x71C8, 0x9FF5, 0x71C9, 0x9FF6, 0x71CA, 0x9FF7, 0x71CB,
+	0x9FF8, 0x71CC, 0x9FF9, 0x71CD, 0x9FFA, 0x71CF, 0x9FFB, 0x71D0,
+	0x9FFC, 0x71D1, 0x9FFD, 0x71D2, 0x9FFE, 0x71D3, 0xA040, 0x71D6,
+	0xA041, 0x71D7, 0xA042, 0x71D8, 0xA043, 0x71D9, 0xA044, 0x71DA,
+	0xA045, 0x71DB, 0xA046, 0x71DC, 0xA047, 0x71DD, 0xA048, 0x71DE,
+	0xA049, 0x71DF, 0xA04A, 0x71E1, 0xA04B, 0x71E2, 0xA04C, 0x71E3,
+	0xA04D, 0x71E4, 0xA04E, 0x71E6, 0xA04F, 0x71E8, 0xA050, 0x71E9,
+	0xA051, 0x71EA, 0xA052, 0x71EB, 0xA053, 0x71EC, 0xA054, 0x71ED,
+	0xA055, 0x71EF, 0xA056, 0x71F0, 0xA057, 0x71F1, 0xA058, 0x71F2,
+	0xA059, 0x71F3, 0xA05A, 0x71F4, 0xA05B, 0x71F5, 0xA05C, 0x71F6,
+	0xA05D, 0x71F7, 0xA05E, 0x71F8, 0xA05F, 0x71FA, 0xA060, 0x71FB,
+	0xA061, 0x71FC, 0xA062, 0x71FD, 0xA063, 0x71FE, 0xA064, 0x71FF,
+	0xA065, 0x7200, 0xA066, 0x7201, 0xA067, 0x7202, 0xA068, 0x7203,
+	0xA069, 0x7204, 0xA06A, 0x7205, 0xA06B, 0x7207, 0xA06C, 0x7208,
+	0xA06D, 0x7209, 0xA06E, 0x720A, 0xA06F, 0x720B, 0xA070, 0x720C,
+	0xA071, 0x720D, 0xA072, 0x720E, 0xA073, 0x720F, 0xA074, 0x7210,
+	0xA075, 0x7211, 0xA076, 0x7212, 0xA077, 0x7213, 0xA078, 0x7214,
+	0xA079, 0x7215, 0xA07A, 0x7216, 0xA07B, 0x7217, 0xA07C, 0x7218,
+	0xA07D, 0x7219, 0xA07E, 0x721A, 0xA080, 0x721B, 0xA081, 0x721C,
+	0xA082, 0x721E, 0xA083, 0x721F, 0xA084, 0x7220, 0xA085, 0x7221,
+	0xA086, 0x7222, 0xA087, 0x7223, 0xA088, 0x7224, 0xA089, 0x7225,
+	0xA08A, 0x7226, 0xA08B, 0x7227, 0xA08C, 0x7229, 0xA08D, 0x722B,
+	0xA08E, 0x722D, 0xA08F, 0x722E, 0xA090, 0x722F, 0xA091, 0x7232,
+	0xA092, 0x7233, 0xA093, 0x7234, 0xA094, 0x723A, 0xA095, 0x723C,
+	0xA096, 0x723E, 0xA097, 0x7240, 0xA098, 0x7241, 0xA099, 0x7242,
+	0xA09A, 0x7243, 0xA09B, 0x7244, 0xA09C, 0x7245, 0xA09D, 0x7246,
+	0xA09E, 0x7249, 0xA09F, 0x724A, 0xA0A0, 0x724B, 0xA0A1, 0x724E,
+	0xA0A2, 0x724F, 0xA0A3, 0x7250, 0xA0A4, 0x7251, 0xA0A5, 0x7253,
+	0xA0A6, 0x7254, 0xA0A7, 0x7255, 0xA0A8, 0x7257, 0xA0A9, 0x7258,
+	0xA0AA, 0x725A, 0xA0AB, 0x725C, 0xA0AC, 0x725E, 0xA0AD, 0x7260,
+	0xA0AE, 0x7263, 0xA0AF, 0x7264, 0xA0B0, 0x7265, 0xA0B1, 0x7268,
+	0xA0B2, 0x726A, 0xA0B3, 0x726B, 0xA0B4, 0x726C, 0xA0B5, 0x726D,
+	0xA0B6, 0x7270, 0xA0B7, 0x7271, 0xA0B8, 0x7273, 0xA0B9, 0x7274,
+	0xA0BA, 0x7276, 0xA0BB, 0x7277, 0xA0BC, 0x7278, 0xA0BD, 0x727B,
+	0xA0BE, 0x727C, 0xA0BF, 0x727D, 0xA0C0, 0x7282, 0xA0C1, 0x7283,
+	0xA0C2, 0x7285, 0xA0C3, 0x7286, 0xA0C4, 0x7287, 0xA0C5, 0x7288,
+	0xA0C6, 0x7289, 0xA0C7, 0x728C, 0xA0C8, 0x728E, 0xA0C9, 0x7290,
+	0xA0CA, 0x7291, 0xA0CB, 0x7293, 0xA0CC, 0x7294, 0xA0CD, 0x7295,
+	0xA0CE, 0x7296, 0xA0CF, 0x7297, 0xA0D0, 0x7298, 0xA0D1, 0x7299,
+	0xA0D2, 0x729A, 0xA0D3, 0x729B, 0xA0D4, 0x729C, 0xA0D5, 0x729D,
+	0xA0D6, 0x729E, 0xA0D7, 0x72A0, 0xA0D8, 0x72A1, 0xA0D9, 0x72A2,
+	0xA0DA, 0x72A3, 0xA0DB, 0x72A4, 0xA0DC, 0x72A5, 0xA0DD, 0x72A6,
+	0xA0DE, 0x72A7, 0xA0DF, 0x72A8, 0xA0E0, 0x72A9, 0xA0E1, 0x72AA,
+	0xA0E2, 0x72AB, 0xA0E3, 0x72AE, 0xA0E4, 0x72B1, 0xA0E5, 0x72B2,
+	0xA0E6, 0x72B3, 0xA0E7, 0x72B5, 0xA0E8, 0x72BA, 0xA0E9, 0x72BB,
+	0xA0EA, 0x72BC, 0xA0EB, 0x72BD, 0xA0EC, 0x72BE, 0xA0ED, 0x72BF,
+	0xA0EE, 0x72C0, 0xA0EF, 0x72C5, 0xA0F0, 0x72C6, 0xA0F1, 0x72C7,
+	0xA0F2, 0x72C9, 0xA0F3, 0x72CA, 0xA0F4, 0x72CB, 0xA0F5, 0x72CC,
+	0xA0F6, 0x72CF, 0xA0F7, 0x72D1, 0xA0F8, 0x72D3, 0xA0F9, 0x72D4,
+	0xA0FA, 0x72D5, 0xA0FB, 0x72D6, 0xA0FC, 0x72D8, 0xA0FD, 0x72DA,
+	0xA0FE, 0x72DB, 0xA1A1, 0x3000, 0xA1A2, 0x3001, 0xA1A3, 0x3002,
+	0xA1A4, 0x00B7, 0xA1A5, 0x02C9, 0xA1A6, 0x02C7, 0xA1A7, 0x00A8,
+	0xA1A8, 0x3003, 0xA1A9, 0x3005, 0xA1AA, 0x2014, 0xA1AB, 0xFF5E,
+	0xA1AC, 0x2016, 0xA1AD, 0x2026, 0xA1AE, 0x2018, 0xA1AF, 0x2019,
+	0xA1B0, 0x201C, 0xA1B1, 0x201D, 0xA1B2, 0x3014, 0xA1B3, 0x3015,
+	0xA1B4, 0x3008, 0xA1B5, 0x3009, 0xA1B6, 0x300A, 0xA1B7, 0x300B,
+	0xA1B8, 0x300C, 0xA1B9, 0x300D, 0xA1BA, 0x300E, 0xA1BB, 0x300F,
+	0xA1BC, 0x3016, 0xA1BD, 0x3017, 0xA1BE, 0x3010, 0xA1BF, 0x3011,
+	0xA1C0, 0x00B1, 0xA1C1, 0x00D7, 0xA1C2, 0x00F7, 0xA1C3, 0x2236,
+	0xA1C4, 0x2227, 0xA1C5, 0x2228, 0xA1C6, 0x2211, 0xA1C7, 0x220F,
+	0xA1C8, 0x222A, 0xA1C9, 0x2229, 0xA1CA, 0x2208, 0xA1CB, 0x2237,
+	0xA1CC, 0x221A, 0xA1CD, 0x22A5, 0xA1CE, 0x2225, 0xA1CF, 0x2220,
+	0xA1D0, 0x2312, 0xA1D1, 0x2299, 0xA1D2, 0x222B, 0xA1D3, 0x222E,
+	0xA1D4, 0x2261, 0xA1D5, 0x224C, 0xA1D6, 0x2248, 0xA1D7, 0x223D,
+	0xA1D8, 0x221D, 0xA1D9, 0x2260, 0xA1DA, 0x226E, 0xA1DB, 0x226F,
+	0xA1DC, 0x2264, 0xA1DD, 0x2265, 0xA1DE, 0x221E, 0xA1DF, 0x2235,
+	0xA1E0, 0x2234, 0xA1E1, 0x2642, 0xA1E2, 0x2640, 0xA1E3, 0x00B0,
+	0xA1E4, 0x2032, 0xA1E5, 0x2033, 0xA1E6, 0x2103, 0xA1E7, 0xFF04,
+	0xA1E8, 0x00A4, 0xA1E9, 0xFFE0, 0xA1EA, 0xFFE1, 0xA1EB, 0x2030,
+	0xA1EC, 0x00A7, 0xA1ED, 0x2116, 0xA1EE, 0x2606, 0xA1EF, 0x2605,
+	0xA1F0, 0x25CB, 0xA1F1, 0x25CF, 0xA1F2, 0x25CE, 0xA1F3, 0x25C7,
+	0xA1F4, 0x25C6, 0xA1F5, 0x25A1, 0xA1F6, 0x25A0, 0xA1F7, 0x25B3,
+	0xA1F8, 0x25B2, 0xA1F9, 0x203B, 0xA1FA, 0x2192, 0xA1FB, 0x2190,
+	0xA1FC, 0x2191, 0xA1FD, 0x2193, 0xA1FE, 0x3013, 0xA2A1, 0x2170,
+	0xA2A2, 0x2171, 0xA2A3, 0x2172, 0xA2A4, 0x2173, 0xA2A5, 0x2174,
+	0xA2A6, 0x2175, 0xA2A7, 0x2176, 0xA2A8, 0x2177, 0xA2A9, 0x2178,
+	0xA2AA, 0x2179, 0xA2B1, 0x2488, 0xA2B2, 0x2489, 0xA2B3, 0x248A,
+	0xA2B4, 0x248B, 0xA2B5, 0x248C, 0xA2B6, 0x248D, 0xA2B7, 0x248E,
+	0xA2B8, 0x248F, 0xA2B9, 0x2490, 0xA2BA, 0x2491, 0xA2BB, 0x2492,
+	0xA2BC, 0x2493, 0xA2BD, 0x2494, 0xA2BE, 0x2495, 0xA2BF, 0x2496,
+	0xA2C0, 0x2497, 0xA2C1, 0x2498, 0xA2C2, 0x2499, 0xA2C3, 0x249A,
+	0xA2C4, 0x249B, 0xA2C5, 0x2474, 0xA2C6, 0x2475, 0xA2C7, 0x2476,
+	0xA2C8, 0x2477, 0xA2C9, 0x2478, 0xA2CA, 0x2479, 0xA2CB, 0x247A,
+	0xA2CC, 0x247B, 0xA2CD, 0x247C, 0xA2CE, 0x247D, 0xA2CF, 0x247E,
+	0xA2D0, 0x247F, 0xA2D1, 0x2480, 0xA2D2, 0x2481, 0xA2D3, 0x2482,
+	0xA2D4, 0x2483, 0xA2D5, 0x2484, 0xA2D6, 0x2485, 0xA2D7, 0x2486,
+	0xA2D8, 0x2487, 0xA2D9, 0x2460, 0xA2DA, 0x2461, 0xA2DB, 0x2462,
+	0xA2DC, 0x2463, 0xA2DD, 0x2464, 0xA2DE, 0x2465, 0xA2DF, 0x2466,
+	0xA2E0, 0x2467, 0xA2E1, 0x2468, 0xA2E2, 0x2469, 0xA2E5, 0x3220,
+	0xA2E6, 0x3221, 0xA2E7, 0x3222, 0xA2E8, 0x3223, 0xA2E9, 0x3224,
+	0xA2EA, 0x3225, 0xA2EB, 0x3226, 0xA2EC, 0x3227, 0xA2ED, 0x3228,
+	0xA2EE, 0x3229, 0xA2F1, 0x2160, 0xA2F2, 0x2161, 0xA2F3, 0x2162,
+	0xA2F4, 0x2163, 0xA2F5, 0x2164, 0xA2F6, 0x2165, 0xA2F7, 0x2166,
+	0xA2F8, 0x2167, 0xA2F9, 0x2168, 0xA2FA, 0x2169, 0xA2FB, 0x216A,
+	0xA2FC, 0x216B, 0xA3A1, 0xFF01, 0xA3A2, 0xFF02, 0xA3A3, 0xFF03,
+	0xA3A4, 0xFFE5, 0xA3A5, 0xFF05, 0xA3A6, 0xFF06, 0xA3A7, 0xFF07,
+	0xA3A8, 0xFF08, 0xA3A9, 0xFF09, 0xA3AA, 0xFF0A, 0xA3AB, 0xFF0B,
+	0xA3AC, 0xFF0C, 0xA3AD, 0xFF0D, 0xA3AE, 0xFF0E, 0xA3AF, 0xFF0F,
+	0xA3B0, 0xFF10, 0xA3B1, 0xFF11, 0xA3B2, 0xFF12, 0xA3B3, 0xFF13,
+	0xA3B4, 0xFF14, 0xA3B5, 0xFF15, 0xA3B6, 0xFF16, 0xA3B7, 0xFF17,
+	0xA3B8, 0xFF18, 0xA3B9, 0xFF19, 0xA3BA, 0xFF1A, 0xA3BB, 0xFF1B,
+	0xA3BC, 0xFF1C, 0xA3BD, 0xFF1D, 0xA3BE, 0xFF1E, 0xA3BF, 0xFF1F,
+	0xA3C0, 0xFF20, 0xA3C1, 0xFF21, 0xA3C2, 0xFF22, 0xA3C3, 0xFF23,
+	0xA3C4, 0xFF24, 0xA3C5, 0xFF25, 0xA3C6, 0xFF26, 0xA3C7, 0xFF27,
+	0xA3C8, 0xFF28, 0xA3C9, 0xFF29, 0xA3CA, 0xFF2A, 0xA3CB, 0xFF2B,
+	0xA3CC, 0xFF2C, 0xA3CD, 0xFF2D, 0xA3CE, 0xFF2E, 0xA3CF, 0xFF2F,
+	0xA3D0, 0xFF30, 0xA3D1, 0xFF31, 0xA3D2, 0xFF32, 0xA3D3, 0xFF33,
+	0xA3D4, 0xFF34, 0xA3D5, 0xFF35, 0xA3D6, 0xFF36, 0xA3D7, 0xFF37,
+	0xA3D8, 0xFF38, 0xA3D9, 0xFF39, 0xA3DA, 0xFF3A, 0xA3DB, 0xFF3B,
+	0xA3DC, 0xFF3C, 0xA3DD, 0xFF3D, 0xA3DE, 0xFF3E, 0xA3DF, 0xFF3F,
+	0xA3E0, 0xFF40, 0xA3E1, 0xFF41, 0xA3E2, 0xFF42, 0xA3E3, 0xFF43,
+	0xA3E4, 0xFF44, 0xA3E5, 0xFF45, 0xA3E6, 0xFF46, 0xA3E7, 0xFF47,
+	0xA3E8, 0xFF48, 0xA3E9, 0xFF49, 0xA3EA, 0xFF4A, 0xA3EB, 0xFF4B,
+	0xA3EC, 0xFF4C, 0xA3ED, 0xFF4D, 0xA3EE, 0xFF4E, 0xA3EF, 0xFF4F,
+	0xA3F0, 0xFF50, 0xA3F1, 0xFF51, 0xA3F2, 0xFF52, 0xA3F3, 0xFF53,
+	0xA3F4, 0xFF54, 0xA3F5, 0xFF55, 0xA3F6, 0xFF56, 0xA3F7, 0xFF57,
+	0xA3F8, 0xFF58, 0xA3F9, 0xFF59, 0xA3FA, 0xFF5A, 0xA3FB, 0xFF5B,
+	0xA3FC, 0xFF5C, 0xA3FD, 0xFF5D, 0xA3FE, 0xFFE3, 0xA4A1, 0x3041,
+	0xA4A2, 0x3042, 0xA4A3, 0x3043, 0xA4A4, 0x3044, 0xA4A5, 0x3045,
+	0xA4A6, 0x3046, 0xA4A7, 0x3047, 0xA4A8, 0x3048, 0xA4A9, 0x3049,
+	0xA4AA, 0x304A, 0xA4AB, 0x304B, 0xA4AC, 0x304C, 0xA4AD, 0x304D,
+	0xA4AE, 0x304E, 0xA4AF, 0x304F, 0xA4B0, 0x3050, 0xA4B1, 0x3051,
+	0xA4B2, 0x3052, 0xA4B3, 0x3053, 0xA4B4, 0x3054, 0xA4B5, 0x3055,
+	0xA4B6, 0x3056, 0xA4B7, 0x3057, 0xA4B8, 0x3058, 0xA4B9, 0x3059,
+	0xA4BA, 0x305A, 0xA4BB, 0x305B, 0xA4BC, 0x305C, 0xA4BD, 0x305D,
+	0xA4BE, 0x305E, 0xA4BF, 0x305F, 0xA4C0, 0x3060, 0xA4C1, 0x3061,
+	0xA4C2, 0x3062, 0xA4C3, 0x3063, 0xA4C4, 0x3064, 0xA4C5, 0x3065,
+	0xA4C6, 0x3066, 0xA4C7, 0x3067, 0xA4C8, 0x3068, 0xA4C9, 0x3069,
+	0xA4CA, 0x306A, 0xA4CB, 0x306B, 0xA4CC, 0x306C, 0xA4CD, 0x306D,
+	0xA4CE, 0x306E, 0xA4CF, 0x306F, 0xA4D0, 0x3070, 0xA4D1, 0x3071,
+	0xA4D2, 0x3072, 0xA4D3, 0x3073, 0xA4D4, 0x3074, 0xA4D5, 0x3075,
+	0xA4D6, 0x3076, 0xA4D7, 0x3077, 0xA4D8, 0x3078, 0xA4D9, 0x3079,
+	0xA4DA, 0x307A, 0xA4DB, 0x307B, 0xA4DC, 0x307C, 0xA4DD, 0x307D,
+	0xA4DE, 0x307E, 0xA4DF, 0x307F, 0xA4E0, 0x3080, 0xA4E1, 0x3081,
+	0xA4E2, 0x3082, 0xA4E3, 0x3083, 0xA4E4, 0x3084, 0xA4E5, 0x3085,
+	0xA4E6, 0x3086, 0xA4E7, 0x3087, 0xA4E8, 0x3088, 0xA4E9, 0x3089,
+	0xA4EA, 0x308A, 0xA4EB, 0x308B, 0xA4EC, 0x308C, 0xA4ED, 0x308D,
+	0xA4EE, 0x308E, 0xA4EF, 0x308F, 0xA4F0, 0x3090, 0xA4F1, 0x3091,
+	0xA4F2, 0x3092, 0xA4F3, 0x3093, 0xA5A1, 0x30A1, 0xA5A2, 0x30A2,
+	0xA5A3, 0x30A3, 0xA5A4, 0x30A4, 0xA5A5, 0x30A5, 0xA5A6, 0x30A6,
+	0xA5A7, 0x30A7, 0xA5A8, 0x30A8, 0xA5A9, 0x30A9, 0xA5AA, 0x30AA,
+	0xA5AB, 0x30AB, 0xA5AC, 0x30AC, 0xA5AD, 0x30AD, 0xA5AE, 0x30AE,
+	0xA5AF, 0x30AF, 0xA5B0, 0x30B0, 0xA5B1, 0x30B1, 0xA5B2, 0x30B2,
+	0xA5B3, 0x30B3, 0xA5B4, 0x30B4, 0xA5B5, 0x30B5, 0xA5B6, 0x30B6,
+	0xA5B7, 0x30B7, 0xA5B8, 0x30B8, 0xA5B9, 0x30B9, 0xA5BA, 0x30BA,
+	0xA5BB, 0x30BB, 0xA5BC, 0x30BC, 0xA5BD, 0x30BD, 0xA5BE, 0x30BE,
+	0xA5BF, 0x30BF, 0xA5C0, 0x30C0, 0xA5C1, 0x30C1, 0xA5C2, 0x30C2,
+	0xA5C3, 0x30C3, 0xA5C4, 0x30C4, 0xA5C5, 0x30C5, 0xA5C6, 0x30C6,
+	0xA5C7, 0x30C7, 0xA5C8, 0x30C8, 0xA5C9, 0x30C9, 0xA5CA, 0x30CA,
+	0xA5CB, 0x30CB, 0xA5CC, 0x30CC, 0xA5CD, 0x30CD, 0xA5CE, 0x30CE,
+	0xA5CF, 0x30CF, 0xA5D0, 0x30D0, 0xA5D1, 0x30D1, 0xA5D2, 0x30D2,
+	0xA5D3, 0x30D3, 0xA5D4, 0x30D4, 0xA5D5, 0x30D5, 0xA5D6, 0x30D6,
+	0xA5D7, 0x30D7, 0xA5D8, 0x30D8, 0xA5D9, 0x30D9, 0xA5DA, 0x30DA,
+	0xA5DB, 0x30DB, 0xA5DC, 0x30DC, 0xA5DD, 0x30DD, 0xA5DE, 0x30DE,
+	0xA5DF, 0x30DF, 0xA5E0, 0x30E0, 0xA5E1, 0x30E1, 0xA5E2, 0x30E2,
+	0xA5E3, 0x30E3, 0xA5E4, 0x30E4, 0xA5E5, 0x30E5, 0xA5E6, 0x30E6,
+	0xA5E7, 0x30E7, 0xA5E8, 0x30E8, 0xA5E9, 0x30E9, 0xA5EA, 0x30EA,
+	0xA5EB, 0x30EB, 0xA5EC, 0x30EC, 0xA5ED, 0x30ED, 0xA5EE, 0x30EE,
+	0xA5EF, 0x30EF, 0xA5F0, 0x30F0, 0xA5F1, 0x30F1, 0xA5F2, 0x30F2,
+	0xA5F3, 0x30F3, 0xA5F4, 0x30F4, 0xA5F5, 0x30F5, 0xA5F6, 0x30F6,
+	0xA6A1, 0x0391, 0xA6A2, 0x0392, 0xA6A3, 0x0393, 0xA6A4, 0x0394,
+	0xA6A5, 0x0395, 0xA6A6, 0x0396, 0xA6A7, 0x0397, 0xA6A8, 0x0398,
+	0xA6A9, 0x0399, 0xA6AA, 0x039A, 0xA6AB, 0x039B, 0xA6AC, 0x039C,
+	0xA6AD, 0x039D, 0xA6AE, 0x039E, 0xA6AF, 0x039F, 0xA6B0, 0x03A0,
+	0xA6B1, 0x03A1, 0xA6B2, 0x03A3, 0xA6B3, 0x03A4, 0xA6B4, 0x03A5,
+	0xA6B5, 0x03A6, 0xA6B6, 0x03A7, 0xA6B7, 0x03A8, 0xA6B8, 0x03A9,
+	0xA6C1, 0x03B1, 0xA6C2, 0x03B2, 0xA6C3, 0x03B3, 0xA6C4, 0x03B4,
+	0xA6C5, 0x03B5, 0xA6C6, 0x03B6, 0xA6C7, 0x03B7, 0xA6C8, 0x03B8,
+	0xA6C9, 0x03B9, 0xA6CA, 0x03BA, 0xA6CB, 0x03BB, 0xA6CC, 0x03BC,
+	0xA6CD, 0x03BD, 0xA6CE, 0x03BE, 0xA6CF, 0x03BF, 0xA6D0, 0x03C0,
+	0xA6D1, 0x03C1, 0xA6D2, 0x03C3, 0xA6D3, 0x03C4, 0xA6D4, 0x03C5,
+	0xA6D5, 0x03C6, 0xA6D6, 0x03C7, 0xA6D7, 0x03C8, 0xA6D8, 0x03C9,
+	0xA6E0, 0xFE35, 0xA6E1, 0xFE36, 0xA6E2, 0xFE39, 0xA6E3, 0xFE3A,
+	0xA6E4, 0xFE3F, 0xA6E5, 0xFE40, 0xA6E6, 0xFE3D, 0xA6E7, 0xFE3E,
+	0xA6E8, 0xFE41, 0xA6E9, 0xFE42, 0xA6EA, 0xFE43, 0xA6EB, 0xFE44,
+	0xA6EE, 0xFE3B, 0xA6EF, 0xFE3C, 0xA6F0, 0xFE37, 0xA6F1, 0xFE38,
+	0xA6F2, 0xFE31, 0xA6F4, 0xFE33, 0xA6F5, 0xFE34, 0xA7A1, 0x0410,
+	0xA7A2, 0x0411, 0xA7A3, 0x0412, 0xA7A4, 0x0413, 0xA7A5, 0x0414,
+	0xA7A6, 0x0415, 0xA7A7, 0x0401, 0xA7A8, 0x0416, 0xA7A9, 0x0417,
+	0xA7AA, 0x0418, 0xA7AB, 0x0419, 0xA7AC, 0x041A, 0xA7AD, 0x041B,
+	0xA7AE, 0x041C, 0xA7AF, 0x041D, 0xA7B0, 0x041E, 0xA7B1, 0x041F,
+	0xA7B2, 0x0420, 0xA7B3, 0x0421, 0xA7B4, 0x0422, 0xA7B5, 0x0423,
+	0xA7B6, 0x0424, 0xA7B7, 0x0425, 0xA7B8, 0x0426, 0xA7B9, 0x0427,
+	0xA7BA, 0x0428, 0xA7BB, 0x0429, 0xA7BC, 0x042A, 0xA7BD, 0x042B,
+	0xA7BE, 0x042C, 0xA7BF, 0x042D, 0xA7C0, 0x042E, 0xA7C1, 0x042F,
+	0xA7D1, 0x0430, 0xA7D2, 0x0431, 0xA7D3, 0x0432, 0xA7D4, 0x0433,
+	0xA7D5, 0x0434, 0xA7D6, 0x0435, 0xA7D7, 0x0451, 0xA7D8, 0x0436,
+	0xA7D9, 0x0437, 0xA7DA, 0x0438, 0xA7DB, 0x0439, 0xA7DC, 0x043A,
+	0xA7DD, 0x043B, 0xA7DE, 0x043C, 0xA7DF, 0x043D, 0xA7E0, 0x043E,
+	0xA7E1, 0x043F, 0xA7E2, 0x0440, 0xA7E3, 0x0441, 0xA7E4, 0x0442,
+	0xA7E5, 0x0443, 0xA7E6, 0x0444, 0xA7E7, 0x0445, 0xA7E8, 0x0446,
+	0xA7E9, 0x0447, 0xA7EA, 0x0448, 0xA7EB, 0x0449, 0xA7EC, 0x044A,
+	0xA7ED, 0x044B, 0xA7EE, 0x044C, 0xA7EF, 0x044D, 0xA7F0, 0x044E,
+	0xA7F1, 0x044F, 0xA840, 0x02CA, 0xA841, 0x02CB, 0xA842, 0x02D9,
+	0xA843, 0x2013, 0xA844, 0x2015, 0xA845, 0x2025, 0xA846, 0x2035,
+	0xA847, 0x2105, 0xA848, 0x2109, 0xA849, 0x2196, 0xA84A, 0x2197,
+	0xA84B, 0x2198, 0xA84C, 0x2199, 0xA84D, 0x2215, 0xA84E, 0x221F,
+	0xA84F, 0x2223, 0xA850, 0x2252, 0xA851, 0x2266, 0xA852, 0x2267,
+	0xA853, 0x22BF, 0xA854, 0x2550, 0xA855, 0x2551, 0xA856, 0x2552,
+	0xA857, 0x2553, 0xA858, 0x2554, 0xA859, 0x2555, 0xA85A, 0x2556,
+	0xA85B, 0x2557, 0xA85C, 0x2558, 0xA85D, 0x2559, 0xA85E, 0x255A,
+	0xA85F, 0x255B, 0xA860, 0x255C, 0xA861, 0x255D, 0xA862, 0x255E,
+	0xA863, 0x255F, 0xA864, 0x2560, 0xA865, 0x2561, 0xA866, 0x2562,
+	0xA867, 0x2563, 0xA868, 0x2564, 0xA869, 0x2565, 0xA86A, 0x2566,
+	0xA86B, 0x2567, 0xA86C, 0x2568, 0xA86D, 0x2569, 0xA86E, 0x256A,
+	0xA86F, 0x256B, 0xA870, 0x256C, 0xA871, 0x256D, 0xA872, 0x256E,
+	0xA873, 0x256F, 0xA874, 0x2570, 0xA875, 0x2571, 0xA876, 0x2572,
+	0xA877, 0x2573, 0xA878, 0x2581, 0xA879, 0x2582, 0xA87A, 0x2583,
+	0xA87B, 0x2584, 0xA87C, 0x2585, 0xA87D, 0x2586, 0xA87E, 0x2587,
+	0xA880, 0x2588, 0xA881, 0x2589, 0xA882, 0x258A, 0xA883, 0x258B,
+	0xA884, 0x258C, 0xA885, 0x258D, 0xA886, 0x258E, 0xA887, 0x258F,
+	0xA888, 0x2593, 0xA889, 0x2594, 0xA88A, 0x2595, 0xA88B, 0x25BC,
+	0xA88C, 0x25BD, 0xA88D, 0x25E2, 0xA88E, 0x25E3, 0xA88F, 0x25E4,
+	0xA890, 0x25E5, 0xA891, 0x2609, 0xA892, 0x2295, 0xA893, 0x3012,
+	0xA894, 0x301D, 0xA895, 0x301E, 0xA8A1, 0x0101, 0xA8A2, 0x00E1,
+	0xA8A3, 0x01CE, 0xA8A4, 0x00E0, 0xA8A5, 0x0113, 0xA8A6, 0x00E9,
+	0xA8A7, 0x011B, 0xA8A8, 0x00E8, 0xA8A9, 0x012B, 0xA8AA, 0x00ED,
+	0xA8AB, 0x01D0, 0xA8AC, 0x00EC, 0xA8AD, 0x014D, 0xA8AE, 0x00F3,
+	0xA8AF, 0x01D2, 0xA8B0, 0x00F2, 0xA8B1, 0x016B, 0xA8B2, 0x00FA,
+	0xA8B3, 0x01D4, 0xA8B4, 0x00F9, 0xA8B5, 0x01D6, 0xA8B6, 0x01D8,
+	0xA8B7, 0x01DA, 0xA8B8, 0x01DC, 0xA8B9, 0x00FC, 0xA8BA, 0x00EA,
+	0xA8BB, 0x0251, 0xA8BD, 0x0144, 0xA8BE, 0x0148, 0xA8C0, 0x0261,
+	0xA8C5, 0x3105, 0xA8C6, 0x3106, 0xA8C7, 0x3107, 0xA8C8, 0x3108,
+	0xA8C9, 0x3109, 0xA8CA, 0x310A, 0xA8CB, 0x310B, 0xA8CC, 0x310C,
+	0xA8CD, 0x310D, 0xA8CE, 0x310E, 0xA8CF, 0x310F, 0xA8D0, 0x3110,
+	0xA8D1, 0x3111, 0xA8D2, 0x3112, 0xA8D3, 0x3113, 0xA8D4, 0x3114,
+	0xA8D5, 0x3115, 0xA8D6, 0x3116, 0xA8D7, 0x3117, 0xA8D8, 0x3118,
+	0xA8D9, 0x3119, 0xA8DA, 0x311A, 0xA8DB, 0x311B, 0xA8DC, 0x311C,
+	0xA8DD, 0x311D, 0xA8DE, 0x311E, 0xA8DF, 0x311F, 0xA8E0, 0x3120,
+	0xA8E1, 0x3121, 0xA8E2, 0x3122, 0xA8E3, 0x3123, 0xA8E4, 0x3124,
+	0xA8E5, 0x3125, 0xA8E6, 0x3126, 0xA8E7, 0x3127, 0xA8E8, 0x3128,
+	0xA8E9, 0x3129, 0xA940, 0x3021, 0xA941, 0x3022, 0xA942, 0x3023,
+	0xA943, 0x3024, 0xA944, 0x3025, 0xA945, 0x3026, 0xA946, 0x3027,
+	0xA947, 0x3028, 0xA948, 0x3029, 0xA949, 0x32A3, 0xA94A, 0x338E,
+	0xA94B, 0x338F, 0xA94C, 0x339C, 0xA94D, 0x339D, 0xA94E, 0x339E,
+	0xA94F, 0x33A1, 0xA950, 0x33C4, 0xA951, 0x33CE, 0xA952, 0x33D1,
+	0xA953, 0x33D2, 0xA954, 0x33D5, 0xA955, 0xFE30, 0xA956, 0xFFE2,
+	0xA957, 0xFFE4, 0xA959, 0x2121, 0xA95A, 0x3231, 0xA95C, 0x2010,
+	0xA960, 0x30FC, 0xA961, 0x309B, 0xA962, 0x309C, 0xA963, 0x30FD,
+	0xA964, 0x30FE, 0xA965, 0x3006, 0xA966, 0x309D, 0xA967, 0x309E,
+	0xA968, 0xFE49, 0xA969, 0xFE4A, 0xA96A, 0xFE4B, 0xA96B, 0xFE4C,
+	0xA96C, 0xFE4D, 0xA96D, 0xFE4E, 0xA96E, 0xFE4F, 0xA96F, 0xFE50,
+	0xA970, 0xFE51, 0xA971, 0xFE52, 0xA972, 0xFE54, 0xA973, 0xFE55,
+	0xA974, 0xFE56, 0xA975, 0xFE57, 0xA976, 0xFE59, 0xA977, 0xFE5A,
+	0xA978, 0xFE5B, 0xA979, 0xFE5C, 0xA97A, 0xFE5D, 0xA97B, 0xFE5E,
+	0xA97C, 0xFE5F, 0xA97D, 0xFE60, 0xA97E, 0xFE61, 0xA980, 0xFE62,
+	0xA981, 0xFE63, 0xA982, 0xFE64, 0xA983, 0xFE65, 0xA984, 0xFE66,
+	0xA985, 0xFE68, 0xA986, 0xFE69, 0xA987, 0xFE6A, 0xA988, 0xFE6B,
+	0xA996, 0x3007, 0xA9A4, 0x2500, 0xA9A5, 0x2501, 0xA9A6, 0x2502,
+	0xA9A7, 0x2503, 0xA9A8, 0x2504, 0xA9A9, 0x2505, 0xA9AA, 0x2506,
+	0xA9AB, 0x2507, 0xA9AC, 0x2508, 0xA9AD, 0x2509, 0xA9AE, 0x250A,
+	0xA9AF, 0x250B, 0xA9B0, 0x250C, 0xA9B1, 0x250D, 0xA9B2, 0x250E,
+	0xA9B3, 0x250F, 0xA9B4, 0x2510, 0xA9B5, 0x2511, 0xA9B6, 0x2512,
+	0xA9B7, 0x2513, 0xA9B8, 0x2514, 0xA9B9, 0x2515, 0xA9BA, 0x2516,
+	0xA9BB, 0x2517, 0xA9BC, 0x2518, 0xA9BD, 0x2519, 0xA9BE, 0x251A,
+	0xA9BF, 0x251B, 0xA9C0, 0x251C, 0xA9C1, 0x251D, 0xA9C2, 0x251E,
+	0xA9C3, 0x251F, 0xA9C4, 0x2520, 0xA9C5, 0x2521, 0xA9C6, 0x2522,
+	0xA9C7, 0x2523, 0xA9C8, 0x2524, 0xA9C9, 0x2525, 0xA9CA, 0x2526,
+	0xA9CB, 0x2527, 0xA9CC, 0x2528, 0xA9CD, 0x2529, 0xA9CE, 0x252A,
+	0xA9CF, 0x252B, 0xA9D0, 0x252C, 0xA9D1, 0x252D, 0xA9D2, 0x252E,
+	0xA9D3, 0x252F, 0xA9D4, 0x2530, 0xA9D5, 0x2531, 0xA9D6, 0x2532,
+	0xA9D7, 0x2533, 0xA9D8, 0x2534, 0xA9D9, 0x2535, 0xA9DA, 0x2536,
+	0xA9DB, 0x2537, 0xA9DC, 0x2538, 0xA9DD, 0x2539, 0xA9DE, 0x253A,
+	0xA9DF, 0x253B, 0xA9E0, 0x253C, 0xA9E1, 0x253D, 0xA9E2, 0x253E,
+	0xA9E3, 0x253F, 0xA9E4, 0x2540, 0xA9E5, 0x2541, 0xA9E6, 0x2542,
+	0xA9E7, 0x2543, 0xA9E8, 0x2544, 0xA9E9, 0x2545, 0xA9EA, 0x2546,
+	0xA9EB, 0x2547, 0xA9EC, 0x2548, 0xA9ED, 0x2549, 0xA9EE, 0x254A,
+	0xA9EF, 0x254B, 0xAA40, 0x72DC, 0xAA41, 0x72DD, 0xAA42, 0x72DF,
+	0xAA43, 0x72E2, 0xAA44, 0x72E3, 0xAA45, 0x72E4, 0xAA46, 0x72E5,
+	0xAA47, 0x72E6, 0xAA48, 0x72E7, 0xAA49, 0x72EA, 0xAA4A, 0x72EB,
+	0xAA4B, 0x72F5, 0xAA4C, 0x72F6, 0xAA4D, 0x72F9, 0xAA4E, 0x72FD,
+	0xAA4F, 0x72FE, 0xAA50, 0x72FF, 0xAA51, 0x7300, 0xAA52, 0x7302,
+	0xAA53, 0x7304, 0xAA54, 0x7305, 0xAA55, 0x7306, 0xAA56, 0x7307,
+	0xAA57, 0x7308, 0xAA58, 0x7309, 0xAA59, 0x730B, 0xAA5A, 0x730C,
+	0xAA5B, 0x730D, 0xAA5C, 0x730F, 0xAA5D, 0x7310, 0xAA5E, 0x7311,
+	0xAA5F, 0x7312, 0xAA60, 0x7314, 0xAA61, 0x7318, 0xAA62, 0x7319,
+	0xAA63, 0x731A, 0xAA64, 0x731F, 0xAA65, 0x7320, 0xAA66, 0x7323,
+	0xAA67, 0x7324, 0xAA68, 0x7326, 0xAA69, 0x7327, 0xAA6A, 0x7328,
+	0xAA6B, 0x732D, 0xAA6C, 0x732F, 0xAA6D, 0x7330, 0xAA6E, 0x7332,
+	0xAA6F, 0x7333, 0xAA70, 0x7335, 0xAA71, 0x7336, 0xAA72, 0x733A,
+	0xAA73, 0x733B, 0xAA74, 0x733C, 0xAA75, 0x733D, 0xAA76, 0x7340,
+	0xAA77, 0x7341, 0xAA78, 0x7342, 0xAA79, 0x7343, 0xAA7A, 0x7344,
+	0xAA7B, 0x7345, 0xAA7C, 0x7346, 0xAA7D, 0x7347, 0xAA7E, 0x7348,
+	0xAA80, 0x7349, 0xAA81, 0x734A, 0xAA82, 0x734B, 0xAA83, 0x734C,
+	0xAA84, 0x734E, 0xAA85, 0x734F, 0xAA86, 0x7351, 0xAA87, 0x7353,
+	0xAA88, 0x7354, 0xAA89, 0x7355, 0xAA8A, 0x7356, 0xAA8B, 0x7358,
+	0xAA8C, 0x7359, 0xAA8D, 0x735A, 0xAA8E, 0x735B, 0xAA8F, 0x735C,
+	0xAA90, 0x735D, 0xAA91, 0x735E, 0xAA92, 0x735F, 0xAA93, 0x7361,
+	0xAA94, 0x7362, 0xAA95, 0x7363, 0xAA96, 0x7364, 0xAA97, 0x7365,
+	0xAA98, 0x7366, 0xAA99, 0x7367, 0xAA9A, 0x7368, 0xAA9B, 0x7369,
+	0xAA9C, 0x736A, 0xAA9D, 0x736B, 0xAA9E, 0x736E, 0xAA9F, 0x7370,
+	0xAAA0, 0x7371, 0xAB40, 0x7372, 0xAB41, 0x7373, 0xAB42, 0x7374,
+	0xAB43, 0x7375, 0xAB44, 0x7376, 0xAB45, 0x7377, 0xAB46, 0x7378,
+	0xAB47, 0x7379, 0xAB48, 0x737A, 0xAB49, 0x737B, 0xAB4A, 0x737C,
+	0xAB4B, 0x737D, 0xAB4C, 0x737F, 0xAB4D, 0x7380, 0xAB4E, 0x7381,
+	0xAB4F, 0x7382, 0xAB50, 0x7383, 0xAB51, 0x7385, 0xAB52, 0x7386,
+	0xAB53, 0x7388, 0xAB54, 0x738A, 0xAB55, 0x738C, 0xAB56, 0x738D,
+	0xAB57, 0x738F, 0xAB58, 0x7390, 0xAB59, 0x7392, 0xAB5A, 0x7393,
+	0xAB5B, 0x7394, 0xAB5C, 0x7395, 0xAB5D, 0x7397, 0xAB5E, 0x7398,
+	0xAB5F, 0x7399, 0xAB60, 0x739A, 0xAB61, 0x739C, 0xAB62, 0x739D,
+	0xAB63, 0x739E, 0xAB64, 0x73A0, 0xAB65, 0x73A1, 0xAB66, 0x73A3,
+	0xAB67, 0x73A4, 0xAB68, 0x73A5, 0xAB69, 0x73A6, 0xAB6A, 0x73A7,
+	0xAB6B, 0x73A8, 0xAB6C, 0x73AA, 0xAB6D, 0x73AC, 0xAB6E, 0x73AD,
+	0xAB6F, 0x73B1, 0xAB70, 0x73B4, 0xAB71, 0x73B5, 0xAB72, 0x73B6,
+	0xAB73, 0x73B8, 0xAB74, 0x73B9, 0xAB75, 0x73BC, 0xAB76, 0x73BD,
+	0xAB77, 0x73BE, 0xAB78, 0x73BF, 0xAB79, 0x73C1, 0xAB7A, 0x73C3,
+	0xAB7B, 0x73C4, 0xAB7C, 0x73C5, 0xAB7D, 0x73C6, 0xAB7E, 0x73C7,
+	0xAB80, 0x73CB, 0xAB81, 0x73CC, 0xAB82, 0x73CE, 0xAB83, 0x73D2,
+	0xAB84, 0x73D3, 0xAB85, 0x73D4, 0xAB86, 0x73D5, 0xAB87, 0x73D6,
+	0xAB88, 0x73D7, 0xAB89, 0x73D8, 0xAB8A, 0x73DA, 0xAB8B, 0x73DB,
+	0xAB8C, 0x73DC, 0xAB8D, 0x73DD, 0xAB8E, 0x73DF, 0xAB8F, 0x73E1,
+	0xAB90, 0x73E2, 0xAB91, 0x73E3, 0xAB92, 0x73E4, 0xAB93, 0x73E6,
+	0xAB94, 0x73E8, 0xAB95, 0x73EA, 0xAB96, 0x73EB, 0xAB97, 0x73EC,
+	0xAB98, 0x73EE, 0xAB99, 0x73EF, 0xAB9A, 0x73F0, 0xAB9B, 0x73F1,
+	0xAB9C, 0x73F3, 0xAB9D, 0x73F4, 0xAB9E, 0x73F5, 0xAB9F, 0x73F6,
+	0xABA0, 0x73F7, 0xAC40, 0x73F8, 0xAC41, 0x73F9, 0xAC42, 0x73FA,
+	0xAC43, 0x73FB, 0xAC44, 0x73FC, 0xAC45, 0x73FD, 0xAC46, 0x73FE,
+	0xAC47, 0x73FF, 0xAC48, 0x7400, 0xAC49, 0x7401, 0xAC4A, 0x7402,
+	0xAC4B, 0x7404, 0xAC4C, 0x7407, 0xAC4D, 0x7408, 0xAC4E, 0x740B,
+	0xAC4F, 0x740C, 0xAC50, 0x740D, 0xAC51, 0x740E, 0xAC52, 0x7411,
+	0xAC53, 0x7412, 0xAC54, 0x7413, 0xAC55, 0x7414, 0xAC56, 0x7415,
+	0xAC57, 0x7416, 0xAC58, 0x7417, 0xAC59, 0x7418, 0xAC5A, 0x7419,
+	0xAC5B, 0x741C, 0xAC5C, 0x741D, 0xAC5D, 0x741E, 0xAC5E, 0x741F,
+	0xAC5F, 0x7420, 0xAC60, 0x7421, 0xAC61, 0x7423, 0xAC62, 0x7424,
+	0xAC63, 0x7427, 0xAC64, 0x7429, 0xAC65, 0x742B, 0xAC66, 0x742D,
+	0xAC67, 0x742F, 0xAC68, 0x7431, 0xAC69, 0x7432, 0xAC6A, 0x7437,
+	0xAC6B, 0x7438, 0xAC6C, 0x7439, 0xAC6D, 0x743A, 0xAC6E, 0x743B,
+	0xAC6F, 0x743D, 0xAC70, 0x743E, 0xAC71, 0x743F, 0xAC72, 0x7440,
+	0xAC73, 0x7442, 0xAC74, 0x7443, 0xAC75, 0x7444, 0xAC76, 0x7445,
+	0xAC77, 0x7446, 0xAC78, 0x7447, 0xAC79, 0x7448, 0xAC7A, 0x7449,
+	0xAC7B, 0x744A, 0xAC7C, 0x744B, 0xAC7D, 0x744C, 0xAC7E, 0x744D,
+	0xAC80, 0x744E, 0xAC81, 0x744F, 0xAC82, 0x7450, 0xAC83, 0x7451,
+	0xAC84, 0x7452, 0xAC85, 0x7453, 0xAC86, 0x7454, 0xAC87, 0x7456,
+	0xAC88, 0x7458, 0xAC89, 0x745D, 0xAC8A, 0x7460, 0xAC8B, 0x7461,
+	0xAC8C, 0x7462, 0xAC8D, 0x7463, 0xAC8E, 0x7464, 0xAC8F, 0x7465,
+	0xAC90, 0x7466, 0xAC91, 0x7467, 0xAC92, 0x7468, 0xAC93, 0x7469,
+	0xAC94, 0x746A, 0xAC95, 0x746B, 0xAC96, 0x746C, 0xAC97, 0x746E,
+	0xAC98, 0x746F, 0xAC99, 0x7471, 0xAC9A, 0x7472, 0xAC9B, 0x7473,
+	0xAC9C, 0x7474, 0xAC9D, 0x7475, 0xAC9E, 0x7478, 0xAC9F, 0x7479,
+	0xACA0, 0x747A, 0xAD40, 0x747B, 0xAD41, 0x747C, 0xAD42, 0x747D,
+	0xAD43, 0x747F, 0xAD44, 0x7482, 0xAD45, 0x7484, 0xAD46, 0x7485,
+	0xAD47, 0x7486, 0xAD48, 0x7488, 0xAD49, 0x7489, 0xAD4A, 0x748A,
+	0xAD4B, 0x748C, 0xAD4C, 0x748D, 0xAD4D, 0x748F, 0xAD4E, 0x7491,
+	0xAD4F, 0x7492, 0xAD50, 0x7493, 0xAD51, 0x7494, 0xAD52, 0x7495,
+	0xAD53, 0x7496, 0xAD54, 0x7497, 0xAD55, 0x7498, 0xAD56, 0x7499,
+	0xAD57, 0x749A, 0xAD58, 0x749B, 0xAD59, 0x749D, 0xAD5A, 0x749F,
+	0xAD5B, 0x74A0, 0xAD5C, 0x74A1, 0xAD5D, 0x74A2, 0xAD5E, 0x74A3,
+	0xAD5F, 0x74A4, 0xAD60, 0x74A5, 0xAD61, 0x74A6, 0xAD62, 0x74AA,
+	0xAD63, 0x74AB, 0xAD64, 0x74AC, 0xAD65, 0x74AD, 0xAD66, 0x74AE,
+	0xAD67, 0x74AF, 0xAD68, 0x74B0, 0xAD69, 0x74B1, 0xAD6A, 0x74B2,
+	0xAD6B, 0x74B3, 0xAD6C, 0x74B4, 0xAD6D, 0x74B5, 0xAD6E, 0x74B6,
+	0xAD6F, 0x74B7, 0xAD70, 0x74B8, 0xAD71, 0x74B9, 0xAD72, 0x74BB,
+	0xAD73, 0x74BC, 0xAD74, 0x74BD, 0xAD75, 0x74BE, 0xAD76, 0x74BF,
+	0xAD77, 0x74C0, 0xAD78, 0x74C1, 0xAD79, 0x74C2, 0xAD7A, 0x74C3,
+	0xAD7B, 0x74C4, 0xAD7C, 0x74C5, 0xAD7D, 0x74C6, 0xAD7E, 0x74C7,
+	0xAD80, 0x74C8, 0xAD81, 0x74C9, 0xAD82, 0x74CA, 0xAD83, 0x74CB,
+	0xAD84, 0x74CC, 0xAD85, 0x74CD, 0xAD86, 0x74CE, 0xAD87, 0x74CF,
+	0xAD88, 0x74D0, 0xAD89, 0x74D1, 0xAD8A, 0x74D3, 0xAD8B, 0x74D4,
+	0xAD8C, 0x74D5, 0xAD8D, 0x74D6, 0xAD8E, 0x74D7, 0xAD8F, 0x74D8,
+	0xAD90, 0x74D9, 0xAD91, 0x74DA, 0xAD92, 0x74DB, 0xAD93, 0x74DD,
+	0xAD94, 0x74DF, 0xAD95, 0x74E1, 0xAD96, 0x74E5, 0xAD97, 0x74E7,
+	0xAD98, 0x74E8, 0xAD99, 0x74E9, 0xAD9A, 0x74EA, 0xAD9B, 0x74EB,
+	0xAD9C, 0x74EC, 0xAD9D, 0x74ED, 0xAD9E, 0x74F0, 0xAD9F, 0x74F1,
+	0xADA0, 0x74F2, 0xAE40, 0x74F3, 0xAE41, 0x74F5, 0xAE42, 0x74F8,
+	0xAE43, 0x74F9, 0xAE44, 0x74FA, 0xAE45, 0x74FB, 0xAE46, 0x74FC,
+	0xAE47, 0x74FD, 0xAE48, 0x74FE, 0xAE49, 0x7500, 0xAE4A, 0x7501,
+	0xAE4B, 0x7502, 0xAE4C, 0x7503, 0xAE4D, 0x7505, 0xAE4E, 0x7506,
+	0xAE4F, 0x7507, 0xAE50, 0x7508, 0xAE51, 0x7509, 0xAE52, 0x750A,
+	0xAE53, 0x750B, 0xAE54, 0x750C, 0xAE55, 0x750E, 0xAE56, 0x7510,
+	0xAE57, 0x7512, 0xAE58, 0x7514, 0xAE59, 0x7515, 0xAE5A, 0x7516,
+	0xAE5B, 0x7517, 0xAE5C, 0x751B, 0xAE5D, 0x751D, 0xAE5E, 0x751E,
+	0xAE5F, 0x7520, 0xAE60, 0x7521, 0xAE61, 0x7522, 0xAE62, 0x7523,
+	0xAE63, 0x7524, 0xAE64, 0x7526, 0xAE65, 0x7527, 0xAE66, 0x752A,
+	0xAE67, 0x752E, 0xAE68, 0x7534, 0xAE69, 0x7536, 0xAE6A, 0x7539,
+	0xAE6B, 0x753C, 0xAE6C, 0x753D, 0xAE6D, 0x753F, 0xAE6E, 0x7541,
+	0xAE6F, 0x7542, 0xAE70, 0x7543, 0xAE71, 0x7544, 0xAE72, 0x7546,
+	0xAE73, 0x7547, 0xAE74, 0x7549, 0xAE75, 0x754A, 0xAE76, 0x754D,
+	0xAE77, 0x7550, 0xAE78, 0x7551, 0xAE79, 0x7552, 0xAE7A, 0x7553,
+	0xAE7B, 0x7555, 0xAE7C, 0x7556, 0xAE7D, 0x7557, 0xAE7E, 0x7558,
+	0xAE80, 0x755D, 0xAE81, 0x755E, 0xAE82, 0x755F, 0xAE83, 0x7560,
+	0xAE84, 0x7561, 0xAE85, 0x7562, 0xAE86, 0x7563, 0xAE87, 0x7564,
+	0xAE88, 0x7567, 0xAE89, 0x7568, 0xAE8A, 0x7569, 0xAE8B, 0x756B,
+	0xAE8C, 0x756C, 0xAE8D, 0x756D, 0xAE8E, 0x756E, 0xAE8F, 0x756F,
+	0xAE90, 0x7570, 0xAE91, 0x7571, 0xAE92, 0x7573, 0xAE93, 0x7575,
+	0xAE94, 0x7576, 0xAE95, 0x7577, 0xAE96, 0x757A, 0xAE97, 0x757B,
+	0xAE98, 0x757C, 0xAE99, 0x757D, 0xAE9A, 0x757E, 0xAE9B, 0x7580,
+	0xAE9C, 0x7581, 0xAE9D, 0x7582, 0xAE9E, 0x7584, 0xAE9F, 0x7585,
+	0xAEA0, 0x7587, 0xAF40, 0x7588, 0xAF41, 0x7589, 0xAF42, 0x758A,
+	0xAF43, 0x758C, 0xAF44, 0x758D, 0xAF45, 0x758E, 0xAF46, 0x7590,
+	0xAF47, 0x7593, 0xAF48, 0x7595, 0xAF49, 0x7598, 0xAF4A, 0x759B,
+	0xAF4B, 0x759C, 0xAF4C, 0x759E, 0xAF4D, 0x75A2, 0xAF4E, 0x75A6,
+	0xAF4F, 0x75A7, 0xAF50, 0x75A8, 0xAF51, 0x75A9, 0xAF52, 0x75AA,
+	0xAF53, 0x75AD, 0xAF54, 0x75B6, 0xAF55, 0x75B7, 0xAF56, 0x75BA,
+	0xAF57, 0x75BB, 0xAF58, 0x75BF, 0xAF59, 0x75C0, 0xAF5A, 0x75C1,
+	0xAF5B, 0x75C6, 0xAF5C, 0x75CB, 0xAF5D, 0x75CC, 0xAF5E, 0x75CE,
+	0xAF5F, 0x75CF, 0xAF60, 0x75D0, 0xAF61, 0x75D1, 0xAF62, 0x75D3,
+	0xAF63, 0x75D7, 0xAF64, 0x75D9, 0xAF65, 0x75DA, 0xAF66, 0x75DC,
+	0xAF67, 0x75DD, 0xAF68, 0x75DF, 0xAF69, 0x75E0, 0xAF6A, 0x75E1,
+	0xAF6B, 0x75E5, 0xAF6C, 0x75E9, 0xAF6D, 0x75EC, 0xAF6E, 0x75ED,
+	0xAF6F, 0x75EE, 0xAF70, 0x75EF, 0xAF71, 0x75F2, 0xAF72, 0x75F3,
+	0xAF73, 0x75F5, 0xAF74, 0x75F6, 0xAF75, 0x75F7, 0xAF76, 0x75F8,
+	0xAF77, 0x75FA, 0xAF78, 0x75FB, 0xAF79, 0x75FD, 0xAF7A, 0x75FE,
+	0xAF7B, 0x7602, 0xAF7C, 0x7604, 0xAF7D, 0x7606, 0xAF7E, 0x7607,
+	0xAF80, 0x7608, 0xAF81, 0x7609, 0xAF82, 0x760B, 0xAF83, 0x760D,
+	0xAF84, 0x760E, 0xAF85, 0x760F, 0xAF86, 0x7611, 0xAF87, 0x7612,
+	0xAF88, 0x7613, 0xAF89, 0x7614, 0xAF8A, 0x7616, 0xAF8B, 0x761A,
+	0xAF8C, 0x761C, 0xAF8D, 0x761D, 0xAF8E, 0x761E, 0xAF8F, 0x7621,
+	0xAF90, 0x7623, 0xAF91, 0x7627, 0xAF92, 0x7628, 0xAF93, 0x762C,
+	0xAF94, 0x762E, 0xAF95, 0x762F, 0xAF96, 0x7631, 0xAF97, 0x7632,
+	0xAF98, 0x7636, 0xAF99, 0x7637, 0xAF9A, 0x7639, 0xAF9B, 0x763A,
+	0xAF9C, 0x763B, 0xAF9D, 0x763D, 0xAF9E, 0x7641, 0xAF9F, 0x7642,
+	0xAFA0, 0x7644, 0xB040, 0x7645, 0xB041, 0x7646, 0xB042, 0x7647,
+	0xB043, 0x7648, 0xB044, 0x7649, 0xB045, 0x764A, 0xB046, 0x764B,
+	0xB047, 0x764E, 0xB048, 0x764F, 0xB049, 0x7650, 0xB04A, 0x7651,
+	0xB04B, 0x7652, 0xB04C, 0x7653, 0xB04D, 0x7655, 0xB04E, 0x7657,
+	0xB04F, 0x7658, 0xB050, 0x7659, 0xB051, 0x765A, 0xB052, 0x765B,
+	0xB053, 0x765D, 0xB054, 0x765F, 0xB055, 0x7660, 0xB056, 0x7661,
+	0xB057, 0x7662, 0xB058, 0x7664, 0xB059, 0x7665, 0xB05A, 0x7666,
+	0xB05B, 0x7667, 0xB05C, 0x7668, 0xB05D, 0x7669, 0xB05E, 0x766A,
+	0xB05F, 0x766C, 0xB060, 0x766D, 0xB061, 0x766E, 0xB062, 0x7670,
+	0xB063, 0x7671, 0xB064, 0x7672, 0xB065, 0x7673, 0xB066, 0x7674,
+	0xB067, 0x7675, 0xB068, 0x7676, 0xB069, 0x7677, 0xB06A, 0x7679,
+	0xB06B, 0x767A, 0xB06C, 0x767C, 0xB06D, 0x767F, 0xB06E, 0x7680,
+	0xB06F, 0x7681, 0xB070, 0x7683, 0xB071, 0x7685, 0xB072, 0x7689,
+	0xB073, 0x768A, 0xB074, 0x768C, 0xB075, 0x768D, 0xB076, 0x768F,
+	0xB077, 0x7690, 0xB078, 0x7692, 0xB079, 0x7694, 0xB07A, 0x7695,
+	0xB07B, 0x7697, 0xB07C, 0x7698, 0xB07D, 0x769A, 0xB07E, 0x769B,
+	0xB080, 0x769C, 0xB081, 0x769D, 0xB082, 0x769E, 0xB083, 0x769F,
+	0xB084, 0x76A0, 0xB085, 0x76A1, 0xB086, 0x76A2, 0xB087, 0x76A3,
+	0xB088, 0x76A5, 0xB089, 0x76A6, 0xB08A, 0x76A7, 0xB08B, 0x76A8,
+	0xB08C, 0x76A9, 0xB08D, 0x76AA, 0xB08E, 0x76AB, 0xB08F, 0x76AC,
+	0xB090, 0x76AD, 0xB091, 0x76AF, 0xB092, 0x76B0, 0xB093, 0x76B3,
+	0xB094, 0x76B5, 0xB095, 0x76B6, 0xB096, 0x76B7, 0xB097, 0x76B8,
+	0xB098, 0x76B9, 0xB099, 0x76BA, 0xB09A, 0x76BB, 0xB09B, 0x76BC,
+	0xB09C, 0x76BD, 0xB09D, 0x76BE, 0xB09E, 0x76C0, 0xB09F, 0x76C1,
+	0xB0A0, 0x76C3, 0xB0A1, 0x554A, 0xB0A2, 0x963F, 0xB0A3, 0x57C3,
+	0xB0A4, 0x6328, 0xB0A5, 0x54CE, 0xB0A6, 0x5509, 0xB0A7, 0x54C0,
+	0xB0A8, 0x7691, 0xB0A9, 0x764C, 0xB0AA, 0x853C, 0xB0AB, 0x77EE,
+	0xB0AC, 0x827E, 0xB0AD, 0x788D, 0xB0AE, 0x7231, 0xB0AF, 0x9698,
+	0xB0B0, 0x978D, 0xB0B1, 0x6C28, 0xB0B2, 0x5B89, 0xB0B3, 0x4FFA,
+	0xB0B4, 0x6309, 0xB0B5, 0x6697, 0xB0B6, 0x5CB8, 0xB0B7, 0x80FA,
+	0xB0B8, 0x6848, 0xB0B9, 0x80AE, 0xB0BA, 0x6602, 0xB0BB, 0x76CE,
+	0xB0BC, 0x51F9, 0xB0BD, 0x6556, 0xB0BE, 0x71AC, 0xB0BF, 0x7FF1,
+	0xB0C0, 0x8884, 0xB0C1, 0x50B2, 0xB0C2, 0x5965, 0xB0C3, 0x61CA,
+	0xB0C4, 0x6FB3, 0xB0C5, 0x82AD, 0xB0C6, 0x634C, 0xB0C7, 0x6252,
+	0xB0C8, 0x53ED, 0xB0C9, 0x5427, 0xB0CA, 0x7B06, 0xB0CB, 0x516B,
+	0xB0CC, 0x75A4, 0xB0CD, 0x5DF4, 0xB0CE, 0x62D4, 0xB0CF, 0x8DCB,
+	0xB0D0, 0x9776, 0xB0D1, 0x628A, 0xB0D2, 0x8019, 0xB0D3, 0x575D,
+	0xB0D4, 0x9738, 0xB0D5, 0x7F62, 0xB0D6, 0x7238, 0xB0D7, 0x767D,
+	0xB0D8, 0x67CF, 0xB0D9, 0x767E, 0xB0DA, 0x6446, 0xB0DB, 0x4F70,
+	0xB0DC, 0x8D25, 0xB0DD, 0x62DC, 0xB0DE, 0x7A17, 0xB0DF, 0x6591,
+	0xB0E0, 0x73ED, 0xB0E1, 0x642C, 0xB0E2, 0x6273, 0xB0E3, 0x822C,
+	0xB0E4, 0x9881, 0xB0E5, 0x677F, 0xB0E6, 0x7248, 0xB0E7, 0x626E,
+	0xB0E8, 0x62CC, 0xB0E9, 0x4F34, 0xB0EA, 0x74E3, 0xB0EB, 0x534A,
+	0xB0EC, 0x529E, 0xB0ED, 0x7ECA, 0xB0EE, 0x90A6, 0xB0EF, 0x5E2E,
+	0xB0F0, 0x6886, 0xB0F1, 0x699C, 0xB0F2, 0x8180, 0xB0F3, 0x7ED1,
+	0xB0F4, 0x68D2, 0xB0F5, 0x78C5, 0xB0F6, 0x868C, 0xB0F7, 0x9551,
+	0xB0F8, 0x508D, 0xB0F9, 0x8C24, 0xB0FA, 0x82DE, 0xB0FB, 0x80DE,
+	0xB0FC, 0x5305, 0xB0FD, 0x8912, 0xB0FE, 0x5265, 0xB140, 0x76C4,
+	0xB141, 0x76C7, 0xB142, 0x76C9, 0xB143, 0x76CB, 0xB144, 0x76CC,
+	0xB145, 0x76D3, 0xB146, 0x76D5, 0xB147, 0x76D9, 0xB148, 0x76DA,
+	0xB149, 0x76DC, 0xB14A, 0x76DD, 0xB14B, 0x76DE, 0xB14C, 0x76E0,
+	0xB14D, 0x76E1, 0xB14E, 0x76E2, 0xB14F, 0x76E3, 0xB150, 0x76E4,
+	0xB151, 0x76E6, 0xB152, 0x76E7, 0xB153, 0x76E8, 0xB154, 0x76E9,
+	0xB155, 0x76EA, 0xB156, 0x76EB, 0xB157, 0x76EC, 0xB158, 0x76ED,
+	0xB159, 0x76F0, 0xB15A, 0x76F3, 0xB15B, 0x76F5, 0xB15C, 0x76F6,
+	0xB15D, 0x76F7, 0xB15E, 0x76FA, 0xB15F, 0x76FB, 0xB160, 0x76FD,
+	0xB161, 0x76FF, 0xB162, 0x7700, 0xB163, 0x7702, 0xB164, 0x7703,
+	0xB165, 0x7705, 0xB166, 0x7706, 0xB167, 0x770A, 0xB168, 0x770C,
+	0xB169, 0x770E, 0xB16A, 0x770F, 0xB16B, 0x7710, 0xB16C, 0x7711,
+	0xB16D, 0x7712, 0xB16E, 0x7713, 0xB16F, 0x7714, 0xB170, 0x7715,
+	0xB171, 0x7716, 0xB172, 0x7717, 0xB173, 0x7718, 0xB174, 0x771B,
+	0xB175, 0x771C, 0xB176, 0x771D, 0xB177, 0x771E, 0xB178, 0x7721,
+	0xB179, 0x7723, 0xB17A, 0x7724, 0xB17B, 0x7725, 0xB17C, 0x7727,
+	0xB17D, 0x772A, 0xB17E, 0x772B, 0xB180, 0x772C, 0xB181, 0x772E,
+	0xB182, 0x7730, 0xB183, 0x7731, 0xB184, 0x7732, 0xB185, 0x7733,
+	0xB186, 0x7734, 0xB187, 0x7739, 0xB188, 0x773B, 0xB189, 0x773D,
+	0xB18A, 0x773E, 0xB18B, 0x773F, 0xB18C, 0x7742, 0xB18D, 0x7744,
+	0xB18E, 0x7745, 0xB18F, 0x7746, 0xB190, 0x7748, 0xB191, 0x7749,
+	0xB192, 0x774A, 0xB193, 0x774B, 0xB194, 0x774C, 0xB195, 0x774D,
+	0xB196, 0x774E, 0xB197, 0x774F, 0xB198, 0x7752, 0xB199, 0x7753,
+	0xB19A, 0x7754, 0xB19B, 0x7755, 0xB19C, 0x7756, 0xB19D, 0x7757,
+	0xB19E, 0x7758, 0xB19F, 0x7759, 0xB1A0, 0x775C, 0xB1A1, 0x8584,
+	0xB1A2, 0x96F9, 0xB1A3, 0x4FDD, 0xB1A4, 0x5821, 0xB1A5, 0x9971,
+	0xB1A6, 0x5B9D, 0xB1A7, 0x62B1, 0xB1A8, 0x62A5, 0xB1A9, 0x66B4,
+	0xB1AA, 0x8C79, 0xB1AB, 0x9C8D, 0xB1AC, 0x7206, 0xB1AD, 0x676F,
+	0xB1AE, 0x7891, 0xB1AF, 0x60B2, 0xB1B0, 0x5351, 0xB1B1, 0x5317,
+	0xB1B2, 0x8F88, 0xB1B3, 0x80CC, 0xB1B4, 0x8D1D, 0xB1B5, 0x94A1,
+	0xB1B6, 0x500D, 0xB1B7, 0x72C8, 0xB1B8, 0x5907, 0xB1B9, 0x60EB,
+	0xB1BA, 0x7119, 0xB1BB, 0x88AB, 0xB1BC, 0x5954, 0xB1BD, 0x82EF,
+	0xB1BE, 0x672C, 0xB1BF, 0x7B28, 0xB1C0, 0x5D29, 0xB1C1, 0x7EF7,
+	0xB1C2, 0x752D, 0xB1C3, 0x6CF5, 0xB1C4, 0x8E66, 0xB1C5, 0x8FF8,
+	0xB1C6, 0x903C, 0xB1C7, 0x9F3B, 0xB1C8, 0x6BD4, 0xB1C9, 0x9119,
+	0xB1CA, 0x7B14, 0xB1CB, 0x5F7C, 0xB1CC, 0x78A7, 0xB1CD, 0x84D6,
+	0xB1CE, 0x853D, 0xB1CF, 0x6BD5, 0xB1D0, 0x6BD9, 0xB1D1, 0x6BD6,
+	0xB1D2, 0x5E01, 0xB1D3, 0x5E87, 0xB1D4, 0x75F9, 0xB1D5, 0x95ED,
+	0xB1D6, 0x655D, 0xB1D7, 0x5F0A, 0xB1D8, 0x5FC5, 0xB1D9, 0x8F9F,
+	0xB1DA, 0x58C1, 0xB1DB, 0x81C2, 0xB1DC, 0x907F, 0xB1DD, 0x965B,
+	0xB1DE, 0x97AD, 0xB1DF, 0x8FB9, 0xB1E0, 0x7F16, 0xB1E1, 0x8D2C,
+	0xB1E2, 0x6241, 0xB1E3, 0x4FBF, 0xB1E4, 0x53D8, 0xB1E5, 0x535E,
+	0xB1E6, 0x8FA8, 0xB1E7, 0x8FA9, 0xB1E8, 0x8FAB, 0xB1E9, 0x904D,
+	0xB1EA, 0x6807, 0xB1EB, 0x5F6A, 0xB1EC, 0x8198, 0xB1ED, 0x8868,
+	0xB1EE, 0x9CD6, 0xB1EF, 0x618B, 0xB1F0, 0x522B, 0xB1F1, 0x762A,
+	0xB1F2, 0x5F6C, 0xB1F3, 0x658C, 0xB1F4, 0x6FD2, 0xB1F5, 0x6EE8,
+	0xB1F6, 0x5BBE, 0xB1F7, 0x6448, 0xB1F8, 0x5175, 0xB1F9, 0x51B0,
+	0xB1FA, 0x67C4, 0xB1FB, 0x4E19, 0xB1FC, 0x79C9, 0xB1FD, 0x997C,
+	0xB1FE, 0x70B3, 0xB240, 0x775D, 0xB241, 0x775E, 0xB242, 0x775F,
+	0xB243, 0x7760, 0xB244, 0x7764, 0xB245, 0x7767, 0xB246, 0x7769,
+	0xB247, 0x776A, 0xB248, 0x776D, 0xB249, 0x776E, 0xB24A, 0x776F,
+	0xB24B, 0x7770, 0xB24C, 0x7771, 0xB24D, 0x7772, 0xB24E, 0x7773,
+	0xB24F, 0x7774, 0xB250, 0x7775, 0xB251, 0x7776, 0xB252, 0x7777,
+	0xB253, 0x7778, 0xB254, 0x777A, 0xB255, 0x777B, 0xB256, 0x777C,
+	0xB257, 0x7781, 0xB258, 0x7782, 0xB259, 0x7783, 0xB25A, 0x7786,
+	0xB25B, 0x7787, 0xB25C, 0x7788, 0xB25D, 0x7789, 0xB25E, 0x778A,
+	0xB25F, 0x778B, 0xB260, 0x778F, 0xB261, 0x7790, 0xB262, 0x7793,
+	0xB263, 0x7794, 0xB264, 0x7795, 0xB265, 0x7796, 0xB266, 0x7797,
+	0xB267, 0x7798, 0xB268, 0x7799, 0xB269, 0x779A, 0xB26A, 0x779B,
+	0xB26B, 0x779C, 0xB26C, 0x779D, 0xB26D, 0x779E, 0xB26E, 0x77A1,
+	0xB26F, 0x77A3, 0xB270, 0x77A4, 0xB271, 0x77A6, 0xB272, 0x77A8,
+	0xB273, 0x77AB, 0xB274, 0x77AD, 0xB275, 0x77AE, 0xB276, 0x77AF,
+	0xB277, 0x77B1, 0xB278, 0x77B2, 0xB279, 0x77B4, 0xB27A, 0x77B6,
+	0xB27B, 0x77B7, 0xB27C, 0x77B8, 0xB27D, 0x77B9, 0xB27E, 0x77BA,
+	0xB280, 0x77BC, 0xB281, 0x77BE, 0xB282, 0x77C0, 0xB283, 0x77C1,
+	0xB284, 0x77C2, 0xB285, 0x77C3, 0xB286, 0x77C4, 0xB287, 0x77C5,
+	0xB288, 0x77C6, 0xB289, 0x77C7, 0xB28A, 0x77C8, 0xB28B, 0x77C9,
+	0xB28C, 0x77CA, 0xB28D, 0x77CB, 0xB28E, 0x77CC, 0xB28F, 0x77CE,
+	0xB290, 0x77CF, 0xB291, 0x77D0, 0xB292, 0x77D1, 0xB293, 0x77D2,
+	0xB294, 0x77D3, 0xB295, 0x77D4, 0xB296, 0x77D5, 0xB297, 0x77D6,
+	0xB298, 0x77D8, 0xB299, 0x77D9, 0xB29A, 0x77DA, 0xB29B, 0x77DD,
+	0xB29C, 0x77DE, 0xB29D, 0x77DF, 0xB29E, 0x77E0, 0xB29F, 0x77E1,
+	0xB2A0, 0x77E4, 0xB2A1, 0x75C5, 0xB2A2, 0x5E76, 0xB2A3, 0x73BB,
+	0xB2A4, 0x83E0, 0xB2A5, 0x64AD, 0xB2A6, 0x62E8, 0xB2A7, 0x94B5,
+	0xB2A8, 0x6CE2, 0xB2A9, 0x535A, 0xB2AA, 0x52C3, 0xB2AB, 0x640F,
+	0xB2AC, 0x94C2, 0xB2AD, 0x7B94, 0xB2AE, 0x4F2F, 0xB2AF, 0x5E1B,
+	0xB2B0, 0x8236, 0xB2B1, 0x8116, 0xB2B2, 0x818A, 0xB2B3, 0x6E24,
+	0xB2B4, 0x6CCA, 0xB2B5, 0x9A73, 0xB2B6, 0x6355, 0xB2B7, 0x535C,
+	0xB2B8, 0x54FA, 0xB2B9, 0x8865, 0xB2BA, 0x57E0, 0xB2BB, 0x4E0D,
+	0xB2BC, 0x5E03, 0xB2BD, 0x6B65, 0xB2BE, 0x7C3F, 0xB2BF, 0x90E8,
+	0xB2C0, 0x6016, 0xB2C1, 0x64E6, 0xB2C2, 0x731C, 0xB2C3, 0x88C1,
+	0xB2C4, 0x6750, 0xB2C5, 0x624D, 0xB2C6, 0x8D22, 0xB2C7, 0x776C,
+	0xB2C8, 0x8E29, 0xB2C9, 0x91C7, 0xB2CA, 0x5F69, 0xB2CB, 0x83DC,
+	0xB2CC, 0x8521, 0xB2CD, 0x9910, 0xB2CE, 0x53C2, 0xB2CF, 0x8695,
+	0xB2D0, 0x6B8B, 0xB2D1, 0x60ED, 0xB2D2, 0x60E8, 0xB2D3, 0x707F,
+	0xB2D4, 0x82CD, 0xB2D5, 0x8231, 0xB2D6, 0x4ED3, 0xB2D7, 0x6CA7,
+	0xB2D8, 0x85CF, 0xB2D9, 0x64CD, 0xB2DA, 0x7CD9, 0xB2DB, 0x69FD,
+	0xB2DC, 0x66F9, 0xB2DD, 0x8349, 0xB2DE, 0x5395, 0xB2DF, 0x7B56,
+	0xB2E0, 0x4FA7, 0xB2E1, 0x518C, 0xB2E2, 0x6D4B, 0xB2E3, 0x5C42,
+	0xB2E4, 0x8E6D, 0xB2E5, 0x63D2, 0xB2E6, 0x53C9, 0xB2E7, 0x832C,
+	0xB2E8, 0x8336, 0xB2E9, 0x67E5, 0xB2EA, 0x78B4, 0xB2EB, 0x643D,
+	0xB2EC, 0x5BDF, 0xB2ED, 0x5C94, 0xB2EE, 0x5DEE, 0xB2EF, 0x8BE7,
+	0xB2F0, 0x62C6, 0xB2F1, 0x67F4, 0xB2F2, 0x8C7A, 0xB2F3, 0x6400,
+	0xB2F4, 0x63BA, 0xB2F5, 0x8749, 0xB2F6, 0x998B, 0xB2F7, 0x8C17,
+	0xB2F8, 0x7F20, 0xB2F9, 0x94F2, 0xB2FA, 0x4EA7, 0xB2FB, 0x9610,
+	0xB2FC, 0x98A4, 0xB2FD, 0x660C, 0xB2FE, 0x7316, 0xB340, 0x77E6,
+	0xB341, 0x77E8, 0xB342, 0x77EA, 0xB343, 0x77EF, 0xB344, 0x77F0,
+	0xB345, 0x77F1, 0xB346, 0x77F2, 0xB347, 0x77F4, 0xB348, 0x77F5,
+	0xB349, 0x77F7, 0xB34A, 0x77F9, 0xB34B, 0x77FA, 0xB34C, 0x77FB,
+	0xB34D, 0x77FC, 0xB34E, 0x7803, 0xB34F, 0x7804, 0xB350, 0x7805,
+	0xB351, 0x7806, 0xB352, 0x7807, 0xB353, 0x7808, 0xB354, 0x780A,
+	0xB355, 0x780B, 0xB356, 0x780E, 0xB357, 0x780F, 0xB358, 0x7810,
+	0xB359, 0x7813, 0xB35A, 0x7815, 0xB35B, 0x7819, 0xB35C, 0x781B,
+	0xB35D, 0x781E, 0xB35E, 0x7820, 0xB35F, 0x7821, 0xB360, 0x7822,
+	0xB361, 0x7824, 0xB362, 0x7828, 0xB363, 0x782A, 0xB364, 0x782B,
+	0xB365, 0x782E, 0xB366, 0x782F, 0xB367, 0x7831, 0xB368, 0x7832,
+	0xB369, 0x7833, 0xB36A, 0x7835, 0xB36B, 0x7836, 0xB36C, 0x783D,
+	0xB36D, 0x783F, 0xB36E, 0x7841, 0xB36F, 0x7842, 0xB370, 0x7843,
+	0xB371, 0x7844, 0xB372, 0x7846, 0xB373, 0x7848, 0xB374, 0x7849,
+	0xB375, 0x784A, 0xB376, 0x784B, 0xB377, 0x784D, 0xB378, 0x784F,
+	0xB379, 0x7851, 0xB37A, 0x7853, 0xB37B, 0x7854, 0xB37C, 0x7858,
+	0xB37D, 0x7859, 0xB37E, 0x785A, 0xB380, 0x785B, 0xB381, 0x785C,
+	0xB382, 0x785E, 0xB383, 0x785F, 0xB384, 0x7860, 0xB385, 0x7861,
+	0xB386, 0x7862, 0xB387, 0x7863, 0xB388, 0x7864, 0xB389, 0x7865,
+	0xB38A, 0x7866, 0xB38B, 0x7867, 0xB38C, 0x7868, 0xB38D, 0x7869,
+	0xB38E, 0x786F, 0xB38F, 0x7870, 0xB390, 0x7871, 0xB391, 0x7872,
+	0xB392, 0x7873, 0xB393, 0x7874, 0xB394, 0x7875, 0xB395, 0x7876,
+	0xB396, 0x7878, 0xB397, 0x7879, 0xB398, 0x787A, 0xB399, 0x787B,
+	0xB39A, 0x787D, 0xB39B, 0x787E, 0xB39C, 0x787F, 0xB39D, 0x7880,
+	0xB39E, 0x7881, 0xB39F, 0x7882, 0xB3A0, 0x7883, 0xB3A1, 0x573A,
+	0xB3A2, 0x5C1D, 0xB3A3, 0x5E38, 0xB3A4, 0x957F, 0xB3A5, 0x507F,
+	0xB3A6, 0x80A0, 0xB3A7, 0x5382, 0xB3A8, 0x655E, 0xB3A9, 0x7545,
+	0xB3AA, 0x5531, 0xB3AB, 0x5021, 0xB3AC, 0x8D85, 0xB3AD, 0x6284,
+	0xB3AE, 0x949E, 0xB3AF, 0x671D, 0xB3B0, 0x5632, 0xB3B1, 0x6F6E,
+	0xB3B2, 0x5DE2, 0xB3B3, 0x5435, 0xB3B4, 0x7092, 0xB3B5, 0x8F66,
+	0xB3B6, 0x626F, 0xB3B7, 0x64A4, 0xB3B8, 0x63A3, 0xB3B9, 0x5F7B,
+	0xB3BA, 0x6F88, 0xB3BB, 0x90F4, 0xB3BC, 0x81E3, 0xB3BD, 0x8FB0,
+	0xB3BE, 0x5C18, 0xB3BF, 0x6668, 0xB3C0, 0x5FF1, 0xB3C1, 0x6C89,
+	0xB3C2, 0x9648, 0xB3C3, 0x8D81, 0xB3C4, 0x886C, 0xB3C5, 0x6491,
+	0xB3C6, 0x79F0, 0xB3C7, 0x57CE, 0xB3C8, 0x6A59, 0xB3C9, 0x6210,
+	0xB3CA, 0x5448, 0xB3CB, 0x4E58, 0xB3CC, 0x7A0B, 0xB3CD, 0x60E9,
+	0xB3CE, 0x6F84, 0xB3CF, 0x8BDA, 0xB3D0, 0x627F, 0xB3D1, 0x901E,
+	0xB3D2, 0x9A8B, 0xB3D3, 0x79E4, 0xB3D4, 0x5403, 0xB3D5, 0x75F4,
+	0xB3D6, 0x6301, 0xB3D7, 0x5319, 0xB3D8, 0x6C60, 0xB3D9, 0x8FDF,
+	0xB3DA, 0x5F1B, 0xB3DB, 0x9A70, 0xB3DC, 0x803B, 0xB3DD, 0x9F7F,
+	0xB3DE, 0x4F88, 0xB3DF, 0x5C3A, 0xB3E0, 0x8D64, 0xB3E1, 0x7FC5,
+	0xB3E2, 0x65A5, 0xB3E3, 0x70BD, 0xB3E4, 0x5145, 0xB3E5, 0x51B2,
+	0xB3E6, 0x866B, 0xB3E7, 0x5D07, 0xB3E8, 0x5BA0, 0xB3E9, 0x62BD,
+	0xB3EA, 0x916C, 0xB3EB, 0x7574, 0xB3EC, 0x8E0C, 0xB3ED, 0x7A20,
+	0xB3EE, 0x6101, 0xB3EF, 0x7B79, 0xB3F0, 0x4EC7, 0xB3F1, 0x7EF8,
+	0xB3F2, 0x7785, 0xB3F3, 0x4E11, 0xB3F4, 0x81ED, 0xB3F5, 0x521D,
+	0xB3F6, 0x51FA, 0xB3F7, 0x6A71, 0xB3F8, 0x53A8, 0xB3F9, 0x8E87,
+	0xB3FA, 0x9504, 0xB3FB, 0x96CF, 0xB3FC, 0x6EC1, 0xB3FD, 0x9664,
+	0xB3FE, 0x695A, 0xB440, 0x7884, 0xB441, 0x7885, 0xB442, 0x7886,
+	0xB443, 0x7888, 0xB444, 0x788A, 0xB445, 0x788B, 0xB446, 0x788F,
+	0xB447, 0x7890, 0xB448, 0x7892, 0xB449, 0x7894, 0xB44A, 0x7895,
+	0xB44B, 0x7896, 0xB44C, 0x7899, 0xB44D, 0x789D, 0xB44E, 0x789E,
+	0xB44F, 0x78A0, 0xB450, 0x78A2, 0xB451, 0x78A4, 0xB452, 0x78A6,
+	0xB453, 0x78A8, 0xB454, 0x78A9, 0xB455, 0x78AA, 0xB456, 0x78AB,
+	0xB457, 0x78AC, 0xB458, 0x78AD, 0xB459, 0x78AE, 0xB45A, 0x78AF,
+	0xB45B, 0x78B5, 0xB45C, 0x78B6, 0xB45D, 0x78B7, 0xB45E, 0x78B8,
+	0xB45F, 0x78BA, 0xB460, 0x78BB, 0xB461, 0x78BC, 0xB462, 0x78BD,
+	0xB463, 0x78BF, 0xB464, 0x78C0, 0xB465, 0x78C2, 0xB466, 0x78C3,
+	0xB467, 0x78C4, 0xB468, 0x78C6, 0xB469, 0x78C7, 0xB46A, 0x78C8,
+	0xB46B, 0x78CC, 0xB46C, 0x78CD, 0xB46D, 0x78CE, 0xB46E, 0x78CF,
+	0xB46F, 0x78D1, 0xB470, 0x78D2, 0xB471, 0x78D3, 0xB472, 0x78D6,
+	0xB473, 0x78D7, 0xB474, 0x78D8, 0xB475, 0x78DA, 0xB476, 0x78DB,
+	0xB477, 0x78DC, 0xB478, 0x78DD, 0xB479, 0x78DE, 0xB47A, 0x78DF,
+	0xB47B, 0x78E0, 0xB47C, 0x78E1, 0xB47D, 0x78E2, 0xB47E, 0x78E3,
+	0xB480, 0x78E4, 0xB481, 0x78E5, 0xB482, 0x78E6, 0xB483, 0x78E7,
+	0xB484, 0x78E9, 0xB485, 0x78EA, 0xB486, 0x78EB, 0xB487, 0x78ED,
+	0xB488, 0x78EE, 0xB489, 0x78EF, 0xB48A, 0x78F0, 0xB48B, 0x78F1,
+	0xB48C, 0x78F3, 0xB48D, 0x78F5, 0xB48E, 0x78F6, 0xB48F, 0x78F8,
+	0xB490, 0x78F9, 0xB491, 0x78FB, 0xB492, 0x78FC, 0xB493, 0x78FD,
+	0xB494, 0x78FE, 0xB495, 0x78FF, 0xB496, 0x7900, 0xB497, 0x7902,
+	0xB498, 0x7903, 0xB499, 0x7904, 0xB49A, 0x7906, 0xB49B, 0x7907,
+	0xB49C, 0x7908, 0xB49D, 0x7909, 0xB49E, 0x790A, 0xB49F, 0x790B,
+	0xB4A0, 0x790C, 0xB4A1, 0x7840, 0xB4A2, 0x50A8, 0xB4A3, 0x77D7,
+	0xB4A4, 0x6410, 0xB4A5, 0x89E6, 0xB4A6, 0x5904, 0xB4A7, 0x63E3,
+	0xB4A8, 0x5DDD, 0xB4A9, 0x7A7F, 0xB4AA, 0x693D, 0xB4AB, 0x4F20,
+	0xB4AC, 0x8239, 0xB4AD, 0x5598, 0xB4AE, 0x4E32, 0xB4AF, 0x75AE,
+	0xB4B0, 0x7A97, 0xB4B1, 0x5E62, 0xB4B2, 0x5E8A, 0xB4B3, 0x95EF,
+	0xB4B4, 0x521B, 0xB4B5, 0x5439, 0xB4B6, 0x708A, 0xB4B7, 0x6376,
+	0xB4B8, 0x9524, 0xB4B9, 0x5782, 0xB4BA, 0x6625, 0xB4BB, 0x693F,
+	0xB4BC, 0x9187, 0xB4BD, 0x5507, 0xB4BE, 0x6DF3, 0xB4BF, 0x7EAF,
+	0xB4C0, 0x8822, 0xB4C1, 0x6233, 0xB4C2, 0x7EF0, 0xB4C3, 0x75B5,
+	0xB4C4, 0x8328, 0xB4C5, 0x78C1, 0xB4C6, 0x96CC, 0xB4C7, 0x8F9E,
+	0xB4C8, 0x6148, 0xB4C9, 0x74F7, 0xB4CA, 0x8BCD, 0xB4CB, 0x6B64,
+	0xB4CC, 0x523A, 0xB4CD, 0x8D50, 0xB4CE, 0x6B21, 0xB4CF, 0x806A,
+	0xB4D0, 0x8471, 0xB4D1, 0x56F1, 0xB4D2, 0x5306, 0xB4D3, 0x4ECE,
+	0xB4D4, 0x4E1B, 0xB4D5, 0x51D1, 0xB4D6, 0x7C97, 0xB4D7, 0x918B,
+	0xB4D8, 0x7C07, 0xB4D9, 0x4FC3, 0xB4DA, 0x8E7F, 0xB4DB, 0x7BE1,
+	0xB4DC, 0x7A9C, 0xB4DD, 0x6467, 0xB4DE, 0x5D14, 0xB4DF, 0x50AC,
+	0xB4E0, 0x8106, 0xB4E1, 0x7601, 0xB4E2, 0x7CB9, 0xB4E3, 0x6DEC,
+	0xB4E4, 0x7FE0, 0xB4E5, 0x6751, 0xB4E6, 0x5B58, 0xB4E7, 0x5BF8,
+	0xB4E8, 0x78CB, 0xB4E9, 0x64AE, 0xB4EA, 0x6413, 0xB4EB, 0x63AA,
+	0xB4EC, 0x632B, 0xB4ED, 0x9519, 0xB4EE, 0x642D, 0xB4EF, 0x8FBE,
+	0xB4F0, 0x7B54, 0xB4F1, 0x7629, 0xB4F2, 0x6253, 0xB4F3, 0x5927,
+	0xB4F4, 0x5446, 0xB4F5, 0x6B79, 0xB4F6, 0x50A3, 0xB4F7, 0x6234,
+	0xB4F8, 0x5E26, 0xB4F9, 0x6B86, 0xB4FA, 0x4EE3, 0xB4FB, 0x8D37,
+	0xB4FC, 0x888B, 0xB4FD, 0x5F85, 0xB4FE, 0x902E, 0xB540, 0x790D,
+	0xB541, 0x790E, 0xB542, 0x790F, 0xB543, 0x7910, 0xB544, 0x7911,
+	0xB545, 0x7912, 0xB546, 0x7914, 0xB547, 0x7915, 0xB548, 0x7916,
+	0xB549, 0x7917, 0xB54A, 0x7918, 0xB54B, 0x7919, 0xB54C, 0x791A,
+	0xB54D, 0x791B, 0xB54E, 0x791C, 0xB54F, 0x791D, 0xB550, 0x791F,
+	0xB551, 0x7920, 0xB552, 0x7921, 0xB553, 0x7922, 0xB554, 0x7923,
+	0xB555, 0x7925, 0xB556, 0x7926, 0xB557, 0x7927, 0xB558, 0x7928,
+	0xB559, 0x7929, 0xB55A, 0x792A, 0xB55B, 0x792B, 0xB55C, 0x792C,
+	0xB55D, 0x792D, 0xB55E, 0x792E, 0xB55F, 0x792F, 0xB560, 0x7930,
+	0xB561, 0x7931, 0xB562, 0x7932, 0xB563, 0x7933, 0xB564, 0x7935,
+	0xB565, 0x7936, 0xB566, 0x7937, 0xB567, 0x7938, 0xB568, 0x7939,
+	0xB569, 0x793D, 0xB56A, 0x793F, 0xB56B, 0x7942, 0xB56C, 0x7943,
+	0xB56D, 0x7944, 0xB56E, 0x7945, 0xB56F, 0x7947, 0xB570, 0x794A,
+	0xB571, 0x794B, 0xB572, 0x794C, 0xB573, 0x794D, 0xB574, 0x794E,
+	0xB575, 0x794F, 0xB576, 0x7950, 0xB577, 0x7951, 0xB578, 0x7952,
+	0xB579, 0x7954, 0xB57A, 0x7955, 0xB57B, 0x7958, 0xB57C, 0x7959,
+	0xB57D, 0x7961, 0xB57E, 0x7963, 0xB580, 0x7964, 0xB581, 0x7966,
+	0xB582, 0x7969, 0xB583, 0x796A, 0xB584, 0x796B, 0xB585, 0x796C,
+	0xB586, 0x796E, 0xB587, 0x7970, 0xB588, 0x7971, 0xB589, 0x7972,
+	0xB58A, 0x7973, 0xB58B, 0x7974, 0xB58C, 0x7975, 0xB58D, 0x7976,
+	0xB58E, 0x7979, 0xB58F, 0x797B, 0xB590, 0x797C, 0xB591, 0x797D,
+	0xB592, 0x797E, 0xB593, 0x797F, 0xB594, 0x7982, 0xB595, 0x7983,
+	0xB596, 0x7986, 0xB597, 0x7987, 0xB598, 0x7988, 0xB599, 0x7989,
+	0xB59A, 0x798B, 0xB59B, 0x798C, 0xB59C, 0x798D, 0xB59D, 0x798E,
+	0xB59E, 0x7990, 0xB59F, 0x7991, 0xB5A0, 0x7992, 0xB5A1, 0x6020,
+	0xB5A2, 0x803D, 0xB5A3, 0x62C5, 0xB5A4, 0x4E39, 0xB5A5, 0x5355,
+	0xB5A6, 0x90F8, 0xB5A7, 0x63B8, 0xB5A8, 0x80C6, 0xB5A9, 0x65E6,
+	0xB5AA, 0x6C2E, 0xB5AB, 0x4F46, 0xB5AC, 0x60EE, 0xB5AD, 0x6DE1,
+	0xB5AE, 0x8BDE, 0xB5AF, 0x5F39, 0xB5B0, 0x86CB, 0xB5B1, 0x5F53,
+	0xB5B2, 0x6321, 0xB5B3, 0x515A, 0xB5B4, 0x8361, 0xB5B5, 0x6863,
+	0xB5B6, 0x5200, 0xB5B7, 0x6363, 0xB5B8, 0x8E48, 0xB5B9, 0x5012,
+	0xB5BA, 0x5C9B, 0xB5BB, 0x7977, 0xB5BC, 0x5BFC, 0xB5BD, 0x5230,
+	0xB5BE, 0x7A3B, 0xB5BF, 0x60BC, 0xB5C0, 0x9053, 0xB5C1, 0x76D7,
+	0xB5C2, 0x5FB7, 0xB5C3, 0x5F97, 0xB5C4, 0x7684, 0xB5C5, 0x8E6C,
+	0xB5C6, 0x706F, 0xB5C7, 0x767B, 0xB5C8, 0x7B49, 0xB5C9, 0x77AA,
+	0xB5CA, 0x51F3, 0xB5CB, 0x9093, 0xB5CC, 0x5824, 0xB5CD, 0x4F4E,
+	0xB5CE, 0x6EF4, 0xB5CF, 0x8FEA, 0xB5D0, 0x654C, 0xB5D1, 0x7B1B,
+	0xB5D2, 0x72C4, 0xB5D3, 0x6DA4, 0xB5D4, 0x7FDF, 0xB5D5, 0x5AE1,
+	0xB5D6, 0x62B5, 0xB5D7, 0x5E95, 0xB5D8, 0x5730, 0xB5D9, 0x8482,
+	0xB5DA, 0x7B2C, 0xB5DB, 0x5E1D, 0xB5DC, 0x5F1F, 0xB5DD, 0x9012,
+	0xB5DE, 0x7F14, 0xB5DF, 0x98A0, 0xB5E0, 0x6382, 0xB5E1, 0x6EC7,
+	0xB5E2, 0x7898, 0xB5E3, 0x70B9, 0xB5E4, 0x5178, 0xB5E5, 0x975B,
+	0xB5E6, 0x57AB, 0xB5E7, 0x7535, 0xB5E8, 0x4F43, 0xB5E9, 0x7538,
+	0xB5EA, 0x5E97, 0xB5EB, 0x60E6, 0xB5EC, 0x5960, 0xB5ED, 0x6DC0,
+	0xB5EE, 0x6BBF, 0xB5EF, 0x7889, 0xB5F0, 0x53FC, 0xB5F1, 0x96D5,
+	0xB5F2, 0x51CB, 0xB5F3, 0x5201, 0xB5F4, 0x6389, 0xB5F5, 0x540A,
+	0xB5F6, 0x9493, 0xB5F7, 0x8C03, 0xB5F8, 0x8DCC, 0xB5F9, 0x7239,
+	0xB5FA, 0x789F, 0xB5FB, 0x8776, 0xB5FC, 0x8FED, 0xB5FD, 0x8C0D,
+	0xB5FE, 0x53E0, 0xB640, 0x7993, 0xB641, 0x7994, 0xB642, 0x7995,
+	0xB643, 0x7996, 0xB644, 0x7997, 0xB645, 0x7998, 0xB646, 0x7999,
+	0xB647, 0x799B, 0xB648, 0x799C, 0xB649, 0x799D, 0xB64A, 0x799E,
+	0xB64B, 0x799F, 0xB64C, 0x79A0, 0xB64D, 0x79A1, 0xB64E, 0x79A2,
+	0xB64F, 0x79A3, 0xB650, 0x79A4, 0xB651, 0x79A5, 0xB652, 0x79A6,
+	0xB653, 0x79A8, 0xB654, 0x79A9, 0xB655, 0x79AA, 0xB656, 0x79AB,
+	0xB657, 0x79AC, 0xB658, 0x79AD, 0xB659, 0x79AE, 0xB65A, 0x79AF,
+	0xB65B, 0x79B0, 0xB65C, 0x79B1, 0xB65D, 0x79B2, 0xB65E, 0x79B4,
+	0xB65F, 0x79B5, 0xB660, 0x79B6, 0xB661, 0x79B7, 0xB662, 0x79B8,
+	0xB663, 0x79BC, 0xB664, 0x79BF, 0xB665, 0x79C2, 0xB666, 0x79C4,
+	0xB667, 0x79C5, 0xB668, 0x79C7, 0xB669, 0x79C8, 0xB66A, 0x79CA,
+	0xB66B, 0x79CC, 0xB66C, 0x79CE, 0xB66D, 0x79CF, 0xB66E, 0x79D0,
+	0xB66F, 0x79D3, 0xB670, 0x79D4, 0xB671, 0x79D6, 0xB672, 0x79D7,
+	0xB673, 0x79D9, 0xB674, 0x79DA, 0xB675, 0x79DB, 0xB676, 0x79DC,
+	0xB677, 0x79DD, 0xB678, 0x79DE, 0xB679, 0x79E0, 0xB67A, 0x79E1,
+	0xB67B, 0x79E2, 0xB67C, 0x79E5, 0xB67D, 0x79E8, 0xB67E, 0x79EA,
+	0xB680, 0x79EC, 0xB681, 0x79EE, 0xB682, 0x79F1, 0xB683, 0x79F2,
+	0xB684, 0x79F3, 0xB685, 0x79F4, 0xB686, 0x79F5, 0xB687, 0x79F6,
+	0xB688, 0x79F7, 0xB689, 0x79F9, 0xB68A, 0x79FA, 0xB68B, 0x79FC,
+	0xB68C, 0x79FE, 0xB68D, 0x79FF, 0xB68E, 0x7A01, 0xB68F, 0x7A04,
+	0xB690, 0x7A05, 0xB691, 0x7A07, 0xB692, 0x7A08, 0xB693, 0x7A09,
+	0xB694, 0x7A0A, 0xB695, 0x7A0C, 0xB696, 0x7A0F, 0xB697, 0x7A10,
+	0xB698, 0x7A11, 0xB699, 0x7A12, 0xB69A, 0x7A13, 0xB69B, 0x7A15,
+	0xB69C, 0x7A16, 0xB69D, 0x7A18, 0xB69E, 0x7A19, 0xB69F, 0x7A1B,
+	0xB6A0, 0x7A1C, 0xB6A1, 0x4E01, 0xB6A2, 0x76EF, 0xB6A3, 0x53EE,
+	0xB6A4, 0x9489, 0xB6A5, 0x9876, 0xB6A6, 0x9F0E, 0xB6A7, 0x952D,
+	0xB6A8, 0x5B9A, 0xB6A9, 0x8BA2, 0xB6AA, 0x4E22, 0xB6AB, 0x4E1C,
+	0xB6AC, 0x51AC, 0xB6AD, 0x8463, 0xB6AE, 0x61C2, 0xB6AF, 0x52A8,
+	0xB6B0, 0x680B, 0xB6B1, 0x4F97, 0xB6B2, 0x606B, 0xB6B3, 0x51BB,
+	0xB6B4, 0x6D1E, 0xB6B5, 0x515C, 0xB6B6, 0x6296, 0xB6B7, 0x6597,
+	0xB6B8, 0x9661, 0xB6B9, 0x8C46, 0xB6BA, 0x9017, 0xB6BB, 0x75D8,
+	0xB6BC, 0x90FD, 0xB6BD, 0x7763, 0xB6BE, 0x6BD2, 0xB6BF, 0x728A,
+	0xB6C0, 0x72EC, 0xB6C1, 0x8BFB, 0xB6C2, 0x5835, 0xB6C3, 0x7779,
+	0xB6C4, 0x8D4C, 0xB6C5, 0x675C, 0xB6C6, 0x9540, 0xB6C7, 0x809A,
+	0xB6C8, 0x5EA6, 0xB6C9, 0x6E21, 0xB6CA, 0x5992, 0xB6CB, 0x7AEF,
+	0xB6CC, 0x77ED, 0xB6CD, 0x953B, 0xB6CE, 0x6BB5, 0xB6CF, 0x65AD,
+	0xB6D0, 0x7F0E, 0xB6D1, 0x5806, 0xB6D2, 0x5151, 0xB6D3, 0x961F,
+	0xB6D4, 0x5BF9, 0xB6D5, 0x58A9, 0xB6D6, 0x5428, 0xB6D7, 0x8E72,
+	0xB6D8, 0x6566, 0xB6D9, 0x987F, 0xB6DA, 0x56E4, 0xB6DB, 0x949D,
+	0xB6DC, 0x76FE, 0xB6DD, 0x9041, 0xB6DE, 0x6387, 0xB6DF, 0x54C6,
+	0xB6E0, 0x591A, 0xB6E1, 0x593A, 0xB6E2, 0x579B, 0xB6E3, 0x8EB2,
+	0xB6E4, 0x6735, 0xB6E5, 0x8DFA, 0xB6E6, 0x8235, 0xB6E7, 0x5241,
+	0xB6E8, 0x60F0, 0xB6E9, 0x5815, 0xB6EA, 0x86FE, 0xB6EB, 0x5CE8,
+	0xB6EC, 0x9E45, 0xB6ED, 0x4FC4, 0xB6EE, 0x989D, 0xB6EF, 0x8BB9,
+	0xB6F0, 0x5A25, 0xB6F1, 0x6076, 0xB6F2, 0x5384, 0xB6F3, 0x627C,
+	0xB6F4, 0x904F, 0xB6F5, 0x9102, 0xB6F6, 0x997F, 0xB6F7, 0x6069,
+	0xB6F8, 0x800C, 0xB6F9, 0x513F, 0xB6FA, 0x8033, 0xB6FB, 0x5C14,
+	0xB6FC, 0x9975, 0xB6FD, 0x6D31, 0xB6FE, 0x4E8C, 0xB740, 0x7A1D,
+	0xB741, 0x7A1F, 0xB742, 0x7A21, 0xB743, 0x7A22, 0xB744, 0x7A24,
+	0xB745, 0x7A25, 0xB746, 0x7A26, 0xB747, 0x7A27, 0xB748, 0x7A28,
+	0xB749, 0x7A29, 0xB74A, 0x7A2A, 0xB74B, 0x7A2B, 0xB74C, 0x7A2C,
+	0xB74D, 0x7A2D, 0xB74E, 0x7A2E, 0xB74F, 0x7A2F, 0xB750, 0x7A30,
+	0xB751, 0x7A31, 0xB752, 0x7A32, 0xB753, 0x7A34, 0xB754, 0x7A35,
+	0xB755, 0x7A36, 0xB756, 0x7A38, 0xB757, 0x7A3A, 0xB758, 0x7A3E,
+	0xB759, 0x7A40, 0xB75A, 0x7A41, 0xB75B, 0x7A42, 0xB75C, 0x7A43,
+	0xB75D, 0x7A44, 0xB75E, 0x7A45, 0xB75F, 0x7A47, 0xB760, 0x7A48,
+	0xB761, 0x7A49, 0xB762, 0x7A4A, 0xB763, 0x7A4B, 0xB764, 0x7A4C,
+	0xB765, 0x7A4D, 0xB766, 0x7A4E, 0xB767, 0x7A4F, 0xB768, 0x7A50,
+	0xB769, 0x7A52, 0xB76A, 0x7A53, 0xB76B, 0x7A54, 0xB76C, 0x7A55,
+	0xB76D, 0x7A56, 0xB76E, 0x7A58, 0xB76F, 0x7A59, 0xB770, 0x7A5A,
+	0xB771, 0x7A5B, 0xB772, 0x7A5C, 0xB773, 0x7A5D, 0xB774, 0x7A5E,
+	0xB775, 0x7A5F, 0xB776, 0x7A60, 0xB777, 0x7A61, 0xB778, 0x7A62,
+	0xB779, 0x7A63, 0xB77A, 0x7A64, 0xB77B, 0x7A65, 0xB77C, 0x7A66,
+	0xB77D, 0x7A67, 0xB77E, 0x7A68, 0xB780, 0x7A69, 0xB781, 0x7A6A,
+	0xB782, 0x7A6B, 0xB783, 0x7A6C, 0xB784, 0x7A6D, 0xB785, 0x7A6E,
+	0xB786, 0x7A6F, 0xB787, 0x7A71, 0xB788, 0x7A72, 0xB789, 0x7A73,
+	0xB78A, 0x7A75, 0xB78B, 0x7A7B, 0xB78C, 0x7A7C, 0xB78D, 0x7A7D,
+	0xB78E, 0x7A7E, 0xB78F, 0x7A82, 0xB790, 0x7A85, 0xB791, 0x7A87,
+	0xB792, 0x7A89, 0xB793, 0x7A8A, 0xB794, 0x7A8B, 0xB795, 0x7A8C,
+	0xB796, 0x7A8E, 0xB797, 0x7A8F, 0xB798, 0x7A90, 0xB799, 0x7A93,
+	0xB79A, 0x7A94, 0xB79B, 0x7A99, 0xB79C, 0x7A9A, 0xB79D, 0x7A9B,
+	0xB79E, 0x7A9E, 0xB79F, 0x7AA1, 0xB7A0, 0x7AA2, 0xB7A1, 0x8D30,
+	0xB7A2, 0x53D1, 0xB7A3, 0x7F5A, 0xB7A4, 0x7B4F, 0xB7A5, 0x4F10,
+	0xB7A6, 0x4E4F, 0xB7A7, 0x9600, 0xB7A8, 0x6CD5, 0xB7A9, 0x73D0,
+	0xB7AA, 0x85E9, 0xB7AB, 0x5E06, 0xB7AC, 0x756A, 0xB7AD, 0x7FFB,
+	0xB7AE, 0x6A0A, 0xB7AF, 0x77FE, 0xB7B0, 0x9492, 0xB7B1, 0x7E41,
+	0xB7B2, 0x51E1, 0xB7B3, 0x70E6, 0xB7B4, 0x53CD, 0xB7B5, 0x8FD4,
+	0xB7B6, 0x8303, 0xB7B7, 0x8D29, 0xB7B8, 0x72AF, 0xB7B9, 0x996D,
+	0xB7BA, 0x6CDB, 0xB7BB, 0x574A, 0xB7BC, 0x82B3, 0xB7BD, 0x65B9,
+	0xB7BE, 0x80AA, 0xB7BF, 0x623F, 0xB7C0, 0x9632, 0xB7C1, 0x59A8,
+	0xB7C2, 0x4EFF, 0xB7C3, 0x8BBF, 0xB7C4, 0x7EBA, 0xB7C5, 0x653E,
+	0xB7C6, 0x83F2, 0xB7C7, 0x975E, 0xB7C8, 0x5561, 0xB7C9, 0x98DE,
+	0xB7CA, 0x80A5, 0xB7CB, 0x532A, 0xB7CC, 0x8BFD, 0xB7CD, 0x5420,
+	0xB7CE, 0x80BA, 0xB7CF, 0x5E9F, 0xB7D0, 0x6CB8, 0xB7D1, 0x8D39,
+	0xB7D2, 0x82AC, 0xB7D3, 0x915A, 0xB7D4, 0x5429, 0xB7D5, 0x6C1B,
+	0xB7D6, 0x5206, 0xB7D7, 0x7EB7, 0xB7D8, 0x575F, 0xB7D9, 0x711A,
+	0xB7DA, 0x6C7E, 0xB7DB, 0x7C89, 0xB7DC, 0x594B, 0xB7DD, 0x4EFD,
+	0xB7DE, 0x5FFF, 0xB7DF, 0x6124, 0xB7E0, 0x7CAA, 0xB7E1, 0x4E30,
+	0xB7E2, 0x5C01, 0xB7E3, 0x67AB, 0xB7E4, 0x8702, 0xB7E5, 0x5CF0,
+	0xB7E6, 0x950B, 0xB7E7, 0x98CE, 0xB7E8, 0x75AF, 0xB7E9, 0x70FD,
+	0xB7EA, 0x9022, 0xB7EB, 0x51AF, 0xB7EC, 0x7F1D, 0xB7ED, 0x8BBD,
+	0xB7EE, 0x5949, 0xB7EF, 0x51E4, 0xB7F0, 0x4F5B, 0xB7F1, 0x5426,
+	0xB7F2, 0x592B, 0xB7F3, 0x6577, 0xB7F4, 0x80A4, 0xB7F5, 0x5B75,
+	0xB7F6, 0x6276, 0xB7F7, 0x62C2, 0xB7F8, 0x8F90, 0xB7F9, 0x5E45,
+	0xB7FA, 0x6C1F, 0xB7FB, 0x7B26, 0xB7FC, 0x4F0F, 0xB7FD, 0x4FD8,
+	0xB7FE, 0x670D, 0xB840, 0x7AA3, 0xB841, 0x7AA4, 0xB842, 0x7AA7,
+	0xB843, 0x7AA9, 0xB844, 0x7AAA, 0xB845, 0x7AAB, 0xB846, 0x7AAE,
+	0xB847, 0x7AAF, 0xB848, 0x7AB0, 0xB849, 0x7AB1, 0xB84A, 0x7AB2,
+	0xB84B, 0x7AB4, 0xB84C, 0x7AB5, 0xB84D, 0x7AB6, 0xB84E, 0x7AB7,
+	0xB84F, 0x7AB8, 0xB850, 0x7AB9, 0xB851, 0x7ABA, 0xB852, 0x7ABB,
+	0xB853, 0x7ABC, 0xB854, 0x7ABD, 0xB855, 0x7ABE, 0xB856, 0x7AC0,
+	0xB857, 0x7AC1, 0xB858, 0x7AC2, 0xB859, 0x7AC3, 0xB85A, 0x7AC4,
+	0xB85B, 0x7AC5, 0xB85C, 0x7AC6, 0xB85D, 0x7AC7, 0xB85E, 0x7AC8,
+	0xB85F, 0x7AC9, 0xB860, 0x7ACA, 0xB861, 0x7ACC, 0xB862, 0x7ACD,
+	0xB863, 0x7ACE, 0xB864, 0x7ACF, 0xB865, 0x7AD0, 0xB866, 0x7AD1,
+	0xB867, 0x7AD2, 0xB868, 0x7AD3, 0xB869, 0x7AD4, 0xB86A, 0x7AD5,
+	0xB86B, 0x7AD7, 0xB86C, 0x7AD8, 0xB86D, 0x7ADA, 0xB86E, 0x7ADB,
+	0xB86F, 0x7ADC, 0xB870, 0x7ADD, 0xB871, 0x7AE1, 0xB872, 0x7AE2,
+	0xB873, 0x7AE4, 0xB874, 0x7AE7, 0xB875, 0x7AE8, 0xB876, 0x7AE9,
+	0xB877, 0x7AEA, 0xB878, 0x7AEB, 0xB879, 0x7AEC, 0xB87A, 0x7AEE,
+	0xB87B, 0x7AF0, 0xB87C, 0x7AF1, 0xB87D, 0x7AF2, 0xB87E, 0x7AF3,
+	0xB880, 0x7AF4, 0xB881, 0x7AF5, 0xB882, 0x7AF6, 0xB883, 0x7AF7,
+	0xB884, 0x7AF8, 0xB885, 0x7AFB, 0xB886, 0x7AFC, 0xB887, 0x7AFE,
+	0xB888, 0x7B00, 0xB889, 0x7B01, 0xB88A, 0x7B02, 0xB88B, 0x7B05,
+	0xB88C, 0x7B07, 0xB88D, 0x7B09, 0xB88E, 0x7B0C, 0xB88F, 0x7B0D,
+	0xB890, 0x7B0E, 0xB891, 0x7B10, 0xB892, 0x7B12, 0xB893, 0x7B13,
+	0xB894, 0x7B16, 0xB895, 0x7B17, 0xB896, 0x7B18, 0xB897, 0x7B1A,
+	0xB898, 0x7B1C, 0xB899, 0x7B1D, 0xB89A, 0x7B1F, 0xB89B, 0x7B21,
+	0xB89C, 0x7B22, 0xB89D, 0x7B23, 0xB89E, 0x7B27, 0xB89F, 0x7B29,
+	0xB8A0, 0x7B2D, 0xB8A1, 0x6D6E, 0xB8A2, 0x6DAA, 0xB8A3, 0x798F,
+	0xB8A4, 0x88B1, 0xB8A5, 0x5F17, 0xB8A6, 0x752B, 0xB8A7, 0x629A,
+	0xB8A8, 0x8F85, 0xB8A9, 0x4FEF, 0xB8AA, 0x91DC, 0xB8AB, 0x65A7,
+	0xB8AC, 0x812F, 0xB8AD, 0x8151, 0xB8AE, 0x5E9C, 0xB8AF, 0x8150,
+	0xB8B0, 0x8D74, 0xB8B1, 0x526F, 0xB8B2, 0x8986, 0xB8B3, 0x8D4B,
+	0xB8B4, 0x590D, 0xB8B5, 0x5085, 0xB8B6, 0x4ED8, 0xB8B7, 0x961C,
+	0xB8B8, 0x7236, 0xB8B9, 0x8179, 0xB8BA, 0x8D1F, 0xB8BB, 0x5BCC,
+	0xB8BC, 0x8BA3, 0xB8BD, 0x9644, 0xB8BE, 0x5987, 0xB8BF, 0x7F1A,
+	0xB8C0, 0x5490, 0xB8C1, 0x5676, 0xB8C2, 0x560E, 0xB8C3, 0x8BE5,
+	0xB8C4, 0x6539, 0xB8C5, 0x6982, 0xB8C6, 0x9499, 0xB8C7, 0x76D6,
+	0xB8C8, 0x6E89, 0xB8C9, 0x5E72, 0xB8CA, 0x7518, 0xB8CB, 0x6746,
+	0xB8CC, 0x67D1, 0xB8CD, 0x7AFF, 0xB8CE, 0x809D, 0xB8CF, 0x8D76,
+	0xB8D0, 0x611F, 0xB8D1, 0x79C6, 0xB8D2, 0x6562, 0xB8D3, 0x8D63,
+	0xB8D4, 0x5188, 0xB8D5, 0x521A, 0xB8D6, 0x94A2, 0xB8D7, 0x7F38,
+	0xB8D8, 0x809B, 0xB8D9, 0x7EB2, 0xB8DA, 0x5C97, 0xB8DB, 0x6E2F,
+	0xB8DC, 0x6760, 0xB8DD, 0x7BD9, 0xB8DE, 0x768B, 0xB8DF, 0x9AD8,
+	0xB8E0, 0x818F, 0xB8E1, 0x7F94, 0xB8E2, 0x7CD5, 0xB8E3, 0x641E,
+	0xB8E4, 0x9550, 0xB8E5, 0x7A3F, 0xB8E6, 0x544A, 0xB8E7, 0x54E5,
+	0xB8E8, 0x6B4C, 0xB8E9, 0x6401, 0xB8EA, 0x6208, 0xB8EB, 0x9E3D,
+	0xB8EC, 0x80F3, 0xB8ED, 0x7599, 0xB8EE, 0x5272, 0xB8EF, 0x9769,
+	0xB8F0, 0x845B, 0xB8F1, 0x683C, 0xB8F2, 0x86E4, 0xB8F3, 0x9601,
+	0xB8F4, 0x9694, 0xB8F5, 0x94EC, 0xB8F6, 0x4E2A, 0xB8F7, 0x5404,
+	0xB8F8, 0x7ED9, 0xB8F9, 0x6839, 0xB8FA, 0x8DDF, 0xB8FB, 0x8015,
+	0xB8FC, 0x66F4, 0xB8FD, 0x5E9A, 0xB8FE, 0x7FB9, 0xB940, 0x7B2F,
+	0xB941, 0x7B30, 0xB942, 0x7B32, 0xB943, 0x7B34, 0xB944, 0x7B35,
+	0xB945, 0x7B36, 0xB946, 0x7B37, 0xB947, 0x7B39, 0xB948, 0x7B3B,
+	0xB949, 0x7B3D, 0xB94A, 0x7B3F, 0xB94B, 0x7B40, 0xB94C, 0x7B41,
+	0xB94D, 0x7B42, 0xB94E, 0x7B43, 0xB94F, 0x7B44, 0xB950, 0x7B46,
+	0xB951, 0x7B48, 0xB952, 0x7B4A, 0xB953, 0x7B4D, 0xB954, 0x7B4E,
+	0xB955, 0x7B53, 0xB956, 0x7B55, 0xB957, 0x7B57, 0xB958, 0x7B59,
+	0xB959, 0x7B5C, 0xB95A, 0x7B5E, 0xB95B, 0x7B5F, 0xB95C, 0x7B61,
+	0xB95D, 0x7B63, 0xB95E, 0x7B64, 0xB95F, 0x7B65, 0xB960, 0x7B66,
+	0xB961, 0x7B67, 0xB962, 0x7B68, 0xB963, 0x7B69, 0xB964, 0x7B6A,
+	0xB965, 0x7B6B, 0xB966, 0x7B6C, 0xB967, 0x7B6D, 0xB968, 0x7B6F,
+	0xB969, 0x7B70, 0xB96A, 0x7B73, 0xB96B, 0x7B74, 0xB96C, 0x7B76,
+	0xB96D, 0x7B78, 0xB96E, 0x7B7A, 0xB96F, 0x7B7C, 0xB970, 0x7B7D,
+	0xB971, 0x7B7F, 0xB972, 0x7B81, 0xB973, 0x7B82, 0xB974, 0x7B83,
+	0xB975, 0x7B84, 0xB976, 0x7B86, 0xB977, 0x7B87, 0xB978, 0x7B88,
+	0xB979, 0x7B89, 0xB97A, 0x7B8A, 0xB97B, 0x7B8B, 0xB97C, 0x7B8C,
+	0xB97D, 0x7B8E, 0xB97E, 0x7B8F, 0xB980, 0x7B91, 0xB981, 0x7B92,
+	0xB982, 0x7B93, 0xB983, 0x7B96, 0xB984, 0x7B98, 0xB985, 0x7B99,
+	0xB986, 0x7B9A, 0xB987, 0x7B9B, 0xB988, 0x7B9E, 0xB989, 0x7B9F,
+	0xB98A, 0x7BA0, 0xB98B, 0x7BA3, 0xB98C, 0x7BA4, 0xB98D, 0x7BA5,
+	0xB98E, 0x7BAE, 0xB98F, 0x7BAF, 0xB990, 0x7BB0, 0xB991, 0x7BB2,
+	0xB992, 0x7BB3, 0xB993, 0x7BB5, 0xB994, 0x7BB6, 0xB995, 0x7BB7,
+	0xB996, 0x7BB9, 0xB997, 0x7BBA, 0xB998, 0x7BBB, 0xB999, 0x7BBC,
+	0xB99A, 0x7BBD, 0xB99B, 0x7BBE, 0xB99C, 0x7BBF, 0xB99D, 0x7BC0,
+	0xB99E, 0x7BC2, 0xB99F, 0x7BC3, 0xB9A0, 0x7BC4, 0xB9A1, 0x57C2,
+	0xB9A2, 0x803F, 0xB9A3, 0x6897, 0xB9A4, 0x5DE5, 0xB9A5, 0x653B,
+	0xB9A6, 0x529F, 0xB9A7, 0x606D, 0xB9A8, 0x9F9A, 0xB9A9, 0x4F9B,
+	0xB9AA, 0x8EAC, 0xB9AB, 0x516C, 0xB9AC, 0x5BAB, 0xB9AD, 0x5F13,
+	0xB9AE, 0x5DE9, 0xB9AF, 0x6C5E, 0xB9B0, 0x62F1, 0xB9B1, 0x8D21,
+	0xB9B2, 0x5171, 0xB9B3, 0x94A9, 0xB9B4, 0x52FE, 0xB9B5, 0x6C9F,
+	0xB9B6, 0x82DF, 0xB9B7, 0x72D7, 0xB9B8, 0x57A2, 0xB9B9, 0x6784,
+	0xB9BA, 0x8D2D, 0xB9BB, 0x591F, 0xB9BC, 0x8F9C, 0xB9BD, 0x83C7,
+	0xB9BE, 0x5495, 0xB9BF, 0x7B8D, 0xB9C0, 0x4F30, 0xB9C1, 0x6CBD,
+	0xB9C2, 0x5B64, 0xB9C3, 0x59D1, 0xB9C4, 0x9F13, 0xB9C5, 0x53E4,
+	0xB9C6, 0x86CA, 0xB9C7, 0x9AA8, 0xB9C8, 0x8C37, 0xB9C9, 0x80A1,
+	0xB9CA, 0x6545, 0xB9CB, 0x987E, 0xB9CC, 0x56FA, 0xB9CD, 0x96C7,
+	0xB9CE, 0x522E, 0xB9CF, 0x74DC, 0xB9D0, 0x5250, 0xB9D1, 0x5BE1,
+	0xB9D2, 0x6302, 0xB9D3, 0x8902, 0xB9D4, 0x4E56, 0xB9D5, 0x62D0,
+	0xB9D6, 0x602A, 0xB9D7, 0x68FA, 0xB9D8, 0x5173, 0xB9D9, 0x5B98,
+	0xB9DA, 0x51A0, 0xB9DB, 0x89C2, 0xB9DC, 0x7BA1, 0xB9DD, 0x9986,
+	0xB9DE, 0x7F50, 0xB9DF, 0x60EF, 0xB9E0, 0x704C, 0xB9E1, 0x8D2F,
+	0xB9E2, 0x5149, 0xB9E3, 0x5E7F, 0xB9E4, 0x901B, 0xB9E5, 0x7470,
+	0xB9E6, 0x89C4, 0xB9E7, 0x572D, 0xB9E8, 0x7845, 0xB9E9, 0x5F52,
+	0xB9EA, 0x9F9F, 0xB9EB, 0x95FA, 0xB9EC, 0x8F68, 0xB9ED, 0x9B3C,
+	0xB9EE, 0x8BE1, 0xB9EF, 0x7678, 0xB9F0, 0x6842, 0xB9F1, 0x67DC,
+	0xB9F2, 0x8DEA, 0xB9F3, 0x8D35, 0xB9F4, 0x523D, 0xB9F5, 0x8F8A,
+	0xB9F6, 0x6EDA, 0xB9F7, 0x68CD, 0xB9F8, 0x9505, 0xB9F9, 0x90ED,
+	0xB9FA, 0x56FD, 0xB9FB, 0x679C, 0xB9FC, 0x88F9, 0xB9FD, 0x8FC7,
+	0xB9FE, 0x54C8, 0xBA40, 0x7BC5, 0xBA41, 0x7BC8, 0xBA42, 0x7BC9,
+	0xBA43, 0x7BCA, 0xBA44, 0x7BCB, 0xBA45, 0x7BCD, 0xBA46, 0x7BCE,
+	0xBA47, 0x7BCF, 0xBA48, 0x7BD0, 0xBA49, 0x7BD2, 0xBA4A, 0x7BD4,
+	0xBA4B, 0x7BD5, 0xBA4C, 0x7BD6, 0xBA4D, 0x7BD7, 0xBA4E, 0x7BD8,
+	0xBA4F, 0x7BDB, 0xBA50, 0x7BDC, 0xBA51, 0x7BDE, 0xBA52, 0x7BDF,
+	0xBA53, 0x7BE0, 0xBA54, 0x7BE2, 0xBA55, 0x7BE3, 0xBA56, 0x7BE4,
+	0xBA57, 0x7BE7, 0xBA58, 0x7BE8, 0xBA59, 0x7BE9, 0xBA5A, 0x7BEB,
+	0xBA5B, 0x7BEC, 0xBA5C, 0x7BED, 0xBA5D, 0x7BEF, 0xBA5E, 0x7BF0,
+	0xBA5F, 0x7BF2, 0xBA60, 0x7BF3, 0xBA61, 0x7BF4, 0xBA62, 0x7BF5,
+	0xBA63, 0x7BF6, 0xBA64, 0x7BF8, 0xBA65, 0x7BF9, 0xBA66, 0x7BFA,
+	0xBA67, 0x7BFB, 0xBA68, 0x7BFD, 0xBA69, 0x7BFF, 0xBA6A, 0x7C00,
+	0xBA6B, 0x7C01, 0xBA6C, 0x7C02, 0xBA6D, 0x7C03, 0xBA6E, 0x7C04,
+	0xBA6F, 0x7C05, 0xBA70, 0x7C06, 0xBA71, 0x7C08, 0xBA72, 0x7C09,
+	0xBA73, 0x7C0A, 0xBA74, 0x7C0D, 0xBA75, 0x7C0E, 0xBA76, 0x7C10,
+	0xBA77, 0x7C11, 0xBA78, 0x7C12, 0xBA79, 0x7C13, 0xBA7A, 0x7C14,
+	0xBA7B, 0x7C15, 0xBA7C, 0x7C17, 0xBA7D, 0x7C18, 0xBA7E, 0x7C19,
+	0xBA80, 0x7C1A, 0xBA81, 0x7C1B, 0xBA82, 0x7C1C, 0xBA83, 0x7C1D,
+	0xBA84, 0x7C1E, 0xBA85, 0x7C20, 0xBA86, 0x7C21, 0xBA87, 0x7C22,
+	0xBA88, 0x7C23, 0xBA89, 0x7C24, 0xBA8A, 0x7C25, 0xBA8B, 0x7C28,
+	0xBA8C, 0x7C29, 0xBA8D, 0x7C2B, 0xBA8E, 0x7C2C, 0xBA8F, 0x7C2D,
+	0xBA90, 0x7C2E, 0xBA91, 0x7C2F, 0xBA92, 0x7C30, 0xBA93, 0x7C31,
+	0xBA94, 0x7C32, 0xBA95, 0x7C33, 0xBA96, 0x7C34, 0xBA97, 0x7C35,
+	0xBA98, 0x7C36, 0xBA99, 0x7C37, 0xBA9A, 0x7C39, 0xBA9B, 0x7C3A,
+	0xBA9C, 0x7C3B, 0xBA9D, 0x7C3C, 0xBA9E, 0x7C3D, 0xBA9F, 0x7C3E,
+	0xBAA0, 0x7C42, 0xBAA1, 0x9AB8, 0xBAA2, 0x5B69, 0xBAA3, 0x6D77,
+	0xBAA4, 0x6C26, 0xBAA5, 0x4EA5, 0xBAA6, 0x5BB3, 0xBAA7, 0x9A87,
+	0xBAA8, 0x9163, 0xBAA9, 0x61A8, 0xBAAA, 0x90AF, 0xBAAB, 0x97E9,
+	0xBAAC, 0x542B, 0xBAAD, 0x6DB5, 0xBAAE, 0x5BD2, 0xBAAF, 0x51FD,
+	0xBAB0, 0x558A, 0xBAB1, 0x7F55, 0xBAB2, 0x7FF0, 0xBAB3, 0x64BC,
+	0xBAB4, 0x634D, 0xBAB5, 0x65F1, 0xBAB6, 0x61BE, 0xBAB7, 0x608D,
+	0xBAB8, 0x710A, 0xBAB9, 0x6C57, 0xBABA, 0x6C49, 0xBABB, 0x592F,
+	0xBABC, 0x676D, 0xBABD, 0x822A, 0xBABE, 0x58D5, 0xBABF, 0x568E,
+	0xBAC0, 0x8C6A, 0xBAC1, 0x6BEB, 0xBAC2, 0x90DD, 0xBAC3, 0x597D,
+	0xBAC4, 0x8017, 0xBAC5, 0x53F7, 0xBAC6, 0x6D69, 0xBAC7, 0x5475,
+	0xBAC8, 0x559D, 0xBAC9, 0x8377, 0xBACA, 0x83CF, 0xBACB, 0x6838,
+	0xBACC, 0x79BE, 0xBACD, 0x548C, 0xBACE, 0x4F55, 0xBACF, 0x5408,
+	0xBAD0, 0x76D2, 0xBAD1, 0x8C89, 0xBAD2, 0x9602, 0xBAD3, 0x6CB3,
+	0xBAD4, 0x6DB8, 0xBAD5, 0x8D6B, 0xBAD6, 0x8910, 0xBAD7, 0x9E64,
+	0xBAD8, 0x8D3A, 0xBAD9, 0x563F, 0xBADA, 0x9ED1, 0xBADB, 0x75D5,
+	0xBADC, 0x5F88, 0xBADD, 0x72E0, 0xBADE, 0x6068, 0xBADF, 0x54FC,
+	0xBAE0, 0x4EA8, 0xBAE1, 0x6A2A, 0xBAE2, 0x8861, 0xBAE3, 0x6052,
+	0xBAE4, 0x8F70, 0xBAE5, 0x54C4, 0xBAE6, 0x70D8, 0xBAE7, 0x8679,
+	0xBAE8, 0x9E3F, 0xBAE9, 0x6D2A, 0xBAEA, 0x5B8F, 0xBAEB, 0x5F18,
+	0xBAEC, 0x7EA2, 0xBAED, 0x5589, 0xBAEE, 0x4FAF, 0xBAEF, 0x7334,
+	0xBAF0, 0x543C, 0xBAF1, 0x539A, 0xBAF2, 0x5019, 0xBAF3, 0x540E,
+	0xBAF4, 0x547C, 0xBAF5, 0x4E4E, 0xBAF6, 0x5FFD, 0xBAF7, 0x745A,
+	0xBAF8, 0x58F6, 0xBAF9, 0x846B, 0xBAFA, 0x80E1, 0xBAFB, 0x8774,
+	0xBAFC, 0x72D0, 0xBAFD, 0x7CCA, 0xBAFE, 0x6E56, 0xBB40, 0x7C43,
+	0xBB41, 0x7C44, 0xBB42, 0x7C45, 0xBB43, 0x7C46, 0xBB44, 0x7C47,
+	0xBB45, 0x7C48, 0xBB46, 0x7C49, 0xBB47, 0x7C4A, 0xBB48, 0x7C4B,
+	0xBB49, 0x7C4C, 0xBB4A, 0x7C4E, 0xBB4B, 0x7C4F, 0xBB4C, 0x7C50,
+	0xBB4D, 0x7C51, 0xBB4E, 0x7C52, 0xBB4F, 0x7C53, 0xBB50, 0x7C54,
+	0xBB51, 0x7C55, 0xBB52, 0x7C56, 0xBB53, 0x7C57, 0xBB54, 0x7C58,
+	0xBB55, 0x7C59, 0xBB56, 0x7C5A, 0xBB57, 0x7C5B, 0xBB58, 0x7C5C,
+	0xBB59, 0x7C5D, 0xBB5A, 0x7C5E, 0xBB5B, 0x7C5F, 0xBB5C, 0x7C60,
+	0xBB5D, 0x7C61, 0xBB5E, 0x7C62, 0xBB5F, 0x7C63, 0xBB60, 0x7C64,
+	0xBB61, 0x7C65, 0xBB62, 0x7C66, 0xBB63, 0x7C67, 0xBB64, 0x7C68,
+	0xBB65, 0x7C69, 0xBB66, 0x7C6A, 0xBB67, 0x7C6B, 0xBB68, 0x7C6C,
+	0xBB69, 0x7C6D, 0xBB6A, 0x7C6E, 0xBB6B, 0x7C6F, 0xBB6C, 0x7C70,
+	0xBB6D, 0x7C71, 0xBB6E, 0x7C72, 0xBB6F, 0x7C75, 0xBB70, 0x7C76,
+	0xBB71, 0x7C77, 0xBB72, 0x7C78, 0xBB73, 0x7C79, 0xBB74, 0x7C7A,
+	0xBB75, 0x7C7E, 0xBB76, 0x7C7F, 0xBB77, 0x7C80, 0xBB78, 0x7C81,
+	0xBB79, 0x7C82, 0xBB7A, 0x7C83, 0xBB7B, 0x7C84, 0xBB7C, 0x7C85,
+	0xBB7D, 0x7C86, 0xBB7E, 0x7C87, 0xBB80, 0x7C88, 0xBB81, 0x7C8A,
+	0xBB82, 0x7C8B, 0xBB83, 0x7C8C, 0xBB84, 0x7C8D, 0xBB85, 0x7C8E,
+	0xBB86, 0x7C8F, 0xBB87, 0x7C90, 0xBB88, 0x7C93, 0xBB89, 0x7C94,
+	0xBB8A, 0x7C96, 0xBB8B, 0x7C99, 0xBB8C, 0x7C9A, 0xBB8D, 0x7C9B,
+	0xBB8E, 0x7CA0, 0xBB8F, 0x7CA1, 0xBB90, 0x7CA3, 0xBB91, 0x7CA6,
+	0xBB92, 0x7CA7, 0xBB93, 0x7CA8, 0xBB94, 0x7CA9, 0xBB95, 0x7CAB,
+	0xBB96, 0x7CAC, 0xBB97, 0x7CAD, 0xBB98, 0x7CAF, 0xBB99, 0x7CB0,
+	0xBB9A, 0x7CB4, 0xBB9B, 0x7CB5, 0xBB9C, 0x7CB6, 0xBB9D, 0x7CB7,
+	0xBB9E, 0x7CB8, 0xBB9F, 0x7CBA, 0xBBA0, 0x7CBB, 0xBBA1, 0x5F27,
+	0xBBA2, 0x864E, 0xBBA3, 0x552C, 0xBBA4, 0x62A4, 0xBBA5, 0x4E92,
+	0xBBA6, 0x6CAA, 0xBBA7, 0x6237, 0xBBA8, 0x82B1, 0xBBA9, 0x54D7,
+	0xBBAA, 0x534E, 0xBBAB, 0x733E, 0xBBAC, 0x6ED1, 0xBBAD, 0x753B,
+	0xBBAE, 0x5212, 0xBBAF, 0x5316, 0xBBB0, 0x8BDD, 0xBBB1, 0x69D0,
+	0xBBB2, 0x5F8A, 0xBBB3, 0x6000, 0xBBB4, 0x6DEE, 0xBBB5, 0x574F,
+	0xBBB6, 0x6B22, 0xBBB7, 0x73AF, 0xBBB8, 0x6853, 0xBBB9, 0x8FD8,
+	0xBBBA, 0x7F13, 0xBBBB, 0x6362, 0xBBBC, 0x60A3, 0xBBBD, 0x5524,
+	0xBBBE, 0x75EA, 0xBBBF, 0x8C62, 0xBBC0, 0x7115, 0xBBC1, 0x6DA3,
+	0xBBC2, 0x5BA6, 0xBBC3, 0x5E7B, 0xBBC4, 0x8352, 0xBBC5, 0x614C,
+	0xBBC6, 0x9EC4, 0xBBC7, 0x78FA, 0xBBC8, 0x8757, 0xBBC9, 0x7C27,
+	0xBBCA, 0x7687, 0xBBCB, 0x51F0, 0xBBCC, 0x60F6, 0xBBCD, 0x714C,
+	0xBBCE, 0x6643, 0xBBCF, 0x5E4C, 0xBBD0, 0x604D, 0xBBD1, 0x8C0E,
+	0xBBD2, 0x7070, 0xBBD3, 0x6325, 0xBBD4, 0x8F89, 0xBBD5, 0x5FBD,
+	0xBBD6, 0x6062, 0xBBD7, 0x86D4, 0xBBD8, 0x56DE, 0xBBD9, 0x6BC1,
+	0xBBDA, 0x6094, 0xBBDB, 0x6167, 0xBBDC, 0x5349, 0xBBDD, 0x60E0,
+	0xBBDE, 0x6666, 0xBBDF, 0x8D3F, 0xBBE0, 0x79FD, 0xBBE1, 0x4F1A,
+	0xBBE2, 0x70E9, 0xBBE3, 0x6C47, 0xBBE4, 0x8BB3, 0xBBE5, 0x8BF2,
+	0xBBE6, 0x7ED8, 0xBBE7, 0x8364, 0xBBE8, 0x660F, 0xBBE9, 0x5A5A,
+	0xBBEA, 0x9B42, 0xBBEB, 0x6D51, 0xBBEC, 0x6DF7, 0xBBED, 0x8C41,
+	0xBBEE, 0x6D3B, 0xBBEF, 0x4F19, 0xBBF0, 0x706B, 0xBBF1, 0x83B7,
+	0xBBF2, 0x6216, 0xBBF3, 0x60D1, 0xBBF4, 0x970D, 0xBBF5, 0x8D27,
+	0xBBF6, 0x7978, 0xBBF7, 0x51FB, 0xBBF8, 0x573E, 0xBBF9, 0x57FA,
+	0xBBFA, 0x673A, 0xBBFB, 0x7578, 0xBBFC, 0x7A3D, 0xBBFD, 0x79EF,
+	0xBBFE, 0x7B95, 0xBC40, 0x7CBF, 0xBC41, 0x7CC0, 0xBC42, 0x7CC2,
+	0xBC43, 0x7CC3, 0xBC44, 0x7CC4, 0xBC45, 0x7CC6, 0xBC46, 0x7CC9,
+	0xBC47, 0x7CCB, 0xBC48, 0x7CCE, 0xBC49, 0x7CCF, 0xBC4A, 0x7CD0,
+	0xBC4B, 0x7CD1, 0xBC4C, 0x7CD2, 0xBC4D, 0x7CD3, 0xBC4E, 0x7CD4,
+	0xBC4F, 0x7CD8, 0xBC50, 0x7CDA, 0xBC51, 0x7CDB, 0xBC52, 0x7CDD,
+	0xBC53, 0x7CDE, 0xBC54, 0x7CE1, 0xBC55, 0x7CE2, 0xBC56, 0x7CE3,
+	0xBC57, 0x7CE4, 0xBC58, 0x7CE5, 0xBC59, 0x7CE6, 0xBC5A, 0x7CE7,
+	0xBC5B, 0x7CE9, 0xBC5C, 0x7CEA, 0xBC5D, 0x7CEB, 0xBC5E, 0x7CEC,
+	0xBC5F, 0x7CED, 0xBC60, 0x7CEE, 0xBC61, 0x7CF0, 0xBC62, 0x7CF1,
+	0xBC63, 0x7CF2, 0xBC64, 0x7CF3, 0xBC65, 0x7CF4, 0xBC66, 0x7CF5,
+	0xBC67, 0x7CF6, 0xBC68, 0x7CF7, 0xBC69, 0x7CF9, 0xBC6A, 0x7CFA,
+	0xBC6B, 0x7CFC, 0xBC6C, 0x7CFD, 0xBC6D, 0x7CFE, 0xBC6E, 0x7CFF,
+	0xBC6F, 0x7D00, 0xBC70, 0x7D01, 0xBC71, 0x7D02, 0xBC72, 0x7D03,
+	0xBC73, 0x7D04, 0xBC74, 0x7D05, 0xBC75, 0x7D06, 0xBC76, 0x7D07,
+	0xBC77, 0x7D08, 0xBC78, 0x7D09, 0xBC79, 0x7D0B, 0xBC7A, 0x7D0C,
+	0xBC7B, 0x7D0D, 0xBC7C, 0x7D0E, 0xBC7D, 0x7D0F, 0xBC7E, 0x7D10,
+	0xBC80, 0x7D11, 0xBC81, 0x7D12, 0xBC82, 0x7D13, 0xBC83, 0x7D14,
+	0xBC84, 0x7D15, 0xBC85, 0x7D16, 0xBC86, 0x7D17, 0xBC87, 0x7D18,
+	0xBC88, 0x7D19, 0xBC89, 0x7D1A, 0xBC8A, 0x7D1B, 0xBC8B, 0x7D1C,
+	0xBC8C, 0x7D1D, 0xBC8D, 0x7D1E, 0xBC8E, 0x7D1F, 0xBC8F, 0x7D21,
+	0xBC90, 0x7D23, 0xBC91, 0x7D24, 0xBC92, 0x7D25, 0xBC93, 0x7D26,
+	0xBC94, 0x7D28, 0xBC95, 0x7D29, 0xBC96, 0x7D2A, 0xBC97, 0x7D2C,
+	0xBC98, 0x7D2D, 0xBC99, 0x7D2E, 0xBC9A, 0x7D30, 0xBC9B, 0x7D31,
+	0xBC9C, 0x7D32, 0xBC9D, 0x7D33, 0xBC9E, 0x7D34, 0xBC9F, 0x7D35,
+	0xBCA0, 0x7D36, 0xBCA1, 0x808C, 0xBCA2, 0x9965, 0xBCA3, 0x8FF9,
+	0xBCA4, 0x6FC0, 0xBCA5, 0x8BA5, 0xBCA6, 0x9E21, 0xBCA7, 0x59EC,
+	0xBCA8, 0x7EE9, 0xBCA9, 0x7F09, 0xBCAA, 0x5409, 0xBCAB, 0x6781,
+	0xBCAC, 0x68D8, 0xBCAD, 0x8F91, 0xBCAE, 0x7C4D, 0xBCAF, 0x96C6,
+	0xBCB0, 0x53CA, 0xBCB1, 0x6025, 0xBCB2, 0x75BE, 0xBCB3, 0x6C72,
+	0xBCB4, 0x5373, 0xBCB5, 0x5AC9, 0xBCB6, 0x7EA7, 0xBCB7, 0x6324,
+	0xBCB8, 0x51E0, 0xBCB9, 0x810A, 0xBCBA, 0x5DF1, 0xBCBB, 0x84DF,
+	0xBCBC, 0x6280, 0xBCBD, 0x5180, 0xBCBE, 0x5B63, 0xBCBF, 0x4F0E,
+	0xBCC0, 0x796D, 0xBCC1, 0x5242, 0xBCC2, 0x60B8, 0xBCC3, 0x6D4E,
+	0xBCC4, 0x5BC4, 0xBCC5, 0x5BC2, 0xBCC6, 0x8BA1, 0xBCC7, 0x8BB0,
+	0xBCC8, 0x65E2, 0xBCC9, 0x5FCC, 0xBCCA, 0x9645, 0xBCCB, 0x5993,
+	0xBCCC, 0x7EE7, 0xBCCD, 0x7EAA, 0xBCCE, 0x5609, 0xBCCF, 0x67B7,
+	0xBCD0, 0x5939, 0xBCD1, 0x4F73, 0xBCD2, 0x5BB6, 0xBCD3, 0x52A0,
+	0xBCD4, 0x835A, 0xBCD5, 0x988A, 0xBCD6, 0x8D3E, 0xBCD7, 0x7532,
+	0xBCD8, 0x94BE, 0xBCD9, 0x5047, 0xBCDA, 0x7A3C, 0xBCDB, 0x4EF7,
+	0xBCDC, 0x67B6, 0xBCDD, 0x9A7E, 0xBCDE, 0x5AC1, 0xBCDF, 0x6B7C,
+	0xBCE0, 0x76D1, 0xBCE1, 0x575A, 0xBCE2, 0x5C16, 0xBCE3, 0x7B3A,
+	0xBCE4, 0x95F4, 0xBCE5, 0x714E, 0xBCE6, 0x517C, 0xBCE7, 0x80A9,
+	0xBCE8, 0x8270, 0xBCE9, 0x5978, 0xBCEA, 0x7F04, 0xBCEB, 0x8327,
+	0xBCEC, 0x68C0, 0xBCED, 0x67EC, 0xBCEE, 0x78B1, 0xBCEF, 0x7877,
+	0xBCF0, 0x62E3, 0xBCF1, 0x6361, 0xBCF2, 0x7B80, 0xBCF3, 0x4FED,
+	0xBCF4, 0x526A, 0xBCF5, 0x51CF, 0xBCF6, 0x8350, 0xBCF7, 0x69DB,
+	0xBCF8, 0x9274, 0xBCF9, 0x8DF5, 0xBCFA, 0x8D31, 0xBCFB, 0x89C1,
+	0xBCFC, 0x952E, 0xBCFD, 0x7BAD, 0xBCFE, 0x4EF6, 0xBD40, 0x7D37,
+	0xBD41, 0x7D38, 0xBD42, 0x7D39, 0xBD43, 0x7D3A, 0xBD44, 0x7D3B,
+	0xBD45, 0x7D3C, 0xBD46, 0x7D3D, 0xBD47, 0x7D3E, 0xBD48, 0x7D3F,
+	0xBD49, 0x7D40, 0xBD4A, 0x7D41, 0xBD4B, 0x7D42, 0xBD4C, 0x7D43,
+	0xBD4D, 0x7D44, 0xBD4E, 0x7D45, 0xBD4F, 0x7D46, 0xBD50, 0x7D47,
+	0xBD51, 0x7D48, 0xBD52, 0x7D49, 0xBD53, 0x7D4A, 0xBD54, 0x7D4B,
+	0xBD55, 0x7D4C, 0xBD56, 0x7D4D, 0xBD57, 0x7D4E, 0xBD58, 0x7D4F,
+	0xBD59, 0x7D50, 0xBD5A, 0x7D51, 0xBD5B, 0x7D52, 0xBD5C, 0x7D53,
+	0xBD5D, 0x7D54, 0xBD5E, 0x7D55, 0xBD5F, 0x7D56, 0xBD60, 0x7D57,
+	0xBD61, 0x7D58, 0xBD62, 0x7D59, 0xBD63, 0x7D5A, 0xBD64, 0x7D5B,
+	0xBD65, 0x7D5C, 0xBD66, 0x7D5D, 0xBD67, 0x7D5E, 0xBD68, 0x7D5F,
+	0xBD69, 0x7D60, 0xBD6A, 0x7D61, 0xBD6B, 0x7D62, 0xBD6C, 0x7D63,
+	0xBD6D, 0x7D64, 0xBD6E, 0x7D65, 0xBD6F, 0x7D66, 0xBD70, 0x7D67,
+	0xBD71, 0x7D68, 0xBD72, 0x7D69, 0xBD73, 0x7D6A, 0xBD74, 0x7D6B,
+	0xBD75, 0x7D6C, 0xBD76, 0x7D6D, 0xBD77, 0x7D6F, 0xBD78, 0x7D70,
+	0xBD79, 0x7D71, 0xBD7A, 0x7D72, 0xBD7B, 0x7D73, 0xBD7C, 0x7D74,
+	0xBD7D, 0x7D75, 0xBD7E, 0x7D76, 0xBD80, 0x7D78, 0xBD81, 0x7D79,
+	0xBD82, 0x7D7A, 0xBD83, 0x7D7B, 0xBD84, 0x7D7C, 0xBD85, 0x7D7D,
+	0xBD86, 0x7D7E, 0xBD87, 0x7D7F, 0xBD88, 0x7D80, 0xBD89, 0x7D81,
+	0xBD8A, 0x7D82, 0xBD8B, 0x7D83, 0xBD8C, 0x7D84, 0xBD8D, 0x7D85,
+	0xBD8E, 0x7D86, 0xBD8F, 0x7D87, 0xBD90, 0x7D88, 0xBD91, 0x7D89,
+	0xBD92, 0x7D8A, 0xBD93, 0x7D8B, 0xBD94, 0x7D8C, 0xBD95, 0x7D8D,
+	0xBD96, 0x7D8E, 0xBD97, 0x7D8F, 0xBD98, 0x7D90, 0xBD99, 0x7D91,
+	0xBD9A, 0x7D92, 0xBD9B, 0x7D93, 0xBD9C, 0x7D94, 0xBD9D, 0x7D95,
+	0xBD9E, 0x7D96, 0xBD9F, 0x7D97, 0xBDA0, 0x7D98, 0xBDA1, 0x5065,
+	0xBDA2, 0x8230, 0xBDA3, 0x5251, 0xBDA4, 0x996F, 0xBDA5, 0x6E10,
+	0xBDA6, 0x6E85, 0xBDA7, 0x6DA7, 0xBDA8, 0x5EFA, 0xBDA9, 0x50F5,
+	0xBDAA, 0x59DC, 0xBDAB, 0x5C06, 0xBDAC, 0x6D46, 0xBDAD, 0x6C5F,
+	0xBDAE, 0x7586, 0xBDAF, 0x848B, 0xBDB0, 0x6868, 0xBDB1, 0x5956,
+	0xBDB2, 0x8BB2, 0xBDB3, 0x5320, 0xBDB4, 0x9171, 0xBDB5, 0x964D,
+	0xBDB6, 0x8549, 0xBDB7, 0x6912, 0xBDB8, 0x7901, 0xBDB9, 0x7126,
+	0xBDBA, 0x80F6, 0xBDBB, 0x4EA4, 0xBDBC, 0x90CA, 0xBDBD, 0x6D47,
+	0xBDBE, 0x9A84, 0xBDBF, 0x5A07, 0xBDC0, 0x56BC, 0xBDC1, 0x6405,
+	0xBDC2, 0x94F0, 0xBDC3, 0x77EB, 0xBDC4, 0x4FA5, 0xBDC5, 0x811A,
+	0xBDC6, 0x72E1, 0xBDC7, 0x89D2, 0xBDC8, 0x997A, 0xBDC9, 0x7F34,
+	0xBDCA, 0x7EDE, 0xBDCB, 0x527F, 0xBDCC, 0x6559, 0xBDCD, 0x9175,
+	0xBDCE, 0x8F7F, 0xBDCF, 0x8F83, 0xBDD0, 0x53EB, 0xBDD1, 0x7A96,
+	0xBDD2, 0x63ED, 0xBDD3, 0x63A5, 0xBDD4, 0x7686, 0xBDD5, 0x79F8,
+	0xBDD6, 0x8857, 0xBDD7, 0x9636, 0xBDD8, 0x622A, 0xBDD9, 0x52AB,
+	0xBDDA, 0x8282, 0xBDDB, 0x6854, 0xBDDC, 0x6770, 0xBDDD, 0x6377,
+	0xBDDE, 0x776B, 0xBDDF, 0x7AED, 0xBDE0, 0x6D01, 0xBDE1, 0x7ED3,
+	0xBDE2, 0x89E3, 0xBDE3, 0x59D0, 0xBDE4, 0x6212, 0xBDE5, 0x85C9,
+	0xBDE6, 0x82A5, 0xBDE7, 0x754C, 0xBDE8, 0x501F, 0xBDE9, 0x4ECB,
+	0xBDEA, 0x75A5, 0xBDEB, 0x8BEB, 0xBDEC, 0x5C4A, 0xBDED, 0x5DFE,
+	0xBDEE, 0x7B4B, 0xBDEF, 0x65A4, 0xBDF0, 0x91D1, 0xBDF1, 0x4ECA,
+	0xBDF2, 0x6D25, 0xBDF3, 0x895F, 0xBDF4, 0x7D27, 0xBDF5, 0x9526,
+	0xBDF6, 0x4EC5, 0xBDF7, 0x8C28, 0xBDF8, 0x8FDB, 0xBDF9, 0x9773,
+	0xBDFA, 0x664B, 0xBDFB, 0x7981, 0xBDFC, 0x8FD1, 0xBDFD, 0x70EC,
+	0xBDFE, 0x6D78, 0xBE40, 0x7D99, 0xBE41, 0x7D9A, 0xBE42, 0x7D9B,
+	0xBE43, 0x7D9C, 0xBE44, 0x7D9D, 0xBE45, 0x7D9E, 0xBE46, 0x7D9F,
+	0xBE47, 0x7DA0, 0xBE48, 0x7DA1, 0xBE49, 0x7DA2, 0xBE4A, 0x7DA3,
+	0xBE4B, 0x7DA4, 0xBE4C, 0x7DA5, 0xBE4D, 0x7DA7, 0xBE4E, 0x7DA8,
+	0xBE4F, 0x7DA9, 0xBE50, 0x7DAA, 0xBE51, 0x7DAB, 0xBE52, 0x7DAC,
+	0xBE53, 0x7DAD, 0xBE54, 0x7DAF, 0xBE55, 0x7DB0, 0xBE56, 0x7DB1,
+	0xBE57, 0x7DB2, 0xBE58, 0x7DB3, 0xBE59, 0x7DB4, 0xBE5A, 0x7DB5,
+	0xBE5B, 0x7DB6, 0xBE5C, 0x7DB7, 0xBE5D, 0x7DB8, 0xBE5E, 0x7DB9,
+	0xBE5F, 0x7DBA, 0xBE60, 0x7DBB, 0xBE61, 0x7DBC, 0xBE62, 0x7DBD,
+	0xBE63, 0x7DBE, 0xBE64, 0x7DBF, 0xBE65, 0x7DC0, 0xBE66, 0x7DC1,
+	0xBE67, 0x7DC2, 0xBE68, 0x7DC3, 0xBE69, 0x7DC4, 0xBE6A, 0x7DC5,
+	0xBE6B, 0x7DC6, 0xBE6C, 0x7DC7, 0xBE6D, 0x7DC8, 0xBE6E, 0x7DC9,
+	0xBE6F, 0x7DCA, 0xBE70, 0x7DCB, 0xBE71, 0x7DCC, 0xBE72, 0x7DCD,
+	0xBE73, 0x7DCE, 0xBE74, 0x7DCF, 0xBE75, 0x7DD0, 0xBE76, 0x7DD1,
+	0xBE77, 0x7DD2, 0xBE78, 0x7DD3, 0xBE79, 0x7DD4, 0xBE7A, 0x7DD5,
+	0xBE7B, 0x7DD6, 0xBE7C, 0x7DD7, 0xBE7D, 0x7DD8, 0xBE7E, 0x7DD9,
+	0xBE80, 0x7DDA, 0xBE81, 0x7DDB, 0xBE82, 0x7DDC, 0xBE83, 0x7DDD,
+	0xBE84, 0x7DDE, 0xBE85, 0x7DDF, 0xBE86, 0x7DE0, 0xBE87, 0x7DE1,
+	0xBE88, 0x7DE2, 0xBE89, 0x7DE3, 0xBE8A, 0x7DE4, 0xBE8B, 0x7DE5,
+	0xBE8C, 0x7DE6, 0xBE8D, 0x7DE7, 0xBE8E, 0x7DE8, 0xBE8F, 0x7DE9,
+	0xBE90, 0x7DEA, 0xBE91, 0x7DEB, 0xBE92, 0x7DEC, 0xBE93, 0x7DED,
+	0xBE94, 0x7DEE, 0xBE95, 0x7DEF, 0xBE96, 0x7DF0, 0xBE97, 0x7DF1,
+	0xBE98, 0x7DF2, 0xBE99, 0x7DF3, 0xBE9A, 0x7DF4, 0xBE9B, 0x7DF5,
+	0xBE9C, 0x7DF6, 0xBE9D, 0x7DF7, 0xBE9E, 0x7DF8, 0xBE9F, 0x7DF9,
+	0xBEA0, 0x7DFA, 0xBEA1, 0x5C3D, 0xBEA2, 0x52B2, 0xBEA3, 0x8346,
+	0xBEA4, 0x5162, 0xBEA5, 0x830E, 0xBEA6, 0x775B, 0xBEA7, 0x6676,
+	0xBEA8, 0x9CB8, 0xBEA9, 0x4EAC, 0xBEAA, 0x60CA, 0xBEAB, 0x7CBE,
+	0xBEAC, 0x7CB3, 0xBEAD, 0x7ECF, 0xBEAE, 0x4E95, 0xBEAF, 0x8B66,
+	0xBEB0, 0x666F, 0xBEB1, 0x9888, 0xBEB2, 0x9759, 0xBEB3, 0x5883,
+	0xBEB4, 0x656C, 0xBEB5, 0x955C, 0xBEB6, 0x5F84, 0xBEB7, 0x75C9,
+	0xBEB8, 0x9756, 0xBEB9, 0x7ADF, 0xBEBA, 0x7ADE, 0xBEBB, 0x51C0,
+	0xBEBC, 0x70AF, 0xBEBD, 0x7A98, 0xBEBE, 0x63EA, 0xBEBF, 0x7A76,
+	0xBEC0, 0x7EA0, 0xBEC1, 0x7396, 0xBEC2, 0x97ED, 0xBEC3, 0x4E45,
+	0xBEC4, 0x7078, 0xBEC5, 0x4E5D, 0xBEC6, 0x9152, 0xBEC7, 0x53A9,
+	0xBEC8, 0x6551, 0xBEC9, 0x65E7, 0xBECA, 0x81FC, 0xBECB, 0x8205,
+	0xBECC, 0x548E, 0xBECD, 0x5C31, 0xBECE, 0x759A, 0xBECF, 0x97A0,
+	0xBED0, 0x62D8, 0xBED1, 0x72D9, 0xBED2, 0x75BD, 0xBED3, 0x5C45,
+	0xBED4, 0x9A79, 0xBED5, 0x83CA, 0xBED6, 0x5C40, 0xBED7, 0x5480,
+	0xBED8, 0x77E9, 0xBED9, 0x4E3E, 0xBEDA, 0x6CAE, 0xBEDB, 0x805A,
+	0xBEDC, 0x62D2, 0xBEDD, 0x636E, 0xBEDE, 0x5DE8, 0xBEDF, 0x5177,
+	0xBEE0, 0x8DDD, 0xBEE1, 0x8E1E, 0xBEE2, 0x952F, 0xBEE3, 0x4FF1,
+	0xBEE4, 0x53E5, 0xBEE5, 0x60E7, 0xBEE6, 0x70AC, 0xBEE7, 0x5267,
+	0xBEE8, 0x6350, 0xBEE9, 0x9E43, 0xBEEA, 0x5A1F, 0xBEEB, 0x5026,
+	0xBEEC, 0x7737, 0xBEED, 0x5377, 0xBEEE, 0x7EE2, 0xBEEF, 0x6485,
+	0xBEF0, 0x652B, 0xBEF1, 0x6289, 0xBEF2, 0x6398, 0xBEF3, 0x5014,
+	0xBEF4, 0x7235, 0xBEF5, 0x89C9, 0xBEF6, 0x51B3, 0xBEF7, 0x8BC0,
+	0xBEF8, 0x7EDD, 0xBEF9, 0x5747, 0xBEFA, 0x83CC, 0xBEFB, 0x94A7,
+	0xBEFC, 0x519B, 0xBEFD, 0x541B, 0xBEFE, 0x5CFB, 0xBF40, 0x7DFB,
+	0xBF41, 0x7DFC, 0xBF42, 0x7DFD, 0xBF43, 0x7DFE, 0xBF44, 0x7DFF,
+	0xBF45, 0x7E00, 0xBF46, 0x7E01, 0xBF47, 0x7E02, 0xBF48, 0x7E03,
+	0xBF49, 0x7E04, 0xBF4A, 0x7E05, 0xBF4B, 0x7E06, 0xBF4C, 0x7E07,
+	0xBF4D, 0x7E08, 0xBF4E, 0x7E09, 0xBF4F, 0x7E0A, 0xBF50, 0x7E0B,
+	0xBF51, 0x7E0C, 0xBF52, 0x7E0D, 0xBF53, 0x7E0E, 0xBF54, 0x7E0F,
+	0xBF55, 0x7E10, 0xBF56, 0x7E11, 0xBF57, 0x7E12, 0xBF58, 0x7E13,
+	0xBF59, 0x7E14, 0xBF5A, 0x7E15, 0xBF5B, 0x7E16, 0xBF5C, 0x7E17,
+	0xBF5D, 0x7E18, 0xBF5E, 0x7E19, 0xBF5F, 0x7E1A, 0xBF60, 0x7E1B,
+	0xBF61, 0x7E1C, 0xBF62, 0x7E1D, 0xBF63, 0x7E1E, 0xBF64, 0x7E1F,
+	0xBF65, 0x7E20, 0xBF66, 0x7E21, 0xBF67, 0x7E22, 0xBF68, 0x7E23,
+	0xBF69, 0x7E24, 0xBF6A, 0x7E25, 0xBF6B, 0x7E26, 0xBF6C, 0x7E27,
+	0xBF6D, 0x7E28, 0xBF6E, 0x7E29, 0xBF6F, 0x7E2A, 0xBF70, 0x7E2B,
+	0xBF71, 0x7E2C, 0xBF72, 0x7E2D, 0xBF73, 0x7E2E, 0xBF74, 0x7E2F,
+	0xBF75, 0x7E30, 0xBF76, 0x7E31, 0xBF77, 0x7E32, 0xBF78, 0x7E33,
+	0xBF79, 0x7E34, 0xBF7A, 0x7E35, 0xBF7B, 0x7E36, 0xBF7C, 0x7E37,
+	0xBF7D, 0x7E38, 0xBF7E, 0x7E39, 0xBF80, 0x7E3A, 0xBF81, 0x7E3C,
+	0xBF82, 0x7E3D, 0xBF83, 0x7E3E, 0xBF84, 0x7E3F, 0xBF85, 0x7E40,
+	0xBF86, 0x7E42, 0xBF87, 0x7E43, 0xBF88, 0x7E44, 0xBF89, 0x7E45,
+	0xBF8A, 0x7E46, 0xBF8B, 0x7E48, 0xBF8C, 0x7E49, 0xBF8D, 0x7E4A,
+	0xBF8E, 0x7E4B, 0xBF8F, 0x7E4C, 0xBF90, 0x7E4D, 0xBF91, 0x7E4E,
+	0xBF92, 0x7E4F, 0xBF93, 0x7E50, 0xBF94, 0x7E51, 0xBF95, 0x7E52,
+	0xBF96, 0x7E53, 0xBF97, 0x7E54, 0xBF98, 0x7E55, 0xBF99, 0x7E56,
+	0xBF9A, 0x7E57, 0xBF9B, 0x7E58, 0xBF9C, 0x7E59, 0xBF9D, 0x7E5A,
+	0xBF9E, 0x7E5B, 0xBF9F, 0x7E5C, 0xBFA0, 0x7E5D, 0xBFA1, 0x4FCA,
+	0xBFA2, 0x7AE3, 0xBFA3, 0x6D5A, 0xBFA4, 0x90E1, 0xBFA5, 0x9A8F,
+	0xBFA6, 0x5580, 0xBFA7, 0x5496, 0xBFA8, 0x5361, 0xBFA9, 0x54AF,
+	0xBFAA, 0x5F00, 0xBFAB, 0x63E9, 0xBFAC, 0x6977, 0xBFAD, 0x51EF,
+	0xBFAE, 0x6168, 0xBFAF, 0x520A, 0xBFB0, 0x582A, 0xBFB1, 0x52D8,
+	0xBFB2, 0x574E, 0xBFB3, 0x780D, 0xBFB4, 0x770B, 0xBFB5, 0x5EB7,
+	0xBFB6, 0x6177, 0xBFB7, 0x7CE0, 0xBFB8, 0x625B, 0xBFB9, 0x6297,
+	0xBFBA, 0x4EA2, 0xBFBB, 0x7095, 0xBFBC, 0x8003, 0xBFBD, 0x62F7,
+	0xBFBE, 0x70E4, 0xBFBF, 0x9760, 0xBFC0, 0x5777, 0xBFC1, 0x82DB,
+	0xBFC2, 0x67EF, 0xBFC3, 0x68F5, 0xBFC4, 0x78D5, 0xBFC5, 0x9897,
+	0xBFC6, 0x79D1, 0xBFC7, 0x58F3, 0xBFC8, 0x54B3, 0xBFC9, 0x53EF,
+	0xBFCA, 0x6E34, 0xBFCB, 0x514B, 0xBFCC, 0x523B, 0xBFCD, 0x5BA2,
+	0xBFCE, 0x8BFE, 0xBFCF, 0x80AF, 0xBFD0, 0x5543, 0xBFD1, 0x57A6,
+	0xBFD2, 0x6073, 0xBFD3, 0x5751, 0xBFD4, 0x542D, 0xBFD5, 0x7A7A,
+	0xBFD6, 0x6050, 0xBFD7, 0x5B54, 0xBFD8, 0x63A7, 0xBFD9, 0x62A0,
+	0xBFDA, 0x53E3, 0xBFDB, 0x6263, 0xBFDC, 0x5BC7, 0xBFDD, 0x67AF,
+	0xBFDE, 0x54ED, 0xBFDF, 0x7A9F, 0xBFE0, 0x82E6, 0xBFE1, 0x9177,
+	0xBFE2, 0x5E93, 0xBFE3, 0x88E4, 0xBFE4, 0x5938, 0xBFE5, 0x57AE,
+	0xBFE6, 0x630E, 0xBFE7, 0x8DE8, 0xBFE8, 0x80EF, 0xBFE9, 0x5757,
+	0xBFEA, 0x7B77, 0xBFEB, 0x4FA9, 0xBFEC, 0x5FEB, 0xBFED, 0x5BBD,
+	0xBFEE, 0x6B3E, 0xBFEF, 0x5321, 0xBFF0, 0x7B50, 0xBFF1, 0x72C2,
+	0xBFF2, 0x6846, 0xBFF3, 0x77FF, 0xBFF4, 0x7736, 0xBFF5, 0x65F7,
+	0xBFF6, 0x51B5, 0xBFF7, 0x4E8F, 0xBFF8, 0x76D4, 0xBFF9, 0x5CBF,
+	0xBFFA, 0x7AA5, 0xBFFB, 0x8475, 0xBFFC, 0x594E, 0xBFFD, 0x9B41,
+	0xBFFE, 0x5080, 0xC040, 0x7E5E, 0xC041, 0x7E5F, 0xC042, 0x7E60,
+	0xC043, 0x7E61, 0xC044, 0x7E62, 0xC045, 0x7E63, 0xC046, 0x7E64,
+	0xC047, 0x7E65, 0xC048, 0x7E66, 0xC049, 0x7E67, 0xC04A, 0x7E68,
+	0xC04B, 0x7E69, 0xC04C, 0x7E6A, 0xC04D, 0x7E6B, 0xC04E, 0x7E6C,
+	0xC04F, 0x7E6D, 0xC050, 0x7E6E, 0xC051, 0x7E6F, 0xC052, 0x7E70,
+	0xC053, 0x7E71, 0xC054, 0x7E72, 0xC055, 0x7E73, 0xC056, 0x7E74,
+	0xC057, 0x7E75, 0xC058, 0x7E76, 0xC059, 0x7E77, 0xC05A, 0x7E78,
+	0xC05B, 0x7E79, 0xC05C, 0x7E7A, 0xC05D, 0x7E7B, 0xC05E, 0x7E7C,
+	0xC05F, 0x7E7D, 0xC060, 0x7E7E, 0xC061, 0x7E7F, 0xC062, 0x7E80,
+	0xC063, 0x7E81, 0xC064, 0x7E83, 0xC065, 0x7E84, 0xC066, 0x7E85,
+	0xC067, 0x7E86, 0xC068, 0x7E87, 0xC069, 0x7E88, 0xC06A, 0x7E89,
+	0xC06B, 0x7E8A, 0xC06C, 0x7E8B, 0xC06D, 0x7E8C, 0xC06E, 0x7E8D,
+	0xC06F, 0x7E8E, 0xC070, 0x7E8F, 0xC071, 0x7E90, 0xC072, 0x7E91,
+	0xC073, 0x7E92, 0xC074, 0x7E93, 0xC075, 0x7E94, 0xC076, 0x7E95,
+	0xC077, 0x7E96, 0xC078, 0x7E97, 0xC079, 0x7E98, 0xC07A, 0x7E99,
+	0xC07B, 0x7E9A, 0xC07C, 0x7E9C, 0xC07D, 0x7E9D, 0xC07E, 0x7E9E,
+	0xC080, 0x7EAE, 0xC081, 0x7EB4, 0xC082, 0x7EBB, 0xC083, 0x7EBC,
+	0xC084, 0x7ED6, 0xC085, 0x7EE4, 0xC086, 0x7EEC, 0xC087, 0x7EF9,
+	0xC088, 0x7F0A, 0xC089, 0x7F10, 0xC08A, 0x7F1E, 0xC08B, 0x7F37,
+	0xC08C, 0x7F39, 0xC08D, 0x7F3B, 0xC08E, 0x7F3C, 0xC08F, 0x7F3D,
+	0xC090, 0x7F3E, 0xC091, 0x7F3F, 0xC092, 0x7F40, 0xC093, 0x7F41,
+	0xC094, 0x7F43, 0xC095, 0x7F46, 0xC096, 0x7F47, 0xC097, 0x7F48,
+	0xC098, 0x7F49, 0xC099, 0x7F4A, 0xC09A, 0x7F4B, 0xC09B, 0x7F4C,
+	0xC09C, 0x7F4D, 0xC09D, 0x7F4E, 0xC09E, 0x7F4F, 0xC09F, 0x7F52,
+	0xC0A0, 0x7F53, 0xC0A1, 0x9988, 0xC0A2, 0x6127, 0xC0A3, 0x6E83,
+	0xC0A4, 0x5764, 0xC0A5, 0x6606, 0xC0A6, 0x6346, 0xC0A7, 0x56F0,
+	0xC0A8, 0x62EC, 0xC0A9, 0x6269, 0xC0AA, 0x5ED3, 0xC0AB, 0x9614,
+	0xC0AC, 0x5783, 0xC0AD, 0x62C9, 0xC0AE, 0x5587, 0xC0AF, 0x8721,
+	0xC0B0, 0x814A, 0xC0B1, 0x8FA3, 0xC0B2, 0x5566, 0xC0B3, 0x83B1,
+	0xC0B4, 0x6765, 0xC0B5, 0x8D56, 0xC0B6, 0x84DD, 0xC0B7, 0x5A6A,
+	0xC0B8, 0x680F, 0xC0B9, 0x62E6, 0xC0BA, 0x7BEE, 0xC0BB, 0x9611,
+	0xC0BC, 0x5170, 0xC0BD, 0x6F9C, 0xC0BE, 0x8C30, 0xC0BF, 0x63FD,
+	0xC0C0, 0x89C8, 0xC0C1, 0x61D2, 0xC0C2, 0x7F06, 0xC0C3, 0x70C2,
+	0xC0C4, 0x6EE5, 0xC0C5, 0x7405, 0xC0C6, 0x6994, 0xC0C7, 0x72FC,
+	0xC0C8, 0x5ECA, 0xC0C9, 0x90CE, 0xC0CA, 0x6717, 0xC0CB, 0x6D6A,
+	0xC0CC, 0x635E, 0xC0CD, 0x52B3, 0xC0CE, 0x7262, 0xC0CF, 0x8001,
+	0xC0D0, 0x4F6C, 0xC0D1, 0x59E5, 0xC0D2, 0x916A, 0xC0D3, 0x70D9,
+	0xC0D4, 0x6D9D, 0xC0D5, 0x52D2, 0xC0D6, 0x4E50, 0xC0D7, 0x96F7,
+	0xC0D8, 0x956D, 0xC0D9, 0x857E, 0xC0DA, 0x78CA, 0xC0DB, 0x7D2F,
+	0xC0DC, 0x5121, 0xC0DD, 0x5792, 0xC0DE, 0x64C2, 0xC0DF, 0x808B,
+	0xC0E0, 0x7C7B, 0xC0E1, 0x6CEA, 0xC0E2, 0x68F1, 0xC0E3, 0x695E,
+	0xC0E4, 0x51B7, 0xC0E5, 0x5398, 0xC0E6, 0x68A8, 0xC0E7, 0x7281,
+	0xC0E8, 0x9ECE, 0xC0E9, 0x7BF1, 0xC0EA, 0x72F8, 0xC0EB, 0x79BB,
+	0xC0EC, 0x6F13, 0xC0ED, 0x7406, 0xC0EE, 0x674E, 0xC0EF, 0x91CC,
+	0xC0F0, 0x9CA4, 0xC0F1, 0x793C, 0xC0F2, 0x8389, 0xC0F3, 0x8354,
+	0xC0F4, 0x540F, 0xC0F5, 0x6817, 0xC0F6, 0x4E3D, 0xC0F7, 0x5389,
+	0xC0F8, 0x52B1, 0xC0F9, 0x783E, 0xC0FA, 0x5386, 0xC0FB, 0x5229,
+	0xC0FC, 0x5088, 0xC0FD, 0x4F8B, 0xC0FE, 0x4FD0, 0xC140, 0x7F56,
+	0xC141, 0x7F59, 0xC142, 0x7F5B, 0xC143, 0x7F5C, 0xC144, 0x7F5D,
+	0xC145, 0x7F5E, 0xC146, 0x7F60, 0xC147, 0x7F63, 0xC148, 0x7F64,
+	0xC149, 0x7F65, 0xC14A, 0x7F66, 0xC14B, 0x7F67, 0xC14C, 0x7F6B,
+	0xC14D, 0x7F6C, 0xC14E, 0x7F6D, 0xC14F, 0x7F6F, 0xC150, 0x7F70,
+	0xC151, 0x7F73, 0xC152, 0x7F75, 0xC153, 0x7F76, 0xC154, 0x7F77,
+	0xC155, 0x7F78, 0xC156, 0x7F7A, 0xC157, 0x7F7B, 0xC158, 0x7F7C,
+	0xC159, 0x7F7D, 0xC15A, 0x7F7F, 0xC15B, 0x7F80, 0xC15C, 0x7F82,
+	0xC15D, 0x7F83, 0xC15E, 0x7F84, 0xC15F, 0x7F85, 0xC160, 0x7F86,
+	0xC161, 0x7F87, 0xC162, 0x7F88, 0xC163, 0x7F89, 0xC164, 0x7F8B,
+	0xC165, 0x7F8D, 0xC166, 0x7F8F, 0xC167, 0x7F90, 0xC168, 0x7F91,
+	0xC169, 0x7F92, 0xC16A, 0x7F93, 0xC16B, 0x7F95, 0xC16C, 0x7F96,
+	0xC16D, 0x7F97, 0xC16E, 0x7F98, 0xC16F, 0x7F99, 0xC170, 0x7F9B,
+	0xC171, 0x7F9C, 0xC172, 0x7FA0, 0xC173, 0x7FA2, 0xC174, 0x7FA3,
+	0xC175, 0x7FA5, 0xC176, 0x7FA6, 0xC177, 0x7FA8, 0xC178, 0x7FA9,
+	0xC179, 0x7FAA, 0xC17A, 0x7FAB, 0xC17B, 0x7FAC, 0xC17C, 0x7FAD,
+	0xC17D, 0x7FAE, 0xC17E, 0x7FB1, 0xC180, 0x7FB3, 0xC181, 0x7FB4,
+	0xC182, 0x7FB5, 0xC183, 0x7FB6, 0xC184, 0x7FB7, 0xC185, 0x7FBA,
+	0xC186, 0x7FBB, 0xC187, 0x7FBE, 0xC188, 0x7FC0, 0xC189, 0x7FC2,
+	0xC18A, 0x7FC3, 0xC18B, 0x7FC4, 0xC18C, 0x7FC6, 0xC18D, 0x7FC7,
+	0xC18E, 0x7FC8, 0xC18F, 0x7FC9, 0xC190, 0x7FCB, 0xC191, 0x7FCD,
+	0xC192, 0x7FCF, 0xC193, 0x7FD0, 0xC194, 0x7FD1, 0xC195, 0x7FD2,
+	0xC196, 0x7FD3, 0xC197, 0x7FD6, 0xC198, 0x7FD7, 0xC199, 0x7FD9,
+	0xC19A, 0x7FDA, 0xC19B, 0x7FDB, 0xC19C, 0x7FDC, 0xC19D, 0x7FDD,
+	0xC19E, 0x7FDE, 0xC19F, 0x7FE2, 0xC1A0, 0x7FE3, 0xC1A1, 0x75E2,
+	0xC1A2, 0x7ACB, 0xC1A3, 0x7C92, 0xC1A4, 0x6CA5, 0xC1A5, 0x96B6,
+	0xC1A6, 0x529B, 0xC1A7, 0x7483, 0xC1A8, 0x54E9, 0xC1A9, 0x4FE9,
+	0xC1AA, 0x8054, 0xC1AB, 0x83B2, 0xC1AC, 0x8FDE, 0xC1AD, 0x9570,
+	0xC1AE, 0x5EC9, 0xC1AF, 0x601C, 0xC1B0, 0x6D9F, 0xC1B1, 0x5E18,
+	0xC1B2, 0x655B, 0xC1B3, 0x8138, 0xC1B4, 0x94FE, 0xC1B5, 0x604B,
+	0xC1B6, 0x70BC, 0xC1B7, 0x7EC3, 0xC1B8, 0x7CAE, 0xC1B9, 0x51C9,
+	0xC1BA, 0x6881, 0xC1BB, 0x7CB1, 0xC1BC, 0x826F, 0xC1BD, 0x4E24,
+	0xC1BE, 0x8F86, 0xC1BF, 0x91CF, 0xC1C0, 0x667E, 0xC1C1, 0x4EAE,
+	0xC1C2, 0x8C05, 0xC1C3, 0x64A9, 0xC1C4, 0x804A, 0xC1C5, 0x50DA,
+	0xC1C6, 0x7597, 0xC1C7, 0x71CE, 0xC1C8, 0x5BE5, 0xC1C9, 0x8FBD,
+	0xC1CA, 0x6F66, 0xC1CB, 0x4E86, 0xC1CC, 0x6482, 0xC1CD, 0x9563,
+	0xC1CE, 0x5ED6, 0xC1CF, 0x6599, 0xC1D0, 0x5217, 0xC1D1, 0x88C2,
+	0xC1D2, 0x70C8, 0xC1D3, 0x52A3, 0xC1D4, 0x730E, 0xC1D5, 0x7433,
+	0xC1D6, 0x6797, 0xC1D7, 0x78F7, 0xC1D8, 0x9716, 0xC1D9, 0x4E34,
+	0xC1DA, 0x90BB, 0xC1DB, 0x9CDE, 0xC1DC, 0x6DCB, 0xC1DD, 0x51DB,
+	0xC1DE, 0x8D41, 0xC1DF, 0x541D, 0xC1E0, 0x62CE, 0xC1E1, 0x73B2,
+	0xC1E2, 0x83F1, 0xC1E3, 0x96F6, 0xC1E4, 0x9F84, 0xC1E5, 0x94C3,
+	0xC1E6, 0x4F36, 0xC1E7, 0x7F9A, 0xC1E8, 0x51CC, 0xC1E9, 0x7075,
+	0xC1EA, 0x9675, 0xC1EB, 0x5CAD, 0xC1EC, 0x9886, 0xC1ED, 0x53E6,
+	0xC1EE, 0x4EE4, 0xC1EF, 0x6E9C, 0xC1F0, 0x7409, 0xC1F1, 0x69B4,
+	0xC1F2, 0x786B, 0xC1F3, 0x998F, 0xC1F4, 0x7559, 0xC1F5, 0x5218,
+	0xC1F6, 0x7624, 0xC1F7, 0x6D41, 0xC1F8, 0x67F3, 0xC1F9, 0x516D,
+	0xC1FA, 0x9F99, 0xC1FB, 0x804B, 0xC1FC, 0x5499, 0xC1FD, 0x7B3C,
+	0xC1FE, 0x7ABF, 0xC240, 0x7FE4, 0xC241, 0x7FE7, 0xC242, 0x7FE8,
+	0xC243, 0x7FEA, 0xC244, 0x7FEB, 0xC245, 0x7FEC, 0xC246, 0x7FED,
+	0xC247, 0x7FEF, 0xC248, 0x7FF2, 0xC249, 0x7FF4, 0xC24A, 0x7FF5,
+	0xC24B, 0x7FF6, 0xC24C, 0x7FF7, 0xC24D, 0x7FF8, 0xC24E, 0x7FF9,
+	0xC24F, 0x7FFA, 0xC250, 0x7FFD, 0xC251, 0x7FFE, 0xC252, 0x7FFF,
+	0xC253, 0x8002, 0xC254, 0x8007, 0xC255, 0x8008, 0xC256, 0x8009,
+	0xC257, 0x800A, 0xC258, 0x800E, 0xC259, 0x800F, 0xC25A, 0x8011,
+	0xC25B, 0x8013, 0xC25C, 0x801A, 0xC25D, 0x801B, 0xC25E, 0x801D,
+	0xC25F, 0x801E, 0xC260, 0x801F, 0xC261, 0x8021, 0xC262, 0x8023,
+	0xC263, 0x8024, 0xC264, 0x802B, 0xC265, 0x802C, 0xC266, 0x802D,
+	0xC267, 0x802E, 0xC268, 0x802F, 0xC269, 0x8030, 0xC26A, 0x8032,
+	0xC26B, 0x8034, 0xC26C, 0x8039, 0xC26D, 0x803A, 0xC26E, 0x803C,
+	0xC26F, 0x803E, 0xC270, 0x8040, 0xC271, 0x8041, 0xC272, 0x8044,
+	0xC273, 0x8045, 0xC274, 0x8047, 0xC275, 0x8048, 0xC276, 0x8049,
+	0xC277, 0x804E, 0xC278, 0x804F, 0xC279, 0x8050, 0xC27A, 0x8051,
+	0xC27B, 0x8053, 0xC27C, 0x8055, 0xC27D, 0x8056, 0xC27E, 0x8057,
+	0xC280, 0x8059, 0xC281, 0x805B, 0xC282, 0x805C, 0xC283, 0x805D,
+	0xC284, 0x805E, 0xC285, 0x805F, 0xC286, 0x8060, 0xC287, 0x8061,
+	0xC288, 0x8062, 0xC289, 0x8063, 0xC28A, 0x8064, 0xC28B, 0x8065,
+	0xC28C, 0x8066, 0xC28D, 0x8067, 0xC28E, 0x8068, 0xC28F, 0x806B,
+	0xC290, 0x806C, 0xC291, 0x806D, 0xC292, 0x806E, 0xC293, 0x806F,
+	0xC294, 0x8070, 0xC295, 0x8072, 0xC296, 0x8073, 0xC297, 0x8074,
+	0xC298, 0x8075, 0xC299, 0x8076, 0xC29A, 0x8077, 0xC29B, 0x8078,
+	0xC29C, 0x8079, 0xC29D, 0x807A, 0xC29E, 0x807B, 0xC29F, 0x807C,
+	0xC2A0, 0x807D, 0xC2A1, 0x9686, 0xC2A2, 0x5784, 0xC2A3, 0x62E2,
+	0xC2A4, 0x9647, 0xC2A5, 0x697C, 0xC2A6, 0x5A04, 0xC2A7, 0x6402,
+	0xC2A8, 0x7BD3, 0xC2A9, 0x6F0F, 0xC2AA, 0x964B, 0xC2AB, 0x82A6,
+	0xC2AC, 0x5362, 0xC2AD, 0x9885, 0xC2AE, 0x5E90, 0xC2AF, 0x7089,
+	0xC2B0, 0x63B3, 0xC2B1, 0x5364, 0xC2B2, 0x864F, 0xC2B3, 0x9C81,
+	0xC2B4, 0x9E93, 0xC2B5, 0x788C, 0xC2B6, 0x9732, 0xC2B7, 0x8DEF,
+	0xC2B8, 0x8D42, 0xC2B9, 0x9E7F, 0xC2BA, 0x6F5E, 0xC2BB, 0x7984,
+	0xC2BC, 0x5F55, 0xC2BD, 0x9646, 0xC2BE, 0x622E, 0xC2BF, 0x9A74,
+	0xC2C0, 0x5415, 0xC2C1, 0x94DD, 0xC2C2, 0x4FA3, 0xC2C3, 0x65C5,
+	0xC2C4, 0x5C65, 0xC2C5, 0x5C61, 0xC2C6, 0x7F15, 0xC2C7, 0x8651,
+	0xC2C8, 0x6C2F, 0xC2C9, 0x5F8B, 0xC2CA, 0x7387, 0xC2CB, 0x6EE4,
+	0xC2CC, 0x7EFF, 0xC2CD, 0x5CE6, 0xC2CE, 0x631B, 0xC2CF, 0x5B6A,
+	0xC2D0, 0x6EE6, 0xC2D1, 0x5375, 0xC2D2, 0x4E71, 0xC2D3, 0x63A0,
+	0xC2D4, 0x7565, 0xC2D5, 0x62A1, 0xC2D6, 0x8F6E, 0xC2D7, 0x4F26,
+	0xC2D8, 0x4ED1, 0xC2D9, 0x6CA6, 0xC2DA, 0x7EB6, 0xC2DB, 0x8BBA,
+	0xC2DC, 0x841D, 0xC2DD, 0x87BA, 0xC2DE, 0x7F57, 0xC2DF, 0x903B,
+	0xC2E0, 0x9523, 0xC2E1, 0x7BA9, 0xC2E2, 0x9AA1, 0xC2E3, 0x88F8,
+	0xC2E4, 0x843D, 0xC2E5, 0x6D1B, 0xC2E6, 0x9A86, 0xC2E7, 0x7EDC,
+	0xC2E8, 0x5988, 0xC2E9, 0x9EBB, 0xC2EA, 0x739B, 0xC2EB, 0x7801,
+	0xC2EC, 0x8682, 0xC2ED, 0x9A6C, 0xC2EE, 0x9A82, 0xC2EF, 0x561B,
+	0xC2F0, 0x5417, 0xC2F1, 0x57CB, 0xC2F2, 0x4E70, 0xC2F3, 0x9EA6,
+	0xC2F4, 0x5356, 0xC2F5, 0x8FC8, 0xC2F6, 0x8109, 0xC2F7, 0x7792,
+	0xC2F8, 0x9992, 0xC2F9, 0x86EE, 0xC2FA, 0x6EE1, 0xC2FB, 0x8513,
+	0xC2FC, 0x66FC, 0xC2FD, 0x6162, 0xC2FE, 0x6F2B, 0xC340, 0x807E,
+	0xC341, 0x8081, 0xC342, 0x8082, 0xC343, 0x8085, 0xC344, 0x8088,
+	0xC345, 0x808A, 0xC346, 0x808D, 0xC347, 0x808E, 0xC348, 0x808F,
+	0xC349, 0x8090, 0xC34A, 0x8091, 0xC34B, 0x8092, 0xC34C, 0x8094,
+	0xC34D, 0x8095, 0xC34E, 0x8097, 0xC34F, 0x8099, 0xC350, 0x809E,
+	0xC351, 0x80A3, 0xC352, 0x80A6, 0xC353, 0x80A7, 0xC354, 0x80A8,
+	0xC355, 0x80AC, 0xC356, 0x80B0, 0xC357, 0x80B3, 0xC358, 0x80B5,
+	0xC359, 0x80B6, 0xC35A, 0x80B8, 0xC35B, 0x80B9, 0xC35C, 0x80BB,
+	0xC35D, 0x80C5, 0xC35E, 0x80C7, 0xC35F, 0x80C8, 0xC360, 0x80C9,
+	0xC361, 0x80CA, 0xC362, 0x80CB, 0xC363, 0x80CF, 0xC364, 0x80D0,
+	0xC365, 0x80D1, 0xC366, 0x80D2, 0xC367, 0x80D3, 0xC368, 0x80D4,
+	0xC369, 0x80D5, 0xC36A, 0x80D8, 0xC36B, 0x80DF, 0xC36C, 0x80E0,
+	0xC36D, 0x80E2, 0xC36E, 0x80E3, 0xC36F, 0x80E6, 0xC370, 0x80EE,
+	0xC371, 0x80F5, 0xC372, 0x80F7, 0xC373, 0x80F9, 0xC374, 0x80FB,
+	0xC375, 0x80FE, 0xC376, 0x80FF, 0xC377, 0x8100, 0xC378, 0x8101,
+	0xC379, 0x8103, 0xC37A, 0x8104, 0xC37B, 0x8105, 0xC37C, 0x8107,
+	0xC37D, 0x8108, 0xC37E, 0x810B, 0xC380, 0x810C, 0xC381, 0x8115,
+	0xC382, 0x8117, 0xC383, 0x8119, 0xC384, 0x811B, 0xC385, 0x811C,
+	0xC386, 0x811D, 0xC387, 0x811F, 0xC388, 0x8120, 0xC389, 0x8121,
+	0xC38A, 0x8122, 0xC38B, 0x8123, 0xC38C, 0x8124, 0xC38D, 0x8125,
+	0xC38E, 0x8126, 0xC38F, 0x8127, 0xC390, 0x8128, 0xC391, 0x8129,
+	0xC392, 0x812A, 0xC393, 0x812B, 0xC394, 0x812D, 0xC395, 0x812E,
+	0xC396, 0x8130, 0xC397, 0x8133, 0xC398, 0x8134, 0xC399, 0x8135,
+	0xC39A, 0x8137, 0xC39B, 0x8139, 0xC39C, 0x813A, 0xC39D, 0x813B,
+	0xC39E, 0x813C, 0xC39F, 0x813D, 0xC3A0, 0x813F, 0xC3A1, 0x8C29,
+	0xC3A2, 0x8292, 0xC3A3, 0x832B, 0xC3A4, 0x76F2, 0xC3A5, 0x6C13,
+	0xC3A6, 0x5FD9, 0xC3A7, 0x83BD, 0xC3A8, 0x732B, 0xC3A9, 0x8305,
+	0xC3AA, 0x951A, 0xC3AB, 0x6BDB, 0xC3AC, 0x77DB, 0xC3AD, 0x94C6,
+	0xC3AE, 0x536F, 0xC3AF, 0x8302, 0xC3B0, 0x5192, 0xC3B1, 0x5E3D,
+	0xC3B2, 0x8C8C, 0xC3B3, 0x8D38, 0xC3B4, 0x4E48, 0xC3B5, 0x73AB,
+	0xC3B6, 0x679A, 0xC3B7, 0x6885, 0xC3B8, 0x9176, 0xC3B9, 0x9709,
+	0xC3BA, 0x7164, 0xC3BB, 0x6CA1, 0xC3BC, 0x7709, 0xC3BD, 0x5A92,
+	0xC3BE, 0x9541, 0xC3BF, 0x6BCF, 0xC3C0, 0x7F8E, 0xC3C1, 0x6627,
+	0xC3C2, 0x5BD0, 0xC3C3, 0x59B9, 0xC3C4, 0x5A9A, 0xC3C5, 0x95E8,
+	0xC3C6, 0x95F7, 0xC3C7, 0x4EEC, 0xC3C8, 0x840C, 0xC3C9, 0x8499,
+	0xC3CA, 0x6AAC, 0xC3CB, 0x76DF, 0xC3CC, 0x9530, 0xC3CD, 0x731B,
+	0xC3CE, 0x68A6, 0xC3CF, 0x5B5F, 0xC3D0, 0x772F, 0xC3D1, 0x919A,
+	0xC3D2, 0x9761, 0xC3D3, 0x7CDC, 0xC3D4, 0x8FF7, 0xC3D5, 0x8C1C,
+	0xC3D6, 0x5F25, 0xC3D7, 0x7C73, 0xC3D8, 0x79D8, 0xC3D9, 0x89C5,
+	0xC3DA, 0x6CCC, 0xC3DB, 0x871C, 0xC3DC, 0x5BC6, 0xC3DD, 0x5E42,
+	0xC3DE, 0x68C9, 0xC3DF, 0x7720, 0xC3E0, 0x7EF5, 0xC3E1, 0x5195,
+	0xC3E2, 0x514D, 0xC3E3, 0x52C9, 0xC3E4, 0x5A29, 0xC3E5, 0x7F05,
+	0xC3E6, 0x9762, 0xC3E7, 0x82D7, 0xC3E8, 0x63CF, 0xC3E9, 0x7784,
+	0xC3EA, 0x85D0, 0xC3EB, 0x79D2, 0xC3EC, 0x6E3A, 0xC3ED, 0x5E99,
+	0xC3EE, 0x5999, 0xC3EF, 0x8511, 0xC3F0, 0x706D, 0xC3F1, 0x6C11,
+	0xC3F2, 0x62BF, 0xC3F3, 0x76BF, 0xC3F4, 0x654F, 0xC3F5, 0x60AF,
+	0xC3F6, 0x95FD, 0xC3F7, 0x660E, 0xC3F8, 0x879F, 0xC3F9, 0x9E23,
+	0xC3FA, 0x94ED, 0xC3FB, 0x540D, 0xC3FC, 0x547D, 0xC3FD, 0x8C2C,
+	0xC3FE, 0x6478, 0xC440, 0x8140, 0xC441, 0x8141, 0xC442, 0x8142,
+	0xC443, 0x8143, 0xC444, 0x8144, 0xC445, 0x8145, 0xC446, 0x8147,
+	0xC447, 0x8149, 0xC448, 0x814D, 0xC449, 0x814E, 0xC44A, 0x814F,
+	0xC44B, 0x8152, 0xC44C, 0x8156, 0xC44D, 0x8157, 0xC44E, 0x8158,
+	0xC44F, 0x815B, 0xC450, 0x815C, 0xC451, 0x815D, 0xC452, 0x815E,
+	0xC453, 0x815F, 0xC454, 0x8161, 0xC455, 0x8162, 0xC456, 0x8163,
+	0xC457, 0x8164, 0xC458, 0x8166, 0xC459, 0x8168, 0xC45A, 0x816A,
+	0xC45B, 0x816B, 0xC45C, 0x816C, 0xC45D, 0x816F, 0xC45E, 0x8172,
+	0xC45F, 0x8173, 0xC460, 0x8175, 0xC461, 0x8176, 0xC462, 0x8177,
+	0xC463, 0x8178, 0xC464, 0x8181, 0xC465, 0x8183, 0xC466, 0x8184,
+	0xC467, 0x8185, 0xC468, 0x8186, 0xC469, 0x8187, 0xC46A, 0x8189,
+	0xC46B, 0x818B, 0xC46C, 0x818C, 0xC46D, 0x818D, 0xC46E, 0x818E,
+	0xC46F, 0x8190, 0xC470, 0x8192, 0xC471, 0x8193, 0xC472, 0x8194,
+	0xC473, 0x8195, 0xC474, 0x8196, 0xC475, 0x8197, 0xC476, 0x8199,
+	0xC477, 0x819A, 0xC478, 0x819E, 0xC479, 0x819F, 0xC47A, 0x81A0,
+	0xC47B, 0x81A1, 0xC47C, 0x81A2, 0xC47D, 0x81A4, 0xC47E, 0x81A5,
+	0xC480, 0x81A7, 0xC481, 0x81A9, 0xC482, 0x81AB, 0xC483, 0x81AC,
+	0xC484, 0x81AD, 0xC485, 0x81AE, 0xC486, 0x81AF, 0xC487, 0x81B0,
+	0xC488, 0x81B1, 0xC489, 0x81B2, 0xC48A, 0x81B4, 0xC48B, 0x81B5,
+	0xC48C, 0x81B6, 0xC48D, 0x81B7, 0xC48E, 0x81B8, 0xC48F, 0x81B9,
+	0xC490, 0x81BC, 0xC491, 0x81BD, 0xC492, 0x81BE, 0xC493, 0x81BF,
+	0xC494, 0x81C4, 0xC495, 0x81C5, 0xC496, 0x81C7, 0xC497, 0x81C8,
+	0xC498, 0x81C9, 0xC499, 0x81CB, 0xC49A, 0x81CD, 0xC49B, 0x81CE,
+	0xC49C, 0x81CF, 0xC49D, 0x81D0, 0xC49E, 0x81D1, 0xC49F, 0x81D2,
+	0xC4A0, 0x81D3, 0xC4A1, 0x6479, 0xC4A2, 0x8611, 0xC4A3, 0x6A21,
+	0xC4A4, 0x819C, 0xC4A5, 0x78E8, 0xC4A6, 0x6469, 0xC4A7, 0x9B54,
+	0xC4A8, 0x62B9, 0xC4A9, 0x672B, 0xC4AA, 0x83AB, 0xC4AB, 0x58A8,
+	0xC4AC, 0x9ED8, 0xC4AD, 0x6CAB, 0xC4AE, 0x6F20, 0xC4AF, 0x5BDE,
+	0xC4B0, 0x964C, 0xC4B1, 0x8C0B, 0xC4B2, 0x725F, 0xC4B3, 0x67D0,
+	0xC4B4, 0x62C7, 0xC4B5, 0x7261, 0xC4B6, 0x4EA9, 0xC4B7, 0x59C6,
+	0xC4B8, 0x6BCD, 0xC4B9, 0x5893, 0xC4BA, 0x66AE, 0xC4BB, 0x5E55,
+	0xC4BC, 0x52DF, 0xC4BD, 0x6155, 0xC4BE, 0x6728, 0xC4BF, 0x76EE,
+	0xC4C0, 0x7766, 0xC4C1, 0x7267, 0xC4C2, 0x7A46, 0xC4C3, 0x62FF,
+	0xC4C4, 0x54EA, 0xC4C5, 0x5450, 0xC4C6, 0x94A0, 0xC4C7, 0x90A3,
+	0xC4C8, 0x5A1C, 0xC4C9, 0x7EB3, 0xC4CA, 0x6C16, 0xC4CB, 0x4E43,
+	0xC4CC, 0x5976, 0xC4CD, 0x8010, 0xC4CE, 0x5948, 0xC4CF, 0x5357,
+	0xC4D0, 0x7537, 0xC4D1, 0x96BE, 0xC4D2, 0x56CA, 0xC4D3, 0x6320,
+	0xC4D4, 0x8111, 0xC4D5, 0x607C, 0xC4D6, 0x95F9, 0xC4D7, 0x6DD6,
+	0xC4D8, 0x5462, 0xC4D9, 0x9981, 0xC4DA, 0x5185, 0xC4DB, 0x5AE9,
+	0xC4DC, 0x80FD, 0xC4DD, 0x59AE, 0xC4DE, 0x9713, 0xC4DF, 0x502A,
+	0xC4E0, 0x6CE5, 0xC4E1, 0x5C3C, 0xC4E2, 0x62DF, 0xC4E3, 0x4F60,
+	0xC4E4, 0x533F, 0xC4E5, 0x817B, 0xC4E6, 0x9006, 0xC4E7, 0x6EBA,
+	0xC4E8, 0x852B, 0xC4E9, 0x62C8, 0xC4EA, 0x5E74, 0xC4EB, 0x78BE,
+	0xC4EC, 0x64B5, 0xC4ED, 0x637B, 0xC4EE, 0x5FF5, 0xC4EF, 0x5A18,
+	0xC4F0, 0x917F, 0xC4F1, 0x9E1F, 0xC4F2, 0x5C3F, 0xC4F3, 0x634F,
+	0xC4F4, 0x8042, 0xC4F5, 0x5B7D, 0xC4F6, 0x556E, 0xC4F7, 0x954A,
+	0xC4F8, 0x954D, 0xC4F9, 0x6D85, 0xC4FA, 0x60A8, 0xC4FB, 0x67E0,
+	0xC4FC, 0x72DE, 0xC4FD, 0x51DD, 0xC4FE, 0x5B81, 0xC540, 0x81D4,
+	0xC541, 0x81D5, 0xC542, 0x81D6, 0xC543, 0x81D7, 0xC544, 0x81D8,
+	0xC545, 0x81D9, 0xC546, 0x81DA, 0xC547, 0x81DB, 0xC548, 0x81DC,
+	0xC549, 0x81DD, 0xC54A, 0x81DE, 0xC54B, 0x81DF, 0xC54C, 0x81E0,
+	0xC54D, 0x81E1, 0xC54E, 0x81E2, 0xC54F, 0x81E4, 0xC550, 0x81E5,
+	0xC551, 0x81E6, 0xC552, 0x81E8, 0xC553, 0x81E9, 0xC554, 0x81EB,
+	0xC555, 0x81EE, 0xC556, 0x81EF, 0xC557, 0x81F0, 0xC558, 0x81F1,
+	0xC559, 0x81F2, 0xC55A, 0x81F5, 0xC55B, 0x81F6, 0xC55C, 0x81F7,
+	0xC55D, 0x81F8, 0xC55E, 0x81F9, 0xC55F, 0x81FA, 0xC560, 0x81FD,
+	0xC561, 0x81FF, 0xC562, 0x8203, 0xC563, 0x8207, 0xC564, 0x8208,
+	0xC565, 0x8209, 0xC566, 0x820A, 0xC567, 0x820B, 0xC568, 0x820E,
+	0xC569, 0x820F, 0xC56A, 0x8211, 0xC56B, 0x8213, 0xC56C, 0x8215,
+	0xC56D, 0x8216, 0xC56E, 0x8217, 0xC56F, 0x8218, 0xC570, 0x8219,
+	0xC571, 0x821A, 0xC572, 0x821D, 0xC573, 0x8220, 0xC574, 0x8224,
+	0xC575, 0x8225, 0xC576, 0x8226, 0xC577, 0x8227, 0xC578, 0x8229,
+	0xC579, 0x822E, 0xC57A, 0x8232, 0xC57B, 0x823A, 0xC57C, 0x823C,
+	0xC57D, 0x823D, 0xC57E, 0x823F, 0xC580, 0x8240, 0xC581, 0x8241,
+	0xC582, 0x8242, 0xC583, 0x8243, 0xC584, 0x8245, 0xC585, 0x8246,
+	0xC586, 0x8248, 0xC587, 0x824A, 0xC588, 0x824C, 0xC589, 0x824D,
+	0xC58A, 0x824E, 0xC58B, 0x8250, 0xC58C, 0x8251, 0xC58D, 0x8252,
+	0xC58E, 0x8253, 0xC58F, 0x8254, 0xC590, 0x8255, 0xC591, 0x8256,
+	0xC592, 0x8257, 0xC593, 0x8259, 0xC594, 0x825B, 0xC595, 0x825C,
+	0xC596, 0x825D, 0xC597, 0x825E, 0xC598, 0x8260, 0xC599, 0x8261,
+	0xC59A, 0x8262, 0xC59B, 0x8263, 0xC59C, 0x8264, 0xC59D, 0x8265,
+	0xC59E, 0x8266, 0xC59F, 0x8267, 0xC5A0, 0x8269, 0xC5A1, 0x62E7,
+	0xC5A2, 0x6CDE, 0xC5A3, 0x725B, 0xC5A4, 0x626D, 0xC5A5, 0x94AE,
+	0xC5A6, 0x7EBD, 0xC5A7, 0x8113, 0xC5A8, 0x6D53, 0xC5A9, 0x519C,
+	0xC5AA, 0x5F04, 0xC5AB, 0x5974, 0xC5AC, 0x52AA, 0xC5AD, 0x6012,
+	0xC5AE, 0x5973, 0xC5AF, 0x6696, 0xC5B0, 0x8650, 0xC5B1, 0x759F,
+	0xC5B2, 0x632A, 0xC5B3, 0x61E6, 0xC5B4, 0x7CEF, 0xC5B5, 0x8BFA,
+	0xC5B6, 0x54E6, 0xC5B7, 0x6B27, 0xC5B8, 0x9E25, 0xC5B9, 0x6BB4,
+	0xC5BA, 0x85D5, 0xC5BB, 0x5455, 0xC5BC, 0x5076, 0xC5BD, 0x6CA4,
+	0xC5BE, 0x556A, 0xC5BF, 0x8DB4, 0xC5C0, 0x722C, 0xC5C1, 0x5E15,
+	0xC5C2, 0x6015, 0xC5C3, 0x7436, 0xC5C4, 0x62CD, 0xC5C5, 0x6392,
+	0xC5C6, 0x724C, 0xC5C7, 0x5F98, 0xC5C8, 0x6E43, 0xC5C9, 0x6D3E,
+	0xC5CA, 0x6500, 0xC5CB, 0x6F58, 0xC5CC, 0x76D8, 0xC5CD, 0x78D0,
+	0xC5CE, 0x76FC, 0xC5CF, 0x7554, 0xC5D0, 0x5224, 0xC5D1, 0x53DB,
+	0xC5D2, 0x4E53, 0xC5D3, 0x5E9E, 0xC5D4, 0x65C1, 0xC5D5, 0x802A,
+	0xC5D6, 0x80D6, 0xC5D7, 0x629B, 0xC5D8, 0x5486, 0xC5D9, 0x5228,
+	0xC5DA, 0x70AE, 0xC5DB, 0x888D, 0xC5DC, 0x8DD1, 0xC5DD, 0x6CE1,
+	0xC5DE, 0x5478, 0xC5DF, 0x80DA, 0xC5E0, 0x57F9, 0xC5E1, 0x88F4,
+	0xC5E2, 0x8D54, 0xC5E3, 0x966A, 0xC5E4, 0x914D, 0xC5E5, 0x4F69,
+	0xC5E6, 0x6C9B, 0xC5E7, 0x55B7, 0xC5E8, 0x76C6, 0xC5E9, 0x7830,
+	0xC5EA, 0x62A8, 0xC5EB, 0x70F9, 0xC5EC, 0x6F8E, 0xC5ED, 0x5F6D,
+	0xC5EE, 0x84EC, 0xC5EF, 0x68DA, 0xC5F0, 0x787C, 0xC5F1, 0x7BF7,
+	0xC5F2, 0x81A8, 0xC5F3, 0x670B, 0xC5F4, 0x9E4F, 0xC5F5, 0x6367,
+	0xC5F6, 0x78B0, 0xC5F7, 0x576F, 0xC5F8, 0x7812, 0xC5F9, 0x9739,
+	0xC5FA, 0x6279, 0xC5FB, 0x62AB, 0xC5FC, 0x5288, 0xC5FD, 0x7435,
+	0xC5FE, 0x6BD7, 0xC640, 0x826A, 0xC641, 0x826B, 0xC642, 0x826C,
+	0xC643, 0x826D, 0xC644, 0x8271, 0xC645, 0x8275, 0xC646, 0x8276,
+	0xC647, 0x8277, 0xC648, 0x8278, 0xC649, 0x827B, 0xC64A, 0x827C,
+	0xC64B, 0x8280, 0xC64C, 0x8281, 0xC64D, 0x8283, 0xC64E, 0x8285,
+	0xC64F, 0x8286, 0xC650, 0x8287, 0xC651, 0x8289, 0xC652, 0x828C,
+	0xC653, 0x8290, 0xC654, 0x8293, 0xC655, 0x8294, 0xC656, 0x8295,
+	0xC657, 0x8296, 0xC658, 0x829A, 0xC659, 0x829B, 0xC65A, 0x829E,
+	0xC65B, 0x82A0, 0xC65C, 0x82A2, 0xC65D, 0x82A3, 0xC65E, 0x82A7,
+	0xC65F, 0x82B2, 0xC660, 0x82B5, 0xC661, 0x82B6, 0xC662, 0x82BA,
+	0xC663, 0x82BB, 0xC664, 0x82BC, 0xC665, 0x82BF, 0xC666, 0x82C0,
+	0xC667, 0x82C2, 0xC668, 0x82C3, 0xC669, 0x82C5, 0xC66A, 0x82C6,
+	0xC66B, 0x82C9, 0xC66C, 0x82D0, 0xC66D, 0x82D6, 0xC66E, 0x82D9,
+	0xC66F, 0x82DA, 0xC670, 0x82DD, 0xC671, 0x82E2, 0xC672, 0x82E7,
+	0xC673, 0x82E8, 0xC674, 0x82E9, 0xC675, 0x82EA, 0xC676, 0x82EC,
+	0xC677, 0x82ED, 0xC678, 0x82EE, 0xC679, 0x82F0, 0xC67A, 0x82F2,
+	0xC67B, 0x82F3, 0xC67C, 0x82F5, 0xC67D, 0x82F6, 0xC67E, 0x82F8,
+	0xC680, 0x82FA, 0xC681, 0x82FC, 0xC682, 0x82FD, 0xC683, 0x82FE,
+	0xC684, 0x82FF, 0xC685, 0x8300, 0xC686, 0x830A, 0xC687, 0x830B,
+	0xC688, 0x830D, 0xC689, 0x8310, 0xC68A, 0x8312, 0xC68B, 0x8313,
+	0xC68C, 0x8316, 0xC68D, 0x8318, 0xC68E, 0x8319, 0xC68F, 0x831D,
+	0xC690, 0x831E, 0xC691, 0x831F, 0xC692, 0x8320, 0xC693, 0x8321,
+	0xC694, 0x8322, 0xC695, 0x8323, 0xC696, 0x8324, 0xC697, 0x8325,
+	0xC698, 0x8326, 0xC699, 0x8329, 0xC69A, 0x832A, 0xC69B, 0x832E,
+	0xC69C, 0x8330, 0xC69D, 0x8332, 0xC69E, 0x8337, 0xC69F, 0x833B,
+	0xC6A0, 0x833D, 0xC6A1, 0x5564, 0xC6A2, 0x813E, 0xC6A3, 0x75B2,
+	0xC6A4, 0x76AE, 0xC6A5, 0x5339, 0xC6A6, 0x75DE, 0xC6A7, 0x50FB,
+	0xC6A8, 0x5C41, 0xC6A9, 0x8B6C, 0xC6AA, 0x7BC7, 0xC6AB, 0x504F,
+	0xC6AC, 0x7247, 0xC6AD, 0x9A97, 0xC6AE, 0x98D8, 0xC6AF, 0x6F02,
+	0xC6B0, 0x74E2, 0xC6B1, 0x7968, 0xC6B2, 0x6487, 0xC6B3, 0x77A5,
+	0xC6B4, 0x62FC, 0xC6B5, 0x9891, 0xC6B6, 0x8D2B, 0xC6B7, 0x54C1,
+	0xC6B8, 0x8058, 0xC6B9, 0x4E52, 0xC6BA, 0x576A, 0xC6BB, 0x82F9,
+	0xC6BC, 0x840D, 0xC6BD, 0x5E73, 0xC6BE, 0x51ED, 0xC6BF, 0x74F6,
+	0xC6C0, 0x8BC4, 0xC6C1, 0x5C4F, 0xC6C2, 0x5761, 0xC6C3, 0x6CFC,
+	0xC6C4, 0x9887, 0xC6C5, 0x5A46, 0xC6C6, 0x7834, 0xC6C7, 0x9B44,
+	0xC6C8, 0x8FEB, 0xC6C9, 0x7C95, 0xC6CA, 0x5256, 0xC6CB, 0x6251,
+	0xC6CC, 0x94FA, 0xC6CD, 0x4EC6, 0xC6CE, 0x8386, 0xC6CF, 0x8461,
+	0xC6D0, 0x83E9, 0xC6D1, 0x84B2, 0xC6D2, 0x57D4, 0xC6D3, 0x6734,
+	0xC6D4, 0x5703, 0xC6D5, 0x666E, 0xC6D6, 0x6D66, 0xC6D7, 0x8C31,
+	0xC6D8, 0x66DD, 0xC6D9, 0x7011, 0xC6DA, 0x671F, 0xC6DB, 0x6B3A,
+	0xC6DC, 0x6816, 0xC6DD, 0x621A, 0xC6DE, 0x59BB, 0xC6DF, 0x4E03,
+	0xC6E0, 0x51C4, 0xC6E1, 0x6F06, 0xC6E2, 0x67D2, 0xC6E3, 0x6C8F,
+	0xC6E4, 0x5176, 0xC6E5, 0x68CB, 0xC6E6, 0x5947, 0xC6E7, 0x6B67,
+	0xC6E8, 0x7566, 0xC6E9, 0x5D0E, 0xC6EA, 0x8110, 0xC6EB, 0x9F50,
+	0xC6EC, 0x65D7, 0xC6ED, 0x7948, 0xC6EE, 0x7941, 0xC6EF, 0x9A91,
+	0xC6F0, 0x8D77, 0xC6F1, 0x5C82, 0xC6F2, 0x4E5E, 0xC6F3, 0x4F01,
+	0xC6F4, 0x542F, 0xC6F5, 0x5951, 0xC6F6, 0x780C, 0xC6F7, 0x5668,
+	0xC6F8, 0x6C14, 0xC6F9, 0x8FC4, 0xC6FA, 0x5F03, 0xC6FB, 0x6C7D,
+	0xC6FC, 0x6CE3, 0xC6FD, 0x8BAB, 0xC6FE, 0x6390, 0xC740, 0x833E,
+	0xC741, 0x833F, 0xC742, 0x8341, 0xC743, 0x8342, 0xC744, 0x8344,
+	0xC745, 0x8345, 0xC746, 0x8348, 0xC747, 0x834A, 0xC748, 0x834B,
+	0xC749, 0x834C, 0xC74A, 0x834D, 0xC74B, 0x834E, 0xC74C, 0x8353,
+	0xC74D, 0x8355, 0xC74E, 0x8356, 0xC74F, 0x8357, 0xC750, 0x8358,
+	0xC751, 0x8359, 0xC752, 0x835D, 0xC753, 0x8362, 0xC754, 0x8370,
+	0xC755, 0x8371, 0xC756, 0x8372, 0xC757, 0x8373, 0xC758, 0x8374,
+	0xC759, 0x8375, 0xC75A, 0x8376, 0xC75B, 0x8379, 0xC75C, 0x837A,
+	0xC75D, 0x837E, 0xC75E, 0x837F, 0xC75F, 0x8380, 0xC760, 0x8381,
+	0xC761, 0x8382, 0xC762, 0x8383, 0xC763, 0x8384, 0xC764, 0x8387,
+	0xC765, 0x8388, 0xC766, 0x838A, 0xC767, 0x838B, 0xC768, 0x838C,
+	0xC769, 0x838D, 0xC76A, 0x838F, 0xC76B, 0x8390, 0xC76C, 0x8391,
+	0xC76D, 0x8394, 0xC76E, 0x8395, 0xC76F, 0x8396, 0xC770, 0x8397,
+	0xC771, 0x8399, 0xC772, 0x839A, 0xC773, 0x839D, 0xC774, 0x839F,
+	0xC775, 0x83A1, 0xC776, 0x83A2, 0xC777, 0x83A3, 0xC778, 0x83A4,
+	0xC779, 0x83A5, 0xC77A, 0x83A6, 0xC77B, 0x83A7, 0xC77C, 0x83AC,
+	0xC77D, 0x83AD, 0xC77E, 0x83AE, 0xC780, 0x83AF, 0xC781, 0x83B5,
+	0xC782, 0x83BB, 0xC783, 0x83BE, 0xC784, 0x83BF, 0xC785, 0x83C2,
+	0xC786, 0x83C3, 0xC787, 0x83C4, 0xC788, 0x83C6, 0xC789, 0x83C8,
+	0xC78A, 0x83C9, 0xC78B, 0x83CB, 0xC78C, 0x83CD, 0xC78D, 0x83CE,
+	0xC78E, 0x83D0, 0xC78F, 0x83D1, 0xC790, 0x83D2, 0xC791, 0x83D3,
+	0xC792, 0x83D5, 0xC793, 0x83D7, 0xC794, 0x83D9, 0xC795, 0x83DA,
+	0xC796, 0x83DB, 0xC797, 0x83DE, 0xC798, 0x83E2, 0xC799, 0x83E3,
+	0xC79A, 0x83E4, 0xC79B, 0x83E6, 0xC79C, 0x83E7, 0xC79D, 0x83E8,
+	0xC79E, 0x83EB, 0xC79F, 0x83EC, 0xC7A0, 0x83ED, 0xC7A1, 0x6070,
+	0xC7A2, 0x6D3D, 0xC7A3, 0x7275, 0xC7A4, 0x6266, 0xC7A5, 0x948E,
+	0xC7A6, 0x94C5, 0xC7A7, 0x5343, 0xC7A8, 0x8FC1, 0xC7A9, 0x7B7E,
+	0xC7AA, 0x4EDF, 0xC7AB, 0x8C26, 0xC7AC, 0x4E7E, 0xC7AD, 0x9ED4,
+	0xC7AE, 0x94B1, 0xC7AF, 0x94B3, 0xC7B0, 0x524D, 0xC7B1, 0x6F5C,
+	0xC7B2, 0x9063, 0xC7B3, 0x6D45, 0xC7B4, 0x8C34, 0xC7B5, 0x5811,
+	0xC7B6, 0x5D4C, 0xC7B7, 0x6B20, 0xC7B8, 0x6B49, 0xC7B9, 0x67AA,
+	0xC7BA, 0x545B, 0xC7BB, 0x8154, 0xC7BC, 0x7F8C, 0xC7BD, 0x5899,
+	0xC7BE, 0x8537, 0xC7BF, 0x5F3A, 0xC7C0, 0x62A2, 0xC7C1, 0x6A47,
+	0xC7C2, 0x9539, 0xC7C3, 0x6572, 0xC7C4, 0x6084, 0xC7C5, 0x6865,
+	0xC7C6, 0x77A7, 0xC7C7, 0x4E54, 0xC7C8, 0x4FA8, 0xC7C9, 0x5DE7,
+	0xC7CA, 0x9798, 0xC7CB, 0x64AC, 0xC7CC, 0x7FD8, 0xC7CD, 0x5CED,
+	0xC7CE, 0x4FCF, 0xC7CF, 0x7A8D, 0xC7D0, 0x5207, 0xC7D1, 0x8304,
+	0xC7D2, 0x4E14, 0xC7D3, 0x602F, 0xC7D4, 0x7A83, 0xC7D5, 0x94A6,
+	0xC7D6, 0x4FB5, 0xC7D7, 0x4EB2, 0xC7D8, 0x79E6, 0xC7D9, 0x7434,
+	0xC7DA, 0x52E4, 0xC7DB, 0x82B9, 0xC7DC, 0x64D2, 0xC7DD, 0x79BD,
+	0xC7DE, 0x5BDD, 0xC7DF, 0x6C81, 0xC7E0, 0x9752, 0xC7E1, 0x8F7B,
+	0xC7E2, 0x6C22, 0xC7E3, 0x503E, 0xC7E4, 0x537F, 0xC7E5, 0x6E05,
+	0xC7E6, 0x64CE, 0xC7E7, 0x6674, 0xC7E8, 0x6C30, 0xC7E9, 0x60C5,
+	0xC7EA, 0x9877, 0xC7EB, 0x8BF7, 0xC7EC, 0x5E86, 0xC7ED, 0x743C,
+	0xC7EE, 0x7A77, 0xC7EF, 0x79CB, 0xC7F0, 0x4E18, 0xC7F1, 0x90B1,
+	0xC7F2, 0x7403, 0xC7F3, 0x6C42, 0xC7F4, 0x56DA, 0xC7F5, 0x914B,
+	0xC7F6, 0x6CC5, 0xC7F7, 0x8D8B, 0xC7F8, 0x533A, 0xC7F9, 0x86C6,
+	0xC7FA, 0x66F2, 0xC7FB, 0x8EAF, 0xC7FC, 0x5C48, 0xC7FD, 0x9A71,
+	0xC7FE, 0x6E20, 0xC840, 0x83EE, 0xC841, 0x83EF, 0xC842, 0x83F3,
+	0xC843, 0x83F4, 0xC844, 0x83F5, 0xC845, 0x83F6, 0xC846, 0x83F7,
+	0xC847, 0x83FA, 0xC848, 0x83FB, 0xC849, 0x83FC, 0xC84A, 0x83FE,
+	0xC84B, 0x83FF, 0xC84C, 0x8400, 0xC84D, 0x8402, 0xC84E, 0x8405,
+	0xC84F, 0x8407, 0xC850, 0x8408, 0xC851, 0x8409, 0xC852, 0x840A,
+	0xC853, 0x8410, 0xC854, 0x8412, 0xC855, 0x8413, 0xC856, 0x8414,
+	0xC857, 0x8415, 0xC858, 0x8416, 0xC859, 0x8417, 0xC85A, 0x8419,
+	0xC85B, 0x841A, 0xC85C, 0x841B, 0xC85D, 0x841E, 0xC85E, 0x841F,
+	0xC85F, 0x8420, 0xC860, 0x8421, 0xC861, 0x8422, 0xC862, 0x8423,
+	0xC863, 0x8429, 0xC864, 0x842A, 0xC865, 0x842B, 0xC866, 0x842C,
+	0xC867, 0x842D, 0xC868, 0x842E, 0xC869, 0x842F, 0xC86A, 0x8430,
+	0xC86B, 0x8432, 0xC86C, 0x8433, 0xC86D, 0x8434, 0xC86E, 0x8435,
+	0xC86F, 0x8436, 0xC870, 0x8437, 0xC871, 0x8439, 0xC872, 0x843A,
+	0xC873, 0x843B, 0xC874, 0x843E, 0xC875, 0x843F, 0xC876, 0x8440,
+	0xC877, 0x8441, 0xC878, 0x8442, 0xC879, 0x8443, 0xC87A, 0x8444,
+	0xC87B, 0x8445, 0xC87C, 0x8447, 0xC87D, 0x8448, 0xC87E, 0x8449,
+	0xC880, 0x844A, 0xC881, 0x844B, 0xC882, 0x844C, 0xC883, 0x844D,
+	0xC884, 0x844E, 0xC885, 0x844F, 0xC886, 0x8450, 0xC887, 0x8452,
+	0xC888, 0x8453, 0xC889, 0x8454, 0xC88A, 0x8455, 0xC88B, 0x8456,
+	0xC88C, 0x8458, 0xC88D, 0x845D, 0xC88E, 0x845E, 0xC88F, 0x845F,
+	0xC890, 0x8460, 0xC891, 0x8462, 0xC892, 0x8464, 0xC893, 0x8465,
+	0xC894, 0x8466, 0xC895, 0x8467, 0xC896, 0x8468, 0xC897, 0x846A,
+	0xC898, 0x846E, 0xC899, 0x846F, 0xC89A, 0x8470, 0xC89B, 0x8472,
+	0xC89C, 0x8474, 0xC89D, 0x8477, 0xC89E, 0x8479, 0xC89F, 0x847B,
+	0xC8A0, 0x847C, 0xC8A1, 0x53D6, 0xC8A2, 0x5A36, 0xC8A3, 0x9F8B,
+	0xC8A4, 0x8DA3, 0xC8A5, 0x53BB, 0xC8A6, 0x5708, 0xC8A7, 0x98A7,
+	0xC8A8, 0x6743, 0xC8A9, 0x919B, 0xC8AA, 0x6CC9, 0xC8AB, 0x5168,
+	0xC8AC, 0x75CA, 0xC8AD, 0x62F3, 0xC8AE, 0x72AC, 0xC8AF, 0x5238,
+	0xC8B0, 0x529D, 0xC8B1, 0x7F3A, 0xC8B2, 0x7094, 0xC8B3, 0x7638,
+	0xC8B4, 0x5374, 0xC8B5, 0x9E4A, 0xC8B6, 0x69B7, 0xC8B7, 0x786E,
+	0xC8B8, 0x96C0, 0xC8B9, 0x88D9, 0xC8BA, 0x7FA4, 0xC8BB, 0x7136,
+	0xC8BC, 0x71C3, 0xC8BD, 0x5189, 0xC8BE, 0x67D3, 0xC8BF, 0x74E4,
+	0xC8C0, 0x58E4, 0xC8C1, 0x6518, 0xC8C2, 0x56B7, 0xC8C3, 0x8BA9,
+	0xC8C4, 0x9976, 0xC8C5, 0x6270, 0xC8C6, 0x7ED5, 0xC8C7, 0x60F9,
+	0xC8C8, 0x70ED, 0xC8C9, 0x58EC, 0xC8CA, 0x4EC1, 0xC8CB, 0x4EBA,
+	0xC8CC, 0x5FCD, 0xC8CD, 0x97E7, 0xC8CE, 0x4EFB, 0xC8CF, 0x8BA4,
+	0xC8D0, 0x5203, 0xC8D1, 0x598A, 0xC8D2, 0x7EAB, 0xC8D3, 0x6254,
+	0xC8D4, 0x4ECD, 0xC8D5, 0x65E5, 0xC8D6, 0x620E, 0xC8D7, 0x8338,
+	0xC8D8, 0x84C9, 0xC8D9, 0x8363, 0xC8DA, 0x878D, 0xC8DB, 0x7194,
+	0xC8DC, 0x6EB6, 0xC8DD, 0x5BB9, 0xC8DE, 0x7ED2, 0xC8DF, 0x5197,
+	0xC8E0, 0x63C9, 0xC8E1, 0x67D4, 0xC8E2, 0x8089, 0xC8E3, 0x8339,
+	0xC8E4, 0x8815, 0xC8E5, 0x5112, 0xC8E6, 0x5B7A, 0xC8E7, 0x5982,
+	0xC8E8, 0x8FB1, 0xC8E9, 0x4E73, 0xC8EA, 0x6C5D, 0xC8EB, 0x5165,
+	0xC8EC, 0x8925, 0xC8ED, 0x8F6F, 0xC8EE, 0x962E, 0xC8EF, 0x854A,
+	0xC8F0, 0x745E, 0xC8F1, 0x9510, 0xC8F2, 0x95F0, 0xC8F3, 0x6DA6,
+	0xC8F4, 0x82E5, 0xC8F5, 0x5F31, 0xC8F6, 0x6492, 0xC8F7, 0x6D12,
+	0xC8F8, 0x8428, 0xC8F9, 0x816E, 0xC8FA, 0x9CC3, 0xC8FB, 0x585E,
+	0xC8FC, 0x8D5B, 0xC8FD, 0x4E09, 0xC8FE, 0x53C1, 0xC940, 0x847D,
+	0xC941, 0x847E, 0xC942, 0x847F, 0xC943, 0x8480, 0xC944, 0x8481,
+	0xC945, 0x8483, 0xC946, 0x8484, 0xC947, 0x8485, 0xC948, 0x8486,
+	0xC949, 0x848A, 0xC94A, 0x848D, 0xC94B, 0x848F, 0xC94C, 0x8490,
+	0xC94D, 0x8491, 0xC94E, 0x8492, 0xC94F, 0x8493, 0xC950, 0x8494,
+	0xC951, 0x8495, 0xC952, 0x8496, 0xC953, 0x8498, 0xC954, 0x849A,
+	0xC955, 0x849B, 0xC956, 0x849D, 0xC957, 0x849E, 0xC958, 0x849F,
+	0xC959, 0x84A0, 0xC95A, 0x84A2, 0xC95B, 0x84A3, 0xC95C, 0x84A4,
+	0xC95D, 0x84A5, 0xC95E, 0x84A6, 0xC95F, 0x84A7, 0xC960, 0x84A8,
+	0xC961, 0x84A9, 0xC962, 0x84AA, 0xC963, 0x84AB, 0xC964, 0x84AC,
+	0xC965, 0x84AD, 0xC966, 0x84AE, 0xC967, 0x84B0, 0xC968, 0x84B1,
+	0xC969, 0x84B3, 0xC96A, 0x84B5, 0xC96B, 0x84B6, 0xC96C, 0x84B7,
+	0xC96D, 0x84BB, 0xC96E, 0x84BC, 0xC96F, 0x84BE, 0xC970, 0x84C0,
+	0xC971, 0x84C2, 0xC972, 0x84C3, 0xC973, 0x84C5, 0xC974, 0x84C6,
+	0xC975, 0x84C7, 0xC976, 0x84C8, 0xC977, 0x84CB, 0xC978, 0x84CC,
+	0xC979, 0x84CE, 0xC97A, 0x84CF, 0xC97B, 0x84D2, 0xC97C, 0x84D4,
+	0xC97D, 0x84D5, 0xC97E, 0x84D7, 0xC980, 0x84D8, 0xC981, 0x84D9,
+	0xC982, 0x84DA, 0xC983, 0x84DB, 0xC984, 0x84DC, 0xC985, 0x84DE,
+	0xC986, 0x84E1, 0xC987, 0x84E2, 0xC988, 0x84E4, 0xC989, 0x84E7,
+	0xC98A, 0x84E8, 0xC98B, 0x84E9, 0xC98C, 0x84EA, 0xC98D, 0x84EB,
+	0xC98E, 0x84ED, 0xC98F, 0x84EE, 0xC990, 0x84EF, 0xC991, 0x84F1,
+	0xC992, 0x84F2, 0xC993, 0x84F3, 0xC994, 0x84F4, 0xC995, 0x84F5,
+	0xC996, 0x84F6, 0xC997, 0x84F7, 0xC998, 0x84F8, 0xC999, 0x84F9,
+	0xC99A, 0x84FA, 0xC99B, 0x84FB, 0xC99C, 0x84FD, 0xC99D, 0x84FE,
+	0xC99E, 0x8500, 0xC99F, 0x8501, 0xC9A0, 0x8502, 0xC9A1, 0x4F1E,
+	0xC9A2, 0x6563, 0xC9A3, 0x6851, 0xC9A4, 0x55D3, 0xC9A5, 0x4E27,
+	0xC9A6, 0x6414, 0xC9A7, 0x9A9A, 0xC9A8, 0x626B, 0xC9A9, 0x5AC2,
+	0xC9AA, 0x745F, 0xC9AB, 0x8272, 0xC9AC, 0x6DA9, 0xC9AD, 0x68EE,
+	0xC9AE, 0x50E7, 0xC9AF, 0x838E, 0xC9B0, 0x7802, 0xC9B1, 0x6740,
+	0xC9B2, 0x5239, 0xC9B3, 0x6C99, 0xC9B4, 0x7EB1, 0xC9B5, 0x50BB,
+	0xC9B6, 0x5565, 0xC9B7, 0x715E, 0xC9B8, 0x7B5B, 0xC9B9, 0x6652,
+	0xC9BA, 0x73CA, 0xC9BB, 0x82EB, 0xC9BC, 0x6749, 0xC9BD, 0x5C71,
+	0xC9BE, 0x5220, 0xC9BF, 0x717D, 0xC9C0, 0x886B, 0xC9C1, 0x95EA,
+	0xC9C2, 0x9655, 0xC9C3, 0x64C5, 0xC9C4, 0x8D61, 0xC9C5, 0x81B3,
+	0xC9C6, 0x5584, 0xC9C7, 0x6C55, 0xC9C8, 0x6247, 0xC9C9, 0x7F2E,
+	0xC9CA, 0x5892, 0xC9CB, 0x4F24, 0xC9CC, 0x5546, 0xC9CD, 0x8D4F,
+	0xC9CE, 0x664C, 0xC9CF, 0x4E0A, 0xC9D0, 0x5C1A, 0xC9D1, 0x88F3,
+	0xC9D2, 0x68A2, 0xC9D3, 0x634E, 0xC9D4, 0x7A0D, 0xC9D5, 0x70E7,
+	0xC9D6, 0x828D, 0xC9D7, 0x52FA, 0xC9D8, 0x97F6, 0xC9D9, 0x5C11,
+	0xC9DA, 0x54E8, 0xC9DB, 0x90B5, 0xC9DC, 0x7ECD, 0xC9DD, 0x5962,
+	0xC9DE, 0x8D4A, 0xC9DF, 0x86C7, 0xC9E0, 0x820C, 0xC9E1, 0x820D,
+	0xC9E2, 0x8D66, 0xC9E3, 0x6444, 0xC9E4, 0x5C04, 0xC9E5, 0x6151,
+	0xC9E6, 0x6D89, 0xC9E7, 0x793E, 0xC9E8, 0x8BBE, 0xC9E9, 0x7837,
+	0xC9EA, 0x7533, 0xC9EB, 0x547B, 0xC9EC, 0x4F38, 0xC9ED, 0x8EAB,
+	0xC9EE, 0x6DF1, 0xC9EF, 0x5A20, 0xC9F0, 0x7EC5, 0xC9F1, 0x795E,
+	0xC9F2, 0x6C88, 0xC9F3, 0x5BA1, 0xC9F4, 0x5A76, 0xC9F5, 0x751A,
+	0xC9F6, 0x80BE, 0xC9F7, 0x614E, 0xC9F8, 0x6E17, 0xC9F9, 0x58F0,
+	0xC9FA, 0x751F, 0xC9FB, 0x7525, 0xC9FC, 0x7272, 0xC9FD, 0x5347,
+	0xC9FE, 0x7EF3, 0xCA40, 0x8503, 0xCA41, 0x8504, 0xCA42, 0x8505,
+	0xCA43, 0x8506, 0xCA44, 0x8507, 0xCA45, 0x8508, 0xCA46, 0x8509,
+	0xCA47, 0x850A, 0xCA48, 0x850B, 0xCA49, 0x850D, 0xCA4A, 0x850E,
+	0xCA4B, 0x850F, 0xCA4C, 0x8510, 0xCA4D, 0x8512, 0xCA4E, 0x8514,
+	0xCA4F, 0x8515, 0xCA50, 0x8516, 0xCA51, 0x8518, 0xCA52, 0x8519,
+	0xCA53, 0x851B, 0xCA54, 0x851C, 0xCA55, 0x851D, 0xCA56, 0x851E,
+	0xCA57, 0x8520, 0xCA58, 0x8522, 0xCA59, 0x8523, 0xCA5A, 0x8524,
+	0xCA5B, 0x8525, 0xCA5C, 0x8526, 0xCA5D, 0x8527, 0xCA5E, 0x8528,
+	0xCA5F, 0x8529, 0xCA60, 0x852A, 0xCA61, 0x852D, 0xCA62, 0x852E,
+	0xCA63, 0x852F, 0xCA64, 0x8530, 0xCA65, 0x8531, 0xCA66, 0x8532,
+	0xCA67, 0x8533, 0xCA68, 0x8534, 0xCA69, 0x8535, 0xCA6A, 0x8536,
+	0xCA6B, 0x853E, 0xCA6C, 0x853F, 0xCA6D, 0x8540, 0xCA6E, 0x8541,
+	0xCA6F, 0x8542, 0xCA70, 0x8544, 0xCA71, 0x8545, 0xCA72, 0x8546,
+	0xCA73, 0x8547, 0xCA74, 0x854B, 0xCA75, 0x854C, 0xCA76, 0x854D,
+	0xCA77, 0x854E, 0xCA78, 0x854F, 0xCA79, 0x8550, 0xCA7A, 0x8551,
+	0xCA7B, 0x8552, 0xCA7C, 0x8553, 0xCA7D, 0x8554, 0xCA7E, 0x8555,
+	0xCA80, 0x8557, 0xCA81, 0x8558, 0xCA82, 0x855A, 0xCA83, 0x855B,
+	0xCA84, 0x855C, 0xCA85, 0x855D, 0xCA86, 0x855F, 0xCA87, 0x8560,
+	0xCA88, 0x8561, 0xCA89, 0x8562, 0xCA8A, 0x8563, 0xCA8B, 0x8565,
+	0xCA8C, 0x8566, 0xCA8D, 0x8567, 0xCA8E, 0x8569, 0xCA8F, 0x856A,
+	0xCA90, 0x856B, 0xCA91, 0x856C, 0xCA92, 0x856D, 0xCA93, 0x856E,
+	0xCA94, 0x856F, 0xCA95, 0x8570, 0xCA96, 0x8571, 0xCA97, 0x8573,
+	0xCA98, 0x8575, 0xCA99, 0x8576, 0xCA9A, 0x8577, 0xCA9B, 0x8578,
+	0xCA9C, 0x857C, 0xCA9D, 0x857D, 0xCA9E, 0x857F, 0xCA9F, 0x8580,
+	0xCAA0, 0x8581, 0xCAA1, 0x7701, 0xCAA2, 0x76DB, 0xCAA3, 0x5269,
+	0xCAA4, 0x80DC, 0xCAA5, 0x5723, 0xCAA6, 0x5E08, 0xCAA7, 0x5931,
+	0xCAA8, 0x72EE, 0xCAA9, 0x65BD, 0xCAAA, 0x6E7F, 0xCAAB, 0x8BD7,
+	0xCAAC, 0x5C38, 0xCAAD, 0x8671, 0xCAAE, 0x5341, 0xCAAF, 0x77F3,
+	0xCAB0, 0x62FE, 0xCAB1, 0x65F6, 0xCAB2, 0x4EC0, 0xCAB3, 0x98DF,
+	0xCAB4, 0x8680, 0xCAB5, 0x5B9E, 0xCAB6, 0x8BC6, 0xCAB7, 0x53F2,
+	0xCAB8, 0x77E2, 0xCAB9, 0x4F7F, 0xCABA, 0x5C4E, 0xCABB, 0x9A76,
+	0xCABC, 0x59CB, 0xCABD, 0x5F0F, 0xCABE, 0x793A, 0xCABF, 0x58EB,
+	0xCAC0, 0x4E16, 0xCAC1, 0x67FF, 0xCAC2, 0x4E8B, 0xCAC3, 0x62ED,
+	0xCAC4, 0x8A93, 0xCAC5, 0x901D, 0xCAC6, 0x52BF, 0xCAC7, 0x662F,
+	0xCAC8, 0x55DC, 0xCAC9, 0x566C, 0xCACA, 0x9002, 0xCACB, 0x4ED5,
+	0xCACC, 0x4F8D, 0xCACD, 0x91CA, 0xCACE, 0x9970, 0xCACF, 0x6C0F,
+	0xCAD0, 0x5E02, 0xCAD1, 0x6043, 0xCAD2, 0x5BA4, 0xCAD3, 0x89C6,
+	0xCAD4, 0x8BD5, 0xCAD5, 0x6536, 0xCAD6, 0x624B, 0xCAD7, 0x9996,
+	0xCAD8, 0x5B88, 0xCAD9, 0x5BFF, 0xCADA, 0x6388, 0xCADB, 0x552E,
+	0xCADC, 0x53D7, 0xCADD, 0x7626, 0xCADE, 0x517D, 0xCADF, 0x852C,
+	0xCAE0, 0x67A2, 0xCAE1, 0x68B3, 0xCAE2, 0x6B8A, 0xCAE3, 0x6292,
+	0xCAE4, 0x8F93, 0xCAE5, 0x53D4, 0xCAE6, 0x8212, 0xCAE7, 0x6DD1,
+	0xCAE8, 0x758F, 0xCAE9, 0x4E66, 0xCAEA, 0x8D4E, 0xCAEB, 0x5B70,
+	0xCAEC, 0x719F, 0xCAED, 0x85AF, 0xCAEE, 0x6691, 0xCAEF, 0x66D9,
+	0xCAF0, 0x7F72, 0xCAF1, 0x8700, 0xCAF2, 0x9ECD, 0xCAF3, 0x9F20,
+	0xCAF4, 0x5C5E, 0xCAF5, 0x672F, 0xCAF6, 0x8FF0, 0xCAF7, 0x6811,
+	0xCAF8, 0x675F, 0xCAF9, 0x620D, 0xCAFA, 0x7AD6, 0xCAFB, 0x5885,
+	0xCAFC, 0x5EB6, 0xCAFD, 0x6570, 0xCAFE, 0x6F31, 0xCB40, 0x8582,
+	0xCB41, 0x8583, 0xCB42, 0x8586, 0xCB43, 0x8588, 0xCB44, 0x8589,
+	0xCB45, 0x858A, 0xCB46, 0x858B, 0xCB47, 0x858C, 0xCB48, 0x858D,
+	0xCB49, 0x858E, 0xCB4A, 0x8590, 0xCB4B, 0x8591, 0xCB4C, 0x8592,
+	0xCB4D, 0x8593, 0xCB4E, 0x8594, 0xCB4F, 0x8595, 0xCB50, 0x8596,
+	0xCB51, 0x8597, 0xCB52, 0x8598, 0xCB53, 0x8599, 0xCB54, 0x859A,
+	0xCB55, 0x859D, 0xCB56, 0x859E, 0xCB57, 0x859F, 0xCB58, 0x85A0,
+	0xCB59, 0x85A1, 0xCB5A, 0x85A2, 0xCB5B, 0x85A3, 0xCB5C, 0x85A5,
+	0xCB5D, 0x85A6, 0xCB5E, 0x85A7, 0xCB5F, 0x85A9, 0xCB60, 0x85AB,
+	0xCB61, 0x85AC, 0xCB62, 0x85AD, 0xCB63, 0x85B1, 0xCB64, 0x85B2,
+	0xCB65, 0x85B3, 0xCB66, 0x85B4, 0xCB67, 0x85B5, 0xCB68, 0x85B6,
+	0xCB69, 0x85B8, 0xCB6A, 0x85BA, 0xCB6B, 0x85BB, 0xCB6C, 0x85BC,
+	0xCB6D, 0x85BD, 0xCB6E, 0x85BE, 0xCB6F, 0x85BF, 0xCB70, 0x85C0,
+	0xCB71, 0x85C2, 0xCB72, 0x85C3, 0xCB73, 0x85C4, 0xCB74, 0x85C5,
+	0xCB75, 0x85C6, 0xCB76, 0x85C7, 0xCB77, 0x85C8, 0xCB78, 0x85CA,
+	0xCB79, 0x85CB, 0xCB7A, 0x85CC, 0xCB7B, 0x85CD, 0xCB7C, 0x85CE,
+	0xCB7D, 0x85D1, 0xCB7E, 0x85D2, 0xCB80, 0x85D4, 0xCB81, 0x85D6,
+	0xCB82, 0x85D7, 0xCB83, 0x85D8, 0xCB84, 0x85D9, 0xCB85, 0x85DA,
+	0xCB86, 0x85DB, 0xCB87, 0x85DD, 0xCB88, 0x85DE, 0xCB89, 0x85DF,
+	0xCB8A, 0x85E0, 0xCB8B, 0x85E1, 0xCB8C, 0x85E2, 0xCB8D, 0x85E3,
+	0xCB8E, 0x85E5, 0xCB8F, 0x85E6, 0xCB90, 0x85E7, 0xCB91, 0x85E8,
+	0xCB92, 0x85EA, 0xCB93, 0x85EB, 0xCB94, 0x85EC, 0xCB95, 0x85ED,
+	0xCB96, 0x85EE, 0xCB97, 0x85EF, 0xCB98, 0x85F0, 0xCB99, 0x85F1,
+	0xCB9A, 0x85F2, 0xCB9B, 0x85F3, 0xCB9C, 0x85F4, 0xCB9D, 0x85F5,
+	0xCB9E, 0x85F6, 0xCB9F, 0x85F7, 0xCBA0, 0x85F8, 0xCBA1, 0x6055,
+	0xCBA2, 0x5237, 0xCBA3, 0x800D, 0xCBA4, 0x6454, 0xCBA5, 0x8870,
+	0xCBA6, 0x7529, 0xCBA7, 0x5E05, 0xCBA8, 0x6813, 0xCBA9, 0x62F4,
+	0xCBAA, 0x971C, 0xCBAB, 0x53CC, 0xCBAC, 0x723D, 0xCBAD, 0x8C01,
+	0xCBAE, 0x6C34, 0xCBAF, 0x7761, 0xCBB0, 0x7A0E, 0xCBB1, 0x542E,
+	0xCBB2, 0x77AC, 0xCBB3, 0x987A, 0xCBB4, 0x821C, 0xCBB5, 0x8BF4,
+	0xCBB6, 0x7855, 0xCBB7, 0x6714, 0xCBB8, 0x70C1, 0xCBB9, 0x65AF,
+	0xCBBA, 0x6495, 0xCBBB, 0x5636, 0xCBBC, 0x601D, 0xCBBD, 0x79C1,
+	0xCBBE, 0x53F8, 0xCBBF, 0x4E1D, 0xCBC0, 0x6B7B, 0xCBC1, 0x8086,
+	0xCBC2, 0x5BFA, 0xCBC3, 0x55E3, 0xCBC4, 0x56DB, 0xCBC5, 0x4F3A,
+	0xCBC6, 0x4F3C, 0xCBC7, 0x9972, 0xCBC8, 0x5DF3, 0xCBC9, 0x677E,
+	0xCBCA, 0x8038, 0xCBCB, 0x6002, 0xCBCC, 0x9882, 0xCBCD, 0x9001,
+	0xCBCE, 0x5B8B, 0xCBCF, 0x8BBC, 0xCBD0, 0x8BF5, 0xCBD1, 0x641C,
+	0xCBD2, 0x8258, 0xCBD3, 0x64DE, 0xCBD4, 0x55FD, 0xCBD5, 0x82CF,
+	0xCBD6, 0x9165, 0xCBD7, 0x4FD7, 0xCBD8, 0x7D20, 0xCBD9, 0x901F,
+	0xCBDA, 0x7C9F, 0xCBDB, 0x50F3, 0xCBDC, 0x5851, 0xCBDD, 0x6EAF,
+	0xCBDE, 0x5BBF, 0xCBDF, 0x8BC9, 0xCBE0, 0x8083, 0xCBE1, 0x9178,
+	0xCBE2, 0x849C, 0xCBE3, 0x7B97, 0xCBE4, 0x867D, 0xCBE5, 0x968B,
+	0xCBE6, 0x968F, 0xCBE7, 0x7EE5, 0xCBE8, 0x9AD3, 0xCBE9, 0x788E,
+	0xCBEA, 0x5C81, 0xCBEB, 0x7A57, 0xCBEC, 0x9042, 0xCBED, 0x96A7,
+	0xCBEE, 0x795F, 0xCBEF, 0x5B59, 0xCBF0, 0x635F, 0xCBF1, 0x7B0B,
+	0xCBF2, 0x84D1, 0xCBF3, 0x68AD, 0xCBF4, 0x5506, 0xCBF5, 0x7F29,
+	0xCBF6, 0x7410, 0xCBF7, 0x7D22, 0xCBF8, 0x9501, 0xCBF9, 0x6240,
+	0xCBFA, 0x584C, 0xCBFB, 0x4ED6, 0xCBFC, 0x5B83, 0xCBFD, 0x5979,
+	0xCBFE, 0x5854, 0xCC40, 0x85F9, 0xCC41, 0x85FA, 0xCC42, 0x85FC,
+	0xCC43, 0x85FD, 0xCC44, 0x85FE, 0xCC45, 0x8600, 0xCC46, 0x8601,
+	0xCC47, 0x8602, 0xCC48, 0x8603, 0xCC49, 0x8604, 0xCC4A, 0x8606,
+	0xCC4B, 0x8607, 0xCC4C, 0x8608, 0xCC4D, 0x8609, 0xCC4E, 0x860A,
+	0xCC4F, 0x860B, 0xCC50, 0x860C, 0xCC51, 0x860D, 0xCC52, 0x860E,
+	0xCC53, 0x860F, 0xCC54, 0x8610, 0xCC55, 0x8612, 0xCC56, 0x8613,
+	0xCC57, 0x8614, 0xCC58, 0x8615, 0xCC59, 0x8617, 0xCC5A, 0x8618,
+	0xCC5B, 0x8619, 0xCC5C, 0x861A, 0xCC5D, 0x861B, 0xCC5E, 0x861C,
+	0xCC5F, 0x861D, 0xCC60, 0x861E, 0xCC61, 0x861F, 0xCC62, 0x8620,
+	0xCC63, 0x8621, 0xCC64, 0x8622, 0xCC65, 0x8623, 0xCC66, 0x8624,
+	0xCC67, 0x8625, 0xCC68, 0x8626, 0xCC69, 0x8628, 0xCC6A, 0x862A,
+	0xCC6B, 0x862B, 0xCC6C, 0x862C, 0xCC6D, 0x862D, 0xCC6E, 0x862E,
+	0xCC6F, 0x862F, 0xCC70, 0x8630, 0xCC71, 0x8631, 0xCC72, 0x8632,
+	0xCC73, 0x8633, 0xCC74, 0x8634, 0xCC75, 0x8635, 0xCC76, 0x8636,
+	0xCC77, 0x8637, 0xCC78, 0x8639, 0xCC79, 0x863A, 0xCC7A, 0x863B,
+	0xCC7B, 0x863D, 0xCC7C, 0x863E, 0xCC7D, 0x863F, 0xCC7E, 0x8640,
+	0xCC80, 0x8641, 0xCC81, 0x8642, 0xCC82, 0x8643, 0xCC83, 0x8644,
+	0xCC84, 0x8645, 0xCC85, 0x8646, 0xCC86, 0x8647, 0xCC87, 0x8648,
+	0xCC88, 0x8649, 0xCC89, 0x864A, 0xCC8A, 0x864B, 0xCC8B, 0x864C,
+	0xCC8C, 0x8652, 0xCC8D, 0x8653, 0xCC8E, 0x8655, 0xCC8F, 0x8656,
+	0xCC90, 0x8657, 0xCC91, 0x8658, 0xCC92, 0x8659, 0xCC93, 0x865B,
+	0xCC94, 0x865C, 0xCC95, 0x865D, 0xCC96, 0x865F, 0xCC97, 0x8660,
+	0xCC98, 0x8661, 0xCC99, 0x8663, 0xCC9A, 0x8664, 0xCC9B, 0x8665,
+	0xCC9C, 0x8666, 0xCC9D, 0x8667, 0xCC9E, 0x8668, 0xCC9F, 0x8669,
+	0xCCA0, 0x866A, 0xCCA1, 0x736D, 0xCCA2, 0x631E, 0xCCA3, 0x8E4B,
+	0xCCA4, 0x8E0F, 0xCCA5, 0x80CE, 0xCCA6, 0x82D4, 0xCCA7, 0x62AC,
+	0xCCA8, 0x53F0, 0xCCA9, 0x6CF0, 0xCCAA, 0x915E, 0xCCAB, 0x592A,
+	0xCCAC, 0x6001, 0xCCAD, 0x6C70, 0xCCAE, 0x574D, 0xCCAF, 0x644A,
+	0xCCB0, 0x8D2A, 0xCCB1, 0x762B, 0xCCB2, 0x6EE9, 0xCCB3, 0x575B,
+	0xCCB4, 0x6A80, 0xCCB5, 0x75F0, 0xCCB6, 0x6F6D, 0xCCB7, 0x8C2D,
+	0xCCB8, 0x8C08, 0xCCB9, 0x5766, 0xCCBA, 0x6BEF, 0xCCBB, 0x8892,
+	0xCCBC, 0x78B3, 0xCCBD, 0x63A2, 0xCCBE, 0x53F9, 0xCCBF, 0x70AD,
+	0xCCC0, 0x6C64, 0xCCC1, 0x5858, 0xCCC2, 0x642A, 0xCCC3, 0x5802,
+	0xCCC4, 0x68E0, 0xCCC5, 0x819B, 0xCCC6, 0x5510, 0xCCC7, 0x7CD6,
+	0xCCC8, 0x5018, 0xCCC9, 0x8EBA, 0xCCCA, 0x6DCC, 0xCCCB, 0x8D9F,
+	0xCCCC, 0x70EB, 0xCCCD, 0x638F, 0xCCCE, 0x6D9B, 0xCCCF, 0x6ED4,
+	0xCCD0, 0x7EE6, 0xCCD1, 0x8404, 0xCCD2, 0x6843, 0xCCD3, 0x9003,
+	0xCCD4, 0x6DD8, 0xCCD5, 0x9676, 0xCCD6, 0x8BA8, 0xCCD7, 0x5957,
+	0xCCD8, 0x7279, 0xCCD9, 0x85E4, 0xCCDA, 0x817E, 0xCCDB, 0x75BC,
+	0xCCDC, 0x8A8A, 0xCCDD, 0x68AF, 0xCCDE, 0x5254, 0xCCDF, 0x8E22,
+	0xCCE0, 0x9511, 0xCCE1, 0x63D0, 0xCCE2, 0x9898, 0xCCE3, 0x8E44,
+	0xCCE4, 0x557C, 0xCCE5, 0x4F53, 0xCCE6, 0x66FF, 0xCCE7, 0x568F,
+	0xCCE8, 0x60D5, 0xCCE9, 0x6D95, 0xCCEA, 0x5243, 0xCCEB, 0x5C49,
+	0xCCEC, 0x5929, 0xCCED, 0x6DFB, 0xCCEE, 0x586B, 0xCCEF, 0x7530,
+	0xCCF0, 0x751C, 0xCCF1, 0x606C, 0xCCF2, 0x8214, 0xCCF3, 0x8146,
+	0xCCF4, 0x6311, 0xCCF5, 0x6761, 0xCCF6, 0x8FE2, 0xCCF7, 0x773A,
+	0xCCF8, 0x8DF3, 0xCCF9, 0x8D34, 0xCCFA, 0x94C1, 0xCCFB, 0x5E16,
+	0xCCFC, 0x5385, 0xCCFD, 0x542C, 0xCCFE, 0x70C3, 0xCD40, 0x866D,
+	0xCD41, 0x866F, 0xCD42, 0x8670, 0xCD43, 0x8672, 0xCD44, 0x8673,
+	0xCD45, 0x8674, 0xCD46, 0x8675, 0xCD47, 0x8676, 0xCD48, 0x8677,
+	0xCD49, 0x8678, 0xCD4A, 0x8683, 0xCD4B, 0x8684, 0xCD4C, 0x8685,
+	0xCD4D, 0x8686, 0xCD4E, 0x8687, 0xCD4F, 0x8688, 0xCD50, 0x8689,
+	0xCD51, 0x868E, 0xCD52, 0x868F, 0xCD53, 0x8690, 0xCD54, 0x8691,
+	0xCD55, 0x8692, 0xCD56, 0x8694, 0xCD57, 0x8696, 0xCD58, 0x8697,
+	0xCD59, 0x8698, 0xCD5A, 0x8699, 0xCD5B, 0x869A, 0xCD5C, 0x869B,
+	0xCD5D, 0x869E, 0xCD5E, 0x869F, 0xCD5F, 0x86A0, 0xCD60, 0x86A1,
+	0xCD61, 0x86A2, 0xCD62, 0x86A5, 0xCD63, 0x86A6, 0xCD64, 0x86AB,
+	0xCD65, 0x86AD, 0xCD66, 0x86AE, 0xCD67, 0x86B2, 0xCD68, 0x86B3,
+	0xCD69, 0x86B7, 0xCD6A, 0x86B8, 0xCD6B, 0x86B9, 0xCD6C, 0x86BB,
+	0xCD6D, 0x86BC, 0xCD6E, 0x86BD, 0xCD6F, 0x86BE, 0xCD70, 0x86BF,
+	0xCD71, 0x86C1, 0xCD72, 0x86C2, 0xCD73, 0x86C3, 0xCD74, 0x86C5,
+	0xCD75, 0x86C8, 0xCD76, 0x86CC, 0xCD77, 0x86CD, 0xCD78, 0x86D2,
+	0xCD79, 0x86D3, 0xCD7A, 0x86D5, 0xCD7B, 0x86D6, 0xCD7C, 0x86D7,
+	0xCD7D, 0x86DA, 0xCD7E, 0x86DC, 0xCD80, 0x86DD, 0xCD81, 0x86E0,
+	0xCD82, 0x86E1, 0xCD83, 0x86E2, 0xCD84, 0x86E3, 0xCD85, 0x86E5,
+	0xCD86, 0x86E6, 0xCD87, 0x86E7, 0xCD88, 0x86E8, 0xCD89, 0x86EA,
+	0xCD8A, 0x86EB, 0xCD8B, 0x86EC, 0xCD8C, 0x86EF, 0xCD8D, 0x86F5,
+	0xCD8E, 0x86F6, 0xCD8F, 0x86F7, 0xCD90, 0x86FA, 0xCD91, 0x86FB,
+	0xCD92, 0x86FC, 0xCD93, 0x86FD, 0xCD94, 0x86FF, 0xCD95, 0x8701,
+	0xCD96, 0x8704, 0xCD97, 0x8705, 0xCD98, 0x8706, 0xCD99, 0x870B,
+	0xCD9A, 0x870C, 0xCD9B, 0x870E, 0xCD9C, 0x870F, 0xCD9D, 0x8710,
+	0xCD9E, 0x8711, 0xCD9F, 0x8714, 0xCDA0, 0x8716, 0xCDA1, 0x6C40,
+	0xCDA2, 0x5EF7, 0xCDA3, 0x505C, 0xCDA4, 0x4EAD, 0xCDA5, 0x5EAD,
+	0xCDA6, 0x633A, 0xCDA7, 0x8247, 0xCDA8, 0x901A, 0xCDA9, 0x6850,
+	0xCDAA, 0x916E, 0xCDAB, 0x77B3, 0xCDAC, 0x540C, 0xCDAD, 0x94DC,
+	0xCDAE, 0x5F64, 0xCDAF, 0x7AE5, 0xCDB0, 0x6876, 0xCDB1, 0x6345,
+	0xCDB2, 0x7B52, 0xCDB3, 0x7EDF, 0xCDB4, 0x75DB, 0xCDB5, 0x5077,
+	0xCDB6, 0x6295, 0xCDB7, 0x5934, 0xCDB8, 0x900F, 0xCDB9, 0x51F8,
+	0xCDBA, 0x79C3, 0xCDBB, 0x7A81, 0xCDBC, 0x56FE, 0xCDBD, 0x5F92,
+	0xCDBE, 0x9014, 0xCDBF, 0x6D82, 0xCDC0, 0x5C60, 0xCDC1, 0x571F,
+	0xCDC2, 0x5410, 0xCDC3, 0x5154, 0xCDC4, 0x6E4D, 0xCDC5, 0x56E2,
+	0xCDC6, 0x63A8, 0xCDC7, 0x9893, 0xCDC8, 0x817F, 0xCDC9, 0x8715,
+	0xCDCA, 0x892A, 0xCDCB, 0x9000, 0xCDCC, 0x541E, 0xCDCD, 0x5C6F,
+	0xCDCE, 0x81C0, 0xCDCF, 0x62D6, 0xCDD0, 0x6258, 0xCDD1, 0x8131,
+	0xCDD2, 0x9E35, 0xCDD3, 0x9640, 0xCDD4, 0x9A6E, 0xCDD5, 0x9A7C,
+	0xCDD6, 0x692D, 0xCDD7, 0x59A5, 0xCDD8, 0x62D3, 0xCDD9, 0x553E,
+	0xCDDA, 0x6316, 0xCDDB, 0x54C7, 0xCDDC, 0x86D9, 0xCDDD, 0x6D3C,
+	0xCDDE, 0x5A03, 0xCDDF, 0x74E6, 0xCDE0, 0x889C, 0xCDE1, 0x6B6A,
+	0xCDE2, 0x5916, 0xCDE3, 0x8C4C, 0xCDE4, 0x5F2F, 0xCDE5, 0x6E7E,
+	0xCDE6, 0x73A9, 0xCDE7, 0x987D, 0xCDE8, 0x4E38, 0xCDE9, 0x70F7,
+	0xCDEA, 0x5B8C, 0xCDEB, 0x7897, 0xCDEC, 0x633D, 0xCDED, 0x665A,
+	0xCDEE, 0x7696, 0xCDEF, 0x60CB, 0xCDF0, 0x5B9B, 0xCDF1, 0x5A49,
+	0xCDF2, 0x4E07, 0xCDF3, 0x8155, 0xCDF4, 0x6C6A, 0xCDF5, 0x738B,
+	0xCDF6, 0x4EA1, 0xCDF7, 0x6789, 0xCDF8, 0x7F51, 0xCDF9, 0x5F80,
+	0xCDFA, 0x65FA, 0xCDFB, 0x671B, 0xCDFC, 0x5FD8, 0xCDFD, 0x5984,
+	0xCDFE, 0x5A01, 0xCE40, 0x8719, 0xCE41, 0x871B, 0xCE42, 0x871D,
+	0xCE43, 0x871F, 0xCE44, 0x8720, 0xCE45, 0x8724, 0xCE46, 0x8726,
+	0xCE47, 0x8727, 0xCE48, 0x8728, 0xCE49, 0x872A, 0xCE4A, 0x872B,
+	0xCE4B, 0x872C, 0xCE4C, 0x872D, 0xCE4D, 0x872F, 0xCE4E, 0x8730,
+	0xCE4F, 0x8732, 0xCE50, 0x8733, 0xCE51, 0x8735, 0xCE52, 0x8736,
+	0xCE53, 0x8738, 0xCE54, 0x8739, 0xCE55, 0x873A, 0xCE56, 0x873C,
+	0xCE57, 0x873D, 0xCE58, 0x8740, 0xCE59, 0x8741, 0xCE5A, 0x8742,
+	0xCE5B, 0x8743, 0xCE5C, 0x8744, 0xCE5D, 0x8745, 0xCE5E, 0x8746,
+	0xCE5F, 0x874A, 0xCE60, 0x874B, 0xCE61, 0x874D, 0xCE62, 0x874F,
+	0xCE63, 0x8750, 0xCE64, 0x8751, 0xCE65, 0x8752, 0xCE66, 0x8754,
+	0xCE67, 0x8755, 0xCE68, 0x8756, 0xCE69, 0x8758, 0xCE6A, 0x875A,
+	0xCE6B, 0x875B, 0xCE6C, 0x875C, 0xCE6D, 0x875D, 0xCE6E, 0x875E,
+	0xCE6F, 0x875F, 0xCE70, 0x8761, 0xCE71, 0x8762, 0xCE72, 0x8766,
+	0xCE73, 0x8767, 0xCE74, 0x8768, 0xCE75, 0x8769, 0xCE76, 0x876A,
+	0xCE77, 0x876B, 0xCE78, 0x876C, 0xCE79, 0x876D, 0xCE7A, 0x876F,
+	0xCE7B, 0x8771, 0xCE7C, 0x8772, 0xCE7D, 0x8773, 0xCE7E, 0x8775,
+	0xCE80, 0x8777, 0xCE81, 0x8778, 0xCE82, 0x8779, 0xCE83, 0x877A,
+	0xCE84, 0x877F, 0xCE85, 0x8780, 0xCE86, 0x8781, 0xCE87, 0x8784,
+	0xCE88, 0x8786, 0xCE89, 0x8787, 0xCE8A, 0x8789, 0xCE8B, 0x878A,
+	0xCE8C, 0x878C, 0xCE8D, 0x878E, 0xCE8E, 0x878F, 0xCE8F, 0x8790,
+	0xCE90, 0x8791, 0xCE91, 0x8792, 0xCE92, 0x8794, 0xCE93, 0x8795,
+	0xCE94, 0x8796, 0xCE95, 0x8798, 0xCE96, 0x8799, 0xCE97, 0x879A,
+	0xCE98, 0x879B, 0xCE99, 0x879C, 0xCE9A, 0x879D, 0xCE9B, 0x879E,
+	0xCE9C, 0x87A0, 0xCE9D, 0x87A1, 0xCE9E, 0x87A2, 0xCE9F, 0x87A3,
+	0xCEA0, 0x87A4, 0xCEA1, 0x5DCD, 0xCEA2, 0x5FAE, 0xCEA3, 0x5371,
+	0xCEA4, 0x97E6, 0xCEA5, 0x8FDD, 0xCEA6, 0x6845, 0xCEA7, 0x56F4,
+	0xCEA8, 0x552F, 0xCEA9, 0x60DF, 0xCEAA, 0x4E3A, 0xCEAB, 0x6F4D,
+	0xCEAC, 0x7EF4, 0xCEAD, 0x82C7, 0xCEAE, 0x840E, 0xCEAF, 0x59D4,
+	0xCEB0, 0x4F1F, 0xCEB1, 0x4F2A, 0xCEB2, 0x5C3E, 0xCEB3, 0x7EAC,
+	0xCEB4, 0x672A, 0xCEB5, 0x851A, 0xCEB6, 0x5473, 0xCEB7, 0x754F,
+	0xCEB8, 0x80C3, 0xCEB9, 0x5582, 0xCEBA, 0x9B4F, 0xCEBB, 0x4F4D,
+	0xCEBC, 0x6E2D, 0xCEBD, 0x8C13, 0xCEBE, 0x5C09, 0xCEBF, 0x6170,
+	0xCEC0, 0x536B, 0xCEC1, 0x761F, 0xCEC2, 0x6E29, 0xCEC3, 0x868A,
+	0xCEC4, 0x6587, 0xCEC5, 0x95FB, 0xCEC6, 0x7EB9, 0xCEC7, 0x543B,
+	0xCEC8, 0x7A33, 0xCEC9, 0x7D0A, 0xCECA, 0x95EE, 0xCECB, 0x55E1,
+	0xCECC, 0x7FC1, 0xCECD, 0x74EE, 0xCECE, 0x631D, 0xCECF, 0x8717,
+	0xCED0, 0x6DA1, 0xCED1, 0x7A9D, 0xCED2, 0x6211, 0xCED3, 0x65A1,
+	0xCED4, 0x5367, 0xCED5, 0x63E1, 0xCED6, 0x6C83, 0xCED7, 0x5DEB,
+	0xCED8, 0x545C, 0xCED9, 0x94A8, 0xCEDA, 0x4E4C, 0xCEDB, 0x6C61,
+	0xCEDC, 0x8BEC, 0xCEDD, 0x5C4B, 0xCEDE, 0x65E0, 0xCEDF, 0x829C,
+	0xCEE0, 0x68A7, 0xCEE1, 0x543E, 0xCEE2, 0x5434, 0xCEE3, 0x6BCB,
+	0xCEE4, 0x6B66, 0xCEE5, 0x4E94, 0xCEE6, 0x6342, 0xCEE7, 0x5348,
+	0xCEE8, 0x821E, 0xCEE9, 0x4F0D, 0xCEEA, 0x4FAE, 0xCEEB, 0x575E,
+	0xCEEC, 0x620A, 0xCEED, 0x96FE, 0xCEEE, 0x6664, 0xCEEF, 0x7269,
+	0xCEF0, 0x52FF, 0xCEF1, 0x52A1, 0xCEF2, 0x609F, 0xCEF3, 0x8BEF,
+	0xCEF4, 0x6614, 0xCEF5, 0x7199, 0xCEF6, 0x6790, 0xCEF7, 0x897F,
+	0xCEF8, 0x7852, 0xCEF9, 0x77FD, 0xCEFA, 0x6670, 0xCEFB, 0x563B,
+	0xCEFC, 0x5438, 0xCEFD, 0x9521, 0xCEFE, 0x727A, 0xCF40, 0x87A5,
+	0xCF41, 0x87A6, 0xCF42, 0x87A7, 0xCF43, 0x87A9, 0xCF44, 0x87AA,
+	0xCF45, 0x87AE, 0xCF46, 0x87B0, 0xCF47, 0x87B1, 0xCF48, 0x87B2,
+	0xCF49, 0x87B4, 0xCF4A, 0x87B6, 0xCF4B, 0x87B7, 0xCF4C, 0x87B8,
+	0xCF4D, 0x87B9, 0xCF4E, 0x87BB, 0xCF4F, 0x87BC, 0xCF50, 0x87BE,
+	0xCF51, 0x87BF, 0xCF52, 0x87C1, 0xCF53, 0x87C2, 0xCF54, 0x87C3,
+	0xCF55, 0x87C4, 0xCF56, 0x87C5, 0xCF57, 0x87C7, 0xCF58, 0x87C8,
+	0xCF59, 0x87C9, 0xCF5A, 0x87CC, 0xCF5B, 0x87CD, 0xCF5C, 0x87CE,
+	0xCF5D, 0x87CF, 0xCF5E, 0x87D0, 0xCF5F, 0x87D4, 0xCF60, 0x87D5,
+	0xCF61, 0x87D6, 0xCF62, 0x87D7, 0xCF63, 0x87D8, 0xCF64, 0x87D9,
+	0xCF65, 0x87DA, 0xCF66, 0x87DC, 0xCF67, 0x87DD, 0xCF68, 0x87DE,
+	0xCF69, 0x87DF, 0xCF6A, 0x87E1, 0xCF6B, 0x87E2, 0xCF6C, 0x87E3,
+	0xCF6D, 0x87E4, 0xCF6E, 0x87E6, 0xCF6F, 0x87E7, 0xCF70, 0x87E8,
+	0xCF71, 0x87E9, 0xCF72, 0x87EB, 0xCF73, 0x87EC, 0xCF74, 0x87ED,
+	0xCF75, 0x87EF, 0xCF76, 0x87F0, 0xCF77, 0x87F1, 0xCF78, 0x87F2,
+	0xCF79, 0x87F3, 0xCF7A, 0x87F4, 0xCF7B, 0x87F5, 0xCF7C, 0x87F6,
+	0xCF7D, 0x87F7, 0xCF7E, 0x87F8, 0xCF80, 0x87FA, 0xCF81, 0x87FB,
+	0xCF82, 0x87FC, 0xCF83, 0x87FD, 0xCF84, 0x87FF, 0xCF85, 0x8800,
+	0xCF86, 0x8801, 0xCF87, 0x8802, 0xCF88, 0x8804, 0xCF89, 0x8805,
+	0xCF8A, 0x8806, 0xCF8B, 0x8807, 0xCF8C, 0x8808, 0xCF8D, 0x8809,
+	0xCF8E, 0x880B, 0xCF8F, 0x880C, 0xCF90, 0x880D, 0xCF91, 0x880E,
+	0xCF92, 0x880F, 0xCF93, 0x8810, 0xCF94, 0x8811, 0xCF95, 0x8812,
+	0xCF96, 0x8814, 0xCF97, 0x8817, 0xCF98, 0x8818, 0xCF99, 0x8819,
+	0xCF9A, 0x881A, 0xCF9B, 0x881C, 0xCF9C, 0x881D, 0xCF9D, 0x881E,
+	0xCF9E, 0x881F, 0xCF9F, 0x8820, 0xCFA0, 0x8823, 0xCFA1, 0x7A00,
+	0xCFA2, 0x606F, 0xCFA3, 0x5E0C, 0xCFA4, 0x6089, 0xCFA5, 0x819D,
+	0xCFA6, 0x5915, 0xCFA7, 0x60DC, 0xCFA8, 0x7184, 0xCFA9, 0x70EF,
+	0xCFAA, 0x6EAA, 0xCFAB, 0x6C50, 0xCFAC, 0x7280, 0xCFAD, 0x6A84,
+	0xCFAE, 0x88AD, 0xCFAF, 0x5E2D, 0xCFB0, 0x4E60, 0xCFB1, 0x5AB3,
+	0xCFB2, 0x559C, 0xCFB3, 0x94E3, 0xCFB4, 0x6D17, 0xCFB5, 0x7CFB,
+	0xCFB6, 0x9699, 0xCFB7, 0x620F, 0xCFB8, 0x7EC6, 0xCFB9, 0x778E,
+	0xCFBA, 0x867E, 0xCFBB, 0x5323, 0xCFBC, 0x971E, 0xCFBD, 0x8F96,
+	0xCFBE, 0x6687, 0xCFBF, 0x5CE1, 0xCFC0, 0x4FA0, 0xCFC1, 0x72ED,
+	0xCFC2, 0x4E0B, 0xCFC3, 0x53A6, 0xCFC4, 0x590F, 0xCFC5, 0x5413,
+	0xCFC6, 0x6380, 0xCFC7, 0x9528, 0xCFC8, 0x5148, 0xCFC9, 0x4ED9,
+	0xCFCA, 0x9C9C, 0xCFCB, 0x7EA4, 0xCFCC, 0x54B8, 0xCFCD, 0x8D24,
+	0xCFCE, 0x8854, 0xCFCF, 0x8237, 0xCFD0, 0x95F2, 0xCFD1, 0x6D8E,
+	0xCFD2, 0x5F26, 0xCFD3, 0x5ACC, 0xCFD4, 0x663E, 0xCFD5, 0x9669,
+	0xCFD6, 0x73B0, 0xCFD7, 0x732E, 0xCFD8, 0x53BF, 0xCFD9, 0x817A,
+	0xCFDA, 0x9985, 0xCFDB, 0x7FA1, 0xCFDC, 0x5BAA, 0xCFDD, 0x9677,
+	0xCFDE, 0x9650, 0xCFDF, 0x7EBF, 0xCFE0, 0x76F8, 0xCFE1, 0x53A2,
+	0xCFE2, 0x9576, 0xCFE3, 0x9999, 0xCFE4, 0x7BB1, 0xCFE5, 0x8944,
+	0xCFE6, 0x6E58, 0xCFE7, 0x4E61, 0xCFE8, 0x7FD4, 0xCFE9, 0x7965,
+	0xCFEA, 0x8BE6, 0xCFEB, 0x60F3, 0xCFEC, 0x54CD, 0xCFED, 0x4EAB,
+	0xCFEE, 0x9879, 0xCFEF, 0x5DF7, 0xCFF0, 0x6A61, 0xCFF1, 0x50CF,
+	0xCFF2, 0x5411, 0xCFF3, 0x8C61, 0xCFF4, 0x8427, 0xCFF5, 0x785D,
+	0xCFF6, 0x9704, 0xCFF7, 0x524A, 0xCFF8, 0x54EE, 0xCFF9, 0x56A3,
+	0xCFFA, 0x9500, 0xCFFB, 0x6D88, 0xCFFC, 0x5BB5, 0xCFFD, 0x6DC6,
+	0xCFFE, 0x6653, 0xD040, 0x8824, 0xD041, 0x8825, 0xD042, 0x8826,
+	0xD043, 0x8827, 0xD044, 0x8828, 0xD045, 0x8829, 0xD046, 0x882A,
+	0xD047, 0x882B, 0xD048, 0x882C, 0xD049, 0x882D, 0xD04A, 0x882E,
+	0xD04B, 0x882F, 0xD04C, 0x8830, 0xD04D, 0x8831, 0xD04E, 0x8833,
+	0xD04F, 0x8834, 0xD050, 0x8835, 0xD051, 0x8836, 0xD052, 0x8837,
+	0xD053, 0x8838, 0xD054, 0x883A, 0xD055, 0x883B, 0xD056, 0x883D,
+	0xD057, 0x883E, 0xD058, 0x883F, 0xD059, 0x8841, 0xD05A, 0x8842,
+	0xD05B, 0x8843, 0xD05C, 0x8846, 0xD05D, 0x8847, 0xD05E, 0x8848,
+	0xD05F, 0x8849, 0xD060, 0x884A, 0xD061, 0x884B, 0xD062, 0x884E,
+	0xD063, 0x884F, 0xD064, 0x8850, 0xD065, 0x8851, 0xD066, 0x8852,
+	0xD067, 0x8853, 0xD068, 0x8855, 0xD069, 0x8856, 0xD06A, 0x8858,
+	0xD06B, 0x885A, 0xD06C, 0x885B, 0xD06D, 0x885C, 0xD06E, 0x885D,
+	0xD06F, 0x885E, 0xD070, 0x885F, 0xD071, 0x8860, 0xD072, 0x8866,
+	0xD073, 0x8867, 0xD074, 0x886A, 0xD075, 0x886D, 0xD076, 0x886F,
+	0xD077, 0x8871, 0xD078, 0x8873, 0xD079, 0x8874, 0xD07A, 0x8875,
+	0xD07B, 0x8876, 0xD07C, 0x8878, 0xD07D, 0x8879, 0xD07E, 0x887A,
+	0xD080, 0x887B, 0xD081, 0x887C, 0xD082, 0x8880, 0xD083, 0x8883,
+	0xD084, 0x8886, 0xD085, 0x8887, 0xD086, 0x8889, 0xD087, 0x888A,
+	0xD088, 0x888C, 0xD089, 0x888E, 0xD08A, 0x888F, 0xD08B, 0x8890,
+	0xD08C, 0x8891, 0xD08D, 0x8893, 0xD08E, 0x8894, 0xD08F, 0x8895,
+	0xD090, 0x8897, 0xD091, 0x8898, 0xD092, 0x8899, 0xD093, 0x889A,
+	0xD094, 0x889B, 0xD095, 0x889D, 0xD096, 0x889E, 0xD097, 0x889F,
+	0xD098, 0x88A0, 0xD099, 0x88A1, 0xD09A, 0x88A3, 0xD09B, 0x88A5,
+	0xD09C, 0x88A6, 0xD09D, 0x88A7, 0xD09E, 0x88A8, 0xD09F, 0x88A9,
+	0xD0A0, 0x88AA, 0xD0A1, 0x5C0F, 0xD0A2, 0x5B5D, 0xD0A3, 0x6821,
+	0xD0A4, 0x8096, 0xD0A5, 0x5578, 0xD0A6, 0x7B11, 0xD0A7, 0x6548,
+	0xD0A8, 0x6954, 0xD0A9, 0x4E9B, 0xD0AA, 0x6B47, 0xD0AB, 0x874E,
+	0xD0AC, 0x978B, 0xD0AD, 0x534F, 0xD0AE, 0x631F, 0xD0AF, 0x643A,
+	0xD0B0, 0x90AA, 0xD0B1, 0x659C, 0xD0B2, 0x80C1, 0xD0B3, 0x8C10,
+	0xD0B4, 0x5199, 0xD0B5, 0x68B0, 0xD0B6, 0x5378, 0xD0B7, 0x87F9,
+	0xD0B8, 0x61C8, 0xD0B9, 0x6CC4, 0xD0BA, 0x6CFB, 0xD0BB, 0x8C22,
+	0xD0BC, 0x5C51, 0xD0BD, 0x85AA, 0xD0BE, 0x82AF, 0xD0BF, 0x950C,
+	0xD0C0, 0x6B23, 0xD0C1, 0x8F9B, 0xD0C2, 0x65B0, 0xD0C3, 0x5FFB,
+	0xD0C4, 0x5FC3, 0xD0C5, 0x4FE1, 0xD0C6, 0x8845, 0xD0C7, 0x661F,
+	0xD0C8, 0x8165, 0xD0C9, 0x7329, 0xD0CA, 0x60FA, 0xD0CB, 0x5174,
+	0xD0CC, 0x5211, 0xD0CD, 0x578B, 0xD0CE, 0x5F62, 0xD0CF, 0x90A2,
+	0xD0D0, 0x884C, 0xD0D1, 0x9192, 0xD0D2, 0x5E78, 0xD0D3, 0x674F,
+	0xD0D4, 0x6027, 0xD0D5, 0x59D3, 0xD0D6, 0x5144, 0xD0D7, 0x51F6,
+	0xD0D8, 0x80F8, 0xD0D9, 0x5308, 0xD0DA, 0x6C79, 0xD0DB, 0x96C4,
+	0xD0DC, 0x718A, 0xD0DD, 0x4F11, 0xD0DE, 0x4FEE, 0xD0DF, 0x7F9E,
+	0xD0E0, 0x673D, 0xD0E1, 0x55C5, 0xD0E2, 0x9508, 0xD0E3, 0x79C0,
+	0xD0E4, 0x8896, 0xD0E5, 0x7EE3, 0xD0E6, 0x589F, 0xD0E7, 0x620C,
+	0xD0E8, 0x9700, 0xD0E9, 0x865A, 0xD0EA, 0x5618, 0xD0EB, 0x987B,
+	0xD0EC, 0x5F90, 0xD0ED, 0x8BB8, 0xD0EE, 0x84C4, 0xD0EF, 0x9157,
+	0xD0F0, 0x53D9, 0xD0F1, 0x65ED, 0xD0F2, 0x5E8F, 0xD0F3, 0x755C,
+	0xD0F4, 0x6064, 0xD0F5, 0x7D6E, 0xD0F6, 0x5A7F, 0xD0F7, 0x7EEA,
+	0xD0F8, 0x7EED, 0xD0F9, 0x8F69, 0xD0FA, 0x55A7, 0xD0FB, 0x5BA3,
+	0xD0FC, 0x60AC, 0xD0FD, 0x65CB, 0xD0FE, 0x7384, 0xD140, 0x88AC,
+	0xD141, 0x88AE, 0xD142, 0x88AF, 0xD143, 0x88B0, 0xD144, 0x88B2,
+	0xD145, 0x88B3, 0xD146, 0x88B4, 0xD147, 0x88B5, 0xD148, 0x88B6,
+	0xD149, 0x88B8, 0xD14A, 0x88B9, 0xD14B, 0x88BA, 0xD14C, 0x88BB,
+	0xD14D, 0x88BD, 0xD14E, 0x88BE, 0xD14F, 0x88BF, 0xD150, 0x88C0,
+	0xD151, 0x88C3, 0xD152, 0x88C4, 0xD153, 0x88C7, 0xD154, 0x88C8,
+	0xD155, 0x88CA, 0xD156, 0x88CB, 0xD157, 0x88CC, 0xD158, 0x88CD,
+	0xD159, 0x88CF, 0xD15A, 0x88D0, 0xD15B, 0x88D1, 0xD15C, 0x88D3,
+	0xD15D, 0x88D6, 0xD15E, 0x88D7, 0xD15F, 0x88DA, 0xD160, 0x88DB,
+	0xD161, 0x88DC, 0xD162, 0x88DD, 0xD163, 0x88DE, 0xD164, 0x88E0,
+	0xD165, 0x88E1, 0xD166, 0x88E6, 0xD167, 0x88E7, 0xD168, 0x88E9,
+	0xD169, 0x88EA, 0xD16A, 0x88EB, 0xD16B, 0x88EC, 0xD16C, 0x88ED,
+	0xD16D, 0x88EE, 0xD16E, 0x88EF, 0xD16F, 0x88F2, 0xD170, 0x88F5,
+	0xD171, 0x88F6, 0xD172, 0x88F7, 0xD173, 0x88FA, 0xD174, 0x88FB,
+	0xD175, 0x88FD, 0xD176, 0x88FF, 0xD177, 0x8900, 0xD178, 0x8901,
+	0xD179, 0x8903, 0xD17A, 0x8904, 0xD17B, 0x8905, 0xD17C, 0x8906,
+	0xD17D, 0x8907, 0xD17E, 0x8908, 0xD180, 0x8909, 0xD181, 0x890B,
+	0xD182, 0x890C, 0xD183, 0x890D, 0xD184, 0x890E, 0xD185, 0x890F,
+	0xD186, 0x8911, 0xD187, 0x8914, 0xD188, 0x8915, 0xD189, 0x8916,
+	0xD18A, 0x8917, 0xD18B, 0x8918, 0xD18C, 0x891C, 0xD18D, 0x891D,
+	0xD18E, 0x891E, 0xD18F, 0x891F, 0xD190, 0x8920, 0xD191, 0x8922,
+	0xD192, 0x8923, 0xD193, 0x8924, 0xD194, 0x8926, 0xD195, 0x8927,
+	0xD196, 0x8928, 0xD197, 0x8929, 0xD198, 0x892C, 0xD199, 0x892D,
+	0xD19A, 0x892E, 0xD19B, 0x892F, 0xD19C, 0x8931, 0xD19D, 0x8932,
+	0xD19E, 0x8933, 0xD19F, 0x8935, 0xD1A0, 0x8937, 0xD1A1, 0x9009,
+	0xD1A2, 0x7663, 0xD1A3, 0x7729, 0xD1A4, 0x7EDA, 0xD1A5, 0x9774,
+	0xD1A6, 0x859B, 0xD1A7, 0x5B66, 0xD1A8, 0x7A74, 0xD1A9, 0x96EA,
+	0xD1AA, 0x8840, 0xD1AB, 0x52CB, 0xD1AC, 0x718F, 0xD1AD, 0x5FAA,
+	0xD1AE, 0x65EC, 0xD1AF, 0x8BE2, 0xD1B0, 0x5BFB, 0xD1B1, 0x9A6F,
+	0xD1B2, 0x5DE1, 0xD1B3, 0x6B89, 0xD1B4, 0x6C5B, 0xD1B5, 0x8BAD,
+	0xD1B6, 0x8BAF, 0xD1B7, 0x900A, 0xD1B8, 0x8FC5, 0xD1B9, 0x538B,
+	0xD1BA, 0x62BC, 0xD1BB, 0x9E26, 0xD1BC, 0x9E2D, 0xD1BD, 0x5440,
+	0xD1BE, 0x4E2B, 0xD1BF, 0x82BD, 0xD1C0, 0x7259, 0xD1C1, 0x869C,
+	0xD1C2, 0x5D16, 0xD1C3, 0x8859, 0xD1C4, 0x6DAF, 0xD1C5, 0x96C5,
+	0xD1C6, 0x54D1, 0xD1C7, 0x4E9A, 0xD1C8, 0x8BB6, 0xD1C9, 0x7109,
+	0xD1CA, 0x54BD, 0xD1CB, 0x9609, 0xD1CC, 0x70DF, 0xD1CD, 0x6DF9,
+	0xD1CE, 0x76D0, 0xD1CF, 0x4E25, 0xD1D0, 0x7814, 0xD1D1, 0x8712,
+	0xD1D2, 0x5CA9, 0xD1D3, 0x5EF6, 0xD1D4, 0x8A00, 0xD1D5, 0x989C,
+	0xD1D6, 0x960E, 0xD1D7, 0x708E, 0xD1D8, 0x6CBF, 0xD1D9, 0x5944,
+	0xD1DA, 0x63A9, 0xD1DB, 0x773C, 0xD1DC, 0x884D, 0xD1DD, 0x6F14,
+	0xD1DE, 0x8273, 0xD1DF, 0x5830, 0xD1E0, 0x71D5, 0xD1E1, 0x538C,
+	0xD1E2, 0x781A, 0xD1E3, 0x96C1, 0xD1E4, 0x5501, 0xD1E5, 0x5F66,
+	0xD1E6, 0x7130, 0xD1E7, 0x5BB4, 0xD1E8, 0x8C1A, 0xD1E9, 0x9A8C,
+	0xD1EA, 0x6B83, 0xD1EB, 0x592E, 0xD1EC, 0x9E2F, 0xD1ED, 0x79E7,
+	0xD1EE, 0x6768, 0xD1EF, 0x626C, 0xD1F0, 0x4F6F, 0xD1F1, 0x75A1,
+	0xD1F2, 0x7F8A, 0xD1F3, 0x6D0B, 0xD1F4, 0x9633, 0xD1F5, 0x6C27,
+	0xD1F6, 0x4EF0, 0xD1F7, 0x75D2, 0xD1F8, 0x517B, 0xD1F9, 0x6837,
+	0xD1FA, 0x6F3E, 0xD1FB, 0x9080, 0xD1FC, 0x8170, 0xD1FD, 0x5996,
+	0xD1FE, 0x7476, 0xD240, 0x8938, 0xD241, 0x8939, 0xD242, 0x893A,
+	0xD243, 0x893B, 0xD244, 0x893C, 0xD245, 0x893D, 0xD246, 0x893E,
+	0xD247, 0x893F, 0xD248, 0x8940, 0xD249, 0x8942, 0xD24A, 0x8943,
+	0xD24B, 0x8945, 0xD24C, 0x8946, 0xD24D, 0x8947, 0xD24E, 0x8948,
+	0xD24F, 0x8949, 0xD250, 0x894A, 0xD251, 0x894B, 0xD252, 0x894C,
+	0xD253, 0x894D, 0xD254, 0x894E, 0xD255, 0x894F, 0xD256, 0x8950,
+	0xD257, 0x8951, 0xD258, 0x8952, 0xD259, 0x8953, 0xD25A, 0x8954,
+	0xD25B, 0x8955, 0xD25C, 0x8956, 0xD25D, 0x8957, 0xD25E, 0x8958,
+	0xD25F, 0x8959, 0xD260, 0x895A, 0xD261, 0x895B, 0xD262, 0x895C,
+	0xD263, 0x895D, 0xD264, 0x8960, 0xD265, 0x8961, 0xD266, 0x8962,
+	0xD267, 0x8963, 0xD268, 0x8964, 0xD269, 0x8965, 0xD26A, 0x8967,
+	0xD26B, 0x8968, 0xD26C, 0x8969, 0xD26D, 0x896A, 0xD26E, 0x896B,
+	0xD26F, 0x896C, 0xD270, 0x896D, 0xD271, 0x896E, 0xD272, 0x896F,
+	0xD273, 0x8970, 0xD274, 0x8971, 0xD275, 0x8972, 0xD276, 0x8973,
+	0xD277, 0x8974, 0xD278, 0x8975, 0xD279, 0x8976, 0xD27A, 0x8977,
+	0xD27B, 0x8978, 0xD27C, 0x8979, 0xD27D, 0x897A, 0xD27E, 0x897C,
+	0xD280, 0x897D, 0xD281, 0x897E, 0xD282, 0x8980, 0xD283, 0x8982,
+	0xD284, 0x8984, 0xD285, 0x8985, 0xD286, 0x8987, 0xD287, 0x8988,
+	0xD288, 0x8989, 0xD289, 0x898A, 0xD28A, 0x898B, 0xD28B, 0x898C,
+	0xD28C, 0x898D, 0xD28D, 0x898E, 0xD28E, 0x898F, 0xD28F, 0x8990,
+	0xD290, 0x8991, 0xD291, 0x8992, 0xD292, 0x8993, 0xD293, 0x8994,
+	0xD294, 0x8995, 0xD295, 0x8996, 0xD296, 0x8997, 0xD297, 0x8998,
+	0xD298, 0x8999, 0xD299, 0x899A, 0xD29A, 0x899B, 0xD29B, 0x899C,
+	0xD29C, 0x899D, 0xD29D, 0x899E, 0xD29E, 0x899F, 0xD29F, 0x89A0,
+	0xD2A0, 0x89A1, 0xD2A1, 0x6447, 0xD2A2, 0x5C27, 0xD2A3, 0x9065,
+	0xD2A4, 0x7A91, 0xD2A5, 0x8C23, 0xD2A6, 0x59DA, 0xD2A7, 0x54AC,
+	0xD2A8, 0x8200, 0xD2A9, 0x836F, 0xD2AA, 0x8981, 0xD2AB, 0x8000,
+	0xD2AC, 0x6930, 0xD2AD, 0x564E, 0xD2AE, 0x8036, 0xD2AF, 0x7237,
+	0xD2B0, 0x91CE, 0xD2B1, 0x51B6, 0xD2B2, 0x4E5F, 0xD2B3, 0x9875,
+	0xD2B4, 0x6396, 0xD2B5, 0x4E1A, 0xD2B6, 0x53F6, 0xD2B7, 0x66F3,
+	0xD2B8, 0x814B, 0xD2B9, 0x591C, 0xD2BA, 0x6DB2, 0xD2BB, 0x4E00,
+	0xD2BC, 0x58F9, 0xD2BD, 0x533B, 0xD2BE, 0x63D6, 0xD2BF, 0x94F1,
+	0xD2C0, 0x4F9D, 0xD2C1, 0x4F0A, 0xD2C2, 0x8863, 0xD2C3, 0x9890,
+	0xD2C4, 0x5937, 0xD2C5, 0x9057, 0xD2C6, 0x79FB, 0xD2C7, 0x4EEA,
+	0xD2C8, 0x80F0, 0xD2C9, 0x7591, 0xD2CA, 0x6C82, 0xD2CB, 0x5B9C,
+	0xD2CC, 0x59E8, 0xD2CD, 0x5F5D, 0xD2CE, 0x6905, 0xD2CF, 0x8681,
+	0xD2D0, 0x501A, 0xD2D1, 0x5DF2, 0xD2D2, 0x4E59, 0xD2D3, 0x77E3,
+	0xD2D4, 0x4EE5, 0xD2D5, 0x827A, 0xD2D6, 0x6291, 0xD2D7, 0x6613,
+	0xD2D8, 0x9091, 0xD2D9, 0x5C79, 0xD2DA, 0x4EBF, 0xD2DB, 0x5F79,
+	0xD2DC, 0x81C6, 0xD2DD, 0x9038, 0xD2DE, 0x8084, 0xD2DF, 0x75AB,
+	0xD2E0, 0x4EA6, 0xD2E1, 0x88D4, 0xD2E2, 0x610F, 0xD2E3, 0x6BC5,
+	0xD2E4, 0x5FC6, 0xD2E5, 0x4E49, 0xD2E6, 0x76CA, 0xD2E7, 0x6EA2,
+	0xD2E8, 0x8BE3, 0xD2E9, 0x8BAE, 0xD2EA, 0x8C0A, 0xD2EB, 0x8BD1,
+	0xD2EC, 0x5F02, 0xD2ED, 0x7FFC, 0xD2EE, 0x7FCC, 0xD2EF, 0x7ECE,
+	0xD2F0, 0x8335, 0xD2F1, 0x836B, 0xD2F2, 0x56E0, 0xD2F3, 0x6BB7,
+	0xD2F4, 0x97F3, 0xD2F5, 0x9634, 0xD2F6, 0x59FB, 0xD2F7, 0x541F,
+	0xD2F8, 0x94F6, 0xD2F9, 0x6DEB, 0xD2FA, 0x5BC5, 0xD2FB, 0x996E,
+	0xD2FC, 0x5C39, 0xD2FD, 0x5F15, 0xD2FE, 0x9690, 0xD340, 0x89A2,
+	0xD341, 0x89A3, 0xD342, 0x89A4, 0xD343, 0x89A5, 0xD344, 0x89A6,
+	0xD345, 0x89A7, 0xD346, 0x89A8, 0xD347, 0x89A9, 0xD348, 0x89AA,
+	0xD349, 0x89AB, 0xD34A, 0x89AC, 0xD34B, 0x89AD, 0xD34C, 0x89AE,
+	0xD34D, 0x89AF, 0xD34E, 0x89B0, 0xD34F, 0x89B1, 0xD350, 0x89B2,
+	0xD351, 0x89B3, 0xD352, 0x89B4, 0xD353, 0x89B5, 0xD354, 0x89B6,
+	0xD355, 0x89B7, 0xD356, 0x89B8, 0xD357, 0x89B9, 0xD358, 0x89BA,
+	0xD359, 0x89BB, 0xD35A, 0x89BC, 0xD35B, 0x89BD, 0xD35C, 0x89BE,
+	0xD35D, 0x89BF, 0xD35E, 0x89C0, 0xD35F, 0x89C3, 0xD360, 0x89CD,
+	0xD361, 0x89D3, 0xD362, 0x89D4, 0xD363, 0x89D5, 0xD364, 0x89D7,
+	0xD365, 0x89D8, 0xD366, 0x89D9, 0xD367, 0x89DB, 0xD368, 0x89DD,
+	0xD369, 0x89DF, 0xD36A, 0x89E0, 0xD36B, 0x89E1, 0xD36C, 0x89E2,
+	0xD36D, 0x89E4, 0xD36E, 0x89E7, 0xD36F, 0x89E8, 0xD370, 0x89E9,
+	0xD371, 0x89EA, 0xD372, 0x89EC, 0xD373, 0x89ED, 0xD374, 0x89EE,
+	0xD375, 0x89F0, 0xD376, 0x89F1, 0xD377, 0x89F2, 0xD378, 0x89F4,
+	0xD379, 0x89F5, 0xD37A, 0x89F6, 0xD37B, 0x89F7, 0xD37C, 0x89F8,
+	0xD37D, 0x89F9, 0xD37E, 0x89FA, 0xD380, 0x89FB, 0xD381, 0x89FC,
+	0xD382, 0x89FD, 0xD383, 0x89FE, 0xD384, 0x89FF, 0xD385, 0x8A01,
+	0xD386, 0x8A02, 0xD387, 0x8A03, 0xD388, 0x8A04, 0xD389, 0x8A05,
+	0xD38A, 0x8A06, 0xD38B, 0x8A08, 0xD38C, 0x8A09, 0xD38D, 0x8A0A,
+	0xD38E, 0x8A0B, 0xD38F, 0x8A0C, 0xD390, 0x8A0D, 0xD391, 0x8A0E,
+	0xD392, 0x8A0F, 0xD393, 0x8A10, 0xD394, 0x8A11, 0xD395, 0x8A12,
+	0xD396, 0x8A13, 0xD397, 0x8A14, 0xD398, 0x8A15, 0xD399, 0x8A16,
+	0xD39A, 0x8A17, 0xD39B, 0x8A18, 0xD39C, 0x8A19, 0xD39D, 0x8A1A,
+	0xD39E, 0x8A1B, 0xD39F, 0x8A1C, 0xD3A0, 0x8A1D, 0xD3A1, 0x5370,
+	0xD3A2, 0x82F1, 0xD3A3, 0x6A31, 0xD3A4, 0x5A74, 0xD3A5, 0x9E70,
+	0xD3A6, 0x5E94, 0xD3A7, 0x7F28, 0xD3A8, 0x83B9, 0xD3A9, 0x8424,
+	0xD3AA, 0x8425, 0xD3AB, 0x8367, 0xD3AC, 0x8747, 0xD3AD, 0x8FCE,
+	0xD3AE, 0x8D62, 0xD3AF, 0x76C8, 0xD3B0, 0x5F71, 0xD3B1, 0x9896,
+	0xD3B2, 0x786C, 0xD3B3, 0x6620, 0xD3B4, 0x54DF, 0xD3B5, 0x62E5,
+	0xD3B6, 0x4F63, 0xD3B7, 0x81C3, 0xD3B8, 0x75C8, 0xD3B9, 0x5EB8,
+	0xD3BA, 0x96CD, 0xD3BB, 0x8E0A, 0xD3BC, 0x86F9, 0xD3BD, 0x548F,
+	0xD3BE, 0x6CF3, 0xD3BF, 0x6D8C, 0xD3C0, 0x6C38, 0xD3C1, 0x607F,
+	0xD3C2, 0x52C7, 0xD3C3, 0x7528, 0xD3C4, 0x5E7D, 0xD3C5, 0x4F18,
+	0xD3C6, 0x60A0, 0xD3C7, 0x5FE7, 0xD3C8, 0x5C24, 0xD3C9, 0x7531,
+	0xD3CA, 0x90AE, 0xD3CB, 0x94C0, 0xD3CC, 0x72B9, 0xD3CD, 0x6CB9,
+	0xD3CE, 0x6E38, 0xD3CF, 0x9149, 0xD3D0, 0x6709, 0xD3D1, 0x53CB,
+	0xD3D2, 0x53F3, 0xD3D3, 0x4F51, 0xD3D4, 0x91C9, 0xD3D5, 0x8BF1,
+	0xD3D6, 0x53C8, 0xD3D7, 0x5E7C, 0xD3D8, 0x8FC2, 0xD3D9, 0x6DE4,
+	0xD3DA, 0x4E8E, 0xD3DB, 0x76C2, 0xD3DC, 0x6986, 0xD3DD, 0x865E,
+	0xD3DE, 0x611A, 0xD3DF, 0x8206, 0xD3E0, 0x4F59, 0xD3E1, 0x4FDE,
+	0xD3E2, 0x903E, 0xD3E3, 0x9C7C, 0xD3E4, 0x6109, 0xD3E5, 0x6E1D,
+	0xD3E6, 0x6E14, 0xD3E7, 0x9685, 0xD3E8, 0x4E88, 0xD3E9, 0x5A31,
+	0xD3EA, 0x96E8, 0xD3EB, 0x4E0E, 0xD3EC, 0x5C7F, 0xD3ED, 0x79B9,
+	0xD3EE, 0x5B87, 0xD3EF, 0x8BED, 0xD3F0, 0x7FBD, 0xD3F1, 0x7389,
+	0xD3F2, 0x57DF, 0xD3F3, 0x828B, 0xD3F4, 0x90C1, 0xD3F5, 0x5401,
+	0xD3F6, 0x9047, 0xD3F7, 0x55BB, 0xD3F8, 0x5CEA, 0xD3F9, 0x5FA1,
+	0xD3FA, 0x6108, 0xD3FB, 0x6B32, 0xD3FC, 0x72F1, 0xD3FD, 0x80B2,
+	0xD3FE, 0x8A89, 0xD440, 0x8A1E, 0xD441, 0x8A1F, 0xD442, 0x8A20,
+	0xD443, 0x8A21, 0xD444, 0x8A22, 0xD445, 0x8A23, 0xD446, 0x8A24,
+	0xD447, 0x8A25, 0xD448, 0x8A26, 0xD449, 0x8A27, 0xD44A, 0x8A28,
+	0xD44B, 0x8A29, 0xD44C, 0x8A2A, 0xD44D, 0x8A2B, 0xD44E, 0x8A2C,
+	0xD44F, 0x8A2D, 0xD450, 0x8A2E, 0xD451, 0x8A2F, 0xD452, 0x8A30,
+	0xD453, 0x8A31, 0xD454, 0x8A32, 0xD455, 0x8A33, 0xD456, 0x8A34,
+	0xD457, 0x8A35, 0xD458, 0x8A36, 0xD459, 0x8A37, 0xD45A, 0x8A38,
+	0xD45B, 0x8A39, 0xD45C, 0x8A3A, 0xD45D, 0x8A3B, 0xD45E, 0x8A3C,
+	0xD45F, 0x8A3D, 0xD460, 0x8A3F, 0xD461, 0x8A40, 0xD462, 0x8A41,
+	0xD463, 0x8A42, 0xD464, 0x8A43, 0xD465, 0x8A44, 0xD466, 0x8A45,
+	0xD467, 0x8A46, 0xD468, 0x8A47, 0xD469, 0x8A49, 0xD46A, 0x8A4A,
+	0xD46B, 0x8A4B, 0xD46C, 0x8A4C, 0xD46D, 0x8A4D, 0xD46E, 0x8A4E,
+	0xD46F, 0x8A4F, 0xD470, 0x8A50, 0xD471, 0x8A51, 0xD472, 0x8A52,
+	0xD473, 0x8A53, 0xD474, 0x8A54, 0xD475, 0x8A55, 0xD476, 0x8A56,
+	0xD477, 0x8A57, 0xD478, 0x8A58, 0xD479, 0x8A59, 0xD47A, 0x8A5A,
+	0xD47B, 0x8A5B, 0xD47C, 0x8A5C, 0xD47D, 0x8A5D, 0xD47E, 0x8A5E,
+	0xD480, 0x8A5F, 0xD481, 0x8A60, 0xD482, 0x8A61, 0xD483, 0x8A62,
+	0xD484, 0x8A63, 0xD485, 0x8A64, 0xD486, 0x8A65, 0xD487, 0x8A66,
+	0xD488, 0x8A67, 0xD489, 0x8A68, 0xD48A, 0x8A69, 0xD48B, 0x8A6A,
+	0xD48C, 0x8A6B, 0xD48D, 0x8A6C, 0xD48E, 0x8A6D, 0xD48F, 0x8A6E,
+	0xD490, 0x8A6F, 0xD491, 0x8A70, 0xD492, 0x8A71, 0xD493, 0x8A72,
+	0xD494, 0x8A73, 0xD495, 0x8A74, 0xD496, 0x8A75, 0xD497, 0x8A76,
+	0xD498, 0x8A77, 0xD499, 0x8A78, 0xD49A, 0x8A7A, 0xD49B, 0x8A7B,
+	0xD49C, 0x8A7C, 0xD49D, 0x8A7D, 0xD49E, 0x8A7E, 0xD49F, 0x8A7F,
+	0xD4A0, 0x8A80, 0xD4A1, 0x6D74, 0xD4A2, 0x5BD3, 0xD4A3, 0x88D5,
+	0xD4A4, 0x9884, 0xD4A5, 0x8C6B, 0xD4A6, 0x9A6D, 0xD4A7, 0x9E33,
+	0xD4A8, 0x6E0A, 0xD4A9, 0x51A4, 0xD4AA, 0x5143, 0xD4AB, 0x57A3,
+	0xD4AC, 0x8881, 0xD4AD, 0x539F, 0xD4AE, 0x63F4, 0xD4AF, 0x8F95,
+	0xD4B0, 0x56ED, 0xD4B1, 0x5458, 0xD4B2, 0x5706, 0xD4B3, 0x733F,
+	0xD4B4, 0x6E90, 0xD4B5, 0x7F18, 0xD4B6, 0x8FDC, 0xD4B7, 0x82D1,
+	0xD4B8, 0x613F, 0xD4B9, 0x6028, 0xD4BA, 0x9662, 0xD4BB, 0x66F0,
+	0xD4BC, 0x7EA6, 0xD4BD, 0x8D8A, 0xD4BE, 0x8DC3, 0xD4BF, 0x94A5,
+	0xD4C0, 0x5CB3, 0xD4C1, 0x7CA4, 0xD4C2, 0x6708, 0xD4C3, 0x60A6,
+	0xD4C4, 0x9605, 0xD4C5, 0x8018, 0xD4C6, 0x4E91, 0xD4C7, 0x90E7,
+	0xD4C8, 0x5300, 0xD4C9, 0x9668, 0xD4CA, 0x5141, 0xD4CB, 0x8FD0,
+	0xD4CC, 0x8574, 0xD4CD, 0x915D, 0xD4CE, 0x6655, 0xD4CF, 0x97F5,
+	0xD4D0, 0x5B55, 0xD4D1, 0x531D, 0xD4D2, 0x7838, 0xD4D3, 0x6742,
+	0xD4D4, 0x683D, 0xD4D5, 0x54C9, 0xD4D6, 0x707E, 0xD4D7, 0x5BB0,
+	0xD4D8, 0x8F7D, 0xD4D9, 0x518D, 0xD4DA, 0x5728, 0xD4DB, 0x54B1,
+	0xD4DC, 0x6512, 0xD4DD, 0x6682, 0xD4DE, 0x8D5E, 0xD4DF, 0x8D43,
+	0xD4E0, 0x810F, 0xD4E1, 0x846C, 0xD4E2, 0x906D, 0xD4E3, 0x7CDF,
+	0xD4E4, 0x51FF, 0xD4E5, 0x85FB, 0xD4E6, 0x67A3, 0xD4E7, 0x65E9,
+	0xD4E8, 0x6FA1, 0xD4E9, 0x86A4, 0xD4EA, 0x8E81, 0xD4EB, 0x566A,
+	0xD4EC, 0x9020, 0xD4ED, 0x7682, 0xD4EE, 0x7076, 0xD4EF, 0x71E5,
+	0xD4F0, 0x8D23, 0xD4F1, 0x62E9, 0xD4F2, 0x5219, 0xD4F3, 0x6CFD,
+	0xD4F4, 0x8D3C, 0xD4F5, 0x600E, 0xD4F6, 0x589E, 0xD4F7, 0x618E,
+	0xD4F8, 0x66FE, 0xD4F9, 0x8D60, 0xD4FA, 0x624E, 0xD4FB, 0x55B3,
+	0xD4FC, 0x6E23, 0xD4FD, 0x672D, 0xD4FE, 0x8F67, 0xD540, 0x8A81,
+	0xD541, 0x8A82, 0xD542, 0x8A83, 0xD543, 0x8A84, 0xD544, 0x8A85,
+	0xD545, 0x8A86, 0xD546, 0x8A87, 0xD547, 0x8A88, 0xD548, 0x8A8B,
+	0xD549, 0x8A8C, 0xD54A, 0x8A8D, 0xD54B, 0x8A8E, 0xD54C, 0x8A8F,
+	0xD54D, 0x8A90, 0xD54E, 0x8A91, 0xD54F, 0x8A92, 0xD550, 0x8A94,
+	0xD551, 0x8A95, 0xD552, 0x8A96, 0xD553, 0x8A97, 0xD554, 0x8A98,
+	0xD555, 0x8A99, 0xD556, 0x8A9A, 0xD557, 0x8A9B, 0xD558, 0x8A9C,
+	0xD559, 0x8A9D, 0xD55A, 0x8A9E, 0xD55B, 0x8A9F, 0xD55C, 0x8AA0,
+	0xD55D, 0x8AA1, 0xD55E, 0x8AA2, 0xD55F, 0x8AA3, 0xD560, 0x8AA4,
+	0xD561, 0x8AA5, 0xD562, 0x8AA6, 0xD563, 0x8AA7, 0xD564, 0x8AA8,
+	0xD565, 0x8AA9, 0xD566, 0x8AAA, 0xD567, 0x8AAB, 0xD568, 0x8AAC,
+	0xD569, 0x8AAD, 0xD56A, 0x8AAE, 0xD56B, 0x8AAF, 0xD56C, 0x8AB0,
+	0xD56D, 0x8AB1, 0xD56E, 0x8AB2, 0xD56F, 0x8AB3, 0xD570, 0x8AB4,
+	0xD571, 0x8AB5, 0xD572, 0x8AB6, 0xD573, 0x8AB7, 0xD574, 0x8AB8,
+	0xD575, 0x8AB9, 0xD576, 0x8ABA, 0xD577, 0x8ABB, 0xD578, 0x8ABC,
+	0xD579, 0x8ABD, 0xD57A, 0x8ABE, 0xD57B, 0x8ABF, 0xD57C, 0x8AC0,
+	0xD57D, 0x8AC1, 0xD57E, 0x8AC2, 0xD580, 0x8AC3, 0xD581, 0x8AC4,
+	0xD582, 0x8AC5, 0xD583, 0x8AC6, 0xD584, 0x8AC7, 0xD585, 0x8AC8,
+	0xD586, 0x8AC9, 0xD587, 0x8ACA, 0xD588, 0x8ACB, 0xD589, 0x8ACC,
+	0xD58A, 0x8ACD, 0xD58B, 0x8ACE, 0xD58C, 0x8ACF, 0xD58D, 0x8AD0,
+	0xD58E, 0x8AD1, 0xD58F, 0x8AD2, 0xD590, 0x8AD3, 0xD591, 0x8AD4,
+	0xD592, 0x8AD5, 0xD593, 0x8AD6, 0xD594, 0x8AD7, 0xD595, 0x8AD8,
+	0xD596, 0x8AD9, 0xD597, 0x8ADA, 0xD598, 0x8ADB, 0xD599, 0x8ADC,
+	0xD59A, 0x8ADD, 0xD59B, 0x8ADE, 0xD59C, 0x8ADF, 0xD59D, 0x8AE0,
+	0xD59E, 0x8AE1, 0xD59F, 0x8AE2, 0xD5A0, 0x8AE3, 0xD5A1, 0x94E1,
+	0xD5A2, 0x95F8, 0xD5A3, 0x7728, 0xD5A4, 0x6805, 0xD5A5, 0x69A8,
+	0xD5A6, 0x548B, 0xD5A7, 0x4E4D, 0xD5A8, 0x70B8, 0xD5A9, 0x8BC8,
+	0xD5AA, 0x6458, 0xD5AB, 0x658B, 0xD5AC, 0x5B85, 0xD5AD, 0x7A84,
+	0xD5AE, 0x503A, 0xD5AF, 0x5BE8, 0xD5B0, 0x77BB, 0xD5B1, 0x6BE1,
+	0xD5B2, 0x8A79, 0xD5B3, 0x7C98, 0xD5B4, 0x6CBE, 0xD5B5, 0x76CF,
+	0xD5B6, 0x65A9, 0xD5B7, 0x8F97, 0xD5B8, 0x5D2D, 0xD5B9, 0x5C55,
+	0xD5BA, 0x8638, 0xD5BB, 0x6808, 0xD5BC, 0x5360, 0xD5BD, 0x6218,
+	0xD5BE, 0x7AD9, 0xD5BF, 0x6E5B, 0xD5C0, 0x7EFD, 0xD5C1, 0x6A1F,
+	0xD5C2, 0x7AE0, 0xD5C3, 0x5F70, 0xD5C4, 0x6F33, 0xD5C5, 0x5F20,
+	0xD5C6, 0x638C, 0xD5C7, 0x6DA8, 0xD5C8, 0x6756, 0xD5C9, 0x4E08,
+	0xD5CA, 0x5E10, 0xD5CB, 0x8D26, 0xD5CC, 0x4ED7, 0xD5CD, 0x80C0,
+	0xD5CE, 0x7634, 0xD5CF, 0x969C, 0xD5D0, 0x62DB, 0xD5D1, 0x662D,
+	0xD5D2, 0x627E, 0xD5D3, 0x6CBC, 0xD5D4, 0x8D75, 0xD5D5, 0x7167,
+	0xD5D6, 0x7F69, 0xD5D7, 0x5146, 0xD5D8, 0x8087, 0xD5D9, 0x53EC,
+	0xD5DA, 0x906E, 0xD5DB, 0x6298, 0xD5DC, 0x54F2, 0xD5DD, 0x86F0,
+	0xD5DE, 0x8F99, 0xD5DF, 0x8005, 0xD5E0, 0x9517, 0xD5E1, 0x8517,
+	0xD5E2, 0x8FD9, 0xD5E3, 0x6D59, 0xD5E4, 0x73CD, 0xD5E5, 0x659F,
+	0xD5E6, 0x771F, 0xD5E7, 0x7504, 0xD5E8, 0x7827, 0xD5E9, 0x81FB,
+	0xD5EA, 0x8D1E, 0xD5EB, 0x9488, 0xD5EC, 0x4FA6, 0xD5ED, 0x6795,
+	0xD5EE, 0x75B9, 0xD5EF, 0x8BCA, 0xD5F0, 0x9707, 0xD5F1, 0x632F,
+	0xD5F2, 0x9547, 0xD5F3, 0x9635, 0xD5F4, 0x84B8, 0xD5F5, 0x6323,
+	0xD5F6, 0x7741, 0xD5F7, 0x5F81, 0xD5F8, 0x72F0, 0xD5F9, 0x4E89,
+	0xD5FA, 0x6014, 0xD5FB, 0x6574, 0xD5FC, 0x62EF, 0xD5FD, 0x6B63,
+	0xD5FE, 0x653F, 0xD640, 0x8AE4, 0xD641, 0x8AE5, 0xD642, 0x8AE6,
+	0xD643, 0x8AE7, 0xD644, 0x8AE8, 0xD645, 0x8AE9, 0xD646, 0x8AEA,
+	0xD647, 0x8AEB, 0xD648, 0x8AEC, 0xD649, 0x8AED, 0xD64A, 0x8AEE,
+	0xD64B, 0x8AEF, 0xD64C, 0x8AF0, 0xD64D, 0x8AF1, 0xD64E, 0x8AF2,
+	0xD64F, 0x8AF3, 0xD650, 0x8AF4, 0xD651, 0x8AF5, 0xD652, 0x8AF6,
+	0xD653, 0x8AF7, 0xD654, 0x8AF8, 0xD655, 0x8AF9, 0xD656, 0x8AFA,
+	0xD657, 0x8AFB, 0xD658, 0x8AFC, 0xD659, 0x8AFD, 0xD65A, 0x8AFE,
+	0xD65B, 0x8AFF, 0xD65C, 0x8B00, 0xD65D, 0x8B01, 0xD65E, 0x8B02,
+	0xD65F, 0x8B03, 0xD660, 0x8B04, 0xD661, 0x8B05, 0xD662, 0x8B06,
+	0xD663, 0x8B08, 0xD664, 0x8B09, 0xD665, 0x8B0A, 0xD666, 0x8B0B,
+	0xD667, 0x8B0C, 0xD668, 0x8B0D, 0xD669, 0x8B0E, 0xD66A, 0x8B0F,
+	0xD66B, 0x8B10, 0xD66C, 0x8B11, 0xD66D, 0x8B12, 0xD66E, 0x8B13,
+	0xD66F, 0x8B14, 0xD670, 0x8B15, 0xD671, 0x8B16, 0xD672, 0x8B17,
+	0xD673, 0x8B18, 0xD674, 0x8B19, 0xD675, 0x8B1A, 0xD676, 0x8B1B,
+	0xD677, 0x8B1C, 0xD678, 0x8B1D, 0xD679, 0x8B1E, 0xD67A, 0x8B1F,
+	0xD67B, 0x8B20, 0xD67C, 0x8B21, 0xD67D, 0x8B22, 0xD67E, 0x8B23,
+	0xD680, 0x8B24, 0xD681, 0x8B25, 0xD682, 0x8B27, 0xD683, 0x8B28,
+	0xD684, 0x8B29, 0xD685, 0x8B2A, 0xD686, 0x8B2B, 0xD687, 0x8B2C,
+	0xD688, 0x8B2D, 0xD689, 0x8B2E, 0xD68A, 0x8B2F, 0xD68B, 0x8B30,
+	0xD68C, 0x8B31, 0xD68D, 0x8B32, 0xD68E, 0x8B33, 0xD68F, 0x8B34,
+	0xD690, 0x8B35, 0xD691, 0x8B36, 0xD692, 0x8B37, 0xD693, 0x8B38,
+	0xD694, 0x8B39, 0xD695, 0x8B3A, 0xD696, 0x8B3B, 0xD697, 0x8B3C,
+	0xD698, 0x8B3D, 0xD699, 0x8B3E, 0xD69A, 0x8B3F, 0xD69B, 0x8B40,
+	0xD69C, 0x8B41, 0xD69D, 0x8B42, 0xD69E, 0x8B43, 0xD69F, 0x8B44,
+	0xD6A0, 0x8B45, 0xD6A1, 0x5E27, 0xD6A2, 0x75C7, 0xD6A3, 0x90D1,
+	0xD6A4, 0x8BC1, 0xD6A5, 0x829D, 0xD6A6, 0x679D, 0xD6A7, 0x652F,
+	0xD6A8, 0x5431, 0xD6A9, 0x8718, 0xD6AA, 0x77E5, 0xD6AB, 0x80A2,
+	0xD6AC, 0x8102, 0xD6AD, 0x6C41, 0xD6AE, 0x4E4B, 0xD6AF, 0x7EC7,
+	0xD6B0, 0x804C, 0xD6B1, 0x76F4, 0xD6B2, 0x690D, 0xD6B3, 0x6B96,
+	0xD6B4, 0x6267, 0xD6B5, 0x503C, 0xD6B6, 0x4F84, 0xD6B7, 0x5740,
+	0xD6B8, 0x6307, 0xD6B9, 0x6B62, 0xD6BA, 0x8DBE, 0xD6BB, 0x53EA,
+	0xD6BC, 0x65E8, 0xD6BD, 0x7EB8, 0xD6BE, 0x5FD7, 0xD6BF, 0x631A,
+	0xD6C0, 0x63B7, 0xD6C1, 0x81F3, 0xD6C2, 0x81F4, 0xD6C3, 0x7F6E,
+	0xD6C4, 0x5E1C, 0xD6C5, 0x5CD9, 0xD6C6, 0x5236, 0xD6C7, 0x667A,
+	0xD6C8, 0x79E9, 0xD6C9, 0x7A1A, 0xD6CA, 0x8D28, 0xD6CB, 0x7099,
+	0xD6CC, 0x75D4, 0xD6CD, 0x6EDE, 0xD6CE, 0x6CBB, 0xD6CF, 0x7A92,
+	0xD6D0, 0x4E2D, 0xD6D1, 0x76C5, 0xD6D2, 0x5FE0, 0xD6D3, 0x949F,
+	0xD6D4, 0x8877, 0xD6D5, 0x7EC8, 0xD6D6, 0x79CD, 0xD6D7, 0x80BF,
+	0xD6D8, 0x91CD, 0xD6D9, 0x4EF2, 0xD6DA, 0x4F17, 0xD6DB, 0x821F,
+	0xD6DC, 0x5468, 0xD6DD, 0x5DDE, 0xD6DE, 0x6D32, 0xD6DF, 0x8BCC,
+	0xD6E0, 0x7CA5, 0xD6E1, 0x8F74, 0xD6E2, 0x8098, 0xD6E3, 0x5E1A,
+	0xD6E4, 0x5492, 0xD6E5, 0x76B1, 0xD6E6, 0x5B99, 0xD6E7, 0x663C,
+	0xD6E8, 0x9AA4, 0xD6E9, 0x73E0, 0xD6EA, 0x682A, 0xD6EB, 0x86DB,
+	0xD6EC, 0x6731, 0xD6ED, 0x732A, 0xD6EE, 0x8BF8, 0xD6EF, 0x8BDB,
+	0xD6F0, 0x9010, 0xD6F1, 0x7AF9, 0xD6F2, 0x70DB, 0xD6F3, 0x716E,
+	0xD6F4, 0x62C4, 0xD6F5, 0x77A9, 0xD6F6, 0x5631, 0xD6F7, 0x4E3B,
+	0xD6F8, 0x8457, 0xD6F9, 0x67F1, 0xD6FA, 0x52A9, 0xD6FB, 0x86C0,
+	0xD6FC, 0x8D2E, 0xD6FD, 0x94F8, 0xD6FE, 0x7B51, 0xD740, 0x8B46,
+	0xD741, 0x8B47, 0xD742, 0x8B48, 0xD743, 0x8B49, 0xD744, 0x8B4A,
+	0xD745, 0x8B4B, 0xD746, 0x8B4C, 0xD747, 0x8B4D, 0xD748, 0x8B4E,
+	0xD749, 0x8B4F, 0xD74A, 0x8B50, 0xD74B, 0x8B51, 0xD74C, 0x8B52,
+	0xD74D, 0x8B53, 0xD74E, 0x8B54, 0xD74F, 0x8B55, 0xD750, 0x8B56,
+	0xD751, 0x8B57, 0xD752, 0x8B58, 0xD753, 0x8B59, 0xD754, 0x8B5A,
+	0xD755, 0x8B5B, 0xD756, 0x8B5C, 0xD757, 0x8B5D, 0xD758, 0x8B5E,
+	0xD759, 0x8B5F, 0xD75A, 0x8B60, 0xD75B, 0x8B61, 0xD75C, 0x8B62,
+	0xD75D, 0x8B63, 0xD75E, 0x8B64, 0xD75F, 0x8B65, 0xD760, 0x8B67,
+	0xD761, 0x8B68, 0xD762, 0x8B69, 0xD763, 0x8B6A, 0xD764, 0x8B6B,
+	0xD765, 0x8B6D, 0xD766, 0x8B6E, 0xD767, 0x8B6F, 0xD768, 0x8B70,
+	0xD769, 0x8B71, 0xD76A, 0x8B72, 0xD76B, 0x8B73, 0xD76C, 0x8B74,
+	0xD76D, 0x8B75, 0xD76E, 0x8B76, 0xD76F, 0x8B77, 0xD770, 0x8B78,
+	0xD771, 0x8B79, 0xD772, 0x8B7A, 0xD773, 0x8B7B, 0xD774, 0x8B7C,
+	0xD775, 0x8B7D, 0xD776, 0x8B7E, 0xD777, 0x8B7F, 0xD778, 0x8B80,
+	0xD779, 0x8B81, 0xD77A, 0x8B82, 0xD77B, 0x8B83, 0xD77C, 0x8B84,
+	0xD77D, 0x8B85, 0xD77E, 0x8B86, 0xD780, 0x8B87, 0xD781, 0x8B88,
+	0xD782, 0x8B89, 0xD783, 0x8B8A, 0xD784, 0x8B8B, 0xD785, 0x8B8C,
+	0xD786, 0x8B8D, 0xD787, 0x8B8E, 0xD788, 0x8B8F, 0xD789, 0x8B90,
+	0xD78A, 0x8B91, 0xD78B, 0x8B92, 0xD78C, 0x8B93, 0xD78D, 0x8B94,
+	0xD78E, 0x8B95, 0xD78F, 0x8B96, 0xD790, 0x8B97, 0xD791, 0x8B98,
+	0xD792, 0x8B99, 0xD793, 0x8B9A, 0xD794, 0x8B9B, 0xD795, 0x8B9C,
+	0xD796, 0x8B9D, 0xD797, 0x8B9E, 0xD798, 0x8B9F, 0xD799, 0x8BAC,
+	0xD79A, 0x8BB1, 0xD79B, 0x8BBB, 0xD79C, 0x8BC7, 0xD79D, 0x8BD0,
+	0xD79E, 0x8BEA, 0xD79F, 0x8C09, 0xD7A0, 0x8C1E, 0xD7A1, 0x4F4F,
+	0xD7A2, 0x6CE8, 0xD7A3, 0x795D, 0xD7A4, 0x9A7B, 0xD7A5, 0x6293,
+	0xD7A6, 0x722A, 0xD7A7, 0x62FD, 0xD7A8, 0x4E13, 0xD7A9, 0x7816,
+	0xD7AA, 0x8F6C, 0xD7AB, 0x64B0, 0xD7AC, 0x8D5A, 0xD7AD, 0x7BC6,
+	0xD7AE, 0x6869, 0xD7AF, 0x5E84, 0xD7B0, 0x88C5, 0xD7B1, 0x5986,
+	0xD7B2, 0x649E, 0xD7B3, 0x58EE, 0xD7B4, 0x72B6, 0xD7B5, 0x690E,
+	0xD7B6, 0x9525, 0xD7B7, 0x8FFD, 0xD7B8, 0x8D58, 0xD7B9, 0x5760,
+	0xD7BA, 0x7F00, 0xD7BB, 0x8C06, 0xD7BC, 0x51C6, 0xD7BD, 0x6349,
+	0xD7BE, 0x62D9, 0xD7BF, 0x5353, 0xD7C0, 0x684C, 0xD7C1, 0x7422,
+	0xD7C2, 0x8301, 0xD7C3, 0x914C, 0xD7C4, 0x5544, 0xD7C5, 0x7740,
+	0xD7C6, 0x707C, 0xD7C7, 0x6D4A, 0xD7C8, 0x5179, 0xD7C9, 0x54A8,
+	0xD7CA, 0x8D44, 0xD7CB, 0x59FF, 0xD7CC, 0x6ECB, 0xD7CD, 0x6DC4,
+	0xD7CE, 0x5B5C, 0xD7CF, 0x7D2B, 0xD7D0, 0x4ED4, 0xD7D1, 0x7C7D,
+	0xD7D2, 0x6ED3, 0xD7D3, 0x5B50, 0xD7D4, 0x81EA, 0xD7D5, 0x6E0D,
+	0xD7D6, 0x5B57, 0xD7D7, 0x9B03, 0xD7D8, 0x68D5, 0xD7D9, 0x8E2A,
+	0xD7DA, 0x5B97, 0xD7DB, 0x7EFC, 0xD7DC, 0x603B, 0xD7DD, 0x7EB5,
+	0xD7DE, 0x90B9, 0xD7DF, 0x8D70, 0xD7E0, 0x594F, 0xD7E1, 0x63CD,
+	0xD7E2, 0x79DF, 0xD7E3, 0x8DB3, 0xD7E4, 0x5352, 0xD7E5, 0x65CF,
+	0xD7E6, 0x7956, 0xD7E7, 0x8BC5, 0xD7E8, 0x963B, 0xD7E9, 0x7EC4,
+	0xD7EA, 0x94BB, 0xD7EB, 0x7E82, 0xD7EC, 0x5634, 0xD7ED, 0x9189,
+	0xD7EE, 0x6700, 0xD7EF, 0x7F6A, 0xD7F0, 0x5C0A, 0xD7F1, 0x9075,
+	0xD7F2, 0x6628, 0xD7F3, 0x5DE6, 0xD7F4, 0x4F50, 0xD7F5, 0x67DE,
+	0xD7F6, 0x505A, 0xD7F7, 0x4F5C, 0xD7F8, 0x5750, 0xD7F9, 0x5EA7,
+	0xD840, 0x8C38, 0xD841, 0x8C39, 0xD842, 0x8C3A, 0xD843, 0x8C3B,
+	0xD844, 0x8C3C, 0xD845, 0x8C3D, 0xD846, 0x8C3E, 0xD847, 0x8C3F,
+	0xD848, 0x8C40, 0xD849, 0x8C42, 0xD84A, 0x8C43, 0xD84B, 0x8C44,
+	0xD84C, 0x8C45, 0xD84D, 0x8C48, 0xD84E, 0x8C4A, 0xD84F, 0x8C4B,
+	0xD850, 0x8C4D, 0xD851, 0x8C4E, 0xD852, 0x8C4F, 0xD853, 0x8C50,
+	0xD854, 0x8C51, 0xD855, 0x8C52, 0xD856, 0x8C53, 0xD857, 0x8C54,
+	0xD858, 0x8C56, 0xD859, 0x8C57, 0xD85A, 0x8C58, 0xD85B, 0x8C59,
+	0xD85C, 0x8C5B, 0xD85D, 0x8C5C, 0xD85E, 0x8C5D, 0xD85F, 0x8C5E,
+	0xD860, 0x8C5F, 0xD861, 0x8C60, 0xD862, 0x8C63, 0xD863, 0x8C64,
+	0xD864, 0x8C65, 0xD865, 0x8C66, 0xD866, 0x8C67, 0xD867, 0x8C68,
+	0xD868, 0x8C69, 0xD869, 0x8C6C, 0xD86A, 0x8C6D, 0xD86B, 0x8C6E,
+	0xD86C, 0x8C6F, 0xD86D, 0x8C70, 0xD86E, 0x8C71, 0xD86F, 0x8C72,
+	0xD870, 0x8C74, 0xD871, 0x8C75, 0xD872, 0x8C76, 0xD873, 0x8C77,
+	0xD874, 0x8C7B, 0xD875, 0x8C7C, 0xD876, 0x8C7D, 0xD877, 0x8C7E,
+	0xD878, 0x8C7F, 0xD879, 0x8C80, 0xD87A, 0x8C81, 0xD87B, 0x8C83,
+	0xD87C, 0x8C84, 0xD87D, 0x8C86, 0xD87E, 0x8C87, 0xD880, 0x8C88,
+	0xD881, 0x8C8B, 0xD882, 0x8C8D, 0xD883, 0x8C8E, 0xD884, 0x8C8F,
+	0xD885, 0x8C90, 0xD886, 0x8C91, 0xD887, 0x8C92, 0xD888, 0x8C93,
+	0xD889, 0x8C95, 0xD88A, 0x8C96, 0xD88B, 0x8C97, 0xD88C, 0x8C99,
+	0xD88D, 0x8C9A, 0xD88E, 0x8C9B, 0xD88F, 0x8C9C, 0xD890, 0x8C9D,
+	0xD891, 0x8C9E, 0xD892, 0x8C9F, 0xD893, 0x8CA0, 0xD894, 0x8CA1,
+	0xD895, 0x8CA2, 0xD896, 0x8CA3, 0xD897, 0x8CA4, 0xD898, 0x8CA5,
+	0xD899, 0x8CA6, 0xD89A, 0x8CA7, 0xD89B, 0x8CA8, 0xD89C, 0x8CA9,
+	0xD89D, 0x8CAA, 0xD89E, 0x8CAB, 0xD89F, 0x8CAC, 0xD8A0, 0x8CAD,
+	0xD8A1, 0x4E8D, 0xD8A2, 0x4E0C, 0xD8A3, 0x5140, 0xD8A4, 0x4E10,
+	0xD8A5, 0x5EFF, 0xD8A6, 0x5345, 0xD8A7, 0x4E15, 0xD8A8, 0x4E98,
+	0xD8A9, 0x4E1E, 0xD8AA, 0x9B32, 0xD8AB, 0x5B6C, 0xD8AC, 0x5669,
+	0xD8AD, 0x4E28, 0xD8AE, 0x79BA, 0xD8AF, 0x4E3F, 0xD8B0, 0x5315,
+	0xD8B1, 0x4E47, 0xD8B2, 0x592D, 0xD8B3, 0x723B, 0xD8B4, 0x536E,
+	0xD8B5, 0x6C10, 0xD8B6, 0x56DF, 0xD8B7, 0x80E4, 0xD8B8, 0x9997,
+	0xD8B9, 0x6BD3, 0xD8BA, 0x777E, 0xD8BB, 0x9F17, 0xD8BC, 0x4E36,
+	0xD8BD, 0x4E9F, 0xD8BE, 0x9F10, 0xD8BF, 0x4E5C, 0xD8C0, 0x4E69,
+	0xD8C1, 0x4E93, 0xD8C2, 0x8288, 0xD8C3, 0x5B5B, 0xD8C4, 0x556C,
+	0xD8C5, 0x560F, 0xD8C6, 0x4EC4, 0xD8C7, 0x538D, 0xD8C8, 0x539D,
+	0xD8C9, 0x53A3, 0xD8CA, 0x53A5, 0xD8CB, 0x53AE, 0xD8CC, 0x9765,
+	0xD8CD, 0x8D5D, 0xD8CE, 0x531A, 0xD8CF, 0x53F5, 0xD8D0, 0x5326,
+	0xD8D1, 0x532E, 0xD8D2, 0x533E, 0xD8D3, 0x8D5C, 0xD8D4, 0x5366,
+	0xD8D5, 0x5363, 0xD8D6, 0x5202, 0xD8D7, 0x5208, 0xD8D8, 0x520E,
+	0xD8D9, 0x522D, 0xD8DA, 0x5233, 0xD8DB, 0x523F, 0xD8DC, 0x5240,
+	0xD8DD, 0x524C, 0xD8DE, 0x525E, 0xD8DF, 0x5261, 0xD8E0, 0x525C,
+	0xD8E1, 0x84AF, 0xD8E2, 0x527D, 0xD8E3, 0x5282, 0xD8E4, 0x5281,
+	0xD8E5, 0x5290, 0xD8E6, 0x5293, 0xD8E7, 0x5182, 0xD8E8, 0x7F54,
+	0xD8E9, 0x4EBB, 0xD8EA, 0x4EC3, 0xD8EB, 0x4EC9, 0xD8EC, 0x4EC2,
+	0xD8ED, 0x4EE8, 0xD8EE, 0x4EE1, 0xD8EF, 0x4EEB, 0xD8F0, 0x4EDE,
+	0xD8F1, 0x4F1B, 0xD8F2, 0x4EF3, 0xD8F3, 0x4F22, 0xD8F4, 0x4F64,
+	0xD8F5, 0x4EF5, 0xD8F6, 0x4F25, 0xD8F7, 0x4F27, 0xD8F8, 0x4F09,
+	0xD8F9, 0x4F2B, 0xD8FA, 0x4F5E, 0xD8FB, 0x4F67, 0xD8FC, 0x6538,
+	0xD8FD, 0x4F5A, 0xD8FE, 0x4F5D, 0xD940, 0x8CAE, 0xD941, 0x8CAF,
+	0xD942, 0x8CB0, 0xD943, 0x8CB1, 0xD944, 0x8CB2, 0xD945, 0x8CB3,
+	0xD946, 0x8CB4, 0xD947, 0x8CB5, 0xD948, 0x8CB6, 0xD949, 0x8CB7,
+	0xD94A, 0x8CB8, 0xD94B, 0x8CB9, 0xD94C, 0x8CBA, 0xD94D, 0x8CBB,
+	0xD94E, 0x8CBC, 0xD94F, 0x8CBD, 0xD950, 0x8CBE, 0xD951, 0x8CBF,
+	0xD952, 0x8CC0, 0xD953, 0x8CC1, 0xD954, 0x8CC2, 0xD955, 0x8CC3,
+	0xD956, 0x8CC4, 0xD957, 0x8CC5, 0xD958, 0x8CC6, 0xD959, 0x8CC7,
+	0xD95A, 0x8CC8, 0xD95B, 0x8CC9, 0xD95C, 0x8CCA, 0xD95D, 0x8CCB,
+	0xD95E, 0x8CCC, 0xD95F, 0x8CCD, 0xD960, 0x8CCE, 0xD961, 0x8CCF,
+	0xD962, 0x8CD0, 0xD963, 0x8CD1, 0xD964, 0x8CD2, 0xD965, 0x8CD3,
+	0xD966, 0x8CD4, 0xD967, 0x8CD5, 0xD968, 0x8CD6, 0xD969, 0x8CD7,
+	0xD96A, 0x8CD8, 0xD96B, 0x8CD9, 0xD96C, 0x8CDA, 0xD96D, 0x8CDB,
+	0xD96E, 0x8CDC, 0xD96F, 0x8CDD, 0xD970, 0x8CDE, 0xD971, 0x8CDF,
+	0xD972, 0x8CE0, 0xD973, 0x8CE1, 0xD974, 0x8CE2, 0xD975, 0x8CE3,
+	0xD976, 0x8CE4, 0xD977, 0x8CE5, 0xD978, 0x8CE6, 0xD979, 0x8CE7,
+	0xD97A, 0x8CE8, 0xD97B, 0x8CE9, 0xD97C, 0x8CEA, 0xD97D, 0x8CEB,
+	0xD97E, 0x8CEC, 0xD980, 0x8CED, 0xD981, 0x8CEE, 0xD982, 0x8CEF,
+	0xD983, 0x8CF0, 0xD984, 0x8CF1, 0xD985, 0x8CF2, 0xD986, 0x8CF3,
+	0xD987, 0x8CF4, 0xD988, 0x8CF5, 0xD989, 0x8CF6, 0xD98A, 0x8CF7,
+	0xD98B, 0x8CF8, 0xD98C, 0x8CF9, 0xD98D, 0x8CFA, 0xD98E, 0x8CFB,
+	0xD98F, 0x8CFC, 0xD990, 0x8CFD, 0xD991, 0x8CFE, 0xD992, 0x8CFF,
+	0xD993, 0x8D00, 0xD994, 0x8D01, 0xD995, 0x8D02, 0xD996, 0x8D03,
+	0xD997, 0x8D04, 0xD998, 0x8D05, 0xD999, 0x8D06, 0xD99A, 0x8D07,
+	0xD99B, 0x8D08, 0xD99C, 0x8D09, 0xD99D, 0x8D0A, 0xD99E, 0x8D0B,
+	0xD99F, 0x8D0C, 0xD9A0, 0x8D0D, 0xD9A1, 0x4F5F, 0xD9A2, 0x4F57,
+	0xD9A3, 0x4F32, 0xD9A4, 0x4F3D, 0xD9A5, 0x4F76, 0xD9A6, 0x4F74,
+	0xD9A7, 0x4F91, 0xD9A8, 0x4F89, 0xD9A9, 0x4F83, 0xD9AA, 0x4F8F,
+	0xD9AB, 0x4F7E, 0xD9AC, 0x4F7B, 0xD9AD, 0x4FAA, 0xD9AE, 0x4F7C,
+	0xD9AF, 0x4FAC, 0xD9B0, 0x4F94, 0xD9B1, 0x4FE6, 0xD9B2, 0x4FE8,
+	0xD9B3, 0x4FEA, 0xD9B4, 0x4FC5, 0xD9B5, 0x4FDA, 0xD9B6, 0x4FE3,
+	0xD9B7, 0x4FDC, 0xD9B8, 0x4FD1, 0xD9B9, 0x4FDF, 0xD9BA, 0x4FF8,
+	0xD9BB, 0x5029, 0xD9BC, 0x504C, 0xD9BD, 0x4FF3, 0xD9BE, 0x502C,
+	0xD9BF, 0x500F, 0xD9C0, 0x502E, 0xD9C1, 0x502D, 0xD9C2, 0x4FFE,
+	0xD9C3, 0x501C, 0xD9C4, 0x500C, 0xD9C5, 0x5025, 0xD9C6, 0x5028,
+	0xD9C7, 0x507E, 0xD9C8, 0x5043, 0xD9C9, 0x5055, 0xD9CA, 0x5048,
+	0xD9CB, 0x504E, 0xD9CC, 0x506C, 0xD9CD, 0x507B, 0xD9CE, 0x50A5,
+	0xD9CF, 0x50A7, 0xD9D0, 0x50A9, 0xD9D1, 0x50BA, 0xD9D2, 0x50D6,
+	0xD9D3, 0x5106, 0xD9D4, 0x50ED, 0xD9D5, 0x50EC, 0xD9D6, 0x50E6,
+	0xD9D7, 0x50EE, 0xD9D8, 0x5107, 0xD9D9, 0x510B, 0xD9DA, 0x4EDD,
+	0xD9DB, 0x6C3D, 0xD9DC, 0x4F58, 0xD9DD, 0x4F65, 0xD9DE, 0x4FCE,
+	0xD9DF, 0x9FA0, 0xD9E0, 0x6C46, 0xD9E1, 0x7C74, 0xD9E2, 0x516E,
+	0xD9E3, 0x5DFD, 0xD9E4, 0x9EC9, 0xD9E5, 0x9998, 0xD9E6, 0x5181,
+	0xD9E7, 0x5914, 0xD9E8, 0x52F9, 0xD9E9, 0x530D, 0xD9EA, 0x8A07,
+	0xD9EB, 0x5310, 0xD9EC, 0x51EB, 0xD9ED, 0x5919, 0xD9EE, 0x5155,
+	0xD9EF, 0x4EA0, 0xD9F0, 0x5156, 0xD9F1, 0x4EB3, 0xD9F2, 0x886E,
+	0xD9F3, 0x88A4, 0xD9F4, 0x4EB5, 0xD9F5, 0x8114, 0xD9F6, 0x88D2,
+	0xD9F7, 0x7980, 0xD9F8, 0x5B34, 0xD9F9, 0x8803, 0xD9FA, 0x7FB8,
+	0xD9FB, 0x51AB, 0xD9FC, 0x51B1, 0xD9FD, 0x51BD, 0xD9FE, 0x51BC,
+	0xDA40, 0x8D0E, 0xDA41, 0x8D0F, 0xDA42, 0x8D10, 0xDA43, 0x8D11,
+	0xDA44, 0x8D12, 0xDA45, 0x8D13, 0xDA46, 0x8D14, 0xDA47, 0x8D15,
+	0xDA48, 0x8D16, 0xDA49, 0x8D17, 0xDA4A, 0x8D18, 0xDA4B, 0x8D19,
+	0xDA4C, 0x8D1A, 0xDA4D, 0x8D1B, 0xDA4E, 0x8D1C, 0xDA4F, 0x8D20,
+	0xDA50, 0x8D51, 0xDA51, 0x8D52, 0xDA52, 0x8D57, 0xDA53, 0x8D5F,
+	0xDA54, 0x8D65, 0xDA55, 0x8D68, 0xDA56, 0x8D69, 0xDA57, 0x8D6A,
+	0xDA58, 0x8D6C, 0xDA59, 0x8D6E, 0xDA5A, 0x8D6F, 0xDA5B, 0x8D71,
+	0xDA5C, 0x8D72, 0xDA5D, 0x8D78, 0xDA5E, 0x8D79, 0xDA5F, 0x8D7A,
+	0xDA60, 0x8D7B, 0xDA61, 0x8D7C, 0xDA62, 0x8D7D, 0xDA63, 0x8D7E,
+	0xDA64, 0x8D7F, 0xDA65, 0x8D80, 0xDA66, 0x8D82, 0xDA67, 0x8D83,
+	0xDA68, 0x8D86, 0xDA69, 0x8D87, 0xDA6A, 0x8D88, 0xDA6B, 0x8D89,
+	0xDA6C, 0x8D8C, 0xDA6D, 0x8D8D, 0xDA6E, 0x8D8E, 0xDA6F, 0x8D8F,
+	0xDA70, 0x8D90, 0xDA71, 0x8D92, 0xDA72, 0x8D93, 0xDA73, 0x8D95,
+	0xDA74, 0x8D96, 0xDA75, 0x8D97, 0xDA76, 0x8D98, 0xDA77, 0x8D99,
+	0xDA78, 0x8D9A, 0xDA79, 0x8D9B, 0xDA7A, 0x8D9C, 0xDA7B, 0x8D9D,
+	0xDA7C, 0x8D9E, 0xDA7D, 0x8DA0, 0xDA7E, 0x8DA1, 0xDA80, 0x8DA2,
+	0xDA81, 0x8DA4, 0xDA82, 0x8DA5, 0xDA83, 0x8DA6, 0xDA84, 0x8DA7,
+	0xDA85, 0x8DA8, 0xDA86, 0x8DA9, 0xDA87, 0x8DAA, 0xDA88, 0x8DAB,
+	0xDA89, 0x8DAC, 0xDA8A, 0x8DAD, 0xDA8B, 0x8DAE, 0xDA8C, 0x8DAF,
+	0xDA8D, 0x8DB0, 0xDA8E, 0x8DB2, 0xDA8F, 0x8DB6, 0xDA90, 0x8DB7,
+	0xDA91, 0x8DB9, 0xDA92, 0x8DBB, 0xDA93, 0x8DBD, 0xDA94, 0x8DC0,
+	0xDA95, 0x8DC1, 0xDA96, 0x8DC2, 0xDA97, 0x8DC5, 0xDA98, 0x8DC7,
+	0xDA99, 0x8DC8, 0xDA9A, 0x8DC9, 0xDA9B, 0x8DCA, 0xDA9C, 0x8DCD,
+	0xDA9D, 0x8DD0, 0xDA9E, 0x8DD2, 0xDA9F, 0x8DD3, 0xDAA0, 0x8DD4,
+	0xDAA1, 0x51C7, 0xDAA2, 0x5196, 0xDAA3, 0x51A2, 0xDAA4, 0x51A5,
+	0xDAA5, 0x8BA0, 0xDAA6, 0x8BA6, 0xDAA7, 0x8BA7, 0xDAA8, 0x8BAA,
+	0xDAA9, 0x8BB4, 0xDAAA, 0x8BB5, 0xDAAB, 0x8BB7, 0xDAAC, 0x8BC2,
+	0xDAAD, 0x8BC3, 0xDAAE, 0x8BCB, 0xDAAF, 0x8BCF, 0xDAB0, 0x8BCE,
+	0xDAB1, 0x8BD2, 0xDAB2, 0x8BD3, 0xDAB3, 0x8BD4, 0xDAB4, 0x8BD6,
+	0xDAB5, 0x8BD8, 0xDAB6, 0x8BD9, 0xDAB7, 0x8BDC, 0xDAB8, 0x8BDF,
+	0xDAB9, 0x8BE0, 0xDABA, 0x8BE4, 0xDABB, 0x8BE8, 0xDABC, 0x8BE9,
+	0xDABD, 0x8BEE, 0xDABE, 0x8BF0, 0xDABF, 0x8BF3, 0xDAC0, 0x8BF6,
+	0xDAC1, 0x8BF9, 0xDAC2, 0x8BFC, 0xDAC3, 0x8BFF, 0xDAC4, 0x8C00,
+	0xDAC5, 0x8C02, 0xDAC6, 0x8C04, 0xDAC7, 0x8C07, 0xDAC8, 0x8C0C,
+	0xDAC9, 0x8C0F, 0xDACA, 0x8C11, 0xDACB, 0x8C12, 0xDACC, 0x8C14,
+	0xDACD, 0x8C15, 0xDACE, 0x8C16, 0xDACF, 0x8C19, 0xDAD0, 0x8C1B,
+	0xDAD1, 0x8C18, 0xDAD2, 0x8C1D, 0xDAD3, 0x8C1F, 0xDAD4, 0x8C20,
+	0xDAD5, 0x8C21, 0xDAD6, 0x8C25, 0xDAD7, 0x8C27, 0xDAD8, 0x8C2A,
+	0xDAD9, 0x8C2B, 0xDADA, 0x8C2E, 0xDADB, 0x8C2F, 0xDADC, 0x8C32,
+	0xDADD, 0x8C33, 0xDADE, 0x8C35, 0xDADF, 0x8C36, 0xDAE0, 0x5369,
+	0xDAE1, 0x537A, 0xDAE2, 0x961D, 0xDAE3, 0x9622, 0xDAE4, 0x9621,
+	0xDAE5, 0x9631, 0xDAE6, 0x962A, 0xDAE7, 0x963D, 0xDAE8, 0x963C,
+	0xDAE9, 0x9642, 0xDAEA, 0x9649, 0xDAEB, 0x9654, 0xDAEC, 0x965F,
+	0xDAED, 0x9667, 0xDAEE, 0x966C, 0xDAEF, 0x9672, 0xDAF0, 0x9674,
+	0xDAF1, 0x9688, 0xDAF2, 0x968D, 0xDAF3, 0x9697, 0xDAF4, 0x96B0,
+	0xDAF5, 0x9097, 0xDAF6, 0x909B, 0xDAF7, 0x909D, 0xDAF8, 0x9099,
+	0xDAF9, 0x90AC, 0xDAFA, 0x90A1, 0xDAFB, 0x90B4, 0xDAFC, 0x90B3,
+	0xDAFD, 0x90B6, 0xDAFE, 0x90BA, 0xDB40, 0x8DD5, 0xDB41, 0x8DD8,
+	0xDB42, 0x8DD9, 0xDB43, 0x8DDC, 0xDB44, 0x8DE0, 0xDB45, 0x8DE1,
+	0xDB46, 0x8DE2, 0xDB47, 0x8DE5, 0xDB48, 0x8DE6, 0xDB49, 0x8DE7,
+	0xDB4A, 0x8DE9, 0xDB4B, 0x8DED, 0xDB4C, 0x8DEE, 0xDB4D, 0x8DF0,
+	0xDB4E, 0x8DF1, 0xDB4F, 0x8DF2, 0xDB50, 0x8DF4, 0xDB51, 0x8DF6,
+	0xDB52, 0x8DFC, 0xDB53, 0x8DFE, 0xDB54, 0x8DFF, 0xDB55, 0x8E00,
+	0xDB56, 0x8E01, 0xDB57, 0x8E02, 0xDB58, 0x8E03, 0xDB59, 0x8E04,
+	0xDB5A, 0x8E06, 0xDB5B, 0x8E07, 0xDB5C, 0x8E08, 0xDB5D, 0x8E0B,
+	0xDB5E, 0x8E0D, 0xDB5F, 0x8E0E, 0xDB60, 0x8E10, 0xDB61, 0x8E11,
+	0xDB62, 0x8E12, 0xDB63, 0x8E13, 0xDB64, 0x8E15, 0xDB65, 0x8E16,
+	0xDB66, 0x8E17, 0xDB67, 0x8E18, 0xDB68, 0x8E19, 0xDB69, 0x8E1A,
+	0xDB6A, 0x8E1B, 0xDB6B, 0x8E1C, 0xDB6C, 0x8E20, 0xDB6D, 0x8E21,
+	0xDB6E, 0x8E24, 0xDB6F, 0x8E25, 0xDB70, 0x8E26, 0xDB71, 0x8E27,
+	0xDB72, 0x8E28, 0xDB73, 0x8E2B, 0xDB74, 0x8E2D, 0xDB75, 0x8E30,
+	0xDB76, 0x8E32, 0xDB77, 0x8E33, 0xDB78, 0x8E34, 0xDB79, 0x8E36,
+	0xDB7A, 0x8E37, 0xDB7B, 0x8E38, 0xDB7C, 0x8E3B, 0xDB7D, 0x8E3C,
+	0xDB7E, 0x8E3E, 0xDB80, 0x8E3F, 0xDB81, 0x8E43, 0xDB82, 0x8E45,
+	0xDB83, 0x8E46, 0xDB84, 0x8E4C, 0xDB85, 0x8E4D, 0xDB86, 0x8E4E,
+	0xDB87, 0x8E4F, 0xDB88, 0x8E50, 0xDB89, 0x8E53, 0xDB8A, 0x8E54,
+	0xDB8B, 0x8E55, 0xDB8C, 0x8E56, 0xDB8D, 0x8E57, 0xDB8E, 0x8E58,
+	0xDB8F, 0x8E5A, 0xDB90, 0x8E5B, 0xDB91, 0x8E5C, 0xDB92, 0x8E5D,
+	0xDB93, 0x8E5E, 0xDB94, 0x8E5F, 0xDB95, 0x8E60, 0xDB96, 0x8E61,
+	0xDB97, 0x8E62, 0xDB98, 0x8E63, 0xDB99, 0x8E64, 0xDB9A, 0x8E65,
+	0xDB9B, 0x8E67, 0xDB9C, 0x8E68, 0xDB9D, 0x8E6A, 0xDB9E, 0x8E6B,
+	0xDB9F, 0x8E6E, 0xDBA0, 0x8E71, 0xDBA1, 0x90B8, 0xDBA2, 0x90B0,
+	0xDBA3, 0x90CF, 0xDBA4, 0x90C5, 0xDBA5, 0x90BE, 0xDBA6, 0x90D0,
+	0xDBA7, 0x90C4, 0xDBA8, 0x90C7, 0xDBA9, 0x90D3, 0xDBAA, 0x90E6,
+	0xDBAB, 0x90E2, 0xDBAC, 0x90DC, 0xDBAD, 0x90D7, 0xDBAE, 0x90DB,
+	0xDBAF, 0x90EB, 0xDBB0, 0x90EF, 0xDBB1, 0x90FE, 0xDBB2, 0x9104,
+	0xDBB3, 0x9122, 0xDBB4, 0x911E, 0xDBB5, 0x9123, 0xDBB6, 0x9131,
+	0xDBB7, 0x912F, 0xDBB8, 0x9139, 0xDBB9, 0x9143, 0xDBBA, 0x9146,
+	0xDBBB, 0x520D, 0xDBBC, 0x5942, 0xDBBD, 0x52A2, 0xDBBE, 0x52AC,
+	0xDBBF, 0x52AD, 0xDBC0, 0x52BE, 0xDBC1, 0x54FF, 0xDBC2, 0x52D0,
+	0xDBC3, 0x52D6, 0xDBC4, 0x52F0, 0xDBC5, 0x53DF, 0xDBC6, 0x71EE,
+	0xDBC7, 0x77CD, 0xDBC8, 0x5EF4, 0xDBC9, 0x51F5, 0xDBCA, 0x51FC,
+	0xDBCB, 0x9B2F, 0xDBCC, 0x53B6, 0xDBCD, 0x5F01, 0xDBCE, 0x755A,
+	0xDBCF, 0x5DEF, 0xDBD0, 0x574C, 0xDBD1, 0x57A9, 0xDBD2, 0x57A1,
+	0xDBD3, 0x587E, 0xDBD4, 0x58BC, 0xDBD5, 0x58C5, 0xDBD6, 0x58D1,
+	0xDBD7, 0x5729, 0xDBD8, 0x572C, 0xDBD9, 0x572A, 0xDBDA, 0x5733,
+	0xDBDB, 0x5739, 0xDBDC, 0x572E, 0xDBDD, 0x572F, 0xDBDE, 0x575C,
+	0xDBDF, 0x573B, 0xDBE0, 0x5742, 0xDBE1, 0x5769, 0xDBE2, 0x5785,
+	0xDBE3, 0x576B, 0xDBE4, 0x5786, 0xDBE5, 0x577C, 0xDBE6, 0x577B,
+	0xDBE7, 0x5768, 0xDBE8, 0x576D, 0xDBE9, 0x5776, 0xDBEA, 0x5773,
+	0xDBEB, 0x57AD, 0xDBEC, 0x57A4, 0xDBED, 0x578C, 0xDBEE, 0x57B2,
+	0xDBEF, 0x57CF, 0xDBF0, 0x57A7, 0xDBF1, 0x57B4, 0xDBF2, 0x5793,
+	0xDBF3, 0x57A0, 0xDBF4, 0x57D5, 0xDBF5, 0x57D8, 0xDBF6, 0x57DA,
+	0xDBF7, 0x57D9, 0xDBF8, 0x57D2, 0xDBF9, 0x57B8, 0xDBFA, 0x57F4,
+	0xDBFB, 0x57EF, 0xDBFC, 0x57F8, 0xDBFD, 0x57E4, 0xDBFE, 0x57DD,
+	0xDC40, 0x8E73, 0xDC41, 0x8E75, 0xDC42, 0x8E77, 0xDC43, 0x8E78,
+	0xDC44, 0x8E79, 0xDC45, 0x8E7A, 0xDC46, 0x8E7B, 0xDC47, 0x8E7D,
+	0xDC48, 0x8E7E, 0xDC49, 0x8E80, 0xDC4A, 0x8E82, 0xDC4B, 0x8E83,
+	0xDC4C, 0x8E84, 0xDC4D, 0x8E86, 0xDC4E, 0x8E88, 0xDC4F, 0x8E89,
+	0xDC50, 0x8E8A, 0xDC51, 0x8E8B, 0xDC52, 0x8E8C, 0xDC53, 0x8E8D,
+	0xDC54, 0x8E8E, 0xDC55, 0x8E91, 0xDC56, 0x8E92, 0xDC57, 0x8E93,
+	0xDC58, 0x8E95, 0xDC59, 0x8E96, 0xDC5A, 0x8E97, 0xDC5B, 0x8E98,
+	0xDC5C, 0x8E99, 0xDC5D, 0x8E9A, 0xDC5E, 0x8E9B, 0xDC5F, 0x8E9D,
+	0xDC60, 0x8E9F, 0xDC61, 0x8EA0, 0xDC62, 0x8EA1, 0xDC63, 0x8EA2,
+	0xDC64, 0x8EA3, 0xDC65, 0x8EA4, 0xDC66, 0x8EA5, 0xDC67, 0x8EA6,
+	0xDC68, 0x8EA7, 0xDC69, 0x8EA8, 0xDC6A, 0x8EA9, 0xDC6B, 0x8EAA,
+	0xDC6C, 0x8EAD, 0xDC6D, 0x8EAE, 0xDC6E, 0x8EB0, 0xDC6F, 0x8EB1,
+	0xDC70, 0x8EB3, 0xDC71, 0x8EB4, 0xDC72, 0x8EB5, 0xDC73, 0x8EB6,
+	0xDC74, 0x8EB7, 0xDC75, 0x8EB8, 0xDC76, 0x8EB9, 0xDC77, 0x8EBB,
+	0xDC78, 0x8EBC, 0xDC79, 0x8EBD, 0xDC7A, 0x8EBE, 0xDC7B, 0x8EBF,
+	0xDC7C, 0x8EC0, 0xDC7D, 0x8EC1, 0xDC7E, 0x8EC2, 0xDC80, 0x8EC3,
+	0xDC81, 0x8EC4, 0xDC82, 0x8EC5, 0xDC83, 0x8EC6, 0xDC84, 0x8EC7,
+	0xDC85, 0x8EC8, 0xDC86, 0x8EC9, 0xDC87, 0x8ECA, 0xDC88, 0x8ECB,
+	0xDC89, 0x8ECC, 0xDC8A, 0x8ECD, 0xDC8B, 0x8ECF, 0xDC8C, 0x8ED0,
+	0xDC8D, 0x8ED1, 0xDC8E, 0x8ED2, 0xDC8F, 0x8ED3, 0xDC90, 0x8ED4,
+	0xDC91, 0x8ED5, 0xDC92, 0x8ED6, 0xDC93, 0x8ED7, 0xDC94, 0x8ED8,
+	0xDC95, 0x8ED9, 0xDC96, 0x8EDA, 0xDC97, 0x8EDB, 0xDC98, 0x8EDC,
+	0xDC99, 0x8EDD, 0xDC9A, 0x8EDE, 0xDC9B, 0x8EDF, 0xDC9C, 0x8EE0,
+	0xDC9D, 0x8EE1, 0xDC9E, 0x8EE2, 0xDC9F, 0x8EE3, 0xDCA0, 0x8EE4,
+	0xDCA1, 0x580B, 0xDCA2, 0x580D, 0xDCA3, 0x57FD, 0xDCA4, 0x57ED,
+	0xDCA5, 0x5800, 0xDCA6, 0x581E, 0xDCA7, 0x5819, 0xDCA8, 0x5844,
+	0xDCA9, 0x5820, 0xDCAA, 0x5865, 0xDCAB, 0x586C, 0xDCAC, 0x5881,
+	0xDCAD, 0x5889, 0xDCAE, 0x589A, 0xDCAF, 0x5880, 0xDCB0, 0x99A8,
+	0xDCB1, 0x9F19, 0xDCB2, 0x61FF, 0xDCB3, 0x8279, 0xDCB4, 0x827D,
+	0xDCB5, 0x827F, 0xDCB6, 0x828F, 0xDCB7, 0x828A, 0xDCB8, 0x82A8,
+	0xDCB9, 0x8284, 0xDCBA, 0x828E, 0xDCBB, 0x8291, 0xDCBC, 0x8297,
+	0xDCBD, 0x8299, 0xDCBE, 0x82AB, 0xDCBF, 0x82B8, 0xDCC0, 0x82BE,
+	0xDCC1, 0x82B0, 0xDCC2, 0x82C8, 0xDCC3, 0x82CA, 0xDCC4, 0x82E3,
+	0xDCC5, 0x8298, 0xDCC6, 0x82B7, 0xDCC7, 0x82AE, 0xDCC8, 0x82CB,
+	0xDCC9, 0x82CC, 0xDCCA, 0x82C1, 0xDCCB, 0x82A9, 0xDCCC, 0x82B4,
+	0xDCCD, 0x82A1, 0xDCCE, 0x82AA, 0xDCCF, 0x829F, 0xDCD0, 0x82C4,
+	0xDCD1, 0x82CE, 0xDCD2, 0x82A4, 0xDCD3, 0x82E1, 0xDCD4, 0x8309,
+	0xDCD5, 0x82F7, 0xDCD6, 0x82E4, 0xDCD7, 0x830F, 0xDCD8, 0x8307,
+	0xDCD9, 0x82DC, 0xDCDA, 0x82F4, 0xDCDB, 0x82D2, 0xDCDC, 0x82D8,
+	0xDCDD, 0x830C, 0xDCDE, 0x82FB, 0xDCDF, 0x82D3, 0xDCE0, 0x8311,
+	0xDCE1, 0x831A, 0xDCE2, 0x8306, 0xDCE3, 0x8314, 0xDCE4, 0x8315,
+	0xDCE5, 0x82E0, 0xDCE6, 0x82D5, 0xDCE7, 0x831C, 0xDCE8, 0x8351,
+	0xDCE9, 0x835B, 0xDCEA, 0x835C, 0xDCEB, 0x8308, 0xDCEC, 0x8392,
+	0xDCED, 0x833C, 0xDCEE, 0x8334, 0xDCEF, 0x8331, 0xDCF0, 0x839B,
+	0xDCF1, 0x835E, 0xDCF2, 0x832F, 0xDCF3, 0x834F, 0xDCF4, 0x8347,
+	0xDCF5, 0x8343, 0xDCF6, 0x835F, 0xDCF7, 0x8340, 0xDCF8, 0x8317,
+	0xDCF9, 0x8360, 0xDCFA, 0x832D, 0xDCFB, 0x833A, 0xDCFC, 0x8333,
+	0xDCFD, 0x8366, 0xDCFE, 0x8365, 0xDD40, 0x8EE5, 0xDD41, 0x8EE6,
+	0xDD42, 0x8EE7, 0xDD43, 0x8EE8, 0xDD44, 0x8EE9, 0xDD45, 0x8EEA,
+	0xDD46, 0x8EEB, 0xDD47, 0x8EEC, 0xDD48, 0x8EED, 0xDD49, 0x8EEE,
+	0xDD4A, 0x8EEF, 0xDD4B, 0x8EF0, 0xDD4C, 0x8EF1, 0xDD4D, 0x8EF2,
+	0xDD4E, 0x8EF3, 0xDD4F, 0x8EF4, 0xDD50, 0x8EF5, 0xDD51, 0x8EF6,
+	0xDD52, 0x8EF7, 0xDD53, 0x8EF8, 0xDD54, 0x8EF9, 0xDD55, 0x8EFA,
+	0xDD56, 0x8EFB, 0xDD57, 0x8EFC, 0xDD58, 0x8EFD, 0xDD59, 0x8EFE,
+	0xDD5A, 0x8EFF, 0xDD5B, 0x8F00, 0xDD5C, 0x8F01, 0xDD5D, 0x8F02,
+	0xDD5E, 0x8F03, 0xDD5F, 0x8F04, 0xDD60, 0x8F05, 0xDD61, 0x8F06,
+	0xDD62, 0x8F07, 0xDD63, 0x8F08, 0xDD64, 0x8F09, 0xDD65, 0x8F0A,
+	0xDD66, 0x8F0B, 0xDD67, 0x8F0C, 0xDD68, 0x8F0D, 0xDD69, 0x8F0E,
+	0xDD6A, 0x8F0F, 0xDD6B, 0x8F10, 0xDD6C, 0x8F11, 0xDD6D, 0x8F12,
+	0xDD6E, 0x8F13, 0xDD6F, 0x8F14, 0xDD70, 0x8F15, 0xDD71, 0x8F16,
+	0xDD72, 0x8F17, 0xDD73, 0x8F18, 0xDD74, 0x8F19, 0xDD75, 0x8F1A,
+	0xDD76, 0x8F1B, 0xDD77, 0x8F1C, 0xDD78, 0x8F1D, 0xDD79, 0x8F1E,
+	0xDD7A, 0x8F1F, 0xDD7B, 0x8F20, 0xDD7C, 0x8F21, 0xDD7D, 0x8F22,
+	0xDD7E, 0x8F23, 0xDD80, 0x8F24, 0xDD81, 0x8F25, 0xDD82, 0x8F26,
+	0xDD83, 0x8F27, 0xDD84, 0x8F28, 0xDD85, 0x8F29, 0xDD86, 0x8F2A,
+	0xDD87, 0x8F2B, 0xDD88, 0x8F2C, 0xDD89, 0x8F2D, 0xDD8A, 0x8F2E,
+	0xDD8B, 0x8F2F, 0xDD8C, 0x8F30, 0xDD8D, 0x8F31, 0xDD8E, 0x8F32,
+	0xDD8F, 0x8F33, 0xDD90, 0x8F34, 0xDD91, 0x8F35, 0xDD92, 0x8F36,
+	0xDD93, 0x8F37, 0xDD94, 0x8F38, 0xDD95, 0x8F39, 0xDD96, 0x8F3A,
+	0xDD97, 0x8F3B, 0xDD98, 0x8F3C, 0xDD99, 0x8F3D, 0xDD9A, 0x8F3E,
+	0xDD9B, 0x8F3F, 0xDD9C, 0x8F40, 0xDD9D, 0x8F41, 0xDD9E, 0x8F42,
+	0xDD9F, 0x8F43, 0xDDA0, 0x8F44, 0xDDA1, 0x8368, 0xDDA2, 0x831B,
+	0xDDA3, 0x8369, 0xDDA4, 0x836C, 0xDDA5, 0x836A, 0xDDA6, 0x836D,
+	0xDDA7, 0x836E, 0xDDA8, 0x83B0, 0xDDA9, 0x8378, 0xDDAA, 0x83B3,
+	0xDDAB, 0x83B4, 0xDDAC, 0x83A0, 0xDDAD, 0x83AA, 0xDDAE, 0x8393,
+	0xDDAF, 0x839C, 0xDDB0, 0x8385, 0xDDB1, 0x837C, 0xDDB2, 0x83B6,
+	0xDDB3, 0x83A9, 0xDDB4, 0x837D, 0xDDB5, 0x83B8, 0xDDB6, 0x837B,
+	0xDDB7, 0x8398, 0xDDB8, 0x839E, 0xDDB9, 0x83A8, 0xDDBA, 0x83BA,
+	0xDDBB, 0x83BC, 0xDDBC, 0x83C1, 0xDDBD, 0x8401, 0xDDBE, 0x83E5,
+	0xDDBF, 0x83D8, 0xDDC0, 0x5807, 0xDDC1, 0x8418, 0xDDC2, 0x840B,
+	0xDDC3, 0x83DD, 0xDDC4, 0x83FD, 0xDDC5, 0x83D6, 0xDDC6, 0x841C,
+	0xDDC7, 0x8438, 0xDDC8, 0x8411, 0xDDC9, 0x8406, 0xDDCA, 0x83D4,
+	0xDDCB, 0x83DF, 0xDDCC, 0x840F, 0xDDCD, 0x8403, 0xDDCE, 0x83F8,
+	0xDDCF, 0x83F9, 0xDDD0, 0x83EA, 0xDDD1, 0x83C5, 0xDDD2, 0x83C0,
+	0xDDD3, 0x8426, 0xDDD4, 0x83F0, 0xDDD5, 0x83E1, 0xDDD6, 0x845C,
+	0xDDD7, 0x8451, 0xDDD8, 0x845A, 0xDDD9, 0x8459, 0xDDDA, 0x8473,
+	0xDDDB, 0x8487, 0xDDDC, 0x8488, 0xDDDD, 0x847A, 0xDDDE, 0x8489,
+	0xDDDF, 0x8478, 0xDDE0, 0x843C, 0xDDE1, 0x8446, 0xDDE2, 0x8469,
+	0xDDE3, 0x8476, 0xDDE4, 0x848C, 0xDDE5, 0x848E, 0xDDE6, 0x8431,
+	0xDDE7, 0x846D, 0xDDE8, 0x84C1, 0xDDE9, 0x84CD, 0xDDEA, 0x84D0,
+	0xDDEB, 0x84E6, 0xDDEC, 0x84BD, 0xDDED, 0x84D3, 0xDDEE, 0x84CA,
+	0xDDEF, 0x84BF, 0xDDF0, 0x84BA, 0xDDF1, 0x84E0, 0xDDF2, 0x84A1,
+	0xDDF3, 0x84B9, 0xDDF4, 0x84B4, 0xDDF5, 0x8497, 0xDDF6, 0x84E5,
+	0xDDF7, 0x84E3, 0xDDF8, 0x850C, 0xDDF9, 0x750D, 0xDDFA, 0x8538,
+	0xDDFB, 0x84F0, 0xDDFC, 0x8539, 0xDDFD, 0x851F, 0xDDFE, 0x853A,
+	0xDE40, 0x8F45, 0xDE41, 0x8F46, 0xDE42, 0x8F47, 0xDE43, 0x8F48,
+	0xDE44, 0x8F49, 0xDE45, 0x8F4A, 0xDE46, 0x8F4B, 0xDE47, 0x8F4C,
+	0xDE48, 0x8F4D, 0xDE49, 0x8F4E, 0xDE4A, 0x8F4F, 0xDE4B, 0x8F50,
+	0xDE4C, 0x8F51, 0xDE4D, 0x8F52, 0xDE4E, 0x8F53, 0xDE4F, 0x8F54,
+	0xDE50, 0x8F55, 0xDE51, 0x8F56, 0xDE52, 0x8F57, 0xDE53, 0x8F58,
+	0xDE54, 0x8F59, 0xDE55, 0x8F5A, 0xDE56, 0x8F5B, 0xDE57, 0x8F5C,
+	0xDE58, 0x8F5D, 0xDE59, 0x8F5E, 0xDE5A, 0x8F5F, 0xDE5B, 0x8F60,
+	0xDE5C, 0x8F61, 0xDE5D, 0x8F62, 0xDE5E, 0x8F63, 0xDE5F, 0x8F64,
+	0xDE60, 0x8F65, 0xDE61, 0x8F6A, 0xDE62, 0x8F80, 0xDE63, 0x8F8C,
+	0xDE64, 0x8F92, 0xDE65, 0x8F9D, 0xDE66, 0x8FA0, 0xDE67, 0x8FA1,
+	0xDE68, 0x8FA2, 0xDE69, 0x8FA4, 0xDE6A, 0x8FA5, 0xDE6B, 0x8FA6,
+	0xDE6C, 0x8FA7, 0xDE6D, 0x8FAA, 0xDE6E, 0x8FAC, 0xDE6F, 0x8FAD,
+	0xDE70, 0x8FAE, 0xDE71, 0x8FAF, 0xDE72, 0x8FB2, 0xDE73, 0x8FB3,
+	0xDE74, 0x8FB4, 0xDE75, 0x8FB5, 0xDE76, 0x8FB7, 0xDE77, 0x8FB8,
+	0xDE78, 0x8FBA, 0xDE79, 0x8FBB, 0xDE7A, 0x8FBC, 0xDE7B, 0x8FBF,
+	0xDE7C, 0x8FC0, 0xDE7D, 0x8FC3, 0xDE7E, 0x8FC6, 0xDE80, 0x8FC9,
+	0xDE81, 0x8FCA, 0xDE82, 0x8FCB, 0xDE83, 0x8FCC, 0xDE84, 0x8FCD,
+	0xDE85, 0x8FCF, 0xDE86, 0x8FD2, 0xDE87, 0x8FD6, 0xDE88, 0x8FD7,
+	0xDE89, 0x8FDA, 0xDE8A, 0x8FE0, 0xDE8B, 0x8FE1, 0xDE8C, 0x8FE3,
+	0xDE8D, 0x8FE7, 0xDE8E, 0x8FEC, 0xDE8F, 0x8FEF, 0xDE90, 0x8FF1,
+	0xDE91, 0x8FF2, 0xDE92, 0x8FF4, 0xDE93, 0x8FF5, 0xDE94, 0x8FF6,
+	0xDE95, 0x8FFA, 0xDE96, 0x8FFB, 0xDE97, 0x8FFC, 0xDE98, 0x8FFE,
+	0xDE99, 0x8FFF, 0xDE9A, 0x9007, 0xDE9B, 0x9008, 0xDE9C, 0x900C,
+	0xDE9D, 0x900E, 0xDE9E, 0x9013, 0xDE9F, 0x9015, 0xDEA0, 0x9018,
+	0xDEA1, 0x8556, 0xDEA2, 0x853B, 0xDEA3, 0x84FF, 0xDEA4, 0x84FC,
+	0xDEA5, 0x8559, 0xDEA6, 0x8548, 0xDEA7, 0x8568, 0xDEA8, 0x8564,
+	0xDEA9, 0x855E, 0xDEAA, 0x857A, 0xDEAB, 0x77A2, 0xDEAC, 0x8543,
+	0xDEAD, 0x8572, 0xDEAE, 0x857B, 0xDEAF, 0x85A4, 0xDEB0, 0x85A8,
+	0xDEB1, 0x8587, 0xDEB2, 0x858F, 0xDEB3, 0x8579, 0xDEB4, 0x85AE,
+	0xDEB5, 0x859C, 0xDEB6, 0x8585, 0xDEB7, 0x85B9, 0xDEB8, 0x85B7,
+	0xDEB9, 0x85B0, 0xDEBA, 0x85D3, 0xDEBB, 0x85C1, 0xDEBC, 0x85DC,
+	0xDEBD, 0x85FF, 0xDEBE, 0x8627, 0xDEBF, 0x8605, 0xDEC0, 0x8629,
+	0xDEC1, 0x8616, 0xDEC2, 0x863C, 0xDEC3, 0x5EFE, 0xDEC4, 0x5F08,
+	0xDEC5, 0x593C, 0xDEC6, 0x5941, 0xDEC7, 0x8037, 0xDEC8, 0x5955,
+	0xDEC9, 0x595A, 0xDECA, 0x5958, 0xDECB, 0x530F, 0xDECC, 0x5C22,
+	0xDECD, 0x5C25, 0xDECE, 0x5C2C, 0xDECF, 0x5C34, 0xDED0, 0x624C,
+	0xDED1, 0x626A, 0xDED2, 0x629F, 0xDED3, 0x62BB, 0xDED4, 0x62CA,
+	0xDED5, 0x62DA, 0xDED6, 0x62D7, 0xDED7, 0x62EE, 0xDED8, 0x6322,
+	0xDED9, 0x62F6, 0xDEDA, 0x6339, 0xDEDB, 0x634B, 0xDEDC, 0x6343,
+	0xDEDD, 0x63AD, 0xDEDE, 0x63F6, 0xDEDF, 0x6371, 0xDEE0, 0x637A,
+	0xDEE1, 0x638E, 0xDEE2, 0x63B4, 0xDEE3, 0x636D, 0xDEE4, 0x63AC,
+	0xDEE5, 0x638A, 0xDEE6, 0x6369, 0xDEE7, 0x63AE, 0xDEE8, 0x63BC,
+	0xDEE9, 0x63F2, 0xDEEA, 0x63F8, 0xDEEB, 0x63E0, 0xDEEC, 0x63FF,
+	0xDEED, 0x63C4, 0xDEEE, 0x63DE, 0xDEEF, 0x63CE, 0xDEF0, 0x6452,
+	0xDEF1, 0x63C6, 0xDEF2, 0x63BE, 0xDEF3, 0x6445, 0xDEF4, 0x6441,
+	0xDEF5, 0x640B, 0xDEF6, 0x641B, 0xDEF7, 0x6420, 0xDEF8, 0x640C,
+	0xDEF9, 0x6426, 0xDEFA, 0x6421, 0xDEFB, 0x645E, 0xDEFC, 0x6484,
+	0xDEFD, 0x646D, 0xDEFE, 0x6496, 0xDF40, 0x9019, 0xDF41, 0x901C,
+	0xDF42, 0x9023, 0xDF43, 0x9024, 0xDF44, 0x9025, 0xDF45, 0x9027,
+	0xDF46, 0x9028, 0xDF47, 0x9029, 0xDF48, 0x902A, 0xDF49, 0x902B,
+	0xDF4A, 0x902C, 0xDF4B, 0x9030, 0xDF4C, 0x9031, 0xDF4D, 0x9032,
+	0xDF4E, 0x9033, 0xDF4F, 0x9034, 0xDF50, 0x9037, 0xDF51, 0x9039,
+	0xDF52, 0x903A, 0xDF53, 0x903D, 0xDF54, 0x903F, 0xDF55, 0x9040,
+	0xDF56, 0x9043, 0xDF57, 0x9045, 0xDF58, 0x9046, 0xDF59, 0x9048,
+	0xDF5A, 0x9049, 0xDF5B, 0x904A, 0xDF5C, 0x904B, 0xDF5D, 0x904C,
+	0xDF5E, 0x904E, 0xDF5F, 0x9054, 0xDF60, 0x9055, 0xDF61, 0x9056,
+	0xDF62, 0x9059, 0xDF63, 0x905A, 0xDF64, 0x905C, 0xDF65, 0x905D,
+	0xDF66, 0x905E, 0xDF67, 0x905F, 0xDF68, 0x9060, 0xDF69, 0x9061,
+	0xDF6A, 0x9064, 0xDF6B, 0x9066, 0xDF6C, 0x9067, 0xDF6D, 0x9069,
+	0xDF6E, 0x906A, 0xDF6F, 0x906B, 0xDF70, 0x906C, 0xDF71, 0x906F,
+	0xDF72, 0x9070, 0xDF73, 0x9071, 0xDF74, 0x9072, 0xDF75, 0x9073,
+	0xDF76, 0x9076, 0xDF77, 0x9077, 0xDF78, 0x9078, 0xDF79, 0x9079,
+	0xDF7A, 0x907A, 0xDF7B, 0x907B, 0xDF7C, 0x907C, 0xDF7D, 0x907E,
+	0xDF7E, 0x9081, 0xDF80, 0x9084, 0xDF81, 0x9085, 0xDF82, 0x9086,
+	0xDF83, 0x9087, 0xDF84, 0x9089, 0xDF85, 0x908A, 0xDF86, 0x908C,
+	0xDF87, 0x908D, 0xDF88, 0x908E, 0xDF89, 0x908F, 0xDF8A, 0x9090,
+	0xDF8B, 0x9092, 0xDF8C, 0x9094, 0xDF8D, 0x9096, 0xDF8E, 0x9098,
+	0xDF8F, 0x909A, 0xDF90, 0x909C, 0xDF91, 0x909E, 0xDF92, 0x909F,
+	0xDF93, 0x90A0, 0xDF94, 0x90A4, 0xDF95, 0x90A5, 0xDF96, 0x90A7,
+	0xDF97, 0x90A8, 0xDF98, 0x90A9, 0xDF99, 0x90AB, 0xDF9A, 0x90AD,
+	0xDF9B, 0x90B2, 0xDF9C, 0x90B7, 0xDF9D, 0x90BC, 0xDF9E, 0x90BD,
+	0xDF9F, 0x90BF, 0xDFA0, 0x90C0, 0xDFA1, 0x647A, 0xDFA2, 0x64B7,
+	0xDFA3, 0x64B8, 0xDFA4, 0x6499, 0xDFA5, 0x64BA, 0xDFA6, 0x64C0,
+	0xDFA7, 0x64D0, 0xDFA8, 0x64D7, 0xDFA9, 0x64E4, 0xDFAA, 0x64E2,
+	0xDFAB, 0x6509, 0xDFAC, 0x6525, 0xDFAD, 0x652E, 0xDFAE, 0x5F0B,
+	0xDFAF, 0x5FD2, 0xDFB0, 0x7519, 0xDFB1, 0x5F11, 0xDFB2, 0x535F,
+	0xDFB3, 0x53F1, 0xDFB4, 0x53FD, 0xDFB5, 0x53E9, 0xDFB6, 0x53E8,
+	0xDFB7, 0x53FB, 0xDFB8, 0x5412, 0xDFB9, 0x5416, 0xDFBA, 0x5406,
+	0xDFBB, 0x544B, 0xDFBC, 0x5452, 0xDFBD, 0x5453, 0xDFBE, 0x5454,
+	0xDFBF, 0x5456, 0xDFC0, 0x5443, 0xDFC1, 0x5421, 0xDFC2, 0x5457,
+	0xDFC3, 0x5459, 0xDFC4, 0x5423, 0xDFC5, 0x5432, 0xDFC6, 0x5482,
+	0xDFC7, 0x5494, 0xDFC8, 0x5477, 0xDFC9, 0x5471, 0xDFCA, 0x5464,
+	0xDFCB, 0x549A, 0xDFCC, 0x549B, 0xDFCD, 0x5484, 0xDFCE, 0x5476,
+	0xDFCF, 0x5466, 0xDFD0, 0x549D, 0xDFD1, 0x54D0, 0xDFD2, 0x54AD,
+	0xDFD3, 0x54C2, 0xDFD4, 0x54B4, 0xDFD5, 0x54D2, 0xDFD6, 0x54A7,
+	0xDFD7, 0x54A6, 0xDFD8, 0x54D3, 0xDFD9, 0x54D4, 0xDFDA, 0x5472,
+	0xDFDB, 0x54A3, 0xDFDC, 0x54D5, 0xDFDD, 0x54BB, 0xDFDE, 0x54BF,
+	0xDFDF, 0x54CC, 0xDFE0, 0x54D9, 0xDFE1, 0x54DA, 0xDFE2, 0x54DC,
+	0xDFE3, 0x54A9, 0xDFE4, 0x54AA, 0xDFE5, 0x54A4, 0xDFE6, 0x54DD,
+	0xDFE7, 0x54CF, 0xDFE8, 0x54DE, 0xDFE9, 0x551B, 0xDFEA, 0x54E7,
+	0xDFEB, 0x5520, 0xDFEC, 0x54FD, 0xDFED, 0x5514, 0xDFEE, 0x54F3,
+	0xDFEF, 0x5522, 0xDFF0, 0x5523, 0xDFF1, 0x550F, 0xDFF2, 0x5511,
+	0xDFF3, 0x5527, 0xDFF4, 0x552A, 0xDFF5, 0x5567, 0xDFF6, 0x558F,
+	0xDFF7, 0x55B5, 0xDFF8, 0x5549, 0xDFF9, 0x556D, 0xDFFA, 0x5541,
+	0xDFFB, 0x5555, 0xDFFC, 0x553F, 0xDFFD, 0x5550, 0xDFFE, 0x553C,
+	0xE040, 0x90C2, 0xE041, 0x90C3, 0xE042, 0x90C6, 0xE043, 0x90C8,
+	0xE044, 0x90C9, 0xE045, 0x90CB, 0xE046, 0x90CC, 0xE047, 0x90CD,
+	0xE048, 0x90D2, 0xE049, 0x90D4, 0xE04A, 0x90D5, 0xE04B, 0x90D6,
+	0xE04C, 0x90D8, 0xE04D, 0x90D9, 0xE04E, 0x90DA, 0xE04F, 0x90DE,
+	0xE050, 0x90DF, 0xE051, 0x90E0, 0xE052, 0x90E3, 0xE053, 0x90E4,
+	0xE054, 0x90E5, 0xE055, 0x90E9, 0xE056, 0x90EA, 0xE057, 0x90EC,
+	0xE058, 0x90EE, 0xE059, 0x90F0, 0xE05A, 0x90F1, 0xE05B, 0x90F2,
+	0xE05C, 0x90F3, 0xE05D, 0x90F5, 0xE05E, 0x90F6, 0xE05F, 0x90F7,
+	0xE060, 0x90F9, 0xE061, 0x90FA, 0xE062, 0x90FB, 0xE063, 0x90FC,
+	0xE064, 0x90FF, 0xE065, 0x9100, 0xE066, 0x9101, 0xE067, 0x9103,
+	0xE068, 0x9105, 0xE069, 0x9106, 0xE06A, 0x9107, 0xE06B, 0x9108,
+	0xE06C, 0x9109, 0xE06D, 0x910A, 0xE06E, 0x910B, 0xE06F, 0x910C,
+	0xE070, 0x910D, 0xE071, 0x910E, 0xE072, 0x910F, 0xE073, 0x9110,
+	0xE074, 0x9111, 0xE075, 0x9112, 0xE076, 0x9113, 0xE077, 0x9114,
+	0xE078, 0x9115, 0xE079, 0x9116, 0xE07A, 0x9117, 0xE07B, 0x9118,
+	0xE07C, 0x911A, 0xE07D, 0x911B, 0xE07E, 0x911C, 0xE080, 0x911D,
+	0xE081, 0x911F, 0xE082, 0x9120, 0xE083, 0x9121, 0xE084, 0x9124,
+	0xE085, 0x9125, 0xE086, 0x9126, 0xE087, 0x9127, 0xE088, 0x9128,
+	0xE089, 0x9129, 0xE08A, 0x912A, 0xE08B, 0x912B, 0xE08C, 0x912C,
+	0xE08D, 0x912D, 0xE08E, 0x912E, 0xE08F, 0x9130, 0xE090, 0x9132,
+	0xE091, 0x9133, 0xE092, 0x9134, 0xE093, 0x9135, 0xE094, 0x9136,
+	0xE095, 0x9137, 0xE096, 0x9138, 0xE097, 0x913A, 0xE098, 0x913B,
+	0xE099, 0x913C, 0xE09A, 0x913D, 0xE09B, 0x913E, 0xE09C, 0x913F,
+	0xE09D, 0x9140, 0xE09E, 0x9141, 0xE09F, 0x9142, 0xE0A0, 0x9144,
+	0xE0A1, 0x5537, 0xE0A2, 0x5556, 0xE0A3, 0x5575, 0xE0A4, 0x5576,
+	0xE0A5, 0x5577, 0xE0A6, 0x5533, 0xE0A7, 0x5530, 0xE0A8, 0x555C,
+	0xE0A9, 0x558B, 0xE0AA, 0x55D2, 0xE0AB, 0x5583, 0xE0AC, 0x55B1,
+	0xE0AD, 0x55B9, 0xE0AE, 0x5588, 0xE0AF, 0x5581, 0xE0B0, 0x559F,
+	0xE0B1, 0x557E, 0xE0B2, 0x55D6, 0xE0B3, 0x5591, 0xE0B4, 0x557B,
+	0xE0B5, 0x55DF, 0xE0B6, 0x55BD, 0xE0B7, 0x55BE, 0xE0B8, 0x5594,
+	0xE0B9, 0x5599, 0xE0BA, 0x55EA, 0xE0BB, 0x55F7, 0xE0BC, 0x55C9,
+	0xE0BD, 0x561F, 0xE0BE, 0x55D1, 0xE0BF, 0x55EB, 0xE0C0, 0x55EC,
+	0xE0C1, 0x55D4, 0xE0C2, 0x55E6, 0xE0C3, 0x55DD, 0xE0C4, 0x55C4,
+	0xE0C5, 0x55EF, 0xE0C6, 0x55E5, 0xE0C7, 0x55F2, 0xE0C8, 0x55F3,
+	0xE0C9, 0x55CC, 0xE0CA, 0x55CD, 0xE0CB, 0x55E8, 0xE0CC, 0x55F5,
+	0xE0CD, 0x55E4, 0xE0CE, 0x8F94, 0xE0CF, 0x561E, 0xE0D0, 0x5608,
+	0xE0D1, 0x560C, 0xE0D2, 0x5601, 0xE0D3, 0x5624, 0xE0D4, 0x5623,
+	0xE0D5, 0x55FE, 0xE0D6, 0x5600, 0xE0D7, 0x5627, 0xE0D8, 0x562D,
+	0xE0D9, 0x5658, 0xE0DA, 0x5639, 0xE0DB, 0x5657, 0xE0DC, 0x562C,
+	0xE0DD, 0x564D, 0xE0DE, 0x5662, 0xE0DF, 0x5659, 0xE0E0, 0x565C,
+	0xE0E1, 0x564C, 0xE0E2, 0x5654, 0xE0E3, 0x5686, 0xE0E4, 0x5664,
+	0xE0E5, 0x5671, 0xE0E6, 0x566B, 0xE0E7, 0x567B, 0xE0E8, 0x567C,
+	0xE0E9, 0x5685, 0xE0EA, 0x5693, 0xE0EB, 0x56AF, 0xE0EC, 0x56D4,
+	0xE0ED, 0x56D7, 0xE0EE, 0x56DD, 0xE0EF, 0x56E1, 0xE0F0, 0x56F5,
+	0xE0F1, 0x56EB, 0xE0F2, 0x56F9, 0xE0F3, 0x56FF, 0xE0F4, 0x5704,
+	0xE0F5, 0x570A, 0xE0F6, 0x5709, 0xE0F7, 0x571C, 0xE0F8, 0x5E0F,
+	0xE0F9, 0x5E19, 0xE0FA, 0x5E14, 0xE0FB, 0x5E11, 0xE0FC, 0x5E31,
+	0xE0FD, 0x5E3B, 0xE0FE, 0x5E3C, 0xE140, 0x9145, 0xE141, 0x9147,
+	0xE142, 0x9148, 0xE143, 0x9151, 0xE144, 0x9153, 0xE145, 0x9154,
+	0xE146, 0x9155, 0xE147, 0x9156, 0xE148, 0x9158, 0xE149, 0x9159,
+	0xE14A, 0x915B, 0xE14B, 0x915C, 0xE14C, 0x915F, 0xE14D, 0x9160,
+	0xE14E, 0x9166, 0xE14F, 0x9167, 0xE150, 0x9168, 0xE151, 0x916B,
+	0xE152, 0x916D, 0xE153, 0x9173, 0xE154, 0x917A, 0xE155, 0x917B,
+	0xE156, 0x917C, 0xE157, 0x9180, 0xE158, 0x9181, 0xE159, 0x9182,
+	0xE15A, 0x9183, 0xE15B, 0x9184, 0xE15C, 0x9186, 0xE15D, 0x9188,
+	0xE15E, 0x918A, 0xE15F, 0x918E, 0xE160, 0x918F, 0xE161, 0x9193,
+	0xE162, 0x9194, 0xE163, 0x9195, 0xE164, 0x9196, 0xE165, 0x9197,
+	0xE166, 0x9198, 0xE167, 0x9199, 0xE168, 0x919C, 0xE169, 0x919D,
+	0xE16A, 0x919E, 0xE16B, 0x919F, 0xE16C, 0x91A0, 0xE16D, 0x91A1,
+	0xE16E, 0x91A4, 0xE16F, 0x91A5, 0xE170, 0x91A6, 0xE171, 0x91A7,
+	0xE172, 0x91A8, 0xE173, 0x91A9, 0xE174, 0x91AB, 0xE175, 0x91AC,
+	0xE176, 0x91B0, 0xE177, 0x91B1, 0xE178, 0x91B2, 0xE179, 0x91B3,
+	0xE17A, 0x91B6, 0xE17B, 0x91B7, 0xE17C, 0x91B8, 0xE17D, 0x91B9,
+	0xE17E, 0x91BB, 0xE180, 0x91BC, 0xE181, 0x91BD, 0xE182, 0x91BE,
+	0xE183, 0x91BF, 0xE184, 0x91C0, 0xE185, 0x91C1, 0xE186, 0x91C2,
+	0xE187, 0x91C3, 0xE188, 0x91C4, 0xE189, 0x91C5, 0xE18A, 0x91C6,
+	0xE18B, 0x91C8, 0xE18C, 0x91CB, 0xE18D, 0x91D0, 0xE18E, 0x91D2,
+	0xE18F, 0x91D3, 0xE190, 0x91D4, 0xE191, 0x91D5, 0xE192, 0x91D6,
+	0xE193, 0x91D7, 0xE194, 0x91D8, 0xE195, 0x91D9, 0xE196, 0x91DA,
+	0xE197, 0x91DB, 0xE198, 0x91DD, 0xE199, 0x91DE, 0xE19A, 0x91DF,
+	0xE19B, 0x91E0, 0xE19C, 0x91E1, 0xE19D, 0x91E2, 0xE19E, 0x91E3,
+	0xE19F, 0x91E4, 0xE1A0, 0x91E5, 0xE1A1, 0x5E37, 0xE1A2, 0x5E44,
+	0xE1A3, 0x5E54, 0xE1A4, 0x5E5B, 0xE1A5, 0x5E5E, 0xE1A6, 0x5E61,
+	0xE1A7, 0x5C8C, 0xE1A8, 0x5C7A, 0xE1A9, 0x5C8D, 0xE1AA, 0x5C90,
+	0xE1AB, 0x5C96, 0xE1AC, 0x5C88, 0xE1AD, 0x5C98, 0xE1AE, 0x5C99,
+	0xE1AF, 0x5C91, 0xE1B0, 0x5C9A, 0xE1B1, 0x5C9C, 0xE1B2, 0x5CB5,
+	0xE1B3, 0x5CA2, 0xE1B4, 0x5CBD, 0xE1B5, 0x5CAC, 0xE1B6, 0x5CAB,
+	0xE1B7, 0x5CB1, 0xE1B8, 0x5CA3, 0xE1B9, 0x5CC1, 0xE1BA, 0x5CB7,
+	0xE1BB, 0x5CC4, 0xE1BC, 0x5CD2, 0xE1BD, 0x5CE4, 0xE1BE, 0x5CCB,
+	0xE1BF, 0x5CE5, 0xE1C0, 0x5D02, 0xE1C1, 0x5D03, 0xE1C2, 0x5D27,
+	0xE1C3, 0x5D26, 0xE1C4, 0x5D2E, 0xE1C5, 0x5D24, 0xE1C6, 0x5D1E,
+	0xE1C7, 0x5D06, 0xE1C8, 0x5D1B, 0xE1C9, 0x5D58, 0xE1CA, 0x5D3E,
+	0xE1CB, 0x5D34, 0xE1CC, 0x5D3D, 0xE1CD, 0x5D6C, 0xE1CE, 0x5D5B,
+	0xE1CF, 0x5D6F, 0xE1D0, 0x5D5D, 0xE1D1, 0x5D6B, 0xE1D2, 0x5D4B,
+	0xE1D3, 0x5D4A, 0xE1D4, 0x5D69, 0xE1D5, 0x5D74, 0xE1D6, 0x5D82,
+	0xE1D7, 0x5D99, 0xE1D8, 0x5D9D, 0xE1D9, 0x8C73, 0xE1DA, 0x5DB7,
+	0xE1DB, 0x5DC5, 0xE1DC, 0x5F73, 0xE1DD, 0x5F77, 0xE1DE, 0x5F82,
+	0xE1DF, 0x5F87, 0xE1E0, 0x5F89, 0xE1E1, 0x5F8C, 0xE1E2, 0x5F95,
+	0xE1E3, 0x5F99, 0xE1E4, 0x5F9C, 0xE1E5, 0x5FA8, 0xE1E6, 0x5FAD,
+	0xE1E7, 0x5FB5, 0xE1E8, 0x5FBC, 0xE1E9, 0x8862, 0xE1EA, 0x5F61,
+	0xE1EB, 0x72AD, 0xE1EC, 0x72B0, 0xE1ED, 0x72B4, 0xE1EE, 0x72B7,
+	0xE1EF, 0x72B8, 0xE1F0, 0x72C3, 0xE1F1, 0x72C1, 0xE1F2, 0x72CE,
+	0xE1F3, 0x72CD, 0xE1F4, 0x72D2, 0xE1F5, 0x72E8, 0xE1F6, 0x72EF,
+	0xE1F7, 0x72E9, 0xE1F8, 0x72F2, 0xE1F9, 0x72F4, 0xE1FA, 0x72F7,
+	0xE1FB, 0x7301, 0xE1FC, 0x72F3, 0xE1FD, 0x7303, 0xE1FE, 0x72FA,
+	0xE240, 0x91E6, 0xE241, 0x91E7, 0xE242, 0x91E8, 0xE243, 0x91E9,
+	0xE244, 0x91EA, 0xE245, 0x91EB, 0xE246, 0x91EC, 0xE247, 0x91ED,
+	0xE248, 0x91EE, 0xE249, 0x91EF, 0xE24A, 0x91F0, 0xE24B, 0x91F1,
+	0xE24C, 0x91F2, 0xE24D, 0x91F3, 0xE24E, 0x91F4, 0xE24F, 0x91F5,
+	0xE250, 0x91F6, 0xE251, 0x91F7, 0xE252, 0x91F8, 0xE253, 0x91F9,
+	0xE254, 0x91FA, 0xE255, 0x91FB, 0xE256, 0x91FC, 0xE257, 0x91FD,
+	0xE258, 0x91FE, 0xE259, 0x91FF, 0xE25A, 0x9200, 0xE25B, 0x9201,
+	0xE25C, 0x9202, 0xE25D, 0x9203, 0xE25E, 0x9204, 0xE25F, 0x9205,
+	0xE260, 0x9206, 0xE261, 0x9207, 0xE262, 0x9208, 0xE263, 0x9209,
+	0xE264, 0x920A, 0xE265, 0x920B, 0xE266, 0x920C, 0xE267, 0x920D,
+	0xE268, 0x920E, 0xE269, 0x920F, 0xE26A, 0x9210, 0xE26B, 0x9211,
+	0xE26C, 0x9212, 0xE26D, 0x9213, 0xE26E, 0x9214, 0xE26F, 0x9215,
+	0xE270, 0x9216, 0xE271, 0x9217, 0xE272, 0x9218, 0xE273, 0x9219,
+	0xE274, 0x921A, 0xE275, 0x921B, 0xE276, 0x921C, 0xE277, 0x921D,
+	0xE278, 0x921E, 0xE279, 0x921F, 0xE27A, 0x9220, 0xE27B, 0x9221,
+	0xE27C, 0x9222, 0xE27D, 0x9223, 0xE27E, 0x9224, 0xE280, 0x9225,
+	0xE281, 0x9226, 0xE282, 0x9227, 0xE283, 0x9228, 0xE284, 0x9229,
+	0xE285, 0x922A, 0xE286, 0x922B, 0xE287, 0x922C, 0xE288, 0x922D,
+	0xE289, 0x922E, 0xE28A, 0x922F, 0xE28B, 0x9230, 0xE28C, 0x9231,
+	0xE28D, 0x9232, 0xE28E, 0x9233, 0xE28F, 0x9234, 0xE290, 0x9235,
+	0xE291, 0x9236, 0xE292, 0x9237, 0xE293, 0x9238, 0xE294, 0x9239,
+	0xE295, 0x923A, 0xE296, 0x923B, 0xE297, 0x923C, 0xE298, 0x923D,
+	0xE299, 0x923E, 0xE29A, 0x923F, 0xE29B, 0x9240, 0xE29C, 0x9241,
+	0xE29D, 0x9242, 0xE29E, 0x9243, 0xE29F, 0x9244, 0xE2A0, 0x9245,
+	0xE2A1, 0x72FB, 0xE2A2, 0x7317, 0xE2A3, 0x7313, 0xE2A4, 0x7321,
+	0xE2A5, 0x730A, 0xE2A6, 0x731E, 0xE2A7, 0x731D, 0xE2A8, 0x7315,
+	0xE2A9, 0x7322, 0xE2AA, 0x7339, 0xE2AB, 0x7325, 0xE2AC, 0x732C,
+	0xE2AD, 0x7338, 0xE2AE, 0x7331, 0xE2AF, 0x7350, 0xE2B0, 0x734D,
+	0xE2B1, 0x7357, 0xE2B2, 0x7360, 0xE2B3, 0x736C, 0xE2B4, 0x736F,
+	0xE2B5, 0x737E, 0xE2B6, 0x821B, 0xE2B7, 0x5925, 0xE2B8, 0x98E7,
+	0xE2B9, 0x5924, 0xE2BA, 0x5902, 0xE2BB, 0x9963, 0xE2BC, 0x9967,
+	0xE2BD, 0x9968, 0xE2BE, 0x9969, 0xE2BF, 0x996A, 0xE2C0, 0x996B,
+	0xE2C1, 0x996C, 0xE2C2, 0x9974, 0xE2C3, 0x9977, 0xE2C4, 0x997D,
+	0xE2C5, 0x9980, 0xE2C6, 0x9984, 0xE2C7, 0x9987, 0xE2C8, 0x998A,
+	0xE2C9, 0x998D, 0xE2CA, 0x9990, 0xE2CB, 0x9991, 0xE2CC, 0x9993,
+	0xE2CD, 0x9994, 0xE2CE, 0x9995, 0xE2CF, 0x5E80, 0xE2D0, 0x5E91,
+	0xE2D1, 0x5E8B, 0xE2D2, 0x5E96, 0xE2D3, 0x5EA5, 0xE2D4, 0x5EA0,
+	0xE2D5, 0x5EB9, 0xE2D6, 0x5EB5, 0xE2D7, 0x5EBE, 0xE2D8, 0x5EB3,
+	0xE2D9, 0x8D53, 0xE2DA, 0x5ED2, 0xE2DB, 0x5ED1, 0xE2DC, 0x5EDB,
+	0xE2DD, 0x5EE8, 0xE2DE, 0x5EEA, 0xE2DF, 0x81BA, 0xE2E0, 0x5FC4,
+	0xE2E1, 0x5FC9, 0xE2E2, 0x5FD6, 0xE2E3, 0x5FCF, 0xE2E4, 0x6003,
+	0xE2E5, 0x5FEE, 0xE2E6, 0x6004, 0xE2E7, 0x5FE1, 0xE2E8, 0x5FE4,
+	0xE2E9, 0x5FFE, 0xE2EA, 0x6005, 0xE2EB, 0x6006, 0xE2EC, 0x5FEA,
+	0xE2ED, 0x5FED, 0xE2EE, 0x5FF8, 0xE2EF, 0x6019, 0xE2F0, 0x6035,
+	0xE2F1, 0x6026, 0xE2F2, 0x601B, 0xE2F3, 0x600F, 0xE2F4, 0x600D,
+	0xE2F5, 0x6029, 0xE2F6, 0x602B, 0xE2F7, 0x600A, 0xE2F8, 0x603F,
+	0xE2F9, 0x6021, 0xE2FA, 0x6078, 0xE2FB, 0x6079, 0xE2FC, 0x607B,
+	0xE2FD, 0x607A, 0xE2FE, 0x6042, 0xE340, 0x9246, 0xE341, 0x9247,
+	0xE342, 0x9248, 0xE343, 0x9249, 0xE344, 0x924A, 0xE345, 0x924B,
+	0xE346, 0x924C, 0xE347, 0x924D, 0xE348, 0x924E, 0xE349, 0x924F,
+	0xE34A, 0x9250, 0xE34B, 0x9251, 0xE34C, 0x9252, 0xE34D, 0x9253,
+	0xE34E, 0x9254, 0xE34F, 0x9255, 0xE350, 0x9256, 0xE351, 0x9257,
+	0xE352, 0x9258, 0xE353, 0x9259, 0xE354, 0x925A, 0xE355, 0x925B,
+	0xE356, 0x925C, 0xE357, 0x925D, 0xE358, 0x925E, 0xE359, 0x925F,
+	0xE35A, 0x9260, 0xE35B, 0x9261, 0xE35C, 0x9262, 0xE35D, 0x9263,
+	0xE35E, 0x9264, 0xE35F, 0x9265, 0xE360, 0x9266, 0xE361, 0x9267,
+	0xE362, 0x9268, 0xE363, 0x9269, 0xE364, 0x926A, 0xE365, 0x926B,
+	0xE366, 0x926C, 0xE367, 0x926D, 0xE368, 0x926E, 0xE369, 0x926F,
+	0xE36A, 0x9270, 0xE36B, 0x9271, 0xE36C, 0x9272, 0xE36D, 0x9273,
+	0xE36E, 0x9275, 0xE36F, 0x9276, 0xE370, 0x9277, 0xE371, 0x9278,
+	0xE372, 0x9279, 0xE373, 0x927A, 0xE374, 0x927B, 0xE375, 0x927C,
+	0xE376, 0x927D, 0xE377, 0x927E, 0xE378, 0x927F, 0xE379, 0x9280,
+	0xE37A, 0x9281, 0xE37B, 0x9282, 0xE37C, 0x9283, 0xE37D, 0x9284,
+	0xE37E, 0x9285, 0xE380, 0x9286, 0xE381, 0x9287, 0xE382, 0x9288,
+	0xE383, 0x9289, 0xE384, 0x928A, 0xE385, 0x928B, 0xE386, 0x928C,
+	0xE387, 0x928D, 0xE388, 0x928F, 0xE389, 0x9290, 0xE38A, 0x9291,
+	0xE38B, 0x9292, 0xE38C, 0x9293, 0xE38D, 0x9294, 0xE38E, 0x9295,
+	0xE38F, 0x9296, 0xE390, 0x9297, 0xE391, 0x9298, 0xE392, 0x9299,
+	0xE393, 0x929A, 0xE394, 0x929B, 0xE395, 0x929C, 0xE396, 0x929D,
+	0xE397, 0x929E, 0xE398, 0x929F, 0xE399, 0x92A0, 0xE39A, 0x92A1,
+	0xE39B, 0x92A2, 0xE39C, 0x92A3, 0xE39D, 0x92A4, 0xE39E, 0x92A5,
+	0xE39F, 0x92A6, 0xE3A0, 0x92A7, 0xE3A1, 0x606A, 0xE3A2, 0x607D,
+	0xE3A3, 0x6096, 0xE3A4, 0x609A, 0xE3A5, 0x60AD, 0xE3A6, 0x609D,
+	0xE3A7, 0x6083, 0xE3A8, 0x6092, 0xE3A9, 0x608C, 0xE3AA, 0x609B,
+	0xE3AB, 0x60EC, 0xE3AC, 0x60BB, 0xE3AD, 0x60B1, 0xE3AE, 0x60DD,
+	0xE3AF, 0x60D8, 0xE3B0, 0x60C6, 0xE3B1, 0x60DA, 0xE3B2, 0x60B4,
+	0xE3B3, 0x6120, 0xE3B4, 0x6126, 0xE3B5, 0x6115, 0xE3B6, 0x6123,
+	0xE3B7, 0x60F4, 0xE3B8, 0x6100, 0xE3B9, 0x610E, 0xE3BA, 0x612B,
+	0xE3BB, 0x614A, 0xE3BC, 0x6175, 0xE3BD, 0x61AC, 0xE3BE, 0x6194,
+	0xE3BF, 0x61A7, 0xE3C0, 0x61B7, 0xE3C1, 0x61D4, 0xE3C2, 0x61F5,
+	0xE3C3, 0x5FDD, 0xE3C4, 0x96B3, 0xE3C5, 0x95E9, 0xE3C6, 0x95EB,
+	0xE3C7, 0x95F1, 0xE3C8, 0x95F3, 0xE3C9, 0x95F5, 0xE3CA, 0x95F6,
+	0xE3CB, 0x95FC, 0xE3CC, 0x95FE, 0xE3CD, 0x9603, 0xE3CE, 0x9604,
+	0xE3CF, 0x9606, 0xE3D0, 0x9608, 0xE3D1, 0x960A, 0xE3D2, 0x960B,
+	0xE3D3, 0x960C, 0xE3D4, 0x960D, 0xE3D5, 0x960F, 0xE3D6, 0x9612,
+	0xE3D7, 0x9615, 0xE3D8, 0x9616, 0xE3D9, 0x9617, 0xE3DA, 0x9619,
+	0xE3DB, 0x961A, 0xE3DC, 0x4E2C, 0xE3DD, 0x723F, 0xE3DE, 0x6215,
+	0xE3DF, 0x6C35, 0xE3E0, 0x6C54, 0xE3E1, 0x6C5C, 0xE3E2, 0x6C4A,
+	0xE3E3, 0x6CA3, 0xE3E4, 0x6C85, 0xE3E5, 0x6C90, 0xE3E6, 0x6C94,
+	0xE3E7, 0x6C8C, 0xE3E8, 0x6C68, 0xE3E9, 0x6C69, 0xE3EA, 0x6C74,
+	0xE3EB, 0x6C76, 0xE3EC, 0x6C86, 0xE3ED, 0x6CA9, 0xE3EE, 0x6CD0,
+	0xE3EF, 0x6CD4, 0xE3F0, 0x6CAD, 0xE3F1, 0x6CF7, 0xE3F2, 0x6CF8,
+	0xE3F3, 0x6CF1, 0xE3F4, 0x6CD7, 0xE3F5, 0x6CB2, 0xE3F6, 0x6CE0,
+	0xE3F7, 0x6CD6, 0xE3F8, 0x6CFA, 0xE3F9, 0x6CEB, 0xE3FA, 0x6CEE,
+	0xE3FB, 0x6CB1, 0xE3FC, 0x6CD3, 0xE3FD, 0x6CEF, 0xE3FE, 0x6CFE,
+	0xE440, 0x92A8, 0xE441, 0x92A9, 0xE442, 0x92AA, 0xE443, 0x92AB,
+	0xE444, 0x92AC, 0xE445, 0x92AD, 0xE446, 0x92AF, 0xE447, 0x92B0,
+	0xE448, 0x92B1, 0xE449, 0x92B2, 0xE44A, 0x92B3, 0xE44B, 0x92B4,
+	0xE44C, 0x92B5, 0xE44D, 0x92B6, 0xE44E, 0x92B7, 0xE44F, 0x92B8,
+	0xE450, 0x92B9, 0xE451, 0x92BA, 0xE452, 0x92BB, 0xE453, 0x92BC,
+	0xE454, 0x92BD, 0xE455, 0x92BE, 0xE456, 0x92BF, 0xE457, 0x92C0,
+	0xE458, 0x92C1, 0xE459, 0x92C2, 0xE45A, 0x92C3, 0xE45B, 0x92C4,
+	0xE45C, 0x92C5, 0xE45D, 0x92C6, 0xE45E, 0x92C7, 0xE45F, 0x92C9,
+	0xE460, 0x92CA, 0xE461, 0x92CB, 0xE462, 0x92CC, 0xE463, 0x92CD,
+	0xE464, 0x92CE, 0xE465, 0x92CF, 0xE466, 0x92D0, 0xE467, 0x92D1,
+	0xE468, 0x92D2, 0xE469, 0x92D3, 0xE46A, 0x92D4, 0xE46B, 0x92D5,
+	0xE46C, 0x92D6, 0xE46D, 0x92D7, 0xE46E, 0x92D8, 0xE46F, 0x92D9,
+	0xE470, 0x92DA, 0xE471, 0x92DB, 0xE472, 0x92DC, 0xE473, 0x92DD,
+	0xE474, 0x92DE, 0xE475, 0x92DF, 0xE476, 0x92E0, 0xE477, 0x92E1,
+	0xE478, 0x92E2, 0xE479, 0x92E3, 0xE47A, 0x92E4, 0xE47B, 0x92E5,
+	0xE47C, 0x92E6, 0xE47D, 0x92E7, 0xE47E, 0x92E8, 0xE480, 0x92E9,
+	0xE481, 0x92EA, 0xE482, 0x92EB, 0xE483, 0x92EC, 0xE484, 0x92ED,
+	0xE485, 0x92EE, 0xE486, 0x92EF, 0xE487, 0x92F0, 0xE488, 0x92F1,
+	0xE489, 0x92F2, 0xE48A, 0x92F3, 0xE48B, 0x92F4, 0xE48C, 0x92F5,
+	0xE48D, 0x92F6, 0xE48E, 0x92F7, 0xE48F, 0x92F8, 0xE490, 0x92F9,
+	0xE491, 0x92FA, 0xE492, 0x92FB, 0xE493, 0x92FC, 0xE494, 0x92FD,
+	0xE495, 0x92FE, 0xE496, 0x92FF, 0xE497, 0x9300, 0xE498, 0x9301,
+	0xE499, 0x9302, 0xE49A, 0x9303, 0xE49B, 0x9304, 0xE49C, 0x9305,
+	0xE49D, 0x9306, 0xE49E, 0x9307, 0xE49F, 0x9308, 0xE4A0, 0x9309,
+	0xE4A1, 0x6D39, 0xE4A2, 0x6D27, 0xE4A3, 0x6D0C, 0xE4A4, 0x6D43,
+	0xE4A5, 0x6D48, 0xE4A6, 0x6D07, 0xE4A7, 0x6D04, 0xE4A8, 0x6D19,
+	0xE4A9, 0x6D0E, 0xE4AA, 0x6D2B, 0xE4AB, 0x6D4D, 0xE4AC, 0x6D2E,
+	0xE4AD, 0x6D35, 0xE4AE, 0x6D1A, 0xE4AF, 0x6D4F, 0xE4B0, 0x6D52,
+	0xE4B1, 0x6D54, 0xE4B2, 0x6D33, 0xE4B3, 0x6D91, 0xE4B4, 0x6D6F,
+	0xE4B5, 0x6D9E, 0xE4B6, 0x6DA0, 0xE4B7, 0x6D5E, 0xE4B8, 0x6D93,
+	0xE4B9, 0x6D94, 0xE4BA, 0x6D5C, 0xE4BB, 0x6D60, 0xE4BC, 0x6D7C,
+	0xE4BD, 0x6D63, 0xE4BE, 0x6E1A, 0xE4BF, 0x6DC7, 0xE4C0, 0x6DC5,
+	0xE4C1, 0x6DDE, 0xE4C2, 0x6E0E, 0xE4C3, 0x6DBF, 0xE4C4, 0x6DE0,
+	0xE4C5, 0x6E11, 0xE4C6, 0x6DE6, 0xE4C7, 0x6DDD, 0xE4C8, 0x6DD9,
+	0xE4C9, 0x6E16, 0xE4CA, 0x6DAB, 0xE4CB, 0x6E0C, 0xE4CC, 0x6DAE,
+	0xE4CD, 0x6E2B, 0xE4CE, 0x6E6E, 0xE4CF, 0x6E4E, 0xE4D0, 0x6E6B,
+	0xE4D1, 0x6EB2, 0xE4D2, 0x6E5F, 0xE4D3, 0x6E86, 0xE4D4, 0x6E53,
+	0xE4D5, 0x6E54, 0xE4D6, 0x6E32, 0xE4D7, 0x6E25, 0xE4D8, 0x6E44,
+	0xE4D9, 0x6EDF, 0xE4DA, 0x6EB1, 0xE4DB, 0x6E98, 0xE4DC, 0x6EE0,
+	0xE4DD, 0x6F2D, 0xE4DE, 0x6EE2, 0xE4DF, 0x6EA5, 0xE4E0, 0x6EA7,
+	0xE4E1, 0x6EBD, 0xE4E2, 0x6EBB, 0xE4E3, 0x6EB7, 0xE4E4, 0x6ED7,
+	0xE4E5, 0x6EB4, 0xE4E6, 0x6ECF, 0xE4E7, 0x6E8F, 0xE4E8, 0x6EC2,
+	0xE4E9, 0x6E9F, 0xE4EA, 0x6F62, 0xE4EB, 0x6F46, 0xE4EC, 0x6F47,
+	0xE4ED, 0x6F24, 0xE4EE, 0x6F15, 0xE4EF, 0x6EF9, 0xE4F0, 0x6F2F,
+	0xE4F1, 0x6F36, 0xE4F2, 0x6F4B, 0xE4F3, 0x6F74, 0xE4F4, 0x6F2A,
+	0xE4F5, 0x6F09, 0xE4F6, 0x6F29, 0xE4F7, 0x6F89, 0xE4F8, 0x6F8D,
+	0xE4F9, 0x6F8C, 0xE4FA, 0x6F78, 0xE4FB, 0x6F72, 0xE4FC, 0x6F7C,
+	0xE4FD, 0x6F7A, 0xE4FE, 0x6FD1, 0xE540, 0x930A, 0xE541, 0x930B,
+	0xE542, 0x930C, 0xE543, 0x930D, 0xE544, 0x930E, 0xE545, 0x930F,
+	0xE546, 0x9310, 0xE547, 0x9311, 0xE548, 0x9312, 0xE549, 0x9313,
+	0xE54A, 0x9314, 0xE54B, 0x9315, 0xE54C, 0x9316, 0xE54D, 0x9317,
+	0xE54E, 0x9318, 0xE54F, 0x9319, 0xE550, 0x931A, 0xE551, 0x931B,
+	0xE552, 0x931C, 0xE553, 0x931D, 0xE554, 0x931E, 0xE555, 0x931F,
+	0xE556, 0x9320, 0xE557, 0x9321, 0xE558, 0x9322, 0xE559, 0x9323,
+	0xE55A, 0x9324, 0xE55B, 0x9325, 0xE55C, 0x9326, 0xE55D, 0x9327,
+	0xE55E, 0x9328, 0xE55F, 0x9329, 0xE560, 0x932A, 0xE561, 0x932B,
+	0xE562, 0x932C, 0xE563, 0x932D, 0xE564, 0x932E, 0xE565, 0x932F,
+	0xE566, 0x9330, 0xE567, 0x9331, 0xE568, 0x9332, 0xE569, 0x9333,
+	0xE56A, 0x9334, 0xE56B, 0x9335, 0xE56C, 0x9336, 0xE56D, 0x9337,
+	0xE56E, 0x9338, 0xE56F, 0x9339, 0xE570, 0x933A, 0xE571, 0x933B,
+	0xE572, 0x933C, 0xE573, 0x933D, 0xE574, 0x933F, 0xE575, 0x9340,
+	0xE576, 0x9341, 0xE577, 0x9342, 0xE578, 0x9343, 0xE579, 0x9344,
+	0xE57A, 0x9345, 0xE57B, 0x9346, 0xE57C, 0x9347, 0xE57D, 0x9348,
+	0xE57E, 0x9349, 0xE580, 0x934A, 0xE581, 0x934B, 0xE582, 0x934C,
+	0xE583, 0x934D, 0xE584, 0x934E, 0xE585, 0x934F, 0xE586, 0x9350,
+	0xE587, 0x9351, 0xE588, 0x9352, 0xE589, 0x9353, 0xE58A, 0x9354,
+	0xE58B, 0x9355, 0xE58C, 0x9356, 0xE58D, 0x9357, 0xE58E, 0x9358,
+	0xE58F, 0x9359, 0xE590, 0x935A, 0xE591, 0x935B, 0xE592, 0x935C,
+	0xE593, 0x935D, 0xE594, 0x935E, 0xE595, 0x935F, 0xE596, 0x9360,
+	0xE597, 0x9361, 0xE598, 0x9362, 0xE599, 0x9363, 0xE59A, 0x9364,
+	0xE59B, 0x9365, 0xE59C, 0x9366, 0xE59D, 0x9367, 0xE59E, 0x9368,
+	0xE59F, 0x9369, 0xE5A0, 0x936B, 0xE5A1, 0x6FC9, 0xE5A2, 0x6FA7,
+	0xE5A3, 0x6FB9, 0xE5A4, 0x6FB6, 0xE5A5, 0x6FC2, 0xE5A6, 0x6FE1,
+	0xE5A7, 0x6FEE, 0xE5A8, 0x6FDE, 0xE5A9, 0x6FE0, 0xE5AA, 0x6FEF,
+	0xE5AB, 0x701A, 0xE5AC, 0x7023, 0xE5AD, 0x701B, 0xE5AE, 0x7039,
+	0xE5AF, 0x7035, 0xE5B0, 0x704F, 0xE5B1, 0x705E, 0xE5B2, 0x5B80,
+	0xE5B3, 0x5B84, 0xE5B4, 0x5B95, 0xE5B5, 0x5B93, 0xE5B6, 0x5BA5,
+	0xE5B7, 0x5BB8, 0xE5B8, 0x752F, 0xE5B9, 0x9A9E, 0xE5BA, 0x6434,
+	0xE5BB, 0x5BE4, 0xE5BC, 0x5BEE, 0xE5BD, 0x8930, 0xE5BE, 0x5BF0,
+	0xE5BF, 0x8E47, 0xE5C0, 0x8B07, 0xE5C1, 0x8FB6, 0xE5C2, 0x8FD3,
+	0xE5C3, 0x8FD5, 0xE5C4, 0x8FE5, 0xE5C5, 0x8FEE, 0xE5C6, 0x8FE4,
+	0xE5C7, 0x8FE9, 0xE5C8, 0x8FE6, 0xE5C9, 0x8FF3, 0xE5CA, 0x8FE8,
+	0xE5CB, 0x9005, 0xE5CC, 0x9004, 0xE5CD, 0x900B, 0xE5CE, 0x9026,
+	0xE5CF, 0x9011, 0xE5D0, 0x900D, 0xE5D1, 0x9016, 0xE5D2, 0x9021,
+	0xE5D3, 0x9035, 0xE5D4, 0x9036, 0xE5D5, 0x902D, 0xE5D6, 0x902F,
+	0xE5D7, 0x9044, 0xE5D8, 0x9051, 0xE5D9, 0x9052, 0xE5DA, 0x9050,
+	0xE5DB, 0x9068, 0xE5DC, 0x9058, 0xE5DD, 0x9062, 0xE5DE, 0x905B,
+	0xE5DF, 0x66B9, 0xE5E0, 0x9074, 0xE5E1, 0x907D, 0xE5E2, 0x9082,
+	0xE5E3, 0x9088, 0xE5E4, 0x9083, 0xE5E5, 0x908B, 0xE5E6, 0x5F50,
+	0xE5E7, 0x5F57, 0xE5E8, 0x5F56, 0xE5E9, 0x5F58, 0xE5EA, 0x5C3B,
+	0xE5EB, 0x54AB, 0xE5EC, 0x5C50, 0xE5ED, 0x5C59, 0xE5EE, 0x5B71,
+	0xE5EF, 0x5C63, 0xE5F0, 0x5C66, 0xE5F1, 0x7FBC, 0xE5F2, 0x5F2A,
+	0xE5F3, 0x5F29, 0xE5F4, 0x5F2D, 0xE5F5, 0x8274, 0xE5F6, 0x5F3C,
+	0xE5F7, 0x9B3B, 0xE5F8, 0x5C6E, 0xE5F9, 0x5981, 0xE5FA, 0x5983,
+	0xE5FB, 0x598D, 0xE5FC, 0x59A9, 0xE5FD, 0x59AA, 0xE5FE, 0x59A3,
+	0xE640, 0x936C, 0xE641, 0x936D, 0xE642, 0x936E, 0xE643, 0x936F,
+	0xE644, 0x9370, 0xE645, 0x9371, 0xE646, 0x9372, 0xE647, 0x9373,
+	0xE648, 0x9374, 0xE649, 0x9375, 0xE64A, 0x9376, 0xE64B, 0x9377,
+	0xE64C, 0x9378, 0xE64D, 0x9379, 0xE64E, 0x937A, 0xE64F, 0x937B,
+	0xE650, 0x937C, 0xE651, 0x937D, 0xE652, 0x937E, 0xE653, 0x937F,
+	0xE654, 0x9380, 0xE655, 0x9381, 0xE656, 0x9382, 0xE657, 0x9383,
+	0xE658, 0x9384, 0xE659, 0x9385, 0xE65A, 0x9386, 0xE65B, 0x9387,
+	0xE65C, 0x9388, 0xE65D, 0x9389, 0xE65E, 0x938A, 0xE65F, 0x938B,
+	0xE660, 0x938C, 0xE661, 0x938D, 0xE662, 0x938E, 0xE663, 0x9390,
+	0xE664, 0x9391, 0xE665, 0x9392, 0xE666, 0x9393, 0xE667, 0x9394,
+	0xE668, 0x9395, 0xE669, 0x9396, 0xE66A, 0x9397, 0xE66B, 0x9398,
+	0xE66C, 0x9399, 0xE66D, 0x939A, 0xE66E, 0x939B, 0xE66F, 0x939C,
+	0xE670, 0x939D, 0xE671, 0x939E, 0xE672, 0x939F, 0xE673, 0x93A0,
+	0xE674, 0x93A1, 0xE675, 0x93A2, 0xE676, 0x93A3, 0xE677, 0x93A4,
+	0xE678, 0x93A5, 0xE679, 0x93A6, 0xE67A, 0x93A7, 0xE67B, 0x93A8,
+	0xE67C, 0x93A9, 0xE67D, 0x93AA, 0xE67E, 0x93AB, 0xE680, 0x93AC,
+	0xE681, 0x93AD, 0xE682, 0x93AE, 0xE683, 0x93AF, 0xE684, 0x93B0,
+	0xE685, 0x93B1, 0xE686, 0x93B2, 0xE687, 0x93B3, 0xE688, 0x93B4,
+	0xE689, 0x93B5, 0xE68A, 0x93B6, 0xE68B, 0x93B7, 0xE68C, 0x93B8,
+	0xE68D, 0x93B9, 0xE68E, 0x93BA, 0xE68F, 0x93BB, 0xE690, 0x93BC,
+	0xE691, 0x93BD, 0xE692, 0x93BE, 0xE693, 0x93BF, 0xE694, 0x93C0,
+	0xE695, 0x93C1, 0xE696, 0x93C2, 0xE697, 0x93C3, 0xE698, 0x93C4,
+	0xE699, 0x93C5, 0xE69A, 0x93C6, 0xE69B, 0x93C7, 0xE69C, 0x93C8,
+	0xE69D, 0x93C9, 0xE69E, 0x93CB, 0xE69F, 0x93CC, 0xE6A0, 0x93CD,
+	0xE6A1, 0x5997, 0xE6A2, 0x59CA, 0xE6A3, 0x59AB, 0xE6A4, 0x599E,
+	0xE6A5, 0x59A4, 0xE6A6, 0x59D2, 0xE6A7, 0x59B2, 0xE6A8, 0x59AF,
+	0xE6A9, 0x59D7, 0xE6AA, 0x59BE, 0xE6AB, 0x5A05, 0xE6AC, 0x5A06,
+	0xE6AD, 0x59DD, 0xE6AE, 0x5A08, 0xE6AF, 0x59E3, 0xE6B0, 0x59D8,
+	0xE6B1, 0x59F9, 0xE6B2, 0x5A0C, 0xE6B3, 0x5A09, 0xE6B4, 0x5A32,
+	0xE6B5, 0x5A34, 0xE6B6, 0x5A11, 0xE6B7, 0x5A23, 0xE6B8, 0x5A13,
+	0xE6B9, 0x5A40, 0xE6BA, 0x5A67, 0xE6BB, 0x5A4A, 0xE6BC, 0x5A55,
+	0xE6BD, 0x5A3C, 0xE6BE, 0x5A62, 0xE6BF, 0x5A75, 0xE6C0, 0x80EC,
+	0xE6C1, 0x5AAA, 0xE6C2, 0x5A9B, 0xE6C3, 0x5A77, 0xE6C4, 0x5A7A,
+	0xE6C5, 0x5ABE, 0xE6C6, 0x5AEB, 0xE6C7, 0x5AB2, 0xE6C8, 0x5AD2,
+	0xE6C9, 0x5AD4, 0xE6CA, 0x5AB8, 0xE6CB, 0x5AE0, 0xE6CC, 0x5AE3,
+	0xE6CD, 0x5AF1, 0xE6CE, 0x5AD6, 0xE6CF, 0x5AE6, 0xE6D0, 0x5AD8,
+	0xE6D1, 0x5ADC, 0xE6D2, 0x5B09, 0xE6D3, 0x5B17, 0xE6D4, 0x5B16,
+	0xE6D5, 0x5B32, 0xE6D6, 0x5B37, 0xE6D7, 0x5B40, 0xE6D8, 0x5C15,
+	0xE6D9, 0x5C1C, 0xE6DA, 0x5B5A, 0xE6DB, 0x5B65, 0xE6DC, 0x5B73,
+	0xE6DD, 0x5B51, 0xE6DE, 0x5B53, 0xE6DF, 0x5B62, 0xE6E0, 0x9A75,
+	0xE6E1, 0x9A77, 0xE6E2, 0x9A78, 0xE6E3, 0x9A7A, 0xE6E4, 0x9A7F,
+	0xE6E5, 0x9A7D, 0xE6E6, 0x9A80, 0xE6E7, 0x9A81, 0xE6E8, 0x9A85,
+	0xE6E9, 0x9A88, 0xE6EA, 0x9A8A, 0xE6EB, 0x9A90, 0xE6EC, 0x9A92,
+	0xE6ED, 0x9A93, 0xE6EE, 0x9A96, 0xE6EF, 0x9A98, 0xE6F0, 0x9A9B,
+	0xE6F1, 0x9A9C, 0xE6F2, 0x9A9D, 0xE6F3, 0x9A9F, 0xE6F4, 0x9AA0,
+	0xE6F5, 0x9AA2, 0xE6F6, 0x9AA3, 0xE6F7, 0x9AA5, 0xE6F8, 0x9AA7,
+	0xE6F9, 0x7E9F, 0xE6FA, 0x7EA1, 0xE6FB, 0x7EA3, 0xE6FC, 0x7EA5,
+	0xE6FD, 0x7EA8, 0xE6FE, 0x7EA9, 0xE740, 0x93CE, 0xE741, 0x93CF,
+	0xE742, 0x93D0, 0xE743, 0x93D1, 0xE744, 0x93D2, 0xE745, 0x93D3,
+	0xE746, 0x93D4, 0xE747, 0x93D5, 0xE748, 0x93D7, 0xE749, 0x93D8,
+	0xE74A, 0x93D9, 0xE74B, 0x93DA, 0xE74C, 0x93DB, 0xE74D, 0x93DC,
+	0xE74E, 0x93DD, 0xE74F, 0x93DE, 0xE750, 0x93DF, 0xE751, 0x93E0,
+	0xE752, 0x93E1, 0xE753, 0x93E2, 0xE754, 0x93E3, 0xE755, 0x93E4,
+	0xE756, 0x93E5, 0xE757, 0x93E6, 0xE758, 0x93E7, 0xE759, 0x93E8,
+	0xE75A, 0x93E9, 0xE75B, 0x93EA, 0xE75C, 0x93EB, 0xE75D, 0x93EC,
+	0xE75E, 0x93ED, 0xE75F, 0x93EE, 0xE760, 0x93EF, 0xE761, 0x93F0,
+	0xE762, 0x93F1, 0xE763, 0x93F2, 0xE764, 0x93F3, 0xE765, 0x93F4,
+	0xE766, 0x93F5, 0xE767, 0x93F6, 0xE768, 0x93F7, 0xE769, 0x93F8,
+	0xE76A, 0x93F9, 0xE76B, 0x93FA, 0xE76C, 0x93FB, 0xE76D, 0x93FC,
+	0xE76E, 0x93FD, 0xE76F, 0x93FE, 0xE770, 0x93FF, 0xE771, 0x9400,
+	0xE772, 0x9401, 0xE773, 0x9402, 0xE774, 0x9403, 0xE775, 0x9404,
+	0xE776, 0x9405, 0xE777, 0x9406, 0xE778, 0x9407, 0xE779, 0x9408,
+	0xE77A, 0x9409, 0xE77B, 0x940A, 0xE77C, 0x940B, 0xE77D, 0x940C,
+	0xE77E, 0x940D, 0xE780, 0x940E, 0xE781, 0x940F, 0xE782, 0x9410,
+	0xE783, 0x9411, 0xE784, 0x9412, 0xE785, 0x9413, 0xE786, 0x9414,
+	0xE787, 0x9415, 0xE788, 0x9416, 0xE789, 0x9417, 0xE78A, 0x9418,
+	0xE78B, 0x9419, 0xE78C, 0x941A, 0xE78D, 0x941B, 0xE78E, 0x941C,
+	0xE78F, 0x941D, 0xE790, 0x941E, 0xE791, 0x941F, 0xE792, 0x9420,
+	0xE793, 0x9421, 0xE794, 0x9422, 0xE795, 0x9423, 0xE796, 0x9424,
+	0xE797, 0x9425, 0xE798, 0x9426, 0xE799, 0x9427, 0xE79A, 0x9428,
+	0xE79B, 0x9429, 0xE79C, 0x942A, 0xE79D, 0x942B, 0xE79E, 0x942C,
+	0xE79F, 0x942D, 0xE7A0, 0x942E, 0xE7A1, 0x7EAD, 0xE7A2, 0x7EB0,
+	0xE7A3, 0x7EBE, 0xE7A4, 0x7EC0, 0xE7A5, 0x7EC1, 0xE7A6, 0x7EC2,
+	0xE7A7, 0x7EC9, 0xE7A8, 0x7ECB, 0xE7A9, 0x7ECC, 0xE7AA, 0x7ED0,
+	0xE7AB, 0x7ED4, 0xE7AC, 0x7ED7, 0xE7AD, 0x7EDB, 0xE7AE, 0x7EE0,
+	0xE7AF, 0x7EE1, 0xE7B0, 0x7EE8, 0xE7B1, 0x7EEB, 0xE7B2, 0x7EEE,
+	0xE7B3, 0x7EEF, 0xE7B4, 0x7EF1, 0xE7B5, 0x7EF2, 0xE7B6, 0x7F0D,
+	0xE7B7, 0x7EF6, 0xE7B8, 0x7EFA, 0xE7B9, 0x7EFB, 0xE7BA, 0x7EFE,
+	0xE7BB, 0x7F01, 0xE7BC, 0x7F02, 0xE7BD, 0x7F03, 0xE7BE, 0x7F07,
+	0xE7BF, 0x7F08, 0xE7C0, 0x7F0B, 0xE7C1, 0x7F0C, 0xE7C2, 0x7F0F,
+	0xE7C3, 0x7F11, 0xE7C4, 0x7F12, 0xE7C5, 0x7F17, 0xE7C6, 0x7F19,
+	0xE7C7, 0x7F1C, 0xE7C8, 0x7F1B, 0xE7C9, 0x7F1F, 0xE7CA, 0x7F21,
+	0xE7CB, 0x7F22, 0xE7CC, 0x7F23, 0xE7CD, 0x7F24, 0xE7CE, 0x7F25,
+	0xE7CF, 0x7F26, 0xE7D0, 0x7F27, 0xE7D1, 0x7F2A, 0xE7D2, 0x7F2B,
+	0xE7D3, 0x7F2C, 0xE7D4, 0x7F2D, 0xE7D5, 0x7F2F, 0xE7D6, 0x7F30,
+	0xE7D7, 0x7F31, 0xE7D8, 0x7F32, 0xE7D9, 0x7F33, 0xE7DA, 0x7F35,
+	0xE7DB, 0x5E7A, 0xE7DC, 0x757F, 0xE7DD, 0x5DDB, 0xE7DE, 0x753E,
+	0xE7DF, 0x9095, 0xE7E0, 0x738E, 0xE7E1, 0x7391, 0xE7E2, 0x73AE,
+	0xE7E3, 0x73A2, 0xE7E4, 0x739F, 0xE7E5, 0x73CF, 0xE7E6, 0x73C2,
+	0xE7E7, 0x73D1, 0xE7E8, 0x73B7, 0xE7E9, 0x73B3, 0xE7EA, 0x73C0,
+	0xE7EB, 0x73C9, 0xE7EC, 0x73C8, 0xE7ED, 0x73E5, 0xE7EE, 0x73D9,
+	0xE7EF, 0x987C, 0xE7F0, 0x740A, 0xE7F1, 0x73E9, 0xE7F2, 0x73E7,
+	0xE7F3, 0x73DE, 0xE7F4, 0x73BA, 0xE7F5, 0x73F2, 0xE7F6, 0x740F,
+	0xE7F7, 0x742A, 0xE7F8, 0x745B, 0xE7F9, 0x7426, 0xE7FA, 0x7425,
+	0xE7FB, 0x7428, 0xE7FC, 0x7430, 0xE7FD, 0x742E, 0xE7FE, 0x742C,
+	0xE840, 0x942F, 0xE841, 0x9430, 0xE842, 0x9431, 0xE843, 0x9432,
+	0xE844, 0x9433, 0xE845, 0x9434, 0xE846, 0x9435, 0xE847, 0x9436,
+	0xE848, 0x9437, 0xE849, 0x9438, 0xE84A, 0x9439, 0xE84B, 0x943A,
+	0xE84C, 0x943B, 0xE84D, 0x943C, 0xE84E, 0x943D, 0xE84F, 0x943F,
+	0xE850, 0x9440, 0xE851, 0x9441, 0xE852, 0x9442, 0xE853, 0x9443,
+	0xE854, 0x9444, 0xE855, 0x9445, 0xE856, 0x9446, 0xE857, 0x9447,
+	0xE858, 0x9448, 0xE859, 0x9449, 0xE85A, 0x944A, 0xE85B, 0x944B,
+	0xE85C, 0x944C, 0xE85D, 0x944D, 0xE85E, 0x944E, 0xE85F, 0x944F,
+	0xE860, 0x9450, 0xE861, 0x9451, 0xE862, 0x9452, 0xE863, 0x9453,
+	0xE864, 0x9454, 0xE865, 0x9455, 0xE866, 0x9456, 0xE867, 0x9457,
+	0xE868, 0x9458, 0xE869, 0x9459, 0xE86A, 0x945A, 0xE86B, 0x945B,
+	0xE86C, 0x945C, 0xE86D, 0x945D, 0xE86E, 0x945E, 0xE86F, 0x945F,
+	0xE870, 0x9460, 0xE871, 0x9461, 0xE872, 0x9462, 0xE873, 0x9463,
+	0xE874, 0x9464, 0xE875, 0x9465, 0xE876, 0x9466, 0xE877, 0x9467,
+	0xE878, 0x9468, 0xE879, 0x9469, 0xE87A, 0x946A, 0xE87B, 0x946C,
+	0xE87C, 0x946D, 0xE87D, 0x946E, 0xE87E, 0x946F, 0xE880, 0x9470,
+	0xE881, 0x9471, 0xE882, 0x9472, 0xE883, 0x9473, 0xE884, 0x9474,
+	0xE885, 0x9475, 0xE886, 0x9476, 0xE887, 0x9477, 0xE888, 0x9478,
+	0xE889, 0x9479, 0xE88A, 0x947A, 0xE88B, 0x947B, 0xE88C, 0x947C,
+	0xE88D, 0x947D, 0xE88E, 0x947E, 0xE88F, 0x947F, 0xE890, 0x9480,
+	0xE891, 0x9481, 0xE892, 0x9482, 0xE893, 0x9483, 0xE894, 0x9484,
+	0xE895, 0x9491, 0xE896, 0x9496, 0xE897, 0x9498, 0xE898, 0x94C7,
+	0xE899, 0x94CF, 0xE89A, 0x94D3, 0xE89B, 0x94D4, 0xE89C, 0x94DA,
+	0xE89D, 0x94E6, 0xE89E, 0x94FB, 0xE89F, 0x951C, 0xE8A0, 0x9520,
+	0xE8A1, 0x741B, 0xE8A2, 0x741A, 0xE8A3, 0x7441, 0xE8A4, 0x745C,
+	0xE8A5, 0x7457, 0xE8A6, 0x7455, 0xE8A7, 0x7459, 0xE8A8, 0x7477,
+	0xE8A9, 0x746D, 0xE8AA, 0x747E, 0xE8AB, 0x749C, 0xE8AC, 0x748E,
+	0xE8AD, 0x7480, 0xE8AE, 0x7481, 0xE8AF, 0x7487, 0xE8B0, 0x748B,
+	0xE8B1, 0x749E, 0xE8B2, 0x74A8, 0xE8B3, 0x74A9, 0xE8B4, 0x7490,
+	0xE8B5, 0x74A7, 0xE8B6, 0x74D2, 0xE8B7, 0x74BA, 0xE8B8, 0x97EA,
+	0xE8B9, 0x97EB, 0xE8BA, 0x97EC, 0xE8BB, 0x674C, 0xE8BC, 0x6753,
+	0xE8BD, 0x675E, 0xE8BE, 0x6748, 0xE8BF, 0x6769, 0xE8C0, 0x67A5,
+	0xE8C1, 0x6787, 0xE8C2, 0x676A, 0xE8C3, 0x6773, 0xE8C4, 0x6798,
+	0xE8C5, 0x67A7, 0xE8C6, 0x6775, 0xE8C7, 0x67A8, 0xE8C8, 0x679E,
+	0xE8C9, 0x67AD, 0xE8CA, 0x678B, 0xE8CB, 0x6777, 0xE8CC, 0x677C,
+	0xE8CD, 0x67F0, 0xE8CE, 0x6809, 0xE8CF, 0x67D8, 0xE8D0, 0x680A,
+	0xE8D1, 0x67E9, 0xE8D2, 0x67B0, 0xE8D3, 0x680C, 0xE8D4, 0x67D9,
+	0xE8D5, 0x67B5, 0xE8D6, 0x67DA, 0xE8D7, 0x67B3, 0xE8D8, 0x67DD,
+	0xE8D9, 0x6800, 0xE8DA, 0x67C3, 0xE8DB, 0x67B8, 0xE8DC, 0x67E2,
+	0xE8DD, 0x680E, 0xE8DE, 0x67C1, 0xE8DF, 0x67FD, 0xE8E0, 0x6832,
+	0xE8E1, 0x6833, 0xE8E2, 0x6860, 0xE8E3, 0x6861, 0xE8E4, 0x684E,
+	0xE8E5, 0x6862, 0xE8E6, 0x6844, 0xE8E7, 0x6864, 0xE8E8, 0x6883,
+	0xE8E9, 0x681D, 0xE8EA, 0x6855, 0xE8EB, 0x6866, 0xE8EC, 0x6841,
+	0xE8ED, 0x6867, 0xE8EE, 0x6840, 0xE8EF, 0x683E, 0xE8F0, 0x684A,
+	0xE8F1, 0x6849, 0xE8F2, 0x6829, 0xE8F3, 0x68B5, 0xE8F4, 0x688F,
+	0xE8F5, 0x6874, 0xE8F6, 0x6877, 0xE8F7, 0x6893, 0xE8F8, 0x686B,
+	0xE8F9, 0x68C2, 0xE8FA, 0x696E, 0xE8FB, 0x68FC, 0xE8FC, 0x691F,
+	0xE8FD, 0x6920, 0xE8FE, 0x68F9, 0xE940, 0x9527, 0xE941, 0x9533,
+	0xE942, 0x953D, 0xE943, 0x9543, 0xE944, 0x9548, 0xE945, 0x954B,
+	0xE946, 0x9555, 0xE947, 0x955A, 0xE948, 0x9560, 0xE949, 0x956E,
+	0xE94A, 0x9574, 0xE94B, 0x9575, 0xE94C, 0x9577, 0xE94D, 0x9578,
+	0xE94E, 0x9579, 0xE94F, 0x957A, 0xE950, 0x957B, 0xE951, 0x957C,
+	0xE952, 0x957D, 0xE953, 0x957E, 0xE954, 0x9580, 0xE955, 0x9581,
+	0xE956, 0x9582, 0xE957, 0x9583, 0xE958, 0x9584, 0xE959, 0x9585,
+	0xE95A, 0x9586, 0xE95B, 0x9587, 0xE95C, 0x9588, 0xE95D, 0x9589,
+	0xE95E, 0x958A, 0xE95F, 0x958B, 0xE960, 0x958C, 0xE961, 0x958D,
+	0xE962, 0x958E, 0xE963, 0x958F, 0xE964, 0x9590, 0xE965, 0x9591,
+	0xE966, 0x9592, 0xE967, 0x9593, 0xE968, 0x9594, 0xE969, 0x9595,
+	0xE96A, 0x9596, 0xE96B, 0x9597, 0xE96C, 0x9598, 0xE96D, 0x9599,
+	0xE96E, 0x959A, 0xE96F, 0x959B, 0xE970, 0x959C, 0xE971, 0x959D,
+	0xE972, 0x959E, 0xE973, 0x959F, 0xE974, 0x95A0, 0xE975, 0x95A1,
+	0xE976, 0x95A2, 0xE977, 0x95A3, 0xE978, 0x95A4, 0xE979, 0x95A5,
+	0xE97A, 0x95A6, 0xE97B, 0x95A7, 0xE97C, 0x95A8, 0xE97D, 0x95A9,
+	0xE97E, 0x95AA, 0xE980, 0x95AB, 0xE981, 0x95AC, 0xE982, 0x95AD,
+	0xE983, 0x95AE, 0xE984, 0x95AF, 0xE985, 0x95B0, 0xE986, 0x95B1,
+	0xE987, 0x95B2, 0xE988, 0x95B3, 0xE989, 0x95B4, 0xE98A, 0x95B5,
+	0xE98B, 0x95B6, 0xE98C, 0x95B7, 0xE98D, 0x95B8, 0xE98E, 0x95B9,
+	0xE98F, 0x95BA, 0xE990, 0x95BB, 0xE991, 0x95BC, 0xE992, 0x95BD,
+	0xE993, 0x95BE, 0xE994, 0x95BF, 0xE995, 0x95C0, 0xE996, 0x95C1,
+	0xE997, 0x95C2, 0xE998, 0x95C3, 0xE999, 0x95C4, 0xE99A, 0x95C5,
+	0xE99B, 0x95C6, 0xE99C, 0x95C7, 0xE99D, 0x95C8, 0xE99E, 0x95C9,
+	0xE99F, 0x95CA, 0xE9A0, 0x95CB, 0xE9A1, 0x6924, 0xE9A2, 0x68F0,
+	0xE9A3, 0x690B, 0xE9A4, 0x6901, 0xE9A5, 0x6957, 0xE9A6, 0x68E3,
+	0xE9A7, 0x6910, 0xE9A8, 0x6971, 0xE9A9, 0x6939, 0xE9AA, 0x6960,
+	0xE9AB, 0x6942, 0xE9AC, 0x695D, 0xE9AD, 0x6984, 0xE9AE, 0x696B,
+	0xE9AF, 0x6980, 0xE9B0, 0x6998, 0xE9B1, 0x6978, 0xE9B2, 0x6934,
+	0xE9B3, 0x69CC, 0xE9B4, 0x6987, 0xE9B5, 0x6988, 0xE9B6, 0x69CE,
+	0xE9B7, 0x6989, 0xE9B8, 0x6966, 0xE9B9, 0x6963, 0xE9BA, 0x6979,
+	0xE9BB, 0x699B, 0xE9BC, 0x69A7, 0xE9BD, 0x69BB, 0xE9BE, 0x69AB,
+	0xE9BF, 0x69AD, 0xE9C0, 0x69D4, 0xE9C1, 0x69B1, 0xE9C2, 0x69C1,
+	0xE9C3, 0x69CA, 0xE9C4, 0x69DF, 0xE9C5, 0x6995, 0xE9C6, 0x69E0,
+	0xE9C7, 0x698D, 0xE9C8, 0x69FF, 0xE9C9, 0x6A2F, 0xE9CA, 0x69ED,
+	0xE9CB, 0x6A17, 0xE9CC, 0x6A18, 0xE9CD, 0x6A65, 0xE9CE, 0x69F2,
+	0xE9CF, 0x6A44, 0xE9D0, 0x6A3E, 0xE9D1, 0x6AA0, 0xE9D2, 0x6A50,
+	0xE9D3, 0x6A5B, 0xE9D4, 0x6A35, 0xE9D5, 0x6A8E, 0xE9D6, 0x6A79,
+	0xE9D7, 0x6A3D, 0xE9D8, 0x6A28, 0xE9D9, 0x6A58, 0xE9DA, 0x6A7C,
+	0xE9DB, 0x6A91, 0xE9DC, 0x6A90, 0xE9DD, 0x6AA9, 0xE9DE, 0x6A97,
+	0xE9DF, 0x6AAB, 0xE9E0, 0x7337, 0xE9E1, 0x7352, 0xE9E2, 0x6B81,
+	0xE9E3, 0x6B82, 0xE9E4, 0x6B87, 0xE9E5, 0x6B84, 0xE9E6, 0x6B92,
+	0xE9E7, 0x6B93, 0xE9E8, 0x6B8D, 0xE9E9, 0x6B9A, 0xE9EA, 0x6B9B,
+	0xE9EB, 0x6BA1, 0xE9EC, 0x6BAA, 0xE9ED, 0x8F6B, 0xE9EE, 0x8F6D,
+	0xE9EF, 0x8F71, 0xE9F0, 0x8F72, 0xE9F1, 0x8F73, 0xE9F2, 0x8F75,
+	0xE9F3, 0x8F76, 0xE9F4, 0x8F78, 0xE9F5, 0x8F77, 0xE9F6, 0x8F79,
+	0xE9F7, 0x8F7A, 0xE9F8, 0x8F7C, 0xE9F9, 0x8F7E, 0xE9FA, 0x8F81,
+	0xE9FB, 0x8F82, 0xE9FC, 0x8F84, 0xE9FD, 0x8F87, 0xE9FE, 0x8F8B,
+	0xEA40, 0x95CC, 0xEA41, 0x95CD, 0xEA42, 0x95CE, 0xEA43, 0x95CF,
+	0xEA44, 0x95D0, 0xEA45, 0x95D1, 0xEA46, 0x95D2, 0xEA47, 0x95D3,
+	0xEA48, 0x95D4, 0xEA49, 0x95D5, 0xEA4A, 0x95D6, 0xEA4B, 0x95D7,
+	0xEA4C, 0x95D8, 0xEA4D, 0x95D9, 0xEA4E, 0x95DA, 0xEA4F, 0x95DB,
+	0xEA50, 0x95DC, 0xEA51, 0x95DD, 0xEA52, 0x95DE, 0xEA53, 0x95DF,
+	0xEA54, 0x95E0, 0xEA55, 0x95E1, 0xEA56, 0x95E2, 0xEA57, 0x95E3,
+	0xEA58, 0x95E4, 0xEA59, 0x95E5, 0xEA5A, 0x95E6, 0xEA5B, 0x95E7,
+	0xEA5C, 0x95EC, 0xEA5D, 0x95FF, 0xEA5E, 0x9607, 0xEA5F, 0x9613,
+	0xEA60, 0x9618, 0xEA61, 0x961B, 0xEA62, 0x961E, 0xEA63, 0x9620,
+	0xEA64, 0x9623, 0xEA65, 0x9624, 0xEA66, 0x9625, 0xEA67, 0x9626,
+	0xEA68, 0x9627, 0xEA69, 0x9628, 0xEA6A, 0x9629, 0xEA6B, 0x962B,
+	0xEA6C, 0x962C, 0xEA6D, 0x962D, 0xEA6E, 0x962F, 0xEA6F, 0x9630,
+	0xEA70, 0x9637, 0xEA71, 0x9638, 0xEA72, 0x9639, 0xEA73, 0x963A,
+	0xEA74, 0x963E, 0xEA75, 0x9641, 0xEA76, 0x9643, 0xEA77, 0x964A,
+	0xEA78, 0x964E, 0xEA79, 0x964F, 0xEA7A, 0x9651, 0xEA7B, 0x9652,
+	0xEA7C, 0x9653, 0xEA7D, 0x9656, 0xEA7E, 0x9657, 0xEA80, 0x9658,
+	0xEA81, 0x9659, 0xEA82, 0x965A, 0xEA83, 0x965C, 0xEA84, 0x965D,
+	0xEA85, 0x965E, 0xEA86, 0x9660, 0xEA87, 0x9663, 0xEA88, 0x9665,
+	0xEA89, 0x9666, 0xEA8A, 0x966B, 0xEA8B, 0x966D, 0xEA8C, 0x966E,
+	0xEA8D, 0x966F, 0xEA8E, 0x9670, 0xEA8F, 0x9671, 0xEA90, 0x9673,
+	0xEA91, 0x9678, 0xEA92, 0x9679, 0xEA93, 0x967A, 0xEA94, 0x967B,
+	0xEA95, 0x967C, 0xEA96, 0x967D, 0xEA97, 0x967E, 0xEA98, 0x967F,
+	0xEA99, 0x9680, 0xEA9A, 0x9681, 0xEA9B, 0x9682, 0xEA9C, 0x9683,
+	0xEA9D, 0x9684, 0xEA9E, 0x9687, 0xEA9F, 0x9689, 0xEAA0, 0x968A,
+	0xEAA1, 0x8F8D, 0xEAA2, 0x8F8E, 0xEAA3, 0x8F8F, 0xEAA4, 0x8F98,
+	0xEAA5, 0x8F9A, 0xEAA6, 0x8ECE, 0xEAA7, 0x620B, 0xEAA8, 0x6217,
+	0xEAA9, 0x621B, 0xEAAA, 0x621F, 0xEAAB, 0x6222, 0xEAAC, 0x6221,
+	0xEAAD, 0x6225, 0xEAAE, 0x6224, 0xEAAF, 0x622C, 0xEAB0, 0x81E7,
+	0xEAB1, 0x74EF, 0xEAB2, 0x74F4, 0xEAB3, 0x74FF, 0xEAB4, 0x750F,
+	0xEAB5, 0x7511, 0xEAB6, 0x7513, 0xEAB7, 0x6534, 0xEAB8, 0x65EE,
+	0xEAB9, 0x65EF, 0xEABA, 0x65F0, 0xEABB, 0x660A, 0xEABC, 0x6619,
+	0xEABD, 0x6772, 0xEABE, 0x6603, 0xEABF, 0x6615, 0xEAC0, 0x6600,
+	0xEAC1, 0x7085, 0xEAC2, 0x66F7, 0xEAC3, 0x661D, 0xEAC4, 0x6634,
+	0xEAC5, 0x6631, 0xEAC6, 0x6636, 0xEAC7, 0x6635, 0xEAC8, 0x8006,
+	0xEAC9, 0x665F, 0xEACA, 0x6654, 0xEACB, 0x6641, 0xEACC, 0x664F,
+	0xEACD, 0x6656, 0xEACE, 0x6661, 0xEACF, 0x6657, 0xEAD0, 0x6677,
+	0xEAD1, 0x6684, 0xEAD2, 0x668C, 0xEAD3, 0x66A7, 0xEAD4, 0x669D,
+	0xEAD5, 0x66BE, 0xEAD6, 0x66DB, 0xEAD7, 0x66DC, 0xEAD8, 0x66E6,
+	0xEAD9, 0x66E9, 0xEADA, 0x8D32, 0xEADB, 0x8D33, 0xEADC, 0x8D36,
+	0xEADD, 0x8D3B, 0xEADE, 0x8D3D, 0xEADF, 0x8D40, 0xEAE0, 0x8D45,
+	0xEAE1, 0x8D46, 0xEAE2, 0x8D48, 0xEAE3, 0x8D49, 0xEAE4, 0x8D47,
+	0xEAE5, 0x8D4D, 0xEAE6, 0x8D55, 0xEAE7, 0x8D59, 0xEAE8, 0x89C7,
+	0xEAE9, 0x89CA, 0xEAEA, 0x89CB, 0xEAEB, 0x89CC, 0xEAEC, 0x89CE,
+	0xEAED, 0x89CF, 0xEAEE, 0x89D0, 0xEAEF, 0x89D1, 0xEAF0, 0x726E,
+	0xEAF1, 0x729F, 0xEAF2, 0x725D, 0xEAF3, 0x7266, 0xEAF4, 0x726F,
+	0xEAF5, 0x727E, 0xEAF6, 0x727F, 0xEAF7, 0x7284, 0xEAF8, 0x728B,
+	0xEAF9, 0x728D, 0xEAFA, 0x728F, 0xEAFB, 0x7292, 0xEAFC, 0x6308,
+	0xEAFD, 0x6332, 0xEAFE, 0x63B0, 0xEB40, 0x968C, 0xEB41, 0x968E,
+	0xEB42, 0x9691, 0xEB43, 0x9692, 0xEB44, 0x9693, 0xEB45, 0x9695,
+	0xEB46, 0x9696, 0xEB47, 0x969A, 0xEB48, 0x969B, 0xEB49, 0x969D,
+	0xEB4A, 0x969E, 0xEB4B, 0x969F, 0xEB4C, 0x96A0, 0xEB4D, 0x96A1,
+	0xEB4E, 0x96A2, 0xEB4F, 0x96A3, 0xEB50, 0x96A4, 0xEB51, 0x96A5,
+	0xEB52, 0x96A6, 0xEB53, 0x96A8, 0xEB54, 0x96A9, 0xEB55, 0x96AA,
+	0xEB56, 0x96AB, 0xEB57, 0x96AC, 0xEB58, 0x96AD, 0xEB59, 0x96AE,
+	0xEB5A, 0x96AF, 0xEB5B, 0x96B1, 0xEB5C, 0x96B2, 0xEB5D, 0x96B4,
+	0xEB5E, 0x96B5, 0xEB5F, 0x96B7, 0xEB60, 0x96B8, 0xEB61, 0x96BA,
+	0xEB62, 0x96BB, 0xEB63, 0x96BF, 0xEB64, 0x96C2, 0xEB65, 0x96C3,
+	0xEB66, 0x96C8, 0xEB67, 0x96CA, 0xEB68, 0x96CB, 0xEB69, 0x96D0,
+	0xEB6A, 0x96D1, 0xEB6B, 0x96D3, 0xEB6C, 0x96D4, 0xEB6D, 0x96D6,
+	0xEB6E, 0x96D7, 0xEB6F, 0x96D8, 0xEB70, 0x96D9, 0xEB71, 0x96DA,
+	0xEB72, 0x96DB, 0xEB73, 0x96DC, 0xEB74, 0x96DD, 0xEB75, 0x96DE,
+	0xEB76, 0x96DF, 0xEB77, 0x96E1, 0xEB78, 0x96E2, 0xEB79, 0x96E3,
+	0xEB7A, 0x96E4, 0xEB7B, 0x96E5, 0xEB7C, 0x96E6, 0xEB7D, 0x96E7,
+	0xEB7E, 0x96EB, 0xEB80, 0x96EC, 0xEB81, 0x96ED, 0xEB82, 0x96EE,
+	0xEB83, 0x96F0, 0xEB84, 0x96F1, 0xEB85, 0x96F2, 0xEB86, 0x96F4,
+	0xEB87, 0x96F5, 0xEB88, 0x96F8, 0xEB89, 0x96FA, 0xEB8A, 0x96FB,
+	0xEB8B, 0x96FC, 0xEB8C, 0x96FD, 0xEB8D, 0x96FF, 0xEB8E, 0x9702,
+	0xEB8F, 0x9703, 0xEB90, 0x9705, 0xEB91, 0x970A, 0xEB92, 0x970B,
+	0xEB93, 0x970C, 0xEB94, 0x9710, 0xEB95, 0x9711, 0xEB96, 0x9712,
+	0xEB97, 0x9714, 0xEB98, 0x9715, 0xEB99, 0x9717, 0xEB9A, 0x9718,
+	0xEB9B, 0x9719, 0xEB9C, 0x971A, 0xEB9D, 0x971B, 0xEB9E, 0x971D,
+	0xEB9F, 0x971F, 0xEBA0, 0x9720, 0xEBA1, 0x643F, 0xEBA2, 0x64D8,
+	0xEBA3, 0x8004, 0xEBA4, 0x6BEA, 0xEBA5, 0x6BF3, 0xEBA6, 0x6BFD,
+	0xEBA7, 0x6BF5, 0xEBA8, 0x6BF9, 0xEBA9, 0x6C05, 0xEBAA, 0x6C07,
+	0xEBAB, 0x6C06, 0xEBAC, 0x6C0D, 0xEBAD, 0x6C15, 0xEBAE, 0x6C18,
+	0xEBAF, 0x6C19, 0xEBB0, 0x6C1A, 0xEBB1, 0x6C21, 0xEBB2, 0x6C29,
+	0xEBB3, 0x6C24, 0xEBB4, 0x6C2A, 0xEBB5, 0x6C32, 0xEBB6, 0x6535,
+	0xEBB7, 0x6555, 0xEBB8, 0x656B, 0xEBB9, 0x724D, 0xEBBA, 0x7252,
+	0xEBBB, 0x7256, 0xEBBC, 0x7230, 0xEBBD, 0x8662, 0xEBBE, 0x5216,
+	0xEBBF, 0x809F, 0xEBC0, 0x809C, 0xEBC1, 0x8093, 0xEBC2, 0x80BC,
+	0xEBC3, 0x670A, 0xEBC4, 0x80BD, 0xEBC5, 0x80B1, 0xEBC6, 0x80AB,
+	0xEBC7, 0x80AD, 0xEBC8, 0x80B4, 0xEBC9, 0x80B7, 0xEBCA, 0x80E7,
+	0xEBCB, 0x80E8, 0xEBCC, 0x80E9, 0xEBCD, 0x80EA, 0xEBCE, 0x80DB,
+	0xEBCF, 0x80C2, 0xEBD0, 0x80C4, 0xEBD1, 0x80D9, 0xEBD2, 0x80CD,
+	0xEBD3, 0x80D7, 0xEBD4, 0x6710, 0xEBD5, 0x80DD, 0xEBD6, 0x80EB,
+	0xEBD7, 0x80F1, 0xEBD8, 0x80F4, 0xEBD9, 0x80ED, 0xEBDA, 0x810D,
+	0xEBDB, 0x810E, 0xEBDC, 0x80F2, 0xEBDD, 0x80FC, 0xEBDE, 0x6715,
+	0xEBDF, 0x8112, 0xEBE0, 0x8C5A, 0xEBE1, 0x8136, 0xEBE2, 0x811E,
+	0xEBE3, 0x812C, 0xEBE4, 0x8118, 0xEBE5, 0x8132, 0xEBE6, 0x8148,
+	0xEBE7, 0x814C, 0xEBE8, 0x8153, 0xEBE9, 0x8174, 0xEBEA, 0x8159,
+	0xEBEB, 0x815A, 0xEBEC, 0x8171, 0xEBED, 0x8160, 0xEBEE, 0x8169,
+	0xEBEF, 0x817C, 0xEBF0, 0x817D, 0xEBF1, 0x816D, 0xEBF2, 0x8167,
+	0xEBF3, 0x584D, 0xEBF4, 0x5AB5, 0xEBF5, 0x8188, 0xEBF6, 0x8182,
+	0xEBF7, 0x8191, 0xEBF8, 0x6ED5, 0xEBF9, 0x81A3, 0xEBFA, 0x81AA,
+	0xEBFB, 0x81CC, 0xEBFC, 0x6726, 0xEBFD, 0x81CA, 0xEBFE, 0x81BB,
+	0xEC40, 0x9721, 0xEC41, 0x9722, 0xEC42, 0x9723, 0xEC43, 0x9724,
+	0xEC44, 0x9725, 0xEC45, 0x9726, 0xEC46, 0x9727, 0xEC47, 0x9728,
+	0xEC48, 0x9729, 0xEC49, 0x972B, 0xEC4A, 0x972C, 0xEC4B, 0x972E,
+	0xEC4C, 0x972F, 0xEC4D, 0x9731, 0xEC4E, 0x9733, 0xEC4F, 0x9734,
+	0xEC50, 0x9735, 0xEC51, 0x9736, 0xEC52, 0x9737, 0xEC53, 0x973A,
+	0xEC54, 0x973B, 0xEC55, 0x973C, 0xEC56, 0x973D, 0xEC57, 0x973F,
+	0xEC58, 0x9740, 0xEC59, 0x9741, 0xEC5A, 0x9742, 0xEC5B, 0x9743,
+	0xEC5C, 0x9744, 0xEC5D, 0x9745, 0xEC5E, 0x9746, 0xEC5F, 0x9747,
+	0xEC60, 0x9748, 0xEC61, 0x9749, 0xEC62, 0x974A, 0xEC63, 0x974B,
+	0xEC64, 0x974C, 0xEC65, 0x974D, 0xEC66, 0x974E, 0xEC67, 0x974F,
+	0xEC68, 0x9750, 0xEC69, 0x9751, 0xEC6A, 0x9754, 0xEC6B, 0x9755,
+	0xEC6C, 0x9757, 0xEC6D, 0x9758, 0xEC6E, 0x975A, 0xEC6F, 0x975C,
+	0xEC70, 0x975D, 0xEC71, 0x975F, 0xEC72, 0x9763, 0xEC73, 0x9764,
+	0xEC74, 0x9766, 0xEC75, 0x9767, 0xEC76, 0x9768, 0xEC77, 0x976A,
+	0xEC78, 0x976B, 0xEC79, 0x976C, 0xEC7A, 0x976D, 0xEC7B, 0x976E,
+	0xEC7C, 0x976F, 0xEC7D, 0x9770, 0xEC7E, 0x9771, 0xEC80, 0x9772,
+	0xEC81, 0x9775, 0xEC82, 0x9777, 0xEC83, 0x9778, 0xEC84, 0x9779,
+	0xEC85, 0x977A, 0xEC86, 0x977B, 0xEC87, 0x977D, 0xEC88, 0x977E,
+	0xEC89, 0x977F, 0xEC8A, 0x9780, 0xEC8B, 0x9781, 0xEC8C, 0x9782,
+	0xEC8D, 0x9783, 0xEC8E, 0x9784, 0xEC8F, 0x9786, 0xEC90, 0x9787,
+	0xEC91, 0x9788, 0xEC92, 0x9789, 0xEC93, 0x978A, 0xEC94, 0x978C,
+	0xEC95, 0x978E, 0xEC96, 0x978F, 0xEC97, 0x9790, 0xEC98, 0x9793,
+	0xEC99, 0x9795, 0xEC9A, 0x9796, 0xEC9B, 0x9797, 0xEC9C, 0x9799,
+	0xEC9D, 0x979A, 0xEC9E, 0x979B, 0xEC9F, 0x979C, 0xECA0, 0x979D,
+	0xECA1, 0x81C1, 0xECA2, 0x81A6, 0xECA3, 0x6B24, 0xECA4, 0x6B37,
+	0xECA5, 0x6B39, 0xECA6, 0x6B43, 0xECA7, 0x6B46, 0xECA8, 0x6B59,
+	0xECA9, 0x98D1, 0xECAA, 0x98D2, 0xECAB, 0x98D3, 0xECAC, 0x98D5,
+	0xECAD, 0x98D9, 0xECAE, 0x98DA, 0xECAF, 0x6BB3, 0xECB0, 0x5F40,
+	0xECB1, 0x6BC2, 0xECB2, 0x89F3, 0xECB3, 0x6590, 0xECB4, 0x9F51,
+	0xECB5, 0x6593, 0xECB6, 0x65BC, 0xECB7, 0x65C6, 0xECB8, 0x65C4,
+	0xECB9, 0x65C3, 0xECBA, 0x65CC, 0xECBB, 0x65CE, 0xECBC, 0x65D2,
+	0xECBD, 0x65D6, 0xECBE, 0x7080, 0xECBF, 0x709C, 0xECC0, 0x7096,
+	0xECC1, 0x709D, 0xECC2, 0x70BB, 0xECC3, 0x70C0, 0xECC4, 0x70B7,
+	0xECC5, 0x70AB, 0xECC6, 0x70B1, 0xECC7, 0x70E8, 0xECC8, 0x70CA,
+	0xECC9, 0x7110, 0xECCA, 0x7113, 0xECCB, 0x7116, 0xECCC, 0x712F,
+	0xECCD, 0x7131, 0xECCE, 0x7173, 0xECCF, 0x715C, 0xECD0, 0x7168,
+	0xECD1, 0x7145, 0xECD2, 0x7172, 0xECD3, 0x714A, 0xECD4, 0x7178,
+	0xECD5, 0x717A, 0xECD6, 0x7198, 0xECD7, 0x71B3, 0xECD8, 0x71B5,
+	0xECD9, 0x71A8, 0xECDA, 0x71A0, 0xECDB, 0x71E0, 0xECDC, 0x71D4,
+	0xECDD, 0x71E7, 0xECDE, 0x71F9, 0xECDF, 0x721D, 0xECE0, 0x7228,
+	0xECE1, 0x706C, 0xECE2, 0x7118, 0xECE3, 0x7166, 0xECE4, 0x71B9,
+	0xECE5, 0x623E, 0xECE6, 0x623D, 0xECE7, 0x6243, 0xECE8, 0x6248,
+	0xECE9, 0x6249, 0xECEA, 0x793B, 0xECEB, 0x7940, 0xECEC, 0x7946,
+	0xECED, 0x7949, 0xECEE, 0x795B, 0xECEF, 0x795C, 0xECF0, 0x7953,
+	0xECF1, 0x795A, 0xECF2, 0x7962, 0xECF3, 0x7957, 0xECF4, 0x7960,
+	0xECF5, 0x796F, 0xECF6, 0x7967, 0xECF7, 0x797A, 0xECF8, 0x7985,
+	0xECF9, 0x798A, 0xECFA, 0x799A, 0xECFB, 0x79A7, 0xECFC, 0x79B3,
+	0xECFD, 0x5FD1, 0xECFE, 0x5FD0, 0xED40, 0x979E, 0xED41, 0x979F,
+	0xED42, 0x97A1, 0xED43, 0x97A2, 0xED44, 0x97A4, 0xED45, 0x97A5,
+	0xED46, 0x97A6, 0xED47, 0x97A7, 0xED48, 0x97A8, 0xED49, 0x97A9,
+	0xED4A, 0x97AA, 0xED4B, 0x97AC, 0xED4C, 0x97AE, 0xED4D, 0x97B0,
+	0xED4E, 0x97B1, 0xED4F, 0x97B3, 0xED50, 0x97B5, 0xED51, 0x97B6,
+	0xED52, 0x97B7, 0xED53, 0x97B8, 0xED54, 0x97B9, 0xED55, 0x97BA,
+	0xED56, 0x97BB, 0xED57, 0x97BC, 0xED58, 0x97BD, 0xED59, 0x97BE,
+	0xED5A, 0x97BF, 0xED5B, 0x97C0, 0xED5C, 0x97C1, 0xED5D, 0x97C2,
+	0xED5E, 0x97C3, 0xED5F, 0x97C4, 0xED60, 0x97C5, 0xED61, 0x97C6,
+	0xED62, 0x97C7, 0xED63, 0x97C8, 0xED64, 0x97C9, 0xED65, 0x97CA,
+	0xED66, 0x97CB, 0xED67, 0x97CC, 0xED68, 0x97CD, 0xED69, 0x97CE,
+	0xED6A, 0x97CF, 0xED6B, 0x97D0, 0xED6C, 0x97D1, 0xED6D, 0x97D2,
+	0xED6E, 0x97D3, 0xED6F, 0x97D4, 0xED70, 0x97D5, 0xED71, 0x97D6,
+	0xED72, 0x97D7, 0xED73, 0x97D8, 0xED74, 0x97D9, 0xED75, 0x97DA,
+	0xED76, 0x97DB, 0xED77, 0x97DC, 0xED78, 0x97DD, 0xED79, 0x97DE,
+	0xED7A, 0x97DF, 0xED7B, 0x97E0, 0xED7C, 0x97E1, 0xED7D, 0x97E2,
+	0xED7E, 0x97E3, 0xED80, 0x97E4, 0xED81, 0x97E5, 0xED82, 0x97E8,
+	0xED83, 0x97EE, 0xED84, 0x97EF, 0xED85, 0x97F0, 0xED86, 0x97F1,
+	0xED87, 0x97F2, 0xED88, 0x97F4, 0xED89, 0x97F7, 0xED8A, 0x97F8,
+	0xED8B, 0x97F9, 0xED8C, 0x97FA, 0xED8D, 0x97FB, 0xED8E, 0x97FC,
+	0xED8F, 0x97FD, 0xED90, 0x97FE, 0xED91, 0x97FF, 0xED92, 0x9800,
+	0xED93, 0x9801, 0xED94, 0x9802, 0xED95, 0x9803, 0xED96, 0x9804,
+	0xED97, 0x9805, 0xED98, 0x9806, 0xED99, 0x9807, 0xED9A, 0x9808,
+	0xED9B, 0x9809, 0xED9C, 0x980A, 0xED9D, 0x980B, 0xED9E, 0x980C,
+	0xED9F, 0x980D, 0xEDA0, 0x980E, 0xEDA1, 0x603C, 0xEDA2, 0x605D,
+	0xEDA3, 0x605A, 0xEDA4, 0x6067, 0xEDA5, 0x6041, 0xEDA6, 0x6059,
+	0xEDA7, 0x6063, 0xEDA8, 0x60AB, 0xEDA9, 0x6106, 0xEDAA, 0x610D,
+	0xEDAB, 0x615D, 0xEDAC, 0x61A9, 0xEDAD, 0x619D, 0xEDAE, 0x61CB,
+	0xEDAF, 0x61D1, 0xEDB0, 0x6206, 0xEDB1, 0x8080, 0xEDB2, 0x807F,
+	0xEDB3, 0x6C93, 0xEDB4, 0x6CF6, 0xEDB5, 0x6DFC, 0xEDB6, 0x77F6,
+	0xEDB7, 0x77F8, 0xEDB8, 0x7800, 0xEDB9, 0x7809, 0xEDBA, 0x7817,
+	0xEDBB, 0x7818, 0xEDBC, 0x7811, 0xEDBD, 0x65AB, 0xEDBE, 0x782D,
+	0xEDBF, 0x781C, 0xEDC0, 0x781D, 0xEDC1, 0x7839, 0xEDC2, 0x783A,
+	0xEDC3, 0x783B, 0xEDC4, 0x781F, 0xEDC5, 0x783C, 0xEDC6, 0x7825,
+	0xEDC7, 0x782C, 0xEDC8, 0x7823, 0xEDC9, 0x7829, 0xEDCA, 0x784E,
+	0xEDCB, 0x786D, 0xEDCC, 0x7856, 0xEDCD, 0x7857, 0xEDCE, 0x7826,
+	0xEDCF, 0x7850, 0xEDD0, 0x7847, 0xEDD1, 0x784C, 0xEDD2, 0x786A,
+	0xEDD3, 0x789B, 0xEDD4, 0x7893, 0xEDD5, 0x789A, 0xEDD6, 0x7887,
+	0xEDD7, 0x789C, 0xEDD8, 0x78A1, 0xEDD9, 0x78A3, 0xEDDA, 0x78B2,
+	0xEDDB, 0x78B9, 0xEDDC, 0x78A5, 0xEDDD, 0x78D4, 0xEDDE, 0x78D9,
+	0xEDDF, 0x78C9, 0xEDE0, 0x78EC, 0xEDE1, 0x78F2, 0xEDE2, 0x7905,
+	0xEDE3, 0x78F4, 0xEDE4, 0x7913, 0xEDE5, 0x7924, 0xEDE6, 0x791E,
+	0xEDE7, 0x7934, 0xEDE8, 0x9F9B, 0xEDE9, 0x9EF9, 0xEDEA, 0x9EFB,
+	0xEDEB, 0x9EFC, 0xEDEC, 0x76F1, 0xEDED, 0x7704, 0xEDEE, 0x770D,
+	0xEDEF, 0x76F9, 0xEDF0, 0x7707, 0xEDF1, 0x7708, 0xEDF2, 0x771A,
+	0xEDF3, 0x7722, 0xEDF4, 0x7719, 0xEDF5, 0x772D, 0xEDF6, 0x7726,
+	0xEDF7, 0x7735, 0xEDF8, 0x7738, 0xEDF9, 0x7750, 0xEDFA, 0x7751,
+	0xEDFB, 0x7747, 0xEDFC, 0x7743, 0xEDFD, 0x775A, 0xEDFE, 0x7768,
+	0xEE40, 0x980F, 0xEE41, 0x9810, 0xEE42, 0x9811, 0xEE43, 0x9812,
+	0xEE44, 0x9813, 0xEE45, 0x9814, 0xEE46, 0x9815, 0xEE47, 0x9816,
+	0xEE48, 0x9817, 0xEE49, 0x9818, 0xEE4A, 0x9819, 0xEE4B, 0x981A,
+	0xEE4C, 0x981B, 0xEE4D, 0x981C, 0xEE4E, 0x981D, 0xEE4F, 0x981E,
+	0xEE50, 0x981F, 0xEE51, 0x9820, 0xEE52, 0x9821, 0xEE53, 0x9822,
+	0xEE54, 0x9823, 0xEE55, 0x9824, 0xEE56, 0x9825, 0xEE57, 0x9826,
+	0xEE58, 0x9827, 0xEE59, 0x9828, 0xEE5A, 0x9829, 0xEE5B, 0x982A,
+	0xEE5C, 0x982B, 0xEE5D, 0x982C, 0xEE5E, 0x982D, 0xEE5F, 0x982E,
+	0xEE60, 0x982F, 0xEE61, 0x9830, 0xEE62, 0x9831, 0xEE63, 0x9832,
+	0xEE64, 0x9833, 0xEE65, 0x9834, 0xEE66, 0x9835, 0xEE67, 0x9836,
+	0xEE68, 0x9837, 0xEE69, 0x9838, 0xEE6A, 0x9839, 0xEE6B, 0x983A,
+	0xEE6C, 0x983B, 0xEE6D, 0x983C, 0xEE6E, 0x983D, 0xEE6F, 0x983E,
+	0xEE70, 0x983F, 0xEE71, 0x9840, 0xEE72, 0x9841, 0xEE73, 0x9842,
+	0xEE74, 0x9843, 0xEE75, 0x9844, 0xEE76, 0x9845, 0xEE77, 0x9846,
+	0xEE78, 0x9847, 0xEE79, 0x9848, 0xEE7A, 0x9849, 0xEE7B, 0x984A,
+	0xEE7C, 0x984B, 0xEE7D, 0x984C, 0xEE7E, 0x984D, 0xEE80, 0x984E,
+	0xEE81, 0x984F, 0xEE82, 0x9850, 0xEE83, 0x9851, 0xEE84, 0x9852,
+	0xEE85, 0x9853, 0xEE86, 0x9854, 0xEE87, 0x9855, 0xEE88, 0x9856,
+	0xEE89, 0x9857, 0xEE8A, 0x9858, 0xEE8B, 0x9859, 0xEE8C, 0x985A,
+	0xEE8D, 0x985B, 0xEE8E, 0x985C, 0xEE8F, 0x985D, 0xEE90, 0x985E,
+	0xEE91, 0x985F, 0xEE92, 0x9860, 0xEE93, 0x9861, 0xEE94, 0x9862,
+	0xEE95, 0x9863, 0xEE96, 0x9864, 0xEE97, 0x9865, 0xEE98, 0x9866,
+	0xEE99, 0x9867, 0xEE9A, 0x9868, 0xEE9B, 0x9869, 0xEE9C, 0x986A,
+	0xEE9D, 0x986B, 0xEE9E, 0x986C, 0xEE9F, 0x986D, 0xEEA0, 0x986E,
+	0xEEA1, 0x7762, 0xEEA2, 0x7765, 0xEEA3, 0x777F, 0xEEA4, 0x778D,
+	0xEEA5, 0x777D, 0xEEA6, 0x7780, 0xEEA7, 0x778C, 0xEEA8, 0x7791,
+	0xEEA9, 0x779F, 0xEEAA, 0x77A0, 0xEEAB, 0x77B0, 0xEEAC, 0x77B5,
+	0xEEAD, 0x77BD, 0xEEAE, 0x753A, 0xEEAF, 0x7540, 0xEEB0, 0x754E,
+	0xEEB1, 0x754B, 0xEEB2, 0x7548, 0xEEB3, 0x755B, 0xEEB4, 0x7572,
+	0xEEB5, 0x7579, 0xEEB6, 0x7583, 0xEEB7, 0x7F58, 0xEEB8, 0x7F61,
+	0xEEB9, 0x7F5F, 0xEEBA, 0x8A48, 0xEEBB, 0x7F68, 0xEEBC, 0x7F74,
+	0xEEBD, 0x7F71, 0xEEBE, 0x7F79, 0xEEBF, 0x7F81, 0xEEC0, 0x7F7E,
+	0xEEC1, 0x76CD, 0xEEC2, 0x76E5, 0xEEC3, 0x8832, 0xEEC4, 0x9485,
+	0xEEC5, 0x9486, 0xEEC6, 0x9487, 0xEEC7, 0x948B, 0xEEC8, 0x948A,
+	0xEEC9, 0x948C, 0xEECA, 0x948D, 0xEECB, 0x948F, 0xEECC, 0x9490,
+	0xEECD, 0x9494, 0xEECE, 0x9497, 0xEECF, 0x9495, 0xEED0, 0x949A,
+	0xEED1, 0x949B, 0xEED2, 0x949C, 0xEED3, 0x94A3, 0xEED4, 0x94A4,
+	0xEED5, 0x94AB, 0xEED6, 0x94AA, 0xEED7, 0x94AD, 0xEED8, 0x94AC,
+	0xEED9, 0x94AF, 0xEEDA, 0x94B0, 0xEEDB, 0x94B2, 0xEEDC, 0x94B4,
+	0xEEDD, 0x94B6, 0xEEDE, 0x94B7, 0xEEDF, 0x94B8, 0xEEE0, 0x94B9,
+	0xEEE1, 0x94BA, 0xEEE2, 0x94BC, 0xEEE3, 0x94BD, 0xEEE4, 0x94BF,
+	0xEEE5, 0x94C4, 0xEEE6, 0x94C8, 0xEEE7, 0x94C9, 0xEEE8, 0x94CA,
+	0xEEE9, 0x94CB, 0xEEEA, 0x94CC, 0xEEEB, 0x94CD, 0xEEEC, 0x94CE,
+	0xEEED, 0x94D0, 0xEEEE, 0x94D1, 0xEEEF, 0x94D2, 0xEEF0, 0x94D5,
+	0xEEF1, 0x94D6, 0xEEF2, 0x94D7, 0xEEF3, 0x94D9, 0xEEF4, 0x94D8,
+	0xEEF5, 0x94DB, 0xEEF6, 0x94DE, 0xEEF7, 0x94DF, 0xEEF8, 0x94E0,
+	0xEEF9, 0x94E2, 0xEEFA, 0x94E4, 0xEEFB, 0x94E5, 0xEEFC, 0x94E7,
+	0xEEFD, 0x94E8, 0xEEFE, 0x94EA, 0xEF40, 0x986F, 0xEF41, 0x9870,
+	0xEF42, 0x9871, 0xEF43, 0x9872, 0xEF44, 0x9873, 0xEF45, 0x9874,
+	0xEF46, 0x988B, 0xEF47, 0x988E, 0xEF48, 0x9892, 0xEF49, 0x9895,
+	0xEF4A, 0x9899, 0xEF4B, 0x98A3, 0xEF4C, 0x98A8, 0xEF4D, 0x98A9,
+	0xEF4E, 0x98AA, 0xEF4F, 0x98AB, 0xEF50, 0x98AC, 0xEF51, 0x98AD,
+	0xEF52, 0x98AE, 0xEF53, 0x98AF, 0xEF54, 0x98B0, 0xEF55, 0x98B1,
+	0xEF56, 0x98B2, 0xEF57, 0x98B3, 0xEF58, 0x98B4, 0xEF59, 0x98B5,
+	0xEF5A, 0x98B6, 0xEF5B, 0x98B7, 0xEF5C, 0x98B8, 0xEF5D, 0x98B9,
+	0xEF5E, 0x98BA, 0xEF5F, 0x98BB, 0xEF60, 0x98BC, 0xEF61, 0x98BD,
+	0xEF62, 0x98BE, 0xEF63, 0x98BF, 0xEF64, 0x98C0, 0xEF65, 0x98C1,
+	0xEF66, 0x98C2, 0xEF67, 0x98C3, 0xEF68, 0x98C4, 0xEF69, 0x98C5,
+	0xEF6A, 0x98C6, 0xEF6B, 0x98C7, 0xEF6C, 0x98C8, 0xEF6D, 0x98C9,
+	0xEF6E, 0x98CA, 0xEF6F, 0x98CB, 0xEF70, 0x98CC, 0xEF71, 0x98CD,
+	0xEF72, 0x98CF, 0xEF73, 0x98D0, 0xEF74, 0x98D4, 0xEF75, 0x98D6,
+	0xEF76, 0x98D7, 0xEF77, 0x98DB, 0xEF78, 0x98DC, 0xEF79, 0x98DD,
+	0xEF7A, 0x98E0, 0xEF7B, 0x98E1, 0xEF7C, 0x98E2, 0xEF7D, 0x98E3,
+	0xEF7E, 0x98E4, 0xEF80, 0x98E5, 0xEF81, 0x98E6, 0xEF82, 0x98E9,
+	0xEF83, 0x98EA, 0xEF84, 0x98EB, 0xEF85, 0x98EC, 0xEF86, 0x98ED,
+	0xEF87, 0x98EE, 0xEF88, 0x98EF, 0xEF89, 0x98F0, 0xEF8A, 0x98F1,
+	0xEF8B, 0x98F2, 0xEF8C, 0x98F3, 0xEF8D, 0x98F4, 0xEF8E, 0x98F5,
+	0xEF8F, 0x98F6, 0xEF90, 0x98F7, 0xEF91, 0x98F8, 0xEF92, 0x98F9,
+	0xEF93, 0x98FA, 0xEF94, 0x98FB, 0xEF95, 0x98FC, 0xEF96, 0x98FD,
+	0xEF97, 0x98FE, 0xEF98, 0x98FF, 0xEF99, 0x9900, 0xEF9A, 0x9901,
+	0xEF9B, 0x9902, 0xEF9C, 0x9903, 0xEF9D, 0x9904, 0xEF9E, 0x9905,
+	0xEF9F, 0x9906, 0xEFA0, 0x9907, 0xEFA1, 0x94E9, 0xEFA2, 0x94EB,
+	0xEFA3, 0x94EE, 0xEFA4, 0x94EF, 0xEFA5, 0x94F3, 0xEFA6, 0x94F4,
+	0xEFA7, 0x94F5, 0xEFA8, 0x94F7, 0xEFA9, 0x94F9, 0xEFAA, 0x94FC,
+	0xEFAB, 0x94FD, 0xEFAC, 0x94FF, 0xEFAD, 0x9503, 0xEFAE, 0x9502,
+	0xEFAF, 0x9506, 0xEFB0, 0x9507, 0xEFB1, 0x9509, 0xEFB2, 0x950A,
+	0xEFB3, 0x950D, 0xEFB4, 0x950E, 0xEFB5, 0x950F, 0xEFB6, 0x9512,
+	0xEFB7, 0x9513, 0xEFB8, 0x9514, 0xEFB9, 0x9515, 0xEFBA, 0x9516,
+	0xEFBB, 0x9518, 0xEFBC, 0x951B, 0xEFBD, 0x951D, 0xEFBE, 0x951E,
+	0xEFBF, 0x951F, 0xEFC0, 0x9522, 0xEFC1, 0x952A, 0xEFC2, 0x952B,
+	0xEFC3, 0x9529, 0xEFC4, 0x952C, 0xEFC5, 0x9531, 0xEFC6, 0x9532,
+	0xEFC7, 0x9534, 0xEFC8, 0x9536, 0xEFC9, 0x9537, 0xEFCA, 0x9538,
+	0xEFCB, 0x953C, 0xEFCC, 0x953E, 0xEFCD, 0x953F, 0xEFCE, 0x9542,
+	0xEFCF, 0x9535, 0xEFD0, 0x9544, 0xEFD1, 0x9545, 0xEFD2, 0x9546,
+	0xEFD3, 0x9549, 0xEFD4, 0x954C, 0xEFD5, 0x954E, 0xEFD6, 0x954F,
+	0xEFD7, 0x9552, 0xEFD8, 0x9553, 0xEFD9, 0x9554, 0xEFDA, 0x9556,
+	0xEFDB, 0x9557, 0xEFDC, 0x9558, 0xEFDD, 0x9559, 0xEFDE, 0x955B,
+	0xEFDF, 0x955E, 0xEFE0, 0x955F, 0xEFE1, 0x955D, 0xEFE2, 0x9561,
+	0xEFE3, 0x9562, 0xEFE4, 0x9564, 0xEFE5, 0x9565, 0xEFE6, 0x9566,
+	0xEFE7, 0x9567, 0xEFE8, 0x9568, 0xEFE9, 0x9569, 0xEFEA, 0x956A,
+	0xEFEB, 0x956B, 0xEFEC, 0x956C, 0xEFED, 0x956F, 0xEFEE, 0x9571,
+	0xEFEF, 0x9572, 0xEFF0, 0x9573, 0xEFF1, 0x953A, 0xEFF2, 0x77E7,
+	0xEFF3, 0x77EC, 0xEFF4, 0x96C9, 0xEFF5, 0x79D5, 0xEFF6, 0x79ED,
+	0xEFF7, 0x79E3, 0xEFF8, 0x79EB, 0xEFF9, 0x7A06, 0xEFFA, 0x5D47,
+	0xEFFB, 0x7A03, 0xEFFC, 0x7A02, 0xEFFD, 0x7A1E, 0xEFFE, 0x7A14,
+	0xF040, 0x9908, 0xF041, 0x9909, 0xF042, 0x990A, 0xF043, 0x990B,
+	0xF044, 0x990C, 0xF045, 0x990E, 0xF046, 0x990F, 0xF047, 0x9911,
+	0xF048, 0x9912, 0xF049, 0x9913, 0xF04A, 0x9914, 0xF04B, 0x9915,
+	0xF04C, 0x9916, 0xF04D, 0x9917, 0xF04E, 0x9918, 0xF04F, 0x9919,
+	0xF050, 0x991A, 0xF051, 0x991B, 0xF052, 0x991C, 0xF053, 0x991D,
+	0xF054, 0x991E, 0xF055, 0x991F, 0xF056, 0x9920, 0xF057, 0x9921,
+	0xF058, 0x9922, 0xF059, 0x9923, 0xF05A, 0x9924, 0xF05B, 0x9925,
+	0xF05C, 0x9926, 0xF05D, 0x9927, 0xF05E, 0x9928, 0xF05F, 0x9929,
+	0xF060, 0x992A, 0xF061, 0x992B, 0xF062, 0x992C, 0xF063, 0x992D,
+	0xF064, 0x992F, 0xF065, 0x9930, 0xF066, 0x9931, 0xF067, 0x9932,
+	0xF068, 0x9933, 0xF069, 0x9934, 0xF06A, 0x9935, 0xF06B, 0x9936,
+	0xF06C, 0x9937, 0xF06D, 0x9938, 0xF06E, 0x9939, 0xF06F, 0x993A,
+	0xF070, 0x993B, 0xF071, 0x993C, 0xF072, 0x993D, 0xF073, 0x993E,
+	0xF074, 0x993F, 0xF075, 0x9940, 0xF076, 0x9941, 0xF077, 0x9942,
+	0xF078, 0x9943, 0xF079, 0x9944, 0xF07A, 0x9945, 0xF07B, 0x9946,
+	0xF07C, 0x9947, 0xF07D, 0x9948, 0xF07E, 0x9949, 0xF080, 0x994A,
+	0xF081, 0x994B, 0xF082, 0x994C, 0xF083, 0x994D, 0xF084, 0x994E,
+	0xF085, 0x994F, 0xF086, 0x9950, 0xF087, 0x9951, 0xF088, 0x9952,
+	0xF089, 0x9953, 0xF08A, 0x9956, 0xF08B, 0x9957, 0xF08C, 0x9958,
+	0xF08D, 0x9959, 0xF08E, 0x995A, 0xF08F, 0x995B, 0xF090, 0x995C,
+	0xF091, 0x995D, 0xF092, 0x995E, 0xF093, 0x995F, 0xF094, 0x9960,
+	0xF095, 0x9961, 0xF096, 0x9962, 0xF097, 0x9964, 0xF098, 0x9966,
+	0xF099, 0x9973, 0xF09A, 0x9978, 0xF09B, 0x9979, 0xF09C, 0x997B,
+	0xF09D, 0x997E, 0xF09E, 0x9982, 0xF09F, 0x9983, 0xF0A0, 0x9989,
+	0xF0A1, 0x7A39, 0xF0A2, 0x7A37, 0xF0A3, 0x7A51, 0xF0A4, 0x9ECF,
+	0xF0A5, 0x99A5, 0xF0A6, 0x7A70, 0xF0A7, 0x7688, 0xF0A8, 0x768E,
+	0xF0A9, 0x7693, 0xF0AA, 0x7699, 0xF0AB, 0x76A4, 0xF0AC, 0x74DE,
+	0xF0AD, 0x74E0, 0xF0AE, 0x752C, 0xF0AF, 0x9E20, 0xF0B0, 0x9E22,
+	0xF0B1, 0x9E28, 0xF0B2, 0x9E29, 0xF0B3, 0x9E2A, 0xF0B4, 0x9E2B,
+	0xF0B5, 0x9E2C, 0xF0B6, 0x9E32, 0xF0B7, 0x9E31, 0xF0B8, 0x9E36,
+	0xF0B9, 0x9E38, 0xF0BA, 0x9E37, 0xF0BB, 0x9E39, 0xF0BC, 0x9E3A,
+	0xF0BD, 0x9E3E, 0xF0BE, 0x9E41, 0xF0BF, 0x9E42, 0xF0C0, 0x9E44,
+	0xF0C1, 0x9E46, 0xF0C2, 0x9E47, 0xF0C3, 0x9E48, 0xF0C4, 0x9E49,
+	0xF0C5, 0x9E4B, 0xF0C6, 0x9E4C, 0xF0C7, 0x9E4E, 0xF0C8, 0x9E51,
+	0xF0C9, 0x9E55, 0xF0CA, 0x9E57, 0xF0CB, 0x9E5A, 0xF0CC, 0x9E5B,
+	0xF0CD, 0x9E5C, 0xF0CE, 0x9E5E, 0xF0CF, 0x9E63, 0xF0D0, 0x9E66,
+	0xF0D1, 0x9E67, 0xF0D2, 0x9E68, 0xF0D3, 0x9E69, 0xF0D4, 0x9E6A,
+	0xF0D5, 0x9E6B, 0xF0D6, 0x9E6C, 0xF0D7, 0x9E71, 0xF0D8, 0x9E6D,
+	0xF0D9, 0x9E73, 0xF0DA, 0x7592, 0xF0DB, 0x7594, 0xF0DC, 0x7596,
+	0xF0DD, 0x75A0, 0xF0DE, 0x759D, 0xF0DF, 0x75AC, 0xF0E0, 0x75A3,
+	0xF0E1, 0x75B3, 0xF0E2, 0x75B4, 0xF0E3, 0x75B8, 0xF0E4, 0x75C4,
+	0xF0E5, 0x75B1, 0xF0E6, 0x75B0, 0xF0E7, 0x75C3, 0xF0E8, 0x75C2,
+	0xF0E9, 0x75D6, 0xF0EA, 0x75CD, 0xF0EB, 0x75E3, 0xF0EC, 0x75E8,
+	0xF0ED, 0x75E6, 0xF0EE, 0x75E4, 0xF0EF, 0x75EB, 0xF0F0, 0x75E7,
+	0xF0F1, 0x7603, 0xF0F2, 0x75F1, 0xF0F3, 0x75FC, 0xF0F4, 0x75FF,
+	0xF0F5, 0x7610, 0xF0F6, 0x7600, 0xF0F7, 0x7605, 0xF0F8, 0x760C,
+	0xF0F9, 0x7617, 0xF0FA, 0x760A, 0xF0FB, 0x7625, 0xF0FC, 0x7618,
+	0xF0FD, 0x7615, 0xF0FE, 0x7619, 0xF140, 0x998C, 0xF141, 0x998E,
+	0xF142, 0x999A, 0xF143, 0x999B, 0xF144, 0x999C, 0xF145, 0x999D,
+	0xF146, 0x999E, 0xF147, 0x999F, 0xF148, 0x99A0, 0xF149, 0x99A1,
+	0xF14A, 0x99A2, 0xF14B, 0x99A3, 0xF14C, 0x99A4, 0xF14D, 0x99A6,
+	0xF14E, 0x99A7, 0xF14F, 0x99A9, 0xF150, 0x99AA, 0xF151, 0x99AB,
+	0xF152, 0x99AC, 0xF153, 0x99AD, 0xF154, 0x99AE, 0xF155, 0x99AF,
+	0xF156, 0x99B0, 0xF157, 0x99B1, 0xF158, 0x99B2, 0xF159, 0x99B3,
+	0xF15A, 0x99B4, 0xF15B, 0x99B5, 0xF15C, 0x99B6, 0xF15D, 0x99B7,
+	0xF15E, 0x99B8, 0xF15F, 0x99B9, 0xF160, 0x99BA, 0xF161, 0x99BB,
+	0xF162, 0x99BC, 0xF163, 0x99BD, 0xF164, 0x99BE, 0xF165, 0x99BF,
+	0xF166, 0x99C0, 0xF167, 0x99C1, 0xF168, 0x99C2, 0xF169, 0x99C3,
+	0xF16A, 0x99C4, 0xF16B, 0x99C5, 0xF16C, 0x99C6, 0xF16D, 0x99C7,
+	0xF16E, 0x99C8, 0xF16F, 0x99C9, 0xF170, 0x99CA, 0xF171, 0x99CB,
+	0xF172, 0x99CC, 0xF173, 0x99CD, 0xF174, 0x99CE, 0xF175, 0x99CF,
+	0xF176, 0x99D0, 0xF177, 0x99D1, 0xF178, 0x99D2, 0xF179, 0x99D3,
+	0xF17A, 0x99D4, 0xF17B, 0x99D5, 0xF17C, 0x99D6, 0xF17D, 0x99D7,
+	0xF17E, 0x99D8, 0xF180, 0x99D9, 0xF181, 0x99DA, 0xF182, 0x99DB,
+	0xF183, 0x99DC, 0xF184, 0x99DD, 0xF185, 0x99DE, 0xF186, 0x99DF,
+	0xF187, 0x99E0, 0xF188, 0x99E1, 0xF189, 0x99E2, 0xF18A, 0x99E3,
+	0xF18B, 0x99E4, 0xF18C, 0x99E5, 0xF18D, 0x99E6, 0xF18E, 0x99E7,
+	0xF18F, 0x99E8, 0xF190, 0x99E9, 0xF191, 0x99EA, 0xF192, 0x99EB,
+	0xF193, 0x99EC, 0xF194, 0x99ED, 0xF195, 0x99EE, 0xF196, 0x99EF,
+	0xF197, 0x99F0, 0xF198, 0x99F1, 0xF199, 0x99F2, 0xF19A, 0x99F3,
+	0xF19B, 0x99F4, 0xF19C, 0x99F5, 0xF19D, 0x99F6, 0xF19E, 0x99F7,
+	0xF19F, 0x99F8, 0xF1A0, 0x99F9, 0xF1A1, 0x761B, 0xF1A2, 0x763C,
+	0xF1A3, 0x7622, 0xF1A4, 0x7620, 0xF1A5, 0x7640, 0xF1A6, 0x762D,
+	0xF1A7, 0x7630, 0xF1A8, 0x763F, 0xF1A9, 0x7635, 0xF1AA, 0x7643,
+	0xF1AB, 0x763E, 0xF1AC, 0x7633, 0xF1AD, 0x764D, 0xF1AE, 0x765E,
+	0xF1AF, 0x7654, 0xF1B0, 0x765C, 0xF1B1, 0x7656, 0xF1B2, 0x766B,
+	0xF1B3, 0x766F, 0xF1B4, 0x7FCA, 0xF1B5, 0x7AE6, 0xF1B6, 0x7A78,
+	0xF1B7, 0x7A79, 0xF1B8, 0x7A80, 0xF1B9, 0x7A86, 0xF1BA, 0x7A88,
+	0xF1BB, 0x7A95, 0xF1BC, 0x7AA6, 0xF1BD, 0x7AA0, 0xF1BE, 0x7AAC,
+	0xF1BF, 0x7AA8, 0xF1C0, 0x7AAD, 0xF1C1, 0x7AB3, 0xF1C2, 0x8864,
+	0xF1C3, 0x8869, 0xF1C4, 0x8872, 0xF1C5, 0x887D, 0xF1C6, 0x887F,
+	0xF1C7, 0x8882, 0xF1C8, 0x88A2, 0xF1C9, 0x88C6, 0xF1CA, 0x88B7,
+	0xF1CB, 0x88BC, 0xF1CC, 0x88C9, 0xF1CD, 0x88E2, 0xF1CE, 0x88CE,
+	0xF1CF, 0x88E3, 0xF1D0, 0x88E5, 0xF1D1, 0x88F1, 0xF1D2, 0x891A,
+	0xF1D3, 0x88FC, 0xF1D4, 0x88E8, 0xF1D5, 0x88FE, 0xF1D6, 0x88F0,
+	0xF1D7, 0x8921, 0xF1D8, 0x8919, 0xF1D9, 0x8913, 0xF1DA, 0x891B,
+	0xF1DB, 0x890A, 0xF1DC, 0x8934, 0xF1DD, 0x892B, 0xF1DE, 0x8936,
+	0xF1DF, 0x8941, 0xF1E0, 0x8966, 0xF1E1, 0x897B, 0xF1E2, 0x758B,
+	0xF1E3, 0x80E5, 0xF1E4, 0x76B2, 0xF1E5, 0x76B4, 0xF1E6, 0x77DC,
+	0xF1E7, 0x8012, 0xF1E8, 0x8014, 0xF1E9, 0x8016, 0xF1EA, 0x801C,
+	0xF1EB, 0x8020, 0xF1EC, 0x8022, 0xF1ED, 0x8025, 0xF1EE, 0x8026,
+	0xF1EF, 0x8027, 0xF1F0, 0x8029, 0xF1F1, 0x8028, 0xF1F2, 0x8031,
+	0xF1F3, 0x800B, 0xF1F4, 0x8035, 0xF1F5, 0x8043, 0xF1F6, 0x8046,
+	0xF1F7, 0x804D, 0xF1F8, 0x8052, 0xF1F9, 0x8069, 0xF1FA, 0x8071,
+	0xF1FB, 0x8983, 0xF1FC, 0x9878, 0xF1FD, 0x9880, 0xF1FE, 0x9883,
+	0xF240, 0x99FA, 0xF241, 0x99FB, 0xF242, 0x99FC, 0xF243, 0x99FD,
+	0xF244, 0x99FE, 0xF245, 0x99FF, 0xF246, 0x9A00, 0xF247, 0x9A01,
+	0xF248, 0x9A02, 0xF249, 0x9A03, 0xF24A, 0x9A04, 0xF24B, 0x9A05,
+	0xF24C, 0x9A06, 0xF24D, 0x9A07, 0xF24E, 0x9A08, 0xF24F, 0x9A09,
+	0xF250, 0x9A0A, 0xF251, 0x9A0B, 0xF252, 0x9A0C, 0xF253, 0x9A0D,
+	0xF254, 0x9A0E, 0xF255, 0x9A0F, 0xF256, 0x9A10, 0xF257, 0x9A11,
+	0xF258, 0x9A12, 0xF259, 0x9A13, 0xF25A, 0x9A14, 0xF25B, 0x9A15,
+	0xF25C, 0x9A16, 0xF25D, 0x9A17, 0xF25E, 0x9A18, 0xF25F, 0x9A19,
+	0xF260, 0x9A1A, 0xF261, 0x9A1B, 0xF262, 0x9A1C, 0xF263, 0x9A1D,
+	0xF264, 0x9A1E, 0xF265, 0x9A1F, 0xF266, 0x9A20, 0xF267, 0x9A21,
+	0xF268, 0x9A22, 0xF269, 0x9A23, 0xF26A, 0x9A24, 0xF26B, 0x9A25,
+	0xF26C, 0x9A26, 0xF26D, 0x9A27, 0xF26E, 0x9A28, 0xF26F, 0x9A29,
+	0xF270, 0x9A2A, 0xF271, 0x9A2B, 0xF272, 0x9A2C, 0xF273, 0x9A2D,
+	0xF274, 0x9A2E, 0xF275, 0x9A2F, 0xF276, 0x9A30, 0xF277, 0x9A31,
+	0xF278, 0x9A32, 0xF279, 0x9A33, 0xF27A, 0x9A34, 0xF27B, 0x9A35,
+	0xF27C, 0x9A36, 0xF27D, 0x9A37, 0xF27E, 0x9A38, 0xF280, 0x9A39,
+	0xF281, 0x9A3A, 0xF282, 0x9A3B, 0xF283, 0x9A3C, 0xF284, 0x9A3D,
+	0xF285, 0x9A3E, 0xF286, 0x9A3F, 0xF287, 0x9A40, 0xF288, 0x9A41,
+	0xF289, 0x9A42, 0xF28A, 0x9A43, 0xF28B, 0x9A44, 0xF28C, 0x9A45,
+	0xF28D, 0x9A46, 0xF28E, 0x9A47, 0xF28F, 0x9A48, 0xF290, 0x9A49,
+	0xF291, 0x9A4A, 0xF292, 0x9A4B, 0xF293, 0x9A4C, 0xF294, 0x9A4D,
+	0xF295, 0x9A4E, 0xF296, 0x9A4F, 0xF297, 0x9A50, 0xF298, 0x9A51,
+	0xF299, 0x9A52, 0xF29A, 0x9A53, 0xF29B, 0x9A54, 0xF29C, 0x9A55,
+	0xF29D, 0x9A56, 0xF29E, 0x9A57, 0xF29F, 0x9A58, 0xF2A0, 0x9A59,
+	0xF2A1, 0x9889, 0xF2A2, 0x988C, 0xF2A3, 0x988D, 0xF2A4, 0x988F,
+	0xF2A5, 0x9894, 0xF2A6, 0x989A, 0xF2A7, 0x989B, 0xF2A8, 0x989E,
+	0xF2A9, 0x989F, 0xF2AA, 0x98A1, 0xF2AB, 0x98A2, 0xF2AC, 0x98A5,
+	0xF2AD, 0x98A6, 0xF2AE, 0x864D, 0xF2AF, 0x8654, 0xF2B0, 0x866C,
+	0xF2B1, 0x866E, 0xF2B2, 0x867F, 0xF2B3, 0x867A, 0xF2B4, 0x867C,
+	0xF2B5, 0x867B, 0xF2B6, 0x86A8, 0xF2B7, 0x868D, 0xF2B8, 0x868B,
+	0xF2B9, 0x86AC, 0xF2BA, 0x869D, 0xF2BB, 0x86A7, 0xF2BC, 0x86A3,
+	0xF2BD, 0x86AA, 0xF2BE, 0x8693, 0xF2BF, 0x86A9, 0xF2C0, 0x86B6,
+	0xF2C1, 0x86C4, 0xF2C2, 0x86B5, 0xF2C3, 0x86CE, 0xF2C4, 0x86B0,
+	0xF2C5, 0x86BA, 0xF2C6, 0x86B1, 0xF2C7, 0x86AF, 0xF2C8, 0x86C9,
+	0xF2C9, 0x86CF, 0xF2CA, 0x86B4, 0xF2CB, 0x86E9, 0xF2CC, 0x86F1,
+	0xF2CD, 0x86F2, 0xF2CE, 0x86ED, 0xF2CF, 0x86F3, 0xF2D0, 0x86D0,
+	0xF2D1, 0x8713, 0xF2D2, 0x86DE, 0xF2D3, 0x86F4, 0xF2D4, 0x86DF,
+	0xF2D5, 0x86D8, 0xF2D6, 0x86D1, 0xF2D7, 0x8703, 0xF2D8, 0x8707,
+	0xF2D9, 0x86F8, 0xF2DA, 0x8708, 0xF2DB, 0x870A, 0xF2DC, 0x870D,
+	0xF2DD, 0x8709, 0xF2DE, 0x8723, 0xF2DF, 0x873B, 0xF2E0, 0x871E,
+	0xF2E1, 0x8725, 0xF2E2, 0x872E, 0xF2E3, 0x871A, 0xF2E4, 0x873E,
+	0xF2E5, 0x8748, 0xF2E6, 0x8734, 0xF2E7, 0x8731, 0xF2E8, 0x8729,
+	0xF2E9, 0x8737, 0xF2EA, 0x873F, 0xF2EB, 0x8782, 0xF2EC, 0x8722,
+	0xF2ED, 0x877D, 0xF2EE, 0x877E, 0xF2EF, 0x877B, 0xF2F0, 0x8760,
+	0xF2F1, 0x8770, 0xF2F2, 0x874C, 0xF2F3, 0x876E, 0xF2F4, 0x878B,
+	0xF2F5, 0x8753, 0xF2F6, 0x8763, 0xF2F7, 0x877C, 0xF2F8, 0x8764,
+	0xF2F9, 0x8759, 0xF2FA, 0x8765, 0xF2FB, 0x8793, 0xF2FC, 0x87AF,
+	0xF2FD, 0x87A8, 0xF2FE, 0x87D2, 0xF340, 0x9A5A, 0xF341, 0x9A5B,
+	0xF342, 0x9A5C, 0xF343, 0x9A5D, 0xF344, 0x9A5E, 0xF345, 0x9A5F,
+	0xF346, 0x9A60, 0xF347, 0x9A61, 0xF348, 0x9A62, 0xF349, 0x9A63,
+	0xF34A, 0x9A64, 0xF34B, 0x9A65, 0xF34C, 0x9A66, 0xF34D, 0x9A67,
+	0xF34E, 0x9A68, 0xF34F, 0x9A69, 0xF350, 0x9A6A, 0xF351, 0x9A6B,
+	0xF352, 0x9A72, 0xF353, 0x9A83, 0xF354, 0x9A89, 0xF355, 0x9A8D,
+	0xF356, 0x9A8E, 0xF357, 0x9A94, 0xF358, 0x9A95, 0xF359, 0x9A99,
+	0xF35A, 0x9AA6, 0xF35B, 0x9AA9, 0xF35C, 0x9AAA, 0xF35D, 0x9AAB,
+	0xF35E, 0x9AAC, 0xF35F, 0x9AAD, 0xF360, 0x9AAE, 0xF361, 0x9AAF,
+	0xF362, 0x9AB2, 0xF363, 0x9AB3, 0xF364, 0x9AB4, 0xF365, 0x9AB5,
+	0xF366, 0x9AB9, 0xF367, 0x9ABB, 0xF368, 0x9ABD, 0xF369, 0x9ABE,
+	0xF36A, 0x9ABF, 0xF36B, 0x9AC3, 0xF36C, 0x9AC4, 0xF36D, 0x9AC6,
+	0xF36E, 0x9AC7, 0xF36F, 0x9AC8, 0xF370, 0x9AC9, 0xF371, 0x9ACA,
+	0xF372, 0x9ACD, 0xF373, 0x9ACE, 0xF374, 0x9ACF, 0xF375, 0x9AD0,
+	0xF376, 0x9AD2, 0xF377, 0x9AD4, 0xF378, 0x9AD5, 0xF379, 0x9AD6,
+	0xF37A, 0x9AD7, 0xF37B, 0x9AD9, 0xF37C, 0x9ADA, 0xF37D, 0x9ADB,
+	0xF37E, 0x9ADC, 0xF380, 0x9ADD, 0xF381, 0x9ADE, 0xF382, 0x9AE0,
+	0xF383, 0x9AE2, 0xF384, 0x9AE3, 0xF385, 0x9AE4, 0xF386, 0x9AE5,
+	0xF387, 0x9AE7, 0xF388, 0x9AE8, 0xF389, 0x9AE9, 0xF38A, 0x9AEA,
+	0xF38B, 0x9AEC, 0xF38C, 0x9AEE, 0xF38D, 0x9AF0, 0xF38E, 0x9AF1,
+	0xF38F, 0x9AF2, 0xF390, 0x9AF3, 0xF391, 0x9AF4, 0xF392, 0x9AF5,
+	0xF393, 0x9AF6, 0xF394, 0x9AF7, 0xF395, 0x9AF8, 0xF396, 0x9AFA,
+	0xF397, 0x9AFC, 0xF398, 0x9AFD, 0xF399, 0x9AFE, 0xF39A, 0x9AFF,
+	0xF39B, 0x9B00, 0xF39C, 0x9B01, 0xF39D, 0x9B02, 0xF39E, 0x9B04,
+	0xF39F, 0x9B05, 0xF3A0, 0x9B06, 0xF3A1, 0x87C6, 0xF3A2, 0x8788,
+	0xF3A3, 0x8785, 0xF3A4, 0x87AD, 0xF3A5, 0x8797, 0xF3A6, 0x8783,
+	0xF3A7, 0x87AB, 0xF3A8, 0x87E5, 0xF3A9, 0x87AC, 0xF3AA, 0x87B5,
+	0xF3AB, 0x87B3, 0xF3AC, 0x87CB, 0xF3AD, 0x87D3, 0xF3AE, 0x87BD,
+	0xF3AF, 0x87D1, 0xF3B0, 0x87C0, 0xF3B1, 0x87CA, 0xF3B2, 0x87DB,
+	0xF3B3, 0x87EA, 0xF3B4, 0x87E0, 0xF3B5, 0x87EE, 0xF3B6, 0x8816,
+	0xF3B7, 0x8813, 0xF3B8, 0x87FE, 0xF3B9, 0x880A, 0xF3BA, 0x881B,
+	0xF3BB, 0x8821, 0xF3BC, 0x8839, 0xF3BD, 0x883C, 0xF3BE, 0x7F36,
+	0xF3BF, 0x7F42, 0xF3C0, 0x7F44, 0xF3C1, 0x7F45, 0xF3C2, 0x8210,
+	0xF3C3, 0x7AFA, 0xF3C4, 0x7AFD, 0xF3C5, 0x7B08, 0xF3C6, 0x7B03,
+	0xF3C7, 0x7B04, 0xF3C8, 0x7B15, 0xF3C9, 0x7B0A, 0xF3CA, 0x7B2B,
+	0xF3CB, 0x7B0F, 0xF3CC, 0x7B47, 0xF3CD, 0x7B38, 0xF3CE, 0x7B2A,
+	0xF3CF, 0x7B19, 0xF3D0, 0x7B2E, 0xF3D1, 0x7B31, 0xF3D2, 0x7B20,
+	0xF3D3, 0x7B25, 0xF3D4, 0x7B24, 0xF3D5, 0x7B33, 0xF3D6, 0x7B3E,
+	0xF3D7, 0x7B1E, 0xF3D8, 0x7B58, 0xF3D9, 0x7B5A, 0xF3DA, 0x7B45,
+	0xF3DB, 0x7B75, 0xF3DC, 0x7B4C, 0xF3DD, 0x7B5D, 0xF3DE, 0x7B60,
+	0xF3DF, 0x7B6E, 0xF3E0, 0x7B7B, 0xF3E1, 0x7B62, 0xF3E2, 0x7B72,
+	0xF3E3, 0x7B71, 0xF3E4, 0x7B90, 0xF3E5, 0x7BA6, 0xF3E6, 0x7BA7,
+	0xF3E7, 0x7BB8, 0xF3E8, 0x7BAC, 0xF3E9, 0x7B9D, 0xF3EA, 0x7BA8,
+	0xF3EB, 0x7B85, 0xF3EC, 0x7BAA, 0xF3ED, 0x7B9C, 0xF3EE, 0x7BA2,
+	0xF3EF, 0x7BAB, 0xF3F0, 0x7BB4, 0xF3F1, 0x7BD1, 0xF3F2, 0x7BC1,
+	0xF3F3, 0x7BCC, 0xF3F4, 0x7BDD, 0xF3F5, 0x7BDA, 0xF3F6, 0x7BE5,
+	0xF3F7, 0x7BE6, 0xF3F8, 0x7BEA, 0xF3F9, 0x7C0C, 0xF3FA, 0x7BFE,
+	0xF3FB, 0x7BFC, 0xF3FC, 0x7C0F, 0xF3FD, 0x7C16, 0xF3FE, 0x7C0B,
+	0xF440, 0x9B07, 0xF441, 0x9B09, 0xF442, 0x9B0A, 0xF443, 0x9B0B,
+	0xF444, 0x9B0C, 0xF445, 0x9B0D, 0xF446, 0x9B0E, 0xF447, 0x9B10,
+	0xF448, 0x9B11, 0xF449, 0x9B12, 0xF44A, 0x9B14, 0xF44B, 0x9B15,
+	0xF44C, 0x9B16, 0xF44D, 0x9B17, 0xF44E, 0x9B18, 0xF44F, 0x9B19,
+	0xF450, 0x9B1A, 0xF451, 0x9B1B, 0xF452, 0x9B1C, 0xF453, 0x9B1D,
+	0xF454, 0x9B1E, 0xF455, 0x9B20, 0xF456, 0x9B21, 0xF457, 0x9B22,
+	0xF458, 0x9B24, 0xF459, 0x9B25, 0xF45A, 0x9B26, 0xF45B, 0x9B27,
+	0xF45C, 0x9B28, 0xF45D, 0x9B29, 0xF45E, 0x9B2A, 0xF45F, 0x9B2B,
+	0xF460, 0x9B2C, 0xF461, 0x9B2D, 0xF462, 0x9B2E, 0xF463, 0x9B30,
+	0xF464, 0x9B31, 0xF465, 0x9B33, 0xF466, 0x9B34, 0xF467, 0x9B35,
+	0xF468, 0x9B36, 0xF469, 0x9B37, 0xF46A, 0x9B38, 0xF46B, 0x9B39,
+	0xF46C, 0x9B3A, 0xF46D, 0x9B3D, 0xF46E, 0x9B3E, 0xF46F, 0x9B3F,
+	0xF470, 0x9B40, 0xF471, 0x9B46, 0xF472, 0x9B4A, 0xF473, 0x9B4B,
+	0xF474, 0x9B4C, 0xF475, 0x9B4E, 0xF476, 0x9B50, 0xF477, 0x9B52,
+	0xF478, 0x9B53, 0xF479, 0x9B55, 0xF47A, 0x9B56, 0xF47B, 0x9B57,
+	0xF47C, 0x9B58, 0xF47D, 0x9B59, 0xF47E, 0x9B5A, 0xF480, 0x9B5B,
+	0xF481, 0x9B5C, 0xF482, 0x9B5D, 0xF483, 0x9B5E, 0xF484, 0x9B5F,
+	0xF485, 0x9B60, 0xF486, 0x9B61, 0xF487, 0x9B62, 0xF488, 0x9B63,
+	0xF489, 0x9B64, 0xF48A, 0x9B65, 0xF48B, 0x9B66, 0xF48C, 0x9B67,
+	0xF48D, 0x9B68, 0xF48E, 0x9B69, 0xF48F, 0x9B6A, 0xF490, 0x9B6B,
+	0xF491, 0x9B6C, 0xF492, 0x9B6D, 0xF493, 0x9B6E, 0xF494, 0x9B6F,
+	0xF495, 0x9B70, 0xF496, 0x9B71, 0xF497, 0x9B72, 0xF498, 0x9B73,
+	0xF499, 0x9B74, 0xF49A, 0x9B75, 0xF49B, 0x9B76, 0xF49C, 0x9B77,
+	0xF49D, 0x9B78, 0xF49E, 0x9B79, 0xF49F, 0x9B7A, 0xF4A0, 0x9B7B,
+	0xF4A1, 0x7C1F, 0xF4A2, 0x7C2A, 0xF4A3, 0x7C26, 0xF4A4, 0x7C38,
+	0xF4A5, 0x7C41, 0xF4A6, 0x7C40, 0xF4A7, 0x81FE, 0xF4A8, 0x8201,
+	0xF4A9, 0x8202, 0xF4AA, 0x8204, 0xF4AB, 0x81EC, 0xF4AC, 0x8844,
+	0xF4AD, 0x8221, 0xF4AE, 0x8222, 0xF4AF, 0x8223, 0xF4B0, 0x822D,
+	0xF4B1, 0x822F, 0xF4B2, 0x8228, 0xF4B3, 0x822B, 0xF4B4, 0x8238,
+	0xF4B5, 0x823B, 0xF4B6, 0x8233, 0xF4B7, 0x8234, 0xF4B8, 0x823E,
+	0xF4B9, 0x8244, 0xF4BA, 0x8249, 0xF4BB, 0x824B, 0xF4BC, 0x824F,
+	0xF4BD, 0x825A, 0xF4BE, 0x825F, 0xF4BF, 0x8268, 0xF4C0, 0x887E,
+	0xF4C1, 0x8885, 0xF4C2, 0x8888, 0xF4C3, 0x88D8, 0xF4C4, 0x88DF,
+	0xF4C5, 0x895E, 0xF4C6, 0x7F9D, 0xF4C7, 0x7F9F, 0xF4C8, 0x7FA7,
+	0xF4C9, 0x7FAF, 0xF4CA, 0x7FB0, 0xF4CB, 0x7FB2, 0xF4CC, 0x7C7C,
+	0xF4CD, 0x6549, 0xF4CE, 0x7C91, 0xF4CF, 0x7C9D, 0xF4D0, 0x7C9C,
+	0xF4D1, 0x7C9E, 0xF4D2, 0x7CA2, 0xF4D3, 0x7CB2, 0xF4D4, 0x7CBC,
+	0xF4D5, 0x7CBD, 0xF4D6, 0x7CC1, 0xF4D7, 0x7CC7, 0xF4D8, 0x7CCC,
+	0xF4D9, 0x7CCD, 0xF4DA, 0x7CC8, 0xF4DB, 0x7CC5, 0xF4DC, 0x7CD7,
+	0xF4DD, 0x7CE8, 0xF4DE, 0x826E, 0xF4DF, 0x66A8, 0xF4E0, 0x7FBF,
+	0xF4E1, 0x7FCE, 0xF4E2, 0x7FD5, 0xF4E3, 0x7FE5, 0xF4E4, 0x7FE1,
+	0xF4E5, 0x7FE6, 0xF4E6, 0x7FE9, 0xF4E7, 0x7FEE, 0xF4E8, 0x7FF3,
+	0xF4E9, 0x7CF8, 0xF4EA, 0x7D77, 0xF4EB, 0x7DA6, 0xF4EC, 0x7DAE,
+	0xF4ED, 0x7E47, 0xF4EE, 0x7E9B, 0xF4EF, 0x9EB8, 0xF4F0, 0x9EB4,
+	0xF4F1, 0x8D73, 0xF4F2, 0x8D84, 0xF4F3, 0x8D94, 0xF4F4, 0x8D91,
+	0xF4F5, 0x8DB1, 0xF4F6, 0x8D67, 0xF4F7, 0x8D6D, 0xF4F8, 0x8C47,
+	0xF4F9, 0x8C49, 0xF4FA, 0x914A, 0xF4FB, 0x9150, 0xF4FC, 0x914E,
+	0xF4FD, 0x914F, 0xF4FE, 0x9164, 0xF540, 0x9B7C, 0xF541, 0x9B7D,
+	0xF542, 0x9B7E, 0xF543, 0x9B7F, 0xF544, 0x9B80, 0xF545, 0x9B81,
+	0xF546, 0x9B82, 0xF547, 0x9B83, 0xF548, 0x9B84, 0xF549, 0x9B85,
+	0xF54A, 0x9B86, 0xF54B, 0x9B87, 0xF54C, 0x9B88, 0xF54D, 0x9B89,
+	0xF54E, 0x9B8A, 0xF54F, 0x9B8B, 0xF550, 0x9B8C, 0xF551, 0x9B8D,
+	0xF552, 0x9B8E, 0xF553, 0x9B8F, 0xF554, 0x9B90, 0xF555, 0x9B91,
+	0xF556, 0x9B92, 0xF557, 0x9B93, 0xF558, 0x9B94, 0xF559, 0x9B95,
+	0xF55A, 0x9B96, 0xF55B, 0x9B97, 0xF55C, 0x9B98, 0xF55D, 0x9B99,
+	0xF55E, 0x9B9A, 0xF55F, 0x9B9B, 0xF560, 0x9B9C, 0xF561, 0x9B9D,
+	0xF562, 0x9B9E, 0xF563, 0x9B9F, 0xF564, 0x9BA0, 0xF565, 0x9BA1,
+	0xF566, 0x9BA2, 0xF567, 0x9BA3, 0xF568, 0x9BA4, 0xF569, 0x9BA5,
+	0xF56A, 0x9BA6, 0xF56B, 0x9BA7, 0xF56C, 0x9BA8, 0xF56D, 0x9BA9,
+	0xF56E, 0x9BAA, 0xF56F, 0x9BAB, 0xF570, 0x9BAC, 0xF571, 0x9BAD,
+	0xF572, 0x9BAE, 0xF573, 0x9BAF, 0xF574, 0x9BB0, 0xF575, 0x9BB1,
+	0xF576, 0x9BB2, 0xF577, 0x9BB3, 0xF578, 0x9BB4, 0xF579, 0x9BB5,
+	0xF57A, 0x9BB6, 0xF57B, 0x9BB7, 0xF57C, 0x9BB8, 0xF57D, 0x9BB9,
+	0xF57E, 0x9BBA, 0xF580, 0x9BBB, 0xF581, 0x9BBC, 0xF582, 0x9BBD,
+	0xF583, 0x9BBE, 0xF584, 0x9BBF, 0xF585, 0x9BC0, 0xF586, 0x9BC1,
+	0xF587, 0x9BC2, 0xF588, 0x9BC3, 0xF589, 0x9BC4, 0xF58A, 0x9BC5,
+	0xF58B, 0x9BC6, 0xF58C, 0x9BC7, 0xF58D, 0x9BC8, 0xF58E, 0x9BC9,
+	0xF58F, 0x9BCA, 0xF590, 0x9BCB, 0xF591, 0x9BCC, 0xF592, 0x9BCD,
+	0xF593, 0x9BCE, 0xF594, 0x9BCF, 0xF595, 0x9BD0, 0xF596, 0x9BD1,
+	0xF597, 0x9BD2, 0xF598, 0x9BD3, 0xF599, 0x9BD4, 0xF59A, 0x9BD5,
+	0xF59B, 0x9BD6, 0xF59C, 0x9BD7, 0xF59D, 0x9BD8, 0xF59E, 0x9BD9,
+	0xF59F, 0x9BDA, 0xF5A0, 0x9BDB, 0xF5A1, 0x9162, 0xF5A2, 0x9161,
+	0xF5A3, 0x9170, 0xF5A4, 0x9169, 0xF5A5, 0x916F, 0xF5A6, 0x917D,
+	0xF5A7, 0x917E, 0xF5A8, 0x9172, 0xF5A9, 0x9174, 0xF5AA, 0x9179,
+	0xF5AB, 0x918C, 0xF5AC, 0x9185, 0xF5AD, 0x9190, 0xF5AE, 0x918D,
+	0xF5AF, 0x9191, 0xF5B0, 0x91A2, 0xF5B1, 0x91A3, 0xF5B2, 0x91AA,
+	0xF5B3, 0x91AD, 0xF5B4, 0x91AE, 0xF5B5, 0x91AF, 0xF5B6, 0x91B5,
+	0xF5B7, 0x91B4, 0xF5B8, 0x91BA, 0xF5B9, 0x8C55, 0xF5BA, 0x9E7E,
+	0xF5BB, 0x8DB8, 0xF5BC, 0x8DEB, 0xF5BD, 0x8E05, 0xF5BE, 0x8E59,
+	0xF5BF, 0x8E69, 0xF5C0, 0x8DB5, 0xF5C1, 0x8DBF, 0xF5C2, 0x8DBC,
+	0xF5C3, 0x8DBA, 0xF5C4, 0x8DC4, 0xF5C5, 0x8DD6, 0xF5C6, 0x8DD7,
+	0xF5C7, 0x8DDA, 0xF5C8, 0x8DDE, 0xF5C9, 0x8DCE, 0xF5CA, 0x8DCF,
+	0xF5CB, 0x8DDB, 0xF5CC, 0x8DC6, 0xF5CD, 0x8DEC, 0xF5CE, 0x8DF7,
+	0xF5CF, 0x8DF8, 0xF5D0, 0x8DE3, 0xF5D1, 0x8DF9, 0xF5D2, 0x8DFB,
+	0xF5D3, 0x8DE4, 0xF5D4, 0x8E09, 0xF5D5, 0x8DFD, 0xF5D6, 0x8E14,
+	0xF5D7, 0x8E1D, 0xF5D8, 0x8E1F, 0xF5D9, 0x8E2C, 0xF5DA, 0x8E2E,
+	0xF5DB, 0x8E23, 0xF5DC, 0x8E2F, 0xF5DD, 0x8E3A, 0xF5DE, 0x8E40,
+	0xF5DF, 0x8E39, 0xF5E0, 0x8E35, 0xF5E1, 0x8E3D, 0xF5E2, 0x8E31,
+	0xF5E3, 0x8E49, 0xF5E4, 0x8E41, 0xF5E5, 0x8E42, 0xF5E6, 0x8E51,
+	0xF5E7, 0x8E52, 0xF5E8, 0x8E4A, 0xF5E9, 0x8E70, 0xF5EA, 0x8E76,
+	0xF5EB, 0x8E7C, 0xF5EC, 0x8E6F, 0xF5ED, 0x8E74, 0xF5EE, 0x8E85,
+	0xF5EF, 0x8E8F, 0xF5F0, 0x8E94, 0xF5F1, 0x8E90, 0xF5F2, 0x8E9C,
+	0xF5F3, 0x8E9E, 0xF5F4, 0x8C78, 0xF5F5, 0x8C82, 0xF5F6, 0x8C8A,
+	0xF5F7, 0x8C85, 0xF5F8, 0x8C98, 0xF5F9, 0x8C94, 0xF5FA, 0x659B,
+	0xF5FB, 0x89D6, 0xF5FC, 0x89DE, 0xF5FD, 0x89DA, 0xF5FE, 0x89DC,
+	0xF640, 0x9BDC, 0xF641, 0x9BDD, 0xF642, 0x9BDE, 0xF643, 0x9BDF,
+	0xF644, 0x9BE0, 0xF645, 0x9BE1, 0xF646, 0x9BE2, 0xF647, 0x9BE3,
+	0xF648, 0x9BE4, 0xF649, 0x9BE5, 0xF64A, 0x9BE6, 0xF64B, 0x9BE7,
+	0xF64C, 0x9BE8, 0xF64D, 0x9BE9, 0xF64E, 0x9BEA, 0xF64F, 0x9BEB,
+	0xF650, 0x9BEC, 0xF651, 0x9BED, 0xF652, 0x9BEE, 0xF653, 0x9BEF,
+	0xF654, 0x9BF0, 0xF655, 0x9BF1, 0xF656, 0x9BF2, 0xF657, 0x9BF3,
+	0xF658, 0x9BF4, 0xF659, 0x9BF5, 0xF65A, 0x9BF6, 0xF65B, 0x9BF7,
+	0xF65C, 0x9BF8, 0xF65D, 0x9BF9, 0xF65E, 0x9BFA, 0xF65F, 0x9BFB,
+	0xF660, 0x9BFC, 0xF661, 0x9BFD, 0xF662, 0x9BFE, 0xF663, 0x9BFF,
+	0xF664, 0x9C00, 0xF665, 0x9C01, 0xF666, 0x9C02, 0xF667, 0x9C03,
+	0xF668, 0x9C04, 0xF669, 0x9C05, 0xF66A, 0x9C06, 0xF66B, 0x9C07,
+	0xF66C, 0x9C08, 0xF66D, 0x9C09, 0xF66E, 0x9C0A, 0xF66F, 0x9C0B,
+	0xF670, 0x9C0C, 0xF671, 0x9C0D, 0xF672, 0x9C0E, 0xF673, 0x9C0F,
+	0xF674, 0x9C10, 0xF675, 0x9C11, 0xF676, 0x9C12, 0xF677, 0x9C13,
+	0xF678, 0x9C14, 0xF679, 0x9C15, 0xF67A, 0x9C16, 0xF67B, 0x9C17,
+	0xF67C, 0x9C18, 0xF67D, 0x9C19, 0xF67E, 0x9C1A, 0xF680, 0x9C1B,
+	0xF681, 0x9C1C, 0xF682, 0x9C1D, 0xF683, 0x9C1E, 0xF684, 0x9C1F,
+	0xF685, 0x9C20, 0xF686, 0x9C21, 0xF687, 0x9C22, 0xF688, 0x9C23,
+	0xF689, 0x9C24, 0xF68A, 0x9C25, 0xF68B, 0x9C26, 0xF68C, 0x9C27,
+	0xF68D, 0x9C28, 0xF68E, 0x9C29, 0xF68F, 0x9C2A, 0xF690, 0x9C2B,
+	0xF691, 0x9C2C, 0xF692, 0x9C2D, 0xF693, 0x9C2E, 0xF694, 0x9C2F,
+	0xF695, 0x9C30, 0xF696, 0x9C31, 0xF697, 0x9C32, 0xF698, 0x9C33,
+	0xF699, 0x9C34, 0xF69A, 0x9C35, 0xF69B, 0x9C36, 0xF69C, 0x9C37,
+	0xF69D, 0x9C38, 0xF69E, 0x9C39, 0xF69F, 0x9C3A, 0xF6A0, 0x9C3B,
+	0xF6A1, 0x89E5, 0xF6A2, 0x89EB, 0xF6A3, 0x89EF, 0xF6A4, 0x8A3E,
+	0xF6A5, 0x8B26, 0xF6A6, 0x9753, 0xF6A7, 0x96E9, 0xF6A8, 0x96F3,
+	0xF6A9, 0x96EF, 0xF6AA, 0x9706, 0xF6AB, 0x9701, 0xF6AC, 0x9708,
+	0xF6AD, 0x970F, 0xF6AE, 0x970E, 0xF6AF, 0x972A, 0xF6B0, 0x972D,
+	0xF6B1, 0x9730, 0xF6B2, 0x973E, 0xF6B3, 0x9F80, 0xF6B4, 0x9F83,
+	0xF6B5, 0x9F85, 0xF6B6, 0x9F86, 0xF6B7, 0x9F87, 0xF6B8, 0x9F88,
+	0xF6B9, 0x9F89, 0xF6BA, 0x9F8A, 0xF6BB, 0x9F8C, 0xF6BC, 0x9EFE,
+	0xF6BD, 0x9F0B, 0xF6BE, 0x9F0D, 0xF6BF, 0x96B9, 0xF6C0, 0x96BC,
+	0xF6C1, 0x96BD, 0xF6C2, 0x96CE, 0xF6C3, 0x96D2, 0xF6C4, 0x77BF,
+	0xF6C5, 0x96E0, 0xF6C6, 0x928E, 0xF6C7, 0x92AE, 0xF6C8, 0x92C8,
+	0xF6C9, 0x933E, 0xF6CA, 0x936A, 0xF6CB, 0x93CA, 0xF6CC, 0x938F,
+	0xF6CD, 0x943E, 0xF6CE, 0x946B, 0xF6CF, 0x9C7F, 0xF6D0, 0x9C82,
+	0xF6D1, 0x9C85, 0xF6D2, 0x9C86, 0xF6D3, 0x9C87, 0xF6D4, 0x9C88,
+	0xF6D5, 0x7A23, 0xF6D6, 0x9C8B, 0xF6D7, 0x9C8E, 0xF6D8, 0x9C90,
+	0xF6D9, 0x9C91, 0xF6DA, 0x9C92, 0xF6DB, 0x9C94, 0xF6DC, 0x9C95,
+	0xF6DD, 0x9C9A, 0xF6DE, 0x9C9B, 0xF6DF, 0x9C9E, 0xF6E0, 0x9C9F,
+	0xF6E1, 0x9CA0, 0xF6E2, 0x9CA1, 0xF6E3, 0x9CA2, 0xF6E4, 0x9CA3,
+	0xF6E5, 0x9CA5, 0xF6E6, 0x9CA6, 0xF6E7, 0x9CA7, 0xF6E8, 0x9CA8,
+	0xF6E9, 0x9CA9, 0xF6EA, 0x9CAB, 0xF6EB, 0x9CAD, 0xF6EC, 0x9CAE,
+	0xF6ED, 0x9CB0, 0xF6EE, 0x9CB1, 0xF6EF, 0x9CB2, 0xF6F0, 0x9CB3,
+	0xF6F1, 0x9CB4, 0xF6F2, 0x9CB5, 0xF6F3, 0x9CB6, 0xF6F4, 0x9CB7,
+	0xF6F5, 0x9CBA, 0xF6F6, 0x9CBB, 0xF6F7, 0x9CBC, 0xF6F8, 0x9CBD,
+	0xF6F9, 0x9CC4, 0xF6FA, 0x9CC5, 0xF6FB, 0x9CC6, 0xF6FC, 0x9CC7,
+	0xF6FD, 0x9CCA, 0xF6FE, 0x9CCB, 0xF740, 0x9C3C, 0xF741, 0x9C3D,
+	0xF742, 0x9C3E, 0xF743, 0x9C3F, 0xF744, 0x9C40, 0xF745, 0x9C41,
+	0xF746, 0x9C42, 0xF747, 0x9C43, 0xF748, 0x9C44, 0xF749, 0x9C45,
+	0xF74A, 0x9C46, 0xF74B, 0x9C47, 0xF74C, 0x9C48, 0xF74D, 0x9C49,
+	0xF74E, 0x9C4A, 0xF74F, 0x9C4B, 0xF750, 0x9C4C, 0xF751, 0x9C4D,
+	0xF752, 0x9C4E, 0xF753, 0x9C4F, 0xF754, 0x9C50, 0xF755, 0x9C51,
+	0xF756, 0x9C52, 0xF757, 0x9C53, 0xF758, 0x9C54, 0xF759, 0x9C55,
+	0xF75A, 0x9C56, 0xF75B, 0x9C57, 0xF75C, 0x9C58, 0xF75D, 0x9C59,
+	0xF75E, 0x9C5A, 0xF75F, 0x9C5B, 0xF760, 0x9C5C, 0xF761, 0x9C5D,
+	0xF762, 0x9C5E, 0xF763, 0x9C5F, 0xF764, 0x9C60, 0xF765, 0x9C61,
+	0xF766, 0x9C62, 0xF767, 0x9C63, 0xF768, 0x9C64, 0xF769, 0x9C65,
+	0xF76A, 0x9C66, 0xF76B, 0x9C67, 0xF76C, 0x9C68, 0xF76D, 0x9C69,
+	0xF76E, 0x9C6A, 0xF76F, 0x9C6B, 0xF770, 0x9C6C, 0xF771, 0x9C6D,
+	0xF772, 0x9C6E, 0xF773, 0x9C6F, 0xF774, 0x9C70, 0xF775, 0x9C71,
+	0xF776, 0x9C72, 0xF777, 0x9C73, 0xF778, 0x9C74, 0xF779, 0x9C75,
+	0xF77A, 0x9C76, 0xF77B, 0x9C77, 0xF77C, 0x9C78, 0xF77D, 0x9C79,
+	0xF77E, 0x9C7A, 0xF780, 0x9C7B, 0xF781, 0x9C7D, 0xF782, 0x9C7E,
+	0xF783, 0x9C80, 0xF784, 0x9C83, 0xF785, 0x9C84, 0xF786, 0x9C89,
+	0xF787, 0x9C8A, 0xF788, 0x9C8C, 0xF789, 0x9C8F, 0xF78A, 0x9C93,
+	0xF78B, 0x9C96, 0xF78C, 0x9C97, 0xF78D, 0x9C98, 0xF78E, 0x9C99,
+	0xF78F, 0x9C9D, 0xF790, 0x9CAA, 0xF791, 0x9CAC, 0xF792, 0x9CAF,
+	0xF793, 0x9CB9, 0xF794, 0x9CBE, 0xF795, 0x9CBF, 0xF796, 0x9CC0,
+	0xF797, 0x9CC1, 0xF798, 0x9CC2, 0xF799, 0x9CC8, 0xF79A, 0x9CC9,
+	0xF79B, 0x9CD1, 0xF79C, 0x9CD2, 0xF79D, 0x9CDA, 0xF79E, 0x9CDB,
+	0xF79F, 0x9CE0, 0xF7A0, 0x9CE1, 0xF7A1, 0x9CCC, 0xF7A2, 0x9CCD,
+	0xF7A3, 0x9CCE, 0xF7A4, 0x9CCF, 0xF7A5, 0x9CD0, 0xF7A6, 0x9CD3,
+	0xF7A7, 0x9CD4, 0xF7A8, 0x9CD5, 0xF7A9, 0x9CD7, 0xF7AA, 0x9CD8,
+	0xF7AB, 0x9CD9, 0xF7AC, 0x9CDC, 0xF7AD, 0x9CDD, 0xF7AE, 0x9CDF,
+	0xF7AF, 0x9CE2, 0xF7B0, 0x977C, 0xF7B1, 0x9785, 0xF7B2, 0x9791,
+	0xF7B3, 0x9792, 0xF7B4, 0x9794, 0xF7B5, 0x97AF, 0xF7B6, 0x97AB,
+	0xF7B7, 0x97A3, 0xF7B8, 0x97B2, 0xF7B9, 0x97B4, 0xF7BA, 0x9AB1,
+	0xF7BB, 0x9AB0, 0xF7BC, 0x9AB7, 0xF7BD, 0x9E58, 0xF7BE, 0x9AB6,
+	0xF7BF, 0x9ABA, 0xF7C0, 0x9ABC, 0xF7C1, 0x9AC1, 0xF7C2, 0x9AC0,
+	0xF7C3, 0x9AC5, 0xF7C4, 0x9AC2, 0xF7C5, 0x9ACB, 0xF7C6, 0x9ACC,
+	0xF7C7, 0x9AD1, 0xF7C8, 0x9B45, 0xF7C9, 0x9B43, 0xF7CA, 0x9B47,
+	0xF7CB, 0x9B49, 0xF7CC, 0x9B48, 0xF7CD, 0x9B4D, 0xF7CE, 0x9B51,
+	0xF7CF, 0x98E8, 0xF7D0, 0x990D, 0xF7D1, 0x992E, 0xF7D2, 0x9955,
+	0xF7D3, 0x9954, 0xF7D4, 0x9ADF, 0xF7D5, 0x9AE1, 0xF7D6, 0x9AE6,
+	0xF7D7, 0x9AEF, 0xF7D8, 0x9AEB, 0xF7D9, 0x9AFB, 0xF7DA, 0x9AED,
+	0xF7DB, 0x9AF9, 0xF7DC, 0x9B08, 0xF7DD, 0x9B0F, 0xF7DE, 0x9B13,
+	0xF7DF, 0x9B1F, 0xF7E0, 0x9B23, 0xF7E1, 0x9EBD, 0xF7E2, 0x9EBE,
+	0xF7E3, 0x7E3B, 0xF7E4, 0x9E82, 0xF7E5, 0x9E87, 0xF7E6, 0x9E88,
+	0xF7E7, 0x9E8B, 0xF7E8, 0x9E92, 0xF7E9, 0x93D6, 0xF7EA, 0x9E9D,
+	0xF7EB, 0x9E9F, 0xF7EC, 0x9EDB, 0xF7ED, 0x9EDC, 0xF7EE, 0x9EDD,
+	0xF7EF, 0x9EE0, 0xF7F0, 0x9EDF, 0xF7F1, 0x9EE2, 0xF7F2, 0x9EE9,
+	0xF7F3, 0x9EE7, 0xF7F4, 0x9EE5, 0xF7F5, 0x9EEA, 0xF7F6, 0x9EEF,
+	0xF7F7, 0x9F22, 0xF7F8, 0x9F2C, 0xF7F9, 0x9F2F, 0xF7FA, 0x9F39,
+	0xF7FB, 0x9F37, 0xF7FC, 0x9F3D, 0xF7FD, 0x9F3E, 0xF7FE, 0x9F44,
+	0xF840, 0x9CE3, 0xF841, 0x9CE4, 0xF842, 0x9CE5, 0xF843, 0x9CE6,
+	0xF844, 0x9CE7, 0xF845, 0x9CE8, 0xF846, 0x9CE9, 0xF847, 0x9CEA,
+	0xF848, 0x9CEB, 0xF849, 0x9CEC, 0xF84A, 0x9CED, 0xF84B, 0x9CEE,
+	0xF84C, 0x9CEF, 0xF84D, 0x9CF0, 0xF84E, 0x9CF1, 0xF84F, 0x9CF2,
+	0xF850, 0x9CF3, 0xF851, 0x9CF4, 0xF852, 0x9CF5, 0xF853, 0x9CF6,
+	0xF854, 0x9CF7, 0xF855, 0x9CF8, 0xF856, 0x9CF9, 0xF857, 0x9CFA,
+	0xF858, 0x9CFB, 0xF859, 0x9CFC, 0xF85A, 0x9CFD, 0xF85B, 0x9CFE,
+	0xF85C, 0x9CFF, 0xF85D, 0x9D00, 0xF85E, 0x9D01, 0xF85F, 0x9D02,
+	0xF860, 0x9D03, 0xF861, 0x9D04, 0xF862, 0x9D05, 0xF863, 0x9D06,
+	0xF864, 0x9D07, 0xF865, 0x9D08, 0xF866, 0x9D09, 0xF867, 0x9D0A,
+	0xF868, 0x9D0B, 0xF869, 0x9D0C, 0xF86A, 0x9D0D, 0xF86B, 0x9D0E,
+	0xF86C, 0x9D0F, 0xF86D, 0x9D10, 0xF86E, 0x9D11, 0xF86F, 0x9D12,
+	0xF870, 0x9D13, 0xF871, 0x9D14, 0xF872, 0x9D15, 0xF873, 0x9D16,
+	0xF874, 0x9D17, 0xF875, 0x9D18, 0xF876, 0x9D19, 0xF877, 0x9D1A,
+	0xF878, 0x9D1B, 0xF879, 0x9D1C, 0xF87A, 0x9D1D, 0xF87B, 0x9D1E,
+	0xF87C, 0x9D1F, 0xF87D, 0x9D20, 0xF87E, 0x9D21, 0xF880, 0x9D22,
+	0xF881, 0x9D23, 0xF882, 0x9D24, 0xF883, 0x9D25, 0xF884, 0x9D26,
+	0xF885, 0x9D27, 0xF886, 0x9D28, 0xF887, 0x9D29, 0xF888, 0x9D2A,
+	0xF889, 0x9D2B, 0xF88A, 0x9D2C, 0xF88B, 0x9D2D, 0xF88C, 0x9D2E,
+	0xF88D, 0x9D2F, 0xF88E, 0x9D30, 0xF88F, 0x9D31, 0xF890, 0x9D32,
+	0xF891, 0x9D33, 0xF892, 0x9D34, 0xF893, 0x9D35, 0xF894, 0x9D36,
+	0xF895, 0x9D37, 0xF896, 0x9D38, 0xF897, 0x9D39, 0xF898, 0x9D3A,
+	0xF899, 0x9D3B, 0xF89A, 0x9D3C, 0xF89B, 0x9D3D, 0xF89C, 0x9D3E,
+	0xF89D, 0x9D3F, 0xF89E, 0x9D40, 0xF89F, 0x9D41, 0xF8A0, 0x9D42,
+	0xF940, 0x9D43, 0xF941, 0x9D44, 0xF942, 0x9D45, 0xF943, 0x9D46,
+	0xF944, 0x9D47, 0xF945, 0x9D48, 0xF946, 0x9D49, 0xF947, 0x9D4A,
+	0xF948, 0x9D4B, 0xF949, 0x9D4C, 0xF94A, 0x9D4D, 0xF94B, 0x9D4E,
+	0xF94C, 0x9D4F, 0xF94D, 0x9D50, 0xF94E, 0x9D51, 0xF94F, 0x9D52,
+	0xF950, 0x9D53, 0xF951, 0x9D54, 0xF952, 0x9D55, 0xF953, 0x9D56,
+	0xF954, 0x9D57, 0xF955, 0x9D58, 0xF956, 0x9D59, 0xF957, 0x9D5A,
+	0xF958, 0x9D5B, 0xF959, 0x9D5C, 0xF95A, 0x9D5D, 0xF95B, 0x9D5E,
+	0xF95C, 0x9D5F, 0xF95D, 0x9D60, 0xF95E, 0x9D61, 0xF95F, 0x9D62,
+	0xF960, 0x9D63, 0xF961, 0x9D64, 0xF962, 0x9D65, 0xF963, 0x9D66,
+	0xF964, 0x9D67, 0xF965, 0x9D68, 0xF966, 0x9D69, 0xF967, 0x9D6A,
+	0xF968, 0x9D6B, 0xF969, 0x9D6C, 0xF96A, 0x9D6D, 0xF96B, 0x9D6E,
+	0xF96C, 0x9D6F, 0xF96D, 0x9D70, 0xF96E, 0x9D71, 0xF96F, 0x9D72,
+	0xF970, 0x9D73, 0xF971, 0x9D74, 0xF972, 0x9D75, 0xF973, 0x9D76,
+	0xF974, 0x9D77, 0xF975, 0x9D78, 0xF976, 0x9D79, 0xF977, 0x9D7A,
+	0xF978, 0x9D7B, 0xF979, 0x9D7C, 0xF97A, 0x9D7D, 0xF97B, 0x9D7E,
+	0xF97C, 0x9D7F, 0xF97D, 0x9D80, 0xF97E, 0x9D81, 0xF980, 0x9D82,
+	0xF981, 0x9D83, 0xF982, 0x9D84, 0xF983, 0x9D85, 0xF984, 0x9D86,
+	0xF985, 0x9D87, 0xF986, 0x9D88, 0xF987, 0x9D89, 0xF988, 0x9D8A,
+	0xF989, 0x9D8B, 0xF98A, 0x9D8C, 0xF98B, 0x9D8D, 0xF98C, 0x9D8E,
+	0xF98D, 0x9D8F, 0xF98E, 0x9D90, 0xF98F, 0x9D91, 0xF990, 0x9D92,
+	0xF991, 0x9D93, 0xF992, 0x9D94, 0xF993, 0x9D95, 0xF994, 0x9D96,
+	0xF995, 0x9D97, 0xF996, 0x9D98, 0xF997, 0x9D99, 0xF998, 0x9D9A,
+	0xF999, 0x9D9B, 0xF99A, 0x9D9C, 0xF99B, 0x9D9D, 0xF99C, 0x9D9E,
+	0xF99D, 0x9D9F, 0xF99E, 0x9DA0, 0xF99F, 0x9DA1, 0xF9A0, 0x9DA2,
+	0xFA40, 0x9DA3, 0xFA41, 0x9DA4, 0xFA42, 0x9DA5, 0xFA43, 0x9DA6,
+	0xFA44, 0x9DA7, 0xFA45, 0x9DA8, 0xFA46, 0x9DA9, 0xFA47, 0x9DAA,
+	0xFA48, 0x9DAB, 0xFA49, 0x9DAC, 0xFA4A, 0x9DAD, 0xFA4B, 0x9DAE,
+	0xFA4C, 0x9DAF, 0xFA4D, 0x9DB0, 0xFA4E, 0x9DB1, 0xFA4F, 0x9DB2,
+	0xFA50, 0x9DB3, 0xFA51, 0x9DB4, 0xFA52, 0x9DB5, 0xFA53, 0x9DB6,
+	0xFA54, 0x9DB7, 0xFA55, 0x9DB8, 0xFA56, 0x9DB9, 0xFA57, 0x9DBA,
+	0xFA58, 0x9DBB, 0xFA59, 0x9DBC, 0xFA5A, 0x9DBD, 0xFA5B, 0x9DBE,
+	0xFA5C, 0x9DBF, 0xFA5D, 0x9DC0, 0xFA5E, 0x9DC1, 0xFA5F, 0x9DC2,
+	0xFA60, 0x9DC3, 0xFA61, 0x9DC4, 0xFA62, 0x9DC5, 0xFA63, 0x9DC6,
+	0xFA64, 0x9DC7, 0xFA65, 0x9DC8, 0xFA66, 0x9DC9, 0xFA67, 0x9DCA,
+	0xFA68, 0x9DCB, 0xFA69, 0x9DCC, 0xFA6A, 0x9DCD, 0xFA6B, 0x9DCE,
+	0xFA6C, 0x9DCF, 0xFA6D, 0x9DD0, 0xFA6E, 0x9DD1, 0xFA6F, 0x9DD2,
+	0xFA70, 0x9DD3, 0xFA71, 0x9DD4, 0xFA72, 0x9DD5, 0xFA73, 0x9DD6,
+	0xFA74, 0x9DD7, 0xFA75, 0x9DD8, 0xFA76, 0x9DD9, 0xFA77, 0x9DDA,
+	0xFA78, 0x9DDB, 0xFA79, 0x9DDC, 0xFA7A, 0x9DDD, 0xFA7B, 0x9DDE,
+	0xFA7C, 0x9DDF, 0xFA7D, 0x9DE0, 0xFA7E, 0x9DE1, 0xFA80, 0x9DE2,
+	0xFA81, 0x9DE3, 0xFA82, 0x9DE4, 0xFA83, 0x9DE5, 0xFA84, 0x9DE6,
+	0xFA85, 0x9DE7, 0xFA86, 0x9DE8, 0xFA87, 0x9DE9, 0xFA88, 0x9DEA,
+	0xFA89, 0x9DEB, 0xFA8A, 0x9DEC, 0xFA8B, 0x9DED, 0xFA8C, 0x9DEE,
+	0xFA8D, 0x9DEF, 0xFA8E, 0x9DF0, 0xFA8F, 0x9DF1, 0xFA90, 0x9DF2,
+	0xFA91, 0x9DF3, 0xFA92, 0x9DF4, 0xFA93, 0x9DF5, 0xFA94, 0x9DF6,
+	0xFA95, 0x9DF7, 0xFA96, 0x9DF8, 0xFA97, 0x9DF9, 0xFA98, 0x9DFA,
+	0xFA99, 0x9DFB, 0xFA9A, 0x9DFC, 0xFA9B, 0x9DFD, 0xFA9C, 0x9DFE,
+	0xFA9D, 0x9DFF, 0xFA9E, 0x9E00, 0xFA9F, 0x9E01, 0xFAA0, 0x9E02,
+	0xFB40, 0x9E03, 0xFB41, 0x9E04, 0xFB42, 0x9E05, 0xFB43, 0x9E06,
+	0xFB44, 0x9E07, 0xFB45, 0x9E08, 0xFB46, 0x9E09, 0xFB47, 0x9E0A,
+	0xFB48, 0x9E0B, 0xFB49, 0x9E0C, 0xFB4A, 0x9E0D, 0xFB4B, 0x9E0E,
+	0xFB4C, 0x9E0F, 0xFB4D, 0x9E10, 0xFB4E, 0x9E11, 0xFB4F, 0x9E12,
+	0xFB50, 0x9E13, 0xFB51, 0x9E14, 0xFB52, 0x9E15, 0xFB53, 0x9E16,
+	0xFB54, 0x9E17, 0xFB55, 0x9E18, 0xFB56, 0x9E19, 0xFB57, 0x9E1A,
+	0xFB58, 0x9E1B, 0xFB59, 0x9E1C, 0xFB5A, 0x9E1D, 0xFB5B, 0x9E1E,
+	0xFB5C, 0x9E24, 0xFB5D, 0x9E27, 0xFB5E, 0x9E2E, 0xFB5F, 0x9E30,
+	0xFB60, 0x9E34, 0xFB61, 0x9E3B, 0xFB62, 0x9E3C, 0xFB63, 0x9E40,
+	0xFB64, 0x9E4D, 0xFB65, 0x9E50, 0xFB66, 0x9E52, 0xFB67, 0x9E53,
+	0xFB68, 0x9E54, 0xFB69, 0x9E56, 0xFB6A, 0x9E59, 0xFB6B, 0x9E5D,
+	0xFB6C, 0x9E5F, 0xFB6D, 0x9E60, 0xFB6E, 0x9E61, 0xFB6F, 0x9E62,
+	0xFB70, 0x9E65, 0xFB71, 0x9E6E, 0xFB72, 0x9E6F, 0xFB73, 0x9E72,
+	0xFB74, 0x9E74, 0xFB75, 0x9E75, 0xFB76, 0x9E76, 0xFB77, 0x9E77,
+	0xFB78, 0x9E78, 0xFB79, 0x9E79, 0xFB7A, 0x9E7A, 0xFB7B, 0x9E7B,
+	0xFB7C, 0x9E7C, 0xFB7D, 0x9E7D, 0xFB7E, 0x9E80, 0xFB80, 0x9E81,
+	0xFB81, 0x9E83, 0xFB82, 0x9E84, 0xFB83, 0x9E85, 0xFB84, 0x9E86,
+	0xFB85, 0x9E89, 0xFB86, 0x9E8A, 0xFB87, 0x9E8C, 0xFB88, 0x9E8D,
+	0xFB89, 0x9E8E, 0xFB8A, 0x9E8F, 0xFB8B, 0x9E90, 0xFB8C, 0x9E91,
+	0xFB8D, 0x9E94, 0xFB8E, 0x9E95, 0xFB8F, 0x9E96, 0xFB90, 0x9E97,
+	0xFB91, 0x9E98, 0xFB92, 0x9E99, 0xFB93, 0x9E9A, 0xFB94, 0x9E9B,
+	0xFB95, 0x9E9C, 0xFB96, 0x9E9E, 0xFB97, 0x9EA0, 0xFB98, 0x9EA1,
+	0xFB99, 0x9EA2, 0xFB9A, 0x9EA3, 0xFB9B, 0x9EA4, 0xFB9C, 0x9EA5,
+	0xFB9D, 0x9EA7, 0xFB9E, 0x9EA8, 0xFB9F, 0x9EA9, 0xFBA0, 0x9EAA,
+	0xFC40, 0x9EAB, 0xFC41, 0x9EAC, 0xFC42, 0x9EAD, 0xFC43, 0x9EAE,
+	0xFC44, 0x9EAF, 0xFC45, 0x9EB0, 0xFC46, 0x9EB1, 0xFC47, 0x9EB2,
+	0xFC48, 0x9EB3, 0xFC49, 0x9EB5, 0xFC4A, 0x9EB6, 0xFC4B, 0x9EB7,
+	0xFC4C, 0x9EB9, 0xFC4D, 0x9EBA, 0xFC4E, 0x9EBC, 0xFC4F, 0x9EBF,
+	0xFC50, 0x9EC0, 0xFC51, 0x9EC1, 0xFC52, 0x9EC2, 0xFC53, 0x9EC3,
+	0xFC54, 0x9EC5, 0xFC55, 0x9EC6, 0xFC56, 0x9EC7, 0xFC57, 0x9EC8,
+	0xFC58, 0x9ECA, 0xFC59, 0x9ECB, 0xFC5A, 0x9ECC, 0xFC5B, 0x9ED0,
+	0xFC5C, 0x9ED2, 0xFC5D, 0x9ED3, 0xFC5E, 0x9ED5, 0xFC5F, 0x9ED6,
+	0xFC60, 0x9ED7, 0xFC61, 0x9ED9, 0xFC62, 0x9EDA, 0xFC63, 0x9EDE,
+	0xFC64, 0x9EE1, 0xFC65, 0x9EE3, 0xFC66, 0x9EE4, 0xFC67, 0x9EE6,
+	0xFC68, 0x9EE8, 0xFC69, 0x9EEB, 0xFC6A, 0x9EEC, 0xFC6B, 0x9EED,
+	0xFC6C, 0x9EEE, 0xFC6D, 0x9EF0, 0xFC6E, 0x9EF1, 0xFC6F, 0x9EF2,
+	0xFC70, 0x9EF3, 0xFC71, 0x9EF4, 0xFC72, 0x9EF5, 0xFC73, 0x9EF6,
+	0xFC74, 0x9EF7, 0xFC75, 0x9EF8, 0xFC76, 0x9EFA, 0xFC77, 0x9EFD,
+	0xFC78, 0x9EFF, 0xFC79, 0x9F00, 0xFC7A, 0x9F01, 0xFC7B, 0x9F02,
+	0xFC7C, 0x9F03, 0xFC7D, 0x9F04, 0xFC7E, 0x9F05, 0xFC80, 0x9F06,
+	0xFC81, 0x9F07, 0xFC82, 0x9F08, 0xFC83, 0x9F09, 0xFC84, 0x9F0A,
+	0xFC85, 0x9F0C, 0xFC86, 0x9F0F, 0xFC87, 0x9F11, 0xFC88, 0x9F12,
+	0xFC89, 0x9F14, 0xFC8A, 0x9F15, 0xFC8B, 0x9F16, 0xFC8C, 0x9F18,
+	0xFC8D, 0x9F1A, 0xFC8E, 0x9F1B, 0xFC8F, 0x9F1C, 0xFC90, 0x9F1D,
+	0xFC91, 0x9F1E, 0xFC92, 0x9F1F, 0xFC93, 0x9F21, 0xFC94, 0x9F23,
+	0xFC95, 0x9F24, 0xFC96, 0x9F25, 0xFC97, 0x9F26, 0xFC98, 0x9F27,
+	0xFC99, 0x9F28, 0xFC9A, 0x9F29, 0xFC9B, 0x9F2A, 0xFC9C, 0x9F2B,
+	0xFC9D, 0x9F2D, 0xFC9E, 0x9F2E, 0xFC9F, 0x9F30, 0xFCA0, 0x9F31,
+	0xFD40, 0x9F32, 0xFD41, 0x9F33, 0xFD42, 0x9F34, 0xFD43, 0x9F35,
+	0xFD44, 0x9F36, 0xFD45, 0x9F38, 0xFD46, 0x9F3A, 0xFD47, 0x9F3C,
+	0xFD48, 0x9F3F, 0xFD49, 0x9F40, 0xFD4A, 0x9F41, 0xFD4B, 0x9F42,
+	0xFD4C, 0x9F43, 0xFD4D, 0x9F45, 0xFD4E, 0x9F46, 0xFD4F, 0x9F47,
+	0xFD50, 0x9F48, 0xFD51, 0x9F49, 0xFD52, 0x9F4A, 0xFD53, 0x9F4B,
+	0xFD54, 0x9F4C, 0xFD55, 0x9F4D, 0xFD56, 0x9F4E, 0xFD57, 0x9F4F,
+	0xFD58, 0x9F52, 0xFD59, 0x9F53, 0xFD5A, 0x9F54, 0xFD5B, 0x9F55,
+	0xFD5C, 0x9F56, 0xFD5D, 0x9F57, 0xFD5E, 0x9F58, 0xFD5F, 0x9F59,
+	0xFD60, 0x9F5A, 0xFD61, 0x9F5B, 0xFD62, 0x9F5C, 0xFD63, 0x9F5D,
+	0xFD64, 0x9F5E, 0xFD65, 0x9F5F, 0xFD66, 0x9F60, 0xFD67, 0x9F61,
+	0xFD68, 0x9F62, 0xFD69, 0x9F63, 0xFD6A, 0x9F64, 0xFD6B, 0x9F65,
+	0xFD6C, 0x9F66, 0xFD6D, 0x9F67, 0xFD6E, 0x9F68, 0xFD6F, 0x9F69,
+	0xFD70, 0x9F6A, 0xFD71, 0x9F6B, 0xFD72, 0x9F6C, 0xFD73, 0x9F6D,
+	0xFD74, 0x9F6E, 0xFD75, 0x9F6F, 0xFD76, 0x9F70, 0xFD77, 0x9F71,
+	0xFD78, 0x9F72, 0xFD79, 0x9F73, 0xFD7A, 0x9F74, 0xFD7B, 0x9F75,
+	0xFD7C, 0x9F76, 0xFD7D, 0x9F77, 0xFD7E, 0x9F78, 0xFD80, 0x9F79,
+	0xFD81, 0x9F7A, 0xFD82, 0x9F7B, 0xFD83, 0x9F7C, 0xFD84, 0x9F7D,
+	0xFD85, 0x9F7E, 0xFD86, 0x9F81, 0xFD87, 0x9F82, 0xFD88, 0x9F8D,
+	0xFD89, 0x9F8E, 0xFD8A, 0x9F8F, 0xFD8B, 0x9F90, 0xFD8C, 0x9F91,
+	0xFD8D, 0x9F92, 0xFD8E, 0x9F93, 0xFD8F, 0x9F94, 0xFD90, 0x9F95,
+	0xFD91, 0x9F96, 0xFD92, 0x9F97, 0xFD93, 0x9F98, 0xFD94, 0x9F9C,
+	0xFD95, 0x9F9D, 0xFD96, 0x9F9E, 0xFD97, 0x9FA1, 0xFD98, 0x9FA2,
+	0xFD99, 0x9FA3, 0xFD9A, 0x9FA4, 0xFD9B, 0x9FA5, 0xFD9C, 0xF92C,
+	0xFD9D, 0xF979, 0xFD9E, 0xF995, 0xFD9F, 0xF9E7, 0xFDA0, 0xF9F1,
+	0xFE40, 0xFA0C, 0xFE41, 0xFA0D, 0xFE42, 0xFA0E, 0xFE43, 0xFA0F,
+	0xFE44, 0xFA11, 0xFE45, 0xFA13, 0xFE46, 0xFA14, 0xFE47, 0xFA18,
+	0xFE48, 0xFA1F, 0xFE49, 0xFA20, 0xFE4A, 0xFA21, 0xFE4B, 0xFA23,
+	0xFE4C, 0xFA24, 0xFE4D, 0xFA27, 0xFE4E, 0xFA28, 0xFE4F, 0xFA29,
+	0, 0
+};
+
+
+
+WCHAR ff_convert (	/* Converted code, 0 means conversion error */
+	WCHAR	src,	/* Character code to be converted */
+	UINT	dir		/* 0: Unicode to OEMCP, 1: OEMCP to Unicode */
+)
+{
+	const WCHAR *p;
+	WCHAR c;
+	int i, n, li, hi;
+
+
+	if (src < 0x80) {	/* ASCII */
+		c = src;
+	} else {
+		if (dir) {		/* OEMCP to unicode */
+			p = oem2uni;
+			hi = sizeof(oem2uni) / 4 - 1;
+		} else {		/* Unicode to OEMCP */
+			p = uni2oem;
+			hi = sizeof(uni2oem) / 4 - 1;
+		}
+		li = 0;
+		for (n = 16; n; n--) {
+			i = li + (hi - li) / 2;
+			if (src == p[i * 2]) break;
+			if (src > p[i * 2])
+				li = i;
+			else
+				hi = i;
+		}
+		c = n ? p[i * 2 + 1] : 0;
+	}
+
+	return c;
+}
+#else
+#error This file is not needed in current configuration.
+
+#endif
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/files/ff/option/cc949.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/files/ff/option/cc949.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/files/ff/option/cc949.c	(revision 457)
@@ -0,0 +1,8588 @@
+/*------------------------------------------------------------------------*/
+/* Unicode - OEM code bidirectional converter  (C)ChaN, 2009              */
+/*                                                                        */
+/* CP949 (Korean)                                                         */
+/*------------------------------------------------------------------------*/
+
+#include "../ff.h"
+
+
+#if _USE_LFN && _CODE_PAGE == 949
+
+
+static
+const WCHAR uni2oem[] = {
+/*  Unicode - OEM,  Unicode - OEM,  Unicode - OEM,  Unicode - OEM */
+	0x00A1, 0xA2AE, 0x00A4, 0xA2B4, 0x00A7, 0xA1D7, 0x00A8, 0xA1A7,
+	0x00AA, 0xA8A3, 0x00AD, 0xA1A9, 0x00AE, 0xA2E7, 0x00B0, 0xA1C6,
+	0x00B1, 0xA1BE, 0x00B2, 0xA9F7, 0x00B3, 0xA9F8, 0x00B4, 0xA2A5,
+	0x00B6, 0xA2D2, 0x00B7, 0xA1A4, 0x00B8, 0xA2AC, 0x00B9, 0xA9F6,
+	0x00BA, 0xA8AC, 0x00BC, 0xA8F9, 0x00BD, 0xA8F6, 0x00BE, 0xA8FA,
+	0x00BF, 0xA2AF, 0x00C6, 0xA8A1, 0x00D0, 0xA8A2, 0x00D7, 0xA1BF,
+	0x00D8, 0xA8AA, 0x00DE, 0xA8AD, 0x00DF, 0xA9AC, 0x00E6, 0xA9A1,
+	0x00F0, 0xA9A3, 0x00F7, 0xA1C0, 0x00F8, 0xA9AA, 0x00FE, 0xA9AD,
+	0x0111, 0xA9A2, 0x0126, 0xA8A4, 0x0127, 0xA9A4, 0x0131, 0xA9A5,
+	0x0132, 0xA8A6, 0x0133, 0xA9A6, 0x0138, 0xA9A7, 0x013F, 0xA8A8,
+	0x0140, 0xA9A8, 0x0141, 0xA8A9, 0x0142, 0xA9A9, 0x0149, 0xA9B0,
+	0x014A, 0xA8AF, 0x014B, 0xA9AF, 0x0152, 0xA8AB, 0x0153, 0xA9AB,
+	0x0166, 0xA8AE, 0x0167, 0xA9AE, 0x02C7, 0xA2A7, 0x02D0, 0xA2B0,
+	0x02D8, 0xA2A8, 0x02D9, 0xA2AB, 0x02DA, 0xA2AA, 0x02DB, 0xA2AD,
+	0x02DD, 0xA2A9, 0x0391, 0xA5C1, 0x0392, 0xA5C2, 0x0393, 0xA5C3,
+	0x0394, 0xA5C4, 0x0395, 0xA5C5, 0x0396, 0xA5C6, 0x0397, 0xA5C7,
+	0x0398, 0xA5C8, 0x0399, 0xA5C9, 0x039A, 0xA5CA, 0x039B, 0xA5CB,
+	0x039C, 0xA5CC, 0x039D, 0xA5CD, 0x039E, 0xA5CE, 0x039F, 0xA5CF,
+	0x03A0, 0xA5D0, 0x03A1, 0xA5D1, 0x03A3, 0xA5D2, 0x03A4, 0xA5D3,
+	0x03A5, 0xA5D4, 0x03A6, 0xA5D5, 0x03A7, 0xA5D6, 0x03A8, 0xA5D7,
+	0x03A9, 0xA5D8, 0x03B1, 0xA5E1, 0x03B2, 0xA5E2, 0x03B3, 0xA5E3,
+	0x03B4, 0xA5E4, 0x03B5, 0xA5E5, 0x03B6, 0xA5E6, 0x03B7, 0xA5E7,
+	0x03B8, 0xA5E8, 0x03B9, 0xA5E9, 0x03BA, 0xA5EA, 0x03BB, 0xA5EB,
+	0x03BC, 0xA5EC, 0x03BD, 0xA5ED, 0x03BE, 0xA5EE, 0x03BF, 0xA5EF,
+	0x03C0, 0xA5F0, 0x03C1, 0xA5F1, 0x03C3, 0xA5F2, 0x03C4, 0xA5F3,
+	0x03C5, 0xA5F4, 0x03C6, 0xA5F5, 0x03C7, 0xA5F6, 0x03C8, 0xA5F7,
+	0x03C9, 0xA5F8, 0x0401, 0xACA7, 0x0410, 0xACA1, 0x0411, 0xACA2,
+	0x0412, 0xACA3, 0x0413, 0xACA4, 0x0414, 0xACA5, 0x0415, 0xACA6,
+	0x0416, 0xACA8, 0x0417, 0xACA9, 0x0418, 0xACAA, 0x0419, 0xACAB,
+	0x041A, 0xACAC, 0x041B, 0xACAD, 0x041C, 0xACAE, 0x041D, 0xACAF,
+	0x041E, 0xACB0, 0x041F, 0xACB1, 0x0420, 0xACB2, 0x0421, 0xACB3,
+	0x0422, 0xACB4, 0x0423, 0xACB5, 0x0424, 0xACB6, 0x0425, 0xACB7,
+	0x0426, 0xACB8, 0x0427, 0xACB9, 0x0428, 0xACBA, 0x0429, 0xACBB,
+	0x042A, 0xACBC, 0x042B, 0xACBD, 0x042C, 0xACBE, 0x042D, 0xACBF,
+	0x042E, 0xACC0, 0x042F, 0xACC1, 0x0430, 0xACD1, 0x0431, 0xACD2,
+	0x0432, 0xACD3, 0x0433, 0xACD4, 0x0434, 0xACD5, 0x0435, 0xACD6,
+	0x0436, 0xACD8, 0x0437, 0xACD9, 0x0438, 0xACDA, 0x0439, 0xACDB,
+	0x043A, 0xACDC, 0x043B, 0xACDD, 0x043C, 0xACDE, 0x043D, 0xACDF,
+	0x043E, 0xACE0, 0x043F, 0xACE1, 0x0440, 0xACE2, 0x0441, 0xACE3,
+	0x0442, 0xACE4, 0x0443, 0xACE5, 0x0444, 0xACE6, 0x0445, 0xACE7,
+	0x0446, 0xACE8, 0x0447, 0xACE9, 0x0448, 0xACEA, 0x0449, 0xACEB,
+	0x044A, 0xACEC, 0x044B, 0xACED, 0x044C, 0xACEE, 0x044D, 0xACEF,
+	0x044E, 0xACF0, 0x044F, 0xACF1, 0x0451, 0xACD7, 0x2015, 0xA1AA,
+	0x2018, 0xA1AE, 0x2019, 0xA1AF, 0x201C, 0xA1B0, 0x201D, 0xA1B1,
+	0x2020, 0xA2D3, 0x2021, 0xA2D4, 0x2025, 0xA1A5, 0x2026, 0xA1A6,
+	0x2030, 0xA2B6, 0x2032, 0xA1C7, 0x2033, 0xA1C8, 0x203B, 0xA1D8,
+	0x2074, 0xA9F9, 0x207F, 0xA9FA, 0x2081, 0xA9FB, 0x2082, 0xA9FC,
+	0x2083, 0xA9FD, 0x2084, 0xA9FE, 0x20AC, 0xA2E6, 0x2103, 0xA1C9,
+	0x2109, 0xA2B5, 0x2113, 0xA7A4, 0x2116, 0xA2E0, 0x2121, 0xA2E5,
+	0x2122, 0xA2E2, 0x2126, 0xA7D9, 0x212B, 0xA1CA, 0x2153, 0xA8F7,
+	0x2154, 0xA8F8, 0x215B, 0xA8FB, 0x215C, 0xA8FC, 0x215D, 0xA8FD,
+	0x215E, 0xA8FE, 0x2160, 0xA5B0, 0x2161, 0xA5B1, 0x2162, 0xA5B2,
+	0x2163, 0xA5B3, 0x2164, 0xA5B4, 0x2165, 0xA5B5, 0x2166, 0xA5B6,
+	0x2167, 0xA5B7, 0x2168, 0xA5B8, 0x2169, 0xA5B9, 0x2170, 0xA5A1,
+	0x2171, 0xA5A2, 0x2172, 0xA5A3, 0x2173, 0xA5A4, 0x2174, 0xA5A5,
+	0x2175, 0xA5A6, 0x2176, 0xA5A7, 0x2177, 0xA5A8, 0x2178, 0xA5A9,
+	0x2179, 0xA5AA, 0x2190, 0xA1E7, 0x2191, 0xA1E8, 0x2192, 0xA1E6,
+	0x2193, 0xA1E9, 0x2194, 0xA1EA, 0x2195, 0xA2D5, 0x2196, 0xA2D8,
+	0x2197, 0xA2D6, 0x2198, 0xA2D9, 0x2199, 0xA2D7, 0x21D2, 0xA2A1,
+	0x21D4, 0xA2A2, 0x2200, 0xA2A3, 0x2202, 0xA1D3, 0x2203, 0xA2A4,
+	0x2207, 0xA1D4, 0x2208, 0xA1F4, 0x220B, 0xA1F5, 0x220F, 0xA2B3,
+	0x2211, 0xA2B2, 0x221A, 0xA1EE, 0x221D, 0xA1F0, 0x221E, 0xA1C4,
+	0x2220, 0xA1D0, 0x2225, 0xA1AB, 0x2227, 0xA1FC, 0x2228, 0xA1FD,
+	0x2229, 0xA1FB, 0x222A, 0xA1FA, 0x222B, 0xA1F2, 0x222C, 0xA1F3,
+	0x222E, 0xA2B1, 0x2234, 0xA1C5, 0x2235, 0xA1F1, 0x223C, 0xA1AD,
+	0x223D, 0xA1EF, 0x2252, 0xA1D6, 0x2260, 0xA1C1, 0x2261, 0xA1D5,
+	0x2264, 0xA1C2, 0x2265, 0xA1C3, 0x226A, 0xA1EC, 0x226B, 0xA1ED,
+	0x2282, 0xA1F8, 0x2283, 0xA1F9, 0x2286, 0xA1F6, 0x2287, 0xA1F7,
+	0x2299, 0xA2C1, 0x22A5, 0xA1D1, 0x2312, 0xA1D2, 0x2460, 0xA8E7,
+	0x2461, 0xA8E8, 0x2462, 0xA8E9, 0x2463, 0xA8EA, 0x2464, 0xA8EB,
+	0x2465, 0xA8EC, 0x2466, 0xA8ED, 0x2467, 0xA8EE, 0x2468, 0xA8EF,
+	0x2469, 0xA8F0, 0x246A, 0xA8F1, 0x246B, 0xA8F2, 0x246C, 0xA8F3,
+	0x246D, 0xA8F4, 0x246E, 0xA8F5, 0x2474, 0xA9E7, 0x2475, 0xA9E8,
+	0x2476, 0xA9E9, 0x2477, 0xA9EA, 0x2478, 0xA9EB, 0x2479, 0xA9EC,
+	0x247A, 0xA9ED, 0x247B, 0xA9EE, 0x247C, 0xA9EF, 0x247D, 0xA9F0,
+	0x247E, 0xA9F1, 0x247F, 0xA9F2, 0x2480, 0xA9F3, 0x2481, 0xA9F4,
+	0x2482, 0xA9F5, 0x249C, 0xA9CD, 0x249D, 0xA9CE, 0x249E, 0xA9CF,
+	0x249F, 0xA9D0, 0x24A0, 0xA9D1, 0x24A1, 0xA9D2, 0x24A2, 0xA9D3,
+	0x24A3, 0xA9D4, 0x24A4, 0xA9D5, 0x24A5, 0xA9D6, 0x24A6, 0xA9D7,
+	0x24A7, 0xA9D8, 0x24A8, 0xA9D9, 0x24A9, 0xA9DA, 0x24AA, 0xA9DB,
+	0x24AB, 0xA9DC, 0x24AC, 0xA9DD, 0x24AD, 0xA9DE, 0x24AE, 0xA9DF,
+	0x24AF, 0xA9E0, 0x24B0, 0xA9E1, 0x24B1, 0xA9E2, 0x24B2, 0xA9E3,
+	0x24B3, 0xA9E4, 0x24B4, 0xA9E5, 0x24B5, 0xA9E6, 0x24D0, 0xA8CD,
+	0x24D1, 0xA8CE, 0x24D2, 0xA8CF, 0x24D3, 0xA8D0, 0x24D4, 0xA8D1,
+	0x24D5, 0xA8D2, 0x24D6, 0xA8D3, 0x24D7, 0xA8D4, 0x24D8, 0xA8D5,
+	0x24D9, 0xA8D6, 0x24DA, 0xA8D7, 0x24DB, 0xA8D8, 0x24DC, 0xA8D9,
+	0x24DD, 0xA8DA, 0x24DE, 0xA8DB, 0x24DF, 0xA8DC, 0x24E0, 0xA8DD,
+	0x24E1, 0xA8DE, 0x24E2, 0xA8DF, 0x24E3, 0xA8E0, 0x24E4, 0xA8E1,
+	0x24E5, 0xA8E2, 0x24E6, 0xA8E3, 0x24E7, 0xA8E4, 0x24E8, 0xA8E5,
+	0x24E9, 0xA8E6, 0x2500, 0xA6A1, 0x2501, 0xA6AC, 0x2502, 0xA6A2,
+	0x2503, 0xA6AD, 0x250C, 0xA6A3, 0x250D, 0xA6C8, 0x250E, 0xA6C7,
+	0x250F, 0xA6AE, 0x2510, 0xA6A4, 0x2511, 0xA6C2, 0x2512, 0xA6C1,
+	0x2513, 0xA6AF, 0x2514, 0xA6A6, 0x2515, 0xA6C6, 0x2516, 0xA6C5,
+	0x2517, 0xA6B1, 0x2518, 0xA6A5, 0x2519, 0xA6C4, 0x251A, 0xA6C3,
+	0x251B, 0xA6B0, 0x251C, 0xA6A7, 0x251D, 0xA6BC, 0x251E, 0xA6C9,
+	0x251F, 0xA6CA, 0x2520, 0xA6B7, 0x2521, 0xA6CB, 0x2522, 0xA6CC,
+	0x2523, 0xA6B2, 0x2524, 0xA6A9, 0x2525, 0xA6BE, 0x2526, 0xA6CD,
+	0x2527, 0xA6CE, 0x2528, 0xA6B9, 0x2529, 0xA6CF, 0x252A, 0xA6D0,
+	0x252B, 0xA6B4, 0x252C, 0xA6A8, 0x252D, 0xA6D1, 0x252E, 0xA6D2,
+	0x252F, 0xA6B8, 0x2530, 0xA6BD, 0x2531, 0xA6D3, 0x2532, 0xA6D4,
+	0x2533, 0xA6B3, 0x2534, 0xA6AA, 0x2535, 0xA6D5, 0x2536, 0xA6D6,
+	0x2537, 0xA6BA, 0x2538, 0xA6BF, 0x2539, 0xA6D7, 0x253A, 0xA6D8,
+	0x253B, 0xA6B5, 0x253C, 0xA6AB, 0x253D, 0xA6D9, 0x253E, 0xA6DA,
+	0x253F, 0xA6BB, 0x2540, 0xA6DB, 0x2541, 0xA6DC, 0x2542, 0xA6C0,
+	0x2543, 0xA6DD, 0x2544, 0xA6DE, 0x2545, 0xA6DF, 0x2546, 0xA6E0,
+	0x2547, 0xA6E1, 0x2548, 0xA6E2, 0x2549, 0xA6E3, 0x254A, 0xA6E4,
+	0x254B, 0xA6B6, 0x2592, 0xA2C6, 0x25A0, 0xA1E1, 0x25A1, 0xA1E0,
+	0x25A3, 0xA2C3, 0x25A4, 0xA2C7, 0x25A5, 0xA2C8, 0x25A6, 0xA2CB,
+	0x25A7, 0xA2CA, 0x25A8, 0xA2C9, 0x25A9, 0xA2CC, 0x25B2, 0xA1E3,
+	0x25B3, 0xA1E2, 0x25B6, 0xA2BA, 0x25B7, 0xA2B9, 0x25BC, 0xA1E5,
+	0x25BD, 0xA1E4, 0x25C0, 0xA2B8, 0x25C1, 0xA2B7, 0x25C6, 0xA1DF,
+	0x25C7, 0xA1DE, 0x25C8, 0xA2C2, 0x25CB, 0xA1DB, 0x25CE, 0xA1DD,
+	0x25CF, 0xA1DC, 0x25D0, 0xA2C4, 0x25D1, 0xA2C5, 0x2605, 0xA1DA,
+	0x2606, 0xA1D9, 0x260E, 0xA2CF, 0x260F, 0xA2CE, 0x261C, 0xA2D0,
+	0x261E, 0xA2D1, 0x2640, 0xA1CF, 0x2642, 0xA1CE, 0x2660, 0xA2BC,
+	0x2661, 0xA2BD, 0x2663, 0xA2C0, 0x2664, 0xA2BB, 0x2665, 0xA2BE,
+	0x2667, 0xA2BF, 0x2668, 0xA2CD, 0x2669, 0xA2DB, 0x266A, 0xA2DC,
+	0x266C, 0xA2DD, 0x266D, 0xA2DA, 0x3000, 0xA1A1, 0x3001, 0xA1A2,
+	0x3002, 0xA1A3, 0x3003, 0xA1A8, 0x3008, 0xA1B4, 0x3009, 0xA1B5,
+	0x300A, 0xA1B6, 0x300B, 0xA1B7, 0x300C, 0xA1B8, 0x300D, 0xA1B9,
+	0x300E, 0xA1BA, 0x300F, 0xA1BB, 0x3010, 0xA1BC, 0x3011, 0xA1BD,
+	0x3013, 0xA1EB, 0x3014, 0xA1B2, 0x3015, 0xA1B3, 0x3041, 0xAAA1,
+	0x3042, 0xAAA2, 0x3043, 0xAAA3, 0x3044, 0xAAA4, 0x3045, 0xAAA5,
+	0x3046, 0xAAA6, 0x3047, 0xAAA7, 0x3048, 0xAAA8, 0x3049, 0xAAA9,
+	0x304A, 0xAAAA, 0x304B, 0xAAAB, 0x304C, 0xAAAC, 0x304D, 0xAAAD,
+	0x304E, 0xAAAE, 0x304F, 0xAAAF, 0x3050, 0xAAB0, 0x3051, 0xAAB1,
+	0x3052, 0xAAB2, 0x3053, 0xAAB3, 0x3054, 0xAAB4, 0x3055, 0xAAB5,
+	0x3056, 0xAAB6, 0x3057, 0xAAB7, 0x3058, 0xAAB8, 0x3059, 0xAAB9,
+	0x305A, 0xAABA, 0x305B, 0xAABB, 0x305C, 0xAABC, 0x305D, 0xAABD,
+	0x305E, 0xAABE, 0x305F, 0xAABF, 0x3060, 0xAAC0, 0x3061, 0xAAC1,
+	0x3062, 0xAAC2, 0x3063, 0xAAC3, 0x3064, 0xAAC4, 0x3065, 0xAAC5,
+	0x3066, 0xAAC6, 0x3067, 0xAAC7, 0x3068, 0xAAC8, 0x3069, 0xAAC9,
+	0x306A, 0xAACA, 0x306B, 0xAACB, 0x306C, 0xAACC, 0x306D, 0xAACD,
+	0x306E, 0xAACE, 0x306F, 0xAACF, 0x3070, 0xAAD0, 0x3071, 0xAAD1,
+	0x3072, 0xAAD2, 0x3073, 0xAAD3, 0x3074, 0xAAD4, 0x3075, 0xAAD5,
+	0x3076, 0xAAD6, 0x3077, 0xAAD7, 0x3078, 0xAAD8, 0x3079, 0xAAD9,
+	0x307A, 0xAADA, 0x307B, 0xAADB, 0x307C, 0xAADC, 0x307D, 0xAADD,
+	0x307E, 0xAADE, 0x307F, 0xAADF, 0x3080, 0xAAE0, 0x3081, 0xAAE1,
+	0x3082, 0xAAE2, 0x3083, 0xAAE3, 0x3084, 0xAAE4, 0x3085, 0xAAE5,
+	0x3086, 0xAAE6, 0x3087, 0xAAE7, 0x3088, 0xAAE8, 0x3089, 0xAAE9,
+	0x308A, 0xAAEA, 0x308B, 0xAAEB, 0x308C, 0xAAEC, 0x308D, 0xAAED,
+	0x308E, 0xAAEE, 0x308F, 0xAAEF, 0x3090, 0xAAF0, 0x3091, 0xAAF1,
+	0x3092, 0xAAF2, 0x3093, 0xAAF3, 0x30A1, 0xABA1, 0x30A2, 0xABA2,
+	0x30A3, 0xABA3, 0x30A4, 0xABA4, 0x30A5, 0xABA5, 0x30A6, 0xABA6,
+	0x30A7, 0xABA7, 0x30A8, 0xABA8, 0x30A9, 0xABA9, 0x30AA, 0xABAA,
+	0x30AB, 0xABAB, 0x30AC, 0xABAC, 0x30AD, 0xABAD, 0x30AE, 0xABAE,
+	0x30AF, 0xABAF, 0x30B0, 0xABB0, 0x30B1, 0xABB1, 0x30B2, 0xABB2,
+	0x30B3, 0xABB3, 0x30B4, 0xABB4, 0x30B5, 0xABB5, 0x30B6, 0xABB6,
+	0x30B7, 0xABB7, 0x30B8, 0xABB8, 0x30B9, 0xABB9, 0x30BA, 0xABBA,
+	0x30BB, 0xABBB, 0x30BC, 0xABBC, 0x30BD, 0xABBD, 0x30BE, 0xABBE,
+	0x30BF, 0xABBF, 0x30C0, 0xABC0, 0x30C1, 0xABC1, 0x30C2, 0xABC2,
+	0x30C3, 0xABC3, 0x30C4, 0xABC4, 0x30C5, 0xABC5, 0x30C6, 0xABC6,
+	0x30C7, 0xABC7, 0x30C8, 0xABC8, 0x30C9, 0xABC9, 0x30CA, 0xABCA,
+	0x30CB, 0xABCB, 0x30CC, 0xABCC, 0x30CD, 0xABCD, 0x30CE, 0xABCE,
+	0x30CF, 0xABCF, 0x30D0, 0xABD0, 0x30D1, 0xABD1, 0x30D2, 0xABD2,
+	0x30D3, 0xABD3, 0x30D4, 0xABD4, 0x30D5, 0xABD5, 0x30D6, 0xABD6,
+	0x30D7, 0xABD7, 0x30D8, 0xABD8, 0x30D9, 0xABD9, 0x30DA, 0xABDA,
+	0x30DB, 0xABDB, 0x30DC, 0xABDC, 0x30DD, 0xABDD, 0x30DE, 0xABDE,
+	0x30DF, 0xABDF, 0x30E0, 0xABE0, 0x30E1, 0xABE1, 0x30E2, 0xABE2,
+	0x30E3, 0xABE3, 0x30E4, 0xABE4, 0x30E5, 0xABE5, 0x30E6, 0xABE6,
+	0x30E7, 0xABE7, 0x30E8, 0xABE8, 0x30E9, 0xABE9, 0x30EA, 0xABEA,
+	0x30EB, 0xABEB, 0x30EC, 0xABEC, 0x30ED, 0xABED, 0x30EE, 0xABEE,
+	0x30EF, 0xABEF, 0x30F0, 0xABF0, 0x30F1, 0xABF1, 0x30F2, 0xABF2,
+	0x30F3, 0xABF3, 0x30F4, 0xABF4, 0x30F5, 0xABF5, 0x30F6, 0xABF6,
+	0x3131, 0xA4A1, 0x3132, 0xA4A2, 0x3133, 0xA4A3, 0x3134, 0xA4A4,
+	0x3135, 0xA4A5, 0x3136, 0xA4A6, 0x3137, 0xA4A7, 0x3138, 0xA4A8,
+	0x3139, 0xA4A9, 0x313A, 0xA4AA, 0x313B, 0xA4AB, 0x313C, 0xA4AC,
+	0x313D, 0xA4AD, 0x313E, 0xA4AE, 0x313F, 0xA4AF, 0x3140, 0xA4B0,
+	0x3141, 0xA4B1, 0x3142, 0xA4B2, 0x3143, 0xA4B3, 0x3144, 0xA4B4,
+	0x3145, 0xA4B5, 0x3146, 0xA4B6, 0x3147, 0xA4B7, 0x3148, 0xA4B8,
+	0x3149, 0xA4B9, 0x314A, 0xA4BA, 0x314B, 0xA4BB, 0x314C, 0xA4BC,
+	0x314D, 0xA4BD, 0x314E, 0xA4BE, 0x314F, 0xA4BF, 0x3150, 0xA4C0,
+	0x3151, 0xA4C1, 0x3152, 0xA4C2, 0x3153, 0xA4C3, 0x3154, 0xA4C4,
+	0x3155, 0xA4C5, 0x3156, 0xA4C6, 0x3157, 0xA4C7, 0x3158, 0xA4C8,
+	0x3159, 0xA4C9, 0x315A, 0xA4CA, 0x315B, 0xA4CB, 0x315C, 0xA4CC,
+	0x315D, 0xA4CD, 0x315E, 0xA4CE, 0x315F, 0xA4CF, 0x3160, 0xA4D0,
+	0x3161, 0xA4D1, 0x3162, 0xA4D2, 0x3163, 0xA4D3, 0x3164, 0xA4D4,
+	0x3165, 0xA4D5, 0x3166, 0xA4D6, 0x3167, 0xA4D7, 0x3168, 0xA4D8,
+	0x3169, 0xA4D9, 0x316A, 0xA4DA, 0x316B, 0xA4DB, 0x316C, 0xA4DC,
+	0x316D, 0xA4DD, 0x316E, 0xA4DE, 0x316F, 0xA4DF, 0x3170, 0xA4E0,
+	0x3171, 0xA4E1, 0x3172, 0xA4E2, 0x3173, 0xA4E3, 0x3174, 0xA4E4,
+	0x3175, 0xA4E5, 0x3176, 0xA4E6, 0x3177, 0xA4E7, 0x3178, 0xA4E8,
+	0x3179, 0xA4E9, 0x317A, 0xA4EA, 0x317B, 0xA4EB, 0x317C, 0xA4EC,
+	0x317D, 0xA4ED, 0x317E, 0xA4EE, 0x317F, 0xA4EF, 0x3180, 0xA4F0,
+	0x3181, 0xA4F1, 0x3182, 0xA4F2, 0x3183, 0xA4F3, 0x3184, 0xA4F4,
+	0x3185, 0xA4F5, 0x3186, 0xA4F6, 0x3187, 0xA4F7, 0x3188, 0xA4F8,
+	0x3189, 0xA4F9, 0x318A, 0xA4FA, 0x318B, 0xA4FB, 0x318C, 0xA4FC,
+	0x318D, 0xA4FD, 0x318E, 0xA4FE, 0x3200, 0xA9B1, 0x3201, 0xA9B2,
+	0x3202, 0xA9B3, 0x3203, 0xA9B4, 0x3204, 0xA9B5, 0x3205, 0xA9B6,
+	0x3206, 0xA9B7, 0x3207, 0xA9B8, 0x3208, 0xA9B9, 0x3209, 0xA9BA,
+	0x320A, 0xA9BB, 0x320B, 0xA9BC, 0x320C, 0xA9BD, 0x320D, 0xA9BE,
+	0x320E, 0xA9BF, 0x320F, 0xA9C0, 0x3210, 0xA9C1, 0x3211, 0xA9C2,
+	0x3212, 0xA9C3, 0x3213, 0xA9C4, 0x3214, 0xA9C5, 0x3215, 0xA9C6,
+	0x3216, 0xA9C7, 0x3217, 0xA9C8, 0x3218, 0xA9C9, 0x3219, 0xA9CA,
+	0x321A, 0xA9CB, 0x321B, 0xA9CC, 0x321C, 0xA2DF, 0x3260, 0xA8B1,
+	0x3261, 0xA8B2, 0x3262, 0xA8B3, 0x3263, 0xA8B4, 0x3264, 0xA8B5,
+	0x3265, 0xA8B6, 0x3266, 0xA8B7, 0x3267, 0xA8B8, 0x3268, 0xA8B9,
+	0x3269, 0xA8BA, 0x326A, 0xA8BB, 0x326B, 0xA8BC, 0x326C, 0xA8BD,
+	0x326D, 0xA8BE, 0x326E, 0xA8BF, 0x326F, 0xA8C0, 0x3270, 0xA8C1,
+	0x3271, 0xA8C2, 0x3272, 0xA8C3, 0x3273, 0xA8C4, 0x3274, 0xA8C5,
+	0x3275, 0xA8C6, 0x3276, 0xA8C7, 0x3277, 0xA8C8, 0x3278, 0xA8C9,
+	0x3279, 0xA8CA, 0x327A, 0xA8CB, 0x327B, 0xA8CC, 0x327F, 0xA2DE,
+	0x3380, 0xA7C9, 0x3381, 0xA7CA, 0x3382, 0xA7CB, 0x3383, 0xA7CC,
+	0x3384, 0xA7CD, 0x3388, 0xA7BA, 0x3389, 0xA7BB, 0x338A, 0xA7DC,
+	0x338B, 0xA7DD, 0x338C, 0xA7DE, 0x338D, 0xA7B6, 0x338E, 0xA7B7,
+	0x338F, 0xA7B8, 0x3390, 0xA7D4, 0x3391, 0xA7D5, 0x3392, 0xA7D6,
+	0x3393, 0xA7D7, 0x3394, 0xA7D8, 0x3395, 0xA7A1, 0x3396, 0xA7A2,
+	0x3397, 0xA7A3, 0x3398, 0xA7A5, 0x3399, 0xA7AB, 0x339A, 0xA7AC,
+	0x339B, 0xA7AD, 0x339C, 0xA7AE, 0x339D, 0xA7AF, 0x339E, 0xA7B0,
+	0x339F, 0xA7B1, 0x33A0, 0xA7B2, 0x33A1, 0xA7B3, 0x33A2, 0xA7B4,
+	0x33A3, 0xA7A7, 0x33A4, 0xA7A8, 0x33A5, 0xA7A9, 0x33A6, 0xA7AA,
+	0x33A7, 0xA7BD, 0x33A8, 0xA7BE, 0x33A9, 0xA7E5, 0x33AA, 0xA7E6,
+	0x33AB, 0xA7E7, 0x33AC, 0xA7E8, 0x33AD, 0xA7E1, 0x33AE, 0xA7E2,
+	0x33AF, 0xA7E3, 0x33B0, 0xA7BF, 0x33B1, 0xA7C0, 0x33B2, 0xA7C1,
+	0x33B3, 0xA7C2, 0x33B4, 0xA7C3, 0x33B5, 0xA7C4, 0x33B6, 0xA7C5,
+	0x33B7, 0xA7C6, 0x33B8, 0xA7C7, 0x33B9, 0xA7C8, 0x33BA, 0xA7CE,
+	0x33BB, 0xA7CF, 0x33BC, 0xA7D0, 0x33BD, 0xA7D1, 0x33BE, 0xA7D2,
+	0x33BF, 0xA7D3, 0x33C0, 0xA7DA, 0x33C1, 0xA7DB, 0x33C2, 0xA2E3,
+	0x33C3, 0xA7EC, 0x33C4, 0xA7A6, 0x33C5, 0xA7E0, 0x33C6, 0xA7EF,
+	0x33C7, 0xA2E1, 0x33C8, 0xA7BC, 0x33C9, 0xA7ED, 0x33CA, 0xA7B5,
+	0x33CF, 0xA7B9, 0x33D0, 0xA7EA, 0x33D3, 0xA7EB, 0x33D6, 0xA7DF,
+	0x33D8, 0xA2E4, 0x33DB, 0xA7E4, 0x33DC, 0xA7EE, 0x33DD, 0xA7E9,
+	0x4E00, 0xECE9, 0x4E01, 0xEFCB, 0x4E03, 0xF6D2, 0x4E07, 0xD8B2,
+	0x4E08, 0xEDDB, 0x4E09, 0xDFB2, 0x4E0A, 0xDFBE, 0x4E0B, 0xF9BB,
+	0x4E0D, 0xDCF4, 0x4E11, 0xF5E4, 0x4E14, 0xF3A6, 0x4E15, 0xDDE0,
+	0x4E16, 0xE1A6, 0x4E18, 0xCEF8, 0x4E19, 0xDCB0, 0x4E1E, 0xE3AA,
+	0x4E2D, 0xF1E9, 0x4E32, 0xCDFA, 0x4E38, 0xFCAF, 0x4E39, 0xD3A1,
+	0x4E3B, 0xF1AB, 0x4E42, 0xE7D1, 0x4E43, 0xD2AC, 0x4E45, 0xCEF9,
+	0x4E4B, 0xF1FD, 0x4E4D, 0xDEBF, 0x4E4E, 0xFBBA, 0x4E4F, 0xF9B9,
+	0x4E56, 0xCED2, 0x4E58, 0xE3AB, 0x4E59, 0xEBE0, 0x4E5D, 0xCEFA,
+	0x4E5E, 0xCBF7, 0x4E5F, 0xE5A5, 0x4E6B, 0xCAE1, 0x4E6D, 0xD4CC,
+	0x4E73, 0xEAE1, 0x4E76, 0xDCE3, 0x4E77, 0xDFAD, 0x4E7E, 0xCBEB,
+	0x4E82, 0xD5AF, 0x4E86, 0xD6F5, 0x4E88, 0xE5F8, 0x4E8B, 0xDEC0,
+	0x4E8C, 0xECA3, 0x4E8E, 0xE9CD, 0x4E90, 0xEAA7, 0x4E91, 0xE9F6,
+	0x4E92, 0xFBBB, 0x4E94, 0xE7E9, 0x4E95, 0xEFCC, 0x4E98, 0xD0E6,
+	0x4E9B, 0xDEC1, 0x4E9E, 0xE4AC, 0x4EA1, 0xD8CC, 0x4EA2, 0xF9F1,
+	0x4EA4, 0xCEDF, 0x4EA5, 0xFAA4, 0x4EA6, 0xE6B2, 0x4EA8, 0xFAFB,
+	0x4EAB, 0xFABD, 0x4EAC, 0xCCC8, 0x4EAD, 0xEFCD, 0x4EAE, 0xD5D5,
+	0x4EB6, 0xD3A2, 0x4EBA, 0xECD1, 0x4EC0, 0xE4A7, 0x4EC1, 0xECD2,
+	0x4EC4, 0xF6B1, 0x4EC7, 0xCEFB, 0x4ECA, 0xD0D1, 0x4ECB, 0xCBBF,
+	0x4ECD, 0xEDA4, 0x4ED4, 0xEDA8, 0x4ED5, 0xDEC2, 0x4ED6, 0xF6E2,
+	0x4ED7, 0xEDDC, 0x4ED8, 0xDCF5, 0x4ED9, 0xE0B9, 0x4EDD, 0xD4CE,
+	0x4EDF, 0xF4B5, 0x4EE3, 0xD3DB, 0x4EE4, 0xD6B5, 0x4EE5, 0xECA4,
+	0x4EF0, 0xE4E6, 0x4EF2, 0xF1EA, 0x4EF6, 0xCBEC, 0x4EF7, 0xCBC0,
+	0x4EFB, 0xECF2, 0x4F01, 0xD0EA, 0x4F09, 0xF9F2, 0x4F0A, 0xECA5,
+	0x4F0B, 0xD0DF, 0x4F0D, 0xE7EA, 0x4F0E, 0xD0EB, 0x4F0F, 0xDCD1,
+	0x4F10, 0xDBE9, 0x4F11, 0xFDCC, 0x4F2F, 0xDBD7, 0x4F34, 0xDAE1,
+	0x4F36, 0xD6B6, 0x4F38, 0xE3DF, 0x4F3A, 0xDEC3, 0x4F3C, 0xDEC4,
+	0x4F3D, 0xCAA1, 0x4F43, 0xEEEC, 0x4F46, 0xD3A3, 0x4F47, 0xEEB7,
+	0x4F48, 0xF8CF, 0x4F4D, 0xEAC8, 0x4F4E, 0xEEB8, 0x4F4F, 0xF1AC,
+	0x4F50, 0xF1A5, 0x4F51, 0xE9CE, 0x4F55, 0xF9BC, 0x4F59, 0xE5F9,
+	0x4F5A, 0xECEA, 0x4F5B, 0xDDD6, 0x4F5C, 0xEDC2, 0x4F69, 0xF8A5,
+	0x4F6F, 0xE5BA, 0x4F70, 0xDBD8, 0x4F73, 0xCAA2, 0x4F76, 0xD1CD,
+	0x4F7A, 0xEEED, 0x4F7E, 0xECEB, 0x4F7F, 0xDEC5, 0x4F81, 0xE3E0,
+	0x4F83, 0xCAC9, 0x4F84, 0xF2E9, 0x4F86, 0xD5CE, 0x4F88, 0xF6B6,
+	0x4F8A, 0xCEC2, 0x4F8B, 0xD6C7, 0x4F8D, 0xE3B4, 0x4F8F, 0xF1AD,
+	0x4F91, 0xEAE2, 0x4F96, 0xD7C2, 0x4F98, 0xF3A7, 0x4F9B, 0xCDEA,
+	0x4F9D, 0xEBEE, 0x4FAE, 0xD9B2, 0x4FAF, 0xFDA5, 0x4FB5, 0xF6D5,
+	0x4FB6, 0xD5E2, 0x4FBF, 0xF8B5, 0x4FC2, 0xCCF5, 0x4FC3, 0xF5B5,
+	0x4FC4, 0xE4AD, 0x4FC9, 0xE7EB, 0x4FCA, 0xF1D5, 0x4FCE, 0xF0BB,
+	0x4FD1, 0xE9B5, 0x4FD3, 0xCCC9, 0x4FD4, 0xFAD5, 0x4FD7, 0xE1D4,
+	0x4FDA, 0xD7D6, 0x4FDD, 0xDCC1, 0x4FDF, 0xDEC6, 0x4FE0, 0xFAEF,
+	0x4FE1, 0xE3E1, 0x4FEE, 0xE1F3, 0x4FEF, 0xDCF6, 0x4FF1, 0xCEFC,
+	0x4FF3, 0xDBC4, 0x4FF5, 0xF8F1, 0x4FF8, 0xDCE4, 0x4FFA, 0xE5EF,
+	0x5002, 0xDCB1, 0x5006, 0xD5D6, 0x5009, 0xF3DA, 0x500B, 0xCBC1,
+	0x500D, 0xDBC3, 0x5011, 0xD9FA, 0x5012, 0xD3EE, 0x5016, 0xFAB8,
+	0x5019, 0xFDA6, 0x501A, 0xEBEF, 0x501C, 0xF4A6, 0x501E, 0xCCCA,
+	0x501F, 0xF3A8, 0x5021, 0xF3DB, 0x5023, 0xDBA7, 0x5024, 0xF6B7,
+	0x5026, 0xCFE6, 0x5027, 0xF0F2, 0x5028, 0xCBDA, 0x502A, 0xE7D2,
+	0x502B, 0xD7C3, 0x502C, 0xF6F0, 0x502D, 0xE8DE, 0x503B, 0xE5A6,
+	0x5043, 0xE5E7, 0x5047, 0xCAA3, 0x5048, 0xCCA7, 0x5049, 0xEAC9,
+	0x504F, 0xF8B6, 0x5055, 0xFAA5, 0x505A, 0xF1AE, 0x505C, 0xEFCE,
+	0x5065, 0xCBED, 0x5074, 0xF6B0, 0x5075, 0xEFCF, 0x5076, 0xE9CF,
+	0x5078, 0xF7DE, 0x5080, 0xCED3, 0x5085, 0xDCF7, 0x508D, 0xDBA8,
+	0x5091, 0xCBF8, 0x5098, 0xDFA1, 0x5099, 0xDDE1, 0x50AC, 0xF5CA,
+	0x50AD, 0xE9B6, 0x50B2, 0xE7EC, 0x50B3, 0xEEEE, 0x50B5, 0xF3F0,
+	0x50B7, 0xDFBF, 0x50BE, 0xCCCB, 0x50C5, 0xD0C1, 0x50C9, 0xF4D2,
+	0x50CA, 0xE0BA, 0x50CF, 0xDFC0, 0x50D1, 0xCEE0, 0x50D5, 0xDCD2,
+	0x50D6, 0xFDEA, 0x50DA, 0xD6F6, 0x50DE, 0xEACA, 0x50E5, 0xE8E9,
+	0x50E7, 0xE3AC, 0x50ED, 0xF3D0, 0x50F9, 0xCAA4, 0x50FB, 0xDBF8,
+	0x50FF, 0xDEC7, 0x5100, 0xEBF0, 0x5101, 0xF1D6, 0x5104, 0xE5E2,
+	0x5106, 0xCCCC, 0x5109, 0xCBFB, 0x5112, 0xEAE3, 0x511F, 0xDFC1,
+	0x5121, 0xD6ED, 0x512A, 0xE9D0, 0x5132, 0xEEB9, 0x5137, 0xD5E3,
+	0x513A, 0xD1D3, 0x513C, 0xE5F0, 0x5140, 0xE8B4, 0x5141, 0xEBC3,
+	0x5143, 0xEAAA, 0x5144, 0xFAFC, 0x5145, 0xF5F6, 0x5146, 0xF0BC,
+	0x5147, 0xFDD4, 0x5148, 0xE0BB, 0x5149, 0xCEC3, 0x514B, 0xD0BA,
+	0x514C, 0xF7BA, 0x514D, 0xD8F3, 0x514E, 0xF7CD, 0x5152, 0xE4AE,
+	0x515C, 0xD4DF, 0x5162, 0xD0E7, 0x5165, 0xECFD, 0x5167, 0xD2AE,
+	0x5168, 0xEEEF, 0x5169, 0xD5D7, 0x516A, 0xEAE4, 0x516B, 0xF8A2,
+	0x516C, 0xCDEB, 0x516D, 0xD7BF, 0x516E, 0xFBB1, 0x5171, 0xCDEC,
+	0x5175, 0xDCB2, 0x5176, 0xD0EC, 0x5177, 0xCEFD, 0x5178, 0xEEF0,
+	0x517C, 0xCCC2, 0x5180, 0xD0ED, 0x5186, 0xE5F7, 0x518A, 0xF3FC,
+	0x518D, 0xEEA2, 0x5192, 0xD9B3, 0x5195, 0xD8F4, 0x5197, 0xE9B7,
+	0x51A0, 0xCEAE, 0x51A5, 0xD9A2, 0x51AA, 0xD8F1, 0x51AC, 0xD4CF,
+	0x51B6, 0xE5A7, 0x51B7, 0xD5D2, 0x51BD, 0xD6A9, 0x51C4, 0xF4A2,
+	0x51C6, 0xF1D7, 0x51C9, 0xD5D8, 0x51CB, 0xF0BD, 0x51CC, 0xD7D0,
+	0x51CD, 0xD4D0, 0x51DC, 0xD7CF, 0x51DD, 0xEBEA, 0x51DE, 0xFDEB,
+	0x51E1, 0xDBED, 0x51F0, 0xFCC5, 0x51F1, 0xCBC2, 0x51F6, 0xFDD5,
+	0x51F8, 0xF4C8, 0x51F9, 0xE8EA, 0x51FA, 0xF5F3, 0x51FD, 0xF9DE,
+	0x5200, 0xD3EF, 0x5203, 0xECD3, 0x5206, 0xDDC2, 0x5207, 0xEFB7,
+	0x5208, 0xE7D4, 0x520A, 0xCACA, 0x520E, 0xD9FB, 0x5211, 0xFAFD,
+	0x5217, 0xD6AA, 0x521D, 0xF4F8, 0x5224, 0xF7F7, 0x5225, 0xDCAC,
+	0x5229, 0xD7D7, 0x522A, 0xDFA2, 0x522E, 0xCEBE, 0x5230, 0xD3F0,
+	0x5236, 0xF0A4, 0x5237, 0xE1EC, 0x5238, 0xCFE7, 0x5239, 0xF3CB,
+	0x523A, 0xEDA9, 0x523B, 0xCABE, 0x5243, 0xF4EF, 0x5247, 0xF6CE,
+	0x524A, 0xDEFB, 0x524B, 0xD0BB, 0x524C, 0xD5B7, 0x524D, 0xEEF1,
+	0x5254, 0xF4A8, 0x5256, 0xDCF8, 0x525B, 0xCBA7, 0x525D, 0xDACE,
+	0x5261, 0xE0E6, 0x5269, 0xEDA5, 0x526A, 0xEEF2, 0x526F, 0xDCF9,
+	0x5272, 0xF9DC, 0x5275, 0xF3DC, 0x527D, 0xF8F2, 0x527F, 0xF4F9,
+	0x5283, 0xFCF1, 0x5287, 0xD0BC, 0x5288, 0xDBF9, 0x5289, 0xD7B1,
+	0x528D, 0xCBFC, 0x5291, 0xF0A5, 0x5292, 0xCBFD, 0x529B, 0xD5F4,
+	0x529F, 0xCDED, 0x52A0, 0xCAA5, 0x52A3, 0xD6AB, 0x52A4, 0xD0C2,
+	0x52A9, 0xF0BE, 0x52AA, 0xD2BD, 0x52AB, 0xCCA4, 0x52BE, 0xFAB6,
+	0x52C1, 0xCCCD, 0x52C3, 0xDAFA, 0x52C5, 0xF6CF, 0x52C7, 0xE9B8,
+	0x52C9, 0xD8F5, 0x52CD, 0xCCCE, 0x52D2, 0xD7CD, 0x52D5, 0xD4D1,
+	0x52D6, 0xE9ED, 0x52D8, 0xCAEB, 0x52D9, 0xD9E2, 0x52DB, 0xFDB2,
+	0x52DD, 0xE3AD, 0x52DE, 0xD6CC, 0x52DF, 0xD9B4, 0x52E2, 0xE1A7,
+	0x52E3, 0xEED3, 0x52E4, 0xD0C3, 0x52F3, 0xFDB3, 0x52F5, 0xD5E4,
+	0x52F8, 0xCFE8, 0x52FA, 0xEDC3, 0x52FB, 0xD0B2, 0x52FE, 0xCEFE,
+	0x52FF, 0xDAA8, 0x5305, 0xF8D0, 0x5308, 0xFDD6, 0x530D, 0xF8D1,
+	0x530F, 0xF8D2, 0x5310, 0xDCD3, 0x5315, 0xDDE2, 0x5316, 0xFBF9,
+	0x5317, 0xDDC1, 0x5319, 0xE3B5, 0x5320, 0xEDDD, 0x5321, 0xCEC4,
+	0x5323, 0xCBA1, 0x532A, 0xDDE3, 0x532F, 0xFCDD, 0x5339, 0xF9AF,
+	0x533F, 0xD2FB, 0x5340, 0xCFA1, 0x5341, 0xE4A8, 0x5343, 0xF4B6,
+	0x5344, 0xECFE, 0x5347, 0xE3AE, 0x5348, 0xE7ED, 0x5349, 0xFDC1,
+	0x534A, 0xDAE2, 0x534D, 0xD8B3, 0x5351, 0xDDE4, 0x5352, 0xF0EF,
+	0x5353, 0xF6F1, 0x5354, 0xFAF0, 0x5357, 0xD1F5, 0x535A, 0xDACF,
+	0x535C, 0xDCD4, 0x535E, 0xDCA6, 0x5360, 0xEFBF, 0x5366, 0xCECF,
+	0x5368, 0xE0D9, 0x536F, 0xD9D6, 0x5370, 0xECD4, 0x5371, 0xEACB,
+	0x5374, 0xCABF, 0x5375, 0xD5B0, 0x5377, 0xCFE9, 0x537D, 0xF1ED,
+	0x537F, 0xCCCF, 0x5384, 0xE4F8, 0x5393, 0xE4ED, 0x5398, 0xD7D8,
+	0x539A, 0xFDA7, 0x539F, 0xEAAB, 0x53A0, 0xF6B2, 0x53A5, 0xCFF0,
+	0x53A6, 0xF9BD, 0x53AD, 0xE6F4, 0x53BB, 0xCBDB, 0x53C3, 0xF3D1,
+	0x53C8, 0xE9D1, 0x53C9, 0xF3A9, 0x53CA, 0xD0E0, 0x53CB, 0xE9D2,
+	0x53CD, 0xDAE3, 0x53D4, 0xE2D2, 0x53D6, 0xF6A2, 0x53D7, 0xE1F4,
+	0x53DB, 0xDAE4, 0x53E1, 0xE7D5, 0x53E2, 0xF5BF, 0x53E3, 0xCFA2,
+	0x53E4, 0xCDAF, 0x53E5, 0xCFA3, 0x53E9, 0xCDB0, 0x53EA, 0xF1FE,
+	0x53EB, 0xD0A3, 0x53EC, 0xE1AF, 0x53ED, 0xF8A3, 0x53EF, 0xCAA6,
+	0x53F0, 0xF7BB, 0x53F1, 0xF2EA, 0x53F2, 0xDEC8, 0x53F3, 0xE9D3,
+	0x53F8, 0xDEC9, 0x5403, 0xFDDE, 0x5404, 0xCAC0, 0x5408, 0xF9EA,
+	0x5409, 0xD1CE, 0x540A, 0xEED4, 0x540C, 0xD4D2, 0x540D, 0xD9A3,
+	0x540E, 0xFDA8, 0x540F, 0xD7D9, 0x5410, 0xF7CE, 0x5411, 0xFABE,
+	0x541B, 0xCFD6, 0x541D, 0xD7F0, 0x541F, 0xEBE1, 0x5420, 0xF8C5,
+	0x5426, 0xDCFA, 0x5429, 0xDDC3, 0x542B, 0xF9DF, 0x5433, 0xE7EF,
+	0x5438, 0xFDE5, 0x5439, 0xF6A3, 0x543B, 0xD9FC, 0x543C, 0xFDA9,
+	0x543E, 0xE7EE, 0x5442, 0xD5E5, 0x5448, 0xEFD0, 0x544A, 0xCDB1,
+	0x5451, 0xF7A2, 0x5468, 0xF1B2, 0x546A, 0xF1B1, 0x5471, 0xCDB2,
+	0x5473, 0xDAAB, 0x5475, 0xCAA7, 0x547B, 0xE3E2, 0x547C, 0xFBBC,
+	0x547D, 0xD9A4, 0x5480, 0xEEBA, 0x5486, 0xF8D3, 0x548C, 0xFBFA,
+	0x548E, 0xCFA4, 0x5490, 0xDCFB, 0x54A4, 0xF6E3, 0x54A8, 0xEDAA,
+	0x54AB, 0xF2A1, 0x54AC, 0xCEE1, 0x54B3, 0xFAA6, 0x54B8, 0xF9E0,
+	0x54BD, 0xECD6, 0x54C0, 0xE4EE, 0x54C1, 0xF9A1, 0x54C4, 0xFBEF,
+	0x54C8, 0xF9EB, 0x54C9, 0xEEA3, 0x54E1, 0xEAAC, 0x54E5, 0xCAA8,
+	0x54E8, 0xF4FA, 0x54ED, 0xCDD6, 0x54EE, 0xFCF6, 0x54F2, 0xF4C9,
+	0x54FA, 0xF8D4, 0x5504, 0xF8A6, 0x5506, 0xDECA, 0x5507, 0xF2C6,
+	0x550E, 0xD7DA, 0x5510, 0xD3D0, 0x551C, 0xD8C5, 0x552F, 0xEAE6,
+	0x5531, 0xF3DD, 0x5535, 0xE4DA, 0x553E, 0xF6E4, 0x5544, 0xF6F2,
+	0x5546, 0xDFC2, 0x554F, 0xD9FD, 0x5553, 0xCCF6, 0x5556, 0xD3BA,
+	0x555E, 0xE4AF, 0x5563, 0xF9E1, 0x557C, 0xF0A6, 0x5580, 0xCBD3,
+	0x5584, 0xE0BC, 0x5586, 0xF4CA, 0x5587, 0xD4FA, 0x5589, 0xFDAA,
+	0x558A, 0xF9E2, 0x5598, 0xF4B7, 0x5599, 0xFDC2, 0x559A, 0xFCB0,
+	0x559C, 0xFDEC, 0x559D, 0xCAE2, 0x55A7, 0xFDBD, 0x55A9, 0xEAE7,
+	0x55AA, 0xDFC3, 0x55AB, 0xD1D2, 0x55AC, 0xCEE2, 0x55AE, 0xD3A4,
+	0x55C5, 0xFDAB, 0x55C7, 0xDFE0, 0x55D4, 0xF2C7, 0x55DA, 0xE7F0,
+	0x55DC, 0xD0EE, 0x55DF, 0xF3AA, 0x55E3, 0xDECB, 0x55E4, 0xF6B8,
+	0x55FD, 0xE1F5, 0x55FE, 0xF1B3, 0x5606, 0xF7A3, 0x5609, 0xCAA9,
+	0x5614, 0xCFA5, 0x5617, 0xDFC4, 0x562F, 0xE1B0, 0x5632, 0xF0BF,
+	0x5634, 0xF6A4, 0x5636, 0xE3B6, 0x5653, 0xFAC6, 0x5668, 0xD0EF,
+	0x566B, 0xFDED, 0x5674, 0xDDC4, 0x5686, 0xFCF7, 0x56A5, 0xE6BF,
+	0x56AC, 0xDEAD, 0x56AE, 0xFABF, 0x56B4, 0xE5F1, 0x56BC, 0xEDC4,
+	0x56CA, 0xD2A5, 0x56CD, 0xFDEE, 0x56D1, 0xF5B6, 0x56DA, 0xE1F6,
+	0x56DB, 0xDECC, 0x56DE, 0xFCDE, 0x56E0, 0xECD7, 0x56F0, 0xCDDD,
+	0x56F9, 0xD6B7, 0x56FA, 0xCDB3, 0x5703, 0xF8D5, 0x5704, 0xE5D8,
+	0x5708, 0xCFEA, 0x570B, 0xCFD0, 0x570D, 0xEACC, 0x5712, 0xEAAE,
+	0x5713, 0xEAAD, 0x5716, 0xD3F1, 0x5718, 0xD3A5, 0x571F, 0xF7CF,
+	0x5728, 0xEEA4, 0x572D, 0xD0A4, 0x5730, 0xF2A2, 0x573B, 0xD0F0,
+	0x5740, 0xF2A3, 0x5742, 0xF7F8, 0x5747, 0xD0B3, 0x574A, 0xDBA9,
+	0x574D, 0xD3BB, 0x574E, 0xCAEC, 0x5750, 0xF1A6, 0x5751, 0xCBD5,
+	0x5761, 0xF7E7, 0x5764, 0xCDDE, 0x5766, 0xF7A4, 0x576A, 0xF8C0,
+	0x576E, 0xD3DD, 0x5770, 0xCCD0, 0x5775, 0xCFA6, 0x577C, 0xF6F3,
+	0x5782, 0xE1F7, 0x5788, 0xD3DC, 0x578B, 0xFAFE, 0x5793, 0xFAA7,
+	0x57A0, 0xEBD9, 0x57A2, 0xCFA7, 0x57A3, 0xEAAF, 0x57C3, 0xE4EF,
+	0x57C7, 0xE9B9, 0x57C8, 0xF1D8, 0x57CB, 0xD8D8, 0x57CE, 0xE0F2,
+	0x57DF, 0xE6B4, 0x57E0, 0xDCFC, 0x57F0, 0xF3F1, 0x57F4, 0xE3D0,
+	0x57F7, 0xF2FB, 0x57F9, 0xDBC6, 0x57FA, 0xD0F1, 0x57FC, 0xD0F2,
+	0x5800, 0xCFDC, 0x5802, 0xD3D1, 0x5805, 0xCCB1, 0x5806, 0xF7D8,
+	0x5808, 0xCBA8, 0x5809, 0xEBBC, 0x580A, 0xE4BE, 0x581E, 0xF4DC,
+	0x5821, 0xDCC2, 0x5824, 0xF0A7, 0x5827, 0xE6C0, 0x582A, 0xCAED,
+	0x582F, 0xE8EB, 0x5830, 0xE5E8, 0x5831, 0xDCC3, 0x5834, 0xEDDE,
+	0x5835, 0xD3F2, 0x583A, 0xCCF7, 0x584A, 0xCED4, 0x584B, 0xE7AB,
+	0x584F, 0xCBC3, 0x5851, 0xE1B1, 0x5854, 0xF7B2, 0x5857, 0xD3F3,
+	0x5858, 0xD3D2, 0x585A, 0xF5C0, 0x585E, 0xDFDD, 0x5861, 0xEEF3,
+	0x5862, 0xE7F1, 0x5864, 0xFDB4, 0x5875, 0xF2C8, 0x5879, 0xF3D2,
+	0x587C, 0xEEF4, 0x587E, 0xE2D3, 0x5883, 0xCCD1, 0x5885, 0xDFEA,
+	0x5889, 0xE9BA, 0x5893, 0xD9D7, 0x589C, 0xF5CD, 0x589E, 0xF1F2,
+	0x589F, 0xFAC7, 0x58A8, 0xD9F8, 0x58A9, 0xD4C2, 0x58AE, 0xF6E5,
+	0x58B3, 0xDDC5, 0x58BA, 0xE7F2, 0x58BB, 0xEDDF, 0x58BE, 0xCACB,
+	0x58C1, 0xDBFA, 0x58C5, 0xE8B5, 0x58C7, 0xD3A6, 0x58CE, 0xFDB5,
+	0x58D1, 0xF9C9, 0x58D3, 0xE4E2, 0x58D5, 0xFBBD, 0x58D8, 0xD7A4,
+	0x58D9, 0xCEC5, 0x58DE, 0xCED5, 0x58DF, 0xD6E6, 0x58E4, 0xE5BD,
+	0x58EB, 0xDECD, 0x58EC, 0xECF3, 0x58EF, 0xEDE0, 0x58F9, 0xECEC,
+	0x58FA, 0xFBBE, 0x58FB, 0xDFEB, 0x58FD, 0xE1F8, 0x590F, 0xF9BE,
+	0x5914, 0xD0F3, 0x5915, 0xE0AA, 0x5916, 0xE8E2, 0x5919, 0xE2D4,
+	0x591A, 0xD2FD, 0x591C, 0xE5A8, 0x5922, 0xD9D3, 0x5927, 0xD3DE,
+	0x5929, 0xF4B8, 0x592A, 0xF7BC, 0x592B, 0xDCFD, 0x592D, 0xE8EC,
+	0x592E, 0xE4E7, 0x5931, 0xE3F7, 0x5937, 0xECA8, 0x593E, 0xFAF1,
+	0x5944, 0xE5F2, 0x5947, 0xD0F4, 0x5948, 0xD2AF, 0x5949, 0xDCE5,
+	0x594E, 0xD0A5, 0x594F, 0xF1B4, 0x5950, 0xFCB1, 0x5951, 0xCCF8,
+	0x5954, 0xDDC6, 0x5955, 0xFAD1, 0x5957, 0xF7DF, 0x595A, 0xFAA8,
+	0x5960, 0xEEF5, 0x5962, 0xDECE, 0x5967, 0xE7F3, 0x596A, 0xF7AC,
+	0x596B, 0xEBC4, 0x596C, 0xEDE1, 0x596D, 0xE0AB, 0x596E, 0xDDC7,
+	0x5973, 0xD2B3, 0x5974, 0xD2BF, 0x5978, 0xCACC, 0x597D, 0xFBBF,
+	0x5982, 0xE5FD, 0x5983, 0xDDE5, 0x5984, 0xD8CD, 0x598A, 0xECF4,
+	0x5993, 0xD0F5, 0x5996, 0xE8ED, 0x5997, 0xD0D2, 0x5999, 0xD9D8,
+	0x59A5, 0xF6E6, 0x59A8, 0xDBAA, 0x59AC, 0xF7E0, 0x59B9, 0xD8D9,
+	0x59BB, 0xF4A3, 0x59BE, 0xF4DD, 0x59C3, 0xEFD1, 0x59C6, 0xD9B5,
+	0x59C9, 0xEDAB, 0x59CB, 0xE3B7, 0x59D0, 0xEEBB, 0x59D1, 0xCDB4,
+	0x59D3, 0xE0F3, 0x59D4, 0xEACD, 0x59D9, 0xECF5, 0x59DA, 0xE8EE,
+	0x59DC, 0xCBA9, 0x59DD, 0xF1AF, 0x59E6, 0xCACD, 0x59E8, 0xECA9,
+	0x59EA, 0xF2EB, 0x59EC, 0xFDEF, 0x59EE, 0xF9F3, 0x59F8, 0xE6C1,
+	0x59FB, 0xECD8, 0x59FF, 0xEDAC, 0x5A01, 0xEACE, 0x5A03, 0xE8DF,
+	0x5A11, 0xDECF, 0x5A18, 0xD2A6, 0x5A1B, 0xE7F4, 0x5A1C, 0xD1D6,
+	0x5A1F, 0xE6C2, 0x5A20, 0xE3E3, 0x5A25, 0xE4B0, 0x5A29, 0xD8B4,
+	0x5A36, 0xF6A5, 0x5A3C, 0xF3DE, 0x5A41, 0xD7A5, 0x5A46, 0xF7E8,
+	0x5A49, 0xE8C6, 0x5A5A, 0xFBE6, 0x5A62, 0xDDE6, 0x5A66, 0xDCFE,
+	0x5A92, 0xD8DA, 0x5A9A, 0xDAAC, 0x5A9B, 0xEAB0, 0x5AA4, 0xE3B8,
+	0x5AC1, 0xCAAA, 0x5AC2, 0xE1F9, 0x5AC4, 0xEAB1, 0x5AC9, 0xF2EC,
+	0x5ACC, 0xFAEE, 0x5AE1, 0xEED5, 0x5AE6, 0xF9F4, 0x5AE9, 0xD2EC,
+	0x5B05, 0xFBFB, 0x5B09, 0xFDF0, 0x5B0B, 0xE0BD, 0x5B0C, 0xCEE3,
+	0x5B16, 0xF8C6, 0x5B2A, 0xDEAE, 0x5B40, 0xDFC5, 0x5B43, 0xE5BE,
+	0x5B50, 0xEDAD, 0x5B51, 0xFAEA, 0x5B54, 0xCDEE, 0x5B55, 0xEDA6,
+	0x5B57, 0xEDAE, 0x5B58, 0xF0ED, 0x5B5A, 0xDDA1, 0x5B5C, 0xEDAF,
+	0x5B5D, 0xFCF8, 0x5B5F, 0xD8EB, 0x5B63, 0xCCF9, 0x5B64, 0xCDB5,
+	0x5B69, 0xFAA9, 0x5B6B, 0xE1DD, 0x5B70, 0xE2D5, 0x5B71, 0xEDCF,
+	0x5B75, 0xDDA2, 0x5B78, 0xF9CA, 0x5B7A, 0xEAE8, 0x5B7C, 0xE5ED,
+	0x5B85, 0xD3EB, 0x5B87, 0xE9D4, 0x5B88, 0xE1FA, 0x5B89, 0xE4CC,
+	0x5B8B, 0xE1E4, 0x5B8C, 0xE8C7, 0x5B8F, 0xCEDB, 0x5B93, 0xDCD5,
+	0x5B95, 0xF7B5, 0x5B96, 0xFCF3, 0x5B97, 0xF0F3, 0x5B98, 0xCEAF,
+	0x5B99, 0xF1B5, 0x5B9A, 0xEFD2, 0x5B9B, 0xE8C8, 0x5B9C, 0xEBF1,
+	0x5BA2, 0xCBD4, 0x5BA3, 0xE0BE, 0x5BA4, 0xE3F8, 0x5BA5, 0xEAE9,
+	0x5BA6, 0xFCB2, 0x5BAC, 0xE0F4, 0x5BAE, 0xCFE0, 0x5BB0, 0xEEA5,
+	0x5BB3, 0xFAAA, 0x5BB4, 0xE6C3, 0x5BB5, 0xE1B2, 0x5BB6, 0xCAAB,
+	0x5BB8, 0xE3E4, 0x5BB9, 0xE9BB, 0x5BBF, 0xE2D6, 0x5BC0, 0xF3F2,
+	0x5BC2, 0xEED6, 0x5BC3, 0xEAB2, 0x5BC4, 0xD0F6, 0x5BC5, 0xECD9,
+	0x5BC6, 0xDACB, 0x5BC7, 0xCFA8, 0x5BCC, 0xDDA3, 0x5BD0, 0xD8DB,
+	0x5BD2, 0xF9CE, 0x5BD3, 0xE9D5, 0x5BD4, 0xE3D1, 0x5BD7, 0xD2BC,
+	0x5BDE, 0xD8AC, 0x5BDF, 0xF3CC, 0x5BE1, 0xCDFB, 0x5BE2, 0xF6D6,
+	0x5BE4, 0xE7F5, 0x5BE5, 0xE8EF, 0x5BE6, 0xE3F9, 0x5BE7, 0xD2BB,
+	0x5BE8, 0xF3F3, 0x5BE9, 0xE3FB, 0x5BEB, 0xDED0, 0x5BEC, 0xCEB0,
+	0x5BEE, 0xD6F7, 0x5BEF, 0xF1D9, 0x5BF5, 0xF5C1, 0x5BF6, 0xDCC4,
+	0x5BF8, 0xF5BB, 0x5BFA, 0xDED1, 0x5C01, 0xDCE6, 0x5C04, 0xDED2,
+	0x5C07, 0xEDE2, 0x5C08, 0xEEF6, 0x5C09, 0xEACF, 0x5C0A, 0xF0EE,
+	0x5C0B, 0xE3FC, 0x5C0D, 0xD3DF, 0x5C0E, 0xD3F4, 0x5C0F, 0xE1B3,
+	0x5C11, 0xE1B4, 0x5C16, 0xF4D3, 0x5C19, 0xDFC6, 0x5C24, 0xE9D6,
+	0x5C28, 0xDBAB, 0x5C31, 0xF6A6, 0x5C38, 0xE3B9, 0x5C39, 0xEBC5,
+	0x5C3A, 0xF4A9, 0x5C3B, 0xCDB6, 0x5C3C, 0xD2F9, 0x5C3E, 0xDAAD,
+	0x5C3F, 0xD2E3, 0x5C40, 0xCFD1, 0x5C45, 0xCBDC, 0x5C46, 0xCCFA,
+	0x5C48, 0xCFDD, 0x5C4B, 0xE8A9, 0x5C4D, 0xE3BB, 0x5C4E, 0xE3BA,
+	0x5C51, 0xE0DA, 0x5C55, 0xEEF7, 0x5C5B, 0xDCB3, 0x5C60, 0xD3F5,
+	0x5C62, 0xD7A6, 0x5C64, 0xF6B5, 0x5C65, 0xD7DB, 0x5C6C, 0xE1D5,
+	0x5C6F, 0xD4EA, 0x5C71, 0xDFA3, 0x5C79, 0xFDDF, 0x5C90, 0xD0F7,
+	0x5C91, 0xEDD4, 0x5CA1, 0xCBAA, 0x5CA9, 0xE4DB, 0x5CAB, 0xE1FB,
+	0x5CAC, 0xCBA2, 0x5CB1, 0xD3E0, 0x5CB3, 0xE4BF, 0x5CB5, 0xFBC0,
+	0x5CB7, 0xDABE, 0x5CB8, 0xE4CD, 0x5CBA, 0xD6B9, 0x5CBE, 0xEFC0,
+	0x5CC0, 0xE1FC, 0x5CD9, 0xF6B9, 0x5CE0, 0xDFC7, 0x5CE8, 0xE4B1,
+	0x5CEF, 0xDCE7, 0x5CF0, 0xDCE8, 0x5CF4, 0xFAD6, 0x5CF6, 0xD3F6,
+	0x5CFB, 0xF1DA, 0x5CFD, 0xFAF2, 0x5D07, 0xE2FD, 0x5D0D, 0xD5CF,
+	0x5D0E, 0xD0F8, 0x5D11, 0xCDDF, 0x5D14, 0xF5CB, 0x5D16, 0xE4F0,
+	0x5D17, 0xCBAB, 0x5D19, 0xD7C4, 0x5D27, 0xE2FE, 0x5D29, 0xDDDA,
+	0x5D4B, 0xDAAE, 0x5D4C, 0xCAEE, 0x5D50, 0xD5B9, 0x5D69, 0xE3A1,
+	0x5D6C, 0xE8E3, 0x5D6F, 0xF3AB, 0x5D87, 0xCFA9, 0x5D8B, 0xD3F7,
+	0x5D9D, 0xD4F1, 0x5DA0, 0xCEE4, 0x5DA2, 0xE8F2, 0x5DAA, 0xE5F5,
+	0x5DB8, 0xE7AE, 0x5DBA, 0xD6BA, 0x5DBC, 0xDFEC, 0x5DBD, 0xE4C0,
+	0x5DCD, 0xE8E4, 0x5DD2, 0xD8B5, 0x5DD6, 0xE4DC, 0x5DDD, 0xF4B9,
+	0x5DDE, 0xF1B6, 0x5DE1, 0xE2DE, 0x5DE2, 0xE1B5, 0x5DE5, 0xCDEF,
+	0x5DE6, 0xF1A7, 0x5DE7, 0xCEE5, 0x5DE8, 0xCBDD, 0x5DEB, 0xD9E3,
+	0x5DEE, 0xF3AC, 0x5DF1, 0xD0F9, 0x5DF2, 0xECAB, 0x5DF3, 0xDED3,
+	0x5DF4, 0xF7E9, 0x5DF7, 0xF9F5, 0x5DFD, 0xE1DE, 0x5DFE, 0xCBEE,
+	0x5E02, 0xE3BC, 0x5E03, 0xF8D6, 0x5E06, 0xDBEE, 0x5E0C, 0xFDF1,
+	0x5E11, 0xF7B6, 0x5E16, 0xF4DE, 0x5E19, 0xF2ED, 0x5E1B, 0xDBD9,
+	0x5E1D, 0xF0A8, 0x5E25, 0xE1FD, 0x5E2B, 0xDED4, 0x5E2D, 0xE0AC,
+	0x5E33, 0xEDE3, 0x5E36, 0xD3E1, 0x5E38, 0xDFC8, 0x5E3D, 0xD9B6,
+	0x5E3F, 0xFDAC, 0x5E40, 0xEFD3, 0x5E44, 0xE4C1, 0x5E45, 0xF8EB,
+	0x5E47, 0xDBAC, 0x5E4C, 0xFCC6, 0x5E55, 0xD8AD, 0x5E5F, 0xF6BA,
+	0x5E61, 0xDBDF, 0x5E62, 0xD3D3, 0x5E63, 0xF8C7, 0x5E72, 0xCACE,
+	0x5E73, 0xF8C1, 0x5E74, 0xD2B4, 0x5E77, 0xDCB4, 0x5E78, 0xFAB9,
+	0x5E79, 0xCACF, 0x5E7B, 0xFCB3, 0x5E7C, 0xEAEA, 0x5E7D, 0xEAEB,
+	0x5E7E, 0xD0FA, 0x5E84, 0xEDE4, 0x5E87, 0xDDE7, 0x5E8A, 0xDFC9,
+	0x5E8F, 0xDFED, 0x5E95, 0xEEBC, 0x5E97, 0xEFC1, 0x5E9A, 0xCCD2,
+	0x5E9C, 0xDDA4, 0x5EA0, 0xDFCA, 0x5EA6, 0xD3F8, 0x5EA7, 0xF1A8,
+	0x5EAB, 0xCDB7, 0x5EAD, 0xEFD4, 0x5EB5, 0xE4DD, 0x5EB6, 0xDFEE,
+	0x5EB7, 0xCBAC, 0x5EB8, 0xE9BC, 0x5EBE, 0xEAEC, 0x5EC2, 0xDFCB,
+	0x5EC8, 0xF9BF, 0x5EC9, 0xD6AF, 0x5ECA, 0xD5C6, 0x5ED0, 0xCFAA,
+	0x5ED3, 0xCEA9, 0x5ED6, 0xD6F8, 0x5EDA, 0xF1B7, 0x5EDB, 0xEEF8,
+	0x5EDF, 0xD9D9, 0x5EE0, 0xF3DF, 0x5EE2, 0xF8C8, 0x5EE3, 0xCEC6,
+	0x5EEC, 0xD5E6, 0x5EF3, 0xF4E6, 0x5EF6, 0xE6C5, 0x5EF7, 0xEFD5,
+	0x5EFA, 0xCBEF, 0x5EFB, 0xFCDF, 0x5F01, 0xDCA7, 0x5F04, 0xD6E7,
+	0x5F0A, 0xF8C9, 0x5F0F, 0xE3D2, 0x5F11, 0xE3BD, 0x5F13, 0xCFE1,
+	0x5F14, 0xF0C0, 0x5F15, 0xECDA, 0x5F17, 0xDDD7, 0x5F18, 0xFBF0,
+	0x5F1B, 0xECAC, 0x5F1F, 0xF0A9, 0x5F26, 0xFAD7, 0x5F27, 0xFBC1,
+	0x5F29, 0xD2C0, 0x5F31, 0xE5B0, 0x5F35, 0xEDE5, 0x5F3A, 0xCBAD,
+	0x5F3C, 0xF9B0, 0x5F48, 0xF7A5, 0x5F4A, 0xCBAE, 0x5F4C, 0xDAAF,
+	0x5F4E, 0xD8B6, 0x5F56, 0xD3A7, 0x5F57, 0xFBB2, 0x5F59, 0xFDC4,
+	0x5F5B, 0xECAD, 0x5F62, 0xFBA1, 0x5F66, 0xE5E9, 0x5F67, 0xE9EE,
+	0x5F69, 0xF3F4, 0x5F6A, 0xF8F3, 0x5F6B, 0xF0C1, 0x5F6C, 0xDEAF,
+	0x5F6D, 0xF8B0, 0x5F70, 0xF3E0, 0x5F71, 0xE7AF, 0x5F77, 0xDBAD,
+	0x5F79, 0xE6B5, 0x5F7C, 0xF9A8, 0x5F7F, 0xDDD8, 0x5F80, 0xE8D9,
+	0x5F81, 0xEFD6, 0x5F85, 0xD3E2, 0x5F87, 0xE2DF, 0x5F8A, 0xFCE0,
+	0x5F8B, 0xD7C8, 0x5F8C, 0xFDAD, 0x5F90, 0xDFEF, 0x5F91, 0xCCD3,
+	0x5F92, 0xD3F9, 0x5F97, 0xD4F0, 0x5F98, 0xDBC7, 0x5F99, 0xDED5,
+	0x5F9E, 0xF0F4, 0x5FA0, 0xD5D0, 0x5FA1, 0xE5D9, 0x5FA8, 0xFCC7,
+	0x5FA9, 0xDCD6, 0x5FAA, 0xE2E0, 0x5FAE, 0xDAB0, 0x5FB5, 0xF3A3,
+	0x5FB7, 0xD3EC, 0x5FB9, 0xF4CB, 0x5FBD, 0xFDC5, 0x5FC3, 0xE3FD,
+	0x5FC5, 0xF9B1, 0x5FCC, 0xD0FB, 0x5FCD, 0xECDB, 0x5FD6, 0xF5BC,
+	0x5FD7, 0xF2A4, 0x5FD8, 0xD8CE, 0x5FD9, 0xD8CF, 0x5FE0, 0xF5F7,
+	0x5FEB, 0xF6E1, 0x5FF5, 0xD2B7, 0x5FFD, 0xFBEC, 0x5FFF, 0xDDC8,
+	0x600F, 0xE4E8, 0x6012, 0xD2C1, 0x6016, 0xF8D7, 0x601C, 0xD6BB,
+	0x601D, 0xDED6, 0x6020, 0xF7BD, 0x6021, 0xECAE, 0x6025, 0xD0E1,
+	0x6027, 0xE0F5, 0x6028, 0xEAB3, 0x602A, 0xCED6, 0x602F, 0xCCA5,
+	0x6041, 0xECF6, 0x6042, 0xE2E1, 0x6043, 0xE3BE, 0x604D, 0xFCC8,
+	0x6050, 0xCDF0, 0x6052, 0xF9F6, 0x6055, 0xDFF0, 0x6059, 0xE5BF,
+	0x605D, 0xCEBF, 0x6062, 0xFCE1, 0x6063, 0xEDB0, 0x6064, 0xFDD1,
+	0x6065, 0xF6BB, 0x6068, 0xF9CF, 0x6069, 0xEBDA, 0x606A, 0xCAC1,
+	0x606C, 0xD2B8, 0x606D, 0xCDF1, 0x606F, 0xE3D3, 0x6070, 0xFDE6,
+	0x6085, 0xE6ED, 0x6089, 0xE3FA, 0x608C, 0xF0AA, 0x608D, 0xF9D0,
+	0x6094, 0xFCE2, 0x6096, 0xF8A7, 0x609A, 0xE1E5, 0x609B, 0xEEF9,
+	0x609F, 0xE7F6, 0x60A0, 0xEAED, 0x60A3, 0xFCB4, 0x60A4, 0xF5C2,
+	0x60A7, 0xD7DC, 0x60B0, 0xF0F5, 0x60B2, 0xDDE8, 0x60B3, 0xD3ED,
+	0x60B4, 0xF5FC, 0x60B6, 0xDABF, 0x60B8, 0xCCFB, 0x60BC, 0xD3FA,
+	0x60BD, 0xF4A4, 0x60C5, 0xEFD7, 0x60C7, 0xD4C3, 0x60D1, 0xFBE3,
+	0x60DA, 0xFBED, 0x60DC, 0xE0AD, 0x60DF, 0xEAEE, 0x60E0, 0xFBB3,
+	0x60E1, 0xE4C2, 0x60F0, 0xF6E7, 0x60F1, 0xD2DD, 0x60F3, 0xDFCC,
+	0x60F6, 0xFCC9, 0x60F9, 0xE5A9, 0x60FA, 0xE0F6, 0x60FB, 0xF6B3,
+	0x6101, 0xE1FE, 0x6106, 0xCBF0, 0x6108, 0xEAEF, 0x6109, 0xEAF0,
+	0x610D, 0xDAC0, 0x610E, 0xF8B4, 0x610F, 0xEBF2, 0x6115, 0xE4C3,
+	0x611A, 0xE9D7, 0x611B, 0xE4F1, 0x611F, 0xCAEF, 0x6127, 0xCED7,
+	0x6130, 0xFCCA, 0x6134, 0xF3E1, 0x6137, 0xCBC4, 0x613C, 0xE3E5,
+	0x613E, 0xCBC5, 0x613F, 0xEAB4, 0x6142, 0xE9BD, 0x6144, 0xD7C9,
+	0x6147, 0xEBDB, 0x6148, 0xEDB1, 0x614A, 0xCCC3, 0x614B, 0xF7BE,
+	0x614C, 0xFCCB, 0x6153, 0xF8F4, 0x6155, 0xD9B7, 0x6158, 0xF3D3,
+	0x6159, 0xF3D4, 0x615D, 0xF7E4, 0x615F, 0xF7D1, 0x6162, 0xD8B7,
+	0x6163, 0xCEB1, 0x6164, 0xCAC2, 0x6167, 0xFBB4, 0x6168, 0xCBC6,
+	0x616B, 0xF0F6, 0x616E, 0xD5E7, 0x6170, 0xEAD0, 0x6176, 0xCCD4,
+	0x6177, 0xCBAF, 0x617D, 0xF4AA, 0x617E, 0xE9AF, 0x6181, 0xF5C3,
+	0x6182, 0xE9D8, 0x618A, 0xDDE9, 0x618E, 0xF1F3, 0x6190, 0xD5FB,
+	0x6191, 0xDEBB, 0x6194, 0xF4FB, 0x6198, 0xFDF3, 0x6199, 0xFDF2,
+	0x619A, 0xF7A6, 0x61A4, 0xDDC9, 0x61A7, 0xD4D3, 0x61A9, 0xCCA8,
+	0x61AB, 0xDAC1, 0x61AC, 0xCCD5, 0x61AE, 0xD9E4, 0x61B2, 0xFACA,
+	0x61B6, 0xE5E3, 0x61BA, 0xD3BC, 0x61BE, 0xCAF0, 0x61C3, 0xD0C4,
+	0x61C7, 0xCAD0, 0x61C8, 0xFAAB, 0x61C9, 0xEBEB, 0x61CA, 0xE7F8,
+	0x61CB, 0xD9E5, 0x61E6, 0xD1D7, 0x61F2, 0xF3A4, 0x61F6, 0xD4FB,
+	0x61F7, 0xFCE3, 0x61F8, 0xFAD8, 0x61FA, 0xF3D5, 0x61FC, 0xCFAB,
+	0x61FF, 0xEBF3, 0x6200, 0xD5FC, 0x6207, 0xD3D4, 0x6208, 0xCDFC,
+	0x620A, 0xD9E6, 0x620C, 0xE2F9, 0x620D, 0xE2A1, 0x620E, 0xEBD4,
+	0x6210, 0xE0F7, 0x6211, 0xE4B2, 0x6212, 0xCCFC, 0x6216, 0xFBE4,
+	0x621A, 0xF4AB, 0x621F, 0xD0BD, 0x6221, 0xCAF1, 0x622A, 0xEFB8,
+	0x622E, 0xD7C0, 0x6230, 0xEEFA, 0x6231, 0xFDF4, 0x6234, 0xD3E3,
+	0x6236, 0xFBC2, 0x623E, 0xD5E8, 0x623F, 0xDBAE, 0x6240, 0xE1B6,
+	0x6241, 0xF8B7, 0x6247, 0xE0BF, 0x6248, 0xFBC3, 0x6249, 0xDDEA,
+	0x624B, 0xE2A2, 0x624D, 0xEEA6, 0x6253, 0xF6E8, 0x6258, 0xF6F5,
+	0x626E, 0xDDCA, 0x6271, 0xD0E2, 0x6276, 0xDDA6, 0x6279, 0xDDEB,
+	0x627C, 0xE4F9, 0x627F, 0xE3AF, 0x6280, 0xD0FC, 0x6284, 0xF4FC,
+	0x6289, 0xCCBC, 0x628A, 0xF7EA, 0x6291, 0xE5E4, 0x6292, 0xDFF1,
+	0x6295, 0xF7E1, 0x6297, 0xF9F7, 0x6298, 0xEFB9, 0x629B, 0xF8D8,
+	0x62AB, 0xF9A9, 0x62B1, 0xF8D9, 0x62B5, 0xEEBD, 0x62B9, 0xD8C6,
+	0x62BC, 0xE4E3, 0x62BD, 0xF5CE, 0x62C2, 0xDDD9, 0x62C7, 0xD9E7,
+	0x62C8, 0xD2B9, 0x62C9, 0xD5C3, 0x62CC, 0xDAE5, 0x62CD, 0xDAD0,
+	0x62CF, 0xD1D9, 0x62D0, 0xCED8, 0x62D2, 0xCBDE, 0x62D3, 0xF4AC,
+	0x62D4, 0xDAFB, 0x62D6, 0xF6E9, 0x62D7, 0xE8F3, 0x62D8, 0xCFAC,
+	0x62D9, 0xF0F0, 0x62DB, 0xF4FD, 0x62DC, 0xDBC8, 0x62EC, 0xCEC0,
+	0x62ED, 0xE3D4, 0x62EE, 0xD1CF, 0x62EF, 0xF1F5, 0x62F1, 0xCDF2,
+	0x62F3, 0xCFEB, 0x62F7, 0xCDB8, 0x62FE, 0xE3A6, 0x62FF, 0xD1DA,
+	0x6301, 0xF2A5, 0x6307, 0xF2A6, 0x6309, 0xE4CE, 0x6311, 0xD3FB,
+	0x632B, 0xF1A9, 0x632F, 0xF2C9, 0x633A, 0xEFD8, 0x633B, 0xE6C9,
+	0x633D, 0xD8B8, 0x633E, 0xFAF3, 0x6349, 0xF3B5, 0x634C, 0xF8A4,
+	0x634F, 0xD1F3, 0x6350, 0xE6C8, 0x6355, 0xF8DA, 0x6367, 0xDCE9,
+	0x6368, 0xDED7, 0x636E, 0xCBDF, 0x6372, 0xCFEC, 0x6377, 0xF4DF,
+	0x637A, 0xD1F4, 0x637B, 0xD2BA, 0x637F, 0xDFF2, 0x6383, 0xE1B7,
+	0x6388, 0xE2A3, 0x6389, 0xD3FC, 0x638C, 0xEDE6, 0x6392, 0xDBC9,
+	0x6396, 0xE4FA, 0x6398, 0xCFDE, 0x639B, 0xCED0, 0x63A0, 0xD5D3,
+	0x63A1, 0xF3F5, 0x63A2, 0xF7AE, 0x63A5, 0xEFC8, 0x63A7, 0xCDF3,
+	0x63A8, 0xF5CF, 0x63A9, 0xE5F3, 0x63AA, 0xF0C2, 0x63C0, 0xCAD1,
+	0x63C4, 0xEAF1, 0x63C6, 0xD0A6, 0x63CF, 0xD9DA, 0x63D0, 0xF0AB,
+	0x63D6, 0xEBE7, 0x63DA, 0xE5C0, 0x63DB, 0xFCB5, 0x63E1, 0xE4C4,
+	0x63ED, 0xCCA9, 0x63EE, 0xFDC6, 0x63F4, 0xEAB5, 0x63F6, 0xE5AA,
+	0x63F7, 0xDFBA, 0x640D, 0xE1DF, 0x640F, 0xDAD1, 0x6414, 0xE1B8,
+	0x6416, 0xE8F4, 0x6417, 0xD3FD, 0x641C, 0xE2A4, 0x6422, 0xF2CA,
+	0x642C, 0xDAE6, 0x642D, 0xF7B3, 0x643A, 0xFDCD, 0x643E, 0xF3B6,
+	0x6458, 0xEED7, 0x6460, 0xF5C4, 0x6469, 0xD8A4, 0x646F, 0xF2A7,
+	0x6478, 0xD9B8, 0x6479, 0xD9B9, 0x647A, 0xEFC9, 0x6488, 0xD6CE,
+	0x6491, 0xF7CB, 0x6492, 0xDFAE, 0x6493, 0xE8F5, 0x649A, 0xD2B5,
+	0x649E, 0xD3D5, 0x64A4, 0xF4CC, 0x64A5, 0xDAFC, 0x64AB, 0xD9E8,
+	0x64AD, 0xF7EB, 0x64AE, 0xF5C9, 0x64B0, 0xF3BC, 0x64B2, 0xDAD2,
+	0x64BB, 0xD3B5, 0x64C1, 0xE8B6, 0x64C4, 0xD6CF, 0x64C5, 0xF4BA,
+	0x64C7, 0xF7C9, 0x64CA, 0xCCAA, 0x64CD, 0xF0C3, 0x64CE, 0xCCD6,
+	0x64D2, 0xD0D3, 0x64D4, 0xD3BD, 0x64D8, 0xDBFB, 0x64DA, 0xCBE0,
+	0x64E1, 0xD3E4, 0x64E2, 0xF6F7, 0x64E5, 0xD5BA, 0x64E6, 0xF3CD,
+	0x64E7, 0xCBE1, 0x64EC, 0xEBF4, 0x64F2, 0xF4AD, 0x64F4, 0xFCAA,
+	0x64FA, 0xF7EC, 0x64FE, 0xE8F6, 0x6500, 0xDAE7, 0x6504, 0xF7CC,
+	0x6518, 0xE5C1, 0x651D, 0xE0EE, 0x6523, 0xD5FD, 0x652A, 0xCEE6,
+	0x652B, 0xFCAB, 0x652C, 0xD5BB, 0x652F, 0xF2A8, 0x6536, 0xE2A5,
+	0x6537, 0xCDB9, 0x6538, 0xEAF2, 0x6539, 0xCBC7, 0x653B, 0xCDF4,
+	0x653E, 0xDBAF, 0x653F, 0xEFD9, 0x6545, 0xCDBA, 0x6548, 0xFCF9,
+	0x654D, 0xDFF3, 0x654E, 0xCEE7, 0x654F, 0xDAC2, 0x6551, 0xCFAD,
+	0x6556, 0xE7F9, 0x6557, 0xF8A8, 0x655E, 0xF3E2, 0x6562, 0xCAF2,
+	0x6563, 0xDFA4, 0x6566, 0xD4C4, 0x656C, 0xCCD7, 0x656D, 0xE5C2,
+	0x6572, 0xCDBB, 0x6574, 0xEFDA, 0x6575, 0xEED8, 0x6577, 0xDDA7,
+	0x6578, 0xE2A6, 0x657E, 0xE0C0, 0x6582, 0xD6B0, 0x6583, 0xF8CA,
+	0x6585, 0xFCFA, 0x6587, 0xD9FE, 0x658C, 0xDEB0, 0x6590, 0xDDEC,
+	0x6591, 0xDAE8, 0x6597, 0xD4E0, 0x6599, 0xD6F9, 0x659B, 0xCDD7,
+	0x659C, 0xDED8, 0x659F, 0xF2F8, 0x65A1, 0xE4D6, 0x65A4, 0xD0C5,
+	0x65A5, 0xF4AE, 0x65A7, 0xDDA8, 0x65AB, 0xEDC5, 0x65AC, 0xF3D6,
+	0x65AF, 0xDED9, 0x65B0, 0xE3E6, 0x65B7, 0xD3A8, 0x65B9, 0xDBB0,
+	0x65BC, 0xE5DA, 0x65BD, 0xE3BF, 0x65C1, 0xDBB1, 0x65C5, 0xD5E9,
+	0x65CB, 0xE0C1, 0x65CC, 0xEFDB, 0x65CF, 0xF0E9, 0x65D2, 0xD7B2,
+	0x65D7, 0xD0FD, 0x65E0, 0xD9E9, 0x65E3, 0xD0FE, 0x65E5, 0xECED,
+	0x65E6, 0xD3A9, 0x65E8, 0xF2A9, 0x65E9, 0xF0C4, 0x65EC, 0xE2E2,
+	0x65ED, 0xE9EF, 0x65F1, 0xF9D1, 0x65F4, 0xE9D9, 0x65FA, 0xE8DA,
+	0x65FB, 0xDAC3, 0x65FC, 0xDAC4, 0x65FD, 0xD4C5, 0x65FF, 0xE7FA,
+	0x6606, 0xCDE0, 0x6607, 0xE3B0, 0x6609, 0xDBB2, 0x660A, 0xFBC4,
+	0x660C, 0xF3E3, 0x660E, 0xD9A5, 0x660F, 0xFBE7, 0x6610, 0xDDCB,
+	0x6611, 0xD0D4, 0x6613, 0xE6B6, 0x6614, 0xE0AE, 0x6615, 0xFDDA,
+	0x661E, 0xDCB5, 0x661F, 0xE0F8, 0x6620, 0xE7B1, 0x6625, 0xF5F0,
+	0x6627, 0xD8DC, 0x6628, 0xEDC6, 0x662D, 0xE1B9, 0x662F, 0xE3C0,
+	0x6630, 0xF9C0, 0x6631, 0xE9F0, 0x6634, 0xD9DB, 0x6636, 0xF3E4,
+	0x663A, 0xDCB6, 0x663B, 0xE4E9, 0x6641, 0xF0C5, 0x6642, 0xE3C1,
+	0x6643, 0xFCCC, 0x6644, 0xFCCD, 0x6649, 0xF2CB, 0x664B, 0xF2CC,
+	0x664F, 0xE4CF, 0x6659, 0xF1DB, 0x665B, 0xFAD9, 0x665D, 0xF1B8,
+	0x665E, 0xFDF5, 0x665F, 0xE0F9, 0x6664, 0xE7FB, 0x6665, 0xFCB7,
+	0x6666, 0xFCE4, 0x6667, 0xFBC5, 0x6668, 0xE3E7, 0x6669, 0xD8B9,
+	0x666B, 0xF6F8, 0x666E, 0xDCC5, 0x666F, 0xCCD8, 0x6673, 0xE0AF,
+	0x6674, 0xF4E7, 0x6676, 0xEFDC, 0x6677, 0xCFFC, 0x6678, 0xEFDD,
+	0x667A, 0xF2AA, 0x6684, 0xFDBE, 0x6687, 0xCAAC, 0x6688, 0xFDBB,
+	0x6689, 0xFDC7, 0x668E, 0xE7B2, 0x6690, 0xEAD1, 0x6691, 0xDFF4,
+	0x6696, 0xD1EC, 0x6697, 0xE4DE, 0x6698, 0xE5C3, 0x669D, 0xD9A6,
+	0x66A0, 0xCDBC, 0x66A2, 0xF3E5, 0x66AB, 0xEDD5, 0x66AE, 0xD9BA,
+	0x66B2, 0xEDE7, 0x66B3, 0xFBB5, 0x66B4, 0xF8EC, 0x66B9, 0xE0E7,
+	0x66BB, 0xCCD9, 0x66BE, 0xD4C6, 0x66C4, 0xE7A5, 0x66C6, 0xD5F5,
+	0x66C7, 0xD3BE, 0x66C9, 0xFCFB, 0x66D6, 0xE4F2, 0x66D9, 0xDFF5,
+	0x66DC, 0xE8F8, 0x66DD, 0xF8ED, 0x66E0, 0xCEC7, 0x66E6, 0xFDF6,
+	0x66F0, 0xE8D8, 0x66F2, 0xCDD8, 0x66F3, 0xE7D6, 0x66F4, 0xCCDA,
+	0x66F7, 0xCAE3, 0x66F8, 0xDFF6, 0x66F9, 0xF0C7, 0x66FA, 0xF0C6,
+	0x66FC, 0xD8BA, 0x66FE, 0xF1F4, 0x66FF, 0xF4F0, 0x6700, 0xF5CC,
+	0x6703, 0xFCE5, 0x6708, 0xEAC5, 0x6709, 0xEAF3, 0x670B, 0xDDDB,
+	0x670D, 0xDCD7, 0x6714, 0xDEFD, 0x6715, 0xF2F9, 0x6717, 0xD5C7,
+	0x671B, 0xD8D0, 0x671D, 0xF0C8, 0x671E, 0xD1A1, 0x671F, 0xD1A2,
+	0x6726, 0xD9D4, 0x6727, 0xD6E8, 0x6728, 0xD9CA, 0x672A, 0xDAB1,
+	0x672B, 0xD8C7, 0x672C, 0xDCE2, 0x672D, 0xF3CE, 0x672E, 0xF5F4,
+	0x6731, 0xF1B9, 0x6734, 0xDAD3, 0x6736, 0xF6EA, 0x673A, 0xCFF5,
+	0x673D, 0xFDAE, 0x6746, 0xCAD2, 0x6749, 0xDFB4, 0x674E, 0xD7DD,
+	0x674F, 0xFABA, 0x6750, 0xEEA7, 0x6751, 0xF5BD, 0x6753, 0xF8F5,
+	0x6756, 0xEDE8, 0x675C, 0xD4E1, 0x675E, 0xD1A3, 0x675F, 0xE1D6,
+	0x676D, 0xF9F8, 0x676F, 0xDBCA, 0x6770, 0xCBF9, 0x6771, 0xD4D4,
+	0x6773, 0xD9DC, 0x6775, 0xEEBE, 0x6777, 0xF7ED, 0x677B, 0xD2EE,
+	0x677E, 0xE1E6, 0x677F, 0xF7F9, 0x6787, 0xDDED, 0x6789, 0xE8DB,
+	0x678B, 0xDBB3, 0x678F, 0xD1F7, 0x6790, 0xE0B0, 0x6793, 0xD4E2,
+	0x6795, 0xF6D7, 0x6797, 0xD7F9, 0x679A, 0xD8DD, 0x679C, 0xCDFD,
+	0x679D, 0xF2AB, 0x67AF, 0xCDBD, 0x67B0, 0xF8C2, 0x67B3, 0xF2AC,
+	0x67B6, 0xCAAD, 0x67B7, 0xCAAE, 0x67B8, 0xCFAE, 0x67BE, 0xE3C2,
+	0x67C4, 0xDCB7, 0x67CF, 0xDBDA, 0x67D0, 0xD9BB, 0x67D1, 0xCAF3,
+	0x67D2, 0xF6D3, 0x67D3, 0xE6F8, 0x67D4, 0xEAF5, 0x67DA, 0xEAF6,
+	0x67DD, 0xF6F9, 0x67E9, 0xCFAF, 0x67EC, 0xCAD3, 0x67EF, 0xCAAF,
+	0x67F0, 0xD2B0, 0x67F1, 0xF1BA, 0x67F3, 0xD7B3, 0x67F4, 0xE3C3,
+	0x67F5, 0xF3FD, 0x67F6, 0xDEDA, 0x67FB, 0xDEDB, 0x67FE, 0xEFDE,
+	0x6812, 0xE2E3, 0x6813, 0xEEFB, 0x6816, 0xDFF7, 0x6817, 0xD7CA,
+	0x6821, 0xCEE8, 0x6822, 0xDBDB, 0x682A, 0xF1BB, 0x682F, 0xE9F1,
+	0x6838, 0xFAB7, 0x6839, 0xD0C6, 0x683C, 0xCCAB, 0x683D, 0xEEA8,
+	0x6840, 0xCBFA, 0x6841, 0xF9F9, 0x6842, 0xCCFD, 0x6843, 0xD3FE,
+	0x6848, 0xE4D0, 0x684E, 0xF2EE, 0x6850, 0xD4D5, 0x6851, 0xDFCD,
+	0x6853, 0xFCB8, 0x6854, 0xD1D0, 0x686D, 0xF2CD, 0x6876, 0xF7D2,
+	0x687F, 0xCAD4, 0x6881, 0xD5D9, 0x6885, 0xD8DE, 0x688F, 0xCDD9,
+	0x6893, 0xEEA9, 0x6894, 0xF6BC, 0x6897, 0xCCDB, 0x689D, 0xF0C9,
+	0x689F, 0xFCFC, 0x68A1, 0xE8C9, 0x68A2, 0xF4FE, 0x68A7, 0xE7FC,
+	0x68A8, 0xD7DE, 0x68AD, 0xDEDC, 0x68AF, 0xF0AC, 0x68B0, 0xCCFE,
+	0x68B1, 0xCDE1, 0x68B3, 0xE1BA, 0x68B5, 0xDBEF, 0x68B6, 0xDAB2,
+	0x68C4, 0xD1A5, 0x68C5, 0xDCB8, 0x68C9, 0xD8F6, 0x68CB, 0xD1A4,
+	0x68CD, 0xCDE2, 0x68D2, 0xDCEA, 0x68D5, 0xF0F7, 0x68D7, 0xF0CA,
+	0x68D8, 0xD0BE, 0x68DA, 0xDDDC, 0x68DF, 0xD4D6, 0x68E0, 0xD3D6,
+	0x68E7, 0xEDD0, 0x68E8, 0xCDA1, 0x68EE, 0xDFB5, 0x68F2, 0xDFF8,
+	0x68F9, 0xD4A1, 0x68FA, 0xCEB2, 0x6900, 0xE8CA, 0x6905, 0xEBF5,
+	0x690D, 0xE3D5, 0x690E, 0xF5D0, 0x6912, 0xF5A1, 0x6927, 0xD9A7,
+	0x6930, 0xE5AB, 0x693D, 0xE6CB, 0x693F, 0xF5F1, 0x694A, 0xE5C5,
+	0x6953, 0xF9A3, 0x6954, 0xE0DB, 0x6955, 0xF6EB, 0x6957, 0xCBF1,
+	0x6959, 0xD9EA, 0x695A, 0xF5A2, 0x695E, 0xD7D1, 0x6960, 0xD1F8,
+	0x6961, 0xEAF8, 0x6962, 0xEAF9, 0x6963, 0xDAB3, 0x6968, 0xEFDF,
+	0x696B, 0xF1EF, 0x696D, 0xE5F6, 0x696E, 0xEEBF, 0x696F, 0xE2E4,
+	0x6975, 0xD0BF, 0x6977, 0xFAAC, 0x6978, 0xF5D1, 0x6979, 0xE7B3,
+	0x6995, 0xE9BE, 0x699B, 0xF2CE, 0x699C, 0xDBB4, 0x69A5, 0xFCCE,
+	0x69A7, 0xDDEE, 0x69AE, 0xE7B4, 0x69B4, 0xD7B4, 0x69BB, 0xF7B4,
+	0x69C1, 0xCDBE, 0x69C3, 0xDAE9, 0x69CB, 0xCFB0, 0x69CC, 0xF7D9,
+	0x69CD, 0xF3E6, 0x69D0, 0xCED9, 0x69E8, 0xCEAA, 0x69EA, 0xCBC8,
+	0x69FB, 0xD0A7, 0x69FD, 0xF0CB, 0x69FF, 0xD0C7, 0x6A02, 0xE4C5,
+	0x6A0A, 0xDBE0, 0x6A11, 0xD5DA, 0x6A13, 0xD7A7, 0x6A17, 0xEEC0,
+	0x6A19, 0xF8F6, 0x6A1E, 0xF5D2, 0x6A1F, 0xEDE9, 0x6A21, 0xD9BC,
+	0x6A23, 0xE5C6, 0x6A35, 0xF5A3, 0x6A38, 0xDAD4, 0x6A39, 0xE2A7,
+	0x6A3A, 0xFBFC, 0x6A3D, 0xF1DC, 0x6A44, 0xCAF4, 0x6A48, 0xE8FA,
+	0x6A4B, 0xCEE9, 0x6A52, 0xE9F8, 0x6A53, 0xE2E5, 0x6A58, 0xD0B9,
+	0x6A59, 0xD4F2, 0x6A5F, 0xD1A6, 0x6A61, 0xDFCE, 0x6A6B, 0xFCF4,
+	0x6A80, 0xD3AA, 0x6A84, 0xCCAC, 0x6A89, 0xEFE0, 0x6A8D, 0xE5E5,
+	0x6A8E, 0xD0D5, 0x6A97, 0xDBFC, 0x6A9C, 0xFCE6, 0x6AA2, 0xCBFE,
+	0x6AA3, 0xEDEA, 0x6AB3, 0xDEB1, 0x6ABB, 0xF9E3, 0x6AC2, 0xD4A2,
+	0x6AC3, 0xCFF6, 0x6AD3, 0xD6D0, 0x6ADA, 0xD5EA, 0x6ADB, 0xF1EE,
+	0x6AF6, 0xFACB, 0x6AFB, 0xE5A1, 0x6B04, 0xD5B1, 0x6B0A, 0xCFED,
+	0x6B0C, 0xEDEB, 0x6B12, 0xD5B2, 0x6B16, 0xD5BC, 0x6B20, 0xFDE2,
+	0x6B21, 0xF3AD, 0x6B23, 0xFDDB, 0x6B32, 0xE9B0, 0x6B3A, 0xD1A7,
+	0x6B3D, 0xFDE3, 0x6B3E, 0xCEB3, 0x6B46, 0xFDE4, 0x6B47, 0xFACE,
+	0x6B4C, 0xCAB0, 0x6B4E, 0xF7A7, 0x6B50, 0xCFB1, 0x6B5F, 0xE6A2,
+	0x6B61, 0xFCB6, 0x6B62, 0xF2AD, 0x6B63, 0xEFE1, 0x6B64, 0xF3AE,
+	0x6B65, 0xDCC6, 0x6B66, 0xD9EB, 0x6B6A, 0xE8E0, 0x6B72, 0xE1A8,
+	0x6B77, 0xD5F6, 0x6B78, 0xCFFD, 0x6B7B, 0xDEDD, 0x6B7F, 0xD9D1,
+	0x6B83, 0xE4EA, 0x6B84, 0xF2CF, 0x6B86, 0xF7BF, 0x6B89, 0xE2E6,
+	0x6B8A, 0xE2A8, 0x6B96, 0xE3D6, 0x6B98, 0xEDD1, 0x6B9E, 0xE9F9,
+	0x6BAE, 0xD6B1, 0x6BAF, 0xDEB2, 0x6BB2, 0xE0E8, 0x6BB5, 0xD3AB,
+	0x6BB7, 0xEBDC, 0x6BBA, 0xDFAF, 0x6BBC, 0xCAC3, 0x6BBF, 0xEEFC,
+	0x6BC1, 0xFDC3, 0x6BC5, 0xEBF6, 0x6BC6, 0xCFB2, 0x6BCB, 0xD9EC,
+	0x6BCD, 0xD9BD, 0x6BCF, 0xD8DF, 0x6BD2, 0xD4B8, 0x6BD3, 0xEBBE,
+	0x6BD4, 0xDDEF, 0x6BD6, 0xDDF0, 0x6BD7, 0xDDF1, 0x6BD8, 0xDDF2,
+	0x6BDB, 0xD9BE, 0x6BEB, 0xFBC6, 0x6BEC, 0xCFB3, 0x6C08, 0xEEFD,
+	0x6C0F, 0xE4AB, 0x6C11, 0xDAC5, 0x6C13, 0xD8EC, 0x6C23, 0xD1A8,
+	0x6C34, 0xE2A9, 0x6C37, 0xDEBC, 0x6C38, 0xE7B5, 0x6C3E, 0xDBF0,
+	0x6C40, 0xEFE2, 0x6C41, 0xF1F0, 0x6C42, 0xCFB4, 0x6C4E, 0xDBF1,
+	0x6C50, 0xE0B1, 0x6C55, 0xDFA5, 0x6C57, 0xF9D2, 0x6C5A, 0xE7FD,
+	0x6C5D, 0xE6A3, 0x6C5E, 0xFBF1, 0x6C5F, 0xCBB0, 0x6C60, 0xF2AE,
+	0x6C68, 0xCDE7, 0x6C6A, 0xE8DC, 0x6C6D, 0xE7D7, 0x6C70, 0xF7C0,
+	0x6C72, 0xD0E3, 0x6C76, 0xDAA1, 0x6C7A, 0xCCBD, 0x6C7D, 0xD1A9,
+	0x6C7E, 0xDDCC, 0x6C81, 0xE3FE, 0x6C82, 0xD1AA, 0x6C83, 0xE8AA,
+	0x6C85, 0xEAB6, 0x6C86, 0xF9FA, 0x6C87, 0xE6CC, 0x6C88, 0xF6D8,
+	0x6C8C, 0xD4C7, 0x6C90, 0xD9CB, 0x6C92, 0xD9D2, 0x6C93, 0xD3CB,
+	0x6C94, 0xD8F7, 0x6C95, 0xDAA9, 0x6C96, 0xF5F8, 0x6C99, 0xDEDE,
+	0x6C9A, 0xF2AF, 0x6C9B, 0xF8A9, 0x6CAB, 0xD8C8, 0x6CAE, 0xEEC1,
+	0x6CB3, 0xF9C1, 0x6CB8, 0xDDF3, 0x6CB9, 0xEAFA, 0x6CBB, 0xF6BD,
+	0x6CBC, 0xE1BB, 0x6CBD, 0xCDBF, 0x6CBE, 0xF4D4, 0x6CBF, 0xE6CD,
+	0x6CC1, 0xFCCF, 0x6CC2, 0xFBA2, 0x6CC4, 0xE0DC, 0x6CC9, 0xF4BB,
+	0x6CCA, 0xDAD5, 0x6CCC, 0xF9B2, 0x6CD3, 0xFBF2, 0x6CD5, 0xDBF6,
+	0x6CD7, 0xDEDF, 0x6CDB, 0xDBF2, 0x6CE1, 0xF8DC, 0x6CE2, 0xF7EE,
+	0x6CE3, 0xEBE8, 0x6CE5, 0xD2FA, 0x6CE8, 0xF1BC, 0x6CEB, 0xFADA,
+	0x6CEE, 0xDAEA, 0x6CEF, 0xDAC6, 0x6CF0, 0xF7C1, 0x6CF3, 0xE7B6,
+	0x6D0B, 0xE5C7, 0x6D0C, 0xD6AC, 0x6D11, 0xDCC7, 0x6D17, 0xE1A9,
+	0x6D19, 0xE2AA, 0x6D1B, 0xD5A6, 0x6D1E, 0xD4D7, 0x6D25, 0xF2D0,
+	0x6D27, 0xEAFB, 0x6D29, 0xE0DD, 0x6D2A, 0xFBF3, 0x6D32, 0xF1BD,
+	0x6D35, 0xE2E7, 0x6D36, 0xFDD7, 0x6D38, 0xCEC8, 0x6D39, 0xEAB7,
+	0x6D3B, 0xFCC0, 0x6D3D, 0xFDE7, 0x6D3E, 0xF7EF, 0x6D41, 0xD7B5,
+	0x6D59, 0xEFBA, 0x6D5A, 0xF1DD, 0x6D5C, 0xDEB3, 0x6D63, 0xE8CB,
+	0x6D66, 0xF8DD, 0x6D69, 0xFBC7, 0x6D6A, 0xD5C8, 0x6D6C, 0xD7DF,
+	0x6D6E, 0xDDA9, 0x6D74, 0xE9B1, 0x6D77, 0xFAAD, 0x6D78, 0xF6D9,
+	0x6D79, 0xFAF4, 0x6D7F, 0xF8AA, 0x6D85, 0xE6EE, 0x6D87, 0xCCDC,
+	0x6D88, 0xE1BC, 0x6D89, 0xE0EF, 0x6D8C, 0xE9BF, 0x6D8D, 0xFCFD,
+	0x6D8E, 0xE6CE, 0x6D91, 0xE1D7, 0x6D93, 0xE6CF, 0x6D95, 0xF4F1,
+	0x6DAF, 0xE4F3, 0x6DB2, 0xE4FB, 0x6DB5, 0xF9E4, 0x6DC0, 0xEFE3,
+	0x6DC3, 0xCFEE, 0x6DC4, 0xF6BE, 0x6DC5, 0xE0B2, 0x6DC6, 0xFCFE,
+	0x6DC7, 0xD1AB, 0x6DCB, 0xD7FA, 0x6DCF, 0xFBC8, 0x6DD1, 0xE2D7,
+	0x6DD8, 0xD4A3, 0x6DD9, 0xF0F8, 0x6DDA, 0xD7A8, 0x6DDE, 0xE1E7,
+	0x6DE1, 0xD3BF, 0x6DE8, 0xEFE4, 0x6DEA, 0xD7C5, 0x6DEB, 0xEBE2,
+	0x6DEE, 0xFCE7, 0x6DF1, 0xE4A2, 0x6DF3, 0xE2E8, 0x6DF5, 0xE6D0,
+	0x6DF7, 0xFBE8, 0x6DF8, 0xF4E8, 0x6DF9, 0xE5F4, 0x6DFA, 0xF4BC,
+	0x6DFB, 0xF4D5, 0x6E17, 0xDFB6, 0x6E19, 0xFCB9, 0x6E1A, 0xEEC2,
+	0x6E1B, 0xCAF5, 0x6E1F, 0xEFE5, 0x6E20, 0xCBE2, 0x6E21, 0xD4A4,
+	0x6E23, 0xDEE0, 0x6E24, 0xDAFD, 0x6E25, 0xE4C6, 0x6E26, 0xE8BE,
+	0x6E2B, 0xE0DE, 0x6E2C, 0xF6B4, 0x6E2D, 0xEAD2, 0x6E2F, 0xF9FB,
+	0x6E32, 0xE0C2, 0x6E34, 0xCAE4, 0x6E36, 0xE7B7, 0x6E38, 0xEAFD,
+	0x6E3A, 0xD9DD, 0x6E3C, 0xDAB4, 0x6E3D, 0xEEAA, 0x6E3E, 0xFBE9,
+	0x6E43, 0xDBCB, 0x6E44, 0xDAB5, 0x6E4A, 0xF1BE, 0x6E4D, 0xD3AC,
+	0x6E56, 0xFBC9, 0x6E58, 0xDFCF, 0x6E5B, 0xD3C0, 0x6E5C, 0xE3D7,
+	0x6E5E, 0xEFE6, 0x6E5F, 0xFCD0, 0x6E67, 0xE9C0, 0x6E6B, 0xF5D3,
+	0x6E6E, 0xECDC, 0x6E6F, 0xF7B7, 0x6E72, 0xEAB8, 0x6E73, 0xD1F9,
+	0x6E7A, 0xDCC8, 0x6E90, 0xEAB9, 0x6E96, 0xF1DE, 0x6E9C, 0xD7B6,
+	0x6E9D, 0xCFB5, 0x6E9F, 0xD9A8, 0x6EA2, 0xECEE, 0x6EA5, 0xDDAA,
+	0x6EAA, 0xCDA2, 0x6EAB, 0xE8AE, 0x6EAF, 0xE1BD, 0x6EB1, 0xF2D1,
+	0x6EB6, 0xE9C1, 0x6EBA, 0xD2FC, 0x6EC2, 0xDBB5, 0x6EC4, 0xF3E7,
+	0x6EC5, 0xD8FE, 0x6EC9, 0xFCD1, 0x6ECB, 0xEDB2, 0x6ECC, 0xF4AF,
+	0x6ECE, 0xFBA3, 0x6ED1, 0xFCC1, 0x6ED3, 0xEEAB, 0x6ED4, 0xD4A5,
+	0x6EEF, 0xF4F2, 0x6EF4, 0xEED9, 0x6EF8, 0xFBCA, 0x6EFE, 0xCDE3,
+	0x6EFF, 0xD8BB, 0x6F01, 0xE5DB, 0x6F02, 0xF8F7, 0x6F06, 0xF6D4,
+	0x6F0F, 0xD7A9, 0x6F11, 0xCBC9, 0x6F14, 0xE6D1, 0x6F15, 0xF0CC,
+	0x6F20, 0xD8AE, 0x6F22, 0xF9D3, 0x6F23, 0xD5FE, 0x6F2B, 0xD8BC,
+	0x6F2C, 0xF2B0, 0x6F31, 0xE2AB, 0x6F32, 0xF3E8, 0x6F38, 0xEFC2,
+	0x6F3F, 0xEDEC, 0x6F41, 0xE7B8, 0x6F51, 0xDAFE, 0x6F54, 0xCCBE,
+	0x6F57, 0xF2FC, 0x6F58, 0xDAEB, 0x6F5A, 0xE2D8, 0x6F5B, 0xEDD6,
+	0x6F5E, 0xD6D1, 0x6F5F, 0xE0B3, 0x6F62, 0xFCD2, 0x6F64, 0xEBC8,
+	0x6F6D, 0xD3C1, 0x6F6E, 0xF0CD, 0x6F70, 0xCFF7, 0x6F7A, 0xEDD2,
+	0x6F7C, 0xD4D8, 0x6F7D, 0xDCC9, 0x6F7E, 0xD7F1, 0x6F81, 0xDFBB,
+	0x6F84, 0xF3A5, 0x6F88, 0xF4CD, 0x6F8D, 0xF1BF, 0x6F8E, 0xF8B1,
+	0x6F90, 0xE9FA, 0x6F94, 0xFBCB, 0x6F97, 0xCAD5, 0x6FA3, 0xF9D4,
+	0x6FA4, 0xF7CA, 0x6FA7, 0xD6C8, 0x6FAE, 0xFCE8, 0x6FAF, 0xF3BD,
+	0x6FB1, 0xEEFE, 0x6FB3, 0xE7FE, 0x6FB9, 0xD3C2, 0x6FBE, 0xD3B6,
+	0x6FC0, 0xCCAD, 0x6FC1, 0xF6FA, 0x6FC2, 0xD6B2, 0x6FC3, 0xD2D8,
+	0x6FCA, 0xE7D8, 0x6FD5, 0xE3A5, 0x6FDA, 0xE7B9, 0x6FDF, 0xF0AD,
+	0x6FE0, 0xFBCC, 0x6FE1, 0xEBA1, 0x6FE4, 0xD4A6, 0x6FE9, 0xFBCD,
+	0x6FEB, 0xD5BD, 0x6FEC, 0xF1DF, 0x6FEF, 0xF6FB, 0x6FF1, 0xDEB4,
+	0x6FFE, 0xD5EB, 0x7001, 0xE5C8, 0x7005, 0xFBA4, 0x7006, 0xD4B9,
+	0x7009, 0xDEE1, 0x700B, 0xE4A3, 0x700F, 0xD7B7, 0x7011, 0xF8EE,
+	0x7015, 0xDEB5, 0x7018, 0xD6D2, 0x701A, 0xF9D5, 0x701B, 0xE7BA,
+	0x701C, 0xEBD5, 0x701D, 0xD5F7, 0x701E, 0xEFE7, 0x701F, 0xE1BE,
+	0x7023, 0xFAAE, 0x7027, 0xD6E9, 0x7028, 0xD6EE, 0x702F, 0xE7BB,
+	0x7037, 0xECCB, 0x703E, 0xD5B3, 0x704C, 0xCEB4, 0x7050, 0xFBA5,
+	0x7051, 0xE1EE, 0x7058, 0xF7A8, 0x705D, 0xFBCE, 0x7063, 0xD8BD,
+	0x706B, 0xFBFD, 0x7070, 0xFCE9, 0x7078, 0xCFB6, 0x707C, 0xEDC7,
+	0x707D, 0xEEAC, 0x7085, 0xCCDD, 0x708A, 0xF6A7, 0x708E, 0xE6FA,
+	0x7092, 0xF5A4, 0x7098, 0xFDDC, 0x7099, 0xEDB3, 0x709A, 0xCEC9,
+	0x70A1, 0xEFE8, 0x70A4, 0xE1BF, 0x70AB, 0xFADB, 0x70AC, 0xCBE3,
+	0x70AD, 0xF7A9, 0x70AF, 0xFBA6, 0x70B3, 0xDCB9, 0x70B7, 0xF1C0,
+	0x70B8, 0xEDC8, 0x70B9, 0xEFC3, 0x70C8, 0xD6AD, 0x70CB, 0xFDCE,
+	0x70CF, 0xE8A1, 0x70D8, 0xFBF4, 0x70D9, 0xD5A7, 0x70DD, 0xF1F6,
+	0x70DF, 0xE6D3, 0x70F1, 0xCCDE, 0x70F9, 0xF8B2, 0x70FD, 0xDCEB,
+	0x7104, 0xFDB6, 0x7109, 0xE5EA, 0x710C, 0xF1E0, 0x7119, 0xDBCC,
+	0x711A, 0xDDCD, 0x711E, 0xD4C8, 0x7121, 0xD9ED, 0x7126, 0xF5A5,
+	0x7130, 0xE6FB, 0x7136, 0xE6D4, 0x7147, 0xFDC8, 0x7149, 0xD6A1,
+	0x714A, 0xFDBF, 0x714C, 0xFCD3, 0x714E, 0xEFA1, 0x7150, 0xE7BC,
+	0x7156, 0xD1EE, 0x7159, 0xE6D5, 0x715C, 0xE9F2, 0x715E, 0xDFB0,
+	0x7164, 0xD8E0, 0x7165, 0xFCBA, 0x7166, 0xFDAF, 0x7167, 0xF0CE,
+	0x7169, 0xDBE1, 0x716C, 0xE5C9, 0x716E, 0xEDB4, 0x717D, 0xE0C3,
+	0x7184, 0xE3D8, 0x7189, 0xE9FB, 0x718A, 0xEAA8, 0x718F, 0xFDB7,
+	0x7192, 0xFBA7, 0x7194, 0xE9C2, 0x7199, 0xFDF7, 0x719F, 0xE2D9,
+	0x71A2, 0xDCEC, 0x71AC, 0xE8A2, 0x71B1, 0xE6F0, 0x71B9, 0xFDF8,
+	0x71BA, 0xFDF9, 0x71BE, 0xF6BF, 0x71C1, 0xE7A7, 0x71C3, 0xE6D7,
+	0x71C8, 0xD4F3, 0x71C9, 0xD4C9, 0x71CE, 0xD6FA, 0x71D0, 0xD7F2,
+	0x71D2, 0xE1C0, 0x71D4, 0xDBE2, 0x71D5, 0xE6D8, 0x71DF, 0xE7BD,
+	0x71E5, 0xF0CF, 0x71E6, 0xF3BE, 0x71E7, 0xE2AC, 0x71ED, 0xF5B7,
+	0x71EE, 0xE0F0, 0x71FB, 0xFDB8, 0x71FC, 0xE3E8, 0x71FE, 0xD4A7,
+	0x71FF, 0xE8FC, 0x7200, 0xFAD2, 0x7206, 0xF8EF, 0x7210, 0xD6D3,
+	0x721B, 0xD5B4, 0x722A, 0xF0D0, 0x722C, 0xF7F0, 0x722D, 0xEEB3,
+	0x7230, 0xEABA, 0x7232, 0xEAD3, 0x7235, 0xEDC9, 0x7236, 0xDDAB,
+	0x723A, 0xE5AC, 0x723B, 0xFDA1, 0x723D, 0xDFD0, 0x723E, 0xECB3,
+	0x7240, 0xDFD1, 0x7246, 0xEDED, 0x7247, 0xF8B8, 0x7248, 0xF7FA,
+	0x724C, 0xF8AB, 0x7252, 0xF4E0, 0x7258, 0xD4BA, 0x7259, 0xE4B3,
+	0x725B, 0xE9DA, 0x725D, 0xDEB6, 0x725F, 0xD9BF, 0x7261, 0xD9C0,
+	0x7262, 0xD6EF, 0x7267, 0xD9CC, 0x7269, 0xDAAA, 0x7272, 0xDFE5,
+	0x7279, 0xF7E5, 0x727D, 0xCCB2, 0x7280, 0xDFF9, 0x7281, 0xD7E0,
+	0x72A2, 0xD4BB, 0x72A7, 0xFDFA, 0x72AC, 0xCCB3, 0x72AF, 0xDBF3,
+	0x72C0, 0xDFD2, 0x72C2, 0xCECA, 0x72C4, 0xEEDA, 0x72CE, 0xE4E4,
+	0x72D0, 0xFBCF, 0x72D7, 0xCFB7, 0x72D9, 0xEEC3, 0x72E1, 0xCEEA,
+	0x72E9, 0xE2AD, 0x72F8, 0xD7E1, 0x72F9, 0xFAF5, 0x72FC, 0xD5C9,
+	0x72FD, 0xF8AC, 0x730A, 0xE7D9, 0x7316, 0xF3E9, 0x731B, 0xD8ED,
+	0x731C, 0xE3C4, 0x731D, 0xF0F1, 0x7325, 0xE8E5, 0x7329, 0xE0FA,
+	0x732A, 0xEEC4, 0x732B, 0xD9DE, 0x7336, 0xEBA2, 0x7337, 0xEBA3,
+	0x733E, 0xFCC2, 0x733F, 0xEABB, 0x7344, 0xE8AB, 0x7345, 0xDEE2,
+	0x7350, 0xEDEF, 0x7352, 0xE8A3, 0x7357, 0xCFF1, 0x7368, 0xD4BC,
+	0x736A, 0xFCEA, 0x7370, 0xE7BE, 0x7372, 0xFCF2, 0x7375, 0xD6B4,
+	0x7378, 0xE2AE, 0x737A, 0xD3B7, 0x737B, 0xFACC, 0x7384, 0xFADC,
+	0x7386, 0xEDB5, 0x7387, 0xE1E3, 0x7389, 0xE8AC, 0x738B, 0xE8DD,
+	0x738E, 0xEFE9, 0x7394, 0xF4BD, 0x7396, 0xCFB8, 0x7397, 0xE9DB,
+	0x7398, 0xD1AC, 0x739F, 0xDAC7, 0x73A7, 0xEBC9, 0x73A9, 0xE8CC,
+	0x73AD, 0xDEB7, 0x73B2, 0xD6BC, 0x73B3, 0xD3E5, 0x73B9, 0xFADD,
+	0x73C0, 0xDAD6, 0x73C2, 0xCAB1, 0x73C9, 0xDAC8, 0x73CA, 0xDFA6,
+	0x73CC, 0xF9B3, 0x73CD, 0xF2D2, 0x73CF, 0xCAC4, 0x73D6, 0xCECB,
+	0x73D9, 0xCDF5, 0x73DD, 0xFDB0, 0x73DE, 0xD5A8, 0x73E0, 0xF1C1,
+	0x73E3, 0xE2E9, 0x73E4, 0xDCCA, 0x73E5, 0xECB4, 0x73E6, 0xFAC0,
+	0x73E9, 0xFBA8, 0x73EA, 0xD0A8, 0x73ED, 0xDAEC, 0x73F7, 0xD9EE,
+	0x73F9, 0xE0FB, 0x73FD, 0xEFEA, 0x73FE, 0xFADE, 0x7401, 0xE0C4,
+	0x7403, 0xCFB9, 0x7405, 0xD5CA, 0x7406, 0xD7E2, 0x7407, 0xE2AF,
+	0x7409, 0xD7B8, 0x7413, 0xE8CD, 0x741B, 0xF6DA, 0x7420, 0xEFA2,
+	0x7421, 0xE2DA, 0x7422, 0xF6FC, 0x7425, 0xFBD0, 0x7426, 0xD1AD,
+	0x7428, 0xCDE4, 0x742A, 0xD1AE, 0x742B, 0xDCED, 0x742C, 0xE8CE,
+	0x742E, 0xF0F9, 0x742F, 0xCEB5, 0x7430, 0xE6FC, 0x7433, 0xD7FB,
+	0x7434, 0xD0D6, 0x7435, 0xDDF5, 0x7436, 0xF7F1, 0x7438, 0xF6FD,
+	0x743A, 0xDBF7, 0x743F, 0xFBEA, 0x7440, 0xE9DC, 0x7441, 0xD9C1,
+	0x7443, 0xF5F2, 0x7444, 0xE0C5, 0x744B, 0xEAD4, 0x7455, 0xF9C2,
+	0x7457, 0xEABC, 0x7459, 0xD2C5, 0x745A, 0xFBD1, 0x745B, 0xE7C0,
+	0x745C, 0xEBA5, 0x745E, 0xDFFA, 0x745F, 0xE3A2, 0x7460, 0xD7B9,
+	0x7462, 0xE9C3, 0x7464, 0xE8FD, 0x7465, 0xE8AF, 0x7468, 0xF2D3,
+	0x7469, 0xFBA9, 0x746A, 0xD8A5, 0x746F, 0xD5CB, 0x747E, 0xD0C8,
+	0x7482, 0xD1AF, 0x7483, 0xD7E3, 0x7487, 0xE0C6, 0x7489, 0xD6A2,
+	0x748B, 0xEDF0, 0x7498, 0xD7F3, 0x749C, 0xFCD4, 0x749E, 0xDAD7,
+	0x749F, 0xCCDF, 0x74A1, 0xF2D4, 0x74A3, 0xD1B0, 0x74A5, 0xCCE0,
+	0x74A7, 0xDBFD, 0x74A8, 0xF3BF, 0x74AA, 0xF0D1, 0x74B0, 0xFCBB,
+	0x74B2, 0xE2B0, 0x74B5, 0xE6A5, 0x74B9, 0xE2DB, 0x74BD, 0xDFDE,
+	0x74BF, 0xE0C7, 0x74C6, 0xF2EF, 0x74CA, 0xCCE1, 0x74CF, 0xD6EA,
+	0x74D4, 0xE7C2, 0x74D8, 0xCEB6, 0x74DA, 0xF3C0, 0x74DC, 0xCDFE,
+	0x74E0, 0xFBD2, 0x74E2, 0xF8F8, 0x74E3, 0xF7FB, 0x74E6, 0xE8BF,
+	0x74EE, 0xE8B7, 0x74F7, 0xEDB6, 0x7501, 0xDCBA, 0x7504, 0xCCB4,
+	0x7511, 0xF1F7, 0x7515, 0xE8B8, 0x7518, 0xCAF6, 0x751A, 0xE4A4,
+	0x751B, 0xF4D6, 0x751F, 0xDFE6, 0x7523, 0xDFA7, 0x7525, 0xDFE7,
+	0x7526, 0xE1C1, 0x7528, 0xE9C4, 0x752B, 0xDCCB, 0x752C, 0xE9C5,
+	0x7530, 0xEFA3, 0x7531, 0xEBA6, 0x7532, 0xCBA3, 0x7533, 0xE3E9,
+	0x7537, 0xD1FB, 0x7538, 0xEFA4, 0x753A, 0xEFEB, 0x7547, 0xD0B4,
+	0x754C, 0xCDA3, 0x754F, 0xE8E6, 0x7551, 0xEFA5, 0x7553, 0xD3CC,
+	0x7554, 0xDAED, 0x7559, 0xD7BA, 0x755B, 0xF2D5, 0x755C, 0xF5E5,
+	0x755D, 0xD9EF, 0x7562, 0xF9B4, 0x7565, 0xD5D4, 0x7566, 0xFDCF,
+	0x756A, 0xDBE3, 0x756F, 0xF1E1, 0x7570, 0xECB6, 0x7575, 0xFBFE,
+	0x7576, 0xD3D7, 0x7578, 0xD1B1, 0x757A, 0xCBB1, 0x757F, 0xD1B2,
+	0x7586, 0xCBB2, 0x7587, 0xF1C2, 0x758A, 0xF4E1, 0x758B, 0xF9B5,
+	0x758E, 0xE1C3, 0x758F, 0xE1C2, 0x7591, 0xEBF7, 0x759D, 0xDFA8,
+	0x75A5, 0xCBCA, 0x75AB, 0xE6B9, 0x75B1, 0xF8DE, 0x75B2, 0xF9AA,
+	0x75B3, 0xCAF7, 0x75B5, 0xEDB7, 0x75B8, 0xD3B8, 0x75B9, 0xF2D6,
+	0x75BC, 0xD4D9, 0x75BD, 0xEEC5, 0x75BE, 0xF2F0, 0x75C2, 0xCAB2,
+	0x75C5, 0xDCBB, 0x75C7, 0xF1F8, 0x75CD, 0xECB7, 0x75D2, 0xE5CA,
+	0x75D4, 0xF6C0, 0x75D5, 0xFDDD, 0x75D8, 0xD4E3, 0x75D9, 0xCCE2,
+	0x75DB, 0xF7D4, 0x75E2, 0xD7E5, 0x75F0, 0xD3C3, 0x75F2, 0xD8A6,
+	0x75F4, 0xF6C1, 0x75FA, 0xDDF6, 0x75FC, 0xCDC0, 0x7600, 0xE5DC,
+	0x760D, 0xE5CB, 0x7619, 0xE1C4, 0x761F, 0xE8B0, 0x7620, 0xF4B0,
+	0x7621, 0xF3EA, 0x7622, 0xDAEE, 0x7624, 0xD7BB, 0x7626, 0xE2B1,
+	0x763B, 0xD7AA, 0x7642, 0xD6FB, 0x764C, 0xE4DF, 0x764E, 0xCAD6,
+	0x7652, 0xEBA8, 0x7656, 0xDBFE, 0x7661, 0xF6C2, 0x7664, 0xEFBB,
+	0x7669, 0xD4FD, 0x766C, 0xE0C8, 0x7670, 0xE8B9, 0x7672, 0xEFA6,
+	0x7678, 0xCDA4, 0x767B, 0xD4F4, 0x767C, 0xDBA1, 0x767D, 0xDBDC,
+	0x767E, 0xDBDD, 0x7684, 0xEEDC, 0x7686, 0xCBCB, 0x7687, 0xFCD5,
+	0x768E, 0xCEEB, 0x7690, 0xCDC1, 0x7693, 0xFBD3, 0x76AE, 0xF9AB,
+	0x76BA, 0xF5D4, 0x76BF, 0xD9A9, 0x76C2, 0xE9DD, 0x76C3, 0xDBCD,
+	0x76C6, 0xDDCE, 0x76C8, 0xE7C3, 0x76CA, 0xECCC, 0x76D2, 0xF9EC,
+	0x76D6, 0xCBCC, 0x76DB, 0xE0FC, 0x76DC, 0xD4A8, 0x76DE, 0xEDD3,
+	0x76DF, 0xD8EF, 0x76E1, 0xF2D7, 0x76E3, 0xCAF8, 0x76E4, 0xDAEF,
+	0x76E7, 0xD6D4, 0x76EE, 0xD9CD, 0x76F2, 0xD8EE, 0x76F4, 0xF2C1,
+	0x76F8, 0xDFD3, 0x76FC, 0xDAF0, 0x76FE, 0xE2EA, 0x7701, 0xE0FD,
+	0x7704, 0xD8F8, 0x7708, 0xF7AF, 0x7709, 0xDAB6, 0x770B, 0xCAD7,
+	0x771E, 0xF2D8, 0x7720, 0xD8F9, 0x7729, 0xFADF, 0x7737, 0xCFEF,
+	0x7738, 0xD9C2, 0x773A, 0xF0D2, 0x773C, 0xE4D1, 0x7740, 0xF3B7,
+	0x774D, 0xFAE0, 0x775B, 0xEFEC, 0x7761, 0xE2B2, 0x7763, 0xD4BD,
+	0x7766, 0xD9CE, 0x776B, 0xF4E2, 0x7779, 0xD4A9, 0x777E, 0xCDC2,
+	0x777F, 0xE7DA, 0x778B, 0xF2D9, 0x7791, 0xD9AA, 0x779E, 0xD8BE,
+	0x77A5, 0xDCAD, 0x77AC, 0xE2EB, 0x77AD, 0xD6FC, 0x77B0, 0xCAF9,
+	0x77B3, 0xD4DA, 0x77BB, 0xF4D7, 0x77BC, 0xCCA1, 0x77BF, 0xCFBA,
+	0x77D7, 0xF5B8, 0x77DB, 0xD9C3, 0x77DC, 0xD0E8, 0x77E2, 0xE3C5,
+	0x77E3, 0xEBF8, 0x77E5, 0xF2B1, 0x77E9, 0xCFBB, 0x77ED, 0xD3AD,
+	0x77EE, 0xE8E1, 0x77EF, 0xCEEC, 0x77F3, 0xE0B4, 0x7802, 0xDEE3,
+	0x7812, 0xDDF7, 0x7825, 0xF2B2, 0x7826, 0xF3F6, 0x7827, 0xF6DB,
+	0x782C, 0xD7FE, 0x7832, 0xF8DF, 0x7834, 0xF7F2, 0x7845, 0xD0A9,
+	0x784F, 0xE6DA, 0x785D, 0xF5A6, 0x786B, 0xD7BC, 0x786C, 0xCCE3,
+	0x786F, 0xE6DB, 0x787C, 0xDDDD, 0x7881, 0xD1B3, 0x7887, 0xEFED,
+	0x788C, 0xD6DE, 0x788D, 0xE4F4, 0x788E, 0xE1EF, 0x7891, 0xDDF8,
+	0x7897, 0xE8CF, 0x78A3, 0xCAE5, 0x78A7, 0xDCA1, 0x78A9, 0xE0B5,
+	0x78BA, 0xFCAC, 0x78BB, 0xFCAD, 0x78BC, 0xD8A7, 0x78C1, 0xEDB8,
+	0x78C5, 0xDBB6, 0x78CA, 0xD6F0, 0x78CB, 0xF3AF, 0x78CE, 0xCDA5,
+	0x78D0, 0xDAF1, 0x78E8, 0xD8A8, 0x78EC, 0xCCE4, 0x78EF, 0xD1B4,
+	0x78F5, 0xCAD8, 0x78FB, 0xDAF2, 0x7901, 0xF5A7, 0x790E, 0xF5A8,
+	0x7916, 0xE6A6, 0x792A, 0xD5EC, 0x792B, 0xD5F8, 0x792C, 0xDAF3,
+	0x793A, 0xE3C6, 0x793E, 0xDEE4, 0x7940, 0xDEE5, 0x7941, 0xD1B5,
+	0x7947, 0xD1B6, 0x7948, 0xD1B7, 0x7949, 0xF2B3, 0x7950, 0xE9DE,
+	0x7956, 0xF0D3, 0x7957, 0xF2B4, 0x795A, 0xF0D4, 0x795B, 0xCBE4,
+	0x795C, 0xFBD4, 0x795D, 0xF5E6, 0x795E, 0xE3EA, 0x7960, 0xDEE6,
+	0x7965, 0xDFD4, 0x7968, 0xF8F9, 0x796D, 0xF0AE, 0x797A, 0xD1B8,
+	0x797F, 0xD6DF, 0x7981, 0xD0D7, 0x798D, 0xFCA1, 0x798E, 0xEFEE,
+	0x798F, 0xDCD8, 0x7991, 0xE9DF, 0x79A6, 0xE5DD, 0x79A7, 0xFDFB,
+	0x79AA, 0xE0C9, 0x79AE, 0xD6C9, 0x79B1, 0xD4AA, 0x79B3, 0xE5CC,
+	0x79B9, 0xE9E0, 0x79BD, 0xD0D8, 0x79BE, 0xFCA2, 0x79BF, 0xD4BE,
+	0x79C0, 0xE2B3, 0x79C1, 0xDEE7, 0x79C9, 0xDCBC, 0x79CA, 0xD2B6,
+	0x79CB, 0xF5D5, 0x79D1, 0xCEA1, 0x79D2, 0xF5A9, 0x79D5, 0xDDF9,
+	0x79D8, 0xDDFA, 0x79DF, 0xF0D5, 0x79E4, 0xF6DF, 0x79E6, 0xF2DA,
+	0x79E7, 0xE4EB, 0x79E9, 0xF2F1, 0x79FB, 0xECB9, 0x7A00, 0xFDFC,
+	0x7A05, 0xE1AA, 0x7A08, 0xCAD9, 0x7A0B, 0xEFEF, 0x7A0D, 0xF5AA,
+	0x7A14, 0xECF9, 0x7A17, 0xF8AD, 0x7A19, 0xF2C2, 0x7A1A, 0xF6C3,
+	0x7A1C, 0xD7D2, 0x7A1F, 0xF9A2, 0x7A20, 0xF0D6, 0x7A2E, 0xF0FA,
+	0x7A31, 0xF6E0, 0x7A36, 0xE9F3, 0x7A37, 0xF2C3, 0x7A3B, 0xD4AB,
+	0x7A3C, 0xCAB3, 0x7A3D, 0xCDA6, 0x7A3F, 0xCDC3, 0x7A40, 0xCDDA,
+	0x7A46, 0xD9CF, 0x7A49, 0xF6C4, 0x7A4D, 0xEEDD, 0x7A4E, 0xE7C4,
+	0x7A57, 0xE2B4, 0x7A61, 0xDFE2, 0x7A62, 0xE7DB, 0x7A69, 0xE8B1,
+	0x7A6B, 0xFCAE, 0x7A70, 0xE5CD, 0x7A74, 0xFAEB, 0x7A76, 0xCFBC,
+	0x7A79, 0xCFE2, 0x7A7A, 0xCDF6, 0x7A7D, 0xEFF0, 0x7A7F, 0xF4BE,
+	0x7A81, 0xD4CD, 0x7A84, 0xF3B8, 0x7A88, 0xE9A1, 0x7A92, 0xF2F2,
+	0x7A93, 0xF3EB, 0x7A95, 0xF0D7, 0x7A98, 0xCFD7, 0x7A9F, 0xCFDF,
+	0x7AA9, 0xE8C0, 0x7AAA, 0xE8C1, 0x7AAE, 0xCFE3, 0x7AAF, 0xE9A2,
+	0x7ABA, 0xD0AA, 0x7AC4, 0xF3C1, 0x7AC5, 0xD0AB, 0x7AC7, 0xD4E4,
+	0x7ACA, 0xEFBC, 0x7ACB, 0xD8A1, 0x7AD7, 0xD9DF, 0x7AD9, 0xF3D7,
+	0x7ADD, 0xDCBD, 0x7ADF, 0xCCE5, 0x7AE0, 0xEDF1, 0x7AE3, 0xF1E2,
+	0x7AE5, 0xD4DB, 0x7AEA, 0xE2B5, 0x7AED, 0xCAE6, 0x7AEF, 0xD3AE,
+	0x7AF6, 0xCCE6, 0x7AF9, 0xF1D3, 0x7AFA, 0xF5E7, 0x7AFF, 0xCADA,
+	0x7B0F, 0xFBEE, 0x7B11, 0xE1C5, 0x7B19, 0xDFE9, 0x7B1B, 0xEEDE,
+	0x7B1E, 0xF7C2, 0x7B20, 0xD8A2, 0x7B26, 0xDDAC, 0x7B2C, 0xF0AF,
+	0x7B2D, 0xD6BD, 0x7B39, 0xE1AB, 0x7B46, 0xF9B6, 0x7B49, 0xD4F5,
+	0x7B4B, 0xD0C9, 0x7B4C, 0xEFA7, 0x7B4D, 0xE2EC, 0x7B4F, 0xDBEA,
+	0x7B50, 0xCECC, 0x7B51, 0xF5E8, 0x7B52, 0xF7D5, 0x7B54, 0xD3CD,
+	0x7B56, 0xF3FE, 0x7B60, 0xD0B5, 0x7B6C, 0xE0FE, 0x7B6E, 0xDFFB,
+	0x7B75, 0xE6DD, 0x7B7D, 0xE8A4, 0x7B87, 0xCBCD, 0x7B8B, 0xEFA8,
+	0x7B8F, 0xEEB4, 0x7B94, 0xDAD8, 0x7B95, 0xD1B9, 0x7B97, 0xDFA9,
+	0x7B9A, 0xF3B0, 0x7B9D, 0xCCC4, 0x7BA1, 0xCEB7, 0x7BAD, 0xEFA9,
+	0x7BB1, 0xDFD5, 0x7BB4, 0xEDD7, 0x7BB8, 0xEEC6, 0x7BC0, 0xEFBD,
+	0x7BC1, 0xFCD6, 0x7BC4, 0xDBF4, 0x7BC6, 0xEFAA, 0x7BC7, 0xF8B9,
+	0x7BC9, 0xF5E9, 0x7BD2, 0xE3D9, 0x7BE0, 0xE1C6, 0x7BE4, 0xD4BF,
+	0x7BE9, 0xDEE8, 0x7C07, 0xF0EA, 0x7C12, 0xF3C2, 0x7C1E, 0xD3AF,
+	0x7C21, 0xCADB, 0x7C27, 0xFCD7, 0x7C2A, 0xEDD8, 0x7C2B, 0xE1C7,
+	0x7C3D, 0xF4D8, 0x7C3E, 0xD6B3, 0x7C3F, 0xDDAD, 0x7C43, 0xD5BE,
+	0x7C4C, 0xF1C3, 0x7C4D, 0xEEDF, 0x7C60, 0xD6EB, 0x7C64, 0xF4D9,
+	0x7C6C, 0xD7E6, 0x7C73, 0xDAB7, 0x7C83, 0xDDFB, 0x7C89, 0xDDCF,
+	0x7C92, 0xD8A3, 0x7C95, 0xDAD9, 0x7C97, 0xF0D8, 0x7C98, 0xEFC4,
+	0x7C9F, 0xE1D8, 0x7CA5, 0xF1D4, 0x7CA7, 0xEDF2, 0x7CAE, 0xD5DB,
+	0x7CB1, 0xD5DC, 0x7CB2, 0xF3C4, 0x7CB3, 0xCBD7, 0x7CB9, 0xE2B6,
+	0x7CBE, 0xEFF1, 0x7CCA, 0xFBD5, 0x7CD6, 0xD3D8, 0x7CDE, 0xDDD0,
+	0x7CDF, 0xF0D9, 0x7CE0, 0xCBB3, 0x7CE7, 0xD5DD, 0x7CFB, 0xCDA7,
+	0x7CFE, 0xD0AC, 0x7D00, 0xD1BA, 0x7D02, 0xF1C4, 0x7D04, 0xE5B3,
+	0x7D05, 0xFBF5, 0x7D06, 0xE9E1, 0x7D07, 0xFDE0, 0x7D08, 0xFCBC,
+	0x7D0A, 0xDAA2, 0x7D0B, 0xDAA3, 0x7D0D, 0xD2A1, 0x7D10, 0xD2EF,
+	0x7D14, 0xE2ED, 0x7D17, 0xDEE9, 0x7D18, 0xCEDC, 0x7D19, 0xF2B5,
+	0x7D1A, 0xD0E4, 0x7D1B, 0xDDD1, 0x7D20, 0xE1C8, 0x7D21, 0xDBB7,
+	0x7D22, 0xDFE3, 0x7D2B, 0xEDB9, 0x7D2C, 0xF1C5, 0x7D2E, 0xF3CF,
+	0x7D2F, 0xD7AB, 0x7D30, 0xE1AC, 0x7D33, 0xE3EB, 0x7D35, 0xEEC7,
+	0x7D39, 0xE1C9, 0x7D3A, 0xCAFA, 0x7D42, 0xF0FB, 0x7D43, 0xFAE1,
+	0x7D44, 0xF0DA, 0x7D45, 0xCCE7, 0x7D46, 0xDAF4, 0x7D50, 0xCCBF,
+	0x7D5E, 0xCEED, 0x7D61, 0xD5A9, 0x7D62, 0xFAE2, 0x7D66, 0xD0E5,
+	0x7D68, 0xEBD6, 0x7D6A, 0xECDF, 0x7D6E, 0xDFFC, 0x7D71, 0xF7D6,
+	0x7D72, 0xDEEA, 0x7D73, 0xCBB4, 0x7D76, 0xEFBE, 0x7D79, 0xCCB5,
+	0x7D7F, 0xCFBD, 0x7D8E, 0xEFF2, 0x7D8F, 0xE2B7, 0x7D93, 0xCCE8,
+	0x7D9C, 0xF0FC, 0x7DA0, 0xD6E0, 0x7DA2, 0xF1C6, 0x7DAC, 0xE2B8,
+	0x7DAD, 0xEBAB, 0x7DB1, 0xCBB5, 0x7DB2, 0xD8D1, 0x7DB4, 0xF4CE,
+	0x7DB5, 0xF3F7, 0x7DB8, 0xD7C6, 0x7DBA, 0xD1BB, 0x7DBB, 0xF7AA,
+	0x7DBD, 0xEDCA, 0x7DBE, 0xD7D3, 0x7DBF, 0xD8FA, 0x7DC7, 0xF6C5,
+	0x7DCA, 0xD1CC, 0x7DCB, 0xDDFC, 0x7DD6, 0xDFFD, 0x7DD8, 0xF9E5,
+	0x7DDA, 0xE0CA, 0x7DDD, 0xF2FD, 0x7DDE, 0xD3B0, 0x7DE0, 0xF4F3,
+	0x7DE1, 0xDAC9, 0x7DE3, 0xE6DE, 0x7DE8, 0xF8BA, 0x7DE9, 0xE8D0,
+	0x7DEC, 0xD8FB, 0x7DEF, 0xEAD5, 0x7DF4, 0xD6A3, 0x7DFB, 0xF6C6,
+	0x7E09, 0xF2DB, 0x7E0A, 0xE4FC, 0x7E15, 0xE8B2, 0x7E1B, 0xDADA,
+	0x7E1D, 0xF2DC, 0x7E1E, 0xFBD6, 0x7E1F, 0xE9B2, 0x7E21, 0xEEAD,
+	0x7E23, 0xFAE3, 0x7E2B, 0xDCEE, 0x7E2E, 0xF5EA, 0x7E2F, 0xE6E0,
+	0x7E31, 0xF0FD, 0x7E37, 0xD7AC, 0x7E3D, 0xF5C5, 0x7E3E, 0xEEE0,
+	0x7E41, 0xDBE5, 0x7E43, 0xDDDE, 0x7E46, 0xD9F0, 0x7E47, 0xE9A3,
+	0x7E52, 0xF1F9, 0x7E54, 0xF2C4, 0x7E55, 0xE0CB, 0x7E5E, 0xE9A4,
+	0x7E61, 0xE2B9, 0x7E69, 0xE3B1, 0x7E6A, 0xFCEB, 0x7E6B, 0xCDA8,
+	0x7E6D, 0xCCB6, 0x7E70, 0xF0DB, 0x7E79, 0xE6BA, 0x7E7C, 0xCDA9,
+	0x7E82, 0xF3C3, 0x7E8C, 0xE1D9, 0x7E8F, 0xEFAB, 0x7E93, 0xE7C5,
+	0x7E96, 0xE0E9, 0x7E98, 0xF3C5, 0x7E9B, 0xD4C0, 0x7E9C, 0xD5BF,
+	0x7F36, 0xDDAE, 0x7F38, 0xF9FC, 0x7F3A, 0xCCC0, 0x7F4C, 0xE5A2,
+	0x7F50, 0xCEB8, 0x7F54, 0xD8D2, 0x7F55, 0xF9D6, 0x7F6A, 0xF1AA,
+	0x7F6B, 0xCED1, 0x7F6E, 0xF6C7, 0x7F70, 0xDBEB, 0x7F72, 0xDFFE,
+	0x7F75, 0xD8E1, 0x7F77, 0xF7F3, 0x7F79, 0xD7E7, 0x7F85, 0xD4FE,
+	0x7F88, 0xD1BC, 0x7F8A, 0xE5CF, 0x7F8C, 0xCBB6, 0x7F8E, 0xDAB8,
+	0x7F94, 0xCDC4, 0x7F9A, 0xD6BE, 0x7F9E, 0xE2BA, 0x7FA4, 0xCFD8,
+	0x7FA8, 0xE0CC, 0x7FA9, 0xEBF9, 0x7FB2, 0xFDFD, 0x7FB8, 0xD7E8,
+	0x7FB9, 0xCBD8, 0x7FBD, 0xE9E2, 0x7FC1, 0xE8BA, 0x7FC5, 0xE3C7,
+	0x7FCA, 0xECCD, 0x7FCC, 0xECCE, 0x7FCE, 0xD6BF, 0x7FD2, 0xE3A7,
+	0x7FD4, 0xDFD6, 0x7FD5, 0xFDE8, 0x7FDF, 0xEEE1, 0x7FE0, 0xF6A8,
+	0x7FE1, 0xDDFD, 0x7FE9, 0xF8BB, 0x7FEB, 0xE8D1, 0x7FF0, 0xF9D7,
+	0x7FF9, 0xCEEE, 0x7FFC, 0xECCF, 0x8000, 0xE9A5, 0x8001, 0xD6D5,
+	0x8003, 0xCDC5, 0x8005, 0xEDBA, 0x8006, 0xD1BD, 0x8009, 0xCFBE,
+	0x800C, 0xECBB, 0x8010, 0xD2B1, 0x8015, 0xCCE9, 0x8017, 0xD9C4,
+	0x8018, 0xE9FC, 0x802D, 0xD1BE, 0x8033, 0xECBC, 0x8036, 0xE5AD,
+	0x803D, 0xF7B0, 0x803F, 0xCCEA, 0x8043, 0xD3C4, 0x8046, 0xD6C0,
+	0x804A, 0xD6FD, 0x8056, 0xE1A1, 0x8058, 0xDEBD, 0x805A, 0xF6A9,
+	0x805E, 0xDAA4, 0x806F, 0xD6A4, 0x8070, 0xF5C6, 0x8072, 0xE1A2,
+	0x8073, 0xE9C6, 0x8077, 0xF2C5, 0x807D, 0xF4E9, 0x807E, 0xD6EC,
+	0x807F, 0xEBD3, 0x8084, 0xECBD, 0x8085, 0xE2DC, 0x8086, 0xDEEB,
+	0x8087, 0xF0DC, 0x8089, 0xEBBF, 0x808B, 0xD7CE, 0x808C, 0xD1BF,
+	0x8096, 0xF5AB, 0x809B, 0xF9FD, 0x809D, 0xCADC, 0x80A1, 0xCDC6,
+	0x80A2, 0xF2B6, 0x80A5, 0xDDFE, 0x80A9, 0xCCB7, 0x80AA, 0xDBB8,
+	0x80AF, 0xD0E9, 0x80B1, 0xCEDD, 0x80B2, 0xEBC0, 0x80B4, 0xFDA2,
+	0x80BA, 0xF8CB, 0x80C3, 0xEAD6, 0x80C4, 0xF1B0, 0x80CC, 0xDBCE,
+	0x80CE, 0xF7C3, 0x80DA, 0xDBCF, 0x80DB, 0xCBA4, 0x80DE, 0xF8E0,
+	0x80E1, 0xFBD7, 0x80E4, 0xEBCA, 0x80E5, 0xE0A1, 0x80F1, 0xCECD,
+	0x80F4, 0xD4DC, 0x80F8, 0xFDD8, 0x80FD, 0xD2F6, 0x8102, 0xF2B7,
+	0x8105, 0xFAF6, 0x8106, 0xF6AA, 0x8107, 0xFAF7, 0x8108, 0xD8E6,
+	0x810A, 0xF4B1, 0x8118, 0xE8D2, 0x811A, 0xCAC5, 0x811B, 0xCCEB,
+	0x8123, 0xE2EE, 0x8129, 0xE2BB, 0x812B, 0xF7AD, 0x812F, 0xF8E1,
+	0x8139, 0xF3EC, 0x813E, 0xDEA1, 0x814B, 0xE4FD, 0x814E, 0xE3EC,
+	0x8150, 0xDDAF, 0x8151, 0xDDB0, 0x8154, 0xCBB7, 0x8155, 0xE8D3,
+	0x8165, 0xE1A3, 0x8166, 0xD2E0, 0x816B, 0xF0FE, 0x8170, 0xE9A6,
+	0x8171, 0xCBF2, 0x8178, 0xEDF3, 0x8179, 0xDCD9, 0x817A, 0xE0CD,
+	0x817F, 0xF7DA, 0x8180, 0xDBB9, 0x8188, 0xCCAE, 0x818A, 0xDADB,
+	0x818F, 0xCDC7, 0x819A, 0xDDB1, 0x819C, 0xD8AF, 0x819D, 0xE3A3,
+	0x81A0, 0xCEEF, 0x81A3, 0xF2F3, 0x81A8, 0xF8B3, 0x81B3, 0xE0CE,
+	0x81B5, 0xF5FD, 0x81BA, 0xEBEC, 0x81BD, 0xD3C5, 0x81BE, 0xFCEC,
+	0x81BF, 0xD2DB, 0x81C0, 0xD4EB, 0x81C2, 0xDEA2, 0x81C6, 0xE5E6,
+	0x81CD, 0xF0B0, 0x81D8, 0xD5C4, 0x81DF, 0xEDF4, 0x81E3, 0xE3ED,
+	0x81E5, 0xE8C2, 0x81E7, 0xEDF5, 0x81E8, 0xD7FC, 0x81EA, 0xEDBB,
+	0x81ED, 0xF6AB, 0x81F3, 0xF2B8, 0x81F4, 0xF6C8, 0x81FA, 0xD3E6,
+	0x81FB, 0xF2DD, 0x81FC, 0xCFBF, 0x81FE, 0xEBAC, 0x8205, 0xCFC0,
+	0x8207, 0xE6A8, 0x8208, 0xFDE9, 0x820A, 0xCFC1, 0x820C, 0xE0DF,
+	0x820D, 0xDEEC, 0x8212, 0xE0A2, 0x821B, 0xF4BF, 0x821C, 0xE2EF,
+	0x821E, 0xD9F1, 0x821F, 0xF1C7, 0x8221, 0xCBB8, 0x822A, 0xF9FE,
+	0x822B, 0xDBBA, 0x822C, 0xDAF5, 0x8235, 0xF6EC, 0x8236, 0xDADC,
+	0x8237, 0xFAE4, 0x8239, 0xE0CF, 0x8240, 0xDDB2, 0x8245, 0xE6A9,
+	0x8247, 0xEFF3, 0x8259, 0xF3ED, 0x8264, 0xEBFA, 0x8266, 0xF9E6,
+	0x826E, 0xCADD, 0x826F, 0xD5DE, 0x8271, 0xCADE, 0x8272, 0xDFE4,
+	0x8276, 0xE6FD, 0x8278, 0xF5AC, 0x827E, 0xE4F5, 0x828B, 0xE9E3,
+	0x828D, 0xEDCB, 0x828E, 0xCFE4, 0x8292, 0xD8D3, 0x8299, 0xDDB3,
+	0x829A, 0xD4EC, 0x829D, 0xF2B9, 0x829F, 0xDFB7, 0x82A5, 0xCBCE,
+	0x82A6, 0xFBD8, 0x82A9, 0xD0D9, 0x82AC, 0xDDD2, 0x82AD, 0xF7F4,
+	0x82AE, 0xE7DC, 0x82AF, 0xE4A5, 0x82B1, 0xFCA3, 0x82B3, 0xDBBB,
+	0x82B7, 0xF2BA, 0x82B8, 0xE9FD, 0x82B9, 0xD0CA, 0x82BB, 0xF5D6,
+	0x82BC, 0xD9C5, 0x82BD, 0xE4B4, 0x82BF, 0xEDA7, 0x82D1, 0xEABD,
+	0x82D2, 0xE6FE, 0x82D4, 0xF7C4, 0x82D5, 0xF5AD, 0x82D7, 0xD9E0,
+	0x82DB, 0xCAB4, 0x82DE, 0xF8E2, 0x82DF, 0xCFC2, 0x82E1, 0xECBE,
+	0x82E5, 0xE5B4, 0x82E6, 0xCDC8, 0x82E7, 0xEEC8, 0x82F1, 0xE7C8,
+	0x82FD, 0xCDC9, 0x82FE, 0xF9B7, 0x8301, 0xF1E8, 0x8302, 0xD9F2,
+	0x8303, 0xDBF5, 0x8304, 0xCAB5, 0x8305, 0xD9C6, 0x8309, 0xD8C9,
+	0x8317, 0xD9AB, 0x8328, 0xEDBC, 0x832B, 0xD8D4, 0x832F, 0xDCDA,
+	0x8331, 0xE2BC, 0x8334, 0xFCED, 0x8335, 0xECE0, 0x8336, 0xD2FE,
+	0x8338, 0xE9C7, 0x8339, 0xE6AA, 0x8340, 0xE2F0, 0x8347, 0xFABB,
+	0x8349, 0xF5AE, 0x834A, 0xFBAA, 0x834F, 0xECFB, 0x8351, 0xECBF,
+	0x8352, 0xFCD8, 0x8373, 0xD4E5, 0x8377, 0xF9C3, 0x837B, 0xEEE2,
+	0x8389, 0xD7E9, 0x838A, 0xEDF6, 0x838E, 0xDEED, 0x8396, 0xCCEC,
+	0x8398, 0xE3EE, 0x839E, 0xE8D4, 0x83A2, 0xFAF8, 0x83A9, 0xDDB4,
+	0x83AA, 0xE4B5, 0x83AB, 0xD8B0, 0x83BD, 0xD8D5, 0x83C1, 0xF4EA,
+	0x83C5, 0xCEB9, 0x83C9, 0xD6E1, 0x83CA, 0xCFD2, 0x83CC, 0xD0B6,
+	0x83D3, 0xCEA2, 0x83D6, 0xF3EE, 0x83DC, 0xF3F8, 0x83E9, 0xDCCC,
+	0x83EB, 0xD0CB, 0x83EF, 0xFCA4, 0x83F0, 0xCDCA, 0x83F1, 0xD7D4,
+	0x83F2, 0xDEA3, 0x83F4, 0xE4E0, 0x83F9, 0xEEC9, 0x83FD, 0xE2DD,
+	0x8403, 0xF5FE, 0x8404, 0xD4AC, 0x840A, 0xD5D1, 0x840C, 0xD8F0,
+	0x840D, 0xF8C3, 0x840E, 0xEAD7, 0x8429, 0xF5D7, 0x842C, 0xD8BF,
+	0x8431, 0xFDC0, 0x8438, 0xEBAD, 0x843D, 0xD5AA, 0x8449, 0xE7A8,
+	0x8457, 0xEECA, 0x845B, 0xCAE7, 0x8461, 0xF8E3, 0x8463, 0xD4DD,
+	0x8466, 0xEAD8, 0x846B, 0xFBD9, 0x846C, 0xEDF7, 0x846F, 0xE5B5,
+	0x8475, 0xD0AD, 0x847A, 0xF1F1, 0x8490, 0xE2BD, 0x8494, 0xE3C8,
+	0x8499, 0xD9D5, 0x849C, 0xDFAA, 0x84A1, 0xDBBC, 0x84B2, 0xF8E4,
+	0x84B8, 0xF1FA, 0x84BB, 0xE5B6, 0x84BC, 0xF3EF, 0x84BF, 0xFBDA,
+	0x84C0, 0xE1E0, 0x84C2, 0xD9AC, 0x84C4, 0xF5EB, 0x84C6, 0xE0B6,
+	0x84C9, 0xE9C8, 0x84CB, 0xCBCF, 0x84CD, 0xE3C9, 0x84D1, 0xDEEE,
+	0x84DA, 0xE2BE, 0x84EC, 0xDCEF, 0x84EE, 0xD6A5, 0x84F4, 0xE2F1,
+	0x84FC, 0xD6FE, 0x8511, 0xD9A1, 0x8513, 0xD8C0, 0x8514, 0xDCDB,
+	0x8517, 0xEDBD, 0x8518, 0xDFB8, 0x851A, 0xEAA5, 0x851E, 0xD7AD,
+	0x8521, 0xF3F9, 0x8523, 0xEDF8, 0x8525, 0xF5C7, 0x852C, 0xE1CA,
+	0x852D, 0xEBE3, 0x852F, 0xF2DE, 0x853D, 0xF8CC, 0x853F, 0xEAD9,
+	0x8541, 0xD3C6, 0x8543, 0xDBE6, 0x8549, 0xF5AF, 0x854E, 0xCEF0,
+	0x8553, 0xE9FE, 0x8559, 0xFBB6, 0x8563, 0xE2F2, 0x8568, 0xCFF2,
+	0x8569, 0xF7B9, 0x856A, 0xD9F3, 0x856D, 0xE1CB, 0x8584, 0xDADD,
+	0x8587, 0xDAB9, 0x858F, 0xEBFB, 0x8591, 0xCBB9, 0x8594, 0xEDF9,
+	0x859B, 0xE0E0, 0x85A6, 0xF4C0, 0x85A8, 0xFDBC, 0x85A9, 0xDFB1,
+	0x85AA, 0xE3EF, 0x85AF, 0xE0A3, 0x85B0, 0xFDB9, 0x85BA, 0xF0B1,
+	0x85C1, 0xCDCB, 0x85C9, 0xEDBE, 0x85CD, 0xD5C0, 0x85CE, 0xE3F0,
+	0x85CF, 0xEDFA, 0x85D5, 0xE9E4, 0x85DC, 0xD5ED, 0x85DD, 0xE7DD,
+	0x85E4, 0xD4F6, 0x85E5, 0xE5B7, 0x85E9, 0xDBE7, 0x85EA, 0xE2BF,
+	0x85F7, 0xEECB, 0x85FA, 0xD7F4, 0x85FB, 0xF0DD, 0x85FF, 0xCEAB,
+	0x8602, 0xE7DE, 0x8606, 0xD6D6, 0x8607, 0xE1CC, 0x860A, 0xE8B3,
+	0x8616, 0xE5EE, 0x8617, 0xDCA2, 0x861A, 0xE0D0, 0x862D, 0xD5B5,
+	0x863F, 0xD5A1, 0x864E, 0xFBDB, 0x8650, 0xF9CB, 0x8654, 0xCBF3,
+	0x8655, 0xF4A5, 0x865B, 0xFAC8, 0x865C, 0xD6D7, 0x865E, 0xE9E5,
+	0x865F, 0xFBDC, 0x8667, 0xFDD0, 0x8679, 0xFBF6, 0x868A, 0xDAA5,
+	0x868C, 0xDBBD, 0x8693, 0xECE2, 0x86A3, 0xCDF7, 0x86A4, 0xF0DE,
+	0x86A9, 0xF6C9, 0x86C7, 0xDEEF, 0x86CB, 0xD3B1, 0x86D4, 0xFCEE,
+	0x86D9, 0xE8C3, 0x86DB, 0xF1C8, 0x86DF, 0xCEF1, 0x86E4, 0xF9ED,
+	0x86ED, 0xF2F4, 0x86FE, 0xE4B6, 0x8700, 0xF5B9, 0x8702, 0xDCF0,
+	0x8703, 0xE3F1, 0x8708, 0xE8A5, 0x8718, 0xF2BB, 0x871A, 0xDEA4,
+	0x871C, 0xDACC, 0x874E, 0xCAE9, 0x8755, 0xE3DA, 0x8757, 0xFCD9,
+	0x875F, 0xEADA, 0x8766, 0xF9C4, 0x8768, 0xE3A4, 0x8774, 0xFBDD,
+	0x8776, 0xEFCA, 0x8778, 0xE8C4, 0x8782, 0xD5CC, 0x878D, 0xEBD7,
+	0x879F, 0xD9AD, 0x87A2, 0xFBAB, 0x87B3, 0xD3D9, 0x87BA, 0xD5A2,
+	0x87C4, 0xF6DE, 0x87E0, 0xDAF6, 0x87EC, 0xE0D1, 0x87EF, 0xE9A8,
+	0x87F2, 0xF5F9, 0x87F9, 0xFAAF, 0x87FB, 0xEBFC, 0x87FE, 0xE0EA,
+	0x8805, 0xE3B2, 0x881F, 0xD5C5, 0x8822, 0xF1E3, 0x8823, 0xD5EE,
+	0x8831, 0xCDCC, 0x8836, 0xEDD9, 0x883B, 0xD8C1, 0x8840, 0xFAEC,
+	0x8846, 0xF1EB, 0x884C, 0xFABC, 0x884D, 0xE6E2, 0x8852, 0xFAE5,
+	0x8853, 0xE2FA, 0x8857, 0xCAB6, 0x8859, 0xE4B7, 0x885B, 0xEADB,
+	0x885D, 0xF5FA, 0x8861, 0xFBAC, 0x8862, 0xCFC3, 0x8863, 0xEBFD,
+	0x8868, 0xF8FA, 0x886B, 0xDFB9, 0x8870, 0xE1F1, 0x8872, 0xD2A4,
+	0x8877, 0xF5FB, 0x887E, 0xD0DA, 0x887F, 0xD0DB, 0x8881, 0xEABE,
+	0x8882, 0xD9B1, 0x8888, 0xCAB7, 0x888B, 0xD3E7, 0x888D, 0xF8E5,
+	0x8892, 0xD3B2, 0x8896, 0xE2C0, 0x8897, 0xF2DF, 0x889E, 0xCDE5,
+	0x88AB, 0xF9AC, 0x88B4, 0xCDCD, 0x88C1, 0xEEAE, 0x88C2, 0xD6AE,
+	0x88CF, 0xD7EA, 0x88D4, 0xE7E0, 0x88D5, 0xEBAE, 0x88D9, 0xCFD9,
+	0x88DC, 0xDCCD, 0x88DD, 0xEDFB, 0x88DF, 0xDEF0, 0x88E1, 0xD7EB,
+	0x88E8, 0xDEA5, 0x88F3, 0xDFD7, 0x88F4, 0xDBD0, 0x88F5, 0xDBD1,
+	0x88F8, 0xD5A3, 0x88FD, 0xF0B2, 0x8907, 0xDCDC, 0x8910, 0xCAE8,
+	0x8912, 0xF8E6, 0x8913, 0xDCCE, 0x8918, 0xEADC, 0x8919, 0xDBD2,
+	0x8925, 0xE9B3, 0x892A, 0xF7DB, 0x8936, 0xE3A8, 0x8938, 0xD7AE,
+	0x893B, 0xE0E1, 0x8941, 0xCBBA, 0x8944, 0xE5D1, 0x895F, 0xD0DC,
+	0x8964, 0xD5C1, 0x896A, 0xD8CA, 0x8972, 0xE3A9, 0x897F, 0xE0A4,
+	0x8981, 0xE9A9, 0x8983, 0xD3C7, 0x8986, 0xDCDD, 0x8987, 0xF8AE,
+	0x898B, 0xCCB8, 0x898F, 0xD0AE, 0x8993, 0xD8F2, 0x8996, 0xE3CA,
+	0x89A1, 0xCCAF, 0x89A9, 0xD4AD, 0x89AA, 0xF6D1, 0x89B2, 0xD0CC,
+	0x89BA, 0xCAC6, 0x89BD, 0xD5C2, 0x89C0, 0xCEBA, 0x89D2, 0xCAC7,
+	0x89E3, 0xFAB0, 0x89F4, 0xDFD8, 0x89F8, 0xF5BA, 0x8A00, 0xE5EB,
+	0x8A02, 0xEFF4, 0x8A03, 0xDDB5, 0x8A08, 0xCDAA, 0x8A0A, 0xE3F2,
+	0x8A0C, 0xFBF7, 0x8A0E, 0xF7D0, 0x8A13, 0xFDBA, 0x8A16, 0xFDE1,
+	0x8A17, 0xF6FE, 0x8A18, 0xD1C0, 0x8A1B, 0xE8C5, 0x8A1D, 0xE4B8,
+	0x8A1F, 0xE1E8, 0x8A23, 0xCCC1, 0x8A25, 0xD2ED, 0x8A2A, 0xDBBE,
+	0x8A2D, 0xE0E2, 0x8A31, 0xFAC9, 0x8A34, 0xE1CD, 0x8A36, 0xCAB8,
+	0x8A3A, 0xF2E0, 0x8A3B, 0xF1C9, 0x8A50, 0xDEF1, 0x8A54, 0xF0DF,
+	0x8A55, 0xF8C4, 0x8A5B, 0xEECC, 0x8A5E, 0xDEF2, 0x8A60, 0xE7C9,
+	0x8A62, 0xE2F3, 0x8A63, 0xE7E1, 0x8A66, 0xE3CB, 0x8A69, 0xE3CC,
+	0x8A6D, 0xCFF8, 0x8A6E, 0xEFAC, 0x8A70, 0xFDFE, 0x8A71, 0xFCA5,
+	0x8A72, 0xFAB1, 0x8A73, 0xDFD9, 0x8A75, 0xE0D2, 0x8A79, 0xF4DA,
+	0x8A85, 0xF1CA, 0x8A87, 0xCEA3, 0x8A8C, 0xF2BC, 0x8A8D, 0xECE3,
+	0x8A93, 0xE0A5, 0x8A95, 0xF7AB, 0x8A98, 0xEBAF, 0x8A9E, 0xE5DE,
+	0x8AA0, 0xE1A4, 0x8AA1, 0xCDAB, 0x8AA3, 0xD9F4, 0x8AA4, 0xE8A6,
+	0x8AA5, 0xCDCE, 0x8AA6, 0xE1E9, 0x8AA8, 0xFCEF, 0x8AAA, 0xE0E3,
+	0x8AB0, 0xE2C1, 0x8AB2, 0xCEA4, 0x8AB9, 0xDEA6, 0x8ABC, 0xEBFE,
+	0x8ABE, 0xEBDD, 0x8ABF, 0xF0E0, 0x8AC2, 0xF4DB, 0x8AC4, 0xE2F4,
+	0x8AC7, 0xD3C8, 0x8ACB, 0xF4EB, 0x8ACD, 0xEEB5, 0x8ACF, 0xF5D8,
+	0x8AD2, 0xD5DF, 0x8AD6, 0xD6E5, 0x8ADB, 0xEBB0, 0x8ADC, 0xF4E3,
+	0x8AE1, 0xE3CD, 0x8AE6, 0xF4F4, 0x8AE7, 0xFAB2, 0x8AEA, 0xEFF5,
+	0x8AEB, 0xCADF, 0x8AED, 0xEBB1, 0x8AEE, 0xEDBF, 0x8AF1, 0xFDC9,
+	0x8AF6, 0xE4A6, 0x8AF7, 0xF9A4, 0x8AF8, 0xF0B3, 0x8AFA, 0xE5EC,
+	0x8AFE, 0xD1E7, 0x8B00, 0xD9C7, 0x8B01, 0xE4D7, 0x8B02, 0xEADD,
+	0x8B04, 0xD4F7, 0x8B0E, 0xDABA, 0x8B10, 0xDACD, 0x8B14, 0xF9CC,
+	0x8B16, 0xE1DA, 0x8B17, 0xDBBF, 0x8B19, 0xCCC5, 0x8B1A, 0xECD0,
+	0x8B1B, 0xCBBB, 0x8B1D, 0xDEF3, 0x8B20, 0xE9AA, 0x8B28, 0xD9C8,
+	0x8B2B, 0xEEE3, 0x8B2C, 0xD7BD, 0x8B33, 0xCFC4, 0x8B39, 0xD0CD,
+	0x8B41, 0xFCA6, 0x8B49, 0xF1FB, 0x8B4E, 0xFDD2, 0x8B4F, 0xD1C1,
+	0x8B58, 0xE3DB, 0x8B5A, 0xD3C9, 0x8B5C, 0xDCCF, 0x8B66, 0xCCED,
+	0x8B6C, 0xDEA7, 0x8B6F, 0xE6BB, 0x8B70, 0xECA1, 0x8B74, 0xCCB9,
+	0x8B77, 0xFBDE, 0x8B7D, 0xE7E2, 0x8B80, 0xD4C1, 0x8B8A, 0xDCA8,
+	0x8B90, 0xE2C2, 0x8B92, 0xF3D8, 0x8B93, 0xE5D3, 0x8B96, 0xF3D9,
+	0x8B9A, 0xF3C6, 0x8C37, 0xCDDB, 0x8C3F, 0xCDAC, 0x8C41, 0xFCC3,
+	0x8C46, 0xD4E7, 0x8C48, 0xD1C2, 0x8C4A, 0xF9A5, 0x8C4C, 0xE8D5,
+	0x8C55, 0xE3CE, 0x8C5A, 0xD4CA, 0x8C61, 0xDFDA, 0x8C6A, 0xFBDF,
+	0x8C6B, 0xE7E3, 0x8C79, 0xF8FB, 0x8C7A, 0xE3CF, 0x8C82, 0xF5B0,
+	0x8C8A, 0xD8E7, 0x8C8C, 0xD9C9, 0x8C9D, 0xF8AF, 0x8C9E, 0xEFF6,
+	0x8CA0, 0xDDB6, 0x8CA1, 0xEEAF, 0x8CA2, 0xCDF8, 0x8CA7, 0xDEB8,
+	0x8CA8, 0xFCA7, 0x8CA9, 0xF7FC, 0x8CAA, 0xF7B1, 0x8CAB, 0xCEBB,
+	0x8CAC, 0xF4A1, 0x8CAF, 0xEECD, 0x8CB0, 0xE1AE, 0x8CB3, 0xECC3,
+	0x8CB4, 0xCFFE, 0x8CB6, 0xF8BF, 0x8CB7, 0xD8E2, 0x8CB8, 0xD3E8,
+	0x8CBB, 0xDEA8, 0x8CBC, 0xF4E4, 0x8CBD, 0xECC2, 0x8CBF, 0xD9F5,
+	0x8CC0, 0xF9C5, 0x8CC1, 0xDDD3, 0x8CC2, 0xD6F1, 0x8CC3, 0xECFC,
+	0x8CC4, 0xFCF0, 0x8CC7, 0xEDC0, 0x8CC8, 0xCAB9, 0x8CCA, 0xEEE4,
+	0x8CD1, 0xF2E1, 0x8CD3, 0xDEB9, 0x8CDA, 0xD6F2, 0x8CDC, 0xDEF4,
+	0x8CDE, 0xDFDB, 0x8CE0, 0xDBD3, 0x8CE2, 0xFAE7, 0x8CE3, 0xD8E3,
+	0x8CE4, 0xF4C1, 0x8CE6, 0xDDB7, 0x8CEA, 0xF2F5, 0x8CED, 0xD4AE,
+	0x8CF4, 0xD6F3, 0x8CFB, 0xDDB8, 0x8CFC, 0xCFC5, 0x8CFD, 0xDFDF,
+	0x8D04, 0xF2BE, 0x8D05, 0xF6A1, 0x8D07, 0xEBCB, 0x8D08, 0xF1FC,
+	0x8D0A, 0xF3C7, 0x8D0D, 0xE0EB, 0x8D13, 0xEDFC, 0x8D16, 0xE1DB,
+	0x8D64, 0xEEE5, 0x8D66, 0xDEF5, 0x8D6B, 0xFAD3, 0x8D70, 0xF1CB,
+	0x8D73, 0xD0AF, 0x8D74, 0xDDB9, 0x8D77, 0xD1C3, 0x8D85, 0xF5B1,
+	0x8D8A, 0xEAC6, 0x8D99, 0xF0E1, 0x8DA3, 0xF6AC, 0x8DA8, 0xF5D9,
+	0x8DB3, 0xF0EB, 0x8DBA, 0xDDBA, 0x8DBE, 0xF2BF, 0x8DC6, 0xF7C5,
+	0x8DCB, 0xDBA2, 0x8DCC, 0xF2F6, 0x8DCF, 0xCABA, 0x8DDB, 0xF7F5,
+	0x8DDD, 0xCBE5, 0x8DE1, 0xEEE6, 0x8DE3, 0xE0D3, 0x8DE8, 0xCEA5,
+	0x8DEF, 0xD6D8, 0x8DF3, 0xD4AF, 0x8E0A, 0xE9C9, 0x8E0F, 0xD3CE,
+	0x8E10, 0xF4C2, 0x8E1E, 0xCBE6, 0x8E2A, 0xF1A1, 0x8E30, 0xEBB2,
+	0x8E35, 0xF1A2, 0x8E42, 0xEBB3, 0x8E44, 0xF0B4, 0x8E47, 0xCBF4,
+	0x8E48, 0xD4B0, 0x8E49, 0xF3B2, 0x8E4A, 0xFBB7, 0x8E59, 0xF5EC,
+	0x8E5F, 0xEEE7, 0x8E60, 0xF4B2, 0x8E74, 0xF5ED, 0x8E76, 0xCFF3,
+	0x8E81, 0xF0E2, 0x8E87, 0xEECE, 0x8E8A, 0xF1CC, 0x8E8D, 0xE5B8,
+	0x8EAA, 0xD7F5, 0x8EAB, 0xE3F3, 0x8EAC, 0xCFE5, 0x8EC0, 0xCFC6,
+	0x8ECA, 0xF3B3, 0x8ECB, 0xE4D8, 0x8ECC, 0xCFF9, 0x8ECD, 0xCFDA,
+	0x8ED2, 0xFACD, 0x8EDF, 0xE6E3, 0x8EEB, 0xF2E2, 0x8EF8, 0xF5EE,
+	0x8EFB, 0xCABB, 0x8EFE, 0xE3DC, 0x8F03, 0xCEF2, 0x8F05, 0xD6D9,
+	0x8F09, 0xEEB0, 0x8F12, 0xF4E5, 0x8F13, 0xD8C2, 0x8F14, 0xDCD0,
+	0x8F15, 0xCCEE, 0x8F1B, 0xD5E0, 0x8F1C, 0xF6CA, 0x8F1D, 0xFDCA,
+	0x8F1E, 0xD8D6, 0x8F1F, 0xF4CF, 0x8F26, 0xD6A6, 0x8F27, 0xDCBE,
+	0x8F29, 0xDBD4, 0x8F2A, 0xD7C7, 0x8F2F, 0xF2FE, 0x8F33, 0xF1CD,
+	0x8F38, 0xE2C3, 0x8F39, 0xDCDE, 0x8F3B, 0xDCDF, 0x8F3E, 0xEFAD,
+	0x8F3F, 0xE6AB, 0x8F44, 0xF9DD, 0x8F45, 0xEABF, 0x8F49, 0xEFAE,
+	0x8F4D, 0xF4D0, 0x8F4E, 0xCEF3, 0x8F5D, 0xE6AC, 0x8F5F, 0xCEDE,
+	0x8F62, 0xD5F9, 0x8F9B, 0xE3F4, 0x8F9C, 0xCDD0, 0x8FA3, 0xD5B8,
+	0x8FA6, 0xF7FD, 0x8FA8, 0xDCA9, 0x8FAD, 0xDEF6, 0x8FAF, 0xDCAA,
+	0x8FB0, 0xF2E3, 0x8FB1, 0xE9B4, 0x8FB2, 0xD2DC, 0x8FC2, 0xE9E6,
+	0x8FC5, 0xE3F6, 0x8FCE, 0xE7CA, 0x8FD1, 0xD0CE, 0x8FD4, 0xDAF7,
+	0x8FE6, 0xCABC, 0x8FEA, 0xEEE8, 0x8FEB, 0xDADE, 0x8FED, 0xF2F7,
+	0x8FF0, 0xE2FB, 0x8FF2, 0xCCA6, 0x8FF7, 0xDABB, 0x8FF9, 0xEEE9,
+	0x8FFD, 0xF5DA, 0x9000, 0xF7DC, 0x9001, 0xE1EA, 0x9002, 0xCEC1,
+	0x9003, 0xD4B1, 0x9005, 0xFDB1, 0x9006, 0xE6BD, 0x9008, 0xFBAD,
+	0x900B, 0xF8E7, 0x900D, 0xE1CE, 0x900F, 0xF7E2, 0x9010, 0xF5EF,
+	0x9011, 0xCFC7, 0x9014, 0xD4B2, 0x9015, 0xCCEF, 0x9017, 0xD4E8,
+	0x9019, 0xEECF, 0x901A, 0xF7D7, 0x901D, 0xE0A6, 0x901E, 0xD6C1,
+	0x901F, 0xE1DC, 0x9020, 0xF0E3, 0x9021, 0xF1E4, 0x9022, 0xDCF1,
+	0x9023, 0xD6A7, 0x902E, 0xF4F5, 0x9031, 0xF1CE, 0x9032, 0xF2E4,
+	0x9035, 0xD0B0, 0x9038, 0xECEF, 0x903C, 0xF9BA, 0x903E, 0xEBB5,
+	0x9041, 0xD4ED, 0x9042, 0xE2C4, 0x9047, 0xE9E7, 0x904A, 0xEBB4,
+	0x904B, 0xEAA1, 0x904D, 0xF8BC, 0x904E, 0xCEA6, 0x9050, 0xF9C6,
+	0x9051, 0xFCDA, 0x9053, 0xD4B3, 0x9054, 0xD3B9, 0x9055, 0xEADE,
+	0x9059, 0xE9AB, 0x905C, 0xE1E1, 0x905D, 0xD3CF, 0x905E, 0xF4F6,
+	0x9060, 0xEAC0, 0x9061, 0xE1CF, 0x9063, 0xCCBA, 0x9069, 0xEEEA,
+	0x906D, 0xF0E4, 0x906E, 0xF3B4, 0x906F, 0xD4EE, 0x9072, 0xF2C0,
+	0x9075, 0xF1E5, 0x9077, 0xF4C3, 0x9078, 0xE0D4, 0x907A, 0xEBB6,
+	0x907C, 0xD7A1, 0x907D, 0xCBE8, 0x907F, 0xF9AD, 0x9080, 0xE9AD,
+	0x9081, 0xD8E4, 0x9082, 0xFAB3, 0x9083, 0xE2C5, 0x9084, 0xFCBD,
+	0x9087, 0xECC4, 0x9088, 0xD8B1, 0x908A, 0xDCAB, 0x908F, 0xD5A4,
+	0x9091, 0xEBE9, 0x9095, 0xE8BB, 0x9099, 0xD8D7, 0x90A2, 0xFBAE,
+	0x90A3, 0xD1E1, 0x90A6, 0xDBC0, 0x90A8, 0xF5BE, 0x90AA, 0xDEF7,
+	0x90AF, 0xCAFB, 0x90B0, 0xF7C6, 0x90B1, 0xCFC8, 0x90B5, 0xE1D0,
+	0x90B8, 0xEED0, 0x90C1, 0xE9F4, 0x90CA, 0xCEF4, 0x90DE, 0xD5CD,
+	0x90E1, 0xCFDB, 0x90E8, 0xDDBB, 0x90ED, 0xCEAC, 0x90F5, 0xE9E8,
+	0x90FD, 0xD4B4, 0x9102, 0xE4C7, 0x9112, 0xF5DB, 0x9115, 0xFAC1,
+	0x9119, 0xDEA9, 0x9127, 0xD4F8, 0x912D, 0xEFF7, 0x9132, 0xD3B3,
+	0x9149, 0xEBB7, 0x914A, 0xEFF8, 0x914B, 0xF5DC, 0x914C, 0xEDCC,
+	0x914D, 0xDBD5, 0x914E, 0xF1CF, 0x9152, 0xF1D0, 0x9162, 0xF5B2,
+	0x9169, 0xD9AE, 0x916A, 0xD5AC, 0x916C, 0xE2C6, 0x9175, 0xFDA3,
+	0x9177, 0xFBE5, 0x9178, 0xDFAB, 0x9187, 0xE2F5, 0x9189, 0xF6AD,
+	0x918B, 0xF5B3, 0x918D, 0xF0B5, 0x9192, 0xE1A5, 0x919C, 0xF5DD,
+	0x91AB, 0xECA2, 0x91AC, 0xEDFD, 0x91AE, 0xF5B4, 0x91AF, 0xFBB8,
+	0x91B1, 0xDBA3, 0x91B4, 0xD6CA, 0x91B5, 0xCBD9, 0x91C0, 0xE5D4,
+	0x91C7, 0xF3FA, 0x91C9, 0xEBB8, 0x91CB, 0xE0B7, 0x91CC, 0xD7EC,
+	0x91CD, 0xF1EC, 0x91CE, 0xE5AF, 0x91CF, 0xD5E1, 0x91D0, 0xD7ED,
+	0x91D1, 0xD1D1, 0x91D7, 0xE1F2, 0x91D8, 0xEFF9, 0x91DC, 0xDDBC,
+	0x91DD, 0xF6DC, 0x91E3, 0xF0E5, 0x91E7, 0xF4C4, 0x91EA, 0xE9E9,
+	0x91F5, 0xF3FB, 0x920D, 0xD4EF, 0x9210, 0xCCA2, 0x9211, 0xF7FE,
+	0x9212, 0xDFBC, 0x9217, 0xEBCD, 0x921E, 0xD0B7, 0x9234, 0xD6C2,
+	0x923A, 0xE8AD, 0x923F, 0xEFAF, 0x9240, 0xCBA5, 0x9245, 0xCBE9,
+	0x9249, 0xFAE8, 0x9257, 0xCCC6, 0x925B, 0xE6E7, 0x925E, 0xEAC7,
+	0x9262, 0xDBA4, 0x9264, 0xCFC9, 0x9265, 0xE2FC, 0x9266, 0xEFFA,
+	0x9280, 0xEBDE, 0x9283, 0xF5C8, 0x9285, 0xD4DE, 0x9291, 0xE0D5,
+	0x9293, 0xEFB0, 0x9296, 0xE2C7, 0x9298, 0xD9AF, 0x929C, 0xF9E7,
+	0x92B3, 0xE7E5, 0x92B6, 0xCFCA, 0x92B7, 0xE1D1, 0x92B9, 0xE2C8,
+	0x92CC, 0xEFFB, 0x92CF, 0xFAF9, 0x92D2, 0xDCF2, 0x92E4, 0xE0A7,
+	0x92EA, 0xF8E8, 0x92F8, 0xCBEA, 0x92FC, 0xCBBC, 0x9304, 0xD6E2,
+	0x9310, 0xF5DE, 0x9318, 0xF5DF, 0x931A, 0xEEB6, 0x931E, 0xE2F6,
+	0x931F, 0xD3CA, 0x9320, 0xEFFC, 0x9321, 0xD1C4, 0x9322, 0xEFB1,
+	0x9324, 0xD1C5, 0x9326, 0xD0DE, 0x9328, 0xD9E1, 0x932B, 0xE0B8,
+	0x932E, 0xCDD1, 0x932F, 0xF3B9, 0x9348, 0xE7CC, 0x934A, 0xD6A8,
+	0x934B, 0xCEA7, 0x934D, 0xD4B5, 0x9354, 0xE4C8, 0x935B, 0xD3B4,
+	0x936E, 0xEBB9, 0x9375, 0xCBF5, 0x937C, 0xF6DD, 0x937E, 0xF1A3,
+	0x938C, 0xCCC7, 0x9394, 0xE9CA, 0x9396, 0xE1F0, 0x939A, 0xF5E0,
+	0x93A3, 0xFBAF, 0x93A7, 0xCBD1, 0x93AC, 0xFBE0, 0x93AD, 0xF2E5,
+	0x93B0, 0xECF0, 0x93C3, 0xF0EC, 0x93D1, 0xEEEB, 0x93DE, 0xE9CB,
+	0x93E1, 0xCCF0, 0x93E4, 0xD7AF, 0x93F6, 0xF3A1, 0x9404, 0xFCF5,
+	0x9418, 0xF1A4, 0x9425, 0xE0D6, 0x942B, 0xEFB2, 0x9435, 0xF4D1,
+	0x9438, 0xF7A1, 0x9444, 0xF1D1, 0x9451, 0xCAFC, 0x9452, 0xCAFD,
+	0x945B, 0xCECE, 0x947D, 0xF3C8, 0x947F, 0xF3BA, 0x9577, 0xEDFE,
+	0x9580, 0xDAA6, 0x9583, 0xE0EC, 0x9589, 0xF8CD, 0x958B, 0xCBD2,
+	0x958F, 0xEBCE, 0x9591, 0xF9D8, 0x9592, 0xF9D9, 0x9593, 0xCAE0,
+	0x9594, 0xDACA, 0x9598, 0xCBA6, 0x95A3, 0xCAC8, 0x95A4, 0xF9EE,
+	0x95A5, 0xDBEC, 0x95A8, 0xD0B1, 0x95AD, 0xD5EF, 0x95B1, 0xE6F3,
+	0x95BB, 0xE7A2, 0x95BC, 0xE4D9, 0x95C7, 0xE4E1, 0x95CA, 0xFCC4,
+	0x95D4, 0xF9EF, 0x95D5, 0xCFF4, 0x95D6, 0xF7E6, 0x95DC, 0xCEBC,
+	0x95E1, 0xF4C5, 0x95E2, 0xDCA3, 0x961C, 0xDDBD, 0x9621, 0xF4C6,
+	0x962A, 0xF8A1, 0x962E, 0xE8D6, 0x9632, 0xDBC1, 0x963B, 0xF0E6,
+	0x963F, 0xE4B9, 0x9640, 0xF6ED, 0x9642, 0xF9AE, 0x9644, 0xDDBE,
+	0x964B, 0xD7B0, 0x964C, 0xD8E8, 0x964D, 0xCBBD, 0x9650, 0xF9DA,
+	0x965B, 0xF8CE, 0x965C, 0xF9F0, 0x965D, 0xE0ED, 0x965E, 0xE3B3,
+	0x965F, 0xF4B3, 0x9662, 0xEAC2, 0x9663, 0xF2E6, 0x9664, 0xF0B6,
+	0x966A, 0xDBD6, 0x9670, 0xEBE4, 0x9673, 0xF2E7, 0x9675, 0xD7D5,
+	0x9676, 0xD4B6, 0x9677, 0xF9E8, 0x9678, 0xD7C1, 0x967D, 0xE5D5,
+	0x9685, 0xE9EA, 0x9686, 0xD7CC, 0x968A, 0xD3E9, 0x968B, 0xE2C9,
+	0x968D, 0xFCDB, 0x968E, 0xCDAD, 0x9694, 0xCCB0, 0x9695, 0xEAA2,
+	0x9698, 0xE4F6, 0x9699, 0xD0C0, 0x969B, 0xF0B7, 0x969C, 0xEEA1,
+	0x96A3, 0xD7F6, 0x96A7, 0xE2CA, 0x96A8, 0xE2CB, 0x96AA, 0xFACF,
+	0x96B1, 0xEBDF, 0x96B7, 0xD6CB, 0x96BB, 0xF4B4, 0x96C0, 0xEDCD,
+	0x96C1, 0xE4D2, 0x96C4, 0xEAA9, 0x96C5, 0xE4BA, 0x96C6, 0xF3A2,
+	0x96C7, 0xCDD2, 0x96C9, 0xF6CB, 0x96CB, 0xF1E6, 0x96CC, 0xEDC1,
+	0x96CD, 0xE8BC, 0x96CE, 0xEED1, 0x96D5, 0xF0E7, 0x96D6, 0xE2CC,
+	0x96D9, 0xE4AA, 0x96DB, 0xF5E1, 0x96DC, 0xEDDA, 0x96E2, 0xD7EE,
+	0x96E3, 0xD1F1, 0x96E8, 0xE9EB, 0x96E9, 0xE9EC, 0x96EA, 0xE0E4,
+	0x96EF, 0xDAA7, 0x96F0, 0xDDD4, 0x96F2, 0xEAA3, 0x96F6, 0xD6C3,
+	0x96F7, 0xD6F4, 0x96F9, 0xDADF, 0x96FB, 0xEFB3, 0x9700, 0xE2CD,
+	0x9706, 0xEFFD, 0x9707, 0xF2E8, 0x9711, 0xEFC5, 0x9713, 0xE7E7,
+	0x9716, 0xD7FD, 0x9719, 0xE7CE, 0x971C, 0xDFDC, 0x971E, 0xF9C7,
+	0x9727, 0xD9F6, 0x9730, 0xDFAC, 0x9732, 0xD6DA, 0x9739, 0xDCA4,
+	0x973D, 0xF0B8, 0x9742, 0xD5FA, 0x9744, 0xE4F7, 0x9748, 0xD6C4,
+	0x9751, 0xF4EC, 0x9756, 0xEFFE, 0x975C, 0xF0A1, 0x975E, 0xDEAA,
+	0x9761, 0xDABC, 0x9762, 0xD8FC, 0x9769, 0xFAD4, 0x976D, 0xECE5,
+	0x9774, 0xFCA8, 0x9777, 0xECE6, 0x977A, 0xD8CB, 0x978B, 0xFBB9,
+	0x978D, 0xE4D3, 0x978F, 0xCDF9, 0x97A0, 0xCFD3, 0x97A8, 0xCAEA,
+	0x97AB, 0xCFD4, 0x97AD, 0xF8BD, 0x97C6, 0xF4C7, 0x97CB, 0xEADF,
+	0x97D3, 0xF9DB, 0x97DC, 0xD4B7, 0x97F3, 0xEBE5, 0x97F6, 0xE1D2,
+	0x97FB, 0xEAA4, 0x97FF, 0xFAC2, 0x9800, 0xFBE1, 0x9801, 0xFAED,
+	0x9802, 0xF0A2, 0x9803, 0xCCF1, 0x9805, 0xFAA3, 0x9806, 0xE2F7,
+	0x9808, 0xE2CE, 0x980A, 0xE9F5, 0x980C, 0xE1EB, 0x9810, 0xE7E8,
+	0x9811, 0xE8D7, 0x9812, 0xDAF8, 0x9813, 0xD4CB, 0x9817, 0xF7F6,
+	0x9818, 0xD6C5, 0x982D, 0xD4E9, 0x9830, 0xFAFA, 0x9838, 0xCCF2,
+	0x9839, 0xF7DD, 0x983B, 0xDEBA, 0x9846, 0xCEA8, 0x984C, 0xF0B9,
+	0x984D, 0xE4FE, 0x984E, 0xE4C9, 0x9854, 0xE4D4, 0x9858, 0xEAC3,
+	0x985A, 0xEFB4, 0x985E, 0xD7BE, 0x9865, 0xFBE2, 0x9867, 0xCDD3,
+	0x986B, 0xEFB5, 0x986F, 0xFAE9, 0x98A8, 0xF9A6, 0x98AF, 0xDFBD,
+	0x98B1, 0xF7C7, 0x98C4, 0xF8FD, 0x98C7, 0xF8FC, 0x98DB, 0xDEAB,
+	0x98DC, 0xDBE8, 0x98DF, 0xE3DD, 0x98E1, 0xE1E2, 0x98E2, 0xD1C6,
+	0x98ED, 0xF6D0, 0x98EE, 0xEBE6, 0x98EF, 0xDAF9, 0x98F4, 0xECC7,
+	0x98FC, 0xDEF8, 0x98FD, 0xF8E9, 0x98FE, 0xE3DE, 0x9903, 0xCEF5,
+	0x9909, 0xFAC3, 0x990A, 0xE5D7, 0x990C, 0xECC8, 0x9910, 0xF3C9,
+	0x9913, 0xE4BB, 0x9918, 0xE6AE, 0x991E, 0xEFB6, 0x9920, 0xDCBF,
+	0x9928, 0xCEBD, 0x9945, 0xD8C3, 0x9949, 0xD0CF, 0x994B, 0xCFFA,
+	0x994C, 0xF3CA, 0x994D, 0xE0D7, 0x9951, 0xD1C7, 0x9952, 0xE9AE,
+	0x9954, 0xE8BD, 0x9957, 0xFAC4, 0x9996, 0xE2CF, 0x9999, 0xFAC5,
+	0x999D, 0xF9B8, 0x99A5, 0xDCE0, 0x99A8, 0xFBB0, 0x99AC, 0xD8A9,
+	0x99AD, 0xE5DF, 0x99AE, 0xF9A7, 0x99B1, 0xF6EE, 0x99B3, 0xF6CC,
+	0x99B4, 0xE2F8, 0x99B9, 0xECF1, 0x99C1, 0xDAE0, 0x99D0, 0xF1D2,
+	0x99D1, 0xD2CC, 0x99D2, 0xCFCB, 0x99D5, 0xCABD, 0x99D9, 0xDDBF,
+	0x99DD, 0xF6EF, 0x99DF, 0xDEF9, 0x99ED, 0xFAB4, 0x99F1, 0xD5AD,
+	0x99FF, 0xF1E7, 0x9A01, 0xDEBE, 0x9A08, 0xDCC0, 0x9A0E, 0xD1C8,
+	0x9A0F, 0xD1C9, 0x9A19, 0xF8BE, 0x9A2B, 0xCBF6, 0x9A30, 0xD4F9,
+	0x9A36, 0xF5E2, 0x9A37, 0xE1D3, 0x9A40, 0xD8E9, 0x9A43, 0xF8FE,
+	0x9A45, 0xCFCC, 0x9A4D, 0xFDA4, 0x9A55, 0xCEF6, 0x9A57, 0xFAD0,
+	0x9A5A, 0xCCF3, 0x9A5B, 0xE6BE, 0x9A5F, 0xF6AE, 0x9A62, 0xD5F0,
+	0x9A65, 0xD1CA, 0x9A69, 0xFCBE, 0x9A6A, 0xD5F1, 0x9AA8, 0xCDE9,
+	0x9AB8, 0xFAB5, 0x9AD3, 0xE2D0, 0x9AD4, 0xF4F7, 0x9AD8, 0xCDD4,
+	0x9AE5, 0xE7A3, 0x9AEE, 0xDBA5, 0x9B1A, 0xE2D1, 0x9B27, 0xD7A2,
+	0x9B2A, 0xF7E3, 0x9B31, 0xEAA6, 0x9B3C, 0xD0A1, 0x9B41, 0xCEDA,
+	0x9B42, 0xFBEB, 0x9B43, 0xDBA6, 0x9B44, 0xDBDE, 0x9B45, 0xD8E5,
+	0x9B4F, 0xEAE0, 0x9B54, 0xD8AA, 0x9B5A, 0xE5E0, 0x9B6F, 0xD6DB,
+	0x9B8E, 0xEFC6, 0x9B91, 0xF8EA, 0x9B9F, 0xE4D5, 0x9BAB, 0xCEF7,
+	0x9BAE, 0xE0D8, 0x9BC9, 0xD7EF, 0x9BD6, 0xF4ED, 0x9BE4, 0xCDE6,
+	0x9BE8, 0xCCF4, 0x9C0D, 0xF5E3, 0x9C10, 0xE4CA, 0x9C12, 0xDCE1,
+	0x9C15, 0xF9C8, 0x9C25, 0xFCBF, 0x9C32, 0xE8A7, 0x9C3B, 0xD8C4,
+	0x9C47, 0xCBBE, 0x9C49, 0xDCAE, 0x9C57, 0xD7F7, 0x9CE5, 0xF0E8,
+	0x9CE7, 0xDDC0, 0x9CE9, 0xCFCD, 0x9CF3, 0xDCF3, 0x9CF4, 0xD9B0,
+	0x9CF6, 0xE6E9, 0x9D09, 0xE4BC, 0x9D1B, 0xEAC4, 0x9D26, 0xE4EC,
+	0x9D28, 0xE4E5, 0x9D3B, 0xFBF8, 0x9D51, 0xCCBB, 0x9D5D, 0xE4BD,
+	0x9D60, 0xCDDC, 0x9D61, 0xD9F7, 0x9D6C, 0xDDDF, 0x9D72, 0xEDCE,
+	0x9DA9, 0xD9D0, 0x9DAF, 0xE5A3, 0x9DB4, 0xF9CD, 0x9DC4, 0xCDAE,
+	0x9DD7, 0xCFCE, 0x9DF2, 0xF6AF, 0x9DF8, 0xFDD3, 0x9DF9, 0xEBED,
+	0x9DFA, 0xD6DC, 0x9E1A, 0xE5A4, 0x9E1E, 0xD5B6, 0x9E75, 0xD6DD,
+	0x9E79, 0xF9E9, 0x9E7D, 0xE7A4, 0x9E7F, 0xD6E3, 0x9E92, 0xD1CB,
+	0x9E93, 0xD6E4, 0x9E97, 0xD5F2, 0x9E9D, 0xDEFA, 0x9E9F, 0xD7F8,
+	0x9EA5, 0xD8EA, 0x9EB4, 0xCFD5, 0x9EB5, 0xD8FD, 0x9EBB, 0xD8AB,
+	0x9EBE, 0xFDCB, 0x9EC3, 0xFCDC, 0x9ECD, 0xE0A8, 0x9ECE, 0xD5F3,
+	0x9ED1, 0xFDD9, 0x9ED4, 0xCCA3, 0x9ED8, 0xD9F9, 0x9EDB, 0xD3EA,
+	0x9EDC, 0xF5F5, 0x9EDE, 0xEFC7, 0x9EE8, 0xD3DA, 0x9EF4, 0xDABD,
+	0x9F07, 0xE8A8, 0x9F08, 0xDCAF, 0x9F0E, 0xF0A3, 0x9F13, 0xCDD5,
+	0x9F20, 0xE0A9, 0x9F3B, 0xDEAC, 0x9F4A, 0xF0BA, 0x9F4B, 0xEEB1,
+	0x9F4E, 0xEEB2, 0x9F52, 0xF6CD, 0x9F5F, 0xEED2, 0x9F61, 0xD6C6,
+	0x9F67, 0xE0E5, 0x9F6A, 0xF3BB, 0x9F6C, 0xE5E1, 0x9F77, 0xE4CB,
+	0x9F8D, 0xD7A3, 0x9F90, 0xDBC2, 0x9F95, 0xCAFE, 0x9F9C, 0xCFCF,
+	0xAC00, 0xB0A1, 0xAC01, 0xB0A2, 0xAC02, 0x8141, 0xAC03, 0x8142,
+	0xAC04, 0xB0A3, 0xAC05, 0x8143, 0xAC06, 0x8144, 0xAC07, 0xB0A4,
+	0xAC08, 0xB0A5, 0xAC09, 0xB0A6, 0xAC0A, 0xB0A7, 0xAC0B, 0x8145,
+	0xAC0C, 0x8146, 0xAC0D, 0x8147, 0xAC0E, 0x8148, 0xAC0F, 0x8149,
+	0xAC10, 0xB0A8, 0xAC11, 0xB0A9, 0xAC12, 0xB0AA, 0xAC13, 0xB0AB,
+	0xAC14, 0xB0AC, 0xAC15, 0xB0AD, 0xAC16, 0xB0AE, 0xAC17, 0xB0AF,
+	0xAC18, 0x814A, 0xAC19, 0xB0B0, 0xAC1A, 0xB0B1, 0xAC1B, 0xB0B2,
+	0xAC1C, 0xB0B3, 0xAC1D, 0xB0B4, 0xAC1E, 0x814B, 0xAC1F, 0x814C,
+	0xAC20, 0xB0B5, 0xAC21, 0x814D, 0xAC22, 0x814E, 0xAC23, 0x814F,
+	0xAC24, 0xB0B6, 0xAC25, 0x8150, 0xAC26, 0x8151, 0xAC27, 0x8152,
+	0xAC28, 0x8153, 0xAC29, 0x8154, 0xAC2A, 0x8155, 0xAC2B, 0x8156,
+	0xAC2C, 0xB0B7, 0xAC2D, 0xB0B8, 0xAC2E, 0x8157, 0xAC2F, 0xB0B9,
+	0xAC30, 0xB0BA, 0xAC31, 0xB0BB, 0xAC32, 0x8158, 0xAC33, 0x8159,
+	0xAC34, 0x815A, 0xAC35, 0x8161, 0xAC36, 0x8162, 0xAC37, 0x8163,
+	0xAC38, 0xB0BC, 0xAC39, 0xB0BD, 0xAC3A, 0x8164, 0xAC3B, 0x8165,
+	0xAC3C, 0xB0BE, 0xAC3D, 0x8166, 0xAC3E, 0x8167, 0xAC3F, 0x8168,
+	0xAC40, 0xB0BF, 0xAC41, 0x8169, 0xAC42, 0x816A, 0xAC43, 0x816B,
+	0xAC44, 0x816C, 0xAC45, 0x816D, 0xAC46, 0x816E, 0xAC47, 0x816F,
+	0xAC48, 0x8170, 0xAC49, 0x8171, 0xAC4A, 0x8172, 0xAC4B, 0xB0C0,
+	0xAC4C, 0x8173, 0xAC4D, 0xB0C1, 0xAC4E, 0x8174, 0xAC4F, 0x8175,
+	0xAC50, 0x8176, 0xAC51, 0x8177, 0xAC52, 0x8178, 0xAC53, 0x8179,
+	0xAC54, 0xB0C2, 0xAC55, 0x817A, 0xAC56, 0x8181, 0xAC57, 0x8182,
+	0xAC58, 0xB0C3, 0xAC59, 0x8183, 0xAC5A, 0x8184, 0xAC5B, 0x8185,
+	0xAC5C, 0xB0C4, 0xAC5D, 0x8186, 0xAC5E, 0x8187, 0xAC5F, 0x8188,
+	0xAC60, 0x8189, 0xAC61, 0x818A, 0xAC62, 0x818B, 0xAC63, 0x818C,
+	0xAC64, 0x818D, 0xAC65, 0x818E, 0xAC66, 0x818F, 0xAC67, 0x8190,
+	0xAC68, 0x8191, 0xAC69, 0x8192, 0xAC6A, 0x8193, 0xAC6B, 0x8194,
+	0xAC6C, 0x8195, 0xAC6D, 0x8196, 0xAC6E, 0x8197, 0xAC6F, 0x8198,
+	0xAC70, 0xB0C5, 0xAC71, 0xB0C6, 0xAC72, 0x8199, 0xAC73, 0x819A,
+	0xAC74, 0xB0C7, 0xAC75, 0x819B, 0xAC76, 0x819C, 0xAC77, 0xB0C8,
+	0xAC78, 0xB0C9, 0xAC79, 0x819D, 0xAC7A, 0xB0CA, 0xAC7B, 0x819E,
+	0xAC7C, 0x819F, 0xAC7D, 0x81A0, 0xAC7E, 0x81A1, 0xAC7F, 0x81A2,
+	0xAC80, 0xB0CB, 0xAC81, 0xB0CC, 0xAC82, 0x81A3, 0xAC83, 0xB0CD,
+	0xAC84, 0xB0CE, 0xAC85, 0xB0CF, 0xAC86, 0xB0D0, 0xAC87, 0x81A4,
+	0xAC88, 0x81A5, 0xAC89, 0xB0D1, 0xAC8A, 0xB0D2, 0xAC8B, 0xB0D3,
+	0xAC8C, 0xB0D4, 0xAC8D, 0x81A6, 0xAC8E, 0x81A7, 0xAC8F, 0x81A8,
+	0xAC90, 0xB0D5, 0xAC91, 0x81A9, 0xAC92, 0x81AA, 0xAC93, 0x81AB,
+	0xAC94, 0xB0D6, 0xAC95, 0x81AC, 0xAC96, 0x81AD, 0xAC97, 0x81AE,
+	0xAC98, 0x81AF, 0xAC99, 0x81B0, 0xAC9A, 0x81B1, 0xAC9B, 0x81B2,
+	0xAC9C, 0xB0D7, 0xAC9D, 0xB0D8, 0xAC9E, 0x81B3, 0xAC9F, 0xB0D9,
+	0xACA0, 0xB0DA, 0xACA1, 0xB0DB, 0xACA2, 0x81B4, 0xACA3, 0x81B5,
+	0xACA4, 0x81B6, 0xACA5, 0x81B7, 0xACA6, 0x81B8, 0xACA7, 0x81B9,
+	0xACA8, 0xB0DC, 0xACA9, 0xB0DD, 0xACAA, 0xB0DE, 0xACAB, 0x81BA,
+	0xACAC, 0xB0DF, 0xACAD, 0x81BB, 0xACAE, 0x81BC, 0xACAF, 0xB0E0,
+	0xACB0, 0xB0E1, 0xACB1, 0x81BD, 0xACB2, 0x81BE, 0xACB3, 0x81BF,
+	0xACB4, 0x81C0, 0xACB5, 0x81C1, 0xACB6, 0x81C2, 0xACB7, 0x81C3,
+	0xACB8, 0xB0E2, 0xACB9, 0xB0E3, 0xACBA, 0x81C4, 0xACBB, 0xB0E4,
+	0xACBC, 0xB0E5, 0xACBD, 0xB0E6, 0xACBE, 0x81C5, 0xACBF, 0x81C6,
+	0xACC0, 0x81C7, 0xACC1, 0xB0E7, 0xACC2, 0x81C8, 0xACC3, 0x81C9,
+	0xACC4, 0xB0E8, 0xACC5, 0x81CA, 0xACC6, 0x81CB, 0xACC7, 0x81CC,
+	0xACC8, 0xB0E9, 0xACC9, 0x81CD, 0xACCA, 0x81CE, 0xACCB, 0x81CF,
+	0xACCC, 0xB0EA, 0xACCD, 0x81D0, 0xACCE, 0x81D1, 0xACCF, 0x81D2,
+	0xACD0, 0x81D3, 0xACD1, 0x81D4, 0xACD2, 0x81D5, 0xACD3, 0x81D6,
+	0xACD4, 0x81D7, 0xACD5, 0xB0EB, 0xACD6, 0x81D8, 0xACD7, 0xB0EC,
+	0xACD8, 0x81D9, 0xACD9, 0x81DA, 0xACDA, 0x81DB, 0xACDB, 0x81DC,
+	0xACDC, 0x81DD, 0xACDD, 0x81DE, 0xACDE, 0x81DF, 0xACDF, 0x81E0,
+	0xACE0, 0xB0ED, 0xACE1, 0xB0EE, 0xACE2, 0x81E1, 0xACE3, 0x81E2,
+	0xACE4, 0xB0EF, 0xACE5, 0x81E3, 0xACE6, 0x81E4, 0xACE7, 0xB0F0,
+	0xACE8, 0xB0F1, 0xACE9, 0x81E5, 0xACEA, 0xB0F2, 0xACEB, 0x81E6,
+	0xACEC, 0xB0F3, 0xACED, 0x81E7, 0xACEE, 0x81E8, 0xACEF, 0xB0F4,
+	0xACF0, 0xB0F5, 0xACF1, 0xB0F6, 0xACF2, 0x81E9, 0xACF3, 0xB0F7,
+	0xACF4, 0x81EA, 0xACF5, 0xB0F8, 0xACF6, 0xB0F9, 0xACF7, 0x81EB,
+	0xACF8, 0x81EC, 0xACF9, 0x81ED, 0xACFA, 0x81EE, 0xACFB, 0x81EF,
+	0xACFC, 0xB0FA, 0xACFD, 0xB0FB, 0xACFE, 0x81F0, 0xACFF, 0x81F1,
+	0xAD00, 0xB0FC, 0xAD01, 0x81F2, 0xAD02, 0x81F3, 0xAD03, 0x81F4,
+	0xAD04, 0xB0FD, 0xAD05, 0x81F5, 0xAD06, 0xB0FE, 0xAD07, 0x81F6,
+	0xAD08, 0x81F7, 0xAD09, 0x81F8, 0xAD0A, 0x81F9, 0xAD0B, 0x81FA,
+	0xAD0C, 0xB1A1, 0xAD0D, 0xB1A2, 0xAD0E, 0x81FB, 0xAD0F, 0xB1A3,
+	0xAD10, 0x81FC, 0xAD11, 0xB1A4, 0xAD12, 0x81FD, 0xAD13, 0x81FE,
+	0xAD14, 0x8241, 0xAD15, 0x8242, 0xAD16, 0x8243, 0xAD17, 0x8244,
+	0xAD18, 0xB1A5, 0xAD19, 0x8245, 0xAD1A, 0x8246, 0xAD1B, 0x8247,
+	0xAD1C, 0xB1A6, 0xAD1D, 0x8248, 0xAD1E, 0x8249, 0xAD1F, 0x824A,
+	0xAD20, 0xB1A7, 0xAD21, 0x824B, 0xAD22, 0x824C, 0xAD23, 0x824D,
+	0xAD24, 0x824E, 0xAD25, 0x824F, 0xAD26, 0x8250, 0xAD27, 0x8251,
+	0xAD28, 0x8252, 0xAD29, 0xB1A8, 0xAD2A, 0x8253, 0xAD2B, 0x8254,
+	0xAD2C, 0xB1A9, 0xAD2D, 0xB1AA, 0xAD2E, 0x8255, 0xAD2F, 0x8256,
+	0xAD30, 0x8257, 0xAD31, 0x8258, 0xAD32, 0x8259, 0xAD33, 0x825A,
+	0xAD34, 0xB1AB, 0xAD35, 0xB1AC, 0xAD36, 0x8261, 0xAD37, 0x8262,
+	0xAD38, 0xB1AD, 0xAD39, 0x8263, 0xAD3A, 0x8264, 0xAD3B, 0x8265,
+	0xAD3C, 0xB1AE, 0xAD3D, 0x8266, 0xAD3E, 0x8267, 0xAD3F, 0x8268,
+	0xAD40, 0x8269, 0xAD41, 0x826A, 0xAD42, 0x826B, 0xAD43, 0x826C,
+	0xAD44, 0xB1AF, 0xAD45, 0xB1B0, 0xAD46, 0x826D, 0xAD47, 0xB1B1,
+	0xAD48, 0x826E, 0xAD49, 0xB1B2, 0xAD4A, 0x826F, 0xAD4B, 0x8270,
+	0xAD4C, 0x8271, 0xAD4D, 0x8272, 0xAD4E, 0x8273, 0xAD4F, 0x8274,
+	0xAD50, 0xB1B3, 0xAD51, 0x8275, 0xAD52, 0x8276, 0xAD53, 0x8277,
+	0xAD54, 0xB1B4, 0xAD55, 0x8278, 0xAD56, 0x8279, 0xAD57, 0x827A,
+	0xAD58, 0xB1B5, 0xAD59, 0x8281, 0xAD5A, 0x8282, 0xAD5B, 0x8283,
+	0xAD5C, 0x8284, 0xAD5D, 0x8285, 0xAD5E, 0x8286, 0xAD5F, 0x8287,
+	0xAD60, 0x8288, 0xAD61, 0xB1B6, 0xAD62, 0x8289, 0xAD63, 0xB1B7,
+	0xAD64, 0x828A, 0xAD65, 0x828B, 0xAD66, 0x828C, 0xAD67, 0x828D,
+	0xAD68, 0x828E, 0xAD69, 0x828F, 0xAD6A, 0x8290, 0xAD6B, 0x8291,
+	0xAD6C, 0xB1B8, 0xAD6D, 0xB1B9, 0xAD6E, 0x8292, 0xAD6F, 0x8293,
+	0xAD70, 0xB1BA, 0xAD71, 0x8294, 0xAD72, 0x8295, 0xAD73, 0xB1BB,
+	0xAD74, 0xB1BC, 0xAD75, 0xB1BD, 0xAD76, 0xB1BE, 0xAD77, 0x8296,
+	0xAD78, 0x8297, 0xAD79, 0x8298, 0xAD7A, 0x8299, 0xAD7B, 0xB1BF,
+	0xAD7C, 0xB1C0, 0xAD7D, 0xB1C1, 0xAD7E, 0x829A, 0xAD7F, 0xB1C2,
+	0xAD80, 0x829B, 0xAD81, 0xB1C3, 0xAD82, 0xB1C4, 0xAD83, 0x829C,
+	0xAD84, 0x829D, 0xAD85, 0x829E, 0xAD86, 0x829F, 0xAD87, 0x82A0,
+	0xAD88, 0xB1C5, 0xAD89, 0xB1C6, 0xAD8A, 0x82A1, 0xAD8B, 0x82A2,
+	0xAD8C, 0xB1C7, 0xAD8D, 0x82A3, 0xAD8E, 0x82A4, 0xAD8F, 0x82A5,
+	0xAD90, 0xB1C8, 0xAD91, 0x82A6, 0xAD92, 0x82A7, 0xAD93, 0x82A8,
+	0xAD94, 0x82A9, 0xAD95, 0x82AA, 0xAD96, 0x82AB, 0xAD97, 0x82AC,
+	0xAD98, 0x82AD, 0xAD99, 0x82AE, 0xAD9A, 0x82AF, 0xAD9B, 0x82B0,
+	0xAD9C, 0xB1C9, 0xAD9D, 0xB1CA, 0xAD9E, 0x82B1, 0xAD9F, 0x82B2,
+	0xADA0, 0x82B3, 0xADA1, 0x82B4, 0xADA2, 0x82B5, 0xADA3, 0x82B6,
+	0xADA4, 0xB1CB, 0xADA5, 0x82B7, 0xADA6, 0x82B8, 0xADA7, 0x82B9,
+	0xADA8, 0x82BA, 0xADA9, 0x82BB, 0xADAA, 0x82BC, 0xADAB, 0x82BD,
+	0xADAC, 0x82BE, 0xADAD, 0x82BF, 0xADAE, 0x82C0, 0xADAF, 0x82C1,
+	0xADB0, 0x82C2, 0xADB1, 0x82C3, 0xADB2, 0x82C4, 0xADB3, 0x82C5,
+	0xADB4, 0x82C6, 0xADB5, 0x82C7, 0xADB6, 0x82C8, 0xADB7, 0xB1CC,
+	0xADB8, 0x82C9, 0xADB9, 0x82CA, 0xADBA, 0x82CB, 0xADBB, 0x82CC,
+	0xADBC, 0x82CD, 0xADBD, 0x82CE, 0xADBE, 0x82CF, 0xADBF, 0x82D0,
+	0xADC0, 0xB1CD, 0xADC1, 0xB1CE, 0xADC2, 0x82D1, 0xADC3, 0x82D2,
+	0xADC4, 0xB1CF, 0xADC5, 0x82D3, 0xADC6, 0x82D4, 0xADC7, 0x82D5,
+	0xADC8, 0xB1D0, 0xADC9, 0x82D6, 0xADCA, 0x82D7, 0xADCB, 0x82D8,
+	0xADCC, 0x82D9, 0xADCD, 0x82DA, 0xADCE, 0x82DB, 0xADCF, 0x82DC,
+	0xADD0, 0xB1D1, 0xADD1, 0xB1D2, 0xADD2, 0x82DD, 0xADD3, 0xB1D3,
+	0xADD4, 0x82DE, 0xADD5, 0x82DF, 0xADD6, 0x82E0, 0xADD7, 0x82E1,
+	0xADD8, 0x82E2, 0xADD9, 0x82E3, 0xADDA, 0x82E4, 0xADDB, 0x82E5,
+	0xADDC, 0xB1D4, 0xADDD, 0x82E6, 0xADDE, 0x82E7, 0xADDF, 0x82E8,
+	0xADE0, 0xB1D5, 0xADE1, 0x82E9, 0xADE2, 0x82EA, 0xADE3, 0x82EB,
+	0xADE4, 0xB1D6, 0xADE5, 0x82EC, 0xADE6, 0x82ED, 0xADE7, 0x82EE,
+	0xADE8, 0x82EF, 0xADE9, 0x82F0, 0xADEA, 0x82F1, 0xADEB, 0x82F2,
+	0xADEC, 0x82F3, 0xADED, 0x82F4, 0xADEE, 0x82F5, 0xADEF, 0x82F6,
+	0xADF0, 0x82F7, 0xADF1, 0x82F8, 0xADF2, 0x82F9, 0xADF3, 0x82FA,
+	0xADF4, 0x82FB, 0xADF5, 0x82FC, 0xADF6, 0x82FD, 0xADF7, 0x82FE,
+	0xADF8, 0xB1D7, 0xADF9, 0xB1D8, 0xADFA, 0x8341, 0xADFB, 0x8342,
+	0xADFC, 0xB1D9, 0xADFD, 0x8343, 0xADFE, 0x8344, 0xADFF, 0xB1DA,
+	0xAE00, 0xB1DB, 0xAE01, 0xB1DC, 0xAE02, 0x8345, 0xAE03, 0x8346,
+	0xAE04, 0x8347, 0xAE05, 0x8348, 0xAE06, 0x8349, 0xAE07, 0x834A,
+	0xAE08, 0xB1DD, 0xAE09, 0xB1DE, 0xAE0A, 0x834B, 0xAE0B, 0xB1DF,
+	0xAE0C, 0x834C, 0xAE0D, 0xB1E0, 0xAE0E, 0x834D, 0xAE0F, 0x834E,
+	0xAE10, 0x834F, 0xAE11, 0x8350, 0xAE12, 0x8351, 0xAE13, 0x8352,
+	0xAE14, 0xB1E1, 0xAE15, 0x8353, 0xAE16, 0x8354, 0xAE17, 0x8355,
+	0xAE18, 0x8356, 0xAE19, 0x8357, 0xAE1A, 0x8358, 0xAE1B, 0x8359,
+	0xAE1C, 0x835A, 0xAE1D, 0x8361, 0xAE1E, 0x8362, 0xAE1F, 0x8363,
+	0xAE20, 0x8364, 0xAE21, 0x8365, 0xAE22, 0x8366, 0xAE23, 0x8367,
+	0xAE24, 0x8368, 0xAE25, 0x8369, 0xAE26, 0x836A, 0xAE27, 0x836B,
+	0xAE28, 0x836C, 0xAE29, 0x836D, 0xAE2A, 0x836E, 0xAE2B, 0x836F,
+	0xAE2C, 0x8370, 0xAE2D, 0x8371, 0xAE2E, 0x8372, 0xAE2F, 0x8373,
+	0xAE30, 0xB1E2, 0xAE31, 0xB1E3, 0xAE32, 0x8374, 0xAE33, 0x8375,
+	0xAE34, 0xB1E4, 0xAE35, 0x8376, 0xAE36, 0x8377, 0xAE37, 0xB1E5,
+	0xAE38, 0xB1E6, 0xAE39, 0x8378, 0xAE3A, 0xB1E7, 0xAE3B, 0x8379,
+	0xAE3C, 0x837A, 0xAE3D, 0x8381, 0xAE3E, 0x8382, 0xAE3F, 0x8383,
+	0xAE40, 0xB1E8, 0xAE41, 0xB1E9, 0xAE42, 0x8384, 0xAE43, 0xB1EA,
+	0xAE44, 0x8385, 0xAE45, 0xB1EB, 0xAE46, 0xB1EC, 0xAE47, 0x8386,
+	0xAE48, 0x8387, 0xAE49, 0x8388, 0xAE4A, 0xB1ED, 0xAE4B, 0x8389,
+	0xAE4C, 0xB1EE, 0xAE4D, 0xB1EF, 0xAE4E, 0xB1F0, 0xAE4F, 0x838A,
+	0xAE50, 0xB1F1, 0xAE51, 0x838B, 0xAE52, 0x838C, 0xAE53, 0x838D,
+	0xAE54, 0xB1F2, 0xAE55, 0x838E, 0xAE56, 0xB1F3, 0xAE57, 0x838F,
+	0xAE58, 0x8390, 0xAE59, 0x8391, 0xAE5A, 0x8392, 0xAE5B, 0x8393,
+	0xAE5C, 0xB1F4, 0xAE5D, 0xB1F5, 0xAE5E, 0x8394, 0xAE5F, 0xB1F6,
+	0xAE60, 0xB1F7, 0xAE61, 0xB1F8, 0xAE62, 0x8395, 0xAE63, 0x8396,
+	0xAE64, 0x8397, 0xAE65, 0xB1F9, 0xAE66, 0x8398, 0xAE67, 0x8399,
+	0xAE68, 0xB1FA, 0xAE69, 0xB1FB, 0xAE6A, 0x839A, 0xAE6B, 0x839B,
+	0xAE6C, 0xB1FC, 0xAE6D, 0x839C, 0xAE6E, 0x839D, 0xAE6F, 0x839E,
+	0xAE70, 0xB1FD, 0xAE71, 0x839F, 0xAE72, 0x83A0, 0xAE73, 0x83A1,
+	0xAE74, 0x83A2, 0xAE75, 0x83A3, 0xAE76, 0x83A4, 0xAE77, 0x83A5,
+	0xAE78, 0xB1FE, 0xAE79, 0xB2A1, 0xAE7A, 0x83A6, 0xAE7B, 0xB2A2,
+	0xAE7C, 0xB2A3, 0xAE7D, 0xB2A4, 0xAE7E, 0x83A7, 0xAE7F, 0x83A8,
+	0xAE80, 0x83A9, 0xAE81, 0x83AA, 0xAE82, 0x83AB, 0xAE83, 0x83AC,
+	0xAE84, 0xB2A5, 0xAE85, 0xB2A6, 0xAE86, 0x83AD, 0xAE87, 0x83AE,
+	0xAE88, 0x83AF, 0xAE89, 0x83B0, 0xAE8A, 0x83B1, 0xAE8B, 0x83B2,
+	0xAE8C, 0xB2A7, 0xAE8D, 0x83B3, 0xAE8E, 0x83B4, 0xAE8F, 0x83B5,
+	0xAE90, 0x83B6, 0xAE91, 0x83B7, 0xAE92, 0x83B8, 0xAE93, 0x83B9,
+	0xAE94, 0x83BA, 0xAE95, 0x83BB, 0xAE96, 0x83BC, 0xAE97, 0x83BD,
+	0xAE98, 0x83BE, 0xAE99, 0x83BF, 0xAE9A, 0x83C0, 0xAE9B, 0x83C1,
+	0xAE9C, 0x83C2, 0xAE9D, 0x83C3, 0xAE9E, 0x83C4, 0xAE9F, 0x83C5,
+	0xAEA0, 0x83C6, 0xAEA1, 0x83C7, 0xAEA2, 0x83C8, 0xAEA3, 0x83C9,
+	0xAEA4, 0x83CA, 0xAEA5, 0x83CB, 0xAEA6, 0x83CC, 0xAEA7, 0x83CD,
+	0xAEA8, 0x83CE, 0xAEA9, 0x83CF, 0xAEAA, 0x83D0, 0xAEAB, 0x83D1,
+	0xAEAC, 0x83D2, 0xAEAD, 0x83D3, 0xAEAE, 0x83D4, 0xAEAF, 0x83D5,
+	0xAEB0, 0x83D6, 0xAEB1, 0x83D7, 0xAEB2, 0x83D8, 0xAEB3, 0x83D9,
+	0xAEB4, 0x83DA, 0xAEB5, 0x83DB, 0xAEB6, 0x83DC, 0xAEB7, 0x83DD,
+	0xAEB8, 0x83DE, 0xAEB9, 0x83DF, 0xAEBA, 0x83E0, 0xAEBB, 0x83E1,
+	0xAEBC, 0xB2A8, 0xAEBD, 0xB2A9, 0xAEBE, 0xB2AA, 0xAEBF, 0x83E2,
+	0xAEC0, 0xB2AB, 0xAEC1, 0x83E3, 0xAEC2, 0x83E4, 0xAEC3, 0x83E5,
+	0xAEC4, 0xB2AC, 0xAEC5, 0x83E6, 0xAEC6, 0x83E7, 0xAEC7, 0x83E8,
+	0xAEC8, 0x83E9, 0xAEC9, 0x83EA, 0xAECA, 0x83EB, 0xAECB, 0x83EC,
+	0xAECC, 0xB2AD, 0xAECD, 0xB2AE, 0xAECE, 0x83ED, 0xAECF, 0xB2AF,
+	0xAED0, 0xB2B0, 0xAED1, 0xB2B1, 0xAED2, 0x83EE, 0xAED3, 0x83EF,
+	0xAED4, 0x83F0, 0xAED5, 0x83F1, 0xAED6, 0x83F2, 0xAED7, 0x83F3,
+	0xAED8, 0xB2B2, 0xAED9, 0xB2B3, 0xAEDA, 0x83F4, 0xAEDB, 0x83F5,
+	0xAEDC, 0xB2B4, 0xAEDD, 0x83F6, 0xAEDE, 0x83F7, 0xAEDF, 0x83F8,
+	0xAEE0, 0x83F9, 0xAEE1, 0x83FA, 0xAEE2, 0x83FB, 0xAEE3, 0x83FC,
+	0xAEE4, 0x83FD, 0xAEE5, 0x83FE, 0xAEE6, 0x8441, 0xAEE7, 0x8442,
+	0xAEE8, 0xB2B5, 0xAEE9, 0x8443, 0xAEEA, 0x8444, 0xAEEB, 0xB2B6,
+	0xAEEC, 0x8445, 0xAEED, 0xB2B7, 0xAEEE, 0x8446, 0xAEEF, 0x8447,
+	0xAEF0, 0x8448, 0xAEF1, 0x8449, 0xAEF2, 0x844A, 0xAEF3, 0x844B,
+	0xAEF4, 0xB2B8, 0xAEF5, 0x844C, 0xAEF6, 0x844D, 0xAEF7, 0x844E,
+	0xAEF8, 0xB2B9, 0xAEF9, 0x844F, 0xAEFA, 0x8450, 0xAEFB, 0x8451,
+	0xAEFC, 0xB2BA, 0xAEFD, 0x8452, 0xAEFE, 0x8453, 0xAEFF, 0x8454,
+	0xAF00, 0x8455, 0xAF01, 0x8456, 0xAF02, 0x8457, 0xAF03, 0x8458,
+	0xAF04, 0x8459, 0xAF05, 0x845A, 0xAF06, 0x8461, 0xAF07, 0xB2BB,
+	0xAF08, 0xB2BC, 0xAF09, 0x8462, 0xAF0A, 0x8463, 0xAF0B, 0x8464,
+	0xAF0C, 0x8465, 0xAF0D, 0xB2BD, 0xAF0E, 0x8466, 0xAF0F, 0x8467,
+	0xAF10, 0xB2BE, 0xAF11, 0x8468, 0xAF12, 0x8469, 0xAF13, 0x846A,
+	0xAF14, 0x846B, 0xAF15, 0x846C, 0xAF16, 0x846D, 0xAF17, 0x846E,
+	0xAF18, 0x846F, 0xAF19, 0x8470, 0xAF1A, 0x8471, 0xAF1B, 0x8472,
+	0xAF1C, 0x8473, 0xAF1D, 0x8474, 0xAF1E, 0x8475, 0xAF1F, 0x8476,
+	0xAF20, 0x8477, 0xAF21, 0x8478, 0xAF22, 0x8479, 0xAF23, 0x847A,
+	0xAF24, 0x8481, 0xAF25, 0x8482, 0xAF26, 0x8483, 0xAF27, 0x8484,
+	0xAF28, 0x8485, 0xAF29, 0x8486, 0xAF2A, 0x8487, 0xAF2B, 0x8488,
+	0xAF2C, 0xB2BF, 0xAF2D, 0xB2C0, 0xAF2E, 0x8489, 0xAF2F, 0x848A,
+	0xAF30, 0xB2C1, 0xAF31, 0x848B, 0xAF32, 0xB2C2, 0xAF33, 0x848C,
+	0xAF34, 0xB2C3, 0xAF35, 0x848D, 0xAF36, 0x848E, 0xAF37, 0x848F,
+	0xAF38, 0x8490, 0xAF39, 0x8491, 0xAF3A, 0x8492, 0xAF3B, 0x8493,
+	0xAF3C, 0xB2C4, 0xAF3D, 0xB2C5, 0xAF3E, 0x8494, 0xAF3F, 0xB2C6,
+	0xAF40, 0x8495, 0xAF41, 0xB2C7, 0xAF42, 0xB2C8, 0xAF43, 0xB2C9,
+	0xAF44, 0x8496, 0xAF45, 0x8497, 0xAF46, 0x8498, 0xAF47, 0x8499,
+	0xAF48, 0xB2CA, 0xAF49, 0xB2CB, 0xAF4A, 0x849A, 0xAF4B, 0x849B,
+	0xAF4C, 0x849C, 0xAF4D, 0x849D, 0xAF4E, 0x849E, 0xAF4F, 0x849F,
+	0xAF50, 0xB2CC, 0xAF51, 0x84A0, 0xAF52, 0x84A1, 0xAF53, 0x84A2,
+	0xAF54, 0x84A3, 0xAF55, 0x84A4, 0xAF56, 0x84A5, 0xAF57, 0x84A6,
+	0xAF58, 0x84A7, 0xAF59, 0x84A8, 0xAF5A, 0x84A9, 0xAF5B, 0x84AA,
+	0xAF5C, 0xB2CD, 0xAF5D, 0xB2CE, 0xAF5E, 0x84AB, 0xAF5F, 0x84AC,
+	0xAF60, 0x84AD, 0xAF61, 0x84AE, 0xAF62, 0x84AF, 0xAF63, 0x84B0,
+	0xAF64, 0xB2CF, 0xAF65, 0xB2D0, 0xAF66, 0x84B1, 0xAF67, 0x84B2,
+	0xAF68, 0x84B3, 0xAF69, 0x84B4, 0xAF6A, 0x84B5, 0xAF6B, 0x84B6,
+	0xAF6C, 0x84B7, 0xAF6D, 0x84B8, 0xAF6E, 0x84B9, 0xAF6F, 0x84BA,
+	0xAF70, 0x84BB, 0xAF71, 0x84BC, 0xAF72, 0x84BD, 0xAF73, 0x84BE,
+	0xAF74, 0x84BF, 0xAF75, 0x84C0, 0xAF76, 0x84C1, 0xAF77, 0x84C2,
+	0xAF78, 0x84C3, 0xAF79, 0xB2D1, 0xAF7A, 0x84C4, 0xAF7B, 0x84C5,
+	0xAF7C, 0x84C6, 0xAF7D, 0x84C7, 0xAF7E, 0x84C8, 0xAF7F, 0x84C9,
+	0xAF80, 0xB2D2, 0xAF81, 0x84CA, 0xAF82, 0x84CB, 0xAF83, 0x84CC,
+	0xAF84, 0xB2D3, 0xAF85, 0x84CD, 0xAF86, 0x84CE, 0xAF87, 0x84CF,
+	0xAF88, 0xB2D4, 0xAF89, 0x84D0, 0xAF8A, 0x84D1, 0xAF8B, 0x84D2,
+	0xAF8C, 0x84D3, 0xAF8D, 0x84D4, 0xAF8E, 0x84D5, 0xAF8F, 0x84D6,
+	0xAF90, 0xB2D5, 0xAF91, 0xB2D6, 0xAF92, 0x84D7, 0xAF93, 0x84D8,
+	0xAF94, 0x84D9, 0xAF95, 0xB2D7, 0xAF96, 0x84DA, 0xAF97, 0x84DB,
+	0xAF98, 0x84DC, 0xAF99, 0x84DD, 0xAF9A, 0x84DE, 0xAF9B, 0x84DF,
+	0xAF9C, 0xB2D8, 0xAF9D, 0x84E0, 0xAF9E, 0x84E1, 0xAF9F, 0x84E2,
+	0xAFA0, 0x84E3, 0xAFA1, 0x84E4, 0xAFA2, 0x84E5, 0xAFA3, 0x84E6,
+	0xAFA4, 0x84E7, 0xAFA5, 0x84E8, 0xAFA6, 0x84E9, 0xAFA7, 0x84EA,
+	0xAFA8, 0x84EB, 0xAFA9, 0x84EC, 0xAFAA, 0x84ED, 0xAFAB, 0x84EE,
+	0xAFAC, 0x84EF, 0xAFAD, 0x84F0, 0xAFAE, 0x84F1, 0xAFAF, 0x84F2,
+	0xAFB0, 0x84F3, 0xAFB1, 0x84F4, 0xAFB2, 0x84F5, 0xAFB3, 0x84F6,
+	0xAFB4, 0x84F7, 0xAFB5, 0x84F8, 0xAFB6, 0x84F9, 0xAFB7, 0x84FA,
+	0xAFB8, 0xB2D9, 0xAFB9, 0xB2DA, 0xAFBA, 0x84FB, 0xAFBB, 0x84FC,
+	0xAFBC, 0xB2DB, 0xAFBD, 0x84FD, 0xAFBE, 0x84FE, 0xAFBF, 0x8541,
+	0xAFC0, 0xB2DC, 0xAFC1, 0x8542, 0xAFC2, 0x8543, 0xAFC3, 0x8544,
+	0xAFC4, 0x8545, 0xAFC5, 0x8546, 0xAFC6, 0x8547, 0xAFC7, 0xB2DD,
+	0xAFC8, 0xB2DE, 0xAFC9, 0xB2DF, 0xAFCA, 0x8548, 0xAFCB, 0xB2E0,
+	0xAFCC, 0x8549, 0xAFCD, 0xB2E1, 0xAFCE, 0xB2E2, 0xAFCF, 0x854A,
+	0xAFD0, 0x854B, 0xAFD1, 0x854C, 0xAFD2, 0x854D, 0xAFD3, 0x854E,
+	0xAFD4, 0xB2E3, 0xAFD5, 0x854F, 0xAFD6, 0x8550, 0xAFD7, 0x8551,
+	0xAFD8, 0x8552, 0xAFD9, 0x8553, 0xAFDA, 0x8554, 0xAFDB, 0x8555,
+	0xAFDC, 0xB2E4, 0xAFDD, 0x8556, 0xAFDE, 0x8557, 0xAFDF, 0x8558,
+	0xAFE0, 0x8559, 0xAFE1, 0x855A, 0xAFE2, 0x8561, 0xAFE3, 0x8562,
+	0xAFE4, 0x8563, 0xAFE5, 0x8564, 0xAFE6, 0x8565, 0xAFE7, 0x8566,
+	0xAFE8, 0xB2E5, 0xAFE9, 0xB2E6, 0xAFEA, 0x8567, 0xAFEB, 0x8568,
+	0xAFEC, 0x8569, 0xAFED, 0x856A, 0xAFEE, 0x856B, 0xAFEF, 0x856C,
+	0xAFF0, 0xB2E7, 0xAFF1, 0xB2E8, 0xAFF2, 0x856D, 0xAFF3, 0x856E,
+	0xAFF4, 0xB2E9, 0xAFF5, 0x856F, 0xAFF6, 0x8570, 0xAFF7, 0x8571,
+	0xAFF8, 0xB2EA, 0xAFF9, 0x8572, 0xAFFA, 0x8573, 0xAFFB, 0x8574,
+	0xAFFC, 0x8575, 0xAFFD, 0x8576, 0xAFFE, 0x8577, 0xAFFF, 0x8578,
+	0xB000, 0xB2EB, 0xB001, 0xB2EC, 0xB002, 0x8579, 0xB003, 0x857A,
+	0xB004, 0xB2ED, 0xB005, 0x8581, 0xB006, 0x8582, 0xB007, 0x8583,
+	0xB008, 0x8584, 0xB009, 0x8585, 0xB00A, 0x8586, 0xB00B, 0x8587,
+	0xB00C, 0xB2EE, 0xB00D, 0x8588, 0xB00E, 0x8589, 0xB00F, 0x858A,
+	0xB010, 0xB2EF, 0xB011, 0x858B, 0xB012, 0x858C, 0xB013, 0x858D,
+	0xB014, 0xB2F0, 0xB015, 0x858E, 0xB016, 0x858F, 0xB017, 0x8590,
+	0xB018, 0x8591, 0xB019, 0x8592, 0xB01A, 0x8593, 0xB01B, 0x8594,
+	0xB01C, 0xB2F1, 0xB01D, 0xB2F2, 0xB01E, 0x8595, 0xB01F, 0x8596,
+	0xB020, 0x8597, 0xB021, 0x8598, 0xB022, 0x8599, 0xB023, 0x859A,
+	0xB024, 0x859B, 0xB025, 0x859C, 0xB026, 0x859D, 0xB027, 0x859E,
+	0xB028, 0xB2F3, 0xB029, 0x859F, 0xB02A, 0x85A0, 0xB02B, 0x85A1,
+	0xB02C, 0x85A2, 0xB02D, 0x85A3, 0xB02E, 0x85A4, 0xB02F, 0x85A5,
+	0xB030, 0x85A6, 0xB031, 0x85A7, 0xB032, 0x85A8, 0xB033, 0x85A9,
+	0xB034, 0x85AA, 0xB035, 0x85AB, 0xB036, 0x85AC, 0xB037, 0x85AD,
+	0xB038, 0x85AE, 0xB039, 0x85AF, 0xB03A, 0x85B0, 0xB03B, 0x85B1,
+	0xB03C, 0x85B2, 0xB03D, 0x85B3, 0xB03E, 0x85B4, 0xB03F, 0x85B5,
+	0xB040, 0x85B6, 0xB041, 0x85B7, 0xB042, 0x85B8, 0xB043, 0x85B9,
+	0xB044, 0xB2F4, 0xB045, 0xB2F5, 0xB046, 0x85BA, 0xB047, 0x85BB,
+	0xB048, 0xB2F6, 0xB049, 0x85BC, 0xB04A, 0xB2F7, 0xB04B, 0x85BD,
+	0xB04C, 0xB2F8, 0xB04D, 0x85BE, 0xB04E, 0xB2F9, 0xB04F, 0x85BF,
+	0xB050, 0x85C0, 0xB051, 0x85C1, 0xB052, 0x85C2, 0xB053, 0xB2FA,
+	0xB054, 0xB2FB, 0xB055, 0xB2FC, 0xB056, 0x85C3, 0xB057, 0xB2FD,
+	0xB058, 0x85C4, 0xB059, 0xB2FE, 0xB05A, 0x85C5, 0xB05B, 0x85C6,
+	0xB05C, 0x85C7, 0xB05D, 0xB3A1, 0xB05E, 0x85C8, 0xB05F, 0x85C9,
+	0xB060, 0x85CA, 0xB061, 0x85CB, 0xB062, 0x85CC, 0xB063, 0x85CD,
+	0xB064, 0x85CE, 0xB065, 0x85CF, 0xB066, 0x85D0, 0xB067, 0x85D1,
+	0xB068, 0x85D2, 0xB069, 0x85D3, 0xB06A, 0x85D4, 0xB06B, 0x85D5,
+	0xB06C, 0x85D6, 0xB06D, 0x85D7, 0xB06E, 0x85D8, 0xB06F, 0x85D9,
+	0xB070, 0x85DA, 0xB071, 0x85DB, 0xB072, 0x85DC, 0xB073, 0x85DD,
+	0xB074, 0x85DE, 0xB075, 0x85DF, 0xB076, 0x85E0, 0xB077, 0x85E1,
+	0xB078, 0x85E2, 0xB079, 0x85E3, 0xB07A, 0x85E4, 0xB07B, 0x85E5,
+	0xB07C, 0xB3A2, 0xB07D, 0xB3A3, 0xB07E, 0x85E6, 0xB07F, 0x85E7,
+	0xB080, 0xB3A4, 0xB081, 0x85E8, 0xB082, 0x85E9, 0xB083, 0x85EA,
+	0xB084, 0xB3A5, 0xB085, 0x85EB, 0xB086, 0x85EC, 0xB087, 0x85ED,
+	0xB088, 0x85EE, 0xB089, 0x85EF, 0xB08A, 0x85F0, 0xB08B, 0x85F1,
+	0xB08C, 0xB3A6, 0xB08D, 0xB3A7, 0xB08E, 0x85F2, 0xB08F, 0xB3A8,
+	0xB090, 0x85F3, 0xB091, 0xB3A9, 0xB092, 0x85F4, 0xB093, 0x85F5,
+	0xB094, 0x85F6, 0xB095, 0x85F7, 0xB096, 0x85F8, 0xB097, 0x85F9,
+	0xB098, 0xB3AA, 0xB099, 0xB3AB, 0xB09A, 0xB3AC, 0xB09B, 0x85FA,
+	0xB09C, 0xB3AD, 0xB09D, 0x85FB, 0xB09E, 0x85FC, 0xB09F, 0xB3AE,
+	0xB0A0, 0xB3AF, 0xB0A1, 0xB3B0, 0xB0A2, 0xB3B1, 0xB0A3, 0x85FD,
+	0xB0A4, 0x85FE, 0xB0A5, 0x8641, 0xB0A6, 0x8642, 0xB0A7, 0x8643,
+	0xB0A8, 0xB3B2, 0xB0A9, 0xB3B3, 0xB0AA, 0x8644, 0xB0AB, 0xB3B4,
+	0xB0AC, 0xB3B5, 0xB0AD, 0xB3B6, 0xB0AE, 0xB3B7, 0xB0AF, 0xB3B8,
+	0xB0B0, 0x8645, 0xB0B1, 0xB3B9, 0xB0B2, 0x8646, 0xB0B3, 0xB3BA,
+	0xB0B4, 0xB3BB, 0xB0B5, 0xB3BC, 0xB0B6, 0x8647, 0xB0B7, 0x8648,
+	0xB0B8, 0xB3BD, 0xB0B9, 0x8649, 0xB0BA, 0x864A, 0xB0BB, 0x864B,
+	0xB0BC, 0xB3BE, 0xB0BD, 0x864C, 0xB0BE, 0x864D, 0xB0BF, 0x864E,
+	0xB0C0, 0x864F, 0xB0C1, 0x8650, 0xB0C2, 0x8651, 0xB0C3, 0x8652,
+	0xB0C4, 0xB3BF, 0xB0C5, 0xB3C0, 0xB0C6, 0x8653, 0xB0C7, 0xB3C1,
+	0xB0C8, 0xB3C2, 0xB0C9, 0xB3C3, 0xB0CA, 0x8654, 0xB0CB, 0x8655,
+	0xB0CC, 0x8656, 0xB0CD, 0x8657, 0xB0CE, 0x8658, 0xB0CF, 0x8659,
+	0xB0D0, 0xB3C4, 0xB0D1, 0xB3C5, 0xB0D2, 0x865A, 0xB0D3, 0x8661,
+	0xB0D4, 0xB3C6, 0xB0D5, 0x8662, 0xB0D6, 0x8663, 0xB0D7, 0x8664,
+	0xB0D8, 0xB3C7, 0xB0D9, 0x8665, 0xB0DA, 0x8666, 0xB0DB, 0x8667,
+	0xB0DC, 0x8668, 0xB0DD, 0x8669, 0xB0DE, 0x866A, 0xB0DF, 0x866B,
+	0xB0E0, 0xB3C8, 0xB0E1, 0x866C, 0xB0E2, 0x866D, 0xB0E3, 0x866E,
+	0xB0E4, 0x866F, 0xB0E5, 0xB3C9, 0xB0E6, 0x8670, 0xB0E7, 0x8671,
+	0xB0E8, 0x8672, 0xB0E9, 0x8673, 0xB0EA, 0x8674, 0xB0EB, 0x8675,
+	0xB0EC, 0x8676, 0xB0ED, 0x8677, 0xB0EE, 0x8678, 0xB0EF, 0x8679,
+	0xB0F0, 0x867A, 0xB0F1, 0x8681, 0xB0F2, 0x8682, 0xB0F3, 0x8683,
+	0xB0F4, 0x8684, 0xB0F5, 0x8685, 0xB0F6, 0x8686, 0xB0F7, 0x8687,
+	0xB0F8, 0x8688, 0xB0F9, 0x8689, 0xB0FA, 0x868A, 0xB0FB, 0x868B,
+	0xB0FC, 0x868C, 0xB0FD, 0x868D, 0xB0FE, 0x868E, 0xB0FF, 0x868F,
+	0xB100, 0x8690, 0xB101, 0x8691, 0xB102, 0x8692, 0xB103, 0x8693,
+	0xB104, 0x8694, 0xB105, 0x8695, 0xB106, 0x8696, 0xB107, 0x8697,
+	0xB108, 0xB3CA, 0xB109, 0xB3CB, 0xB10A, 0x8698, 0xB10B, 0xB3CC,
+	0xB10C, 0xB3CD, 0xB10D, 0x8699, 0xB10E, 0x869A, 0xB10F, 0x869B,
+	0xB110, 0xB3CE, 0xB111, 0x869C, 0xB112, 0xB3CF, 0xB113, 0xB3D0,
+	0xB114, 0x869D, 0xB115, 0x869E, 0xB116, 0x869F, 0xB117, 0x86A0,
+	0xB118, 0xB3D1, 0xB119, 0xB3D2, 0xB11A, 0x86A1, 0xB11B, 0xB3D3,
+	0xB11C, 0xB3D4, 0xB11D, 0xB3D5, 0xB11E, 0x86A2, 0xB11F, 0x86A3,
+	0xB120, 0x86A4, 0xB121, 0x86A5, 0xB122, 0x86A6, 0xB123, 0xB3D6,
+	0xB124, 0xB3D7, 0xB125, 0xB3D8, 0xB126, 0x86A7, 0xB127, 0x86A8,
+	0xB128, 0xB3D9, 0xB129, 0x86A9, 0xB12A, 0x86AA, 0xB12B, 0x86AB,
+	0xB12C, 0xB3DA, 0xB12D, 0x86AC, 0xB12E, 0x86AD, 0xB12F, 0x86AE,
+	0xB130, 0x86AF, 0xB131, 0x86B0, 0xB132, 0x86B1, 0xB133, 0x86B2,
+	0xB134, 0xB3DB, 0xB135, 0xB3DC, 0xB136, 0x86B3, 0xB137, 0xB3DD,
+	0xB138, 0xB3DE, 0xB139, 0xB3DF, 0xB13A, 0x86B4, 0xB13B, 0x86B5,
+	0xB13C, 0x86B6, 0xB13D, 0x86B7, 0xB13E, 0x86B8, 0xB13F, 0x86B9,
+	0xB140, 0xB3E0, 0xB141, 0xB3E1, 0xB142, 0x86BA, 0xB143, 0x86BB,
+	0xB144, 0xB3E2, 0xB145, 0x86BC, 0xB146, 0x86BD, 0xB147, 0x86BE,
+	0xB148, 0xB3E3, 0xB149, 0x86BF, 0xB14A, 0x86C0, 0xB14B, 0x86C1,
+	0xB14C, 0x86C2, 0xB14D, 0x86C3, 0xB14E, 0x86C4, 0xB14F, 0x86C5,
+	0xB150, 0xB3E4, 0xB151, 0xB3E5, 0xB152, 0x86C6, 0xB153, 0x86C7,
+	0xB154, 0xB3E6, 0xB155, 0xB3E7, 0xB156, 0x86C8, 0xB157, 0x86C9,
+	0xB158, 0xB3E8, 0xB159, 0x86CA, 0xB15A, 0x86CB, 0xB15B, 0x86CC,
+	0xB15C, 0xB3E9, 0xB15D, 0x86CD, 0xB15E, 0x86CE, 0xB15F, 0x86CF,
+	0xB160, 0xB3EA, 0xB161, 0x86D0, 0xB162, 0x86D1, 0xB163, 0x86D2,
+	0xB164, 0x86D3, 0xB165, 0x86D4, 0xB166, 0x86D5, 0xB167, 0x86D6,
+	0xB168, 0x86D7, 0xB169, 0x86D8, 0xB16A, 0x86D9, 0xB16B, 0x86DA,
+	0xB16C, 0x86DB, 0xB16D, 0x86DC, 0xB16E, 0x86DD, 0xB16F, 0x86DE,
+	0xB170, 0x86DF, 0xB171, 0x86E0, 0xB172, 0x86E1, 0xB173, 0x86E2,
+	0xB174, 0x86E3, 0xB175, 0x86E4, 0xB176, 0x86E5, 0xB177, 0x86E6,
+	0xB178, 0xB3EB, 0xB179, 0xB3EC, 0xB17A, 0x86E7, 0xB17B, 0x86E8,
+	0xB17C, 0xB3ED, 0xB17D, 0x86E9, 0xB17E, 0x86EA, 0xB17F, 0x86EB,
+	0xB180, 0xB3EE, 0xB181, 0x86EC, 0xB182, 0xB3EF, 0xB183, 0x86ED,
+	0xB184, 0x86EE, 0xB185, 0x86EF, 0xB186, 0x86F0, 0xB187, 0x86F1,
+	0xB188, 0xB3F0, 0xB189, 0xB3F1, 0xB18A, 0x86F2, 0xB18B, 0xB3F2,
+	0xB18C, 0x86F3, 0xB18D, 0xB3F3, 0xB18E, 0x86F4, 0xB18F, 0x86F5,
+	0xB190, 0x86F6, 0xB191, 0x86F7, 0xB192, 0xB3F4, 0xB193, 0xB3F5,
+	0xB194, 0xB3F6, 0xB195, 0x86F8, 0xB196, 0x86F9, 0xB197, 0x86FA,
+	0xB198, 0xB3F7, 0xB199, 0x86FB, 0xB19A, 0x86FC, 0xB19B, 0x86FD,
+	0xB19C, 0xB3F8, 0xB19D, 0x86FE, 0xB19E, 0x8741, 0xB19F, 0x8742,
+	0xB1A0, 0x8743, 0xB1A1, 0x8744, 0xB1A2, 0x8745, 0xB1A3, 0x8746,
+	0xB1A4, 0x8747, 0xB1A5, 0x8748, 0xB1A6, 0x8749, 0xB1A7, 0x874A,
+	0xB1A8, 0xB3F9, 0xB1A9, 0x874B, 0xB1AA, 0x874C, 0xB1AB, 0x874D,
+	0xB1AC, 0x874E, 0xB1AD, 0x874F, 0xB1AE, 0x8750, 0xB1AF, 0x8751,
+	0xB1B0, 0x8752, 0xB1B1, 0x8753, 0xB1B2, 0x8754, 0xB1B3, 0x8755,
+	0xB1B4, 0x8756, 0xB1B5, 0x8757, 0xB1B6, 0x8758, 0xB1B7, 0x8759,
+	0xB1B8, 0x875A, 0xB1B9, 0x8761, 0xB1BA, 0x8762, 0xB1BB, 0x8763,
+	0xB1BC, 0x8764, 0xB1BD, 0x8765, 0xB1BE, 0x8766, 0xB1BF, 0x8767,
+	0xB1C0, 0x8768, 0xB1C1, 0x8769, 0xB1C2, 0x876A, 0xB1C3, 0x876B,
+	0xB1C4, 0x876C, 0xB1C5, 0x876D, 0xB1C6, 0x876E, 0xB1C7, 0x876F,
+	0xB1C8, 0x8770, 0xB1C9, 0x8771, 0xB1CA, 0x8772, 0xB1CB, 0x8773,
+	0xB1CC, 0xB3FA, 0xB1CD, 0x8774, 0xB1CE, 0x8775, 0xB1CF, 0x8776,
+	0xB1D0, 0xB3FB, 0xB1D1, 0x8777, 0xB1D2, 0x8778, 0xB1D3, 0x8779,
+	0xB1D4, 0xB3FC, 0xB1D5, 0x877A, 0xB1D6, 0x8781, 0xB1D7, 0x8782,
+	0xB1D8, 0x8783, 0xB1D9, 0x8784, 0xB1DA, 0x8785, 0xB1DB, 0x8786,
+	0xB1DC, 0xB3FD, 0xB1DD, 0xB3FE, 0xB1DE, 0x8787, 0xB1DF, 0xB4A1,
+	0xB1E0, 0x8788, 0xB1E1, 0x8789, 0xB1E2, 0x878A, 0xB1E3, 0x878B,
+	0xB1E4, 0x878C, 0xB1E5, 0x878D, 0xB1E6, 0x878E, 0xB1E7, 0x878F,
+	0xB1E8, 0xB4A2, 0xB1E9, 0xB4A3, 0xB1EA, 0x8790, 0xB1EB, 0x8791,
+	0xB1EC, 0xB4A4, 0xB1ED, 0x8792, 0xB1EE, 0x8793, 0xB1EF, 0x8794,
+	0xB1F0, 0xB4A5, 0xB1F1, 0x8795, 0xB1F2, 0x8796, 0xB1F3, 0x8797,
+	0xB1F4, 0x8798, 0xB1F5, 0x8799, 0xB1F6, 0x879A, 0xB1F7, 0x879B,
+	0xB1F8, 0x879C, 0xB1F9, 0xB4A6, 0xB1FA, 0x879D, 0xB1FB, 0xB4A7,
+	0xB1FC, 0x879E, 0xB1FD, 0xB4A8, 0xB1FE, 0x879F, 0xB1FF, 0x87A0,
+	0xB200, 0x87A1, 0xB201, 0x87A2, 0xB202, 0x87A3, 0xB203, 0x87A4,
+	0xB204, 0xB4A9, 0xB205, 0xB4AA, 0xB206, 0x87A5, 0xB207, 0x87A6,
+	0xB208, 0xB4AB, 0xB209, 0x87A7, 0xB20A, 0x87A8, 0xB20B, 0xB4AC,
+	0xB20C, 0xB4AD, 0xB20D, 0x87A9, 0xB20E, 0x87AA, 0xB20F, 0x87AB,
+	0xB210, 0x87AC, 0xB211, 0x87AD, 0xB212, 0x87AE, 0xB213, 0x87AF,
+	0xB214, 0xB4AE, 0xB215, 0xB4AF, 0xB216, 0x87B0, 0xB217, 0xB4B0,
+	0xB218, 0x87B1, 0xB219, 0xB4B1, 0xB21A, 0x87B2, 0xB21B, 0x87B3,
+	0xB21C, 0x87B4, 0xB21D, 0x87B5, 0xB21E, 0x87B6, 0xB21F, 0x87B7,
+	0xB220, 0xB4B2, 0xB221, 0x87B8, 0xB222, 0x87B9, 0xB223, 0x87BA,
+	0xB224, 0x87BB, 0xB225, 0x87BC, 0xB226, 0x87BD, 0xB227, 0x87BE,
+	0xB228, 0x87BF, 0xB229, 0x87C0, 0xB22A, 0x87C1, 0xB22B, 0x87C2,
+	0xB22C, 0x87C3, 0xB22D, 0x87C4, 0xB22E, 0x87C5, 0xB22F, 0x87C6,
+	0xB230, 0x87C7, 0xB231, 0x87C8, 0xB232, 0x87C9, 0xB233, 0x87CA,
+	0xB234, 0xB4B3, 0xB235, 0x87CB, 0xB236, 0x87CC, 0xB237, 0x87CD,
+	0xB238, 0x87CE, 0xB239, 0x87CF, 0xB23A, 0x87D0, 0xB23B, 0x87D1,
+	0xB23C, 0xB4B4, 0xB23D, 0x87D2, 0xB23E, 0x87D3, 0xB23F, 0x87D4,
+	0xB240, 0x87D5, 0xB241, 0x87D6, 0xB242, 0x87D7, 0xB243, 0x87D8,
+	0xB244, 0x87D9, 0xB245, 0x87DA, 0xB246, 0x87DB, 0xB247, 0x87DC,
+	0xB248, 0x87DD, 0xB249, 0x87DE, 0xB24A, 0x87DF, 0xB24B, 0x87E0,
+	0xB24C, 0x87E1, 0xB24D, 0x87E2, 0xB24E, 0x87E3, 0xB24F, 0x87E4,
+	0xB250, 0x87E5, 0xB251, 0x87E6, 0xB252, 0x87E7, 0xB253, 0x87E8,
+	0xB254, 0x87E9, 0xB255, 0x87EA, 0xB256, 0x87EB, 0xB257, 0x87EC,
+	0xB258, 0xB4B5, 0xB259, 0x87ED, 0xB25A, 0x87EE, 0xB25B, 0x87EF,
+	0xB25C, 0xB4B6, 0xB25D, 0x87F0, 0xB25E, 0x87F1, 0xB25F, 0x87F2,
+	0xB260, 0xB4B7, 0xB261, 0x87F3, 0xB262, 0x87F4, 0xB263, 0x87F5,
+	0xB264, 0x87F6, 0xB265, 0x87F7, 0xB266, 0x87F8, 0xB267, 0x87F9,
+	0xB268, 0xB4B8, 0xB269, 0xB4B9, 0xB26A, 0x87FA, 0xB26B, 0x87FB,
+	0xB26C, 0x87FC, 0xB26D, 0x87FD, 0xB26E, 0x87FE, 0xB26F, 0x8841,
+	0xB270, 0x8842, 0xB271, 0x8843, 0xB272, 0x8844, 0xB273, 0x8845,
+	0xB274, 0xB4BA, 0xB275, 0xB4BB, 0xB276, 0x8846, 0xB277, 0x8847,
+	0xB278, 0x8848, 0xB279, 0x8849, 0xB27A, 0x884A, 0xB27B, 0x884B,
+	0xB27C, 0xB4BC, 0xB27D, 0x884C, 0xB27E, 0x884D, 0xB27F, 0x884E,
+	0xB280, 0x884F, 0xB281, 0x8850, 0xB282, 0x8851, 0xB283, 0x8852,
+	0xB284, 0xB4BD, 0xB285, 0xB4BE, 0xB286, 0x8853, 0xB287, 0x8854,
+	0xB288, 0x8855, 0xB289, 0xB4BF, 0xB28A, 0x8856, 0xB28B, 0x8857,
+	0xB28C, 0x8858, 0xB28D, 0x8859, 0xB28E, 0x885A, 0xB28F, 0x8861,
+	0xB290, 0xB4C0, 0xB291, 0xB4C1, 0xB292, 0x8862, 0xB293, 0x8863,
+	0xB294, 0xB4C2, 0xB295, 0x8864, 0xB296, 0x8865, 0xB297, 0x8866,
+	0xB298, 0xB4C3, 0xB299, 0xB4C4, 0xB29A, 0xB4C5, 0xB29B, 0x8867,
+	0xB29C, 0x8868, 0xB29D, 0x8869, 0xB29E, 0x886A, 0xB29F, 0x886B,
+	0xB2A0, 0xB4C6, 0xB2A1, 0xB4C7, 0xB2A2, 0x886C, 0xB2A3, 0xB4C8,
+	0xB2A4, 0x886D, 0xB2A5, 0xB4C9, 0xB2A6, 0xB4CA, 0xB2A7, 0x886E,
+	0xB2A8, 0x886F, 0xB2A9, 0x8870, 0xB2AA, 0xB4CB, 0xB2AB, 0x8871,
+	0xB2AC, 0xB4CC, 0xB2AD, 0x8872, 0xB2AE, 0x8873, 0xB2AF, 0x8874,
+	0xB2B0, 0xB4CD, 0xB2B1, 0x8875, 0xB2B2, 0x8876, 0xB2B3, 0x8877,
+	0xB2B4, 0xB4CE, 0xB2B5, 0x8878, 0xB2B6, 0x8879, 0xB2B7, 0x887A,
+	0xB2B8, 0x8881, 0xB2B9, 0x8882, 0xB2BA, 0x8883, 0xB2BB, 0x8884,
+	0xB2BC, 0x8885, 0xB2BD, 0x8886, 0xB2BE, 0x8887, 0xB2BF, 0x8888,
+	0xB2C0, 0x8889, 0xB2C1, 0x888A, 0xB2C2, 0x888B, 0xB2C3, 0x888C,
+	0xB2C4, 0x888D, 0xB2C5, 0x888E, 0xB2C6, 0x888F, 0xB2C7, 0x8890,
+	0xB2C8, 0xB4CF, 0xB2C9, 0xB4D0, 0xB2CA, 0x8891, 0xB2CB, 0x8892,
+	0xB2CC, 0xB4D1, 0xB2CD, 0x8893, 0xB2CE, 0x8894, 0xB2CF, 0x8895,
+	0xB2D0, 0xB4D2, 0xB2D1, 0x8896, 0xB2D2, 0xB4D3, 0xB2D3, 0x8897,
+	0xB2D4, 0x8898, 0xB2D5, 0x8899, 0xB2D6, 0x889A, 0xB2D7, 0x889B,
+	0xB2D8, 0xB4D4, 0xB2D9, 0xB4D5, 0xB2DA, 0x889C, 0xB2DB, 0xB4D6,
+	0xB2DC, 0x889D, 0xB2DD, 0xB4D7, 0xB2DE, 0x889E, 0xB2DF, 0x889F,
+	0xB2E0, 0x88A0, 0xB2E1, 0x88A1, 0xB2E2, 0xB4D8, 0xB2E3, 0x88A2,
+	0xB2E4, 0xB4D9, 0xB2E5, 0xB4DA, 0xB2E6, 0xB4DB, 0xB2E7, 0x88A3,
+	0xB2E8, 0xB4DC, 0xB2E9, 0x88A4, 0xB2EA, 0x88A5, 0xB2EB, 0xB4DD,
+	0xB2EC, 0xB4DE, 0xB2ED, 0xB4DF, 0xB2EE, 0xB4E0, 0xB2EF, 0xB4E1,
+	0xB2F0, 0x88A6, 0xB2F1, 0x88A7, 0xB2F2, 0x88A8, 0xB2F3, 0xB4E2,
+	0xB2F4, 0xB4E3, 0xB2F5, 0xB4E4, 0xB2F6, 0x88A9, 0xB2F7, 0xB4E5,
+	0xB2F8, 0xB4E6, 0xB2F9, 0xB4E7, 0xB2FA, 0xB4E8, 0xB2FB, 0xB4E9,
+	0xB2FC, 0x88AA, 0xB2FD, 0x88AB, 0xB2FE, 0x88AC, 0xB2FF, 0xB4EA,
+	0xB300, 0xB4EB, 0xB301, 0xB4EC, 0xB302, 0x88AD, 0xB303, 0x88AE,
+	0xB304, 0xB4ED, 0xB305, 0x88AF, 0xB306, 0x88B0, 0xB307, 0x88B1,
+	0xB308, 0xB4EE, 0xB309, 0x88B2, 0xB30A, 0x88B3, 0xB30B, 0x88B4,
+	0xB30C, 0x88B5, 0xB30D, 0x88B6, 0xB30E, 0x88B7, 0xB30F, 0x88B8,
+	0xB310, 0xB4EF, 0xB311, 0xB4F0, 0xB312, 0x88B9, 0xB313, 0xB4F1,
+	0xB314, 0xB4F2, 0xB315, 0xB4F3, 0xB316, 0x88BA, 0xB317, 0x88BB,
+	0xB318, 0x88BC, 0xB319, 0x88BD, 0xB31A, 0x88BE, 0xB31B, 0x88BF,
+	0xB31C, 0xB4F4, 0xB31D, 0x88C0, 0xB31E, 0x88C1, 0xB31F, 0x88C2,
+	0xB320, 0x88C3, 0xB321, 0x88C4, 0xB322, 0x88C5, 0xB323, 0x88C6,
+	0xB324, 0x88C7, 0xB325, 0x88C8, 0xB326, 0x88C9, 0xB327, 0x88CA,
+	0xB328, 0x88CB, 0xB329, 0x88CC, 0xB32A, 0x88CD, 0xB32B, 0x88CE,
+	0xB32C, 0x88CF, 0xB32D, 0x88D0, 0xB32E, 0x88D1, 0xB32F, 0x88D2,
+	0xB330, 0x88D3, 0xB331, 0x88D4, 0xB332, 0x88D5, 0xB333, 0x88D6,
+	0xB334, 0x88D7, 0xB335, 0x88D8, 0xB336, 0x88D9, 0xB337, 0x88DA,
+	0xB338, 0x88DB, 0xB339, 0x88DC, 0xB33A, 0x88DD, 0xB33B, 0x88DE,
+	0xB33C, 0x88DF, 0xB33D, 0x88E0, 0xB33E, 0x88E1, 0xB33F, 0x88E2,
+	0xB340, 0x88E3, 0xB341, 0x88E4, 0xB342, 0x88E5, 0xB343, 0x88E6,
+	0xB344, 0x88E7, 0xB345, 0x88E8, 0xB346, 0x88E9, 0xB347, 0x88EA,
+	0xB348, 0x88EB, 0xB349, 0x88EC, 0xB34A, 0x88ED, 0xB34B, 0x88EE,
+	0xB34C, 0x88EF, 0xB34D, 0x88F0, 0xB34E, 0x88F1, 0xB34F, 0x88F2,
+	0xB350, 0x88F3, 0xB351, 0x88F4, 0xB352, 0x88F5, 0xB353, 0x88F6,
+	0xB354, 0xB4F5, 0xB355, 0xB4F6, 0xB356, 0xB4F7, 0xB357, 0x88F7,
+	0xB358, 0xB4F8, 0xB359, 0x88F8, 0xB35A, 0x88F9, 0xB35B, 0xB4F9,
+	0xB35C, 0xB4FA, 0xB35D, 0x88FA, 0xB35E, 0xB4FB, 0xB35F, 0xB4FC,
+	0xB360, 0x88FB, 0xB361, 0x88FC, 0xB362, 0x88FD, 0xB363, 0x88FE,
+	0xB364, 0xB4FD, 0xB365, 0xB4FE, 0xB366, 0x8941, 0xB367, 0xB5A1,
+	0xB368, 0x8942, 0xB369, 0xB5A2, 0xB36A, 0x8943, 0xB36B, 0xB5A3,
+	0xB36C, 0x8944, 0xB36D, 0x8945, 0xB36E, 0xB5A4, 0xB36F, 0x8946,
+	0xB370, 0xB5A5, 0xB371, 0xB5A6, 0xB372, 0x8947, 0xB373, 0x8948,
+	0xB374, 0xB5A7, 0xB375, 0x8949, 0xB376, 0x894A, 0xB377, 0x894B,
+	0xB378, 0xB5A8, 0xB379, 0x894C, 0xB37A, 0x894D, 0xB37B, 0x894E,
+	0xB37C, 0x894F, 0xB37D, 0x8950, 0xB37E, 0x8951, 0xB37F, 0x8952,
+	0xB380, 0xB5A9, 0xB381, 0xB5AA, 0xB382, 0x8953, 0xB383, 0xB5AB,
+	0xB384, 0xB5AC, 0xB385, 0xB5AD, 0xB386, 0x8954, 0xB387, 0x8955,
+	0xB388, 0x8956, 0xB389, 0x8957, 0xB38A, 0x8958, 0xB38B, 0x8959,
+	0xB38C, 0xB5AE, 0xB38D, 0x895A, 0xB38E, 0x8961, 0xB38F, 0x8962,
+	0xB390, 0xB5AF, 0xB391, 0x8963, 0xB392, 0x8964, 0xB393, 0x8965,
+	0xB394, 0xB5B0, 0xB395, 0x8966, 0xB396, 0x8967, 0xB397, 0x8968,
+	0xB398, 0x8969, 0xB399, 0x896A, 0xB39A, 0x896B, 0xB39B, 0x896C,
+	0xB39C, 0x896D, 0xB39D, 0x896E, 0xB39E, 0x896F, 0xB39F, 0x8970,
+	0xB3A0, 0xB5B1, 0xB3A1, 0xB5B2, 0xB3A2, 0x8971, 0xB3A3, 0x8972,
+	0xB3A4, 0x8973, 0xB3A5, 0x8974, 0xB3A6, 0x8975, 0xB3A7, 0x8976,
+	0xB3A8, 0xB5B3, 0xB3A9, 0x8977, 0xB3AA, 0x8978, 0xB3AB, 0x8979,
+	0xB3AC, 0xB5B4, 0xB3AD, 0x897A, 0xB3AE, 0x8981, 0xB3AF, 0x8982,
+	0xB3B0, 0x8983, 0xB3B1, 0x8984, 0xB3B2, 0x8985, 0xB3B3, 0x8986,
+	0xB3B4, 0x8987, 0xB3B5, 0x8988, 0xB3B6, 0x8989, 0xB3B7, 0x898A,
+	0xB3B8, 0x898B, 0xB3B9, 0x898C, 0xB3BA, 0x898D, 0xB3BB, 0x898E,
+	0xB3BC, 0x898F, 0xB3BD, 0x8990, 0xB3BE, 0x8991, 0xB3BF, 0x8992,
+	0xB3C0, 0x8993, 0xB3C1, 0x8994, 0xB3C2, 0x8995, 0xB3C3, 0x8996,
+	0xB3C4, 0xB5B5, 0xB3C5, 0xB5B6, 0xB3C6, 0x8997, 0xB3C7, 0x8998,
+	0xB3C8, 0xB5B7, 0xB3C9, 0x8999, 0xB3CA, 0x899A, 0xB3CB, 0xB5B8,
+	0xB3CC, 0xB5B9, 0xB3CD, 0x899B, 0xB3CE, 0xB5BA, 0xB3CF, 0x899C,
+	0xB3D0, 0xB5BB, 0xB3D1, 0x899D, 0xB3D2, 0x899E, 0xB3D3, 0x899F,
+	0xB3D4, 0xB5BC, 0xB3D5, 0xB5BD, 0xB3D6, 0x89A0, 0xB3D7, 0xB5BE,
+	0xB3D8, 0x89A1, 0xB3D9, 0xB5BF, 0xB3DA, 0x89A2, 0xB3DB, 0xB5C0,
+	0xB3DC, 0x89A3, 0xB3DD, 0xB5C1, 0xB3DE, 0x89A4, 0xB3DF, 0x89A5,
+	0xB3E0, 0xB5C2, 0xB3E1, 0x89A6, 0xB3E2, 0x89A7, 0xB3E3, 0x89A8,
+	0xB3E4, 0xB5C3, 0xB3E5, 0x89A9, 0xB3E6, 0x89AA, 0xB3E7, 0x89AB,
+	0xB3E8, 0xB5C4, 0xB3E9, 0x89AC, 0xB3EA, 0x89AD, 0xB3EB, 0x89AE,
+	0xB3EC, 0x89AF, 0xB3ED, 0x89B0, 0xB3EE, 0x89B1, 0xB3EF, 0x89B2,
+	0xB3F0, 0x89B3, 0xB3F1, 0x89B4, 0xB3F2, 0x89B5, 0xB3F3, 0x89B6,
+	0xB3F4, 0x89B7, 0xB3F5, 0x89B8, 0xB3F6, 0x89B9, 0xB3F7, 0x89BA,
+	0xB3F8, 0x89BB, 0xB3F9, 0x89BC, 0xB3FA, 0x89BD, 0xB3FB, 0x89BE,
+	0xB3FC, 0xB5C5, 0xB3FD, 0x89BF, 0xB3FE, 0x89C0, 0xB3FF, 0x89C1,
+	0xB400, 0x89C2, 0xB401, 0x89C3, 0xB402, 0x89C4, 0xB403, 0x89C5,
+	0xB404, 0x89C6, 0xB405, 0x89C7, 0xB406, 0x89C8, 0xB407, 0x89C9,
+	0xB408, 0x89CA, 0xB409, 0x89CB, 0xB40A, 0x89CC, 0xB40B, 0x89CD,
+	0xB40C, 0x89CE, 0xB40D, 0x89CF, 0xB40E, 0x89D0, 0xB40F, 0x89D1,
+	0xB410, 0xB5C6, 0xB411, 0x89D2, 0xB412, 0x89D3, 0xB413, 0x89D4,
+	0xB414, 0x89D5, 0xB415, 0x89D6, 0xB416, 0x89D7, 0xB417, 0x89D8,
+	0xB418, 0xB5C7, 0xB419, 0x89D9, 0xB41A, 0x89DA, 0xB41B, 0x89DB,
+	0xB41C, 0xB5C8, 0xB41D, 0x89DC, 0xB41E, 0x89DD, 0xB41F, 0x89DE,
+	0xB420, 0xB5C9, 0xB421, 0x89DF, 0xB422, 0x89E0, 0xB423, 0x89E1,
+	0xB424, 0x89E2, 0xB425, 0x89E3, 0xB426, 0x89E4, 0xB427, 0x89E5,
+	0xB428, 0xB5CA, 0xB429, 0xB5CB, 0xB42A, 0x89E6, 0xB42B, 0xB5CC,
+	0xB42C, 0x89E7, 0xB42D, 0x89E8, 0xB42E, 0x89E9, 0xB42F, 0x89EA,
+	0xB430, 0x89EB, 0xB431, 0x89EC, 0xB432, 0x89ED, 0xB433, 0x89EE,
+	0xB434, 0xB5CD, 0xB435, 0x89EF, 0xB436, 0x89F0, 0xB437, 0x89F1,
+	0xB438, 0x89F2, 0xB439, 0x89F3, 0xB43A, 0x89F4, 0xB43B, 0x89F5,
+	0xB43C, 0x89F6, 0xB43D, 0x89F7, 0xB43E, 0x89F8, 0xB43F, 0x89F9,
+	0xB440, 0x89FA, 0xB441, 0x89FB, 0xB442, 0x89FC, 0xB443, 0x89FD,
+	0xB444, 0x89FE, 0xB445, 0x8A41, 0xB446, 0x8A42, 0xB447, 0x8A43,
+	0xB448, 0x8A44, 0xB449, 0x8A45, 0xB44A, 0x8A46, 0xB44B, 0x8A47,
+	0xB44C, 0x8A48, 0xB44D, 0x8A49, 0xB44E, 0x8A4A, 0xB44F, 0x8A4B,
+	0xB450, 0xB5CE, 0xB451, 0xB5CF, 0xB452, 0x8A4C, 0xB453, 0x8A4D,
+	0xB454, 0xB5D0, 0xB455, 0x8A4E, 0xB456, 0x8A4F, 0xB457, 0x8A50,
+	0xB458, 0xB5D1, 0xB459, 0x8A51, 0xB45A, 0x8A52, 0xB45B, 0x8A53,
+	0xB45C, 0x8A54, 0xB45D, 0x8A55, 0xB45E, 0x8A56, 0xB45F, 0x8A57,
+	0xB460, 0xB5D2, 0xB461, 0xB5D3, 0xB462, 0x8A58, 0xB463, 0xB5D4,
+	0xB464, 0x8A59, 0xB465, 0xB5D5, 0xB466, 0x8A5A, 0xB467, 0x8A61,
+	0xB468, 0x8A62, 0xB469, 0x8A63, 0xB46A, 0x8A64, 0xB46B, 0x8A65,
+	0xB46C, 0xB5D6, 0xB46D, 0x8A66, 0xB46E, 0x8A67, 0xB46F, 0x8A68,
+	0xB470, 0x8A69, 0xB471, 0x8A6A, 0xB472, 0x8A6B, 0xB473, 0x8A6C,
+	0xB474, 0x8A6D, 0xB475, 0x8A6E, 0xB476, 0x8A6F, 0xB477, 0x8A70,
+	0xB478, 0x8A71, 0xB479, 0x8A72, 0xB47A, 0x8A73, 0xB47B, 0x8A74,
+	0xB47C, 0x8A75, 0xB47D, 0x8A76, 0xB47E, 0x8A77, 0xB47F, 0x8A78,
+	0xB480, 0xB5D7, 0xB481, 0x8A79, 0xB482, 0x8A7A, 0xB483, 0x8A81,
+	0xB484, 0x8A82, 0xB485, 0x8A83, 0xB486, 0x8A84, 0xB487, 0x8A85,
+	0xB488, 0xB5D8, 0xB489, 0x8A86, 0xB48A, 0x8A87, 0xB48B, 0x8A88,
+	0xB48C, 0x8A89, 0xB48D, 0x8A8A, 0xB48E, 0x8A8B, 0xB48F, 0x8A8C,
+	0xB490, 0x8A8D, 0xB491, 0x8A8E, 0xB492, 0x8A8F, 0xB493, 0x8A90,
+	0xB494, 0x8A91, 0xB495, 0x8A92, 0xB496, 0x8A93, 0xB497, 0x8A94,
+	0xB498, 0x8A95, 0xB499, 0x8A96, 0xB49A, 0x8A97, 0xB49B, 0x8A98,
+	0xB49C, 0x8A99, 0xB49D, 0xB5D9, 0xB49E, 0x8A9A, 0xB49F, 0x8A9B,
+	0xB4A0, 0x8A9C, 0xB4A1, 0x8A9D, 0xB4A2, 0x8A9E, 0xB4A3, 0x8A9F,
+	0xB4A4, 0xB5DA, 0xB4A5, 0x8AA0, 0xB4A6, 0x8AA1, 0xB4A7, 0x8AA2,
+	0xB4A8, 0xB5DB, 0xB4A9, 0x8AA3, 0xB4AA, 0x8AA4, 0xB4AB, 0x8AA5,
+	0xB4AC, 0xB5DC, 0xB4AD, 0x8AA6, 0xB4AE, 0x8AA7, 0xB4AF, 0x8AA8,
+	0xB4B0, 0x8AA9, 0xB4B1, 0x8AAA, 0xB4B2, 0x8AAB, 0xB4B3, 0x8AAC,
+	0xB4B4, 0x8AAD, 0xB4B5, 0xB5DD, 0xB4B6, 0x8AAE, 0xB4B7, 0xB5DE,
+	0xB4B8, 0x8AAF, 0xB4B9, 0xB5DF, 0xB4BA, 0x8AB0, 0xB4BB, 0x8AB1,
+	0xB4BC, 0x8AB2, 0xB4BD, 0x8AB3, 0xB4BE, 0x8AB4, 0xB4BF, 0x8AB5,
+	0xB4C0, 0xB5E0, 0xB4C1, 0x8AB6, 0xB4C2, 0x8AB7, 0xB4C3, 0x8AB8,
+	0xB4C4, 0xB5E1, 0xB4C5, 0x8AB9, 0xB4C6, 0x8ABA, 0xB4C7, 0x8ABB,
+	0xB4C8, 0xB5E2, 0xB4C9, 0x8ABC, 0xB4CA, 0x8ABD, 0xB4CB, 0x8ABE,
+	0xB4CC, 0x8ABF, 0xB4CD, 0x8AC0, 0xB4CE, 0x8AC1, 0xB4CF, 0x8AC2,
+	0xB4D0, 0xB5E3, 0xB4D1, 0x8AC3, 0xB4D2, 0x8AC4, 0xB4D3, 0x8AC5,
+	0xB4D4, 0x8AC6, 0xB4D5, 0xB5E4, 0xB4D6, 0x8AC7, 0xB4D7, 0x8AC8,
+	0xB4D8, 0x8AC9, 0xB4D9, 0x8ACA, 0xB4DA, 0x8ACB, 0xB4DB, 0x8ACC,
+	0xB4DC, 0xB5E5, 0xB4DD, 0xB5E6, 0xB4DE, 0x8ACD, 0xB4DF, 0x8ACE,
+	0xB4E0, 0xB5E7, 0xB4E1, 0x8ACF, 0xB4E2, 0x8AD0, 0xB4E3, 0xB5E8,
+	0xB4E4, 0xB5E9, 0xB4E5, 0x8AD1, 0xB4E6, 0xB5EA, 0xB4E7, 0x8AD2,
+	0xB4E8, 0x8AD3, 0xB4E9, 0x8AD4, 0xB4EA, 0x8AD5, 0xB4EB, 0x8AD6,
+	0xB4EC, 0xB5EB, 0xB4ED, 0xB5EC, 0xB4EE, 0x8AD7, 0xB4EF, 0xB5ED,
+	0xB4F0, 0x8AD8, 0xB4F1, 0xB5EE, 0xB4F2, 0x8AD9, 0xB4F3, 0x8ADA,
+	0xB4F4, 0x8ADB, 0xB4F5, 0x8ADC, 0xB4F6, 0x8ADD, 0xB4F7, 0x8ADE,
+	0xB4F8, 0xB5EF, 0xB4F9, 0x8ADF, 0xB4FA, 0x8AE0, 0xB4FB, 0x8AE1,
+	0xB4FC, 0x8AE2, 0xB4FD, 0x8AE3, 0xB4FE, 0x8AE4, 0xB4FF, 0x8AE5,
+	0xB500, 0x8AE6, 0xB501, 0x8AE7, 0xB502, 0x8AE8, 0xB503, 0x8AE9,
+	0xB504, 0x8AEA, 0xB505, 0x8AEB, 0xB506, 0x8AEC, 0xB507, 0x8AED,
+	0xB508, 0x8AEE, 0xB509, 0x8AEF, 0xB50A, 0x8AF0, 0xB50B, 0x8AF1,
+	0xB50C, 0x8AF2, 0xB50D, 0x8AF3, 0xB50E, 0x8AF4, 0xB50F, 0x8AF5,
+	0xB510, 0x8AF6, 0xB511, 0x8AF7, 0xB512, 0x8AF8, 0xB513, 0x8AF9,
+	0xB514, 0xB5F0, 0xB515, 0xB5F1, 0xB516, 0x8AFA, 0xB517, 0x8AFB,
+	0xB518, 0xB5F2, 0xB519, 0x8AFC, 0xB51A, 0x8AFD, 0xB51B, 0xB5F3,
+	0xB51C, 0xB5F4, 0xB51D, 0x8AFE, 0xB51E, 0x8B41, 0xB51F, 0x8B42,
+	0xB520, 0x8B43, 0xB521, 0x8B44, 0xB522, 0x8B45, 0xB523, 0x8B46,
+	0xB524, 0xB5F5, 0xB525, 0xB5F6, 0xB526, 0x8B47, 0xB527, 0xB5F7,
+	0xB528, 0xB5F8, 0xB529, 0xB5F9, 0xB52A, 0xB5FA, 0xB52B, 0x8B48,
+	0xB52C, 0x8B49, 0xB52D, 0x8B4A, 0xB52E, 0x8B4B, 0xB52F, 0x8B4C,
+	0xB530, 0xB5FB, 0xB531, 0xB5FC, 0xB532, 0x8B4D, 0xB533, 0x8B4E,
+	0xB534, 0xB5FD, 0xB535, 0x8B4F, 0xB536, 0x8B50, 0xB537, 0x8B51,
+	0xB538, 0xB5FE, 0xB539, 0x8B52, 0xB53A, 0x8B53, 0xB53B, 0x8B54,
+	0xB53C, 0x8B55, 0xB53D, 0x8B56, 0xB53E, 0x8B57, 0xB53F, 0x8B58,
+	0xB540, 0xB6A1, 0xB541, 0xB6A2, 0xB542, 0x8B59, 0xB543, 0xB6A3,
+	0xB544, 0xB6A4, 0xB545, 0xB6A5, 0xB546, 0x8B5A, 0xB547, 0x8B61,
+	0xB548, 0x8B62, 0xB549, 0x8B63, 0xB54A, 0x8B64, 0xB54B, 0xB6A6,
+	0xB54C, 0xB6A7, 0xB54D, 0xB6A8, 0xB54E, 0x8B65, 0xB54F, 0x8B66,
+	0xB550, 0xB6A9, 0xB551, 0x8B67, 0xB552, 0x8B68, 0xB553, 0x8B69,
+	0xB554, 0xB6AA, 0xB555, 0x8B6A, 0xB556, 0x8B6B, 0xB557, 0x8B6C,
+	0xB558, 0x8B6D, 0xB559, 0x8B6E, 0xB55A, 0x8B6F, 0xB55B, 0x8B70,
+	0xB55C, 0xB6AB, 0xB55D, 0xB6AC, 0xB55E, 0x8B71, 0xB55F, 0xB6AD,
+	0xB560, 0xB6AE, 0xB561, 0xB6AF, 0xB562, 0x8B72, 0xB563, 0x8B73,
+	0xB564, 0x8B74, 0xB565, 0x8B75, 0xB566, 0x8B76, 0xB567, 0x8B77,
+	0xB568, 0x8B78, 0xB569, 0x8B79, 0xB56A, 0x8B7A, 0xB56B, 0x8B81,
+	0xB56C, 0x8B82, 0xB56D, 0x8B83, 0xB56E, 0x8B84, 0xB56F, 0x8B85,
+	0xB570, 0x8B86, 0xB571, 0x8B87, 0xB572, 0x8B88, 0xB573, 0x8B89,
+	0xB574, 0x8B8A, 0xB575, 0x8B8B, 0xB576, 0x8B8C, 0xB577, 0x8B8D,
+	0xB578, 0x8B8E, 0xB579, 0x8B8F, 0xB57A, 0x8B90, 0xB57B, 0x8B91,
+	0xB57C, 0x8B92, 0xB57D, 0x8B93, 0xB57E, 0x8B94, 0xB57F, 0x8B95,
+	0xB580, 0x8B96, 0xB581, 0x8B97, 0xB582, 0x8B98, 0xB583, 0x8B99,
+	0xB584, 0x8B9A, 0xB585, 0x8B9B, 0xB586, 0x8B9C, 0xB587, 0x8B9D,
+	0xB588, 0x8B9E, 0xB589, 0x8B9F, 0xB58A, 0x8BA0, 0xB58B, 0x8BA1,
+	0xB58C, 0x8BA2, 0xB58D, 0x8BA3, 0xB58E, 0x8BA4, 0xB58F, 0x8BA5,
+	0xB590, 0x8BA6, 0xB591, 0x8BA7, 0xB592, 0x8BA8, 0xB593, 0x8BA9,
+	0xB594, 0x8BAA, 0xB595, 0x8BAB, 0xB596, 0x8BAC, 0xB597, 0x8BAD,
+	0xB598, 0x8BAE, 0xB599, 0x8BAF, 0xB59A, 0x8BB0, 0xB59B, 0x8BB1,
+	0xB59C, 0x8BB2, 0xB59D, 0x8BB3, 0xB59E, 0x8BB4, 0xB59F, 0x8BB5,
+	0xB5A0, 0xB6B0, 0xB5A1, 0xB6B1, 0xB5A2, 0x8BB6, 0xB5A3, 0x8BB7,
+	0xB5A4, 0xB6B2, 0xB5A5, 0x8BB8, 0xB5A6, 0x8BB9, 0xB5A7, 0x8BBA,
+	0xB5A8, 0xB6B3, 0xB5A9, 0x8BBB, 0xB5AA, 0xB6B4, 0xB5AB, 0xB6B5,
+	0xB5AC, 0x8BBC, 0xB5AD, 0x8BBD, 0xB5AE, 0x8BBE, 0xB5AF, 0x8BBF,
+	0xB5B0, 0xB6B6, 0xB5B1, 0xB6B7, 0xB5B2, 0x8BC0, 0xB5B3, 0xB6B8,
+	0xB5B4, 0xB6B9, 0xB5B5, 0xB6BA, 0xB5B6, 0x8BC1, 0xB5B7, 0x8BC2,
+	0xB5B8, 0x8BC3, 0xB5B9, 0x8BC4, 0xB5BA, 0x8BC5, 0xB5BB, 0xB6BB,
+	0xB5BC, 0xB6BC, 0xB5BD, 0xB6BD, 0xB5BE, 0x8BC6, 0xB5BF, 0x8BC7,
+	0xB5C0, 0xB6BE, 0xB5C1, 0x8BC8, 0xB5C2, 0x8BC9, 0xB5C3, 0x8BCA,
+	0xB5C4, 0xB6BF, 0xB5C5, 0x8BCB, 0xB5C6, 0x8BCC, 0xB5C7, 0x8BCD,
+	0xB5C8, 0x8BCE, 0xB5C9, 0x8BCF, 0xB5CA, 0x8BD0, 0xB5CB, 0x8BD1,
+	0xB5CC, 0xB6C0, 0xB5CD, 0xB6C1, 0xB5CE, 0x8BD2, 0xB5CF, 0xB6C2,
+	0xB5D0, 0xB6C3, 0xB5D1, 0xB6C4, 0xB5D2, 0x8BD3, 0xB5D3, 0x8BD4,
+	0xB5D4, 0x8BD5, 0xB5D5, 0x8BD6, 0xB5D6, 0x8BD7, 0xB5D7, 0x8BD8,
+	0xB5D8, 0xB6C5, 0xB5D9, 0x8BD9, 0xB5DA, 0x8BDA, 0xB5DB, 0x8BDB,
+	0xB5DC, 0x8BDC, 0xB5DD, 0x8BDD, 0xB5DE, 0x8BDE, 0xB5DF, 0x8BDF,
+	0xB5E0, 0x8BE0, 0xB5E1, 0x8BE1, 0xB5E2, 0x8BE2, 0xB5E3, 0x8BE3,
+	0xB5E4, 0x8BE4, 0xB5E5, 0x8BE5, 0xB5E6, 0x8BE6, 0xB5E7, 0x8BE7,
+	0xB5E8, 0x8BE8, 0xB5E9, 0x8BE9, 0xB5EA, 0x8BEA, 0xB5EB, 0x8BEB,
+	0xB5EC, 0xB6C6, 0xB5ED, 0x8BEC, 0xB5EE, 0x8BED, 0xB5EF, 0x8BEE,
+	0xB5F0, 0x8BEF, 0xB5F1, 0x8BF0, 0xB5F2, 0x8BF1, 0xB5F3, 0x8BF2,
+	0xB5F4, 0x8BF3, 0xB5F5, 0x8BF4, 0xB5F6, 0x8BF5, 0xB5F7, 0x8BF6,
+	0xB5F8, 0x8BF7, 0xB5F9, 0x8BF8, 0xB5FA, 0x8BF9, 0xB5FB, 0x8BFA,
+	0xB5FC, 0x8BFB, 0xB5FD, 0x8BFC, 0xB5FE, 0x8BFD, 0xB5FF, 0x8BFE,
+	0xB600, 0x8C41, 0xB601, 0x8C42, 0xB602, 0x8C43, 0xB603, 0x8C44,
+	0xB604, 0x8C45, 0xB605, 0x8C46, 0xB606, 0x8C47, 0xB607, 0x8C48,
+	0xB608, 0x8C49, 0xB609, 0x8C4A, 0xB60A, 0x8C4B, 0xB60B, 0x8C4C,
+	0xB60C, 0x8C4D, 0xB60D, 0x8C4E, 0xB60E, 0x8C4F, 0xB60F, 0x8C50,
+	0xB610, 0xB6C7, 0xB611, 0xB6C8, 0xB612, 0x8C51, 0xB613, 0x8C52,
+	0xB614, 0xB6C9, 0xB615, 0x8C53, 0xB616, 0x8C54, 0xB617, 0x8C55,
+	0xB618, 0xB6CA, 0xB619, 0x8C56, 0xB61A, 0x8C57, 0xB61B, 0x8C58,
+	0xB61C, 0x8C59, 0xB61D, 0x8C5A, 0xB61E, 0x8C61, 0xB61F, 0x8C62,
+	0xB620, 0x8C63, 0xB621, 0x8C64, 0xB622, 0x8C65, 0xB623, 0x8C66,
+	0xB624, 0x8C67, 0xB625, 0xB6CB, 0xB626, 0x8C68, 0xB627, 0x8C69,
+	0xB628, 0x8C6A, 0xB629, 0x8C6B, 0xB62A, 0x8C6C, 0xB62B, 0x8C6D,
+	0xB62C, 0xB6CC, 0xB62D, 0x8C6E, 0xB62E, 0x8C6F, 0xB62F, 0x8C70,
+	0xB630, 0x8C71, 0xB631, 0x8C72, 0xB632, 0x8C73, 0xB633, 0x8C74,
+	0xB634, 0xB6CD, 0xB635, 0x8C75, 0xB636, 0x8C76, 0xB637, 0x8C77,
+	0xB638, 0x8C78, 0xB639, 0x8C79, 0xB63A, 0x8C7A, 0xB63B, 0x8C81,
+	0xB63C, 0x8C82, 0xB63D, 0x8C83, 0xB63E, 0x8C84, 0xB63F, 0x8C85,
+	0xB640, 0x8C86, 0xB641, 0x8C87, 0xB642, 0x8C88, 0xB643, 0x8C89,
+	0xB644, 0x8C8A, 0xB645, 0x8C8B, 0xB646, 0x8C8C, 0xB647, 0x8C8D,
+	0xB648, 0xB6CE, 0xB649, 0x8C8E, 0xB64A, 0x8C8F, 0xB64B, 0x8C90,
+	0xB64C, 0x8C91, 0xB64D, 0x8C92, 0xB64E, 0x8C93, 0xB64F, 0x8C94,
+	0xB650, 0x8C95, 0xB651, 0x8C96, 0xB652, 0x8C97, 0xB653, 0x8C98,
+	0xB654, 0x8C99, 0xB655, 0x8C9A, 0xB656, 0x8C9B, 0xB657, 0x8C9C,
+	0xB658, 0x8C9D, 0xB659, 0x8C9E, 0xB65A, 0x8C9F, 0xB65B, 0x8CA0,
+	0xB65C, 0x8CA1, 0xB65D, 0x8CA2, 0xB65E, 0x8CA3, 0xB65F, 0x8CA4,
+	0xB660, 0x8CA5, 0xB661, 0x8CA6, 0xB662, 0x8CA7, 0xB663, 0x8CA8,
+	0xB664, 0xB6CF, 0xB665, 0x8CA9, 0xB666, 0x8CAA, 0xB667, 0x8CAB,
+	0xB668, 0xB6D0, 0xB669, 0x8CAC, 0xB66A, 0x8CAD, 0xB66B, 0x8CAE,
+	0xB66C, 0x8CAF, 0xB66D, 0x8CB0, 0xB66E, 0x8CB1, 0xB66F, 0x8CB2,
+	0xB670, 0x8CB3, 0xB671, 0x8CB4, 0xB672, 0x8CB5, 0xB673, 0x8CB6,
+	0xB674, 0x8CB7, 0xB675, 0x8CB8, 0xB676, 0x8CB9, 0xB677, 0x8CBA,
+	0xB678, 0x8CBB, 0xB679, 0x8CBC, 0xB67A, 0x8CBD, 0xB67B, 0x8CBE,
+	0xB67C, 0x8CBF, 0xB67D, 0x8CC0, 0xB67E, 0x8CC1, 0xB67F, 0x8CC2,
+	0xB680, 0x8CC3, 0xB681, 0x8CC4, 0xB682, 0x8CC5, 0xB683, 0x8CC6,
+	0xB684, 0x8CC7, 0xB685, 0x8CC8, 0xB686, 0x8CC9, 0xB687, 0x8CCA,
+	0xB688, 0x8CCB, 0xB689, 0x8CCC, 0xB68A, 0x8CCD, 0xB68B, 0x8CCE,
+	0xB68C, 0x8CCF, 0xB68D, 0x8CD0, 0xB68E, 0x8CD1, 0xB68F, 0x8CD2,
+	0xB690, 0x8CD3, 0xB691, 0x8CD4, 0xB692, 0x8CD5, 0xB693, 0x8CD6,
+	0xB694, 0x8CD7, 0xB695, 0x8CD8, 0xB696, 0x8CD9, 0xB697, 0x8CDA,
+	0xB698, 0x8CDB, 0xB699, 0x8CDC, 0xB69A, 0x8CDD, 0xB69B, 0x8CDE,
+	0xB69C, 0xB6D1, 0xB69D, 0xB6D2, 0xB69E, 0x8CDF, 0xB69F, 0x8CE0,
+	0xB6A0, 0xB6D3, 0xB6A1, 0x8CE1, 0xB6A2, 0x8CE2, 0xB6A3, 0x8CE3,
+	0xB6A4, 0xB6D4, 0xB6A5, 0x8CE4, 0xB6A6, 0x8CE5, 0xB6A7, 0x8CE6,
+	0xB6A8, 0x8CE7, 0xB6A9, 0x8CE8, 0xB6AA, 0x8CE9, 0xB6AB, 0xB6D5,
+	0xB6AC, 0xB6D6, 0xB6AD, 0x8CEA, 0xB6AE, 0x8CEB, 0xB6AF, 0x8CEC,
+	0xB6B0, 0x8CED, 0xB6B1, 0xB6D7, 0xB6B2, 0x8CEE, 0xB6B3, 0x8CEF,
+	0xB6B4, 0x8CF0, 0xB6B5, 0x8CF1, 0xB6B6, 0x8CF2, 0xB6B7, 0x8CF3,
+	0xB6B8, 0x8CF4, 0xB6B9, 0x8CF5, 0xB6BA, 0x8CF6, 0xB6BB, 0x8CF7,
+	0xB6BC, 0x8CF8, 0xB6BD, 0x8CF9, 0xB6BE, 0x8CFA, 0xB6BF, 0x8CFB,
+	0xB6C0, 0x8CFC, 0xB6C1, 0x8CFD, 0xB6C2, 0x8CFE, 0xB6C3, 0x8D41,
+	0xB6C4, 0x8D42, 0xB6C5, 0x8D43, 0xB6C6, 0x8D44, 0xB6C7, 0x8D45,
+	0xB6C8, 0x8D46, 0xB6C9, 0x8D47, 0xB6CA, 0x8D48, 0xB6CB, 0x8D49,
+	0xB6CC, 0x8D4A, 0xB6CD, 0x8D4B, 0xB6CE, 0x8D4C, 0xB6CF, 0x8D4D,
+	0xB6D0, 0x8D4E, 0xB6D1, 0x8D4F, 0xB6D2, 0x8D50, 0xB6D3, 0x8D51,
+	0xB6D4, 0xB6D8, 0xB6D5, 0x8D52, 0xB6D6, 0x8D53, 0xB6D7, 0x8D54,
+	0xB6D8, 0x8D55, 0xB6D9, 0x8D56, 0xB6DA, 0x8D57, 0xB6DB, 0x8D58,
+	0xB6DC, 0x8D59, 0xB6DD, 0x8D5A, 0xB6DE, 0x8D61, 0xB6DF, 0x8D62,
+	0xB6E0, 0x8D63, 0xB6E1, 0x8D64, 0xB6E2, 0x8D65, 0xB6E3, 0x8D66,
+	0xB6E4, 0x8D67, 0xB6E5, 0x8D68, 0xB6E6, 0x8D69, 0xB6E7, 0x8D6A,
+	0xB6E8, 0x8D6B, 0xB6E9, 0x8D6C, 0xB6EA, 0x8D6D, 0xB6EB, 0x8D6E,
+	0xB6EC, 0x8D6F, 0xB6ED, 0x8D70, 0xB6EE, 0x8D71, 0xB6EF, 0x8D72,
+	0xB6F0, 0xB6D9, 0xB6F1, 0x8D73, 0xB6F2, 0x8D74, 0xB6F3, 0x8D75,
+	0xB6F4, 0xB6DA, 0xB6F5, 0x8D76, 0xB6F6, 0x8D77, 0xB6F7, 0x8D78,
+	0xB6F8, 0xB6DB, 0xB6F9, 0x8D79, 0xB6FA, 0x8D7A, 0xB6FB, 0x8D81,
+	0xB6FC, 0x8D82, 0xB6FD, 0x8D83, 0xB6FE, 0x8D84, 0xB6FF, 0x8D85,
+	0xB700, 0xB6DC, 0xB701, 0xB6DD, 0xB702, 0x8D86, 0xB703, 0x8D87,
+	0xB704, 0x8D88, 0xB705, 0xB6DE, 0xB706, 0x8D89, 0xB707, 0x8D8A,
+	0xB708, 0x8D8B, 0xB709, 0x8D8C, 0xB70A, 0x8D8D, 0xB70B, 0x8D8E,
+	0xB70C, 0x8D8F, 0xB70D, 0x8D90, 0xB70E, 0x8D91, 0xB70F, 0x8D92,
+	0xB710, 0x8D93, 0xB711, 0x8D94, 0xB712, 0x8D95, 0xB713, 0x8D96,
+	0xB714, 0x8D97, 0xB715, 0x8D98, 0xB716, 0x8D99, 0xB717, 0x8D9A,
+	0xB718, 0x8D9B, 0xB719, 0x8D9C, 0xB71A, 0x8D9D, 0xB71B, 0x8D9E,
+	0xB71C, 0x8D9F, 0xB71D, 0x8DA0, 0xB71E, 0x8DA1, 0xB71F, 0x8DA2,
+	0xB720, 0x8DA3, 0xB721, 0x8DA4, 0xB722, 0x8DA5, 0xB723, 0x8DA6,
+	0xB724, 0x8DA7, 0xB725, 0x8DA8, 0xB726, 0x8DA9, 0xB727, 0x8DAA,
+	0xB728, 0xB6DF, 0xB729, 0xB6E0, 0xB72A, 0x8DAB, 0xB72B, 0x8DAC,
+	0xB72C, 0xB6E1, 0xB72D, 0x8DAD, 0xB72E, 0x8DAE, 0xB72F, 0xB6E2,
+	0xB730, 0xB6E3, 0xB731, 0x8DAF, 0xB732, 0x8DB0, 0xB733, 0x8DB1,
+	0xB734, 0x8DB2, 0xB735, 0x8DB3, 0xB736, 0x8DB4, 0xB737, 0x8DB5,
+	0xB738, 0xB6E4, 0xB739, 0xB6E5, 0xB73A, 0x8DB6, 0xB73B, 0xB6E6,
+	0xB73C, 0x8DB7, 0xB73D, 0x8DB8, 0xB73E, 0x8DB9, 0xB73F, 0x8DBA,
+	0xB740, 0x8DBB, 0xB741, 0x8DBC, 0xB742, 0x8DBD, 0xB743, 0x8DBE,
+	0xB744, 0xB6E7, 0xB745, 0x8DBF, 0xB746, 0x8DC0, 0xB747, 0x8DC1,
+	0xB748, 0xB6E8, 0xB749, 0x8DC2, 0xB74A, 0x8DC3, 0xB74B, 0x8DC4,
+	0xB74C, 0xB6E9, 0xB74D, 0x8DC5, 0xB74E, 0x8DC6, 0xB74F, 0x8DC7,
+	0xB750, 0x8DC8, 0xB751, 0x8DC9, 0xB752, 0x8DCA, 0xB753, 0x8DCB,
+	0xB754, 0xB6EA, 0xB755, 0xB6EB, 0xB756, 0x8DCC, 0xB757, 0x8DCD,
+	0xB758, 0x8DCE, 0xB759, 0x8DCF, 0xB75A, 0x8DD0, 0xB75B, 0x8DD1,
+	0xB75C, 0x8DD2, 0xB75D, 0x8DD3, 0xB75E, 0x8DD4, 0xB75F, 0x8DD5,
+	0xB760, 0xB6EC, 0xB761, 0x8DD6, 0xB762, 0x8DD7, 0xB763, 0x8DD8,
+	0xB764, 0xB6ED, 0xB765, 0x8DD9, 0xB766, 0x8DDA, 0xB767, 0x8DDB,
+	0xB768, 0xB6EE, 0xB769, 0x8DDC, 0xB76A, 0x8DDD, 0xB76B, 0x8DDE,
+	0xB76C, 0x8DDF, 0xB76D, 0x8DE0, 0xB76E, 0x8DE1, 0xB76F, 0x8DE2,
+	0xB770, 0xB6EF, 0xB771, 0xB6F0, 0xB772, 0x8DE3, 0xB773, 0xB6F1,
+	0xB774, 0x8DE4, 0xB775, 0xB6F2, 0xB776, 0x8DE5, 0xB777, 0x8DE6,
+	0xB778, 0x8DE7, 0xB779, 0x8DE8, 0xB77A, 0x8DE9, 0xB77B, 0x8DEA,
+	0xB77C, 0xB6F3, 0xB77D, 0xB6F4, 0xB77E, 0x8DEB, 0xB77F, 0x8DEC,
+	0xB780, 0xB6F5, 0xB781, 0x8DED, 0xB782, 0x8DEE, 0xB783, 0x8DEF,
+	0xB784, 0xB6F6, 0xB785, 0x8DF0, 0xB786, 0x8DF1, 0xB787, 0x8DF2,
+	0xB788, 0x8DF3, 0xB789, 0x8DF4, 0xB78A, 0x8DF5, 0xB78B, 0x8DF6,
+	0xB78C, 0xB6F7, 0xB78D, 0xB6F8, 0xB78E, 0x8DF7, 0xB78F, 0xB6F9,
+	0xB790, 0xB6FA, 0xB791, 0xB6FB, 0xB792, 0xB6FC, 0xB793, 0x8DF8,
+	0xB794, 0x8DF9, 0xB795, 0x8DFA, 0xB796, 0xB6FD, 0xB797, 0xB6FE,
+	0xB798, 0xB7A1, 0xB799, 0xB7A2, 0xB79A, 0x8DFB, 0xB79B, 0x8DFC,
+	0xB79C, 0xB7A3, 0xB79D, 0x8DFD, 0xB79E, 0x8DFE, 0xB79F, 0x8E41,
+	0xB7A0, 0xB7A4, 0xB7A1, 0x8E42, 0xB7A2, 0x8E43, 0xB7A3, 0x8E44,
+	0xB7A4, 0x8E45, 0xB7A5, 0x8E46, 0xB7A6, 0x8E47, 0xB7A7, 0x8E48,
+	0xB7A8, 0xB7A5, 0xB7A9, 0xB7A6, 0xB7AA, 0x8E49, 0xB7AB, 0xB7A7,
+	0xB7AC, 0xB7A8, 0xB7AD, 0xB7A9, 0xB7AE, 0x8E4A, 0xB7AF, 0x8E4B,
+	0xB7B0, 0x8E4C, 0xB7B1, 0x8E4D, 0xB7B2, 0x8E4E, 0xB7B3, 0x8E4F,
+	0xB7B4, 0xB7AA, 0xB7B5, 0xB7AB, 0xB7B6, 0x8E50, 0xB7B7, 0x8E51,
+	0xB7B8, 0xB7AC, 0xB7B9, 0x8E52, 0xB7BA, 0x8E53, 0xB7BB, 0x8E54,
+	0xB7BC, 0x8E55, 0xB7BD, 0x8E56, 0xB7BE, 0x8E57, 0xB7BF, 0x8E58,
+	0xB7C0, 0x8E59, 0xB7C1, 0x8E5A, 0xB7C2, 0x8E61, 0xB7C3, 0x8E62,
+	0xB7C4, 0x8E63, 0xB7C5, 0x8E64, 0xB7C6, 0x8E65, 0xB7C7, 0xB7AD,
+	0xB7C8, 0x8E66, 0xB7C9, 0xB7AE, 0xB7CA, 0x8E67, 0xB7CB, 0x8E68,
+	0xB7CC, 0x8E69, 0xB7CD, 0x8E6A, 0xB7CE, 0x8E6B, 0xB7CF, 0x8E6C,
+	0xB7D0, 0x8E6D, 0xB7D1, 0x8E6E, 0xB7D2, 0x8E6F, 0xB7D3, 0x8E70,
+	0xB7D4, 0x8E71, 0xB7D5, 0x8E72, 0xB7D6, 0x8E73, 0xB7D7, 0x8E74,
+	0xB7D8, 0x8E75, 0xB7D9, 0x8E76, 0xB7DA, 0x8E77, 0xB7DB, 0x8E78,
+	0xB7DC, 0x8E79, 0xB7DD, 0x8E7A, 0xB7DE, 0x8E81, 0xB7DF, 0x8E82,
+	0xB7E0, 0x8E83, 0xB7E1, 0x8E84, 0xB7E2, 0x8E85, 0xB7E3, 0x8E86,
+	0xB7E4, 0x8E87, 0xB7E5, 0x8E88, 0xB7E6, 0x8E89, 0xB7E7, 0x8E8A,
+	0xB7E8, 0x8E8B, 0xB7E9, 0x8E8C, 0xB7EA, 0x8E8D, 0xB7EB, 0x8E8E,
+	0xB7EC, 0xB7AF, 0xB7ED, 0xB7B0, 0xB7EE, 0x8E8F, 0xB7EF, 0x8E90,
+	0xB7F0, 0xB7B1, 0xB7F1, 0x8E91, 0xB7F2, 0x8E92, 0xB7F3, 0x8E93,
+	0xB7F4, 0xB7B2, 0xB7F5, 0x8E94, 0xB7F6, 0x8E95, 0xB7F7, 0x8E96,
+	0xB7F8, 0x8E97, 0xB7F9, 0x8E98, 0xB7FA, 0x8E99, 0xB7FB, 0x8E9A,
+	0xB7FC, 0xB7B3, 0xB7FD, 0xB7B4, 0xB7FE, 0x8E9B, 0xB7FF, 0xB7B5,
+	0xB800, 0xB7B6, 0xB801, 0xB7B7, 0xB802, 0x8E9C, 0xB803, 0x8E9D,
+	0xB804, 0x8E9E, 0xB805, 0x8E9F, 0xB806, 0x8EA0, 0xB807, 0xB7B8,
+	0xB808, 0xB7B9, 0xB809, 0xB7BA, 0xB80A, 0x8EA1, 0xB80B, 0x8EA2,
+	0xB80C, 0xB7BB, 0xB80D, 0x8EA3, 0xB80E, 0x8EA4, 0xB80F, 0x8EA5,
+	0xB810, 0xB7BC, 0xB811, 0x8EA6, 0xB812, 0x8EA7, 0xB813, 0x8EA8,
+	0xB814, 0x8EA9, 0xB815, 0x8EAA, 0xB816, 0x8EAB, 0xB817, 0x8EAC,
+	0xB818, 0xB7BD, 0xB819, 0xB7BE, 0xB81A, 0x8EAD, 0xB81B, 0xB7BF,
+	0xB81C, 0x8EAE, 0xB81D, 0xB7C0, 0xB81E, 0x8EAF, 0xB81F, 0x8EB0,
+	0xB820, 0x8EB1, 0xB821, 0x8EB2, 0xB822, 0x8EB3, 0xB823, 0x8EB4,
+	0xB824, 0xB7C1, 0xB825, 0xB7C2, 0xB826, 0x8EB5, 0xB827, 0x8EB6,
+	0xB828, 0xB7C3, 0xB829, 0x8EB7, 0xB82A, 0x8EB8, 0xB82B, 0x8EB9,
+	0xB82C, 0xB7C4, 0xB82D, 0x8EBA, 0xB82E, 0x8EBB, 0xB82F, 0x8EBC,
+	0xB830, 0x8EBD, 0xB831, 0x8EBE, 0xB832, 0x8EBF, 0xB833, 0x8EC0,
+	0xB834, 0xB7C5, 0xB835, 0xB7C6, 0xB836, 0x8EC1, 0xB837, 0xB7C7,
+	0xB838, 0xB7C8, 0xB839, 0xB7C9, 0xB83A, 0x8EC2, 0xB83B, 0x8EC3,
+	0xB83C, 0x8EC4, 0xB83D, 0x8EC5, 0xB83E, 0x8EC6, 0xB83F, 0x8EC7,
+	0xB840, 0xB7CA, 0xB841, 0x8EC8, 0xB842, 0x8EC9, 0xB843, 0x8ECA,
+	0xB844, 0xB7CB, 0xB845, 0x8ECB, 0xB846, 0x8ECC, 0xB847, 0x8ECD,
+	0xB848, 0x8ECE, 0xB849, 0x8ECF, 0xB84A, 0x8ED0, 0xB84B, 0x8ED1,
+	0xB84C, 0x8ED2, 0xB84D, 0x8ED3, 0xB84E, 0x8ED4, 0xB84F, 0x8ED5,
+	0xB850, 0x8ED6, 0xB851, 0xB7CC, 0xB852, 0x8ED7, 0xB853, 0xB7CD,
+	0xB854, 0x8ED8, 0xB855, 0x8ED9, 0xB856, 0x8EDA, 0xB857, 0x8EDB,
+	0xB858, 0x8EDC, 0xB859, 0x8EDD, 0xB85A, 0x8EDE, 0xB85B, 0x8EDF,
+	0xB85C, 0xB7CE, 0xB85D, 0xB7CF, 0xB85E, 0x8EE0, 0xB85F, 0x8EE1,
+	0xB860, 0xB7D0, 0xB861, 0x8EE2, 0xB862, 0x8EE3, 0xB863, 0x8EE4,
+	0xB864, 0xB7D1, 0xB865, 0x8EE5, 0xB866, 0x8EE6, 0xB867, 0x8EE7,
+	0xB868, 0x8EE8, 0xB869, 0x8EE9, 0xB86A, 0x8EEA, 0xB86B, 0x8EEB,
+	0xB86C, 0xB7D2, 0xB86D, 0xB7D3, 0xB86E, 0x8EEC, 0xB86F, 0xB7D4,
+	0xB870, 0x8EED, 0xB871, 0xB7D5, 0xB872, 0x8EEE, 0xB873, 0x8EEF,
+	0xB874, 0x8EF0, 0xB875, 0x8EF1, 0xB876, 0x8EF2, 0xB877, 0x8EF3,
+	0xB878, 0xB7D6, 0xB879, 0x8EF4, 0xB87A, 0x8EF5, 0xB87B, 0x8EF6,
+	0xB87C, 0xB7D7, 0xB87D, 0x8EF7, 0xB87E, 0x8EF8, 0xB87F, 0x8EF9,
+	0xB880, 0x8EFA, 0xB881, 0x8EFB, 0xB882, 0x8EFC, 0xB883, 0x8EFD,
+	0xB884, 0x8EFE, 0xB885, 0x8F41, 0xB886, 0x8F42, 0xB887, 0x8F43,
+	0xB888, 0x8F44, 0xB889, 0x8F45, 0xB88A, 0x8F46, 0xB88B, 0x8F47,
+	0xB88C, 0x8F48, 0xB88D, 0xB7D8, 0xB88E, 0x8F49, 0xB88F, 0x8F4A,
+	0xB890, 0x8F4B, 0xB891, 0x8F4C, 0xB892, 0x8F4D, 0xB893, 0x8F4E,
+	0xB894, 0x8F4F, 0xB895, 0x8F50, 0xB896, 0x8F51, 0xB897, 0x8F52,
+	0xB898, 0x8F53, 0xB899, 0x8F54, 0xB89A, 0x8F55, 0xB89B, 0x8F56,
+	0xB89C, 0x8F57, 0xB89D, 0x8F58, 0xB89E, 0x8F59, 0xB89F, 0x8F5A,
+	0xB8A0, 0x8F61, 0xB8A1, 0x8F62, 0xB8A2, 0x8F63, 0xB8A3, 0x8F64,
+	0xB8A4, 0x8F65, 0xB8A5, 0x8F66, 0xB8A6, 0x8F67, 0xB8A7, 0x8F68,
+	0xB8A8, 0xB7D9, 0xB8A9, 0x8F69, 0xB8AA, 0x8F6A, 0xB8AB, 0x8F6B,
+	0xB8AC, 0x8F6C, 0xB8AD, 0x8F6D, 0xB8AE, 0x8F6E, 0xB8AF, 0x8F6F,
+	0xB8B0, 0xB7DA, 0xB8B1, 0x8F70, 0xB8B2, 0x8F71, 0xB8B3, 0x8F72,
+	0xB8B4, 0xB7DB, 0xB8B5, 0x8F73, 0xB8B6, 0x8F74, 0xB8B7, 0x8F75,
+	0xB8B8, 0xB7DC, 0xB8B9, 0x8F76, 0xB8BA, 0x8F77, 0xB8BB, 0x8F78,
+	0xB8BC, 0x8F79, 0xB8BD, 0x8F7A, 0xB8BE, 0x8F81, 0xB8BF, 0x8F82,
+	0xB8C0, 0xB7DD, 0xB8C1, 0xB7DE, 0xB8C2, 0x8F83, 0xB8C3, 0xB7DF,
+	0xB8C4, 0x8F84, 0xB8C5, 0xB7E0, 0xB8C6, 0x8F85, 0xB8C7, 0x8F86,
+	0xB8C8, 0x8F87, 0xB8C9, 0x8F88, 0xB8CA, 0x8F89, 0xB8CB, 0x8F8A,
+	0xB8CC, 0xB7E1, 0xB8CD, 0x8F8B, 0xB8CE, 0x8F8C, 0xB8CF, 0x8F8D,
+	0xB8D0, 0xB7E2, 0xB8D1, 0x8F8E, 0xB8D2, 0x8F8F, 0xB8D3, 0x8F90,
+	0xB8D4, 0xB7E3, 0xB8D5, 0x8F91, 0xB8D6, 0x8F92, 0xB8D7, 0x8F93,
+	0xB8D8, 0x8F94, 0xB8D9, 0x8F95, 0xB8DA, 0x8F96, 0xB8DB, 0x8F97,
+	0xB8DC, 0x8F98, 0xB8DD, 0xB7E4, 0xB8DE, 0x8F99, 0xB8DF, 0xB7E5,
+	0xB8E0, 0x8F9A, 0xB8E1, 0xB7E6, 0xB8E2, 0x8F9B, 0xB8E3, 0x8F9C,
+	0xB8E4, 0x8F9D, 0xB8E5, 0x8F9E, 0xB8E6, 0x8F9F, 0xB8E7, 0x8FA0,
+	0xB8E8, 0xB7E7, 0xB8E9, 0xB7E8, 0xB8EA, 0x8FA1, 0xB8EB, 0x8FA2,
+	0xB8EC, 0xB7E9, 0xB8ED, 0x8FA3, 0xB8EE, 0x8FA4, 0xB8EF, 0x8FA5,
+	0xB8F0, 0xB7EA, 0xB8F1, 0x8FA6, 0xB8F2, 0x8FA7, 0xB8F3, 0x8FA8,
+	0xB8F4, 0x8FA9, 0xB8F5, 0x8FAA, 0xB8F6, 0x8FAB, 0xB8F7, 0x8FAC,
+	0xB8F8, 0xB7EB, 0xB8F9, 0xB7EC, 0xB8FA, 0x8FAD, 0xB8FB, 0xB7ED,
+	0xB8FC, 0x8FAE, 0xB8FD, 0xB7EE, 0xB8FE, 0x8FAF, 0xB8FF, 0x8FB0,
+	0xB900, 0x8FB1, 0xB901, 0x8FB2, 0xB902, 0x8FB3, 0xB903, 0x8FB4,
+	0xB904, 0xB7EF, 0xB905, 0x8FB5, 0xB906, 0x8FB6, 0xB907, 0x8FB7,
+	0xB908, 0x8FB8, 0xB909, 0x8FB9, 0xB90A, 0x8FBA, 0xB90B, 0x8FBB,
+	0xB90C, 0x8FBC, 0xB90D, 0x8FBD, 0xB90E, 0x8FBE, 0xB90F, 0x8FBF,
+	0xB910, 0x8FC0, 0xB911, 0x8FC1, 0xB912, 0x8FC2, 0xB913, 0x8FC3,
+	0xB914, 0x8FC4, 0xB915, 0x8FC5, 0xB916, 0x8FC6, 0xB917, 0x8FC7,
+	0xB918, 0xB7F0, 0xB919, 0x8FC8, 0xB91A, 0x8FC9, 0xB91B, 0x8FCA,
+	0xB91C, 0x8FCB, 0xB91D, 0x8FCC, 0xB91E, 0x8FCD, 0xB91F, 0x8FCE,
+	0xB920, 0xB7F1, 0xB921, 0x8FCF, 0xB922, 0x8FD0, 0xB923, 0x8FD1,
+	0xB924, 0x8FD2, 0xB925, 0x8FD3, 0xB926, 0x8FD4, 0xB927, 0x8FD5,
+	0xB928, 0x8FD6, 0xB929, 0x8FD7, 0xB92A, 0x8FD8, 0xB92B, 0x8FD9,
+	0xB92C, 0x8FDA, 0xB92D, 0x8FDB, 0xB92E, 0x8FDC, 0xB92F, 0x8FDD,
+	0xB930, 0x8FDE, 0xB931, 0x8FDF, 0xB932, 0x8FE0, 0xB933, 0x8FE1,
+	0xB934, 0x8FE2, 0xB935, 0x8FE3, 0xB936, 0x8FE4, 0xB937, 0x8FE5,
+	0xB938, 0x8FE6, 0xB939, 0x8FE7, 0xB93A, 0x8FE8, 0xB93B, 0x8FE9,
+	0xB93C, 0xB7F2, 0xB93D, 0xB7F3, 0xB93E, 0x8FEA, 0xB93F, 0x8FEB,
+	0xB940, 0xB7F4, 0xB941, 0x8FEC, 0xB942, 0x8FED, 0xB943, 0x8FEE,
+	0xB944, 0xB7F5, 0xB945, 0x8FEF, 0xB946, 0x8FF0, 0xB947, 0x8FF1,
+	0xB948, 0x8FF2, 0xB949, 0x8FF3, 0xB94A, 0x8FF4, 0xB94B, 0x8FF5,
+	0xB94C, 0xB7F6, 0xB94D, 0x8FF6, 0xB94E, 0x8FF7, 0xB94F, 0xB7F7,
+	0xB950, 0x8FF8, 0xB951, 0xB7F8, 0xB952, 0x8FF9, 0xB953, 0x8FFA,
+	0xB954, 0x8FFB, 0xB955, 0x8FFC, 0xB956, 0x8FFD, 0xB957, 0x8FFE,
+	0xB958, 0xB7F9, 0xB959, 0xB7FA, 0xB95A, 0x9041, 0xB95B, 0x9042,
+	0xB95C, 0xB7FB, 0xB95D, 0x9043, 0xB95E, 0x9044, 0xB95F, 0x9045,
+	0xB960, 0xB7FC, 0xB961, 0x9046, 0xB962, 0x9047, 0xB963, 0x9048,
+	0xB964, 0x9049, 0xB965, 0x904A, 0xB966, 0x904B, 0xB967, 0x904C,
+	0xB968, 0xB7FD, 0xB969, 0xB7FE, 0xB96A, 0x904D, 0xB96B, 0xB8A1,
+	0xB96C, 0x904E, 0xB96D, 0xB8A2, 0xB96E, 0x904F, 0xB96F, 0x9050,
+	0xB970, 0x9051, 0xB971, 0x9052, 0xB972, 0x9053, 0xB973, 0x9054,
+	0xB974, 0xB8A3, 0xB975, 0xB8A4, 0xB976, 0x9055, 0xB977, 0x9056,
+	0xB978, 0xB8A5, 0xB979, 0x9057, 0xB97A, 0x9058, 0xB97B, 0x9059,
+	0xB97C, 0xB8A6, 0xB97D, 0x905A, 0xB97E, 0x9061, 0xB97F, 0x9062,
+	0xB980, 0x9063, 0xB981, 0x9064, 0xB982, 0x9065, 0xB983, 0x9066,
+	0xB984, 0xB8A7, 0xB985, 0xB8A8, 0xB986, 0x9067, 0xB987, 0xB8A9,
+	0xB988, 0x9068, 0xB989, 0xB8AA, 0xB98A, 0xB8AB, 0xB98B, 0x9069,
+	0xB98C, 0x906A, 0xB98D, 0xB8AC, 0xB98E, 0xB8AD, 0xB98F, 0x906B,
+	0xB990, 0x906C, 0xB991, 0x906D, 0xB992, 0x906E, 0xB993, 0x906F,
+	0xB994, 0x9070, 0xB995, 0x9071, 0xB996, 0x9072, 0xB997, 0x9073,
+	0xB998, 0x9074, 0xB999, 0x9075, 0xB99A, 0x9076, 0xB99B, 0x9077,
+	0xB99C, 0x9078, 0xB99D, 0x9079, 0xB99E, 0x907A, 0xB99F, 0x9081,
+	0xB9A0, 0x9082, 0xB9A1, 0x9083, 0xB9A2, 0x9084, 0xB9A3, 0x9085,
+	0xB9A4, 0x9086, 0xB9A5, 0x9087, 0xB9A6, 0x9088, 0xB9A7, 0x9089,
+	0xB9A8, 0x908A, 0xB9A9, 0x908B, 0xB9AA, 0x908C, 0xB9AB, 0x908D,
+	0xB9AC, 0xB8AE, 0xB9AD, 0xB8AF, 0xB9AE, 0x908E, 0xB9AF, 0x908F,
+	0xB9B0, 0xB8B0, 0xB9B1, 0x9090, 0xB9B2, 0x9091, 0xB9B3, 0x9092,
+	0xB9B4, 0xB8B1, 0xB9B5, 0x9093, 0xB9B6, 0x9094, 0xB9B7, 0x9095,
+	0xB9B8, 0x9096, 0xB9B9, 0x9097, 0xB9BA, 0x9098, 0xB9BB, 0x9099,
+	0xB9BC, 0xB8B2, 0xB9BD, 0xB8B3, 0xB9BE, 0x909A, 0xB9BF, 0xB8B4,
+	0xB9C0, 0x909B, 0xB9C1, 0xB8B5, 0xB9C2, 0x909C, 0xB9C3, 0x909D,
+	0xB9C4, 0x909E, 0xB9C5, 0x909F, 0xB9C6, 0x90A0, 0xB9C7, 0x90A1,
+	0xB9C8, 0xB8B6, 0xB9C9, 0xB8B7, 0xB9CA, 0x90A2, 0xB9CB, 0x90A3,
+	0xB9CC, 0xB8B8, 0xB9CD, 0x90A4, 0xB9CE, 0xB8B9, 0xB9CF, 0xB8BA,
+	0xB9D0, 0xB8BB, 0xB9D1, 0xB8BC, 0xB9D2, 0xB8BD, 0xB9D3, 0x90A5,
+	0xB9D4, 0x90A6, 0xB9D5, 0x90A7, 0xB9D6, 0x90A8, 0xB9D7, 0x90A9,
+	0xB9D8, 0xB8BE, 0xB9D9, 0xB8BF, 0xB9DA, 0x90AA, 0xB9DB, 0xB8C0,
+	0xB9DC, 0x90AB, 0xB9DD, 0xB8C1, 0xB9DE, 0xB8C2, 0xB9DF, 0x90AC,
+	0xB9E0, 0x90AD, 0xB9E1, 0xB8C3, 0xB9E2, 0x90AE, 0xB9E3, 0xB8C4,
+	0xB9E4, 0xB8C5, 0xB9E5, 0xB8C6, 0xB9E6, 0x90AF, 0xB9E7, 0x90B0,
+	0xB9E8, 0xB8C7, 0xB9E9, 0x90B1, 0xB9EA, 0x90B2, 0xB9EB, 0x90B3,
+	0xB9EC, 0xB8C8, 0xB9ED, 0x90B4, 0xB9EE, 0x90B5, 0xB9EF, 0x90B6,
+	0xB9F0, 0x90B7, 0xB9F1, 0x90B8, 0xB9F2, 0x90B9, 0xB9F3, 0x90BA,
+	0xB9F4, 0xB8C9, 0xB9F5, 0xB8CA, 0xB9F6, 0x90BB, 0xB9F7, 0xB8CB,
+	0xB9F8, 0xB8CC, 0xB9F9, 0xB8CD, 0xB9FA, 0xB8CE, 0xB9FB, 0x90BC,
+	0xB9FC, 0x90BD, 0xB9FD, 0x90BE, 0xB9FE, 0x90BF, 0xB9FF, 0x90C0,
+	0xBA00, 0xB8CF, 0xBA01, 0xB8D0, 0xBA02, 0x90C1, 0xBA03, 0x90C2,
+	0xBA04, 0x90C3, 0xBA05, 0x90C4, 0xBA06, 0x90C5, 0xBA07, 0x90C6,
+	0xBA08, 0xB8D1, 0xBA09, 0x90C7, 0xBA0A, 0x90C8, 0xBA0B, 0x90C9,
+	0xBA0C, 0x90CA, 0xBA0D, 0x90CB, 0xBA0E, 0x90CC, 0xBA0F, 0x90CD,
+	0xBA10, 0x90CE, 0xBA11, 0x90CF, 0xBA12, 0x90D0, 0xBA13, 0x90D1,
+	0xBA14, 0x90D2, 0xBA15, 0xB8D2, 0xBA16, 0x90D3, 0xBA17, 0x90D4,
+	0xBA18, 0x90D5, 0xBA19, 0x90D6, 0xBA1A, 0x90D7, 0xBA1B, 0x90D8,
+	0xBA1C, 0x90D9, 0xBA1D, 0x90DA, 0xBA1E, 0x90DB, 0xBA1F, 0x90DC,
+	0xBA20, 0x90DD, 0xBA21, 0x90DE, 0xBA22, 0x90DF, 0xBA23, 0x90E0,
+	0xBA24, 0x90E1, 0xBA25, 0x90E2, 0xBA26, 0x90E3, 0xBA27, 0x90E4,
+	0xBA28, 0x90E5, 0xBA29, 0x90E6, 0xBA2A, 0x90E7, 0xBA2B, 0x90E8,
+	0xBA2C, 0x90E9, 0xBA2D, 0x90EA, 0xBA2E, 0x90EB, 0xBA2F, 0x90EC,
+	0xBA30, 0x90ED, 0xBA31, 0x90EE, 0xBA32, 0x90EF, 0xBA33, 0x90F0,
+	0xBA34, 0x90F1, 0xBA35, 0x90F2, 0xBA36, 0x90F3, 0xBA37, 0x90F4,
+	0xBA38, 0xB8D3, 0xBA39, 0xB8D4, 0xBA3A, 0x90F5, 0xBA3B, 0x90F6,
+	0xBA3C, 0xB8D5, 0xBA3D, 0x90F7, 0xBA3E, 0x90F8, 0xBA3F, 0x90F9,
+	0xBA40, 0xB8D6, 0xBA41, 0x90FA, 0xBA42, 0xB8D7, 0xBA43, 0x90FB,
+	0xBA44, 0x90FC, 0xBA45, 0x90FD, 0xBA46, 0x90FE, 0xBA47, 0x9141,
+	0xBA48, 0xB8D8, 0xBA49, 0xB8D9, 0xBA4A, 0x9142, 0xBA4B, 0xB8DA,
+	0xBA4C, 0x9143, 0xBA4D, 0xB8DB, 0xBA4E, 0xB8DC, 0xBA4F, 0x9144,
+	0xBA50, 0x9145, 0xBA51, 0x9146, 0xBA52, 0x9147, 0xBA53, 0xB8DD,
+	0xBA54, 0xB8DE, 0xBA55, 0xB8DF, 0xBA56, 0x9148, 0xBA57, 0x9149,
+	0xBA58, 0xB8E0, 0xBA59, 0x914A, 0xBA5A, 0x914B, 0xBA5B, 0x914C,
+	0xBA5C, 0xB8E1, 0xBA5D, 0x914D, 0xBA5E, 0x914E, 0xBA5F, 0x914F,
+	0xBA60, 0x9150, 0xBA61, 0x9151, 0xBA62, 0x9152, 0xBA63, 0x9153,
+	0xBA64, 0xB8E2, 0xBA65, 0xB8E3, 0xBA66, 0x9154, 0xBA67, 0xB8E4,
+	0xBA68, 0xB8E5, 0xBA69, 0xB8E6, 0xBA6A, 0x9155, 0xBA6B, 0x9156,
+	0xBA6C, 0x9157, 0xBA6D, 0x9158, 0xBA6E, 0x9159, 0xBA6F, 0x915A,
+	0xBA70, 0xB8E7, 0xBA71, 0xB8E8, 0xBA72, 0x9161, 0xBA73, 0x9162,
+	0xBA74, 0xB8E9, 0xBA75, 0x9163, 0xBA76, 0x9164, 0xBA77, 0x9165,
+	0xBA78, 0xB8EA, 0xBA79, 0x9166, 0xBA7A, 0x9167, 0xBA7B, 0x9168,
+	0xBA7C, 0x9169, 0xBA7D, 0x916A, 0xBA7E, 0x916B, 0xBA7F, 0x916C,
+	0xBA80, 0x916D, 0xBA81, 0x916E, 0xBA82, 0x916F, 0xBA83, 0xB8EB,
+	0xBA84, 0xB8EC, 0xBA85, 0xB8ED, 0xBA86, 0x9170, 0xBA87, 0xB8EE,
+	0xBA88, 0x9171, 0xBA89, 0x9172, 0xBA8A, 0x9173, 0xBA8B, 0x9174,
+	0xBA8C, 0xB8EF, 0xBA8D, 0x9175, 0xBA8E, 0x9176, 0xBA8F, 0x9177,
+	0xBA90, 0x9178, 0xBA91, 0x9179, 0xBA92, 0x917A, 0xBA93, 0x9181,
+	0xBA94, 0x9182, 0xBA95, 0x9183, 0xBA96, 0x9184, 0xBA97, 0x9185,
+	0xBA98, 0x9186, 0xBA99, 0x9187, 0xBA9A, 0x9188, 0xBA9B, 0x9189,
+	0xBA9C, 0x918A, 0xBA9D, 0x918B, 0xBA9E, 0x918C, 0xBA9F, 0x918D,
+	0xBAA0, 0x918E, 0xBAA1, 0x918F, 0xBAA2, 0x9190, 0xBAA3, 0x9191,
+	0xBAA4, 0x9192, 0xBAA5, 0x9193, 0xBAA6, 0x9194, 0xBAA7, 0x9195,
+	0xBAA8, 0xB8F0, 0xBAA9, 0xB8F1, 0xBAAA, 0x9196, 0xBAAB, 0xB8F2,
+	0xBAAC, 0xB8F3, 0xBAAD, 0x9197, 0xBAAE, 0x9198, 0xBAAF, 0x9199,
+	0xBAB0, 0xB8F4, 0xBAB1, 0x919A, 0xBAB2, 0xB8F5, 0xBAB3, 0x919B,
+	0xBAB4, 0x919C, 0xBAB5, 0x919D, 0xBAB6, 0x919E, 0xBAB7, 0x919F,
+	0xBAB8, 0xB8F6, 0xBAB9, 0xB8F7, 0xBABA, 0x91A0, 0xBABB, 0xB8F8,
+	0xBABC, 0x91A1, 0xBABD, 0xB8F9, 0xBABE, 0x91A2, 0xBABF, 0x91A3,
+	0xBAC0, 0x91A4, 0xBAC1, 0x91A5, 0xBAC2, 0x91A6, 0xBAC3, 0x91A7,
+	0xBAC4, 0xB8FA, 0xBAC5, 0x91A8, 0xBAC6, 0x91A9, 0xBAC7, 0x91AA,
+	0xBAC8, 0xB8FB, 0xBAC9, 0x91AB, 0xBACA, 0x91AC, 0xBACB, 0x91AD,
+	0xBACC, 0x91AE, 0xBACD, 0x91AF, 0xBACE, 0x91B0, 0xBACF, 0x91B1,
+	0xBAD0, 0x91B2, 0xBAD1, 0x91B3, 0xBAD2, 0x91B4, 0xBAD3, 0x91B5,
+	0xBAD4, 0x91B6, 0xBAD5, 0x91B7, 0xBAD6, 0x91B8, 0xBAD7, 0x91B9,
+	0xBAD8, 0xB8FC, 0xBAD9, 0xB8FD, 0xBADA, 0x91BA, 0xBADB, 0x91BB,
+	0xBADC, 0x91BC, 0xBADD, 0x91BD, 0xBADE, 0x91BE, 0xBADF, 0x91BF,
+	0xBAE0, 0x91C0, 0xBAE1, 0x91C1, 0xBAE2, 0x91C2, 0xBAE3, 0x91C3,
+	0xBAE4, 0x91C4, 0xBAE5, 0x91C5, 0xBAE6, 0x91C6, 0xBAE7, 0x91C7,
+	0xBAE8, 0x91C8, 0xBAE9, 0x91C9, 0xBAEA, 0x91CA, 0xBAEB, 0x91CB,
+	0xBAEC, 0x91CC, 0xBAED, 0x91CD, 0xBAEE, 0x91CE, 0xBAEF, 0x91CF,
+	0xBAF0, 0x91D0, 0xBAF1, 0x91D1, 0xBAF2, 0x91D2, 0xBAF3, 0x91D3,
+	0xBAF4, 0x91D4, 0xBAF5, 0x91D5, 0xBAF6, 0x91D6, 0xBAF7, 0x91D7,
+	0xBAF8, 0x91D8, 0xBAF9, 0x91D9, 0xBAFA, 0x91DA, 0xBAFB, 0x91DB,
+	0xBAFC, 0xB8FE, 0xBAFD, 0x91DC, 0xBAFE, 0x91DD, 0xBAFF, 0x91DE,
+	0xBB00, 0xB9A1, 0xBB01, 0x91DF, 0xBB02, 0x91E0, 0xBB03, 0x91E1,
+	0xBB04, 0xB9A2, 0xBB05, 0x91E2, 0xBB06, 0x91E3, 0xBB07, 0x91E4,
+	0xBB08, 0x91E5, 0xBB09, 0x91E6, 0xBB0A, 0x91E7, 0xBB0B, 0x91E8,
+	0xBB0C, 0x91E9, 0xBB0D, 0xB9A3, 0xBB0E, 0x91EA, 0xBB0F, 0xB9A4,
+	0xBB10, 0x91EB, 0xBB11, 0xB9A5, 0xBB12, 0x91EC, 0xBB13, 0x91ED,
+	0xBB14, 0x91EE, 0xBB15, 0x91EF, 0xBB16, 0x91F0, 0xBB17, 0x91F1,
+	0xBB18, 0xB9A6, 0xBB19, 0x91F2, 0xBB1A, 0x91F3, 0xBB1B, 0x91F4,
+	0xBB1C, 0xB9A7, 0xBB1D, 0x91F5, 0xBB1E, 0x91F6, 0xBB1F, 0x91F7,
+	0xBB20, 0xB9A8, 0xBB21, 0x91F8, 0xBB22, 0x91F9, 0xBB23, 0x91FA,
+	0xBB24, 0x91FB, 0xBB25, 0x91FC, 0xBB26, 0x91FD, 0xBB27, 0x91FE,
+	0xBB28, 0x9241, 0xBB29, 0xB9A9, 0xBB2A, 0x9242, 0xBB2B, 0xB9AA,
+	0xBB2C, 0x9243, 0xBB2D, 0x9244, 0xBB2E, 0x9245, 0xBB2F, 0x9246,
+	0xBB30, 0x9247, 0xBB31, 0x9248, 0xBB32, 0x9249, 0xBB33, 0x924A,
+	0xBB34, 0xB9AB, 0xBB35, 0xB9AC, 0xBB36, 0xB9AD, 0xBB37, 0x924B,
+	0xBB38, 0xB9AE, 0xBB39, 0x924C, 0xBB3A, 0x924D, 0xBB3B, 0xB9AF,
+	0xBB3C, 0xB9B0, 0xBB3D, 0xB9B1, 0xBB3E, 0xB9B2, 0xBB3F, 0x924E,
+	0xBB40, 0x924F, 0xBB41, 0x9250, 0xBB42, 0x9251, 0xBB43, 0x9252,
+	0xBB44, 0xB9B3, 0xBB45, 0xB9B4, 0xBB46, 0x9253, 0xBB47, 0xB9B5,
+	0xBB48, 0x9254, 0xBB49, 0xB9B6, 0xBB4A, 0x9255, 0xBB4B, 0x9256,
+	0xBB4C, 0x9257, 0xBB4D, 0xB9B7, 0xBB4E, 0x9258, 0xBB4F, 0xB9B8,
+	0xBB50, 0xB9B9, 0xBB51, 0x9259, 0xBB52, 0x925A, 0xBB53, 0x9261,
+	0xBB54, 0xB9BA, 0xBB55, 0x9262, 0xBB56, 0x9263, 0xBB57, 0x9264,
+	0xBB58, 0xB9BB, 0xBB59, 0x9265, 0xBB5A, 0x9266, 0xBB5B, 0x9267,
+	0xBB5C, 0x9268, 0xBB5D, 0x9269, 0xBB5E, 0x926A, 0xBB5F, 0x926B,
+	0xBB60, 0x926C, 0xBB61, 0xB9BC, 0xBB62, 0x926D, 0xBB63, 0xB9BD,
+	0xBB64, 0x926E, 0xBB65, 0x926F, 0xBB66, 0x9270, 0xBB67, 0x9271,
+	0xBB68, 0x9272, 0xBB69, 0x9273, 0xBB6A, 0x9274, 0xBB6B, 0x9275,
+	0xBB6C, 0xB9BE, 0xBB6D, 0x9276, 0xBB6E, 0x9277, 0xBB6F, 0x9278,
+	0xBB70, 0x9279, 0xBB71, 0x927A, 0xBB72, 0x9281, 0xBB73, 0x9282,
+	0xBB74, 0x9283, 0xBB75, 0x9284, 0xBB76, 0x9285, 0xBB77, 0x9286,
+	0xBB78, 0x9287, 0xBB79, 0x9288, 0xBB7A, 0x9289, 0xBB7B, 0x928A,
+	0xBB7C, 0x928B, 0xBB7D, 0x928C, 0xBB7E, 0x928D, 0xBB7F, 0x928E,
+	0xBB80, 0x928F, 0xBB81, 0x9290, 0xBB82, 0x9291, 0xBB83, 0x9292,
+	0xBB84, 0x9293, 0xBB85, 0x9294, 0xBB86, 0x9295, 0xBB87, 0x9296,
+	0xBB88, 0xB9BF, 0xBB89, 0x9297, 0xBB8A, 0x9298, 0xBB8B, 0x9299,
+	0xBB8C, 0xB9C0, 0xBB8D, 0x929A, 0xBB8E, 0x929B, 0xBB8F, 0x929C,
+	0xBB90, 0xB9C1, 0xBB91, 0x929D, 0xBB92, 0x929E, 0xBB93, 0x929F,
+	0xBB94, 0x92A0, 0xBB95, 0x92A1, 0xBB96, 0x92A2, 0xBB97, 0x92A3,
+	0xBB98, 0x92A4, 0xBB99, 0x92A5, 0xBB9A, 0x92A6, 0xBB9B, 0x92A7,
+	0xBB9C, 0x92A8, 0xBB9D, 0x92A9, 0xBB9E, 0x92AA, 0xBB9F, 0x92AB,
+	0xBBA0, 0x92AC, 0xBBA1, 0x92AD, 0xBBA2, 0x92AE, 0xBBA3, 0x92AF,
+	0xBBA4, 0xB9C2, 0xBBA5, 0x92B0, 0xBBA6, 0x92B1, 0xBBA7, 0x92B2,
+	0xBBA8, 0xB9C3, 0xBBA9, 0x92B3, 0xBBAA, 0x92B4, 0xBBAB, 0x92B5,
+	0xBBAC, 0xB9C4, 0xBBAD, 0x92B6, 0xBBAE, 0x92B7, 0xBBAF, 0x92B8,
+	0xBBB0, 0x92B9, 0xBBB1, 0x92BA, 0xBBB2, 0x92BB, 0xBBB3, 0x92BC,
+	0xBBB4, 0xB9C5, 0xBBB5, 0x92BD, 0xBBB6, 0x92BE, 0xBBB7, 0xB9C6,
+	0xBBB8, 0x92BF, 0xBBB9, 0x92C0, 0xBBBA, 0x92C1, 0xBBBB, 0x92C2,
+	0xBBBC, 0x92C3, 0xBBBD, 0x92C4, 0xBBBE, 0x92C5, 0xBBBF, 0x92C6,
+	0xBBC0, 0xB9C7, 0xBBC1, 0x92C7, 0xBBC2, 0x92C8, 0xBBC3, 0x92C9,
+	0xBBC4, 0xB9C8, 0xBBC5, 0x92CA, 0xBBC6, 0x92CB, 0xBBC7, 0x92CC,
+	0xBBC8, 0xB9C9, 0xBBC9, 0x92CD, 0xBBCA, 0x92CE, 0xBBCB, 0x92CF,
+	0xBBCC, 0x92D0, 0xBBCD, 0x92D1, 0xBBCE, 0x92D2, 0xBBCF, 0x92D3,
+	0xBBD0, 0xB9CA, 0xBBD1, 0x92D4, 0xBBD2, 0x92D5, 0xBBD3, 0xB9CB,
+	0xBBD4, 0x92D6, 0xBBD5, 0x92D7, 0xBBD6, 0x92D8, 0xBBD7, 0x92D9,
+	0xBBD8, 0x92DA, 0xBBD9, 0x92DB, 0xBBDA, 0x92DC, 0xBBDB, 0x92DD,
+	0xBBDC, 0x92DE, 0xBBDD, 0x92DF, 0xBBDE, 0x92E0, 0xBBDF, 0x92E1,
+	0xBBE0, 0x92E2, 0xBBE1, 0x92E3, 0xBBE2, 0x92E4, 0xBBE3, 0x92E5,
+	0xBBE4, 0x92E6, 0xBBE5, 0x92E7, 0xBBE6, 0x92E8, 0xBBE7, 0x92E9,
+	0xBBE8, 0x92EA, 0xBBE9, 0x92EB, 0xBBEA, 0x92EC, 0xBBEB, 0x92ED,
+	0xBBEC, 0x92EE, 0xBBED, 0x92EF, 0xBBEE, 0x92F0, 0xBBEF, 0x92F1,
+	0xBBF0, 0x92F2, 0xBBF1, 0x92F3, 0xBBF2, 0x92F4, 0xBBF3, 0x92F5,
+	0xBBF4, 0x92F6, 0xBBF5, 0x92F7, 0xBBF6, 0x92F8, 0xBBF7, 0x92F9,
+	0xBBF8, 0xB9CC, 0xBBF9, 0xB9CD, 0xBBFA, 0x92FA, 0xBBFB, 0x92FB,
+	0xBBFC, 0xB9CE, 0xBBFD, 0x92FC, 0xBBFE, 0x92FD, 0xBBFF, 0xB9CF,
+	0xBC00, 0xB9D0, 0xBC01, 0x92FE, 0xBC02, 0xB9D1, 0xBC03, 0x9341,
+	0xBC04, 0x9342, 0xBC05, 0x9343, 0xBC06, 0x9344, 0xBC07, 0x9345,
+	0xBC08, 0xB9D2, 0xBC09, 0xB9D3, 0xBC0A, 0x9346, 0xBC0B, 0xB9D4,
+	0xBC0C, 0xB9D5, 0xBC0D, 0xB9D6, 0xBC0E, 0x9347, 0xBC0F, 0xB9D7,
+	0xBC10, 0x9348, 0xBC11, 0xB9D8, 0xBC12, 0x9349, 0xBC13, 0x934A,
+	0xBC14, 0xB9D9, 0xBC15, 0xB9DA, 0xBC16, 0xB9DB, 0xBC17, 0xB9DC,
+	0xBC18, 0xB9DD, 0xBC19, 0x934B, 0xBC1A, 0x934C, 0xBC1B, 0xB9DE,
+	0xBC1C, 0xB9DF, 0xBC1D, 0xB9E0, 0xBC1E, 0xB9E1, 0xBC1F, 0xB9E2,
+	0xBC20, 0x934D, 0xBC21, 0x934E, 0xBC22, 0x934F, 0xBC23, 0x9350,
+	0xBC24, 0xB9E3, 0xBC25, 0xB9E4, 0xBC26, 0x9351, 0xBC27, 0xB9E5,
+	0xBC28, 0x9352, 0xBC29, 0xB9E6, 0xBC2A, 0x9353, 0xBC2B, 0x9354,
+	0xBC2C, 0x9355, 0xBC2D, 0xB9E7, 0xBC2E, 0x9356, 0xBC2F, 0x9357,
+	0xBC30, 0xB9E8, 0xBC31, 0xB9E9, 0xBC32, 0x9358, 0xBC33, 0x9359,
+	0xBC34, 0xB9EA, 0xBC35, 0x935A, 0xBC36, 0x9361, 0xBC37, 0x9362,
+	0xBC38, 0xB9EB, 0xBC39, 0x9363, 0xBC3A, 0x9364, 0xBC3B, 0x9365,
+	0xBC3C, 0x9366, 0xBC3D, 0x9367, 0xBC3E, 0x9368, 0xBC3F, 0x9369,
+	0xBC40, 0xB9EC, 0xBC41, 0xB9ED, 0xBC42, 0x936A, 0xBC43, 0xB9EE,
+	0xBC44, 0xB9EF, 0xBC45, 0xB9F0, 0xBC46, 0x936B, 0xBC47, 0x936C,
+	0xBC48, 0x936D, 0xBC49, 0xB9F1, 0xBC4A, 0x936E, 0xBC4B, 0x936F,
+	0xBC4C, 0xB9F2, 0xBC4D, 0xB9F3, 0xBC4E, 0x9370, 0xBC4F, 0x9371,
+	0xBC50, 0xB9F4, 0xBC51, 0x9372, 0xBC52, 0x9373, 0xBC53, 0x9374,
+	0xBC54, 0x9375, 0xBC55, 0x9376, 0xBC56, 0x9377, 0xBC57, 0x9378,
+	0xBC58, 0x9379, 0xBC59, 0x937A, 0xBC5A, 0x9381, 0xBC5B, 0x9382,
+	0xBC5C, 0x9383, 0xBC5D, 0xB9F5, 0xBC5E, 0x9384, 0xBC5F, 0x9385,
+	0xBC60, 0x9386, 0xBC61, 0x9387, 0xBC62, 0x9388, 0xBC63, 0x9389,
+	0xBC64, 0x938A, 0xBC65, 0x938B, 0xBC66, 0x938C, 0xBC67, 0x938D,
+	0xBC68, 0x938E, 0xBC69, 0x938F, 0xBC6A, 0x9390, 0xBC6B, 0x9391,
+	0xBC6C, 0x9392, 0xBC6D, 0x9393, 0xBC6E, 0x9394, 0xBC6F, 0x9395,
+	0xBC70, 0x9396, 0xBC71, 0x9397, 0xBC72, 0x9398, 0xBC73, 0x9399,
+	0xBC74, 0x939A, 0xBC75, 0x939B, 0xBC76, 0x939C, 0xBC77, 0x939D,
+	0xBC78, 0x939E, 0xBC79, 0x939F, 0xBC7A, 0x93A0, 0xBC7B, 0x93A1,
+	0xBC7C, 0x93A2, 0xBC7D, 0x93A3, 0xBC7E, 0x93A4, 0xBC7F, 0x93A5,
+	0xBC80, 0x93A6, 0xBC81, 0x93A7, 0xBC82, 0x93A8, 0xBC83, 0x93A9,
+	0xBC84, 0xB9F6, 0xBC85, 0xB9F7, 0xBC86, 0x93AA, 0xBC87, 0x93AB,
+	0xBC88, 0xB9F8, 0xBC89, 0x93AC, 0xBC8A, 0x93AD, 0xBC8B, 0xB9F9,
+	0xBC8C, 0xB9FA, 0xBC8D, 0x93AE, 0xBC8E, 0xB9FB, 0xBC8F, 0x93AF,
+	0xBC90, 0x93B0, 0xBC91, 0x93B1, 0xBC92, 0x93B2, 0xBC93, 0x93B3,
+	0xBC94, 0xB9FC, 0xBC95, 0xB9FD, 0xBC96, 0x93B4, 0xBC97, 0xB9FE,
+	0xBC98, 0x93B5, 0xBC99, 0xBAA1, 0xBC9A, 0xBAA2, 0xBC9B, 0x93B6,
+	0xBC9C, 0x93B7, 0xBC9D, 0x93B8, 0xBC9E, 0x93B9, 0xBC9F, 0x93BA,
+	0xBCA0, 0xBAA3, 0xBCA1, 0xBAA4, 0xBCA2, 0x93BB, 0xBCA3, 0x93BC,
+	0xBCA4, 0xBAA5, 0xBCA5, 0x93BD, 0xBCA6, 0x93BE, 0xBCA7, 0xBAA6,
+	0xBCA8, 0xBAA7, 0xBCA9, 0x93BF, 0xBCAA, 0x93C0, 0xBCAB, 0x93C1,
+	0xBCAC, 0x93C2, 0xBCAD, 0x93C3, 0xBCAE, 0x93C4, 0xBCAF, 0x93C5,
+	0xBCB0, 0xBAA8, 0xBCB1, 0xBAA9, 0xBCB2, 0x93C6, 0xBCB3, 0xBAAA,
+	0xBCB4, 0xBAAB, 0xBCB5, 0xBAAC, 0xBCB6, 0x93C7, 0xBCB7, 0x93C8,
+	0xBCB8, 0x93C9, 0xBCB9, 0x93CA, 0xBCBA, 0x93CB, 0xBCBB, 0x93CC,
+	0xBCBC, 0xBAAD, 0xBCBD, 0xBAAE, 0xBCBE, 0x93CD, 0xBCBF, 0x93CE,
+	0xBCC0, 0xBAAF, 0xBCC1, 0x93CF, 0xBCC2, 0x93D0, 0xBCC3, 0x93D1,
+	0xBCC4, 0xBAB0, 0xBCC5, 0x93D2, 0xBCC6, 0x93D3, 0xBCC7, 0x93D4,
+	0xBCC8, 0x93D5, 0xBCC9, 0x93D6, 0xBCCA, 0x93D7, 0xBCCB, 0x93D8,
+	0xBCCC, 0x93D9, 0xBCCD, 0xBAB1, 0xBCCE, 0x93DA, 0xBCCF, 0xBAB2,
+	0xBCD0, 0xBAB3, 0xBCD1, 0xBAB4, 0xBCD2, 0x93DB, 0xBCD3, 0x93DC,
+	0xBCD4, 0x93DD, 0xBCD5, 0xBAB5, 0xBCD6, 0x93DE, 0xBCD7, 0x93DF,
+	0xBCD8, 0xBAB6, 0xBCD9, 0x93E0, 0xBCDA, 0x93E1, 0xBCDB, 0x93E2,
+	0xBCDC, 0xBAB7, 0xBCDD, 0x93E3, 0xBCDE, 0x93E4, 0xBCDF, 0x93E5,
+	0xBCE0, 0x93E6, 0xBCE1, 0x93E7, 0xBCE2, 0x93E8, 0xBCE3, 0x93E9,
+	0xBCE4, 0x93EA, 0xBCE5, 0x93EB, 0xBCE6, 0x93EC, 0xBCE7, 0x93ED,
+	0xBCE8, 0x93EE, 0xBCE9, 0x93EF, 0xBCEA, 0x93F0, 0xBCEB, 0x93F1,
+	0xBCEC, 0x93F2, 0xBCED, 0x93F3, 0xBCEE, 0x93F4, 0xBCEF, 0x93F5,
+	0xBCF0, 0x93F6, 0xBCF1, 0x93F7, 0xBCF2, 0x93F8, 0xBCF3, 0x93F9,
+	0xBCF4, 0xBAB8, 0xBCF5, 0xBAB9, 0xBCF6, 0xBABA, 0xBCF7, 0x93FA,
+	0xBCF8, 0xBABB, 0xBCF9, 0x93FB, 0xBCFA, 0x93FC, 0xBCFB, 0x93FD,
+	0xBCFC, 0xBABC, 0xBCFD, 0x93FE, 0xBCFE, 0x9441, 0xBCFF, 0x9442,
+	0xBD00, 0x9443, 0xBD01, 0x9444, 0xBD02, 0x9445, 0xBD03, 0x9446,
+	0xBD04, 0xBABD, 0xBD05, 0xBABE, 0xBD06, 0x9447, 0xBD07, 0xBABF,
+	0xBD08, 0x9448, 0xBD09, 0xBAC0, 0xBD0A, 0x9449, 0xBD0B, 0x944A,
+	0xBD0C, 0x944B, 0xBD0D, 0x944C, 0xBD0E, 0x944D, 0xBD0F, 0x944E,
+	0xBD10, 0xBAC1, 0xBD11, 0x944F, 0xBD12, 0x9450, 0xBD13, 0x9451,
+	0xBD14, 0xBAC2, 0xBD15, 0x9452, 0xBD16, 0x9453, 0xBD17, 0x9454,
+	0xBD18, 0x9455, 0xBD19, 0x9456, 0xBD1A, 0x9457, 0xBD1B, 0x9458,
+	0xBD1C, 0x9459, 0xBD1D, 0x945A, 0xBD1E, 0x9461, 0xBD1F, 0x9462,
+	0xBD20, 0x9463, 0xBD21, 0x9464, 0xBD22, 0x9465, 0xBD23, 0x9466,
+	0xBD24, 0xBAC3, 0xBD25, 0x9467, 0xBD26, 0x9468, 0xBD27, 0x9469,
+	0xBD28, 0x946A, 0xBD29, 0x946B, 0xBD2A, 0x946C, 0xBD2B, 0x946D,
+	0xBD2C, 0xBAC4, 0xBD2D, 0x946E, 0xBD2E, 0x946F, 0xBD2F, 0x9470,
+	0xBD30, 0x9471, 0xBD31, 0x9472, 0xBD32, 0x9473, 0xBD33, 0x9474,
+	0xBD34, 0x9475, 0xBD35, 0x9476, 0xBD36, 0x9477, 0xBD37, 0x9478,
+	0xBD38, 0x9479, 0xBD39, 0x947A, 0xBD3A, 0x9481, 0xBD3B, 0x9482,
+	0xBD3C, 0x9483, 0xBD3D, 0x9484, 0xBD3E, 0x9485, 0xBD3F, 0x9486,
+	0xBD40, 0xBAC5, 0xBD41, 0x9487, 0xBD42, 0x9488, 0xBD43, 0x9489,
+	0xBD44, 0x948A, 0xBD45, 0x948B, 0xBD46, 0x948C, 0xBD47, 0x948D,
+	0xBD48, 0xBAC6, 0xBD49, 0xBAC7, 0xBD4A, 0x948E, 0xBD4B, 0x948F,
+	0xBD4C, 0xBAC8, 0xBD4D, 0x9490, 0xBD4E, 0x9491, 0xBD4F, 0x9492,
+	0xBD50, 0xBAC9, 0xBD51, 0x9493, 0xBD52, 0x9494, 0xBD53, 0x9495,
+	0xBD54, 0x9496, 0xBD55, 0x9497, 0xBD56, 0x9498, 0xBD57, 0x9499,
+	0xBD58, 0xBACA, 0xBD59, 0xBACB, 0xBD5A, 0x949A, 0xBD5B, 0x949B,
+	0xBD5C, 0x949C, 0xBD5D, 0x949D, 0xBD5E, 0x949E, 0xBD5F, 0x949F,
+	0xBD60, 0x94A0, 0xBD61, 0x94A1, 0xBD62, 0x94A2, 0xBD63, 0x94A3,
+	0xBD64, 0xBACC, 0xBD65, 0x94A4, 0xBD66, 0x94A5, 0xBD67, 0x94A6,
+	0xBD68, 0xBACD, 0xBD69, 0x94A7, 0xBD6A, 0x94A8, 0xBD6B, 0x94A9,
+	0xBD6C, 0x94AA, 0xBD6D, 0x94AB, 0xBD6E, 0x94AC, 0xBD6F, 0x94AD,
+	0xBD70, 0x94AE, 0xBD71, 0x94AF, 0xBD72, 0x94B0, 0xBD73, 0x94B1,
+	0xBD74, 0x94B2, 0xBD75, 0x94B3, 0xBD76, 0x94B4, 0xBD77, 0x94B5,
+	0xBD78, 0x94B6, 0xBD79, 0x94B7, 0xBD7A, 0x94B8, 0xBD7B, 0x94B9,
+	0xBD7C, 0x94BA, 0xBD7D, 0x94BB, 0xBD7E, 0x94BC, 0xBD7F, 0x94BD,
+	0xBD80, 0xBACE, 0xBD81, 0xBACF, 0xBD82, 0x94BE, 0xBD83, 0x94BF,
+	0xBD84, 0xBAD0, 0xBD85, 0x94C0, 0xBD86, 0x94C1, 0xBD87, 0xBAD1,
+	0xBD88, 0xBAD2, 0xBD89, 0xBAD3, 0xBD8A, 0xBAD4, 0xBD8B, 0x94C2,
+	0xBD8C, 0x94C3, 0xBD8D, 0x94C4, 0xBD8E, 0x94C5, 0xBD8F, 0x94C6,
+	0xBD90, 0xBAD5, 0xBD91, 0xBAD6, 0xBD92, 0x94C7, 0xBD93, 0xBAD7,
+	0xBD94, 0x94C8, 0xBD95, 0xBAD8, 0xBD96, 0x94C9, 0xBD97, 0x94CA,
+	0xBD98, 0x94CB, 0xBD99, 0xBAD9, 0xBD9A, 0xBADA, 0xBD9B, 0x94CC,
+	0xBD9C, 0xBADB, 0xBD9D, 0x94CD, 0xBD9E, 0x94CE, 0xBD9F, 0x94CF,
+	0xBDA0, 0x94D0, 0xBDA1, 0x94D1, 0xBDA2, 0x94D2, 0xBDA3, 0x94D3,
+	0xBDA4, 0xBADC, 0xBDA5, 0x94D4, 0xBDA6, 0x94D5, 0xBDA7, 0x94D6,
+	0xBDA8, 0x94D7, 0xBDA9, 0x94D8, 0xBDAA, 0x94D9, 0xBDAB, 0x94DA,
+	0xBDAC, 0x94DB, 0xBDAD, 0x94DC, 0xBDAE, 0x94DD, 0xBDAF, 0x94DE,
+	0xBDB0, 0xBADD, 0xBDB1, 0x94DF, 0xBDB2, 0x94E0, 0xBDB3, 0x94E1,
+	0xBDB4, 0x94E2, 0xBDB5, 0x94E3, 0xBDB6, 0x94E4, 0xBDB7, 0x94E5,
+	0xBDB8, 0xBADE, 0xBDB9, 0x94E6, 0xBDBA, 0x94E7, 0xBDBB, 0x94E8,
+	0xBDBC, 0x94E9, 0xBDBD, 0x94EA, 0xBDBE, 0x94EB, 0xBDBF, 0x94EC,
+	0xBDC0, 0x94ED, 0xBDC1, 0x94EE, 0xBDC2, 0x94EF, 0xBDC3, 0x94F0,
+	0xBDC4, 0x94F1, 0xBDC5, 0x94F2, 0xBDC6, 0x94F3, 0xBDC7, 0x94F4,
+	0xBDC8, 0x94F5, 0xBDC9, 0x94F6, 0xBDCA, 0x94F7, 0xBDCB, 0x94F8,
+	0xBDCC, 0x94F9, 0xBDCD, 0x94FA, 0xBDCE, 0x94FB, 0xBDCF, 0x94FC,
+	0xBDD0, 0x94FD, 0xBDD1, 0x94FE, 0xBDD2, 0x9541, 0xBDD3, 0x9542,
+	0xBDD4, 0xBADF, 0xBDD5, 0xBAE0, 0xBDD6, 0x9543, 0xBDD7, 0x9544,
+	0xBDD8, 0xBAE1, 0xBDD9, 0x9545, 0xBDDA, 0x9546, 0xBDDB, 0x9547,
+	0xBDDC, 0xBAE2, 0xBDDD, 0x9548, 0xBDDE, 0x9549, 0xBDDF, 0x954A,
+	0xBDE0, 0x954B, 0xBDE1, 0x954C, 0xBDE2, 0x954D, 0xBDE3, 0x954E,
+	0xBDE4, 0x954F, 0xBDE5, 0x9550, 0xBDE6, 0x9551, 0xBDE7, 0x9552,
+	0xBDE8, 0x9553, 0xBDE9, 0xBAE3, 0xBDEA, 0x9554, 0xBDEB, 0x9555,
+	0xBDEC, 0x9556, 0xBDED, 0x9557, 0xBDEE, 0x9558, 0xBDEF, 0x9559,
+	0xBDF0, 0xBAE4, 0xBDF1, 0x955A, 0xBDF2, 0x9561, 0xBDF3, 0x9562,
+	0xBDF4, 0xBAE5, 0xBDF5, 0x9563, 0xBDF6, 0x9564, 0xBDF7, 0x9565,
+	0xBDF8, 0xBAE6, 0xBDF9, 0x9566, 0xBDFA, 0x9567, 0xBDFB, 0x9568,
+	0xBDFC, 0x9569, 0xBDFD, 0x956A, 0xBDFE, 0x956B, 0xBDFF, 0x956C,
+	0xBE00, 0xBAE7, 0xBE01, 0x956D, 0xBE02, 0x956E, 0xBE03, 0xBAE8,
+	0xBE04, 0x956F, 0xBE05, 0xBAE9, 0xBE06, 0x9570, 0xBE07, 0x9571,
+	0xBE08, 0x9572, 0xBE09, 0x9573, 0xBE0A, 0x9574, 0xBE0B, 0x9575,
+	0xBE0C, 0xBAEA, 0xBE0D, 0xBAEB, 0xBE0E, 0x9576, 0xBE0F, 0x9577,
+	0xBE10, 0xBAEC, 0xBE11, 0x9578, 0xBE12, 0x9579, 0xBE13, 0x957A,
+	0xBE14, 0xBAED, 0xBE15, 0x9581, 0xBE16, 0x9582, 0xBE17, 0x9583,
+	0xBE18, 0x9584, 0xBE19, 0x9585, 0xBE1A, 0x9586, 0xBE1B, 0x9587,
+	0xBE1C, 0xBAEE, 0xBE1D, 0xBAEF, 0xBE1E, 0x9588, 0xBE1F, 0xBAF0,
+	0xBE20, 0x9589, 0xBE21, 0x958A, 0xBE22, 0x958B, 0xBE23, 0x958C,
+	0xBE24, 0x958D, 0xBE25, 0x958E, 0xBE26, 0x958F, 0xBE27, 0x9590,
+	0xBE28, 0x9591, 0xBE29, 0x9592, 0xBE2A, 0x9593, 0xBE2B, 0x9594,
+	0xBE2C, 0x9595, 0xBE2D, 0x9596, 0xBE2E, 0x9597, 0xBE2F, 0x9598,
+	0xBE30, 0x9599, 0xBE31, 0x959A, 0xBE32, 0x959B, 0xBE33, 0x959C,
+	0xBE34, 0x959D, 0xBE35, 0x959E, 0xBE36, 0x959F, 0xBE37, 0x95A0,
+	0xBE38, 0x95A1, 0xBE39, 0x95A2, 0xBE3A, 0x95A3, 0xBE3B, 0x95A4,
+	0xBE3C, 0x95A5, 0xBE3D, 0x95A6, 0xBE3E, 0x95A7, 0xBE3F, 0x95A8,
+	0xBE40, 0x95A9, 0xBE41, 0x95AA, 0xBE42, 0x95AB, 0xBE43, 0x95AC,
+	0xBE44, 0xBAF1, 0xBE45, 0xBAF2, 0xBE46, 0x95AD, 0xBE47, 0x95AE,
+	0xBE48, 0xBAF3, 0xBE49, 0x95AF, 0xBE4A, 0x95B0, 0xBE4B, 0x95B1,
+	0xBE4C, 0xBAF4, 0xBE4D, 0x95B2, 0xBE4E, 0xBAF5, 0xBE4F, 0x95B3,
+	0xBE50, 0x95B4, 0xBE51, 0x95B5, 0xBE52, 0x95B6, 0xBE53, 0x95B7,
+	0xBE54, 0xBAF6, 0xBE55, 0xBAF7, 0xBE56, 0x95B8, 0xBE57, 0xBAF8,
+	0xBE58, 0x95B9, 0xBE59, 0xBAF9, 0xBE5A, 0xBAFA, 0xBE5B, 0xBAFB,
+	0xBE5C, 0x95BA, 0xBE5D, 0x95BB, 0xBE5E, 0x95BC, 0xBE5F, 0x95BD,
+	0xBE60, 0xBAFC, 0xBE61, 0xBAFD, 0xBE62, 0x95BE, 0xBE63, 0x95BF,
+	0xBE64, 0xBAFE, 0xBE65, 0x95C0, 0xBE66, 0x95C1, 0xBE67, 0x95C2,
+	0xBE68, 0xBBA1, 0xBE69, 0x95C3, 0xBE6A, 0xBBA2, 0xBE6B, 0x95C4,
+	0xBE6C, 0x95C5, 0xBE6D, 0x95C6, 0xBE6E, 0x95C7, 0xBE6F, 0x95C8,
+	0xBE70, 0xBBA3, 0xBE71, 0xBBA4, 0xBE72, 0x95C9, 0xBE73, 0xBBA5,
+	0xBE74, 0xBBA6, 0xBE75, 0xBBA7, 0xBE76, 0x95CA, 0xBE77, 0x95CB,
+	0xBE78, 0x95CC, 0xBE79, 0x95CD, 0xBE7A, 0x95CE, 0xBE7B, 0xBBA8,
+	0xBE7C, 0xBBA9, 0xBE7D, 0xBBAA, 0xBE7E, 0x95CF, 0xBE7F, 0x95D0,
+	0xBE80, 0xBBAB, 0xBE81, 0x95D1, 0xBE82, 0x95D2, 0xBE83, 0x95D3,
+	0xBE84, 0xBBAC, 0xBE85, 0x95D4, 0xBE86, 0x95D5, 0xBE87, 0x95D6,
+	0xBE88, 0x95D7, 0xBE89, 0x95D8, 0xBE8A, 0x95D9, 0xBE8B, 0x95DA,
+	0xBE8C, 0xBBAD, 0xBE8D, 0xBBAE, 0xBE8E, 0x95DB, 0xBE8F, 0xBBAF,
+	0xBE90, 0xBBB0, 0xBE91, 0xBBB1, 0xBE92, 0x95DC, 0xBE93, 0x95DD,
+	0xBE94, 0x95DE, 0xBE95, 0x95DF, 0xBE96, 0x95E0, 0xBE97, 0x95E1,
+	0xBE98, 0xBBB2, 0xBE99, 0xBBB3, 0xBE9A, 0x95E2, 0xBE9B, 0x95E3,
+	0xBE9C, 0x95E4, 0xBE9D, 0x95E5, 0xBE9E, 0x95E6, 0xBE9F, 0x95E7,
+	0xBEA0, 0x95E8, 0xBEA1, 0x95E9, 0xBEA2, 0x95EA, 0xBEA3, 0x95EB,
+	0xBEA4, 0x95EC, 0xBEA5, 0x95ED, 0xBEA6, 0x95EE, 0xBEA7, 0x95EF,
+	0xBEA8, 0xBBB4, 0xBEA9, 0x95F0, 0xBEAA, 0x95F1, 0xBEAB, 0x95F2,
+	0xBEAC, 0x95F3, 0xBEAD, 0x95F4, 0xBEAE, 0x95F5, 0xBEAF, 0x95F6,
+	0xBEB0, 0x95F7, 0xBEB1, 0x95F8, 0xBEB2, 0x95F9, 0xBEB3, 0x95FA,
+	0xBEB4, 0x95FB, 0xBEB5, 0x95FC, 0xBEB6, 0x95FD, 0xBEB7, 0x95FE,
+	0xBEB8, 0x9641, 0xBEB9, 0x9642, 0xBEBA, 0x9643, 0xBEBB, 0x9644,
+	0xBEBC, 0x9645, 0xBEBD, 0x9646, 0xBEBE, 0x9647, 0xBEBF, 0x9648,
+	0xBEC0, 0x9649, 0xBEC1, 0x964A, 0xBEC2, 0x964B, 0xBEC3, 0x964C,
+	0xBEC4, 0x964D, 0xBEC5, 0x964E, 0xBEC6, 0x964F, 0xBEC7, 0x9650,
+	0xBEC8, 0x9651, 0xBEC9, 0x9652, 0xBECA, 0x9653, 0xBECB, 0x9654,
+	0xBECC, 0x9655, 0xBECD, 0x9656, 0xBECE, 0x9657, 0xBECF, 0x9658,
+	0xBED0, 0xBBB5, 0xBED1, 0xBBB6, 0xBED2, 0x9659, 0xBED3, 0x965A,
+	0xBED4, 0xBBB7, 0xBED5, 0x9661, 0xBED6, 0x9662, 0xBED7, 0xBBB8,
+	0xBED8, 0xBBB9, 0xBED9, 0x9663, 0xBEDA, 0x9664, 0xBEDB, 0x9665,
+	0xBEDC, 0x9666, 0xBEDD, 0x9667, 0xBEDE, 0x9668, 0xBEDF, 0x9669,
+	0xBEE0, 0xBBBA, 0xBEE1, 0x966A, 0xBEE2, 0x966B, 0xBEE3, 0xBBBB,
+	0xBEE4, 0xBBBC, 0xBEE5, 0xBBBD, 0xBEE6, 0x966C, 0xBEE7, 0x966D,
+	0xBEE8, 0x966E, 0xBEE9, 0x966F, 0xBEEA, 0x9670, 0xBEEB, 0x9671,
+	0xBEEC, 0xBBBE, 0xBEED, 0x9672, 0xBEEE, 0x9673, 0xBEEF, 0x9674,
+	0xBEF0, 0x9675, 0xBEF1, 0x9676, 0xBEF2, 0x9677, 0xBEF3, 0x9678,
+	0xBEF4, 0x9679, 0xBEF5, 0x967A, 0xBEF6, 0x9681, 0xBEF7, 0x9682,
+	0xBEF8, 0x9683, 0xBEF9, 0x9684, 0xBEFA, 0x9685, 0xBEFB, 0x9686,
+	0xBEFC, 0x9687, 0xBEFD, 0x9688, 0xBEFE, 0x9689, 0xBEFF, 0x968A,
+	0xBF00, 0x968B, 0xBF01, 0xBBBF, 0xBF02, 0x968C, 0xBF03, 0x968D,
+	0xBF04, 0x968E, 0xBF05, 0x968F, 0xBF06, 0x9690, 0xBF07, 0x9691,
+	0xBF08, 0xBBC0, 0xBF09, 0xBBC1, 0xBF0A, 0x9692, 0xBF0B, 0x9693,
+	0xBF0C, 0x9694, 0xBF0D, 0x9695, 0xBF0E, 0x9696, 0xBF0F, 0x9697,
+	0xBF10, 0x9698, 0xBF11, 0x9699, 0xBF12, 0x969A, 0xBF13, 0x969B,
+	0xBF14, 0x969C, 0xBF15, 0x969D, 0xBF16, 0x969E, 0xBF17, 0x969F,
+	0xBF18, 0xBBC2, 0xBF19, 0xBBC3, 0xBF1A, 0x96A0, 0xBF1B, 0xBBC4,
+	0xBF1C, 0xBBC5, 0xBF1D, 0xBBC6, 0xBF1E, 0x96A1, 0xBF1F, 0x96A2,
+	0xBF20, 0x96A3, 0xBF21, 0x96A4, 0xBF22, 0x96A5, 0xBF23, 0x96A6,
+	0xBF24, 0x96A7, 0xBF25, 0x96A8, 0xBF26, 0x96A9, 0xBF27, 0x96AA,
+	0xBF28, 0x96AB, 0xBF29, 0x96AC, 0xBF2A, 0x96AD, 0xBF2B, 0x96AE,
+	0xBF2C, 0x96AF, 0xBF2D, 0x96B0, 0xBF2E, 0x96B1, 0xBF2F, 0x96B2,
+	0xBF30, 0x96B3, 0xBF31, 0x96B4, 0xBF32, 0x96B5, 0xBF33, 0x96B6,
+	0xBF34, 0x96B7, 0xBF35, 0x96B8, 0xBF36, 0x96B9, 0xBF37, 0x96BA,
+	0xBF38, 0x96BB, 0xBF39, 0x96BC, 0xBF3A, 0x96BD, 0xBF3B, 0x96BE,
+	0xBF3C, 0x96BF, 0xBF3D, 0x96C0, 0xBF3E, 0x96C1, 0xBF3F, 0x96C2,
+	0xBF40, 0xBBC7, 0xBF41, 0xBBC8, 0xBF42, 0x96C3, 0xBF43, 0x96C4,
+	0xBF44, 0xBBC9, 0xBF45, 0x96C5, 0xBF46, 0x96C6, 0xBF47, 0x96C7,
+	0xBF48, 0xBBCA, 0xBF49, 0x96C8, 0xBF4A, 0x96C9, 0xBF4B, 0x96CA,
+	0xBF4C, 0x96CB, 0xBF4D, 0x96CC, 0xBF4E, 0x96CD, 0xBF4F, 0x96CE,
+	0xBF50, 0xBBCB, 0xBF51, 0xBBCC, 0xBF52, 0x96CF, 0xBF53, 0x96D0,
+	0xBF54, 0x96D1, 0xBF55, 0xBBCD, 0xBF56, 0x96D2, 0xBF57, 0x96D3,
+	0xBF58, 0x96D4, 0xBF59, 0x96D5, 0xBF5A, 0x96D6, 0xBF5B, 0x96D7,
+	0xBF5C, 0x96D8, 0xBF5D, 0x96D9, 0xBF5E, 0x96DA, 0xBF5F, 0x96DB,
+	0xBF60, 0x96DC, 0xBF61, 0x96DD, 0xBF62, 0x96DE, 0xBF63, 0x96DF,
+	0xBF64, 0x96E0, 0xBF65, 0x96E1, 0xBF66, 0x96E2, 0xBF67, 0x96E3,
+	0xBF68, 0x96E4, 0xBF69, 0x96E5, 0xBF6A, 0x96E6, 0xBF6B, 0x96E7,
+	0xBF6C, 0x96E8, 0xBF6D, 0x96E9, 0xBF6E, 0x96EA, 0xBF6F, 0x96EB,
+	0xBF70, 0x96EC, 0xBF71, 0x96ED, 0xBF72, 0x96EE, 0xBF73, 0x96EF,
+	0xBF74, 0x96F0, 0xBF75, 0x96F1, 0xBF76, 0x96F2, 0xBF77, 0x96F3,
+	0xBF78, 0x96F4, 0xBF79, 0x96F5, 0xBF7A, 0x96F6, 0xBF7B, 0x96F7,
+	0xBF7C, 0x96F8, 0xBF7D, 0x96F9, 0xBF7E, 0x96FA, 0xBF7F, 0x96FB,
+	0xBF80, 0x96FC, 0xBF81, 0x96FD, 0xBF82, 0x96FE, 0xBF83, 0x9741,
+	0xBF84, 0x9742, 0xBF85, 0x9743, 0xBF86, 0x9744, 0xBF87, 0x9745,
+	0xBF88, 0x9746, 0xBF89, 0x9747, 0xBF8A, 0x9748, 0xBF8B, 0x9749,
+	0xBF8C, 0x974A, 0xBF8D, 0x974B, 0xBF8E, 0x974C, 0xBF8F, 0x974D,
+	0xBF90, 0x974E, 0xBF91, 0x974F, 0xBF92, 0x9750, 0xBF93, 0x9751,
+	0xBF94, 0xBBCE, 0xBF95, 0x9752, 0xBF96, 0x9753, 0xBF97, 0x9754,
+	0xBF98, 0x9755, 0xBF99, 0x9756, 0xBF9A, 0x9757, 0xBF9B, 0x9758,
+	0xBF9C, 0x9759, 0xBF9D, 0x975A, 0xBF9E, 0x9761, 0xBF9F, 0x9762,
+	0xBFA0, 0x9763, 0xBFA1, 0x9764, 0xBFA2, 0x9765, 0xBFA3, 0x9766,
+	0xBFA4, 0x9767, 0xBFA5, 0x9768, 0xBFA6, 0x9769, 0xBFA7, 0x976A,
+	0xBFA8, 0x976B, 0xBFA9, 0x976C, 0xBFAA, 0x976D, 0xBFAB, 0x976E,
+	0xBFAC, 0x976F, 0xBFAD, 0x9770, 0xBFAE, 0x9771, 0xBFAF, 0x9772,
+	0xBFB0, 0xBBCF, 0xBFB1, 0x9773, 0xBFB2, 0x9774, 0xBFB3, 0x9775,
+	0xBFB4, 0x9776, 0xBFB5, 0x9777, 0xBFB6, 0x9778, 0xBFB7, 0x9779,
+	0xBFB8, 0x977A, 0xBFB9, 0x9781, 0xBFBA, 0x9782, 0xBFBB, 0x9783,
+	0xBFBC, 0x9784, 0xBFBD, 0x9785, 0xBFBE, 0x9786, 0xBFBF, 0x9787,
+	0xBFC0, 0x9788, 0xBFC1, 0x9789, 0xBFC2, 0x978A, 0xBFC3, 0x978B,
+	0xBFC4, 0x978C, 0xBFC5, 0xBBD0, 0xBFC6, 0x978D, 0xBFC7, 0x978E,
+	0xBFC8, 0x978F, 0xBFC9, 0x9790, 0xBFCA, 0x9791, 0xBFCB, 0x9792,
+	0xBFCC, 0xBBD1, 0xBFCD, 0xBBD2, 0xBFCE, 0x9793, 0xBFCF, 0x9794,
+	0xBFD0, 0xBBD3, 0xBFD1, 0x9795, 0xBFD2, 0x9796, 0xBFD3, 0x9797,
+	0xBFD4, 0xBBD4, 0xBFD5, 0x9798, 0xBFD6, 0x9799, 0xBFD7, 0x979A,
+	0xBFD8, 0x979B, 0xBFD9, 0x979C, 0xBFDA, 0x979D, 0xBFDB, 0x979E,
+	0xBFDC, 0xBBD5, 0xBFDD, 0x979F, 0xBFDE, 0x97A0, 0xBFDF, 0xBBD6,
+	0xBFE0, 0x97A1, 0xBFE1, 0xBBD7, 0xBFE2, 0x97A2, 0xBFE3, 0x97A3,
+	0xBFE4, 0x97A4, 0xBFE5, 0x97A5, 0xBFE6, 0x97A6, 0xBFE7, 0x97A7,
+	0xBFE8, 0x97A8, 0xBFE9, 0x97A9, 0xBFEA, 0x97AA, 0xBFEB, 0x97AB,
+	0xBFEC, 0x97AC, 0xBFED, 0x97AD, 0xBFEE, 0x97AE, 0xBFEF, 0x97AF,
+	0xBFF0, 0x97B0, 0xBFF1, 0x97B1, 0xBFF2, 0x97B2, 0xBFF3, 0x97B3,
+	0xBFF4, 0x97B4, 0xBFF5, 0x97B5, 0xBFF6, 0x97B6, 0xBFF7, 0x97B7,
+	0xBFF8, 0x97B8, 0xBFF9, 0x97B9, 0xBFFA, 0x97BA, 0xBFFB, 0x97BB,
+	0xBFFC, 0x97BC, 0xBFFD, 0x97BD, 0xBFFE, 0x97BE, 0xBFFF, 0x97BF,
+	0xC000, 0x97C0, 0xC001, 0x97C1, 0xC002, 0x97C2, 0xC003, 0x97C3,
+	0xC004, 0x97C4, 0xC005, 0x97C5, 0xC006, 0x97C6, 0xC007, 0x97C7,
+	0xC008, 0x97C8, 0xC009, 0x97C9, 0xC00A, 0x97CA, 0xC00B, 0x97CB,
+	0xC00C, 0x97CC, 0xC00D, 0x97CD, 0xC00E, 0x97CE, 0xC00F, 0x97CF,
+	0xC010, 0x97D0, 0xC011, 0x97D1, 0xC012, 0x97D2, 0xC013, 0x97D3,
+	0xC014, 0x97D4, 0xC015, 0x97D5, 0xC016, 0x97D6, 0xC017, 0x97D7,
+	0xC018, 0x97D8, 0xC019, 0x97D9, 0xC01A, 0x97DA, 0xC01B, 0x97DB,
+	0xC01C, 0x97DC, 0xC01D, 0x97DD, 0xC01E, 0x97DE, 0xC01F, 0x97DF,
+	0xC020, 0x97E0, 0xC021, 0x97E1, 0xC022, 0x97E2, 0xC023, 0x97E3,
+	0xC024, 0x97E4, 0xC025, 0x97E5, 0xC026, 0x97E6, 0xC027, 0x97E7,
+	0xC028, 0x97E8, 0xC029, 0x97E9, 0xC02A, 0x97EA, 0xC02B, 0x97EB,
+	0xC02C, 0x97EC, 0xC02D, 0x97ED, 0xC02E, 0x97EE, 0xC02F, 0x97EF,
+	0xC030, 0x97F0, 0xC031, 0x97F1, 0xC032, 0x97F2, 0xC033, 0x97F3,
+	0xC034, 0x97F4, 0xC035, 0x97F5, 0xC036, 0x97F6, 0xC037, 0x97F7,
+	0xC038, 0x97F8, 0xC039, 0x97F9, 0xC03A, 0x97FA, 0xC03B, 0x97FB,
+	0xC03C, 0xBBD8, 0xC03D, 0x97FC, 0xC03E, 0x97FD, 0xC03F, 0x97FE,
+	0xC040, 0x9841, 0xC041, 0x9842, 0xC042, 0x9843, 0xC043, 0x9844,
+	0xC044, 0x9845, 0xC045, 0x9846, 0xC046, 0x9847, 0xC047, 0x9848,
+	0xC048, 0x9849, 0xC049, 0x984A, 0xC04A, 0x984B, 0xC04B, 0x984C,
+	0xC04C, 0x984D, 0xC04D, 0x984E, 0xC04E, 0x984F, 0xC04F, 0x9850,
+	0xC050, 0x9851, 0xC051, 0xBBD9, 0xC052, 0x9852, 0xC053, 0x9853,
+	0xC054, 0x9854, 0xC055, 0x9855, 0xC056, 0x9856, 0xC057, 0x9857,
+	0xC058, 0xBBDA, 0xC059, 0x9858, 0xC05A, 0x9859, 0xC05B, 0x985A,
+	0xC05C, 0xBBDB, 0xC05D, 0x9861, 0xC05E, 0x9862, 0xC05F, 0x9863,
+	0xC060, 0xBBDC, 0xC061, 0x9864, 0xC062, 0x9865, 0xC063, 0x9866,
+	0xC064, 0x9867, 0xC065, 0x9868, 0xC066, 0x9869, 0xC067, 0x986A,
+	0xC068, 0xBBDD, 0xC069, 0xBBDE, 0xC06A, 0x986B, 0xC06B, 0x986C,
+	0xC06C, 0x986D, 0xC06D, 0x986E, 0xC06E, 0x986F, 0xC06F, 0x9870,
+	0xC070, 0x9871, 0xC071, 0x9872, 0xC072, 0x9873, 0xC073, 0x9874,
+	0xC074, 0x9875, 0xC075, 0x9876, 0xC076, 0x9877, 0xC077, 0x9878,
+	0xC078, 0x9879, 0xC079, 0x987A, 0xC07A, 0x9881, 0xC07B, 0x9882,
+	0xC07C, 0x9883, 0xC07D, 0x9884, 0xC07E, 0x9885, 0xC07F, 0x9886,
+	0xC080, 0x9887, 0xC081, 0x9888, 0xC082, 0x9889, 0xC083, 0x988A,
+	0xC084, 0x988B, 0xC085, 0x988C, 0xC086, 0x988D, 0xC087, 0x988E,
+	0xC088, 0x988F, 0xC089, 0x9890, 0xC08A, 0x9891, 0xC08B, 0x9892,
+	0xC08C, 0x9893, 0xC08D, 0x9894, 0xC08E, 0x9895, 0xC08F, 0x9896,
+	0xC090, 0xBBDF, 0xC091, 0xBBE0, 0xC092, 0x9897, 0xC093, 0x9898,
+	0xC094, 0xBBE1, 0xC095, 0x9899, 0xC096, 0x989A, 0xC097, 0x989B,
+	0xC098, 0xBBE2, 0xC099, 0x989C, 0xC09A, 0x989D, 0xC09B, 0x989E,
+	0xC09C, 0x989F, 0xC09D, 0x98A0, 0xC09E, 0x98A1, 0xC09F, 0x98A2,
+	0xC0A0, 0xBBE3, 0xC0A1, 0xBBE4, 0xC0A2, 0x98A3, 0xC0A3, 0xBBE5,
+	0xC0A4, 0x98A4, 0xC0A5, 0xBBE6, 0xC0A6, 0x98A5, 0xC0A7, 0x98A6,
+	0xC0A8, 0x98A7, 0xC0A9, 0x98A8, 0xC0AA, 0x98A9, 0xC0AB, 0x98AA,
+	0xC0AC, 0xBBE7, 0xC0AD, 0xBBE8, 0xC0AE, 0x98AB, 0xC0AF, 0xBBE9,
+	0xC0B0, 0xBBEA, 0xC0B1, 0x98AC, 0xC0B2, 0x98AD, 0xC0B3, 0xBBEB,
+	0xC0B4, 0xBBEC, 0xC0B5, 0xBBED, 0xC0B6, 0xBBEE, 0xC0B7, 0x98AE,
+	0xC0B8, 0x98AF, 0xC0B9, 0x98B0, 0xC0BA, 0x98B1, 0xC0BB, 0x98B2,
+	0xC0BC, 0xBBEF, 0xC0BD, 0xBBF0, 0xC0BE, 0x98B3, 0xC0BF, 0xBBF1,
+	0xC0C0, 0xBBF2, 0xC0C1, 0xBBF3, 0xC0C2, 0x98B4, 0xC0C3, 0x98B5,
+	0xC0C4, 0x98B6, 0xC0C5, 0xBBF4, 0xC0C6, 0x98B7, 0xC0C7, 0x98B8,
+	0xC0C8, 0xBBF5, 0xC0C9, 0xBBF6, 0xC0CA, 0x98B9, 0xC0CB, 0x98BA,
+	0xC0CC, 0xBBF7, 0xC0CD, 0x98BB, 0xC0CE, 0x98BC, 0xC0CF, 0x98BD,
+	0xC0D0, 0xBBF8, 0xC0D1, 0x98BE, 0xC0D2, 0x98BF, 0xC0D3, 0x98C0,
+	0xC0D4, 0x98C1, 0xC0D5, 0x98C2, 0xC0D6, 0x98C3, 0xC0D7, 0x98C4,
+	0xC0D8, 0xBBF9, 0xC0D9, 0xBBFA, 0xC0DA, 0x98C5, 0xC0DB, 0xBBFB,
+	0xC0DC, 0xBBFC, 0xC0DD, 0xBBFD, 0xC0DE, 0x98C6, 0xC0DF, 0x98C7,
+	0xC0E0, 0x98C8, 0xC0E1, 0x98C9, 0xC0E2, 0x98CA, 0xC0E3, 0x98CB,
+	0xC0E4, 0xBBFE, 0xC0E5, 0xBCA1, 0xC0E6, 0x98CC, 0xC0E7, 0x98CD,
+	0xC0E8, 0xBCA2, 0xC0E9, 0x98CE, 0xC0EA, 0x98CF, 0xC0EB, 0x98D0,
+	0xC0EC, 0xBCA3, 0xC0ED, 0x98D1, 0xC0EE, 0x98D2, 0xC0EF, 0x98D3,
+	0xC0F0, 0x98D4, 0xC0F1, 0x98D5, 0xC0F2, 0x98D6, 0xC0F3, 0x98D7,
+	0xC0F4, 0xBCA4, 0xC0F5, 0xBCA5, 0xC0F6, 0x98D8, 0xC0F7, 0xBCA6,
+	0xC0F8, 0x98D9, 0xC0F9, 0xBCA7, 0xC0FA, 0x98DA, 0xC0FB, 0x98DB,
+	0xC0FC, 0x98DC, 0xC0FD, 0x98DD, 0xC0FE, 0x98DE, 0xC0FF, 0x98DF,
+	0xC100, 0xBCA8, 0xC101, 0x98E0, 0xC102, 0x98E1, 0xC103, 0x98E2,
+	0xC104, 0xBCA9, 0xC105, 0x98E3, 0xC106, 0x98E4, 0xC107, 0x98E5,
+	0xC108, 0xBCAA, 0xC109, 0x98E6, 0xC10A, 0x98E7, 0xC10B, 0x98E8,
+	0xC10C, 0x98E9, 0xC10D, 0x98EA, 0xC10E, 0x98EB, 0xC10F, 0x98EC,
+	0xC110, 0xBCAB, 0xC111, 0x98ED, 0xC112, 0x98EE, 0xC113, 0x98EF,
+	0xC114, 0x98F0, 0xC115, 0xBCAC, 0xC116, 0x98F1, 0xC117, 0x98F2,
+	0xC118, 0x98F3, 0xC119, 0x98F4, 0xC11A, 0x98F5, 0xC11B, 0x98F6,
+	0xC11C, 0xBCAD, 0xC11D, 0xBCAE, 0xC11E, 0xBCAF, 0xC11F, 0xBCB0,
+	0xC120, 0xBCB1, 0xC121, 0x98F7, 0xC122, 0x98F8, 0xC123, 0xBCB2,
+	0xC124, 0xBCB3, 0xC125, 0x98F9, 0xC126, 0xBCB4, 0xC127, 0xBCB5,
+	0xC128, 0x98FA, 0xC129, 0x98FB, 0xC12A, 0x98FC, 0xC12B, 0x98FD,
+	0xC12C, 0xBCB6, 0xC12D, 0xBCB7, 0xC12E, 0x98FE, 0xC12F, 0xBCB8,
+	0xC130, 0xBCB9, 0xC131, 0xBCBA, 0xC132, 0x9941, 0xC133, 0x9942,
+	0xC134, 0x9943, 0xC135, 0x9944, 0xC136, 0xBCBB, 0xC137, 0x9945,
+	0xC138, 0xBCBC, 0xC139, 0xBCBD, 0xC13A, 0x9946, 0xC13B, 0x9947,
+	0xC13C, 0xBCBE, 0xC13D, 0x9948, 0xC13E, 0x9949, 0xC13F, 0x994A,
+	0xC140, 0xBCBF, 0xC141, 0x994B, 0xC142, 0x994C, 0xC143, 0x994D,
+	0xC144, 0x994E, 0xC145, 0x994F, 0xC146, 0x9950, 0xC147, 0x9951,
+	0xC148, 0xBCC0, 0xC149, 0xBCC1, 0xC14A, 0x9952, 0xC14B, 0xBCC2,
+	0xC14C, 0xBCC3, 0xC14D, 0xBCC4, 0xC14E, 0x9953, 0xC14F, 0x9954,
+	0xC150, 0x9955, 0xC151, 0x9956, 0xC152, 0x9957, 0xC153, 0x9958,
+	0xC154, 0xBCC5, 0xC155, 0xBCC6, 0xC156, 0x9959, 0xC157, 0x995A,
+	0xC158, 0xBCC7, 0xC159, 0x9961, 0xC15A, 0x9962, 0xC15B, 0x9963,
+	0xC15C, 0xBCC8, 0xC15D, 0x9964, 0xC15E, 0x9965, 0xC15F, 0x9966,
+	0xC160, 0x9967, 0xC161, 0x9968, 0xC162, 0x9969, 0xC163, 0x996A,
+	0xC164, 0xBCC9, 0xC165, 0xBCCA, 0xC166, 0x996B, 0xC167, 0xBCCB,
+	0xC168, 0xBCCC, 0xC169, 0xBCCD, 0xC16A, 0x996C, 0xC16B, 0x996D,
+	0xC16C, 0x996E, 0xC16D, 0x996F, 0xC16E, 0x9970, 0xC16F, 0x9971,
+	0xC170, 0xBCCE, 0xC171, 0x9972, 0xC172, 0x9973, 0xC173, 0x9974,
+	0xC174, 0xBCCF, 0xC175, 0x9975, 0xC176, 0x9976, 0xC177, 0x9977,
+	0xC178, 0xBCD0, 0xC179, 0x9978, 0xC17A, 0x9979, 0xC17B, 0x997A,
+	0xC17C, 0x9981, 0xC17D, 0x9982, 0xC17E, 0x9983, 0xC17F, 0x9984,
+	0xC180, 0x9985, 0xC181, 0x9986, 0xC182, 0x9987, 0xC183, 0x9988,
+	0xC184, 0x9989, 0xC185, 0xBCD1, 0xC186, 0x998A, 0xC187, 0x998B,
+	0xC188, 0x998C, 0xC189, 0x998D, 0xC18A, 0x998E, 0xC18B, 0x998F,
+	0xC18C, 0xBCD2, 0xC18D, 0xBCD3, 0xC18E, 0xBCD4, 0xC18F, 0x9990,
+	0xC190, 0xBCD5, 0xC191, 0x9991, 0xC192, 0x9992, 0xC193, 0x9993,
+	0xC194, 0xBCD6, 0xC195, 0x9994, 0xC196, 0xBCD7, 0xC197, 0x9995,
+	0xC198, 0x9996, 0xC199, 0x9997, 0xC19A, 0x9998, 0xC19B, 0x9999,
+	0xC19C, 0xBCD8, 0xC19D, 0xBCD9, 0xC19E, 0x999A, 0xC19F, 0xBCDA,
+	0xC1A0, 0x999B, 0xC1A1, 0xBCDB, 0xC1A2, 0x999C, 0xC1A3, 0x999D,
+	0xC1A4, 0x999E, 0xC1A5, 0xBCDC, 0xC1A6, 0x999F, 0xC1A7, 0x99A0,
+	0xC1A8, 0xBCDD, 0xC1A9, 0xBCDE, 0xC1AA, 0x99A1, 0xC1AB, 0x99A2,
+	0xC1AC, 0xBCDF, 0xC1AD, 0x99A3, 0xC1AE, 0x99A4, 0xC1AF, 0x99A5,
+	0xC1B0, 0xBCE0, 0xC1B1, 0x99A6, 0xC1B2, 0x99A7, 0xC1B3, 0x99A8,
+	0xC1B4, 0x99A9, 0xC1B5, 0x99AA, 0xC1B6, 0x99AB, 0xC1B7, 0x99AC,
+	0xC1B8, 0x99AD, 0xC1B9, 0x99AE, 0xC1BA, 0x99AF, 0xC1BB, 0x99B0,
+	0xC1BC, 0x99B1, 0xC1BD, 0xBCE1, 0xC1BE, 0x99B2, 0xC1BF, 0x99B3,
+	0xC1C0, 0x99B4, 0xC1C1, 0x99B5, 0xC1C2, 0x99B6, 0xC1C3, 0x99B7,
+	0xC1C4, 0xBCE2, 0xC1C5, 0x99B8, 0xC1C6, 0x99B9, 0xC1C7, 0x99BA,
+	0xC1C8, 0xBCE3, 0xC1C9, 0x99BB, 0xC1CA, 0x99BC, 0xC1CB, 0x99BD,
+	0xC1CC, 0xBCE4, 0xC1CD, 0x99BE, 0xC1CE, 0x99BF, 0xC1CF, 0x99C0,
+	0xC1D0, 0x99C1, 0xC1D1, 0x99C2, 0xC1D2, 0x99C3, 0xC1D3, 0x99C4,
+	0xC1D4, 0xBCE5, 0xC1D5, 0x99C5, 0xC1D6, 0x99C6, 0xC1D7, 0xBCE6,
+	0xC1D8, 0xBCE7, 0xC1D9, 0x99C7, 0xC1DA, 0x99C8, 0xC1DB, 0x99C9,
+	0xC1DC, 0x99CA, 0xC1DD, 0x99CB, 0xC1DE, 0x99CC, 0xC1DF, 0x99CD,
+	0xC1E0, 0xBCE8, 0xC1E1, 0x99CE, 0xC1E2, 0x99CF, 0xC1E3, 0x99D0,
+	0xC1E4, 0xBCE9, 0xC1E5, 0x99D1, 0xC1E6, 0x99D2, 0xC1E7, 0x99D3,
+	0xC1E8, 0xBCEA, 0xC1E9, 0x99D4, 0xC1EA, 0x99D5, 0xC1EB, 0x99D6,
+	0xC1EC, 0x99D7, 0xC1ED, 0x99D8, 0xC1EE, 0x99D9, 0xC1EF, 0x99DA,
+	0xC1F0, 0xBCEB, 0xC1F1, 0xBCEC, 0xC1F2, 0x99DB, 0xC1F3, 0xBCED,
+	0xC1F4, 0x99DC, 0xC1F5, 0x99DD, 0xC1F6, 0x99DE, 0xC1F7, 0x99DF,
+	0xC1F8, 0x99E0, 0xC1F9, 0x99E1, 0xC1FA, 0x99E2, 0xC1FB, 0x99E3,
+	0xC1FC, 0xBCEE, 0xC1FD, 0xBCEF, 0xC1FE, 0x99E4, 0xC1FF, 0x99E5,
+	0xC200, 0xBCF0, 0xC201, 0x99E6, 0xC202, 0x99E7, 0xC203, 0x99E8,
+	0xC204, 0xBCF1, 0xC205, 0x99E9, 0xC206, 0x99EA, 0xC207, 0x99EB,
+	0xC208, 0x99EC, 0xC209, 0x99ED, 0xC20A, 0x99EE, 0xC20B, 0x99EF,
+	0xC20C, 0xBCF2, 0xC20D, 0xBCF3, 0xC20E, 0x99F0, 0xC20F, 0xBCF4,
+	0xC210, 0x99F1, 0xC211, 0xBCF5, 0xC212, 0x99F2, 0xC213, 0x99F3,
+	0xC214, 0x99F4, 0xC215, 0x99F5, 0xC216, 0x99F6, 0xC217, 0x99F7,
+	0xC218, 0xBCF6, 0xC219, 0xBCF7, 0xC21A, 0x99F8, 0xC21B, 0x99F9,
+	0xC21C, 0xBCF8, 0xC21D, 0x99FA, 0xC21E, 0x99FB, 0xC21F, 0xBCF9,
+	0xC220, 0xBCFA, 0xC221, 0x99FC, 0xC222, 0x99FD, 0xC223, 0x99FE,
+	0xC224, 0x9A41, 0xC225, 0x9A42, 0xC226, 0x9A43, 0xC227, 0x9A44,
+	0xC228, 0xBCFB, 0xC229, 0xBCFC, 0xC22A, 0x9A45, 0xC22B, 0xBCFD,
+	0xC22C, 0x9A46, 0xC22D, 0xBCFE, 0xC22E, 0x9A47, 0xC22F, 0xBDA1,
+	0xC230, 0x9A48, 0xC231, 0xBDA2, 0xC232, 0xBDA3, 0xC233, 0x9A49,
+	0xC234, 0xBDA4, 0xC235, 0x9A4A, 0xC236, 0x9A4B, 0xC237, 0x9A4C,
+	0xC238, 0x9A4D, 0xC239, 0x9A4E, 0xC23A, 0x9A4F, 0xC23B, 0x9A50,
+	0xC23C, 0x9A51, 0xC23D, 0x9A52, 0xC23E, 0x9A53, 0xC23F, 0x9A54,
+	0xC240, 0x9A55, 0xC241, 0x9A56, 0xC242, 0x9A57, 0xC243, 0x9A58,
+	0xC244, 0x9A59, 0xC245, 0x9A5A, 0xC246, 0x9A61, 0xC247, 0x9A62,
+	0xC248, 0xBDA5, 0xC249, 0x9A63, 0xC24A, 0x9A64, 0xC24B, 0x9A65,
+	0xC24C, 0x9A66, 0xC24D, 0x9A67, 0xC24E, 0x9A68, 0xC24F, 0x9A69,
+	0xC250, 0xBDA6, 0xC251, 0xBDA7, 0xC252, 0x9A6A, 0xC253, 0x9A6B,
+	0xC254, 0xBDA8, 0xC255, 0x9A6C, 0xC256, 0x9A6D, 0xC257, 0x9A6E,
+	0xC258, 0xBDA9, 0xC259, 0x9A6F, 0xC25A, 0x9A70, 0xC25B, 0x9A71,
+	0xC25C, 0x9A72, 0xC25D, 0x9A73, 0xC25E, 0x9A74, 0xC25F, 0x9A75,
+	0xC260, 0xBDAA, 0xC261, 0x9A76, 0xC262, 0x9A77, 0xC263, 0x9A78,
+	0xC264, 0x9A79, 0xC265, 0xBDAB, 0xC266, 0x9A7A, 0xC267, 0x9A81,
+	0xC268, 0x9A82, 0xC269, 0x9A83, 0xC26A, 0x9A84, 0xC26B, 0x9A85,
+	0xC26C, 0xBDAC, 0xC26D, 0xBDAD, 0xC26E, 0x9A86, 0xC26F, 0x9A87,
+	0xC270, 0xBDAE, 0xC271, 0x9A88, 0xC272, 0x9A89, 0xC273, 0x9A8A,
+	0xC274, 0xBDAF, 0xC275, 0x9A8B, 0xC276, 0x9A8C, 0xC277, 0x9A8D,
+	0xC278, 0x9A8E, 0xC279, 0x9A8F, 0xC27A, 0x9A90, 0xC27B, 0x9A91,
+	0xC27C, 0xBDB0, 0xC27D, 0xBDB1, 0xC27E, 0x9A92, 0xC27F, 0xBDB2,
+	0xC280, 0x9A93, 0xC281, 0xBDB3, 0xC282, 0x9A94, 0xC283, 0x9A95,
+	0xC284, 0x9A96, 0xC285, 0x9A97, 0xC286, 0x9A98, 0xC287, 0x9A99,
+	0xC288, 0xBDB4, 0xC289, 0xBDB5, 0xC28A, 0x9A9A, 0xC28B, 0x9A9B,
+	0xC28C, 0x9A9C, 0xC28D, 0x9A9D, 0xC28E, 0x9A9E, 0xC28F, 0x9A9F,
+	0xC290, 0xBDB6, 0xC291, 0x9AA0, 0xC292, 0x9AA1, 0xC293, 0x9AA2,
+	0xC294, 0x9AA3, 0xC295, 0x9AA4, 0xC296, 0x9AA5, 0xC297, 0x9AA6,
+	0xC298, 0xBDB7, 0xC299, 0x9AA7, 0xC29A, 0x9AA8, 0xC29B, 0xBDB8,
+	0xC29C, 0x9AA9, 0xC29D, 0xBDB9, 0xC29E, 0x9AAA, 0xC29F, 0x9AAB,
+	0xC2A0, 0x9AAC, 0xC2A1, 0x9AAD, 0xC2A2, 0x9AAE, 0xC2A3, 0x9AAF,
+	0xC2A4, 0xBDBA, 0xC2A5, 0xBDBB, 0xC2A6, 0x9AB0, 0xC2A7, 0x9AB1,
+	0xC2A8, 0xBDBC, 0xC2A9, 0x9AB2, 0xC2AA, 0x9AB3, 0xC2AB, 0x9AB4,
+	0xC2AC, 0xBDBD, 0xC2AD, 0xBDBE, 0xC2AE, 0x9AB5, 0xC2AF, 0x9AB6,
+	0xC2B0, 0x9AB7, 0xC2B1, 0x9AB8, 0xC2B2, 0x9AB9, 0xC2B3, 0x9ABA,
+	0xC2B4, 0xBDBF, 0xC2B5, 0xBDC0, 0xC2B6, 0x9ABB, 0xC2B7, 0xBDC1,
+	0xC2B8, 0x9ABC, 0xC2B9, 0xBDC2, 0xC2BA, 0x9ABD, 0xC2BB, 0x9ABE,
+	0xC2BC, 0x9ABF, 0xC2BD, 0x9AC0, 0xC2BE, 0x9AC1, 0xC2BF, 0x9AC2,
+	0xC2C0, 0x9AC3, 0xC2C1, 0x9AC4, 0xC2C2, 0x9AC5, 0xC2C3, 0x9AC6,
+	0xC2C4, 0x9AC7, 0xC2C5, 0x9AC8, 0xC2C6, 0x9AC9, 0xC2C7, 0x9ACA,
+	0xC2C8, 0x9ACB, 0xC2C9, 0x9ACC, 0xC2CA, 0x9ACD, 0xC2CB, 0x9ACE,
+	0xC2CC, 0x9ACF, 0xC2CD, 0x9AD0, 0xC2CE, 0x9AD1, 0xC2CF, 0x9AD2,
+	0xC2D0, 0x9AD3, 0xC2D1, 0x9AD4, 0xC2D2, 0x9AD5, 0xC2D3, 0x9AD6,
+	0xC2D4, 0x9AD7, 0xC2D5, 0x9AD8, 0xC2D6, 0x9AD9, 0xC2D7, 0x9ADA,
+	0xC2D8, 0x9ADB, 0xC2D9, 0x9ADC, 0xC2DA, 0x9ADD, 0xC2DB, 0x9ADE,
+	0xC2DC, 0xBDC3, 0xC2DD, 0xBDC4, 0xC2DE, 0x9ADF, 0xC2DF, 0x9AE0,
+	0xC2E0, 0xBDC5, 0xC2E1, 0x9AE1, 0xC2E2, 0x9AE2, 0xC2E3, 0xBDC6,
+	0xC2E4, 0xBDC7, 0xC2E5, 0x9AE3, 0xC2E6, 0x9AE4, 0xC2E7, 0x9AE5,
+	0xC2E8, 0x9AE6, 0xC2E9, 0x9AE7, 0xC2EA, 0x9AE8, 0xC2EB, 0xBDC8,
+	0xC2EC, 0xBDC9, 0xC2ED, 0xBDCA, 0xC2EE, 0x9AE9, 0xC2EF, 0xBDCB,
+	0xC2F0, 0x9AEA, 0xC2F1, 0xBDCC, 0xC2F2, 0x9AEB, 0xC2F3, 0x9AEC,
+	0xC2F4, 0x9AED, 0xC2F5, 0x9AEE, 0xC2F6, 0xBDCD, 0xC2F7, 0x9AEF,
+	0xC2F8, 0xBDCE, 0xC2F9, 0xBDCF, 0xC2FA, 0x9AF0, 0xC2FB, 0xBDD0,
+	0xC2FC, 0xBDD1, 0xC2FD, 0x9AF1, 0xC2FE, 0x9AF2, 0xC2FF, 0x9AF3,
+	0xC300, 0xBDD2, 0xC301, 0x9AF4, 0xC302, 0x9AF5, 0xC303, 0x9AF6,
+	0xC304, 0x9AF7, 0xC305, 0x9AF8, 0xC306, 0x9AF9, 0xC307, 0x9AFA,
+	0xC308, 0xBDD3, 0xC309, 0xBDD4, 0xC30A, 0x9AFB, 0xC30B, 0x9AFC,
+	0xC30C, 0xBDD5, 0xC30D, 0xBDD6, 0xC30E, 0x9AFD, 0xC30F, 0x9AFE,
+	0xC310, 0x9B41, 0xC311, 0x9B42, 0xC312, 0x9B43, 0xC313, 0xBDD7,
+	0xC314, 0xBDD8, 0xC315, 0xBDD9, 0xC316, 0x9B44, 0xC317, 0x9B45,
+	0xC318, 0xBDDA, 0xC319, 0x9B46, 0xC31A, 0x9B47, 0xC31B, 0x9B48,
+	0xC31C, 0xBDDB, 0xC31D, 0x9B49, 0xC31E, 0x9B4A, 0xC31F, 0x9B4B,
+	0xC320, 0x9B4C, 0xC321, 0x9B4D, 0xC322, 0x9B4E, 0xC323, 0x9B4F,
+	0xC324, 0xBDDC, 0xC325, 0xBDDD, 0xC326, 0x9B50, 0xC327, 0x9B51,
+	0xC328, 0xBDDE, 0xC329, 0xBDDF, 0xC32A, 0x9B52, 0xC32B, 0x9B53,
+	0xC32C, 0x9B54, 0xC32D, 0x9B55, 0xC32E, 0x9B56, 0xC32F, 0x9B57,
+	0xC330, 0x9B58, 0xC331, 0x9B59, 0xC332, 0x9B5A, 0xC333, 0x9B61,
+	0xC334, 0x9B62, 0xC335, 0x9B63, 0xC336, 0x9B64, 0xC337, 0x9B65,
+	0xC338, 0x9B66, 0xC339, 0x9B67, 0xC33A, 0x9B68, 0xC33B, 0x9B69,
+	0xC33C, 0x9B6A, 0xC33D, 0x9B6B, 0xC33E, 0x9B6C, 0xC33F, 0x9B6D,
+	0xC340, 0x9B6E, 0xC341, 0x9B6F, 0xC342, 0x9B70, 0xC343, 0x9B71,
+	0xC344, 0x9B72, 0xC345, 0xBDE0, 0xC346, 0x9B73, 0xC347, 0x9B74,
+	0xC348, 0x9B75, 0xC349, 0x9B76, 0xC34A, 0x9B77, 0xC34B, 0x9B78,
+	0xC34C, 0x9B79, 0xC34D, 0x9B7A, 0xC34E, 0x9B81, 0xC34F, 0x9B82,
+	0xC350, 0x9B83, 0xC351, 0x9B84, 0xC352, 0x9B85, 0xC353, 0x9B86,
+	0xC354, 0x9B87, 0xC355, 0x9B88, 0xC356, 0x9B89, 0xC357, 0x9B8A,
+	0xC358, 0x9B8B, 0xC359, 0x9B8C, 0xC35A, 0x9B8D, 0xC35B, 0x9B8E,
+	0xC35C, 0x9B8F, 0xC35D, 0x9B90, 0xC35E, 0x9B91, 0xC35F, 0x9B92,
+	0xC360, 0x9B93, 0xC361, 0x9B94, 0xC362, 0x9B95, 0xC363, 0x9B96,
+	0xC364, 0x9B97, 0xC365, 0x9B98, 0xC366, 0x9B99, 0xC367, 0x9B9A,
+	0xC368, 0xBDE1, 0xC369, 0xBDE2, 0xC36A, 0x9B9B, 0xC36B, 0x9B9C,
+	0xC36C, 0xBDE3, 0xC36D, 0x9B9D, 0xC36E, 0x9B9E, 0xC36F, 0x9B9F,
+	0xC370, 0xBDE4, 0xC371, 0x9BA0, 0xC372, 0xBDE5, 0xC373, 0x9BA1,
+	0xC374, 0x9BA2, 0xC375, 0x9BA3, 0xC376, 0x9BA4, 0xC377, 0x9BA5,
+	0xC378, 0xBDE6, 0xC379, 0xBDE7, 0xC37A, 0x9BA6, 0xC37B, 0x9BA7,
+	0xC37C, 0xBDE8, 0xC37D, 0xBDE9, 0xC37E, 0x9BA8, 0xC37F, 0x9BA9,
+	0xC380, 0x9BAA, 0xC381, 0x9BAB, 0xC382, 0x9BAC, 0xC383, 0x9BAD,
+	0xC384, 0xBDEA, 0xC385, 0x9BAE, 0xC386, 0x9BAF, 0xC387, 0x9BB0,
+	0xC388, 0xBDEB, 0xC389, 0x9BB1, 0xC38A, 0x9BB2, 0xC38B, 0x9BB3,
+	0xC38C, 0xBDEC, 0xC38D, 0x9BB4, 0xC38E, 0x9BB5, 0xC38F, 0x9BB6,
+	0xC390, 0x9BB7, 0xC391, 0x9BB8, 0xC392, 0x9BB9, 0xC393, 0x9BBA,
+	0xC394, 0x9BBB, 0xC395, 0x9BBC, 0xC396, 0x9BBD, 0xC397, 0x9BBE,
+	0xC398, 0x9BBF, 0xC399, 0x9BC0, 0xC39A, 0x9BC1, 0xC39B, 0x9BC2,
+	0xC39C, 0x9BC3, 0xC39D, 0x9BC4, 0xC39E, 0x9BC5, 0xC39F, 0x9BC6,
+	0xC3A0, 0x9BC7, 0xC3A1, 0x9BC8, 0xC3A2, 0x9BC9, 0xC3A3, 0x9BCA,
+	0xC3A4, 0x9BCB, 0xC3A5, 0x9BCC, 0xC3A6, 0x9BCD, 0xC3A7, 0x9BCE,
+	0xC3A8, 0x9BCF, 0xC3A9, 0x9BD0, 0xC3AA, 0x9BD1, 0xC3AB, 0x9BD2,
+	0xC3AC, 0x9BD3, 0xC3AD, 0x9BD4, 0xC3AE, 0x9BD5, 0xC3AF, 0x9BD6,
+	0xC3B0, 0x9BD7, 0xC3B1, 0x9BD8, 0xC3B2, 0x9BD9, 0xC3B3, 0x9BDA,
+	0xC3B4, 0x9BDB, 0xC3B5, 0x9BDC, 0xC3B6, 0x9BDD, 0xC3B7, 0x9BDE,
+	0xC3B8, 0x9BDF, 0xC3B9, 0x9BE0, 0xC3BA, 0x9BE1, 0xC3BB, 0x9BE2,
+	0xC3BC, 0x9BE3, 0xC3BD, 0x9BE4, 0xC3BE, 0x9BE5, 0xC3BF, 0x9BE6,
+	0xC3C0, 0xBDED, 0xC3C1, 0x9BE7, 0xC3C2, 0x9BE8, 0xC3C3, 0x9BE9,
+	0xC3C4, 0x9BEA, 0xC3C5, 0x9BEB, 0xC3C6, 0x9BEC, 0xC3C7, 0x9BED,
+	0xC3C8, 0x9BEE, 0xC3C9, 0x9BEF, 0xC3CA, 0x9BF0, 0xC3CB, 0x9BF1,
+	0xC3CC, 0x9BF2, 0xC3CD, 0x9BF3, 0xC3CE, 0x9BF4, 0xC3CF, 0x9BF5,
+	0xC3D0, 0x9BF6, 0xC3D1, 0x9BF7, 0xC3D2, 0x9BF8, 0xC3D3, 0x9BF9,
+	0xC3D4, 0x9BFA, 0xC3D5, 0x9BFB, 0xC3D6, 0x9BFC, 0xC3D7, 0x9BFD,
+	0xC3D8, 0xBDEE, 0xC3D9, 0xBDEF, 0xC3DA, 0x9BFE, 0xC3DB, 0x9C41,
+	0xC3DC, 0xBDF0, 0xC3DD, 0x9C42, 0xC3DE, 0x9C43, 0xC3DF, 0xBDF1,
+	0xC3E0, 0xBDF2, 0xC3E1, 0x9C44, 0xC3E2, 0xBDF3, 0xC3E3, 0x9C45,
+	0xC3E4, 0x9C46, 0xC3E5, 0x9C47, 0xC3E6, 0x9C48, 0xC3E7, 0x9C49,
+	0xC3E8, 0xBDF4, 0xC3E9, 0xBDF5, 0xC3EA, 0x9C4A, 0xC3EB, 0x9C4B,
+	0xC3EC, 0x9C4C, 0xC3ED, 0xBDF6, 0xC3EE, 0x9C4D, 0xC3EF, 0x9C4E,
+	0xC3F0, 0x9C4F, 0xC3F1, 0x9C50, 0xC3F2, 0x9C51, 0xC3F3, 0x9C52,
+	0xC3F4, 0xBDF7, 0xC3F5, 0xBDF8, 0xC3F6, 0x9C53, 0xC3F7, 0x9C54,
+	0xC3F8, 0xBDF9, 0xC3F9, 0x9C55, 0xC3FA, 0x9C56, 0xC3FB, 0x9C57,
+	0xC3FC, 0x9C58, 0xC3FD, 0x9C59, 0xC3FE, 0x9C5A, 0xC3FF, 0x9C61,
+	0xC400, 0x9C62, 0xC401, 0x9C63, 0xC402, 0x9C64, 0xC403, 0x9C65,
+	0xC404, 0x9C66, 0xC405, 0x9C67, 0xC406, 0x9C68, 0xC407, 0x9C69,
+	0xC408, 0xBDFA, 0xC409, 0x9C6A, 0xC40A, 0x9C6B, 0xC40B, 0x9C6C,
+	0xC40C, 0x9C6D, 0xC40D, 0x9C6E, 0xC40E, 0x9C6F, 0xC40F, 0x9C70,
+	0xC410, 0xBDFB, 0xC411, 0x9C71, 0xC412, 0x9C72, 0xC413, 0x9C73,
+	0xC414, 0x9C74, 0xC415, 0x9C75, 0xC416, 0x9C76, 0xC417, 0x9C77,
+	0xC418, 0x9C78, 0xC419, 0x9C79, 0xC41A, 0x9C7A, 0xC41B, 0x9C81,
+	0xC41C, 0x9C82, 0xC41D, 0x9C83, 0xC41E, 0x9C84, 0xC41F, 0x9C85,
+	0xC420, 0x9C86, 0xC421, 0x9C87, 0xC422, 0x9C88, 0xC423, 0x9C89,
+	0xC424, 0xBDFC, 0xC425, 0x9C8A, 0xC426, 0x9C8B, 0xC427, 0x9C8C,
+	0xC428, 0x9C8D, 0xC429, 0x9C8E, 0xC42A, 0x9C8F, 0xC42B, 0x9C90,
+	0xC42C, 0xBDFD, 0xC42D, 0x9C91, 0xC42E, 0x9C92, 0xC42F, 0x9C93,
+	0xC430, 0xBDFE, 0xC431, 0x9C94, 0xC432, 0x9C95, 0xC433, 0x9C96,
+	0xC434, 0xBEA1, 0xC435, 0x9C97, 0xC436, 0x9C98, 0xC437, 0x9C99,
+	0xC438, 0x9C9A, 0xC439, 0x9C9B, 0xC43A, 0x9C9C, 0xC43B, 0x9C9D,
+	0xC43C, 0xBEA2, 0xC43D, 0xBEA3, 0xC43E, 0x9C9E, 0xC43F, 0x9C9F,
+	0xC440, 0x9CA0, 0xC441, 0x9CA1, 0xC442, 0x9CA2, 0xC443, 0x9CA3,
+	0xC444, 0x9CA4, 0xC445, 0x9CA5, 0xC446, 0x9CA6, 0xC447, 0x9CA7,
+	0xC448, 0xBEA4, 0xC449, 0x9CA8, 0xC44A, 0x9CA9, 0xC44B, 0x9CAA,
+	0xC44C, 0x9CAB, 0xC44D, 0x9CAC, 0xC44E, 0x9CAD, 0xC44F, 0x9CAE,
+	0xC450, 0x9CAF, 0xC451, 0x9CB0, 0xC452, 0x9CB1, 0xC453, 0x9CB2,
+	0xC454, 0x9CB3, 0xC455, 0x9CB4, 0xC456, 0x9CB5, 0xC457, 0x9CB6,
+	0xC458, 0x9CB7, 0xC459, 0x9CB8, 0xC45A, 0x9CB9, 0xC45B, 0x9CBA,
+	0xC45C, 0x9CBB, 0xC45D, 0x9CBC, 0xC45E, 0x9CBD, 0xC45F, 0x9CBE,
+	0xC460, 0x9CBF, 0xC461, 0x9CC0, 0xC462, 0x9CC1, 0xC463, 0x9CC2,
+	0xC464, 0xBEA5, 0xC465, 0xBEA6, 0xC466, 0x9CC3, 0xC467, 0x9CC4,
+	0xC468, 0xBEA7, 0xC469, 0x9CC5, 0xC46A, 0x9CC6, 0xC46B, 0x9CC7,
+	0xC46C, 0xBEA8, 0xC46D, 0x9CC8, 0xC46E, 0x9CC9, 0xC46F, 0x9CCA,
+	0xC470, 0x9CCB, 0xC471, 0x9CCC, 0xC472, 0x9CCD, 0xC473, 0x9CCE,
+	0xC474, 0xBEA9, 0xC475, 0xBEAA, 0xC476, 0x9CCF, 0xC477, 0x9CD0,
+	0xC478, 0x9CD1, 0xC479, 0xBEAB, 0xC47A, 0x9CD2, 0xC47B, 0x9CD3,
+	0xC47C, 0x9CD4, 0xC47D, 0x9CD5, 0xC47E, 0x9CD6, 0xC47F, 0x9CD7,
+	0xC480, 0xBEAC, 0xC481, 0x9CD8, 0xC482, 0x9CD9, 0xC483, 0x9CDA,
+	0xC484, 0x9CDB, 0xC485, 0x9CDC, 0xC486, 0x9CDD, 0xC487, 0x9CDE,
+	0xC488, 0x9CDF, 0xC489, 0x9CE0, 0xC48A, 0x9CE1, 0xC48B, 0x9CE2,
+	0xC48C, 0x9CE3, 0xC48D, 0x9CE4, 0xC48E, 0x9CE5, 0xC48F, 0x9CE6,
+	0xC490, 0x9CE7, 0xC491, 0x9CE8, 0xC492, 0x9CE9, 0xC493, 0x9CEA,
+	0xC494, 0xBEAD, 0xC495, 0x9CEB, 0xC496, 0x9CEC, 0xC497, 0x9CED,
+	0xC498, 0x9CEE, 0xC499, 0x9CEF, 0xC49A, 0x9CF0, 0xC49B, 0x9CF1,
+	0xC49C, 0xBEAE, 0xC49D, 0x9CF2, 0xC49E, 0x9CF3, 0xC49F, 0x9CF4,
+	0xC4A0, 0x9CF5, 0xC4A1, 0x9CF6, 0xC4A2, 0x9CF7, 0xC4A3, 0x9CF8,
+	0xC4A4, 0x9CF9, 0xC4A5, 0x9CFA, 0xC4A6, 0x9CFB, 0xC4A7, 0x9CFC,
+	0xC4A8, 0x9CFD, 0xC4A9, 0x9CFE, 0xC4AA, 0x9D41, 0xC4AB, 0x9D42,
+	0xC4AC, 0x9D43, 0xC4AD, 0x9D44, 0xC4AE, 0x9D45, 0xC4AF, 0x9D46,
+	0xC4B0, 0x9D47, 0xC4B1, 0x9D48, 0xC4B2, 0x9D49, 0xC4B3, 0x9D4A,
+	0xC4B4, 0x9D4B, 0xC4B5, 0x9D4C, 0xC4B6, 0x9D4D, 0xC4B7, 0x9D4E,
+	0xC4B8, 0xBEAF, 0xC4B9, 0x9D4F, 0xC4BA, 0x9D50, 0xC4BB, 0x9D51,
+	0xC4BC, 0xBEB0, 0xC4BD, 0x9D52, 0xC4BE, 0x9D53, 0xC4BF, 0x9D54,
+	0xC4C0, 0x9D55, 0xC4C1, 0x9D56, 0xC4C2, 0x9D57, 0xC4C3, 0x9D58,
+	0xC4C4, 0x9D59, 0xC4C5, 0x9D5A, 0xC4C6, 0x9D61, 0xC4C7, 0x9D62,
+	0xC4C8, 0x9D63, 0xC4C9, 0x9D64, 0xC4CA, 0x9D65, 0xC4CB, 0x9D66,
+	0xC4CC, 0x9D67, 0xC4CD, 0x9D68, 0xC4CE, 0x9D69, 0xC4CF, 0x9D6A,
+	0xC4D0, 0x9D6B, 0xC4D1, 0x9D6C, 0xC4D2, 0x9D6D, 0xC4D3, 0x9D6E,
+	0xC4D4, 0x9D6F, 0xC4D5, 0x9D70, 0xC4D6, 0x9D71, 0xC4D7, 0x9D72,
+	0xC4D8, 0x9D73, 0xC4D9, 0x9D74, 0xC4DA, 0x9D75, 0xC4DB, 0x9D76,
+	0xC4DC, 0x9D77, 0xC4DD, 0x9D78, 0xC4DE, 0x9D79, 0xC4DF, 0x9D7A,
+	0xC4E0, 0x9D81, 0xC4E1, 0x9D82, 0xC4E2, 0x9D83, 0xC4E3, 0x9D84,
+	0xC4E4, 0x9D85, 0xC4E5, 0x9D86, 0xC4E6, 0x9D87, 0xC4E7, 0x9D88,
+	0xC4E8, 0x9D89, 0xC4E9, 0xBEB1, 0xC4EA, 0x9D8A, 0xC4EB, 0x9D8B,
+	0xC4EC, 0x9D8C, 0xC4ED, 0x9D8D, 0xC4EE, 0x9D8E, 0xC4EF, 0x9D8F,
+	0xC4F0, 0xBEB2, 0xC4F1, 0xBEB3, 0xC4F2, 0x9D90, 0xC4F3, 0x9D91,
+	0xC4F4, 0xBEB4, 0xC4F5, 0x9D92, 0xC4F6, 0x9D93, 0xC4F7, 0x9D94,
+	0xC4F8, 0xBEB5, 0xC4F9, 0x9D95, 0xC4FA, 0xBEB6, 0xC4FB, 0x9D96,
+	0xC4FC, 0x9D97, 0xC4FD, 0x9D98, 0xC4FE, 0x9D99, 0xC4FF, 0xBEB7,
+	0xC500, 0xBEB8, 0xC501, 0xBEB9, 0xC502, 0x9D9A, 0xC503, 0x9D9B,
+	0xC504, 0x9D9C, 0xC505, 0x9D9D, 0xC506, 0x9D9E, 0xC507, 0x9D9F,
+	0xC508, 0x9DA0, 0xC509, 0x9DA1, 0xC50A, 0x9DA2, 0xC50B, 0x9DA3,
+	0xC50C, 0xBEBA, 0xC50D, 0x9DA4, 0xC50E, 0x9DA5, 0xC50F, 0x9DA6,
+	0xC510, 0xBEBB, 0xC511, 0x9DA7, 0xC512, 0x9DA8, 0xC513, 0x9DA9,
+	0xC514, 0xBEBC, 0xC515, 0x9DAA, 0xC516, 0x9DAB, 0xC517, 0x9DAC,
+	0xC518, 0x9DAD, 0xC519, 0x9DAE, 0xC51A, 0x9DAF, 0xC51B, 0x9DB0,
+	0xC51C, 0xBEBD, 0xC51D, 0x9DB1, 0xC51E, 0x9DB2, 0xC51F, 0x9DB3,
+	0xC520, 0x9DB4, 0xC521, 0x9DB5, 0xC522, 0x9DB6, 0xC523, 0x9DB7,
+	0xC524, 0x9DB8, 0xC525, 0x9DB9, 0xC526, 0x9DBA, 0xC527, 0x9DBB,
+	0xC528, 0xBEBE, 0xC529, 0xBEBF, 0xC52A, 0x9DBC, 0xC52B, 0x9DBD,
+	0xC52C, 0xBEC0, 0xC52D, 0x9DBE, 0xC52E, 0x9DBF, 0xC52F, 0x9DC0,
+	0xC530, 0xBEC1, 0xC531, 0x9DC1, 0xC532, 0x9DC2, 0xC533, 0x9DC3,
+	0xC534, 0x9DC4, 0xC535, 0x9DC5, 0xC536, 0x9DC6, 0xC537, 0x9DC7,
+	0xC538, 0xBEC2, 0xC539, 0xBEC3, 0xC53A, 0x9DC8, 0xC53B, 0xBEC4,
+	0xC53C, 0x9DC9, 0xC53D, 0xBEC5, 0xC53E, 0x9DCA, 0xC53F, 0x9DCB,
+	0xC540, 0x9DCC, 0xC541, 0x9DCD, 0xC542, 0x9DCE, 0xC543, 0x9DCF,
+	0xC544, 0xBEC6, 0xC545, 0xBEC7, 0xC546, 0x9DD0, 0xC547, 0x9DD1,
+	0xC548, 0xBEC8, 0xC549, 0xBEC9, 0xC54A, 0xBECA, 0xC54B, 0x9DD2,
+	0xC54C, 0xBECB, 0xC54D, 0xBECC, 0xC54E, 0xBECD, 0xC54F, 0x9DD3,
+	0xC550, 0x9DD4, 0xC551, 0x9DD5, 0xC552, 0x9DD6, 0xC553, 0xBECE,
+	0xC554, 0xBECF, 0xC555, 0xBED0, 0xC556, 0x9DD7, 0xC557, 0xBED1,
+	0xC558, 0xBED2, 0xC559, 0xBED3, 0xC55A, 0x9DD8, 0xC55B, 0x9DD9,
+	0xC55C, 0x9DDA, 0xC55D, 0xBED4, 0xC55E, 0xBED5, 0xC55F, 0x9DDB,
+	0xC560, 0xBED6, 0xC561, 0xBED7, 0xC562, 0x9DDC, 0xC563, 0x9DDD,
+	0xC564, 0xBED8, 0xC565, 0x9DDE, 0xC566, 0x9DDF, 0xC567, 0x9DE0,
+	0xC568, 0xBED9, 0xC569, 0x9DE1, 0xC56A, 0x9DE2, 0xC56B, 0x9DE3,
+	0xC56C, 0x9DE4, 0xC56D, 0x9DE5, 0xC56E, 0x9DE6, 0xC56F, 0x9DE7,
+	0xC570, 0xBEDA, 0xC571, 0xBEDB, 0xC572, 0x9DE8, 0xC573, 0xBEDC,
+	0xC574, 0xBEDD, 0xC575, 0xBEDE, 0xC576, 0x9DE9, 0xC577, 0x9DEA,
+	0xC578, 0x9DEB, 0xC579, 0x9DEC, 0xC57A, 0x9DED, 0xC57B, 0x9DEE,
+	0xC57C, 0xBEDF, 0xC57D, 0xBEE0, 0xC57E, 0x9DEF, 0xC57F, 0x9DF0,
+	0xC580, 0xBEE1, 0xC581, 0x9DF1, 0xC582, 0x9DF2, 0xC583, 0x9DF3,
+	0xC584, 0xBEE2, 0xC585, 0x9DF4, 0xC586, 0x9DF5, 0xC587, 0xBEE3,
+	0xC588, 0x9DF6, 0xC589, 0x9DF7, 0xC58A, 0x9DF8, 0xC58B, 0x9DF9,
+	0xC58C, 0xBEE4, 0xC58D, 0xBEE5, 0xC58E, 0x9DFA, 0xC58F, 0xBEE6,
+	0xC590, 0x9DFB, 0xC591, 0xBEE7, 0xC592, 0x9DFC, 0xC593, 0x9DFD,
+	0xC594, 0x9DFE, 0xC595, 0xBEE8, 0xC596, 0x9E41, 0xC597, 0xBEE9,
+	0xC598, 0xBEEA, 0xC599, 0x9E42, 0xC59A, 0x9E43, 0xC59B, 0x9E44,
+	0xC59C, 0xBEEB, 0xC59D, 0x9E45, 0xC59E, 0x9E46, 0xC59F, 0x9E47,
+	0xC5A0, 0xBEEC, 0xC5A1, 0x9E48, 0xC5A2, 0x9E49, 0xC5A3, 0x9E4A,
+	0xC5A4, 0x9E4B, 0xC5A5, 0x9E4C, 0xC5A6, 0x9E4D, 0xC5A7, 0x9E4E,
+	0xC5A8, 0x9E4F, 0xC5A9, 0xBEED, 0xC5AA, 0x9E50, 0xC5AB, 0x9E51,
+	0xC5AC, 0x9E52, 0xC5AD, 0x9E53, 0xC5AE, 0x9E54, 0xC5AF, 0x9E55,
+	0xC5B0, 0x9E56, 0xC5B1, 0x9E57, 0xC5B2, 0x9E58, 0xC5B3, 0x9E59,
+	0xC5B4, 0xBEEE, 0xC5B5, 0xBEEF, 0xC5B6, 0x9E5A, 0xC5B7, 0x9E61,
+	0xC5B8, 0xBEF0, 0xC5B9, 0xBEF1, 0xC5BA, 0x9E62, 0xC5BB, 0xBEF2,
+	0xC5BC, 0xBEF3, 0xC5BD, 0xBEF4, 0xC5BE, 0xBEF5, 0xC5BF, 0x9E63,
+	0xC5C0, 0x9E64, 0xC5C1, 0x9E65, 0xC5C2, 0x9E66, 0xC5C3, 0x9E67,
+	0xC5C4, 0xBEF6, 0xC5C5, 0xBEF7, 0xC5C6, 0xBEF8, 0xC5C7, 0xBEF9,
+	0xC5C8, 0xBEFA, 0xC5C9, 0xBEFB, 0xC5CA, 0xBEFC, 0xC5CB, 0x9E68,
+	0xC5CC, 0xBEFD, 0xC5CD, 0x9E69, 0xC5CE, 0xBEFE, 0xC5CF, 0x9E6A,
+	0xC5D0, 0xBFA1, 0xC5D1, 0xBFA2, 0xC5D2, 0x9E6B, 0xC5D3, 0x9E6C,
+	0xC5D4, 0xBFA3, 0xC5D5, 0x9E6D, 0xC5D6, 0x9E6E, 0xC5D7, 0x9E6F,
+	0xC5D8, 0xBFA4, 0xC5D9, 0x9E70, 0xC5DA, 0x9E71, 0xC5DB, 0x9E72,
+	0xC5DC, 0x9E73, 0xC5DD, 0x9E74, 0xC5DE, 0x9E75, 0xC5DF, 0x9E76,
+	0xC5E0, 0xBFA5, 0xC5E1, 0xBFA6, 0xC5E2, 0x9E77, 0xC5E3, 0xBFA7,
+	0xC5E4, 0x9E78, 0xC5E5, 0xBFA8, 0xC5E6, 0x9E79, 0xC5E7, 0x9E7A,
+	0xC5E8, 0x9E81, 0xC5E9, 0x9E82, 0xC5EA, 0x9E83, 0xC5EB, 0x9E84,
+	0xC5EC, 0xBFA9, 0xC5ED, 0xBFAA, 0xC5EE, 0xBFAB, 0xC5EF, 0x9E85,
+	0xC5F0, 0xBFAC, 0xC5F1, 0x9E86, 0xC5F2, 0x9E87, 0xC5F3, 0x9E88,
+	0xC5F4, 0xBFAD, 0xC5F5, 0x9E89, 0xC5F6, 0xBFAE, 0xC5F7, 0xBFAF,
+	0xC5F8, 0x9E8A, 0xC5F9, 0x9E8B, 0xC5FA, 0x9E8C, 0xC5FB, 0x9E8D,
+	0xC5FC, 0xBFB0, 0xC5FD, 0xBFB1, 0xC5FE, 0xBFB2, 0xC5FF, 0xBFB3,
+	0xC600, 0xBFB4, 0xC601, 0xBFB5, 0xC602, 0x9E8E, 0xC603, 0x9E8F,
+	0xC604, 0x9E90, 0xC605, 0xBFB6, 0xC606, 0xBFB7, 0xC607, 0xBFB8,
+	0xC608, 0xBFB9, 0xC609, 0x9E91, 0xC60A, 0x9E92, 0xC60B, 0x9E93,
+	0xC60C, 0xBFBA, 0xC60D, 0x9E94, 0xC60E, 0x9E95, 0xC60F, 0x9E96,
+	0xC610, 0xBFBB, 0xC611, 0x9E97, 0xC612, 0x9E98, 0xC613, 0x9E99,
+	0xC614, 0x9E9A, 0xC615, 0x9E9B, 0xC616, 0x9E9C, 0xC617, 0x9E9D,
+	0xC618, 0xBFBC, 0xC619, 0xBFBD, 0xC61A, 0x9E9E, 0xC61B, 0xBFBE,
+	0xC61C, 0xBFBF, 0xC61D, 0x9E9F, 0xC61E, 0x9EA0, 0xC61F, 0x9EA1,
+	0xC620, 0x9EA2, 0xC621, 0x9EA3, 0xC622, 0x9EA4, 0xC623, 0x9EA5,
+	0xC624, 0xBFC0, 0xC625, 0xBFC1, 0xC626, 0x9EA6, 0xC627, 0x9EA7,
+	0xC628, 0xBFC2, 0xC629, 0x9EA8, 0xC62A, 0x9EA9, 0xC62B, 0x9EAA,
+	0xC62C, 0xBFC3, 0xC62D, 0xBFC4, 0xC62E, 0xBFC5, 0xC62F, 0x9EAB,
+	0xC630, 0xBFC6, 0xC631, 0x9EAC, 0xC632, 0x9EAD, 0xC633, 0xBFC7,
+	0xC634, 0xBFC8, 0xC635, 0xBFC9, 0xC636, 0x9EAE, 0xC637, 0xBFCA,
+	0xC638, 0x9EAF, 0xC639, 0xBFCB, 0xC63A, 0x9EB0, 0xC63B, 0xBFCC,
+	0xC63C, 0x9EB1, 0xC63D, 0x9EB2, 0xC63E, 0x9EB3, 0xC63F, 0x9EB4,
+	0xC640, 0xBFCD, 0xC641, 0xBFCE, 0xC642, 0x9EB5, 0xC643, 0x9EB6,
+	0xC644, 0xBFCF, 0xC645, 0x9EB7, 0xC646, 0x9EB8, 0xC647, 0x9EB9,
+	0xC648, 0xBFD0, 0xC649, 0x9EBA, 0xC64A, 0x9EBB, 0xC64B, 0x9EBC,
+	0xC64C, 0x9EBD, 0xC64D, 0x9EBE, 0xC64E, 0x9EBF, 0xC64F, 0x9EC0,
+	0xC650, 0xBFD1, 0xC651, 0xBFD2, 0xC652, 0x9EC1, 0xC653, 0xBFD3,
+	0xC654, 0xBFD4, 0xC655, 0xBFD5, 0xC656, 0x9EC2, 0xC657, 0x9EC3,
+	0xC658, 0x9EC4, 0xC659, 0x9EC5, 0xC65A, 0x9EC6, 0xC65B, 0x9EC7,
+	0xC65C, 0xBFD6, 0xC65D, 0xBFD7, 0xC65E, 0x9EC8, 0xC65F, 0x9EC9,
+	0xC660, 0xBFD8, 0xC661, 0x9ECA, 0xC662, 0x9ECB, 0xC663, 0x9ECC,
+	0xC664, 0x9ECD, 0xC665, 0x9ECE, 0xC666, 0x9ECF, 0xC667, 0x9ED0,
+	0xC668, 0x9ED1, 0xC669, 0x9ED2, 0xC66A, 0x9ED3, 0xC66B, 0x9ED4,
+	0xC66C, 0xBFD9, 0xC66D, 0x9ED5, 0xC66E, 0x9ED6, 0xC66F, 0xBFDA,
+	0xC670, 0x9ED7, 0xC671, 0xBFDB, 0xC672, 0x9ED8, 0xC673, 0x9ED9,
+	0xC674, 0x9EDA, 0xC675, 0x9EDB, 0xC676, 0x9EDC, 0xC677, 0x9EDD,
+	0xC678, 0xBFDC, 0xC679, 0xBFDD, 0xC67A, 0x9EDE, 0xC67B, 0x9EDF,
+	0xC67C, 0xBFDE, 0xC67D, 0x9EE0, 0xC67E, 0x9EE1, 0xC67F, 0x9EE2,
+	0xC680, 0xBFDF, 0xC681, 0x9EE3, 0xC682, 0x9EE4, 0xC683, 0x9EE5,
+	0xC684, 0x9EE6, 0xC685, 0x9EE7, 0xC686, 0x9EE8, 0xC687, 0x9EE9,
+	0xC688, 0xBFE0, 0xC689, 0xBFE1, 0xC68A, 0x9EEA, 0xC68B, 0xBFE2,
+	0xC68C, 0x9EEB, 0xC68D, 0xBFE3, 0xC68E, 0x9EEC, 0xC68F, 0x9EED,
+	0xC690, 0x9EEE, 0xC691, 0x9EEF, 0xC692, 0x9EF0, 0xC693, 0x9EF1,
+	0xC694, 0xBFE4, 0xC695, 0xBFE5, 0xC696, 0x9EF2, 0xC697, 0x9EF3,
+	0xC698, 0xBFE6, 0xC699, 0x9EF4, 0xC69A, 0x9EF5, 0xC69B, 0x9EF6,
+	0xC69C, 0xBFE7, 0xC69D, 0x9EF7, 0xC69E, 0x9EF8, 0xC69F, 0x9EF9,
+	0xC6A0, 0x9EFA, 0xC6A1, 0x9EFB, 0xC6A2, 0x9EFC, 0xC6A3, 0x9EFD,
+	0xC6A4, 0xBFE8, 0xC6A5, 0xBFE9, 0xC6A6, 0x9EFE, 0xC6A7, 0xBFEA,
+	0xC6A8, 0x9F41, 0xC6A9, 0xBFEB, 0xC6AA, 0x9F42, 0xC6AB, 0x9F43,
+	0xC6AC, 0x9F44, 0xC6AD, 0x9F45, 0xC6AE, 0x9F46, 0xC6AF, 0x9F47,
+	0xC6B0, 0xBFEC, 0xC6B1, 0xBFED, 0xC6B2, 0x9F48, 0xC6B3, 0x9F49,
+	0xC6B4, 0xBFEE, 0xC6B5, 0x9F4A, 0xC6B6, 0x9F4B, 0xC6B7, 0x9F4C,
+	0xC6B8, 0xBFEF, 0xC6B9, 0xBFF0, 0xC6BA, 0xBFF1, 0xC6BB, 0x9F4D,
+	0xC6BC, 0x9F4E, 0xC6BD, 0x9F4F, 0xC6BE, 0x9F50, 0xC6BF, 0x9F51,
+	0xC6C0, 0xBFF2, 0xC6C1, 0xBFF3, 0xC6C2, 0x9F52, 0xC6C3, 0xBFF4,
+	0xC6C4, 0x9F53, 0xC6C5, 0xBFF5, 0xC6C6, 0x9F54, 0xC6C7, 0x9F55,
+	0xC6C8, 0x9F56, 0xC6C9, 0x9F57, 0xC6CA, 0x9F58, 0xC6CB, 0x9F59,
+	0xC6CC, 0xBFF6, 0xC6CD, 0xBFF7, 0xC6CE, 0x9F5A, 0xC6CF, 0x9F61,
+	0xC6D0, 0xBFF8, 0xC6D1, 0x9F62, 0xC6D2, 0x9F63, 0xC6D3, 0x9F64,
+	0xC6D4, 0xBFF9, 0xC6D5, 0x9F65, 0xC6D6, 0x9F66, 0xC6D7, 0x9F67,
+	0xC6D8, 0x9F68, 0xC6D9, 0x9F69, 0xC6DA, 0x9F6A, 0xC6DB, 0x9F6B,
+	0xC6DC, 0xBFFA, 0xC6DD, 0xBFFB, 0xC6DE, 0x9F6C, 0xC6DF, 0x9F6D,
+	0xC6E0, 0xBFFC, 0xC6E1, 0xBFFD, 0xC6E2, 0x9F6E, 0xC6E3, 0x9F6F,
+	0xC6E4, 0x9F70, 0xC6E5, 0x9F71, 0xC6E6, 0x9F72, 0xC6E7, 0x9F73,
+	0xC6E8, 0xBFFE, 0xC6E9, 0xC0A1, 0xC6EA, 0x9F74, 0xC6EB, 0x9F75,
+	0xC6EC, 0xC0A2, 0xC6ED, 0x9F76, 0xC6EE, 0x9F77, 0xC6EF, 0x9F78,
+	0xC6F0, 0xC0A3, 0xC6F1, 0x9F79, 0xC6F2, 0x9F7A, 0xC6F3, 0x9F81,
+	0xC6F4, 0x9F82, 0xC6F5, 0x9F83, 0xC6F6, 0x9F84, 0xC6F7, 0x9F85,
+	0xC6F8, 0xC0A4, 0xC6F9, 0xC0A5, 0xC6FA, 0x9F86, 0xC6FB, 0x9F87,
+	0xC6FC, 0x9F88, 0xC6FD, 0xC0A6, 0xC6FE, 0x9F89, 0xC6FF, 0x9F8A,
+	0xC700, 0x9F8B, 0xC701, 0x9F8C, 0xC702, 0x9F8D, 0xC703, 0x9F8E,
+	0xC704, 0xC0A7, 0xC705, 0xC0A8, 0xC706, 0x9F8F, 0xC707, 0x9F90,
+	0xC708, 0xC0A9, 0xC709, 0x9F91, 0xC70A, 0x9F92, 0xC70B, 0x9F93,
+	0xC70C, 0xC0AA, 0xC70D, 0x9F94, 0xC70E, 0x9F95, 0xC70F, 0x9F96,
+	0xC710, 0x9F97, 0xC711, 0x9F98, 0xC712, 0x9F99, 0xC713, 0x9F9A,
+	0xC714, 0xC0AB, 0xC715, 0xC0AC, 0xC716, 0x9F9B, 0xC717, 0xC0AD,
+	0xC718, 0x9F9C, 0xC719, 0xC0AE, 0xC71A, 0x9F9D, 0xC71B, 0x9F9E,
+	0xC71C, 0x9F9F, 0xC71D, 0x9FA0, 0xC71E, 0x9FA1, 0xC71F, 0x9FA2,
+	0xC720, 0xC0AF, 0xC721, 0xC0B0, 0xC722, 0x9FA3, 0xC723, 0x9FA4,
+	0xC724, 0xC0B1, 0xC725, 0x9FA5, 0xC726, 0x9FA6, 0xC727, 0x9FA7,
+	0xC728, 0xC0B2, 0xC729, 0x9FA8, 0xC72A, 0x9FA9, 0xC72B, 0x9FAA,
+	0xC72C, 0x9FAB, 0xC72D, 0x9FAC, 0xC72E, 0x9FAD, 0xC72F, 0x9FAE,
+	0xC730, 0xC0B3, 0xC731, 0xC0B4, 0xC732, 0x9FAF, 0xC733, 0xC0B5,
+	0xC734, 0x9FB0, 0xC735, 0xC0B6, 0xC736, 0x9FB1, 0xC737, 0xC0B7,
+	0xC738, 0x9FB2, 0xC739, 0x9FB3, 0xC73A, 0x9FB4, 0xC73B, 0x9FB5,
+	0xC73C, 0xC0B8, 0xC73D, 0xC0B9, 0xC73E, 0x9FB6, 0xC73F, 0x9FB7,
+	0xC740, 0xC0BA, 0xC741, 0x9FB8, 0xC742, 0x9FB9, 0xC743, 0x9FBA,
+	0xC744, 0xC0BB, 0xC745, 0x9FBB, 0xC746, 0x9FBC, 0xC747, 0x9FBD,
+	0xC748, 0x9FBE, 0xC749, 0x9FBF, 0xC74A, 0xC0BC, 0xC74B, 0x9FC0,
+	0xC74C, 0xC0BD, 0xC74D, 0xC0BE, 0xC74E, 0x9FC1, 0xC74F, 0xC0BF,
+	0xC750, 0x9FC2, 0xC751, 0xC0C0, 0xC752, 0xC0C1, 0xC753, 0xC0C2,
+	0xC754, 0xC0C3, 0xC755, 0xC0C4, 0xC756, 0xC0C5, 0xC757, 0xC0C6,
+	0xC758, 0xC0C7, 0xC759, 0x9FC3, 0xC75A, 0x9FC4, 0xC75B, 0x9FC5,
+	0xC75C, 0xC0C8, 0xC75D, 0x9FC6, 0xC75E, 0x9FC7, 0xC75F, 0x9FC8,
+	0xC760, 0xC0C9, 0xC761, 0x9FC9, 0xC762, 0x9FCA, 0xC763, 0x9FCB,
+	0xC764, 0x9FCC, 0xC765, 0x9FCD, 0xC766, 0x9FCE, 0xC767, 0x9FCF,
+	0xC768, 0xC0CA, 0xC769, 0x9FD0, 0xC76A, 0x9FD1, 0xC76B, 0xC0CB,
+	0xC76C, 0x9FD2, 0xC76D, 0x9FD3, 0xC76E, 0x9FD4, 0xC76F, 0x9FD5,
+	0xC770, 0x9FD6, 0xC771, 0x9FD7, 0xC772, 0x9FD8, 0xC773, 0x9FD9,
+	0xC774, 0xC0CC, 0xC775, 0xC0CD, 0xC776, 0x9FDA, 0xC777, 0x9FDB,
+	0xC778, 0xC0CE, 0xC779, 0x9FDC, 0xC77A, 0x9FDD, 0xC77B, 0x9FDE,
+	0xC77C, 0xC0CF, 0xC77D, 0xC0D0, 0xC77E, 0xC0D1, 0xC77F, 0x9FDF,
+	0xC780, 0x9FE0, 0xC781, 0x9FE1, 0xC782, 0x9FE2, 0xC783, 0xC0D2,
+	0xC784, 0xC0D3, 0xC785, 0xC0D4, 0xC786, 0x9FE3, 0xC787, 0xC0D5,
+	0xC788, 0xC0D6, 0xC789, 0xC0D7, 0xC78A, 0xC0D8, 0xC78B, 0x9FE4,
+	0xC78C, 0x9FE5, 0xC78D, 0x9FE6, 0xC78E, 0xC0D9, 0xC78F, 0x9FE7,
+	0xC790, 0xC0DA, 0xC791, 0xC0DB, 0xC792, 0x9FE8, 0xC793, 0x9FE9,
+	0xC794, 0xC0DC, 0xC795, 0x9FEA, 0xC796, 0xC0DD, 0xC797, 0xC0DE,
+	0xC798, 0xC0DF, 0xC799, 0x9FEB, 0xC79A, 0xC0E0, 0xC79B, 0x9FEC,
+	0xC79C, 0x9FED, 0xC79D, 0x9FEE, 0xC79E, 0x9FEF, 0xC79F, 0x9FF0,
+	0xC7A0, 0xC0E1, 0xC7A1, 0xC0E2, 0xC7A2, 0x9FF1, 0xC7A3, 0xC0E3,
+	0xC7A4, 0xC0E4, 0xC7A5, 0xC0E5, 0xC7A6, 0xC0E6, 0xC7A7, 0x9FF2,
+	0xC7A8, 0x9FF3, 0xC7A9, 0x9FF4, 0xC7AA, 0x9FF5, 0xC7AB, 0x9FF6,
+	0xC7AC, 0xC0E7, 0xC7AD, 0xC0E8, 0xC7AE, 0x9FF7, 0xC7AF, 0x9FF8,
+	0xC7B0, 0xC0E9, 0xC7B1, 0x9FF9, 0xC7B2, 0x9FFA, 0xC7B3, 0x9FFB,
+	0xC7B4, 0xC0EA, 0xC7B5, 0x9FFC, 0xC7B6, 0x9FFD, 0xC7B7, 0x9FFE,
+	0xC7B8, 0xA041, 0xC7B9, 0xA042, 0xC7BA, 0xA043, 0xC7BB, 0xA044,
+	0xC7BC, 0xC0EB, 0xC7BD, 0xC0EC, 0xC7BE, 0xA045, 0xC7BF, 0xC0ED,
+	0xC7C0, 0xC0EE, 0xC7C1, 0xC0EF, 0xC7C2, 0xA046, 0xC7C3, 0xA047,
+	0xC7C4, 0xA048, 0xC7C5, 0xA049, 0xC7C6, 0xA04A, 0xC7C7, 0xA04B,
+	0xC7C8, 0xC0F0, 0xC7C9, 0xC0F1, 0xC7CA, 0xA04C, 0xC7CB, 0xA04D,
+	0xC7CC, 0xC0F2, 0xC7CD, 0xA04E, 0xC7CE, 0xC0F3, 0xC7CF, 0xA04F,
+	0xC7D0, 0xC0F4, 0xC7D1, 0xA050, 0xC7D2, 0xA051, 0xC7D3, 0xA052,
+	0xC7D4, 0xA053, 0xC7D5, 0xA054, 0xC7D6, 0xA055, 0xC7D7, 0xA056,
+	0xC7D8, 0xC0F5, 0xC7D9, 0xA057, 0xC7DA, 0xA058, 0xC7DB, 0xA059,
+	0xC7DC, 0xA05A, 0xC7DD, 0xC0F6, 0xC7DE, 0xA061, 0xC7DF, 0xA062,
+	0xC7E0, 0xA063, 0xC7E1, 0xA064, 0xC7E2, 0xA065, 0xC7E3, 0xA066,
+	0xC7E4, 0xC0F7, 0xC7E5, 0xA067, 0xC7E6, 0xA068, 0xC7E7, 0xA069,
+	0xC7E8, 0xC0F8, 0xC7E9, 0xA06A, 0xC7EA, 0xA06B, 0xC7EB, 0xA06C,
+	0xC7EC, 0xC0F9, 0xC7ED, 0xA06D, 0xC7EE, 0xA06E, 0xC7EF, 0xA06F,
+	0xC7F0, 0xA070, 0xC7F1, 0xA071, 0xC7F2, 0xA072, 0xC7F3, 0xA073,
+	0xC7F4, 0xA074, 0xC7F5, 0xA075, 0xC7F6, 0xA076, 0xC7F7, 0xA077,
+	0xC7F8, 0xA078, 0xC7F9, 0xA079, 0xC7FA, 0xA07A, 0xC7FB, 0xA081,
+	0xC7FC, 0xA082, 0xC7FD, 0xA083, 0xC7FE, 0xA084, 0xC7FF, 0xA085,
+	0xC800, 0xC0FA, 0xC801, 0xC0FB, 0xC802, 0xA086, 0xC803, 0xA087,
+	0xC804, 0xC0FC, 0xC805, 0xA088, 0xC806, 0xA089, 0xC807, 0xA08A,
+	0xC808, 0xC0FD, 0xC809, 0xA08B, 0xC80A, 0xC0FE, 0xC80B, 0xA08C,
+	0xC80C, 0xA08D, 0xC80D, 0xA08E, 0xC80E, 0xA08F, 0xC80F, 0xA090,
+	0xC810, 0xC1A1, 0xC811, 0xC1A2, 0xC812, 0xA091, 0xC813, 0xC1A3,
+	0xC814, 0xA092, 0xC815, 0xC1A4, 0xC816, 0xC1A5, 0xC817, 0xA093,
+	0xC818, 0xA094, 0xC819, 0xA095, 0xC81A, 0xA096, 0xC81B, 0xA097,
+	0xC81C, 0xC1A6, 0xC81D, 0xC1A7, 0xC81E, 0xA098, 0xC81F, 0xA099,
+	0xC820, 0xC1A8, 0xC821, 0xA09A, 0xC822, 0xA09B, 0xC823, 0xA09C,
+	0xC824, 0xC1A9, 0xC825, 0xA09D, 0xC826, 0xA09E, 0xC827, 0xA09F,
+	0xC828, 0xA0A0, 0xC829, 0xA0A1, 0xC82A, 0xA0A2, 0xC82B, 0xA0A3,
+	0xC82C, 0xC1AA, 0xC82D, 0xC1AB, 0xC82E, 0xA0A4, 0xC82F, 0xC1AC,
+	0xC830, 0xA0A5, 0xC831, 0xC1AD, 0xC832, 0xA0A6, 0xC833, 0xA0A7,
+	0xC834, 0xA0A8, 0xC835, 0xA0A9, 0xC836, 0xA0AA, 0xC837, 0xA0AB,
+	0xC838, 0xC1AE, 0xC839, 0xA0AC, 0xC83A, 0xA0AD, 0xC83B, 0xA0AE,
+	0xC83C, 0xC1AF, 0xC83D, 0xA0AF, 0xC83E, 0xA0B0, 0xC83F, 0xA0B1,
+	0xC840, 0xC1B0, 0xC841, 0xA0B2, 0xC842, 0xA0B3, 0xC843, 0xA0B4,
+	0xC844, 0xA0B5, 0xC845, 0xA0B6, 0xC846, 0xA0B7, 0xC847, 0xA0B8,
+	0xC848, 0xC1B1, 0xC849, 0xC1B2, 0xC84A, 0xA0B9, 0xC84B, 0xA0BA,
+	0xC84C, 0xC1B3, 0xC84D, 0xC1B4, 0xC84E, 0xA0BB, 0xC84F, 0xA0BC,
+	0xC850, 0xA0BD, 0xC851, 0xA0BE, 0xC852, 0xA0BF, 0xC853, 0xA0C0,
+	0xC854, 0xC1B5, 0xC855, 0xA0C1, 0xC856, 0xA0C2, 0xC857, 0xA0C3,
+	0xC858, 0xA0C4, 0xC859, 0xA0C5, 0xC85A, 0xA0C6, 0xC85B, 0xA0C7,
+	0xC85C, 0xA0C8, 0xC85D, 0xA0C9, 0xC85E, 0xA0CA, 0xC85F, 0xA0CB,
+	0xC860, 0xA0CC, 0xC861, 0xA0CD, 0xC862, 0xA0CE, 0xC863, 0xA0CF,
+	0xC864, 0xA0D0, 0xC865, 0xA0D1, 0xC866, 0xA0D2, 0xC867, 0xA0D3,
+	0xC868, 0xA0D4, 0xC869, 0xA0D5, 0xC86A, 0xA0D6, 0xC86B, 0xA0D7,
+	0xC86C, 0xA0D8, 0xC86D, 0xA0D9, 0xC86E, 0xA0DA, 0xC86F, 0xA0DB,
+	0xC870, 0xC1B6, 0xC871, 0xC1B7, 0xC872, 0xA0DC, 0xC873, 0xA0DD,
+	0xC874, 0xC1B8, 0xC875, 0xA0DE, 0xC876, 0xA0DF, 0xC877, 0xA0E0,
+	0xC878, 0xC1B9, 0xC879, 0xA0E1, 0xC87A, 0xC1BA, 0xC87B, 0xA0E2,
+	0xC87C, 0xA0E3, 0xC87D, 0xA0E4, 0xC87E, 0xA0E5, 0xC87F, 0xA0E6,
+	0xC880, 0xC1BB, 0xC881, 0xC1BC, 0xC882, 0xA0E7, 0xC883, 0xC1BD,
+	0xC884, 0xA0E8, 0xC885, 0xC1BE, 0xC886, 0xC1BF, 0xC887, 0xC1C0,
+	0xC888, 0xA0E9, 0xC889, 0xA0EA, 0xC88A, 0xA0EB, 0xC88B, 0xC1C1,
+	0xC88C, 0xC1C2, 0xC88D, 0xC1C3, 0xC88E, 0xA0EC, 0xC88F, 0xA0ED,
+	0xC890, 0xA0EE, 0xC891, 0xA0EF, 0xC892, 0xA0F0, 0xC893, 0xA0F1,
+	0xC894, 0xC1C4, 0xC895, 0xA0F2, 0xC896, 0xA0F3, 0xC897, 0xA0F4,
+	0xC898, 0xA0F5, 0xC899, 0xA0F6, 0xC89A, 0xA0F7, 0xC89B, 0xA0F8,
+	0xC89C, 0xA0F9, 0xC89D, 0xC1C5, 0xC89E, 0xA0FA, 0xC89F, 0xC1C6,
+	0xC8A0, 0xA0FB, 0xC8A1, 0xC1C7, 0xC8A2, 0xA0FC, 0xC8A3, 0xA0FD,
+	0xC8A4, 0xA0FE, 0xC8A5, 0xA141, 0xC8A6, 0xA142, 0xC8A7, 0xA143,
+	0xC8A8, 0xC1C8, 0xC8A9, 0xA144, 0xC8AA, 0xA145, 0xC8AB, 0xA146,
+	0xC8AC, 0xA147, 0xC8AD, 0xA148, 0xC8AE, 0xA149, 0xC8AF, 0xA14A,
+	0xC8B0, 0xA14B, 0xC8B1, 0xA14C, 0xC8B2, 0xA14D, 0xC8B3, 0xA14E,
+	0xC8B4, 0xA14F, 0xC8B5, 0xA150, 0xC8B6, 0xA151, 0xC8B7, 0xA152,
+	0xC8B8, 0xA153, 0xC8B9, 0xA154, 0xC8BA, 0xA155, 0xC8BB, 0xA156,
+	0xC8BC, 0xC1C9, 0xC8BD, 0xC1CA, 0xC8BE, 0xA157, 0xC8BF, 0xA158,
+	0xC8C0, 0xA159, 0xC8C1, 0xA15A, 0xC8C2, 0xA161, 0xC8C3, 0xA162,
+	0xC8C4, 0xC1CB, 0xC8C5, 0xA163, 0xC8C6, 0xA164, 0xC8C7, 0xA165,
+	0xC8C8, 0xC1CC, 0xC8C9, 0xA166, 0xC8CA, 0xA167, 0xC8CB, 0xA168,
+	0xC8CC, 0xC1CD, 0xC8CD, 0xA169, 0xC8CE, 0xA16A, 0xC8CF, 0xA16B,
+	0xC8D0, 0xA16C, 0xC8D1, 0xA16D, 0xC8D2, 0xA16E, 0xC8D3, 0xA16F,
+	0xC8D4, 0xC1CE, 0xC8D5, 0xC1CF, 0xC8D6, 0xA170, 0xC8D7, 0xC1D0,
+	0xC8D8, 0xA171, 0xC8D9, 0xC1D1, 0xC8DA, 0xA172, 0xC8DB, 0xA173,
+	0xC8DC, 0xA174, 0xC8DD, 0xA175, 0xC8DE, 0xA176, 0xC8DF, 0xA177,
+	0xC8E0, 0xC1D2, 0xC8E1, 0xC1D3, 0xC8E2, 0xA178, 0xC8E3, 0xA179,
+	0xC8E4, 0xC1D4, 0xC8E5, 0xA17A, 0xC8E6, 0xA181, 0xC8E7, 0xA182,
+	0xC8E8, 0xA183, 0xC8E9, 0xA184, 0xC8EA, 0xA185, 0xC8EB, 0xA186,
+	0xC8EC, 0xA187, 0xC8ED, 0xA188, 0xC8EE, 0xA189, 0xC8EF, 0xA18A,
+	0xC8F0, 0xA18B, 0xC8F1, 0xA18C, 0xC8F2, 0xA18D, 0xC8F3, 0xA18E,
+	0xC8F4, 0xA18F, 0xC8F5, 0xC1D5, 0xC8F6, 0xA190, 0xC8F7, 0xA191,
+	0xC8F8, 0xA192, 0xC8F9, 0xA193, 0xC8FA, 0xA194, 0xC8FB, 0xA195,
+	0xC8FC, 0xC1D6, 0xC8FD, 0xC1D7, 0xC8FE, 0xA196, 0xC8FF, 0xA197,
+	0xC900, 0xC1D8, 0xC901, 0xA198, 0xC902, 0xA199, 0xC903, 0xA19A,
+	0xC904, 0xC1D9, 0xC905, 0xC1DA, 0xC906, 0xC1DB, 0xC907, 0xA19B,
+	0xC908, 0xA19C, 0xC909, 0xA19D, 0xC90A, 0xA19E, 0xC90B, 0xA19F,
+	0xC90C, 0xC1DC, 0xC90D, 0xC1DD, 0xC90E, 0xA1A0, 0xC90F, 0xC1DE,
+	0xC910, 0xA241, 0xC911, 0xC1DF, 0xC912, 0xA242, 0xC913, 0xA243,
+	0xC914, 0xA244, 0xC915, 0xA245, 0xC916, 0xA246, 0xC917, 0xA247,
+	0xC918, 0xC1E0, 0xC919, 0xA248, 0xC91A, 0xA249, 0xC91B, 0xA24A,
+	0xC91C, 0xA24B, 0xC91D, 0xA24C, 0xC91E, 0xA24D, 0xC91F, 0xA24E,
+	0xC920, 0xA24F, 0xC921, 0xA250, 0xC922, 0xA251, 0xC923, 0xA252,
+	0xC924, 0xA253, 0xC925, 0xA254, 0xC926, 0xA255, 0xC927, 0xA256,
+	0xC928, 0xA257, 0xC929, 0xA258, 0xC92A, 0xA259, 0xC92B, 0xA25A,
+	0xC92C, 0xC1E1, 0xC92D, 0xA261, 0xC92E, 0xA262, 0xC92F, 0xA263,
+	0xC930, 0xA264, 0xC931, 0xA265, 0xC932, 0xA266, 0xC933, 0xA267,
+	0xC934, 0xC1E2, 0xC935, 0xA268, 0xC936, 0xA269, 0xC937, 0xA26A,
+	0xC938, 0xA26B, 0xC939, 0xA26C, 0xC93A, 0xA26D, 0xC93B, 0xA26E,
+	0xC93C, 0xA26F, 0xC93D, 0xA270, 0xC93E, 0xA271, 0xC93F, 0xA272,
+	0xC940, 0xA273, 0xC941, 0xA274, 0xC942, 0xA275, 0xC943, 0xA276,
+	0xC944, 0xA277, 0xC945, 0xA278, 0xC946, 0xA279, 0xC947, 0xA27A,
+	0xC948, 0xA281, 0xC949, 0xA282, 0xC94A, 0xA283, 0xC94B, 0xA284,
+	0xC94C, 0xA285, 0xC94D, 0xA286, 0xC94E, 0xA287, 0xC94F, 0xA288,
+	0xC950, 0xC1E3, 0xC951, 0xC1E4, 0xC952, 0xA289, 0xC953, 0xA28A,
+	0xC954, 0xC1E5, 0xC955, 0xA28B, 0xC956, 0xA28C, 0xC957, 0xA28D,
+	0xC958, 0xC1E6, 0xC959, 0xA28E, 0xC95A, 0xA28F, 0xC95B, 0xA290,
+	0xC95C, 0xA291, 0xC95D, 0xA292, 0xC95E, 0xA293, 0xC95F, 0xA294,
+	0xC960, 0xC1E7, 0xC961, 0xC1E8, 0xC962, 0xA295, 0xC963, 0xC1E9,
+	0xC964, 0xA296, 0xC965, 0xA297, 0xC966, 0xA298, 0xC967, 0xA299,
+	0xC968, 0xA29A, 0xC969, 0xA29B, 0xC96A, 0xA29C, 0xC96B, 0xA29D,
+	0xC96C, 0xC1EA, 0xC96D, 0xA29E, 0xC96E, 0xA29F, 0xC96F, 0xA2A0,
+	0xC970, 0xC1EB, 0xC971, 0xA341, 0xC972, 0xA342, 0xC973, 0xA343,
+	0xC974, 0xC1EC, 0xC975, 0xA344, 0xC976, 0xA345, 0xC977, 0xA346,
+	0xC978, 0xA347, 0xC979, 0xA348, 0xC97A, 0xA349, 0xC97B, 0xA34A,
+	0xC97C, 0xC1ED, 0xC97D, 0xA34B, 0xC97E, 0xA34C, 0xC97F, 0xA34D,
+	0xC980, 0xA34E, 0xC981, 0xA34F, 0xC982, 0xA350, 0xC983, 0xA351,
+	0xC984, 0xA352, 0xC985, 0xA353, 0xC986, 0xA354, 0xC987, 0xA355,
+	0xC988, 0xC1EE, 0xC989, 0xC1EF, 0xC98A, 0xA356, 0xC98B, 0xA357,
+	0xC98C, 0xC1F0, 0xC98D, 0xA358, 0xC98E, 0xA359, 0xC98F, 0xA35A,
+	0xC990, 0xC1F1, 0xC991, 0xA361, 0xC992, 0xA362, 0xC993, 0xA363,
+	0xC994, 0xA364, 0xC995, 0xA365, 0xC996, 0xA366, 0xC997, 0xA367,
+	0xC998, 0xC1F2, 0xC999, 0xC1F3, 0xC99A, 0xA368, 0xC99B, 0xC1F4,
+	0xC99C, 0xA369, 0xC99D, 0xC1F5, 0xC99E, 0xA36A, 0xC99F, 0xA36B,
+	0xC9A0, 0xA36C, 0xC9A1, 0xA36D, 0xC9A2, 0xA36E, 0xC9A3, 0xA36F,
+	0xC9A4, 0xA370, 0xC9A5, 0xA371, 0xC9A6, 0xA372, 0xC9A7, 0xA373,
+	0xC9A8, 0xA374, 0xC9A9, 0xA375, 0xC9AA, 0xA376, 0xC9AB, 0xA377,
+	0xC9AC, 0xA378, 0xC9AD, 0xA379, 0xC9AE, 0xA37A, 0xC9AF, 0xA381,
+	0xC9B0, 0xA382, 0xC9B1, 0xA383, 0xC9B2, 0xA384, 0xC9B3, 0xA385,
+	0xC9B4, 0xA386, 0xC9B5, 0xA387, 0xC9B6, 0xA388, 0xC9B7, 0xA389,
+	0xC9B8, 0xA38A, 0xC9B9, 0xA38B, 0xC9BA, 0xA38C, 0xC9BB, 0xA38D,
+	0xC9BC, 0xA38E, 0xC9BD, 0xA38F, 0xC9BE, 0xA390, 0xC9BF, 0xA391,
+	0xC9C0, 0xC1F6, 0xC9C1, 0xC1F7, 0xC9C2, 0xA392, 0xC9C3, 0xA393,
+	0xC9C4, 0xC1F8, 0xC9C5, 0xA394, 0xC9C6, 0xA395, 0xC9C7, 0xC1F9,
+	0xC9C8, 0xC1FA, 0xC9C9, 0xA396, 0xC9CA, 0xC1FB, 0xC9CB, 0xA397,
+	0xC9CC, 0xA398, 0xC9CD, 0xA399, 0xC9CE, 0xA39A, 0xC9CF, 0xA39B,
+	0xC9D0, 0xC1FC, 0xC9D1, 0xC1FD, 0xC9D2, 0xA39C, 0xC9D3, 0xC1FE,
+	0xC9D4, 0xA39D, 0xC9D5, 0xC2A1, 0xC9D6, 0xC2A2, 0xC9D7, 0xA39E,
+	0xC9D8, 0xA39F, 0xC9D9, 0xC2A3, 0xC9DA, 0xC2A4, 0xC9DB, 0xA3A0,
+	0xC9DC, 0xC2A5, 0xC9DD, 0xC2A6, 0xC9DE, 0xA441, 0xC9DF, 0xA442,
+	0xC9E0, 0xC2A7, 0xC9E1, 0xA443, 0xC9E2, 0xC2A8, 0xC9E3, 0xA444,
+	0xC9E4, 0xC2A9, 0xC9E5, 0xA445, 0xC9E6, 0xA446, 0xC9E7, 0xC2AA,
+	0xC9E8, 0xA447, 0xC9E9, 0xA448, 0xC9EA, 0xA449, 0xC9EB, 0xA44A,
+	0xC9EC, 0xC2AB, 0xC9ED, 0xC2AC, 0xC9EE, 0xA44B, 0xC9EF, 0xC2AD,
+	0xC9F0, 0xC2AE, 0xC9F1, 0xC2AF, 0xC9F2, 0xA44C, 0xC9F3, 0xA44D,
+	0xC9F4, 0xA44E, 0xC9F5, 0xA44F, 0xC9F6, 0xA450, 0xC9F7, 0xA451,
+	0xC9F8, 0xC2B0, 0xC9F9, 0xC2B1, 0xC9FA, 0xA452, 0xC9FB, 0xA453,
+	0xC9FC, 0xC2B2, 0xC9FD, 0xA454, 0xC9FE, 0xA455, 0xC9FF, 0xA456,
+	0xCA00, 0xC2B3, 0xCA01, 0xA457, 0xCA02, 0xA458, 0xCA03, 0xA459,
+	0xCA04, 0xA45A, 0xCA05, 0xA461, 0xCA06, 0xA462, 0xCA07, 0xA463,
+	0xCA08, 0xC2B4, 0xCA09, 0xC2B5, 0xCA0A, 0xA464, 0xCA0B, 0xC2B6,
+	0xCA0C, 0xC2B7, 0xCA0D, 0xC2B8, 0xCA0E, 0xA465, 0xCA0F, 0xA466,
+	0xCA10, 0xA467, 0xCA11, 0xA468, 0xCA12, 0xA469, 0xCA13, 0xA46A,
+	0xCA14, 0xC2B9, 0xCA15, 0xA46B, 0xCA16, 0xA46C, 0xCA17, 0xA46D,
+	0xCA18, 0xC2BA, 0xCA19, 0xA46E, 0xCA1A, 0xA46F, 0xCA1B, 0xA470,
+	0xCA1C, 0xA471, 0xCA1D, 0xA472, 0xCA1E, 0xA473, 0xCA1F, 0xA474,
+	0xCA20, 0xA475, 0xCA21, 0xA476, 0xCA22, 0xA477, 0xCA23, 0xA478,
+	0xCA24, 0xA479, 0xCA25, 0xA47A, 0xCA26, 0xA481, 0xCA27, 0xA482,
+	0xCA28, 0xA483, 0xCA29, 0xC2BB, 0xCA2A, 0xA484, 0xCA2B, 0xA485,
+	0xCA2C, 0xA486, 0xCA2D, 0xA487, 0xCA2E, 0xA488, 0xCA2F, 0xA489,
+	0xCA30, 0xA48A, 0xCA31, 0xA48B, 0xCA32, 0xA48C, 0xCA33, 0xA48D,
+	0xCA34, 0xA48E, 0xCA35, 0xA48F, 0xCA36, 0xA490, 0xCA37, 0xA491,
+	0xCA38, 0xA492, 0xCA39, 0xA493, 0xCA3A, 0xA494, 0xCA3B, 0xA495,
+	0xCA3C, 0xA496, 0xCA3D, 0xA497, 0xCA3E, 0xA498, 0xCA3F, 0xA499,
+	0xCA40, 0xA49A, 0xCA41, 0xA49B, 0xCA42, 0xA49C, 0xCA43, 0xA49D,
+	0xCA44, 0xA49E, 0xCA45, 0xA49F, 0xCA46, 0xA4A0, 0xCA47, 0xA541,
+	0xCA48, 0xA542, 0xCA49, 0xA543, 0xCA4A, 0xA544, 0xCA4B, 0xA545,
+	0xCA4C, 0xC2BC, 0xCA4D, 0xC2BD, 0xCA4E, 0xA546, 0xCA4F, 0xA547,
+	0xCA50, 0xC2BE, 0xCA51, 0xA548, 0xCA52, 0xA549, 0xCA53, 0xA54A,
+	0xCA54, 0xC2BF, 0xCA55, 0xA54B, 0xCA56, 0xA54C, 0xCA57, 0xA54D,
+	0xCA58, 0xA54E, 0xCA59, 0xA54F, 0xCA5A, 0xA550, 0xCA5B, 0xA551,
+	0xCA5C, 0xC2C0, 0xCA5D, 0xC2C1, 0xCA5E, 0xA552, 0xCA5F, 0xC2C2,
+	0xCA60, 0xC2C3, 0xCA61, 0xC2C4, 0xCA62, 0xA553, 0xCA63, 0xA554,
+	0xCA64, 0xA555, 0xCA65, 0xA556, 0xCA66, 0xA557, 0xCA67, 0xA558,
+	0xCA68, 0xC2C5, 0xCA69, 0xA559, 0xCA6A, 0xA55A, 0xCA6B, 0xA561,
+	0xCA6C, 0xA562, 0xCA6D, 0xA563, 0xCA6E, 0xA564, 0xCA6F, 0xA565,
+	0xCA70, 0xA566, 0xCA71, 0xA567, 0xCA72, 0xA568, 0xCA73, 0xA569,
+	0xCA74, 0xA56A, 0xCA75, 0xA56B, 0xCA76, 0xA56C, 0xCA77, 0xA56D,
+	0xCA78, 0xA56E, 0xCA79, 0xA56F, 0xCA7A, 0xA570, 0xCA7B, 0xA571,
+	0xCA7C, 0xA572, 0xCA7D, 0xC2C6, 0xCA7E, 0xA573, 0xCA7F, 0xA574,
+	0xCA80, 0xA575, 0xCA81, 0xA576, 0xCA82, 0xA577, 0xCA83, 0xA578,
+	0xCA84, 0xC2C7, 0xCA85, 0xA579, 0xCA86, 0xA57A, 0xCA87, 0xA581,
+	0xCA88, 0xA582, 0xCA89, 0xA583, 0xCA8A, 0xA584, 0xCA8B, 0xA585,
+	0xCA8C, 0xA586, 0xCA8D, 0xA587, 0xCA8E, 0xA588, 0xCA8F, 0xA589,
+	0xCA90, 0xA58A, 0xCA91, 0xA58B, 0xCA92, 0xA58C, 0xCA93, 0xA58D,
+	0xCA94, 0xA58E, 0xCA95, 0xA58F, 0xCA96, 0xA590, 0xCA97, 0xA591,
+	0xCA98, 0xC2C8, 0xCA99, 0xA592, 0xCA9A, 0xA593, 0xCA9B, 0xA594,
+	0xCA9C, 0xA595, 0xCA9D, 0xA596, 0xCA9E, 0xA597, 0xCA9F, 0xA598,
+	0xCAA0, 0xA599, 0xCAA1, 0xA59A, 0xCAA2, 0xA59B, 0xCAA3, 0xA59C,
+	0xCAA4, 0xA59D, 0xCAA5, 0xA59E, 0xCAA6, 0xA59F, 0xCAA7, 0xA5A0,
+	0xCAA8, 0xA641, 0xCAA9, 0xA642, 0xCAAA, 0xA643, 0xCAAB, 0xA644,
+	0xCAAC, 0xA645, 0xCAAD, 0xA646, 0xCAAE, 0xA647, 0xCAAF, 0xA648,
+	0xCAB0, 0xA649, 0xCAB1, 0xA64A, 0xCAB2, 0xA64B, 0xCAB3, 0xA64C,
+	0xCAB4, 0xA64D, 0xCAB5, 0xA64E, 0xCAB6, 0xA64F, 0xCAB7, 0xA650,
+	0xCAB8, 0xA651, 0xCAB9, 0xA652, 0xCABA, 0xA653, 0xCABB, 0xA654,
+	0xCABC, 0xC2C9, 0xCABD, 0xC2CA, 0xCABE, 0xA655, 0xCABF, 0xA656,
+	0xCAC0, 0xC2CB, 0xCAC1, 0xA657, 0xCAC2, 0xA658, 0xCAC3, 0xA659,
+	0xCAC4, 0xC2CC, 0xCAC5, 0xA65A, 0xCAC6, 0xA661, 0xCAC7, 0xA662,
+	0xCAC8, 0xA663, 0xCAC9, 0xA664, 0xCACA, 0xA665, 0xCACB, 0xA666,
+	0xCACC, 0xC2CD, 0xCACD, 0xC2CE, 0xCACE, 0xA667, 0xCACF, 0xC2CF,
+	0xCAD0, 0xA668, 0xCAD1, 0xC2D0, 0xCAD2, 0xA669, 0xCAD3, 0xC2D1,
+	0xCAD4, 0xA66A, 0xCAD5, 0xA66B, 0xCAD6, 0xA66C, 0xCAD7, 0xA66D,
+	0xCAD8, 0xC2D2, 0xCAD9, 0xC2D3, 0xCADA, 0xA66E, 0xCADB, 0xA66F,
+	0xCADC, 0xA670, 0xCADD, 0xA671, 0xCADE, 0xA672, 0xCADF, 0xA673,
+	0xCAE0, 0xC2D4, 0xCAE1, 0xA674, 0xCAE2, 0xA675, 0xCAE3, 0xA676,
+	0xCAE4, 0xA677, 0xCAE5, 0xA678, 0xCAE6, 0xA679, 0xCAE7, 0xA67A,
+	0xCAE8, 0xA681, 0xCAE9, 0xA682, 0xCAEA, 0xA683, 0xCAEB, 0xA684,
+	0xCAEC, 0xC2D5, 0xCAED, 0xA685, 0xCAEE, 0xA686, 0xCAEF, 0xA687,
+	0xCAF0, 0xA688, 0xCAF1, 0xA689, 0xCAF2, 0xA68A, 0xCAF3, 0xA68B,
+	0xCAF4, 0xC2D6, 0xCAF5, 0xA68C, 0xCAF6, 0xA68D, 0xCAF7, 0xA68E,
+	0xCAF8, 0xA68F, 0xCAF9, 0xA690, 0xCAFA, 0xA691, 0xCAFB, 0xA692,
+	0xCAFC, 0xA693, 0xCAFD, 0xA694, 0xCAFE, 0xA695, 0xCAFF, 0xA696,
+	0xCB00, 0xA697, 0xCB01, 0xA698, 0xCB02, 0xA699, 0xCB03, 0xA69A,
+	0xCB04, 0xA69B, 0xCB05, 0xA69C, 0xCB06, 0xA69D, 0xCB07, 0xA69E,
+	0xCB08, 0xC2D7, 0xCB09, 0xA69F, 0xCB0A, 0xA6A0, 0xCB0B, 0xA741,
+	0xCB0C, 0xA742, 0xCB0D, 0xA743, 0xCB0E, 0xA744, 0xCB0F, 0xA745,
+	0xCB10, 0xC2D8, 0xCB11, 0xA746, 0xCB12, 0xA747, 0xCB13, 0xA748,
+	0xCB14, 0xC2D9, 0xCB15, 0xA749, 0xCB16, 0xA74A, 0xCB17, 0xA74B,
+	0xCB18, 0xC2DA, 0xCB19, 0xA74C, 0xCB1A, 0xA74D, 0xCB1B, 0xA74E,
+	0xCB1C, 0xA74F, 0xCB1D, 0xA750, 0xCB1E, 0xA751, 0xCB1F, 0xA752,
+	0xCB20, 0xC2DB, 0xCB21, 0xC2DC, 0xCB22, 0xA753, 0xCB23, 0xA754,
+	0xCB24, 0xA755, 0xCB25, 0xA756, 0xCB26, 0xA757, 0xCB27, 0xA758,
+	0xCB28, 0xA759, 0xCB29, 0xA75A, 0xCB2A, 0xA761, 0xCB2B, 0xA762,
+	0xCB2C, 0xA763, 0xCB2D, 0xA764, 0xCB2E, 0xA765, 0xCB2F, 0xA766,
+	0xCB30, 0xA767, 0xCB31, 0xA768, 0xCB32, 0xA769, 0xCB33, 0xA76A,
+	0xCB34, 0xA76B, 0xCB35, 0xA76C, 0xCB36, 0xA76D, 0xCB37, 0xA76E,
+	0xCB38, 0xA76F, 0xCB39, 0xA770, 0xCB3A, 0xA771, 0xCB3B, 0xA772,
+	0xCB3C, 0xA773, 0xCB3D, 0xA774, 0xCB3E, 0xA775, 0xCB3F, 0xA776,
+	0xCB40, 0xA777, 0xCB41, 0xC2DD, 0xCB42, 0xA778, 0xCB43, 0xA779,
+	0xCB44, 0xA77A, 0xCB45, 0xA781, 0xCB46, 0xA782, 0xCB47, 0xA783,
+	0xCB48, 0xC2DE, 0xCB49, 0xC2DF, 0xCB4A, 0xA784, 0xCB4B, 0xA785,
+	0xCB4C, 0xC2E0, 0xCB4D, 0xA786, 0xCB4E, 0xA787, 0xCB4F, 0xA788,
+	0xCB50, 0xC2E1, 0xCB51, 0xA789, 0xCB52, 0xA78A, 0xCB53, 0xA78B,
+	0xCB54, 0xA78C, 0xCB55, 0xA78D, 0xCB56, 0xA78E, 0xCB57, 0xA78F,
+	0xCB58, 0xC2E2, 0xCB59, 0xC2E3, 0xCB5A, 0xA790, 0xCB5B, 0xA791,
+	0xCB5C, 0xA792, 0xCB5D, 0xC2E4, 0xCB5E, 0xA793, 0xCB5F, 0xA794,
+	0xCB60, 0xA795, 0xCB61, 0xA796, 0xCB62, 0xA797, 0xCB63, 0xA798,
+	0xCB64, 0xC2E5, 0xCB65, 0xA799, 0xCB66, 0xA79A, 0xCB67, 0xA79B,
+	0xCB68, 0xA79C, 0xCB69, 0xA79D, 0xCB6A, 0xA79E, 0xCB6B, 0xA79F,
+	0xCB6C, 0xA7A0, 0xCB6D, 0xA841, 0xCB6E, 0xA842, 0xCB6F, 0xA843,
+	0xCB70, 0xA844, 0xCB71, 0xA845, 0xCB72, 0xA846, 0xCB73, 0xA847,
+	0xCB74, 0xA848, 0xCB75, 0xA849, 0xCB76, 0xA84A, 0xCB77, 0xA84B,
+	0xCB78, 0xC2E6, 0xCB79, 0xC2E7, 0xCB7A, 0xA84C, 0xCB7B, 0xA84D,
+	0xCB7C, 0xA84E, 0xCB7D, 0xA84F, 0xCB7E, 0xA850, 0xCB7F, 0xA851,
+	0xCB80, 0xA852, 0xCB81, 0xA853, 0xCB82, 0xA854, 0xCB83, 0xA855,
+	0xCB84, 0xA856, 0xCB85, 0xA857, 0xCB86, 0xA858, 0xCB87, 0xA859,
+	0xCB88, 0xA85A, 0xCB89, 0xA861, 0xCB8A, 0xA862, 0xCB8B, 0xA863,
+	0xCB8C, 0xA864, 0xCB8D, 0xA865, 0xCB8E, 0xA866, 0xCB8F, 0xA867,
+	0xCB90, 0xA868, 0xCB91, 0xA869, 0xCB92, 0xA86A, 0xCB93, 0xA86B,
+	0xCB94, 0xA86C, 0xCB95, 0xA86D, 0xCB96, 0xA86E, 0xCB97, 0xA86F,
+	0xCB98, 0xA870, 0xCB99, 0xA871, 0xCB9A, 0xA872, 0xCB9B, 0xA873,
+	0xCB9C, 0xC2E8, 0xCB9D, 0xA874, 0xCB9E, 0xA875, 0xCB9F, 0xA876,
+	0xCBA0, 0xA877, 0xCBA1, 0xA878, 0xCBA2, 0xA879, 0xCBA3, 0xA87A,
+	0xCBA4, 0xA881, 0xCBA5, 0xA882, 0xCBA6, 0xA883, 0xCBA7, 0xA884,
+	0xCBA8, 0xA885, 0xCBA9, 0xA886, 0xCBAA, 0xA887, 0xCBAB, 0xA888,
+	0xCBAC, 0xA889, 0xCBAD, 0xA88A, 0xCBAE, 0xA88B, 0xCBAF, 0xA88C,
+	0xCBB0, 0xA88D, 0xCBB1, 0xA88E, 0xCBB2, 0xA88F, 0xCBB3, 0xA890,
+	0xCBB4, 0xA891, 0xCBB5, 0xA892, 0xCBB6, 0xA893, 0xCBB7, 0xA894,
+	0xCBB8, 0xC2E9, 0xCBB9, 0xA895, 0xCBBA, 0xA896, 0xCBBB, 0xA897,
+	0xCBBC, 0xA898, 0xCBBD, 0xA899, 0xCBBE, 0xA89A, 0xCBBF, 0xA89B,
+	0xCBC0, 0xA89C, 0xCBC1, 0xA89D, 0xCBC2, 0xA89E, 0xCBC3, 0xA89F,
+	0xCBC4, 0xA8A0, 0xCBC5, 0xA941, 0xCBC6, 0xA942, 0xCBC7, 0xA943,
+	0xCBC8, 0xA944, 0xCBC9, 0xA945, 0xCBCA, 0xA946, 0xCBCB, 0xA947,
+	0xCBCC, 0xA948, 0xCBCD, 0xA949, 0xCBCE, 0xA94A, 0xCBCF, 0xA94B,
+	0xCBD0, 0xA94C, 0xCBD1, 0xA94D, 0xCBD2, 0xA94E, 0xCBD3, 0xA94F,
+	0xCBD4, 0xC2EA, 0xCBD5, 0xA950, 0xCBD6, 0xA951, 0xCBD7, 0xA952,
+	0xCBD8, 0xA953, 0xCBD9, 0xA954, 0xCBDA, 0xA955, 0xCBDB, 0xA956,
+	0xCBDC, 0xA957, 0xCBDD, 0xA958, 0xCBDE, 0xA959, 0xCBDF, 0xA95A,
+	0xCBE0, 0xA961, 0xCBE1, 0xA962, 0xCBE2, 0xA963, 0xCBE3, 0xA964,
+	0xCBE4, 0xC2EB, 0xCBE5, 0xA965, 0xCBE6, 0xA966, 0xCBE7, 0xC2EC,
+	0xCBE8, 0xA967, 0xCBE9, 0xC2ED, 0xCBEA, 0xA968, 0xCBEB, 0xA969,
+	0xCBEC, 0xA96A, 0xCBED, 0xA96B, 0xCBEE, 0xA96C, 0xCBEF, 0xA96D,
+	0xCBF0, 0xA96E, 0xCBF1, 0xA96F, 0xCBF2, 0xA970, 0xCBF3, 0xA971,
+	0xCBF4, 0xA972, 0xCBF5, 0xA973, 0xCBF6, 0xA974, 0xCBF7, 0xA975,
+	0xCBF8, 0xA976, 0xCBF9, 0xA977, 0xCBFA, 0xA978, 0xCBFB, 0xA979,
+	0xCBFC, 0xA97A, 0xCBFD, 0xA981, 0xCBFE, 0xA982, 0xCBFF, 0xA983,
+	0xCC00, 0xA984, 0xCC01, 0xA985, 0xCC02, 0xA986, 0xCC03, 0xA987,
+	0xCC04, 0xA988, 0xCC05, 0xA989, 0xCC06, 0xA98A, 0xCC07, 0xA98B,
+	0xCC08, 0xA98C, 0xCC09, 0xA98D, 0xCC0A, 0xA98E, 0xCC0B, 0xA98F,
+	0xCC0C, 0xC2EE, 0xCC0D, 0xC2EF, 0xCC0E, 0xA990, 0xCC0F, 0xA991,
+	0xCC10, 0xC2F0, 0xCC11, 0xA992, 0xCC12, 0xA993, 0xCC13, 0xA994,
+	0xCC14, 0xC2F1, 0xCC15, 0xA995, 0xCC16, 0xA996, 0xCC17, 0xA997,
+	0xCC18, 0xA998, 0xCC19, 0xA999, 0xCC1A, 0xA99A, 0xCC1B, 0xA99B,
+	0xCC1C, 0xC2F2, 0xCC1D, 0xC2F3, 0xCC1E, 0xA99C, 0xCC1F, 0xA99D,
+	0xCC20, 0xA99E, 0xCC21, 0xC2F4, 0xCC22, 0xC2F5, 0xCC23, 0xA99F,
+	0xCC24, 0xA9A0, 0xCC25, 0xAA41, 0xCC26, 0xAA42, 0xCC27, 0xC2F6,
+	0xCC28, 0xC2F7, 0xCC29, 0xC2F8, 0xCC2A, 0xAA43, 0xCC2B, 0xAA44,
+	0xCC2C, 0xC2F9, 0xCC2D, 0xAA45, 0xCC2E, 0xC2FA, 0xCC2F, 0xAA46,
+	0xCC30, 0xC2FB, 0xCC31, 0xAA47, 0xCC32, 0xAA48, 0xCC33, 0xAA49,
+	0xCC34, 0xAA4A, 0xCC35, 0xAA4B, 0xCC36, 0xAA4C, 0xCC37, 0xAA4D,
+	0xCC38, 0xC2FC, 0xCC39, 0xC2FD, 0xCC3A, 0xAA4E, 0xCC3B, 0xC2FE,
+	0xCC3C, 0xC3A1, 0xCC3D, 0xC3A2, 0xCC3E, 0xC3A3, 0xCC3F, 0xAA4F,
+	0xCC40, 0xAA50, 0xCC41, 0xAA51, 0xCC42, 0xAA52, 0xCC43, 0xAA53,
+	0xCC44, 0xC3A4, 0xCC45, 0xC3A5, 0xCC46, 0xAA54, 0xCC47, 0xAA55,
+	0xCC48, 0xC3A6, 0xCC49, 0xAA56, 0xCC4A, 0xAA57, 0xCC4B, 0xAA58,
+	0xCC4C, 0xC3A7, 0xCC4D, 0xAA59, 0xCC4E, 0xAA5A, 0xCC4F, 0xAA61,
+	0xCC50, 0xAA62, 0xCC51, 0xAA63, 0xCC52, 0xAA64, 0xCC53, 0xAA65,
+	0xCC54, 0xC3A8, 0xCC55, 0xC3A9, 0xCC56, 0xAA66, 0xCC57, 0xC3AA,
+	0xCC58, 0xC3AB, 0xCC59, 0xC3AC, 0xCC5A, 0xAA67, 0xCC5B, 0xAA68,
+	0xCC5C, 0xAA69, 0xCC5D, 0xAA6A, 0xCC5E, 0xAA6B, 0xCC5F, 0xAA6C,
+	0xCC60, 0xC3AD, 0xCC61, 0xAA6D, 0xCC62, 0xAA6E, 0xCC63, 0xAA6F,
+	0xCC64, 0xC3AE, 0xCC65, 0xAA70, 0xCC66, 0xC3AF, 0xCC67, 0xAA71,
+	0xCC68, 0xC3B0, 0xCC69, 0xAA72, 0xCC6A, 0xAA73, 0xCC6B, 0xAA74,
+	0xCC6C, 0xAA75, 0xCC6D, 0xAA76, 0xCC6E, 0xAA77, 0xCC6F, 0xAA78,
+	0xCC70, 0xC3B1, 0xCC71, 0xAA79, 0xCC72, 0xAA7A, 0xCC73, 0xAA81,
+	0xCC74, 0xAA82, 0xCC75, 0xC3B2, 0xCC76, 0xAA83, 0xCC77, 0xAA84,
+	0xCC78, 0xAA85, 0xCC79, 0xAA86, 0xCC7A, 0xAA87, 0xCC7B, 0xAA88,
+	0xCC7C, 0xAA89, 0xCC7D, 0xAA8A, 0xCC7E, 0xAA8B, 0xCC7F, 0xAA8C,
+	0xCC80, 0xAA8D, 0xCC81, 0xAA8E, 0xCC82, 0xAA8F, 0xCC83, 0xAA90,
+	0xCC84, 0xAA91, 0xCC85, 0xAA92, 0xCC86, 0xAA93, 0xCC87, 0xAA94,
+	0xCC88, 0xAA95, 0xCC89, 0xAA96, 0xCC8A, 0xAA97, 0xCC8B, 0xAA98,
+	0xCC8C, 0xAA99, 0xCC8D, 0xAA9A, 0xCC8E, 0xAA9B, 0xCC8F, 0xAA9C,
+	0xCC90, 0xAA9D, 0xCC91, 0xAA9E, 0xCC92, 0xAA9F, 0xCC93, 0xAAA0,
+	0xCC94, 0xAB41, 0xCC95, 0xAB42, 0xCC96, 0xAB43, 0xCC97, 0xAB44,
+	0xCC98, 0xC3B3, 0xCC99, 0xC3B4, 0xCC9A, 0xAB45, 0xCC9B, 0xAB46,
+	0xCC9C, 0xC3B5, 0xCC9D, 0xAB47, 0xCC9E, 0xAB48, 0xCC9F, 0xAB49,
+	0xCCA0, 0xC3B6, 0xCCA1, 0xAB4A, 0xCCA2, 0xAB4B, 0xCCA3, 0xAB4C,
+	0xCCA4, 0xAB4D, 0xCCA5, 0xAB4E, 0xCCA6, 0xAB4F, 0xCCA7, 0xAB50,
+	0xCCA8, 0xC3B7, 0xCCA9, 0xC3B8, 0xCCAA, 0xAB51, 0xCCAB, 0xC3B9,
+	0xCCAC, 0xC3BA, 0xCCAD, 0xC3BB, 0xCCAE, 0xAB52, 0xCCAF, 0xAB53,
+	0xCCB0, 0xAB54, 0xCCB1, 0xAB55, 0xCCB2, 0xAB56, 0xCCB3, 0xAB57,
+	0xCCB4, 0xC3BC, 0xCCB5, 0xC3BD, 0xCCB6, 0xAB58, 0xCCB7, 0xAB59,
+	0xCCB8, 0xC3BE, 0xCCB9, 0xAB5A, 0xCCBA, 0xAB61, 0xCCBB, 0xAB62,
+	0xCCBC, 0xC3BF, 0xCCBD, 0xAB63, 0xCCBE, 0xAB64, 0xCCBF, 0xAB65,
+	0xCCC0, 0xAB66, 0xCCC1, 0xAB67, 0xCCC2, 0xAB68, 0xCCC3, 0xAB69,
+	0xCCC4, 0xC3C0, 0xCCC5, 0xC3C1, 0xCCC6, 0xAB6A, 0xCCC7, 0xC3C2,
+	0xCCC8, 0xAB6B, 0xCCC9, 0xC3C3, 0xCCCA, 0xAB6C, 0xCCCB, 0xAB6D,
+	0xCCCC, 0xAB6E, 0xCCCD, 0xAB6F, 0xCCCE, 0xAB70, 0xCCCF, 0xAB71,
+	0xCCD0, 0xC3C4, 0xCCD1, 0xAB72, 0xCCD2, 0xAB73, 0xCCD3, 0xAB74,
+	0xCCD4, 0xC3C5, 0xCCD5, 0xAB75, 0xCCD6, 0xAB76, 0xCCD7, 0xAB77,
+	0xCCD8, 0xAB78, 0xCCD9, 0xAB79, 0xCCDA, 0xAB7A, 0xCCDB, 0xAB81,
+	0xCCDC, 0xAB82, 0xCCDD, 0xAB83, 0xCCDE, 0xAB84, 0xCCDF, 0xAB85,
+	0xCCE0, 0xAB86, 0xCCE1, 0xAB87, 0xCCE2, 0xAB88, 0xCCE3, 0xAB89,
+	0xCCE4, 0xC3C6, 0xCCE5, 0xAB8A, 0xCCE6, 0xAB8B, 0xCCE7, 0xAB8C,
+	0xCCE8, 0xAB8D, 0xCCE9, 0xAB8E, 0xCCEA, 0xAB8F, 0xCCEB, 0xAB90,
+	0xCCEC, 0xC3C7, 0xCCED, 0xAB91, 0xCCEE, 0xAB92, 0xCCEF, 0xAB93,
+	0xCCF0, 0xC3C8, 0xCCF1, 0xAB94, 0xCCF2, 0xAB95, 0xCCF3, 0xAB96,
+	0xCCF4, 0xAB97, 0xCCF5, 0xAB98, 0xCCF6, 0xAB99, 0xCCF7, 0xAB9A,
+	0xCCF8, 0xAB9B, 0xCCF9, 0xAB9C, 0xCCFA, 0xAB9D, 0xCCFB, 0xAB9E,
+	0xCCFC, 0xAB9F, 0xCCFD, 0xABA0, 0xCCFE, 0xAC41, 0xCCFF, 0xAC42,
+	0xCD00, 0xAC43, 0xCD01, 0xC3C9, 0xCD02, 0xAC44, 0xCD03, 0xAC45,
+	0xCD04, 0xAC46, 0xCD05, 0xAC47, 0xCD06, 0xAC48, 0xCD07, 0xAC49,
+	0xCD08, 0xC3CA, 0xCD09, 0xC3CB, 0xCD0A, 0xAC4A, 0xCD0B, 0xAC4B,
+	0xCD0C, 0xC3CC, 0xCD0D, 0xAC4C, 0xCD0E, 0xAC4D, 0xCD0F, 0xAC4E,
+	0xCD10, 0xC3CD, 0xCD11, 0xAC4F, 0xCD12, 0xAC50, 0xCD13, 0xAC51,
+	0xCD14, 0xAC52, 0xCD15, 0xAC53, 0xCD16, 0xAC54, 0xCD17, 0xAC55,
+	0xCD18, 0xC3CE, 0xCD19, 0xC3CF, 0xCD1A, 0xAC56, 0xCD1B, 0xC3D0,
+	0xCD1C, 0xAC57, 0xCD1D, 0xC3D1, 0xCD1E, 0xAC58, 0xCD1F, 0xAC59,
+	0xCD20, 0xAC5A, 0xCD21, 0xAC61, 0xCD22, 0xAC62, 0xCD23, 0xAC63,
+	0xCD24, 0xC3D2, 0xCD25, 0xAC64, 0xCD26, 0xAC65, 0xCD27, 0xAC66,
+	0xCD28, 0xC3D3, 0xCD29, 0xAC67, 0xCD2A, 0xAC68, 0xCD2B, 0xAC69,
+	0xCD2C, 0xC3D4, 0xCD2D, 0xAC6A, 0xCD2E, 0xAC6B, 0xCD2F, 0xAC6C,
+	0xCD30, 0xAC6D, 0xCD31, 0xAC6E, 0xCD32, 0xAC6F, 0xCD33, 0xAC70,
+	0xCD34, 0xAC71, 0xCD35, 0xAC72, 0xCD36, 0xAC73, 0xCD37, 0xAC74,
+	0xCD38, 0xAC75, 0xCD39, 0xC3D5, 0xCD3A, 0xAC76, 0xCD3B, 0xAC77,
+	0xCD3C, 0xAC78, 0xCD3D, 0xAC79, 0xCD3E, 0xAC7A, 0xCD3F, 0xAC81,
+	0xCD40, 0xAC82, 0xCD41, 0xAC83, 0xCD42, 0xAC84, 0xCD43, 0xAC85,
+	0xCD44, 0xAC86, 0xCD45, 0xAC87, 0xCD46, 0xAC88, 0xCD47, 0xAC89,
+	0xCD48, 0xAC8A, 0xCD49, 0xAC8B, 0xCD4A, 0xAC8C, 0xCD4B, 0xAC8D,
+	0xCD4C, 0xAC8E, 0xCD4D, 0xAC8F, 0xCD4E, 0xAC90, 0xCD4F, 0xAC91,
+	0xCD50, 0xAC92, 0xCD51, 0xAC93, 0xCD52, 0xAC94, 0xCD53, 0xAC95,
+	0xCD54, 0xAC96, 0xCD55, 0xAC97, 0xCD56, 0xAC98, 0xCD57, 0xAC99,
+	0xCD58, 0xAC9A, 0xCD59, 0xAC9B, 0xCD5A, 0xAC9C, 0xCD5B, 0xAC9D,
+	0xCD5C, 0xC3D6, 0xCD5D, 0xAC9E, 0xCD5E, 0xAC9F, 0xCD5F, 0xACA0,
+	0xCD60, 0xC3D7, 0xCD61, 0xAD41, 0xCD62, 0xAD42, 0xCD63, 0xAD43,
+	0xCD64, 0xC3D8, 0xCD65, 0xAD44, 0xCD66, 0xAD45, 0xCD67, 0xAD46,
+	0xCD68, 0xAD47, 0xCD69, 0xAD48, 0xCD6A, 0xAD49, 0xCD6B, 0xAD4A,
+	0xCD6C, 0xC3D9, 0xCD6D, 0xC3DA, 0xCD6E, 0xAD4B, 0xCD6F, 0xC3DB,
+	0xCD70, 0xAD4C, 0xCD71, 0xC3DC, 0xCD72, 0xAD4D, 0xCD73, 0xAD4E,
+	0xCD74, 0xAD4F, 0xCD75, 0xAD50, 0xCD76, 0xAD51, 0xCD77, 0xAD52,
+	0xCD78, 0xC3DD, 0xCD79, 0xAD53, 0xCD7A, 0xAD54, 0xCD7B, 0xAD55,
+	0xCD7C, 0xAD56, 0xCD7D, 0xAD57, 0xCD7E, 0xAD58, 0xCD7F, 0xAD59,
+	0xCD80, 0xAD5A, 0xCD81, 0xAD61, 0xCD82, 0xAD62, 0xCD83, 0xAD63,
+	0xCD84, 0xAD64, 0xCD85, 0xAD65, 0xCD86, 0xAD66, 0xCD87, 0xAD67,
+	0xCD88, 0xC3DE, 0xCD89, 0xAD68, 0xCD8A, 0xAD69, 0xCD8B, 0xAD6A,
+	0xCD8C, 0xAD6B, 0xCD8D, 0xAD6C, 0xCD8E, 0xAD6D, 0xCD8F, 0xAD6E,
+	0xCD90, 0xAD6F, 0xCD91, 0xAD70, 0xCD92, 0xAD71, 0xCD93, 0xAD72,
+	0xCD94, 0xC3DF, 0xCD95, 0xC3E0, 0xCD96, 0xAD73, 0xCD97, 0xAD74,
+	0xCD98, 0xC3E1, 0xCD99, 0xAD75, 0xCD9A, 0xAD76, 0xCD9B, 0xAD77,
+	0xCD9C, 0xC3E2, 0xCD9D, 0xAD78, 0xCD9E, 0xAD79, 0xCD9F, 0xAD7A,
+	0xCDA0, 0xAD81, 0xCDA1, 0xAD82, 0xCDA2, 0xAD83, 0xCDA3, 0xAD84,
+	0xCDA4, 0xC3E3, 0xCDA5, 0xC3E4, 0xCDA6, 0xAD85, 0xCDA7, 0xC3E5,
+	0xCDA8, 0xAD86, 0xCDA9, 0xC3E6, 0xCDAA, 0xAD87, 0xCDAB, 0xAD88,
+	0xCDAC, 0xAD89, 0xCDAD, 0xAD8A, 0xCDAE, 0xAD8B, 0xCDAF, 0xAD8C,
+	0xCDB0, 0xC3E7, 0xCDB1, 0xAD8D, 0xCDB2, 0xAD8E, 0xCDB3, 0xAD8F,
+	0xCDB4, 0xAD90, 0xCDB5, 0xAD91, 0xCDB6, 0xAD92, 0xCDB7, 0xAD93,
+	0xCDB8, 0xAD94, 0xCDB9, 0xAD95, 0xCDBA, 0xAD96, 0xCDBB, 0xAD97,
+	0xCDBC, 0xAD98, 0xCDBD, 0xAD99, 0xCDBE, 0xAD9A, 0xCDBF, 0xAD9B,
+	0xCDC0, 0xAD9C, 0xCDC1, 0xAD9D, 0xCDC2, 0xAD9E, 0xCDC3, 0xAD9F,
+	0xCDC4, 0xC3E8, 0xCDC5, 0xADA0, 0xCDC6, 0xAE41, 0xCDC7, 0xAE42,
+	0xCDC8, 0xAE43, 0xCDC9, 0xAE44, 0xCDCA, 0xAE45, 0xCDCB, 0xAE46,
+	0xCDCC, 0xC3E9, 0xCDCD, 0xAE47, 0xCDCE, 0xAE48, 0xCDCF, 0xAE49,
+	0xCDD0, 0xC3EA, 0xCDD1, 0xAE4A, 0xCDD2, 0xAE4B, 0xCDD3, 0xAE4C,
+	0xCDD4, 0xAE4D, 0xCDD5, 0xAE4E, 0xCDD6, 0xAE4F, 0xCDD7, 0xAE50,
+	0xCDD8, 0xAE51, 0xCDD9, 0xAE52, 0xCDDA, 0xAE53, 0xCDDB, 0xAE54,
+	0xCDDC, 0xAE55, 0xCDDD, 0xAE56, 0xCDDE, 0xAE57, 0xCDDF, 0xAE58,
+	0xCDE0, 0xAE59, 0xCDE1, 0xAE5A, 0xCDE2, 0xAE61, 0xCDE3, 0xAE62,
+	0xCDE4, 0xAE63, 0xCDE5, 0xAE64, 0xCDE6, 0xAE65, 0xCDE7, 0xAE66,
+	0xCDE8, 0xC3EB, 0xCDE9, 0xAE67, 0xCDEA, 0xAE68, 0xCDEB, 0xAE69,
+	0xCDEC, 0xC3EC, 0xCDED, 0xAE6A, 0xCDEE, 0xAE6B, 0xCDEF, 0xAE6C,
+	0xCDF0, 0xC3ED, 0xCDF1, 0xAE6D, 0xCDF2, 0xAE6E, 0xCDF3, 0xAE6F,
+	0xCDF4, 0xAE70, 0xCDF5, 0xAE71, 0xCDF6, 0xAE72, 0xCDF7, 0xAE73,
+	0xCDF8, 0xC3EE, 0xCDF9, 0xC3EF, 0xCDFA, 0xAE74, 0xCDFB, 0xC3F0,
+	0xCDFC, 0xAE75, 0xCDFD, 0xC3F1, 0xCDFE, 0xAE76, 0xCDFF, 0xAE77,
+	0xCE00, 0xAE78, 0xCE01, 0xAE79, 0xCE02, 0xAE7A, 0xCE03, 0xAE81,
+	0xCE04, 0xC3F2, 0xCE05, 0xAE82, 0xCE06, 0xAE83, 0xCE07, 0xAE84,
+	0xCE08, 0xC3F3, 0xCE09, 0xAE85, 0xCE0A, 0xAE86, 0xCE0B, 0xAE87,
+	0xCE0C, 0xC3F4, 0xCE0D, 0xAE88, 0xCE0E, 0xAE89, 0xCE0F, 0xAE8A,
+	0xCE10, 0xAE8B, 0xCE11, 0xAE8C, 0xCE12, 0xAE8D, 0xCE13, 0xAE8E,
+	0xCE14, 0xC3F5, 0xCE15, 0xAE8F, 0xCE16, 0xAE90, 0xCE17, 0xAE91,
+	0xCE18, 0xAE92, 0xCE19, 0xC3F6, 0xCE1A, 0xAE93, 0xCE1B, 0xAE94,
+	0xCE1C, 0xAE95, 0xCE1D, 0xAE96, 0xCE1E, 0xAE97, 0xCE1F, 0xAE98,
+	0xCE20, 0xC3F7, 0xCE21, 0xC3F8, 0xCE22, 0xAE99, 0xCE23, 0xAE9A,
+	0xCE24, 0xC3F9, 0xCE25, 0xAE9B, 0xCE26, 0xAE9C, 0xCE27, 0xAE9D,
+	0xCE28, 0xC3FA, 0xCE29, 0xAE9E, 0xCE2A, 0xAE9F, 0xCE2B, 0xAEA0,
+	0xCE2C, 0xAF41, 0xCE2D, 0xAF42, 0xCE2E, 0xAF43, 0xCE2F, 0xAF44,
+	0xCE30, 0xC3FB, 0xCE31, 0xC3FC, 0xCE32, 0xAF45, 0xCE33, 0xC3FD,
+	0xCE34, 0xAF46, 0xCE35, 0xC3FE, 0xCE36, 0xAF47, 0xCE37, 0xAF48,
+	0xCE38, 0xAF49, 0xCE39, 0xAF4A, 0xCE3A, 0xAF4B, 0xCE3B, 0xAF4C,
+	0xCE3C, 0xAF4D, 0xCE3D, 0xAF4E, 0xCE3E, 0xAF4F, 0xCE3F, 0xAF50,
+	0xCE40, 0xAF51, 0xCE41, 0xAF52, 0xCE42, 0xAF53, 0xCE43, 0xAF54,
+	0xCE44, 0xAF55, 0xCE45, 0xAF56, 0xCE46, 0xAF57, 0xCE47, 0xAF58,
+	0xCE48, 0xAF59, 0xCE49, 0xAF5A, 0xCE4A, 0xAF61, 0xCE4B, 0xAF62,
+	0xCE4C, 0xAF63, 0xCE4D, 0xAF64, 0xCE4E, 0xAF65, 0xCE4F, 0xAF66,
+	0xCE50, 0xAF67, 0xCE51, 0xAF68, 0xCE52, 0xAF69, 0xCE53, 0xAF6A,
+	0xCE54, 0xAF6B, 0xCE55, 0xAF6C, 0xCE56, 0xAF6D, 0xCE57, 0xAF6E,
+	0xCE58, 0xC4A1, 0xCE59, 0xC4A2, 0xCE5A, 0xAF6F, 0xCE5B, 0xAF70,
+	0xCE5C, 0xC4A3, 0xCE5D, 0xAF71, 0xCE5E, 0xAF72, 0xCE5F, 0xC4A4,
+	0xCE60, 0xC4A5, 0xCE61, 0xC4A6, 0xCE62, 0xAF73, 0xCE63, 0xAF74,
+	0xCE64, 0xAF75, 0xCE65, 0xAF76, 0xCE66, 0xAF77, 0xCE67, 0xAF78,
+	0xCE68, 0xC4A7, 0xCE69, 0xC4A8, 0xCE6A, 0xAF79, 0xCE6B, 0xC4A9,
+	0xCE6C, 0xAF7A, 0xCE6D, 0xC4AA, 0xCE6E, 0xAF81, 0xCE6F, 0xAF82,
+	0xCE70, 0xAF83, 0xCE71, 0xAF84, 0xCE72, 0xAF85, 0xCE73, 0xAF86,
+	0xCE74, 0xC4AB, 0xCE75, 0xC4AC, 0xCE76, 0xAF87, 0xCE77, 0xAF88,
+	0xCE78, 0xC4AD, 0xCE79, 0xAF89, 0xCE7A, 0xAF8A, 0xCE7B, 0xAF8B,
+	0xCE7C, 0xC4AE, 0xCE7D, 0xAF8C, 0xCE7E, 0xAF8D, 0xCE7F, 0xAF8E,
+	0xCE80, 0xAF8F, 0xCE81, 0xAF90, 0xCE82, 0xAF91, 0xCE83, 0xAF92,
+	0xCE84, 0xC4AF, 0xCE85, 0xC4B0, 0xCE86, 0xAF93, 0xCE87, 0xC4B1,
+	0xCE88, 0xAF94, 0xCE89, 0xC4B2, 0xCE8A, 0xAF95, 0xCE8B, 0xAF96,
+	0xCE8C, 0xAF97, 0xCE8D, 0xAF98, 0xCE8E, 0xAF99, 0xCE8F, 0xAF9A,
+	0xCE90, 0xC4B3, 0xCE91, 0xC4B4, 0xCE92, 0xAF9B, 0xCE93, 0xAF9C,
+	0xCE94, 0xC4B5, 0xCE95, 0xAF9D, 0xCE96, 0xAF9E, 0xCE97, 0xAF9F,
+	0xCE98, 0xC4B6, 0xCE99, 0xAFA0, 0xCE9A, 0xB041, 0xCE9B, 0xB042,
+	0xCE9C, 0xB043, 0xCE9D, 0xB044, 0xCE9E, 0xB045, 0xCE9F, 0xB046,
+	0xCEA0, 0xC4B7, 0xCEA1, 0xC4B8, 0xCEA2, 0xB047, 0xCEA3, 0xC4B9,
+	0xCEA4, 0xC4BA, 0xCEA5, 0xC4BB, 0xCEA6, 0xB048, 0xCEA7, 0xB049,
+	0xCEA8, 0xB04A, 0xCEA9, 0xB04B, 0xCEAA, 0xB04C, 0xCEAB, 0xB04D,
+	0xCEAC, 0xC4BC, 0xCEAD, 0xC4BD, 0xCEAE, 0xB04E, 0xCEAF, 0xB04F,
+	0xCEB0, 0xB050, 0xCEB1, 0xB051, 0xCEB2, 0xB052, 0xCEB3, 0xB053,
+	0xCEB4, 0xB054, 0xCEB5, 0xB055, 0xCEB6, 0xB056, 0xCEB7, 0xB057,
+	0xCEB8, 0xB058, 0xCEB9, 0xB059, 0xCEBA, 0xB05A, 0xCEBB, 0xB061,
+	0xCEBC, 0xB062, 0xCEBD, 0xB063, 0xCEBE, 0xB064, 0xCEBF, 0xB065,
+	0xCEC0, 0xB066, 0xCEC1, 0xC4BE, 0xCEC2, 0xB067, 0xCEC3, 0xB068,
+	0xCEC4, 0xB069, 0xCEC5, 0xB06A, 0xCEC6, 0xB06B, 0xCEC7, 0xB06C,
+	0xCEC8, 0xB06D, 0xCEC9, 0xB06E, 0xCECA, 0xB06F, 0xCECB, 0xB070,
+	0xCECC, 0xB071, 0xCECD, 0xB072, 0xCECE, 0xB073, 0xCECF, 0xB074,
+	0xCED0, 0xB075, 0xCED1, 0xB076, 0xCED2, 0xB077, 0xCED3, 0xB078,
+	0xCED4, 0xB079, 0xCED5, 0xB07A, 0xCED6, 0xB081, 0xCED7, 0xB082,
+	0xCED8, 0xB083, 0xCED9, 0xB084, 0xCEDA, 0xB085, 0xCEDB, 0xB086,
+	0xCEDC, 0xB087, 0xCEDD, 0xB088, 0xCEDE, 0xB089, 0xCEDF, 0xB08A,
+	0xCEE0, 0xB08B, 0xCEE1, 0xB08C, 0xCEE2, 0xB08D, 0xCEE3, 0xB08E,
+	0xCEE4, 0xC4BF, 0xCEE5, 0xC4C0, 0xCEE6, 0xB08F, 0xCEE7, 0xB090,
+	0xCEE8, 0xC4C1, 0xCEE9, 0xB091, 0xCEEA, 0xB092, 0xCEEB, 0xC4C2,
+	0xCEEC, 0xC4C3, 0xCEED, 0xB093, 0xCEEE, 0xB094, 0xCEEF, 0xB095,
+	0xCEF0, 0xB096, 0xCEF1, 0xB097, 0xCEF2, 0xB098, 0xCEF3, 0xB099,
+	0xCEF4, 0xC4C4, 0xCEF5, 0xC4C5, 0xCEF6, 0xB09A, 0xCEF7, 0xC4C6,
+	0xCEF8, 0xC4C7, 0xCEF9, 0xC4C8, 0xCEFA, 0xB09B, 0xCEFB, 0xB09C,
+	0xCEFC, 0xB09D, 0xCEFD, 0xB09E, 0xCEFE, 0xB09F, 0xCEFF, 0xB0A0,
+	0xCF00, 0xC4C9, 0xCF01, 0xC4CA, 0xCF02, 0xB141, 0xCF03, 0xB142,
+	0xCF04, 0xC4CB, 0xCF05, 0xB143, 0xCF06, 0xB144, 0xCF07, 0xB145,
+	0xCF08, 0xC4CC, 0xCF09, 0xB146, 0xCF0A, 0xB147, 0xCF0B, 0xB148,
+	0xCF0C, 0xB149, 0xCF0D, 0xB14A, 0xCF0E, 0xB14B, 0xCF0F, 0xB14C,
+	0xCF10, 0xC4CD, 0xCF11, 0xC4CE, 0xCF12, 0xB14D, 0xCF13, 0xC4CF,
+	0xCF14, 0xB14E, 0xCF15, 0xC4D0, 0xCF16, 0xB14F, 0xCF17, 0xB150,
+	0xCF18, 0xB151, 0xCF19, 0xB152, 0xCF1A, 0xB153, 0xCF1B, 0xB154,
+	0xCF1C, 0xC4D1, 0xCF1D, 0xB155, 0xCF1E, 0xB156, 0xCF1F, 0xB157,
+	0xCF20, 0xC4D2, 0xCF21, 0xB158, 0xCF22, 0xB159, 0xCF23, 0xB15A,
+	0xCF24, 0xC4D3, 0xCF25, 0xB161, 0xCF26, 0xB162, 0xCF27, 0xB163,
+	0xCF28, 0xB164, 0xCF29, 0xB165, 0xCF2A, 0xB166, 0xCF2B, 0xB167,
+	0xCF2C, 0xC4D4, 0xCF2D, 0xC4D5, 0xCF2E, 0xB168, 0xCF2F, 0xC4D6,
+	0xCF30, 0xC4D7, 0xCF31, 0xC4D8, 0xCF32, 0xB169, 0xCF33, 0xB16A,
+	0xCF34, 0xB16B, 0xCF35, 0xB16C, 0xCF36, 0xB16D, 0xCF37, 0xB16E,
+	0xCF38, 0xC4D9, 0xCF39, 0xB16F, 0xCF3A, 0xB170, 0xCF3B, 0xB171,
+	0xCF3C, 0xB172, 0xCF3D, 0xB173, 0xCF3E, 0xB174, 0xCF3F, 0xB175,
+	0xCF40, 0xB176, 0xCF41, 0xB177, 0xCF42, 0xB178, 0xCF43, 0xB179,
+	0xCF44, 0xB17A, 0xCF45, 0xB181, 0xCF46, 0xB182, 0xCF47, 0xB183,
+	0xCF48, 0xB184, 0xCF49, 0xB185, 0xCF4A, 0xB186, 0xCF4B, 0xB187,
+	0xCF4C, 0xB188, 0xCF4D, 0xB189, 0xCF4E, 0xB18A, 0xCF4F, 0xB18B,
+	0xCF50, 0xB18C, 0xCF51, 0xB18D, 0xCF52, 0xB18E, 0xCF53, 0xB18F,
+	0xCF54, 0xC4DA, 0xCF55, 0xC4DB, 0xCF56, 0xB190, 0xCF57, 0xB191,
+	0xCF58, 0xC4DC, 0xCF59, 0xB192, 0xCF5A, 0xB193, 0xCF5B, 0xB194,
+	0xCF5C, 0xC4DD, 0xCF5D, 0xB195, 0xCF5E, 0xB196, 0xCF5F, 0xB197,
+	0xCF60, 0xB198, 0xCF61, 0xB199, 0xCF62, 0xB19A, 0xCF63, 0xB19B,
+	0xCF64, 0xC4DE, 0xCF65, 0xC4DF, 0xCF66, 0xB19C, 0xCF67, 0xC4E0,
+	0xCF68, 0xB19D, 0xCF69, 0xC4E1, 0xCF6A, 0xB19E, 0xCF6B, 0xB19F,
+	0xCF6C, 0xB1A0, 0xCF6D, 0xB241, 0xCF6E, 0xB242, 0xCF6F, 0xB243,
+	0xCF70, 0xC4E2, 0xCF71, 0xC4E3, 0xCF72, 0xB244, 0xCF73, 0xB245,
+	0xCF74, 0xC4E4, 0xCF75, 0xB246, 0xCF76, 0xB247, 0xCF77, 0xB248,
+	0xCF78, 0xC4E5, 0xCF79, 0xB249, 0xCF7A, 0xB24A, 0xCF7B, 0xB24B,
+	0xCF7C, 0xB24C, 0xCF7D, 0xB24D, 0xCF7E, 0xB24E, 0xCF7F, 0xB24F,
+	0xCF80, 0xC4E6, 0xCF81, 0xB250, 0xCF82, 0xB251, 0xCF83, 0xB252,
+	0xCF84, 0xB253, 0xCF85, 0xC4E7, 0xCF86, 0xB254, 0xCF87, 0xB255,
+	0xCF88, 0xB256, 0xCF89, 0xB257, 0xCF8A, 0xB258, 0xCF8B, 0xB259,
+	0xCF8C, 0xC4E8, 0xCF8D, 0xB25A, 0xCF8E, 0xB261, 0xCF8F, 0xB262,
+	0xCF90, 0xB263, 0xCF91, 0xB264, 0xCF92, 0xB265, 0xCF93, 0xB266,
+	0xCF94, 0xB267, 0xCF95, 0xB268, 0xCF96, 0xB269, 0xCF97, 0xB26A,
+	0xCF98, 0xB26B, 0xCF99, 0xB26C, 0xCF9A, 0xB26D, 0xCF9B, 0xB26E,
+	0xCF9C, 0xB26F, 0xCF9D, 0xB270, 0xCF9E, 0xB271, 0xCF9F, 0xB272,
+	0xCFA0, 0xB273, 0xCFA1, 0xC4E9, 0xCFA2, 0xB274, 0xCFA3, 0xB275,
+	0xCFA4, 0xB276, 0xCFA5, 0xB277, 0xCFA6, 0xB278, 0xCFA7, 0xB279,
+	0xCFA8, 0xC4EA, 0xCFA9, 0xB27A, 0xCFAA, 0xB281, 0xCFAB, 0xB282,
+	0xCFAC, 0xB283, 0xCFAD, 0xB284, 0xCFAE, 0xB285, 0xCFAF, 0xB286,
+	0xCFB0, 0xC4EB, 0xCFB1, 0xB287, 0xCFB2, 0xB288, 0xCFB3, 0xB289,
+	0xCFB4, 0xB28A, 0xCFB5, 0xB28B, 0xCFB6, 0xB28C, 0xCFB7, 0xB28D,
+	0xCFB8, 0xB28E, 0xCFB9, 0xB28F, 0xCFBA, 0xB290, 0xCFBB, 0xB291,
+	0xCFBC, 0xB292, 0xCFBD, 0xB293, 0xCFBE, 0xB294, 0xCFBF, 0xB295,
+	0xCFC0, 0xB296, 0xCFC1, 0xB297, 0xCFC2, 0xB298, 0xCFC3, 0xB299,
+	0xCFC4, 0xC4EC, 0xCFC5, 0xB29A, 0xCFC6, 0xB29B, 0xCFC7, 0xB29C,
+	0xCFC8, 0xB29D, 0xCFC9, 0xB29E, 0xCFCA, 0xB29F, 0xCFCB, 0xB2A0,
+	0xCFCC, 0xB341, 0xCFCD, 0xB342, 0xCFCE, 0xB343, 0xCFCF, 0xB344,
+	0xCFD0, 0xB345, 0xCFD1, 0xB346, 0xCFD2, 0xB347, 0xCFD3, 0xB348,
+	0xCFD4, 0xB349, 0xCFD5, 0xB34A, 0xCFD6, 0xB34B, 0xCFD7, 0xB34C,
+	0xCFD8, 0xB34D, 0xCFD9, 0xB34E, 0xCFDA, 0xB34F, 0xCFDB, 0xB350,
+	0xCFDC, 0xB351, 0xCFDD, 0xB352, 0xCFDE, 0xB353, 0xCFDF, 0xB354,
+	0xCFE0, 0xC4ED, 0xCFE1, 0xC4EE, 0xCFE2, 0xB355, 0xCFE3, 0xB356,
+	0xCFE4, 0xC4EF, 0xCFE5, 0xB357, 0xCFE6, 0xB358, 0xCFE7, 0xB359,
+	0xCFE8, 0xC4F0, 0xCFE9, 0xB35A, 0xCFEA, 0xB361, 0xCFEB, 0xB362,
+	0xCFEC, 0xB363, 0xCFED, 0xB364, 0xCFEE, 0xB365, 0xCFEF, 0xB366,
+	0xCFF0, 0xC4F1, 0xCFF1, 0xC4F2, 0xCFF2, 0xB367, 0xCFF3, 0xC4F3,
+	0xCFF4, 0xB368, 0xCFF5, 0xC4F4, 0xCFF6, 0xB369, 0xCFF7, 0xB36A,
+	0xCFF8, 0xB36B, 0xCFF9, 0xB36C, 0xCFFA, 0xB36D, 0xCFFB, 0xB36E,
+	0xCFFC, 0xC4F5, 0xCFFD, 0xB36F, 0xCFFE, 0xB370, 0xCFFF, 0xB371,
+	0xD000, 0xC4F6, 0xD001, 0xB372, 0xD002, 0xB373, 0xD003, 0xB374,
+	0xD004, 0xC4F7, 0xD005, 0xB375, 0xD006, 0xB376, 0xD007, 0xB377,
+	0xD008, 0xB378, 0xD009, 0xB379, 0xD00A, 0xB37A, 0xD00B, 0xB381,
+	0xD00C, 0xB382, 0xD00D, 0xB383, 0xD00E, 0xB384, 0xD00F, 0xB385,
+	0xD010, 0xB386, 0xD011, 0xC4F8, 0xD012, 0xB387, 0xD013, 0xB388,
+	0xD014, 0xB389, 0xD015, 0xB38A, 0xD016, 0xB38B, 0xD017, 0xB38C,
+	0xD018, 0xC4F9, 0xD019, 0xB38D, 0xD01A, 0xB38E, 0xD01B, 0xB38F,
+	0xD01C, 0xB390, 0xD01D, 0xB391, 0xD01E, 0xB392, 0xD01F, 0xB393,
+	0xD020, 0xB394, 0xD021, 0xB395, 0xD022, 0xB396, 0xD023, 0xB397,
+	0xD024, 0xB398, 0xD025, 0xB399, 0xD026, 0xB39A, 0xD027, 0xB39B,
+	0xD028, 0xB39C, 0xD029, 0xB39D, 0xD02A, 0xB39E, 0xD02B, 0xB39F,
+	0xD02C, 0xB3A0, 0xD02D, 0xC4FA, 0xD02E, 0xB441, 0xD02F, 0xB442,
+	0xD030, 0xB443, 0xD031, 0xB444, 0xD032, 0xB445, 0xD033, 0xB446,
+	0xD034, 0xC4FB, 0xD035, 0xC4FC, 0xD036, 0xB447, 0xD037, 0xB448,
+	0xD038, 0xC4FD, 0xD039, 0xB449, 0xD03A, 0xB44A, 0xD03B, 0xB44B,
+	0xD03C, 0xC4FE, 0xD03D, 0xB44C, 0xD03E, 0xB44D, 0xD03F, 0xB44E,
+	0xD040, 0xB44F, 0xD041, 0xB450, 0xD042, 0xB451, 0xD043, 0xB452,
+	0xD044, 0xC5A1, 0xD045, 0xC5A2, 0xD046, 0xB453, 0xD047, 0xC5A3,
+	0xD048, 0xB454, 0xD049, 0xC5A4, 0xD04A, 0xB455, 0xD04B, 0xB456,
+	0xD04C, 0xB457, 0xD04D, 0xB458, 0xD04E, 0xB459, 0xD04F, 0xB45A,
+	0xD050, 0xC5A5, 0xD051, 0xB461, 0xD052, 0xB462, 0xD053, 0xB463,
+	0xD054, 0xC5A6, 0xD055, 0xB464, 0xD056, 0xB465, 0xD057, 0xB466,
+	0xD058, 0xC5A7, 0xD059, 0xB467, 0xD05A, 0xB468, 0xD05B, 0xB469,
+	0xD05C, 0xB46A, 0xD05D, 0xB46B, 0xD05E, 0xB46C, 0xD05F, 0xB46D,
+	0xD060, 0xC5A8, 0xD061, 0xB46E, 0xD062, 0xB46F, 0xD063, 0xB470,
+	0xD064, 0xB471, 0xD065, 0xB472, 0xD066, 0xB473, 0xD067, 0xB474,
+	0xD068, 0xB475, 0xD069, 0xB476, 0xD06A, 0xB477, 0xD06B, 0xB478,
+	0xD06C, 0xC5A9, 0xD06D, 0xC5AA, 0xD06E, 0xB479, 0xD06F, 0xB47A,
+	0xD070, 0xC5AB, 0xD071, 0xB481, 0xD072, 0xB482, 0xD073, 0xB483,
+	0xD074, 0xC5AC, 0xD075, 0xB484, 0xD076, 0xB485, 0xD077, 0xB486,
+	0xD078, 0xB487, 0xD079, 0xB488, 0xD07A, 0xB489, 0xD07B, 0xB48A,
+	0xD07C, 0xC5AD, 0xD07D, 0xC5AE, 0xD07E, 0xB48B, 0xD07F, 0xB48C,
+	0xD080, 0xB48D, 0xD081, 0xC5AF, 0xD082, 0xB48E, 0xD083, 0xB48F,
+	0xD084, 0xB490, 0xD085, 0xB491, 0xD086, 0xB492, 0xD087, 0xB493,
+	0xD088, 0xB494, 0xD089, 0xB495, 0xD08A, 0xB496, 0xD08B, 0xB497,
+	0xD08C, 0xB498, 0xD08D, 0xB499, 0xD08E, 0xB49A, 0xD08F, 0xB49B,
+	0xD090, 0xB49C, 0xD091, 0xB49D, 0xD092, 0xB49E, 0xD093, 0xB49F,
+	0xD094, 0xB4A0, 0xD095, 0xB541, 0xD096, 0xB542, 0xD097, 0xB543,
+	0xD098, 0xB544, 0xD099, 0xB545, 0xD09A, 0xB546, 0xD09B, 0xB547,
+	0xD09C, 0xB548, 0xD09D, 0xB549, 0xD09E, 0xB54A, 0xD09F, 0xB54B,
+	0xD0A0, 0xB54C, 0xD0A1, 0xB54D, 0xD0A2, 0xB54E, 0xD0A3, 0xB54F,
+	0xD0A4, 0xC5B0, 0xD0A5, 0xC5B1, 0xD0A6, 0xB550, 0xD0A7, 0xB551,
+	0xD0A8, 0xC5B2, 0xD0A9, 0xB552, 0xD0AA, 0xB553, 0xD0AB, 0xB554,
+	0xD0AC, 0xC5B3, 0xD0AD, 0xB555, 0xD0AE, 0xB556, 0xD0AF, 0xB557,
+	0xD0B0, 0xB558, 0xD0B1, 0xB559, 0xD0B2, 0xB55A, 0xD0B3, 0xB561,
+	0xD0B4, 0xC5B4, 0xD0B5, 0xC5B5, 0xD0B6, 0xB562, 0xD0B7, 0xC5B6,
+	0xD0B8, 0xB563, 0xD0B9, 0xC5B7, 0xD0BA, 0xB564, 0xD0BB, 0xB565,
+	0xD0BC, 0xB566, 0xD0BD, 0xB567, 0xD0BE, 0xB568, 0xD0BF, 0xB569,
+	0xD0C0, 0xC5B8, 0xD0C1, 0xC5B9, 0xD0C2, 0xB56A, 0xD0C3, 0xB56B,
+	0xD0C4, 0xC5BA, 0xD0C5, 0xB56C, 0xD0C6, 0xB56D, 0xD0C7, 0xB56E,
+	0xD0C8, 0xC5BB, 0xD0C9, 0xC5BC, 0xD0CA, 0xB56F, 0xD0CB, 0xB570,
+	0xD0CC, 0xB571, 0xD0CD, 0xB572, 0xD0CE, 0xB573, 0xD0CF, 0xB574,
+	0xD0D0, 0xC5BD, 0xD0D1, 0xC5BE, 0xD0D2, 0xB575, 0xD0D3, 0xC5BF,
+	0xD0D4, 0xC5C0, 0xD0D5, 0xC5C1, 0xD0D6, 0xB576, 0xD0D7, 0xB577,
+	0xD0D8, 0xB578, 0xD0D9, 0xB579, 0xD0DA, 0xB57A, 0xD0DB, 0xB581,
+	0xD0DC, 0xC5C2, 0xD0DD, 0xC5C3, 0xD0DE, 0xB582, 0xD0DF, 0xB583,
+	0xD0E0, 0xC5C4, 0xD0E1, 0xB584, 0xD0E2, 0xB585, 0xD0E3, 0xB586,
+	0xD0E4, 0xC5C5, 0xD0E5, 0xB587, 0xD0E6, 0xB588, 0xD0E7, 0xB589,
+	0xD0E8, 0xB58A, 0xD0E9, 0xB58B, 0xD0EA, 0xB58C, 0xD0EB, 0xB58D,
+	0xD0EC, 0xC5C6, 0xD0ED, 0xC5C7, 0xD0EE, 0xB58E, 0xD0EF, 0xC5C8,
+	0xD0F0, 0xC5C9, 0xD0F1, 0xC5CA, 0xD0F2, 0xB58F, 0xD0F3, 0xB590,
+	0xD0F4, 0xB591, 0xD0F5, 0xB592, 0xD0F6, 0xB593, 0xD0F7, 0xB594,
+	0xD0F8, 0xC5CB, 0xD0F9, 0xB595, 0xD0FA, 0xB596, 0xD0FB, 0xB597,
+	0xD0FC, 0xB598, 0xD0FD, 0xB599, 0xD0FE, 0xB59A, 0xD0FF, 0xB59B,
+	0xD100, 0xB59C, 0xD101, 0xB59D, 0xD102, 0xB59E, 0xD103, 0xB59F,
+	0xD104, 0xB5A0, 0xD105, 0xB641, 0xD106, 0xB642, 0xD107, 0xB643,
+	0xD108, 0xB644, 0xD109, 0xB645, 0xD10A, 0xB646, 0xD10B, 0xB647,
+	0xD10C, 0xB648, 0xD10D, 0xC5CC, 0xD10E, 0xB649, 0xD10F, 0xB64A,
+	0xD110, 0xB64B, 0xD111, 0xB64C, 0xD112, 0xB64D, 0xD113, 0xB64E,
+	0xD114, 0xB64F, 0xD115, 0xB650, 0xD116, 0xB651, 0xD117, 0xB652,
+	0xD118, 0xB653, 0xD119, 0xB654, 0xD11A, 0xB655, 0xD11B, 0xB656,
+	0xD11C, 0xB657, 0xD11D, 0xB658, 0xD11E, 0xB659, 0xD11F, 0xB65A,
+	0xD120, 0xB661, 0xD121, 0xB662, 0xD122, 0xB663, 0xD123, 0xB664,
+	0xD124, 0xB665, 0xD125, 0xB666, 0xD126, 0xB667, 0xD127, 0xB668,
+	0xD128, 0xB669, 0xD129, 0xB66A, 0xD12A, 0xB66B, 0xD12B, 0xB66C,
+	0xD12C, 0xB66D, 0xD12D, 0xB66E, 0xD12E, 0xB66F, 0xD12F, 0xB670,
+	0xD130, 0xC5CD, 0xD131, 0xC5CE, 0xD132, 0xB671, 0xD133, 0xB672,
+	0xD134, 0xC5CF, 0xD135, 0xB673, 0xD136, 0xB674, 0xD137, 0xB675,
+	0xD138, 0xC5D0, 0xD139, 0xB676, 0xD13A, 0xC5D1, 0xD13B, 0xB677,
+	0xD13C, 0xB678, 0xD13D, 0xB679, 0xD13E, 0xB67A, 0xD13F, 0xB681,
+	0xD140, 0xC5D2, 0xD141, 0xC5D3, 0xD142, 0xB682, 0xD143, 0xC5D4,
+	0xD144, 0xC5D5, 0xD145, 0xC5D6, 0xD146, 0xB683, 0xD147, 0xB684,
+	0xD148, 0xB685, 0xD149, 0xB686, 0xD14A, 0xB687, 0xD14B, 0xB688,
+	0xD14C, 0xC5D7, 0xD14D, 0xC5D8, 0xD14E, 0xB689, 0xD14F, 0xB68A,
+	0xD150, 0xC5D9, 0xD151, 0xB68B, 0xD152, 0xB68C, 0xD153, 0xB68D,
+	0xD154, 0xC5DA, 0xD155, 0xB68E, 0xD156, 0xB68F, 0xD157, 0xB690,
+	0xD158, 0xB691, 0xD159, 0xB692, 0xD15A, 0xB693, 0xD15B, 0xB694,
+	0xD15C, 0xC5DB, 0xD15D, 0xC5DC, 0xD15E, 0xB695, 0xD15F, 0xC5DD,
+	0xD160, 0xB696, 0xD161, 0xC5DE, 0xD162, 0xB697, 0xD163, 0xB698,
+	0xD164, 0xB699, 0xD165, 0xB69A, 0xD166, 0xB69B, 0xD167, 0xB69C,
+	0xD168, 0xC5DF, 0xD169, 0xB69D, 0xD16A, 0xB69E, 0xD16B, 0xB69F,
+	0xD16C, 0xC5E0, 0xD16D, 0xB6A0, 0xD16E, 0xB741, 0xD16F, 0xB742,
+	0xD170, 0xB743, 0xD171, 0xB744, 0xD172, 0xB745, 0xD173, 0xB746,
+	0xD174, 0xB747, 0xD175, 0xB748, 0xD176, 0xB749, 0xD177, 0xB74A,
+	0xD178, 0xB74B, 0xD179, 0xB74C, 0xD17A, 0xB74D, 0xD17B, 0xB74E,
+	0xD17C, 0xC5E1, 0xD17D, 0xB74F, 0xD17E, 0xB750, 0xD17F, 0xB751,
+	0xD180, 0xB752, 0xD181, 0xB753, 0xD182, 0xB754, 0xD183, 0xB755,
+	0xD184, 0xC5E2, 0xD185, 0xB756, 0xD186, 0xB757, 0xD187, 0xB758,
+	0xD188, 0xC5E3, 0xD189, 0xB759, 0xD18A, 0xB75A, 0xD18B, 0xB761,
+	0xD18C, 0xB762, 0xD18D, 0xB763, 0xD18E, 0xB764, 0xD18F, 0xB765,
+	0xD190, 0xB766, 0xD191, 0xB767, 0xD192, 0xB768, 0xD193, 0xB769,
+	0xD194, 0xB76A, 0xD195, 0xB76B, 0xD196, 0xB76C, 0xD197, 0xB76D,
+	0xD198, 0xB76E, 0xD199, 0xB76F, 0xD19A, 0xB770, 0xD19B, 0xB771,
+	0xD19C, 0xB772, 0xD19D, 0xB773, 0xD19E, 0xB774, 0xD19F, 0xB775,
+	0xD1A0, 0xC5E4, 0xD1A1, 0xC5E5, 0xD1A2, 0xB776, 0xD1A3, 0xB777,
+	0xD1A4, 0xC5E6, 0xD1A5, 0xB778, 0xD1A6, 0xB779, 0xD1A7, 0xB77A,
+	0xD1A8, 0xC5E7, 0xD1A9, 0xB781, 0xD1AA, 0xB782, 0xD1AB, 0xB783,
+	0xD1AC, 0xB784, 0xD1AD, 0xB785, 0xD1AE, 0xB786, 0xD1AF, 0xB787,
+	0xD1B0, 0xC5E8, 0xD1B1, 0xC5E9, 0xD1B2, 0xB788, 0xD1B3, 0xC5EA,
+	0xD1B4, 0xB789, 0xD1B5, 0xC5EB, 0xD1B6, 0xB78A, 0xD1B7, 0xB78B,
+	0xD1B8, 0xB78C, 0xD1B9, 0xB78D, 0xD1BA, 0xC5EC, 0xD1BB, 0xB78E,
+	0xD1BC, 0xC5ED, 0xD1BD, 0xB78F, 0xD1BE, 0xB790, 0xD1BF, 0xB791,
+	0xD1C0, 0xC5EE, 0xD1C1, 0xB792, 0xD1C2, 0xB793, 0xD1C3, 0xB794,
+	0xD1C4, 0xB795, 0xD1C5, 0xB796, 0xD1C6, 0xB797, 0xD1C7, 0xB798,
+	0xD1C8, 0xB799, 0xD1C9, 0xB79A, 0xD1CA, 0xB79B, 0xD1CB, 0xB79C,
+	0xD1CC, 0xB79D, 0xD1CD, 0xB79E, 0xD1CE, 0xB79F, 0xD1CF, 0xB7A0,
+	0xD1D0, 0xB841, 0xD1D1, 0xB842, 0xD1D2, 0xB843, 0xD1D3, 0xB844,
+	0xD1D4, 0xB845, 0xD1D5, 0xB846, 0xD1D6, 0xB847, 0xD1D7, 0xB848,
+	0xD1D8, 0xC5EF, 0xD1D9, 0xB849, 0xD1DA, 0xB84A, 0xD1DB, 0xB84B,
+	0xD1DC, 0xB84C, 0xD1DD, 0xB84D, 0xD1DE, 0xB84E, 0xD1DF, 0xB84F,
+	0xD1E0, 0xB850, 0xD1E1, 0xB851, 0xD1E2, 0xB852, 0xD1E3, 0xB853,
+	0xD1E4, 0xB854, 0xD1E5, 0xB855, 0xD1E6, 0xB856, 0xD1E7, 0xB857,
+	0xD1E8, 0xB858, 0xD1E9, 0xB859, 0xD1EA, 0xB85A, 0xD1EB, 0xB861,
+	0xD1EC, 0xB862, 0xD1ED, 0xB863, 0xD1EE, 0xB864, 0xD1EF, 0xB865,
+	0xD1F0, 0xB866, 0xD1F1, 0xB867, 0xD1F2, 0xB868, 0xD1F3, 0xB869,
+	0xD1F4, 0xC5F0, 0xD1F5, 0xB86A, 0xD1F6, 0xB86B, 0xD1F7, 0xB86C,
+	0xD1F8, 0xC5F1, 0xD1F9, 0xB86D, 0xD1FA, 0xB86E, 0xD1FB, 0xB86F,
+	0xD1FC, 0xB870, 0xD1FD, 0xB871, 0xD1FE, 0xB872, 0xD1FF, 0xB873,
+	0xD200, 0xB874, 0xD201, 0xB875, 0xD202, 0xB876, 0xD203, 0xB877,
+	0xD204, 0xB878, 0xD205, 0xB879, 0xD206, 0xB87A, 0xD207, 0xC5F2,
+	0xD208, 0xB881, 0xD209, 0xC5F3, 0xD20A, 0xB882, 0xD20B, 0xB883,
+	0xD20C, 0xB884, 0xD20D, 0xB885, 0xD20E, 0xB886, 0xD20F, 0xB887,
+	0xD210, 0xC5F4, 0xD211, 0xB888, 0xD212, 0xB889, 0xD213, 0xB88A,
+	0xD214, 0xB88B, 0xD215, 0xB88C, 0xD216, 0xB88D, 0xD217, 0xB88E,
+	0xD218, 0xB88F, 0xD219, 0xB890, 0xD21A, 0xB891, 0xD21B, 0xB892,
+	0xD21C, 0xB893, 0xD21D, 0xB894, 0xD21E, 0xB895, 0xD21F, 0xB896,
+	0xD220, 0xB897, 0xD221, 0xB898, 0xD222, 0xB899, 0xD223, 0xB89A,
+	0xD224, 0xB89B, 0xD225, 0xB89C, 0xD226, 0xB89D, 0xD227, 0xB89E,
+	0xD228, 0xB89F, 0xD229, 0xB8A0, 0xD22A, 0xB941, 0xD22B, 0xB942,
+	0xD22C, 0xC5F5, 0xD22D, 0xC5F6, 0xD22E, 0xB943, 0xD22F, 0xB944,
+	0xD230, 0xC5F7, 0xD231, 0xB945, 0xD232, 0xB946, 0xD233, 0xB947,
+	0xD234, 0xC5F8, 0xD235, 0xB948, 0xD236, 0xB949, 0xD237, 0xB94A,
+	0xD238, 0xB94B, 0xD239, 0xB94C, 0xD23A, 0xB94D, 0xD23B, 0xB94E,
+	0xD23C, 0xC5F9, 0xD23D, 0xC5FA, 0xD23E, 0xB94F, 0xD23F, 0xC5FB,
+	0xD240, 0xB950, 0xD241, 0xC5FC, 0xD242, 0xB951, 0xD243, 0xB952,
+	0xD244, 0xB953, 0xD245, 0xB954, 0xD246, 0xB955, 0xD247, 0xB956,
+	0xD248, 0xC5FD, 0xD249, 0xB957, 0xD24A, 0xB958, 0xD24B, 0xB959,
+	0xD24C, 0xB95A, 0xD24D, 0xB961, 0xD24E, 0xB962, 0xD24F, 0xB963,
+	0xD250, 0xB964, 0xD251, 0xB965, 0xD252, 0xB966, 0xD253, 0xB967,
+	0xD254, 0xB968, 0xD255, 0xB969, 0xD256, 0xB96A, 0xD257, 0xB96B,
+	0xD258, 0xB96C, 0xD259, 0xB96D, 0xD25A, 0xB96E, 0xD25B, 0xB96F,
+	0xD25C, 0xC5FE, 0xD25D, 0xB970, 0xD25E, 0xB971, 0xD25F, 0xB972,
+	0xD260, 0xB973, 0xD261, 0xB974, 0xD262, 0xB975, 0xD263, 0xB976,
+	0xD264, 0xC6A1, 0xD265, 0xB977, 0xD266, 0xB978, 0xD267, 0xB979,
+	0xD268, 0xB97A, 0xD269, 0xB981, 0xD26A, 0xB982, 0xD26B, 0xB983,
+	0xD26C, 0xB984, 0xD26D, 0xB985, 0xD26E, 0xB986, 0xD26F, 0xB987,
+	0xD270, 0xB988, 0xD271, 0xB989, 0xD272, 0xB98A, 0xD273, 0xB98B,
+	0xD274, 0xB98C, 0xD275, 0xB98D, 0xD276, 0xB98E, 0xD277, 0xB98F,
+	0xD278, 0xB990, 0xD279, 0xB991, 0xD27A, 0xB992, 0xD27B, 0xB993,
+	0xD27C, 0xB994, 0xD27D, 0xB995, 0xD27E, 0xB996, 0xD27F, 0xB997,
+	0xD280, 0xC6A2, 0xD281, 0xC6A3, 0xD282, 0xB998, 0xD283, 0xB999,
+	0xD284, 0xC6A4, 0xD285, 0xB99A, 0xD286, 0xB99B, 0xD287, 0xB99C,
+	0xD288, 0xC6A5, 0xD289, 0xB99D, 0xD28A, 0xB99E, 0xD28B, 0xB99F,
+	0xD28C, 0xB9A0, 0xD28D, 0xBA41, 0xD28E, 0xBA42, 0xD28F, 0xBA43,
+	0xD290, 0xC6A6, 0xD291, 0xC6A7, 0xD292, 0xBA44, 0xD293, 0xBA45,
+	0xD294, 0xBA46, 0xD295, 0xC6A8, 0xD296, 0xBA47, 0xD297, 0xBA48,
+	0xD298, 0xBA49, 0xD299, 0xBA4A, 0xD29A, 0xBA4B, 0xD29B, 0xBA4C,
+	0xD29C, 0xC6A9, 0xD29D, 0xBA4D, 0xD29E, 0xBA4E, 0xD29F, 0xBA4F,
+	0xD2A0, 0xC6AA, 0xD2A1, 0xBA50, 0xD2A2, 0xBA51, 0xD2A3, 0xBA52,
+	0xD2A4, 0xC6AB, 0xD2A5, 0xBA53, 0xD2A6, 0xBA54, 0xD2A7, 0xBA55,
+	0xD2A8, 0xBA56, 0xD2A9, 0xBA57, 0xD2AA, 0xBA58, 0xD2AB, 0xBA59,
+	0xD2AC, 0xC6AC, 0xD2AD, 0xBA5A, 0xD2AE, 0xBA61, 0xD2AF, 0xBA62,
+	0xD2B0, 0xBA63, 0xD2B1, 0xC6AD, 0xD2B2, 0xBA64, 0xD2B3, 0xBA65,
+	0xD2B4, 0xBA66, 0xD2B5, 0xBA67, 0xD2B6, 0xBA68, 0xD2B7, 0xBA69,
+	0xD2B8, 0xC6AE, 0xD2B9, 0xC6AF, 0xD2BA, 0xBA6A, 0xD2BB, 0xBA6B,
+	0xD2BC, 0xC6B0, 0xD2BD, 0xBA6C, 0xD2BE, 0xBA6D, 0xD2BF, 0xC6B1,
+	0xD2C0, 0xC6B2, 0xD2C1, 0xBA6E, 0xD2C2, 0xC6B3, 0xD2C3, 0xBA6F,
+	0xD2C4, 0xBA70, 0xD2C5, 0xBA71, 0xD2C6, 0xBA72, 0xD2C7, 0xBA73,
+	0xD2C8, 0xC6B4, 0xD2C9, 0xC6B5, 0xD2CA, 0xBA74, 0xD2CB, 0xC6B6,
+	0xD2CC, 0xBA75, 0xD2CD, 0xBA76, 0xD2CE, 0xBA77, 0xD2CF, 0xBA78,
+	0xD2D0, 0xBA79, 0xD2D1, 0xBA7A, 0xD2D2, 0xBA81, 0xD2D3, 0xBA82,
+	0xD2D4, 0xC6B7, 0xD2D5, 0xBA83, 0xD2D6, 0xBA84, 0xD2D7, 0xBA85,
+	0xD2D8, 0xC6B8, 0xD2D9, 0xBA86, 0xD2DA, 0xBA87, 0xD2DB, 0xBA88,
+	0xD2DC, 0xC6B9, 0xD2DD, 0xBA89, 0xD2DE, 0xBA8A, 0xD2DF, 0xBA8B,
+	0xD2E0, 0xBA8C, 0xD2E1, 0xBA8D, 0xD2E2, 0xBA8E, 0xD2E3, 0xBA8F,
+	0xD2E4, 0xC6BA, 0xD2E5, 0xC6BB, 0xD2E6, 0xBA90, 0xD2E7, 0xBA91,
+	0xD2E8, 0xBA92, 0xD2E9, 0xBA93, 0xD2EA, 0xBA94, 0xD2EB, 0xBA95,
+	0xD2EC, 0xBA96, 0xD2ED, 0xBA97, 0xD2EE, 0xBA98, 0xD2EF, 0xBA99,
+	0xD2F0, 0xC6BC, 0xD2F1, 0xC6BD, 0xD2F2, 0xBA9A, 0xD2F3, 0xBA9B,
+	0xD2F4, 0xC6BE, 0xD2F5, 0xBA9C, 0xD2F6, 0xBA9D, 0xD2F7, 0xBA9E,
+	0xD2F8, 0xC6BF, 0xD2F9, 0xBA9F, 0xD2FA, 0xBAA0, 0xD2FB, 0xBB41,
+	0xD2FC, 0xBB42, 0xD2FD, 0xBB43, 0xD2FE, 0xBB44, 0xD2FF, 0xBB45,
+	0xD300, 0xC6C0, 0xD301, 0xC6C1, 0xD302, 0xBB46, 0xD303, 0xC6C2,
+	0xD304, 0xBB47, 0xD305, 0xC6C3, 0xD306, 0xBB48, 0xD307, 0xBB49,
+	0xD308, 0xBB4A, 0xD309, 0xBB4B, 0xD30A, 0xBB4C, 0xD30B, 0xBB4D,
+	0xD30C, 0xC6C4, 0xD30D, 0xC6C5, 0xD30E, 0xC6C6, 0xD30F, 0xBB4E,
+	0xD310, 0xC6C7, 0xD311, 0xBB4F, 0xD312, 0xBB50, 0xD313, 0xBB51,
+	0xD314, 0xC6C8, 0xD315, 0xBB52, 0xD316, 0xC6C9, 0xD317, 0xBB53,
+	0xD318, 0xBB54, 0xD319, 0xBB55, 0xD31A, 0xBB56, 0xD31B, 0xBB57,
+	0xD31C, 0xC6CA, 0xD31D, 0xC6CB, 0xD31E, 0xBB58, 0xD31F, 0xC6CC,
+	0xD320, 0xC6CD, 0xD321, 0xC6CE, 0xD322, 0xBB59, 0xD323, 0xBB5A,
+	0xD324, 0xBB61, 0xD325, 0xC6CF, 0xD326, 0xBB62, 0xD327, 0xBB63,
+	0xD328, 0xC6D0, 0xD329, 0xC6D1, 0xD32A, 0xBB64, 0xD32B, 0xBB65,
+	0xD32C, 0xC6D2, 0xD32D, 0xBB66, 0xD32E, 0xBB67, 0xD32F, 0xBB68,
+	0xD330, 0xC6D3, 0xD331, 0xBB69, 0xD332, 0xBB6A, 0xD333, 0xBB6B,
+	0xD334, 0xBB6C, 0xD335, 0xBB6D, 0xD336, 0xBB6E, 0xD337, 0xBB6F,
+	0xD338, 0xC6D4, 0xD339, 0xC6D5, 0xD33A, 0xBB70, 0xD33B, 0xC6D6,
+	0xD33C, 0xC6D7, 0xD33D, 0xC6D8, 0xD33E, 0xBB71, 0xD33F, 0xBB72,
+	0xD340, 0xBB73, 0xD341, 0xBB74, 0xD342, 0xBB75, 0xD343, 0xBB76,
+	0xD344, 0xC6D9, 0xD345, 0xC6DA, 0xD346, 0xBB77, 0xD347, 0xBB78,
+	0xD348, 0xBB79, 0xD349, 0xBB7A, 0xD34A, 0xBB81, 0xD34B, 0xBB82,
+	0xD34C, 0xBB83, 0xD34D, 0xBB84, 0xD34E, 0xBB85, 0xD34F, 0xBB86,
+	0xD350, 0xBB87, 0xD351, 0xBB88, 0xD352, 0xBB89, 0xD353, 0xBB8A,
+	0xD354, 0xBB8B, 0xD355, 0xBB8C, 0xD356, 0xBB8D, 0xD357, 0xBB8E,
+	0xD358, 0xBB8F, 0xD359, 0xBB90, 0xD35A, 0xBB91, 0xD35B, 0xBB92,
+	0xD35C, 0xBB93, 0xD35D, 0xBB94, 0xD35E, 0xBB95, 0xD35F, 0xBB96,
+	0xD360, 0xBB97, 0xD361, 0xBB98, 0xD362, 0xBB99, 0xD363, 0xBB9A,
+	0xD364, 0xBB9B, 0xD365, 0xBB9C, 0xD366, 0xBB9D, 0xD367, 0xBB9E,
+	0xD368, 0xBB9F, 0xD369, 0xBBA0, 0xD36A, 0xBC41, 0xD36B, 0xBC42,
+	0xD36C, 0xBC43, 0xD36D, 0xBC44, 0xD36E, 0xBC45, 0xD36F, 0xBC46,
+	0xD370, 0xBC47, 0xD371, 0xBC48, 0xD372, 0xBC49, 0xD373, 0xBC4A,
+	0xD374, 0xBC4B, 0xD375, 0xBC4C, 0xD376, 0xBC4D, 0xD377, 0xBC4E,
+	0xD378, 0xBC4F, 0xD379, 0xBC50, 0xD37A, 0xBC51, 0xD37B, 0xBC52,
+	0xD37C, 0xC6DB, 0xD37D, 0xC6DC, 0xD37E, 0xBC53, 0xD37F, 0xBC54,
+	0xD380, 0xC6DD, 0xD381, 0xBC55, 0xD382, 0xBC56, 0xD383, 0xBC57,
+	0xD384, 0xC6DE, 0xD385, 0xBC58, 0xD386, 0xBC59, 0xD387, 0xBC5A,
+	0xD388, 0xBC61, 0xD389, 0xBC62, 0xD38A, 0xBC63, 0xD38B, 0xBC64,
+	0xD38C, 0xC6DF, 0xD38D, 0xC6E0, 0xD38E, 0xBC65, 0xD38F, 0xC6E1,
+	0xD390, 0xC6E2, 0xD391, 0xC6E3, 0xD392, 0xBC66, 0xD393, 0xBC67,
+	0xD394, 0xBC68, 0xD395, 0xBC69, 0xD396, 0xBC6A, 0xD397, 0xBC6B,
+	0xD398, 0xC6E4, 0xD399, 0xC6E5, 0xD39A, 0xBC6C, 0xD39B, 0xBC6D,
+	0xD39C, 0xC6E6, 0xD39D, 0xBC6E, 0xD39E, 0xBC6F, 0xD39F, 0xBC70,
+	0xD3A0, 0xC6E7, 0xD3A1, 0xBC71, 0xD3A2, 0xBC72, 0xD3A3, 0xBC73,
+	0xD3A4, 0xBC74, 0xD3A5, 0xBC75, 0xD3A6, 0xBC76, 0xD3A7, 0xBC77,
+	0xD3A8, 0xC6E8, 0xD3A9, 0xC6E9, 0xD3AA, 0xBC78, 0xD3AB, 0xC6EA,
+	0xD3AC, 0xBC79, 0xD3AD, 0xC6EB, 0xD3AE, 0xBC7A, 0xD3AF, 0xBC81,
+	0xD3B0, 0xBC82, 0xD3B1, 0xBC83, 0xD3B2, 0xBC84, 0xD3B3, 0xBC85,
+	0xD3B4, 0xC6EC, 0xD3B5, 0xBC86, 0xD3B6, 0xBC87, 0xD3B7, 0xBC88,
+	0xD3B8, 0xC6ED, 0xD3B9, 0xBC89, 0xD3BA, 0xBC8A, 0xD3BB, 0xBC8B,
+	0xD3BC, 0xC6EE, 0xD3BD, 0xBC8C, 0xD3BE, 0xBC8D, 0xD3BF, 0xBC8E,
+	0xD3C0, 0xBC8F, 0xD3C1, 0xBC90, 0xD3C2, 0xBC91, 0xD3C3, 0xBC92,
+	0xD3C4, 0xC6EF, 0xD3C5, 0xC6F0, 0xD3C6, 0xBC93, 0xD3C7, 0xBC94,
+	0xD3C8, 0xC6F1, 0xD3C9, 0xC6F2, 0xD3CA, 0xBC95, 0xD3CB, 0xBC96,
+	0xD3CC, 0xBC97, 0xD3CD, 0xBC98, 0xD3CE, 0xBC99, 0xD3CF, 0xBC9A,
+	0xD3D0, 0xC6F3, 0xD3D1, 0xBC9B, 0xD3D2, 0xBC9C, 0xD3D3, 0xBC9D,
+	0xD3D4, 0xBC9E, 0xD3D5, 0xBC9F, 0xD3D6, 0xBCA0, 0xD3D7, 0xBD41,
+	0xD3D8, 0xC6F4, 0xD3D9, 0xBD42, 0xD3DA, 0xBD43, 0xD3DB, 0xBD44,
+	0xD3DC, 0xBD45, 0xD3DD, 0xBD46, 0xD3DE, 0xBD47, 0xD3DF, 0xBD48,
+	0xD3E0, 0xBD49, 0xD3E1, 0xC6F5, 0xD3E2, 0xBD4A, 0xD3E3, 0xC6F6,
+	0xD3E4, 0xBD4B, 0xD3E5, 0xBD4C, 0xD3E6, 0xBD4D, 0xD3E7, 0xBD4E,
+	0xD3E8, 0xBD4F, 0xD3E9, 0xBD50, 0xD3EA, 0xBD51, 0xD3EB, 0xBD52,
+	0xD3EC, 0xC6F7, 0xD3ED, 0xC6F8, 0xD3EE, 0xBD53, 0xD3EF, 0xBD54,
+	0xD3F0, 0xC6F9, 0xD3F1, 0xBD55, 0xD3F2, 0xBD56, 0xD3F3, 0xBD57,
+	0xD3F4, 0xC6FA, 0xD3F5, 0xBD58, 0xD3F6, 0xBD59, 0xD3F7, 0xBD5A,
+	0xD3F8, 0xBD61, 0xD3F9, 0xBD62, 0xD3FA, 0xBD63, 0xD3FB, 0xBD64,
+	0xD3FC, 0xC6FB, 0xD3FD, 0xC6FC, 0xD3FE, 0xBD65, 0xD3FF, 0xC6FD,
+	0xD400, 0xBD66, 0xD401, 0xC6FE, 0xD402, 0xBD67, 0xD403, 0xBD68,
+	0xD404, 0xBD69, 0xD405, 0xBD6A, 0xD406, 0xBD6B, 0xD407, 0xBD6C,
+	0xD408, 0xC7A1, 0xD409, 0xBD6D, 0xD40A, 0xBD6E, 0xD40B, 0xBD6F,
+	0xD40C, 0xBD70, 0xD40D, 0xBD71, 0xD40E, 0xBD72, 0xD40F, 0xBD73,
+	0xD410, 0xBD74, 0xD411, 0xBD75, 0xD412, 0xBD76, 0xD413, 0xBD77,
+	0xD414, 0xBD78, 0xD415, 0xBD79, 0xD416, 0xBD7A, 0xD417, 0xBD81,
+	0xD418, 0xBD82, 0xD419, 0xBD83, 0xD41A, 0xBD84, 0xD41B, 0xBD85,
+	0xD41C, 0xBD86, 0xD41D, 0xC7A2, 0xD41E, 0xBD87, 0xD41F, 0xBD88,
+	0xD420, 0xBD89, 0xD421, 0xBD8A, 0xD422, 0xBD8B, 0xD423, 0xBD8C,
+	0xD424, 0xBD8D, 0xD425, 0xBD8E, 0xD426, 0xBD8F, 0xD427, 0xBD90,
+	0xD428, 0xBD91, 0xD429, 0xBD92, 0xD42A, 0xBD93, 0xD42B, 0xBD94,
+	0xD42C, 0xBD95, 0xD42D, 0xBD96, 0xD42E, 0xBD97, 0xD42F, 0xBD98,
+	0xD430, 0xBD99, 0xD431, 0xBD9A, 0xD432, 0xBD9B, 0xD433, 0xBD9C,
+	0xD434, 0xBD9D, 0xD435, 0xBD9E, 0xD436, 0xBD9F, 0xD437, 0xBDA0,
+	0xD438, 0xBE41, 0xD439, 0xBE42, 0xD43A, 0xBE43, 0xD43B, 0xBE44,
+	0xD43C, 0xBE45, 0xD43D, 0xBE46, 0xD43E, 0xBE47, 0xD43F, 0xBE48,
+	0xD440, 0xC7A3, 0xD441, 0xBE49, 0xD442, 0xBE4A, 0xD443, 0xBE4B,
+	0xD444, 0xC7A4, 0xD445, 0xBE4C, 0xD446, 0xBE4D, 0xD447, 0xBE4E,
+	0xD448, 0xBE4F, 0xD449, 0xBE50, 0xD44A, 0xBE51, 0xD44B, 0xBE52,
+	0xD44C, 0xBE53, 0xD44D, 0xBE54, 0xD44E, 0xBE55, 0xD44F, 0xBE56,
+	0xD450, 0xBE57, 0xD451, 0xBE58, 0xD452, 0xBE59, 0xD453, 0xBE5A,
+	0xD454, 0xBE61, 0xD455, 0xBE62, 0xD456, 0xBE63, 0xD457, 0xBE64,
+	0xD458, 0xBE65, 0xD459, 0xBE66, 0xD45A, 0xBE67, 0xD45B, 0xBE68,
+	0xD45C, 0xC7A5, 0xD45D, 0xBE69, 0xD45E, 0xBE6A, 0xD45F, 0xBE6B,
+	0xD460, 0xC7A6, 0xD461, 0xBE6C, 0xD462, 0xBE6D, 0xD463, 0xBE6E,
+	0xD464, 0xC7A7, 0xD465, 0xBE6F, 0xD466, 0xBE70, 0xD467, 0xBE71,
+	0xD468, 0xBE72, 0xD469, 0xBE73, 0xD46A, 0xBE74, 0xD46B, 0xBE75,
+	0xD46C, 0xBE76, 0xD46D, 0xC7A8, 0xD46E, 0xBE77, 0xD46F, 0xC7A9,
+	0xD470, 0xBE78, 0xD471, 0xBE79, 0xD472, 0xBE7A, 0xD473, 0xBE81,
+	0xD474, 0xBE82, 0xD475, 0xBE83, 0xD476, 0xBE84, 0xD477, 0xBE85,
+	0xD478, 0xC7AA, 0xD479, 0xC7AB, 0xD47A, 0xBE86, 0xD47B, 0xBE87,
+	0xD47C, 0xC7AC, 0xD47D, 0xBE88, 0xD47E, 0xBE89, 0xD47F, 0xC7AD,
+	0xD480, 0xC7AE, 0xD481, 0xBE8A, 0xD482, 0xC7AF, 0xD483, 0xBE8B,
+	0xD484, 0xBE8C, 0xD485, 0xBE8D, 0xD486, 0xBE8E, 0xD487, 0xBE8F,
+	0xD488, 0xC7B0, 0xD489, 0xC7B1, 0xD48A, 0xBE90, 0xD48B, 0xC7B2,
+	0xD48C, 0xBE91, 0xD48D, 0xC7B3, 0xD48E, 0xBE92, 0xD48F, 0xBE93,
+	0xD490, 0xBE94, 0xD491, 0xBE95, 0xD492, 0xBE96, 0xD493, 0xBE97,
+	0xD494, 0xC7B4, 0xD495, 0xBE98, 0xD496, 0xBE99, 0xD497, 0xBE9A,
+	0xD498, 0xBE9B, 0xD499, 0xBE9C, 0xD49A, 0xBE9D, 0xD49B, 0xBE9E,
+	0xD49C, 0xBE9F, 0xD49D, 0xBEA0, 0xD49E, 0xBF41, 0xD49F, 0xBF42,
+	0xD4A0, 0xBF43, 0xD4A1, 0xBF44, 0xD4A2, 0xBF45, 0xD4A3, 0xBF46,
+	0xD4A4, 0xBF47, 0xD4A5, 0xBF48, 0xD4A6, 0xBF49, 0xD4A7, 0xBF4A,
+	0xD4A8, 0xBF4B, 0xD4A9, 0xC7B5, 0xD4AA, 0xBF4C, 0xD4AB, 0xBF4D,
+	0xD4AC, 0xBF4E, 0xD4AD, 0xBF4F, 0xD4AE, 0xBF50, 0xD4AF, 0xBF51,
+	0xD4B0, 0xBF52, 0xD4B1, 0xBF53, 0xD4B2, 0xBF54, 0xD4B3, 0xBF55,
+	0xD4B4, 0xBF56, 0xD4B5, 0xBF57, 0xD4B6, 0xBF58, 0xD4B7, 0xBF59,
+	0xD4B8, 0xBF5A, 0xD4B9, 0xBF61, 0xD4BA, 0xBF62, 0xD4BB, 0xBF63,
+	0xD4BC, 0xBF64, 0xD4BD, 0xBF65, 0xD4BE, 0xBF66, 0xD4BF, 0xBF67,
+	0xD4C0, 0xBF68, 0xD4C1, 0xBF69, 0xD4C2, 0xBF6A, 0xD4C3, 0xBF6B,
+	0xD4C4, 0xBF6C, 0xD4C5, 0xBF6D, 0xD4C6, 0xBF6E, 0xD4C7, 0xBF6F,
+	0xD4C8, 0xBF70, 0xD4C9, 0xBF71, 0xD4CA, 0xBF72, 0xD4CB, 0xBF73,
+	0xD4CC, 0xC7B6, 0xD4CD, 0xBF74, 0xD4CE, 0xBF75, 0xD4CF, 0xBF76,
+	0xD4D0, 0xC7B7, 0xD4D1, 0xBF77, 0xD4D2, 0xBF78, 0xD4D3, 0xBF79,
+	0xD4D4, 0xC7B8, 0xD4D5, 0xBF7A, 0xD4D6, 0xBF81, 0xD4D7, 0xBF82,
+	0xD4D8, 0xBF83, 0xD4D9, 0xBF84, 0xD4DA, 0xBF85, 0xD4DB, 0xBF86,
+	0xD4DC, 0xC7B9, 0xD4DD, 0xBF87, 0xD4DE, 0xBF88, 0xD4DF, 0xC7BA,
+	0xD4E0, 0xBF89, 0xD4E1, 0xBF8A, 0xD4E2, 0xBF8B, 0xD4E3, 0xBF8C,
+	0xD4E4, 0xBF8D, 0xD4E5, 0xBF8E, 0xD4E6, 0xBF8F, 0xD4E7, 0xBF90,
+	0xD4E8, 0xC7BB, 0xD4E9, 0xBF91, 0xD4EA, 0xBF92, 0xD4EB, 0xBF93,
+	0xD4EC, 0xC7BC, 0xD4ED, 0xBF94, 0xD4EE, 0xBF95, 0xD4EF, 0xBF96,
+	0xD4F0, 0xC7BD, 0xD4F1, 0xBF97, 0xD4F2, 0xBF98, 0xD4F3, 0xBF99,
+	0xD4F4, 0xBF9A, 0xD4F5, 0xBF9B, 0xD4F6, 0xBF9C, 0xD4F7, 0xBF9D,
+	0xD4F8, 0xC7BE, 0xD4F9, 0xBF9E, 0xD4FA, 0xBF9F, 0xD4FB, 0xC7BF,
+	0xD4FC, 0xBFA0, 0xD4FD, 0xC7C0, 0xD4FE, 0xC041, 0xD4FF, 0xC042,
+	0xD500, 0xC043, 0xD501, 0xC044, 0xD502, 0xC045, 0xD503, 0xC046,
+	0xD504, 0xC7C1, 0xD505, 0xC047, 0xD506, 0xC048, 0xD507, 0xC049,
+	0xD508, 0xC7C2, 0xD509, 0xC04A, 0xD50A, 0xC04B, 0xD50B, 0xC04C,
+	0xD50C, 0xC7C3, 0xD50D, 0xC04D, 0xD50E, 0xC04E, 0xD50F, 0xC04F,
+	0xD510, 0xC050, 0xD511, 0xC051, 0xD512, 0xC052, 0xD513, 0xC053,
+	0xD514, 0xC7C4, 0xD515, 0xC7C5, 0xD516, 0xC054, 0xD517, 0xC7C6,
+	0xD518, 0xC055, 0xD519, 0xC056, 0xD51A, 0xC057, 0xD51B, 0xC058,
+	0xD51C, 0xC059, 0xD51D, 0xC05A, 0xD51E, 0xC061, 0xD51F, 0xC062,
+	0xD520, 0xC063, 0xD521, 0xC064, 0xD522, 0xC065, 0xD523, 0xC066,
+	0xD524, 0xC067, 0xD525, 0xC068, 0xD526, 0xC069, 0xD527, 0xC06A,
+	0xD528, 0xC06B, 0xD529, 0xC06C, 0xD52A, 0xC06D, 0xD52B, 0xC06E,
+	0xD52C, 0xC06F, 0xD52D, 0xC070, 0xD52E, 0xC071, 0xD52F, 0xC072,
+	0xD530, 0xC073, 0xD531, 0xC074, 0xD532, 0xC075, 0xD533, 0xC076,
+	0xD534, 0xC077, 0xD535, 0xC078, 0xD536, 0xC079, 0xD537, 0xC07A,
+	0xD538, 0xC081, 0xD539, 0xC082, 0xD53A, 0xC083, 0xD53B, 0xC084,
+	0xD53C, 0xC7C7, 0xD53D, 0xC7C8, 0xD53E, 0xC085, 0xD53F, 0xC086,
+	0xD540, 0xC7C9, 0xD541, 0xC087, 0xD542, 0xC088, 0xD543, 0xC089,
+	0xD544, 0xC7CA, 0xD545, 0xC08A, 0xD546, 0xC08B, 0xD547, 0xC08C,
+	0xD548, 0xC08D, 0xD549, 0xC08E, 0xD54A, 0xC08F, 0xD54B, 0xC090,
+	0xD54C, 0xC7CB, 0xD54D, 0xC7CC, 0xD54E, 0xC091, 0xD54F, 0xC7CD,
+	0xD550, 0xC092, 0xD551, 0xC7CE, 0xD552, 0xC093, 0xD553, 0xC094,
+	0xD554, 0xC095, 0xD555, 0xC096, 0xD556, 0xC097, 0xD557, 0xC098,
+	0xD558, 0xC7CF, 0xD559, 0xC7D0, 0xD55A, 0xC099, 0xD55B, 0xC09A,
+	0xD55C, 0xC7D1, 0xD55D, 0xC09B, 0xD55E, 0xC09C, 0xD55F, 0xC09D,
+	0xD560, 0xC7D2, 0xD561, 0xC09E, 0xD562, 0xC09F, 0xD563, 0xC0A0,
+	0xD564, 0xC141, 0xD565, 0xC7D3, 0xD566, 0xC142, 0xD567, 0xC143,
+	0xD568, 0xC7D4, 0xD569, 0xC7D5, 0xD56A, 0xC144, 0xD56B, 0xC7D6,
+	0xD56C, 0xC145, 0xD56D, 0xC7D7, 0xD56E, 0xC146, 0xD56F, 0xC147,
+	0xD570, 0xC148, 0xD571, 0xC149, 0xD572, 0xC14A, 0xD573, 0xC14B,
+	0xD574, 0xC7D8, 0xD575, 0xC7D9, 0xD576, 0xC14C, 0xD577, 0xC14D,
+	0xD578, 0xC7DA, 0xD579, 0xC14E, 0xD57A, 0xC14F, 0xD57B, 0xC150,
+	0xD57C, 0xC7DB, 0xD57D, 0xC151, 0xD57E, 0xC152, 0xD57F, 0xC153,
+	0xD580, 0xC154, 0xD581, 0xC155, 0xD582, 0xC156, 0xD583, 0xC157,
+	0xD584, 0xC7DC, 0xD585, 0xC7DD, 0xD586, 0xC158, 0xD587, 0xC7DE,
+	0xD588, 0xC7DF, 0xD589, 0xC7E0, 0xD58A, 0xC159, 0xD58B, 0xC15A,
+	0xD58C, 0xC161, 0xD58D, 0xC162, 0xD58E, 0xC163, 0xD58F, 0xC164,
+	0xD590, 0xC7E1, 0xD591, 0xC165, 0xD592, 0xC166, 0xD593, 0xC167,
+	0xD594, 0xC168, 0xD595, 0xC169, 0xD596, 0xC16A, 0xD597, 0xC16B,
+	0xD598, 0xC16C, 0xD599, 0xC16D, 0xD59A, 0xC16E, 0xD59B, 0xC16F,
+	0xD59C, 0xC170, 0xD59D, 0xC171, 0xD59E, 0xC172, 0xD59F, 0xC173,
+	0xD5A0, 0xC174, 0xD5A1, 0xC175, 0xD5A2, 0xC176, 0xD5A3, 0xC177,
+	0xD5A4, 0xC178, 0xD5A5, 0xC7E2, 0xD5A6, 0xC179, 0xD5A7, 0xC17A,
+	0xD5A8, 0xC181, 0xD5A9, 0xC182, 0xD5AA, 0xC183, 0xD5AB, 0xC184,
+	0xD5AC, 0xC185, 0xD5AD, 0xC186, 0xD5AE, 0xC187, 0xD5AF, 0xC188,
+	0xD5B0, 0xC189, 0xD5B1, 0xC18A, 0xD5B2, 0xC18B, 0xD5B3, 0xC18C,
+	0xD5B4, 0xC18D, 0xD5B5, 0xC18E, 0xD5B6, 0xC18F, 0xD5B7, 0xC190,
+	0xD5B8, 0xC191, 0xD5B9, 0xC192, 0xD5BA, 0xC193, 0xD5BB, 0xC194,
+	0xD5BC, 0xC195, 0xD5BD, 0xC196, 0xD5BE, 0xC197, 0xD5BF, 0xC198,
+	0xD5C0, 0xC199, 0xD5C1, 0xC19A, 0xD5C2, 0xC19B, 0xD5C3, 0xC19C,
+	0xD5C4, 0xC19D, 0xD5C5, 0xC19E, 0xD5C6, 0xC19F, 0xD5C7, 0xC1A0,
+	0xD5C8, 0xC7E3, 0xD5C9, 0xC7E4, 0xD5CA, 0xC241, 0xD5CB, 0xC242,
+	0xD5CC, 0xC7E5, 0xD5CD, 0xC243, 0xD5CE, 0xC244, 0xD5CF, 0xC245,
+	0xD5D0, 0xC7E6, 0xD5D1, 0xC246, 0xD5D2, 0xC7E7, 0xD5D3, 0xC247,
+	0xD5D4, 0xC248, 0xD5D5, 0xC249, 0xD5D6, 0xC24A, 0xD5D7, 0xC24B,
+	0xD5D8, 0xC7E8, 0xD5D9, 0xC7E9, 0xD5DA, 0xC24C, 0xD5DB, 0xC7EA,
+	0xD5DC, 0xC24D, 0xD5DD, 0xC7EB, 0xD5DE, 0xC24E, 0xD5DF, 0xC24F,
+	0xD5E0, 0xC250, 0xD5E1, 0xC251, 0xD5E2, 0xC252, 0xD5E3, 0xC253,
+	0xD5E4, 0xC7EC, 0xD5E5, 0xC7ED, 0xD5E6, 0xC254, 0xD5E7, 0xC255,
+	0xD5E8, 0xC7EE, 0xD5E9, 0xC256, 0xD5EA, 0xC257, 0xD5EB, 0xC258,
+	0xD5EC, 0xC7EF, 0xD5ED, 0xC259, 0xD5EE, 0xC25A, 0xD5EF, 0xC261,
+	0xD5F0, 0xC262, 0xD5F1, 0xC263, 0xD5F2, 0xC264, 0xD5F3, 0xC265,
+	0xD5F4, 0xC7F0, 0xD5F5, 0xC7F1, 0xD5F6, 0xC266, 0xD5F7, 0xC7F2,
+	0xD5F8, 0xC267, 0xD5F9, 0xC7F3, 0xD5FA, 0xC268, 0xD5FB, 0xC269,
+	0xD5FC, 0xC26A, 0xD5FD, 0xC26B, 0xD5FE, 0xC26C, 0xD5FF, 0xC26D,
+	0xD600, 0xC7F4, 0xD601, 0xC7F5, 0xD602, 0xC26E, 0xD603, 0xC26F,
+	0xD604, 0xC7F6, 0xD605, 0xC270, 0xD606, 0xC271, 0xD607, 0xC272,
+	0xD608, 0xC7F7, 0xD609, 0xC273, 0xD60A, 0xC274, 0xD60B, 0xC275,
+	0xD60C, 0xC276, 0xD60D, 0xC277, 0xD60E, 0xC278, 0xD60F, 0xC279,
+	0xD610, 0xC7F8, 0xD611, 0xC7F9, 0xD612, 0xC27A, 0xD613, 0xC7FA,
+	0xD614, 0xC7FB, 0xD615, 0xC7FC, 0xD616, 0xC281, 0xD617, 0xC282,
+	0xD618, 0xC283, 0xD619, 0xC284, 0xD61A, 0xC285, 0xD61B, 0xC286,
+	0xD61C, 0xC7FD, 0xD61D, 0xC287, 0xD61E, 0xC288, 0xD61F, 0xC289,
+	0xD620, 0xC7FE, 0xD621, 0xC28A, 0xD622, 0xC28B, 0xD623, 0xC28C,
+	0xD624, 0xC8A1, 0xD625, 0xC28D, 0xD626, 0xC28E, 0xD627, 0xC28F,
+	0xD628, 0xC290, 0xD629, 0xC291, 0xD62A, 0xC292, 0xD62B, 0xC293,
+	0xD62C, 0xC294, 0xD62D, 0xC8A2, 0xD62E, 0xC295, 0xD62F, 0xC296,
+	0xD630, 0xC297, 0xD631, 0xC298, 0xD632, 0xC299, 0xD633, 0xC29A,
+	0xD634, 0xC29B, 0xD635, 0xC29C, 0xD636, 0xC29D, 0xD637, 0xC29E,
+	0xD638, 0xC8A3, 0xD639, 0xC8A4, 0xD63A, 0xC29F, 0xD63B, 0xC2A0,
+	0xD63C, 0xC8A5, 0xD63D, 0xC341, 0xD63E, 0xC342, 0xD63F, 0xC343,
+	0xD640, 0xC8A6, 0xD641, 0xC344, 0xD642, 0xC345, 0xD643, 0xC346,
+	0xD644, 0xC347, 0xD645, 0xC8A7, 0xD646, 0xC348, 0xD647, 0xC349,
+	0xD648, 0xC8A8, 0xD649, 0xC8A9, 0xD64A, 0xC34A, 0xD64B, 0xC8AA,
+	0xD64C, 0xC34B, 0xD64D, 0xC8AB, 0xD64E, 0xC34C, 0xD64F, 0xC34D,
+	0xD650, 0xC34E, 0xD651, 0xC8AC, 0xD652, 0xC34F, 0xD653, 0xC350,
+	0xD654, 0xC8AD, 0xD655, 0xC8AE, 0xD656, 0xC351, 0xD657, 0xC352,
+	0xD658, 0xC8AF, 0xD659, 0xC353, 0xD65A, 0xC354, 0xD65B, 0xC355,
+	0xD65C, 0xC8B0, 0xD65D, 0xC356, 0xD65E, 0xC357, 0xD65F, 0xC358,
+	0xD660, 0xC359, 0xD661, 0xC35A, 0xD662, 0xC361, 0xD663, 0xC362,
+	0xD664, 0xC363, 0xD665, 0xC364, 0xD666, 0xC365, 0xD667, 0xC8B1,
+	0xD668, 0xC366, 0xD669, 0xC8B2, 0xD66A, 0xC367, 0xD66B, 0xC368,
+	0xD66C, 0xC369, 0xD66D, 0xC36A, 0xD66E, 0xC36B, 0xD66F, 0xC36C,
+	0xD670, 0xC8B3, 0xD671, 0xC8B4, 0xD672, 0xC36D, 0xD673, 0xC36E,
+	0xD674, 0xC8B5, 0xD675, 0xC36F, 0xD676, 0xC370, 0xD677, 0xC371,
+	0xD678, 0xC372, 0xD679, 0xC373, 0xD67A, 0xC374, 0xD67B, 0xC375,
+	0xD67C, 0xC376, 0xD67D, 0xC377, 0xD67E, 0xC378, 0xD67F, 0xC379,
+	0xD680, 0xC37A, 0xD681, 0xC381, 0xD682, 0xC382, 0xD683, 0xC8B6,
+	0xD684, 0xC383, 0xD685, 0xC8B7, 0xD686, 0xC384, 0xD687, 0xC385,
+	0xD688, 0xC386, 0xD689, 0xC387, 0xD68A, 0xC388, 0xD68B, 0xC389,
+	0xD68C, 0xC8B8, 0xD68D, 0xC8B9, 0xD68E, 0xC38A, 0xD68F, 0xC38B,
+	0xD690, 0xC8BA, 0xD691, 0xC38C, 0xD692, 0xC38D, 0xD693, 0xC38E,
+	0xD694, 0xC8BB, 0xD695, 0xC38F, 0xD696, 0xC390, 0xD697, 0xC391,
+	0xD698, 0xC392, 0xD699, 0xC393, 0xD69A, 0xC394, 0xD69B, 0xC395,
+	0xD69C, 0xC396, 0xD69D, 0xC8BC, 0xD69E, 0xC397, 0xD69F, 0xC8BD,
+	0xD6A0, 0xC398, 0xD6A1, 0xC8BE, 0xD6A2, 0xC399, 0xD6A3, 0xC39A,
+	0xD6A4, 0xC39B, 0xD6A5, 0xC39C, 0xD6A6, 0xC39D, 0xD6A7, 0xC39E,
+	0xD6A8, 0xC8BF, 0xD6A9, 0xC39F, 0xD6AA, 0xC3A0, 0xD6AB, 0xC441,
+	0xD6AC, 0xC8C0, 0xD6AD, 0xC442, 0xD6AE, 0xC443, 0xD6AF, 0xC444,
+	0xD6B0, 0xC8C1, 0xD6B1, 0xC445, 0xD6B2, 0xC446, 0xD6B3, 0xC447,
+	0xD6B4, 0xC448, 0xD6B5, 0xC449, 0xD6B6, 0xC44A, 0xD6B7, 0xC44B,
+	0xD6B8, 0xC44C, 0xD6B9, 0xC8C2, 0xD6BA, 0xC44D, 0xD6BB, 0xC8C3,
+	0xD6BC, 0xC44E, 0xD6BD, 0xC44F, 0xD6BE, 0xC450, 0xD6BF, 0xC451,
+	0xD6C0, 0xC452, 0xD6C1, 0xC453, 0xD6C2, 0xC454, 0xD6C3, 0xC455,
+	0xD6C4, 0xC8C4, 0xD6C5, 0xC8C5, 0xD6C6, 0xC456, 0xD6C7, 0xC457,
+	0xD6C8, 0xC8C6, 0xD6C9, 0xC458, 0xD6CA, 0xC459, 0xD6CB, 0xC45A,
+	0xD6CC, 0xC8C7, 0xD6CD, 0xC461, 0xD6CE, 0xC462, 0xD6CF, 0xC463,
+	0xD6D0, 0xC464, 0xD6D1, 0xC8C8, 0xD6D2, 0xC465, 0xD6D3, 0xC466,
+	0xD6D4, 0xC8C9, 0xD6D5, 0xC467, 0xD6D6, 0xC468, 0xD6D7, 0xC8CA,
+	0xD6D8, 0xC469, 0xD6D9, 0xC8CB, 0xD6DA, 0xC46A, 0xD6DB, 0xC46B,
+	0xD6DC, 0xC46C, 0xD6DD, 0xC46D, 0xD6DE, 0xC46E, 0xD6DF, 0xC46F,
+	0xD6E0, 0xC8CC, 0xD6E1, 0xC470, 0xD6E2, 0xC471, 0xD6E3, 0xC472,
+	0xD6E4, 0xC8CD, 0xD6E5, 0xC473, 0xD6E6, 0xC474, 0xD6E7, 0xC475,
+	0xD6E8, 0xC8CE, 0xD6E9, 0xC476, 0xD6EA, 0xC477, 0xD6EB, 0xC478,
+	0xD6EC, 0xC479, 0xD6ED, 0xC47A, 0xD6EE, 0xC481, 0xD6EF, 0xC482,
+	0xD6F0, 0xC8CF, 0xD6F1, 0xC483, 0xD6F2, 0xC484, 0xD6F3, 0xC485,
+	0xD6F4, 0xC486, 0xD6F5, 0xC8D0, 0xD6F6, 0xC487, 0xD6F7, 0xC488,
+	0xD6F8, 0xC489, 0xD6F9, 0xC48A, 0xD6FA, 0xC48B, 0xD6FB, 0xC48C,
+	0xD6FC, 0xC8D1, 0xD6FD, 0xC8D2, 0xD6FE, 0xC48D, 0xD6FF, 0xC48E,
+	0xD700, 0xC8D3, 0xD701, 0xC48F, 0xD702, 0xC490, 0xD703, 0xC491,
+	0xD704, 0xC8D4, 0xD705, 0xC492, 0xD706, 0xC493, 0xD707, 0xC494,
+	0xD708, 0xC495, 0xD709, 0xC496, 0xD70A, 0xC497, 0xD70B, 0xC498,
+	0xD70C, 0xC499, 0xD70D, 0xC49A, 0xD70E, 0xC49B, 0xD70F, 0xC49C,
+	0xD710, 0xC49D, 0xD711, 0xC8D5, 0xD712, 0xC49E, 0xD713, 0xC49F,
+	0xD714, 0xC4A0, 0xD715, 0xC541, 0xD716, 0xC542, 0xD717, 0xC543,
+	0xD718, 0xC8D6, 0xD719, 0xC8D7, 0xD71A, 0xC544, 0xD71B, 0xC545,
+	0xD71C, 0xC8D8, 0xD71D, 0xC546, 0xD71E, 0xC547, 0xD71F, 0xC548,
+	0xD720, 0xC8D9, 0xD721, 0xC549, 0xD722, 0xC54A, 0xD723, 0xC54B,
+	0xD724, 0xC54C, 0xD725, 0xC54D, 0xD726, 0xC54E, 0xD727, 0xC54F,
+	0xD728, 0xC8DA, 0xD729, 0xC8DB, 0xD72A, 0xC550, 0xD72B, 0xC8DC,
+	0xD72C, 0xC551, 0xD72D, 0xC8DD, 0xD72E, 0xC552, 0xD72F, 0xC553,
+	0xD730, 0xC554, 0xD731, 0xC555, 0xD732, 0xC556, 0xD733, 0xC557,
+	0xD734, 0xC8DE, 0xD735, 0xC8DF, 0xD736, 0xC558, 0xD737, 0xC559,
+	0xD738, 0xC8E0, 0xD739, 0xC55A, 0xD73A, 0xC561, 0xD73B, 0xC562,
+	0xD73C, 0xC8E1, 0xD73D, 0xC563, 0xD73E, 0xC564, 0xD73F, 0xC565,
+	0xD740, 0xC566, 0xD741, 0xC567, 0xD742, 0xC568, 0xD743, 0xC569,
+	0xD744, 0xC8E2, 0xD745, 0xC56A, 0xD746, 0xC56B, 0xD747, 0xC8E3,
+	0xD748, 0xC56C, 0xD749, 0xC8E4, 0xD74A, 0xC56D, 0xD74B, 0xC56E,
+	0xD74C, 0xC56F, 0xD74D, 0xC570, 0xD74E, 0xC571, 0xD74F, 0xC572,
+	0xD750, 0xC8E5, 0xD751, 0xC8E6, 0xD752, 0xC573, 0xD753, 0xC574,
+	0xD754, 0xC8E7, 0xD755, 0xC575, 0xD756, 0xC8E8, 0xD757, 0xC8E9,
+	0xD758, 0xC8EA, 0xD759, 0xC8EB, 0xD75A, 0xC576, 0xD75B, 0xC577,
+	0xD75C, 0xC578, 0xD75D, 0xC579, 0xD75E, 0xC57A, 0xD75F, 0xC581,
+	0xD760, 0xC8EC, 0xD761, 0xC8ED, 0xD762, 0xC582, 0xD763, 0xC8EE,
+	0xD764, 0xC583, 0xD765, 0xC8EF, 0xD766, 0xC584, 0xD767, 0xC585,
+	0xD768, 0xC586, 0xD769, 0xC8F0, 0xD76A, 0xC587, 0xD76B, 0xC588,
+	0xD76C, 0xC8F1, 0xD76D, 0xC589, 0xD76E, 0xC58A, 0xD76F, 0xC58B,
+	0xD770, 0xC8F2, 0xD771, 0xC58C, 0xD772, 0xC58D, 0xD773, 0xC58E,
+	0xD774, 0xC8F3, 0xD775, 0xC58F, 0xD776, 0xC590, 0xD777, 0xC591,
+	0xD778, 0xC592, 0xD779, 0xC593, 0xD77A, 0xC594, 0xD77B, 0xC595,
+	0xD77C, 0xC8F4, 0xD77D, 0xC8F5, 0xD77E, 0xC596, 0xD77F, 0xC597,
+	0xD780, 0xC598, 0xD781, 0xC8F6, 0xD782, 0xC599, 0xD783, 0xC59A,
+	0xD784, 0xC59B, 0xD785, 0xC59C, 0xD786, 0xC59D, 0xD787, 0xC59E,
+	0xD788, 0xC8F7, 0xD789, 0xC8F8, 0xD78A, 0xC59F, 0xD78B, 0xC5A0,
+	0xD78C, 0xC8F9, 0xD78D, 0xC641, 0xD78E, 0xC642, 0xD78F, 0xC643,
+	0xD790, 0xC8FA, 0xD791, 0xC644, 0xD792, 0xC645, 0xD793, 0xC646,
+	0xD794, 0xC647, 0xD795, 0xC648, 0xD796, 0xC649, 0xD797, 0xC64A,
+	0xD798, 0xC8FB, 0xD799, 0xC8FC, 0xD79A, 0xC64B, 0xD79B, 0xC8FD,
+	0xD79C, 0xC64C, 0xD79D, 0xC8FE, 0xD79E, 0xC64D, 0xD79F, 0xC64E,
+	0xD7A0, 0xC64F, 0xD7A1, 0xC650, 0xD7A2, 0xC651, 0xD7A3, 0xC652,
+	0xF900, 0xCBD0, 0xF901, 0xCBD6, 0xF902, 0xCBE7, 0xF903, 0xCDCF,
+	0xF904, 0xCDE8, 0xF905, 0xCEAD, 0xF906, 0xCFFB, 0xF907, 0xD0A2,
+	0xF908, 0xD0B8, 0xF909, 0xD0D0, 0xF90A, 0xD0DD, 0xF90B, 0xD1D4,
+	0xF90C, 0xD1D5, 0xF90D, 0xD1D8, 0xF90E, 0xD1DB, 0xF90F, 0xD1DC,
+	0xF910, 0xD1DD, 0xF911, 0xD1DE, 0xF912, 0xD1DF, 0xF913, 0xD1E0,
+	0xF914, 0xD1E2, 0xF915, 0xD1E3, 0xF916, 0xD1E4, 0xF917, 0xD1E5,
+	0xF918, 0xD1E6, 0xF919, 0xD1E8, 0xF91A, 0xD1E9, 0xF91B, 0xD1EA,
+	0xF91C, 0xD1EB, 0xF91D, 0xD1ED, 0xF91E, 0xD1EF, 0xF91F, 0xD1F0,
+	0xF920, 0xD1F2, 0xF921, 0xD1F6, 0xF922, 0xD1FA, 0xF923, 0xD1FC,
+	0xF924, 0xD1FD, 0xF925, 0xD1FE, 0xF926, 0xD2A2, 0xF927, 0xD2A3,
+	0xF928, 0xD2A7, 0xF929, 0xD2A8, 0xF92A, 0xD2A9, 0xF92B, 0xD2AA,
+	0xF92C, 0xD2AB, 0xF92D, 0xD2AD, 0xF92E, 0xD2B2, 0xF92F, 0xD2BE,
+	0xF930, 0xD2C2, 0xF931, 0xD2C3, 0xF932, 0xD2C4, 0xF933, 0xD2C6,
+	0xF934, 0xD2C7, 0xF935, 0xD2C8, 0xF936, 0xD2C9, 0xF937, 0xD2CA,
+	0xF938, 0xD2CB, 0xF939, 0xD2CD, 0xF93A, 0xD2CE, 0xF93B, 0xD2CF,
+	0xF93C, 0xD2D0, 0xF93D, 0xD2D1, 0xF93E, 0xD2D2, 0xF93F, 0xD2D3,
+	0xF940, 0xD2D4, 0xF941, 0xD2D5, 0xF942, 0xD2D6, 0xF943, 0xD2D7,
+	0xF944, 0xD2D9, 0xF945, 0xD2DA, 0xF946, 0xD2DE, 0xF947, 0xD2DF,
+	0xF948, 0xD2E1, 0xF949, 0xD2E2, 0xF94A, 0xD2E4, 0xF94B, 0xD2E5,
+	0xF94C, 0xD2E6, 0xF94D, 0xD2E7, 0xF94E, 0xD2E8, 0xF94F, 0xD2E9,
+	0xF950, 0xD2EA, 0xF951, 0xD2EB, 0xF952, 0xD2F0, 0xF953, 0xD2F1,
+	0xF954, 0xD2F2, 0xF955, 0xD2F3, 0xF956, 0xD2F4, 0xF957, 0xD2F5,
+	0xF958, 0xD2F7, 0xF959, 0xD2F8, 0xF95A, 0xD4E6, 0xF95B, 0xD4FC,
+	0xF95C, 0xD5A5, 0xF95D, 0xD5AB, 0xF95E, 0xD5AE, 0xF95F, 0xD6B8,
+	0xF960, 0xD6CD, 0xF961, 0xD7CB, 0xF962, 0xD7E4, 0xF963, 0xDBC5,
+	0xF964, 0xDBE4, 0xF965, 0xDCA5, 0xF966, 0xDDA5, 0xF967, 0xDDD5,
+	0xF968, 0xDDF4, 0xF969, 0xDEFC, 0xF96A, 0xDEFE, 0xF96B, 0xDFB3,
+	0xF96C, 0xDFE1, 0xF96D, 0xDFE8, 0xF96E, 0xE0F1, 0xF96F, 0xE1AD,
+	0xF970, 0xE1ED, 0xF971, 0xE3F5, 0xF972, 0xE4A1, 0xF973, 0xE4A9,
+	0xF974, 0xE5AE, 0xF975, 0xE5B1, 0xF976, 0xE5B2, 0xF977, 0xE5B9,
+	0xF978, 0xE5BB, 0xF979, 0xE5BC, 0xF97A, 0xE5C4, 0xF97B, 0xE5CE,
+	0xF97C, 0xE5D0, 0xF97D, 0xE5D2, 0xF97E, 0xE5D6, 0xF97F, 0xE5FA,
+	0xF980, 0xE5FB, 0xF981, 0xE5FC, 0xF982, 0xE5FE, 0xF983, 0xE6A1,
+	0xF984, 0xE6A4, 0xF985, 0xE6A7, 0xF986, 0xE6AD, 0xF987, 0xE6AF,
+	0xF988, 0xE6B0, 0xF989, 0xE6B1, 0xF98A, 0xE6B3, 0xF98B, 0xE6B7,
+	0xF98C, 0xE6B8, 0xF98D, 0xE6BC, 0xF98E, 0xE6C4, 0xF98F, 0xE6C6,
+	0xF990, 0xE6C7, 0xF991, 0xE6CA, 0xF992, 0xE6D2, 0xF993, 0xE6D6,
+	0xF994, 0xE6D9, 0xF995, 0xE6DC, 0xF996, 0xE6DF, 0xF997, 0xE6E1,
+	0xF998, 0xE6E4, 0xF999, 0xE6E5, 0xF99A, 0xE6E6, 0xF99B, 0xE6E8,
+	0xF99C, 0xE6EA, 0xF99D, 0xE6EB, 0xF99E, 0xE6EC, 0xF99F, 0xE6EF,
+	0xF9A0, 0xE6F1, 0xF9A1, 0xE6F2, 0xF9A2, 0xE6F5, 0xF9A3, 0xE6F6,
+	0xF9A4, 0xE6F7, 0xF9A5, 0xE6F9, 0xF9A6, 0xE7A1, 0xF9A7, 0xE7A6,
+	0xF9A8, 0xE7A9, 0xF9A9, 0xE7AA, 0xF9AA, 0xE7AC, 0xF9AB, 0xE7AD,
+	0xF9AC, 0xE7B0, 0xF9AD, 0xE7BF, 0xF9AE, 0xE7C1, 0xF9AF, 0xE7C6,
+	0xF9B0, 0xE7C7, 0xF9B1, 0xE7CB, 0xF9B2, 0xE7CD, 0xF9B3, 0xE7CF,
+	0xF9B4, 0xE7D0, 0xF9B5, 0xE7D3, 0xF9B6, 0xE7DF, 0xF9B7, 0xE7E4,
+	0xF9B8, 0xE7E6, 0xF9B9, 0xE7F7, 0xF9BA, 0xE8E7, 0xF9BB, 0xE8E8,
+	0xF9BC, 0xE8F0, 0xF9BD, 0xE8F1, 0xF9BE, 0xE8F7, 0xF9BF, 0xE8F9,
+	0xF9C0, 0xE8FB, 0xF9C1, 0xE8FE, 0xF9C2, 0xE9A7, 0xF9C3, 0xE9AC,
+	0xF9C4, 0xE9CC, 0xF9C5, 0xE9F7, 0xF9C6, 0xEAC1, 0xF9C7, 0xEAE5,
+	0xF9C8, 0xEAF4, 0xF9C9, 0xEAF7, 0xF9CA, 0xEAFC, 0xF9CB, 0xEAFE,
+	0xF9CC, 0xEBA4, 0xF9CD, 0xEBA7, 0xF9CE, 0xEBA9, 0xF9CF, 0xEBAA,
+	0xF9D0, 0xEBBA, 0xF9D1, 0xEBBB, 0xF9D2, 0xEBBD, 0xF9D3, 0xEBC1,
+	0xF9D4, 0xEBC2, 0xF9D5, 0xEBC6, 0xF9D6, 0xEBC7, 0xF9D7, 0xEBCC,
+	0xF9D8, 0xEBCF, 0xF9D9, 0xEBD0, 0xF9DA, 0xEBD1, 0xF9DB, 0xEBD2,
+	0xF9DC, 0xEBD8, 0xF9DD, 0xECA6, 0xF9DE, 0xECA7, 0xF9DF, 0xECAA,
+	0xF9E0, 0xECAF, 0xF9E1, 0xECB0, 0xF9E2, 0xECB1, 0xF9E3, 0xECB2,
+	0xF9E4, 0xECB5, 0xF9E5, 0xECB8, 0xF9E6, 0xECBA, 0xF9E7, 0xECC0,
+	0xF9E8, 0xECC1, 0xF9E9, 0xECC5, 0xF9EA, 0xECC6, 0xF9EB, 0xECC9,
+	0xF9EC, 0xECCA, 0xF9ED, 0xECD5, 0xF9EE, 0xECDD, 0xF9EF, 0xECDE,
+	0xF9F0, 0xECE1, 0xF9F1, 0xECE4, 0xF9F2, 0xECE7, 0xF9F3, 0xECE8,
+	0xF9F4, 0xECF7, 0xF9F5, 0xECF8, 0xF9F6, 0xECFA, 0xF9F7, 0xEDA1,
+	0xF9F8, 0xEDA2, 0xF9F9, 0xEDA3, 0xF9FA, 0xEDEE, 0xF9FB, 0xEEDB,
+	0xF9FC, 0xF2BD, 0xF9FD, 0xF2FA, 0xF9FE, 0xF3B1, 0xF9FF, 0xF4A7,
+	0xFA00, 0xF4EE, 0xFA01, 0xF6F4, 0xFA02, 0xF6F6, 0xFA03, 0xF7B8,
+	0xFA04, 0xF7C8, 0xFA05, 0xF7D3, 0xFA06, 0xF8DB, 0xFA07, 0xF8F0,
+	0xFA08, 0xFAA1, 0xFA09, 0xFAA2, 0xFA0A, 0xFAE6, 0xFA0B, 0xFCA9,
+	0xFF01, 0xA3A1, 0xFF02, 0xA3A2, 0xFF03, 0xA3A3, 0xFF04, 0xA3A4,
+	0xFF05, 0xA3A5, 0xFF06, 0xA3A6, 0xFF07, 0xA3A7, 0xFF08, 0xA3A8,
+	0xFF09, 0xA3A9, 0xFF0A, 0xA3AA, 0xFF0B, 0xA3AB, 0xFF0C, 0xA3AC,
+	0xFF0D, 0xA3AD, 0xFF0E, 0xA3AE, 0xFF0F, 0xA3AF, 0xFF10, 0xA3B0,
+	0xFF11, 0xA3B1, 0xFF12, 0xA3B2, 0xFF13, 0xA3B3, 0xFF14, 0xA3B4,
+	0xFF15, 0xA3B5, 0xFF16, 0xA3B6, 0xFF17, 0xA3B7, 0xFF18, 0xA3B8,
+	0xFF19, 0xA3B9, 0xFF1A, 0xA3BA, 0xFF1B, 0xA3BB, 0xFF1C, 0xA3BC,
+	0xFF1D, 0xA3BD, 0xFF1E, 0xA3BE, 0xFF1F, 0xA3BF, 0xFF20, 0xA3C0,
+	0xFF21, 0xA3C1, 0xFF22, 0xA3C2, 0xFF23, 0xA3C3, 0xFF24, 0xA3C4,
+	0xFF25, 0xA3C5, 0xFF26, 0xA3C6, 0xFF27, 0xA3C7, 0xFF28, 0xA3C8,
+	0xFF29, 0xA3C9, 0xFF2A, 0xA3CA, 0xFF2B, 0xA3CB, 0xFF2C, 0xA3CC,
+	0xFF2D, 0xA3CD, 0xFF2E, 0xA3CE, 0xFF2F, 0xA3CF, 0xFF30, 0xA3D0,
+	0xFF31, 0xA3D1, 0xFF32, 0xA3D2, 0xFF33, 0xA3D3, 0xFF34, 0xA3D4,
+	0xFF35, 0xA3D5, 0xFF36, 0xA3D6, 0xFF37, 0xA3D7, 0xFF38, 0xA3D8,
+	0xFF39, 0xA3D9, 0xFF3A, 0xA3DA, 0xFF3B, 0xA3DB, 0xFF3C, 0xA1AC,
+	0xFF3D, 0xA3DD, 0xFF3E, 0xA3DE, 0xFF3F, 0xA3DF, 0xFF40, 0xA3E0,
+	0xFF41, 0xA3E1, 0xFF42, 0xA3E2, 0xFF43, 0xA3E3, 0xFF44, 0xA3E4,
+	0xFF45, 0xA3E5, 0xFF46, 0xA3E6, 0xFF47, 0xA3E7, 0xFF48, 0xA3E8,
+	0xFF49, 0xA3E9, 0xFF4A, 0xA3EA, 0xFF4B, 0xA3EB, 0xFF4C, 0xA3EC,
+	0xFF4D, 0xA3ED, 0xFF4E, 0xA3EE, 0xFF4F, 0xA3EF, 0xFF50, 0xA3F0,
+	0xFF51, 0xA3F1, 0xFF52, 0xA3F2, 0xFF53, 0xA3F3, 0xFF54, 0xA3F4,
+	0xFF55, 0xA3F5, 0xFF56, 0xA3F6, 0xFF57, 0xA3F7, 0xFF58, 0xA3F8,
+	0xFF59, 0xA3F9, 0xFF5A, 0xA3FA, 0xFF5B, 0xA3FB, 0xFF5C, 0xA3FC,
+	0xFF5D, 0xA3FD, 0xFF5E, 0xA2A6, 0xFFE0, 0xA1CB, 0xFFE1, 0xA1CC,
+	0xFFE2, 0xA1FE, 0xFFE3, 0xA3FE, 0xFFE5, 0xA1CD, 0xFFE6, 0xA3DC,
+	0, 0
+};
+
+static
+const WCHAR oem2uni[] = {
+/*	OEM - Unicode,  OEM - Unicode,  OEM - Unicode,  OEM - Unicode */
+	0x8141, 0xAC02, 0x8142, 0xAC03, 0x8143, 0xAC05, 0x8144, 0xAC06,
+	0x8145, 0xAC0B, 0x8146, 0xAC0C, 0x8147, 0xAC0D, 0x8148, 0xAC0E,
+	0x8149, 0xAC0F, 0x814A, 0xAC18, 0x814B, 0xAC1E, 0x814C, 0xAC1F,
+	0x814D, 0xAC21, 0x814E, 0xAC22, 0x814F, 0xAC23, 0x8150, 0xAC25,
+	0x8151, 0xAC26, 0x8152, 0xAC27, 0x8153, 0xAC28, 0x8154, 0xAC29,
+	0x8155, 0xAC2A, 0x8156, 0xAC2B, 0x8157, 0xAC2E, 0x8158, 0xAC32,
+	0x8159, 0xAC33, 0x815A, 0xAC34, 0x8161, 0xAC35, 0x8162, 0xAC36,
+	0x8163, 0xAC37, 0x8164, 0xAC3A, 0x8165, 0xAC3B, 0x8166, 0xAC3D,
+	0x8167, 0xAC3E, 0x8168, 0xAC3F, 0x8169, 0xAC41, 0x816A, 0xAC42,
+	0x816B, 0xAC43, 0x816C, 0xAC44, 0x816D, 0xAC45, 0x816E, 0xAC46,
+	0x816F, 0xAC47, 0x8170, 0xAC48, 0x8171, 0xAC49, 0x8172, 0xAC4A,
+	0x8173, 0xAC4C, 0x8174, 0xAC4E, 0x8175, 0xAC4F, 0x8176, 0xAC50,
+	0x8177, 0xAC51, 0x8178, 0xAC52, 0x8179, 0xAC53, 0x817A, 0xAC55,
+	0x8181, 0xAC56, 0x8182, 0xAC57, 0x8183, 0xAC59, 0x8184, 0xAC5A,
+	0x8185, 0xAC5B, 0x8186, 0xAC5D, 0x8187, 0xAC5E, 0x8188, 0xAC5F,
+	0x8189, 0xAC60, 0x818A, 0xAC61, 0x818B, 0xAC62, 0x818C, 0xAC63,
+	0x818D, 0xAC64, 0x818E, 0xAC65, 0x818F, 0xAC66, 0x8190, 0xAC67,
+	0x8191, 0xAC68, 0x8192, 0xAC69, 0x8193, 0xAC6A, 0x8194, 0xAC6B,
+	0x8195, 0xAC6C, 0x8196, 0xAC6D, 0x8197, 0xAC6E, 0x8198, 0xAC6F,
+	0x8199, 0xAC72, 0x819A, 0xAC73, 0x819B, 0xAC75, 0x819C, 0xAC76,
+	0x819D, 0xAC79, 0x819E, 0xAC7B, 0x819F, 0xAC7C, 0x81A0, 0xAC7D,
+	0x81A1, 0xAC7E, 0x81A2, 0xAC7F, 0x81A3, 0xAC82, 0x81A4, 0xAC87,
+	0x81A5, 0xAC88, 0x81A6, 0xAC8D, 0x81A7, 0xAC8E, 0x81A8, 0xAC8F,
+	0x81A9, 0xAC91, 0x81AA, 0xAC92, 0x81AB, 0xAC93, 0x81AC, 0xAC95,
+	0x81AD, 0xAC96, 0x81AE, 0xAC97, 0x81AF, 0xAC98, 0x81B0, 0xAC99,
+	0x81B1, 0xAC9A, 0x81B2, 0xAC9B, 0x81B3, 0xAC9E, 0x81B4, 0xACA2,
+	0x81B5, 0xACA3, 0x81B6, 0xACA4, 0x81B7, 0xACA5, 0x81B8, 0xACA6,
+	0x81B9, 0xACA7, 0x81BA, 0xACAB, 0x81BB, 0xACAD, 0x81BC, 0xACAE,
+	0x81BD, 0xACB1, 0x81BE, 0xACB2, 0x81BF, 0xACB3, 0x81C0, 0xACB4,
+	0x81C1, 0xACB5, 0x81C2, 0xACB6, 0x81C3, 0xACB7, 0x81C4, 0xACBA,
+	0x81C5, 0xACBE, 0x81C6, 0xACBF, 0x81C7, 0xACC0, 0x81C8, 0xACC2,
+	0x81C9, 0xACC3, 0x81CA, 0xACC5, 0x81CB, 0xACC6, 0x81CC, 0xACC7,
+	0x81CD, 0xACC9, 0x81CE, 0xACCA, 0x81CF, 0xACCB, 0x81D0, 0xACCD,
+	0x81D1, 0xACCE, 0x81D2, 0xACCF, 0x81D3, 0xACD0, 0x81D4, 0xACD1,
+	0x81D5, 0xACD2, 0x81D6, 0xACD3, 0x81D7, 0xACD4, 0x81D8, 0xACD6,
+	0x81D9, 0xACD8, 0x81DA, 0xACD9, 0x81DB, 0xACDA, 0x81DC, 0xACDB,
+	0x81DD, 0xACDC, 0x81DE, 0xACDD, 0x81DF, 0xACDE, 0x81E0, 0xACDF,
+	0x81E1, 0xACE2, 0x81E2, 0xACE3, 0x81E3, 0xACE5, 0x81E4, 0xACE6,
+	0x81E5, 0xACE9, 0x81E6, 0xACEB, 0x81E7, 0xACED, 0x81E8, 0xACEE,
+	0x81E9, 0xACF2, 0x81EA, 0xACF4, 0x81EB, 0xACF7, 0x81EC, 0xACF8,
+	0x81ED, 0xACF9, 0x81EE, 0xACFA, 0x81EF, 0xACFB, 0x81F0, 0xACFE,
+	0x81F1, 0xACFF, 0x81F2, 0xAD01, 0x81F3, 0xAD02, 0x81F4, 0xAD03,
+	0x81F5, 0xAD05, 0x81F6, 0xAD07, 0x81F7, 0xAD08, 0x81F8, 0xAD09,
+	0x81F9, 0xAD0A, 0x81FA, 0xAD0B, 0x81FB, 0xAD0E, 0x81FC, 0xAD10,
+	0x81FD, 0xAD12, 0x81FE, 0xAD13, 0x8241, 0xAD14, 0x8242, 0xAD15,
+	0x8243, 0xAD16, 0x8244, 0xAD17, 0x8245, 0xAD19, 0x8246, 0xAD1A,
+	0x8247, 0xAD1B, 0x8248, 0xAD1D, 0x8249, 0xAD1E, 0x824A, 0xAD1F,
+	0x824B, 0xAD21, 0x824C, 0xAD22, 0x824D, 0xAD23, 0x824E, 0xAD24,
+	0x824F, 0xAD25, 0x8250, 0xAD26, 0x8251, 0xAD27, 0x8252, 0xAD28,
+	0x8253, 0xAD2A, 0x8254, 0xAD2B, 0x8255, 0xAD2E, 0x8256, 0xAD2F,
+	0x8257, 0xAD30, 0x8258, 0xAD31, 0x8259, 0xAD32, 0x825A, 0xAD33,
+	0x8261, 0xAD36, 0x8262, 0xAD37, 0x8263, 0xAD39, 0x8264, 0xAD3A,
+	0x8265, 0xAD3B, 0x8266, 0xAD3D, 0x8267, 0xAD3E, 0x8268, 0xAD3F,
+	0x8269, 0xAD40, 0x826A, 0xAD41, 0x826B, 0xAD42, 0x826C, 0xAD43,
+	0x826D, 0xAD46, 0x826E, 0xAD48, 0x826F, 0xAD4A, 0x8270, 0xAD4B,
+	0x8271, 0xAD4C, 0x8272, 0xAD4D, 0x8273, 0xAD4E, 0x8274, 0xAD4F,
+	0x8275, 0xAD51, 0x8276, 0xAD52, 0x8277, 0xAD53, 0x8278, 0xAD55,
+	0x8279, 0xAD56, 0x827A, 0xAD57, 0x8281, 0xAD59, 0x8282, 0xAD5A,
+	0x8283, 0xAD5B, 0x8284, 0xAD5C, 0x8285, 0xAD5D, 0x8286, 0xAD5E,
+	0x8287, 0xAD5F, 0x8288, 0xAD60, 0x8289, 0xAD62, 0x828A, 0xAD64,
+	0x828B, 0xAD65, 0x828C, 0xAD66, 0x828D, 0xAD67, 0x828E, 0xAD68,
+	0x828F, 0xAD69, 0x8290, 0xAD6A, 0x8291, 0xAD6B, 0x8292, 0xAD6E,
+	0x8293, 0xAD6F, 0x8294, 0xAD71, 0x8295, 0xAD72, 0x8296, 0xAD77,
+	0x8297, 0xAD78, 0x8298, 0xAD79, 0x8299, 0xAD7A, 0x829A, 0xAD7E,
+	0x829B, 0xAD80, 0x829C, 0xAD83, 0x829D, 0xAD84, 0x829E, 0xAD85,
+	0x829F, 0xAD86, 0x82A0, 0xAD87, 0x82A1, 0xAD8A, 0x82A2, 0xAD8B,
+	0x82A3, 0xAD8D, 0x82A4, 0xAD8E, 0x82A5, 0xAD8F, 0x82A6, 0xAD91,
+	0x82A7, 0xAD92, 0x82A8, 0xAD93, 0x82A9, 0xAD94, 0x82AA, 0xAD95,
+	0x82AB, 0xAD96, 0x82AC, 0xAD97, 0x82AD, 0xAD98, 0x82AE, 0xAD99,
+	0x82AF, 0xAD9A, 0x82B0, 0xAD9B, 0x82B1, 0xAD9E, 0x82B2, 0xAD9F,
+	0x82B3, 0xADA0, 0x82B4, 0xADA1, 0x82B5, 0xADA2, 0x82B6, 0xADA3,
+	0x82B7, 0xADA5, 0x82B8, 0xADA6, 0x82B9, 0xADA7, 0x82BA, 0xADA8,
+	0x82BB, 0xADA9, 0x82BC, 0xADAA, 0x82BD, 0xADAB, 0x82BE, 0xADAC,
+	0x82BF, 0xADAD, 0x82C0, 0xADAE, 0x82C1, 0xADAF, 0x82C2, 0xADB0,
+	0x82C3, 0xADB1, 0x82C4, 0xADB2, 0x82C5, 0xADB3, 0x82C6, 0xADB4,
+	0x82C7, 0xADB5, 0x82C8, 0xADB6, 0x82C9, 0xADB8, 0x82CA, 0xADB9,
+	0x82CB, 0xADBA, 0x82CC, 0xADBB, 0x82CD, 0xADBC, 0x82CE, 0xADBD,
+	0x82CF, 0xADBE, 0x82D0, 0xADBF, 0x82D1, 0xADC2, 0x82D2, 0xADC3,
+	0x82D3, 0xADC5, 0x82D4, 0xADC6, 0x82D5, 0xADC7, 0x82D6, 0xADC9,
+	0x82D7, 0xADCA, 0x82D8, 0xADCB, 0x82D9, 0xADCC, 0x82DA, 0xADCD,
+	0x82DB, 0xADCE, 0x82DC, 0xADCF, 0x82DD, 0xADD2, 0x82DE, 0xADD4,
+	0x82DF, 0xADD5, 0x82E0, 0xADD6, 0x82E1, 0xADD7, 0x82E2, 0xADD8,
+	0x82E3, 0xADD9, 0x82E4, 0xADDA, 0x82E5, 0xADDB, 0x82E6, 0xADDD,
+	0x82E7, 0xADDE, 0x82E8, 0xADDF, 0x82E9, 0xADE1, 0x82EA, 0xADE2,
+	0x82EB, 0xADE3, 0x82EC, 0xADE5, 0x82ED, 0xADE6, 0x82EE, 0xADE7,
+	0x82EF, 0xADE8, 0x82F0, 0xADE9, 0x82F1, 0xADEA, 0x82F2, 0xADEB,
+	0x82F3, 0xADEC, 0x82F4, 0xADED, 0x82F5, 0xADEE, 0x82F6, 0xADEF,
+	0x82F7, 0xADF0, 0x82F8, 0xADF1, 0x82F9, 0xADF2, 0x82FA, 0xADF3,
+	0x82FB, 0xADF4, 0x82FC, 0xADF5, 0x82FD, 0xADF6, 0x82FE, 0xADF7,
+	0x8341, 0xADFA, 0x8342, 0xADFB, 0x8343, 0xADFD, 0x8344, 0xADFE,
+	0x8345, 0xAE02, 0x8346, 0xAE03, 0x8347, 0xAE04, 0x8348, 0xAE05,
+	0x8349, 0xAE06, 0x834A, 0xAE07, 0x834B, 0xAE0A, 0x834C, 0xAE0C,
+	0x834D, 0xAE0E, 0x834E, 0xAE0F, 0x834F, 0xAE10, 0x8350, 0xAE11,
+	0x8351, 0xAE12, 0x8352, 0xAE13, 0x8353, 0xAE15, 0x8354, 0xAE16,
+	0x8355, 0xAE17, 0x8356, 0xAE18, 0x8357, 0xAE19, 0x8358, 0xAE1A,
+	0x8359, 0xAE1B, 0x835A, 0xAE1C, 0x8361, 0xAE1D, 0x8362, 0xAE1E,
+	0x8363, 0xAE1F, 0x8364, 0xAE20, 0x8365, 0xAE21, 0x8366, 0xAE22,
+	0x8367, 0xAE23, 0x8368, 0xAE24, 0x8369, 0xAE25, 0x836A, 0xAE26,
+	0x836B, 0xAE27, 0x836C, 0xAE28, 0x836D, 0xAE29, 0x836E, 0xAE2A,
+	0x836F, 0xAE2B, 0x8370, 0xAE2C, 0x8371, 0xAE2D, 0x8372, 0xAE2E,
+	0x8373, 0xAE2F, 0x8374, 0xAE32, 0x8375, 0xAE33, 0x8376, 0xAE35,
+	0x8377, 0xAE36, 0x8378, 0xAE39, 0x8379, 0xAE3B, 0x837A, 0xAE3C,
+	0x8381, 0xAE3D, 0x8382, 0xAE3E, 0x8383, 0xAE3F, 0x8384, 0xAE42,
+	0x8385, 0xAE44, 0x8386, 0xAE47, 0x8387, 0xAE48, 0x8388, 0xAE49,
+	0x8389, 0xAE4B, 0x838A, 0xAE4F, 0x838B, 0xAE51, 0x838C, 0xAE52,
+	0x838D, 0xAE53, 0x838E, 0xAE55, 0x838F, 0xAE57, 0x8390, 0xAE58,
+	0x8391, 0xAE59, 0x8392, 0xAE5A, 0x8393, 0xAE5B, 0x8394, 0xAE5E,
+	0x8395, 0xAE62, 0x8396, 0xAE63, 0x8397, 0xAE64, 0x8398, 0xAE66,
+	0x8399, 0xAE67, 0x839A, 0xAE6A, 0x839B, 0xAE6B, 0x839C, 0xAE6D,
+	0x839D, 0xAE6E, 0x839E, 0xAE6F, 0x839F, 0xAE71, 0x83A0, 0xAE72,
+	0x83A1, 0xAE73, 0x83A2, 0xAE74, 0x83A3, 0xAE75, 0x83A4, 0xAE76,
+	0x83A5, 0xAE77, 0x83A6, 0xAE7A, 0x83A7, 0xAE7E, 0x83A8, 0xAE7F,
+	0x83A9, 0xAE80, 0x83AA, 0xAE81, 0x83AB, 0xAE82, 0x83AC, 0xAE83,
+	0x83AD, 0xAE86, 0x83AE, 0xAE87, 0x83AF, 0xAE88, 0x83B0, 0xAE89,
+	0x83B1, 0xAE8A, 0x83B2, 0xAE8B, 0x83B3, 0xAE8D, 0x83B4, 0xAE8E,
+	0x83B5, 0xAE8F, 0x83B6, 0xAE90, 0x83B7, 0xAE91, 0x83B8, 0xAE92,
+	0x83B9, 0xAE93, 0x83BA, 0xAE94, 0x83BB, 0xAE95, 0x83BC, 0xAE96,
+	0x83BD, 0xAE97, 0x83BE, 0xAE98, 0x83BF, 0xAE99, 0x83C0, 0xAE9A,
+	0x83C1, 0xAE9B, 0x83C2, 0xAE9C, 0x83C3, 0xAE9D, 0x83C4, 0xAE9E,
+	0x83C5, 0xAE9F, 0x83C6, 0xAEA0, 0x83C7, 0xAEA1, 0x83C8, 0xAEA2,
+	0x83C9, 0xAEA3, 0x83CA, 0xAEA4, 0x83CB, 0xAEA5, 0x83CC, 0xAEA6,
+	0x83CD, 0xAEA7, 0x83CE, 0xAEA8, 0x83CF, 0xAEA9, 0x83D0, 0xAEAA,
+	0x83D1, 0xAEAB, 0x83D2, 0xAEAC, 0x83D3, 0xAEAD, 0x83D4, 0xAEAE,
+	0x83D5, 0xAEAF, 0x83D6, 0xAEB0, 0x83D7, 0xAEB1, 0x83D8, 0xAEB2,
+	0x83D9, 0xAEB3, 0x83DA, 0xAEB4, 0x83DB, 0xAEB5, 0x83DC, 0xAEB6,
+	0x83DD, 0xAEB7, 0x83DE, 0xAEB8, 0x83DF, 0xAEB9, 0x83E0, 0xAEBA,
+	0x83E1, 0xAEBB, 0x83E2, 0xAEBF, 0x83E3, 0xAEC1, 0x83E4, 0xAEC2,
+	0x83E5, 0xAEC3, 0x83E6, 0xAEC5, 0x83E7, 0xAEC6, 0x83E8, 0xAEC7,
+	0x83E9, 0xAEC8, 0x83EA, 0xAEC9, 0x83EB, 0xAECA, 0x83EC, 0xAECB,
+	0x83ED, 0xAECE, 0x83EE, 0xAED2, 0x83EF, 0xAED3, 0x83F0, 0xAED4,
+	0x83F1, 0xAED5, 0x83F2, 0xAED6, 0x83F3, 0xAED7, 0x83F4, 0xAEDA,
+	0x83F5, 0xAEDB, 0x83F6, 0xAEDD, 0x83F7, 0xAEDE, 0x83F8, 0xAEDF,
+	0x83F9, 0xAEE0, 0x83FA, 0xAEE1, 0x83FB, 0xAEE2, 0x83FC, 0xAEE3,
+	0x83FD, 0xAEE4, 0x83FE, 0xAEE5, 0x8441, 0xAEE6, 0x8442, 0xAEE7,
+	0x8443, 0xAEE9, 0x8444, 0xAEEA, 0x8445, 0xAEEC, 0x8446, 0xAEEE,
+	0x8447, 0xAEEF, 0x8448, 0xAEF0, 0x8449, 0xAEF1, 0x844A, 0xAEF2,
+	0x844B, 0xAEF3, 0x844C, 0xAEF5, 0x844D, 0xAEF6, 0x844E, 0xAEF7,
+	0x844F, 0xAEF9, 0x8450, 0xAEFA, 0x8451, 0xAEFB, 0x8452, 0xAEFD,
+	0x8453, 0xAEFE, 0x8454, 0xAEFF, 0x8455, 0xAF00, 0x8456, 0xAF01,
+	0x8457, 0xAF02, 0x8458, 0xAF03, 0x8459, 0xAF04, 0x845A, 0xAF05,
+	0x8461, 0xAF06, 0x8462, 0xAF09, 0x8463, 0xAF0A, 0x8464, 0xAF0B,
+	0x8465, 0xAF0C, 0x8466, 0xAF0E, 0x8467, 0xAF0F, 0x8468, 0xAF11,
+	0x8469, 0xAF12, 0x846A, 0xAF13, 0x846B, 0xAF14, 0x846C, 0xAF15,
+	0x846D, 0xAF16, 0x846E, 0xAF17, 0x846F, 0xAF18, 0x8470, 0xAF19,
+	0x8471, 0xAF1A, 0x8472, 0xAF1B, 0x8473, 0xAF1C, 0x8474, 0xAF1D,
+	0x8475, 0xAF1E, 0x8476, 0xAF1F, 0x8477, 0xAF20, 0x8478, 0xAF21,
+	0x8479, 0xAF22, 0x847A, 0xAF23, 0x8481, 0xAF24, 0x8482, 0xAF25,
+	0x8483, 0xAF26, 0x8484, 0xAF27, 0x8485, 0xAF28, 0x8486, 0xAF29,
+	0x8487, 0xAF2A, 0x8488, 0xAF2B, 0x8489, 0xAF2E, 0x848A, 0xAF2F,
+	0x848B, 0xAF31, 0x848C, 0xAF33, 0x848D, 0xAF35, 0x848E, 0xAF36,
+	0x848F, 0xAF37, 0x8490, 0xAF38, 0x8491, 0xAF39, 0x8492, 0xAF3A,
+	0x8493, 0xAF3B, 0x8494, 0xAF3E, 0x8495, 0xAF40, 0x8496, 0xAF44,
+	0x8497, 0xAF45, 0x8498, 0xAF46, 0x8499, 0xAF47, 0x849A, 0xAF4A,
+	0x849B, 0xAF4B, 0x849C, 0xAF4C, 0x849D, 0xAF4D, 0x849E, 0xAF4E,
+	0x849F, 0xAF4F, 0x84A0, 0xAF51, 0x84A1, 0xAF52, 0x84A2, 0xAF53,
+	0x84A3, 0xAF54, 0x84A4, 0xAF55, 0x84A5, 0xAF56, 0x84A6, 0xAF57,
+	0x84A7, 0xAF58, 0x84A8, 0xAF59, 0x84A9, 0xAF5A, 0x84AA, 0xAF5B,
+	0x84AB, 0xAF5E, 0x84AC, 0xAF5F, 0x84AD, 0xAF60, 0x84AE, 0xAF61,
+	0x84AF, 0xAF62, 0x84B0, 0xAF63, 0x84B1, 0xAF66, 0x84B2, 0xAF67,
+	0x84B3, 0xAF68, 0x84B4, 0xAF69, 0x84B5, 0xAF6A, 0x84B6, 0xAF6B,
+	0x84B7, 0xAF6C, 0x84B8, 0xAF6D, 0x84B9, 0xAF6E, 0x84BA, 0xAF6F,
+	0x84BB, 0xAF70, 0x84BC, 0xAF71, 0x84BD, 0xAF72, 0x84BE, 0xAF73,
+	0x84BF, 0xAF74, 0x84C0, 0xAF75, 0x84C1, 0xAF76, 0x84C2, 0xAF77,
+	0x84C3, 0xAF78, 0x84C4, 0xAF7A, 0x84C5, 0xAF7B, 0x84C6, 0xAF7C,
+	0x84C7, 0xAF7D, 0x84C8, 0xAF7E, 0x84C9, 0xAF7F, 0x84CA, 0xAF81,
+	0x84CB, 0xAF82, 0x84CC, 0xAF83, 0x84CD, 0xAF85, 0x84CE, 0xAF86,
+	0x84CF, 0xAF87, 0x84D0, 0xAF89, 0x84D1, 0xAF8A, 0x84D2, 0xAF8B,
+	0x84D3, 0xAF8C, 0x84D4, 0xAF8D, 0x84D5, 0xAF8E, 0x84D6, 0xAF8F,
+	0x84D7, 0xAF92, 0x84D8, 0xAF93, 0x84D9, 0xAF94, 0x84DA, 0xAF96,
+	0x84DB, 0xAF97, 0x84DC, 0xAF98, 0x84DD, 0xAF99, 0x84DE, 0xAF9A,
+	0x84DF, 0xAF9B, 0x84E0, 0xAF9D, 0x84E1, 0xAF9E, 0x84E2, 0xAF9F,
+	0x84E3, 0xAFA0, 0x84E4, 0xAFA1, 0x84E5, 0xAFA2, 0x84E6, 0xAFA3,
+	0x84E7, 0xAFA4, 0x84E8, 0xAFA5, 0x84E9, 0xAFA6, 0x84EA, 0xAFA7,
+	0x84EB, 0xAFA8, 0x84EC, 0xAFA9, 0x84ED, 0xAFAA, 0x84EE, 0xAFAB,
+	0x84EF, 0xAFAC, 0x84F0, 0xAFAD, 0x84F1, 0xAFAE, 0x84F2, 0xAFAF,
+	0x84F3, 0xAFB0, 0x84F4, 0xAFB1, 0x84F5, 0xAFB2, 0x84F6, 0xAFB3,
+	0x84F7, 0xAFB4, 0x84F8, 0xAFB5, 0x84F9, 0xAFB6, 0x84FA, 0xAFB7,
+	0x84FB, 0xAFBA, 0x84FC, 0xAFBB, 0x84FD, 0xAFBD, 0x84FE, 0xAFBE,
+	0x8541, 0xAFBF, 0x8542, 0xAFC1, 0x8543, 0xAFC2, 0x8544, 0xAFC3,
+	0x8545, 0xAFC4, 0x8546, 0xAFC5, 0x8547, 0xAFC6, 0x8548, 0xAFCA,
+	0x8549, 0xAFCC, 0x854A, 0xAFCF, 0x854B, 0xAFD0, 0x854C, 0xAFD1,
+	0x854D, 0xAFD2, 0x854E, 0xAFD3, 0x854F, 0xAFD5, 0x8550, 0xAFD6,
+	0x8551, 0xAFD7, 0x8552, 0xAFD8, 0x8553, 0xAFD9, 0x8554, 0xAFDA,
+	0x8555, 0xAFDB, 0x8556, 0xAFDD, 0x8557, 0xAFDE, 0x8558, 0xAFDF,
+	0x8559, 0xAFE0, 0x855A, 0xAFE1, 0x8561, 0xAFE2, 0x8562, 0xAFE3,
+	0x8563, 0xAFE4, 0x8564, 0xAFE5, 0x8565, 0xAFE6, 0x8566, 0xAFE7,
+	0x8567, 0xAFEA, 0x8568, 0xAFEB, 0x8569, 0xAFEC, 0x856A, 0xAFED,
+	0x856B, 0xAFEE, 0x856C, 0xAFEF, 0x856D, 0xAFF2, 0x856E, 0xAFF3,
+	0x856F, 0xAFF5, 0x8570, 0xAFF6, 0x8571, 0xAFF7, 0x8572, 0xAFF9,
+	0x8573, 0xAFFA, 0x8574, 0xAFFB, 0x8575, 0xAFFC, 0x8576, 0xAFFD,
+	0x8577, 0xAFFE, 0x8578, 0xAFFF, 0x8579, 0xB002, 0x857A, 0xB003,
+	0x8581, 0xB005, 0x8582, 0xB006, 0x8583, 0xB007, 0x8584, 0xB008,
+	0x8585, 0xB009, 0x8586, 0xB00A, 0x8587, 0xB00B, 0x8588, 0xB00D,
+	0x8589, 0xB00E, 0x858A, 0xB00F, 0x858B, 0xB011, 0x858C, 0xB012,
+	0x858D, 0xB013, 0x858E, 0xB015, 0x858F, 0xB016, 0x8590, 0xB017,
+	0x8591, 0xB018, 0x8592, 0xB019, 0x8593, 0xB01A, 0x8594, 0xB01B,
+	0x8595, 0xB01E, 0x8596, 0xB01F, 0x8597, 0xB020, 0x8598, 0xB021,
+	0x8599, 0xB022, 0x859A, 0xB023, 0x859B, 0xB024, 0x859C, 0xB025,
+	0x859D, 0xB026, 0x859E, 0xB027, 0x859F, 0xB029, 0x85A0, 0xB02A,
+	0x85A1, 0xB02B, 0x85A2, 0xB02C, 0x85A3, 0xB02D, 0x85A4, 0xB02E,
+	0x85A5, 0xB02F, 0x85A6, 0xB030, 0x85A7, 0xB031, 0x85A8, 0xB032,
+	0x85A9, 0xB033, 0x85AA, 0xB034, 0x85AB, 0xB035, 0x85AC, 0xB036,
+	0x85AD, 0xB037, 0x85AE, 0xB038, 0x85AF, 0xB039, 0x85B0, 0xB03A,
+	0x85B1, 0xB03B, 0x85B2, 0xB03C, 0x85B3, 0xB03D, 0x85B4, 0xB03E,
+	0x85B5, 0xB03F, 0x85B6, 0xB040, 0x85B7, 0xB041, 0x85B8, 0xB042,
+	0x85B9, 0xB043, 0x85BA, 0xB046, 0x85BB, 0xB047, 0x85BC, 0xB049,
+	0x85BD, 0xB04B, 0x85BE, 0xB04D, 0x85BF, 0xB04F, 0x85C0, 0xB050,
+	0x85C1, 0xB051, 0x85C2, 0xB052, 0x85C3, 0xB056, 0x85C4, 0xB058,
+	0x85C5, 0xB05A, 0x85C6, 0xB05B, 0x85C7, 0xB05C, 0x85C8, 0xB05E,
+	0x85C9, 0xB05F, 0x85CA, 0xB060, 0x85CB, 0xB061, 0x85CC, 0xB062,
+	0x85CD, 0xB063, 0x85CE, 0xB064, 0x85CF, 0xB065, 0x85D0, 0xB066,
+	0x85D1, 0xB067, 0x85D2, 0xB068, 0x85D3, 0xB069, 0x85D4, 0xB06A,
+	0x85D5, 0xB06B, 0x85D6, 0xB06C, 0x85D7, 0xB06D, 0x85D8, 0xB06E,
+	0x85D9, 0xB06F, 0x85DA, 0xB070, 0x85DB, 0xB071, 0x85DC, 0xB072,
+	0x85DD, 0xB073, 0x85DE, 0xB074, 0x85DF, 0xB075, 0x85E0, 0xB076,
+	0x85E1, 0xB077, 0x85E2, 0xB078, 0x85E3, 0xB079, 0x85E4, 0xB07A,
+	0x85E5, 0xB07B, 0x85E6, 0xB07E, 0x85E7, 0xB07F, 0x85E8, 0xB081,
+	0x85E9, 0xB082, 0x85EA, 0xB083, 0x85EB, 0xB085, 0x85EC, 0xB086,
+	0x85ED, 0xB087, 0x85EE, 0xB088, 0x85EF, 0xB089, 0x85F0, 0xB08A,
+	0x85F1, 0xB08B, 0x85F2, 0xB08E, 0x85F3, 0xB090, 0x85F4, 0xB092,
+	0x85F5, 0xB093, 0x85F6, 0xB094, 0x85F7, 0xB095, 0x85F8, 0xB096,
+	0x85F9, 0xB097, 0x85FA, 0xB09B, 0x85FB, 0xB09D, 0x85FC, 0xB09E,
+	0x85FD, 0xB0A3, 0x85FE, 0xB0A4, 0x8641, 0xB0A5, 0x8642, 0xB0A6,
+	0x8643, 0xB0A7, 0x8644, 0xB0AA, 0x8645, 0xB0B0, 0x8646, 0xB0B2,
+	0x8647, 0xB0B6, 0x8648, 0xB0B7, 0x8649, 0xB0B9, 0x864A, 0xB0BA,
+	0x864B, 0xB0BB, 0x864C, 0xB0BD, 0x864D, 0xB0BE, 0x864E, 0xB0BF,
+	0x864F, 0xB0C0, 0x8650, 0xB0C1, 0x8651, 0xB0C2, 0x8652, 0xB0C3,
+	0x8653, 0xB0C6, 0x8654, 0xB0CA, 0x8655, 0xB0CB, 0x8656, 0xB0CC,
+	0x8657, 0xB0CD, 0x8658, 0xB0CE, 0x8659, 0xB0CF, 0x865A, 0xB0D2,
+	0x8661, 0xB0D3, 0x8662, 0xB0D5, 0x8663, 0xB0D6, 0x8664, 0xB0D7,
+	0x8665, 0xB0D9, 0x8666, 0xB0DA, 0x8667, 0xB0DB, 0x8668, 0xB0DC,
+	0x8669, 0xB0DD, 0x866A, 0xB0DE, 0x866B, 0xB0DF, 0x866C, 0xB0E1,
+	0x866D, 0xB0E2, 0x866E, 0xB0E3, 0x866F, 0xB0E4, 0x8670, 0xB0E6,
+	0x8671, 0xB0E7, 0x8672, 0xB0E8, 0x8673, 0xB0E9, 0x8674, 0xB0EA,
+	0x8675, 0xB0EB, 0x8676, 0xB0EC, 0x8677, 0xB0ED, 0x8678, 0xB0EE,
+	0x8679, 0xB0EF, 0x867A, 0xB0F0, 0x8681, 0xB0F1, 0x8682, 0xB0F2,
+	0x8683, 0xB0F3, 0x8684, 0xB0F4, 0x8685, 0xB0F5, 0x8686, 0xB0F6,
+	0x8687, 0xB0F7, 0x8688, 0xB0F8, 0x8689, 0xB0F9, 0x868A, 0xB0FA,
+	0x868B, 0xB0FB, 0x868C, 0xB0FC, 0x868D, 0xB0FD, 0x868E, 0xB0FE,
+	0x868F, 0xB0FF, 0x8690, 0xB100, 0x8691, 0xB101, 0x8692, 0xB102,
+	0x8693, 0xB103, 0x8694, 0xB104, 0x8695, 0xB105, 0x8696, 0xB106,
+	0x8697, 0xB107, 0x8698, 0xB10A, 0x8699, 0xB10D, 0x869A, 0xB10E,
+	0x869B, 0xB10F, 0x869C, 0xB111, 0x869D, 0xB114, 0x869E, 0xB115,
+	0x869F, 0xB116, 0x86A0, 0xB117, 0x86A1, 0xB11A, 0x86A2, 0xB11E,
+	0x86A3, 0xB11F, 0x86A4, 0xB120, 0x86A5, 0xB121, 0x86A6, 0xB122,
+	0x86A7, 0xB126, 0x86A8, 0xB127, 0x86A9, 0xB129, 0x86AA, 0xB12A,
+	0x86AB, 0xB12B, 0x86AC, 0xB12D, 0x86AD, 0xB12E, 0x86AE, 0xB12F,
+	0x86AF, 0xB130, 0x86B0, 0xB131, 0x86B1, 0xB132, 0x86B2, 0xB133,
+	0x86B3, 0xB136, 0x86B4, 0xB13A, 0x86B5, 0xB13B, 0x86B6, 0xB13C,
+	0x86B7, 0xB13D, 0x86B8, 0xB13E, 0x86B9, 0xB13F, 0x86BA, 0xB142,
+	0x86BB, 0xB143, 0x86BC, 0xB145, 0x86BD, 0xB146, 0x86BE, 0xB147,
+	0x86BF, 0xB149, 0x86C0, 0xB14A, 0x86C1, 0xB14B, 0x86C2, 0xB14C,
+	0x86C3, 0xB14D, 0x86C4, 0xB14E, 0x86C5, 0xB14F, 0x86C6, 0xB152,
+	0x86C7, 0xB153, 0x86C8, 0xB156, 0x86C9, 0xB157, 0x86CA, 0xB159,
+	0x86CB, 0xB15A, 0x86CC, 0xB15B, 0x86CD, 0xB15D, 0x86CE, 0xB15E,
+	0x86CF, 0xB15F, 0x86D0, 0xB161, 0x86D1, 0xB162, 0x86D2, 0xB163,
+	0x86D3, 0xB164, 0x86D4, 0xB165, 0x86D5, 0xB166, 0x86D6, 0xB167,
+	0x86D7, 0xB168, 0x86D8, 0xB169, 0x86D9, 0xB16A, 0x86DA, 0xB16B,
+	0x86DB, 0xB16C, 0x86DC, 0xB16D, 0x86DD, 0xB16E, 0x86DE, 0xB16F,
+	0x86DF, 0xB170, 0x86E0, 0xB171, 0x86E1, 0xB172, 0x86E2, 0xB173,
+	0x86E3, 0xB174, 0x86E4, 0xB175, 0x86E5, 0xB176, 0x86E6, 0xB177,
+	0x86E7, 0xB17A, 0x86E8, 0xB17B, 0x86E9, 0xB17D, 0x86EA, 0xB17E,
+	0x86EB, 0xB17F, 0x86EC, 0xB181, 0x86ED, 0xB183, 0x86EE, 0xB184,
+	0x86EF, 0xB185, 0x86F0, 0xB186, 0x86F1, 0xB187, 0x86F2, 0xB18A,
+	0x86F3, 0xB18C, 0x86F4, 0xB18E, 0x86F5, 0xB18F, 0x86F6, 0xB190,
+	0x86F7, 0xB191, 0x86F8, 0xB195, 0x86F9, 0xB196, 0x86FA, 0xB197,
+	0x86FB, 0xB199, 0x86FC, 0xB19A, 0x86FD, 0xB19B, 0x86FE, 0xB19D,
+	0x8741, 0xB19E, 0x8742, 0xB19F, 0x8743, 0xB1A0, 0x8744, 0xB1A1,
+	0x8745, 0xB1A2, 0x8746, 0xB1A3, 0x8747, 0xB1A4, 0x8748, 0xB1A5,
+	0x8749, 0xB1A6, 0x874A, 0xB1A7, 0x874B, 0xB1A9, 0x874C, 0xB1AA,
+	0x874D, 0xB1AB, 0x874E, 0xB1AC, 0x874F, 0xB1AD, 0x8750, 0xB1AE,
+	0x8751, 0xB1AF, 0x8752, 0xB1B0, 0x8753, 0xB1B1, 0x8754, 0xB1B2,
+	0x8755, 0xB1B3, 0x8756, 0xB1B4, 0x8757, 0xB1B5, 0x8758, 0xB1B6,
+	0x8759, 0xB1B7, 0x875A, 0xB1B8, 0x8761, 0xB1B9, 0x8762, 0xB1BA,
+	0x8763, 0xB1BB, 0x8764, 0xB1BC, 0x8765, 0xB1BD, 0x8766, 0xB1BE,
+	0x8767, 0xB1BF, 0x8768, 0xB1C0, 0x8769, 0xB1C1, 0x876A, 0xB1C2,
+	0x876B, 0xB1C3, 0x876C, 0xB1C4, 0x876D, 0xB1C5, 0x876E, 0xB1C6,
+	0x876F, 0xB1C7, 0x8770, 0xB1C8, 0x8771, 0xB1C9, 0x8772, 0xB1CA,
+	0x8773, 0xB1CB, 0x8774, 0xB1CD, 0x8775, 0xB1CE, 0x8776, 0xB1CF,
+	0x8777, 0xB1D1, 0x8778, 0xB1D2, 0x8779, 0xB1D3, 0x877A, 0xB1D5,
+	0x8781, 0xB1D6, 0x8782, 0xB1D7, 0x8783, 0xB1D8, 0x8784, 0xB1D9,
+	0x8785, 0xB1DA, 0x8786, 0xB1DB, 0x8787, 0xB1DE, 0x8788, 0xB1E0,
+	0x8789, 0xB1E1, 0x878A, 0xB1E2, 0x878B, 0xB1E3, 0x878C, 0xB1E4,
+	0x878D, 0xB1E5, 0x878E, 0xB1E6, 0x878F, 0xB1E7, 0x8790, 0xB1EA,
+	0x8791, 0xB1EB, 0x8792, 0xB1ED, 0x8793, 0xB1EE, 0x8794, 0xB1EF,
+	0x8795, 0xB1F1, 0x8796, 0xB1F2, 0x8797, 0xB1F3, 0x8798, 0xB1F4,
+	0x8799, 0xB1F5, 0x879A, 0xB1F6, 0x879B, 0xB1F7, 0x879C, 0xB1F8,
+	0x879D, 0xB1FA, 0x879E, 0xB1FC, 0x879F, 0xB1FE, 0x87A0, 0xB1FF,
+	0x87A1, 0xB200, 0x87A2, 0xB201, 0x87A3, 0xB202, 0x87A4, 0xB203,
+	0x87A5, 0xB206, 0x87A6, 0xB207, 0x87A7, 0xB209, 0x87A8, 0xB20A,
+	0x87A9, 0xB20D, 0x87AA, 0xB20E, 0x87AB, 0xB20F, 0x87AC, 0xB210,
+	0x87AD, 0xB211, 0x87AE, 0xB212, 0x87AF, 0xB213, 0x87B0, 0xB216,
+	0x87B1, 0xB218, 0x87B2, 0xB21A, 0x87B3, 0xB21B, 0x87B4, 0xB21C,
+	0x87B5, 0xB21D, 0x87B6, 0xB21E, 0x87B7, 0xB21F, 0x87B8, 0xB221,
+	0x87B9, 0xB222, 0x87BA, 0xB223, 0x87BB, 0xB224, 0x87BC, 0xB225,
+	0x87BD, 0xB226, 0x87BE, 0xB227, 0x87BF, 0xB228, 0x87C0, 0xB229,
+	0x87C1, 0xB22A, 0x87C2, 0xB22B, 0x87C3, 0xB22C, 0x87C4, 0xB22D,
+	0x87C5, 0xB22E, 0x87C6, 0xB22F, 0x87C7, 0xB230, 0x87C8, 0xB231,
+	0x87C9, 0xB232, 0x87CA, 0xB233, 0x87CB, 0xB235, 0x87CC, 0xB236,
+	0x87CD, 0xB237, 0x87CE, 0xB238, 0x87CF, 0xB239, 0x87D0, 0xB23A,
+	0x87D1, 0xB23B, 0x87D2, 0xB23D, 0x87D3, 0xB23E, 0x87D4, 0xB23F,
+	0x87D5, 0xB240, 0x87D6, 0xB241, 0x87D7, 0xB242, 0x87D8, 0xB243,
+	0x87D9, 0xB244, 0x87DA, 0xB245, 0x87DB, 0xB246, 0x87DC, 0xB247,
+	0x87DD, 0xB248, 0x87DE, 0xB249, 0x87DF, 0xB24A, 0x87E0, 0xB24B,
+	0x87E1, 0xB24C, 0x87E2, 0xB24D, 0x87E3, 0xB24E, 0x87E4, 0xB24F,
+	0x87E5, 0xB250, 0x87E6, 0xB251, 0x87E7, 0xB252, 0x87E8, 0xB253,
+	0x87E9, 0xB254, 0x87EA, 0xB255, 0x87EB, 0xB256, 0x87EC, 0xB257,
+	0x87ED, 0xB259, 0x87EE, 0xB25A, 0x87EF, 0xB25B, 0x87F0, 0xB25D,
+	0x87F1, 0xB25E, 0x87F2, 0xB25F, 0x87F3, 0xB261, 0x87F4, 0xB262,
+	0x87F5, 0xB263, 0x87F6, 0xB264, 0x87F7, 0xB265, 0x87F8, 0xB266,
+	0x87F9, 0xB267, 0x87FA, 0xB26A, 0x87FB, 0xB26B, 0x87FC, 0xB26C,
+	0x87FD, 0xB26D, 0x87FE, 0xB26E, 0x8841, 0xB26F, 0x8842, 0xB270,
+	0x8843, 0xB271, 0x8844, 0xB272, 0x8845, 0xB273, 0x8846, 0xB276,
+	0x8847, 0xB277, 0x8848, 0xB278, 0x8849, 0xB279, 0x884A, 0xB27A,
+	0x884B, 0xB27B, 0x884C, 0xB27D, 0x884D, 0xB27E, 0x884E, 0xB27F,
+	0x884F, 0xB280, 0x8850, 0xB281, 0x8851, 0xB282, 0x8852, 0xB283,
+	0x8853, 0xB286, 0x8854, 0xB287, 0x8855, 0xB288, 0x8856, 0xB28A,
+	0x8857, 0xB28B, 0x8858, 0xB28C, 0x8859, 0xB28D, 0x885A, 0xB28E,
+	0x8861, 0xB28F, 0x8862, 0xB292, 0x8863, 0xB293, 0x8864, 0xB295,
+	0x8865, 0xB296, 0x8866, 0xB297, 0x8867, 0xB29B, 0x8868, 0xB29C,
+	0x8869, 0xB29D, 0x886A, 0xB29E, 0x886B, 0xB29F, 0x886C, 0xB2A2,
+	0x886D, 0xB2A4, 0x886E, 0xB2A7, 0x886F, 0xB2A8, 0x8870, 0xB2A9,
+	0x8871, 0xB2AB, 0x8872, 0xB2AD, 0x8873, 0xB2AE, 0x8874, 0xB2AF,
+	0x8875, 0xB2B1, 0x8876, 0xB2B2, 0x8877, 0xB2B3, 0x8878, 0xB2B5,
+	0x8879, 0xB2B6, 0x887A, 0xB2B7, 0x8881, 0xB2B8, 0x8882, 0xB2B9,
+	0x8883, 0xB2BA, 0x8884, 0xB2BB, 0x8885, 0xB2BC, 0x8886, 0xB2BD,
+	0x8887, 0xB2BE, 0x8888, 0xB2BF, 0x8889, 0xB2C0, 0x888A, 0xB2C1,
+	0x888B, 0xB2C2, 0x888C, 0xB2C3, 0x888D, 0xB2C4, 0x888E, 0xB2C5,
+	0x888F, 0xB2C6, 0x8890, 0xB2C7, 0x8891, 0xB2CA, 0x8892, 0xB2CB,
+	0x8893, 0xB2CD, 0x8894, 0xB2CE, 0x8895, 0xB2CF, 0x8896, 0xB2D1,
+	0x8897, 0xB2D3, 0x8898, 0xB2D4, 0x8899, 0xB2D5, 0x889A, 0xB2D6,
+	0x889B, 0xB2D7, 0x889C, 0xB2DA, 0x889D, 0xB2DC, 0x889E, 0xB2DE,
+	0x889F, 0xB2DF, 0x88A0, 0xB2E0, 0x88A1, 0xB2E1, 0x88A2, 0xB2E3,
+	0x88A3, 0xB2E7, 0x88A4, 0xB2E9, 0x88A5, 0xB2EA, 0x88A6, 0xB2F0,
+	0x88A7, 0xB2F1, 0x88A8, 0xB2F2, 0x88A9, 0xB2F6, 0x88AA, 0xB2FC,
+	0x88AB, 0xB2FD, 0x88AC, 0xB2FE, 0x88AD, 0xB302, 0x88AE, 0xB303,
+	0x88AF, 0xB305, 0x88B0, 0xB306, 0x88B1, 0xB307, 0x88B2, 0xB309,
+	0x88B3, 0xB30A, 0x88B4, 0xB30B, 0x88B5, 0xB30C, 0x88B6, 0xB30D,
+	0x88B7, 0xB30E, 0x88B8, 0xB30F, 0x88B9, 0xB312, 0x88BA, 0xB316,
+	0x88BB, 0xB317, 0x88BC, 0xB318, 0x88BD, 0xB319, 0x88BE, 0xB31A,
+	0x88BF, 0xB31B, 0x88C0, 0xB31D, 0x88C1, 0xB31E, 0x88C2, 0xB31F,
+	0x88C3, 0xB320, 0x88C4, 0xB321, 0x88C5, 0xB322, 0x88C6, 0xB323,
+	0x88C7, 0xB324, 0x88C8, 0xB325, 0x88C9, 0xB326, 0x88CA, 0xB327,
+	0x88CB, 0xB328, 0x88CC, 0xB329, 0x88CD, 0xB32A, 0x88CE, 0xB32B,
+	0x88CF, 0xB32C, 0x88D0, 0xB32D, 0x88D1, 0xB32E, 0x88D2, 0xB32F,
+	0x88D3, 0xB330, 0x88D4, 0xB331, 0x88D5, 0xB332, 0x88D6, 0xB333,
+	0x88D7, 0xB334, 0x88D8, 0xB335, 0x88D9, 0xB336, 0x88DA, 0xB337,
+	0x88DB, 0xB338, 0x88DC, 0xB339, 0x88DD, 0xB33A, 0x88DE, 0xB33B,
+	0x88DF, 0xB33C, 0x88E0, 0xB33D, 0x88E1, 0xB33E, 0x88E2, 0xB33F,
+	0x88E3, 0xB340, 0x88E4, 0xB341, 0x88E5, 0xB342, 0x88E6, 0xB343,
+	0x88E7, 0xB344, 0x88E8, 0xB345, 0x88E9, 0xB346, 0x88EA, 0xB347,
+	0x88EB, 0xB348, 0x88EC, 0xB349, 0x88ED, 0xB34A, 0x88EE, 0xB34B,
+	0x88EF, 0xB34C, 0x88F0, 0xB34D, 0x88F1, 0xB34E, 0x88F2, 0xB34F,
+	0x88F3, 0xB350, 0x88F4, 0xB351, 0x88F5, 0xB352, 0x88F6, 0xB353,
+	0x88F7, 0xB357, 0x88F8, 0xB359, 0x88F9, 0xB35A, 0x88FA, 0xB35D,
+	0x88FB, 0xB360, 0x88FC, 0xB361, 0x88FD, 0xB362, 0x88FE, 0xB363,
+	0x8941, 0xB366, 0x8942, 0xB368, 0x8943, 0xB36A, 0x8944, 0xB36C,
+	0x8945, 0xB36D, 0x8946, 0xB36F, 0x8947, 0xB372, 0x8948, 0xB373,
+	0x8949, 0xB375, 0x894A, 0xB376, 0x894B, 0xB377, 0x894C, 0xB379,
+	0x894D, 0xB37A, 0x894E, 0xB37B, 0x894F, 0xB37C, 0x8950, 0xB37D,
+	0x8951, 0xB37E, 0x8952, 0xB37F, 0x8953, 0xB382, 0x8954, 0xB386,
+	0x8955, 0xB387, 0x8956, 0xB388, 0x8957, 0xB389, 0x8958, 0xB38A,
+	0x8959, 0xB38B, 0x895A, 0xB38D, 0x8961, 0xB38E, 0x8962, 0xB38F,
+	0x8963, 0xB391, 0x8964, 0xB392, 0x8965, 0xB393, 0x8966, 0xB395,
+	0x8967, 0xB396, 0x8968, 0xB397, 0x8969, 0xB398, 0x896A, 0xB399,
+	0x896B, 0xB39A, 0x896C, 0xB39B, 0x896D, 0xB39C, 0x896E, 0xB39D,
+	0x896F, 0xB39E, 0x8970, 0xB39F, 0x8971, 0xB3A2, 0x8972, 0xB3A3,
+	0x8973, 0xB3A4, 0x8974, 0xB3A5, 0x8975, 0xB3A6, 0x8976, 0xB3A7,
+	0x8977, 0xB3A9, 0x8978, 0xB3AA, 0x8979, 0xB3AB, 0x897A, 0xB3AD,
+	0x8981, 0xB3AE, 0x8982, 0xB3AF, 0x8983, 0xB3B0, 0x8984, 0xB3B1,
+	0x8985, 0xB3B2, 0x8986, 0xB3B3, 0x8987, 0xB3B4, 0x8988, 0xB3B5,
+	0x8989, 0xB3B6, 0x898A, 0xB3B7, 0x898B, 0xB3B8, 0x898C, 0xB3B9,
+	0x898D, 0xB3BA, 0x898E, 0xB3BB, 0x898F, 0xB3BC, 0x8990, 0xB3BD,
+	0x8991, 0xB3BE, 0x8992, 0xB3BF, 0x8993, 0xB3C0, 0x8994, 0xB3C1,
+	0x8995, 0xB3C2, 0x8996, 0xB3C3, 0x8997, 0xB3C6, 0x8998, 0xB3C7,
+	0x8999, 0xB3C9, 0x899A, 0xB3CA, 0x899B, 0xB3CD, 0x899C, 0xB3CF,
+	0x899D, 0xB3D1, 0x899E, 0xB3D2, 0x899F, 0xB3D3, 0x89A0, 0xB3D6,
+	0x89A1, 0xB3D8, 0x89A2, 0xB3DA, 0x89A3, 0xB3DC, 0x89A4, 0xB3DE,
+	0x89A5, 0xB3DF, 0x89A6, 0xB3E1, 0x89A7, 0xB3E2, 0x89A8, 0xB3E3,
+	0x89A9, 0xB3E5, 0x89AA, 0xB3E6, 0x89AB, 0xB3E7, 0x89AC, 0xB3E9,
+	0x89AD, 0xB3EA, 0x89AE, 0xB3EB, 0x89AF, 0xB3EC, 0x89B0, 0xB3ED,
+	0x89B1, 0xB3EE, 0x89B2, 0xB3EF, 0x89B3, 0xB3F0, 0x89B4, 0xB3F1,
+	0x89B5, 0xB3F2, 0x89B6, 0xB3F3, 0x89B7, 0xB3F4, 0x89B8, 0xB3F5,
+	0x89B9, 0xB3F6, 0x89BA, 0xB3F7, 0x89BB, 0xB3F8, 0x89BC, 0xB3F9,
+	0x89BD, 0xB3FA, 0x89BE, 0xB3FB, 0x89BF, 0xB3FD, 0x89C0, 0xB3FE,
+	0x89C1, 0xB3FF, 0x89C2, 0xB400, 0x89C3, 0xB401, 0x89C4, 0xB402,
+	0x89C5, 0xB403, 0x89C6, 0xB404, 0x89C7, 0xB405, 0x89C8, 0xB406,
+	0x89C9, 0xB407, 0x89CA, 0xB408, 0x89CB, 0xB409, 0x89CC, 0xB40A,
+	0x89CD, 0xB40B, 0x89CE, 0xB40C, 0x89CF, 0xB40D, 0x89D0, 0xB40E,
+	0x89D1, 0xB40F, 0x89D2, 0xB411, 0x89D3, 0xB412, 0x89D4, 0xB413,
+	0x89D5, 0xB414, 0x89D6, 0xB415, 0x89D7, 0xB416, 0x89D8, 0xB417,
+	0x89D9, 0xB419, 0x89DA, 0xB41A, 0x89DB, 0xB41B, 0x89DC, 0xB41D,
+	0x89DD, 0xB41E, 0x89DE, 0xB41F, 0x89DF, 0xB421, 0x89E0, 0xB422,
+	0x89E1, 0xB423, 0x89E2, 0xB424, 0x89E3, 0xB425, 0x89E4, 0xB426,
+	0x89E5, 0xB427, 0x89E6, 0xB42A, 0x89E7, 0xB42C, 0x89E8, 0xB42D,
+	0x89E9, 0xB42E, 0x89EA, 0xB42F, 0x89EB, 0xB430, 0x89EC, 0xB431,
+	0x89ED, 0xB432, 0x89EE, 0xB433, 0x89EF, 0xB435, 0x89F0, 0xB436,
+	0x89F1, 0xB437, 0x89F2, 0xB438, 0x89F3, 0xB439, 0x89F4, 0xB43A,
+	0x89F5, 0xB43B, 0x89F6, 0xB43C, 0x89F7, 0xB43D, 0x89F8, 0xB43E,
+	0x89F9, 0xB43F, 0x89FA, 0xB440, 0x89FB, 0xB441, 0x89FC, 0xB442,
+	0x89FD, 0xB443, 0x89FE, 0xB444, 0x8A41, 0xB445, 0x8A42, 0xB446,
+	0x8A43, 0xB447, 0x8A44, 0xB448, 0x8A45, 0xB449, 0x8A46, 0xB44A,
+	0x8A47, 0xB44B, 0x8A48, 0xB44C, 0x8A49, 0xB44D, 0x8A4A, 0xB44E,
+	0x8A4B, 0xB44F, 0x8A4C, 0xB452, 0x8A4D, 0xB453, 0x8A4E, 0xB455,
+	0x8A4F, 0xB456, 0x8A50, 0xB457, 0x8A51, 0xB459, 0x8A52, 0xB45A,
+	0x8A53, 0xB45B, 0x8A54, 0xB45C, 0x8A55, 0xB45D, 0x8A56, 0xB45E,
+	0x8A57, 0xB45F, 0x8A58, 0xB462, 0x8A59, 0xB464, 0x8A5A, 0xB466,
+	0x8A61, 0xB467, 0x8A62, 0xB468, 0x8A63, 0xB469, 0x8A64, 0xB46A,
+	0x8A65, 0xB46B, 0x8A66, 0xB46D, 0x8A67, 0xB46E, 0x8A68, 0xB46F,
+	0x8A69, 0xB470, 0x8A6A, 0xB471, 0x8A6B, 0xB472, 0x8A6C, 0xB473,
+	0x8A6D, 0xB474, 0x8A6E, 0xB475, 0x8A6F, 0xB476, 0x8A70, 0xB477,
+	0x8A71, 0xB478, 0x8A72, 0xB479, 0x8A73, 0xB47A, 0x8A74, 0xB47B,
+	0x8A75, 0xB47C, 0x8A76, 0xB47D, 0x8A77, 0xB47E, 0x8A78, 0xB47F,
+	0x8A79, 0xB481, 0x8A7A, 0xB482, 0x8A81, 0xB483, 0x8A82, 0xB484,
+	0x8A83, 0xB485, 0x8A84, 0xB486, 0x8A85, 0xB487, 0x8A86, 0xB489,
+	0x8A87, 0xB48A, 0x8A88, 0xB48B, 0x8A89, 0xB48C, 0x8A8A, 0xB48D,
+	0x8A8B, 0xB48E, 0x8A8C, 0xB48F, 0x8A8D, 0xB490, 0x8A8E, 0xB491,
+	0x8A8F, 0xB492, 0x8A90, 0xB493, 0x8A91, 0xB494, 0x8A92, 0xB495,
+	0x8A93, 0xB496, 0x8A94, 0xB497, 0x8A95, 0xB498, 0x8A96, 0xB499,
+	0x8A97, 0xB49A, 0x8A98, 0xB49B, 0x8A99, 0xB49C, 0x8A9A, 0xB49E,
+	0x8A9B, 0xB49F, 0x8A9C, 0xB4A0, 0x8A9D, 0xB4A1, 0x8A9E, 0xB4A2,
+	0x8A9F, 0xB4A3, 0x8AA0, 0xB4A5, 0x8AA1, 0xB4A6, 0x8AA2, 0xB4A7,
+	0x8AA3, 0xB4A9, 0x8AA4, 0xB4AA, 0x8AA5, 0xB4AB, 0x8AA6, 0xB4AD,
+	0x8AA7, 0xB4AE, 0x8AA8, 0xB4AF, 0x8AA9, 0xB4B0, 0x8AAA, 0xB4B1,
+	0x8AAB, 0xB4B2, 0x8AAC, 0xB4B3, 0x8AAD, 0xB4B4, 0x8AAE, 0xB4B6,
+	0x8AAF, 0xB4B8, 0x8AB0, 0xB4BA, 0x8AB1, 0xB4BB, 0x8AB2, 0xB4BC,
+	0x8AB3, 0xB4BD, 0x8AB4, 0xB4BE, 0x8AB5, 0xB4BF, 0x8AB6, 0xB4C1,
+	0x8AB7, 0xB4C2, 0x8AB8, 0xB4C3, 0x8AB9, 0xB4C5, 0x8ABA, 0xB4C6,
+	0x8ABB, 0xB4C7, 0x8ABC, 0xB4C9, 0x8ABD, 0xB4CA, 0x8ABE, 0xB4CB,
+	0x8ABF, 0xB4CC, 0x8AC0, 0xB4CD, 0x8AC1, 0xB4CE, 0x8AC2, 0xB4CF,
+	0x8AC3, 0xB4D1, 0x8AC4, 0xB4D2, 0x8AC5, 0xB4D3, 0x8AC6, 0xB4D4,
+	0x8AC7, 0xB4D6, 0x8AC8, 0xB4D7, 0x8AC9, 0xB4D8, 0x8ACA, 0xB4D9,
+	0x8ACB, 0xB4DA, 0x8ACC, 0xB4DB, 0x8ACD, 0xB4DE, 0x8ACE, 0xB4DF,
+	0x8ACF, 0xB4E1, 0x8AD0, 0xB4E2, 0x8AD1, 0xB4E5, 0x8AD2, 0xB4E7,
+	0x8AD3, 0xB4E8, 0x8AD4, 0xB4E9, 0x8AD5, 0xB4EA, 0x8AD6, 0xB4EB,
+	0x8AD7, 0xB4EE, 0x8AD8, 0xB4F0, 0x8AD9, 0xB4F2, 0x8ADA, 0xB4F3,
+	0x8ADB, 0xB4F4, 0x8ADC, 0xB4F5, 0x8ADD, 0xB4F6, 0x8ADE, 0xB4F7,
+	0x8ADF, 0xB4F9, 0x8AE0, 0xB4FA, 0x8AE1, 0xB4FB, 0x8AE2, 0xB4FC,
+	0x8AE3, 0xB4FD, 0x8AE4, 0xB4FE, 0x8AE5, 0xB4FF, 0x8AE6, 0xB500,
+	0x8AE7, 0xB501, 0x8AE8, 0xB502, 0x8AE9, 0xB503, 0x8AEA, 0xB504,
+	0x8AEB, 0xB505, 0x8AEC, 0xB506, 0x8AED, 0xB507, 0x8AEE, 0xB508,
+	0x8AEF, 0xB509, 0x8AF0, 0xB50A, 0x8AF1, 0xB50B, 0x8AF2, 0xB50C,
+	0x8AF3, 0xB50D, 0x8AF4, 0xB50E, 0x8AF5, 0xB50F, 0x8AF6, 0xB510,
+	0x8AF7, 0xB511, 0x8AF8, 0xB512, 0x8AF9, 0xB513, 0x8AFA, 0xB516,
+	0x8AFB, 0xB517, 0x8AFC, 0xB519, 0x8AFD, 0xB51A, 0x8AFE, 0xB51D,
+	0x8B41, 0xB51E, 0x8B42, 0xB51F, 0x8B43, 0xB520, 0x8B44, 0xB521,
+	0x8B45, 0xB522, 0x8B46, 0xB523, 0x8B47, 0xB526, 0x8B48, 0xB52B,
+	0x8B49, 0xB52C, 0x8B4A, 0xB52D, 0x8B4B, 0xB52E, 0x8B4C, 0xB52F,
+	0x8B4D, 0xB532, 0x8B4E, 0xB533, 0x8B4F, 0xB535, 0x8B50, 0xB536,
+	0x8B51, 0xB537, 0x8B52, 0xB539, 0x8B53, 0xB53A, 0x8B54, 0xB53B,
+	0x8B55, 0xB53C, 0x8B56, 0xB53D, 0x8B57, 0xB53E, 0x8B58, 0xB53F,
+	0x8B59, 0xB542, 0x8B5A, 0xB546, 0x8B61, 0xB547, 0x8B62, 0xB548,
+	0x8B63, 0xB549, 0x8B64, 0xB54A, 0x8B65, 0xB54E, 0x8B66, 0xB54F,
+	0x8B67, 0xB551, 0x8B68, 0xB552, 0x8B69, 0xB553, 0x8B6A, 0xB555,
+	0x8B6B, 0xB556, 0x8B6C, 0xB557, 0x8B6D, 0xB558, 0x8B6E, 0xB559,
+	0x8B6F, 0xB55A, 0x8B70, 0xB55B, 0x8B71, 0xB55E, 0x8B72, 0xB562,
+	0x8B73, 0xB563, 0x8B74, 0xB564, 0x8B75, 0xB565, 0x8B76, 0xB566,
+	0x8B77, 0xB567, 0x8B78, 0xB568, 0x8B79, 0xB569, 0x8B7A, 0xB56A,
+	0x8B81, 0xB56B, 0x8B82, 0xB56C, 0x8B83, 0xB56D, 0x8B84, 0xB56E,
+	0x8B85, 0xB56F, 0x8B86, 0xB570, 0x8B87, 0xB571, 0x8B88, 0xB572,
+	0x8B89, 0xB573, 0x8B8A, 0xB574, 0x8B8B, 0xB575, 0x8B8C, 0xB576,
+	0x8B8D, 0xB577, 0x8B8E, 0xB578, 0x8B8F, 0xB579, 0x8B90, 0xB57A,
+	0x8B91, 0xB57B, 0x8B92, 0xB57C, 0x8B93, 0xB57D, 0x8B94, 0xB57E,
+	0x8B95, 0xB57F, 0x8B96, 0xB580, 0x8B97, 0xB581, 0x8B98, 0xB582,
+	0x8B99, 0xB583, 0x8B9A, 0xB584, 0x8B9B, 0xB585, 0x8B9C, 0xB586,
+	0x8B9D, 0xB587, 0x8B9E, 0xB588, 0x8B9F, 0xB589, 0x8BA0, 0xB58A,
+	0x8BA1, 0xB58B, 0x8BA2, 0xB58C, 0x8BA3, 0xB58D, 0x8BA4, 0xB58E,
+	0x8BA5, 0xB58F, 0x8BA6, 0xB590, 0x8BA7, 0xB591, 0x8BA8, 0xB592,
+	0x8BA9, 0xB593, 0x8BAA, 0xB594, 0x8BAB, 0xB595, 0x8BAC, 0xB596,
+	0x8BAD, 0xB597, 0x8BAE, 0xB598, 0x8BAF, 0xB599, 0x8BB0, 0xB59A,
+	0x8BB1, 0xB59B, 0x8BB2, 0xB59C, 0x8BB3, 0xB59D, 0x8BB4, 0xB59E,
+	0x8BB5, 0xB59F, 0x8BB6, 0xB5A2, 0x8BB7, 0xB5A3, 0x8BB8, 0xB5A5,
+	0x8BB9, 0xB5A6, 0x8BBA, 0xB5A7, 0x8BBB, 0xB5A9, 0x8BBC, 0xB5AC,
+	0x8BBD, 0xB5AD, 0x8BBE, 0xB5AE, 0x8BBF, 0xB5AF, 0x8BC0, 0xB5B2,
+	0x8BC1, 0xB5B6, 0x8BC2, 0xB5B7, 0x8BC3, 0xB5B8, 0x8BC4, 0xB5B9,
+	0x8BC5, 0xB5BA, 0x8BC6, 0xB5BE, 0x8BC7, 0xB5BF, 0x8BC8, 0xB5C1,
+	0x8BC9, 0xB5C2, 0x8BCA, 0xB5C3, 0x8BCB, 0xB5C5, 0x8BCC, 0xB5C6,
+	0x8BCD, 0xB5C7, 0x8BCE, 0xB5C8, 0x8BCF, 0xB5C9, 0x8BD0, 0xB5CA,
+	0x8BD1, 0xB5CB, 0x8BD2, 0xB5CE, 0x8BD3, 0xB5D2, 0x8BD4, 0xB5D3,
+	0x8BD5, 0xB5D4, 0x8BD6, 0xB5D5, 0x8BD7, 0xB5D6, 0x8BD8, 0xB5D7,
+	0x8BD9, 0xB5D9, 0x8BDA, 0xB5DA, 0x8BDB, 0xB5DB, 0x8BDC, 0xB5DC,
+	0x8BDD, 0xB5DD, 0x8BDE, 0xB5DE, 0x8BDF, 0xB5DF, 0x8BE0, 0xB5E0,
+	0x8BE1, 0xB5E1, 0x8BE2, 0xB5E2, 0x8BE3, 0xB5E3, 0x8BE4, 0xB5E4,
+	0x8BE5, 0xB5E5, 0x8BE6, 0xB5E6, 0x8BE7, 0xB5E7, 0x8BE8, 0xB5E8,
+	0x8BE9, 0xB5E9, 0x8BEA, 0xB5EA, 0x8BEB, 0xB5EB, 0x8BEC, 0xB5ED,
+	0x8BED, 0xB5EE, 0x8BEE, 0xB5EF, 0x8BEF, 0xB5F0, 0x8BF0, 0xB5F1,
+	0x8BF1, 0xB5F2, 0x8BF2, 0xB5F3, 0x8BF3, 0xB5F4, 0x8BF4, 0xB5F5,
+	0x8BF5, 0xB5F6, 0x8BF6, 0xB5F7, 0x8BF7, 0xB5F8, 0x8BF8, 0xB5F9,
+	0x8BF9, 0xB5FA, 0x8BFA, 0xB5FB, 0x8BFB, 0xB5FC, 0x8BFC, 0xB5FD,
+	0x8BFD, 0xB5FE, 0x8BFE, 0xB5FF, 0x8C41, 0xB600, 0x8C42, 0xB601,
+	0x8C43, 0xB602, 0x8C44, 0xB603, 0x8C45, 0xB604, 0x8C46, 0xB605,
+	0x8C47, 0xB606, 0x8C48, 0xB607, 0x8C49, 0xB608, 0x8C4A, 0xB609,
+	0x8C4B, 0xB60A, 0x8C4C, 0xB60B, 0x8C4D, 0xB60C, 0x8C4E, 0xB60D,
+	0x8C4F, 0xB60E, 0x8C50, 0xB60F, 0x8C51, 0xB612, 0x8C52, 0xB613,
+	0x8C53, 0xB615, 0x8C54, 0xB616, 0x8C55, 0xB617, 0x8C56, 0xB619,
+	0x8C57, 0xB61A, 0x8C58, 0xB61B, 0x8C59, 0xB61C, 0x8C5A, 0xB61D,
+	0x8C61, 0xB61E, 0x8C62, 0xB61F, 0x8C63, 0xB620, 0x8C64, 0xB621,
+	0x8C65, 0xB622, 0x8C66, 0xB623, 0x8C67, 0xB624, 0x8C68, 0xB626,
+	0x8C69, 0xB627, 0x8C6A, 0xB628, 0x8C6B, 0xB629, 0x8C6C, 0xB62A,
+	0x8C6D, 0xB62B, 0x8C6E, 0xB62D, 0x8C6F, 0xB62E, 0x8C70, 0xB62F,
+	0x8C71, 0xB630, 0x8C72, 0xB631, 0x8C73, 0xB632, 0x8C74, 0xB633,
+	0x8C75, 0xB635, 0x8C76, 0xB636, 0x8C77, 0xB637, 0x8C78, 0xB638,
+	0x8C79, 0xB639, 0x8C7A, 0xB63A, 0x8C81, 0xB63B, 0x8C82, 0xB63C,
+	0x8C83, 0xB63D, 0x8C84, 0xB63E, 0x8C85, 0xB63F, 0x8C86, 0xB640,
+	0x8C87, 0xB641, 0x8C88, 0xB642, 0x8C89, 0xB643, 0x8C8A, 0xB644,
+	0x8C8B, 0xB645, 0x8C8C, 0xB646, 0x8C8D, 0xB647, 0x8C8E, 0xB649,
+	0x8C8F, 0xB64A, 0x8C90, 0xB64B, 0x8C91, 0xB64C, 0x8C92, 0xB64D,
+	0x8C93, 0xB64E, 0x8C94, 0xB64F, 0x8C95, 0xB650, 0x8C96, 0xB651,
+	0x8C97, 0xB652, 0x8C98, 0xB653, 0x8C99, 0xB654, 0x8C9A, 0xB655,
+	0x8C9B, 0xB656, 0x8C9C, 0xB657, 0x8C9D, 0xB658, 0x8C9E, 0xB659,
+	0x8C9F, 0xB65A, 0x8CA0, 0xB65B, 0x8CA1, 0xB65C, 0x8CA2, 0xB65D,
+	0x8CA3, 0xB65E, 0x8CA4, 0xB65F, 0x8CA5, 0xB660, 0x8CA6, 0xB661,
+	0x8CA7, 0xB662, 0x8CA8, 0xB663, 0x8CA9, 0xB665, 0x8CAA, 0xB666,
+	0x8CAB, 0xB667, 0x8CAC, 0xB669, 0x8CAD, 0xB66A, 0x8CAE, 0xB66B,
+	0x8CAF, 0xB66C, 0x8CB0, 0xB66D, 0x8CB1, 0xB66E, 0x8CB2, 0xB66F,
+	0x8CB3, 0xB670, 0x8CB4, 0xB671, 0x8CB5, 0xB672, 0x8CB6, 0xB673,
+	0x8CB7, 0xB674, 0x8CB8, 0xB675, 0x8CB9, 0xB676, 0x8CBA, 0xB677,
+	0x8CBB, 0xB678, 0x8CBC, 0xB679, 0x8CBD, 0xB67A, 0x8CBE, 0xB67B,
+	0x8CBF, 0xB67C, 0x8CC0, 0xB67D, 0x8CC1, 0xB67E, 0x8CC2, 0xB67F,
+	0x8CC3, 0xB680, 0x8CC4, 0xB681, 0x8CC5, 0xB682, 0x8CC6, 0xB683,
+	0x8CC7, 0xB684, 0x8CC8, 0xB685, 0x8CC9, 0xB686, 0x8CCA, 0xB687,
+	0x8CCB, 0xB688, 0x8CCC, 0xB689, 0x8CCD, 0xB68A, 0x8CCE, 0xB68B,
+	0x8CCF, 0xB68C, 0x8CD0, 0xB68D, 0x8CD1, 0xB68E, 0x8CD2, 0xB68F,
+	0x8CD3, 0xB690, 0x8CD4, 0xB691, 0x8CD5, 0xB692, 0x8CD6, 0xB693,
+	0x8CD7, 0xB694, 0x8CD8, 0xB695, 0x8CD9, 0xB696, 0x8CDA, 0xB697,
+	0x8CDB, 0xB698, 0x8CDC, 0xB699, 0x8CDD, 0xB69A, 0x8CDE, 0xB69B,
+	0x8CDF, 0xB69E, 0x8CE0, 0xB69F, 0x8CE1, 0xB6A1, 0x8CE2, 0xB6A2,
+	0x8CE3, 0xB6A3, 0x8CE4, 0xB6A5, 0x8CE5, 0xB6A6, 0x8CE6, 0xB6A7,
+	0x8CE7, 0xB6A8, 0x8CE8, 0xB6A9, 0x8CE9, 0xB6AA, 0x8CEA, 0xB6AD,
+	0x8CEB, 0xB6AE, 0x8CEC, 0xB6AF, 0x8CED, 0xB6B0, 0x8CEE, 0xB6B2,
+	0x8CEF, 0xB6B3, 0x8CF0, 0xB6B4, 0x8CF1, 0xB6B5, 0x8CF2, 0xB6B6,
+	0x8CF3, 0xB6B7, 0x8CF4, 0xB6B8, 0x8CF5, 0xB6B9, 0x8CF6, 0xB6BA,
+	0x8CF7, 0xB6BB, 0x8CF8, 0xB6BC, 0x8CF9, 0xB6BD, 0x8CFA, 0xB6BE,
+	0x8CFB, 0xB6BF, 0x8CFC, 0xB6C0, 0x8CFD, 0xB6C1, 0x8CFE, 0xB6C2,
+	0x8D41, 0xB6C3, 0x8D42, 0xB6C4, 0x8D43, 0xB6C5, 0x8D44, 0xB6C6,
+	0x8D45, 0xB6C7, 0x8D46, 0xB6C8, 0x8D47, 0xB6C9, 0x8D48, 0xB6CA,
+	0x8D49, 0xB6CB, 0x8D4A, 0xB6CC, 0x8D4B, 0xB6CD, 0x8D4C, 0xB6CE,
+	0x8D4D, 0xB6CF, 0x8D4E, 0xB6D0, 0x8D4F, 0xB6D1, 0x8D50, 0xB6D2,
+	0x8D51, 0xB6D3, 0x8D52, 0xB6D5, 0x8D53, 0xB6D6, 0x8D54, 0xB6D7,
+	0x8D55, 0xB6D8, 0x8D56, 0xB6D9, 0x8D57, 0xB6DA, 0x8D58, 0xB6DB,
+	0x8D59, 0xB6DC, 0x8D5A, 0xB6DD, 0x8D61, 0xB6DE, 0x8D62, 0xB6DF,
+	0x8D63, 0xB6E0, 0x8D64, 0xB6E1, 0x8D65, 0xB6E2, 0x8D66, 0xB6E3,
+	0x8D67, 0xB6E4, 0x8D68, 0xB6E5, 0x8D69, 0xB6E6, 0x8D6A, 0xB6E7,
+	0x8D6B, 0xB6E8, 0x8D6C, 0xB6E9, 0x8D6D, 0xB6EA, 0x8D6E, 0xB6EB,
+	0x8D6F, 0xB6EC, 0x8D70, 0xB6ED, 0x8D71, 0xB6EE, 0x8D72, 0xB6EF,
+	0x8D73, 0xB6F1, 0x8D74, 0xB6F2, 0x8D75, 0xB6F3, 0x8D76, 0xB6F5,
+	0x8D77, 0xB6F6, 0x8D78, 0xB6F7, 0x8D79, 0xB6F9, 0x8D7A, 0xB6FA,
+	0x8D81, 0xB6FB, 0x8D82, 0xB6FC, 0x8D83, 0xB6FD, 0x8D84, 0xB6FE,
+	0x8D85, 0xB6FF, 0x8D86, 0xB702, 0x8D87, 0xB703, 0x8D88, 0xB704,
+	0x8D89, 0xB706, 0x8D8A, 0xB707, 0x8D8B, 0xB708, 0x8D8C, 0xB709,
+	0x8D8D, 0xB70A, 0x8D8E, 0xB70B, 0x8D8F, 0xB70C, 0x8D90, 0xB70D,
+	0x8D91, 0xB70E, 0x8D92, 0xB70F, 0x8D93, 0xB710, 0x8D94, 0xB711,
+	0x8D95, 0xB712, 0x8D96, 0xB713, 0x8D97, 0xB714, 0x8D98, 0xB715,
+	0x8D99, 0xB716, 0x8D9A, 0xB717, 0x8D9B, 0xB718, 0x8D9C, 0xB719,
+	0x8D9D, 0xB71A, 0x8D9E, 0xB71B, 0x8D9F, 0xB71C, 0x8DA0, 0xB71D,
+	0x8DA1, 0xB71E, 0x8DA2, 0xB71F, 0x8DA3, 0xB720, 0x8DA4, 0xB721,
+	0x8DA5, 0xB722, 0x8DA6, 0xB723, 0x8DA7, 0xB724, 0x8DA8, 0xB725,
+	0x8DA9, 0xB726, 0x8DAA, 0xB727, 0x8DAB, 0xB72A, 0x8DAC, 0xB72B,
+	0x8DAD, 0xB72D, 0x8DAE, 0xB72E, 0x8DAF, 0xB731, 0x8DB0, 0xB732,
+	0x8DB1, 0xB733, 0x8DB2, 0xB734, 0x8DB3, 0xB735, 0x8DB4, 0xB736,
+	0x8DB5, 0xB737, 0x8DB6, 0xB73A, 0x8DB7, 0xB73C, 0x8DB8, 0xB73D,
+	0x8DB9, 0xB73E, 0x8DBA, 0xB73F, 0x8DBB, 0xB740, 0x8DBC, 0xB741,
+	0x8DBD, 0xB742, 0x8DBE, 0xB743, 0x8DBF, 0xB745, 0x8DC0, 0xB746,
+	0x8DC1, 0xB747, 0x8DC2, 0xB749, 0x8DC3, 0xB74A, 0x8DC4, 0xB74B,
+	0x8DC5, 0xB74D, 0x8DC6, 0xB74E, 0x8DC7, 0xB74F, 0x8DC8, 0xB750,
+	0x8DC9, 0xB751, 0x8DCA, 0xB752, 0x8DCB, 0xB753, 0x8DCC, 0xB756,
+	0x8DCD, 0xB757, 0x8DCE, 0xB758, 0x8DCF, 0xB759, 0x8DD0, 0xB75A,
+	0x8DD1, 0xB75B, 0x8DD2, 0xB75C, 0x8DD3, 0xB75D, 0x8DD4, 0xB75E,
+	0x8DD5, 0xB75F, 0x8DD6, 0xB761, 0x8DD7, 0xB762, 0x8DD8, 0xB763,
+	0x8DD9, 0xB765, 0x8DDA, 0xB766, 0x8DDB, 0xB767, 0x8DDC, 0xB769,
+	0x8DDD, 0xB76A, 0x8DDE, 0xB76B, 0x8DDF, 0xB76C, 0x8DE0, 0xB76D,
+	0x8DE1, 0xB76E, 0x8DE2, 0xB76F, 0x8DE3, 0xB772, 0x8DE4, 0xB774,
+	0x8DE5, 0xB776, 0x8DE6, 0xB777, 0x8DE7, 0xB778, 0x8DE8, 0xB779,
+	0x8DE9, 0xB77A, 0x8DEA, 0xB77B, 0x8DEB, 0xB77E, 0x8DEC, 0xB77F,
+	0x8DED, 0xB781, 0x8DEE, 0xB782, 0x8DEF, 0xB783, 0x8DF0, 0xB785,
+	0x8DF1, 0xB786, 0x8DF2, 0xB787, 0x8DF3, 0xB788, 0x8DF4, 0xB789,
+	0x8DF5, 0xB78A, 0x8DF6, 0xB78B, 0x8DF7, 0xB78E, 0x8DF8, 0xB793,
+	0x8DF9, 0xB794, 0x8DFA, 0xB795, 0x8DFB, 0xB79A, 0x8DFC, 0xB79B,
+	0x8DFD, 0xB79D, 0x8DFE, 0xB79E, 0x8E41, 0xB79F, 0x8E42, 0xB7A1,
+	0x8E43, 0xB7A2, 0x8E44, 0xB7A3, 0x8E45, 0xB7A4, 0x8E46, 0xB7A5,
+	0x8E47, 0xB7A6, 0x8E48, 0xB7A7, 0x8E49, 0xB7AA, 0x8E4A, 0xB7AE,
+	0x8E4B, 0xB7AF, 0x8E4C, 0xB7B0, 0x8E4D, 0xB7B1, 0x8E4E, 0xB7B2,
+	0x8E4F, 0xB7B3, 0x8E50, 0xB7B6, 0x8E51, 0xB7B7, 0x8E52, 0xB7B9,
+	0x8E53, 0xB7BA, 0x8E54, 0xB7BB, 0x8E55, 0xB7BC, 0x8E56, 0xB7BD,
+	0x8E57, 0xB7BE, 0x8E58, 0xB7BF, 0x8E59, 0xB7C0, 0x8E5A, 0xB7C1,
+	0x8E61, 0xB7C2, 0x8E62, 0xB7C3, 0x8E63, 0xB7C4, 0x8E64, 0xB7C5,
+	0x8E65, 0xB7C6, 0x8E66, 0xB7C8, 0x8E67, 0xB7CA, 0x8E68, 0xB7CB,
+	0x8E69, 0xB7CC, 0x8E6A, 0xB7CD, 0x8E6B, 0xB7CE, 0x8E6C, 0xB7CF,
+	0x8E6D, 0xB7D0, 0x8E6E, 0xB7D1, 0x8E6F, 0xB7D2, 0x8E70, 0xB7D3,
+	0x8E71, 0xB7D4, 0x8E72, 0xB7D5, 0x8E73, 0xB7D6, 0x8E74, 0xB7D7,
+	0x8E75, 0xB7D8, 0x8E76, 0xB7D9, 0x8E77, 0xB7DA, 0x8E78, 0xB7DB,
+	0x8E79, 0xB7DC, 0x8E7A, 0xB7DD, 0x8E81, 0xB7DE, 0x8E82, 0xB7DF,
+	0x8E83, 0xB7E0, 0x8E84, 0xB7E1, 0x8E85, 0xB7E2, 0x8E86, 0xB7E3,
+	0x8E87, 0xB7E4, 0x8E88, 0xB7E5, 0x8E89, 0xB7E6, 0x8E8A, 0xB7E7,
+	0x8E8B, 0xB7E8, 0x8E8C, 0xB7E9, 0x8E8D, 0xB7EA, 0x8E8E, 0xB7EB,
+	0x8E8F, 0xB7EE, 0x8E90, 0xB7EF, 0x8E91, 0xB7F1, 0x8E92, 0xB7F2,
+	0x8E93, 0xB7F3, 0x8E94, 0xB7F5, 0x8E95, 0xB7F6, 0x8E96, 0xB7F7,
+	0x8E97, 0xB7F8, 0x8E98, 0xB7F9, 0x8E99, 0xB7FA, 0x8E9A, 0xB7FB,
+	0x8E9B, 0xB7FE, 0x8E9C, 0xB802, 0x8E9D, 0xB803, 0x8E9E, 0xB804,
+	0x8E9F, 0xB805, 0x8EA0, 0xB806, 0x8EA1, 0xB80A, 0x8EA2, 0xB80B,
+	0x8EA3, 0xB80D, 0x8EA4, 0xB80E, 0x8EA5, 0xB80F, 0x8EA6, 0xB811,
+	0x8EA7, 0xB812, 0x8EA8, 0xB813, 0x8EA9, 0xB814, 0x8EAA, 0xB815,
+	0x8EAB, 0xB816, 0x8EAC, 0xB817, 0x8EAD, 0xB81A, 0x8EAE, 0xB81C,
+	0x8EAF, 0xB81E, 0x8EB0, 0xB81F, 0x8EB1, 0xB820, 0x8EB2, 0xB821,
+	0x8EB3, 0xB822, 0x8EB4, 0xB823, 0x8EB5, 0xB826, 0x8EB6, 0xB827,
+	0x8EB7, 0xB829, 0x8EB8, 0xB82A, 0x8EB9, 0xB82B, 0x8EBA, 0xB82D,
+	0x8EBB, 0xB82E, 0x8EBC, 0xB82F, 0x8EBD, 0xB830, 0x8EBE, 0xB831,
+	0x8EBF, 0xB832, 0x8EC0, 0xB833, 0x8EC1, 0xB836, 0x8EC2, 0xB83A,
+	0x8EC3, 0xB83B, 0x8EC4, 0xB83C, 0x8EC5, 0xB83D, 0x8EC6, 0xB83E,
+	0x8EC7, 0xB83F, 0x8EC8, 0xB841, 0x8EC9, 0xB842, 0x8ECA, 0xB843,
+	0x8ECB, 0xB845, 0x8ECC, 0xB846, 0x8ECD, 0xB847, 0x8ECE, 0xB848,
+	0x8ECF, 0xB849, 0x8ED0, 0xB84A, 0x8ED1, 0xB84B, 0x8ED2, 0xB84C,
+	0x8ED3, 0xB84D, 0x8ED4, 0xB84E, 0x8ED5, 0xB84F, 0x8ED6, 0xB850,
+	0x8ED7, 0xB852, 0x8ED8, 0xB854, 0x8ED9, 0xB855, 0x8EDA, 0xB856,
+	0x8EDB, 0xB857, 0x8EDC, 0xB858, 0x8EDD, 0xB859, 0x8EDE, 0xB85A,
+	0x8EDF, 0xB85B, 0x8EE0, 0xB85E, 0x8EE1, 0xB85F, 0x8EE2, 0xB861,
+	0x8EE3, 0xB862, 0x8EE4, 0xB863, 0x8EE5, 0xB865, 0x8EE6, 0xB866,
+	0x8EE7, 0xB867, 0x8EE8, 0xB868, 0x8EE9, 0xB869, 0x8EEA, 0xB86A,
+	0x8EEB, 0xB86B, 0x8EEC, 0xB86E, 0x8EED, 0xB870, 0x8EEE, 0xB872,
+	0x8EEF, 0xB873, 0x8EF0, 0xB874, 0x8EF1, 0xB875, 0x8EF2, 0xB876,
+	0x8EF3, 0xB877, 0x8EF4, 0xB879, 0x8EF5, 0xB87A, 0x8EF6, 0xB87B,
+	0x8EF7, 0xB87D, 0x8EF8, 0xB87E, 0x8EF9, 0xB87F, 0x8EFA, 0xB880,
+	0x8EFB, 0xB881, 0x8EFC, 0xB882, 0x8EFD, 0xB883, 0x8EFE, 0xB884,
+	0x8F41, 0xB885, 0x8F42, 0xB886, 0x8F43, 0xB887, 0x8F44, 0xB888,
+	0x8F45, 0xB889, 0x8F46, 0xB88A, 0x8F47, 0xB88B, 0x8F48, 0xB88C,
+	0x8F49, 0xB88E, 0x8F4A, 0xB88F, 0x8F4B, 0xB890, 0x8F4C, 0xB891,
+	0x8F4D, 0xB892, 0x8F4E, 0xB893, 0x8F4F, 0xB894, 0x8F50, 0xB895,
+	0x8F51, 0xB896, 0x8F52, 0xB897, 0x8F53, 0xB898, 0x8F54, 0xB899,
+	0x8F55, 0xB89A, 0x8F56, 0xB89B, 0x8F57, 0xB89C, 0x8F58, 0xB89D,
+	0x8F59, 0xB89E, 0x8F5A, 0xB89F, 0x8F61, 0xB8A0, 0x8F62, 0xB8A1,
+	0x8F63, 0xB8A2, 0x8F64, 0xB8A3, 0x8F65, 0xB8A4, 0x8F66, 0xB8A5,
+	0x8F67, 0xB8A6, 0x8F68, 0xB8A7, 0x8F69, 0xB8A9, 0x8F6A, 0xB8AA,
+	0x8F6B, 0xB8AB, 0x8F6C, 0xB8AC, 0x8F6D, 0xB8AD, 0x8F6E, 0xB8AE,
+	0x8F6F, 0xB8AF, 0x8F70, 0xB8B1, 0x8F71, 0xB8B2, 0x8F72, 0xB8B3,
+	0x8F73, 0xB8B5, 0x8F74, 0xB8B6, 0x8F75, 0xB8B7, 0x8F76, 0xB8B9,
+	0x8F77, 0xB8BA, 0x8F78, 0xB8BB, 0x8F79, 0xB8BC, 0x8F7A, 0xB8BD,
+	0x8F81, 0xB8BE, 0x8F82, 0xB8BF, 0x8F83, 0xB8C2, 0x8F84, 0xB8C4,
+	0x8F85, 0xB8C6, 0x8F86, 0xB8C7, 0x8F87, 0xB8C8, 0x8F88, 0xB8C9,
+	0x8F89, 0xB8CA, 0x8F8A, 0xB8CB, 0x8F8B, 0xB8CD, 0x8F8C, 0xB8CE,
+	0x8F8D, 0xB8CF, 0x8F8E, 0xB8D1, 0x8F8F, 0xB8D2, 0x8F90, 0xB8D3,
+	0x8F91, 0xB8D5, 0x8F92, 0xB8D6, 0x8F93, 0xB8D7, 0x8F94, 0xB8D8,
+	0x8F95, 0xB8D9, 0x8F96, 0xB8DA, 0x8F97, 0xB8DB, 0x8F98, 0xB8DC,
+	0x8F99, 0xB8DE, 0x8F9A, 0xB8E0, 0x8F9B, 0xB8E2, 0x8F9C, 0xB8E3,
+	0x8F9D, 0xB8E4, 0x8F9E, 0xB8E5, 0x8F9F, 0xB8E6, 0x8FA0, 0xB8E7,
+	0x8FA1, 0xB8EA, 0x8FA2, 0xB8EB, 0x8FA3, 0xB8ED, 0x8FA4, 0xB8EE,
+	0x8FA5, 0xB8EF, 0x8FA6, 0xB8F1, 0x8FA7, 0xB8F2, 0x8FA8, 0xB8F3,
+	0x8FA9, 0xB8F4, 0x8FAA, 0xB8F5, 0x8FAB, 0xB8F6, 0x8FAC, 0xB8F7,
+	0x8FAD, 0xB8FA, 0x8FAE, 0xB8FC, 0x8FAF, 0xB8FE, 0x8FB0, 0xB8FF,
+	0x8FB1, 0xB900, 0x8FB2, 0xB901, 0x8FB3, 0xB902, 0x8FB4, 0xB903,
+	0x8FB5, 0xB905, 0x8FB6, 0xB906, 0x8FB7, 0xB907, 0x8FB8, 0xB908,
+	0x8FB9, 0xB909, 0x8FBA, 0xB90A, 0x8FBB, 0xB90B, 0x8FBC, 0xB90C,
+	0x8FBD, 0xB90D, 0x8FBE, 0xB90E, 0x8FBF, 0xB90F, 0x8FC0, 0xB910,
+	0x8FC1, 0xB911, 0x8FC2, 0xB912, 0x8FC3, 0xB913, 0x8FC4, 0xB914,
+	0x8FC5, 0xB915, 0x8FC6, 0xB916, 0x8FC7, 0xB917, 0x8FC8, 0xB919,
+	0x8FC9, 0xB91A, 0x8FCA, 0xB91B, 0x8FCB, 0xB91C, 0x8FCC, 0xB91D,
+	0x8FCD, 0xB91E, 0x8FCE, 0xB91F, 0x8FCF, 0xB921, 0x8FD0, 0xB922,
+	0x8FD1, 0xB923, 0x8FD2, 0xB924, 0x8FD3, 0xB925, 0x8FD4, 0xB926,
+	0x8FD5, 0xB927, 0x8FD6, 0xB928, 0x8FD7, 0xB929, 0x8FD8, 0xB92A,
+	0x8FD9, 0xB92B, 0x8FDA, 0xB92C, 0x8FDB, 0xB92D, 0x8FDC, 0xB92E,
+	0x8FDD, 0xB92F, 0x8FDE, 0xB930, 0x8FDF, 0xB931, 0x8FE0, 0xB932,
+	0x8FE1, 0xB933, 0x8FE2, 0xB934, 0x8FE3, 0xB935, 0x8FE4, 0xB936,
+	0x8FE5, 0xB937, 0x8FE6, 0xB938, 0x8FE7, 0xB939, 0x8FE8, 0xB93A,
+	0x8FE9, 0xB93B, 0x8FEA, 0xB93E, 0x8FEB, 0xB93F, 0x8FEC, 0xB941,
+	0x8FED, 0xB942, 0x8FEE, 0xB943, 0x8FEF, 0xB945, 0x8FF0, 0xB946,
+	0x8FF1, 0xB947, 0x8FF2, 0xB948, 0x8FF3, 0xB949, 0x8FF4, 0xB94A,
+	0x8FF5, 0xB94B, 0x8FF6, 0xB94D, 0x8FF7, 0xB94E, 0x8FF8, 0xB950,
+	0x8FF9, 0xB952, 0x8FFA, 0xB953, 0x8FFB, 0xB954, 0x8FFC, 0xB955,
+	0x8FFD, 0xB956, 0x8FFE, 0xB957, 0x9041, 0xB95A, 0x9042, 0xB95B,
+	0x9043, 0xB95D, 0x9044, 0xB95E, 0x9045, 0xB95F, 0x9046, 0xB961,
+	0x9047, 0xB962, 0x9048, 0xB963, 0x9049, 0xB964, 0x904A, 0xB965,
+	0x904B, 0xB966, 0x904C, 0xB967, 0x904D, 0xB96A, 0x904E, 0xB96C,
+	0x904F, 0xB96E, 0x9050, 0xB96F, 0x9051, 0xB970, 0x9052, 0xB971,
+	0x9053, 0xB972, 0x9054, 0xB973, 0x9055, 0xB976, 0x9056, 0xB977,
+	0x9057, 0xB979, 0x9058, 0xB97A, 0x9059, 0xB97B, 0x905A, 0xB97D,
+	0x9061, 0xB97E, 0x9062, 0xB97F, 0x9063, 0xB980, 0x9064, 0xB981,
+	0x9065, 0xB982, 0x9066, 0xB983, 0x9067, 0xB986, 0x9068, 0xB988,
+	0x9069, 0xB98B, 0x906A, 0xB98C, 0x906B, 0xB98F, 0x906C, 0xB990,
+	0x906D, 0xB991, 0x906E, 0xB992, 0x906F, 0xB993, 0x9070, 0xB994,
+	0x9071, 0xB995, 0x9072, 0xB996, 0x9073, 0xB997, 0x9074, 0xB998,
+	0x9075, 0xB999, 0x9076, 0xB99A, 0x9077, 0xB99B, 0x9078, 0xB99C,
+	0x9079, 0xB99D, 0x907A, 0xB99E, 0x9081, 0xB99F, 0x9082, 0xB9A0,
+	0x9083, 0xB9A1, 0x9084, 0xB9A2, 0x9085, 0xB9A3, 0x9086, 0xB9A4,
+	0x9087, 0xB9A5, 0x9088, 0xB9A6, 0x9089, 0xB9A7, 0x908A, 0xB9A8,
+	0x908B, 0xB9A9, 0x908C, 0xB9AA, 0x908D, 0xB9AB, 0x908E, 0xB9AE,
+	0x908F, 0xB9AF, 0x9090, 0xB9B1, 0x9091, 0xB9B2, 0x9092, 0xB9B3,
+	0x9093, 0xB9B5, 0x9094, 0xB9B6, 0x9095, 0xB9B7, 0x9096, 0xB9B8,
+	0x9097, 0xB9B9, 0x9098, 0xB9BA, 0x9099, 0xB9BB, 0x909A, 0xB9BE,
+	0x909B, 0xB9C0, 0x909C, 0xB9C2, 0x909D, 0xB9C3, 0x909E, 0xB9C4,
+	0x909F, 0xB9C5, 0x90A0, 0xB9C6, 0x90A1, 0xB9C7, 0x90A2, 0xB9CA,
+	0x90A3, 0xB9CB, 0x90A4, 0xB9CD, 0x90A5, 0xB9D3, 0x90A6, 0xB9D4,
+	0x90A7, 0xB9D5, 0x90A8, 0xB9D6, 0x90A9, 0xB9D7, 0x90AA, 0xB9DA,
+	0x90AB, 0xB9DC, 0x90AC, 0xB9DF, 0x90AD, 0xB9E0, 0x90AE, 0xB9E2,
+	0x90AF, 0xB9E6, 0x90B0, 0xB9E7, 0x90B1, 0xB9E9, 0x90B2, 0xB9EA,
+	0x90B3, 0xB9EB, 0x90B4, 0xB9ED, 0x90B5, 0xB9EE, 0x90B6, 0xB9EF,
+	0x90B7, 0xB9F0, 0x90B8, 0xB9F1, 0x90B9, 0xB9F2, 0x90BA, 0xB9F3,
+	0x90BB, 0xB9F6, 0x90BC, 0xB9FB, 0x90BD, 0xB9FC, 0x90BE, 0xB9FD,
+	0x90BF, 0xB9FE, 0x90C0, 0xB9FF, 0x90C1, 0xBA02, 0x90C2, 0xBA03,
+	0x90C3, 0xBA04, 0x90C4, 0xBA05, 0x90C5, 0xBA06, 0x90C6, 0xBA07,
+	0x90C7, 0xBA09, 0x90C8, 0xBA0A, 0x90C9, 0xBA0B, 0x90CA, 0xBA0C,
+	0x90CB, 0xBA0D, 0x90CC, 0xBA0E, 0x90CD, 0xBA0F, 0x90CE, 0xBA10,
+	0x90CF, 0xBA11, 0x90D0, 0xBA12, 0x90D1, 0xBA13, 0x90D2, 0xBA14,
+	0x90D3, 0xBA16, 0x90D4, 0xBA17, 0x90D5, 0xBA18, 0x90D6, 0xBA19,
+	0x90D7, 0xBA1A, 0x90D8, 0xBA1B, 0x90D9, 0xBA1C, 0x90DA, 0xBA1D,
+	0x90DB, 0xBA1E, 0x90DC, 0xBA1F, 0x90DD, 0xBA20, 0x90DE, 0xBA21,
+	0x90DF, 0xBA22, 0x90E0, 0xBA23, 0x90E1, 0xBA24, 0x90E2, 0xBA25,
+	0x90E3, 0xBA26, 0x90E4, 0xBA27, 0x90E5, 0xBA28, 0x90E6, 0xBA29,
+	0x90E7, 0xBA2A, 0x90E8, 0xBA2B, 0x90E9, 0xBA2C, 0x90EA, 0xBA2D,
+	0x90EB, 0xBA2E, 0x90EC, 0xBA2F, 0x90ED, 0xBA30, 0x90EE, 0xBA31,
+	0x90EF, 0xBA32, 0x90F0, 0xBA33, 0x90F1, 0xBA34, 0x90F2, 0xBA35,
+	0x90F3, 0xBA36, 0x90F4, 0xBA37, 0x90F5, 0xBA3A, 0x90F6, 0xBA3B,
+	0x90F7, 0xBA3D, 0x90F8, 0xBA3E, 0x90F9, 0xBA3F, 0x90FA, 0xBA41,
+	0x90FB, 0xBA43, 0x90FC, 0xBA44, 0x90FD, 0xBA45, 0x90FE, 0xBA46,
+	0x9141, 0xBA47, 0x9142, 0xBA4A, 0x9143, 0xBA4C, 0x9144, 0xBA4F,
+	0x9145, 0xBA50, 0x9146, 0xBA51, 0x9147, 0xBA52, 0x9148, 0xBA56,
+	0x9149, 0xBA57, 0x914A, 0xBA59, 0x914B, 0xBA5A, 0x914C, 0xBA5B,
+	0x914D, 0xBA5D, 0x914E, 0xBA5E, 0x914F, 0xBA5F, 0x9150, 0xBA60,
+	0x9151, 0xBA61, 0x9152, 0xBA62, 0x9153, 0xBA63, 0x9154, 0xBA66,
+	0x9155, 0xBA6A, 0x9156, 0xBA6B, 0x9157, 0xBA6C, 0x9158, 0xBA6D,
+	0x9159, 0xBA6E, 0x915A, 0xBA6F, 0x9161, 0xBA72, 0x9162, 0xBA73,
+	0x9163, 0xBA75, 0x9164, 0xBA76, 0x9165, 0xBA77, 0x9166, 0xBA79,
+	0x9167, 0xBA7A, 0x9168, 0xBA7B, 0x9169, 0xBA7C, 0x916A, 0xBA7D,
+	0x916B, 0xBA7E, 0x916C, 0xBA7F, 0x916D, 0xBA80, 0x916E, 0xBA81,
+	0x916F, 0xBA82, 0x9170, 0xBA86, 0x9171, 0xBA88, 0x9172, 0xBA89,
+	0x9173, 0xBA8A, 0x9174, 0xBA8B, 0x9175, 0xBA8D, 0x9176, 0xBA8E,
+	0x9177, 0xBA8F, 0x9178, 0xBA90, 0x9179, 0xBA91, 0x917A, 0xBA92,
+	0x9181, 0xBA93, 0x9182, 0xBA94, 0x9183, 0xBA95, 0x9184, 0xBA96,
+	0x9185, 0xBA97, 0x9186, 0xBA98, 0x9187, 0xBA99, 0x9188, 0xBA9A,
+	0x9189, 0xBA9B, 0x918A, 0xBA9C, 0x918B, 0xBA9D, 0x918C, 0xBA9E,
+	0x918D, 0xBA9F, 0x918E, 0xBAA0, 0x918F, 0xBAA1, 0x9190, 0xBAA2,
+	0x9191, 0xBAA3, 0x9192, 0xBAA4, 0x9193, 0xBAA5, 0x9194, 0xBAA6,
+	0x9195, 0xBAA7, 0x9196, 0xBAAA, 0x9197, 0xBAAD, 0x9198, 0xBAAE,
+	0x9199, 0xBAAF, 0x919A, 0xBAB1, 0x919B, 0xBAB3, 0x919C, 0xBAB4,
+	0x919D, 0xBAB5, 0x919E, 0xBAB6, 0x919F, 0xBAB7, 0x91A0, 0xBABA,
+	0x91A1, 0xBABC, 0x91A2, 0xBABE, 0x91A3, 0xBABF, 0x91A4, 0xBAC0,
+	0x91A5, 0xBAC1, 0x91A6, 0xBAC2, 0x91A7, 0xBAC3, 0x91A8, 0xBAC5,
+	0x91A9, 0xBAC6, 0x91AA, 0xBAC7, 0x91AB, 0xBAC9, 0x91AC, 0xBACA,
+	0x91AD, 0xBACB, 0x91AE, 0xBACC, 0x91AF, 0xBACD, 0x91B0, 0xBACE,
+	0x91B1, 0xBACF, 0x91B2, 0xBAD0, 0x91B3, 0xBAD1, 0x91B4, 0xBAD2,
+	0x91B5, 0xBAD3, 0x91B6, 0xBAD4, 0x91B7, 0xBAD5, 0x91B8, 0xBAD6,
+	0x91B9, 0xBAD7, 0x91BA, 0xBADA, 0x91BB, 0xBADB, 0x91BC, 0xBADC,
+	0x91BD, 0xBADD, 0x91BE, 0xBADE, 0x91BF, 0xBADF, 0x91C0, 0xBAE0,
+	0x91C1, 0xBAE1, 0x91C2, 0xBAE2, 0x91C3, 0xBAE3, 0x91C4, 0xBAE4,
+	0x91C5, 0xBAE5, 0x91C6, 0xBAE6, 0x91C7, 0xBAE7, 0x91C8, 0xBAE8,
+	0x91C9, 0xBAE9, 0x91CA, 0xBAEA, 0x91CB, 0xBAEB, 0x91CC, 0xBAEC,
+	0x91CD, 0xBAED, 0x91CE, 0xBAEE, 0x91CF, 0xBAEF, 0x91D0, 0xBAF0,
+	0x91D1, 0xBAF1, 0x91D2, 0xBAF2, 0x91D3, 0xBAF3, 0x91D4, 0xBAF4,
+	0x91D5, 0xBAF5, 0x91D6, 0xBAF6, 0x91D7, 0xBAF7, 0x91D8, 0xBAF8,
+	0x91D9, 0xBAF9, 0x91DA, 0xBAFA, 0x91DB, 0xBAFB, 0x91DC, 0xBAFD,
+	0x91DD, 0xBAFE, 0x91DE, 0xBAFF, 0x91DF, 0xBB01, 0x91E0, 0xBB02,
+	0x91E1, 0xBB03, 0x91E2, 0xBB05, 0x91E3, 0xBB06, 0x91E4, 0xBB07,
+	0x91E5, 0xBB08, 0x91E6, 0xBB09, 0x91E7, 0xBB0A, 0x91E8, 0xBB0B,
+	0x91E9, 0xBB0C, 0x91EA, 0xBB0E, 0x91EB, 0xBB10, 0x91EC, 0xBB12,
+	0x91ED, 0xBB13, 0x91EE, 0xBB14, 0x91EF, 0xBB15, 0x91F0, 0xBB16,
+	0x91F1, 0xBB17, 0x91F2, 0xBB19, 0x91F3, 0xBB1A, 0x91F4, 0xBB1B,
+	0x91F5, 0xBB1D, 0x91F6, 0xBB1E, 0x91F7, 0xBB1F, 0x91F8, 0xBB21,
+	0x91F9, 0xBB22, 0x91FA, 0xBB23, 0x91FB, 0xBB24, 0x91FC, 0xBB25,
+	0x91FD, 0xBB26, 0x91FE, 0xBB27, 0x9241, 0xBB28, 0x9242, 0xBB2A,
+	0x9243, 0xBB2C, 0x9244, 0xBB2D, 0x9245, 0xBB2E, 0x9246, 0xBB2F,
+	0x9247, 0xBB30, 0x9248, 0xBB31, 0x9249, 0xBB32, 0x924A, 0xBB33,
+	0x924B, 0xBB37, 0x924C, 0xBB39, 0x924D, 0xBB3A, 0x924E, 0xBB3F,
+	0x924F, 0xBB40, 0x9250, 0xBB41, 0x9251, 0xBB42, 0x9252, 0xBB43,
+	0x9253, 0xBB46, 0x9254, 0xBB48, 0x9255, 0xBB4A, 0x9256, 0xBB4B,
+	0x9257, 0xBB4C, 0x9258, 0xBB4E, 0x9259, 0xBB51, 0x925A, 0xBB52,
+	0x9261, 0xBB53, 0x9262, 0xBB55, 0x9263, 0xBB56, 0x9264, 0xBB57,
+	0x9265, 0xBB59, 0x9266, 0xBB5A, 0x9267, 0xBB5B, 0x9268, 0xBB5C,
+	0x9269, 0xBB5D, 0x926A, 0xBB5E, 0x926B, 0xBB5F, 0x926C, 0xBB60,
+	0x926D, 0xBB62, 0x926E, 0xBB64, 0x926F, 0xBB65, 0x9270, 0xBB66,
+	0x9271, 0xBB67, 0x9272, 0xBB68, 0x9273, 0xBB69, 0x9274, 0xBB6A,
+	0x9275, 0xBB6B, 0x9276, 0xBB6D, 0x9277, 0xBB6E, 0x9278, 0xBB6F,
+	0x9279, 0xBB70, 0x927A, 0xBB71, 0x9281, 0xBB72, 0x9282, 0xBB73,
+	0x9283, 0xBB74, 0x9284, 0xBB75, 0x9285, 0xBB76, 0x9286, 0xBB77,
+	0x9287, 0xBB78, 0x9288, 0xBB79, 0x9289, 0xBB7A, 0x928A, 0xBB7B,
+	0x928B, 0xBB7C, 0x928C, 0xBB7D, 0x928D, 0xBB7E, 0x928E, 0xBB7F,
+	0x928F, 0xBB80, 0x9290, 0xBB81, 0x9291, 0xBB82, 0x9292, 0xBB83,
+	0x9293, 0xBB84, 0x9294, 0xBB85, 0x9295, 0xBB86, 0x9296, 0xBB87,
+	0x9297, 0xBB89, 0x9298, 0xBB8A, 0x9299, 0xBB8B, 0x929A, 0xBB8D,
+	0x929B, 0xBB8E, 0x929C, 0xBB8F, 0x929D, 0xBB91, 0x929E, 0xBB92,
+	0x929F, 0xBB93, 0x92A0, 0xBB94, 0x92A1, 0xBB95, 0x92A2, 0xBB96,
+	0x92A3, 0xBB97, 0x92A4, 0xBB98, 0x92A5, 0xBB99, 0x92A6, 0xBB9A,
+	0x92A7, 0xBB9B, 0x92A8, 0xBB9C, 0x92A9, 0xBB9D, 0x92AA, 0xBB9E,
+	0x92AB, 0xBB9F, 0x92AC, 0xBBA0, 0x92AD, 0xBBA1, 0x92AE, 0xBBA2,
+	0x92AF, 0xBBA3, 0x92B0, 0xBBA5, 0x92B1, 0xBBA6, 0x92B2, 0xBBA7,
+	0x92B3, 0xBBA9, 0x92B4, 0xBBAA, 0x92B5, 0xBBAB, 0x92B6, 0xBBAD,
+	0x92B7, 0xBBAE, 0x92B8, 0xBBAF, 0x92B9, 0xBBB0, 0x92BA, 0xBBB1,
+	0x92BB, 0xBBB2, 0x92BC, 0xBBB3, 0x92BD, 0xBBB5, 0x92BE, 0xBBB6,
+	0x92BF, 0xBBB8, 0x92C0, 0xBBB9, 0x92C1, 0xBBBA, 0x92C2, 0xBBBB,
+	0x92C3, 0xBBBC, 0x92C4, 0xBBBD, 0x92C5, 0xBBBE, 0x92C6, 0xBBBF,
+	0x92C7, 0xBBC1, 0x92C8, 0xBBC2, 0x92C9, 0xBBC3, 0x92CA, 0xBBC5,
+	0x92CB, 0xBBC6, 0x92CC, 0xBBC7, 0x92CD, 0xBBC9, 0x92CE, 0xBBCA,
+	0x92CF, 0xBBCB, 0x92D0, 0xBBCC, 0x92D1, 0xBBCD, 0x92D2, 0xBBCE,
+	0x92D3, 0xBBCF, 0x92D4, 0xBBD1, 0x92D5, 0xBBD2, 0x92D6, 0xBBD4,
+	0x92D7, 0xBBD5, 0x92D8, 0xBBD6, 0x92D9, 0xBBD7, 0x92DA, 0xBBD8,
+	0x92DB, 0xBBD9, 0x92DC, 0xBBDA, 0x92DD, 0xBBDB, 0x92DE, 0xBBDC,
+	0x92DF, 0xBBDD, 0x92E0, 0xBBDE, 0x92E1, 0xBBDF, 0x92E2, 0xBBE0,
+	0x92E3, 0xBBE1, 0x92E4, 0xBBE2, 0x92E5, 0xBBE3, 0x92E6, 0xBBE4,
+	0x92E7, 0xBBE5, 0x92E8, 0xBBE6, 0x92E9, 0xBBE7, 0x92EA, 0xBBE8,
+	0x92EB, 0xBBE9, 0x92EC, 0xBBEA, 0x92ED, 0xBBEB, 0x92EE, 0xBBEC,
+	0x92EF, 0xBBED, 0x92F0, 0xBBEE, 0x92F1, 0xBBEF, 0x92F2, 0xBBF0,
+	0x92F3, 0xBBF1, 0x92F4, 0xBBF2, 0x92F5, 0xBBF3, 0x92F6, 0xBBF4,
+	0x92F7, 0xBBF5, 0x92F8, 0xBBF6, 0x92F9, 0xBBF7, 0x92FA, 0xBBFA,
+	0x92FB, 0xBBFB, 0x92FC, 0xBBFD, 0x92FD, 0xBBFE, 0x92FE, 0xBC01,
+	0x9341, 0xBC03, 0x9342, 0xBC04, 0x9343, 0xBC05, 0x9344, 0xBC06,
+	0x9345, 0xBC07, 0x9346, 0xBC0A, 0x9347, 0xBC0E, 0x9348, 0xBC10,
+	0x9349, 0xBC12, 0x934A, 0xBC13, 0x934B, 0xBC19, 0x934C, 0xBC1A,
+	0x934D, 0xBC20, 0x934E, 0xBC21, 0x934F, 0xBC22, 0x9350, 0xBC23,
+	0x9351, 0xBC26, 0x9352, 0xBC28, 0x9353, 0xBC2A, 0x9354, 0xBC2B,
+	0x9355, 0xBC2C, 0x9356, 0xBC2E, 0x9357, 0xBC2F, 0x9358, 0xBC32,
+	0x9359, 0xBC33, 0x935A, 0xBC35, 0x9361, 0xBC36, 0x9362, 0xBC37,
+	0x9363, 0xBC39, 0x9364, 0xBC3A, 0x9365, 0xBC3B, 0x9366, 0xBC3C,
+	0x9367, 0xBC3D, 0x9368, 0xBC3E, 0x9369, 0xBC3F, 0x936A, 0xBC42,
+	0x936B, 0xBC46, 0x936C, 0xBC47, 0x936D, 0xBC48, 0x936E, 0xBC4A,
+	0x936F, 0xBC4B, 0x9370, 0xBC4E, 0x9371, 0xBC4F, 0x9372, 0xBC51,
+	0x9373, 0xBC52, 0x9374, 0xBC53, 0x9375, 0xBC54, 0x9376, 0xBC55,
+	0x9377, 0xBC56, 0x9378, 0xBC57, 0x9379, 0xBC58, 0x937A, 0xBC59,
+	0x9381, 0xBC5A, 0x9382, 0xBC5B, 0x9383, 0xBC5C, 0x9384, 0xBC5E,
+	0x9385, 0xBC5F, 0x9386, 0xBC60, 0x9387, 0xBC61, 0x9388, 0xBC62,
+	0x9389, 0xBC63, 0x938A, 0xBC64, 0x938B, 0xBC65, 0x938C, 0xBC66,
+	0x938D, 0xBC67, 0x938E, 0xBC68, 0x938F, 0xBC69, 0x9390, 0xBC6A,
+	0x9391, 0xBC6B, 0x9392, 0xBC6C, 0x9393, 0xBC6D, 0x9394, 0xBC6E,
+	0x9395, 0xBC6F, 0x9396, 0xBC70, 0x9397, 0xBC71, 0x9398, 0xBC72,
+	0x9399, 0xBC73, 0x939A, 0xBC74, 0x939B, 0xBC75, 0x939C, 0xBC76,
+	0x939D, 0xBC77, 0x939E, 0xBC78, 0x939F, 0xBC79, 0x93A0, 0xBC7A,
+	0x93A1, 0xBC7B, 0x93A2, 0xBC7C, 0x93A3, 0xBC7D, 0x93A4, 0xBC7E,
+	0x93A5, 0xBC7F, 0x93A6, 0xBC80, 0x93A7, 0xBC81, 0x93A8, 0xBC82,
+	0x93A9, 0xBC83, 0x93AA, 0xBC86, 0x93AB, 0xBC87, 0x93AC, 0xBC89,
+	0x93AD, 0xBC8A, 0x93AE, 0xBC8D, 0x93AF, 0xBC8F, 0x93B0, 0xBC90,
+	0x93B1, 0xBC91, 0x93B2, 0xBC92, 0x93B3, 0xBC93, 0x93B4, 0xBC96,
+	0x93B5, 0xBC98, 0x93B6, 0xBC9B, 0x93B7, 0xBC9C, 0x93B8, 0xBC9D,
+	0x93B9, 0xBC9E, 0x93BA, 0xBC9F, 0x93BB, 0xBCA2, 0x93BC, 0xBCA3,
+	0x93BD, 0xBCA5, 0x93BE, 0xBCA6, 0x93BF, 0xBCA9, 0x93C0, 0xBCAA,
+	0x93C1, 0xBCAB, 0x93C2, 0xBCAC, 0x93C3, 0xBCAD, 0x93C4, 0xBCAE,
+	0x93C5, 0xBCAF, 0x93C6, 0xBCB2, 0x93C7, 0xBCB6, 0x93C8, 0xBCB7,
+	0x93C9, 0xBCB8, 0x93CA, 0xBCB9, 0x93CB, 0xBCBA, 0x93CC, 0xBCBB,
+	0x93CD, 0xBCBE, 0x93CE, 0xBCBF, 0x93CF, 0xBCC1, 0x93D0, 0xBCC2,
+	0x93D1, 0xBCC3, 0x93D2, 0xBCC5, 0x93D3, 0xBCC6, 0x93D4, 0xBCC7,
+	0x93D5, 0xBCC8, 0x93D6, 0xBCC9, 0x93D7, 0xBCCA, 0x93D8, 0xBCCB,
+	0x93D9, 0xBCCC, 0x93DA, 0xBCCE, 0x93DB, 0xBCD2, 0x93DC, 0xBCD3,
+	0x93DD, 0xBCD4, 0x93DE, 0xBCD6, 0x93DF, 0xBCD7, 0x93E0, 0xBCD9,
+	0x93E1, 0xBCDA, 0x93E2, 0xBCDB, 0x93E3, 0xBCDD, 0x93E4, 0xBCDE,
+	0x93E5, 0xBCDF, 0x93E6, 0xBCE0, 0x93E7, 0xBCE1, 0x93E8, 0xBCE2,
+	0x93E9, 0xBCE3, 0x93EA, 0xBCE4, 0x93EB, 0xBCE5, 0x93EC, 0xBCE6,
+	0x93ED, 0xBCE7, 0x93EE, 0xBCE8, 0x93EF, 0xBCE9, 0x93F0, 0xBCEA,
+	0x93F1, 0xBCEB, 0x93F2, 0xBCEC, 0x93F3, 0xBCED, 0x93F4, 0xBCEE,
+	0x93F5, 0xBCEF, 0x93F6, 0xBCF0, 0x93F7, 0xBCF1, 0x93F8, 0xBCF2,
+	0x93F9, 0xBCF3, 0x93FA, 0xBCF7, 0x93FB, 0xBCF9, 0x93FC, 0xBCFA,
+	0x93FD, 0xBCFB, 0x93FE, 0xBCFD, 0x9441, 0xBCFE, 0x9442, 0xBCFF,
+	0x9443, 0xBD00, 0x9444, 0xBD01, 0x9445, 0xBD02, 0x9446, 0xBD03,
+	0x9447, 0xBD06, 0x9448, 0xBD08, 0x9449, 0xBD0A, 0x944A, 0xBD0B,
+	0x944B, 0xBD0C, 0x944C, 0xBD0D, 0x944D, 0xBD0E, 0x944E, 0xBD0F,
+	0x944F, 0xBD11, 0x9450, 0xBD12, 0x9451, 0xBD13, 0x9452, 0xBD15,
+	0x9453, 0xBD16, 0x9454, 0xBD17, 0x9455, 0xBD18, 0x9456, 0xBD19,
+	0x9457, 0xBD1A, 0x9458, 0xBD1B, 0x9459, 0xBD1C, 0x945A, 0xBD1D,
+	0x9461, 0xBD1E, 0x9462, 0xBD1F, 0x9463, 0xBD20, 0x9464, 0xBD21,
+	0x9465, 0xBD22, 0x9466, 0xBD23, 0x9467, 0xBD25, 0x9468, 0xBD26,
+	0x9469, 0xBD27, 0x946A, 0xBD28, 0x946B, 0xBD29, 0x946C, 0xBD2A,
+	0x946D, 0xBD2B, 0x946E, 0xBD2D, 0x946F, 0xBD2E, 0x9470, 0xBD2F,
+	0x9471, 0xBD30, 0x9472, 0xBD31, 0x9473, 0xBD32, 0x9474, 0xBD33,
+	0x9475, 0xBD34, 0x9476, 0xBD35, 0x9477, 0xBD36, 0x9478, 0xBD37,
+	0x9479, 0xBD38, 0x947A, 0xBD39, 0x9481, 0xBD3A, 0x9482, 0xBD3B,
+	0x9483, 0xBD3C, 0x9484, 0xBD3D, 0x9485, 0xBD3E, 0x9486, 0xBD3F,
+	0x9487, 0xBD41, 0x9488, 0xBD42, 0x9489, 0xBD43, 0x948A, 0xBD44,
+	0x948B, 0xBD45, 0x948C, 0xBD46, 0x948D, 0xBD47, 0x948E, 0xBD4A,
+	0x948F, 0xBD4B, 0x9490, 0xBD4D, 0x9491, 0xBD4E, 0x9492, 0xBD4F,
+	0x9493, 0xBD51, 0x9494, 0xBD52, 0x9495, 0xBD53, 0x9496, 0xBD54,
+	0x9497, 0xBD55, 0x9498, 0xBD56, 0x9499, 0xBD57, 0x949A, 0xBD5A,
+	0x949B, 0xBD5B, 0x949C, 0xBD5C, 0x949D, 0xBD5D, 0x949E, 0xBD5E,
+	0x949F, 0xBD5F, 0x94A0, 0xBD60, 0x94A1, 0xBD61, 0x94A2, 0xBD62,
+	0x94A3, 0xBD63, 0x94A4, 0xBD65, 0x94A5, 0xBD66, 0x94A6, 0xBD67,
+	0x94A7, 0xBD69, 0x94A8, 0xBD6A, 0x94A9, 0xBD6B, 0x94AA, 0xBD6C,
+	0x94AB, 0xBD6D, 0x94AC, 0xBD6E, 0x94AD, 0xBD6F, 0x94AE, 0xBD70,
+	0x94AF, 0xBD71, 0x94B0, 0xBD72, 0x94B1, 0xBD73, 0x94B2, 0xBD74,
+	0x94B3, 0xBD75, 0x94B4, 0xBD76, 0x94B5, 0xBD77, 0x94B6, 0xBD78,
+	0x94B7, 0xBD79, 0x94B8, 0xBD7A, 0x94B9, 0xBD7B, 0x94BA, 0xBD7C,
+	0x94BB, 0xBD7D, 0x94BC, 0xBD7E, 0x94BD, 0xBD7F, 0x94BE, 0xBD82,
+	0x94BF, 0xBD83, 0x94C0, 0xBD85, 0x94C1, 0xBD86, 0x94C2, 0xBD8B,
+	0x94C3, 0xBD8C, 0x94C4, 0xBD8D, 0x94C5, 0xBD8E, 0x94C6, 0xBD8F,
+	0x94C7, 0xBD92, 0x94C8, 0xBD94, 0x94C9, 0xBD96, 0x94CA, 0xBD97,
+	0x94CB, 0xBD98, 0x94CC, 0xBD9B, 0x94CD, 0xBD9D, 0x94CE, 0xBD9E,
+	0x94CF, 0xBD9F, 0x94D0, 0xBDA0, 0x94D1, 0xBDA1, 0x94D2, 0xBDA2,
+	0x94D3, 0xBDA3, 0x94D4, 0xBDA5, 0x94D5, 0xBDA6, 0x94D6, 0xBDA7,
+	0x94D7, 0xBDA8, 0x94D8, 0xBDA9, 0x94D9, 0xBDAA, 0x94DA, 0xBDAB,
+	0x94DB, 0xBDAC, 0x94DC, 0xBDAD, 0x94DD, 0xBDAE, 0x94DE, 0xBDAF,
+	0x94DF, 0xBDB1, 0x94E0, 0xBDB2, 0x94E1, 0xBDB3, 0x94E2, 0xBDB4,
+	0x94E3, 0xBDB5, 0x94E4, 0xBDB6, 0x94E5, 0xBDB7, 0x94E6, 0xBDB9,
+	0x94E7, 0xBDBA, 0x94E8, 0xBDBB, 0x94E9, 0xBDBC, 0x94EA, 0xBDBD,
+	0x94EB, 0xBDBE, 0x94EC, 0xBDBF, 0x94ED, 0xBDC0, 0x94EE, 0xBDC1,
+	0x94EF, 0xBDC2, 0x94F0, 0xBDC3, 0x94F1, 0xBDC4, 0x94F2, 0xBDC5,
+	0x94F3, 0xBDC6, 0x94F4, 0xBDC7, 0x94F5, 0xBDC8, 0x94F6, 0xBDC9,
+	0x94F7, 0xBDCA, 0x94F8, 0xBDCB, 0x94F9, 0xBDCC, 0x94FA, 0xBDCD,
+	0x94FB, 0xBDCE, 0x94FC, 0xBDCF, 0x94FD, 0xBDD0, 0x94FE, 0xBDD1,
+	0x9541, 0xBDD2, 0x9542, 0xBDD3, 0x9543, 0xBDD6, 0x9544, 0xBDD7,
+	0x9545, 0xBDD9, 0x9546, 0xBDDA, 0x9547, 0xBDDB, 0x9548, 0xBDDD,
+	0x9549, 0xBDDE, 0x954A, 0xBDDF, 0x954B, 0xBDE0, 0x954C, 0xBDE1,
+	0x954D, 0xBDE2, 0x954E, 0xBDE3, 0x954F, 0xBDE4, 0x9550, 0xBDE5,
+	0x9551, 0xBDE6, 0x9552, 0xBDE7, 0x9553, 0xBDE8, 0x9554, 0xBDEA,
+	0x9555, 0xBDEB, 0x9556, 0xBDEC, 0x9557, 0xBDED, 0x9558, 0xBDEE,
+	0x9559, 0xBDEF, 0x955A, 0xBDF1, 0x9561, 0xBDF2, 0x9562, 0xBDF3,
+	0x9563, 0xBDF5, 0x9564, 0xBDF6, 0x9565, 0xBDF7, 0x9566, 0xBDF9,
+	0x9567, 0xBDFA, 0x9568, 0xBDFB, 0x9569, 0xBDFC, 0x956A, 0xBDFD,
+	0x956B, 0xBDFE, 0x956C, 0xBDFF, 0x956D, 0xBE01, 0x956E, 0xBE02,
+	0x956F, 0xBE04, 0x9570, 0xBE06, 0x9571, 0xBE07, 0x9572, 0xBE08,
+	0x9573, 0xBE09, 0x9574, 0xBE0A, 0x9575, 0xBE0B, 0x9576, 0xBE0E,
+	0x9577, 0xBE0F, 0x9578, 0xBE11, 0x9579, 0xBE12, 0x957A, 0xBE13,
+	0x9581, 0xBE15, 0x9582, 0xBE16, 0x9583, 0xBE17, 0x9584, 0xBE18,
+	0x9585, 0xBE19, 0x9586, 0xBE1A, 0x9587, 0xBE1B, 0x9588, 0xBE1E,
+	0x9589, 0xBE20, 0x958A, 0xBE21, 0x958B, 0xBE22, 0x958C, 0xBE23,
+	0x958D, 0xBE24, 0x958E, 0xBE25, 0x958F, 0xBE26, 0x9590, 0xBE27,
+	0x9591, 0xBE28, 0x9592, 0xBE29, 0x9593, 0xBE2A, 0x9594, 0xBE2B,
+	0x9595, 0xBE2C, 0x9596, 0xBE2D, 0x9597, 0xBE2E, 0x9598, 0xBE2F,
+	0x9599, 0xBE30, 0x959A, 0xBE31, 0x959B, 0xBE32, 0x959C, 0xBE33,
+	0x959D, 0xBE34, 0x959E, 0xBE35, 0x959F, 0xBE36, 0x95A0, 0xBE37,
+	0x95A1, 0xBE38, 0x95A2, 0xBE39, 0x95A3, 0xBE3A, 0x95A4, 0xBE3B,
+	0x95A5, 0xBE3C, 0x95A6, 0xBE3D, 0x95A7, 0xBE3E, 0x95A8, 0xBE3F,
+	0x95A9, 0xBE40, 0x95AA, 0xBE41, 0x95AB, 0xBE42, 0x95AC, 0xBE43,
+	0x95AD, 0xBE46, 0x95AE, 0xBE47, 0x95AF, 0xBE49, 0x95B0, 0xBE4A,
+	0x95B1, 0xBE4B, 0x95B2, 0xBE4D, 0x95B3, 0xBE4F, 0x95B4, 0xBE50,
+	0x95B5, 0xBE51, 0x95B6, 0xBE52, 0x95B7, 0xBE53, 0x95B8, 0xBE56,
+	0x95B9, 0xBE58, 0x95BA, 0xBE5C, 0x95BB, 0xBE5D, 0x95BC, 0xBE5E,
+	0x95BD, 0xBE5F, 0x95BE, 0xBE62, 0x95BF, 0xBE63, 0x95C0, 0xBE65,
+	0x95C1, 0xBE66, 0x95C2, 0xBE67, 0x95C3, 0xBE69, 0x95C4, 0xBE6B,
+	0x95C5, 0xBE6C, 0x95C6, 0xBE6D, 0x95C7, 0xBE6E, 0x95C8, 0xBE6F,
+	0x95C9, 0xBE72, 0x95CA, 0xBE76, 0x95CB, 0xBE77, 0x95CC, 0xBE78,
+	0x95CD, 0xBE79, 0x95CE, 0xBE7A, 0x95CF, 0xBE7E, 0x95D0, 0xBE7F,
+	0x95D1, 0xBE81, 0x95D2, 0xBE82, 0x95D3, 0xBE83, 0x95D4, 0xBE85,
+	0x95D5, 0xBE86, 0x95D6, 0xBE87, 0x95D7, 0xBE88, 0x95D8, 0xBE89,
+	0x95D9, 0xBE8A, 0x95DA, 0xBE8B, 0x95DB, 0xBE8E, 0x95DC, 0xBE92,
+	0x95DD, 0xBE93, 0x95DE, 0xBE94, 0x95DF, 0xBE95, 0x95E0, 0xBE96,
+	0x95E1, 0xBE97, 0x95E2, 0xBE9A, 0x95E3, 0xBE9B, 0x95E4, 0xBE9C,
+	0x95E5, 0xBE9D, 0x95E6, 0xBE9E, 0x95E7, 0xBE9F, 0x95E8, 0xBEA0,
+	0x95E9, 0xBEA1, 0x95EA, 0xBEA2, 0x95EB, 0xBEA3, 0x95EC, 0xBEA4,
+	0x95ED, 0xBEA5, 0x95EE, 0xBEA6, 0x95EF, 0xBEA7, 0x95F0, 0xBEA9,
+	0x95F1, 0xBEAA, 0x95F2, 0xBEAB, 0x95F3, 0xBEAC, 0x95F4, 0xBEAD,
+	0x95F5, 0xBEAE, 0x95F6, 0xBEAF, 0x95F7, 0xBEB0, 0x95F8, 0xBEB1,
+	0x95F9, 0xBEB2, 0x95FA, 0xBEB3, 0x95FB, 0xBEB4, 0x95FC, 0xBEB5,
+	0x95FD, 0xBEB6, 0x95FE, 0xBEB7, 0x9641, 0xBEB8, 0x9642, 0xBEB9,
+	0x9643, 0xBEBA, 0x9644, 0xBEBB, 0x9645, 0xBEBC, 0x9646, 0xBEBD,
+	0x9647, 0xBEBE, 0x9648, 0xBEBF, 0x9649, 0xBEC0, 0x964A, 0xBEC1,
+	0x964B, 0xBEC2, 0x964C, 0xBEC3, 0x964D, 0xBEC4, 0x964E, 0xBEC5,
+	0x964F, 0xBEC6, 0x9650, 0xBEC7, 0x9651, 0xBEC8, 0x9652, 0xBEC9,
+	0x9653, 0xBECA, 0x9654, 0xBECB, 0x9655, 0xBECC, 0x9656, 0xBECD,
+	0x9657, 0xBECE, 0x9658, 0xBECF, 0x9659, 0xBED2, 0x965A, 0xBED3,
+	0x9661, 0xBED5, 0x9662, 0xBED6, 0x9663, 0xBED9, 0x9664, 0xBEDA,
+	0x9665, 0xBEDB, 0x9666, 0xBEDC, 0x9667, 0xBEDD, 0x9668, 0xBEDE,
+	0x9669, 0xBEDF, 0x966A, 0xBEE1, 0x966B, 0xBEE2, 0x966C, 0xBEE6,
+	0x966D, 0xBEE7, 0x966E, 0xBEE8, 0x966F, 0xBEE9, 0x9670, 0xBEEA,
+	0x9671, 0xBEEB, 0x9672, 0xBEED, 0x9673, 0xBEEE, 0x9674, 0xBEEF,
+	0x9675, 0xBEF0, 0x9676, 0xBEF1, 0x9677, 0xBEF2, 0x9678, 0xBEF3,
+	0x9679, 0xBEF4, 0x967A, 0xBEF5, 0x9681, 0xBEF6, 0x9682, 0xBEF7,
+	0x9683, 0xBEF8, 0x9684, 0xBEF9, 0x9685, 0xBEFA, 0x9686, 0xBEFB,
+	0x9687, 0xBEFC, 0x9688, 0xBEFD, 0x9689, 0xBEFE, 0x968A, 0xBEFF,
+	0x968B, 0xBF00, 0x968C, 0xBF02, 0x968D, 0xBF03, 0x968E, 0xBF04,
+	0x968F, 0xBF05, 0x9690, 0xBF06, 0x9691, 0xBF07, 0x9692, 0xBF0A,
+	0x9693, 0xBF0B, 0x9694, 0xBF0C, 0x9695, 0xBF0D, 0x9696, 0xBF0E,
+	0x9697, 0xBF0F, 0x9698, 0xBF10, 0x9699, 0xBF11, 0x969A, 0xBF12,
+	0x969B, 0xBF13, 0x969C, 0xBF14, 0x969D, 0xBF15, 0x969E, 0xBF16,
+	0x969F, 0xBF17, 0x96A0, 0xBF1A, 0x96A1, 0xBF1E, 0x96A2, 0xBF1F,
+	0x96A3, 0xBF20, 0x96A4, 0xBF21, 0x96A5, 0xBF22, 0x96A6, 0xBF23,
+	0x96A7, 0xBF24, 0x96A8, 0xBF25, 0x96A9, 0xBF26, 0x96AA, 0xBF27,
+	0x96AB, 0xBF28, 0x96AC, 0xBF29, 0x96AD, 0xBF2A, 0x96AE, 0xBF2B,
+	0x96AF, 0xBF2C, 0x96B0, 0xBF2D, 0x96B1, 0xBF2E, 0x96B2, 0xBF2F,
+	0x96B3, 0xBF30, 0x96B4, 0xBF31, 0x96B5, 0xBF32, 0x96B6, 0xBF33,
+	0x96B7, 0xBF34, 0x96B8, 0xBF35, 0x96B9, 0xBF36, 0x96BA, 0xBF37,
+	0x96BB, 0xBF38, 0x96BC, 0xBF39, 0x96BD, 0xBF3A, 0x96BE, 0xBF3B,
+	0x96BF, 0xBF3C, 0x96C0, 0xBF3D, 0x96C1, 0xBF3E, 0x96C2, 0xBF3F,
+	0x96C3, 0xBF42, 0x96C4, 0xBF43, 0x96C5, 0xBF45, 0x96C6, 0xBF46,
+	0x96C7, 0xBF47, 0x96C8, 0xBF49, 0x96C9, 0xBF4A, 0x96CA, 0xBF4B,
+	0x96CB, 0xBF4C, 0x96CC, 0xBF4D, 0x96CD, 0xBF4E, 0x96CE, 0xBF4F,
+	0x96CF, 0xBF52, 0x96D0, 0xBF53, 0x96D1, 0xBF54, 0x96D2, 0xBF56,
+	0x96D3, 0xBF57, 0x96D4, 0xBF58, 0x96D5, 0xBF59, 0x96D6, 0xBF5A,
+	0x96D7, 0xBF5B, 0x96D8, 0xBF5C, 0x96D9, 0xBF5D, 0x96DA, 0xBF5E,
+	0x96DB, 0xBF5F, 0x96DC, 0xBF60, 0x96DD, 0xBF61, 0x96DE, 0xBF62,
+	0x96DF, 0xBF63, 0x96E0, 0xBF64, 0x96E1, 0xBF65, 0x96E2, 0xBF66,
+	0x96E3, 0xBF67, 0x96E4, 0xBF68, 0x96E5, 0xBF69, 0x96E6, 0xBF6A,
+	0x96E7, 0xBF6B, 0x96E8, 0xBF6C, 0x96E9, 0xBF6D, 0x96EA, 0xBF6E,
+	0x96EB, 0xBF6F, 0x96EC, 0xBF70, 0x96ED, 0xBF71, 0x96EE, 0xBF72,
+	0x96EF, 0xBF73, 0x96F0, 0xBF74, 0x96F1, 0xBF75, 0x96F2, 0xBF76,
+	0x96F3, 0xBF77, 0x96F4, 0xBF78, 0x96F5, 0xBF79, 0x96F6, 0xBF7A,
+	0x96F7, 0xBF7B, 0x96F8, 0xBF7C, 0x96F9, 0xBF7D, 0x96FA, 0xBF7E,
+	0x96FB, 0xBF7F, 0x96FC, 0xBF80, 0x96FD, 0xBF81, 0x96FE, 0xBF82,
+	0x9741, 0xBF83, 0x9742, 0xBF84, 0x9743, 0xBF85, 0x9744, 0xBF86,
+	0x9745, 0xBF87, 0x9746, 0xBF88, 0x9747, 0xBF89, 0x9748, 0xBF8A,
+	0x9749, 0xBF8B, 0x974A, 0xBF8C, 0x974B, 0xBF8D, 0x974C, 0xBF8E,
+	0x974D, 0xBF8F, 0x974E, 0xBF90, 0x974F, 0xBF91, 0x9750, 0xBF92,
+	0x9751, 0xBF93, 0x9752, 0xBF95, 0x9753, 0xBF96, 0x9754, 0xBF97,
+	0x9755, 0xBF98, 0x9756, 0xBF99, 0x9757, 0xBF9A, 0x9758, 0xBF9B,
+	0x9759, 0xBF9C, 0x975A, 0xBF9D, 0x9761, 0xBF9E, 0x9762, 0xBF9F,
+	0x9763, 0xBFA0, 0x9764, 0xBFA1, 0x9765, 0xBFA2, 0x9766, 0xBFA3,
+	0x9767, 0xBFA4, 0x9768, 0xBFA5, 0x9769, 0xBFA6, 0x976A, 0xBFA7,
+	0x976B, 0xBFA8, 0x976C, 0xBFA9, 0x976D, 0xBFAA, 0x976E, 0xBFAB,
+	0x976F, 0xBFAC, 0x9770, 0xBFAD, 0x9771, 0xBFAE, 0x9772, 0xBFAF,
+	0x9773, 0xBFB1, 0x9774, 0xBFB2, 0x9775, 0xBFB3, 0x9776, 0xBFB4,
+	0x9777, 0xBFB5, 0x9778, 0xBFB6, 0x9779, 0xBFB7, 0x977A, 0xBFB8,
+	0x9781, 0xBFB9, 0x9782, 0xBFBA, 0x9783, 0xBFBB, 0x9784, 0xBFBC,
+	0x9785, 0xBFBD, 0x9786, 0xBFBE, 0x9787, 0xBFBF, 0x9788, 0xBFC0,
+	0x9789, 0xBFC1, 0x978A, 0xBFC2, 0x978B, 0xBFC3, 0x978C, 0xBFC4,
+	0x978D, 0xBFC6, 0x978E, 0xBFC7, 0x978F, 0xBFC8, 0x9790, 0xBFC9,
+	0x9791, 0xBFCA, 0x9792, 0xBFCB, 0x9793, 0xBFCE, 0x9794, 0xBFCF,
+	0x9795, 0xBFD1, 0x9796, 0xBFD2, 0x9797, 0xBFD3, 0x9798, 0xBFD5,
+	0x9799, 0xBFD6, 0x979A, 0xBFD7, 0x979B, 0xBFD8, 0x979C, 0xBFD9,
+	0x979D, 0xBFDA, 0x979E, 0xBFDB, 0x979F, 0xBFDD, 0x97A0, 0xBFDE,
+	0x97A1, 0xBFE0, 0x97A2, 0xBFE2, 0x97A3, 0xBFE3, 0x97A4, 0xBFE4,
+	0x97A5, 0xBFE5, 0x97A6, 0xBFE6, 0x97A7, 0xBFE7, 0x97A8, 0xBFE8,
+	0x97A9, 0xBFE9, 0x97AA, 0xBFEA, 0x97AB, 0xBFEB, 0x97AC, 0xBFEC,
+	0x97AD, 0xBFED, 0x97AE, 0xBFEE, 0x97AF, 0xBFEF, 0x97B0, 0xBFF0,
+	0x97B1, 0xBFF1, 0x97B2, 0xBFF2, 0x97B3, 0xBFF3, 0x97B4, 0xBFF4,
+	0x97B5, 0xBFF5, 0x97B6, 0xBFF6, 0x97B7, 0xBFF7, 0x97B8, 0xBFF8,
+	0x97B9, 0xBFF9, 0x97BA, 0xBFFA, 0x97BB, 0xBFFB, 0x97BC, 0xBFFC,
+	0x97BD, 0xBFFD, 0x97BE, 0xBFFE, 0x97BF, 0xBFFF, 0x97C0, 0xC000,
+	0x97C1, 0xC001, 0x97C2, 0xC002, 0x97C3, 0xC003, 0x97C4, 0xC004,
+	0x97C5, 0xC005, 0x97C6, 0xC006, 0x97C7, 0xC007, 0x97C8, 0xC008,
+	0x97C9, 0xC009, 0x97CA, 0xC00A, 0x97CB, 0xC00B, 0x97CC, 0xC00C,
+	0x97CD, 0xC00D, 0x97CE, 0xC00E, 0x97CF, 0xC00F, 0x97D0, 0xC010,
+	0x97D1, 0xC011, 0x97D2, 0xC012, 0x97D3, 0xC013, 0x97D4, 0xC014,
+	0x97D5, 0xC015, 0x97D6, 0xC016, 0x97D7, 0xC017, 0x97D8, 0xC018,
+	0x97D9, 0xC019, 0x97DA, 0xC01A, 0x97DB, 0xC01B, 0x97DC, 0xC01C,
+	0x97DD, 0xC01D, 0x97DE, 0xC01E, 0x97DF, 0xC01F, 0x97E0, 0xC020,
+	0x97E1, 0xC021, 0x97E2, 0xC022, 0x97E3, 0xC023, 0x97E4, 0xC024,
+	0x97E5, 0xC025, 0x97E6, 0xC026, 0x97E7, 0xC027, 0x97E8, 0xC028,
+	0x97E9, 0xC029, 0x97EA, 0xC02A, 0x97EB, 0xC02B, 0x97EC, 0xC02C,
+	0x97ED, 0xC02D, 0x97EE, 0xC02E, 0x97EF, 0xC02F, 0x97F0, 0xC030,
+	0x97F1, 0xC031, 0x97F2, 0xC032, 0x97F3, 0xC033, 0x97F4, 0xC034,
+	0x97F5, 0xC035, 0x97F6, 0xC036, 0x97F7, 0xC037, 0x97F8, 0xC038,
+	0x97F9, 0xC039, 0x97FA, 0xC03A, 0x97FB, 0xC03B, 0x97FC, 0xC03D,
+	0x97FD, 0xC03E, 0x97FE, 0xC03F, 0x9841, 0xC040, 0x9842, 0xC041,
+	0x9843, 0xC042, 0x9844, 0xC043, 0x9845, 0xC044, 0x9846, 0xC045,
+	0x9847, 0xC046, 0x9848, 0xC047, 0x9849, 0xC048, 0x984A, 0xC049,
+	0x984B, 0xC04A, 0x984C, 0xC04B, 0x984D, 0xC04C, 0x984E, 0xC04D,
+	0x984F, 0xC04E, 0x9850, 0xC04F, 0x9851, 0xC050, 0x9852, 0xC052,
+	0x9853, 0xC053, 0x9854, 0xC054, 0x9855, 0xC055, 0x9856, 0xC056,
+	0x9857, 0xC057, 0x9858, 0xC059, 0x9859, 0xC05A, 0x985A, 0xC05B,
+	0x9861, 0xC05D, 0x9862, 0xC05E, 0x9863, 0xC05F, 0x9864, 0xC061,
+	0x9865, 0xC062, 0x9866, 0xC063, 0x9867, 0xC064, 0x9868, 0xC065,
+	0x9869, 0xC066, 0x986A, 0xC067, 0x986B, 0xC06A, 0x986C, 0xC06B,
+	0x986D, 0xC06C, 0x986E, 0xC06D, 0x986F, 0xC06E, 0x9870, 0xC06F,
+	0x9871, 0xC070, 0x9872, 0xC071, 0x9873, 0xC072, 0x9874, 0xC073,
+	0x9875, 0xC074, 0x9876, 0xC075, 0x9877, 0xC076, 0x9878, 0xC077,
+	0x9879, 0xC078, 0x987A, 0xC079, 0x9881, 0xC07A, 0x9882, 0xC07B,
+	0x9883, 0xC07C, 0x9884, 0xC07D, 0x9885, 0xC07E, 0x9886, 0xC07F,
+	0x9887, 0xC080, 0x9888, 0xC081, 0x9889, 0xC082, 0x988A, 0xC083,
+	0x988B, 0xC084, 0x988C, 0xC085, 0x988D, 0xC086, 0x988E, 0xC087,
+	0x988F, 0xC088, 0x9890, 0xC089, 0x9891, 0xC08A, 0x9892, 0xC08B,
+	0x9893, 0xC08C, 0x9894, 0xC08D, 0x9895, 0xC08E, 0x9896, 0xC08F,
+	0x9897, 0xC092, 0x9898, 0xC093, 0x9899, 0xC095, 0x989A, 0xC096,
+	0x989B, 0xC097, 0x989C, 0xC099, 0x989D, 0xC09A, 0x989E, 0xC09B,
+	0x989F, 0xC09C, 0x98A0, 0xC09D, 0x98A1, 0xC09E, 0x98A2, 0xC09F,
+	0x98A3, 0xC0A2, 0x98A4, 0xC0A4, 0x98A5, 0xC0A6, 0x98A6, 0xC0A7,
+	0x98A7, 0xC0A8, 0x98A8, 0xC0A9, 0x98A9, 0xC0AA, 0x98AA, 0xC0AB,
+	0x98AB, 0xC0AE, 0x98AC, 0xC0B1, 0x98AD, 0xC0B2, 0x98AE, 0xC0B7,
+	0x98AF, 0xC0B8, 0x98B0, 0xC0B9, 0x98B1, 0xC0BA, 0x98B2, 0xC0BB,
+	0x98B3, 0xC0BE, 0x98B4, 0xC0C2, 0x98B5, 0xC0C3, 0x98B6, 0xC0C4,
+	0x98B7, 0xC0C6, 0x98B8, 0xC0C7, 0x98B9, 0xC0CA, 0x98BA, 0xC0CB,
+	0x98BB, 0xC0CD, 0x98BC, 0xC0CE, 0x98BD, 0xC0CF, 0x98BE, 0xC0D1,
+	0x98BF, 0xC0D2, 0x98C0, 0xC0D3, 0x98C1, 0xC0D4, 0x98C2, 0xC0D5,
+	0x98C3, 0xC0D6, 0x98C4, 0xC0D7, 0x98C5, 0xC0DA, 0x98C6, 0xC0DE,
+	0x98C7, 0xC0DF, 0x98C8, 0xC0E0, 0x98C9, 0xC0E1, 0x98CA, 0xC0E2,
+	0x98CB, 0xC0E3, 0x98CC, 0xC0E6, 0x98CD, 0xC0E7, 0x98CE, 0xC0E9,
+	0x98CF, 0xC0EA, 0x98D0, 0xC0EB, 0x98D1, 0xC0ED, 0x98D2, 0xC0EE,
+	0x98D3, 0xC0EF, 0x98D4, 0xC0F0, 0x98D5, 0xC0F1, 0x98D6, 0xC0F2,
+	0x98D7, 0xC0F3, 0x98D8, 0xC0F6, 0x98D9, 0xC0F8, 0x98DA, 0xC0FA,
+	0x98DB, 0xC0FB, 0x98DC, 0xC0FC, 0x98DD, 0xC0FD, 0x98DE, 0xC0FE,
+	0x98DF, 0xC0FF, 0x98E0, 0xC101, 0x98E1, 0xC102, 0x98E2, 0xC103,
+	0x98E3, 0xC105, 0x98E4, 0xC106, 0x98E5, 0xC107, 0x98E6, 0xC109,
+	0x98E7, 0xC10A, 0x98E8, 0xC10B, 0x98E9, 0xC10C, 0x98EA, 0xC10D,
+	0x98EB, 0xC10E, 0x98EC, 0xC10F, 0x98ED, 0xC111, 0x98EE, 0xC112,
+	0x98EF, 0xC113, 0x98F0, 0xC114, 0x98F1, 0xC116, 0x98F2, 0xC117,
+	0x98F3, 0xC118, 0x98F4, 0xC119, 0x98F5, 0xC11A, 0x98F6, 0xC11B,
+	0x98F7, 0xC121, 0x98F8, 0xC122, 0x98F9, 0xC125, 0x98FA, 0xC128,
+	0x98FB, 0xC129, 0x98FC, 0xC12A, 0x98FD, 0xC12B, 0x98FE, 0xC12E,
+	0x9941, 0xC132, 0x9942, 0xC133, 0x9943, 0xC134, 0x9944, 0xC135,
+	0x9945, 0xC137, 0x9946, 0xC13A, 0x9947, 0xC13B, 0x9948, 0xC13D,
+	0x9949, 0xC13E, 0x994A, 0xC13F, 0x994B, 0xC141, 0x994C, 0xC142,
+	0x994D, 0xC143, 0x994E, 0xC144, 0x994F, 0xC145, 0x9950, 0xC146,
+	0x9951, 0xC147, 0x9952, 0xC14A, 0x9953, 0xC14E, 0x9954, 0xC14F,
+	0x9955, 0xC150, 0x9956, 0xC151, 0x9957, 0xC152, 0x9958, 0xC153,
+	0x9959, 0xC156, 0x995A, 0xC157, 0x9961, 0xC159, 0x9962, 0xC15A,
+	0x9963, 0xC15B, 0x9964, 0xC15D, 0x9965, 0xC15E, 0x9966, 0xC15F,
+	0x9967, 0xC160, 0x9968, 0xC161, 0x9969, 0xC162, 0x996A, 0xC163,
+	0x996B, 0xC166, 0x996C, 0xC16A, 0x996D, 0xC16B, 0x996E, 0xC16C,
+	0x996F, 0xC16D, 0x9970, 0xC16E, 0x9971, 0xC16F, 0x9972, 0xC171,
+	0x9973, 0xC172, 0x9974, 0xC173, 0x9975, 0xC175, 0x9976, 0xC176,
+	0x9977, 0xC177, 0x9978, 0xC179, 0x9979, 0xC17A, 0x997A, 0xC17B,
+	0x9981, 0xC17C, 0x9982, 0xC17D, 0x9983, 0xC17E, 0x9984, 0xC17F,
+	0x9985, 0xC180, 0x9986, 0xC181, 0x9987, 0xC182, 0x9988, 0xC183,
+	0x9989, 0xC184, 0x998A, 0xC186, 0x998B, 0xC187, 0x998C, 0xC188,
+	0x998D, 0xC189, 0x998E, 0xC18A, 0x998F, 0xC18B, 0x9990, 0xC18F,
+	0x9991, 0xC191, 0x9992, 0xC192, 0x9993, 0xC193, 0x9994, 0xC195,
+	0x9995, 0xC197, 0x9996, 0xC198, 0x9997, 0xC199, 0x9998, 0xC19A,
+	0x9999, 0xC19B, 0x999A, 0xC19E, 0x999B, 0xC1A0, 0x999C, 0xC1A2,
+	0x999D, 0xC1A3, 0x999E, 0xC1A4, 0x999F, 0xC1A6, 0x99A0, 0xC1A7,
+	0x99A1, 0xC1AA, 0x99A2, 0xC1AB, 0x99A3, 0xC1AD, 0x99A4, 0xC1AE,
+	0x99A5, 0xC1AF, 0x99A6, 0xC1B1, 0x99A7, 0xC1B2, 0x99A8, 0xC1B3,
+	0x99A9, 0xC1B4, 0x99AA, 0xC1B5, 0x99AB, 0xC1B6, 0x99AC, 0xC1B7,
+	0x99AD, 0xC1B8, 0x99AE, 0xC1B9, 0x99AF, 0xC1BA, 0x99B0, 0xC1BB,
+	0x99B1, 0xC1BC, 0x99B2, 0xC1BE, 0x99B3, 0xC1BF, 0x99B4, 0xC1C0,
+	0x99B5, 0xC1C1, 0x99B6, 0xC1C2, 0x99B7, 0xC1C3, 0x99B8, 0xC1C5,
+	0x99B9, 0xC1C6, 0x99BA, 0xC1C7, 0x99BB, 0xC1C9, 0x99BC, 0xC1CA,
+	0x99BD, 0xC1CB, 0x99BE, 0xC1CD, 0x99BF, 0xC1CE, 0x99C0, 0xC1CF,
+	0x99C1, 0xC1D0, 0x99C2, 0xC1D1, 0x99C3, 0xC1D2, 0x99C4, 0xC1D3,
+	0x99C5, 0xC1D5, 0x99C6, 0xC1D6, 0x99C7, 0xC1D9, 0x99C8, 0xC1DA,
+	0x99C9, 0xC1DB, 0x99CA, 0xC1DC, 0x99CB, 0xC1DD, 0x99CC, 0xC1DE,
+	0x99CD, 0xC1DF, 0x99CE, 0xC1E1, 0x99CF, 0xC1E2, 0x99D0, 0xC1E3,
+	0x99D1, 0xC1E5, 0x99D2, 0xC1E6, 0x99D3, 0xC1E7, 0x99D4, 0xC1E9,
+	0x99D5, 0xC1EA, 0x99D6, 0xC1EB, 0x99D7, 0xC1EC, 0x99D8, 0xC1ED,
+	0x99D9, 0xC1EE, 0x99DA, 0xC1EF, 0x99DB, 0xC1F2, 0x99DC, 0xC1F4,
+	0x99DD, 0xC1F5, 0x99DE, 0xC1F6, 0x99DF, 0xC1F7, 0x99E0, 0xC1F8,
+	0x99E1, 0xC1F9, 0x99E2, 0xC1FA, 0x99E3, 0xC1FB, 0x99E4, 0xC1FE,
+	0x99E5, 0xC1FF, 0x99E6, 0xC201, 0x99E7, 0xC202, 0x99E8, 0xC203,
+	0x99E9, 0xC205, 0x99EA, 0xC206, 0x99EB, 0xC207, 0x99EC, 0xC208,
+	0x99ED, 0xC209, 0x99EE, 0xC20A, 0x99EF, 0xC20B, 0x99F0, 0xC20E,
+	0x99F1, 0xC210, 0x99F2, 0xC212, 0x99F3, 0xC213, 0x99F4, 0xC214,
+	0x99F5, 0xC215, 0x99F6, 0xC216, 0x99F7, 0xC217, 0x99F8, 0xC21A,
+	0x99F9, 0xC21B, 0x99FA, 0xC21D, 0x99FB, 0xC21E, 0x99FC, 0xC221,
+	0x99FD, 0xC222, 0x99FE, 0xC223, 0x9A41, 0xC224, 0x9A42, 0xC225,
+	0x9A43, 0xC226, 0x9A44, 0xC227, 0x9A45, 0xC22A, 0x9A46, 0xC22C,
+	0x9A47, 0xC22E, 0x9A48, 0xC230, 0x9A49, 0xC233, 0x9A4A, 0xC235,
+	0x9A4B, 0xC236, 0x9A4C, 0xC237, 0x9A4D, 0xC238, 0x9A4E, 0xC239,
+	0x9A4F, 0xC23A, 0x9A50, 0xC23B, 0x9A51, 0xC23C, 0x9A52, 0xC23D,
+	0x9A53, 0xC23E, 0x9A54, 0xC23F, 0x9A55, 0xC240, 0x9A56, 0xC241,
+	0x9A57, 0xC242, 0x9A58, 0xC243, 0x9A59, 0xC244, 0x9A5A, 0xC245,
+	0x9A61, 0xC246, 0x9A62, 0xC247, 0x9A63, 0xC249, 0x9A64, 0xC24A,
+	0x9A65, 0xC24B, 0x9A66, 0xC24C, 0x9A67, 0xC24D, 0x9A68, 0xC24E,
+	0x9A69, 0xC24F, 0x9A6A, 0xC252, 0x9A6B, 0xC253, 0x9A6C, 0xC255,
+	0x9A6D, 0xC256, 0x9A6E, 0xC257, 0x9A6F, 0xC259, 0x9A70, 0xC25A,
+	0x9A71, 0xC25B, 0x9A72, 0xC25C, 0x9A73, 0xC25D, 0x9A74, 0xC25E,
+	0x9A75, 0xC25F, 0x9A76, 0xC261, 0x9A77, 0xC262, 0x9A78, 0xC263,
+	0x9A79, 0xC264, 0x9A7A, 0xC266, 0x9A81, 0xC267, 0x9A82, 0xC268,
+	0x9A83, 0xC269, 0x9A84, 0xC26A, 0x9A85, 0xC26B, 0x9A86, 0xC26E,
+	0x9A87, 0xC26F, 0x9A88, 0xC271, 0x9A89, 0xC272, 0x9A8A, 0xC273,
+	0x9A8B, 0xC275, 0x9A8C, 0xC276, 0x9A8D, 0xC277, 0x9A8E, 0xC278,
+	0x9A8F, 0xC279, 0x9A90, 0xC27A, 0x9A91, 0xC27B, 0x9A92, 0xC27E,
+	0x9A93, 0xC280, 0x9A94, 0xC282, 0x9A95, 0xC283, 0x9A96, 0xC284,
+	0x9A97, 0xC285, 0x9A98, 0xC286, 0x9A99, 0xC287, 0x9A9A, 0xC28A,
+	0x9A9B, 0xC28B, 0x9A9C, 0xC28C, 0x9A9D, 0xC28D, 0x9A9E, 0xC28E,
+	0x9A9F, 0xC28F, 0x9AA0, 0xC291, 0x9AA1, 0xC292, 0x9AA2, 0xC293,
+	0x9AA3, 0xC294, 0x9AA4, 0xC295, 0x9AA5, 0xC296, 0x9AA6, 0xC297,
+	0x9AA7, 0xC299, 0x9AA8, 0xC29A, 0x9AA9, 0xC29C, 0x9AAA, 0xC29E,
+	0x9AAB, 0xC29F, 0x9AAC, 0xC2A0, 0x9AAD, 0xC2A1, 0x9AAE, 0xC2A2,
+	0x9AAF, 0xC2A3, 0x9AB0, 0xC2A6, 0x9AB1, 0xC2A7, 0x9AB2, 0xC2A9,
+	0x9AB3, 0xC2AA, 0x9AB4, 0xC2AB, 0x9AB5, 0xC2AE, 0x9AB6, 0xC2AF,
+	0x9AB7, 0xC2B0, 0x9AB8, 0xC2B1, 0x9AB9, 0xC2B2, 0x9ABA, 0xC2B3,
+	0x9ABB, 0xC2B6, 0x9ABC, 0xC2B8, 0x9ABD, 0xC2BA, 0x9ABE, 0xC2BB,
+	0x9ABF, 0xC2BC, 0x9AC0, 0xC2BD, 0x9AC1, 0xC2BE, 0x9AC2, 0xC2BF,
+	0x9AC3, 0xC2C0, 0x9AC4, 0xC2C1, 0x9AC5, 0xC2C2, 0x9AC6, 0xC2C3,
+	0x9AC7, 0xC2C4, 0x9AC8, 0xC2C5, 0x9AC9, 0xC2C6, 0x9ACA, 0xC2C7,
+	0x9ACB, 0xC2C8, 0x9ACC, 0xC2C9, 0x9ACD, 0xC2CA, 0x9ACE, 0xC2CB,
+	0x9ACF, 0xC2CC, 0x9AD0, 0xC2CD, 0x9AD1, 0xC2CE, 0x9AD2, 0xC2CF,
+	0x9AD3, 0xC2D0, 0x9AD4, 0xC2D1, 0x9AD5, 0xC2D2, 0x9AD6, 0xC2D3,
+	0x9AD7, 0xC2D4, 0x9AD8, 0xC2D5, 0x9AD9, 0xC2D6, 0x9ADA, 0xC2D7,
+	0x9ADB, 0xC2D8, 0x9ADC, 0xC2D9, 0x9ADD, 0xC2DA, 0x9ADE, 0xC2DB,
+	0x9ADF, 0xC2DE, 0x9AE0, 0xC2DF, 0x9AE1, 0xC2E1, 0x9AE2, 0xC2E2,
+	0x9AE3, 0xC2E5, 0x9AE4, 0xC2E6, 0x9AE5, 0xC2E7, 0x9AE6, 0xC2E8,
+	0x9AE7, 0xC2E9, 0x9AE8, 0xC2EA, 0x9AE9, 0xC2EE, 0x9AEA, 0xC2F0,
+	0x9AEB, 0xC2F2, 0x9AEC, 0xC2F3, 0x9AED, 0xC2F4, 0x9AEE, 0xC2F5,
+	0x9AEF, 0xC2F7, 0x9AF0, 0xC2FA, 0x9AF1, 0xC2FD, 0x9AF2, 0xC2FE,
+	0x9AF3, 0xC2FF, 0x9AF4, 0xC301, 0x9AF5, 0xC302, 0x9AF6, 0xC303,
+	0x9AF7, 0xC304, 0x9AF8, 0xC305, 0x9AF9, 0xC306, 0x9AFA, 0xC307,
+	0x9AFB, 0xC30A, 0x9AFC, 0xC30B, 0x9AFD, 0xC30E, 0x9AFE, 0xC30F,
+	0x9B41, 0xC310, 0x9B42, 0xC311, 0x9B43, 0xC312, 0x9B44, 0xC316,
+	0x9B45, 0xC317, 0x9B46, 0xC319, 0x9B47, 0xC31A, 0x9B48, 0xC31B,
+	0x9B49, 0xC31D, 0x9B4A, 0xC31E, 0x9B4B, 0xC31F, 0x9B4C, 0xC320,
+	0x9B4D, 0xC321, 0x9B4E, 0xC322, 0x9B4F, 0xC323, 0x9B50, 0xC326,
+	0x9B51, 0xC327, 0x9B52, 0xC32A, 0x9B53, 0xC32B, 0x9B54, 0xC32C,
+	0x9B55, 0xC32D, 0x9B56, 0xC32E, 0x9B57, 0xC32F, 0x9B58, 0xC330,
+	0x9B59, 0xC331, 0x9B5A, 0xC332, 0x9B61, 0xC333, 0x9B62, 0xC334,
+	0x9B63, 0xC335, 0x9B64, 0xC336, 0x9B65, 0xC337, 0x9B66, 0xC338,
+	0x9B67, 0xC339, 0x9B68, 0xC33A, 0x9B69, 0xC33B, 0x9B6A, 0xC33C,
+	0x9B6B, 0xC33D, 0x9B6C, 0xC33E, 0x9B6D, 0xC33F, 0x9B6E, 0xC340,
+	0x9B6F, 0xC341, 0x9B70, 0xC342, 0x9B71, 0xC343, 0x9B72, 0xC344,
+	0x9B73, 0xC346, 0x9B74, 0xC347, 0x9B75, 0xC348, 0x9B76, 0xC349,
+	0x9B77, 0xC34A, 0x9B78, 0xC34B, 0x9B79, 0xC34C, 0x9B7A, 0xC34D,
+	0x9B81, 0xC34E, 0x9B82, 0xC34F, 0x9B83, 0xC350, 0x9B84, 0xC351,
+	0x9B85, 0xC352, 0x9B86, 0xC353, 0x9B87, 0xC354, 0x9B88, 0xC355,
+	0x9B89, 0xC356, 0x9B8A, 0xC357, 0x9B8B, 0xC358, 0x9B8C, 0xC359,
+	0x9B8D, 0xC35A, 0x9B8E, 0xC35B, 0x9B8F, 0xC35C, 0x9B90, 0xC35D,
+	0x9B91, 0xC35E, 0x9B92, 0xC35F, 0x9B93, 0xC360, 0x9B94, 0xC361,
+	0x9B95, 0xC362, 0x9B96, 0xC363, 0x9B97, 0xC364, 0x9B98, 0xC365,
+	0x9B99, 0xC366, 0x9B9A, 0xC367, 0x9B9B, 0xC36A, 0x9B9C, 0xC36B,
+	0x9B9D, 0xC36D, 0x9B9E, 0xC36E, 0x9B9F, 0xC36F, 0x9BA0, 0xC371,
+	0x9BA1, 0xC373, 0x9BA2, 0xC374, 0x9BA3, 0xC375, 0x9BA4, 0xC376,
+	0x9BA5, 0xC377, 0x9BA6, 0xC37A, 0x9BA7, 0xC37B, 0x9BA8, 0xC37E,
+	0x9BA9, 0xC37F, 0x9BAA, 0xC380, 0x9BAB, 0xC381, 0x9BAC, 0xC382,
+	0x9BAD, 0xC383, 0x9BAE, 0xC385, 0x9BAF, 0xC386, 0x9BB0, 0xC387,
+	0x9BB1, 0xC389, 0x9BB2, 0xC38A, 0x9BB3, 0xC38B, 0x9BB4, 0xC38D,
+	0x9BB5, 0xC38E, 0x9BB6, 0xC38F, 0x9BB7, 0xC390, 0x9BB8, 0xC391,
+	0x9BB9, 0xC392, 0x9BBA, 0xC393, 0x9BBB, 0xC394, 0x9BBC, 0xC395,
+	0x9BBD, 0xC396, 0x9BBE, 0xC397, 0x9BBF, 0xC398, 0x9BC0, 0xC399,
+	0x9BC1, 0xC39A, 0x9BC2, 0xC39B, 0x9BC3, 0xC39C, 0x9BC4, 0xC39D,
+	0x9BC5, 0xC39E, 0x9BC6, 0xC39F, 0x9BC7, 0xC3A0, 0x9BC8, 0xC3A1,
+	0x9BC9, 0xC3A2, 0x9BCA, 0xC3A3, 0x9BCB, 0xC3A4, 0x9BCC, 0xC3A5,
+	0x9BCD, 0xC3A6, 0x9BCE, 0xC3A7, 0x9BCF, 0xC3A8, 0x9BD0, 0xC3A9,
+	0x9BD1, 0xC3AA, 0x9BD2, 0xC3AB, 0x9BD3, 0xC3AC, 0x9BD4, 0xC3AD,
+	0x9BD5, 0xC3AE, 0x9BD6, 0xC3AF, 0x9BD7, 0xC3B0, 0x9BD8, 0xC3B1,
+	0x9BD9, 0xC3B2, 0x9BDA, 0xC3B3, 0x9BDB, 0xC3B4, 0x9BDC, 0xC3B5,
+	0x9BDD, 0xC3B6, 0x9BDE, 0xC3B7, 0x9BDF, 0xC3B8, 0x9BE0, 0xC3B9,
+	0x9BE1, 0xC3BA, 0x9BE2, 0xC3BB, 0x9BE3, 0xC3BC, 0x9BE4, 0xC3BD,
+	0x9BE5, 0xC3BE, 0x9BE6, 0xC3BF, 0x9BE7, 0xC3C1, 0x9BE8, 0xC3C2,
+	0x9BE9, 0xC3C3, 0x9BEA, 0xC3C4, 0x9BEB, 0xC3C5, 0x9BEC, 0xC3C6,
+	0x9BED, 0xC3C7, 0x9BEE, 0xC3C8, 0x9BEF, 0xC3C9, 0x9BF0, 0xC3CA,
+	0x9BF1, 0xC3CB, 0x9BF2, 0xC3CC, 0x9BF3, 0xC3CD, 0x9BF4, 0xC3CE,
+	0x9BF5, 0xC3CF, 0x9BF6, 0xC3D0, 0x9BF7, 0xC3D1, 0x9BF8, 0xC3D2,
+	0x9BF9, 0xC3D3, 0x9BFA, 0xC3D4, 0x9BFB, 0xC3D5, 0x9BFC, 0xC3D6,
+	0x9BFD, 0xC3D7, 0x9BFE, 0xC3DA, 0x9C41, 0xC3DB, 0x9C42, 0xC3DD,
+	0x9C43, 0xC3DE, 0x9C44, 0xC3E1, 0x9C45, 0xC3E3, 0x9C46, 0xC3E4,
+	0x9C47, 0xC3E5, 0x9C48, 0xC3E6, 0x9C49, 0xC3E7, 0x9C4A, 0xC3EA,
+	0x9C4B, 0xC3EB, 0x9C4C, 0xC3EC, 0x9C4D, 0xC3EE, 0x9C4E, 0xC3EF,
+	0x9C4F, 0xC3F0, 0x9C50, 0xC3F1, 0x9C51, 0xC3F2, 0x9C52, 0xC3F3,
+	0x9C53, 0xC3F6, 0x9C54, 0xC3F7, 0x9C55, 0xC3F9, 0x9C56, 0xC3FA,
+	0x9C57, 0xC3FB, 0x9C58, 0xC3FC, 0x9C59, 0xC3FD, 0x9C5A, 0xC3FE,
+	0x9C61, 0xC3FF, 0x9C62, 0xC400, 0x9C63, 0xC401, 0x9C64, 0xC402,
+	0x9C65, 0xC403, 0x9C66, 0xC404, 0x9C67, 0xC405, 0x9C68, 0xC406,
+	0x9C69, 0xC407, 0x9C6A, 0xC409, 0x9C6B, 0xC40A, 0x9C6C, 0xC40B,
+	0x9C6D, 0xC40C, 0x9C6E, 0xC40D, 0x9C6F, 0xC40E, 0x9C70, 0xC40F,
+	0x9C71, 0xC411, 0x9C72, 0xC412, 0x9C73, 0xC413, 0x9C74, 0xC414,
+	0x9C75, 0xC415, 0x9C76, 0xC416, 0x9C77, 0xC417, 0x9C78, 0xC418,
+	0x9C79, 0xC419, 0x9C7A, 0xC41A, 0x9C81, 0xC41B, 0x9C82, 0xC41C,
+	0x9C83, 0xC41D, 0x9C84, 0xC41E, 0x9C85, 0xC41F, 0x9C86, 0xC420,
+	0x9C87, 0xC421, 0x9C88, 0xC422, 0x9C89, 0xC423, 0x9C8A, 0xC425,
+	0x9C8B, 0xC426, 0x9C8C, 0xC427, 0x9C8D, 0xC428, 0x9C8E, 0xC429,
+	0x9C8F, 0xC42A, 0x9C90, 0xC42B, 0x9C91, 0xC42D, 0x9C92, 0xC42E,
+	0x9C93, 0xC42F, 0x9C94, 0xC431, 0x9C95, 0xC432, 0x9C96, 0xC433,
+	0x9C97, 0xC435, 0x9C98, 0xC436, 0x9C99, 0xC437, 0x9C9A, 0xC438,
+	0x9C9B, 0xC439, 0x9C9C, 0xC43A, 0x9C9D, 0xC43B, 0x9C9E, 0xC43E,
+	0x9C9F, 0xC43F, 0x9CA0, 0xC440, 0x9CA1, 0xC441, 0x9CA2, 0xC442,
+	0x9CA3, 0xC443, 0x9CA4, 0xC444, 0x9CA5, 0xC445, 0x9CA6, 0xC446,
+	0x9CA7, 0xC447, 0x9CA8, 0xC449, 0x9CA9, 0xC44A, 0x9CAA, 0xC44B,
+	0x9CAB, 0xC44C, 0x9CAC, 0xC44D, 0x9CAD, 0xC44E, 0x9CAE, 0xC44F,
+	0x9CAF, 0xC450, 0x9CB0, 0xC451, 0x9CB1, 0xC452, 0x9CB2, 0xC453,
+	0x9CB3, 0xC454, 0x9CB4, 0xC455, 0x9CB5, 0xC456, 0x9CB6, 0xC457,
+	0x9CB7, 0xC458, 0x9CB8, 0xC459, 0x9CB9, 0xC45A, 0x9CBA, 0xC45B,
+	0x9CBB, 0xC45C, 0x9CBC, 0xC45D, 0x9CBD, 0xC45E, 0x9CBE, 0xC45F,
+	0x9CBF, 0xC460, 0x9CC0, 0xC461, 0x9CC1, 0xC462, 0x9CC2, 0xC463,
+	0x9CC3, 0xC466, 0x9CC4, 0xC467, 0x9CC5, 0xC469, 0x9CC6, 0xC46A,
+	0x9CC7, 0xC46B, 0x9CC8, 0xC46D, 0x9CC9, 0xC46E, 0x9CCA, 0xC46F,
+	0x9CCB, 0xC470, 0x9CCC, 0xC471, 0x9CCD, 0xC472, 0x9CCE, 0xC473,
+	0x9CCF, 0xC476, 0x9CD0, 0xC477, 0x9CD1, 0xC478, 0x9CD2, 0xC47A,
+	0x9CD3, 0xC47B, 0x9CD4, 0xC47C, 0x9CD5, 0xC47D, 0x9CD6, 0xC47E,
+	0x9CD7, 0xC47F, 0x9CD8, 0xC481, 0x9CD9, 0xC482, 0x9CDA, 0xC483,
+	0x9CDB, 0xC484, 0x9CDC, 0xC485, 0x9CDD, 0xC486, 0x9CDE, 0xC487,
+	0x9CDF, 0xC488, 0x9CE0, 0xC489, 0x9CE1, 0xC48A, 0x9CE2, 0xC48B,
+	0x9CE3, 0xC48C, 0x9CE4, 0xC48D, 0x9CE5, 0xC48E, 0x9CE6, 0xC48F,
+	0x9CE7, 0xC490, 0x9CE8, 0xC491, 0x9CE9, 0xC492, 0x9CEA, 0xC493,
+	0x9CEB, 0xC495, 0x9CEC, 0xC496, 0x9CED, 0xC497, 0x9CEE, 0xC498,
+	0x9CEF, 0xC499, 0x9CF0, 0xC49A, 0x9CF1, 0xC49B, 0x9CF2, 0xC49D,
+	0x9CF3, 0xC49E, 0x9CF4, 0xC49F, 0x9CF5, 0xC4A0, 0x9CF6, 0xC4A1,
+	0x9CF7, 0xC4A2, 0x9CF8, 0xC4A3, 0x9CF9, 0xC4A4, 0x9CFA, 0xC4A5,
+	0x9CFB, 0xC4A6, 0x9CFC, 0xC4A7, 0x9CFD, 0xC4A8, 0x9CFE, 0xC4A9,
+	0x9D41, 0xC4AA, 0x9D42, 0xC4AB, 0x9D43, 0xC4AC, 0x9D44, 0xC4AD,
+	0x9D45, 0xC4AE, 0x9D46, 0xC4AF, 0x9D47, 0xC4B0, 0x9D48, 0xC4B1,
+	0x9D49, 0xC4B2, 0x9D4A, 0xC4B3, 0x9D4B, 0xC4B4, 0x9D4C, 0xC4B5,
+	0x9D4D, 0xC4B6, 0x9D4E, 0xC4B7, 0x9D4F, 0xC4B9, 0x9D50, 0xC4BA,
+	0x9D51, 0xC4BB, 0x9D52, 0xC4BD, 0x9D53, 0xC4BE, 0x9D54, 0xC4BF,
+	0x9D55, 0xC4C0, 0x9D56, 0xC4C1, 0x9D57, 0xC4C2, 0x9D58, 0xC4C3,
+	0x9D59, 0xC4C4, 0x9D5A, 0xC4C5, 0x9D61, 0xC4C6, 0x9D62, 0xC4C7,
+	0x9D63, 0xC4C8, 0x9D64, 0xC4C9, 0x9D65, 0xC4CA, 0x9D66, 0xC4CB,
+	0x9D67, 0xC4CC, 0x9D68, 0xC4CD, 0x9D69, 0xC4CE, 0x9D6A, 0xC4CF,
+	0x9D6B, 0xC4D0, 0x9D6C, 0xC4D1, 0x9D6D, 0xC4D2, 0x9D6E, 0xC4D3,
+	0x9D6F, 0xC4D4, 0x9D70, 0xC4D5, 0x9D71, 0xC4D6, 0x9D72, 0xC4D7,
+	0x9D73, 0xC4D8, 0x9D74, 0xC4D9, 0x9D75, 0xC4DA, 0x9D76, 0xC4DB,
+	0x9D77, 0xC4DC, 0x9D78, 0xC4DD, 0x9D79, 0xC4DE, 0x9D7A, 0xC4DF,
+	0x9D81, 0xC4E0, 0x9D82, 0xC4E1, 0x9D83, 0xC4E2, 0x9D84, 0xC4E3,
+	0x9D85, 0xC4E4, 0x9D86, 0xC4E5, 0x9D87, 0xC4E6, 0x9D88, 0xC4E7,
+	0x9D89, 0xC4E8, 0x9D8A, 0xC4EA, 0x9D8B, 0xC4EB, 0x9D8C, 0xC4EC,
+	0x9D8D, 0xC4ED, 0x9D8E, 0xC4EE, 0x9D8F, 0xC4EF, 0x9D90, 0xC4F2,
+	0x9D91, 0xC4F3, 0x9D92, 0xC4F5, 0x9D93, 0xC4F6, 0x9D94, 0xC4F7,
+	0x9D95, 0xC4F9, 0x9D96, 0xC4FB, 0x9D97, 0xC4FC, 0x9D98, 0xC4FD,
+	0x9D99, 0xC4FE, 0x9D9A, 0xC502, 0x9D9B, 0xC503, 0x9D9C, 0xC504,
+	0x9D9D, 0xC505, 0x9D9E, 0xC506, 0x9D9F, 0xC507, 0x9DA0, 0xC508,
+	0x9DA1, 0xC509, 0x9DA2, 0xC50A, 0x9DA3, 0xC50B, 0x9DA4, 0xC50D,
+	0x9DA5, 0xC50E, 0x9DA6, 0xC50F, 0x9DA7, 0xC511, 0x9DA8, 0xC512,
+	0x9DA9, 0xC513, 0x9DAA, 0xC515, 0x9DAB, 0xC516, 0x9DAC, 0xC517,
+	0x9DAD, 0xC518, 0x9DAE, 0xC519, 0x9DAF, 0xC51A, 0x9DB0, 0xC51B,
+	0x9DB1, 0xC51D, 0x9DB2, 0xC51E, 0x9DB3, 0xC51F, 0x9DB4, 0xC520,
+	0x9DB5, 0xC521, 0x9DB6, 0xC522, 0x9DB7, 0xC523, 0x9DB8, 0xC524,
+	0x9DB9, 0xC525, 0x9DBA, 0xC526, 0x9DBB, 0xC527, 0x9DBC, 0xC52A,
+	0x9DBD, 0xC52B, 0x9DBE, 0xC52D, 0x9DBF, 0xC52E, 0x9DC0, 0xC52F,
+	0x9DC1, 0xC531, 0x9DC2, 0xC532, 0x9DC3, 0xC533, 0x9DC4, 0xC534,
+	0x9DC5, 0xC535, 0x9DC6, 0xC536, 0x9DC7, 0xC537, 0x9DC8, 0xC53A,
+	0x9DC9, 0xC53C, 0x9DCA, 0xC53E, 0x9DCB, 0xC53F, 0x9DCC, 0xC540,
+	0x9DCD, 0xC541, 0x9DCE, 0xC542, 0x9DCF, 0xC543, 0x9DD0, 0xC546,
+	0x9DD1, 0xC547, 0x9DD2, 0xC54B, 0x9DD3, 0xC54F, 0x9DD4, 0xC550,
+	0x9DD5, 0xC551, 0x9DD6, 0xC552, 0x9DD7, 0xC556, 0x9DD8, 0xC55A,
+	0x9DD9, 0xC55B, 0x9DDA, 0xC55C, 0x9DDB, 0xC55F, 0x9DDC, 0xC562,
+	0x9DDD, 0xC563, 0x9DDE, 0xC565, 0x9DDF, 0xC566, 0x9DE0, 0xC567,
+	0x9DE1, 0xC569, 0x9DE2, 0xC56A, 0x9DE3, 0xC56B, 0x9DE4, 0xC56C,
+	0x9DE5, 0xC56D, 0x9DE6, 0xC56E, 0x9DE7, 0xC56F, 0x9DE8, 0xC572,
+	0x9DE9, 0xC576, 0x9DEA, 0xC577, 0x9DEB, 0xC578, 0x9DEC, 0xC579,
+	0x9DED, 0xC57A, 0x9DEE, 0xC57B, 0x9DEF, 0xC57E, 0x9DF0, 0xC57F,
+	0x9DF1, 0xC581, 0x9DF2, 0xC582, 0x9DF3, 0xC583, 0x9DF4, 0xC585,
+	0x9DF5, 0xC586, 0x9DF6, 0xC588, 0x9DF7, 0xC589, 0x9DF8, 0xC58A,
+	0x9DF9, 0xC58B, 0x9DFA, 0xC58E, 0x9DFB, 0xC590, 0x9DFC, 0xC592,
+	0x9DFD, 0xC593, 0x9DFE, 0xC594, 0x9E41, 0xC596, 0x9E42, 0xC599,
+	0x9E43, 0xC59A, 0x9E44, 0xC59B, 0x9E45, 0xC59D, 0x9E46, 0xC59E,
+	0x9E47, 0xC59F, 0x9E48, 0xC5A1, 0x9E49, 0xC5A2, 0x9E4A, 0xC5A3,
+	0x9E4B, 0xC5A4, 0x9E4C, 0xC5A5, 0x9E4D, 0xC5A6, 0x9E4E, 0xC5A7,
+	0x9E4F, 0xC5A8, 0x9E50, 0xC5AA, 0x9E51, 0xC5AB, 0x9E52, 0xC5AC,
+	0x9E53, 0xC5AD, 0x9E54, 0xC5AE, 0x9E55, 0xC5AF, 0x9E56, 0xC5B0,
+	0x9E57, 0xC5B1, 0x9E58, 0xC5B2, 0x9E59, 0xC5B3, 0x9E5A, 0xC5B6,
+	0x9E61, 0xC5B7, 0x9E62, 0xC5BA, 0x9E63, 0xC5BF, 0x9E64, 0xC5C0,
+	0x9E65, 0xC5C1, 0x9E66, 0xC5C2, 0x9E67, 0xC5C3, 0x9E68, 0xC5CB,
+	0x9E69, 0xC5CD, 0x9E6A, 0xC5CF, 0x9E6B, 0xC5D2, 0x9E6C, 0xC5D3,
+	0x9E6D, 0xC5D5, 0x9E6E, 0xC5D6, 0x9E6F, 0xC5D7, 0x9E70, 0xC5D9,
+	0x9E71, 0xC5DA, 0x9E72, 0xC5DB, 0x9E73, 0xC5DC, 0x9E74, 0xC5DD,
+	0x9E75, 0xC5DE, 0x9E76, 0xC5DF, 0x9E77, 0xC5E2, 0x9E78, 0xC5E4,
+	0x9E79, 0xC5E6, 0x9E7A, 0xC5E7, 0x9E81, 0xC5E8, 0x9E82, 0xC5E9,
+	0x9E83, 0xC5EA, 0x9E84, 0xC5EB, 0x9E85, 0xC5EF, 0x9E86, 0xC5F1,
+	0x9E87, 0xC5F2, 0x9E88, 0xC5F3, 0x9E89, 0xC5F5, 0x9E8A, 0xC5F8,
+	0x9E8B, 0xC5F9, 0x9E8C, 0xC5FA, 0x9E8D, 0xC5FB, 0x9E8E, 0xC602,
+	0x9E8F, 0xC603, 0x9E90, 0xC604, 0x9E91, 0xC609, 0x9E92, 0xC60A,
+	0x9E93, 0xC60B, 0x9E94, 0xC60D, 0x9E95, 0xC60E, 0x9E96, 0xC60F,
+	0x9E97, 0xC611, 0x9E98, 0xC612, 0x9E99, 0xC613, 0x9E9A, 0xC614,
+	0x9E9B, 0xC615, 0x9E9C, 0xC616, 0x9E9D, 0xC617, 0x9E9E, 0xC61A,
+	0x9E9F, 0xC61D, 0x9EA0, 0xC61E, 0x9EA1, 0xC61F, 0x9EA2, 0xC620,
+	0x9EA3, 0xC621, 0x9EA4, 0xC622, 0x9EA5, 0xC623, 0x9EA6, 0xC626,
+	0x9EA7, 0xC627, 0x9EA8, 0xC629, 0x9EA9, 0xC62A, 0x9EAA, 0xC62B,
+	0x9EAB, 0xC62F, 0x9EAC, 0xC631, 0x9EAD, 0xC632, 0x9EAE, 0xC636,
+	0x9EAF, 0xC638, 0x9EB0, 0xC63A, 0x9EB1, 0xC63C, 0x9EB2, 0xC63D,
+	0x9EB3, 0xC63E, 0x9EB4, 0xC63F, 0x9EB5, 0xC642, 0x9EB6, 0xC643,
+	0x9EB7, 0xC645, 0x9EB8, 0xC646, 0x9EB9, 0xC647, 0x9EBA, 0xC649,
+	0x9EBB, 0xC64A, 0x9EBC, 0xC64B, 0x9EBD, 0xC64C, 0x9EBE, 0xC64D,
+	0x9EBF, 0xC64E, 0x9EC0, 0xC64F, 0x9EC1, 0xC652, 0x9EC2, 0xC656,
+	0x9EC3, 0xC657, 0x9EC4, 0xC658, 0x9EC5, 0xC659, 0x9EC6, 0xC65A,
+	0x9EC7, 0xC65B, 0x9EC8, 0xC65E, 0x9EC9, 0xC65F, 0x9ECA, 0xC661,
+	0x9ECB, 0xC662, 0x9ECC, 0xC663, 0x9ECD, 0xC664, 0x9ECE, 0xC665,
+	0x9ECF, 0xC666, 0x9ED0, 0xC667, 0x9ED1, 0xC668, 0x9ED2, 0xC669,
+	0x9ED3, 0xC66A, 0x9ED4, 0xC66B, 0x9ED5, 0xC66D, 0x9ED6, 0xC66E,
+	0x9ED7, 0xC670, 0x9ED8, 0xC672, 0x9ED9, 0xC673, 0x9EDA, 0xC674,
+	0x9EDB, 0xC675, 0x9EDC, 0xC676, 0x9EDD, 0xC677, 0x9EDE, 0xC67A,
+	0x9EDF, 0xC67B, 0x9EE0, 0xC67D, 0x9EE1, 0xC67E, 0x9EE2, 0xC67F,
+	0x9EE3, 0xC681, 0x9EE4, 0xC682, 0x9EE5, 0xC683, 0x9EE6, 0xC684,
+	0x9EE7, 0xC685, 0x9EE8, 0xC686, 0x9EE9, 0xC687, 0x9EEA, 0xC68A,
+	0x9EEB, 0xC68C, 0x9EEC, 0xC68E, 0x9EED, 0xC68F, 0x9EEE, 0xC690,
+	0x9EEF, 0xC691, 0x9EF0, 0xC692, 0x9EF1, 0xC693, 0x9EF2, 0xC696,
+	0x9EF3, 0xC697, 0x9EF4, 0xC699, 0x9EF5, 0xC69A, 0x9EF6, 0xC69B,
+	0x9EF7, 0xC69D, 0x9EF8, 0xC69E, 0x9EF9, 0xC69F, 0x9EFA, 0xC6A0,
+	0x9EFB, 0xC6A1, 0x9EFC, 0xC6A2, 0x9EFD, 0xC6A3, 0x9EFE, 0xC6A6,
+	0x9F41, 0xC6A8, 0x9F42, 0xC6AA, 0x9F43, 0xC6AB, 0x9F44, 0xC6AC,
+	0x9F45, 0xC6AD, 0x9F46, 0xC6AE, 0x9F47, 0xC6AF, 0x9F48, 0xC6B2,
+	0x9F49, 0xC6B3, 0x9F4A, 0xC6B5, 0x9F4B, 0xC6B6, 0x9F4C, 0xC6B7,
+	0x9F4D, 0xC6BB, 0x9F4E, 0xC6BC, 0x9F4F, 0xC6BD, 0x9F50, 0xC6BE,
+	0x9F51, 0xC6BF, 0x9F52, 0xC6C2, 0x9F53, 0xC6C4, 0x9F54, 0xC6C6,
+	0x9F55, 0xC6C7, 0x9F56, 0xC6C8, 0x9F57, 0xC6C9, 0x9F58, 0xC6CA,
+	0x9F59, 0xC6CB, 0x9F5A, 0xC6CE, 0x9F61, 0xC6CF, 0x9F62, 0xC6D1,
+	0x9F63, 0xC6D2, 0x9F64, 0xC6D3, 0x9F65, 0xC6D5, 0x9F66, 0xC6D6,
+	0x9F67, 0xC6D7, 0x9F68, 0xC6D8, 0x9F69, 0xC6D9, 0x9F6A, 0xC6DA,
+	0x9F6B, 0xC6DB, 0x9F6C, 0xC6DE, 0x9F6D, 0xC6DF, 0x9F6E, 0xC6E2,
+	0x9F6F, 0xC6E3, 0x9F70, 0xC6E4, 0x9F71, 0xC6E5, 0x9F72, 0xC6E6,
+	0x9F73, 0xC6E7, 0x9F74, 0xC6EA, 0x9F75, 0xC6EB, 0x9F76, 0xC6ED,
+	0x9F77, 0xC6EE, 0x9F78, 0xC6EF, 0x9F79, 0xC6F1, 0x9F7A, 0xC6F2,
+	0x9F81, 0xC6F3, 0x9F82, 0xC6F4, 0x9F83, 0xC6F5, 0x9F84, 0xC6F6,
+	0x9F85, 0xC6F7, 0x9F86, 0xC6FA, 0x9F87, 0xC6FB, 0x9F88, 0xC6FC,
+	0x9F89, 0xC6FE, 0x9F8A, 0xC6FF, 0x9F8B, 0xC700, 0x9F8C, 0xC701,
+	0x9F8D, 0xC702, 0x9F8E, 0xC703, 0x9F8F, 0xC706, 0x9F90, 0xC707,
+	0x9F91, 0xC709, 0x9F92, 0xC70A, 0x9F93, 0xC70B, 0x9F94, 0xC70D,
+	0x9F95, 0xC70E, 0x9F96, 0xC70F, 0x9F97, 0xC710, 0x9F98, 0xC711,
+	0x9F99, 0xC712, 0x9F9A, 0xC713, 0x9F9B, 0xC716, 0x9F9C, 0xC718,
+	0x9F9D, 0xC71A, 0x9F9E, 0xC71B, 0x9F9F, 0xC71C, 0x9FA0, 0xC71D,
+	0x9FA1, 0xC71E, 0x9FA2, 0xC71F, 0x9FA3, 0xC722, 0x9FA4, 0xC723,
+	0x9FA5, 0xC725, 0x9FA6, 0xC726, 0x9FA7, 0xC727, 0x9FA8, 0xC729,
+	0x9FA9, 0xC72A, 0x9FAA, 0xC72B, 0x9FAB, 0xC72C, 0x9FAC, 0xC72D,
+	0x9FAD, 0xC72E, 0x9FAE, 0xC72F, 0x9FAF, 0xC732, 0x9FB0, 0xC734,
+	0x9FB1, 0xC736, 0x9FB2, 0xC738, 0x9FB3, 0xC739, 0x9FB4, 0xC73A,
+	0x9FB5, 0xC73B, 0x9FB6, 0xC73E, 0x9FB7, 0xC73F, 0x9FB8, 0xC741,
+	0x9FB9, 0xC742, 0x9FBA, 0xC743, 0x9FBB, 0xC745, 0x9FBC, 0xC746,
+	0x9FBD, 0xC747, 0x9FBE, 0xC748, 0x9FBF, 0xC749, 0x9FC0, 0xC74B,
+	0x9FC1, 0xC74E, 0x9FC2, 0xC750, 0x9FC3, 0xC759, 0x9FC4, 0xC75A,
+	0x9FC5, 0xC75B, 0x9FC6, 0xC75D, 0x9FC7, 0xC75E, 0x9FC8, 0xC75F,
+	0x9FC9, 0xC761, 0x9FCA, 0xC762, 0x9FCB, 0xC763, 0x9FCC, 0xC764,
+	0x9FCD, 0xC765, 0x9FCE, 0xC766, 0x9FCF, 0xC767, 0x9FD0, 0xC769,
+	0x9FD1, 0xC76A, 0x9FD2, 0xC76C, 0x9FD3, 0xC76D, 0x9FD4, 0xC76E,
+	0x9FD5, 0xC76F, 0x9FD6, 0xC770, 0x9FD7, 0xC771, 0x9FD8, 0xC772,
+	0x9FD9, 0xC773, 0x9FDA, 0xC776, 0x9FDB, 0xC777, 0x9FDC, 0xC779,
+	0x9FDD, 0xC77A, 0x9FDE, 0xC77B, 0x9FDF, 0xC77F, 0x9FE0, 0xC780,
+	0x9FE1, 0xC781, 0x9FE2, 0xC782, 0x9FE3, 0xC786, 0x9FE4, 0xC78B,
+	0x9FE5, 0xC78C, 0x9FE6, 0xC78D, 0x9FE7, 0xC78F, 0x9FE8, 0xC792,
+	0x9FE9, 0xC793, 0x9FEA, 0xC795, 0x9FEB, 0xC799, 0x9FEC, 0xC79B,
+	0x9FED, 0xC79C, 0x9FEE, 0xC79D, 0x9FEF, 0xC79E, 0x9FF0, 0xC79F,
+	0x9FF1, 0xC7A2, 0x9FF2, 0xC7A7, 0x9FF3, 0xC7A8, 0x9FF4, 0xC7A9,
+	0x9FF5, 0xC7AA, 0x9FF6, 0xC7AB, 0x9FF7, 0xC7AE, 0x9FF8, 0xC7AF,
+	0x9FF9, 0xC7B1, 0x9FFA, 0xC7B2, 0x9FFB, 0xC7B3, 0x9FFC, 0xC7B5,
+	0x9FFD, 0xC7B6, 0x9FFE, 0xC7B7, 0xA041, 0xC7B8, 0xA042, 0xC7B9,
+	0xA043, 0xC7BA, 0xA044, 0xC7BB, 0xA045, 0xC7BE, 0xA046, 0xC7C2,
+	0xA047, 0xC7C3, 0xA048, 0xC7C4, 0xA049, 0xC7C5, 0xA04A, 0xC7C6,
+	0xA04B, 0xC7C7, 0xA04C, 0xC7CA, 0xA04D, 0xC7CB, 0xA04E, 0xC7CD,
+	0xA04F, 0xC7CF, 0xA050, 0xC7D1, 0xA051, 0xC7D2, 0xA052, 0xC7D3,
+	0xA053, 0xC7D4, 0xA054, 0xC7D5, 0xA055, 0xC7D6, 0xA056, 0xC7D7,
+	0xA057, 0xC7D9, 0xA058, 0xC7DA, 0xA059, 0xC7DB, 0xA05A, 0xC7DC,
+	0xA061, 0xC7DE, 0xA062, 0xC7DF, 0xA063, 0xC7E0, 0xA064, 0xC7E1,
+	0xA065, 0xC7E2, 0xA066, 0xC7E3, 0xA067, 0xC7E5, 0xA068, 0xC7E6,
+	0xA069, 0xC7E7, 0xA06A, 0xC7E9, 0xA06B, 0xC7EA, 0xA06C, 0xC7EB,
+	0xA06D, 0xC7ED, 0xA06E, 0xC7EE, 0xA06F, 0xC7EF, 0xA070, 0xC7F0,
+	0xA071, 0xC7F1, 0xA072, 0xC7F2, 0xA073, 0xC7F3, 0xA074, 0xC7F4,
+	0xA075, 0xC7F5, 0xA076, 0xC7F6, 0xA077, 0xC7F7, 0xA078, 0xC7F8,
+	0xA079, 0xC7F9, 0xA07A, 0xC7FA, 0xA081, 0xC7FB, 0xA082, 0xC7FC,
+	0xA083, 0xC7FD, 0xA084, 0xC7FE, 0xA085, 0xC7FF, 0xA086, 0xC802,
+	0xA087, 0xC803, 0xA088, 0xC805, 0xA089, 0xC806, 0xA08A, 0xC807,
+	0xA08B, 0xC809, 0xA08C, 0xC80B, 0xA08D, 0xC80C, 0xA08E, 0xC80D,
+	0xA08F, 0xC80E, 0xA090, 0xC80F, 0xA091, 0xC812, 0xA092, 0xC814,
+	0xA093, 0xC817, 0xA094, 0xC818, 0xA095, 0xC819, 0xA096, 0xC81A,
+	0xA097, 0xC81B, 0xA098, 0xC81E, 0xA099, 0xC81F, 0xA09A, 0xC821,
+	0xA09B, 0xC822, 0xA09C, 0xC823, 0xA09D, 0xC825, 0xA09E, 0xC826,
+	0xA09F, 0xC827, 0xA0A0, 0xC828, 0xA0A1, 0xC829, 0xA0A2, 0xC82A,
+	0xA0A3, 0xC82B, 0xA0A4, 0xC82E, 0xA0A5, 0xC830, 0xA0A6, 0xC832,
+	0xA0A7, 0xC833, 0xA0A8, 0xC834, 0xA0A9, 0xC835, 0xA0AA, 0xC836,
+	0xA0AB, 0xC837, 0xA0AC, 0xC839, 0xA0AD, 0xC83A, 0xA0AE, 0xC83B,
+	0xA0AF, 0xC83D, 0xA0B0, 0xC83E, 0xA0B1, 0xC83F, 0xA0B2, 0xC841,
+	0xA0B3, 0xC842, 0xA0B4, 0xC843, 0xA0B5, 0xC844, 0xA0B6, 0xC845,
+	0xA0B7, 0xC846, 0xA0B8, 0xC847, 0xA0B9, 0xC84A, 0xA0BA, 0xC84B,
+	0xA0BB, 0xC84E, 0xA0BC, 0xC84F, 0xA0BD, 0xC850, 0xA0BE, 0xC851,
+	0xA0BF, 0xC852, 0xA0C0, 0xC853, 0xA0C1, 0xC855, 0xA0C2, 0xC856,
+	0xA0C3, 0xC857, 0xA0C4, 0xC858, 0xA0C5, 0xC859, 0xA0C6, 0xC85A,
+	0xA0C7, 0xC85B, 0xA0C8, 0xC85C, 0xA0C9, 0xC85D, 0xA0CA, 0xC85E,
+	0xA0CB, 0xC85F, 0xA0CC, 0xC860, 0xA0CD, 0xC861, 0xA0CE, 0xC862,
+	0xA0CF, 0xC863, 0xA0D0, 0xC864, 0xA0D1, 0xC865, 0xA0D2, 0xC866,
+	0xA0D3, 0xC867, 0xA0D4, 0xC868, 0xA0D5, 0xC869, 0xA0D6, 0xC86A,
+	0xA0D7, 0xC86B, 0xA0D8, 0xC86C, 0xA0D9, 0xC86D, 0xA0DA, 0xC86E,
+	0xA0DB, 0xC86F, 0xA0DC, 0xC872, 0xA0DD, 0xC873, 0xA0DE, 0xC875,
+	0xA0DF, 0xC876, 0xA0E0, 0xC877, 0xA0E1, 0xC879, 0xA0E2, 0xC87B,
+	0xA0E3, 0xC87C, 0xA0E4, 0xC87D, 0xA0E5, 0xC87E, 0xA0E6, 0xC87F,
+	0xA0E7, 0xC882, 0xA0E8, 0xC884, 0xA0E9, 0xC888, 0xA0EA, 0xC889,
+	0xA0EB, 0xC88A, 0xA0EC, 0xC88E, 0xA0ED, 0xC88F, 0xA0EE, 0xC890,
+	0xA0EF, 0xC891, 0xA0F0, 0xC892, 0xA0F1, 0xC893, 0xA0F2, 0xC895,
+	0xA0F3, 0xC896, 0xA0F4, 0xC897, 0xA0F5, 0xC898, 0xA0F6, 0xC899,
+	0xA0F7, 0xC89A, 0xA0F8, 0xC89B, 0xA0F9, 0xC89C, 0xA0FA, 0xC89E,
+	0xA0FB, 0xC8A0, 0xA0FC, 0xC8A2, 0xA0FD, 0xC8A3, 0xA0FE, 0xC8A4,
+	0xA141, 0xC8A5, 0xA142, 0xC8A6, 0xA143, 0xC8A7, 0xA144, 0xC8A9,
+	0xA145, 0xC8AA, 0xA146, 0xC8AB, 0xA147, 0xC8AC, 0xA148, 0xC8AD,
+	0xA149, 0xC8AE, 0xA14A, 0xC8AF, 0xA14B, 0xC8B0, 0xA14C, 0xC8B1,
+	0xA14D, 0xC8B2, 0xA14E, 0xC8B3, 0xA14F, 0xC8B4, 0xA150, 0xC8B5,
+	0xA151, 0xC8B6, 0xA152, 0xC8B7, 0xA153, 0xC8B8, 0xA154, 0xC8B9,
+	0xA155, 0xC8BA, 0xA156, 0xC8BB, 0xA157, 0xC8BE, 0xA158, 0xC8BF,
+	0xA159, 0xC8C0, 0xA15A, 0xC8C1, 0xA161, 0xC8C2, 0xA162, 0xC8C3,
+	0xA163, 0xC8C5, 0xA164, 0xC8C6, 0xA165, 0xC8C7, 0xA166, 0xC8C9,
+	0xA167, 0xC8CA, 0xA168, 0xC8CB, 0xA169, 0xC8CD, 0xA16A, 0xC8CE,
+	0xA16B, 0xC8CF, 0xA16C, 0xC8D0, 0xA16D, 0xC8D1, 0xA16E, 0xC8D2,
+	0xA16F, 0xC8D3, 0xA170, 0xC8D6, 0xA171, 0xC8D8, 0xA172, 0xC8DA,
+	0xA173, 0xC8DB, 0xA174, 0xC8DC, 0xA175, 0xC8DD, 0xA176, 0xC8DE,
+	0xA177, 0xC8DF, 0xA178, 0xC8E2, 0xA179, 0xC8E3, 0xA17A, 0xC8E5,
+	0xA181, 0xC8E6, 0xA182, 0xC8E7, 0xA183, 0xC8E8, 0xA184, 0xC8E9,
+	0xA185, 0xC8EA, 0xA186, 0xC8EB, 0xA187, 0xC8EC, 0xA188, 0xC8ED,
+	0xA189, 0xC8EE, 0xA18A, 0xC8EF, 0xA18B, 0xC8F0, 0xA18C, 0xC8F1,
+	0xA18D, 0xC8F2, 0xA18E, 0xC8F3, 0xA18F, 0xC8F4, 0xA190, 0xC8F6,
+	0xA191, 0xC8F7, 0xA192, 0xC8F8, 0xA193, 0xC8F9, 0xA194, 0xC8FA,
+	0xA195, 0xC8FB, 0xA196, 0xC8FE, 0xA197, 0xC8FF, 0xA198, 0xC901,
+	0xA199, 0xC902, 0xA19A, 0xC903, 0xA19B, 0xC907, 0xA19C, 0xC908,
+	0xA19D, 0xC909, 0xA19E, 0xC90A, 0xA19F, 0xC90B, 0xA1A0, 0xC90E,
+	0xA1A1, 0x3000, 0xA1A2, 0x3001, 0xA1A3, 0x3002, 0xA1A4, 0x00B7,
+	0xA1A5, 0x2025, 0xA1A6, 0x2026, 0xA1A7, 0x00A8, 0xA1A8, 0x3003,
+	0xA1A9, 0x00AD, 0xA1AA, 0x2015, 0xA1AB, 0x2225, 0xA1AC, 0xFF3C,
+	0xA1AD, 0x223C, 0xA1AE, 0x2018, 0xA1AF, 0x2019, 0xA1B0, 0x201C,
+	0xA1B1, 0x201D, 0xA1B2, 0x3014, 0xA1B3, 0x3015, 0xA1B4, 0x3008,
+	0xA1B5, 0x3009, 0xA1B6, 0x300A, 0xA1B7, 0x300B, 0xA1B8, 0x300C,
+	0xA1B9, 0x300D, 0xA1BA, 0x300E, 0xA1BB, 0x300F, 0xA1BC, 0x3010,
+	0xA1BD, 0x3011, 0xA1BE, 0x00B1, 0xA1BF, 0x00D7, 0xA1C0, 0x00F7,
+	0xA1C1, 0x2260, 0xA1C2, 0x2264, 0xA1C3, 0x2265, 0xA1C4, 0x221E,
+	0xA1C5, 0x2234, 0xA1C6, 0x00B0, 0xA1C7, 0x2032, 0xA1C8, 0x2033,
+	0xA1C9, 0x2103, 0xA1CA, 0x212B, 0xA1CB, 0xFFE0, 0xA1CC, 0xFFE1,
+	0xA1CD, 0xFFE5, 0xA1CE, 0x2642, 0xA1CF, 0x2640, 0xA1D0, 0x2220,
+	0xA1D1, 0x22A5, 0xA1D2, 0x2312, 0xA1D3, 0x2202, 0xA1D4, 0x2207,
+	0xA1D5, 0x2261, 0xA1D6, 0x2252, 0xA1D7, 0x00A7, 0xA1D8, 0x203B,
+	0xA1D9, 0x2606, 0xA1DA, 0x2605, 0xA1DB, 0x25CB, 0xA1DC, 0x25CF,
+	0xA1DD, 0x25CE, 0xA1DE, 0x25C7, 0xA1DF, 0x25C6, 0xA1E0, 0x25A1,
+	0xA1E1, 0x25A0, 0xA1E2, 0x25B3, 0xA1E3, 0x25B2, 0xA1E4, 0x25BD,
+	0xA1E5, 0x25BC, 0xA1E6, 0x2192, 0xA1E7, 0x2190, 0xA1E8, 0x2191,
+	0xA1E9, 0x2193, 0xA1EA, 0x2194, 0xA1EB, 0x3013, 0xA1EC, 0x226A,
+	0xA1ED, 0x226B, 0xA1EE, 0x221A, 0xA1EF, 0x223D, 0xA1F0, 0x221D,
+	0xA1F1, 0x2235, 0xA1F2, 0x222B, 0xA1F3, 0x222C, 0xA1F4, 0x2208,
+	0xA1F5, 0x220B, 0xA1F6, 0x2286, 0xA1F7, 0x2287, 0xA1F8, 0x2282,
+	0xA1F9, 0x2283, 0xA1FA, 0x222A, 0xA1FB, 0x2229, 0xA1FC, 0x2227,
+	0xA1FD, 0x2228, 0xA1FE, 0xFFE2, 0xA241, 0xC910, 0xA242, 0xC912,
+	0xA243, 0xC913, 0xA244, 0xC914, 0xA245, 0xC915, 0xA246, 0xC916,
+	0xA247, 0xC917, 0xA248, 0xC919, 0xA249, 0xC91A, 0xA24A, 0xC91B,
+	0xA24B, 0xC91C, 0xA24C, 0xC91D, 0xA24D, 0xC91E, 0xA24E, 0xC91F,
+	0xA24F, 0xC920, 0xA250, 0xC921, 0xA251, 0xC922, 0xA252, 0xC923,
+	0xA253, 0xC924, 0xA254, 0xC925, 0xA255, 0xC926, 0xA256, 0xC927,
+	0xA257, 0xC928, 0xA258, 0xC929, 0xA259, 0xC92A, 0xA25A, 0xC92B,
+	0xA261, 0xC92D, 0xA262, 0xC92E, 0xA263, 0xC92F, 0xA264, 0xC930,
+	0xA265, 0xC931, 0xA266, 0xC932, 0xA267, 0xC933, 0xA268, 0xC935,
+	0xA269, 0xC936, 0xA26A, 0xC937, 0xA26B, 0xC938, 0xA26C, 0xC939,
+	0xA26D, 0xC93A, 0xA26E, 0xC93B, 0xA26F, 0xC93C, 0xA270, 0xC93D,
+	0xA271, 0xC93E, 0xA272, 0xC93F, 0xA273, 0xC940, 0xA274, 0xC941,
+	0xA275, 0xC942, 0xA276, 0xC943, 0xA277, 0xC944, 0xA278, 0xC945,
+	0xA279, 0xC946, 0xA27A, 0xC947, 0xA281, 0xC948, 0xA282, 0xC949,
+	0xA283, 0xC94A, 0xA284, 0xC94B, 0xA285, 0xC94C, 0xA286, 0xC94D,
+	0xA287, 0xC94E, 0xA288, 0xC94F, 0xA289, 0xC952, 0xA28A, 0xC953,
+	0xA28B, 0xC955, 0xA28C, 0xC956, 0xA28D, 0xC957, 0xA28E, 0xC959,
+	0xA28F, 0xC95A, 0xA290, 0xC95B, 0xA291, 0xC95C, 0xA292, 0xC95D,
+	0xA293, 0xC95E, 0xA294, 0xC95F, 0xA295, 0xC962, 0xA296, 0xC964,
+	0xA297, 0xC965, 0xA298, 0xC966, 0xA299, 0xC967, 0xA29A, 0xC968,
+	0xA29B, 0xC969, 0xA29C, 0xC96A, 0xA29D, 0xC96B, 0xA29E, 0xC96D,
+	0xA29F, 0xC96E, 0xA2A0, 0xC96F, 0xA2A1, 0x21D2, 0xA2A2, 0x21D4,
+	0xA2A3, 0x2200, 0xA2A4, 0x2203, 0xA2A5, 0x00B4, 0xA2A6, 0xFF5E,
+	0xA2A7, 0x02C7, 0xA2A8, 0x02D8, 0xA2A9, 0x02DD, 0xA2AA, 0x02DA,
+	0xA2AB, 0x02D9, 0xA2AC, 0x00B8, 0xA2AD, 0x02DB, 0xA2AE, 0x00A1,
+	0xA2AF, 0x00BF, 0xA2B0, 0x02D0, 0xA2B1, 0x222E, 0xA2B2, 0x2211,
+	0xA2B3, 0x220F, 0xA2B4, 0x00A4, 0xA2B5, 0x2109, 0xA2B6, 0x2030,
+	0xA2B7, 0x25C1, 0xA2B8, 0x25C0, 0xA2B9, 0x25B7, 0xA2BA, 0x25B6,
+	0xA2BB, 0x2664, 0xA2BC, 0x2660, 0xA2BD, 0x2661, 0xA2BE, 0x2665,
+	0xA2BF, 0x2667, 0xA2C0, 0x2663, 0xA2C1, 0x2299, 0xA2C2, 0x25C8,
+	0xA2C3, 0x25A3, 0xA2C4, 0x25D0, 0xA2C5, 0x25D1, 0xA2C6, 0x2592,
+	0xA2C7, 0x25A4, 0xA2C8, 0x25A5, 0xA2C9, 0x25A8, 0xA2CA, 0x25A7,
+	0xA2CB, 0x25A6, 0xA2CC, 0x25A9, 0xA2CD, 0x2668, 0xA2CE, 0x260F,
+	0xA2CF, 0x260E, 0xA2D0, 0x261C, 0xA2D1, 0x261E, 0xA2D2, 0x00B6,
+	0xA2D3, 0x2020, 0xA2D4, 0x2021, 0xA2D5, 0x2195, 0xA2D6, 0x2197,
+	0xA2D7, 0x2199, 0xA2D8, 0x2196, 0xA2D9, 0x2198, 0xA2DA, 0x266D,
+	0xA2DB, 0x2669, 0xA2DC, 0x266A, 0xA2DD, 0x266C, 0xA2DE, 0x327F,
+	0xA2DF, 0x321C, 0xA2E0, 0x2116, 0xA2E1, 0x33C7, 0xA2E2, 0x2122,
+	0xA2E3, 0x33C2, 0xA2E4, 0x33D8, 0xA2E5, 0x2121, 0xA2E6, 0x20AC,
+	0xA2E7, 0x00AE, 0xA341, 0xC971, 0xA342, 0xC972, 0xA343, 0xC973,
+	0xA344, 0xC975, 0xA345, 0xC976, 0xA346, 0xC977, 0xA347, 0xC978,
+	0xA348, 0xC979, 0xA349, 0xC97A, 0xA34A, 0xC97B, 0xA34B, 0xC97D,
+	0xA34C, 0xC97E, 0xA34D, 0xC97F, 0xA34E, 0xC980, 0xA34F, 0xC981,
+	0xA350, 0xC982, 0xA351, 0xC983, 0xA352, 0xC984, 0xA353, 0xC985,
+	0xA354, 0xC986, 0xA355, 0xC987, 0xA356, 0xC98A, 0xA357, 0xC98B,
+	0xA358, 0xC98D, 0xA359, 0xC98E, 0xA35A, 0xC98F, 0xA361, 0xC991,
+	0xA362, 0xC992, 0xA363, 0xC993, 0xA364, 0xC994, 0xA365, 0xC995,
+	0xA366, 0xC996, 0xA367, 0xC997, 0xA368, 0xC99A, 0xA369, 0xC99C,
+	0xA36A, 0xC99E, 0xA36B, 0xC99F, 0xA36C, 0xC9A0, 0xA36D, 0xC9A1,
+	0xA36E, 0xC9A2, 0xA36F, 0xC9A3, 0xA370, 0xC9A4, 0xA371, 0xC9A5,
+	0xA372, 0xC9A6, 0xA373, 0xC9A7, 0xA374, 0xC9A8, 0xA375, 0xC9A9,
+	0xA376, 0xC9AA, 0xA377, 0xC9AB, 0xA378, 0xC9AC, 0xA379, 0xC9AD,
+	0xA37A, 0xC9AE, 0xA381, 0xC9AF, 0xA382, 0xC9B0, 0xA383, 0xC9B1,
+	0xA384, 0xC9B2, 0xA385, 0xC9B3, 0xA386, 0xC9B4, 0xA387, 0xC9B5,
+	0xA388, 0xC9B6, 0xA389, 0xC9B7, 0xA38A, 0xC9B8, 0xA38B, 0xC9B9,
+	0xA38C, 0xC9BA, 0xA38D, 0xC9BB, 0xA38E, 0xC9BC, 0xA38F, 0xC9BD,
+	0xA390, 0xC9BE, 0xA391, 0xC9BF, 0xA392, 0xC9C2, 0xA393, 0xC9C3,
+	0xA394, 0xC9C5, 0xA395, 0xC9C6, 0xA396, 0xC9C9, 0xA397, 0xC9CB,
+	0xA398, 0xC9CC, 0xA399, 0xC9CD, 0xA39A, 0xC9CE, 0xA39B, 0xC9CF,
+	0xA39C, 0xC9D2, 0xA39D, 0xC9D4, 0xA39E, 0xC9D7, 0xA39F, 0xC9D8,
+	0xA3A0, 0xC9DB, 0xA3A1, 0xFF01, 0xA3A2, 0xFF02, 0xA3A3, 0xFF03,
+	0xA3A4, 0xFF04, 0xA3A5, 0xFF05, 0xA3A6, 0xFF06, 0xA3A7, 0xFF07,
+	0xA3A8, 0xFF08, 0xA3A9, 0xFF09, 0xA3AA, 0xFF0A, 0xA3AB, 0xFF0B,
+	0xA3AC, 0xFF0C, 0xA3AD, 0xFF0D, 0xA3AE, 0xFF0E, 0xA3AF, 0xFF0F,
+	0xA3B0, 0xFF10, 0xA3B1, 0xFF11, 0xA3B2, 0xFF12, 0xA3B3, 0xFF13,
+	0xA3B4, 0xFF14, 0xA3B5, 0xFF15, 0xA3B6, 0xFF16, 0xA3B7, 0xFF17,
+	0xA3B8, 0xFF18, 0xA3B9, 0xFF19, 0xA3BA, 0xFF1A, 0xA3BB, 0xFF1B,
+	0xA3BC, 0xFF1C, 0xA3BD, 0xFF1D, 0xA3BE, 0xFF1E, 0xA3BF, 0xFF1F,
+	0xA3C0, 0xFF20, 0xA3C1, 0xFF21, 0xA3C2, 0xFF22, 0xA3C3, 0xFF23,
+	0xA3C4, 0xFF24, 0xA3C5, 0xFF25, 0xA3C6, 0xFF26, 0xA3C7, 0xFF27,
+	0xA3C8, 0xFF28, 0xA3C9, 0xFF29, 0xA3CA, 0xFF2A, 0xA3CB, 0xFF2B,
+	0xA3CC, 0xFF2C, 0xA3CD, 0xFF2D, 0xA3CE, 0xFF2E, 0xA3CF, 0xFF2F,
+	0xA3D0, 0xFF30, 0xA3D1, 0xFF31, 0xA3D2, 0xFF32, 0xA3D3, 0xFF33,
+	0xA3D4, 0xFF34, 0xA3D5, 0xFF35, 0xA3D6, 0xFF36, 0xA3D7, 0xFF37,
+	0xA3D8, 0xFF38, 0xA3D9, 0xFF39, 0xA3DA, 0xFF3A, 0xA3DB, 0xFF3B,
+	0xA3DC, 0xFFE6, 0xA3DD, 0xFF3D, 0xA3DE, 0xFF3E, 0xA3DF, 0xFF3F,
+	0xA3E0, 0xFF40, 0xA3E1, 0xFF41, 0xA3E2, 0xFF42, 0xA3E3, 0xFF43,
+	0xA3E4, 0xFF44, 0xA3E5, 0xFF45, 0xA3E6, 0xFF46, 0xA3E7, 0xFF47,
+	0xA3E8, 0xFF48, 0xA3E9, 0xFF49, 0xA3EA, 0xFF4A, 0xA3EB, 0xFF4B,
+	0xA3EC, 0xFF4C, 0xA3ED, 0xFF4D, 0xA3EE, 0xFF4E, 0xA3EF, 0xFF4F,
+	0xA3F0, 0xFF50, 0xA3F1, 0xFF51, 0xA3F2, 0xFF52, 0xA3F3, 0xFF53,
+	0xA3F4, 0xFF54, 0xA3F5, 0xFF55, 0xA3F6, 0xFF56, 0xA3F7, 0xFF57,
+	0xA3F8, 0xFF58, 0xA3F9, 0xFF59, 0xA3FA, 0xFF5A, 0xA3FB, 0xFF5B,
+	0xA3FC, 0xFF5C, 0xA3FD, 0xFF5D, 0xA3FE, 0xFFE3, 0xA441, 0xC9DE,
+	0xA442, 0xC9DF, 0xA443, 0xC9E1, 0xA444, 0xC9E3, 0xA445, 0xC9E5,
+	0xA446, 0xC9E6, 0xA447, 0xC9E8, 0xA448, 0xC9E9, 0xA449, 0xC9EA,
+	0xA44A, 0xC9EB, 0xA44B, 0xC9EE, 0xA44C, 0xC9F2, 0xA44D, 0xC9F3,
+	0xA44E, 0xC9F4, 0xA44F, 0xC9F5, 0xA450, 0xC9F6, 0xA451, 0xC9F7,
+	0xA452, 0xC9FA, 0xA453, 0xC9FB, 0xA454, 0xC9FD, 0xA455, 0xC9FE,
+	0xA456, 0xC9FF, 0xA457, 0xCA01, 0xA458, 0xCA02, 0xA459, 0xCA03,
+	0xA45A, 0xCA04, 0xA461, 0xCA05, 0xA462, 0xCA06, 0xA463, 0xCA07,
+	0xA464, 0xCA0A, 0xA465, 0xCA0E, 0xA466, 0xCA0F, 0xA467, 0xCA10,
+	0xA468, 0xCA11, 0xA469, 0xCA12, 0xA46A, 0xCA13, 0xA46B, 0xCA15,
+	0xA46C, 0xCA16, 0xA46D, 0xCA17, 0xA46E, 0xCA19, 0xA46F, 0xCA1A,
+	0xA470, 0xCA1B, 0xA471, 0xCA1C, 0xA472, 0xCA1D, 0xA473, 0xCA1E,
+	0xA474, 0xCA1F, 0xA475, 0xCA20, 0xA476, 0xCA21, 0xA477, 0xCA22,
+	0xA478, 0xCA23, 0xA479, 0xCA24, 0xA47A, 0xCA25, 0xA481, 0xCA26,
+	0xA482, 0xCA27, 0xA483, 0xCA28, 0xA484, 0xCA2A, 0xA485, 0xCA2B,
+	0xA486, 0xCA2C, 0xA487, 0xCA2D, 0xA488, 0xCA2E, 0xA489, 0xCA2F,
+	0xA48A, 0xCA30, 0xA48B, 0xCA31, 0xA48C, 0xCA32, 0xA48D, 0xCA33,
+	0xA48E, 0xCA34, 0xA48F, 0xCA35, 0xA490, 0xCA36, 0xA491, 0xCA37,
+	0xA492, 0xCA38, 0xA493, 0xCA39, 0xA494, 0xCA3A, 0xA495, 0xCA3B,
+	0xA496, 0xCA3C, 0xA497, 0xCA3D, 0xA498, 0xCA3E, 0xA499, 0xCA3F,
+	0xA49A, 0xCA40, 0xA49B, 0xCA41, 0xA49C, 0xCA42, 0xA49D, 0xCA43,
+	0xA49E, 0xCA44, 0xA49F, 0xCA45, 0xA4A0, 0xCA46, 0xA4A1, 0x3131,
+	0xA4A2, 0x3132, 0xA4A3, 0x3133, 0xA4A4, 0x3134, 0xA4A5, 0x3135,
+	0xA4A6, 0x3136, 0xA4A7, 0x3137, 0xA4A8, 0x3138, 0xA4A9, 0x3139,
+	0xA4AA, 0x313A, 0xA4AB, 0x313B, 0xA4AC, 0x313C, 0xA4AD, 0x313D,
+	0xA4AE, 0x313E, 0xA4AF, 0x313F, 0xA4B0, 0x3140, 0xA4B1, 0x3141,
+	0xA4B2, 0x3142, 0xA4B3, 0x3143, 0xA4B4, 0x3144, 0xA4B5, 0x3145,
+	0xA4B6, 0x3146, 0xA4B7, 0x3147, 0xA4B8, 0x3148, 0xA4B9, 0x3149,
+	0xA4BA, 0x314A, 0xA4BB, 0x314B, 0xA4BC, 0x314C, 0xA4BD, 0x314D,
+	0xA4BE, 0x314E, 0xA4BF, 0x314F, 0xA4C0, 0x3150, 0xA4C1, 0x3151,
+	0xA4C2, 0x3152, 0xA4C3, 0x3153, 0xA4C4, 0x3154, 0xA4C5, 0x3155,
+	0xA4C6, 0x3156, 0xA4C7, 0x3157, 0xA4C8, 0x3158, 0xA4C9, 0x3159,
+	0xA4CA, 0x315A, 0xA4CB, 0x315B, 0xA4CC, 0x315C, 0xA4CD, 0x315D,
+	0xA4CE, 0x315E, 0xA4CF, 0x315F, 0xA4D0, 0x3160, 0xA4D1, 0x3161,
+	0xA4D2, 0x3162, 0xA4D3, 0x3163, 0xA4D4, 0x3164, 0xA4D5, 0x3165,
+	0xA4D6, 0x3166, 0xA4D7, 0x3167, 0xA4D8, 0x3168, 0xA4D9, 0x3169,
+	0xA4DA, 0x316A, 0xA4DB, 0x316B, 0xA4DC, 0x316C, 0xA4DD, 0x316D,
+	0xA4DE, 0x316E, 0xA4DF, 0x316F, 0xA4E0, 0x3170, 0xA4E1, 0x3171,
+	0xA4E2, 0x3172, 0xA4E3, 0x3173, 0xA4E4, 0x3174, 0xA4E5, 0x3175,
+	0xA4E6, 0x3176, 0xA4E7, 0x3177, 0xA4E8, 0x3178, 0xA4E9, 0x3179,
+	0xA4EA, 0x317A, 0xA4EB, 0x317B, 0xA4EC, 0x317C, 0xA4ED, 0x317D,
+	0xA4EE, 0x317E, 0xA4EF, 0x317F, 0xA4F0, 0x3180, 0xA4F1, 0x3181,
+	0xA4F2, 0x3182, 0xA4F3, 0x3183, 0xA4F4, 0x3184, 0xA4F5, 0x3185,
+	0xA4F6, 0x3186, 0xA4F7, 0x3187, 0xA4F8, 0x3188, 0xA4F9, 0x3189,
+	0xA4FA, 0x318A, 0xA4FB, 0x318B, 0xA4FC, 0x318C, 0xA4FD, 0x318D,
+	0xA4FE, 0x318E, 0xA541, 0xCA47, 0xA542, 0xCA48, 0xA543, 0xCA49,
+	0xA544, 0xCA4A, 0xA545, 0xCA4B, 0xA546, 0xCA4E, 0xA547, 0xCA4F,
+	0xA548, 0xCA51, 0xA549, 0xCA52, 0xA54A, 0xCA53, 0xA54B, 0xCA55,
+	0xA54C, 0xCA56, 0xA54D, 0xCA57, 0xA54E, 0xCA58, 0xA54F, 0xCA59,
+	0xA550, 0xCA5A, 0xA551, 0xCA5B, 0xA552, 0xCA5E, 0xA553, 0xCA62,
+	0xA554, 0xCA63, 0xA555, 0xCA64, 0xA556, 0xCA65, 0xA557, 0xCA66,
+	0xA558, 0xCA67, 0xA559, 0xCA69, 0xA55A, 0xCA6A, 0xA561, 0xCA6B,
+	0xA562, 0xCA6C, 0xA563, 0xCA6D, 0xA564, 0xCA6E, 0xA565, 0xCA6F,
+	0xA566, 0xCA70, 0xA567, 0xCA71, 0xA568, 0xCA72, 0xA569, 0xCA73,
+	0xA56A, 0xCA74, 0xA56B, 0xCA75, 0xA56C, 0xCA76, 0xA56D, 0xCA77,
+	0xA56E, 0xCA78, 0xA56F, 0xCA79, 0xA570, 0xCA7A, 0xA571, 0xCA7B,
+	0xA572, 0xCA7C, 0xA573, 0xCA7E, 0xA574, 0xCA7F, 0xA575, 0xCA80,
+	0xA576, 0xCA81, 0xA577, 0xCA82, 0xA578, 0xCA83, 0xA579, 0xCA85,
+	0xA57A, 0xCA86, 0xA581, 0xCA87, 0xA582, 0xCA88, 0xA583, 0xCA89,
+	0xA584, 0xCA8A, 0xA585, 0xCA8B, 0xA586, 0xCA8C, 0xA587, 0xCA8D,
+	0xA588, 0xCA8E, 0xA589, 0xCA8F, 0xA58A, 0xCA90, 0xA58B, 0xCA91,
+	0xA58C, 0xCA92, 0xA58D, 0xCA93, 0xA58E, 0xCA94, 0xA58F, 0xCA95,
+	0xA590, 0xCA96, 0xA591, 0xCA97, 0xA592, 0xCA99, 0xA593, 0xCA9A,
+	0xA594, 0xCA9B, 0xA595, 0xCA9C, 0xA596, 0xCA9D, 0xA597, 0xCA9E,
+	0xA598, 0xCA9F, 0xA599, 0xCAA0, 0xA59A, 0xCAA1, 0xA59B, 0xCAA2,
+	0xA59C, 0xCAA3, 0xA59D, 0xCAA4, 0xA59E, 0xCAA5, 0xA59F, 0xCAA6,
+	0xA5A0, 0xCAA7, 0xA5A1, 0x2170, 0xA5A2, 0x2171, 0xA5A3, 0x2172,
+	0xA5A4, 0x2173, 0xA5A5, 0x2174, 0xA5A6, 0x2175, 0xA5A7, 0x2176,
+	0xA5A8, 0x2177, 0xA5A9, 0x2178, 0xA5AA, 0x2179, 0xA5B0, 0x2160,
+	0xA5B1, 0x2161, 0xA5B2, 0x2162, 0xA5B3, 0x2163, 0xA5B4, 0x2164,
+	0xA5B5, 0x2165, 0xA5B6, 0x2166, 0xA5B7, 0x2167, 0xA5B8, 0x2168,
+	0xA5B9, 0x2169, 0xA5C1, 0x0391, 0xA5C2, 0x0392, 0xA5C3, 0x0393,
+	0xA5C4, 0x0394, 0xA5C5, 0x0395, 0xA5C6, 0x0396, 0xA5C7, 0x0397,
+	0xA5C8, 0x0398, 0xA5C9, 0x0399, 0xA5CA, 0x039A, 0xA5CB, 0x039B,
+	0xA5CC, 0x039C, 0xA5CD, 0x039D, 0xA5CE, 0x039E, 0xA5CF, 0x039F,
+	0xA5D0, 0x03A0, 0xA5D1, 0x03A1, 0xA5D2, 0x03A3, 0xA5D3, 0x03A4,
+	0xA5D4, 0x03A5, 0xA5D5, 0x03A6, 0xA5D6, 0x03A7, 0xA5D7, 0x03A8,
+	0xA5D8, 0x03A9, 0xA5E1, 0x03B1, 0xA5E2, 0x03B2, 0xA5E3, 0x03B3,
+	0xA5E4, 0x03B4, 0xA5E5, 0x03B5, 0xA5E6, 0x03B6, 0xA5E7, 0x03B7,
+	0xA5E8, 0x03B8, 0xA5E9, 0x03B9, 0xA5EA, 0x03BA, 0xA5EB, 0x03BB,
+	0xA5EC, 0x03BC, 0xA5ED, 0x03BD, 0xA5EE, 0x03BE, 0xA5EF, 0x03BF,
+	0xA5F0, 0x03C0, 0xA5F1, 0x03C1, 0xA5F2, 0x03C3, 0xA5F3, 0x03C4,
+	0xA5F4, 0x03C5, 0xA5F5, 0x03C6, 0xA5F6, 0x03C7, 0xA5F7, 0x03C8,
+	0xA5F8, 0x03C9, 0xA641, 0xCAA8, 0xA642, 0xCAA9, 0xA643, 0xCAAA,
+	0xA644, 0xCAAB, 0xA645, 0xCAAC, 0xA646, 0xCAAD, 0xA647, 0xCAAE,
+	0xA648, 0xCAAF, 0xA649, 0xCAB0, 0xA64A, 0xCAB1, 0xA64B, 0xCAB2,
+	0xA64C, 0xCAB3, 0xA64D, 0xCAB4, 0xA64E, 0xCAB5, 0xA64F, 0xCAB6,
+	0xA650, 0xCAB7, 0xA651, 0xCAB8, 0xA652, 0xCAB9, 0xA653, 0xCABA,
+	0xA654, 0xCABB, 0xA655, 0xCABE, 0xA656, 0xCABF, 0xA657, 0xCAC1,
+	0xA658, 0xCAC2, 0xA659, 0xCAC3, 0xA65A, 0xCAC5, 0xA661, 0xCAC6,
+	0xA662, 0xCAC7, 0xA663, 0xCAC8, 0xA664, 0xCAC9, 0xA665, 0xCACA,
+	0xA666, 0xCACB, 0xA667, 0xCACE, 0xA668, 0xCAD0, 0xA669, 0xCAD2,
+	0xA66A, 0xCAD4, 0xA66B, 0xCAD5, 0xA66C, 0xCAD6, 0xA66D, 0xCAD7,
+	0xA66E, 0xCADA, 0xA66F, 0xCADB, 0xA670, 0xCADC, 0xA671, 0xCADD,
+	0xA672, 0xCADE, 0xA673, 0xCADF, 0xA674, 0xCAE1, 0xA675, 0xCAE2,
+	0xA676, 0xCAE3, 0xA677, 0xCAE4, 0xA678, 0xCAE5, 0xA679, 0xCAE6,
+	0xA67A, 0xCAE7, 0xA681, 0xCAE8, 0xA682, 0xCAE9, 0xA683, 0xCAEA,
+	0xA684, 0xCAEB, 0xA685, 0xCAED, 0xA686, 0xCAEE, 0xA687, 0xCAEF,
+	0xA688, 0xCAF0, 0xA689, 0xCAF1, 0xA68A, 0xCAF2, 0xA68B, 0xCAF3,
+	0xA68C, 0xCAF5, 0xA68D, 0xCAF6, 0xA68E, 0xCAF7, 0xA68F, 0xCAF8,
+	0xA690, 0xCAF9, 0xA691, 0xCAFA, 0xA692, 0xCAFB, 0xA693, 0xCAFC,
+	0xA694, 0xCAFD, 0xA695, 0xCAFE, 0xA696, 0xCAFF, 0xA697, 0xCB00,
+	0xA698, 0xCB01, 0xA699, 0xCB02, 0xA69A, 0xCB03, 0xA69B, 0xCB04,
+	0xA69C, 0xCB05, 0xA69D, 0xCB06, 0xA69E, 0xCB07, 0xA69F, 0xCB09,
+	0xA6A0, 0xCB0A, 0xA6A1, 0x2500, 0xA6A2, 0x2502, 0xA6A3, 0x250C,
+	0xA6A4, 0x2510, 0xA6A5, 0x2518, 0xA6A6, 0x2514, 0xA6A7, 0x251C,
+	0xA6A8, 0x252C, 0xA6A9, 0x2524, 0xA6AA, 0x2534, 0xA6AB, 0x253C,
+	0xA6AC, 0x2501, 0xA6AD, 0x2503, 0xA6AE, 0x250F, 0xA6AF, 0x2513,
+	0xA6B0, 0x251B, 0xA6B1, 0x2517, 0xA6B2, 0x2523, 0xA6B3, 0x2533,
+	0xA6B4, 0x252B, 0xA6B5, 0x253B, 0xA6B6, 0x254B, 0xA6B7, 0x2520,
+	0xA6B8, 0x252F, 0xA6B9, 0x2528, 0xA6BA, 0x2537, 0xA6BB, 0x253F,
+	0xA6BC, 0x251D, 0xA6BD, 0x2530, 0xA6BE, 0x2525, 0xA6BF, 0x2538,
+	0xA6C0, 0x2542, 0xA6C1, 0x2512, 0xA6C2, 0x2511, 0xA6C3, 0x251A,
+	0xA6C4, 0x2519, 0xA6C5, 0x2516, 0xA6C6, 0x2515, 0xA6C7, 0x250E,
+	0xA6C8, 0x250D, 0xA6C9, 0x251E, 0xA6CA, 0x251F, 0xA6CB, 0x2521,
+	0xA6CC, 0x2522, 0xA6CD, 0x2526, 0xA6CE, 0x2527, 0xA6CF, 0x2529,
+	0xA6D0, 0x252A, 0xA6D1, 0x252D, 0xA6D2, 0x252E, 0xA6D3, 0x2531,
+	0xA6D4, 0x2532, 0xA6D5, 0x2535, 0xA6D6, 0x2536, 0xA6D7, 0x2539,
+	0xA6D8, 0x253A, 0xA6D9, 0x253D, 0xA6DA, 0x253E, 0xA6DB, 0x2540,
+	0xA6DC, 0x2541, 0xA6DD, 0x2543, 0xA6DE, 0x2544, 0xA6DF, 0x2545,
+	0xA6E0, 0x2546, 0xA6E1, 0x2547, 0xA6E2, 0x2548, 0xA6E3, 0x2549,
+	0xA6E4, 0x254A, 0xA741, 0xCB0B, 0xA742, 0xCB0C, 0xA743, 0xCB0D,
+	0xA744, 0xCB0E, 0xA745, 0xCB0F, 0xA746, 0xCB11, 0xA747, 0xCB12,
+	0xA748, 0xCB13, 0xA749, 0xCB15, 0xA74A, 0xCB16, 0xA74B, 0xCB17,
+	0xA74C, 0xCB19, 0xA74D, 0xCB1A, 0xA74E, 0xCB1B, 0xA74F, 0xCB1C,
+	0xA750, 0xCB1D, 0xA751, 0xCB1E, 0xA752, 0xCB1F, 0xA753, 0xCB22,
+	0xA754, 0xCB23, 0xA755, 0xCB24, 0xA756, 0xCB25, 0xA757, 0xCB26,
+	0xA758, 0xCB27, 0xA759, 0xCB28, 0xA75A, 0xCB29, 0xA761, 0xCB2A,
+	0xA762, 0xCB2B, 0xA763, 0xCB2C, 0xA764, 0xCB2D, 0xA765, 0xCB2E,
+	0xA766, 0xCB2F, 0xA767, 0xCB30, 0xA768, 0xCB31, 0xA769, 0xCB32,
+	0xA76A, 0xCB33, 0xA76B, 0xCB34, 0xA76C, 0xCB35, 0xA76D, 0xCB36,
+	0xA76E, 0xCB37, 0xA76F, 0xCB38, 0xA770, 0xCB39, 0xA771, 0xCB3A,
+	0xA772, 0xCB3B, 0xA773, 0xCB3C, 0xA774, 0xCB3D, 0xA775, 0xCB3E,
+	0xA776, 0xCB3F, 0xA777, 0xCB40, 0xA778, 0xCB42, 0xA779, 0xCB43,
+	0xA77A, 0xCB44, 0xA781, 0xCB45, 0xA782, 0xCB46, 0xA783, 0xCB47,
+	0xA784, 0xCB4A, 0xA785, 0xCB4B, 0xA786, 0xCB4D, 0xA787, 0xCB4E,
+	0xA788, 0xCB4F, 0xA789, 0xCB51, 0xA78A, 0xCB52, 0xA78B, 0xCB53,
+	0xA78C, 0xCB54, 0xA78D, 0xCB55, 0xA78E, 0xCB56, 0xA78F, 0xCB57,
+	0xA790, 0xCB5A, 0xA791, 0xCB5B, 0xA792, 0xCB5C, 0xA793, 0xCB5E,
+	0xA794, 0xCB5F, 0xA795, 0xCB60, 0xA796, 0xCB61, 0xA797, 0xCB62,
+	0xA798, 0xCB63, 0xA799, 0xCB65, 0xA79A, 0xCB66, 0xA79B, 0xCB67,
+	0xA79C, 0xCB68, 0xA79D, 0xCB69, 0xA79E, 0xCB6A, 0xA79F, 0xCB6B,
+	0xA7A0, 0xCB6C, 0xA7A1, 0x3395, 0xA7A2, 0x3396, 0xA7A3, 0x3397,
+	0xA7A4, 0x2113, 0xA7A5, 0x3398, 0xA7A6, 0x33C4, 0xA7A7, 0x33A3,
+	0xA7A8, 0x33A4, 0xA7A9, 0x33A5, 0xA7AA, 0x33A6, 0xA7AB, 0x3399,
+	0xA7AC, 0x339A, 0xA7AD, 0x339B, 0xA7AE, 0x339C, 0xA7AF, 0x339D,
+	0xA7B0, 0x339E, 0xA7B1, 0x339F, 0xA7B2, 0x33A0, 0xA7B3, 0x33A1,
+	0xA7B4, 0x33A2, 0xA7B5, 0x33CA, 0xA7B6, 0x338D, 0xA7B7, 0x338E,
+	0xA7B8, 0x338F, 0xA7B9, 0x33CF, 0xA7BA, 0x3388, 0xA7BB, 0x3389,
+	0xA7BC, 0x33C8, 0xA7BD, 0x33A7, 0xA7BE, 0x33A8, 0xA7BF, 0x33B0,
+	0xA7C0, 0x33B1, 0xA7C1, 0x33B2, 0xA7C2, 0x33B3, 0xA7C3, 0x33B4,
+	0xA7C4, 0x33B5, 0xA7C5, 0x33B6, 0xA7C6, 0x33B7, 0xA7C7, 0x33B8,
+	0xA7C8, 0x33B9, 0xA7C9, 0x3380, 0xA7CA, 0x3381, 0xA7CB, 0x3382,
+	0xA7CC, 0x3383, 0xA7CD, 0x3384, 0xA7CE, 0x33BA, 0xA7CF, 0x33BB,
+	0xA7D0, 0x33BC, 0xA7D1, 0x33BD, 0xA7D2, 0x33BE, 0xA7D3, 0x33BF,
+	0xA7D4, 0x3390, 0xA7D5, 0x3391, 0xA7D6, 0x3392, 0xA7D7, 0x3393,
+	0xA7D8, 0x3394, 0xA7D9, 0x2126, 0xA7DA, 0x33C0, 0xA7DB, 0x33C1,
+	0xA7DC, 0x338A, 0xA7DD, 0x338B, 0xA7DE, 0x338C, 0xA7DF, 0x33D6,
+	0xA7E0, 0x33C5, 0xA7E1, 0x33AD, 0xA7E2, 0x33AE, 0xA7E3, 0x33AF,
+	0xA7E4, 0x33DB, 0xA7E5, 0x33A9, 0xA7E6, 0x33AA, 0xA7E7, 0x33AB,
+	0xA7E8, 0x33AC, 0xA7E9, 0x33DD, 0xA7EA, 0x33D0, 0xA7EB, 0x33D3,
+	0xA7EC, 0x33C3, 0xA7ED, 0x33C9, 0xA7EE, 0x33DC, 0xA7EF, 0x33C6,
+	0xA841, 0xCB6D, 0xA842, 0xCB6E, 0xA843, 0xCB6F, 0xA844, 0xCB70,
+	0xA845, 0xCB71, 0xA846, 0xCB72, 0xA847, 0xCB73, 0xA848, 0xCB74,
+	0xA849, 0xCB75, 0xA84A, 0xCB76, 0xA84B, 0xCB77, 0xA84C, 0xCB7A,
+	0xA84D, 0xCB7B, 0xA84E, 0xCB7C, 0xA84F, 0xCB7D, 0xA850, 0xCB7E,
+	0xA851, 0xCB7F, 0xA852, 0xCB80, 0xA853, 0xCB81, 0xA854, 0xCB82,
+	0xA855, 0xCB83, 0xA856, 0xCB84, 0xA857, 0xCB85, 0xA858, 0xCB86,
+	0xA859, 0xCB87, 0xA85A, 0xCB88, 0xA861, 0xCB89, 0xA862, 0xCB8A,
+	0xA863, 0xCB8B, 0xA864, 0xCB8C, 0xA865, 0xCB8D, 0xA866, 0xCB8E,
+	0xA867, 0xCB8F, 0xA868, 0xCB90, 0xA869, 0xCB91, 0xA86A, 0xCB92,
+	0xA86B, 0xCB93, 0xA86C, 0xCB94, 0xA86D, 0xCB95, 0xA86E, 0xCB96,
+	0xA86F, 0xCB97, 0xA870, 0xCB98, 0xA871, 0xCB99, 0xA872, 0xCB9A,
+	0xA873, 0xCB9B, 0xA874, 0xCB9D, 0xA875, 0xCB9E, 0xA876, 0xCB9F,
+	0xA877, 0xCBA0, 0xA878, 0xCBA1, 0xA879, 0xCBA2, 0xA87A, 0xCBA3,
+	0xA881, 0xCBA4, 0xA882, 0xCBA5, 0xA883, 0xCBA6, 0xA884, 0xCBA7,
+	0xA885, 0xCBA8, 0xA886, 0xCBA9, 0xA887, 0xCBAA, 0xA888, 0xCBAB,
+	0xA889, 0xCBAC, 0xA88A, 0xCBAD, 0xA88B, 0xCBAE, 0xA88C, 0xCBAF,
+	0xA88D, 0xCBB0, 0xA88E, 0xCBB1, 0xA88F, 0xCBB2, 0xA890, 0xCBB3,
+	0xA891, 0xCBB4, 0xA892, 0xCBB5, 0xA893, 0xCBB6, 0xA894, 0xCBB7,
+	0xA895, 0xCBB9, 0xA896, 0xCBBA, 0xA897, 0xCBBB, 0xA898, 0xCBBC,
+	0xA899, 0xCBBD, 0xA89A, 0xCBBE, 0xA89B, 0xCBBF, 0xA89C, 0xCBC0,
+	0xA89D, 0xCBC1, 0xA89E, 0xCBC2, 0xA89F, 0xCBC3, 0xA8A0, 0xCBC4,
+	0xA8A1, 0x00C6, 0xA8A2, 0x00D0, 0xA8A3, 0x00AA, 0xA8A4, 0x0126,
+	0xA8A6, 0x0132, 0xA8A8, 0x013F, 0xA8A9, 0x0141, 0xA8AA, 0x00D8,
+	0xA8AB, 0x0152, 0xA8AC, 0x00BA, 0xA8AD, 0x00DE, 0xA8AE, 0x0166,
+	0xA8AF, 0x014A, 0xA8B1, 0x3260, 0xA8B2, 0x3261, 0xA8B3, 0x3262,
+	0xA8B4, 0x3263, 0xA8B5, 0x3264, 0xA8B6, 0x3265, 0xA8B7, 0x3266,
+	0xA8B8, 0x3267, 0xA8B9, 0x3268, 0xA8BA, 0x3269, 0xA8BB, 0x326A,
+	0xA8BC, 0x326B, 0xA8BD, 0x326C, 0xA8BE, 0x326D, 0xA8BF, 0x326E,
+	0xA8C0, 0x326F, 0xA8C1, 0x3270, 0xA8C2, 0x3271, 0xA8C3, 0x3272,
+	0xA8C4, 0x3273, 0xA8C5, 0x3274, 0xA8C6, 0x3275, 0xA8C7, 0x3276,
+	0xA8C8, 0x3277, 0xA8C9, 0x3278, 0xA8CA, 0x3279, 0xA8CB, 0x327A,
+	0xA8CC, 0x327B, 0xA8CD, 0x24D0, 0xA8CE, 0x24D1, 0xA8CF, 0x24D2,
+	0xA8D0, 0x24D3, 0xA8D1, 0x24D4, 0xA8D2, 0x24D5, 0xA8D3, 0x24D6,
+	0xA8D4, 0x24D7, 0xA8D5, 0x24D8, 0xA8D6, 0x24D9, 0xA8D7, 0x24DA,
+	0xA8D8, 0x24DB, 0xA8D9, 0x24DC, 0xA8DA, 0x24DD, 0xA8DB, 0x24DE,
+	0xA8DC, 0x24DF, 0xA8DD, 0x24E0, 0xA8DE, 0x24E1, 0xA8DF, 0x24E2,
+	0xA8E0, 0x24E3, 0xA8E1, 0x24E4, 0xA8E2, 0x24E5, 0xA8E3, 0x24E6,
+	0xA8E4, 0x24E7, 0xA8E5, 0x24E8, 0xA8E6, 0x24E9, 0xA8E7, 0x2460,
+	0xA8E8, 0x2461, 0xA8E9, 0x2462, 0xA8EA, 0x2463, 0xA8EB, 0x2464,
+	0xA8EC, 0x2465, 0xA8ED, 0x2466, 0xA8EE, 0x2467, 0xA8EF, 0x2468,
+	0xA8F0, 0x2469, 0xA8F1, 0x246A, 0xA8F2, 0x246B, 0xA8F3, 0x246C,
+	0xA8F4, 0x246D, 0xA8F5, 0x246E, 0xA8F6, 0x00BD, 0xA8F7, 0x2153,
+	0xA8F8, 0x2154, 0xA8F9, 0x00BC, 0xA8FA, 0x00BE, 0xA8FB, 0x215B,
+	0xA8FC, 0x215C, 0xA8FD, 0x215D, 0xA8FE, 0x215E, 0xA941, 0xCBC5,
+	0xA942, 0xCBC6, 0xA943, 0xCBC7, 0xA944, 0xCBC8, 0xA945, 0xCBC9,
+	0xA946, 0xCBCA, 0xA947, 0xCBCB, 0xA948, 0xCBCC, 0xA949, 0xCBCD,
+	0xA94A, 0xCBCE, 0xA94B, 0xCBCF, 0xA94C, 0xCBD0, 0xA94D, 0xCBD1,
+	0xA94E, 0xCBD2, 0xA94F, 0xCBD3, 0xA950, 0xCBD5, 0xA951, 0xCBD6,
+	0xA952, 0xCBD7, 0xA953, 0xCBD8, 0xA954, 0xCBD9, 0xA955, 0xCBDA,
+	0xA956, 0xCBDB, 0xA957, 0xCBDC, 0xA958, 0xCBDD, 0xA959, 0xCBDE,
+	0xA95A, 0xCBDF, 0xA961, 0xCBE0, 0xA962, 0xCBE1, 0xA963, 0xCBE2,
+	0xA964, 0xCBE3, 0xA965, 0xCBE5, 0xA966, 0xCBE6, 0xA967, 0xCBE8,
+	0xA968, 0xCBEA, 0xA969, 0xCBEB, 0xA96A, 0xCBEC, 0xA96B, 0xCBED,
+	0xA96C, 0xCBEE, 0xA96D, 0xCBEF, 0xA96E, 0xCBF0, 0xA96F, 0xCBF1,
+	0xA970, 0xCBF2, 0xA971, 0xCBF3, 0xA972, 0xCBF4, 0xA973, 0xCBF5,
+	0xA974, 0xCBF6, 0xA975, 0xCBF7, 0xA976, 0xCBF8, 0xA977, 0xCBF9,
+	0xA978, 0xCBFA, 0xA979, 0xCBFB, 0xA97A, 0xCBFC, 0xA981, 0xCBFD,
+	0xA982, 0xCBFE, 0xA983, 0xCBFF, 0xA984, 0xCC00, 0xA985, 0xCC01,
+	0xA986, 0xCC02, 0xA987, 0xCC03, 0xA988, 0xCC04, 0xA989, 0xCC05,
+	0xA98A, 0xCC06, 0xA98B, 0xCC07, 0xA98C, 0xCC08, 0xA98D, 0xCC09,
+	0xA98E, 0xCC0A, 0xA98F, 0xCC0B, 0xA990, 0xCC0E, 0xA991, 0xCC0F,
+	0xA992, 0xCC11, 0xA993, 0xCC12, 0xA994, 0xCC13, 0xA995, 0xCC15,
+	0xA996, 0xCC16, 0xA997, 0xCC17, 0xA998, 0xCC18, 0xA999, 0xCC19,
+	0xA99A, 0xCC1A, 0xA99B, 0xCC1B, 0xA99C, 0xCC1E, 0xA99D, 0xCC1F,
+	0xA99E, 0xCC20, 0xA99F, 0xCC23, 0xA9A0, 0xCC24, 0xA9A1, 0x00E6,
+	0xA9A2, 0x0111, 0xA9A3, 0x00F0, 0xA9A4, 0x0127, 0xA9A5, 0x0131,
+	0xA9A6, 0x0133, 0xA9A7, 0x0138, 0xA9A8, 0x0140, 0xA9A9, 0x0142,
+	0xA9AA, 0x00F8, 0xA9AB, 0x0153, 0xA9AC, 0x00DF, 0xA9AD, 0x00FE,
+	0xA9AE, 0x0167, 0xA9AF, 0x014B, 0xA9B0, 0x0149, 0xA9B1, 0x3200,
+	0xA9B2, 0x3201, 0xA9B3, 0x3202, 0xA9B4, 0x3203, 0xA9B5, 0x3204,
+	0xA9B6, 0x3205, 0xA9B7, 0x3206, 0xA9B8, 0x3207, 0xA9B9, 0x3208,
+	0xA9BA, 0x3209, 0xA9BB, 0x320A, 0xA9BC, 0x320B, 0xA9BD, 0x320C,
+	0xA9BE, 0x320D, 0xA9BF, 0x320E, 0xA9C0, 0x320F, 0xA9C1, 0x3210,
+	0xA9C2, 0x3211, 0xA9C3, 0x3212, 0xA9C4, 0x3213, 0xA9C5, 0x3214,
+	0xA9C6, 0x3215, 0xA9C7, 0x3216, 0xA9C8, 0x3217, 0xA9C9, 0x3218,
+	0xA9CA, 0x3219, 0xA9CB, 0x321A, 0xA9CC, 0x321B, 0xA9CD, 0x249C,
+	0xA9CE, 0x249D, 0xA9CF, 0x249E, 0xA9D0, 0x249F, 0xA9D1, 0x24A0,
+	0xA9D2, 0x24A1, 0xA9D3, 0x24A2, 0xA9D4, 0x24A3, 0xA9D5, 0x24A4,
+	0xA9D6, 0x24A5, 0xA9D7, 0x24A6, 0xA9D8, 0x24A7, 0xA9D9, 0x24A8,
+	0xA9DA, 0x24A9, 0xA9DB, 0x24AA, 0xA9DC, 0x24AB, 0xA9DD, 0x24AC,
+	0xA9DE, 0x24AD, 0xA9DF, 0x24AE, 0xA9E0, 0x24AF, 0xA9E1, 0x24B0,
+	0xA9E2, 0x24B1, 0xA9E3, 0x24B2, 0xA9E4, 0x24B3, 0xA9E5, 0x24B4,
+	0xA9E6, 0x24B5, 0xA9E7, 0x2474, 0xA9E8, 0x2475, 0xA9E9, 0x2476,
+	0xA9EA, 0x2477, 0xA9EB, 0x2478, 0xA9EC, 0x2479, 0xA9ED, 0x247A,
+	0xA9EE, 0x247B, 0xA9EF, 0x247C, 0xA9F0, 0x247D, 0xA9F1, 0x247E,
+	0xA9F2, 0x247F, 0xA9F3, 0x2480, 0xA9F4, 0x2481, 0xA9F5, 0x2482,
+	0xA9F6, 0x00B9, 0xA9F7, 0x00B2, 0xA9F8, 0x00B3, 0xA9F9, 0x2074,
+	0xA9FA, 0x207F, 0xA9FB, 0x2081, 0xA9FC, 0x2082, 0xA9FD, 0x2083,
+	0xA9FE, 0x2084, 0xAA41, 0xCC25, 0xAA42, 0xCC26, 0xAA43, 0xCC2A,
+	0xAA44, 0xCC2B, 0xAA45, 0xCC2D, 0xAA46, 0xCC2F, 0xAA47, 0xCC31,
+	0xAA48, 0xCC32, 0xAA49, 0xCC33, 0xAA4A, 0xCC34, 0xAA4B, 0xCC35,
+	0xAA4C, 0xCC36, 0xAA4D, 0xCC37, 0xAA4E, 0xCC3A, 0xAA4F, 0xCC3F,
+	0xAA50, 0xCC40, 0xAA51, 0xCC41, 0xAA52, 0xCC42, 0xAA53, 0xCC43,
+	0xAA54, 0xCC46, 0xAA55, 0xCC47, 0xAA56, 0xCC49, 0xAA57, 0xCC4A,
+	0xAA58, 0xCC4B, 0xAA59, 0xCC4D, 0xAA5A, 0xCC4E, 0xAA61, 0xCC4F,
+	0xAA62, 0xCC50, 0xAA63, 0xCC51, 0xAA64, 0xCC52, 0xAA65, 0xCC53,
+	0xAA66, 0xCC56, 0xAA67, 0xCC5A, 0xAA68, 0xCC5B, 0xAA69, 0xCC5C,
+	0xAA6A, 0xCC5D, 0xAA6B, 0xCC5E, 0xAA6C, 0xCC5F, 0xAA6D, 0xCC61,
+	0xAA6E, 0xCC62, 0xAA6F, 0xCC63, 0xAA70, 0xCC65, 0xAA71, 0xCC67,
+	0xAA72, 0xCC69, 0xAA73, 0xCC6A, 0xAA74, 0xCC6B, 0xAA75, 0xCC6C,
+	0xAA76, 0xCC6D, 0xAA77, 0xCC6E, 0xAA78, 0xCC6F, 0xAA79, 0xCC71,
+	0xAA7A, 0xCC72, 0xAA81, 0xCC73, 0xAA82, 0xCC74, 0xAA83, 0xCC76,
+	0xAA84, 0xCC77, 0xAA85, 0xCC78, 0xAA86, 0xCC79, 0xAA87, 0xCC7A,
+	0xAA88, 0xCC7B, 0xAA89, 0xCC7C, 0xAA8A, 0xCC7D, 0xAA8B, 0xCC7E,
+	0xAA8C, 0xCC7F, 0xAA8D, 0xCC80, 0xAA8E, 0xCC81, 0xAA8F, 0xCC82,
+	0xAA90, 0xCC83, 0xAA91, 0xCC84, 0xAA92, 0xCC85, 0xAA93, 0xCC86,
+	0xAA94, 0xCC87, 0xAA95, 0xCC88, 0xAA96, 0xCC89, 0xAA97, 0xCC8A,
+	0xAA98, 0xCC8B, 0xAA99, 0xCC8C, 0xAA9A, 0xCC8D, 0xAA9B, 0xCC8E,
+	0xAA9C, 0xCC8F, 0xAA9D, 0xCC90, 0xAA9E, 0xCC91, 0xAA9F, 0xCC92,
+	0xAAA0, 0xCC93, 0xAAA1, 0x3041, 0xAAA2, 0x3042, 0xAAA3, 0x3043,
+	0xAAA4, 0x3044, 0xAAA5, 0x3045, 0xAAA6, 0x3046, 0xAAA7, 0x3047,
+	0xAAA8, 0x3048, 0xAAA9, 0x3049, 0xAAAA, 0x304A, 0xAAAB, 0x304B,
+	0xAAAC, 0x304C, 0xAAAD, 0x304D, 0xAAAE, 0x304E, 0xAAAF, 0x304F,
+	0xAAB0, 0x3050, 0xAAB1, 0x3051, 0xAAB2, 0x3052, 0xAAB3, 0x3053,
+	0xAAB4, 0x3054, 0xAAB5, 0x3055, 0xAAB6, 0x3056, 0xAAB7, 0x3057,
+	0xAAB8, 0x3058, 0xAAB9, 0x3059, 0xAABA, 0x305A, 0xAABB, 0x305B,
+	0xAABC, 0x305C, 0xAABD, 0x305D, 0xAABE, 0x305E, 0xAABF, 0x305F,
+	0xAAC0, 0x3060, 0xAAC1, 0x3061, 0xAAC2, 0x3062, 0xAAC3, 0x3063,
+	0xAAC4, 0x3064, 0xAAC5, 0x3065, 0xAAC6, 0x3066, 0xAAC7, 0x3067,
+	0xAAC8, 0x3068, 0xAAC9, 0x3069, 0xAACA, 0x306A, 0xAACB, 0x306B,
+	0xAACC, 0x306C, 0xAACD, 0x306D, 0xAACE, 0x306E, 0xAACF, 0x306F,
+	0xAAD0, 0x3070, 0xAAD1, 0x3071, 0xAAD2, 0x3072, 0xAAD3, 0x3073,
+	0xAAD4, 0x3074, 0xAAD5, 0x3075, 0xAAD6, 0x3076, 0xAAD7, 0x3077,
+	0xAAD8, 0x3078, 0xAAD9, 0x3079, 0xAADA, 0x307A, 0xAADB, 0x307B,
+	0xAADC, 0x307C, 0xAADD, 0x307D, 0xAADE, 0x307E, 0xAADF, 0x307F,
+	0xAAE0, 0x3080, 0xAAE1, 0x3081, 0xAAE2, 0x3082, 0xAAE3, 0x3083,
+	0xAAE4, 0x3084, 0xAAE5, 0x3085, 0xAAE6, 0x3086, 0xAAE7, 0x3087,
+	0xAAE8, 0x3088, 0xAAE9, 0x3089, 0xAAEA, 0x308A, 0xAAEB, 0x308B,
+	0xAAEC, 0x308C, 0xAAED, 0x308D, 0xAAEE, 0x308E, 0xAAEF, 0x308F,
+	0xAAF0, 0x3090, 0xAAF1, 0x3091, 0xAAF2, 0x3092, 0xAAF3, 0x3093,
+	0xAB41, 0xCC94, 0xAB42, 0xCC95, 0xAB43, 0xCC96, 0xAB44, 0xCC97,
+	0xAB45, 0xCC9A, 0xAB46, 0xCC9B, 0xAB47, 0xCC9D, 0xAB48, 0xCC9E,
+	0xAB49, 0xCC9F, 0xAB4A, 0xCCA1, 0xAB4B, 0xCCA2, 0xAB4C, 0xCCA3,
+	0xAB4D, 0xCCA4, 0xAB4E, 0xCCA5, 0xAB4F, 0xCCA6, 0xAB50, 0xCCA7,
+	0xAB51, 0xCCAA, 0xAB52, 0xCCAE, 0xAB53, 0xCCAF, 0xAB54, 0xCCB0,
+	0xAB55, 0xCCB1, 0xAB56, 0xCCB2, 0xAB57, 0xCCB3, 0xAB58, 0xCCB6,
+	0xAB59, 0xCCB7, 0xAB5A, 0xCCB9, 0xAB61, 0xCCBA, 0xAB62, 0xCCBB,
+	0xAB63, 0xCCBD, 0xAB64, 0xCCBE, 0xAB65, 0xCCBF, 0xAB66, 0xCCC0,
+	0xAB67, 0xCCC1, 0xAB68, 0xCCC2, 0xAB69, 0xCCC3, 0xAB6A, 0xCCC6,
+	0xAB6B, 0xCCC8, 0xAB6C, 0xCCCA, 0xAB6D, 0xCCCB, 0xAB6E, 0xCCCC,
+	0xAB6F, 0xCCCD, 0xAB70, 0xCCCE, 0xAB71, 0xCCCF, 0xAB72, 0xCCD1,
+	0xAB73, 0xCCD2, 0xAB74, 0xCCD3, 0xAB75, 0xCCD5, 0xAB76, 0xCCD6,
+	0xAB77, 0xCCD7, 0xAB78, 0xCCD8, 0xAB79, 0xCCD9, 0xAB7A, 0xCCDA,
+	0xAB81, 0xCCDB, 0xAB82, 0xCCDC, 0xAB83, 0xCCDD, 0xAB84, 0xCCDE,
+	0xAB85, 0xCCDF, 0xAB86, 0xCCE0, 0xAB87, 0xCCE1, 0xAB88, 0xCCE2,
+	0xAB89, 0xCCE3, 0xAB8A, 0xCCE5, 0xAB8B, 0xCCE6, 0xAB8C, 0xCCE7,
+	0xAB8D, 0xCCE8, 0xAB8E, 0xCCE9, 0xAB8F, 0xCCEA, 0xAB90, 0xCCEB,
+	0xAB91, 0xCCED, 0xAB92, 0xCCEE, 0xAB93, 0xCCEF, 0xAB94, 0xCCF1,
+	0xAB95, 0xCCF2, 0xAB96, 0xCCF3, 0xAB97, 0xCCF4, 0xAB98, 0xCCF5,
+	0xAB99, 0xCCF6, 0xAB9A, 0xCCF7, 0xAB9B, 0xCCF8, 0xAB9C, 0xCCF9,
+	0xAB9D, 0xCCFA, 0xAB9E, 0xCCFB, 0xAB9F, 0xCCFC, 0xABA0, 0xCCFD,
+	0xABA1, 0x30A1, 0xABA2, 0x30A2, 0xABA3, 0x30A3, 0xABA4, 0x30A4,
+	0xABA5, 0x30A5, 0xABA6, 0x30A6, 0xABA7, 0x30A7, 0xABA8, 0x30A8,
+	0xABA9, 0x30A9, 0xABAA, 0x30AA, 0xABAB, 0x30AB, 0xABAC, 0x30AC,
+	0xABAD, 0x30AD, 0xABAE, 0x30AE, 0xABAF, 0x30AF, 0xABB0, 0x30B0,
+	0xABB1, 0x30B1, 0xABB2, 0x30B2, 0xABB3, 0x30B3, 0xABB4, 0x30B4,
+	0xABB5, 0x30B5, 0xABB6, 0x30B6, 0xABB7, 0x30B7, 0xABB8, 0x30B8,
+	0xABB9, 0x30B9, 0xABBA, 0x30BA, 0xABBB, 0x30BB, 0xABBC, 0x30BC,
+	0xABBD, 0x30BD, 0xABBE, 0x30BE, 0xABBF, 0x30BF, 0xABC0, 0x30C0,
+	0xABC1, 0x30C1, 0xABC2, 0x30C2, 0xABC3, 0x30C3, 0xABC4, 0x30C4,
+	0xABC5, 0x30C5, 0xABC6, 0x30C6, 0xABC7, 0x30C7, 0xABC8, 0x30C8,
+	0xABC9, 0x30C9, 0xABCA, 0x30CA, 0xABCB, 0x30CB, 0xABCC, 0x30CC,
+	0xABCD, 0x30CD, 0xABCE, 0x30CE, 0xABCF, 0x30CF, 0xABD0, 0x30D0,
+	0xABD1, 0x30D1, 0xABD2, 0x30D2, 0xABD3, 0x30D3, 0xABD4, 0x30D4,
+	0xABD5, 0x30D5, 0xABD6, 0x30D6, 0xABD7, 0x30D7, 0xABD8, 0x30D8,
+	0xABD9, 0x30D9, 0xABDA, 0x30DA, 0xABDB, 0x30DB, 0xABDC, 0x30DC,
+	0xABDD, 0x30DD, 0xABDE, 0x30DE, 0xABDF, 0x30DF, 0xABE0, 0x30E0,
+	0xABE1, 0x30E1, 0xABE2, 0x30E2, 0xABE3, 0x30E3, 0xABE4, 0x30E4,
+	0xABE5, 0x30E5, 0xABE6, 0x30E6, 0xABE7, 0x30E7, 0xABE8, 0x30E8,
+	0xABE9, 0x30E9, 0xABEA, 0x30EA, 0xABEB, 0x30EB, 0xABEC, 0x30EC,
+	0xABED, 0x30ED, 0xABEE, 0x30EE, 0xABEF, 0x30EF, 0xABF0, 0x30F0,
+	0xABF1, 0x30F1, 0xABF2, 0x30F2, 0xABF3, 0x30F3, 0xABF4, 0x30F4,
+	0xABF5, 0x30F5, 0xABF6, 0x30F6, 0xAC41, 0xCCFE, 0xAC42, 0xCCFF,
+	0xAC43, 0xCD00, 0xAC44, 0xCD02, 0xAC45, 0xCD03, 0xAC46, 0xCD04,
+	0xAC47, 0xCD05, 0xAC48, 0xCD06, 0xAC49, 0xCD07, 0xAC4A, 0xCD0A,
+	0xAC4B, 0xCD0B, 0xAC4C, 0xCD0D, 0xAC4D, 0xCD0E, 0xAC4E, 0xCD0F,
+	0xAC4F, 0xCD11, 0xAC50, 0xCD12, 0xAC51, 0xCD13, 0xAC52, 0xCD14,
+	0xAC53, 0xCD15, 0xAC54, 0xCD16, 0xAC55, 0xCD17, 0xAC56, 0xCD1A,
+	0xAC57, 0xCD1C, 0xAC58, 0xCD1E, 0xAC59, 0xCD1F, 0xAC5A, 0xCD20,
+	0xAC61, 0xCD21, 0xAC62, 0xCD22, 0xAC63, 0xCD23, 0xAC64, 0xCD25,
+	0xAC65, 0xCD26, 0xAC66, 0xCD27, 0xAC67, 0xCD29, 0xAC68, 0xCD2A,
+	0xAC69, 0xCD2B, 0xAC6A, 0xCD2D, 0xAC6B, 0xCD2E, 0xAC6C, 0xCD2F,
+	0xAC6D, 0xCD30, 0xAC6E, 0xCD31, 0xAC6F, 0xCD32, 0xAC70, 0xCD33,
+	0xAC71, 0xCD34, 0xAC72, 0xCD35, 0xAC73, 0xCD36, 0xAC74, 0xCD37,
+	0xAC75, 0xCD38, 0xAC76, 0xCD3A, 0xAC77, 0xCD3B, 0xAC78, 0xCD3C,
+	0xAC79, 0xCD3D, 0xAC7A, 0xCD3E, 0xAC81, 0xCD3F, 0xAC82, 0xCD40,
+	0xAC83, 0xCD41, 0xAC84, 0xCD42, 0xAC85, 0xCD43, 0xAC86, 0xCD44,
+	0xAC87, 0xCD45, 0xAC88, 0xCD46, 0xAC89, 0xCD47, 0xAC8A, 0xCD48,
+	0xAC8B, 0xCD49, 0xAC8C, 0xCD4A, 0xAC8D, 0xCD4B, 0xAC8E, 0xCD4C,
+	0xAC8F, 0xCD4D, 0xAC90, 0xCD4E, 0xAC91, 0xCD4F, 0xAC92, 0xCD50,
+	0xAC93, 0xCD51, 0xAC94, 0xCD52, 0xAC95, 0xCD53, 0xAC96, 0xCD54,
+	0xAC97, 0xCD55, 0xAC98, 0xCD56, 0xAC99, 0xCD57, 0xAC9A, 0xCD58,
+	0xAC9B, 0xCD59, 0xAC9C, 0xCD5A, 0xAC9D, 0xCD5B, 0xAC9E, 0xCD5D,
+	0xAC9F, 0xCD5E, 0xACA0, 0xCD5F, 0xACA1, 0x0410, 0xACA2, 0x0411,
+	0xACA3, 0x0412, 0xACA4, 0x0413, 0xACA5, 0x0414, 0xACA6, 0x0415,
+	0xACA7, 0x0401, 0xACA8, 0x0416, 0xACA9, 0x0417, 0xACAA, 0x0418,
+	0xACAB, 0x0419, 0xACAC, 0x041A, 0xACAD, 0x041B, 0xACAE, 0x041C,
+	0xACAF, 0x041D, 0xACB0, 0x041E, 0xACB1, 0x041F, 0xACB2, 0x0420,
+	0xACB3, 0x0421, 0xACB4, 0x0422, 0xACB5, 0x0423, 0xACB6, 0x0424,
+	0xACB7, 0x0425, 0xACB8, 0x0426, 0xACB9, 0x0427, 0xACBA, 0x0428,
+	0xACBB, 0x0429, 0xACBC, 0x042A, 0xACBD, 0x042B, 0xACBE, 0x042C,
+	0xACBF, 0x042D, 0xACC0, 0x042E, 0xACC1, 0x042F, 0xACD1, 0x0430,
+	0xACD2, 0x0431, 0xACD3, 0x0432, 0xACD4, 0x0433, 0xACD5, 0x0434,
+	0xACD6, 0x0435, 0xACD7, 0x0451, 0xACD8, 0x0436, 0xACD9, 0x0437,
+	0xACDA, 0x0438, 0xACDB, 0x0439, 0xACDC, 0x043A, 0xACDD, 0x043B,
+	0xACDE, 0x043C, 0xACDF, 0x043D, 0xACE0, 0x043E, 0xACE1, 0x043F,
+	0xACE2, 0x0440, 0xACE3, 0x0441, 0xACE4, 0x0442, 0xACE5, 0x0443,
+	0xACE6, 0x0444, 0xACE7, 0x0445, 0xACE8, 0x0446, 0xACE9, 0x0447,
+	0xACEA, 0x0448, 0xACEB, 0x0449, 0xACEC, 0x044A, 0xACED, 0x044B,
+	0xACEE, 0x044C, 0xACEF, 0x044D, 0xACF0, 0x044E, 0xACF1, 0x044F,
+	0xAD41, 0xCD61, 0xAD42, 0xCD62, 0xAD43, 0xCD63, 0xAD44, 0xCD65,
+	0xAD45, 0xCD66, 0xAD46, 0xCD67, 0xAD47, 0xCD68, 0xAD48, 0xCD69,
+	0xAD49, 0xCD6A, 0xAD4A, 0xCD6B, 0xAD4B, 0xCD6E, 0xAD4C, 0xCD70,
+	0xAD4D, 0xCD72, 0xAD4E, 0xCD73, 0xAD4F, 0xCD74, 0xAD50, 0xCD75,
+	0xAD51, 0xCD76, 0xAD52, 0xCD77, 0xAD53, 0xCD79, 0xAD54, 0xCD7A,
+	0xAD55, 0xCD7B, 0xAD56, 0xCD7C, 0xAD57, 0xCD7D, 0xAD58, 0xCD7E,
+	0xAD59, 0xCD7F, 0xAD5A, 0xCD80, 0xAD61, 0xCD81, 0xAD62, 0xCD82,
+	0xAD63, 0xCD83, 0xAD64, 0xCD84, 0xAD65, 0xCD85, 0xAD66, 0xCD86,
+	0xAD67, 0xCD87, 0xAD68, 0xCD89, 0xAD69, 0xCD8A, 0xAD6A, 0xCD8B,
+	0xAD6B, 0xCD8C, 0xAD6C, 0xCD8D, 0xAD6D, 0xCD8E, 0xAD6E, 0xCD8F,
+	0xAD6F, 0xCD90, 0xAD70, 0xCD91, 0xAD71, 0xCD92, 0xAD72, 0xCD93,
+	0xAD73, 0xCD96, 0xAD74, 0xCD97, 0xAD75, 0xCD99, 0xAD76, 0xCD9A,
+	0xAD77, 0xCD9B, 0xAD78, 0xCD9D, 0xAD79, 0xCD9E, 0xAD7A, 0xCD9F,
+	0xAD81, 0xCDA0, 0xAD82, 0xCDA1, 0xAD83, 0xCDA2, 0xAD84, 0xCDA3,
+	0xAD85, 0xCDA6, 0xAD86, 0xCDA8, 0xAD87, 0xCDAA, 0xAD88, 0xCDAB,
+	0xAD89, 0xCDAC, 0xAD8A, 0xCDAD, 0xAD8B, 0xCDAE, 0xAD8C, 0xCDAF,
+	0xAD8D, 0xCDB1, 0xAD8E, 0xCDB2, 0xAD8F, 0xCDB3, 0xAD90, 0xCDB4,
+	0xAD91, 0xCDB5, 0xAD92, 0xCDB6, 0xAD93, 0xCDB7, 0xAD94, 0xCDB8,
+	0xAD95, 0xCDB9, 0xAD96, 0xCDBA, 0xAD97, 0xCDBB, 0xAD98, 0xCDBC,
+	0xAD99, 0xCDBD, 0xAD9A, 0xCDBE, 0xAD9B, 0xCDBF, 0xAD9C, 0xCDC0,
+	0xAD9D, 0xCDC1, 0xAD9E, 0xCDC2, 0xAD9F, 0xCDC3, 0xADA0, 0xCDC5,
+	0xAE41, 0xCDC6, 0xAE42, 0xCDC7, 0xAE43, 0xCDC8, 0xAE44, 0xCDC9,
+	0xAE45, 0xCDCA, 0xAE46, 0xCDCB, 0xAE47, 0xCDCD, 0xAE48, 0xCDCE,
+	0xAE49, 0xCDCF, 0xAE4A, 0xCDD1, 0xAE4B, 0xCDD2, 0xAE4C, 0xCDD3,
+	0xAE4D, 0xCDD4, 0xAE4E, 0xCDD5, 0xAE4F, 0xCDD6, 0xAE50, 0xCDD7,
+	0xAE51, 0xCDD8, 0xAE52, 0xCDD9, 0xAE53, 0xCDDA, 0xAE54, 0xCDDB,
+	0xAE55, 0xCDDC, 0xAE56, 0xCDDD, 0xAE57, 0xCDDE, 0xAE58, 0xCDDF,
+	0xAE59, 0xCDE0, 0xAE5A, 0xCDE1, 0xAE61, 0xCDE2, 0xAE62, 0xCDE3,
+	0xAE63, 0xCDE4, 0xAE64, 0xCDE5, 0xAE65, 0xCDE6, 0xAE66, 0xCDE7,
+	0xAE67, 0xCDE9, 0xAE68, 0xCDEA, 0xAE69, 0xCDEB, 0xAE6A, 0xCDED,
+	0xAE6B, 0xCDEE, 0xAE6C, 0xCDEF, 0xAE6D, 0xCDF1, 0xAE6E, 0xCDF2,
+	0xAE6F, 0xCDF3, 0xAE70, 0xCDF4, 0xAE71, 0xCDF5, 0xAE72, 0xCDF6,
+	0xAE73, 0xCDF7, 0xAE74, 0xCDFA, 0xAE75, 0xCDFC, 0xAE76, 0xCDFE,
+	0xAE77, 0xCDFF, 0xAE78, 0xCE00, 0xAE79, 0xCE01, 0xAE7A, 0xCE02,
+	0xAE81, 0xCE03, 0xAE82, 0xCE05, 0xAE83, 0xCE06, 0xAE84, 0xCE07,
+	0xAE85, 0xCE09, 0xAE86, 0xCE0A, 0xAE87, 0xCE0B, 0xAE88, 0xCE0D,
+	0xAE89, 0xCE0E, 0xAE8A, 0xCE0F, 0xAE8B, 0xCE10, 0xAE8C, 0xCE11,
+	0xAE8D, 0xCE12, 0xAE8E, 0xCE13, 0xAE8F, 0xCE15, 0xAE90, 0xCE16,
+	0xAE91, 0xCE17, 0xAE92, 0xCE18, 0xAE93, 0xCE1A, 0xAE94, 0xCE1B,
+	0xAE95, 0xCE1C, 0xAE96, 0xCE1D, 0xAE97, 0xCE1E, 0xAE98, 0xCE1F,
+	0xAE99, 0xCE22, 0xAE9A, 0xCE23, 0xAE9B, 0xCE25, 0xAE9C, 0xCE26,
+	0xAE9D, 0xCE27, 0xAE9E, 0xCE29, 0xAE9F, 0xCE2A, 0xAEA0, 0xCE2B,
+	0xAF41, 0xCE2C, 0xAF42, 0xCE2D, 0xAF43, 0xCE2E, 0xAF44, 0xCE2F,
+	0xAF45, 0xCE32, 0xAF46, 0xCE34, 0xAF47, 0xCE36, 0xAF48, 0xCE37,
+	0xAF49, 0xCE38, 0xAF4A, 0xCE39, 0xAF4B, 0xCE3A, 0xAF4C, 0xCE3B,
+	0xAF4D, 0xCE3C, 0xAF4E, 0xCE3D, 0xAF4F, 0xCE3E, 0xAF50, 0xCE3F,
+	0xAF51, 0xCE40, 0xAF52, 0xCE41, 0xAF53, 0xCE42, 0xAF54, 0xCE43,
+	0xAF55, 0xCE44, 0xAF56, 0xCE45, 0xAF57, 0xCE46, 0xAF58, 0xCE47,
+	0xAF59, 0xCE48, 0xAF5A, 0xCE49, 0xAF61, 0xCE4A, 0xAF62, 0xCE4B,
+	0xAF63, 0xCE4C, 0xAF64, 0xCE4D, 0xAF65, 0xCE4E, 0xAF66, 0xCE4F,
+	0xAF67, 0xCE50, 0xAF68, 0xCE51, 0xAF69, 0xCE52, 0xAF6A, 0xCE53,
+	0xAF6B, 0xCE54, 0xAF6C, 0xCE55, 0xAF6D, 0xCE56, 0xAF6E, 0xCE57,
+	0xAF6F, 0xCE5A, 0xAF70, 0xCE5B, 0xAF71, 0xCE5D, 0xAF72, 0xCE5E,
+	0xAF73, 0xCE62, 0xAF74, 0xCE63, 0xAF75, 0xCE64, 0xAF76, 0xCE65,
+	0xAF77, 0xCE66, 0xAF78, 0xCE67, 0xAF79, 0xCE6A, 0xAF7A, 0xCE6C,
+	0xAF81, 0xCE6E, 0xAF82, 0xCE6F, 0xAF83, 0xCE70, 0xAF84, 0xCE71,
+	0xAF85, 0xCE72, 0xAF86, 0xCE73, 0xAF87, 0xCE76, 0xAF88, 0xCE77,
+	0xAF89, 0xCE79, 0xAF8A, 0xCE7A, 0xAF8B, 0xCE7B, 0xAF8C, 0xCE7D,
+	0xAF8D, 0xCE7E, 0xAF8E, 0xCE7F, 0xAF8F, 0xCE80, 0xAF90, 0xCE81,
+	0xAF91, 0xCE82, 0xAF92, 0xCE83, 0xAF93, 0xCE86, 0xAF94, 0xCE88,
+	0xAF95, 0xCE8A, 0xAF96, 0xCE8B, 0xAF97, 0xCE8C, 0xAF98, 0xCE8D,
+	0xAF99, 0xCE8E, 0xAF9A, 0xCE8F, 0xAF9B, 0xCE92, 0xAF9C, 0xCE93,
+	0xAF9D, 0xCE95, 0xAF9E, 0xCE96, 0xAF9F, 0xCE97, 0xAFA0, 0xCE99,
+	0xB041, 0xCE9A, 0xB042, 0xCE9B, 0xB043, 0xCE9C, 0xB044, 0xCE9D,
+	0xB045, 0xCE9E, 0xB046, 0xCE9F, 0xB047, 0xCEA2, 0xB048, 0xCEA6,
+	0xB049, 0xCEA7, 0xB04A, 0xCEA8, 0xB04B, 0xCEA9, 0xB04C, 0xCEAA,
+	0xB04D, 0xCEAB, 0xB04E, 0xCEAE, 0xB04F, 0xCEAF, 0xB050, 0xCEB0,
+	0xB051, 0xCEB1, 0xB052, 0xCEB2, 0xB053, 0xCEB3, 0xB054, 0xCEB4,
+	0xB055, 0xCEB5, 0xB056, 0xCEB6, 0xB057, 0xCEB7, 0xB058, 0xCEB8,
+	0xB059, 0xCEB9, 0xB05A, 0xCEBA, 0xB061, 0xCEBB, 0xB062, 0xCEBC,
+	0xB063, 0xCEBD, 0xB064, 0xCEBE, 0xB065, 0xCEBF, 0xB066, 0xCEC0,
+	0xB067, 0xCEC2, 0xB068, 0xCEC3, 0xB069, 0xCEC4, 0xB06A, 0xCEC5,
+	0xB06B, 0xCEC6, 0xB06C, 0xCEC7, 0xB06D, 0xCEC8, 0xB06E, 0xCEC9,
+	0xB06F, 0xCECA, 0xB070, 0xCECB, 0xB071, 0xCECC, 0xB072, 0xCECD,
+	0xB073, 0xCECE, 0xB074, 0xCECF, 0xB075, 0xCED0, 0xB076, 0xCED1,
+	0xB077, 0xCED2, 0xB078, 0xCED3, 0xB079, 0xCED4, 0xB07A, 0xCED5,
+	0xB081, 0xCED6, 0xB082, 0xCED7, 0xB083, 0xCED8, 0xB084, 0xCED9,
+	0xB085, 0xCEDA, 0xB086, 0xCEDB, 0xB087, 0xCEDC, 0xB088, 0xCEDD,
+	0xB089, 0xCEDE, 0xB08A, 0xCEDF, 0xB08B, 0xCEE0, 0xB08C, 0xCEE1,
+	0xB08D, 0xCEE2, 0xB08E, 0xCEE3, 0xB08F, 0xCEE6, 0xB090, 0xCEE7,
+	0xB091, 0xCEE9, 0xB092, 0xCEEA, 0xB093, 0xCEED, 0xB094, 0xCEEE,
+	0xB095, 0xCEEF, 0xB096, 0xCEF0, 0xB097, 0xCEF1, 0xB098, 0xCEF2,
+	0xB099, 0xCEF3, 0xB09A, 0xCEF6, 0xB09B, 0xCEFA, 0xB09C, 0xCEFB,
+	0xB09D, 0xCEFC, 0xB09E, 0xCEFD, 0xB09F, 0xCEFE, 0xB0A0, 0xCEFF,
+	0xB0A1, 0xAC00, 0xB0A2, 0xAC01, 0xB0A3, 0xAC04, 0xB0A4, 0xAC07,
+	0xB0A5, 0xAC08, 0xB0A6, 0xAC09, 0xB0A7, 0xAC0A, 0xB0A8, 0xAC10,
+	0xB0A9, 0xAC11, 0xB0AA, 0xAC12, 0xB0AB, 0xAC13, 0xB0AC, 0xAC14,
+	0xB0AD, 0xAC15, 0xB0AE, 0xAC16, 0xB0AF, 0xAC17, 0xB0B0, 0xAC19,
+	0xB0B1, 0xAC1A, 0xB0B2, 0xAC1B, 0xB0B3, 0xAC1C, 0xB0B4, 0xAC1D,
+	0xB0B5, 0xAC20, 0xB0B6, 0xAC24, 0xB0B7, 0xAC2C, 0xB0B8, 0xAC2D,
+	0xB0B9, 0xAC2F, 0xB0BA, 0xAC30, 0xB0BB, 0xAC31, 0xB0BC, 0xAC38,
+	0xB0BD, 0xAC39, 0xB0BE, 0xAC3C, 0xB0BF, 0xAC40, 0xB0C0, 0xAC4B,
+	0xB0C1, 0xAC4D, 0xB0C2, 0xAC54, 0xB0C3, 0xAC58, 0xB0C4, 0xAC5C,
+	0xB0C5, 0xAC70, 0xB0C6, 0xAC71, 0xB0C7, 0xAC74, 0xB0C8, 0xAC77,
+	0xB0C9, 0xAC78, 0xB0CA, 0xAC7A, 0xB0CB, 0xAC80, 0xB0CC, 0xAC81,
+	0xB0CD, 0xAC83, 0xB0CE, 0xAC84, 0xB0CF, 0xAC85, 0xB0D0, 0xAC86,
+	0xB0D1, 0xAC89, 0xB0D2, 0xAC8A, 0xB0D3, 0xAC8B, 0xB0D4, 0xAC8C,
+	0xB0D5, 0xAC90, 0xB0D6, 0xAC94, 0xB0D7, 0xAC9C, 0xB0D8, 0xAC9D,
+	0xB0D9, 0xAC9F, 0xB0DA, 0xACA0, 0xB0DB, 0xACA1, 0xB0DC, 0xACA8,
+	0xB0DD, 0xACA9, 0xB0DE, 0xACAA, 0xB0DF, 0xACAC, 0xB0E0, 0xACAF,
+	0xB0E1, 0xACB0, 0xB0E2, 0xACB8, 0xB0E3, 0xACB9, 0xB0E4, 0xACBB,
+	0xB0E5, 0xACBC, 0xB0E6, 0xACBD, 0xB0E7, 0xACC1, 0xB0E8, 0xACC4,
+	0xB0E9, 0xACC8, 0xB0EA, 0xACCC, 0xB0EB, 0xACD5, 0xB0EC, 0xACD7,
+	0xB0ED, 0xACE0, 0xB0EE, 0xACE1, 0xB0EF, 0xACE4, 0xB0F0, 0xACE7,
+	0xB0F1, 0xACE8, 0xB0F2, 0xACEA, 0xB0F3, 0xACEC, 0xB0F4, 0xACEF,
+	0xB0F5, 0xACF0, 0xB0F6, 0xACF1, 0xB0F7, 0xACF3, 0xB0F8, 0xACF5,
+	0xB0F9, 0xACF6, 0xB0FA, 0xACFC, 0xB0FB, 0xACFD, 0xB0FC, 0xAD00,
+	0xB0FD, 0xAD04, 0xB0FE, 0xAD06, 0xB141, 0xCF02, 0xB142, 0xCF03,
+	0xB143, 0xCF05, 0xB144, 0xCF06, 0xB145, 0xCF07, 0xB146, 0xCF09,
+	0xB147, 0xCF0A, 0xB148, 0xCF0B, 0xB149, 0xCF0C, 0xB14A, 0xCF0D,
+	0xB14B, 0xCF0E, 0xB14C, 0xCF0F, 0xB14D, 0xCF12, 0xB14E, 0xCF14,
+	0xB14F, 0xCF16, 0xB150, 0xCF17, 0xB151, 0xCF18, 0xB152, 0xCF19,
+	0xB153, 0xCF1A, 0xB154, 0xCF1B, 0xB155, 0xCF1D, 0xB156, 0xCF1E,
+	0xB157, 0xCF1F, 0xB158, 0xCF21, 0xB159, 0xCF22, 0xB15A, 0xCF23,
+	0xB161, 0xCF25, 0xB162, 0xCF26, 0xB163, 0xCF27, 0xB164, 0xCF28,
+	0xB165, 0xCF29, 0xB166, 0xCF2A, 0xB167, 0xCF2B, 0xB168, 0xCF2E,
+	0xB169, 0xCF32, 0xB16A, 0xCF33, 0xB16B, 0xCF34, 0xB16C, 0xCF35,
+	0xB16D, 0xCF36, 0xB16E, 0xCF37, 0xB16F, 0xCF39, 0xB170, 0xCF3A,
+	0xB171, 0xCF3B, 0xB172, 0xCF3C, 0xB173, 0xCF3D, 0xB174, 0xCF3E,
+	0xB175, 0xCF3F, 0xB176, 0xCF40, 0xB177, 0xCF41, 0xB178, 0xCF42,
+	0xB179, 0xCF43, 0xB17A, 0xCF44, 0xB181, 0xCF45, 0xB182, 0xCF46,
+	0xB183, 0xCF47, 0xB184, 0xCF48, 0xB185, 0xCF49, 0xB186, 0xCF4A,
+	0xB187, 0xCF4B, 0xB188, 0xCF4C, 0xB189, 0xCF4D, 0xB18A, 0xCF4E,
+	0xB18B, 0xCF4F, 0xB18C, 0xCF50, 0xB18D, 0xCF51, 0xB18E, 0xCF52,
+	0xB18F, 0xCF53, 0xB190, 0xCF56, 0xB191, 0xCF57, 0xB192, 0xCF59,
+	0xB193, 0xCF5A, 0xB194, 0xCF5B, 0xB195, 0xCF5D, 0xB196, 0xCF5E,
+	0xB197, 0xCF5F, 0xB198, 0xCF60, 0xB199, 0xCF61, 0xB19A, 0xCF62,
+	0xB19B, 0xCF63, 0xB19C, 0xCF66, 0xB19D, 0xCF68, 0xB19E, 0xCF6A,
+	0xB19F, 0xCF6B, 0xB1A0, 0xCF6C, 0xB1A1, 0xAD0C, 0xB1A2, 0xAD0D,
+	0xB1A3, 0xAD0F, 0xB1A4, 0xAD11, 0xB1A5, 0xAD18, 0xB1A6, 0xAD1C,
+	0xB1A7, 0xAD20, 0xB1A8, 0xAD29, 0xB1A9, 0xAD2C, 0xB1AA, 0xAD2D,
+	0xB1AB, 0xAD34, 0xB1AC, 0xAD35, 0xB1AD, 0xAD38, 0xB1AE, 0xAD3C,
+	0xB1AF, 0xAD44, 0xB1B0, 0xAD45, 0xB1B1, 0xAD47, 0xB1B2, 0xAD49,
+	0xB1B3, 0xAD50, 0xB1B4, 0xAD54, 0xB1B5, 0xAD58, 0xB1B6, 0xAD61,
+	0xB1B7, 0xAD63, 0xB1B8, 0xAD6C, 0xB1B9, 0xAD6D, 0xB1BA, 0xAD70,
+	0xB1BB, 0xAD73, 0xB1BC, 0xAD74, 0xB1BD, 0xAD75, 0xB1BE, 0xAD76,
+	0xB1BF, 0xAD7B, 0xB1C0, 0xAD7C, 0xB1C1, 0xAD7D, 0xB1C2, 0xAD7F,
+	0xB1C3, 0xAD81, 0xB1C4, 0xAD82, 0xB1C5, 0xAD88, 0xB1C6, 0xAD89,
+	0xB1C7, 0xAD8C, 0xB1C8, 0xAD90, 0xB1C9, 0xAD9C, 0xB1CA, 0xAD9D,
+	0xB1CB, 0xADA4, 0xB1CC, 0xADB7, 0xB1CD, 0xADC0, 0xB1CE, 0xADC1,
+	0xB1CF, 0xADC4, 0xB1D0, 0xADC8, 0xB1D1, 0xADD0, 0xB1D2, 0xADD1,
+	0xB1D3, 0xADD3, 0xB1D4, 0xADDC, 0xB1D5, 0xADE0, 0xB1D6, 0xADE4,
+	0xB1D7, 0xADF8, 0xB1D8, 0xADF9, 0xB1D9, 0xADFC, 0xB1DA, 0xADFF,
+	0xB1DB, 0xAE00, 0xB1DC, 0xAE01, 0xB1DD, 0xAE08, 0xB1DE, 0xAE09,
+	0xB1DF, 0xAE0B, 0xB1E0, 0xAE0D, 0xB1E1, 0xAE14, 0xB1E2, 0xAE30,
+	0xB1E3, 0xAE31, 0xB1E4, 0xAE34, 0xB1E5, 0xAE37, 0xB1E6, 0xAE38,
+	0xB1E7, 0xAE3A, 0xB1E8, 0xAE40, 0xB1E9, 0xAE41, 0xB1EA, 0xAE43,
+	0xB1EB, 0xAE45, 0xB1EC, 0xAE46, 0xB1ED, 0xAE4A, 0xB1EE, 0xAE4C,
+	0xB1EF, 0xAE4D, 0xB1F0, 0xAE4E, 0xB1F1, 0xAE50, 0xB1F2, 0xAE54,
+	0xB1F3, 0xAE56, 0xB1F4, 0xAE5C, 0xB1F5, 0xAE5D, 0xB1F6, 0xAE5F,
+	0xB1F7, 0xAE60, 0xB1F8, 0xAE61, 0xB1F9, 0xAE65, 0xB1FA, 0xAE68,
+	0xB1FB, 0xAE69, 0xB1FC, 0xAE6C, 0xB1FD, 0xAE70, 0xB1FE, 0xAE78,
+	0xB241, 0xCF6D, 0xB242, 0xCF6E, 0xB243, 0xCF6F, 0xB244, 0xCF72,
+	0xB245, 0xCF73, 0xB246, 0xCF75, 0xB247, 0xCF76, 0xB248, 0xCF77,
+	0xB249, 0xCF79, 0xB24A, 0xCF7A, 0xB24B, 0xCF7B, 0xB24C, 0xCF7C,
+	0xB24D, 0xCF7D, 0xB24E, 0xCF7E, 0xB24F, 0xCF7F, 0xB250, 0xCF81,
+	0xB251, 0xCF82, 0xB252, 0xCF83, 0xB253, 0xCF84, 0xB254, 0xCF86,
+	0xB255, 0xCF87, 0xB256, 0xCF88, 0xB257, 0xCF89, 0xB258, 0xCF8A,
+	0xB259, 0xCF8B, 0xB25A, 0xCF8D, 0xB261, 0xCF8E, 0xB262, 0xCF8F,
+	0xB263, 0xCF90, 0xB264, 0xCF91, 0xB265, 0xCF92, 0xB266, 0xCF93,
+	0xB267, 0xCF94, 0xB268, 0xCF95, 0xB269, 0xCF96, 0xB26A, 0xCF97,
+	0xB26B, 0xCF98, 0xB26C, 0xCF99, 0xB26D, 0xCF9A, 0xB26E, 0xCF9B,
+	0xB26F, 0xCF9C, 0xB270, 0xCF9D, 0xB271, 0xCF9E, 0xB272, 0xCF9F,
+	0xB273, 0xCFA0, 0xB274, 0xCFA2, 0xB275, 0xCFA3, 0xB276, 0xCFA4,
+	0xB277, 0xCFA5, 0xB278, 0xCFA6, 0xB279, 0xCFA7, 0xB27A, 0xCFA9,
+	0xB281, 0xCFAA, 0xB282, 0xCFAB, 0xB283, 0xCFAC, 0xB284, 0xCFAD,
+	0xB285, 0xCFAE, 0xB286, 0xCFAF, 0xB287, 0xCFB1, 0xB288, 0xCFB2,
+	0xB289, 0xCFB3, 0xB28A, 0xCFB4, 0xB28B, 0xCFB5, 0xB28C, 0xCFB6,
+	0xB28D, 0xCFB7, 0xB28E, 0xCFB8, 0xB28F, 0xCFB9, 0xB290, 0xCFBA,
+	0xB291, 0xCFBB, 0xB292, 0xCFBC, 0xB293, 0xCFBD, 0xB294, 0xCFBE,
+	0xB295, 0xCFBF, 0xB296, 0xCFC0, 0xB297, 0xCFC1, 0xB298, 0xCFC2,
+	0xB299, 0xCFC3, 0xB29A, 0xCFC5, 0xB29B, 0xCFC6, 0xB29C, 0xCFC7,
+	0xB29D, 0xCFC8, 0xB29E, 0xCFC9, 0xB29F, 0xCFCA, 0xB2A0, 0xCFCB,
+	0xB2A1, 0xAE79, 0xB2A2, 0xAE7B, 0xB2A3, 0xAE7C, 0xB2A4, 0xAE7D,
+	0xB2A5, 0xAE84, 0xB2A6, 0xAE85, 0xB2A7, 0xAE8C, 0xB2A8, 0xAEBC,
+	0xB2A9, 0xAEBD, 0xB2AA, 0xAEBE, 0xB2AB, 0xAEC0, 0xB2AC, 0xAEC4,
+	0xB2AD, 0xAECC, 0xB2AE, 0xAECD, 0xB2AF, 0xAECF, 0xB2B0, 0xAED0,
+	0xB2B1, 0xAED1, 0xB2B2, 0xAED8, 0xB2B3, 0xAED9, 0xB2B4, 0xAEDC,
+	0xB2B5, 0xAEE8, 0xB2B6, 0xAEEB, 0xB2B7, 0xAEED, 0xB2B8, 0xAEF4,
+	0xB2B9, 0xAEF8, 0xB2BA, 0xAEFC, 0xB2BB, 0xAF07, 0xB2BC, 0xAF08,
+	0xB2BD, 0xAF0D, 0xB2BE, 0xAF10, 0xB2BF, 0xAF2C, 0xB2C0, 0xAF2D,
+	0xB2C1, 0xAF30, 0xB2C2, 0xAF32, 0xB2C3, 0xAF34, 0xB2C4, 0xAF3C,
+	0xB2C5, 0xAF3D, 0xB2C6, 0xAF3F, 0xB2C7, 0xAF41, 0xB2C8, 0xAF42,
+	0xB2C9, 0xAF43, 0xB2CA, 0xAF48, 0xB2CB, 0xAF49, 0xB2CC, 0xAF50,
+	0xB2CD, 0xAF5C, 0xB2CE, 0xAF5D, 0xB2CF, 0xAF64, 0xB2D0, 0xAF65,
+	0xB2D1, 0xAF79, 0xB2D2, 0xAF80, 0xB2D3, 0xAF84, 0xB2D4, 0xAF88,
+	0xB2D5, 0xAF90, 0xB2D6, 0xAF91, 0xB2D7, 0xAF95, 0xB2D8, 0xAF9C,
+	0xB2D9, 0xAFB8, 0xB2DA, 0xAFB9, 0xB2DB, 0xAFBC, 0xB2DC, 0xAFC0,
+	0xB2DD, 0xAFC7, 0xB2DE, 0xAFC8, 0xB2DF, 0xAFC9, 0xB2E0, 0xAFCB,
+	0xB2E1, 0xAFCD, 0xB2E2, 0xAFCE, 0xB2E3, 0xAFD4, 0xB2E4, 0xAFDC,
+	0xB2E5, 0xAFE8, 0xB2E6, 0xAFE9, 0xB2E7, 0xAFF0, 0xB2E8, 0xAFF1,
+	0xB2E9, 0xAFF4, 0xB2EA, 0xAFF8, 0xB2EB, 0xB000, 0xB2EC, 0xB001,
+	0xB2ED, 0xB004, 0xB2EE, 0xB00C, 0xB2EF, 0xB010, 0xB2F0, 0xB014,
+	0xB2F1, 0xB01C, 0xB2F2, 0xB01D, 0xB2F3, 0xB028, 0xB2F4, 0xB044,
+	0xB2F5, 0xB045, 0xB2F6, 0xB048, 0xB2F7, 0xB04A, 0xB2F8, 0xB04C,
+	0xB2F9, 0xB04E, 0xB2FA, 0xB053, 0xB2FB, 0xB054, 0xB2FC, 0xB055,
+	0xB2FD, 0xB057, 0xB2FE, 0xB059, 0xB341, 0xCFCC, 0xB342, 0xCFCD,
+	0xB343, 0xCFCE, 0xB344, 0xCFCF, 0xB345, 0xCFD0, 0xB346, 0xCFD1,
+	0xB347, 0xCFD2, 0xB348, 0xCFD3, 0xB349, 0xCFD4, 0xB34A, 0xCFD5,
+	0xB34B, 0xCFD6, 0xB34C, 0xCFD7, 0xB34D, 0xCFD8, 0xB34E, 0xCFD9,
+	0xB34F, 0xCFDA, 0xB350, 0xCFDB, 0xB351, 0xCFDC, 0xB352, 0xCFDD,
+	0xB353, 0xCFDE, 0xB354, 0xCFDF, 0xB355, 0xCFE2, 0xB356, 0xCFE3,
+	0xB357, 0xCFE5, 0xB358, 0xCFE6, 0xB359, 0xCFE7, 0xB35A, 0xCFE9,
+	0xB361, 0xCFEA, 0xB362, 0xCFEB, 0xB363, 0xCFEC, 0xB364, 0xCFED,
+	0xB365, 0xCFEE, 0xB366, 0xCFEF, 0xB367, 0xCFF2, 0xB368, 0xCFF4,
+	0xB369, 0xCFF6, 0xB36A, 0xCFF7, 0xB36B, 0xCFF8, 0xB36C, 0xCFF9,
+	0xB36D, 0xCFFA, 0xB36E, 0xCFFB, 0xB36F, 0xCFFD, 0xB370, 0xCFFE,
+	0xB371, 0xCFFF, 0xB372, 0xD001, 0xB373, 0xD002, 0xB374, 0xD003,
+	0xB375, 0xD005, 0xB376, 0xD006, 0xB377, 0xD007, 0xB378, 0xD008,
+	0xB379, 0xD009, 0xB37A, 0xD00A, 0xB381, 0xD00B, 0xB382, 0xD00C,
+	0xB383, 0xD00D, 0xB384, 0xD00E, 0xB385, 0xD00F, 0xB386, 0xD010,
+	0xB387, 0xD012, 0xB388, 0xD013, 0xB389, 0xD014, 0xB38A, 0xD015,
+	0xB38B, 0xD016, 0xB38C, 0xD017, 0xB38D, 0xD019, 0xB38E, 0xD01A,
+	0xB38F, 0xD01B, 0xB390, 0xD01C, 0xB391, 0xD01D, 0xB392, 0xD01E,
+	0xB393, 0xD01F, 0xB394, 0xD020, 0xB395, 0xD021, 0xB396, 0xD022,
+	0xB397, 0xD023, 0xB398, 0xD024, 0xB399, 0xD025, 0xB39A, 0xD026,
+	0xB39B, 0xD027, 0xB39C, 0xD028, 0xB39D, 0xD029, 0xB39E, 0xD02A,
+	0xB39F, 0xD02B, 0xB3A0, 0xD02C, 0xB3A1, 0xB05D, 0xB3A2, 0xB07C,
+	0xB3A3, 0xB07D, 0xB3A4, 0xB080, 0xB3A5, 0xB084, 0xB3A6, 0xB08C,
+	0xB3A7, 0xB08D, 0xB3A8, 0xB08F, 0xB3A9, 0xB091, 0xB3AA, 0xB098,
+	0xB3AB, 0xB099, 0xB3AC, 0xB09A, 0xB3AD, 0xB09C, 0xB3AE, 0xB09F,
+	0xB3AF, 0xB0A0, 0xB3B0, 0xB0A1, 0xB3B1, 0xB0A2, 0xB3B2, 0xB0A8,
+	0xB3B3, 0xB0A9, 0xB3B4, 0xB0AB, 0xB3B5, 0xB0AC, 0xB3B6, 0xB0AD,
+	0xB3B7, 0xB0AE, 0xB3B8, 0xB0AF, 0xB3B9, 0xB0B1, 0xB3BA, 0xB0B3,
+	0xB3BB, 0xB0B4, 0xB3BC, 0xB0B5, 0xB3BD, 0xB0B8, 0xB3BE, 0xB0BC,
+	0xB3BF, 0xB0C4, 0xB3C0, 0xB0C5, 0xB3C1, 0xB0C7, 0xB3C2, 0xB0C8,
+	0xB3C3, 0xB0C9, 0xB3C4, 0xB0D0, 0xB3C5, 0xB0D1, 0xB3C6, 0xB0D4,
+	0xB3C7, 0xB0D8, 0xB3C8, 0xB0E0, 0xB3C9, 0xB0E5, 0xB3CA, 0xB108,
+	0xB3CB, 0xB109, 0xB3CC, 0xB10B, 0xB3CD, 0xB10C, 0xB3CE, 0xB110,
+	0xB3CF, 0xB112, 0xB3D0, 0xB113, 0xB3D1, 0xB118, 0xB3D2, 0xB119,
+	0xB3D3, 0xB11B, 0xB3D4, 0xB11C, 0xB3D5, 0xB11D, 0xB3D6, 0xB123,
+	0xB3D7, 0xB124, 0xB3D8, 0xB125, 0xB3D9, 0xB128, 0xB3DA, 0xB12C,
+	0xB3DB, 0xB134, 0xB3DC, 0xB135, 0xB3DD, 0xB137, 0xB3DE, 0xB138,
+	0xB3DF, 0xB139, 0xB3E0, 0xB140, 0xB3E1, 0xB141, 0xB3E2, 0xB144,
+	0xB3E3, 0xB148, 0xB3E4, 0xB150, 0xB3E5, 0xB151, 0xB3E6, 0xB154,
+	0xB3E7, 0xB155, 0xB3E8, 0xB158, 0xB3E9, 0xB15C, 0xB3EA, 0xB160,
+	0xB3EB, 0xB178, 0xB3EC, 0xB179, 0xB3ED, 0xB17C, 0xB3EE, 0xB180,
+	0xB3EF, 0xB182, 0xB3F0, 0xB188, 0xB3F1, 0xB189, 0xB3F2, 0xB18B,
+	0xB3F3, 0xB18D, 0xB3F4, 0xB192, 0xB3F5, 0xB193, 0xB3F6, 0xB194,
+	0xB3F7, 0xB198, 0xB3F8, 0xB19C, 0xB3F9, 0xB1A8, 0xB3FA, 0xB1CC,
+	0xB3FB, 0xB1D0, 0xB3FC, 0xB1D4, 0xB3FD, 0xB1DC, 0xB3FE, 0xB1DD,
+	0xB441, 0xD02E, 0xB442, 0xD02F, 0xB443, 0xD030, 0xB444, 0xD031,
+	0xB445, 0xD032, 0xB446, 0xD033, 0xB447, 0xD036, 0xB448, 0xD037,
+	0xB449, 0xD039, 0xB44A, 0xD03A, 0xB44B, 0xD03B, 0xB44C, 0xD03D,
+	0xB44D, 0xD03E, 0xB44E, 0xD03F, 0xB44F, 0xD040, 0xB450, 0xD041,
+	0xB451, 0xD042, 0xB452, 0xD043, 0xB453, 0xD046, 0xB454, 0xD048,
+	0xB455, 0xD04A, 0xB456, 0xD04B, 0xB457, 0xD04C, 0xB458, 0xD04D,
+	0xB459, 0xD04E, 0xB45A, 0xD04F, 0xB461, 0xD051, 0xB462, 0xD052,
+	0xB463, 0xD053, 0xB464, 0xD055, 0xB465, 0xD056, 0xB466, 0xD057,
+	0xB467, 0xD059, 0xB468, 0xD05A, 0xB469, 0xD05B, 0xB46A, 0xD05C,
+	0xB46B, 0xD05D, 0xB46C, 0xD05E, 0xB46D, 0xD05F, 0xB46E, 0xD061,
+	0xB46F, 0xD062, 0xB470, 0xD063, 0xB471, 0xD064, 0xB472, 0xD065,
+	0xB473, 0xD066, 0xB474, 0xD067, 0xB475, 0xD068, 0xB476, 0xD069,
+	0xB477, 0xD06A, 0xB478, 0xD06B, 0xB479, 0xD06E, 0xB47A, 0xD06F,
+	0xB481, 0xD071, 0xB482, 0xD072, 0xB483, 0xD073, 0xB484, 0xD075,
+	0xB485, 0xD076, 0xB486, 0xD077, 0xB487, 0xD078, 0xB488, 0xD079,
+	0xB489, 0xD07A, 0xB48A, 0xD07B, 0xB48B, 0xD07E, 0xB48C, 0xD07F,
+	0xB48D, 0xD080, 0xB48E, 0xD082, 0xB48F, 0xD083, 0xB490, 0xD084,
+	0xB491, 0xD085, 0xB492, 0xD086, 0xB493, 0xD087, 0xB494, 0xD088,
+	0xB495, 0xD089, 0xB496, 0xD08A, 0xB497, 0xD08B, 0xB498, 0xD08C,
+	0xB499, 0xD08D, 0xB49A, 0xD08E, 0xB49B, 0xD08F, 0xB49C, 0xD090,
+	0xB49D, 0xD091, 0xB49E, 0xD092, 0xB49F, 0xD093, 0xB4A0, 0xD094,
+	0xB4A1, 0xB1DF, 0xB4A2, 0xB1E8, 0xB4A3, 0xB1E9, 0xB4A4, 0xB1EC,
+	0xB4A5, 0xB1F0, 0xB4A6, 0xB1F9, 0xB4A7, 0xB1FB, 0xB4A8, 0xB1FD,
+	0xB4A9, 0xB204, 0xB4AA, 0xB205, 0xB4AB, 0xB208, 0xB4AC, 0xB20B,
+	0xB4AD, 0xB20C, 0xB4AE, 0xB214, 0xB4AF, 0xB215, 0xB4B0, 0xB217,
+	0xB4B1, 0xB219, 0xB4B2, 0xB220, 0xB4B3, 0xB234, 0xB4B4, 0xB23C,
+	0xB4B5, 0xB258, 0xB4B6, 0xB25C, 0xB4B7, 0xB260, 0xB4B8, 0xB268,
+	0xB4B9, 0xB269, 0xB4BA, 0xB274, 0xB4BB, 0xB275, 0xB4BC, 0xB27C,
+	0xB4BD, 0xB284, 0xB4BE, 0xB285, 0xB4BF, 0xB289, 0xB4C0, 0xB290,
+	0xB4C1, 0xB291, 0xB4C2, 0xB294, 0xB4C3, 0xB298, 0xB4C4, 0xB299,
+	0xB4C5, 0xB29A, 0xB4C6, 0xB2A0, 0xB4C7, 0xB2A1, 0xB4C8, 0xB2A3,
+	0xB4C9, 0xB2A5, 0xB4CA, 0xB2A6, 0xB4CB, 0xB2AA, 0xB4CC, 0xB2AC,
+	0xB4CD, 0xB2B0, 0xB4CE, 0xB2B4, 0xB4CF, 0xB2C8, 0xB4D0, 0xB2C9,
+	0xB4D1, 0xB2CC, 0xB4D2, 0xB2D0, 0xB4D3, 0xB2D2, 0xB4D4, 0xB2D8,
+	0xB4D5, 0xB2D9, 0xB4D6, 0xB2DB, 0xB4D7, 0xB2DD, 0xB4D8, 0xB2E2,
+	0xB4D9, 0xB2E4, 0xB4DA, 0xB2E5, 0xB4DB, 0xB2E6, 0xB4DC, 0xB2E8,
+	0xB4DD, 0xB2EB, 0xB4DE, 0xB2EC, 0xB4DF, 0xB2ED, 0xB4E0, 0xB2EE,
+	0xB4E1, 0xB2EF, 0xB4E2, 0xB2F3, 0xB4E3, 0xB2F4, 0xB4E4, 0xB2F5,
+	0xB4E5, 0xB2F7, 0xB4E6, 0xB2F8, 0xB4E7, 0xB2F9, 0xB4E8, 0xB2FA,
+	0xB4E9, 0xB2FB, 0xB4EA, 0xB2FF, 0xB4EB, 0xB300, 0xB4EC, 0xB301,
+	0xB4ED, 0xB304, 0xB4EE, 0xB308, 0xB4EF, 0xB310, 0xB4F0, 0xB311,
+	0xB4F1, 0xB313, 0xB4F2, 0xB314, 0xB4F3, 0xB315, 0xB4F4, 0xB31C,
+	0xB4F5, 0xB354, 0xB4F6, 0xB355, 0xB4F7, 0xB356, 0xB4F8, 0xB358,
+	0xB4F9, 0xB35B, 0xB4FA, 0xB35C, 0xB4FB, 0xB35E, 0xB4FC, 0xB35F,
+	0xB4FD, 0xB364, 0xB4FE, 0xB365, 0xB541, 0xD095, 0xB542, 0xD096,
+	0xB543, 0xD097, 0xB544, 0xD098, 0xB545, 0xD099, 0xB546, 0xD09A,
+	0xB547, 0xD09B, 0xB548, 0xD09C, 0xB549, 0xD09D, 0xB54A, 0xD09E,
+	0xB54B, 0xD09F, 0xB54C, 0xD0A0, 0xB54D, 0xD0A1, 0xB54E, 0xD0A2,
+	0xB54F, 0xD0A3, 0xB550, 0xD0A6, 0xB551, 0xD0A7, 0xB552, 0xD0A9,
+	0xB553, 0xD0AA, 0xB554, 0xD0AB, 0xB555, 0xD0AD, 0xB556, 0xD0AE,
+	0xB557, 0xD0AF, 0xB558, 0xD0B0, 0xB559, 0xD0B1, 0xB55A, 0xD0B2,
+	0xB561, 0xD0B3, 0xB562, 0xD0B6, 0xB563, 0xD0B8, 0xB564, 0xD0BA,
+	0xB565, 0xD0BB, 0xB566, 0xD0BC, 0xB567, 0xD0BD, 0xB568, 0xD0BE,
+	0xB569, 0xD0BF, 0xB56A, 0xD0C2, 0xB56B, 0xD0C3, 0xB56C, 0xD0C5,
+	0xB56D, 0xD0C6, 0xB56E, 0xD0C7, 0xB56F, 0xD0CA, 0xB570, 0xD0CB,
+	0xB571, 0xD0CC, 0xB572, 0xD0CD, 0xB573, 0xD0CE, 0xB574, 0xD0CF,
+	0xB575, 0xD0D2, 0xB576, 0xD0D6, 0xB577, 0xD0D7, 0xB578, 0xD0D8,
+	0xB579, 0xD0D9, 0xB57A, 0xD0DA, 0xB581, 0xD0DB, 0xB582, 0xD0DE,
+	0xB583, 0xD0DF, 0xB584, 0xD0E1, 0xB585, 0xD0E2, 0xB586, 0xD0E3,
+	0xB587, 0xD0E5, 0xB588, 0xD0E6, 0xB589, 0xD0E7, 0xB58A, 0xD0E8,
+	0xB58B, 0xD0E9, 0xB58C, 0xD0EA, 0xB58D, 0xD0EB, 0xB58E, 0xD0EE,
+	0xB58F, 0xD0F2, 0xB590, 0xD0F3, 0xB591, 0xD0F4, 0xB592, 0xD0F5,
+	0xB593, 0xD0F6, 0xB594, 0xD0F7, 0xB595, 0xD0F9, 0xB596, 0xD0FA,
+	0xB597, 0xD0FB, 0xB598, 0xD0FC, 0xB599, 0xD0FD, 0xB59A, 0xD0FE,
+	0xB59B, 0xD0FF, 0xB59C, 0xD100, 0xB59D, 0xD101, 0xB59E, 0xD102,
+	0xB59F, 0xD103, 0xB5A0, 0xD104, 0xB5A1, 0xB367, 0xB5A2, 0xB369,
+	0xB5A3, 0xB36B, 0xB5A4, 0xB36E, 0xB5A5, 0xB370, 0xB5A6, 0xB371,
+	0xB5A7, 0xB374, 0xB5A8, 0xB378, 0xB5A9, 0xB380, 0xB5AA, 0xB381,
+	0xB5AB, 0xB383, 0xB5AC, 0xB384, 0xB5AD, 0xB385, 0xB5AE, 0xB38C,
+	0xB5AF, 0xB390, 0xB5B0, 0xB394, 0xB5B1, 0xB3A0, 0xB5B2, 0xB3A1,
+	0xB5B3, 0xB3A8, 0xB5B4, 0xB3AC, 0xB5B5, 0xB3C4, 0xB5B6, 0xB3C5,
+	0xB5B7, 0xB3C8, 0xB5B8, 0xB3CB, 0xB5B9, 0xB3CC, 0xB5BA, 0xB3CE,
+	0xB5BB, 0xB3D0, 0xB5BC, 0xB3D4, 0xB5BD, 0xB3D5, 0xB5BE, 0xB3D7,
+	0xB5BF, 0xB3D9, 0xB5C0, 0xB3DB, 0xB5C1, 0xB3DD, 0xB5C2, 0xB3E0,
+	0xB5C3, 0xB3E4, 0xB5C4, 0xB3E8, 0xB5C5, 0xB3FC, 0xB5C6, 0xB410,
+	0xB5C7, 0xB418, 0xB5C8, 0xB41C, 0xB5C9, 0xB420, 0xB5CA, 0xB428,
+	0xB5CB, 0xB429, 0xB5CC, 0xB42B, 0xB5CD, 0xB434, 0xB5CE, 0xB450,
+	0xB5CF, 0xB451, 0xB5D0, 0xB454, 0xB5D1, 0xB458, 0xB5D2, 0xB460,
+	0xB5D3, 0xB461, 0xB5D4, 0xB463, 0xB5D5, 0xB465, 0xB5D6, 0xB46C,
+	0xB5D7, 0xB480, 0xB5D8, 0xB488, 0xB5D9, 0xB49D, 0xB5DA, 0xB4A4,
+	0xB5DB, 0xB4A8, 0xB5DC, 0xB4AC, 0xB5DD, 0xB4B5, 0xB5DE, 0xB4B7,
+	0xB5DF, 0xB4B9, 0xB5E0, 0xB4C0, 0xB5E1, 0xB4C4, 0xB5E2, 0xB4C8,
+	0xB5E3, 0xB4D0, 0xB5E4, 0xB4D5, 0xB5E5, 0xB4DC, 0xB5E6, 0xB4DD,
+	0xB5E7, 0xB4E0, 0xB5E8, 0xB4E3, 0xB5E9, 0xB4E4, 0xB5EA, 0xB4E6,
+	0xB5EB, 0xB4EC, 0xB5EC, 0xB4ED, 0xB5ED, 0xB4EF, 0xB5EE, 0xB4F1,
+	0xB5EF, 0xB4F8, 0xB5F0, 0xB514, 0xB5F1, 0xB515, 0xB5F2, 0xB518,
+	0xB5F3, 0xB51B, 0xB5F4, 0xB51C, 0xB5F5, 0xB524, 0xB5F6, 0xB525,
+	0xB5F7, 0xB527, 0xB5F8, 0xB528, 0xB5F9, 0xB529, 0xB5FA, 0xB52A,
+	0xB5FB, 0xB530, 0xB5FC, 0xB531, 0xB5FD, 0xB534, 0xB5FE, 0xB538,
+	0xB641, 0xD105, 0xB642, 0xD106, 0xB643, 0xD107, 0xB644, 0xD108,
+	0xB645, 0xD109, 0xB646, 0xD10A, 0xB647, 0xD10B, 0xB648, 0xD10C,
+	0xB649, 0xD10E, 0xB64A, 0xD10F, 0xB64B, 0xD110, 0xB64C, 0xD111,
+	0xB64D, 0xD112, 0xB64E, 0xD113, 0xB64F, 0xD114, 0xB650, 0xD115,
+	0xB651, 0xD116, 0xB652, 0xD117, 0xB653, 0xD118, 0xB654, 0xD119,
+	0xB655, 0xD11A, 0xB656, 0xD11B, 0xB657, 0xD11C, 0xB658, 0xD11D,
+	0xB659, 0xD11E, 0xB65A, 0xD11F, 0xB661, 0xD120, 0xB662, 0xD121,
+	0xB663, 0xD122, 0xB664, 0xD123, 0xB665, 0xD124, 0xB666, 0xD125,
+	0xB667, 0xD126, 0xB668, 0xD127, 0xB669, 0xD128, 0xB66A, 0xD129,
+	0xB66B, 0xD12A, 0xB66C, 0xD12B, 0xB66D, 0xD12C, 0xB66E, 0xD12D,
+	0xB66F, 0xD12E, 0xB670, 0xD12F, 0xB671, 0xD132, 0xB672, 0xD133,
+	0xB673, 0xD135, 0xB674, 0xD136, 0xB675, 0xD137, 0xB676, 0xD139,
+	0xB677, 0xD13B, 0xB678, 0xD13C, 0xB679, 0xD13D, 0xB67A, 0xD13E,
+	0xB681, 0xD13F, 0xB682, 0xD142, 0xB683, 0xD146, 0xB684, 0xD147,
+	0xB685, 0xD148, 0xB686, 0xD149, 0xB687, 0xD14A, 0xB688, 0xD14B,
+	0xB689, 0xD14E, 0xB68A, 0xD14F, 0xB68B, 0xD151, 0xB68C, 0xD152,
+	0xB68D, 0xD153, 0xB68E, 0xD155, 0xB68F, 0xD156, 0xB690, 0xD157,
+	0xB691, 0xD158, 0xB692, 0xD159, 0xB693, 0xD15A, 0xB694, 0xD15B,
+	0xB695, 0xD15E, 0xB696, 0xD160, 0xB697, 0xD162, 0xB698, 0xD163,
+	0xB699, 0xD164, 0xB69A, 0xD165, 0xB69B, 0xD166, 0xB69C, 0xD167,
+	0xB69D, 0xD169, 0xB69E, 0xD16A, 0xB69F, 0xD16B, 0xB6A0, 0xD16D,
+	0xB6A1, 0xB540, 0xB6A2, 0xB541, 0xB6A3, 0xB543, 0xB6A4, 0xB544,
+	0xB6A5, 0xB545, 0xB6A6, 0xB54B, 0xB6A7, 0xB54C, 0xB6A8, 0xB54D,
+	0xB6A9, 0xB550, 0xB6AA, 0xB554, 0xB6AB, 0xB55C, 0xB6AC, 0xB55D,
+	0xB6AD, 0xB55F, 0xB6AE, 0xB560, 0xB6AF, 0xB561, 0xB6B0, 0xB5A0,
+	0xB6B1, 0xB5A1, 0xB6B2, 0xB5A4, 0xB6B3, 0xB5A8, 0xB6B4, 0xB5AA,
+	0xB6B5, 0xB5AB, 0xB6B6, 0xB5B0, 0xB6B7, 0xB5B1, 0xB6B8, 0xB5B3,
+	0xB6B9, 0xB5B4, 0xB6BA, 0xB5B5, 0xB6BB, 0xB5BB, 0xB6BC, 0xB5BC,
+	0xB6BD, 0xB5BD, 0xB6BE, 0xB5C0, 0xB6BF, 0xB5C4, 0xB6C0, 0xB5CC,
+	0xB6C1, 0xB5CD, 0xB6C2, 0xB5CF, 0xB6C3, 0xB5D0, 0xB6C4, 0xB5D1,
+	0xB6C5, 0xB5D8, 0xB6C6, 0xB5EC, 0xB6C7, 0xB610, 0xB6C8, 0xB611,
+	0xB6C9, 0xB614, 0xB6CA, 0xB618, 0xB6CB, 0xB625, 0xB6CC, 0xB62C,
+	0xB6CD, 0xB634, 0xB6CE, 0xB648, 0xB6CF, 0xB664, 0xB6D0, 0xB668,
+	0xB6D1, 0xB69C, 0xB6D2, 0xB69D, 0xB6D3, 0xB6A0, 0xB6D4, 0xB6A4,
+	0xB6D5, 0xB6AB, 0xB6D6, 0xB6AC, 0xB6D7, 0xB6B1, 0xB6D8, 0xB6D4,
+	0xB6D9, 0xB6F0, 0xB6DA, 0xB6F4, 0xB6DB, 0xB6F8, 0xB6DC, 0xB700,
+	0xB6DD, 0xB701, 0xB6DE, 0xB705, 0xB6DF, 0xB728, 0xB6E0, 0xB729,
+	0xB6E1, 0xB72C, 0xB6E2, 0xB72F, 0xB6E3, 0xB730, 0xB6E4, 0xB738,
+	0xB6E5, 0xB739, 0xB6E6, 0xB73B, 0xB6E7, 0xB744, 0xB6E8, 0xB748,
+	0xB6E9, 0xB74C, 0xB6EA, 0xB754, 0xB6EB, 0xB755, 0xB6EC, 0xB760,
+	0xB6ED, 0xB764, 0xB6EE, 0xB768, 0xB6EF, 0xB770, 0xB6F0, 0xB771,
+	0xB6F1, 0xB773, 0xB6F2, 0xB775, 0xB6F3, 0xB77C, 0xB6F4, 0xB77D,
+	0xB6F5, 0xB780, 0xB6F6, 0xB784, 0xB6F7, 0xB78C, 0xB6F8, 0xB78D,
+	0xB6F9, 0xB78F, 0xB6FA, 0xB790, 0xB6FB, 0xB791, 0xB6FC, 0xB792,
+	0xB6FD, 0xB796, 0xB6FE, 0xB797, 0xB741, 0xD16E, 0xB742, 0xD16F,
+	0xB743, 0xD170, 0xB744, 0xD171, 0xB745, 0xD172, 0xB746, 0xD173,
+	0xB747, 0xD174, 0xB748, 0xD175, 0xB749, 0xD176, 0xB74A, 0xD177,
+	0xB74B, 0xD178, 0xB74C, 0xD179, 0xB74D, 0xD17A, 0xB74E, 0xD17B,
+	0xB74F, 0xD17D, 0xB750, 0xD17E, 0xB751, 0xD17F, 0xB752, 0xD180,
+	0xB753, 0xD181, 0xB754, 0xD182, 0xB755, 0xD183, 0xB756, 0xD185,
+	0xB757, 0xD186, 0xB758, 0xD187, 0xB759, 0xD189, 0xB75A, 0xD18A,
+	0xB761, 0xD18B, 0xB762, 0xD18C, 0xB763, 0xD18D, 0xB764, 0xD18E,
+	0xB765, 0xD18F, 0xB766, 0xD190, 0xB767, 0xD191, 0xB768, 0xD192,
+	0xB769, 0xD193, 0xB76A, 0xD194, 0xB76B, 0xD195, 0xB76C, 0xD196,
+	0xB76D, 0xD197, 0xB76E, 0xD198, 0xB76F, 0xD199, 0xB770, 0xD19A,
+	0xB771, 0xD19B, 0xB772, 0xD19C, 0xB773, 0xD19D, 0xB774, 0xD19E,
+	0xB775, 0xD19F, 0xB776, 0xD1A2, 0xB777, 0xD1A3, 0xB778, 0xD1A5,
+	0xB779, 0xD1A6, 0xB77A, 0xD1A7, 0xB781, 0xD1A9, 0xB782, 0xD1AA,
+	0xB783, 0xD1AB, 0xB784, 0xD1AC, 0xB785, 0xD1AD, 0xB786, 0xD1AE,
+	0xB787, 0xD1AF, 0xB788, 0xD1B2, 0xB789, 0xD1B4, 0xB78A, 0xD1B6,
+	0xB78B, 0xD1B7, 0xB78C, 0xD1B8, 0xB78D, 0xD1B9, 0xB78E, 0xD1BB,
+	0xB78F, 0xD1BD, 0xB790, 0xD1BE, 0xB791, 0xD1BF, 0xB792, 0xD1C1,
+	0xB793, 0xD1C2, 0xB794, 0xD1C3, 0xB795, 0xD1C4, 0xB796, 0xD1C5,
+	0xB797, 0xD1C6, 0xB798, 0xD1C7, 0xB799, 0xD1C8, 0xB79A, 0xD1C9,
+	0xB79B, 0xD1CA, 0xB79C, 0xD1CB, 0xB79D, 0xD1CC, 0xB79E, 0xD1CD,
+	0xB79F, 0xD1CE, 0xB7A0, 0xD1CF, 0xB7A1, 0xB798, 0xB7A2, 0xB799,
+	0xB7A3, 0xB79C, 0xB7A4, 0xB7A0, 0xB7A5, 0xB7A8, 0xB7A6, 0xB7A9,
+	0xB7A7, 0xB7AB, 0xB7A8, 0xB7AC, 0xB7A9, 0xB7AD, 0xB7AA, 0xB7B4,
+	0xB7AB, 0xB7B5, 0xB7AC, 0xB7B8, 0xB7AD, 0xB7C7, 0xB7AE, 0xB7C9,
+	0xB7AF, 0xB7EC, 0xB7B0, 0xB7ED, 0xB7B1, 0xB7F0, 0xB7B2, 0xB7F4,
+	0xB7B3, 0xB7FC, 0xB7B4, 0xB7FD, 0xB7B5, 0xB7FF, 0xB7B6, 0xB800,
+	0xB7B7, 0xB801, 0xB7B8, 0xB807, 0xB7B9, 0xB808, 0xB7BA, 0xB809,
+	0xB7BB, 0xB80C, 0xB7BC, 0xB810, 0xB7BD, 0xB818, 0xB7BE, 0xB819,
+	0xB7BF, 0xB81B, 0xB7C0, 0xB81D, 0xB7C1, 0xB824, 0xB7C2, 0xB825,
+	0xB7C3, 0xB828, 0xB7C4, 0xB82C, 0xB7C5, 0xB834, 0xB7C6, 0xB835,
+	0xB7C7, 0xB837, 0xB7C8, 0xB838, 0xB7C9, 0xB839, 0xB7CA, 0xB840,
+	0xB7CB, 0xB844, 0xB7CC, 0xB851, 0xB7CD, 0xB853, 0xB7CE, 0xB85C,
+	0xB7CF, 0xB85D, 0xB7D0, 0xB860, 0xB7D1, 0xB864, 0xB7D2, 0xB86C,
+	0xB7D3, 0xB86D, 0xB7D4, 0xB86F, 0xB7D5, 0xB871, 0xB7D6, 0xB878,
+	0xB7D7, 0xB87C, 0xB7D8, 0xB88D, 0xB7D9, 0xB8A8, 0xB7DA, 0xB8B0,
+	0xB7DB, 0xB8B4, 0xB7DC, 0xB8B8, 0xB7DD, 0xB8C0, 0xB7DE, 0xB8C1,
+	0xB7DF, 0xB8C3, 0xB7E0, 0xB8C5, 0xB7E1, 0xB8CC, 0xB7E2, 0xB8D0,
+	0xB7E3, 0xB8D4, 0xB7E4, 0xB8DD, 0xB7E5, 0xB8DF, 0xB7E6, 0xB8E1,
+	0xB7E7, 0xB8E8, 0xB7E8, 0xB8E9, 0xB7E9, 0xB8EC, 0xB7EA, 0xB8F0,
+	0xB7EB, 0xB8F8, 0xB7EC, 0xB8F9, 0xB7ED, 0xB8FB, 0xB7EE, 0xB8FD,
+	0xB7EF, 0xB904, 0xB7F0, 0xB918, 0xB7F1, 0xB920, 0xB7F2, 0xB93C,
+	0xB7F3, 0xB93D, 0xB7F4, 0xB940, 0xB7F5, 0xB944, 0xB7F6, 0xB94C,
+	0xB7F7, 0xB94F, 0xB7F8, 0xB951, 0xB7F9, 0xB958, 0xB7FA, 0xB959,
+	0xB7FB, 0xB95C, 0xB7FC, 0xB960, 0xB7FD, 0xB968, 0xB7FE, 0xB969,
+	0xB841, 0xD1D0, 0xB842, 0xD1D1, 0xB843, 0xD1D2, 0xB844, 0xD1D3,
+	0xB845, 0xD1D4, 0xB846, 0xD1D5, 0xB847, 0xD1D6, 0xB848, 0xD1D7,
+	0xB849, 0xD1D9, 0xB84A, 0xD1DA, 0xB84B, 0xD1DB, 0xB84C, 0xD1DC,
+	0xB84D, 0xD1DD, 0xB84E, 0xD1DE, 0xB84F, 0xD1DF, 0xB850, 0xD1E0,
+	0xB851, 0xD1E1, 0xB852, 0xD1E2, 0xB853, 0xD1E3, 0xB854, 0xD1E4,
+	0xB855, 0xD1E5, 0xB856, 0xD1E6, 0xB857, 0xD1E7, 0xB858, 0xD1E8,
+	0xB859, 0xD1E9, 0xB85A, 0xD1EA, 0xB861, 0xD1EB, 0xB862, 0xD1EC,
+	0xB863, 0xD1ED, 0xB864, 0xD1EE, 0xB865, 0xD1EF, 0xB866, 0xD1F0,
+	0xB867, 0xD1F1, 0xB868, 0xD1F2, 0xB869, 0xD1F3, 0xB86A, 0xD1F5,
+	0xB86B, 0xD1F6, 0xB86C, 0xD1F7, 0xB86D, 0xD1F9, 0xB86E, 0xD1FA,
+	0xB86F, 0xD1FB, 0xB870, 0xD1FC, 0xB871, 0xD1FD, 0xB872, 0xD1FE,
+	0xB873, 0xD1FF, 0xB874, 0xD200, 0xB875, 0xD201, 0xB876, 0xD202,
+	0xB877, 0xD203, 0xB878, 0xD204, 0xB879, 0xD205, 0xB87A, 0xD206,
+	0xB881, 0xD208, 0xB882, 0xD20A, 0xB883, 0xD20B, 0xB884, 0xD20C,
+	0xB885, 0xD20D, 0xB886, 0xD20E, 0xB887, 0xD20F, 0xB888, 0xD211,
+	0xB889, 0xD212, 0xB88A, 0xD213, 0xB88B, 0xD214, 0xB88C, 0xD215,
+	0xB88D, 0xD216, 0xB88E, 0xD217, 0xB88F, 0xD218, 0xB890, 0xD219,
+	0xB891, 0xD21A, 0xB892, 0xD21B, 0xB893, 0xD21C, 0xB894, 0xD21D,
+	0xB895, 0xD21E, 0xB896, 0xD21F, 0xB897, 0xD220, 0xB898, 0xD221,
+	0xB899, 0xD222, 0xB89A, 0xD223, 0xB89B, 0xD224, 0xB89C, 0xD225,
+	0xB89D, 0xD226, 0xB89E, 0xD227, 0xB89F, 0xD228, 0xB8A0, 0xD229,
+	0xB8A1, 0xB96B, 0xB8A2, 0xB96D, 0xB8A3, 0xB974, 0xB8A4, 0xB975,
+	0xB8A5, 0xB978, 0xB8A6, 0xB97C, 0xB8A7, 0xB984, 0xB8A8, 0xB985,
+	0xB8A9, 0xB987, 0xB8AA, 0xB989, 0xB8AB, 0xB98A, 0xB8AC, 0xB98D,
+	0xB8AD, 0xB98E, 0xB8AE, 0xB9AC, 0xB8AF, 0xB9AD, 0xB8B0, 0xB9B0,
+	0xB8B1, 0xB9B4, 0xB8B2, 0xB9BC, 0xB8B3, 0xB9BD, 0xB8B4, 0xB9BF,
+	0xB8B5, 0xB9C1, 0xB8B6, 0xB9C8, 0xB8B7, 0xB9C9, 0xB8B8, 0xB9CC,
+	0xB8B9, 0xB9CE, 0xB8BA, 0xB9CF, 0xB8BB, 0xB9D0, 0xB8BC, 0xB9D1,
+	0xB8BD, 0xB9D2, 0xB8BE, 0xB9D8, 0xB8BF, 0xB9D9, 0xB8C0, 0xB9DB,
+	0xB8C1, 0xB9DD, 0xB8C2, 0xB9DE, 0xB8C3, 0xB9E1, 0xB8C4, 0xB9E3,
+	0xB8C5, 0xB9E4, 0xB8C6, 0xB9E5, 0xB8C7, 0xB9E8, 0xB8C8, 0xB9EC,
+	0xB8C9, 0xB9F4, 0xB8CA, 0xB9F5, 0xB8CB, 0xB9F7, 0xB8CC, 0xB9F8,
+	0xB8CD, 0xB9F9, 0xB8CE, 0xB9FA, 0xB8CF, 0xBA00, 0xB8D0, 0xBA01,
+	0xB8D1, 0xBA08, 0xB8D2, 0xBA15, 0xB8D3, 0xBA38, 0xB8D4, 0xBA39,
+	0xB8D5, 0xBA3C, 0xB8D6, 0xBA40, 0xB8D7, 0xBA42, 0xB8D8, 0xBA48,
+	0xB8D9, 0xBA49, 0xB8DA, 0xBA4B, 0xB8DB, 0xBA4D, 0xB8DC, 0xBA4E,
+	0xB8DD, 0xBA53, 0xB8DE, 0xBA54, 0xB8DF, 0xBA55, 0xB8E0, 0xBA58,
+	0xB8E1, 0xBA5C, 0xB8E2, 0xBA64, 0xB8E3, 0xBA65, 0xB8E4, 0xBA67,
+	0xB8E5, 0xBA68, 0xB8E6, 0xBA69, 0xB8E7, 0xBA70, 0xB8E8, 0xBA71,
+	0xB8E9, 0xBA74, 0xB8EA, 0xBA78, 0xB8EB, 0xBA83, 0xB8EC, 0xBA84,
+	0xB8ED, 0xBA85, 0xB8EE, 0xBA87, 0xB8EF, 0xBA8C, 0xB8F0, 0xBAA8,
+	0xB8F1, 0xBAA9, 0xB8F2, 0xBAAB, 0xB8F3, 0xBAAC, 0xB8F4, 0xBAB0,
+	0xB8F5, 0xBAB2, 0xB8F6, 0xBAB8, 0xB8F7, 0xBAB9, 0xB8F8, 0xBABB,
+	0xB8F9, 0xBABD, 0xB8FA, 0xBAC4, 0xB8FB, 0xBAC8, 0xB8FC, 0xBAD8,
+	0xB8FD, 0xBAD9, 0xB8FE, 0xBAFC, 0xB941, 0xD22A, 0xB942, 0xD22B,
+	0xB943, 0xD22E, 0xB944, 0xD22F, 0xB945, 0xD231, 0xB946, 0xD232,
+	0xB947, 0xD233, 0xB948, 0xD235, 0xB949, 0xD236, 0xB94A, 0xD237,
+	0xB94B, 0xD238, 0xB94C, 0xD239, 0xB94D, 0xD23A, 0xB94E, 0xD23B,
+	0xB94F, 0xD23E, 0xB950, 0xD240, 0xB951, 0xD242, 0xB952, 0xD243,
+	0xB953, 0xD244, 0xB954, 0xD245, 0xB955, 0xD246, 0xB956, 0xD247,
+	0xB957, 0xD249, 0xB958, 0xD24A, 0xB959, 0xD24B, 0xB95A, 0xD24C,
+	0xB961, 0xD24D, 0xB962, 0xD24E, 0xB963, 0xD24F, 0xB964, 0xD250,
+	0xB965, 0xD251, 0xB966, 0xD252, 0xB967, 0xD253, 0xB968, 0xD254,
+	0xB969, 0xD255, 0xB96A, 0xD256, 0xB96B, 0xD257, 0xB96C, 0xD258,
+	0xB96D, 0xD259, 0xB96E, 0xD25A, 0xB96F, 0xD25B, 0xB970, 0xD25D,
+	0xB971, 0xD25E, 0xB972, 0xD25F, 0xB973, 0xD260, 0xB974, 0xD261,
+	0xB975, 0xD262, 0xB976, 0xD263, 0xB977, 0xD265, 0xB978, 0xD266,
+	0xB979, 0xD267, 0xB97A, 0xD268, 0xB981, 0xD269, 0xB982, 0xD26A,
+	0xB983, 0xD26B, 0xB984, 0xD26C, 0xB985, 0xD26D, 0xB986, 0xD26E,
+	0xB987, 0xD26F, 0xB988, 0xD270, 0xB989, 0xD271, 0xB98A, 0xD272,
+	0xB98B, 0xD273, 0xB98C, 0xD274, 0xB98D, 0xD275, 0xB98E, 0xD276,
+	0xB98F, 0xD277, 0xB990, 0xD278, 0xB991, 0xD279, 0xB992, 0xD27A,
+	0xB993, 0xD27B, 0xB994, 0xD27C, 0xB995, 0xD27D, 0xB996, 0xD27E,
+	0xB997, 0xD27F, 0xB998, 0xD282, 0xB999, 0xD283, 0xB99A, 0xD285,
+	0xB99B, 0xD286, 0xB99C, 0xD287, 0xB99D, 0xD289, 0xB99E, 0xD28A,
+	0xB99F, 0xD28B, 0xB9A0, 0xD28C, 0xB9A1, 0xBB00, 0xB9A2, 0xBB04,
+	0xB9A3, 0xBB0D, 0xB9A4, 0xBB0F, 0xB9A5, 0xBB11, 0xB9A6, 0xBB18,
+	0xB9A7, 0xBB1C, 0xB9A8, 0xBB20, 0xB9A9, 0xBB29, 0xB9AA, 0xBB2B,
+	0xB9AB, 0xBB34, 0xB9AC, 0xBB35, 0xB9AD, 0xBB36, 0xB9AE, 0xBB38,
+	0xB9AF, 0xBB3B, 0xB9B0, 0xBB3C, 0xB9B1, 0xBB3D, 0xB9B2, 0xBB3E,
+	0xB9B3, 0xBB44, 0xB9B4, 0xBB45, 0xB9B5, 0xBB47, 0xB9B6, 0xBB49,
+	0xB9B7, 0xBB4D, 0xB9B8, 0xBB4F, 0xB9B9, 0xBB50, 0xB9BA, 0xBB54,
+	0xB9BB, 0xBB58, 0xB9BC, 0xBB61, 0xB9BD, 0xBB63, 0xB9BE, 0xBB6C,
+	0xB9BF, 0xBB88, 0xB9C0, 0xBB8C, 0xB9C1, 0xBB90, 0xB9C2, 0xBBA4,
+	0xB9C3, 0xBBA8, 0xB9C4, 0xBBAC, 0xB9C5, 0xBBB4, 0xB9C6, 0xBBB7,
+	0xB9C7, 0xBBC0, 0xB9C8, 0xBBC4, 0xB9C9, 0xBBC8, 0xB9CA, 0xBBD0,
+	0xB9CB, 0xBBD3, 0xB9CC, 0xBBF8, 0xB9CD, 0xBBF9, 0xB9CE, 0xBBFC,
+	0xB9CF, 0xBBFF, 0xB9D0, 0xBC00, 0xB9D1, 0xBC02, 0xB9D2, 0xBC08,
+	0xB9D3, 0xBC09, 0xB9D4, 0xBC0B, 0xB9D5, 0xBC0C, 0xB9D6, 0xBC0D,
+	0xB9D7, 0xBC0F, 0xB9D8, 0xBC11, 0xB9D9, 0xBC14, 0xB9DA, 0xBC15,
+	0xB9DB, 0xBC16, 0xB9DC, 0xBC17, 0xB9DD, 0xBC18, 0xB9DE, 0xBC1B,
+	0xB9DF, 0xBC1C, 0xB9E0, 0xBC1D, 0xB9E1, 0xBC1E, 0xB9E2, 0xBC1F,
+	0xB9E3, 0xBC24, 0xB9E4, 0xBC25, 0xB9E5, 0xBC27, 0xB9E6, 0xBC29,
+	0xB9E7, 0xBC2D, 0xB9E8, 0xBC30, 0xB9E9, 0xBC31, 0xB9EA, 0xBC34,
+	0xB9EB, 0xBC38, 0xB9EC, 0xBC40, 0xB9ED, 0xBC41, 0xB9EE, 0xBC43,
+	0xB9EF, 0xBC44, 0xB9F0, 0xBC45, 0xB9F1, 0xBC49, 0xB9F2, 0xBC4C,
+	0xB9F3, 0xBC4D, 0xB9F4, 0xBC50, 0xB9F5, 0xBC5D, 0xB9F6, 0xBC84,
+	0xB9F7, 0xBC85, 0xB9F8, 0xBC88, 0xB9F9, 0xBC8B, 0xB9FA, 0xBC8C,
+	0xB9FB, 0xBC8E, 0xB9FC, 0xBC94, 0xB9FD, 0xBC95, 0xB9FE, 0xBC97,
+	0xBA41, 0xD28D, 0xBA42, 0xD28E, 0xBA43, 0xD28F, 0xBA44, 0xD292,
+	0xBA45, 0xD293, 0xBA46, 0xD294, 0xBA47, 0xD296, 0xBA48, 0xD297,
+	0xBA49, 0xD298, 0xBA4A, 0xD299, 0xBA4B, 0xD29A, 0xBA4C, 0xD29B,
+	0xBA4D, 0xD29D, 0xBA4E, 0xD29E, 0xBA4F, 0xD29F, 0xBA50, 0xD2A1,
+	0xBA51, 0xD2A2, 0xBA52, 0xD2A3, 0xBA53, 0xD2A5, 0xBA54, 0xD2A6,
+	0xBA55, 0xD2A7, 0xBA56, 0xD2A8, 0xBA57, 0xD2A9, 0xBA58, 0xD2AA,
+	0xBA59, 0xD2AB, 0xBA5A, 0xD2AD, 0xBA61, 0xD2AE, 0xBA62, 0xD2AF,
+	0xBA63, 0xD2B0, 0xBA64, 0xD2B2, 0xBA65, 0xD2B3, 0xBA66, 0xD2B4,
+	0xBA67, 0xD2B5, 0xBA68, 0xD2B6, 0xBA69, 0xD2B7, 0xBA6A, 0xD2BA,
+	0xBA6B, 0xD2BB, 0xBA6C, 0xD2BD, 0xBA6D, 0xD2BE, 0xBA6E, 0xD2C1,
+	0xBA6F, 0xD2C3, 0xBA70, 0xD2C4, 0xBA71, 0xD2C5, 0xBA72, 0xD2C6,
+	0xBA73, 0xD2C7, 0xBA74, 0xD2CA, 0xBA75, 0xD2CC, 0xBA76, 0xD2CD,
+	0xBA77, 0xD2CE, 0xBA78, 0xD2CF, 0xBA79, 0xD2D0, 0xBA7A, 0xD2D1,
+	0xBA81, 0xD2D2, 0xBA82, 0xD2D3, 0xBA83, 0xD2D5, 0xBA84, 0xD2D6,
+	0xBA85, 0xD2D7, 0xBA86, 0xD2D9, 0xBA87, 0xD2DA, 0xBA88, 0xD2DB,
+	0xBA89, 0xD2DD, 0xBA8A, 0xD2DE, 0xBA8B, 0xD2DF, 0xBA8C, 0xD2E0,
+	0xBA8D, 0xD2E1, 0xBA8E, 0xD2E2, 0xBA8F, 0xD2E3, 0xBA90, 0xD2E6,
+	0xBA91, 0xD2E7, 0xBA92, 0xD2E8, 0xBA93, 0xD2E9, 0xBA94, 0xD2EA,
+	0xBA95, 0xD2EB, 0xBA96, 0xD2EC, 0xBA97, 0xD2ED, 0xBA98, 0xD2EE,
+	0xBA99, 0xD2EF, 0xBA9A, 0xD2F2, 0xBA9B, 0xD2F3, 0xBA9C, 0xD2F5,
+	0xBA9D, 0xD2F6, 0xBA9E, 0xD2F7, 0xBA9F, 0xD2F9, 0xBAA0, 0xD2FA,
+	0xBAA1, 0xBC99, 0xBAA2, 0xBC9A, 0xBAA3, 0xBCA0, 0xBAA4, 0xBCA1,
+	0xBAA5, 0xBCA4, 0xBAA6, 0xBCA7, 0xBAA7, 0xBCA8, 0xBAA8, 0xBCB0,
+	0xBAA9, 0xBCB1, 0xBAAA, 0xBCB3, 0xBAAB, 0xBCB4, 0xBAAC, 0xBCB5,
+	0xBAAD, 0xBCBC, 0xBAAE, 0xBCBD, 0xBAAF, 0xBCC0, 0xBAB0, 0xBCC4,
+	0xBAB1, 0xBCCD, 0xBAB2, 0xBCCF, 0xBAB3, 0xBCD0, 0xBAB4, 0xBCD1,
+	0xBAB5, 0xBCD5, 0xBAB6, 0xBCD8, 0xBAB7, 0xBCDC, 0xBAB8, 0xBCF4,
+	0xBAB9, 0xBCF5, 0xBABA, 0xBCF6, 0xBABB, 0xBCF8, 0xBABC, 0xBCFC,
+	0xBABD, 0xBD04, 0xBABE, 0xBD05, 0xBABF, 0xBD07, 0xBAC0, 0xBD09,
+	0xBAC1, 0xBD10, 0xBAC2, 0xBD14, 0xBAC3, 0xBD24, 0xBAC4, 0xBD2C,
+	0xBAC5, 0xBD40, 0xBAC6, 0xBD48, 0xBAC7, 0xBD49, 0xBAC8, 0xBD4C,
+	0xBAC9, 0xBD50, 0xBACA, 0xBD58, 0xBACB, 0xBD59, 0xBACC, 0xBD64,
+	0xBACD, 0xBD68, 0xBACE, 0xBD80, 0xBACF, 0xBD81, 0xBAD0, 0xBD84,
+	0xBAD1, 0xBD87, 0xBAD2, 0xBD88, 0xBAD3, 0xBD89, 0xBAD4, 0xBD8A,
+	0xBAD5, 0xBD90, 0xBAD6, 0xBD91, 0xBAD7, 0xBD93, 0xBAD8, 0xBD95,
+	0xBAD9, 0xBD99, 0xBADA, 0xBD9A, 0xBADB, 0xBD9C, 0xBADC, 0xBDA4,
+	0xBADD, 0xBDB0, 0xBADE, 0xBDB8, 0xBADF, 0xBDD4, 0xBAE0, 0xBDD5,
+	0xBAE1, 0xBDD8, 0xBAE2, 0xBDDC, 0xBAE3, 0xBDE9, 0xBAE4, 0xBDF0,
+	0xBAE5, 0xBDF4, 0xBAE6, 0xBDF8, 0xBAE7, 0xBE00, 0xBAE8, 0xBE03,
+	0xBAE9, 0xBE05, 0xBAEA, 0xBE0C, 0xBAEB, 0xBE0D, 0xBAEC, 0xBE10,
+	0xBAED, 0xBE14, 0xBAEE, 0xBE1C, 0xBAEF, 0xBE1D, 0xBAF0, 0xBE1F,
+	0xBAF1, 0xBE44, 0xBAF2, 0xBE45, 0xBAF3, 0xBE48, 0xBAF4, 0xBE4C,
+	0xBAF5, 0xBE4E, 0xBAF6, 0xBE54, 0xBAF7, 0xBE55, 0xBAF8, 0xBE57,
+	0xBAF9, 0xBE59, 0xBAFA, 0xBE5A, 0xBAFB, 0xBE5B, 0xBAFC, 0xBE60,
+	0xBAFD, 0xBE61, 0xBAFE, 0xBE64, 0xBB41, 0xD2FB, 0xBB42, 0xD2FC,
+	0xBB43, 0xD2FD, 0xBB44, 0xD2FE, 0xBB45, 0xD2FF, 0xBB46, 0xD302,
+	0xBB47, 0xD304, 0xBB48, 0xD306, 0xBB49, 0xD307, 0xBB4A, 0xD308,
+	0xBB4B, 0xD309, 0xBB4C, 0xD30A, 0xBB4D, 0xD30B, 0xBB4E, 0xD30F,
+	0xBB4F, 0xD311, 0xBB50, 0xD312, 0xBB51, 0xD313, 0xBB52, 0xD315,
+	0xBB53, 0xD317, 0xBB54, 0xD318, 0xBB55, 0xD319, 0xBB56, 0xD31A,
+	0xBB57, 0xD31B, 0xBB58, 0xD31E, 0xBB59, 0xD322, 0xBB5A, 0xD323,
+	0xBB61, 0xD324, 0xBB62, 0xD326, 0xBB63, 0xD327, 0xBB64, 0xD32A,
+	0xBB65, 0xD32B, 0xBB66, 0xD32D, 0xBB67, 0xD32E, 0xBB68, 0xD32F,
+	0xBB69, 0xD331, 0xBB6A, 0xD332, 0xBB6B, 0xD333, 0xBB6C, 0xD334,
+	0xBB6D, 0xD335, 0xBB6E, 0xD336, 0xBB6F, 0xD337, 0xBB70, 0xD33A,
+	0xBB71, 0xD33E, 0xBB72, 0xD33F, 0xBB73, 0xD340, 0xBB74, 0xD341,
+	0xBB75, 0xD342, 0xBB76, 0xD343, 0xBB77, 0xD346, 0xBB78, 0xD347,
+	0xBB79, 0xD348, 0xBB7A, 0xD349, 0xBB81, 0xD34A, 0xBB82, 0xD34B,
+	0xBB83, 0xD34C, 0xBB84, 0xD34D, 0xBB85, 0xD34E, 0xBB86, 0xD34F,
+	0xBB87, 0xD350, 0xBB88, 0xD351, 0xBB89, 0xD352, 0xBB8A, 0xD353,
+	0xBB8B, 0xD354, 0xBB8C, 0xD355, 0xBB8D, 0xD356, 0xBB8E, 0xD357,
+	0xBB8F, 0xD358, 0xBB90, 0xD359, 0xBB91, 0xD35A, 0xBB92, 0xD35B,
+	0xBB93, 0xD35C, 0xBB94, 0xD35D, 0xBB95, 0xD35E, 0xBB96, 0xD35F,
+	0xBB97, 0xD360, 0xBB98, 0xD361, 0xBB99, 0xD362, 0xBB9A, 0xD363,
+	0xBB9B, 0xD364, 0xBB9C, 0xD365, 0xBB9D, 0xD366, 0xBB9E, 0xD367,
+	0xBB9F, 0xD368, 0xBBA0, 0xD369, 0xBBA1, 0xBE68, 0xBBA2, 0xBE6A,
+	0xBBA3, 0xBE70, 0xBBA4, 0xBE71, 0xBBA5, 0xBE73, 0xBBA6, 0xBE74,
+	0xBBA7, 0xBE75, 0xBBA8, 0xBE7B, 0xBBA9, 0xBE7C, 0xBBAA, 0xBE7D,
+	0xBBAB, 0xBE80, 0xBBAC, 0xBE84, 0xBBAD, 0xBE8C, 0xBBAE, 0xBE8D,
+	0xBBAF, 0xBE8F, 0xBBB0, 0xBE90, 0xBBB1, 0xBE91, 0xBBB2, 0xBE98,
+	0xBBB3, 0xBE99, 0xBBB4, 0xBEA8, 0xBBB5, 0xBED0, 0xBBB6, 0xBED1,
+	0xBBB7, 0xBED4, 0xBBB8, 0xBED7, 0xBBB9, 0xBED8, 0xBBBA, 0xBEE0,
+	0xBBBB, 0xBEE3, 0xBBBC, 0xBEE4, 0xBBBD, 0xBEE5, 0xBBBE, 0xBEEC,
+	0xBBBF, 0xBF01, 0xBBC0, 0xBF08, 0xBBC1, 0xBF09, 0xBBC2, 0xBF18,
+	0xBBC3, 0xBF19, 0xBBC4, 0xBF1B, 0xBBC5, 0xBF1C, 0xBBC6, 0xBF1D,
+	0xBBC7, 0xBF40, 0xBBC8, 0xBF41, 0xBBC9, 0xBF44, 0xBBCA, 0xBF48,
+	0xBBCB, 0xBF50, 0xBBCC, 0xBF51, 0xBBCD, 0xBF55, 0xBBCE, 0xBF94,
+	0xBBCF, 0xBFB0, 0xBBD0, 0xBFC5, 0xBBD1, 0xBFCC, 0xBBD2, 0xBFCD,
+	0xBBD3, 0xBFD0, 0xBBD4, 0xBFD4, 0xBBD5, 0xBFDC, 0xBBD6, 0xBFDF,
+	0xBBD7, 0xBFE1, 0xBBD8, 0xC03C, 0xBBD9, 0xC051, 0xBBDA, 0xC058,
+	0xBBDB, 0xC05C, 0xBBDC, 0xC060, 0xBBDD, 0xC068, 0xBBDE, 0xC069,
+	0xBBDF, 0xC090, 0xBBE0, 0xC091, 0xBBE1, 0xC094, 0xBBE2, 0xC098,
+	0xBBE3, 0xC0A0, 0xBBE4, 0xC0A1, 0xBBE5, 0xC0A3, 0xBBE6, 0xC0A5,
+	0xBBE7, 0xC0AC, 0xBBE8, 0xC0AD, 0xBBE9, 0xC0AF, 0xBBEA, 0xC0B0,
+	0xBBEB, 0xC0B3, 0xBBEC, 0xC0B4, 0xBBED, 0xC0B5, 0xBBEE, 0xC0B6,
+	0xBBEF, 0xC0BC, 0xBBF0, 0xC0BD, 0xBBF1, 0xC0BF, 0xBBF2, 0xC0C0,
+	0xBBF3, 0xC0C1, 0xBBF4, 0xC0C5, 0xBBF5, 0xC0C8, 0xBBF6, 0xC0C9,
+	0xBBF7, 0xC0CC, 0xBBF8, 0xC0D0, 0xBBF9, 0xC0D8, 0xBBFA, 0xC0D9,
+	0xBBFB, 0xC0DB, 0xBBFC, 0xC0DC, 0xBBFD, 0xC0DD, 0xBBFE, 0xC0E4,
+	0xBC41, 0xD36A, 0xBC42, 0xD36B, 0xBC43, 0xD36C, 0xBC44, 0xD36D,
+	0xBC45, 0xD36E, 0xBC46, 0xD36F, 0xBC47, 0xD370, 0xBC48, 0xD371,
+	0xBC49, 0xD372, 0xBC4A, 0xD373, 0xBC4B, 0xD374, 0xBC4C, 0xD375,
+	0xBC4D, 0xD376, 0xBC4E, 0xD377, 0xBC4F, 0xD378, 0xBC50, 0xD379,
+	0xBC51, 0xD37A, 0xBC52, 0xD37B, 0xBC53, 0xD37E, 0xBC54, 0xD37F,
+	0xBC55, 0xD381, 0xBC56, 0xD382, 0xBC57, 0xD383, 0xBC58, 0xD385,
+	0xBC59, 0xD386, 0xBC5A, 0xD387, 0xBC61, 0xD388, 0xBC62, 0xD389,
+	0xBC63, 0xD38A, 0xBC64, 0xD38B, 0xBC65, 0xD38E, 0xBC66, 0xD392,
+	0xBC67, 0xD393, 0xBC68, 0xD394, 0xBC69, 0xD395, 0xBC6A, 0xD396,
+	0xBC6B, 0xD397, 0xBC6C, 0xD39A, 0xBC6D, 0xD39B, 0xBC6E, 0xD39D,
+	0xBC6F, 0xD39E, 0xBC70, 0xD39F, 0xBC71, 0xD3A1, 0xBC72, 0xD3A2,
+	0xBC73, 0xD3A3, 0xBC74, 0xD3A4, 0xBC75, 0xD3A5, 0xBC76, 0xD3A6,
+	0xBC77, 0xD3A7, 0xBC78, 0xD3AA, 0xBC79, 0xD3AC, 0xBC7A, 0xD3AE,
+	0xBC81, 0xD3AF, 0xBC82, 0xD3B0, 0xBC83, 0xD3B1, 0xBC84, 0xD3B2,
+	0xBC85, 0xD3B3, 0xBC86, 0xD3B5, 0xBC87, 0xD3B6, 0xBC88, 0xD3B7,
+	0xBC89, 0xD3B9, 0xBC8A, 0xD3BA, 0xBC8B, 0xD3BB, 0xBC8C, 0xD3BD,
+	0xBC8D, 0xD3BE, 0xBC8E, 0xD3BF, 0xBC8F, 0xD3C0, 0xBC90, 0xD3C1,
+	0xBC91, 0xD3C2, 0xBC92, 0xD3C3, 0xBC93, 0xD3C6, 0xBC94, 0xD3C7,
+	0xBC95, 0xD3CA, 0xBC96, 0xD3CB, 0xBC97, 0xD3CC, 0xBC98, 0xD3CD,
+	0xBC99, 0xD3CE, 0xBC9A, 0xD3CF, 0xBC9B, 0xD3D1, 0xBC9C, 0xD3D2,
+	0xBC9D, 0xD3D3, 0xBC9E, 0xD3D4, 0xBC9F, 0xD3D5, 0xBCA0, 0xD3D6,
+	0xBCA1, 0xC0E5, 0xBCA2, 0xC0E8, 0xBCA3, 0xC0EC, 0xBCA4, 0xC0F4,
+	0xBCA5, 0xC0F5, 0xBCA6, 0xC0F7, 0xBCA7, 0xC0F9, 0xBCA8, 0xC100,
+	0xBCA9, 0xC104, 0xBCAA, 0xC108, 0xBCAB, 0xC110, 0xBCAC, 0xC115,
+	0xBCAD, 0xC11C, 0xBCAE, 0xC11D, 0xBCAF, 0xC11E, 0xBCB0, 0xC11F,
+	0xBCB1, 0xC120, 0xBCB2, 0xC123, 0xBCB3, 0xC124, 0xBCB4, 0xC126,
+	0xBCB5, 0xC127, 0xBCB6, 0xC12C, 0xBCB7, 0xC12D, 0xBCB8, 0xC12F,
+	0xBCB9, 0xC130, 0xBCBA, 0xC131, 0xBCBB, 0xC136, 0xBCBC, 0xC138,
+	0xBCBD, 0xC139, 0xBCBE, 0xC13C, 0xBCBF, 0xC140, 0xBCC0, 0xC148,
+	0xBCC1, 0xC149, 0xBCC2, 0xC14B, 0xBCC3, 0xC14C, 0xBCC4, 0xC14D,
+	0xBCC5, 0xC154, 0xBCC6, 0xC155, 0xBCC7, 0xC158, 0xBCC8, 0xC15C,
+	0xBCC9, 0xC164, 0xBCCA, 0xC165, 0xBCCB, 0xC167, 0xBCCC, 0xC168,
+	0xBCCD, 0xC169, 0xBCCE, 0xC170, 0xBCCF, 0xC174, 0xBCD0, 0xC178,
+	0xBCD1, 0xC185, 0xBCD2, 0xC18C, 0xBCD3, 0xC18D, 0xBCD4, 0xC18E,
+	0xBCD5, 0xC190, 0xBCD6, 0xC194, 0xBCD7, 0xC196, 0xBCD8, 0xC19C,
+	0xBCD9, 0xC19D, 0xBCDA, 0xC19F, 0xBCDB, 0xC1A1, 0xBCDC, 0xC1A5,
+	0xBCDD, 0xC1A8, 0xBCDE, 0xC1A9, 0xBCDF, 0xC1AC, 0xBCE0, 0xC1B0,
+	0xBCE1, 0xC1BD, 0xBCE2, 0xC1C4, 0xBCE3, 0xC1C8, 0xBCE4, 0xC1CC,
+	0xBCE5, 0xC1D4, 0xBCE6, 0xC1D7, 0xBCE7, 0xC1D8, 0xBCE8, 0xC1E0,
+	0xBCE9, 0xC1E4, 0xBCEA, 0xC1E8, 0xBCEB, 0xC1F0, 0xBCEC, 0xC1F1,
+	0xBCED, 0xC1F3, 0xBCEE, 0xC1FC, 0xBCEF, 0xC1FD, 0xBCF0, 0xC200,
+	0xBCF1, 0xC204, 0xBCF2, 0xC20C, 0xBCF3, 0xC20D, 0xBCF4, 0xC20F,
+	0xBCF5, 0xC211, 0xBCF6, 0xC218, 0xBCF7, 0xC219, 0xBCF8, 0xC21C,
+	0xBCF9, 0xC21F, 0xBCFA, 0xC220, 0xBCFB, 0xC228, 0xBCFC, 0xC229,
+	0xBCFD, 0xC22B, 0xBCFE, 0xC22D, 0xBD41, 0xD3D7, 0xBD42, 0xD3D9,
+	0xBD43, 0xD3DA, 0xBD44, 0xD3DB, 0xBD45, 0xD3DC, 0xBD46, 0xD3DD,
+	0xBD47, 0xD3DE, 0xBD48, 0xD3DF, 0xBD49, 0xD3E0, 0xBD4A, 0xD3E2,
+	0xBD4B, 0xD3E4, 0xBD4C, 0xD3E5, 0xBD4D, 0xD3E6, 0xBD4E, 0xD3E7,
+	0xBD4F, 0xD3E8, 0xBD50, 0xD3E9, 0xBD51, 0xD3EA, 0xBD52, 0xD3EB,
+	0xBD53, 0xD3EE, 0xBD54, 0xD3EF, 0xBD55, 0xD3F1, 0xBD56, 0xD3F2,
+	0xBD57, 0xD3F3, 0xBD58, 0xD3F5, 0xBD59, 0xD3F6, 0xBD5A, 0xD3F7,
+	0xBD61, 0xD3F8, 0xBD62, 0xD3F9, 0xBD63, 0xD3FA, 0xBD64, 0xD3FB,
+	0xBD65, 0xD3FE, 0xBD66, 0xD400, 0xBD67, 0xD402, 0xBD68, 0xD403,
+	0xBD69, 0xD404, 0xBD6A, 0xD405, 0xBD6B, 0xD406, 0xBD6C, 0xD407,
+	0xBD6D, 0xD409, 0xBD6E, 0xD40A, 0xBD6F, 0xD40B, 0xBD70, 0xD40C,
+	0xBD71, 0xD40D, 0xBD72, 0xD40E, 0xBD73, 0xD40F, 0xBD74, 0xD410,
+	0xBD75, 0xD411, 0xBD76, 0xD412, 0xBD77, 0xD413, 0xBD78, 0xD414,
+	0xBD79, 0xD415, 0xBD7A, 0xD416, 0xBD81, 0xD417, 0xBD82, 0xD418,
+	0xBD83, 0xD419, 0xBD84, 0xD41A, 0xBD85, 0xD41B, 0xBD86, 0xD41C,
+	0xBD87, 0xD41E, 0xBD88, 0xD41F, 0xBD89, 0xD420, 0xBD8A, 0xD421,
+	0xBD8B, 0xD422, 0xBD8C, 0xD423, 0xBD8D, 0xD424, 0xBD8E, 0xD425,
+	0xBD8F, 0xD426, 0xBD90, 0xD427, 0xBD91, 0xD428, 0xBD92, 0xD429,
+	0xBD93, 0xD42A, 0xBD94, 0xD42B, 0xBD95, 0xD42C, 0xBD96, 0xD42D,
+	0xBD97, 0xD42E, 0xBD98, 0xD42F, 0xBD99, 0xD430, 0xBD9A, 0xD431,
+	0xBD9B, 0xD432, 0xBD9C, 0xD433, 0xBD9D, 0xD434, 0xBD9E, 0xD435,
+	0xBD9F, 0xD436, 0xBDA0, 0xD437, 0xBDA1, 0xC22F, 0xBDA2, 0xC231,
+	0xBDA3, 0xC232, 0xBDA4, 0xC234, 0xBDA5, 0xC248, 0xBDA6, 0xC250,
+	0xBDA7, 0xC251, 0xBDA8, 0xC254, 0xBDA9, 0xC258, 0xBDAA, 0xC260,
+	0xBDAB, 0xC265, 0xBDAC, 0xC26C, 0xBDAD, 0xC26D, 0xBDAE, 0xC270,
+	0xBDAF, 0xC274, 0xBDB0, 0xC27C, 0xBDB1, 0xC27D, 0xBDB2, 0xC27F,
+	0xBDB3, 0xC281, 0xBDB4, 0xC288, 0xBDB5, 0xC289, 0xBDB6, 0xC290,
+	0xBDB7, 0xC298, 0xBDB8, 0xC29B, 0xBDB9, 0xC29D, 0xBDBA, 0xC2A4,
+	0xBDBB, 0xC2A5, 0xBDBC, 0xC2A8, 0xBDBD, 0xC2AC, 0xBDBE, 0xC2AD,
+	0xBDBF, 0xC2B4, 0xBDC0, 0xC2B5, 0xBDC1, 0xC2B7, 0xBDC2, 0xC2B9,
+	0xBDC3, 0xC2DC, 0xBDC4, 0xC2DD, 0xBDC5, 0xC2E0, 0xBDC6, 0xC2E3,
+	0xBDC7, 0xC2E4, 0xBDC8, 0xC2EB, 0xBDC9, 0xC2EC, 0xBDCA, 0xC2ED,
+	0xBDCB, 0xC2EF, 0xBDCC, 0xC2F1, 0xBDCD, 0xC2F6, 0xBDCE, 0xC2F8,
+	0xBDCF, 0xC2F9, 0xBDD0, 0xC2FB, 0xBDD1, 0xC2FC, 0xBDD2, 0xC300,
+	0xBDD3, 0xC308, 0xBDD4, 0xC309, 0xBDD5, 0xC30C, 0xBDD6, 0xC30D,
+	0xBDD7, 0xC313, 0xBDD8, 0xC314, 0xBDD9, 0xC315, 0xBDDA, 0xC318,
+	0xBDDB, 0xC31C, 0xBDDC, 0xC324, 0xBDDD, 0xC325, 0xBDDE, 0xC328,
+	0xBDDF, 0xC329, 0xBDE0, 0xC345, 0xBDE1, 0xC368, 0xBDE2, 0xC369,
+	0xBDE3, 0xC36C, 0xBDE4, 0xC370, 0xBDE5, 0xC372, 0xBDE6, 0xC378,
+	0xBDE7, 0xC379, 0xBDE8, 0xC37C, 0xBDE9, 0xC37D, 0xBDEA, 0xC384,
+	0xBDEB, 0xC388, 0xBDEC, 0xC38C, 0xBDED, 0xC3C0, 0xBDEE, 0xC3D8,
+	0xBDEF, 0xC3D9, 0xBDF0, 0xC3DC, 0xBDF1, 0xC3DF, 0xBDF2, 0xC3E0,
+	0xBDF3, 0xC3E2, 0xBDF4, 0xC3E8, 0xBDF5, 0xC3E9, 0xBDF6, 0xC3ED,
+	0xBDF7, 0xC3F4, 0xBDF8, 0xC3F5, 0xBDF9, 0xC3F8, 0xBDFA, 0xC408,
+	0xBDFB, 0xC410, 0xBDFC, 0xC424, 0xBDFD, 0xC42C, 0xBDFE, 0xC430,
+	0xBE41, 0xD438, 0xBE42, 0xD439, 0xBE43, 0xD43A, 0xBE44, 0xD43B,
+	0xBE45, 0xD43C, 0xBE46, 0xD43D, 0xBE47, 0xD43E, 0xBE48, 0xD43F,
+	0xBE49, 0xD441, 0xBE4A, 0xD442, 0xBE4B, 0xD443, 0xBE4C, 0xD445,
+	0xBE4D, 0xD446, 0xBE4E, 0xD447, 0xBE4F, 0xD448, 0xBE50, 0xD449,
+	0xBE51, 0xD44A, 0xBE52, 0xD44B, 0xBE53, 0xD44C, 0xBE54, 0xD44D,
+	0xBE55, 0xD44E, 0xBE56, 0xD44F, 0xBE57, 0xD450, 0xBE58, 0xD451,
+	0xBE59, 0xD452, 0xBE5A, 0xD453, 0xBE61, 0xD454, 0xBE62, 0xD455,
+	0xBE63, 0xD456, 0xBE64, 0xD457, 0xBE65, 0xD458, 0xBE66, 0xD459,
+	0xBE67, 0xD45A, 0xBE68, 0xD45B, 0xBE69, 0xD45D, 0xBE6A, 0xD45E,
+	0xBE6B, 0xD45F, 0xBE6C, 0xD461, 0xBE6D, 0xD462, 0xBE6E, 0xD463,
+	0xBE6F, 0xD465, 0xBE70, 0xD466, 0xBE71, 0xD467, 0xBE72, 0xD468,
+	0xBE73, 0xD469, 0xBE74, 0xD46A, 0xBE75, 0xD46B, 0xBE76, 0xD46C,
+	0xBE77, 0xD46E, 0xBE78, 0xD470, 0xBE79, 0xD471, 0xBE7A, 0xD472,
+	0xBE81, 0xD473, 0xBE82, 0xD474, 0xBE83, 0xD475, 0xBE84, 0xD476,
+	0xBE85, 0xD477, 0xBE86, 0xD47A, 0xBE87, 0xD47B, 0xBE88, 0xD47D,
+	0xBE89, 0xD47E, 0xBE8A, 0xD481, 0xBE8B, 0xD483, 0xBE8C, 0xD484,
+	0xBE8D, 0xD485, 0xBE8E, 0xD486, 0xBE8F, 0xD487, 0xBE90, 0xD48A,
+	0xBE91, 0xD48C, 0xBE92, 0xD48E, 0xBE93, 0xD48F, 0xBE94, 0xD490,
+	0xBE95, 0xD491, 0xBE96, 0xD492, 0xBE97, 0xD493, 0xBE98, 0xD495,
+	0xBE99, 0xD496, 0xBE9A, 0xD497, 0xBE9B, 0xD498, 0xBE9C, 0xD499,
+	0xBE9D, 0xD49A, 0xBE9E, 0xD49B, 0xBE9F, 0xD49C, 0xBEA0, 0xD49D,
+	0xBEA1, 0xC434, 0xBEA2, 0xC43C, 0xBEA3, 0xC43D, 0xBEA4, 0xC448,
+	0xBEA5, 0xC464, 0xBEA6, 0xC465, 0xBEA7, 0xC468, 0xBEA8, 0xC46C,
+	0xBEA9, 0xC474, 0xBEAA, 0xC475, 0xBEAB, 0xC479, 0xBEAC, 0xC480,
+	0xBEAD, 0xC494, 0xBEAE, 0xC49C, 0xBEAF, 0xC4B8, 0xBEB0, 0xC4BC,
+	0xBEB1, 0xC4E9, 0xBEB2, 0xC4F0, 0xBEB3, 0xC4F1, 0xBEB4, 0xC4F4,
+	0xBEB5, 0xC4F8, 0xBEB6, 0xC4FA, 0xBEB7, 0xC4FF, 0xBEB8, 0xC500,
+	0xBEB9, 0xC501, 0xBEBA, 0xC50C, 0xBEBB, 0xC510, 0xBEBC, 0xC514,
+	0xBEBD, 0xC51C, 0xBEBE, 0xC528, 0xBEBF, 0xC529, 0xBEC0, 0xC52C,
+	0xBEC1, 0xC530, 0xBEC2, 0xC538, 0xBEC3, 0xC539, 0xBEC4, 0xC53B,
+	0xBEC5, 0xC53D, 0xBEC6, 0xC544, 0xBEC7, 0xC545, 0xBEC8, 0xC548,
+	0xBEC9, 0xC549, 0xBECA, 0xC54A, 0xBECB, 0xC54C, 0xBECC, 0xC54D,
+	0xBECD, 0xC54E, 0xBECE, 0xC553, 0xBECF, 0xC554, 0xBED0, 0xC555,
+	0xBED1, 0xC557, 0xBED2, 0xC558, 0xBED3, 0xC559, 0xBED4, 0xC55D,
+	0xBED5, 0xC55E, 0xBED6, 0xC560, 0xBED7, 0xC561, 0xBED8, 0xC564,
+	0xBED9, 0xC568, 0xBEDA, 0xC570, 0xBEDB, 0xC571, 0xBEDC, 0xC573,
+	0xBEDD, 0xC574, 0xBEDE, 0xC575, 0xBEDF, 0xC57C, 0xBEE0, 0xC57D,
+	0xBEE1, 0xC580, 0xBEE2, 0xC584, 0xBEE3, 0xC587, 0xBEE4, 0xC58C,
+	0xBEE5, 0xC58D, 0xBEE6, 0xC58F, 0xBEE7, 0xC591, 0xBEE8, 0xC595,
+	0xBEE9, 0xC597, 0xBEEA, 0xC598, 0xBEEB, 0xC59C, 0xBEEC, 0xC5A0,
+	0xBEED, 0xC5A9, 0xBEEE, 0xC5B4, 0xBEEF, 0xC5B5, 0xBEF0, 0xC5B8,
+	0xBEF1, 0xC5B9, 0xBEF2, 0xC5BB, 0xBEF3, 0xC5BC, 0xBEF4, 0xC5BD,
+	0xBEF5, 0xC5BE, 0xBEF6, 0xC5C4, 0xBEF7, 0xC5C5, 0xBEF8, 0xC5C6,
+	0xBEF9, 0xC5C7, 0xBEFA, 0xC5C8, 0xBEFB, 0xC5C9, 0xBEFC, 0xC5CA,
+	0xBEFD, 0xC5CC, 0xBEFE, 0xC5CE, 0xBF41, 0xD49E, 0xBF42, 0xD49F,
+	0xBF43, 0xD4A0, 0xBF44, 0xD4A1, 0xBF45, 0xD4A2, 0xBF46, 0xD4A3,
+	0xBF47, 0xD4A4, 0xBF48, 0xD4A5, 0xBF49, 0xD4A6, 0xBF4A, 0xD4A7,
+	0xBF4B, 0xD4A8, 0xBF4C, 0xD4AA, 0xBF4D, 0xD4AB, 0xBF4E, 0xD4AC,
+	0xBF4F, 0xD4AD, 0xBF50, 0xD4AE, 0xBF51, 0xD4AF, 0xBF52, 0xD4B0,
+	0xBF53, 0xD4B1, 0xBF54, 0xD4B2, 0xBF55, 0xD4B3, 0xBF56, 0xD4B4,
+	0xBF57, 0xD4B5, 0xBF58, 0xD4B6, 0xBF59, 0xD4B7, 0xBF5A, 0xD4B8,
+	0xBF61, 0xD4B9, 0xBF62, 0xD4BA, 0xBF63, 0xD4BB, 0xBF64, 0xD4BC,
+	0xBF65, 0xD4BD, 0xBF66, 0xD4BE, 0xBF67, 0xD4BF, 0xBF68, 0xD4C0,
+	0xBF69, 0xD4C1, 0xBF6A, 0xD4C2, 0xBF6B, 0xD4C3, 0xBF6C, 0xD4C4,
+	0xBF6D, 0xD4C5, 0xBF6E, 0xD4C6, 0xBF6F, 0xD4C7, 0xBF70, 0xD4C8,
+	0xBF71, 0xD4C9, 0xBF72, 0xD4CA, 0xBF73, 0xD4CB, 0xBF74, 0xD4CD,
+	0xBF75, 0xD4CE, 0xBF76, 0xD4CF, 0xBF77, 0xD4D1, 0xBF78, 0xD4D2,
+	0xBF79, 0xD4D3, 0xBF7A, 0xD4D5, 0xBF81, 0xD4D6, 0xBF82, 0xD4D7,
+	0xBF83, 0xD4D8, 0xBF84, 0xD4D9, 0xBF85, 0xD4DA, 0xBF86, 0xD4DB,
+	0xBF87, 0xD4DD, 0xBF88, 0xD4DE, 0xBF89, 0xD4E0, 0xBF8A, 0xD4E1,
+	0xBF8B, 0xD4E2, 0xBF8C, 0xD4E3, 0xBF8D, 0xD4E4, 0xBF8E, 0xD4E5,
+	0xBF8F, 0xD4E6, 0xBF90, 0xD4E7, 0xBF91, 0xD4E9, 0xBF92, 0xD4EA,
+	0xBF93, 0xD4EB, 0xBF94, 0xD4ED, 0xBF95, 0xD4EE, 0xBF96, 0xD4EF,
+	0xBF97, 0xD4F1, 0xBF98, 0xD4F2, 0xBF99, 0xD4F3, 0xBF9A, 0xD4F4,
+	0xBF9B, 0xD4F5, 0xBF9C, 0xD4F6, 0xBF9D, 0xD4F7, 0xBF9E, 0xD4F9,
+	0xBF9F, 0xD4FA, 0xBFA0, 0xD4FC, 0xBFA1, 0xC5D0, 0xBFA2, 0xC5D1,
+	0xBFA3, 0xC5D4, 0xBFA4, 0xC5D8, 0xBFA5, 0xC5E0, 0xBFA6, 0xC5E1,
+	0xBFA7, 0xC5E3, 0xBFA8, 0xC5E5, 0xBFA9, 0xC5EC, 0xBFAA, 0xC5ED,
+	0xBFAB, 0xC5EE, 0xBFAC, 0xC5F0, 0xBFAD, 0xC5F4, 0xBFAE, 0xC5F6,
+	0xBFAF, 0xC5F7, 0xBFB0, 0xC5FC, 0xBFB1, 0xC5FD, 0xBFB2, 0xC5FE,
+	0xBFB3, 0xC5FF, 0xBFB4, 0xC600, 0xBFB5, 0xC601, 0xBFB6, 0xC605,
+	0xBFB7, 0xC606, 0xBFB8, 0xC607, 0xBFB9, 0xC608, 0xBFBA, 0xC60C,
+	0xBFBB, 0xC610, 0xBFBC, 0xC618, 0xBFBD, 0xC619, 0xBFBE, 0xC61B,
+	0xBFBF, 0xC61C, 0xBFC0, 0xC624, 0xBFC1, 0xC625, 0xBFC2, 0xC628,
+	0xBFC3, 0xC62C, 0xBFC4, 0xC62D, 0xBFC5, 0xC62E, 0xBFC6, 0xC630,
+	0xBFC7, 0xC633, 0xBFC8, 0xC634, 0xBFC9, 0xC635, 0xBFCA, 0xC637,
+	0xBFCB, 0xC639, 0xBFCC, 0xC63B, 0xBFCD, 0xC640, 0xBFCE, 0xC641,
+	0xBFCF, 0xC644, 0xBFD0, 0xC648, 0xBFD1, 0xC650, 0xBFD2, 0xC651,
+	0xBFD3, 0xC653, 0xBFD4, 0xC654, 0xBFD5, 0xC655, 0xBFD6, 0xC65C,
+	0xBFD7, 0xC65D, 0xBFD8, 0xC660, 0xBFD9, 0xC66C, 0xBFDA, 0xC66F,
+	0xBFDB, 0xC671, 0xBFDC, 0xC678, 0xBFDD, 0xC679, 0xBFDE, 0xC67C,
+	0xBFDF, 0xC680, 0xBFE0, 0xC688, 0xBFE1, 0xC689, 0xBFE2, 0xC68B,
+	0xBFE3, 0xC68D, 0xBFE4, 0xC694, 0xBFE5, 0xC695, 0xBFE6, 0xC698,
+	0xBFE7, 0xC69C, 0xBFE8, 0xC6A4, 0xBFE9, 0xC6A5, 0xBFEA, 0xC6A7,
+	0xBFEB, 0xC6A9, 0xBFEC, 0xC6B0, 0xBFED, 0xC6B1, 0xBFEE, 0xC6B4,
+	0xBFEF, 0xC6B8, 0xBFF0, 0xC6B9, 0xBFF1, 0xC6BA, 0xBFF2, 0xC6C0,
+	0xBFF3, 0xC6C1, 0xBFF4, 0xC6C3, 0xBFF5, 0xC6C5, 0xBFF6, 0xC6CC,
+	0xBFF7, 0xC6CD, 0xBFF8, 0xC6D0, 0xBFF9, 0xC6D4, 0xBFFA, 0xC6DC,
+	0xBFFB, 0xC6DD, 0xBFFC, 0xC6E0, 0xBFFD, 0xC6E1, 0xBFFE, 0xC6E8,
+	0xC041, 0xD4FE, 0xC042, 0xD4FF, 0xC043, 0xD500, 0xC044, 0xD501,
+	0xC045, 0xD502, 0xC046, 0xD503, 0xC047, 0xD505, 0xC048, 0xD506,
+	0xC049, 0xD507, 0xC04A, 0xD509, 0xC04B, 0xD50A, 0xC04C, 0xD50B,
+	0xC04D, 0xD50D, 0xC04E, 0xD50E, 0xC04F, 0xD50F, 0xC050, 0xD510,
+	0xC051, 0xD511, 0xC052, 0xD512, 0xC053, 0xD513, 0xC054, 0xD516,
+	0xC055, 0xD518, 0xC056, 0xD519, 0xC057, 0xD51A, 0xC058, 0xD51B,
+	0xC059, 0xD51C, 0xC05A, 0xD51D, 0xC061, 0xD51E, 0xC062, 0xD51F,
+	0xC063, 0xD520, 0xC064, 0xD521, 0xC065, 0xD522, 0xC066, 0xD523,
+	0xC067, 0xD524, 0xC068, 0xD525, 0xC069, 0xD526, 0xC06A, 0xD527,
+	0xC06B, 0xD528, 0xC06C, 0xD529, 0xC06D, 0xD52A, 0xC06E, 0xD52B,
+	0xC06F, 0xD52C, 0xC070, 0xD52D, 0xC071, 0xD52E, 0xC072, 0xD52F,
+	0xC073, 0xD530, 0xC074, 0xD531, 0xC075, 0xD532, 0xC076, 0xD533,
+	0xC077, 0xD534, 0xC078, 0xD535, 0xC079, 0xD536, 0xC07A, 0xD537,
+	0xC081, 0xD538, 0xC082, 0xD539, 0xC083, 0xD53A, 0xC084, 0xD53B,
+	0xC085, 0xD53E, 0xC086, 0xD53F, 0xC087, 0xD541, 0xC088, 0xD542,
+	0xC089, 0xD543, 0xC08A, 0xD545, 0xC08B, 0xD546, 0xC08C, 0xD547,
+	0xC08D, 0xD548, 0xC08E, 0xD549, 0xC08F, 0xD54A, 0xC090, 0xD54B,
+	0xC091, 0xD54E, 0xC092, 0xD550, 0xC093, 0xD552, 0xC094, 0xD553,
+	0xC095, 0xD554, 0xC096, 0xD555, 0xC097, 0xD556, 0xC098, 0xD557,
+	0xC099, 0xD55A, 0xC09A, 0xD55B, 0xC09B, 0xD55D, 0xC09C, 0xD55E,
+	0xC09D, 0xD55F, 0xC09E, 0xD561, 0xC09F, 0xD562, 0xC0A0, 0xD563,
+	0xC0A1, 0xC6E9, 0xC0A2, 0xC6EC, 0xC0A3, 0xC6F0, 0xC0A4, 0xC6F8,
+	0xC0A5, 0xC6F9, 0xC0A6, 0xC6FD, 0xC0A7, 0xC704, 0xC0A8, 0xC705,
+	0xC0A9, 0xC708, 0xC0AA, 0xC70C, 0xC0AB, 0xC714, 0xC0AC, 0xC715,
+	0xC0AD, 0xC717, 0xC0AE, 0xC719, 0xC0AF, 0xC720, 0xC0B0, 0xC721,
+	0xC0B1, 0xC724, 0xC0B2, 0xC728, 0xC0B3, 0xC730, 0xC0B4, 0xC731,
+	0xC0B5, 0xC733, 0xC0B6, 0xC735, 0xC0B7, 0xC737, 0xC0B8, 0xC73C,
+	0xC0B9, 0xC73D, 0xC0BA, 0xC740, 0xC0BB, 0xC744, 0xC0BC, 0xC74A,
+	0xC0BD, 0xC74C, 0xC0BE, 0xC74D, 0xC0BF, 0xC74F, 0xC0C0, 0xC751,
+	0xC0C1, 0xC752, 0xC0C2, 0xC753, 0xC0C3, 0xC754, 0xC0C4, 0xC755,
+	0xC0C5, 0xC756, 0xC0C6, 0xC757, 0xC0C7, 0xC758, 0xC0C8, 0xC75C,
+	0xC0C9, 0xC760, 0xC0CA, 0xC768, 0xC0CB, 0xC76B, 0xC0CC, 0xC774,
+	0xC0CD, 0xC775, 0xC0CE, 0xC778, 0xC0CF, 0xC77C, 0xC0D0, 0xC77D,
+	0xC0D1, 0xC77E, 0xC0D2, 0xC783, 0xC0D3, 0xC784, 0xC0D4, 0xC785,
+	0xC0D5, 0xC787, 0xC0D6, 0xC788, 0xC0D7, 0xC789, 0xC0D8, 0xC78A,
+	0xC0D9, 0xC78E, 0xC0DA, 0xC790, 0xC0DB, 0xC791, 0xC0DC, 0xC794,
+	0xC0DD, 0xC796, 0xC0DE, 0xC797, 0xC0DF, 0xC798, 0xC0E0, 0xC79A,
+	0xC0E1, 0xC7A0, 0xC0E2, 0xC7A1, 0xC0E3, 0xC7A3, 0xC0E4, 0xC7A4,
+	0xC0E5, 0xC7A5, 0xC0E6, 0xC7A6, 0xC0E7, 0xC7AC, 0xC0E8, 0xC7AD,
+	0xC0E9, 0xC7B0, 0xC0EA, 0xC7B4, 0xC0EB, 0xC7BC, 0xC0EC, 0xC7BD,
+	0xC0ED, 0xC7BF, 0xC0EE, 0xC7C0, 0xC0EF, 0xC7C1, 0xC0F0, 0xC7C8,
+	0xC0F1, 0xC7C9, 0xC0F2, 0xC7CC, 0xC0F3, 0xC7CE, 0xC0F4, 0xC7D0,
+	0xC0F5, 0xC7D8, 0xC0F6, 0xC7DD, 0xC0F7, 0xC7E4, 0xC0F8, 0xC7E8,
+	0xC0F9, 0xC7EC, 0xC0FA, 0xC800, 0xC0FB, 0xC801, 0xC0FC, 0xC804,
+	0xC0FD, 0xC808, 0xC0FE, 0xC80A, 0xC141, 0xD564, 0xC142, 0xD566,
+	0xC143, 0xD567, 0xC144, 0xD56A, 0xC145, 0xD56C, 0xC146, 0xD56E,
+	0xC147, 0xD56F, 0xC148, 0xD570, 0xC149, 0xD571, 0xC14A, 0xD572,
+	0xC14B, 0xD573, 0xC14C, 0xD576, 0xC14D, 0xD577, 0xC14E, 0xD579,
+	0xC14F, 0xD57A, 0xC150, 0xD57B, 0xC151, 0xD57D, 0xC152, 0xD57E,
+	0xC153, 0xD57F, 0xC154, 0xD580, 0xC155, 0xD581, 0xC156, 0xD582,
+	0xC157, 0xD583, 0xC158, 0xD586, 0xC159, 0xD58A, 0xC15A, 0xD58B,
+	0xC161, 0xD58C, 0xC162, 0xD58D, 0xC163, 0xD58E, 0xC164, 0xD58F,
+	0xC165, 0xD591, 0xC166, 0xD592, 0xC167, 0xD593, 0xC168, 0xD594,
+	0xC169, 0xD595, 0xC16A, 0xD596, 0xC16B, 0xD597, 0xC16C, 0xD598,
+	0xC16D, 0xD599, 0xC16E, 0xD59A, 0xC16F, 0xD59B, 0xC170, 0xD59C,
+	0xC171, 0xD59D, 0xC172, 0xD59E, 0xC173, 0xD59F, 0xC174, 0xD5A0,
+	0xC175, 0xD5A1, 0xC176, 0xD5A2, 0xC177, 0xD5A3, 0xC178, 0xD5A4,
+	0xC179, 0xD5A6, 0xC17A, 0xD5A7, 0xC181, 0xD5A8, 0xC182, 0xD5A9,
+	0xC183, 0xD5AA, 0xC184, 0xD5AB, 0xC185, 0xD5AC, 0xC186, 0xD5AD,
+	0xC187, 0xD5AE, 0xC188, 0xD5AF, 0xC189, 0xD5B0, 0xC18A, 0xD5B1,
+	0xC18B, 0xD5B2, 0xC18C, 0xD5B3, 0xC18D, 0xD5B4, 0xC18E, 0xD5B5,
+	0xC18F, 0xD5B6, 0xC190, 0xD5B7, 0xC191, 0xD5B8, 0xC192, 0xD5B9,
+	0xC193, 0xD5BA, 0xC194, 0xD5BB, 0xC195, 0xD5BC, 0xC196, 0xD5BD,
+	0xC197, 0xD5BE, 0xC198, 0xD5BF, 0xC199, 0xD5C0, 0xC19A, 0xD5C1,
+	0xC19B, 0xD5C2, 0xC19C, 0xD5C3, 0xC19D, 0xD5C4, 0xC19E, 0xD5C5,
+	0xC19F, 0xD5C6, 0xC1A0, 0xD5C7, 0xC1A1, 0xC810, 0xC1A2, 0xC811,
+	0xC1A3, 0xC813, 0xC1A4, 0xC815, 0xC1A5, 0xC816, 0xC1A6, 0xC81C,
+	0xC1A7, 0xC81D, 0xC1A8, 0xC820, 0xC1A9, 0xC824, 0xC1AA, 0xC82C,
+	0xC1AB, 0xC82D, 0xC1AC, 0xC82F, 0xC1AD, 0xC831, 0xC1AE, 0xC838,
+	0xC1AF, 0xC83C, 0xC1B0, 0xC840, 0xC1B1, 0xC848, 0xC1B2, 0xC849,
+	0xC1B3, 0xC84C, 0xC1B4, 0xC84D, 0xC1B5, 0xC854, 0xC1B6, 0xC870,
+	0xC1B7, 0xC871, 0xC1B8, 0xC874, 0xC1B9, 0xC878, 0xC1BA, 0xC87A,
+	0xC1BB, 0xC880, 0xC1BC, 0xC881, 0xC1BD, 0xC883, 0xC1BE, 0xC885,
+	0xC1BF, 0xC886, 0xC1C0, 0xC887, 0xC1C1, 0xC88B, 0xC1C2, 0xC88C,
+	0xC1C3, 0xC88D, 0xC1C4, 0xC894, 0xC1C5, 0xC89D, 0xC1C6, 0xC89F,
+	0xC1C7, 0xC8A1, 0xC1C8, 0xC8A8, 0xC1C9, 0xC8BC, 0xC1CA, 0xC8BD,
+	0xC1CB, 0xC8C4, 0xC1CC, 0xC8C8, 0xC1CD, 0xC8CC, 0xC1CE, 0xC8D4,
+	0xC1CF, 0xC8D5, 0xC1D0, 0xC8D7, 0xC1D1, 0xC8D9, 0xC1D2, 0xC8E0,
+	0xC1D3, 0xC8E1, 0xC1D4, 0xC8E4, 0xC1D5, 0xC8F5, 0xC1D6, 0xC8FC,
+	0xC1D7, 0xC8FD, 0xC1D8, 0xC900, 0xC1D9, 0xC904, 0xC1DA, 0xC905,
+	0xC1DB, 0xC906, 0xC1DC, 0xC90C, 0xC1DD, 0xC90D, 0xC1DE, 0xC90F,
+	0xC1DF, 0xC911, 0xC1E0, 0xC918, 0xC1E1, 0xC92C, 0xC1E2, 0xC934,
+	0xC1E3, 0xC950, 0xC1E4, 0xC951, 0xC1E5, 0xC954, 0xC1E6, 0xC958,
+	0xC1E7, 0xC960, 0xC1E8, 0xC961, 0xC1E9, 0xC963, 0xC1EA, 0xC96C,
+	0xC1EB, 0xC970, 0xC1EC, 0xC974, 0xC1ED, 0xC97C, 0xC1EE, 0xC988,
+	0xC1EF, 0xC989, 0xC1F0, 0xC98C, 0xC1F1, 0xC990, 0xC1F2, 0xC998,
+	0xC1F3, 0xC999, 0xC1F4, 0xC99B, 0xC1F5, 0xC99D, 0xC1F6, 0xC9C0,
+	0xC1F7, 0xC9C1, 0xC1F8, 0xC9C4, 0xC1F9, 0xC9C7, 0xC1FA, 0xC9C8,
+	0xC1FB, 0xC9CA, 0xC1FC, 0xC9D0, 0xC1FD, 0xC9D1, 0xC1FE, 0xC9D3,
+	0xC241, 0xD5CA, 0xC242, 0xD5CB, 0xC243, 0xD5CD, 0xC244, 0xD5CE,
+	0xC245, 0xD5CF, 0xC246, 0xD5D1, 0xC247, 0xD5D3, 0xC248, 0xD5D4,
+	0xC249, 0xD5D5, 0xC24A, 0xD5D6, 0xC24B, 0xD5D7, 0xC24C, 0xD5DA,
+	0xC24D, 0xD5DC, 0xC24E, 0xD5DE, 0xC24F, 0xD5DF, 0xC250, 0xD5E0,
+	0xC251, 0xD5E1, 0xC252, 0xD5E2, 0xC253, 0xD5E3, 0xC254, 0xD5E6,
+	0xC255, 0xD5E7, 0xC256, 0xD5E9, 0xC257, 0xD5EA, 0xC258, 0xD5EB,
+	0xC259, 0xD5ED, 0xC25A, 0xD5EE, 0xC261, 0xD5EF, 0xC262, 0xD5F0,
+	0xC263, 0xD5F1, 0xC264, 0xD5F2, 0xC265, 0xD5F3, 0xC266, 0xD5F6,
+	0xC267, 0xD5F8, 0xC268, 0xD5FA, 0xC269, 0xD5FB, 0xC26A, 0xD5FC,
+	0xC26B, 0xD5FD, 0xC26C, 0xD5FE, 0xC26D, 0xD5FF, 0xC26E, 0xD602,
+	0xC26F, 0xD603, 0xC270, 0xD605, 0xC271, 0xD606, 0xC272, 0xD607,
+	0xC273, 0xD609, 0xC274, 0xD60A, 0xC275, 0xD60B, 0xC276, 0xD60C,
+	0xC277, 0xD60D, 0xC278, 0xD60E, 0xC279, 0xD60F, 0xC27A, 0xD612,
+	0xC281, 0xD616, 0xC282, 0xD617, 0xC283, 0xD618, 0xC284, 0xD619,
+	0xC285, 0xD61A, 0xC286, 0xD61B, 0xC287, 0xD61D, 0xC288, 0xD61E,
+	0xC289, 0xD61F, 0xC28A, 0xD621, 0xC28B, 0xD622, 0xC28C, 0xD623,
+	0xC28D, 0xD625, 0xC28E, 0xD626, 0xC28F, 0xD627, 0xC290, 0xD628,
+	0xC291, 0xD629, 0xC292, 0xD62A, 0xC293, 0xD62B, 0xC294, 0xD62C,
+	0xC295, 0xD62E, 0xC296, 0xD62F, 0xC297, 0xD630, 0xC298, 0xD631,
+	0xC299, 0xD632, 0xC29A, 0xD633, 0xC29B, 0xD634, 0xC29C, 0xD635,
+	0xC29D, 0xD636, 0xC29E, 0xD637, 0xC29F, 0xD63A, 0xC2A0, 0xD63B,
+	0xC2A1, 0xC9D5, 0xC2A2, 0xC9D6, 0xC2A3, 0xC9D9, 0xC2A4, 0xC9DA,
+	0xC2A5, 0xC9DC, 0xC2A6, 0xC9DD, 0xC2A7, 0xC9E0, 0xC2A8, 0xC9E2,
+	0xC2A9, 0xC9E4, 0xC2AA, 0xC9E7, 0xC2AB, 0xC9EC, 0xC2AC, 0xC9ED,
+	0xC2AD, 0xC9EF, 0xC2AE, 0xC9F0, 0xC2AF, 0xC9F1, 0xC2B0, 0xC9F8,
+	0xC2B1, 0xC9F9, 0xC2B2, 0xC9FC, 0xC2B3, 0xCA00, 0xC2B4, 0xCA08,
+	0xC2B5, 0xCA09, 0xC2B6, 0xCA0B, 0xC2B7, 0xCA0C, 0xC2B8, 0xCA0D,
+	0xC2B9, 0xCA14, 0xC2BA, 0xCA18, 0xC2BB, 0xCA29, 0xC2BC, 0xCA4C,
+	0xC2BD, 0xCA4D, 0xC2BE, 0xCA50, 0xC2BF, 0xCA54, 0xC2C0, 0xCA5C,
+	0xC2C1, 0xCA5D, 0xC2C2, 0xCA5F, 0xC2C3, 0xCA60, 0xC2C4, 0xCA61,
+	0xC2C5, 0xCA68, 0xC2C6, 0xCA7D, 0xC2C7, 0xCA84, 0xC2C8, 0xCA98,
+	0xC2C9, 0xCABC, 0xC2CA, 0xCABD, 0xC2CB, 0xCAC0, 0xC2CC, 0xCAC4,
+	0xC2CD, 0xCACC, 0xC2CE, 0xCACD, 0xC2CF, 0xCACF, 0xC2D0, 0xCAD1,
+	0xC2D1, 0xCAD3, 0xC2D2, 0xCAD8, 0xC2D3, 0xCAD9, 0xC2D4, 0xCAE0,
+	0xC2D5, 0xCAEC, 0xC2D6, 0xCAF4, 0xC2D7, 0xCB08, 0xC2D8, 0xCB10,
+	0xC2D9, 0xCB14, 0xC2DA, 0xCB18, 0xC2DB, 0xCB20, 0xC2DC, 0xCB21,
+	0xC2DD, 0xCB41, 0xC2DE, 0xCB48, 0xC2DF, 0xCB49, 0xC2E0, 0xCB4C,
+	0xC2E1, 0xCB50, 0xC2E2, 0xCB58, 0xC2E3, 0xCB59, 0xC2E4, 0xCB5D,
+	0xC2E5, 0xCB64, 0xC2E6, 0xCB78, 0xC2E7, 0xCB79, 0xC2E8, 0xCB9C,
+	0xC2E9, 0xCBB8, 0xC2EA, 0xCBD4, 0xC2EB, 0xCBE4, 0xC2EC, 0xCBE7,
+	0xC2ED, 0xCBE9, 0xC2EE, 0xCC0C, 0xC2EF, 0xCC0D, 0xC2F0, 0xCC10,
+	0xC2F1, 0xCC14, 0xC2F2, 0xCC1C, 0xC2F3, 0xCC1D, 0xC2F4, 0xCC21,
+	0xC2F5, 0xCC22, 0xC2F6, 0xCC27, 0xC2F7, 0xCC28, 0xC2F8, 0xCC29,
+	0xC2F9, 0xCC2C, 0xC2FA, 0xCC2E, 0xC2FB, 0xCC30, 0xC2FC, 0xCC38,
+	0xC2FD, 0xCC39, 0xC2FE, 0xCC3B, 0xC341, 0xD63D, 0xC342, 0xD63E,
+	0xC343, 0xD63F, 0xC344, 0xD641, 0xC345, 0xD642, 0xC346, 0xD643,
+	0xC347, 0xD644, 0xC348, 0xD646, 0xC349, 0xD647, 0xC34A, 0xD64A,
+	0xC34B, 0xD64C, 0xC34C, 0xD64E, 0xC34D, 0xD64F, 0xC34E, 0xD650,
+	0xC34F, 0xD652, 0xC350, 0xD653, 0xC351, 0xD656, 0xC352, 0xD657,
+	0xC353, 0xD659, 0xC354, 0xD65A, 0xC355, 0xD65B, 0xC356, 0xD65D,
+	0xC357, 0xD65E, 0xC358, 0xD65F, 0xC359, 0xD660, 0xC35A, 0xD661,
+	0xC361, 0xD662, 0xC362, 0xD663, 0xC363, 0xD664, 0xC364, 0xD665,
+	0xC365, 0xD666, 0xC366, 0xD668, 0xC367, 0xD66A, 0xC368, 0xD66B,
+	0xC369, 0xD66C, 0xC36A, 0xD66D, 0xC36B, 0xD66E, 0xC36C, 0xD66F,
+	0xC36D, 0xD672, 0xC36E, 0xD673, 0xC36F, 0xD675, 0xC370, 0xD676,
+	0xC371, 0xD677, 0xC372, 0xD678, 0xC373, 0xD679, 0xC374, 0xD67A,
+	0xC375, 0xD67B, 0xC376, 0xD67C, 0xC377, 0xD67D, 0xC378, 0xD67E,
+	0xC379, 0xD67F, 0xC37A, 0xD680, 0xC381, 0xD681, 0xC382, 0xD682,
+	0xC383, 0xD684, 0xC384, 0xD686, 0xC385, 0xD687, 0xC386, 0xD688,
+	0xC387, 0xD689, 0xC388, 0xD68A, 0xC389, 0xD68B, 0xC38A, 0xD68E,
+	0xC38B, 0xD68F, 0xC38C, 0xD691, 0xC38D, 0xD692, 0xC38E, 0xD693,
+	0xC38F, 0xD695, 0xC390, 0xD696, 0xC391, 0xD697, 0xC392, 0xD698,
+	0xC393, 0xD699, 0xC394, 0xD69A, 0xC395, 0xD69B, 0xC396, 0xD69C,
+	0xC397, 0xD69E, 0xC398, 0xD6A0, 0xC399, 0xD6A2, 0xC39A, 0xD6A3,
+	0xC39B, 0xD6A4, 0xC39C, 0xD6A5, 0xC39D, 0xD6A6, 0xC39E, 0xD6A7,
+	0xC39F, 0xD6A9, 0xC3A0, 0xD6AA, 0xC3A1, 0xCC3C, 0xC3A2, 0xCC3D,
+	0xC3A3, 0xCC3E, 0xC3A4, 0xCC44, 0xC3A5, 0xCC45, 0xC3A6, 0xCC48,
+	0xC3A7, 0xCC4C, 0xC3A8, 0xCC54, 0xC3A9, 0xCC55, 0xC3AA, 0xCC57,
+	0xC3AB, 0xCC58, 0xC3AC, 0xCC59, 0xC3AD, 0xCC60, 0xC3AE, 0xCC64,
+	0xC3AF, 0xCC66, 0xC3B0, 0xCC68, 0xC3B1, 0xCC70, 0xC3B2, 0xCC75,
+	0xC3B3, 0xCC98, 0xC3B4, 0xCC99, 0xC3B5, 0xCC9C, 0xC3B6, 0xCCA0,
+	0xC3B7, 0xCCA8, 0xC3B8, 0xCCA9, 0xC3B9, 0xCCAB, 0xC3BA, 0xCCAC,
+	0xC3BB, 0xCCAD, 0xC3BC, 0xCCB4, 0xC3BD, 0xCCB5, 0xC3BE, 0xCCB8,
+	0xC3BF, 0xCCBC, 0xC3C0, 0xCCC4, 0xC3C1, 0xCCC5, 0xC3C2, 0xCCC7,
+	0xC3C3, 0xCCC9, 0xC3C4, 0xCCD0, 0xC3C5, 0xCCD4, 0xC3C6, 0xCCE4,
+	0xC3C7, 0xCCEC, 0xC3C8, 0xCCF0, 0xC3C9, 0xCD01, 0xC3CA, 0xCD08,
+	0xC3CB, 0xCD09, 0xC3CC, 0xCD0C, 0xC3CD, 0xCD10, 0xC3CE, 0xCD18,
+	0xC3CF, 0xCD19, 0xC3D0, 0xCD1B, 0xC3D1, 0xCD1D, 0xC3D2, 0xCD24,
+	0xC3D3, 0xCD28, 0xC3D4, 0xCD2C, 0xC3D5, 0xCD39, 0xC3D6, 0xCD5C,
+	0xC3D7, 0xCD60, 0xC3D8, 0xCD64, 0xC3D9, 0xCD6C, 0xC3DA, 0xCD6D,
+	0xC3DB, 0xCD6F, 0xC3DC, 0xCD71, 0xC3DD, 0xCD78, 0xC3DE, 0xCD88,
+	0xC3DF, 0xCD94, 0xC3E0, 0xCD95, 0xC3E1, 0xCD98, 0xC3E2, 0xCD9C,
+	0xC3E3, 0xCDA4, 0xC3E4, 0xCDA5, 0xC3E5, 0xCDA7, 0xC3E6, 0xCDA9,
+	0xC3E7, 0xCDB0, 0xC3E8, 0xCDC4, 0xC3E9, 0xCDCC, 0xC3EA, 0xCDD0,
+	0xC3EB, 0xCDE8, 0xC3EC, 0xCDEC, 0xC3ED, 0xCDF0, 0xC3EE, 0xCDF8,
+	0xC3EF, 0xCDF9, 0xC3F0, 0xCDFB, 0xC3F1, 0xCDFD, 0xC3F2, 0xCE04,
+	0xC3F3, 0xCE08, 0xC3F4, 0xCE0C, 0xC3F5, 0xCE14, 0xC3F6, 0xCE19,
+	0xC3F7, 0xCE20, 0xC3F8, 0xCE21, 0xC3F9, 0xCE24, 0xC3FA, 0xCE28,
+	0xC3FB, 0xCE30, 0xC3FC, 0xCE31, 0xC3FD, 0xCE33, 0xC3FE, 0xCE35,
+	0xC441, 0xD6AB, 0xC442, 0xD6AD, 0xC443, 0xD6AE, 0xC444, 0xD6AF,
+	0xC445, 0xD6B1, 0xC446, 0xD6B2, 0xC447, 0xD6B3, 0xC448, 0xD6B4,
+	0xC449, 0xD6B5, 0xC44A, 0xD6B6, 0xC44B, 0xD6B7, 0xC44C, 0xD6B8,
+	0xC44D, 0xD6BA, 0xC44E, 0xD6BC, 0xC44F, 0xD6BD, 0xC450, 0xD6BE,
+	0xC451, 0xD6BF, 0xC452, 0xD6C0, 0xC453, 0xD6C1, 0xC454, 0xD6C2,
+	0xC455, 0xD6C3, 0xC456, 0xD6C6, 0xC457, 0xD6C7, 0xC458, 0xD6C9,
+	0xC459, 0xD6CA, 0xC45A, 0xD6CB, 0xC461, 0xD6CD, 0xC462, 0xD6CE,
+	0xC463, 0xD6CF, 0xC464, 0xD6D0, 0xC465, 0xD6D2, 0xC466, 0xD6D3,
+	0xC467, 0xD6D5, 0xC468, 0xD6D6, 0xC469, 0xD6D8, 0xC46A, 0xD6DA,
+	0xC46B, 0xD6DB, 0xC46C, 0xD6DC, 0xC46D, 0xD6DD, 0xC46E, 0xD6DE,
+	0xC46F, 0xD6DF, 0xC470, 0xD6E1, 0xC471, 0xD6E2, 0xC472, 0xD6E3,
+	0xC473, 0xD6E5, 0xC474, 0xD6E6, 0xC475, 0xD6E7, 0xC476, 0xD6E9,
+	0xC477, 0xD6EA, 0xC478, 0xD6EB, 0xC479, 0xD6EC, 0xC47A, 0xD6ED,
+	0xC481, 0xD6EE, 0xC482, 0xD6EF, 0xC483, 0xD6F1, 0xC484, 0xD6F2,
+	0xC485, 0xD6F3, 0xC486, 0xD6F4, 0xC487, 0xD6F6, 0xC488, 0xD6F7,
+	0xC489, 0xD6F8, 0xC48A, 0xD6F9, 0xC48B, 0xD6FA, 0xC48C, 0xD6FB,
+	0xC48D, 0xD6FE, 0xC48E, 0xD6FF, 0xC48F, 0xD701, 0xC490, 0xD702,
+	0xC491, 0xD703, 0xC492, 0xD705, 0xC493, 0xD706, 0xC494, 0xD707,
+	0xC495, 0xD708, 0xC496, 0xD709, 0xC497, 0xD70A, 0xC498, 0xD70B,
+	0xC499, 0xD70C, 0xC49A, 0xD70D, 0xC49B, 0xD70E, 0xC49C, 0xD70F,
+	0xC49D, 0xD710, 0xC49E, 0xD712, 0xC49F, 0xD713, 0xC4A0, 0xD714,
+	0xC4A1, 0xCE58, 0xC4A2, 0xCE59, 0xC4A3, 0xCE5C, 0xC4A4, 0xCE5F,
+	0xC4A5, 0xCE60, 0xC4A6, 0xCE61, 0xC4A7, 0xCE68, 0xC4A8, 0xCE69,
+	0xC4A9, 0xCE6B, 0xC4AA, 0xCE6D, 0xC4AB, 0xCE74, 0xC4AC, 0xCE75,
+	0xC4AD, 0xCE78, 0xC4AE, 0xCE7C, 0xC4AF, 0xCE84, 0xC4B0, 0xCE85,
+	0xC4B1, 0xCE87, 0xC4B2, 0xCE89, 0xC4B3, 0xCE90, 0xC4B4, 0xCE91,
+	0xC4B5, 0xCE94, 0xC4B6, 0xCE98, 0xC4B7, 0xCEA0, 0xC4B8, 0xCEA1,
+	0xC4B9, 0xCEA3, 0xC4BA, 0xCEA4, 0xC4BB, 0xCEA5, 0xC4BC, 0xCEAC,
+	0xC4BD, 0xCEAD, 0xC4BE, 0xCEC1, 0xC4BF, 0xCEE4, 0xC4C0, 0xCEE5,
+	0xC4C1, 0xCEE8, 0xC4C2, 0xCEEB, 0xC4C3, 0xCEEC, 0xC4C4, 0xCEF4,
+	0xC4C5, 0xCEF5, 0xC4C6, 0xCEF7, 0xC4C7, 0xCEF8, 0xC4C8, 0xCEF9,
+	0xC4C9, 0xCF00, 0xC4CA, 0xCF01, 0xC4CB, 0xCF04, 0xC4CC, 0xCF08,
+	0xC4CD, 0xCF10, 0xC4CE, 0xCF11, 0xC4CF, 0xCF13, 0xC4D0, 0xCF15,
+	0xC4D1, 0xCF1C, 0xC4D2, 0xCF20, 0xC4D3, 0xCF24, 0xC4D4, 0xCF2C,
+	0xC4D5, 0xCF2D, 0xC4D6, 0xCF2F, 0xC4D7, 0xCF30, 0xC4D8, 0xCF31,
+	0xC4D9, 0xCF38, 0xC4DA, 0xCF54, 0xC4DB, 0xCF55, 0xC4DC, 0xCF58,
+	0xC4DD, 0xCF5C, 0xC4DE, 0xCF64, 0xC4DF, 0xCF65, 0xC4E0, 0xCF67,
+	0xC4E1, 0xCF69, 0xC4E2, 0xCF70, 0xC4E3, 0xCF71, 0xC4E4, 0xCF74,
+	0xC4E5, 0xCF78, 0xC4E6, 0xCF80, 0xC4E7, 0xCF85, 0xC4E8, 0xCF8C,
+	0xC4E9, 0xCFA1, 0xC4EA, 0xCFA8, 0xC4EB, 0xCFB0, 0xC4EC, 0xCFC4,
+	0xC4ED, 0xCFE0, 0xC4EE, 0xCFE1, 0xC4EF, 0xCFE4, 0xC4F0, 0xCFE8,
+	0xC4F1, 0xCFF0, 0xC4F2, 0xCFF1, 0xC4F3, 0xCFF3, 0xC4F4, 0xCFF5,
+	0xC4F5, 0xCFFC, 0xC4F6, 0xD000, 0xC4F7, 0xD004, 0xC4F8, 0xD011,
+	0xC4F9, 0xD018, 0xC4FA, 0xD02D, 0xC4FB, 0xD034, 0xC4FC, 0xD035,
+	0xC4FD, 0xD038, 0xC4FE, 0xD03C, 0xC541, 0xD715, 0xC542, 0xD716,
+	0xC543, 0xD717, 0xC544, 0xD71A, 0xC545, 0xD71B, 0xC546, 0xD71D,
+	0xC547, 0xD71E, 0xC548, 0xD71F, 0xC549, 0xD721, 0xC54A, 0xD722,
+	0xC54B, 0xD723, 0xC54C, 0xD724, 0xC54D, 0xD725, 0xC54E, 0xD726,
+	0xC54F, 0xD727, 0xC550, 0xD72A, 0xC551, 0xD72C, 0xC552, 0xD72E,
+	0xC553, 0xD72F, 0xC554, 0xD730, 0xC555, 0xD731, 0xC556, 0xD732,
+	0xC557, 0xD733, 0xC558, 0xD736, 0xC559, 0xD737, 0xC55A, 0xD739,
+	0xC561, 0xD73A, 0xC562, 0xD73B, 0xC563, 0xD73D, 0xC564, 0xD73E,
+	0xC565, 0xD73F, 0xC566, 0xD740, 0xC567, 0xD741, 0xC568, 0xD742,
+	0xC569, 0xD743, 0xC56A, 0xD745, 0xC56B, 0xD746, 0xC56C, 0xD748,
+	0xC56D, 0xD74A, 0xC56E, 0xD74B, 0xC56F, 0xD74C, 0xC570, 0xD74D,
+	0xC571, 0xD74E, 0xC572, 0xD74F, 0xC573, 0xD752, 0xC574, 0xD753,
+	0xC575, 0xD755, 0xC576, 0xD75A, 0xC577, 0xD75B, 0xC578, 0xD75C,
+	0xC579, 0xD75D, 0xC57A, 0xD75E, 0xC581, 0xD75F, 0xC582, 0xD762,
+	0xC583, 0xD764, 0xC584, 0xD766, 0xC585, 0xD767, 0xC586, 0xD768,
+	0xC587, 0xD76A, 0xC588, 0xD76B, 0xC589, 0xD76D, 0xC58A, 0xD76E,
+	0xC58B, 0xD76F, 0xC58C, 0xD771, 0xC58D, 0xD772, 0xC58E, 0xD773,
+	0xC58F, 0xD775, 0xC590, 0xD776, 0xC591, 0xD777, 0xC592, 0xD778,
+	0xC593, 0xD779, 0xC594, 0xD77A, 0xC595, 0xD77B, 0xC596, 0xD77E,
+	0xC597, 0xD77F, 0xC598, 0xD780, 0xC599, 0xD782, 0xC59A, 0xD783,
+	0xC59B, 0xD784, 0xC59C, 0xD785, 0xC59D, 0xD786, 0xC59E, 0xD787,
+	0xC59F, 0xD78A, 0xC5A0, 0xD78B, 0xC5A1, 0xD044, 0xC5A2, 0xD045,
+	0xC5A3, 0xD047, 0xC5A4, 0xD049, 0xC5A5, 0xD050, 0xC5A6, 0xD054,
+	0xC5A7, 0xD058, 0xC5A8, 0xD060, 0xC5A9, 0xD06C, 0xC5AA, 0xD06D,
+	0xC5AB, 0xD070, 0xC5AC, 0xD074, 0xC5AD, 0xD07C, 0xC5AE, 0xD07D,
+	0xC5AF, 0xD081, 0xC5B0, 0xD0A4, 0xC5B1, 0xD0A5, 0xC5B2, 0xD0A8,
+	0xC5B3, 0xD0AC, 0xC5B4, 0xD0B4, 0xC5B5, 0xD0B5, 0xC5B6, 0xD0B7,
+	0xC5B7, 0xD0B9, 0xC5B8, 0xD0C0, 0xC5B9, 0xD0C1, 0xC5BA, 0xD0C4,
+	0xC5BB, 0xD0C8, 0xC5BC, 0xD0C9, 0xC5BD, 0xD0D0, 0xC5BE, 0xD0D1,
+	0xC5BF, 0xD0D3, 0xC5C0, 0xD0D4, 0xC5C1, 0xD0D5, 0xC5C2, 0xD0DC,
+	0xC5C3, 0xD0DD, 0xC5C4, 0xD0E0, 0xC5C5, 0xD0E4, 0xC5C6, 0xD0EC,
+	0xC5C7, 0xD0ED, 0xC5C8, 0xD0EF, 0xC5C9, 0xD0F0, 0xC5CA, 0xD0F1,
+	0xC5CB, 0xD0F8, 0xC5CC, 0xD10D, 0xC5CD, 0xD130, 0xC5CE, 0xD131,
+	0xC5CF, 0xD134, 0xC5D0, 0xD138, 0xC5D1, 0xD13A, 0xC5D2, 0xD140,
+	0xC5D3, 0xD141, 0xC5D4, 0xD143, 0xC5D5, 0xD144, 0xC5D6, 0xD145,
+	0xC5D7, 0xD14C, 0xC5D8, 0xD14D, 0xC5D9, 0xD150, 0xC5DA, 0xD154,
+	0xC5DB, 0xD15C, 0xC5DC, 0xD15D, 0xC5DD, 0xD15F, 0xC5DE, 0xD161,
+	0xC5DF, 0xD168, 0xC5E0, 0xD16C, 0xC5E1, 0xD17C, 0xC5E2, 0xD184,
+	0xC5E3, 0xD188, 0xC5E4, 0xD1A0, 0xC5E5, 0xD1A1, 0xC5E6, 0xD1A4,
+	0xC5E7, 0xD1A8, 0xC5E8, 0xD1B0, 0xC5E9, 0xD1B1, 0xC5EA, 0xD1B3,
+	0xC5EB, 0xD1B5, 0xC5EC, 0xD1BA, 0xC5ED, 0xD1BC, 0xC5EE, 0xD1C0,
+	0xC5EF, 0xD1D8, 0xC5F0, 0xD1F4, 0xC5F1, 0xD1F8, 0xC5F2, 0xD207,
+	0xC5F3, 0xD209, 0xC5F4, 0xD210, 0xC5F5, 0xD22C, 0xC5F6, 0xD22D,
+	0xC5F7, 0xD230, 0xC5F8, 0xD234, 0xC5F9, 0xD23C, 0xC5FA, 0xD23D,
+	0xC5FB, 0xD23F, 0xC5FC, 0xD241, 0xC5FD, 0xD248, 0xC5FE, 0xD25C,
+	0xC641, 0xD78D, 0xC642, 0xD78E, 0xC643, 0xD78F, 0xC644, 0xD791,
+	0xC645, 0xD792, 0xC646, 0xD793, 0xC647, 0xD794, 0xC648, 0xD795,
+	0xC649, 0xD796, 0xC64A, 0xD797, 0xC64B, 0xD79A, 0xC64C, 0xD79C,
+	0xC64D, 0xD79E, 0xC64E, 0xD79F, 0xC64F, 0xD7A0, 0xC650, 0xD7A1,
+	0xC651, 0xD7A2, 0xC652, 0xD7A3, 0xC6A1, 0xD264, 0xC6A2, 0xD280,
+	0xC6A3, 0xD281, 0xC6A4, 0xD284, 0xC6A5, 0xD288, 0xC6A6, 0xD290,
+	0xC6A7, 0xD291, 0xC6A8, 0xD295, 0xC6A9, 0xD29C, 0xC6AA, 0xD2A0,
+	0xC6AB, 0xD2A4, 0xC6AC, 0xD2AC, 0xC6AD, 0xD2B1, 0xC6AE, 0xD2B8,
+	0xC6AF, 0xD2B9, 0xC6B0, 0xD2BC, 0xC6B1, 0xD2BF, 0xC6B2, 0xD2C0,
+	0xC6B3, 0xD2C2, 0xC6B4, 0xD2C8, 0xC6B5, 0xD2C9, 0xC6B6, 0xD2CB,
+	0xC6B7, 0xD2D4, 0xC6B8, 0xD2D8, 0xC6B9, 0xD2DC, 0xC6BA, 0xD2E4,
+	0xC6BB, 0xD2E5, 0xC6BC, 0xD2F0, 0xC6BD, 0xD2F1, 0xC6BE, 0xD2F4,
+	0xC6BF, 0xD2F8, 0xC6C0, 0xD300, 0xC6C1, 0xD301, 0xC6C2, 0xD303,
+	0xC6C3, 0xD305, 0xC6C4, 0xD30C, 0xC6C5, 0xD30D, 0xC6C6, 0xD30E,
+	0xC6C7, 0xD310, 0xC6C8, 0xD314, 0xC6C9, 0xD316, 0xC6CA, 0xD31C,
+	0xC6CB, 0xD31D, 0xC6CC, 0xD31F, 0xC6CD, 0xD320, 0xC6CE, 0xD321,
+	0xC6CF, 0xD325, 0xC6D0, 0xD328, 0xC6D1, 0xD329, 0xC6D2, 0xD32C,
+	0xC6D3, 0xD330, 0xC6D4, 0xD338, 0xC6D5, 0xD339, 0xC6D6, 0xD33B,
+	0xC6D7, 0xD33C, 0xC6D8, 0xD33D, 0xC6D9, 0xD344, 0xC6DA, 0xD345,
+	0xC6DB, 0xD37C, 0xC6DC, 0xD37D, 0xC6DD, 0xD380, 0xC6DE, 0xD384,
+	0xC6DF, 0xD38C, 0xC6E0, 0xD38D, 0xC6E1, 0xD38F, 0xC6E2, 0xD390,
+	0xC6E3, 0xD391, 0xC6E4, 0xD398, 0xC6E5, 0xD399, 0xC6E6, 0xD39C,
+	0xC6E7, 0xD3A0, 0xC6E8, 0xD3A8, 0xC6E9, 0xD3A9, 0xC6EA, 0xD3AB,
+	0xC6EB, 0xD3AD, 0xC6EC, 0xD3B4, 0xC6ED, 0xD3B8, 0xC6EE, 0xD3BC,
+	0xC6EF, 0xD3C4, 0xC6F0, 0xD3C5, 0xC6F1, 0xD3C8, 0xC6F2, 0xD3C9,
+	0xC6F3, 0xD3D0, 0xC6F4, 0xD3D8, 0xC6F5, 0xD3E1, 0xC6F6, 0xD3E3,
+	0xC6F7, 0xD3EC, 0xC6F8, 0xD3ED, 0xC6F9, 0xD3F0, 0xC6FA, 0xD3F4,
+	0xC6FB, 0xD3FC, 0xC6FC, 0xD3FD, 0xC6FD, 0xD3FF, 0xC6FE, 0xD401,
+	0xC7A1, 0xD408, 0xC7A2, 0xD41D, 0xC7A3, 0xD440, 0xC7A4, 0xD444,
+	0xC7A5, 0xD45C, 0xC7A6, 0xD460, 0xC7A7, 0xD464, 0xC7A8, 0xD46D,
+	0xC7A9, 0xD46F, 0xC7AA, 0xD478, 0xC7AB, 0xD479, 0xC7AC, 0xD47C,
+	0xC7AD, 0xD47F, 0xC7AE, 0xD480, 0xC7AF, 0xD482, 0xC7B0, 0xD488,
+	0xC7B1, 0xD489, 0xC7B2, 0xD48B, 0xC7B3, 0xD48D, 0xC7B4, 0xD494,
+	0xC7B5, 0xD4A9, 0xC7B6, 0xD4CC, 0xC7B7, 0xD4D0, 0xC7B8, 0xD4D4,
+	0xC7B9, 0xD4DC, 0xC7BA, 0xD4DF, 0xC7BB, 0xD4E8, 0xC7BC, 0xD4EC,
+	0xC7BD, 0xD4F0, 0xC7BE, 0xD4F8, 0xC7BF, 0xD4FB, 0xC7C0, 0xD4FD,
+	0xC7C1, 0xD504, 0xC7C2, 0xD508, 0xC7C3, 0xD50C, 0xC7C4, 0xD514,
+	0xC7C5, 0xD515, 0xC7C6, 0xD517, 0xC7C7, 0xD53C, 0xC7C8, 0xD53D,
+	0xC7C9, 0xD540, 0xC7CA, 0xD544, 0xC7CB, 0xD54C, 0xC7CC, 0xD54D,
+	0xC7CD, 0xD54F, 0xC7CE, 0xD551, 0xC7CF, 0xD558, 0xC7D0, 0xD559,
+	0xC7D1, 0xD55C, 0xC7D2, 0xD560, 0xC7D3, 0xD565, 0xC7D4, 0xD568,
+	0xC7D5, 0xD569, 0xC7D6, 0xD56B, 0xC7D7, 0xD56D, 0xC7D8, 0xD574,
+	0xC7D9, 0xD575, 0xC7DA, 0xD578, 0xC7DB, 0xD57C, 0xC7DC, 0xD584,
+	0xC7DD, 0xD585, 0xC7DE, 0xD587, 0xC7DF, 0xD588, 0xC7E0, 0xD589,
+	0xC7E1, 0xD590, 0xC7E2, 0xD5A5, 0xC7E3, 0xD5C8, 0xC7E4, 0xD5C9,
+	0xC7E5, 0xD5CC, 0xC7E6, 0xD5D0, 0xC7E7, 0xD5D2, 0xC7E8, 0xD5D8,
+	0xC7E9, 0xD5D9, 0xC7EA, 0xD5DB, 0xC7EB, 0xD5DD, 0xC7EC, 0xD5E4,
+	0xC7ED, 0xD5E5, 0xC7EE, 0xD5E8, 0xC7EF, 0xD5EC, 0xC7F0, 0xD5F4,
+	0xC7F1, 0xD5F5, 0xC7F2, 0xD5F7, 0xC7F3, 0xD5F9, 0xC7F4, 0xD600,
+	0xC7F5, 0xD601, 0xC7F6, 0xD604, 0xC7F7, 0xD608, 0xC7F8, 0xD610,
+	0xC7F9, 0xD611, 0xC7FA, 0xD613, 0xC7FB, 0xD614, 0xC7FC, 0xD615,
+	0xC7FD, 0xD61C, 0xC7FE, 0xD620, 0xC8A1, 0xD624, 0xC8A2, 0xD62D,
+	0xC8A3, 0xD638, 0xC8A4, 0xD639, 0xC8A5, 0xD63C, 0xC8A6, 0xD640,
+	0xC8A7, 0xD645, 0xC8A8, 0xD648, 0xC8A9, 0xD649, 0xC8AA, 0xD64B,
+	0xC8AB, 0xD64D, 0xC8AC, 0xD651, 0xC8AD, 0xD654, 0xC8AE, 0xD655,
+	0xC8AF, 0xD658, 0xC8B0, 0xD65C, 0xC8B1, 0xD667, 0xC8B2, 0xD669,
+	0xC8B3, 0xD670, 0xC8B4, 0xD671, 0xC8B5, 0xD674, 0xC8B6, 0xD683,
+	0xC8B7, 0xD685, 0xC8B8, 0xD68C, 0xC8B9, 0xD68D, 0xC8BA, 0xD690,
+	0xC8BB, 0xD694, 0xC8BC, 0xD69D, 0xC8BD, 0xD69F, 0xC8BE, 0xD6A1,
+	0xC8BF, 0xD6A8, 0xC8C0, 0xD6AC, 0xC8C1, 0xD6B0, 0xC8C2, 0xD6B9,
+	0xC8C3, 0xD6BB, 0xC8C4, 0xD6C4, 0xC8C5, 0xD6C5, 0xC8C6, 0xD6C8,
+	0xC8C7, 0xD6CC, 0xC8C8, 0xD6D1, 0xC8C9, 0xD6D4, 0xC8CA, 0xD6D7,
+	0xC8CB, 0xD6D9, 0xC8CC, 0xD6E0, 0xC8CD, 0xD6E4, 0xC8CE, 0xD6E8,
+	0xC8CF, 0xD6F0, 0xC8D0, 0xD6F5, 0xC8D1, 0xD6FC, 0xC8D2, 0xD6FD,
+	0xC8D3, 0xD700, 0xC8D4, 0xD704, 0xC8D5, 0xD711, 0xC8D6, 0xD718,
+	0xC8D7, 0xD719, 0xC8D8, 0xD71C, 0xC8D9, 0xD720, 0xC8DA, 0xD728,
+	0xC8DB, 0xD729, 0xC8DC, 0xD72B, 0xC8DD, 0xD72D, 0xC8DE, 0xD734,
+	0xC8DF, 0xD735, 0xC8E0, 0xD738, 0xC8E1, 0xD73C, 0xC8E2, 0xD744,
+	0xC8E3, 0xD747, 0xC8E4, 0xD749, 0xC8E5, 0xD750, 0xC8E6, 0xD751,
+	0xC8E7, 0xD754, 0xC8E8, 0xD756, 0xC8E9, 0xD757, 0xC8EA, 0xD758,
+	0xC8EB, 0xD759, 0xC8EC, 0xD760, 0xC8ED, 0xD761, 0xC8EE, 0xD763,
+	0xC8EF, 0xD765, 0xC8F0, 0xD769, 0xC8F1, 0xD76C, 0xC8F2, 0xD770,
+	0xC8F3, 0xD774, 0xC8F4, 0xD77C, 0xC8F5, 0xD77D, 0xC8F6, 0xD781,
+	0xC8F7, 0xD788, 0xC8F8, 0xD789, 0xC8F9, 0xD78C, 0xC8FA, 0xD790,
+	0xC8FB, 0xD798, 0xC8FC, 0xD799, 0xC8FD, 0xD79B, 0xC8FE, 0xD79D,
+	0xCAA1, 0x4F3D, 0xCAA2, 0x4F73, 0xCAA3, 0x5047, 0xCAA4, 0x50F9,
+	0xCAA5, 0x52A0, 0xCAA6, 0x53EF, 0xCAA7, 0x5475, 0xCAA8, 0x54E5,
+	0xCAA9, 0x5609, 0xCAAA, 0x5AC1, 0xCAAB, 0x5BB6, 0xCAAC, 0x6687,
+	0xCAAD, 0x67B6, 0xCAAE, 0x67B7, 0xCAAF, 0x67EF, 0xCAB0, 0x6B4C,
+	0xCAB1, 0x73C2, 0xCAB2, 0x75C2, 0xCAB3, 0x7A3C, 0xCAB4, 0x82DB,
+	0xCAB5, 0x8304, 0xCAB6, 0x8857, 0xCAB7, 0x8888, 0xCAB8, 0x8A36,
+	0xCAB9, 0x8CC8, 0xCABA, 0x8DCF, 0xCABB, 0x8EFB, 0xCABC, 0x8FE6,
+	0xCABD, 0x99D5, 0xCABE, 0x523B, 0xCABF, 0x5374, 0xCAC0, 0x5404,
+	0xCAC1, 0x606A, 0xCAC2, 0x6164, 0xCAC3, 0x6BBC, 0xCAC4, 0x73CF,
+	0xCAC5, 0x811A, 0xCAC6, 0x89BA, 0xCAC7, 0x89D2, 0xCAC8, 0x95A3,
+	0xCAC9, 0x4F83, 0xCACA, 0x520A, 0xCACB, 0x58BE, 0xCACC, 0x5978,
+	0xCACD, 0x59E6, 0xCACE, 0x5E72, 0xCACF, 0x5E79, 0xCAD0, 0x61C7,
+	0xCAD1, 0x63C0, 0xCAD2, 0x6746, 0xCAD3, 0x67EC, 0xCAD4, 0x687F,
+	0xCAD5, 0x6F97, 0xCAD6, 0x764E, 0xCAD7, 0x770B, 0xCAD8, 0x78F5,
+	0xCAD9, 0x7A08, 0xCADA, 0x7AFF, 0xCADB, 0x7C21, 0xCADC, 0x809D,
+	0xCADD, 0x826E, 0xCADE, 0x8271, 0xCADF, 0x8AEB, 0xCAE0, 0x9593,
+	0xCAE1, 0x4E6B, 0xCAE2, 0x559D, 0xCAE3, 0x66F7, 0xCAE4, 0x6E34,
+	0xCAE5, 0x78A3, 0xCAE6, 0x7AED, 0xCAE7, 0x845B, 0xCAE8, 0x8910,
+	0xCAE9, 0x874E, 0xCAEA, 0x97A8, 0xCAEB, 0x52D8, 0xCAEC, 0x574E,
+	0xCAED, 0x582A, 0xCAEE, 0x5D4C, 0xCAEF, 0x611F, 0xCAF0, 0x61BE,
+	0xCAF1, 0x6221, 0xCAF2, 0x6562, 0xCAF3, 0x67D1, 0xCAF4, 0x6A44,
+	0xCAF5, 0x6E1B, 0xCAF6, 0x7518, 0xCAF7, 0x75B3, 0xCAF8, 0x76E3,
+	0xCAF9, 0x77B0, 0xCAFA, 0x7D3A, 0xCAFB, 0x90AF, 0xCAFC, 0x9451,
+	0xCAFD, 0x9452, 0xCAFE, 0x9F95, 0xCBA1, 0x5323, 0xCBA2, 0x5CAC,
+	0xCBA3, 0x7532, 0xCBA4, 0x80DB, 0xCBA5, 0x9240, 0xCBA6, 0x9598,
+	0xCBA7, 0x525B, 0xCBA8, 0x5808, 0xCBA9, 0x59DC, 0xCBAA, 0x5CA1,
+	0xCBAB, 0x5D17, 0xCBAC, 0x5EB7, 0xCBAD, 0x5F3A, 0xCBAE, 0x5F4A,
+	0xCBAF, 0x6177, 0xCBB0, 0x6C5F, 0xCBB1, 0x757A, 0xCBB2, 0x7586,
+	0xCBB3, 0x7CE0, 0xCBB4, 0x7D73, 0xCBB5, 0x7DB1, 0xCBB6, 0x7F8C,
+	0xCBB7, 0x8154, 0xCBB8, 0x8221, 0xCBB9, 0x8591, 0xCBBA, 0x8941,
+	0xCBBB, 0x8B1B, 0xCBBC, 0x92FC, 0xCBBD, 0x964D, 0xCBBE, 0x9C47,
+	0xCBBF, 0x4ECB, 0xCBC0, 0x4EF7, 0xCBC1, 0x500B, 0xCBC2, 0x51F1,
+	0xCBC3, 0x584F, 0xCBC4, 0x6137, 0xCBC5, 0x613E, 0xCBC6, 0x6168,
+	0xCBC7, 0x6539, 0xCBC8, 0x69EA, 0xCBC9, 0x6F11, 0xCBCA, 0x75A5,
+	0xCBCB, 0x7686, 0xCBCC, 0x76D6, 0xCBCD, 0x7B87, 0xCBCE, 0x82A5,
+	0xCBCF, 0x84CB, 0xCBD0, 0xF900, 0xCBD1, 0x93A7, 0xCBD2, 0x958B,
+	0xCBD3, 0x5580, 0xCBD4, 0x5BA2, 0xCBD5, 0x5751, 0xCBD6, 0xF901,
+	0xCBD7, 0x7CB3, 0xCBD8, 0x7FB9, 0xCBD9, 0x91B5, 0xCBDA, 0x5028,
+	0xCBDB, 0x53BB, 0xCBDC, 0x5C45, 0xCBDD, 0x5DE8, 0xCBDE, 0x62D2,
+	0xCBDF, 0x636E, 0xCBE0, 0x64DA, 0xCBE1, 0x64E7, 0xCBE2, 0x6E20,
+	0xCBE3, 0x70AC, 0xCBE4, 0x795B, 0xCBE5, 0x8DDD, 0xCBE6, 0x8E1E,
+	0xCBE7, 0xF902, 0xCBE8, 0x907D, 0xCBE9, 0x9245, 0xCBEA, 0x92F8,
+	0xCBEB, 0x4E7E, 0xCBEC, 0x4EF6, 0xCBED, 0x5065, 0xCBEE, 0x5DFE,
+	0xCBEF, 0x5EFA, 0xCBF0, 0x6106, 0xCBF1, 0x6957, 0xCBF2, 0x8171,
+	0xCBF3, 0x8654, 0xCBF4, 0x8E47, 0xCBF5, 0x9375, 0xCBF6, 0x9A2B,
+	0xCBF7, 0x4E5E, 0xCBF8, 0x5091, 0xCBF9, 0x6770, 0xCBFA, 0x6840,
+	0xCBFB, 0x5109, 0xCBFC, 0x528D, 0xCBFD, 0x5292, 0xCBFE, 0x6AA2,
+	0xCCA1, 0x77BC, 0xCCA2, 0x9210, 0xCCA3, 0x9ED4, 0xCCA4, 0x52AB,
+	0xCCA5, 0x602F, 0xCCA6, 0x8FF2, 0xCCA7, 0x5048, 0xCCA8, 0x61A9,
+	0xCCA9, 0x63ED, 0xCCAA, 0x64CA, 0xCCAB, 0x683C, 0xCCAC, 0x6A84,
+	0xCCAD, 0x6FC0, 0xCCAE, 0x8188, 0xCCAF, 0x89A1, 0xCCB0, 0x9694,
+	0xCCB1, 0x5805, 0xCCB2, 0x727D, 0xCCB3, 0x72AC, 0xCCB4, 0x7504,
+	0xCCB5, 0x7D79, 0xCCB6, 0x7E6D, 0xCCB7, 0x80A9, 0xCCB8, 0x898B,
+	0xCCB9, 0x8B74, 0xCCBA, 0x9063, 0xCCBB, 0x9D51, 0xCCBC, 0x6289,
+	0xCCBD, 0x6C7A, 0xCCBE, 0x6F54, 0xCCBF, 0x7D50, 0xCCC0, 0x7F3A,
+	0xCCC1, 0x8A23, 0xCCC2, 0x517C, 0xCCC3, 0x614A, 0xCCC4, 0x7B9D,
+	0xCCC5, 0x8B19, 0xCCC6, 0x9257, 0xCCC7, 0x938C, 0xCCC8, 0x4EAC,
+	0xCCC9, 0x4FD3, 0xCCCA, 0x501E, 0xCCCB, 0x50BE, 0xCCCC, 0x5106,
+	0xCCCD, 0x52C1, 0xCCCE, 0x52CD, 0xCCCF, 0x537F, 0xCCD0, 0x5770,
+	0xCCD1, 0x5883, 0xCCD2, 0x5E9A, 0xCCD3, 0x5F91, 0xCCD4, 0x6176,
+	0xCCD5, 0x61AC, 0xCCD6, 0x64CE, 0xCCD7, 0x656C, 0xCCD8, 0x666F,
+	0xCCD9, 0x66BB, 0xCCDA, 0x66F4, 0xCCDB, 0x6897, 0xCCDC, 0x6D87,
+	0xCCDD, 0x7085, 0xCCDE, 0x70F1, 0xCCDF, 0x749F, 0xCCE0, 0x74A5,
+	0xCCE1, 0x74CA, 0xCCE2, 0x75D9, 0xCCE3, 0x786C, 0xCCE4, 0x78EC,
+	0xCCE5, 0x7ADF, 0xCCE6, 0x7AF6, 0xCCE7, 0x7D45, 0xCCE8, 0x7D93,
+	0xCCE9, 0x8015, 0xCCEA, 0x803F, 0xCCEB, 0x811B, 0xCCEC, 0x8396,
+	0xCCED, 0x8B66, 0xCCEE, 0x8F15, 0xCCEF, 0x9015, 0xCCF0, 0x93E1,
+	0xCCF1, 0x9803, 0xCCF2, 0x9838, 0xCCF3, 0x9A5A, 0xCCF4, 0x9BE8,
+	0xCCF5, 0x4FC2, 0xCCF6, 0x5553, 0xCCF7, 0x583A, 0xCCF8, 0x5951,
+	0xCCF9, 0x5B63, 0xCCFA, 0x5C46, 0xCCFB, 0x60B8, 0xCCFC, 0x6212,
+	0xCCFD, 0x6842, 0xCCFE, 0x68B0, 0xCDA1, 0x68E8, 0xCDA2, 0x6EAA,
+	0xCDA3, 0x754C, 0xCDA4, 0x7678, 0xCDA5, 0x78CE, 0xCDA6, 0x7A3D,
+	0xCDA7, 0x7CFB, 0xCDA8, 0x7E6B, 0xCDA9, 0x7E7C, 0xCDAA, 0x8A08,
+	0xCDAB, 0x8AA1, 0xCDAC, 0x8C3F, 0xCDAD, 0x968E, 0xCDAE, 0x9DC4,
+	0xCDAF, 0x53E4, 0xCDB0, 0x53E9, 0xCDB1, 0x544A, 0xCDB2, 0x5471,
+	0xCDB3, 0x56FA, 0xCDB4, 0x59D1, 0xCDB5, 0x5B64, 0xCDB6, 0x5C3B,
+	0xCDB7, 0x5EAB, 0xCDB8, 0x62F7, 0xCDB9, 0x6537, 0xCDBA, 0x6545,
+	0xCDBB, 0x6572, 0xCDBC, 0x66A0, 0xCDBD, 0x67AF, 0xCDBE, 0x69C1,
+	0xCDBF, 0x6CBD, 0xCDC0, 0x75FC, 0xCDC1, 0x7690, 0xCDC2, 0x777E,
+	0xCDC3, 0x7A3F, 0xCDC4, 0x7F94, 0xCDC5, 0x8003, 0xCDC6, 0x80A1,
+	0xCDC7, 0x818F, 0xCDC8, 0x82E6, 0xCDC9, 0x82FD, 0xCDCA, 0x83F0,
+	0xCDCB, 0x85C1, 0xCDCC, 0x8831, 0xCDCD, 0x88B4, 0xCDCE, 0x8AA5,
+	0xCDCF, 0xF903, 0xCDD0, 0x8F9C, 0xCDD1, 0x932E, 0xCDD2, 0x96C7,
+	0xCDD3, 0x9867, 0xCDD4, 0x9AD8, 0xCDD5, 0x9F13, 0xCDD6, 0x54ED,
+	0xCDD7, 0x659B, 0xCDD8, 0x66F2, 0xCDD9, 0x688F, 0xCDDA, 0x7A40,
+	0xCDDB, 0x8C37, 0xCDDC, 0x9D60, 0xCDDD, 0x56F0, 0xCDDE, 0x5764,
+	0xCDDF, 0x5D11, 0xCDE0, 0x6606, 0xCDE1, 0x68B1, 0xCDE2, 0x68CD,
+	0xCDE3, 0x6EFE, 0xCDE4, 0x7428, 0xCDE5, 0x889E, 0xCDE6, 0x9BE4,
+	0xCDE7, 0x6C68, 0xCDE8, 0xF904, 0xCDE9, 0x9AA8, 0xCDEA, 0x4F9B,
+	0xCDEB, 0x516C, 0xCDEC, 0x5171, 0xCDED, 0x529F, 0xCDEE, 0x5B54,
+	0xCDEF, 0x5DE5, 0xCDF0, 0x6050, 0xCDF1, 0x606D, 0xCDF2, 0x62F1,
+	0xCDF3, 0x63A7, 0xCDF4, 0x653B, 0xCDF5, 0x73D9, 0xCDF6, 0x7A7A,
+	0xCDF7, 0x86A3, 0xCDF8, 0x8CA2, 0xCDF9, 0x978F, 0xCDFA, 0x4E32,
+	0xCDFB, 0x5BE1, 0xCDFC, 0x6208, 0xCDFD, 0x679C, 0xCDFE, 0x74DC,
+	0xCEA1, 0x79D1, 0xCEA2, 0x83D3, 0xCEA3, 0x8A87, 0xCEA4, 0x8AB2,
+	0xCEA5, 0x8DE8, 0xCEA6, 0x904E, 0xCEA7, 0x934B, 0xCEA8, 0x9846,
+	0xCEA9, 0x5ED3, 0xCEAA, 0x69E8, 0xCEAB, 0x85FF, 0xCEAC, 0x90ED,
+	0xCEAD, 0xF905, 0xCEAE, 0x51A0, 0xCEAF, 0x5B98, 0xCEB0, 0x5BEC,
+	0xCEB1, 0x6163, 0xCEB2, 0x68FA, 0xCEB3, 0x6B3E, 0xCEB4, 0x704C,
+	0xCEB5, 0x742F, 0xCEB6, 0x74D8, 0xCEB7, 0x7BA1, 0xCEB8, 0x7F50,
+	0xCEB9, 0x83C5, 0xCEBA, 0x89C0, 0xCEBB, 0x8CAB, 0xCEBC, 0x95DC,
+	0xCEBD, 0x9928, 0xCEBE, 0x522E, 0xCEBF, 0x605D, 0xCEC0, 0x62EC,
+	0xCEC1, 0x9002, 0xCEC2, 0x4F8A, 0xCEC3, 0x5149, 0xCEC4, 0x5321,
+	0xCEC5, 0x58D9, 0xCEC6, 0x5EE3, 0xCEC7, 0x66E0, 0xCEC8, 0x6D38,
+	0xCEC9, 0x709A, 0xCECA, 0x72C2, 0xCECB, 0x73D6, 0xCECC, 0x7B50,
+	0xCECD, 0x80F1, 0xCECE, 0x945B, 0xCECF, 0x5366, 0xCED0, 0x639B,
+	0xCED1, 0x7F6B, 0xCED2, 0x4E56, 0xCED3, 0x5080, 0xCED4, 0x584A,
+	0xCED5, 0x58DE, 0xCED6, 0x602A, 0xCED7, 0x6127, 0xCED8, 0x62D0,
+	0xCED9, 0x69D0, 0xCEDA, 0x9B41, 0xCEDB, 0x5B8F, 0xCEDC, 0x7D18,
+	0xCEDD, 0x80B1, 0xCEDE, 0x8F5F, 0xCEDF, 0x4EA4, 0xCEE0, 0x50D1,
+	0xCEE1, 0x54AC, 0xCEE2, 0x55AC, 0xCEE3, 0x5B0C, 0xCEE4, 0x5DA0,
+	0xCEE5, 0x5DE7, 0xCEE6, 0x652A, 0xCEE7, 0x654E, 0xCEE8, 0x6821,
+	0xCEE9, 0x6A4B, 0xCEEA, 0x72E1, 0xCEEB, 0x768E, 0xCEEC, 0x77EF,
+	0xCEED, 0x7D5E, 0xCEEE, 0x7FF9, 0xCEEF, 0x81A0, 0xCEF0, 0x854E,
+	0xCEF1, 0x86DF, 0xCEF2, 0x8F03, 0xCEF3, 0x8F4E, 0xCEF4, 0x90CA,
+	0xCEF5, 0x9903, 0xCEF6, 0x9A55, 0xCEF7, 0x9BAB, 0xCEF8, 0x4E18,
+	0xCEF9, 0x4E45, 0xCEFA, 0x4E5D, 0xCEFB, 0x4EC7, 0xCEFC, 0x4FF1,
+	0xCEFD, 0x5177, 0xCEFE, 0x52FE, 0xCFA1, 0x5340, 0xCFA2, 0x53E3,
+	0xCFA3, 0x53E5, 0xCFA4, 0x548E, 0xCFA5, 0x5614, 0xCFA6, 0x5775,
+	0xCFA7, 0x57A2, 0xCFA8, 0x5BC7, 0xCFA9, 0x5D87, 0xCFAA, 0x5ED0,
+	0xCFAB, 0x61FC, 0xCFAC, 0x62D8, 0xCFAD, 0x6551, 0xCFAE, 0x67B8,
+	0xCFAF, 0x67E9, 0xCFB0, 0x69CB, 0xCFB1, 0x6B50, 0xCFB2, 0x6BC6,
+	0xCFB3, 0x6BEC, 0xCFB4, 0x6C42, 0xCFB5, 0x6E9D, 0xCFB6, 0x7078,
+	0xCFB7, 0x72D7, 0xCFB8, 0x7396, 0xCFB9, 0x7403, 0xCFBA, 0x77BF,
+	0xCFBB, 0x77E9, 0xCFBC, 0x7A76, 0xCFBD, 0x7D7F, 0xCFBE, 0x8009,
+	0xCFBF, 0x81FC, 0xCFC0, 0x8205, 0xCFC1, 0x820A, 0xCFC2, 0x82DF,
+	0xCFC3, 0x8862, 0xCFC4, 0x8B33, 0xCFC5, 0x8CFC, 0xCFC6, 0x8EC0,
+	0xCFC7, 0x9011, 0xCFC8, 0x90B1, 0xCFC9, 0x9264, 0xCFCA, 0x92B6,
+	0xCFCB, 0x99D2, 0xCFCC, 0x9A45, 0xCFCD, 0x9CE9, 0xCFCE, 0x9DD7,
+	0xCFCF, 0x9F9C, 0xCFD0, 0x570B, 0xCFD1, 0x5C40, 0xCFD2, 0x83CA,
+	0xCFD3, 0x97A0, 0xCFD4, 0x97AB, 0xCFD5, 0x9EB4, 0xCFD6, 0x541B,
+	0xCFD7, 0x7A98, 0xCFD8, 0x7FA4, 0xCFD9, 0x88D9, 0xCFDA, 0x8ECD,
+	0xCFDB, 0x90E1, 0xCFDC, 0x5800, 0xCFDD, 0x5C48, 0xCFDE, 0x6398,
+	0xCFDF, 0x7A9F, 0xCFE0, 0x5BAE, 0xCFE1, 0x5F13, 0xCFE2, 0x7A79,
+	0xCFE3, 0x7AAE, 0xCFE4, 0x828E, 0xCFE5, 0x8EAC, 0xCFE6, 0x5026,
+	0xCFE7, 0x5238, 0xCFE8, 0x52F8, 0xCFE9, 0x5377, 0xCFEA, 0x5708,
+	0xCFEB, 0x62F3, 0xCFEC, 0x6372, 0xCFED, 0x6B0A, 0xCFEE, 0x6DC3,
+	0xCFEF, 0x7737, 0xCFF0, 0x53A5, 0xCFF1, 0x7357, 0xCFF2, 0x8568,
+	0xCFF3, 0x8E76, 0xCFF4, 0x95D5, 0xCFF5, 0x673A, 0xCFF6, 0x6AC3,
+	0xCFF7, 0x6F70, 0xCFF8, 0x8A6D, 0xCFF9, 0x8ECC, 0xCFFA, 0x994B,
+	0xCFFB, 0xF906, 0xCFFC, 0x6677, 0xCFFD, 0x6B78, 0xCFFE, 0x8CB4,
+	0xD0A1, 0x9B3C, 0xD0A2, 0xF907, 0xD0A3, 0x53EB, 0xD0A4, 0x572D,
+	0xD0A5, 0x594E, 0xD0A6, 0x63C6, 0xD0A7, 0x69FB, 0xD0A8, 0x73EA,
+	0xD0A9, 0x7845, 0xD0AA, 0x7ABA, 0xD0AB, 0x7AC5, 0xD0AC, 0x7CFE,
+	0xD0AD, 0x8475, 0xD0AE, 0x898F, 0xD0AF, 0x8D73, 0xD0B0, 0x9035,
+	0xD0B1, 0x95A8, 0xD0B2, 0x52FB, 0xD0B3, 0x5747, 0xD0B4, 0x7547,
+	0xD0B5, 0x7B60, 0xD0B6, 0x83CC, 0xD0B7, 0x921E, 0xD0B8, 0xF908,
+	0xD0B9, 0x6A58, 0xD0BA, 0x514B, 0xD0BB, 0x524B, 0xD0BC, 0x5287,
+	0xD0BD, 0x621F, 0xD0BE, 0x68D8, 0xD0BF, 0x6975, 0xD0C0, 0x9699,
+	0xD0C1, 0x50C5, 0xD0C2, 0x52A4, 0xD0C3, 0x52E4, 0xD0C4, 0x61C3,
+	0xD0C5, 0x65A4, 0xD0C6, 0x6839, 0xD0C7, 0x69FF, 0xD0C8, 0x747E,
+	0xD0C9, 0x7B4B, 0xD0CA, 0x82B9, 0xD0CB, 0x83EB, 0xD0CC, 0x89B2,
+	0xD0CD, 0x8B39, 0xD0CE, 0x8FD1, 0xD0CF, 0x9949, 0xD0D0, 0xF909,
+	0xD0D1, 0x4ECA, 0xD0D2, 0x5997, 0xD0D3, 0x64D2, 0xD0D4, 0x6611,
+	0xD0D5, 0x6A8E, 0xD0D6, 0x7434, 0xD0D7, 0x7981, 0xD0D8, 0x79BD,
+	0xD0D9, 0x82A9, 0xD0DA, 0x887E, 0xD0DB, 0x887F, 0xD0DC, 0x895F,
+	0xD0DD, 0xF90A, 0xD0DE, 0x9326, 0xD0DF, 0x4F0B, 0xD0E0, 0x53CA,
+	0xD0E1, 0x6025, 0xD0E2, 0x6271, 0xD0E3, 0x6C72, 0xD0E4, 0x7D1A,
+	0xD0E5, 0x7D66, 0xD0E6, 0x4E98, 0xD0E7, 0x5162, 0xD0E8, 0x77DC,
+	0xD0E9, 0x80AF, 0xD0EA, 0x4F01, 0xD0EB, 0x4F0E, 0xD0EC, 0x5176,
+	0xD0ED, 0x5180, 0xD0EE, 0x55DC, 0xD0EF, 0x5668, 0xD0F0, 0x573B,
+	0xD0F1, 0x57FA, 0xD0F2, 0x57FC, 0xD0F3, 0x5914, 0xD0F4, 0x5947,
+	0xD0F5, 0x5993, 0xD0F6, 0x5BC4, 0xD0F7, 0x5C90, 0xD0F8, 0x5D0E,
+	0xD0F9, 0x5DF1, 0xD0FA, 0x5E7E, 0xD0FB, 0x5FCC, 0xD0FC, 0x6280,
+	0xD0FD, 0x65D7, 0xD0FE, 0x65E3, 0xD1A1, 0x671E, 0xD1A2, 0x671F,
+	0xD1A3, 0x675E, 0xD1A4, 0x68CB, 0xD1A5, 0x68C4, 0xD1A6, 0x6A5F,
+	0xD1A7, 0x6B3A, 0xD1A8, 0x6C23, 0xD1A9, 0x6C7D, 0xD1AA, 0x6C82,
+	0xD1AB, 0x6DC7, 0xD1AC, 0x7398, 0xD1AD, 0x7426, 0xD1AE, 0x742A,
+	0xD1AF, 0x7482, 0xD1B0, 0x74A3, 0xD1B1, 0x7578, 0xD1B2, 0x757F,
+	0xD1B3, 0x7881, 0xD1B4, 0x78EF, 0xD1B5, 0x7941, 0xD1B6, 0x7947,
+	0xD1B7, 0x7948, 0xD1B8, 0x797A, 0xD1B9, 0x7B95, 0xD1BA, 0x7D00,
+	0xD1BB, 0x7DBA, 0xD1BC, 0x7F88, 0xD1BD, 0x8006, 0xD1BE, 0x802D,
+	0xD1BF, 0x808C, 0xD1C0, 0x8A18, 0xD1C1, 0x8B4F, 0xD1C2, 0x8C48,
+	0xD1C3, 0x8D77, 0xD1C4, 0x9321, 0xD1C5, 0x9324, 0xD1C6, 0x98E2,
+	0xD1C7, 0x9951, 0xD1C8, 0x9A0E, 0xD1C9, 0x9A0F, 0xD1CA, 0x9A65,
+	0xD1CB, 0x9E92, 0xD1CC, 0x7DCA, 0xD1CD, 0x4F76, 0xD1CE, 0x5409,
+	0xD1CF, 0x62EE, 0xD1D0, 0x6854, 0xD1D1, 0x91D1, 0xD1D2, 0x55AB,
+	0xD1D3, 0x513A, 0xD1D4, 0xF90B, 0xD1D5, 0xF90C, 0xD1D6, 0x5A1C,
+	0xD1D7, 0x61E6, 0xD1D8, 0xF90D, 0xD1D9, 0x62CF, 0xD1DA, 0x62FF,
+	0xD1DB, 0xF90E, 0xD1DC, 0xF90F, 0xD1DD, 0xF910, 0xD1DE, 0xF911,
+	0xD1DF, 0xF912, 0xD1E0, 0xF913, 0xD1E1, 0x90A3, 0xD1E2, 0xF914,
+	0xD1E3, 0xF915, 0xD1E4, 0xF916, 0xD1E5, 0xF917, 0xD1E6, 0xF918,
+	0xD1E7, 0x8AFE, 0xD1E8, 0xF919, 0xD1E9, 0xF91A, 0xD1EA, 0xF91B,
+	0xD1EB, 0xF91C, 0xD1EC, 0x6696, 0xD1ED, 0xF91D, 0xD1EE, 0x7156,
+	0xD1EF, 0xF91E, 0xD1F0, 0xF91F, 0xD1F1, 0x96E3, 0xD1F2, 0xF920,
+	0xD1F3, 0x634F, 0xD1F4, 0x637A, 0xD1F5, 0x5357, 0xD1F6, 0xF921,
+	0xD1F7, 0x678F, 0xD1F8, 0x6960, 0xD1F9, 0x6E73, 0xD1FA, 0xF922,
+	0xD1FB, 0x7537, 0xD1FC, 0xF923, 0xD1FD, 0xF924, 0xD1FE, 0xF925,
+	0xD2A1, 0x7D0D, 0xD2A2, 0xF926, 0xD2A3, 0xF927, 0xD2A4, 0x8872,
+	0xD2A5, 0x56CA, 0xD2A6, 0x5A18, 0xD2A7, 0xF928, 0xD2A8, 0xF929,
+	0xD2A9, 0xF92A, 0xD2AA, 0xF92B, 0xD2AB, 0xF92C, 0xD2AC, 0x4E43,
+	0xD2AD, 0xF92D, 0xD2AE, 0x5167, 0xD2AF, 0x5948, 0xD2B0, 0x67F0,
+	0xD2B1, 0x8010, 0xD2B2, 0xF92E, 0xD2B3, 0x5973, 0xD2B4, 0x5E74,
+	0xD2B5, 0x649A, 0xD2B6, 0x79CA, 0xD2B7, 0x5FF5, 0xD2B8, 0x606C,
+	0xD2B9, 0x62C8, 0xD2BA, 0x637B, 0xD2BB, 0x5BE7, 0xD2BC, 0x5BD7,
+	0xD2BD, 0x52AA, 0xD2BE, 0xF92F, 0xD2BF, 0x5974, 0xD2C0, 0x5F29,
+	0xD2C1, 0x6012, 0xD2C2, 0xF930, 0xD2C3, 0xF931, 0xD2C4, 0xF932,
+	0xD2C5, 0x7459, 0xD2C6, 0xF933, 0xD2C7, 0xF934, 0xD2C8, 0xF935,
+	0xD2C9, 0xF936, 0xD2CA, 0xF937, 0xD2CB, 0xF938, 0xD2CC, 0x99D1,
+	0xD2CD, 0xF939, 0xD2CE, 0xF93A, 0xD2CF, 0xF93B, 0xD2D0, 0xF93C,
+	0xD2D1, 0xF93D, 0xD2D2, 0xF93E, 0xD2D3, 0xF93F, 0xD2D4, 0xF940,
+	0xD2D5, 0xF941, 0xD2D6, 0xF942, 0xD2D7, 0xF943, 0xD2D8, 0x6FC3,
+	0xD2D9, 0xF944, 0xD2DA, 0xF945, 0xD2DB, 0x81BF, 0xD2DC, 0x8FB2,
+	0xD2DD, 0x60F1, 0xD2DE, 0xF946, 0xD2DF, 0xF947, 0xD2E0, 0x8166,
+	0xD2E1, 0xF948, 0xD2E2, 0xF949, 0xD2E3, 0x5C3F, 0xD2E4, 0xF94A,
+	0xD2E5, 0xF94B, 0xD2E6, 0xF94C, 0xD2E7, 0xF94D, 0xD2E8, 0xF94E,
+	0xD2E9, 0xF94F, 0xD2EA, 0xF950, 0xD2EB, 0xF951, 0xD2EC, 0x5AE9,
+	0xD2ED, 0x8A25, 0xD2EE, 0x677B, 0xD2EF, 0x7D10, 0xD2F0, 0xF952,
+	0xD2F1, 0xF953, 0xD2F2, 0xF954, 0xD2F3, 0xF955, 0xD2F4, 0xF956,
+	0xD2F5, 0xF957, 0xD2F6, 0x80FD, 0xD2F7, 0xF958, 0xD2F8, 0xF959,
+	0xD2F9, 0x5C3C, 0xD2FA, 0x6CE5, 0xD2FB, 0x533F, 0xD2FC, 0x6EBA,
+	0xD2FD, 0x591A, 0xD2FE, 0x8336, 0xD3A1, 0x4E39, 0xD3A2, 0x4EB6,
+	0xD3A3, 0x4F46, 0xD3A4, 0x55AE, 0xD3A5, 0x5718, 0xD3A6, 0x58C7,
+	0xD3A7, 0x5F56, 0xD3A8, 0x65B7, 0xD3A9, 0x65E6, 0xD3AA, 0x6A80,
+	0xD3AB, 0x6BB5, 0xD3AC, 0x6E4D, 0xD3AD, 0x77ED, 0xD3AE, 0x7AEF,
+	0xD3AF, 0x7C1E, 0xD3B0, 0x7DDE, 0xD3B1, 0x86CB, 0xD3B2, 0x8892,
+	0xD3B3, 0x9132, 0xD3B4, 0x935B, 0xD3B5, 0x64BB, 0xD3B6, 0x6FBE,
+	0xD3B7, 0x737A, 0xD3B8, 0x75B8, 0xD3B9, 0x9054, 0xD3BA, 0x5556,
+	0xD3BB, 0x574D, 0xD3BC, 0x61BA, 0xD3BD, 0x64D4, 0xD3BE, 0x66C7,
+	0xD3BF, 0x6DE1, 0xD3C0, 0x6E5B, 0xD3C1, 0x6F6D, 0xD3C2, 0x6FB9,
+	0xD3C3, 0x75F0, 0xD3C4, 0x8043, 0xD3C5, 0x81BD, 0xD3C6, 0x8541,
+	0xD3C7, 0x8983, 0xD3C8, 0x8AC7, 0xD3C9, 0x8B5A, 0xD3CA, 0x931F,
+	0xD3CB, 0x6C93, 0xD3CC, 0x7553, 0xD3CD, 0x7B54, 0xD3CE, 0x8E0F,
+	0xD3CF, 0x905D, 0xD3D0, 0x5510, 0xD3D1, 0x5802, 0xD3D2, 0x5858,
+	0xD3D3, 0x5E62, 0xD3D4, 0x6207, 0xD3D5, 0x649E, 0xD3D6, 0x68E0,
+	0xD3D7, 0x7576, 0xD3D8, 0x7CD6, 0xD3D9, 0x87B3, 0xD3DA, 0x9EE8,
+	0xD3DB, 0x4EE3, 0xD3DC, 0x5788, 0xD3DD, 0x576E, 0xD3DE, 0x5927,
+	0xD3DF, 0x5C0D, 0xD3E0, 0x5CB1, 0xD3E1, 0x5E36, 0xD3E2, 0x5F85,
+	0xD3E3, 0x6234, 0xD3E4, 0x64E1, 0xD3E5, 0x73B3, 0xD3E6, 0x81FA,
+	0xD3E7, 0x888B, 0xD3E8, 0x8CB8, 0xD3E9, 0x968A, 0xD3EA, 0x9EDB,
+	0xD3EB, 0x5B85, 0xD3EC, 0x5FB7, 0xD3ED, 0x60B3, 0xD3EE, 0x5012,
+	0xD3EF, 0x5200, 0xD3F0, 0x5230, 0xD3F1, 0x5716, 0xD3F2, 0x5835,
+	0xD3F3, 0x5857, 0xD3F4, 0x5C0E, 0xD3F5, 0x5C60, 0xD3F6, 0x5CF6,
+	0xD3F7, 0x5D8B, 0xD3F8, 0x5EA6, 0xD3F9, 0x5F92, 0xD3FA, 0x60BC,
+	0xD3FB, 0x6311, 0xD3FC, 0x6389, 0xD3FD, 0x6417, 0xD3FE, 0x6843,
+	0xD4A1, 0x68F9, 0xD4A2, 0x6AC2, 0xD4A3, 0x6DD8, 0xD4A4, 0x6E21,
+	0xD4A5, 0x6ED4, 0xD4A6, 0x6FE4, 0xD4A7, 0x71FE, 0xD4A8, 0x76DC,
+	0xD4A9, 0x7779, 0xD4AA, 0x79B1, 0xD4AB, 0x7A3B, 0xD4AC, 0x8404,
+	0xD4AD, 0x89A9, 0xD4AE, 0x8CED, 0xD4AF, 0x8DF3, 0xD4B0, 0x8E48,
+	0xD4B1, 0x9003, 0xD4B2, 0x9014, 0xD4B3, 0x9053, 0xD4B4, 0x90FD,
+	0xD4B5, 0x934D, 0xD4B6, 0x9676, 0xD4B7, 0x97DC, 0xD4B8, 0x6BD2,
+	0xD4B9, 0x7006, 0xD4BA, 0x7258, 0xD4BB, 0x72A2, 0xD4BC, 0x7368,
+	0xD4BD, 0x7763, 0xD4BE, 0x79BF, 0xD4BF, 0x7BE4, 0xD4C0, 0x7E9B,
+	0xD4C1, 0x8B80, 0xD4C2, 0x58A9, 0xD4C3, 0x60C7, 0xD4C4, 0x6566,
+	0xD4C5, 0x65FD, 0xD4C6, 0x66BE, 0xD4C7, 0x6C8C, 0xD4C8, 0x711E,
+	0xD4C9, 0x71C9, 0xD4CA, 0x8C5A, 0xD4CB, 0x9813, 0xD4CC, 0x4E6D,
+	0xD4CD, 0x7A81, 0xD4CE, 0x4EDD, 0xD4CF, 0x51AC, 0xD4D0, 0x51CD,
+	0xD4D1, 0x52D5, 0xD4D2, 0x540C, 0xD4D3, 0x61A7, 0xD4D4, 0x6771,
+	0xD4D5, 0x6850, 0xD4D6, 0x68DF, 0xD4D7, 0x6D1E, 0xD4D8, 0x6F7C,
+	0xD4D9, 0x75BC, 0xD4DA, 0x77B3, 0xD4DB, 0x7AE5, 0xD4DC, 0x80F4,
+	0xD4DD, 0x8463, 0xD4DE, 0x9285, 0xD4DF, 0x515C, 0xD4E0, 0x6597,
+	0xD4E1, 0x675C, 0xD4E2, 0x6793, 0xD4E3, 0x75D8, 0xD4E4, 0x7AC7,
+	0xD4E5, 0x8373, 0xD4E6, 0xF95A, 0xD4E7, 0x8C46, 0xD4E8, 0x9017,
+	0xD4E9, 0x982D, 0xD4EA, 0x5C6F, 0xD4EB, 0x81C0, 0xD4EC, 0x829A,
+	0xD4ED, 0x9041, 0xD4EE, 0x906F, 0xD4EF, 0x920D, 0xD4F0, 0x5F97,
+	0xD4F1, 0x5D9D, 0xD4F2, 0x6A59, 0xD4F3, 0x71C8, 0xD4F4, 0x767B,
+	0xD4F5, 0x7B49, 0xD4F6, 0x85E4, 0xD4F7, 0x8B04, 0xD4F8, 0x9127,
+	0xD4F9, 0x9A30, 0xD4FA, 0x5587, 0xD4FB, 0x61F6, 0xD4FC, 0xF95B,
+	0xD4FD, 0x7669, 0xD4FE, 0x7F85, 0xD5A1, 0x863F, 0xD5A2, 0x87BA,
+	0xD5A3, 0x88F8, 0xD5A4, 0x908F, 0xD5A5, 0xF95C, 0xD5A6, 0x6D1B,
+	0xD5A7, 0x70D9, 0xD5A8, 0x73DE, 0xD5A9, 0x7D61, 0xD5AA, 0x843D,
+	0xD5AB, 0xF95D, 0xD5AC, 0x916A, 0xD5AD, 0x99F1, 0xD5AE, 0xF95E,
+	0xD5AF, 0x4E82, 0xD5B0, 0x5375, 0xD5B1, 0x6B04, 0xD5B2, 0x6B12,
+	0xD5B3, 0x703E, 0xD5B4, 0x721B, 0xD5B5, 0x862D, 0xD5B6, 0x9E1E,
+	0xD5B7, 0x524C, 0xD5B8, 0x8FA3, 0xD5B9, 0x5D50, 0xD5BA, 0x64E5,
+	0xD5BB, 0x652C, 0xD5BC, 0x6B16, 0xD5BD, 0x6FEB, 0xD5BE, 0x7C43,
+	0xD5BF, 0x7E9C, 0xD5C0, 0x85CD, 0xD5C1, 0x8964, 0xD5C2, 0x89BD,
+	0xD5C3, 0x62C9, 0xD5C4, 0x81D8, 0xD5C5, 0x881F, 0xD5C6, 0x5ECA,
+	0xD5C7, 0x6717, 0xD5C8, 0x6D6A, 0xD5C9, 0x72FC, 0xD5CA, 0x7405,
+	0xD5CB, 0x746F, 0xD5CC, 0x8782, 0xD5CD, 0x90DE, 0xD5CE, 0x4F86,
+	0xD5CF, 0x5D0D, 0xD5D0, 0x5FA0, 0xD5D1, 0x840A, 0xD5D2, 0x51B7,
+	0xD5D3, 0x63A0, 0xD5D4, 0x7565, 0xD5D5, 0x4EAE, 0xD5D6, 0x5006,
+	0xD5D7, 0x5169, 0xD5D8, 0x51C9, 0xD5D9, 0x6881, 0xD5DA, 0x6A11,
+	0xD5DB, 0x7CAE, 0xD5DC, 0x7CB1, 0xD5DD, 0x7CE7, 0xD5DE, 0x826F,
+	0xD5DF, 0x8AD2, 0xD5E0, 0x8F1B, 0xD5E1, 0x91CF, 0xD5E2, 0x4FB6,
+	0xD5E3, 0x5137, 0xD5E4, 0x52F5, 0xD5E5, 0x5442, 0xD5E6, 0x5EEC,
+	0xD5E7, 0x616E, 0xD5E8, 0x623E, 0xD5E9, 0x65C5, 0xD5EA, 0x6ADA,
+	0xD5EB, 0x6FFE, 0xD5EC, 0x792A, 0xD5ED, 0x85DC, 0xD5EE, 0x8823,
+	0xD5EF, 0x95AD, 0xD5F0, 0x9A62, 0xD5F1, 0x9A6A, 0xD5F2, 0x9E97,
+	0xD5F3, 0x9ECE, 0xD5F4, 0x529B, 0xD5F5, 0x66C6, 0xD5F6, 0x6B77,
+	0xD5F7, 0x701D, 0xD5F8, 0x792B, 0xD5F9, 0x8F62, 0xD5FA, 0x9742,
+	0xD5FB, 0x6190, 0xD5FC, 0x6200, 0xD5FD, 0x6523, 0xD5FE, 0x6F23,
+	0xD6A1, 0x7149, 0xD6A2, 0x7489, 0xD6A3, 0x7DF4, 0xD6A4, 0x806F,
+	0xD6A5, 0x84EE, 0xD6A6, 0x8F26, 0xD6A7, 0x9023, 0xD6A8, 0x934A,
+	0xD6A9, 0x51BD, 0xD6AA, 0x5217, 0xD6AB, 0x52A3, 0xD6AC, 0x6D0C,
+	0xD6AD, 0x70C8, 0xD6AE, 0x88C2, 0xD6AF, 0x5EC9, 0xD6B0, 0x6582,
+	0xD6B1, 0x6BAE, 0xD6B2, 0x6FC2, 0xD6B3, 0x7C3E, 0xD6B4, 0x7375,
+	0xD6B5, 0x4EE4, 0xD6B6, 0x4F36, 0xD6B7, 0x56F9, 0xD6B8, 0xF95F,
+	0xD6B9, 0x5CBA, 0xD6BA, 0x5DBA, 0xD6BB, 0x601C, 0xD6BC, 0x73B2,
+	0xD6BD, 0x7B2D, 0xD6BE, 0x7F9A, 0xD6BF, 0x7FCE, 0xD6C0, 0x8046,
+	0xD6C1, 0x901E, 0xD6C2, 0x9234, 0xD6C3, 0x96F6, 0xD6C4, 0x9748,
+	0xD6C5, 0x9818, 0xD6C6, 0x9F61, 0xD6C7, 0x4F8B, 0xD6C8, 0x6FA7,
+	0xD6C9, 0x79AE, 0xD6CA, 0x91B4, 0xD6CB, 0x96B7, 0xD6CC, 0x52DE,
+	0xD6CD, 0xF960, 0xD6CE, 0x6488, 0xD6CF, 0x64C4, 0xD6D0, 0x6AD3,
+	0xD6D1, 0x6F5E, 0xD6D2, 0x7018, 0xD6D3, 0x7210, 0xD6D4, 0x76E7,
+	0xD6D5, 0x8001, 0xD6D6, 0x8606, 0xD6D7, 0x865C, 0xD6D8, 0x8DEF,
+	0xD6D9, 0x8F05, 0xD6DA, 0x9732, 0xD6DB, 0x9B6F, 0xD6DC, 0x9DFA,
+	0xD6DD, 0x9E75, 0xD6DE, 0x788C, 0xD6DF, 0x797F, 0xD6E0, 0x7DA0,
+	0xD6E1, 0x83C9, 0xD6E2, 0x9304, 0xD6E3, 0x9E7F, 0xD6E4, 0x9E93,
+	0xD6E5, 0x8AD6, 0xD6E6, 0x58DF, 0xD6E7, 0x5F04, 0xD6E8, 0x6727,
+	0xD6E9, 0x7027, 0xD6EA, 0x74CF, 0xD6EB, 0x7C60, 0xD6EC, 0x807E,
+	0xD6ED, 0x5121, 0xD6EE, 0x7028, 0xD6EF, 0x7262, 0xD6F0, 0x78CA,
+	0xD6F1, 0x8CC2, 0xD6F2, 0x8CDA, 0xD6F3, 0x8CF4, 0xD6F4, 0x96F7,
+	0xD6F5, 0x4E86, 0xD6F6, 0x50DA, 0xD6F7, 0x5BEE, 0xD6F8, 0x5ED6,
+	0xD6F9, 0x6599, 0xD6FA, 0x71CE, 0xD6FB, 0x7642, 0xD6FC, 0x77AD,
+	0xD6FD, 0x804A, 0xD6FE, 0x84FC, 0xD7A1, 0x907C, 0xD7A2, 0x9B27,
+	0xD7A3, 0x9F8D, 0xD7A4, 0x58D8, 0xD7A5, 0x5A41, 0xD7A6, 0x5C62,
+	0xD7A7, 0x6A13, 0xD7A8, 0x6DDA, 0xD7A9, 0x6F0F, 0xD7AA, 0x763B,
+	0xD7AB, 0x7D2F, 0xD7AC, 0x7E37, 0xD7AD, 0x851E, 0xD7AE, 0x8938,
+	0xD7AF, 0x93E4, 0xD7B0, 0x964B, 0xD7B1, 0x5289, 0xD7B2, 0x65D2,
+	0xD7B3, 0x67F3, 0xD7B4, 0x69B4, 0xD7B5, 0x6D41, 0xD7B6, 0x6E9C,
+	0xD7B7, 0x700F, 0xD7B8, 0x7409, 0xD7B9, 0x7460, 0xD7BA, 0x7559,
+	0xD7BB, 0x7624, 0xD7BC, 0x786B, 0xD7BD, 0x8B2C, 0xD7BE, 0x985E,
+	0xD7BF, 0x516D, 0xD7C0, 0x622E, 0xD7C1, 0x9678, 0xD7C2, 0x4F96,
+	0xD7C3, 0x502B, 0xD7C4, 0x5D19, 0xD7C5, 0x6DEA, 0xD7C6, 0x7DB8,
+	0xD7C7, 0x8F2A, 0xD7C8, 0x5F8B, 0xD7C9, 0x6144, 0xD7CA, 0x6817,
+	0xD7CB, 0xF961, 0xD7CC, 0x9686, 0xD7CD, 0x52D2, 0xD7CE, 0x808B,
+	0xD7CF, 0x51DC, 0xD7D0, 0x51CC, 0xD7D1, 0x695E, 0xD7D2, 0x7A1C,
+	0xD7D3, 0x7DBE, 0xD7D4, 0x83F1, 0xD7D5, 0x9675, 0xD7D6, 0x4FDA,
+	0xD7D7, 0x5229, 0xD7D8, 0x5398, 0xD7D9, 0x540F, 0xD7DA, 0x550E,
+	0xD7DB, 0x5C65, 0xD7DC, 0x60A7, 0xD7DD, 0x674E, 0xD7DE, 0x68A8,
+	0xD7DF, 0x6D6C, 0xD7E0, 0x7281, 0xD7E1, 0x72F8, 0xD7E2, 0x7406,
+	0xD7E3, 0x7483, 0xD7E4, 0xF962, 0xD7E5, 0x75E2, 0xD7E6, 0x7C6C,
+	0xD7E7, 0x7F79, 0xD7E8, 0x7FB8, 0xD7E9, 0x8389, 0xD7EA, 0x88CF,
+	0xD7EB, 0x88E1, 0xD7EC, 0x91CC, 0xD7ED, 0x91D0, 0xD7EE, 0x96E2,
+	0xD7EF, 0x9BC9, 0xD7F0, 0x541D, 0xD7F1, 0x6F7E, 0xD7F2, 0x71D0,
+	0xD7F3, 0x7498, 0xD7F4, 0x85FA, 0xD7F5, 0x8EAA, 0xD7F6, 0x96A3,
+	0xD7F7, 0x9C57, 0xD7F8, 0x9E9F, 0xD7F9, 0x6797, 0xD7FA, 0x6DCB,
+	0xD7FB, 0x7433, 0xD7FC, 0x81E8, 0xD7FD, 0x9716, 0xD7FE, 0x782C,
+	0xD8A1, 0x7ACB, 0xD8A2, 0x7B20, 0xD8A3, 0x7C92, 0xD8A4, 0x6469,
+	0xD8A5, 0x746A, 0xD8A6, 0x75F2, 0xD8A7, 0x78BC, 0xD8A8, 0x78E8,
+	0xD8A9, 0x99AC, 0xD8AA, 0x9B54, 0xD8AB, 0x9EBB, 0xD8AC, 0x5BDE,
+	0xD8AD, 0x5E55, 0xD8AE, 0x6F20, 0xD8AF, 0x819C, 0xD8B0, 0x83AB,
+	0xD8B1, 0x9088, 0xD8B2, 0x4E07, 0xD8B3, 0x534D, 0xD8B4, 0x5A29,
+	0xD8B5, 0x5DD2, 0xD8B6, 0x5F4E, 0xD8B7, 0x6162, 0xD8B8, 0x633D,
+	0xD8B9, 0x6669, 0xD8BA, 0x66FC, 0xD8BB, 0x6EFF, 0xD8BC, 0x6F2B,
+	0xD8BD, 0x7063, 0xD8BE, 0x779E, 0xD8BF, 0x842C, 0xD8C0, 0x8513,
+	0xD8C1, 0x883B, 0xD8C2, 0x8F13, 0xD8C3, 0x9945, 0xD8C4, 0x9C3B,
+	0xD8C5, 0x551C, 0xD8C6, 0x62B9, 0xD8C7, 0x672B, 0xD8C8, 0x6CAB,
+	0xD8C9, 0x8309, 0xD8CA, 0x896A, 0xD8CB, 0x977A, 0xD8CC, 0x4EA1,
+	0xD8CD, 0x5984, 0xD8CE, 0x5FD8, 0xD8CF, 0x5FD9, 0xD8D0, 0x671B,
+	0xD8D1, 0x7DB2, 0xD8D2, 0x7F54, 0xD8D3, 0x8292, 0xD8D4, 0x832B,
+	0xD8D5, 0x83BD, 0xD8D6, 0x8F1E, 0xD8D7, 0x9099, 0xD8D8, 0x57CB,
+	0xD8D9, 0x59B9, 0xD8DA, 0x5A92, 0xD8DB, 0x5BD0, 0xD8DC, 0x6627,
+	0xD8DD, 0x679A, 0xD8DE, 0x6885, 0xD8DF, 0x6BCF, 0xD8E0, 0x7164,
+	0xD8E1, 0x7F75, 0xD8E2, 0x8CB7, 0xD8E3, 0x8CE3, 0xD8E4, 0x9081,
+	0xD8E5, 0x9B45, 0xD8E6, 0x8108, 0xD8E7, 0x8C8A, 0xD8E8, 0x964C,
+	0xD8E9, 0x9A40, 0xD8EA, 0x9EA5, 0xD8EB, 0x5B5F, 0xD8EC, 0x6C13,
+	0xD8ED, 0x731B, 0xD8EE, 0x76F2, 0xD8EF, 0x76DF, 0xD8F0, 0x840C,
+	0xD8F1, 0x51AA, 0xD8F2, 0x8993, 0xD8F3, 0x514D, 0xD8F4, 0x5195,
+	0xD8F5, 0x52C9, 0xD8F6, 0x68C9, 0xD8F7, 0x6C94, 0xD8F8, 0x7704,
+	0xD8F9, 0x7720, 0xD8FA, 0x7DBF, 0xD8FB, 0x7DEC, 0xD8FC, 0x9762,
+	0xD8FD, 0x9EB5, 0xD8FE, 0x6EC5, 0xD9A1, 0x8511, 0xD9A2, 0x51A5,
+	0xD9A3, 0x540D, 0xD9A4, 0x547D, 0xD9A5, 0x660E, 0xD9A6, 0x669D,
+	0xD9A7, 0x6927, 0xD9A8, 0x6E9F, 0xD9A9, 0x76BF, 0xD9AA, 0x7791,
+	0xD9AB, 0x8317, 0xD9AC, 0x84C2, 0xD9AD, 0x879F, 0xD9AE, 0x9169,
+	0xD9AF, 0x9298, 0xD9B0, 0x9CF4, 0xD9B1, 0x8882, 0xD9B2, 0x4FAE,
+	0xD9B3, 0x5192, 0xD9B4, 0x52DF, 0xD9B5, 0x59C6, 0xD9B6, 0x5E3D,
+	0xD9B7, 0x6155, 0xD9B8, 0x6478, 0xD9B9, 0x6479, 0xD9BA, 0x66AE,
+	0xD9BB, 0x67D0, 0xD9BC, 0x6A21, 0xD9BD, 0x6BCD, 0xD9BE, 0x6BDB,
+	0xD9BF, 0x725F, 0xD9C0, 0x7261, 0xD9C1, 0x7441, 0xD9C2, 0x7738,
+	0xD9C3, 0x77DB, 0xD9C4, 0x8017, 0xD9C5, 0x82BC, 0xD9C6, 0x8305,
+	0xD9C7, 0x8B00, 0xD9C8, 0x8B28, 0xD9C9, 0x8C8C, 0xD9CA, 0x6728,
+	0xD9CB, 0x6C90, 0xD9CC, 0x7267, 0xD9CD, 0x76EE, 0xD9CE, 0x7766,
+	0xD9CF, 0x7A46, 0xD9D0, 0x9DA9, 0xD9D1, 0x6B7F, 0xD9D2, 0x6C92,
+	0xD9D3, 0x5922, 0xD9D4, 0x6726, 0xD9D5, 0x8499, 0xD9D6, 0x536F,
+	0xD9D7, 0x5893, 0xD9D8, 0x5999, 0xD9D9, 0x5EDF, 0xD9DA, 0x63CF,
+	0xD9DB, 0x6634, 0xD9DC, 0x6773, 0xD9DD, 0x6E3A, 0xD9DE, 0x732B,
+	0xD9DF, 0x7AD7, 0xD9E0, 0x82D7, 0xD9E1, 0x9328, 0xD9E2, 0x52D9,
+	0xD9E3, 0x5DEB, 0xD9E4, 0x61AE, 0xD9E5, 0x61CB, 0xD9E6, 0x620A,
+	0xD9E7, 0x62C7, 0xD9E8, 0x64AB, 0xD9E9, 0x65E0, 0xD9EA, 0x6959,
+	0xD9EB, 0x6B66, 0xD9EC, 0x6BCB, 0xD9ED, 0x7121, 0xD9EE, 0x73F7,
+	0xD9EF, 0x755D, 0xD9F0, 0x7E46, 0xD9F1, 0x821E, 0xD9F2, 0x8302,
+	0xD9F3, 0x856A, 0xD9F4, 0x8AA3, 0xD9F5, 0x8CBF, 0xD9F6, 0x9727,
+	0xD9F7, 0x9D61, 0xD9F8, 0x58A8, 0xD9F9, 0x9ED8, 0xD9FA, 0x5011,
+	0xD9FB, 0x520E, 0xD9FC, 0x543B, 0xD9FD, 0x554F, 0xD9FE, 0x6587,
+	0xDAA1, 0x6C76, 0xDAA2, 0x7D0A, 0xDAA3, 0x7D0B, 0xDAA4, 0x805E,
+	0xDAA5, 0x868A, 0xDAA6, 0x9580, 0xDAA7, 0x96EF, 0xDAA8, 0x52FF,
+	0xDAA9, 0x6C95, 0xDAAA, 0x7269, 0xDAAB, 0x5473, 0xDAAC, 0x5A9A,
+	0xDAAD, 0x5C3E, 0xDAAE, 0x5D4B, 0xDAAF, 0x5F4C, 0xDAB0, 0x5FAE,
+	0xDAB1, 0x672A, 0xDAB2, 0x68B6, 0xDAB3, 0x6963, 0xDAB4, 0x6E3C,
+	0xDAB5, 0x6E44, 0xDAB6, 0x7709, 0xDAB7, 0x7C73, 0xDAB8, 0x7F8E,
+	0xDAB9, 0x8587, 0xDABA, 0x8B0E, 0xDABB, 0x8FF7, 0xDABC, 0x9761,
+	0xDABD, 0x9EF4, 0xDABE, 0x5CB7, 0xDABF, 0x60B6, 0xDAC0, 0x610D,
+	0xDAC1, 0x61AB, 0xDAC2, 0x654F, 0xDAC3, 0x65FB, 0xDAC4, 0x65FC,
+	0xDAC5, 0x6C11, 0xDAC6, 0x6CEF, 0xDAC7, 0x739F, 0xDAC8, 0x73C9,
+	0xDAC9, 0x7DE1, 0xDACA, 0x9594, 0xDACB, 0x5BC6, 0xDACC, 0x871C,
+	0xDACD, 0x8B10, 0xDACE, 0x525D, 0xDACF, 0x535A, 0xDAD0, 0x62CD,
+	0xDAD1, 0x640F, 0xDAD2, 0x64B2, 0xDAD3, 0x6734, 0xDAD4, 0x6A38,
+	0xDAD5, 0x6CCA, 0xDAD6, 0x73C0, 0xDAD7, 0x749E, 0xDAD8, 0x7B94,
+	0xDAD9, 0x7C95, 0xDADA, 0x7E1B, 0xDADB, 0x818A, 0xDADC, 0x8236,
+	0xDADD, 0x8584, 0xDADE, 0x8FEB, 0xDADF, 0x96F9, 0xDAE0, 0x99C1,
+	0xDAE1, 0x4F34, 0xDAE2, 0x534A, 0xDAE3, 0x53CD, 0xDAE4, 0x53DB,
+	0xDAE5, 0x62CC, 0xDAE6, 0x642C, 0xDAE7, 0x6500, 0xDAE8, 0x6591,
+	0xDAE9, 0x69C3, 0xDAEA, 0x6CEE, 0xDAEB, 0x6F58, 0xDAEC, 0x73ED,
+	0xDAED, 0x7554, 0xDAEE, 0x7622, 0xDAEF, 0x76E4, 0xDAF0, 0x76FC,
+	0xDAF1, 0x78D0, 0xDAF2, 0x78FB, 0xDAF3, 0x792C, 0xDAF4, 0x7D46,
+	0xDAF5, 0x822C, 0xDAF6, 0x87E0, 0xDAF7, 0x8FD4, 0xDAF8, 0x9812,
+	0xDAF9, 0x98EF, 0xDAFA, 0x52C3, 0xDAFB, 0x62D4, 0xDAFC, 0x64A5,
+	0xDAFD, 0x6E24, 0xDAFE, 0x6F51, 0xDBA1, 0x767C, 0xDBA2, 0x8DCB,
+	0xDBA3, 0x91B1, 0xDBA4, 0x9262, 0xDBA5, 0x9AEE, 0xDBA6, 0x9B43,
+	0xDBA7, 0x5023, 0xDBA8, 0x508D, 0xDBA9, 0x574A, 0xDBAA, 0x59A8,
+	0xDBAB, 0x5C28, 0xDBAC, 0x5E47, 0xDBAD, 0x5F77, 0xDBAE, 0x623F,
+	0xDBAF, 0x653E, 0xDBB0, 0x65B9, 0xDBB1, 0x65C1, 0xDBB2, 0x6609,
+	0xDBB3, 0x678B, 0xDBB4, 0x699C, 0xDBB5, 0x6EC2, 0xDBB6, 0x78C5,
+	0xDBB7, 0x7D21, 0xDBB8, 0x80AA, 0xDBB9, 0x8180, 0xDBBA, 0x822B,
+	0xDBBB, 0x82B3, 0xDBBC, 0x84A1, 0xDBBD, 0x868C, 0xDBBE, 0x8A2A,
+	0xDBBF, 0x8B17, 0xDBC0, 0x90A6, 0xDBC1, 0x9632, 0xDBC2, 0x9F90,
+	0xDBC3, 0x500D, 0xDBC4, 0x4FF3, 0xDBC5, 0xF963, 0xDBC6, 0x57F9,
+	0xDBC7, 0x5F98, 0xDBC8, 0x62DC, 0xDBC9, 0x6392, 0xDBCA, 0x676F,
+	0xDBCB, 0x6E43, 0xDBCC, 0x7119, 0xDBCD, 0x76C3, 0xDBCE, 0x80CC,
+	0xDBCF, 0x80DA, 0xDBD0, 0x88F4, 0xDBD1, 0x88F5, 0xDBD2, 0x8919,
+	0xDBD3, 0x8CE0, 0xDBD4, 0x8F29, 0xDBD5, 0x914D, 0xDBD6, 0x966A,
+	0xDBD7, 0x4F2F, 0xDBD8, 0x4F70, 0xDBD9, 0x5E1B, 0xDBDA, 0x67CF,
+	0xDBDB, 0x6822, 0xDBDC, 0x767D, 0xDBDD, 0x767E, 0xDBDE, 0x9B44,
+	0xDBDF, 0x5E61, 0xDBE0, 0x6A0A, 0xDBE1, 0x7169, 0xDBE2, 0x71D4,
+	0xDBE3, 0x756A, 0xDBE4, 0xF964, 0xDBE5, 0x7E41, 0xDBE6, 0x8543,
+	0xDBE7, 0x85E9, 0xDBE8, 0x98DC, 0xDBE9, 0x4F10, 0xDBEA, 0x7B4F,
+	0xDBEB, 0x7F70, 0xDBEC, 0x95A5, 0xDBED, 0x51E1, 0xDBEE, 0x5E06,
+	0xDBEF, 0x68B5, 0xDBF0, 0x6C3E, 0xDBF1, 0x6C4E, 0xDBF2, 0x6CDB,
+	0xDBF3, 0x72AF, 0xDBF4, 0x7BC4, 0xDBF5, 0x8303, 0xDBF6, 0x6CD5,
+	0xDBF7, 0x743A, 0xDBF8, 0x50FB, 0xDBF9, 0x5288, 0xDBFA, 0x58C1,
+	0xDBFB, 0x64D8, 0xDBFC, 0x6A97, 0xDBFD, 0x74A7, 0xDBFE, 0x7656,
+	0xDCA1, 0x78A7, 0xDCA2, 0x8617, 0xDCA3, 0x95E2, 0xDCA4, 0x9739,
+	0xDCA5, 0xF965, 0xDCA6, 0x535E, 0xDCA7, 0x5F01, 0xDCA8, 0x8B8A,
+	0xDCA9, 0x8FA8, 0xDCAA, 0x8FAF, 0xDCAB, 0x908A, 0xDCAC, 0x5225,
+	0xDCAD, 0x77A5, 0xDCAE, 0x9C49, 0xDCAF, 0x9F08, 0xDCB0, 0x4E19,
+	0xDCB1, 0x5002, 0xDCB2, 0x5175, 0xDCB3, 0x5C5B, 0xDCB4, 0x5E77,
+	0xDCB5, 0x661E, 0xDCB6, 0x663A, 0xDCB7, 0x67C4, 0xDCB8, 0x68C5,
+	0xDCB9, 0x70B3, 0xDCBA, 0x7501, 0xDCBB, 0x75C5, 0xDCBC, 0x79C9,
+	0xDCBD, 0x7ADD, 0xDCBE, 0x8F27, 0xDCBF, 0x9920, 0xDCC0, 0x9A08,
+	0xDCC1, 0x4FDD, 0xDCC2, 0x5821, 0xDCC3, 0x5831, 0xDCC4, 0x5BF6,
+	0xDCC5, 0x666E, 0xDCC6, 0x6B65, 0xDCC7, 0x6D11, 0xDCC8, 0x6E7A,
+	0xDCC9, 0x6F7D, 0xDCCA, 0x73E4, 0xDCCB, 0x752B, 0xDCCC, 0x83E9,
+	0xDCCD, 0x88DC, 0xDCCE, 0x8913, 0xDCCF, 0x8B5C, 0xDCD0, 0x8F14,
+	0xDCD1, 0x4F0F, 0xDCD2, 0x50D5, 0xDCD3, 0x5310, 0xDCD4, 0x535C,
+	0xDCD5, 0x5B93, 0xDCD6, 0x5FA9, 0xDCD7, 0x670D, 0xDCD8, 0x798F,
+	0xDCD9, 0x8179, 0xDCDA, 0x832F, 0xDCDB, 0x8514, 0xDCDC, 0x8907,
+	0xDCDD, 0x8986, 0xDCDE, 0x8F39, 0xDCDF, 0x8F3B, 0xDCE0, 0x99A5,
+	0xDCE1, 0x9C12, 0xDCE2, 0x672C, 0xDCE3, 0x4E76, 0xDCE4, 0x4FF8,
+	0xDCE5, 0x5949, 0xDCE6, 0x5C01, 0xDCE7, 0x5CEF, 0xDCE8, 0x5CF0,
+	0xDCE9, 0x6367, 0xDCEA, 0x68D2, 0xDCEB, 0x70FD, 0xDCEC, 0x71A2,
+	0xDCED, 0x742B, 0xDCEE, 0x7E2B, 0xDCEF, 0x84EC, 0xDCF0, 0x8702,
+	0xDCF1, 0x9022, 0xDCF2, 0x92D2, 0xDCF3, 0x9CF3, 0xDCF4, 0x4E0D,
+	0xDCF5, 0x4ED8, 0xDCF6, 0x4FEF, 0xDCF7, 0x5085, 0xDCF8, 0x5256,
+	0xDCF9, 0x526F, 0xDCFA, 0x5426, 0xDCFB, 0x5490, 0xDCFC, 0x57E0,
+	0xDCFD, 0x592B, 0xDCFE, 0x5A66, 0xDDA1, 0x5B5A, 0xDDA2, 0x5B75,
+	0xDDA3, 0x5BCC, 0xDDA4, 0x5E9C, 0xDDA5, 0xF966, 0xDDA6, 0x6276,
+	0xDDA7, 0x6577, 0xDDA8, 0x65A7, 0xDDA9, 0x6D6E, 0xDDAA, 0x6EA5,
+	0xDDAB, 0x7236, 0xDDAC, 0x7B26, 0xDDAD, 0x7C3F, 0xDDAE, 0x7F36,
+	0xDDAF, 0x8150, 0xDDB0, 0x8151, 0xDDB1, 0x819A, 0xDDB2, 0x8240,
+	0xDDB3, 0x8299, 0xDDB4, 0x83A9, 0xDDB5, 0x8A03, 0xDDB6, 0x8CA0,
+	0xDDB7, 0x8CE6, 0xDDB8, 0x8CFB, 0xDDB9, 0x8D74, 0xDDBA, 0x8DBA,
+	0xDDBB, 0x90E8, 0xDDBC, 0x91DC, 0xDDBD, 0x961C, 0xDDBE, 0x9644,
+	0xDDBF, 0x99D9, 0xDDC0, 0x9CE7, 0xDDC1, 0x5317, 0xDDC2, 0x5206,
+	0xDDC3, 0x5429, 0xDDC4, 0x5674, 0xDDC5, 0x58B3, 0xDDC6, 0x5954,
+	0xDDC7, 0x596E, 0xDDC8, 0x5FFF, 0xDDC9, 0x61A4, 0xDDCA, 0x626E,
+	0xDDCB, 0x6610, 0xDDCC, 0x6C7E, 0xDDCD, 0x711A, 0xDDCE, 0x76C6,
+	0xDDCF, 0x7C89, 0xDDD0, 0x7CDE, 0xDDD1, 0x7D1B, 0xDDD2, 0x82AC,
+	0xDDD3, 0x8CC1, 0xDDD4, 0x96F0, 0xDDD5, 0xF967, 0xDDD6, 0x4F5B,
+	0xDDD7, 0x5F17, 0xDDD8, 0x5F7F, 0xDDD9, 0x62C2, 0xDDDA, 0x5D29,
+	0xDDDB, 0x670B, 0xDDDC, 0x68DA, 0xDDDD, 0x787C, 0xDDDE, 0x7E43,
+	0xDDDF, 0x9D6C, 0xDDE0, 0x4E15, 0xDDE1, 0x5099, 0xDDE2, 0x5315,
+	0xDDE3, 0x532A, 0xDDE4, 0x5351, 0xDDE5, 0x5983, 0xDDE6, 0x5A62,
+	0xDDE7, 0x5E87, 0xDDE8, 0x60B2, 0xDDE9, 0x618A, 0xDDEA, 0x6249,
+	0xDDEB, 0x6279, 0xDDEC, 0x6590, 0xDDED, 0x6787, 0xDDEE, 0x69A7,
+	0xDDEF, 0x6BD4, 0xDDF0, 0x6BD6, 0xDDF1, 0x6BD7, 0xDDF2, 0x6BD8,
+	0xDDF3, 0x6CB8, 0xDDF4, 0xF968, 0xDDF5, 0x7435, 0xDDF6, 0x75FA,
+	0xDDF7, 0x7812, 0xDDF8, 0x7891, 0xDDF9, 0x79D5, 0xDDFA, 0x79D8,
+	0xDDFB, 0x7C83, 0xDDFC, 0x7DCB, 0xDDFD, 0x7FE1, 0xDDFE, 0x80A5,
+	0xDEA1, 0x813E, 0xDEA2, 0x81C2, 0xDEA3, 0x83F2, 0xDEA4, 0x871A,
+	0xDEA5, 0x88E8, 0xDEA6, 0x8AB9, 0xDEA7, 0x8B6C, 0xDEA8, 0x8CBB,
+	0xDEA9, 0x9119, 0xDEAA, 0x975E, 0xDEAB, 0x98DB, 0xDEAC, 0x9F3B,
+	0xDEAD, 0x56AC, 0xDEAE, 0x5B2A, 0xDEAF, 0x5F6C, 0xDEB0, 0x658C,
+	0xDEB1, 0x6AB3, 0xDEB2, 0x6BAF, 0xDEB3, 0x6D5C, 0xDEB4, 0x6FF1,
+	0xDEB5, 0x7015, 0xDEB6, 0x725D, 0xDEB7, 0x73AD, 0xDEB8, 0x8CA7,
+	0xDEB9, 0x8CD3, 0xDEBA, 0x983B, 0xDEBB, 0x6191, 0xDEBC, 0x6C37,
+	0xDEBD, 0x8058, 0xDEBE, 0x9A01, 0xDEBF, 0x4E4D, 0xDEC0, 0x4E8B,
+	0xDEC1, 0x4E9B, 0xDEC2, 0x4ED5, 0xDEC3, 0x4F3A, 0xDEC4, 0x4F3C,
+	0xDEC5, 0x4F7F, 0xDEC6, 0x4FDF, 0xDEC7, 0x50FF, 0xDEC8, 0x53F2,
+	0xDEC9, 0x53F8, 0xDECA, 0x5506, 0xDECB, 0x55E3, 0xDECC, 0x56DB,
+	0xDECD, 0x58EB, 0xDECE, 0x5962, 0xDECF, 0x5A11, 0xDED0, 0x5BEB,
+	0xDED1, 0x5BFA, 0xDED2, 0x5C04, 0xDED3, 0x5DF3, 0xDED4, 0x5E2B,
+	0xDED5, 0x5F99, 0xDED6, 0x601D, 0xDED7, 0x6368, 0xDED8, 0x659C,
+	0xDED9, 0x65AF, 0xDEDA, 0x67F6, 0xDEDB, 0x67FB, 0xDEDC, 0x68AD,
+	0xDEDD, 0x6B7B, 0xDEDE, 0x6C99, 0xDEDF, 0x6CD7, 0xDEE0, 0x6E23,
+	0xDEE1, 0x7009, 0xDEE2, 0x7345, 0xDEE3, 0x7802, 0xDEE4, 0x793E,
+	0xDEE5, 0x7940, 0xDEE6, 0x7960, 0xDEE7, 0x79C1, 0xDEE8, 0x7BE9,
+	0xDEE9, 0x7D17, 0xDEEA, 0x7D72, 0xDEEB, 0x8086, 0xDEEC, 0x820D,
+	0xDEED, 0x838E, 0xDEEE, 0x84D1, 0xDEEF, 0x86C7, 0xDEF0, 0x88DF,
+	0xDEF1, 0x8A50, 0xDEF2, 0x8A5E, 0xDEF3, 0x8B1D, 0xDEF4, 0x8CDC,
+	0xDEF5, 0x8D66, 0xDEF6, 0x8FAD, 0xDEF7, 0x90AA, 0xDEF8, 0x98FC,
+	0xDEF9, 0x99DF, 0xDEFA, 0x9E9D, 0xDEFB, 0x524A, 0xDEFC, 0xF969,
+	0xDEFD, 0x6714, 0xDEFE, 0xF96A, 0xDFA1, 0x5098, 0xDFA2, 0x522A,
+	0xDFA3, 0x5C71, 0xDFA4, 0x6563, 0xDFA5, 0x6C55, 0xDFA6, 0x73CA,
+	0xDFA7, 0x7523, 0xDFA8, 0x759D, 0xDFA9, 0x7B97, 0xDFAA, 0x849C,
+	0xDFAB, 0x9178, 0xDFAC, 0x9730, 0xDFAD, 0x4E77, 0xDFAE, 0x6492,
+	0xDFAF, 0x6BBA, 0xDFB0, 0x715E, 0xDFB1, 0x85A9, 0xDFB2, 0x4E09,
+	0xDFB3, 0xF96B, 0xDFB4, 0x6749, 0xDFB5, 0x68EE, 0xDFB6, 0x6E17,
+	0xDFB7, 0x829F, 0xDFB8, 0x8518, 0xDFB9, 0x886B, 0xDFBA, 0x63F7,
+	0xDFBB, 0x6F81, 0xDFBC, 0x9212, 0xDFBD, 0x98AF, 0xDFBE, 0x4E0A,
+	0xDFBF, 0x50B7, 0xDFC0, 0x50CF, 0xDFC1, 0x511F, 0xDFC2, 0x5546,
+	0xDFC3, 0x55AA, 0xDFC4, 0x5617, 0xDFC5, 0x5B40, 0xDFC6, 0x5C19,
+	0xDFC7, 0x5CE0, 0xDFC8, 0x5E38, 0xDFC9, 0x5E8A, 0xDFCA, 0x5EA0,
+	0xDFCB, 0x5EC2, 0xDFCC, 0x60F3, 0xDFCD, 0x6851, 0xDFCE, 0x6A61,
+	0xDFCF, 0x6E58, 0xDFD0, 0x723D, 0xDFD1, 0x7240, 0xDFD2, 0x72C0,
+	0xDFD3, 0x76F8, 0xDFD4, 0x7965, 0xDFD5, 0x7BB1, 0xDFD6, 0x7FD4,
+	0xDFD7, 0x88F3, 0xDFD8, 0x89F4, 0xDFD9, 0x8A73, 0xDFDA, 0x8C61,
+	0xDFDB, 0x8CDE, 0xDFDC, 0x971C, 0xDFDD, 0x585E, 0xDFDE, 0x74BD,
+	0xDFDF, 0x8CFD, 0xDFE0, 0x55C7, 0xDFE1, 0xF96C, 0xDFE2, 0x7A61,
+	0xDFE3, 0x7D22, 0xDFE4, 0x8272, 0xDFE5, 0x7272, 0xDFE6, 0x751F,
+	0xDFE7, 0x7525, 0xDFE8, 0xF96D, 0xDFE9, 0x7B19, 0xDFEA, 0x5885,
+	0xDFEB, 0x58FB, 0xDFEC, 0x5DBC, 0xDFED, 0x5E8F, 0xDFEE, 0x5EB6,
+	0xDFEF, 0x5F90, 0xDFF0, 0x6055, 0xDFF1, 0x6292, 0xDFF2, 0x637F,
+	0xDFF3, 0x654D, 0xDFF4, 0x6691, 0xDFF5, 0x66D9, 0xDFF6, 0x66F8,
+	0xDFF7, 0x6816, 0xDFF8, 0x68F2, 0xDFF9, 0x7280, 0xDFFA, 0x745E,
+	0xDFFB, 0x7B6E, 0xDFFC, 0x7D6E, 0xDFFD, 0x7DD6, 0xDFFE, 0x7F72,
+	0xE0A1, 0x80E5, 0xE0A2, 0x8212, 0xE0A3, 0x85AF, 0xE0A4, 0x897F,
+	0xE0A5, 0x8A93, 0xE0A6, 0x901D, 0xE0A7, 0x92E4, 0xE0A8, 0x9ECD,
+	0xE0A9, 0x9F20, 0xE0AA, 0x5915, 0xE0AB, 0x596D, 0xE0AC, 0x5E2D,
+	0xE0AD, 0x60DC, 0xE0AE, 0x6614, 0xE0AF, 0x6673, 0xE0B0, 0x6790,
+	0xE0B1, 0x6C50, 0xE0B2, 0x6DC5, 0xE0B3, 0x6F5F, 0xE0B4, 0x77F3,
+	0xE0B5, 0x78A9, 0xE0B6, 0x84C6, 0xE0B7, 0x91CB, 0xE0B8, 0x932B,
+	0xE0B9, 0x4ED9, 0xE0BA, 0x50CA, 0xE0BB, 0x5148, 0xE0BC, 0x5584,
+	0xE0BD, 0x5B0B, 0xE0BE, 0x5BA3, 0xE0BF, 0x6247, 0xE0C0, 0x657E,
+	0xE0C1, 0x65CB, 0xE0C2, 0x6E32, 0xE0C3, 0x717D, 0xE0C4, 0x7401,
+	0xE0C5, 0x7444, 0xE0C6, 0x7487, 0xE0C7, 0x74BF, 0xE0C8, 0x766C,
+	0xE0C9, 0x79AA, 0xE0CA, 0x7DDA, 0xE0CB, 0x7E55, 0xE0CC, 0x7FA8,
+	0xE0CD, 0x817A, 0xE0CE, 0x81B3, 0xE0CF, 0x8239, 0xE0D0, 0x861A,
+	0xE0D1, 0x87EC, 0xE0D2, 0x8A75, 0xE0D3, 0x8DE3, 0xE0D4, 0x9078,
+	0xE0D5, 0x9291, 0xE0D6, 0x9425, 0xE0D7, 0x994D, 0xE0D8, 0x9BAE,
+	0xE0D9, 0x5368, 0xE0DA, 0x5C51, 0xE0DB, 0x6954, 0xE0DC, 0x6CC4,
+	0xE0DD, 0x6D29, 0xE0DE, 0x6E2B, 0xE0DF, 0x820C, 0xE0E0, 0x859B,
+	0xE0E1, 0x893B, 0xE0E2, 0x8A2D, 0xE0E3, 0x8AAA, 0xE0E4, 0x96EA,
+	0xE0E5, 0x9F67, 0xE0E6, 0x5261, 0xE0E7, 0x66B9, 0xE0E8, 0x6BB2,
+	0xE0E9, 0x7E96, 0xE0EA, 0x87FE, 0xE0EB, 0x8D0D, 0xE0EC, 0x9583,
+	0xE0ED, 0x965D, 0xE0EE, 0x651D, 0xE0EF, 0x6D89, 0xE0F0, 0x71EE,
+	0xE0F1, 0xF96E, 0xE0F2, 0x57CE, 0xE0F3, 0x59D3, 0xE0F4, 0x5BAC,
+	0xE0F5, 0x6027, 0xE0F6, 0x60FA, 0xE0F7, 0x6210, 0xE0F8, 0x661F,
+	0xE0F9, 0x665F, 0xE0FA, 0x7329, 0xE0FB, 0x73F9, 0xE0FC, 0x76DB,
+	0xE0FD, 0x7701, 0xE0FE, 0x7B6C, 0xE1A1, 0x8056, 0xE1A2, 0x8072,
+	0xE1A3, 0x8165, 0xE1A4, 0x8AA0, 0xE1A5, 0x9192, 0xE1A6, 0x4E16,
+	0xE1A7, 0x52E2, 0xE1A8, 0x6B72, 0xE1A9, 0x6D17, 0xE1AA, 0x7A05,
+	0xE1AB, 0x7B39, 0xE1AC, 0x7D30, 0xE1AD, 0xF96F, 0xE1AE, 0x8CB0,
+	0xE1AF, 0x53EC, 0xE1B0, 0x562F, 0xE1B1, 0x5851, 0xE1B2, 0x5BB5,
+	0xE1B3, 0x5C0F, 0xE1B4, 0x5C11, 0xE1B5, 0x5DE2, 0xE1B6, 0x6240,
+	0xE1B7, 0x6383, 0xE1B8, 0x6414, 0xE1B9, 0x662D, 0xE1BA, 0x68B3,
+	0xE1BB, 0x6CBC, 0xE1BC, 0x6D88, 0xE1BD, 0x6EAF, 0xE1BE, 0x701F,
+	0xE1BF, 0x70A4, 0xE1C0, 0x71D2, 0xE1C1, 0x7526, 0xE1C2, 0x758F,
+	0xE1C3, 0x758E, 0xE1C4, 0x7619, 0xE1C5, 0x7B11, 0xE1C6, 0x7BE0,
+	0xE1C7, 0x7C2B, 0xE1C8, 0x7D20, 0xE1C9, 0x7D39, 0xE1CA, 0x852C,
+	0xE1CB, 0x856D, 0xE1CC, 0x8607, 0xE1CD, 0x8A34, 0xE1CE, 0x900D,
+	0xE1CF, 0x9061, 0xE1D0, 0x90B5, 0xE1D1, 0x92B7, 0xE1D2, 0x97F6,
+	0xE1D3, 0x9A37, 0xE1D4, 0x4FD7, 0xE1D5, 0x5C6C, 0xE1D6, 0x675F,
+	0xE1D7, 0x6D91, 0xE1D8, 0x7C9F, 0xE1D9, 0x7E8C, 0xE1DA, 0x8B16,
+	0xE1DB, 0x8D16, 0xE1DC, 0x901F, 0xE1DD, 0x5B6B, 0xE1DE, 0x5DFD,
+	0xE1DF, 0x640D, 0xE1E0, 0x84C0, 0xE1E1, 0x905C, 0xE1E2, 0x98E1,
+	0xE1E3, 0x7387, 0xE1E4, 0x5B8B, 0xE1E5, 0x609A, 0xE1E6, 0x677E,
+	0xE1E7, 0x6DDE, 0xE1E8, 0x8A1F, 0xE1E9, 0x8AA6, 0xE1EA, 0x9001,
+	0xE1EB, 0x980C, 0xE1EC, 0x5237, 0xE1ED, 0xF970, 0xE1EE, 0x7051,
+	0xE1EF, 0x788E, 0xE1F0, 0x9396, 0xE1F1, 0x8870, 0xE1F2, 0x91D7,
+	0xE1F3, 0x4FEE, 0xE1F4, 0x53D7, 0xE1F5, 0x55FD, 0xE1F6, 0x56DA,
+	0xE1F7, 0x5782, 0xE1F8, 0x58FD, 0xE1F9, 0x5AC2, 0xE1FA, 0x5B88,
+	0xE1FB, 0x5CAB, 0xE1FC, 0x5CC0, 0xE1FD, 0x5E25, 0xE1FE, 0x6101,
+	0xE2A1, 0x620D, 0xE2A2, 0x624B, 0xE2A3, 0x6388, 0xE2A4, 0x641C,
+	0xE2A5, 0x6536, 0xE2A6, 0x6578, 0xE2A7, 0x6A39, 0xE2A8, 0x6B8A,
+	0xE2A9, 0x6C34, 0xE2AA, 0x6D19, 0xE2AB, 0x6F31, 0xE2AC, 0x71E7,
+	0xE2AD, 0x72E9, 0xE2AE, 0x7378, 0xE2AF, 0x7407, 0xE2B0, 0x74B2,
+	0xE2B1, 0x7626, 0xE2B2, 0x7761, 0xE2B3, 0x79C0, 0xE2B4, 0x7A57,
+	0xE2B5, 0x7AEA, 0xE2B6, 0x7CB9, 0xE2B7, 0x7D8F, 0xE2B8, 0x7DAC,
+	0xE2B9, 0x7E61, 0xE2BA, 0x7F9E, 0xE2BB, 0x8129, 0xE2BC, 0x8331,
+	0xE2BD, 0x8490, 0xE2BE, 0x84DA, 0xE2BF, 0x85EA, 0xE2C0, 0x8896,
+	0xE2C1, 0x8AB0, 0xE2C2, 0x8B90, 0xE2C3, 0x8F38, 0xE2C4, 0x9042,
+	0xE2C5, 0x9083, 0xE2C6, 0x916C, 0xE2C7, 0x9296, 0xE2C8, 0x92B9,
+	0xE2C9, 0x968B, 0xE2CA, 0x96A7, 0xE2CB, 0x96A8, 0xE2CC, 0x96D6,
+	0xE2CD, 0x9700, 0xE2CE, 0x9808, 0xE2CF, 0x9996, 0xE2D0, 0x9AD3,
+	0xE2D1, 0x9B1A, 0xE2D2, 0x53D4, 0xE2D3, 0x587E, 0xE2D4, 0x5919,
+	0xE2D5, 0x5B70, 0xE2D6, 0x5BBF, 0xE2D7, 0x6DD1, 0xE2D8, 0x6F5A,
+	0xE2D9, 0x719F, 0xE2DA, 0x7421, 0xE2DB, 0x74B9, 0xE2DC, 0x8085,
+	0xE2DD, 0x83FD, 0xE2DE, 0x5DE1, 0xE2DF, 0x5F87, 0xE2E0, 0x5FAA,
+	0xE2E1, 0x6042, 0xE2E2, 0x65EC, 0xE2E3, 0x6812, 0xE2E4, 0x696F,
+	0xE2E5, 0x6A53, 0xE2E6, 0x6B89, 0xE2E7, 0x6D35, 0xE2E8, 0x6DF3,
+	0xE2E9, 0x73E3, 0xE2EA, 0x76FE, 0xE2EB, 0x77AC, 0xE2EC, 0x7B4D,
+	0xE2ED, 0x7D14, 0xE2EE, 0x8123, 0xE2EF, 0x821C, 0xE2F0, 0x8340,
+	0xE2F1, 0x84F4, 0xE2F2, 0x8563, 0xE2F3, 0x8A62, 0xE2F4, 0x8AC4,
+	0xE2F5, 0x9187, 0xE2F6, 0x931E, 0xE2F7, 0x9806, 0xE2F8, 0x99B4,
+	0xE2F9, 0x620C, 0xE2FA, 0x8853, 0xE2FB, 0x8FF0, 0xE2FC, 0x9265,
+	0xE2FD, 0x5D07, 0xE2FE, 0x5D27, 0xE3A1, 0x5D69, 0xE3A2, 0x745F,
+	0xE3A3, 0x819D, 0xE3A4, 0x8768, 0xE3A5, 0x6FD5, 0xE3A6, 0x62FE,
+	0xE3A7, 0x7FD2, 0xE3A8, 0x8936, 0xE3A9, 0x8972, 0xE3AA, 0x4E1E,
+	0xE3AB, 0x4E58, 0xE3AC, 0x50E7, 0xE3AD, 0x52DD, 0xE3AE, 0x5347,
+	0xE3AF, 0x627F, 0xE3B0, 0x6607, 0xE3B1, 0x7E69, 0xE3B2, 0x8805,
+	0xE3B3, 0x965E, 0xE3B4, 0x4F8D, 0xE3B5, 0x5319, 0xE3B6, 0x5636,
+	0xE3B7, 0x59CB, 0xE3B8, 0x5AA4, 0xE3B9, 0x5C38, 0xE3BA, 0x5C4E,
+	0xE3BB, 0x5C4D, 0xE3BC, 0x5E02, 0xE3BD, 0x5F11, 0xE3BE, 0x6043,
+	0xE3BF, 0x65BD, 0xE3C0, 0x662F, 0xE3C1, 0x6642, 0xE3C2, 0x67BE,
+	0xE3C3, 0x67F4, 0xE3C4, 0x731C, 0xE3C5, 0x77E2, 0xE3C6, 0x793A,
+	0xE3C7, 0x7FC5, 0xE3C8, 0x8494, 0xE3C9, 0x84CD, 0xE3CA, 0x8996,
+	0xE3CB, 0x8A66, 0xE3CC, 0x8A69, 0xE3CD, 0x8AE1, 0xE3CE, 0x8C55,
+	0xE3CF, 0x8C7A, 0xE3D0, 0x57F4, 0xE3D1, 0x5BD4, 0xE3D2, 0x5F0F,
+	0xE3D3, 0x606F, 0xE3D4, 0x62ED, 0xE3D5, 0x690D, 0xE3D6, 0x6B96,
+	0xE3D7, 0x6E5C, 0xE3D8, 0x7184, 0xE3D9, 0x7BD2, 0xE3DA, 0x8755,
+	0xE3DB, 0x8B58, 0xE3DC, 0x8EFE, 0xE3DD, 0x98DF, 0xE3DE, 0x98FE,
+	0xE3DF, 0x4F38, 0xE3E0, 0x4F81, 0xE3E1, 0x4FE1, 0xE3E2, 0x547B,
+	0xE3E3, 0x5A20, 0xE3E4, 0x5BB8, 0xE3E5, 0x613C, 0xE3E6, 0x65B0,
+	0xE3E7, 0x6668, 0xE3E8, 0x71FC, 0xE3E9, 0x7533, 0xE3EA, 0x795E,
+	0xE3EB, 0x7D33, 0xE3EC, 0x814E, 0xE3ED, 0x81E3, 0xE3EE, 0x8398,
+	0xE3EF, 0x85AA, 0xE3F0, 0x85CE, 0xE3F1, 0x8703, 0xE3F2, 0x8A0A,
+	0xE3F3, 0x8EAB, 0xE3F4, 0x8F9B, 0xE3F5, 0xF971, 0xE3F6, 0x8FC5,
+	0xE3F7, 0x5931, 0xE3F8, 0x5BA4, 0xE3F9, 0x5BE6, 0xE3FA, 0x6089,
+	0xE3FB, 0x5BE9, 0xE3FC, 0x5C0B, 0xE3FD, 0x5FC3, 0xE3FE, 0x6C81,
+	0xE4A1, 0xF972, 0xE4A2, 0x6DF1, 0xE4A3, 0x700B, 0xE4A4, 0x751A,
+	0xE4A5, 0x82AF, 0xE4A6, 0x8AF6, 0xE4A7, 0x4EC0, 0xE4A8, 0x5341,
+	0xE4A9, 0xF973, 0xE4AA, 0x96D9, 0xE4AB, 0x6C0F, 0xE4AC, 0x4E9E,
+	0xE4AD, 0x4FC4, 0xE4AE, 0x5152, 0xE4AF, 0x555E, 0xE4B0, 0x5A25,
+	0xE4B1, 0x5CE8, 0xE4B2, 0x6211, 0xE4B3, 0x7259, 0xE4B4, 0x82BD,
+	0xE4B5, 0x83AA, 0xE4B6, 0x86FE, 0xE4B7, 0x8859, 0xE4B8, 0x8A1D,
+	0xE4B9, 0x963F, 0xE4BA, 0x96C5, 0xE4BB, 0x9913, 0xE4BC, 0x9D09,
+	0xE4BD, 0x9D5D, 0xE4BE, 0x580A, 0xE4BF, 0x5CB3, 0xE4C0, 0x5DBD,
+	0xE4C1, 0x5E44, 0xE4C2, 0x60E1, 0xE4C3, 0x6115, 0xE4C4, 0x63E1,
+	0xE4C5, 0x6A02, 0xE4C6, 0x6E25, 0xE4C7, 0x9102, 0xE4C8, 0x9354,
+	0xE4C9, 0x984E, 0xE4CA, 0x9C10, 0xE4CB, 0x9F77, 0xE4CC, 0x5B89,
+	0xE4CD, 0x5CB8, 0xE4CE, 0x6309, 0xE4CF, 0x664F, 0xE4D0, 0x6848,
+	0xE4D1, 0x773C, 0xE4D2, 0x96C1, 0xE4D3, 0x978D, 0xE4D4, 0x9854,
+	0xE4D5, 0x9B9F, 0xE4D6, 0x65A1, 0xE4D7, 0x8B01, 0xE4D8, 0x8ECB,
+	0xE4D9, 0x95BC, 0xE4DA, 0x5535, 0xE4DB, 0x5CA9, 0xE4DC, 0x5DD6,
+	0xE4DD, 0x5EB5, 0xE4DE, 0x6697, 0xE4DF, 0x764C, 0xE4E0, 0x83F4,
+	0xE4E1, 0x95C7, 0xE4E2, 0x58D3, 0xE4E3, 0x62BC, 0xE4E4, 0x72CE,
+	0xE4E5, 0x9D28, 0xE4E6, 0x4EF0, 0xE4E7, 0x592E, 0xE4E8, 0x600F,
+	0xE4E9, 0x663B, 0xE4EA, 0x6B83, 0xE4EB, 0x79E7, 0xE4EC, 0x9D26,
+	0xE4ED, 0x5393, 0xE4EE, 0x54C0, 0xE4EF, 0x57C3, 0xE4F0, 0x5D16,
+	0xE4F1, 0x611B, 0xE4F2, 0x66D6, 0xE4F3, 0x6DAF, 0xE4F4, 0x788D,
+	0xE4F5, 0x827E, 0xE4F6, 0x9698, 0xE4F7, 0x9744, 0xE4F8, 0x5384,
+	0xE4F9, 0x627C, 0xE4FA, 0x6396, 0xE4FB, 0x6DB2, 0xE4FC, 0x7E0A,
+	0xE4FD, 0x814B, 0xE4FE, 0x984D, 0xE5A1, 0x6AFB, 0xE5A2, 0x7F4C,
+	0xE5A3, 0x9DAF, 0xE5A4, 0x9E1A, 0xE5A5, 0x4E5F, 0xE5A6, 0x503B,
+	0xE5A7, 0x51B6, 0xE5A8, 0x591C, 0xE5A9, 0x60F9, 0xE5AA, 0x63F6,
+	0xE5AB, 0x6930, 0xE5AC, 0x723A, 0xE5AD, 0x8036, 0xE5AE, 0xF974,
+	0xE5AF, 0x91CE, 0xE5B0, 0x5F31, 0xE5B1, 0xF975, 0xE5B2, 0xF976,
+	0xE5B3, 0x7D04, 0xE5B4, 0x82E5, 0xE5B5, 0x846F, 0xE5B6, 0x84BB,
+	0xE5B7, 0x85E5, 0xE5B8, 0x8E8D, 0xE5B9, 0xF977, 0xE5BA, 0x4F6F,
+	0xE5BB, 0xF978, 0xE5BC, 0xF979, 0xE5BD, 0x58E4, 0xE5BE, 0x5B43,
+	0xE5BF, 0x6059, 0xE5C0, 0x63DA, 0xE5C1, 0x6518, 0xE5C2, 0x656D,
+	0xE5C3, 0x6698, 0xE5C4, 0xF97A, 0xE5C5, 0x694A, 0xE5C6, 0x6A23,
+	0xE5C7, 0x6D0B, 0xE5C8, 0x7001, 0xE5C9, 0x716C, 0xE5CA, 0x75D2,
+	0xE5CB, 0x760D, 0xE5CC, 0x79B3, 0xE5CD, 0x7A70, 0xE5CE, 0xF97B,
+	0xE5CF, 0x7F8A, 0xE5D0, 0xF97C, 0xE5D1, 0x8944, 0xE5D2, 0xF97D,
+	0xE5D3, 0x8B93, 0xE5D4, 0x91C0, 0xE5D5, 0x967D, 0xE5D6, 0xF97E,
+	0xE5D7, 0x990A, 0xE5D8, 0x5704, 0xE5D9, 0x5FA1, 0xE5DA, 0x65BC,
+	0xE5DB, 0x6F01, 0xE5DC, 0x7600, 0xE5DD, 0x79A6, 0xE5DE, 0x8A9E,
+	0xE5DF, 0x99AD, 0xE5E0, 0x9B5A, 0xE5E1, 0x9F6C, 0xE5E2, 0x5104,
+	0xE5E3, 0x61B6, 0xE5E4, 0x6291, 0xE5E5, 0x6A8D, 0xE5E6, 0x81C6,
+	0xE5E7, 0x5043, 0xE5E8, 0x5830, 0xE5E9, 0x5F66, 0xE5EA, 0x7109,
+	0xE5EB, 0x8A00, 0xE5EC, 0x8AFA, 0xE5ED, 0x5B7C, 0xE5EE, 0x8616,
+	0xE5EF, 0x4FFA, 0xE5F0, 0x513C, 0xE5F1, 0x56B4, 0xE5F2, 0x5944,
+	0xE5F3, 0x63A9, 0xE5F4, 0x6DF9, 0xE5F5, 0x5DAA, 0xE5F6, 0x696D,
+	0xE5F7, 0x5186, 0xE5F8, 0x4E88, 0xE5F9, 0x4F59, 0xE5FA, 0xF97F,
+	0xE5FB, 0xF980, 0xE5FC, 0xF981, 0xE5FD, 0x5982, 0xE5FE, 0xF982,
+	0xE6A1, 0xF983, 0xE6A2, 0x6B5F, 0xE6A3, 0x6C5D, 0xE6A4, 0xF984,
+	0xE6A5, 0x74B5, 0xE6A6, 0x7916, 0xE6A7, 0xF985, 0xE6A8, 0x8207,
+	0xE6A9, 0x8245, 0xE6AA, 0x8339, 0xE6AB, 0x8F3F, 0xE6AC, 0x8F5D,
+	0xE6AD, 0xF986, 0xE6AE, 0x9918, 0xE6AF, 0xF987, 0xE6B0, 0xF988,
+	0xE6B1, 0xF989, 0xE6B2, 0x4EA6, 0xE6B3, 0xF98A, 0xE6B4, 0x57DF,
+	0xE6B5, 0x5F79, 0xE6B6, 0x6613, 0xE6B7, 0xF98B, 0xE6B8, 0xF98C,
+	0xE6B9, 0x75AB, 0xE6BA, 0x7E79, 0xE6BB, 0x8B6F, 0xE6BC, 0xF98D,
+	0xE6BD, 0x9006, 0xE6BE, 0x9A5B, 0xE6BF, 0x56A5, 0xE6C0, 0x5827,
+	0xE6C1, 0x59F8, 0xE6C2, 0x5A1F, 0xE6C3, 0x5BB4, 0xE6C4, 0xF98E,
+	0xE6C5, 0x5EF6, 0xE6C6, 0xF98F, 0xE6C7, 0xF990, 0xE6C8, 0x6350,
+	0xE6C9, 0x633B, 0xE6CA, 0xF991, 0xE6CB, 0x693D, 0xE6CC, 0x6C87,
+	0xE6CD, 0x6CBF, 0xE6CE, 0x6D8E, 0xE6CF, 0x6D93, 0xE6D0, 0x6DF5,
+	0xE6D1, 0x6F14, 0xE6D2, 0xF992, 0xE6D3, 0x70DF, 0xE6D4, 0x7136,
+	0xE6D5, 0x7159, 0xE6D6, 0xF993, 0xE6D7, 0x71C3, 0xE6D8, 0x71D5,
+	0xE6D9, 0xF994, 0xE6DA, 0x784F, 0xE6DB, 0x786F, 0xE6DC, 0xF995,
+	0xE6DD, 0x7B75, 0xE6DE, 0x7DE3, 0xE6DF, 0xF996, 0xE6E0, 0x7E2F,
+	0xE6E1, 0xF997, 0xE6E2, 0x884D, 0xE6E3, 0x8EDF, 0xE6E4, 0xF998,
+	0xE6E5, 0xF999, 0xE6E6, 0xF99A, 0xE6E7, 0x925B, 0xE6E8, 0xF99B,
+	0xE6E9, 0x9CF6, 0xE6EA, 0xF99C, 0xE6EB, 0xF99D, 0xE6EC, 0xF99E,
+	0xE6ED, 0x6085, 0xE6EE, 0x6D85, 0xE6EF, 0xF99F, 0xE6F0, 0x71B1,
+	0xE6F1, 0xF9A0, 0xE6F2, 0xF9A1, 0xE6F3, 0x95B1, 0xE6F4, 0x53AD,
+	0xE6F5, 0xF9A2, 0xE6F6, 0xF9A3, 0xE6F7, 0xF9A4, 0xE6F8, 0x67D3,
+	0xE6F9, 0xF9A5, 0xE6FA, 0x708E, 0xE6FB, 0x7130, 0xE6FC, 0x7430,
+	0xE6FD, 0x8276, 0xE6FE, 0x82D2, 0xE7A1, 0xF9A6, 0xE7A2, 0x95BB,
+	0xE7A3, 0x9AE5, 0xE7A4, 0x9E7D, 0xE7A5, 0x66C4, 0xE7A6, 0xF9A7,
+	0xE7A7, 0x71C1, 0xE7A8, 0x8449, 0xE7A9, 0xF9A8, 0xE7AA, 0xF9A9,
+	0xE7AB, 0x584B, 0xE7AC, 0xF9AA, 0xE7AD, 0xF9AB, 0xE7AE, 0x5DB8,
+	0xE7AF, 0x5F71, 0xE7B0, 0xF9AC, 0xE7B1, 0x6620, 0xE7B2, 0x668E,
+	0xE7B3, 0x6979, 0xE7B4, 0x69AE, 0xE7B5, 0x6C38, 0xE7B6, 0x6CF3,
+	0xE7B7, 0x6E36, 0xE7B8, 0x6F41, 0xE7B9, 0x6FDA, 0xE7BA, 0x701B,
+	0xE7BB, 0x702F, 0xE7BC, 0x7150, 0xE7BD, 0x71DF, 0xE7BE, 0x7370,
+	0xE7BF, 0xF9AD, 0xE7C0, 0x745B, 0xE7C1, 0xF9AE, 0xE7C2, 0x74D4,
+	0xE7C3, 0x76C8, 0xE7C4, 0x7A4E, 0xE7C5, 0x7E93, 0xE7C6, 0xF9AF,
+	0xE7C7, 0xF9B0, 0xE7C8, 0x82F1, 0xE7C9, 0x8A60, 0xE7CA, 0x8FCE,
+	0xE7CB, 0xF9B1, 0xE7CC, 0x9348, 0xE7CD, 0xF9B2, 0xE7CE, 0x9719,
+	0xE7CF, 0xF9B3, 0xE7D0, 0xF9B4, 0xE7D1, 0x4E42, 0xE7D2, 0x502A,
+	0xE7D3, 0xF9B5, 0xE7D4, 0x5208, 0xE7D5, 0x53E1, 0xE7D6, 0x66F3,
+	0xE7D7, 0x6C6D, 0xE7D8, 0x6FCA, 0xE7D9, 0x730A, 0xE7DA, 0x777F,
+	0xE7DB, 0x7A62, 0xE7DC, 0x82AE, 0xE7DD, 0x85DD, 0xE7DE, 0x8602,
+	0xE7DF, 0xF9B6, 0xE7E0, 0x88D4, 0xE7E1, 0x8A63, 0xE7E2, 0x8B7D,
+	0xE7E3, 0x8C6B, 0xE7E4, 0xF9B7, 0xE7E5, 0x92B3, 0xE7E6, 0xF9B8,
+	0xE7E7, 0x9713, 0xE7E8, 0x9810, 0xE7E9, 0x4E94, 0xE7EA, 0x4F0D,
+	0xE7EB, 0x4FC9, 0xE7EC, 0x50B2, 0xE7ED, 0x5348, 0xE7EE, 0x543E,
+	0xE7EF, 0x5433, 0xE7F0, 0x55DA, 0xE7F1, 0x5862, 0xE7F2, 0x58BA,
+	0xE7F3, 0x5967, 0xE7F4, 0x5A1B, 0xE7F5, 0x5BE4, 0xE7F6, 0x609F,
+	0xE7F7, 0xF9B9, 0xE7F8, 0x61CA, 0xE7F9, 0x6556, 0xE7FA, 0x65FF,
+	0xE7FB, 0x6664, 0xE7FC, 0x68A7, 0xE7FD, 0x6C5A, 0xE7FE, 0x6FB3,
+	0xE8A1, 0x70CF, 0xE8A2, 0x71AC, 0xE8A3, 0x7352, 0xE8A4, 0x7B7D,
+	0xE8A5, 0x8708, 0xE8A6, 0x8AA4, 0xE8A7, 0x9C32, 0xE8A8, 0x9F07,
+	0xE8A9, 0x5C4B, 0xE8AA, 0x6C83, 0xE8AB, 0x7344, 0xE8AC, 0x7389,
+	0xE8AD, 0x923A, 0xE8AE, 0x6EAB, 0xE8AF, 0x7465, 0xE8B0, 0x761F,
+	0xE8B1, 0x7A69, 0xE8B2, 0x7E15, 0xE8B3, 0x860A, 0xE8B4, 0x5140,
+	0xE8B5, 0x58C5, 0xE8B6, 0x64C1, 0xE8B7, 0x74EE, 0xE8B8, 0x7515,
+	0xE8B9, 0x7670, 0xE8BA, 0x7FC1, 0xE8BB, 0x9095, 0xE8BC, 0x96CD,
+	0xE8BD, 0x9954, 0xE8BE, 0x6E26, 0xE8BF, 0x74E6, 0xE8C0, 0x7AA9,
+	0xE8C1, 0x7AAA, 0xE8C2, 0x81E5, 0xE8C3, 0x86D9, 0xE8C4, 0x8778,
+	0xE8C5, 0x8A1B, 0xE8C6, 0x5A49, 0xE8C7, 0x5B8C, 0xE8C8, 0x5B9B,
+	0xE8C9, 0x68A1, 0xE8CA, 0x6900, 0xE8CB, 0x6D63, 0xE8CC, 0x73A9,
+	0xE8CD, 0x7413, 0xE8CE, 0x742C, 0xE8CF, 0x7897, 0xE8D0, 0x7DE9,
+	0xE8D1, 0x7FEB, 0xE8D2, 0x8118, 0xE8D3, 0x8155, 0xE8D4, 0x839E,
+	0xE8D5, 0x8C4C, 0xE8D6, 0x962E, 0xE8D7, 0x9811, 0xE8D8, 0x66F0,
+	0xE8D9, 0x5F80, 0xE8DA, 0x65FA, 0xE8DB, 0x6789, 0xE8DC, 0x6C6A,
+	0xE8DD, 0x738B, 0xE8DE, 0x502D, 0xE8DF, 0x5A03, 0xE8E0, 0x6B6A,
+	0xE8E1, 0x77EE, 0xE8E2, 0x5916, 0xE8E3, 0x5D6C, 0xE8E4, 0x5DCD,
+	0xE8E5, 0x7325, 0xE8E6, 0x754F, 0xE8E7, 0xF9BA, 0xE8E8, 0xF9BB,
+	0xE8E9, 0x50E5, 0xE8EA, 0x51F9, 0xE8EB, 0x582F, 0xE8EC, 0x592D,
+	0xE8ED, 0x5996, 0xE8EE, 0x59DA, 0xE8EF, 0x5BE5, 0xE8F0, 0xF9BC,
+	0xE8F1, 0xF9BD, 0xE8F2, 0x5DA2, 0xE8F3, 0x62D7, 0xE8F4, 0x6416,
+	0xE8F5, 0x6493, 0xE8F6, 0x64FE, 0xE8F7, 0xF9BE, 0xE8F8, 0x66DC,
+	0xE8F9, 0xF9BF, 0xE8FA, 0x6A48, 0xE8FB, 0xF9C0, 0xE8FC, 0x71FF,
+	0xE8FD, 0x7464, 0xE8FE, 0xF9C1, 0xE9A1, 0x7A88, 0xE9A2, 0x7AAF,
+	0xE9A3, 0x7E47, 0xE9A4, 0x7E5E, 0xE9A5, 0x8000, 0xE9A6, 0x8170,
+	0xE9A7, 0xF9C2, 0xE9A8, 0x87EF, 0xE9A9, 0x8981, 0xE9AA, 0x8B20,
+	0xE9AB, 0x9059, 0xE9AC, 0xF9C3, 0xE9AD, 0x9080, 0xE9AE, 0x9952,
+	0xE9AF, 0x617E, 0xE9B0, 0x6B32, 0xE9B1, 0x6D74, 0xE9B2, 0x7E1F,
+	0xE9B3, 0x8925, 0xE9B4, 0x8FB1, 0xE9B5, 0x4FD1, 0xE9B6, 0x50AD,
+	0xE9B7, 0x5197, 0xE9B8, 0x52C7, 0xE9B9, 0x57C7, 0xE9BA, 0x5889,
+	0xE9BB, 0x5BB9, 0xE9BC, 0x5EB8, 0xE9BD, 0x6142, 0xE9BE, 0x6995,
+	0xE9BF, 0x6D8C, 0xE9C0, 0x6E67, 0xE9C1, 0x6EB6, 0xE9C2, 0x7194,
+	0xE9C3, 0x7462, 0xE9C4, 0x7528, 0xE9C5, 0x752C, 0xE9C6, 0x8073,
+	0xE9C7, 0x8338, 0xE9C8, 0x84C9, 0xE9C9, 0x8E0A, 0xE9CA, 0x9394,
+	0xE9CB, 0x93DE, 0xE9CC, 0xF9C4, 0xE9CD, 0x4E8E, 0xE9CE, 0x4F51,
+	0xE9CF, 0x5076, 0xE9D0, 0x512A, 0xE9D1, 0x53C8, 0xE9D2, 0x53CB,
+	0xE9D3, 0x53F3, 0xE9D4, 0x5B87, 0xE9D5, 0x5BD3, 0xE9D6, 0x5C24,
+	0xE9D7, 0x611A, 0xE9D8, 0x6182, 0xE9D9, 0x65F4, 0xE9DA, 0x725B,
+	0xE9DB, 0x7397, 0xE9DC, 0x7440, 0xE9DD, 0x76C2, 0xE9DE, 0x7950,
+	0xE9DF, 0x7991, 0xE9E0, 0x79B9, 0xE9E1, 0x7D06, 0xE9E2, 0x7FBD,
+	0xE9E3, 0x828B, 0xE9E4, 0x85D5, 0xE9E5, 0x865E, 0xE9E6, 0x8FC2,
+	0xE9E7, 0x9047, 0xE9E8, 0x90F5, 0xE9E9, 0x91EA, 0xE9EA, 0x9685,
+	0xE9EB, 0x96E8, 0xE9EC, 0x96E9, 0xE9ED, 0x52D6, 0xE9EE, 0x5F67,
+	0xE9EF, 0x65ED, 0xE9F0, 0x6631, 0xE9F1, 0x682F, 0xE9F2, 0x715C,
+	0xE9F3, 0x7A36, 0xE9F4, 0x90C1, 0xE9F5, 0x980A, 0xE9F6, 0x4E91,
+	0xE9F7, 0xF9C5, 0xE9F8, 0x6A52, 0xE9F9, 0x6B9E, 0xE9FA, 0x6F90,
+	0xE9FB, 0x7189, 0xE9FC, 0x8018, 0xE9FD, 0x82B8, 0xE9FE, 0x8553,
+	0xEAA1, 0x904B, 0xEAA2, 0x9695, 0xEAA3, 0x96F2, 0xEAA4, 0x97FB,
+	0xEAA5, 0x851A, 0xEAA6, 0x9B31, 0xEAA7, 0x4E90, 0xEAA8, 0x718A,
+	0xEAA9, 0x96C4, 0xEAAA, 0x5143, 0xEAAB, 0x539F, 0xEAAC, 0x54E1,
+	0xEAAD, 0x5713, 0xEAAE, 0x5712, 0xEAAF, 0x57A3, 0xEAB0, 0x5A9B,
+	0xEAB1, 0x5AC4, 0xEAB2, 0x5BC3, 0xEAB3, 0x6028, 0xEAB4, 0x613F,
+	0xEAB5, 0x63F4, 0xEAB6, 0x6C85, 0xEAB7, 0x6D39, 0xEAB8, 0x6E72,
+	0xEAB9, 0x6E90, 0xEABA, 0x7230, 0xEABB, 0x733F, 0xEABC, 0x7457,
+	0xEABD, 0x82D1, 0xEABE, 0x8881, 0xEABF, 0x8F45, 0xEAC0, 0x9060,
+	0xEAC1, 0xF9C6, 0xEAC2, 0x9662, 0xEAC3, 0x9858, 0xEAC4, 0x9D1B,
+	0xEAC5, 0x6708, 0xEAC6, 0x8D8A, 0xEAC7, 0x925E, 0xEAC8, 0x4F4D,
+	0xEAC9, 0x5049, 0xEACA, 0x50DE, 0xEACB, 0x5371, 0xEACC, 0x570D,
+	0xEACD, 0x59D4, 0xEACE, 0x5A01, 0xEACF, 0x5C09, 0xEAD0, 0x6170,
+	0xEAD1, 0x6690, 0xEAD2, 0x6E2D, 0xEAD3, 0x7232, 0xEAD4, 0x744B,
+	0xEAD5, 0x7DEF, 0xEAD6, 0x80C3, 0xEAD7, 0x840E, 0xEAD8, 0x8466,
+	0xEAD9, 0x853F, 0xEADA, 0x875F, 0xEADB, 0x885B, 0xEADC, 0x8918,
+	0xEADD, 0x8B02, 0xEADE, 0x9055, 0xEADF, 0x97CB, 0xEAE0, 0x9B4F,
+	0xEAE1, 0x4E73, 0xEAE2, 0x4F91, 0xEAE3, 0x5112, 0xEAE4, 0x516A,
+	0xEAE5, 0xF9C7, 0xEAE6, 0x552F, 0xEAE7, 0x55A9, 0xEAE8, 0x5B7A,
+	0xEAE9, 0x5BA5, 0xEAEA, 0x5E7C, 0xEAEB, 0x5E7D, 0xEAEC, 0x5EBE,
+	0xEAED, 0x60A0, 0xEAEE, 0x60DF, 0xEAEF, 0x6108, 0xEAF0, 0x6109,
+	0xEAF1, 0x63C4, 0xEAF2, 0x6538, 0xEAF3, 0x6709, 0xEAF4, 0xF9C8,
+	0xEAF5, 0x67D4, 0xEAF6, 0x67DA, 0xEAF7, 0xF9C9, 0xEAF8, 0x6961,
+	0xEAF9, 0x6962, 0xEAFA, 0x6CB9, 0xEAFB, 0x6D27, 0xEAFC, 0xF9CA,
+	0xEAFD, 0x6E38, 0xEAFE, 0xF9CB, 0xEBA1, 0x6FE1, 0xEBA2, 0x7336,
+	0xEBA3, 0x7337, 0xEBA4, 0xF9CC, 0xEBA5, 0x745C, 0xEBA6, 0x7531,
+	0xEBA7, 0xF9CD, 0xEBA8, 0x7652, 0xEBA9, 0xF9CE, 0xEBAA, 0xF9CF,
+	0xEBAB, 0x7DAD, 0xEBAC, 0x81FE, 0xEBAD, 0x8438, 0xEBAE, 0x88D5,
+	0xEBAF, 0x8A98, 0xEBB0, 0x8ADB, 0xEBB1, 0x8AED, 0xEBB2, 0x8E30,
+	0xEBB3, 0x8E42, 0xEBB4, 0x904A, 0xEBB5, 0x903E, 0xEBB6, 0x907A,
+	0xEBB7, 0x9149, 0xEBB8, 0x91C9, 0xEBB9, 0x936E, 0xEBBA, 0xF9D0,
+	0xEBBB, 0xF9D1, 0xEBBC, 0x5809, 0xEBBD, 0xF9D2, 0xEBBE, 0x6BD3,
+	0xEBBF, 0x8089, 0xEBC0, 0x80B2, 0xEBC1, 0xF9D3, 0xEBC2, 0xF9D4,
+	0xEBC3, 0x5141, 0xEBC4, 0x596B, 0xEBC5, 0x5C39, 0xEBC6, 0xF9D5,
+	0xEBC7, 0xF9D6, 0xEBC8, 0x6F64, 0xEBC9, 0x73A7, 0xEBCA, 0x80E4,
+	0xEBCB, 0x8D07, 0xEBCC, 0xF9D7, 0xEBCD, 0x9217, 0xEBCE, 0x958F,
+	0xEBCF, 0xF9D8, 0xEBD0, 0xF9D9, 0xEBD1, 0xF9DA, 0xEBD2, 0xF9DB,
+	0xEBD3, 0x807F, 0xEBD4, 0x620E, 0xEBD5, 0x701C, 0xEBD6, 0x7D68,
+	0xEBD7, 0x878D, 0xEBD8, 0xF9DC, 0xEBD9, 0x57A0, 0xEBDA, 0x6069,
+	0xEBDB, 0x6147, 0xEBDC, 0x6BB7, 0xEBDD, 0x8ABE, 0xEBDE, 0x9280,
+	0xEBDF, 0x96B1, 0xEBE0, 0x4E59, 0xEBE1, 0x541F, 0xEBE2, 0x6DEB,
+	0xEBE3, 0x852D, 0xEBE4, 0x9670, 0xEBE5, 0x97F3, 0xEBE6, 0x98EE,
+	0xEBE7, 0x63D6, 0xEBE8, 0x6CE3, 0xEBE9, 0x9091, 0xEBEA, 0x51DD,
+	0xEBEB, 0x61C9, 0xEBEC, 0x81BA, 0xEBED, 0x9DF9, 0xEBEE, 0x4F9D,
+	0xEBEF, 0x501A, 0xEBF0, 0x5100, 0xEBF1, 0x5B9C, 0xEBF2, 0x610F,
+	0xEBF3, 0x61FF, 0xEBF4, 0x64EC, 0xEBF5, 0x6905, 0xEBF6, 0x6BC5,
+	0xEBF7, 0x7591, 0xEBF8, 0x77E3, 0xEBF9, 0x7FA9, 0xEBFA, 0x8264,
+	0xEBFB, 0x858F, 0xEBFC, 0x87FB, 0xEBFD, 0x8863, 0xEBFE, 0x8ABC,
+	0xECA1, 0x8B70, 0xECA2, 0x91AB, 0xECA3, 0x4E8C, 0xECA4, 0x4EE5,
+	0xECA5, 0x4F0A, 0xECA6, 0xF9DD, 0xECA7, 0xF9DE, 0xECA8, 0x5937,
+	0xECA9, 0x59E8, 0xECAA, 0xF9DF, 0xECAB, 0x5DF2, 0xECAC, 0x5F1B,
+	0xECAD, 0x5F5B, 0xECAE, 0x6021, 0xECAF, 0xF9E0, 0xECB0, 0xF9E1,
+	0xECB1, 0xF9E2, 0xECB2, 0xF9E3, 0xECB3, 0x723E, 0xECB4, 0x73E5,
+	0xECB5, 0xF9E4, 0xECB6, 0x7570, 0xECB7, 0x75CD, 0xECB8, 0xF9E5,
+	0xECB9, 0x79FB, 0xECBA, 0xF9E6, 0xECBB, 0x800C, 0xECBC, 0x8033,
+	0xECBD, 0x8084, 0xECBE, 0x82E1, 0xECBF, 0x8351, 0xECC0, 0xF9E7,
+	0xECC1, 0xF9E8, 0xECC2, 0x8CBD, 0xECC3, 0x8CB3, 0xECC4, 0x9087,
+	0xECC5, 0xF9E9, 0xECC6, 0xF9EA, 0xECC7, 0x98F4, 0xECC8, 0x990C,
+	0xECC9, 0xF9EB, 0xECCA, 0xF9EC, 0xECCB, 0x7037, 0xECCC, 0x76CA,
+	0xECCD, 0x7FCA, 0xECCE, 0x7FCC, 0xECCF, 0x7FFC, 0xECD0, 0x8B1A,
+	0xECD1, 0x4EBA, 0xECD2, 0x4EC1, 0xECD3, 0x5203, 0xECD4, 0x5370,
+	0xECD5, 0xF9ED, 0xECD6, 0x54BD, 0xECD7, 0x56E0, 0xECD8, 0x59FB,
+	0xECD9, 0x5BC5, 0xECDA, 0x5F15, 0xECDB, 0x5FCD, 0xECDC, 0x6E6E,
+	0xECDD, 0xF9EE, 0xECDE, 0xF9EF, 0xECDF, 0x7D6A, 0xECE0, 0x8335,
+	0xECE1, 0xF9F0, 0xECE2, 0x8693, 0xECE3, 0x8A8D, 0xECE4, 0xF9F1,
+	0xECE5, 0x976D, 0xECE6, 0x9777, 0xECE7, 0xF9F2, 0xECE8, 0xF9F3,
+	0xECE9, 0x4E00, 0xECEA, 0x4F5A, 0xECEB, 0x4F7E, 0xECEC, 0x58F9,
+	0xECED, 0x65E5, 0xECEE, 0x6EA2, 0xECEF, 0x9038, 0xECF0, 0x93B0,
+	0xECF1, 0x99B9, 0xECF2, 0x4EFB, 0xECF3, 0x58EC, 0xECF4, 0x598A,
+	0xECF5, 0x59D9, 0xECF6, 0x6041, 0xECF7, 0xF9F4, 0xECF8, 0xF9F5,
+	0xECF9, 0x7A14, 0xECFA, 0xF9F6, 0xECFB, 0x834F, 0xECFC, 0x8CC3,
+	0xECFD, 0x5165, 0xECFE, 0x5344, 0xEDA1, 0xF9F7, 0xEDA2, 0xF9F8,
+	0xEDA3, 0xF9F9, 0xEDA4, 0x4ECD, 0xEDA5, 0x5269, 0xEDA6, 0x5B55,
+	0xEDA7, 0x82BF, 0xEDA8, 0x4ED4, 0xEDA9, 0x523A, 0xEDAA, 0x54A8,
+	0xEDAB, 0x59C9, 0xEDAC, 0x59FF, 0xEDAD, 0x5B50, 0xEDAE, 0x5B57,
+	0xEDAF, 0x5B5C, 0xEDB0, 0x6063, 0xEDB1, 0x6148, 0xEDB2, 0x6ECB,
+	0xEDB3, 0x7099, 0xEDB4, 0x716E, 0xEDB5, 0x7386, 0xEDB6, 0x74F7,
+	0xEDB7, 0x75B5, 0xEDB8, 0x78C1, 0xEDB9, 0x7D2B, 0xEDBA, 0x8005,
+	0xEDBB, 0x81EA, 0xEDBC, 0x8328, 0xEDBD, 0x8517, 0xEDBE, 0x85C9,
+	0xEDBF, 0x8AEE, 0xEDC0, 0x8CC7, 0xEDC1, 0x96CC, 0xEDC2, 0x4F5C,
+	0xEDC3, 0x52FA, 0xEDC4, 0x56BC, 0xEDC5, 0x65AB, 0xEDC6, 0x6628,
+	0xEDC7, 0x707C, 0xEDC8, 0x70B8, 0xEDC9, 0x7235, 0xEDCA, 0x7DBD,
+	0xEDCB, 0x828D, 0xEDCC, 0x914C, 0xEDCD, 0x96C0, 0xEDCE, 0x9D72,
+	0xEDCF, 0x5B71, 0xEDD0, 0x68E7, 0xEDD1, 0x6B98, 0xEDD2, 0x6F7A,
+	0xEDD3, 0x76DE, 0xEDD4, 0x5C91, 0xEDD5, 0x66AB, 0xEDD6, 0x6F5B,
+	0xEDD7, 0x7BB4, 0xEDD8, 0x7C2A, 0xEDD9, 0x8836, 0xEDDA, 0x96DC,
+	0xEDDB, 0x4E08, 0xEDDC, 0x4ED7, 0xEDDD, 0x5320, 0xEDDE, 0x5834,
+	0xEDDF, 0x58BB, 0xEDE0, 0x58EF, 0xEDE1, 0x596C, 0xEDE2, 0x5C07,
+	0xEDE3, 0x5E33, 0xEDE4, 0x5E84, 0xEDE5, 0x5F35, 0xEDE6, 0x638C,
+	0xEDE7, 0x66B2, 0xEDE8, 0x6756, 0xEDE9, 0x6A1F, 0xEDEA, 0x6AA3,
+	0xEDEB, 0x6B0C, 0xEDEC, 0x6F3F, 0xEDED, 0x7246, 0xEDEE, 0xF9FA,
+	0xEDEF, 0x7350, 0xEDF0, 0x748B, 0xEDF1, 0x7AE0, 0xEDF2, 0x7CA7,
+	0xEDF3, 0x8178, 0xEDF4, 0x81DF, 0xEDF5, 0x81E7, 0xEDF6, 0x838A,
+	0xEDF7, 0x846C, 0xEDF8, 0x8523, 0xEDF9, 0x8594, 0xEDFA, 0x85CF,
+	0xEDFB, 0x88DD, 0xEDFC, 0x8D13, 0xEDFD, 0x91AC, 0xEDFE, 0x9577,
+	0xEEA1, 0x969C, 0xEEA2, 0x518D, 0xEEA3, 0x54C9, 0xEEA4, 0x5728,
+	0xEEA5, 0x5BB0, 0xEEA6, 0x624D, 0xEEA7, 0x6750, 0xEEA8, 0x683D,
+	0xEEA9, 0x6893, 0xEEAA, 0x6E3D, 0xEEAB, 0x6ED3, 0xEEAC, 0x707D,
+	0xEEAD, 0x7E21, 0xEEAE, 0x88C1, 0xEEAF, 0x8CA1, 0xEEB0, 0x8F09,
+	0xEEB1, 0x9F4B, 0xEEB2, 0x9F4E, 0xEEB3, 0x722D, 0xEEB4, 0x7B8F,
+	0xEEB5, 0x8ACD, 0xEEB6, 0x931A, 0xEEB7, 0x4F47, 0xEEB8, 0x4F4E,
+	0xEEB9, 0x5132, 0xEEBA, 0x5480, 0xEEBB, 0x59D0, 0xEEBC, 0x5E95,
+	0xEEBD, 0x62B5, 0xEEBE, 0x6775, 0xEEBF, 0x696E, 0xEEC0, 0x6A17,
+	0xEEC1, 0x6CAE, 0xEEC2, 0x6E1A, 0xEEC3, 0x72D9, 0xEEC4, 0x732A,
+	0xEEC5, 0x75BD, 0xEEC6, 0x7BB8, 0xEEC7, 0x7D35, 0xEEC8, 0x82E7,
+	0xEEC9, 0x83F9, 0xEECA, 0x8457, 0xEECB, 0x85F7, 0xEECC, 0x8A5B,
+	0xEECD, 0x8CAF, 0xEECE, 0x8E87, 0xEECF, 0x9019, 0xEED0, 0x90B8,
+	0xEED1, 0x96CE, 0xEED2, 0x9F5F, 0xEED3, 0x52E3, 0xEED4, 0x540A,
+	0xEED5, 0x5AE1, 0xEED6, 0x5BC2, 0xEED7, 0x6458, 0xEED8, 0x6575,
+	0xEED9, 0x6EF4, 0xEEDA, 0x72C4, 0xEEDB, 0xF9FB, 0xEEDC, 0x7684,
+	0xEEDD, 0x7A4D, 0xEEDE, 0x7B1B, 0xEEDF, 0x7C4D, 0xEEE0, 0x7E3E,
+	0xEEE1, 0x7FDF, 0xEEE2, 0x837B, 0xEEE3, 0x8B2B, 0xEEE4, 0x8CCA,
+	0xEEE5, 0x8D64, 0xEEE6, 0x8DE1, 0xEEE7, 0x8E5F, 0xEEE8, 0x8FEA,
+	0xEEE9, 0x8FF9, 0xEEEA, 0x9069, 0xEEEB, 0x93D1, 0xEEEC, 0x4F43,
+	0xEEED, 0x4F7A, 0xEEEE, 0x50B3, 0xEEEF, 0x5168, 0xEEF0, 0x5178,
+	0xEEF1, 0x524D, 0xEEF2, 0x526A, 0xEEF3, 0x5861, 0xEEF4, 0x587C,
+	0xEEF5, 0x5960, 0xEEF6, 0x5C08, 0xEEF7, 0x5C55, 0xEEF8, 0x5EDB,
+	0xEEF9, 0x609B, 0xEEFA, 0x6230, 0xEEFB, 0x6813, 0xEEFC, 0x6BBF,
+	0xEEFD, 0x6C08, 0xEEFE, 0x6FB1, 0xEFA1, 0x714E, 0xEFA2, 0x7420,
+	0xEFA3, 0x7530, 0xEFA4, 0x7538, 0xEFA5, 0x7551, 0xEFA6, 0x7672,
+	0xEFA7, 0x7B4C, 0xEFA8, 0x7B8B, 0xEFA9, 0x7BAD, 0xEFAA, 0x7BC6,
+	0xEFAB, 0x7E8F, 0xEFAC, 0x8A6E, 0xEFAD, 0x8F3E, 0xEFAE, 0x8F49,
+	0xEFAF, 0x923F, 0xEFB0, 0x9293, 0xEFB1, 0x9322, 0xEFB2, 0x942B,
+	0xEFB3, 0x96FB, 0xEFB4, 0x985A, 0xEFB5, 0x986B, 0xEFB6, 0x991E,
+	0xEFB7, 0x5207, 0xEFB8, 0x622A, 0xEFB9, 0x6298, 0xEFBA, 0x6D59,
+	0xEFBB, 0x7664, 0xEFBC, 0x7ACA, 0xEFBD, 0x7BC0, 0xEFBE, 0x7D76,
+	0xEFBF, 0x5360, 0xEFC0, 0x5CBE, 0xEFC1, 0x5E97, 0xEFC2, 0x6F38,
+	0xEFC3, 0x70B9, 0xEFC4, 0x7C98, 0xEFC5, 0x9711, 0xEFC6, 0x9B8E,
+	0xEFC7, 0x9EDE, 0xEFC8, 0x63A5, 0xEFC9, 0x647A, 0xEFCA, 0x8776,
+	0xEFCB, 0x4E01, 0xEFCC, 0x4E95, 0xEFCD, 0x4EAD, 0xEFCE, 0x505C,
+	0xEFCF, 0x5075, 0xEFD0, 0x5448, 0xEFD1, 0x59C3, 0xEFD2, 0x5B9A,
+	0xEFD3, 0x5E40, 0xEFD4, 0x5EAD, 0xEFD5, 0x5EF7, 0xEFD6, 0x5F81,
+	0xEFD7, 0x60C5, 0xEFD8, 0x633A, 0xEFD9, 0x653F, 0xEFDA, 0x6574,
+	0xEFDB, 0x65CC, 0xEFDC, 0x6676, 0xEFDD, 0x6678, 0xEFDE, 0x67FE,
+	0xEFDF, 0x6968, 0xEFE0, 0x6A89, 0xEFE1, 0x6B63, 0xEFE2, 0x6C40,
+	0xEFE3, 0x6DC0, 0xEFE4, 0x6DE8, 0xEFE5, 0x6E1F, 0xEFE6, 0x6E5E,
+	0xEFE7, 0x701E, 0xEFE8, 0x70A1, 0xEFE9, 0x738E, 0xEFEA, 0x73FD,
+	0xEFEB, 0x753A, 0xEFEC, 0x775B, 0xEFED, 0x7887, 0xEFEE, 0x798E,
+	0xEFEF, 0x7A0B, 0xEFF0, 0x7A7D, 0xEFF1, 0x7CBE, 0xEFF2, 0x7D8E,
+	0xEFF3, 0x8247, 0xEFF4, 0x8A02, 0xEFF5, 0x8AEA, 0xEFF6, 0x8C9E,
+	0xEFF7, 0x912D, 0xEFF8, 0x914A, 0xEFF9, 0x91D8, 0xEFFA, 0x9266,
+	0xEFFB, 0x92CC, 0xEFFC, 0x9320, 0xEFFD, 0x9706, 0xEFFE, 0x9756,
+	0xF0A1, 0x975C, 0xF0A2, 0x9802, 0xF0A3, 0x9F0E, 0xF0A4, 0x5236,
+	0xF0A5, 0x5291, 0xF0A6, 0x557C, 0xF0A7, 0x5824, 0xF0A8, 0x5E1D,
+	0xF0A9, 0x5F1F, 0xF0AA, 0x608C, 0xF0AB, 0x63D0, 0xF0AC, 0x68AF,
+	0xF0AD, 0x6FDF, 0xF0AE, 0x796D, 0xF0AF, 0x7B2C, 0xF0B0, 0x81CD,
+	0xF0B1, 0x85BA, 0xF0B2, 0x88FD, 0xF0B3, 0x8AF8, 0xF0B4, 0x8E44,
+	0xF0B5, 0x918D, 0xF0B6, 0x9664, 0xF0B7, 0x969B, 0xF0B8, 0x973D,
+	0xF0B9, 0x984C, 0xF0BA, 0x9F4A, 0xF0BB, 0x4FCE, 0xF0BC, 0x5146,
+	0xF0BD, 0x51CB, 0xF0BE, 0x52A9, 0xF0BF, 0x5632, 0xF0C0, 0x5F14,
+	0xF0C1, 0x5F6B, 0xF0C2, 0x63AA, 0xF0C3, 0x64CD, 0xF0C4, 0x65E9,
+	0xF0C5, 0x6641, 0xF0C6, 0x66FA, 0xF0C7, 0x66F9, 0xF0C8, 0x671D,
+	0xF0C9, 0x689D, 0xF0CA, 0x68D7, 0xF0CB, 0x69FD, 0xF0CC, 0x6F15,
+	0xF0CD, 0x6F6E, 0xF0CE, 0x7167, 0xF0CF, 0x71E5, 0xF0D0, 0x722A,
+	0xF0D1, 0x74AA, 0xF0D2, 0x773A, 0xF0D3, 0x7956, 0xF0D4, 0x795A,
+	0xF0D5, 0x79DF, 0xF0D6, 0x7A20, 0xF0D7, 0x7A95, 0xF0D8, 0x7C97,
+	0xF0D9, 0x7CDF, 0xF0DA, 0x7D44, 0xF0DB, 0x7E70, 0xF0DC, 0x8087,
+	0xF0DD, 0x85FB, 0xF0DE, 0x86A4, 0xF0DF, 0x8A54, 0xF0E0, 0x8ABF,
+	0xF0E1, 0x8D99, 0xF0E2, 0x8E81, 0xF0E3, 0x9020, 0xF0E4, 0x906D,
+	0xF0E5, 0x91E3, 0xF0E6, 0x963B, 0xF0E7, 0x96D5, 0xF0E8, 0x9CE5,
+	0xF0E9, 0x65CF, 0xF0EA, 0x7C07, 0xF0EB, 0x8DB3, 0xF0EC, 0x93C3,
+	0xF0ED, 0x5B58, 0xF0EE, 0x5C0A, 0xF0EF, 0x5352, 0xF0F0, 0x62D9,
+	0xF0F1, 0x731D, 0xF0F2, 0x5027, 0xF0F3, 0x5B97, 0xF0F4, 0x5F9E,
+	0xF0F5, 0x60B0, 0xF0F6, 0x616B, 0xF0F7, 0x68D5, 0xF0F8, 0x6DD9,
+	0xF0F9, 0x742E, 0xF0FA, 0x7A2E, 0xF0FB, 0x7D42, 0xF0FC, 0x7D9C,
+	0xF0FD, 0x7E31, 0xF0FE, 0x816B, 0xF1A1, 0x8E2A, 0xF1A2, 0x8E35,
+	0xF1A3, 0x937E, 0xF1A4, 0x9418, 0xF1A5, 0x4F50, 0xF1A6, 0x5750,
+	0xF1A7, 0x5DE6, 0xF1A8, 0x5EA7, 0xF1A9, 0x632B, 0xF1AA, 0x7F6A,
+	0xF1AB, 0x4E3B, 0xF1AC, 0x4F4F, 0xF1AD, 0x4F8F, 0xF1AE, 0x505A,
+	0xF1AF, 0x59DD, 0xF1B0, 0x80C4, 0xF1B1, 0x546A, 0xF1B2, 0x5468,
+	0xF1B3, 0x55FE, 0xF1B4, 0x594F, 0xF1B5, 0x5B99, 0xF1B6, 0x5DDE,
+	0xF1B7, 0x5EDA, 0xF1B8, 0x665D, 0xF1B9, 0x6731, 0xF1BA, 0x67F1,
+	0xF1BB, 0x682A, 0xF1BC, 0x6CE8, 0xF1BD, 0x6D32, 0xF1BE, 0x6E4A,
+	0xF1BF, 0x6F8D, 0xF1C0, 0x70B7, 0xF1C1, 0x73E0, 0xF1C2, 0x7587,
+	0xF1C3, 0x7C4C, 0xF1C4, 0x7D02, 0xF1C5, 0x7D2C, 0xF1C6, 0x7DA2,
+	0xF1C7, 0x821F, 0xF1C8, 0x86DB, 0xF1C9, 0x8A3B, 0xF1CA, 0x8A85,
+	0xF1CB, 0x8D70, 0xF1CC, 0x8E8A, 0xF1CD, 0x8F33, 0xF1CE, 0x9031,
+	0xF1CF, 0x914E, 0xF1D0, 0x9152, 0xF1D1, 0x9444, 0xF1D2, 0x99D0,
+	0xF1D3, 0x7AF9, 0xF1D4, 0x7CA5, 0xF1D5, 0x4FCA, 0xF1D6, 0x5101,
+	0xF1D7, 0x51C6, 0xF1D8, 0x57C8, 0xF1D9, 0x5BEF, 0xF1DA, 0x5CFB,
+	0xF1DB, 0x6659, 0xF1DC, 0x6A3D, 0xF1DD, 0x6D5A, 0xF1DE, 0x6E96,
+	0xF1DF, 0x6FEC, 0xF1E0, 0x710C, 0xF1E1, 0x756F, 0xF1E2, 0x7AE3,
+	0xF1E3, 0x8822, 0xF1E4, 0x9021, 0xF1E5, 0x9075, 0xF1E6, 0x96CB,
+	0xF1E7, 0x99FF, 0xF1E8, 0x8301, 0xF1E9, 0x4E2D, 0xF1EA, 0x4EF2,
+	0xF1EB, 0x8846, 0xF1EC, 0x91CD, 0xF1ED, 0x537D, 0xF1EE, 0x6ADB,
+	0xF1EF, 0x696B, 0xF1F0, 0x6C41, 0xF1F1, 0x847A, 0xF1F2, 0x589E,
+	0xF1F3, 0x618E, 0xF1F4, 0x66FE, 0xF1F5, 0x62EF, 0xF1F6, 0x70DD,
+	0xF1F7, 0x7511, 0xF1F8, 0x75C7, 0xF1F9, 0x7E52, 0xF1FA, 0x84B8,
+	0xF1FB, 0x8B49, 0xF1FC, 0x8D08, 0xF1FD, 0x4E4B, 0xF1FE, 0x53EA,
+	0xF2A1, 0x54AB, 0xF2A2, 0x5730, 0xF2A3, 0x5740, 0xF2A4, 0x5FD7,
+	0xF2A5, 0x6301, 0xF2A6, 0x6307, 0xF2A7, 0x646F, 0xF2A8, 0x652F,
+	0xF2A9, 0x65E8, 0xF2AA, 0x667A, 0xF2AB, 0x679D, 0xF2AC, 0x67B3,
+	0xF2AD, 0x6B62, 0xF2AE, 0x6C60, 0xF2AF, 0x6C9A, 0xF2B0, 0x6F2C,
+	0xF2B1, 0x77E5, 0xF2B2, 0x7825, 0xF2B3, 0x7949, 0xF2B4, 0x7957,
+	0xF2B5, 0x7D19, 0xF2B6, 0x80A2, 0xF2B7, 0x8102, 0xF2B8, 0x81F3,
+	0xF2B9, 0x829D, 0xF2BA, 0x82B7, 0xF2BB, 0x8718, 0xF2BC, 0x8A8C,
+	0xF2BD, 0xF9FC, 0xF2BE, 0x8D04, 0xF2BF, 0x8DBE, 0xF2C0, 0x9072,
+	0xF2C1, 0x76F4, 0xF2C2, 0x7A19, 0xF2C3, 0x7A37, 0xF2C4, 0x7E54,
+	0xF2C5, 0x8077, 0xF2C6, 0x5507, 0xF2C7, 0x55D4, 0xF2C8, 0x5875,
+	0xF2C9, 0x632F, 0xF2CA, 0x6422, 0xF2CB, 0x6649, 0xF2CC, 0x664B,
+	0xF2CD, 0x686D, 0xF2CE, 0x699B, 0xF2CF, 0x6B84, 0xF2D0, 0x6D25,
+	0xF2D1, 0x6EB1, 0xF2D2, 0x73CD, 0xF2D3, 0x7468, 0xF2D4, 0x74A1,
+	0xF2D5, 0x755B, 0xF2D6, 0x75B9, 0xF2D7, 0x76E1, 0xF2D8, 0x771E,
+	0xF2D9, 0x778B, 0xF2DA, 0x79E6, 0xF2DB, 0x7E09, 0xF2DC, 0x7E1D,
+	0xF2DD, 0x81FB, 0xF2DE, 0x852F, 0xF2DF, 0x8897, 0xF2E0, 0x8A3A,
+	0xF2E1, 0x8CD1, 0xF2E2, 0x8EEB, 0xF2E3, 0x8FB0, 0xF2E4, 0x9032,
+	0xF2E5, 0x93AD, 0xF2E6, 0x9663, 0xF2E7, 0x9673, 0xF2E8, 0x9707,
+	0xF2E9, 0x4F84, 0xF2EA, 0x53F1, 0xF2EB, 0x59EA, 0xF2EC, 0x5AC9,
+	0xF2ED, 0x5E19, 0xF2EE, 0x684E, 0xF2EF, 0x74C6, 0xF2F0, 0x75BE,
+	0xF2F1, 0x79E9, 0xF2F2, 0x7A92, 0xF2F3, 0x81A3, 0xF2F4, 0x86ED,
+	0xF2F5, 0x8CEA, 0xF2F6, 0x8DCC, 0xF2F7, 0x8FED, 0xF2F8, 0x659F,
+	0xF2F9, 0x6715, 0xF2FA, 0xF9FD, 0xF2FB, 0x57F7, 0xF2FC, 0x6F57,
+	0xF2FD, 0x7DDD, 0xF2FE, 0x8F2F, 0xF3A1, 0x93F6, 0xF3A2, 0x96C6,
+	0xF3A3, 0x5FB5, 0xF3A4, 0x61F2, 0xF3A5, 0x6F84, 0xF3A6, 0x4E14,
+	0xF3A7, 0x4F98, 0xF3A8, 0x501F, 0xF3A9, 0x53C9, 0xF3AA, 0x55DF,
+	0xF3AB, 0x5D6F, 0xF3AC, 0x5DEE, 0xF3AD, 0x6B21, 0xF3AE, 0x6B64,
+	0xF3AF, 0x78CB, 0xF3B0, 0x7B9A, 0xF3B1, 0xF9FE, 0xF3B2, 0x8E49,
+	0xF3B3, 0x8ECA, 0xF3B4, 0x906E, 0xF3B5, 0x6349, 0xF3B6, 0x643E,
+	0xF3B7, 0x7740, 0xF3B8, 0x7A84, 0xF3B9, 0x932F, 0xF3BA, 0x947F,
+	0xF3BB, 0x9F6A, 0xF3BC, 0x64B0, 0xF3BD, 0x6FAF, 0xF3BE, 0x71E6,
+	0xF3BF, 0x74A8, 0xF3C0, 0x74DA, 0xF3C1, 0x7AC4, 0xF3C2, 0x7C12,
+	0xF3C3, 0x7E82, 0xF3C4, 0x7CB2, 0xF3C5, 0x7E98, 0xF3C6, 0x8B9A,
+	0xF3C7, 0x8D0A, 0xF3C8, 0x947D, 0xF3C9, 0x9910, 0xF3CA, 0x994C,
+	0xF3CB, 0x5239, 0xF3CC, 0x5BDF, 0xF3CD, 0x64E6, 0xF3CE, 0x672D,
+	0xF3CF, 0x7D2E, 0xF3D0, 0x50ED, 0xF3D1, 0x53C3, 0xF3D2, 0x5879,
+	0xF3D3, 0x6158, 0xF3D4, 0x6159, 0xF3D5, 0x61FA, 0xF3D6, 0x65AC,
+	0xF3D7, 0x7AD9, 0xF3D8, 0x8B92, 0xF3D9, 0x8B96, 0xF3DA, 0x5009,
+	0xF3DB, 0x5021, 0xF3DC, 0x5275, 0xF3DD, 0x5531, 0xF3DE, 0x5A3C,
+	0xF3DF, 0x5EE0, 0xF3E0, 0x5F70, 0xF3E1, 0x6134, 0xF3E2, 0x655E,
+	0xF3E3, 0x660C, 0xF3E4, 0x6636, 0xF3E5, 0x66A2, 0xF3E6, 0x69CD,
+	0xF3E7, 0x6EC4, 0xF3E8, 0x6F32, 0xF3E9, 0x7316, 0xF3EA, 0x7621,
+	0xF3EB, 0x7A93, 0xF3EC, 0x8139, 0xF3ED, 0x8259, 0xF3EE, 0x83D6,
+	0xF3EF, 0x84BC, 0xF3F0, 0x50B5, 0xF3F1, 0x57F0, 0xF3F2, 0x5BC0,
+	0xF3F3, 0x5BE8, 0xF3F4, 0x5F69, 0xF3F5, 0x63A1, 0xF3F6, 0x7826,
+	0xF3F7, 0x7DB5, 0xF3F8, 0x83DC, 0xF3F9, 0x8521, 0xF3FA, 0x91C7,
+	0xF3FB, 0x91F5, 0xF3FC, 0x518A, 0xF3FD, 0x67F5, 0xF3FE, 0x7B56,
+	0xF4A1, 0x8CAC, 0xF4A2, 0x51C4, 0xF4A3, 0x59BB, 0xF4A4, 0x60BD,
+	0xF4A5, 0x8655, 0xF4A6, 0x501C, 0xF4A7, 0xF9FF, 0xF4A8, 0x5254,
+	0xF4A9, 0x5C3A, 0xF4AA, 0x617D, 0xF4AB, 0x621A, 0xF4AC, 0x62D3,
+	0xF4AD, 0x64F2, 0xF4AE, 0x65A5, 0xF4AF, 0x6ECC, 0xF4B0, 0x7620,
+	0xF4B1, 0x810A, 0xF4B2, 0x8E60, 0xF4B3, 0x965F, 0xF4B4, 0x96BB,
+	0xF4B5, 0x4EDF, 0xF4B6, 0x5343, 0xF4B7, 0x5598, 0xF4B8, 0x5929,
+	0xF4B9, 0x5DDD, 0xF4BA, 0x64C5, 0xF4BB, 0x6CC9, 0xF4BC, 0x6DFA,
+	0xF4BD, 0x7394, 0xF4BE, 0x7A7F, 0xF4BF, 0x821B, 0xF4C0, 0x85A6,
+	0xF4C1, 0x8CE4, 0xF4C2, 0x8E10, 0xF4C3, 0x9077, 0xF4C4, 0x91E7,
+	0xF4C5, 0x95E1, 0xF4C6, 0x9621, 0xF4C7, 0x97C6, 0xF4C8, 0x51F8,
+	0xF4C9, 0x54F2, 0xF4CA, 0x5586, 0xF4CB, 0x5FB9, 0xF4CC, 0x64A4,
+	0xF4CD, 0x6F88, 0xF4CE, 0x7DB4, 0xF4CF, 0x8F1F, 0xF4D0, 0x8F4D,
+	0xF4D1, 0x9435, 0xF4D2, 0x50C9, 0xF4D3, 0x5C16, 0xF4D4, 0x6CBE,
+	0xF4D5, 0x6DFB, 0xF4D6, 0x751B, 0xF4D7, 0x77BB, 0xF4D8, 0x7C3D,
+	0xF4D9, 0x7C64, 0xF4DA, 0x8A79, 0xF4DB, 0x8AC2, 0xF4DC, 0x581E,
+	0xF4DD, 0x59BE, 0xF4DE, 0x5E16, 0xF4DF, 0x6377, 0xF4E0, 0x7252,
+	0xF4E1, 0x758A, 0xF4E2, 0x776B, 0xF4E3, 0x8ADC, 0xF4E4, 0x8CBC,
+	0xF4E5, 0x8F12, 0xF4E6, 0x5EF3, 0xF4E7, 0x6674, 0xF4E8, 0x6DF8,
+	0xF4E9, 0x807D, 0xF4EA, 0x83C1, 0xF4EB, 0x8ACB, 0xF4EC, 0x9751,
+	0xF4ED, 0x9BD6, 0xF4EE, 0xFA00, 0xF4EF, 0x5243, 0xF4F0, 0x66FF,
+	0xF4F1, 0x6D95, 0xF4F2, 0x6EEF, 0xF4F3, 0x7DE0, 0xF4F4, 0x8AE6,
+	0xF4F5, 0x902E, 0xF4F6, 0x905E, 0xF4F7, 0x9AD4, 0xF4F8, 0x521D,
+	0xF4F9, 0x527F, 0xF4FA, 0x54E8, 0xF4FB, 0x6194, 0xF4FC, 0x6284,
+	0xF4FD, 0x62DB, 0xF4FE, 0x68A2, 0xF5A1, 0x6912, 0xF5A2, 0x695A,
+	0xF5A3, 0x6A35, 0xF5A4, 0x7092, 0xF5A5, 0x7126, 0xF5A6, 0x785D,
+	0xF5A7, 0x7901, 0xF5A8, 0x790E, 0xF5A9, 0x79D2, 0xF5AA, 0x7A0D,
+	0xF5AB, 0x8096, 0xF5AC, 0x8278, 0xF5AD, 0x82D5, 0xF5AE, 0x8349,
+	0xF5AF, 0x8549, 0xF5B0, 0x8C82, 0xF5B1, 0x8D85, 0xF5B2, 0x9162,
+	0xF5B3, 0x918B, 0xF5B4, 0x91AE, 0xF5B5, 0x4FC3, 0xF5B6, 0x56D1,
+	0xF5B7, 0x71ED, 0xF5B8, 0x77D7, 0xF5B9, 0x8700, 0xF5BA, 0x89F8,
+	0xF5BB, 0x5BF8, 0xF5BC, 0x5FD6, 0xF5BD, 0x6751, 0xF5BE, 0x90A8,
+	0xF5BF, 0x53E2, 0xF5C0, 0x585A, 0xF5C1, 0x5BF5, 0xF5C2, 0x60A4,
+	0xF5C3, 0x6181, 0xF5C4, 0x6460, 0xF5C5, 0x7E3D, 0xF5C6, 0x8070,
+	0xF5C7, 0x8525, 0xF5C8, 0x9283, 0xF5C9, 0x64AE, 0xF5CA, 0x50AC,
+	0xF5CB, 0x5D14, 0xF5CC, 0x6700, 0xF5CD, 0x589C, 0xF5CE, 0x62BD,
+	0xF5CF, 0x63A8, 0xF5D0, 0x690E, 0xF5D1, 0x6978, 0xF5D2, 0x6A1E,
+	0xF5D3, 0x6E6B, 0xF5D4, 0x76BA, 0xF5D5, 0x79CB, 0xF5D6, 0x82BB,
+	0xF5D7, 0x8429, 0xF5D8, 0x8ACF, 0xF5D9, 0x8DA8, 0xF5DA, 0x8FFD,
+	0xF5DB, 0x9112, 0xF5DC, 0x914B, 0xF5DD, 0x919C, 0xF5DE, 0x9310,
+	0xF5DF, 0x9318, 0xF5E0, 0x939A, 0xF5E1, 0x96DB, 0xF5E2, 0x9A36,
+	0xF5E3, 0x9C0D, 0xF5E4, 0x4E11, 0xF5E5, 0x755C, 0xF5E6, 0x795D,
+	0xF5E7, 0x7AFA, 0xF5E8, 0x7B51, 0xF5E9, 0x7BC9, 0xF5EA, 0x7E2E,
+	0xF5EB, 0x84C4, 0xF5EC, 0x8E59, 0xF5ED, 0x8E74, 0xF5EE, 0x8EF8,
+	0xF5EF, 0x9010, 0xF5F0, 0x6625, 0xF5F1, 0x693F, 0xF5F2, 0x7443,
+	0xF5F3, 0x51FA, 0xF5F4, 0x672E, 0xF5F5, 0x9EDC, 0xF5F6, 0x5145,
+	0xF5F7, 0x5FE0, 0xF5F8, 0x6C96, 0xF5F9, 0x87F2, 0xF5FA, 0x885D,
+	0xF5FB, 0x8877, 0xF5FC, 0x60B4, 0xF5FD, 0x81B5, 0xF5FE, 0x8403,
+	0xF6A1, 0x8D05, 0xF6A2, 0x53D6, 0xF6A3, 0x5439, 0xF6A4, 0x5634,
+	0xF6A5, 0x5A36, 0xF6A6, 0x5C31, 0xF6A7, 0x708A, 0xF6A8, 0x7FE0,
+	0xF6A9, 0x805A, 0xF6AA, 0x8106, 0xF6AB, 0x81ED, 0xF6AC, 0x8DA3,
+	0xF6AD, 0x9189, 0xF6AE, 0x9A5F, 0xF6AF, 0x9DF2, 0xF6B0, 0x5074,
+	0xF6B1, 0x4EC4, 0xF6B2, 0x53A0, 0xF6B3, 0x60FB, 0xF6B4, 0x6E2C,
+	0xF6B5, 0x5C64, 0xF6B6, 0x4F88, 0xF6B7, 0x5024, 0xF6B8, 0x55E4,
+	0xF6B9, 0x5CD9, 0xF6BA, 0x5E5F, 0xF6BB, 0x6065, 0xF6BC, 0x6894,
+	0xF6BD, 0x6CBB, 0xF6BE, 0x6DC4, 0xF6BF, 0x71BE, 0xF6C0, 0x75D4,
+	0xF6C1, 0x75F4, 0xF6C2, 0x7661, 0xF6C3, 0x7A1A, 0xF6C4, 0x7A49,
+	0xF6C5, 0x7DC7, 0xF6C6, 0x7DFB, 0xF6C7, 0x7F6E, 0xF6C8, 0x81F4,
+	0xF6C9, 0x86A9, 0xF6CA, 0x8F1C, 0xF6CB, 0x96C9, 0xF6CC, 0x99B3,
+	0xF6CD, 0x9F52, 0xF6CE, 0x5247, 0xF6CF, 0x52C5, 0xF6D0, 0x98ED,
+	0xF6D1, 0x89AA, 0xF6D2, 0x4E03, 0xF6D3, 0x67D2, 0xF6D4, 0x6F06,
+	0xF6D5, 0x4FB5, 0xF6D6, 0x5BE2, 0xF6D7, 0x6795, 0xF6D8, 0x6C88,
+	0xF6D9, 0x6D78, 0xF6DA, 0x741B, 0xF6DB, 0x7827, 0xF6DC, 0x91DD,
+	0xF6DD, 0x937C, 0xF6DE, 0x87C4, 0xF6DF, 0x79E4, 0xF6E0, 0x7A31,
+	0xF6E1, 0x5FEB, 0xF6E2, 0x4ED6, 0xF6E3, 0x54A4, 0xF6E4, 0x553E,
+	0xF6E5, 0x58AE, 0xF6E6, 0x59A5, 0xF6E7, 0x60F0, 0xF6E8, 0x6253,
+	0xF6E9, 0x62D6, 0xF6EA, 0x6736, 0xF6EB, 0x6955, 0xF6EC, 0x8235,
+	0xF6ED, 0x9640, 0xF6EE, 0x99B1, 0xF6EF, 0x99DD, 0xF6F0, 0x502C,
+	0xF6F1, 0x5353, 0xF6F2, 0x5544, 0xF6F3, 0x577C, 0xF6F4, 0xFA01,
+	0xF6F5, 0x6258, 0xF6F6, 0xFA02, 0xF6F7, 0x64E2, 0xF6F8, 0x666B,
+	0xF6F9, 0x67DD, 0xF6FA, 0x6FC1, 0xF6FB, 0x6FEF, 0xF6FC, 0x7422,
+	0xF6FD, 0x7438, 0xF6FE, 0x8A17, 0xF7A1, 0x9438, 0xF7A2, 0x5451,
+	0xF7A3, 0x5606, 0xF7A4, 0x5766, 0xF7A5, 0x5F48, 0xF7A6, 0x619A,
+	0xF7A7, 0x6B4E, 0xF7A8, 0x7058, 0xF7A9, 0x70AD, 0xF7AA, 0x7DBB,
+	0xF7AB, 0x8A95, 0xF7AC, 0x596A, 0xF7AD, 0x812B, 0xF7AE, 0x63A2,
+	0xF7AF, 0x7708, 0xF7B0, 0x803D, 0xF7B1, 0x8CAA, 0xF7B2, 0x5854,
+	0xF7B3, 0x642D, 0xF7B4, 0x69BB, 0xF7B5, 0x5B95, 0xF7B6, 0x5E11,
+	0xF7B7, 0x6E6F, 0xF7B8, 0xFA03, 0xF7B9, 0x8569, 0xF7BA, 0x514C,
+	0xF7BB, 0x53F0, 0xF7BC, 0x592A, 0xF7BD, 0x6020, 0xF7BE, 0x614B,
+	0xF7BF, 0x6B86, 0xF7C0, 0x6C70, 0xF7C1, 0x6CF0, 0xF7C2, 0x7B1E,
+	0xF7C3, 0x80CE, 0xF7C4, 0x82D4, 0xF7C5, 0x8DC6, 0xF7C6, 0x90B0,
+	0xF7C7, 0x98B1, 0xF7C8, 0xFA04, 0xF7C9, 0x64C7, 0xF7CA, 0x6FA4,
+	0xF7CB, 0x6491, 0xF7CC, 0x6504, 0xF7CD, 0x514E, 0xF7CE, 0x5410,
+	0xF7CF, 0x571F, 0xF7D0, 0x8A0E, 0xF7D1, 0x615F, 0xF7D2, 0x6876,
+	0xF7D3, 0xFA05, 0xF7D4, 0x75DB, 0xF7D5, 0x7B52, 0xF7D6, 0x7D71,
+	0xF7D7, 0x901A, 0xF7D8, 0x5806, 0xF7D9, 0x69CC, 0xF7DA, 0x817F,
+	0xF7DB, 0x892A, 0xF7DC, 0x9000, 0xF7DD, 0x9839, 0xF7DE, 0x5078,
+	0xF7DF, 0x5957, 0xF7E0, 0x59AC, 0xF7E1, 0x6295, 0xF7E2, 0x900F,
+	0xF7E3, 0x9B2A, 0xF7E4, 0x615D, 0xF7E5, 0x7279, 0xF7E6, 0x95D6,
+	0xF7E7, 0x5761, 0xF7E8, 0x5A46, 0xF7E9, 0x5DF4, 0xF7EA, 0x628A,
+	0xF7EB, 0x64AD, 0xF7EC, 0x64FA, 0xF7ED, 0x6777, 0xF7EE, 0x6CE2,
+	0xF7EF, 0x6D3E, 0xF7F0, 0x722C, 0xF7F1, 0x7436, 0xF7F2, 0x7834,
+	0xF7F3, 0x7F77, 0xF7F4, 0x82AD, 0xF7F5, 0x8DDB, 0xF7F6, 0x9817,
+	0xF7F7, 0x5224, 0xF7F8, 0x5742, 0xF7F9, 0x677F, 0xF7FA, 0x7248,
+	0xF7FB, 0x74E3, 0xF7FC, 0x8CA9, 0xF7FD, 0x8FA6, 0xF7FE, 0x9211,
+	0xF8A1, 0x962A, 0xF8A2, 0x516B, 0xF8A3, 0x53ED, 0xF8A4, 0x634C,
+	0xF8A5, 0x4F69, 0xF8A6, 0x5504, 0xF8A7, 0x6096, 0xF8A8, 0x6557,
+	0xF8A9, 0x6C9B, 0xF8AA, 0x6D7F, 0xF8AB, 0x724C, 0xF8AC, 0x72FD,
+	0xF8AD, 0x7A17, 0xF8AE, 0x8987, 0xF8AF, 0x8C9D, 0xF8B0, 0x5F6D,
+	0xF8B1, 0x6F8E, 0xF8B2, 0x70F9, 0xF8B3, 0x81A8, 0xF8B4, 0x610E,
+	0xF8B5, 0x4FBF, 0xF8B6, 0x504F, 0xF8B7, 0x6241, 0xF8B8, 0x7247,
+	0xF8B9, 0x7BC7, 0xF8BA, 0x7DE8, 0xF8BB, 0x7FE9, 0xF8BC, 0x904D,
+	0xF8BD, 0x97AD, 0xF8BE, 0x9A19, 0xF8BF, 0x8CB6, 0xF8C0, 0x576A,
+	0xF8C1, 0x5E73, 0xF8C2, 0x67B0, 0xF8C3, 0x840D, 0xF8C4, 0x8A55,
+	0xF8C5, 0x5420, 0xF8C6, 0x5B16, 0xF8C7, 0x5E63, 0xF8C8, 0x5EE2,
+	0xF8C9, 0x5F0A, 0xF8CA, 0x6583, 0xF8CB, 0x80BA, 0xF8CC, 0x853D,
+	0xF8CD, 0x9589, 0xF8CE, 0x965B, 0xF8CF, 0x4F48, 0xF8D0, 0x5305,
+	0xF8D1, 0x530D, 0xF8D2, 0x530F, 0xF8D3, 0x5486, 0xF8D4, 0x54FA,
+	0xF8D5, 0x5703, 0xF8D6, 0x5E03, 0xF8D7, 0x6016, 0xF8D8, 0x629B,
+	0xF8D9, 0x62B1, 0xF8DA, 0x6355, 0xF8DB, 0xFA06, 0xF8DC, 0x6CE1,
+	0xF8DD, 0x6D66, 0xF8DE, 0x75B1, 0xF8DF, 0x7832, 0xF8E0, 0x80DE,
+	0xF8E1, 0x812F, 0xF8E2, 0x82DE, 0xF8E3, 0x8461, 0xF8E4, 0x84B2,
+	0xF8E5, 0x888D, 0xF8E6, 0x8912, 0xF8E7, 0x900B, 0xF8E8, 0x92EA,
+	0xF8E9, 0x98FD, 0xF8EA, 0x9B91, 0xF8EB, 0x5E45, 0xF8EC, 0x66B4,
+	0xF8ED, 0x66DD, 0xF8EE, 0x7011, 0xF8EF, 0x7206, 0xF8F0, 0xFA07,
+	0xF8F1, 0x4FF5, 0xF8F2, 0x527D, 0xF8F3, 0x5F6A, 0xF8F4, 0x6153,
+	0xF8F5, 0x6753, 0xF8F6, 0x6A19, 0xF8F7, 0x6F02, 0xF8F8, 0x74E2,
+	0xF8F9, 0x7968, 0xF8FA, 0x8868, 0xF8FB, 0x8C79, 0xF8FC, 0x98C7,
+	0xF8FD, 0x98C4, 0xF8FE, 0x9A43, 0xF9A1, 0x54C1, 0xF9A2, 0x7A1F,
+	0xF9A3, 0x6953, 0xF9A4, 0x8AF7, 0xF9A5, 0x8C4A, 0xF9A6, 0x98A8,
+	0xF9A7, 0x99AE, 0xF9A8, 0x5F7C, 0xF9A9, 0x62AB, 0xF9AA, 0x75B2,
+	0xF9AB, 0x76AE, 0xF9AC, 0x88AB, 0xF9AD, 0x907F, 0xF9AE, 0x9642,
+	0xF9AF, 0x5339, 0xF9B0, 0x5F3C, 0xF9B1, 0x5FC5, 0xF9B2, 0x6CCC,
+	0xF9B3, 0x73CC, 0xF9B4, 0x7562, 0xF9B5, 0x758B, 0xF9B6, 0x7B46,
+	0xF9B7, 0x82FE, 0xF9B8, 0x999D, 0xF9B9, 0x4E4F, 0xF9BA, 0x903C,
+	0xF9BB, 0x4E0B, 0xF9BC, 0x4F55, 0xF9BD, 0x53A6, 0xF9BE, 0x590F,
+	0xF9BF, 0x5EC8, 0xF9C0, 0x6630, 0xF9C1, 0x6CB3, 0xF9C2, 0x7455,
+	0xF9C3, 0x8377, 0xF9C4, 0x8766, 0xF9C5, 0x8CC0, 0xF9C6, 0x9050,
+	0xF9C7, 0x971E, 0xF9C8, 0x9C15, 0xF9C9, 0x58D1, 0xF9CA, 0x5B78,
+	0xF9CB, 0x8650, 0xF9CC, 0x8B14, 0xF9CD, 0x9DB4, 0xF9CE, 0x5BD2,
+	0xF9CF, 0x6068, 0xF9D0, 0x608D, 0xF9D1, 0x65F1, 0xF9D2, 0x6C57,
+	0xF9D3, 0x6F22, 0xF9D4, 0x6FA3, 0xF9D5, 0x701A, 0xF9D6, 0x7F55,
+	0xF9D7, 0x7FF0, 0xF9D8, 0x9591, 0xF9D9, 0x9592, 0xF9DA, 0x9650,
+	0xF9DB, 0x97D3, 0xF9DC, 0x5272, 0xF9DD, 0x8F44, 0xF9DE, 0x51FD,
+	0xF9DF, 0x542B, 0xF9E0, 0x54B8, 0xF9E1, 0x5563, 0xF9E2, 0x558A,
+	0xF9E3, 0x6ABB, 0xF9E4, 0x6DB5, 0xF9E5, 0x7DD8, 0xF9E6, 0x8266,
+	0xF9E7, 0x929C, 0xF9E8, 0x9677, 0xF9E9, 0x9E79, 0xF9EA, 0x5408,
+	0xF9EB, 0x54C8, 0xF9EC, 0x76D2, 0xF9ED, 0x86E4, 0xF9EE, 0x95A4,
+	0xF9EF, 0x95D4, 0xF9F0, 0x965C, 0xF9F1, 0x4EA2, 0xF9F2, 0x4F09,
+	0xF9F3, 0x59EE, 0xF9F4, 0x5AE6, 0xF9F5, 0x5DF7, 0xF9F6, 0x6052,
+	0xF9F7, 0x6297, 0xF9F8, 0x676D, 0xF9F9, 0x6841, 0xF9FA, 0x6C86,
+	0xF9FB, 0x6E2F, 0xF9FC, 0x7F38, 0xF9FD, 0x809B, 0xF9FE, 0x822A,
+	0xFAA1, 0xFA08, 0xFAA2, 0xFA09, 0xFAA3, 0x9805, 0xFAA4, 0x4EA5,
+	0xFAA5, 0x5055, 0xFAA6, 0x54B3, 0xFAA7, 0x5793, 0xFAA8, 0x595A,
+	0xFAA9, 0x5B69, 0xFAAA, 0x5BB3, 0xFAAB, 0x61C8, 0xFAAC, 0x6977,
+	0xFAAD, 0x6D77, 0xFAAE, 0x7023, 0xFAAF, 0x87F9, 0xFAB0, 0x89E3,
+	0xFAB1, 0x8A72, 0xFAB2, 0x8AE7, 0xFAB3, 0x9082, 0xFAB4, 0x99ED,
+	0xFAB5, 0x9AB8, 0xFAB6, 0x52BE, 0xFAB7, 0x6838, 0xFAB8, 0x5016,
+	0xFAB9, 0x5E78, 0xFABA, 0x674F, 0xFABB, 0x8347, 0xFABC, 0x884C,
+	0xFABD, 0x4EAB, 0xFABE, 0x5411, 0xFABF, 0x56AE, 0xFAC0, 0x73E6,
+	0xFAC1, 0x9115, 0xFAC2, 0x97FF, 0xFAC3, 0x9909, 0xFAC4, 0x9957,
+	0xFAC5, 0x9999, 0xFAC6, 0x5653, 0xFAC7, 0x589F, 0xFAC8, 0x865B,
+	0xFAC9, 0x8A31, 0xFACA, 0x61B2, 0xFACB, 0x6AF6, 0xFACC, 0x737B,
+	0xFACD, 0x8ED2, 0xFACE, 0x6B47, 0xFACF, 0x96AA, 0xFAD0, 0x9A57,
+	0xFAD1, 0x5955, 0xFAD2, 0x7200, 0xFAD3, 0x8D6B, 0xFAD4, 0x9769,
+	0xFAD5, 0x4FD4, 0xFAD6, 0x5CF4, 0xFAD7, 0x5F26, 0xFAD8, 0x61F8,
+	0xFAD9, 0x665B, 0xFADA, 0x6CEB, 0xFADB, 0x70AB, 0xFADC, 0x7384,
+	0xFADD, 0x73B9, 0xFADE, 0x73FE, 0xFADF, 0x7729, 0xFAE0, 0x774D,
+	0xFAE1, 0x7D43, 0xFAE2, 0x7D62, 0xFAE3, 0x7E23, 0xFAE4, 0x8237,
+	0xFAE5, 0x8852, 0xFAE6, 0xFA0A, 0xFAE7, 0x8CE2, 0xFAE8, 0x9249,
+	0xFAE9, 0x986F, 0xFAEA, 0x5B51, 0xFAEB, 0x7A74, 0xFAEC, 0x8840,
+	0xFAED, 0x9801, 0xFAEE, 0x5ACC, 0xFAEF, 0x4FE0, 0xFAF0, 0x5354,
+	0xFAF1, 0x593E, 0xFAF2, 0x5CFD, 0xFAF3, 0x633E, 0xFAF4, 0x6D79,
+	0xFAF5, 0x72F9, 0xFAF6, 0x8105, 0xFAF7, 0x8107, 0xFAF8, 0x83A2,
+	0xFAF9, 0x92CF, 0xFAFA, 0x9830, 0xFAFB, 0x4EA8, 0xFAFC, 0x5144,
+	0xFAFD, 0x5211, 0xFAFE, 0x578B, 0xFBA1, 0x5F62, 0xFBA2, 0x6CC2,
+	0xFBA3, 0x6ECE, 0xFBA4, 0x7005, 0xFBA5, 0x7050, 0xFBA6, 0x70AF,
+	0xFBA7, 0x7192, 0xFBA8, 0x73E9, 0xFBA9, 0x7469, 0xFBAA, 0x834A,
+	0xFBAB, 0x87A2, 0xFBAC, 0x8861, 0xFBAD, 0x9008, 0xFBAE, 0x90A2,
+	0xFBAF, 0x93A3, 0xFBB0, 0x99A8, 0xFBB1, 0x516E, 0xFBB2, 0x5F57,
+	0xFBB3, 0x60E0, 0xFBB4, 0x6167, 0xFBB5, 0x66B3, 0xFBB6, 0x8559,
+	0xFBB7, 0x8E4A, 0xFBB8, 0x91AF, 0xFBB9, 0x978B, 0xFBBA, 0x4E4E,
+	0xFBBB, 0x4E92, 0xFBBC, 0x547C, 0xFBBD, 0x58D5, 0xFBBE, 0x58FA,
+	0xFBBF, 0x597D, 0xFBC0, 0x5CB5, 0xFBC1, 0x5F27, 0xFBC2, 0x6236,
+	0xFBC3, 0x6248, 0xFBC4, 0x660A, 0xFBC5, 0x6667, 0xFBC6, 0x6BEB,
+	0xFBC7, 0x6D69, 0xFBC8, 0x6DCF, 0xFBC9, 0x6E56, 0xFBCA, 0x6EF8,
+	0xFBCB, 0x6F94, 0xFBCC, 0x6FE0, 0xFBCD, 0x6FE9, 0xFBCE, 0x705D,
+	0xFBCF, 0x72D0, 0xFBD0, 0x7425, 0xFBD1, 0x745A, 0xFBD2, 0x74E0,
+	0xFBD3, 0x7693, 0xFBD4, 0x795C, 0xFBD5, 0x7CCA, 0xFBD6, 0x7E1E,
+	0xFBD7, 0x80E1, 0xFBD8, 0x82A6, 0xFBD9, 0x846B, 0xFBDA, 0x84BF,
+	0xFBDB, 0x864E, 0xFBDC, 0x865F, 0xFBDD, 0x8774, 0xFBDE, 0x8B77,
+	0xFBDF, 0x8C6A, 0xFBE0, 0x93AC, 0xFBE1, 0x9800, 0xFBE2, 0x9865,
+	0xFBE3, 0x60D1, 0xFBE4, 0x6216, 0xFBE5, 0x9177, 0xFBE6, 0x5A5A,
+	0xFBE7, 0x660F, 0xFBE8, 0x6DF7, 0xFBE9, 0x6E3E, 0xFBEA, 0x743F,
+	0xFBEB, 0x9B42, 0xFBEC, 0x5FFD, 0xFBED, 0x60DA, 0xFBEE, 0x7B0F,
+	0xFBEF, 0x54C4, 0xFBF0, 0x5F18, 0xFBF1, 0x6C5E, 0xFBF2, 0x6CD3,
+	0xFBF3, 0x6D2A, 0xFBF4, 0x70D8, 0xFBF5, 0x7D05, 0xFBF6, 0x8679,
+	0xFBF7, 0x8A0C, 0xFBF8, 0x9D3B, 0xFBF9, 0x5316, 0xFBFA, 0x548C,
+	0xFBFB, 0x5B05, 0xFBFC, 0x6A3A, 0xFBFD, 0x706B, 0xFBFE, 0x7575,
+	0xFCA1, 0x798D, 0xFCA2, 0x79BE, 0xFCA3, 0x82B1, 0xFCA4, 0x83EF,
+	0xFCA5, 0x8A71, 0xFCA6, 0x8B41, 0xFCA7, 0x8CA8, 0xFCA8, 0x9774,
+	0xFCA9, 0xFA0B, 0xFCAA, 0x64F4, 0xFCAB, 0x652B, 0xFCAC, 0x78BA,
+	0xFCAD, 0x78BB, 0xFCAE, 0x7A6B, 0xFCAF, 0x4E38, 0xFCB0, 0x559A,
+	0xFCB1, 0x5950, 0xFCB2, 0x5BA6, 0xFCB3, 0x5E7B, 0xFCB4, 0x60A3,
+	0xFCB5, 0x63DB, 0xFCB6, 0x6B61, 0xFCB7, 0x6665, 0xFCB8, 0x6853,
+	0xFCB9, 0x6E19, 0xFCBA, 0x7165, 0xFCBB, 0x74B0, 0xFCBC, 0x7D08,
+	0xFCBD, 0x9084, 0xFCBE, 0x9A69, 0xFCBF, 0x9C25, 0xFCC0, 0x6D3B,
+	0xFCC1, 0x6ED1, 0xFCC2, 0x733E, 0xFCC3, 0x8C41, 0xFCC4, 0x95CA,
+	0xFCC5, 0x51F0, 0xFCC6, 0x5E4C, 0xFCC7, 0x5FA8, 0xFCC8, 0x604D,
+	0xFCC9, 0x60F6, 0xFCCA, 0x6130, 0xFCCB, 0x614C, 0xFCCC, 0x6643,
+	0xFCCD, 0x6644, 0xFCCE, 0x69A5, 0xFCCF, 0x6CC1, 0xFCD0, 0x6E5F,
+	0xFCD1, 0x6EC9, 0xFCD2, 0x6F62, 0xFCD3, 0x714C, 0xFCD4, 0x749C,
+	0xFCD5, 0x7687, 0xFCD6, 0x7BC1, 0xFCD7, 0x7C27, 0xFCD8, 0x8352,
+	0xFCD9, 0x8757, 0xFCDA, 0x9051, 0xFCDB, 0x968D, 0xFCDC, 0x9EC3,
+	0xFCDD, 0x532F, 0xFCDE, 0x56DE, 0xFCDF, 0x5EFB, 0xFCE0, 0x5F8A,
+	0xFCE1, 0x6062, 0xFCE2, 0x6094, 0xFCE3, 0x61F7, 0xFCE4, 0x6666,
+	0xFCE5, 0x6703, 0xFCE6, 0x6A9C, 0xFCE7, 0x6DEE, 0xFCE8, 0x6FAE,
+	0xFCE9, 0x7070, 0xFCEA, 0x736A, 0xFCEB, 0x7E6A, 0xFCEC, 0x81BE,
+	0xFCED, 0x8334, 0xFCEE, 0x86D4, 0xFCEF, 0x8AA8, 0xFCF0, 0x8CC4,
+	0xFCF1, 0x5283, 0xFCF2, 0x7372, 0xFCF3, 0x5B96, 0xFCF4, 0x6A6B,
+	0xFCF5, 0x9404, 0xFCF6, 0x54EE, 0xFCF7, 0x5686, 0xFCF8, 0x5B5D,
+	0xFCF9, 0x6548, 0xFCFA, 0x6585, 0xFCFB, 0x66C9, 0xFCFC, 0x689F,
+	0xFCFD, 0x6D8D, 0xFCFE, 0x6DC6, 0xFDA1, 0x723B, 0xFDA2, 0x80B4,
+	0xFDA3, 0x9175, 0xFDA4, 0x9A4D, 0xFDA5, 0x4FAF, 0xFDA6, 0x5019,
+	0xFDA7, 0x539A, 0xFDA8, 0x540E, 0xFDA9, 0x543C, 0xFDAA, 0x5589,
+	0xFDAB, 0x55C5, 0xFDAC, 0x5E3F, 0xFDAD, 0x5F8C, 0xFDAE, 0x673D,
+	0xFDAF, 0x7166, 0xFDB0, 0x73DD, 0xFDB1, 0x9005, 0xFDB2, 0x52DB,
+	0xFDB3, 0x52F3, 0xFDB4, 0x5864, 0xFDB5, 0x58CE, 0xFDB6, 0x7104,
+	0xFDB7, 0x718F, 0xFDB8, 0x71FB, 0xFDB9, 0x85B0, 0xFDBA, 0x8A13,
+	0xFDBB, 0x6688, 0xFDBC, 0x85A8, 0xFDBD, 0x55A7, 0xFDBE, 0x6684,
+	0xFDBF, 0x714A, 0xFDC0, 0x8431, 0xFDC1, 0x5349, 0xFDC2, 0x5599,
+	0xFDC3, 0x6BC1, 0xFDC4, 0x5F59, 0xFDC5, 0x5FBD, 0xFDC6, 0x63EE,
+	0xFDC7, 0x6689, 0xFDC8, 0x7147, 0xFDC9, 0x8AF1, 0xFDCA, 0x8F1D,
+	0xFDCB, 0x9EBE, 0xFDCC, 0x4F11, 0xFDCD, 0x643A, 0xFDCE, 0x70CB,
+	0xFDCF, 0x7566, 0xFDD0, 0x8667, 0xFDD1, 0x6064, 0xFDD2, 0x8B4E,
+	0xFDD3, 0x9DF8, 0xFDD4, 0x5147, 0xFDD5, 0x51F6, 0xFDD6, 0x5308,
+	0xFDD7, 0x6D36, 0xFDD8, 0x80F8, 0xFDD9, 0x9ED1, 0xFDDA, 0x6615,
+	0xFDDB, 0x6B23, 0xFDDC, 0x7098, 0xFDDD, 0x75D5, 0xFDDE, 0x5403,
+	0xFDDF, 0x5C79, 0xFDE0, 0x7D07, 0xFDE1, 0x8A16, 0xFDE2, 0x6B20,
+	0xFDE3, 0x6B3D, 0xFDE4, 0x6B46, 0xFDE5, 0x5438, 0xFDE6, 0x6070,
+	0xFDE7, 0x6D3D, 0xFDE8, 0x7FD5, 0xFDE9, 0x8208, 0xFDEA, 0x50D6,
+	0xFDEB, 0x51DE, 0xFDEC, 0x559C, 0xFDED, 0x566B, 0xFDEE, 0x56CD,
+	0xFDEF, 0x59EC, 0xFDF0, 0x5B09, 0xFDF1, 0x5E0C, 0xFDF2, 0x6199,
+	0xFDF3, 0x6198, 0xFDF4, 0x6231, 0xFDF5, 0x665E, 0xFDF6, 0x66E6,
+	0xFDF7, 0x7199, 0xFDF8, 0x71B9, 0xFDF9, 0x71BA, 0xFDFA, 0x72A7,
+	0xFDFB, 0x79A7, 0xFDFC, 0x7A00, 0xFDFD, 0x7FB2, 0xFDFE, 0x8A70,
+	0, 0
+};
+
+
+
+WCHAR ff_convert (	/* Converted code, 0 means conversion error */
+	WCHAR	src,	/* Character code to be converted */
+	UINT	dir		/* 0: Unicode to OEMCP, 1: OEMCP to Unicode */
+)
+{
+	const WCHAR *p;
+	WCHAR c;
+	int i, n, li, hi;
+
+
+	if (src < 0x80) {	/* ASCII */
+		c = src;
+	} else {
+		if (dir) {		/* OEMCP to unicode */
+			p = oem2uni;
+			hi = sizeof(oem2uni) / 4 - 1;
+		} else {		/* Unicode to OEMCP */
+			p = uni2oem;
+			hi = sizeof(uni2oem) / 4 - 1;
+		}
+		li = 0;
+		for (n = 16; n; n--) {
+			i = li + (hi - li) / 2;
+			if (src == p[i * 2]) break;
+			if (src > p[i * 2])
+				li = i;
+			else
+				hi = i;
+		}
+		c = n ? p[i * 2 + 1] : 0;
+	}
+
+	return c;
+}
+#else
+#error This file is not needed in current configuration.
+
+#endif
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/files/ff/option/cc950.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/files/ff/option/cc950.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/files/ff/option/cc950.c	(revision 457)
@@ -0,0 +1,6814 @@
+/*------------------------------------------------------------------------*/
+/* Unicode - OEM code bidirectional converter  (C)ChaN, 2009              */
+/*                                                                        */
+/* CP950 (Traditional Chinese Big5)                                       */
+/*------------------------------------------------------------------------*/
+
+#include "../ff.h"
+
+
+#if _USE_LFN && _CODE_PAGE == 950
+
+
+static
+const WCHAR uni2oem[] = {
+/*  Unicode - OEM,  Unicode - OEM,  Unicode - OEM,  Unicode - OEM */
+	0x00A7, 0xA1B1, 0x00AF, 0xA1C2, 0x00B0, 0xA258, 0x00B1, 0xA1D3,
+	0x00B7, 0xA150, 0x00D7, 0xA1D1, 0x00F7, 0xA1D2, 0x02C7, 0xA3BE,
+	0x02C9, 0xA3BC, 0x02CA, 0xA3BD, 0x02CB, 0xA3BF, 0x02CD, 0xA1C5,
+	0x02D9, 0xA3BB, 0x0391, 0xA344, 0x0392, 0xA345, 0x0393, 0xA346,
+	0x0394, 0xA347, 0x0395, 0xA348, 0x0396, 0xA349, 0x0397, 0xA34A,
+	0x0398, 0xA34B, 0x0399, 0xA34C, 0x039A, 0xA34D, 0x039B, 0xA34E,
+	0x039C, 0xA34F, 0x039D, 0xA350, 0x039E, 0xA351, 0x039F, 0xA352,
+	0x03A0, 0xA353, 0x03A1, 0xA354, 0x03A3, 0xA355, 0x03A4, 0xA356,
+	0x03A5, 0xA357, 0x03A6, 0xA358, 0x03A7, 0xA359, 0x03A8, 0xA35A,
+	0x03A9, 0xA35B, 0x03B1, 0xA35C, 0x03B2, 0xA35D, 0x03B3, 0xA35E,
+	0x03B4, 0xA35F, 0x03B5, 0xA360, 0x03B6, 0xA361, 0x03B7, 0xA362,
+	0x03B8, 0xA363, 0x03B9, 0xA364, 0x03BA, 0xA365, 0x03BB, 0xA366,
+	0x03BC, 0xA367, 0x03BD, 0xA368, 0x03BE, 0xA369, 0x03BF, 0xA36A,
+	0x03C0, 0xA36B, 0x03C1, 0xA36C, 0x03C3, 0xA36D, 0x03C4, 0xA36E,
+	0x03C5, 0xA36F, 0x03C6, 0xA370, 0x03C7, 0xA371, 0x03C8, 0xA372,
+	0x03C9, 0xA373, 0x2013, 0xA156, 0x2014, 0xA158, 0x2018, 0xA1A5,
+	0x2019, 0xA1A6, 0x201C, 0xA1A7, 0x201D, 0xA1A8, 0x2025, 0xA14C,
+	0x2026, 0xA14B, 0x2027, 0xA145, 0x2032, 0xA1AC, 0x2035, 0xA1AB,
+	0x203B, 0xA1B0, 0x20AC, 0xA3E1, 0x2103, 0xA24A, 0x2105, 0xA1C1,
+	0x2109, 0xA24B, 0x2160, 0xA2B9, 0x2161, 0xA2BA, 0x2162, 0xA2BB,
+	0x2163, 0xA2BC, 0x2164, 0xA2BD, 0x2165, 0xA2BE, 0x2166, 0xA2BF,
+	0x2167, 0xA2C0, 0x2168, 0xA2C1, 0x2169, 0xA2C2, 0x2190, 0xA1F6,
+	0x2191, 0xA1F4, 0x2192, 0xA1F7, 0x2193, 0xA1F5, 0x2196, 0xA1F8,
+	0x2197, 0xA1F9, 0x2198, 0xA1FB, 0x2199, 0xA1FA, 0x2215, 0xA241,
+	0x221A, 0xA1D4, 0x221E, 0xA1DB, 0x221F, 0xA1E8, 0x2220, 0xA1E7,
+	0x2223, 0xA1FD, 0x2225, 0xA1FC, 0x2229, 0xA1E4, 0x222A, 0xA1E5,
+	0x222B, 0xA1EC, 0x222E, 0xA1ED, 0x2234, 0xA1EF, 0x2235, 0xA1EE,
+	0x2252, 0xA1DC, 0x2260, 0xA1DA, 0x2261, 0xA1DD, 0x2266, 0xA1D8,
+	0x2267, 0xA1D9, 0x2295, 0xA1F2, 0x2299, 0xA1F3, 0x22A5, 0xA1E6,
+	0x22BF, 0xA1E9, 0x2500, 0xA277, 0x2502, 0xA278, 0x250C, 0xA27A,
+	0x2510, 0xA27B, 0x2514, 0xA27C, 0x2518, 0xA27D, 0x251C, 0xA275,
+	0x2524, 0xA274, 0x252C, 0xA273, 0x2534, 0xA272, 0x253C, 0xA271,
+	0x2550, 0xA2A4, 0x2550, 0xF9F9, 0x2551, 0xF9F8, 0x2552, 0xF9E6,
+	0x2553, 0xF9EF, 0x2554, 0xF9DD, 0x2555, 0xF9E8, 0x2556, 0xF9F1,
+	0x2557, 0xF9DF, 0x2558, 0xF9EC, 0x2559, 0xF9F5, 0x255A, 0xF9E3,
+	0x255B, 0xF9EE, 0x255C, 0xF9F7, 0x255D, 0xF9E5, 0x255E, 0xA2A5,
+	0x255E, 0xF9E9, 0x255F, 0xF9F2, 0x2560, 0xF9E0, 0x2561, 0xA2A7,
+	0x2561, 0xF9EB, 0x2562, 0xF9F4, 0x2563, 0xF9E2, 0x2564, 0xF9E7,
+	0x2565, 0xF9F0, 0x2566, 0xF9DE, 0x2567, 0xF9ED, 0x2568, 0xF9F6,
+	0x2569, 0xF9E4, 0x256A, 0xA2A6, 0x256A, 0xF9EA, 0x256B, 0xF9F3,
+	0x256C, 0xF9E1, 0x256D, 0xA27E, 0x256D, 0xF9FA, 0x256E, 0xA2A1,
+	0x256E, 0xF9FB, 0x256F, 0xA2A3, 0x256F, 0xF9FD, 0x2570, 0xA2A2,
+	0x2570, 0xF9FC, 0x2571, 0xA2AC, 0x2572, 0xA2AD, 0x2573, 0xA2AE,
+	0x2574, 0xA15A, 0x2581, 0xA262, 0x2582, 0xA263, 0x2583, 0xA264,
+	0x2584, 0xA265, 0x2585, 0xA266, 0x2586, 0xA267, 0x2587, 0xA268,
+	0x2588, 0xA269, 0x2589, 0xA270, 0x258A, 0xA26F, 0x258B, 0xA26E,
+	0x258C, 0xA26D, 0x258D, 0xA26C, 0x258E, 0xA26B, 0x258F, 0xA26A,
+	0x2593, 0xF9FE, 0x2594, 0xA276, 0x2595, 0xA279, 0x25A0, 0xA1BD,
+	0x25A1, 0xA1BC, 0x25B2, 0xA1B6, 0x25B3, 0xA1B5, 0x25BC, 0xA1BF,
+	0x25BD, 0xA1BE, 0x25C6, 0xA1BB, 0x25C7, 0xA1BA, 0x25CB, 0xA1B3,
+	0x25CE, 0xA1B7, 0x25CF, 0xA1B4, 0x25E2, 0xA2A8, 0x25E3, 0xA2A9,
+	0x25E4, 0xA2AB, 0x25E5, 0xA2AA, 0x2605, 0xA1B9, 0x2606, 0xA1B8,
+	0x2640, 0xA1F0, 0x2642, 0xA1F1, 0x3000, 0xA140, 0x3001, 0xA142,
+	0x3002, 0xA143, 0x3003, 0xA1B2, 0x3008, 0xA171, 0x3009, 0xA172,
+	0x300A, 0xA16D, 0x300B, 0xA16E, 0x300C, 0xA175, 0x300D, 0xA176,
+	0x300E, 0xA179, 0x300F, 0xA17A, 0x3010, 0xA169, 0x3011, 0xA16A,
+	0x3012, 0xA245, 0x3014, 0xA165, 0x3015, 0xA166, 0x301D, 0xA1A9,
+	0x301E, 0xA1AA, 0x3021, 0xA2C3, 0x3022, 0xA2C4, 0x3023, 0xA2C5,
+	0x3024, 0xA2C6, 0x3025, 0xA2C7, 0x3026, 0xA2C8, 0x3027, 0xA2C9,
+	0x3028, 0xA2CA, 0x3029, 0xA2CB, 0x3105, 0xA374, 0x3106, 0xA375,
+	0x3107, 0xA376, 0x3108, 0xA377, 0x3109, 0xA378, 0x310A, 0xA379,
+	0x310B, 0xA37A, 0x310C, 0xA37B, 0x310D, 0xA37C, 0x310E, 0xA37D,
+	0x310F, 0xA37E, 0x3110, 0xA3A1, 0x3111, 0xA3A2, 0x3112, 0xA3A3,
+	0x3113, 0xA3A4, 0x3114, 0xA3A5, 0x3115, 0xA3A6, 0x3116, 0xA3A7,
+	0x3117, 0xA3A8, 0x3118, 0xA3A9, 0x3119, 0xA3AA, 0x311A, 0xA3AB,
+	0x311B, 0xA3AC, 0x311C, 0xA3AD, 0x311D, 0xA3AE, 0x311E, 0xA3AF,
+	0x311F, 0xA3B0, 0x3120, 0xA3B1, 0x3121, 0xA3B2, 0x3122, 0xA3B3,
+	0x3123, 0xA3B4, 0x3124, 0xA3B5, 0x3125, 0xA3B6, 0x3126, 0xA3B7,
+	0x3127, 0xA3B8, 0x3128, 0xA3B9, 0x3129, 0xA3BA, 0x32A3, 0xA1C0,
+	0x338E, 0xA255, 0x338F, 0xA256, 0x339C, 0xA250, 0x339D, 0xA251,
+	0x339E, 0xA252, 0x33A1, 0xA254, 0x33C4, 0xA257, 0x33CE, 0xA253,
+	0x33D1, 0xA1EB, 0x33D2, 0xA1EA, 0x33D5, 0xA24F, 0x4E00, 0xA440,
+	0x4E01, 0xA442, 0x4E03, 0xA443, 0x4E07, 0xC945, 0x4E08, 0xA456,
+	0x4E09, 0xA454, 0x4E0A, 0xA457, 0x4E0B, 0xA455, 0x4E0C, 0xC946,
+	0x4E0D, 0xA4A3, 0x4E0E, 0xC94F, 0x4E0F, 0xC94D, 0x4E10, 0xA4A2,
+	0x4E11, 0xA4A1, 0x4E14, 0xA542, 0x4E15, 0xA541, 0x4E16, 0xA540,
+	0x4E18, 0xA543, 0x4E19, 0xA4FE, 0x4E1E, 0xA5E0, 0x4E1F, 0xA5E1,
+	0x4E26, 0xA8C3, 0x4E2B, 0xA458, 0x4E2D, 0xA4A4, 0x4E2E, 0xC950,
+	0x4E30, 0xA4A5, 0x4E31, 0xC963, 0x4E32, 0xA6EA, 0x4E33, 0xCBB1,
+	0x4E38, 0xA459, 0x4E39, 0xA4A6, 0x4E3B, 0xA544, 0x4E3C, 0xC964,
+	0x4E42, 0xC940, 0x4E43, 0xA444, 0x4E45, 0xA45B, 0x4E47, 0xC947,
+	0x4E48, 0xA45C, 0x4E4B, 0xA4A7, 0x4E4D, 0xA545, 0x4E4E, 0xA547,
+	0x4E4F, 0xA546, 0x4E52, 0xA5E2, 0x4E53, 0xA5E3, 0x4E56, 0xA8C4,
+	0x4E58, 0xADBC, 0x4E59, 0xA441, 0x4E5C, 0xC941, 0x4E5D, 0xA445,
+	0x4E5E, 0xA45E, 0x4E5F, 0xA45D, 0x4E69, 0xA5E4, 0x4E73, 0xA8C5,
+	0x4E7E, 0xB0AE, 0x4E7F, 0xD44B, 0x4E82, 0xB6C3, 0x4E83, 0xDCB1,
+	0x4E84, 0xDCB2, 0x4E86, 0xA446, 0x4E88, 0xA4A9, 0x4E8B, 0xA8C6,
+	0x4E8C, 0xA447, 0x4E8D, 0xC948, 0x4E8E, 0xA45F, 0x4E91, 0xA4AA,
+	0x4E92, 0xA4AC, 0x4E93, 0xC951, 0x4E94, 0xA4AD, 0x4E95, 0xA4AB,
+	0x4E99, 0xA5E5, 0x4E9B, 0xA8C7, 0x4E9E, 0xA8C8, 0x4E9F, 0xAB45,
+	0x4EA1, 0xA460, 0x4EA2, 0xA4AE, 0x4EA4, 0xA5E6, 0x4EA5, 0xA5E8,
+	0x4EA6, 0xA5E7, 0x4EA8, 0xA6EB, 0x4EAB, 0xA8C9, 0x4EAC, 0xA8CA,
+	0x4EAD, 0xAB46, 0x4EAE, 0xAB47, 0x4EB3, 0xADBD, 0x4EB6, 0xDCB3,
+	0x4EB9, 0xF6D6, 0x4EBA, 0xA448, 0x4EC0, 0xA4B0, 0x4EC1, 0xA4AF,
+	0x4EC2, 0xC952, 0x4EC3, 0xA4B1, 0x4EC4, 0xA4B7, 0x4EC6, 0xA4B2,
+	0x4EC7, 0xA4B3, 0x4EC8, 0xC954, 0x4EC9, 0xC953, 0x4ECA, 0xA4B5,
+	0x4ECB, 0xA4B6, 0x4ECD, 0xA4B4, 0x4ED4, 0xA54A, 0x4ED5, 0xA54B,
+	0x4ED6, 0xA54C, 0x4ED7, 0xA54D, 0x4ED8, 0xA549, 0x4ED9, 0xA550,
+	0x4EDA, 0xC96A, 0x4EDC, 0xC966, 0x4EDD, 0xC969, 0x4EDE, 0xA551,
+	0x4EDF, 0xA561, 0x4EE1, 0xC968, 0x4EE3, 0xA54E, 0x4EE4, 0xA54F,
+	0x4EE5, 0xA548, 0x4EE8, 0xC965, 0x4EE9, 0xC967, 0x4EF0, 0xA5F5,
+	0x4EF1, 0xC9B0, 0x4EF2, 0xA5F2, 0x4EF3, 0xA5F6, 0x4EF4, 0xC9BA,
+	0x4EF5, 0xC9AE, 0x4EF6, 0xA5F3, 0x4EF7, 0xC9B2, 0x4EFB, 0xA5F4,
+	0x4EFD, 0xA5F7, 0x4EFF, 0xA5E9, 0x4F00, 0xC9B1, 0x4F01, 0xA5F8,
+	0x4F02, 0xC9B5, 0x4F04, 0xC9B9, 0x4F05, 0xC9B6, 0x4F08, 0xC9B3,
+	0x4F09, 0xA5EA, 0x4F0A, 0xA5EC, 0x4F0B, 0xA5F9, 0x4F0D, 0xA5EE,
+	0x4F0E, 0xC9AB, 0x4F0F, 0xA5F1, 0x4F10, 0xA5EF, 0x4F11, 0xA5F0,
+	0x4F12, 0xC9BB, 0x4F13, 0xC9B8, 0x4F14, 0xC9AF, 0x4F15, 0xA5ED,
+	0x4F18, 0xC9AC, 0x4F19, 0xA5EB, 0x4F1D, 0xC9B4, 0x4F22, 0xC9B7,
+	0x4F2C, 0xC9AD, 0x4F2D, 0xCA66, 0x4F2F, 0xA742, 0x4F30, 0xA6F4,
+	0x4F33, 0xCA67, 0x4F34, 0xA6F1, 0x4F36, 0xA744, 0x4F38, 0xA6F9,
+	0x4F3A, 0xA6F8, 0x4F3B, 0xCA5B, 0x4F3C, 0xA6FC, 0x4F3D, 0xA6F7,
+	0x4F3E, 0xCA60, 0x4F3F, 0xCA68, 0x4F41, 0xCA64, 0x4F43, 0xA6FA,
+	0x4F46, 0xA6FD, 0x4F47, 0xA6EE, 0x4F48, 0xA747, 0x4F49, 0xCA5D,
+	0x4F4C, 0xCBBD, 0x4F4D, 0xA6EC, 0x4F4E, 0xA743, 0x4F4F, 0xA6ED,
+	0x4F50, 0xA6F5, 0x4F51, 0xA6F6, 0x4F52, 0xCA62, 0x4F53, 0xCA5E,
+	0x4F54, 0xA6FB, 0x4F55, 0xA6F3, 0x4F56, 0xCA5A, 0x4F57, 0xA6EF,
+	0x4F58, 0xCA65, 0x4F59, 0xA745, 0x4F5A, 0xA748, 0x4F5B, 0xA6F2,
+	0x4F5C, 0xA740, 0x4F5D, 0xA746, 0x4F5E, 0xA6F0, 0x4F5F, 0xCA63,
+	0x4F60, 0xA741, 0x4F61, 0xCA69, 0x4F62, 0xCA5C, 0x4F63, 0xA6FE,
+	0x4F64, 0xCA5F, 0x4F67, 0xCA61, 0x4F69, 0xA8D8, 0x4F6A, 0xCBBF,
+	0x4F6B, 0xCBCB, 0x4F6C, 0xA8D0, 0x4F6E, 0xCBCC, 0x4F6F, 0xA8CB,
+	0x4F70, 0xA8D5, 0x4F73, 0xA8CE, 0x4F74, 0xCBB9, 0x4F75, 0xA8D6,
+	0x4F76, 0xCBB8, 0x4F77, 0xCBBC, 0x4F78, 0xCBC3, 0x4F79, 0xCBC1,
+	0x4F7A, 0xA8DE, 0x4F7B, 0xA8D9, 0x4F7C, 0xCBB3, 0x4F7D, 0xCBB5,
+	0x4F7E, 0xA8DB, 0x4F7F, 0xA8CF, 0x4F80, 0xCBB6, 0x4F81, 0xCBC2,
+	0x4F82, 0xCBC9, 0x4F83, 0xA8D4, 0x4F84, 0xCBBB, 0x4F85, 0xCBB4,
+	0x4F86, 0xA8D3, 0x4F87, 0xCBB7, 0x4F88, 0xA8D7, 0x4F89, 0xCBBA,
+	0x4F8B, 0xA8D2, 0x4F8D, 0xA8CD, 0x4F8F, 0xA8DC, 0x4F90, 0xCBC4,
+	0x4F91, 0xA8DD, 0x4F92, 0xCBC8, 0x4F94, 0xCBC6, 0x4F95, 0xCBCA,
+	0x4F96, 0xA8DA, 0x4F97, 0xCBBE, 0x4F98, 0xCBB2, 0x4F9A, 0xCBC0,
+	0x4F9B, 0xA8D1, 0x4F9C, 0xCBC5, 0x4F9D, 0xA8CC, 0x4F9E, 0xCBC7,
+	0x4FAE, 0xAB56, 0x4FAF, 0xAB4A, 0x4FB2, 0xCDE0, 0x4FB3, 0xCDE8,
+	0x4FB5, 0xAB49, 0x4FB6, 0xAB51, 0x4FB7, 0xAB5D, 0x4FB9, 0xCDEE,
+	0x4FBA, 0xCDEC, 0x4FBB, 0xCDE7, 0x4FBF, 0xAB4B, 0x4FC0, 0xCDED,
+	0x4FC1, 0xCDE3, 0x4FC2, 0xAB59, 0x4FC3, 0xAB50, 0x4FC4, 0xAB58,
+	0x4FC5, 0xCDDE, 0x4FC7, 0xCDEA, 0x4FC9, 0xCDE1, 0x4FCA, 0xAB54,
+	0x4FCB, 0xCDE2, 0x4FCD, 0xCDDD, 0x4FCE, 0xAB5B, 0x4FCF, 0xAB4E,
+	0x4FD0, 0xAB57, 0x4FD1, 0xAB4D, 0x4FD3, 0xCDDF, 0x4FD4, 0xCDE4,
+	0x4FD6, 0xCDEB, 0x4FD7, 0xAB55, 0x4FD8, 0xAB52, 0x4FD9, 0xCDE6,
+	0x4FDA, 0xAB5A, 0x4FDB, 0xCDE9, 0x4FDC, 0xCDE5, 0x4FDD, 0xAB4F,
+	0x4FDE, 0xAB5C, 0x4FDF, 0xAB53, 0x4FE0, 0xAB4C, 0x4FE1, 0xAB48,
+	0x4FEC, 0xCDEF, 0x4FEE, 0xADD7, 0x4FEF, 0xADC1, 0x4FF1, 0xADD1,
+	0x4FF3, 0xADD6, 0x4FF4, 0xD0D0, 0x4FF5, 0xD0CF, 0x4FF6, 0xD0D4,
+	0x4FF7, 0xD0D5, 0x4FF8, 0xADC4, 0x4FFA, 0xADCD, 0x4FFE, 0xADDA,
+	0x5000, 0xADCE, 0x5005, 0xD0C9, 0x5006, 0xADC7, 0x5007, 0xD0CA,
+	0x5009, 0xADDC, 0x500B, 0xADD3, 0x500C, 0xADBE, 0x500D, 0xADBF,
+	0x500E, 0xD0DD, 0x500F, 0xB0BF, 0x5011, 0xADCC, 0x5012, 0xADCB,
+	0x5013, 0xD0CB, 0x5014, 0xADCF, 0x5015, 0xD45B, 0x5016, 0xADC6,
+	0x5017, 0xD0D6, 0x5018, 0xADD5, 0x5019, 0xADD4, 0x501A, 0xADCA,
+	0x501B, 0xD0CE, 0x501C, 0xD0D7, 0x501E, 0xD0C8, 0x501F, 0xADC9,
+	0x5020, 0xD0D8, 0x5021, 0xADD2, 0x5022, 0xD0CC, 0x5023, 0xADC0,
+	0x5025, 0xADC3, 0x5026, 0xADC2, 0x5027, 0xD0D9, 0x5028, 0xADD0,
+	0x5029, 0xADC5, 0x502A, 0xADD9, 0x502B, 0xADDB, 0x502C, 0xD0D3,
+	0x502D, 0xADD8, 0x502F, 0xD0DB, 0x5030, 0xD0CD, 0x5031, 0xD0DC,
+	0x5033, 0xD0D1, 0x5035, 0xD0DA, 0x5037, 0xD0D2, 0x503C, 0xADC8,
+	0x5040, 0xD463, 0x5041, 0xD457, 0x5043, 0xB0B3, 0x5045, 0xD45C,
+	0x5046, 0xD462, 0x5047, 0xB0B2, 0x5048, 0xD455, 0x5049, 0xB0B6,
+	0x504A, 0xD459, 0x504B, 0xD452, 0x504C, 0xB0B4, 0x504D, 0xD456,
+	0x504E, 0xB0B9, 0x504F, 0xB0BE, 0x5051, 0xD467, 0x5053, 0xD451,
+	0x5055, 0xB0BA, 0x5057, 0xD466, 0x505A, 0xB0B5, 0x505B, 0xD458,
+	0x505C, 0xB0B1, 0x505D, 0xD453, 0x505E, 0xD44F, 0x505F, 0xD45D,
+	0x5060, 0xD450, 0x5061, 0xD44E, 0x5062, 0xD45A, 0x5063, 0xD460,
+	0x5064, 0xD461, 0x5065, 0xB0B7, 0x5068, 0xD85B, 0x5069, 0xD45E,
+	0x506A, 0xD44D, 0x506B, 0xD45F, 0x506D, 0xB0C1, 0x506E, 0xD464,
+	0x506F, 0xB0C0, 0x5070, 0xD44C, 0x5072, 0xD454, 0x5073, 0xD465,
+	0x5074, 0xB0BC, 0x5075, 0xB0BB, 0x5076, 0xB0B8, 0x5077, 0xB0BD,
+	0x507A, 0xB0AF, 0x507D, 0xB0B0, 0x5080, 0xB3C8, 0x5082, 0xD85E,
+	0x5083, 0xD857, 0x5085, 0xB3C5, 0x5087, 0xD85F, 0x508B, 0xD855,
+	0x508C, 0xD858, 0x508D, 0xB3C4, 0x508E, 0xD859, 0x5091, 0xB3C7,
+	0x5092, 0xD85D, 0x5094, 0xD853, 0x5095, 0xD852, 0x5096, 0xB3C9,
+	0x5098, 0xB3CA, 0x5099, 0xB3C6, 0x509A, 0xB3CB, 0x509B, 0xD851,
+	0x509C, 0xD85C, 0x509D, 0xD85A, 0x509E, 0xD854, 0x50A2, 0xB3C3,
+	0x50A3, 0xD856, 0x50AC, 0xB6CA, 0x50AD, 0xB6C4, 0x50AE, 0xDCB7,
+	0x50AF, 0xB6CD, 0x50B0, 0xDCBD, 0x50B1, 0xDCC0, 0x50B2, 0xB6C6,
+	0x50B3, 0xB6C7, 0x50B4, 0xDCBA, 0x50B5, 0xB6C5, 0x50B6, 0xDCC3,
+	0x50B7, 0xB6CB, 0x50B8, 0xDCC4, 0x50BA, 0xDCBF, 0x50BB, 0xB6CC,
+	0x50BD, 0xDCB4, 0x50BE, 0xB6C9, 0x50BF, 0xDCB5, 0x50C1, 0xDCBE,
+	0x50C2, 0xDCBC, 0x50C4, 0xDCB8, 0x50C5, 0xB6C8, 0x50C6, 0xDCB6,
+	0x50C7, 0xB6CE, 0x50C8, 0xDCBB, 0x50C9, 0xDCC2, 0x50CA, 0xDCB9,
+	0x50CB, 0xDCC1, 0x50CE, 0xB9B6, 0x50CF, 0xB9B3, 0x50D1, 0xB9B4,
+	0x50D3, 0xE0F9, 0x50D4, 0xE0F1, 0x50D5, 0xB9B2, 0x50D6, 0xB9AF,
+	0x50D7, 0xE0F2, 0x50DA, 0xB9B1, 0x50DB, 0xE0F5, 0x50DD, 0xE0F7,
+	0x50E0, 0xE0FE, 0x50E3, 0xE0FD, 0x50E4, 0xE0F8, 0x50E5, 0xB9AE,
+	0x50E6, 0xE0F0, 0x50E7, 0xB9AC, 0x50E8, 0xE0F3, 0x50E9, 0xB9B7,
+	0x50EA, 0xE0F6, 0x50EC, 0xE0FA, 0x50ED, 0xB9B0, 0x50EE, 0xB9AD,
+	0x50EF, 0xE0FC, 0x50F0, 0xE0FB, 0x50F1, 0xB9B5, 0x50F3, 0xE0F4,
+	0x50F5, 0xBBF8, 0x50F6, 0xE4EC, 0x50F8, 0xE4E9, 0x50F9, 0xBBF9,
+	0x50FB, 0xBBF7, 0x50FD, 0xE4F0, 0x50FE, 0xE4ED, 0x50FF, 0xE4E6,
+	0x5100, 0xBBF6, 0x5102, 0xBBFA, 0x5103, 0xE4E7, 0x5104, 0xBBF5,
+	0x5105, 0xBBFD, 0x5106, 0xE4EA, 0x5107, 0xE4EB, 0x5108, 0xBBFB,
+	0x5109, 0xBBFC, 0x510A, 0xE4F1, 0x510B, 0xE4EE, 0x510C, 0xE4EF,
+	0x5110, 0xBEAA, 0x5111, 0xE8F8, 0x5112, 0xBEA7, 0x5113, 0xE8F5,
+	0x5114, 0xBEA9, 0x5115, 0xBEAB, 0x5117, 0xE8F6, 0x5118, 0xBEA8,
+	0x511A, 0xE8F7, 0x511C, 0xE8F4, 0x511F, 0xC076, 0x5120, 0xECBD,
+	0x5121, 0xC077, 0x5122, 0xECBB, 0x5124, 0xECBC, 0x5125, 0xECBA,
+	0x5126, 0xECB9, 0x5129, 0xECBE, 0x512A, 0xC075, 0x512D, 0xEFB8,
+	0x512E, 0xEFB9, 0x5130, 0xE4E8, 0x5131, 0xEFB7, 0x5132, 0xC078,
+	0x5133, 0xC35F, 0x5134, 0xF1EB, 0x5135, 0xF1EC, 0x5137, 0xC4D7,
+	0x5138, 0xC4D8, 0x5139, 0xF5C1, 0x513A, 0xF5C0, 0x513B, 0xC56C,
+	0x513C, 0xC56B, 0x513D, 0xF7D0, 0x513F, 0xA449, 0x5140, 0xA461,
+	0x5141, 0xA4B9, 0x5143, 0xA4B8, 0x5144, 0xA553, 0x5145, 0xA552,
+	0x5146, 0xA5FC, 0x5147, 0xA5FB, 0x5148, 0xA5FD, 0x5149, 0xA5FA,
+	0x514B, 0xA74A, 0x514C, 0xA749, 0x514D, 0xA74B, 0x5152, 0xA8E0,
+	0x5154, 0xA8DF, 0x5155, 0xA8E1, 0x5157, 0xAB5E, 0x5159, 0xA259,
+	0x515A, 0xD0DE, 0x515B, 0xA25A, 0x515C, 0xB0C2, 0x515D, 0xA25C,
+	0x515E, 0xA25B, 0x515F, 0xD860, 0x5161, 0xA25D, 0x5162, 0xB9B8,
+	0x5163, 0xA25E, 0x5165, 0xA44A, 0x5167, 0xA4BA, 0x5168, 0xA5FE,
+	0x5169, 0xA8E2, 0x516B, 0xA44B, 0x516C, 0xA4BD, 0x516D, 0xA4BB,
+	0x516E, 0xA4BC, 0x5171, 0xA640, 0x5175, 0xA74C, 0x5176, 0xA8E4,
+	0x5177, 0xA8E3, 0x5178, 0xA8E5, 0x517C, 0xADDD, 0x5180, 0xBEAC,
+	0x5187, 0xC94E, 0x5189, 0xA554, 0x518A, 0xA555, 0x518D, 0xA641,
+	0x518F, 0xCA6A, 0x5191, 0xAB60, 0x5192, 0xAB5F, 0x5193, 0xD0E0,
+	0x5194, 0xD0DF, 0x5195, 0xB0C3, 0x5197, 0xA4BE, 0x5198, 0xC955,
+	0x519E, 0xCBCD, 0x51A0, 0xAB61, 0x51A2, 0xADE0, 0x51A4, 0xADDE,
+	0x51A5, 0xADDF, 0x51AA, 0xBEAD, 0x51AC, 0xA556, 0x51B0, 0xA642,
+	0x51B1, 0xC9BC, 0x51B6, 0xA74D, 0x51B7, 0xA74E, 0x51B9, 0xCA6B,
+	0x51BC, 0xCBCE, 0x51BD, 0xA8E6, 0x51BE, 0xCBCF, 0x51C4, 0xD0E2,
+	0x51C5, 0xD0E3, 0x51C6, 0xADE3, 0x51C8, 0xD0E4, 0x51CA, 0xD0E1,
+	0x51CB, 0xADE4, 0x51CC, 0xADE2, 0x51CD, 0xADE1, 0x51CE, 0xD0E5,
+	0x51D0, 0xD468, 0x51D4, 0xD861, 0x51D7, 0xDCC5, 0x51D8, 0xE140,
+	0x51DC, 0xBBFE, 0x51DD, 0xBEAE, 0x51DE, 0xE8F9, 0x51E0, 0xA44C,
+	0x51E1, 0xA45A, 0x51F0, 0xB0C4, 0x51F1, 0xB3CD, 0x51F3, 0xB9B9,
+	0x51F5, 0xC942, 0x51F6, 0xA4BF, 0x51F8, 0xA559, 0x51F9, 0xA557,
+	0x51FA, 0xA558, 0x51FD, 0xA8E7, 0x5200, 0xA44D, 0x5201, 0xA44E,
+	0x5203, 0xA462, 0x5206, 0xA4C0, 0x5207, 0xA4C1, 0x5208, 0xA4C2,
+	0x5209, 0xC9BE, 0x520A, 0xA55A, 0x520C, 0xC96B, 0x520E, 0xA646,
+	0x5210, 0xC9BF, 0x5211, 0xA644, 0x5212, 0xA645, 0x5213, 0xC9BD,
+	0x5216, 0xA647, 0x5217, 0xA643, 0x521C, 0xCA6C, 0x521D, 0xAAEC,
+	0x521E, 0xCA6D, 0x5221, 0xCA6E, 0x5224, 0xA750, 0x5225, 0xA74F,
+	0x5228, 0xA753, 0x5229, 0xA751, 0x522A, 0xA752, 0x522E, 0xA8ED,
+	0x5230, 0xA8EC, 0x5231, 0xCBD4, 0x5232, 0xCBD1, 0x5233, 0xCBD2,
+	0x5235, 0xCBD0, 0x5236, 0xA8EE, 0x5237, 0xA8EA, 0x5238, 0xA8E9,
+	0x523A, 0xA8EB, 0x523B, 0xA8E8, 0x5241, 0xA8EF, 0x5243, 0xAB63,
+	0x5244, 0xCDF0, 0x5246, 0xCBD3, 0x5247, 0xAB68, 0x5249, 0xCDF1,
+	0x524A, 0xAB64, 0x524B, 0xAB67, 0x524C, 0xAB66, 0x524D, 0xAB65,
+	0x524E, 0xAB62, 0x5252, 0xD0E8, 0x5254, 0xADE7, 0x5255, 0xD0EB,
+	0x5256, 0xADE5, 0x525A, 0xD0E7, 0x525B, 0xADE8, 0x525C, 0xADE6,
+	0x525D, 0xADE9, 0x525E, 0xD0E9, 0x525F, 0xD0EA, 0x5261, 0xD0E6,
+	0x5262, 0xD0EC, 0x5269, 0xB3D1, 0x526A, 0xB0C5, 0x526B, 0xD469,
+	0x526C, 0xD46B, 0x526D, 0xD46A, 0x526E, 0xD46C, 0x526F, 0xB0C6,
+	0x5272, 0xB3CE, 0x5274, 0xB3CF, 0x5275, 0xB3D0, 0x5277, 0xB6D0,
+	0x5278, 0xDCC7, 0x527A, 0xDCC6, 0x527B, 0xDCC8, 0x527C, 0xDCC9,
+	0x527D, 0xB6D1, 0x527F, 0xB6CF, 0x5280, 0xE141, 0x5281, 0xE142,
+	0x5282, 0xB9BB, 0x5283, 0xB9BA, 0x5284, 0xE35A, 0x5287, 0xBC40,
+	0x5288, 0xBC41, 0x5289, 0xBC42, 0x528A, 0xBC44, 0x528B, 0xE4F2,
+	0x528C, 0xE4F3, 0x528D, 0xBC43, 0x5291, 0xBEAF, 0x5293, 0xBEB0,
+	0x5296, 0xF1ED, 0x5297, 0xF5C3, 0x5298, 0xF5C2, 0x5299, 0xF7D1,
+	0x529B, 0xA44F, 0x529F, 0xA55C, 0x52A0, 0xA55B, 0x52A3, 0xA648,
+	0x52A6, 0xC9C0, 0x52A9, 0xA755, 0x52AA, 0xA756, 0x52AB, 0xA754,
+	0x52AC, 0xA757, 0x52AD, 0xCA6F, 0x52AE, 0xCA70, 0x52BB, 0xA8F1,
+	0x52BC, 0xCBD5, 0x52BE, 0xA8F0, 0x52C0, 0xCDF2, 0x52C1, 0xAB6C,
+	0x52C2, 0xCDF3, 0x52C3, 0xAB6B, 0x52C7, 0xAB69, 0x52C9, 0xAB6A,
+	0x52CD, 0xD0ED, 0x52D2, 0xB0C7, 0x52D3, 0xD46E, 0x52D5, 0xB0CA,
+	0x52D6, 0xD46D, 0x52D7, 0xB1E5, 0x52D8, 0xB0C9, 0x52D9, 0xB0C8,
+	0x52DB, 0xB3D4, 0x52DD, 0xB3D3, 0x52DE, 0xB3D2, 0x52DF, 0xB6D2,
+	0x52E2, 0xB6D5, 0x52E3, 0xB6D6, 0x52E4, 0xB6D4, 0x52E6, 0xB6D3,
+	0x52E9, 0xE143, 0x52EB, 0xE144, 0x52EF, 0xE4F5, 0x52F0, 0xBC45,
+	0x52F1, 0xE4F4, 0x52F3, 0xBEB1, 0x52F4, 0xECBF, 0x52F5, 0xC079,
+	0x52F7, 0xF1EE, 0x52F8, 0xC455, 0x52FA, 0xA463, 0x52FB, 0xA4C3,
+	0x52FC, 0xC956, 0x52FE, 0xA4C4, 0x52FF, 0xA4C5, 0x5305, 0xA55D,
+	0x5306, 0xA55E, 0x5308, 0xA649, 0x5309, 0xCA71, 0x530A, 0xCBD6,
+	0x530B, 0xCBD7, 0x530D, 0xAB6D, 0x530E, 0xD0EE, 0x530F, 0xB0CC,
+	0x5310, 0xB0CB, 0x5311, 0xD863, 0x5312, 0xD862, 0x5315, 0xA450,
+	0x5316, 0xA4C6, 0x5317, 0xA55F, 0x5319, 0xB0CD, 0x531A, 0xC943,
+	0x531C, 0xC96C, 0x531D, 0xA560, 0x531F, 0xC9C2, 0x5320, 0xA64B,
+	0x5321, 0xA64A, 0x5322, 0xC9C1, 0x5323, 0xA758, 0x532A, 0xADEA,
+	0x532D, 0xD46F, 0x532F, 0xB6D7, 0x5330, 0xE145, 0x5331, 0xB9BC,
+	0x5334, 0xE8FA, 0x5337, 0xF3FD, 0x5339, 0xA4C7, 0x533C, 0xCBD8,
+	0x533D, 0xCDF4, 0x533E, 0xB0D0, 0x533F, 0xB0CE, 0x5340, 0xB0CF,
+	0x5341, 0xA2CC, 0x5341, 0xA451, 0x5343, 0xA464, 0x5344, 0xA2CD,
+	0x5345, 0xA2CE, 0x5345, 0xA4CA, 0x5347, 0xA4C9, 0x5348, 0xA4C8,
+	0x5349, 0xA563, 0x534A, 0xA562, 0x534C, 0xC96D, 0x534D, 0xC9C3,
+	0x5351, 0xA8F5, 0x5352, 0xA8F2, 0x5353, 0xA8F4, 0x5354, 0xA8F3,
+	0x5357, 0xAB6E, 0x535A, 0xB3D5, 0x535C, 0xA452, 0x535E, 0xA4CB,
+	0x5360, 0xA565, 0x5361, 0xA564, 0x5363, 0xCA72, 0x5366, 0xA8F6,
+	0x536C, 0xC957, 0x536E, 0xA567, 0x536F, 0xA566, 0x5370, 0xA64C,
+	0x5371, 0xA64D, 0x5372, 0xCA73, 0x5373, 0xA759, 0x5375, 0xA75A,
+	0x5377, 0xA8F7, 0x5378, 0xA8F8, 0x5379, 0xA8F9, 0x537B, 0xAB6F,
+	0x537C, 0xCDF5, 0x537F, 0xADEB, 0x5382, 0xC944, 0x5384, 0xA4CC,
+	0x538A, 0xC9C4, 0x538E, 0xCA74, 0x538F, 0xCA75, 0x5392, 0xCBD9,
+	0x5394, 0xCBDA, 0x5396, 0xCDF7, 0x5397, 0xCDF6, 0x5398, 0xCDF9,
+	0x5399, 0xCDF8, 0x539A, 0xAB70, 0x539C, 0xD470, 0x539D, 0xADED,
+	0x539E, 0xD0EF, 0x539F, 0xADEC, 0x53A4, 0xD864, 0x53A5, 0xB3D6,
+	0x53A7, 0xD865, 0x53AC, 0xE146, 0x53AD, 0xB9BD, 0x53B2, 0xBC46,
+	0x53B4, 0xF1EF, 0x53B9, 0xC958, 0x53BB, 0xA568, 0x53C3, 0xB0D1,
+	0x53C8, 0xA453, 0x53C9, 0xA465, 0x53CA, 0xA4CE, 0x53CB, 0xA4CD,
+	0x53CD, 0xA4CF, 0x53D4, 0xA8FB, 0x53D6, 0xA8FA, 0x53D7, 0xA8FC,
+	0x53DB, 0xAB71, 0x53DF, 0xADEE, 0x53E1, 0xE8FB, 0x53E2, 0xC24F,
+	0x53E3, 0xA466, 0x53E4, 0xA56A, 0x53E5, 0xA579, 0x53E6, 0xA574,
+	0x53E8, 0xA56F, 0x53E9, 0xA56E, 0x53EA, 0xA575, 0x53EB, 0xA573,
+	0x53EC, 0xA56C, 0x53ED, 0xA57A, 0x53EE, 0xA56D, 0x53EF, 0xA569,
+	0x53F0, 0xA578, 0x53F1, 0xA577, 0x53F2, 0xA576, 0x53F3, 0xA56B,
+	0x53F5, 0xA572, 0x53F8, 0xA571, 0x53FB, 0xA57B, 0x53FC, 0xA570,
+	0x5401, 0xA653, 0x5403, 0xA659, 0x5404, 0xA655, 0x5406, 0xA65B,
+	0x5407, 0xC9C5, 0x5408, 0xA658, 0x5409, 0xA64E, 0x540A, 0xA651,
+	0x540B, 0xA654, 0x540C, 0xA650, 0x540D, 0xA657, 0x540E, 0xA65A,
+	0x540F, 0xA64F, 0x5410, 0xA652, 0x5411, 0xA656, 0x5412, 0xA65C,
+	0x5418, 0xCA7E, 0x5419, 0xCA7B, 0x541B, 0xA767, 0x541C, 0xCA7C,
+	0x541D, 0xA75B, 0x541E, 0xA75D, 0x541F, 0xA775, 0x5420, 0xA770,
+	0x5424, 0xCAA5, 0x5425, 0xCA7D, 0x5426, 0xA75F, 0x5427, 0xA761,
+	0x5428, 0xCAA4, 0x5429, 0xA768, 0x542A, 0xCA78, 0x542B, 0xA774,
+	0x542C, 0xA776, 0x542D, 0xA75C, 0x542E, 0xA76D, 0x5430, 0xCA76,
+	0x5431, 0xA773, 0x5433, 0xA764, 0x5435, 0xA76E, 0x5436, 0xA76F,
+	0x5437, 0xCA77, 0x5438, 0xA76C, 0x5439, 0xA76A, 0x543B, 0xA76B,
+	0x543C, 0xA771, 0x543D, 0xCAA1, 0x543E, 0xA75E, 0x5440, 0xA772,
+	0x5441, 0xCAA3, 0x5442, 0xA766, 0x5443, 0xA763, 0x5445, 0xCA7A,
+	0x5446, 0xA762, 0x5447, 0xCAA6, 0x5448, 0xA765, 0x544A, 0xA769,
+	0x544E, 0xA760, 0x544F, 0xCAA2, 0x5454, 0xCA79, 0x5460, 0xCBEB,
+	0x5461, 0xCBEA, 0x5462, 0xA94F, 0x5463, 0xCBED, 0x5464, 0xCBEF,
+	0x5465, 0xCBE4, 0x5466, 0xCBE7, 0x5467, 0xCBEE, 0x5468, 0xA950,
+	0x546B, 0xCBE1, 0x546C, 0xCBE5, 0x546F, 0xCBE9, 0x5470, 0xCE49,
+	0x5471, 0xA94B, 0x5472, 0xCE4D, 0x5473, 0xA8FD, 0x5474, 0xCBE6,
+	0x5475, 0xA8FE, 0x5476, 0xA94C, 0x5477, 0xA945, 0x5478, 0xA941,
+	0x547A, 0xCBE2, 0x547B, 0xA944, 0x547C, 0xA949, 0x547D, 0xA952,
+	0x547E, 0xCBE3, 0x547F, 0xCBDC, 0x5480, 0xA943, 0x5481, 0xCBDD,
+	0x5482, 0xCBDF, 0x5484, 0xA946, 0x5486, 0xA948, 0x5487, 0xCBDB,
+	0x5488, 0xCBE0, 0x548B, 0xA951, 0x548C, 0xA94D, 0x548D, 0xCBE8,
+	0x548E, 0xA953, 0x5490, 0xA94A, 0x5491, 0xCBDE, 0x5492, 0xA947,
+	0x5495, 0xA942, 0x5496, 0xA940, 0x5498, 0xCBEC, 0x549A, 0xA94E,
+	0x54A0, 0xCE48, 0x54A1, 0xCDFB, 0x54A2, 0xCE4B, 0x54A5, 0xCDFD,
+	0x54A6, 0xAB78, 0x54A7, 0xABA8, 0x54A8, 0xAB74, 0x54A9, 0xABA7,
+	0x54AA, 0xAB7D, 0x54AB, 0xABA4, 0x54AC, 0xAB72, 0x54AD, 0xCDFC,
+	0x54AE, 0xCE43, 0x54AF, 0xABA3, 0x54B0, 0xCE4F, 0x54B1, 0xABA5,
+	0x54B3, 0xAB79, 0x54B6, 0xCE45, 0x54B7, 0xCE42, 0x54B8, 0xAB77,
+	0x54BA, 0xCDFA, 0x54BB, 0xABA6, 0x54BC, 0xCE4A, 0x54BD, 0xAB7C,
+	0x54BE, 0xCE4C, 0x54BF, 0xABA9, 0x54C0, 0xAB73, 0x54C1, 0xAB7E,
+	0x54C2, 0xAB7B, 0x54C3, 0xCE40, 0x54C4, 0xABA1, 0x54C5, 0xCE46,
+	0x54C6, 0xCE47, 0x54C7, 0xAB7A, 0x54C8, 0xABA2, 0x54C9, 0xAB76,
+	0x54CE, 0xAB75, 0x54CF, 0xCDFE, 0x54D6, 0xCE44, 0x54DE, 0xCE4E,
+	0x54E0, 0xD144, 0x54E1, 0xADFB, 0x54E2, 0xD0F1, 0x54E4, 0xD0F6,
+	0x54E5, 0xADF4, 0x54E6, 0xAE40, 0x54E7, 0xD0F4, 0x54E8, 0xADEF,
+	0x54E9, 0xADF9, 0x54EA, 0xADFE, 0x54EB, 0xD0FB, 0x54ED, 0xADFA,
+	0x54EE, 0xADFD, 0x54F1, 0xD0FE, 0x54F2, 0xADF5, 0x54F3, 0xD0F5,
+	0x54F7, 0xD142, 0x54F8, 0xD143, 0x54FA, 0xADF7, 0x54FB, 0xD141,
+	0x54FC, 0xADF3, 0x54FD, 0xAE43, 0x54FF, 0xD0F8, 0x5501, 0xADF1,
+	0x5503, 0xD146, 0x5504, 0xD0F9, 0x5505, 0xD0FD, 0x5506, 0xADF6,
+	0x5507, 0xAE42, 0x5508, 0xD0FA, 0x5509, 0xADFC, 0x550A, 0xD140,
+	0x550B, 0xD147, 0x550C, 0xD4A1, 0x550E, 0xD145, 0x550F, 0xAE44,
+	0x5510, 0xADF0, 0x5511, 0xD0FC, 0x5512, 0xD0F3, 0x5514, 0xADF8,
+	0x5517, 0xD0F2, 0x551A, 0xD0F7, 0x5526, 0xD0F0, 0x5527, 0xAE41,
+	0x552A, 0xD477, 0x552C, 0xB0E4, 0x552D, 0xD4A7, 0x552E, 0xB0E2,
+	0x552F, 0xB0DF, 0x5530, 0xD47C, 0x5531, 0xB0DB, 0x5532, 0xD4A2,
+	0x5533, 0xB0E6, 0x5534, 0xD476, 0x5535, 0xD47B, 0x5536, 0xD47A,
+	0x5537, 0xADF2, 0x5538, 0xB0E1, 0x5539, 0xD4A5, 0x553B, 0xD4A8,
+	0x553C, 0xD473, 0x553E, 0xB3E8, 0x5540, 0xD4A9, 0x5541, 0xB0E7,
+	0x5543, 0xB0D9, 0x5544, 0xB0D6, 0x5545, 0xD47E, 0x5546, 0xB0D3,
+	0x5548, 0xD4A6, 0x554A, 0xB0DA, 0x554B, 0xD4AA, 0x554D, 0xD474,
+	0x554E, 0xD4A4, 0x554F, 0xB0DD, 0x5550, 0xD475, 0x5551, 0xD478,
+	0x5552, 0xD47D, 0x5555, 0xB0DE, 0x5556, 0xB0DC, 0x5557, 0xB0E8,
+	0x555C, 0xB0E3, 0x555E, 0xB0D7, 0x555F, 0xB1D2, 0x5561, 0xB0D8,
+	0x5562, 0xD479, 0x5563, 0xB0E5, 0x5564, 0xB0E0, 0x5565, 0xD4A3,
+	0x5566, 0xB0D5, 0x556A, 0xB0D4, 0x5575, 0xD471, 0x5576, 0xD472,
+	0x5577, 0xD86A, 0x557B, 0xB3D7, 0x557C, 0xB3DA, 0x557D, 0xD875,
+	0x557E, 0xB3EE, 0x557F, 0xD878, 0x5580, 0xB3D8, 0x5581, 0xD871,
+	0x5582, 0xB3DE, 0x5583, 0xB3E4, 0x5584, 0xB5BD, 0x5587, 0xB3E2,
+	0x5588, 0xD86E, 0x5589, 0xB3EF, 0x558A, 0xB3DB, 0x558B, 0xB3E3,
+	0x558C, 0xD876, 0x558D, 0xDCD7, 0x558E, 0xD87B, 0x558F, 0xD86F,
+	0x5591, 0xD866, 0x5592, 0xD873, 0x5593, 0xD86D, 0x5594, 0xB3E1,
+	0x5595, 0xD879, 0x5598, 0xB3DD, 0x5599, 0xB3F1, 0x559A, 0xB3EA,
+	0x559C, 0xB3DF, 0x559D, 0xB3DC, 0x559F, 0xB3E7, 0x55A1, 0xD87A,
+	0x55A2, 0xD86C, 0x55A3, 0xD872, 0x55A4, 0xD874, 0x55A5, 0xD868,
+	0x55A6, 0xD877, 0x55A7, 0xB3D9, 0x55A8, 0xD867, 0x55AA, 0xB3E0,
+	0x55AB, 0xB3F0, 0x55AC, 0xB3EC, 0x55AD, 0xD869, 0x55AE, 0xB3E6,
+	0x55B1, 0xB3ED, 0x55B2, 0xB3E9, 0x55B3, 0xB3E5, 0x55B5, 0xD870,
+	0x55BB, 0xB3EB, 0x55BF, 0xDCD5, 0x55C0, 0xDCD1, 0x55C2, 0xDCE0,
+	0x55C3, 0xDCCA, 0x55C4, 0xDCD3, 0x55C5, 0xB6E5, 0x55C6, 0xB6E6,
+	0x55C7, 0xB6DE, 0x55C8, 0xDCDC, 0x55C9, 0xB6E8, 0x55CA, 0xDCCF,
+	0x55CB, 0xDCCE, 0x55CC, 0xDCCC, 0x55CD, 0xDCDE, 0x55CE, 0xB6DC,
+	0x55CF, 0xDCD8, 0x55D0, 0xDCCD, 0x55D1, 0xB6DF, 0x55D2, 0xDCD6,
+	0x55D3, 0xB6DA, 0x55D4, 0xDCD2, 0x55D5, 0xDCD9, 0x55D6, 0xDCDB,
+	0x55D9, 0xDCDF, 0x55DA, 0xB6E3, 0x55DB, 0xDCCB, 0x55DC, 0xB6DD,
+	0x55DD, 0xDCD0, 0x55DF, 0xB6D8, 0x55E1, 0xB6E4, 0x55E2, 0xDCDA,
+	0x55E3, 0xB6E0, 0x55E4, 0xB6E1, 0x55E5, 0xB6E7, 0x55E6, 0xB6DB,
+	0x55E7, 0xA25F, 0x55E8, 0xB6D9, 0x55E9, 0xDCD4, 0x55EF, 0xB6E2,
+	0x55F2, 0xDCDD, 0x55F6, 0xB9CD, 0x55F7, 0xB9C8, 0x55F9, 0xE155,
+	0x55FA, 0xE151, 0x55FC, 0xE14B, 0x55FD, 0xB9C2, 0x55FE, 0xB9BE,
+	0x55FF, 0xE154, 0x5600, 0xB9BF, 0x5601, 0xE14E, 0x5602, 0xE150,
+	0x5604, 0xE153, 0x5606, 0xB9C4, 0x5608, 0xB9CB, 0x5609, 0xB9C5,
+	0x560C, 0xE149, 0x560D, 0xB9C6, 0x560E, 0xB9C7, 0x560F, 0xE14C,
+	0x5610, 0xB9CC, 0x5612, 0xE14A, 0x5613, 0xE14F, 0x5614, 0xB9C3,
+	0x5615, 0xE148, 0x5616, 0xB9C9, 0x5617, 0xB9C1, 0x561B, 0xB9C0,
+	0x561C, 0xE14D, 0x561D, 0xE152, 0x561F, 0xB9CA, 0x5627, 0xE147,
+	0x5629, 0xBC4D, 0x562A, 0xE547, 0x562C, 0xE544, 0x562E, 0xBC47,
+	0x562F, 0xBC53, 0x5630, 0xBC54, 0x5632, 0xBC4A, 0x5633, 0xE542,
+	0x5634, 0xBC4C, 0x5635, 0xE4F9, 0x5636, 0xBC52, 0x5638, 0xE546,
+	0x5639, 0xBC49, 0x563A, 0xE548, 0x563B, 0xBC48, 0x563D, 0xE543,
+	0x563E, 0xE545, 0x563F, 0xBC4B, 0x5640, 0xE541, 0x5641, 0xE4FA,
+	0x5642, 0xE4F7, 0x5645, 0xD86B, 0x5646, 0xE4FD, 0x5648, 0xE4F6,
+	0x5649, 0xE4FC, 0x564A, 0xE4FB, 0x564C, 0xE4F8, 0x564E, 0xBC4F,
+	0x5653, 0xBC4E, 0x5657, 0xBC50, 0x5658, 0xE4FE, 0x5659, 0xBEB2,
+	0x565A, 0xE540, 0x565E, 0xE945, 0x5660, 0xE8FD, 0x5662, 0xBEBE,
+	0x5663, 0xE942, 0x5664, 0xBEB6, 0x5665, 0xBEBA, 0x5666, 0xE941,
+	0x5668, 0xBEB9, 0x5669, 0xBEB5, 0x566A, 0xBEB8, 0x566B, 0xBEB3,
+	0x566C, 0xBEBD, 0x566D, 0xE943, 0x566E, 0xE8FE, 0x566F, 0xBEBC,
+	0x5670, 0xE8FC, 0x5671, 0xBEBB, 0x5672, 0xE944, 0x5673, 0xE940,
+	0x5674, 0xBC51, 0x5676, 0xBEBF, 0x5677, 0xE946, 0x5678, 0xBEB7,
+	0x5679, 0xBEB4, 0x567E, 0xECC6, 0x567F, 0xECC8, 0x5680, 0xC07B,
+	0x5681, 0xECC9, 0x5682, 0xECC7, 0x5683, 0xECC5, 0x5684, 0xECC4,
+	0x5685, 0xC07D, 0x5686, 0xECC3, 0x5687, 0xC07E, 0x568C, 0xECC1,
+	0x568D, 0xECC2, 0x568E, 0xC07A, 0x568F, 0xC0A1, 0x5690, 0xC07C,
+	0x5693, 0xECC0, 0x5695, 0xC250, 0x5697, 0xEFBC, 0x5698, 0xEFBA,
+	0x5699, 0xEFBF, 0x569A, 0xEFBD, 0x569C, 0xEFBB, 0x569D, 0xEFBE,
+	0x56A5, 0xC360, 0x56A6, 0xF1F2, 0x56A7, 0xF1F3, 0x56A8, 0xC456,
+	0x56AA, 0xF1F4, 0x56AB, 0xF1F0, 0x56AC, 0xF1F5, 0x56AD, 0xF1F1,
+	0x56AE, 0xC251, 0x56B2, 0xF3FE, 0x56B3, 0xF441, 0x56B4, 0xC459,
+	0x56B5, 0xF440, 0x56B6, 0xC458, 0x56B7, 0xC457, 0x56BC, 0xC45A,
+	0x56BD, 0xF5C5, 0x56BE, 0xF5C6, 0x56C0, 0xC4DA, 0x56C1, 0xC4D9,
+	0x56C2, 0xC4DB, 0x56C3, 0xF5C4, 0x56C5, 0xF6D8, 0x56C6, 0xF6D7,
+	0x56C8, 0xC56D, 0x56C9, 0xC56F, 0x56CA, 0xC56E, 0x56CB, 0xF6D9,
+	0x56CC, 0xC5C8, 0x56CD, 0xF8A6, 0x56D1, 0xC5F1, 0x56D3, 0xF8A5,
+	0x56D4, 0xF8EE, 0x56D7, 0xC949, 0x56DA, 0xA57D, 0x56DB, 0xA57C,
+	0x56DD, 0xA65F, 0x56DE, 0xA65E, 0x56DF, 0xC9C7, 0x56E0, 0xA65D,
+	0x56E1, 0xC9C6, 0x56E4, 0xA779, 0x56E5, 0xCAA9, 0x56E7, 0xCAA8,
+	0x56EA, 0xA777, 0x56EB, 0xA77A, 0x56EE, 0xCAA7, 0x56F0, 0xA778,
+	0x56F7, 0xCBF0, 0x56F9, 0xCBF1, 0x56FA, 0xA954, 0x56FF, 0xABAA,
+	0x5701, 0xD148, 0x5702, 0xD149, 0x5703, 0xAE45, 0x5704, 0xAE46,
+	0x5707, 0xD4AC, 0x5708, 0xB0E9, 0x5709, 0xB0EB, 0x570A, 0xD4AB,
+	0x570B, 0xB0EA, 0x570C, 0xD87C, 0x570D, 0xB3F2, 0x5712, 0xB6E9,
+	0x5713, 0xB6EA, 0x5714, 0xDCE1, 0x5716, 0xB9CF, 0x5718, 0xB9CE,
+	0x571A, 0xE549, 0x571B, 0xE948, 0x571C, 0xE947, 0x571E, 0xF96B,
+	0x571F, 0xA467, 0x5720, 0xC959, 0x5722, 0xC96E, 0x5723, 0xC96F,
+	0x5728, 0xA662, 0x5729, 0xA666, 0x572A, 0xC9C9, 0x572C, 0xA664,
+	0x572D, 0xA663, 0x572E, 0xC9C8, 0x572F, 0xA665, 0x5730, 0xA661,
+	0x5733, 0xA660, 0x5734, 0xC9CA, 0x573B, 0xA7A6, 0x573E, 0xA7A3,
+	0x5740, 0xA77D, 0x5741, 0xCAAA, 0x5745, 0xCAAB, 0x5747, 0xA7A1,
+	0x5749, 0xCAAD, 0x574A, 0xA77B, 0x574B, 0xCAAE, 0x574C, 0xCAAC,
+	0x574D, 0xA77E, 0x574E, 0xA7A2, 0x574F, 0xA7A5, 0x5750, 0xA7A4,
+	0x5751, 0xA77C, 0x5752, 0xCAAF, 0x5761, 0xA959, 0x5762, 0xCBFE,
+	0x5764, 0xA95B, 0x5766, 0xA95A, 0x5768, 0xCC40, 0x5769, 0xA958,
+	0x576A, 0xA957, 0x576B, 0xCBF5, 0x576D, 0xCBF4, 0x576F, 0xCBF2,
+	0x5770, 0xCBF7, 0x5771, 0xCBF6, 0x5772, 0xCBF3, 0x5773, 0xCBFC,
+	0x5774, 0xCBFD, 0x5775, 0xCBFA, 0x5776, 0xCBF8, 0x5777, 0xA956,
+	0x577B, 0xCBFB, 0x577C, 0xA95C, 0x577D, 0xCC41, 0x5780, 0xCBF9,
+	0x5782, 0xABAB, 0x5783, 0xA955, 0x578B, 0xABAC, 0x578C, 0xCE54,
+	0x578F, 0xCE5A, 0x5793, 0xABB2, 0x5794, 0xCE58, 0x5795, 0xCE5E,
+	0x5797, 0xCE55, 0x5798, 0xCE59, 0x5799, 0xCE5B, 0x579A, 0xCE5D,
+	0x579B, 0xCE57, 0x579D, 0xCE56, 0x579E, 0xCE51, 0x579F, 0xCE52,
+	0x57A0, 0xABAD, 0x57A2, 0xABAF, 0x57A3, 0xABAE, 0x57A4, 0xCE53,
+	0x57A5, 0xCE5C, 0x57AE, 0xABB1, 0x57B5, 0xCE50, 0x57B6, 0xD153,
+	0x57B8, 0xD152, 0x57B9, 0xD157, 0x57BA, 0xD14E, 0x57BC, 0xD151,
+	0x57BD, 0xD150, 0x57BF, 0xD154, 0x57C1, 0xD158, 0x57C2, 0xAE47,
+	0x57C3, 0xAE4A, 0x57C6, 0xD14F, 0x57C7, 0xD155, 0x57CB, 0xAE49,
+	0x57CC, 0xD14A, 0x57CE, 0xABB0, 0x57CF, 0xD4BA, 0x57D0, 0xD156,
+	0x57D2, 0xD14D, 0x57D4, 0xAE48, 0x57D5, 0xD14C, 0x57DC, 0xD4B1,
+	0x57DF, 0xB0EC, 0x57E0, 0xB0F0, 0x57E1, 0xD4C1, 0x57E2, 0xD4AF,
+	0x57E3, 0xD4BD, 0x57E4, 0xB0F1, 0x57E5, 0xD4BF, 0x57E7, 0xD4C5,
+	0x57E9, 0xD4C9, 0x57EC, 0xD4C0, 0x57ED, 0xD4B4, 0x57EE, 0xD4BC,
+	0x57F0, 0xD4CA, 0x57F1, 0xD4C8, 0x57F2, 0xD4BE, 0x57F3, 0xD4B9,
+	0x57F4, 0xD4B2, 0x57F5, 0xD8A6, 0x57F6, 0xD4B0, 0x57F7, 0xB0F5,
+	0x57F8, 0xD4B7, 0x57F9, 0xB0F6, 0x57FA, 0xB0F2, 0x57FB, 0xD4AD,
+	0x57FC, 0xD4C3, 0x57FD, 0xD4B5, 0x5800, 0xD4B3, 0x5801, 0xD4C6,
+	0x5802, 0xB0F3, 0x5804, 0xD4CC, 0x5805, 0xB0ED, 0x5806, 0xB0EF,
+	0x5807, 0xD4BB, 0x5808, 0xD4B6, 0x5809, 0xAE4B, 0x580A, 0xB0EE,
+	0x580B, 0xD4B8, 0x580C, 0xD4C7, 0x580D, 0xD4CB, 0x580E, 0xD4C2,
+	0x5810, 0xD4C4, 0x5814, 0xD4AE, 0x5819, 0xD8A1, 0x581B, 0xD8AA,
+	0x581C, 0xD8A9, 0x581D, 0xB3FA, 0x581E, 0xD8A2, 0x5820, 0xB3FB,
+	0x5821, 0xB3F9, 0x5823, 0xD8A4, 0x5824, 0xB3F6, 0x5825, 0xD8A8,
+	0x5827, 0xD8A3, 0x5828, 0xD8A5, 0x5829, 0xD87D, 0x582A, 0xB3F4,
+	0x582C, 0xD8B2, 0x582D, 0xD8B1, 0x582E, 0xD8AE, 0x582F, 0xB3F3,
+	0x5830, 0xB3F7, 0x5831, 0xB3F8, 0x5832, 0xD14B, 0x5833, 0xD8AB,
+	0x5834, 0xB3F5, 0x5835, 0xB0F4, 0x5836, 0xD8AD, 0x5837, 0xD87E,
+	0x5838, 0xD8B0, 0x5839, 0xD8AF, 0x583B, 0xD8B3, 0x583D, 0xDCEF,
+	0x583F, 0xD8AC, 0x5848, 0xD8A7, 0x5849, 0xDCE7, 0x584A, 0xB6F4,
+	0x584B, 0xB6F7, 0x584C, 0xB6F2, 0x584D, 0xDCE6, 0x584E, 0xDCEA,
+	0x584F, 0xDCE5, 0x5851, 0xB6EC, 0x5852, 0xB6F6, 0x5853, 0xDCE2,
+	0x5854, 0xB6F0, 0x5855, 0xDCE9, 0x5857, 0xB6EE, 0x5858, 0xB6ED,
+	0x5859, 0xDCEC, 0x585A, 0xB6EF, 0x585B, 0xDCEE, 0x585D, 0xDCEB,
+	0x585E, 0xB6EB, 0x5862, 0xB6F5, 0x5863, 0xDCF0, 0x5864, 0xDCE4,
+	0x5865, 0xDCED, 0x5868, 0xDCE3, 0x586B, 0xB6F1, 0x586D, 0xB6F3,
+	0x586F, 0xDCE8, 0x5871, 0xDCF1, 0x5874, 0xE15D, 0x5875, 0xB9D0,
+	0x5876, 0xE163, 0x5879, 0xB9D5, 0x587A, 0xE15F, 0x587B, 0xE166,
+	0x587C, 0xE157, 0x587D, 0xB9D7, 0x587E, 0xB9D1, 0x587F, 0xE15C,
+	0x5880, 0xBC55, 0x5881, 0xE15B, 0x5882, 0xE164, 0x5883, 0xB9D2,
+	0x5885, 0xB9D6, 0x5886, 0xE15A, 0x5887, 0xE160, 0x5888, 0xE165,
+	0x5889, 0xE156, 0x588A, 0xB9D4, 0x588B, 0xE15E, 0x588E, 0xE162,
+	0x588F, 0xE168, 0x5890, 0xE158, 0x5891, 0xE161, 0x5893, 0xB9D3,
+	0x5894, 0xE167, 0x5898, 0xE159, 0x589C, 0xBC59, 0x589D, 0xE54B,
+	0x589E, 0xBC57, 0x589F, 0xBC56, 0x58A0, 0xE54D, 0x58A1, 0xE552,
+	0x58A3, 0xE54E, 0x58A5, 0xE551, 0x58A6, 0xBC5C, 0x58A8, 0xBEA5,
+	0x58A9, 0xBC5B, 0x58AB, 0xE54A, 0x58AC, 0xE550, 0x58AE, 0xBC5A,
+	0x58AF, 0xE54F, 0x58B1, 0xE54C, 0x58B3, 0xBC58, 0x58BA, 0xE94D,
+	0x58BB, 0xF9D9, 0x58BC, 0xE94F, 0x58BD, 0xE94A, 0x58BE, 0xBEC1,
+	0x58BF, 0xE94C, 0x58C1, 0xBEC0, 0x58C2, 0xE94E, 0x58C5, 0xBEC3,
+	0x58C6, 0xE950, 0x58C7, 0xBEC2, 0x58C8, 0xE949, 0x58C9, 0xE94B,
+	0x58CE, 0xC0A5, 0x58CF, 0xECCC, 0x58D1, 0xC0A4, 0x58D2, 0xECCD,
+	0x58D3, 0xC0A3, 0x58D4, 0xECCB, 0x58D5, 0xC0A2, 0x58D6, 0xECCA,
+	0x58D8, 0xC253, 0x58D9, 0xC252, 0x58DA, 0xF1F6, 0x58DB, 0xF1F8,
+	0x58DD, 0xF1F7, 0x58DE, 0xC361, 0x58DF, 0xC362, 0x58E2, 0xC363,
+	0x58E3, 0xF442, 0x58E4, 0xC45B, 0x58E7, 0xF7D3, 0x58E8, 0xF7D2,
+	0x58E9, 0xC5F2, 0x58EB, 0xA468, 0x58EC, 0xA4D0, 0x58EF, 0xA7A7,
+	0x58F4, 0xCE5F, 0x58F9, 0xB3FC, 0x58FA, 0xB3FD, 0x58FC, 0xDCF2,
+	0x58FD, 0xB9D8, 0x58FE, 0xE169, 0x58FF, 0xE553, 0x5903, 0xC95A,
+	0x5906, 0xCAB0, 0x590C, 0xCC42, 0x590D, 0xCE60, 0x590E, 0xD159,
+	0x590F, 0xAE4C, 0x5912, 0xF1F9, 0x5914, 0xC4DC, 0x5915, 0xA469,
+	0x5916, 0xA57E, 0x5917, 0xC970, 0x5919, 0xA667, 0x591A, 0xA668,
+	0x591C, 0xA95D, 0x5920, 0xB0F7, 0x5922, 0xB9DA, 0x5924, 0xB9DB,
+	0x5925, 0xB9D9, 0x5927, 0xA46A, 0x5929, 0xA4D1, 0x592A, 0xA4D3,
+	0x592B, 0xA4D2, 0x592C, 0xC95B, 0x592D, 0xA4D4, 0x592E, 0xA5A1,
+	0x592F, 0xC971, 0x5931, 0xA5A2, 0x5937, 0xA669, 0x5938, 0xA66A,
+	0x593C, 0xC9CB, 0x593E, 0xA7A8, 0x5940, 0xCAB1, 0x5944, 0xA961,
+	0x5945, 0xCC43, 0x5947, 0xA95F, 0x5948, 0xA960, 0x5949, 0xA95E,
+	0x594A, 0xD15A, 0x594E, 0xABB6, 0x594F, 0xABB5, 0x5950, 0xABB7,
+	0x5951, 0xABB4, 0x5953, 0xCE61, 0x5954, 0xA962, 0x5955, 0xABB3,
+	0x5957, 0xAE4D, 0x5958, 0xAE4E, 0x595A, 0xAE4F, 0x595C, 0xD4CD,
+	0x5960, 0xB3FE, 0x5961, 0xD8B4, 0x5962, 0xB0F8, 0x5967, 0xB6F8,
+	0x5969, 0xB9DD, 0x596A, 0xB9DC, 0x596B, 0xE16A, 0x596D, 0xBC5D,
+	0x596E, 0xBEC4, 0x5970, 0xEFC0, 0x5971, 0xF6DA, 0x5972, 0xF7D4,
+	0x5973, 0xA46B, 0x5974, 0xA5A3, 0x5976, 0xA5A4, 0x5977, 0xC9D1,
+	0x5978, 0xA66C, 0x5979, 0xA66F, 0x597B, 0xC9CF, 0x597C, 0xC9CD,
+	0x597D, 0xA66E, 0x597E, 0xC9D0, 0x597F, 0xC9D2, 0x5980, 0xC9CC,
+	0x5981, 0xA671, 0x5982, 0xA670, 0x5983, 0xA66D, 0x5984, 0xA66B,
+	0x5985, 0xC9CE, 0x598A, 0xA7B3, 0x598D, 0xA7B0, 0x598E, 0xCAB6,
+	0x598F, 0xCAB9, 0x5990, 0xCAB8, 0x5992, 0xA7AA, 0x5993, 0xA7B2,
+	0x5996, 0xA7AF, 0x5997, 0xCAB5, 0x5998, 0xCAB3, 0x5999, 0xA7AE,
+	0x599D, 0xA7A9, 0x599E, 0xA7AC, 0x59A0, 0xCAB4, 0x59A1, 0xCABB,
+	0x59A2, 0xCAB7, 0x59A3, 0xA7AD, 0x59A4, 0xA7B1, 0x59A5, 0xA7B4,
+	0x59A6, 0xCAB2, 0x59A7, 0xCABA, 0x59A8, 0xA7AB, 0x59AE, 0xA967,
+	0x59AF, 0xA96F, 0x59B1, 0xCC4F, 0x59B2, 0xCC48, 0x59B3, 0xA970,
+	0x59B4, 0xCC53, 0x59B5, 0xCC44, 0x59B6, 0xCC4B, 0x59B9, 0xA966,
+	0x59BA, 0xCC45, 0x59BB, 0xA964, 0x59BC, 0xCC4C, 0x59BD, 0xCC50,
+	0x59BE, 0xA963, 0x59C0, 0xCC51, 0x59C1, 0xCC4A, 0x59C3, 0xCC4D,
+	0x59C5, 0xA972, 0x59C6, 0xA969, 0x59C7, 0xCC54, 0x59C8, 0xCC52,
+	0x59CA, 0xA96E, 0x59CB, 0xA96C, 0x59CC, 0xCC49, 0x59CD, 0xA96B,
+	0x59CE, 0xCC47, 0x59CF, 0xCC46, 0x59D0, 0xA96A, 0x59D1, 0xA968,
+	0x59D2, 0xA971, 0x59D3, 0xA96D, 0x59D4, 0xA965, 0x59D6, 0xCC4E,
+	0x59D8, 0xABB9, 0x59DA, 0xABC0, 0x59DB, 0xCE6F, 0x59DC, 0xABB8,
+	0x59DD, 0xCE67, 0x59DE, 0xCE63, 0x59E0, 0xCE73, 0x59E1, 0xCE62,
+	0x59E3, 0xABBB, 0x59E4, 0xCE6C, 0x59E5, 0xABBE, 0x59E6, 0xABC1,
+	0x59E8, 0xABBC, 0x59E9, 0xCE70, 0x59EA, 0xABBF, 0x59EC, 0xAE56,
+	0x59ED, 0xCE76, 0x59EE, 0xCE64, 0x59F1, 0xCE66, 0x59F2, 0xCE6D,
+	0x59F3, 0xCE71, 0x59F4, 0xCE75, 0x59F5, 0xCE72, 0x59F6, 0xCE6B,
+	0x59F7, 0xCE6E, 0x59FA, 0xCE68, 0x59FB, 0xABC3, 0x59FC, 0xCE6A,
+	0x59FD, 0xCE69, 0x59FE, 0xCE74, 0x59FF, 0xABBA, 0x5A00, 0xCE65,
+	0x5A01, 0xABC2, 0x5A03, 0xABBD, 0x5A09, 0xAE5C, 0x5A0A, 0xD162,
+	0x5A0C, 0xAE5B, 0x5A0F, 0xD160, 0x5A11, 0xAE50, 0x5A13, 0xAE55,
+	0x5A15, 0xD15F, 0x5A16, 0xD15C, 0x5A17, 0xD161, 0x5A18, 0xAE51,
+	0x5A19, 0xD15B, 0x5A1B, 0xAE54, 0x5A1C, 0xAE52, 0x5A1E, 0xD163,
+	0x5A1F, 0xAE53, 0x5A20, 0xAE57, 0x5A23, 0xAE58, 0x5A25, 0xAE5A,
+	0x5A29, 0xAE59, 0x5A2D, 0xD15D, 0x5A2E, 0xD15E, 0x5A33, 0xD164,
+	0x5A35, 0xD4D4, 0x5A36, 0xB0F9, 0x5A37, 0xD8C2, 0x5A38, 0xD4D3,
+	0x5A39, 0xD4E6, 0x5A3C, 0xB140, 0x5A3E, 0xD4E4, 0x5A40, 0xB0FE,
+	0x5A41, 0xB0FA, 0x5A42, 0xD4ED, 0x5A43, 0xD4DD, 0x5A44, 0xD4E0,
+	0x5A46, 0xB143, 0x5A47, 0xD4EA, 0x5A48, 0xD4E2, 0x5A49, 0xB0FB,
+	0x5A4A, 0xB144, 0x5A4C, 0xD4E7, 0x5A4D, 0xD4E5, 0x5A50, 0xD4D6,
+	0x5A51, 0xD4EB, 0x5A52, 0xD4DF, 0x5A53, 0xD4DA, 0x5A55, 0xD4D0,
+	0x5A56, 0xD4EC, 0x5A57, 0xD4DC, 0x5A58, 0xD4CF, 0x5A5A, 0xB142,
+	0x5A5B, 0xD4E1, 0x5A5C, 0xD4EE, 0x5A5D, 0xD4DE, 0x5A5E, 0xD4D2,
+	0x5A5F, 0xD4D7, 0x5A60, 0xD4CE, 0x5A62, 0xB141, 0x5A64, 0xD4DB,
+	0x5A65, 0xD4D8, 0x5A66, 0xB0FC, 0x5A67, 0xD4D1, 0x5A69, 0xD4E9,
+	0x5A6A, 0xB0FD, 0x5A6C, 0xD4D9, 0x5A6D, 0xD4D5, 0x5A70, 0xD4E8,
+	0x5A77, 0xB440, 0x5A78, 0xD8BB, 0x5A7A, 0xD8B8, 0x5A7B, 0xD8C9,
+	0x5A7C, 0xD8BD, 0x5A7D, 0xD8CA, 0x5A7F, 0xB442, 0x5A83, 0xD8C6,
+	0x5A84, 0xD8C3, 0x5A8A, 0xD8C4, 0x5A8B, 0xD8C7, 0x5A8C, 0xD8CB,
+	0x5A8E, 0xD4E3, 0x5A8F, 0xD8CD, 0x5A90, 0xDD47, 0x5A92, 0xB443,
+	0x5A93, 0xD8CE, 0x5A94, 0xD8B6, 0x5A95, 0xD8C0, 0x5A97, 0xD8C5,
+	0x5A9A, 0xB441, 0x5A9B, 0xB444, 0x5A9C, 0xD8CC, 0x5A9D, 0xD8CF,
+	0x5A9E, 0xD8BA, 0x5A9F, 0xD8B7, 0x5AA2, 0xD8B9, 0x5AA5, 0xD8BE,
+	0x5AA6, 0xD8BC, 0x5AA7, 0xB445, 0x5AA9, 0xD8C8, 0x5AAC, 0xD8BF,
+	0x5AAE, 0xD8C1, 0x5AAF, 0xD8B5, 0x5AB0, 0xDCFA, 0x5AB1, 0xDCF8,
+	0x5AB2, 0xB742, 0x5AB3, 0xB740, 0x5AB4, 0xDD43, 0x5AB5, 0xDCF9,
+	0x5AB6, 0xDD44, 0x5AB7, 0xDD40, 0x5AB8, 0xDCF7, 0x5AB9, 0xDD46,
+	0x5ABA, 0xDCF6, 0x5ABB, 0xDCFD, 0x5ABC, 0xB6FE, 0x5ABD, 0xB6FD,
+	0x5ABE, 0xB6FC, 0x5ABF, 0xDCFB, 0x5AC0, 0xDD41, 0x5AC1, 0xB6F9,
+	0x5AC2, 0xB741, 0x5AC4, 0xDCF4, 0x5AC6, 0xDCFE, 0x5AC7, 0xDCF3,
+	0x5AC8, 0xDCFC, 0x5AC9, 0xB6FA, 0x5ACA, 0xDD42, 0x5ACB, 0xDCF5,
+	0x5ACC, 0xB6FB, 0x5ACD, 0xDD45, 0x5AD5, 0xE16E, 0x5AD6, 0xB9E2,
+	0x5AD7, 0xB9E1, 0x5AD8, 0xB9E3, 0x5AD9, 0xE17A, 0x5ADA, 0xE170,
+	0x5ADB, 0xE176, 0x5ADC, 0xE16B, 0x5ADD, 0xE179, 0x5ADE, 0xE178,
+	0x5ADF, 0xE17C, 0x5AE0, 0xE175, 0x5AE1, 0xB9DE, 0x5AE2, 0xE174,
+	0x5AE3, 0xB9E4, 0x5AE5, 0xE16D, 0x5AE6, 0xB9DF, 0x5AE8, 0xE17B,
+	0x5AE9, 0xB9E0, 0x5AEA, 0xE16F, 0x5AEB, 0xE172, 0x5AEC, 0xE177,
+	0x5AED, 0xE171, 0x5AEE, 0xE16C, 0x5AF3, 0xE173, 0x5AF4, 0xE555,
+	0x5AF5, 0xBC61, 0x5AF6, 0xE558, 0x5AF7, 0xE557, 0x5AF8, 0xE55A,
+	0x5AF9, 0xE55C, 0x5AFA, 0xF9DC, 0x5AFB, 0xBC5F, 0x5AFD, 0xE556,
+	0x5AFF, 0xE554, 0x5B01, 0xE55D, 0x5B02, 0xE55B, 0x5B03, 0xE559,
+	0x5B05, 0xE55F, 0x5B07, 0xE55E, 0x5B08, 0xBC63, 0x5B09, 0xBC5E,
+	0x5B0B, 0xBC60, 0x5B0C, 0xBC62, 0x5B0F, 0xE560, 0x5B10, 0xE957,
+	0x5B13, 0xE956, 0x5B14, 0xE955, 0x5B16, 0xE958, 0x5B17, 0xE951,
+	0x5B19, 0xE952, 0x5B1A, 0xE95A, 0x5B1B, 0xE953, 0x5B1D, 0xBEC5,
+	0x5B1E, 0xE95C, 0x5B20, 0xE95B, 0x5B21, 0xE954, 0x5B23, 0xECD1,
+	0x5B24, 0xC0A8, 0x5B25, 0xECCF, 0x5B26, 0xECD4, 0x5B27, 0xECD3,
+	0x5B28, 0xE959, 0x5B2A, 0xC0A7, 0x5B2C, 0xECD2, 0x5B2D, 0xECCE,
+	0x5B2E, 0xECD6, 0x5B2F, 0xECD5, 0x5B30, 0xC0A6, 0x5B32, 0xECD0,
+	0x5B34, 0xBEC6, 0x5B38, 0xC254, 0x5B3C, 0xEFC1, 0x5B3D, 0xF1FA,
+	0x5B3E, 0xF1FB, 0x5B3F, 0xF1FC, 0x5B40, 0xC45C, 0x5B43, 0xC45D,
+	0x5B45, 0xF443, 0x5B47, 0xF5C8, 0x5B48, 0xF5C7, 0x5B4B, 0xF6DB,
+	0x5B4C, 0xF6DC, 0x5B4D, 0xF7D5, 0x5B4E, 0xF8A7, 0x5B50, 0xA46C,
+	0x5B51, 0xA46D, 0x5B53, 0xA46E, 0x5B54, 0xA4D5, 0x5B55, 0xA5A5,
+	0x5B56, 0xC9D3, 0x5B57, 0xA672, 0x5B58, 0xA673, 0x5B5A, 0xA7B7,
+	0x5B5B, 0xA7B8, 0x5B5C, 0xA7B6, 0x5B5D, 0xA7B5, 0x5B5F, 0xA973,
+	0x5B62, 0xCC55, 0x5B63, 0xA975, 0x5B64, 0xA974, 0x5B65, 0xCC56,
+	0x5B69, 0xABC4, 0x5B6B, 0xAE5D, 0x5B6C, 0xD165, 0x5B6E, 0xD4F0,
+	0x5B70, 0xB145, 0x5B71, 0xB447, 0x5B72, 0xD4EF, 0x5B73, 0xB446,
+	0x5B75, 0xB9E5, 0x5B77, 0xE17D, 0x5B78, 0xBEC7, 0x5B7A, 0xC0A9,
+	0x5B7B, 0xECD7, 0x5B7D, 0xC45E, 0x5B7F, 0xC570, 0x5B81, 0xC972,
+	0x5B83, 0xA5A6, 0x5B84, 0xC973, 0x5B85, 0xA676, 0x5B87, 0xA674,
+	0x5B88, 0xA675, 0x5B89, 0xA677, 0x5B8B, 0xA7BA, 0x5B8C, 0xA7B9,
+	0x5B8E, 0xCABC, 0x5B8F, 0xA7BB, 0x5B92, 0xCABD, 0x5B93, 0xCC57,
+	0x5B95, 0xCC58, 0x5B97, 0xA976, 0x5B98, 0xA978, 0x5B99, 0xA97A,
+	0x5B9A, 0xA977, 0x5B9B, 0xA97B, 0x5B9C, 0xA979, 0x5BA2, 0xABC8,
+	0x5BA3, 0xABC5, 0x5BA4, 0xABC7, 0x5BA5, 0xABC9, 0x5BA6, 0xABC6,
+	0x5BA7, 0xD166, 0x5BA8, 0xCE77, 0x5BAC, 0xD168, 0x5BAD, 0xD167,
+	0x5BAE, 0xAE63, 0x5BB0, 0xAE5F, 0x5BB3, 0xAE60, 0x5BB4, 0xAE62,
+	0x5BB5, 0xAE64, 0x5BB6, 0xAE61, 0x5BB8, 0xAE66, 0x5BB9, 0xAE65,
+	0x5BBF, 0xB14A, 0x5BC0, 0xD4F2, 0x5BC1, 0xD4F1, 0x5BC2, 0xB149,
+	0x5BC4, 0xB148, 0x5BC5, 0xB147, 0x5BC6, 0xB14B, 0x5BC7, 0xB146,
+	0x5BCA, 0xD8D5, 0x5BCB, 0xD8D2, 0x5BCC, 0xB449, 0x5BCD, 0xD8D1,
+	0x5BCE, 0xD8D6, 0x5BD0, 0xB44B, 0x5BD1, 0xD8D4, 0x5BD2, 0xB448,
+	0x5BD3, 0xB44A, 0x5BD4, 0xD8D3, 0x5BD6, 0xDD48, 0x5BD8, 0xDD49,
+	0x5BD9, 0xDD4A, 0x5BDE, 0xB9E6, 0x5BDF, 0xB9EE, 0x5BE0, 0xE17E,
+	0x5BE1, 0xB9E8, 0x5BE2, 0xB9EC, 0x5BE3, 0xE1A1, 0x5BE4, 0xB9ED,
+	0x5BE5, 0xB9E9, 0x5BE6, 0xB9EA, 0x5BE7, 0xB9E7, 0x5BE8, 0xB9EB,
+	0x5BE9, 0xBC66, 0x5BEA, 0xD8D0, 0x5BEB, 0xBC67, 0x5BEC, 0xBC65,
+	0x5BEE, 0xBC64, 0x5BEF, 0xE95D, 0x5BF0, 0xBEC8, 0x5BF1, 0xECD8,
+	0x5BF2, 0xECD9, 0x5BF5, 0xC364, 0x5BF6, 0xC45F, 0x5BF8, 0xA46F,
+	0x5BFA, 0xA678, 0x5C01, 0xABCA, 0x5C03, 0xD169, 0x5C04, 0xAE67,
+	0x5C07, 0xB14E, 0x5C08, 0xB14D, 0x5C09, 0xB14C, 0x5C0A, 0xB44C,
+	0x5C0B, 0xB44D, 0x5C0C, 0xD8D7, 0x5C0D, 0xB9EF, 0x5C0E, 0xBEC9,
+	0x5C0F, 0xA470, 0x5C10, 0xC95C, 0x5C11, 0xA4D6, 0x5C12, 0xC974,
+	0x5C15, 0xC9D4, 0x5C16, 0xA679, 0x5C1A, 0xA97C, 0x5C1F, 0xDD4B,
+	0x5C22, 0xA471, 0x5C24, 0xA4D7, 0x5C25, 0xC9D5, 0x5C28, 0xCABE,
+	0x5C2A, 0xCABF, 0x5C2C, 0xA7BC, 0x5C30, 0xD8D8, 0x5C31, 0xB44E,
+	0x5C33, 0xDD4C, 0x5C37, 0xC0AA, 0x5C38, 0xA472, 0x5C39, 0xA4A8,
+	0x5C3A, 0xA4D8, 0x5C3B, 0xC975, 0x5C3C, 0xA5A7, 0x5C3E, 0xA7C0,
+	0x5C3F, 0xA7BF, 0x5C40, 0xA7BD, 0x5C41, 0xA7BE, 0x5C44, 0xCC59,
+	0x5C45, 0xA97E, 0x5C46, 0xA9A1, 0x5C47, 0xCC5A, 0x5C48, 0xA97D,
+	0x5C4B, 0xABCE, 0x5C4C, 0xCE78, 0x5C4D, 0xABCD, 0x5C4E, 0xABCB,
+	0x5C4F, 0xABCC, 0x5C50, 0xAE6A, 0x5C51, 0xAE68, 0x5C54, 0xD16B,
+	0x5C55, 0xAE69, 0x5C56, 0xD16A, 0x5C58, 0xAE5E, 0x5C59, 0xD4F3,
+	0x5C5C, 0xB150, 0x5C5D, 0xB151, 0x5C60, 0xB14F, 0x5C62, 0xB9F0,
+	0x5C63, 0xE1A2, 0x5C64, 0xBC68, 0x5C65, 0xBC69, 0x5C67, 0xE561,
+	0x5C68, 0xC0AB, 0x5C69, 0xEFC2, 0x5C6A, 0xEFC3, 0x5C6C, 0xC4DD,
+	0x5C6D, 0xF8A8, 0x5C6E, 0xC94B, 0x5C6F, 0xA4D9, 0x5C71, 0xA473,
+	0x5C73, 0xC977, 0x5C74, 0xC976, 0x5C79, 0xA67A, 0x5C7A, 0xC9D7,
+	0x5C7B, 0xC9D8, 0x5C7C, 0xC9D6, 0x5C7E, 0xC9D9, 0x5C86, 0xCAC7,
+	0x5C88, 0xCAC2, 0x5C89, 0xCAC4, 0x5C8A, 0xCAC6, 0x5C8B, 0xCAC3,
+	0x5C8C, 0xA7C4, 0x5C8D, 0xCAC0, 0x5C8F, 0xCAC1, 0x5C90, 0xA7C1,
+	0x5C91, 0xA7C2, 0x5C92, 0xCAC5, 0x5C93, 0xCAC8, 0x5C94, 0xA7C3,
+	0x5C95, 0xCAC9, 0x5C9D, 0xCC68, 0x5C9F, 0xCC62, 0x5CA0, 0xCC5D,
+	0x5CA1, 0xA9A3, 0x5CA2, 0xCC65, 0x5CA3, 0xCC63, 0x5CA4, 0xCC5C,
+	0x5CA5, 0xCC69, 0x5CA6, 0xCC6C, 0x5CA7, 0xCC67, 0x5CA8, 0xCC60,
+	0x5CA9, 0xA9A5, 0x5CAA, 0xCC66, 0x5CAB, 0xA9A6, 0x5CAC, 0xCC61,
+	0x5CAD, 0xCC64, 0x5CAE, 0xCC5B, 0x5CAF, 0xCC5F, 0x5CB0, 0xCC6B,
+	0x5CB1, 0xA9A7, 0x5CB3, 0xA9A8, 0x5CB5, 0xCC5E, 0x5CB6, 0xCC6A,
+	0x5CB7, 0xA9A2, 0x5CB8, 0xA9A4, 0x5CC6, 0xCEAB, 0x5CC7, 0xCEA4,
+	0x5CC8, 0xCEAA, 0x5CC9, 0xCEA3, 0x5CCA, 0xCEA5, 0x5CCB, 0xCE7D,
+	0x5CCC, 0xCE7B, 0x5CCE, 0xCEAC, 0x5CCF, 0xCEA9, 0x5CD0, 0xCE79,
+	0x5CD2, 0xABD0, 0x5CD3, 0xCEA7, 0x5CD4, 0xCEA8, 0x5CD6, 0xCEA6,
+	0x5CD7, 0xCE7C, 0x5CD8, 0xCE7A, 0x5CD9, 0xABCF, 0x5CDA, 0xCEA2,
+	0x5CDB, 0xCE7E, 0x5CDE, 0xCEA1, 0x5CDF, 0xCEAD, 0x5CE8, 0xAE6F,
+	0x5CEA, 0xAE6E, 0x5CEC, 0xD16C, 0x5CED, 0xAE6B, 0x5CEE, 0xD16E,
+	0x5CF0, 0xAE70, 0x5CF1, 0xD16F, 0x5CF4, 0xAE73, 0x5CF6, 0xAE71,
+	0x5CF7, 0xD170, 0x5CF8, 0xCEAE, 0x5CF9, 0xD172, 0x5CFB, 0xAE6D,
+	0x5CFD, 0xAE6C, 0x5CFF, 0xD16D, 0x5D00, 0xD171, 0x5D01, 0xAE72,
+	0x5D06, 0xB153, 0x5D07, 0xB152, 0x5D0B, 0xD4F5, 0x5D0C, 0xD4F9,
+	0x5D0D, 0xD4FB, 0x5D0E, 0xB154, 0x5D0F, 0xD4FE, 0x5D11, 0xB158,
+	0x5D12, 0xD541, 0x5D14, 0xB15A, 0x5D16, 0xB156, 0x5D17, 0xB15E,
+	0x5D19, 0xB15B, 0x5D1A, 0xD4F7, 0x5D1B, 0xB155, 0x5D1D, 0xD4F6,
+	0x5D1E, 0xD4F4, 0x5D1F, 0xD543, 0x5D20, 0xD4F8, 0x5D22, 0xB157,
+	0x5D23, 0xD542, 0x5D24, 0xB15C, 0x5D25, 0xD4FD, 0x5D26, 0xD4FC,
+	0x5D27, 0xB15D, 0x5D28, 0xD4FA, 0x5D29, 0xB159, 0x5D2E, 0xD544,
+	0x5D30, 0xD540, 0x5D31, 0xD8E7, 0x5D32, 0xD8EE, 0x5D33, 0xD8E3,
+	0x5D34, 0xB451, 0x5D35, 0xD8DF, 0x5D36, 0xD8EF, 0x5D37, 0xD8D9,
+	0x5D38, 0xD8EC, 0x5D39, 0xD8EA, 0x5D3A, 0xD8E4, 0x5D3C, 0xD8ED,
+	0x5D3D, 0xD8E6, 0x5D3F, 0xD8DE, 0x5D40, 0xD8F0, 0x5D41, 0xD8DC,
+	0x5D42, 0xD8E9, 0x5D43, 0xD8DA, 0x5D45, 0xD8F1, 0x5D47, 0xB452,
+	0x5D49, 0xD8EB, 0x5D4A, 0xDD4F, 0x5D4B, 0xD8DD, 0x5D4C, 0xB44F,
+	0x5D4E, 0xD8E1, 0x5D50, 0xB450, 0x5D51, 0xD8E0, 0x5D52, 0xD8E5,
+	0x5D55, 0xD8E2, 0x5D59, 0xD8E8, 0x5D5E, 0xDD53, 0x5D62, 0xDD56,
+	0x5D63, 0xDD4E, 0x5D65, 0xDD50, 0x5D67, 0xDD55, 0x5D68, 0xDD54,
+	0x5D69, 0xB743, 0x5D6B, 0xD8DB, 0x5D6C, 0xDD52, 0x5D6F, 0xB744,
+	0x5D71, 0xDD4D, 0x5D72, 0xDD51, 0x5D77, 0xE1A9, 0x5D79, 0xE1B0,
+	0x5D7A, 0xE1A7, 0x5D7C, 0xE1AE, 0x5D7D, 0xE1A5, 0x5D7E, 0xE1AD,
+	0x5D7F, 0xE1B1, 0x5D80, 0xE1A4, 0x5D81, 0xE1A8, 0x5D82, 0xE1A3,
+	0x5D84, 0xB9F1, 0x5D86, 0xE1A6, 0x5D87, 0xB9F2, 0x5D88, 0xE1AC,
+	0x5D89, 0xE1AB, 0x5D8A, 0xE1AA, 0x5D8D, 0xE1AF, 0x5D92, 0xE565,
+	0x5D93, 0xE567, 0x5D94, 0xBC6B, 0x5D95, 0xE568, 0x5D97, 0xE563,
+	0x5D99, 0xE562, 0x5D9A, 0xE56C, 0x5D9C, 0xE56A, 0x5D9D, 0xBC6A,
+	0x5D9E, 0xE56D, 0x5D9F, 0xE564, 0x5DA0, 0xE569, 0x5DA1, 0xE56B,
+	0x5DA2, 0xE566, 0x5DA7, 0xE961, 0x5DA8, 0xE966, 0x5DA9, 0xE960,
+	0x5DAA, 0xE965, 0x5DAC, 0xE95E, 0x5DAD, 0xE968, 0x5DAE, 0xE964,
+	0x5DAF, 0xE969, 0x5DB0, 0xE963, 0x5DB1, 0xE95F, 0x5DB2, 0xE967,
+	0x5DB4, 0xE96A, 0x5DB5, 0xE962, 0x5DB7, 0xECDA, 0x5DB8, 0xC0AF,
+	0x5DBA, 0xC0AD, 0x5DBC, 0xC0AC, 0x5DBD, 0xC0AE, 0x5DC0, 0xEFC4,
+	0x5DC2, 0xF172, 0x5DC3, 0xF1FD, 0x5DC6, 0xF444, 0x5DC7, 0xF445,
+	0x5DC9, 0xC460, 0x5DCB, 0xF5C9, 0x5DCD, 0xC4DE, 0x5DCF, 0xF5CA,
+	0x5DD1, 0xF6DE, 0x5DD2, 0xC572, 0x5DD4, 0xC571, 0x5DD5, 0xF6DD,
+	0x5DD6, 0xC5C9, 0x5DD8, 0xF7D6, 0x5DDD, 0xA474, 0x5DDE, 0xA67B,
+	0x5DDF, 0xC9DA, 0x5DE0, 0xCACA, 0x5DE1, 0xA8B5, 0x5DE2, 0xB15F,
+	0x5DE5, 0xA475, 0x5DE6, 0xA5AA, 0x5DE7, 0xA5A9, 0x5DE8, 0xA5A8,
+	0x5DEB, 0xA7C5, 0x5DEE, 0xAE74, 0x5DF0, 0xDD57, 0x5DF1, 0xA476,
+	0x5DF2, 0xA477, 0x5DF3, 0xA478, 0x5DF4, 0xA4DA, 0x5DF7, 0xABD1,
+	0x5DF9, 0xCEAF, 0x5DFD, 0xB453, 0x5DFE, 0xA479, 0x5DFF, 0xC95D,
+	0x5E02, 0xA5AB, 0x5E03, 0xA5AC, 0x5E04, 0xC978, 0x5E06, 0xA67C,
+	0x5E0A, 0xCACB, 0x5E0C, 0xA7C6, 0x5E0E, 0xCACC, 0x5E11, 0xA9AE,
+	0x5E14, 0xCC6E, 0x5E15, 0xA9AC, 0x5E16, 0xA9AB, 0x5E17, 0xCC6D,
+	0x5E18, 0xA9A9, 0x5E19, 0xCC6F, 0x5E1A, 0xA9AA, 0x5E1B, 0xA9AD,
+	0x5E1D, 0xABD2, 0x5E1F, 0xABD4, 0x5E20, 0xCEB3, 0x5E21, 0xCEB0,
+	0x5E22, 0xCEB1, 0x5E23, 0xCEB2, 0x5E24, 0xCEB4, 0x5E25, 0xABD3,
+	0x5E28, 0xD174, 0x5E29, 0xD173, 0x5E2B, 0xAE76, 0x5E2D, 0xAE75,
+	0x5E33, 0xB162, 0x5E34, 0xD546, 0x5E36, 0xB161, 0x5E37, 0xB163,
+	0x5E38, 0xB160, 0x5E3D, 0xB455, 0x5E3E, 0xD545, 0x5E40, 0xB456,
+	0x5E41, 0xD8F3, 0x5E43, 0xB457, 0x5E44, 0xD8F2, 0x5E45, 0xB454,
+	0x5E4A, 0xDD5A, 0x5E4B, 0xDD5C, 0x5E4C, 0xB745, 0x5E4D, 0xDD5B,
+	0x5E4E, 0xDD59, 0x5E4F, 0xDD58, 0x5E53, 0xE1B4, 0x5E54, 0xB9F7,
+	0x5E55, 0xB9F5, 0x5E57, 0xB9F6, 0x5E58, 0xE1B2, 0x5E59, 0xE1B3,
+	0x5E5B, 0xB9F3, 0x5E5C, 0xE571, 0x5E5D, 0xE56F, 0x5E5F, 0xBC6D,
+	0x5E60, 0xE570, 0x5E61, 0xBC6E, 0x5E62, 0xBC6C, 0x5E63, 0xB9F4,
+	0x5E66, 0xE96D, 0x5E67, 0xE96B, 0x5E68, 0xE96C, 0x5E69, 0xE56E,
+	0x5E6A, 0xECDC, 0x5E6B, 0xC0B0, 0x5E6C, 0xECDB, 0x5E6D, 0xEFC5,
+	0x5E6E, 0xEFC6, 0x5E6F, 0xE96E, 0x5E70, 0xF1FE, 0x5E72, 0xA47A,
+	0x5E73, 0xA5AD, 0x5E74, 0xA67E, 0x5E75, 0xC9DB, 0x5E76, 0xA67D,
+	0x5E78, 0xA9AF, 0x5E79, 0xB746, 0x5E7B, 0xA4DB, 0x5E7C, 0xA5AE,
+	0x5E7D, 0xABD5, 0x5E7E, 0xB458, 0x5E80, 0xC979, 0x5E82, 0xC97A,
+	0x5E84, 0xC9DC, 0x5E87, 0xA7C8, 0x5E88, 0xCAD0, 0x5E89, 0xCACE,
+	0x5E8A, 0xA7C9, 0x5E8B, 0xCACD, 0x5E8C, 0xCACF, 0x5E8D, 0xCAD1,
+	0x5E8F, 0xA7C7, 0x5E95, 0xA9B3, 0x5E96, 0xA9B4, 0x5E97, 0xA9B1,
+	0x5E9A, 0xA9B0, 0x5E9B, 0xCEB8, 0x5E9C, 0xA9B2, 0x5EA0, 0xABD6,
+	0x5EA2, 0xCEB7, 0x5EA3, 0xCEB9, 0x5EA4, 0xCEB6, 0x5EA5, 0xCEBA,
+	0x5EA6, 0xABD7, 0x5EA7, 0xAE79, 0x5EA8, 0xD175, 0x5EAA, 0xD177,
+	0x5EAB, 0xAE77, 0x5EAC, 0xD178, 0x5EAD, 0xAE78, 0x5EAE, 0xD176,
+	0x5EB0, 0xCEB5, 0x5EB1, 0xD547, 0x5EB2, 0xD54A, 0x5EB3, 0xD54B,
+	0x5EB4, 0xD548, 0x5EB5, 0xB167, 0x5EB6, 0xB166, 0x5EB7, 0xB164,
+	0x5EB8, 0xB165, 0x5EB9, 0xD549, 0x5EBE, 0xB168, 0x5EC1, 0xB45A,
+	0x5EC2, 0xB45B, 0x5EC4, 0xB45C, 0x5EC5, 0xDD5D, 0x5EC6, 0xDD5F,
+	0x5EC7, 0xDD61, 0x5EC8, 0xB748, 0x5EC9, 0xB747, 0x5ECA, 0xB459,
+	0x5ECB, 0xDD60, 0x5ECC, 0xDD5E, 0x5ECE, 0xE1B8, 0x5ED1, 0xE1B6,
+	0x5ED2, 0xE1BC, 0x5ED3, 0xB9F8, 0x5ED4, 0xE1BD, 0x5ED5, 0xE1BA,
+	0x5ED6, 0xB9F9, 0x5ED7, 0xE1B7, 0x5ED8, 0xE1B5, 0x5ED9, 0xE1BB,
+	0x5EDA, 0xBC70, 0x5EDB, 0xE573, 0x5EDC, 0xE1B9, 0x5EDD, 0xBC72,
+	0x5EDE, 0xE574, 0x5EDF, 0xBC71, 0x5EE0, 0xBC74, 0x5EE1, 0xE575,
+	0x5EE2, 0xBC6F, 0x5EE3, 0xBC73, 0x5EE5, 0xE973, 0x5EE6, 0xE971,
+	0x5EE7, 0xE970, 0x5EE8, 0xE972, 0x5EE9, 0xE96F, 0x5EEC, 0xC366,
+	0x5EEE, 0xF446, 0x5EEF, 0xF447, 0x5EF1, 0xF5CB, 0x5EF2, 0xF6DF,
+	0x5EF3, 0xC655, 0x5EF6, 0xA9B5, 0x5EF7, 0xA7CA, 0x5EFA, 0xABD8,
+	0x5EFE, 0xA47B, 0x5EFF, 0xA4DC, 0x5F01, 0xA5AF, 0x5F02, 0xC9DD,
+	0x5F04, 0xA7CB, 0x5F05, 0xCAD2, 0x5F07, 0xCEBB, 0x5F08, 0xABD9,
+	0x5F0A, 0xB9FA, 0x5F0B, 0xA47C, 0x5F0F, 0xA6A1, 0x5F12, 0xB749,
+	0x5F13, 0xA47D, 0x5F14, 0xA4DD, 0x5F15, 0xA4DE, 0x5F17, 0xA5B1,
+	0x5F18, 0xA5B0, 0x5F1A, 0xC9DE, 0x5F1B, 0xA6A2, 0x5F1D, 0xCAD3,
+	0x5F1F, 0xA7CC, 0x5F22, 0xCC71, 0x5F23, 0xCC72, 0x5F24, 0xCC73,
+	0x5F26, 0xA9B6, 0x5F27, 0xA9B7, 0x5F28, 0xCC70, 0x5F29, 0xA9B8,
+	0x5F2D, 0xABDA, 0x5F2E, 0xCEBC, 0x5F30, 0xD17A, 0x5F31, 0xAE7A,
+	0x5F33, 0xD179, 0x5F35, 0xB169, 0x5F36, 0xD54C, 0x5F37, 0xB16A,
+	0x5F38, 0xD54D, 0x5F3C, 0xB45D, 0x5F40, 0xDD62, 0x5F43, 0xE1BF,
+	0x5F44, 0xE1BE, 0x5F46, 0xB9FB, 0x5F48, 0xBC75, 0x5F49, 0xE576,
+	0x5F4A, 0xBECA, 0x5F4B, 0xE974, 0x5F4C, 0xC0B1, 0x5F4E, 0xC573,
+	0x5F4F, 0xF7D8, 0x5F54, 0xCC74, 0x5F56, 0xCEBD, 0x5F57, 0xB16B,
+	0x5F58, 0xD8F4, 0x5F59, 0xB74A, 0x5F5D, 0xC255, 0x5F62, 0xA7CE,
+	0x5F64, 0xA7CD, 0x5F65, 0xABDB, 0x5F67, 0xD17B, 0x5F69, 0xB16D,
+	0x5F6A, 0xB343, 0x5F6B, 0xB16E, 0x5F6C, 0xB16C, 0x5F6D, 0xB45E,
+	0x5F6F, 0xE1C0, 0x5F70, 0xB9FC, 0x5F71, 0xBC76, 0x5F73, 0xC94C,
+	0x5F74, 0xC9DF, 0x5F76, 0xCAD5, 0x5F77, 0xA7CF, 0x5F78, 0xCAD4,
+	0x5F79, 0xA7D0, 0x5F7C, 0xA9BC, 0x5F7D, 0xCC77, 0x5F7E, 0xCC76,
+	0x5F7F, 0xA9BB, 0x5F80, 0xA9B9, 0x5F81, 0xA9BA, 0x5F82, 0xCC75,
+	0x5F85, 0xABDD, 0x5F86, 0xCEBE, 0x5F87, 0xABE0, 0x5F88, 0xABDC,
+	0x5F89, 0xABE2, 0x5F8A, 0xABDE, 0x5F8B, 0xABDF, 0x5F8C, 0xABE1,
+	0x5F90, 0xAE7D, 0x5F91, 0xAE7C, 0x5F92, 0xAE7B, 0x5F96, 0xD54F,
+	0x5F97, 0xB16F, 0x5F98, 0xB172, 0x5F99, 0xB170, 0x5F9B, 0xD54E,
+	0x5F9C, 0xB175, 0x5F9E, 0xB171, 0x5F9F, 0xD550, 0x5FA0, 0xB174,
+	0x5FA1, 0xB173, 0x5FA5, 0xD8F6, 0x5FA6, 0xD8F5, 0x5FA8, 0xB461,
+	0x5FA9, 0xB45F, 0x5FAA, 0xB460, 0x5FAB, 0xD8F7, 0x5FAC, 0xB74B,
+	0x5FAD, 0xDD64, 0x5FAE, 0xB74C, 0x5FAF, 0xDD63, 0x5FB2, 0xE577,
+	0x5FB5, 0xBC78, 0x5FB6, 0xE1C1, 0x5FB7, 0xBC77, 0x5FB9, 0xB9FD,
+	0x5FBB, 0xECDE, 0x5FBC, 0xE975, 0x5FBD, 0xC0B2, 0x5FBE, 0xECDD,
+	0x5FBF, 0xF240, 0x5FC0, 0xF448, 0x5FC1, 0xF449, 0x5FC3, 0xA4DF,
+	0x5FC5, 0xA5B2, 0x5FC9, 0xC97B, 0x5FCC, 0xA7D2, 0x5FCD, 0xA7D4,
+	0x5FCF, 0xC9E2, 0x5FD0, 0xCAD8, 0x5FD1, 0xCAD7, 0x5FD2, 0xCAD6,
+	0x5FD4, 0xC9E1, 0x5FD5, 0xC9E0, 0x5FD6, 0xA6A4, 0x5FD7, 0xA7D3,
+	0x5FD8, 0xA7D1, 0x5FD9, 0xA6A3, 0x5FDD, 0xA9BD, 0x5FDE, 0xCC78,
+	0x5FE0, 0xA9BE, 0x5FE1, 0xCADD, 0x5FE3, 0xCADF, 0x5FE4, 0xCADE,
+	0x5FE5, 0xCC79, 0x5FE8, 0xCADA, 0x5FEA, 0xA7D8, 0x5FEB, 0xA7D6,
+	0x5FED, 0xCAD9, 0x5FEE, 0xCADB, 0x5FEF, 0xCAE1, 0x5FF1, 0xA7D5,
+	0x5FF3, 0xCADC, 0x5FF4, 0xCAE5, 0x5FF5, 0xA9C0, 0x5FF7, 0xCAE2,
+	0x5FF8, 0xA7D7, 0x5FFA, 0xCAE0, 0x5FFB, 0xCAE3, 0x5FFD, 0xA9BF,
+	0x5FFF, 0xA9C1, 0x6000, 0xCAE4, 0x6009, 0xCCAF, 0x600A, 0xCCA2,
+	0x600B, 0xCC7E, 0x600C, 0xCCAE, 0x600D, 0xCCA9, 0x600E, 0xABE7,
+	0x600F, 0xA9C2, 0x6010, 0xCCAA, 0x6011, 0xCCAD, 0x6012, 0xABE3,
+	0x6013, 0xCCAC, 0x6014, 0xA9C3, 0x6015, 0xA9C8, 0x6016, 0xA9C6,
+	0x6017, 0xCCA3, 0x6019, 0xCC7C, 0x601A, 0xCCA5, 0x601B, 0xA9CD,
+	0x601C, 0xCCB0, 0x601D, 0xABE4, 0x601E, 0xCCA6, 0x6020, 0xABE5,
+	0x6021, 0xA9C9, 0x6022, 0xCCA8, 0x6024, 0xCECD, 0x6025, 0xABE6,
+	0x6026, 0xCC7B, 0x6027, 0xA9CA, 0x6028, 0xABE8, 0x6029, 0xA9CB,
+	0x602A, 0xA9C7, 0x602B, 0xA9CC, 0x602C, 0xCCA7, 0x602D, 0xCC7A,
+	0x602E, 0xCCAB, 0x602F, 0xA9C4, 0x6032, 0xCC7D, 0x6033, 0xCCA4,
+	0x6034, 0xCCA1, 0x6035, 0xA9C5, 0x6037, 0xCEBF, 0x6039, 0xCEC0,
+	0x6040, 0xCECA, 0x6041, 0xD1A1, 0x6042, 0xCECB, 0x6043, 0xABEE,
+	0x6044, 0xCECE, 0x6045, 0xCEC4, 0x6046, 0xABED, 0x6047, 0xCEC6,
+	0x6049, 0xCEC7, 0x604C, 0xCEC9, 0x604D, 0xABE9, 0x6050, 0xAEA3,
+	0x6052, 0xF9DA, 0x6053, 0xCEC5, 0x6054, 0xCEC1, 0x6055, 0xAEA4,
+	0x6058, 0xCECF, 0x6059, 0xAE7E, 0x605A, 0xD17D, 0x605B, 0xCEC8,
+	0x605D, 0xD17C, 0x605E, 0xCEC3, 0x605F, 0xCECC, 0x6062, 0xABEC,
+	0x6063, 0xAEA1, 0x6064, 0xABF2, 0x6065, 0xAEA2, 0x6066, 0xCED0,
+	0x6067, 0xD17E, 0x6068, 0xABEB, 0x6069, 0xAEA6, 0x606A, 0xABF1,
+	0x606B, 0xABF0, 0x606C, 0xABEF, 0x606D, 0xAEA5, 0x606E, 0xCED1,
+	0x606F, 0xAEA7, 0x6070, 0xABEA, 0x6072, 0xCEC2, 0x607F, 0xB176,
+	0x6080, 0xD1A4, 0x6081, 0xD1A6, 0x6083, 0xD1A8, 0x6084, 0xAEA8,
+	0x6085, 0xAEAE, 0x6086, 0xD553, 0x6087, 0xD1AC, 0x6088, 0xD1A3,
+	0x6089, 0xB178, 0x608A, 0xD551, 0x608C, 0xAEAD, 0x608D, 0xAEAB,
+	0x608E, 0xD1AE, 0x6090, 0xD552, 0x6092, 0xD1A5, 0x6094, 0xAEAC,
+	0x6095, 0xD1A9, 0x6096, 0xAEAF, 0x6097, 0xD1AB, 0x609A, 0xAEAA,
+	0x609B, 0xD1AA, 0x609C, 0xD1AD, 0x609D, 0xD1A7, 0x609F, 0xAEA9,
+	0x60A0, 0xB179, 0x60A2, 0xD1A2, 0x60A3, 0xB177, 0x60A8, 0xB17A,
+	0x60B0, 0xD555, 0x60B1, 0xD55E, 0x60B2, 0xB464, 0x60B4, 0xB17C,
+	0x60B5, 0xB1A3, 0x60B6, 0xB465, 0x60B7, 0xD560, 0x60B8, 0xB1AA,
+	0x60B9, 0xD8F9, 0x60BA, 0xD556, 0x60BB, 0xB1A2, 0x60BC, 0xB1A5,
+	0x60BD, 0xB17E, 0x60BE, 0xD554, 0x60BF, 0xD562, 0x60C0, 0xD565,
+	0x60C1, 0xD949, 0x60C3, 0xD563, 0x60C4, 0xD8FD, 0x60C5, 0xB1A1,
+	0x60C6, 0xB1A8, 0x60C7, 0xB1AC, 0x60C8, 0xD55D, 0x60C9, 0xD8F8,
+	0x60CA, 0xD561, 0x60CB, 0xB17B, 0x60CC, 0xD8FA, 0x60CD, 0xD564,
+	0x60CE, 0xD8FC, 0x60CF, 0xD559, 0x60D1, 0xB462, 0x60D3, 0xD557,
+	0x60D4, 0xD558, 0x60D5, 0xB1A7, 0x60D8, 0xB1A6, 0x60D9, 0xD55B,
+	0x60DA, 0xB1AB, 0x60DB, 0xD55F, 0x60DC, 0xB1A4, 0x60DD, 0xD55C,
+	0x60DF, 0xB1A9, 0x60E0, 0xB466, 0x60E1, 0xB463, 0x60E2, 0xD8FB,
+	0x60E4, 0xD55A, 0x60E6, 0xB17D, 0x60F0, 0xB46B, 0x60F1, 0xB46F,
+	0x60F2, 0xD940, 0x60F3, 0xB751, 0x60F4, 0xB46D, 0x60F5, 0xD944,
+	0x60F6, 0xB471, 0x60F7, 0xDD65, 0x60F8, 0xD946, 0x60F9, 0xB753,
+	0x60FA, 0xB469, 0x60FB, 0xB46C, 0x60FC, 0xD947, 0x60FE, 0xD948,
+	0x60FF, 0xD94E, 0x6100, 0xB473, 0x6101, 0xB754, 0x6103, 0xD94A,
+	0x6104, 0xD94F, 0x6105, 0xD943, 0x6106, 0xB75E, 0x6108, 0xB755,
+	0x6109, 0xB472, 0x610A, 0xD941, 0x610B, 0xD950, 0x610D, 0xB75D,
+	0x610E, 0xB470, 0x610F, 0xB74E, 0x6110, 0xD94D, 0x6112, 0xB474,
+	0x6113, 0xD945, 0x6114, 0xD8FE, 0x6115, 0xB46A, 0x6116, 0xD942,
+	0x6118, 0xD94B, 0x611A, 0xB74D, 0x611B, 0xB752, 0x611C, 0xB467,
+	0x611D, 0xD94C, 0x611F, 0xB750, 0x6123, 0xB468, 0x6127, 0xB75C,
+	0x6128, 0xE1C3, 0x6129, 0xDD70, 0x612B, 0xDD68, 0x612C, 0xE1C2,
+	0x612E, 0xDD6C, 0x612F, 0xDD6E, 0x6132, 0xDD6B, 0x6134, 0xB75B,
+	0x6136, 0xDD6A, 0x6137, 0xB75F, 0x613B, 0xE1D2, 0x613E, 0xB75A,
+	0x613F, 0xBA40, 0x6140, 0xDD71, 0x6141, 0xE1C4, 0x6144, 0xB758,
+	0x6145, 0xDD69, 0x6146, 0xDD6D, 0x6147, 0xB9FE, 0x6148, 0xB74F,
+	0x6149, 0xDD66, 0x614A, 0xDD67, 0x614B, 0xBA41, 0x614C, 0xB757,
+	0x614D, 0xB759, 0x614E, 0xB756, 0x614F, 0xDD6F, 0x6152, 0xE1C8,
+	0x6153, 0xE1C9, 0x6154, 0xE1CE, 0x6155, 0xBC7D, 0x6156, 0xE1D5,
+	0x6158, 0xBA47, 0x615A, 0xBA46, 0x615B, 0xE1D0, 0x615D, 0xBC7C,
+	0x615E, 0xE1C5, 0x615F, 0xBA45, 0x6161, 0xE1D4, 0x6162, 0xBA43,
+	0x6163, 0xBA44, 0x6165, 0xE1D1, 0x6166, 0xE5AA, 0x6167, 0xBC7A,
+	0x6168, 0xB46E, 0x616A, 0xE1D3, 0x616B, 0xBCA3, 0x616C, 0xE1CB,
+	0x616E, 0xBC7B, 0x6170, 0xBCA2, 0x6171, 0xE1C6, 0x6172, 0xE1CA,
+	0x6173, 0xE1C7, 0x6174, 0xE1CD, 0x6175, 0xBA48, 0x6176, 0xBC79,
+	0x6177, 0xBA42, 0x6179, 0xE57A, 0x617A, 0xE1CF, 0x617C, 0xBCA1,
+	0x617E, 0xBCA4, 0x6180, 0xE1CC, 0x6182, 0xBC7E, 0x6183, 0xE579,
+	0x6189, 0xE57E, 0x618A, 0xBECE, 0x618B, 0xE578, 0x618C, 0xE9A3,
+	0x618D, 0xE5A9, 0x618E, 0xBCA8, 0x6190, 0xBCA6, 0x6191, 0xBECC,
+	0x6192, 0xE5A6, 0x6193, 0xE5A2, 0x6194, 0xBCAC, 0x6196, 0xE978,
+	0x619A, 0xBCAA, 0x619B, 0xE5A1, 0x619D, 0xE976, 0x619F, 0xE5A5,
+	0x61A1, 0xE5A8, 0x61A2, 0xE57D, 0x61A4, 0xBCAB, 0x61A7, 0xBCA5,
+	0x61A8, 0xE977, 0x61A9, 0xBECD, 0x61AA, 0xE5A7, 0x61AB, 0xBCA7,
+	0x61AC, 0xBCA9, 0x61AD, 0xE5A4, 0x61AE, 0xBCAD, 0x61AF, 0xE5A3,
+	0x61B0, 0xE57C, 0x61B1, 0xE57B, 0x61B2, 0xBECB, 0x61B3, 0xE5AB,
+	0x61B4, 0xE97A, 0x61B5, 0xECE0, 0x61B6, 0xBED0, 0x61B8, 0xE9A2,
+	0x61BA, 0xE97E, 0x61BC, 0xECE1, 0x61BE, 0xBED1, 0x61BF, 0xE9A1,
+	0x61C1, 0xE97C, 0x61C2, 0xC0B4, 0x61C3, 0xECDF, 0x61C5, 0xE979,
+	0x61C6, 0xE97B, 0x61C7, 0xC0B5, 0x61C8, 0xBED3, 0x61C9, 0xC0B3,
+	0x61CA, 0xBED2, 0x61CB, 0xC0B7, 0x61CC, 0xE97D, 0x61CD, 0xBECF,
+	0x61D6, 0xEFCF, 0x61D8, 0xEFC7, 0x61DE, 0xECE7, 0x61DF, 0xEFC8,
+	0x61E0, 0xECE3, 0x61E3, 0xC256, 0x61E4, 0xECE5, 0x61E5, 0xECE4,
+	0x61E6, 0xC0B6, 0x61E7, 0xECE2, 0x61E8, 0xECE6, 0x61E9, 0xEFD0,
+	0x61EA, 0xEFCC, 0x61EB, 0xEFCE, 0x61ED, 0xEFC9, 0x61EE, 0xEFCA,
+	0x61F0, 0xEFCD, 0x61F1, 0xEFCB, 0x61F2, 0xC367, 0x61F5, 0xC36A,
+	0x61F6, 0xC369, 0x61F7, 0xC368, 0x61F8, 0xC461, 0x61F9, 0xF44A,
+	0x61FA, 0xC462, 0x61FB, 0xF241, 0x61FC, 0xC4DF, 0x61FD, 0xF5CC,
+	0x61FE, 0xC4E0, 0x61FF, 0xC574, 0x6200, 0xC5CA, 0x6201, 0xF7D9,
+	0x6203, 0xF7DA, 0x6204, 0xF7DB, 0x6207, 0xF9BA, 0x6208, 0xA4E0,
+	0x6209, 0xC97C, 0x620A, 0xA5B3, 0x620C, 0xA6A6, 0x620D, 0xA6A7,
+	0x620E, 0xA6A5, 0x6210, 0xA6A8, 0x6211, 0xA7DA, 0x6212, 0xA7D9,
+	0x6214, 0xCCB1, 0x6215, 0xA9CF, 0x6216, 0xA9CE, 0x6219, 0xD1AF,
+	0x621A, 0xB1AD, 0x621B, 0xB1AE, 0x621F, 0xB475, 0x6220, 0xDD72,
+	0x6221, 0xB760, 0x6222, 0xB761, 0x6223, 0xDD74, 0x6224, 0xDD76,
+	0x6225, 0xDD75, 0x6227, 0xE1D7, 0x6229, 0xE1D6, 0x622A, 0xBA49,
+	0x622B, 0xE1D8, 0x622D, 0xE5AC, 0x622E, 0xBCAE, 0x6230, 0xBED4,
+	0x6232, 0xC0B8, 0x6233, 0xC257, 0x6234, 0xC0B9, 0x6236, 0xA4E1,
+	0x623A, 0xCAE6, 0x623D, 0xCCB2, 0x623E, 0xA9D1, 0x623F, 0xA9D0,
+	0x6240, 0xA9D2, 0x6241, 0xABF3, 0x6242, 0xCED2, 0x6243, 0xCED3,
+	0x6246, 0xD1B0, 0x6247, 0xAEB0, 0x6248, 0xB1AF, 0x6249, 0xB476,
+	0x624A, 0xD951, 0x624B, 0xA4E2, 0x624D, 0xA47E, 0x624E, 0xA4E3,
+	0x6250, 0xC97D, 0x6251, 0xA5B7, 0x6252, 0xA5B6, 0x6253, 0xA5B4,
+	0x6254, 0xA5B5, 0x6258, 0xA6AB, 0x6259, 0xC9E9, 0x625A, 0xC9EB,
+	0x625B, 0xA6AA, 0x625C, 0xC9E3, 0x625E, 0xC9E4, 0x6260, 0xC9EA,
+	0x6261, 0xC9E6, 0x6262, 0xC9E8, 0x6263, 0xA6A9, 0x6264, 0xC9E5,
+	0x6265, 0xC9EC, 0x6266, 0xC9E7, 0x626D, 0xA7E1, 0x626E, 0xA7EA,
+	0x626F, 0xA7E8, 0x6270, 0xCAF0, 0x6271, 0xCAED, 0x6272, 0xCAF5,
+	0x6273, 0xA7E6, 0x6274, 0xCAF6, 0x6276, 0xA7DF, 0x6277, 0xCAF3,
+	0x6279, 0xA7E5, 0x627A, 0xCAEF, 0x627B, 0xCAEE, 0x627C, 0xA7E3,
+	0x627D, 0xCAF4, 0x627E, 0xA7E4, 0x627F, 0xA9D3, 0x6280, 0xA7DE,
+	0x6281, 0xCAF1, 0x6283, 0xCAE7, 0x6284, 0xA7DB, 0x6286, 0xA7EE,
+	0x6287, 0xCAEC, 0x6288, 0xCAF2, 0x6289, 0xA7E0, 0x628A, 0xA7E2,
+	0x628C, 0xCAE8, 0x628E, 0xCAE9, 0x628F, 0xCAEA, 0x6291, 0xA7ED,
+	0x6292, 0xA7E7, 0x6293, 0xA7EC, 0x6294, 0xCAEB, 0x6295, 0xA7EB,
+	0x6296, 0xA7DD, 0x6297, 0xA7DC, 0x6298, 0xA7E9, 0x62A8, 0xA9E1,
+	0x62A9, 0xCCBE, 0x62AA, 0xCCB7, 0x62AB, 0xA9DC, 0x62AC, 0xA9EF,
+	0x62AD, 0xCCB3, 0x62AE, 0xCCBA, 0x62AF, 0xCCBC, 0x62B0, 0xCCBF,
+	0x62B1, 0xA9EA, 0x62B3, 0xCCBB, 0x62B4, 0xCCB4, 0x62B5, 0xA9E8,
+	0x62B6, 0xCCB8, 0x62B8, 0xCCC0, 0x62B9, 0xA9D9, 0x62BB, 0xCCBD,
+	0x62BC, 0xA9E3, 0x62BD, 0xA9E2, 0x62BE, 0xCCB6, 0x62BF, 0xA9D7,
+	0x62C2, 0xA9D8, 0x62C4, 0xA9D6, 0x62C6, 0xA9EE, 0x62C7, 0xA9E6,
+	0x62C8, 0xA9E0, 0x62C9, 0xA9D4, 0x62CA, 0xCCB9, 0x62CB, 0xA9DF,
+	0x62CC, 0xA9D5, 0x62CD, 0xA9E7, 0x62CE, 0xA9F0, 0x62CF, 0xCED4,
+	0x62D0, 0xA9E4, 0x62D1, 0xCCB5, 0x62D2, 0xA9DA, 0x62D3, 0xA9DD,
+	0x62D4, 0xA9DE, 0x62D6, 0xA9EC, 0x62D7, 0xA9ED, 0x62D8, 0xA9EB,
+	0x62D9, 0xA9E5, 0x62DA, 0xA9E9, 0x62DB, 0xA9DB, 0x62DC, 0xABF4,
+	0x62EB, 0xCEDA, 0x62EC, 0xAC41, 0x62ED, 0xABF8, 0x62EE, 0xABFA,
+	0x62EF, 0xAC40, 0x62F0, 0xCEE6, 0x62F1, 0xABFD, 0x62F2, 0xD1B1,
+	0x62F3, 0xAEB1, 0x62F4, 0xAC43, 0x62F5, 0xCED7, 0x62F6, 0xCEDF,
+	0x62F7, 0xABFE, 0x62F8, 0xCEDE, 0x62F9, 0xCEDB, 0x62FA, 0xCEE3,
+	0x62FB, 0xCEE5, 0x62FC, 0xABF7, 0x62FD, 0xABFB, 0x62FE, 0xAC42,
+	0x62FF, 0xAEB3, 0x6300, 0xCEE0, 0x6301, 0xABF9, 0x6302, 0xAC45,
+	0x6303, 0xCED9, 0x6307, 0xABFC, 0x6308, 0xAEB2, 0x6309, 0xABF6,
+	0x630B, 0xCED6, 0x630C, 0xCEDD, 0x630D, 0xCED5, 0x630E, 0xCED8,
+	0x630F, 0xCEDC, 0x6310, 0xD1B2, 0x6311, 0xAC44, 0x6313, 0xCEE1,
+	0x6314, 0xCEE2, 0x6315, 0xCEE4, 0x6316, 0xABF5, 0x6328, 0xAEC1,
+	0x6329, 0xD1BE, 0x632A, 0xAEBF, 0x632B, 0xAEC0, 0x632C, 0xD1B4,
+	0x632D, 0xD1C4, 0x632F, 0xAEB6, 0x6332, 0xD566, 0x6333, 0xD1C6,
+	0x6334, 0xD1C0, 0x6336, 0xD1B7, 0x6338, 0xD1C9, 0x6339, 0xD1BA,
+	0x633A, 0xAEBC, 0x633B, 0xD57D, 0x633C, 0xD1BD, 0x633D, 0xAEBE,
+	0x633E, 0xAEB5, 0x6340, 0xD1CB, 0x6341, 0xD1BF, 0x6342, 0xAEB8,
+	0x6343, 0xD1B8, 0x6344, 0xD1B5, 0x6345, 0xD1B6, 0x6346, 0xAEB9,
+	0x6347, 0xD1C5, 0x6348, 0xD1CC, 0x6349, 0xAEBB, 0x634A, 0xD1BC,
+	0x634B, 0xD1BB, 0x634C, 0xAEC3, 0x634D, 0xAEC2, 0x634E, 0xAEB4,
+	0x634F, 0xAEBA, 0x6350, 0xAEBD, 0x6351, 0xD1C8, 0x6354, 0xD1C2,
+	0x6355, 0xAEB7, 0x6356, 0xD1B3, 0x6357, 0xD1CA, 0x6358, 0xD1C1,
+	0x6359, 0xD1C3, 0x635A, 0xD1C7, 0x6365, 0xD567, 0x6367, 0xB1B7,
+	0x6368, 0xB1CB, 0x6369, 0xB1CA, 0x636B, 0xB1BF, 0x636D, 0xD579,
+	0x636E, 0xD575, 0x636F, 0xD572, 0x6370, 0xD5A6, 0x6371, 0xB1BA,
+	0x6372, 0xB1B2, 0x6375, 0xD577, 0x6376, 0xB4A8, 0x6377, 0xB1B6,
+	0x6378, 0xD5A1, 0x637A, 0xB1CC, 0x637B, 0xB1C9, 0x637C, 0xD57B,
+	0x637D, 0xD56A, 0x6380, 0xB1C8, 0x6381, 0xD5A3, 0x6382, 0xD569,
+	0x6383, 0xB1BD, 0x6384, 0xB1C1, 0x6385, 0xD5A2, 0x6387, 0xD573,
+	0x6388, 0xB1C2, 0x6389, 0xB1BC, 0x638A, 0xD568, 0x638C, 0xB478,
+	0x638D, 0xD5A5, 0x638E, 0xD571, 0x638F, 0xB1C7, 0x6390, 0xD574,
+	0x6391, 0xD5A4, 0x6392, 0xB1C6, 0x6394, 0xD952, 0x6396, 0xB1B3,
+	0x6397, 0xD56F, 0x6398, 0xB1B8, 0x6399, 0xB1C3, 0x639B, 0xB1BE,
+	0x639C, 0xD578, 0x639D, 0xD56E, 0x639E, 0xD56C, 0x639F, 0xD57E,
+	0x63A0, 0xB1B0, 0x63A1, 0xB1C4, 0x63A2, 0xB1B4, 0x63A3, 0xB477,
+	0x63A4, 0xD57C, 0x63A5, 0xB1B5, 0x63A7, 0xB1B1, 0x63A8, 0xB1C0,
+	0x63A9, 0xB1BB, 0x63AA, 0xB1B9, 0x63AB, 0xD570, 0x63AC, 0xB1C5,
+	0x63AD, 0xD56D, 0x63AE, 0xD57A, 0x63AF, 0xD576, 0x63B0, 0xD954,
+	0x63B1, 0xD953, 0x63BD, 0xD56B, 0x63BE, 0xD964, 0x63C0, 0xB47A,
+	0x63C2, 0xD96A, 0x63C3, 0xD959, 0x63C4, 0xD967, 0x63C5, 0xDD77,
+	0x63C6, 0xB47D, 0x63C7, 0xD96B, 0x63C8, 0xD96E, 0x63C9, 0xB47C,
+	0x63CA, 0xD95C, 0x63CB, 0xD96D, 0x63CC, 0xD96C, 0x63CD, 0xB47E,
+	0x63CE, 0xD955, 0x63CF, 0xB479, 0x63D0, 0xB4A3, 0x63D2, 0xB4A1,
+	0x63D3, 0xD969, 0x63D5, 0xD95F, 0x63D6, 0xB4A5, 0x63D7, 0xD970,
+	0x63D8, 0xD968, 0x63D9, 0xD971, 0x63DA, 0xB4AD, 0x63DB, 0xB4AB,
+	0x63DC, 0xD966, 0x63DD, 0xD965, 0x63DF, 0xD963, 0x63E0, 0xD95D,
+	0x63E1, 0xB4A4, 0x63E3, 0xB4A2, 0x63E4, 0xD1B9, 0x63E5, 0xD956,
+	0x63E7, 0xDDB7, 0x63E8, 0xD957, 0x63E9, 0xB47B, 0x63EA, 0xB4AA,
+	0x63EB, 0xDD79, 0x63ED, 0xB4A6, 0x63EE, 0xB4A7, 0x63EF, 0xD958,
+	0x63F0, 0xD96F, 0x63F1, 0xDD78, 0x63F2, 0xD960, 0x63F3, 0xD95B,
+	0x63F4, 0xB4A9, 0x63F5, 0xD961, 0x63F6, 0xD95E, 0x63F9, 0xB4AE,
+	0x6406, 0xB770, 0x6409, 0xDD7C, 0x640A, 0xDDB1, 0x640B, 0xDDB6,
+	0x640C, 0xDDAA, 0x640D, 0xB76C, 0x640E, 0xDDBB, 0x640F, 0xB769,
+	0x6410, 0xDD7A, 0x6412, 0xDD7B, 0x6413, 0xB762, 0x6414, 0xB76B,
+	0x6415, 0xDDA4, 0x6416, 0xB76E, 0x6417, 0xB76F, 0x6418, 0xDDA5,
+	0x641A, 0xDDB2, 0x641B, 0xDDB8, 0x641C, 0xB76A, 0x641E, 0xB764,
+	0x641F, 0xDDA3, 0x6420, 0xDD7D, 0x6421, 0xDDBA, 0x6422, 0xDDA8,
+	0x6423, 0xDDA9, 0x6424, 0xDD7E, 0x6425, 0xDDB4, 0x6426, 0xDDAB,
+	0x6427, 0xDDB5, 0x6428, 0xDDAD, 0x642A, 0xB765, 0x642B, 0xE1D9,
+	0x642C, 0xB768, 0x642D, 0xB766, 0x642E, 0xDDB9, 0x642F, 0xDDB0,
+	0x6430, 0xDDAC, 0x6433, 0xDDA1, 0x6434, 0xBA53, 0x6435, 0xDDAF,
+	0x6436, 0xB76D, 0x6437, 0xDDA7, 0x6439, 0xDDA6, 0x643D, 0xB767,
+	0x643E, 0xB763, 0x643F, 0xE1EE, 0x6440, 0xDDB3, 0x6441, 0xDDAE,
+	0x6443, 0xDDA2, 0x644B, 0xE1E9, 0x644D, 0xE1DA, 0x644E, 0xE1E5,
+	0x6450, 0xE1EC, 0x6451, 0xBA51, 0x6452, 0xB4AC, 0x6453, 0xE1EA,
+	0x6454, 0xBA4C, 0x6458, 0xBA4B, 0x6459, 0xE1F1, 0x645B, 0xE1DB,
+	0x645C, 0xE1E8, 0x645D, 0xE1DC, 0x645E, 0xE1E7, 0x645F, 0xBA4F,
+	0x6460, 0xE1EB, 0x6461, 0xD962, 0x6465, 0xE1F2, 0x6466, 0xE1E3,
+	0x6467, 0xBA52, 0x6468, 0xE5BA, 0x6469, 0xBCAF, 0x646B, 0xE1F0,
+	0x646C, 0xE1EF, 0x646D, 0xBA54, 0x646E, 0xE5AD, 0x646F, 0xBCB0,
+	0x6470, 0xE5AE, 0x6472, 0xE1DF, 0x6473, 0xE1E0, 0x6474, 0xE1DD,
+	0x6475, 0xE1E2, 0x6476, 0xE1DE, 0x6477, 0xE1F3, 0x6478, 0xBA4E,
+	0x6479, 0xBCB1, 0x647A, 0xBA50, 0x647B, 0xBA55, 0x647D, 0xE1E1,
+	0x647F, 0xE1ED, 0x6482, 0xE1E6, 0x6485, 0xE5B1, 0x6487, 0xBA4A,
+	0x6488, 0xBCB4, 0x6489, 0xE9AA, 0x648A, 0xE5B6, 0x648B, 0xE5B5,
+	0x648C, 0xE5B7, 0x648F, 0xE5B4, 0x6490, 0xBCB5, 0x6492, 0xBCBB,
+	0x6493, 0xBCB8, 0x6495, 0xBCB9, 0x6496, 0xE5AF, 0x6497, 0xE5B2,
+	0x6498, 0xE5BC, 0x6499, 0xBCC1, 0x649A, 0xBCBF, 0x649C, 0xE5B3,
+	0x649D, 0xD95A, 0x649E, 0xBCB2, 0x649F, 0xE5B9, 0x64A0, 0xE5B0,
+	0x64A2, 0xBCC2, 0x64A3, 0xE5B8, 0x64A4, 0xBA4D, 0x64A5, 0xBCB7,
+	0x64A6, 0xE1E4, 0x64A9, 0xBCBA, 0x64AB, 0xBCBE, 0x64AC, 0xBCC0,
+	0x64AD, 0xBCBD, 0x64AE, 0xBCBC, 0x64B0, 0xBCB6, 0x64B1, 0xE5BB,
+	0x64B2, 0xBCB3, 0x64B3, 0xBCC3, 0x64BB, 0xBED8, 0x64BC, 0xBED9,
+	0x64BD, 0xE9A9, 0x64BE, 0xBEE2, 0x64BF, 0xBEDF, 0x64C1, 0xBED6,
+	0x64C2, 0xBEDD, 0x64C3, 0xE9AB, 0x64C4, 0xBEDB, 0x64C5, 0xBED5,
+	0x64C7, 0xBEDC, 0x64C9, 0xE9A8, 0x64CA, 0xC0BB, 0x64CB, 0xBED7,
+	0x64CD, 0xBEDE, 0x64CE, 0xC0BA, 0x64CF, 0xE9A7, 0x64D0, 0xE9A6,
+	0x64D2, 0xBEE0, 0x64D4, 0xBEE1, 0x64D6, 0xE9A5, 0x64D7, 0xE9A4,
+	0x64D8, 0xC0BC, 0x64D9, 0xE9AE, 0x64DA, 0xBEDA, 0x64DB, 0xE9AC,
+	0x64E0, 0xC0BD, 0x64E2, 0xC0C2, 0x64E3, 0xECEA, 0x64E4, 0xECEC,
+	0x64E6, 0xC0BF, 0x64E8, 0xECED, 0x64E9, 0xECE9, 0x64EB, 0xECEB,
+	0x64EC, 0xC0C0, 0x64ED, 0xC0C3, 0x64EF, 0xECE8, 0x64F0, 0xC0BE,
+	0x64F1, 0xC0C1, 0x64F2, 0xC259, 0x64F3, 0xE9AD, 0x64F4, 0xC258,
+	0x64F7, 0xC25E, 0x64F8, 0xEFD4, 0x64FA, 0xC25C, 0x64FB, 0xC25D,
+	0x64FC, 0xEFD7, 0x64FD, 0xEFD3, 0x64FE, 0xC25A, 0x64FF, 0xEFD1,
+	0x6500, 0xC36B, 0x6501, 0xEFD5, 0x6503, 0xEFD6, 0x6504, 0xEFD2,
+	0x6506, 0xC25B, 0x6507, 0xF242, 0x6509, 0xF245, 0x650C, 0xF246,
+	0x650D, 0xF244, 0x650E, 0xF247, 0x650F, 0xC36C, 0x6510, 0xF243,
+	0x6513, 0xF44E, 0x6514, 0xC464, 0x6515, 0xF44D, 0x6516, 0xF44C,
+	0x6517, 0xF44B, 0x6518, 0xC463, 0x6519, 0xC465, 0x651B, 0xF5CD,
+	0x651C, 0xC4E2, 0x651D, 0xC4E1, 0x6520, 0xF6E1, 0x6521, 0xF6E0,
+	0x6522, 0xF6E3, 0x6523, 0xC5CB, 0x6524, 0xC575, 0x6525, 0xF7DD,
+	0x6526, 0xF6E2, 0x6529, 0xF7DC, 0x652A, 0xC5CD, 0x652B, 0xC5CC,
+	0x652C, 0xC5F3, 0x652D, 0xF8A9, 0x652E, 0xF8EF, 0x652F, 0xA4E4,
+	0x6532, 0xD972, 0x6533, 0xE9AF, 0x6536, 0xA6AC, 0x6537, 0xCAF7,
+	0x6538, 0xA7F1, 0x6539, 0xA7EF, 0x653B, 0xA7F0, 0x653D, 0xCCC1,
+	0x653E, 0xA9F1, 0x653F, 0xAC46, 0x6541, 0xCEE7, 0x6543, 0xCEE8,
+	0x6545, 0xAC47, 0x6546, 0xD1CE, 0x6548, 0xAEC4, 0x6549, 0xAEC5,
+	0x654A, 0xD1CD, 0x654F, 0xB1D3, 0x6551, 0xB1CF, 0x6553, 0xD5A7,
+	0x6554, 0xB1D6, 0x6555, 0xB1D5, 0x6556, 0xB1CE, 0x6557, 0xB1D1,
+	0x6558, 0xB1D4, 0x6559, 0xB1D0, 0x655C, 0xD976, 0x655D, 0xB1CD,
+	0x655E, 0xB4AF, 0x6562, 0xB4B1, 0x6563, 0xB4B2, 0x6564, 0xD975,
+	0x6565, 0xD978, 0x6566, 0xB4B0, 0x6567, 0xD973, 0x6568, 0xD977,
+	0x656A, 0xD974, 0x656C, 0xB771, 0x656F, 0xDDBC, 0x6572, 0xBA56,
+	0x6573, 0xE1F4, 0x6574, 0xBEE3, 0x6575, 0xBCC4, 0x6576, 0xE5BD,
+	0x6577, 0xBCC5, 0x6578, 0xBCC6, 0x6579, 0xE5BF, 0x657A, 0xE5BE,
+	0x657B, 0xE5C0, 0x657C, 0xE9B1, 0x657F, 0xE9B0, 0x6580, 0xECEF,
+	0x6581, 0xECEE, 0x6582, 0xC0C4, 0x6583, 0xC0C5, 0x6584, 0xF248,
+	0x6587, 0xA4E5, 0x658C, 0xD979, 0x6590, 0xB4B4, 0x6591, 0xB4B3,
+	0x6592, 0xDDBD, 0x6594, 0xEFD8, 0x6595, 0xC4E3, 0x6596, 0xF7DE,
+	0x6597, 0xA4E6, 0x6599, 0xAEC6, 0x659B, 0xB1D8, 0x659C, 0xB1D7,
+	0x659D, 0xD97A, 0x659E, 0xD97B, 0x659F, 0xB772, 0x65A0, 0xE1F5,
+	0x65A1, 0xBA57, 0x65A2, 0xE9B2, 0x65A4, 0xA4E7, 0x65A5, 0xA5B8,
+	0x65A7, 0xA9F2, 0x65A8, 0xCCC2, 0x65AA, 0xCEE9, 0x65AB, 0xAC48,
+	0x65AC, 0xB1D9, 0x65AE, 0xD97C, 0x65AF, 0xB4B5, 0x65B0, 0xB773,
+	0x65B2, 0xE5C1, 0x65B3, 0xE5C2, 0x65B6, 0xECF0, 0x65B7, 0xC25F,
+	0x65B8, 0xF8F0, 0x65B9, 0xA4E8, 0x65BB, 0xCCC3, 0x65BC, 0xA9F3,
+	0x65BD, 0xAC49, 0x65BF, 0xCEEA, 0x65C1, 0xAEC7, 0x65C2, 0xD1D2,
+	0x65C3, 0xD1D0, 0x65C4, 0xD1D1, 0x65C5, 0xAEC8, 0x65C6, 0xD1CF,
+	0x65CB, 0xB1DB, 0x65CC, 0xB1DC, 0x65CD, 0xD5A8, 0x65CE, 0xB1DD,
+	0x65CF, 0xB1DA, 0x65D0, 0xD97D, 0x65D2, 0xD97E, 0x65D3, 0xDDBE,
+	0x65D6, 0xBA59, 0x65D7, 0xBA58, 0x65DA, 0xECF1, 0x65DB, 0xEFD9,
+	0x65DD, 0xF24A, 0x65DE, 0xF249, 0x65DF, 0xF44F, 0x65E1, 0xC95E,
+	0x65E2, 0xAC4A, 0x65E5, 0xA4E9, 0x65E6, 0xA5B9, 0x65E8, 0xA6AE,
+	0x65E9, 0xA6AD, 0x65EC, 0xA6AF, 0x65ED, 0xA6B0, 0x65EE, 0xC9EE,
+	0x65EF, 0xC9ED, 0x65F0, 0xCAF8, 0x65F1, 0xA7F2, 0x65F2, 0xCAFB,
+	0x65F3, 0xCAFA, 0x65F4, 0xCAF9, 0x65F5, 0xCAFC, 0x65FA, 0xA9F4,
+	0x65FB, 0xCCC9, 0x65FC, 0xCCC5, 0x65FD, 0xCCCE, 0x6600, 0xA9FB,
+	0x6602, 0xA9F9, 0x6603, 0xCCCA, 0x6604, 0xCCC6, 0x6605, 0xCCCD,
+	0x6606, 0xA9F8, 0x6607, 0xAA40, 0x6608, 0xCCC8, 0x6609, 0xCCC4,
+	0x660A, 0xA9FE, 0x660B, 0xCCCB, 0x660C, 0xA9F7, 0x660D, 0xCCCC,
+	0x660E, 0xA9FA, 0x660F, 0xA9FC, 0x6610, 0xCCD0, 0x6611, 0xCCCF,
+	0x6612, 0xCCC7, 0x6613, 0xA9F6, 0x6614, 0xA9F5, 0x6615, 0xA9FD,
+	0x661C, 0xCEEF, 0x661D, 0xCEF5, 0x661F, 0xAC50, 0x6620, 0xAC4D,
+	0x6621, 0xCEEC, 0x6622, 0xCEF1, 0x6624, 0xAC53, 0x6625, 0xAC4B,
+	0x6626, 0xCEF0, 0x6627, 0xAC4E, 0x6628, 0xAC51, 0x662B, 0xCEF3,
+	0x662D, 0xAC4C, 0x662E, 0xCEF8, 0x662F, 0xAC4F, 0x6631, 0xAC52,
+	0x6632, 0xCEED, 0x6633, 0xCEF2, 0x6634, 0xCEF6, 0x6635, 0xCEEE,
+	0x6636, 0xCEEB, 0x6639, 0xCEF7, 0x663A, 0xCEF4, 0x6641, 0xAED0,
+	0x6642, 0xAEC9, 0x6643, 0xAECC, 0x6645, 0xAECF, 0x6647, 0xD1D5,
+	0x6649, 0xAECA, 0x664A, 0xD1D3, 0x664C, 0xAECE, 0x664F, 0xAECB,
+	0x6651, 0xD1D6, 0x6652, 0xAECD, 0x6659, 0xD5AC, 0x665A, 0xB1DF,
+	0x665B, 0xD5AB, 0x665C, 0xD5AD, 0x665D, 0xB1DE, 0x665E, 0xB1E3,
+	0x665F, 0xD1D4, 0x6661, 0xD5AA, 0x6662, 0xD5AE, 0x6664, 0xB1E0,
+	0x6665, 0xD5A9, 0x6666, 0xB1E2, 0x6668, 0xB1E1, 0x666A, 0xD9A7,
+	0x666C, 0xD9A2, 0x666E, 0xB4B6, 0x666F, 0xB4BA, 0x6670, 0xB4B7,
+	0x6671, 0xD9A5, 0x6672, 0xD9A8, 0x6674, 0xB4B8, 0x6676, 0xB4B9,
+	0x6677, 0xB4BE, 0x6678, 0xDDC7, 0x6679, 0xD9A6, 0x667A, 0xB4BC,
+	0x667B, 0xD9A3, 0x667C, 0xD9A1, 0x667E, 0xB4BD, 0x6680, 0xD9A4,
+	0x6684, 0xB779, 0x6686, 0xDDBF, 0x6687, 0xB776, 0x6688, 0xB777,
+	0x6689, 0xB775, 0x668A, 0xDDC4, 0x668B, 0xDDC3, 0x668C, 0xDDC0,
+	0x668D, 0xB77B, 0x6690, 0xDDC2, 0x6691, 0xB4BB, 0x6694, 0xDDC6,
+	0x6695, 0xDDC1, 0x6696, 0xB778, 0x6697, 0xB774, 0x6698, 0xB77A,
+	0x6699, 0xDDC5, 0x669D, 0xBA5C, 0x669F, 0xE1F8, 0x66A0, 0xE1F7,
+	0x66A1, 0xE1F6, 0x66A2, 0xBA5A, 0x66A8, 0xBA5B, 0x66A9, 0xE5C5,
+	0x66AA, 0xE5C8, 0x66AB, 0xBCC8, 0x66AE, 0xBCC7, 0x66AF, 0xE5C9,
+	0x66B0, 0xE5C4, 0x66B1, 0xBCCA, 0x66B2, 0xE5C6, 0x66B4, 0xBCC9,
+	0x66B5, 0xE5C3, 0x66B7, 0xE5C7, 0x66B8, 0xBEE9, 0x66B9, 0xBEE6,
+	0x66BA, 0xE9BB, 0x66BB, 0xE9BA, 0x66BD, 0xE9B9, 0x66BE, 0xE9B4,
+	0x66C0, 0xE9B5, 0x66C4, 0xBEE7, 0x66C6, 0xBEE4, 0x66C7, 0xBEE8,
+	0x66C8, 0xE9B3, 0x66C9, 0xBEE5, 0x66CA, 0xE9B6, 0x66CB, 0xE9B7,
+	0x66CC, 0xE9BC, 0x66CF, 0xE9B8, 0x66D2, 0xECF2, 0x66D6, 0xC0C7,
+	0x66D8, 0xEFDC, 0x66D9, 0xC0C6, 0x66DA, 0xEFDA, 0x66DB, 0xEFDB,
+	0x66DC, 0xC260, 0x66DD, 0xC36E, 0x66DE, 0xF24B, 0x66E0, 0xC36D,
+	0x66E3, 0xF451, 0x66E4, 0xF452, 0x66E6, 0xC466, 0x66E8, 0xF450,
+	0x66E9, 0xC4E4, 0x66EB, 0xF7DF, 0x66EC, 0xC5CE, 0x66ED, 0xF8AA,
+	0x66EE, 0xF8AB, 0x66F0, 0xA4EA, 0x66F2, 0xA6B1, 0x66F3, 0xA6B2,
+	0x66F4, 0xA7F3, 0x66F6, 0xCCD1, 0x66F7, 0xAC54, 0x66F8, 0xAED1,
+	0x66F9, 0xB1E4, 0x66FC, 0xB0D2, 0x66FE, 0xB4BF, 0x66FF, 0xB4C0,
+	0x6700, 0xB3CC, 0x6701, 0xD9A9, 0x6703, 0xB77C, 0x6704, 0xE1FA,
+	0x6705, 0xE1F9, 0x6708, 0xA4EB, 0x6709, 0xA6B3, 0x670A, 0xCCD2,
+	0x670B, 0xAA42, 0x670D, 0xAA41, 0x670F, 0xCEF9, 0x6710, 0xCEFA,
+	0x6712, 0xD1D7, 0x6713, 0xD1D8, 0x6714, 0xAED2, 0x6715, 0xAED3,
+	0x6717, 0xAED4, 0x6718, 0xD5AF, 0x671B, 0xB1E6, 0x671D, 0xB4C2,
+	0x671F, 0xB4C1, 0x6720, 0xDDC8, 0x6721, 0xDF7A, 0x6722, 0xE1FB,
+	0x6723, 0xE9BD, 0x6726, 0xC261, 0x6727, 0xC467, 0x6728, 0xA4EC,
+	0x672A, 0xA5BC, 0x672B, 0xA5BD, 0x672C, 0xA5BB, 0x672D, 0xA5BE,
+	0x672E, 0xA5BA, 0x6731, 0xA6B6, 0x6733, 0xC9F6, 0x6734, 0xA6B5,
+	0x6735, 0xA6B7, 0x6738, 0xC9F1, 0x6739, 0xC9F0, 0x673A, 0xC9F3,
+	0x673B, 0xC9F2, 0x673C, 0xC9F5, 0x673D, 0xA6B4, 0x673E, 0xC9EF,
+	0x673F, 0xC9F4, 0x6745, 0xCAFD, 0x6746, 0xA7FD, 0x6747, 0xCAFE,
+	0x6748, 0xCB43, 0x6749, 0xA7FC, 0x674B, 0xCB47, 0x674C, 0xCB42,
+	0x674D, 0xCB45, 0x674E, 0xA7F5, 0x674F, 0xA7F6, 0x6750, 0xA7F7,
+	0x6751, 0xA7F8, 0x6753, 0xA840, 0x6755, 0xCB41, 0x6756, 0xA7FA,
+	0x6757, 0xA841, 0x6759, 0xCB40, 0x675A, 0xCB46, 0x675C, 0xA7F9,
+	0x675D, 0xCB44, 0x675E, 0xA7FB, 0x675F, 0xA7F4, 0x6760, 0xA7FE,
+	0x676A, 0xAA57, 0x676C, 0xCCD4, 0x676D, 0xAA43, 0x676F, 0xAA4D,
+	0x6770, 0xAA4E, 0x6771, 0xAA46, 0x6772, 0xAA58, 0x6773, 0xAA48,
+	0x6774, 0xCCDC, 0x6775, 0xAA53, 0x6776, 0xCCD7, 0x6777, 0xAA49,
+	0x6778, 0xCCE6, 0x6779, 0xCCE7, 0x677A, 0xCCDF, 0x677B, 0xCCD8,
+	0x677C, 0xAA56, 0x677D, 0xCCE4, 0x677E, 0xAA51, 0x677F, 0xAA4F,
+	0x6781, 0xCCE5, 0x6783, 0xCCE3, 0x6784, 0xCCDB, 0x6785, 0xCCD3,
+	0x6786, 0xCCDA, 0x6787, 0xAA4A, 0x6789, 0xAA50, 0x678B, 0xAA44,
+	0x678C, 0xCCDE, 0x678D, 0xCCDD, 0x678E, 0xCCD5, 0x6790, 0xAA52,
+	0x6791, 0xCCE1, 0x6792, 0xCCD6, 0x6793, 0xAA55, 0x6794, 0xCCE8,
+	0x6795, 0xAA45, 0x6797, 0xAA4C, 0x6798, 0xCCD9, 0x6799, 0xCCE2,
+	0x679A, 0xAA54, 0x679C, 0xAA47, 0x679D, 0xAA4B, 0x679F, 0xCCE0,
+	0x67AE, 0xCF5B, 0x67AF, 0xAC5C, 0x67B0, 0xAC69, 0x67B2, 0xCF56,
+	0x67B3, 0xCF4C, 0x67B4, 0xAC62, 0x67B5, 0xCF4A, 0x67B6, 0xAC5B,
+	0x67B7, 0xCF45, 0x67B8, 0xAC65, 0x67B9, 0xCF52, 0x67BA, 0xCEFE,
+	0x67BB, 0xCF41, 0x67C0, 0xCF44, 0x67C1, 0xCEFB, 0x67C2, 0xCF51,
+	0x67C3, 0xCF61, 0x67C4, 0xAC60, 0x67C5, 0xCF46, 0x67C6, 0xCF58,
+	0x67C8, 0xCEFD, 0x67C9, 0xCF5F, 0x67CA, 0xCF60, 0x67CB, 0xCF63,
+	0x67CC, 0xCF5A, 0x67CD, 0xCF4B, 0x67CE, 0xCF53, 0x67CF, 0xAC66,
+	0x67D0, 0xAC59, 0x67D1, 0xAC61, 0x67D2, 0xAC6D, 0x67D3, 0xAC56,
+	0x67D4, 0xAC58, 0x67D8, 0xCF43, 0x67D9, 0xAC6A, 0x67DA, 0xAC63,
+	0x67DB, 0xCF5D, 0x67DC, 0xCF40, 0x67DD, 0xAC6C, 0x67DE, 0xAC67,
+	0x67DF, 0xCF49, 0x67E2, 0xAC6B, 0x67E3, 0xCF50, 0x67E4, 0xCF48,
+	0x67E5, 0xAC64, 0x67E6, 0xCF5C, 0x67E7, 0xCF54, 0x67E9, 0xAC5E,
+	0x67EA, 0xCF62, 0x67EB, 0xCF47, 0x67EC, 0xAC5A, 0x67ED, 0xCF59,
+	0x67EE, 0xCF4F, 0x67EF, 0xAC5F, 0x67F0, 0xCF55, 0x67F1, 0xAC57,
+	0x67F2, 0xCEFC, 0x67F3, 0xAC68, 0x67F4, 0xAEE3, 0x67F5, 0xAC5D,
+	0x67F6, 0xCF4E, 0x67F7, 0xCF4D, 0x67F8, 0xCF42, 0x67FA, 0xCF5E,
+	0x67FC, 0xCF57, 0x67FF, 0xAC55, 0x6812, 0xD1EC, 0x6813, 0xAEEA,
+	0x6814, 0xD1ED, 0x6816, 0xD1E1, 0x6817, 0xAEDF, 0x6818, 0xAEEB,
+	0x681A, 0xD1DA, 0x681C, 0xD1E3, 0x681D, 0xD1EB, 0x681F, 0xD1D9,
+	0x6820, 0xD1F4, 0x6821, 0xAED5, 0x6825, 0xD1F3, 0x6826, 0xD1EE,
+	0x6828, 0xD1EF, 0x6829, 0xAEDD, 0x682A, 0xAEE8, 0x682B, 0xD1E5,
+	0x682D, 0xD1E6, 0x682E, 0xD1F0, 0x682F, 0xD1E7, 0x6831, 0xD1E2,
+	0x6832, 0xD1DC, 0x6833, 0xD1DD, 0x6834, 0xD1EA, 0x6835, 0xD1E4,
+	0x6838, 0xAED6, 0x6839, 0xAEDA, 0x683A, 0xD1F2, 0x683B, 0xD1DE,
+	0x683C, 0xAEE6, 0x683D, 0xAEE2, 0x6840, 0xAEE5, 0x6841, 0xAEEC,
+	0x6842, 0xAEDB, 0x6843, 0xAEE7, 0x6844, 0xD1E9, 0x6845, 0xAEE9,
+	0x6846, 0xAED8, 0x6848, 0xAED7, 0x6849, 0xD1DB, 0x684B, 0xD1DF,
+	0x684C, 0xAEE0, 0x684D, 0xD1F1, 0x684E, 0xD1E8, 0x684F, 0xD1E0,
+	0x6850, 0xAEE4, 0x6851, 0xAEE1, 0x6853, 0xAED9, 0x6854, 0xAEDC,
+	0x686B, 0xD5C4, 0x686D, 0xD5B4, 0x686E, 0xD5B5, 0x686F, 0xD5B9,
+	0x6871, 0xD5C8, 0x6872, 0xD5C5, 0x6874, 0xD5BE, 0x6875, 0xD5BD,
+	0x6876, 0xB1ED, 0x6877, 0xD5C1, 0x6878, 0xD5D0, 0x6879, 0xD5B0,
+	0x687B, 0xD5D1, 0x687C, 0xD5C3, 0x687D, 0xD5D5, 0x687E, 0xD5C9,
+	0x687F, 0xB1EC, 0x6880, 0xD5C7, 0x6881, 0xB1E7, 0x6882, 0xB1FC,
+	0x6883, 0xB1F2, 0x6885, 0xB1F6, 0x6886, 0xB1F5, 0x6887, 0xD5B1,
+	0x6889, 0xD5CE, 0x688A, 0xD5D4, 0x688B, 0xD5CC, 0x688C, 0xD5D3,
+	0x688F, 0xD5C0, 0x6890, 0xD5B2, 0x6891, 0xD5D2, 0x6892, 0xD5C2,
+	0x6893, 0xB1EA, 0x6894, 0xB1F7, 0x6896, 0xD5CB, 0x6897, 0xB1F0,
+	0x689B, 0xD5CA, 0x689C, 0xD5B3, 0x689D, 0xB1F8, 0x689F, 0xB1FA,
+	0x68A0, 0xD5CD, 0x68A1, 0xB1FB, 0x68A2, 0xB1E9, 0x68A3, 0xD5BA,
+	0x68A4, 0xD5CF, 0x68A7, 0xB1EF, 0x68A8, 0xB1F9, 0x68A9, 0xD5BC,
+	0x68AA, 0xD5C6, 0x68AB, 0xD5B7, 0x68AC, 0xD5BB, 0x68AD, 0xB1F4,
+	0x68AE, 0xD5B6, 0x68AF, 0xB1E8, 0x68B0, 0xB1F1, 0x68B1, 0xB1EE,
+	0x68B2, 0xD5BF, 0x68B3, 0xAEDE, 0x68B4, 0xD9C0, 0x68B5, 0xB1EB,
+	0x68C4, 0xB1F3, 0x68C6, 0xD9C3, 0x68C7, 0xD9D9, 0x68C8, 0xD9CE,
+	0x68C9, 0xB4D6, 0x68CB, 0xB4D1, 0x68CC, 0xD9BD, 0x68CD, 0xB4D2,
+	0x68CE, 0xD9CD, 0x68D0, 0xD9C6, 0x68D1, 0xD9D3, 0x68D2, 0xB4CE,
+	0x68D3, 0xD9AB, 0x68D4, 0xD9D5, 0x68D5, 0xB4C4, 0x68D6, 0xD9B3,
+	0x68D7, 0xB4C7, 0x68D8, 0xB4C6, 0x68DA, 0xB4D7, 0x68DC, 0xD9AD,
+	0x68DD, 0xD9CF, 0x68DE, 0xD9D0, 0x68DF, 0xB4C9, 0x68E0, 0xB4C5,
+	0x68E1, 0xD9BB, 0x68E3, 0xB4D0, 0x68E4, 0xD9B6, 0x68E6, 0xD9D1,
+	0x68E7, 0xB4CC, 0x68E8, 0xD9C9, 0x68E9, 0xD9D6, 0x68EA, 0xD9B0,
+	0x68EB, 0xD9B5, 0x68EC, 0xD9AF, 0x68EE, 0xB4CB, 0x68EF, 0xD9C2,
+	0x68F0, 0xDDDE, 0x68F1, 0xD9B1, 0x68F2, 0xB4CF, 0x68F3, 0xD9BA,
+	0x68F4, 0xD9D2, 0x68F5, 0xB4CA, 0x68F6, 0xD9B7, 0x68F7, 0xD9B4,
+	0x68F8, 0xD9C5, 0x68F9, 0xB4CD, 0x68FA, 0xB4C3, 0x68FB, 0xB4D9,
+	0x68FC, 0xD9C8, 0x68FD, 0xD9C7, 0x6904, 0xD9AC, 0x6905, 0xB4C8,
+	0x6906, 0xD9D4, 0x6907, 0xD9BC, 0x6908, 0xD9BE, 0x690A, 0xD9CB,
+	0x690B, 0xD9CA, 0x690C, 0xD9AA, 0x690D, 0xB4D3, 0x690E, 0xB4D5,
+	0x690F, 0xD9B2, 0x6910, 0xD9B9, 0x6911, 0xD9C1, 0x6912, 0xB4D4,
+	0x6913, 0xD9B8, 0x6914, 0xD9C4, 0x6915, 0xD9D7, 0x6917, 0xD9CC,
+	0x6925, 0xD9D8, 0x692A, 0xD9AE, 0x692F, 0xDDF2, 0x6930, 0xB7A6,
+	0x6932, 0xDDF0, 0x6933, 0xDDDB, 0x6934, 0xDDE0, 0x6935, 0xDDD9,
+	0x6937, 0xDDEC, 0x6938, 0xDDCB, 0x6939, 0xDDD2, 0x693B, 0xDDEA,
+	0x693C, 0xDDF4, 0x693D, 0xDDDC, 0x693F, 0xDDCF, 0x6940, 0xDDE2,
+	0x6941, 0xDDE7, 0x6942, 0xDDD3, 0x6944, 0xDDE4, 0x6945, 0xDDD0,
+	0x6948, 0xDDD7, 0x6949, 0xDDD8, 0x694A, 0xB7A8, 0x694B, 0xDDEB,
+	0x694C, 0xDDE9, 0x694E, 0xDDCC, 0x694F, 0xDDEE, 0x6951, 0xDDEF,
+	0x6952, 0xDDF1, 0x6953, 0xB7AC, 0x6954, 0xB7A4, 0x6956, 0xD5B8,
+	0x6957, 0xDDD4, 0x6958, 0xDDE6, 0x6959, 0xDDD5, 0x695A, 0xB7A1,
+	0x695B, 0xB7B1, 0x695C, 0xDDED, 0x695D, 0xB7AF, 0x695E, 0xB7AB,
+	0x695F, 0xDDCA, 0x6960, 0xB7A3, 0x6962, 0xDDCD, 0x6963, 0xB7B0,
+	0x6965, 0xDDDD, 0x6966, 0xDDC9, 0x6968, 0xB7A9, 0x6969, 0xDDE1,
+	0x696A, 0xDDD1, 0x696B, 0xB7AA, 0x696C, 0xDDDA, 0x696D, 0xB77E,
+	0x696E, 0xB4D8, 0x696F, 0xDDE3, 0x6970, 0xD9BF, 0x6971, 0xDDCE,
+	0x6974, 0xDDE8, 0x6975, 0xB7A5, 0x6976, 0xDDE5, 0x6977, 0xB7A2,
+	0x6978, 0xDDDF, 0x6979, 0xB7AD, 0x697A, 0xDDD6, 0x697B, 0xDDF3,
+	0x6982, 0xB7A7, 0x6983, 0xDEC6, 0x6986, 0xB7AE, 0x698D, 0xE24A,
+	0x698E, 0xE248, 0x6990, 0xE25E, 0x6991, 0xE246, 0x6993, 0xE258,
+	0x6994, 0xB77D, 0x6995, 0xBA5F, 0x6996, 0xE242, 0x6997, 0xE25D,
+	0x6999, 0xE247, 0x699A, 0xE255, 0x699B, 0xBA64, 0x699C, 0xBA5D,
+	0x699E, 0xE25B, 0x69A0, 0xE240, 0x69A1, 0xE25A, 0x69A3, 0xBA6F,
+	0x69A4, 0xE251, 0x69A5, 0xE261, 0x69A6, 0xBA6D, 0x69A7, 0xE249,
+	0x69A8, 0xBA5E, 0x69A9, 0xE24B, 0x69AA, 0xE259, 0x69AB, 0xBA67,
+	0x69AC, 0xE244, 0x69AD, 0xBA6B, 0x69AE, 0xBA61, 0x69AF, 0xE24D,
+	0x69B0, 0xE243, 0x69B1, 0xE1FC, 0x69B3, 0xE257, 0x69B4, 0xBA68,
+	0x69B5, 0xE260, 0x69B6, 0xE1FD, 0x69B7, 0xBA65, 0x69B9, 0xE253,
+	0x69BB, 0xBA66, 0x69BC, 0xE245, 0x69BD, 0xE250, 0x69BE, 0xE24C,
+	0x69BF, 0xE24E, 0x69C1, 0xBA60, 0x69C2, 0xE25F, 0x69C3, 0xBA6E,
+	0x69C4, 0xE24F, 0x69C6, 0xE262, 0x69C9, 0xE1FE, 0x69CA, 0xE254,
+	0x69CB, 0xBA63, 0x69CC, 0xBA6C, 0x69CD, 0xBA6A, 0x69CE, 0xE241,
+	0x69CF, 0xE256, 0x69D0, 0xBA69, 0x69D3, 0xBA62, 0x69D4, 0xE252,
+	0x69D9, 0xE25C, 0x69E2, 0xE5D5, 0x69E4, 0xE5D1, 0x69E5, 0xE5CD,
+	0x69E6, 0xE5E1, 0x69E7, 0xE5DE, 0x69E8, 0xBCCD, 0x69EB, 0xE5E5,
+	0x69EC, 0xE5D4, 0x69ED, 0xBCD8, 0x69EE, 0xE5DB, 0x69F1, 0xE5D0,
+	0x69F2, 0xE5DA, 0x69F3, 0xBCD5, 0x69F4, 0xE5EE, 0x69F6, 0xE5EB,
+	0x69F7, 0xE5DD, 0x69F8, 0xE5CE, 0x69FB, 0xE5E2, 0x69FC, 0xE5E4,
+	0x69FD, 0xBCD1, 0x69FE, 0xE5D8, 0x69FF, 0xE5D3, 0x6A00, 0xE5CA,
+	0x6A01, 0xBCCE, 0x6A02, 0xBCD6, 0x6A04, 0xE5E7, 0x6A05, 0xBCD7,
+	0x6A06, 0xE5CB, 0x6A07, 0xE5ED, 0x6A08, 0xE5E0, 0x6A09, 0xE5E6,
+	0x6A0A, 0xBCD4, 0x6A0D, 0xE5E3, 0x6A0F, 0xE5EA, 0x6A11, 0xBCD9,
+	0x6A13, 0xBCD3, 0x6A14, 0xE5DC, 0x6A15, 0xE5CF, 0x6A16, 0xE5EF,
+	0x6A17, 0xE5CC, 0x6A18, 0xE5E8, 0x6A19, 0xBCD0, 0x6A1B, 0xE5D6,
+	0x6A1D, 0xE5D7, 0x6A1E, 0xBCCF, 0x6A1F, 0xBCCC, 0x6A20, 0xE5D2,
+	0x6A21, 0xBCD2, 0x6A23, 0xBCCB, 0x6A25, 0xE5E9, 0x6A26, 0xE5EC,
+	0x6A27, 0xE5D9, 0x6A28, 0xE9CA, 0x6A32, 0xE9C2, 0x6A34, 0xE9BE,
+	0x6A35, 0xBEF6, 0x6A38, 0xBEEB, 0x6A39, 0xBEF0, 0x6A3A, 0xBEEC,
+	0x6A3B, 0xE9CC, 0x6A3C, 0xE9D7, 0x6A3D, 0xBEEA, 0x6A3E, 0xE9C4,
+	0x6A3F, 0xE9CD, 0x6A40, 0xE5DF, 0x6A41, 0xE9CE, 0x6A44, 0xBEF1,
+	0x6A46, 0xE9DD, 0x6A47, 0xBEF5, 0x6A48, 0xBEF8, 0x6A49, 0xE9C0,
+	0x6A4B, 0xBEF4, 0x6A4D, 0xE9DB, 0x6A4E, 0xE9DC, 0x6A4F, 0xE9D2,
+	0x6A50, 0xE9D1, 0x6A51, 0xE9C9, 0x6A54, 0xE9D3, 0x6A55, 0xE9DA,
+	0x6A56, 0xE9D9, 0x6A58, 0xBEEF, 0x6A59, 0xBEED, 0x6A5A, 0xE9CB,
+	0x6A5B, 0xE9C8, 0x6A5D, 0xE9C5, 0x6A5E, 0xE9D8, 0x6A5F, 0xBEF7,
+	0x6A60, 0xE9D6, 0x6A61, 0xBEF3, 0x6A62, 0xBEF2, 0x6A64, 0xE9D0,
+	0x6A66, 0xE9BF, 0x6A67, 0xE9C1, 0x6A68, 0xE9C3, 0x6A69, 0xE9D5,
+	0x6A6A, 0xE9CF, 0x6A6B, 0xBEEE, 0x6A6D, 0xE9C6, 0x6A6F, 0xE9D4,
+	0x6A76, 0xE9C7, 0x6A7E, 0xC0CF, 0x6A7F, 0xED45, 0x6A80, 0xC0C8,
+	0x6A81, 0xECF5, 0x6A83, 0xED41, 0x6A84, 0xC0CA, 0x6A85, 0xED48,
+	0x6A87, 0xECFC, 0x6A89, 0xECF7, 0x6A8C, 0xED49, 0x6A8D, 0xECF3,
+	0x6A8E, 0xECFE, 0x6A90, 0xC0D1, 0x6A91, 0xED44, 0x6A92, 0xED4A,
+	0x6A93, 0xECFD, 0x6A94, 0xC0C9, 0x6A95, 0xED40, 0x6A96, 0xECF4,
+	0x6A97, 0xC0D0, 0x6A9A, 0xED47, 0x6A9B, 0xECF9, 0x6A9C, 0xC0CC,
+	0x6A9E, 0xECFB, 0x6A9F, 0xECF8, 0x6AA0, 0xC0D2, 0x6AA1, 0xECFA,
+	0x6AA2, 0xC0CB, 0x6AA3, 0xC0CE, 0x6AA4, 0xED43, 0x6AA5, 0xECF6,
+	0x6AA6, 0xED46, 0x6AA8, 0xED42, 0x6AAC, 0xC263, 0x6AAD, 0xEFE7,
+	0x6AAE, 0xC268, 0x6AAF, 0xC269, 0x6AB3, 0xC262, 0x6AB4, 0xEFE6,
+	0x6AB6, 0xEFE3, 0x6AB7, 0xEFE4, 0x6AB8, 0xC266, 0x6AB9, 0xEFDE,
+	0x6ABA, 0xEFE2, 0x6ABB, 0xC265, 0x6ABD, 0xEFDF, 0x6AC2, 0xC267,
+	0x6AC3, 0xC264, 0x6AC5, 0xEFDD, 0x6AC6, 0xEFE1, 0x6AC7, 0xEFE5,
+	0x6ACB, 0xF251, 0x6ACC, 0xF24E, 0x6ACD, 0xF257, 0x6ACF, 0xF256,
+	0x6AD0, 0xF254, 0x6AD1, 0xF24F, 0x6AD3, 0xC372, 0x6AD9, 0xF250,
+	0x6ADA, 0xC371, 0x6ADB, 0xC0CD, 0x6ADC, 0xF253, 0x6ADD, 0xC370,
+	0x6ADE, 0xF258, 0x6ADF, 0xF252, 0x6AE0, 0xF24D, 0x6AE1, 0xEFE0,
+	0x6AE5, 0xC36F, 0x6AE7, 0xF24C, 0x6AE8, 0xF456, 0x6AEA, 0xF455,
+	0x6AEB, 0xF255, 0x6AEC, 0xC468, 0x6AEE, 0xF459, 0x6AEF, 0xF45A,
+	0x6AF0, 0xF454, 0x6AF1, 0xF458, 0x6AF3, 0xF453, 0x6AF8, 0xF5D1,
+	0x6AF9, 0xF457, 0x6AFA, 0xC4E7, 0x6AFB, 0xC4E5, 0x6AFC, 0xF5CF,
+	0x6B00, 0xF5D2, 0x6B02, 0xF5CE, 0x6B03, 0xF5D0, 0x6B04, 0xC4E6,
+	0x6B08, 0xF6E5, 0x6B09, 0xF6E6, 0x6B0A, 0xC576, 0x6B0B, 0xF6E4,
+	0x6B0F, 0xF7E2, 0x6B10, 0xC5CF, 0x6B11, 0xF7E0, 0x6B12, 0xF7E1,
+	0x6B13, 0xF8AC, 0x6B16, 0xC656, 0x6B17, 0xF8F3, 0x6B18, 0xF8F1,
+	0x6B19, 0xF8F2, 0x6B1A, 0xF8F4, 0x6B1E, 0xF9BB, 0x6B20, 0xA4ED,
+	0x6B21, 0xA6B8, 0x6B23, 0xAA59, 0x6B25, 0xCCE9, 0x6B28, 0xCF64,
+	0x6B2C, 0xD1F5, 0x6B2D, 0xD1F7, 0x6B2F, 0xD1F6, 0x6B31, 0xD1F8,
+	0x6B32, 0xB1FD, 0x6B33, 0xD5D7, 0x6B34, 0xD1F9, 0x6B36, 0xD5D6,
+	0x6B37, 0xD5D8, 0x6B38, 0xD5D9, 0x6B39, 0xD9DA, 0x6B3A, 0xB4DB,
+	0x6B3B, 0xD9DB, 0x6B3C, 0xD9DD, 0x6B3D, 0xB4DC, 0x6B3E, 0xB4DA,
+	0x6B3F, 0xD9DC, 0x6B41, 0xDDFA, 0x6B42, 0xDDF8, 0x6B43, 0xDDF7,
+	0x6B45, 0xDDF6, 0x6B46, 0xDDF5, 0x6B47, 0xB7B2, 0x6B48, 0xDDF9,
+	0x6B49, 0xBA70, 0x6B4A, 0xE263, 0x6B4B, 0xE265, 0x6B4C, 0xBA71,
+	0x6B4D, 0xE264, 0x6B4E, 0xBCDB, 0x6B50, 0xBCDA, 0x6B51, 0xE5F0,
+	0x6B54, 0xE9DF, 0x6B55, 0xE9DE, 0x6B56, 0xE9E0, 0x6B59, 0xBEF9,
+	0x6B5B, 0xED4B, 0x6B5C, 0xC0D3, 0x6B5E, 0xEFE8, 0x6B5F, 0xC26A,
+	0x6B60, 0xF259, 0x6B61, 0xC577, 0x6B62, 0xA4EE, 0x6B63, 0xA5BF,
+	0x6B64, 0xA6B9, 0x6B65, 0xA842, 0x6B66, 0xAA5A, 0x6B67, 0xAA5B,
+	0x6B6A, 0xAC6E, 0x6B6D, 0xD1FA, 0x6B72, 0xB7B3, 0x6B76, 0xE6D1,
+	0x6B77, 0xBEFA, 0x6B78, 0xC26B, 0x6B79, 0xA4EF, 0x6B7B, 0xA6BA,
+	0x6B7E, 0xCCEB, 0x6B7F, 0xAA5C, 0x6B80, 0xCCEA, 0x6B82, 0xCF65,
+	0x6B83, 0xAC6F, 0x6B84, 0xCF66, 0x6B86, 0xAC70, 0x6B88, 0xD1FC,
+	0x6B89, 0xAEEE, 0x6B8A, 0xAEED, 0x6B8C, 0xD5DE, 0x6B8D, 0xD5DC,
+	0x6B8E, 0xD5DD, 0x6B8F, 0xD5DB, 0x6B91, 0xD5DA, 0x6B94, 0xD9DE,
+	0x6B95, 0xD9E1, 0x6B96, 0xB4DE, 0x6B97, 0xD9DF, 0x6B98, 0xB4DD,
+	0x6B99, 0xD9E0, 0x6B9B, 0xDDFB, 0x6B9E, 0xE266, 0x6B9F, 0xE267,
+	0x6BA0, 0xE268, 0x6BA2, 0xE5F3, 0x6BA3, 0xE5F2, 0x6BA4, 0xBCDC,
+	0x6BA5, 0xE5F1, 0x6BA6, 0xE5F4, 0x6BA7, 0xE9E1, 0x6BAA, 0xE9E2,
+	0x6BAB, 0xE9E3, 0x6BAD, 0xED4C, 0x6BAE, 0xC0D4, 0x6BAF, 0xC26C,
+	0x6BB0, 0xF25A, 0x6BB2, 0xC4E8, 0x6BB3, 0xC95F, 0x6BB5, 0xAC71,
+	0x6BB6, 0xCF67, 0x6BB7, 0xAEEF, 0x6BBA, 0xB1FE, 0x6BBC, 0xB4DF,
+	0x6BBD, 0xD9E2, 0x6BBF, 0xB7B5, 0x6BC0, 0xB7B4, 0x6BC3, 0xE269,
+	0x6BC4, 0xE26A, 0x6BC5, 0xBCDD, 0x6BC6, 0xBCDE, 0x6BC7, 0xE9E5,
+	0x6BC8, 0xE9E4, 0x6BC9, 0xEFE9, 0x6BCA, 0xF7E3, 0x6BCB, 0xA4F0,
+	0x6BCC, 0xC960, 0x6BCD, 0xA5C0, 0x6BCF, 0xA843, 0x6BD0, 0xCB48,
+	0x6BD2, 0xAC72, 0x6BD3, 0xB7B6, 0x6BD4, 0xA4F1, 0x6BD6, 0xCF68,
+	0x6BD7, 0xAC73, 0x6BD8, 0xCF69, 0x6BDA, 0xC0D5, 0x6BDB, 0xA4F2,
+	0x6BDE, 0xCCEC, 0x6BE0, 0xCF6A, 0x6BE2, 0xD242, 0x6BE3, 0xD241,
+	0x6BE4, 0xD1FE, 0x6BE6, 0xD1FD, 0x6BE7, 0xD243, 0x6BE8, 0xD240,
+	0x6BEB, 0xB240, 0x6BEC, 0xB241, 0x6BEF, 0xB4E0, 0x6BF0, 0xD9E3,
+	0x6BF2, 0xD9E4, 0x6BF3, 0xD9E5, 0x6BF7, 0xDE41, 0x6BF8, 0xDE42,
+	0x6BF9, 0xDE40, 0x6BFB, 0xDDFD, 0x6BFC, 0xDDFE, 0x6BFD, 0xB7B7,
+	0x6BFE, 0xE26B, 0x6BFF, 0xE5F7, 0x6C00, 0xE5F6, 0x6C01, 0xE5F5,
+	0x6C02, 0xE5F8, 0x6C03, 0xE9E7, 0x6C04, 0xE9E6, 0x6C05, 0xBEFB,
+	0x6C06, 0xE9E8, 0x6C08, 0xC0D6, 0x6C09, 0xED4D, 0x6C0B, 0xEFEA,
+	0x6C0C, 0xF25B, 0x6C0D, 0xF6E7, 0x6C0F, 0xA4F3, 0x6C10, 0xA5C2,
+	0x6C11, 0xA5C1, 0x6C13, 0xAA5D, 0x6C14, 0xC961, 0x6C15, 0xC97E,
+	0x6C16, 0xA6BB, 0x6C18, 0xC9F7, 0x6C19, 0xCB49, 0x6C1A, 0xCB4A,
+	0x6C1B, 0xAA5E, 0x6C1D, 0xCCED, 0x6C1F, 0xAC74, 0x6C20, 0xCF6B,
+	0x6C21, 0xCF6C, 0x6C23, 0xAEF0, 0x6C24, 0xAEF4, 0x6C25, 0xD244,
+	0x6C26, 0xAEF3, 0x6C27, 0xAEF1, 0x6C28, 0xAEF2, 0x6C2A, 0xD5DF,
+	0x6C2B, 0xB242, 0x6C2C, 0xB4E3, 0x6C2E, 0xB4E1, 0x6C2F, 0xB4E2,
+	0x6C30, 0xD9E6, 0x6C33, 0xBA72, 0x6C34, 0xA4F4, 0x6C36, 0xC9A1,
+	0x6C38, 0xA5C3, 0x6C3B, 0xC9A4, 0x6C3E, 0xA5C6, 0x6C3F, 0xC9A3,
+	0x6C40, 0xA5C5, 0x6C41, 0xA5C4, 0x6C42, 0xA844, 0x6C43, 0xC9A2,
+	0x6C46, 0xC9F8, 0x6C4A, 0xC9FC, 0x6C4B, 0xC9FE, 0x6C4C, 0xCA40,
+	0x6C4D, 0xA6C5, 0x6C4E, 0xA6C6, 0x6C4F, 0xC9FB, 0x6C50, 0xA6C1,
+	0x6C52, 0xC9F9, 0x6C54, 0xC9FD, 0x6C55, 0xA6C2, 0x6C57, 0xA6BD,
+	0x6C59, 0xA6BE, 0x6C5B, 0xA6C4, 0x6C5C, 0xC9FA, 0x6C5D, 0xA6BC,
+	0x6C5E, 0xA845, 0x6C5F, 0xA6BF, 0x6C60, 0xA6C0, 0x6C61, 0xA6C3,
+	0x6C65, 0xCB5B, 0x6C66, 0xCB59, 0x6C67, 0xCB4C, 0x6C68, 0xA851,
+	0x6C69, 0xCB53, 0x6C6A, 0xA84C, 0x6C6B, 0xCB4D, 0x6C6D, 0xCB55,
+	0x6C6F, 0xCB52, 0x6C70, 0xA84F, 0x6C71, 0xCB51, 0x6C72, 0xA856,
+	0x6C73, 0xCB5A, 0x6C74, 0xA858, 0x6C76, 0xA85A, 0x6C78, 0xCB4B,
+	0x6C7A, 0xA84D, 0x6C7B, 0xCB5C, 0x6C7D, 0xA854, 0x6C7E, 0xA857,
+	0x6C80, 0xCD45, 0x6C81, 0xA847, 0x6C82, 0xA85E, 0x6C83, 0xA855,
+	0x6C84, 0xCB4E, 0x6C85, 0xA84A, 0x6C86, 0xA859, 0x6C87, 0xCB56,
+	0x6C88, 0xA848, 0x6C89, 0xA849, 0x6C8A, 0xCD43, 0x6C8B, 0xCB4F,
+	0x6C8C, 0xA850, 0x6C8D, 0xA85B, 0x6C8E, 0xCB5D, 0x6C8F, 0xCB50,
+	0x6C90, 0xA84E, 0x6C92, 0xA853, 0x6C93, 0xCCEE, 0x6C94, 0xA85C,
+	0x6C95, 0xCB57, 0x6C96, 0xA852, 0x6C98, 0xA85D, 0x6C99, 0xA846,
+	0x6C9A, 0xCB54, 0x6C9B, 0xA84B, 0x6C9C, 0xCB58, 0x6C9D, 0xCD44,
+	0x6CAB, 0xAA6A, 0x6CAC, 0xAA7A, 0x6CAD, 0xCCF5, 0x6CAE, 0xAA71,
+	0x6CB0, 0xCD4B, 0x6CB1, 0xAA62, 0x6CB3, 0xAA65, 0x6CB4, 0xCD42,
+	0x6CB6, 0xCCF3, 0x6CB7, 0xCCF7, 0x6CB8, 0xAA6D, 0x6CB9, 0xAA6F,
+	0x6CBA, 0xCCFA, 0x6CBB, 0xAA76, 0x6CBC, 0xAA68, 0x6CBD, 0xAA66,
+	0x6CBE, 0xAA67, 0x6CBF, 0xAA75, 0x6CC0, 0xCD47, 0x6CC1, 0xAA70,
+	0x6CC2, 0xCCF9, 0x6CC3, 0xCCFB, 0x6CC4, 0xAA6E, 0x6CC5, 0xAA73,
+	0x6CC6, 0xCCFC, 0x6CC7, 0xCD4A, 0x6CC9, 0xAC75, 0x6CCA, 0xAA79,
+	0x6CCC, 0xAA63, 0x6CCD, 0xCD49, 0x6CCF, 0xCD4D, 0x6CD0, 0xCCF8,
+	0x6CD1, 0xCD4F, 0x6CD2, 0xCD40, 0x6CD3, 0xAA6C, 0x6CD4, 0xCCF4,
+	0x6CD5, 0xAA6B, 0x6CD6, 0xAA7D, 0x6CD7, 0xAA72, 0x6CD9, 0xCCF2,
+	0x6CDA, 0xCF75, 0x6CDB, 0xAA78, 0x6CDC, 0xAA7C, 0x6CDD, 0xCD41,
+	0x6CDE, 0xCD46, 0x6CE0, 0xAA7E, 0x6CE1, 0xAA77, 0x6CE2, 0xAA69,
+	0x6CE3, 0xAA5F, 0x6CE5, 0xAA64, 0x6CE7, 0xCCF6, 0x6CE8, 0xAA60,
+	0x6CE9, 0xCD4E, 0x6CEB, 0xCCF0, 0x6CEC, 0xCCEF, 0x6CED, 0xCCFD,
+	0x6CEE, 0xCCF1, 0x6CEF, 0xAA7B, 0x6CF0, 0xAEF5, 0x6CF1, 0xAA74,
+	0x6CF2, 0xCCFE, 0x6CF3, 0xAA61, 0x6CF5, 0xACA6, 0x6CF9, 0xCD4C,
+	0x6D00, 0xCF7C, 0x6D01, 0xCFA1, 0x6D03, 0xCFA4, 0x6D04, 0xCF77,
+	0x6D07, 0xCFA7, 0x6D08, 0xCFAA, 0x6D09, 0xCFAC, 0x6D0A, 0xCF74,
+	0x6D0B, 0xAC76, 0x6D0C, 0xAC7B, 0x6D0D, 0xD249, 0x6D0E, 0xACAD,
+	0x6D0F, 0xCFA5, 0x6D10, 0xCFAD, 0x6D11, 0xCF7B, 0x6D12, 0xCF73,
+	0x6D16, 0xD264, 0x6D17, 0xAC7E, 0x6D18, 0xCFA2, 0x6D19, 0xCF78,
+	0x6D1A, 0xCF7A, 0x6D1B, 0xACA5, 0x6D1D, 0xCF7D, 0x6D1E, 0xAC7D,
+	0x6D1F, 0xCF70, 0x6D20, 0xCFA8, 0x6D22, 0xCFAB, 0x6D25, 0xAC7A,
+	0x6D27, 0xACA8, 0x6D28, 0xCF6D, 0x6D29, 0xACAA, 0x6D2A, 0xAC78,
+	0x6D2B, 0xACAE, 0x6D2C, 0xCFA9, 0x6D2D, 0xCF6F, 0x6D2E, 0xACAB,
+	0x6D2F, 0xD25E, 0x6D30, 0xCD48, 0x6D31, 0xAC7C, 0x6D32, 0xAC77,
+	0x6D33, 0xCF76, 0x6D34, 0xCF6E, 0x6D35, 0xACAC, 0x6D36, 0xACA4,
+	0x6D37, 0xCFA3, 0x6D38, 0xACA9, 0x6D39, 0xACA7, 0x6D3A, 0xCF79,
+	0x6D3B, 0xACA1, 0x6D3C, 0xCF71, 0x6D3D, 0xACA2, 0x6D3E, 0xACA3,
+	0x6D3F, 0xCF72, 0x6D40, 0xCFA6, 0x6D41, 0xAC79, 0x6D42, 0xCF7E,
+	0x6D58, 0xD24C, 0x6D59, 0xAEFD, 0x6D5A, 0xAF43, 0x6D5E, 0xD255,
+	0x6D5F, 0xD25B, 0x6D60, 0xD257, 0x6D61, 0xD24A, 0x6D62, 0xD24D,
+	0x6D63, 0xD246, 0x6D64, 0xD247, 0x6D65, 0xAF4A, 0x6D66, 0xAEFA,
+	0x6D67, 0xD256, 0x6D68, 0xD25F, 0x6D69, 0xAF45, 0x6D6A, 0xAEF6,
+	0x6D6C, 0xAF40, 0x6D6D, 0xD24E, 0x6D6E, 0xAF42, 0x6D6F, 0xD24F,
+	0x6D70, 0xD259, 0x6D74, 0xAF44, 0x6D75, 0xD268, 0x6D76, 0xD248,
+	0x6D77, 0xAEFC, 0x6D78, 0xAEFB, 0x6D79, 0xAF48, 0x6D7A, 0xD245,
+	0x6D7B, 0xD266, 0x6D7C, 0xD25A, 0x6D7D, 0xD267, 0x6D7E, 0xD261,
+	0x6D7F, 0xD253, 0x6D80, 0xD262, 0x6D82, 0xD25C, 0x6D83, 0xD265,
+	0x6D84, 0xD263, 0x6D85, 0xAF49, 0x6D86, 0xD254, 0x6D87, 0xAEF9,
+	0x6D88, 0xAEF8, 0x6D89, 0xAF41, 0x6D8A, 0xAF47, 0x6D8B, 0xD260,
+	0x6D8C, 0xAF46, 0x6D8D, 0xD251, 0x6D8E, 0xB243, 0x6D90, 0xD269,
+	0x6D91, 0xD250, 0x6D92, 0xD24B, 0x6D93, 0xAEFE, 0x6D94, 0xAF4B,
+	0x6D95, 0xAEF7, 0x6D97, 0xD258, 0x6D98, 0xD25D, 0x6DAA, 0xB265,
+	0x6DAB, 0xD5E1, 0x6DAC, 0xD5E5, 0x6DAE, 0xB252, 0x6DAF, 0xB250,
+	0x6DB2, 0xB247, 0x6DB3, 0xD5E3, 0x6DB4, 0xD5E2, 0x6DB5, 0xB25B,
+	0x6DB7, 0xD5E8, 0x6DB8, 0xB255, 0x6DBA, 0xD5FA, 0x6DBB, 0xD647,
+	0x6DBC, 0xB244, 0x6DBD, 0xD5F7, 0x6DBE, 0xD5F0, 0x6DBF, 0xB267,
+	0x6DC0, 0xD5E0, 0x6DC2, 0xD5FC, 0x6DC4, 0xB264, 0x6DC5, 0xB258,
+	0x6DC6, 0xB263, 0x6DC7, 0xB24E, 0x6DC8, 0xD5EC, 0x6DC9, 0xD5FE,
+	0x6DCA, 0xD5F6, 0x6DCB, 0xB24F, 0x6DCC, 0xB249, 0x6DCD, 0xD645,
+	0x6DCF, 0xD5FD, 0x6DD0, 0xD640, 0x6DD1, 0xB251, 0x6DD2, 0xB259,
+	0x6DD3, 0xD642, 0x6DD4, 0xD5EA, 0x6DD5, 0xD5FB, 0x6DD6, 0xD5EF,
+	0x6DD7, 0xD644, 0x6DD8, 0xB25E, 0x6DD9, 0xB246, 0x6DDA, 0xB25C,
+	0x6DDB, 0xD5F4, 0x6DDC, 0xD5F2, 0x6DDD, 0xD5F3, 0x6DDE, 0xB253,
+	0x6DDF, 0xD5EE, 0x6DE0, 0xD5ED, 0x6DE1, 0xB248, 0x6DE2, 0xD5E7,
+	0x6DE3, 0xD646, 0x6DE4, 0xB24A, 0x6DE5, 0xD5F1, 0x6DE6, 0xB268,
+	0x6DE8, 0xB262, 0x6DE9, 0xD5E6, 0x6DEA, 0xB25F, 0x6DEB, 0xB25D,
+	0x6DEC, 0xB266, 0x6DED, 0xD5F8, 0x6DEE, 0xB261, 0x6DEF, 0xD252,
+	0x6DF0, 0xD5F9, 0x6DF1, 0xB260, 0x6DF2, 0xD641, 0x6DF3, 0xB245,
+	0x6DF4, 0xD5F5, 0x6DF5, 0xB257, 0x6DF6, 0xD5E9, 0x6DF7, 0xB256,
+	0x6DF9, 0xB254, 0x6DFA, 0xB24C, 0x6DFB, 0xB24B, 0x6DFC, 0xD9E7,
+	0x6DFD, 0xD643, 0x6E00, 0xD5EB, 0x6E03, 0xD9FC, 0x6E05, 0xB24D,
+	0x6E19, 0xB541, 0x6E1A, 0xB25A, 0x6E1B, 0xB4EE, 0x6E1C, 0xD9F6,
+	0x6E1D, 0xB4FC, 0x6E1F, 0xD9EA, 0x6E20, 0xB4EB, 0x6E21, 0xB4E7,
+	0x6E22, 0xDA49, 0x6E23, 0xB4ED, 0x6E24, 0xB4F1, 0x6E25, 0xB4EC,
+	0x6E26, 0xB4F5, 0x6E27, 0xDA4D, 0x6E28, 0xDA44, 0x6E2B, 0xD9F1,
+	0x6E2C, 0xB4FA, 0x6E2D, 0xB4F4, 0x6E2E, 0xD9FD, 0x6E2F, 0xB4E4,
+	0x6E30, 0xDA4A, 0x6E31, 0xDA43, 0x6E32, 0xB4E8, 0x6E33, 0xD9F7,
+	0x6E34, 0xB4F7, 0x6E35, 0xDA55, 0x6E36, 0xDA56, 0x6E38, 0xB4E5,
+	0x6E39, 0xDA48, 0x6E3A, 0xB4F9, 0x6E3B, 0xD9FB, 0x6E3C, 0xD9ED,
+	0x6E3D, 0xD9EE, 0x6E3E, 0xB4FD, 0x6E3F, 0xD9F2, 0x6E40, 0xD9F9,
+	0x6E41, 0xD9F3, 0x6E43, 0xB4FB, 0x6E44, 0xB544, 0x6E45, 0xD9EF,
+	0x6E46, 0xD9E8, 0x6E47, 0xD9E9, 0x6E49, 0xD9EB, 0x6E4A, 0xB4EA,
+	0x6E4B, 0xD9F8, 0x6E4D, 0xB4F8, 0x6E4E, 0xB542, 0x6E51, 0xD9FA,
+	0x6E52, 0xDA53, 0x6E53, 0xDA4B, 0x6E54, 0xB4E6, 0x6E55, 0xDA51,
+	0x6E56, 0xB4F2, 0x6E58, 0xB4F0, 0x6E5A, 0xDA57, 0x6E5B, 0xB4EF,
+	0x6E5C, 0xDA41, 0x6E5D, 0xD9F4, 0x6E5E, 0xD9FE, 0x6E5F, 0xB547,
+	0x6E60, 0xDA45, 0x6E61, 0xDA42, 0x6E62, 0xD9F0, 0x6E63, 0xB543,
+	0x6E64, 0xDA4F, 0x6E65, 0xDA4C, 0x6E66, 0xDA54, 0x6E67, 0xB4E9,
+	0x6E68, 0xDA40, 0x6E69, 0xB546, 0x6E6B, 0xDA47, 0x6E6E, 0xB4F3,
+	0x6E6F, 0xB4F6, 0x6E71, 0xDA46, 0x6E72, 0xB545, 0x6E73, 0xD9F5,
+	0x6E74, 0xD5E4, 0x6E77, 0xDA50, 0x6E78, 0xDA4E, 0x6E79, 0xDA52,
+	0x6E88, 0xD9EC, 0x6E89, 0xB540, 0x6E8D, 0xDE61, 0x6E8E, 0xDE60,
+	0x6E8F, 0xDE46, 0x6E90, 0xB7BD, 0x6E92, 0xDE5F, 0x6E93, 0xDE49,
+	0x6E94, 0xDE4A, 0x6E96, 0xB7C7, 0x6E97, 0xDE68, 0x6E98, 0xB7C2,
+	0x6E99, 0xDE5E, 0x6E9B, 0xDE43, 0x6E9C, 0xB7C8, 0x6E9D, 0xB7BE,
+	0x6E9E, 0xDE52, 0x6E9F, 0xDE48, 0x6EA0, 0xDE4B, 0x6EA1, 0xDE63,
+	0x6EA2, 0xB7B8, 0x6EA3, 0xDE6A, 0x6EA4, 0xDE62, 0x6EA5, 0xB7C1,
+	0x6EA6, 0xDE57, 0x6EA7, 0xB7CC, 0x6EAA, 0xB7CB, 0x6EAB, 0xB7C5,
+	0x6EAE, 0xDE69, 0x6EAF, 0xB7B9, 0x6EB0, 0xDE55, 0x6EB1, 0xDE4C,
+	0x6EB2, 0xDE59, 0x6EB3, 0xDE65, 0x6EB4, 0xB7CD, 0x6EB6, 0xB7BB,
+	0x6EB7, 0xDE54, 0x6EB9, 0xDE4D, 0x6EBA, 0xB7C4, 0x6EBC, 0xB7C3,
+	0x6EBD, 0xDE50, 0x6EBE, 0xDE5A, 0x6EBF, 0xDE64, 0x6EC0, 0xDE47,
+	0x6EC1, 0xDE51, 0x6EC2, 0xB7BC, 0x6EC3, 0xDE5B, 0x6EC4, 0xB7C9,
+	0x6EC5, 0xB7C0, 0x6EC6, 0xDE4E, 0x6EC7, 0xB7BF, 0x6EC8, 0xDE45,
+	0x6EC9, 0xDE53, 0x6ECA, 0xDE67, 0x6ECB, 0xB4FE, 0x6ECC, 0xBAB0,
+	0x6ECD, 0xDE56, 0x6ECE, 0xE26C, 0x6ECF, 0xDE58, 0x6ED0, 0xDE66,
+	0x6ED1, 0xB7C6, 0x6ED2, 0xDE4F, 0x6ED3, 0xB7BA, 0x6ED4, 0xB7CA,
+	0x6ED5, 0xBCF0, 0x6ED6, 0xDE44, 0x6ED8, 0xDE5D, 0x6EDC, 0xDE5C,
+	0x6EEB, 0xE2AA, 0x6EEC, 0xBAAD, 0x6EED, 0xE27D, 0x6EEE, 0xE2A4,
+	0x6EEF, 0xBAA2, 0x6EF1, 0xE26E, 0x6EF2, 0xBAAF, 0x6EF4, 0xBA77,
+	0x6EF5, 0xE26D, 0x6EF6, 0xE2B0, 0x6EF7, 0xBAB1, 0x6EF8, 0xE271,
+	0x6EF9, 0xE2A3, 0x6EFB, 0xE273, 0x6EFC, 0xE2B3, 0x6EFD, 0xE2AF,
+	0x6EFE, 0xBA75, 0x6EFF, 0xBAA1, 0x6F00, 0xE653, 0x6F01, 0xBAAE,
+	0x6F02, 0xBA7D, 0x6F03, 0xE26F, 0x6F05, 0xE2AE, 0x6F06, 0xBAA3,
+	0x6F07, 0xE2AB, 0x6F08, 0xE2B8, 0x6F09, 0xE275, 0x6F0A, 0xE27E,
+	0x6F0D, 0xE2B6, 0x6F0E, 0xE2AC, 0x6F0F, 0xBA7C, 0x6F12, 0xE27C,
+	0x6F13, 0xBA76, 0x6F14, 0xBA74, 0x6F15, 0xBAA8, 0x6F18, 0xE27A,
+	0x6F19, 0xE277, 0x6F1A, 0xE278, 0x6F1C, 0xE2B2, 0x6F1E, 0xE2B7,
+	0x6F1F, 0xE2B5, 0x6F20, 0xBA7A, 0x6F21, 0xE2B9, 0x6F22, 0xBA7E,
+	0x6F23, 0xBAA7, 0x6F25, 0xE270, 0x6F26, 0xE5FA, 0x6F27, 0xE279,
+	0x6F29, 0xBA78, 0x6F2A, 0xBAAC, 0x6F2B, 0xBAA9, 0x6F2C, 0xBA7B,
+	0x6F2D, 0xE2A5, 0x6F2E, 0xE274, 0x6F2F, 0xBAAA, 0x6F30, 0xE2A7,
+	0x6F31, 0xBAA4, 0x6F32, 0xBAA6, 0x6F33, 0xBA73, 0x6F35, 0xE2A9,
+	0x6F36, 0xE2A1, 0x6F37, 0xE272, 0x6F38, 0xBAA5, 0x6F39, 0xE2B1,
+	0x6F3A, 0xE2B4, 0x6F3B, 0xE27B, 0x6F3C, 0xE2A8, 0x6F3E, 0xBA79,
+	0x6F3F, 0xBCDF, 0x6F40, 0xE2A6, 0x6F41, 0xE5F9, 0x6F43, 0xE2AD,
+	0x6F4E, 0xE276, 0x6F4F, 0xE644, 0x6F50, 0xE64E, 0x6F51, 0xBCE2,
+	0x6F52, 0xE64D, 0x6F53, 0xE659, 0x6F54, 0xBCE4, 0x6F55, 0xE64B,
+	0x6F57, 0xE64F, 0x6F58, 0xBCEF, 0x6F5A, 0xE646, 0x6F5B, 0xBCE7,
+	0x6F5D, 0xE652, 0x6F5E, 0xE9F0, 0x6F5F, 0xBCF3, 0x6F60, 0xBCF2,
+	0x6F61, 0xE654, 0x6F62, 0xE643, 0x6F63, 0xE65E, 0x6F64, 0xBCED,
+	0x6F66, 0xBCE3, 0x6F67, 0xE657, 0x6F69, 0xE65B, 0x6F6A, 0xE660,
+	0x6F6B, 0xE655, 0x6F6C, 0xE649, 0x6F6D, 0xBCE6, 0x6F6E, 0xBCE9,
+	0x6F6F, 0xBCF1, 0x6F70, 0xBCEC, 0x6F72, 0xE64C, 0x6F73, 0xE2A2,
+	0x6F76, 0xE648, 0x6F77, 0xE65F, 0x6F78, 0xBCE8, 0x6F7A, 0xBCEB,
+	0x6F7B, 0xE661, 0x6F7C, 0xBCE0, 0x6F7D, 0xE656, 0x6F7E, 0xE5FB,
+	0x6F7F, 0xE65C, 0x6F80, 0xC0DF, 0x6F82, 0xE64A, 0x6F84, 0xBCE1,
+	0x6F85, 0xE645, 0x6F86, 0xBCE5, 0x6F87, 0xE5FC, 0x6F88, 0xBAAB,
+	0x6F89, 0xE641, 0x6F8B, 0xE65A, 0x6F8C, 0xE642, 0x6F8D, 0xE640,
+	0x6F8E, 0xBCEA, 0x6F90, 0xE658, 0x6F92, 0xE5FE, 0x6F93, 0xE651,
+	0x6F94, 0xE650, 0x6F95, 0xE65D, 0x6F96, 0xE647, 0x6F97, 0xBCEE,
+	0x6F9E, 0xE9F3, 0x6FA0, 0xBF49, 0x6FA1, 0xBEFE, 0x6FA2, 0xEA40,
+	0x6FA3, 0xE9EB, 0x6FA4, 0xBF41, 0x6FA5, 0xE9F7, 0x6FA6, 0xBF48,
+	0x6FA7, 0xBF43, 0x6FA8, 0xE9F5, 0x6FA9, 0xED4F, 0x6FAA, 0xE9FB,
+	0x6FAB, 0xEA42, 0x6FAC, 0xE9FA, 0x6FAD, 0xE9E9, 0x6FAE, 0xE9F8,
+	0x6FAF, 0xEA44, 0x6FB0, 0xEA46, 0x6FB1, 0xBEFD, 0x6FB2, 0xEA45,
+	0x6FB3, 0xBF44, 0x6FB4, 0xBF4A, 0x6FB6, 0xBF47, 0x6FB8, 0xE9FE,
+	0x6FB9, 0xBF46, 0x6FBA, 0xE9F9, 0x6FBC, 0xE9ED, 0x6FBD, 0xE9F2,
+	0x6FBF, 0xE9FD, 0x6FC0, 0xBF45, 0x6FC1, 0xBF42, 0x6FC2, 0xBEFC,
+	0x6FC3, 0xBF40, 0x6FC4, 0xE9F1, 0x6FC6, 0xE5FD, 0x6FC7, 0xE9EC,
+	0x6FC8, 0xE9EF, 0x6FC9, 0xEA41, 0x6FCA, 0xE9F4, 0x6FCB, 0xE9EA,
+	0x6FCC, 0xED4E, 0x6FCD, 0xEA43, 0x6FCE, 0xE9EE, 0x6FCF, 0xE9FC,
+	0x6FD4, 0xED51, 0x6FD5, 0xC0E3, 0x6FD8, 0xC0D7, 0x6FDB, 0xC0DB,
+	0x6FDC, 0xED53, 0x6FDD, 0xED59, 0x6FDE, 0xED57, 0x6FDF, 0xC0D9,
+	0x6FE0, 0xC0DA, 0x6FE1, 0xC0E1, 0x6FE2, 0xED5A, 0x6FE3, 0xED52,
+	0x6FE4, 0xC0DC, 0x6FE6, 0xED56, 0x6FE7, 0xED55, 0x6FE8, 0xED5B,
+	0x6FE9, 0xC0E2, 0x6FEB, 0xC0DD, 0x6FEC, 0xC0E0, 0x6FED, 0xED54,
+	0x6FEE, 0xC0E4, 0x6FEF, 0xC0DE, 0x6FF0, 0xC0E5, 0x6FF1, 0xC0D8,
+	0x6FF2, 0xED58, 0x6FF4, 0xED50, 0x6FF7, 0xEFF7, 0x6FFA, 0xC271,
+	0x6FFB, 0xEFF4, 0x6FFC, 0xEFF6, 0x6FFE, 0xC26F, 0x6FFF, 0xEFF2,
+	0x7000, 0xEFF3, 0x7001, 0xEFEE, 0x7004, 0xE9F6, 0x7005, 0xEFEF,
+	0x7006, 0xC270, 0x7007, 0xEFEB, 0x7009, 0xC26D, 0x700A, 0xEFF8,
+	0x700B, 0xC26E, 0x700C, 0xEFEC, 0x700D, 0xEFED, 0x700E, 0xEFF1,
+	0x700F, 0xC273, 0x7011, 0xC272, 0x7014, 0xEFF0, 0x7015, 0xC378,
+	0x7016, 0xF25F, 0x7017, 0xF265, 0x7018, 0xC379, 0x7019, 0xF25C,
+	0x701A, 0xC376, 0x701B, 0xC373, 0x701C, 0xF267, 0x701D, 0xC377,
+	0x701F, 0xC374, 0x7020, 0xF25E, 0x7021, 0xF261, 0x7022, 0xF262,
+	0x7023, 0xF263, 0x7024, 0xF266, 0x7026, 0xEFF5, 0x7027, 0xF25D,
+	0x7028, 0xC375, 0x7029, 0xF264, 0x702A, 0xF268, 0x702B, 0xF260,
+	0x702F, 0xF45D, 0x7030, 0xC46A, 0x7031, 0xF460, 0x7032, 0xC46B,
+	0x7033, 0xF468, 0x7034, 0xF45F, 0x7035, 0xF45C, 0x7037, 0xF45E,
+	0x7038, 0xF462, 0x7039, 0xF465, 0x703A, 0xF464, 0x703B, 0xF467,
+	0x703C, 0xF45B, 0x703E, 0xC469, 0x703F, 0xF463, 0x7040, 0xF466,
+	0x7041, 0xF469, 0x7042, 0xF461, 0x7043, 0xF5D3, 0x7044, 0xF5D4,
+	0x7045, 0xF5D8, 0x7046, 0xF5D9, 0x7048, 0xF5D6, 0x7049, 0xF5D7,
+	0x704A, 0xF5D5, 0x704C, 0xC4E9, 0x7051, 0xC578, 0x7052, 0xF6EB,
+	0x7055, 0xF6E8, 0x7056, 0xF6E9, 0x7057, 0xF6EA, 0x7058, 0xC579,
+	0x705A, 0xF7E5, 0x705B, 0xF7E4, 0x705D, 0xF8AF, 0x705E, 0xC5F4,
+	0x705F, 0xF8AD, 0x7060, 0xF8B0, 0x7061, 0xF8AE, 0x7062, 0xF8F5,
+	0x7063, 0xC657, 0x7064, 0xC665, 0x7065, 0xF9A3, 0x7066, 0xF96C,
+	0x7068, 0xF9A2, 0x7069, 0xF9D0, 0x706A, 0xF9D1, 0x706B, 0xA4F5,
+	0x7070, 0xA6C7, 0x7071, 0xCA41, 0x7074, 0xCB5E, 0x7076, 0xA85F,
+	0x7078, 0xA862, 0x707A, 0xCB5F, 0x707C, 0xA860, 0x707D, 0xA861,
+	0x7082, 0xCD58, 0x7083, 0xCD5A, 0x7084, 0xCD55, 0x7085, 0xCD52,
+	0x7086, 0xCD54, 0x708A, 0xAAA4, 0x708E, 0xAAA2, 0x7091, 0xCD56,
+	0x7092, 0xAAA3, 0x7093, 0xCD53, 0x7094, 0xCD50, 0x7095, 0xAAA1,
+	0x7096, 0xCD57, 0x7098, 0xCD51, 0x7099, 0xAAA5, 0x709A, 0xCD59,
+	0x709F, 0xCFAF, 0x70A1, 0xCFB3, 0x70A4, 0xACB7, 0x70A9, 0xCFB6,
+	0x70AB, 0xACAF, 0x70AC, 0xACB2, 0x70AD, 0xACB4, 0x70AE, 0xACB6,
+	0x70AF, 0xACB3, 0x70B0, 0xCFB2, 0x70B1, 0xCFB1, 0x70B3, 0xACB1,
+	0x70B4, 0xCFB4, 0x70B5, 0xCFB5, 0x70B7, 0xCFAE, 0x70B8, 0xACB5,
+	0x70BA, 0xACB0, 0x70BE, 0xCFB0, 0x70C5, 0xD277, 0x70C6, 0xD278,
+	0x70C7, 0xD279, 0x70C8, 0xAF50, 0x70CA, 0xAF4C, 0x70CB, 0xD26E,
+	0x70CD, 0xD276, 0x70CE, 0xD27B, 0x70CF, 0xAF51, 0x70D1, 0xD26C,
+	0x70D2, 0xD272, 0x70D3, 0xD26B, 0x70D4, 0xD275, 0x70D7, 0xD271,
+	0x70D8, 0xAF4D, 0x70D9, 0xAF4F, 0x70DA, 0xD27A, 0x70DC, 0xD26A,
+	0x70DD, 0xD26D, 0x70DE, 0xD273, 0x70E0, 0xD274, 0x70E1, 0xD27C,
+	0x70E2, 0xD270, 0x70E4, 0xAF4E, 0x70EF, 0xB26D, 0x70F0, 0xD64E,
+	0x70F3, 0xD650, 0x70F4, 0xD64C, 0x70F6, 0xD658, 0x70F7, 0xD64A,
+	0x70F8, 0xD657, 0x70F9, 0xB269, 0x70FA, 0xD648, 0x70FB, 0xDA5B,
+	0x70FC, 0xD652, 0x70FD, 0xB26C, 0x70FF, 0xD653, 0x7100, 0xD656,
+	0x7102, 0xD65A, 0x7104, 0xD64F, 0x7106, 0xD654, 0x7109, 0xB26A,
+	0x710A, 0xB26B, 0x710B, 0xD659, 0x710C, 0xD64D, 0x710D, 0xD649,
+	0x710E, 0xD65B, 0x7110, 0xD651, 0x7113, 0xD655, 0x7117, 0xD64B,
+	0x7119, 0xB548, 0x711A, 0xB549, 0x711B, 0xDA65, 0x711C, 0xB54F,
+	0x711E, 0xDA59, 0x711F, 0xDA62, 0x7120, 0xDA58, 0x7121, 0xB54C,
+	0x7122, 0xDA60, 0x7123, 0xDA5E, 0x7125, 0xDA5F, 0x7126, 0xB54A,
+	0x7128, 0xDA63, 0x712E, 0xDA5C, 0x712F, 0xDA5A, 0x7130, 0xB54B,
+	0x7131, 0xDA5D, 0x7132, 0xDA61, 0x7136, 0xB54D, 0x713A, 0xDA64,
+	0x7141, 0xDE70, 0x7142, 0xDE77, 0x7143, 0xDE79, 0x7144, 0xDEA1,
+	0x7146, 0xB7DA, 0x7147, 0xDE6B, 0x7149, 0xB7D2, 0x714B, 0xDE7A,
+	0x714C, 0xB7D7, 0x714D, 0xDEA2, 0x714E, 0xB7CE, 0x7150, 0xDE7D,
+	0x7152, 0xDE6D, 0x7153, 0xDE7E, 0x7154, 0xDE6C, 0x7156, 0xB7DC,
+	0x7158, 0xDE78, 0x7159, 0xB7CF, 0x715A, 0xDEA3, 0x715C, 0xB7D4,
+	0x715D, 0xDE71, 0x715E, 0xB7D9, 0x715F, 0xDE7C, 0x7160, 0xDE6F,
+	0x7161, 0xDE76, 0x7162, 0xDE72, 0x7163, 0xDE6E, 0x7164, 0xB7D1,
+	0x7165, 0xB7D8, 0x7166, 0xB7D6, 0x7167, 0xB7D3, 0x7168, 0xB7DB,
+	0x7169, 0xB7D0, 0x716A, 0xDE75, 0x716C, 0xB7D5, 0x716E, 0xB54E,
+	0x7170, 0xDE7B, 0x7172, 0xDE73, 0x7178, 0xDE74, 0x717B, 0xE2C1,
+	0x717D, 0xBAB4, 0x7180, 0xE2BD, 0x7181, 0xE2C3, 0x7182, 0xE2BF,
+	0x7184, 0xBAB6, 0x7185, 0xE2BE, 0x7186, 0xE2C2, 0x7187, 0xE2BA,
+	0x7189, 0xE2BC, 0x718A, 0xBAB5, 0x718F, 0xE2C0, 0x7190, 0xE2BB,
+	0x7192, 0xBAB7, 0x7194, 0xBAB2, 0x7197, 0xE2C4, 0x7199, 0xBAB3,
+	0x719A, 0xE667, 0x719B, 0xE664, 0x719C, 0xE670, 0x719D, 0xE66A,
+	0x719E, 0xE66C, 0x719F, 0xBCF4, 0x71A0, 0xE666, 0x71A1, 0xE66E,
+	0x71A4, 0xE66D, 0x71A5, 0xE66B, 0x71A7, 0xE671, 0x71A8, 0xBCF7,
+	0x71A9, 0xE668, 0x71AA, 0xE66F, 0x71AC, 0xBCF5, 0x71AF, 0xE663,
+	0x71B0, 0xE665, 0x71B1, 0xBCF6, 0x71B2, 0xE662, 0x71B3, 0xE672,
+	0x71B5, 0xE669, 0x71B8, 0xEA4A, 0x71B9, 0xBF51, 0x71BC, 0xEA55,
+	0x71BD, 0xEA53, 0x71BE, 0xBF4B, 0x71BF, 0xEA49, 0x71C0, 0xEA4C,
+	0x71C1, 0xEA4D, 0x71C2, 0xEA48, 0x71C3, 0xBF55, 0x71C4, 0xBF56,
+	0x71C5, 0xEA47, 0x71C6, 0xEA56, 0x71C7, 0xEA51, 0x71C8, 0xBF4F,
+	0x71C9, 0xBF4C, 0x71CA, 0xEA50, 0x71CB, 0xEA4E, 0x71CE, 0xBF52,
+	0x71CF, 0xEA52, 0x71D0, 0xBF4D, 0x71D2, 0xBF4E, 0x71D4, 0xEA4F,
+	0x71D5, 0xBF50, 0x71D6, 0xEA4B, 0x71D8, 0xEA54, 0x71D9, 0xBF53,
+	0x71DA, 0xEA57, 0x71DB, 0xEA58, 0x71DC, 0xBF54, 0x71DF, 0xC0E7,
+	0x71E0, 0xC0EE, 0x71E1, 0xED5C, 0x71E2, 0xED62, 0x71E4, 0xED60,
+	0x71E5, 0xC0EA, 0x71E6, 0xC0E9, 0x71E7, 0xC0E6, 0x71E8, 0xED5E,
+	0x71EC, 0xC0EC, 0x71ED, 0xC0EB, 0x71EE, 0xC0E8, 0x71F0, 0xED61,
+	0x71F1, 0xED5D, 0x71F2, 0xED5F, 0x71F4, 0xC0ED, 0x71F8, 0xC277,
+	0x71F9, 0xEFFB, 0x71FB, 0xC274, 0x71FC, 0xC275, 0x71FD, 0xEFFD,
+	0x71FE, 0xC276, 0x71FF, 0xEFFA, 0x7201, 0xEFF9, 0x7202, 0xF26C,
+	0x7203, 0xEFFC, 0x7205, 0xF26D, 0x7206, 0xC37A, 0x7207, 0xF26B,
+	0x720A, 0xF26A, 0x720C, 0xF269, 0x720D, 0xC37B, 0x7210, 0xC46C,
+	0x7213, 0xF46A, 0x7214, 0xF46B, 0x7219, 0xF5DC, 0x721A, 0xF5DB,
+	0x721B, 0xC4EA, 0x721D, 0xF5DA, 0x721E, 0xF6EC, 0x721F, 0xF6ED,
+	0x7222, 0xF7E6, 0x7223, 0xF8B1, 0x7226, 0xF8F6, 0x7227, 0xF9BC,
+	0x7228, 0xC679, 0x7229, 0xF9C6, 0x722A, 0xA4F6, 0x722C, 0xAAA6,
+	0x722D, 0xAAA7, 0x7230, 0xACB8, 0x7235, 0xC0EF, 0x7236, 0xA4F7,
+	0x7238, 0xAAA8, 0x7239, 0xAF52, 0x723A, 0xB7DD, 0x723B, 0xA4F8,
+	0x723D, 0xB26E, 0x723E, 0xBAB8, 0x723F, 0xC962, 0x7241, 0xCFB7,
+	0x7242, 0xD27D, 0x7244, 0xE2C5, 0x7246, 0xC0F0, 0x7247, 0xA4F9,
+	0x7248, 0xAAA9, 0x7249, 0xCFB8, 0x724A, 0xCFB9, 0x724B, 0xDA66,
+	0x724C, 0xB550, 0x724F, 0xDEA4, 0x7252, 0xB7DE, 0x7253, 0xE2C6,
+	0x7256, 0xBCF8, 0x7258, 0xC37C, 0x7259, 0xA4FA, 0x725A, 0xDA67,
+	0x725B, 0xA4FB, 0x725D, 0xA6C9, 0x725E, 0xCA42, 0x725F, 0xA6C8,
+	0x7260, 0xA865, 0x7261, 0xA864, 0x7262, 0xA863, 0x7263, 0xCB60,
+	0x7267, 0xAAAA, 0x7269, 0xAAAB, 0x726A, 0xCD5B, 0x726C, 0xCFBA,
+	0x726E, 0xCFBD, 0x726F, 0xACBA, 0x7270, 0xCFBB, 0x7272, 0xACB9,
+	0x7273, 0xCFBC, 0x7274, 0xACBB, 0x7276, 0xD2A2, 0x7277, 0xD2A1,
+	0x7278, 0xD27E, 0x7279, 0xAF53, 0x727B, 0xD65D, 0x727C, 0xD65E,
+	0x727D, 0xB26F, 0x727E, 0xD65C, 0x727F, 0xD65F, 0x7280, 0xB552,
+	0x7281, 0xB270, 0x7284, 0xB551, 0x7285, 0xDA6B, 0x7286, 0xDA6A,
+	0x7288, 0xDA68, 0x7289, 0xDA69, 0x728B, 0xDA6C, 0x728C, 0xDEA6,
+	0x728D, 0xDEA5, 0x728E, 0xDEA9, 0x7290, 0xDEA8, 0x7291, 0xDEA7,
+	0x7292, 0xBAB9, 0x7293, 0xE2C9, 0x7295, 0xE2C8, 0x7296, 0xBABA,
+	0x7297, 0xE2C7, 0x7298, 0xE673, 0x729A, 0xE674, 0x729B, 0xBCF9,
+	0x729D, 0xEA59, 0x729E, 0xEA5A, 0x72A1, 0xF272, 0x72A2, 0xC37D,
+	0x72A3, 0xF271, 0x72A4, 0xF270, 0x72A5, 0xF26E, 0x72A6, 0xF26F,
+	0x72A7, 0xC4EB, 0x72A8, 0xF46C, 0x72A9, 0xF6EE, 0x72AA, 0xF8F7,
+	0x72AC, 0xA4FC, 0x72AE, 0xC9A5, 0x72AF, 0xA5C7, 0x72B0, 0xC9A6,
+	0x72B4, 0xCA43, 0x72B5, 0xCA44, 0x72BA, 0xCB66, 0x72BD, 0xCB62,
+	0x72BF, 0xCB61, 0x72C0, 0xAAAC, 0x72C1, 0xCB65, 0x72C2, 0xA867,
+	0x72C3, 0xCB63, 0x72C4, 0xA866, 0x72C5, 0xCB67, 0x72C6, 0xCB64,
+	0x72C9, 0xCD5F, 0x72CA, 0xCFBE, 0x72CB, 0xCD5D, 0x72CC, 0xCD64,
+	0x72CE, 0xAAAD, 0x72D0, 0xAAB0, 0x72D1, 0xCD65, 0x72D2, 0xCD61,
+	0x72D4, 0xCD62, 0x72D6, 0xCD5C, 0x72D7, 0xAAAF, 0x72D8, 0xCD5E,
+	0x72D9, 0xAAAE, 0x72DA, 0xCD63, 0x72DC, 0xCD60, 0x72DF, 0xCFC2,
+	0x72E0, 0xACBD, 0x72E1, 0xACBE, 0x72E3, 0xCFC5, 0x72E4, 0xCFBF,
+	0x72E6, 0xCFC4, 0x72E8, 0xCFC0, 0x72E9, 0xACBC, 0x72EA, 0xCFC3,
+	0x72EB, 0xCFC1, 0x72F3, 0xD2A8, 0x72F4, 0xD2A5, 0x72F6, 0xD2A7,
+	0x72F7, 0xAF58, 0x72F8, 0xAF57, 0x72F9, 0xAF55, 0x72FA, 0xD2A4,
+	0x72FB, 0xD2A9, 0x72FC, 0xAF54, 0x72FD, 0xAF56, 0x72FE, 0xD2A6,
+	0x72FF, 0xD667, 0x7300, 0xD2A3, 0x7301, 0xD2AA, 0x7307, 0xD662,
+	0x7308, 0xD666, 0x730A, 0xD665, 0x730B, 0xDA6E, 0x730C, 0xDA79,
+	0x730F, 0xD668, 0x7311, 0xD663, 0x7312, 0xDA6D, 0x7313, 0xB274,
+	0x7316, 0xB273, 0x7317, 0xD661, 0x7318, 0xD664, 0x7319, 0xB275,
+	0x731B, 0xB272, 0x731C, 0xB271, 0x731D, 0xD660, 0x731E, 0xD669,
+	0x7322, 0xDA70, 0x7323, 0xDA77, 0x7325, 0xB554, 0x7326, 0xDA76,
+	0x7327, 0xDA73, 0x7329, 0xB556, 0x732D, 0xDA75, 0x7330, 0xDA6F,
+	0x7331, 0xDA71, 0x7332, 0xDA74, 0x7333, 0xDA72, 0x7334, 0xB555,
+	0x7335, 0xDA78, 0x7336, 0xB553, 0x7337, 0xB7DF, 0x733A, 0xDEAD,
+	0x733B, 0xDEAC, 0x733C, 0xDEAA, 0x733E, 0xB7E2, 0x733F, 0xB7E1,
+	0x7340, 0xDEAE, 0x7342, 0xDEAB, 0x7343, 0xE2CA, 0x7344, 0xBABB,
+	0x7345, 0xB7E0, 0x7349, 0xDEB0, 0x734A, 0xDEAF, 0x734C, 0xE2CD,
+	0x734D, 0xE2CB, 0x734E, 0xBCFA, 0x7350, 0xBABC, 0x7351, 0xE2CC,
+	0x7352, 0xE676, 0x7357, 0xBCFB, 0x7358, 0xE675, 0x7359, 0xE67E,
+	0x735A, 0xE67D, 0x735B, 0xE67B, 0x735D, 0xE67A, 0x735E, 0xE677,
+	0x735F, 0xE678, 0x7360, 0xE679, 0x7361, 0xE67C, 0x7362, 0xE6A1,
+	0x7365, 0xEA5F, 0x7366, 0xEA5C, 0x7367, 0xEA5D, 0x7368, 0xBF57,
+	0x7369, 0xEA5B, 0x736A, 0xEA61, 0x736B, 0xEA60, 0x736C, 0xEA5E,
+	0x736E, 0xED64, 0x736F, 0xED65, 0x7370, 0xC0F1, 0x7372, 0xC0F2,
+	0x7373, 0xED63, 0x7375, 0xC279, 0x7376, 0xEFFE, 0x7377, 0xC278,
+	0x7378, 0xC37E, 0x737A, 0xC3A1, 0x737B, 0xC46D, 0x737C, 0xF46E,
+	0x737D, 0xF46D, 0x737E, 0xF5DD, 0x737F, 0xF6EF, 0x7380, 0xC57A,
+	0x7381, 0xF7E8, 0x7382, 0xF7E7, 0x7383, 0xF7E9, 0x7384, 0xA5C8,
+	0x7385, 0xCFC6, 0x7386, 0xAF59, 0x7387, 0xB276, 0x7388, 0xD66A,
+	0x7389, 0xA5C9, 0x738A, 0xC9A7, 0x738B, 0xA4FD, 0x738E, 0xCA45,
+	0x7392, 0xCB6C, 0x7393, 0xCB6A, 0x7394, 0xCB6B, 0x7395, 0xCB68,
+	0x7396, 0xA868, 0x7397, 0xCB69, 0x739D, 0xCD6D, 0x739F, 0xAAB3,
+	0x73A0, 0xCD6B, 0x73A1, 0xCD67, 0x73A2, 0xCD6A, 0x73A4, 0xCD66,
+	0x73A5, 0xAAB5, 0x73A6, 0xCD69, 0x73A8, 0xAAB2, 0x73A9, 0xAAB1,
+	0x73AB, 0xAAB4, 0x73AC, 0xCD6C, 0x73AD, 0xCD68, 0x73B2, 0xACC2,
+	0x73B3, 0xACC5, 0x73B4, 0xCFCE, 0x73B5, 0xCFCD, 0x73B6, 0xCFCC,
+	0x73B7, 0xACBF, 0x73B8, 0xCFD5, 0x73B9, 0xCFCB, 0x73BB, 0xACC1,
+	0x73BC, 0xD2AF, 0x73BE, 0xCFD2, 0x73BF, 0xCFD0, 0x73C0, 0xACC4,
+	0x73C2, 0xCFC8, 0x73C3, 0xCFD3, 0x73C5, 0xCFCA, 0x73C6, 0xCFD4,
+	0x73C7, 0xCFD1, 0x73C8, 0xCFC9, 0x73CA, 0xACC0, 0x73CB, 0xCFD6,
+	0x73CC, 0xCFC7, 0x73CD, 0xACC3, 0x73D2, 0xD2B4, 0x73D3, 0xD2AB,
+	0x73D4, 0xD2B6, 0x73D6, 0xD2AE, 0x73D7, 0xD2B9, 0x73D8, 0xD2BA,
+	0x73D9, 0xD2AC, 0x73DA, 0xD2B8, 0x73DB, 0xD2B5, 0x73DC, 0xD2B3,
+	0x73DD, 0xD2B7, 0x73DE, 0xAF5F, 0x73E0, 0xAF5D, 0x73E3, 0xD2B1,
+	0x73E5, 0xD2AD, 0x73E7, 0xD2B0, 0x73E8, 0xD2BB, 0x73E9, 0xD2B2,
+	0x73EA, 0xAF5E, 0x73EB, 0xCFCF, 0x73ED, 0xAF5A, 0x73EE, 0xAF5C,
+	0x73F4, 0xD678, 0x73F5, 0xD66D, 0x73F6, 0xD66B, 0x73F8, 0xD66C,
+	0x73FA, 0xD673, 0x73FC, 0xD674, 0x73FD, 0xD670, 0x73FE, 0xB27B,
+	0x73FF, 0xD675, 0x7400, 0xD672, 0x7401, 0xD66F, 0x7403, 0xB279,
+	0x7404, 0xD66E, 0x7405, 0xB277, 0x7406, 0xB27A, 0x7407, 0xD671,
+	0x7408, 0xD679, 0x7409, 0xAF5B, 0x740A, 0xB278, 0x740B, 0xD677,
+	0x740C, 0xD676, 0x740D, 0xB27C, 0x7416, 0xDA7E, 0x741A, 0xDAA1,
+	0x741B, 0xB560, 0x741D, 0xDAA7, 0x7420, 0xDAA9, 0x7421, 0xDAA2,
+	0x7422, 0xB55A, 0x7423, 0xDAA6, 0x7424, 0xDAA5, 0x7425, 0xB55B,
+	0x7426, 0xB561, 0x7428, 0xB562, 0x7429, 0xDAA8, 0x742A, 0xB558,
+	0x742B, 0xDA7D, 0x742C, 0xDA7B, 0x742D, 0xDAA3, 0x742E, 0xDA7A,
+	0x742F, 0xB55F, 0x7430, 0xDA7C, 0x7431, 0xDAA4, 0x7432, 0xDAAA,
+	0x7433, 0xB559, 0x7434, 0xB55E, 0x7435, 0xB55C, 0x7436, 0xB55D,
+	0x743A, 0xB557, 0x743F, 0xB7E9, 0x7440, 0xDEB7, 0x7441, 0xB7E8,
+	0x7442, 0xDEBB, 0x7444, 0xDEB1, 0x7446, 0xDEBC, 0x744A, 0xDEB2,
+	0x744B, 0xDEB3, 0x744D, 0xDEBD, 0x744E, 0xDEBA, 0x744F, 0xDEB8,
+	0x7450, 0xDEB9, 0x7451, 0xDEB5, 0x7452, 0xDEB4, 0x7454, 0xDEBE,
+	0x7455, 0xB7E5, 0x7457, 0xDEB6, 0x7459, 0xB7EA, 0x745A, 0xB7E4,
+	0x745B, 0xB7EB, 0x745C, 0xB7EC, 0x745E, 0xB7E7, 0x745F, 0xB7E6,
+	0x7462, 0xE2CE, 0x7463, 0xBABE, 0x7464, 0xBABD, 0x7467, 0xE2D3,
+	0x7469, 0xBCFC, 0x746A, 0xBABF, 0x746D, 0xBAC1, 0x746E, 0xE2D4,
+	0x746F, 0xB7E3, 0x7470, 0xBAC0, 0x7471, 0xE2D0, 0x7472, 0xE2D2,
+	0x7473, 0xE2CF, 0x7475, 0xE2D1, 0x7479, 0xE6AB, 0x747C, 0xE6AA,
+	0x747D, 0xE6A7, 0x747E, 0xBD40, 0x747F, 0xEA62, 0x7480, 0xBD41,
+	0x7481, 0xE6A6, 0x7483, 0xBCFE, 0x7485, 0xE6A8, 0x7486, 0xE6A5,
+	0x7487, 0xE6A2, 0x7488, 0xE6A9, 0x7489, 0xE6A3, 0x748A, 0xE6A4,
+	0x748B, 0xBCFD, 0x7490, 0xED69, 0x7492, 0xEA66, 0x7494, 0xEA65,
+	0x7495, 0xEA67, 0x7497, 0xED66, 0x7498, 0xBF5A, 0x749A, 0xEA63,
+	0x749C, 0xBF58, 0x749E, 0xBF5C, 0x749F, 0xBF5B, 0x74A0, 0xEA64,
+	0x74A1, 0xEA68, 0x74A3, 0xBF59, 0x74A5, 0xED6D, 0x74A6, 0xC0F5,
+	0x74A7, 0xC27A, 0x74A8, 0xC0F6, 0x74A9, 0xC0F3, 0x74AA, 0xED6A,
+	0x74AB, 0xED68, 0x74AD, 0xED6B, 0x74AF, 0xED6E, 0x74B0, 0xC0F4,
+	0x74B1, 0xED6C, 0x74B2, 0xED67, 0x74B5, 0xF042, 0x74B6, 0xF045,
+	0x74B7, 0xF275, 0x74B8, 0xF040, 0x74BA, 0xF46F, 0x74BB, 0xF046,
+	0x74BD, 0xC3A2, 0x74BE, 0xF044, 0x74BF, 0xC27B, 0x74C0, 0xF041,
+	0x74C1, 0xF043, 0x74C2, 0xF047, 0x74C3, 0xF276, 0x74C5, 0xF274,
+	0x74CA, 0xC3A3, 0x74CB, 0xF273, 0x74CF, 0xC46E, 0x74D4, 0xC4ED,
+	0x74D5, 0xF6F1, 0x74D6, 0xC4EC, 0x74D7, 0xF6F3, 0x74D8, 0xF6F0,
+	0x74D9, 0xF6F2, 0x74DA, 0xC5D0, 0x74DB, 0xF8B2, 0x74DC, 0xA5CA,
+	0x74DD, 0xCD6E, 0x74DE, 0xD2BC, 0x74DF, 0xD2BD, 0x74E0, 0xB27D,
+	0x74E1, 0xDEBF, 0x74E2, 0xBF5D, 0x74E3, 0xC3A4, 0x74E4, 0xC57B,
+	0x74E5, 0xF8B3, 0x74E6, 0xA5CB, 0x74E8, 0xCD6F, 0x74E9, 0xA260,
+	0x74EC, 0xCFD7, 0x74EE, 0xCFD8, 0x74F4, 0xD2BE, 0x74F5, 0xD2BF,
+	0x74F6, 0xB27E, 0x74F7, 0xB2A1, 0x74FB, 0xDAAB, 0x74FD, 0xDEC2,
+	0x74FE, 0xDEC1, 0x74FF, 0xDEC0, 0x7500, 0xE2D5, 0x7502, 0xE2D6,
+	0x7503, 0xE2D7, 0x7504, 0xBAC2, 0x7507, 0xE6AD, 0x7508, 0xE6AC,
+	0x750B, 0xEA69, 0x750C, 0xBF5E, 0x750D, 0xBF5F, 0x750F, 0xED72,
+	0x7510, 0xED6F, 0x7511, 0xED70, 0x7512, 0xED71, 0x7513, 0xF049,
+	0x7514, 0xF048, 0x7515, 0xC27C, 0x7516, 0xF277, 0x7517, 0xF5DE,
+	0x7518, 0xA5CC, 0x751A, 0xACC6, 0x751C, 0xB2A2, 0x751D, 0xDEC3,
+	0x751F, 0xA5CD, 0x7521, 0xD2C0, 0x7522, 0xB2A3, 0x7525, 0xB563,
+	0x7526, 0xB564, 0x7528, 0xA5CE, 0x7529, 0xA5CF, 0x752A, 0xCA46,
+	0x752B, 0xA86A, 0x752C, 0xA869, 0x752D, 0xACC7, 0x752E, 0xCFD9,
+	0x752F, 0xDAAC, 0x7530, 0xA5D0, 0x7531, 0xA5D1, 0x7532, 0xA5D2,
+	0x7533, 0xA5D3, 0x7537, 0xA86B, 0x7538, 0xA86C, 0x7539, 0xCB6E,
+	0x753A, 0xCB6D, 0x753D, 0xAAB6, 0x753E, 0xCD72, 0x753F, 0xCD70,
+	0x7540, 0xCD71, 0x7547, 0xCFDA, 0x7548, 0xCFDB, 0x754B, 0xACCB,
+	0x754C, 0xACC9, 0x754E, 0xACCA, 0x754F, 0xACC8, 0x7554, 0xAF60,
+	0x7559, 0xAF64, 0x755A, 0xAF63, 0x755B, 0xD2C1, 0x755C, 0xAF62,
+	0x755D, 0xAF61, 0x755F, 0xD2C2, 0x7562, 0xB2A6, 0x7563, 0xD67B,
+	0x7564, 0xD67A, 0x7565, 0xB2A4, 0x7566, 0xB2A5, 0x756A, 0xB566,
+	0x756B, 0xB565, 0x756C, 0xDAAE, 0x756F, 0xDAAD, 0x7570, 0xB2A7,
+	0x7576, 0xB7ED, 0x7577, 0xDEC5, 0x7578, 0xB7EE, 0x7579, 0xDEC4,
+	0x757D, 0xE2D8, 0x757E, 0xE6AE, 0x757F, 0xBD42, 0x7580, 0xEA6A,
+	0x7584, 0xED73, 0x7586, 0xC3A6, 0x7587, 0xC3A5, 0x758A, 0xC57C,
+	0x758B, 0xA5D4, 0x758C, 0xCD73, 0x758F, 0xB2A8, 0x7590, 0xE2D9,
+	0x7591, 0xBAC3, 0x7594, 0xCB6F, 0x7595, 0xCB70, 0x7598, 0xCD74,
+	0x7599, 0xAAB8, 0x759A, 0xAAB9, 0x759D, 0xAAB7, 0x75A2, 0xACCF,
+	0x75A3, 0xACD0, 0x75A4, 0xACCD, 0x75A5, 0xACCE, 0x75A7, 0xCFDC,
+	0x75AA, 0xCFDD, 0x75AB, 0xACCC, 0x75B0, 0xD2C3, 0x75B2, 0xAF68,
+	0x75B3, 0xAF69, 0x75B5, 0xB2AB, 0x75B6, 0xD2C9, 0x75B8, 0xAF6E,
+	0x75B9, 0xAF6C, 0x75BA, 0xD2CA, 0x75BB, 0xD2C5, 0x75BC, 0xAF6B,
+	0x75BD, 0xAF6A, 0x75BE, 0xAF65, 0x75BF, 0xD2C8, 0x75C0, 0xD2C7,
+	0x75C1, 0xD2C4, 0x75C2, 0xAF6D, 0x75C4, 0xD2C6, 0x75C5, 0xAF66,
+	0x75C7, 0xAF67, 0x75CA, 0xB2AC, 0x75CB, 0xD6A1, 0x75CC, 0xD6A2,
+	0x75CD, 0xB2AD, 0x75CE, 0xD67C, 0x75CF, 0xD67E, 0x75D0, 0xD6A4,
+	0x75D1, 0xD6A3, 0x75D2, 0xD67D, 0x75D4, 0xB2A9, 0x75D5, 0xB2AA,
+	0x75D7, 0xDAB6, 0x75D8, 0xB56B, 0x75D9, 0xB56A, 0x75DA, 0xDAB0,
+	0x75DB, 0xB568, 0x75DD, 0xDAB3, 0x75DE, 0xB56C, 0x75DF, 0xDAB4,
+	0x75E0, 0xB56D, 0x75E1, 0xDAB1, 0x75E2, 0xB567, 0x75E3, 0xB569,
+	0x75E4, 0xDAB5, 0x75E6, 0xDAB2, 0x75E7, 0xDAAF, 0x75ED, 0xDED2,
+	0x75EF, 0xDEC7, 0x75F0, 0xB7F0, 0x75F1, 0xB7F3, 0x75F2, 0xB7F2,
+	0x75F3, 0xB7F7, 0x75F4, 0xB7F6, 0x75F5, 0xDED3, 0x75F6, 0xDED1,
+	0x75F7, 0xDECA, 0x75F8, 0xDECE, 0x75F9, 0xDECD, 0x75FA, 0xB7F4,
+	0x75FB, 0xDED0, 0x75FC, 0xDECC, 0x75FD, 0xDED4, 0x75FE, 0xDECB,
+	0x75FF, 0xB7F5, 0x7600, 0xB7EF, 0x7601, 0xB7F1, 0x7603, 0xDEC9,
+	0x7608, 0xE2DB, 0x7609, 0xBAC7, 0x760A, 0xE2DF, 0x760B, 0xBAC6,
+	0x760C, 0xE2DC, 0x760D, 0xBAC5, 0x760F, 0xDEC8, 0x7610, 0xDECF,
+	0x7611, 0xE2DE, 0x7613, 0xBAC8, 0x7614, 0xE2E0, 0x7615, 0xE2DD,
+	0x7616, 0xE2DA, 0x7619, 0xE6B1, 0x761A, 0xE6B5, 0x761B, 0xE6B7,
+	0x761C, 0xE6B3, 0x761D, 0xE6B2, 0x761E, 0xE6B0, 0x761F, 0xBD45,
+	0x7620, 0xBD43, 0x7621, 0xBD48, 0x7622, 0xBD49, 0x7623, 0xE6B4,
+	0x7624, 0xBD46, 0x7625, 0xE6AF, 0x7626, 0xBD47, 0x7627, 0xBAC4,
+	0x7628, 0xE6B6, 0x7629, 0xBD44, 0x762D, 0xEA6C, 0x762F, 0xEA6B,
+	0x7630, 0xEA73, 0x7631, 0xEA6D, 0x7632, 0xEA72, 0x7633, 0xEA6F,
+	0x7634, 0xBF60, 0x7635, 0xEA71, 0x7638, 0xBF61, 0x763A, 0xBF62,
+	0x763C, 0xEA70, 0x763D, 0xEA6E, 0x7642, 0xC0F8, 0x7643, 0xED74,
+	0x7646, 0xC0F7, 0x7647, 0xED77, 0x7648, 0xED75, 0x7649, 0xED76,
+	0x764C, 0xC0F9, 0x7650, 0xF04D, 0x7652, 0xC2A1, 0x7653, 0xF04E,
+	0x7656, 0xC27D, 0x7657, 0xF04F, 0x7658, 0xC27E, 0x7659, 0xF04C,
+	0x765A, 0xF050, 0x765C, 0xF04A, 0x765F, 0xC3A7, 0x7660, 0xF278,
+	0x7661, 0xC3A8, 0x7662, 0xC46F, 0x7664, 0xF04B, 0x7665, 0xC470,
+	0x7669, 0xC4EE, 0x766A, 0xF5DF, 0x766C, 0xC57E, 0x766D, 0xF6F4,
+	0x766E, 0xC57D, 0x7670, 0xF7EA, 0x7671, 0xC5F5, 0x7672, 0xC5F6,
+	0x7675, 0xF9CC, 0x7678, 0xACD1, 0x7679, 0xCFDE, 0x767B, 0xB56E,
+	0x767C, 0xB56F, 0x767D, 0xA5D5, 0x767E, 0xA6CA, 0x767F, 0xCA47,
+	0x7681, 0xCB71, 0x7682, 0xA86D, 0x7684, 0xAABA, 0x7686, 0xACD2,
+	0x7687, 0xACD3, 0x7688, 0xACD4, 0x7689, 0xD6A6, 0x768A, 0xD2CB,
+	0x768B, 0xAF6F, 0x768E, 0xB2AE, 0x768F, 0xD6A5, 0x7692, 0xDAB8,
+	0x7693, 0xB571, 0x7695, 0xDAB7, 0x7696, 0xB570, 0x7699, 0xDED5,
+	0x769A, 0xBD4A, 0x769B, 0xE6BB, 0x769C, 0xE6B8, 0x769D, 0xE6B9,
+	0x769E, 0xE6BA, 0x76A4, 0xED78, 0x76A6, 0xF051, 0x76AA, 0xF471,
+	0x76AB, 0xF470, 0x76AD, 0xF6F5, 0x76AE, 0xA5D6, 0x76AF, 0xCD75,
+	0x76B0, 0xAF70, 0x76B4, 0xB572, 0x76B5, 0xDED6, 0x76B8, 0xE2E1,
+	0x76BA, 0xBD4B, 0x76BB, 0xEA74, 0x76BD, 0xF052, 0x76BE, 0xF472,
+	0x76BF, 0xA5D7, 0x76C2, 0xAABB, 0x76C3, 0xACD7, 0x76C4, 0xCFDF,
+	0x76C5, 0xACD8, 0x76C6, 0xACD6, 0x76C8, 0xACD5, 0x76C9, 0xD2CC,
+	0x76CA, 0xAF71, 0x76CD, 0xAF72, 0x76CE, 0xAF73, 0x76D2, 0xB2B0,
+	0x76D3, 0xD6A7, 0x76D4, 0xB2AF, 0x76DA, 0xDAB9, 0x76DB, 0xB2B1,
+	0x76DC, 0xB573, 0x76DD, 0xDED7, 0x76DE, 0xB7F8, 0x76DF, 0xB7F9,
+	0x76E1, 0xBAC9, 0x76E3, 0xBACA, 0x76E4, 0xBD4C, 0x76E5, 0xBF64,
+	0x76E6, 0xEA75, 0x76E7, 0xBF63, 0x76E9, 0xED79, 0x76EA, 0xC0FA,
+	0x76EC, 0xF053, 0x76ED, 0xF473, 0x76EE, 0xA5D8, 0x76EF, 0xA86E,
+	0x76F0, 0xCD78, 0x76F1, 0xCD77, 0x76F2, 0xAABC, 0x76F3, 0xCD76,
+	0x76F4, 0xAABD, 0x76F5, 0xCD79, 0x76F7, 0xCFE5, 0x76F8, 0xACDB,
+	0x76F9, 0xACDA, 0x76FA, 0xCFE7, 0x76FB, 0xCFE6, 0x76FC, 0xACDF,
+	0x76FE, 0xACDE, 0x7701, 0xACD9, 0x7703, 0xCFE1, 0x7704, 0xCFE2,
+	0x7705, 0xCFE3, 0x7707, 0xACE0, 0x7708, 0xCFE0, 0x7709, 0xACDC,
+	0x770A, 0xCFE4, 0x770B, 0xACDD, 0x7710, 0xD2CF, 0x7711, 0xD2D3,
+	0x7712, 0xD2D1, 0x7713, 0xD2D0, 0x7715, 0xD2D4, 0x7719, 0xD2D5,
+	0x771A, 0xD2D6, 0x771B, 0xD2CE, 0x771D, 0xD2CD, 0x771F, 0xAF75,
+	0x7720, 0xAF76, 0x7722, 0xD2D7, 0x7723, 0xD2D2, 0x7725, 0xD6B0,
+	0x7727, 0xD2D8, 0x7728, 0xAF77, 0x7729, 0xAF74, 0x772D, 0xD6AA,
+	0x772F, 0xD6A9, 0x7731, 0xD6AB, 0x7732, 0xD6AC, 0x7733, 0xD6AE,
+	0x7734, 0xD6AD, 0x7735, 0xD6B2, 0x7736, 0xB2B5, 0x7737, 0xB2B2,
+	0x7738, 0xB2B6, 0x7739, 0xD6A8, 0x773A, 0xB2B7, 0x773B, 0xD6B1,
+	0x773C, 0xB2B4, 0x773D, 0xD6AF, 0x773E, 0xB2B3, 0x7744, 0xDABC,
+	0x7745, 0xDABE, 0x7746, 0xDABA, 0x7747, 0xDABB, 0x774A, 0xDABF,
+	0x774B, 0xDAC1, 0x774C, 0xDAC2, 0x774D, 0xDABD, 0x774E, 0xDAC0,
+	0x774F, 0xB574, 0x7752, 0xDEDB, 0x7754, 0xDEE0, 0x7755, 0xDED8,
+	0x7756, 0xDEDC, 0x7759, 0xDEE1, 0x775A, 0xDEDD, 0x775B, 0xB7FA,
+	0x775C, 0xB843, 0x775E, 0xB7FD, 0x775F, 0xDED9, 0x7760, 0xDEDA,
+	0x7761, 0xBACE, 0x7762, 0xB846, 0x7763, 0xB7FE, 0x7765, 0xB844,
+	0x7766, 0xB7FC, 0x7767, 0xDEDF, 0x7768, 0xB845, 0x7769, 0xDEDE,
+	0x776A, 0xB841, 0x776B, 0xB7FB, 0x776C, 0xB842, 0x776D, 0xDEE2,
+	0x776E, 0xE2E6, 0x776F, 0xE2E8, 0x7779, 0xB840, 0x777C, 0xE2E3,
+	0x777D, 0xBACC, 0x777E, 0xE2E9, 0x777F, 0xBACD, 0x7780, 0xE2E7,
+	0x7781, 0xE2E2, 0x7782, 0xE2E5, 0x7783, 0xE2EA, 0x7784, 0xBACB,
+	0x7785, 0xE2E4, 0x7787, 0xBD4E, 0x7788, 0xE6BF, 0x7789, 0xE6BE,
+	0x778B, 0xBD51, 0x778C, 0xBD4F, 0x778D, 0xE6BC, 0x778E, 0xBD4D,
+	0x778F, 0xE6BD, 0x7791, 0xBD50, 0x7795, 0xEA7D, 0x7797, 0xEAA1,
+	0x7799, 0xEA7E, 0x779A, 0xEA76, 0x779B, 0xEA7A, 0x779C, 0xEA79,
+	0x779D, 0xEA77, 0x779E, 0xBF66, 0x779F, 0xBF67, 0x77A0, 0xBF65,
+	0x77A1, 0xEA78, 0x77A2, 0xEA7B, 0x77A3, 0xEA7C, 0x77A5, 0xBF68,
+	0x77A7, 0xC140, 0x77A8, 0xEDA3, 0x77AA, 0xC0FC, 0x77AB, 0xED7B,
+	0x77AC, 0xC0FE, 0x77AD, 0xC141, 0x77B0, 0xC0FD, 0x77B1, 0xEDA2,
+	0x77B2, 0xED7C, 0x77B3, 0xC0FB, 0x77B4, 0xEDA1, 0x77B5, 0xED7A,
+	0x77B6, 0xED7E, 0x77B7, 0xED7D, 0x77BA, 0xF055, 0x77BB, 0xC2A4,
+	0x77BC, 0xC2A5, 0x77BD, 0xC2A2, 0x77BF, 0xC2A3, 0x77C2, 0xF054,
+	0x77C4, 0xF27B, 0x77C7, 0xC3A9, 0x77C9, 0xF279, 0x77CA, 0xF27A,
+	0x77CC, 0xF474, 0x77CD, 0xF477, 0x77CE, 0xF475, 0x77CF, 0xF476,
+	0x77D0, 0xF5E0, 0x77D3, 0xC4EF, 0x77D4, 0xF7EB, 0x77D5, 0xF8B4,
+	0x77D7, 0xC5F7, 0x77D8, 0xF8F8, 0x77D9, 0xF8F9, 0x77DA, 0xC666,
+	0x77DB, 0xA5D9, 0x77DC, 0xACE1, 0x77DE, 0xDAC3, 0x77E0, 0xDEE3,
+	0x77E2, 0xA5DA, 0x77E3, 0xA86F, 0x77E5, 0xAABE, 0x77E7, 0xCFE8,
+	0x77E8, 0xCFE9, 0x77E9, 0xAF78, 0x77EC, 0xDAC4, 0x77ED, 0xB575,
+	0x77EE, 0xB847, 0x77EF, 0xC142, 0x77F0, 0xEDA4, 0x77F1, 0xF27C,
+	0x77F2, 0xF478, 0x77F3, 0xA5DB, 0x77F7, 0xCDA1, 0x77F8, 0xCD7A,
+	0x77F9, 0xCD7C, 0x77FA, 0xCD7E, 0x77FB, 0xCD7D, 0x77FC, 0xCD7B,
+	0x77FD, 0xAABF, 0x7802, 0xACE2, 0x7803, 0xCFF2, 0x7805, 0xCFED,
+	0x7806, 0xCFEA, 0x7809, 0xCFF1, 0x780C, 0xACE4, 0x780D, 0xACE5,
+	0x780E, 0xCFF0, 0x780F, 0xCFEF, 0x7810, 0xCFEE, 0x7811, 0xCFEB,
+	0x7812, 0xCFEC, 0x7813, 0xCFF3, 0x7814, 0xACE3, 0x781D, 0xAF7C,
+	0x781F, 0xAFA4, 0x7820, 0xAFA3, 0x7821, 0xD2E1, 0x7822, 0xD2DB,
+	0x7823, 0xD2D9, 0x7825, 0xAFA1, 0x7826, 0xD6B9, 0x7827, 0xAF7A,
+	0x7828, 0xD2DE, 0x7829, 0xD2E2, 0x782A, 0xD2E4, 0x782B, 0xD2E0,
+	0x782C, 0xD2DA, 0x782D, 0xAFA2, 0x782E, 0xD2DF, 0x782F, 0xD2DD,
+	0x7830, 0xAF79, 0x7831, 0xD2E5, 0x7832, 0xAFA5, 0x7833, 0xD2E3,
+	0x7834, 0xAF7D, 0x7835, 0xD2DC, 0x7837, 0xAF7E, 0x7838, 0xAF7B,
+	0x7843, 0xB2B9, 0x7845, 0xD6BA, 0x7848, 0xD6B3, 0x7849, 0xD6B5,
+	0x784A, 0xD6B7, 0x784C, 0xD6B8, 0x784D, 0xD6B6, 0x784E, 0xB2BA,
+	0x7850, 0xD6BB, 0x7852, 0xD6B4, 0x785C, 0xDAC8, 0x785D, 0xB576,
+	0x785E, 0xDAD0, 0x7860, 0xDAC5, 0x7862, 0xDAD1, 0x7864, 0xDAC6,
+	0x7865, 0xDAC7, 0x7868, 0xDACF, 0x7869, 0xDACE, 0x786A, 0xDACB,
+	0x786B, 0xB2B8, 0x786C, 0xB577, 0x786D, 0xDAC9, 0x786E, 0xDACC,
+	0x786F, 0xB578, 0x7870, 0xDACD, 0x7871, 0xDACA, 0x7879, 0xDEEE,
+	0x787B, 0xDEF2, 0x787C, 0xB84E, 0x787E, 0xE2F0, 0x787F, 0xB851,
+	0x7880, 0xDEF0, 0x7881, 0xF9D6, 0x7883, 0xDEED, 0x7884, 0xDEE8,
+	0x7885, 0xDEEA, 0x7886, 0xDEEB, 0x7887, 0xDEE4, 0x7889, 0xB84D,
+	0x788C, 0xB84C, 0x788E, 0xB848, 0x788F, 0xDEE7, 0x7891, 0xB84F,
+	0x7893, 0xB850, 0x7894, 0xDEE6, 0x7895, 0xDEE9, 0x7896, 0xDEF1,
+	0x7897, 0xB84A, 0x7898, 0xB84B, 0x7899, 0xDEEF, 0x789A, 0xDEE5,
+	0x789E, 0xE2F2, 0x789F, 0xBAD0, 0x78A0, 0xE2F4, 0x78A1, 0xDEEC,
+	0x78A2, 0xE2F6, 0x78A3, 0xBAD4, 0x78A4, 0xE2F7, 0x78A5, 0xE2F3,
+	0x78A7, 0xBAD1, 0x78A8, 0xE2EF, 0x78A9, 0xBAD3, 0x78AA, 0xE2EC,
+	0x78AB, 0xE2F1, 0x78AC, 0xE2F5, 0x78AD, 0xE2EE, 0x78B0, 0xB849,
+	0x78B2, 0xE2EB, 0x78B3, 0xBAD2, 0x78B4, 0xE2ED, 0x78BA, 0xBD54,
+	0x78BB, 0xE6C1, 0x78BC, 0xBD58, 0x78BE, 0xBD56, 0x78C1, 0xBACF,
+	0x78C3, 0xE6C8, 0x78C4, 0xE6C9, 0x78C5, 0xBD53, 0x78C8, 0xE6C7,
+	0x78C9, 0xE6CA, 0x78CA, 0xBD55, 0x78CB, 0xBD52, 0x78CC, 0xE6C3,
+	0x78CD, 0xE6C0, 0x78CE, 0xE6C5, 0x78CF, 0xE6C2, 0x78D0, 0xBD59,
+	0x78D1, 0xE6C4, 0x78D4, 0xE6C6, 0x78D5, 0xBD57, 0x78DA, 0xBF6A,
+	0x78DB, 0xEAA8, 0x78DD, 0xEAA2, 0x78DE, 0xEAA6, 0x78DF, 0xEAAC,
+	0x78E0, 0xEAAD, 0x78E1, 0xEAA9, 0x78E2, 0xEAAA, 0x78E3, 0xEAA7,
+	0x78E5, 0xEAA4, 0x78E7, 0xBF6C, 0x78E8, 0xBF69, 0x78E9, 0xEAA3,
+	0x78EA, 0xEAA5, 0x78EC, 0xBF6B, 0x78ED, 0xEAAB, 0x78EF, 0xC146,
+	0x78F2, 0xEDAA, 0x78F3, 0xEDA5, 0x78F4, 0xC145, 0x78F7, 0xC143,
+	0x78F9, 0xEDAC, 0x78FA, 0xC144, 0x78FB, 0xEDA8, 0x78FC, 0xEDA9,
+	0x78FD, 0xEDA6, 0x78FE, 0xEDAD, 0x78FF, 0xF056, 0x7901, 0xC147,
+	0x7902, 0xEDA7, 0x7904, 0xEDAE, 0x7905, 0xEDAB, 0x7909, 0xF05A,
+	0x790C, 0xF057, 0x790E, 0xC2A6, 0x7910, 0xF05B, 0x7911, 0xF05D,
+	0x7912, 0xF05C, 0x7913, 0xF058, 0x7914, 0xF059, 0x7917, 0xF2A3,
+	0x7919, 0xC3AA, 0x791B, 0xF27E, 0x791C, 0xF2A2, 0x791D, 0xF27D,
+	0x791E, 0xF2A4, 0x7921, 0xF2A1, 0x7923, 0xF47A, 0x7924, 0xF47D,
+	0x7925, 0xF479, 0x7926, 0xC471, 0x7927, 0xF47B, 0x7928, 0xF47C,
+	0x7929, 0xF47E, 0x792A, 0xC472, 0x792B, 0xC474, 0x792C, 0xC473,
+	0x792D, 0xF5E1, 0x792F, 0xF5E3, 0x7931, 0xF5E2, 0x7935, 0xF6F6,
+	0x7938, 0xF8B5, 0x7939, 0xF8FA, 0x793A, 0xA5DC, 0x793D, 0xCB72,
+	0x793E, 0xAAC0, 0x793F, 0xCDA3, 0x7940, 0xAAC1, 0x7941, 0xAAC2,
+	0x7942, 0xCDA2, 0x7944, 0xCFF8, 0x7945, 0xCFF7, 0x7946, 0xACE6,
+	0x7947, 0xACE9, 0x7948, 0xACE8, 0x7949, 0xACE7, 0x794A, 0xCFF4,
+	0x794B, 0xCFF6, 0x794C, 0xCFF5, 0x794F, 0xD2E8, 0x7950, 0xAFA7,
+	0x7951, 0xD2EC, 0x7952, 0xD2EB, 0x7953, 0xD2EA, 0x7954, 0xD2E6,
+	0x7955, 0xAFA6, 0x7956, 0xAFAA, 0x7957, 0xAFAD, 0x795A, 0xAFAE,
+	0x795B, 0xD2E7, 0x795C, 0xD2E9, 0x795D, 0xAFAC, 0x795E, 0xAFAB,
+	0x795F, 0xAFA9, 0x7960, 0xAFA8, 0x7961, 0xD6C2, 0x7963, 0xD6C0,
+	0x7964, 0xD6BC, 0x7965, 0xB2BB, 0x7967, 0xD6BD, 0x7968, 0xB2BC,
+	0x7969, 0xD6BE, 0x796A, 0xD6BF, 0x796B, 0xD6C1, 0x796D, 0xB2BD,
+	0x7970, 0xDAD5, 0x7972, 0xDAD4, 0x7973, 0xDAD3, 0x7974, 0xDAD2,
+	0x7979, 0xDEF6, 0x797A, 0xB852, 0x797C, 0xDEF3, 0x797D, 0xDEF5,
+	0x797F, 0xB853, 0x7981, 0xB854, 0x7982, 0xDEF4, 0x7988, 0xE341,
+	0x798A, 0xE2F9, 0x798B, 0xE2FA, 0x798D, 0xBAD7, 0x798E, 0xBAD5,
+	0x798F, 0xBAD6, 0x7990, 0xE343, 0x7992, 0xE342, 0x7993, 0xE2FE,
+	0x7994, 0xE2FD, 0x7995, 0xE2FC, 0x7996, 0xE2FB, 0x7997, 0xE340,
+	0x7998, 0xE2F8, 0x799A, 0xE6CB, 0x799B, 0xE6D0, 0x799C, 0xE6CE,
+	0x79A0, 0xE6CD, 0x79A1, 0xE6CC, 0x79A2, 0xE6CF, 0x79A4, 0xEAAE,
+	0x79A6, 0xBF6D, 0x79A7, 0xC148, 0x79A8, 0xEDB0, 0x79AA, 0xC149,
+	0x79AB, 0xEDAF, 0x79AC, 0xF05F, 0x79AD, 0xF05E, 0x79AE, 0xC2A7,
+	0x79B0, 0xF2A5, 0x79B1, 0xC3AB, 0x79B2, 0xF4A1, 0x79B3, 0xC5A1,
+	0x79B4, 0xF6F7, 0x79B6, 0xF8B7, 0x79B7, 0xF8B6, 0x79B8, 0xC9A8,
+	0x79B9, 0xACEA, 0x79BA, 0xACEB, 0x79BB, 0xD6C3, 0x79BD, 0xB856,
+	0x79BE, 0xA5DD, 0x79BF, 0xA872, 0x79C0, 0xA871, 0x79C1, 0xA870,
+	0x79C5, 0xCDA4, 0x79C8, 0xAAC4, 0x79C9, 0xAAC3, 0x79CB, 0xACEE,
+	0x79CD, 0xCFFA, 0x79CE, 0xCFFD, 0x79CF, 0xCFFB, 0x79D1, 0xACEC,
+	0x79D2, 0xACED, 0x79D5, 0xCFF9, 0x79D6, 0xCFFC, 0x79D8, 0xAFB5,
+	0x79DC, 0xD2F3, 0x79DD, 0xD2F5, 0x79DE, 0xD2F4, 0x79DF, 0xAFB2,
+	0x79E0, 0xD2EF, 0x79E3, 0xAFB0, 0x79E4, 0xAFAF, 0x79E6, 0xAFB3,
+	0x79E7, 0xAFB1, 0x79E9, 0xAFB4, 0x79EA, 0xD2F2, 0x79EB, 0xD2ED,
+	0x79EC, 0xD2EE, 0x79ED, 0xD2F1, 0x79EE, 0xD2F0, 0x79F6, 0xD6C6,
+	0x79F7, 0xD6C7, 0x79F8, 0xD6C5, 0x79FA, 0xD6C4, 0x79FB, 0xB2BE,
+	0x7A00, 0xB57D, 0x7A02, 0xDAD6, 0x7A03, 0xDAD8, 0x7A04, 0xDADA,
+	0x7A05, 0xB57C, 0x7A08, 0xB57A, 0x7A0A, 0xDAD7, 0x7A0B, 0xB57B,
+	0x7A0C, 0xDAD9, 0x7A0D, 0xB579, 0x7A10, 0xDF41, 0x7A11, 0xDEF7,
+	0x7A12, 0xDEFA, 0x7A13, 0xDEFE, 0x7A14, 0xB85A, 0x7A15, 0xDEFC,
+	0x7A17, 0xDEFB, 0x7A18, 0xDEF8, 0x7A19, 0xDEF9, 0x7A1A, 0xB858,
+	0x7A1B, 0xDF40, 0x7A1C, 0xB857, 0x7A1E, 0xB85C, 0x7A1F, 0xB85B,
+	0x7A20, 0xB859, 0x7A22, 0xDEFD, 0x7A26, 0xE349, 0x7A28, 0xE348,
+	0x7A2B, 0xE344, 0x7A2E, 0xBAD8, 0x7A2F, 0xE347, 0x7A30, 0xE346,
+	0x7A31, 0xBAD9, 0x7A37, 0xBD5E, 0x7A39, 0xE6D2, 0x7A3B, 0xBD5F,
+	0x7A3C, 0xBD5B, 0x7A3D, 0xBD5D, 0x7A3F, 0xBD5A, 0x7A40, 0xBD5C,
+	0x7A44, 0xEAAF, 0x7A46, 0xBF70, 0x7A47, 0xEAB1, 0x7A48, 0xEAB0,
+	0x7A4A, 0xE345, 0x7A4B, 0xBF72, 0x7A4C, 0xBF71, 0x7A4D, 0xBF6E,
+	0x7A4E, 0xBF6F, 0x7A54, 0xEDB5, 0x7A56, 0xEDB3, 0x7A57, 0xC14A,
+	0x7A58, 0xEDB4, 0x7A5A, 0xEDB6, 0x7A5B, 0xEDB2, 0x7A5C, 0xEDB1,
+	0x7A5F, 0xF060, 0x7A60, 0xC2AA, 0x7A61, 0xC2A8, 0x7A62, 0xC2A9,
+	0x7A67, 0xF2A6, 0x7A68, 0xF2A7, 0x7A69, 0xC3AD, 0x7A6B, 0xC3AC,
+	0x7A6C, 0xF4A3, 0x7A6D, 0xF4A4, 0x7A6E, 0xF4A2, 0x7A70, 0xF6F8,
+	0x7A71, 0xF6F9, 0x7A74, 0xA5DE, 0x7A75, 0xCA48, 0x7A76, 0xA873,
+	0x7A78, 0xCDA5, 0x7A79, 0xAAC6, 0x7A7A, 0xAAC5, 0x7A7B, 0xCDA6,
+	0x7A7E, 0xD040, 0x7A7F, 0xACEF, 0x7A80, 0xCFFE, 0x7A81, 0xACF0,
+	0x7A84, 0xAFB6, 0x7A85, 0xD2F8, 0x7A86, 0xD2F6, 0x7A87, 0xD2FC,
+	0x7A88, 0xAFB7, 0x7A89, 0xD2F7, 0x7A8A, 0xD2FB, 0x7A8B, 0xD2F9,
+	0x7A8C, 0xD2FA, 0x7A8F, 0xD6C8, 0x7A90, 0xD6CA, 0x7A92, 0xB2BF,
+	0x7A94, 0xD6C9, 0x7A95, 0xB2C0, 0x7A96, 0xB5A2, 0x7A97, 0xB5A1,
+	0x7A98, 0xB57E, 0x7A99, 0xDADB, 0x7A9E, 0xDF44, 0x7A9F, 0xB85D,
+	0x7AA0, 0xB85E, 0x7AA2, 0xDF43, 0x7AA3, 0xDF42, 0x7AA8, 0xE34A,
+	0x7AA9, 0xBADB, 0x7AAA, 0xBADA, 0x7AAB, 0xE34B, 0x7AAC, 0xE34C,
+	0x7AAE, 0xBD61, 0x7AAF, 0xBD60, 0x7AB1, 0xEAB5, 0x7AB2, 0xE6D3,
+	0x7AB3, 0xE6D5, 0x7AB4, 0xE6D4, 0x7AB5, 0xEAB4, 0x7AB6, 0xEAB2,
+	0x7AB7, 0xEAB6, 0x7AB8, 0xEAB3, 0x7ABA, 0xBF73, 0x7ABE, 0xEDB7,
+	0x7ABF, 0xC14B, 0x7AC0, 0xEDB8, 0x7AC1, 0xEDB9, 0x7AC4, 0xC2AB,
+	0x7AC5, 0xC2AC, 0x7AC7, 0xC475, 0x7ACA, 0xC5D1, 0x7ACB, 0xA5DF,
+	0x7AD1, 0xD041, 0x7AD8, 0xD2FD, 0x7AD9, 0xAFB8, 0x7ADF, 0xB3BA,
+	0x7AE0, 0xB3B9, 0x7AE3, 0xB5A4, 0x7AE4, 0xDADD, 0x7AE5, 0xB5A3,
+	0x7AE6, 0xDADC, 0x7AEB, 0xDF45, 0x7AED, 0xBADC, 0x7AEE, 0xE34D,
+	0x7AEF, 0xBADD, 0x7AF6, 0xC476, 0x7AF7, 0xF4A5, 0x7AF9, 0xA6CB,
+	0x7AFA, 0xAAC7, 0x7AFB, 0xCDA7, 0x7AFD, 0xACF2, 0x7AFF, 0xACF1,
+	0x7B00, 0xD042, 0x7B01, 0xD043, 0x7B04, 0xD340, 0x7B05, 0xD342,
+	0x7B06, 0xAFB9, 0x7B08, 0xD344, 0x7B09, 0xD347, 0x7B0A, 0xD345,
+	0x7B0E, 0xD346, 0x7B0F, 0xD343, 0x7B10, 0xD2FE, 0x7B11, 0xAFBA,
+	0x7B12, 0xD348, 0x7B13, 0xD341, 0x7B18, 0xD6D3, 0x7B19, 0xB2C6,
+	0x7B1A, 0xD6DC, 0x7B1B, 0xB2C3, 0x7B1D, 0xD6D5, 0x7B1E, 0xB2C7,
+	0x7B20, 0xB2C1, 0x7B22, 0xD6D0, 0x7B23, 0xD6DD, 0x7B24, 0xD6D1,
+	0x7B25, 0xD6CE, 0x7B26, 0xB2C5, 0x7B28, 0xB2C2, 0x7B2A, 0xD6D4,
+	0x7B2B, 0xD6D7, 0x7B2C, 0xB2C4, 0x7B2D, 0xD6D8, 0x7B2E, 0xB2C8,
+	0x7B2F, 0xD6D9, 0x7B30, 0xD6CF, 0x7B31, 0xD6D6, 0x7B32, 0xD6DA,
+	0x7B33, 0xD6D2, 0x7B34, 0xD6CD, 0x7B35, 0xD6CB, 0x7B38, 0xD6DB,
+	0x7B3B, 0xDADF, 0x7B40, 0xDAE4, 0x7B44, 0xDAE0, 0x7B45, 0xDAE6,
+	0x7B46, 0xB5A7, 0x7B47, 0xD6CC, 0x7B48, 0xDAE1, 0x7B49, 0xB5A5,
+	0x7B4A, 0xDADE, 0x7B4B, 0xB5AC, 0x7B4C, 0xDAE2, 0x7B4D, 0xB5AB,
+	0x7B4E, 0xDAE3, 0x7B4F, 0xB5AD, 0x7B50, 0xB5A8, 0x7B51, 0xB5AE,
+	0x7B52, 0xB5A9, 0x7B54, 0xB5AA, 0x7B56, 0xB5A6, 0x7B58, 0xDAE5,
+	0x7B60, 0xB861, 0x7B61, 0xDF50, 0x7B63, 0xDF53, 0x7B64, 0xDF47,
+	0x7B65, 0xDF4C, 0x7B66, 0xDF46, 0x7B67, 0xB863, 0x7B69, 0xDF4A,
+	0x7B6D, 0xDF48, 0x7B6E, 0xB862, 0x7B70, 0xDF4F, 0x7B71, 0xDF4E,
+	0x7B72, 0xDF4B, 0x7B73, 0xDF4D, 0x7B74, 0xDF49, 0x7B75, 0xBAE1,
+	0x7B76, 0xDF52, 0x7B77, 0xB85F, 0x7B78, 0xDF51, 0x7B82, 0xE35D,
+	0x7B84, 0xBAE8, 0x7B85, 0xE358, 0x7B87, 0xBAE7, 0x7B88, 0xE34E,
+	0x7B8A, 0xE350, 0x7B8B, 0xBAE0, 0x7B8C, 0xE355, 0x7B8D, 0xE354,
+	0x7B8E, 0xE357, 0x7B8F, 0xBAE5, 0x7B90, 0xE352, 0x7B91, 0xE351,
+	0x7B94, 0xBAE4, 0x7B95, 0xBADF, 0x7B96, 0xE353, 0x7B97, 0xBAE2,
+	0x7B98, 0xE359, 0x7B99, 0xE35B, 0x7B9B, 0xE356, 0x7B9C, 0xE34F,
+	0x7B9D, 0xBAE3, 0x7BA0, 0xBD69, 0x7BA1, 0xBADE, 0x7BA4, 0xE35C,
+	0x7BAC, 0xE6D9, 0x7BAD, 0xBD62, 0x7BAF, 0xE6DB, 0x7BB1, 0xBD63,
+	0x7BB4, 0xBD65, 0x7BB5, 0xE6DE, 0x7BB7, 0xE6D6, 0x7BB8, 0xBAE6,
+	0x7BB9, 0xE6DC, 0x7BBE, 0xE6D8, 0x7BC0, 0xB860, 0x7BC1, 0xBD68,
+	0x7BC4, 0xBD64, 0x7BC6, 0xBD66, 0x7BC7, 0xBD67, 0x7BC9, 0xBF76,
+	0x7BCA, 0xE6DD, 0x7BCB, 0xE6D7, 0x7BCC, 0xBD6A, 0x7BCE, 0xE6DA,
+	0x7BD4, 0xEAC0, 0x7BD5, 0xEABB, 0x7BD8, 0xEAC5, 0x7BD9, 0xBF74,
+	0x7BDA, 0xEABD, 0x7BDB, 0xBF78, 0x7BDC, 0xEAC3, 0x7BDD, 0xEABA,
+	0x7BDE, 0xEAB7, 0x7BDF, 0xEAC6, 0x7BE0, 0xC151, 0x7BE1, 0xBF79,
+	0x7BE2, 0xEAC2, 0x7BE3, 0xEAB8, 0x7BE4, 0xBF77, 0x7BE5, 0xEABC,
+	0x7BE6, 0xBF7B, 0x7BE7, 0xEAB9, 0x7BE8, 0xEABE, 0x7BE9, 0xBF7A,
+	0x7BEA, 0xEAC1, 0x7BEB, 0xEAC4, 0x7BF0, 0xEDCB, 0x7BF1, 0xEDCC,
+	0x7BF2, 0xEDBC, 0x7BF3, 0xEDC3, 0x7BF4, 0xEDC1, 0x7BF7, 0xC14F,
+	0x7BF8, 0xEDC8, 0x7BF9, 0xEABF, 0x7BFB, 0xEDBF, 0x7BFD, 0xEDC9,
+	0x7BFE, 0xC14E, 0x7BFF, 0xEDBE, 0x7C00, 0xEDBD, 0x7C01, 0xEDC7,
+	0x7C02, 0xEDC4, 0x7C03, 0xEDC6, 0x7C05, 0xEDBA, 0x7C06, 0xEDCA,
+	0x7C07, 0xC14C, 0x7C09, 0xEDC5, 0x7C0A, 0xEDCE, 0x7C0B, 0xEDC2,
+	0x7C0C, 0xC150, 0x7C0D, 0xC14D, 0x7C0E, 0xEDC0, 0x7C0F, 0xEDBB,
+	0x7C10, 0xEDCD, 0x7C11, 0xBF75, 0x7C19, 0xF063, 0x7C1C, 0xF061,
+	0x7C1D, 0xF067, 0x7C1E, 0xC2B0, 0x7C1F, 0xF065, 0x7C20, 0xF064,
+	0x7C21, 0xC2B2, 0x7C22, 0xF06A, 0x7C23, 0xC2B1, 0x7C25, 0xF06B,
+	0x7C26, 0xF068, 0x7C27, 0xC2AE, 0x7C28, 0xF069, 0x7C29, 0xF062,
+	0x7C2A, 0xC2AF, 0x7C2B, 0xC2AD, 0x7C2C, 0xF2AB, 0x7C2D, 0xF066,
+	0x7C30, 0xF06C, 0x7C33, 0xF2A8, 0x7C37, 0xC3B2, 0x7C38, 0xC3B0,
+	0x7C39, 0xF2AA, 0x7C3B, 0xF2AC, 0x7C3C, 0xF2A9, 0x7C3D, 0xC3B1,
+	0x7C3E, 0xC3AE, 0x7C3F, 0xC3AF, 0x7C40, 0xC3B3, 0x7C43, 0xC478,
+	0x7C45, 0xF4AA, 0x7C47, 0xF4A9, 0x7C48, 0xF4A7, 0x7C49, 0xF4A6,
+	0x7C4A, 0xF4A8, 0x7C4C, 0xC477, 0x7C4D, 0xC479, 0x7C50, 0xC4F0,
+	0x7C53, 0xF5E5, 0x7C54, 0xF5E4, 0x7C57, 0xF6FA, 0x7C59, 0xF6FC,
+	0x7C5A, 0xF6FE, 0x7C5B, 0xF6FD, 0x7C5C, 0xF6FB, 0x7C5F, 0xC5A3,
+	0x7C60, 0xC5A2, 0x7C63, 0xC5D3, 0x7C64, 0xC5D2, 0x7C65, 0xC5D4,
+	0x7C66, 0xF7ED, 0x7C67, 0xF7EC, 0x7C69, 0xF8FB, 0x7C6A, 0xF8B8,
+	0x7C6B, 0xF8FC, 0x7C6C, 0xC658, 0x7C6E, 0xC659, 0x7C6F, 0xF96D,
+	0x7C72, 0xC67E, 0x7C73, 0xA6CC, 0x7C75, 0xCDA8, 0x7C78, 0xD045,
+	0x7C79, 0xD046, 0x7C7A, 0xD044, 0x7C7D, 0xACF3, 0x7C7F, 0xD047,
+	0x7C80, 0xD048, 0x7C81, 0xD049, 0x7C84, 0xD349, 0x7C85, 0xD34F,
+	0x7C88, 0xD34D, 0x7C89, 0xAFBB, 0x7C8A, 0xD34B, 0x7C8C, 0xD34C,
+	0x7C8D, 0xD34E, 0x7C91, 0xD34A, 0x7C92, 0xB2C9, 0x7C94, 0xD6DE,
+	0x7C95, 0xB2CB, 0x7C96, 0xD6E0, 0x7C97, 0xB2CA, 0x7C98, 0xD6DF,
+	0x7C9E, 0xDAE8, 0x7C9F, 0xB5AF, 0x7CA1, 0xDAEA, 0x7CA2, 0xDAE7,
+	0x7CA3, 0xD6E1, 0x7CA5, 0xB5B0, 0x7CA7, 0xF9DB, 0x7CA8, 0xDAE9,
+	0x7CAF, 0xDF56, 0x7CB1, 0xB864, 0x7CB2, 0xDF54, 0x7CB3, 0xB865,
+	0x7CB4, 0xDF55, 0x7CB5, 0xB866, 0x7CB9, 0xBAE9, 0x7CBA, 0xE361,
+	0x7CBB, 0xE35E, 0x7CBC, 0xE360, 0x7CBD, 0xBAEA, 0x7CBE, 0xBAEB,
+	0x7CBF, 0xE35F, 0x7CC5, 0xE6DF, 0x7CC8, 0xE6E0, 0x7CCA, 0xBD6B,
+	0x7CCB, 0xE6E2, 0x7CCC, 0xE6E1, 0x7CCE, 0xA261, 0x7CD0, 0xEACA,
+	0x7CD1, 0xEACB, 0x7CD2, 0xEAC7, 0x7CD4, 0xEAC8, 0x7CD5, 0xBF7C,
+	0x7CD6, 0xBF7D, 0x7CD7, 0xEAC9, 0x7CD9, 0xC157, 0x7CDC, 0xC153,
+	0x7CDD, 0xC158, 0x7CDE, 0xC154, 0x7CDF, 0xC156, 0x7CE0, 0xC152,
+	0x7CE2, 0xC155, 0x7CE7, 0xC2B3, 0x7CE8, 0xEDCF, 0x7CEA, 0xF2AE,
+	0x7CEC, 0xF2AD, 0x7CEE, 0xF4AB, 0x7CEF, 0xC47A, 0x7CF0, 0xC47B,
+	0x7CF1, 0xF741, 0x7CF2, 0xF5E6, 0x7CF4, 0xF740, 0x7CF6, 0xF8FD,
+	0x7CF7, 0xF9A4, 0x7CF8, 0xA6CD, 0x7CFB, 0xA874, 0x7CFD, 0xCDA9,
+	0x7CFE, 0xAAC8, 0x7D00, 0xACF6, 0x7D01, 0xD04C, 0x7D02, 0xACF4,
+	0x7D03, 0xD04A, 0x7D04, 0xACF9, 0x7D05, 0xACF5, 0x7D06, 0xACFA,
+	0x7D07, 0xACF8, 0x7D08, 0xD04B, 0x7D09, 0xACF7, 0x7D0A, 0xAFBF,
+	0x7D0B, 0xAFBE, 0x7D0C, 0xD35A, 0x7D0D, 0xAFC7, 0x7D0E, 0xD353,
+	0x7D0F, 0xD359, 0x7D10, 0xAFC3, 0x7D11, 0xD352, 0x7D12, 0xD358,
+	0x7D13, 0xD356, 0x7D14, 0xAFC2, 0x7D15, 0xAFC4, 0x7D16, 0xD355,
+	0x7D17, 0xAFBD, 0x7D18, 0xD354, 0x7D19, 0xAFC8, 0x7D1A, 0xAFC5,
+	0x7D1B, 0xAFC9, 0x7D1C, 0xAFC6, 0x7D1D, 0xD351, 0x7D1E, 0xD350,
+	0x7D1F, 0xD357, 0x7D20, 0xAFC0, 0x7D21, 0xAFBC, 0x7D22, 0xAFC1,
+	0x7D28, 0xD6F0, 0x7D29, 0xD6E9, 0x7D2B, 0xB5B5, 0x7D2C, 0xD6E8,
+	0x7D2E, 0xB2CF, 0x7D2F, 0xB2D6, 0x7D30, 0xB2D3, 0x7D31, 0xB2D9,
+	0x7D32, 0xB2D8, 0x7D33, 0xB2D4, 0x7D35, 0xD6E2, 0x7D36, 0xD6E5,
+	0x7D38, 0xD6E4, 0x7D39, 0xB2D0, 0x7D3A, 0xD6E6, 0x7D3B, 0xD6EF,
+	0x7D3C, 0xB2D1, 0x7D3D, 0xD6E3, 0x7D3E, 0xD6EC, 0x7D3F, 0xD6ED,
+	0x7D40, 0xB2D2, 0x7D41, 0xD6EA, 0x7D42, 0xB2D7, 0x7D43, 0xB2CD,
+	0x7D44, 0xB2D5, 0x7D45, 0xD6E7, 0x7D46, 0xB2CC, 0x7D47, 0xD6EB,
+	0x7D4A, 0xD6EE, 0x7D4E, 0xDAFB, 0x7D4F, 0xDAF2, 0x7D50, 0xB5B2,
+	0x7D51, 0xDAF9, 0x7D52, 0xDAF6, 0x7D53, 0xDAEE, 0x7D54, 0xDAF7,
+	0x7D55, 0xB5B4, 0x7D56, 0xDAEF, 0x7D58, 0xDAEB, 0x7D5B, 0xB86C,
+	0x7D5C, 0xDAF4, 0x7D5E, 0xB5B1, 0x7D5F, 0xDAFA, 0x7D61, 0xB5B8,
+	0x7D62, 0xB5BA, 0x7D63, 0xDAED, 0x7D66, 0xB5B9, 0x7D67, 0xDAF0,
+	0x7D68, 0xB5B3, 0x7D69, 0xDAF8, 0x7D6A, 0xDAF1, 0x7D6B, 0xDAF5,
+	0x7D6D, 0xDAF3, 0x7D6E, 0xB5B6, 0x7D6F, 0xDAEC, 0x7D70, 0xB5BB,
+	0x7D71, 0xB2CE, 0x7D72, 0xB5B7, 0x7D73, 0xB5BC, 0x7D79, 0xB868,
+	0x7D7A, 0xDF5D, 0x7D7B, 0xDF5F, 0x7D7C, 0xDF61, 0x7D7D, 0xDF65,
+	0x7D7F, 0xDF5B, 0x7D80, 0xDF59, 0x7D81, 0xB86A, 0x7D83, 0xDF60,
+	0x7D84, 0xDF64, 0x7D85, 0xDF5C, 0x7D86, 0xDF58, 0x7D88, 0xDF57,
+	0x7D8C, 0xDF62, 0x7D8D, 0xDF5A, 0x7D8E, 0xDF5E, 0x7D8F, 0xB86B,
+	0x7D91, 0xB869, 0x7D92, 0xDF66, 0x7D93, 0xB867, 0x7D94, 0xDF63,
+	0x7D96, 0xE372, 0x7D9C, 0xBAEE, 0x7D9D, 0xE36A, 0x7D9E, 0xBD78,
+	0x7D9F, 0xE374, 0x7DA0, 0xBAF1, 0x7DA1, 0xE378, 0x7DA2, 0xBAF7,
+	0x7DA3, 0xE365, 0x7DA6, 0xE375, 0x7DA7, 0xE362, 0x7DA9, 0xE377,
+	0x7DAA, 0xE366, 0x7DAC, 0xBAFE, 0x7DAD, 0xBAFB, 0x7DAE, 0xE376,
+	0x7DAF, 0xE370, 0x7DB0, 0xBAED, 0x7DB1, 0xBAF5, 0x7DB2, 0xBAF4,
+	0x7DB4, 0xBAF3, 0x7DB5, 0xBAF9, 0x7DB7, 0xE363, 0x7DB8, 0xBAFA,
+	0x7DB9, 0xE371, 0x7DBA, 0xBAF6, 0x7DBB, 0xBAEC, 0x7DBC, 0xE373,
+	0x7DBD, 0xBAEF, 0x7DBE, 0xBAF0, 0x7DBF, 0xBAF8, 0x7DC0, 0xE368,
+	0x7DC1, 0xE367, 0x7DC2, 0xE364, 0x7DC4, 0xE36C, 0x7DC5, 0xE369,
+	0x7DC6, 0xE36D, 0x7DC7, 0xBAFD, 0x7DC9, 0xE379, 0x7DCA, 0xBAF2,
+	0x7DCB, 0xE36E, 0x7DCC, 0xE36F, 0x7DCE, 0xE36B, 0x7DD2, 0xBAFC,
+	0x7DD7, 0xE6E7, 0x7DD8, 0xBD70, 0x7DD9, 0xBD79, 0x7DDA, 0xBD75,
+	0x7DDB, 0xE6E4, 0x7DDD, 0xBD72, 0x7DDE, 0xBD76, 0x7DDF, 0xE6F0,
+	0x7DE0, 0xBD6C, 0x7DE1, 0xE6E8, 0x7DE3, 0xBD74, 0x7DE6, 0xE6EB,
+	0x7DE7, 0xE6E6, 0x7DE8, 0xBD73, 0x7DE9, 0xBD77, 0x7DEA, 0xE6E5,
+	0x7DEC, 0xBD71, 0x7DEE, 0xE6EF, 0x7DEF, 0xBD6E, 0x7DF0, 0xE6EE,
+	0x7DF1, 0xE6ED, 0x7DF2, 0xBD7A, 0x7DF3, 0xE572, 0x7DF4, 0xBD6D,
+	0x7DF6, 0xE6EC, 0x7DF7, 0xE6E3, 0x7DF9, 0xBD7B, 0x7DFA, 0xE6EA,
+	0x7DFB, 0xBD6F, 0x7E03, 0xE6E9, 0x7E08, 0xBFA2, 0x7E09, 0xBFA7,
+	0x7E0A, 0xBF7E, 0x7E0B, 0xEAD8, 0x7E0C, 0xEACF, 0x7E0D, 0xEADB,
+	0x7E0E, 0xEAD3, 0x7E0F, 0xEAD9, 0x7E10, 0xBFA8, 0x7E11, 0xBFA1,
+	0x7E12, 0xEACC, 0x7E13, 0xEAD2, 0x7E14, 0xEADC, 0x7E15, 0xEAD5,
+	0x7E16, 0xEADA, 0x7E17, 0xEACE, 0x7E1A, 0xEAD6, 0x7E1B, 0xBFA3,
+	0x7E1C, 0xEAD4, 0x7E1D, 0xBFA6, 0x7E1E, 0xBFA5, 0x7E1F, 0xEAD0,
+	0x7E20, 0xEAD1, 0x7E21, 0xEACD, 0x7E22, 0xEAD7, 0x7E23, 0xBFA4,
+	0x7E24, 0xEADE, 0x7E25, 0xEADD, 0x7E29, 0xEDDA, 0x7E2A, 0xEDD6,
+	0x7E2B, 0xC15F, 0x7E2D, 0xEDD0, 0x7E2E, 0xC159, 0x7E2F, 0xC169,
+	0x7E30, 0xEDDC, 0x7E31, 0xC161, 0x7E32, 0xC15D, 0x7E33, 0xEDD3,
+	0x7E34, 0xC164, 0x7E35, 0xC167, 0x7E36, 0xEDDE, 0x7E37, 0xC15C,
+	0x7E38, 0xEDD5, 0x7E39, 0xC165, 0x7E3A, 0xEDE0, 0x7E3B, 0xEDDD,
+	0x7E3C, 0xEDD1, 0x7E3D, 0xC160, 0x7E3E, 0xC15A, 0x7E3F, 0xC168,
+	0x7E40, 0xEDD8, 0x7E41, 0xC163, 0x7E42, 0xEDD2, 0x7E43, 0xC15E,
+	0x7E44, 0xEDDF, 0x7E45, 0xC162, 0x7E46, 0xC15B, 0x7E47, 0xEDD9,
+	0x7E48, 0xC166, 0x7E49, 0xEDD7, 0x7E4C, 0xEDDB, 0x7E50, 0xF06E,
+	0x7E51, 0xF074, 0x7E52, 0xC2B9, 0x7E53, 0xF077, 0x7E54, 0xC2B4,
+	0x7E55, 0xC2B5, 0x7E56, 0xF06F, 0x7E57, 0xF076, 0x7E58, 0xF071,
+	0x7E59, 0xC2BA, 0x7E5A, 0xC2B7, 0x7E5C, 0xF06D, 0x7E5E, 0xC2B6,
+	0x7E5F, 0xF073, 0x7E60, 0xF075, 0x7E61, 0xC2B8, 0x7E62, 0xF072,
+	0x7E63, 0xF070, 0x7E68, 0xF2B8, 0x7E69, 0xC3B7, 0x7E6A, 0xC3B8,
+	0x7E6B, 0xC3B4, 0x7E6D, 0xC3B5, 0x7E6F, 0xF2B4, 0x7E70, 0xF2B2,
+	0x7E72, 0xF2B6, 0x7E73, 0xC3BA, 0x7E74, 0xF2B7, 0x7E75, 0xF2B0,
+	0x7E76, 0xF2AF, 0x7E77, 0xF2B3, 0x7E78, 0xF2B1, 0x7E79, 0xC3B6,
+	0x7E7A, 0xF2B5, 0x7E7B, 0xF4AC, 0x7E7C, 0xC47E, 0x7E7D, 0xC47D,
+	0x7E7E, 0xF4AD, 0x7E80, 0xF4AF, 0x7E81, 0xF4AE, 0x7E82, 0xC4A1,
+	0x7E86, 0xF5EB, 0x7E87, 0xF5E8, 0x7E88, 0xF5E9, 0x7E8A, 0xF5E7,
+	0x7E8B, 0xF5EA, 0x7E8C, 0xC4F2, 0x7E8D, 0xF5EC, 0x7E8F, 0xC4F1,
+	0x7E91, 0xF742, 0x7E93, 0xC5D5, 0x7E94, 0xC5D7, 0x7E95, 0xF7EE,
+	0x7E96, 0xC5D6, 0x7E97, 0xF8B9, 0x7E98, 0xF940, 0x7E99, 0xF942,
+	0x7E9A, 0xF8FE, 0x7E9B, 0xF941, 0x7E9C, 0xC66C, 0x7F36, 0xA6CE,
+	0x7F38, 0xACFB, 0x7F39, 0xD26F, 0x7F3A, 0xAFCA, 0x7F3D, 0xB2DA,
+	0x7F3E, 0xDAFC, 0x7F3F, 0xDAFD, 0x7F43, 0xEADF, 0x7F44, 0xC16A,
+	0x7F45, 0xEDE1, 0x7F48, 0xC2BB, 0x7F4A, 0xF2BA, 0x7F4B, 0xF2B9,
+	0x7F4C, 0xC4A2, 0x7F4D, 0xF5ED, 0x7F4F, 0xF743, 0x7F50, 0xC5F8,
+	0x7F51, 0xCA49, 0x7F54, 0xAAC9, 0x7F55, 0xA875, 0x7F58, 0xD04D,
+	0x7F5B, 0xD360, 0x7F5C, 0xD35B, 0x7F5D, 0xD35F, 0x7F5E, 0xD35D,
+	0x7F5F, 0xAFCB, 0x7F60, 0xD35E, 0x7F61, 0xD35C, 0x7F63, 0xD6F1,
+	0x7F65, 0xDAFE, 0x7F66, 0xDB40, 0x7F67, 0xDF69, 0x7F68, 0xDF6A,
+	0x7F69, 0xB86E, 0x7F6A, 0xB86F, 0x7F6B, 0xDF68, 0x7F6C, 0xDF6B,
+	0x7F6D, 0xDF67, 0x7F6E, 0xB86D, 0x7F70, 0xBB40, 0x7F72, 0xB870,
+	0x7F73, 0xE37A, 0x7F75, 0xBD7C, 0x7F76, 0xE6F1, 0x7F77, 0xBD7D,
+	0x7F79, 0xBFA9, 0x7F7A, 0xEAE2, 0x7F7B, 0xEAE0, 0x7F7C, 0xEAE1,
+	0x7F7D, 0xEDE4, 0x7F7E, 0xEDE3, 0x7F7F, 0xEDE2, 0x7F83, 0xF2BB,
+	0x7F85, 0xC3B9, 0x7F86, 0xF2BC, 0x7F87, 0xF744, 0x7F88, 0xC5F9,
+	0x7F89, 0xF8BA, 0x7F8A, 0xA6CF, 0x7F8B, 0xAACB, 0x7F8C, 0xAACA,
+	0x7F8D, 0xD04F, 0x7F8E, 0xACFC, 0x7F91, 0xD04E, 0x7F92, 0xD362,
+	0x7F94, 0xAFCC, 0x7F95, 0xD6F2, 0x7F96, 0xD361, 0x7F9A, 0xB2DC,
+	0x7F9B, 0xD6F5, 0x7F9C, 0xD6F3, 0x7F9D, 0xD6F4, 0x7F9E, 0xB2DB,
+	0x7FA0, 0xDB42, 0x7FA1, 0xDB43, 0x7FA2, 0xDB41, 0x7FA4, 0xB873,
+	0x7FA5, 0xDF6D, 0x7FA6, 0xDF6C, 0x7FA7, 0xDF6E, 0x7FA8, 0xB872,
+	0x7FA9, 0xB871, 0x7FAC, 0xE6F2, 0x7FAD, 0xE6F4, 0x7FAF, 0xBD7E,
+	0x7FB0, 0xE6F3, 0x7FB1, 0xEAE3, 0x7FB2, 0xBFAA, 0x7FB3, 0xF079,
+	0x7FB5, 0xF078, 0x7FB6, 0xC3BB, 0x7FB7, 0xF2BD, 0x7FB8, 0xC3BD,
+	0x7FB9, 0xC3BC, 0x7FBA, 0xF4B0, 0x7FBB, 0xF5EE, 0x7FBC, 0xC4F3,
+	0x7FBD, 0xA6D0, 0x7FBE, 0xD050, 0x7FBF, 0xACFD, 0x7FC0, 0xD365,
+	0x7FC1, 0xAFCE, 0x7FC2, 0xD364, 0x7FC3, 0xD363, 0x7FC5, 0xAFCD,
+	0x7FC7, 0xD6FB, 0x7FC9, 0xD6FD, 0x7FCA, 0xD6F6, 0x7FCB, 0xD6F7,
+	0x7FCC, 0xB2DD, 0x7FCD, 0xD6F8, 0x7FCE, 0xB2DE, 0x7FCF, 0xD6FC,
+	0x7FD0, 0xD6F9, 0x7FD1, 0xD6FA, 0x7FD2, 0xB2DF, 0x7FD4, 0xB5BE,
+	0x7FD5, 0xB5BF, 0x7FD7, 0xDB44, 0x7FDB, 0xDF6F, 0x7FDC, 0xDF70,
+	0x7FDE, 0xE37E, 0x7FDF, 0xBB43, 0x7FE0, 0xBB41, 0x7FE1, 0xBB42,
+	0x7FE2, 0xE37B, 0x7FE3, 0xE37C, 0x7FE5, 0xE37D, 0x7FE6, 0xE6F9,
+	0x7FE8, 0xE6FA, 0x7FE9, 0xBDA1, 0x7FEA, 0xE6F7, 0x7FEB, 0xE6F6,
+	0x7FEC, 0xE6F8, 0x7FED, 0xE6F5, 0x7FEE, 0xBFAD, 0x7FEF, 0xEAE4,
+	0x7FF0, 0xBFAB, 0x7FF1, 0xBFAC, 0x7FF2, 0xEDE6, 0x7FF3, 0xC16B,
+	0x7FF4, 0xEDE5, 0x7FF5, 0xEFA8, 0x7FF7, 0xF07A, 0x7FF8, 0xF07B,
+	0x7FF9, 0xC2BC, 0x7FFB, 0xC2BD, 0x7FFC, 0xC16C, 0x7FFD, 0xF2BE,
+	0x7FFE, 0xF2BF, 0x7FFF, 0xF4B1, 0x8000, 0xC4A3, 0x8001, 0xA6D1,
+	0x8003, 0xA6D2, 0x8004, 0xACFE, 0x8005, 0xAACC, 0x8006, 0xAFCF,
+	0x8007, 0xD051, 0x800B, 0xB5C0, 0x800C, 0xA6D3, 0x800D, 0xAD41,
+	0x800E, 0xD052, 0x800F, 0xD053, 0x8010, 0xAD40, 0x8011, 0xAD42,
+	0x8012, 0xA6D4, 0x8014, 0xD054, 0x8015, 0xAFD1, 0x8016, 0xD366,
+	0x8017, 0xAFD3, 0x8018, 0xAFD0, 0x8019, 0xAFD2, 0x801B, 0xD741,
+	0x801C, 0xB2E0, 0x801E, 0xD740, 0x801F, 0xD6FE, 0x8021, 0xDF71,
+	0x8024, 0xE3A1, 0x8026, 0xBDA2, 0x8028, 0xBFAE, 0x8029, 0xEAE6,
+	0x802A, 0xEAE5, 0x802C, 0xEDE7, 0x8030, 0xF5EF, 0x8033, 0xA6D5,
+	0x8034, 0xCB73, 0x8035, 0xCDAA, 0x8036, 0xAD43, 0x8037, 0xD055,
+	0x8039, 0xD368, 0x803D, 0xAFD4, 0x803E, 0xD367, 0x803F, 0xAFD5,
+	0x8043, 0xD743, 0x8046, 0xB2E2, 0x8047, 0xD742, 0x8048, 0xD744,
+	0x804A, 0xB2E1, 0x804F, 0xDB46, 0x8050, 0xDB47, 0x8051, 0xDB45,
+	0x8052, 0xB5C1, 0x8056, 0xB874, 0x8058, 0xB875, 0x805A, 0xBB45,
+	0x805C, 0xE3A3, 0x805D, 0xE3A2, 0x805E, 0xBB44, 0x8064, 0xE6FB,
+	0x8067, 0xE6FC, 0x806C, 0xEAE7, 0x806F, 0xC170, 0x8070, 0xC16F,
+	0x8071, 0xC16D, 0x8072, 0xC16E, 0x8073, 0xC171, 0x8075, 0xF07C,
+	0x8076, 0xC2BF, 0x8077, 0xC2BE, 0x8078, 0xF2C0, 0x8079, 0xF4B2,
+	0x807D, 0xC5A5, 0x807E, 0xC5A4, 0x807F, 0xA6D6, 0x8082, 0xD1FB,
+	0x8084, 0xB877, 0x8085, 0xB5C2, 0x8086, 0xB876, 0x8087, 0xBB46,
+	0x8089, 0xA6D7, 0x808A, 0xC9A9, 0x808B, 0xA6D8, 0x808C, 0xA6D9,
+	0x808F, 0xCDAB, 0x8090, 0xCB76, 0x8092, 0xCB77, 0x8093, 0xA877,
+	0x8095, 0xCB74, 0x8096, 0xA876, 0x8098, 0xA879, 0x8099, 0xCB75,
+	0x809A, 0xA87B, 0x809B, 0xA87A, 0x809C, 0xCB78, 0x809D, 0xA878,
+	0x80A1, 0xAAD1, 0x80A2, 0xAACF, 0x80A3, 0xCDAD, 0x80A5, 0xAACE,
+	0x80A9, 0xAAD3, 0x80AA, 0xAAD5, 0x80AB, 0xAAD2, 0x80AD, 0xCDB0,
+	0x80AE, 0xCDAC, 0x80AF, 0xAAD6, 0x80B1, 0xAAD0, 0x80B2, 0xA87C,
+	0x80B4, 0xAAD4, 0x80B5, 0xCDAF, 0x80B8, 0xCDAE, 0x80BA, 0xAACD,
+	0x80C2, 0xD05B, 0x80C3, 0xAD47, 0x80C4, 0xAD48, 0x80C5, 0xD05D,
+	0x80C7, 0xD057, 0x80C8, 0xD05A, 0x80C9, 0xD063, 0x80CA, 0xD061,
+	0x80CC, 0xAD49, 0x80CD, 0xD067, 0x80CE, 0xAD4C, 0x80CF, 0xD064,
+	0x80D0, 0xD05C, 0x80D1, 0xD059, 0x80D4, 0xDB49, 0x80D5, 0xD062,
+	0x80D6, 0xAD44, 0x80D7, 0xD065, 0x80D8, 0xD056, 0x80D9, 0xD05F,
+	0x80DA, 0xAD46, 0x80DB, 0xAD4B, 0x80DC, 0xD060, 0x80DD, 0xAD4F,
+	0x80DE, 0xAD4D, 0x80E0, 0xD058, 0x80E1, 0xAD4A, 0x80E3, 0xD05E,
+	0x80E4, 0xAD4E, 0x80E5, 0xAD45, 0x80E6, 0xD066, 0x80ED, 0xAFDA,
+	0x80EF, 0xAFE3, 0x80F0, 0xAFD8, 0x80F1, 0xAFD6, 0x80F2, 0xD36A,
+	0x80F3, 0xAFDE, 0x80F4, 0xAFDB, 0x80F5, 0xD36C, 0x80F8, 0xAFDD,
+	0x80F9, 0xD36B, 0x80FA, 0xD369, 0x80FB, 0xD36E, 0x80FC, 0xAFE2,
+	0x80FD, 0xAFE0, 0x80FE, 0xDB48, 0x8100, 0xD36F, 0x8101, 0xD36D,
+	0x8102, 0xAFD7, 0x8105, 0xAFD9, 0x8106, 0xAFDC, 0x8108, 0xAFDF,
+	0x810A, 0xAFE1, 0x8115, 0xD74E, 0x8116, 0xB2E4, 0x8118, 0xD745,
+	0x8119, 0xD747, 0x811B, 0xD748, 0x811D, 0xD750, 0x811E, 0xD74C,
+	0x811F, 0xD74A, 0x8121, 0xD74D, 0x8122, 0xD751, 0x8123, 0xB2E5,
+	0x8124, 0xB2E9, 0x8125, 0xD746, 0x8127, 0xD74F, 0x8129, 0xB2E7,
+	0x812B, 0xB2E6, 0x812C, 0xD74B, 0x812D, 0xD749, 0x812F, 0xB2E3,
+	0x8130, 0xB2E8, 0x8139, 0xB5C8, 0x813A, 0xDB51, 0x813D, 0xDB4F,
+	0x813E, 0xB5CA, 0x8143, 0xDB4A, 0x8144, 0xDFA1, 0x8146, 0xB5C9,
+	0x8147, 0xDB4E, 0x814A, 0xDB4B, 0x814B, 0xB5C5, 0x814C, 0xB5CB,
+	0x814D, 0xDB50, 0x814E, 0xB5C7, 0x814F, 0xDB4D, 0x8150, 0xBB47,
+	0x8151, 0xB5C6, 0x8152, 0xDB4C, 0x8153, 0xB5CC, 0x8154, 0xB5C4,
+	0x8155, 0xB5C3, 0x815B, 0xDF77, 0x815C, 0xDF75, 0x815E, 0xDF7B,
+	0x8160, 0xDF73, 0x8161, 0xDFA2, 0x8162, 0xDF78, 0x8164, 0xDF72,
+	0x8165, 0xB87B, 0x8166, 0xB8A3, 0x8167, 0xDF7D, 0x8169, 0xDF76,
+	0x816B, 0xB87E, 0x816E, 0xB87C, 0x816F, 0xDF7E, 0x8170, 0xB879,
+	0x8171, 0xB878, 0x8172, 0xDF79, 0x8173, 0xB87D, 0x8174, 0xB5CD,
+	0x8176, 0xDF7C, 0x8177, 0xDF74, 0x8178, 0xB87A, 0x8179, 0xB8A1,
+	0x817A, 0xB8A2, 0x817F, 0xBB4C, 0x8180, 0xBB48, 0x8182, 0xBB4D,
+	0x8183, 0xE3A6, 0x8186, 0xE3A5, 0x8187, 0xE3A7, 0x8188, 0xBB4A,
+	0x8189, 0xE3A4, 0x818A, 0xBB4B, 0x818B, 0xE3AA, 0x818C, 0xE3A9,
+	0x818D, 0xE3A8, 0x818F, 0xBB49, 0x8195, 0xE741, 0x8197, 0xE744,
+	0x8198, 0xBDA8, 0x8199, 0xE743, 0x819A, 0xBDA7, 0x819B, 0xBDA3,
+	0x819C, 0xBDA4, 0x819D, 0xBDA5, 0x819E, 0xE740, 0x819F, 0xE6FE,
+	0x81A0, 0xBDA6, 0x81A2, 0xE742, 0x81A3, 0xE6FD, 0x81A6, 0xEAE9,
+	0x81A7, 0xEAF3, 0x81A8, 0xBFB1, 0x81A9, 0xBFB0, 0x81AB, 0xEAED,
+	0x81AC, 0xEAEF, 0x81AE, 0xEAEA, 0x81B0, 0xEAEE, 0x81B1, 0xEAE8,
+	0x81B2, 0xEAF1, 0x81B3, 0xBFAF, 0x81B4, 0xEAF0, 0x81B5, 0xEAEC,
+	0x81B7, 0xEAF2, 0x81B9, 0xEAEB, 0x81BA, 0xC174, 0x81BB, 0xEDE8,
+	0x81BC, 0xEDEE, 0x81BD, 0xC178, 0x81BE, 0xC17A, 0x81BF, 0xC177,
+	0x81C0, 0xC176, 0x81C2, 0xC175, 0x81C3, 0xC173, 0x81C4, 0xEDE9,
+	0x81C5, 0xEDEC, 0x81C6, 0xC172, 0x81C7, 0xEDED, 0x81C9, 0xC179,
+	0x81CA, 0xEDEB, 0x81CC, 0xEDEA, 0x81CD, 0xC2C0, 0x81CF, 0xC2C1,
+	0x81D0, 0xF0A1, 0x81D1, 0xF07D, 0x81D2, 0xF07E, 0x81D5, 0xF2C2,
+	0x81D7, 0xF2C1, 0x81D8, 0xC3BE, 0x81D9, 0xF4B4, 0x81DA, 0xC4A4,
+	0x81DB, 0xF4B3, 0x81DD, 0xF5F0, 0x81DE, 0xF745, 0x81DF, 0xC5A6,
+	0x81E0, 0xF943, 0x81E1, 0xF944, 0x81E2, 0xC5D8, 0x81E3, 0xA6DA,
+	0x81E5, 0xAAD7, 0x81E6, 0xDB52, 0x81E7, 0xBB4E, 0x81E8, 0xC17B,
+	0x81E9, 0xEDEF, 0x81EA, 0xA6DB, 0x81EC, 0xAFE5, 0x81ED, 0xAFE4,
+	0x81EE, 0xDB53, 0x81F2, 0xEAF4, 0x81F3, 0xA6DC, 0x81F4, 0xAD50,
+	0x81F7, 0xDB54, 0x81F8, 0xDB55, 0x81F9, 0xDB56, 0x81FA, 0xBB4F,
+	0x81FB, 0xBFB2, 0x81FC, 0xA6DD, 0x81FE, 0xAAD8, 0x81FF, 0xD068,
+	0x8200, 0xAFE6, 0x8201, 0xD370, 0x8202, 0xB2EA, 0x8204, 0xDB57,
+	0x8205, 0xB8A4, 0x8207, 0xBB50, 0x8208, 0xBFB3, 0x8209, 0xC17C,
+	0x820A, 0xC2C2, 0x820B, 0xF4B5, 0x820C, 0xA6DE, 0x820D, 0xAAD9,
+	0x8210, 0xAFE7, 0x8211, 0xD752, 0x8212, 0xB5CE, 0x8214, 0xBB51,
+	0x8215, 0xE3AB, 0x8216, 0xE745, 0x821B, 0xA6DF, 0x821C, 0xB5CF,
+	0x821D, 0xDFA3, 0x821E, 0xBB52, 0x821F, 0xA6E0, 0x8220, 0xCDB1,
+	0x8221, 0xD069, 0x8222, 0xAD51, 0x8225, 0xD372, 0x8228, 0xAFEA,
+	0x822A, 0xAFE8, 0x822B, 0xAFE9, 0x822C, 0xAFEB, 0x822F, 0xD371,
+	0x8232, 0xD757, 0x8233, 0xD754, 0x8234, 0xD756, 0x8235, 0xB2EB,
+	0x8236, 0xB2ED, 0x8237, 0xB2EC, 0x8238, 0xD753, 0x8239, 0xB2EE,
+	0x823A, 0xD755, 0x823C, 0xDB58, 0x823D, 0xDB59, 0x823F, 0xDB5A,
+	0x8240, 0xDFA6, 0x8242, 0xDFA7, 0x8244, 0xDFA5, 0x8245, 0xDFA8,
+	0x8247, 0xB8A5, 0x8249, 0xDFA4, 0x824B, 0xBB53, 0x824E, 0xE74A,
+	0x824F, 0xE746, 0x8250, 0xE749, 0x8251, 0xE74B, 0x8252, 0xE748,
+	0x8253, 0xE747, 0x8255, 0xEAF5, 0x8256, 0xEAF6, 0x8257, 0xEAF7,
+	0x8258, 0xBFB4, 0x8259, 0xBFB5, 0x825A, 0xEDF1, 0x825B, 0xEDF0,
+	0x825C, 0xEDF2, 0x825E, 0xF0A3, 0x825F, 0xF0A2, 0x8261, 0xF2C4,
+	0x8263, 0xF2C5, 0x8264, 0xF2C3, 0x8266, 0xC4A5, 0x8268, 0xF4B6,
+	0x8269, 0xF4B7, 0x826B, 0xF746, 0x826C, 0xF7EF, 0x826D, 0xF8BB,
+	0x826E, 0xA6E1, 0x826F, 0xA87D, 0x8271, 0xC17D, 0x8272, 0xA6E2,
+	0x8274, 0xD758, 0x8275, 0xDB5B, 0x8277, 0xC641, 0x8278, 0xCA4A,
+	0x827C, 0xCA4B, 0x827D, 0xCA4D, 0x827E, 0xA6E3, 0x827F, 0xCA4E,
+	0x8280, 0xCA4C, 0x8283, 0xCBA2, 0x8284, 0xCBA3, 0x8285, 0xCB7B,
+	0x828A, 0xCBA1, 0x828B, 0xA8A1, 0x828D, 0xA8A2, 0x828E, 0xCB7C,
+	0x828F, 0xCB7A, 0x8290, 0xCB79, 0x8291, 0xCB7D, 0x8292, 0xA87E,
+	0x8293, 0xCB7E, 0x8294, 0xD06A, 0x8298, 0xCDB6, 0x8299, 0xAADC,
+	0x829A, 0xCDB5, 0x829B, 0xCDB7, 0x829D, 0xAADB, 0x829E, 0xCDBC,
+	0x829F, 0xAADF, 0x82A0, 0xCDB2, 0x82A1, 0xCDC0, 0x82A2, 0xCDC6,
+	0x82A3, 0xAAE6, 0x82A4, 0xCDC3, 0x82A5, 0xAAE3, 0x82A7, 0xCDB9,
+	0x82A8, 0xCDBF, 0x82A9, 0xCDC1, 0x82AB, 0xCDB4, 0x82AC, 0xAAE2,
+	0x82AD, 0xAADD, 0x82AE, 0xCDBA, 0x82AF, 0xAAE4, 0x82B0, 0xAAE7,
+	0x82B1, 0xAAE1, 0x82B3, 0xAADA, 0x82B4, 0xCDBE, 0x82B5, 0xCDB8,
+	0x82B6, 0xCDC5, 0x82B7, 0xAAE9, 0x82B8, 0xAAE5, 0x82B9, 0xAAE0,
+	0x82BA, 0xCDBD, 0x82BB, 0xAFEC, 0x82BC, 0xCDBB, 0x82BD, 0xAADE,
+	0x82BE, 0xAAE8, 0x82C0, 0xCDB3, 0x82C2, 0xCDC2, 0x82C3, 0xCDC4,
+	0x82D1, 0xAD62, 0x82D2, 0xAD5C, 0x82D3, 0xAD64, 0x82D4, 0xAD61,
+	0x82D5, 0xD071, 0x82D6, 0xD074, 0x82D7, 0xAD5D, 0x82D9, 0xD06B,
+	0x82DB, 0xAD56, 0x82DC, 0xAD60, 0x82DE, 0xAD63, 0x82DF, 0xAD65,
+	0x82E0, 0xD0A2, 0x82E1, 0xD077, 0x82E3, 0xAD55, 0x82E4, 0xD0A1,
+	0x82E5, 0xAD59, 0x82E6, 0xAD57, 0x82E7, 0xAD52, 0x82E8, 0xD06F,
+	0x82EA, 0xD07E, 0x82EB, 0xD073, 0x82EC, 0xD076, 0x82ED, 0xD0A5,
+	0x82EF, 0xAD66, 0x82F0, 0xD07D, 0x82F1, 0xAD5E, 0x82F2, 0xD078,
+	0x82F3, 0xD0A4, 0x82F4, 0xD075, 0x82F5, 0xD079, 0x82F6, 0xD07C,
+	0x82F9, 0xD06D, 0x82FA, 0xD0A3, 0x82FB, 0xD07B, 0x82FE, 0xD06C,
+	0x8300, 0xD070, 0x8301, 0xAD5F, 0x8302, 0xAD5A, 0x8303, 0xAD53,
+	0x8304, 0xAD58, 0x8305, 0xAD54, 0x8306, 0xAD67, 0x8307, 0xD06E,
+	0x8308, 0xD3A5, 0x8309, 0xAD5B, 0x830C, 0xD07A, 0x830D, 0xCE41,
+	0x8316, 0xD3A8, 0x8317, 0xAFFA, 0x8319, 0xD376, 0x831B, 0xD3A3,
+	0x831C, 0xD37D, 0x831E, 0xD3B2, 0x8320, 0xD3AA, 0x8322, 0xD37E,
+	0x8324, 0xD3A9, 0x8325, 0xD378, 0x8326, 0xD37C, 0x8327, 0xD3B5,
+	0x8328, 0xAFFD, 0x8329, 0xD3AD, 0x832A, 0xD3A4, 0x832B, 0xAFED,
+	0x832C, 0xD3B3, 0x832D, 0xD374, 0x832F, 0xD3AC, 0x8331, 0xAFFC,
+	0x8332, 0xAFF7, 0x8333, 0xD373, 0x8334, 0xAFF5, 0x8335, 0xAFF4,
+	0x8336, 0xAFF9, 0x8337, 0xD3AB, 0x8338, 0xAFF1, 0x8339, 0xAFF8,
+	0x833A, 0xD072, 0x833B, 0xDB5C, 0x833C, 0xD3A6, 0x833F, 0xD37A,
+	0x8340, 0xAFFB, 0x8341, 0xD37B, 0x8342, 0xD3A1, 0x8343, 0xAFFE,
+	0x8344, 0xD375, 0x8345, 0xD3AF, 0x8347, 0xD3AE, 0x8348, 0xD3B6,
+	0x8349, 0xAFF3, 0x834A, 0xAFF0, 0x834B, 0xD3B4, 0x834C, 0xD3B0,
+	0x834D, 0xD3A7, 0x834E, 0xD3A2, 0x834F, 0xAFF6, 0x8350, 0xAFF2,
+	0x8351, 0xD377, 0x8352, 0xAFEE, 0x8353, 0xD3B1, 0x8354, 0xAFEF,
+	0x8356, 0xD379, 0x8373, 0xD75E, 0x8374, 0xD760, 0x8375, 0xD765,
+	0x8376, 0xD779, 0x8377, 0xB2FC, 0x8378, 0xB2F2, 0x837A, 0xD75D,
+	0x837B, 0xB2FD, 0x837C, 0xB2FE, 0x837D, 0xD768, 0x837E, 0xD76F,
+	0x837F, 0xD775, 0x8381, 0xD762, 0x8383, 0xD769, 0x8386, 0xB340,
+	0x8387, 0xD777, 0x8388, 0xD772, 0x8389, 0xB2FA, 0x838A, 0xB2F8,
+	0x838B, 0xD76E, 0x838C, 0xD76A, 0x838D, 0xD75C, 0x838E, 0xB2EF,
+	0x838F, 0xD761, 0x8390, 0xD759, 0x8392, 0xB2F7, 0x8393, 0xB2F9,
+	0x8394, 0xD766, 0x8395, 0xD763, 0x8396, 0xB2F4, 0x8397, 0xD773,
+	0x8398, 0xB2F1, 0x8399, 0xD764, 0x839A, 0xD77A, 0x839B, 0xD76C,
+	0x839D, 0xD76B, 0x839E, 0xB2F0, 0x83A0, 0xB2FB, 0x83A2, 0xB2F3,
+	0x83A3, 0xD75A, 0x83A4, 0xD75F, 0x83A5, 0xD770, 0x83A6, 0xD776,
+	0x83A7, 0xB341, 0x83A8, 0xD75B, 0x83A9, 0xD767, 0x83AA, 0xD76D,
+	0x83AB, 0xB2F6, 0x83AE, 0xD778, 0x83AF, 0xD771, 0x83B0, 0xD774,
+	0x83BD, 0xB2F5, 0x83BF, 0xDB6C, 0x83C0, 0xDB60, 0x83C1, 0xB5D7,
+	0x83C2, 0xDB7D, 0x83C3, 0xDBA7, 0x83C4, 0xDBAA, 0x83C5, 0xB5D5,
+	0x83C6, 0xDB68, 0x83C7, 0xDBA3, 0x83C8, 0xDB69, 0x83C9, 0xDB77,
+	0x83CA, 0xB5E2, 0x83CB, 0xDB73, 0x83CC, 0xB5DF, 0x83CE, 0xDB74,
+	0x83CF, 0xDB5D, 0x83D1, 0xDBA4, 0x83D4, 0xB5E8, 0x83D5, 0xDBA1,
+	0x83D6, 0xDB75, 0x83D7, 0xDBAC, 0x83D8, 0xDB70, 0x83D9, 0xDFC8,
+	0x83DB, 0xDBAF, 0x83DC, 0xB5E6, 0x83DD, 0xDB6E, 0x83DE, 0xDB7A,
+	0x83DF, 0xB5E9, 0x83E0, 0xB5D4, 0x83E1, 0xDB72, 0x83E2, 0xDBAD,
+	0x83E3, 0xDB6B, 0x83E4, 0xDB64, 0x83E5, 0xDB6F, 0x83E7, 0xDB63,
+	0x83E8, 0xDB61, 0x83E9, 0xB5D0, 0x83EA, 0xDBA5, 0x83EB, 0xDB6A,
+	0x83EC, 0xDBA8, 0x83EE, 0xDBA9, 0x83EF, 0xB5D8, 0x83F0, 0xB5DD,
+	0x83F1, 0xB5D9, 0x83F2, 0xB5E1, 0x83F3, 0xDB7E, 0x83F4, 0xB5DA,
+	0x83F5, 0xDB76, 0x83F6, 0xDB66, 0x83F8, 0xB5D2, 0x83F9, 0xDB5E,
+	0x83FA, 0xDBA2, 0x83FB, 0xDBAB, 0x83FC, 0xDB65, 0x83FD, 0xB5E0,
+	0x83FE, 0xDBB0, 0x83FF, 0xDB71, 0x8401, 0xDB6D, 0x8403, 0xB5D1,
+	0x8404, 0xB5E5, 0x8406, 0xDB7C, 0x8407, 0xB5E7, 0x8409, 0xDB78,
+	0x840A, 0xB5DC, 0x840B, 0xB5D6, 0x840C, 0xB5DE, 0x840D, 0xB5D3,
+	0x840E, 0xB5E4, 0x840F, 0xDB79, 0x8410, 0xDB67, 0x8411, 0xDB7B,
+	0x8412, 0xDB62, 0x8413, 0xDBA6, 0x841B, 0xDBAE, 0x8423, 0xDB5F,
+	0x8429, 0xDFC7, 0x842B, 0xDFDD, 0x842C, 0xB855, 0x842D, 0xDFCC,
+	0x842F, 0xDFCA, 0x8430, 0xDFB5, 0x8431, 0xB8A9, 0x8432, 0xDFC5,
+	0x8433, 0xDFD9, 0x8434, 0xDFC1, 0x8435, 0xB8B1, 0x8436, 0xDFD8,
+	0x8437, 0xDFBF, 0x8438, 0xB5E3, 0x8439, 0xDFCF, 0x843A, 0xDFC0,
+	0x843B, 0xDFD6, 0x843C, 0xB8B0, 0x843D, 0xB8A8, 0x843F, 0xDFAA,
+	0x8440, 0xDFB2, 0x8442, 0xDFCB, 0x8443, 0xDFC3, 0x8444, 0xDFDC,
+	0x8445, 0xDFC6, 0x8446, 0xB8B6, 0x8447, 0xDFD7, 0x8449, 0xB8AD,
+	0x844B, 0xDFC9, 0x844C, 0xDFD1, 0x844D, 0xDFB6, 0x844E, 0xDFD0,
+	0x8450, 0xDFE1, 0x8451, 0xDFB1, 0x8452, 0xDFD2, 0x8454, 0xDFDF,
+	0x8456, 0xDFAB, 0x8457, 0xB5DB, 0x8459, 0xDFB9, 0x845A, 0xDFB8,
+	0x845B, 0xB8AF, 0x845D, 0xDFBC, 0x845E, 0xDFBE, 0x845F, 0xDFCD,
+	0x8460, 0xDFDE, 0x8461, 0xB8B2, 0x8463, 0xB8B3, 0x8465, 0xDFB0,
+	0x8466, 0xB8AB, 0x8467, 0xDFB4, 0x8468, 0xDFDA, 0x8469, 0xB8B4,
+	0x846B, 0xB8AC, 0x846C, 0xB8AE, 0x846D, 0xB8B5, 0x846E, 0xDFE0,
+	0x846F, 0xDFD3, 0x8470, 0xDFCE, 0x8473, 0xDFBB, 0x8474, 0xDFBA,
+	0x8475, 0xB8AA, 0x8476, 0xDFAC, 0x8477, 0xB8A7, 0x8478, 0xDFC4,
+	0x8479, 0xDFAD, 0x847A, 0xDFC2, 0x847D, 0xDFB7, 0x847E, 0xDFDB,
+	0x8482, 0xB8A6, 0x8486, 0xDFB3, 0x848D, 0xDFAF, 0x848E, 0xDFD5,
+	0x848F, 0xDFAE, 0x8490, 0xBB60, 0x8491, 0xE3D3, 0x8494, 0xE3C2,
+	0x8497, 0xE3AC, 0x8498, 0xE3CA, 0x8499, 0xBB58, 0x849A, 0xE3BB,
+	0x849B, 0xE3C5, 0x849C, 0xBB5B, 0x849D, 0xE3BE, 0x849E, 0xBB59,
+	0x849F, 0xE3AF, 0x84A0, 0xE3CD, 0x84A1, 0xE3AE, 0x84A2, 0xE3C1,
+	0x84A4, 0xE3AD, 0x84A7, 0xE3BF, 0x84A8, 0xE3C8, 0x84A9, 0xE3C6,
+	0x84AA, 0xE3BA, 0x84AB, 0xE3B5, 0x84AC, 0xE3B3, 0x84AE, 0xE3B4,
+	0x84AF, 0xE3C7, 0x84B0, 0xE3D2, 0x84B1, 0xE3BC, 0x84B2, 0xBB5A,
+	0x84B4, 0xE3B7, 0x84B6, 0xE3CB, 0x84B8, 0xBB5D, 0x84B9, 0xE3B6,
+	0x84BA, 0xE3B0, 0x84BB, 0xE3C0, 0x84BC, 0xBB61, 0x84BF, 0xBB55,
+	0x84C0, 0xBB5E, 0x84C1, 0xE3B8, 0x84C2, 0xE3B2, 0x84C4, 0xBB57,
+	0x84C5, 0xDFD4, 0x84C6, 0xBB56, 0x84C7, 0xE3C3, 0x84C9, 0xBB54,
+	0x84CA, 0xBB63, 0x84CB, 0xBB5C, 0x84CC, 0xE3C4, 0x84CD, 0xE3B9,
+	0x84CE, 0xE3B1, 0x84CF, 0xE3CC, 0x84D0, 0xE3BD, 0x84D1, 0xBB62,
+	0x84D2, 0xE3D0, 0x84D3, 0xBB5F, 0x84D4, 0xE3CF, 0x84D6, 0xE3C9,
+	0x84D7, 0xE3CE, 0x84DB, 0xE3D1, 0x84E7, 0xE773, 0x84E8, 0xE774,
+	0x84E9, 0xE767, 0x84EA, 0xE766, 0x84EB, 0xE762, 0x84EC, 0xBDB4,
+	0x84EE, 0xBDAC, 0x84EF, 0xE776, 0x84F0, 0xE775, 0x84F1, 0xDFA9,
+	0x84F2, 0xE75F, 0x84F3, 0xE763, 0x84F4, 0xE75D, 0x84F6, 0xE770,
+	0x84F7, 0xE761, 0x84F9, 0xE777, 0x84FA, 0xE75A, 0x84FB, 0xE758,
+	0x84FC, 0xE764, 0x84FD, 0xE76E, 0x84FE, 0xE769, 0x84FF, 0xBDB6,
+	0x8500, 0xE74F, 0x8502, 0xE76D, 0x8506, 0xBDB7, 0x8507, 0xDFBD,
+	0x8508, 0xE75B, 0x8509, 0xE752, 0x850A, 0xE755, 0x850B, 0xE77B,
+	0x850C, 0xE75C, 0x850D, 0xE753, 0x850E, 0xE751, 0x850F, 0xE74E,
+	0x8511, 0xBDB0, 0x8512, 0xE765, 0x8513, 0xBDAF, 0x8514, 0xBDB3,
+	0x8515, 0xE760, 0x8516, 0xE768, 0x8517, 0xBDA9, 0x8518, 0xE778,
+	0x8519, 0xE77C, 0x851A, 0xBDAB, 0x851C, 0xE757, 0x851D, 0xE76B,
+	0x851E, 0xE76F, 0x851F, 0xE754, 0x8520, 0xE779, 0x8521, 0xBDB2,
+	0x8523, 0xBDB1, 0x8524, 0xE74C, 0x8525, 0xBDB5, 0x8526, 0xE772,
+	0x8527, 0xE756, 0x8528, 0xE76A, 0x8529, 0xE750, 0x852A, 0xE75E,
+	0x852B, 0xE759, 0x852C, 0xBDAD, 0x852D, 0xBDAE, 0x852E, 0xE76C,
+	0x852F, 0xE77D, 0x8530, 0xE77A, 0x8531, 0xE771, 0x853B, 0xE74D,
+	0x853D, 0xBDAA, 0x853E, 0xEB49, 0x8540, 0xEB40, 0x8541, 0xEB43,
+	0x8543, 0xBFBB, 0x8544, 0xEB45, 0x8545, 0xEAF9, 0x8546, 0xEB41,
+	0x8547, 0xEB47, 0x8548, 0xBFB8, 0x8549, 0xBFBC, 0x854A, 0xBFB6,
+	0x854D, 0xEAFB, 0x854E, 0xEB4C, 0x8551, 0xEB46, 0x8553, 0xEAFC,
+	0x8554, 0xEB55, 0x8555, 0xEB4F, 0x8556, 0xEAF8, 0x8557, 0xEE46,
+	0x8558, 0xEAFE, 0x8559, 0xBFB7, 0x855B, 0xEB4A, 0x855D, 0xEB54,
+	0x855E, 0xBFBF, 0x8560, 0xEB51, 0x8561, 0xEAFD, 0x8562, 0xEB44,
+	0x8563, 0xEB48, 0x8564, 0xEB42, 0x8565, 0xEB56, 0x8566, 0xEB53,
+	0x8567, 0xEB50, 0x8568, 0xBFB9, 0x8569, 0xBFBA, 0x856A, 0xBFBE,
+	0x856B, 0xEAFA, 0x856C, 0xEB57, 0x856D, 0xBFBD, 0x856E, 0xEB4D,
+	0x8571, 0xEB4B, 0x8575, 0xEB4E, 0x8576, 0xEE53, 0x8577, 0xEE40,
+	0x8578, 0xEE45, 0x8579, 0xEE52, 0x857A, 0xEE44, 0x857B, 0xEDFB,
+	0x857C, 0xEE41, 0x857E, 0xC1A2, 0x8580, 0xEDF4, 0x8581, 0xEE4D,
+	0x8582, 0xEE4F, 0x8583, 0xEDF3, 0x8584, 0xC1A1, 0x8585, 0xEE51,
+	0x8586, 0xEE49, 0x8587, 0xC1A8, 0x8588, 0xEE50, 0x8589, 0xEE42,
+	0x858A, 0xC1AA, 0x858B, 0xEDF9, 0x858C, 0xEB52, 0x858D, 0xEE4A,
+	0x858E, 0xEE47, 0x858F, 0xEDF5, 0x8590, 0xEE55, 0x8591, 0xC1A4,
+	0x8594, 0xC1A5, 0x8595, 0xEDF7, 0x8596, 0xEE48, 0x8598, 0xEE54,
+	0x8599, 0xEE4B, 0x859A, 0xEDFD, 0x859B, 0xC1A7, 0x859C, 0xC1A3,
+	0x859D, 0xEE4C, 0x859E, 0xEDFE, 0x859F, 0xEE56, 0x85A0, 0xEDF8,
+	0x85A1, 0xEE43, 0x85A2, 0xEE4E, 0x85A3, 0xEDFA, 0x85A4, 0xEDFC,
+	0x85A6, 0xC2CB, 0x85A7, 0xEDF6, 0x85A8, 0xC1A9, 0x85A9, 0xC2C4,
+	0x85AA, 0xC17E, 0x85AF, 0xC1A6, 0x85B0, 0xC2C8, 0x85B1, 0xF0B3,
+	0x85B3, 0xF0A9, 0x85B4, 0xF0A4, 0x85B5, 0xF0AA, 0x85B6, 0xF0B4,
+	0x85B7, 0xF0B8, 0x85B8, 0xF0B7, 0x85B9, 0xC2CA, 0x85BA, 0xC2C9,
+	0x85BD, 0xF0AB, 0x85BE, 0xF0B9, 0x85BF, 0xF0AE, 0x85C0, 0xF0A6,
+	0x85C2, 0xF0A8, 0x85C3, 0xF0A7, 0x85C4, 0xF0AD, 0x85C5, 0xF0B2,
+	0x85C6, 0xF0A5, 0x85C7, 0xF0AC, 0x85C8, 0xF0B1, 0x85C9, 0xC2C7,
+	0x85CB, 0xF0AF, 0x85CD, 0xC2C5, 0x85CE, 0xF0B0, 0x85CF, 0xC2C3,
+	0x85D0, 0xC2C6, 0x85D1, 0xF2D5, 0x85D2, 0xF0B5, 0x85D5, 0xC3C2,
+	0x85D7, 0xF2CD, 0x85D8, 0xF2D1, 0x85D9, 0xF2C9, 0x85DA, 0xF2CC,
+	0x85DC, 0xF2D4, 0x85DD, 0xC3C0, 0x85DE, 0xF2D9, 0x85DF, 0xF2D2,
+	0x85E1, 0xF2CA, 0x85E2, 0xF2DA, 0x85E3, 0xF2D3, 0x85E4, 0xC3C3,
+	0x85E5, 0xC3C4, 0x85E6, 0xF2D7, 0x85E8, 0xF2CB, 0x85E9, 0xC3BF,
+	0x85EA, 0xC3C1, 0x85EB, 0xF2C6, 0x85EC, 0xF2CE, 0x85ED, 0xF2C8,
+	0x85EF, 0xF2D8, 0x85F0, 0xF2D6, 0x85F1, 0xF2C7, 0x85F2, 0xF2CF,
+	0x85F6, 0xF4BE, 0x85F7, 0xC3C5, 0x85F8, 0xF2D0, 0x85F9, 0xC4A7,
+	0x85FA, 0xC4A9, 0x85FB, 0xC4A6, 0x85FD, 0xF4C3, 0x85FE, 0xF4BB,
+	0x85FF, 0xF4B9, 0x8600, 0xF4BD, 0x8601, 0xF4BA, 0x8604, 0xF4BF,
+	0x8605, 0xF4C1, 0x8606, 0xC4AA, 0x8607, 0xC4AC, 0x8609, 0xF4C0,
+	0x860A, 0xC4AD, 0x860B, 0xC4AB, 0x860C, 0xF4C2, 0x8611, 0xC4A8,
+	0x8617, 0xC4F4, 0x8618, 0xF5F1, 0x8619, 0xF5F7, 0x861A, 0xC4F6,
+	0x861B, 0xF4BC, 0x861C, 0xF5F6, 0x861E, 0xF5FD, 0x861F, 0xF5F4,
+	0x8620, 0xF5FB, 0x8621, 0xF5FA, 0x8622, 0xF4B8, 0x8623, 0xF5F5,
+	0x8624, 0xF0B6, 0x8625, 0xF5FE, 0x8626, 0xF5F3, 0x8627, 0xF5F8,
+	0x8629, 0xF5FC, 0x862A, 0xF5F2, 0x862C, 0xF74A, 0x862D, 0xC4F5,
+	0x862E, 0xF5F9, 0x8631, 0xF7F4, 0x8632, 0xF74B, 0x8633, 0xF749,
+	0x8634, 0xF747, 0x8635, 0xF748, 0x8636, 0xF74C, 0x8638, 0xC5D9,
+	0x8639, 0xF7F2, 0x863A, 0xF7F0, 0x863B, 0xF7F5, 0x863C, 0xF7F3,
+	0x863E, 0xF7F6, 0x863F, 0xC5DA, 0x8640, 0xF7F1, 0x8643, 0xF8BC,
+	0x8646, 0xF945, 0x8647, 0xF946, 0x8648, 0xF947, 0x864B, 0xF9C7,
+	0x864C, 0xF9BD, 0x864D, 0xCA4F, 0x864E, 0xAAEA, 0x8650, 0xAD68,
+	0x8652, 0xD3B8, 0x8653, 0xD3B7, 0x8654, 0xB040, 0x8655, 0xB342,
+	0x8656, 0xD77C, 0x8659, 0xD77B, 0x865B, 0xB5EA, 0x865C, 0xB8B8,
+	0x865E, 0xB8B7, 0x865F, 0xB8B9, 0x8661, 0xE3D4, 0x8662, 0xE77E,
+	0x8663, 0xEB58, 0x8664, 0xEB5A, 0x8665, 0xEB59, 0x8667, 0xC1AB,
+	0x8668, 0xEE57, 0x8669, 0xF0BA, 0x866A, 0xF9A5, 0x866B, 0xA6E4,
+	0x866D, 0xCDC9, 0x866E, 0xCDCA, 0x866F, 0xCDC8, 0x8670, 0xCDC7,
+	0x8671, 0xAAEB, 0x8673, 0xD0A9, 0x8674, 0xD0A7, 0x8677, 0xD0A6,
+	0x8679, 0xAD69, 0x867A, 0xAD6B, 0x867B, 0xAD6A, 0x867C, 0xD0A8,
+	0x8685, 0xD3C4, 0x8686, 0xD3C1, 0x8687, 0xD3BF, 0x868A, 0xB041,
+	0x868B, 0xD3C2, 0x868C, 0xB046, 0x868D, 0xD3BC, 0x868E, 0xD3CB,
+	0x8690, 0xD3CD, 0x8691, 0xD3BD, 0x8693, 0xB043, 0x8694, 0xD3CE,
+	0x8695, 0xD3C9, 0x8696, 0xD3BB, 0x8697, 0xD3C0, 0x8698, 0xD3CA,
+	0x8699, 0xD3C6, 0x869A, 0xD3C3, 0x869C, 0xB048, 0x869D, 0xD3CC,
+	0x869E, 0xD3BE, 0x86A1, 0xD3C7, 0x86A2, 0xD3B9, 0x86A3, 0xB047,
+	0x86A4, 0xB044, 0x86A5, 0xD3C5, 0x86A7, 0xD3C8, 0x86A8, 0xD3BA,
+	0x86A9, 0xB045, 0x86AA, 0xB042, 0x86AF, 0xB34C, 0x86B0, 0xD7A5,
+	0x86B1, 0xB34B, 0x86B3, 0xD7A8, 0x86B4, 0xD7AB, 0x86B5, 0xB348,
+	0x86B6, 0xB346, 0x86B7, 0xD77E, 0x86B8, 0xD7A9, 0x86B9, 0xD7A7,
+	0x86BA, 0xD7A4, 0x86BB, 0xD7AC, 0x86BC, 0xD7AD, 0x86BD, 0xD7AF,
+	0x86BE, 0xD7B0, 0x86BF, 0xD77D, 0x86C0, 0xB345, 0x86C1, 0xD7A2,
+	0x86C2, 0xD7A1, 0x86C3, 0xD7AE, 0x86C4, 0xB347, 0x86C5, 0xD7A3,
+	0x86C6, 0xB349, 0x86C7, 0xB344, 0x86C8, 0xD7A6, 0x86C9, 0xB34D,
+	0x86CB, 0xB34A, 0x86CC, 0xD7AA, 0x86D0, 0xB5F1, 0x86D1, 0xDBBF,
+	0x86D3, 0xDBB4, 0x86D4, 0xB5EE, 0x86D6, 0xDFE7, 0x86D7, 0xDBBD,
+	0x86D8, 0xDBB1, 0x86D9, 0xB5EC, 0x86DA, 0xDBB6, 0x86DB, 0xB5EF,
+	0x86DC, 0xDBBA, 0x86DD, 0xDBB8, 0x86DE, 0xB5F2, 0x86DF, 0xB5EB,
+	0x86E2, 0xDBB2, 0x86E3, 0xDBB5, 0x86E4, 0xB5F0, 0x86E6, 0xDBB3,
+	0x86E8, 0xDBBE, 0x86E9, 0xDBBC, 0x86EA, 0xDBB7, 0x86EB, 0xDBB9,
+	0x86EC, 0xDBBB, 0x86ED, 0xB5ED, 0x86F5, 0xDFE8, 0x86F6, 0xDFEE,
+	0x86F7, 0xDFE4, 0x86F8, 0xDFEA, 0x86F9, 0xB8BA, 0x86FA, 0xDFE6,
+	0x86FB, 0xB8C0, 0x86FE, 0xB8BF, 0x8700, 0xB8BE, 0x8701, 0xDFED,
+	0x8702, 0xB8C1, 0x8703, 0xB8C2, 0x8704, 0xDFE3, 0x8705, 0xDFF0,
+	0x8706, 0xB8C3, 0x8707, 0xB8BD, 0x8708, 0xB8BC, 0x8709, 0xDFEC,
+	0x870A, 0xB8C4, 0x870B, 0xDFE2, 0x870C, 0xDFE5, 0x870D, 0xDFEF,
+	0x870E, 0xDFEB, 0x8711, 0xE3F4, 0x8712, 0xE3E9, 0x8713, 0xB8BB,
+	0x8718, 0xBB6A, 0x8719, 0xE3DD, 0x871A, 0xE3F2, 0x871B, 0xE3DE,
+	0x871C, 0xBB65, 0x871E, 0xE3DB, 0x8720, 0xE3E4, 0x8721, 0xE3DC,
+	0x8722, 0xBB67, 0x8723, 0xE3D6, 0x8724, 0xE3F1, 0x8725, 0xBB68,
+	0x8726, 0xE3EE, 0x8727, 0xE3EF, 0x8728, 0xE3D7, 0x8729, 0xBB6D,
+	0x872A, 0xE3E6, 0x872C, 0xE3E0, 0x872D, 0xE3E7, 0x872E, 0xE3DA,
+	0x8730, 0xE3F3, 0x8731, 0xE3EB, 0x8732, 0xE3E5, 0x8733, 0xE3D5,
+	0x8734, 0xBB69, 0x8735, 0xE3EC, 0x8737, 0xBB6C, 0x8738, 0xE3F0,
+	0x873A, 0xE3EA, 0x873B, 0xBB66, 0x873C, 0xE3E8, 0x873E, 0xE3E2,
+	0x873F, 0xBB64, 0x8740, 0xE3D9, 0x8741, 0xE3E1, 0x8742, 0xE3ED,
+	0x8743, 0xE3DF, 0x8746, 0xE3E3, 0x874C, 0xBDC1, 0x874D, 0xDFE9,
+	0x874E, 0xE7B2, 0x874F, 0xE7BB, 0x8750, 0xE7B1, 0x8751, 0xE7AD,
+	0x8752, 0xE7AA, 0x8753, 0xBDC2, 0x8754, 0xE7A8, 0x8755, 0xBB6B,
+	0x8756, 0xE7A1, 0x8757, 0xBDC0, 0x8758, 0xE7A7, 0x8759, 0xBDBF,
+	0x875A, 0xE7AC, 0x875B, 0xE7A9, 0x875C, 0xE7B9, 0x875D, 0xE7B4,
+	0x875E, 0xE7AE, 0x875F, 0xE7B3, 0x8760, 0xBDBB, 0x8761, 0xE7AB,
+	0x8762, 0xE7BE, 0x8763, 0xE7A2, 0x8764, 0xE7A3, 0x8765, 0xE7BA,
+	0x8766, 0xBDBC, 0x8767, 0xE7BF, 0x8768, 0xBDBE, 0x8769, 0xE7C0,
+	0x876A, 0xE7B0, 0x876B, 0xE3D8, 0x876C, 0xE7B6, 0x876D, 0xE7AF,
+	0x876E, 0xE7B8, 0x876F, 0xE7B5, 0x8773, 0xE7A6, 0x8774, 0xBDB9,
+	0x8775, 0xE7BD, 0x8776, 0xBDBA, 0x8777, 0xE7A4, 0x8778, 0xBDBD,
+	0x8779, 0xEB64, 0x877A, 0xE7B7, 0x877B, 0xE7BC, 0x8781, 0xEB61,
+	0x8782, 0xBDB8, 0x8783, 0xBFC0, 0x8784, 0xEB6B, 0x8785, 0xEB67,
+	0x8787, 0xEB65, 0x8788, 0xEB60, 0x8789, 0xEB6F, 0x878D, 0xBFC4,
+	0x878F, 0xEB5C, 0x8790, 0xEB68, 0x8791, 0xEB69, 0x8792, 0xEB5F,
+	0x8793, 0xEB5E, 0x8794, 0xEB6C, 0x8796, 0xEB62, 0x8797, 0xEB5D,
+	0x8798, 0xEB63, 0x879A, 0xEB6E, 0x879B, 0xEB5B, 0x879C, 0xEB6D,
+	0x879D, 0xEB6A, 0x879E, 0xBFC2, 0x879F, 0xBFC1, 0x87A2, 0xBFC3,
+	0x87A3, 0xEB66, 0x87A4, 0xF0CB, 0x87AA, 0xEE59, 0x87AB, 0xC1B1,
+	0x87AC, 0xEE5D, 0x87AD, 0xEE5A, 0x87AE, 0xEE61, 0x87AF, 0xEE67,
+	0x87B0, 0xEE5C, 0x87B2, 0xEE70, 0x87B3, 0xC1AE, 0x87B4, 0xEE6A,
+	0x87B5, 0xEE5F, 0x87B6, 0xEE6B, 0x87B7, 0xEE66, 0x87B8, 0xEE6D,
+	0x87B9, 0xEE5E, 0x87BA, 0xC1B3, 0x87BB, 0xC1B2, 0x87BC, 0xEE60,
+	0x87BD, 0xEE6E, 0x87BE, 0xEE58, 0x87BF, 0xEE6C, 0x87C0, 0xC1AC,
+	0x87C2, 0xEE64, 0x87C3, 0xEE63, 0x87C4, 0xEE68, 0x87C5, 0xEE5B,
+	0x87C6, 0xC1B0, 0x87C8, 0xC1B4, 0x87C9, 0xEE62, 0x87CA, 0xEE69,
+	0x87CB, 0xC1B5, 0x87CC, 0xEE65, 0x87D1, 0xC1AD, 0x87D2, 0xC1AF,
+	0x87D3, 0xF0C7, 0x87D4, 0xF0C5, 0x87D7, 0xF0CC, 0x87D8, 0xF0C9,
+	0x87D9, 0xF0CD, 0x87DB, 0xF0BE, 0x87DC, 0xF0C6, 0x87DD, 0xF0D1,
+	0x87DE, 0xEE6F, 0x87DF, 0xF0C2, 0x87E0, 0xC2CF, 0x87E1, 0xE7A5,
+	0x87E2, 0xF0BD, 0x87E3, 0xF0CA, 0x87E4, 0xF0C4, 0x87E5, 0xF0C1,
+	0x87E6, 0xF0BC, 0x87E7, 0xF0BB, 0x87E8, 0xF0D0, 0x87EA, 0xF0C0,
+	0x87EB, 0xF0BF, 0x87EC, 0xC2CD, 0x87ED, 0xF0C8, 0x87EF, 0xC2CC,
+	0x87F2, 0xC2CE, 0x87F3, 0xF0C3, 0x87F4, 0xF0CF, 0x87F6, 0xF2DE,
+	0x87F7, 0xF2DF, 0x87F9, 0xC3C9, 0x87FA, 0xF2DC, 0x87FB, 0xC3C6,
+	0x87FC, 0xF2E4, 0x87FE, 0xC3CA, 0x87FF, 0xF2E6, 0x8800, 0xF2DB,
+	0x8801, 0xF0CE, 0x8802, 0xF2E8, 0x8803, 0xF2DD, 0x8805, 0xC3C7,
+	0x8806, 0xF2E3, 0x8808, 0xF2E5, 0x8809, 0xF2E0, 0x880A, 0xF2E7,
+	0x880B, 0xF2E2, 0x880C, 0xF2E1, 0x880D, 0xC3C8, 0x8810, 0xF4C5,
+	0x8811, 0xF4C6, 0x8813, 0xF4C8, 0x8814, 0xC4AE, 0x8815, 0xC4AF,
+	0x8816, 0xF4C9, 0x8817, 0xF4C7, 0x8819, 0xF4C4, 0x881B, 0xF642,
+	0x881C, 0xF645, 0x881D, 0xF641, 0x881F, 0xC4FA, 0x8820, 0xF643,
+	0x8821, 0xC4F9, 0x8822, 0xC4F8, 0x8823, 0xC4F7, 0x8824, 0xF644,
+	0x8825, 0xF751, 0x8826, 0xF74F, 0x8828, 0xF74E, 0x8829, 0xF640,
+	0x882A, 0xF750, 0x882B, 0xF646, 0x882C, 0xF74D, 0x882E, 0xF7F9,
+	0x882F, 0xF7D7, 0x8830, 0xF7F7, 0x8831, 0xC5DB, 0x8832, 0xF7F8,
+	0x8833, 0xF7FA, 0x8835, 0xF8BF, 0x8836, 0xC5FA, 0x8837, 0xF8BE,
+	0x8838, 0xF8BD, 0x8839, 0xC5FB, 0x883B, 0xC65A, 0x883C, 0xF96E,
+	0x883D, 0xF9A7, 0x883E, 0xF9A6, 0x883F, 0xF9A8, 0x8840, 0xA6E5,
+	0x8841, 0xD0AA, 0x8843, 0xD3CF, 0x8844, 0xD3D0, 0x8848, 0xDBC0,
+	0x884A, 0xF647, 0x884B, 0xF8C0, 0x884C, 0xA6E6, 0x884D, 0xAD6C,
+	0x884E, 0xD0AB, 0x8852, 0xD7B1, 0x8853, 0xB34E, 0x8855, 0xDBC2,
+	0x8856, 0xDBC1, 0x8857, 0xB5F3, 0x8859, 0xB8C5, 0x885A, 0xE7C1,
+	0x885B, 0xBDC3, 0x885D, 0xBDC4, 0x8861, 0xBFC5, 0x8862, 0xC5FC,
+	0x8863, 0xA6E7, 0x8867, 0xD0AC, 0x8868, 0xAAED, 0x8869, 0xD0AE,
+	0x886A, 0xD0AD, 0x886B, 0xAD6D, 0x886D, 0xD3D1, 0x886F, 0xD3D8,
+	0x8870, 0xB049, 0x8871, 0xD3D6, 0x8872, 0xD3D4, 0x8874, 0xD3DB,
+	0x8875, 0xD3D2, 0x8876, 0xD3D3, 0x8877, 0xB04A, 0x8879, 0xB04E,
+	0x887C, 0xD3DC, 0x887D, 0xB04D, 0x887E, 0xD3DA, 0x887F, 0xD3D7,
+	0x8880, 0xD3D5, 0x8881, 0xB04B, 0x8882, 0xB04C, 0x8883, 0xD3D9,
+	0x8888, 0xB350, 0x8889, 0xD7B2, 0x888B, 0xB355, 0x888C, 0xD7C2,
+	0x888D, 0xB354, 0x888E, 0xD7C4, 0x8891, 0xD7B8, 0x8892, 0xB352,
+	0x8893, 0xD7C3, 0x8895, 0xD7B3, 0x8896, 0xB353, 0x8897, 0xD7BF,
+	0x8898, 0xD7BB, 0x8899, 0xD7BD, 0x889A, 0xD7B7, 0x889B, 0xD7BE,
+	0x889E, 0xB34F, 0x889F, 0xD7BA, 0x88A1, 0xD7B9, 0x88A2, 0xD7B5,
+	0x88A4, 0xD7C0, 0x88A7, 0xD7BC, 0x88A8, 0xD7B4, 0x88AA, 0xD7B6,
+	0x88AB, 0xB351, 0x88AC, 0xD7C1, 0x88B1, 0xB5F6, 0x88B2, 0xDBCD,
+	0x88B6, 0xDBC9, 0x88B7, 0xDBCB, 0x88B8, 0xDBC6, 0x88B9, 0xDBC5,
+	0x88BA, 0xDBC3, 0x88BC, 0xDBCA, 0x88BD, 0xDBCC, 0x88BE, 0xDBC8,
+	0x88C0, 0xDBC7, 0x88C1, 0xB5F4, 0x88C2, 0xB5F5, 0x88C9, 0xDBCF,
+	0x88CA, 0xB8CD, 0x88CB, 0xDFF2, 0x88CC, 0xDFF8, 0x88CD, 0xDFF3,
+	0x88CE, 0xDFF4, 0x88CF, 0xF9D8, 0x88D0, 0xDFF9, 0x88D2, 0xB8CF,
+	0x88D4, 0xB8C7, 0x88D5, 0xB8CE, 0x88D6, 0xDFF1, 0x88D7, 0xDBC4,
+	0x88D8, 0xB8CA, 0x88D9, 0xB8C8, 0x88DA, 0xDFF7, 0x88DB, 0xDFF6,
+	0x88DC, 0xB8C9, 0x88DD, 0xB8CB, 0x88DE, 0xDFF5, 0x88DF, 0xB8C6,
+	0x88E1, 0xB8CC, 0x88E7, 0xE3F6, 0x88E8, 0xBB74, 0x88EB, 0xE442,
+	0x88EC, 0xE441, 0x88EE, 0xE3FB, 0x88EF, 0xBB76, 0x88F0, 0xE440,
+	0x88F1, 0xE3F7, 0x88F2, 0xE3F8, 0x88F3, 0xBB6E, 0x88F4, 0xBB70,
+	0x88F6, 0xE3FD, 0x88F7, 0xE3F5, 0x88F8, 0xBB72, 0x88F9, 0xBB71,
+	0x88FA, 0xE3F9, 0x88FB, 0xE3FE, 0x88FC, 0xE3FC, 0x88FD, 0xBB73,
+	0x88FE, 0xE3FA, 0x8901, 0xDBCE, 0x8902, 0xBB6F, 0x8905, 0xE7C2,
+	0x8906, 0xE7C9, 0x8907, 0xBDC6, 0x8909, 0xE7CD, 0x890A, 0xBDCA,
+	0x890B, 0xE7C5, 0x890C, 0xE7C3, 0x890E, 0xE7CC, 0x8910, 0xBDC5,
+	0x8911, 0xE7CB, 0x8912, 0xBDC7, 0x8913, 0xBDC8, 0x8914, 0xE7C4,
+	0x8915, 0xBDC9, 0x8916, 0xE7CA, 0x8917, 0xE7C6, 0x8918, 0xE7C7,
+	0x8919, 0xE7C8, 0x891A, 0xBB75, 0x891E, 0xEB70, 0x891F, 0xEB7C,
+	0x8921, 0xBFCA, 0x8922, 0xEB77, 0x8923, 0xEB79, 0x8925, 0xBFC8,
+	0x8926, 0xEB71, 0x8927, 0xEB75, 0x8929, 0xEB78, 0x892A, 0xBFC6,
+	0x892B, 0xBFC9, 0x892C, 0xEB7B, 0x892D, 0xEB73, 0x892E, 0xEB74,
+	0x892F, 0xEB7A, 0x8930, 0xEB72, 0x8931, 0xEB76, 0x8932, 0xBFC7,
+	0x8933, 0xEE72, 0x8935, 0xEE71, 0x8936, 0xC1B7, 0x8937, 0xEE77,
+	0x8938, 0xC1B9, 0x893B, 0xC1B6, 0x893C, 0xEE73, 0x893D, 0xC1BA,
+	0x893E, 0xEE74, 0x8941, 0xEE75, 0x8942, 0xEE78, 0x8944, 0xC1B8,
+	0x8946, 0xF0D6, 0x8949, 0xF0D9, 0x894B, 0xF0D3, 0x894C, 0xF0D5,
+	0x894F, 0xF0D4, 0x8950, 0xF0D7, 0x8951, 0xF0D8, 0x8952, 0xEE76,
+	0x8953, 0xF0D2, 0x8956, 0xC3CD, 0x8957, 0xF2EC, 0x8958, 0xF2EF,
+	0x8959, 0xF2F1, 0x895A, 0xF2EA, 0x895B, 0xF2EB, 0x895C, 0xF2EE,
+	0x895D, 0xF2F0, 0x895E, 0xC3CE, 0x895F, 0xC3CC, 0x8960, 0xC3CB,
+	0x8961, 0xF2ED, 0x8962, 0xF2E9, 0x8963, 0xF4CA, 0x8964, 0xC4B0,
+	0x8966, 0xF4CB, 0x8969, 0xF649, 0x896A, 0xC4FB, 0x896B, 0xF64B,
+	0x896C, 0xC4FC, 0x896D, 0xF648, 0x896E, 0xF64A, 0x896F, 0xC5A8,
+	0x8971, 0xF752, 0x8972, 0xC5A7, 0x8973, 0xF7FD, 0x8974, 0xF7FC,
+	0x8976, 0xF7FB, 0x8979, 0xF948, 0x897A, 0xF949, 0x897B, 0xF94B,
+	0x897C, 0xF94A, 0x897E, 0xCA50, 0x897F, 0xA6E8, 0x8981, 0xAD6E,
+	0x8982, 0xD7C5, 0x8983, 0xB5F7, 0x8985, 0xDFFA, 0x8986, 0xC2D0,
+	0x8988, 0xF2F2, 0x898B, 0xA8A3, 0x898F, 0xB357, 0x8993, 0xB356,
+	0x8995, 0xDBD0, 0x8996, 0xB5F8, 0x8997, 0xDBD2, 0x8998, 0xDBD1,
+	0x899B, 0xDFFB, 0x899C, 0xB8D0, 0x899D, 0xE443, 0x899E, 0xE446,
+	0x899F, 0xE445, 0x89A1, 0xE444, 0x89A2, 0xE7CE, 0x89A3, 0xE7D0,
+	0x89A4, 0xE7CF, 0x89A6, 0xBFCC, 0x89AA, 0xBFCB, 0x89AC, 0xC1BB,
+	0x89AD, 0xEE79, 0x89AE, 0xEE7B, 0x89AF, 0xEE7A, 0x89B2, 0xC2D1,
+	0x89B6, 0xF2F4, 0x89B7, 0xF2F3, 0x89B9, 0xF4CC, 0x89BA, 0xC4B1,
+	0x89BD, 0xC4FD, 0x89BE, 0xF754, 0x89BF, 0xF753, 0x89C0, 0xC65B,
+	0x89D2, 0xA8A4, 0x89D3, 0xD0AF, 0x89D4, 0xAD6F, 0x89D5, 0xD7C8,
+	0x89D6, 0xD7C6, 0x89D9, 0xD7C7, 0x89DA, 0xDBD4, 0x89DB, 0xDBD5,
+	0x89DC, 0xE043, 0x89DD, 0xDBD3, 0x89DF, 0xDFFC, 0x89E0, 0xE041,
+	0x89E1, 0xE040, 0x89E2, 0xE042, 0x89E3, 0xB8D1, 0x89E4, 0xDFFE,
+	0x89E5, 0xDFFD, 0x89E6, 0xE044, 0x89E8, 0xE449, 0x89E9, 0xE447,
+	0x89EB, 0xE448, 0x89EC, 0xE7D3, 0x89ED, 0xE7D1, 0x89F0, 0xE7D2,
+	0x89F1, 0xEB7D, 0x89F2, 0xEE7C, 0x89F3, 0xEE7D, 0x89F4, 0xC2D2,
+	0x89F6, 0xF2F5, 0x89F7, 0xF4CD, 0x89F8, 0xC4B2, 0x89FA, 0xF64C,
+	0x89FB, 0xF755, 0x89FC, 0xC5A9, 0x89FE, 0xF7FE, 0x89FF, 0xF94C,
+	0x8A00, 0xA8A5, 0x8A02, 0xAD71, 0x8A03, 0xAD72, 0x8A04, 0xD0B0,
+	0x8A07, 0xD0B1, 0x8A08, 0xAD70, 0x8A0A, 0xB054, 0x8A0C, 0xB052,
+	0x8A0E, 0xB051, 0x8A0F, 0xB058, 0x8A10, 0xB050, 0x8A11, 0xB059,
+	0x8A12, 0xD3DD, 0x8A13, 0xB056, 0x8A15, 0xB053, 0x8A16, 0xB057,
+	0x8A17, 0xB055, 0x8A18, 0xB04F, 0x8A1B, 0xB35F, 0x8A1D, 0xB359,
+	0x8A1E, 0xD7CC, 0x8A1F, 0xB35E, 0x8A22, 0xB360, 0x8A23, 0xB35A,
+	0x8A25, 0xB35B, 0x8A27, 0xD7CA, 0x8A2A, 0xB358, 0x8A2C, 0xD7CB,
+	0x8A2D, 0xB35D, 0x8A30, 0xD7C9, 0x8A31, 0xB35C, 0x8A34, 0xB644,
+	0x8A36, 0xB646, 0x8A39, 0xDBD8, 0x8A3A, 0xB645, 0x8A3B, 0xB5F9,
+	0x8A3C, 0xB5FD, 0x8A3E, 0xB8E4, 0x8A3F, 0xE049, 0x8A40, 0xDBDA,
+	0x8A41, 0xB5FE, 0x8A44, 0xDBDD, 0x8A45, 0xDBDE, 0x8A46, 0xB643,
+	0x8A48, 0xDBE0, 0x8A4A, 0xDBE2, 0x8A4C, 0xDBE3, 0x8A4D, 0xDBD7,
+	0x8A4E, 0xDBD6, 0x8A4F, 0xDBE4, 0x8A50, 0xB642, 0x8A51, 0xDBE1,
+	0x8A52, 0xDBDF, 0x8A54, 0xB640, 0x8A55, 0xB5FB, 0x8A56, 0xB647,
+	0x8A57, 0xDBDB, 0x8A58, 0xDBDC, 0x8A59, 0xDBD9, 0x8A5B, 0xB641,
+	0x8A5E, 0xB5FC, 0x8A60, 0xB5FA, 0x8A61, 0xE048, 0x8A62, 0xB8DF,
+	0x8A63, 0xB8DA, 0x8A66, 0xB8D5, 0x8A68, 0xB8E5, 0x8A69, 0xB8D6,
+	0x8A6B, 0xB8D2, 0x8A6C, 0xB8E1, 0x8A6D, 0xB8DE, 0x8A6E, 0xB8E0,
+	0x8A70, 0xB8D7, 0x8A71, 0xB8DC, 0x8A72, 0xB8D3, 0x8A73, 0xB8D4,
+	0x8A74, 0xE050, 0x8A75, 0xE04D, 0x8A76, 0xE045, 0x8A77, 0xE04A,
+	0x8A79, 0xB8E2, 0x8A7A, 0xE051, 0x8A7B, 0xB8E3, 0x8A7C, 0xB8D9,
+	0x8A7F, 0xE047, 0x8A81, 0xE04F, 0x8A82, 0xE04B, 0x8A83, 0xE04E,
+	0x8A84, 0xE04C, 0x8A85, 0xB8DD, 0x8A86, 0xE046, 0x8A87, 0xB8D8,
+	0x8A8B, 0xE44C, 0x8A8C, 0xBB78, 0x8A8D, 0xBB7B, 0x8A8F, 0xE44E,
+	0x8A91, 0xBBA5, 0x8A92, 0xE44D, 0x8A93, 0xBB7D, 0x8A95, 0xBDCF,
+	0x8A96, 0xE44F, 0x8A98, 0xBBA4, 0x8A99, 0xE44B, 0x8A9A, 0xBBA6,
+	0x8A9E, 0xBB79, 0x8AA0, 0xB8DB, 0x8AA1, 0xBB7C, 0x8AA3, 0xBB7A,
+	0x8AA4, 0xBB7E, 0x8AA5, 0xBBA2, 0x8AA6, 0xBB77, 0x8AA7, 0xBBA7,
+	0x8AA8, 0xBBA3, 0x8AAA, 0xBBA1, 0x8AAB, 0xE44A, 0x8AB0, 0xBDD6,
+	0x8AB2, 0xBDD2, 0x8AB6, 0xBDD9, 0x8AB8, 0xE7D6, 0x8AB9, 0xBDDA,
+	0x8ABA, 0xE7E2, 0x8ABB, 0xE7DB, 0x8ABC, 0xBDCB, 0x8ABD, 0xE7E3,
+	0x8ABE, 0xE7DD, 0x8ABF, 0xBDD5, 0x8AC0, 0xE7DE, 0x8AC2, 0xBDD4,
+	0x8AC3, 0xE7E1, 0x8AC4, 0xBDCE, 0x8AC5, 0xE7DF, 0x8AC6, 0xE7D5,
+	0x8AC7, 0xBDCD, 0x8AC8, 0xEBAA, 0x8AC9, 0xBDD3, 0x8ACB, 0xBDD0,
+	0x8ACD, 0xBDD8, 0x8ACF, 0xE7D4, 0x8AD1, 0xE7D8, 0x8AD2, 0xBDCC,
+	0x8AD3, 0xE7D7, 0x8AD4, 0xE7D9, 0x8AD5, 0xE7DA, 0x8AD6, 0xBDD7,
+	0x8AD7, 0xE7DC, 0x8AD8, 0xE7E0, 0x8AD9, 0xE7E4, 0x8ADB, 0xBDDB,
+	0x8ADC, 0xBFD2, 0x8ADD, 0xEBA5, 0x8ADE, 0xEBAB, 0x8ADF, 0xEBA8,
+	0x8AE0, 0xEB7E, 0x8AE1, 0xEBAC, 0x8AE2, 0xEBA1, 0x8AE4, 0xEBA7,
+	0x8AE6, 0xBFCD, 0x8AE7, 0xBFD3, 0x8AE8, 0xEBAD, 0x8AEB, 0xBFCF,
+	0x8AED, 0xBFD9, 0x8AEE, 0xBFD4, 0x8AEF, 0xEBAF, 0x8AF0, 0xEBA9,
+	0x8AF1, 0xBFD0, 0x8AF2, 0xEBA2, 0x8AF3, 0xBFDA, 0x8AF4, 0xEBA3,
+	0x8AF5, 0xEBA4, 0x8AF6, 0xBFDB, 0x8AF7, 0xBFD8, 0x8AF8, 0xBDD1,
+	0x8AFA, 0xBFCE, 0x8AFB, 0xEBB0, 0x8AFC, 0xBFDC, 0x8AFE, 0xBFD5,
+	0x8AFF, 0xEBAE, 0x8B00, 0xBFD1, 0x8B01, 0xBFD6, 0x8B02, 0xBFD7,
+	0x8B04, 0xC1C3, 0x8B05, 0xEEA4, 0x8B06, 0xEEAD, 0x8B07, 0xEEAA,
+	0x8B08, 0xEEAC, 0x8B0A, 0xC1C0, 0x8B0B, 0xEEA5, 0x8B0D, 0xEEAB,
+	0x8B0E, 0xC1BC, 0x8B0F, 0xEEA7, 0x8B10, 0xC1C4, 0x8B11, 0xEEA3,
+	0x8B12, 0xEEA8, 0x8B13, 0xEEAF, 0x8B14, 0xEBA6, 0x8B15, 0xEEA9,
+	0x8B16, 0xEEA2, 0x8B17, 0xC1BD, 0x8B18, 0xEEA1, 0x8B19, 0xC1BE,
+	0x8B1A, 0xEEB0, 0x8B1B, 0xC1BF, 0x8B1C, 0xEEAE, 0x8B1D, 0xC1C2,
+	0x8B1E, 0xEE7E, 0x8B20, 0xC1C1, 0x8B22, 0xEEA6, 0x8B23, 0xF0DC,
+	0x8B24, 0xF0EA, 0x8B25, 0xF0E5, 0x8B26, 0xF0E7, 0x8B27, 0xF0DB,
+	0x8B28, 0xC2D3, 0x8B2A, 0xF0DA, 0x8B2B, 0xC2D6, 0x8B2C, 0xC2D5,
+	0x8B2E, 0xF0E9, 0x8B2F, 0xF0E1, 0x8B30, 0xF0DE, 0x8B31, 0xF0E4,
+	0x8B33, 0xF0DD, 0x8B35, 0xF0DF, 0x8B36, 0xF0E8, 0x8B37, 0xF0E6,
+	0x8B39, 0xC2D4, 0x8B3A, 0xF0ED, 0x8B3B, 0xF0EB, 0x8B3C, 0xF0E2,
+	0x8B3D, 0xF0EC, 0x8B3E, 0xF0E3, 0x8B40, 0xF2F9, 0x8B41, 0xC3CF,
+	0x8B42, 0xF341, 0x8B45, 0xF64F, 0x8B46, 0xC3D6, 0x8B47, 0xF0E0,
+	0x8B48, 0xF2F7, 0x8B49, 0xC3D2, 0x8B4A, 0xF2F8, 0x8B4B, 0xF2FD,
+	0x8B4E, 0xC3D4, 0x8B4F, 0xC3D5, 0x8B50, 0xF2F6, 0x8B51, 0xF340,
+	0x8B52, 0xF342, 0x8B53, 0xF2FA, 0x8B54, 0xF2FC, 0x8B55, 0xF2FE,
+	0x8B56, 0xF2FB, 0x8B57, 0xF343, 0x8B58, 0xC3D1, 0x8B59, 0xC3D7,
+	0x8B5A, 0xC3D3, 0x8B5C, 0xC3D0, 0x8B5D, 0xF4D0, 0x8B5F, 0xC4B7,
+	0x8B60, 0xF4CE, 0x8B63, 0xF4D2, 0x8B65, 0xF4D3, 0x8B66, 0xC4B5,
+	0x8B67, 0xF4D4, 0x8B68, 0xF4D1, 0x8B6A, 0xF4CF, 0x8B6B, 0xC4B8,
+	0x8B6C, 0xC4B4, 0x8B6D, 0xF4D5, 0x8B6F, 0xC4B6, 0x8B70, 0xC4B3,
+	0x8B74, 0xC4FE, 0x8B77, 0xC540, 0x8B78, 0xF64E, 0x8B79, 0xF64D,
+	0x8B7A, 0xF650, 0x8B7B, 0xF651, 0x8B7D, 0xC541, 0x8B7E, 0xF756,
+	0x8B7F, 0xF75B, 0x8B80, 0xC5AA, 0x8B82, 0xF758, 0x8B84, 0xF757,
+	0x8B85, 0xF75A, 0x8B86, 0xF759, 0x8B88, 0xF843, 0x8B8A, 0xC5DC,
+	0x8B8B, 0xF842, 0x8B8C, 0xF840, 0x8B8E, 0xF841, 0x8B92, 0xC5FE,
+	0x8B93, 0xC5FD, 0x8B94, 0xF8C1, 0x8B95, 0xF8C2, 0x8B96, 0xC640,
+	0x8B98, 0xF94D, 0x8B99, 0xF94E, 0x8B9A, 0xC667, 0x8B9C, 0xC66D,
+	0x8B9E, 0xF9A9, 0x8B9F, 0xF9C8, 0x8C37, 0xA8A6, 0x8C39, 0xD7CD,
+	0x8C3B, 0xD7CE, 0x8C3C, 0xE052, 0x8C3D, 0xE450, 0x8C3E, 0xE7E5,
+	0x8C3F, 0xC1C6, 0x8C41, 0xC1C5, 0x8C42, 0xF0EE, 0x8C43, 0xF344,
+	0x8C45, 0xF844, 0x8C46, 0xA8A7, 0x8C47, 0xD3DE, 0x8C48, 0xB05A,
+	0x8C49, 0xB361, 0x8C4A, 0xE054, 0x8C4B, 0xE053, 0x8C4C, 0xBDDC,
+	0x8C4D, 0xE7E6, 0x8C4E, 0xBDDD, 0x8C4F, 0xEEB1, 0x8C50, 0xC2D7,
+	0x8C54, 0xC676, 0x8C55, 0xA8A8, 0x8C56, 0xCDCB, 0x8C57, 0xD3DF,
+	0x8C5A, 0xB362, 0x8C5C, 0xD7CF, 0x8C5D, 0xD7D0, 0x8C5F, 0xDBE5,
+	0x8C61, 0xB648, 0x8C62, 0xB8E6, 0x8C64, 0xE056, 0x8C65, 0xE055,
+	0x8C66, 0xE057, 0x8C68, 0xE451, 0x8C69, 0xE452, 0x8C6A, 0xBBA8,
+	0x8C6B, 0xBFDD, 0x8C6C, 0xBDDE, 0x8C6D, 0xBFDE, 0x8C6F, 0xEEB5,
+	0x8C70, 0xEEB2, 0x8C71, 0xEEB4, 0x8C72, 0xEEB3, 0x8C73, 0xC1C7,
+	0x8C75, 0xF0EF, 0x8C76, 0xF346, 0x8C77, 0xF345, 0x8C78, 0xCBA4,
+	0x8C79, 0xB05C, 0x8C7A, 0xB05B, 0x8C7B, 0xD3E0, 0x8C7D, 0xD7D1,
+	0x8C80, 0xDBE7, 0x8C81, 0xDBE6, 0x8C82, 0xB649, 0x8C84, 0xE059,
+	0x8C85, 0xE05A, 0x8C86, 0xE058, 0x8C89, 0xB8E8, 0x8C8A, 0xB8E7,
+	0x8C8C, 0xBBAA, 0x8C8D, 0xBBA9, 0x8C8F, 0xE7E7, 0x8C90, 0xEBB3,
+	0x8C91, 0xEBB1, 0x8C92, 0xEBB2, 0x8C93, 0xBFDF, 0x8C94, 0xEEB7,
+	0x8C95, 0xEEB6, 0x8C97, 0xF0F2, 0x8C98, 0xF0F1, 0x8C99, 0xF0F0,
+	0x8C9A, 0xF347, 0x8C9C, 0xF9AA, 0x8C9D, 0xA8A9, 0x8C9E, 0xAD73,
+	0x8CA0, 0xAD74, 0x8CA1, 0xB05D, 0x8CA2, 0xB05E, 0x8CA3, 0xD3E2,
+	0x8CA4, 0xD3E1, 0x8CA5, 0xD7D2, 0x8CA7, 0xB368, 0x8CA8, 0xB366,
+	0x8CA9, 0xB363, 0x8CAA, 0xB367, 0x8CAB, 0xB365, 0x8CAC, 0xB364,
+	0x8CAF, 0xB64A, 0x8CB0, 0xDBEA, 0x8CB2, 0xB8ED, 0x8CB3, 0xB64C,
+	0x8CB4, 0xB651, 0x8CB5, 0xDBEC, 0x8CB6, 0xB653, 0x8CB7, 0xB652,
+	0x8CB8, 0xB655, 0x8CB9, 0xDBEB, 0x8CBA, 0xDBE8, 0x8CBB, 0xB64F,
+	0x8CBC, 0xB64B, 0x8CBD, 0xB64D, 0x8CBE, 0xDBE9, 0x8CBF, 0xB654,
+	0x8CC0, 0xB650, 0x8CC1, 0xB64E, 0x8CC2, 0xB8EF, 0x8CC3, 0xB8EE,
+	0x8CC4, 0xB8EC, 0x8CC5, 0xB8F0, 0x8CC7, 0xB8EA, 0x8CC8, 0xB8EB,
+	0x8CCA, 0xB8E9, 0x8CCC, 0xE05B, 0x8CCF, 0xE454, 0x8CD1, 0xBBAC,
+	0x8CD2, 0xBBAD, 0x8CD3, 0xBBAB, 0x8CD5, 0xE453, 0x8CD7, 0xE455,
+	0x8CD9, 0xE7EA, 0x8CDA, 0xE7EC, 0x8CDC, 0xBDE7, 0x8CDD, 0xE7ED,
+	0x8CDE, 0xBDE0, 0x8CDF, 0xE7E9, 0x8CE0, 0xBDDF, 0x8CE1, 0xBDE9,
+	0x8CE2, 0xBDE5, 0x8CE3, 0xBDE6, 0x8CE4, 0xBDE2, 0x8CE5, 0xE7E8,
+	0x8CE6, 0xBDE1, 0x8CE7, 0xE7EE, 0x8CE8, 0xE7EB, 0x8CEA, 0xBDE8,
+	0x8CEC, 0xBDE3, 0x8CED, 0xBDE4, 0x8CEE, 0xEBB5, 0x8CF0, 0xEBB7,
+	0x8CF1, 0xEBB6, 0x8CF3, 0xEBB8, 0x8CF4, 0xBFE0, 0x8CF5, 0xEBB4,
+	0x8CF8, 0xC1CB, 0x8CF9, 0xEEB8, 0x8CFA, 0xC1C8, 0x8CFB, 0xC1CC,
+	0x8CFC, 0xC1CA, 0x8CFD, 0xC1C9, 0x8CFE, 0xF0F3, 0x8D00, 0xF0F6,
+	0x8D02, 0xF0F5, 0x8D04, 0xF0F4, 0x8D05, 0xC2D8, 0x8D06, 0xF348,
+	0x8D07, 0xF349, 0x8D08, 0xC3D8, 0x8D09, 0xF34A, 0x8D0A, 0xC3D9,
+	0x8D0D, 0xC4BA, 0x8D0F, 0xC4B9, 0x8D10, 0xF652, 0x8D13, 0xC542,
+	0x8D14, 0xF653, 0x8D15, 0xF75C, 0x8D16, 0xC5AB, 0x8D17, 0xC5AC,
+	0x8D19, 0xF845, 0x8D1B, 0xC642, 0x8D64, 0xA8AA, 0x8D66, 0xB36A,
+	0x8D67, 0xB369, 0x8D68, 0xE05C, 0x8D69, 0xE05D, 0x8D6B, 0xBBAE,
+	0x8D6C, 0xEBB9, 0x8D6D, 0xBDEA, 0x8D6E, 0xEBBA, 0x8D6F, 0xEEB9,
+	0x8D70, 0xA8AB, 0x8D72, 0xD0B2, 0x8D73, 0xAD76, 0x8D74, 0xAD75,
+	0x8D76, 0xD3E3, 0x8D77, 0xB05F, 0x8D78, 0xD3E4, 0x8D79, 0xD7D5,
+	0x8D7B, 0xD7D4, 0x8D7D, 0xD7D3, 0x8D80, 0xDBEE, 0x8D81, 0xB658,
+	0x8D84, 0xDBED, 0x8D85, 0xB657, 0x8D89, 0xDBEF, 0x8D8A, 0xB656,
+	0x8D8C, 0xE05F, 0x8D8D, 0xE062, 0x8D8E, 0xE060, 0x8D8F, 0xE061,
+	0x8D90, 0xE065, 0x8D91, 0xE05E, 0x8D92, 0xE066, 0x8D93, 0xE063,
+	0x8D94, 0xE064, 0x8D95, 0xBBB0, 0x8D96, 0xE456, 0x8D99, 0xBBAF,
+	0x8D9B, 0xE7F2, 0x8D9C, 0xE7F0, 0x8D9F, 0xBDEB, 0x8DA0, 0xE7EF,
+	0x8DA1, 0xE7F1, 0x8DA3, 0xBDEC, 0x8DA5, 0xEBBB, 0x8DA7, 0xEBBC,
+	0x8DA8, 0xC1CD, 0x8DAA, 0xF34C, 0x8DAB, 0xF34E, 0x8DAC, 0xF34B,
+	0x8DAD, 0xF34D, 0x8DAE, 0xF4D6, 0x8DAF, 0xF654, 0x8DB2, 0xF96F,
+	0x8DB3, 0xA8AC, 0x8DB4, 0xAD77, 0x8DB5, 0xD3E5, 0x8DB6, 0xD3E7,
+	0x8DB7, 0xD3E6, 0x8DB9, 0xD7D8, 0x8DBA, 0xB36C, 0x8DBC, 0xD7D6,
+	0x8DBE, 0xB36B, 0x8DBF, 0xD7D9, 0x8DC1, 0xD7DA, 0x8DC2, 0xD7D7,
+	0x8DC5, 0xDBFB, 0x8DC6, 0xB660, 0x8DC7, 0xDBF3, 0x8DC8, 0xDBF9,
+	0x8DCB, 0xB65B, 0x8DCC, 0xB65E, 0x8DCD, 0xDBF2, 0x8DCE, 0xB659,
+	0x8DCF, 0xDBF6, 0x8DD0, 0xE06C, 0x8DD1, 0xB65D, 0x8DD3, 0xDBF1,
+	0x8DD5, 0xDBF7, 0x8DD6, 0xDBF4, 0x8DD7, 0xDBFA, 0x8DD8, 0xDBF0,
+	0x8DD9, 0xDBF8, 0x8DDA, 0xB65C, 0x8DDB, 0xB65F, 0x8DDC, 0xDBF5,
+	0x8DDD, 0xB65A, 0x8DDF, 0xB8F2, 0x8DE0, 0xE068, 0x8DE1, 0xB8F1,
+	0x8DE2, 0xE06F, 0x8DE3, 0xE06E, 0x8DE4, 0xB8F8, 0x8DE6, 0xB8F9,
+	0x8DE7, 0xE070, 0x8DE8, 0xB8F3, 0x8DE9, 0xE06D, 0x8DEA, 0xB8F7,
+	0x8DEB, 0xE072, 0x8DEC, 0xE069, 0x8DEE, 0xE06B, 0x8DEF, 0xB8F4,
+	0x8DF0, 0xE067, 0x8DF1, 0xE06A, 0x8DF2, 0xE071, 0x8DF3, 0xB8F5,
+	0x8DF4, 0xE073, 0x8DFA, 0xB8F6, 0x8DFC, 0xBBB1, 0x8DFD, 0xE45B,
+	0x8DFE, 0xE461, 0x8DFF, 0xE459, 0x8E00, 0xE462, 0x8E02, 0xE458,
+	0x8E03, 0xE45D, 0x8E04, 0xE463, 0x8E05, 0xE460, 0x8E06, 0xE45F,
+	0x8E07, 0xE45E, 0x8E09, 0xE457, 0x8E0A, 0xE45C, 0x8E0D, 0xE45A,
+	0x8E0F, 0xBDF1, 0x8E10, 0xBDEE, 0x8E11, 0xE7FB, 0x8E12, 0xE841,
+	0x8E13, 0xE843, 0x8E14, 0xE840, 0x8E15, 0xE7F8, 0x8E16, 0xE7FA,
+	0x8E17, 0xE845, 0x8E18, 0xE842, 0x8E19, 0xE7FC, 0x8E1A, 0xE846,
+	0x8E1B, 0xE7F9, 0x8E1C, 0xE844, 0x8E1D, 0xBDEF, 0x8E1E, 0xBDF5,
+	0x8E1F, 0xBDF3, 0x8E20, 0xE7F3, 0x8E21, 0xBDF4, 0x8E22, 0xBDF0,
+	0x8E23, 0xE7F4, 0x8E24, 0xE7F6, 0x8E25, 0xE7F5, 0x8E26, 0xE7FD,
+	0x8E27, 0xE7FE, 0x8E29, 0xBDF2, 0x8E2B, 0xBDED, 0x8E2E, 0xE7F7,
+	0x8E30, 0xEBC6, 0x8E31, 0xBFE2, 0x8E33, 0xEBBD, 0x8E34, 0xBFE3,
+	0x8E35, 0xBFE6, 0x8E36, 0xEBC2, 0x8E38, 0xEBBF, 0x8E39, 0xBFE5,
+	0x8E3C, 0xEBC3, 0x8E3D, 0xEBC4, 0x8E3E, 0xEBBE, 0x8E3F, 0xEBC7,
+	0x8E40, 0xEBC0, 0x8E41, 0xEBC5, 0x8E42, 0xBFE4, 0x8E44, 0xBFE1,
+	0x8E45, 0xEBC1, 0x8E47, 0xEEBF, 0x8E48, 0xC1D0, 0x8E49, 0xC1CE,
+	0x8E4A, 0xC1D1, 0x8E4B, 0xC1CF, 0x8E4C, 0xEEBE, 0x8E4D, 0xEEBB,
+	0x8E4E, 0xEEBA, 0x8E50, 0xEEBD, 0x8E53, 0xEEBC, 0x8E54, 0xF145,
+	0x8E55, 0xC2DE, 0x8E56, 0xF0FB, 0x8E57, 0xF0FA, 0x8E59, 0xC2D9,
+	0x8E5A, 0xF141, 0x8E5B, 0xF140, 0x8E5C, 0xF0F7, 0x8E5D, 0xF143,
+	0x8E5E, 0xF0FC, 0x8E5F, 0xC2DD, 0x8E60, 0xF0F9, 0x8E61, 0xF142,
+	0x8E62, 0xF0F8, 0x8E63, 0xC2DA, 0x8E64, 0xC2DC, 0x8E65, 0xF0FD,
+	0x8E66, 0xC2DB, 0x8E67, 0xF0FE, 0x8E69, 0xF144, 0x8E6A, 0xF352,
+	0x8E6C, 0xC3DE, 0x8E6D, 0xF34F, 0x8E6F, 0xF353, 0x8E72, 0xC3DB,
+	0x8E73, 0xF351, 0x8E74, 0xC3E0, 0x8E76, 0xC3DD, 0x8E78, 0xF350,
+	0x8E7A, 0xC3DF, 0x8E7B, 0xF354, 0x8E7C, 0xC3DA, 0x8E81, 0xC4BC,
+	0x8E82, 0xC4BE, 0x8E84, 0xF4D9, 0x8E85, 0xC4BD, 0x8E86, 0xF4D7,
+	0x8E87, 0xC3DC, 0x8E88, 0xF4D8, 0x8E89, 0xC4BB, 0x8E8A, 0xC543,
+	0x8E8B, 0xC545, 0x8E8C, 0xF656, 0x8E8D, 0xC544, 0x8E8E, 0xF655,
+	0x8E90, 0xF761, 0x8E91, 0xC5AD, 0x8E92, 0xF760, 0x8E93, 0xC5AE,
+	0x8E94, 0xF75E, 0x8E95, 0xF75D, 0x8E96, 0xF762, 0x8E97, 0xF763,
+	0x8E98, 0xF846, 0x8E9A, 0xF75F, 0x8E9D, 0xF8C6, 0x8E9E, 0xF8C3,
+	0x8E9F, 0xF8C4, 0x8EA0, 0xF8C5, 0x8EA1, 0xC65C, 0x8EA3, 0xF951,
+	0x8EA4, 0xF950, 0x8EA5, 0xF94F, 0x8EA6, 0xF970, 0x8EA8, 0xF9BE,
+	0x8EA9, 0xF9AB, 0x8EAA, 0xC66E, 0x8EAB, 0xA8AD, 0x8EAC, 0xB060,
+	0x8EB2, 0xB8FA, 0x8EBA, 0xBDF6, 0x8EBD, 0xEBC8, 0x8EC0, 0xC2DF,
+	0x8EC2, 0xF355, 0x8EC9, 0xF9AC, 0x8ECA, 0xA8AE, 0x8ECB, 0xAAEE,
+	0x8ECC, 0xAD79, 0x8ECD, 0xAD78, 0x8ECF, 0xB063, 0x8ED1, 0xD3E8,
+	0x8ED2, 0xB061, 0x8ED3, 0xD3E9, 0x8ED4, 0xB062, 0x8ED7, 0xD7DF,
+	0x8ED8, 0xD7DB, 0x8EDB, 0xB36D, 0x8EDC, 0xD7DE, 0x8EDD, 0xD7DD,
+	0x8EDE, 0xD7DC, 0x8EDF, 0xB36E, 0x8EE0, 0xD7E0, 0x8EE1, 0xD7E1,
+	0x8EE5, 0xDC43, 0x8EE6, 0xDC41, 0x8EE7, 0xDC45, 0x8EE8, 0xDC46,
+	0x8EE9, 0xDC4C, 0x8EEB, 0xDC48, 0x8EEC, 0xDC4A, 0x8EEE, 0xDC42,
+	0x8EEF, 0xDBFC, 0x8EF1, 0xDC49, 0x8EF4, 0xDC4B, 0x8EF5, 0xDC44,
+	0x8EF6, 0xDC47, 0x8EF7, 0xDBFD, 0x8EF8, 0xB662, 0x8EF9, 0xDC40,
+	0x8EFA, 0xDBFE, 0x8EFB, 0xB661, 0x8EFC, 0xB663, 0x8EFE, 0xB8FD,
+	0x8EFF, 0xE075, 0x8F00, 0xE077, 0x8F01, 0xE076, 0x8F02, 0xE07B,
+	0x8F03, 0xB8FB, 0x8F05, 0xE078, 0x8F06, 0xE074, 0x8F07, 0xE079,
+	0x8F08, 0xE07A, 0x8F09, 0xB8FC, 0x8F0A, 0xB8FE, 0x8F0B, 0xE07C,
+	0x8F0D, 0xE467, 0x8F0E, 0xE466, 0x8F10, 0xE464, 0x8F11, 0xE465,
+	0x8F12, 0xBBB3, 0x8F13, 0xBBB5, 0x8F14, 0xBBB2, 0x8F15, 0xBBB4,
+	0x8F16, 0xE84D, 0x8F17, 0xE84E, 0x8F18, 0xE849, 0x8F1A, 0xE84A,
+	0x8F1B, 0xBDF8, 0x8F1C, 0xBDFD, 0x8F1D, 0xBDF7, 0x8F1E, 0xBDFE,
+	0x8F1F, 0xBDF9, 0x8F20, 0xE84B, 0x8F23, 0xE84C, 0x8F24, 0xE848,
+	0x8F25, 0xBE40, 0x8F26, 0xBDFB, 0x8F29, 0xBDFA, 0x8F2A, 0xBDFC,
+	0x8F2C, 0xE847, 0x8F2E, 0xEBCA, 0x8F2F, 0xBFE8, 0x8F32, 0xEBCC,
+	0x8F33, 0xBFEA, 0x8F34, 0xEBCF, 0x8F35, 0xEBCB, 0x8F36, 0xEBC9,
+	0x8F37, 0xEBCE, 0x8F38, 0xBFE9, 0x8F39, 0xEBCD, 0x8F3B, 0xBFE7,
+	0x8F3E, 0xC1D3, 0x8F3F, 0xC1D6, 0x8F40, 0xEEC1, 0x8F42, 0xC1D4,
+	0x8F43, 0xEEC0, 0x8F44, 0xC1D2, 0x8F45, 0xC1D5, 0x8F46, 0xF146,
+	0x8F47, 0xF147, 0x8F48, 0xF148, 0x8F49, 0xC2E0, 0x8F4B, 0xF149,
+	0x8F4D, 0xC2E1, 0x8F4E, 0xC3E2, 0x8F4F, 0xF358, 0x8F50, 0xF359,
+	0x8F51, 0xF357, 0x8F52, 0xF356, 0x8F53, 0xF35A, 0x8F54, 0xC3E1,
+	0x8F55, 0xF4DD, 0x8F56, 0xF4DB, 0x8F57, 0xF4DC, 0x8F58, 0xF4DE,
+	0x8F59, 0xF4DA, 0x8F5A, 0xF4DF, 0x8F5B, 0xF658, 0x8F5D, 0xF659,
+	0x8F5E, 0xF657, 0x8F5F, 0xC546, 0x8F60, 0xF764, 0x8F61, 0xC5AF,
+	0x8F62, 0xF765, 0x8F63, 0xF848, 0x8F64, 0xF847, 0x8F9B, 0xA8AF,
+	0x8F9C, 0xB664, 0x8F9F, 0xB940, 0x8FA3, 0xBBB6, 0x8FA6, 0xBFEC,
+	0x8FA8, 0xBFEB, 0x8FAD, 0xC3E3, 0x8FAE, 0xC47C, 0x8FAF, 0xC547,
+	0x8FB0, 0xA8B0, 0x8FB1, 0xB064, 0x8FB2, 0xB941, 0x8FB4, 0xF35B,
+	0x8FBF, 0xCBA6, 0x8FC2, 0xA8B1, 0x8FC4, 0xA8B4, 0x8FC5, 0xA8B3,
+	0x8FC6, 0xA8B2, 0x8FC9, 0xCBA5, 0x8FCB, 0xCDCD, 0x8FCD, 0xCDCF,
+	0x8FCE, 0xAAEF, 0x8FD1, 0xAAF1, 0x8FD2, 0xCDCC, 0x8FD3, 0xCDCE,
+	0x8FD4, 0xAAF0, 0x8FD5, 0xCDD1, 0x8FD6, 0xCDD0, 0x8FD7, 0xCDD2,
+	0x8FE0, 0xD0B6, 0x8FE1, 0xD0B4, 0x8FE2, 0xAD7C, 0x8FE3, 0xD0B3,
+	0x8FE4, 0xADA3, 0x8FE5, 0xAD7E, 0x8FE6, 0xAD7B, 0x8FE8, 0xADA4,
+	0x8FEA, 0xAD7D, 0x8FEB, 0xADA2, 0x8FED, 0xADA1, 0x8FEE, 0xD0B5,
+	0x8FF0, 0xAD7A, 0x8FF4, 0xB06A, 0x8FF5, 0xD3EB, 0x8FF6, 0xD3F1,
+	0x8FF7, 0xB067, 0x8FF8, 0xB06E, 0x8FFA, 0xB069, 0x8FFB, 0xD3EE,
+	0x8FFC, 0xD3F0, 0x8FFD, 0xB06C, 0x8FFE, 0xD3EA, 0x8FFF, 0xD3ED,
+	0x9000, 0xB068, 0x9001, 0xB065, 0x9002, 0xD3EC, 0x9003, 0xB06B,
+	0x9004, 0xD3EF, 0x9005, 0xB06D, 0x9006, 0xB066, 0x900B, 0xD7E3,
+	0x900C, 0xD7E6, 0x900D, 0xB370, 0x900F, 0xB37A, 0x9010, 0xB376,
+	0x9011, 0xD7E4, 0x9014, 0xB37E, 0x9015, 0xB377, 0x9016, 0xB37C,
+	0x9017, 0xB372, 0x9019, 0xB36F, 0x901A, 0xB371, 0x901B, 0xB37D,
+	0x901C, 0xD7E5, 0x901D, 0xB375, 0x901E, 0xB378, 0x901F, 0xB374,
+	0x9020, 0xB379, 0x9021, 0xD7E7, 0x9022, 0xB37B, 0x9023, 0xB373,
+	0x9024, 0xD7E2, 0x902D, 0xDC4D, 0x902E, 0xB665, 0x902F, 0xDC4F,
+	0x9031, 0xB667, 0x9032, 0xB669, 0x9034, 0xDC4E, 0x9035, 0xB666,
+	0x9036, 0xB66A, 0x9038, 0xB668, 0x903C, 0xB947, 0x903D, 0xE0A3,
+	0x903E, 0xB94F, 0x903F, 0xE07E, 0x9041, 0xB950, 0x9042, 0xB945,
+	0x9044, 0xE0A1, 0x9047, 0xB94A, 0x9049, 0xE0A2, 0x904A, 0xB943,
+	0x904B, 0xB942, 0x904D, 0xB94D, 0x904E, 0xB94C, 0x904F, 0xB94B,
+	0x9050, 0xB949, 0x9051, 0xB94E, 0x9052, 0xE07D, 0x9053, 0xB944,
+	0x9054, 0xB946, 0x9055, 0xB948, 0x9058, 0xBBB8, 0x9059, 0xBBBB,
+	0x905B, 0xBBBF, 0x905C, 0xBBB9, 0x905D, 0xBBBE, 0x905E, 0xBBBC,
+	0x9060, 0xBBB7, 0x9062, 0xBBBD, 0x9063, 0xBBBA, 0x9067, 0xE852,
+	0x9068, 0xBE43, 0x9069, 0xBE41, 0x906B, 0xE853, 0x906D, 0xBE44,
+	0x906E, 0xBE42, 0x906F, 0xE851, 0x9070, 0xE850, 0x9072, 0xBFF0,
+	0x9073, 0xE84F, 0x9074, 0xBFEE, 0x9075, 0xBFED, 0x9076, 0xEBD0,
+	0x9077, 0xBE45, 0x9078, 0xBFEF, 0x9079, 0xEBD1, 0x907A, 0xBFF2,
+	0x907B, 0xEBD2, 0x907C, 0xBFF1, 0x907D, 0xC1D8, 0x907E, 0xEEC3,
+	0x907F, 0xC1D7, 0x9080, 0xC1DC, 0x9081, 0xC1DA, 0x9082, 0xC1DB,
+	0x9083, 0xC2E3, 0x9084, 0xC1D9, 0x9085, 0xEEC2, 0x9086, 0xEBD3,
+	0x9087, 0xC2E2, 0x9088, 0xC2E4, 0x908A, 0xC3E4, 0x908B, 0xC3E5,
+	0x908D, 0xF4E0, 0x908F, 0xC5DE, 0x9090, 0xC5DD, 0x9091, 0xA8B6,
+	0x9094, 0xCA55, 0x9095, 0xB06F, 0x9097, 0xCA52, 0x9098, 0xCA53,
+	0x9099, 0xCA51, 0x909B, 0xCA54, 0x909E, 0xCBAA, 0x909F, 0xCBA7,
+	0x90A0, 0xCBAC, 0x90A1, 0xCBA8, 0x90A2, 0xA8B7, 0x90A3, 0xA8BA,
+	0x90A5, 0xCBA9, 0x90A6, 0xA8B9, 0x90A7, 0xCBAB, 0x90AA, 0xA8B8,
+	0x90AF, 0xCDD5, 0x90B0, 0xCDD7, 0x90B1, 0xAAF4, 0x90B2, 0xCDD3,
+	0x90B3, 0xCDD6, 0x90B4, 0xCDD4, 0x90B5, 0xAAF2, 0x90B6, 0xAAF5,
+	0x90B8, 0xAAF3, 0x90BD, 0xD0B8, 0x90BE, 0xD0BC, 0x90BF, 0xD0B9,
+	0x90C1, 0xADA7, 0x90C3, 0xADA8, 0x90C5, 0xD0BB, 0x90C7, 0xD0BD,
+	0x90C8, 0xD0BF, 0x90CA, 0xADA5, 0x90CB, 0xD0BE, 0x90CE, 0xADA6,
+	0x90D4, 0xD7EE, 0x90D5, 0xD0BA, 0x90D6, 0xD3F2, 0x90D7, 0xD3FB,
+	0x90D8, 0xD3F9, 0x90D9, 0xD3F4, 0x90DA, 0xD3F5, 0x90DB, 0xD3FA,
+	0x90DC, 0xD3FC, 0x90DD, 0xB071, 0x90DF, 0xD3F7, 0x90E0, 0xD3F3,
+	0x90E1, 0xB070, 0x90E2, 0xB072, 0x90E3, 0xD3F6, 0x90E4, 0xD3FD,
+	0x90E5, 0xD3F8, 0x90E8, 0xB3A1, 0x90E9, 0xD7F1, 0x90EA, 0xD7E9,
+	0x90EB, 0xD7EF, 0x90EC, 0xD7F0, 0x90ED, 0xB3A2, 0x90EF, 0xD7E8,
+	0x90F0, 0xD7EA, 0x90F1, 0xD0B7, 0x90F2, 0xD7EC, 0x90F3, 0xD7ED,
+	0x90F4, 0xD7EB, 0x90F5, 0xB66C, 0x90F9, 0xDC56, 0x90FA, 0xEBD4,
+	0x90FB, 0xDC57, 0x90FC, 0xDC54, 0x90FD, 0xB3A3, 0x90FE, 0xB66E,
+	0x90FF, 0xDC53, 0x9100, 0xDC59, 0x9101, 0xDC58, 0x9102, 0xB66B,
+	0x9103, 0xDC5C, 0x9104, 0xDC52, 0x9105, 0xDC5B, 0x9106, 0xDC50,
+	0x9107, 0xDC5A, 0x9108, 0xDC55, 0x9109, 0xB66D, 0x910B, 0xE0AA,
+	0x910D, 0xE0A5, 0x910E, 0xE0AB, 0x910F, 0xE0A6, 0x9110, 0xE0A4,
+	0x9111, 0xE0A7, 0x9112, 0xB951, 0x9114, 0xE0A9, 0x9116, 0xE0A8,
+	0x9117, 0xB952, 0x9118, 0xBBC1, 0x9119, 0xBBC0, 0x911A, 0xE46E,
+	0x911B, 0xE471, 0x911C, 0xE469, 0x911D, 0xE46D, 0x911E, 0xBBC2,
+	0x911F, 0xE46C, 0x9120, 0xE46A, 0x9121, 0xE470, 0x9122, 0xE46B,
+	0x9123, 0xE468, 0x9124, 0xE46F, 0x9126, 0xE859, 0x9127, 0xBE48,
+	0x9128, 0xF14A, 0x9129, 0xE856, 0x912A, 0xE857, 0x912B, 0xE855,
+	0x912C, 0xDC51, 0x912D, 0xBE47, 0x912E, 0xE85A, 0x912F, 0xE854,
+	0x9130, 0xBE46, 0x9131, 0xBE49, 0x9132, 0xE858, 0x9133, 0xEBD5,
+	0x9134, 0xBFF3, 0x9135, 0xEBD6, 0x9136, 0xEBD7, 0x9138, 0xEEC4,
+	0x9139, 0xC1DD, 0x913A, 0xF14B, 0x913B, 0xF14C, 0x913E, 0xF14D,
+	0x913F, 0xF35D, 0x9140, 0xF35C, 0x9141, 0xF4E2, 0x9143, 0xF4E1,
+	0x9144, 0xF65B, 0x9145, 0xF65C, 0x9146, 0xF65A, 0x9147, 0xF766,
+	0x9148, 0xC5B0, 0x9149, 0xA8BB, 0x914A, 0xADAA, 0x914B, 0xADA9,
+	0x914C, 0xB075, 0x914D, 0xB074, 0x914E, 0xD440, 0x914F, 0xD441,
+	0x9150, 0xD3FE, 0x9152, 0xB073, 0x9153, 0xD7F5, 0x9155, 0xD7F6,
+	0x9156, 0xD7F2, 0x9157, 0xB3A4, 0x9158, 0xD7F3, 0x915A, 0xD7F4,
+	0x915F, 0xDC5F, 0x9160, 0xDC61, 0x9161, 0xDC5D, 0x9162, 0xDC60,
+	0x9163, 0xB66F, 0x9164, 0xDC5E, 0x9165, 0xB670, 0x9168, 0xDD73,
+	0x9169, 0xB955, 0x916A, 0xB954, 0x916C, 0xB953, 0x916E, 0xE0AC,
+	0x916F, 0xE0AD, 0x9172, 0xE473, 0x9173, 0xE475, 0x9174, 0xBBC6,
+	0x9175, 0xBBC3, 0x9177, 0xBBC5, 0x9178, 0xBBC4, 0x9179, 0xE474,
+	0x917A, 0xE472, 0x9180, 0xE861, 0x9181, 0xE85E, 0x9182, 0xE85F,
+	0x9183, 0xBE4D, 0x9184, 0xE860, 0x9185, 0xE85B, 0x9186, 0xE85C,
+	0x9187, 0xBE4A, 0x9189, 0xBE4B, 0x918A, 0xE85D, 0x918B, 0xBE4C,
+	0x918D, 0xEBDB, 0x918F, 0xEBDC, 0x9190, 0xEBD9, 0x9191, 0xEBDA,
+	0x9192, 0xBFF4, 0x9193, 0xEBD8, 0x9199, 0xEEC8, 0x919A, 0xEEC5,
+	0x919B, 0xEEC7, 0x919C, 0xC1E0, 0x919D, 0xEECB, 0x919E, 0xC1DF,
+	0x919F, 0xEEC9, 0x91A0, 0xEECC, 0x91A1, 0xEECA, 0x91A2, 0xEEC6,
+	0x91A3, 0xC1DE, 0x91A5, 0xF14F, 0x91A7, 0xF150, 0x91A8, 0xF14E,
+	0x91AA, 0xF152, 0x91AB, 0xC2E5, 0x91AC, 0xC2E6, 0x91AD, 0xF35F,
+	0x91AE, 0xC3E7, 0x91AF, 0xF151, 0x91B0, 0xF35E, 0x91B1, 0xC3E6,
+	0x91B2, 0xF4E5, 0x91B3, 0xF4E6, 0x91B4, 0xC4BF, 0x91B5, 0xF4E4,
+	0x91B7, 0xF4E3, 0x91B9, 0xF65D, 0x91BA, 0xC548, 0x91BC, 0xF849,
+	0x91BD, 0xF8C8, 0x91BE, 0xF8C7, 0x91C0, 0xC643, 0x91C1, 0xC65D,
+	0x91C2, 0xF8C9, 0x91C3, 0xF971, 0x91C5, 0xC66F, 0x91C6, 0xA8BC,
+	0x91C7, 0xAAF6, 0x91C9, 0xB956, 0x91CB, 0xC4C0, 0x91CC, 0xA8BD,
+	0x91CD, 0xADAB, 0x91CE, 0xB3A5, 0x91CF, 0xB671, 0x91D0, 0xC2E7,
+	0x91D1, 0xAAF7, 0x91D3, 0xD0C1, 0x91D4, 0xD0C0, 0x91D5, 0xD442,
+	0x91D7, 0xB078, 0x91D8, 0xB076, 0x91D9, 0xB07A, 0x91DA, 0xD444,
+	0x91DC, 0xB079, 0x91DD, 0xB077, 0x91E2, 0xD443, 0x91E3, 0xB3A8,
+	0x91E4, 0xD7FC, 0x91E6, 0xB3A7, 0x91E7, 0xB3A9, 0x91E8, 0xD842,
+	0x91E9, 0xB3AB, 0x91EA, 0xD7FE, 0x91EB, 0xD840, 0x91EC, 0xD7F7,
+	0x91ED, 0xB3AA, 0x91EE, 0xD843, 0x91F1, 0xD7F9, 0x91F3, 0xD7FA,
+	0x91F4, 0xD7F8, 0x91F5, 0xB3A6, 0x91F7, 0xD841, 0x91F8, 0xD7FB,
+	0x91F9, 0xD7FD, 0x91FD, 0xDC6D, 0x91FF, 0xDC6C, 0x9200, 0xDC6A,
+	0x9201, 0xDC62, 0x9202, 0xDC71, 0x9203, 0xDC65, 0x9204, 0xDC6F,
+	0x9205, 0xDC76, 0x9206, 0xDC6E, 0x9207, 0xB679, 0x9209, 0xB675,
+	0x920A, 0xDC63, 0x920C, 0xDC69, 0x920D, 0xB677, 0x920F, 0xDC68,
+	0x9210, 0xB678, 0x9211, 0xB67A, 0x9212, 0xDC6B, 0x9214, 0xB672,
+	0x9215, 0xB673, 0x9216, 0xDC77, 0x9217, 0xDC75, 0x9219, 0xDC74,
+	0x921A, 0xDC66, 0x921C, 0xDC72, 0x921E, 0xB676, 0x9223, 0xB674,
+	0x9224, 0xDC73, 0x9225, 0xDC64, 0x9226, 0xDC67, 0x9227, 0xDC70,
+	0x922D, 0xE4BA, 0x922E, 0xE0B7, 0x9230, 0xE0B0, 0x9231, 0xE0C3,
+	0x9232, 0xE0CC, 0x9233, 0xE0B3, 0x9234, 0xB961, 0x9236, 0xE0C0,
+	0x9237, 0xB957, 0x9238, 0xB959, 0x9239, 0xB965, 0x923A, 0xE0B1,
+	0x923D, 0xB95A, 0x923E, 0xB95C, 0x923F, 0xB966, 0x9240, 0xB95B,
+	0x9245, 0xB964, 0x9246, 0xE0B9, 0x9248, 0xE0AE, 0x9249, 0xB962,
+	0x924A, 0xE0B8, 0x924B, 0xB95E, 0x924C, 0xE0CA, 0x924D, 0xB963,
+	0x924E, 0xE0C8, 0x924F, 0xE0BC, 0x9250, 0xE0C6, 0x9251, 0xB960,
+	0x9252, 0xE0AF, 0x9253, 0xE0C9, 0x9254, 0xE0C4, 0x9256, 0xE0CB,
+	0x9257, 0xB958, 0x925A, 0xB967, 0x925B, 0xB95D, 0x925E, 0xE0B5,
+	0x9260, 0xE0BD, 0x9261, 0xE0C1, 0x9263, 0xE0C5, 0x9264, 0xB95F,
+	0x9265, 0xE0B4, 0x9266, 0xE0B2, 0x9267, 0xE0BE, 0x926C, 0xE0BB,
+	0x926D, 0xE0BA, 0x926F, 0xE0BF, 0x9270, 0xE0C2, 0x9272, 0xE0C7,
+	0x9276, 0xE478, 0x9278, 0xBBC7, 0x9279, 0xE4A4, 0x927A, 0xE47A,
+	0x927B, 0xBBCC, 0x927C, 0xBBD0, 0x927D, 0xE4AD, 0x927E, 0xE4B5,
+	0x927F, 0xE4A6, 0x9280, 0xBBC8, 0x9282, 0xE4AA, 0x9283, 0xE0B6,
+	0x9285, 0xBBC9, 0x9286, 0xE4B1, 0x9287, 0xE4B6, 0x9288, 0xE4AE,
+	0x928A, 0xE4B0, 0x928B, 0xE4B9, 0x928C, 0xE4B2, 0x928D, 0xE47E,
+	0x928E, 0xE4A9, 0x9291, 0xBBD1, 0x9293, 0xBBCD, 0x9294, 0xE47C,
+	0x9295, 0xE4AB, 0x9296, 0xBBCB, 0x9297, 0xE4A5, 0x9298, 0xBBCA,
+	0x9299, 0xE4B3, 0x929A, 0xE4A2, 0x929B, 0xE479, 0x929C, 0xBBCE,
+	0x929D, 0xE4B8, 0x92A0, 0xE47B, 0x92A1, 0xE4AF, 0x92A2, 0xE4AC,
+	0x92A3, 0xE4A7, 0x92A4, 0xE477, 0x92A5, 0xE476, 0x92A6, 0xE4A1,
+	0x92A7, 0xE4B4, 0x92A8, 0xBBCF, 0x92A9, 0xE4B7, 0x92AA, 0xE47D,
+	0x92AB, 0xE4A3, 0x92AC, 0xBE52, 0x92B2, 0xBE5A, 0x92B3, 0xBE55,
+	0x92B4, 0xE8A4, 0x92B5, 0xE8A1, 0x92B6, 0xE867, 0x92B7, 0xBE50,
+	0x92B9, 0xF9D7, 0x92BB, 0xBE4F, 0x92BC, 0xBE56, 0x92C0, 0xE865,
+	0x92C1, 0xBE54, 0x92C2, 0xE871, 0x92C3, 0xE863, 0x92C4, 0xE864,
+	0x92C5, 0xBE4E, 0x92C6, 0xE8A3, 0x92C7, 0xBE58, 0x92C8, 0xE874,
+	0x92C9, 0xE879, 0x92CA, 0xE873, 0x92CB, 0xEBEE, 0x92CC, 0xE86F,
+	0x92CD, 0xE877, 0x92CE, 0xE875, 0x92CF, 0xE868, 0x92D0, 0xE862,
+	0x92D1, 0xE87D, 0x92D2, 0xBE57, 0x92D3, 0xE87E, 0x92D5, 0xE878,
+	0x92D7, 0xE86D, 0x92D8, 0xE86B, 0x92D9, 0xE866, 0x92DD, 0xE86E,
+	0x92DE, 0xE87B, 0x92DF, 0xE86A, 0x92E0, 0xE87A, 0x92E1, 0xE8A2,
+	0x92E4, 0xBE53, 0x92E6, 0xE876, 0x92E7, 0xE87C, 0x92E8, 0xE872,
+	0x92E9, 0xE86C, 0x92EA, 0xBE51, 0x92EE, 0xE4A8, 0x92EF, 0xE870,
+	0x92F0, 0xBE59, 0x92F1, 0xE869, 0x92F7, 0xEBF4, 0x92F8, 0xBFF7,
+	0x92F9, 0xEBF3, 0x92FA, 0xEBF0, 0x92FB, 0xEC44, 0x92FC, 0xBFFB,
+	0x92FE, 0xEC41, 0x92FF, 0xEBF8, 0x9300, 0xEC43, 0x9301, 0xEBE9,
+	0x9302, 0xEBF6, 0x9304, 0xBFFD, 0x9306, 0xEBE1, 0x9308, 0xEBDF,
+	0x9309, 0xEC42, 0x930B, 0xEC40, 0x930C, 0xEBFE, 0x930D, 0xEBED,
+	0x930E, 0xEBEC, 0x930F, 0xEBE2, 0x9310, 0xC040, 0x9312, 0xEBE8,
+	0x9313, 0xEBF2, 0x9314, 0xEBFD, 0x9315, 0xC043, 0x9316, 0xEC45,
+	0x9318, 0xC1E8, 0x9319, 0xC045, 0x931A, 0xBFFE, 0x931B, 0xEBE6,
+	0x931D, 0xEBEF, 0x931E, 0xEBDE, 0x931F, 0xEBE0, 0x9320, 0xBFF5,
+	0x9321, 0xC042, 0x9322, 0xBFFA, 0x9323, 0xEBE7, 0x9324, 0xEBF7,
+	0x9325, 0xEBF1, 0x9326, 0xC041, 0x9327, 0xEBDD, 0x9328, 0xC1E3,
+	0x9329, 0xEBF9, 0x932A, 0xEBFC, 0x932B, 0xBFFC, 0x932D, 0xEBEB,
+	0x932E, 0xC044, 0x932F, 0xBFF9, 0x9333, 0xBFF8, 0x9334, 0xEBF5,
+	0x9335, 0xEBFB, 0x9336, 0xBFF6, 0x9338, 0xEBE4, 0x9339, 0xEBFA,
+	0x933C, 0xEBE5, 0x9346, 0xEBEA, 0x9347, 0xEED2, 0x9349, 0xEED7,
+	0x934A, 0xC1E5, 0x934B, 0xC1E7, 0x934C, 0xEEDD, 0x934D, 0xC1E1,
+	0x934E, 0xEEEC, 0x934F, 0xEEE3, 0x9350, 0xEED8, 0x9351, 0xEED9,
+	0x9352, 0xEEE2, 0x9354, 0xC1EE, 0x9355, 0xEEE1, 0x9356, 0xEED1,
+	0x9357, 0xEEE0, 0x9358, 0xEED4, 0x9359, 0xEEED, 0x935A, 0xC1ED,
+	0x935B, 0xC1EB, 0x935C, 0xEED5, 0x935E, 0xEEE8, 0x9360, 0xEEDA,
+	0x9361, 0xEEE7, 0x9363, 0xEEE9, 0x9364, 0xEED0, 0x9365, 0xC1E6,
+	0x9367, 0xEEEA, 0x936A, 0xEEDE, 0x936C, 0xC1EA, 0x936D, 0xEEDB,
+	0x9370, 0xC1EC, 0x9371, 0xEEE4, 0x9375, 0xC1E4, 0x9376, 0xEED6,
+	0x9377, 0xEEE5, 0x9379, 0xEEDF, 0x937A, 0xEBE3, 0x937B, 0xEEE6,
+	0x937C, 0xEED3, 0x937E, 0xC1E9, 0x9380, 0xEEEB, 0x9382, 0xC1E2,
+	0x9383, 0xEECE, 0x9388, 0xF160, 0x9389, 0xF159, 0x938A, 0xC2E9,
+	0x938C, 0xF154, 0x938D, 0xF163, 0x938E, 0xF15B, 0x938F, 0xEEDC,
+	0x9391, 0xF165, 0x9392, 0xF155, 0x9394, 0xC2E8, 0x9395, 0xF15F,
+	0x9396, 0xC2EA, 0x9397, 0xC2F2, 0x9398, 0xC2F0, 0x9399, 0xF161,
+	0x939A, 0xC2F1, 0x939B, 0xF157, 0x939D, 0xF158, 0x939E, 0xF15D,
+	0x939F, 0xF162, 0x93A1, 0xEECD, 0x93A2, 0xC2EB, 0x93A3, 0xF16A,
+	0x93A4, 0xF167, 0x93A5, 0xF16B, 0x93A6, 0xF15E, 0x93A7, 0xF15A,
+	0x93A8, 0xF168, 0x93A9, 0xF36A, 0x93AA, 0xF15C, 0x93AC, 0xC2EE,
+	0x93AE, 0xC2ED, 0x93AF, 0xEECF, 0x93B0, 0xC2EF, 0x93B1, 0xF164,
+	0x93B2, 0xF166, 0x93B3, 0xC2EC, 0x93B4, 0xF169, 0x93B5, 0xF153,
+	0x93B7, 0xF156, 0x93C0, 0xF373, 0x93C2, 0xF363, 0x93C3, 0xC3EB,
+	0x93C4, 0xF371, 0x93C7, 0xF361, 0x93C8, 0xC3EC, 0x93CA, 0xF36C,
+	0x93CC, 0xF368, 0x93CD, 0xC3F1, 0x93CE, 0xF372, 0x93CF, 0xF362,
+	0x93D0, 0xF365, 0x93D1, 0xC3E9, 0x93D2, 0xF374, 0x93D4, 0xF36D,
+	0x93D5, 0xF370, 0x93D6, 0xC3EF, 0x93D7, 0xC3F4, 0x93D8, 0xC3F2,
+	0x93D9, 0xF369, 0x93DA, 0xF364, 0x93DC, 0xC3ED, 0x93DD, 0xC3EE,
+	0x93DE, 0xF360, 0x93DF, 0xC3EA, 0x93E1, 0xC3E8, 0x93E2, 0xC3F0,
+	0x93E3, 0xF36F, 0x93E4, 0xC3F3, 0x93E6, 0xF36B, 0x93E7, 0xF375,
+	0x93E8, 0xC3F5, 0x93EC, 0xF367, 0x93EE, 0xF36E, 0x93F5, 0xF4F3,
+	0x93F6, 0xF542, 0x93F7, 0xF4F5, 0x93F8, 0xF4FC, 0x93F9, 0xF366,
+	0x93FA, 0xF4FA, 0x93FB, 0xF4E9, 0x93FC, 0xF540, 0x93FD, 0xC4C3,
+	0x93FE, 0xF4ED, 0x93FF, 0xF4FE, 0x9400, 0xF4F4, 0x9403, 0xC4C2,
+	0x9406, 0xF544, 0x9407, 0xF4F6, 0x9409, 0xF4FB, 0x940A, 0xF4FD,
+	0x940B, 0xF4E7, 0x940C, 0xF541, 0x940D, 0xF4F2, 0x940E, 0xF4F7,
+	0x940F, 0xF4EB, 0x9410, 0xF4EF, 0x9411, 0xF543, 0x9412, 0xF4F9,
+	0x9413, 0xF4E8, 0x9414, 0xF4EC, 0x9415, 0xF4EE, 0x9416, 0xF4F8,
+	0x9418, 0xC4C1, 0x9419, 0xF4F1, 0x9420, 0xF4EA, 0x9428, 0xF4F0,
+	0x9429, 0xF661, 0x942A, 0xF666, 0x942B, 0xC54F, 0x942C, 0xF668,
+	0x942E, 0xC549, 0x9430, 0xF664, 0x9431, 0xF66A, 0x9432, 0xC54E,
+	0x9433, 0xC54A, 0x9435, 0xC54B, 0x9436, 0xF660, 0x9437, 0xF667,
+	0x9438, 0xC54D, 0x9439, 0xF665, 0x943A, 0xC54C, 0x943B, 0xF65F,
+	0x943C, 0xF663, 0x943D, 0xF662, 0x943F, 0xF65E, 0x9440, 0xF669,
+	0x9444, 0xC5B1, 0x9445, 0xF76D, 0x9446, 0xF770, 0x9447, 0xF76C,
+	0x9448, 0xF76E, 0x9449, 0xF76F, 0x944A, 0xF769, 0x944B, 0xF76A,
+	0x944C, 0xF767, 0x944F, 0xF76B, 0x9450, 0xF768, 0x9451, 0xC5B2,
+	0x9452, 0xC5B3, 0x9455, 0xF84B, 0x9457, 0xF84D, 0x945D, 0xF84C,
+	0x945E, 0xF84E, 0x9460, 0xC5E0, 0x9462, 0xF84A, 0x9463, 0xC5DF,
+	0x9464, 0xC5E1, 0x9468, 0xF8CB, 0x9469, 0xF8CC, 0x946A, 0xC644,
+	0x946B, 0xF8CA, 0x946D, 0xF953, 0x946E, 0xF952, 0x946F, 0xF954,
+	0x9470, 0xC65F, 0x9471, 0xF955, 0x9472, 0xC65E, 0x9473, 0xF956,
+	0x9474, 0xF972, 0x9475, 0xF975, 0x9476, 0xF974, 0x9477, 0xC668,
+	0x9478, 0xF973, 0x947C, 0xC672, 0x947D, 0xC670, 0x947E, 0xC671,
+	0x947F, 0xC677, 0x9480, 0xF9C0, 0x9481, 0xF9C1, 0x9482, 0xF9BF,
+	0x9483, 0xF9C9, 0x9577, 0xAAF8, 0x957A, 0xD844, 0x957B, 0xDC78,
+	0x957C, 0xE8A5, 0x957D, 0xF376, 0x9580, 0xAAF9, 0x9582, 0xADAC,
+	0x9583, 0xB07B, 0x9586, 0xD845, 0x9588, 0xD846, 0x9589, 0xB3AC,
+	0x958B, 0xB67D, 0x958C, 0xDC7A, 0x958D, 0xDC79, 0x958E, 0xB6A3,
+	0x958F, 0xB67C, 0x9590, 0xDC7B, 0x9591, 0xB67E, 0x9592, 0xB6A2,
+	0x9593, 0xB6A1, 0x9594, 0xB67B, 0x9598, 0xB968, 0x959B, 0xE0D0,
+	0x959C, 0xE0CE, 0x959E, 0xE0CF, 0x959F, 0xE0CD, 0x95A1, 0xBBD2,
+	0x95A3, 0xBBD5, 0x95A4, 0xBBD7, 0x95A5, 0xBBD6, 0x95A8, 0xBBD3,
+	0x95A9, 0xBBD4, 0x95AB, 0xE8A7, 0x95AC, 0xE8A6, 0x95AD, 0xBE5B,
+	0x95AE, 0xE8A8, 0x95B0, 0xE8A9, 0x95B1, 0xBE5C, 0x95B5, 0xEC4D,
+	0x95B6, 0xEC4B, 0x95B7, 0xEEF3, 0x95B9, 0xEC49, 0x95BA, 0xEC4A,
+	0x95BB, 0xC046, 0x95BC, 0xEC46, 0x95BD, 0xEC4E, 0x95BE, 0xEC48,
+	0x95BF, 0xEC4C, 0x95C0, 0xEEEF, 0x95C3, 0xEEF1, 0x95C5, 0xEEF2,
+	0x95C6, 0xC1F3, 0x95C7, 0xEEEE, 0x95C8, 0xC1F2, 0x95C9, 0xEEF0,
+	0x95CA, 0xC1EF, 0x95CB, 0xC1F0, 0x95CC, 0xC1F1, 0x95CD, 0xEC47,
+	0x95D0, 0xC2F5, 0x95D1, 0xF16E, 0x95D2, 0xF16C, 0x95D3, 0xF16D,
+	0x95D4, 0xC2F3, 0x95D5, 0xC2F6, 0x95D6, 0xC2F4, 0x95DA, 0xF377,
+	0x95DB, 0xF378, 0x95DC, 0xC3F6, 0x95DE, 0xF545, 0x95DF, 0xF547,
+	0x95E0, 0xF546, 0x95E1, 0xC4C4, 0x95E2, 0xC550, 0x95E3, 0xF66D,
+	0x95E4, 0xF66C, 0x95E5, 0xF66B, 0x961C, 0xAAFA, 0x961E, 0xC9AA,
+	0x9620, 0xCA58, 0x9621, 0xA6E9, 0x9622, 0xCA56, 0x9623, 0xCA59,
+	0x9624, 0xCA57, 0x9628, 0xCBAE, 0x962A, 0xA8C1, 0x962C, 0xA8C2,
+	0x962D, 0xCBB0, 0x962E, 0xA8BF, 0x962F, 0xCBAF, 0x9630, 0xCBAD,
+	0x9631, 0xA8C0, 0x9632, 0xA8BE, 0x9639, 0xCDD8, 0x963A, 0xCDDB,
+	0x963B, 0xAAFD, 0x963C, 0xCDDA, 0x963D, 0xCDD9, 0x963F, 0xAAFC,
+	0x9640, 0xAAFB, 0x9642, 0xAB40, 0x9643, 0xCDDC, 0x9644, 0xAAFE,
+	0x964A, 0xD0C6, 0x964B, 0xADAE, 0x964C, 0xADAF, 0x964D, 0xADB0,
+	0x964E, 0xD0C7, 0x964F, 0xD0C3, 0x9650, 0xADAD, 0x9651, 0xD0C4,
+	0x9653, 0xD0C5, 0x9654, 0xD0C2, 0x9658, 0xB0A4, 0x965B, 0xB0A1,
+	0x965C, 0xD445, 0x965D, 0xB0A2, 0x965E, 0xB0A5, 0x965F, 0xD446,
+	0x9661, 0xB07E, 0x9662, 0xB07C, 0x9663, 0xB07D, 0x9664, 0xB0A3,
+	0x966A, 0xB3AD, 0x966B, 0xD849, 0x966C, 0xB3B5, 0x966D, 0xD848,
+	0x966F, 0xD84B, 0x9670, 0xB3B1, 0x9671, 0xD84A, 0x9672, 0xB6AB,
+	0x9673, 0xB3AF, 0x9674, 0xB3B2, 0x9675, 0xB3AE, 0x9676, 0xB3B3,
+	0x9677, 0xB3B4, 0x9678, 0xB3B0, 0x967C, 0xD847, 0x967D, 0xB6A7,
+	0x967E, 0xDC7D, 0x9680, 0xDCA3, 0x9683, 0xDCA2, 0x9684, 0xB6AC,
+	0x9685, 0xB6A8, 0x9686, 0xB6A9, 0x9687, 0xDC7C, 0x9688, 0xDC7E,
+	0x9689, 0xDCA1, 0x968A, 0xB6A4, 0x968B, 0xB6A6, 0x968D, 0xB6AA,
+	0x968E, 0xB6A5, 0x9691, 0xE0D3, 0x9692, 0xE0D1, 0x9693, 0xE0D2,
+	0x9694, 0xB96A, 0x9695, 0xB96B, 0x9697, 0xE0D4, 0x9698, 0xB969,
+	0x9699, 0xBBD8, 0x969B, 0xBBDA, 0x969C, 0xBBD9, 0x969E, 0xE4BB,
+	0x96A1, 0xE4BC, 0x96A2, 0xE8AB, 0x96A4, 0xE8AA, 0x96A7, 0xC047,
+	0x96A8, 0xC048, 0x96A9, 0xEC4F, 0x96AA, 0xC049, 0x96AC, 0xEEF6,
+	0x96AE, 0xEEF4, 0x96B0, 0xEEF5, 0x96B1, 0xC1F4, 0x96B3, 0xF16F,
+	0x96B4, 0xC3F7, 0x96B8, 0xC1F5, 0x96B9, 0xAB41, 0x96BB, 0xB0A6,
+	0x96BC, 0xD447, 0x96BF, 0xD84C, 0x96C0, 0xB3B6, 0x96C1, 0xB6AD,
+	0x96C2, 0xDCA4, 0x96C3, 0xDCA6, 0x96C4, 0xB6AF, 0x96C5, 0xB6AE,
+	0x96C6, 0xB6B0, 0x96C7, 0xB6B1, 0x96C8, 0xDCA5, 0x96C9, 0xB96E,
+	0x96CA, 0xB96F, 0x96CB, 0xB96D, 0x96CC, 0xBBDB, 0x96CD, 0xB96C,
+	0x96CE, 0xE0D5, 0x96D2, 0xBBDC, 0x96D3, 0xE8AC, 0x96D4, 0xEC50,
+	0x96D5, 0xC04A, 0x96D6, 0xC1F6, 0x96D7, 0xF170, 0x96D8, 0xF174,
+	0x96D9, 0xC2F9, 0x96DA, 0xF171, 0x96DB, 0xC2FA, 0x96DC, 0xC2F8,
+	0x96DD, 0xF175, 0x96DE, 0xC2FB, 0x96DF, 0xF173, 0x96E1, 0xF379,
+	0x96E2, 0xC2F7, 0x96E3, 0xC3F8, 0x96E5, 0xF8CD, 0x96E8, 0xAB42,
+	0x96E9, 0xB3B8, 0x96EA, 0xB3B7, 0x96EF, 0xB6B2, 0x96F0, 0xDCA8,
+	0x96F1, 0xDCA7, 0x96F2, 0xB6B3, 0x96F5, 0xE0D9, 0x96F6, 0xB973,
+	0x96F7, 0xB970, 0x96F8, 0xE0D8, 0x96F9, 0xB972, 0x96FA, 0xE0D6,
+	0x96FB, 0xB971, 0x96FD, 0xE0D7, 0x96FF, 0xE4BD, 0x9700, 0xBBDD,
+	0x9702, 0xE8AF, 0x9704, 0xBE5D, 0x9705, 0xE8AD, 0x9706, 0xBE5E,
+	0x9707, 0xBE5F, 0x9708, 0xE8AE, 0x9709, 0xBE60, 0x970B, 0xEC51,
+	0x970D, 0xC04E, 0x970E, 0xC04B, 0x970F, 0xC050, 0x9710, 0xEC53,
+	0x9711, 0xC04C, 0x9712, 0xEC52, 0x9713, 0xC04F, 0x9716, 0xC04D,
+	0x9718, 0xEEF9, 0x9719, 0xEEFB, 0x971C, 0xC1F7, 0x971D, 0xEEFA,
+	0x971E, 0xC1F8, 0x971F, 0xEEF8, 0x9720, 0xEEF7, 0x9722, 0xF177,
+	0x9723, 0xF176, 0x9724, 0xC2FC, 0x9725, 0xF178, 0x9726, 0xF37E,
+	0x9727, 0xC3FA, 0x9728, 0xF37D, 0x9729, 0xF37A, 0x972A, 0xC3F9,
+	0x972B, 0xF37B, 0x972C, 0xF37C, 0x972E, 0xF548, 0x972F, 0xF549,
+	0x9730, 0xC4C5, 0x9732, 0xC553, 0x9735, 0xF66E, 0x9738, 0xC551,
+	0x9739, 0xC552, 0x973A, 0xF66F, 0x973D, 0xC5B4, 0x973E, 0xC5B5,
+	0x973F, 0xF771, 0x9742, 0xC645, 0x9743, 0xF8CF, 0x9744, 0xC647,
+	0x9746, 0xF8CE, 0x9747, 0xF8D0, 0x9748, 0xC646, 0x9749, 0xF957,
+	0x974B, 0xF9AD, 0x9752, 0xAB43, 0x9756, 0xB974, 0x9758, 0xE4BE,
+	0x975A, 0xE8B0, 0x975B, 0xC051, 0x975C, 0xC052, 0x975E, 0xAB44,
+	0x9760, 0xBE61, 0x9761, 0xC3FB, 0x9762, 0xADB1, 0x9766, 0xC053,
+	0x9768, 0xC5E2, 0x9769, 0xADB2, 0x976A, 0xD84D, 0x976C, 0xDCA9,
+	0x976E, 0xDCAB, 0x9770, 0xDCAA, 0x9772, 0xE0DD, 0x9773, 0xE0DA,
+	0x9774, 0xB975, 0x9776, 0xB976, 0x9777, 0xE0DB, 0x9778, 0xE0DC,
+	0x977A, 0xE4C0, 0x977B, 0xE4C5, 0x977C, 0xBBDE, 0x977D, 0xE4BF,
+	0x977E, 0xE4C1, 0x977F, 0xE4C8, 0x9780, 0xE4C3, 0x9781, 0xE4C7,
+	0x9782, 0xE4C4, 0x9783, 0xE4C2, 0x9784, 0xE4C6, 0x9785, 0xBBDF,
+	0x9788, 0xE8B3, 0x978A, 0xE8B1, 0x978B, 0xBE63, 0x978D, 0xBE62,
+	0x978E, 0xE8B2, 0x978F, 0xBE64, 0x9794, 0xEC56, 0x9797, 0xEC55,
+	0x9798, 0xC054, 0x9799, 0xEC54, 0x979A, 0xEEFC, 0x979C, 0xEEFE,
+	0x979D, 0xEF41, 0x979E, 0xEF40, 0x97A0, 0xC1F9, 0x97A1, 0xEEFD,
+	0x97A2, 0xF1A1, 0x97A3, 0xC2FD, 0x97A4, 0xF17D, 0x97A5, 0xF1A2,
+	0x97A6, 0xC2FE, 0x97A8, 0xF17B, 0x97AA, 0xF17E, 0x97AB, 0xF17C,
+	0x97AC, 0xF179, 0x97AD, 0xC340, 0x97AE, 0xF17A, 0x97B3, 0xF3A1,
+	0x97B6, 0xF3A3, 0x97B7, 0xF3A2, 0x97B9, 0xF54A, 0x97BB, 0xF54B,
+	0x97BF, 0xF670, 0x97C1, 0xC5B7, 0x97C3, 0xC5B6, 0x97C4, 0xF84F,
+	0x97C5, 0xF850, 0x97C6, 0xC648, 0x97C7, 0xF8D1, 0x97C9, 0xC669,
+	0x97CB, 0xADB3, 0x97CC, 0xB6B4, 0x97CD, 0xE4CA, 0x97CE, 0xE4C9,
+	0x97CF, 0xE8B5, 0x97D0, 0xE8B4, 0x97D3, 0xC1FA, 0x97D4, 0xEF43,
+	0x97D5, 0xEF42, 0x97D6, 0xF1A5, 0x97D7, 0xF1A3, 0x97D8, 0xF1A6,
+	0x97D9, 0xF1A4, 0x97DC, 0xC3FC, 0x97DD, 0xF3A4, 0x97DE, 0xF3A5,
+	0x97DF, 0xF3A6, 0x97E1, 0xF671, 0x97E3, 0xF772, 0x97E5, 0xF8D2,
+	0x97ED, 0xADB4, 0x97F0, 0xEC57, 0x97F1, 0xEF44, 0x97F3, 0xADB5,
+	0x97F6, 0xBBE0, 0x97F8, 0xEC58, 0x97F9, 0xC341, 0x97FA, 0xF1A7,
+	0x97FB, 0xC3FD, 0x97FD, 0xF54C, 0x97FE, 0xF54D, 0x97FF, 0xC554,
+	0x9800, 0xF851, 0x9801, 0xADB6, 0x9802, 0xB3BB, 0x9803, 0xB3BC,
+	0x9804, 0xD84E, 0x9805, 0xB6B5, 0x9806, 0xB6B6, 0x9807, 0xDCAC,
+	0x9808, 0xB6B7, 0x980A, 0xB97A, 0x980C, 0xB97C, 0x980D, 0xE0DF,
+	0x980E, 0xE0E0, 0x980F, 0xE0DE, 0x9810, 0xB977, 0x9811, 0xB978,
+	0x9812, 0xB97B, 0x9813, 0xB979, 0x9816, 0xE4CB, 0x9817, 0xBBE1,
+	0x9818, 0xBBE2, 0x981B, 0xE8BC, 0x981C, 0xBE67, 0x981D, 0xE8B7,
+	0x981E, 0xE8B6, 0x9820, 0xE8BB, 0x9821, 0xBE65, 0x9824, 0xC05B,
+	0x9826, 0xE8B8, 0x9827, 0xE8BD, 0x9828, 0xE8BA, 0x9829, 0xE8B9,
+	0x982B, 0xBE66, 0x982D, 0xC059, 0x982F, 0xEC5A, 0x9830, 0xC055,
+	0x9832, 0xEC5B, 0x9835, 0xEC59, 0x9837, 0xC058, 0x9838, 0xC056,
+	0x9839, 0xC05A, 0x983B, 0xC057, 0x9841, 0xEF45, 0x9843, 0xEF4A,
+	0x9844, 0xEF46, 0x9845, 0xEF49, 0x9846, 0xC1FB, 0x9848, 0xEDD4,
+	0x9849, 0xEF48, 0x984A, 0xEF47, 0x984C, 0xC344, 0x984D, 0xC342,
+	0x984E, 0xC345, 0x984F, 0xC343, 0x9850, 0xF1A8, 0x9851, 0xF1A9,
+	0x9852, 0xF1AA, 0x9853, 0xC346, 0x9857, 0xF3AA, 0x9858, 0xC440,
+	0x9859, 0xF3A8, 0x985B, 0xC441, 0x985C, 0xF3A7, 0x985D, 0xF3A9,
+	0x985E, 0xC3FE, 0x985F, 0xF551, 0x9860, 0xF54E, 0x9862, 0xF54F,
+	0x9863, 0xF550, 0x9864, 0xF672, 0x9865, 0xC556, 0x9867, 0xC555,
+	0x9869, 0xF774, 0x986A, 0xF773, 0x986B, 0xC5B8, 0x986F, 0xC5E3,
+	0x9870, 0xC649, 0x9871, 0xC660, 0x9872, 0xF958, 0x9873, 0xF9AE,
+	0x9874, 0xF9AF, 0x98A8, 0xADB7, 0x98A9, 0xDCAD, 0x98AC, 0xE0E1,
+	0x98AD, 0xE4CC, 0x98AE, 0xE4CD, 0x98AF, 0xBBE3, 0x98B1, 0xBBE4,
+	0x98B2, 0xE8BE, 0x98B3, 0xBE68, 0x98B6, 0xC1FC, 0x98B8, 0xF1AB,
+	0x98BA, 0xC347, 0x98BB, 0xF3AD, 0x98BC, 0xC442, 0x98BD, 0xF3AC,
+	0x98BE, 0xF3AE, 0x98BF, 0xF3AB, 0x98C0, 0xF675, 0x98C1, 0xF552,
+	0x98C2, 0xF553, 0x98C4, 0xC4C6, 0x98C6, 0xF674, 0x98C9, 0xF673,
+	0x98CB, 0xF775, 0x98CC, 0xF9B0, 0x98DB, 0xADB8, 0x98DF, 0xADB9,
+	0x98E2, 0xB0A7, 0x98E3, 0xD448, 0x98E5, 0xD84F, 0x98E7, 0xB6B8,
+	0x98E9, 0xB6BB, 0x98EA, 0xB6B9, 0x98EB, 0xDCAE, 0x98ED, 0xB6BD,
+	0x98EF, 0xB6BA, 0x98F2, 0xB6BC, 0x98F4, 0xB97E, 0x98F6, 0xE0E2,
+	0x98F9, 0xE0E3, 0x98FA, 0xE8C0, 0x98FC, 0xB97D, 0x98FD, 0xB9A1,
+	0x98FE, 0xB9A2, 0x9900, 0xE4CF, 0x9902, 0xE4CE, 0x9903, 0xBBE5,
+	0x9905, 0xBBE6, 0x9907, 0xE4D0, 0x9908, 0xE8BF, 0x9909, 0xBBE8,
+	0x990A, 0xBE69, 0x990C, 0xBBE7, 0x9910, 0xC05C, 0x9911, 0xE8C1,
+	0x9912, 0xBE6B, 0x9913, 0xBE6A, 0x9914, 0xE8C2, 0x9915, 0xE8C5,
+	0x9916, 0xE8C3, 0x9917, 0xE8C4, 0x9918, 0xBE6C, 0x991A, 0xC061,
+	0x991B, 0xC05F, 0x991E, 0xC05E, 0x991F, 0xEC5D, 0x9921, 0xC060,
+	0x9924, 0xEC5C, 0x9925, 0xEF4B, 0x9927, 0xEC5E, 0x9928, 0xC05D,
+	0x9929, 0xEC5F, 0x992A, 0xEF4E, 0x992B, 0xEF4C, 0x992C, 0xEF4D,
+	0x992D, 0xEF52, 0x992E, 0xC34B, 0x992F, 0xEF51, 0x9930, 0xEF54,
+	0x9931, 0xEF53, 0x9932, 0xEF50, 0x9933, 0xEF4F, 0x9935, 0xC1FD,
+	0x993A, 0xF1AE, 0x993C, 0xF1AD, 0x993D, 0xC34A, 0x993E, 0xC348,
+	0x993F, 0xC349, 0x9941, 0xF1AC, 0x9943, 0xF3B1, 0x9945, 0xC443,
+	0x9947, 0xF3B0, 0x9948, 0xF3AF, 0x9949, 0xC444, 0x994B, 0xF558,
+	0x994C, 0xF557, 0x994E, 0xF555, 0x9950, 0xF554, 0x9951, 0xC4C8,
+	0x9952, 0xC4C7, 0x9953, 0xF559, 0x9954, 0xF776, 0x9955, 0xC5B9,
+	0x9956, 0xF677, 0x9957, 0xC557, 0x9958, 0xF676, 0x9959, 0xF556,
+	0x995B, 0xF777, 0x995C, 0xC5E4, 0x995E, 0xC661, 0x995F, 0xF959,
+	0x9961, 0xF9B1, 0x9996, 0xADBA, 0x9997, 0xD850, 0x9998, 0xEF55,
+	0x9999, 0xADBB, 0x999C, 0xE4D2, 0x999D, 0xE4D1, 0x999E, 0xEC60,
+	0x99A1, 0xEF57, 0x99A3, 0xEF56, 0x99A5, 0xC34C, 0x99A6, 0xF3B2,
+	0x99A7, 0xF3B3, 0x99A8, 0xC4C9, 0x99AB, 0xF9B2, 0x99AC, 0xB0A8,
+	0x99AD, 0xB6BF, 0x99AE, 0xB6BE, 0x99AF, 0xE0E4, 0x99B0, 0xE0E6,
+	0x99B1, 0xB9A4, 0x99B2, 0xE0E5, 0x99B3, 0xB9A3, 0x99B4, 0xB9A5,
+	0x99B5, 0xE0E7, 0x99B9, 0xE4D4, 0x99BA, 0xE4D6, 0x99BB, 0xE4D5,
+	0x99BD, 0xE4D8, 0x99C1, 0xBBE9, 0x99C2, 0xE4D7, 0x99C3, 0xE4D3,
+	0x99C7, 0xE4D9, 0x99C9, 0xE8CC, 0x99CB, 0xE8CF, 0x99CC, 0xE8D1,
+	0x99CD, 0xE8C7, 0x99CE, 0xE8CB, 0x99CF, 0xE8C8, 0x99D0, 0xBE6E,
+	0x99D1, 0xBE71, 0x99D2, 0xBE73, 0x99D3, 0xE8C9, 0x99D4, 0xE8CA,
+	0x99D5, 0xBE72, 0x99D6, 0xE8CD, 0x99D7, 0xE8D0, 0x99D8, 0xE8CE,
+	0x99D9, 0xBE74, 0x99DB, 0xBE70, 0x99DC, 0xE8C6, 0x99DD, 0xBE6D,
+	0x99DF, 0xBE6F, 0x99E2, 0xC063, 0x99E3, 0xEC66, 0x99E4, 0xEC64,
+	0x99E5, 0xEC63, 0x99E7, 0xEC69, 0x99E9, 0xEC68, 0x99EA, 0xEC67,
+	0x99EC, 0xEC62, 0x99ED, 0xC062, 0x99EE, 0xEC61, 0x99F0, 0xEC65,
+	0x99F1, 0xC064, 0x99F4, 0xEF5A, 0x99F6, 0xEF5E, 0x99F7, 0xEF5B,
+	0x99F8, 0xEF5D, 0x99F9, 0xEF5C, 0x99FA, 0xEF59, 0x99FB, 0xEF5F,
+	0x99FC, 0xEF62, 0x99FD, 0xEF60, 0x99FE, 0xEF61, 0x99FF, 0xC240,
+	0x9A01, 0xC1FE, 0x9A02, 0xEF58, 0x9A03, 0xEF63, 0x9A04, 0xF1B3,
+	0x9A05, 0xF1B6, 0x9A06, 0xF1B8, 0x9A07, 0xF1B7, 0x9A09, 0xF1B1,
+	0x9A0A, 0xF1B5, 0x9A0B, 0xF1B0, 0x9A0D, 0xF1B2, 0x9A0E, 0xC34D,
+	0x9A0F, 0xF1AF, 0x9A11, 0xF1B4, 0x9A14, 0xF3C0, 0x9A15, 0xF3B5,
+	0x9A16, 0xC445, 0x9A19, 0xC446, 0x9A1A, 0xF3B4, 0x9A1B, 0xF3B9,
+	0x9A1C, 0xF3BF, 0x9A1D, 0xF3B7, 0x9A1E, 0xF3BE, 0x9A20, 0xF3BB,
+	0x9A22, 0xF3BA, 0x9A23, 0xF3BD, 0x9A24, 0xF3B8, 0x9A25, 0xF3B6,
+	0x9A27, 0xF3BC, 0x9A29, 0xF560, 0x9A2A, 0xF55E, 0x9A2B, 0xC4CA,
+	0x9A2C, 0xF55D, 0x9A2D, 0xF563, 0x9A2E, 0xF561, 0x9A30, 0xC4CB,
+	0x9A31, 0xF55C, 0x9A32, 0xF55A, 0x9A34, 0xF55B, 0x9A35, 0xC4CD,
+	0x9A36, 0xF55F, 0x9A37, 0xC4CC, 0x9A38, 0xF562, 0x9A39, 0xF678,
+	0x9A3A, 0xF67E, 0x9A3D, 0xF679, 0x9A3E, 0xC55B, 0x9A3F, 0xF6A1,
+	0x9A40, 0xC55A, 0x9A41, 0xF67D, 0x9A42, 0xF67C, 0x9A43, 0xC559,
+	0x9A44, 0xF67B, 0x9A45, 0xC558, 0x9A46, 0xF67A, 0x9A48, 0xF77D,
+	0x9A49, 0xF7A1, 0x9A4A, 0xF77E, 0x9A4C, 0xF77B, 0x9A4D, 0xC5BB,
+	0x9A4E, 0xF778, 0x9A4F, 0xF77C, 0x9A50, 0xF7A3, 0x9A52, 0xF7A2,
+	0x9A53, 0xF779, 0x9A54, 0xF77A, 0x9A55, 0xC5BA, 0x9A56, 0xF852,
+	0x9A57, 0xC5E7, 0x9A59, 0xF853, 0x9A5A, 0xC5E5, 0x9A5B, 0xC5E6,
+	0x9A5E, 0xF8D3, 0x9A5F, 0xC64A, 0x9A60, 0xF976, 0x9A62, 0xC66A,
+	0x9A64, 0xF9B3, 0x9A65, 0xC66B, 0x9A66, 0xF9B4, 0x9A67, 0xF9B5,
+	0x9A68, 0xF9C3, 0x9A69, 0xF9C2, 0x9A6A, 0xC67A, 0x9A6B, 0xF9CD,
+	0x9AA8, 0xB0A9, 0x9AAB, 0xE0E9, 0x9AAD, 0xE0E8, 0x9AAF, 0xBBEA,
+	0x9AB0, 0xBBEB, 0x9AB1, 0xE4DA, 0x9AB3, 0xE8D2, 0x9AB4, 0xEC6C,
+	0x9AB7, 0xBE75, 0x9AB8, 0xC065, 0x9AB9, 0xEC6A, 0x9ABB, 0xEC6D,
+	0x9ABC, 0xC066, 0x9ABE, 0xEF64, 0x9ABF, 0xEC6B, 0x9AC0, 0xF1B9,
+	0x9AC1, 0xC34E, 0x9AC2, 0xF3C1, 0x9AC6, 0xF566, 0x9AC7, 0xF564,
+	0x9ACA, 0xF565, 0x9ACD, 0xF6A2, 0x9ACF, 0xC55C, 0x9AD0, 0xF7A4,
+	0x9AD1, 0xC5EA, 0x9AD2, 0xC5BC, 0x9AD3, 0xC5E8, 0x9AD4, 0xC5E9,
+	0x9AD5, 0xF8D4, 0x9AD6, 0xC662, 0x9AD8, 0xB0AA, 0x9ADC, 0xF1BA,
+	0x9ADF, 0xD449, 0x9AE1, 0xB9A6, 0x9AE3, 0xE4DB, 0x9AE6, 0xBBEC,
+	0x9AE7, 0xE4DC, 0x9AEB, 0xE8D4, 0x9AEC, 0xE8D3, 0x9AED, 0xC068,
+	0x9AEE, 0xBE76, 0x9AEF, 0xBE77, 0x9AF1, 0xE8D7, 0x9AF2, 0xE8D6,
+	0x9AF3, 0xE8D5, 0x9AF6, 0xEC6E, 0x9AF7, 0xEC71, 0x9AF9, 0xEC70,
+	0x9AFA, 0xEC6F, 0x9AFB, 0xC067, 0x9AFC, 0xEF68, 0x9AFD, 0xEF66,
+	0x9AFE, 0xEF65, 0x9B01, 0xEF67, 0x9B03, 0xC34F, 0x9B04, 0xF1BC,
+	0x9B05, 0xF1BD, 0x9B06, 0xC350, 0x9B08, 0xF1BB, 0x9B0A, 0xF3C3,
+	0x9B0B, 0xF3C2, 0x9B0C, 0xF3C5, 0x9B0D, 0xC447, 0x9B0E, 0xF3C4,
+	0x9B10, 0xF567, 0x9B11, 0xF569, 0x9B12, 0xF568, 0x9B15, 0xF6A3,
+	0x9B16, 0xF6A6, 0x9B17, 0xF6A4, 0x9B18, 0xF6A5, 0x9B19, 0xF7A5,
+	0x9B1A, 0xC5BD, 0x9B1E, 0xF854, 0x9B1F, 0xF855, 0x9B20, 0xF856,
+	0x9B22, 0xC64B, 0x9B23, 0xC663, 0x9B24, 0xF9B6, 0x9B25, 0xB0AB,
+	0x9B27, 0xBE78, 0x9B28, 0xC069, 0x9B29, 0xF1BE, 0x9B2B, 0xF7A6,
+	0x9B2E, 0xF9C4, 0x9B2F, 0xD44A, 0x9B31, 0xC67B, 0x9B32, 0xB0AC,
+	0x9B33, 0xEC72, 0x9B35, 0xF1BF, 0x9B37, 0xF3C6, 0x9B3A, 0xF6A7,
+	0x9B3B, 0xF7A7, 0x9B3C, 0xB0AD, 0x9B3E, 0xE4DD, 0x9B3F, 0xE4DE,
+	0x9B41, 0xBBED, 0x9B42, 0xBBEE, 0x9B43, 0xE8D9, 0x9B44, 0xBE7A,
+	0x9B45, 0xBE79, 0x9B46, 0xE8D8, 0x9B48, 0xEF69, 0x9B4A, 0xF1C0,
+	0x9B4B, 0xF1C2, 0x9B4C, 0xF1C1, 0x9B4D, 0xC353, 0x9B4E, 0xC352,
+	0x9B4F, 0xC351, 0x9B51, 0xC55E, 0x9B52, 0xF6A8, 0x9B54, 0xC55D,
+	0x9B55, 0xF7A9, 0x9B56, 0xF7A8, 0x9B58, 0xC64C, 0x9B59, 0xF8D5,
+	0x9B5A, 0xB3BD, 0x9B5B, 0xE0EA, 0x9B5F, 0xE4E1, 0x9B60, 0xE4DF,
+	0x9B61, 0xE4E0, 0x9B64, 0xE8E2, 0x9B66, 0xE8DD, 0x9B67, 0xE8DA,
+	0x9B68, 0xE8E1, 0x9B6C, 0xE8E3, 0x9B6F, 0xBE7C, 0x9B70, 0xE8E0,
+	0x9B71, 0xE8DC, 0x9B74, 0xE8DB, 0x9B75, 0xE8DF, 0x9B76, 0xE8DE,
+	0x9B77, 0xBE7B, 0x9B7A, 0xEC7D, 0x9B7B, 0xEC78, 0x9B7C, 0xEC76,
+	0x9B7D, 0xECA1, 0x9B7E, 0xEC77, 0x9B80, 0xEC73, 0x9B82, 0xEC79,
+	0x9B85, 0xEC74, 0x9B86, 0xEF72, 0x9B87, 0xEC75, 0x9B88, 0xECA2,
+	0x9B90, 0xEC7C, 0x9B91, 0xC06A, 0x9B92, 0xEC7B, 0x9B93, 0xEC7A,
+	0x9B95, 0xEC7E, 0x9B9A, 0xEF6A, 0x9B9B, 0xEF6D, 0x9B9E, 0xEF6C,
+	0x9BA0, 0xEF74, 0x9BA1, 0xEF6F, 0x9BA2, 0xEF73, 0x9BA4, 0xEF71,
+	0x9BA5, 0xEF70, 0x9BA6, 0xEF6E, 0x9BA8, 0xEF6B, 0x9BAA, 0xC243,
+	0x9BAB, 0xC242, 0x9BAD, 0xC244, 0x9BAE, 0xC241, 0x9BAF, 0xEF75,
+	0x9BB5, 0xF1C8, 0x9BB6, 0xF1CB, 0x9BB8, 0xF1C9, 0x9BB9, 0xF1CD,
+	0x9BBD, 0xF1CE, 0x9BBF, 0xF1C6, 0x9BC0, 0xC358, 0x9BC1, 0xF1C7,
+	0x9BC3, 0xF1C5, 0x9BC4, 0xF1CC, 0x9BC6, 0xF1C4, 0x9BC7, 0xF1C3,
+	0x9BC8, 0xC357, 0x9BC9, 0xC355, 0x9BCA, 0xC354, 0x9BD3, 0xF1CA,
+	0x9BD4, 0xF3CF, 0x9BD5, 0xF3D5, 0x9BD6, 0xC44A, 0x9BD7, 0xF3D0,
+	0x9BD9, 0xF3D3, 0x9BDA, 0xF3D7, 0x9BDB, 0xC44B, 0x9BDC, 0xF3D2,
+	0x9BDE, 0xF3CA, 0x9BE0, 0xF3C9, 0x9BE1, 0xF3D6, 0x9BE2, 0xF3CD,
+	0x9BE4, 0xF3CB, 0x9BE5, 0xF3D4, 0x9BE6, 0xF3CC, 0x9BE7, 0xC449,
+	0x9BE8, 0xC448, 0x9BEA, 0xF3C7, 0x9BEB, 0xF3C8, 0x9BEC, 0xF3D1,
+	0x9BF0, 0xF3CE, 0x9BF7, 0xF56C, 0x9BF8, 0xF56F, 0x9BFD, 0xC356,
+	0x9C05, 0xF56D, 0x9C06, 0xF573, 0x9C07, 0xF571, 0x9C08, 0xF56B,
+	0x9C09, 0xF576, 0x9C0B, 0xF56A, 0x9C0D, 0xC4CF, 0x9C0E, 0xF572,
+	0x9C12, 0xF56E, 0x9C13, 0xC4CE, 0x9C14, 0xF575, 0x9C17, 0xF574,
+	0x9C1C, 0xF6AB, 0x9C1D, 0xF6AA, 0x9C21, 0xF6B1, 0x9C23, 0xF6AD,
+	0x9C24, 0xF6B0, 0x9C25, 0xC560, 0x9C28, 0xF6AE, 0x9C29, 0xF6AF,
+	0x9C2B, 0xF6A9, 0x9C2C, 0xF6AC, 0x9C2D, 0xC55F, 0x9C31, 0xC5BF,
+	0x9C32, 0xF7B4, 0x9C33, 0xF7AF, 0x9C34, 0xF7B3, 0x9C36, 0xF7B6,
+	0x9C37, 0xF7B2, 0x9C39, 0xF7AE, 0x9C3B, 0xC5C1, 0x9C3C, 0xF7B1,
+	0x9C3D, 0xF7B5, 0x9C3E, 0xC5C0, 0x9C3F, 0xF7AC, 0x9C40, 0xF570,
+	0x9C41, 0xF7B0, 0x9C44, 0xF7AD, 0x9C46, 0xF7AA, 0x9C48, 0xF7AB,
+	0x9C49, 0xC5BE, 0x9C4A, 0xF85A, 0x9C4B, 0xF85C, 0x9C4C, 0xF85F,
+	0x9C4D, 0xF85B, 0x9C4E, 0xF860, 0x9C50, 0xF859, 0x9C52, 0xF857,
+	0x9C54, 0xC5EB, 0x9C55, 0xF85D, 0x9C56, 0xC5ED, 0x9C57, 0xC5EC,
+	0x9C58, 0xF858, 0x9C59, 0xF85E, 0x9C5E, 0xF8DA, 0x9C5F, 0xC64D,
+	0x9C60, 0xF8DB, 0x9C62, 0xF8D9, 0x9C63, 0xF8D6, 0x9C66, 0xF8D8,
+	0x9C67, 0xF8D7, 0x9C68, 0xF95A, 0x9C6D, 0xF95C, 0x9C6E, 0xF95B,
+	0x9C71, 0xF979, 0x9C73, 0xF978, 0x9C74, 0xF977, 0x9C75, 0xF97A,
+	0x9C77, 0xC673, 0x9C78, 0xC674, 0x9C79, 0xF9CA, 0x9C7A, 0xF9CE,
+	0x9CE5, 0xB3BE, 0x9CE6, 0xDCAF, 0x9CE7, 0xE0ED, 0x9CE9, 0xB9A7,
+	0x9CEA, 0xE0EB, 0x9CED, 0xE0EC, 0x9CF1, 0xE4E2, 0x9CF2, 0xE4E3,
+	0x9CF3, 0xBBF1, 0x9CF4, 0xBBEF, 0x9CF5, 0xE4E4, 0x9CF6, 0xBBF0,
+	0x9CF7, 0xE8E8, 0x9CF9, 0xE8EB, 0x9CFA, 0xE8E5, 0x9CFB, 0xE8EC,
+	0x9CFC, 0xE8E4, 0x9CFD, 0xE8E6, 0x9CFF, 0xE8E7, 0x9D00, 0xE8EA,
+	0x9D03, 0xBEA1, 0x9D04, 0xE8EF, 0x9D05, 0xE8EE, 0x9D06, 0xBE7D,
+	0x9D07, 0xE8E9, 0x9D08, 0xE8ED, 0x9D09, 0xBE7E, 0x9D10, 0xECAC,
+	0x9D12, 0xC06F, 0x9D14, 0xECA7, 0x9D15, 0xC06B, 0x9D17, 0xECA4,
+	0x9D18, 0xECAA, 0x9D19, 0xECAD, 0x9D1B, 0xC070, 0x9D1D, 0xECA9,
+	0x9D1E, 0xECA6, 0x9D1F, 0xECAE, 0x9D20, 0xECA5, 0x9D22, 0xECAB,
+	0x9D23, 0xC06C, 0x9D25, 0xECA3, 0x9D26, 0xC06D, 0x9D28, 0xC06E,
+	0x9D29, 0xECA8, 0x9D2D, 0xEFA9, 0x9D2E, 0xEF7A, 0x9D2F, 0xEF7B,
+	0x9D30, 0xEF7E, 0x9D31, 0xEF7C, 0x9D33, 0xEF76, 0x9D36, 0xEF79,
+	0x9D37, 0xEFA5, 0x9D38, 0xEF7D, 0x9D3B, 0xC245, 0x9D3D, 0xEFA7,
+	0x9D3E, 0xEFA4, 0x9D3F, 0xC246, 0x9D40, 0xEFA6, 0x9D41, 0xEF77,
+	0x9D42, 0xEFA2, 0x9D43, 0xEFA3, 0x9D45, 0xEFA1, 0x9D4A, 0xF1D2,
+	0x9D4B, 0xF1D4, 0x9D4C, 0xF1D7, 0x9D4F, 0xF1D1, 0x9D51, 0xC359,
+	0x9D52, 0xF1D9, 0x9D53, 0xF1D0, 0x9D54, 0xF1DA, 0x9D56, 0xF1D6,
+	0x9D57, 0xF1D8, 0x9D58, 0xF1DC, 0x9D59, 0xF1D5, 0x9D5A, 0xF1DD,
+	0x9D5B, 0xF1D3, 0x9D5C, 0xF1CF, 0x9D5D, 0xC35A, 0x9D5F, 0xF1DB,
+	0x9D60, 0xC35B, 0x9D61, 0xC44D, 0x9D67, 0xEF78, 0x9D68, 0xF3F1,
+	0x9D69, 0xF3E8, 0x9D6A, 0xC44F, 0x9D6B, 0xF3E4, 0x9D6C, 0xC450,
+	0x9D6F, 0xF3ED, 0x9D70, 0xF3E7, 0x9D71, 0xF3DD, 0x9D72, 0xC44E,
+	0x9D73, 0xF3EA, 0x9D74, 0xF3E5, 0x9D75, 0xF3E6, 0x9D77, 0xF3D8,
+	0x9D78, 0xF3DF, 0x9D79, 0xF3EE, 0x9D7B, 0xF3EB, 0x9D7D, 0xF3E3,
+	0x9D7F, 0xF3EF, 0x9D80, 0xF3DE, 0x9D81, 0xF3D9, 0x9D82, 0xF3EC,
+	0x9D84, 0xF3DB, 0x9D85, 0xF3E9, 0x9D86, 0xF3E0, 0x9D87, 0xF3F0,
+	0x9D88, 0xF3DC, 0x9D89, 0xC44C, 0x9D8A, 0xF3DA, 0x9D8B, 0xF3E1,
+	0x9D8C, 0xF3E2, 0x9D90, 0xF57D, 0x9D92, 0xF57B, 0x9D94, 0xF5A2,
+	0x9D96, 0xF5AE, 0x9D97, 0xF5A5, 0x9D98, 0xF57C, 0x9D99, 0xF578,
+	0x9D9A, 0xF5A7, 0x9D9B, 0xF57E, 0x9D9C, 0xF5A3, 0x9D9D, 0xF57A,
+	0x9D9E, 0xF5AA, 0x9D9F, 0xF577, 0x9DA0, 0xF5A1, 0x9DA1, 0xF5A6,
+	0x9DA2, 0xF5A8, 0x9DA3, 0xF5AB, 0x9DA4, 0xF579, 0x9DA6, 0xF5AF,
+	0x9DA7, 0xF5B0, 0x9DA8, 0xF5A9, 0x9DA9, 0xF5AD, 0x9DAA, 0xF5A4,
+	0x9DAC, 0xF6C1, 0x9DAD, 0xF6C4, 0x9DAF, 0xC561, 0x9DB1, 0xF6C3,
+	0x9DB2, 0xF6C8, 0x9DB3, 0xF6C6, 0x9DB4, 0xC562, 0x9DB5, 0xF6BD,
+	0x9DB6, 0xF6B3, 0x9DB7, 0xF6B2, 0x9DB8, 0xC564, 0x9DB9, 0xF6BF,
+	0x9DBA, 0xF6C0, 0x9DBB, 0xF6BC, 0x9DBC, 0xF6B4, 0x9DBE, 0xF6B9,
+	0x9DBF, 0xF5AC, 0x9DC1, 0xF6B5, 0x9DC2, 0xC563, 0x9DC3, 0xF6BB,
+	0x9DC5, 0xF6BA, 0x9DC7, 0xF6B6, 0x9DC8, 0xF6C2, 0x9DCA, 0xF6B7,
+	0x9DCB, 0xF7BB, 0x9DCC, 0xF6C5, 0x9DCD, 0xF6C7, 0x9DCE, 0xF6BE,
+	0x9DCF, 0xF6B8, 0x9DD0, 0xF7BC, 0x9DD1, 0xF7BE, 0x9DD2, 0xF7B8,
+	0x9DD3, 0xC5C2, 0x9DD5, 0xF7C5, 0x9DD6, 0xF7C3, 0x9DD7, 0xC5C3,
+	0x9DD8, 0xF7C2, 0x9DD9, 0xF7C1, 0x9DDA, 0xF7BA, 0x9DDB, 0xF7B7,
+	0x9DDC, 0xF7BD, 0x9DDD, 0xF7C6, 0x9DDE, 0xF7B9, 0x9DDF, 0xF7BF,
+	0x9DE1, 0xF869, 0x9DE2, 0xF86E, 0x9DE3, 0xF864, 0x9DE4, 0xF867,
+	0x9DE5, 0xC5EE, 0x9DE6, 0xF86B, 0x9DE8, 0xF872, 0x9DE9, 0xF7C0,
+	0x9DEB, 0xF865, 0x9DEC, 0xF86F, 0x9DED, 0xF873, 0x9DEE, 0xF86A,
+	0x9DEF, 0xF863, 0x9DF0, 0xF86D, 0x9DF2, 0xF86C, 0x9DF3, 0xF871,
+	0x9DF4, 0xF870, 0x9DF5, 0xF7C4, 0x9DF6, 0xF868, 0x9DF7, 0xF862,
+	0x9DF8, 0xF866, 0x9DF9, 0xC64E, 0x9DFA, 0xC64F, 0x9DFB, 0xF861,
+	0x9DFD, 0xF8E6, 0x9DFE, 0xF8DD, 0x9DFF, 0xF8E5, 0x9E00, 0xF8E2,
+	0x9E01, 0xF8E3, 0x9E02, 0xF8DC, 0x9E03, 0xF8DF, 0x9E04, 0xF8E7,
+	0x9E05, 0xF8E1, 0x9E06, 0xF8E0, 0x9E07, 0xF8DE, 0x9E09, 0xF8E4,
+	0x9E0B, 0xF95D, 0x9E0D, 0xF95E, 0x9E0F, 0xF960, 0x9E10, 0xF95F,
+	0x9E11, 0xF962, 0x9E12, 0xF961, 0x9E13, 0xF97C, 0x9E14, 0xF97B,
+	0x9E15, 0xF9B7, 0x9E17, 0xF9B8, 0x9E19, 0xF9C5, 0x9E1A, 0xC678,
+	0x9E1B, 0xC67C, 0x9E1D, 0xF9CF, 0x9E1E, 0xC67D, 0x9E75, 0xB3BF,
+	0x9E79, 0xC4D0, 0x9E7A, 0xF6C9, 0x9E7C, 0xC650, 0x9E7D, 0xC651,
+	0x9E7F, 0xB3C0, 0x9E80, 0xE0EE, 0x9E82, 0xB9A8, 0x9E83, 0xE8F0,
+	0x9E86, 0xECB0, 0x9E87, 0xECB1, 0x9E88, 0xECAF, 0x9E89, 0xEFAB,
+	0x9E8A, 0xEFAA, 0x9E8B, 0xC247, 0x9E8C, 0xF1DF, 0x9E8D, 0xEFAC,
+	0x9E8E, 0xF1DE, 0x9E91, 0xF3F3, 0x9E92, 0xC451, 0x9E93, 0xC453,
+	0x9E94, 0xF3F2, 0x9E97, 0xC452, 0x9E99, 0xF5B1, 0x9E9A, 0xF5B3,
+	0x9E9B, 0xF5B2, 0x9E9C, 0xF6CA, 0x9E9D, 0xC565, 0x9E9F, 0xC5EF,
+	0x9EA0, 0xF8E8, 0x9EA1, 0xF963, 0x9EA4, 0xF9D2, 0x9EA5, 0xB3C1,
+	0x9EA7, 0xE4E5, 0x9EA9, 0xBEA2, 0x9EAD, 0xECB3, 0x9EAE, 0xECB2,
+	0x9EB0, 0xEFAD, 0x9EB4, 0xC454, 0x9EB5, 0xC4D1, 0x9EB6, 0xF7C7,
+	0x9EB7, 0xF9CB, 0x9EBB, 0xB3C2, 0x9EBC, 0xBBF2, 0x9EBE, 0xBEA3,
+	0x9EC0, 0xF3F4, 0x9EC2, 0xF874, 0x9EC3, 0xB6C0, 0x9EC8, 0xEFAE,
+	0x9ECC, 0xC664, 0x9ECD, 0xB6C1, 0x9ECE, 0xBEA4, 0x9ECF, 0xC248,
+	0x9ED0, 0xF875, 0x9ED1, 0xB6C2, 0x9ED3, 0xE8F1, 0x9ED4, 0xC072,
+	0x9ED5, 0xECB4, 0x9ED6, 0xECB5, 0x9ED8, 0xC071, 0x9EDA, 0xEFAF,
+	0x9EDB, 0xC24C, 0x9EDC, 0xC24A, 0x9EDD, 0xC24B, 0x9EDE, 0xC249,
+	0x9EDF, 0xF1E0, 0x9EE0, 0xC35C, 0x9EE4, 0xF5B5, 0x9EE5, 0xF5B4,
+	0x9EE6, 0xF5B7, 0x9EE7, 0xF5B6, 0x9EE8, 0xC4D2, 0x9EEB, 0xF6CB,
+	0x9EED, 0xF6CD, 0x9EEE, 0xF6CC, 0x9EEF, 0xC566, 0x9EF0, 0xF7C8,
+	0x9EF2, 0xF876, 0x9EF3, 0xF877, 0x9EF4, 0xC5F0, 0x9EF5, 0xF964,
+	0x9EF6, 0xF97D, 0x9EF7, 0xC675, 0x9EF9, 0xDCB0, 0x9EFA, 0xECB6,
+	0x9EFB, 0xEFB0, 0x9EFC, 0xF3F5, 0x9EFD, 0xE0EF, 0x9EFF, 0xEFB1,
+	0x9F00, 0xF1E2, 0x9F01, 0xF1E1, 0x9F06, 0xF878, 0x9F07, 0xC652,
+	0x9F09, 0xF965, 0x9F0A, 0xF97E, 0x9F0E, 0xB9A9, 0x9F0F, 0xE8F2,
+	0x9F10, 0xE8F3, 0x9F12, 0xECB7, 0x9F13, 0xB9AA, 0x9F15, 0xC35D,
+	0x9F16, 0xF1E3, 0x9F18, 0xF6CF, 0x9F19, 0xC567, 0x9F1A, 0xF6D0,
+	0x9F1B, 0xF6CE, 0x9F1C, 0xF879, 0x9F1E, 0xF8E9, 0x9F20, 0xB9AB,
+	0x9F22, 0xEFB4, 0x9F23, 0xEFB3, 0x9F24, 0xEFB2, 0x9F25, 0xF1E4,
+	0x9F28, 0xF1E8, 0x9F29, 0xF1E7, 0x9F2A, 0xF1E6, 0x9F2B, 0xF1E5,
+	0x9F2C, 0xC35E, 0x9F2D, 0xF3F6, 0x9F2E, 0xF5B9, 0x9F2F, 0xC4D3,
+	0x9F30, 0xF5B8, 0x9F31, 0xF6D1, 0x9F32, 0xF7CB, 0x9F33, 0xF7CA,
+	0x9F34, 0xC5C4, 0x9F35, 0xF7C9, 0x9F36, 0xF87C, 0x9F37, 0xF87B,
+	0x9F38, 0xF87A, 0x9F3B, 0xBBF3, 0x9F3D, 0xECB8, 0x9F3E, 0xC24D,
+	0x9F40, 0xF3F7, 0x9F41, 0xF3F8, 0x9F42, 0xF7CC, 0x9F43, 0xF87D,
+	0x9F46, 0xF8EA, 0x9F47, 0xF966, 0x9F48, 0xF9B9, 0x9F49, 0xF9D4,
+	0x9F4A, 0xBBF4, 0x9F4B, 0xC24E, 0x9F4C, 0xF1E9, 0x9F4D, 0xF3F9,
+	0x9F4E, 0xF6D2, 0x9F4F, 0xF87E, 0x9F52, 0xBEA6, 0x9F54, 0xEFB5,
+	0x9F55, 0xF1EA, 0x9F56, 0xF3FA, 0x9F57, 0xF3FB, 0x9F58, 0xF3FC,
+	0x9F59, 0xF5BE, 0x9F5B, 0xF5BA, 0x9F5C, 0xC568, 0x9F5D, 0xF5BD,
+	0x9F5E, 0xF5BC, 0x9F5F, 0xC4D4, 0x9F60, 0xF5BB, 0x9F61, 0xC4D6,
+	0x9F63, 0xC4D5, 0x9F64, 0xF6D4, 0x9F65, 0xF6D3, 0x9F66, 0xC569,
+	0x9F67, 0xC56A, 0x9F6A, 0xC5C6, 0x9F6B, 0xF7CD, 0x9F6C, 0xC5C5,
+	0x9F6E, 0xF8A3, 0x9F6F, 0xF8A4, 0x9F70, 0xF8A2, 0x9F71, 0xF8A1,
+	0x9F72, 0xC654, 0x9F74, 0xF8EB, 0x9F75, 0xF8EC, 0x9F76, 0xF8ED,
+	0x9F77, 0xC653, 0x9F78, 0xF967, 0x9F79, 0xF96A, 0x9F7A, 0xF969,
+	0x9F7B, 0xF968, 0x9F7E, 0xF9D3, 0x9F8D, 0xC073, 0x9F90, 0xC365,
+	0x9F91, 0xF5BF, 0x9F92, 0xF6D5, 0x9F94, 0xC5C7, 0x9F95, 0xF7CE,
+	0x9F98, 0xF9D5, 0x9F9C, 0xC074, 0x9FA0, 0xEFB6, 0x9FA2, 0xF7CF,
+	0x9FA4, 0xF9A1, 0xFA0C, 0xC94A, 0xFA0D, 0xDDFC, 0xFE30, 0xA14A,
+	0xFE31, 0xA157, 0xFE33, 0xA159, 0xFE34, 0xA15B, 0xFE35, 0xA15F,
+	0xFE36, 0xA160, 0xFE37, 0xA163, 0xFE38, 0xA164, 0xFE39, 0xA167,
+	0xFE3A, 0xA168, 0xFE3B, 0xA16B, 0xFE3C, 0xA16C, 0xFE3D, 0xA16F,
+	0xFE3E, 0xA170, 0xFE3F, 0xA173, 0xFE40, 0xA174, 0xFE41, 0xA177,
+	0xFE42, 0xA178, 0xFE43, 0xA17B, 0xFE44, 0xA17C, 0xFE49, 0xA1C6,
+	0xFE4A, 0xA1C7, 0xFE4B, 0xA1CA, 0xFE4C, 0xA1CB, 0xFE4D, 0xA1C8,
+	0xFE4E, 0xA1C9, 0xFE4F, 0xA15C, 0xFE50, 0xA14D, 0xFE51, 0xA14E,
+	0xFE52, 0xA14F, 0xFE54, 0xA151, 0xFE55, 0xA152, 0xFE56, 0xA153,
+	0xFE57, 0xA154, 0xFE59, 0xA17D, 0xFE5A, 0xA17E, 0xFE5B, 0xA1A1,
+	0xFE5C, 0xA1A2, 0xFE5D, 0xA1A3, 0xFE5E, 0xA1A4, 0xFE5F, 0xA1CC,
+	0xFE60, 0xA1CD, 0xFE61, 0xA1CE, 0xFE62, 0xA1DE, 0xFE63, 0xA1DF,
+	0xFE64, 0xA1E0, 0xFE65, 0xA1E1, 0xFE66, 0xA1E2, 0xFE68, 0xA242,
+	0xFE69, 0xA24C, 0xFE6A, 0xA24D, 0xFE6B, 0xA24E, 0xFF01, 0xA149,
+	0xFF03, 0xA1AD, 0xFF04, 0xA243, 0xFF05, 0xA248, 0xFF06, 0xA1AE,
+	0xFF08, 0xA15D, 0xFF09, 0xA15E, 0xFF0A, 0xA1AF, 0xFF0B, 0xA1CF,
+	0xFF0C, 0xA141, 0xFF0D, 0xA1D0, 0xFF0E, 0xA144, 0xFF0F, 0xA1FE,
+	0xFF10, 0xA2AF, 0xFF11, 0xA2B0, 0xFF12, 0xA2B1, 0xFF13, 0xA2B2,
+	0xFF14, 0xA2B3, 0xFF15, 0xA2B4, 0xFF16, 0xA2B5, 0xFF17, 0xA2B6,
+	0xFF18, 0xA2B7, 0xFF19, 0xA2B8, 0xFF1A, 0xA147, 0xFF1B, 0xA146,
+	0xFF1C, 0xA1D5, 0xFF1D, 0xA1D7, 0xFF1E, 0xA1D6, 0xFF1F, 0xA148,
+	0xFF20, 0xA249, 0xFF21, 0xA2CF, 0xFF22, 0xA2D0, 0xFF23, 0xA2D1,
+	0xFF24, 0xA2D2, 0xFF25, 0xA2D3, 0xFF26, 0xA2D4, 0xFF27, 0xA2D5,
+	0xFF28, 0xA2D6, 0xFF29, 0xA2D7, 0xFF2A, 0xA2D8, 0xFF2B, 0xA2D9,
+	0xFF2C, 0xA2DA, 0xFF2D, 0xA2DB, 0xFF2E, 0xA2DC, 0xFF2F, 0xA2DD,
+	0xFF30, 0xA2DE, 0xFF31, 0xA2DF, 0xFF32, 0xA2E0, 0xFF33, 0xA2E1,
+	0xFF34, 0xA2E2, 0xFF35, 0xA2E3, 0xFF36, 0xA2E4, 0xFF37, 0xA2E5,
+	0xFF38, 0xA2E6, 0xFF39, 0xA2E7, 0xFF3A, 0xA2E8, 0xFF3C, 0xA240,
+	0xFF3F, 0xA1C4, 0xFF41, 0xA2E9, 0xFF42, 0xA2EA, 0xFF43, 0xA2EB,
+	0xFF44, 0xA2EC, 0xFF45, 0xA2ED, 0xFF46, 0xA2EE, 0xFF47, 0xA2EF,
+	0xFF48, 0xA2F0, 0xFF49, 0xA2F1, 0xFF4A, 0xA2F2, 0xFF4B, 0xA2F3,
+	0xFF4C, 0xA2F4, 0xFF4D, 0xA2F5, 0xFF4E, 0xA2F6, 0xFF4F, 0xA2F7,
+	0xFF50, 0xA2F8, 0xFF51, 0xA2F9, 0xFF52, 0xA2FA, 0xFF53, 0xA2FB,
+	0xFF54, 0xA2FC, 0xFF55, 0xA2FD, 0xFF56, 0xA2FE, 0xFF57, 0xA340,
+	0xFF58, 0xA341, 0xFF59, 0xA342, 0xFF5A, 0xA343, 0xFF5B, 0xA161,
+	0xFF5C, 0xA155, 0xFF5D, 0xA162, 0xFF5E, 0xA1E3, 0xFFE0, 0xA246,
+	0xFFE1, 0xA247, 0xFFE3, 0xA1C3, 0xFFE5, 0xA244, 0, 0
+};
+
+static
+const WCHAR oem2uni[] = {
+/*	OEM - Unicode,  OEM - Unicode,  OEM - Unicode,  OEM - Unicode */
+	0xA140, 0x3000, 0xA141, 0xFF0C, 0xA142, 0x3001, 0xA143, 0x3002,
+	0xA144, 0xFF0E, 0xA145, 0x2027, 0xA146, 0xFF1B, 0xA147, 0xFF1A,
+	0xA148, 0xFF1F, 0xA149, 0xFF01, 0xA14A, 0xFE30, 0xA14B, 0x2026,
+	0xA14C, 0x2025, 0xA14D, 0xFE50, 0xA14E, 0xFE51, 0xA14F, 0xFE52,
+	0xA150, 0x00B7, 0xA151, 0xFE54, 0xA152, 0xFE55, 0xA153, 0xFE56,
+	0xA154, 0xFE57, 0xA155, 0xFF5C, 0xA156, 0x2013, 0xA157, 0xFE31,
+	0xA158, 0x2014, 0xA159, 0xFE33, 0xA15A, 0x2574, 0xA15B, 0xFE34,
+	0xA15C, 0xFE4F, 0xA15D, 0xFF08, 0xA15E, 0xFF09, 0xA15F, 0xFE35,
+	0xA160, 0xFE36, 0xA161, 0xFF5B, 0xA162, 0xFF5D, 0xA163, 0xFE37,
+	0xA164, 0xFE38, 0xA165, 0x3014, 0xA166, 0x3015, 0xA167, 0xFE39,
+	0xA168, 0xFE3A, 0xA169, 0x3010, 0xA16A, 0x3011, 0xA16B, 0xFE3B,
+	0xA16C, 0xFE3C, 0xA16D, 0x300A, 0xA16E, 0x300B, 0xA16F, 0xFE3D,
+	0xA170, 0xFE3E, 0xA171, 0x3008, 0xA172, 0x3009, 0xA173, 0xFE3F,
+	0xA174, 0xFE40, 0xA175, 0x300C, 0xA176, 0x300D, 0xA177, 0xFE41,
+	0xA178, 0xFE42, 0xA179, 0x300E, 0xA17A, 0x300F, 0xA17B, 0xFE43,
+	0xA17C, 0xFE44, 0xA17D, 0xFE59, 0xA17E, 0xFE5A, 0xA1A1, 0xFE5B,
+	0xA1A2, 0xFE5C, 0xA1A3, 0xFE5D, 0xA1A4, 0xFE5E, 0xA1A5, 0x2018,
+	0xA1A6, 0x2019, 0xA1A7, 0x201C, 0xA1A8, 0x201D, 0xA1A9, 0x301D,
+	0xA1AA, 0x301E, 0xA1AB, 0x2035, 0xA1AC, 0x2032, 0xA1AD, 0xFF03,
+	0xA1AE, 0xFF06, 0xA1AF, 0xFF0A, 0xA1B0, 0x203B, 0xA1B1, 0x00A7,
+	0xA1B2, 0x3003, 0xA1B3, 0x25CB, 0xA1B4, 0x25CF, 0xA1B5, 0x25B3,
+	0xA1B6, 0x25B2, 0xA1B7, 0x25CE, 0xA1B8, 0x2606, 0xA1B9, 0x2605,
+	0xA1BA, 0x25C7, 0xA1BB, 0x25C6, 0xA1BC, 0x25A1, 0xA1BD, 0x25A0,
+	0xA1BE, 0x25BD, 0xA1BF, 0x25BC, 0xA1C0, 0x32A3, 0xA1C1, 0x2105,
+	0xA1C2, 0x00AF, 0xA1C3, 0xFFE3, 0xA1C4, 0xFF3F, 0xA1C5, 0x02CD,
+	0xA1C6, 0xFE49, 0xA1C7, 0xFE4A, 0xA1C8, 0xFE4D, 0xA1C9, 0xFE4E,
+	0xA1CA, 0xFE4B, 0xA1CB, 0xFE4C, 0xA1CC, 0xFE5F, 0xA1CD, 0xFE60,
+	0xA1CE, 0xFE61, 0xA1CF, 0xFF0B, 0xA1D0, 0xFF0D, 0xA1D1, 0x00D7,
+	0xA1D2, 0x00F7, 0xA1D3, 0x00B1, 0xA1D4, 0x221A, 0xA1D5, 0xFF1C,
+	0xA1D6, 0xFF1E, 0xA1D7, 0xFF1D, 0xA1D8, 0x2266, 0xA1D9, 0x2267,
+	0xA1DA, 0x2260, 0xA1DB, 0x221E, 0xA1DC, 0x2252, 0xA1DD, 0x2261,
+	0xA1DE, 0xFE62, 0xA1DF, 0xFE63, 0xA1E0, 0xFE64, 0xA1E1, 0xFE65,
+	0xA1E2, 0xFE66, 0xA1E3, 0xFF5E, 0xA1E4, 0x2229, 0xA1E5, 0x222A,
+	0xA1E6, 0x22A5, 0xA1E7, 0x2220, 0xA1E8, 0x221F, 0xA1E9, 0x22BF,
+	0xA1EA, 0x33D2, 0xA1EB, 0x33D1, 0xA1EC, 0x222B, 0xA1ED, 0x222E,
+	0xA1EE, 0x2235, 0xA1EF, 0x2234, 0xA1F0, 0x2640, 0xA1F1, 0x2642,
+	0xA1F2, 0x2295, 0xA1F3, 0x2299, 0xA1F4, 0x2191, 0xA1F5, 0x2193,
+	0xA1F6, 0x2190, 0xA1F7, 0x2192, 0xA1F8, 0x2196, 0xA1F9, 0x2197,
+	0xA1FA, 0x2199, 0xA1FB, 0x2198, 0xA1FC, 0x2225, 0xA1FD, 0x2223,
+	0xA1FE, 0xFF0F, 0xA240, 0xFF3C, 0xA241, 0x2215, 0xA242, 0xFE68,
+	0xA243, 0xFF04, 0xA244, 0xFFE5, 0xA245, 0x3012, 0xA246, 0xFFE0,
+	0xA247, 0xFFE1, 0xA248, 0xFF05, 0xA249, 0xFF20, 0xA24A, 0x2103,
+	0xA24B, 0x2109, 0xA24C, 0xFE69, 0xA24D, 0xFE6A, 0xA24E, 0xFE6B,
+	0xA24F, 0x33D5, 0xA250, 0x339C, 0xA251, 0x339D, 0xA252, 0x339E,
+	0xA253, 0x33CE, 0xA254, 0x33A1, 0xA255, 0x338E, 0xA256, 0x338F,
+	0xA257, 0x33C4, 0xA258, 0x00B0, 0xA259, 0x5159, 0xA25A, 0x515B,
+	0xA25B, 0x515E, 0xA25C, 0x515D, 0xA25D, 0x5161, 0xA25E, 0x5163,
+	0xA25F, 0x55E7, 0xA260, 0x74E9, 0xA261, 0x7CCE, 0xA262, 0x2581,
+	0xA263, 0x2582, 0xA264, 0x2583, 0xA265, 0x2584, 0xA266, 0x2585,
+	0xA267, 0x2586, 0xA268, 0x2587, 0xA269, 0x2588, 0xA26A, 0x258F,
+	0xA26B, 0x258E, 0xA26C, 0x258D, 0xA26D, 0x258C, 0xA26E, 0x258B,
+	0xA26F, 0x258A, 0xA270, 0x2589, 0xA271, 0x253C, 0xA272, 0x2534,
+	0xA273, 0x252C, 0xA274, 0x2524, 0xA275, 0x251C, 0xA276, 0x2594,
+	0xA277, 0x2500, 0xA278, 0x2502, 0xA279, 0x2595, 0xA27A, 0x250C,
+	0xA27B, 0x2510, 0xA27C, 0x2514, 0xA27D, 0x2518, 0xA27E, 0x256D,
+	0xA2A1, 0x256E, 0xA2A2, 0x2570, 0xA2A3, 0x256F, 0xA2A4, 0x2550,
+	0xA2A5, 0x255E, 0xA2A6, 0x256A, 0xA2A7, 0x2561, 0xA2A8, 0x25E2,
+	0xA2A9, 0x25E3, 0xA2AA, 0x25E5, 0xA2AB, 0x25E4, 0xA2AC, 0x2571,
+	0xA2AD, 0x2572, 0xA2AE, 0x2573, 0xA2AF, 0xFF10, 0xA2B0, 0xFF11,
+	0xA2B1, 0xFF12, 0xA2B2, 0xFF13, 0xA2B3, 0xFF14, 0xA2B4, 0xFF15,
+	0xA2B5, 0xFF16, 0xA2B6, 0xFF17, 0xA2B7, 0xFF18, 0xA2B8, 0xFF19,
+	0xA2B9, 0x2160, 0xA2BA, 0x2161, 0xA2BB, 0x2162, 0xA2BC, 0x2163,
+	0xA2BD, 0x2164, 0xA2BE, 0x2165, 0xA2BF, 0x2166, 0xA2C0, 0x2167,
+	0xA2C1, 0x2168, 0xA2C2, 0x2169, 0xA2C3, 0x3021, 0xA2C4, 0x3022,
+	0xA2C5, 0x3023, 0xA2C6, 0x3024, 0xA2C7, 0x3025, 0xA2C8, 0x3026,
+	0xA2C9, 0x3027, 0xA2CA, 0x3028, 0xA2CB, 0x3029, 0xA2CC, 0x5341,
+	0xA2CD, 0x5344, 0xA2CE, 0x5345, 0xA2CF, 0xFF21, 0xA2D0, 0xFF22,
+	0xA2D1, 0xFF23, 0xA2D2, 0xFF24, 0xA2D3, 0xFF25, 0xA2D4, 0xFF26,
+	0xA2D5, 0xFF27, 0xA2D6, 0xFF28, 0xA2D7, 0xFF29, 0xA2D8, 0xFF2A,
+	0xA2D9, 0xFF2B, 0xA2DA, 0xFF2C, 0xA2DB, 0xFF2D, 0xA2DC, 0xFF2E,
+	0xA2DD, 0xFF2F, 0xA2DE, 0xFF30, 0xA2DF, 0xFF31, 0xA2E0, 0xFF32,
+	0xA2E1, 0xFF33, 0xA2E2, 0xFF34, 0xA2E3, 0xFF35, 0xA2E4, 0xFF36,
+	0xA2E5, 0xFF37, 0xA2E6, 0xFF38, 0xA2E7, 0xFF39, 0xA2E8, 0xFF3A,
+	0xA2E9, 0xFF41, 0xA2EA, 0xFF42, 0xA2EB, 0xFF43, 0xA2EC, 0xFF44,
+	0xA2ED, 0xFF45, 0xA2EE, 0xFF46, 0xA2EF, 0xFF47, 0xA2F0, 0xFF48,
+	0xA2F1, 0xFF49, 0xA2F2, 0xFF4A, 0xA2F3, 0xFF4B, 0xA2F4, 0xFF4C,
+	0xA2F5, 0xFF4D, 0xA2F6, 0xFF4E, 0xA2F7, 0xFF4F, 0xA2F8, 0xFF50,
+	0xA2F9, 0xFF51, 0xA2FA, 0xFF52, 0xA2FB, 0xFF53, 0xA2FC, 0xFF54,
+	0xA2FD, 0xFF55, 0xA2FE, 0xFF56, 0xA340, 0xFF57, 0xA341, 0xFF58,
+	0xA342, 0xFF59, 0xA343, 0xFF5A, 0xA344, 0x0391, 0xA345, 0x0392,
+	0xA346, 0x0393, 0xA347, 0x0394, 0xA348, 0x0395, 0xA349, 0x0396,
+	0xA34A, 0x0397, 0xA34B, 0x0398, 0xA34C, 0x0399, 0xA34D, 0x039A,
+	0xA34E, 0x039B, 0xA34F, 0x039C, 0xA350, 0x039D, 0xA351, 0x039E,
+	0xA352, 0x039F, 0xA353, 0x03A0, 0xA354, 0x03A1, 0xA355, 0x03A3,
+	0xA356, 0x03A4, 0xA357, 0x03A5, 0xA358, 0x03A6, 0xA359, 0x03A7,
+	0xA35A, 0x03A8, 0xA35B, 0x03A9, 0xA35C, 0x03B1, 0xA35D, 0x03B2,
+	0xA35E, 0x03B3, 0xA35F, 0x03B4, 0xA360, 0x03B5, 0xA361, 0x03B6,
+	0xA362, 0x03B7, 0xA363, 0x03B8, 0xA364, 0x03B9, 0xA365, 0x03BA,
+	0xA366, 0x03BB, 0xA367, 0x03BC, 0xA368, 0x03BD, 0xA369, 0x03BE,
+	0xA36A, 0x03BF, 0xA36B, 0x03C0, 0xA36C, 0x03C1, 0xA36D, 0x03C3,
+	0xA36E, 0x03C4, 0xA36F, 0x03C5, 0xA370, 0x03C6, 0xA371, 0x03C7,
+	0xA372, 0x03C8, 0xA373, 0x03C9, 0xA374, 0x3105, 0xA375, 0x3106,
+	0xA376, 0x3107, 0xA377, 0x3108, 0xA378, 0x3109, 0xA379, 0x310A,
+	0xA37A, 0x310B, 0xA37B, 0x310C, 0xA37C, 0x310D, 0xA37D, 0x310E,
+	0xA37E, 0x310F, 0xA3A1, 0x3110, 0xA3A2, 0x3111, 0xA3A3, 0x3112,
+	0xA3A4, 0x3113, 0xA3A5, 0x3114, 0xA3A6, 0x3115, 0xA3A7, 0x3116,
+	0xA3A8, 0x3117, 0xA3A9, 0x3118, 0xA3AA, 0x3119, 0xA3AB, 0x311A,
+	0xA3AC, 0x311B, 0xA3AD, 0x311C, 0xA3AE, 0x311D, 0xA3AF, 0x311E,
+	0xA3B0, 0x311F, 0xA3B1, 0x3120, 0xA3B2, 0x3121, 0xA3B3, 0x3122,
+	0xA3B4, 0x3123, 0xA3B5, 0x3124, 0xA3B6, 0x3125, 0xA3B7, 0x3126,
+	0xA3B8, 0x3127, 0xA3B9, 0x3128, 0xA3BA, 0x3129, 0xA3BB, 0x02D9,
+	0xA3BC, 0x02C9, 0xA3BD, 0x02CA, 0xA3BE, 0x02C7, 0xA3BF, 0x02CB,
+	0xA3E1, 0x20AC, 0xA440, 0x4E00, 0xA441, 0x4E59, 0xA442, 0x4E01,
+	0xA443, 0x4E03, 0xA444, 0x4E43, 0xA445, 0x4E5D, 0xA446, 0x4E86,
+	0xA447, 0x4E8C, 0xA448, 0x4EBA, 0xA449, 0x513F, 0xA44A, 0x5165,
+	0xA44B, 0x516B, 0xA44C, 0x51E0, 0xA44D, 0x5200, 0xA44E, 0x5201,
+	0xA44F, 0x529B, 0xA450, 0x5315, 0xA451, 0x5341, 0xA452, 0x535C,
+	0xA453, 0x53C8, 0xA454, 0x4E09, 0xA455, 0x4E0B, 0xA456, 0x4E08,
+	0xA457, 0x4E0A, 0xA458, 0x4E2B, 0xA459, 0x4E38, 0xA45A, 0x51E1,
+	0xA45B, 0x4E45, 0xA45C, 0x4E48, 0xA45D, 0x4E5F, 0xA45E, 0x4E5E,
+	0xA45F, 0x4E8E, 0xA460, 0x4EA1, 0xA461, 0x5140, 0xA462, 0x5203,
+	0xA463, 0x52FA, 0xA464, 0x5343, 0xA465, 0x53C9, 0xA466, 0x53E3,
+	0xA467, 0x571F, 0xA468, 0x58EB, 0xA469, 0x5915, 0xA46A, 0x5927,
+	0xA46B, 0x5973, 0xA46C, 0x5B50, 0xA46D, 0x5B51, 0xA46E, 0x5B53,
+	0xA46F, 0x5BF8, 0xA470, 0x5C0F, 0xA471, 0x5C22, 0xA472, 0x5C38,
+	0xA473, 0x5C71, 0xA474, 0x5DDD, 0xA475, 0x5DE5, 0xA476, 0x5DF1,
+	0xA477, 0x5DF2, 0xA478, 0x5DF3, 0xA479, 0x5DFE, 0xA47A, 0x5E72,
+	0xA47B, 0x5EFE, 0xA47C, 0x5F0B, 0xA47D, 0x5F13, 0xA47E, 0x624D,
+	0xA4A1, 0x4E11, 0xA4A2, 0x4E10, 0xA4A3, 0x4E0D, 0xA4A4, 0x4E2D,
+	0xA4A5, 0x4E30, 0xA4A6, 0x4E39, 0xA4A7, 0x4E4B, 0xA4A8, 0x5C39,
+	0xA4A9, 0x4E88, 0xA4AA, 0x4E91, 0xA4AB, 0x4E95, 0xA4AC, 0x4E92,
+	0xA4AD, 0x4E94, 0xA4AE, 0x4EA2, 0xA4AF, 0x4EC1, 0xA4B0, 0x4EC0,
+	0xA4B1, 0x4EC3, 0xA4B2, 0x4EC6, 0xA4B3, 0x4EC7, 0xA4B4, 0x4ECD,
+	0xA4B5, 0x4ECA, 0xA4B6, 0x4ECB, 0xA4B7, 0x4EC4, 0xA4B8, 0x5143,
+	0xA4B9, 0x5141, 0xA4BA, 0x5167, 0xA4BB, 0x516D, 0xA4BC, 0x516E,
+	0xA4BD, 0x516C, 0xA4BE, 0x5197, 0xA4BF, 0x51F6, 0xA4C0, 0x5206,
+	0xA4C1, 0x5207, 0xA4C2, 0x5208, 0xA4C3, 0x52FB, 0xA4C4, 0x52FE,
+	0xA4C5, 0x52FF, 0xA4C6, 0x5316, 0xA4C7, 0x5339, 0xA4C8, 0x5348,
+	0xA4C9, 0x5347, 0xA4CA, 0x5345, 0xA4CB, 0x535E, 0xA4CC, 0x5384,
+	0xA4CD, 0x53CB, 0xA4CE, 0x53CA, 0xA4CF, 0x53CD, 0xA4D0, 0x58EC,
+	0xA4D1, 0x5929, 0xA4D2, 0x592B, 0xA4D3, 0x592A, 0xA4D4, 0x592D,
+	0xA4D5, 0x5B54, 0xA4D6, 0x5C11, 0xA4D7, 0x5C24, 0xA4D8, 0x5C3A,
+	0xA4D9, 0x5C6F, 0xA4DA, 0x5DF4, 0xA4DB, 0x5E7B, 0xA4DC, 0x5EFF,
+	0xA4DD, 0x5F14, 0xA4DE, 0x5F15, 0xA4DF, 0x5FC3, 0xA4E0, 0x6208,
+	0xA4E1, 0x6236, 0xA4E2, 0x624B, 0xA4E3, 0x624E, 0xA4E4, 0x652F,
+	0xA4E5, 0x6587, 0xA4E6, 0x6597, 0xA4E7, 0x65A4, 0xA4E8, 0x65B9,
+	0xA4E9, 0x65E5, 0xA4EA, 0x66F0, 0xA4EB, 0x6708, 0xA4EC, 0x6728,
+	0xA4ED, 0x6B20, 0xA4EE, 0x6B62, 0xA4EF, 0x6B79, 0xA4F0, 0x6BCB,
+	0xA4F1, 0x6BD4, 0xA4F2, 0x6BDB, 0xA4F3, 0x6C0F, 0xA4F4, 0x6C34,
+	0xA4F5, 0x706B, 0xA4F6, 0x722A, 0xA4F7, 0x7236, 0xA4F8, 0x723B,
+	0xA4F9, 0x7247, 0xA4FA, 0x7259, 0xA4FB, 0x725B, 0xA4FC, 0x72AC,
+	0xA4FD, 0x738B, 0xA4FE, 0x4E19, 0xA540, 0x4E16, 0xA541, 0x4E15,
+	0xA542, 0x4E14, 0xA543, 0x4E18, 0xA544, 0x4E3B, 0xA545, 0x4E4D,
+	0xA546, 0x4E4F, 0xA547, 0x4E4E, 0xA548, 0x4EE5, 0xA549, 0x4ED8,
+	0xA54A, 0x4ED4, 0xA54B, 0x4ED5, 0xA54C, 0x4ED6, 0xA54D, 0x4ED7,
+	0xA54E, 0x4EE3, 0xA54F, 0x4EE4, 0xA550, 0x4ED9, 0xA551, 0x4EDE,
+	0xA552, 0x5145, 0xA553, 0x5144, 0xA554, 0x5189, 0xA555, 0x518A,
+	0xA556, 0x51AC, 0xA557, 0x51F9, 0xA558, 0x51FA, 0xA559, 0x51F8,
+	0xA55A, 0x520A, 0xA55B, 0x52A0, 0xA55C, 0x529F, 0xA55D, 0x5305,
+	0xA55E, 0x5306, 0xA55F, 0x5317, 0xA560, 0x531D, 0xA561, 0x4EDF,
+	0xA562, 0x534A, 0xA563, 0x5349, 0xA564, 0x5361, 0xA565, 0x5360,
+	0xA566, 0x536F, 0xA567, 0x536E, 0xA568, 0x53BB, 0xA569, 0x53EF,
+	0xA56A, 0x53E4, 0xA56B, 0x53F3, 0xA56C, 0x53EC, 0xA56D, 0x53EE,
+	0xA56E, 0x53E9, 0xA56F, 0x53E8, 0xA570, 0x53FC, 0xA571, 0x53F8,
+	0xA572, 0x53F5, 0xA573, 0x53EB, 0xA574, 0x53E6, 0xA575, 0x53EA,
+	0xA576, 0x53F2, 0xA577, 0x53F1, 0xA578, 0x53F0, 0xA579, 0x53E5,
+	0xA57A, 0x53ED, 0xA57B, 0x53FB, 0xA57C, 0x56DB, 0xA57D, 0x56DA,
+	0xA57E, 0x5916, 0xA5A1, 0x592E, 0xA5A2, 0x5931, 0xA5A3, 0x5974,
+	0xA5A4, 0x5976, 0xA5A5, 0x5B55, 0xA5A6, 0x5B83, 0xA5A7, 0x5C3C,
+	0xA5A8, 0x5DE8, 0xA5A9, 0x5DE7, 0xA5AA, 0x5DE6, 0xA5AB, 0x5E02,
+	0xA5AC, 0x5E03, 0xA5AD, 0x5E73, 0xA5AE, 0x5E7C, 0xA5AF, 0x5F01,
+	0xA5B0, 0x5F18, 0xA5B1, 0x5F17, 0xA5B2, 0x5FC5, 0xA5B3, 0x620A,
+	0xA5B4, 0x6253, 0xA5B5, 0x6254, 0xA5B6, 0x6252, 0xA5B7, 0x6251,
+	0xA5B8, 0x65A5, 0xA5B9, 0x65E6, 0xA5BA, 0x672E, 0xA5BB, 0x672C,
+	0xA5BC, 0x672A, 0xA5BD, 0x672B, 0xA5BE, 0x672D, 0xA5BF, 0x6B63,
+	0xA5C0, 0x6BCD, 0xA5C1, 0x6C11, 0xA5C2, 0x6C10, 0xA5C3, 0x6C38,
+	0xA5C4, 0x6C41, 0xA5C5, 0x6C40, 0xA5C6, 0x6C3E, 0xA5C7, 0x72AF,
+	0xA5C8, 0x7384, 0xA5C9, 0x7389, 0xA5CA, 0x74DC, 0xA5CB, 0x74E6,
+	0xA5CC, 0x7518, 0xA5CD, 0x751F, 0xA5CE, 0x7528, 0xA5CF, 0x7529,
+	0xA5D0, 0x7530, 0xA5D1, 0x7531, 0xA5D2, 0x7532, 0xA5D3, 0x7533,
+	0xA5D4, 0x758B, 0xA5D5, 0x767D, 0xA5D6, 0x76AE, 0xA5D7, 0x76BF,
+	0xA5D8, 0x76EE, 0xA5D9, 0x77DB, 0xA5DA, 0x77E2, 0xA5DB, 0x77F3,
+	0xA5DC, 0x793A, 0xA5DD, 0x79BE, 0xA5DE, 0x7A74, 0xA5DF, 0x7ACB,
+	0xA5E0, 0x4E1E, 0xA5E1, 0x4E1F, 0xA5E2, 0x4E52, 0xA5E3, 0x4E53,
+	0xA5E4, 0x4E69, 0xA5E5, 0x4E99, 0xA5E6, 0x4EA4, 0xA5E7, 0x4EA6,
+	0xA5E8, 0x4EA5, 0xA5E9, 0x4EFF, 0xA5EA, 0x4F09, 0xA5EB, 0x4F19,
+	0xA5EC, 0x4F0A, 0xA5ED, 0x4F15, 0xA5EE, 0x4F0D, 0xA5EF, 0x4F10,
+	0xA5F0, 0x4F11, 0xA5F1, 0x4F0F, 0xA5F2, 0x4EF2, 0xA5F3, 0x4EF6,
+	0xA5F4, 0x4EFB, 0xA5F5, 0x4EF0, 0xA5F6, 0x4EF3, 0xA5F7, 0x4EFD,
+	0xA5F8, 0x4F01, 0xA5F9, 0x4F0B, 0xA5FA, 0x5149, 0xA5FB, 0x5147,
+	0xA5FC, 0x5146, 0xA5FD, 0x5148, 0xA5FE, 0x5168, 0xA640, 0x5171,
+	0xA641, 0x518D, 0xA642, 0x51B0, 0xA643, 0x5217, 0xA644, 0x5211,
+	0xA645, 0x5212, 0xA646, 0x520E, 0xA647, 0x5216, 0xA648, 0x52A3,
+	0xA649, 0x5308, 0xA64A, 0x5321, 0xA64B, 0x5320, 0xA64C, 0x5370,
+	0xA64D, 0x5371, 0xA64E, 0x5409, 0xA64F, 0x540F, 0xA650, 0x540C,
+	0xA651, 0x540A, 0xA652, 0x5410, 0xA653, 0x5401, 0xA654, 0x540B,
+	0xA655, 0x5404, 0xA656, 0x5411, 0xA657, 0x540D, 0xA658, 0x5408,
+	0xA659, 0x5403, 0xA65A, 0x540E, 0xA65B, 0x5406, 0xA65C, 0x5412,
+	0xA65D, 0x56E0, 0xA65E, 0x56DE, 0xA65F, 0x56DD, 0xA660, 0x5733,
+	0xA661, 0x5730, 0xA662, 0x5728, 0xA663, 0x572D, 0xA664, 0x572C,
+	0xA665, 0x572F, 0xA666, 0x5729, 0xA667, 0x5919, 0xA668, 0x591A,
+	0xA669, 0x5937, 0xA66A, 0x5938, 0xA66B, 0x5984, 0xA66C, 0x5978,
+	0xA66D, 0x5983, 0xA66E, 0x597D, 0xA66F, 0x5979, 0xA670, 0x5982,
+	0xA671, 0x5981, 0xA672, 0x5B57, 0xA673, 0x5B58, 0xA674, 0x5B87,
+	0xA675, 0x5B88, 0xA676, 0x5B85, 0xA677, 0x5B89, 0xA678, 0x5BFA,
+	0xA679, 0x5C16, 0xA67A, 0x5C79, 0xA67B, 0x5DDE, 0xA67C, 0x5E06,
+	0xA67D, 0x5E76, 0xA67E, 0x5E74, 0xA6A1, 0x5F0F, 0xA6A2, 0x5F1B,
+	0xA6A3, 0x5FD9, 0xA6A4, 0x5FD6, 0xA6A5, 0x620E, 0xA6A6, 0x620C,
+	0xA6A7, 0x620D, 0xA6A8, 0x6210, 0xA6A9, 0x6263, 0xA6AA, 0x625B,
+	0xA6AB, 0x6258, 0xA6AC, 0x6536, 0xA6AD, 0x65E9, 0xA6AE, 0x65E8,
+	0xA6AF, 0x65EC, 0xA6B0, 0x65ED, 0xA6B1, 0x66F2, 0xA6B2, 0x66F3,
+	0xA6B3, 0x6709, 0xA6B4, 0x673D, 0xA6B5, 0x6734, 0xA6B6, 0x6731,
+	0xA6B7, 0x6735, 0xA6B8, 0x6B21, 0xA6B9, 0x6B64, 0xA6BA, 0x6B7B,
+	0xA6BB, 0x6C16, 0xA6BC, 0x6C5D, 0xA6BD, 0x6C57, 0xA6BE, 0x6C59,
+	0xA6BF, 0x6C5F, 0xA6C0, 0x6C60, 0xA6C1, 0x6C50, 0xA6C2, 0x6C55,
+	0xA6C3, 0x6C61, 0xA6C4, 0x6C5B, 0xA6C5, 0x6C4D, 0xA6C6, 0x6C4E,
+	0xA6C7, 0x7070, 0xA6C8, 0x725F, 0xA6C9, 0x725D, 0xA6CA, 0x767E,
+	0xA6CB, 0x7AF9, 0xA6CC, 0x7C73, 0xA6CD, 0x7CF8, 0xA6CE, 0x7F36,
+	0xA6CF, 0x7F8A, 0xA6D0, 0x7FBD, 0xA6D1, 0x8001, 0xA6D2, 0x8003,
+	0xA6D3, 0x800C, 0xA6D4, 0x8012, 0xA6D5, 0x8033, 0xA6D6, 0x807F,
+	0xA6D7, 0x8089, 0xA6D8, 0x808B, 0xA6D9, 0x808C, 0xA6DA, 0x81E3,
+	0xA6DB, 0x81EA, 0xA6DC, 0x81F3, 0xA6DD, 0x81FC, 0xA6DE, 0x820C,
+	0xA6DF, 0x821B, 0xA6E0, 0x821F, 0xA6E1, 0x826E, 0xA6E2, 0x8272,
+	0xA6E3, 0x827E, 0xA6E4, 0x866B, 0xA6E5, 0x8840, 0xA6E6, 0x884C,
+	0xA6E7, 0x8863, 0xA6E8, 0x897F, 0xA6E9, 0x9621, 0xA6EA, 0x4E32,
+	0xA6EB, 0x4EA8, 0xA6EC, 0x4F4D, 0xA6ED, 0x4F4F, 0xA6EE, 0x4F47,
+	0xA6EF, 0x4F57, 0xA6F0, 0x4F5E, 0xA6F1, 0x4F34, 0xA6F2, 0x4F5B,
+	0xA6F3, 0x4F55, 0xA6F4, 0x4F30, 0xA6F5, 0x4F50, 0xA6F6, 0x4F51,
+	0xA6F7, 0x4F3D, 0xA6F8, 0x4F3A, 0xA6F9, 0x4F38, 0xA6FA, 0x4F43,
+	0xA6FB, 0x4F54, 0xA6FC, 0x4F3C, 0xA6FD, 0x4F46, 0xA6FE, 0x4F63,
+	0xA740, 0x4F5C, 0xA741, 0x4F60, 0xA742, 0x4F2F, 0xA743, 0x4F4E,
+	0xA744, 0x4F36, 0xA745, 0x4F59, 0xA746, 0x4F5D, 0xA747, 0x4F48,
+	0xA748, 0x4F5A, 0xA749, 0x514C, 0xA74A, 0x514B, 0xA74B, 0x514D,
+	0xA74C, 0x5175, 0xA74D, 0x51B6, 0xA74E, 0x51B7, 0xA74F, 0x5225,
+	0xA750, 0x5224, 0xA751, 0x5229, 0xA752, 0x522A, 0xA753, 0x5228,
+	0xA754, 0x52AB, 0xA755, 0x52A9, 0xA756, 0x52AA, 0xA757, 0x52AC,
+	0xA758, 0x5323, 0xA759, 0x5373, 0xA75A, 0x5375, 0xA75B, 0x541D,
+	0xA75C, 0x542D, 0xA75D, 0x541E, 0xA75E, 0x543E, 0xA75F, 0x5426,
+	0xA760, 0x544E, 0xA761, 0x5427, 0xA762, 0x5446, 0xA763, 0x5443,
+	0xA764, 0x5433, 0xA765, 0x5448, 0xA766, 0x5442, 0xA767, 0x541B,
+	0xA768, 0x5429, 0xA769, 0x544A, 0xA76A, 0x5439, 0xA76B, 0x543B,
+	0xA76C, 0x5438, 0xA76D, 0x542E, 0xA76E, 0x5435, 0xA76F, 0x5436,
+	0xA770, 0x5420, 0xA771, 0x543C, 0xA772, 0x5440, 0xA773, 0x5431,
+	0xA774, 0x542B, 0xA775, 0x541F, 0xA776, 0x542C, 0xA777, 0x56EA,
+	0xA778, 0x56F0, 0xA779, 0x56E4, 0xA77A, 0x56EB, 0xA77B, 0x574A,
+	0xA77C, 0x5751, 0xA77D, 0x5740, 0xA77E, 0x574D, 0xA7A1, 0x5747,
+	0xA7A2, 0x574E, 0xA7A3, 0x573E, 0xA7A4, 0x5750, 0xA7A5, 0x574F,
+	0xA7A6, 0x573B, 0xA7A7, 0x58EF, 0xA7A8, 0x593E, 0xA7A9, 0x599D,
+	0xA7AA, 0x5992, 0xA7AB, 0x59A8, 0xA7AC, 0x599E, 0xA7AD, 0x59A3,
+	0xA7AE, 0x5999, 0xA7AF, 0x5996, 0xA7B0, 0x598D, 0xA7B1, 0x59A4,
+	0xA7B2, 0x5993, 0xA7B3, 0x598A, 0xA7B4, 0x59A5, 0xA7B5, 0x5B5D,
+	0xA7B6, 0x5B5C, 0xA7B7, 0x5B5A, 0xA7B8, 0x5B5B, 0xA7B9, 0x5B8C,
+	0xA7BA, 0x5B8B, 0xA7BB, 0x5B8F, 0xA7BC, 0x5C2C, 0xA7BD, 0x5C40,
+	0xA7BE, 0x5C41, 0xA7BF, 0x5C3F, 0xA7C0, 0x5C3E, 0xA7C1, 0x5C90,
+	0xA7C2, 0x5C91, 0xA7C3, 0x5C94, 0xA7C4, 0x5C8C, 0xA7C5, 0x5DEB,
+	0xA7C6, 0x5E0C, 0xA7C7, 0x5E8F, 0xA7C8, 0x5E87, 0xA7C9, 0x5E8A,
+	0xA7CA, 0x5EF7, 0xA7CB, 0x5F04, 0xA7CC, 0x5F1F, 0xA7CD, 0x5F64,
+	0xA7CE, 0x5F62, 0xA7CF, 0x5F77, 0xA7D0, 0x5F79, 0xA7D1, 0x5FD8,
+	0xA7D2, 0x5FCC, 0xA7D3, 0x5FD7, 0xA7D4, 0x5FCD, 0xA7D5, 0x5FF1,
+	0xA7D6, 0x5FEB, 0xA7D7, 0x5FF8, 0xA7D8, 0x5FEA, 0xA7D9, 0x6212,
+	0xA7DA, 0x6211, 0xA7DB, 0x6284, 0xA7DC, 0x6297, 0xA7DD, 0x6296,
+	0xA7DE, 0x6280, 0xA7DF, 0x6276, 0xA7E0, 0x6289, 0xA7E1, 0x626D,
+	0xA7E2, 0x628A, 0xA7E3, 0x627C, 0xA7E4, 0x627E, 0xA7E5, 0x6279,
+	0xA7E6, 0x6273, 0xA7E7, 0x6292, 0xA7E8, 0x626F, 0xA7E9, 0x6298,
+	0xA7EA, 0x626E, 0xA7EB, 0x6295, 0xA7EC, 0x6293, 0xA7ED, 0x6291,
+	0xA7EE, 0x6286, 0xA7EF, 0x6539, 0xA7F0, 0x653B, 0xA7F1, 0x6538,
+	0xA7F2, 0x65F1, 0xA7F3, 0x66F4, 0xA7F4, 0x675F, 0xA7F5, 0x674E,
+	0xA7F6, 0x674F, 0xA7F7, 0x6750, 0xA7F8, 0x6751, 0xA7F9, 0x675C,
+	0xA7FA, 0x6756, 0xA7FB, 0x675E, 0xA7FC, 0x6749, 0xA7FD, 0x6746,
+	0xA7FE, 0x6760, 0xA840, 0x6753, 0xA841, 0x6757, 0xA842, 0x6B65,
+	0xA843, 0x6BCF, 0xA844, 0x6C42, 0xA845, 0x6C5E, 0xA846, 0x6C99,
+	0xA847, 0x6C81, 0xA848, 0x6C88, 0xA849, 0x6C89, 0xA84A, 0x6C85,
+	0xA84B, 0x6C9B, 0xA84C, 0x6C6A, 0xA84D, 0x6C7A, 0xA84E, 0x6C90,
+	0xA84F, 0x6C70, 0xA850, 0x6C8C, 0xA851, 0x6C68, 0xA852, 0x6C96,
+	0xA853, 0x6C92, 0xA854, 0x6C7D, 0xA855, 0x6C83, 0xA856, 0x6C72,
+	0xA857, 0x6C7E, 0xA858, 0x6C74, 0xA859, 0x6C86, 0xA85A, 0x6C76,
+	0xA85B, 0x6C8D, 0xA85C, 0x6C94, 0xA85D, 0x6C98, 0xA85E, 0x6C82,
+	0xA85F, 0x7076, 0xA860, 0x707C, 0xA861, 0x707D, 0xA862, 0x7078,
+	0xA863, 0x7262, 0xA864, 0x7261, 0xA865, 0x7260, 0xA866, 0x72C4,
+	0xA867, 0x72C2, 0xA868, 0x7396, 0xA869, 0x752C, 0xA86A, 0x752B,
+	0xA86B, 0x7537, 0xA86C, 0x7538, 0xA86D, 0x7682, 0xA86E, 0x76EF,
+	0xA86F, 0x77E3, 0xA870, 0x79C1, 0xA871, 0x79C0, 0xA872, 0x79BF,
+	0xA873, 0x7A76, 0xA874, 0x7CFB, 0xA875, 0x7F55, 0xA876, 0x8096,
+	0xA877, 0x8093, 0xA878, 0x809D, 0xA879, 0x8098, 0xA87A, 0x809B,
+	0xA87B, 0x809A, 0xA87C, 0x80B2, 0xA87D, 0x826F, 0xA87E, 0x8292,
+	0xA8A1, 0x828B, 0xA8A2, 0x828D, 0xA8A3, 0x898B, 0xA8A4, 0x89D2,
+	0xA8A5, 0x8A00, 0xA8A6, 0x8C37, 0xA8A7, 0x8C46, 0xA8A8, 0x8C55,
+	0xA8A9, 0x8C9D, 0xA8AA, 0x8D64, 0xA8AB, 0x8D70, 0xA8AC, 0x8DB3,
+	0xA8AD, 0x8EAB, 0xA8AE, 0x8ECA, 0xA8AF, 0x8F9B, 0xA8B0, 0x8FB0,
+	0xA8B1, 0x8FC2, 0xA8B2, 0x8FC6, 0xA8B3, 0x8FC5, 0xA8B4, 0x8FC4,
+	0xA8B5, 0x5DE1, 0xA8B6, 0x9091, 0xA8B7, 0x90A2, 0xA8B8, 0x90AA,
+	0xA8B9, 0x90A6, 0xA8BA, 0x90A3, 0xA8BB, 0x9149, 0xA8BC, 0x91C6,
+	0xA8BD, 0x91CC, 0xA8BE, 0x9632, 0xA8BF, 0x962E, 0xA8C0, 0x9631,
+	0xA8C1, 0x962A, 0xA8C2, 0x962C, 0xA8C3, 0x4E26, 0xA8C4, 0x4E56,
+	0xA8C5, 0x4E73, 0xA8C6, 0x4E8B, 0xA8C7, 0x4E9B, 0xA8C8, 0x4E9E,
+	0xA8C9, 0x4EAB, 0xA8CA, 0x4EAC, 0xA8CB, 0x4F6F, 0xA8CC, 0x4F9D,
+	0xA8CD, 0x4F8D, 0xA8CE, 0x4F73, 0xA8CF, 0x4F7F, 0xA8D0, 0x4F6C,
+	0xA8D1, 0x4F9B, 0xA8D2, 0x4F8B, 0xA8D3, 0x4F86, 0xA8D4, 0x4F83,
+	0xA8D5, 0x4F70, 0xA8D6, 0x4F75, 0xA8D7, 0x4F88, 0xA8D8, 0x4F69,
+	0xA8D9, 0x4F7B, 0xA8DA, 0x4F96, 0xA8DB, 0x4F7E, 0xA8DC, 0x4F8F,
+	0xA8DD, 0x4F91, 0xA8DE, 0x4F7A, 0xA8DF, 0x5154, 0xA8E0, 0x5152,
+	0xA8E1, 0x5155, 0xA8E2, 0x5169, 0xA8E3, 0x5177, 0xA8E4, 0x5176,
+	0xA8E5, 0x5178, 0xA8E6, 0x51BD, 0xA8E7, 0x51FD, 0xA8E8, 0x523B,
+	0xA8E9, 0x5238, 0xA8EA, 0x5237, 0xA8EB, 0x523A, 0xA8EC, 0x5230,
+	0xA8ED, 0x522E, 0xA8EE, 0x5236, 0xA8EF, 0x5241, 0xA8F0, 0x52BE,
+	0xA8F1, 0x52BB, 0xA8F2, 0x5352, 0xA8F3, 0x5354, 0xA8F4, 0x5353,
+	0xA8F5, 0x5351, 0xA8F6, 0x5366, 0xA8F7, 0x5377, 0xA8F8, 0x5378,
+	0xA8F9, 0x5379, 0xA8FA, 0x53D6, 0xA8FB, 0x53D4, 0xA8FC, 0x53D7,
+	0xA8FD, 0x5473, 0xA8FE, 0x5475, 0xA940, 0x5496, 0xA941, 0x5478,
+	0xA942, 0x5495, 0xA943, 0x5480, 0xA944, 0x547B, 0xA945, 0x5477,
+	0xA946, 0x5484, 0xA947, 0x5492, 0xA948, 0x5486, 0xA949, 0x547C,
+	0xA94A, 0x5490, 0xA94B, 0x5471, 0xA94C, 0x5476, 0xA94D, 0x548C,
+	0xA94E, 0x549A, 0xA94F, 0x5462, 0xA950, 0x5468, 0xA951, 0x548B,
+	0xA952, 0x547D, 0xA953, 0x548E, 0xA954, 0x56FA, 0xA955, 0x5783,
+	0xA956, 0x5777, 0xA957, 0x576A, 0xA958, 0x5769, 0xA959, 0x5761,
+	0xA95A, 0x5766, 0xA95B, 0x5764, 0xA95C, 0x577C, 0xA95D, 0x591C,
+	0xA95E, 0x5949, 0xA95F, 0x5947, 0xA960, 0x5948, 0xA961, 0x5944,
+	0xA962, 0x5954, 0xA963, 0x59BE, 0xA964, 0x59BB, 0xA965, 0x59D4,
+	0xA966, 0x59B9, 0xA967, 0x59AE, 0xA968, 0x59D1, 0xA969, 0x59C6,
+	0xA96A, 0x59D0, 0xA96B, 0x59CD, 0xA96C, 0x59CB, 0xA96D, 0x59D3,
+	0xA96E, 0x59CA, 0xA96F, 0x59AF, 0xA970, 0x59B3, 0xA971, 0x59D2,
+	0xA972, 0x59C5, 0xA973, 0x5B5F, 0xA974, 0x5B64, 0xA975, 0x5B63,
+	0xA976, 0x5B97, 0xA977, 0x5B9A, 0xA978, 0x5B98, 0xA979, 0x5B9C,
+	0xA97A, 0x5B99, 0xA97B, 0x5B9B, 0xA97C, 0x5C1A, 0xA97D, 0x5C48,
+	0xA97E, 0x5C45, 0xA9A1, 0x5C46, 0xA9A2, 0x5CB7, 0xA9A3, 0x5CA1,
+	0xA9A4, 0x5CB8, 0xA9A5, 0x5CA9, 0xA9A6, 0x5CAB, 0xA9A7, 0x5CB1,
+	0xA9A8, 0x5CB3, 0xA9A9, 0x5E18, 0xA9AA, 0x5E1A, 0xA9AB, 0x5E16,
+	0xA9AC, 0x5E15, 0xA9AD, 0x5E1B, 0xA9AE, 0x5E11, 0xA9AF, 0x5E78,
+	0xA9B0, 0x5E9A, 0xA9B1, 0x5E97, 0xA9B2, 0x5E9C, 0xA9B3, 0x5E95,
+	0xA9B4, 0x5E96, 0xA9B5, 0x5EF6, 0xA9B6, 0x5F26, 0xA9B7, 0x5F27,
+	0xA9B8, 0x5F29, 0xA9B9, 0x5F80, 0xA9BA, 0x5F81, 0xA9BB, 0x5F7F,
+	0xA9BC, 0x5F7C, 0xA9BD, 0x5FDD, 0xA9BE, 0x5FE0, 0xA9BF, 0x5FFD,
+	0xA9C0, 0x5FF5, 0xA9C1, 0x5FFF, 0xA9C2, 0x600F, 0xA9C3, 0x6014,
+	0xA9C4, 0x602F, 0xA9C5, 0x6035, 0xA9C6, 0x6016, 0xA9C7, 0x602A,
+	0xA9C8, 0x6015, 0xA9C9, 0x6021, 0xA9CA, 0x6027, 0xA9CB, 0x6029,
+	0xA9CC, 0x602B, 0xA9CD, 0x601B, 0xA9CE, 0x6216, 0xA9CF, 0x6215,
+	0xA9D0, 0x623F, 0xA9D1, 0x623E, 0xA9D2, 0x6240, 0xA9D3, 0x627F,
+	0xA9D4, 0x62C9, 0xA9D5, 0x62CC, 0xA9D6, 0x62C4, 0xA9D7, 0x62BF,
+	0xA9D8, 0x62C2, 0xA9D9, 0x62B9, 0xA9DA, 0x62D2, 0xA9DB, 0x62DB,
+	0xA9DC, 0x62AB, 0xA9DD, 0x62D3, 0xA9DE, 0x62D4, 0xA9DF, 0x62CB,
+	0xA9E0, 0x62C8, 0xA9E1, 0x62A8, 0xA9E2, 0x62BD, 0xA9E3, 0x62BC,
+	0xA9E4, 0x62D0, 0xA9E5, 0x62D9, 0xA9E6, 0x62C7, 0xA9E7, 0x62CD,
+	0xA9E8, 0x62B5, 0xA9E9, 0x62DA, 0xA9EA, 0x62B1, 0xA9EB, 0x62D8,
+	0xA9EC, 0x62D6, 0xA9ED, 0x62D7, 0xA9EE, 0x62C6, 0xA9EF, 0x62AC,
+	0xA9F0, 0x62CE, 0xA9F1, 0x653E, 0xA9F2, 0x65A7, 0xA9F3, 0x65BC,
+	0xA9F4, 0x65FA, 0xA9F5, 0x6614, 0xA9F6, 0x6613, 0xA9F7, 0x660C,
+	0xA9F8, 0x6606, 0xA9F9, 0x6602, 0xA9FA, 0x660E, 0xA9FB, 0x6600,
+	0xA9FC, 0x660F, 0xA9FD, 0x6615, 0xA9FE, 0x660A, 0xAA40, 0x6607,
+	0xAA41, 0x670D, 0xAA42, 0x670B, 0xAA43, 0x676D, 0xAA44, 0x678B,
+	0xAA45, 0x6795, 0xAA46, 0x6771, 0xAA47, 0x679C, 0xAA48, 0x6773,
+	0xAA49, 0x6777, 0xAA4A, 0x6787, 0xAA4B, 0x679D, 0xAA4C, 0x6797,
+	0xAA4D, 0x676F, 0xAA4E, 0x6770, 0xAA4F, 0x677F, 0xAA50, 0x6789,
+	0xAA51, 0x677E, 0xAA52, 0x6790, 0xAA53, 0x6775, 0xAA54, 0x679A,
+	0xAA55, 0x6793, 0xAA56, 0x677C, 0xAA57, 0x676A, 0xAA58, 0x6772,
+	0xAA59, 0x6B23, 0xAA5A, 0x6B66, 0xAA5B, 0x6B67, 0xAA5C, 0x6B7F,
+	0xAA5D, 0x6C13, 0xAA5E, 0x6C1B, 0xAA5F, 0x6CE3, 0xAA60, 0x6CE8,
+	0xAA61, 0x6CF3, 0xAA62, 0x6CB1, 0xAA63, 0x6CCC, 0xAA64, 0x6CE5,
+	0xAA65, 0x6CB3, 0xAA66, 0x6CBD, 0xAA67, 0x6CBE, 0xAA68, 0x6CBC,
+	0xAA69, 0x6CE2, 0xAA6A, 0x6CAB, 0xAA6B, 0x6CD5, 0xAA6C, 0x6CD3,
+	0xAA6D, 0x6CB8, 0xAA6E, 0x6CC4, 0xAA6F, 0x6CB9, 0xAA70, 0x6CC1,
+	0xAA71, 0x6CAE, 0xAA72, 0x6CD7, 0xAA73, 0x6CC5, 0xAA74, 0x6CF1,
+	0xAA75, 0x6CBF, 0xAA76, 0x6CBB, 0xAA77, 0x6CE1, 0xAA78, 0x6CDB,
+	0xAA79, 0x6CCA, 0xAA7A, 0x6CAC, 0xAA7B, 0x6CEF, 0xAA7C, 0x6CDC,
+	0xAA7D, 0x6CD6, 0xAA7E, 0x6CE0, 0xAAA1, 0x7095, 0xAAA2, 0x708E,
+	0xAAA3, 0x7092, 0xAAA4, 0x708A, 0xAAA5, 0x7099, 0xAAA6, 0x722C,
+	0xAAA7, 0x722D, 0xAAA8, 0x7238, 0xAAA9, 0x7248, 0xAAAA, 0x7267,
+	0xAAAB, 0x7269, 0xAAAC, 0x72C0, 0xAAAD, 0x72CE, 0xAAAE, 0x72D9,
+	0xAAAF, 0x72D7, 0xAAB0, 0x72D0, 0xAAB1, 0x73A9, 0xAAB2, 0x73A8,
+	0xAAB3, 0x739F, 0xAAB4, 0x73AB, 0xAAB5, 0x73A5, 0xAAB6, 0x753D,
+	0xAAB7, 0x759D, 0xAAB8, 0x7599, 0xAAB9, 0x759A, 0xAABA, 0x7684,
+	0xAABB, 0x76C2, 0xAABC, 0x76F2, 0xAABD, 0x76F4, 0xAABE, 0x77E5,
+	0xAABF, 0x77FD, 0xAAC0, 0x793E, 0xAAC1, 0x7940, 0xAAC2, 0x7941,
+	0xAAC3, 0x79C9, 0xAAC4, 0x79C8, 0xAAC5, 0x7A7A, 0xAAC6, 0x7A79,
+	0xAAC7, 0x7AFA, 0xAAC8, 0x7CFE, 0xAAC9, 0x7F54, 0xAACA, 0x7F8C,
+	0xAACB, 0x7F8B, 0xAACC, 0x8005, 0xAACD, 0x80BA, 0xAACE, 0x80A5,
+	0xAACF, 0x80A2, 0xAAD0, 0x80B1, 0xAAD1, 0x80A1, 0xAAD2, 0x80AB,
+	0xAAD3, 0x80A9, 0xAAD4, 0x80B4, 0xAAD5, 0x80AA, 0xAAD6, 0x80AF,
+	0xAAD7, 0x81E5, 0xAAD8, 0x81FE, 0xAAD9, 0x820D, 0xAADA, 0x82B3,
+	0xAADB, 0x829D, 0xAADC, 0x8299, 0xAADD, 0x82AD, 0xAADE, 0x82BD,
+	0xAADF, 0x829F, 0xAAE0, 0x82B9, 0xAAE1, 0x82B1, 0xAAE2, 0x82AC,
+	0xAAE3, 0x82A5, 0xAAE4, 0x82AF, 0xAAE5, 0x82B8, 0xAAE6, 0x82A3,
+	0xAAE7, 0x82B0, 0xAAE8, 0x82BE, 0xAAE9, 0x82B7, 0xAAEA, 0x864E,
+	0xAAEB, 0x8671, 0xAAEC, 0x521D, 0xAAED, 0x8868, 0xAAEE, 0x8ECB,
+	0xAAEF, 0x8FCE, 0xAAF0, 0x8FD4, 0xAAF1, 0x8FD1, 0xAAF2, 0x90B5,
+	0xAAF3, 0x90B8, 0xAAF4, 0x90B1, 0xAAF5, 0x90B6, 0xAAF6, 0x91C7,
+	0xAAF7, 0x91D1, 0xAAF8, 0x9577, 0xAAF9, 0x9580, 0xAAFA, 0x961C,
+	0xAAFB, 0x9640, 0xAAFC, 0x963F, 0xAAFD, 0x963B, 0xAAFE, 0x9644,
+	0xAB40, 0x9642, 0xAB41, 0x96B9, 0xAB42, 0x96E8, 0xAB43, 0x9752,
+	0xAB44, 0x975E, 0xAB45, 0x4E9F, 0xAB46, 0x4EAD, 0xAB47, 0x4EAE,
+	0xAB48, 0x4FE1, 0xAB49, 0x4FB5, 0xAB4A, 0x4FAF, 0xAB4B, 0x4FBF,
+	0xAB4C, 0x4FE0, 0xAB4D, 0x4FD1, 0xAB4E, 0x4FCF, 0xAB4F, 0x4FDD,
+	0xAB50, 0x4FC3, 0xAB51, 0x4FB6, 0xAB52, 0x4FD8, 0xAB53, 0x4FDF,
+	0xAB54, 0x4FCA, 0xAB55, 0x4FD7, 0xAB56, 0x4FAE, 0xAB57, 0x4FD0,
+	0xAB58, 0x4FC4, 0xAB59, 0x4FC2, 0xAB5A, 0x4FDA, 0xAB5B, 0x4FCE,
+	0xAB5C, 0x4FDE, 0xAB5D, 0x4FB7, 0xAB5E, 0x5157, 0xAB5F, 0x5192,
+	0xAB60, 0x5191, 0xAB61, 0x51A0, 0xAB62, 0x524E, 0xAB63, 0x5243,
+	0xAB64, 0x524A, 0xAB65, 0x524D, 0xAB66, 0x524C, 0xAB67, 0x524B,
+	0xAB68, 0x5247, 0xAB69, 0x52C7, 0xAB6A, 0x52C9, 0xAB6B, 0x52C3,
+	0xAB6C, 0x52C1, 0xAB6D, 0x530D, 0xAB6E, 0x5357, 0xAB6F, 0x537B,
+	0xAB70, 0x539A, 0xAB71, 0x53DB, 0xAB72, 0x54AC, 0xAB73, 0x54C0,
+	0xAB74, 0x54A8, 0xAB75, 0x54CE, 0xAB76, 0x54C9, 0xAB77, 0x54B8,
+	0xAB78, 0x54A6, 0xAB79, 0x54B3, 0xAB7A, 0x54C7, 0xAB7B, 0x54C2,
+	0xAB7C, 0x54BD, 0xAB7D, 0x54AA, 0xAB7E, 0x54C1, 0xABA1, 0x54C4,
+	0xABA2, 0x54C8, 0xABA3, 0x54AF, 0xABA4, 0x54AB, 0xABA5, 0x54B1,
+	0xABA6, 0x54BB, 0xABA7, 0x54A9, 0xABA8, 0x54A7, 0xABA9, 0x54BF,
+	0xABAA, 0x56FF, 0xABAB, 0x5782, 0xABAC, 0x578B, 0xABAD, 0x57A0,
+	0xABAE, 0x57A3, 0xABAF, 0x57A2, 0xABB0, 0x57CE, 0xABB1, 0x57AE,
+	0xABB2, 0x5793, 0xABB3, 0x5955, 0xABB4, 0x5951, 0xABB5, 0x594F,
+	0xABB6, 0x594E, 0xABB7, 0x5950, 0xABB8, 0x59DC, 0xABB9, 0x59D8,
+	0xABBA, 0x59FF, 0xABBB, 0x59E3, 0xABBC, 0x59E8, 0xABBD, 0x5A03,
+	0xABBE, 0x59E5, 0xABBF, 0x59EA, 0xABC0, 0x59DA, 0xABC1, 0x59E6,
+	0xABC2, 0x5A01, 0xABC3, 0x59FB, 0xABC4, 0x5B69, 0xABC5, 0x5BA3,
+	0xABC6, 0x5BA6, 0xABC7, 0x5BA4, 0xABC8, 0x5BA2, 0xABC9, 0x5BA5,
+	0xABCA, 0x5C01, 0xABCB, 0x5C4E, 0xABCC, 0x5C4F, 0xABCD, 0x5C4D,
+	0xABCE, 0x5C4B, 0xABCF, 0x5CD9, 0xABD0, 0x5CD2, 0xABD1, 0x5DF7,
+	0xABD2, 0x5E1D, 0xABD3, 0x5E25, 0xABD4, 0x5E1F, 0xABD5, 0x5E7D,
+	0xABD6, 0x5EA0, 0xABD7, 0x5EA6, 0xABD8, 0x5EFA, 0xABD9, 0x5F08,
+	0xABDA, 0x5F2D, 0xABDB, 0x5F65, 0xABDC, 0x5F88, 0xABDD, 0x5F85,
+	0xABDE, 0x5F8A, 0xABDF, 0x5F8B, 0xABE0, 0x5F87, 0xABE1, 0x5F8C,
+	0xABE2, 0x5F89, 0xABE3, 0x6012, 0xABE4, 0x601D, 0xABE5, 0x6020,
+	0xABE6, 0x6025, 0xABE7, 0x600E, 0xABE8, 0x6028, 0xABE9, 0x604D,
+	0xABEA, 0x6070, 0xABEB, 0x6068, 0xABEC, 0x6062, 0xABED, 0x6046,
+	0xABEE, 0x6043, 0xABEF, 0x606C, 0xABF0, 0x606B, 0xABF1, 0x606A,
+	0xABF2, 0x6064, 0xABF3, 0x6241, 0xABF4, 0x62DC, 0xABF5, 0x6316,
+	0xABF6, 0x6309, 0xABF7, 0x62FC, 0xABF8, 0x62ED, 0xABF9, 0x6301,
+	0xABFA, 0x62EE, 0xABFB, 0x62FD, 0xABFC, 0x6307, 0xABFD, 0x62F1,
+	0xABFE, 0x62F7, 0xAC40, 0x62EF, 0xAC41, 0x62EC, 0xAC42, 0x62FE,
+	0xAC43, 0x62F4, 0xAC44, 0x6311, 0xAC45, 0x6302, 0xAC46, 0x653F,
+	0xAC47, 0x6545, 0xAC48, 0x65AB, 0xAC49, 0x65BD, 0xAC4A, 0x65E2,
+	0xAC4B, 0x6625, 0xAC4C, 0x662D, 0xAC4D, 0x6620, 0xAC4E, 0x6627,
+	0xAC4F, 0x662F, 0xAC50, 0x661F, 0xAC51, 0x6628, 0xAC52, 0x6631,
+	0xAC53, 0x6624, 0xAC54, 0x66F7, 0xAC55, 0x67FF, 0xAC56, 0x67D3,
+	0xAC57, 0x67F1, 0xAC58, 0x67D4, 0xAC59, 0x67D0, 0xAC5A, 0x67EC,
+	0xAC5B, 0x67B6, 0xAC5C, 0x67AF, 0xAC5D, 0x67F5, 0xAC5E, 0x67E9,
+	0xAC5F, 0x67EF, 0xAC60, 0x67C4, 0xAC61, 0x67D1, 0xAC62, 0x67B4,
+	0xAC63, 0x67DA, 0xAC64, 0x67E5, 0xAC65, 0x67B8, 0xAC66, 0x67CF,
+	0xAC67, 0x67DE, 0xAC68, 0x67F3, 0xAC69, 0x67B0, 0xAC6A, 0x67D9,
+	0xAC6B, 0x67E2, 0xAC6C, 0x67DD, 0xAC6D, 0x67D2, 0xAC6E, 0x6B6A,
+	0xAC6F, 0x6B83, 0xAC70, 0x6B86, 0xAC71, 0x6BB5, 0xAC72, 0x6BD2,
+	0xAC73, 0x6BD7, 0xAC74, 0x6C1F, 0xAC75, 0x6CC9, 0xAC76, 0x6D0B,
+	0xAC77, 0x6D32, 0xAC78, 0x6D2A, 0xAC79, 0x6D41, 0xAC7A, 0x6D25,
+	0xAC7B, 0x6D0C, 0xAC7C, 0x6D31, 0xAC7D, 0x6D1E, 0xAC7E, 0x6D17,
+	0xACA1, 0x6D3B, 0xACA2, 0x6D3D, 0xACA3, 0x6D3E, 0xACA4, 0x6D36,
+	0xACA5, 0x6D1B, 0xACA6, 0x6CF5, 0xACA7, 0x6D39, 0xACA8, 0x6D27,
+	0xACA9, 0x6D38, 0xACAA, 0x6D29, 0xACAB, 0x6D2E, 0xACAC, 0x6D35,
+	0xACAD, 0x6D0E, 0xACAE, 0x6D2B, 0xACAF, 0x70AB, 0xACB0, 0x70BA,
+	0xACB1, 0x70B3, 0xACB2, 0x70AC, 0xACB3, 0x70AF, 0xACB4, 0x70AD,
+	0xACB5, 0x70B8, 0xACB6, 0x70AE, 0xACB7, 0x70A4, 0xACB8, 0x7230,
+	0xACB9, 0x7272, 0xACBA, 0x726F, 0xACBB, 0x7274, 0xACBC, 0x72E9,
+	0xACBD, 0x72E0, 0xACBE, 0x72E1, 0xACBF, 0x73B7, 0xACC0, 0x73CA,
+	0xACC1, 0x73BB, 0xACC2, 0x73B2, 0xACC3, 0x73CD, 0xACC4, 0x73C0,
+	0xACC5, 0x73B3, 0xACC6, 0x751A, 0xACC7, 0x752D, 0xACC8, 0x754F,
+	0xACC9, 0x754C, 0xACCA, 0x754E, 0xACCB, 0x754B, 0xACCC, 0x75AB,
+	0xACCD, 0x75A4, 0xACCE, 0x75A5, 0xACCF, 0x75A2, 0xACD0, 0x75A3,
+	0xACD1, 0x7678, 0xACD2, 0x7686, 0xACD3, 0x7687, 0xACD4, 0x7688,
+	0xACD5, 0x76C8, 0xACD6, 0x76C6, 0xACD7, 0x76C3, 0xACD8, 0x76C5,
+	0xACD9, 0x7701, 0xACDA, 0x76F9, 0xACDB, 0x76F8, 0xACDC, 0x7709,
+	0xACDD, 0x770B, 0xACDE, 0x76FE, 0xACDF, 0x76FC, 0xACE0, 0x7707,
+	0xACE1, 0x77DC, 0xACE2, 0x7802, 0xACE3, 0x7814, 0xACE4, 0x780C,
+	0xACE5, 0x780D, 0xACE6, 0x7946, 0xACE7, 0x7949, 0xACE8, 0x7948,
+	0xACE9, 0x7947, 0xACEA, 0x79B9, 0xACEB, 0x79BA, 0xACEC, 0x79D1,
+	0xACED, 0x79D2, 0xACEE, 0x79CB, 0xACEF, 0x7A7F, 0xACF0, 0x7A81,
+	0xACF1, 0x7AFF, 0xACF2, 0x7AFD, 0xACF3, 0x7C7D, 0xACF4, 0x7D02,
+	0xACF5, 0x7D05, 0xACF6, 0x7D00, 0xACF7, 0x7D09, 0xACF8, 0x7D07,
+	0xACF9, 0x7D04, 0xACFA, 0x7D06, 0xACFB, 0x7F38, 0xACFC, 0x7F8E,
+	0xACFD, 0x7FBF, 0xACFE, 0x8004, 0xAD40, 0x8010, 0xAD41, 0x800D,
+	0xAD42, 0x8011, 0xAD43, 0x8036, 0xAD44, 0x80D6, 0xAD45, 0x80E5,
+	0xAD46, 0x80DA, 0xAD47, 0x80C3, 0xAD48, 0x80C4, 0xAD49, 0x80CC,
+	0xAD4A, 0x80E1, 0xAD4B, 0x80DB, 0xAD4C, 0x80CE, 0xAD4D, 0x80DE,
+	0xAD4E, 0x80E4, 0xAD4F, 0x80DD, 0xAD50, 0x81F4, 0xAD51, 0x8222,
+	0xAD52, 0x82E7, 0xAD53, 0x8303, 0xAD54, 0x8305, 0xAD55, 0x82E3,
+	0xAD56, 0x82DB, 0xAD57, 0x82E6, 0xAD58, 0x8304, 0xAD59, 0x82E5,
+	0xAD5A, 0x8302, 0xAD5B, 0x8309, 0xAD5C, 0x82D2, 0xAD5D, 0x82D7,
+	0xAD5E, 0x82F1, 0xAD5F, 0x8301, 0xAD60, 0x82DC, 0xAD61, 0x82D4,
+	0xAD62, 0x82D1, 0xAD63, 0x82DE, 0xAD64, 0x82D3, 0xAD65, 0x82DF,
+	0xAD66, 0x82EF, 0xAD67, 0x8306, 0xAD68, 0x8650, 0xAD69, 0x8679,
+	0xAD6A, 0x867B, 0xAD6B, 0x867A, 0xAD6C, 0x884D, 0xAD6D, 0x886B,
+	0xAD6E, 0x8981, 0xAD6F, 0x89D4, 0xAD70, 0x8A08, 0xAD71, 0x8A02,
+	0xAD72, 0x8A03, 0xAD73, 0x8C9E, 0xAD74, 0x8CA0, 0xAD75, 0x8D74,
+	0xAD76, 0x8D73, 0xAD77, 0x8DB4, 0xAD78, 0x8ECD, 0xAD79, 0x8ECC,
+	0xAD7A, 0x8FF0, 0xAD7B, 0x8FE6, 0xAD7C, 0x8FE2, 0xAD7D, 0x8FEA,
+	0xAD7E, 0x8FE5, 0xADA1, 0x8FED, 0xADA2, 0x8FEB, 0xADA3, 0x8FE4,
+	0xADA4, 0x8FE8, 0xADA5, 0x90CA, 0xADA6, 0x90CE, 0xADA7, 0x90C1,
+	0xADA8, 0x90C3, 0xADA9, 0x914B, 0xADAA, 0x914A, 0xADAB, 0x91CD,
+	0xADAC, 0x9582, 0xADAD, 0x9650, 0xADAE, 0x964B, 0xADAF, 0x964C,
+	0xADB0, 0x964D, 0xADB1, 0x9762, 0xADB2, 0x9769, 0xADB3, 0x97CB,
+	0xADB4, 0x97ED, 0xADB5, 0x97F3, 0xADB6, 0x9801, 0xADB7, 0x98A8,
+	0xADB8, 0x98DB, 0xADB9, 0x98DF, 0xADBA, 0x9996, 0xADBB, 0x9999,
+	0xADBC, 0x4E58, 0xADBD, 0x4EB3, 0xADBE, 0x500C, 0xADBF, 0x500D,
+	0xADC0, 0x5023, 0xADC1, 0x4FEF, 0xADC2, 0x5026, 0xADC3, 0x5025,
+	0xADC4, 0x4FF8, 0xADC5, 0x5029, 0xADC6, 0x5016, 0xADC7, 0x5006,
+	0xADC8, 0x503C, 0xADC9, 0x501F, 0xADCA, 0x501A, 0xADCB, 0x5012,
+	0xADCC, 0x5011, 0xADCD, 0x4FFA, 0xADCE, 0x5000, 0xADCF, 0x5014,
+	0xADD0, 0x5028, 0xADD1, 0x4FF1, 0xADD2, 0x5021, 0xADD3, 0x500B,
+	0xADD4, 0x5019, 0xADD5, 0x5018, 0xADD6, 0x4FF3, 0xADD7, 0x4FEE,
+	0xADD8, 0x502D, 0xADD9, 0x502A, 0xADDA, 0x4FFE, 0xADDB, 0x502B,
+	0xADDC, 0x5009, 0xADDD, 0x517C, 0xADDE, 0x51A4, 0xADDF, 0x51A5,
+	0xADE0, 0x51A2, 0xADE1, 0x51CD, 0xADE2, 0x51CC, 0xADE3, 0x51C6,
+	0xADE4, 0x51CB, 0xADE5, 0x5256, 0xADE6, 0x525C, 0xADE7, 0x5254,
+	0xADE8, 0x525B, 0xADE9, 0x525D, 0xADEA, 0x532A, 0xADEB, 0x537F,
+	0xADEC, 0x539F, 0xADED, 0x539D, 0xADEE, 0x53DF, 0xADEF, 0x54E8,
+	0xADF0, 0x5510, 0xADF1, 0x5501, 0xADF2, 0x5537, 0xADF3, 0x54FC,
+	0xADF4, 0x54E5, 0xADF5, 0x54F2, 0xADF6, 0x5506, 0xADF7, 0x54FA,
+	0xADF8, 0x5514, 0xADF9, 0x54E9, 0xADFA, 0x54ED, 0xADFB, 0x54E1,
+	0xADFC, 0x5509, 0xADFD, 0x54EE, 0xADFE, 0x54EA, 0xAE40, 0x54E6,
+	0xAE41, 0x5527, 0xAE42, 0x5507, 0xAE43, 0x54FD, 0xAE44, 0x550F,
+	0xAE45, 0x5703, 0xAE46, 0x5704, 0xAE47, 0x57C2, 0xAE48, 0x57D4,
+	0xAE49, 0x57CB, 0xAE4A, 0x57C3, 0xAE4B, 0x5809, 0xAE4C, 0x590F,
+	0xAE4D, 0x5957, 0xAE4E, 0x5958, 0xAE4F, 0x595A, 0xAE50, 0x5A11,
+	0xAE51, 0x5A18, 0xAE52, 0x5A1C, 0xAE53, 0x5A1F, 0xAE54, 0x5A1B,
+	0xAE55, 0x5A13, 0xAE56, 0x59EC, 0xAE57, 0x5A20, 0xAE58, 0x5A23,
+	0xAE59, 0x5A29, 0xAE5A, 0x5A25, 0xAE5B, 0x5A0C, 0xAE5C, 0x5A09,
+	0xAE5D, 0x5B6B, 0xAE5E, 0x5C58, 0xAE5F, 0x5BB0, 0xAE60, 0x5BB3,
+	0xAE61, 0x5BB6, 0xAE62, 0x5BB4, 0xAE63, 0x5BAE, 0xAE64, 0x5BB5,
+	0xAE65, 0x5BB9, 0xAE66, 0x5BB8, 0xAE67, 0x5C04, 0xAE68, 0x5C51,
+	0xAE69, 0x5C55, 0xAE6A, 0x5C50, 0xAE6B, 0x5CED, 0xAE6C, 0x5CFD,
+	0xAE6D, 0x5CFB, 0xAE6E, 0x5CEA, 0xAE6F, 0x5CE8, 0xAE70, 0x5CF0,
+	0xAE71, 0x5CF6, 0xAE72, 0x5D01, 0xAE73, 0x5CF4, 0xAE74, 0x5DEE,
+	0xAE75, 0x5E2D, 0xAE76, 0x5E2B, 0xAE77, 0x5EAB, 0xAE78, 0x5EAD,
+	0xAE79, 0x5EA7, 0xAE7A, 0x5F31, 0xAE7B, 0x5F92, 0xAE7C, 0x5F91,
+	0xAE7D, 0x5F90, 0xAE7E, 0x6059, 0xAEA1, 0x6063, 0xAEA2, 0x6065,
+	0xAEA3, 0x6050, 0xAEA4, 0x6055, 0xAEA5, 0x606D, 0xAEA6, 0x6069,
+	0xAEA7, 0x606F, 0xAEA8, 0x6084, 0xAEA9, 0x609F, 0xAEAA, 0x609A,
+	0xAEAB, 0x608D, 0xAEAC, 0x6094, 0xAEAD, 0x608C, 0xAEAE, 0x6085,
+	0xAEAF, 0x6096, 0xAEB0, 0x6247, 0xAEB1, 0x62F3, 0xAEB2, 0x6308,
+	0xAEB3, 0x62FF, 0xAEB4, 0x634E, 0xAEB5, 0x633E, 0xAEB6, 0x632F,
+	0xAEB7, 0x6355, 0xAEB8, 0x6342, 0xAEB9, 0x6346, 0xAEBA, 0x634F,
+	0xAEBB, 0x6349, 0xAEBC, 0x633A, 0xAEBD, 0x6350, 0xAEBE, 0x633D,
+	0xAEBF, 0x632A, 0xAEC0, 0x632B, 0xAEC1, 0x6328, 0xAEC2, 0x634D,
+	0xAEC3, 0x634C, 0xAEC4, 0x6548, 0xAEC5, 0x6549, 0xAEC6, 0x6599,
+	0xAEC7, 0x65C1, 0xAEC8, 0x65C5, 0xAEC9, 0x6642, 0xAECA, 0x6649,
+	0xAECB, 0x664F, 0xAECC, 0x6643, 0xAECD, 0x6652, 0xAECE, 0x664C,
+	0xAECF, 0x6645, 0xAED0, 0x6641, 0xAED1, 0x66F8, 0xAED2, 0x6714,
+	0xAED3, 0x6715, 0xAED4, 0x6717, 0xAED5, 0x6821, 0xAED6, 0x6838,
+	0xAED7, 0x6848, 0xAED8, 0x6846, 0xAED9, 0x6853, 0xAEDA, 0x6839,
+	0xAEDB, 0x6842, 0xAEDC, 0x6854, 0xAEDD, 0x6829, 0xAEDE, 0x68B3,
+	0xAEDF, 0x6817, 0xAEE0, 0x684C, 0xAEE1, 0x6851, 0xAEE2, 0x683D,
+	0xAEE3, 0x67F4, 0xAEE4, 0x6850, 0xAEE5, 0x6840, 0xAEE6, 0x683C,
+	0xAEE7, 0x6843, 0xAEE8, 0x682A, 0xAEE9, 0x6845, 0xAEEA, 0x6813,
+	0xAEEB, 0x6818, 0xAEEC, 0x6841, 0xAEED, 0x6B8A, 0xAEEE, 0x6B89,
+	0xAEEF, 0x6BB7, 0xAEF0, 0x6C23, 0xAEF1, 0x6C27, 0xAEF2, 0x6C28,
+	0xAEF3, 0x6C26, 0xAEF4, 0x6C24, 0xAEF5, 0x6CF0, 0xAEF6, 0x6D6A,
+	0xAEF7, 0x6D95, 0xAEF8, 0x6D88, 0xAEF9, 0x6D87, 0xAEFA, 0x6D66,
+	0xAEFB, 0x6D78, 0xAEFC, 0x6D77, 0xAEFD, 0x6D59, 0xAEFE, 0x6D93,
+	0xAF40, 0x6D6C, 0xAF41, 0x6D89, 0xAF42, 0x6D6E, 0xAF43, 0x6D5A,
+	0xAF44, 0x6D74, 0xAF45, 0x6D69, 0xAF46, 0x6D8C, 0xAF47, 0x6D8A,
+	0xAF48, 0x6D79, 0xAF49, 0x6D85, 0xAF4A, 0x6D65, 0xAF4B, 0x6D94,
+	0xAF4C, 0x70CA, 0xAF4D, 0x70D8, 0xAF4E, 0x70E4, 0xAF4F, 0x70D9,
+	0xAF50, 0x70C8, 0xAF51, 0x70CF, 0xAF52, 0x7239, 0xAF53, 0x7279,
+	0xAF54, 0x72FC, 0xAF55, 0x72F9, 0xAF56, 0x72FD, 0xAF57, 0x72F8,
+	0xAF58, 0x72F7, 0xAF59, 0x7386, 0xAF5A, 0x73ED, 0xAF5B, 0x7409,
+	0xAF5C, 0x73EE, 0xAF5D, 0x73E0, 0xAF5E, 0x73EA, 0xAF5F, 0x73DE,
+	0xAF60, 0x7554, 0xAF61, 0x755D, 0xAF62, 0x755C, 0xAF63, 0x755A,
+	0xAF64, 0x7559, 0xAF65, 0x75BE, 0xAF66, 0x75C5, 0xAF67, 0x75C7,
+	0xAF68, 0x75B2, 0xAF69, 0x75B3, 0xAF6A, 0x75BD, 0xAF6B, 0x75BC,
+	0xAF6C, 0x75B9, 0xAF6D, 0x75C2, 0xAF6E, 0x75B8, 0xAF6F, 0x768B,
+	0xAF70, 0x76B0, 0xAF71, 0x76CA, 0xAF72, 0x76CD, 0xAF73, 0x76CE,
+	0xAF74, 0x7729, 0xAF75, 0x771F, 0xAF76, 0x7720, 0xAF77, 0x7728,
+	0xAF78, 0x77E9, 0xAF79, 0x7830, 0xAF7A, 0x7827, 0xAF7B, 0x7838,
+	0xAF7C, 0x781D, 0xAF7D, 0x7834, 0xAF7E, 0x7837, 0xAFA1, 0x7825,
+	0xAFA2, 0x782D, 0xAFA3, 0x7820, 0xAFA4, 0x781F, 0xAFA5, 0x7832,
+	0xAFA6, 0x7955, 0xAFA7, 0x7950, 0xAFA8, 0x7960, 0xAFA9, 0x795F,
+	0xAFAA, 0x7956, 0xAFAB, 0x795E, 0xAFAC, 0x795D, 0xAFAD, 0x7957,
+	0xAFAE, 0x795A, 0xAFAF, 0x79E4, 0xAFB0, 0x79E3, 0xAFB1, 0x79E7,
+	0xAFB2, 0x79DF, 0xAFB3, 0x79E6, 0xAFB4, 0x79E9, 0xAFB5, 0x79D8,
+	0xAFB6, 0x7A84, 0xAFB7, 0x7A88, 0xAFB8, 0x7AD9, 0xAFB9, 0x7B06,
+	0xAFBA, 0x7B11, 0xAFBB, 0x7C89, 0xAFBC, 0x7D21, 0xAFBD, 0x7D17,
+	0xAFBE, 0x7D0B, 0xAFBF, 0x7D0A, 0xAFC0, 0x7D20, 0xAFC1, 0x7D22,
+	0xAFC2, 0x7D14, 0xAFC3, 0x7D10, 0xAFC4, 0x7D15, 0xAFC5, 0x7D1A,
+	0xAFC6, 0x7D1C, 0xAFC7, 0x7D0D, 0xAFC8, 0x7D19, 0xAFC9, 0x7D1B,
+	0xAFCA, 0x7F3A, 0xAFCB, 0x7F5F, 0xAFCC, 0x7F94, 0xAFCD, 0x7FC5,
+	0xAFCE, 0x7FC1, 0xAFCF, 0x8006, 0xAFD0, 0x8018, 0xAFD1, 0x8015,
+	0xAFD2, 0x8019, 0xAFD3, 0x8017, 0xAFD4, 0x803D, 0xAFD5, 0x803F,
+	0xAFD6, 0x80F1, 0xAFD7, 0x8102, 0xAFD8, 0x80F0, 0xAFD9, 0x8105,
+	0xAFDA, 0x80ED, 0xAFDB, 0x80F4, 0xAFDC, 0x8106, 0xAFDD, 0x80F8,
+	0xAFDE, 0x80F3, 0xAFDF, 0x8108, 0xAFE0, 0x80FD, 0xAFE1, 0x810A,
+	0xAFE2, 0x80FC, 0xAFE3, 0x80EF, 0xAFE4, 0x81ED, 0xAFE5, 0x81EC,
+	0xAFE6, 0x8200, 0xAFE7, 0x8210, 0xAFE8, 0x822A, 0xAFE9, 0x822B,
+	0xAFEA, 0x8228, 0xAFEB, 0x822C, 0xAFEC, 0x82BB, 0xAFED, 0x832B,
+	0xAFEE, 0x8352, 0xAFEF, 0x8354, 0xAFF0, 0x834A, 0xAFF1, 0x8338,
+	0xAFF2, 0x8350, 0xAFF3, 0x8349, 0xAFF4, 0x8335, 0xAFF5, 0x8334,
+	0xAFF6, 0x834F, 0xAFF7, 0x8332, 0xAFF8, 0x8339, 0xAFF9, 0x8336,
+	0xAFFA, 0x8317, 0xAFFB, 0x8340, 0xAFFC, 0x8331, 0xAFFD, 0x8328,
+	0xAFFE, 0x8343, 0xB040, 0x8654, 0xB041, 0x868A, 0xB042, 0x86AA,
+	0xB043, 0x8693, 0xB044, 0x86A4, 0xB045, 0x86A9, 0xB046, 0x868C,
+	0xB047, 0x86A3, 0xB048, 0x869C, 0xB049, 0x8870, 0xB04A, 0x8877,
+	0xB04B, 0x8881, 0xB04C, 0x8882, 0xB04D, 0x887D, 0xB04E, 0x8879,
+	0xB04F, 0x8A18, 0xB050, 0x8A10, 0xB051, 0x8A0E, 0xB052, 0x8A0C,
+	0xB053, 0x8A15, 0xB054, 0x8A0A, 0xB055, 0x8A17, 0xB056, 0x8A13,
+	0xB057, 0x8A16, 0xB058, 0x8A0F, 0xB059, 0x8A11, 0xB05A, 0x8C48,
+	0xB05B, 0x8C7A, 0xB05C, 0x8C79, 0xB05D, 0x8CA1, 0xB05E, 0x8CA2,
+	0xB05F, 0x8D77, 0xB060, 0x8EAC, 0xB061, 0x8ED2, 0xB062, 0x8ED4,
+	0xB063, 0x8ECF, 0xB064, 0x8FB1, 0xB065, 0x9001, 0xB066, 0x9006,
+	0xB067, 0x8FF7, 0xB068, 0x9000, 0xB069, 0x8FFA, 0xB06A, 0x8FF4,
+	0xB06B, 0x9003, 0xB06C, 0x8FFD, 0xB06D, 0x9005, 0xB06E, 0x8FF8,
+	0xB06F, 0x9095, 0xB070, 0x90E1, 0xB071, 0x90DD, 0xB072, 0x90E2,
+	0xB073, 0x9152, 0xB074, 0x914D, 0xB075, 0x914C, 0xB076, 0x91D8,
+	0xB077, 0x91DD, 0xB078, 0x91D7, 0xB079, 0x91DC, 0xB07A, 0x91D9,
+	0xB07B, 0x9583, 0xB07C, 0x9662, 0xB07D, 0x9663, 0xB07E, 0x9661,
+	0xB0A1, 0x965B, 0xB0A2, 0x965D, 0xB0A3, 0x9664, 0xB0A4, 0x9658,
+	0xB0A5, 0x965E, 0xB0A6, 0x96BB, 0xB0A7, 0x98E2, 0xB0A8, 0x99AC,
+	0xB0A9, 0x9AA8, 0xB0AA, 0x9AD8, 0xB0AB, 0x9B25, 0xB0AC, 0x9B32,
+	0xB0AD, 0x9B3C, 0xB0AE, 0x4E7E, 0xB0AF, 0x507A, 0xB0B0, 0x507D,
+	0xB0B1, 0x505C, 0xB0B2, 0x5047, 0xB0B3, 0x5043, 0xB0B4, 0x504C,
+	0xB0B5, 0x505A, 0xB0B6, 0x5049, 0xB0B7, 0x5065, 0xB0B8, 0x5076,
+	0xB0B9, 0x504E, 0xB0BA, 0x5055, 0xB0BB, 0x5075, 0xB0BC, 0x5074,
+	0xB0BD, 0x5077, 0xB0BE, 0x504F, 0xB0BF, 0x500F, 0xB0C0, 0x506F,
+	0xB0C1, 0x506D, 0xB0C2, 0x515C, 0xB0C3, 0x5195, 0xB0C4, 0x51F0,
+	0xB0C5, 0x526A, 0xB0C6, 0x526F, 0xB0C7, 0x52D2, 0xB0C8, 0x52D9,
+	0xB0C9, 0x52D8, 0xB0CA, 0x52D5, 0xB0CB, 0x5310, 0xB0CC, 0x530F,
+	0xB0CD, 0x5319, 0xB0CE, 0x533F, 0xB0CF, 0x5340, 0xB0D0, 0x533E,
+	0xB0D1, 0x53C3, 0xB0D2, 0x66FC, 0xB0D3, 0x5546, 0xB0D4, 0x556A,
+	0xB0D5, 0x5566, 0xB0D6, 0x5544, 0xB0D7, 0x555E, 0xB0D8, 0x5561,
+	0xB0D9, 0x5543, 0xB0DA, 0x554A, 0xB0DB, 0x5531, 0xB0DC, 0x5556,
+	0xB0DD, 0x554F, 0xB0DE, 0x5555, 0xB0DF, 0x552F, 0xB0E0, 0x5564,
+	0xB0E1, 0x5538, 0xB0E2, 0x552E, 0xB0E3, 0x555C, 0xB0E4, 0x552C,
+	0xB0E5, 0x5563, 0xB0E6, 0x5533, 0xB0E7, 0x5541, 0xB0E8, 0x5557,
+	0xB0E9, 0x5708, 0xB0EA, 0x570B, 0xB0EB, 0x5709, 0xB0EC, 0x57DF,
+	0xB0ED, 0x5805, 0xB0EE, 0x580A, 0xB0EF, 0x5806, 0xB0F0, 0x57E0,
+	0xB0F1, 0x57E4, 0xB0F2, 0x57FA, 0xB0F3, 0x5802, 0xB0F4, 0x5835,
+	0xB0F5, 0x57F7, 0xB0F6, 0x57F9, 0xB0F7, 0x5920, 0xB0F8, 0x5962,
+	0xB0F9, 0x5A36, 0xB0FA, 0x5A41, 0xB0FB, 0x5A49, 0xB0FC, 0x5A66,
+	0xB0FD, 0x5A6A, 0xB0FE, 0x5A40, 0xB140, 0x5A3C, 0xB141, 0x5A62,
+	0xB142, 0x5A5A, 0xB143, 0x5A46, 0xB144, 0x5A4A, 0xB145, 0x5B70,
+	0xB146, 0x5BC7, 0xB147, 0x5BC5, 0xB148, 0x5BC4, 0xB149, 0x5BC2,
+	0xB14A, 0x5BBF, 0xB14B, 0x5BC6, 0xB14C, 0x5C09, 0xB14D, 0x5C08,
+	0xB14E, 0x5C07, 0xB14F, 0x5C60, 0xB150, 0x5C5C, 0xB151, 0x5C5D,
+	0xB152, 0x5D07, 0xB153, 0x5D06, 0xB154, 0x5D0E, 0xB155, 0x5D1B,
+	0xB156, 0x5D16, 0xB157, 0x5D22, 0xB158, 0x5D11, 0xB159, 0x5D29,
+	0xB15A, 0x5D14, 0xB15B, 0x5D19, 0xB15C, 0x5D24, 0xB15D, 0x5D27,
+	0xB15E, 0x5D17, 0xB15F, 0x5DE2, 0xB160, 0x5E38, 0xB161, 0x5E36,
+	0xB162, 0x5E33, 0xB163, 0x5E37, 0xB164, 0x5EB7, 0xB165, 0x5EB8,
+	0xB166, 0x5EB6, 0xB167, 0x5EB5, 0xB168, 0x5EBE, 0xB169, 0x5F35,
+	0xB16A, 0x5F37, 0xB16B, 0x5F57, 0xB16C, 0x5F6C, 0xB16D, 0x5F69,
+	0xB16E, 0x5F6B, 0xB16F, 0x5F97, 0xB170, 0x5F99, 0xB171, 0x5F9E,
+	0xB172, 0x5F98, 0xB173, 0x5FA1, 0xB174, 0x5FA0, 0xB175, 0x5F9C,
+	0xB176, 0x607F, 0xB177, 0x60A3, 0xB178, 0x6089, 0xB179, 0x60A0,
+	0xB17A, 0x60A8, 0xB17B, 0x60CB, 0xB17C, 0x60B4, 0xB17D, 0x60E6,
+	0xB17E, 0x60BD, 0xB1A1, 0x60C5, 0xB1A2, 0x60BB, 0xB1A3, 0x60B5,
+	0xB1A4, 0x60DC, 0xB1A5, 0x60BC, 0xB1A6, 0x60D8, 0xB1A7, 0x60D5,
+	0xB1A8, 0x60C6, 0xB1A9, 0x60DF, 0xB1AA, 0x60B8, 0xB1AB, 0x60DA,
+	0xB1AC, 0x60C7, 0xB1AD, 0x621A, 0xB1AE, 0x621B, 0xB1AF, 0x6248,
+	0xB1B0, 0x63A0, 0xB1B1, 0x63A7, 0xB1B2, 0x6372, 0xB1B3, 0x6396,
+	0xB1B4, 0x63A2, 0xB1B5, 0x63A5, 0xB1B6, 0x6377, 0xB1B7, 0x6367,
+	0xB1B8, 0x6398, 0xB1B9, 0x63AA, 0xB1BA, 0x6371, 0xB1BB, 0x63A9,
+	0xB1BC, 0x6389, 0xB1BD, 0x6383, 0xB1BE, 0x639B, 0xB1BF, 0x636B,
+	0xB1C0, 0x63A8, 0xB1C1, 0x6384, 0xB1C2, 0x6388, 0xB1C3, 0x6399,
+	0xB1C4, 0x63A1, 0xB1C5, 0x63AC, 0xB1C6, 0x6392, 0xB1C7, 0x638F,
+	0xB1C8, 0x6380, 0xB1C9, 0x637B, 0xB1CA, 0x6369, 0xB1CB, 0x6368,
+	0xB1CC, 0x637A, 0xB1CD, 0x655D, 0xB1CE, 0x6556, 0xB1CF, 0x6551,
+	0xB1D0, 0x6559, 0xB1D1, 0x6557, 0xB1D2, 0x555F, 0xB1D3, 0x654F,
+	0xB1D4, 0x6558, 0xB1D5, 0x6555, 0xB1D6, 0x6554, 0xB1D7, 0x659C,
+	0xB1D8, 0x659B, 0xB1D9, 0x65AC, 0xB1DA, 0x65CF, 0xB1DB, 0x65CB,
+	0xB1DC, 0x65CC, 0xB1DD, 0x65CE, 0xB1DE, 0x665D, 0xB1DF, 0x665A,
+	0xB1E0, 0x6664, 0xB1E1, 0x6668, 0xB1E2, 0x6666, 0xB1E3, 0x665E,
+	0xB1E4, 0x66F9, 0xB1E5, 0x52D7, 0xB1E6, 0x671B, 0xB1E7, 0x6881,
+	0xB1E8, 0x68AF, 0xB1E9, 0x68A2, 0xB1EA, 0x6893, 0xB1EB, 0x68B5,
+	0xB1EC, 0x687F, 0xB1ED, 0x6876, 0xB1EE, 0x68B1, 0xB1EF, 0x68A7,
+	0xB1F0, 0x6897, 0xB1F1, 0x68B0, 0xB1F2, 0x6883, 0xB1F3, 0x68C4,
+	0xB1F4, 0x68AD, 0xB1F5, 0x6886, 0xB1F6, 0x6885, 0xB1F7, 0x6894,
+	0xB1F8, 0x689D, 0xB1F9, 0x68A8, 0xB1FA, 0x689F, 0xB1FB, 0x68A1,
+	0xB1FC, 0x6882, 0xB1FD, 0x6B32, 0xB1FE, 0x6BBA, 0xB240, 0x6BEB,
+	0xB241, 0x6BEC, 0xB242, 0x6C2B, 0xB243, 0x6D8E, 0xB244, 0x6DBC,
+	0xB245, 0x6DF3, 0xB246, 0x6DD9, 0xB247, 0x6DB2, 0xB248, 0x6DE1,
+	0xB249, 0x6DCC, 0xB24A, 0x6DE4, 0xB24B, 0x6DFB, 0xB24C, 0x6DFA,
+	0xB24D, 0x6E05, 0xB24E, 0x6DC7, 0xB24F, 0x6DCB, 0xB250, 0x6DAF,
+	0xB251, 0x6DD1, 0xB252, 0x6DAE, 0xB253, 0x6DDE, 0xB254, 0x6DF9,
+	0xB255, 0x6DB8, 0xB256, 0x6DF7, 0xB257, 0x6DF5, 0xB258, 0x6DC5,
+	0xB259, 0x6DD2, 0xB25A, 0x6E1A, 0xB25B, 0x6DB5, 0xB25C, 0x6DDA,
+	0xB25D, 0x6DEB, 0xB25E, 0x6DD8, 0xB25F, 0x6DEA, 0xB260, 0x6DF1,
+	0xB261, 0x6DEE, 0xB262, 0x6DE8, 0xB263, 0x6DC6, 0xB264, 0x6DC4,
+	0xB265, 0x6DAA, 0xB266, 0x6DEC, 0xB267, 0x6DBF, 0xB268, 0x6DE6,
+	0xB269, 0x70F9, 0xB26A, 0x7109, 0xB26B, 0x710A, 0xB26C, 0x70FD,
+	0xB26D, 0x70EF, 0xB26E, 0x723D, 0xB26F, 0x727D, 0xB270, 0x7281,
+	0xB271, 0x731C, 0xB272, 0x731B, 0xB273, 0x7316, 0xB274, 0x7313,
+	0xB275, 0x7319, 0xB276, 0x7387, 0xB277, 0x7405, 0xB278, 0x740A,
+	0xB279, 0x7403, 0xB27A, 0x7406, 0xB27B, 0x73FE, 0xB27C, 0x740D,
+	0xB27D, 0x74E0, 0xB27E, 0x74F6, 0xB2A1, 0x74F7, 0xB2A2, 0x751C,
+	0xB2A3, 0x7522, 0xB2A4, 0x7565, 0xB2A5, 0x7566, 0xB2A6, 0x7562,
+	0xB2A7, 0x7570, 0xB2A8, 0x758F, 0xB2A9, 0x75D4, 0xB2AA, 0x75D5,
+	0xB2AB, 0x75B5, 0xB2AC, 0x75CA, 0xB2AD, 0x75CD, 0xB2AE, 0x768E,
+	0xB2AF, 0x76D4, 0xB2B0, 0x76D2, 0xB2B1, 0x76DB, 0xB2B2, 0x7737,
+	0xB2B3, 0x773E, 0xB2B4, 0x773C, 0xB2B5, 0x7736, 0xB2B6, 0x7738,
+	0xB2B7, 0x773A, 0xB2B8, 0x786B, 0xB2B9, 0x7843, 0xB2BA, 0x784E,
+	0xB2BB, 0x7965, 0xB2BC, 0x7968, 0xB2BD, 0x796D, 0xB2BE, 0x79FB,
+	0xB2BF, 0x7A92, 0xB2C0, 0x7A95, 0xB2C1, 0x7B20, 0xB2C2, 0x7B28,
+	0xB2C3, 0x7B1B, 0xB2C4, 0x7B2C, 0xB2C5, 0x7B26, 0xB2C6, 0x7B19,
+	0xB2C7, 0x7B1E, 0xB2C8, 0x7B2E, 0xB2C9, 0x7C92, 0xB2CA, 0x7C97,
+	0xB2CB, 0x7C95, 0xB2CC, 0x7D46, 0xB2CD, 0x7D43, 0xB2CE, 0x7D71,
+	0xB2CF, 0x7D2E, 0xB2D0, 0x7D39, 0xB2D1, 0x7D3C, 0xB2D2, 0x7D40,
+	0xB2D3, 0x7D30, 0xB2D4, 0x7D33, 0xB2D5, 0x7D44, 0xB2D6, 0x7D2F,
+	0xB2D7, 0x7D42, 0xB2D8, 0x7D32, 0xB2D9, 0x7D31, 0xB2DA, 0x7F3D,
+	0xB2DB, 0x7F9E, 0xB2DC, 0x7F9A, 0xB2DD, 0x7FCC, 0xB2DE, 0x7FCE,
+	0xB2DF, 0x7FD2, 0xB2E0, 0x801C, 0xB2E1, 0x804A, 0xB2E2, 0x8046,
+	0xB2E3, 0x812F, 0xB2E4, 0x8116, 0xB2E5, 0x8123, 0xB2E6, 0x812B,
+	0xB2E7, 0x8129, 0xB2E8, 0x8130, 0xB2E9, 0x8124, 0xB2EA, 0x8202,
+	0xB2EB, 0x8235, 0xB2EC, 0x8237, 0xB2ED, 0x8236, 0xB2EE, 0x8239,
+	0xB2EF, 0x838E, 0xB2F0, 0x839E, 0xB2F1, 0x8398, 0xB2F2, 0x8378,
+	0xB2F3, 0x83A2, 0xB2F4, 0x8396, 0xB2F5, 0x83BD, 0xB2F6, 0x83AB,
+	0xB2F7, 0x8392, 0xB2F8, 0x838A, 0xB2F9, 0x8393, 0xB2FA, 0x8389,
+	0xB2FB, 0x83A0, 0xB2FC, 0x8377, 0xB2FD, 0x837B, 0xB2FE, 0x837C,
+	0xB340, 0x8386, 0xB341, 0x83A7, 0xB342, 0x8655, 0xB343, 0x5F6A,
+	0xB344, 0x86C7, 0xB345, 0x86C0, 0xB346, 0x86B6, 0xB347, 0x86C4,
+	0xB348, 0x86B5, 0xB349, 0x86C6, 0xB34A, 0x86CB, 0xB34B, 0x86B1,
+	0xB34C, 0x86AF, 0xB34D, 0x86C9, 0xB34E, 0x8853, 0xB34F, 0x889E,
+	0xB350, 0x8888, 0xB351, 0x88AB, 0xB352, 0x8892, 0xB353, 0x8896,
+	0xB354, 0x888D, 0xB355, 0x888B, 0xB356, 0x8993, 0xB357, 0x898F,
+	0xB358, 0x8A2A, 0xB359, 0x8A1D, 0xB35A, 0x8A23, 0xB35B, 0x8A25,
+	0xB35C, 0x8A31, 0xB35D, 0x8A2D, 0xB35E, 0x8A1F, 0xB35F, 0x8A1B,
+	0xB360, 0x8A22, 0xB361, 0x8C49, 0xB362, 0x8C5A, 0xB363, 0x8CA9,
+	0xB364, 0x8CAC, 0xB365, 0x8CAB, 0xB366, 0x8CA8, 0xB367, 0x8CAA,
+	0xB368, 0x8CA7, 0xB369, 0x8D67, 0xB36A, 0x8D66, 0xB36B, 0x8DBE,
+	0xB36C, 0x8DBA, 0xB36D, 0x8EDB, 0xB36E, 0x8EDF, 0xB36F, 0x9019,
+	0xB370, 0x900D, 0xB371, 0x901A, 0xB372, 0x9017, 0xB373, 0x9023,
+	0xB374, 0x901F, 0xB375, 0x901D, 0xB376, 0x9010, 0xB377, 0x9015,
+	0xB378, 0x901E, 0xB379, 0x9020, 0xB37A, 0x900F, 0xB37B, 0x9022,
+	0xB37C, 0x9016, 0xB37D, 0x901B, 0xB37E, 0x9014, 0xB3A1, 0x90E8,
+	0xB3A2, 0x90ED, 0xB3A3, 0x90FD, 0xB3A4, 0x9157, 0xB3A5, 0x91CE,
+	0xB3A6, 0x91F5, 0xB3A7, 0x91E6, 0xB3A8, 0x91E3, 0xB3A9, 0x91E7,
+	0xB3AA, 0x91ED, 0xB3AB, 0x91E9, 0xB3AC, 0x9589, 0xB3AD, 0x966A,
+	0xB3AE, 0x9675, 0xB3AF, 0x9673, 0xB3B0, 0x9678, 0xB3B1, 0x9670,
+	0xB3B2, 0x9674, 0xB3B3, 0x9676, 0xB3B4, 0x9677, 0xB3B5, 0x966C,
+	0xB3B6, 0x96C0, 0xB3B7, 0x96EA, 0xB3B8, 0x96E9, 0xB3B9, 0x7AE0,
+	0xB3BA, 0x7ADF, 0xB3BB, 0x9802, 0xB3BC, 0x9803, 0xB3BD, 0x9B5A,
+	0xB3BE, 0x9CE5, 0xB3BF, 0x9E75, 0xB3C0, 0x9E7F, 0xB3C1, 0x9EA5,
+	0xB3C2, 0x9EBB, 0xB3C3, 0x50A2, 0xB3C4, 0x508D, 0xB3C5, 0x5085,
+	0xB3C6, 0x5099, 0xB3C7, 0x5091, 0xB3C8, 0x5080, 0xB3C9, 0x5096,
+	0xB3CA, 0x5098, 0xB3CB, 0x509A, 0xB3CC, 0x6700, 0xB3CD, 0x51F1,
+	0xB3CE, 0x5272, 0xB3CF, 0x5274, 0xB3D0, 0x5275, 0xB3D1, 0x5269,
+	0xB3D2, 0x52DE, 0xB3D3, 0x52DD, 0xB3D4, 0x52DB, 0xB3D5, 0x535A,
+	0xB3D6, 0x53A5, 0xB3D7, 0x557B, 0xB3D8, 0x5580, 0xB3D9, 0x55A7,
+	0xB3DA, 0x557C, 0xB3DB, 0x558A, 0xB3DC, 0x559D, 0xB3DD, 0x5598,
+	0xB3DE, 0x5582, 0xB3DF, 0x559C, 0xB3E0, 0x55AA, 0xB3E1, 0x5594,
+	0xB3E2, 0x5587, 0xB3E3, 0x558B, 0xB3E4, 0x5583, 0xB3E5, 0x55B3,
+	0xB3E6, 0x55AE, 0xB3E7, 0x559F, 0xB3E8, 0x553E, 0xB3E9, 0x55B2,
+	0xB3EA, 0x559A, 0xB3EB, 0x55BB, 0xB3EC, 0x55AC, 0xB3ED, 0x55B1,
+	0xB3EE, 0x557E, 0xB3EF, 0x5589, 0xB3F0, 0x55AB, 0xB3F1, 0x5599,
+	0xB3F2, 0x570D, 0xB3F3, 0x582F, 0xB3F4, 0x582A, 0xB3F5, 0x5834,
+	0xB3F6, 0x5824, 0xB3F7, 0x5830, 0xB3F8, 0x5831, 0xB3F9, 0x5821,
+	0xB3FA, 0x581D, 0xB3FB, 0x5820, 0xB3FC, 0x58F9, 0xB3FD, 0x58FA,
+	0xB3FE, 0x5960, 0xB440, 0x5A77, 0xB441, 0x5A9A, 0xB442, 0x5A7F,
+	0xB443, 0x5A92, 0xB444, 0x5A9B, 0xB445, 0x5AA7, 0xB446, 0x5B73,
+	0xB447, 0x5B71, 0xB448, 0x5BD2, 0xB449, 0x5BCC, 0xB44A, 0x5BD3,
+	0xB44B, 0x5BD0, 0xB44C, 0x5C0A, 0xB44D, 0x5C0B, 0xB44E, 0x5C31,
+	0xB44F, 0x5D4C, 0xB450, 0x5D50, 0xB451, 0x5D34, 0xB452, 0x5D47,
+	0xB453, 0x5DFD, 0xB454, 0x5E45, 0xB455, 0x5E3D, 0xB456, 0x5E40,
+	0xB457, 0x5E43, 0xB458, 0x5E7E, 0xB459, 0x5ECA, 0xB45A, 0x5EC1,
+	0xB45B, 0x5EC2, 0xB45C, 0x5EC4, 0xB45D, 0x5F3C, 0xB45E, 0x5F6D,
+	0xB45F, 0x5FA9, 0xB460, 0x5FAA, 0xB461, 0x5FA8, 0xB462, 0x60D1,
+	0xB463, 0x60E1, 0xB464, 0x60B2, 0xB465, 0x60B6, 0xB466, 0x60E0,
+	0xB467, 0x611C, 0xB468, 0x6123, 0xB469, 0x60FA, 0xB46A, 0x6115,
+	0xB46B, 0x60F0, 0xB46C, 0x60FB, 0xB46D, 0x60F4, 0xB46E, 0x6168,
+	0xB46F, 0x60F1, 0xB470, 0x610E, 0xB471, 0x60F6, 0xB472, 0x6109,
+	0xB473, 0x6100, 0xB474, 0x6112, 0xB475, 0x621F, 0xB476, 0x6249,
+	0xB477, 0x63A3, 0xB478, 0x638C, 0xB479, 0x63CF, 0xB47A, 0x63C0,
+	0xB47B, 0x63E9, 0xB47C, 0x63C9, 0xB47D, 0x63C6, 0xB47E, 0x63CD,
+	0xB4A1, 0x63D2, 0xB4A2, 0x63E3, 0xB4A3, 0x63D0, 0xB4A4, 0x63E1,
+	0xB4A5, 0x63D6, 0xB4A6, 0x63ED, 0xB4A7, 0x63EE, 0xB4A8, 0x6376,
+	0xB4A9, 0x63F4, 0xB4AA, 0x63EA, 0xB4AB, 0x63DB, 0xB4AC, 0x6452,
+	0xB4AD, 0x63DA, 0xB4AE, 0x63F9, 0xB4AF, 0x655E, 0xB4B0, 0x6566,
+	0xB4B1, 0x6562, 0xB4B2, 0x6563, 0xB4B3, 0x6591, 0xB4B4, 0x6590,
+	0xB4B5, 0x65AF, 0xB4B6, 0x666E, 0xB4B7, 0x6670, 0xB4B8, 0x6674,
+	0xB4B9, 0x6676, 0xB4BA, 0x666F, 0xB4BB, 0x6691, 0xB4BC, 0x667A,
+	0xB4BD, 0x667E, 0xB4BE, 0x6677, 0xB4BF, 0x66FE, 0xB4C0, 0x66FF,
+	0xB4C1, 0x671F, 0xB4C2, 0x671D, 0xB4C3, 0x68FA, 0xB4C4, 0x68D5,
+	0xB4C5, 0x68E0, 0xB4C6, 0x68D8, 0xB4C7, 0x68D7, 0xB4C8, 0x6905,
+	0xB4C9, 0x68DF, 0xB4CA, 0x68F5, 0xB4CB, 0x68EE, 0xB4CC, 0x68E7,
+	0xB4CD, 0x68F9, 0xB4CE, 0x68D2, 0xB4CF, 0x68F2, 0xB4D0, 0x68E3,
+	0xB4D1, 0x68CB, 0xB4D2, 0x68CD, 0xB4D3, 0x690D, 0xB4D4, 0x6912,
+	0xB4D5, 0x690E, 0xB4D6, 0x68C9, 0xB4D7, 0x68DA, 0xB4D8, 0x696E,
+	0xB4D9, 0x68FB, 0xB4DA, 0x6B3E, 0xB4DB, 0x6B3A, 0xB4DC, 0x6B3D,
+	0xB4DD, 0x6B98, 0xB4DE, 0x6B96, 0xB4DF, 0x6BBC, 0xB4E0, 0x6BEF,
+	0xB4E1, 0x6C2E, 0xB4E2, 0x6C2F, 0xB4E3, 0x6C2C, 0xB4E4, 0x6E2F,
+	0xB4E5, 0x6E38, 0xB4E6, 0x6E54, 0xB4E7, 0x6E21, 0xB4E8, 0x6E32,
+	0xB4E9, 0x6E67, 0xB4EA, 0x6E4A, 0xB4EB, 0x6E20, 0xB4EC, 0x6E25,
+	0xB4ED, 0x6E23, 0xB4EE, 0x6E1B, 0xB4EF, 0x6E5B, 0xB4F0, 0x6E58,
+	0xB4F1, 0x6E24, 0xB4F2, 0x6E56, 0xB4F3, 0x6E6E, 0xB4F4, 0x6E2D,
+	0xB4F5, 0x6E26, 0xB4F6, 0x6E6F, 0xB4F7, 0x6E34, 0xB4F8, 0x6E4D,
+	0xB4F9, 0x6E3A, 0xB4FA, 0x6E2C, 0xB4FB, 0x6E43, 0xB4FC, 0x6E1D,
+	0xB4FD, 0x6E3E, 0xB4FE, 0x6ECB, 0xB540, 0x6E89, 0xB541, 0x6E19,
+	0xB542, 0x6E4E, 0xB543, 0x6E63, 0xB544, 0x6E44, 0xB545, 0x6E72,
+	0xB546, 0x6E69, 0xB547, 0x6E5F, 0xB548, 0x7119, 0xB549, 0x711A,
+	0xB54A, 0x7126, 0xB54B, 0x7130, 0xB54C, 0x7121, 0xB54D, 0x7136,
+	0xB54E, 0x716E, 0xB54F, 0x711C, 0xB550, 0x724C, 0xB551, 0x7284,
+	0xB552, 0x7280, 0xB553, 0x7336, 0xB554, 0x7325, 0xB555, 0x7334,
+	0xB556, 0x7329, 0xB557, 0x743A, 0xB558, 0x742A, 0xB559, 0x7433,
+	0xB55A, 0x7422, 0xB55B, 0x7425, 0xB55C, 0x7435, 0xB55D, 0x7436,
+	0xB55E, 0x7434, 0xB55F, 0x742F, 0xB560, 0x741B, 0xB561, 0x7426,
+	0xB562, 0x7428, 0xB563, 0x7525, 0xB564, 0x7526, 0xB565, 0x756B,
+	0xB566, 0x756A, 0xB567, 0x75E2, 0xB568, 0x75DB, 0xB569, 0x75E3,
+	0xB56A, 0x75D9, 0xB56B, 0x75D8, 0xB56C, 0x75DE, 0xB56D, 0x75E0,
+	0xB56E, 0x767B, 0xB56F, 0x767C, 0xB570, 0x7696, 0xB571, 0x7693,
+	0xB572, 0x76B4, 0xB573, 0x76DC, 0xB574, 0x774F, 0xB575, 0x77ED,
+	0xB576, 0x785D, 0xB577, 0x786C, 0xB578, 0x786F, 0xB579, 0x7A0D,
+	0xB57A, 0x7A08, 0xB57B, 0x7A0B, 0xB57C, 0x7A05, 0xB57D, 0x7A00,
+	0xB57E, 0x7A98, 0xB5A1, 0x7A97, 0xB5A2, 0x7A96, 0xB5A3, 0x7AE5,
+	0xB5A4, 0x7AE3, 0xB5A5, 0x7B49, 0xB5A6, 0x7B56, 0xB5A7, 0x7B46,
+	0xB5A8, 0x7B50, 0xB5A9, 0x7B52, 0xB5AA, 0x7B54, 0xB5AB, 0x7B4D,
+	0xB5AC, 0x7B4B, 0xB5AD, 0x7B4F, 0xB5AE, 0x7B51, 0xB5AF, 0x7C9F,
+	0xB5B0, 0x7CA5, 0xB5B1, 0x7D5E, 0xB5B2, 0x7D50, 0xB5B3, 0x7D68,
+	0xB5B4, 0x7D55, 0xB5B5, 0x7D2B, 0xB5B6, 0x7D6E, 0xB5B7, 0x7D72,
+	0xB5B8, 0x7D61, 0xB5B9, 0x7D66, 0xB5BA, 0x7D62, 0xB5BB, 0x7D70,
+	0xB5BC, 0x7D73, 0xB5BD, 0x5584, 0xB5BE, 0x7FD4, 0xB5BF, 0x7FD5,
+	0xB5C0, 0x800B, 0xB5C1, 0x8052, 0xB5C2, 0x8085, 0xB5C3, 0x8155,
+	0xB5C4, 0x8154, 0xB5C5, 0x814B, 0xB5C6, 0x8151, 0xB5C7, 0x814E,
+	0xB5C8, 0x8139, 0xB5C9, 0x8146, 0xB5CA, 0x813E, 0xB5CB, 0x814C,
+	0xB5CC, 0x8153, 0xB5CD, 0x8174, 0xB5CE, 0x8212, 0xB5CF, 0x821C,
+	0xB5D0, 0x83E9, 0xB5D1, 0x8403, 0xB5D2, 0x83F8, 0xB5D3, 0x840D,
+	0xB5D4, 0x83E0, 0xB5D5, 0x83C5, 0xB5D6, 0x840B, 0xB5D7, 0x83C1,
+	0xB5D8, 0x83EF, 0xB5D9, 0x83F1, 0xB5DA, 0x83F4, 0xB5DB, 0x8457,
+	0xB5DC, 0x840A, 0xB5DD, 0x83F0, 0xB5DE, 0x840C, 0xB5DF, 0x83CC,
+	0xB5E0, 0x83FD, 0xB5E1, 0x83F2, 0xB5E2, 0x83CA, 0xB5E3, 0x8438,
+	0xB5E4, 0x840E, 0xB5E5, 0x8404, 0xB5E6, 0x83DC, 0xB5E7, 0x8407,
+	0xB5E8, 0x83D4, 0xB5E9, 0x83DF, 0xB5EA, 0x865B, 0xB5EB, 0x86DF,
+	0xB5EC, 0x86D9, 0xB5ED, 0x86ED, 0xB5EE, 0x86D4, 0xB5EF, 0x86DB,
+	0xB5F0, 0x86E4, 0xB5F1, 0x86D0, 0xB5F2, 0x86DE, 0xB5F3, 0x8857,
+	0xB5F4, 0x88C1, 0xB5F5, 0x88C2, 0xB5F6, 0x88B1, 0xB5F7, 0x8983,
+	0xB5F8, 0x8996, 0xB5F9, 0x8A3B, 0xB5FA, 0x8A60, 0xB5FB, 0x8A55,
+	0xB5FC, 0x8A5E, 0xB5FD, 0x8A3C, 0xB5FE, 0x8A41, 0xB640, 0x8A54,
+	0xB641, 0x8A5B, 0xB642, 0x8A50, 0xB643, 0x8A46, 0xB644, 0x8A34,
+	0xB645, 0x8A3A, 0xB646, 0x8A36, 0xB647, 0x8A56, 0xB648, 0x8C61,
+	0xB649, 0x8C82, 0xB64A, 0x8CAF, 0xB64B, 0x8CBC, 0xB64C, 0x8CB3,
+	0xB64D, 0x8CBD, 0xB64E, 0x8CC1, 0xB64F, 0x8CBB, 0xB650, 0x8CC0,
+	0xB651, 0x8CB4, 0xB652, 0x8CB7, 0xB653, 0x8CB6, 0xB654, 0x8CBF,
+	0xB655, 0x8CB8, 0xB656, 0x8D8A, 0xB657, 0x8D85, 0xB658, 0x8D81,
+	0xB659, 0x8DCE, 0xB65A, 0x8DDD, 0xB65B, 0x8DCB, 0xB65C, 0x8DDA,
+	0xB65D, 0x8DD1, 0xB65E, 0x8DCC, 0xB65F, 0x8DDB, 0xB660, 0x8DC6,
+	0xB661, 0x8EFB, 0xB662, 0x8EF8, 0xB663, 0x8EFC, 0xB664, 0x8F9C,
+	0xB665, 0x902E, 0xB666, 0x9035, 0xB667, 0x9031, 0xB668, 0x9038,
+	0xB669, 0x9032, 0xB66A, 0x9036, 0xB66B, 0x9102, 0xB66C, 0x90F5,
+	0xB66D, 0x9109, 0xB66E, 0x90FE, 0xB66F, 0x9163, 0xB670, 0x9165,
+	0xB671, 0x91CF, 0xB672, 0x9214, 0xB673, 0x9215, 0xB674, 0x9223,
+	0xB675, 0x9209, 0xB676, 0x921E, 0xB677, 0x920D, 0xB678, 0x9210,
+	0xB679, 0x9207, 0xB67A, 0x9211, 0xB67B, 0x9594, 0xB67C, 0x958F,
+	0xB67D, 0x958B, 0xB67E, 0x9591, 0xB6A1, 0x9593, 0xB6A2, 0x9592,
+	0xB6A3, 0x958E, 0xB6A4, 0x968A, 0xB6A5, 0x968E, 0xB6A6, 0x968B,
+	0xB6A7, 0x967D, 0xB6A8, 0x9685, 0xB6A9, 0x9686, 0xB6AA, 0x968D,
+	0xB6AB, 0x9672, 0xB6AC, 0x9684, 0xB6AD, 0x96C1, 0xB6AE, 0x96C5,
+	0xB6AF, 0x96C4, 0xB6B0, 0x96C6, 0xB6B1, 0x96C7, 0xB6B2, 0x96EF,
+	0xB6B3, 0x96F2, 0xB6B4, 0x97CC, 0xB6B5, 0x9805, 0xB6B6, 0x9806,
+	0xB6B7, 0x9808, 0xB6B8, 0x98E7, 0xB6B9, 0x98EA, 0xB6BA, 0x98EF,
+	0xB6BB, 0x98E9, 0xB6BC, 0x98F2, 0xB6BD, 0x98ED, 0xB6BE, 0x99AE,
+	0xB6BF, 0x99AD, 0xB6C0, 0x9EC3, 0xB6C1, 0x9ECD, 0xB6C2, 0x9ED1,
+	0xB6C3, 0x4E82, 0xB6C4, 0x50AD, 0xB6C5, 0x50B5, 0xB6C6, 0x50B2,
+	0xB6C7, 0x50B3, 0xB6C8, 0x50C5, 0xB6C9, 0x50BE, 0xB6CA, 0x50AC,
+	0xB6CB, 0x50B7, 0xB6CC, 0x50BB, 0xB6CD, 0x50AF, 0xB6CE, 0x50C7,
+	0xB6CF, 0x527F, 0xB6D0, 0x5277, 0xB6D1, 0x527D, 0xB6D2, 0x52DF,
+	0xB6D3, 0x52E6, 0xB6D4, 0x52E4, 0xB6D5, 0x52E2, 0xB6D6, 0x52E3,
+	0xB6D7, 0x532F, 0xB6D8, 0x55DF, 0xB6D9, 0x55E8, 0xB6DA, 0x55D3,
+	0xB6DB, 0x55E6, 0xB6DC, 0x55CE, 0xB6DD, 0x55DC, 0xB6DE, 0x55C7,
+	0xB6DF, 0x55D1, 0xB6E0, 0x55E3, 0xB6E1, 0x55E4, 0xB6E2, 0x55EF,
+	0xB6E3, 0x55DA, 0xB6E4, 0x55E1, 0xB6E5, 0x55C5, 0xB6E6, 0x55C6,
+	0xB6E7, 0x55E5, 0xB6E8, 0x55C9, 0xB6E9, 0x5712, 0xB6EA, 0x5713,
+	0xB6EB, 0x585E, 0xB6EC, 0x5851, 0xB6ED, 0x5858, 0xB6EE, 0x5857,
+	0xB6EF, 0x585A, 0xB6F0, 0x5854, 0xB6F1, 0x586B, 0xB6F2, 0x584C,
+	0xB6F3, 0x586D, 0xB6F4, 0x584A, 0xB6F5, 0x5862, 0xB6F6, 0x5852,
+	0xB6F7, 0x584B, 0xB6F8, 0x5967, 0xB6F9, 0x5AC1, 0xB6FA, 0x5AC9,
+	0xB6FB, 0x5ACC, 0xB6FC, 0x5ABE, 0xB6FD, 0x5ABD, 0xB6FE, 0x5ABC,
+	0xB740, 0x5AB3, 0xB741, 0x5AC2, 0xB742, 0x5AB2, 0xB743, 0x5D69,
+	0xB744, 0x5D6F, 0xB745, 0x5E4C, 0xB746, 0x5E79, 0xB747, 0x5EC9,
+	0xB748, 0x5EC8, 0xB749, 0x5F12, 0xB74A, 0x5F59, 0xB74B, 0x5FAC,
+	0xB74C, 0x5FAE, 0xB74D, 0x611A, 0xB74E, 0x610F, 0xB74F, 0x6148,
+	0xB750, 0x611F, 0xB751, 0x60F3, 0xB752, 0x611B, 0xB753, 0x60F9,
+	0xB754, 0x6101, 0xB755, 0x6108, 0xB756, 0x614E, 0xB757, 0x614C,
+	0xB758, 0x6144, 0xB759, 0x614D, 0xB75A, 0x613E, 0xB75B, 0x6134,
+	0xB75C, 0x6127, 0xB75D, 0x610D, 0xB75E, 0x6106, 0xB75F, 0x6137,
+	0xB760, 0x6221, 0xB761, 0x6222, 0xB762, 0x6413, 0xB763, 0x643E,
+	0xB764, 0x641E, 0xB765, 0x642A, 0xB766, 0x642D, 0xB767, 0x643D,
+	0xB768, 0x642C, 0xB769, 0x640F, 0xB76A, 0x641C, 0xB76B, 0x6414,
+	0xB76C, 0x640D, 0xB76D, 0x6436, 0xB76E, 0x6416, 0xB76F, 0x6417,
+	0xB770, 0x6406, 0xB771, 0x656C, 0xB772, 0x659F, 0xB773, 0x65B0,
+	0xB774, 0x6697, 0xB775, 0x6689, 0xB776, 0x6687, 0xB777, 0x6688,
+	0xB778, 0x6696, 0xB779, 0x6684, 0xB77A, 0x6698, 0xB77B, 0x668D,
+	0xB77C, 0x6703, 0xB77D, 0x6994, 0xB77E, 0x696D, 0xB7A1, 0x695A,
+	0xB7A2, 0x6977, 0xB7A3, 0x6960, 0xB7A4, 0x6954, 0xB7A5, 0x6975,
+	0xB7A6, 0x6930, 0xB7A7, 0x6982, 0xB7A8, 0x694A, 0xB7A9, 0x6968,
+	0xB7AA, 0x696B, 0xB7AB, 0x695E, 0xB7AC, 0x6953, 0xB7AD, 0x6979,
+	0xB7AE, 0x6986, 0xB7AF, 0x695D, 0xB7B0, 0x6963, 0xB7B1, 0x695B,
+	0xB7B2, 0x6B47, 0xB7B3, 0x6B72, 0xB7B4, 0x6BC0, 0xB7B5, 0x6BBF,
+	0xB7B6, 0x6BD3, 0xB7B7, 0x6BFD, 0xB7B8, 0x6EA2, 0xB7B9, 0x6EAF,
+	0xB7BA, 0x6ED3, 0xB7BB, 0x6EB6, 0xB7BC, 0x6EC2, 0xB7BD, 0x6E90,
+	0xB7BE, 0x6E9D, 0xB7BF, 0x6EC7, 0xB7C0, 0x6EC5, 0xB7C1, 0x6EA5,
+	0xB7C2, 0x6E98, 0xB7C3, 0x6EBC, 0xB7C4, 0x6EBA, 0xB7C5, 0x6EAB,
+	0xB7C6, 0x6ED1, 0xB7C7, 0x6E96, 0xB7C8, 0x6E9C, 0xB7C9, 0x6EC4,
+	0xB7CA, 0x6ED4, 0xB7CB, 0x6EAA, 0xB7CC, 0x6EA7, 0xB7CD, 0x6EB4,
+	0xB7CE, 0x714E, 0xB7CF, 0x7159, 0xB7D0, 0x7169, 0xB7D1, 0x7164,
+	0xB7D2, 0x7149, 0xB7D3, 0x7167, 0xB7D4, 0x715C, 0xB7D5, 0x716C,
+	0xB7D6, 0x7166, 0xB7D7, 0x714C, 0xB7D8, 0x7165, 0xB7D9, 0x715E,
+	0xB7DA, 0x7146, 0xB7DB, 0x7168, 0xB7DC, 0x7156, 0xB7DD, 0x723A,
+	0xB7DE, 0x7252, 0xB7DF, 0x7337, 0xB7E0, 0x7345, 0xB7E1, 0x733F,
+	0xB7E2, 0x733E, 0xB7E3, 0x746F, 0xB7E4, 0x745A, 0xB7E5, 0x7455,
+	0xB7E6, 0x745F, 0xB7E7, 0x745E, 0xB7E8, 0x7441, 0xB7E9, 0x743F,
+	0xB7EA, 0x7459, 0xB7EB, 0x745B, 0xB7EC, 0x745C, 0xB7ED, 0x7576,
+	0xB7EE, 0x7578, 0xB7EF, 0x7600, 0xB7F0, 0x75F0, 0xB7F1, 0x7601,
+	0xB7F2, 0x75F2, 0xB7F3, 0x75F1, 0xB7F4, 0x75FA, 0xB7F5, 0x75FF,
+	0xB7F6, 0x75F4, 0xB7F7, 0x75F3, 0xB7F8, 0x76DE, 0xB7F9, 0x76DF,
+	0xB7FA, 0x775B, 0xB7FB, 0x776B, 0xB7FC, 0x7766, 0xB7FD, 0x775E,
+	0xB7FE, 0x7763, 0xB840, 0x7779, 0xB841, 0x776A, 0xB842, 0x776C,
+	0xB843, 0x775C, 0xB844, 0x7765, 0xB845, 0x7768, 0xB846, 0x7762,
+	0xB847, 0x77EE, 0xB848, 0x788E, 0xB849, 0x78B0, 0xB84A, 0x7897,
+	0xB84B, 0x7898, 0xB84C, 0x788C, 0xB84D, 0x7889, 0xB84E, 0x787C,
+	0xB84F, 0x7891, 0xB850, 0x7893, 0xB851, 0x787F, 0xB852, 0x797A,
+	0xB853, 0x797F, 0xB854, 0x7981, 0xB855, 0x842C, 0xB856, 0x79BD,
+	0xB857, 0x7A1C, 0xB858, 0x7A1A, 0xB859, 0x7A20, 0xB85A, 0x7A14,
+	0xB85B, 0x7A1F, 0xB85C, 0x7A1E, 0xB85D, 0x7A9F, 0xB85E, 0x7AA0,
+	0xB85F, 0x7B77, 0xB860, 0x7BC0, 0xB861, 0x7B60, 0xB862, 0x7B6E,
+	0xB863, 0x7B67, 0xB864, 0x7CB1, 0xB865, 0x7CB3, 0xB866, 0x7CB5,
+	0xB867, 0x7D93, 0xB868, 0x7D79, 0xB869, 0x7D91, 0xB86A, 0x7D81,
+	0xB86B, 0x7D8F, 0xB86C, 0x7D5B, 0xB86D, 0x7F6E, 0xB86E, 0x7F69,
+	0xB86F, 0x7F6A, 0xB870, 0x7F72, 0xB871, 0x7FA9, 0xB872, 0x7FA8,
+	0xB873, 0x7FA4, 0xB874, 0x8056, 0xB875, 0x8058, 0xB876, 0x8086,
+	0xB877, 0x8084, 0xB878, 0x8171, 0xB879, 0x8170, 0xB87A, 0x8178,
+	0xB87B, 0x8165, 0xB87C, 0x816E, 0xB87D, 0x8173, 0xB87E, 0x816B,
+	0xB8A1, 0x8179, 0xB8A2, 0x817A, 0xB8A3, 0x8166, 0xB8A4, 0x8205,
+	0xB8A5, 0x8247, 0xB8A6, 0x8482, 0xB8A7, 0x8477, 0xB8A8, 0x843D,
+	0xB8A9, 0x8431, 0xB8AA, 0x8475, 0xB8AB, 0x8466, 0xB8AC, 0x846B,
+	0xB8AD, 0x8449, 0xB8AE, 0x846C, 0xB8AF, 0x845B, 0xB8B0, 0x843C,
+	0xB8B1, 0x8435, 0xB8B2, 0x8461, 0xB8B3, 0x8463, 0xB8B4, 0x8469,
+	0xB8B5, 0x846D, 0xB8B6, 0x8446, 0xB8B7, 0x865E, 0xB8B8, 0x865C,
+	0xB8B9, 0x865F, 0xB8BA, 0x86F9, 0xB8BB, 0x8713, 0xB8BC, 0x8708,
+	0xB8BD, 0x8707, 0xB8BE, 0x8700, 0xB8BF, 0x86FE, 0xB8C0, 0x86FB,
+	0xB8C1, 0x8702, 0xB8C2, 0x8703, 0xB8C3, 0x8706, 0xB8C4, 0x870A,
+	0xB8C5, 0x8859, 0xB8C6, 0x88DF, 0xB8C7, 0x88D4, 0xB8C8, 0x88D9,
+	0xB8C9, 0x88DC, 0xB8CA, 0x88D8, 0xB8CB, 0x88DD, 0xB8CC, 0x88E1,
+	0xB8CD, 0x88CA, 0xB8CE, 0x88D5, 0xB8CF, 0x88D2, 0xB8D0, 0x899C,
+	0xB8D1, 0x89E3, 0xB8D2, 0x8A6B, 0xB8D3, 0x8A72, 0xB8D4, 0x8A73,
+	0xB8D5, 0x8A66, 0xB8D6, 0x8A69, 0xB8D7, 0x8A70, 0xB8D8, 0x8A87,
+	0xB8D9, 0x8A7C, 0xB8DA, 0x8A63, 0xB8DB, 0x8AA0, 0xB8DC, 0x8A71,
+	0xB8DD, 0x8A85, 0xB8DE, 0x8A6D, 0xB8DF, 0x8A62, 0xB8E0, 0x8A6E,
+	0xB8E1, 0x8A6C, 0xB8E2, 0x8A79, 0xB8E3, 0x8A7B, 0xB8E4, 0x8A3E,
+	0xB8E5, 0x8A68, 0xB8E6, 0x8C62, 0xB8E7, 0x8C8A, 0xB8E8, 0x8C89,
+	0xB8E9, 0x8CCA, 0xB8EA, 0x8CC7, 0xB8EB, 0x8CC8, 0xB8EC, 0x8CC4,
+	0xB8ED, 0x8CB2, 0xB8EE, 0x8CC3, 0xB8EF, 0x8CC2, 0xB8F0, 0x8CC5,
+	0xB8F1, 0x8DE1, 0xB8F2, 0x8DDF, 0xB8F3, 0x8DE8, 0xB8F4, 0x8DEF,
+	0xB8F5, 0x8DF3, 0xB8F6, 0x8DFA, 0xB8F7, 0x8DEA, 0xB8F8, 0x8DE4,
+	0xB8F9, 0x8DE6, 0xB8FA, 0x8EB2, 0xB8FB, 0x8F03, 0xB8FC, 0x8F09,
+	0xB8FD, 0x8EFE, 0xB8FE, 0x8F0A, 0xB940, 0x8F9F, 0xB941, 0x8FB2,
+	0xB942, 0x904B, 0xB943, 0x904A, 0xB944, 0x9053, 0xB945, 0x9042,
+	0xB946, 0x9054, 0xB947, 0x903C, 0xB948, 0x9055, 0xB949, 0x9050,
+	0xB94A, 0x9047, 0xB94B, 0x904F, 0xB94C, 0x904E, 0xB94D, 0x904D,
+	0xB94E, 0x9051, 0xB94F, 0x903E, 0xB950, 0x9041, 0xB951, 0x9112,
+	0xB952, 0x9117, 0xB953, 0x916C, 0xB954, 0x916A, 0xB955, 0x9169,
+	0xB956, 0x91C9, 0xB957, 0x9237, 0xB958, 0x9257, 0xB959, 0x9238,
+	0xB95A, 0x923D, 0xB95B, 0x9240, 0xB95C, 0x923E, 0xB95D, 0x925B,
+	0xB95E, 0x924B, 0xB95F, 0x9264, 0xB960, 0x9251, 0xB961, 0x9234,
+	0xB962, 0x9249, 0xB963, 0x924D, 0xB964, 0x9245, 0xB965, 0x9239,
+	0xB966, 0x923F, 0xB967, 0x925A, 0xB968, 0x9598, 0xB969, 0x9698,
+	0xB96A, 0x9694, 0xB96B, 0x9695, 0xB96C, 0x96CD, 0xB96D, 0x96CB,
+	0xB96E, 0x96C9, 0xB96F, 0x96CA, 0xB970, 0x96F7, 0xB971, 0x96FB,
+	0xB972, 0x96F9, 0xB973, 0x96F6, 0xB974, 0x9756, 0xB975, 0x9774,
+	0xB976, 0x9776, 0xB977, 0x9810, 0xB978, 0x9811, 0xB979, 0x9813,
+	0xB97A, 0x980A, 0xB97B, 0x9812, 0xB97C, 0x980C, 0xB97D, 0x98FC,
+	0xB97E, 0x98F4, 0xB9A1, 0x98FD, 0xB9A2, 0x98FE, 0xB9A3, 0x99B3,
+	0xB9A4, 0x99B1, 0xB9A5, 0x99B4, 0xB9A6, 0x9AE1, 0xB9A7, 0x9CE9,
+	0xB9A8, 0x9E82, 0xB9A9, 0x9F0E, 0xB9AA, 0x9F13, 0xB9AB, 0x9F20,
+	0xB9AC, 0x50E7, 0xB9AD, 0x50EE, 0xB9AE, 0x50E5, 0xB9AF, 0x50D6,
+	0xB9B0, 0x50ED, 0xB9B1, 0x50DA, 0xB9B2, 0x50D5, 0xB9B3, 0x50CF,
+	0xB9B4, 0x50D1, 0xB9B5, 0x50F1, 0xB9B6, 0x50CE, 0xB9B7, 0x50E9,
+	0xB9B8, 0x5162, 0xB9B9, 0x51F3, 0xB9BA, 0x5283, 0xB9BB, 0x5282,
+	0xB9BC, 0x5331, 0xB9BD, 0x53AD, 0xB9BE, 0x55FE, 0xB9BF, 0x5600,
+	0xB9C0, 0x561B, 0xB9C1, 0x5617, 0xB9C2, 0x55FD, 0xB9C3, 0x5614,
+	0xB9C4, 0x5606, 0xB9C5, 0x5609, 0xB9C6, 0x560D, 0xB9C7, 0x560E,
+	0xB9C8, 0x55F7, 0xB9C9, 0x5616, 0xB9CA, 0x561F, 0xB9CB, 0x5608,
+	0xB9CC, 0x5610, 0xB9CD, 0x55F6, 0xB9CE, 0x5718, 0xB9CF, 0x5716,
+	0xB9D0, 0x5875, 0xB9D1, 0x587E, 0xB9D2, 0x5883, 0xB9D3, 0x5893,
+	0xB9D4, 0x588A, 0xB9D5, 0x5879, 0xB9D6, 0x5885, 0xB9D7, 0x587D,
+	0xB9D8, 0x58FD, 0xB9D9, 0x5925, 0xB9DA, 0x5922, 0xB9DB, 0x5924,
+	0xB9DC, 0x596A, 0xB9DD, 0x5969, 0xB9DE, 0x5AE1, 0xB9DF, 0x5AE6,
+	0xB9E0, 0x5AE9, 0xB9E1, 0x5AD7, 0xB9E2, 0x5AD6, 0xB9E3, 0x5AD8,
+	0xB9E4, 0x5AE3, 0xB9E5, 0x5B75, 0xB9E6, 0x5BDE, 0xB9E7, 0x5BE7,
+	0xB9E8, 0x5BE1, 0xB9E9, 0x5BE5, 0xB9EA, 0x5BE6, 0xB9EB, 0x5BE8,
+	0xB9EC, 0x5BE2, 0xB9ED, 0x5BE4, 0xB9EE, 0x5BDF, 0xB9EF, 0x5C0D,
+	0xB9F0, 0x5C62, 0xB9F1, 0x5D84, 0xB9F2, 0x5D87, 0xB9F3, 0x5E5B,
+	0xB9F4, 0x5E63, 0xB9F5, 0x5E55, 0xB9F6, 0x5E57, 0xB9F7, 0x5E54,
+	0xB9F8, 0x5ED3, 0xB9F9, 0x5ED6, 0xB9FA, 0x5F0A, 0xB9FB, 0x5F46,
+	0xB9FC, 0x5F70, 0xB9FD, 0x5FB9, 0xB9FE, 0x6147, 0xBA40, 0x613F,
+	0xBA41, 0x614B, 0xBA42, 0x6177, 0xBA43, 0x6162, 0xBA44, 0x6163,
+	0xBA45, 0x615F, 0xBA46, 0x615A, 0xBA47, 0x6158, 0xBA48, 0x6175,
+	0xBA49, 0x622A, 0xBA4A, 0x6487, 0xBA4B, 0x6458, 0xBA4C, 0x6454,
+	0xBA4D, 0x64A4, 0xBA4E, 0x6478, 0xBA4F, 0x645F, 0xBA50, 0x647A,
+	0xBA51, 0x6451, 0xBA52, 0x6467, 0xBA53, 0x6434, 0xBA54, 0x646D,
+	0xBA55, 0x647B, 0xBA56, 0x6572, 0xBA57, 0x65A1, 0xBA58, 0x65D7,
+	0xBA59, 0x65D6, 0xBA5A, 0x66A2, 0xBA5B, 0x66A8, 0xBA5C, 0x669D,
+	0xBA5D, 0x699C, 0xBA5E, 0x69A8, 0xBA5F, 0x6995, 0xBA60, 0x69C1,
+	0xBA61, 0x69AE, 0xBA62, 0x69D3, 0xBA63, 0x69CB, 0xBA64, 0x699B,
+	0xBA65, 0x69B7, 0xBA66, 0x69BB, 0xBA67, 0x69AB, 0xBA68, 0x69B4,
+	0xBA69, 0x69D0, 0xBA6A, 0x69CD, 0xBA6B, 0x69AD, 0xBA6C, 0x69CC,
+	0xBA6D, 0x69A6, 0xBA6E, 0x69C3, 0xBA6F, 0x69A3, 0xBA70, 0x6B49,
+	0xBA71, 0x6B4C, 0xBA72, 0x6C33, 0xBA73, 0x6F33, 0xBA74, 0x6F14,
+	0xBA75, 0x6EFE, 0xBA76, 0x6F13, 0xBA77, 0x6EF4, 0xBA78, 0x6F29,
+	0xBA79, 0x6F3E, 0xBA7A, 0x6F20, 0xBA7B, 0x6F2C, 0xBA7C, 0x6F0F,
+	0xBA7D, 0x6F02, 0xBA7E, 0x6F22, 0xBAA1, 0x6EFF, 0xBAA2, 0x6EEF,
+	0xBAA3, 0x6F06, 0xBAA4, 0x6F31, 0xBAA5, 0x6F38, 0xBAA6, 0x6F32,
+	0xBAA7, 0x6F23, 0xBAA8, 0x6F15, 0xBAA9, 0x6F2B, 0xBAAA, 0x6F2F,
+	0xBAAB, 0x6F88, 0xBAAC, 0x6F2A, 0xBAAD, 0x6EEC, 0xBAAE, 0x6F01,
+	0xBAAF, 0x6EF2, 0xBAB0, 0x6ECC, 0xBAB1, 0x6EF7, 0xBAB2, 0x7194,
+	0xBAB3, 0x7199, 0xBAB4, 0x717D, 0xBAB5, 0x718A, 0xBAB6, 0x7184,
+	0xBAB7, 0x7192, 0xBAB8, 0x723E, 0xBAB9, 0x7292, 0xBABA, 0x7296,
+	0xBABB, 0x7344, 0xBABC, 0x7350, 0xBABD, 0x7464, 0xBABE, 0x7463,
+	0xBABF, 0x746A, 0xBAC0, 0x7470, 0xBAC1, 0x746D, 0xBAC2, 0x7504,
+	0xBAC3, 0x7591, 0xBAC4, 0x7627, 0xBAC5, 0x760D, 0xBAC6, 0x760B,
+	0xBAC7, 0x7609, 0xBAC8, 0x7613, 0xBAC9, 0x76E1, 0xBACA, 0x76E3,
+	0xBACB, 0x7784, 0xBACC, 0x777D, 0xBACD, 0x777F, 0xBACE, 0x7761,
+	0xBACF, 0x78C1, 0xBAD0, 0x789F, 0xBAD1, 0x78A7, 0xBAD2, 0x78B3,
+	0xBAD3, 0x78A9, 0xBAD4, 0x78A3, 0xBAD5, 0x798E, 0xBAD6, 0x798F,
+	0xBAD7, 0x798D, 0xBAD8, 0x7A2E, 0xBAD9, 0x7A31, 0xBADA, 0x7AAA,
+	0xBADB, 0x7AA9, 0xBADC, 0x7AED, 0xBADD, 0x7AEF, 0xBADE, 0x7BA1,
+	0xBADF, 0x7B95, 0xBAE0, 0x7B8B, 0xBAE1, 0x7B75, 0xBAE2, 0x7B97,
+	0xBAE3, 0x7B9D, 0xBAE4, 0x7B94, 0xBAE5, 0x7B8F, 0xBAE6, 0x7BB8,
+	0xBAE7, 0x7B87, 0xBAE8, 0x7B84, 0xBAE9, 0x7CB9, 0xBAEA, 0x7CBD,
+	0xBAEB, 0x7CBE, 0xBAEC, 0x7DBB, 0xBAED, 0x7DB0, 0xBAEE, 0x7D9C,
+	0xBAEF, 0x7DBD, 0xBAF0, 0x7DBE, 0xBAF1, 0x7DA0, 0xBAF2, 0x7DCA,
+	0xBAF3, 0x7DB4, 0xBAF4, 0x7DB2, 0xBAF5, 0x7DB1, 0xBAF6, 0x7DBA,
+	0xBAF7, 0x7DA2, 0xBAF8, 0x7DBF, 0xBAF9, 0x7DB5, 0xBAFA, 0x7DB8,
+	0xBAFB, 0x7DAD, 0xBAFC, 0x7DD2, 0xBAFD, 0x7DC7, 0xBAFE, 0x7DAC,
+	0xBB40, 0x7F70, 0xBB41, 0x7FE0, 0xBB42, 0x7FE1, 0xBB43, 0x7FDF,
+	0xBB44, 0x805E, 0xBB45, 0x805A, 0xBB46, 0x8087, 0xBB47, 0x8150,
+	0xBB48, 0x8180, 0xBB49, 0x818F, 0xBB4A, 0x8188, 0xBB4B, 0x818A,
+	0xBB4C, 0x817F, 0xBB4D, 0x8182, 0xBB4E, 0x81E7, 0xBB4F, 0x81FA,
+	0xBB50, 0x8207, 0xBB51, 0x8214, 0xBB52, 0x821E, 0xBB53, 0x824B,
+	0xBB54, 0x84C9, 0xBB55, 0x84BF, 0xBB56, 0x84C6, 0xBB57, 0x84C4,
+	0xBB58, 0x8499, 0xBB59, 0x849E, 0xBB5A, 0x84B2, 0xBB5B, 0x849C,
+	0xBB5C, 0x84CB, 0xBB5D, 0x84B8, 0xBB5E, 0x84C0, 0xBB5F, 0x84D3,
+	0xBB60, 0x8490, 0xBB61, 0x84BC, 0xBB62, 0x84D1, 0xBB63, 0x84CA,
+	0xBB64, 0x873F, 0xBB65, 0x871C, 0xBB66, 0x873B, 0xBB67, 0x8722,
+	0xBB68, 0x8725, 0xBB69, 0x8734, 0xBB6A, 0x8718, 0xBB6B, 0x8755,
+	0xBB6C, 0x8737, 0xBB6D, 0x8729, 0xBB6E, 0x88F3, 0xBB6F, 0x8902,
+	0xBB70, 0x88F4, 0xBB71, 0x88F9, 0xBB72, 0x88F8, 0xBB73, 0x88FD,
+	0xBB74, 0x88E8, 0xBB75, 0x891A, 0xBB76, 0x88EF, 0xBB77, 0x8AA6,
+	0xBB78, 0x8A8C, 0xBB79, 0x8A9E, 0xBB7A, 0x8AA3, 0xBB7B, 0x8A8D,
+	0xBB7C, 0x8AA1, 0xBB7D, 0x8A93, 0xBB7E, 0x8AA4, 0xBBA1, 0x8AAA,
+	0xBBA2, 0x8AA5, 0xBBA3, 0x8AA8, 0xBBA4, 0x8A98, 0xBBA5, 0x8A91,
+	0xBBA6, 0x8A9A, 0xBBA7, 0x8AA7, 0xBBA8, 0x8C6A, 0xBBA9, 0x8C8D,
+	0xBBAA, 0x8C8C, 0xBBAB, 0x8CD3, 0xBBAC, 0x8CD1, 0xBBAD, 0x8CD2,
+	0xBBAE, 0x8D6B, 0xBBAF, 0x8D99, 0xBBB0, 0x8D95, 0xBBB1, 0x8DFC,
+	0xBBB2, 0x8F14, 0xBBB3, 0x8F12, 0xBBB4, 0x8F15, 0xBBB5, 0x8F13,
+	0xBBB6, 0x8FA3, 0xBBB7, 0x9060, 0xBBB8, 0x9058, 0xBBB9, 0x905C,
+	0xBBBA, 0x9063, 0xBBBB, 0x9059, 0xBBBC, 0x905E, 0xBBBD, 0x9062,
+	0xBBBE, 0x905D, 0xBBBF, 0x905B, 0xBBC0, 0x9119, 0xBBC1, 0x9118,
+	0xBBC2, 0x911E, 0xBBC3, 0x9175, 0xBBC4, 0x9178, 0xBBC5, 0x9177,
+	0xBBC6, 0x9174, 0xBBC7, 0x9278, 0xBBC8, 0x9280, 0xBBC9, 0x9285,
+	0xBBCA, 0x9298, 0xBBCB, 0x9296, 0xBBCC, 0x927B, 0xBBCD, 0x9293,
+	0xBBCE, 0x929C, 0xBBCF, 0x92A8, 0xBBD0, 0x927C, 0xBBD1, 0x9291,
+	0xBBD2, 0x95A1, 0xBBD3, 0x95A8, 0xBBD4, 0x95A9, 0xBBD5, 0x95A3,
+	0xBBD6, 0x95A5, 0xBBD7, 0x95A4, 0xBBD8, 0x9699, 0xBBD9, 0x969C,
+	0xBBDA, 0x969B, 0xBBDB, 0x96CC, 0xBBDC, 0x96D2, 0xBBDD, 0x9700,
+	0xBBDE, 0x977C, 0xBBDF, 0x9785, 0xBBE0, 0x97F6, 0xBBE1, 0x9817,
+	0xBBE2, 0x9818, 0xBBE3, 0x98AF, 0xBBE4, 0x98B1, 0xBBE5, 0x9903,
+	0xBBE6, 0x9905, 0xBBE7, 0x990C, 0xBBE8, 0x9909, 0xBBE9, 0x99C1,
+	0xBBEA, 0x9AAF, 0xBBEB, 0x9AB0, 0xBBEC, 0x9AE6, 0xBBED, 0x9B41,
+	0xBBEE, 0x9B42, 0xBBEF, 0x9CF4, 0xBBF0, 0x9CF6, 0xBBF1, 0x9CF3,
+	0xBBF2, 0x9EBC, 0xBBF3, 0x9F3B, 0xBBF4, 0x9F4A, 0xBBF5, 0x5104,
+	0xBBF6, 0x5100, 0xBBF7, 0x50FB, 0xBBF8, 0x50F5, 0xBBF9, 0x50F9,
+	0xBBFA, 0x5102, 0xBBFB, 0x5108, 0xBBFC, 0x5109, 0xBBFD, 0x5105,
+	0xBBFE, 0x51DC, 0xBC40, 0x5287, 0xBC41, 0x5288, 0xBC42, 0x5289,
+	0xBC43, 0x528D, 0xBC44, 0x528A, 0xBC45, 0x52F0, 0xBC46, 0x53B2,
+	0xBC47, 0x562E, 0xBC48, 0x563B, 0xBC49, 0x5639, 0xBC4A, 0x5632,
+	0xBC4B, 0x563F, 0xBC4C, 0x5634, 0xBC4D, 0x5629, 0xBC4E, 0x5653,
+	0xBC4F, 0x564E, 0xBC50, 0x5657, 0xBC51, 0x5674, 0xBC52, 0x5636,
+	0xBC53, 0x562F, 0xBC54, 0x5630, 0xBC55, 0x5880, 0xBC56, 0x589F,
+	0xBC57, 0x589E, 0xBC58, 0x58B3, 0xBC59, 0x589C, 0xBC5A, 0x58AE,
+	0xBC5B, 0x58A9, 0xBC5C, 0x58A6, 0xBC5D, 0x596D, 0xBC5E, 0x5B09,
+	0xBC5F, 0x5AFB, 0xBC60, 0x5B0B, 0xBC61, 0x5AF5, 0xBC62, 0x5B0C,
+	0xBC63, 0x5B08, 0xBC64, 0x5BEE, 0xBC65, 0x5BEC, 0xBC66, 0x5BE9,
+	0xBC67, 0x5BEB, 0xBC68, 0x5C64, 0xBC69, 0x5C65, 0xBC6A, 0x5D9D,
+	0xBC6B, 0x5D94, 0xBC6C, 0x5E62, 0xBC6D, 0x5E5F, 0xBC6E, 0x5E61,
+	0xBC6F, 0x5EE2, 0xBC70, 0x5EDA, 0xBC71, 0x5EDF, 0xBC72, 0x5EDD,
+	0xBC73, 0x5EE3, 0xBC74, 0x5EE0, 0xBC75, 0x5F48, 0xBC76, 0x5F71,
+	0xBC77, 0x5FB7, 0xBC78, 0x5FB5, 0xBC79, 0x6176, 0xBC7A, 0x6167,
+	0xBC7B, 0x616E, 0xBC7C, 0x615D, 0xBC7D, 0x6155, 0xBC7E, 0x6182,
+	0xBCA1, 0x617C, 0xBCA2, 0x6170, 0xBCA3, 0x616B, 0xBCA4, 0x617E,
+	0xBCA5, 0x61A7, 0xBCA6, 0x6190, 0xBCA7, 0x61AB, 0xBCA8, 0x618E,
+	0xBCA9, 0x61AC, 0xBCAA, 0x619A, 0xBCAB, 0x61A4, 0xBCAC, 0x6194,
+	0xBCAD, 0x61AE, 0xBCAE, 0x622E, 0xBCAF, 0x6469, 0xBCB0, 0x646F,
+	0xBCB1, 0x6479, 0xBCB2, 0x649E, 0xBCB3, 0x64B2, 0xBCB4, 0x6488,
+	0xBCB5, 0x6490, 0xBCB6, 0x64B0, 0xBCB7, 0x64A5, 0xBCB8, 0x6493,
+	0xBCB9, 0x6495, 0xBCBA, 0x64A9, 0xBCBB, 0x6492, 0xBCBC, 0x64AE,
+	0xBCBD, 0x64AD, 0xBCBE, 0x64AB, 0xBCBF, 0x649A, 0xBCC0, 0x64AC,
+	0xBCC1, 0x6499, 0xBCC2, 0x64A2, 0xBCC3, 0x64B3, 0xBCC4, 0x6575,
+	0xBCC5, 0x6577, 0xBCC6, 0x6578, 0xBCC7, 0x66AE, 0xBCC8, 0x66AB,
+	0xBCC9, 0x66B4, 0xBCCA, 0x66B1, 0xBCCB, 0x6A23, 0xBCCC, 0x6A1F,
+	0xBCCD, 0x69E8, 0xBCCE, 0x6A01, 0xBCCF, 0x6A1E, 0xBCD0, 0x6A19,
+	0xBCD1, 0x69FD, 0xBCD2, 0x6A21, 0xBCD3, 0x6A13, 0xBCD4, 0x6A0A,
+	0xBCD5, 0x69F3, 0xBCD6, 0x6A02, 0xBCD7, 0x6A05, 0xBCD8, 0x69ED,
+	0xBCD9, 0x6A11, 0xBCDA, 0x6B50, 0xBCDB, 0x6B4E, 0xBCDC, 0x6BA4,
+	0xBCDD, 0x6BC5, 0xBCDE, 0x6BC6, 0xBCDF, 0x6F3F, 0xBCE0, 0x6F7C,
+	0xBCE1, 0x6F84, 0xBCE2, 0x6F51, 0xBCE3, 0x6F66, 0xBCE4, 0x6F54,
+	0xBCE5, 0x6F86, 0xBCE6, 0x6F6D, 0xBCE7, 0x6F5B, 0xBCE8, 0x6F78,
+	0xBCE9, 0x6F6E, 0xBCEA, 0x6F8E, 0xBCEB, 0x6F7A, 0xBCEC, 0x6F70,
+	0xBCED, 0x6F64, 0xBCEE, 0x6F97, 0xBCEF, 0x6F58, 0xBCF0, 0x6ED5,
+	0xBCF1, 0x6F6F, 0xBCF2, 0x6F60, 0xBCF3, 0x6F5F, 0xBCF4, 0x719F,
+	0xBCF5, 0x71AC, 0xBCF6, 0x71B1, 0xBCF7, 0x71A8, 0xBCF8, 0x7256,
+	0xBCF9, 0x729B, 0xBCFA, 0x734E, 0xBCFB, 0x7357, 0xBCFC, 0x7469,
+	0xBCFD, 0x748B, 0xBCFE, 0x7483, 0xBD40, 0x747E, 0xBD41, 0x7480,
+	0xBD42, 0x757F, 0xBD43, 0x7620, 0xBD44, 0x7629, 0xBD45, 0x761F,
+	0xBD46, 0x7624, 0xBD47, 0x7626, 0xBD48, 0x7621, 0xBD49, 0x7622,
+	0xBD4A, 0x769A, 0xBD4B, 0x76BA, 0xBD4C, 0x76E4, 0xBD4D, 0x778E,
+	0xBD4E, 0x7787, 0xBD4F, 0x778C, 0xBD50, 0x7791, 0xBD51, 0x778B,
+	0xBD52, 0x78CB, 0xBD53, 0x78C5, 0xBD54, 0x78BA, 0xBD55, 0x78CA,
+	0xBD56, 0x78BE, 0xBD57, 0x78D5, 0xBD58, 0x78BC, 0xBD59, 0x78D0,
+	0xBD5A, 0x7A3F, 0xBD5B, 0x7A3C, 0xBD5C, 0x7A40, 0xBD5D, 0x7A3D,
+	0xBD5E, 0x7A37, 0xBD5F, 0x7A3B, 0xBD60, 0x7AAF, 0xBD61, 0x7AAE,
+	0xBD62, 0x7BAD, 0xBD63, 0x7BB1, 0xBD64, 0x7BC4, 0xBD65, 0x7BB4,
+	0xBD66, 0x7BC6, 0xBD67, 0x7BC7, 0xBD68, 0x7BC1, 0xBD69, 0x7BA0,
+	0xBD6A, 0x7BCC, 0xBD6B, 0x7CCA, 0xBD6C, 0x7DE0, 0xBD6D, 0x7DF4,
+	0xBD6E, 0x7DEF, 0xBD6F, 0x7DFB, 0xBD70, 0x7DD8, 0xBD71, 0x7DEC,
+	0xBD72, 0x7DDD, 0xBD73, 0x7DE8, 0xBD74, 0x7DE3, 0xBD75, 0x7DDA,
+	0xBD76, 0x7DDE, 0xBD77, 0x7DE9, 0xBD78, 0x7D9E, 0xBD79, 0x7DD9,
+	0xBD7A, 0x7DF2, 0xBD7B, 0x7DF9, 0xBD7C, 0x7F75, 0xBD7D, 0x7F77,
+	0xBD7E, 0x7FAF, 0xBDA1, 0x7FE9, 0xBDA2, 0x8026, 0xBDA3, 0x819B,
+	0xBDA4, 0x819C, 0xBDA5, 0x819D, 0xBDA6, 0x81A0, 0xBDA7, 0x819A,
+	0xBDA8, 0x8198, 0xBDA9, 0x8517, 0xBDAA, 0x853D, 0xBDAB, 0x851A,
+	0xBDAC, 0x84EE, 0xBDAD, 0x852C, 0xBDAE, 0x852D, 0xBDAF, 0x8513,
+	0xBDB0, 0x8511, 0xBDB1, 0x8523, 0xBDB2, 0x8521, 0xBDB3, 0x8514,
+	0xBDB4, 0x84EC, 0xBDB5, 0x8525, 0xBDB6, 0x84FF, 0xBDB7, 0x8506,
+	0xBDB8, 0x8782, 0xBDB9, 0x8774, 0xBDBA, 0x8776, 0xBDBB, 0x8760,
+	0xBDBC, 0x8766, 0xBDBD, 0x8778, 0xBDBE, 0x8768, 0xBDBF, 0x8759,
+	0xBDC0, 0x8757, 0xBDC1, 0x874C, 0xBDC2, 0x8753, 0xBDC3, 0x885B,
+	0xBDC4, 0x885D, 0xBDC5, 0x8910, 0xBDC6, 0x8907, 0xBDC7, 0x8912,
+	0xBDC8, 0x8913, 0xBDC9, 0x8915, 0xBDCA, 0x890A, 0xBDCB, 0x8ABC,
+	0xBDCC, 0x8AD2, 0xBDCD, 0x8AC7, 0xBDCE, 0x8AC4, 0xBDCF, 0x8A95,
+	0xBDD0, 0x8ACB, 0xBDD1, 0x8AF8, 0xBDD2, 0x8AB2, 0xBDD3, 0x8AC9,
+	0xBDD4, 0x8AC2, 0xBDD5, 0x8ABF, 0xBDD6, 0x8AB0, 0xBDD7, 0x8AD6,
+	0xBDD8, 0x8ACD, 0xBDD9, 0x8AB6, 0xBDDA, 0x8AB9, 0xBDDB, 0x8ADB,
+	0xBDDC, 0x8C4C, 0xBDDD, 0x8C4E, 0xBDDE, 0x8C6C, 0xBDDF, 0x8CE0,
+	0xBDE0, 0x8CDE, 0xBDE1, 0x8CE6, 0xBDE2, 0x8CE4, 0xBDE3, 0x8CEC,
+	0xBDE4, 0x8CED, 0xBDE5, 0x8CE2, 0xBDE6, 0x8CE3, 0xBDE7, 0x8CDC,
+	0xBDE8, 0x8CEA, 0xBDE9, 0x8CE1, 0xBDEA, 0x8D6D, 0xBDEB, 0x8D9F,
+	0xBDEC, 0x8DA3, 0xBDED, 0x8E2B, 0xBDEE, 0x8E10, 0xBDEF, 0x8E1D,
+	0xBDF0, 0x8E22, 0xBDF1, 0x8E0F, 0xBDF2, 0x8E29, 0xBDF3, 0x8E1F,
+	0xBDF4, 0x8E21, 0xBDF5, 0x8E1E, 0xBDF6, 0x8EBA, 0xBDF7, 0x8F1D,
+	0xBDF8, 0x8F1B, 0xBDF9, 0x8F1F, 0xBDFA, 0x8F29, 0xBDFB, 0x8F26,
+	0xBDFC, 0x8F2A, 0xBDFD, 0x8F1C, 0xBDFE, 0x8F1E, 0xBE40, 0x8F25,
+	0xBE41, 0x9069, 0xBE42, 0x906E, 0xBE43, 0x9068, 0xBE44, 0x906D,
+	0xBE45, 0x9077, 0xBE46, 0x9130, 0xBE47, 0x912D, 0xBE48, 0x9127,
+	0xBE49, 0x9131, 0xBE4A, 0x9187, 0xBE4B, 0x9189, 0xBE4C, 0x918B,
+	0xBE4D, 0x9183, 0xBE4E, 0x92C5, 0xBE4F, 0x92BB, 0xBE50, 0x92B7,
+	0xBE51, 0x92EA, 0xBE52, 0x92AC, 0xBE53, 0x92E4, 0xBE54, 0x92C1,
+	0xBE55, 0x92B3, 0xBE56, 0x92BC, 0xBE57, 0x92D2, 0xBE58, 0x92C7,
+	0xBE59, 0x92F0, 0xBE5A, 0x92B2, 0xBE5B, 0x95AD, 0xBE5C, 0x95B1,
+	0xBE5D, 0x9704, 0xBE5E, 0x9706, 0xBE5F, 0x9707, 0xBE60, 0x9709,
+	0xBE61, 0x9760, 0xBE62, 0x978D, 0xBE63, 0x978B, 0xBE64, 0x978F,
+	0xBE65, 0x9821, 0xBE66, 0x982B, 0xBE67, 0x981C, 0xBE68, 0x98B3,
+	0xBE69, 0x990A, 0xBE6A, 0x9913, 0xBE6B, 0x9912, 0xBE6C, 0x9918,
+	0xBE6D, 0x99DD, 0xBE6E, 0x99D0, 0xBE6F, 0x99DF, 0xBE70, 0x99DB,
+	0xBE71, 0x99D1, 0xBE72, 0x99D5, 0xBE73, 0x99D2, 0xBE74, 0x99D9,
+	0xBE75, 0x9AB7, 0xBE76, 0x9AEE, 0xBE77, 0x9AEF, 0xBE78, 0x9B27,
+	0xBE79, 0x9B45, 0xBE7A, 0x9B44, 0xBE7B, 0x9B77, 0xBE7C, 0x9B6F,
+	0xBE7D, 0x9D06, 0xBE7E, 0x9D09, 0xBEA1, 0x9D03, 0xBEA2, 0x9EA9,
+	0xBEA3, 0x9EBE, 0xBEA4, 0x9ECE, 0xBEA5, 0x58A8, 0xBEA6, 0x9F52,
+	0xBEA7, 0x5112, 0xBEA8, 0x5118, 0xBEA9, 0x5114, 0xBEAA, 0x5110,
+	0xBEAB, 0x5115, 0xBEAC, 0x5180, 0xBEAD, 0x51AA, 0xBEAE, 0x51DD,
+	0xBEAF, 0x5291, 0xBEB0, 0x5293, 0xBEB1, 0x52F3, 0xBEB2, 0x5659,
+	0xBEB3, 0x566B, 0xBEB4, 0x5679, 0xBEB5, 0x5669, 0xBEB6, 0x5664,
+	0xBEB7, 0x5678, 0xBEB8, 0x566A, 0xBEB9, 0x5668, 0xBEBA, 0x5665,
+	0xBEBB, 0x5671, 0xBEBC, 0x566F, 0xBEBD, 0x566C, 0xBEBE, 0x5662,
+	0xBEBF, 0x5676, 0xBEC0, 0x58C1, 0xBEC1, 0x58BE, 0xBEC2, 0x58C7,
+	0xBEC3, 0x58C5, 0xBEC4, 0x596E, 0xBEC5, 0x5B1D, 0xBEC6, 0x5B34,
+	0xBEC7, 0x5B78, 0xBEC8, 0x5BF0, 0xBEC9, 0x5C0E, 0xBECA, 0x5F4A,
+	0xBECB, 0x61B2, 0xBECC, 0x6191, 0xBECD, 0x61A9, 0xBECE, 0x618A,
+	0xBECF, 0x61CD, 0xBED0, 0x61B6, 0xBED1, 0x61BE, 0xBED2, 0x61CA,
+	0xBED3, 0x61C8, 0xBED4, 0x6230, 0xBED5, 0x64C5, 0xBED6, 0x64C1,
+	0xBED7, 0x64CB, 0xBED8, 0x64BB, 0xBED9, 0x64BC, 0xBEDA, 0x64DA,
+	0xBEDB, 0x64C4, 0xBEDC, 0x64C7, 0xBEDD, 0x64C2, 0xBEDE, 0x64CD,
+	0xBEDF, 0x64BF, 0xBEE0, 0x64D2, 0xBEE1, 0x64D4, 0xBEE2, 0x64BE,
+	0xBEE3, 0x6574, 0xBEE4, 0x66C6, 0xBEE5, 0x66C9, 0xBEE6, 0x66B9,
+	0xBEE7, 0x66C4, 0xBEE8, 0x66C7, 0xBEE9, 0x66B8, 0xBEEA, 0x6A3D,
+	0xBEEB, 0x6A38, 0xBEEC, 0x6A3A, 0xBEED, 0x6A59, 0xBEEE, 0x6A6B,
+	0xBEEF, 0x6A58, 0xBEF0, 0x6A39, 0xBEF1, 0x6A44, 0xBEF2, 0x6A62,
+	0xBEF3, 0x6A61, 0xBEF4, 0x6A4B, 0xBEF5, 0x6A47, 0xBEF6, 0x6A35,
+	0xBEF7, 0x6A5F, 0xBEF8, 0x6A48, 0xBEF9, 0x6B59, 0xBEFA, 0x6B77,
+	0xBEFB, 0x6C05, 0xBEFC, 0x6FC2, 0xBEFD, 0x6FB1, 0xBEFE, 0x6FA1,
+	0xBF40, 0x6FC3, 0xBF41, 0x6FA4, 0xBF42, 0x6FC1, 0xBF43, 0x6FA7,
+	0xBF44, 0x6FB3, 0xBF45, 0x6FC0, 0xBF46, 0x6FB9, 0xBF47, 0x6FB6,
+	0xBF48, 0x6FA6, 0xBF49, 0x6FA0, 0xBF4A, 0x6FB4, 0xBF4B, 0x71BE,
+	0xBF4C, 0x71C9, 0xBF4D, 0x71D0, 0xBF4E, 0x71D2, 0xBF4F, 0x71C8,
+	0xBF50, 0x71D5, 0xBF51, 0x71B9, 0xBF52, 0x71CE, 0xBF53, 0x71D9,
+	0xBF54, 0x71DC, 0xBF55, 0x71C3, 0xBF56, 0x71C4, 0xBF57, 0x7368,
+	0xBF58, 0x749C, 0xBF59, 0x74A3, 0xBF5A, 0x7498, 0xBF5B, 0x749F,
+	0xBF5C, 0x749E, 0xBF5D, 0x74E2, 0xBF5E, 0x750C, 0xBF5F, 0x750D,
+	0xBF60, 0x7634, 0xBF61, 0x7638, 0xBF62, 0x763A, 0xBF63, 0x76E7,
+	0xBF64, 0x76E5, 0xBF65, 0x77A0, 0xBF66, 0x779E, 0xBF67, 0x779F,
+	0xBF68, 0x77A5, 0xBF69, 0x78E8, 0xBF6A, 0x78DA, 0xBF6B, 0x78EC,
+	0xBF6C, 0x78E7, 0xBF6D, 0x79A6, 0xBF6E, 0x7A4D, 0xBF6F, 0x7A4E,
+	0xBF70, 0x7A46, 0xBF71, 0x7A4C, 0xBF72, 0x7A4B, 0xBF73, 0x7ABA,
+	0xBF74, 0x7BD9, 0xBF75, 0x7C11, 0xBF76, 0x7BC9, 0xBF77, 0x7BE4,
+	0xBF78, 0x7BDB, 0xBF79, 0x7BE1, 0xBF7A, 0x7BE9, 0xBF7B, 0x7BE6,
+	0xBF7C, 0x7CD5, 0xBF7D, 0x7CD6, 0xBF7E, 0x7E0A, 0xBFA1, 0x7E11,
+	0xBFA2, 0x7E08, 0xBFA3, 0x7E1B, 0xBFA4, 0x7E23, 0xBFA5, 0x7E1E,
+	0xBFA6, 0x7E1D, 0xBFA7, 0x7E09, 0xBFA8, 0x7E10, 0xBFA9, 0x7F79,
+	0xBFAA, 0x7FB2, 0xBFAB, 0x7FF0, 0xBFAC, 0x7FF1, 0xBFAD, 0x7FEE,
+	0xBFAE, 0x8028, 0xBFAF, 0x81B3, 0xBFB0, 0x81A9, 0xBFB1, 0x81A8,
+	0xBFB2, 0x81FB, 0xBFB3, 0x8208, 0xBFB4, 0x8258, 0xBFB5, 0x8259,
+	0xBFB6, 0x854A, 0xBFB7, 0x8559, 0xBFB8, 0x8548, 0xBFB9, 0x8568,
+	0xBFBA, 0x8569, 0xBFBB, 0x8543, 0xBFBC, 0x8549, 0xBFBD, 0x856D,
+	0xBFBE, 0x856A, 0xBFBF, 0x855E, 0xBFC0, 0x8783, 0xBFC1, 0x879F,
+	0xBFC2, 0x879E, 0xBFC3, 0x87A2, 0xBFC4, 0x878D, 0xBFC5, 0x8861,
+	0xBFC6, 0x892A, 0xBFC7, 0x8932, 0xBFC8, 0x8925, 0xBFC9, 0x892B,
+	0xBFCA, 0x8921, 0xBFCB, 0x89AA, 0xBFCC, 0x89A6, 0xBFCD, 0x8AE6,
+	0xBFCE, 0x8AFA, 0xBFCF, 0x8AEB, 0xBFD0, 0x8AF1, 0xBFD1, 0x8B00,
+	0xBFD2, 0x8ADC, 0xBFD3, 0x8AE7, 0xBFD4, 0x8AEE, 0xBFD5, 0x8AFE,
+	0xBFD6, 0x8B01, 0xBFD7, 0x8B02, 0xBFD8, 0x8AF7, 0xBFD9, 0x8AED,
+	0xBFDA, 0x8AF3, 0xBFDB, 0x8AF6, 0xBFDC, 0x8AFC, 0xBFDD, 0x8C6B,
+	0xBFDE, 0x8C6D, 0xBFDF, 0x8C93, 0xBFE0, 0x8CF4, 0xBFE1, 0x8E44,
+	0xBFE2, 0x8E31, 0xBFE3, 0x8E34, 0xBFE4, 0x8E42, 0xBFE5, 0x8E39,
+	0xBFE6, 0x8E35, 0xBFE7, 0x8F3B, 0xBFE8, 0x8F2F, 0xBFE9, 0x8F38,
+	0xBFEA, 0x8F33, 0xBFEB, 0x8FA8, 0xBFEC, 0x8FA6, 0xBFED, 0x9075,
+	0xBFEE, 0x9074, 0xBFEF, 0x9078, 0xBFF0, 0x9072, 0xBFF1, 0x907C,
+	0xBFF2, 0x907A, 0xBFF3, 0x9134, 0xBFF4, 0x9192, 0xBFF5, 0x9320,
+	0xBFF6, 0x9336, 0xBFF7, 0x92F8, 0xBFF8, 0x9333, 0xBFF9, 0x932F,
+	0xBFFA, 0x9322, 0xBFFB, 0x92FC, 0xBFFC, 0x932B, 0xBFFD, 0x9304,
+	0xBFFE, 0x931A, 0xC040, 0x9310, 0xC041, 0x9326, 0xC042, 0x9321,
+	0xC043, 0x9315, 0xC044, 0x932E, 0xC045, 0x9319, 0xC046, 0x95BB,
+	0xC047, 0x96A7, 0xC048, 0x96A8, 0xC049, 0x96AA, 0xC04A, 0x96D5,
+	0xC04B, 0x970E, 0xC04C, 0x9711, 0xC04D, 0x9716, 0xC04E, 0x970D,
+	0xC04F, 0x9713, 0xC050, 0x970F, 0xC051, 0x975B, 0xC052, 0x975C,
+	0xC053, 0x9766, 0xC054, 0x9798, 0xC055, 0x9830, 0xC056, 0x9838,
+	0xC057, 0x983B, 0xC058, 0x9837, 0xC059, 0x982D, 0xC05A, 0x9839,
+	0xC05B, 0x9824, 0xC05C, 0x9910, 0xC05D, 0x9928, 0xC05E, 0x991E,
+	0xC05F, 0x991B, 0xC060, 0x9921, 0xC061, 0x991A, 0xC062, 0x99ED,
+	0xC063, 0x99E2, 0xC064, 0x99F1, 0xC065, 0x9AB8, 0xC066, 0x9ABC,
+	0xC067, 0x9AFB, 0xC068, 0x9AED, 0xC069, 0x9B28, 0xC06A, 0x9B91,
+	0xC06B, 0x9D15, 0xC06C, 0x9D23, 0xC06D, 0x9D26, 0xC06E, 0x9D28,
+	0xC06F, 0x9D12, 0xC070, 0x9D1B, 0xC071, 0x9ED8, 0xC072, 0x9ED4,
+	0xC073, 0x9F8D, 0xC074, 0x9F9C, 0xC075, 0x512A, 0xC076, 0x511F,
+	0xC077, 0x5121, 0xC078, 0x5132, 0xC079, 0x52F5, 0xC07A, 0x568E,
+	0xC07B, 0x5680, 0xC07C, 0x5690, 0xC07D, 0x5685, 0xC07E, 0x5687,
+	0xC0A1, 0x568F, 0xC0A2, 0x58D5, 0xC0A3, 0x58D3, 0xC0A4, 0x58D1,
+	0xC0A5, 0x58CE, 0xC0A6, 0x5B30, 0xC0A7, 0x5B2A, 0xC0A8, 0x5B24,
+	0xC0A9, 0x5B7A, 0xC0AA, 0x5C37, 0xC0AB, 0x5C68, 0xC0AC, 0x5DBC,
+	0xC0AD, 0x5DBA, 0xC0AE, 0x5DBD, 0xC0AF, 0x5DB8, 0xC0B0, 0x5E6B,
+	0xC0B1, 0x5F4C, 0xC0B2, 0x5FBD, 0xC0B3, 0x61C9, 0xC0B4, 0x61C2,
+	0xC0B5, 0x61C7, 0xC0B6, 0x61E6, 0xC0B7, 0x61CB, 0xC0B8, 0x6232,
+	0xC0B9, 0x6234, 0xC0BA, 0x64CE, 0xC0BB, 0x64CA, 0xC0BC, 0x64D8,
+	0xC0BD, 0x64E0, 0xC0BE, 0x64F0, 0xC0BF, 0x64E6, 0xC0C0, 0x64EC,
+	0xC0C1, 0x64F1, 0xC0C2, 0x64E2, 0xC0C3, 0x64ED, 0xC0C4, 0x6582,
+	0xC0C5, 0x6583, 0xC0C6, 0x66D9, 0xC0C7, 0x66D6, 0xC0C8, 0x6A80,
+	0xC0C9, 0x6A94, 0xC0CA, 0x6A84, 0xC0CB, 0x6AA2, 0xC0CC, 0x6A9C,
+	0xC0CD, 0x6ADB, 0xC0CE, 0x6AA3, 0xC0CF, 0x6A7E, 0xC0D0, 0x6A97,
+	0xC0D1, 0x6A90, 0xC0D2, 0x6AA0, 0xC0D3, 0x6B5C, 0xC0D4, 0x6BAE,
+	0xC0D5, 0x6BDA, 0xC0D6, 0x6C08, 0xC0D7, 0x6FD8, 0xC0D8, 0x6FF1,
+	0xC0D9, 0x6FDF, 0xC0DA, 0x6FE0, 0xC0DB, 0x6FDB, 0xC0DC, 0x6FE4,
+	0xC0DD, 0x6FEB, 0xC0DE, 0x6FEF, 0xC0DF, 0x6F80, 0xC0E0, 0x6FEC,
+	0xC0E1, 0x6FE1, 0xC0E2, 0x6FE9, 0xC0E3, 0x6FD5, 0xC0E4, 0x6FEE,
+	0xC0E5, 0x6FF0, 0xC0E6, 0x71E7, 0xC0E7, 0x71DF, 0xC0E8, 0x71EE,
+	0xC0E9, 0x71E6, 0xC0EA, 0x71E5, 0xC0EB, 0x71ED, 0xC0EC, 0x71EC,
+	0xC0ED, 0x71F4, 0xC0EE, 0x71E0, 0xC0EF, 0x7235, 0xC0F0, 0x7246,
+	0xC0F1, 0x7370, 0xC0F2, 0x7372, 0xC0F3, 0x74A9, 0xC0F4, 0x74B0,
+	0xC0F5, 0x74A6, 0xC0F6, 0x74A8, 0xC0F7, 0x7646, 0xC0F8, 0x7642,
+	0xC0F9, 0x764C, 0xC0FA, 0x76EA, 0xC0FB, 0x77B3, 0xC0FC, 0x77AA,
+	0xC0FD, 0x77B0, 0xC0FE, 0x77AC, 0xC140, 0x77A7, 0xC141, 0x77AD,
+	0xC142, 0x77EF, 0xC143, 0x78F7, 0xC144, 0x78FA, 0xC145, 0x78F4,
+	0xC146, 0x78EF, 0xC147, 0x7901, 0xC148, 0x79A7, 0xC149, 0x79AA,
+	0xC14A, 0x7A57, 0xC14B, 0x7ABF, 0xC14C, 0x7C07, 0xC14D, 0x7C0D,
+	0xC14E, 0x7BFE, 0xC14F, 0x7BF7, 0xC150, 0x7C0C, 0xC151, 0x7BE0,
+	0xC152, 0x7CE0, 0xC153, 0x7CDC, 0xC154, 0x7CDE, 0xC155, 0x7CE2,
+	0xC156, 0x7CDF, 0xC157, 0x7CD9, 0xC158, 0x7CDD, 0xC159, 0x7E2E,
+	0xC15A, 0x7E3E, 0xC15B, 0x7E46, 0xC15C, 0x7E37, 0xC15D, 0x7E32,
+	0xC15E, 0x7E43, 0xC15F, 0x7E2B, 0xC160, 0x7E3D, 0xC161, 0x7E31,
+	0xC162, 0x7E45, 0xC163, 0x7E41, 0xC164, 0x7E34, 0xC165, 0x7E39,
+	0xC166, 0x7E48, 0xC167, 0x7E35, 0xC168, 0x7E3F, 0xC169, 0x7E2F,
+	0xC16A, 0x7F44, 0xC16B, 0x7FF3, 0xC16C, 0x7FFC, 0xC16D, 0x8071,
+	0xC16E, 0x8072, 0xC16F, 0x8070, 0xC170, 0x806F, 0xC171, 0x8073,
+	0xC172, 0x81C6, 0xC173, 0x81C3, 0xC174, 0x81BA, 0xC175, 0x81C2,
+	0xC176, 0x81C0, 0xC177, 0x81BF, 0xC178, 0x81BD, 0xC179, 0x81C9,
+	0xC17A, 0x81BE, 0xC17B, 0x81E8, 0xC17C, 0x8209, 0xC17D, 0x8271,
+	0xC17E, 0x85AA, 0xC1A1, 0x8584, 0xC1A2, 0x857E, 0xC1A3, 0x859C,
+	0xC1A4, 0x8591, 0xC1A5, 0x8594, 0xC1A6, 0x85AF, 0xC1A7, 0x859B,
+	0xC1A8, 0x8587, 0xC1A9, 0x85A8, 0xC1AA, 0x858A, 0xC1AB, 0x8667,
+	0xC1AC, 0x87C0, 0xC1AD, 0x87D1, 0xC1AE, 0x87B3, 0xC1AF, 0x87D2,
+	0xC1B0, 0x87C6, 0xC1B1, 0x87AB, 0xC1B2, 0x87BB, 0xC1B3, 0x87BA,
+	0xC1B4, 0x87C8, 0xC1B5, 0x87CB, 0xC1B6, 0x893B, 0xC1B7, 0x8936,
+	0xC1B8, 0x8944, 0xC1B9, 0x8938, 0xC1BA, 0x893D, 0xC1BB, 0x89AC,
+	0xC1BC, 0x8B0E, 0xC1BD, 0x8B17, 0xC1BE, 0x8B19, 0xC1BF, 0x8B1B,
+	0xC1C0, 0x8B0A, 0xC1C1, 0x8B20, 0xC1C2, 0x8B1D, 0xC1C3, 0x8B04,
+	0xC1C4, 0x8B10, 0xC1C5, 0x8C41, 0xC1C6, 0x8C3F, 0xC1C7, 0x8C73,
+	0xC1C8, 0x8CFA, 0xC1C9, 0x8CFD, 0xC1CA, 0x8CFC, 0xC1CB, 0x8CF8,
+	0xC1CC, 0x8CFB, 0xC1CD, 0x8DA8, 0xC1CE, 0x8E49, 0xC1CF, 0x8E4B,
+	0xC1D0, 0x8E48, 0xC1D1, 0x8E4A, 0xC1D2, 0x8F44, 0xC1D3, 0x8F3E,
+	0xC1D4, 0x8F42, 0xC1D5, 0x8F45, 0xC1D6, 0x8F3F, 0xC1D7, 0x907F,
+	0xC1D8, 0x907D, 0xC1D9, 0x9084, 0xC1DA, 0x9081, 0xC1DB, 0x9082,
+	0xC1DC, 0x9080, 0xC1DD, 0x9139, 0xC1DE, 0x91A3, 0xC1DF, 0x919E,
+	0xC1E0, 0x919C, 0xC1E1, 0x934D, 0xC1E2, 0x9382, 0xC1E3, 0x9328,
+	0xC1E4, 0x9375, 0xC1E5, 0x934A, 0xC1E6, 0x9365, 0xC1E7, 0x934B,
+	0xC1E8, 0x9318, 0xC1E9, 0x937E, 0xC1EA, 0x936C, 0xC1EB, 0x935B,
+	0xC1EC, 0x9370, 0xC1ED, 0x935A, 0xC1EE, 0x9354, 0xC1EF, 0x95CA,
+	0xC1F0, 0x95CB, 0xC1F1, 0x95CC, 0xC1F2, 0x95C8, 0xC1F3, 0x95C6,
+	0xC1F4, 0x96B1, 0xC1F5, 0x96B8, 0xC1F6, 0x96D6, 0xC1F7, 0x971C,
+	0xC1F8, 0x971E, 0xC1F9, 0x97A0, 0xC1FA, 0x97D3, 0xC1FB, 0x9846,
+	0xC1FC, 0x98B6, 0xC1FD, 0x9935, 0xC1FE, 0x9A01, 0xC240, 0x99FF,
+	0xC241, 0x9BAE, 0xC242, 0x9BAB, 0xC243, 0x9BAA, 0xC244, 0x9BAD,
+	0xC245, 0x9D3B, 0xC246, 0x9D3F, 0xC247, 0x9E8B, 0xC248, 0x9ECF,
+	0xC249, 0x9EDE, 0xC24A, 0x9EDC, 0xC24B, 0x9EDD, 0xC24C, 0x9EDB,
+	0xC24D, 0x9F3E, 0xC24E, 0x9F4B, 0xC24F, 0x53E2, 0xC250, 0x5695,
+	0xC251, 0x56AE, 0xC252, 0x58D9, 0xC253, 0x58D8, 0xC254, 0x5B38,
+	0xC255, 0x5F5D, 0xC256, 0x61E3, 0xC257, 0x6233, 0xC258, 0x64F4,
+	0xC259, 0x64F2, 0xC25A, 0x64FE, 0xC25B, 0x6506, 0xC25C, 0x64FA,
+	0xC25D, 0x64FB, 0xC25E, 0x64F7, 0xC25F, 0x65B7, 0xC260, 0x66DC,
+	0xC261, 0x6726, 0xC262, 0x6AB3, 0xC263, 0x6AAC, 0xC264, 0x6AC3,
+	0xC265, 0x6ABB, 0xC266, 0x6AB8, 0xC267, 0x6AC2, 0xC268, 0x6AAE,
+	0xC269, 0x6AAF, 0xC26A, 0x6B5F, 0xC26B, 0x6B78, 0xC26C, 0x6BAF,
+	0xC26D, 0x7009, 0xC26E, 0x700B, 0xC26F, 0x6FFE, 0xC270, 0x7006,
+	0xC271, 0x6FFA, 0xC272, 0x7011, 0xC273, 0x700F, 0xC274, 0x71FB,
+	0xC275, 0x71FC, 0xC276, 0x71FE, 0xC277, 0x71F8, 0xC278, 0x7377,
+	0xC279, 0x7375, 0xC27A, 0x74A7, 0xC27B, 0x74BF, 0xC27C, 0x7515,
+	0xC27D, 0x7656, 0xC27E, 0x7658, 0xC2A1, 0x7652, 0xC2A2, 0x77BD,
+	0xC2A3, 0x77BF, 0xC2A4, 0x77BB, 0xC2A5, 0x77BC, 0xC2A6, 0x790E,
+	0xC2A7, 0x79AE, 0xC2A8, 0x7A61, 0xC2A9, 0x7A62, 0xC2AA, 0x7A60,
+	0xC2AB, 0x7AC4, 0xC2AC, 0x7AC5, 0xC2AD, 0x7C2B, 0xC2AE, 0x7C27,
+	0xC2AF, 0x7C2A, 0xC2B0, 0x7C1E, 0xC2B1, 0x7C23, 0xC2B2, 0x7C21,
+	0xC2B3, 0x7CE7, 0xC2B4, 0x7E54, 0xC2B5, 0x7E55, 0xC2B6, 0x7E5E,
+	0xC2B7, 0x7E5A, 0xC2B8, 0x7E61, 0xC2B9, 0x7E52, 0xC2BA, 0x7E59,
+	0xC2BB, 0x7F48, 0xC2BC, 0x7FF9, 0xC2BD, 0x7FFB, 0xC2BE, 0x8077,
+	0xC2BF, 0x8076, 0xC2C0, 0x81CD, 0xC2C1, 0x81CF, 0xC2C2, 0x820A,
+	0xC2C3, 0x85CF, 0xC2C4, 0x85A9, 0xC2C5, 0x85CD, 0xC2C6, 0x85D0,
+	0xC2C7, 0x85C9, 0xC2C8, 0x85B0, 0xC2C9, 0x85BA, 0xC2CA, 0x85B9,
+	0xC2CB, 0x85A6, 0xC2CC, 0x87EF, 0xC2CD, 0x87EC, 0xC2CE, 0x87F2,
+	0xC2CF, 0x87E0, 0xC2D0, 0x8986, 0xC2D1, 0x89B2, 0xC2D2, 0x89F4,
+	0xC2D3, 0x8B28, 0xC2D4, 0x8B39, 0xC2D5, 0x8B2C, 0xC2D6, 0x8B2B,
+	0xC2D7, 0x8C50, 0xC2D8, 0x8D05, 0xC2D9, 0x8E59, 0xC2DA, 0x8E63,
+	0xC2DB, 0x8E66, 0xC2DC, 0x8E64, 0xC2DD, 0x8E5F, 0xC2DE, 0x8E55,
+	0xC2DF, 0x8EC0, 0xC2E0, 0x8F49, 0xC2E1, 0x8F4D, 0xC2E2, 0x9087,
+	0xC2E3, 0x9083, 0xC2E4, 0x9088, 0xC2E5, 0x91AB, 0xC2E6, 0x91AC,
+	0xC2E7, 0x91D0, 0xC2E8, 0x9394, 0xC2E9, 0x938A, 0xC2EA, 0x9396,
+	0xC2EB, 0x93A2, 0xC2EC, 0x93B3, 0xC2ED, 0x93AE, 0xC2EE, 0x93AC,
+	0xC2EF, 0x93B0, 0xC2F0, 0x9398, 0xC2F1, 0x939A, 0xC2F2, 0x9397,
+	0xC2F3, 0x95D4, 0xC2F4, 0x95D6, 0xC2F5, 0x95D0, 0xC2F6, 0x95D5,
+	0xC2F7, 0x96E2, 0xC2F8, 0x96DC, 0xC2F9, 0x96D9, 0xC2FA, 0x96DB,
+	0xC2FB, 0x96DE, 0xC2FC, 0x9724, 0xC2FD, 0x97A3, 0xC2FE, 0x97A6,
+	0xC340, 0x97AD, 0xC341, 0x97F9, 0xC342, 0x984D, 0xC343, 0x984F,
+	0xC344, 0x984C, 0xC345, 0x984E, 0xC346, 0x9853, 0xC347, 0x98BA,
+	0xC348, 0x993E, 0xC349, 0x993F, 0xC34A, 0x993D, 0xC34B, 0x992E,
+	0xC34C, 0x99A5, 0xC34D, 0x9A0E, 0xC34E, 0x9AC1, 0xC34F, 0x9B03,
+	0xC350, 0x9B06, 0xC351, 0x9B4F, 0xC352, 0x9B4E, 0xC353, 0x9B4D,
+	0xC354, 0x9BCA, 0xC355, 0x9BC9, 0xC356, 0x9BFD, 0xC357, 0x9BC8,
+	0xC358, 0x9BC0, 0xC359, 0x9D51, 0xC35A, 0x9D5D, 0xC35B, 0x9D60,
+	0xC35C, 0x9EE0, 0xC35D, 0x9F15, 0xC35E, 0x9F2C, 0xC35F, 0x5133,
+	0xC360, 0x56A5, 0xC361, 0x58DE, 0xC362, 0x58DF, 0xC363, 0x58E2,
+	0xC364, 0x5BF5, 0xC365, 0x9F90, 0xC366, 0x5EEC, 0xC367, 0x61F2,
+	0xC368, 0x61F7, 0xC369, 0x61F6, 0xC36A, 0x61F5, 0xC36B, 0x6500,
+	0xC36C, 0x650F, 0xC36D, 0x66E0, 0xC36E, 0x66DD, 0xC36F, 0x6AE5,
+	0xC370, 0x6ADD, 0xC371, 0x6ADA, 0xC372, 0x6AD3, 0xC373, 0x701B,
+	0xC374, 0x701F, 0xC375, 0x7028, 0xC376, 0x701A, 0xC377, 0x701D,
+	0xC378, 0x7015, 0xC379, 0x7018, 0xC37A, 0x7206, 0xC37B, 0x720D,
+	0xC37C, 0x7258, 0xC37D, 0x72A2, 0xC37E, 0x7378, 0xC3A1, 0x737A,
+	0xC3A2, 0x74BD, 0xC3A3, 0x74CA, 0xC3A4, 0x74E3, 0xC3A5, 0x7587,
+	0xC3A6, 0x7586, 0xC3A7, 0x765F, 0xC3A8, 0x7661, 0xC3A9, 0x77C7,
+	0xC3AA, 0x7919, 0xC3AB, 0x79B1, 0xC3AC, 0x7A6B, 0xC3AD, 0x7A69,
+	0xC3AE, 0x7C3E, 0xC3AF, 0x7C3F, 0xC3B0, 0x7C38, 0xC3B1, 0x7C3D,
+	0xC3B2, 0x7C37, 0xC3B3, 0x7C40, 0xC3B4, 0x7E6B, 0xC3B5, 0x7E6D,
+	0xC3B6, 0x7E79, 0xC3B7, 0x7E69, 0xC3B8, 0x7E6A, 0xC3B9, 0x7F85,
+	0xC3BA, 0x7E73, 0xC3BB, 0x7FB6, 0xC3BC, 0x7FB9, 0xC3BD, 0x7FB8,
+	0xC3BE, 0x81D8, 0xC3BF, 0x85E9, 0xC3C0, 0x85DD, 0xC3C1, 0x85EA,
+	0xC3C2, 0x85D5, 0xC3C3, 0x85E4, 0xC3C4, 0x85E5, 0xC3C5, 0x85F7,
+	0xC3C6, 0x87FB, 0xC3C7, 0x8805, 0xC3C8, 0x880D, 0xC3C9, 0x87F9,
+	0xC3CA, 0x87FE, 0xC3CB, 0x8960, 0xC3CC, 0x895F, 0xC3CD, 0x8956,
+	0xC3CE, 0x895E, 0xC3CF, 0x8B41, 0xC3D0, 0x8B5C, 0xC3D1, 0x8B58,
+	0xC3D2, 0x8B49, 0xC3D3, 0x8B5A, 0xC3D4, 0x8B4E, 0xC3D5, 0x8B4F,
+	0xC3D6, 0x8B46, 0xC3D7, 0x8B59, 0xC3D8, 0x8D08, 0xC3D9, 0x8D0A,
+	0xC3DA, 0x8E7C, 0xC3DB, 0x8E72, 0xC3DC, 0x8E87, 0xC3DD, 0x8E76,
+	0xC3DE, 0x8E6C, 0xC3DF, 0x8E7A, 0xC3E0, 0x8E74, 0xC3E1, 0x8F54,
+	0xC3E2, 0x8F4E, 0xC3E3, 0x8FAD, 0xC3E4, 0x908A, 0xC3E5, 0x908B,
+	0xC3E6, 0x91B1, 0xC3E7, 0x91AE, 0xC3E8, 0x93E1, 0xC3E9, 0x93D1,
+	0xC3EA, 0x93DF, 0xC3EB, 0x93C3, 0xC3EC, 0x93C8, 0xC3ED, 0x93DC,
+	0xC3EE, 0x93DD, 0xC3EF, 0x93D6, 0xC3F0, 0x93E2, 0xC3F1, 0x93CD,
+	0xC3F2, 0x93D8, 0xC3F3, 0x93E4, 0xC3F4, 0x93D7, 0xC3F5, 0x93E8,
+	0xC3F6, 0x95DC, 0xC3F7, 0x96B4, 0xC3F8, 0x96E3, 0xC3F9, 0x972A,
+	0xC3FA, 0x9727, 0xC3FB, 0x9761, 0xC3FC, 0x97DC, 0xC3FD, 0x97FB,
+	0xC3FE, 0x985E, 0xC440, 0x9858, 0xC441, 0x985B, 0xC442, 0x98BC,
+	0xC443, 0x9945, 0xC444, 0x9949, 0xC445, 0x9A16, 0xC446, 0x9A19,
+	0xC447, 0x9B0D, 0xC448, 0x9BE8, 0xC449, 0x9BE7, 0xC44A, 0x9BD6,
+	0xC44B, 0x9BDB, 0xC44C, 0x9D89, 0xC44D, 0x9D61, 0xC44E, 0x9D72,
+	0xC44F, 0x9D6A, 0xC450, 0x9D6C, 0xC451, 0x9E92, 0xC452, 0x9E97,
+	0xC453, 0x9E93, 0xC454, 0x9EB4, 0xC455, 0x52F8, 0xC456, 0x56A8,
+	0xC457, 0x56B7, 0xC458, 0x56B6, 0xC459, 0x56B4, 0xC45A, 0x56BC,
+	0xC45B, 0x58E4, 0xC45C, 0x5B40, 0xC45D, 0x5B43, 0xC45E, 0x5B7D,
+	0xC45F, 0x5BF6, 0xC460, 0x5DC9, 0xC461, 0x61F8, 0xC462, 0x61FA,
+	0xC463, 0x6518, 0xC464, 0x6514, 0xC465, 0x6519, 0xC466, 0x66E6,
+	0xC467, 0x6727, 0xC468, 0x6AEC, 0xC469, 0x703E, 0xC46A, 0x7030,
+	0xC46B, 0x7032, 0xC46C, 0x7210, 0xC46D, 0x737B, 0xC46E, 0x74CF,
+	0xC46F, 0x7662, 0xC470, 0x7665, 0xC471, 0x7926, 0xC472, 0x792A,
+	0xC473, 0x792C, 0xC474, 0x792B, 0xC475, 0x7AC7, 0xC476, 0x7AF6,
+	0xC477, 0x7C4C, 0xC478, 0x7C43, 0xC479, 0x7C4D, 0xC47A, 0x7CEF,
+	0xC47B, 0x7CF0, 0xC47C, 0x8FAE, 0xC47D, 0x7E7D, 0xC47E, 0x7E7C,
+	0xC4A1, 0x7E82, 0xC4A2, 0x7F4C, 0xC4A3, 0x8000, 0xC4A4, 0x81DA,
+	0xC4A5, 0x8266, 0xC4A6, 0x85FB, 0xC4A7, 0x85F9, 0xC4A8, 0x8611,
+	0xC4A9, 0x85FA, 0xC4AA, 0x8606, 0xC4AB, 0x860B, 0xC4AC, 0x8607,
+	0xC4AD, 0x860A, 0xC4AE, 0x8814, 0xC4AF, 0x8815, 0xC4B0, 0x8964,
+	0xC4B1, 0x89BA, 0xC4B2, 0x89F8, 0xC4B3, 0x8B70, 0xC4B4, 0x8B6C,
+	0xC4B5, 0x8B66, 0xC4B6, 0x8B6F, 0xC4B7, 0x8B5F, 0xC4B8, 0x8B6B,
+	0xC4B9, 0x8D0F, 0xC4BA, 0x8D0D, 0xC4BB, 0x8E89, 0xC4BC, 0x8E81,
+	0xC4BD, 0x8E85, 0xC4BE, 0x8E82, 0xC4BF, 0x91B4, 0xC4C0, 0x91CB,
+	0xC4C1, 0x9418, 0xC4C2, 0x9403, 0xC4C3, 0x93FD, 0xC4C4, 0x95E1,
+	0xC4C5, 0x9730, 0xC4C6, 0x98C4, 0xC4C7, 0x9952, 0xC4C8, 0x9951,
+	0xC4C9, 0x99A8, 0xC4CA, 0x9A2B, 0xC4CB, 0x9A30, 0xC4CC, 0x9A37,
+	0xC4CD, 0x9A35, 0xC4CE, 0x9C13, 0xC4CF, 0x9C0D, 0xC4D0, 0x9E79,
+	0xC4D1, 0x9EB5, 0xC4D2, 0x9EE8, 0xC4D3, 0x9F2F, 0xC4D4, 0x9F5F,
+	0xC4D5, 0x9F63, 0xC4D6, 0x9F61, 0xC4D7, 0x5137, 0xC4D8, 0x5138,
+	0xC4D9, 0x56C1, 0xC4DA, 0x56C0, 0xC4DB, 0x56C2, 0xC4DC, 0x5914,
+	0xC4DD, 0x5C6C, 0xC4DE, 0x5DCD, 0xC4DF, 0x61FC, 0xC4E0, 0x61FE,
+	0xC4E1, 0x651D, 0xC4E2, 0x651C, 0xC4E3, 0x6595, 0xC4E4, 0x66E9,
+	0xC4E5, 0x6AFB, 0xC4E6, 0x6B04, 0xC4E7, 0x6AFA, 0xC4E8, 0x6BB2,
+	0xC4E9, 0x704C, 0xC4EA, 0x721B, 0xC4EB, 0x72A7, 0xC4EC, 0x74D6,
+	0xC4ED, 0x74D4, 0xC4EE, 0x7669, 0xC4EF, 0x77D3, 0xC4F0, 0x7C50,
+	0xC4F1, 0x7E8F, 0xC4F2, 0x7E8C, 0xC4F3, 0x7FBC, 0xC4F4, 0x8617,
+	0xC4F5, 0x862D, 0xC4F6, 0x861A, 0xC4F7, 0x8823, 0xC4F8, 0x8822,
+	0xC4F9, 0x8821, 0xC4FA, 0x881F, 0xC4FB, 0x896A, 0xC4FC, 0x896C,
+	0xC4FD, 0x89BD, 0xC4FE, 0x8B74, 0xC540, 0x8B77, 0xC541, 0x8B7D,
+	0xC542, 0x8D13, 0xC543, 0x8E8A, 0xC544, 0x8E8D, 0xC545, 0x8E8B,
+	0xC546, 0x8F5F, 0xC547, 0x8FAF, 0xC548, 0x91BA, 0xC549, 0x942E,
+	0xC54A, 0x9433, 0xC54B, 0x9435, 0xC54C, 0x943A, 0xC54D, 0x9438,
+	0xC54E, 0x9432, 0xC54F, 0x942B, 0xC550, 0x95E2, 0xC551, 0x9738,
+	0xC552, 0x9739, 0xC553, 0x9732, 0xC554, 0x97FF, 0xC555, 0x9867,
+	0xC556, 0x9865, 0xC557, 0x9957, 0xC558, 0x9A45, 0xC559, 0x9A43,
+	0xC55A, 0x9A40, 0xC55B, 0x9A3E, 0xC55C, 0x9ACF, 0xC55D, 0x9B54,
+	0xC55E, 0x9B51, 0xC55F, 0x9C2D, 0xC560, 0x9C25, 0xC561, 0x9DAF,
+	0xC562, 0x9DB4, 0xC563, 0x9DC2, 0xC564, 0x9DB8, 0xC565, 0x9E9D,
+	0xC566, 0x9EEF, 0xC567, 0x9F19, 0xC568, 0x9F5C, 0xC569, 0x9F66,
+	0xC56A, 0x9F67, 0xC56B, 0x513C, 0xC56C, 0x513B, 0xC56D, 0x56C8,
+	0xC56E, 0x56CA, 0xC56F, 0x56C9, 0xC570, 0x5B7F, 0xC571, 0x5DD4,
+	0xC572, 0x5DD2, 0xC573, 0x5F4E, 0xC574, 0x61FF, 0xC575, 0x6524,
+	0xC576, 0x6B0A, 0xC577, 0x6B61, 0xC578, 0x7051, 0xC579, 0x7058,
+	0xC57A, 0x7380, 0xC57B, 0x74E4, 0xC57C, 0x758A, 0xC57D, 0x766E,
+	0xC57E, 0x766C, 0xC5A1, 0x79B3, 0xC5A2, 0x7C60, 0xC5A3, 0x7C5F,
+	0xC5A4, 0x807E, 0xC5A5, 0x807D, 0xC5A6, 0x81DF, 0xC5A7, 0x8972,
+	0xC5A8, 0x896F, 0xC5A9, 0x89FC, 0xC5AA, 0x8B80, 0xC5AB, 0x8D16,
+	0xC5AC, 0x8D17, 0xC5AD, 0x8E91, 0xC5AE, 0x8E93, 0xC5AF, 0x8F61,
+	0xC5B0, 0x9148, 0xC5B1, 0x9444, 0xC5B2, 0x9451, 0xC5B3, 0x9452,
+	0xC5B4, 0x973D, 0xC5B5, 0x973E, 0xC5B6, 0x97C3, 0xC5B7, 0x97C1,
+	0xC5B8, 0x986B, 0xC5B9, 0x9955, 0xC5BA, 0x9A55, 0xC5BB, 0x9A4D,
+	0xC5BC, 0x9AD2, 0xC5BD, 0x9B1A, 0xC5BE, 0x9C49, 0xC5BF, 0x9C31,
+	0xC5C0, 0x9C3E, 0xC5C1, 0x9C3B, 0xC5C2, 0x9DD3, 0xC5C3, 0x9DD7,
+	0xC5C4, 0x9F34, 0xC5C5, 0x9F6C, 0xC5C6, 0x9F6A, 0xC5C7, 0x9F94,
+	0xC5C8, 0x56CC, 0xC5C9, 0x5DD6, 0xC5CA, 0x6200, 0xC5CB, 0x6523,
+	0xC5CC, 0x652B, 0xC5CD, 0x652A, 0xC5CE, 0x66EC, 0xC5CF, 0x6B10,
+	0xC5D0, 0x74DA, 0xC5D1, 0x7ACA, 0xC5D2, 0x7C64, 0xC5D3, 0x7C63,
+	0xC5D4, 0x7C65, 0xC5D5, 0x7E93, 0xC5D6, 0x7E96, 0xC5D7, 0x7E94,
+	0xC5D8, 0x81E2, 0xC5D9, 0x8638, 0xC5DA, 0x863F, 0xC5DB, 0x8831,
+	0xC5DC, 0x8B8A, 0xC5DD, 0x9090, 0xC5DE, 0x908F, 0xC5DF, 0x9463,
+	0xC5E0, 0x9460, 0xC5E1, 0x9464, 0xC5E2, 0x9768, 0xC5E3, 0x986F,
+	0xC5E4, 0x995C, 0xC5E5, 0x9A5A, 0xC5E6, 0x9A5B, 0xC5E7, 0x9A57,
+	0xC5E8, 0x9AD3, 0xC5E9, 0x9AD4, 0xC5EA, 0x9AD1, 0xC5EB, 0x9C54,
+	0xC5EC, 0x9C57, 0xC5ED, 0x9C56, 0xC5EE, 0x9DE5, 0xC5EF, 0x9E9F,
+	0xC5F0, 0x9EF4, 0xC5F1, 0x56D1, 0xC5F2, 0x58E9, 0xC5F3, 0x652C,
+	0xC5F4, 0x705E, 0xC5F5, 0x7671, 0xC5F6, 0x7672, 0xC5F7, 0x77D7,
+	0xC5F8, 0x7F50, 0xC5F9, 0x7F88, 0xC5FA, 0x8836, 0xC5FB, 0x8839,
+	0xC5FC, 0x8862, 0xC5FD, 0x8B93, 0xC5FE, 0x8B92, 0xC640, 0x8B96,
+	0xC641, 0x8277, 0xC642, 0x8D1B, 0xC643, 0x91C0, 0xC644, 0x946A,
+	0xC645, 0x9742, 0xC646, 0x9748, 0xC647, 0x9744, 0xC648, 0x97C6,
+	0xC649, 0x9870, 0xC64A, 0x9A5F, 0xC64B, 0x9B22, 0xC64C, 0x9B58,
+	0xC64D, 0x9C5F, 0xC64E, 0x9DF9, 0xC64F, 0x9DFA, 0xC650, 0x9E7C,
+	0xC651, 0x9E7D, 0xC652, 0x9F07, 0xC653, 0x9F77, 0xC654, 0x9F72,
+	0xC655, 0x5EF3, 0xC656, 0x6B16, 0xC657, 0x7063, 0xC658, 0x7C6C,
+	0xC659, 0x7C6E, 0xC65A, 0x883B, 0xC65B, 0x89C0, 0xC65C, 0x8EA1,
+	0xC65D, 0x91C1, 0xC65E, 0x9472, 0xC65F, 0x9470, 0xC660, 0x9871,
+	0xC661, 0x995E, 0xC662, 0x9AD6, 0xC663, 0x9B23, 0xC664, 0x9ECC,
+	0xC665, 0x7064, 0xC666, 0x77DA, 0xC667, 0x8B9A, 0xC668, 0x9477,
+	0xC669, 0x97C9, 0xC66A, 0x9A62, 0xC66B, 0x9A65, 0xC66C, 0x7E9C,
+	0xC66D, 0x8B9C, 0xC66E, 0x8EAA, 0xC66F, 0x91C5, 0xC670, 0x947D,
+	0xC671, 0x947E, 0xC672, 0x947C, 0xC673, 0x9C77, 0xC674, 0x9C78,
+	0xC675, 0x9EF7, 0xC676, 0x8C54, 0xC677, 0x947F, 0xC678, 0x9E1A,
+	0xC679, 0x7228, 0xC67A, 0x9A6A, 0xC67B, 0x9B31, 0xC67C, 0x9E1B,
+	0xC67D, 0x9E1E, 0xC67E, 0x7C72, 0xC940, 0x4E42, 0xC941, 0x4E5C,
+	0xC942, 0x51F5, 0xC943, 0x531A, 0xC944, 0x5382, 0xC945, 0x4E07,
+	0xC946, 0x4E0C, 0xC947, 0x4E47, 0xC948, 0x4E8D, 0xC949, 0x56D7,
+	0xC94A, 0xFA0C, 0xC94B, 0x5C6E, 0xC94C, 0x5F73, 0xC94D, 0x4E0F,
+	0xC94E, 0x5187, 0xC94F, 0x4E0E, 0xC950, 0x4E2E, 0xC951, 0x4E93,
+	0xC952, 0x4EC2, 0xC953, 0x4EC9, 0xC954, 0x4EC8, 0xC955, 0x5198,
+	0xC956, 0x52FC, 0xC957, 0x536C, 0xC958, 0x53B9, 0xC959, 0x5720,
+	0xC95A, 0x5903, 0xC95B, 0x592C, 0xC95C, 0x5C10, 0xC95D, 0x5DFF,
+	0xC95E, 0x65E1, 0xC95F, 0x6BB3, 0xC960, 0x6BCC, 0xC961, 0x6C14,
+	0xC962, 0x723F, 0xC963, 0x4E31, 0xC964, 0x4E3C, 0xC965, 0x4EE8,
+	0xC966, 0x4EDC, 0xC967, 0x4EE9, 0xC968, 0x4EE1, 0xC969, 0x4EDD,
+	0xC96A, 0x4EDA, 0xC96B, 0x520C, 0xC96C, 0x531C, 0xC96D, 0x534C,
+	0xC96E, 0x5722, 0xC96F, 0x5723, 0xC970, 0x5917, 0xC971, 0x592F,
+	0xC972, 0x5B81, 0xC973, 0x5B84, 0xC974, 0x5C12, 0xC975, 0x5C3B,
+	0xC976, 0x5C74, 0xC977, 0x5C73, 0xC978, 0x5E04, 0xC979, 0x5E80,
+	0xC97A, 0x5E82, 0xC97B, 0x5FC9, 0xC97C, 0x6209, 0xC97D, 0x6250,
+	0xC97E, 0x6C15, 0xC9A1, 0x6C36, 0xC9A2, 0x6C43, 0xC9A3, 0x6C3F,
+	0xC9A4, 0x6C3B, 0xC9A5, 0x72AE, 0xC9A6, 0x72B0, 0xC9A7, 0x738A,
+	0xC9A8, 0x79B8, 0xC9A9, 0x808A, 0xC9AA, 0x961E, 0xC9AB, 0x4F0E,
+	0xC9AC, 0x4F18, 0xC9AD, 0x4F2C, 0xC9AE, 0x4EF5, 0xC9AF, 0x4F14,
+	0xC9B0, 0x4EF1, 0xC9B1, 0x4F00, 0xC9B2, 0x4EF7, 0xC9B3, 0x4F08,
+	0xC9B4, 0x4F1D, 0xC9B5, 0x4F02, 0xC9B6, 0x4F05, 0xC9B7, 0x4F22,
+	0xC9B8, 0x4F13, 0xC9B9, 0x4F04, 0xC9BA, 0x4EF4, 0xC9BB, 0x4F12,
+	0xC9BC, 0x51B1, 0xC9BD, 0x5213, 0xC9BE, 0x5209, 0xC9BF, 0x5210,
+	0xC9C0, 0x52A6, 0xC9C1, 0x5322, 0xC9C2, 0x531F, 0xC9C3, 0x534D,
+	0xC9C4, 0x538A, 0xC9C5, 0x5407, 0xC9C6, 0x56E1, 0xC9C7, 0x56DF,
+	0xC9C8, 0x572E, 0xC9C9, 0x572A, 0xC9CA, 0x5734, 0xC9CB, 0x593C,
+	0xC9CC, 0x5980, 0xC9CD, 0x597C, 0xC9CE, 0x5985, 0xC9CF, 0x597B,
+	0xC9D0, 0x597E, 0xC9D1, 0x5977, 0xC9D2, 0x597F, 0xC9D3, 0x5B56,
+	0xC9D4, 0x5C15, 0xC9D5, 0x5C25, 0xC9D6, 0x5C7C, 0xC9D7, 0x5C7A,
+	0xC9D8, 0x5C7B, 0xC9D9, 0x5C7E, 0xC9DA, 0x5DDF, 0xC9DB, 0x5E75,
+	0xC9DC, 0x5E84, 0xC9DD, 0x5F02, 0xC9DE, 0x5F1A, 0xC9DF, 0x5F74,
+	0xC9E0, 0x5FD5, 0xC9E1, 0x5FD4, 0xC9E2, 0x5FCF, 0xC9E3, 0x625C,
+	0xC9E4, 0x625E, 0xC9E5, 0x6264, 0xC9E6, 0x6261, 0xC9E7, 0x6266,
+	0xC9E8, 0x6262, 0xC9E9, 0x6259, 0xC9EA, 0x6260, 0xC9EB, 0x625A,
+	0xC9EC, 0x6265, 0xC9ED, 0x65EF, 0xC9EE, 0x65EE, 0xC9EF, 0x673E,
+	0xC9F0, 0x6739, 0xC9F1, 0x6738, 0xC9F2, 0x673B, 0xC9F3, 0x673A,
+	0xC9F4, 0x673F, 0xC9F5, 0x673C, 0xC9F6, 0x6733, 0xC9F7, 0x6C18,
+	0xC9F8, 0x6C46, 0xC9F9, 0x6C52, 0xC9FA, 0x6C5C, 0xC9FB, 0x6C4F,
+	0xC9FC, 0x6C4A, 0xC9FD, 0x6C54, 0xC9FE, 0x6C4B, 0xCA40, 0x6C4C,
+	0xCA41, 0x7071, 0xCA42, 0x725E, 0xCA43, 0x72B4, 0xCA44, 0x72B5,
+	0xCA45, 0x738E, 0xCA46, 0x752A, 0xCA47, 0x767F, 0xCA48, 0x7A75,
+	0xCA49, 0x7F51, 0xCA4A, 0x8278, 0xCA4B, 0x827C, 0xCA4C, 0x8280,
+	0xCA4D, 0x827D, 0xCA4E, 0x827F, 0xCA4F, 0x864D, 0xCA50, 0x897E,
+	0xCA51, 0x9099, 0xCA52, 0x9097, 0xCA53, 0x9098, 0xCA54, 0x909B,
+	0xCA55, 0x9094, 0xCA56, 0x9622, 0xCA57, 0x9624, 0xCA58, 0x9620,
+	0xCA59, 0x9623, 0xCA5A, 0x4F56, 0xCA5B, 0x4F3B, 0xCA5C, 0x4F62,
+	0xCA5D, 0x4F49, 0xCA5E, 0x4F53, 0xCA5F, 0x4F64, 0xCA60, 0x4F3E,
+	0xCA61, 0x4F67, 0xCA62, 0x4F52, 0xCA63, 0x4F5F, 0xCA64, 0x4F41,
+	0xCA65, 0x4F58, 0xCA66, 0x4F2D, 0xCA67, 0x4F33, 0xCA68, 0x4F3F,
+	0xCA69, 0x4F61, 0xCA6A, 0x518F, 0xCA6B, 0x51B9, 0xCA6C, 0x521C,
+	0xCA6D, 0x521E, 0xCA6E, 0x5221, 0xCA6F, 0x52AD, 0xCA70, 0x52AE,
+	0xCA71, 0x5309, 0xCA72, 0x5363, 0xCA73, 0x5372, 0xCA74, 0x538E,
+	0xCA75, 0x538F, 0xCA76, 0x5430, 0xCA77, 0x5437, 0xCA78, 0x542A,
+	0xCA79, 0x5454, 0xCA7A, 0x5445, 0xCA7B, 0x5419, 0xCA7C, 0x541C,
+	0xCA7D, 0x5425, 0xCA7E, 0x5418, 0xCAA1, 0x543D, 0xCAA2, 0x544F,
+	0xCAA3, 0x5441, 0xCAA4, 0x5428, 0xCAA5, 0x5424, 0xCAA6, 0x5447,
+	0xCAA7, 0x56EE, 0xCAA8, 0x56E7, 0xCAA9, 0x56E5, 0xCAAA, 0x5741,
+	0xCAAB, 0x5745, 0xCAAC, 0x574C, 0xCAAD, 0x5749, 0xCAAE, 0x574B,
+	0xCAAF, 0x5752, 0xCAB0, 0x5906, 0xCAB1, 0x5940, 0xCAB2, 0x59A6,
+	0xCAB3, 0x5998, 0xCAB4, 0x59A0, 0xCAB5, 0x5997, 0xCAB6, 0x598E,
+	0xCAB7, 0x59A2, 0xCAB8, 0x5990, 0xCAB9, 0x598F, 0xCABA, 0x59A7,
+	0xCABB, 0x59A1, 0xCABC, 0x5B8E, 0xCABD, 0x5B92, 0xCABE, 0x5C28,
+	0xCABF, 0x5C2A, 0xCAC0, 0x5C8D, 0xCAC1, 0x5C8F, 0xCAC2, 0x5C88,
+	0xCAC3, 0x5C8B, 0xCAC4, 0x5C89, 0xCAC5, 0x5C92, 0xCAC6, 0x5C8A,
+	0xCAC7, 0x5C86, 0xCAC8, 0x5C93, 0xCAC9, 0x5C95, 0xCACA, 0x5DE0,
+	0xCACB, 0x5E0A, 0xCACC, 0x5E0E, 0xCACD, 0x5E8B, 0xCACE, 0x5E89,
+	0xCACF, 0x5E8C, 0xCAD0, 0x5E88, 0xCAD1, 0x5E8D, 0xCAD2, 0x5F05,
+	0xCAD3, 0x5F1D, 0xCAD4, 0x5F78, 0xCAD5, 0x5F76, 0xCAD6, 0x5FD2,
+	0xCAD7, 0x5FD1, 0xCAD8, 0x5FD0, 0xCAD9, 0x5FED, 0xCADA, 0x5FE8,
+	0xCADB, 0x5FEE, 0xCADC, 0x5FF3, 0xCADD, 0x5FE1, 0xCADE, 0x5FE4,
+	0xCADF, 0x5FE3, 0xCAE0, 0x5FFA, 0xCAE1, 0x5FEF, 0xCAE2, 0x5FF7,
+	0xCAE3, 0x5FFB, 0xCAE4, 0x6000, 0xCAE5, 0x5FF4, 0xCAE6, 0x623A,
+	0xCAE7, 0x6283, 0xCAE8, 0x628C, 0xCAE9, 0x628E, 0xCAEA, 0x628F,
+	0xCAEB, 0x6294, 0xCAEC, 0x6287, 0xCAED, 0x6271, 0xCAEE, 0x627B,
+	0xCAEF, 0x627A, 0xCAF0, 0x6270, 0xCAF1, 0x6281, 0xCAF2, 0x6288,
+	0xCAF3, 0x6277, 0xCAF4, 0x627D, 0xCAF5, 0x6272, 0xCAF6, 0x6274,
+	0xCAF7, 0x6537, 0xCAF8, 0x65F0, 0xCAF9, 0x65F4, 0xCAFA, 0x65F3,
+	0xCAFB, 0x65F2, 0xCAFC, 0x65F5, 0xCAFD, 0x6745, 0xCAFE, 0x6747,
+	0xCB40, 0x6759, 0xCB41, 0x6755, 0xCB42, 0x674C, 0xCB43, 0x6748,
+	0xCB44, 0x675D, 0xCB45, 0x674D, 0xCB46, 0x675A, 0xCB47, 0x674B,
+	0xCB48, 0x6BD0, 0xCB49, 0x6C19, 0xCB4A, 0x6C1A, 0xCB4B, 0x6C78,
+	0xCB4C, 0x6C67, 0xCB4D, 0x6C6B, 0xCB4E, 0x6C84, 0xCB4F, 0x6C8B,
+	0xCB50, 0x6C8F, 0xCB51, 0x6C71, 0xCB52, 0x6C6F, 0xCB53, 0x6C69,
+	0xCB54, 0x6C9A, 0xCB55, 0x6C6D, 0xCB56, 0x6C87, 0xCB57, 0x6C95,
+	0xCB58, 0x6C9C, 0xCB59, 0x6C66, 0xCB5A, 0x6C73, 0xCB5B, 0x6C65,
+	0xCB5C, 0x6C7B, 0xCB5D, 0x6C8E, 0xCB5E, 0x7074, 0xCB5F, 0x707A,
+	0xCB60, 0x7263, 0xCB61, 0x72BF, 0xCB62, 0x72BD, 0xCB63, 0x72C3,
+	0xCB64, 0x72C6, 0xCB65, 0x72C1, 0xCB66, 0x72BA, 0xCB67, 0x72C5,
+	0xCB68, 0x7395, 0xCB69, 0x7397, 0xCB6A, 0x7393, 0xCB6B, 0x7394,
+	0xCB6C, 0x7392, 0xCB6D, 0x753A, 0xCB6E, 0x7539, 0xCB6F, 0x7594,
+	0xCB70, 0x7595, 0xCB71, 0x7681, 0xCB72, 0x793D, 0xCB73, 0x8034,
+	0xCB74, 0x8095, 0xCB75, 0x8099, 0xCB76, 0x8090, 0xCB77, 0x8092,
+	0xCB78, 0x809C, 0xCB79, 0x8290, 0xCB7A, 0x828F, 0xCB7B, 0x8285,
+	0xCB7C, 0x828E, 0xCB7D, 0x8291, 0xCB7E, 0x8293, 0xCBA1, 0x828A,
+	0xCBA2, 0x8283, 0xCBA3, 0x8284, 0xCBA4, 0x8C78, 0xCBA5, 0x8FC9,
+	0xCBA6, 0x8FBF, 0xCBA7, 0x909F, 0xCBA8, 0x90A1, 0xCBA9, 0x90A5,
+	0xCBAA, 0x909E, 0xCBAB, 0x90A7, 0xCBAC, 0x90A0, 0xCBAD, 0x9630,
+	0xCBAE, 0x9628, 0xCBAF, 0x962F, 0xCBB0, 0x962D, 0xCBB1, 0x4E33,
+	0xCBB2, 0x4F98, 0xCBB3, 0x4F7C, 0xCBB4, 0x4F85, 0xCBB5, 0x4F7D,
+	0xCBB6, 0x4F80, 0xCBB7, 0x4F87, 0xCBB8, 0x4F76, 0xCBB9, 0x4F74,
+	0xCBBA, 0x4F89, 0xCBBB, 0x4F84, 0xCBBC, 0x4F77, 0xCBBD, 0x4F4C,
+	0xCBBE, 0x4F97, 0xCBBF, 0x4F6A, 0xCBC0, 0x4F9A, 0xCBC1, 0x4F79,
+	0xCBC2, 0x4F81, 0xCBC3, 0x4F78, 0xCBC4, 0x4F90, 0xCBC5, 0x4F9C,
+	0xCBC6, 0x4F94, 0xCBC7, 0x4F9E, 0xCBC8, 0x4F92, 0xCBC9, 0x4F82,
+	0xCBCA, 0x4F95, 0xCBCB, 0x4F6B, 0xCBCC, 0x4F6E, 0xCBCD, 0x519E,
+	0xCBCE, 0x51BC, 0xCBCF, 0x51BE, 0xCBD0, 0x5235, 0xCBD1, 0x5232,
+	0xCBD2, 0x5233, 0xCBD3, 0x5246, 0xCBD4, 0x5231, 0xCBD5, 0x52BC,
+	0xCBD6, 0x530A, 0xCBD7, 0x530B, 0xCBD8, 0x533C, 0xCBD9, 0x5392,
+	0xCBDA, 0x5394, 0xCBDB, 0x5487, 0xCBDC, 0x547F, 0xCBDD, 0x5481,
+	0xCBDE, 0x5491, 0xCBDF, 0x5482, 0xCBE0, 0x5488, 0xCBE1, 0x546B,
+	0xCBE2, 0x547A, 0xCBE3, 0x547E, 0xCBE4, 0x5465, 0xCBE5, 0x546C,
+	0xCBE6, 0x5474, 0xCBE7, 0x5466, 0xCBE8, 0x548D, 0xCBE9, 0x546F,
+	0xCBEA, 0x5461, 0xCBEB, 0x5460, 0xCBEC, 0x5498, 0xCBED, 0x5463,
+	0xCBEE, 0x5467, 0xCBEF, 0x5464, 0xCBF0, 0x56F7, 0xCBF1, 0x56F9,
+	0xCBF2, 0x576F, 0xCBF3, 0x5772, 0xCBF4, 0x576D, 0xCBF5, 0x576B,
+	0xCBF6, 0x5771, 0xCBF7, 0x5770, 0xCBF8, 0x5776, 0xCBF9, 0x5780,
+	0xCBFA, 0x5775, 0xCBFB, 0x577B, 0xCBFC, 0x5773, 0xCBFD, 0x5774,
+	0xCBFE, 0x5762, 0xCC40, 0x5768, 0xCC41, 0x577D, 0xCC42, 0x590C,
+	0xCC43, 0x5945, 0xCC44, 0x59B5, 0xCC45, 0x59BA, 0xCC46, 0x59CF,
+	0xCC47, 0x59CE, 0xCC48, 0x59B2, 0xCC49, 0x59CC, 0xCC4A, 0x59C1,
+	0xCC4B, 0x59B6, 0xCC4C, 0x59BC, 0xCC4D, 0x59C3, 0xCC4E, 0x59D6,
+	0xCC4F, 0x59B1, 0xCC50, 0x59BD, 0xCC51, 0x59C0, 0xCC52, 0x59C8,
+	0xCC53, 0x59B4, 0xCC54, 0x59C7, 0xCC55, 0x5B62, 0xCC56, 0x5B65,
+	0xCC57, 0x5B93, 0xCC58, 0x5B95, 0xCC59, 0x5C44, 0xCC5A, 0x5C47,
+	0xCC5B, 0x5CAE, 0xCC5C, 0x5CA4, 0xCC5D, 0x5CA0, 0xCC5E, 0x5CB5,
+	0xCC5F, 0x5CAF, 0xCC60, 0x5CA8, 0xCC61, 0x5CAC, 0xCC62, 0x5C9F,
+	0xCC63, 0x5CA3, 0xCC64, 0x5CAD, 0xCC65, 0x5CA2, 0xCC66, 0x5CAA,
+	0xCC67, 0x5CA7, 0xCC68, 0x5C9D, 0xCC69, 0x5CA5, 0xCC6A, 0x5CB6,
+	0xCC6B, 0x5CB0, 0xCC6C, 0x5CA6, 0xCC6D, 0x5E17, 0xCC6E, 0x5E14,
+	0xCC6F, 0x5E19, 0xCC70, 0x5F28, 0xCC71, 0x5F22, 0xCC72, 0x5F23,
+	0xCC73, 0x5F24, 0xCC74, 0x5F54, 0xCC75, 0x5F82, 0xCC76, 0x5F7E,
+	0xCC77, 0x5F7D, 0xCC78, 0x5FDE, 0xCC79, 0x5FE5, 0xCC7A, 0x602D,
+	0xCC7B, 0x6026, 0xCC7C, 0x6019, 0xCC7D, 0x6032, 0xCC7E, 0x600B,
+	0xCCA1, 0x6034, 0xCCA2, 0x600A, 0xCCA3, 0x6017, 0xCCA4, 0x6033,
+	0xCCA5, 0x601A, 0xCCA6, 0x601E, 0xCCA7, 0x602C, 0xCCA8, 0x6022,
+	0xCCA9, 0x600D, 0xCCAA, 0x6010, 0xCCAB, 0x602E, 0xCCAC, 0x6013,
+	0xCCAD, 0x6011, 0xCCAE, 0x600C, 0xCCAF, 0x6009, 0xCCB0, 0x601C,
+	0xCCB1, 0x6214, 0xCCB2, 0x623D, 0xCCB3, 0x62AD, 0xCCB4, 0x62B4,
+	0xCCB5, 0x62D1, 0xCCB6, 0x62BE, 0xCCB7, 0x62AA, 0xCCB8, 0x62B6,
+	0xCCB9, 0x62CA, 0xCCBA, 0x62AE, 0xCCBB, 0x62B3, 0xCCBC, 0x62AF,
+	0xCCBD, 0x62BB, 0xCCBE, 0x62A9, 0xCCBF, 0x62B0, 0xCCC0, 0x62B8,
+	0xCCC1, 0x653D, 0xCCC2, 0x65A8, 0xCCC3, 0x65BB, 0xCCC4, 0x6609,
+	0xCCC5, 0x65FC, 0xCCC6, 0x6604, 0xCCC7, 0x6612, 0xCCC8, 0x6608,
+	0xCCC9, 0x65FB, 0xCCCA, 0x6603, 0xCCCB, 0x660B, 0xCCCC, 0x660D,
+	0xCCCD, 0x6605, 0xCCCE, 0x65FD, 0xCCCF, 0x6611, 0xCCD0, 0x6610,
+	0xCCD1, 0x66F6, 0xCCD2, 0x670A, 0xCCD3, 0x6785, 0xCCD4, 0x676C,
+	0xCCD5, 0x678E, 0xCCD6, 0x6792, 0xCCD7, 0x6776, 0xCCD8, 0x677B,
+	0xCCD9, 0x6798, 0xCCDA, 0x6786, 0xCCDB, 0x6784, 0xCCDC, 0x6774,
+	0xCCDD, 0x678D, 0xCCDE, 0x678C, 0xCCDF, 0x677A, 0xCCE0, 0x679F,
+	0xCCE1, 0x6791, 0xCCE2, 0x6799, 0xCCE3, 0x6783, 0xCCE4, 0x677D,
+	0xCCE5, 0x6781, 0xCCE6, 0x6778, 0xCCE7, 0x6779, 0xCCE8, 0x6794,
+	0xCCE9, 0x6B25, 0xCCEA, 0x6B80, 0xCCEB, 0x6B7E, 0xCCEC, 0x6BDE,
+	0xCCED, 0x6C1D, 0xCCEE, 0x6C93, 0xCCEF, 0x6CEC, 0xCCF0, 0x6CEB,
+	0xCCF1, 0x6CEE, 0xCCF2, 0x6CD9, 0xCCF3, 0x6CB6, 0xCCF4, 0x6CD4,
+	0xCCF5, 0x6CAD, 0xCCF6, 0x6CE7, 0xCCF7, 0x6CB7, 0xCCF8, 0x6CD0,
+	0xCCF9, 0x6CC2, 0xCCFA, 0x6CBA, 0xCCFB, 0x6CC3, 0xCCFC, 0x6CC6,
+	0xCCFD, 0x6CED, 0xCCFE, 0x6CF2, 0xCD40, 0x6CD2, 0xCD41, 0x6CDD,
+	0xCD42, 0x6CB4, 0xCD43, 0x6C8A, 0xCD44, 0x6C9D, 0xCD45, 0x6C80,
+	0xCD46, 0x6CDE, 0xCD47, 0x6CC0, 0xCD48, 0x6D30, 0xCD49, 0x6CCD,
+	0xCD4A, 0x6CC7, 0xCD4B, 0x6CB0, 0xCD4C, 0x6CF9, 0xCD4D, 0x6CCF,
+	0xCD4E, 0x6CE9, 0xCD4F, 0x6CD1, 0xCD50, 0x7094, 0xCD51, 0x7098,
+	0xCD52, 0x7085, 0xCD53, 0x7093, 0xCD54, 0x7086, 0xCD55, 0x7084,
+	0xCD56, 0x7091, 0xCD57, 0x7096, 0xCD58, 0x7082, 0xCD59, 0x709A,
+	0xCD5A, 0x7083, 0xCD5B, 0x726A, 0xCD5C, 0x72D6, 0xCD5D, 0x72CB,
+	0xCD5E, 0x72D8, 0xCD5F, 0x72C9, 0xCD60, 0x72DC, 0xCD61, 0x72D2,
+	0xCD62, 0x72D4, 0xCD63, 0x72DA, 0xCD64, 0x72CC, 0xCD65, 0x72D1,
+	0xCD66, 0x73A4, 0xCD67, 0x73A1, 0xCD68, 0x73AD, 0xCD69, 0x73A6,
+	0xCD6A, 0x73A2, 0xCD6B, 0x73A0, 0xCD6C, 0x73AC, 0xCD6D, 0x739D,
+	0xCD6E, 0x74DD, 0xCD6F, 0x74E8, 0xCD70, 0x753F, 0xCD71, 0x7540,
+	0xCD72, 0x753E, 0xCD73, 0x758C, 0xCD74, 0x7598, 0xCD75, 0x76AF,
+	0xCD76, 0x76F3, 0xCD77, 0x76F1, 0xCD78, 0x76F0, 0xCD79, 0x76F5,
+	0xCD7A, 0x77F8, 0xCD7B, 0x77FC, 0xCD7C, 0x77F9, 0xCD7D, 0x77FB,
+	0xCD7E, 0x77FA, 0xCDA1, 0x77F7, 0xCDA2, 0x7942, 0xCDA3, 0x793F,
+	0xCDA4, 0x79C5, 0xCDA5, 0x7A78, 0xCDA6, 0x7A7B, 0xCDA7, 0x7AFB,
+	0xCDA8, 0x7C75, 0xCDA9, 0x7CFD, 0xCDAA, 0x8035, 0xCDAB, 0x808F,
+	0xCDAC, 0x80AE, 0xCDAD, 0x80A3, 0xCDAE, 0x80B8, 0xCDAF, 0x80B5,
+	0xCDB0, 0x80AD, 0xCDB1, 0x8220, 0xCDB2, 0x82A0, 0xCDB3, 0x82C0,
+	0xCDB4, 0x82AB, 0xCDB5, 0x829A, 0xCDB6, 0x8298, 0xCDB7, 0x829B,
+	0xCDB8, 0x82B5, 0xCDB9, 0x82A7, 0xCDBA, 0x82AE, 0xCDBB, 0x82BC,
+	0xCDBC, 0x829E, 0xCDBD, 0x82BA, 0xCDBE, 0x82B4, 0xCDBF, 0x82A8,
+	0xCDC0, 0x82A1, 0xCDC1, 0x82A9, 0xCDC2, 0x82C2, 0xCDC3, 0x82A4,
+	0xCDC4, 0x82C3, 0xCDC5, 0x82B6, 0xCDC6, 0x82A2, 0xCDC7, 0x8670,
+	0xCDC8, 0x866F, 0xCDC9, 0x866D, 0xCDCA, 0x866E, 0xCDCB, 0x8C56,
+	0xCDCC, 0x8FD2, 0xCDCD, 0x8FCB, 0xCDCE, 0x8FD3, 0xCDCF, 0x8FCD,
+	0xCDD0, 0x8FD6, 0xCDD1, 0x8FD5, 0xCDD2, 0x8FD7, 0xCDD3, 0x90B2,
+	0xCDD4, 0x90B4, 0xCDD5, 0x90AF, 0xCDD6, 0x90B3, 0xCDD7, 0x90B0,
+	0xCDD8, 0x9639, 0xCDD9, 0x963D, 0xCDDA, 0x963C, 0xCDDB, 0x963A,
+	0xCDDC, 0x9643, 0xCDDD, 0x4FCD, 0xCDDE, 0x4FC5, 0xCDDF, 0x4FD3,
+	0xCDE0, 0x4FB2, 0xCDE1, 0x4FC9, 0xCDE2, 0x4FCB, 0xCDE3, 0x4FC1,
+	0xCDE4, 0x4FD4, 0xCDE5, 0x4FDC, 0xCDE6, 0x4FD9, 0xCDE7, 0x4FBB,
+	0xCDE8, 0x4FB3, 0xCDE9, 0x4FDB, 0xCDEA, 0x4FC7, 0xCDEB, 0x4FD6,
+	0xCDEC, 0x4FBA, 0xCDED, 0x4FC0, 0xCDEE, 0x4FB9, 0xCDEF, 0x4FEC,
+	0xCDF0, 0x5244, 0xCDF1, 0x5249, 0xCDF2, 0x52C0, 0xCDF3, 0x52C2,
+	0xCDF4, 0x533D, 0xCDF5, 0x537C, 0xCDF6, 0x5397, 0xCDF7, 0x5396,
+	0xCDF8, 0x5399, 0xCDF9, 0x5398, 0xCDFA, 0x54BA, 0xCDFB, 0x54A1,
+	0xCDFC, 0x54AD, 0xCDFD, 0x54A5, 0xCDFE, 0x54CF, 0xCE40, 0x54C3,
+	0xCE41, 0x830D, 0xCE42, 0x54B7, 0xCE43, 0x54AE, 0xCE44, 0x54D6,
+	0xCE45, 0x54B6, 0xCE46, 0x54C5, 0xCE47, 0x54C6, 0xCE48, 0x54A0,
+	0xCE49, 0x5470, 0xCE4A, 0x54BC, 0xCE4B, 0x54A2, 0xCE4C, 0x54BE,
+	0xCE4D, 0x5472, 0xCE4E, 0x54DE, 0xCE4F, 0x54B0, 0xCE50, 0x57B5,
+	0xCE51, 0x579E, 0xCE52, 0x579F, 0xCE53, 0x57A4, 0xCE54, 0x578C,
+	0xCE55, 0x5797, 0xCE56, 0x579D, 0xCE57, 0x579B, 0xCE58, 0x5794,
+	0xCE59, 0x5798, 0xCE5A, 0x578F, 0xCE5B, 0x5799, 0xCE5C, 0x57A5,
+	0xCE5D, 0x579A, 0xCE5E, 0x5795, 0xCE5F, 0x58F4, 0xCE60, 0x590D,
+	0xCE61, 0x5953, 0xCE62, 0x59E1, 0xCE63, 0x59DE, 0xCE64, 0x59EE,
+	0xCE65, 0x5A00, 0xCE66, 0x59F1, 0xCE67, 0x59DD, 0xCE68, 0x59FA,
+	0xCE69, 0x59FD, 0xCE6A, 0x59FC, 0xCE6B, 0x59F6, 0xCE6C, 0x59E4,
+	0xCE6D, 0x59F2, 0xCE6E, 0x59F7, 0xCE6F, 0x59DB, 0xCE70, 0x59E9,
+	0xCE71, 0x59F3, 0xCE72, 0x59F5, 0xCE73, 0x59E0, 0xCE74, 0x59FE,
+	0xCE75, 0x59F4, 0xCE76, 0x59ED, 0xCE77, 0x5BA8, 0xCE78, 0x5C4C,
+	0xCE79, 0x5CD0, 0xCE7A, 0x5CD8, 0xCE7B, 0x5CCC, 0xCE7C, 0x5CD7,
+	0xCE7D, 0x5CCB, 0xCE7E, 0x5CDB, 0xCEA1, 0x5CDE, 0xCEA2, 0x5CDA,
+	0xCEA3, 0x5CC9, 0xCEA4, 0x5CC7, 0xCEA5, 0x5CCA, 0xCEA6, 0x5CD6,
+	0xCEA7, 0x5CD3, 0xCEA8, 0x5CD4, 0xCEA9, 0x5CCF, 0xCEAA, 0x5CC8,
+	0xCEAB, 0x5CC6, 0xCEAC, 0x5CCE, 0xCEAD, 0x5CDF, 0xCEAE, 0x5CF8,
+	0xCEAF, 0x5DF9, 0xCEB0, 0x5E21, 0xCEB1, 0x5E22, 0xCEB2, 0x5E23,
+	0xCEB3, 0x5E20, 0xCEB4, 0x5E24, 0xCEB5, 0x5EB0, 0xCEB6, 0x5EA4,
+	0xCEB7, 0x5EA2, 0xCEB8, 0x5E9B, 0xCEB9, 0x5EA3, 0xCEBA, 0x5EA5,
+	0xCEBB, 0x5F07, 0xCEBC, 0x5F2E, 0xCEBD, 0x5F56, 0xCEBE, 0x5F86,
+	0xCEBF, 0x6037, 0xCEC0, 0x6039, 0xCEC1, 0x6054, 0xCEC2, 0x6072,
+	0xCEC3, 0x605E, 0xCEC4, 0x6045, 0xCEC5, 0x6053, 0xCEC6, 0x6047,
+	0xCEC7, 0x6049, 0xCEC8, 0x605B, 0xCEC9, 0x604C, 0xCECA, 0x6040,
+	0xCECB, 0x6042, 0xCECC, 0x605F, 0xCECD, 0x6024, 0xCECE, 0x6044,
+	0xCECF, 0x6058, 0xCED0, 0x6066, 0xCED1, 0x606E, 0xCED2, 0x6242,
+	0xCED3, 0x6243, 0xCED4, 0x62CF, 0xCED5, 0x630D, 0xCED6, 0x630B,
+	0xCED7, 0x62F5, 0xCED8, 0x630E, 0xCED9, 0x6303, 0xCEDA, 0x62EB,
+	0xCEDB, 0x62F9, 0xCEDC, 0x630F, 0xCEDD, 0x630C, 0xCEDE, 0x62F8,
+	0xCEDF, 0x62F6, 0xCEE0, 0x6300, 0xCEE1, 0x6313, 0xCEE2, 0x6314,
+	0xCEE3, 0x62FA, 0xCEE4, 0x6315, 0xCEE5, 0x62FB, 0xCEE6, 0x62F0,
+	0xCEE7, 0x6541, 0xCEE8, 0x6543, 0xCEE9, 0x65AA, 0xCEEA, 0x65BF,
+	0xCEEB, 0x6636, 0xCEEC, 0x6621, 0xCEED, 0x6632, 0xCEEE, 0x6635,
+	0xCEEF, 0x661C, 0xCEF0, 0x6626, 0xCEF1, 0x6622, 0xCEF2, 0x6633,
+	0xCEF3, 0x662B, 0xCEF4, 0x663A, 0xCEF5, 0x661D, 0xCEF6, 0x6634,
+	0xCEF7, 0x6639, 0xCEF8, 0x662E, 0xCEF9, 0x670F, 0xCEFA, 0x6710,
+	0xCEFB, 0x67C1, 0xCEFC, 0x67F2, 0xCEFD, 0x67C8, 0xCEFE, 0x67BA,
+	0xCF40, 0x67DC, 0xCF41, 0x67BB, 0xCF42, 0x67F8, 0xCF43, 0x67D8,
+	0xCF44, 0x67C0, 0xCF45, 0x67B7, 0xCF46, 0x67C5, 0xCF47, 0x67EB,
+	0xCF48, 0x67E4, 0xCF49, 0x67DF, 0xCF4A, 0x67B5, 0xCF4B, 0x67CD,
+	0xCF4C, 0x67B3, 0xCF4D, 0x67F7, 0xCF4E, 0x67F6, 0xCF4F, 0x67EE,
+	0xCF50, 0x67E3, 0xCF51, 0x67C2, 0xCF52, 0x67B9, 0xCF53, 0x67CE,
+	0xCF54, 0x67E7, 0xCF55, 0x67F0, 0xCF56, 0x67B2, 0xCF57, 0x67FC,
+	0xCF58, 0x67C6, 0xCF59, 0x67ED, 0xCF5A, 0x67CC, 0xCF5B, 0x67AE,
+	0xCF5C, 0x67E6, 0xCF5D, 0x67DB, 0xCF5E, 0x67FA, 0xCF5F, 0x67C9,
+	0xCF60, 0x67CA, 0xCF61, 0x67C3, 0xCF62, 0x67EA, 0xCF63, 0x67CB,
+	0xCF64, 0x6B28, 0xCF65, 0x6B82, 0xCF66, 0x6B84, 0xCF67, 0x6BB6,
+	0xCF68, 0x6BD6, 0xCF69, 0x6BD8, 0xCF6A, 0x6BE0, 0xCF6B, 0x6C20,
+	0xCF6C, 0x6C21, 0xCF6D, 0x6D28, 0xCF6E, 0x6D34, 0xCF6F, 0x6D2D,
+	0xCF70, 0x6D1F, 0xCF71, 0x6D3C, 0xCF72, 0x6D3F, 0xCF73, 0x6D12,
+	0xCF74, 0x6D0A, 0xCF75, 0x6CDA, 0xCF76, 0x6D33, 0xCF77, 0x6D04,
+	0xCF78, 0x6D19, 0xCF79, 0x6D3A, 0xCF7A, 0x6D1A, 0xCF7B, 0x6D11,
+	0xCF7C, 0x6D00, 0xCF7D, 0x6D1D, 0xCF7E, 0x6D42, 0xCFA1, 0x6D01,
+	0xCFA2, 0x6D18, 0xCFA3, 0x6D37, 0xCFA4, 0x6D03, 0xCFA5, 0x6D0F,
+	0xCFA6, 0x6D40, 0xCFA7, 0x6D07, 0xCFA8, 0x6D20, 0xCFA9, 0x6D2C,
+	0xCFAA, 0x6D08, 0xCFAB, 0x6D22, 0xCFAC, 0x6D09, 0xCFAD, 0x6D10,
+	0xCFAE, 0x70B7, 0xCFAF, 0x709F, 0xCFB0, 0x70BE, 0xCFB1, 0x70B1,
+	0xCFB2, 0x70B0, 0xCFB3, 0x70A1, 0xCFB4, 0x70B4, 0xCFB5, 0x70B5,
+	0xCFB6, 0x70A9, 0xCFB7, 0x7241, 0xCFB8, 0x7249, 0xCFB9, 0x724A,
+	0xCFBA, 0x726C, 0xCFBB, 0x7270, 0xCFBC, 0x7273, 0xCFBD, 0x726E,
+	0xCFBE, 0x72CA, 0xCFBF, 0x72E4, 0xCFC0, 0x72E8, 0xCFC1, 0x72EB,
+	0xCFC2, 0x72DF, 0xCFC3, 0x72EA, 0xCFC4, 0x72E6, 0xCFC5, 0x72E3,
+	0xCFC6, 0x7385, 0xCFC7, 0x73CC, 0xCFC8, 0x73C2, 0xCFC9, 0x73C8,
+	0xCFCA, 0x73C5, 0xCFCB, 0x73B9, 0xCFCC, 0x73B6, 0xCFCD, 0x73B5,
+	0xCFCE, 0x73B4, 0xCFCF, 0x73EB, 0xCFD0, 0x73BF, 0xCFD1, 0x73C7,
+	0xCFD2, 0x73BE, 0xCFD3, 0x73C3, 0xCFD4, 0x73C6, 0xCFD5, 0x73B8,
+	0xCFD6, 0x73CB, 0xCFD7, 0x74EC, 0xCFD8, 0x74EE, 0xCFD9, 0x752E,
+	0xCFDA, 0x7547, 0xCFDB, 0x7548, 0xCFDC, 0x75A7, 0xCFDD, 0x75AA,
+	0xCFDE, 0x7679, 0xCFDF, 0x76C4, 0xCFE0, 0x7708, 0xCFE1, 0x7703,
+	0xCFE2, 0x7704, 0xCFE3, 0x7705, 0xCFE4, 0x770A, 0xCFE5, 0x76F7,
+	0xCFE6, 0x76FB, 0xCFE7, 0x76FA, 0xCFE8, 0x77E7, 0xCFE9, 0x77E8,
+	0xCFEA, 0x7806, 0xCFEB, 0x7811, 0xCFEC, 0x7812, 0xCFED, 0x7805,
+	0xCFEE, 0x7810, 0xCFEF, 0x780F, 0xCFF0, 0x780E, 0xCFF1, 0x7809,
+	0xCFF2, 0x7803, 0xCFF3, 0x7813, 0xCFF4, 0x794A, 0xCFF5, 0x794C,
+	0xCFF6, 0x794B, 0xCFF7, 0x7945, 0xCFF8, 0x7944, 0xCFF9, 0x79D5,
+	0xCFFA, 0x79CD, 0xCFFB, 0x79CF, 0xCFFC, 0x79D6, 0xCFFD, 0x79CE,
+	0xCFFE, 0x7A80, 0xD040, 0x7A7E, 0xD041, 0x7AD1, 0xD042, 0x7B00,
+	0xD043, 0x7B01, 0xD044, 0x7C7A, 0xD045, 0x7C78, 0xD046, 0x7C79,
+	0xD047, 0x7C7F, 0xD048, 0x7C80, 0xD049, 0x7C81, 0xD04A, 0x7D03,
+	0xD04B, 0x7D08, 0xD04C, 0x7D01, 0xD04D, 0x7F58, 0xD04E, 0x7F91,
+	0xD04F, 0x7F8D, 0xD050, 0x7FBE, 0xD051, 0x8007, 0xD052, 0x800E,
+	0xD053, 0x800F, 0xD054, 0x8014, 0xD055, 0x8037, 0xD056, 0x80D8,
+	0xD057, 0x80C7, 0xD058, 0x80E0, 0xD059, 0x80D1, 0xD05A, 0x80C8,
+	0xD05B, 0x80C2, 0xD05C, 0x80D0, 0xD05D, 0x80C5, 0xD05E, 0x80E3,
+	0xD05F, 0x80D9, 0xD060, 0x80DC, 0xD061, 0x80CA, 0xD062, 0x80D5,
+	0xD063, 0x80C9, 0xD064, 0x80CF, 0xD065, 0x80D7, 0xD066, 0x80E6,
+	0xD067, 0x80CD, 0xD068, 0x81FF, 0xD069, 0x8221, 0xD06A, 0x8294,
+	0xD06B, 0x82D9, 0xD06C, 0x82FE, 0xD06D, 0x82F9, 0xD06E, 0x8307,
+	0xD06F, 0x82E8, 0xD070, 0x8300, 0xD071, 0x82D5, 0xD072, 0x833A,
+	0xD073, 0x82EB, 0xD074, 0x82D6, 0xD075, 0x82F4, 0xD076, 0x82EC,
+	0xD077, 0x82E1, 0xD078, 0x82F2, 0xD079, 0x82F5, 0xD07A, 0x830C,
+	0xD07B, 0x82FB, 0xD07C, 0x82F6, 0xD07D, 0x82F0, 0xD07E, 0x82EA,
+	0xD0A1, 0x82E4, 0xD0A2, 0x82E0, 0xD0A3, 0x82FA, 0xD0A4, 0x82F3,
+	0xD0A5, 0x82ED, 0xD0A6, 0x8677, 0xD0A7, 0x8674, 0xD0A8, 0x867C,
+	0xD0A9, 0x8673, 0xD0AA, 0x8841, 0xD0AB, 0x884E, 0xD0AC, 0x8867,
+	0xD0AD, 0x886A, 0xD0AE, 0x8869, 0xD0AF, 0x89D3, 0xD0B0, 0x8A04,
+	0xD0B1, 0x8A07, 0xD0B2, 0x8D72, 0xD0B3, 0x8FE3, 0xD0B4, 0x8FE1,
+	0xD0B5, 0x8FEE, 0xD0B6, 0x8FE0, 0xD0B7, 0x90F1, 0xD0B8, 0x90BD,
+	0xD0B9, 0x90BF, 0xD0BA, 0x90D5, 0xD0BB, 0x90C5, 0xD0BC, 0x90BE,
+	0xD0BD, 0x90C7, 0xD0BE, 0x90CB, 0xD0BF, 0x90C8, 0xD0C0, 0x91D4,
+	0xD0C1, 0x91D3, 0xD0C2, 0x9654, 0xD0C3, 0x964F, 0xD0C4, 0x9651,
+	0xD0C5, 0x9653, 0xD0C6, 0x964A, 0xD0C7, 0x964E, 0xD0C8, 0x501E,
+	0xD0C9, 0x5005, 0xD0CA, 0x5007, 0xD0CB, 0x5013, 0xD0CC, 0x5022,
+	0xD0CD, 0x5030, 0xD0CE, 0x501B, 0xD0CF, 0x4FF5, 0xD0D0, 0x4FF4,
+	0xD0D1, 0x5033, 0xD0D2, 0x5037, 0xD0D3, 0x502C, 0xD0D4, 0x4FF6,
+	0xD0D5, 0x4FF7, 0xD0D6, 0x5017, 0xD0D7, 0x501C, 0xD0D8, 0x5020,
+	0xD0D9, 0x5027, 0xD0DA, 0x5035, 0xD0DB, 0x502F, 0xD0DC, 0x5031,
+	0xD0DD, 0x500E, 0xD0DE, 0x515A, 0xD0DF, 0x5194, 0xD0E0, 0x5193,
+	0xD0E1, 0x51CA, 0xD0E2, 0x51C4, 0xD0E3, 0x51C5, 0xD0E4, 0x51C8,
+	0xD0E5, 0x51CE, 0xD0E6, 0x5261, 0xD0E7, 0x525A, 0xD0E8, 0x5252,
+	0xD0E9, 0x525E, 0xD0EA, 0x525F, 0xD0EB, 0x5255, 0xD0EC, 0x5262,
+	0xD0ED, 0x52CD, 0xD0EE, 0x530E, 0xD0EF, 0x539E, 0xD0F0, 0x5526,
+	0xD0F1, 0x54E2, 0xD0F2, 0x5517, 0xD0F3, 0x5512, 0xD0F4, 0x54E7,
+	0xD0F5, 0x54F3, 0xD0F6, 0x54E4, 0xD0F7, 0x551A, 0xD0F8, 0x54FF,
+	0xD0F9, 0x5504, 0xD0FA, 0x5508, 0xD0FB, 0x54EB, 0xD0FC, 0x5511,
+	0xD0FD, 0x5505, 0xD0FE, 0x54F1, 0xD140, 0x550A, 0xD141, 0x54FB,
+	0xD142, 0x54F7, 0xD143, 0x54F8, 0xD144, 0x54E0, 0xD145, 0x550E,
+	0xD146, 0x5503, 0xD147, 0x550B, 0xD148, 0x5701, 0xD149, 0x5702,
+	0xD14A, 0x57CC, 0xD14B, 0x5832, 0xD14C, 0x57D5, 0xD14D, 0x57D2,
+	0xD14E, 0x57BA, 0xD14F, 0x57C6, 0xD150, 0x57BD, 0xD151, 0x57BC,
+	0xD152, 0x57B8, 0xD153, 0x57B6, 0xD154, 0x57BF, 0xD155, 0x57C7,
+	0xD156, 0x57D0, 0xD157, 0x57B9, 0xD158, 0x57C1, 0xD159, 0x590E,
+	0xD15A, 0x594A, 0xD15B, 0x5A19, 0xD15C, 0x5A16, 0xD15D, 0x5A2D,
+	0xD15E, 0x5A2E, 0xD15F, 0x5A15, 0xD160, 0x5A0F, 0xD161, 0x5A17,
+	0xD162, 0x5A0A, 0xD163, 0x5A1E, 0xD164, 0x5A33, 0xD165, 0x5B6C,
+	0xD166, 0x5BA7, 0xD167, 0x5BAD, 0xD168, 0x5BAC, 0xD169, 0x5C03,
+	0xD16A, 0x5C56, 0xD16B, 0x5C54, 0xD16C, 0x5CEC, 0xD16D, 0x5CFF,
+	0xD16E, 0x5CEE, 0xD16F, 0x5CF1, 0xD170, 0x5CF7, 0xD171, 0x5D00,
+	0xD172, 0x5CF9, 0xD173, 0x5E29, 0xD174, 0x5E28, 0xD175, 0x5EA8,
+	0xD176, 0x5EAE, 0xD177, 0x5EAA, 0xD178, 0x5EAC, 0xD179, 0x5F33,
+	0xD17A, 0x5F30, 0xD17B, 0x5F67, 0xD17C, 0x605D, 0xD17D, 0x605A,
+	0xD17E, 0x6067, 0xD1A1, 0x6041, 0xD1A2, 0x60A2, 0xD1A3, 0x6088,
+	0xD1A4, 0x6080, 0xD1A5, 0x6092, 0xD1A6, 0x6081, 0xD1A7, 0x609D,
+	0xD1A8, 0x6083, 0xD1A9, 0x6095, 0xD1AA, 0x609B, 0xD1AB, 0x6097,
+	0xD1AC, 0x6087, 0xD1AD, 0x609C, 0xD1AE, 0x608E, 0xD1AF, 0x6219,
+	0xD1B0, 0x6246, 0xD1B1, 0x62F2, 0xD1B2, 0x6310, 0xD1B3, 0x6356,
+	0xD1B4, 0x632C, 0xD1B5, 0x6344, 0xD1B6, 0x6345, 0xD1B7, 0x6336,
+	0xD1B8, 0x6343, 0xD1B9, 0x63E4, 0xD1BA, 0x6339, 0xD1BB, 0x634B,
+	0xD1BC, 0x634A, 0xD1BD, 0x633C, 0xD1BE, 0x6329, 0xD1BF, 0x6341,
+	0xD1C0, 0x6334, 0xD1C1, 0x6358, 0xD1C2, 0x6354, 0xD1C3, 0x6359,
+	0xD1C4, 0x632D, 0xD1C5, 0x6347, 0xD1C6, 0x6333, 0xD1C7, 0x635A,
+	0xD1C8, 0x6351, 0xD1C9, 0x6338, 0xD1CA, 0x6357, 0xD1CB, 0x6340,
+	0xD1CC, 0x6348, 0xD1CD, 0x654A, 0xD1CE, 0x6546, 0xD1CF, 0x65C6,
+	0xD1D0, 0x65C3, 0xD1D1, 0x65C4, 0xD1D2, 0x65C2, 0xD1D3, 0x664A,
+	0xD1D4, 0x665F, 0xD1D5, 0x6647, 0xD1D6, 0x6651, 0xD1D7, 0x6712,
+	0xD1D8, 0x6713, 0xD1D9, 0x681F, 0xD1DA, 0x681A, 0xD1DB, 0x6849,
+	0xD1DC, 0x6832, 0xD1DD, 0x6833, 0xD1DE, 0x683B, 0xD1DF, 0x684B,
+	0xD1E0, 0x684F, 0xD1E1, 0x6816, 0xD1E2, 0x6831, 0xD1E3, 0x681C,
+	0xD1E4, 0x6835, 0xD1E5, 0x682B, 0xD1E6, 0x682D, 0xD1E7, 0x682F,
+	0xD1E8, 0x684E, 0xD1E9, 0x6844, 0xD1EA, 0x6834, 0xD1EB, 0x681D,
+	0xD1EC, 0x6812, 0xD1ED, 0x6814, 0xD1EE, 0x6826, 0xD1EF, 0x6828,
+	0xD1F0, 0x682E, 0xD1F1, 0x684D, 0xD1F2, 0x683A, 0xD1F3, 0x6825,
+	0xD1F4, 0x6820, 0xD1F5, 0x6B2C, 0xD1F6, 0x6B2F, 0xD1F7, 0x6B2D,
+	0xD1F8, 0x6B31, 0xD1F9, 0x6B34, 0xD1FA, 0x6B6D, 0xD1FB, 0x8082,
+	0xD1FC, 0x6B88, 0xD1FD, 0x6BE6, 0xD1FE, 0x6BE4, 0xD240, 0x6BE8,
+	0xD241, 0x6BE3, 0xD242, 0x6BE2, 0xD243, 0x6BE7, 0xD244, 0x6C25,
+	0xD245, 0x6D7A, 0xD246, 0x6D63, 0xD247, 0x6D64, 0xD248, 0x6D76,
+	0xD249, 0x6D0D, 0xD24A, 0x6D61, 0xD24B, 0x6D92, 0xD24C, 0x6D58,
+	0xD24D, 0x6D62, 0xD24E, 0x6D6D, 0xD24F, 0x6D6F, 0xD250, 0x6D91,
+	0xD251, 0x6D8D, 0xD252, 0x6DEF, 0xD253, 0x6D7F, 0xD254, 0x6D86,
+	0xD255, 0x6D5E, 0xD256, 0x6D67, 0xD257, 0x6D60, 0xD258, 0x6D97,
+	0xD259, 0x6D70, 0xD25A, 0x6D7C, 0xD25B, 0x6D5F, 0xD25C, 0x6D82,
+	0xD25D, 0x6D98, 0xD25E, 0x6D2F, 0xD25F, 0x6D68, 0xD260, 0x6D8B,
+	0xD261, 0x6D7E, 0xD262, 0x6D80, 0xD263, 0x6D84, 0xD264, 0x6D16,
+	0xD265, 0x6D83, 0xD266, 0x6D7B, 0xD267, 0x6D7D, 0xD268, 0x6D75,
+	0xD269, 0x6D90, 0xD26A, 0x70DC, 0xD26B, 0x70D3, 0xD26C, 0x70D1,
+	0xD26D, 0x70DD, 0xD26E, 0x70CB, 0xD26F, 0x7F39, 0xD270, 0x70E2,
+	0xD271, 0x70D7, 0xD272, 0x70D2, 0xD273, 0x70DE, 0xD274, 0x70E0,
+	0xD275, 0x70D4, 0xD276, 0x70CD, 0xD277, 0x70C5, 0xD278, 0x70C6,
+	0xD279, 0x70C7, 0xD27A, 0x70DA, 0xD27B, 0x70CE, 0xD27C, 0x70E1,
+	0xD27D, 0x7242, 0xD27E, 0x7278, 0xD2A1, 0x7277, 0xD2A2, 0x7276,
+	0xD2A3, 0x7300, 0xD2A4, 0x72FA, 0xD2A5, 0x72F4, 0xD2A6, 0x72FE,
+	0xD2A7, 0x72F6, 0xD2A8, 0x72F3, 0xD2A9, 0x72FB, 0xD2AA, 0x7301,
+	0xD2AB, 0x73D3, 0xD2AC, 0x73D9, 0xD2AD, 0x73E5, 0xD2AE, 0x73D6,
+	0xD2AF, 0x73BC, 0xD2B0, 0x73E7, 0xD2B1, 0x73E3, 0xD2B2, 0x73E9,
+	0xD2B3, 0x73DC, 0xD2B4, 0x73D2, 0xD2B5, 0x73DB, 0xD2B6, 0x73D4,
+	0xD2B7, 0x73DD, 0xD2B8, 0x73DA, 0xD2B9, 0x73D7, 0xD2BA, 0x73D8,
+	0xD2BB, 0x73E8, 0xD2BC, 0x74DE, 0xD2BD, 0x74DF, 0xD2BE, 0x74F4,
+	0xD2BF, 0x74F5, 0xD2C0, 0x7521, 0xD2C1, 0x755B, 0xD2C2, 0x755F,
+	0xD2C3, 0x75B0, 0xD2C4, 0x75C1, 0xD2C5, 0x75BB, 0xD2C6, 0x75C4,
+	0xD2C7, 0x75C0, 0xD2C8, 0x75BF, 0xD2C9, 0x75B6, 0xD2CA, 0x75BA,
+	0xD2CB, 0x768A, 0xD2CC, 0x76C9, 0xD2CD, 0x771D, 0xD2CE, 0x771B,
+	0xD2CF, 0x7710, 0xD2D0, 0x7713, 0xD2D1, 0x7712, 0xD2D2, 0x7723,
+	0xD2D3, 0x7711, 0xD2D4, 0x7715, 0xD2D5, 0x7719, 0xD2D6, 0x771A,
+	0xD2D7, 0x7722, 0xD2D8, 0x7727, 0xD2D9, 0x7823, 0xD2DA, 0x782C,
+	0xD2DB, 0x7822, 0xD2DC, 0x7835, 0xD2DD, 0x782F, 0xD2DE, 0x7828,
+	0xD2DF, 0x782E, 0xD2E0, 0x782B, 0xD2E1, 0x7821, 0xD2E2, 0x7829,
+	0xD2E3, 0x7833, 0xD2E4, 0x782A, 0xD2E5, 0x7831, 0xD2E6, 0x7954,
+	0xD2E7, 0x795B, 0xD2E8, 0x794F, 0xD2E9, 0x795C, 0xD2EA, 0x7953,
+	0xD2EB, 0x7952, 0xD2EC, 0x7951, 0xD2ED, 0x79EB, 0xD2EE, 0x79EC,
+	0xD2EF, 0x79E0, 0xD2F0, 0x79EE, 0xD2F1, 0x79ED, 0xD2F2, 0x79EA,
+	0xD2F3, 0x79DC, 0xD2F4, 0x79DE, 0xD2F5, 0x79DD, 0xD2F6, 0x7A86,
+	0xD2F7, 0x7A89, 0xD2F8, 0x7A85, 0xD2F9, 0x7A8B, 0xD2FA, 0x7A8C,
+	0xD2FB, 0x7A8A, 0xD2FC, 0x7A87, 0xD2FD, 0x7AD8, 0xD2FE, 0x7B10,
+	0xD340, 0x7B04, 0xD341, 0x7B13, 0xD342, 0x7B05, 0xD343, 0x7B0F,
+	0xD344, 0x7B08, 0xD345, 0x7B0A, 0xD346, 0x7B0E, 0xD347, 0x7B09,
+	0xD348, 0x7B12, 0xD349, 0x7C84, 0xD34A, 0x7C91, 0xD34B, 0x7C8A,
+	0xD34C, 0x7C8C, 0xD34D, 0x7C88, 0xD34E, 0x7C8D, 0xD34F, 0x7C85,
+	0xD350, 0x7D1E, 0xD351, 0x7D1D, 0xD352, 0x7D11, 0xD353, 0x7D0E,
+	0xD354, 0x7D18, 0xD355, 0x7D16, 0xD356, 0x7D13, 0xD357, 0x7D1F,
+	0xD358, 0x7D12, 0xD359, 0x7D0F, 0xD35A, 0x7D0C, 0xD35B, 0x7F5C,
+	0xD35C, 0x7F61, 0xD35D, 0x7F5E, 0xD35E, 0x7F60, 0xD35F, 0x7F5D,
+	0xD360, 0x7F5B, 0xD361, 0x7F96, 0xD362, 0x7F92, 0xD363, 0x7FC3,
+	0xD364, 0x7FC2, 0xD365, 0x7FC0, 0xD366, 0x8016, 0xD367, 0x803E,
+	0xD368, 0x8039, 0xD369, 0x80FA, 0xD36A, 0x80F2, 0xD36B, 0x80F9,
+	0xD36C, 0x80F5, 0xD36D, 0x8101, 0xD36E, 0x80FB, 0xD36F, 0x8100,
+	0xD370, 0x8201, 0xD371, 0x822F, 0xD372, 0x8225, 0xD373, 0x8333,
+	0xD374, 0x832D, 0xD375, 0x8344, 0xD376, 0x8319, 0xD377, 0x8351,
+	0xD378, 0x8325, 0xD379, 0x8356, 0xD37A, 0x833F, 0xD37B, 0x8341,
+	0xD37C, 0x8326, 0xD37D, 0x831C, 0xD37E, 0x8322, 0xD3A1, 0x8342,
+	0xD3A2, 0x834E, 0xD3A3, 0x831B, 0xD3A4, 0x832A, 0xD3A5, 0x8308,
+	0xD3A6, 0x833C, 0xD3A7, 0x834D, 0xD3A8, 0x8316, 0xD3A9, 0x8324,
+	0xD3AA, 0x8320, 0xD3AB, 0x8337, 0xD3AC, 0x832F, 0xD3AD, 0x8329,
+	0xD3AE, 0x8347, 0xD3AF, 0x8345, 0xD3B0, 0x834C, 0xD3B1, 0x8353,
+	0xD3B2, 0x831E, 0xD3B3, 0x832C, 0xD3B4, 0x834B, 0xD3B5, 0x8327,
+	0xD3B6, 0x8348, 0xD3B7, 0x8653, 0xD3B8, 0x8652, 0xD3B9, 0x86A2,
+	0xD3BA, 0x86A8, 0xD3BB, 0x8696, 0xD3BC, 0x868D, 0xD3BD, 0x8691,
+	0xD3BE, 0x869E, 0xD3BF, 0x8687, 0xD3C0, 0x8697, 0xD3C1, 0x8686,
+	0xD3C2, 0x868B, 0xD3C3, 0x869A, 0xD3C4, 0x8685, 0xD3C5, 0x86A5,
+	0xD3C6, 0x8699, 0xD3C7, 0x86A1, 0xD3C8, 0x86A7, 0xD3C9, 0x8695,
+	0xD3CA, 0x8698, 0xD3CB, 0x868E, 0xD3CC, 0x869D, 0xD3CD, 0x8690,
+	0xD3CE, 0x8694, 0xD3CF, 0x8843, 0xD3D0, 0x8844, 0xD3D1, 0x886D,
+	0xD3D2, 0x8875, 0xD3D3, 0x8876, 0xD3D4, 0x8872, 0xD3D5, 0x8880,
+	0xD3D6, 0x8871, 0xD3D7, 0x887F, 0xD3D8, 0x886F, 0xD3D9, 0x8883,
+	0xD3DA, 0x887E, 0xD3DB, 0x8874, 0xD3DC, 0x887C, 0xD3DD, 0x8A12,
+	0xD3DE, 0x8C47, 0xD3DF, 0x8C57, 0xD3E0, 0x8C7B, 0xD3E1, 0x8CA4,
+	0xD3E2, 0x8CA3, 0xD3E3, 0x8D76, 0xD3E4, 0x8D78, 0xD3E5, 0x8DB5,
+	0xD3E6, 0x8DB7, 0xD3E7, 0x8DB6, 0xD3E8, 0x8ED1, 0xD3E9, 0x8ED3,
+	0xD3EA, 0x8FFE, 0xD3EB, 0x8FF5, 0xD3EC, 0x9002, 0xD3ED, 0x8FFF,
+	0xD3EE, 0x8FFB, 0xD3EF, 0x9004, 0xD3F0, 0x8FFC, 0xD3F1, 0x8FF6,
+	0xD3F2, 0x90D6, 0xD3F3, 0x90E0, 0xD3F4, 0x90D9, 0xD3F5, 0x90DA,
+	0xD3F6, 0x90E3, 0xD3F7, 0x90DF, 0xD3F8, 0x90E5, 0xD3F9, 0x90D8,
+	0xD3FA, 0x90DB, 0xD3FB, 0x90D7, 0xD3FC, 0x90DC, 0xD3FD, 0x90E4,
+	0xD3FE, 0x9150, 0xD440, 0x914E, 0xD441, 0x914F, 0xD442, 0x91D5,
+	0xD443, 0x91E2, 0xD444, 0x91DA, 0xD445, 0x965C, 0xD446, 0x965F,
+	0xD447, 0x96BC, 0xD448, 0x98E3, 0xD449, 0x9ADF, 0xD44A, 0x9B2F,
+	0xD44B, 0x4E7F, 0xD44C, 0x5070, 0xD44D, 0x506A, 0xD44E, 0x5061,
+	0xD44F, 0x505E, 0xD450, 0x5060, 0xD451, 0x5053, 0xD452, 0x504B,
+	0xD453, 0x505D, 0xD454, 0x5072, 0xD455, 0x5048, 0xD456, 0x504D,
+	0xD457, 0x5041, 0xD458, 0x505B, 0xD459, 0x504A, 0xD45A, 0x5062,
+	0xD45B, 0x5015, 0xD45C, 0x5045, 0xD45D, 0x505F, 0xD45E, 0x5069,
+	0xD45F, 0x506B, 0xD460, 0x5063, 0xD461, 0x5064, 0xD462, 0x5046,
+	0xD463, 0x5040, 0xD464, 0x506E, 0xD465, 0x5073, 0xD466, 0x5057,
+	0xD467, 0x5051, 0xD468, 0x51D0, 0xD469, 0x526B, 0xD46A, 0x526D,
+	0xD46B, 0x526C, 0xD46C, 0x526E, 0xD46D, 0x52D6, 0xD46E, 0x52D3,
+	0xD46F, 0x532D, 0xD470, 0x539C, 0xD471, 0x5575, 0xD472, 0x5576,
+	0xD473, 0x553C, 0xD474, 0x554D, 0xD475, 0x5550, 0xD476, 0x5534,
+	0xD477, 0x552A, 0xD478, 0x5551, 0xD479, 0x5562, 0xD47A, 0x5536,
+	0xD47B, 0x5535, 0xD47C, 0x5530, 0xD47D, 0x5552, 0xD47E, 0x5545,
+	0xD4A1, 0x550C, 0xD4A2, 0x5532, 0xD4A3, 0x5565, 0xD4A4, 0x554E,
+	0xD4A5, 0x5539, 0xD4A6, 0x5548, 0xD4A7, 0x552D, 0xD4A8, 0x553B,
+	0xD4A9, 0x5540, 0xD4AA, 0x554B, 0xD4AB, 0x570A, 0xD4AC, 0x5707,
+	0xD4AD, 0x57FB, 0xD4AE, 0x5814, 0xD4AF, 0x57E2, 0xD4B0, 0x57F6,
+	0xD4B1, 0x57DC, 0xD4B2, 0x57F4, 0xD4B3, 0x5800, 0xD4B4, 0x57ED,
+	0xD4B5, 0x57FD, 0xD4B6, 0x5808, 0xD4B7, 0x57F8, 0xD4B8, 0x580B,
+	0xD4B9, 0x57F3, 0xD4BA, 0x57CF, 0xD4BB, 0x5807, 0xD4BC, 0x57EE,
+	0xD4BD, 0x57E3, 0xD4BE, 0x57F2, 0xD4BF, 0x57E5, 0xD4C0, 0x57EC,
+	0xD4C1, 0x57E1, 0xD4C2, 0x580E, 0xD4C3, 0x57FC, 0xD4C4, 0x5810,
+	0xD4C5, 0x57E7, 0xD4C6, 0x5801, 0xD4C7, 0x580C, 0xD4C8, 0x57F1,
+	0xD4C9, 0x57E9, 0xD4CA, 0x57F0, 0xD4CB, 0x580D, 0xD4CC, 0x5804,
+	0xD4CD, 0x595C, 0xD4CE, 0x5A60, 0xD4CF, 0x5A58, 0xD4D0, 0x5A55,
+	0xD4D1, 0x5A67, 0xD4D2, 0x5A5E, 0xD4D3, 0x5A38, 0xD4D4, 0x5A35,
+	0xD4D5, 0x5A6D, 0xD4D6, 0x5A50, 0xD4D7, 0x5A5F, 0xD4D8, 0x5A65,
+	0xD4D9, 0x5A6C, 0xD4DA, 0x5A53, 0xD4DB, 0x5A64, 0xD4DC, 0x5A57,
+	0xD4DD, 0x5A43, 0xD4DE, 0x5A5D, 0xD4DF, 0x5A52, 0xD4E0, 0x5A44,
+	0xD4E1, 0x5A5B, 0xD4E2, 0x5A48, 0xD4E3, 0x5A8E, 0xD4E4, 0x5A3E,
+	0xD4E5, 0x5A4D, 0xD4E6, 0x5A39, 0xD4E7, 0x5A4C, 0xD4E8, 0x5A70,
+	0xD4E9, 0x5A69, 0xD4EA, 0x5A47, 0xD4EB, 0x5A51, 0xD4EC, 0x5A56,
+	0xD4ED, 0x5A42, 0xD4EE, 0x5A5C, 0xD4EF, 0x5B72, 0xD4F0, 0x5B6E,
+	0xD4F1, 0x5BC1, 0xD4F2, 0x5BC0, 0xD4F3, 0x5C59, 0xD4F4, 0x5D1E,
+	0xD4F5, 0x5D0B, 0xD4F6, 0x5D1D, 0xD4F7, 0x5D1A, 0xD4F8, 0x5D20,
+	0xD4F9, 0x5D0C, 0xD4FA, 0x5D28, 0xD4FB, 0x5D0D, 0xD4FC, 0x5D26,
+	0xD4FD, 0x5D25, 0xD4FE, 0x5D0F, 0xD540, 0x5D30, 0xD541, 0x5D12,
+	0xD542, 0x5D23, 0xD543, 0x5D1F, 0xD544, 0x5D2E, 0xD545, 0x5E3E,
+	0xD546, 0x5E34, 0xD547, 0x5EB1, 0xD548, 0x5EB4, 0xD549, 0x5EB9,
+	0xD54A, 0x5EB2, 0xD54B, 0x5EB3, 0xD54C, 0x5F36, 0xD54D, 0x5F38,
+	0xD54E, 0x5F9B, 0xD54F, 0x5F96, 0xD550, 0x5F9F, 0xD551, 0x608A,
+	0xD552, 0x6090, 0xD553, 0x6086, 0xD554, 0x60BE, 0xD555, 0x60B0,
+	0xD556, 0x60BA, 0xD557, 0x60D3, 0xD558, 0x60D4, 0xD559, 0x60CF,
+	0xD55A, 0x60E4, 0xD55B, 0x60D9, 0xD55C, 0x60DD, 0xD55D, 0x60C8,
+	0xD55E, 0x60B1, 0xD55F, 0x60DB, 0xD560, 0x60B7, 0xD561, 0x60CA,
+	0xD562, 0x60BF, 0xD563, 0x60C3, 0xD564, 0x60CD, 0xD565, 0x60C0,
+	0xD566, 0x6332, 0xD567, 0x6365, 0xD568, 0x638A, 0xD569, 0x6382,
+	0xD56A, 0x637D, 0xD56B, 0x63BD, 0xD56C, 0x639E, 0xD56D, 0x63AD,
+	0xD56E, 0x639D, 0xD56F, 0x6397, 0xD570, 0x63AB, 0xD571, 0x638E,
+	0xD572, 0x636F, 0xD573, 0x6387, 0xD574, 0x6390, 0xD575, 0x636E,
+	0xD576, 0x63AF, 0xD577, 0x6375, 0xD578, 0x639C, 0xD579, 0x636D,
+	0xD57A, 0x63AE, 0xD57B, 0x637C, 0xD57C, 0x63A4, 0xD57D, 0x633B,
+	0xD57E, 0x639F, 0xD5A1, 0x6378, 0xD5A2, 0x6385, 0xD5A3, 0x6381,
+	0xD5A4, 0x6391, 0xD5A5, 0x638D, 0xD5A6, 0x6370, 0xD5A7, 0x6553,
+	0xD5A8, 0x65CD, 0xD5A9, 0x6665, 0xD5AA, 0x6661, 0xD5AB, 0x665B,
+	0xD5AC, 0x6659, 0xD5AD, 0x665C, 0xD5AE, 0x6662, 0xD5AF, 0x6718,
+	0xD5B0, 0x6879, 0xD5B1, 0x6887, 0xD5B2, 0x6890, 0xD5B3, 0x689C,
+	0xD5B4, 0x686D, 0xD5B5, 0x686E, 0xD5B6, 0x68AE, 0xD5B7, 0x68AB,
+	0xD5B8, 0x6956, 0xD5B9, 0x686F, 0xD5BA, 0x68A3, 0xD5BB, 0x68AC,
+	0xD5BC, 0x68A9, 0xD5BD, 0x6875, 0xD5BE, 0x6874, 0xD5BF, 0x68B2,
+	0xD5C0, 0x688F, 0xD5C1, 0x6877, 0xD5C2, 0x6892, 0xD5C3, 0x687C,
+	0xD5C4, 0x686B, 0xD5C5, 0x6872, 0xD5C6, 0x68AA, 0xD5C7, 0x6880,
+	0xD5C8, 0x6871, 0xD5C9, 0x687E, 0xD5CA, 0x689B, 0xD5CB, 0x6896,
+	0xD5CC, 0x688B, 0xD5CD, 0x68A0, 0xD5CE, 0x6889, 0xD5CF, 0x68A4,
+	0xD5D0, 0x6878, 0xD5D1, 0x687B, 0xD5D2, 0x6891, 0xD5D3, 0x688C,
+	0xD5D4, 0x688A, 0xD5D5, 0x687D, 0xD5D6, 0x6B36, 0xD5D7, 0x6B33,
+	0xD5D8, 0x6B37, 0xD5D9, 0x6B38, 0xD5DA, 0x6B91, 0xD5DB, 0x6B8F,
+	0xD5DC, 0x6B8D, 0xD5DD, 0x6B8E, 0xD5DE, 0x6B8C, 0xD5DF, 0x6C2A,
+	0xD5E0, 0x6DC0, 0xD5E1, 0x6DAB, 0xD5E2, 0x6DB4, 0xD5E3, 0x6DB3,
+	0xD5E4, 0x6E74, 0xD5E5, 0x6DAC, 0xD5E6, 0x6DE9, 0xD5E7, 0x6DE2,
+	0xD5E8, 0x6DB7, 0xD5E9, 0x6DF6, 0xD5EA, 0x6DD4, 0xD5EB, 0x6E00,
+	0xD5EC, 0x6DC8, 0xD5ED, 0x6DE0, 0xD5EE, 0x6DDF, 0xD5EF, 0x6DD6,
+	0xD5F0, 0x6DBE, 0xD5F1, 0x6DE5, 0xD5F2, 0x6DDC, 0xD5F3, 0x6DDD,
+	0xD5F4, 0x6DDB, 0xD5F5, 0x6DF4, 0xD5F6, 0x6DCA, 0xD5F7, 0x6DBD,
+	0xD5F8, 0x6DED, 0xD5F9, 0x6DF0, 0xD5FA, 0x6DBA, 0xD5FB, 0x6DD5,
+	0xD5FC, 0x6DC2, 0xD5FD, 0x6DCF, 0xD5FE, 0x6DC9, 0xD640, 0x6DD0,
+	0xD641, 0x6DF2, 0xD642, 0x6DD3, 0xD643, 0x6DFD, 0xD644, 0x6DD7,
+	0xD645, 0x6DCD, 0xD646, 0x6DE3, 0xD647, 0x6DBB, 0xD648, 0x70FA,
+	0xD649, 0x710D, 0xD64A, 0x70F7, 0xD64B, 0x7117, 0xD64C, 0x70F4,
+	0xD64D, 0x710C, 0xD64E, 0x70F0, 0xD64F, 0x7104, 0xD650, 0x70F3,
+	0xD651, 0x7110, 0xD652, 0x70FC, 0xD653, 0x70FF, 0xD654, 0x7106,
+	0xD655, 0x7113, 0xD656, 0x7100, 0xD657, 0x70F8, 0xD658, 0x70F6,
+	0xD659, 0x710B, 0xD65A, 0x7102, 0xD65B, 0x710E, 0xD65C, 0x727E,
+	0xD65D, 0x727B, 0xD65E, 0x727C, 0xD65F, 0x727F, 0xD660, 0x731D,
+	0xD661, 0x7317, 0xD662, 0x7307, 0xD663, 0x7311, 0xD664, 0x7318,
+	0xD665, 0x730A, 0xD666, 0x7308, 0xD667, 0x72FF, 0xD668, 0x730F,
+	0xD669, 0x731E, 0xD66A, 0x7388, 0xD66B, 0x73F6, 0xD66C, 0x73F8,
+	0xD66D, 0x73F5, 0xD66E, 0x7404, 0xD66F, 0x7401, 0xD670, 0x73FD,
+	0xD671, 0x7407, 0xD672, 0x7400, 0xD673, 0x73FA, 0xD674, 0x73FC,
+	0xD675, 0x73FF, 0xD676, 0x740C, 0xD677, 0x740B, 0xD678, 0x73F4,
+	0xD679, 0x7408, 0xD67A, 0x7564, 0xD67B, 0x7563, 0xD67C, 0x75CE,
+	0xD67D, 0x75D2, 0xD67E, 0x75CF, 0xD6A1, 0x75CB, 0xD6A2, 0x75CC,
+	0xD6A3, 0x75D1, 0xD6A4, 0x75D0, 0xD6A5, 0x768F, 0xD6A6, 0x7689,
+	0xD6A7, 0x76D3, 0xD6A8, 0x7739, 0xD6A9, 0x772F, 0xD6AA, 0x772D,
+	0xD6AB, 0x7731, 0xD6AC, 0x7732, 0xD6AD, 0x7734, 0xD6AE, 0x7733,
+	0xD6AF, 0x773D, 0xD6B0, 0x7725, 0xD6B1, 0x773B, 0xD6B2, 0x7735,
+	0xD6B3, 0x7848, 0xD6B4, 0x7852, 0xD6B5, 0x7849, 0xD6B6, 0x784D,
+	0xD6B7, 0x784A, 0xD6B8, 0x784C, 0xD6B9, 0x7826, 0xD6BA, 0x7845,
+	0xD6BB, 0x7850, 0xD6BC, 0x7964, 0xD6BD, 0x7967, 0xD6BE, 0x7969,
+	0xD6BF, 0x796A, 0xD6C0, 0x7963, 0xD6C1, 0x796B, 0xD6C2, 0x7961,
+	0xD6C3, 0x79BB, 0xD6C4, 0x79FA, 0xD6C5, 0x79F8, 0xD6C6, 0x79F6,
+	0xD6C7, 0x79F7, 0xD6C8, 0x7A8F, 0xD6C9, 0x7A94, 0xD6CA, 0x7A90,
+	0xD6CB, 0x7B35, 0xD6CC, 0x7B47, 0xD6CD, 0x7B34, 0xD6CE, 0x7B25,
+	0xD6CF, 0x7B30, 0xD6D0, 0x7B22, 0xD6D1, 0x7B24, 0xD6D2, 0x7B33,
+	0xD6D3, 0x7B18, 0xD6D4, 0x7B2A, 0xD6D5, 0x7B1D, 0xD6D6, 0x7B31,
+	0xD6D7, 0x7B2B, 0xD6D8, 0x7B2D, 0xD6D9, 0x7B2F, 0xD6DA, 0x7B32,
+	0xD6DB, 0x7B38, 0xD6DC, 0x7B1A, 0xD6DD, 0x7B23, 0xD6DE, 0x7C94,
+	0xD6DF, 0x7C98, 0xD6E0, 0x7C96, 0xD6E1, 0x7CA3, 0xD6E2, 0x7D35,
+	0xD6E3, 0x7D3D, 0xD6E4, 0x7D38, 0xD6E5, 0x7D36, 0xD6E6, 0x7D3A,
+	0xD6E7, 0x7D45, 0xD6E8, 0x7D2C, 0xD6E9, 0x7D29, 0xD6EA, 0x7D41,
+	0xD6EB, 0x7D47, 0xD6EC, 0x7D3E, 0xD6ED, 0x7D3F, 0xD6EE, 0x7D4A,
+	0xD6EF, 0x7D3B, 0xD6F0, 0x7D28, 0xD6F1, 0x7F63, 0xD6F2, 0x7F95,
+	0xD6F3, 0x7F9C, 0xD6F4, 0x7F9D, 0xD6F5, 0x7F9B, 0xD6F6, 0x7FCA,
+	0xD6F7, 0x7FCB, 0xD6F8, 0x7FCD, 0xD6F9, 0x7FD0, 0xD6FA, 0x7FD1,
+	0xD6FB, 0x7FC7, 0xD6FC, 0x7FCF, 0xD6FD, 0x7FC9, 0xD6FE, 0x801F,
+	0xD740, 0x801E, 0xD741, 0x801B, 0xD742, 0x8047, 0xD743, 0x8043,
+	0xD744, 0x8048, 0xD745, 0x8118, 0xD746, 0x8125, 0xD747, 0x8119,
+	0xD748, 0x811B, 0xD749, 0x812D, 0xD74A, 0x811F, 0xD74B, 0x812C,
+	0xD74C, 0x811E, 0xD74D, 0x8121, 0xD74E, 0x8115, 0xD74F, 0x8127,
+	0xD750, 0x811D, 0xD751, 0x8122, 0xD752, 0x8211, 0xD753, 0x8238,
+	0xD754, 0x8233, 0xD755, 0x823A, 0xD756, 0x8234, 0xD757, 0x8232,
+	0xD758, 0x8274, 0xD759, 0x8390, 0xD75A, 0x83A3, 0xD75B, 0x83A8,
+	0xD75C, 0x838D, 0xD75D, 0x837A, 0xD75E, 0x8373, 0xD75F, 0x83A4,
+	0xD760, 0x8374, 0xD761, 0x838F, 0xD762, 0x8381, 0xD763, 0x8395,
+	0xD764, 0x8399, 0xD765, 0x8375, 0xD766, 0x8394, 0xD767, 0x83A9,
+	0xD768, 0x837D, 0xD769, 0x8383, 0xD76A, 0x838C, 0xD76B, 0x839D,
+	0xD76C, 0x839B, 0xD76D, 0x83AA, 0xD76E, 0x838B, 0xD76F, 0x837E,
+	0xD770, 0x83A5, 0xD771, 0x83AF, 0xD772, 0x8388, 0xD773, 0x8397,
+	0xD774, 0x83B0, 0xD775, 0x837F, 0xD776, 0x83A6, 0xD777, 0x8387,
+	0xD778, 0x83AE, 0xD779, 0x8376, 0xD77A, 0x839A, 0xD77B, 0x8659,
+	0xD77C, 0x8656, 0xD77D, 0x86BF, 0xD77E, 0x86B7, 0xD7A1, 0x86C2,
+	0xD7A2, 0x86C1, 0xD7A3, 0x86C5, 0xD7A4, 0x86BA, 0xD7A5, 0x86B0,
+	0xD7A6, 0x86C8, 0xD7A7, 0x86B9, 0xD7A8, 0x86B3, 0xD7A9, 0x86B8,
+	0xD7AA, 0x86CC, 0xD7AB, 0x86B4, 0xD7AC, 0x86BB, 0xD7AD, 0x86BC,
+	0xD7AE, 0x86C3, 0xD7AF, 0x86BD, 0xD7B0, 0x86BE, 0xD7B1, 0x8852,
+	0xD7B2, 0x8889, 0xD7B3, 0x8895, 0xD7B4, 0x88A8, 0xD7B5, 0x88A2,
+	0xD7B6, 0x88AA, 0xD7B7, 0x889A, 0xD7B8, 0x8891, 0xD7B9, 0x88A1,
+	0xD7BA, 0x889F, 0xD7BB, 0x8898, 0xD7BC, 0x88A7, 0xD7BD, 0x8899,
+	0xD7BE, 0x889B, 0xD7BF, 0x8897, 0xD7C0, 0x88A4, 0xD7C1, 0x88AC,
+	0xD7C2, 0x888C, 0xD7C3, 0x8893, 0xD7C4, 0x888E, 0xD7C5, 0x8982,
+	0xD7C6, 0x89D6, 0xD7C7, 0x89D9, 0xD7C8, 0x89D5, 0xD7C9, 0x8A30,
+	0xD7CA, 0x8A27, 0xD7CB, 0x8A2C, 0xD7CC, 0x8A1E, 0xD7CD, 0x8C39,
+	0xD7CE, 0x8C3B, 0xD7CF, 0x8C5C, 0xD7D0, 0x8C5D, 0xD7D1, 0x8C7D,
+	0xD7D2, 0x8CA5, 0xD7D3, 0x8D7D, 0xD7D4, 0x8D7B, 0xD7D5, 0x8D79,
+	0xD7D6, 0x8DBC, 0xD7D7, 0x8DC2, 0xD7D8, 0x8DB9, 0xD7D9, 0x8DBF,
+	0xD7DA, 0x8DC1, 0xD7DB, 0x8ED8, 0xD7DC, 0x8EDE, 0xD7DD, 0x8EDD,
+	0xD7DE, 0x8EDC, 0xD7DF, 0x8ED7, 0xD7E0, 0x8EE0, 0xD7E1, 0x8EE1,
+	0xD7E2, 0x9024, 0xD7E3, 0x900B, 0xD7E4, 0x9011, 0xD7E5, 0x901C,
+	0xD7E6, 0x900C, 0xD7E7, 0x9021, 0xD7E8, 0x90EF, 0xD7E9, 0x90EA,
+	0xD7EA, 0x90F0, 0xD7EB, 0x90F4, 0xD7EC, 0x90F2, 0xD7ED, 0x90F3,
+	0xD7EE, 0x90D4, 0xD7EF, 0x90EB, 0xD7F0, 0x90EC, 0xD7F1, 0x90E9,
+	0xD7F2, 0x9156, 0xD7F3, 0x9158, 0xD7F4, 0x915A, 0xD7F5, 0x9153,
+	0xD7F6, 0x9155, 0xD7F7, 0x91EC, 0xD7F8, 0x91F4, 0xD7F9, 0x91F1,
+	0xD7FA, 0x91F3, 0xD7FB, 0x91F8, 0xD7FC, 0x91E4, 0xD7FD, 0x91F9,
+	0xD7FE, 0x91EA, 0xD840, 0x91EB, 0xD841, 0x91F7, 0xD842, 0x91E8,
+	0xD843, 0x91EE, 0xD844, 0x957A, 0xD845, 0x9586, 0xD846, 0x9588,
+	0xD847, 0x967C, 0xD848, 0x966D, 0xD849, 0x966B, 0xD84A, 0x9671,
+	0xD84B, 0x966F, 0xD84C, 0x96BF, 0xD84D, 0x976A, 0xD84E, 0x9804,
+	0xD84F, 0x98E5, 0xD850, 0x9997, 0xD851, 0x509B, 0xD852, 0x5095,
+	0xD853, 0x5094, 0xD854, 0x509E, 0xD855, 0x508B, 0xD856, 0x50A3,
+	0xD857, 0x5083, 0xD858, 0x508C, 0xD859, 0x508E, 0xD85A, 0x509D,
+	0xD85B, 0x5068, 0xD85C, 0x509C, 0xD85D, 0x5092, 0xD85E, 0x5082,
+	0xD85F, 0x5087, 0xD860, 0x515F, 0xD861, 0x51D4, 0xD862, 0x5312,
+	0xD863, 0x5311, 0xD864, 0x53A4, 0xD865, 0x53A7, 0xD866, 0x5591,
+	0xD867, 0x55A8, 0xD868, 0x55A5, 0xD869, 0x55AD, 0xD86A, 0x5577,
+	0xD86B, 0x5645, 0xD86C, 0x55A2, 0xD86D, 0x5593, 0xD86E, 0x5588,
+	0xD86F, 0x558F, 0xD870, 0x55B5, 0xD871, 0x5581, 0xD872, 0x55A3,
+	0xD873, 0x5592, 0xD874, 0x55A4, 0xD875, 0x557D, 0xD876, 0x558C,
+	0xD877, 0x55A6, 0xD878, 0x557F, 0xD879, 0x5595, 0xD87A, 0x55A1,
+	0xD87B, 0x558E, 0xD87C, 0x570C, 0xD87D, 0x5829, 0xD87E, 0x5837,
+	0xD8A1, 0x5819, 0xD8A2, 0x581E, 0xD8A3, 0x5827, 0xD8A4, 0x5823,
+	0xD8A5, 0x5828, 0xD8A6, 0x57F5, 0xD8A7, 0x5848, 0xD8A8, 0x5825,
+	0xD8A9, 0x581C, 0xD8AA, 0x581B, 0xD8AB, 0x5833, 0xD8AC, 0x583F,
+	0xD8AD, 0x5836, 0xD8AE, 0x582E, 0xD8AF, 0x5839, 0xD8B0, 0x5838,
+	0xD8B1, 0x582D, 0xD8B2, 0x582C, 0xD8B3, 0x583B, 0xD8B4, 0x5961,
+	0xD8B5, 0x5AAF, 0xD8B6, 0x5A94, 0xD8B7, 0x5A9F, 0xD8B8, 0x5A7A,
+	0xD8B9, 0x5AA2, 0xD8BA, 0x5A9E, 0xD8BB, 0x5A78, 0xD8BC, 0x5AA6,
+	0xD8BD, 0x5A7C, 0xD8BE, 0x5AA5, 0xD8BF, 0x5AAC, 0xD8C0, 0x5A95,
+	0xD8C1, 0x5AAE, 0xD8C2, 0x5A37, 0xD8C3, 0x5A84, 0xD8C4, 0x5A8A,
+	0xD8C5, 0x5A97, 0xD8C6, 0x5A83, 0xD8C7, 0x5A8B, 0xD8C8, 0x5AA9,
+	0xD8C9, 0x5A7B, 0xD8CA, 0x5A7D, 0xD8CB, 0x5A8C, 0xD8CC, 0x5A9C,
+	0xD8CD, 0x5A8F, 0xD8CE, 0x5A93, 0xD8CF, 0x5A9D, 0xD8D0, 0x5BEA,
+	0xD8D1, 0x5BCD, 0xD8D2, 0x5BCB, 0xD8D3, 0x5BD4, 0xD8D4, 0x5BD1,
+	0xD8D5, 0x5BCA, 0xD8D6, 0x5BCE, 0xD8D7, 0x5C0C, 0xD8D8, 0x5C30,
+	0xD8D9, 0x5D37, 0xD8DA, 0x5D43, 0xD8DB, 0x5D6B, 0xD8DC, 0x5D41,
+	0xD8DD, 0x5D4B, 0xD8DE, 0x5D3F, 0xD8DF, 0x5D35, 0xD8E0, 0x5D51,
+	0xD8E1, 0x5D4E, 0xD8E2, 0x5D55, 0xD8E3, 0x5D33, 0xD8E4, 0x5D3A,
+	0xD8E5, 0x5D52, 0xD8E6, 0x5D3D, 0xD8E7, 0x5D31, 0xD8E8, 0x5D59,
+	0xD8E9, 0x5D42, 0xD8EA, 0x5D39, 0xD8EB, 0x5D49, 0xD8EC, 0x5D38,
+	0xD8ED, 0x5D3C, 0xD8EE, 0x5D32, 0xD8EF, 0x5D36, 0xD8F0, 0x5D40,
+	0xD8F1, 0x5D45, 0xD8F2, 0x5E44, 0xD8F3, 0x5E41, 0xD8F4, 0x5F58,
+	0xD8F5, 0x5FA6, 0xD8F6, 0x5FA5, 0xD8F7, 0x5FAB, 0xD8F8, 0x60C9,
+	0xD8F9, 0x60B9, 0xD8FA, 0x60CC, 0xD8FB, 0x60E2, 0xD8FC, 0x60CE,
+	0xD8FD, 0x60C4, 0xD8FE, 0x6114, 0xD940, 0x60F2, 0xD941, 0x610A,
+	0xD942, 0x6116, 0xD943, 0x6105, 0xD944, 0x60F5, 0xD945, 0x6113,
+	0xD946, 0x60F8, 0xD947, 0x60FC, 0xD948, 0x60FE, 0xD949, 0x60C1,
+	0xD94A, 0x6103, 0xD94B, 0x6118, 0xD94C, 0x611D, 0xD94D, 0x6110,
+	0xD94E, 0x60FF, 0xD94F, 0x6104, 0xD950, 0x610B, 0xD951, 0x624A,
+	0xD952, 0x6394, 0xD953, 0x63B1, 0xD954, 0x63B0, 0xD955, 0x63CE,
+	0xD956, 0x63E5, 0xD957, 0x63E8, 0xD958, 0x63EF, 0xD959, 0x63C3,
+	0xD95A, 0x649D, 0xD95B, 0x63F3, 0xD95C, 0x63CA, 0xD95D, 0x63E0,
+	0xD95E, 0x63F6, 0xD95F, 0x63D5, 0xD960, 0x63F2, 0xD961, 0x63F5,
+	0xD962, 0x6461, 0xD963, 0x63DF, 0xD964, 0x63BE, 0xD965, 0x63DD,
+	0xD966, 0x63DC, 0xD967, 0x63C4, 0xD968, 0x63D8, 0xD969, 0x63D3,
+	0xD96A, 0x63C2, 0xD96B, 0x63C7, 0xD96C, 0x63CC, 0xD96D, 0x63CB,
+	0xD96E, 0x63C8, 0xD96F, 0x63F0, 0xD970, 0x63D7, 0xD971, 0x63D9,
+	0xD972, 0x6532, 0xD973, 0x6567, 0xD974, 0x656A, 0xD975, 0x6564,
+	0xD976, 0x655C, 0xD977, 0x6568, 0xD978, 0x6565, 0xD979, 0x658C,
+	0xD97A, 0x659D, 0xD97B, 0x659E, 0xD97C, 0x65AE, 0xD97D, 0x65D0,
+	0xD97E, 0x65D2, 0xD9A1, 0x667C, 0xD9A2, 0x666C, 0xD9A3, 0x667B,
+	0xD9A4, 0x6680, 0xD9A5, 0x6671, 0xD9A6, 0x6679, 0xD9A7, 0x666A,
+	0xD9A8, 0x6672, 0xD9A9, 0x6701, 0xD9AA, 0x690C, 0xD9AB, 0x68D3,
+	0xD9AC, 0x6904, 0xD9AD, 0x68DC, 0xD9AE, 0x692A, 0xD9AF, 0x68EC,
+	0xD9B0, 0x68EA, 0xD9B1, 0x68F1, 0xD9B2, 0x690F, 0xD9B3, 0x68D6,
+	0xD9B4, 0x68F7, 0xD9B5, 0x68EB, 0xD9B6, 0x68E4, 0xD9B7, 0x68F6,
+	0xD9B8, 0x6913, 0xD9B9, 0x6910, 0xD9BA, 0x68F3, 0xD9BB, 0x68E1,
+	0xD9BC, 0x6907, 0xD9BD, 0x68CC, 0xD9BE, 0x6908, 0xD9BF, 0x6970,
+	0xD9C0, 0x68B4, 0xD9C1, 0x6911, 0xD9C2, 0x68EF, 0xD9C3, 0x68C6,
+	0xD9C4, 0x6914, 0xD9C5, 0x68F8, 0xD9C6, 0x68D0, 0xD9C7, 0x68FD,
+	0xD9C8, 0x68FC, 0xD9C9, 0x68E8, 0xD9CA, 0x690B, 0xD9CB, 0x690A,
+	0xD9CC, 0x6917, 0xD9CD, 0x68CE, 0xD9CE, 0x68C8, 0xD9CF, 0x68DD,
+	0xD9D0, 0x68DE, 0xD9D1, 0x68E6, 0xD9D2, 0x68F4, 0xD9D3, 0x68D1,
+	0xD9D4, 0x6906, 0xD9D5, 0x68D4, 0xD9D6, 0x68E9, 0xD9D7, 0x6915,
+	0xD9D8, 0x6925, 0xD9D9, 0x68C7, 0xD9DA, 0x6B39, 0xD9DB, 0x6B3B,
+	0xD9DC, 0x6B3F, 0xD9DD, 0x6B3C, 0xD9DE, 0x6B94, 0xD9DF, 0x6B97,
+	0xD9E0, 0x6B99, 0xD9E1, 0x6B95, 0xD9E2, 0x6BBD, 0xD9E3, 0x6BF0,
+	0xD9E4, 0x6BF2, 0xD9E5, 0x6BF3, 0xD9E6, 0x6C30, 0xD9E7, 0x6DFC,
+	0xD9E8, 0x6E46, 0xD9E9, 0x6E47, 0xD9EA, 0x6E1F, 0xD9EB, 0x6E49,
+	0xD9EC, 0x6E88, 0xD9ED, 0x6E3C, 0xD9EE, 0x6E3D, 0xD9EF, 0x6E45,
+	0xD9F0, 0x6E62, 0xD9F1, 0x6E2B, 0xD9F2, 0x6E3F, 0xD9F3, 0x6E41,
+	0xD9F4, 0x6E5D, 0xD9F5, 0x6E73, 0xD9F6, 0x6E1C, 0xD9F7, 0x6E33,
+	0xD9F8, 0x6E4B, 0xD9F9, 0x6E40, 0xD9FA, 0x6E51, 0xD9FB, 0x6E3B,
+	0xD9FC, 0x6E03, 0xD9FD, 0x6E2E, 0xD9FE, 0x6E5E, 0xDA40, 0x6E68,
+	0xDA41, 0x6E5C, 0xDA42, 0x6E61, 0xDA43, 0x6E31, 0xDA44, 0x6E28,
+	0xDA45, 0x6E60, 0xDA46, 0x6E71, 0xDA47, 0x6E6B, 0xDA48, 0x6E39,
+	0xDA49, 0x6E22, 0xDA4A, 0x6E30, 0xDA4B, 0x6E53, 0xDA4C, 0x6E65,
+	0xDA4D, 0x6E27, 0xDA4E, 0x6E78, 0xDA4F, 0x6E64, 0xDA50, 0x6E77,
+	0xDA51, 0x6E55, 0xDA52, 0x6E79, 0xDA53, 0x6E52, 0xDA54, 0x6E66,
+	0xDA55, 0x6E35, 0xDA56, 0x6E36, 0xDA57, 0x6E5A, 0xDA58, 0x7120,
+	0xDA59, 0x711E, 0xDA5A, 0x712F, 0xDA5B, 0x70FB, 0xDA5C, 0x712E,
+	0xDA5D, 0x7131, 0xDA5E, 0x7123, 0xDA5F, 0x7125, 0xDA60, 0x7122,
+	0xDA61, 0x7132, 0xDA62, 0x711F, 0xDA63, 0x7128, 0xDA64, 0x713A,
+	0xDA65, 0x711B, 0xDA66, 0x724B, 0xDA67, 0x725A, 0xDA68, 0x7288,
+	0xDA69, 0x7289, 0xDA6A, 0x7286, 0xDA6B, 0x7285, 0xDA6C, 0x728B,
+	0xDA6D, 0x7312, 0xDA6E, 0x730B, 0xDA6F, 0x7330, 0xDA70, 0x7322,
+	0xDA71, 0x7331, 0xDA72, 0x7333, 0xDA73, 0x7327, 0xDA74, 0x7332,
+	0xDA75, 0x732D, 0xDA76, 0x7326, 0xDA77, 0x7323, 0xDA78, 0x7335,
+	0xDA79, 0x730C, 0xDA7A, 0x742E, 0xDA7B, 0x742C, 0xDA7C, 0x7430,
+	0xDA7D, 0x742B, 0xDA7E, 0x7416, 0xDAA1, 0x741A, 0xDAA2, 0x7421,
+	0xDAA3, 0x742D, 0xDAA4, 0x7431, 0xDAA5, 0x7424, 0xDAA6, 0x7423,
+	0xDAA7, 0x741D, 0xDAA8, 0x7429, 0xDAA9, 0x7420, 0xDAAA, 0x7432,
+	0xDAAB, 0x74FB, 0xDAAC, 0x752F, 0xDAAD, 0x756F, 0xDAAE, 0x756C,
+	0xDAAF, 0x75E7, 0xDAB0, 0x75DA, 0xDAB1, 0x75E1, 0xDAB2, 0x75E6,
+	0xDAB3, 0x75DD, 0xDAB4, 0x75DF, 0xDAB5, 0x75E4, 0xDAB6, 0x75D7,
+	0xDAB7, 0x7695, 0xDAB8, 0x7692, 0xDAB9, 0x76DA, 0xDABA, 0x7746,
+	0xDABB, 0x7747, 0xDABC, 0x7744, 0xDABD, 0x774D, 0xDABE, 0x7745,
+	0xDABF, 0x774A, 0xDAC0, 0x774E, 0xDAC1, 0x774B, 0xDAC2, 0x774C,
+	0xDAC3, 0x77DE, 0xDAC4, 0x77EC, 0xDAC5, 0x7860, 0xDAC6, 0x7864,
+	0xDAC7, 0x7865, 0xDAC8, 0x785C, 0xDAC9, 0x786D, 0xDACA, 0x7871,
+	0xDACB, 0x786A, 0xDACC, 0x786E, 0xDACD, 0x7870, 0xDACE, 0x7869,
+	0xDACF, 0x7868, 0xDAD0, 0x785E, 0xDAD1, 0x7862, 0xDAD2, 0x7974,
+	0xDAD3, 0x7973, 0xDAD4, 0x7972, 0xDAD5, 0x7970, 0xDAD6, 0x7A02,
+	0xDAD7, 0x7A0A, 0xDAD8, 0x7A03, 0xDAD9, 0x7A0C, 0xDADA, 0x7A04,
+	0xDADB, 0x7A99, 0xDADC, 0x7AE6, 0xDADD, 0x7AE4, 0xDADE, 0x7B4A,
+	0xDADF, 0x7B3B, 0xDAE0, 0x7B44, 0xDAE1, 0x7B48, 0xDAE2, 0x7B4C,
+	0xDAE3, 0x7B4E, 0xDAE4, 0x7B40, 0xDAE5, 0x7B58, 0xDAE6, 0x7B45,
+	0xDAE7, 0x7CA2, 0xDAE8, 0x7C9E, 0xDAE9, 0x7CA8, 0xDAEA, 0x7CA1,
+	0xDAEB, 0x7D58, 0xDAEC, 0x7D6F, 0xDAED, 0x7D63, 0xDAEE, 0x7D53,
+	0xDAEF, 0x7D56, 0xDAF0, 0x7D67, 0xDAF1, 0x7D6A, 0xDAF2, 0x7D4F,
+	0xDAF3, 0x7D6D, 0xDAF4, 0x7D5C, 0xDAF5, 0x7D6B, 0xDAF6, 0x7D52,
+	0xDAF7, 0x7D54, 0xDAF8, 0x7D69, 0xDAF9, 0x7D51, 0xDAFA, 0x7D5F,
+	0xDAFB, 0x7D4E, 0xDAFC, 0x7F3E, 0xDAFD, 0x7F3F, 0xDAFE, 0x7F65,
+	0xDB40, 0x7F66, 0xDB41, 0x7FA2, 0xDB42, 0x7FA0, 0xDB43, 0x7FA1,
+	0xDB44, 0x7FD7, 0xDB45, 0x8051, 0xDB46, 0x804F, 0xDB47, 0x8050,
+	0xDB48, 0x80FE, 0xDB49, 0x80D4, 0xDB4A, 0x8143, 0xDB4B, 0x814A,
+	0xDB4C, 0x8152, 0xDB4D, 0x814F, 0xDB4E, 0x8147, 0xDB4F, 0x813D,
+	0xDB50, 0x814D, 0xDB51, 0x813A, 0xDB52, 0x81E6, 0xDB53, 0x81EE,
+	0xDB54, 0x81F7, 0xDB55, 0x81F8, 0xDB56, 0x81F9, 0xDB57, 0x8204,
+	0xDB58, 0x823C, 0xDB59, 0x823D, 0xDB5A, 0x823F, 0xDB5B, 0x8275,
+	0xDB5C, 0x833B, 0xDB5D, 0x83CF, 0xDB5E, 0x83F9, 0xDB5F, 0x8423,
+	0xDB60, 0x83C0, 0xDB61, 0x83E8, 0xDB62, 0x8412, 0xDB63, 0x83E7,
+	0xDB64, 0x83E4, 0xDB65, 0x83FC, 0xDB66, 0x83F6, 0xDB67, 0x8410,
+	0xDB68, 0x83C6, 0xDB69, 0x83C8, 0xDB6A, 0x83EB, 0xDB6B, 0x83E3,
+	0xDB6C, 0x83BF, 0xDB6D, 0x8401, 0xDB6E, 0x83DD, 0xDB6F, 0x83E5,
+	0xDB70, 0x83D8, 0xDB71, 0x83FF, 0xDB72, 0x83E1, 0xDB73, 0x83CB,
+	0xDB74, 0x83CE, 0xDB75, 0x83D6, 0xDB76, 0x83F5, 0xDB77, 0x83C9,
+	0xDB78, 0x8409, 0xDB79, 0x840F, 0xDB7A, 0x83DE, 0xDB7B, 0x8411,
+	0xDB7C, 0x8406, 0xDB7D, 0x83C2, 0xDB7E, 0x83F3, 0xDBA1, 0x83D5,
+	0xDBA2, 0x83FA, 0xDBA3, 0x83C7, 0xDBA4, 0x83D1, 0xDBA5, 0x83EA,
+	0xDBA6, 0x8413, 0xDBA7, 0x83C3, 0xDBA8, 0x83EC, 0xDBA9, 0x83EE,
+	0xDBAA, 0x83C4, 0xDBAB, 0x83FB, 0xDBAC, 0x83D7, 0xDBAD, 0x83E2,
+	0xDBAE, 0x841B, 0xDBAF, 0x83DB, 0xDBB0, 0x83FE, 0xDBB1, 0x86D8,
+	0xDBB2, 0x86E2, 0xDBB3, 0x86E6, 0xDBB4, 0x86D3, 0xDBB5, 0x86E3,
+	0xDBB6, 0x86DA, 0xDBB7, 0x86EA, 0xDBB8, 0x86DD, 0xDBB9, 0x86EB,
+	0xDBBA, 0x86DC, 0xDBBB, 0x86EC, 0xDBBC, 0x86E9, 0xDBBD, 0x86D7,
+	0xDBBE, 0x86E8, 0xDBBF, 0x86D1, 0xDBC0, 0x8848, 0xDBC1, 0x8856,
+	0xDBC2, 0x8855, 0xDBC3, 0x88BA, 0xDBC4, 0x88D7, 0xDBC5, 0x88B9,
+	0xDBC6, 0x88B8, 0xDBC7, 0x88C0, 0xDBC8, 0x88BE, 0xDBC9, 0x88B6,
+	0xDBCA, 0x88BC, 0xDBCB, 0x88B7, 0xDBCC, 0x88BD, 0xDBCD, 0x88B2,
+	0xDBCE, 0x8901, 0xDBCF, 0x88C9, 0xDBD0, 0x8995, 0xDBD1, 0x8998,
+	0xDBD2, 0x8997, 0xDBD3, 0x89DD, 0xDBD4, 0x89DA, 0xDBD5, 0x89DB,
+	0xDBD6, 0x8A4E, 0xDBD7, 0x8A4D, 0xDBD8, 0x8A39, 0xDBD9, 0x8A59,
+	0xDBDA, 0x8A40, 0xDBDB, 0x8A57, 0xDBDC, 0x8A58, 0xDBDD, 0x8A44,
+	0xDBDE, 0x8A45, 0xDBDF, 0x8A52, 0xDBE0, 0x8A48, 0xDBE1, 0x8A51,
+	0xDBE2, 0x8A4A, 0xDBE3, 0x8A4C, 0xDBE4, 0x8A4F, 0xDBE5, 0x8C5F,
+	0xDBE6, 0x8C81, 0xDBE7, 0x8C80, 0xDBE8, 0x8CBA, 0xDBE9, 0x8CBE,
+	0xDBEA, 0x8CB0, 0xDBEB, 0x8CB9, 0xDBEC, 0x8CB5, 0xDBED, 0x8D84,
+	0xDBEE, 0x8D80, 0xDBEF, 0x8D89, 0xDBF0, 0x8DD8, 0xDBF1, 0x8DD3,
+	0xDBF2, 0x8DCD, 0xDBF3, 0x8DC7, 0xDBF4, 0x8DD6, 0xDBF5, 0x8DDC,
+	0xDBF6, 0x8DCF, 0xDBF7, 0x8DD5, 0xDBF8, 0x8DD9, 0xDBF9, 0x8DC8,
+	0xDBFA, 0x8DD7, 0xDBFB, 0x8DC5, 0xDBFC, 0x8EEF, 0xDBFD, 0x8EF7,
+	0xDBFE, 0x8EFA, 0xDC40, 0x8EF9, 0xDC41, 0x8EE6, 0xDC42, 0x8EEE,
+	0xDC43, 0x8EE5, 0xDC44, 0x8EF5, 0xDC45, 0x8EE7, 0xDC46, 0x8EE8,
+	0xDC47, 0x8EF6, 0xDC48, 0x8EEB, 0xDC49, 0x8EF1, 0xDC4A, 0x8EEC,
+	0xDC4B, 0x8EF4, 0xDC4C, 0x8EE9, 0xDC4D, 0x902D, 0xDC4E, 0x9034,
+	0xDC4F, 0x902F, 0xDC50, 0x9106, 0xDC51, 0x912C, 0xDC52, 0x9104,
+	0xDC53, 0x90FF, 0xDC54, 0x90FC, 0xDC55, 0x9108, 0xDC56, 0x90F9,
+	0xDC57, 0x90FB, 0xDC58, 0x9101, 0xDC59, 0x9100, 0xDC5A, 0x9107,
+	0xDC5B, 0x9105, 0xDC5C, 0x9103, 0xDC5D, 0x9161, 0xDC5E, 0x9164,
+	0xDC5F, 0x915F, 0xDC60, 0x9162, 0xDC61, 0x9160, 0xDC62, 0x9201,
+	0xDC63, 0x920A, 0xDC64, 0x9225, 0xDC65, 0x9203, 0xDC66, 0x921A,
+	0xDC67, 0x9226, 0xDC68, 0x920F, 0xDC69, 0x920C, 0xDC6A, 0x9200,
+	0xDC6B, 0x9212, 0xDC6C, 0x91FF, 0xDC6D, 0x91FD, 0xDC6E, 0x9206,
+	0xDC6F, 0x9204, 0xDC70, 0x9227, 0xDC71, 0x9202, 0xDC72, 0x921C,
+	0xDC73, 0x9224, 0xDC74, 0x9219, 0xDC75, 0x9217, 0xDC76, 0x9205,
+	0xDC77, 0x9216, 0xDC78, 0x957B, 0xDC79, 0x958D, 0xDC7A, 0x958C,
+	0xDC7B, 0x9590, 0xDC7C, 0x9687, 0xDC7D, 0x967E, 0xDC7E, 0x9688,
+	0xDCA1, 0x9689, 0xDCA2, 0x9683, 0xDCA3, 0x9680, 0xDCA4, 0x96C2,
+	0xDCA5, 0x96C8, 0xDCA6, 0x96C3, 0xDCA7, 0x96F1, 0xDCA8, 0x96F0,
+	0xDCA9, 0x976C, 0xDCAA, 0x9770, 0xDCAB, 0x976E, 0xDCAC, 0x9807,
+	0xDCAD, 0x98A9, 0xDCAE, 0x98EB, 0xDCAF, 0x9CE6, 0xDCB0, 0x9EF9,
+	0xDCB1, 0x4E83, 0xDCB2, 0x4E84, 0xDCB3, 0x4EB6, 0xDCB4, 0x50BD,
+	0xDCB5, 0x50BF, 0xDCB6, 0x50C6, 0xDCB7, 0x50AE, 0xDCB8, 0x50C4,
+	0xDCB9, 0x50CA, 0xDCBA, 0x50B4, 0xDCBB, 0x50C8, 0xDCBC, 0x50C2,
+	0xDCBD, 0x50B0, 0xDCBE, 0x50C1, 0xDCBF, 0x50BA, 0xDCC0, 0x50B1,
+	0xDCC1, 0x50CB, 0xDCC2, 0x50C9, 0xDCC3, 0x50B6, 0xDCC4, 0x50B8,
+	0xDCC5, 0x51D7, 0xDCC6, 0x527A, 0xDCC7, 0x5278, 0xDCC8, 0x527B,
+	0xDCC9, 0x527C, 0xDCCA, 0x55C3, 0xDCCB, 0x55DB, 0xDCCC, 0x55CC,
+	0xDCCD, 0x55D0, 0xDCCE, 0x55CB, 0xDCCF, 0x55CA, 0xDCD0, 0x55DD,
+	0xDCD1, 0x55C0, 0xDCD2, 0x55D4, 0xDCD3, 0x55C4, 0xDCD4, 0x55E9,
+	0xDCD5, 0x55BF, 0xDCD6, 0x55D2, 0xDCD7, 0x558D, 0xDCD8, 0x55CF,
+	0xDCD9, 0x55D5, 0xDCDA, 0x55E2, 0xDCDB, 0x55D6, 0xDCDC, 0x55C8,
+	0xDCDD, 0x55F2, 0xDCDE, 0x55CD, 0xDCDF, 0x55D9, 0xDCE0, 0x55C2,
+	0xDCE1, 0x5714, 0xDCE2, 0x5853, 0xDCE3, 0x5868, 0xDCE4, 0x5864,
+	0xDCE5, 0x584F, 0xDCE6, 0x584D, 0xDCE7, 0x5849, 0xDCE8, 0x586F,
+	0xDCE9, 0x5855, 0xDCEA, 0x584E, 0xDCEB, 0x585D, 0xDCEC, 0x5859,
+	0xDCED, 0x5865, 0xDCEE, 0x585B, 0xDCEF, 0x583D, 0xDCF0, 0x5863,
+	0xDCF1, 0x5871, 0xDCF2, 0x58FC, 0xDCF3, 0x5AC7, 0xDCF4, 0x5AC4,
+	0xDCF5, 0x5ACB, 0xDCF6, 0x5ABA, 0xDCF7, 0x5AB8, 0xDCF8, 0x5AB1,
+	0xDCF9, 0x5AB5, 0xDCFA, 0x5AB0, 0xDCFB, 0x5ABF, 0xDCFC, 0x5AC8,
+	0xDCFD, 0x5ABB, 0xDCFE, 0x5AC6, 0xDD40, 0x5AB7, 0xDD41, 0x5AC0,
+	0xDD42, 0x5ACA, 0xDD43, 0x5AB4, 0xDD44, 0x5AB6, 0xDD45, 0x5ACD,
+	0xDD46, 0x5AB9, 0xDD47, 0x5A90, 0xDD48, 0x5BD6, 0xDD49, 0x5BD8,
+	0xDD4A, 0x5BD9, 0xDD4B, 0x5C1F, 0xDD4C, 0x5C33, 0xDD4D, 0x5D71,
+	0xDD4E, 0x5D63, 0xDD4F, 0x5D4A, 0xDD50, 0x5D65, 0xDD51, 0x5D72,
+	0xDD52, 0x5D6C, 0xDD53, 0x5D5E, 0xDD54, 0x5D68, 0xDD55, 0x5D67,
+	0xDD56, 0x5D62, 0xDD57, 0x5DF0, 0xDD58, 0x5E4F, 0xDD59, 0x5E4E,
+	0xDD5A, 0x5E4A, 0xDD5B, 0x5E4D, 0xDD5C, 0x5E4B, 0xDD5D, 0x5EC5,
+	0xDD5E, 0x5ECC, 0xDD5F, 0x5EC6, 0xDD60, 0x5ECB, 0xDD61, 0x5EC7,
+	0xDD62, 0x5F40, 0xDD63, 0x5FAF, 0xDD64, 0x5FAD, 0xDD65, 0x60F7,
+	0xDD66, 0x6149, 0xDD67, 0x614A, 0xDD68, 0x612B, 0xDD69, 0x6145,
+	0xDD6A, 0x6136, 0xDD6B, 0x6132, 0xDD6C, 0x612E, 0xDD6D, 0x6146,
+	0xDD6E, 0x612F, 0xDD6F, 0x614F, 0xDD70, 0x6129, 0xDD71, 0x6140,
+	0xDD72, 0x6220, 0xDD73, 0x9168, 0xDD74, 0x6223, 0xDD75, 0x6225,
+	0xDD76, 0x6224, 0xDD77, 0x63C5, 0xDD78, 0x63F1, 0xDD79, 0x63EB,
+	0xDD7A, 0x6410, 0xDD7B, 0x6412, 0xDD7C, 0x6409, 0xDD7D, 0x6420,
+	0xDD7E, 0x6424, 0xDDA1, 0x6433, 0xDDA2, 0x6443, 0xDDA3, 0x641F,
+	0xDDA4, 0x6415, 0xDDA5, 0x6418, 0xDDA6, 0x6439, 0xDDA7, 0x6437,
+	0xDDA8, 0x6422, 0xDDA9, 0x6423, 0xDDAA, 0x640C, 0xDDAB, 0x6426,
+	0xDDAC, 0x6430, 0xDDAD, 0x6428, 0xDDAE, 0x6441, 0xDDAF, 0x6435,
+	0xDDB0, 0x642F, 0xDDB1, 0x640A, 0xDDB2, 0x641A, 0xDDB3, 0x6440,
+	0xDDB4, 0x6425, 0xDDB5, 0x6427, 0xDDB6, 0x640B, 0xDDB7, 0x63E7,
+	0xDDB8, 0x641B, 0xDDB9, 0x642E, 0xDDBA, 0x6421, 0xDDBB, 0x640E,
+	0xDDBC, 0x656F, 0xDDBD, 0x6592, 0xDDBE, 0x65D3, 0xDDBF, 0x6686,
+	0xDDC0, 0x668C, 0xDDC1, 0x6695, 0xDDC2, 0x6690, 0xDDC3, 0x668B,
+	0xDDC4, 0x668A, 0xDDC5, 0x6699, 0xDDC6, 0x6694, 0xDDC7, 0x6678,
+	0xDDC8, 0x6720, 0xDDC9, 0x6966, 0xDDCA, 0x695F, 0xDDCB, 0x6938,
+	0xDDCC, 0x694E, 0xDDCD, 0x6962, 0xDDCE, 0x6971, 0xDDCF, 0x693F,
+	0xDDD0, 0x6945, 0xDDD1, 0x696A, 0xDDD2, 0x6939, 0xDDD3, 0x6942,
+	0xDDD4, 0x6957, 0xDDD5, 0x6959, 0xDDD6, 0x697A, 0xDDD7, 0x6948,
+	0xDDD8, 0x6949, 0xDDD9, 0x6935, 0xDDDA, 0x696C, 0xDDDB, 0x6933,
+	0xDDDC, 0x693D, 0xDDDD, 0x6965, 0xDDDE, 0x68F0, 0xDDDF, 0x6978,
+	0xDDE0, 0x6934, 0xDDE1, 0x6969, 0xDDE2, 0x6940, 0xDDE3, 0x696F,
+	0xDDE4, 0x6944, 0xDDE5, 0x6976, 0xDDE6, 0x6958, 0xDDE7, 0x6941,
+	0xDDE8, 0x6974, 0xDDE9, 0x694C, 0xDDEA, 0x693B, 0xDDEB, 0x694B,
+	0xDDEC, 0x6937, 0xDDED, 0x695C, 0xDDEE, 0x694F, 0xDDEF, 0x6951,
+	0xDDF0, 0x6932, 0xDDF1, 0x6952, 0xDDF2, 0x692F, 0xDDF3, 0x697B,
+	0xDDF4, 0x693C, 0xDDF5, 0x6B46, 0xDDF6, 0x6B45, 0xDDF7, 0x6B43,
+	0xDDF8, 0x6B42, 0xDDF9, 0x6B48, 0xDDFA, 0x6B41, 0xDDFB, 0x6B9B,
+	0xDDFC, 0xFA0D, 0xDDFD, 0x6BFB, 0xDDFE, 0x6BFC, 0xDE40, 0x6BF9,
+	0xDE41, 0x6BF7, 0xDE42, 0x6BF8, 0xDE43, 0x6E9B, 0xDE44, 0x6ED6,
+	0xDE45, 0x6EC8, 0xDE46, 0x6E8F, 0xDE47, 0x6EC0, 0xDE48, 0x6E9F,
+	0xDE49, 0x6E93, 0xDE4A, 0x6E94, 0xDE4B, 0x6EA0, 0xDE4C, 0x6EB1,
+	0xDE4D, 0x6EB9, 0xDE4E, 0x6EC6, 0xDE4F, 0x6ED2, 0xDE50, 0x6EBD,
+	0xDE51, 0x6EC1, 0xDE52, 0x6E9E, 0xDE53, 0x6EC9, 0xDE54, 0x6EB7,
+	0xDE55, 0x6EB0, 0xDE56, 0x6ECD, 0xDE57, 0x6EA6, 0xDE58, 0x6ECF,
+	0xDE59, 0x6EB2, 0xDE5A, 0x6EBE, 0xDE5B, 0x6EC3, 0xDE5C, 0x6EDC,
+	0xDE5D, 0x6ED8, 0xDE5E, 0x6E99, 0xDE5F, 0x6E92, 0xDE60, 0x6E8E,
+	0xDE61, 0x6E8D, 0xDE62, 0x6EA4, 0xDE63, 0x6EA1, 0xDE64, 0x6EBF,
+	0xDE65, 0x6EB3, 0xDE66, 0x6ED0, 0xDE67, 0x6ECA, 0xDE68, 0x6E97,
+	0xDE69, 0x6EAE, 0xDE6A, 0x6EA3, 0xDE6B, 0x7147, 0xDE6C, 0x7154,
+	0xDE6D, 0x7152, 0xDE6E, 0x7163, 0xDE6F, 0x7160, 0xDE70, 0x7141,
+	0xDE71, 0x715D, 0xDE72, 0x7162, 0xDE73, 0x7172, 0xDE74, 0x7178,
+	0xDE75, 0x716A, 0xDE76, 0x7161, 0xDE77, 0x7142, 0xDE78, 0x7158,
+	0xDE79, 0x7143, 0xDE7A, 0x714B, 0xDE7B, 0x7170, 0xDE7C, 0x715F,
+	0xDE7D, 0x7150, 0xDE7E, 0x7153, 0xDEA1, 0x7144, 0xDEA2, 0x714D,
+	0xDEA3, 0x715A, 0xDEA4, 0x724F, 0xDEA5, 0x728D, 0xDEA6, 0x728C,
+	0xDEA7, 0x7291, 0xDEA8, 0x7290, 0xDEA9, 0x728E, 0xDEAA, 0x733C,
+	0xDEAB, 0x7342, 0xDEAC, 0x733B, 0xDEAD, 0x733A, 0xDEAE, 0x7340,
+	0xDEAF, 0x734A, 0xDEB0, 0x7349, 0xDEB1, 0x7444, 0xDEB2, 0x744A,
+	0xDEB3, 0x744B, 0xDEB4, 0x7452, 0xDEB5, 0x7451, 0xDEB6, 0x7457,
+	0xDEB7, 0x7440, 0xDEB8, 0x744F, 0xDEB9, 0x7450, 0xDEBA, 0x744E,
+	0xDEBB, 0x7442, 0xDEBC, 0x7446, 0xDEBD, 0x744D, 0xDEBE, 0x7454,
+	0xDEBF, 0x74E1, 0xDEC0, 0x74FF, 0xDEC1, 0x74FE, 0xDEC2, 0x74FD,
+	0xDEC3, 0x751D, 0xDEC4, 0x7579, 0xDEC5, 0x7577, 0xDEC6, 0x6983,
+	0xDEC7, 0x75EF, 0xDEC8, 0x760F, 0xDEC9, 0x7603, 0xDECA, 0x75F7,
+	0xDECB, 0x75FE, 0xDECC, 0x75FC, 0xDECD, 0x75F9, 0xDECE, 0x75F8,
+	0xDECF, 0x7610, 0xDED0, 0x75FB, 0xDED1, 0x75F6, 0xDED2, 0x75ED,
+	0xDED3, 0x75F5, 0xDED4, 0x75FD, 0xDED5, 0x7699, 0xDED6, 0x76B5,
+	0xDED7, 0x76DD, 0xDED8, 0x7755, 0xDED9, 0x775F, 0xDEDA, 0x7760,
+	0xDEDB, 0x7752, 0xDEDC, 0x7756, 0xDEDD, 0x775A, 0xDEDE, 0x7769,
+	0xDEDF, 0x7767, 0xDEE0, 0x7754, 0xDEE1, 0x7759, 0xDEE2, 0x776D,
+	0xDEE3, 0x77E0, 0xDEE4, 0x7887, 0xDEE5, 0x789A, 0xDEE6, 0x7894,
+	0xDEE7, 0x788F, 0xDEE8, 0x7884, 0xDEE9, 0x7895, 0xDEEA, 0x7885,
+	0xDEEB, 0x7886, 0xDEEC, 0x78A1, 0xDEED, 0x7883, 0xDEEE, 0x7879,
+	0xDEEF, 0x7899, 0xDEF0, 0x7880, 0xDEF1, 0x7896, 0xDEF2, 0x787B,
+	0xDEF3, 0x797C, 0xDEF4, 0x7982, 0xDEF5, 0x797D, 0xDEF6, 0x7979,
+	0xDEF7, 0x7A11, 0xDEF8, 0x7A18, 0xDEF9, 0x7A19, 0xDEFA, 0x7A12,
+	0xDEFB, 0x7A17, 0xDEFC, 0x7A15, 0xDEFD, 0x7A22, 0xDEFE, 0x7A13,
+	0xDF40, 0x7A1B, 0xDF41, 0x7A10, 0xDF42, 0x7AA3, 0xDF43, 0x7AA2,
+	0xDF44, 0x7A9E, 0xDF45, 0x7AEB, 0xDF46, 0x7B66, 0xDF47, 0x7B64,
+	0xDF48, 0x7B6D, 0xDF49, 0x7B74, 0xDF4A, 0x7B69, 0xDF4B, 0x7B72,
+	0xDF4C, 0x7B65, 0xDF4D, 0x7B73, 0xDF4E, 0x7B71, 0xDF4F, 0x7B70,
+	0xDF50, 0x7B61, 0xDF51, 0x7B78, 0xDF52, 0x7B76, 0xDF53, 0x7B63,
+	0xDF54, 0x7CB2, 0xDF55, 0x7CB4, 0xDF56, 0x7CAF, 0xDF57, 0x7D88,
+	0xDF58, 0x7D86, 0xDF59, 0x7D80, 0xDF5A, 0x7D8D, 0xDF5B, 0x7D7F,
+	0xDF5C, 0x7D85, 0xDF5D, 0x7D7A, 0xDF5E, 0x7D8E, 0xDF5F, 0x7D7B,
+	0xDF60, 0x7D83, 0xDF61, 0x7D7C, 0xDF62, 0x7D8C, 0xDF63, 0x7D94,
+	0xDF64, 0x7D84, 0xDF65, 0x7D7D, 0xDF66, 0x7D92, 0xDF67, 0x7F6D,
+	0xDF68, 0x7F6B, 0xDF69, 0x7F67, 0xDF6A, 0x7F68, 0xDF6B, 0x7F6C,
+	0xDF6C, 0x7FA6, 0xDF6D, 0x7FA5, 0xDF6E, 0x7FA7, 0xDF6F, 0x7FDB,
+	0xDF70, 0x7FDC, 0xDF71, 0x8021, 0xDF72, 0x8164, 0xDF73, 0x8160,
+	0xDF74, 0x8177, 0xDF75, 0x815C, 0xDF76, 0x8169, 0xDF77, 0x815B,
+	0xDF78, 0x8162, 0xDF79, 0x8172, 0xDF7A, 0x6721, 0xDF7B, 0x815E,
+	0xDF7C, 0x8176, 0xDF7D, 0x8167, 0xDF7E, 0x816F, 0xDFA1, 0x8144,
+	0xDFA2, 0x8161, 0xDFA3, 0x821D, 0xDFA4, 0x8249, 0xDFA5, 0x8244,
+	0xDFA6, 0x8240, 0xDFA7, 0x8242, 0xDFA8, 0x8245, 0xDFA9, 0x84F1,
+	0xDFAA, 0x843F, 0xDFAB, 0x8456, 0xDFAC, 0x8476, 0xDFAD, 0x8479,
+	0xDFAE, 0x848F, 0xDFAF, 0x848D, 0xDFB0, 0x8465, 0xDFB1, 0x8451,
+	0xDFB2, 0x8440, 0xDFB3, 0x8486, 0xDFB4, 0x8467, 0xDFB5, 0x8430,
+	0xDFB6, 0x844D, 0xDFB7, 0x847D, 0xDFB8, 0x845A, 0xDFB9, 0x8459,
+	0xDFBA, 0x8474, 0xDFBB, 0x8473, 0xDFBC, 0x845D, 0xDFBD, 0x8507,
+	0xDFBE, 0x845E, 0xDFBF, 0x8437, 0xDFC0, 0x843A, 0xDFC1, 0x8434,
+	0xDFC2, 0x847A, 0xDFC3, 0x8443, 0xDFC4, 0x8478, 0xDFC5, 0x8432,
+	0xDFC6, 0x8445, 0xDFC7, 0x8429, 0xDFC8, 0x83D9, 0xDFC9, 0x844B,
+	0xDFCA, 0x842F, 0xDFCB, 0x8442, 0xDFCC, 0x842D, 0xDFCD, 0x845F,
+	0xDFCE, 0x8470, 0xDFCF, 0x8439, 0xDFD0, 0x844E, 0xDFD1, 0x844C,
+	0xDFD2, 0x8452, 0xDFD3, 0x846F, 0xDFD4, 0x84C5, 0xDFD5, 0x848E,
+	0xDFD6, 0x843B, 0xDFD7, 0x8447, 0xDFD8, 0x8436, 0xDFD9, 0x8433,
+	0xDFDA, 0x8468, 0xDFDB, 0x847E, 0xDFDC, 0x8444, 0xDFDD, 0x842B,
+	0xDFDE, 0x8460, 0xDFDF, 0x8454, 0xDFE0, 0x846E, 0xDFE1, 0x8450,
+	0xDFE2, 0x870B, 0xDFE3, 0x8704, 0xDFE4, 0x86F7, 0xDFE5, 0x870C,
+	0xDFE6, 0x86FA, 0xDFE7, 0x86D6, 0xDFE8, 0x86F5, 0xDFE9, 0x874D,
+	0xDFEA, 0x86F8, 0xDFEB, 0x870E, 0xDFEC, 0x8709, 0xDFED, 0x8701,
+	0xDFEE, 0x86F6, 0xDFEF, 0x870D, 0xDFF0, 0x8705, 0xDFF1, 0x88D6,
+	0xDFF2, 0x88CB, 0xDFF3, 0x88CD, 0xDFF4, 0x88CE, 0xDFF5, 0x88DE,
+	0xDFF6, 0x88DB, 0xDFF7, 0x88DA, 0xDFF8, 0x88CC, 0xDFF9, 0x88D0,
+	0xDFFA, 0x8985, 0xDFFB, 0x899B, 0xDFFC, 0x89DF, 0xDFFD, 0x89E5,
+	0xDFFE, 0x89E4, 0xE040, 0x89E1, 0xE041, 0x89E0, 0xE042, 0x89E2,
+	0xE043, 0x89DC, 0xE044, 0x89E6, 0xE045, 0x8A76, 0xE046, 0x8A86,
+	0xE047, 0x8A7F, 0xE048, 0x8A61, 0xE049, 0x8A3F, 0xE04A, 0x8A77,
+	0xE04B, 0x8A82, 0xE04C, 0x8A84, 0xE04D, 0x8A75, 0xE04E, 0x8A83,
+	0xE04F, 0x8A81, 0xE050, 0x8A74, 0xE051, 0x8A7A, 0xE052, 0x8C3C,
+	0xE053, 0x8C4B, 0xE054, 0x8C4A, 0xE055, 0x8C65, 0xE056, 0x8C64,
+	0xE057, 0x8C66, 0xE058, 0x8C86, 0xE059, 0x8C84, 0xE05A, 0x8C85,
+	0xE05B, 0x8CCC, 0xE05C, 0x8D68, 0xE05D, 0x8D69, 0xE05E, 0x8D91,
+	0xE05F, 0x8D8C, 0xE060, 0x8D8E, 0xE061, 0x8D8F, 0xE062, 0x8D8D,
+	0xE063, 0x8D93, 0xE064, 0x8D94, 0xE065, 0x8D90, 0xE066, 0x8D92,
+	0xE067, 0x8DF0, 0xE068, 0x8DE0, 0xE069, 0x8DEC, 0xE06A, 0x8DF1,
+	0xE06B, 0x8DEE, 0xE06C, 0x8DD0, 0xE06D, 0x8DE9, 0xE06E, 0x8DE3,
+	0xE06F, 0x8DE2, 0xE070, 0x8DE7, 0xE071, 0x8DF2, 0xE072, 0x8DEB,
+	0xE073, 0x8DF4, 0xE074, 0x8F06, 0xE075, 0x8EFF, 0xE076, 0x8F01,
+	0xE077, 0x8F00, 0xE078, 0x8F05, 0xE079, 0x8F07, 0xE07A, 0x8F08,
+	0xE07B, 0x8F02, 0xE07C, 0x8F0B, 0xE07D, 0x9052, 0xE07E, 0x903F,
+	0xE0A1, 0x9044, 0xE0A2, 0x9049, 0xE0A3, 0x903D, 0xE0A4, 0x9110,
+	0xE0A5, 0x910D, 0xE0A6, 0x910F, 0xE0A7, 0x9111, 0xE0A8, 0x9116,
+	0xE0A9, 0x9114, 0xE0AA, 0x910B, 0xE0AB, 0x910E, 0xE0AC, 0x916E,
+	0xE0AD, 0x916F, 0xE0AE, 0x9248, 0xE0AF, 0x9252, 0xE0B0, 0x9230,
+	0xE0B1, 0x923A, 0xE0B2, 0x9266, 0xE0B3, 0x9233, 0xE0B4, 0x9265,
+	0xE0B5, 0x925E, 0xE0B6, 0x9283, 0xE0B7, 0x922E, 0xE0B8, 0x924A,
+	0xE0B9, 0x9246, 0xE0BA, 0x926D, 0xE0BB, 0x926C, 0xE0BC, 0x924F,
+	0xE0BD, 0x9260, 0xE0BE, 0x9267, 0xE0BF, 0x926F, 0xE0C0, 0x9236,
+	0xE0C1, 0x9261, 0xE0C2, 0x9270, 0xE0C3, 0x9231, 0xE0C4, 0x9254,
+	0xE0C5, 0x9263, 0xE0C6, 0x9250, 0xE0C7, 0x9272, 0xE0C8, 0x924E,
+	0xE0C9, 0x9253, 0xE0CA, 0x924C, 0xE0CB, 0x9256, 0xE0CC, 0x9232,
+	0xE0CD, 0x959F, 0xE0CE, 0x959C, 0xE0CF, 0x959E, 0xE0D0, 0x959B,
+	0xE0D1, 0x9692, 0xE0D2, 0x9693, 0xE0D3, 0x9691, 0xE0D4, 0x9697,
+	0xE0D5, 0x96CE, 0xE0D6, 0x96FA, 0xE0D7, 0x96FD, 0xE0D8, 0x96F8,
+	0xE0D9, 0x96F5, 0xE0DA, 0x9773, 0xE0DB, 0x9777, 0xE0DC, 0x9778,
+	0xE0DD, 0x9772, 0xE0DE, 0x980F, 0xE0DF, 0x980D, 0xE0E0, 0x980E,
+	0xE0E1, 0x98AC, 0xE0E2, 0x98F6, 0xE0E3, 0x98F9, 0xE0E4, 0x99AF,
+	0xE0E5, 0x99B2, 0xE0E6, 0x99B0, 0xE0E7, 0x99B5, 0xE0E8, 0x9AAD,
+	0xE0E9, 0x9AAB, 0xE0EA, 0x9B5B, 0xE0EB, 0x9CEA, 0xE0EC, 0x9CED,
+	0xE0ED, 0x9CE7, 0xE0EE, 0x9E80, 0xE0EF, 0x9EFD, 0xE0F0, 0x50E6,
+	0xE0F1, 0x50D4, 0xE0F2, 0x50D7, 0xE0F3, 0x50E8, 0xE0F4, 0x50F3,
+	0xE0F5, 0x50DB, 0xE0F6, 0x50EA, 0xE0F7, 0x50DD, 0xE0F8, 0x50E4,
+	0xE0F9, 0x50D3, 0xE0FA, 0x50EC, 0xE0FB, 0x50F0, 0xE0FC, 0x50EF,
+	0xE0FD, 0x50E3, 0xE0FE, 0x50E0, 0xE140, 0x51D8, 0xE141, 0x5280,
+	0xE142, 0x5281, 0xE143, 0x52E9, 0xE144, 0x52EB, 0xE145, 0x5330,
+	0xE146, 0x53AC, 0xE147, 0x5627, 0xE148, 0x5615, 0xE149, 0x560C,
+	0xE14A, 0x5612, 0xE14B, 0x55FC, 0xE14C, 0x560F, 0xE14D, 0x561C,
+	0xE14E, 0x5601, 0xE14F, 0x5613, 0xE150, 0x5602, 0xE151, 0x55FA,
+	0xE152, 0x561D, 0xE153, 0x5604, 0xE154, 0x55FF, 0xE155, 0x55F9,
+	0xE156, 0x5889, 0xE157, 0x587C, 0xE158, 0x5890, 0xE159, 0x5898,
+	0xE15A, 0x5886, 0xE15B, 0x5881, 0xE15C, 0x587F, 0xE15D, 0x5874,
+	0xE15E, 0x588B, 0xE15F, 0x587A, 0xE160, 0x5887, 0xE161, 0x5891,
+	0xE162, 0x588E, 0xE163, 0x5876, 0xE164, 0x5882, 0xE165, 0x5888,
+	0xE166, 0x587B, 0xE167, 0x5894, 0xE168, 0x588F, 0xE169, 0x58FE,
+	0xE16A, 0x596B, 0xE16B, 0x5ADC, 0xE16C, 0x5AEE, 0xE16D, 0x5AE5,
+	0xE16E, 0x5AD5, 0xE16F, 0x5AEA, 0xE170, 0x5ADA, 0xE171, 0x5AED,
+	0xE172, 0x5AEB, 0xE173, 0x5AF3, 0xE174, 0x5AE2, 0xE175, 0x5AE0,
+	0xE176, 0x5ADB, 0xE177, 0x5AEC, 0xE178, 0x5ADE, 0xE179, 0x5ADD,
+	0xE17A, 0x5AD9, 0xE17B, 0x5AE8, 0xE17C, 0x5ADF, 0xE17D, 0x5B77,
+	0xE17E, 0x5BE0, 0xE1A1, 0x5BE3, 0xE1A2, 0x5C63, 0xE1A3, 0x5D82,
+	0xE1A4, 0x5D80, 0xE1A5, 0x5D7D, 0xE1A6, 0x5D86, 0xE1A7, 0x5D7A,
+	0xE1A8, 0x5D81, 0xE1A9, 0x5D77, 0xE1AA, 0x5D8A, 0xE1AB, 0x5D89,
+	0xE1AC, 0x5D88, 0xE1AD, 0x5D7E, 0xE1AE, 0x5D7C, 0xE1AF, 0x5D8D,
+	0xE1B0, 0x5D79, 0xE1B1, 0x5D7F, 0xE1B2, 0x5E58, 0xE1B3, 0x5E59,
+	0xE1B4, 0x5E53, 0xE1B5, 0x5ED8, 0xE1B6, 0x5ED1, 0xE1B7, 0x5ED7,
+	0xE1B8, 0x5ECE, 0xE1B9, 0x5EDC, 0xE1BA, 0x5ED5, 0xE1BB, 0x5ED9,
+	0xE1BC, 0x5ED2, 0xE1BD, 0x5ED4, 0xE1BE, 0x5F44, 0xE1BF, 0x5F43,
+	0xE1C0, 0x5F6F, 0xE1C1, 0x5FB6, 0xE1C2, 0x612C, 0xE1C3, 0x6128,
+	0xE1C4, 0x6141, 0xE1C5, 0x615E, 0xE1C6, 0x6171, 0xE1C7, 0x6173,
+	0xE1C8, 0x6152, 0xE1C9, 0x6153, 0xE1CA, 0x6172, 0xE1CB, 0x616C,
+	0xE1CC, 0x6180, 0xE1CD, 0x6174, 0xE1CE, 0x6154, 0xE1CF, 0x617A,
+	0xE1D0, 0x615B, 0xE1D1, 0x6165, 0xE1D2, 0x613B, 0xE1D3, 0x616A,
+	0xE1D4, 0x6161, 0xE1D5, 0x6156, 0xE1D6, 0x6229, 0xE1D7, 0x6227,
+	0xE1D8, 0x622B, 0xE1D9, 0x642B, 0xE1DA, 0x644D, 0xE1DB, 0x645B,
+	0xE1DC, 0x645D, 0xE1DD, 0x6474, 0xE1DE, 0x6476, 0xE1DF, 0x6472,
+	0xE1E0, 0x6473, 0xE1E1, 0x647D, 0xE1E2, 0x6475, 0xE1E3, 0x6466,
+	0xE1E4, 0x64A6, 0xE1E5, 0x644E, 0xE1E6, 0x6482, 0xE1E7, 0x645E,
+	0xE1E8, 0x645C, 0xE1E9, 0x644B, 0xE1EA, 0x6453, 0xE1EB, 0x6460,
+	0xE1EC, 0x6450, 0xE1ED, 0x647F, 0xE1EE, 0x643F, 0xE1EF, 0x646C,
+	0xE1F0, 0x646B, 0xE1F1, 0x6459, 0xE1F2, 0x6465, 0xE1F3, 0x6477,
+	0xE1F4, 0x6573, 0xE1F5, 0x65A0, 0xE1F6, 0x66A1, 0xE1F7, 0x66A0,
+	0xE1F8, 0x669F, 0xE1F9, 0x6705, 0xE1FA, 0x6704, 0xE1FB, 0x6722,
+	0xE1FC, 0x69B1, 0xE1FD, 0x69B6, 0xE1FE, 0x69C9, 0xE240, 0x69A0,
+	0xE241, 0x69CE, 0xE242, 0x6996, 0xE243, 0x69B0, 0xE244, 0x69AC,
+	0xE245, 0x69BC, 0xE246, 0x6991, 0xE247, 0x6999, 0xE248, 0x698E,
+	0xE249, 0x69A7, 0xE24A, 0x698D, 0xE24B, 0x69A9, 0xE24C, 0x69BE,
+	0xE24D, 0x69AF, 0xE24E, 0x69BF, 0xE24F, 0x69C4, 0xE250, 0x69BD,
+	0xE251, 0x69A4, 0xE252, 0x69D4, 0xE253, 0x69B9, 0xE254, 0x69CA,
+	0xE255, 0x699A, 0xE256, 0x69CF, 0xE257, 0x69B3, 0xE258, 0x6993,
+	0xE259, 0x69AA, 0xE25A, 0x69A1, 0xE25B, 0x699E, 0xE25C, 0x69D9,
+	0xE25D, 0x6997, 0xE25E, 0x6990, 0xE25F, 0x69C2, 0xE260, 0x69B5,
+	0xE261, 0x69A5, 0xE262, 0x69C6, 0xE263, 0x6B4A, 0xE264, 0x6B4D,
+	0xE265, 0x6B4B, 0xE266, 0x6B9E, 0xE267, 0x6B9F, 0xE268, 0x6BA0,
+	0xE269, 0x6BC3, 0xE26A, 0x6BC4, 0xE26B, 0x6BFE, 0xE26C, 0x6ECE,
+	0xE26D, 0x6EF5, 0xE26E, 0x6EF1, 0xE26F, 0x6F03, 0xE270, 0x6F25,
+	0xE271, 0x6EF8, 0xE272, 0x6F37, 0xE273, 0x6EFB, 0xE274, 0x6F2E,
+	0xE275, 0x6F09, 0xE276, 0x6F4E, 0xE277, 0x6F19, 0xE278, 0x6F1A,
+	0xE279, 0x6F27, 0xE27A, 0x6F18, 0xE27B, 0x6F3B, 0xE27C, 0x6F12,
+	0xE27D, 0x6EED, 0xE27E, 0x6F0A, 0xE2A1, 0x6F36, 0xE2A2, 0x6F73,
+	0xE2A3, 0x6EF9, 0xE2A4, 0x6EEE, 0xE2A5, 0x6F2D, 0xE2A6, 0x6F40,
+	0xE2A7, 0x6F30, 0xE2A8, 0x6F3C, 0xE2A9, 0x6F35, 0xE2AA, 0x6EEB,
+	0xE2AB, 0x6F07, 0xE2AC, 0x6F0E, 0xE2AD, 0x6F43, 0xE2AE, 0x6F05,
+	0xE2AF, 0x6EFD, 0xE2B0, 0x6EF6, 0xE2B1, 0x6F39, 0xE2B2, 0x6F1C,
+	0xE2B3, 0x6EFC, 0xE2B4, 0x6F3A, 0xE2B5, 0x6F1F, 0xE2B6, 0x6F0D,
+	0xE2B7, 0x6F1E, 0xE2B8, 0x6F08, 0xE2B9, 0x6F21, 0xE2BA, 0x7187,
+	0xE2BB, 0x7190, 0xE2BC, 0x7189, 0xE2BD, 0x7180, 0xE2BE, 0x7185,
+	0xE2BF, 0x7182, 0xE2C0, 0x718F, 0xE2C1, 0x717B, 0xE2C2, 0x7186,
+	0xE2C3, 0x7181, 0xE2C4, 0x7197, 0xE2C5, 0x7244, 0xE2C6, 0x7253,
+	0xE2C7, 0x7297, 0xE2C8, 0x7295, 0xE2C9, 0x7293, 0xE2CA, 0x7343,
+	0xE2CB, 0x734D, 0xE2CC, 0x7351, 0xE2CD, 0x734C, 0xE2CE, 0x7462,
+	0xE2CF, 0x7473, 0xE2D0, 0x7471, 0xE2D1, 0x7475, 0xE2D2, 0x7472,
+	0xE2D3, 0x7467, 0xE2D4, 0x746E, 0xE2D5, 0x7500, 0xE2D6, 0x7502,
+	0xE2D7, 0x7503, 0xE2D8, 0x757D, 0xE2D9, 0x7590, 0xE2DA, 0x7616,
+	0xE2DB, 0x7608, 0xE2DC, 0x760C, 0xE2DD, 0x7615, 0xE2DE, 0x7611,
+	0xE2DF, 0x760A, 0xE2E0, 0x7614, 0xE2E1, 0x76B8, 0xE2E2, 0x7781,
+	0xE2E3, 0x777C, 0xE2E4, 0x7785, 0xE2E5, 0x7782, 0xE2E6, 0x776E,
+	0xE2E7, 0x7780, 0xE2E8, 0x776F, 0xE2E9, 0x777E, 0xE2EA, 0x7783,
+	0xE2EB, 0x78B2, 0xE2EC, 0x78AA, 0xE2ED, 0x78B4, 0xE2EE, 0x78AD,
+	0xE2EF, 0x78A8, 0xE2F0, 0x787E, 0xE2F1, 0x78AB, 0xE2F2, 0x789E,
+	0xE2F3, 0x78A5, 0xE2F4, 0x78A0, 0xE2F5, 0x78AC, 0xE2F6, 0x78A2,
+	0xE2F7, 0x78A4, 0xE2F8, 0x7998, 0xE2F9, 0x798A, 0xE2FA, 0x798B,
+	0xE2FB, 0x7996, 0xE2FC, 0x7995, 0xE2FD, 0x7994, 0xE2FE, 0x7993,
+	0xE340, 0x7997, 0xE341, 0x7988, 0xE342, 0x7992, 0xE343, 0x7990,
+	0xE344, 0x7A2B, 0xE345, 0x7A4A, 0xE346, 0x7A30, 0xE347, 0x7A2F,
+	0xE348, 0x7A28, 0xE349, 0x7A26, 0xE34A, 0x7AA8, 0xE34B, 0x7AAB,
+	0xE34C, 0x7AAC, 0xE34D, 0x7AEE, 0xE34E, 0x7B88, 0xE34F, 0x7B9C,
+	0xE350, 0x7B8A, 0xE351, 0x7B91, 0xE352, 0x7B90, 0xE353, 0x7B96,
+	0xE354, 0x7B8D, 0xE355, 0x7B8C, 0xE356, 0x7B9B, 0xE357, 0x7B8E,
+	0xE358, 0x7B85, 0xE359, 0x7B98, 0xE35A, 0x5284, 0xE35B, 0x7B99,
+	0xE35C, 0x7BA4, 0xE35D, 0x7B82, 0xE35E, 0x7CBB, 0xE35F, 0x7CBF,
+	0xE360, 0x7CBC, 0xE361, 0x7CBA, 0xE362, 0x7DA7, 0xE363, 0x7DB7,
+	0xE364, 0x7DC2, 0xE365, 0x7DA3, 0xE366, 0x7DAA, 0xE367, 0x7DC1,
+	0xE368, 0x7DC0, 0xE369, 0x7DC5, 0xE36A, 0x7D9D, 0xE36B, 0x7DCE,
+	0xE36C, 0x7DC4, 0xE36D, 0x7DC6, 0xE36E, 0x7DCB, 0xE36F, 0x7DCC,
+	0xE370, 0x7DAF, 0xE371, 0x7DB9, 0xE372, 0x7D96, 0xE373, 0x7DBC,
+	0xE374, 0x7D9F, 0xE375, 0x7DA6, 0xE376, 0x7DAE, 0xE377, 0x7DA9,
+	0xE378, 0x7DA1, 0xE379, 0x7DC9, 0xE37A, 0x7F73, 0xE37B, 0x7FE2,
+	0xE37C, 0x7FE3, 0xE37D, 0x7FE5, 0xE37E, 0x7FDE, 0xE3A1, 0x8024,
+	0xE3A2, 0x805D, 0xE3A3, 0x805C, 0xE3A4, 0x8189, 0xE3A5, 0x8186,
+	0xE3A6, 0x8183, 0xE3A7, 0x8187, 0xE3A8, 0x818D, 0xE3A9, 0x818C,
+	0xE3AA, 0x818B, 0xE3AB, 0x8215, 0xE3AC, 0x8497, 0xE3AD, 0x84A4,
+	0xE3AE, 0x84A1, 0xE3AF, 0x849F, 0xE3B0, 0x84BA, 0xE3B1, 0x84CE,
+	0xE3B2, 0x84C2, 0xE3B3, 0x84AC, 0xE3B4, 0x84AE, 0xE3B5, 0x84AB,
+	0xE3B6, 0x84B9, 0xE3B7, 0x84B4, 0xE3B8, 0x84C1, 0xE3B9, 0x84CD,
+	0xE3BA, 0x84AA, 0xE3BB, 0x849A, 0xE3BC, 0x84B1, 0xE3BD, 0x84D0,
+	0xE3BE, 0x849D, 0xE3BF, 0x84A7, 0xE3C0, 0x84BB, 0xE3C1, 0x84A2,
+	0xE3C2, 0x8494, 0xE3C3, 0x84C7, 0xE3C4, 0x84CC, 0xE3C5, 0x849B,
+	0xE3C6, 0x84A9, 0xE3C7, 0x84AF, 0xE3C8, 0x84A8, 0xE3C9, 0x84D6,
+	0xE3CA, 0x8498, 0xE3CB, 0x84B6, 0xE3CC, 0x84CF, 0xE3CD, 0x84A0,
+	0xE3CE, 0x84D7, 0xE3CF, 0x84D4, 0xE3D0, 0x84D2, 0xE3D1, 0x84DB,
+	0xE3D2, 0x84B0, 0xE3D3, 0x8491, 0xE3D4, 0x8661, 0xE3D5, 0x8733,
+	0xE3D6, 0x8723, 0xE3D7, 0x8728, 0xE3D8, 0x876B, 0xE3D9, 0x8740,
+	0xE3DA, 0x872E, 0xE3DB, 0x871E, 0xE3DC, 0x8721, 0xE3DD, 0x8719,
+	0xE3DE, 0x871B, 0xE3DF, 0x8743, 0xE3E0, 0x872C, 0xE3E1, 0x8741,
+	0xE3E2, 0x873E, 0xE3E3, 0x8746, 0xE3E4, 0x8720, 0xE3E5, 0x8732,
+	0xE3E6, 0x872A, 0xE3E7, 0x872D, 0xE3E8, 0x873C, 0xE3E9, 0x8712,
+	0xE3EA, 0x873A, 0xE3EB, 0x8731, 0xE3EC, 0x8735, 0xE3ED, 0x8742,
+	0xE3EE, 0x8726, 0xE3EF, 0x8727, 0xE3F0, 0x8738, 0xE3F1, 0x8724,
+	0xE3F2, 0x871A, 0xE3F3, 0x8730, 0xE3F4, 0x8711, 0xE3F5, 0x88F7,
+	0xE3F6, 0x88E7, 0xE3F7, 0x88F1, 0xE3F8, 0x88F2, 0xE3F9, 0x88FA,
+	0xE3FA, 0x88FE, 0xE3FB, 0x88EE, 0xE3FC, 0x88FC, 0xE3FD, 0x88F6,
+	0xE3FE, 0x88FB, 0xE440, 0x88F0, 0xE441, 0x88EC, 0xE442, 0x88EB,
+	0xE443, 0x899D, 0xE444, 0x89A1, 0xE445, 0x899F, 0xE446, 0x899E,
+	0xE447, 0x89E9, 0xE448, 0x89EB, 0xE449, 0x89E8, 0xE44A, 0x8AAB,
+	0xE44B, 0x8A99, 0xE44C, 0x8A8B, 0xE44D, 0x8A92, 0xE44E, 0x8A8F,
+	0xE44F, 0x8A96, 0xE450, 0x8C3D, 0xE451, 0x8C68, 0xE452, 0x8C69,
+	0xE453, 0x8CD5, 0xE454, 0x8CCF, 0xE455, 0x8CD7, 0xE456, 0x8D96,
+	0xE457, 0x8E09, 0xE458, 0x8E02, 0xE459, 0x8DFF, 0xE45A, 0x8E0D,
+	0xE45B, 0x8DFD, 0xE45C, 0x8E0A, 0xE45D, 0x8E03, 0xE45E, 0x8E07,
+	0xE45F, 0x8E06, 0xE460, 0x8E05, 0xE461, 0x8DFE, 0xE462, 0x8E00,
+	0xE463, 0x8E04, 0xE464, 0x8F10, 0xE465, 0x8F11, 0xE466, 0x8F0E,
+	0xE467, 0x8F0D, 0xE468, 0x9123, 0xE469, 0x911C, 0xE46A, 0x9120,
+	0xE46B, 0x9122, 0xE46C, 0x911F, 0xE46D, 0x911D, 0xE46E, 0x911A,
+	0xE46F, 0x9124, 0xE470, 0x9121, 0xE471, 0x911B, 0xE472, 0x917A,
+	0xE473, 0x9172, 0xE474, 0x9179, 0xE475, 0x9173, 0xE476, 0x92A5,
+	0xE477, 0x92A4, 0xE478, 0x9276, 0xE479, 0x929B, 0xE47A, 0x927A,
+	0xE47B, 0x92A0, 0xE47C, 0x9294, 0xE47D, 0x92AA, 0xE47E, 0x928D,
+	0xE4A1, 0x92A6, 0xE4A2, 0x929A, 0xE4A3, 0x92AB, 0xE4A4, 0x9279,
+	0xE4A5, 0x9297, 0xE4A6, 0x927F, 0xE4A7, 0x92A3, 0xE4A8, 0x92EE,
+	0xE4A9, 0x928E, 0xE4AA, 0x9282, 0xE4AB, 0x9295, 0xE4AC, 0x92A2,
+	0xE4AD, 0x927D, 0xE4AE, 0x9288, 0xE4AF, 0x92A1, 0xE4B0, 0x928A,
+	0xE4B1, 0x9286, 0xE4B2, 0x928C, 0xE4B3, 0x9299, 0xE4B4, 0x92A7,
+	0xE4B5, 0x927E, 0xE4B6, 0x9287, 0xE4B7, 0x92A9, 0xE4B8, 0x929D,
+	0xE4B9, 0x928B, 0xE4BA, 0x922D, 0xE4BB, 0x969E, 0xE4BC, 0x96A1,
+	0xE4BD, 0x96FF, 0xE4BE, 0x9758, 0xE4BF, 0x977D, 0xE4C0, 0x977A,
+	0xE4C1, 0x977E, 0xE4C2, 0x9783, 0xE4C3, 0x9780, 0xE4C4, 0x9782,
+	0xE4C5, 0x977B, 0xE4C6, 0x9784, 0xE4C7, 0x9781, 0xE4C8, 0x977F,
+	0xE4C9, 0x97CE, 0xE4CA, 0x97CD, 0xE4CB, 0x9816, 0xE4CC, 0x98AD,
+	0xE4CD, 0x98AE, 0xE4CE, 0x9902, 0xE4CF, 0x9900, 0xE4D0, 0x9907,
+	0xE4D1, 0x999D, 0xE4D2, 0x999C, 0xE4D3, 0x99C3, 0xE4D4, 0x99B9,
+	0xE4D5, 0x99BB, 0xE4D6, 0x99BA, 0xE4D7, 0x99C2, 0xE4D8, 0x99BD,
+	0xE4D9, 0x99C7, 0xE4DA, 0x9AB1, 0xE4DB, 0x9AE3, 0xE4DC, 0x9AE7,
+	0xE4DD, 0x9B3E, 0xE4DE, 0x9B3F, 0xE4DF, 0x9B60, 0xE4E0, 0x9B61,
+	0xE4E1, 0x9B5F, 0xE4E2, 0x9CF1, 0xE4E3, 0x9CF2, 0xE4E4, 0x9CF5,
+	0xE4E5, 0x9EA7, 0xE4E6, 0x50FF, 0xE4E7, 0x5103, 0xE4E8, 0x5130,
+	0xE4E9, 0x50F8, 0xE4EA, 0x5106, 0xE4EB, 0x5107, 0xE4EC, 0x50F6,
+	0xE4ED, 0x50FE, 0xE4EE, 0x510B, 0xE4EF, 0x510C, 0xE4F0, 0x50FD,
+	0xE4F1, 0x510A, 0xE4F2, 0x528B, 0xE4F3, 0x528C, 0xE4F4, 0x52F1,
+	0xE4F5, 0x52EF, 0xE4F6, 0x5648, 0xE4F7, 0x5642, 0xE4F8, 0x564C,
+	0xE4F9, 0x5635, 0xE4FA, 0x5641, 0xE4FB, 0x564A, 0xE4FC, 0x5649,
+	0xE4FD, 0x5646, 0xE4FE, 0x5658, 0xE540, 0x565A, 0xE541, 0x5640,
+	0xE542, 0x5633, 0xE543, 0x563D, 0xE544, 0x562C, 0xE545, 0x563E,
+	0xE546, 0x5638, 0xE547, 0x562A, 0xE548, 0x563A, 0xE549, 0x571A,
+	0xE54A, 0x58AB, 0xE54B, 0x589D, 0xE54C, 0x58B1, 0xE54D, 0x58A0,
+	0xE54E, 0x58A3, 0xE54F, 0x58AF, 0xE550, 0x58AC, 0xE551, 0x58A5,
+	0xE552, 0x58A1, 0xE553, 0x58FF, 0xE554, 0x5AFF, 0xE555, 0x5AF4,
+	0xE556, 0x5AFD, 0xE557, 0x5AF7, 0xE558, 0x5AF6, 0xE559, 0x5B03,
+	0xE55A, 0x5AF8, 0xE55B, 0x5B02, 0xE55C, 0x5AF9, 0xE55D, 0x5B01,
+	0xE55E, 0x5B07, 0xE55F, 0x5B05, 0xE560, 0x5B0F, 0xE561, 0x5C67,
+	0xE562, 0x5D99, 0xE563, 0x5D97, 0xE564, 0x5D9F, 0xE565, 0x5D92,
+	0xE566, 0x5DA2, 0xE567, 0x5D93, 0xE568, 0x5D95, 0xE569, 0x5DA0,
+	0xE56A, 0x5D9C, 0xE56B, 0x5DA1, 0xE56C, 0x5D9A, 0xE56D, 0x5D9E,
+	0xE56E, 0x5E69, 0xE56F, 0x5E5D, 0xE570, 0x5E60, 0xE571, 0x5E5C,
+	0xE572, 0x7DF3, 0xE573, 0x5EDB, 0xE574, 0x5EDE, 0xE575, 0x5EE1,
+	0xE576, 0x5F49, 0xE577, 0x5FB2, 0xE578, 0x618B, 0xE579, 0x6183,
+	0xE57A, 0x6179, 0xE57B, 0x61B1, 0xE57C, 0x61B0, 0xE57D, 0x61A2,
+	0xE57E, 0x6189, 0xE5A1, 0x619B, 0xE5A2, 0x6193, 0xE5A3, 0x61AF,
+	0xE5A4, 0x61AD, 0xE5A5, 0x619F, 0xE5A6, 0x6192, 0xE5A7, 0x61AA,
+	0xE5A8, 0x61A1, 0xE5A9, 0x618D, 0xE5AA, 0x6166, 0xE5AB, 0x61B3,
+	0xE5AC, 0x622D, 0xE5AD, 0x646E, 0xE5AE, 0x6470, 0xE5AF, 0x6496,
+	0xE5B0, 0x64A0, 0xE5B1, 0x6485, 0xE5B2, 0x6497, 0xE5B3, 0x649C,
+	0xE5B4, 0x648F, 0xE5B5, 0x648B, 0xE5B6, 0x648A, 0xE5B7, 0x648C,
+	0xE5B8, 0x64A3, 0xE5B9, 0x649F, 0xE5BA, 0x6468, 0xE5BB, 0x64B1,
+	0xE5BC, 0x6498, 0xE5BD, 0x6576, 0xE5BE, 0x657A, 0xE5BF, 0x6579,
+	0xE5C0, 0x657B, 0xE5C1, 0x65B2, 0xE5C2, 0x65B3, 0xE5C3, 0x66B5,
+	0xE5C4, 0x66B0, 0xE5C5, 0x66A9, 0xE5C6, 0x66B2, 0xE5C7, 0x66B7,
+	0xE5C8, 0x66AA, 0xE5C9, 0x66AF, 0xE5CA, 0x6A00, 0xE5CB, 0x6A06,
+	0xE5CC, 0x6A17, 0xE5CD, 0x69E5, 0xE5CE, 0x69F8, 0xE5CF, 0x6A15,
+	0xE5D0, 0x69F1, 0xE5D1, 0x69E4, 0xE5D2, 0x6A20, 0xE5D3, 0x69FF,
+	0xE5D4, 0x69EC, 0xE5D5, 0x69E2, 0xE5D6, 0x6A1B, 0xE5D7, 0x6A1D,
+	0xE5D8, 0x69FE, 0xE5D9, 0x6A27, 0xE5DA, 0x69F2, 0xE5DB, 0x69EE,
+	0xE5DC, 0x6A14, 0xE5DD, 0x69F7, 0xE5DE, 0x69E7, 0xE5DF, 0x6A40,
+	0xE5E0, 0x6A08, 0xE5E1, 0x69E6, 0xE5E2, 0x69FB, 0xE5E3, 0x6A0D,
+	0xE5E4, 0x69FC, 0xE5E5, 0x69EB, 0xE5E6, 0x6A09, 0xE5E7, 0x6A04,
+	0xE5E8, 0x6A18, 0xE5E9, 0x6A25, 0xE5EA, 0x6A0F, 0xE5EB, 0x69F6,
+	0xE5EC, 0x6A26, 0xE5ED, 0x6A07, 0xE5EE, 0x69F4, 0xE5EF, 0x6A16,
+	0xE5F0, 0x6B51, 0xE5F1, 0x6BA5, 0xE5F2, 0x6BA3, 0xE5F3, 0x6BA2,
+	0xE5F4, 0x6BA6, 0xE5F5, 0x6C01, 0xE5F6, 0x6C00, 0xE5F7, 0x6BFF,
+	0xE5F8, 0x6C02, 0xE5F9, 0x6F41, 0xE5FA, 0x6F26, 0xE5FB, 0x6F7E,
+	0xE5FC, 0x6F87, 0xE5FD, 0x6FC6, 0xE5FE, 0x6F92, 0xE640, 0x6F8D,
+	0xE641, 0x6F89, 0xE642, 0x6F8C, 0xE643, 0x6F62, 0xE644, 0x6F4F,
+	0xE645, 0x6F85, 0xE646, 0x6F5A, 0xE647, 0x6F96, 0xE648, 0x6F76,
+	0xE649, 0x6F6C, 0xE64A, 0x6F82, 0xE64B, 0x6F55, 0xE64C, 0x6F72,
+	0xE64D, 0x6F52, 0xE64E, 0x6F50, 0xE64F, 0x6F57, 0xE650, 0x6F94,
+	0xE651, 0x6F93, 0xE652, 0x6F5D, 0xE653, 0x6F00, 0xE654, 0x6F61,
+	0xE655, 0x6F6B, 0xE656, 0x6F7D, 0xE657, 0x6F67, 0xE658, 0x6F90,
+	0xE659, 0x6F53, 0xE65A, 0x6F8B, 0xE65B, 0x6F69, 0xE65C, 0x6F7F,
+	0xE65D, 0x6F95, 0xE65E, 0x6F63, 0xE65F, 0x6F77, 0xE660, 0x6F6A,
+	0xE661, 0x6F7B, 0xE662, 0x71B2, 0xE663, 0x71AF, 0xE664, 0x719B,
+	0xE665, 0x71B0, 0xE666, 0x71A0, 0xE667, 0x719A, 0xE668, 0x71A9,
+	0xE669, 0x71B5, 0xE66A, 0x719D, 0xE66B, 0x71A5, 0xE66C, 0x719E,
+	0xE66D, 0x71A4, 0xE66E, 0x71A1, 0xE66F, 0x71AA, 0xE670, 0x719C,
+	0xE671, 0x71A7, 0xE672, 0x71B3, 0xE673, 0x7298, 0xE674, 0x729A,
+	0xE675, 0x7358, 0xE676, 0x7352, 0xE677, 0x735E, 0xE678, 0x735F,
+	0xE679, 0x7360, 0xE67A, 0x735D, 0xE67B, 0x735B, 0xE67C, 0x7361,
+	0xE67D, 0x735A, 0xE67E, 0x7359, 0xE6A1, 0x7362, 0xE6A2, 0x7487,
+	0xE6A3, 0x7489, 0xE6A4, 0x748A, 0xE6A5, 0x7486, 0xE6A6, 0x7481,
+	0xE6A7, 0x747D, 0xE6A8, 0x7485, 0xE6A9, 0x7488, 0xE6AA, 0x747C,
+	0xE6AB, 0x7479, 0xE6AC, 0x7508, 0xE6AD, 0x7507, 0xE6AE, 0x757E,
+	0xE6AF, 0x7625, 0xE6B0, 0x761E, 0xE6B1, 0x7619, 0xE6B2, 0x761D,
+	0xE6B3, 0x761C, 0xE6B4, 0x7623, 0xE6B5, 0x761A, 0xE6B6, 0x7628,
+	0xE6B7, 0x761B, 0xE6B8, 0x769C, 0xE6B9, 0x769D, 0xE6BA, 0x769E,
+	0xE6BB, 0x769B, 0xE6BC, 0x778D, 0xE6BD, 0x778F, 0xE6BE, 0x7789,
+	0xE6BF, 0x7788, 0xE6C0, 0x78CD, 0xE6C1, 0x78BB, 0xE6C2, 0x78CF,
+	0xE6C3, 0x78CC, 0xE6C4, 0x78D1, 0xE6C5, 0x78CE, 0xE6C6, 0x78D4,
+	0xE6C7, 0x78C8, 0xE6C8, 0x78C3, 0xE6C9, 0x78C4, 0xE6CA, 0x78C9,
+	0xE6CB, 0x799A, 0xE6CC, 0x79A1, 0xE6CD, 0x79A0, 0xE6CE, 0x799C,
+	0xE6CF, 0x79A2, 0xE6D0, 0x799B, 0xE6D1, 0x6B76, 0xE6D2, 0x7A39,
+	0xE6D3, 0x7AB2, 0xE6D4, 0x7AB4, 0xE6D5, 0x7AB3, 0xE6D6, 0x7BB7,
+	0xE6D7, 0x7BCB, 0xE6D8, 0x7BBE, 0xE6D9, 0x7BAC, 0xE6DA, 0x7BCE,
+	0xE6DB, 0x7BAF, 0xE6DC, 0x7BB9, 0xE6DD, 0x7BCA, 0xE6DE, 0x7BB5,
+	0xE6DF, 0x7CC5, 0xE6E0, 0x7CC8, 0xE6E1, 0x7CCC, 0xE6E2, 0x7CCB,
+	0xE6E3, 0x7DF7, 0xE6E4, 0x7DDB, 0xE6E5, 0x7DEA, 0xE6E6, 0x7DE7,
+	0xE6E7, 0x7DD7, 0xE6E8, 0x7DE1, 0xE6E9, 0x7E03, 0xE6EA, 0x7DFA,
+	0xE6EB, 0x7DE6, 0xE6EC, 0x7DF6, 0xE6ED, 0x7DF1, 0xE6EE, 0x7DF0,
+	0xE6EF, 0x7DEE, 0xE6F0, 0x7DDF, 0xE6F1, 0x7F76, 0xE6F2, 0x7FAC,
+	0xE6F3, 0x7FB0, 0xE6F4, 0x7FAD, 0xE6F5, 0x7FED, 0xE6F6, 0x7FEB,
+	0xE6F7, 0x7FEA, 0xE6F8, 0x7FEC, 0xE6F9, 0x7FE6, 0xE6FA, 0x7FE8,
+	0xE6FB, 0x8064, 0xE6FC, 0x8067, 0xE6FD, 0x81A3, 0xE6FE, 0x819F,
+	0xE740, 0x819E, 0xE741, 0x8195, 0xE742, 0x81A2, 0xE743, 0x8199,
+	0xE744, 0x8197, 0xE745, 0x8216, 0xE746, 0x824F, 0xE747, 0x8253,
+	0xE748, 0x8252, 0xE749, 0x8250, 0xE74A, 0x824E, 0xE74B, 0x8251,
+	0xE74C, 0x8524, 0xE74D, 0x853B, 0xE74E, 0x850F, 0xE74F, 0x8500,
+	0xE750, 0x8529, 0xE751, 0x850E, 0xE752, 0x8509, 0xE753, 0x850D,
+	0xE754, 0x851F, 0xE755, 0x850A, 0xE756, 0x8527, 0xE757, 0x851C,
+	0xE758, 0x84FB, 0xE759, 0x852B, 0xE75A, 0x84FA, 0xE75B, 0x8508,
+	0xE75C, 0x850C, 0xE75D, 0x84F4, 0xE75E, 0x852A, 0xE75F, 0x84F2,
+	0xE760, 0x8515, 0xE761, 0x84F7, 0xE762, 0x84EB, 0xE763, 0x84F3,
+	0xE764, 0x84FC, 0xE765, 0x8512, 0xE766, 0x84EA, 0xE767, 0x84E9,
+	0xE768, 0x8516, 0xE769, 0x84FE, 0xE76A, 0x8528, 0xE76B, 0x851D,
+	0xE76C, 0x852E, 0xE76D, 0x8502, 0xE76E, 0x84FD, 0xE76F, 0x851E,
+	0xE770, 0x84F6, 0xE771, 0x8531, 0xE772, 0x8526, 0xE773, 0x84E7,
+	0xE774, 0x84E8, 0xE775, 0x84F0, 0xE776, 0x84EF, 0xE777, 0x84F9,
+	0xE778, 0x8518, 0xE779, 0x8520, 0xE77A, 0x8530, 0xE77B, 0x850B,
+	0xE77C, 0x8519, 0xE77D, 0x852F, 0xE77E, 0x8662, 0xE7A1, 0x8756,
+	0xE7A2, 0x8763, 0xE7A3, 0x8764, 0xE7A4, 0x8777, 0xE7A5, 0x87E1,
+	0xE7A6, 0x8773, 0xE7A7, 0x8758, 0xE7A8, 0x8754, 0xE7A9, 0x875B,
+	0xE7AA, 0x8752, 0xE7AB, 0x8761, 0xE7AC, 0x875A, 0xE7AD, 0x8751,
+	0xE7AE, 0x875E, 0xE7AF, 0x876D, 0xE7B0, 0x876A, 0xE7B1, 0x8750,
+	0xE7B2, 0x874E, 0xE7B3, 0x875F, 0xE7B4, 0x875D, 0xE7B5, 0x876F,
+	0xE7B6, 0x876C, 0xE7B7, 0x877A, 0xE7B8, 0x876E, 0xE7B9, 0x875C,
+	0xE7BA, 0x8765, 0xE7BB, 0x874F, 0xE7BC, 0x877B, 0xE7BD, 0x8775,
+	0xE7BE, 0x8762, 0xE7BF, 0x8767, 0xE7C0, 0x8769, 0xE7C1, 0x885A,
+	0xE7C2, 0x8905, 0xE7C3, 0x890C, 0xE7C4, 0x8914, 0xE7C5, 0x890B,
+	0xE7C6, 0x8917, 0xE7C7, 0x8918, 0xE7C8, 0x8919, 0xE7C9, 0x8906,
+	0xE7CA, 0x8916, 0xE7CB, 0x8911, 0xE7CC, 0x890E, 0xE7CD, 0x8909,
+	0xE7CE, 0x89A2, 0xE7CF, 0x89A4, 0xE7D0, 0x89A3, 0xE7D1, 0x89ED,
+	0xE7D2, 0x89F0, 0xE7D3, 0x89EC, 0xE7D4, 0x8ACF, 0xE7D5, 0x8AC6,
+	0xE7D6, 0x8AB8, 0xE7D7, 0x8AD3, 0xE7D8, 0x8AD1, 0xE7D9, 0x8AD4,
+	0xE7DA, 0x8AD5, 0xE7DB, 0x8ABB, 0xE7DC, 0x8AD7, 0xE7DD, 0x8ABE,
+	0xE7DE, 0x8AC0, 0xE7DF, 0x8AC5, 0xE7E0, 0x8AD8, 0xE7E1, 0x8AC3,
+	0xE7E2, 0x8ABA, 0xE7E3, 0x8ABD, 0xE7E4, 0x8AD9, 0xE7E5, 0x8C3E,
+	0xE7E6, 0x8C4D, 0xE7E7, 0x8C8F, 0xE7E8, 0x8CE5, 0xE7E9, 0x8CDF,
+	0xE7EA, 0x8CD9, 0xE7EB, 0x8CE8, 0xE7EC, 0x8CDA, 0xE7ED, 0x8CDD,
+	0xE7EE, 0x8CE7, 0xE7EF, 0x8DA0, 0xE7F0, 0x8D9C, 0xE7F1, 0x8DA1,
+	0xE7F2, 0x8D9B, 0xE7F3, 0x8E20, 0xE7F4, 0x8E23, 0xE7F5, 0x8E25,
+	0xE7F6, 0x8E24, 0xE7F7, 0x8E2E, 0xE7F8, 0x8E15, 0xE7F9, 0x8E1B,
+	0xE7FA, 0x8E16, 0xE7FB, 0x8E11, 0xE7FC, 0x8E19, 0xE7FD, 0x8E26,
+	0xE7FE, 0x8E27, 0xE840, 0x8E14, 0xE841, 0x8E12, 0xE842, 0x8E18,
+	0xE843, 0x8E13, 0xE844, 0x8E1C, 0xE845, 0x8E17, 0xE846, 0x8E1A,
+	0xE847, 0x8F2C, 0xE848, 0x8F24, 0xE849, 0x8F18, 0xE84A, 0x8F1A,
+	0xE84B, 0x8F20, 0xE84C, 0x8F23, 0xE84D, 0x8F16, 0xE84E, 0x8F17,
+	0xE84F, 0x9073, 0xE850, 0x9070, 0xE851, 0x906F, 0xE852, 0x9067,
+	0xE853, 0x906B, 0xE854, 0x912F, 0xE855, 0x912B, 0xE856, 0x9129,
+	0xE857, 0x912A, 0xE858, 0x9132, 0xE859, 0x9126, 0xE85A, 0x912E,
+	0xE85B, 0x9185, 0xE85C, 0x9186, 0xE85D, 0x918A, 0xE85E, 0x9181,
+	0xE85F, 0x9182, 0xE860, 0x9184, 0xE861, 0x9180, 0xE862, 0x92D0,
+	0xE863, 0x92C3, 0xE864, 0x92C4, 0xE865, 0x92C0, 0xE866, 0x92D9,
+	0xE867, 0x92B6, 0xE868, 0x92CF, 0xE869, 0x92F1, 0xE86A, 0x92DF,
+	0xE86B, 0x92D8, 0xE86C, 0x92E9, 0xE86D, 0x92D7, 0xE86E, 0x92DD,
+	0xE86F, 0x92CC, 0xE870, 0x92EF, 0xE871, 0x92C2, 0xE872, 0x92E8,
+	0xE873, 0x92CA, 0xE874, 0x92C8, 0xE875, 0x92CE, 0xE876, 0x92E6,
+	0xE877, 0x92CD, 0xE878, 0x92D5, 0xE879, 0x92C9, 0xE87A, 0x92E0,
+	0xE87B, 0x92DE, 0xE87C, 0x92E7, 0xE87D, 0x92D1, 0xE87E, 0x92D3,
+	0xE8A1, 0x92B5, 0xE8A2, 0x92E1, 0xE8A3, 0x92C6, 0xE8A4, 0x92B4,
+	0xE8A5, 0x957C, 0xE8A6, 0x95AC, 0xE8A7, 0x95AB, 0xE8A8, 0x95AE,
+	0xE8A9, 0x95B0, 0xE8AA, 0x96A4, 0xE8AB, 0x96A2, 0xE8AC, 0x96D3,
+	0xE8AD, 0x9705, 0xE8AE, 0x9708, 0xE8AF, 0x9702, 0xE8B0, 0x975A,
+	0xE8B1, 0x978A, 0xE8B2, 0x978E, 0xE8B3, 0x9788, 0xE8B4, 0x97D0,
+	0xE8B5, 0x97CF, 0xE8B6, 0x981E, 0xE8B7, 0x981D, 0xE8B8, 0x9826,
+	0xE8B9, 0x9829, 0xE8BA, 0x9828, 0xE8BB, 0x9820, 0xE8BC, 0x981B,
+	0xE8BD, 0x9827, 0xE8BE, 0x98B2, 0xE8BF, 0x9908, 0xE8C0, 0x98FA,
+	0xE8C1, 0x9911, 0xE8C2, 0x9914, 0xE8C3, 0x9916, 0xE8C4, 0x9917,
+	0xE8C5, 0x9915, 0xE8C6, 0x99DC, 0xE8C7, 0x99CD, 0xE8C8, 0x99CF,
+	0xE8C9, 0x99D3, 0xE8CA, 0x99D4, 0xE8CB, 0x99CE, 0xE8CC, 0x99C9,
+	0xE8CD, 0x99D6, 0xE8CE, 0x99D8, 0xE8CF, 0x99CB, 0xE8D0, 0x99D7,
+	0xE8D1, 0x99CC, 0xE8D2, 0x9AB3, 0xE8D3, 0x9AEC, 0xE8D4, 0x9AEB,
+	0xE8D5, 0x9AF3, 0xE8D6, 0x9AF2, 0xE8D7, 0x9AF1, 0xE8D8, 0x9B46,
+	0xE8D9, 0x9B43, 0xE8DA, 0x9B67, 0xE8DB, 0x9B74, 0xE8DC, 0x9B71,
+	0xE8DD, 0x9B66, 0xE8DE, 0x9B76, 0xE8DF, 0x9B75, 0xE8E0, 0x9B70,
+	0xE8E1, 0x9B68, 0xE8E2, 0x9B64, 0xE8E3, 0x9B6C, 0xE8E4, 0x9CFC,
+	0xE8E5, 0x9CFA, 0xE8E6, 0x9CFD, 0xE8E7, 0x9CFF, 0xE8E8, 0x9CF7,
+	0xE8E9, 0x9D07, 0xE8EA, 0x9D00, 0xE8EB, 0x9CF9, 0xE8EC, 0x9CFB,
+	0xE8ED, 0x9D08, 0xE8EE, 0x9D05, 0xE8EF, 0x9D04, 0xE8F0, 0x9E83,
+	0xE8F1, 0x9ED3, 0xE8F2, 0x9F0F, 0xE8F3, 0x9F10, 0xE8F4, 0x511C,
+	0xE8F5, 0x5113, 0xE8F6, 0x5117, 0xE8F7, 0x511A, 0xE8F8, 0x5111,
+	0xE8F9, 0x51DE, 0xE8FA, 0x5334, 0xE8FB, 0x53E1, 0xE8FC, 0x5670,
+	0xE8FD, 0x5660, 0xE8FE, 0x566E, 0xE940, 0x5673, 0xE941, 0x5666,
+	0xE942, 0x5663, 0xE943, 0x566D, 0xE944, 0x5672, 0xE945, 0x565E,
+	0xE946, 0x5677, 0xE947, 0x571C, 0xE948, 0x571B, 0xE949, 0x58C8,
+	0xE94A, 0x58BD, 0xE94B, 0x58C9, 0xE94C, 0x58BF, 0xE94D, 0x58BA,
+	0xE94E, 0x58C2, 0xE94F, 0x58BC, 0xE950, 0x58C6, 0xE951, 0x5B17,
+	0xE952, 0x5B19, 0xE953, 0x5B1B, 0xE954, 0x5B21, 0xE955, 0x5B14,
+	0xE956, 0x5B13, 0xE957, 0x5B10, 0xE958, 0x5B16, 0xE959, 0x5B28,
+	0xE95A, 0x5B1A, 0xE95B, 0x5B20, 0xE95C, 0x5B1E, 0xE95D, 0x5BEF,
+	0xE95E, 0x5DAC, 0xE95F, 0x5DB1, 0xE960, 0x5DA9, 0xE961, 0x5DA7,
+	0xE962, 0x5DB5, 0xE963, 0x5DB0, 0xE964, 0x5DAE, 0xE965, 0x5DAA,
+	0xE966, 0x5DA8, 0xE967, 0x5DB2, 0xE968, 0x5DAD, 0xE969, 0x5DAF,
+	0xE96A, 0x5DB4, 0xE96B, 0x5E67, 0xE96C, 0x5E68, 0xE96D, 0x5E66,
+	0xE96E, 0x5E6F, 0xE96F, 0x5EE9, 0xE970, 0x5EE7, 0xE971, 0x5EE6,
+	0xE972, 0x5EE8, 0xE973, 0x5EE5, 0xE974, 0x5F4B, 0xE975, 0x5FBC,
+	0xE976, 0x619D, 0xE977, 0x61A8, 0xE978, 0x6196, 0xE979, 0x61C5,
+	0xE97A, 0x61B4, 0xE97B, 0x61C6, 0xE97C, 0x61C1, 0xE97D, 0x61CC,
+	0xE97E, 0x61BA, 0xE9A1, 0x61BF, 0xE9A2, 0x61B8, 0xE9A3, 0x618C,
+	0xE9A4, 0x64D7, 0xE9A5, 0x64D6, 0xE9A6, 0x64D0, 0xE9A7, 0x64CF,
+	0xE9A8, 0x64C9, 0xE9A9, 0x64BD, 0xE9AA, 0x6489, 0xE9AB, 0x64C3,
+	0xE9AC, 0x64DB, 0xE9AD, 0x64F3, 0xE9AE, 0x64D9, 0xE9AF, 0x6533,
+	0xE9B0, 0x657F, 0xE9B1, 0x657C, 0xE9B2, 0x65A2, 0xE9B3, 0x66C8,
+	0xE9B4, 0x66BE, 0xE9B5, 0x66C0, 0xE9B6, 0x66CA, 0xE9B7, 0x66CB,
+	0xE9B8, 0x66CF, 0xE9B9, 0x66BD, 0xE9BA, 0x66BB, 0xE9BB, 0x66BA,
+	0xE9BC, 0x66CC, 0xE9BD, 0x6723, 0xE9BE, 0x6A34, 0xE9BF, 0x6A66,
+	0xE9C0, 0x6A49, 0xE9C1, 0x6A67, 0xE9C2, 0x6A32, 0xE9C3, 0x6A68,
+	0xE9C4, 0x6A3E, 0xE9C5, 0x6A5D, 0xE9C6, 0x6A6D, 0xE9C7, 0x6A76,
+	0xE9C8, 0x6A5B, 0xE9C9, 0x6A51, 0xE9CA, 0x6A28, 0xE9CB, 0x6A5A,
+	0xE9CC, 0x6A3B, 0xE9CD, 0x6A3F, 0xE9CE, 0x6A41, 0xE9CF, 0x6A6A,
+	0xE9D0, 0x6A64, 0xE9D1, 0x6A50, 0xE9D2, 0x6A4F, 0xE9D3, 0x6A54,
+	0xE9D4, 0x6A6F, 0xE9D5, 0x6A69, 0xE9D6, 0x6A60, 0xE9D7, 0x6A3C,
+	0xE9D8, 0x6A5E, 0xE9D9, 0x6A56, 0xE9DA, 0x6A55, 0xE9DB, 0x6A4D,
+	0xE9DC, 0x6A4E, 0xE9DD, 0x6A46, 0xE9DE, 0x6B55, 0xE9DF, 0x6B54,
+	0xE9E0, 0x6B56, 0xE9E1, 0x6BA7, 0xE9E2, 0x6BAA, 0xE9E3, 0x6BAB,
+	0xE9E4, 0x6BC8, 0xE9E5, 0x6BC7, 0xE9E6, 0x6C04, 0xE9E7, 0x6C03,
+	0xE9E8, 0x6C06, 0xE9E9, 0x6FAD, 0xE9EA, 0x6FCB, 0xE9EB, 0x6FA3,
+	0xE9EC, 0x6FC7, 0xE9ED, 0x6FBC, 0xE9EE, 0x6FCE, 0xE9EF, 0x6FC8,
+	0xE9F0, 0x6F5E, 0xE9F1, 0x6FC4, 0xE9F2, 0x6FBD, 0xE9F3, 0x6F9E,
+	0xE9F4, 0x6FCA, 0xE9F5, 0x6FA8, 0xE9F6, 0x7004, 0xE9F7, 0x6FA5,
+	0xE9F8, 0x6FAE, 0xE9F9, 0x6FBA, 0xE9FA, 0x6FAC, 0xE9FB, 0x6FAA,
+	0xE9FC, 0x6FCF, 0xE9FD, 0x6FBF, 0xE9FE, 0x6FB8, 0xEA40, 0x6FA2,
+	0xEA41, 0x6FC9, 0xEA42, 0x6FAB, 0xEA43, 0x6FCD, 0xEA44, 0x6FAF,
+	0xEA45, 0x6FB2, 0xEA46, 0x6FB0, 0xEA47, 0x71C5, 0xEA48, 0x71C2,
+	0xEA49, 0x71BF, 0xEA4A, 0x71B8, 0xEA4B, 0x71D6, 0xEA4C, 0x71C0,
+	0xEA4D, 0x71C1, 0xEA4E, 0x71CB, 0xEA4F, 0x71D4, 0xEA50, 0x71CA,
+	0xEA51, 0x71C7, 0xEA52, 0x71CF, 0xEA53, 0x71BD, 0xEA54, 0x71D8,
+	0xEA55, 0x71BC, 0xEA56, 0x71C6, 0xEA57, 0x71DA, 0xEA58, 0x71DB,
+	0xEA59, 0x729D, 0xEA5A, 0x729E, 0xEA5B, 0x7369, 0xEA5C, 0x7366,
+	0xEA5D, 0x7367, 0xEA5E, 0x736C, 0xEA5F, 0x7365, 0xEA60, 0x736B,
+	0xEA61, 0x736A, 0xEA62, 0x747F, 0xEA63, 0x749A, 0xEA64, 0x74A0,
+	0xEA65, 0x7494, 0xEA66, 0x7492, 0xEA67, 0x7495, 0xEA68, 0x74A1,
+	0xEA69, 0x750B, 0xEA6A, 0x7580, 0xEA6B, 0x762F, 0xEA6C, 0x762D,
+	0xEA6D, 0x7631, 0xEA6E, 0x763D, 0xEA6F, 0x7633, 0xEA70, 0x763C,
+	0xEA71, 0x7635, 0xEA72, 0x7632, 0xEA73, 0x7630, 0xEA74, 0x76BB,
+	0xEA75, 0x76E6, 0xEA76, 0x779A, 0xEA77, 0x779D, 0xEA78, 0x77A1,
+	0xEA79, 0x779C, 0xEA7A, 0x779B, 0xEA7B, 0x77A2, 0xEA7C, 0x77A3,
+	0xEA7D, 0x7795, 0xEA7E, 0x7799, 0xEAA1, 0x7797, 0xEAA2, 0x78DD,
+	0xEAA3, 0x78E9, 0xEAA4, 0x78E5, 0xEAA5, 0x78EA, 0xEAA6, 0x78DE,
+	0xEAA7, 0x78E3, 0xEAA8, 0x78DB, 0xEAA9, 0x78E1, 0xEAAA, 0x78E2,
+	0xEAAB, 0x78ED, 0xEAAC, 0x78DF, 0xEAAD, 0x78E0, 0xEAAE, 0x79A4,
+	0xEAAF, 0x7A44, 0xEAB0, 0x7A48, 0xEAB1, 0x7A47, 0xEAB2, 0x7AB6,
+	0xEAB3, 0x7AB8, 0xEAB4, 0x7AB5, 0xEAB5, 0x7AB1, 0xEAB6, 0x7AB7,
+	0xEAB7, 0x7BDE, 0xEAB8, 0x7BE3, 0xEAB9, 0x7BE7, 0xEABA, 0x7BDD,
+	0xEABB, 0x7BD5, 0xEABC, 0x7BE5, 0xEABD, 0x7BDA, 0xEABE, 0x7BE8,
+	0xEABF, 0x7BF9, 0xEAC0, 0x7BD4, 0xEAC1, 0x7BEA, 0xEAC2, 0x7BE2,
+	0xEAC3, 0x7BDC, 0xEAC4, 0x7BEB, 0xEAC5, 0x7BD8, 0xEAC6, 0x7BDF,
+	0xEAC7, 0x7CD2, 0xEAC8, 0x7CD4, 0xEAC9, 0x7CD7, 0xEACA, 0x7CD0,
+	0xEACB, 0x7CD1, 0xEACC, 0x7E12, 0xEACD, 0x7E21, 0xEACE, 0x7E17,
+	0xEACF, 0x7E0C, 0xEAD0, 0x7E1F, 0xEAD1, 0x7E20, 0xEAD2, 0x7E13,
+	0xEAD3, 0x7E0E, 0xEAD4, 0x7E1C, 0xEAD5, 0x7E15, 0xEAD6, 0x7E1A,
+	0xEAD7, 0x7E22, 0xEAD8, 0x7E0B, 0xEAD9, 0x7E0F, 0xEADA, 0x7E16,
+	0xEADB, 0x7E0D, 0xEADC, 0x7E14, 0xEADD, 0x7E25, 0xEADE, 0x7E24,
+	0xEADF, 0x7F43, 0xEAE0, 0x7F7B, 0xEAE1, 0x7F7C, 0xEAE2, 0x7F7A,
+	0xEAE3, 0x7FB1, 0xEAE4, 0x7FEF, 0xEAE5, 0x802A, 0xEAE6, 0x8029,
+	0xEAE7, 0x806C, 0xEAE8, 0x81B1, 0xEAE9, 0x81A6, 0xEAEA, 0x81AE,
+	0xEAEB, 0x81B9, 0xEAEC, 0x81B5, 0xEAED, 0x81AB, 0xEAEE, 0x81B0,
+	0xEAEF, 0x81AC, 0xEAF0, 0x81B4, 0xEAF1, 0x81B2, 0xEAF2, 0x81B7,
+	0xEAF3, 0x81A7, 0xEAF4, 0x81F2, 0xEAF5, 0x8255, 0xEAF6, 0x8256,
+	0xEAF7, 0x8257, 0xEAF8, 0x8556, 0xEAF9, 0x8545, 0xEAFA, 0x856B,
+	0xEAFB, 0x854D, 0xEAFC, 0x8553, 0xEAFD, 0x8561, 0xEAFE, 0x8558,
+	0xEB40, 0x8540, 0xEB41, 0x8546, 0xEB42, 0x8564, 0xEB43, 0x8541,
+	0xEB44, 0x8562, 0xEB45, 0x8544, 0xEB46, 0x8551, 0xEB47, 0x8547,
+	0xEB48, 0x8563, 0xEB49, 0x853E, 0xEB4A, 0x855B, 0xEB4B, 0x8571,
+	0xEB4C, 0x854E, 0xEB4D, 0x856E, 0xEB4E, 0x8575, 0xEB4F, 0x8555,
+	0xEB50, 0x8567, 0xEB51, 0x8560, 0xEB52, 0x858C, 0xEB53, 0x8566,
+	0xEB54, 0x855D, 0xEB55, 0x8554, 0xEB56, 0x8565, 0xEB57, 0x856C,
+	0xEB58, 0x8663, 0xEB59, 0x8665, 0xEB5A, 0x8664, 0xEB5B, 0x879B,
+	0xEB5C, 0x878F, 0xEB5D, 0x8797, 0xEB5E, 0x8793, 0xEB5F, 0x8792,
+	0xEB60, 0x8788, 0xEB61, 0x8781, 0xEB62, 0x8796, 0xEB63, 0x8798,
+	0xEB64, 0x8779, 0xEB65, 0x8787, 0xEB66, 0x87A3, 0xEB67, 0x8785,
+	0xEB68, 0x8790, 0xEB69, 0x8791, 0xEB6A, 0x879D, 0xEB6B, 0x8784,
+	0xEB6C, 0x8794, 0xEB6D, 0x879C, 0xEB6E, 0x879A, 0xEB6F, 0x8789,
+	0xEB70, 0x891E, 0xEB71, 0x8926, 0xEB72, 0x8930, 0xEB73, 0x892D,
+	0xEB74, 0x892E, 0xEB75, 0x8927, 0xEB76, 0x8931, 0xEB77, 0x8922,
+	0xEB78, 0x8929, 0xEB79, 0x8923, 0xEB7A, 0x892F, 0xEB7B, 0x892C,
+	0xEB7C, 0x891F, 0xEB7D, 0x89F1, 0xEB7E, 0x8AE0, 0xEBA1, 0x8AE2,
+	0xEBA2, 0x8AF2, 0xEBA3, 0x8AF4, 0xEBA4, 0x8AF5, 0xEBA5, 0x8ADD,
+	0xEBA6, 0x8B14, 0xEBA7, 0x8AE4, 0xEBA8, 0x8ADF, 0xEBA9, 0x8AF0,
+	0xEBAA, 0x8AC8, 0xEBAB, 0x8ADE, 0xEBAC, 0x8AE1, 0xEBAD, 0x8AE8,
+	0xEBAE, 0x8AFF, 0xEBAF, 0x8AEF, 0xEBB0, 0x8AFB, 0xEBB1, 0x8C91,
+	0xEBB2, 0x8C92, 0xEBB3, 0x8C90, 0xEBB4, 0x8CF5, 0xEBB5, 0x8CEE,
+	0xEBB6, 0x8CF1, 0xEBB7, 0x8CF0, 0xEBB8, 0x8CF3, 0xEBB9, 0x8D6C,
+	0xEBBA, 0x8D6E, 0xEBBB, 0x8DA5, 0xEBBC, 0x8DA7, 0xEBBD, 0x8E33,
+	0xEBBE, 0x8E3E, 0xEBBF, 0x8E38, 0xEBC0, 0x8E40, 0xEBC1, 0x8E45,
+	0xEBC2, 0x8E36, 0xEBC3, 0x8E3C, 0xEBC4, 0x8E3D, 0xEBC5, 0x8E41,
+	0xEBC6, 0x8E30, 0xEBC7, 0x8E3F, 0xEBC8, 0x8EBD, 0xEBC9, 0x8F36,
+	0xEBCA, 0x8F2E, 0xEBCB, 0x8F35, 0xEBCC, 0x8F32, 0xEBCD, 0x8F39,
+	0xEBCE, 0x8F37, 0xEBCF, 0x8F34, 0xEBD0, 0x9076, 0xEBD1, 0x9079,
+	0xEBD2, 0x907B, 0xEBD3, 0x9086, 0xEBD4, 0x90FA, 0xEBD5, 0x9133,
+	0xEBD6, 0x9135, 0xEBD7, 0x9136, 0xEBD8, 0x9193, 0xEBD9, 0x9190,
+	0xEBDA, 0x9191, 0xEBDB, 0x918D, 0xEBDC, 0x918F, 0xEBDD, 0x9327,
+	0xEBDE, 0x931E, 0xEBDF, 0x9308, 0xEBE0, 0x931F, 0xEBE1, 0x9306,
+	0xEBE2, 0x930F, 0xEBE3, 0x937A, 0xEBE4, 0x9338, 0xEBE5, 0x933C,
+	0xEBE6, 0x931B, 0xEBE7, 0x9323, 0xEBE8, 0x9312, 0xEBE9, 0x9301,
+	0xEBEA, 0x9346, 0xEBEB, 0x932D, 0xEBEC, 0x930E, 0xEBED, 0x930D,
+	0xEBEE, 0x92CB, 0xEBEF, 0x931D, 0xEBF0, 0x92FA, 0xEBF1, 0x9325,
+	0xEBF2, 0x9313, 0xEBF3, 0x92F9, 0xEBF4, 0x92F7, 0xEBF5, 0x9334,
+	0xEBF6, 0x9302, 0xEBF7, 0x9324, 0xEBF8, 0x92FF, 0xEBF9, 0x9329,
+	0xEBFA, 0x9339, 0xEBFB, 0x9335, 0xEBFC, 0x932A, 0xEBFD, 0x9314,
+	0xEBFE, 0x930C, 0xEC40, 0x930B, 0xEC41, 0x92FE, 0xEC42, 0x9309,
+	0xEC43, 0x9300, 0xEC44, 0x92FB, 0xEC45, 0x9316, 0xEC46, 0x95BC,
+	0xEC47, 0x95CD, 0xEC48, 0x95BE, 0xEC49, 0x95B9, 0xEC4A, 0x95BA,
+	0xEC4B, 0x95B6, 0xEC4C, 0x95BF, 0xEC4D, 0x95B5, 0xEC4E, 0x95BD,
+	0xEC4F, 0x96A9, 0xEC50, 0x96D4, 0xEC51, 0x970B, 0xEC52, 0x9712,
+	0xEC53, 0x9710, 0xEC54, 0x9799, 0xEC55, 0x9797, 0xEC56, 0x9794,
+	0xEC57, 0x97F0, 0xEC58, 0x97F8, 0xEC59, 0x9835, 0xEC5A, 0x982F,
+	0xEC5B, 0x9832, 0xEC5C, 0x9924, 0xEC5D, 0x991F, 0xEC5E, 0x9927,
+	0xEC5F, 0x9929, 0xEC60, 0x999E, 0xEC61, 0x99EE, 0xEC62, 0x99EC,
+	0xEC63, 0x99E5, 0xEC64, 0x99E4, 0xEC65, 0x99F0, 0xEC66, 0x99E3,
+	0xEC67, 0x99EA, 0xEC68, 0x99E9, 0xEC69, 0x99E7, 0xEC6A, 0x9AB9,
+	0xEC6B, 0x9ABF, 0xEC6C, 0x9AB4, 0xEC6D, 0x9ABB, 0xEC6E, 0x9AF6,
+	0xEC6F, 0x9AFA, 0xEC70, 0x9AF9, 0xEC71, 0x9AF7, 0xEC72, 0x9B33,
+	0xEC73, 0x9B80, 0xEC74, 0x9B85, 0xEC75, 0x9B87, 0xEC76, 0x9B7C,
+	0xEC77, 0x9B7E, 0xEC78, 0x9B7B, 0xEC79, 0x9B82, 0xEC7A, 0x9B93,
+	0xEC7B, 0x9B92, 0xEC7C, 0x9B90, 0xEC7D, 0x9B7A, 0xEC7E, 0x9B95,
+	0xECA1, 0x9B7D, 0xECA2, 0x9B88, 0xECA3, 0x9D25, 0xECA4, 0x9D17,
+	0xECA5, 0x9D20, 0xECA6, 0x9D1E, 0xECA7, 0x9D14, 0xECA8, 0x9D29,
+	0xECA9, 0x9D1D, 0xECAA, 0x9D18, 0xECAB, 0x9D22, 0xECAC, 0x9D10,
+	0xECAD, 0x9D19, 0xECAE, 0x9D1F, 0xECAF, 0x9E88, 0xECB0, 0x9E86,
+	0xECB1, 0x9E87, 0xECB2, 0x9EAE, 0xECB3, 0x9EAD, 0xECB4, 0x9ED5,
+	0xECB5, 0x9ED6, 0xECB6, 0x9EFA, 0xECB7, 0x9F12, 0xECB8, 0x9F3D,
+	0xECB9, 0x5126, 0xECBA, 0x5125, 0xECBB, 0x5122, 0xECBC, 0x5124,
+	0xECBD, 0x5120, 0xECBE, 0x5129, 0xECBF, 0x52F4, 0xECC0, 0x5693,
+	0xECC1, 0x568C, 0xECC2, 0x568D, 0xECC3, 0x5686, 0xECC4, 0x5684,
+	0xECC5, 0x5683, 0xECC6, 0x567E, 0xECC7, 0x5682, 0xECC8, 0x567F,
+	0xECC9, 0x5681, 0xECCA, 0x58D6, 0xECCB, 0x58D4, 0xECCC, 0x58CF,
+	0xECCD, 0x58D2, 0xECCE, 0x5B2D, 0xECCF, 0x5B25, 0xECD0, 0x5B32,
+	0xECD1, 0x5B23, 0xECD2, 0x5B2C, 0xECD3, 0x5B27, 0xECD4, 0x5B26,
+	0xECD5, 0x5B2F, 0xECD6, 0x5B2E, 0xECD7, 0x5B7B, 0xECD8, 0x5BF1,
+	0xECD9, 0x5BF2, 0xECDA, 0x5DB7, 0xECDB, 0x5E6C, 0xECDC, 0x5E6A,
+	0xECDD, 0x5FBE, 0xECDE, 0x5FBB, 0xECDF, 0x61C3, 0xECE0, 0x61B5,
+	0xECE1, 0x61BC, 0xECE2, 0x61E7, 0xECE3, 0x61E0, 0xECE4, 0x61E5,
+	0xECE5, 0x61E4, 0xECE6, 0x61E8, 0xECE7, 0x61DE, 0xECE8, 0x64EF,
+	0xECE9, 0x64E9, 0xECEA, 0x64E3, 0xECEB, 0x64EB, 0xECEC, 0x64E4,
+	0xECED, 0x64E8, 0xECEE, 0x6581, 0xECEF, 0x6580, 0xECF0, 0x65B6,
+	0xECF1, 0x65DA, 0xECF2, 0x66D2, 0xECF3, 0x6A8D, 0xECF4, 0x6A96,
+	0xECF5, 0x6A81, 0xECF6, 0x6AA5, 0xECF7, 0x6A89, 0xECF8, 0x6A9F,
+	0xECF9, 0x6A9B, 0xECFA, 0x6AA1, 0xECFB, 0x6A9E, 0xECFC, 0x6A87,
+	0xECFD, 0x6A93, 0xECFE, 0x6A8E, 0xED40, 0x6A95, 0xED41, 0x6A83,
+	0xED42, 0x6AA8, 0xED43, 0x6AA4, 0xED44, 0x6A91, 0xED45, 0x6A7F,
+	0xED46, 0x6AA6, 0xED47, 0x6A9A, 0xED48, 0x6A85, 0xED49, 0x6A8C,
+	0xED4A, 0x6A92, 0xED4B, 0x6B5B, 0xED4C, 0x6BAD, 0xED4D, 0x6C09,
+	0xED4E, 0x6FCC, 0xED4F, 0x6FA9, 0xED50, 0x6FF4, 0xED51, 0x6FD4,
+	0xED52, 0x6FE3, 0xED53, 0x6FDC, 0xED54, 0x6FED, 0xED55, 0x6FE7,
+	0xED56, 0x6FE6, 0xED57, 0x6FDE, 0xED58, 0x6FF2, 0xED59, 0x6FDD,
+	0xED5A, 0x6FE2, 0xED5B, 0x6FE8, 0xED5C, 0x71E1, 0xED5D, 0x71F1,
+	0xED5E, 0x71E8, 0xED5F, 0x71F2, 0xED60, 0x71E4, 0xED61, 0x71F0,
+	0xED62, 0x71E2, 0xED63, 0x7373, 0xED64, 0x736E, 0xED65, 0x736F,
+	0xED66, 0x7497, 0xED67, 0x74B2, 0xED68, 0x74AB, 0xED69, 0x7490,
+	0xED6A, 0x74AA, 0xED6B, 0x74AD, 0xED6C, 0x74B1, 0xED6D, 0x74A5,
+	0xED6E, 0x74AF, 0xED6F, 0x7510, 0xED70, 0x7511, 0xED71, 0x7512,
+	0xED72, 0x750F, 0xED73, 0x7584, 0xED74, 0x7643, 0xED75, 0x7648,
+	0xED76, 0x7649, 0xED77, 0x7647, 0xED78, 0x76A4, 0xED79, 0x76E9,
+	0xED7A, 0x77B5, 0xED7B, 0x77AB, 0xED7C, 0x77B2, 0xED7D, 0x77B7,
+	0xED7E, 0x77B6, 0xEDA1, 0x77B4, 0xEDA2, 0x77B1, 0xEDA3, 0x77A8,
+	0xEDA4, 0x77F0, 0xEDA5, 0x78F3, 0xEDA6, 0x78FD, 0xEDA7, 0x7902,
+	0xEDA8, 0x78FB, 0xEDA9, 0x78FC, 0xEDAA, 0x78F2, 0xEDAB, 0x7905,
+	0xEDAC, 0x78F9, 0xEDAD, 0x78FE, 0xEDAE, 0x7904, 0xEDAF, 0x79AB,
+	0xEDB0, 0x79A8, 0xEDB1, 0x7A5C, 0xEDB2, 0x7A5B, 0xEDB3, 0x7A56,
+	0xEDB4, 0x7A58, 0xEDB5, 0x7A54, 0xEDB6, 0x7A5A, 0xEDB7, 0x7ABE,
+	0xEDB8, 0x7AC0, 0xEDB9, 0x7AC1, 0xEDBA, 0x7C05, 0xEDBB, 0x7C0F,
+	0xEDBC, 0x7BF2, 0xEDBD, 0x7C00, 0xEDBE, 0x7BFF, 0xEDBF, 0x7BFB,
+	0xEDC0, 0x7C0E, 0xEDC1, 0x7BF4, 0xEDC2, 0x7C0B, 0xEDC3, 0x7BF3,
+	0xEDC4, 0x7C02, 0xEDC5, 0x7C09, 0xEDC6, 0x7C03, 0xEDC7, 0x7C01,
+	0xEDC8, 0x7BF8, 0xEDC9, 0x7BFD, 0xEDCA, 0x7C06, 0xEDCB, 0x7BF0,
+	0xEDCC, 0x7BF1, 0xEDCD, 0x7C10, 0xEDCE, 0x7C0A, 0xEDCF, 0x7CE8,
+	0xEDD0, 0x7E2D, 0xEDD1, 0x7E3C, 0xEDD2, 0x7E42, 0xEDD3, 0x7E33,
+	0xEDD4, 0x9848, 0xEDD5, 0x7E38, 0xEDD6, 0x7E2A, 0xEDD7, 0x7E49,
+	0xEDD8, 0x7E40, 0xEDD9, 0x7E47, 0xEDDA, 0x7E29, 0xEDDB, 0x7E4C,
+	0xEDDC, 0x7E30, 0xEDDD, 0x7E3B, 0xEDDE, 0x7E36, 0xEDDF, 0x7E44,
+	0xEDE0, 0x7E3A, 0xEDE1, 0x7F45, 0xEDE2, 0x7F7F, 0xEDE3, 0x7F7E,
+	0xEDE4, 0x7F7D, 0xEDE5, 0x7FF4, 0xEDE6, 0x7FF2, 0xEDE7, 0x802C,
+	0xEDE8, 0x81BB, 0xEDE9, 0x81C4, 0xEDEA, 0x81CC, 0xEDEB, 0x81CA,
+	0xEDEC, 0x81C5, 0xEDED, 0x81C7, 0xEDEE, 0x81BC, 0xEDEF, 0x81E9,
+	0xEDF0, 0x825B, 0xEDF1, 0x825A, 0xEDF2, 0x825C, 0xEDF3, 0x8583,
+	0xEDF4, 0x8580, 0xEDF5, 0x858F, 0xEDF6, 0x85A7, 0xEDF7, 0x8595,
+	0xEDF8, 0x85A0, 0xEDF9, 0x858B, 0xEDFA, 0x85A3, 0xEDFB, 0x857B,
+	0xEDFC, 0x85A4, 0xEDFD, 0x859A, 0xEDFE, 0x859E, 0xEE40, 0x8577,
+	0xEE41, 0x857C, 0xEE42, 0x8589, 0xEE43, 0x85A1, 0xEE44, 0x857A,
+	0xEE45, 0x8578, 0xEE46, 0x8557, 0xEE47, 0x858E, 0xEE48, 0x8596,
+	0xEE49, 0x8586, 0xEE4A, 0x858D, 0xEE4B, 0x8599, 0xEE4C, 0x859D,
+	0xEE4D, 0x8581, 0xEE4E, 0x85A2, 0xEE4F, 0x8582, 0xEE50, 0x8588,
+	0xEE51, 0x8585, 0xEE52, 0x8579, 0xEE53, 0x8576, 0xEE54, 0x8598,
+	0xEE55, 0x8590, 0xEE56, 0x859F, 0xEE57, 0x8668, 0xEE58, 0x87BE,
+	0xEE59, 0x87AA, 0xEE5A, 0x87AD, 0xEE5B, 0x87C5, 0xEE5C, 0x87B0,
+	0xEE5D, 0x87AC, 0xEE5E, 0x87B9, 0xEE5F, 0x87B5, 0xEE60, 0x87BC,
+	0xEE61, 0x87AE, 0xEE62, 0x87C9, 0xEE63, 0x87C3, 0xEE64, 0x87C2,
+	0xEE65, 0x87CC, 0xEE66, 0x87B7, 0xEE67, 0x87AF, 0xEE68, 0x87C4,
+	0xEE69, 0x87CA, 0xEE6A, 0x87B4, 0xEE6B, 0x87B6, 0xEE6C, 0x87BF,
+	0xEE6D, 0x87B8, 0xEE6E, 0x87BD, 0xEE6F, 0x87DE, 0xEE70, 0x87B2,
+	0xEE71, 0x8935, 0xEE72, 0x8933, 0xEE73, 0x893C, 0xEE74, 0x893E,
+	0xEE75, 0x8941, 0xEE76, 0x8952, 0xEE77, 0x8937, 0xEE78, 0x8942,
+	0xEE79, 0x89AD, 0xEE7A, 0x89AF, 0xEE7B, 0x89AE, 0xEE7C, 0x89F2,
+	0xEE7D, 0x89F3, 0xEE7E, 0x8B1E, 0xEEA1, 0x8B18, 0xEEA2, 0x8B16,
+	0xEEA3, 0x8B11, 0xEEA4, 0x8B05, 0xEEA5, 0x8B0B, 0xEEA6, 0x8B22,
+	0xEEA7, 0x8B0F, 0xEEA8, 0x8B12, 0xEEA9, 0x8B15, 0xEEAA, 0x8B07,
+	0xEEAB, 0x8B0D, 0xEEAC, 0x8B08, 0xEEAD, 0x8B06, 0xEEAE, 0x8B1C,
+	0xEEAF, 0x8B13, 0xEEB0, 0x8B1A, 0xEEB1, 0x8C4F, 0xEEB2, 0x8C70,
+	0xEEB3, 0x8C72, 0xEEB4, 0x8C71, 0xEEB5, 0x8C6F, 0xEEB6, 0x8C95,
+	0xEEB7, 0x8C94, 0xEEB8, 0x8CF9, 0xEEB9, 0x8D6F, 0xEEBA, 0x8E4E,
+	0xEEBB, 0x8E4D, 0xEEBC, 0x8E53, 0xEEBD, 0x8E50, 0xEEBE, 0x8E4C,
+	0xEEBF, 0x8E47, 0xEEC0, 0x8F43, 0xEEC1, 0x8F40, 0xEEC2, 0x9085,
+	0xEEC3, 0x907E, 0xEEC4, 0x9138, 0xEEC5, 0x919A, 0xEEC6, 0x91A2,
+	0xEEC7, 0x919B, 0xEEC8, 0x9199, 0xEEC9, 0x919F, 0xEECA, 0x91A1,
+	0xEECB, 0x919D, 0xEECC, 0x91A0, 0xEECD, 0x93A1, 0xEECE, 0x9383,
+	0xEECF, 0x93AF, 0xEED0, 0x9364, 0xEED1, 0x9356, 0xEED2, 0x9347,
+	0xEED3, 0x937C, 0xEED4, 0x9358, 0xEED5, 0x935C, 0xEED6, 0x9376,
+	0xEED7, 0x9349, 0xEED8, 0x9350, 0xEED9, 0x9351, 0xEEDA, 0x9360,
+	0xEEDB, 0x936D, 0xEEDC, 0x938F, 0xEEDD, 0x934C, 0xEEDE, 0x936A,
+	0xEEDF, 0x9379, 0xEEE0, 0x9357, 0xEEE1, 0x9355, 0xEEE2, 0x9352,
+	0xEEE3, 0x934F, 0xEEE4, 0x9371, 0xEEE5, 0x9377, 0xEEE6, 0x937B,
+	0xEEE7, 0x9361, 0xEEE8, 0x935E, 0xEEE9, 0x9363, 0xEEEA, 0x9367,
+	0xEEEB, 0x9380, 0xEEEC, 0x934E, 0xEEED, 0x9359, 0xEEEE, 0x95C7,
+	0xEEEF, 0x95C0, 0xEEF0, 0x95C9, 0xEEF1, 0x95C3, 0xEEF2, 0x95C5,
+	0xEEF3, 0x95B7, 0xEEF4, 0x96AE, 0xEEF5, 0x96B0, 0xEEF6, 0x96AC,
+	0xEEF7, 0x9720, 0xEEF8, 0x971F, 0xEEF9, 0x9718, 0xEEFA, 0x971D,
+	0xEEFB, 0x9719, 0xEEFC, 0x979A, 0xEEFD, 0x97A1, 0xEEFE, 0x979C,
+	0xEF40, 0x979E, 0xEF41, 0x979D, 0xEF42, 0x97D5, 0xEF43, 0x97D4,
+	0xEF44, 0x97F1, 0xEF45, 0x9841, 0xEF46, 0x9844, 0xEF47, 0x984A,
+	0xEF48, 0x9849, 0xEF49, 0x9845, 0xEF4A, 0x9843, 0xEF4B, 0x9925,
+	0xEF4C, 0x992B, 0xEF4D, 0x992C, 0xEF4E, 0x992A, 0xEF4F, 0x9933,
+	0xEF50, 0x9932, 0xEF51, 0x992F, 0xEF52, 0x992D, 0xEF53, 0x9931,
+	0xEF54, 0x9930, 0xEF55, 0x9998, 0xEF56, 0x99A3, 0xEF57, 0x99A1,
+	0xEF58, 0x9A02, 0xEF59, 0x99FA, 0xEF5A, 0x99F4, 0xEF5B, 0x99F7,
+	0xEF5C, 0x99F9, 0xEF5D, 0x99F8, 0xEF5E, 0x99F6, 0xEF5F, 0x99FB,
+	0xEF60, 0x99FD, 0xEF61, 0x99FE, 0xEF62, 0x99FC, 0xEF63, 0x9A03,
+	0xEF64, 0x9ABE, 0xEF65, 0x9AFE, 0xEF66, 0x9AFD, 0xEF67, 0x9B01,
+	0xEF68, 0x9AFC, 0xEF69, 0x9B48, 0xEF6A, 0x9B9A, 0xEF6B, 0x9BA8,
+	0xEF6C, 0x9B9E, 0xEF6D, 0x9B9B, 0xEF6E, 0x9BA6, 0xEF6F, 0x9BA1,
+	0xEF70, 0x9BA5, 0xEF71, 0x9BA4, 0xEF72, 0x9B86, 0xEF73, 0x9BA2,
+	0xEF74, 0x9BA0, 0xEF75, 0x9BAF, 0xEF76, 0x9D33, 0xEF77, 0x9D41,
+	0xEF78, 0x9D67, 0xEF79, 0x9D36, 0xEF7A, 0x9D2E, 0xEF7B, 0x9D2F,
+	0xEF7C, 0x9D31, 0xEF7D, 0x9D38, 0xEF7E, 0x9D30, 0xEFA1, 0x9D45,
+	0xEFA2, 0x9D42, 0xEFA3, 0x9D43, 0xEFA4, 0x9D3E, 0xEFA5, 0x9D37,
+	0xEFA6, 0x9D40, 0xEFA7, 0x9D3D, 0xEFA8, 0x7FF5, 0xEFA9, 0x9D2D,
+	0xEFAA, 0x9E8A, 0xEFAB, 0x9E89, 0xEFAC, 0x9E8D, 0xEFAD, 0x9EB0,
+	0xEFAE, 0x9EC8, 0xEFAF, 0x9EDA, 0xEFB0, 0x9EFB, 0xEFB1, 0x9EFF,
+	0xEFB2, 0x9F24, 0xEFB3, 0x9F23, 0xEFB4, 0x9F22, 0xEFB5, 0x9F54,
+	0xEFB6, 0x9FA0, 0xEFB7, 0x5131, 0xEFB8, 0x512D, 0xEFB9, 0x512E,
+	0xEFBA, 0x5698, 0xEFBB, 0x569C, 0xEFBC, 0x5697, 0xEFBD, 0x569A,
+	0xEFBE, 0x569D, 0xEFBF, 0x5699, 0xEFC0, 0x5970, 0xEFC1, 0x5B3C,
+	0xEFC2, 0x5C69, 0xEFC3, 0x5C6A, 0xEFC4, 0x5DC0, 0xEFC5, 0x5E6D,
+	0xEFC6, 0x5E6E, 0xEFC7, 0x61D8, 0xEFC8, 0x61DF, 0xEFC9, 0x61ED,
+	0xEFCA, 0x61EE, 0xEFCB, 0x61F1, 0xEFCC, 0x61EA, 0xEFCD, 0x61F0,
+	0xEFCE, 0x61EB, 0xEFCF, 0x61D6, 0xEFD0, 0x61E9, 0xEFD1, 0x64FF,
+	0xEFD2, 0x6504, 0xEFD3, 0x64FD, 0xEFD4, 0x64F8, 0xEFD5, 0x6501,
+	0xEFD6, 0x6503, 0xEFD7, 0x64FC, 0xEFD8, 0x6594, 0xEFD9, 0x65DB,
+	0xEFDA, 0x66DA, 0xEFDB, 0x66DB, 0xEFDC, 0x66D8, 0xEFDD, 0x6AC5,
+	0xEFDE, 0x6AB9, 0xEFDF, 0x6ABD, 0xEFE0, 0x6AE1, 0xEFE1, 0x6AC6,
+	0xEFE2, 0x6ABA, 0xEFE3, 0x6AB6, 0xEFE4, 0x6AB7, 0xEFE5, 0x6AC7,
+	0xEFE6, 0x6AB4, 0xEFE7, 0x6AAD, 0xEFE8, 0x6B5E, 0xEFE9, 0x6BC9,
+	0xEFEA, 0x6C0B, 0xEFEB, 0x7007, 0xEFEC, 0x700C, 0xEFED, 0x700D,
+	0xEFEE, 0x7001, 0xEFEF, 0x7005, 0xEFF0, 0x7014, 0xEFF1, 0x700E,
+	0xEFF2, 0x6FFF, 0xEFF3, 0x7000, 0xEFF4, 0x6FFB, 0xEFF5, 0x7026,
+	0xEFF6, 0x6FFC, 0xEFF7, 0x6FF7, 0xEFF8, 0x700A, 0xEFF9, 0x7201,
+	0xEFFA, 0x71FF, 0xEFFB, 0x71F9, 0xEFFC, 0x7203, 0xEFFD, 0x71FD,
+	0xEFFE, 0x7376, 0xF040, 0x74B8, 0xF041, 0x74C0, 0xF042, 0x74B5,
+	0xF043, 0x74C1, 0xF044, 0x74BE, 0xF045, 0x74B6, 0xF046, 0x74BB,
+	0xF047, 0x74C2, 0xF048, 0x7514, 0xF049, 0x7513, 0xF04A, 0x765C,
+	0xF04B, 0x7664, 0xF04C, 0x7659, 0xF04D, 0x7650, 0xF04E, 0x7653,
+	0xF04F, 0x7657, 0xF050, 0x765A, 0xF051, 0x76A6, 0xF052, 0x76BD,
+	0xF053, 0x76EC, 0xF054, 0x77C2, 0xF055, 0x77BA, 0xF056, 0x78FF,
+	0xF057, 0x790C, 0xF058, 0x7913, 0xF059, 0x7914, 0xF05A, 0x7909,
+	0xF05B, 0x7910, 0xF05C, 0x7912, 0xF05D, 0x7911, 0xF05E, 0x79AD,
+	0xF05F, 0x79AC, 0xF060, 0x7A5F, 0xF061, 0x7C1C, 0xF062, 0x7C29,
+	0xF063, 0x7C19, 0xF064, 0x7C20, 0xF065, 0x7C1F, 0xF066, 0x7C2D,
+	0xF067, 0x7C1D, 0xF068, 0x7C26, 0xF069, 0x7C28, 0xF06A, 0x7C22,
+	0xF06B, 0x7C25, 0xF06C, 0x7C30, 0xF06D, 0x7E5C, 0xF06E, 0x7E50,
+	0xF06F, 0x7E56, 0xF070, 0x7E63, 0xF071, 0x7E58, 0xF072, 0x7E62,
+	0xF073, 0x7E5F, 0xF074, 0x7E51, 0xF075, 0x7E60, 0xF076, 0x7E57,
+	0xF077, 0x7E53, 0xF078, 0x7FB5, 0xF079, 0x7FB3, 0xF07A, 0x7FF7,
+	0xF07B, 0x7FF8, 0xF07C, 0x8075, 0xF07D, 0x81D1, 0xF07E, 0x81D2,
+	0xF0A1, 0x81D0, 0xF0A2, 0x825F, 0xF0A3, 0x825E, 0xF0A4, 0x85B4,
+	0xF0A5, 0x85C6, 0xF0A6, 0x85C0, 0xF0A7, 0x85C3, 0xF0A8, 0x85C2,
+	0xF0A9, 0x85B3, 0xF0AA, 0x85B5, 0xF0AB, 0x85BD, 0xF0AC, 0x85C7,
+	0xF0AD, 0x85C4, 0xF0AE, 0x85BF, 0xF0AF, 0x85CB, 0xF0B0, 0x85CE,
+	0xF0B1, 0x85C8, 0xF0B2, 0x85C5, 0xF0B3, 0x85B1, 0xF0B4, 0x85B6,
+	0xF0B5, 0x85D2, 0xF0B6, 0x8624, 0xF0B7, 0x85B8, 0xF0B8, 0x85B7,
+	0xF0B9, 0x85BE, 0xF0BA, 0x8669, 0xF0BB, 0x87E7, 0xF0BC, 0x87E6,
+	0xF0BD, 0x87E2, 0xF0BE, 0x87DB, 0xF0BF, 0x87EB, 0xF0C0, 0x87EA,
+	0xF0C1, 0x87E5, 0xF0C2, 0x87DF, 0xF0C3, 0x87F3, 0xF0C4, 0x87E4,
+	0xF0C5, 0x87D4, 0xF0C6, 0x87DC, 0xF0C7, 0x87D3, 0xF0C8, 0x87ED,
+	0xF0C9, 0x87D8, 0xF0CA, 0x87E3, 0xF0CB, 0x87A4, 0xF0CC, 0x87D7,
+	0xF0CD, 0x87D9, 0xF0CE, 0x8801, 0xF0CF, 0x87F4, 0xF0D0, 0x87E8,
+	0xF0D1, 0x87DD, 0xF0D2, 0x8953, 0xF0D3, 0x894B, 0xF0D4, 0x894F,
+	0xF0D5, 0x894C, 0xF0D6, 0x8946, 0xF0D7, 0x8950, 0xF0D8, 0x8951,
+	0xF0D9, 0x8949, 0xF0DA, 0x8B2A, 0xF0DB, 0x8B27, 0xF0DC, 0x8B23,
+	0xF0DD, 0x8B33, 0xF0DE, 0x8B30, 0xF0DF, 0x8B35, 0xF0E0, 0x8B47,
+	0xF0E1, 0x8B2F, 0xF0E2, 0x8B3C, 0xF0E3, 0x8B3E, 0xF0E4, 0x8B31,
+	0xF0E5, 0x8B25, 0xF0E6, 0x8B37, 0xF0E7, 0x8B26, 0xF0E8, 0x8B36,
+	0xF0E9, 0x8B2E, 0xF0EA, 0x8B24, 0xF0EB, 0x8B3B, 0xF0EC, 0x8B3D,
+	0xF0ED, 0x8B3A, 0xF0EE, 0x8C42, 0xF0EF, 0x8C75, 0xF0F0, 0x8C99,
+	0xF0F1, 0x8C98, 0xF0F2, 0x8C97, 0xF0F3, 0x8CFE, 0xF0F4, 0x8D04,
+	0xF0F5, 0x8D02, 0xF0F6, 0x8D00, 0xF0F7, 0x8E5C, 0xF0F8, 0x8E62,
+	0xF0F9, 0x8E60, 0xF0FA, 0x8E57, 0xF0FB, 0x8E56, 0xF0FC, 0x8E5E,
+	0xF0FD, 0x8E65, 0xF0FE, 0x8E67, 0xF140, 0x8E5B, 0xF141, 0x8E5A,
+	0xF142, 0x8E61, 0xF143, 0x8E5D, 0xF144, 0x8E69, 0xF145, 0x8E54,
+	0xF146, 0x8F46, 0xF147, 0x8F47, 0xF148, 0x8F48, 0xF149, 0x8F4B,
+	0xF14A, 0x9128, 0xF14B, 0x913A, 0xF14C, 0x913B, 0xF14D, 0x913E,
+	0xF14E, 0x91A8, 0xF14F, 0x91A5, 0xF150, 0x91A7, 0xF151, 0x91AF,
+	0xF152, 0x91AA, 0xF153, 0x93B5, 0xF154, 0x938C, 0xF155, 0x9392,
+	0xF156, 0x93B7, 0xF157, 0x939B, 0xF158, 0x939D, 0xF159, 0x9389,
+	0xF15A, 0x93A7, 0xF15B, 0x938E, 0xF15C, 0x93AA, 0xF15D, 0x939E,
+	0xF15E, 0x93A6, 0xF15F, 0x9395, 0xF160, 0x9388, 0xF161, 0x9399,
+	0xF162, 0x939F, 0xF163, 0x938D, 0xF164, 0x93B1, 0xF165, 0x9391,
+	0xF166, 0x93B2, 0xF167, 0x93A4, 0xF168, 0x93A8, 0xF169, 0x93B4,
+	0xF16A, 0x93A3, 0xF16B, 0x93A5, 0xF16C, 0x95D2, 0xF16D, 0x95D3,
+	0xF16E, 0x95D1, 0xF16F, 0x96B3, 0xF170, 0x96D7, 0xF171, 0x96DA,
+	0xF172, 0x5DC2, 0xF173, 0x96DF, 0xF174, 0x96D8, 0xF175, 0x96DD,
+	0xF176, 0x9723, 0xF177, 0x9722, 0xF178, 0x9725, 0xF179, 0x97AC,
+	0xF17A, 0x97AE, 0xF17B, 0x97A8, 0xF17C, 0x97AB, 0xF17D, 0x97A4,
+	0xF17E, 0x97AA, 0xF1A1, 0x97A2, 0xF1A2, 0x97A5, 0xF1A3, 0x97D7,
+	0xF1A4, 0x97D9, 0xF1A5, 0x97D6, 0xF1A6, 0x97D8, 0xF1A7, 0x97FA,
+	0xF1A8, 0x9850, 0xF1A9, 0x9851, 0xF1AA, 0x9852, 0xF1AB, 0x98B8,
+	0xF1AC, 0x9941, 0xF1AD, 0x993C, 0xF1AE, 0x993A, 0xF1AF, 0x9A0F,
+	0xF1B0, 0x9A0B, 0xF1B1, 0x9A09, 0xF1B2, 0x9A0D, 0xF1B3, 0x9A04,
+	0xF1B4, 0x9A11, 0xF1B5, 0x9A0A, 0xF1B6, 0x9A05, 0xF1B7, 0x9A07,
+	0xF1B8, 0x9A06, 0xF1B9, 0x9AC0, 0xF1BA, 0x9ADC, 0xF1BB, 0x9B08,
+	0xF1BC, 0x9B04, 0xF1BD, 0x9B05, 0xF1BE, 0x9B29, 0xF1BF, 0x9B35,
+	0xF1C0, 0x9B4A, 0xF1C1, 0x9B4C, 0xF1C2, 0x9B4B, 0xF1C3, 0x9BC7,
+	0xF1C4, 0x9BC6, 0xF1C5, 0x9BC3, 0xF1C6, 0x9BBF, 0xF1C7, 0x9BC1,
+	0xF1C8, 0x9BB5, 0xF1C9, 0x9BB8, 0xF1CA, 0x9BD3, 0xF1CB, 0x9BB6,
+	0xF1CC, 0x9BC4, 0xF1CD, 0x9BB9, 0xF1CE, 0x9BBD, 0xF1CF, 0x9D5C,
+	0xF1D0, 0x9D53, 0xF1D1, 0x9D4F, 0xF1D2, 0x9D4A, 0xF1D3, 0x9D5B,
+	0xF1D4, 0x9D4B, 0xF1D5, 0x9D59, 0xF1D6, 0x9D56, 0xF1D7, 0x9D4C,
+	0xF1D8, 0x9D57, 0xF1D9, 0x9D52, 0xF1DA, 0x9D54, 0xF1DB, 0x9D5F,
+	0xF1DC, 0x9D58, 0xF1DD, 0x9D5A, 0xF1DE, 0x9E8E, 0xF1DF, 0x9E8C,
+	0xF1E0, 0x9EDF, 0xF1E1, 0x9F01, 0xF1E2, 0x9F00, 0xF1E3, 0x9F16,
+	0xF1E4, 0x9F25, 0xF1E5, 0x9F2B, 0xF1E6, 0x9F2A, 0xF1E7, 0x9F29,
+	0xF1E8, 0x9F28, 0xF1E9, 0x9F4C, 0xF1EA, 0x9F55, 0xF1EB, 0x5134,
+	0xF1EC, 0x5135, 0xF1ED, 0x5296, 0xF1EE, 0x52F7, 0xF1EF, 0x53B4,
+	0xF1F0, 0x56AB, 0xF1F1, 0x56AD, 0xF1F2, 0x56A6, 0xF1F3, 0x56A7,
+	0xF1F4, 0x56AA, 0xF1F5, 0x56AC, 0xF1F6, 0x58DA, 0xF1F7, 0x58DD,
+	0xF1F8, 0x58DB, 0xF1F9, 0x5912, 0xF1FA, 0x5B3D, 0xF1FB, 0x5B3E,
+	0xF1FC, 0x5B3F, 0xF1FD, 0x5DC3, 0xF1FE, 0x5E70, 0xF240, 0x5FBF,
+	0xF241, 0x61FB, 0xF242, 0x6507, 0xF243, 0x6510, 0xF244, 0x650D,
+	0xF245, 0x6509, 0xF246, 0x650C, 0xF247, 0x650E, 0xF248, 0x6584,
+	0xF249, 0x65DE, 0xF24A, 0x65DD, 0xF24B, 0x66DE, 0xF24C, 0x6AE7,
+	0xF24D, 0x6AE0, 0xF24E, 0x6ACC, 0xF24F, 0x6AD1, 0xF250, 0x6AD9,
+	0xF251, 0x6ACB, 0xF252, 0x6ADF, 0xF253, 0x6ADC, 0xF254, 0x6AD0,
+	0xF255, 0x6AEB, 0xF256, 0x6ACF, 0xF257, 0x6ACD, 0xF258, 0x6ADE,
+	0xF259, 0x6B60, 0xF25A, 0x6BB0, 0xF25B, 0x6C0C, 0xF25C, 0x7019,
+	0xF25D, 0x7027, 0xF25E, 0x7020, 0xF25F, 0x7016, 0xF260, 0x702B,
+	0xF261, 0x7021, 0xF262, 0x7022, 0xF263, 0x7023, 0xF264, 0x7029,
+	0xF265, 0x7017, 0xF266, 0x7024, 0xF267, 0x701C, 0xF268, 0x702A,
+	0xF269, 0x720C, 0xF26A, 0x720A, 0xF26B, 0x7207, 0xF26C, 0x7202,
+	0xF26D, 0x7205, 0xF26E, 0x72A5, 0xF26F, 0x72A6, 0xF270, 0x72A4,
+	0xF271, 0x72A3, 0xF272, 0x72A1, 0xF273, 0x74CB, 0xF274, 0x74C5,
+	0xF275, 0x74B7, 0xF276, 0x74C3, 0xF277, 0x7516, 0xF278, 0x7660,
+	0xF279, 0x77C9, 0xF27A, 0x77CA, 0xF27B, 0x77C4, 0xF27C, 0x77F1,
+	0xF27D, 0x791D, 0xF27E, 0x791B, 0xF2A1, 0x7921, 0xF2A2, 0x791C,
+	0xF2A3, 0x7917, 0xF2A4, 0x791E, 0xF2A5, 0x79B0, 0xF2A6, 0x7A67,
+	0xF2A7, 0x7A68, 0xF2A8, 0x7C33, 0xF2A9, 0x7C3C, 0xF2AA, 0x7C39,
+	0xF2AB, 0x7C2C, 0xF2AC, 0x7C3B, 0xF2AD, 0x7CEC, 0xF2AE, 0x7CEA,
+	0xF2AF, 0x7E76, 0xF2B0, 0x7E75, 0xF2B1, 0x7E78, 0xF2B2, 0x7E70,
+	0xF2B3, 0x7E77, 0xF2B4, 0x7E6F, 0xF2B5, 0x7E7A, 0xF2B6, 0x7E72,
+	0xF2B7, 0x7E74, 0xF2B8, 0x7E68, 0xF2B9, 0x7F4B, 0xF2BA, 0x7F4A,
+	0xF2BB, 0x7F83, 0xF2BC, 0x7F86, 0xF2BD, 0x7FB7, 0xF2BE, 0x7FFD,
+	0xF2BF, 0x7FFE, 0xF2C0, 0x8078, 0xF2C1, 0x81D7, 0xF2C2, 0x81D5,
+	0xF2C3, 0x8264, 0xF2C4, 0x8261, 0xF2C5, 0x8263, 0xF2C6, 0x85EB,
+	0xF2C7, 0x85F1, 0xF2C8, 0x85ED, 0xF2C9, 0x85D9, 0xF2CA, 0x85E1,
+	0xF2CB, 0x85E8, 0xF2CC, 0x85DA, 0xF2CD, 0x85D7, 0xF2CE, 0x85EC,
+	0xF2CF, 0x85F2, 0xF2D0, 0x85F8, 0xF2D1, 0x85D8, 0xF2D2, 0x85DF,
+	0xF2D3, 0x85E3, 0xF2D4, 0x85DC, 0xF2D5, 0x85D1, 0xF2D6, 0x85F0,
+	0xF2D7, 0x85E6, 0xF2D8, 0x85EF, 0xF2D9, 0x85DE, 0xF2DA, 0x85E2,
+	0xF2DB, 0x8800, 0xF2DC, 0x87FA, 0xF2DD, 0x8803, 0xF2DE, 0x87F6,
+	0xF2DF, 0x87F7, 0xF2E0, 0x8809, 0xF2E1, 0x880C, 0xF2E2, 0x880B,
+	0xF2E3, 0x8806, 0xF2E4, 0x87FC, 0xF2E5, 0x8808, 0xF2E6, 0x87FF,
+	0xF2E7, 0x880A, 0xF2E8, 0x8802, 0xF2E9, 0x8962, 0xF2EA, 0x895A,
+	0xF2EB, 0x895B, 0xF2EC, 0x8957, 0xF2ED, 0x8961, 0xF2EE, 0x895C,
+	0xF2EF, 0x8958, 0xF2F0, 0x895D, 0xF2F1, 0x8959, 0xF2F2, 0x8988,
+	0xF2F3, 0x89B7, 0xF2F4, 0x89B6, 0xF2F5, 0x89F6, 0xF2F6, 0x8B50,
+	0xF2F7, 0x8B48, 0xF2F8, 0x8B4A, 0xF2F9, 0x8B40, 0xF2FA, 0x8B53,
+	0xF2FB, 0x8B56, 0xF2FC, 0x8B54, 0xF2FD, 0x8B4B, 0xF2FE, 0x8B55,
+	0xF340, 0x8B51, 0xF341, 0x8B42, 0xF342, 0x8B52, 0xF343, 0x8B57,
+	0xF344, 0x8C43, 0xF345, 0x8C77, 0xF346, 0x8C76, 0xF347, 0x8C9A,
+	0xF348, 0x8D06, 0xF349, 0x8D07, 0xF34A, 0x8D09, 0xF34B, 0x8DAC,
+	0xF34C, 0x8DAA, 0xF34D, 0x8DAD, 0xF34E, 0x8DAB, 0xF34F, 0x8E6D,
+	0xF350, 0x8E78, 0xF351, 0x8E73, 0xF352, 0x8E6A, 0xF353, 0x8E6F,
+	0xF354, 0x8E7B, 0xF355, 0x8EC2, 0xF356, 0x8F52, 0xF357, 0x8F51,
+	0xF358, 0x8F4F, 0xF359, 0x8F50, 0xF35A, 0x8F53, 0xF35B, 0x8FB4,
+	0xF35C, 0x9140, 0xF35D, 0x913F, 0xF35E, 0x91B0, 0xF35F, 0x91AD,
+	0xF360, 0x93DE, 0xF361, 0x93C7, 0xF362, 0x93CF, 0xF363, 0x93C2,
+	0xF364, 0x93DA, 0xF365, 0x93D0, 0xF366, 0x93F9, 0xF367, 0x93EC,
+	0xF368, 0x93CC, 0xF369, 0x93D9, 0xF36A, 0x93A9, 0xF36B, 0x93E6,
+	0xF36C, 0x93CA, 0xF36D, 0x93D4, 0xF36E, 0x93EE, 0xF36F, 0x93E3,
+	0xF370, 0x93D5, 0xF371, 0x93C4, 0xF372, 0x93CE, 0xF373, 0x93C0,
+	0xF374, 0x93D2, 0xF375, 0x93E7, 0xF376, 0x957D, 0xF377, 0x95DA,
+	0xF378, 0x95DB, 0xF379, 0x96E1, 0xF37A, 0x9729, 0xF37B, 0x972B,
+	0xF37C, 0x972C, 0xF37D, 0x9728, 0xF37E, 0x9726, 0xF3A1, 0x97B3,
+	0xF3A2, 0x97B7, 0xF3A3, 0x97B6, 0xF3A4, 0x97DD, 0xF3A5, 0x97DE,
+	0xF3A6, 0x97DF, 0xF3A7, 0x985C, 0xF3A8, 0x9859, 0xF3A9, 0x985D,
+	0xF3AA, 0x9857, 0xF3AB, 0x98BF, 0xF3AC, 0x98BD, 0xF3AD, 0x98BB,
+	0xF3AE, 0x98BE, 0xF3AF, 0x9948, 0xF3B0, 0x9947, 0xF3B1, 0x9943,
+	0xF3B2, 0x99A6, 0xF3B3, 0x99A7, 0xF3B4, 0x9A1A, 0xF3B5, 0x9A15,
+	0xF3B6, 0x9A25, 0xF3B7, 0x9A1D, 0xF3B8, 0x9A24, 0xF3B9, 0x9A1B,
+	0xF3BA, 0x9A22, 0xF3BB, 0x9A20, 0xF3BC, 0x9A27, 0xF3BD, 0x9A23,
+	0xF3BE, 0x9A1E, 0xF3BF, 0x9A1C, 0xF3C0, 0x9A14, 0xF3C1, 0x9AC2,
+	0xF3C2, 0x9B0B, 0xF3C3, 0x9B0A, 0xF3C4, 0x9B0E, 0xF3C5, 0x9B0C,
+	0xF3C6, 0x9B37, 0xF3C7, 0x9BEA, 0xF3C8, 0x9BEB, 0xF3C9, 0x9BE0,
+	0xF3CA, 0x9BDE, 0xF3CB, 0x9BE4, 0xF3CC, 0x9BE6, 0xF3CD, 0x9BE2,
+	0xF3CE, 0x9BF0, 0xF3CF, 0x9BD4, 0xF3D0, 0x9BD7, 0xF3D1, 0x9BEC,
+	0xF3D2, 0x9BDC, 0xF3D3, 0x9BD9, 0xF3D4, 0x9BE5, 0xF3D5, 0x9BD5,
+	0xF3D6, 0x9BE1, 0xF3D7, 0x9BDA, 0xF3D8, 0x9D77, 0xF3D9, 0x9D81,
+	0xF3DA, 0x9D8A, 0xF3DB, 0x9D84, 0xF3DC, 0x9D88, 0xF3DD, 0x9D71,
+	0xF3DE, 0x9D80, 0xF3DF, 0x9D78, 0xF3E0, 0x9D86, 0xF3E1, 0x9D8B,
+	0xF3E2, 0x9D8C, 0xF3E3, 0x9D7D, 0xF3E4, 0x9D6B, 0xF3E5, 0x9D74,
+	0xF3E6, 0x9D75, 0xF3E7, 0x9D70, 0xF3E8, 0x9D69, 0xF3E9, 0x9D85,
+	0xF3EA, 0x9D73, 0xF3EB, 0x9D7B, 0xF3EC, 0x9D82, 0xF3ED, 0x9D6F,
+	0xF3EE, 0x9D79, 0xF3EF, 0x9D7F, 0xF3F0, 0x9D87, 0xF3F1, 0x9D68,
+	0xF3F2, 0x9E94, 0xF3F3, 0x9E91, 0xF3F4, 0x9EC0, 0xF3F5, 0x9EFC,
+	0xF3F6, 0x9F2D, 0xF3F7, 0x9F40, 0xF3F8, 0x9F41, 0xF3F9, 0x9F4D,
+	0xF3FA, 0x9F56, 0xF3FB, 0x9F57, 0xF3FC, 0x9F58, 0xF3FD, 0x5337,
+	0xF3FE, 0x56B2, 0xF440, 0x56B5, 0xF441, 0x56B3, 0xF442, 0x58E3,
+	0xF443, 0x5B45, 0xF444, 0x5DC6, 0xF445, 0x5DC7, 0xF446, 0x5EEE,
+	0xF447, 0x5EEF, 0xF448, 0x5FC0, 0xF449, 0x5FC1, 0xF44A, 0x61F9,
+	0xF44B, 0x6517, 0xF44C, 0x6516, 0xF44D, 0x6515, 0xF44E, 0x6513,
+	0xF44F, 0x65DF, 0xF450, 0x66E8, 0xF451, 0x66E3, 0xF452, 0x66E4,
+	0xF453, 0x6AF3, 0xF454, 0x6AF0, 0xF455, 0x6AEA, 0xF456, 0x6AE8,
+	0xF457, 0x6AF9, 0xF458, 0x6AF1, 0xF459, 0x6AEE, 0xF45A, 0x6AEF,
+	0xF45B, 0x703C, 0xF45C, 0x7035, 0xF45D, 0x702F, 0xF45E, 0x7037,
+	0xF45F, 0x7034, 0xF460, 0x7031, 0xF461, 0x7042, 0xF462, 0x7038,
+	0xF463, 0x703F, 0xF464, 0x703A, 0xF465, 0x7039, 0xF466, 0x7040,
+	0xF467, 0x703B, 0xF468, 0x7033, 0xF469, 0x7041, 0xF46A, 0x7213,
+	0xF46B, 0x7214, 0xF46C, 0x72A8, 0xF46D, 0x737D, 0xF46E, 0x737C,
+	0xF46F, 0x74BA, 0xF470, 0x76AB, 0xF471, 0x76AA, 0xF472, 0x76BE,
+	0xF473, 0x76ED, 0xF474, 0x77CC, 0xF475, 0x77CE, 0xF476, 0x77CF,
+	0xF477, 0x77CD, 0xF478, 0x77F2, 0xF479, 0x7925, 0xF47A, 0x7923,
+	0xF47B, 0x7927, 0xF47C, 0x7928, 0xF47D, 0x7924, 0xF47E, 0x7929,
+	0xF4A1, 0x79B2, 0xF4A2, 0x7A6E, 0xF4A3, 0x7A6C, 0xF4A4, 0x7A6D,
+	0xF4A5, 0x7AF7, 0xF4A6, 0x7C49, 0xF4A7, 0x7C48, 0xF4A8, 0x7C4A,
+	0xF4A9, 0x7C47, 0xF4AA, 0x7C45, 0xF4AB, 0x7CEE, 0xF4AC, 0x7E7B,
+	0xF4AD, 0x7E7E, 0xF4AE, 0x7E81, 0xF4AF, 0x7E80, 0xF4B0, 0x7FBA,
+	0xF4B1, 0x7FFF, 0xF4B2, 0x8079, 0xF4B3, 0x81DB, 0xF4B4, 0x81D9,
+	0xF4B5, 0x820B, 0xF4B6, 0x8268, 0xF4B7, 0x8269, 0xF4B8, 0x8622,
+	0xF4B9, 0x85FF, 0xF4BA, 0x8601, 0xF4BB, 0x85FE, 0xF4BC, 0x861B,
+	0xF4BD, 0x8600, 0xF4BE, 0x85F6, 0xF4BF, 0x8604, 0xF4C0, 0x8609,
+	0xF4C1, 0x8605, 0xF4C2, 0x860C, 0xF4C3, 0x85FD, 0xF4C4, 0x8819,
+	0xF4C5, 0x8810, 0xF4C6, 0x8811, 0xF4C7, 0x8817, 0xF4C8, 0x8813,
+	0xF4C9, 0x8816, 0xF4CA, 0x8963, 0xF4CB, 0x8966, 0xF4CC, 0x89B9,
+	0xF4CD, 0x89F7, 0xF4CE, 0x8B60, 0xF4CF, 0x8B6A, 0xF4D0, 0x8B5D,
+	0xF4D1, 0x8B68, 0xF4D2, 0x8B63, 0xF4D3, 0x8B65, 0xF4D4, 0x8B67,
+	0xF4D5, 0x8B6D, 0xF4D6, 0x8DAE, 0xF4D7, 0x8E86, 0xF4D8, 0x8E88,
+	0xF4D9, 0x8E84, 0xF4DA, 0x8F59, 0xF4DB, 0x8F56, 0xF4DC, 0x8F57,
+	0xF4DD, 0x8F55, 0xF4DE, 0x8F58, 0xF4DF, 0x8F5A, 0xF4E0, 0x908D,
+	0xF4E1, 0x9143, 0xF4E2, 0x9141, 0xF4E3, 0x91B7, 0xF4E4, 0x91B5,
+	0xF4E5, 0x91B2, 0xF4E6, 0x91B3, 0xF4E7, 0x940B, 0xF4E8, 0x9413,
+	0xF4E9, 0x93FB, 0xF4EA, 0x9420, 0xF4EB, 0x940F, 0xF4EC, 0x9414,
+	0xF4ED, 0x93FE, 0xF4EE, 0x9415, 0xF4EF, 0x9410, 0xF4F0, 0x9428,
+	0xF4F1, 0x9419, 0xF4F2, 0x940D, 0xF4F3, 0x93F5, 0xF4F4, 0x9400,
+	0xF4F5, 0x93F7, 0xF4F6, 0x9407, 0xF4F7, 0x940E, 0xF4F8, 0x9416,
+	0xF4F9, 0x9412, 0xF4FA, 0x93FA, 0xF4FB, 0x9409, 0xF4FC, 0x93F8,
+	0xF4FD, 0x940A, 0xF4FE, 0x93FF, 0xF540, 0x93FC, 0xF541, 0x940C,
+	0xF542, 0x93F6, 0xF543, 0x9411, 0xF544, 0x9406, 0xF545, 0x95DE,
+	0xF546, 0x95E0, 0xF547, 0x95DF, 0xF548, 0x972E, 0xF549, 0x972F,
+	0xF54A, 0x97B9, 0xF54B, 0x97BB, 0xF54C, 0x97FD, 0xF54D, 0x97FE,
+	0xF54E, 0x9860, 0xF54F, 0x9862, 0xF550, 0x9863, 0xF551, 0x985F,
+	0xF552, 0x98C1, 0xF553, 0x98C2, 0xF554, 0x9950, 0xF555, 0x994E,
+	0xF556, 0x9959, 0xF557, 0x994C, 0xF558, 0x994B, 0xF559, 0x9953,
+	0xF55A, 0x9A32, 0xF55B, 0x9A34, 0xF55C, 0x9A31, 0xF55D, 0x9A2C,
+	0xF55E, 0x9A2A, 0xF55F, 0x9A36, 0xF560, 0x9A29, 0xF561, 0x9A2E,
+	0xF562, 0x9A38, 0xF563, 0x9A2D, 0xF564, 0x9AC7, 0xF565, 0x9ACA,
+	0xF566, 0x9AC6, 0xF567, 0x9B10, 0xF568, 0x9B12, 0xF569, 0x9B11,
+	0xF56A, 0x9C0B, 0xF56B, 0x9C08, 0xF56C, 0x9BF7, 0xF56D, 0x9C05,
+	0xF56E, 0x9C12, 0xF56F, 0x9BF8, 0xF570, 0x9C40, 0xF571, 0x9C07,
+	0xF572, 0x9C0E, 0xF573, 0x9C06, 0xF574, 0x9C17, 0xF575, 0x9C14,
+	0xF576, 0x9C09, 0xF577, 0x9D9F, 0xF578, 0x9D99, 0xF579, 0x9DA4,
+	0xF57A, 0x9D9D, 0xF57B, 0x9D92, 0xF57C, 0x9D98, 0xF57D, 0x9D90,
+	0xF57E, 0x9D9B, 0xF5A1, 0x9DA0, 0xF5A2, 0x9D94, 0xF5A3, 0x9D9C,
+	0xF5A4, 0x9DAA, 0xF5A5, 0x9D97, 0xF5A6, 0x9DA1, 0xF5A7, 0x9D9A,
+	0xF5A8, 0x9DA2, 0xF5A9, 0x9DA8, 0xF5AA, 0x9D9E, 0xF5AB, 0x9DA3,
+	0xF5AC, 0x9DBF, 0xF5AD, 0x9DA9, 0xF5AE, 0x9D96, 0xF5AF, 0x9DA6,
+	0xF5B0, 0x9DA7, 0xF5B1, 0x9E99, 0xF5B2, 0x9E9B, 0xF5B3, 0x9E9A,
+	0xF5B4, 0x9EE5, 0xF5B5, 0x9EE4, 0xF5B6, 0x9EE7, 0xF5B7, 0x9EE6,
+	0xF5B8, 0x9F30, 0xF5B9, 0x9F2E, 0xF5BA, 0x9F5B, 0xF5BB, 0x9F60,
+	0xF5BC, 0x9F5E, 0xF5BD, 0x9F5D, 0xF5BE, 0x9F59, 0xF5BF, 0x9F91,
+	0xF5C0, 0x513A, 0xF5C1, 0x5139, 0xF5C2, 0x5298, 0xF5C3, 0x5297,
+	0xF5C4, 0x56C3, 0xF5C5, 0x56BD, 0xF5C6, 0x56BE, 0xF5C7, 0x5B48,
+	0xF5C8, 0x5B47, 0xF5C9, 0x5DCB, 0xF5CA, 0x5DCF, 0xF5CB, 0x5EF1,
+	0xF5CC, 0x61FD, 0xF5CD, 0x651B, 0xF5CE, 0x6B02, 0xF5CF, 0x6AFC,
+	0xF5D0, 0x6B03, 0xF5D1, 0x6AF8, 0xF5D2, 0x6B00, 0xF5D3, 0x7043,
+	0xF5D4, 0x7044, 0xF5D5, 0x704A, 0xF5D6, 0x7048, 0xF5D7, 0x7049,
+	0xF5D8, 0x7045, 0xF5D9, 0x7046, 0xF5DA, 0x721D, 0xF5DB, 0x721A,
+	0xF5DC, 0x7219, 0xF5DD, 0x737E, 0xF5DE, 0x7517, 0xF5DF, 0x766A,
+	0xF5E0, 0x77D0, 0xF5E1, 0x792D, 0xF5E2, 0x7931, 0xF5E3, 0x792F,
+	0xF5E4, 0x7C54, 0xF5E5, 0x7C53, 0xF5E6, 0x7CF2, 0xF5E7, 0x7E8A,
+	0xF5E8, 0x7E87, 0xF5E9, 0x7E88, 0xF5EA, 0x7E8B, 0xF5EB, 0x7E86,
+	0xF5EC, 0x7E8D, 0xF5ED, 0x7F4D, 0xF5EE, 0x7FBB, 0xF5EF, 0x8030,
+	0xF5F0, 0x81DD, 0xF5F1, 0x8618, 0xF5F2, 0x862A, 0xF5F3, 0x8626,
+	0xF5F4, 0x861F, 0xF5F5, 0x8623, 0xF5F6, 0x861C, 0xF5F7, 0x8619,
+	0xF5F8, 0x8627, 0xF5F9, 0x862E, 0xF5FA, 0x8621, 0xF5FB, 0x8620,
+	0xF5FC, 0x8629, 0xF5FD, 0x861E, 0xF5FE, 0x8625, 0xF640, 0x8829,
+	0xF641, 0x881D, 0xF642, 0x881B, 0xF643, 0x8820, 0xF644, 0x8824,
+	0xF645, 0x881C, 0xF646, 0x882B, 0xF647, 0x884A, 0xF648, 0x896D,
+	0xF649, 0x8969, 0xF64A, 0x896E, 0xF64B, 0x896B, 0xF64C, 0x89FA,
+	0xF64D, 0x8B79, 0xF64E, 0x8B78, 0xF64F, 0x8B45, 0xF650, 0x8B7A,
+	0xF651, 0x8B7B, 0xF652, 0x8D10, 0xF653, 0x8D14, 0xF654, 0x8DAF,
+	0xF655, 0x8E8E, 0xF656, 0x8E8C, 0xF657, 0x8F5E, 0xF658, 0x8F5B,
+	0xF659, 0x8F5D, 0xF65A, 0x9146, 0xF65B, 0x9144, 0xF65C, 0x9145,
+	0xF65D, 0x91B9, 0xF65E, 0x943F, 0xF65F, 0x943B, 0xF660, 0x9436,
+	0xF661, 0x9429, 0xF662, 0x943D, 0xF663, 0x943C, 0xF664, 0x9430,
+	0xF665, 0x9439, 0xF666, 0x942A, 0xF667, 0x9437, 0xF668, 0x942C,
+	0xF669, 0x9440, 0xF66A, 0x9431, 0xF66B, 0x95E5, 0xF66C, 0x95E4,
+	0xF66D, 0x95E3, 0xF66E, 0x9735, 0xF66F, 0x973A, 0xF670, 0x97BF,
+	0xF671, 0x97E1, 0xF672, 0x9864, 0xF673, 0x98C9, 0xF674, 0x98C6,
+	0xF675, 0x98C0, 0xF676, 0x9958, 0xF677, 0x9956, 0xF678, 0x9A39,
+	0xF679, 0x9A3D, 0xF67A, 0x9A46, 0xF67B, 0x9A44, 0xF67C, 0x9A42,
+	0xF67D, 0x9A41, 0xF67E, 0x9A3A, 0xF6A1, 0x9A3F, 0xF6A2, 0x9ACD,
+	0xF6A3, 0x9B15, 0xF6A4, 0x9B17, 0xF6A5, 0x9B18, 0xF6A6, 0x9B16,
+	0xF6A7, 0x9B3A, 0xF6A8, 0x9B52, 0xF6A9, 0x9C2B, 0xF6AA, 0x9C1D,
+	0xF6AB, 0x9C1C, 0xF6AC, 0x9C2C, 0xF6AD, 0x9C23, 0xF6AE, 0x9C28,
+	0xF6AF, 0x9C29, 0xF6B0, 0x9C24, 0xF6B1, 0x9C21, 0xF6B2, 0x9DB7,
+	0xF6B3, 0x9DB6, 0xF6B4, 0x9DBC, 0xF6B5, 0x9DC1, 0xF6B6, 0x9DC7,
+	0xF6B7, 0x9DCA, 0xF6B8, 0x9DCF, 0xF6B9, 0x9DBE, 0xF6BA, 0x9DC5,
+	0xF6BB, 0x9DC3, 0xF6BC, 0x9DBB, 0xF6BD, 0x9DB5, 0xF6BE, 0x9DCE,
+	0xF6BF, 0x9DB9, 0xF6C0, 0x9DBA, 0xF6C1, 0x9DAC, 0xF6C2, 0x9DC8,
+	0xF6C3, 0x9DB1, 0xF6C4, 0x9DAD, 0xF6C5, 0x9DCC, 0xF6C6, 0x9DB3,
+	0xF6C7, 0x9DCD, 0xF6C8, 0x9DB2, 0xF6C9, 0x9E7A, 0xF6CA, 0x9E9C,
+	0xF6CB, 0x9EEB, 0xF6CC, 0x9EEE, 0xF6CD, 0x9EED, 0xF6CE, 0x9F1B,
+	0xF6CF, 0x9F18, 0xF6D0, 0x9F1A, 0xF6D1, 0x9F31, 0xF6D2, 0x9F4E,
+	0xF6D3, 0x9F65, 0xF6D4, 0x9F64, 0xF6D5, 0x9F92, 0xF6D6, 0x4EB9,
+	0xF6D7, 0x56C6, 0xF6D8, 0x56C5, 0xF6D9, 0x56CB, 0xF6DA, 0x5971,
+	0xF6DB, 0x5B4B, 0xF6DC, 0x5B4C, 0xF6DD, 0x5DD5, 0xF6DE, 0x5DD1,
+	0xF6DF, 0x5EF2, 0xF6E0, 0x6521, 0xF6E1, 0x6520, 0xF6E2, 0x6526,
+	0xF6E3, 0x6522, 0xF6E4, 0x6B0B, 0xF6E5, 0x6B08, 0xF6E6, 0x6B09,
+	0xF6E7, 0x6C0D, 0xF6E8, 0x7055, 0xF6E9, 0x7056, 0xF6EA, 0x7057,
+	0xF6EB, 0x7052, 0xF6EC, 0x721E, 0xF6ED, 0x721F, 0xF6EE, 0x72A9,
+	0xF6EF, 0x737F, 0xF6F0, 0x74D8, 0xF6F1, 0x74D5, 0xF6F2, 0x74D9,
+	0xF6F3, 0x74D7, 0xF6F4, 0x766D, 0xF6F5, 0x76AD, 0xF6F6, 0x7935,
+	0xF6F7, 0x79B4, 0xF6F8, 0x7A70, 0xF6F9, 0x7A71, 0xF6FA, 0x7C57,
+	0xF6FB, 0x7C5C, 0xF6FC, 0x7C59, 0xF6FD, 0x7C5B, 0xF6FE, 0x7C5A,
+	0xF740, 0x7CF4, 0xF741, 0x7CF1, 0xF742, 0x7E91, 0xF743, 0x7F4F,
+	0xF744, 0x7F87, 0xF745, 0x81DE, 0xF746, 0x826B, 0xF747, 0x8634,
+	0xF748, 0x8635, 0xF749, 0x8633, 0xF74A, 0x862C, 0xF74B, 0x8632,
+	0xF74C, 0x8636, 0xF74D, 0x882C, 0xF74E, 0x8828, 0xF74F, 0x8826,
+	0xF750, 0x882A, 0xF751, 0x8825, 0xF752, 0x8971, 0xF753, 0x89BF,
+	0xF754, 0x89BE, 0xF755, 0x89FB, 0xF756, 0x8B7E, 0xF757, 0x8B84,
+	0xF758, 0x8B82, 0xF759, 0x8B86, 0xF75A, 0x8B85, 0xF75B, 0x8B7F,
+	0xF75C, 0x8D15, 0xF75D, 0x8E95, 0xF75E, 0x8E94, 0xF75F, 0x8E9A,
+	0xF760, 0x8E92, 0xF761, 0x8E90, 0xF762, 0x8E96, 0xF763, 0x8E97,
+	0xF764, 0x8F60, 0xF765, 0x8F62, 0xF766, 0x9147, 0xF767, 0x944C,
+	0xF768, 0x9450, 0xF769, 0x944A, 0xF76A, 0x944B, 0xF76B, 0x944F,
+	0xF76C, 0x9447, 0xF76D, 0x9445, 0xF76E, 0x9448, 0xF76F, 0x9449,
+	0xF770, 0x9446, 0xF771, 0x973F, 0xF772, 0x97E3, 0xF773, 0x986A,
+	0xF774, 0x9869, 0xF775, 0x98CB, 0xF776, 0x9954, 0xF777, 0x995B,
+	0xF778, 0x9A4E, 0xF779, 0x9A53, 0xF77A, 0x9A54, 0xF77B, 0x9A4C,
+	0xF77C, 0x9A4F, 0xF77D, 0x9A48, 0xF77E, 0x9A4A, 0xF7A1, 0x9A49,
+	0xF7A2, 0x9A52, 0xF7A3, 0x9A50, 0xF7A4, 0x9AD0, 0xF7A5, 0x9B19,
+	0xF7A6, 0x9B2B, 0xF7A7, 0x9B3B, 0xF7A8, 0x9B56, 0xF7A9, 0x9B55,
+	0xF7AA, 0x9C46, 0xF7AB, 0x9C48, 0xF7AC, 0x9C3F, 0xF7AD, 0x9C44,
+	0xF7AE, 0x9C39, 0xF7AF, 0x9C33, 0xF7B0, 0x9C41, 0xF7B1, 0x9C3C,
+	0xF7B2, 0x9C37, 0xF7B3, 0x9C34, 0xF7B4, 0x9C32, 0xF7B5, 0x9C3D,
+	0xF7B6, 0x9C36, 0xF7B7, 0x9DDB, 0xF7B8, 0x9DD2, 0xF7B9, 0x9DDE,
+	0xF7BA, 0x9DDA, 0xF7BB, 0x9DCB, 0xF7BC, 0x9DD0, 0xF7BD, 0x9DDC,
+	0xF7BE, 0x9DD1, 0xF7BF, 0x9DDF, 0xF7C0, 0x9DE9, 0xF7C1, 0x9DD9,
+	0xF7C2, 0x9DD8, 0xF7C3, 0x9DD6, 0xF7C4, 0x9DF5, 0xF7C5, 0x9DD5,
+	0xF7C6, 0x9DDD, 0xF7C7, 0x9EB6, 0xF7C8, 0x9EF0, 0xF7C9, 0x9F35,
+	0xF7CA, 0x9F33, 0xF7CB, 0x9F32, 0xF7CC, 0x9F42, 0xF7CD, 0x9F6B,
+	0xF7CE, 0x9F95, 0xF7CF, 0x9FA2, 0xF7D0, 0x513D, 0xF7D1, 0x5299,
+	0xF7D2, 0x58E8, 0xF7D3, 0x58E7, 0xF7D4, 0x5972, 0xF7D5, 0x5B4D,
+	0xF7D6, 0x5DD8, 0xF7D7, 0x882F, 0xF7D8, 0x5F4F, 0xF7D9, 0x6201,
+	0xF7DA, 0x6203, 0xF7DB, 0x6204, 0xF7DC, 0x6529, 0xF7DD, 0x6525,
+	0xF7DE, 0x6596, 0xF7DF, 0x66EB, 0xF7E0, 0x6B11, 0xF7E1, 0x6B12,
+	0xF7E2, 0x6B0F, 0xF7E3, 0x6BCA, 0xF7E4, 0x705B, 0xF7E5, 0x705A,
+	0xF7E6, 0x7222, 0xF7E7, 0x7382, 0xF7E8, 0x7381, 0xF7E9, 0x7383,
+	0xF7EA, 0x7670, 0xF7EB, 0x77D4, 0xF7EC, 0x7C67, 0xF7ED, 0x7C66,
+	0xF7EE, 0x7E95, 0xF7EF, 0x826C, 0xF7F0, 0x863A, 0xF7F1, 0x8640,
+	0xF7F2, 0x8639, 0xF7F3, 0x863C, 0xF7F4, 0x8631, 0xF7F5, 0x863B,
+	0xF7F6, 0x863E, 0xF7F7, 0x8830, 0xF7F8, 0x8832, 0xF7F9, 0x882E,
+	0xF7FA, 0x8833, 0xF7FB, 0x8976, 0xF7FC, 0x8974, 0xF7FD, 0x8973,
+	0xF7FE, 0x89FE, 0xF840, 0x8B8C, 0xF841, 0x8B8E, 0xF842, 0x8B8B,
+	0xF843, 0x8B88, 0xF844, 0x8C45, 0xF845, 0x8D19, 0xF846, 0x8E98,
+	0xF847, 0x8F64, 0xF848, 0x8F63, 0xF849, 0x91BC, 0xF84A, 0x9462,
+	0xF84B, 0x9455, 0xF84C, 0x945D, 0xF84D, 0x9457, 0xF84E, 0x945E,
+	0xF84F, 0x97C4, 0xF850, 0x97C5, 0xF851, 0x9800, 0xF852, 0x9A56,
+	0xF853, 0x9A59, 0xF854, 0x9B1E, 0xF855, 0x9B1F, 0xF856, 0x9B20,
+	0xF857, 0x9C52, 0xF858, 0x9C58, 0xF859, 0x9C50, 0xF85A, 0x9C4A,
+	0xF85B, 0x9C4D, 0xF85C, 0x9C4B, 0xF85D, 0x9C55, 0xF85E, 0x9C59,
+	0xF85F, 0x9C4C, 0xF860, 0x9C4E, 0xF861, 0x9DFB, 0xF862, 0x9DF7,
+	0xF863, 0x9DEF, 0xF864, 0x9DE3, 0xF865, 0x9DEB, 0xF866, 0x9DF8,
+	0xF867, 0x9DE4, 0xF868, 0x9DF6, 0xF869, 0x9DE1, 0xF86A, 0x9DEE,
+	0xF86B, 0x9DE6, 0xF86C, 0x9DF2, 0xF86D, 0x9DF0, 0xF86E, 0x9DE2,
+	0xF86F, 0x9DEC, 0xF870, 0x9DF4, 0xF871, 0x9DF3, 0xF872, 0x9DE8,
+	0xF873, 0x9DED, 0xF874, 0x9EC2, 0xF875, 0x9ED0, 0xF876, 0x9EF2,
+	0xF877, 0x9EF3, 0xF878, 0x9F06, 0xF879, 0x9F1C, 0xF87A, 0x9F38,
+	0xF87B, 0x9F37, 0xF87C, 0x9F36, 0xF87D, 0x9F43, 0xF87E, 0x9F4F,
+	0xF8A1, 0x9F71, 0xF8A2, 0x9F70, 0xF8A3, 0x9F6E, 0xF8A4, 0x9F6F,
+	0xF8A5, 0x56D3, 0xF8A6, 0x56CD, 0xF8A7, 0x5B4E, 0xF8A8, 0x5C6D,
+	0xF8A9, 0x652D, 0xF8AA, 0x66ED, 0xF8AB, 0x66EE, 0xF8AC, 0x6B13,
+	0xF8AD, 0x705F, 0xF8AE, 0x7061, 0xF8AF, 0x705D, 0xF8B0, 0x7060,
+	0xF8B1, 0x7223, 0xF8B2, 0x74DB, 0xF8B3, 0x74E5, 0xF8B4, 0x77D5,
+	0xF8B5, 0x7938, 0xF8B6, 0x79B7, 0xF8B7, 0x79B6, 0xF8B8, 0x7C6A,
+	0xF8B9, 0x7E97, 0xF8BA, 0x7F89, 0xF8BB, 0x826D, 0xF8BC, 0x8643,
+	0xF8BD, 0x8838, 0xF8BE, 0x8837, 0xF8BF, 0x8835, 0xF8C0, 0x884B,
+	0xF8C1, 0x8B94, 0xF8C2, 0x8B95, 0xF8C3, 0x8E9E, 0xF8C4, 0x8E9F,
+	0xF8C5, 0x8EA0, 0xF8C6, 0x8E9D, 0xF8C7, 0x91BE, 0xF8C8, 0x91BD,
+	0xF8C9, 0x91C2, 0xF8CA, 0x946B, 0xF8CB, 0x9468, 0xF8CC, 0x9469,
+	0xF8CD, 0x96E5, 0xF8CE, 0x9746, 0xF8CF, 0x9743, 0xF8D0, 0x9747,
+	0xF8D1, 0x97C7, 0xF8D2, 0x97E5, 0xF8D3, 0x9A5E, 0xF8D4, 0x9AD5,
+	0xF8D5, 0x9B59, 0xF8D6, 0x9C63, 0xF8D7, 0x9C67, 0xF8D8, 0x9C66,
+	0xF8D9, 0x9C62, 0xF8DA, 0x9C5E, 0xF8DB, 0x9C60, 0xF8DC, 0x9E02,
+	0xF8DD, 0x9DFE, 0xF8DE, 0x9E07, 0xF8DF, 0x9E03, 0xF8E0, 0x9E06,
+	0xF8E1, 0x9E05, 0xF8E2, 0x9E00, 0xF8E3, 0x9E01, 0xF8E4, 0x9E09,
+	0xF8E5, 0x9DFF, 0xF8E6, 0x9DFD, 0xF8E7, 0x9E04, 0xF8E8, 0x9EA0,
+	0xF8E9, 0x9F1E, 0xF8EA, 0x9F46, 0xF8EB, 0x9F74, 0xF8EC, 0x9F75,
+	0xF8ED, 0x9F76, 0xF8EE, 0x56D4, 0xF8EF, 0x652E, 0xF8F0, 0x65B8,
+	0xF8F1, 0x6B18, 0xF8F2, 0x6B19, 0xF8F3, 0x6B17, 0xF8F4, 0x6B1A,
+	0xF8F5, 0x7062, 0xF8F6, 0x7226, 0xF8F7, 0x72AA, 0xF8F8, 0x77D8,
+	0xF8F9, 0x77D9, 0xF8FA, 0x7939, 0xF8FB, 0x7C69, 0xF8FC, 0x7C6B,
+	0xF8FD, 0x7CF6, 0xF8FE, 0x7E9A, 0xF940, 0x7E98, 0xF941, 0x7E9B,
+	0xF942, 0x7E99, 0xF943, 0x81E0, 0xF944, 0x81E1, 0xF945, 0x8646,
+	0xF946, 0x8647, 0xF947, 0x8648, 0xF948, 0x8979, 0xF949, 0x897A,
+	0xF94A, 0x897C, 0xF94B, 0x897B, 0xF94C, 0x89FF, 0xF94D, 0x8B98,
+	0xF94E, 0x8B99, 0xF94F, 0x8EA5, 0xF950, 0x8EA4, 0xF951, 0x8EA3,
+	0xF952, 0x946E, 0xF953, 0x946D, 0xF954, 0x946F, 0xF955, 0x9471,
+	0xF956, 0x9473, 0xF957, 0x9749, 0xF958, 0x9872, 0xF959, 0x995F,
+	0xF95A, 0x9C68, 0xF95B, 0x9C6E, 0xF95C, 0x9C6D, 0xF95D, 0x9E0B,
+	0xF95E, 0x9E0D, 0xF95F, 0x9E10, 0xF960, 0x9E0F, 0xF961, 0x9E12,
+	0xF962, 0x9E11, 0xF963, 0x9EA1, 0xF964, 0x9EF5, 0xF965, 0x9F09,
+	0xF966, 0x9F47, 0xF967, 0x9F78, 0xF968, 0x9F7B, 0xF969, 0x9F7A,
+	0xF96A, 0x9F79, 0xF96B, 0x571E, 0xF96C, 0x7066, 0xF96D, 0x7C6F,
+	0xF96E, 0x883C, 0xF96F, 0x8DB2, 0xF970, 0x8EA6, 0xF971, 0x91C3,
+	0xF972, 0x9474, 0xF973, 0x9478, 0xF974, 0x9476, 0xF975, 0x9475,
+	0xF976, 0x9A60, 0xF977, 0x9C74, 0xF978, 0x9C73, 0xF979, 0x9C71,
+	0xF97A, 0x9C75, 0xF97B, 0x9E14, 0xF97C, 0x9E13, 0xF97D, 0x9EF6,
+	0xF97E, 0x9F0A, 0xF9A1, 0x9FA4, 0xF9A2, 0x7068, 0xF9A3, 0x7065,
+	0xF9A4, 0x7CF7, 0xF9A5, 0x866A, 0xF9A6, 0x883E, 0xF9A7, 0x883D,
+	0xF9A8, 0x883F, 0xF9A9, 0x8B9E, 0xF9AA, 0x8C9C, 0xF9AB, 0x8EA9,
+	0xF9AC, 0x8EC9, 0xF9AD, 0x974B, 0xF9AE, 0x9873, 0xF9AF, 0x9874,
+	0xF9B0, 0x98CC, 0xF9B1, 0x9961, 0xF9B2, 0x99AB, 0xF9B3, 0x9A64,
+	0xF9B4, 0x9A66, 0xF9B5, 0x9A67, 0xF9B6, 0x9B24, 0xF9B7, 0x9E15,
+	0xF9B8, 0x9E17, 0xF9B9, 0x9F48, 0xF9BA, 0x6207, 0xF9BB, 0x6B1E,
+	0xF9BC, 0x7227, 0xF9BD, 0x864C, 0xF9BE, 0x8EA8, 0xF9BF, 0x9482,
+	0xF9C0, 0x9480, 0xF9C1, 0x9481, 0xF9C2, 0x9A69, 0xF9C3, 0x9A68,
+	0xF9C4, 0x9B2E, 0xF9C5, 0x9E19, 0xF9C6, 0x7229, 0xF9C7, 0x864B,
+	0xF9C8, 0x8B9F, 0xF9C9, 0x9483, 0xF9CA, 0x9C79, 0xF9CB, 0x9EB7,
+	0xF9CC, 0x7675, 0xF9CD, 0x9A6B, 0xF9CE, 0x9C7A, 0xF9CF, 0x9E1D,
+	0xF9D0, 0x7069, 0xF9D1, 0x706A, 0xF9D2, 0x9EA4, 0xF9D3, 0x9F7E,
+	0xF9D4, 0x9F49, 0xF9D5, 0x9F98, 0xF9D6, 0x7881, 0xF9D7, 0x92B9,
+	0xF9D8, 0x88CF, 0xF9D9, 0x58BB, 0xF9DA, 0x6052, 0xF9DB, 0x7CA7,
+	0xF9DC, 0x5AFA, 0xF9DD, 0x2554, 0xF9DE, 0x2566, 0xF9DF, 0x2557,
+	0xF9E0, 0x2560, 0xF9E1, 0x256C, 0xF9E2, 0x2563, 0xF9E3, 0x255A,
+	0xF9E4, 0x2569, 0xF9E5, 0x255D, 0xF9E6, 0x2552, 0xF9E7, 0x2564,
+	0xF9E8, 0x2555, 0xF9E9, 0x255E, 0xF9EA, 0x256A, 0xF9EB, 0x2561,
+	0xF9EC, 0x2558, 0xF9ED, 0x2567, 0xF9EE, 0x255B, 0xF9EF, 0x2553,
+	0xF9F0, 0x2565, 0xF9F1, 0x2556, 0xF9F2, 0x255F, 0xF9F3, 0x256B,
+	0xF9F4, 0x2562, 0xF9F5, 0x2559, 0xF9F6, 0x2568, 0xF9F7, 0x255C,
+	0xF9F8, 0x2551, 0xF9F9, 0x2550, 0xF9FA, 0x256D, 0xF9FB, 0x256E,
+	0xF9FC, 0x2570, 0xF9FD, 0x256F, 0xF9FE, 0x2593, 0, 0
+};
+
+
+
+WCHAR ff_convert (	/* Converted code, 0 means conversion error */
+	WCHAR	src,	/* Character code to be converted */
+	UINT	dir		/* 0: Unicode to OEMCP, 1: OEMCP to Unicode */
+)
+{
+	const WCHAR *p;
+	WCHAR c;
+	int i, n, li, hi;
+
+
+	if (src < 0x80) {	/* ASCII */
+		c = src;
+	} else {
+		if (dir) {		/* OEMCP to unicode */
+			p = oem2uni;
+			hi = sizeof(oem2uni) / 4 - 1;
+		} else {		/* Unicode to OEMCP */
+			p = uni2oem;
+			hi = sizeof(uni2oem) / 4 - 1;
+		}
+		li = 0;
+		for (n = 16; n; n--) {
+			i = li + (hi - li) / 2;
+			if (src == p[i * 2]) break;
+			if (src > p[i * 2])
+				li = i;
+			else
+				hi = i;
+		}
+		c = n ? p[i * 2 + 1] : 0;
+	}
+
+	return c;
+}
+#else
+#error This file is not needed in current configuration.
+
+#endif
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/files/ff/option/ccsbcs.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/files/ff/option/ccsbcs.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/files/ff/option/ccsbcs.c	(revision 457)
@@ -0,0 +1,332 @@
+/*------------------------------------------------------------------------*/
+/* Unicode - OEM code bidirectional converter  (C)ChaN, 2009              */
+/*                                                                        */
+/* SBCS code                                                              */
+/*------------------------------------------------------------------------*/
+
+#include "../ff.h"
+
+
+#if _USE_LFN && _CODE_PAGE == 437
+#define _TBLDEF 1
+static
+const WCHAR Tbl[] = {	/*  CP437(0x80-0xFF) to Unicode conversion table */
+	0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E4, 0x00E0, 0x00E5, 0x00E7,
+	0x00EA, 0x00EB, 0x00E8, 0x00EF, 0x00EE, 0x00EC, 0x00C4, 0x00C5,
+	0x00C9, 0x00E6, 0x00C6, 0x00F4, 0x00F6, 0x00F2, 0x00FB, 0x00F9,
+	0x00FF, 0x00D6, 0x00DC, 0x00A2, 0x00A3, 0x00A5, 0x20A7, 0x0192,
+	0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x00F1, 0x00D1, 0x00AA, 0x00BA,
+	0x00BF, 0x2310, 0x00AC, 0x00BD, 0x00BC, 0x00A1, 0x00AB, 0x00BB,
+	0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556,
+	0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x255B, 0x2510,
+	0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F,
+	0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567,
+	0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B,
+	0x256A, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580,
+	0x03B1, 0x00DF, 0x0393, 0x03C0, 0x03A3, 0x03C3, 0x00B5, 0x03C4,
+	0x03A6, 0x0398, 0x03A9, 0x03B4, 0x221E, 0x03C6, 0x03B5, 0x2229,
+	0x2261, 0x00B1, 0x2265, 0x2264, 0x2320, 0x2321, 0x00F7, 0x2248,
+	0x00B0, 0x2219, 0x00B7, 0x221A, 0x207F, 0x00B2, 0x25A0, 0x00A0
+};
+
+#elif _CODE_PAGE == 720
+#define _TBLDEF 1
+static
+const WCHAR Tbl[] = {	/*  CP720(0x80-0xFF) to Unicode conversion table */
+	0x0000, 0x0000, 0x00E9, 0x00E2, 0x0000, 0x00E0, 0x0000, 0x00E7,
+	0x00EA, 0x00EB, 0x00E8, 0x00EF, 0x00EE, 0x0000, 0x0000, 0x0000,
+	0x0000, 0x0651, 0x0652, 0x00F4, 0x00A4, 0x0640, 0x00FB, 0x00F9,
+	0x0621, 0x0622, 0x0623, 0x0624, 0x00A3, 0x0625, 0x0626, 0x0627,
+	0x0628, 0x0629, 0x062A, 0x062B, 0x062C, 0x062D, 0x062E, 0x062F,
+	0x0630, 0x0631, 0x0632, 0x0633, 0x0634, 0x0635, 0x00AB, 0x00BB,
+	0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556,
+	0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x255B, 0x2510,
+	0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F,
+	0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567,
+	0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B,
+	0x256A, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580,
+	0x0636, 0x0637, 0x0638, 0x0639, 0x063A, 0x0641, 0x00B5, 0x0642,
+	0x0643, 0x0644, 0x0645, 0x0646, 0x0647, 0x0648, 0x0649, 0x064A,
+	0x2261, 0x064B, 0x064C, 0x064D, 0x064E, 0x064F, 0xO650, 0x2248,
+	0x00B0, 0x2219, 0x00B7, 0x221A, 0x207F, 0x00B2, 0x25A0, 0x00A0
+};
+
+#elif _CODE_PAGE == 737
+#define _TBLDEF 1
+static
+const WCHAR Tbl[] = {	/*  CP737(0x80-0xFF) to Unicode conversion table */
+	0x0391, 0x0392, 0x0393, 0x0394, 0x0395, 0x0396, 0x0397, 0x0398,
+	0x0399, 0x039A, 0x039B, 0x039C, 0x039D, 0x039E, 0x039F, 0x03A0,
+	0x03A1, 0x03A3, 0x03A4, 0x03A5, 0x03A6, 0x03A7, 0x03A8, 0x03A9,
+	0x03B1, 0x03B2, 0x03B3, 0x03B4, 0x03B5, 0x03B6, 0x03B7, 0x03B8,
+	0x03B9, 0x03BA, 0x03BB, 0x03BC, 0x03BD, 0x03BE, 0x03BF, 0x03C0,
+	0x03C1, 0x03C3, 0x03C2, 0x03C4, 0x03C5, 0x03C6, 0x03C7, 0x03C8,
+	0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556,
+	0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x255B, 0x2510,
+	0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F,
+	0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567,
+	0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B,
+	0x256A, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580,
+	0x03C9, 0x03AC, 0x03AD, 0x03AE, 0x03CA, 0x03AF, 0x03CC, 0x03CD,
+	0x03CB, 0x03CE, 0x0386, 0x0388, 0x0389, 0x038A, 0x038C, 0x038E,
+	0x038F, 0x00B1, 0x2265, 0x2264, 0x03AA, 0x03AB, 0x00F7, 0x2248,
+	0x00B0, 0x2219, 0x00B7, 0x221A, 0x207F, 0x00B2, 0x25A0, 0x00A0
+};
+
+#elif _CODE_PAGE == 775
+#define _TBLDEF 1
+static
+const WCHAR Tbl[] = {	/*  CP775(0x80-0xFF) to Unicode conversion table */
+	0x0106, 0x00FC, 0x00E9, 0x0101, 0x00E4, 0x0123, 0x00E5, 0x0107,
+	0x0142, 0x0113, 0x0156, 0x0157, 0x012B, 0x0179, 0x00C4, 0x00C5,
+	0x00C9, 0x00E6, 0x00C6, 0x014D, 0x00F6, 0x0122, 0x00A2, 0x015A,
+	0x015B, 0x00D6, 0x00DC, 0x00F8, 0x00A3, 0x00D8, 0x00D7, 0x00A4,
+	0x0100, 0x012A, 0x00F3, 0x017B, 0x017C, 0x017A, 0x201D, 0x00A6,
+	0x00A9, 0x00AE, 0x00AC, 0x00BD, 0x00BC, 0x0141, 0x00AB, 0x00BB,
+	0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x0104, 0x010C, 0x0118,
+	0x0116, 0x2563, 0x2551, 0x2557, 0x255D, 0x012E, 0x0160, 0x2510,
+	0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x0172, 0x016A,
+	0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x017D,
+	0x0105, 0x010D, 0x0119, 0x0117, 0x012F, 0x0161, 0x0173, 0x016B,
+	0x017E, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580,
+	0x00D3, 0x00DF, 0x014C, 0x0143, 0x00F5, 0x00D5, 0x00B5, 0x0144,
+	0x0136, 0x0137, 0x013B, 0x013C, 0x0146, 0x0112, 0x0145, 0x2019,
+	0x00AD, 0x00B1, 0x201C, 0x00BE, 0x00B6, 0x00A7, 0x00F7, 0x201E,
+	0x00B0, 0x2219, 0x00B7, 0x00B9, 0x00B3, 0x00B2, 0x25A0, 0x00A0
+};
+
+#elif _CODE_PAGE == 850
+#define _TBLDEF 1
+static
+const WCHAR Tbl[] = {	/*  CP850(0x80-0xFF) to Unicode conversion table */
+	0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E4, 0x00E0, 0x00E5, 0x00E7,
+	0x00EA, 0x00EB, 0x00E8, 0x00EF, 0x00EE, 0x00EC, 0x00C4, 0x00C5,
+	0x00C9, 0x00E6, 0x00C6, 0x00F4, 0x00F6, 0x00F2, 0x00FB, 0x00F9,
+	0x00FF, 0x00D6, 0x00DC, 0x00F8, 0x00A3, 0x00D8, 0x00D7, 0x0192,
+	0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x00F1, 0x00D1, 0x00AA, 0x00BA,
+	0x00BF, 0x00AE, 0x00AC, 0x00BD, 0x00BC, 0x00A1, 0x00AB, 0x00BB,
+	0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x00C1, 0x00C2, 0x00C0,
+	0x00A9, 0x2563, 0x2551, 0x2557, 0x255D, 0x00A2, 0x00A5, 0x2510,
+	0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x00E3, 0x00C3,
+	0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x00A4,
+	0x00F0, 0x00D0, 0x00CA, 0x00CB, 0x00C8, 0x0131, 0x00CD, 0x00CE,
+	0x00CF, 0x2518, 0x250C, 0x2588, 0x2584, 0x00A6, 0x00CC, 0x2580,
+	0x00D3, 0x00DF, 0x00D4, 0x00D2, 0x00F5, 0x00D5, 0x00B5, 0x00FE,
+	0x00DE, 0x00DA, 0x00DB, 0x00D9, 0x00FD, 0x00DD, 0x00AF, 0x00B4,
+	0x00AD, 0x00B1, 0x2017, 0x00BE, 0x00B6, 0x00A7, 0x00F7, 0x00B8,
+	0x00B0, 0x00A8, 0x00B7, 0x00B9, 0x00B3, 0x00B2, 0x25A0, 0x00A0
+};
+
+#elif _CODE_PAGE == 852
+#define _TBLDEF 1
+static
+const WCHAR Tbl[] = {	/*  CP852(0x80-0xFF) to Unicode conversion table */
+	0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E4, 0x016F, 0x0107, 0x00E7,
+	0x0142, 0x00EB, 0x0150, 0x0151, 0x00EE, 0x0179, 0x00C4, 0x0106,
+	0x00C9, 0x0139, 0x013A, 0x00F4, 0x00F6, 0x013D, 0x013E, 0x015A,
+	0x015B, 0x00D6, 0x00DC, 0x0164, 0x0165, 0x0141, 0x00D7, 0x010D,
+	0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x0104, 0x0105, 0x017D, 0x017E,
+	0x0118, 0x0119, 0x00AC, 0x017A, 0x010C, 0x015F, 0x00AB, 0x00BB,
+	0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x00C1, 0x00C2, 0x011A,
+	0x015E, 0x2563, 0x2551, 0x2557, 0x255D, 0x017B, 0x017C, 0x2510,
+	0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x0102, 0x0103,
+	0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x00A4,
+	0x0111, 0x0110, 0x010E, 0x00CB, 0x010F, 0x0147, 0x00CD, 0x00CE,
+	0x011B, 0x2518, 0x250C, 0x2588, 0x2584, 0x0162, 0x016E, 0x2580,
+	0x00D3, 0x00DF, 0x00D4, 0x0143, 0x0144, 0x0148, 0x0160, 0x0161,
+	0x0154, 0x00DA, 0x0155, 0x0170, 0x00FD, 0x00DD, 0x0163, 0x00B4,
+	0x00AD, 0x02DD, 0x02DB, 0x02C7, 0x02D8, 0x00A7, 0x00F7, 0x00B8,
+	0x00B0, 0x00A8, 0x02D9, 0x0171, 0x0158, 0x0159, 0x25A0, 0x00A0
+};
+
+#elif _CODE_PAGE == 855
+#define _TBLDEF 1
+static
+const WCHAR Tbl[] = {	/*  CP855(0x80-0xFF) to Unicode conversion table */
+	0x0452, 0x0402, 0x0453, 0x0403, 0x0451, 0x0401, 0x0454, 0x0404,
+	0x0455, 0x0405, 0x0456, 0x0406, 0x0457, 0x0407, 0x0458, 0x0408,
+	0x0459, 0x0409, 0x045A, 0x040A, 0x045B, 0x040B, 0x045C, 0x040C,
+	0x045E, 0x040E, 0x045F, 0x040F, 0x044E, 0x042E, 0x044A, 0x042A,
+	0x0430, 0x0410, 0x0431, 0x0411, 0x0446, 0x0426, 0x0434, 0x0414,
+	0x0435, 0x0415, 0x0444, 0x0424, 0x0433, 0x0413, 0x00AB, 0x00BB,
+	0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x0445, 0x0425, 0x0438,
+	0x0418, 0x2563, 0x2551, 0x2557, 0x255D, 0x0439, 0x0419, 0x2510,
+	0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x043A, 0x041A,
+	0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x00A4,
+	0x043B, 0x041B, 0x043C, 0x041C, 0x043D, 0x041D, 0x043E, 0x041E,
+	0x043F, 0x2518, 0x250C, 0x2588, 0x2584, 0x041F, 0x044F, 0x2580,
+	0x042F, 0x0440, 0x0420, 0x0441, 0x0421, 0x0442, 0x0422, 0x0443,
+	0x0423, 0x0436, 0x0416, 0x0432, 0x0412, 0x044C, 0x042C, 0x2116,
+	0x00AD, 0x044B, 0x042B, 0x0437, 0x0417, 0x0448, 0x0428, 0x044D,
+	0x042D, 0x0449, 0x0429, 0x0447, 0x0427, 0x00A7, 0x25A0, 0x00A0
+};
+
+#elif _CODE_PAGE == 857
+#define _TBLDEF 1
+static
+const WCHAR Tbl[] = {	/*  CP857(0x80-0xFF) to Unicode conversion table */
+	0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E4, 0x00E0, 0x00E5, 0x00E7,
+	0x00EA, 0x00EB, 0x00E8, 0x00EF, 0x00EE, 0x0131, 0x00C4, 0x00C5,
+	0x00C9, 0x00E6, 0x00C6, 0x00F4, 0x00F6, 0x00F2, 0x00FB, 0x00F9,
+	0x0130, 0x00D6, 0x00DC, 0x00F8, 0x00A3, 0x00D8, 0x015E, 0x015F,
+	0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x00F1, 0x00D1, 0x011E, 0x011F,
+	0x00BF, 0x00AE, 0x00AC, 0x00BD, 0x00BC, 0x00A1, 0x00AB, 0x00BB,
+	0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x00C1, 0x00C2, 0x00C0,
+	0x00A9, 0x2563, 0x2551, 0x2557, 0x255D, 0x00A2, 0x00A5, 0x2510,
+	0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x00E3, 0x00C3,
+	0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x00A4,
+	0x00BA, 0x00AA, 0x00CA, 0x00CB, 0x00C8, 0x0000, 0x00CD, 0x00CE,
+	0x00CF, 0x2518, 0x250C, 0x2588, 0x2584, 0x00A6, 0x00CC, 0x2580,
+	0x00D3, 0x00DF, 0x00D4, 0x00D2, 0x00F5, 0x00D5, 0x00B5, 0x0000,
+	0x00D7, 0x00DA, 0x00DB, 0x00D9, 0x00EC, 0x00FF, 0x00AF, 0x00B4,
+	0x00AD, 0x00B1, 0x0000, 0x00BE, 0x00B6, 0x00A7, 0x00F7, 0x00B8,
+	0x00B0, 0x00A8, 0x00B7, 0x00B9, 0x00B3, 0x00B2, 0x25A0, 0x00A0
+};
+
+#elif _CODE_PAGE == 858
+#define _TBLDEF 1
+static
+const WCHAR Tbl[] = {	/*  CP858(0x80-0xFF) to Unicode conversion table */
+	0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E4, 0x00E0, 0x00E5, 0x00E7,
+	0x00EA, 0x00EB, 0x00E8, 0x00EF, 0x00EE, 0x00EC, 0x00C4, 0x00C5,
+	0x00C9, 0x00E6, 0x00C6, 0x00F4, 0x00F6, 0x00F2, 0x00FB, 0x00F9,
+	0x00FF, 0x00D6, 0x00DC, 0x00F8, 0x00A3, 0x00D8, 0x00D7, 0x0192,
+	0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x00F1, 0x00D1, 0x00AA, 0x00BA,
+	0x00BF, 0x00AE, 0x00AC, 0x00BD, 0x00BC, 0x00A1, 0x00AB, 0x00BB,
+	0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x00C1, 0x00C2, 0x00C0,
+	0x00A9, 0x2563, 0x2551, 0x2557, 0x2550, 0x00A2, 0x00A5, 0x2510,
+	0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x00E3, 0x00C3,
+	0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x00A4,
+	0x00F0, 0x00D0, 0x00CA, 0x00CB, 0x00C8, 0x20AC, 0x00CD, 0x00CE,
+	0x00CF, 0x2518, 0x250C, 0x2588, 0x2584, 0x00C6, 0x00CC, 0x2580,
+	0x00D3, 0x00DF, 0x00D4, 0x00D2, 0x00F5, 0x00D5, 0x00B5, 0x00FE,
+	0x00DE, 0x00DA, 0x00DB, 0x00D9, 0x00FD, 0x00DD, 0x00AF, 0x00B4,
+	0x00AD, 0x00B1, 0x2017, 0x00BE, 0x00B6, 0x00A7, 0x00F7, 0x00B8,
+	0x00B0, 0x00A8, 0x00B7, 0x00B9, 0x00B3, 0x00B2, 0x25A0, 0x00A0
+};
+
+#elif _CODE_PAGE == 862
+#define _TBLDEF 1
+static
+const WCHAR Tbl[] = {	/*  CP862(0x80-0xFF) to Unicode conversion table */
+	0x05D0, 0x05D1, 0x05D2, 0x05D3, 0x05D4, 0x05D5, 0x05D6, 0x05D7,
+	0x05D8, 0x05D9, 0x05DA, 0x05DB, 0x05DC, 0x05DD, 0x05DE, 0x05DF,
+	0x05E0, 0x05E1, 0x05E2, 0x05E3, 0x05E4, 0x05E5, 0x05E6, 0x05E7,
+	0x05E8, 0x05E9, 0x05EA, 0x00A2, 0x00A3, 0x00A5, 0x20A7, 0x0192,
+	0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x00F1, 0x00D1, 0x00AA, 0x00BA,
+	0x00BF, 0x2310, 0x00AC, 0x00BD, 0x00BC, 0x00A1, 0x00AB, 0x00BB,
+	0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556,
+	0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x255B, 0x2510,
+	0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F,
+	0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567,
+	0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B,
+	0x256A, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580,
+	0x03B1, 0x00DF, 0x0393, 0x03C0, 0x03A3, 0x03C3, 0x00B5, 0x03C4,
+	0x03A6, 0x0398, 0x03A9, 0x03B4, 0x221E, 0x03C6, 0x03B5, 0x2229,
+	0x2261, 0x00B1, 0x2265, 0x2264, 0x2320, 0x2321, 0x00F7, 0x2248,
+	0x00B0, 0x2219, 0x00B7, 0x221A, 0x207F, 0x00B2, 0x25A0, 0x00A0
+};
+
+#elif _CODE_PAGE == 866
+#define _TBLDEF 1
+static
+const WCHAR Tbl[] = {	/*  CP866(0x80-0xFF) to Unicode conversion table */
+	0x0410, 0x0411, 0x0412, 0x0413, 0x0414, 0x0415, 0x0416, 0x0417,
+	0x0418, 0x0419, 0x041A, 0x041B, 0x041C, 0x041D, 0x041E, 0x041F,
+	0x0420, 0x0421, 0x0422, 0x0423, 0x0424, 0x0425, 0x0426, 0x0427,
+	0x0428, 0x0429, 0x042A, 0x042B, 0x042C, 0x042D, 0x042E, 0x042F,
+	0x0430, 0x0431, 0x0432, 0x0433, 0x0434, 0x0435, 0x0436, 0x0437,
+	0x0438, 0x0439, 0x043A, 0x043B, 0x043C, 0x043D, 0x043E, 0x043F,
+	0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556,
+	0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x255B, 0x2510,
+	0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F,
+	0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567,
+	0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B,
+	0x256A, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580,
+	0x0440, 0x0441, 0x0442, 0x0443, 0x0444, 0x0445, 0x0446, 0x0447,
+	0x0448, 0x0449, 0x044A, 0x044B, 0x044C, 0x044D, 0x044E, 0x044F,
+	0x0401, 0x0451, 0x0404, 0x0454, 0x0407, 0x0457, 0x040E, 0x045E,
+	0x00B0, 0x2219, 0x00B7, 0x221A, 0x2116, 0x00A4, 0x25A0, 0x00A0
+};
+
+#elif _CODE_PAGE == 874
+#define _TBLDEF 1
+static
+const WCHAR Tbl[] = {	/*  CP874(0x80-0xFF) to Unicode conversion table */
+	0x20AC, 0x0000, 0x0000, 0x0000, 0x0000, 0x2026, 0x0000, 0x0000,
+	0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+	0x0000, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014,
+	0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+	0x00A0, 0x0E01, 0x0E02, 0x0E03, 0x0E04, 0x0E05, 0x0E06, 0x0E07,
+	0x0E08, 0x0E09, 0x0E0A, 0x0E0B, 0x0E0C, 0x0E0D, 0x0E0E, 0x0E0F,
+	0x0E10, 0x0E11, 0x0E12, 0x0E13, 0x0E14, 0x0E15, 0x0E16, 0x0E17,
+	0x0E18, 0x0E19, 0x0E1A, 0x0E1B, 0x0E1C, 0x0E1D, 0x0E1E, 0x0E1F,
+	0x0E20, 0x0E21, 0x0E22, 0x0E23, 0x0E24, 0x0E25, 0x0E26, 0x0E27,
+	0x0E28, 0x0E29, 0x0E2A, 0x0E2B, 0x0E2C, 0x0E2D, 0x0E2E, 0x0E2F,
+	0x0E30, 0x0E31, 0x0E32, 0x0E33, 0x0E34, 0x0E35, 0x0E36, 0x0E37,
+	0x0E38, 0x0E39, 0x0E3A, 0x0000, 0x0000, 0x0000, 0x0000, 0x0E3F,
+	0x0E40, 0x0E41, 0x0E42, 0x0E43, 0x0E44, 0x0E45, 0x0E46, 0x0E47,
+	0x0E48, 0x0E49, 0x0E4A, 0x0E4B, 0x0E4C, 0x0E4D, 0x0E4E, 0x0E4F,
+	0x0E50, 0x0E51, 0x0E52, 0x0E53, 0x0E54, 0x0E55, 0x0E56, 0x0E57,
+	0x0E58, 0x0E59, 0x0E5A, 0x0E5B, 0x0000, 0x0000, 0x0000, 0x0000
+};
+
+#elif _CODE_PAGE == 1258
+#define _TBLDEF 1
+static
+const WCHAR Tbl[] = {	/*  CP1258(0x80-0xFF) to Unicode conversion table */
+	0x20AC, 0x0000, 0x201A, 0x0192, 0x201E, 0x2026, 0x2020, 0x2021,
+	0x02C6, 0x2030, 0x0000, 0x2039, 0x0152, 0x0000, 0x0000, 0x0000,
+	0x0000, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014,
+	0x02DC, 0x2122, 0x0000, 0x203A, 0x0153, 0x0000, 0x0000, 0x0178,
+	0x00A0, 0x00A1, 0x00A2, 0x00A3, 0x00A4, 0x00A5, 0x00A6, 0x00A7,
+	0x00A8, 0x00A9, 0x00AA, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00AF,
+	0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x00B4, 0x00B5, 0x00B6, 0x00B7,
+	0x00B8, 0x00B9, 0x00BA, 0x00BB, 0x00BC, 0x00BD, 0x00BE, 0x00BF,
+	0x00C0, 0x00C1, 0x00C2, 0x0102, 0x00C4, 0x00C5, 0x00C6, 0x00C7,
+	0x00C8, 0x00C9, 0x00CA, 0x00CB, 0x0300, 0x00CD, 0x00CE, 0x00CF,
+	0x0110, 0x00D1, 0x0309, 0x00D3, 0x00D4, 0x01A0, 0x00D6, 0x00D7,
+	0x00D8, 0x00D9, 0x00DA, 0x00DB, 0x00DC, 0x01AF, 0x0303, 0x00DF,
+	0x00E0, 0x00E1, 0x00E2, 0x0103, 0x00E4, 0x00E5, 0x00E6, 0x00E7,
+	0x00E8, 0x00E9, 0x00EA, 0x00EB, 0x0301, 0x00ED, 0x00EE, 0x00EF,
+	0x0111, 0x00F1, 0x0323, 0x00F3, 0x00F4, 0x01A1, 0x00F6, 0x00F7,
+	0x00F8, 0x00F9, 0x00FA, 0x00FB, 0x00FC, 0x01B0, 0x20AB, 0x00FF
+};
+
+#endif
+
+
+#if _TBLDEF
+
+WCHAR ff_convert (	/* Converted code, 0 means conversion error */
+	WCHAR	src,	/* Character code to be converted */
+	UINT	dir		/* 0: Unicode to OEMCP, 1: OEMCP to Unicode */
+)
+{
+	const WCHAR *p;
+	WCHAR c;
+
+
+	if (src < 0x80) {	/* ASCII */
+		c = src;
+
+	} else {
+		if (dir) {		/* OEMCP to Unicode */
+			c = (src >= 0x100) ? 0 : Tbl[src - 0x80];
+
+		} else {		/* Unicode to OEMCP */
+			for (c = 0; c < 0x80; c++) {
+				if (src == Tbl[c]) break;
+			}
+			c = (c + 0x80) & 0xFF;
+		}
+	}
+
+	return c;
+}
+
+#else
+#error This file is not needed in current configuration
+
+#endif
+
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/files/ff/option/syncobj.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/files/ff/option/syncobj.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/files/ff/option/syncobj.c	(revision 457)
@@ -0,0 +1,124 @@
+/*------------------------------------------------------------------------*/
+/* Sample code of OS dependent synchronization object controls            */
+/* for FatFs R0.07a  (C)ChaN, 2009                                        */
+/*------------------------------------------------------------------------*/
+
+//#include <windows.h>	// Win32
+#include <kernel.h>
+#include "kernel_cfg.h"
+//#include <ucos_ii.h>	// uC/OS-II
+
+#include "../ff.h"
+
+#if _FS_REENTRANT
+
+static const ID VolumeSemId[4] = {
+	SEMID_FATFS1,
+	SEMID_FATFS2,
+	SEMID_FATFS3,
+	SEMID_FATFS4
+};
+
+/*------------------------------------------------------------------------*/
+/* Create a Synchronization Object for a Volume                           */
+/*------------------------------------------------------------------------*/
+/* This function is called in f_mount function to create a new
+/  synchronization object, such as semaphore and mutex. When a FALSE is
+/  returned, the f_mount function fails with FR_INT_ERR.
+*/
+
+BOOL ff_cre_syncobj (	/* TRUE:Function succeeded, FALSE:Could not create due to any error */
+	BYTE vol,			/* Corresponding logical drive being processed */
+	_SYNC_t *sobj		/* Pointer to return the created sync object */
+)
+{
+	BOOL ret;
+
+//	*sobj = CreateMutex(NULL, FALSE, NULL);					// Win32
+//	ret = (*sobj != INVALID_HANDLE_VALUE) ? TRUE : FALSE;	//
+
+	*sobj = VolumeSemId[vol];	// uITRON (give a static created sync object)
+	ret = TRUE;					// The initial value of the semaphore must be 1.
+
+//	*sobj = OSMutexCreate(0, &err);				// uC/OS-II
+//	ret = (err == OS_NO_ERR) ? TRUE : FALSE;	//
+
+	return ret;
+}
+
+
+
+/*------------------------------------------------------------------------*/
+/* Delete a Synchronization Object                                        */
+/*------------------------------------------------------------------------*/
+/* This function is called in f_mount function to delete a synchronization
+/  object that created with ff_cre_syncobj function. When a FALSE is
+/  returned, the f_mount function fails with FR_INT_ERR.
+*/
+
+BOOL ff_del_syncobj (	/* TRUE:Function succeeded, FALSE:Could not delete due to any error */
+	_SYNC_t sobj		/* Sync object tied to the logical drive to be deleted */
+)
+{
+	BOOL ret;
+
+//	ret = CloseHandle(sobj);	// Win32
+
+	ret = TRUE;					// uITRON (nothing to do)
+
+//	OSMutexDel(sobj, OS_DEL_ALWAYS, &err);		// uC/OS-II
+//	ret = (err == OS_NO_ERR) ? TRUE : FALSE;	//
+
+	return ret;
+}
+
+
+
+/*------------------------------------------------------------------------*/
+/* Request Grant to Access the Volume                                     */
+/*------------------------------------------------------------------------*/
+/* This function is called on entering file functions to lock the volume.
+/  When a FALSE is returned, the file function fails with FR_TIMEOUT.
+*/
+
+BOOL ff_req_grant (	/* TRUE:Got a grant to access the volume, FALSE:Could not get a grant */
+	_SYNC_t sobj	/* Sync object to wait */
+)
+{
+	BOOL ret;
+
+//	ret = (WaitForSingleObject(sobj, _TIMEOUT) == WAIT_OBJECT_0) ? TRUE : FALSE;	// Win32
+
+	ret = (wai_sem(sobj) == E_OK) ? TRUE : FALSE;	// uITRON
+
+//	OSMutexPend(sobj, _TIMEOUT, &err));				// uC/OS-II
+//	ret = (err == OS_NO_ERR) ? TRUE : FALSE;		//
+
+	return ret;
+}
+
+
+
+/*------------------------------------------------------------------------*/
+/* Release Grant to Access the Volume                                     */
+/*------------------------------------------------------------------------*/
+/* This function is called on leaving file functions to unlock the volume.
+*/
+
+void ff_rel_grant (
+	_SYNC_t sobj	/* Sync object to be signaled */
+)
+{
+//	ReleaseMutex(sobj);	// Win32
+
+	sig_sem(sobj);		// uITRON
+
+//	OSMutexPost(sobj);	// uC/OS-II
+}
+
+
+#else
+
+#error This file is not needed in this configuration.
+
+#endif
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/files/ff/sddiskio.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/files/ff/sddiskio.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/files/ff/sddiskio.c	(revision 457)
@@ -0,0 +1,336 @@
+/*
+ *  TOPPERS/JSP/ASP/FMP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Just Standard Profile Kernel
+ * 
+ *  Copyright (C) 2008-2011 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ *  Copyright (C) 2015-2018 by TOPPERS PROJECT Educational Working Group.
+ * 
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ * このプログラムはITRON専用のFFドライバ・ソフトウェアである。
+ * ＳＤカード専用ストレージ関数をサポートする
+ * 擬似的なストレージ関数郡であり、標準ライブラリィと分けての使用が望ましい。
+ * 1. sd_init                  この関数郡の初期化関数(bssがゼロ設定の場合この関数は不要)
+ * 2. sdcard_sense             SD-CARDのセンスを行う
+ * 3. sdcard_diskstatus        SD-CARDのステータス取得:なし
+ * 4. sdcard_diskread          SD-CARDの読み込み:なし
+ * 5. sdcard_diskwrite         SD-CARDの書き込み:なし
+ * 6. sdcard_iocil             SD-CARDのIO制御:なし
+ *
+ */
+
+#include "kernel_impl.h"
+#include <stdlib.h>
+#include <string.h>
+#include <t_syslog.h>
+#include <t_stdlib.h>
+#include "fcntl.h"
+#include "device.h"
+#include "mcicmd.h"
+#include "storagedevice.h"
+#include "ff.h"
+#include "diskio.h"
+#include "sddiskio.h"
+
+static int sdcard_sense(void *psdev, BOOL on);
+static int sdcard_diskstatus(void *psdev);
+static int sdcard_diskread(void *pif, BYTE *Buffer, DWORD SectorNumber, BYTE SectorCount);
+static int sdcard_diskwrite(void *pif, const BYTE *Buffer, DWORD SectorNumber, BYTE SectorCount);
+static int sdcard_diskioctl(void *pif, BYTE Func, void* Buffer);
+
+static const StorageDeviceFunc_t fatfsSDeviceFunc = {
+	sdcard_sense,
+	sdcard_diskstatus,
+	sdcard_diskstatus,
+	(int (*)())sdcard_diskread,
+	(int (*)())sdcard_diskwrite,
+	(int (*)())sdcard_diskioctl
+};
+
+static MCIINFO SDCardInfo;
+static FATFS ActiveFatFsObj __attribute__ ((aligned (32)));
+
+#ifdef DMA_ALINE
+static unsigned int abuff[512/sizeof(unsigned int)];
+
+static void mem_cpy(unsigned char *d, unsigned char *s, int len)
+{
+	while(len > 0){
+		*d++ = *s++;
+		len--;
+	}
+}
+#endif
+
+/*
+ *  FatFs用SDカードファイルドライバの初期化
+ */
+void sd_init(intptr_t exinf)
+{
+	StorageDevice_t *psdev;
+
+	SDMSetupDevice(SDCARD_DEVNO, &psdev);
+	psdev->pdevf            = (StorageDeviceFunc_t *)&fatfsSDeviceFunc;
+	psdev->pdevff           = (StorageDeviceFileFunc_t *)&fatfsSDeviceFileFunc;
+	psdev->_sdev_secsize    = 512;
+	psdev->_sdev_port       = SDCRAD_PORTID;
+#ifdef SDEV_INSWAIT_TIME
+	psdev->_sdev_inswait    = SDEV_INSWAIT_TIME;
+#else
+	psdev->_sdev_inswait    = 0;
+#endif
+	psdev->_sdev_attribute |= SDEV_INSERTCHK|SDEV_CHKREMOVE;
+	psdev->_sdev_local[0]   = &ActiveFatFsObj;
+}
+
+/*
+ *  SDCARDセンス関数
+ */
+static int sdcard_sense(void *pif, BOOL on)
+{
+	StorageDevice_t *psdev = pif;
+	bool_t   exist = mci_ses_por(((StorageDevice_t *)psdev)->_sdev_port);
+	MCIPCB   *pmci;
+	int      result = FR_DISK_ERR;
+
+	pmci = psdev->_sdev_local[1];
+	if(on && !exist){
+		f_mount(psdev->_sdev_devno, 0);
+		psdev->_sdev_attribute &= ~SDEV_DEVERROR;
+		mci_cls_por(pmci);
+		return TRUE;
+	}
+	else if(!on && exist){
+		psdev->_sdev_instimer += SENSE_TIME;
+		if((psdev->_sdev_attribute & SDEV_ONEEXIT) != 0 && psdev->_sdev_instimer < psdev->_sdev_inswait)
+			return FALSE;
+		pmci = mci_opn_por(((StorageDevice_t *)psdev)->_sdev_port);
+		if(pmci == NULL)
+			return FALSE;
+		psdev->_sdev_local[1] = pmci;
+		if(MciCheckCID(pmci) != E_OK){
+			psdev->_sdev_attribute |= SDEV_DEVERROR;
+			return TRUE;
+		}
+		if(MciSetAddress(pmci) != E_OK){
+			psdev->_sdev_attribute |= SDEV_DEVERROR;
+			return TRUE;
+		}
+		if(MciSendCID(pmci) != E_OK){
+			psdev->_sdev_attribute |= SDEV_DEVERROR;
+			return TRUE;
+		}
+		if(MciGetCardInfo(pmci, &SDCardInfo) != E_OK)
+			psdev->_sdev_attribute |= SDEV_DEVERROR;
+		else{
+			psdev->_sdev_maxsec = SDCardInfo.maxsector;
+			if(MciSelectCard(pmci, (((uint32_t)SDCardInfo.RCA) << 16)) != E_OK)
+				psdev->_sdev_attribute |= SDEV_DEVERROR;
+		}
+		if(MciConfiguration(pmci) != E_OK)
+			psdev->_sdev_attribute |= SDEV_DEVERROR;
+		if(MciSetWideBus(pmci) != E_OK)
+			psdev->_sdev_attribute |= SDEV_DEVERROR;
+		if((psdev->_sdev_attribute & SDEV_DEVERROR) == 0)
+			result = f_mount(psdev->_sdev_devno, &ActiveFatFsObj);
+		if(result != FR_OK)
+			psdev->_sdev_attribute |= SDEV_DEVERROR;
+		else
+			psdev->_sdev_local[0]   = &ActiveFatFsObj;
+#if 1
+		syslog_3(LOG_NOTICE, "## attr[%04x] max(%d) result(%d) ##", psdev->_sdev_attribute, psdev->_sdev_maxsec, result);
+#endif
+		return TRUE;
+	}
+	else
+		return FALSE;
+}
+
+/*
+ *  FatFs用SDCARDステータス関数
+ */
+static int sdcard_diskstatus(void *pif)
+{
+	StorageDevice_t *psdev = pif;
+	MCIPCB          *pmci;
+
+	if(psdev == NULL)
+		return STA_NODISK;
+	pmci = psdev->_sdev_local[1];
+	if((psdev->_sdev_attribute & (SDEV_EMPLOY|SDEV_NOTUSE)) != SDEV_EMPLOY || pmci == NULL)
+		return STA_NOINIT;
+	else if((pmci->status & SDMODE_PROTECT) != 0)
+		return STA_PROTECT;
+	else
+		return 0;
+}
+
+/*
+ *  FatFs用SDCARD読み込み関数
+ */
+static int sdcard_diskread(void *pif, BYTE *Buffer, DWORD SectorNumber, BYTE SectorCount)
+{
+ 	StorageDevice_t *psdev = pif;
+	MCIPCB          *pmci;
+	ER              ercd = E_OK;
+	int             retry = 0;
+#ifdef DMA_ALINE
+	unsigned int    align = ((unsigned int)Buffer) & 3;
+	int             i;
+#endif
+
+	pmci = psdev->_sdev_local[1];
+	if((psdev->_sdev_attribute & (SDEV_EMPLOY|SDEV_NOTUSE)) != SDEV_EMPLOY || pmci == NULL)
+		return RES_ERROR;
+#ifndef DMA_ALINE
+	do{
+		ercd = mci_red_blk(pmci, Buffer, SectorNumber * psdev->_sdev_secsize, psdev->_sdev_secsize, SectorCount);
+		if(ercd == E_OK)
+			ercd = mci_wai_trn(pmci, 30*1000);
+		retry++;
+	}while(ercd != E_OK && retry < RETRY_COUNT);
+#else
+	if(align == 0){
+		do{
+			ercd = mci_red_blk(pmci, Buffer, SectorNumber * psdev->_sdev_secsize, psdev->_sdev_secsize, SectorCount);
+			if(ercd == E_OK)
+				ercd = mci_wai_trn(pmci, 30*1000);
+			retry++;
+		}while(ercd != E_OK && retry < RETRY_COUNT);
+	}
+	else{
+		for(i = 0 ; i < SectorCount ; i++, SectorNumber++, Buffer += psdev->_sdev_secsize){
+			do{
+				ercd = mci_red_blk(pmci, abuff, SectorNumber * psdev->_sdev_secsize, psdev->_sdev_secsize, 1);
+				if(ercd == E_OK)
+					ercd = mci_wai_trn(pmci, 30*1000);
+				retry++;
+			}while(ercd != E_OK && retry < RETRY_COUNT);
+			mem_cpy(Buffer, abuff, psdev->_sdev_secsize);
+		}
+	}
+#endif
+	if(ercd == E_OK)
+		return RES_OK;
+	else
+		return RES_ERROR;
+}
+
+/*
+ *  FatFs用SDCARD書き込み関数
+ */
+static int sdcard_diskwrite(void *pif, const BYTE *Buffer, DWORD SectorNumber, BYTE SectorCount)
+{
+	StorageDevice_t *psdev = pif;
+	MCIPCB          *pmci;
+	ER              ercd = E_OK;
+	int             retry = 0;
+#ifdef DMA_ALINE
+	unsigned int    align = ((unsigned int)Buffer) & 3;
+	int             i;
+#endif
+
+	pmci = psdev->_sdev_local[1];
+	if((psdev->_sdev_attribute & (SDEV_EMPLOY|SDEV_NOTUSE)) != SDEV_EMPLOY || pmci == NULL)
+		return RES_ERROR;
+#ifndef DMA_ALINE
+	do{
+		ercd = mci_wri_blk(pmci, (void *)Buffer, SectorNumber * psdev->_sdev_secsize, psdev->_sdev_secsize, SectorCount);
+		if(ercd == E_OK)
+			ercd = mci_wai_trn(pmci, 30*1000);
+		retry++;
+	}while(ercd != E_OK && retry < RETRY_COUNT);
+#else
+	if(align == 0){
+		do{
+			ercd = mci_wri_blk(pmci, (void *)Buffer, SectorNumber * psdev->_sdev_secsize, psdev->_sdev_secsize, SectorCount);
+			if(ercd == E_OK)
+				ercd = mci_wai_trn(pmci, 30*1000);
+			retry++;
+		}while(ercd != E_OK && retry < RETRY_COUNT);
+	}
+	else{
+		for(i = 0 ; i < SectorCount ; i++, SectorNumber++, Buffer += psdev->_sdev_secsize){
+			mem_cpy(abuff, Buffer, psdev->_sdev_secsize);
+			do{
+				ercd = mci_wri_blk(pmci, (void *)abuff, SectorNumber * psdev->_sdev_secsize, psdev->_sdev_secsize, 1);
+				if(ercd == E_OK)
+					ercd = mci_wai_trn(pmci, 30*1000);
+				retry++;
+			}while(ercd != E_OK && retry < RETRY_COUNT);
+		}
+	}
+#endif
+	if(ercd == E_OK)
+		return RES_OK;
+	else
+		return RES_ERROR;
+}
+
+
+/*
+ *  FatFs用SDCARDIO制御関数
+ */
+static int sdcard_diskioctl(void *pif, BYTE Func, void* Buffer)
+{
+	StorageDevice_t *psdev = (StorageDevice_t *)pif;
+	DRESULT         result;
+
+	if(psdev == NULL)
+		return RES_ERROR;
+	if((psdev->_sdev_attribute & (SDEV_EMPLOY|SDEV_NOTUSE)) != SDEV_EMPLOY)
+		return RES_ERROR;
+	switch(Func){
+	case CTRL_SYNC:
+		result = RES_OK;			/* no action */
+		break;
+	case GET_SECTOR_COUNT:
+		*((DWORD *)Buffer) = psdev->_sdev_maxsec;
+		syslog_2(LOG_NOTICE, "ioctl notuse (%d)(%d) ", (int)Func, psdev->_sdev_maxsec);
+		result = RES_OK;
+		break;
+	case GET_BLOCK_SIZE:
+		*((DWORD *)Buffer) = 135;	/* ERASE_BLK */
+		syslog_1(LOG_NOTICE, "call disk_ioctl(GET_BLOCK_SIZE, %08x)", (int)(*((DWORD *)Buffer)));
+		result = RES_OK;
+		break;
+	default:
+		syslog_2(LOG_NOTICE, "call disk_ioctl(%d, %08x)", (int)psdev->_sdev_devno, (int)Buffer);
+		slp_tsk();
+		result = RES_PARERR;
+		break;
+	}
+	return result;
+}
+
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/files/ff/sddiskio.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/files/ff/sddiskio.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/files/ff/sddiskio.h	(revision 457)
@@ -0,0 +1,56 @@
+/*
+ *  TOPPERS/ASP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Advanced Standard Profile Kernel
+ * 
+ *  Copyright (C) 2012 by GT Development Center RICOH COMPANY,LTD. JAPAN
+ *  Copyright (C) 2015-2016 by TOPPERS PROJECT Educational Working Group.
+ * 
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+#ifndef _SDDISKIO_H_
+#define _SDDISKIO_H_
+
+#include "storagedevice.h"
+
+#define RETRY_COUNT    8
+
+#define SDCARD_DEVNO   0
+#define SDCRAD_PORTID  0
+
+extern StorageDeviceFileFunc_t fatfsSDeviceFileFunc;
+
+extern void sd_init(intptr_t exinf);
+extern void _sd_setfcntldev(int no);
+
+
+#endif
+
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/files/stdfile.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/files/stdfile.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/files/stdfile.c	(revision 457)
@@ -0,0 +1,487 @@
+/*
+ *  TOPPERS/ASP/FMP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Advanced Standard Profile/Flexible MultiProcessor Kernel
+ * 
+ *  Copyright (C) 2008-2011 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ *  Copyright (C) 2015-2020 by TOPPERS PROJECT Educational Working Group.
+ * 
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+/*
+ * TOPPERS/ASP/FMP+FATFS対応のPOSIXファイル関数
+ */
+#include <kernel.h>
+#include <stdio.h>
+#include <string.h>
+#include <fcntl.h>
+#include "storagedevice.h"
+#include "kernel_cfg.h"
+
+#ifndef NUM_FIL
+#define NUM_FIL 16
+#endif
+
+/* sys/dirent.h */
+struct dirent {
+  unsigned long  d_fileno;		/* file number of entry */
+  unsigned short d_reclen;		/* length of this record */
+  unsigned char  d_type; 		/* file type, see below */
+  unsigned char  d_namlen;		/* length of string in d_name */
+#define	MAXNAMLEN	255
+  char	d_name[MAXNAMLEN + 1];	/* name must be no longer than this */
+};
+
+/* File types */
+#define DT_UNKMOWN  0
+#define DT_FIFO     1
+#define DT_CHAR     2
+#define DT_DIR      4
+#define DT_BLK      6
+#define DT_REG      8
+#define DT_LNK      10
+#define DT_SOCK     12
+#define DT_WHT      14
+
+
+static FILE iod[NUM_FIL];
+static StorageDevice_t *pdirpsdev = 0;
+
+extern int _setup_file(FILE *st, StorageDevice_t *pd, int lid);
+
+/*
+ *  allocate file structure
+ */
+static FILE *alloc_file(void)
+{
+  FILE *fp;
+  int i;
+
+  loc_cpu();
+  for(fp = iod, i = 0 ; i < NUM_FIL ; fp++, i++){
+    if(fp->_flags == 0){
+      fp->_flags = __SRW;
+      unl_cpu();
+      return fp;
+    }
+  }
+  unl_cpu();
+  return 0;
+}
+
+/*
+ *  free file structure
+ */
+static void free_file(FILE * fp)
+{
+  if(fp != NULL)
+    fp->_flags = 0;
+}
+
+/*
+ *  fopen - open a file
+ *  notice - not support text mode.
+ *           not support append mode.
+ */
+FILE *__wrap_fopen(const char *name, const char *type)
+{
+  StorageDevice_t         *psdev;
+  StorageDeviceFileFunc_t *pff;
+  FILE                    *fp;
+  int                     devno, i, id;
+  unsigned int            mode = 0;
+  unsigned int            stat = 0;
+
+  if((devno = SDMGetDeviceNo(&name)) < 0)
+    return NULL;
+  if((psdev = SDMGetStorageDevice(devno)) == 0)
+    return NULL;
+  pff = psdev->pdevff;
+  if(pff != 0 && pff->_sdevff_open == 0)
+    return NULL;
+
+  if((fp = alloc_file()) != 0){
+    for(i = 0 ; i < 8 && type[i] >= ' ' ; i++){
+      switch(type[i]){
+      case 'r':
+        stat |= O_RDONLY;
+        fp->_flags |= __SRD;
+        break;
+      case 'w':
+        stat |= O_WRONLY | O_CREAT;
+        fp->_flags |= __SWR;
+        break;
+      case 'a':
+        stat |= O_RDWR | O_CREAT;
+        fp->_flags |= __SRD | __SWR;
+        break;
+      case 'b':
+        break;
+      case '+':
+        break;
+      }
+    }
+    if((stat & O_ACCMODE) == (O_WRONLY | O_RDWR))
+      mode = (stat & ~O_ACCMODE) | O_RDWR;
+    else
+      mode = stat;
+    wai_sem(SEM_STDFILE);
+    id = pff->_sdevff_open(devno, name, mode);
+    sig_sem(SEM_STDFILE);
+    if(id < 0){
+      free_file(fp);
+      return NULL;
+    }
+    _setup_file(fp, psdev, id);
+    return fp;
+  }
+  else
+    return NULL;
+}
+
+/*
+ *  fclose - close a file
+ */
+int __wrap_fclose(FILE *fp)
+{
+  StorageDevice_t  *psdev;
+  int              result;
+
+  if(fp == NULL)
+    return -1;
+  psdev = fp->_dev;
+  wai_sem(SEM_STDFILE);
+  if(psdev->pdevff != 0 && psdev->pdevff->_sdevff_close != 0)
+    result = psdev->pdevff->_sdevff_close(fp->_file);
+  else
+    result = -1;
+  sig_sem(SEM_STDFILE);
+  free_file(fp);
+  return result;
+}
+
+/*
+ *  fseek - seek a file
+ */
+int __wrap_fseek(FILE *fp, long offset, int whence)
+{
+  StorageDevice_t  *psdev;
+  int result, res = 0;
+
+  if(fp == NULL)
+    return -1;
+  psdev = fp->_dev;
+  if(psdev->pdevff != 0 && psdev->pdevff->_sdevff_lseek != 0){
+    result = psdev->pdevff->_sdevff_lseek(fp->_file, offset, whence, &res);
+    if(res < 0)
+        fp->_flags |= __SERR;
+    return result;
+  }
+  else
+    return -1;
+}
+
+/*
+ *  ftell - get position file indicator
+ */
+long ftell(FILE *fp)
+{
+  StorageDevice_t  *psdev;
+  long result;
+  int  res = 0;
+
+  if(fp == NULL)
+    return -1;
+  psdev = fp->_dev;
+  if(psdev->pdevff != 0 && psdev->pdevff->_sdevff_lseek != 0){
+    result = psdev->pdevff->_sdevff_lseek(fp->_file, 0, SEEK_CUR, &res);
+    if(res < 0)
+        fp->_flags |= __SERR;
+    return result;
+  }
+  else
+    return -1;
+}
+
+/*
+ *  stat - get file status
+ *       - set st_mode, st_atime, st_atimensec, st_mtime, st_mtimensec
+ *             st_ctime, st_ctimensec, st_blksize, st_blocks, st_size
+ */
+int _stat(const char *name, struct stat *buf)
+{
+  StorageDevice_t *psdev;
+  int             devno;
+  const char      *sname = name;
+
+  devno = SDMGetDeviceNo((const char **)&name);
+  psdev = SDMGetStorageDevice(devno);
+  if(psdev == NULL)
+    return -1;
+  if(psdev->pdevff == 0 || psdev->pdevff->_sdevff_stat == 0)
+    return -1;
+  if(psdev->pdevff->_sdevff_stat(sname, buf) >= 0)
+    return 0;
+  else
+    return -1;
+}
+
+/*
+ *  lstat from fsiunixlike.c, fslpux.c
+ */
+int lstat(const char *path, struct stat *buf)
+{
+  return stat(path, buf);
+}
+
+/*
+ *  access from fsiunixlike.c(2)
+ *  mode=0-file exist, mode=2-writeable OK-0 Err--1
+ */
+int access(const char *path, int mode)
+{
+  struct stat     buf;
+  int             res = -1;
+
+  if(stat(path, &buf) >= 0){
+    res = 0;
+    if((mode & 0x02) != 0 && (buf.st_flags & 0x0001) != 0)	/* read only(no debug) */
+      res = -1;
+  }
+  return res;
+}
+
+/*
+ *  mkdir - make directory
+ *        - not support mode
+ */
+int mkdir(const char *path, mode_t mode)
+{
+  StorageDevice_t *psdev;
+  int             devno;
+
+  devno = SDMGetDeviceNo((const char **)&path);
+  psdev = SDMGetStorageDevice(devno);
+  if(psdev == NULL)
+    return -1;
+  if(psdev->pdevff == 0 || psdev->pdevff->_sdevff_mkdir == 0)
+    return -1;
+  if(psdev->pdevff->_sdevff_mkdir(path) >= 0)
+    return 0;
+  else
+    return -1;
+}
+
+/*
+ *  rmdir from fsiunixlike.c(3), fslpux.c, device.c
+ */
+int rmdir(const char *path)
+{
+  StorageDevice_t *psdev;
+  int             devno;
+
+  devno = SDMGetDeviceNo((const char **)&path);
+  psdev = SDMGetStorageDevice(devno);
+  if(psdev == NULL)
+    return -1;
+  if(psdev->pdevff == 0 || psdev->pdevff->_sdevff_rmdir == 0)
+    return -1;
+  if(psdev->pdevff->_sdevff_rmdir(path) >= 0)
+    return 0;
+  else
+    return -1;
+}
+
+/*
+ *  chmod from fsiunixlike.c(2)
+ */
+int chmod(const char *path, mode_t mode)
+{
+  StorageDevice_t *psdev;
+  int             devno;
+
+  devno = SDMGetDeviceNo((const char **)&path);
+  psdev = SDMGetStorageDevice(devno);
+  if(psdev == NULL)
+    return -1;
+  if(psdev->pdevff == 0 || psdev->pdevff->_sdevff_chmod == 0)
+    return -1;
+  if(psdev->pdevff->_sdevff_chmod(path, mode) >= 0)
+    return 0;
+  else
+    return -1;
+}
+
+/*
+ *  remove - remove a file
+ */
+int remove(const char *name)
+{
+  StorageDevice_t *psdev;
+  int             devno;
+
+  devno = SDMGetDeviceNo((const char **)&name);
+  psdev = SDMGetStorageDevice(devno);
+  if(psdev == NULL)
+    return -1;
+  if(psdev->pdevff == 0 || psdev->pdevff->_sdevff_unlink == 0)
+    return -1;
+  if(psdev->pdevff->_sdevff_unlink(name) >= 0)
+    return 0;
+  else
+    return -1;
+}
+
+/*
+ *  unlink - remove file
+ */
+bool_t unlink(const char *path)
+{
+  StorageDevice_t *psdev;
+  int             devno;
+
+  devno = SDMGetDeviceNo((const char **)&path);
+  psdev = SDMGetStorageDevice(devno);
+  if(psdev == NULL)
+    return -1;
+  if(psdev->pdevff == 0 || psdev->pdevff->_sdevff_unlink == 0)
+    return -1;
+  if(psdev->pdevff->_sdevff_unlink(path) >= 0)
+    return 0;
+  else
+    return -1;
+}
+
+/*
+ *  rename - change file name
+ */
+int rename(const char *oldpath, const char *newpath)
+{
+  StorageDevice_t *psdev;
+  int             devno;
+
+  devno = SDMGetDeviceNo((const char **)&oldpath);
+  psdev = SDMGetStorageDevice(devno);
+  if(psdev == NULL)
+    return -1;
+  if(psdev->pdevff == 0 || psdev->pdevff->_sdevff_rename == 0)
+    return -1;
+  if(psdev->pdevff->_sdevff_rename(oldpath, newpath) >= 0)
+    return 0;
+  else
+    return -1;
+}
+
+/*
+ *  mkstemp from fsiunixlike.c, device.c
+ */
+int mkstemp(char *path)
+{
+	printf("### mkstemp() !! ##\n");
+	slp_tsk();
+	return 0;
+}
+
+/*
+ *  opendir from fsiunixlike.c, fslpux.c(2), device.c
+ */
+void *opendir(const char *path)
+{
+  int             devno;
+
+  devno = SDMGetDeviceNo((const char **)&path);
+  pdirpsdev = SDMGetStorageDevice(devno);
+  if(pdirpsdev == NULL)
+    return NULL;
+  if(pdirpsdev->pdevff == 0 || pdirpsdev->pdevff->_sdevff_opendir == 0)
+    return NULL;
+  return pdirpsdev->pdevff->_sdevff_opendir(path);
+}
+
+/*
+ *  closedir from fsiunixlike.c(2), fslpux.c(4)
+ */
+int closedir(void *dir)
+{
+  if(pdirpsdev == NULL)
+    return 0;
+  if(pdirpsdev->pdevff == 0 || pdirpsdev->pdevff->_sdevff_closedir == 0)
+    return 0;
+  return pdirpsdev->pdevff->_sdevff_closedir(dir);
+}
+
+/*
+ *  readdir from fsiunixlike.c, fslpux.c(2), device.c
+ */
+struct dirent *readdir(void *dir)
+{
+  static struct dirent  Dirent;
+  static struct dirent2 finfo;
+  struct dirent *pdirent;
+  int    i;
+
+  if(pdirpsdev == 0)
+    return NULL;
+  if(pdirpsdev->pdevff == 0 || pdirpsdev->pdevff->_sdevff_readdir == 0)
+    return NULL;
+  if(pdirpsdev->pdevff->_sdevff_readdir(dir, &finfo) == 0)
+    return NULL;
+  pdirent = &Dirent;
+  memset(pdirent, 0, sizeof(struct dirent));
+  for(i = 0 ; i < MAXNAMLEN && finfo.d_name[i] != 0 ; i++)
+    pdirent->d_name[i] = finfo.d_name[i];
+  pdirent->d_namlen = i;
+  pdirent->d_reclen = i;
+  if(finfo.d_type & AM_DIR)
+    Dirent.d_type = DT_DIR;
+  else
+    Dirent.d_type = DT_BLK;
+  return pdirent;
+}
+
+/*
+ *  statfs from fslpux.c
+ */
+int statfs(const char *path, struct statfs2 *status)
+{
+  StorageDevice_t *psdev;
+  int             devno;
+  const char      *name = path;
+
+  devno = SDMGetDeviceNo((const char **)&path);
+  psdev = SDMGetStorageDevice(devno);
+  if(psdev == NULL)
+    return -1;
+  if(psdev->pdevff == 0 || psdev->pdevff->_sdevff_statfs == 0)
+    return -1;
+  return psdev->pdevff->_sdevff_statfs(name, (void *)status);
+}
+
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/files/stdio.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/files/stdio.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/files/stdio.c	(revision 457)
@@ -0,0 +1,399 @@
+/*
+ *  TOPPERS/ASP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Advanced Standard Profile Kernel
+ * 
+ *  Copyright (C) 2008-2011 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ *  Copyright (C) 2015-2016 by TOPPERS PROJECT Educational Working Group.
+ * 
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+/*
+ * このプログラムはITRON専用のTYPE3ソフトウェアである。
+ * POSIXのファイル関数を供給する。
+ * 擬似的なストレージ関数郡であり、標準ライブラリィと分けての使用が望ましい。
+ * 1. _stdfile_init            ファイルインデックスの初期化を行う
+ * 2. open                     ファイルのオープン(特別な専用FDを発行する)
+ * 3. close                    ファイルのクローズ
+ * 4. fstat                    ファイルのステートの取り出し
+ * 5. fseek                    ファイルのシーク
+ * 6. read                     ファイルからのデータ読み出し
+ * 7. write                    ファイルからのデータ書き込み
+ * 8. mmap                     ファイルデータのマップ化
+ * 9. munmap                   ファイルデータのアンマップ化
+ */
+
+#include <kernel.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include "kernel_cfg.h"
+#include "fcntl.h"
+#include "storagedevice.h"
+
+#ifndef NUM_FILEIDX
+#define NUM_FILEIDX	128
+#endif
+
+
+static struct StdFileIndex stdfile[NUM_FILEIDX];
+
+
+void stdfile_init(intptr_t exinf)
+{
+	unsigned int idx;
+
+	for(idx = 0 ; idx < NUM_FILEIDX ; idx++){
+		stdfile[idx].sdmdev = 0;
+		stdfile[idx].sdmfd = -1;
+	}
+}
+
+/*
+ *  FDチェック関数
+ */
+static struct StdFileIndex *fdcheck(int fd)
+{
+	struct StdFileIndex *pf;
+
+	if(fd <= 0 || fd > NUM_FILEIDX)
+		return 0;
+	pf = &stdfile[fd-1];
+	if(pf->sdmfd == -1)
+		return 0;
+	else
+		return pf;
+}
+
+/*
+ *  標準ファイルインターフェイス関数(open)
+ */
+int _open(const char *pathname, int flags)
+{
+	StorageDevice_t         *psdev;
+	StorageDeviceFileFunc_t *pff;
+	int             devno, id, no;
+
+	if((devno = SDMGetDeviceNo(&pathname)) < 0)
+		return -1;
+	if((psdev = SDMGetStorageDevice(devno)) == 0)
+		return -1;
+	pff = psdev->pdevff;
+	if(pff != 0 && pff->_sdevff_open == 0)
+		return -1;
+
+	wai_sem(SEM_STDFILE);
+	for(no = 0 ; no < NUM_FILEIDX ; no++){
+		if(stdfile[no].sdmfd == -1)
+			break;
+	}
+	if(no >= NUM_FILEIDX){
+		sig_sem(SEM_STDFILE);
+		return -1;
+	}
+
+	id = pff->_sdevff_open(devno, pathname, flags);
+	if(id < 0){
+		sig_sem(SEM_STDFILE);
+		return id;
+	}
+	stdfile[no].sdmfd  = id;
+	stdfile[no].sdmdev = psdev;
+	sig_sem(SEM_STDFILE);
+	return no+1;
+}
+
+/*
+ *  標準ファイルインターフェイス関数(close)
+ */
+int _close(int fd)
+{
+	struct StdFileIndex *ps;
+	StorageDevice_t     *psdev;
+	int             result;
+
+	if((ps = fdcheck(fd)) == 0)
+		return -1;
+	wai_sem(SEM_STDFILE);
+	psdev = ps->sdmdev;
+	if(psdev->pdevff != 0 && psdev->pdevff->_sdevff_close != 0)
+		result = psdev->pdevff->_sdevff_close(ps->sdmfd);
+	else
+		result = -1;
+	ps->sdmfd = -1;
+	sig_sem(SEM_STDFILE);
+	return result;
+}
+
+/*
+ *  標準ファイルインターフェイス関数(fstat)
+ */
+int _fstat(int fd, struct stat *buf)
+{
+	struct StdFileIndex *ps;
+	StorageDevice_t     *psdev;
+
+	if((ps = fdcheck(fd)) == 0)
+		return -1;
+	psdev = ps->sdmdev;
+	if(psdev->pdevff != 0 && psdev->pdevff->_sdevff_fstat != 0)
+		return psdev->pdevff->_sdevff_fstat(ps->sdmfd, buf);
+	else
+		return -1;
+}
+
+/*
+ *  標準ファイルインターフェイス関数(lseek)
+ */
+off_t _lseek(int fd, off_t offset, int whence)
+{
+	struct StdFileIndex *ps;
+	StorageDevice_t     *psdev;
+	int                 result;
+
+	if((ps = fdcheck(fd)) == 0)
+		return -1;
+	psdev = ps->sdmdev;
+	if(psdev->pdevff != 0 && psdev->pdevff->_sdevff_lseek != 0)
+		return psdev->pdevff->_sdevff_lseek(ps->sdmfd, offset, whence, &result);
+	else
+		return -1;
+}
+
+/*
+ *  標準ファイルインターフェイス関数(read)
+ */
+long _read(int fd, void *buf, long count)
+{
+	struct StdFileIndex *ps;
+	StorageDevice_t     *psdev;
+	int                 result;
+
+	if((ps = fdcheck(fd)) == 0)
+		return -1;
+	psdev = ps->sdmdev;
+	if(psdev->pdevff != 0 && psdev->pdevff->_sdevff_read != 0)
+		return psdev->pdevff->_sdevff_read(ps->sdmfd, buf, count, &result);
+	else
+		return 0;
+}
+
+/*
+ *  標準ファイルインターフェイス関数(write)
+ */
+long _write(int fd, const void *buf, long count)
+{
+	struct StdFileIndex *ps;
+	StorageDevice_t     *psdev;
+	int                 result;
+
+	if((ps = fdcheck(fd)) == 0)
+		return -1;
+	psdev = ps->sdmdev;
+	if(psdev->pdevff != 0 && psdev->pdevff->_sdevff_write != 0)
+		return psdev->pdevff->_sdevff_write(ps->sdmfd, buf, count, &result);
+	else
+		return 0;
+}
+
+int _isatty(int fd)
+{
+	return 1;
+}
+
+/*
+ *  ファイルマップ関数(mmap)
+ */
+void *mmap(void *start, size_t length, int prot, int flags, int fd, off_t offset)
+{
+	struct StdFileIndex *ps;
+	StorageDevice_t     *psdev;
+
+	if((ps = fdcheck(fd)) == 0)
+		return (void*)-1;
+	psdev = ps->sdmdev;
+	if(psdev->pdevff != 0 && psdev->pdevff->_sdevff_mmap != 0)
+		return psdev->pdevff->_sdevff_mmap(start, length, prot, flags, ps->sdmfd, offset);
+	else
+		return (void*)-1;
+}
+
+/*
+ *  ファイルアンマップ関数(未処理)
+ */
+int munmap(void *start, size_t length)
+{
+	return 0;
+}
+
+/*
+ *  標入出力用１文字入力文
+ */
+static int local_getc(void *st)
+{
+	StorageDevice_t     *psdev;
+	int  result, res = 0;
+	char buf[2];
+
+	if(st == 0 && ((FILE *)st)->_file < 0)
+		return -1;
+	if((psdev = (StorageDevice_t *)((FILE*)st)->_dev) == 0)
+		return -1;
+	if(psdev->pdevff != 0 && psdev->pdevff->_sdevff_read != 0){
+		result = psdev->pdevff->_sdevff_read(((FILE *)st)->_file, buf, 1, &res);
+		if(res < 0)
+			((FILE *)st)->_flags |= __SERR;
+		if(result == 1)
+			return buf[0];
+		else
+			return -1;
+	}
+	else
+		return -1;
+}
+
+/*
+ *  標入出力用１文字入力文
+ */
+static int local_gets(void *st, unsigned int len, char *s)
+{
+	StorageDevice_t     *psdev;
+	int result, res = 0;
+
+	if(st == 0 && ((FILE *)st)->_file < 0)
+		return -1;
+	if((psdev = (StorageDevice_t *)((FILE*)st)->_dev) == 0)
+		return -1;
+	if(psdev->pdevff != 0 && psdev->pdevff->_sdevff_read != 0){
+		result = psdev->pdevff->_sdevff_read(((FILE *)st)->_file, s, len, &res);
+		if(res < 0)
+			((FILE *)st)->_flags |= __SERR;
+		return result;
+	}
+	else
+		return 0;
+}
+
+/*
+ *  標入出力用文字出力文
+ */
+static void local_putc(void *st, int c)
+{
+	StorageDevice_t     *psdev;
+	int  res = 0;
+	char buf[2];
+
+	if(st == 0 && ((FILE *)st)->_file < 0)
+		return;
+	if((psdev = (StorageDevice_t *)((FILE*)st)->_dev) == 0)
+		return;
+	buf[0] = c;
+	if(psdev->pdevff != 0 && psdev->pdevff->_sdevff_write != 0){
+		psdev->pdevff->_sdevff_write(((FILE *)st)->_file, buf, 1, &res);
+		if(res < 0)
+			((FILE *)st)->_flags |= __SERR;
+	}
+}
+
+/*
+ *  標入出力用文字列出力文
+ */
+static int local_puts(void *st, unsigned int len, char *s)
+{
+	StorageDevice_t     *psdev;
+	int result, res = 0;
+
+	if(st == 0 && ((FILE *)st)->_file < 0)
+		return -1;
+	if((psdev = (StorageDevice_t *)((FILE*)st)->_dev) == 0)
+		return -1;
+	if(psdev->pdevff != 0 && psdev->pdevff->_sdevff_write != 0){
+		result = psdev->pdevff->_sdevff_write(((FILE *)st)->_file, s, len, &res);
+		if(res < 0)
+			((FILE *)st)->_flags |= __SERR;
+		return result;
+	}
+	else
+		return 0;
+}
+
+/*
+ *  標入出力用データフラッシュ文
+ */
+static int local_flush(FILE *st)
+{
+	return 0;
+}
+
+/*
+ *  通常ファイルの設定
+ */
+int _setup_file(FILE *st, StorageDevice_t *pd, int lid)
+{
+	if(st == NULL)
+		return 0;
+	st->_file       = lid;
+	st->_func_in    = local_getc;
+	st->_func_ins   = local_gets;
+	st->_func_out   = local_putc;
+	st->_func_outs  = local_puts;
+	st->_func_flush = local_flush;
+	st->_dev        = pd;
+	return 1;
+}
+
+/*
+ *  標準入出力ファイルの設定
+ */
+int _setupstd_file(FILE *st, int fd)
+{
+	struct StdFileIndex *ps;
+
+	if(st == NULL)
+		return 0;
+
+	st->_func_in    = local_getc;
+	st->_func_ins   = local_gets;
+	st->_func_out   = local_putc;
+	st->_func_outs  = local_puts;
+	st->_func_flush = local_flush;
+
+	if((ps = fdcheck(fd)) == 0){
+		st->_file = -1;
+		st->_dev  = 0;
+		return 0;
+	}
+	else{
+		st->_file       = ps->sdmfd;
+		st->_dev        = ps->sdmdev;
+		return 1;
+	}
+}
+
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/files/storagedevice.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/files/storagedevice.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/files/storagedevice.c	(revision 457)
@@ -0,0 +1,178 @@
+/*
+ *  TOPPERS/ASP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Advanced Standard Profile Kernel
+ * 
+ *  Copyright (C) 2008-2011 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ *  Copyright (C) 2015-2016 by TOPPERS PROJECT Educational Working Group.
+ * 
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#include "kernel_cfg.h"
+#include "storagedevice.h"
+
+#define SENSE_DEVICE    (SDEV_ACTIVE|SDEV_INSERTCHK)
+
+/*
+ *  Storage Device Mnanagerの全体定義
+ */
+StorageDeviceHead_t SDeviceHead;
+
+/*
+ *  デバイス単位の構造体領域定義
+ */
+static StorageDevice_t SDevice[NUM_STORAGEDEVICE];
+
+
+
+void sdev_init(intptr_t exinf)
+{
+	unsigned int no;
+
+	for(no = 0 ; no < NUM_STORAGEDEVICE ; no++){
+		memset(&SDevice[no], 0, sizeof(StorageDevice_t));
+	}
+	memset(&SDeviceHead, 0, sizeof(StorageDeviceHead_t));
+	SDeviceHead._psd            = &SDevice[0];
+	SDeviceHead._default_device = DEFAULT_DEVNO;
+    SDeviceHead._sdev_active    = true;
+}
+
+void sdev_terminate(void)
+{
+	SDeviceHead._sdev_active    = false;
+}
+
+ER SDMSetupDevice(int16_t devno, StorageDevice_t **ppsdev)
+{
+	StorageDevice_t *psdev;
+	unsigned int    no;
+
+	if(devno < MINIMUM_DEVNO || devno > MAXIMUM_DEVNO)
+		return E_ID;
+	if(SDeviceHead._num_activedev >= NUM_STORAGEDEVICE)
+		return E_OBJ;
+	for(no = 0, psdev = SDeviceHead._psd ; no < SDeviceHead._num_activedev ; no++, psdev++){
+		if(devno == psdev->_sdev_devno)
+			return E_ID;
+	}
+	psdev->_sdev_attribute = SDEV_ACTIVE;
+	psdev->_sdev_devno     = devno;
+	*ppsdev = psdev;
+	SDeviceHead._num_activedev++;
+	return E_OK;
+}
+
+ER_ID SDMGetDeviceNo(const char **ppathname)
+{
+	ER_ID devno = DEFAULT_DEVNO;
+	const char *p = *ppathname;
+
+	if(*p >= '0'&& *p <= '9'){
+		devno = *p++ - '0';
+		while(*p >= '0' && *p <= '9'){
+			devno *= 10;
+			devno  = *p++ - '0';
+		}
+		if(devno < MINIMUM_DEVNO || devno > MAXIMUM_DEVNO)
+			devno = E_ID;
+	}
+	if(*p == ':')
+		p++;
+	*ppathname = p;
+	return devno;
+}
+
+StorageDevice_t *SDMGetStorageDevice(int devno)
+{
+	StorageDevice_t *psdev = SDeviceHead._psd;
+	unsigned int no;
+
+    for(no = 0 ; no < SDeviceHead._num_activedev ; no++){
+		if((psdev->_sdev_attribute & SDEV_ACTIVE) != 0
+			 && psdev->_sdev_devno == devno)
+			return psdev;
+		psdev++;
+	}
+	return NULL;
+}
+
+ER SDMEmploy(StorageDevice_t *psdev, bool_t sw)
+{
+	if(psdev == 0)
+		return E_PAR;
+	if((psdev->_sdev_attribute & SDEV_ACTIVE) == 0)
+		return E_PAR;
+	if(sw)
+		psdev->_sdev_attribute |= SDEV_EMPLOY;
+	else
+		psdev->_sdev_attribute &= ~SDEV_EMPLOY;
+	return E_OK;
+}
+
+void SDMSence_task(intptr_t exinf)
+{
+	StorageDevice_t *psdev;
+	unsigned int dno;
+	bool_t       employ;
+
+	while(SDeviceHead._sdev_active == true){
+		psdev = SDeviceHead._psd;
+		for(dno = 0 ; dno < SDeviceHead._num_activedev ; dno++, psdev++){
+			if((psdev->_sdev_attribute & SENSE_DEVICE) == SENSE_DEVICE){
+				employ = (psdev->_sdev_attribute & SDEV_EMPLOY) != 0;
+				if(!employ && psdev->pdevf->_sdevf_sense(psdev, employ) != 0){
+					psdev->_sdev_attribute |= SDEV_EMPLOY;
+                    if(psdev->_sdev_notice)
+						psdev->_sdev_notice(psdev, true);
+				}
+				else if((psdev->_sdev_attribute & SDEV_CHKREMOVE) != 0 && employ){
+					if(psdev->pdevf->_sdevf_sense(psdev, employ) != 0){
+						psdev->_sdev_attribute &= ~SDEV_EMPLOY;
+						psdev->_sdev_attribute |= SDEV_ONEEXIT;
+						psdev->_sdev_instimer   = 0;
+	                    if(psdev->_sdev_notice)
+							psdev->_sdev_notice(psdev, false);
+					}
+				}
+			}
+		}
+		dly_tsk(SENSE_TIME);
+#ifdef SDEV_SENSE_ONETIME
+		break;
+#endif
+	}
+}
+
+
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/files/storagedevice.cfg
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/files/storagedevice.cfg	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/files/storagedevice.cfg	(revision 457)
@@ -0,0 +1,18 @@
+/*
+ *  @(#) $Id$
+ */
+
+/*
+ *  STORAGE DEVICEのコンフィギュレーションファイル
+ */
+
+#include "storagedevice.h"
+ATT_INI({TA_NULL, 0, sdev_init});
+ATT_INI({TA_NULL, 0, stdfile_init});
+ATT_INI({TA_NULL, 0, volume_info_init});
+CRE_SEM(SEM_STDFILE,  { TA_TPRI, 1, 1 });
+
+#ifndef SDEV_SENSE_ONETIME
+CRE_TSK(SDM_TASK, { TA_ACT, 1, SDMSence_task, 15, 1024, NULL });
+#endif
+
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/files/storagedevice.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/files/storagedevice.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/files/storagedevice.h	(revision 457)
@@ -0,0 +1,222 @@
+/*
+ *  TOPPERS/ASP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Advanced Standard Profile Kernel
+ * 
+ *  Copyright (C) 2008-2011 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ *  Copyright (C) 2015-2016 by TOPPERS PROJECT Educational Working Group.
+ * 
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+#ifndef _STORAGEDEVICE_H_
+#define _STORAGEDEVICE_H_
+
+#include <kernel.h>
+#include <stdlib.h>
+#include <string.h>
+#include <t_syslog.h>
+#include <t_stdlib.h>
+#ifndef TOPPERS_MACRO_ONLY
+#include <fcntl.h>
+#endif /* TOPPERS_MACRO_ONLY */
+
+/*
+ * This file includes the definitions for open and fcntl
+ * described by POSIX for <fcntl.h>; it also includes
+ * related kernel definitions.
+ */
+#ifndef TOPPERS_MACRO_ONLY
+#include <sys/types.h>
+#endif /* TOPPERS_MACRO_ONLY */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ *  ストレージデバイスの基本設定
+ */
+#ifndef NUM_STORAGEDEVICE
+#define	NUM_STORAGEDEVICE   4		/* デフォルトのストレージデバイス数 */
+#endif
+#define MINIMUM_DEVNO       0
+#define MAXIMUM_DEVNO       9
+#ifndef DEFAULT_DEVNO
+#define DEFAULT_DEVNO       MINIMUM_DEVNO
+#endif
+
+#define SDEV_ACTIVE         (1<<15)	/* アクティブなデバイス */
+#define SDEV_INSERTCHK      (1<<14)	/* 挿入・排出の設定あり */
+#define SDEV_CHKREMOVE      (1<<13)	/* 排出検査する */
+#define SDEV_ONEEXIT        (1<<12)	/* 一度排出あり */
+#define SDEV_EMPLOY         (1<<8)	/* 使用可能 */
+#define SDEV_DEVERROR       (1<<7)	/* DEVICE ERROR */
+#define SDEV_DEVNOTUSE      (1<<0)	/* DEVICE 使用不可 */
+#define SDEV_NOTUSE         255
+
+
+/* File attribute bits for directory entry */
+
+#define	AM_RDO	0x01	/* Read only */
+#define	AM_HID	0x02	/* Hidden */
+#define	AM_SYS	0x04	/* System */
+#define	AM_VOL	0x08	/* Volume label */
+#define AM_LFN	0x0F	/* LFN entry */
+#define AM_DIR	0x10	/* Directory */
+#define AM_ARC	0x20	/* Archive */
+#define AM_MASK	0x3F	/* Mask of defined bits */
+
+/*
+ *  chmod value
+ */
+#define FF_READ     0x0000444
+#define FF_WRITE    0x0000222
+#define FF_EXEC     0x0000111
+
+#define SENSE_TIME      (500)
+
+#ifndef TOPPERS_MACRO_ONLY
+
+struct dirent2
+{
+/* NOTE: This is OUR VERSION of this structure. It contains all the fields currently used by IPS code.
+	If you add fields here, you will also have to modify vcwrapnt.c::*dir() to fill those fields! */
+	unsigned long  d_fsize;
+	unsigned short d_date;
+	unsigned short d_time;
+	unsigned short d_reclen;
+	unsigned char  d_type;
+	unsigned char  d_dummy;
+	char           d_name[256];		/* FIXME: use NAME_MAX? */
+};
+
+/*
+ * file system statistics
+ */
+struct statfs2 {
+  long           f_type;		/* type of file system (unused; zero) */
+  long           f_bsize;		/* fundamental file system block size */
+  long           f_blocks;		/* total data blocks in file system */
+  long           f_bfree;		/* free blocks in fs */
+  long           f_bavail;		/* free blocks avail to non-superuser */
+};
+
+/*
+ *  デバイスドライバー用関数テーブル定義
+ */
+typedef struct StorageDeviceFunc {
+	int (*_sdevf_sense)(void *psdev, bool_t on);
+	int (*_sdevf_diskinit)();
+	int (*_sdevf_diskstatus)();
+	int (*_sdevf_diskread)();
+	int (*_sdevf_diskwrite)();
+	int (*_sdevf_diskioctl)();
+} StorageDeviceFunc_t;
+
+/*
+ *  POSIXファイルインターフェイス用関数テーブル定義
+ */
+typedef struct StorageDeviceFileFunc {
+	void  *(*_sdevff_opendir)(const char *name);
+	int   (*_sdevff_closedir)(void *dir);
+	int   (*_sdevff_readdir)(void *dir, void *dirent2);
+	int   (*_sdevff_mkdir)(const char *name);
+	int   (*_sdevff_rmdir)(const char *name);
+	int   (*_sdevff_unlink)(const char *name);
+	int   (*_sdevff_rename)(const char *oname, const char *nname);
+	int   (*_sdevff_chmod)(const char *name, int mode);
+	int   (*_sdevff_stat)(const char *name, struct stat *buf);
+	int   (*_sdevff_statfs)(const char *name, void *status);
+	int   (*_sdevff_open)(int devno, const char *name, int flags);
+	int   (*_sdevff_close)(int fd);
+ 	int   (*_sdevff_fstat)(int fd, struct stat *buf);
+	off_t (*_sdevff_lseek)(int fd, off_t offset, int whence, int *res);
+	long  (*_sdevff_read)(int fd, void *buf, long count, int *res);
+	long  (*_sdevff_write)(int fd, const void *buf, long count, int *res);
+	void  *(*_sdevff_mmap)(void *start, size_t length, int prot, int flags, int fd, off_t offset);
+} StorageDeviceFileFunc_t;
+
+/*
+ *  ストレージデバイス型定義
+ */
+typedef struct StorageDevice {
+    uint16_t    _sdev_attribute;
+	uint8_t     _sdev_devno;
+	uint8_t     _sdev_port;
+    uint32_t    _sdev_maxsec;
+    uint32_t    _sdev_secsize;
+	uint16_t    _sdev_instimer;
+	uint16_t    _sdev_inswait;
+    void  (*_sdev_notice)(void *psdev, bool_t sw);
+    void  *_sdev_local[4];
+	StorageDeviceFunc_t     *pdevf;
+	StorageDeviceFileFunc_t *pdevff;
+} StorageDevice_t;
+
+/*
+ *  ストレージデバイスヘッダー型定義
+ */
+typedef struct StorageDeviceHead {
+	int16_t     _num_activedev;
+    int8_t      _sdev_active;
+	int8_t      _default_device;
+	uint32_t    (*_get_datetime)(void);
+    StorageDevice_t *_psd;
+} StorageDeviceHead_t;
+
+/*
+ *  SDMの全体定義
+ */
+extern StorageDeviceHead_t SDeviceHead;
+
+/*
+ *  各サービスのプロトタイプ宣言
+ */
+extern void  sdev_init(intptr_t exinf);
+extern void  sdev_terminate(void);
+extern ER    SDMSetupDevice(int16_t devno, StorageDevice_t **ppsdev);
+extern ER_ID SDMGetDeviceNo(const char **ppathname);
+extern StorageDevice_t *SDMGetStorageDevice(int devno);
+extern ER    SDMEmploy(StorageDevice_t *psdev, bool_t sw);
+extern void  SDMSence_task(intptr_t exinf);
+
+extern void stdfile_init(intptr_t exinf);
+extern void volume_info_init(intptr_t exinf);
+
+#endif /* TOPPERS_MACRO_ONLY */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _STORAGEDEVICE_H_ */
+/*  end of file  */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/adafruit_ILI9341/Makefile.config
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/adafruit_ILI9341/Makefile.config	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/adafruit_ILI9341/Makefile.config	(revision 457)
@@ -0,0 +1,55 @@
+#
+#   TOPPERS/ASP/FMP Kernel
+#       Toyohashi Open Platform for Embedded Real-Time Systems/
+#       Advanced Standard Profile Kernel
+#
+#   Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
+#                               Toyohashi Univ. of Technology, JAPAN
+#   Copyright (C) 2003-2008 by Ryosuke Takeuchi
+#                Platform Development Center RICOH COMPANY,LTD. JAPAN
+#   Copyright (C) 2015-2019 by TOPPERS PROJECT Educational Working Group.
+#
+#   上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+#   によって公表されている GNU General Public License の Version 2 に記
+#   述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+#   を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+#   利用と呼ぶ）することを無償で許諾する．
+#   (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+#       権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+#       スコード中に含まれていること．
+#   (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+#       用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+#       者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+#       の無保証規定を掲載すること．
+#   (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+#       用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+#       と．
+#     (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+#         作権表示，この利用条件および下記の無保証規定を掲載すること．
+#     (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+#         報告すること．
+#   (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+#       害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+#
+#   本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+#   よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+#   含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+#   接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+#
+#  @(#) $Id$
+#
+ 
+#
+#  Makefile のプロセッサ依存 (adafruit ILI9341:LCD用)
+#
+
+#
+#  コンパイルオプション
+#
+INCLUDES := $(INCLUDES) -I$(SRCDIR)/gdic/adafruit_ILI9341
+
+#
+#  ADAFRUIT ILI9341 LCD DRIVER(GDIC)に関する定義
+#
+SYSSVC_DIR := $(SYSSVC_DIR):$(SRCDIR)/gdic/adafruit_ILI9341
+SYSSVC_COBJS := $(SYSSVC_COBJS) adafruit_ILI9341.o
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/adafruit_ILI9341/adafruit_ILI9341.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/adafruit_ILI9341/adafruit_ILI9341.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/adafruit_ILI9341/adafruit_ILI9341.c	(revision 457)
@@ -0,0 +1,757 @@
+/*
+ *  TOPPERS BASE PLATFORM MIDDLEWARE
+ * 
+ *  Copyright (C) 2017-2019 by TOPPERS PROJECT
+ *                             Educational Working Group.
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  $Id$
+ */
+
+/*
+ *  Written by Limor Fried/Ladyada for Adafruit Industries.
+ *  MIT license, all text above must be included in any redistribution
+ *　http://opensource.org/licenses/mit-license.php 
+ */
+
+/* 
+ *  ADAFRUIT ILI9341 2.8"LCD制御プログラムの本体
+ */
+
+#include <kernel.h>
+#include <t_syslog.h>
+#include <t_stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <target_syssvc.h>
+#include "syssvc/syslog.h"
+#include "device.h"
+#include "adafruit_ILI9341.h"
+
+/*
+ *  サービスコールのエラーのログ出力
+ */
+Inline void
+svc_perror(const char *file, int_t line, const char *expr, ER ercd)
+{
+	if (ercd < 0) {
+		t_perror(LOG_ERROR, file, line, expr, ercd);
+	}
+}
+
+#define	SVC_PERROR(expr)	svc_perror(__FILE__, __LINE__, #expr, (expr))
+#define ABS(X)  ((X) > 0 ? (X) : -(X))
+
+
+/* Buffer used for transmission */
+static uint8_t aTxBuffer[4];
+
+#define PORT_HIGH           1
+#define PORT_LOW            0
+
+#define MADCTL_MY           0x80
+#define MADCTL_MX           0x40
+#define MADCTL_MV           0x20
+#define MADCTL_ML           0x10
+#define MADCTL_RGB          0x00
+#define MADCTL_BGR          0x08
+#define MADCTL_MH           0x04
+
+
+#define cs_set(sw)  digitalWrite(hlcd->cs_pin, sw)
+#define dc_set(sw)  digitalWrite(hlcd->dc_pin, sw)
+#define rst_set(sw) digitalWrite(hlcd->rst_pin, sw)
+#define cs2_set(sw) digitalWrite(hlcd->cs2_pin, sw)
+
+
+/*
+ *  LCDへのコマンド送信関数
+ */
+ER
+lcd_writecommand(LCD_Handler_t *hlcd, uint8_t c)
+{
+	ER ercd = E_OK;
+
+	if(hlcd->spi_lock != 0){
+		if((ercd = wai_sem(hlcd->spi_lock)) != E_OK)
+			return ercd;
+	}
+	dc_set(PORT_LOW);
+	cs_set(PORT_LOW);
+
+	aTxBuffer[0] = c;
+#if SPI_WAIT_TIME != 0
+	ercd = spi_transmit(hlcd->hspi, (uint8_t*)aTxBuffer, 1);
+#else
+	if((ercd = spi_transmit(hlcd->hspi, (uint8_t*)aTxBuffer, 1)) == E_OK){
+		ercd = spi_wait(hlcd->hspi, 100);
+	}
+#endif
+
+	cs_set(PORT_HIGH);
+	if(hlcd->spi_lock != 0)
+		sig_sem(hlcd->spi_lock);
+	return ercd;
+}
+
+/*
+ *  LCDへのデータ送信関数
+ */
+ER
+lcd_writedata(LCD_Handler_t *hlcd, uint8_t c)
+{
+	ER ercd = E_OK;
+
+	if(hlcd->spi_lock != 0){
+		if((ercd = wai_sem(hlcd->spi_lock)) != E_OK)
+			return ercd;
+	}
+	dc_set(PORT_HIGH);
+	cs_set(PORT_LOW);
+	sil_dly_nse(100);
+
+	aTxBuffer[0] = c;
+#if SPI_WAIT_TIME != 0
+	ercd = spi_transmit(hlcd->hspi, (uint8_t*)aTxBuffer, 1);
+#else
+	if((ercd = spi_transmit(hlcd->hspi, (uint8_t*)aTxBuffer, 1)) == E_OK){
+		ercd = spi_wait(hlcd->hspi, 100);
+	}
+#endif
+
+	sil_dly_nse(100);
+	cs_set(PORT_HIGH);
+	if(hlcd->spi_lock != 0)
+		sig_sem(hlcd->spi_lock);
+	return ercd;
+}
+
+/*
+ *  LCDへの２バイトデータ送信関数
+ */
+ER
+lcd_writedata2(LCD_Handler_t *hlcd, uint16_t c, int cnt)
+{
+	ER  ercd = E_OK;
+	int i;
+
+	if(cnt == 0)
+		return ercd;
+	if(hlcd->spi_lock != 0){
+		if((ercd = wai_sem(hlcd->spi_lock)) != E_OK)
+			return ercd;
+	}
+	dc_set(PORT_HIGH);
+	cs_set(PORT_LOW);
+	sil_dly_nse(100);
+	aTxBuffer[0] = c >> 8;
+	aTxBuffer[1] = (uint8_t)c;
+	for(i = 0 ; i < cnt ; i++){
+		if((ercd = spi_transmit(hlcd->hspi, (uint8_t*)aTxBuffer, 2)) != E_OK){
+			break;
+		}
+#if SPI_WAIT_TIME == 0
+		if((ercd = spi_wait(hlcd->hspi, 100)) != E_OK){
+			break;
+		}
+#endif
+	}
+	sil_dly_nse(100);
+	cs_set(PORT_HIGH);
+	if(hlcd->spi_lock != 0)
+		sig_sem(hlcd->spi_lock);
+	return ercd;
+}
+
+/*
+ *  LCDへのRGBデータ送信関数
+ */
+ER
+lcd_writedata3(LCD_Handler_t *hlcd, uint8_t *pbmp, uint16_t width, uint16_t height)
+{
+	ER  ercd = E_OK;
+	int index, i;
+
+	if(width == 0 || height == 0)
+		return ercd;
+	if(hlcd->spi_lock != 0){
+		if((ercd = wai_sem(hlcd->spi_lock)) != E_OK)
+			return ercd;
+	}
+	dc_set(PORT_HIGH);
+	cs_set(PORT_LOW);
+	sil_dly_nse(100);
+	for(index=0; index < height; index++){
+		uint8_t *p = pbmp;
+		for (i = 0; i < width; i++){
+			aTxBuffer[0]  = (*p++) & 0xf8;
+			aTxBuffer[0] |= *p >> 5;
+			aTxBuffer[1]  = (*p++ << 3) & 0xE0;
+			aTxBuffer[1] |= (*p++ >> 3) & 0x1F;
+			if((ercd = spi_transmit(hlcd->hspi, (uint8_t*)aTxBuffer, 2)) != E_OK){
+				break;
+			}
+#if SPI_WAIT_TIME == 0
+			if((ercd = spi_wait(hlcd->hspi, 100)) != E_OK){
+				break;
+			}
+#endif
+		}
+		pbmp -= width*3;
+	}
+	sil_dly_nse(100);
+	cs_set(PORT_HIGH);
+	if(hlcd->spi_lock != 0)
+		sig_sem(hlcd->spi_lock);
+	return ercd;
+}
+
+
+/*
+ *  表示ウィンドウ設定
+ */
+void
+lcd_setAddrWindow(LCD_Handler_t *hlcd, uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1)
+{
+	uint16_t tmp;
+
+	SVC_PERROR(lcd_writecommand(hlcd, ILI9341_CASET)); // Column addr set
+	tmp = x0 + hlcd->colstart;
+	SVC_PERROR(lcd_writedata(hlcd, (tmp >> 8)));
+	SVC_PERROR(lcd_writedata(hlcd, (tmp & 0xFF)));     // XSTART 
+	tmp = x1 + hlcd->colstart;
+	SVC_PERROR(lcd_writedata(hlcd, (tmp >> 8)));
+	SVC_PERROR(lcd_writedata(hlcd, (tmp & 0xFF)));     // XEND
+
+	SVC_PERROR(lcd_writecommand(hlcd, ILI9341_PASET)); // Row addr set
+	tmp = y0 + hlcd->rowstart;
+	SVC_PERROR(lcd_writedata(hlcd, (tmp >> 8)));
+	SVC_PERROR(lcd_writedata(hlcd, (tmp & 0xFF)));     // YSTART
+	tmp = y1 + hlcd->rowstart;
+	SVC_PERROR(lcd_writedata(hlcd, (tmp >> 8)));
+	SVC_PERROR(lcd_writedata(hlcd, (tmp & 0xFF)));     // YEND
+
+	SVC_PERROR(lcd_writecommand(hlcd, ILI9341_RAMWR)); // write to RAM
+}
+
+
+/*
+ *  ILI9341 screensの初期化関数
+ */
+void
+lcd_init(LCD_Handler_t *hlcd, uint8_t rotation)
+{
+	hlcd->colstart  = hlcd->rowstart = 0; // May be overridden in init func
+	hlcd->_width = ILI9341_TFTWIDTH;
+	hlcd->_height = ILI9341_TFTHEIGHT;
+
+	// toggle RST low to reset; CS low so it'll listen to us
+	cs_set(PORT_LOW);
+	if(hlcd->rst_pin < 14){
+		rst_set(PORT_HIGH);
+		dly_tsk(5);
+		rst_set(PORT_LOW);
+		dly_tsk(20);
+		rst_set(PORT_HIGH);
+		dly_tsk(150);
+	}
+
+	SVC_PERROR(lcd_writecommand(hlcd, 0xEF));
+	SVC_PERROR(lcd_writedata(hlcd, 0x03));
+	SVC_PERROR(lcd_writedata(hlcd, 0x80));
+	SVC_PERROR(lcd_writedata(hlcd, 0x02));
+
+	SVC_PERROR(lcd_writecommand(hlcd, 0xCF));
+	SVC_PERROR(lcd_writedata(hlcd, 0x00));
+	SVC_PERROR(lcd_writedata(hlcd, 0xC1));
+	SVC_PERROR(lcd_writedata(hlcd, 0x30));
+
+	SVC_PERROR(lcd_writecommand(hlcd, 0xED));
+	SVC_PERROR(lcd_writedata(hlcd, 0x64));
+	SVC_PERROR(lcd_writedata(hlcd, 0x03));
+	SVC_PERROR(lcd_writedata(hlcd, 0x12));
+	SVC_PERROR(lcd_writedata(hlcd, 0x81));
+
+	SVC_PERROR(lcd_writecommand(hlcd, 0xE8));
+	SVC_PERROR(lcd_writedata(hlcd, 0x85));
+	SVC_PERROR(lcd_writedata(hlcd, 0x00));
+	SVC_PERROR(lcd_writedata(hlcd, 0x78));
+
+	SVC_PERROR(lcd_writecommand(hlcd, 0xCB));
+	SVC_PERROR(lcd_writedata(hlcd, 0x39));
+	SVC_PERROR(lcd_writedata(hlcd, 0x2C));
+	SVC_PERROR(lcd_writedata(hlcd, 0x00));
+	SVC_PERROR(lcd_writedata(hlcd, 0x34));
+	SVC_PERROR(lcd_writedata(hlcd, 0x02));
+
+	SVC_PERROR(lcd_writecommand(hlcd, 0xF7));
+	SVC_PERROR(lcd_writedata(hlcd, 0x20));
+
+	SVC_PERROR(lcd_writecommand(hlcd, 0xEA));
+	SVC_PERROR(lcd_writedata(hlcd, 0x00));
+	SVC_PERROR(lcd_writedata(hlcd, 0x00));
+
+	SVC_PERROR(lcd_writecommand(hlcd, ILI9341_PWCTR1));	/* Power control */
+	SVC_PERROR(lcd_writedata(hlcd, 0x23));				/* VRH[5:0] */
+
+	SVC_PERROR(lcd_writecommand(hlcd, ILI9341_PWCTR2));	/* Power control */
+	SVC_PERROR(lcd_writedata(hlcd, 0x10));				/* SAP[2:0];BT[3:0] */
+
+	SVC_PERROR(lcd_writecommand(hlcd, ILI9341_VMCTR1));	/* VCM control */
+	SVC_PERROR(lcd_writedata(hlcd, 0x3e));
+	SVC_PERROR(lcd_writedata(hlcd, 0x28));
+
+	SVC_PERROR(lcd_writecommand(hlcd, ILI9341_VMCTR2));	/* VCM control2 */
+	SVC_PERROR(lcd_writedata(hlcd, 0x86));				/* -- */
+
+	SVC_PERROR(lcd_writecommand(hlcd, ILI9341_MADCTL));	/* Memory Access Control */
+	SVC_PERROR(lcd_writedata(hlcd, 0x48));
+
+	SVC_PERROR(lcd_writecommand(hlcd, ILI9341_PIXFMT));
+	SVC_PERROR(lcd_writedata(hlcd, 0x55));
+
+	SVC_PERROR(lcd_writecommand(hlcd, ILI9341_FRMCTR1));
+	SVC_PERROR(lcd_writedata(hlcd, 0x00));
+	SVC_PERROR(lcd_writedata(hlcd, 0x18));
+
+	SVC_PERROR(lcd_writecommand(hlcd, ILI9341_DFUNCTR)); /* Display Function Control */
+	SVC_PERROR(lcd_writedata(hlcd, 0x08));
+	SVC_PERROR(lcd_writedata(hlcd, 0x82));
+	SVC_PERROR(lcd_writedata(hlcd, 0x27));
+
+	SVC_PERROR(lcd_writecommand(hlcd, 0xF2));			/* 3Gamma Function Disable */
+	SVC_PERROR(lcd_writedata(hlcd, 0x00));
+
+	SVC_PERROR(lcd_writecommand(hlcd, ILI9341_GAMMASET)); /* Gamma curve selected */
+	SVC_PERROR(lcd_writedata(hlcd, 0x01));
+
+	SVC_PERROR(lcd_writecommand(hlcd, ILI9341_GMCTRP1)); /* Set Gamma */
+	SVC_PERROR(lcd_writedata(hlcd, 0x0F));
+	SVC_PERROR(lcd_writedata(hlcd, 0x31));
+	SVC_PERROR(lcd_writedata(hlcd, 0x2B));
+	SVC_PERROR(lcd_writedata(hlcd, 0x0C));
+	SVC_PERROR(lcd_writedata(hlcd, 0x0E));
+	SVC_PERROR(lcd_writedata(hlcd, 0x08));
+	SVC_PERROR(lcd_writedata(hlcd, 0x4E));
+	SVC_PERROR(lcd_writedata(hlcd, 0xF1));
+	SVC_PERROR(lcd_writedata(hlcd, 0x37));
+	SVC_PERROR(lcd_writedata(hlcd, 0x07));
+	SVC_PERROR(lcd_writedata(hlcd, 0x10));
+	SVC_PERROR(lcd_writedata(hlcd, 0x03));
+	SVC_PERROR(lcd_writedata(hlcd, 0x0E));
+	SVC_PERROR(lcd_writedata(hlcd, 0x09));
+	SVC_PERROR(lcd_writedata(hlcd, 0x00));
+
+	SVC_PERROR(lcd_writecommand(hlcd, ILI9341_GMCTRN1)); /* Set Gamma */
+	SVC_PERROR(lcd_writedata(hlcd, 0x00));
+	SVC_PERROR(lcd_writedata(hlcd, 0x0E));
+	SVC_PERROR(lcd_writedata(hlcd, 0x14));
+	SVC_PERROR(lcd_writedata(hlcd, 0x03));
+	SVC_PERROR(lcd_writedata(hlcd, 0x11));
+	SVC_PERROR(lcd_writedata(hlcd, 0x07));
+	SVC_PERROR(lcd_writedata(hlcd, 0x31));
+	SVC_PERROR(lcd_writedata(hlcd, 0xC1));
+	SVC_PERROR(lcd_writedata(hlcd, 0x48));
+	SVC_PERROR(lcd_writedata(hlcd, 0x08));
+	SVC_PERROR(lcd_writedata(hlcd, 0x0F));
+	SVC_PERROR(lcd_writedata(hlcd, 0x0C));
+	SVC_PERROR(lcd_writedata(hlcd, 0x31));
+	SVC_PERROR(lcd_writedata(hlcd, 0x36));
+	SVC_PERROR(lcd_writedata(hlcd, 0x0F));
+
+	SVC_PERROR(lcd_writecommand(hlcd, ILI9341_SLPOUT));	/* Exit Sleep */
+	dly_tsk(120);
+	SVC_PERROR(lcd_writecommand(hlcd, ILI9341_DISPON));	/* Display on */
+	lcd_setRotation(hlcd, rotation);
+}
+
+/*
+ *  RECTANGLEのフィル描画
+ *  param1  hlcd: Pointer to LCD Handler
+ *  param2  x: start X position
+ *  param3  y: start Y position
+ *  param4  w: width
+ *  param5  h: height
+ *  param6  color: color value
+ */
+void
+lcd_fillRect(LCD_Handler_t *hlcd, int16_t x, int16_t y, int16_t w, int16_t h, color_t color)
+{
+	// rudimentary clipping (drawChar w/big text requires this)
+	if((x >= hlcd->_width) || (y >= hlcd->_height)) return;
+	if((x + w - 1) >= hlcd->_width)  w = hlcd->_width  - x;
+	if((y + h - 1) >= hlcd->_height) h = hlcd->_height - y;
+
+	lcd_setAddrWindow(hlcd, x, y, x+w-1, y+h-1);
+	SVC_PERROR(lcd_writedata2(hlcd, color, h*w));
+}
+
+void
+lcd_pushColor(LCD_Handler_t *hlcd, color_t color)
+{
+	SVC_PERROR(lcd_writedata2(hlcd, color, 1));
+}
+
+/*
+ *  PIXEL描画
+ *  param1  hlcd: Pointer to LCD Handler
+ *  param2  x: X position
+ *  param3  y: Y position
+ *  param4  color: color value
+ */
+void
+lcd_drawPixel(LCD_Handler_t *hlcd, int16_t x, int16_t y, color_t color)
+{
+	if((x < 0) ||(x >= hlcd->_width) || (y < 0) || (y >= hlcd->_height)) return;
+
+	lcd_setAddrWindow(hlcd, x, y, x, y);
+	SVC_PERROR(lcd_writedata2(hlcd, color, 1));
+}
+
+/*
+ *  垂直方向LINEの高速描画
+ *  param1  hlcd: Pointer to LCD Handler
+ *  param2  x: start X position
+ *  param3  y: start Y position
+ *  param4  h: height
+ *  param5  color: color value
+ */
+void
+lcd_drawFastVLine(LCD_Handler_t *hlcd, int16_t x, int16_t y, int16_t h, color_t color)
+{
+	// Rudimentary clipping
+	if((x >= hlcd->_width) || (y >= hlcd->_height)) return;
+	if((y+h-1) >= hlcd->_height) h = hlcd->_height-y;
+	lcd_setAddrWindow(hlcd, x, y, x, y+h-1);
+	SVC_PERROR(lcd_writedata2(hlcd, color, h));
+}
+
+/*
+ *  水平方向LINEの高速描画
+ *  param1  hlcd: Pointer to LCD Handler
+ *  param2  x: start X position
+ *  param3  y: start Y position
+ *  param4  w: width
+ *  param5  color: color value
+ */
+void lcd_drawFastHLine(LCD_Handler_t *hlcd, int16_t x, int16_t y, int16_t w, color_t color)
+{
+	// Rudimentary clipping
+	if((x >= hlcd->_width) || (y >= hlcd->_height)) return;
+	if((x+w-1) >= hlcd->_width)  w = hlcd->_width-x;
+	lcd_setAddrWindow(hlcd, x, y, x+w-1, y);
+	SVC_PERROR(lcd_writedata2(hlcd, color, w));
+}
+
+/*
+ *  DRAW IMAGE LINE描画
+ *  param1  hlcd: Pointer to LCD Handler
+ *  param2  x: X position
+ *  param3  y: Y position
+ *  param4  w: width
+ *  param5  pcolor: color value
+ */
+void
+lcd_drawImageHLine(LCD_Handler_t *hlcd, int16_t x, int16_t y, uint16_t w, color_t *pcolor)
+{
+	uint32_t i;
+
+	if((x >= hlcd->_width) || (y >= hlcd->_height)) return;
+	if((x+w-1) >= hlcd->_width)  w = hlcd->_width-x;
+
+	lcd_setAddrWindow(hlcd, x, y, x+w-1, y);
+	for(i = 0 ; i < w ; i++, pcolor++)
+		SVC_PERROR(lcd_writedata2(hlcd, *pcolor, 1));
+}
+
+/*
+ *  BITMAP描画
+ *  param1  hlcd: Pointer to LCD Handler
+ *  param2  x0: Bmp X position in the LCD
+ *  param3  y0: Bmp Y position in the LCD
+ *  param4  pbmp: Pointer to Bmp picture address in the internal Flash
+ */
+void
+lcd_drawBitmap(LCD_Handler_t *hlcd, uint16_t x0, uint16_t y0, uint8_t *pbmp)
+{
+	uint32_t index = 0, width = 0, height = 0, bit_pixel = 0;
+	uint32_t input_color_mode = 0;
+
+	/* Get bitmap data address offset */
+	index = *(uint16_t *) (pbmp + 10);
+	index |= (*(uint16_t *) (pbmp + 12)) << 16;
+
+	/* Read bitmap width */
+	width = *(uint16_t *) (pbmp + 18);
+	width |= (*(uint16_t *) (pbmp + 20)) << 16;
+
+	/* Read bitmap height */
+	height = *(uint16_t *) (pbmp + 22);
+	height |= (*(uint16_t *) (pbmp + 24)) << 16;
+
+	/* Read bit/pixel */
+	bit_pixel = *(uint16_t *) (pbmp + 28);
+
+	/* Get the layer pixel format */
+	if ((bit_pixel/8) == 4){
+		input_color_mode = CM_ARGB8888;
+	}
+	else if ((bit_pixel/8) == 2){
+		input_color_mode = CM_RGB565;
+	}
+	else{
+		input_color_mode = CM_RGB888;
+	}
+
+	/* Bypass the bitmap header */
+	pbmp += (index + (width * (height - 1) * (bit_pixel/8)));  
+	syslog_4(LOG_INFO, "lcd_drawBitmap input_color_mode(%d) width(%d) height(%d) bit_pixel(%d)", input_color_mode, width, height, bit_pixel);
+
+	lcd_setAddrWindow(hlcd, x0, y0, x0+width-1, y0+height-1);
+	lcd_writedata3(hlcd, pbmp, width, height);
+}
+
+/*
+ *  ROTATION設定
+ *  param1  hlcd: Pointer to LCD Handler
+ *  param2  m: 0:0, 1:90, 2:180, 3:270
+ */
+void
+lcd_setRotation(LCD_Handler_t *hlcd, uint8_t m)
+{
+	SVC_PERROR(lcd_writecommand(hlcd, ILI9341_MADCTL));
+	hlcd->rotation = m % 4;	// can't be higher than 3
+	switch(hlcd->rotation){
+	case 1:
+		SVC_PERROR(lcd_writedata(hlcd, (MADCTL_MV | MADCTL_BGR)));
+		hlcd->_width  = ILI9341_TFTHEIGHT;
+		hlcd->_height = ILI9341_TFTWIDTH;
+		break;
+	case 2:
+		SVC_PERROR(lcd_writedata(hlcd, (MADCTL_MY | MADCTL_BGR)));
+		hlcd->_width  = ILI9341_TFTWIDTH;
+		hlcd->_height = ILI9341_TFTHEIGHT;
+		break;
+	case 3:
+		SVC_PERROR(lcd_writedata(hlcd, (MADCTL_MX | MADCTL_MY | MADCTL_MV | MADCTL_BGR)));
+		hlcd->_width  = ILI9341_TFTHEIGHT;
+		hlcd->_height = ILI9341_TFTWIDTH;
+		break;
+	case 0:
+	default:
+		SVC_PERROR(lcd_writedata(hlcd, (MADCTL_MX | MADCTL_BGR)));
+		hlcd->_width  = ILI9341_TFTWIDTH;
+		hlcd->_height = ILI9341_TFTHEIGHT;
+		break;
+	}
+}
+
+/*
+ *  INVERT DISPLAY
+ *  param1  hlcd: Pointer to LCD Handler
+ *  param2  i: invert value
+ */
+void
+lcd_invertDisplay(LCD_Handler_t *hlcd, bool_t i)
+{
+	SVC_PERROR(lcd_writecommand(hlcd, i ? ILI9341_INVON : ILI9341_INVOFF));
+}
+
+
+/*
+ *  スクリーンフィル
+ *  param1  pDrawProp: Pointer to Draw Prop
+ */
+void
+lcd_fillScreen(LCD_DrawProp_t *pDrawProp)
+{
+	lcd_fillRect(pDrawProp->hlcd, 0, 0,  pDrawProp->hlcd->_width, pDrawProp->hlcd->_height, pDrawProp->BackColor);
+}
+
+/*
+ *  RECTANGLE描画
+ *  param1  pDrawProp: Pointer to Draw Prop
+ *  param2  x: left X position
+ *  param3  y: top Y position
+ *  param4  w: width
+ *  param5  h: height
+ */
+void
+lcd_drawRect(LCD_DrawProp_t *pDrawProp, int16_t x, int16_t y, int16_t w, int16_t h)
+{
+	LCD_Handler_t *hlcd = pDrawProp->hlcd;
+	color_t color;
+
+	// rudimentary clipping (drawChar w/big text requires this)
+	if((x >= hlcd->_width) || (y >= hlcd->_height)) return;
+	if((x + w - 1) >= hlcd->_width)  w = hlcd->_width  - x;
+	if((y + h - 1) >= hlcd->_height) h = hlcd->_height - y;
+
+	color = pDrawProp->TextColor;
+	lcd_drawFastVLine(hlcd, x, y, h, color);
+	lcd_drawFastHLine(hlcd, x, y+h-1, w, color);
+	lcd_drawFastVLine(hlcd, x+w-1, y, h, color);
+	lcd_drawFastHLine(hlcd, x, y, w, color);
+}
+
+/*
+ *  円描画
+ *  param1  pDrawProp: Pointer to Draw Prop
+ *  param2  x0: X position
+ *  param3  y0: Y position
+ *  param4  Radius: Circle radius
+ */
+void
+lcd_DrawCircle(LCD_DrawProp_t *pDrawProp, uint16_t x0, uint16_t y0, uint16_t Radius)
+{
+	LCD_Handler_t *hlcd = pDrawProp->hlcd;
+ 	int32_t   decision;    /* Decision Variable */ 
+	uint32_t  current_x;   /* Current X Value */
+	uint32_t  current_y;   /* Current Y Value */
+
+	decision = 3 - (Radius << 1);
+	current_x = 0;
+	current_y = Radius;
+
+	while(current_x <= current_y){
+		lcd_drawPixel(hlcd, (x0 + current_x), (y0 - current_y), pDrawProp->TextColor);
+		lcd_drawPixel(hlcd, (x0 - current_x), (y0 - current_y), pDrawProp->TextColor);
+		lcd_drawPixel(hlcd, (x0 + current_y), (y0 - current_x), pDrawProp->TextColor);
+		lcd_drawPixel(hlcd, (x0 - current_y), (y0 - current_x), pDrawProp->TextColor);
+		lcd_drawPixel(hlcd, (x0 + current_x), (y0 + current_y), pDrawProp->TextColor);
+		lcd_drawPixel(hlcd, (x0 - current_x), (y0 + current_y), pDrawProp->TextColor);
+		lcd_drawPixel(hlcd, (x0 + current_y), (y0 + current_x), pDrawProp->TextColor);
+		lcd_drawPixel(hlcd, (x0 - current_y), (y0 + current_x), pDrawProp->TextColor);
+
+		if (decision < 0){
+			decision += (current_x << 2) + 6;
+		}
+		else{
+			decision += ((current_x - current_y) << 2) + 10;
+			current_y--;
+		}
+		current_x++;
+	}
+}
+
+/*
+ *  線描画
+ *  param1  pDrawProp: Pointer to Draw Prop
+ *  param2  x1: Point 1 X position
+ *  param3  y1: Point 1 Y position
+ *  param4  x2: Point 2 X position
+ *  param5  y2: Point 2 Y position
+ */
+void
+lcd_drawLine(LCD_DrawProp_t *pDrawProp, uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2)
+{
+	LCD_Handler_t *hlcd = pDrawProp->hlcd;
+	int16_t deltax = 0, deltay = 0, x = 0, y = 0, xinc1 = 0, xinc2 = 0, 
+	yinc1 = 0, yinc2 = 0, den = 0, num = 0, num_add = 0, num_pixels = 0, 
+	curpixel = 0;
+
+	deltax = ABS(x2 - x1);		/* The difference between the x's */
+	deltay = ABS(y2 - y1);		/* The difference between the y's */
+	x = x1;						/* Start x off at the first pixel */
+	y = y1;						/* Start y off at the first pixel */
+
+	if(x2 >= x1){				/* The x-values are increasing */
+		xinc1 = 1;
+		xinc2 = 1;
+	}
+	else{						/* The x-values are decreasing */
+		xinc1 = -1;
+		xinc2 = -1;
+	}
+
+	if(y2 >= y1){				/* The y-values are increasing */
+		yinc1 = 1;
+		yinc2 = 1;
+	}
+	else{						/* The y-values are decreasing */
+		yinc1 = -1;
+		yinc2 = -1;
+	}
+
+	if(deltax >= deltay){		/* There is at least one x-value for every y-value */
+		xinc1 = 0;				/* Don't change the x when numerator >= denominator */
+		yinc2 = 0;				/* Don't change the y for every iteration */
+		den = deltax;
+		num = deltax / 2;
+		num_add = deltay;
+		num_pixels = deltax;	/* There are more x-values than y-values */
+	}
+	else{						/* There is at least one y-value for every x-value */
+		xinc2 = 0;				/* Don't change the x for every iteration */
+		yinc1 = 0;				/* Don't change the y when numerator >= denominator */
+		den = deltay;
+		num = deltay / 2;
+		num_add = deltax;
+		num_pixels = deltay;	/* There are more y-values than x-values */
+	}
+
+	for (curpixel = 0; curpixel <= num_pixels; curpixel++){
+		lcd_drawPixel(hlcd, x, y, pDrawProp->TextColor);	/* Draw the current pixel */
+		num += num_add;			/* Increase the numerator by the top of the fraction */
+		if(num >= den){			/* Check if numerator >= denominator */
+			num -= den;			/* Calculate the new numerator value */
+			x += xinc1;			/* Change the x as appropriate */
+			y += yinc1;			/* Change the y as appropriate */
+		}
+		x += xinc2;				/* Change the x as appropriate */
+		y += yinc2;				/* Change the y as appropriate */
+	}
+}
+
+/*
+ *  PLOY-LINE描画
+ *  param1  pDrawProp: Pointer to Draw Prop
+ *  param2  Points: Pointer to the points array
+ *  param3  PointCount: Number of points
+ */
+void
+lcd_drawPolygon(LCD_DrawProp_t *pDrawProp, pPoint Points, uint16_t PointCount)
+{
+	int16_t x = 0, y = 0;
+
+	if(PointCount < 2){
+		return;
+	}
+
+	lcd_drawLine(pDrawProp, Points->X, Points->Y, (Points+PointCount-1)->X, (Points+PointCount-1)->Y);
+	while(--PointCount){
+		x = Points->X;
+		y = Points->Y;
+		Points++;
+		lcd_drawLine(pDrawProp, x, y, Points->X, Points->Y);
+	}
+}
+
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/adafruit_ILI9341/adafruit_ILI9341.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/adafruit_ILI9341/adafruit_ILI9341.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/adafruit_ILI9341/adafruit_ILI9341.h	(revision 457)
@@ -0,0 +1,210 @@
+/*
+ *  TOPPERS BASE PLATFORM MIDDLEWARE
+ * 
+ *  Copyright (C) 2017-2019 by TOPPERS PROJECT
+ *                             Educational Working Group.
+ *
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ *
+ *  $Id$
+ */
+
+/*
+ *  Written by Limor Fried/Ladyada for Adafruit Industries.
+ *  MIT license, all text above must be included in any redistribution
+ *　http://opensource.org/licenses/mit-license.php 
+ */
+
+/*
+ *  ADAFRUIT ILI9341 2.8"LCD制御プログラムのヘッダファイル
+ */
+
+#ifndef _ADAFRUIT_ILI9341_H_
+#define _ADAFRUIT_ILI9341_H_
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+#include "device.h"
+#include "pinmode.h"
+#include "spi.h"
+
+/*
+ *  LCDカラーモード定義
+ */
+#define CM_ARGB8888         0x00000000			/* ARGB8888 color mode */
+#define CM_RGB888           0x00000001			/* RGB888 color mode */
+#define CM_RGB565           0x00000002			/* RGB565 color mode */
+
+
+
+#define ILI9341_TFTWIDTH  240
+#define ILI9341_TFTHEIGHT 320
+
+#define ILI9341_NOP     0x00
+#define ILI9341_SWRESET 0x01
+#define ILI9341_RDDID   0x04
+#define ILI9341_RDDST   0x09
+
+#define ILI9341_SLPIN   0x10
+#define ILI9341_SLPOUT  0x11
+#define ILI9341_PTLON   0x12
+#define ILI9341_NORON   0x13
+
+#define ILI9341_RDMODE  0x0A
+#define ILI9341_RDMADCTL  0x0B
+#define ILI9341_RDPIXFMT  0x0C
+#define ILI9341_RDIMGFMT  0x0A
+#define ILI9341_RDSELFDIAG  0x0F
+
+#define ILI9341_INVOFF  0x20
+#define ILI9341_INVON   0x21
+#define ILI9341_GAMMASET 0x26
+#define ILI9341_DISPOFF 0x28
+#define ILI9341_DISPON  0x29
+
+#define ILI9341_CASET   0x2A
+#define ILI9341_PASET   0x2B
+#define ILI9341_RAMWR   0x2C
+#define ILI9341_RAMRD   0x2E
+
+#define ILI9341_PTLAR   0x30
+#define ILI9341_MADCTL  0x36
+#define ILI9341_PIXFMT  0x3A
+
+#define ILI9341_FRMCTR1 0xB1
+#define ILI9341_FRMCTR2 0xB2
+#define ILI9341_FRMCTR3 0xB3
+#define ILI9341_INVCTR  0xB4
+#define ILI9341_DFUNCTR 0xB6
+
+#define ILI9341_PWCTR1  0xC0
+#define ILI9341_PWCTR2  0xC1
+#define ILI9341_PWCTR3  0xC2
+#define ILI9341_PWCTR4  0xC3
+#define ILI9341_PWCTR5  0xC4
+#define ILI9341_VMCTR1  0xC5
+#define ILI9341_VMCTR2  0xC7
+
+#define ILI9341_RDID1   0xDA
+#define ILI9341_RDID2   0xDB
+#define ILI9341_RDID3   0xDC
+#define ILI9341_RDID4   0xDD
+
+#define ILI9341_GMCTRP1 0xE0
+#define ILI9341_GMCTRN1 0xE1
+
+// Color definitions
+#define	ILI9341_BLACK   0x0000
+#define	ILI9341_BLUE    0x001F
+#define	ILI9341_RED     0xF800
+#define	ILI9341_GREEN   0x07E0
+#define ILI9341_CYAN    0x07FF
+#define ILI9341_MAGENTA 0xF81F
+#define ILI9341_YELLOW  0xFFE0
+#define ILI9341_WHITE   0xFFFF
+
+
+#ifndef TOPPERS_MACRO_ONLY
+
+/*
+ *  カラーの属性を定義
+ */
+typedef uint16_t   color_t;
+
+/*
+ *  LCDハンドラ構造体定義
+ */
+typedef struct
+{
+	SPI_Handle_t            *hspi;		/* spiハンドラ */
+	uint16_t                _width;		/* 幅ピクセル数 */
+	uint16_t				_height;	/* 高さピクセル数 */
+	uint16_t                colstart;
+	uint16_t                rowstart;
+	uint8_t                 rotation;	/* LCD回転設定 */
+	uint8_t                 cs_pin;
+	uint8_t                 dc_pin;
+	uint8_t                 rst_pin;
+	ID                      spi_lock;
+}LCD_Handler_t;
+
+/*
+ *  描画構造体
+ */
+typedef struct
+{
+	LCD_Handler_t           *hlcd;
+	color_t                 TextColor;
+	color_t                 BackColor;
+	void                    *pFont;
+}LCD_DrawProp_t;
+
+typedef struct
+{
+	int16_t X;
+	int16_t Y;
+}Point, * pPoint;
+
+/*
+ *  関数のプロトタイプ宣言
+ */
+extern ER lcd_writecommand(LCD_Handler_t *hlcd, uint8_t c);
+extern ER lcd_writedata(LCD_Handler_t *hlcd, uint8_t c);
+extern ER lcd_writedata2(LCD_Handler_t *hlcd, uint16_t c, int cnt);
+extern ER lcd_writedata3(LCD_Handler_t *hlcd, uint8_t *pbmp, uint16_t width, uint16_t height);
+
+extern void lcd_init(LCD_Handler_t *hlcd, uint8_t rotation);
+extern void lcd_setAddrWindow(LCD_Handler_t *hlcd, uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1);
+extern void lcd_fillRect(LCD_Handler_t *hlcd, int16_t x, int16_t y, int16_t w, int16_t h, color_t color);
+extern void lcd_pushColor(LCD_Handler_t *hlcd, color_t color);
+extern void lcd_drawPixel(LCD_Handler_t *hlcd, int16_t x, int16_t y, color_t color);
+extern void lcd_drawFastVLine(LCD_Handler_t *hlcd, int16_t x, int16_t y, int16_t h, color_t color);
+extern void lcd_drawFastHLine(LCD_Handler_t *hlcd, int16_t x, int16_t y, int16_t w, color_t color);
+extern void lcd_drawImageHLine(LCD_Handler_t *hlcd, int16_t x, int16_t y, uint16_t w, color_t *pcolor);
+extern void lcd_drawBitmap(LCD_Handler_t *hlcd, uint16_t x0, uint16_t y0, uint8_t *pbmp);
+extern void lcd_setRotation(LCD_Handler_t *hlcd, uint8_t m);
+extern void lcd_invertDisplay(LCD_Handler_t *hlcd, bool_t i);
+
+extern void lcd_fillScreen(LCD_DrawProp_t *pDrawProp);
+extern void lcd_drawRect(LCD_DrawProp_t *pDrawProp, int16_t x, int16_t y, int16_t w, int16_t h);
+extern void lcd_DrawCircle(LCD_DrawProp_t *pDrawProp, uint16_t x0, uint16_t y0, uint16_t Radius);
+extern void lcd_drawLine(LCD_DrawProp_t *pDrawProp, uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2);
+extern void lcd_drawPolygon(LCD_DrawProp_t *pDrawProp, pPoint Points, uint16_t PointCount);
+
+#endif /* TOPPERS_MACRO_ONLY */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif	/* _ADAFRUIT_ILI9341_H_ */
+
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/adafruit_ILI9341/glcd_core.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/adafruit_ILI9341/glcd_core.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/adafruit_ILI9341/glcd_core.h	(revision 457)
@@ -0,0 +1,45 @@
+/*
+ *  TOPPERS BASE PLATFORM MIDDLEWARE
+ * 
+ *  Copyright (C) 2017-2019 by TOPPERS PROJECT
+ *                             Educational Working Group.
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+#ifndef _LCD_CORE_H_
+#define _LCD_CORE_H_
+
+#include "adafruit_ILI9341.h"
+
+#endif /* _LCD_CORE_H_ */
+
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/adafruit_st7735/Makefile.config
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/adafruit_st7735/Makefile.config	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/adafruit_st7735/Makefile.config	(revision 457)
@@ -0,0 +1,55 @@
+#
+#   TOPPERS/ASP/FMP Kernel
+#       Toyohashi Open Platform for Embedded Real-Time Systems/
+#       Advanced Standard Profile Kernel
+#
+#   Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
+#                               Toyohashi Univ. of Technology, JAPAN
+#   Copyright (C) 2003-2008 by Ryosuke Takeuchi
+#                Platform Development Center RICOH COMPANY,LTD. JAPAN
+#   Copyright (C) 2015-2017 by TOPPERS PROJECT Educational Working Group.
+#
+#   上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+#   によって公表されている GNU General Public License の Version 2 に記
+#   述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+#   を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+#   利用と呼ぶ）することを無償で許諾する．
+#   (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+#       権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+#       スコード中に含まれていること．
+#   (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+#       用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+#       者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+#       の無保証規定を掲載すること．
+#   (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+#       用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+#       と．
+#     (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+#         作権表示，この利用条件および下記の無保証規定を掲載すること．
+#     (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+#         報告すること．
+#   (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+#       害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+#
+#   本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+#   よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+#   含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+#   接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+#
+#  @(#) $Id$
+#
+ 
+#
+#  Makefile のプロセッサ依存 (adafruit st7735:LCD用)
+#
+
+#
+#  コンパイルオプション
+#
+INCLUDES := $(INCLUDES) -I$(SRCDIR)/gdic/adafruit_st7735
+
+#
+#  ADAFRUIT ST7735 LCD DRIVER(GDIC)に関する定義
+#
+SYSSVC_DIR := $(SYSSVC_DIR):$(SRCDIR)/gdic/adafruit_st7735
+SYSSVC_COBJS := $(SYSSVC_COBJS) adafruit_st7735.o
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/adafruit_st7735/adafruit_st7735.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/adafruit_st7735/adafruit_st7735.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/adafruit_st7735/adafruit_st7735.c	(revision 457)
@@ -0,0 +1,836 @@
+/*
+ *  TOPPERS/ASP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Advanced Standard Profile Kernel
+ * 
+ *  Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
+ *                              Toyohashi Univ. of Technology, JAPAN
+ *  Copyright (C) 2004-2012 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ *  Copyright (C) 2015-2018 by TOPPERS PROJECT Educational Working Group.
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  $Id$
+ */
+
+/*
+ *  Written by Limor Fried/Ladyada for Adafruit Industries.
+ *  MIT license, all text above must be included in any redistribution
+ *　http://opensource.org/licenses/mit-license.php 
+ */
+
+/* 
+ *  ADAFRUIT ST7735 1.8",1.44"LCD制御プログラムの本体
+ */
+
+#include <kernel.h>
+#include <t_syslog.h>
+#include <t_stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <target_syssvc.h>
+#include "syssvc/serial.h"
+#include "syssvc/syslog.h"
+#include "device.h"
+#include "adafruit_st7735.h"
+
+/*
+ *  サービスコールのエラーのログ出力
+ */
+Inline void
+svc_perror(const char *file, int_t line, const char *expr, ER ercd)
+{
+	if (ercd < 0) {
+		t_perror(LOG_ERROR, file, line, expr, ercd);
+	}
+}
+
+#define	SVC_PERROR(expr)	svc_perror(__FILE__, __LINE__, #expr, (expr))
+#define ABS(X)  ((X) > 0 ? (X) : -(X))
+
+
+// Rather than a bazillion writecommand() and writedata() calls, screen
+// initialization commands and arguments are organized in these tables
+// stored in PROGMEM.  The table may look bulky, but that's mostly the
+// formatting -- storage-wise this is hundreds of bytes more compact
+// than the equivalent code.  Companion function follows.
+#define DELAY 0x80
+static const uint8_t
+  Bcmd[] = {                  // Initialization commands for 7735B screens
+    18,                       // 18 commands in list:
+    ST7735_SWRESET,   DELAY,  //  1: Software reset, no args, w/delay
+      50,                     //     50 ms delay
+    ST7735_SLPOUT ,   DELAY,  //  2: Out of sleep mode, no args, w/delay
+      255,                    //     255 = 500 ms delay
+    ST7735_COLMOD , 1+DELAY,  //  3: Set color mode, 1 arg + delay:
+      0x05,                   //     16-bit color
+      10,                     //     10 ms delay
+    ST7735_FRMCTR1, 3+DELAY,  //  4: Frame rate control, 3 args + delay:
+      0x00,                   //     fastest refresh
+      0x06,                   //     6 lines front porch
+      0x03,                   //     3 lines back porch
+      10,                     //     10 ms delay
+    ST7735_MADCTL , 1      ,  //  5: Memory access ctrl (directions), 1 arg:
+      0x08,                   //     Row addr/col addr, bottom to top refresh
+    ST7735_DISSET5, 2      ,  //  6: Display settings #5, 2 args, no delay:
+      0x15,                   //     1 clk cycle nonoverlap, 2 cycle gate
+                              //     rise, 3 cycle osc equalize
+      0x02,                   //     Fix on VTL
+    ST7735_INVCTR , 1      ,  //  7: Display inversion control, 1 arg:
+      0x0,                    //     Line inversion
+    ST7735_PWCTR1 , 2+DELAY,  //  8: Power control, 2 args + delay:
+      0x02,                   //     GVDD = 4.7V
+      0x70,                   //     1.0uA
+      10,                     //     10 ms delay
+    ST7735_PWCTR2 , 1      ,  //  9: Power control, 1 arg, no delay:
+      0x05,                   //     VGH = 14.7V, VGL = -7.35V
+    ST7735_PWCTR3 , 2      ,  // 10: Power control, 2 args, no delay:
+      0x01,                   //     Opamp current small
+      0x02,                   //     Boost frequency
+    ST7735_VMCTR1 , 2+DELAY,  // 11: Power control, 2 args + delay:
+      0x3C,                   //     VCOMH = 4V
+      0x38,                   //     VCOML = -1.1V
+      10,                     //     10 ms delay
+    ST7735_PWCTR6 , 2      ,  // 12: Power control, 2 args, no delay:
+      0x11, 0x15,
+    ST7735_GMCTRP1,16      ,  // 13: Magical unicorn dust, 16 args, no delay:
+      0x09, 0x16, 0x09, 0x20, //     (seriously though, not sure what
+      0x21, 0x1B, 0x13, 0x19, //      these config values represent)
+      0x17, 0x15, 0x1E, 0x2B,
+      0x04, 0x05, 0x02, 0x0E,
+    ST7735_GMCTRN1,16+DELAY,  // 14: Sparkles and rainbows, 16 args + delay:
+      0x0B, 0x14, 0x08, 0x1E, //     (ditto)
+      0x22, 0x1D, 0x18, 0x1E,
+      0x1B, 0x1A, 0x24, 0x2B,
+      0x06, 0x06, 0x02, 0x0F,
+      10,                     //     10 ms delay
+    ST7735_CASET  , 4      ,  // 15: Column addr set, 4 args, no delay:
+      0x00, 0x02,             //     XSTART = 2
+      0x00, 0x81,             //     XEND = 129
+    ST7735_RASET  , 4      ,  // 16: Row addr set, 4 args, no delay:
+      0x00, 0x02,             //     XSTART = 1
+      0x00, 0x81,             //     XEND = 160
+    ST7735_NORON  ,   DELAY,  // 17: Normal display on, no args, w/delay
+      10,                     //     10 ms delay
+    ST7735_DISPON ,   DELAY,  // 18: Main screen turn on, no args, w/delay
+      255};                   //     255 = 500 ms delay
+
+static const uint8_t
+  Rcmd1[] = {                 // Init for 7735R, part 1 (red or green tab)
+    15,                       // 15 commands in list:
+    ST7735_SWRESET,   DELAY,  //  1: Software reset, 0 args, w/delay
+      150,                    //     150 ms delay
+    ST7735_SLPOUT ,   DELAY,  //  2: Out of sleep mode, 0 args, w/delay
+      255,                    //     500 ms delay
+    ST7735_FRMCTR1, 3      ,  //  3: Frame rate ctrl - normal mode, 3 args:
+      0x01, 0x2C, 0x2D,       //     Rate = fosc/(1x2+40) * (LINE+2C+2D)
+    ST7735_FRMCTR2, 3      ,  //  4: Frame rate control - idle mode, 3 args:
+      0x01, 0x2C, 0x2D,       //     Rate = fosc/(1x2+40) * (LINE+2C+2D)
+    ST7735_FRMCTR3, 6      ,  //  5: Frame rate ctrl - partial mode, 6 args:
+      0x01, 0x2C, 0x2D,       //     Dot inversion mode
+      0x01, 0x2C, 0x2D,       //     Line inversion mode
+    ST7735_INVCTR , 1      ,  //  6: Display inversion ctrl, 1 arg, no delay:
+      0x07,                   //     No inversion
+    ST7735_PWCTR1 , 3      ,  //  7: Power control, 3 args, no delay:
+      0xA2,
+      0x02,                   //     -4.6V
+      0x84,                   //     AUTO mode
+    ST7735_PWCTR2 , 1      ,  //  8: Power control, 1 arg, no delay:
+      0xC5,                   //     VGH25 = 2.4C VGSEL = -10 VGH = 3 * AVDD
+    ST7735_PWCTR3 , 2      ,  //  9: Power control, 2 args, no delay:
+      0x0A,                   //     Opamp current small
+      0x00,                   //     Boost frequency
+    ST7735_PWCTR4 , 2      ,  // 10: Power control, 2 args, no delay:
+      0x8A,                   //     BCLK/2, Opamp current small & Medium low
+      0x2A,  
+    ST7735_PWCTR5 , 2      ,  // 11: Power control, 2 args, no delay:
+      0x8A, 0xEE,
+    ST7735_VMCTR1 , 1      ,  // 12: Power control, 1 arg, no delay:
+      0x0E,
+    ST7735_INVOFF , 0      ,  // 13: Don't invert display, no args, no delay
+    ST7735_MADCTL , 1      ,  // 14: Memory access control (directions), 1 arg:
+      0xC8,                   //     row addr/col addr, bottom to top refresh
+    ST7735_COLMOD , 1      ,  // 15: set color mode, 1 arg, no delay:
+      0x05 };                 //     16-bit color
+
+static const uint8_t
+  Rcmd2green[] = {            // Init for 7735R, part 2 (green tab only)
+    2,                        //  2 commands in list:
+    ST7735_CASET  , 4      ,  //  1: Column addr set, 4 args, no delay:
+      0x00, 0x02,             //     XSTART = 0
+      0x00, 0x7F+0x02,        //     XEND = 127
+    ST7735_RASET  , 4      ,  //  2: Row addr set, 4 args, no delay:
+      0x00, 0x01,             //     XSTART = 0
+      0x00, 0x9F+0x01 };      //     XEND = 159
+
+static const uint8_t
+  Rcmd2red[] = {              // Init for 7735R, part 2 (red tab only)
+    2,                        //  2 commands in list:
+    ST7735_CASET  , 4      ,  //  1: Column addr set, 4 args, no delay:
+      0x00, 0x00,             //     XSTART = 0
+      0x00, 0x7F,             //     XEND = 127
+    ST7735_RASET  , 4      ,  //  2: Row addr set, 4 args, no delay:
+      0x00, 0x00,             //     XSTART = 0
+      0x00, 0x9F };           //     XEND = 159
+
+static const uint8_t
+  Rcmd2green144[] = {              // Init for 7735R, part 2 (green 1.44 tab)
+    2,                        //  2 commands in list:
+    ST7735_CASET  , 4      ,  //  1: Column addr set, 4 args, no delay:
+      0x00, 0x00,             //     XSTART = 0
+      0x00, 0x7F,             //     XEND = 127
+    ST7735_RASET  , 4      ,  //  2: Row addr set, 4 args, no delay:
+      0x00, 0x00,             //     XSTART = 0
+      0x00, 0x7F };           //     XEND = 127
+
+static const uint8_t
+  Rcmd3[] = {                 // Init for 7735R, part 3 (red or green tab)
+    4,                        //  4 commands in list:
+    ST7735_GMCTRP1, 16      , //  1: Magical unicorn dust, 16 args, no delay:
+      0x02, 0x1c, 0x07, 0x12,
+      0x37, 0x32, 0x29, 0x2d,
+      0x29, 0x25, 0x2B, 0x39,
+      0x00, 0x01, 0x03, 0x10,
+    ST7735_GMCTRN1, 16      , //  2: Sparkles and rainbows, 16 args, no delay:
+      0x03, 0x1d, 0x07, 0x06,
+      0x2E, 0x2C, 0x29, 0x2D,
+      0x2E, 0x2E, 0x37, 0x3F,
+      0x00, 0x00, 0x02, 0x10,
+    ST7735_NORON  ,    DELAY, //  3: Normal display on, no args, w/delay
+      10,                     //     10 ms delay
+    ST7735_DISPON ,    DELAY, //  4: Main screen turn on, no args w/delay
+      100 };                  //     100 ms delay
+
+
+
+
+/* Buffer used for transmission */
+static uint8_t aTxBuffer[4];
+
+#define PORT_HIGH           1
+#define PORT_LOW            0
+
+#define cs_set(sw)  digitalWrite(hlcd->cs_pin, sw)
+#define rs_set(sw)  digitalWrite(hlcd->rs_pin, sw)
+#define rst_set(sw) digitalWrite(hlcd->rst_pin, sw)
+#define cs2_set(sw) digitalWrite(hlcd->cs2_pin, sw)
+
+/*
+ *  LCDへのコマンド送信関数
+ */
+ER
+lcd_writecommand(LCD_Handler_t *hlcd, uint8_t c)
+{
+	ER ercd = E_OK;
+
+	if(hlcd->spi_lock != 0){
+		if((ercd = wai_sem(hlcd->spi_lock)) != E_OK)
+			return ercd;
+	}
+	rs_set(PORT_LOW);
+	cs_set(PORT_LOW);
+
+	aTxBuffer[0] = c;
+#if SPI_WAIT_TIME != 0
+	ercd = spi_transmit(hlcd->hspi, (uint8_t*)aTxBuffer, 1);
+#else
+	if((ercd = spi_transmit(hlcd->hspi, (uint8_t*)aTxBuffer, 1)) == E_OK){
+		ercd = spi_wait(hlcd->hspi, 100);
+	}
+#endif
+
+	cs_set(PORT_HIGH);
+	if(hlcd->spi_lock != 0)
+		sig_sem(hlcd->spi_lock);
+	return ercd;
+}
+
+/*
+ *  LCDへのデータ送信関数
+ */
+ER
+lcd_writedata(LCD_Handler_t *hlcd, uint8_t *p, uint32_t len)
+{
+	ER ercd = E_OK;
+
+	if(hlcd->spi_lock != 0){
+		if((ercd = wai_sem(hlcd->spi_lock)) != E_OK)
+			return ercd;
+	}
+	rs_set(PORT_HIGH);
+	cs_set(PORT_LOW);
+	sil_dly_nse(100);
+
+#if SPI_WAIT_TIME != 0
+	ercd = spi_transmit(hlcd->hspi, (uint8_t*)p, len);
+#else
+	if((ercd = spi_transmit(hlcd->hspi, (uint8_t*)p, len)) == E_OK){
+		ercd = spi_wait(hlcd->hspi, 100);
+	}
+#endif
+
+	sil_dly_nse(100);
+	cs_set(PORT_HIGH);
+	if(hlcd->spi_lock != 0)
+		sig_sem(hlcd->spi_lock);
+	return ercd;
+}
+
+/*
+ *  LCDへの２バイトデータ送信関数
+ */
+ER
+lcd_writedata2(LCD_Handler_t *hlcd, uint16_t c, int cnt)
+{
+	ER  ercd = E_OK;
+	int i;
+
+	if(cnt == 0)
+		return ercd;
+	if(hlcd->spi_lock != 0){
+		if((ercd = wai_sem(hlcd->spi_lock)) != E_OK)
+			return ercd;
+	}
+	rs_set(PORT_HIGH);
+	cs_set(PORT_LOW);
+	sil_dly_nse(100);
+	aTxBuffer[0] = c>>8;
+	aTxBuffer[1] = (uint8_t)c;
+	for(i = 0 ; i < cnt ; i++){
+		if((ercd = spi_transmit(hlcd->hspi, (uint8_t*)aTxBuffer, 2)) != E_OK){
+			break;
+		}
+#if SPI_WAIT_TIME == 0
+		if((ercd = spi_wait(hlcd->hspi, 100)) != E_OK){
+			break;
+		}
+#endif
+	}
+	sil_dly_nse(100);
+	cs_set(PORT_HIGH);
+	if(hlcd->spi_lock != 0)
+		sig_sem(hlcd->spi_lock);
+	return ercd;
+}
+
+/*
+ *  LCDへのRGBデータ送信関数
+ */
+ER
+lcd_writedata3(LCD_Handler_t *hlcd, uint8_t *pbmp, uint16_t width, uint16_t height)
+{
+	ER  ercd = E_OK;
+	int index, i;
+
+	if(width == 0 || height == 0)
+		return ercd;
+	if(hlcd->spi_lock != 0){
+		if((ercd = wai_sem(hlcd->spi_lock)) != E_OK)
+			return ercd;
+	}
+	rs_set(PORT_HIGH);
+	cs_set(PORT_LOW);
+	sil_dly_nse(100);
+	for(index=0; index < height; index++){
+		uint8_t *p = pbmp;
+		for (i = 0; i < width; i++){
+			aTxBuffer[0]  = (*p++) & 0xf8;
+			aTxBuffer[0] |= *p >> 5;
+			aTxBuffer[1]  = (*p++ << 3) & 0xE0;
+			aTxBuffer[1] |= (*p++ >> 3) & 0x1F;
+			if((ercd = spi_transmit(hlcd->hspi, (uint8_t*)aTxBuffer, 2)) != E_OK){
+				break;
+			}
+#if SPI_WAIT_TIME == 0
+			if((ercd = spi_wait(hlcd->hspi, 100)) != E_OK){
+				break;
+			}
+#endif
+		}
+		pbmp -= width*3;
+	}
+	sil_dly_nse(100);
+	cs_set(PORT_HIGH);
+	if(hlcd->spi_lock != 0)
+		sig_sem(hlcd->spi_lock);
+	return ercd;
+}
+
+/*
+ *  ST7735へのコマンドリスト送信
+ */
+static void
+Adafruit_ST7735_commandList(LCD_Handler_t *hlcd, const uint8_t *addr)
+{
+	uint8_t  numCommands, numArgs;
+	uint8_t  data[4];
+	uint16_t ms;
+
+	numCommands = *addr++;   // Number of commands to follow
+	while(numCommands--) {                 // For each command...
+		SVC_PERROR(lcd_writecommand(hlcd, *addr++)); //   Read, issue command
+		numArgs  = *addr++;    //   Number of args to follow
+		ms       = numArgs & DELAY;          //   If hibit set, delay follows args
+		numArgs &= ~DELAY;                   //   Mask out delay bit
+		while(numArgs--) {                   //   For each argument...
+			data[0] = *addr++;
+			SVC_PERROR(lcd_writedata(hlcd, data, 1));  //     Read, issue argument
+		}
+
+		if(ms) {
+			ms = *addr++; // Read post-command delay time (ms)
+			if(ms == 255) ms = 500;     // If 255, delay for 500 ms
+			dly_tsk(ms);
+		}
+	}
+}
+
+
+/*
+ *  ST7735B または ST7735RタイプのLEDの共通初期化関数
+ */
+static void
+Adafruit_ST7735_commonInit(LCD_Handler_t *hlcd, const uint8_t *cmdList)
+{
+	hlcd->colstart  = hlcd->rowstart = 0; // May be overridden in init func
+	hlcd->_width = ST7735_TFTWIDTH;
+	hlcd->_height = ST7735_TFTHEIGHT_18;
+
+	// toggle RST low to reset; CS low so it'll listen to us
+	cs_set(PORT_LOW);
+	rst_set(PORT_HIGH);
+	dly_tsk(500);
+	rst_set(PORT_LOW);
+	dly_tsk(500);
+	rst_set(PORT_HIGH);
+
+	if(cmdList) Adafruit_ST7735_commandList(hlcd, cmdList);
+}
+
+
+/*
+ *  表示ウィンドウ設定
+ */
+void
+lcd_setAddrWindow(LCD_Handler_t *hlcd, uint8_t x0, uint8_t y0, uint8_t x1, uint8_t y1)
+{
+	uint8_t  data[4];
+
+	SVC_PERROR(lcd_writecommand(hlcd, ST7735_CASET)); // Column addr set
+	data[0] = (uint8_t)((x0 + hlcd->colstart) >> 8);
+	data[1] = (uint8_t)(x0 + hlcd->colstart);		// XSTART
+	data[2] = (uint8_t)((x1 + hlcd->colstart) >> 8);
+	data[3] = (uint8_t)(x1 + hlcd->colstart);		// XEND
+	SVC_PERROR(lcd_writedata(hlcd, data, 4));
+
+	SVC_PERROR(lcd_writecommand(hlcd, ST7735_RASET)); // Row addr set
+	data[0] = (uint8_t)((y0 + hlcd->rowstart) >> 8);
+	data[1] = (uint8_t)(y0 + hlcd->rowstart);		// YSTART
+	data[2] = (uint8_t)((y1 + hlcd->rowstart) >> 8);
+	data[3] = (uint8_t)(y1 + hlcd->rowstart);		// YEND
+	SVC_PERROR(lcd_writedata(hlcd, data, 4));
+
+	SVC_PERROR(lcd_writecommand(hlcd, ST7735_RAMWR)); // write to RAM
+}
+
+/*
+ *  ST7735B screensの初期化関数
+ */
+void
+lcd_initB(LCD_Handler_t *hlcd)
+{
+	Adafruit_ST7735_commonInit(hlcd, Bcmd);
+}
+
+/*
+ *  ST7735R screens (green or red tabs)の初期化関数
+ */
+void
+lcd_initR(LCD_Handler_t *hlcd, uint8_t options)
+{
+	uint8_t data[4];
+
+	Adafruit_ST7735_commonInit(hlcd, Rcmd1);
+
+	if(options == INITR_GREENTAB){
+		Adafruit_ST7735_commandList(hlcd, Rcmd2green);
+		hlcd->colstart = 2;
+		hlcd->rowstart = 1;
+	}
+	else if(options == INITR_144GREENTAB){
+		hlcd->_height = ST7735_TFTHEIGHT_144;
+		Adafruit_ST7735_commandList(hlcd, Rcmd2green144);
+ 		hlcd->colstart = 2;
+		hlcd->rowstart = 3;
+	}
+	else{
+		// colstart, rowstart left at default '0' values
+		Adafruit_ST7735_commandList(hlcd, Rcmd2red);
+	}
+	Adafruit_ST7735_commandList(hlcd, Rcmd3);
+
+	// if black, change MADCTL color filter
+	if(options == INITR_BLACKTAB){
+		SVC_PERROR(lcd_writecommand(hlcd, ST7735_MADCTL));
+		data[0] = 0xC0;
+		SVC_PERROR(lcd_writedata(hlcd, data, 1));
+	}
+	syslog_2(LOG_NOTICE, "## width(%d) height(%d) ##", hlcd->_width, hlcd->_height);
+	hlcd->tabcolor = options;
+}
+
+/*
+ *  RECTANGLEのフィル描画
+ *  param1  hlcd: Pointer to LCD Handler
+ *  param2  x: start X position
+ *  param3  y: start Y position
+ *  param4  w: width
+ *  param5  h: height
+ *  param6  color: color value
+ */
+void
+lcd_fillRect(LCD_Handler_t *hlcd, int16_t x, int16_t y, int16_t w, int16_t h, color_t color)
+{
+	// rudimentary clipping (drawChar w/big text requires this)
+	if((x >= hlcd->_width) || (y >= hlcd->_height)) return;
+	if((x + w - 1) >= hlcd->_width)  w = hlcd->_width  - x;
+	if((y + h - 1) >= hlcd->_height) h = hlcd->_height - y;
+
+	lcd_setAddrWindow(hlcd, x, y, x+w-1, y+h-1);
+	SVC_PERROR(lcd_writedata2(hlcd, color, h*w));
+}
+
+void
+lcd_pushColor(LCD_Handler_t *hlcd, color_t color)
+{
+	SVC_PERROR(lcd_writedata2(hlcd, color, 1));
+}
+
+/*
+ *  PIXEL描画
+ *  param1  hlcd: Pointer to LCD Handler
+ *  param2  x: X position
+ *  param3  y: Y position
+ *  param4  color: color value
+ */
+void
+lcd_drawPixel(LCD_Handler_t *hlcd, int16_t x, int16_t y, color_t color)
+{
+	if((x < 0) ||(x >= hlcd->_width) || (y < 0) || (y >= hlcd->_height)) return;
+
+	lcd_setAddrWindow(hlcd, x, y, x, y);
+	SVC_PERROR(lcd_writedata2(hlcd, color, 1));
+}
+
+/*
+ *  垂直方向LINEの高速描画
+ *  param1  hlcd: Pointer to LCD Handler
+ *  param2  x: start X position
+ *  param3  y: start Y position
+ *  param4  h: height
+ *  param5  color: color value
+ */
+void
+lcd_drawFastVLine(LCD_Handler_t *hlcd, int16_t x, int16_t y, int16_t h, color_t color)
+{
+	// Rudimentary clipping
+	if((x >= hlcd->_width) || (y >= hlcd->_height)) return;
+	if((y+h-1) >= hlcd->_height) h = hlcd->_height-y;
+	lcd_setAddrWindow(hlcd, x, y, x, y+h-1);
+	SVC_PERROR(lcd_writedata2(hlcd, color, h));
+}
+
+/*
+ *  水平方向LINEの高速描画
+ *  param1  hlcd: Pointer to LCD Handler
+ *  param2  x: start X position
+ *  param3  y: start Y position
+ *  param4  w: width
+ *  param5  color: color value
+ */
+void lcd_drawFastHLine(LCD_Handler_t *hlcd, int16_t x, int16_t y, int16_t w, color_t color)
+{
+	// Rudimentary clipping
+	if((x >= hlcd->_width) || (y >= hlcd->_height)) return;
+	if((x+w-1) >= hlcd->_width)  w = hlcd->_width-x;
+	lcd_setAddrWindow(hlcd, x, y, x+w-1, y);
+	SVC_PERROR(lcd_writedata2(hlcd, color, w));
+}
+
+/*
+ *  DRAW IMAGE LINE描画
+ *  param1  hlcd: Pointer to LCD Handler
+ *  param2  x: X position
+ *  param3  y: Y position
+ *  param4  w: width
+ *  param5  pcolor: color value
+ */
+void
+lcd_drawImageHLine(LCD_Handler_t *hlcd, int16_t x, int16_t y, uint16_t w, color_t *pcolor)
+{
+	uint32_t i;
+
+	if((x >= hlcd->_width) || (y >= hlcd->_height)) return;
+	if((x+w-1) >= hlcd->_width)  w = hlcd->_width-x;
+
+	lcd_setAddrWindow(hlcd, x, y, x+w-1, y);
+	for(i = 0 ; i < w ; i++, pcolor++)
+		SVC_PERROR(lcd_writedata2(hlcd, *pcolor, 1));
+}
+
+/*
+ *  BITMAP描画
+ *  param1  hlcd: Pointer to LCD Handler
+ *  param2  x0: Bmp X position in the LCD
+ *  param3  y0: Bmp Y position in the LCD
+ *  param4  pbmp: Pointer to Bmp picture address in the internal Flash
+ */
+void
+lcd_drawBitmap(LCD_Handler_t *hlcd, uint16_t x0, uint16_t y0, uint8_t *pbmp)
+{
+	uint32_t index = 0, width = 0, height = 0, bit_pixel = 0;
+	uint32_t input_color_mode = 0;
+
+	/* Get bitmap data address offset */
+	index = *(uint16_t *) (pbmp + 10);
+	index |= (*(uint16_t *) (pbmp + 12)) << 16;
+
+	/* Read bitmap width */
+	width = *(uint16_t *) (pbmp + 18);
+	width |= (*(uint16_t *) (pbmp + 20)) << 16;
+
+	/* Read bitmap height */
+	height = *(uint16_t *) (pbmp + 22);
+	height |= (*(uint16_t *) (pbmp + 24)) << 16;
+
+	/* Read bit/pixel */
+	bit_pixel = *(uint16_t *) (pbmp + 28);
+
+	/* Get the layer pixel format */
+	if ((bit_pixel/8) == 4){
+		input_color_mode = CM_ARGB8888;
+	}
+	else if ((bit_pixel/8) == 2){
+		input_color_mode = CM_RGB565;
+	}
+	else{
+		input_color_mode = CM_RGB888;
+	}
+
+	/* Bypass the bitmap header */
+	pbmp += (index + (width * (height - 1) * (bit_pixel/8)));  
+	syslog_4(LOG_NOTICE, "## input_color_mode(%d) width(%d) height(%d) bit_pixel(%d) ##", input_color_mode, width, height, bit_pixel);
+
+	lcd_setAddrWindow(hlcd, x0, y0, x0+width-1, y0+height-1);
+	lcd_writedata3(hlcd, pbmp, width, height);
+}
+
+/*
+ *  INVERT DISPLAY
+ *  param1  hlcd: Pointer to LCD Handler
+ *  param2  i: invert value
+ */
+void
+lcd_invertDisplay(LCD_Handler_t *hlcd, bool_t i)
+{
+  SVC_PERROR(lcd_writecommand(hlcd, i ? ST7735_INVON : ST7735_INVOFF));
+}
+
+
+/*
+ *  スクリーンフィル
+ *  param1  pDrawProp: Pointer to Draw Prop
+ */
+void
+lcd_fillScreen(LCD_DrawProp_t *pDrawProp)
+{
+	lcd_fillRect(pDrawProp->hlcd, 0, 0,  pDrawProp->hlcd->_width, pDrawProp->hlcd->_height, pDrawProp->BackColor);
+}
+
+/*
+ *  RECTANGLE描画
+ *  param1  pDrawProp: Pointer to Draw Prop
+ *  param2  x: left X position
+ *  param3  y: top Y position
+ *  param4  w: width
+ *  param5  h: height
+ */
+void
+lcd_drawRect(LCD_DrawProp_t *pDrawProp, int16_t x, int16_t y, int16_t w, int16_t h)
+{
+	LCD_Handler_t *hlcd = pDrawProp->hlcd;
+	color_t color;
+
+	// rudimentary clipping (drawChar w/big text requires this)
+	if((x >= hlcd->_width) || (y >= hlcd->_height)) return;
+	if((x + w - 1) >= hlcd->_width)  w = hlcd->_width  - x;
+	if((y + h - 1) >= hlcd->_height) h = hlcd->_height - y;
+
+	color = pDrawProp->TextColor;
+	lcd_drawFastVLine(hlcd, x, y, h, color);
+	lcd_drawFastHLine(hlcd, x, y+h-1, w, color);
+	lcd_drawFastVLine(hlcd, x+w-1, y, h, color);
+	lcd_drawFastHLine(hlcd, x, y, w, color);
+}
+
+/*
+ *  円描画
+ *  param1  pDrawProp: Pointer to Draw Prop
+ *  param2  x0: X position
+ *  param3  y0: Y position
+ *  param4  Radius: Circle radius
+ */
+void
+lcd_DrawCircle(LCD_DrawProp_t *pDrawProp, uint16_t x0, uint16_t y0, uint16_t Radius)
+{
+	LCD_Handler_t *hlcd = pDrawProp->hlcd;
+ 	int32_t   decision;    /* Decision Variable */ 
+	uint32_t  current_x;   /* Current X Value */
+	uint32_t  current_y;   /* Current Y Value */
+
+	decision = 3 - (Radius << 1);
+	current_x = 0;
+	current_y = Radius;
+
+	while(current_x <= current_y){
+		lcd_drawPixel(hlcd, (x0 + current_x), (y0 - current_y), pDrawProp->TextColor);
+		lcd_drawPixel(hlcd, (x0 - current_x), (y0 - current_y), pDrawProp->TextColor);
+		lcd_drawPixel(hlcd, (x0 + current_y), (y0 - current_x), pDrawProp->TextColor);
+		lcd_drawPixel(hlcd, (x0 - current_y), (y0 - current_x), pDrawProp->TextColor);
+		lcd_drawPixel(hlcd, (x0 + current_x), (y0 + current_y), pDrawProp->TextColor);
+		lcd_drawPixel(hlcd, (x0 - current_x), (y0 + current_y), pDrawProp->TextColor);
+		lcd_drawPixel(hlcd, (x0 + current_y), (y0 + current_x), pDrawProp->TextColor);
+		lcd_drawPixel(hlcd, (x0 - current_y), (y0 + current_x), pDrawProp->TextColor);
+
+		if (decision < 0){
+			decision += (current_x << 2) + 6;
+		}
+		else{
+			decision += ((current_x - current_y) << 2) + 10;
+			current_y--;
+		}
+		current_x++;
+	}
+}
+
+/*
+ *  線描画
+ *  param1  pDrawProp: Pointer to Draw Prop
+ *  param2  x1: Point 1 X position
+ *  param3  y1: Point 1 Y position
+ *  param4  x2: Point 2 X position
+ *  param5  y2: Point 2 Y position
+ */
+void
+lcd_drawLine(LCD_DrawProp_t *pDrawProp, uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2)
+{
+	LCD_Handler_t *hlcd = pDrawProp->hlcd;
+	int16_t deltax = 0, deltay = 0, x = 0, y = 0, xinc1 = 0, xinc2 = 0, 
+	yinc1 = 0, yinc2 = 0, den = 0, num = 0, num_add = 0, num_pixels = 0, 
+	curpixel = 0;
+
+	deltax = ABS(x2 - x1);		/* The difference between the x's */
+	deltay = ABS(y2 - y1);		/* The difference between the y's */
+	x = x1;						/* Start x off at the first pixel */
+	y = y1;						/* Start y off at the first pixel */
+
+	if(x2 >= x1){				/* The x-values are increasing */
+		xinc1 = 1;
+		xinc2 = 1;
+	}
+	else{						/* The x-values are decreasing */
+		xinc1 = -1;
+		xinc2 = -1;
+	}
+
+	if(y2 >= y1){				/* The y-values are increasing */
+		yinc1 = 1;
+		yinc2 = 1;
+	}
+	else{						/* The y-values are decreasing */
+		yinc1 = -1;
+		yinc2 = -1;
+	}
+
+	if(deltax >= deltay){		/* There is at least one x-value for every y-value */
+		xinc1 = 0;				/* Don't change the x when numerator >= denominator */
+		yinc2 = 0;				/* Don't change the y for every iteration */
+		den = deltax;
+		num = deltax / 2;
+		num_add = deltay;
+		num_pixels = deltax;	/* There are more x-values than y-values */
+	}
+	else{						/* There is at least one y-value for every x-value */
+		xinc2 = 0;				/* Don't change the x for every iteration */
+		yinc1 = 0;				/* Don't change the y when numerator >= denominator */
+		den = deltay;
+		num = deltay / 2;
+		num_add = deltax;
+		num_pixels = deltay;	/* There are more y-values than x-values */
+	}
+
+	for (curpixel = 0; curpixel <= num_pixels; curpixel++){
+		lcd_drawPixel(hlcd, x, y, pDrawProp->TextColor);	/* Draw the current pixel */
+		num += num_add;			/* Increase the numerator by the top of the fraction */
+		if(num >= den){			/* Check if numerator >= denominator */
+			num -= den;			/* Calculate the new numerator value */
+			x += xinc1;			/* Change the x as appropriate */
+			y += yinc1;			/* Change the y as appropriate */
+		}
+		x += xinc2;				/* Change the x as appropriate */
+		y += yinc2;				/* Change the y as appropriate */
+	}
+}
+
+/*
+ *  PLOY-LINE描画
+ *  param1  pDrawProp: Pointer to Draw Prop
+ *  param2  Points: Pointer to the points array
+ *  param3  PointCount: Number of points
+ */
+void
+lcd_drawPolygon(LCD_DrawProp_t *pDrawProp, pPoint Points, uint16_t PointCount)
+{
+	int16_t x = 0, y = 0;
+
+	if(PointCount < 2){
+		return;
+	}
+
+	lcd_drawLine(pDrawProp, Points->X, Points->Y, (Points+PointCount-1)->X, (Points+PointCount-1)->Y);
+	while(--PointCount){
+		x = Points->X;
+		y = Points->Y;
+		Points++;
+		lcd_drawLine(pDrawProp, x, y, Points->X, Points->Y);
+	}
+}
+
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/adafruit_st7735/adafruit_st7735.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/adafruit_st7735/adafruit_st7735.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/adafruit_st7735/adafruit_st7735.h	(revision 457)
@@ -0,0 +1,221 @@
+/*
+ *  TOPPERS/ASP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Advanced Standard Profile Kernel
+ *
+ *  Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
+ *                              Toyohashi Univ. of Technology, JAPAN
+ *  Copyright (C) 2004-2010 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ *  Copyright (C) 2015-2019 by TOPPERS PROJECT Educational Working Group.
+ *
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ *
+ *  $Id$
+ */
+
+/*
+ *  Written by Limor Fried/Ladyada for Adafruit Industries.
+ *  MIT license, all text above must be included in any redistribution
+ *　http://opensource.org/licenses/mit-license.php 
+ */
+
+/*
+ *  ADAFRUIT ST7735 1.8",1.44"LCD制御プログラムのヘッダファイル
+ */
+
+#ifndef _ADAFRUIT_ST7735_H_
+#define _ADAFRUIT_ST7735_H_
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+#include "device.h"
+#include "pinmode.h"
+#include "spi.h"
+
+/*
+ *  LCDカラーモード定義
+ */
+#define CM_ARGB8888         0x00000000			/* ARGB8888 color mode */
+#define CM_RGB888           0x00000001			/* RGB888 color mode */
+#define CM_RGB565           0x00000002			/* RGB565 color mode */
+
+// some flags for initR() :(
+#define INITR_GREENTAB 0x0
+#define INITR_REDTAB   0x1
+#define INITR_BLACKTAB   0x2
+
+#define INITR_18GREENTAB    INITR_GREENTAB
+#define INITR_18REDTAB      INITR_REDTAB
+#define INITR_18BLACKTAB    INITR_BLACKTAB
+#define INITR_144GREENTAB   0x1
+
+#define ST7735_TFTWIDTH  128
+// for 1.44" display
+#define ST7735_TFTHEIGHT_144 128
+// for 1.8" display
+#define ST7735_TFTHEIGHT_18  160
+
+#define ST7735_NOP     0x00
+#define ST7735_SWRESET 0x01
+#define ST7735_RDDID   0x04
+#define ST7735_RDDST   0x09
+
+#define ST7735_SLPIN   0x10
+#define ST7735_SLPOUT  0x11
+#define ST7735_PTLON   0x12
+#define ST7735_NORON   0x13
+
+#define ST7735_INVOFF  0x20
+#define ST7735_INVON   0x21
+#define ST7735_DISPOFF 0x28
+#define ST7735_DISPON  0x29
+#define ST7735_CASET   0x2A
+#define ST7735_RASET   0x2B
+#define ST7735_RAMWR   0x2C
+#define ST7735_RAMRD   0x2E
+
+#define ST7735_PTLAR   0x30
+#define ST7735_COLMOD  0x3A
+#define ST7735_MADCTL  0x36
+
+#define ST7735_FRMCTR1 0xB1
+#define ST7735_FRMCTR2 0xB2
+#define ST7735_FRMCTR3 0xB3
+#define ST7735_INVCTR  0xB4
+#define ST7735_DISSET5 0xB6
+
+#define ST7735_PWCTR1  0xC0
+#define ST7735_PWCTR2  0xC1
+#define ST7735_PWCTR3  0xC2
+#define ST7735_PWCTR4  0xC3
+#define ST7735_PWCTR5  0xC4
+#define ST7735_VMCTR1  0xC5
+
+#define ST7735_RDID1   0xDA
+#define ST7735_RDID2   0xDB
+#define ST7735_RDID3   0xDC
+#define ST7735_RDID4   0xDD
+
+#define ST7735_PWCTR6  0xFC
+
+#define ST7735_GMCTRP1 0xE0
+#define ST7735_GMCTRN1 0xE1
+
+// Color definitions
+#define	ST7735_BLACK   0x0000
+#define	ST7735_BLUE    0x001F
+#define	ST7735_RED     0xF800
+#define	ST7735_GREEN   0x07E0
+#define ST7735_CYAN    0x07FF
+#define ST7735_MAGENTA 0xF81F
+#define ST7735_YELLOW  0xFFE0
+#define ST7735_WHITE   0xFFFF
+
+
+#ifndef TOPPERS_MACRO_ONLY
+
+/*
+ *  カラーの属性を定義
+ */
+typedef uint16_t   color_t;
+
+/*
+ *  LCDハンドラ構造体定義
+ */
+typedef struct
+{
+	SPI_Handle_t            *hspi;		/* spiハンドラ */
+	uint16_t                _width;		/* 幅ピクセル数 */
+	uint16_t				_height;	/* 高さピクセル数 */
+	uint8_t                 colstart;
+	uint8_t                 rowstart;
+	uint8_t                 tabcolor;	/* some displays need this changed */
+	uint8_t                 dummy;
+	ID                      spi_lock;
+	uint8_t                 cs_pin;
+	uint8_t                 rs_pin;
+	uint8_t                 rst_pin;
+	uint8_t                 cs2_pin;
+}LCD_Handler_t;
+
+/*
+ *  描画構造体
+ */
+typedef struct
+{
+	LCD_Handler_t           *hlcd;
+	color_t                 TextColor;
+	color_t                 BackColor;
+	void                    *pFont;
+}LCD_DrawProp_t;
+
+typedef struct
+{
+	int16_t X;
+	int16_t Y;
+}Point, * pPoint;
+
+/*
+ *  関数のプロトタイプ宣言
+ */
+extern ER lcd_writecommand(LCD_Handler_t *hlcd, uint8_t c);
+extern ER lcd_writedata(LCD_Handler_t *hlcd, uint8_t *p, uint32_t len);
+extern ER lcd_writedata2(LCD_Handler_t *hlcd, uint16_t c, int cnt);
+extern ER lcd_writedata3(LCD_Handler_t *hlcd, uint8_t *pbmp, uint16_t width, uint16_t height);
+
+extern void lcd_initB(LCD_Handler_t *hlcd);
+extern void lcd_initR(LCD_Handler_t *hlcd, uint8_t options);
+extern void lcd_setAddrWindow(LCD_Handler_t *hlcd, uint8_t x0, uint8_t y0, uint8_t x1, uint8_t y1);
+extern void lcd_fillRect(LCD_Handler_t *hlcd, int16_t x, int16_t y, int16_t w, int16_t h, color_t color);
+extern void lcd_pushColor(LCD_Handler_t *hlcd, color_t color);
+extern void lcd_drawPixel(LCD_Handler_t *hlcd, int16_t x, int16_t y, color_t color);
+extern void lcd_drawFastVLine(LCD_Handler_t *hlcd, int16_t x, int16_t y, int16_t h, color_t color);
+extern void lcd_drawFastHLine(LCD_Handler_t *hlcd, int16_t x, int16_t y, int16_t w, color_t color);
+extern void lcd_drawImageHLine(LCD_Handler_t *hlcd, int16_t x, int16_t y, uint16_t w, color_t *pcolor);
+extern void lcd_drawBitmap(LCD_Handler_t *hlcd, uint16_t x0, uint16_t y0, uint8_t *pbmp);
+extern void lcd_invertDisplay(LCD_Handler_t *hlcd, bool_t i);
+
+extern void lcd_fillScreen(LCD_DrawProp_t *pDrawProp);
+extern void lcd_drawRect(LCD_DrawProp_t *pDrawProp, int16_t x, int16_t y, int16_t w, int16_t h);
+extern void lcd_DrawCircle(LCD_DrawProp_t *pDrawProp, uint16_t x0, uint16_t y0, uint16_t Radius);
+extern void lcd_drawLine(LCD_DrawProp_t *pDrawProp, uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2);
+extern void lcd_drawPolygon(LCD_DrawProp_t *pDrawProp, pPoint Points, uint16_t PointCount);
+
+#endif /* TOPPERS_MACRO_ONLY */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif	/* _ADAFRUIT_ST7735_H_ */
+
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/adafruit_st7735/glcd_core.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/adafruit_st7735/glcd_core.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/adafruit_st7735/glcd_core.h	(revision 457)
@@ -0,0 +1,45 @@
+/*
+ *  TOPPERS BASE PLATFORM MIDDLEWARE
+ * 
+ *  Copyright (C) 2017-2018 by TOPPERS PROJECT
+ *                             Educational Working Group.
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+#ifndef _LCD_CORE_H_
+#define _LCD_CORE_H_
+
+#include "adafruit_st7735.h"
+
+#endif /* _LCD_CORE_H_ */
+
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/adafruit_st7789/Makefile.config
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/adafruit_st7789/Makefile.config	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/adafruit_st7789/Makefile.config	(revision 457)
@@ -0,0 +1,49 @@
+#
+#   TOPPERS BASE PLATFORM MIDDLEWARE
+#
+#   Copyright (C) 2015-2019 by TOPPERS PROJECT Educational Working Group.
+#
+#   上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+#   によって公表されている GNU General Public License の Version 2 に記
+#   述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+#   を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+#   利用と呼ぶ）することを無償で許諾する．
+#   (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+#       権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+#       スコード中に含まれていること．
+#   (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+#       用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+#       者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+#       の無保証規定を掲載すること．
+#   (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+#       用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+#       と．
+#     (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+#         作権表示，この利用条件および下記の無保証規定を掲載すること．
+#     (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+#         報告すること．
+#   (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+#       害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+#
+#   本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+#   よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+#   含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+#   接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+#
+#  @(#) $Id$
+#
+ 
+#
+#  Makefile のプロセッサ依存 (adafruit st7789:LCD用)
+#
+
+#
+#  コンパイルオプション
+#
+INCLUDES := $(INCLUDES) -I$(SRCDIR)/gdic/adafruit_st7789
+
+#
+#  ADAFRUIT ST7735 LCD DRIVER(GDIC)に関する定義
+#
+SYSSVC_DIR := $(SYSSVC_DIR):$(SRCDIR)/gdic/adafruit_st7789
+SYSSVC_COBJS := $(SYSSVC_COBJS) adafruit_st7789.o
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/adafruit_st7789/adafruit_st7789.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/adafruit_st7789/adafruit_st7789.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/adafruit_st7789/adafruit_st7789.c	(revision 457)
@@ -0,0 +1,754 @@
+/*
+ *  TOPPERS/ASP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Advanced Standard Profile Kernel
+ * 
+ *  Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
+ *                              Toyohashi Univ. of Technology, JAPAN
+ *  Copyright (C) 2004-2012 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ *  Copyright (C) 2015-2020 by TOPPERS PROJECT Educational Working Group.
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  $Id$
+ */
+
+/*
+ *  Written by Limor Fried/Ladyada for Adafruit Industries.
+ *  MIT license, all text above must be included in any redistribution
+ *　http://opensource.org/licenses/mit-license.php 
+ */
+
+/* 
+ *  ADAFRUIT ST7789 LCD制御プログラムの本体
+ */
+
+#include <kernel.h>
+#include <t_syslog.h>
+#include <t_stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <target_syssvc.h>
+#include "syssvc/serial.h"
+#include "syssvc/syslog.h"
+#include "device.h"
+#include "adafruit_st7789.h"
+
+/*
+ *  サービスコールのエラーのログ出力
+ */
+Inline void
+svc_perror(const char *file, int_t line, const char *expr, ER ercd)
+{
+	if (ercd < 0) {
+		t_perror(LOG_ERROR, file, line, expr, ercd);
+	}
+}
+
+#define	SVC_PERROR(expr)	svc_perror(__FILE__, __LINE__, #expr, (expr))
+#define ABS(X)  ((X) > 0 ? (X) : -(X))
+
+
+// Rather than a bazillion writecommand() and writedata() calls, screen
+// initialization commands and arguments are organized in these tables
+// stored in PROGMEM.  The table may look bulky, but that's mostly the
+// formatting -- storage-wise this is hundreds of bytes more compact
+// than the equivalent code.  Companion function follows.
+#define DELAY 0x80
+static const uint8_t
+  Gcmd[] = {                  // Initialization commands for 7789 screens
+    9,                        // 9 commands in list:
+    ST7789_SWRESET,   DELAY,  //  1: Software reset, no args, w/delay
+      150,                    //     150 ms delay
+    ST7789_SLPOUT ,   DELAY,  //  2: Out of sleep mode, no args, w/delay
+      10,                     //     10 ms delay
+    ST7789_COLMOD , 1+DELAY,  //  3: Set color mode, 1 arg + delay:
+      0x55,                   //     16-bit color
+      10,                     //     10 ms delay
+    ST7789_MADCTL , 1,        //  4: Mem access ctrl (directions), 1 arg:
+      0x08,                   //     Row/col addr, bottom-top refresh
+    ST7789_CASET  , 4,        //  5: Column addr set, 4 args, no delay:
+      0x00,                   //
+      0,                      //     XSTART = 0
+      0,                      //
+      240,                    //     XEND = 240
+    ST7789_RASET  , 4,        //  6: Row addr set, 4 args, no delay:
+      0x00,
+      0,                      //     YSTART = 0
+      320>>8,
+      320&0xFF,               //     YEND = 320
+    ST7789_INVON  ,   DELAY,  //  7: hack
+      10,                     //     10 ms delay
+    ST7789_NORON  ,   DELAY,  //  8: Normal display on, no args, w/delay
+      10,                     //     10 ms delay
+    ST7789_DISPON ,   DELAY,  //  9: Main screen turn on, no args, delay
+      10 };                   //    10 ms delay
+
+
+
+
+/* Buffer used for transmission */
+static uint8_t aTxBuffer[4];
+
+#define PORT_HIGH           1
+#define PORT_LOW            0
+
+#define cs_set(sw)  digitalWrite(hlcd->cs_pin, sw)
+#define rs_set(sw)  digitalWrite(hlcd->rs_pin, sw)
+#define rst_set(sw) digitalWrite(hlcd->rst_pin, sw)
+#define cs2_set(sw) digitalWrite(hlcd->cs2_pin, sw)
+
+/*
+ *  LCDへのコマンド送信関数
+ */
+ER
+lcd_writecommand(LCD_Handler_t *hlcd, uint8_t c)
+{
+	ER ercd = E_OK;
+
+	if(hlcd->spi_lock != 0){
+		if((ercd = wai_sem(hlcd->spi_lock)) != E_OK)
+			return ercd;
+	}
+	rs_set(PORT_LOW);
+	cs_set(PORT_LOW);
+
+	aTxBuffer[0] = c;
+#if SPI_WAIT_TIME != 0
+	ercd = spi_transmit(hlcd->hspi, (uint8_t*)aTxBuffer, 1);
+#else
+	if((ercd = spi_transmit(hlcd->hspi, (uint8_t*)aTxBuffer, 1)) == E_OK){
+		ercd = spi_wait(hlcd->hspi, 100);
+	}
+#endif
+
+	cs_set(PORT_HIGH);
+	if(hlcd->spi_lock != 0)
+		sig_sem(hlcd->spi_lock);
+	return ercd;
+}
+
+/*
+ *  LCDへのデータ送信関数
+ */
+ER
+lcd_writedata(LCD_Handler_t *hlcd, uint8_t *p, uint32_t len)
+{
+	ER ercd = E_OK;
+
+	if(hlcd->spi_lock != 0){
+		if((ercd = wai_sem(hlcd->spi_lock)) != E_OK)
+			return ercd;
+	}
+	rs_set(PORT_HIGH);
+	cs_set(PORT_LOW);
+	sil_dly_nse(100);
+
+#if SPI_WAIT_TIME != 0
+	ercd = spi_transmit(hlcd->hspi, (uint8_t*)p, len);
+#else
+	if((ercd = spi_transmit(hlcd->hspi, (uint8_t*)p, len)) == E_OK){
+		ercd = spi_wait(hlcd->hspi, 100);
+	}
+#endif
+
+	sil_dly_nse(100);
+	cs_set(PORT_HIGH);
+	if(hlcd->spi_lock != 0)
+		sig_sem(hlcd->spi_lock);
+	return ercd;
+}
+
+/*
+ *  LCDへの２バイトデータ送信関数
+ */
+ER
+lcd_writedata2(LCD_Handler_t *hlcd, uint16_t c, int cnt)
+{
+	ER  ercd = E_OK;
+	int i;
+
+	if(cnt == 0)
+		return ercd;
+	if(hlcd->spi_lock != 0){
+		if((ercd = wai_sem(hlcd->spi_lock)) != E_OK)
+			return ercd;
+	}
+	rs_set(PORT_HIGH);
+	cs_set(PORT_LOW);
+	sil_dly_nse(100);
+	aTxBuffer[0] = c>>8;
+	aTxBuffer[1] = (uint8_t)c;
+	for(i = 0 ; i < cnt ; i++){
+		if((ercd = spi_transmit(hlcd->hspi, (uint8_t*)aTxBuffer, 2)) != E_OK){
+			break;
+		}
+#if SPI_WAIT_TIME == 0
+		if((ercd = spi_wait(hlcd->hspi, 100)) != E_OK){
+			break;
+		}
+#endif
+	}
+	sil_dly_nse(100);
+	cs_set(PORT_HIGH);
+	if(hlcd->spi_lock != 0)
+		sig_sem(hlcd->spi_lock);
+	return ercd;
+}
+
+/*
+ *  LCDへのRGBデータ送信関数
+ */
+ER
+lcd_writedata3(LCD_Handler_t *hlcd, uint8_t *pbmp, uint16_t width, uint16_t height)
+{
+	ER  ercd = E_OK;
+	int index, i;
+
+	if(width == 0 || height == 0)
+		return ercd;
+	if(hlcd->spi_lock != 0){
+		if((ercd = wai_sem(hlcd->spi_lock)) != E_OK)
+			return ercd;
+	}
+	rs_set(PORT_HIGH);
+	cs_set(PORT_LOW);
+	sil_dly_nse(100);
+	for(index=0; index < height; index++){
+		uint8_t *p = pbmp;
+		for (i = 0; i < width; i++){
+			aTxBuffer[0]  = (*p++) & 0xf8;
+			aTxBuffer[0] |= *p >> 5;
+			aTxBuffer[1]  = (*p++ << 3) & 0xE0;
+			aTxBuffer[1] |= (*p++ >> 3) & 0x1F;
+			if((ercd = spi_transmit(hlcd->hspi, (uint8_t*)aTxBuffer, 2)) != E_OK){
+				break;
+			}
+#if SPI_WAIT_TIME == 0
+			if((ercd = spi_wait(hlcd->hspi, 100)) != E_OK){
+				break;
+			}
+#endif
+		}
+		pbmp -= width*3;
+	}
+	sil_dly_nse(100);
+	cs_set(PORT_HIGH);
+	if(hlcd->spi_lock != 0)
+		sig_sem(hlcd->spi_lock);
+	return ercd;
+}
+
+/*
+ *  ST7789へのコマンドリスト送信
+ */
+static void
+displayInit(LCD_Handler_t *hlcd, const uint8_t *addr)
+{
+	uint8_t  numCommands, numArgs;
+	uint8_t  data[4];
+	uint16_t ms;
+
+	numCommands = *addr++;   // Number of commands to follow
+	while(numCommands--) {                 // For each command...
+		SVC_PERROR(lcd_writecommand(hlcd, *addr++)); //   Read, issue command
+		numArgs  = *addr++;    //   Number of args to follow
+		ms       = numArgs & DELAY;          //   If hibit set, delay follows args
+		numArgs &= ~DELAY;                   //   Mask out delay bit
+		while(numArgs--) {                   //   For each argument...
+			data[0] = *addr++;
+			SVC_PERROR(lcd_writedata(hlcd, data, 1));  //     Read, issue argument
+		}
+
+		if(ms) {
+			ms = *addr++; // Read post-command delay time (ms)
+			if(ms == 255) ms = 500;     // If 255, delay for 500 ms
+			dly_tsk(ms);
+		}
+	}
+}
+
+
+/*
+ *  ST7735B または ST7735RタイプのLEDの共通初期化関数
+ */
+static void
+commonInit(LCD_Handler_t *hlcd, uint16_t width, uint16_t height)
+{
+	hlcd->colstart  = hlcd->rowstart = 0; // May be overridden in init func
+	hlcd->lcd_width = width;
+	hlcd->lcd_height = height;
+	if(width == 240 && height == 240){	/* 1.3" and 1.54 displays */
+		hlcd->lcd_colstart = 0;
+		hlcd->lcd_rowstart = 80;
+	}
+	else if(width == 135 && height == 240){	/*1.13" display */
+		hlcd->lcd_colstart = 53;
+		hlcd->lcd_rowstart = 40;
+	}
+	else{
+		hlcd->lcd_colstart = 0;
+		hlcd->lcd_rowstart = 0;
+	}
+
+	// toggle RST low to reset; CS low so it'll listen to us
+	cs_set(PORT_LOW);
+	rst_set(PORT_HIGH);
+	dly_tsk(500);
+	rst_set(PORT_LOW);
+	dly_tsk(500);
+	rst_set(PORT_HIGH);
+}
+
+/*
+ *  表示ウィンドウ設定
+ */
+void
+lcd_setAddrWindow(LCD_Handler_t *hlcd, uint8_t x0, uint8_t y0, uint8_t x1, uint8_t y1)
+{
+	uint8_t  data[4];
+
+	SVC_PERROR(lcd_writecommand(hlcd, ST7789_CASET)); // Column addr set
+	data[0] = (uint8_t)((x0 + hlcd->colstart) >> 8);
+	data[1] = (uint8_t)(x0 + hlcd->colstart);		// XSTART
+	data[2] = (uint8_t)((x1 + hlcd->colstart) >> 8);
+	data[3] = (uint8_t)(x1 + hlcd->colstart);		// XEND
+	SVC_PERROR(lcd_writedata(hlcd, data, 4));
+
+	SVC_PERROR(lcd_writecommand(hlcd, ST7789_RASET)); // Row addr set
+	data[0] = (uint8_t)((y0 + hlcd->rowstart) >> 8);
+	data[1] = (uint8_t)(y0 + hlcd->rowstart);		// YSTART
+	data[2] = (uint8_t)((y1 + hlcd->rowstart) >> 8);
+	data[3] = (uint8_t)(y1 + hlcd->rowstart);		// YEND
+	SVC_PERROR(lcd_writedata(hlcd, data, 4));
+
+	SVC_PERROR(lcd_writecommand(hlcd, ST7789_RAMWR)); // write to RAM
+}
+
+/*
+ *  オリエンテーション設定
+ *  param1  hlcd: Pointer to LCD Handler
+ *  param2  m: orientation value(0-3)
+ */
+void
+lcd_setRotation(LCD_Handler_t *hlcd, uint8_t m)
+{
+	uint8_t madctl[4];
+
+	hlcd->rotation = m & 3; // can't be higher than 3
+	madctl[0] = 0;
+
+	switch(hlcd->rotation){
+	case 0:
+		madctl[0]  = ST7789_MADCTL_MX | ST7789_MADCTL_MY | ST7789_MADCTL_RGB;
+		hlcd->colstart = hlcd->lcd_colstart;
+		hlcd->rowstart = hlcd->lcd_rowstart;
+		hlcd->_width  = hlcd->lcd_width;
+		hlcd->_height = hlcd->lcd_height;
+		break;
+	case 1:
+		madctl[0]  = ST7789_MADCTL_MY | ST7789_MADCTL_MV | ST7789_MADCTL_RGB;
+		hlcd->colstart = hlcd->lcd_rowstart;
+		hlcd->rowstart = hlcd->lcd_colstart;
+		hlcd->_height = hlcd->lcd_width;
+		hlcd->_width  = hlcd->lcd_height;
+		break;
+	case 2:
+		madctl[0]  = ST7789_MADCTL_RGB;
+		if(hlcd->lcd_width == 135 && hlcd->lcd_height == 240){
+			hlcd->colstart = hlcd->lcd_colstart-1;
+			hlcd->rowstart = hlcd->lcd_rowstart;
+		}
+		else{
+			hlcd->colstart = 0;
+			hlcd->rowstart = 0;
+		}
+		hlcd->_width  = hlcd->lcd_width;
+		hlcd->_height = hlcd->lcd_height;
+		break;
+	case 3:
+		madctl[0]  = ST7789_MADCTL_MX | ST7789_MADCTL_MV | ST7789_MADCTL_RGB;
+		if(hlcd->lcd_width == 135 && hlcd->lcd_height == 240){
+			hlcd->colstart = hlcd->lcd_rowstart;
+			hlcd->rowstart = hlcd->lcd_colstart;
+		}
+		else{
+			hlcd->colstart = 0;
+			hlcd->rowstart = 0;
+		}
+		hlcd->_height = hlcd->lcd_width;
+		hlcd->_width  = hlcd->lcd_height;
+		break;
+	}
+	SVC_PERROR(lcd_writecommand(hlcd, ST7789_MADCTL));
+	SVC_PERROR(lcd_writedata(hlcd, madctl, 1));
+}
+
+/*
+ *  ST7789 screensの初期化関数
+ */
+void
+lcd_init(LCD_Handler_t *hlcd, uint16_t width, uint16_t height)
+{
+	commonInit(hlcd, width, height);
+
+	displayInit(hlcd, Gcmd);
+	lcd_setRotation(hlcd, hlcd->rotation);
+	syslog_2(LOG_NOTICE, "## width(%d) height(%d) ##", hlcd->_width, hlcd->_height);
+}
+
+/*
+ *  RECTANGLEのフィル描画
+ *  param1  hlcd: Pointer to LCD Handler
+ *  param2  x: start X position
+ *  param3  y: start Y position
+ *  param4  w: width
+ *  param5  h: height
+ *  param6  color: color value
+ */
+void
+lcd_fillRect(LCD_Handler_t *hlcd, int16_t x, int16_t y, int16_t w, int16_t h, color_t color)
+{
+	// rudimentary clipping (drawChar w/big text requires this)
+	if((x >= hlcd->_width) || (y >= hlcd->_height)) return;
+	if((x + w - 1) >= hlcd->_width)  w = hlcd->_width  - x;
+	if((y + h - 1) >= hlcd->_height) h = hlcd->_height - y;
+
+	lcd_setAddrWindow(hlcd, x, y, x+w-1, y+h-1);
+	SVC_PERROR(lcd_writedata2(hlcd, color, h*w));
+}
+
+void
+lcd_pushColor(LCD_Handler_t *hlcd, color_t color)
+{
+	SVC_PERROR(lcd_writedata2(hlcd, color, 1));
+}
+
+/*
+ *  PIXEL描画
+ *  param1  hlcd: Pointer to LCD Handler
+ *  param2  x: X position
+ *  param3  y: Y position
+ *  param4  color: color value
+ */
+void
+lcd_drawPixel(LCD_Handler_t *hlcd, int16_t x, int16_t y, color_t color)
+{
+	if((x < 0) ||(x >= hlcd->_width) || (y < 0) || (y >= hlcd->_height)) return;
+
+	lcd_setAddrWindow(hlcd, x, y, x, y);
+	SVC_PERROR(lcd_writedata2(hlcd, color, 1));
+}
+
+/*
+ *  垂直方向LINEの高速描画
+ *  param1  hlcd: Pointer to LCD Handler
+ *  param2  x: start X position
+ *  param3  y: start Y position
+ *  param4  h: height
+ *  param5  color: color value
+ */
+void
+lcd_drawFastVLine(LCD_Handler_t *hlcd, int16_t x, int16_t y, int16_t h, color_t color)
+{
+	// Rudimentary clipping
+	if((x >= hlcd->_width) || (y >= hlcd->_height)) return;
+	if((y+h-1) >= hlcd->_height) h = hlcd->_height-y;
+	lcd_setAddrWindow(hlcd, x, y, x, y+h-1);
+	SVC_PERROR(lcd_writedata2(hlcd, color, h));
+}
+
+/*
+ *  水平方向LINEの高速描画
+ *  param1  hlcd: Pointer to LCD Handler
+ *  param2  x: start X position
+ *  param3  y: start Y position
+ *  param4  w: width
+ *  param5  color: color value
+ */
+void lcd_drawFastHLine(LCD_Handler_t *hlcd, int16_t x, int16_t y, int16_t w, color_t color)
+{
+	// Rudimentary clipping
+	if((x >= hlcd->_width) || (y >= hlcd->_height)) return;
+	if((x+w-1) >= hlcd->_width)  w = hlcd->_width-x;
+	lcd_setAddrWindow(hlcd, x, y, x+w-1, y);
+	SVC_PERROR(lcd_writedata2(hlcd, color, w));
+}
+
+/*
+ *  DRAW IMAGE LINE描画
+ *  param1  hlcd: Pointer to LCD Handler
+ *  param2  x: X position
+ *  param3  y: Y position
+ *  param4  w: width
+ *  param5  pcolor: color value
+ */
+void
+lcd_drawImageHLine(LCD_Handler_t *hlcd, int16_t x, int16_t y, uint16_t w, color_t *pcolor)
+{
+	uint32_t i;
+
+	if((x >= hlcd->_width) || (y >= hlcd->_height)) return;
+	if((x+w-1) >= hlcd->_width)  w = hlcd->_width-x;
+
+	lcd_setAddrWindow(hlcd, x, y, x+w-1, y);
+	for(i = 0 ; i < w ; i++, pcolor++)
+		SVC_PERROR(lcd_writedata2(hlcd, *pcolor, 1));
+}
+
+/*
+ *  BITMAP描画
+ *  param1  hlcd: Pointer to LCD Handler
+ *  param2  x0: Bmp X position in the LCD
+ *  param3  y0: Bmp Y position in the LCD
+ *  param4  pbmp: Pointer to Bmp picture address in the internal Flash
+ */
+void
+lcd_drawBitmap(LCD_Handler_t *hlcd, uint16_t x0, uint16_t y0, uint8_t *pbmp)
+{
+	uint32_t index = 0, width = 0, height = 0, bit_pixel = 0;
+	uint32_t input_color_mode = 0;
+
+	/* Get bitmap data address offset */
+	index = *(uint16_t *) (pbmp + 10);
+	index |= (*(uint16_t *) (pbmp + 12)) << 16;
+
+	/* Read bitmap width */
+	width = *(uint16_t *) (pbmp + 18);
+	width |= (*(uint16_t *) (pbmp + 20)) << 16;
+
+	/* Read bitmap height */
+	height = *(uint16_t *) (pbmp + 22);
+	height |= (*(uint16_t *) (pbmp + 24)) << 16;
+
+	/* Read bit/pixel */
+	bit_pixel = *(uint16_t *) (pbmp + 28);
+
+	/* Get the layer pixel format */
+	if ((bit_pixel/8) == 4){
+		input_color_mode = CM_ARGB8888;
+	}
+	else if ((bit_pixel/8) == 2){
+		input_color_mode = CM_RGB565;
+	}
+	else{
+		input_color_mode = CM_RGB888;
+	}
+
+	/* Bypass the bitmap header */
+	pbmp += (index + (width * (height - 1) * (bit_pixel/8)));  
+	syslog_4(LOG_NOTICE, "## input_color_mode(%d) width(%d) height(%d) bit_pixel(%d) ##", input_color_mode, width, height, bit_pixel);
+
+	lcd_setAddrWindow(hlcd, x0, y0, x0+width-1, y0+height-1);
+	lcd_writedata3(hlcd, pbmp, width, height);
+}
+
+/*
+ *  INVERT DISPLAY
+ *  param1  hlcd: Pointer to LCD Handler
+ *  param2  i: invert value
+ */
+void
+lcd_invertDisplay(LCD_Handler_t *hlcd, bool_t i)
+{
+  SVC_PERROR(lcd_writecommand(hlcd, i ? ST7789_INVOFF : ST7789_INVON));
+}
+
+
+/*
+ *  スクリーンフィル
+ *  param1  pDrawProp: Pointer to Draw Prop
+ */
+void
+lcd_fillScreen(LCD_DrawProp_t *pDrawProp)
+{
+	lcd_fillRect(pDrawProp->hlcd, 0, 0,  pDrawProp->hlcd->_width, pDrawProp->hlcd->_height, pDrawProp->BackColor);
+}
+
+/*
+ *  RECTANGLE描画
+ *  param1  pDrawProp: Pointer to Draw Prop
+ *  param2  x: left X position
+ *  param3  y: top Y position
+ *  param4  w: width
+ *  param5  h: height
+ */
+void
+lcd_drawRect(LCD_DrawProp_t *pDrawProp, int16_t x, int16_t y, int16_t w, int16_t h)
+{
+	LCD_Handler_t *hlcd = pDrawProp->hlcd;
+	color_t color;
+
+	// rudimentary clipping (drawChar w/big text requires this)
+	if((x >= hlcd->_width) || (y >= hlcd->_height)) return;
+	if((x + w - 1) >= hlcd->_width)  w = hlcd->_width  - x;
+	if((y + h - 1) >= hlcd->_height) h = hlcd->_height - y;
+
+	color = pDrawProp->TextColor;
+	lcd_drawFastVLine(hlcd, x, y, h, color);
+	lcd_drawFastHLine(hlcd, x, y+h-1, w, color);
+	lcd_drawFastVLine(hlcd, x+w-1, y, h, color);
+	lcd_drawFastHLine(hlcd, x, y, w, color);
+}
+
+/*
+ *  円描画
+ *  param1  pDrawProp: Pointer to Draw Prop
+ *  param2  x0: X position
+ *  param3  y0: Y position
+ *  param4  Radius: Circle radius
+ */
+void
+lcd_DrawCircle(LCD_DrawProp_t *pDrawProp, uint16_t x0, uint16_t y0, uint16_t Radius)
+{
+	LCD_Handler_t *hlcd = pDrawProp->hlcd;
+ 	int32_t   decision;    /* Decision Variable */ 
+	uint32_t  current_x;   /* Current X Value */
+	uint32_t  current_y;   /* Current Y Value */
+
+	decision = 3 - (Radius << 1);
+	current_x = 0;
+	current_y = Radius;
+
+	while(current_x <= current_y){
+		lcd_drawPixel(hlcd, (x0 + current_x), (y0 - current_y), pDrawProp->TextColor);
+		lcd_drawPixel(hlcd, (x0 - current_x), (y0 - current_y), pDrawProp->TextColor);
+		lcd_drawPixel(hlcd, (x0 + current_y), (y0 - current_x), pDrawProp->TextColor);
+		lcd_drawPixel(hlcd, (x0 - current_y), (y0 - current_x), pDrawProp->TextColor);
+		lcd_drawPixel(hlcd, (x0 + current_x), (y0 + current_y), pDrawProp->TextColor);
+		lcd_drawPixel(hlcd, (x0 - current_x), (y0 + current_y), pDrawProp->TextColor);
+		lcd_drawPixel(hlcd, (x0 + current_y), (y0 + current_x), pDrawProp->TextColor);
+		lcd_drawPixel(hlcd, (x0 - current_y), (y0 + current_x), pDrawProp->TextColor);
+
+		if (decision < 0){
+			decision += (current_x << 2) + 6;
+		}
+		else{
+			decision += ((current_x - current_y) << 2) + 10;
+			current_y--;
+		}
+		current_x++;
+	}
+}
+
+/*
+ *  線描画
+ *  param1  pDrawProp: Pointer to Draw Prop
+ *  param2  x1: Point 1 X position
+ *  param3  y1: Point 1 Y position
+ *  param4  x2: Point 2 X position
+ *  param5  y2: Point 2 Y position
+ */
+void
+lcd_drawLine(LCD_DrawProp_t *pDrawProp, uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2)
+{
+	LCD_Handler_t *hlcd = pDrawProp->hlcd;
+	int16_t deltax = 0, deltay = 0, x = 0, y = 0, xinc1 = 0, xinc2 = 0, 
+	yinc1 = 0, yinc2 = 0, den = 0, num = 0, num_add = 0, num_pixels = 0, 
+	curpixel = 0;
+
+	deltax = ABS(x2 - x1);		/* The difference between the x's */
+	deltay = ABS(y2 - y1);		/* The difference between the y's */
+	x = x1;						/* Start x off at the first pixel */
+	y = y1;						/* Start y off at the first pixel */
+
+	if(x2 >= x1){				/* The x-values are increasing */
+		xinc1 = 1;
+		xinc2 = 1;
+	}
+	else{						/* The x-values are decreasing */
+		xinc1 = -1;
+		xinc2 = -1;
+	}
+
+	if(y2 >= y1){				/* The y-values are increasing */
+		yinc1 = 1;
+		yinc2 = 1;
+	}
+	else{						/* The y-values are decreasing */
+		yinc1 = -1;
+		yinc2 = -1;
+	}
+
+	if(deltax >= deltay){		/* There is at least one x-value for every y-value */
+		xinc1 = 0;				/* Don't change the x when numerator >= denominator */
+		yinc2 = 0;				/* Don't change the y for every iteration */
+		den = deltax;
+		num = deltax / 2;
+		num_add = deltay;
+		num_pixels = deltax;	/* There are more x-values than y-values */
+	}
+	else{						/* There is at least one y-value for every x-value */
+		xinc2 = 0;				/* Don't change the x for every iteration */
+		yinc1 = 0;				/* Don't change the y when numerator >= denominator */
+		den = deltay;
+		num = deltay / 2;
+		num_add = deltax;
+		num_pixels = deltay;	/* There are more y-values than x-values */
+	}
+
+	for (curpixel = 0; curpixel <= num_pixels; curpixel++){
+		lcd_drawPixel(hlcd, x, y, pDrawProp->TextColor);	/* Draw the current pixel */
+		num += num_add;			/* Increase the numerator by the top of the fraction */
+		if(num >= den){			/* Check if numerator >= denominator */
+			num -= den;			/* Calculate the new numerator value */
+			x += xinc1;			/* Change the x as appropriate */
+			y += yinc1;			/* Change the y as appropriate */
+		}
+		x += xinc2;				/* Change the x as appropriate */
+		y += yinc2;				/* Change the y as appropriate */
+	}
+}
+
+/*
+ *  PLOY-LINE描画
+ *  param1  pDrawProp: Pointer to Draw Prop
+ *  param2  Points: Pointer to the points array
+ *  param3  PointCount: Number of points
+ */
+void
+lcd_drawPolygon(LCD_DrawProp_t *pDrawProp, pPoint Points, uint16_t PointCount)
+{
+	int16_t x = 0, y = 0;
+
+	if(PointCount < 2){
+		return;
+	}
+
+	lcd_drawLine(pDrawProp, Points->X, Points->Y, (Points+PointCount-1)->X, (Points+PointCount-1)->Y);
+	while(--PointCount){
+		x = Points->X;
+		y = Points->Y;
+		Points++;
+		lcd_drawLine(pDrawProp, x, y, Points->X, Points->Y);
+	}
+}
+
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/adafruit_st7789/adafruit_st7789.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/adafruit_st7789/adafruit_st7789.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/adafruit_st7789/adafruit_st7789.h	(revision 457)
@@ -0,0 +1,199 @@
+/*
+ *  TOPPERS/ASP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Advanced Standard Profile Kernel
+ *
+ *  Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
+ *                              Toyohashi Univ. of Technology, JAPAN
+ *  Copyright (C) 2004-2010 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ *  Copyright (C) 2015-2019 by TOPPERS PROJECT Educational Working Group.
+ *
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ *
+ *  $Id$
+ */
+
+/*
+ *  Written by Limor Fried/Ladyada for Adafruit Industries.
+ *  MIT license, all text above must be included in any redistribution
+ *　http://opensource.org/licenses/mit-license.php 
+ */
+
+/*
+ *  ADAFRUIT ST7789 LCD制御プログラムのヘッダファイル
+ */
+
+#ifndef _ADAFRUIT_ST7789_H_
+#define _ADAFRUIT_ST7789_H_
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+#include "device.h"
+#include "pinmode.h"
+#include "spi.h"
+
+/*
+ *  LCDカラーモード定義
+ */
+#define CM_ARGB8888         0x00000000			/* ARGB8888 color mode */
+#define CM_RGB888           0x00000001			/* RGB888 color mode */
+#define CM_RGB565           0x00000002			/* RGB565 color mode */
+
+#define ST7789_NOP          0x00
+#define ST7789_SWRESET      0x01
+#define ST7789_RDDID        0x04
+#define ST7789_RDDST        0x09
+
+#define ST7789_SLPIN        0x10
+#define ST7789_SLPOUT       0x11
+#define ST7789_PTLON        0x12
+#define ST7789_NORON        0x13
+
+#define ST7789_INVOFF       0x20
+#define ST7789_INVON        0x21
+#define ST7789_DISPOFF      0x28
+#define ST7789_DISPON       0x29
+#define ST7789_CASET        0x2A
+#define ST7789_RASET        0x2B
+#define ST7789_RAMWR        0x2C
+#define ST7789_RAMRD        0x2E
+
+#define ST7789_PTLAR        0x30
+#define ST7789_TEOFF        0x34
+#define ST7789_TEON         0x35
+#define ST7789_COLMOD       0x3A
+#define ST7789_MADCTL       0x36
+
+#define ST7789_MADCTL_MY    0x80
+#define ST7789_MADCTL_MX    0x40
+#define ST7789_MADCTL_MV    0x20
+#define ST7789_MADCTL_ML    0x10
+#define ST7789_MADCTL_RGB   0x00
+
+#define ST7789_RDID1        0xDA
+#define ST7789_RDID2        0xDB
+#define ST7789_RDID3        0xDC
+#define ST7789_RDID4        0xDD
+
+// Color definitions
+#define	ST7789_BLACK        0x0000
+#define	ST7789_BLUE         0x001F
+#define	ST7789_RED          0xF800
+#define	ST7789_GREEN        0x07E0
+#define ST7789_CYAN         0x07FF
+#define ST7789_MAGENTA      0xF81F
+#define ST7789_YELLOW       0xFFE0
+#define ST7789_WHITE        0xFFFF
+
+
+#ifndef TOPPERS_MACRO_ONLY
+
+/*
+ *  カラーの属性を定義
+ */
+typedef uint16_t   color_t;
+
+/*
+ *  LCDハンドラ構造体定義
+ */
+typedef struct
+{
+	SPI_Handle_t            *hspi;		/* spiハンドラ */
+	uint16_t                _width;		/* 幅ピクセル数 */
+	uint16_t				_height;	/* 高さピクセル数 */
+	uint16_t                colstart;
+	uint16_t                rowstart;
+	uint16_t                lcd_width;
+	uint16_t                lcd_height;
+	uint16_t                lcd_colstart;
+	uint16_t                lcd_rowstart;
+	uint8_t                 rotation;
+	uint8_t                 dummy[3];
+	ID                      spi_lock;
+	int8_t                  cs_pin;
+	int8_t                  rs_pin;
+	int8_t                  rst_pin;
+	int8_t                  cs2_pin;
+}LCD_Handler_t;
+
+/*
+ *  描画構造体
+ */
+typedef struct
+{
+	LCD_Handler_t           *hlcd;
+	color_t                 TextColor;
+	color_t                 BackColor;
+	void                    *pFont;
+}LCD_DrawProp_t;
+
+typedef struct
+{
+	int16_t X;
+	int16_t Y;
+}Point, * pPoint;
+
+/*
+ *  関数のプロトタイプ宣言
+ */
+extern ER lcd_writecommand(LCD_Handler_t *hlcd, uint8_t c);
+extern ER lcd_writedata(LCD_Handler_t *hlcd, uint8_t *p, uint32_t len);
+extern ER lcd_writedata2(LCD_Handler_t *hlcd, uint16_t c, int cnt);
+extern ER lcd_writedata3(LCD_Handler_t *hlcd, uint8_t *pbmp, uint16_t width, uint16_t height);
+
+extern void lcd_init(LCD_Handler_t *hlcd, uint16_t width, uint16_t height);
+extern void lcd_setAddrWindow(LCD_Handler_t *hlcd, uint8_t x0, uint8_t y0, uint8_t x1, uint8_t y1);
+extern void lcd_setRotation(LCD_Handler_t *hlcd, uint8_t m);
+extern void lcd_fillRect(LCD_Handler_t *hlcd, int16_t x, int16_t y, int16_t w, int16_t h, color_t color);
+extern void lcd_pushColor(LCD_Handler_t *hlcd, color_t color);
+extern void lcd_drawPixel(LCD_Handler_t *hlcd, int16_t x, int16_t y, color_t color);
+extern void lcd_drawFastVLine(LCD_Handler_t *hlcd, int16_t x, int16_t y, int16_t h, color_t color);
+extern void lcd_drawFastHLine(LCD_Handler_t *hlcd, int16_t x, int16_t y, int16_t w, color_t color);
+extern void lcd_drawImageHLine(LCD_Handler_t *hlcd, int16_t x, int16_t y, uint16_t w, color_t *pcolor);
+extern void lcd_drawBitmap(LCD_Handler_t *hlcd, uint16_t x0, uint16_t y0, uint8_t *pbmp);
+extern void lcd_invertDisplay(LCD_Handler_t *hlcd, bool_t i);
+
+extern void lcd_fillScreen(LCD_DrawProp_t *pDrawProp);
+extern void lcd_drawRect(LCD_DrawProp_t *pDrawProp, int16_t x, int16_t y, int16_t w, int16_t h);
+extern void lcd_DrawCircle(LCD_DrawProp_t *pDrawProp, uint16_t x0, uint16_t y0, uint16_t Radius);
+extern void lcd_drawLine(LCD_DrawProp_t *pDrawProp, uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2);
+extern void lcd_drawPolygon(LCD_DrawProp_t *pDrawProp, pPoint Points, uint16_t PointCount);
+
+#endif /* TOPPERS_MACRO_ONLY */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif	/* _ADAFRUIT_ST7789_H_ */
+
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/adafruit_st7789/glcd_core.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/adafruit_st7789/glcd_core.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/adafruit_st7789/glcd_core.h	(revision 457)
@@ -0,0 +1,45 @@
+/*
+ *  TOPPERS BASE PLATFORM MIDDLEWARE
+ * 
+ *  Copyright (C) 2017-2018 by TOPPERS PROJECT
+ *                             Educational Working Group.
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+#ifndef _LCD_CORE_H_
+#define _LCD_CORE_H_
+
+#include "adafruit_st7789.h"
+
+#endif /* _LCD_CORE_H_ */
+
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/adafruitts_stmp610/Makefile.config
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/adafruitts_stmp610/Makefile.config	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/adafruitts_stmp610/Makefile.config	(revision 457)
@@ -0,0 +1,55 @@
+#
+#   TOPPERS/ASP/FMP Kernel
+#       Toyohashi Open Platform for Embedded Real-Time Systems/
+#       Advanced Standard Profile Kernel
+#
+#   Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
+#                               Toyohashi Univ. of Technology, JAPAN
+#   Copyright (C) 2003-2008 by Ryosuke Takeuchi
+#                Platform Development Center RICOH COMPANY,LTD. JAPAN
+#   Copyright (C) 2015-2019 by TOPPERS PROJECT Educational Working Group.
+#
+#   上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+#   によって公表されている GNU General Public License の Version 2 に記
+#   述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+#   を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+#   利用と呼ぶ）することを無償で許諾する．
+#   (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+#       権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+#       スコード中に含まれていること．
+#   (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+#       用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+#       者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+#       の無保証規定を掲載すること．
+#   (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+#       用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+#       と．
+#     (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+#         作権表示，この利用条件および下記の無保証規定を掲載すること．
+#     (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+#         報告すること．
+#   (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+#       害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+#
+#   本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+#   よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+#   含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+#   接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+#
+#  @(#) $Id$
+#
+ 
+#
+#  Makefile のプロセッサ依存 (adafruitts_stmp610用)
+#
+
+#
+#  コンパイルオプション
+#
+INCLUDES := $(INCLUDES) -I$(SRCDIR)/gdic/adafruitts_stmp610
+
+#
+#  USB DEVICE(GDIC)に関する定義
+#
+SYSSVC_DIR := $(SYSSVC_DIR):$(SRCDIR)/gdic/adafruitts_stmp610
+SYSSVC_COBJS := $(SYSSVC_COBJS) adafruitts_stmp610.o
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/adafruitts_stmp610/adafruitts_stmp610.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/adafruitts_stmp610/adafruitts_stmp610.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/adafruitts_stmp610/adafruitts_stmp610.c	(revision 457)
@@ -0,0 +1,302 @@
+/*
+ *  TOPPERS BASE PLATFORM MIDDLEWARE
+ * 
+ *  Copyright (C) 2017-2019 by TOPPERS PROJECT
+ *                             Educational Working Group.
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *  Written by Limor Fried/Ladyada for Adafruit Industries.
+ *  MIT license, all text above must be included in any redistribution
+ *　http://opensource.org/licenses/mit-license.php 
+ */
+
+#include <kernel.h>
+#include <t_syslog.h>
+#include <t_stdlib.h>
+#include <sil.h>
+#include <target_syssvc.h>
+#include "device.h"
+#include "pinmode.h"
+#include "adafruitts_stmp610.h"
+
+#define PORT_HIGH           1
+#define PORT_LOW            0
+
+#define TS_MINX             150
+#define TS_MINY             130
+#define TS_MAXX             3800
+#define TS_MAXY             4000
+
+#define cs_set(sw)  digitalWrite(hts->cs_pin, (sw))
+
+static uint8_t aTxBuffer[4];
+
+/*
+ *  STMP610レジスタ読み出し
+ */
+static ER_UINT
+touchscreen_readRegister(TouchScreen_Handle_t *hts, uint8_t reg)
+{
+	ER_UINT ercd = E_OK;
+
+	if(hts->spi_lock != 0){
+		if((ercd = wai_sem(hts->spi_lock)) != E_OK)
+			return ercd;
+	}
+	cs_set(PORT_LOW);
+
+	aTxBuffer[0] = 0x80 | reg;
+	aTxBuffer[1] = 0;
+#if SPI_WAIT_TIME != 0
+	ercd = spi_transmit(hts->hspi, (uint8_t*)aTxBuffer, 2);
+#else
+	if((ercd = spi_transmit(hts->hspi, (uint8_t*)aTxBuffer, 2)) == E_OK){
+		ercd = spi_wait(hts->hspi, 100);
+	}
+#endif
+
+	if(ercd == E_OK){
+#if SPI_WAIT_TIME != 0
+		ercd = spi_receive(hts->hspi, (uint8_t*)aTxBuffer, 1);
+#else
+		if((ercd = spi_receive(hts->hspi, (uint8_t*)aTxBuffer, 1)) == E_OK){
+			ercd = spi_wait(hts->hspi, 100);
+		}
+#endif
+	}
+	if(ercd == E_OK)
+		ercd = aTxBuffer[0];
+
+	cs_set(PORT_HIGH);
+	if(hts->spi_lock != 0)
+		sig_sem(hts->spi_lock);
+	return ercd;
+}
+
+/*
+ *  STMP610レジスタ書き込み
+ */
+ER
+touchscreen_writeRegister(TouchScreen_Handle_t *hts, uint8_t reg, uint8_t val)
+{
+	ER ercd = E_OK;
+
+	if(hts->spi_lock != 0){
+		if((ercd = wai_sem(hts->spi_lock)) != E_OK)
+			return ercd;
+	}
+	cs_set(PORT_LOW);
+
+	aTxBuffer[0] = reg;
+	aTxBuffer[1] = val;
+#if SPI_WAIT_TIME != 0
+	ercd = spi_transmit(hts->hspi, (uint8_t*)aTxBuffer, 2);
+#else
+	if((ercd = spi_transmit(hts->hspi, (uint8_t*)aTxBuffer, 2)) == E_OK){
+		ercd = spi_wait(hts->hspi, 100);
+	}
+#endif
+
+	cs_set(PORT_HIGH);
+	if(hts->spi_lock != 0)
+		sig_sem(hts->spi_lock);
+	return ercd;
+}
+
+
+/*
+ *  STMP610 初期化
+ */
+ER
+touchscreen_init(TouchScreen_Handle_t *hts, uint8_t orientation)
+{
+	Arduino_PortControlBlock *pgcb = getGpioTable(DIGITAL_PIN, hts->cs_pin);
+	GPIO_Init_t GPIO_Init_Data;
+	ER ercd;
+	uint32_t i;
+
+	if(hts == NULL)
+		return E_PAR;
+	if(hts->hspi == NULL)
+		return E_PAR;
+	pgcb = getGpioTable(DIGITAL_PIN, hts->cs_pin);
+	if(pgcb == NULL)
+		return E_PAR;
+
+	GPIO_Init_Data.mode  = GPIO_MODE_OUTPUT;
+	GPIO_Init_Data.pull  = hts->pullmode;
+	GPIO_Init_Data.otype = hts->otype;
+	GPIO_Init_Data.speed = GPIO_SPEED_FAST;
+	gpio_setup(pgcb->giobase, &GPIO_Init_Data, pgcb->giopin);
+
+	/*
+	 *  VERSIONを検証
+	 */
+	if(touchscreen_getversion(hts) != 0x811)
+		return E_SYS;
+	hts->min_x = TS_MINX;
+	hts->min_y = TS_MINY;
+	hts->max_x = TS_MAXX;
+	hts->max_y = TS_MAXY;
+
+	ercd = touchscreen_writeRegister(hts, STMPE_SYS_CTRL1, STMPE_SYS_CTRL1_RESET);
+	dly_tsk(10);
+
+	for(i = 0 ; i < 65 ; i++){
+		touchscreen_readRegister(hts, i);
+	}
+
+	if(ercd == E_OK)
+		ercd = touchscreen_writeRegister(hts, STMPE_SYS_CTRL2, 0x0);	/* turn on clocks! */
+	if(ercd == E_OK)
+		ercd = touchscreen_writeRegister(hts, STMPE_TSC_CTRL, STMPE_TSC_CTRL_XYZ | STMPE_TSC_CTRL_EN);	/* XYZ and enable! */
+	if(ercd == E_OK)
+		ercd = touchscreen_writeRegister(hts, STMPE_INT_EN, STMPE_INT_EN_TOUCHDET);
+	if(ercd == E_OK)
+		ercd = touchscreen_writeRegister(hts, STMPE_ADC_CTRL1, STMPE_ADC_CTRL1_10BIT | (0x6 << 4));	/* 96 clocks per conversion */
+	if(ercd == E_OK)
+		ercd = touchscreen_writeRegister(hts, STMPE_ADC_CTRL2, STMPE_ADC_CTRL2_6_5MHZ);
+	if(ercd == E_OK)
+		ercd = touchscreen_writeRegister(hts, STMPE_TSC_CFG, STMPE_TSC_CFG_4SAMPLE | STMPE_TSC_CFG_DELAY_1MS | STMPE_TSC_CFG_SETTLE_5MS);
+	if(ercd == E_OK)
+		ercd = touchscreen_writeRegister(hts, STMPE_TSC_FRACTION_Z, 0x6);
+	if(ercd == E_OK)
+		ercd = touchscreen_writeRegister(hts, STMPE_FIFO_TH, 1);
+	if(ercd == E_OK)
+		ercd = touchscreen_writeRegister(hts, STMPE_FIFO_STA, STMPE_FIFO_STA_RESET);
+	if(ercd == E_OK)
+		ercd = touchscreen_writeRegister(hts, STMPE_FIFO_STA, 0);		/* unreset */
+	if(ercd == E_OK)
+		ercd = touchscreen_writeRegister(hts, STMPE_TSC_I_DRIVE, STMPE_TSC_I_DRIVE_50MA);
+	if(ercd == E_OK)
+		ercd = touchscreen_writeRegister(hts, STMPE_INT_STA, 0xFF);		/* reset all ints */
+	if(ercd == E_OK)
+		ercd = touchscreen_writeRegister(hts, STMPE_INT_CTRL, STMPE_INT_CTRL_POL_HIGH | STMPE_INT_CTRL_ENABLE);
+	return ercd;
+}
+
+/*
+ *  STMP610 タッチ判定
+ *  param1  hts: Pointer to Touch Screen Handler
+ *  result  エラーまたはbool判定
+ */
+ER_BOOL
+touchscreen_touched(TouchScreen_Handle_t *hts)
+{
+	ER_BOOL ercd;
+
+	if(hts == NULL)
+		return E_PAR;
+	if((ercd = touchscreen_readRegister(hts, STMPE_TSC_CTRL)) >= E_OK)
+		ercd = (ercd & 0x80) != 0;
+	return ercd;
+}
+
+/*
+ *  STMP610 FIFOサイズ読み出し
+ *  param1  hts: Pointer to Touch Screen Handler
+ *  result  エラーまたは現在のアイテム数
+ */
+ER_UINT
+touchscreen_buffersize(TouchScreen_Handle_t *hts)
+{
+	ER_BOOL ercd;
+
+	if(hts == NULL)
+		return E_PAR;
+	if((ercd = touchscreen_readRegister(hts, STMPE_FIFO_STA)) >= E_OK){
+		if((ercd & STMPE_FIFO_STA_EMPTY) == 0)
+			ercd = touchscreen_readRegister(hts, STMPE_FIFO_SIZE);
+		else
+			ercd = 0;
+	}
+	return ercd;
+}
+
+/*
+ *  STMP610 ポイント読み出し
+ *  param1  hts: Pointer to Touch Screen Handler
+ *  param2  pt:  Pointer to Point type arry
+ *  param3  len: max number of arry items
+ *  result  エラーまたは設定アイテム数
+ */
+ER_UINT
+touchscreen_getpoint(TouchScreen_Handle_t *hts, TouchScreen_Point_t *pt, uint8_t len)
+{
+	ER_UINT  buffer[4], no = 0, ercd;
+	uint32_t i;
+
+	if(hts == NULL || pt == NULL)
+		return E_PAR;
+	while((ercd = touchscreen_buffersize(hts)) > 0){
+		for(i = 0 ; i < 4 ; i++){
+			if((buffer[i] = touchscreen_readRegister(hts, 0xD7)) < E_OK)
+				return buffer[i];
+		}
+		if(no < len){
+			pt->x  = buffer[0] << 4;
+			pt->x |= (buffer[1] >> 4 & 0x0F);
+			pt->y  = (buffer[1] & 0x0F) << 8;
+			pt->y |= buffer[2] & 0xFF;
+			pt->z = buffer[3];
+			no++;
+			pt++;
+		}
+	}
+	return no;
+}
+
+/*
+ *  STMP610 バージョン読み出し
+ */
+ER_UINT
+touchscreen_getversion(TouchScreen_Handle_t *hts)
+{
+	ER_UINT ercd, ercd2;
+
+	if(hts == NULL)
+		return E_PAR;
+
+	if((ercd = touchscreen_readRegister(hts, 0)) >= E_OK){
+		ercd <<= 8;
+		if((ercd2 = touchscreen_readRegister(hts, 1)) >= E_OK){
+			ercd |= ercd2 & 0xFF;
+			return ercd;
+		}
+		ercd = ercd2;
+	}
+	return ercd;
+}
+
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/adafruitts_stmp610/adafruitts_stmp610.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/adafruitts_stmp610/adafruitts_stmp610.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/adafruitts_stmp610/adafruitts_stmp610.h	(revision 457)
@@ -0,0 +1,182 @@
+/*
+ *  TOPPERS BASE PLATFORM MIDDLEWARE
+ * 
+ *  Copyright (C) 2017-2019 by TOPPERS PROJECT
+ *                             Educational Working Group.
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *  Written by Limor Fried/Ladyada for Adafruit Industries.
+ *  MIT license, all text above must be included in any redistribution
+ *　http://opensource.org/licenses/mit-license.php 
+ */
+
+#ifndef _ADAFRUITTS_STMP610_H_
+#define _ADAFRUITTS_STMP610_H_
+
+#include <kernel.h>
+#include <t_syslog.h>
+#include <t_stdlib.h>
+#include "device.h"
+#include "spi.h"
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+#define STMPE_ADDR 0x41
+
+#define STMPE_SYS_CTRL1 0x03
+#define STMPE_SYS_CTRL1_RESET 0x02
+#define STMPE_SYS_CTRL2 0x04
+
+#define STMPE_TSC_CTRL 0x40
+#define STMPE_TSC_CTRL_EN 0x01
+#define STMPE_TSC_CTRL_XYZ 0x00
+#define STMPE_TSC_CTRL_XY 0x02
+
+#define STMPE_INT_CTRL 0x09
+#define STMPE_INT_CTRL_POL_HIGH 0x04
+#define STMPE_INT_CTRL_POL_LOW 0x00
+#define STMPE_INT_CTRL_EDGE 0x02
+#define STMPE_INT_CTRL_LEVEL 0x00
+#define STMPE_INT_CTRL_ENABLE 0x01
+#define STMPE_INT_CTRL_DISABLE 0x00
+
+
+
+#define STMPE_INT_EN 0x0A
+#define STMPE_INT_EN_TOUCHDET 0x01
+#define STMPE_INT_EN_FIFOTH 0x02
+#define STMPE_INT_EN_FIFOOF 0x04
+#define STMPE_INT_EN_FIFOFULL 0x08
+#define STMPE_INT_EN_FIFOEMPTY 0x10
+#define STMPE_INT_EN_ADC 0x40
+#define STMPE_INT_EN_GPIO 0x80
+
+#define STMPE_INT_STA 0x0B
+#define STMPE_INT_STA_TOUCHDET 0x01
+
+#define STMPE_ADC_CTRL1 0x20
+#define STMPE_ADC_CTRL1_12BIT 0x08
+#define STMPE_ADC_CTRL1_10BIT 0x00
+
+#define STMPE_ADC_CTRL2 0x21
+#define STMPE_ADC_CTRL2_1_625MHZ 0x00
+#define STMPE_ADC_CTRL2_3_25MHZ 0x01
+#define STMPE_ADC_CTRL2_6_5MHZ 0x02
+
+#define STMPE_TSC_CFG 0x41
+#define STMPE_TSC_CFG_1SAMPLE 0x00
+#define STMPE_TSC_CFG_2SAMPLE 0x40
+#define STMPE_TSC_CFG_4SAMPLE 0x80
+#define STMPE_TSC_CFG_8SAMPLE 0xC0
+#define STMPE_TSC_CFG_DELAY_10US 0x00
+#define STMPE_TSC_CFG_DELAY_50US 0x08
+#define STMPE_TSC_CFG_DELAY_100US 0x10
+#define STMPE_TSC_CFG_DELAY_500US 0x18
+#define STMPE_TSC_CFG_DELAY_1MS 0x20
+#define STMPE_TSC_CFG_DELAY_5MS 0x28
+#define STMPE_TSC_CFG_DELAY_10MS 0x30
+#define STMPE_TSC_CFG_DELAY_50MS 0x38
+#define STMPE_TSC_CFG_SETTLE_10US 0x00
+#define STMPE_TSC_CFG_SETTLE_100US 0x01
+#define STMPE_TSC_CFG_SETTLE_500US 0x02
+#define STMPE_TSC_CFG_SETTLE_1MS 0x03
+#define STMPE_TSC_CFG_SETTLE_5MS 0x04
+#define STMPE_TSC_CFG_SETTLE_10MS 0x05
+#define STMPE_TSC_CFG_SETTLE_50MS 0x06
+#define STMPE_TSC_CFG_SETTLE_100MS 0x07
+
+#define STMPE_FIFO_TH 0x4A
+
+#define STMPE_FIFO_SIZE 0x4C 
+
+#define STMPE_FIFO_STA 0x4B
+#define STMPE_FIFO_STA_RESET 0x01
+#define STMPE_FIFO_STA_OFLOW 0x80
+#define STMPE_FIFO_STA_FULL 0x40
+#define STMPE_FIFO_STA_EMPTY 0x20
+#define STMPE_FIFO_STA_THTRIG 0x10
+
+#define STMPE_TSC_I_DRIVE 0x58
+#define STMPE_TSC_I_DRIVE_20MA 0x00
+#define STMPE_TSC_I_DRIVE_50MA 0x01
+
+#define STMPE_TSC_DATA_X 0x4D
+#define STMPE_TSC_DATA_Y 0x4F
+#define STMPE_TSC_FRACTION_Z 0x56
+
+#define STMPE_GPIO_SET_PIN 0x10
+#define STMPE_GPIO_CLR_PIN 0x11
+#define STMPE_GPIO_DIR 0x13
+#define STMPE_GPIO_ALT_FUNCT 0x17
+
+typedef struct
+{
+	int16_t                 x;
+	int16_t                 y;
+	int16_t                 z;
+} TouchScreen_Point_t;
+
+/*
+ *  TouchScreenハンドラ構造体定義
+ */
+typedef struct
+{
+	SPI_Handle_t            *hspi;		/* spiハンドラ */
+	uint16_t                min_x;
+	uint16_t                min_y;
+	uint16_t                max_x;
+	uint16_t                max_y;
+	uint8_t                 cs_pin;
+	uint32_t                otype;
+	uint32_t                pullmode;
+	ID                      spi_lock;
+} TouchScreen_Handle_t;
+
+extern ER touchscreen_init(TouchScreen_Handle_t *hts, uint8_t orientation);
+extern ER_BOOL touchscreen_touched(TouchScreen_Handle_t *hts);
+extern ER_UINT touchscreen_buffersize(TouchScreen_Handle_t *hts);
+extern ER_UINT touchscreen_getversion(TouchScreen_Handle_t *hts);
+extern ER touchscreen_getpoint(TouchScreen_Handle_t *hts, TouchScreen_Point_t *point, uint8_t len);
+extern ER touchscreen_writeRegister(TouchScreen_Handle_t *hts, uint8_t reg, uint8_t val);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _ADAFRUITTS_STMP610_H_ */
+
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/aqm0802_st7032/Makefile.config
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/aqm0802_st7032/Makefile.config	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/aqm0802_st7032/Makefile.config	(revision 457)
@@ -0,0 +1,55 @@
+#
+#   TOPPERS/ASP/FMP Kernel
+#       Toyohashi Open Platform for Embedded Real-Time Systems/
+#       Advanced Standard Profile Kernel
+#
+#   Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
+#                               Toyohashi Univ. of Technology, JAPAN
+#   Copyright (C) 2003-2008 by Ryosuke Takeuchi
+#                Platform Development Center RICOH COMPANY,LTD. JAPAN
+#   Copyright (C) 2015-2017 by TOPPERS PROJECT Educational Working Group.
+#
+#   上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+#   によって公表されている GNU General Public License の Version 2 に記
+#   述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+#   を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+#   利用と呼ぶ）することを無償で許諾する．
+#   (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+#       権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+#       スコード中に含まれていること．
+#   (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+#       用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+#       者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+#       の無保証規定を掲載すること．
+#   (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+#       用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+#       と．
+#     (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+#         作権表示，この利用条件および下記の無保証規定を掲載すること．
+#     (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+#         報告すること．
+#   (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+#       害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+#
+#   本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+#   よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+#   含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+#   接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+#
+#  @(#) $Id$
+#
+ 
+#
+#  Makefile のプロセッサ依存 (aqm0802 st7032:LCD用)
+#
+
+#
+#  コンパイルオプション
+#
+INCLUDES := $(INCLUDES) -I$(SRCDIR)/gdic/aqm0802_st7032
+
+#
+#  AQM0802 ST7032 LCD DRIVER(GDIC)に関する定義
+#
+SYSSVC_DIR := $(SYSSVC_DIR):$(SRCDIR)/gdic/aqm0802_st7032
+SYSSVC_COBJS := $(SYSSVC_COBJS) aqm0802_st7032.o
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/aqm0802_st7032/aqm0802_st7032.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/aqm0802_st7032/aqm0802_st7032.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/aqm0802_st7032/aqm0802_st7032.c	(revision 457)
@@ -0,0 +1,210 @@
+/*
+ *  TOPPERS/ASP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Advanced Standard Profile Kernel
+ * 
+ *  Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
+ *                              Toyohashi Univ. of Technology, JAPAN
+ *  Copyright (C) 2004-2012 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ *  Copyright (C) 2015-2019 by TOPPERS PROJECT Educational Working Group.
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  $Id$
+ */
+
+/* 
+ *  AQM0802 ST7032 LCD制御プログラムの本体
+ */
+
+#include <kernel.h>
+#include <t_syslog.h>
+#include <t_stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <target_syssvc.h>
+#include "syssvc/serial.h"
+#include "syssvc/syslog.h"
+#include "kernel_cfg.h"
+#include "device.h"
+#include "aqm0802_st7032.h"
+
+#define TXBUFFERSIZE  2
+
+#if defined(TOPPERS_BASE_PLATFORM_STF7)
+#define i2c_send(h, a, b, l)    i2c_memwrite((h), (a), 0, 0, (b), (l), 500)
+#else
+#define i2c_send(h, a, b, l)    i2c_memwrite((h), (a), 0, 0, (b), (l))
+#endif
+
+static uint8_t aTxBuffer[TXBUFFERSIZE];
+
+/*
+ *  LCDの初期化
+ */
+ER
+aqm0802_init(CLCD_Handler_t *hlcd)
+{
+	I2C_Handle_t *hi2c = hlcd->hi2c;
+	ER ercd;
+
+	hlcd->max_col = 8;
+	hlcd->max_raw = 2;
+
+	/*
+	 *  LED COMMAND 0x38
+	 */
+    aTxBuffer[0] = ST7032_CMD;
+    aTxBuffer[1] = 0x38;
+	if((ercd = i2c_send(hi2c, hlcd->saddr, aTxBuffer, TXBUFFERSIZE)) != E_OK)
+		return ercd;
+
+    // Wait 70us
+    sil_dly_nse(LCD_INTERVAL1*1000);
+    /*
+	 *  LCD COMMAND 0x39
+	 */
+    aTxBuffer[0] = ST7032_CMD;
+    aTxBuffer[1] = 0x39;
+	if((ercd = i2c_send(hi2c, hlcd->saddr, aTxBuffer, TXBUFFERSIZE)) != E_OK)
+		return ercd;
+
+    // Wait 26.3us
+    sil_dly_nse(LCD_INTERVAL2*1000);
+	/*
+	 *  LCD COMMAND 0x14
+	 */
+    aTxBuffer[0] = ST7032_CMD;
+    aTxBuffer[1] = 0x14;
+	if((ercd = i2c_send(hi2c, hlcd->saddr, aTxBuffer, TXBUFFERSIZE)) != E_OK)
+		return ercd;
+
+    // Wait 26.3us
+    sil_dly_nse(LCD_INTERVAL2*1000);
+	/*
+	 *  LCD COMMAND 0x70
+	 */
+    aTxBuffer[0] = ST7032_CMD;
+    aTxBuffer[1] = 0x70;
+	if((ercd = i2c_send(hi2c, hlcd->saddr, aTxBuffer, TXBUFFERSIZE)) != E_OK)
+		return ercd;
+
+    // Wait 26.3us
+    sil_dly_nse(LCD_INTERVAL2*1000);
+	/*
+	 *  LCD COMMAND 0x56
+	 */
+    aTxBuffer[0] = ST7032_CMD;
+    aTxBuffer[1] = 0x56;
+	if((ercd = i2c_send(hi2c, hlcd->saddr, aTxBuffer, TXBUFFERSIZE)) != E_OK)
+		return ercd;
+
+    // Wait 26.3us
+    sil_dly_nse(LCD_INTERVAL2*1000);
+	/*
+	 *  LCD COMMAND 0x6C
+	 */
+    aTxBuffer[0] = ST7032_CMD;
+    aTxBuffer[1] = 0x6C;
+	if((ercd = i2c_send(hi2c, hlcd->saddr, aTxBuffer, TXBUFFERSIZE)) != E_OK)
+		return ercd;
+
+    // Wait 200ms
+	dly_tsk(200);
+	/*
+	 *  LCD COMMAND 0x38
+	 */
+    aTxBuffer[0] = ST7032_CMD;
+    aTxBuffer[1] = 0x38;
+	if((ercd = i2c_send(hi2c, hlcd->saddr, aTxBuffer, TXBUFFERSIZE)) != E_OK)
+		return ercd;
+
+    // Wait 26.3us
+    sil_dly_nse(LCD_INTERVAL2*1000);
+	/*
+	 * LCD COMMAND 0x0C Display ON/OFF control
+	 */
+    aTxBuffer[0] = ST7032_CMD;
+    aTxBuffer[1] = 0x0C;
+	if((ercd = i2c_send(hi2c, hlcd->saddr, aTxBuffer, TXBUFFERSIZE)) != E_OK)
+		return ercd;
+
+    // Wait 26.3us
+    sil_dly_nse(LCD_INTERVAL2*1000);
+	/*
+	 *  LCD COMMAND 0x01 Clear Display
+	 */
+    aTxBuffer[0] = ST7032_CMD;
+    aTxBuffer[1] = 0x01;
+	if((ercd = i2c_send(hi2c, hlcd->saddr, aTxBuffer, TXBUFFERSIZE)) != E_OK)
+		return ercd;
+
+    // Wait 1.08ms
+	dly_tsk(2);
+	/*
+	 *  LCD COMMAND 0x80
+	 */
+    aTxBuffer[0] = ST7032_CMD;
+    aTxBuffer[1] = 0x80;
+	i2c_send(hi2c, hlcd->saddr, aTxBuffer, TXBUFFERSIZE);
+	return ercd;
+}
+
+/*
+ *  LCDへのコマンド送信関数
+ */
+ER
+aqm0802_set_command(CLCD_Handler_t *hlcd, uint8_t c)
+{
+    aTxBuffer[0] = ST7032_CMD;
+    aTxBuffer[1] = c;
+	return i2c_send(hlcd->hi2c, hlcd->saddr, aTxBuffer, TXBUFFERSIZE);
+}
+
+/*
+ *  LCDへのデータ送信関数
+ */
+ER
+aqm0802_set_data(CLCD_Handler_t *hlcd, uint8_t *p, uint8_t len)
+{
+	ER  ercd = E_OK;
+	int i;
+
+	for(i = 0 ; i < len ; i++){
+	    aTxBuffer[0] = ST7032_DAT;
+    	aTxBuffer[1] = *p++;
+		ercd = i2c_send(hlcd->hi2c, hlcd->saddr, aTxBuffer, TXBUFFERSIZE);
+		if(ercd != E_OK)
+			break;
+    }
+	return ercd;
+}
+
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/aqm0802_st7032/aqm0802_st7032.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/aqm0802_st7032/aqm0802_st7032.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/aqm0802_st7032/aqm0802_st7032.h	(revision 457)
@@ -0,0 +1,96 @@
+/*
+ *  TOPPERS/ASP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Advanced Standard Profile Kernel
+ *
+ *  Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
+ *                              Toyohashi Univ. of Technology, JAPAN
+ *  Copyright (C) 2004-2010 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ *  Copyright (C) 2015-2017 by TOPPERS PROJECT Educational Working Group.
+ *
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ *
+ *  $Id$
+ */
+
+/*
+ *  AQM0802 ST7032 LCD制御プログラムのヘッダファイル
+ */
+
+#ifndef _AQM0802_ST7032_H_
+#define _AQM0802_ST7032_H_
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+#include "device.h"
+#include "pinmode.h"
+#include "i2c.h"
+
+/*
+ *  ST7032 RS R/W
+ */
+#define ST7032_CMD          0x00
+#define ST7032_DAT          0x40
+#define ST7032_CONT         0x80
+
+#define LCD_INTERVAL1       70
+#define LCD_INTERVAL2       27
+
+#ifndef TOPPERS_MACRO_ONLY
+
+/*
+ *  LCDハンドラ構造体定義
+ */
+typedef struct
+{
+	I2C_Handle_t            *hi2c;
+	uint16_t                saddr;		/* 幅ピクセル数 */
+	uint8_t                 max_col;	/* 高さピクセル数 */
+	uint8_t                 max_raw;
+}CLCD_Handler_t;
+
+/*
+ *  関数のプロトタイプ宣言
+ */
+extern ER aqm0802_init(CLCD_Handler_t *hlcd);
+extern ER aqm0802_set_command(CLCD_Handler_t *hlcd, uint8_t c);
+extern ER aqm0802_set_data(CLCD_Handler_t *hlcd, uint8_t *p, uint8_t len);
+
+#endif /* TOPPERS_MACRO_ONLY */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif	/* _AQM0802_ST7032_H_ */
+
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/aqm1248_st7565/Makefile.config
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/aqm1248_st7565/Makefile.config	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/aqm1248_st7565/Makefile.config	(revision 457)
@@ -0,0 +1,56 @@
+#
+#   TOPPERS/ASP/FMP Kernel
+#       Toyohashi Open Platform for Embedded Real-Time Systems/
+#       Advanced Standard Profile Kernel
+#
+#   Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
+#                               Toyohashi Univ. of Technology, JAPAN
+#   Copyright (C) 2003-2008 by Ryosuke Takeuchi
+#                Platform Development Center RICOH COMPANY,LTD. JAPAN
+#   Copyright (C) 2015-2018 by TOPPERS PROJECT Educational Working Group.
+#
+#   上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+#   によって公表されている GNU General Public License の Version 2 に記
+#   述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+#   を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+#   利用と呼ぶ）することを無償で許諾する．
+#   (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+#       権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+#       スコード中に含まれていること．
+#   (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+#       用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+#       者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+#       の無保証規定を掲載すること．
+#   (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+#       用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+#       と．
+#     (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+#         作権表示，この利用条件および下記の無保証規定を掲載すること．
+#     (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+#         報告すること．
+#   (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+#       害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+#
+#   本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+#   よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+#   含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+#   接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+#
+#  @(#) $Id$
+#
+ 
+#
+#  Makefile のプロセッサ依存 (aqm1248 st7565:LCD用)
+#
+
+#
+#  コンパイルオプション
+#
+INCLUDES := $(INCLUDES) -I$(SRCDIR)/gdic/aqm1248_st7565
+
+#
+#  AQM0802 ST7032 LCD DRIVER(GDIC)に関する定義
+#
+SYSSVC_DIR := $(SYSSVC_DIR):$(SRCDIR)/gdic/aqm1248_st7565
+SYSSVC_COBJS := $(SYSSVC_COBJS) aqm1248_st7565.o
+
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/aqm1248_st7565/aqm1248_st7565.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/aqm1248_st7565/aqm1248_st7565.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/aqm1248_st7565/aqm1248_st7565.c	(revision 457)
@@ -0,0 +1,631 @@
+/*
+ *  TOPPERS BASE PLATFORM MIDDLEWARE
+ * 
+ *  Copyright (C) 2017-2019 by TOPPERS PROJECT
+ *                             Educational Working Group.
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  $Id$
+ */
+
+/* 
+ *  AQM1248 ST7565 LCD制御プログラムの本体
+ */
+
+#include <kernel.h>
+#include <t_syslog.h>
+#include <t_stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <target_syssvc.h>
+#include "syssvc/serial.h"
+#include "syssvc/syslog.h"
+#include "kernel_cfg.h"
+#include "device.h"
+#include "aqm1248_st7565.h"
+
+/*
+ *  サービスコールのエラーのログ出力
+ */
+Inline void
+svc_perror(const char *file, int_t line, const char *expr, ER ercd)
+{
+	if (ercd < 0) {
+		t_perror(LOG_ERROR, file, line, expr, ercd);
+	}
+}
+
+#define	SVC_PERROR(expr)	svc_perror(__FILE__, __LINE__, #expr, (expr))
+#define ABS(X)  ((X) > 0 ? (X) : -(X))
+
+#define PORT_HIGH           1
+#define PORT_LOW            0
+
+#define cs_set(sw)  digitalWrite(hlcd->cs_pin, sw)
+#define rs_set(sw)  digitalWrite(hlcd->rs_pin, sw)
+#define rst_set(sw) digitalWrite(hlcd->rst_pin, sw)
+
+static const uint8_t left_mask_table[8] = {
+	0xFF, 0x7F, 0x3F, 0x1F, 0x0F, 0x07, 0x03, 0x01
+};
+
+static const uint8_t right_mask_table[8] = {
+	0x80, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC, 0xFE, 0xFF
+};
+
+static const uint8_t dither_table[8][8] = {
+	{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},	/* BLACK */
+	{0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55},	/* BLUE */
+	{0xFA, 0x5F, 0xF5, 0xAF, 0xFA, 0x5F, 0xF5, 0xAF},	/* GREEN */
+	{0xFD, 0xDF, 0xFB, 0xBF, 0xFD, 0xDF, 0xFB, 0xBF},	/* CYAN */
+	{0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA},	/* RED */
+	{0xAF, 0xF5, 0x5F, 0xFA, 0xAF, 0xF5, 0x5F, 0xFA},	/* MAGENTA */
+	{0xDF, 0xFD, 0xBF, 0xFB, 0xDF, 0xFD, 0xBF, 0xFB},	/* YELLOW */
+	{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}	/* WHITE */
+};
+
+/* Buffer used for transmission */
+static uint8_t aTxBuffer[4];
+
+
+/*
+ *  バッファデータをLCDに転送
+ */
+static void
+lcd_flush_buffer(LCD_Handler_t *hlcd)
+{
+	uint32_t l, col, i;
+	uint8_t page, val1, val2;
+
+	for(l = hlcd->_winy1 ; l <= hlcd->_winy2 ; l += AQM1248_PLINE){
+		page = l / AQM1248_PLINE;
+		col  = hlcd->_winx1;
+		SVC_PERROR(lcd_writecommand(hlcd, ST7565_PAGEADR + page));
+		SVC_PERROR(lcd_writecommand(hlcd, ST7565_COLADR + (col >> 4)));
+		SVC_PERROR(lcd_writecommand(hlcd, (col & 0x0f)));
+		for(; col <= hlcd->_winx2 ; col++){
+			for(i = val1 = 0 ; i < 8 ; i++){
+				val2  = hlcd->buffer[(page * AQM1248_PLINE) + i][col/8] << (col & 7);
+				val1 |= (val2 & 0x80) >> (7 - i);
+			}
+			SVC_PERROR(lcd_writedata(hlcd, val1));
+		}
+	}
+}
+
+/*
+ *  バッファ上にイメージを作る
+ */
+static void
+lcd_fill_buffer(LCD_Handler_t *hlcd, color_t color)
+{
+	uint32_t x, y;
+	uint8_t  *p;
+
+	color &= 7;
+	for(y = hlcd->_winy1 ; y <= hlcd->_winy2 ; y++){
+		p = &hlcd->buffer[y][hlcd->_winx1/8];
+		for(x = 0 ; x < hlcd->stride ; x++, p++){
+			if(x == 0){
+				*p &= ~hlcd->lmask;
+				*p |= dither_table[color][y & 7] & hlcd->lmask;
+			}
+			else if(x == (hlcd->stride-1)){
+				*p &= ~hlcd->rmask;
+				*p |= dither_table[color][y & 7] & hlcd->rmask;
+			}
+			else
+				*p = dither_table[color][y & 7];
+		}
+	}
+}
+
+/*
+ *  LCDへのコマンド送信関数
+ */
+ER
+lcd_writecommand(LCD_Handler_t *hlcd, uint8_t c)
+{
+	ER ercd = E_OK;
+
+	if(hlcd->spi_lock != 0){
+		if((ercd = wai_sem(hlcd->spi_lock)) != E_OK)
+			return ercd;
+	}
+	rs_set(PORT_LOW);
+	cs_set(PORT_LOW);
+
+	aTxBuffer[0] = c;
+#if SPI_WAIT_TIME != 0
+	ercd = spi_transmit(hlcd->hspi, (uint8_t*)aTxBuffer, 1);
+#else
+	if((ercd = spi_transmit(hlcd->hspi, (uint8_t*)aTxBuffer, 1)) == E_OK){
+		ercd = spi_wait(hlcd->hspi, 100);
+	}
+#endif
+
+	cs_set(PORT_HIGH);
+	if(hlcd->spi_lock != 0)
+		sig_sem(hlcd->spi_lock);
+	return ercd;
+}
+
+/*
+ *  LCDへのデータ送信関数
+ */
+ER
+lcd_writedata(LCD_Handler_t *hlcd, uint8_t c)
+{
+	ER ercd = E_OK;
+
+	if(hlcd->spi_lock != 0){
+		if((ercd = wai_sem(hlcd->spi_lock)) != E_OK)
+			return ercd;
+	}
+	rs_set(PORT_HIGH);
+	cs_set(PORT_LOW);
+	sil_dly_nse(100);
+
+	aTxBuffer[0] = c;
+#if SPI_WAIT_TIME != 0
+	ercd = spi_transmit(hlcd->hspi, (uint8_t*)aTxBuffer, 1);
+#else
+	if((ercd = spi_transmit(hlcd->hspi, (uint8_t*)aTxBuffer, 1)) == E_OK){
+		ercd = spi_wait(hlcd->hspi, 100);
+	}
+#endif
+
+	sil_dly_nse(100);
+	cs_set(PORT_HIGH);
+	if(hlcd->spi_lock != 0)
+		sig_sem(hlcd->spi_lock);
+	return ercd;
+}
+
+
+/*
+ *  ST7565 LCDの初期化関数
+ */
+void
+lcd_init(LCD_Handler_t *hlcd)
+{
+	uint32_t i;
+
+	rst_set(PORT_LOW);
+	dly_tsk(100);
+	rst_set(PORT_HIGH);
+	dly_tsk(100);
+
+	hlcd->_width  = AQM1248_WIDTH;
+	hlcd->_height = AQM1248_HEIGHT;
+
+	SVC_PERROR(lcd_writecommand(hlcd, ST7565_DISPOFF));		/* 表示OFF */
+	SVC_PERROR(lcd_writecommand(hlcd, ST7565_ADCSELN));		/* ADC select normal */
+	SVC_PERROR(lcd_writecommand(hlcd, ST7565_COMOUTR));		/* comon output reverse */
+	SVC_PERROR(lcd_writecommand(hlcd, ST7565_BIAS17));		/* lcd bias 1/7 */
+
+	SVC_PERROR(lcd_writecommand(hlcd, ST7565_PWRSEL+4));	/* power select 1 */
+	dly_tsk(2);
+	SVC_PERROR(lcd_writecommand(hlcd, ST7565_PWRSEL+6));	/* power select 2 */
+	dly_tsk(2);
+	SVC_PERROR(lcd_writecommand(hlcd, ST7565_PWRSEL+7));	/* power select 3 */
+
+	SVC_PERROR(lcd_writecommand(hlcd, ST7565_RATSEL+3));	/* voltage resistor ratio 3 */
+	SVC_PERROR(lcd_writecommand(hlcd, ST7565_SETEVOL));		/* electronic volume set */
+	SVC_PERROR(lcd_writecommand(hlcd, 0x1C));				/* volume value */
+
+	SVC_PERROR(lcd_writecommand(hlcd, ST7565_ALLPNL));		/* all point normal */
+	SVC_PERROR(lcd_writecommand(hlcd, ST7565_STRLINE));		/* start line #0 */
+	SVC_PERROR(lcd_writecommand(hlcd, ST7565_DISPREV));		/* 表示reverse */
+	SVC_PERROR(lcd_writecommand(hlcd, ST7565_DISPON));		/* 表示ON */
+	for(i = 0 ; i < AQM1248_HEIGHT ; i++)
+		memset(&hlcd->buffer[i][0], 0xff, AQM1248_WIDTH/8);
+}
+
+/*
+ *  表示ウィンドウ設定
+ */
+void
+lcd_setAddrWindow(LCD_Handler_t *hlcd, uint8_t x0, uint8_t y0, uint8_t x1, uint8_t y1)
+{
+	uint8_t hx = x0 & 7;
+
+	hlcd->_winx1 = x0;
+	hlcd->_winy1 = y0;
+	hlcd->_winx2 = x1;
+	hlcd->_winy2 = y1;
+	hlcd->lmask  = left_mask_table[hx];
+	hlcd->rmask  = right_mask_table[x1 & 7];
+	if(hx == 0)
+		hlcd->stride = (x1 - x0 + 8) / 8;
+	else
+		hlcd->stride = (x1 - x0 + hx) / 8 + 1;
+	if(hlcd->stride == 1)
+		hlcd->lmask &= hlcd->rmask;
+}
+
+/*
+ *  RECTANGLEのフィル描画
+ *  param1  hlcd: Pointer to LCD Handler
+ *  param2  x: start X position
+ *  param3  y: start Y position
+ *  param4  w: width
+ *  param5  h: height
+ *  param6  color: color value
+ */
+void
+lcd_fillRect(LCD_Handler_t *hlcd, int16_t x, int16_t y, int16_t w, int16_t h, color_t color)
+{
+	// rudimentary clipping (drawChar w/big text requires this)
+	if((x >= hlcd->_width) || (y >= hlcd->_height)) return;
+	if((x + w - 1) >= hlcd->_width)  w = hlcd->_width  - x;
+	if((y + h - 1) >= hlcd->_height) h = hlcd->_height - y;
+
+	lcd_setAddrWindow(hlcd, x, y, x+w-1, y+h-1);
+	lcd_fill_buffer(hlcd, color);
+	lcd_flush_buffer(hlcd);
+}
+
+/*
+ *  PIXEL描画
+ *  param1  hlcd: Pointer to LCD Handler
+ *  param2  x: X position
+ *  param3  y: Y position
+ *  param4  color: color value
+ */
+void
+lcd_drawPixel(LCD_Handler_t *hlcd, int16_t x, int16_t y, color_t color)
+{
+	if((x < 0) ||(x >= hlcd->_width) || (y < 0) || (y >= hlcd->_height)) return;
+
+	lcd_setAddrWindow(hlcd, x, y, x, y);
+	lcd_fill_buffer(hlcd, color);
+	lcd_flush_buffer(hlcd);
+}
+
+/*
+ *  垂直方向LINEの高速描画
+ *  param1  hlcd: Pointer to LCD Handler
+ *  param2  x: start X position
+ *  param3  y: start Y position
+ *  param4  h: height
+ *  param5  color: color value
+ */
+void
+lcd_drawFastVLine(LCD_Handler_t *hlcd, int16_t x, int16_t y, int16_t h, color_t color)
+{
+	// Rudimentary clipping
+	if((x >= hlcd->_width) || (y >= hlcd->_height)) return;
+	if((y+h-1) >= hlcd->_height) h = hlcd->_height-y;
+	lcd_setAddrWindow(hlcd, x, y, x, y+h-1);
+	lcd_fill_buffer(hlcd, color);
+	lcd_flush_buffer(hlcd);
+}
+
+/*
+ *  水平方向LINEの高速描画
+ *  param1  hlcd: Pointer to LCD Handler
+ *  param2  x: start X position
+ *  param3  y: start Y position
+ *  param4  w: width
+ *  param5  color: color value
+ */
+void lcd_drawFastHLine(LCD_Handler_t *hlcd, int16_t x, int16_t y, int16_t w, color_t color)
+{
+	// Rudimentary clipping
+	if((x >= hlcd->_width) || (y >= hlcd->_height)) return;
+	if((x+w-1) >= hlcd->_width)  w = hlcd->_width-x;
+	lcd_setAddrWindow(hlcd, x, y, x+w-1, y);
+	lcd_fill_buffer(hlcd, color);
+	lcd_flush_buffer(hlcd);
+}
+
+/*
+ *  DRAW IMAGE LINE描画
+ *  param1  hlcd: Pointer to LCD Handler
+ *  param2  x: X position
+ *  param3  y: Y position
+ *  param4  w: width
+ *  param5  pcolor: color value
+ */
+void
+lcd_drawImageHLine(LCD_Handler_t *hlcd, int16_t x, int16_t y, uint16_t w, color_t *pcolor)
+{
+	uint32_t i;
+
+	if((x >= hlcd->_width) || (y >= hlcd->_height)) return;
+	if((x+w-1) >= hlcd->_width)  w = hlcd->_width-x;
+
+	for(i = 0 ; i < w ; i++, pcolor++){
+		lcd_setAddrWindow(hlcd, x+i, y, x+i, y);
+		lcd_fill_buffer(hlcd, *pcolor);
+		lcd_flush_buffer(hlcd);
+	}
+}
+
+/*
+ *  BITMAP描画
+ *  param1  hlcd: Pointer to LCD Handler
+ *  param2  x0: Bmp X position in the LCD
+ *  param3  y0: Bmp Y position in the LCD
+ *  param4  pbmp: Pointer to Bmp picture address in the internal Flash
+ */
+void
+lcd_drawBitmap(LCD_Handler_t *hlcd, uint16_t x0, uint16_t y0, uint8_t *pbmp)
+{
+	uint32_t index = 0, width = 0, height = 0, bit_pixel = 0;
+	uint32_t input_color_mode = 0;
+	uint16_t val, l, col;
+
+	/* Get bitmap data address offset */
+	index = *(uint16_t *) (pbmp + 10);
+	index |= (*(uint16_t *) (pbmp + 12)) << 16;
+
+	/* Read bitmap width */
+	width = *(uint16_t *) (pbmp + 18);
+	width |= (*(uint16_t *) (pbmp + 20)) << 16;
+
+	/* Read bitmap height */
+	height = *(uint16_t *) (pbmp + 22);
+	height |= (*(uint16_t *) (pbmp + 24)) << 16;
+
+	/* Read bit/pixel */
+	bit_pixel = *(uint16_t *) (pbmp + 28);
+
+	/* Get the layer pixel format */
+	if ((bit_pixel/8) == 4){
+		input_color_mode = CM_ARGB8888;
+	}
+	else if ((bit_pixel/8) == 2){
+		input_color_mode = CM_RGB565;
+	}
+	else{
+		input_color_mode = CM_RGB888;
+	}
+
+	/* Bypass the bitmap header */
+	pbmp += (index + (width * (height - 1) * (bit_pixel/8)));  
+	syslog_4(LOG_NOTICE, "## input_color_mode(%d) width(%d) height(%d) bit_pixel(%d) ##", input_color_mode, width, height, bit_pixel);
+
+	for(l = 0 ; l < height ; l++){
+		uint8_t *p = pbmp;
+		for(col = 0 ; col < width ; col++){
+			switch(input_color_mode){
+			case CM_RGB565:
+				if((*p & 0xC0) == 0xC0)
+					val = 0x04;
+				else
+					val = 0x00;
+				if((*p++ & 0x06) == 0x06)
+					val |= 0x02;
+				if((*p++ & 0x18) == 0x18)
+					val |= 0x01;
+				break;
+			default:
+				if((*p++ & 0xE0) == 0xE0)
+					val = 0x04;
+				else
+					val = 0x00;
+				if((*p++ & 0xE0) == 0xE0)
+					val |= 0x02;
+				if((*p++ & 0xE0) == 0xE0)
+					val |= 0x01;
+				break;
+			}
+			if((l+y0) < hlcd->_height)
+				lcd_drawPixel(hlcd, col+x0, l+y0, val);
+		}
+		pbmp -= (bit_pixel/8) * width;
+	}
+}
+
+/*
+ *  INVERT DISPLAY
+ *  param1  hlcd: Pointer to LCD Handler
+ *  param2  i: invert value
+ */
+void
+lcd_invertDisplay(LCD_Handler_t *hlcd, bool_t i)
+{
+ 	SVC_PERROR(lcd_writecommand(hlcd, i ? ST7565_DISPNOR : ST7565_DISPREV));
+}
+
+
+/*
+ *  スクリーンフィル
+ *  param1  pDrawProp: Pointer to Draw Prop
+ */
+void
+lcd_fillScreen(LCD_DrawProp_t *pDrawProp)
+{
+	lcd_fillRect(pDrawProp->hlcd, 0, 0,  pDrawProp->hlcd->_width, pDrawProp->hlcd->_height, pDrawProp->BackColor);
+}
+
+/*
+ *  RECTANGLE描画
+ *  param1  pDrawProp: Pointer to Draw Prop
+ *  param2  x: left X position
+ *  param3  y: top Y position
+ *  param4  w: width
+ *  param5  h: height
+ */
+void
+lcd_drawRect(LCD_DrawProp_t *pDrawProp, int16_t x, int16_t y, int16_t w, int16_t h)
+{
+	LCD_Handler_t *hlcd = pDrawProp->hlcd;
+	color_t color;
+
+	// rudimentary clipping (drawChar w/big text requires this)
+	if((x >= hlcd->_width) || (y >= hlcd->_height)) return;
+	if(y < 0) return;
+	if((x + w - 1) >= hlcd->_width)  w = hlcd->_width  - x;
+	if((y + h - 1) >= hlcd->_height) h = hlcd->_height - y;
+
+	color = pDrawProp->TextColor;
+	lcd_drawFastVLine(hlcd, x, y, h, color);
+	lcd_drawFastHLine(hlcd, x, y+h-1, w, color);
+	lcd_drawFastVLine(hlcd, x+w-1, y, h, color);
+	lcd_drawFastHLine(hlcd, x, y, w, color);
+}
+
+/*
+ *  円描画
+ *  param1  pDrawProp: Pointer to Draw Prop
+ *  param2  x0: X position
+ *  param3  y0: Y position
+ *  param4  Radius: Circle radius
+ */
+void
+lcd_DrawCircle(LCD_DrawProp_t *pDrawProp, uint16_t x0, uint16_t y0, uint16_t Radius)
+{
+	LCD_Handler_t *hlcd = pDrawProp->hlcd;
+ 	int32_t   decision;    /* Decision Variable */ 
+	uint32_t  current_x;   /* Current X Value */
+	uint32_t  current_y;   /* Current Y Value */
+
+	decision = 3 - (Radius << 1);
+	current_x = 0;
+	current_y = Radius;
+
+	while(current_x <= current_y){
+		lcd_drawPixel(hlcd, (x0 + current_x), (y0 - current_y), pDrawProp->TextColor);
+		lcd_drawPixel(hlcd, (x0 - current_x), (y0 - current_y), pDrawProp->TextColor);
+		lcd_drawPixel(hlcd, (x0 + current_y), (y0 - current_x), pDrawProp->TextColor);
+		lcd_drawPixel(hlcd, (x0 - current_y), (y0 - current_x), pDrawProp->TextColor);
+		lcd_drawPixel(hlcd, (x0 + current_x), (y0 + current_y), pDrawProp->TextColor);
+		lcd_drawPixel(hlcd, (x0 - current_x), (y0 + current_y), pDrawProp->TextColor);
+		lcd_drawPixel(hlcd, (x0 + current_y), (y0 + current_x), pDrawProp->TextColor);
+		lcd_drawPixel(hlcd, (x0 - current_y), (y0 + current_x), pDrawProp->TextColor);
+
+		if (decision < 0){
+			decision += (current_x << 2) + 6;
+		}
+		else{
+			decision += ((current_x - current_y) << 2) + 10;
+			current_y--;
+		}
+		current_x++;
+	}
+}
+
+/*
+ *  線描画
+ *  param1  pDrawProp: Pointer to Draw Prop
+ *  param2  x1: Point 1 X position
+ *  param3  y1: Point 1 Y position
+ *  param4  x2: Point 2 X position
+ *  param5  y2: Point 2 Y position
+ */
+void
+lcd_drawLine(LCD_DrawProp_t *pDrawProp, uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2)
+{
+	LCD_Handler_t *hlcd = pDrawProp->hlcd;
+	int16_t deltax = 0, deltay = 0, x = 0, y = 0, xinc1 = 0, xinc2 = 0, 
+	yinc1 = 0, yinc2 = 0, den = 0, num = 0, num_add = 0, num_pixels = 0, 
+	curpixel = 0;
+
+	deltax = ABS(x2 - x1);		/* The difference between the x's */
+	deltay = ABS(y2 - y1);		/* The difference between the y's */
+	x = x1;						/* Start x off at the first pixel */
+	y = y1;						/* Start y off at the first pixel */
+
+	if(x2 >= x1){				/* The x-values are increasing */
+		xinc1 = 1;
+		xinc2 = 1;
+	}
+	else{						/* The x-values are decreasing */
+		xinc1 = -1;
+		xinc2 = -1;
+	}
+
+	if(y2 >= y1){				/* The y-values are increasing */
+		yinc1 = 1;
+		yinc2 = 1;
+	}
+	else{						/* The y-values are decreasing */
+		yinc1 = -1;
+		yinc2 = -1;
+	}
+
+	if(deltax >= deltay){		/* There is at least one x-value for every y-value */
+		xinc1 = 0;				/* Don't change the x when numerator >= denominator */
+		yinc2 = 0;				/* Don't change the y for every iteration */
+		den = deltax;
+		num = deltax / 2;
+		num_add = deltay;
+		num_pixels = deltax;	/* There are more x-values than y-values */
+	}
+	else{						/* There is at least one y-value for every x-value */
+		xinc2 = 0;				/* Don't change the x for every iteration */
+		yinc1 = 0;				/* Don't change the y when numerator >= denominator */
+		den = deltay;
+		num = deltay / 2;
+		num_add = deltax;
+		num_pixels = deltay;	/* There are more y-values than x-values */
+	}
+
+	for (curpixel = 0; curpixel <= num_pixels; curpixel++){
+		lcd_drawPixel(hlcd, x, y, pDrawProp->TextColor);	/* Draw the current pixel */
+		num += num_add;			/* Increase the numerator by the top of the fraction */
+		if(num >= den){			/* Check if numerator >= denominator */
+			num -= den;			/* Calculate the new numerator value */
+			x += xinc1;			/* Change the x as appropriate */
+			y += yinc1;			/* Change the y as appropriate */
+		}
+		x += xinc2;				/* Change the x as appropriate */
+		y += yinc2;				/* Change the y as appropriate */
+	}
+}
+
+/*
+ *  PLOY-LINE描画
+ *  param1  pDrawProp: Pointer to Draw Prop
+ *  param2  Points: Pointer to the points array
+ *  param3  PointCount: Number of points
+ */
+void
+lcd_drawPolygon(LCD_DrawProp_t *pDrawProp, pPoint Points, uint16_t PointCount)
+{
+	int16_t x = 0, y = 0;
+
+	if(PointCount < 2){
+		return;
+	}
+
+	lcd_drawLine(pDrawProp, Points->X, Points->Y, (Points+PointCount-1)->X, (Points+PointCount-1)->Y);
+	while(--PointCount){
+		x = Points->X;
+		y = Points->Y;
+		Points++;
+		lcd_drawLine(pDrawProp, x, y, Points->X, Points->Y);
+	}
+}
+
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/aqm1248_st7565/aqm1248_st7565.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/aqm1248_st7565/aqm1248_st7565.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/aqm1248_st7565/aqm1248_st7565.h	(revision 457)
@@ -0,0 +1,175 @@
+/*
+ *  TOPPERS BASE PLATFORM MIDDLEWARE
+ * 
+ *  Copyright (C) 2017-2019 by TOPPERS PROJECT
+ *                             Educational Working Group.
+ *
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ *
+ *  $Id$
+ */
+
+/*
+ *  AQM1248 ST7565 LCD制御プログラムのヘッダファイル
+ */
+
+#ifndef _AQM1248_ST7565_H_
+#define _AQM1248_ST7565_H_
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+#include "device.h"
+#include "pinmode.h"
+#include "spi.h"
+
+/*
+ *  LCDカラーモード定義
+ */
+#define CM_ARGB8888         0x00000000			/* ARGB8888 color mode */
+#define CM_RGB888           0x00000001			/* RGB888 color mode */
+#define CM_RGB565           0x00000002			/* RGB565 color mode */
+
+#define AQM1248_WIDTH  128
+#define AQM1248_HEIGHT 48
+#define AQM1248_PLINE  8
+
+#define ST7565_COLADR  0x10
+#define ST7565_RATSEL  0x20
+#define ST7565_PWRSEL  0x28
+#define ST7565_STRLINE 0x40
+#define ST7565_SETEVOL 0x81
+
+#define ST7565_ADCSELN 0xA0
+#define ST7565_ADCSELR 0xA1
+#define ST7565_BIAS19  0xA2
+#define ST7565_BIAS17  0xA3
+#define ST7565_ALLPNL  0xA4
+#define ST7565_ALLPON  0xA5
+#define ST7565_DISPNOR 0xA6
+#define ST7565_DISPREV 0xA7
+#define ST7565_DISPOFF 0xAE
+#define ST7565_DISPON  0xAF
+#define ST7565_PAGEADR 0xB0
+
+#define ST7565_COMOUTN 0xC0
+#define ST7565_COMOUTR 0xC8
+#define ST7565_NOP     0xE3
+
+// Color definitions
+#define	ST7565_BLACK   0x00
+#define	ST7565_BLUE    0x01
+#define	ST7565_GREEN   0x02
+#define ST7565_CYAN    0x03
+#define	ST7565_RED     0x04
+#define ST7565_MAGENTA 0x05
+#define ST7565_YELLOW  0x06
+#define ST7565_WHITE   0x07
+
+#ifndef TOPPERS_MACRO_ONLY
+
+/*
+ *  カラーの属性を定義
+ */
+typedef uint16_t   color_t;
+
+
+/*
+ *  LCDハンドラ構造体定義
+ */
+typedef struct
+{
+	SPI_Handle_t            *hspi;		/* spiハンドラ */
+	uint16_t                _width;		/* 幅ピクセル数 */
+	uint16_t				_height;	/* 高さピクセル数 */
+	uint16_t                _winx1;
+	uint16_t                _winy1;
+	uint16_t                _winx2;
+	uint16_t                _winy2;
+	ID                      spi_lock;
+	uint8_t                 cs_pin;
+	uint8_t                 rs_pin;
+	uint8_t                 rst_pin;
+	uint8_t                 lmask;
+	uint8_t                 rmask;
+	uint8_t                 stride;
+	uint8_t                 dummy[2];
+	uint8_t                 buffer[AQM1248_HEIGHT][AQM1248_WIDTH/8];
+}LCD_Handler_t;
+
+/*
+ *  描画構造体
+ */
+typedef struct
+{
+	LCD_Handler_t           *hlcd;
+	color_t                 TextColor;
+	color_t                 BackColor;
+	void                    *pFont;
+}LCD_DrawProp_t;
+
+typedef struct
+{
+	int16_t X;
+	int16_t Y;
+}Point, * pPoint;
+
+/*
+ *  関数のプロトタイプ宣言
+ */
+extern ER lcd_writecommand(LCD_Handler_t *hlcd, uint8_t c);
+extern ER lcd_writedata(LCD_Handler_t *hlcd, uint8_t c);
+
+extern void lcd_init(LCD_Handler_t *hlcd);
+extern void lcd_setAddrWindow(LCD_Handler_t *hlcd, uint8_t x0, uint8_t y0, uint8_t x1, uint8_t y1);
+extern void lcd_fillRect(LCD_Handler_t *hlcd, int16_t x, int16_t y, int16_t w, int16_t h, color_t color);
+extern void lcd_pushColor(LCD_Handler_t *hlcd, color_t color);
+extern void lcd_drawPixel(LCD_Handler_t *hlcd, int16_t x, int16_t y, color_t color);
+extern void lcd_drawFastVLine(LCD_Handler_t *hlcd, int16_t x, int16_t y, int16_t h, color_t color);
+extern void lcd_drawFastHLine(LCD_Handler_t *hlcd, int16_t x, int16_t y, int16_t w, color_t color);
+extern void lcd_drawImageHLine(LCD_Handler_t *hlcd, int16_t x, int16_t y, uint16_t w, color_t *pcolor);
+extern void lcd_drawBitmap(LCD_Handler_t *hlcd, uint16_t x0, uint16_t y0, uint8_t *pbmp);
+extern void lcd_invertDisplay(LCD_Handler_t *hlcd, bool_t i);
+
+extern void lcd_fillScreen(LCD_DrawProp_t *pDrawProp);
+extern void lcd_drawRect(LCD_DrawProp_t *pDrawProp, int16_t x, int16_t y, int16_t w, int16_t h);
+extern void lcd_DrawCircle(LCD_DrawProp_t *pDrawProp, uint16_t x0, uint16_t y0, uint16_t Radius);
+extern void lcd_drawLine(LCD_DrawProp_t *pDrawProp, uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2);
+extern void lcd_drawPolygon(LCD_DrawProp_t *pDrawProp, pPoint Points, uint16_t PointCount);
+
+#endif /* TOPPERS_MACRO_ONLY */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif	/* _AQM1248_ST7565_H_ */
+
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/aqm1248_st7565/glcd_core.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/aqm1248_st7565/glcd_core.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/aqm1248_st7565/glcd_core.h	(revision 457)
@@ -0,0 +1,45 @@
+/*
+ *  TOPPERS BASE PLATFORM MIDDLEWARE
+ * 
+ *  Copyright (C) 2017-2018 by TOPPERS PROJECT
+ *                             Educational Working Group.
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+#ifndef _LCD_CORE_H_
+#define _LCD_CORE_H_
+
+#include "aqm1248_st7565.h"
+
+#endif /* _LCD_CORE_H_ */
+
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/ble_shield2.1/BLEAttribute.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/ble_shield2.1/BLEAttribute.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/ble_shield2.1/BLEAttribute.h	(revision 457)
@@ -0,0 +1,114 @@
+/*
+ *  TOPPERS BASE PLATFORM MIDDLEWARE
+ * 
+ *  Copyright (C) 2017-2018 by TOPPERS PROJECT
+ *                             Educational Working Group.
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+The MIT License (MIT)
+
+Copyright (c) 2014 Sandeep Mistry
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+*/
+
+#ifndef _BLE_ATTRIBUTE_H_
+#define _BLE_ATTRIBUTE_H_
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+enum BLEAttributeType {
+	BLETypeService        = 0x2800,
+	BLETypeCharacteristic = 0x2803,
+	BLETypeDescriptor     = 0x2900
+};
+
+enum BLEProperty {
+	BLERead                 = 0x02,
+	BLEWriteWithoutResponse = 0x04,
+	BLEWrite                = 0x08,
+	BLENotify               = 0x10,
+	BLEIndicate             = 0x20
+};
+
+#define MAX_UUID_LENGTH                   16
+#define BLE_ATTRIBUTE_MAX_VALUE_LENGTH    19
+
+typedef struct _nRF8001 nRF8001;
+
+typedef struct _BLEUuid {
+  const char *   _str;
+  unsigned char  _data[MAX_UUID_LENGTH];
+  unsigned char  _length;
+} BLEUuid;
+
+
+typedef struct _BLEAttribute {
+  BLEUuid               _uuid;
+  enum BLEAttributeType _type;
+} BLEAttribute;
+
+#define BLEService  BLEAttribute
+
+typedef struct _BLEDescriptor {
+  BLEAttribute          _attr;
+  unsigned char         _valueSize;
+  unsigned char*        _value;
+  unsigned char         _valueLength;
+} BLEDescriptor;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif	/* _BLE_ATTRIBUTE_H_ */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/ble_shield2.1/BLECentral.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/ble_shield2.1/BLECentral.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/ble_shield2.1/BLECentral.c	(revision 457)
@@ -0,0 +1,134 @@
+/*
+ *  TOPPERS BASE PLATFORM MIDDLEWARE
+ * 
+ *  Copyright (C) 2017-2018 by TOPPERS PROJECT
+ *                             Educational Working Group.
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+The MIT License (MIT)
+
+Copyright (c) 2014 Sandeep Mistry
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+*/
+
+#include <utility/lib_aci.h>
+#include <utility/aci_setup.h>
+#include "BLECentral.h"
+#include "BLECharacteristic.h"
+#include "BLEPeripheral.h"
+
+/*
+ *  BLECentral接続判定
+ */
+bool_t
+BLECentral_connected(BLECentral *pcent)
+{
+	BLEPeripheral *pblep = pcent->_peripheral;
+	if(pblep == NULL)
+		return false;
+	BLECentral_poll(pcent);
+	return pcent->_connected;
+}
+
+/*
+ *  BLECentralポーリング
+ */
+void
+BLECentral_poll(BLECentral *pcent)
+{
+	BLEPeripheral *pblep = pcent->_peripheral;
+	if(pblep == NULL)
+		return;
+	BLEPeripheral_poll(pblep);
+}
+
+/*
+ *  BLECentral切断
+ */
+void
+BLECentral_disconnect(BLECentral *pcent)
+{
+	BLEPeripheral *pblep = pcent->_peripheral;
+	if(pblep == NULL)
+		return;
+	if(BLECentral_connected(pcent)){
+		nRF8001_disconnect(&pblep->_nRF8001);
+	}
+}
+
+/*
+ *  BLECentralアドレス設定
+ */
+void
+BLECentral_setAddress(BLECentral *pcent, const uint8_t *address)
+{
+	memcpy(pcent->_address, address, sizeof(pcent->_address));
+}
+
+/*
+ *  BLECentralアドレスクリア
+ */
+void
+BLECentral_clearAddress(BLECentral *pcent)
+{
+	memset(pcent->_address, 0x00, sizeof(pcent->_address));
+}
+
+/*
+ *  BLECentralアドレス比較
+ */
+bool_t
+BLECentral_cmpAddress(BLECentral *pcent, const uint8_t *address)
+{
+	return (memcmp(pcent->_address, address, sizeof(pcent->_address)) == 0);
+}
+
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/ble_shield2.1/BLECentral.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/ble_shield2.1/BLECentral.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/ble_shield2.1/BLECentral.h	(revision 457)
@@ -0,0 +1,87 @@
+/*
+ *  TOPPERS BASE PLATFORM MIDDLEWARE
+ * 
+ *  Copyright (C) 2017-2018 by TOPPERS PROJECT
+ *                             Educational Working Group.
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+The MIT License (MIT)
+
+Copyright (c) 2014 Sandeep Mistry
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+*/
+
+#ifndef _BLE_CENTRAL_H_
+#define _BLE_CENTRAL_H_
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+typedef struct _BLECentral {
+	void*          _peripheral;	/* BLEPeripheral */
+	bool_t         _connected;
+	unsigned char  _address[6];
+} BLECentral;
+
+extern bool_t BLECentral_connected(BLECentral *pcent);
+extern void BLECentral_poll(BLECentral *pcent);
+extern void BLECentral_disconnect(BLECentral *pcent);
+extern void BLECentral_setAddress(BLECentral *pcent, const uint8_t *address);
+extern void BLECentral_clearAddress(BLECentral *pcent);
+extern bool_t BLECentral_cmpAddress(BLECentral *pcent, const uint8_t *address);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/ble_shield2.1/BLECharacteristic.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/ble_shield2.1/BLECharacteristic.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/ble_shield2.1/BLECharacteristic.c	(revision 457)
@@ -0,0 +1,263 @@
+/*
+ *  TOPPERS BASE PLATFORM MIDDLEWARE
+ * 
+ *  Copyright (C) 2017-2019 by TOPPERS PROJECT
+ *                             Educational Working Group.
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+The MIT License (MIT)
+
+Copyright (c) 2014 Sandeep Mistry
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+*/
+
+#include <stdlib.h>
+#include <utility/lib_aci.h>
+#include <utility/aci_setup.h>
+#include "BLECentral.h"
+#include "BLECharacteristic.h"
+#include "BLEPeripheral.h"
+
+#define MIN(a, b) ((a) > (b) ? (b) : (a))
+
+static unsigned int
+convert_hex(const char a)
+{
+	if(a >= '0' && a <= '9')
+		return a - '0';
+	else if(a >= 'A' && a <= 'F')
+		return a - 'A' + 10;
+	else if(a >= 'a' && a <= 'f')
+		return a - 'a' + 10;
+	else
+		return 0;
+}
+
+static int
+uuid_setup(BLEUuid* puuid, const char *str)
+{
+  int i, len = 0;
+
+  puuid->_str = str;
+  puuid->_length = 0;
+  for (i = strlen(str) - 1; i >= 0 && puuid->_length < MAX_UUID_LENGTH; i -= 2) {
+    if (str[i] == '-') {
+      i++;
+      continue;
+    }
+
+	len = convert_hex(str[i - 1]) << 4;
+	len |= convert_hex(str[i]);
+	puuid->_data[puuid->_length] = len;
+
+    puuid->_length++;
+  }
+  return puuid->_length;
+}
+
+/*
+ *  BLEServiceセットアップ
+ */
+void
+BLEService_setup(BLEService* pserv, const char *uuid)
+{
+	uuid_setup(&pserv->_uuid, uuid);
+	pserv->_type = BLETypeService;
+}
+
+/*
+ *  BLECharacteristicセットアップ
+ */
+void
+BLECharacteristic_setup(BLECharacteristic* pcharc, const char *uuid, unsigned char properties, unsigned char *value, unsigned char len)
+{
+	memset(pcharc, 0, sizeof(BLECharacteristic));
+	uuid_setup(&pcharc->_attr._uuid, uuid);
+	pcharc->_attr._type  = BLETypeCharacteristic;
+	pcharc->_properties  = properties;
+	pcharc->_valueSize   = MIN(BLE_ATTRIBUTE_MAX_VALUE_LENGTH, len);
+	pcharc->_value = value;
+	pcharc->_valueLength = 0;
+	pcharc->_fixedLength = 0;
+	pcharc->_notify      = false;
+	pcharc->_written     = false;
+	pcharc->_subscribed  = false;
+}
+
+/*
+ *  BLECharacteristic値設定(値の長さあり)
+ */
+bool_t
+BLECharacteristic_setValue1(BLECharacteristic *pcharc, const unsigned char value[], unsigned char length)
+{
+	bool_t success = true;
+
+	if(length > pcharc->_valueSize)
+		pcharc->_valueLength = pcharc->_valueSize;
+	else
+		pcharc->_valueLength = length;
+
+	memcpy(pcharc->_value, value, pcharc->_valueLength);
+
+	if(pcharc->characteristicValueChanged != NULL){
+		BLEPeripheral *pblep = pcharc->_pblePeripheral;
+		success = pcharc->characteristicValueChanged(&pblep->_nRF8001, pcharc);
+	}
+	return success;
+}
+
+/*
+ *  BLECharacteristic 値設定(値の長さなし)
+ */
+bool_t
+BLECharacteristic_setValue2(BLECharacteristic *pcharc, const char* value)
+{
+	return BLECharacteristic_setValue1(pcharc, (const unsigned char *)value, strlen(value));
+}
+
+/*
+ *  BLECharacteristic 値設定(設定後通知)
+ */
+void
+BLECharacteristic_setValue(BLECharacteristic *pcharc, BLECentral* central, const unsigned char value[], unsigned char length)
+{
+	BLECharacteristicEventHandler eventHandler = pcharc->_eventHandlers[BLEWritten];
+
+	BLECharacteristic_setValue1(pcharc, value, length);
+	pcharc->_written = true;
+	if(eventHandler != NULL)
+		eventHandler(central, pcharc);
+}
+
+/*
+ *  BLECharacteristic 通知確認
+ */
+bool_t
+BLECharacteristic_notified(BLECharacteristic *pcharc)
+{
+	bool_t notify = pcharc->_notify;
+
+	if(notify){
+		pcharc->_notify = false;
+	}
+	return notify;
+}
+
+/*
+ *  BLECharacteristic 書き込み確認
+ */
+bool_t
+BLECharacteristic_written(BLECharacteristic *pcharc)
+{
+	bool_t written = pcharc->_written;
+
+	if(written){
+		pcharc->_written = false;
+	}
+	return written;
+}
+
+
+/*
+ *  BLECharacteristic Subscribed設定
+ */
+void
+BLECharacteristic_setSubscribed(BLECharacteristic *pcharc, BLECentral* central, bool_t subscribed)
+{
+	BLECharacteristicEventHandler eventHandler = pcharc->_eventHandlers[subscribed ? BLESubscribed : BLEUnsubscribed];
+
+	pcharc->_subscribed = subscribed;
+	if(eventHandler != NULL)
+		eventHandler(central, pcharc);
+}
+
+/*
+ *  BLECharacteristic Notify可能判定
+ */
+bool_t
+BLECharacteristic_canNotify(BLECharacteristic *pcharc)
+{
+	BLEPeripheral *pblep = pcharc->_pblePeripheral;
+	if(pblep == NULL)
+		return false;
+	if(pcharc->canNotifyCharacteristic != NULL)
+		return pcharc->canNotifyCharacteristic(&pblep->_nRF8001, pcharc);
+	else
+		return false;
+}
+
+/*
+ *  BLECharacteristic Indicate可能判定
+ */
+bool_t
+BLECharacteristic_canIndicate(BLECharacteristic *pcharc)
+{
+	BLEPeripheral *pblep = pcharc->_pblePeripheral;
+	if(pblep == NULL)
+		return false;
+	if(pcharc->canIndicateCharacteristic != NULL)
+		return pcharc->canIndicateCharacteristic(&pblep->_nRF8001, pcharc);
+	else
+		return false;
+}
+
+/*
+ *  BLECharacteristic コールバック関数設定
+ */
+void
+BLECharacteristic_setEventHandler(BLECharacteristic *pcharc, uint8_t event, void *eventHandler)
+{
+	if(event < 3){
+		pcharc->_eventHandlers[event] = eventHandler;
+	}
+}
+
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/ble_shield2.1/BLECharacteristic.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/ble_shield2.1/BLECharacteristic.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/ble_shield2.1/BLECharacteristic.h	(revision 457)
@@ -0,0 +1,125 @@
+/*
+ *  TOPPERS BASE PLATFORM MIDDLEWARE
+ * 
+ *  Copyright (C) 2017-2018 by TOPPERS PROJECT
+ *                             Educational Working Group.
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+The MIT License (MIT)
+
+Copyright (c) 2014 Sandeep Mistry
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+*/
+
+#ifndef _BLE_CHARACTERISTIC_H_
+#define _BLE_CHARACTERISTIC_H_
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+#include "BLEAttribute.h"
+
+enum BLECharacteristicEvent {
+	BLEWritten = 0,
+	BLESubscribed = 1,
+	BLEUnsubscribed = 2
+};
+
+typedef struct _BLECharacteristic BLECharacteristic;
+typedef void (*BLECharacteristicEventHandler)(BLECentral* central, BLECharacteristic *pcharc);
+
+struct _BLECharacteristic{
+	BLEAttribute          _attr;
+	unsigned char         _properties;
+	unsigned char         _valueSize;
+	unsigned char*        _value;
+	unsigned char         _valueLength;
+	bool_t                _fixedLength;
+
+	bool_t                _notify;
+	bool_t                _written;
+	bool_t                _subscribed;
+
+	void*                 _pblePeripheral;
+	bool_t (*characteristicValueChanged)(nRF8001* nRF8001, BLECharacteristic *pcharc);
+	bool_t (*canNotifyCharacteristic)(nRF8001* nRF8001, BLECharacteristic *pcharc);
+	bool_t (*canIndicateCharacteristic)(nRF8001* nRF8001, BLECharacteristic *pcharc);
+
+	BLECharacteristicEventHandler  _eventHandlers[3];
+};
+
+#define BLECharacteristic_getproperties(c)   (c)->_properties
+#define BLECharacteristic_getvalueSize(c)    (c)->_valueSize
+#define BLECharacteristic_getvalue(c)        (c)->_value
+#define BLECharacteristic_getvalueLength(c)  (c)->_valueLength
+#define BLECharacteristic_getfixedLength(c)  (c)->_fixedLength
+#define BLECharacteristic_getsubscribed(c)   (c)->_subscribed
+
+
+extern void BLEService_setup(BLEService* pserv, const char *uuid);
+extern void BLECharacteristic_setup(BLECharacteristic* pcharc, const char *uuid, unsigned char properties, unsigned char *value, unsigned char len);
+extern bool_t BLECharacteristic_setValue1(BLECharacteristic *pcharc, const unsigned char value[], unsigned char length);
+extern bool_t BLECharacteristic_setValue2(BLECharacteristic *pcharc, const char* value);
+extern bool_t BLECharacteristic_notified(BLECharacteristic *pcharc);
+extern bool_t BLECharacteristic_written(BLECharacteristic *pcharc);
+extern void BLECharacteristic_setValue(BLECharacteristic *pcharc, BLECentral* central, const unsigned char value[], unsigned char length);
+extern void BLECharacteristic_setSubscribed(BLECharacteristic *pcharc, BLECentral* central, bool_t subscribed);
+extern bool_t BLECharacteristic_canNotify(BLECharacteristic *pcharc);
+extern bool_t BLECharacteristic_canIndicate(BLECharacteristic *pcharc);
+extern void BLECharacteristic_setEventHandler(BLECharacteristic *pcharc, uint8_t event, void *eventHandler);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif	/* _BLE_CHARACTERISTIC_H_ */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/ble_shield2.1/BLEPeripheral.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/ble_shield2.1/BLEPeripheral.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/ble_shield2.1/BLEPeripheral.c	(revision 457)
@@ -0,0 +1,487 @@
+/*
+ *  TOPPERS BASE PLATFORM MIDDLEWARE
+ * 
+ *  Copyright (C) 2017-2018 by TOPPERS PROJECT
+ *                             Educational Working Group.
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+The MIT License (MIT)
+
+Copyright (c) 2014 Sandeep Mistry
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+*/
+
+#include <utility/lib_aci.h>
+#include <utility/aci_setup.h>
+#include "BLECentral.h"
+#include "BLECharacteristic.h"
+#include "BLEPeripheral.h"
+
+
+#define DEFAULT_DEVICE_NAME "Arduino"
+#define DEFAULT_APPEARANCE  0x0000
+
+static unsigned char _devicevalue[NUM_DEVICE_NAME];
+static unsigned char _appearvalue[NUM_APPEAR_VALUE];
+static unsigned char _servicevalue[NUM_SERVICE_VALUE];
+
+static BLEService _genericAccessService = {
+	{"1800", {0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, 2},
+	BLETypeService
+};
+
+static BLECharacteristic _deviceNameCharacteristic = {
+	{{"2a00", {0x00, 0x2A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, 2},
+	BLETypeCharacteristic},
+	BLERead,        /* _properties */
+	19,             /* _valueSize */
+	_devicevalue,   /* _value */
+	0,              /* _valueLength */
+	0,              /* _fixedLength */
+	false,          /* _notify */
+	false,          /* _written */
+	false,          /* _subscribed */
+	NULL,           /* _pblePeripheral */
+	NULL,           /* characteristicValueChanged */
+	NULL,           /* canNotifyCharacteristic */
+	NULL,           /* canIndicateCharacteristic */
+	{0, 0, 0}       /* _eventHandlers[3] */
+};
+
+static BLECharacteristic _appearanceCharacteristic = {
+	{{"2a01", {0x01, 0x2A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, 2},
+	BLETypeCharacteristic},
+	BLERead,        /* _properties */
+	2,              /* _valueSize */
+	_appearvalue,   /* _value */
+	0,              /* _valueLength */
+	0,              /* _fixedLength */
+	false,          /* _notify */
+	false,          /* _written */
+	false,          /* _subscribed */
+	NULL,           /* _pblePeripheral */
+	NULL,           /* characteristicValueChanged */
+	NULL,           /* canNotifyCharacteristic */
+	NULL,           /* canIndicateCharacteristic */
+	{0, 0, 0}       /* _eventHandlers[3] */
+};
+
+static BLEService _genericAttributeService = {
+	{"1801", {0x01, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, 2},
+	BLETypeService
+};
+
+static BLECharacteristic _servicesChangedCharacteristic = {
+	{{"2a05", {0x05, 0x2A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, 2},
+	BLETypeCharacteristic},
+	BLEIndicate,    /* _properties */
+	4,              /* _valueSize */
+	_servicevalue,  /* _value */
+	0,              /* _valueLength */
+	0,              /* _fixedLength */
+	false,          /* _notify */
+	false,          /* _written */
+	false,          /* _subscribed */
+	NULL,           /* _pblePeripheral */
+	NULL,           /* characteristicValueChanged */
+	NULL,           /* canNotifyCharacteristic */
+	NULL,           /* canIndicateCharacteristic */
+	{0, 0, 0}       /* _eventHandlers[3] */
+};
+
+static bool_t
+BLEPeripheral_characteristicValueChanged(nRF8001* nRF8001, BLECharacteristic *pcharc)
+{
+	return nRF8001_updateCharacteristicValue(nRF8001, pcharc);
+}
+
+static bool_t
+BLEPeripheral_canNotifyCharacteristic(nRF8001* nRF8001, BLECharacteristic *pcharc)
+{
+	return nRF8001_canNotifyCharacteristic(nRF8001, pcharc);
+}
+
+static bool_t
+BLEPeripheral_canIndicateCharacteristic(nRF8001* nRF8001, BLECharacteristic *pcharc)
+{
+	return nRF8001_canIndicateCharacteristic(nRF8001, pcharc);
+}
+
+
+/*
+ *  BLEPeripheralのセットアップ
+ */
+void
+BLEPeripheral_setup(BLEPeripheral *pblep, unsigned char req, unsigned char rdy, unsigned char rst)
+{
+	memset(pblep, 0, sizeof(BLEPeripheral));
+	pblep->_nRF8001._aciState.aci_pins.reqn_pin = req;
+	pblep->_nRF8001._aciState.aci_pins.rdyn_pin = rdy;
+	pblep->_nRF8001._aciState.aci_pins.reset_pin = rst;
+
+	pblep->_nRF8001._aciState.aci_pins.board_name = BOARD_DEFAULT;
+	pblep->_nRF8001._aciState.aci_pins.active_pin  = UNUSED;
+	pblep->_nRF8001._aciState.aci_pins.optional_chip_sel_pin = UNUSED;
+	pblep->_nRF8001._aciState.aci_pins.interface_is_interrupt = false;
+	pblep->_nRF8001._aciState.aci_pins.event_taskid = 0;
+	pblep->_nRF8001._pipeInfo = NULL;
+	pblep->_nRF8001._numPipeInfo = 0;
+	pblep->_nRF8001._crcSeed = 0xFFFF;
+	pblep->_nRF8001._pblePeripheral = pblep;
+
+	pblep->_attributes[0] = &_genericAccessService;
+	_deviceNameCharacteristic._valueLength = strlen(DEFAULT_DEVICE_NAME);
+	memcpy(_devicevalue, DEFAULT_DEVICE_NAME, _deviceNameCharacteristic._valueLength);
+	_deviceNameCharacteristic._pblePeripheral = pblep;
+	pblep->_attributes[1] = (BLEAttribute*)&_deviceNameCharacteristic;
+	_appearanceCharacteristic._pblePeripheral = pblep;
+	pblep->_attributes[2] = (BLEAttribute*)&_appearanceCharacteristic;
+	pblep->_attributes[3] = &_genericAttributeService;
+	_servicesChangedCharacteristic._pblePeripheral = pblep;
+	pblep->_attributes[4] = (BLEAttribute*)&_servicesChangedCharacteristic;
+	pblep->_numAttributes = 5;
+	pblep->_central._peripheral = pblep;
+	pblep->_central._connected  = false;
+	memset(pblep->_central._address, 0x00, 6);
+
+	pblep->_manufacturerData = NULL;
+	pblep->_manufacturerDataLength = 0;
+}
+
+/*
+ *  BLEPeripheral開始
+ */
+void
+BLEPeripheral_begin(BLEPeripheral *pblep)
+{
+	uint8_t advertisementData[20];
+	uint8_t scanData[20];
+	uint8_t advertisementDataLength = 0;
+	uint8_t scanDataLength = 0;
+	int i;
+
+	if(pblep->_advertisedServiceUuid){
+		unsigned char advertisedServiceUuidLength = sizeof(pblep->_advertisedServiceUuid);
+		advertisementDataLength = 2 + advertisedServiceUuidLength;
+		advertisementData[0] = (advertisedServiceUuidLength > 2) ? 0x06 : 0x02;
+		advertisementData[1] = advertisedServiceUuidLength;
+		memcpy(&advertisementData[2], pblep->_advertisedServiceUuid, advertisedServiceUuidLength);
+	}
+	else if(pblep->_manufacturerData && pblep->_manufacturerDataLength > 0) {
+		if(pblep->_manufacturerDataLength > sizeof(advertisementData))
+			pblep->_manufacturerDataLength = sizeof(advertisementData);
+
+		advertisementDataLength = 2 + pblep->_manufacturerDataLength;
+		advertisementData[0] = 0xff;
+		advertisementData[1] = pblep->_manufacturerDataLength;
+		memcpy(&advertisementData[2], pblep->_manufacturerData, pblep->_manufacturerDataLength);
+	}
+
+	if(pblep->_localName){
+		unsigned char originalLocalNameLength = strlen(pblep->_localName);
+		unsigned char localNameLength = originalLocalNameLength;
+
+		if(localNameLength > sizeof(scanData))
+			localNameLength = sizeof(scanData);
+		scanDataLength = 2 + localNameLength;
+		scanData[0] = (originalLocalNameLength > sizeof(scanData)) ? 0x08 : 0x09;
+		scanData[1] = localNameLength;
+		memcpy(&scanData[2], pblep->_localName, localNameLength);
+	}
+
+	for(i = 0 ; i < pblep->_numAttributes ; i++){
+		BLEAttribute* attribute = pblep->_attributes[i];
+		if(attribute->_type == BLETypeCharacteristic){
+			BLECharacteristic* pcharc = (BLECharacteristic*)attribute;
+			pcharc->characteristicValueChanged = BLEPeripheral_characteristicValueChanged;
+			pcharc->canNotifyCharacteristic    = BLEPeripheral_canNotifyCharacteristic;
+			pcharc->canIndicateCharacteristic  = BLEPeripheral_canIndicateCharacteristic;
+		}
+	}
+
+	nRF8001_begin(&pblep->_nRF8001, advertisementData, advertisementDataLength, scanData, scanDataLength, pblep->_attributes, pblep->_numAttributes);
+	nRF8001_requestAddress();
+}
+
+/*
+ *  BLEPeripheralの状態ポーリング
+ */
+void
+BLEPeripheral_poll(BLEPeripheral *pblep)
+{
+	nRF8001_poll(&pblep->_nRF8001);
+}
+
+/*
+ *  BLEPeripheral UUIDのセット
+ */
+void
+BLEPeripheral_setAdvertisedServiceUuid(BLEPeripheral *pblep, const char* advertisedServiceUuid)
+{
+	pblep->_advertisedServiceUuid = advertisedServiceUuid;
+}
+
+/*
+ *  BLEPeripheral MANUFACURER DATAのセット
+ */
+void
+BLEPeripheral_setManufacturerData(BLEPeripheral *pblep, const unsigned char manufacturerData[], unsigned char manufacturerDataLength)
+{
+	pblep->_manufacturerData = manufacturerData;
+	pblep->_manufacturerDataLength = manufacturerDataLength;
+}
+
+/*
+ *  BLEPeripheral LOCAL NAMEのセット
+ */
+void
+BLEPeripheral_setLocalName(BLEPeripheral *pblep, const char* localName)
+{
+	pblep->_localName = localName;
+}
+
+/*
+ *  BLEPeripheral ATTRIBUTEの追加
+ */
+void
+BLEPeripheral_addAttribute(BLEPeripheral *pblep, BLEAttribute* attribute)
+{
+	if(attribute->_type == BLETypeCharacteristic){
+		BLECharacteristic *pcharc = (BLECharacteristic*)attribute;
+		pcharc->_pblePeripheral = pblep;
+	}
+	pblep->_attributes[pblep->_numAttributes++] = attribute;
+}
+
+/*
+ *  BLEPeripheral DEVICENMAEのセット
+ */
+void
+BLEPeripheral_setDeviceName(BLEPeripheral *pblep, const char* deviceName)
+{
+	BLECharacteristic_setValue2(&_deviceNameCharacteristic, deviceName);
+}
+
+/*
+ *  BLEPeripheral APPEARANCEのセット
+ */
+void
+BLEPeripheral_setAppearance(BLEPeripheral *pblep, unsigned short appearance)
+{
+	BLECharacteristic_setValue1(&_appearanceCharacteristic, (unsigned char *)&appearance, sizeof(appearance));
+}
+
+/*
+ *  BLEPeripheral切断
+ */
+void
+BLEPeripheral_disconnect(BLEPeripheral *pblep)
+{
+	nRF8001_disconnect(&pblep->_nRF8001);
+}
+
+/*
+ *  BLEPeripheral セントラル構造体の取り出し
+ */
+BLECentral *
+BLEPeripheral_central(BLEPeripheral *pblep)
+{
+	BLEPeripheral_poll(pblep);
+	return &pblep->_central;
+}
+
+/*
+ *  BLEPeripheral セントラル接続判定
+ */
+bool_t
+BLEPeripheral_connected(BLEPeripheral *pblep)
+{
+	BLEPeripheral_poll(pblep);
+	return BLECentral_connected(&pblep->_central);
+}
+
+/*
+ *  BLEPeripheral ペリフェラルのイベントハンドラを設定
+ */
+void
+BLEPeripheral_setEventHandler(BLEPeripheral *pblep, uint8_t event, BLEPeripheralEventHandler eventHandler)
+{
+	if(event < 2){
+		pblep->_eventHandlers[event] = eventHandler;
+	}
+}
+
+/*
+ *  BLEPeripheral バージョン取得
+ */
+bool_t
+BLEPeripheral_version(BLEPeripheral *pblep)
+{
+	return lib_aci_device_version();
+}
+
+
+/*
+ *  nRF8001Connectedデフォルトコールバック関数
+ */
+void
+BLEPeripheral_nRF8001Connected(nRF8001* nRF8001, const unsigned char* address)
+{
+	BLEPeripheral *pblep = nRF8001->_pblePeripheral;
+	memcpy(pblep->_central._address, address, 6);
+	pblep->_central._connected = true;
+
+#ifdef BLE_PERIPHERAL_DEBUG
+	syslog_5(LOG_NOTICE, "Peripheral connected to central:%02:%02:%02:%02:%02:XX ", address[0], address[1], address[2], address[3], address[4]);
+#endif
+
+	BLEPeripheralEventHandler eventHandler = pblep->_eventHandlers[BLEConnected];
+	if(eventHandler)
+		eventHandler(&pblep->_central);
+}
+
+/*
+ *  nRF8001Disconnectedデフォルトコールバック関数
+ */
+void
+BLEPeripheral_nRF8001Disconnected(nRF8001* nRF8001)
+{
+	BLEPeripheral *pblep = nRF8001->_pblePeripheral;
+#ifdef BLE_PERIPHERAL_DEBUG
+	unsigned char *address = pblep->_central._address;
+	syslog_5(LOG_NOTICE, "Peripheral disconnected from central:%02:%02:%02:%02:%02:XX ", address[0], address[1], address[2], address[3], address[4]);
+#endif
+
+	BLEPeripheralEventHandler eventHandler = pblep->_eventHandlers[BLEDisconnected];
+	if(eventHandler)
+		eventHandler(&pblep->_central);
+	pblep->_central._connected = false;
+}
+
+/*
+ *  nRF8001CharacteristicValueChangedデフォルトコールバック関数
+ */
+void
+BLEPeripheral_nRF8001CharacteristicValueChanged(nRF8001* nRF8001, BLECharacteristic *pcharc, const unsigned char* value, unsigned char valueLength)
+{
+	BLEPeripheral *pblep = nRF8001->_pblePeripheral;
+
+	if(valueLength > pcharc->_valueSize)
+		pcharc->_valueLength = pcharc->_valueSize;
+	else
+		pcharc->_valueLength = valueLength;
+	memcpy(pcharc->_value, value, pcharc->_valueLength);
+
+	pcharc->_notify  = true;
+	pcharc->_written = true;
+
+	BLECharacteristicEventHandler eventHandler = pcharc->_eventHandlers[BLEWritten];
+	if(eventHandler)
+		eventHandler(&pblep->_central, pcharc);
+}
+
+/*
+ *  nRF8001CharacteristicSubscribedChangedデフォルトコールバック関数
+ */
+void
+BLEPeripheral_nRF8001CharacteristicSubscribedChanged(nRF8001* nRF8001, BLECharacteristic *pcharc, bool_t subscribed)
+{
+	BLEPeripheral *pblep = nRF8001->_pblePeripheral;
+	pcharc->_subscribed = subscribed;
+
+	BLECharacteristicEventHandler eventHandler = pcharc->_eventHandlers[subscribed ? BLESubscribed : BLEUnsubscribed];
+
+	if(eventHandler)
+		eventHandler(&pblep->_central, pcharc);
+}
+
+/*
+ *  nRF8001AddressReceivedデフォルトコールバック関数
+ */
+void
+BLEPeripheral_nRF8001AddressReceived(nRF8001* nRF8001, const unsigned char* address)
+{
+#ifdef BLE_PERIPHERAL_DEBUG
+	syslog_5(LOG_NOTICE, "Peripheral address:%02:%02:%02:%02:%02:XX ", address[0], address[1], address[2], address[3], address[4]);
+#endif
+}
+
+/*
+ *  nRF8001TemperatureReceivedデフォルトコールバック関数
+ */
+void
+BLEPeripheral_nRF8001TemperatureReceived(nRF8001* nRF8001, float temperature)
+{
+#ifdef BLE_PERIPHERAL_DEBUG
+	int32_t  tmp1 = temperature;
+	uint32_t tmp2;
+
+	tmp2 = (temperature - tmp1) * 100;
+	syslog_2(LOG_NOTICE, "Temperature = %d.%02d", tmp1, tmp2);
+#endif
+}
+
+/*
+ *  nRF8001BatteryLevelReceivedデフォルトコールバック関数
+ */
+void
+BLEPeripheral_nRF8001BatteryLevelReceived(nRF8001* nRF8001, float batteryLevel)
+{
+#ifdef BLE_PERIPHERAL_DEBUG
+	int32_t tmp1 = batteryLevel;
+	uint32_t tmp2;
+
+	tmp2 = (batteryLevel - tmp1) * 10000;
+	syslog_2(LOG_NOTICE, "Battery level = %d.%04d", tmp1, tmp2);
+#endif
+}
+
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/ble_shield2.1/BLEPeripheral.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/ble_shield2.1/BLEPeripheral.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/ble_shield2.1/BLEPeripheral.h	(revision 457)
@@ -0,0 +1,179 @@
+/*
+ *  TOPPERS BASE PLATFORM MIDDLEWARE
+ * 
+ *  Copyright (C) 2017-2018 by TOPPERS PROJECT
+ *                             Educational Working Group.
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+The MIT License (MIT)
+
+Copyright (c) 2014 Sandeep Mistry
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+*/
+
+#ifndef _BLEPERIPHERAL_H_
+#define _BLEPERIPHERAL_H_
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+#define MAX_ATTRIBUTE       32
+#define NB_BASE_SETUP_MESSAGES 7
+#define NUM_DEVICE_NAME     20
+#define NUM_APPEAR_VALUE    4
+#define NUM_SERVICE_VALUE   4
+
+#ifndef _BLE_ATTRIBUTE_H_
+typedef struct _nRF8001 nRF8001;
+#endif
+
+enum BLEPeripheralEvent {
+	BLEConnected = 0,
+	BLEDisconnected = 1
+};
+
+struct pipeInfo {
+	BLECharacteristic  *pcharc;
+
+	uint16_t           valueHandle;
+	uint16_t           configHandle;
+
+	uint8_t            startPipe;
+	uint8_t            txPipe;
+	uint8_t            txAckPipe;
+	uint8_t            rxPipe;
+	uint8_t            rxAckPipe;
+	uint8_t            setPipe;
+
+	bool_t             txPipeOpen;
+	bool_t             txAckPipeOpen;
+};
+
+struct _nRF8001 {
+	struct aci_state_t _aciState;
+	hal_aci_evt_t      _aciData;
+
+	void*              _pblePeripheral;
+	struct pipeInfo*   _pipeInfo;
+	uint8_t            _numPipeInfo;
+	uint16_t           _crcSeed;
+
+	void (*nRF8001Connected)(nRF8001* nRF8001, const unsigned char* address);
+	void (*nRF8001Disconnected)(nRF8001* nRF8001);
+	void (*nRF8001CharacteristicValueChanged)(nRF8001* nRF8001, BLECharacteristic *pcharc, const unsigned char* value, unsigned char valueLength);
+	void (*nRF8001CharacteristicSubscribedChanged)(nRF8001* nRF8001, BLECharacteristic *pcharc, bool_t subscribed);
+	void (*nRF8001AddressReceived)(nRF8001* nRF8001, const unsigned char* address);
+	void (*nRF8001TemperatureReceived)(nRF8001* nRF8001, float temperature);
+	void (*nRF8001BatteryLevelReceived)(nRF8001* nRF8001, float batteryLevel);
+};
+
+
+typedef void (*BLEPeripheralEventHandler)(BLECentral* central);
+
+typedef struct _BLEPeripheral {
+	nRF8001            _nRF8001;
+
+	const char         *_advertisedServiceUuid;
+	const uint8_t      *_manufacturerData;
+	uint8_t            _manufacturerDataLength;
+	const char*        _localName;
+
+	BLEAttribute*      _attributes[MAX_ATTRIBUTE];
+	uint8_t            _numAttributes;
+
+	BLECentral         _central;
+	BLEPeripheralEventHandler _eventHandlers[2];
+} BLEPeripheral;
+
+
+extern void nRF8001_begin(nRF8001* pnRF8001, const uint8_t *advertisementData, uint8_t advertisementDataLength, const uint8_t *scanData,
+                    uint8_t scanDataLength, BLEAttribute** attributes, uint8_t numAttributes);
+extern bool_t nRF8001_poll(nRF8001* pnRF8001);
+extern bool_t nRF8001_updateCharacteristicValue(nRF8001* pnRF8001, BLECharacteristic *pcharc);
+extern bool_t nRF8001_canNotifyCharacteristic(nRF8001* pnRF8001, BLECharacteristic* pcharc);
+extern bool_t nRF8001_canIndicateCharacteristic(nRF8001* pnRF8001, BLECharacteristic* pcharc);
+extern void nRF8001_disconnect(nRF8001* pnRF8001);
+extern void nRF8001_requestAddress(void);
+extern void nRF8001_requestTemperature(void);
+extern void nRF8001_requestBatteryLevel(void);
+extern void nRF8001_waitForSetupMode(nRF8001* pnRF8001);
+extern ER nRF8001_sendSetupMessage(nRF8001* pnRF8001, hal_aci_data_t* data);
+extern void nRF8001_sendCrc(nRF8001* pnRF8001);
+
+extern void BLEPeripheral_setup(BLEPeripheral *pblep, unsigned char req, unsigned char rdy, unsigned char rst);
+extern void BLEPeripheral_begin(BLEPeripheral *pblep);
+extern void BLEPeripheral_poll(BLEPeripheral *pblep);
+extern void BLEPeripheral_setAdvertisedServiceUuid(BLEPeripheral *pblep, const char* advertisedServiceUuid);
+extern void BLEPeripheral_setManufacturerData(BLEPeripheral *pblep, const unsigned char manufacturerData[], unsigned char manufacturerDataLength);
+extern void BLEPeripheral_setLocalName(BLEPeripheral *pblep, const char* localName);
+extern void BLEPeripheral_addAttribute(BLEPeripheral *pblep, BLEAttribute* attribute);
+extern void BLEPeripheral_setDeviceName(BLEPeripheral *pblep, const char* deviceName);
+extern void BLEPeripheral_setAppearance(BLEPeripheral *pblep, unsigned short appearance);
+extern void BLEPeripheral_disconnect(BLEPeripheral *pblep);
+extern BLECentral *BLEPeripheral_central(BLEPeripheral *pblep);
+extern bool_t BLEPeripheral_connected(BLEPeripheral *pblep);
+extern void BLEPeripheral_setEventHandler(BLEPeripheral *pblep, uint8_t event, BLEPeripheralEventHandler eventHandler);
+extern bool_t BLEPeripheral_version(BLEPeripheral *pblep);
+extern void BLEPeripheral_nRF8001Connected(nRF8001* nRF8001, const unsigned char* address);
+extern void BLEPeripheral_nRF8001Disconnected(nRF8001* nRF8001);
+extern void BLEPeripheral_nRF8001CharacteristicValueChanged(nRF8001* nRF8001, BLECharacteristic* pcharc, const unsigned char* value, unsigned char valueLength);
+extern void BLEPeripheral_nRF8001CharacteristicSubscribedChanged(nRF8001* nRF8001, BLECharacteristic* pcharc, bool_t subscribed);
+extern void BLEPeripheral_nRF8001AddressReceived(nRF8001* nRF8001, const unsigned char* address);
+extern void BLEPeripheral_nRF8001TemperatureReceived(nRF8001* nRF8001, float temperature);
+extern void BLEPeripheral_nRF8001BatteryLevelReceived(nRF8001* nRF8001, float batteryLevel);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif	/* _BLEPERIPHERAL_H_ */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/ble_shield2.1/Makefile.config
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/ble_shield2.1/Makefile.config	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/ble_shield2.1/Makefile.config	(revision 457)
@@ -0,0 +1,57 @@
+#
+#   TOPPERS/ASP/FMP Kernel
+#       Toyohashi Open Platform for Embedded Real-Time Systems/
+#       Advanced Standard Profile Kernel
+#
+#   Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
+#                               Toyohashi Univ. of Technology, JAPAN
+#   Copyright (C) 2003-2008 by Ryosuke Takeuchi
+#                Platform Development Center RICOH COMPANY,LTD. JAPAN
+#   Copyright (C) 2015-2018 by TOPPERS PROJECT Educational Working Group.
+#
+#   上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+#   によって公表されている GNU General Public License の Version 2 に記
+#   述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+#   を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+#   利用と呼ぶ）することを無償で許諾する．
+#   (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+#       権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+#       スコード中に含まれていること．
+#   (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+#       用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+#       者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+#       の無保証規定を掲載すること．
+#   (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+#       用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+#       と．
+#     (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+#         作権表示，この利用条件および下記の無保証規定を掲載すること．
+#     (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+#         報告すること．
+#   (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+#       害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+#
+#   本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+#   よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+#   含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+#   接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+#
+#  @(#) $Id$
+#
+ 
+#
+#  Makefile のプロセッサ依存 (ble shield2.1用)
+#
+
+#
+#  コンパイルオプション
+#
+INCLUDES	:= $(INCLUDES) -I$(SRCDIR)/gdic/ble_shield2.1 -I$(SRCDIR)/gdic/ble_shield2.1/utility
+
+#
+#  モニターに関する定義
+#
+SYSSVC_DIR := $(SYSSVC_DIR):$(SRCDIR)/gdic/ble_shield2.1:$(SRCDIR)/gdic/ble_shield2.1/utility
+SYSSVC_COBJS := $(SYSSVC_COBJS) aci_queue.o aci_setup.o acilib.o hal_aci_tl.o lib_aci.o \
+			BLECentral.o BLECharacteristic.o BLEPeripheral.o nRF8001.o
+
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/ble_shield2.1/nRF8001.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/ble_shield2.1/nRF8001.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/ble_shield2.1/nRF8001.c	(revision 457)
@@ -0,0 +1,900 @@
+/*
+ *  TOPPERS BASE PLATFORM MIDDLEWARE
+ * 
+ *  Copyright (C) 2017-2018 by TOPPERS PROJECT
+ *                             Educational Working Group.
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+The MIT License (MIT)
+
+Copyright (c) 2014 Sandeep Mistry
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+*/
+
+#include <utility/lib_aci.h>
+#include <utility/aci_setup.h>
+#include "BLECentral.h"
+#include "BLECharacteristic.h"
+#include "BLEPeripheral.h"
+
+
+#define ADVERTISING_INTERVAL 0x050
+
+struct setupMsgData {
+	uint8_t length;
+	uint8_t cmd;
+	uint8_t type;
+	uint8_t offset;
+	uint8_t data[28];
+};
+
+/*
+ *  nRF8001セットアップデータ
+ */
+static hal_aci_data_t baseSetupMsgs[NB_BASE_SETUP_MESSAGES] PROGMEM = {
+	{0x00,
+		{0x07,0x06,0x00,0x00,0x03,0x02,0x41,0xfe,},
+	},
+	{0x00,
+		{0x1f,0x06,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x00,0x00,0x06,0x00,0x06,
+		 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,},
+	},
+	{0x00,
+		{0x1f,0x06,0x10,0x1c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+		 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x90,0x00,0xff,},
+	},
+	{0x00,
+		{0x1f,0x06,0x10,0x38,0xff,0xff,0x02,0x58,0x0a,0x05,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+		 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x02,0x00,0x00,},
+	},
+	{0x00,
+		{0x05,0x06,0x10,0x54,0x00,0x02,},
+	},
+	{0x00,
+		{0x19,0x06,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+		 0x00,0x00,0x00,0x00,0x00,0x00,},
+	},
+	{0x00,
+		{0x19,0x06,0x70,0x16,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+		 0x00,0x00,0x00,0x00,0x00,0x00,},
+	},
+};
+
+static struct pipeInfo _pinfovalue[MAX_ATTRIBUTE];
+
+/*
+ *  CRC16計算
+ */
+static uint16_t
+crc_16_ccitt(uint16_t crc, uint8_t * data_in, uint16_t data_len)
+{
+	uint16_t i;
+
+	for(i = 0 ; i < data_len ; i++){
+		crc  = (unsigned char)(crc >> 8) | (crc << 8);
+		crc ^= data_in[i];
+		crc ^= (unsigned char)(crc & 0xff) >> 4;
+		crc ^= (crc << 8) << 4;
+		crc ^= ((crc & 0xff) << 4) << 1;
+	}
+	return crc;
+}
+
+/*
+ *  nRF8001開始
+ */
+void
+nRF8001_begin(nRF8001* pnRF8001, const uint8_t *advertisementData, uint8_t advertisementDataLength, const uint8_t *scanData,
+                      uint8_t scanDataLength, BLEAttribute** attributes, uint8_t numAttributes)
+{
+	hal_aci_data_t setupMsg;
+	struct setupMsgData *setupMsgData;
+	uint8_t   numPipedCharacteristics = 0;
+	uint8_t   pipeSetupMsgOffet  = 0;
+	uint8_t   gattSetupMsgOffset = 0;
+	uint16_t  handle             = 1;
+	uint8_t   pipe               = 1;
+	uint8_t   numPiped           = 0;
+	ER        ercd;
+	int       i;
+
+	for(i = 0 ; i < numAttributes ; i++){
+		BLEAttribute* attribute = attributes[i];
+
+		if(attribute->_type == BLETypeCharacteristic){
+			BLECharacteristic *pcharc = (BLECharacteristic *)attribute;
+
+			if(pcharc->_properties){
+				numPipedCharacteristics++;
+			}
+		}
+	}
+
+	pnRF8001->_pipeInfo = _pinfovalue;
+
+#if DEBUG == 0
+	lib_aci_init(&pnRF8001->_aciState, false);
+#else
+	lib_aci_init(&pnRF8001->_aciState, true);
+#endif
+
+	nRF8001_waitForSetupMode(pnRF8001);
+
+	setupMsgData = (struct setupMsgData*)setupMsg.buffer;
+	setupMsg.status_byte = 0;
+
+	for (i = 0; i < NB_BASE_SETUP_MESSAGES; i++) {
+		int setupMsgSize = pgm_read_byte_near(&baseSetupMsgs[i].buffer[0]) + 2;
+
+		memcpy(&setupMsg, &baseSetupMsgs[i], setupMsgSize);
+		if(i == 1){
+			setupMsgData->data[6] = numPipedCharacteristics;
+			setupMsgData->data[8] = numPipedCharacteristics;
+		}
+		else if(i == 2 && advertisementData && advertisementDataLength){
+			setupMsgData->data[22] = 0x40;
+		}
+		else if(i == 3 && scanData && scanDataLength){
+			setupMsgData->data[12] = 0x40;
+		}
+		else if(i == 5 && advertisementData && advertisementDataLength){
+			memcpy(setupMsgData->data, advertisementData, advertisementDataLength);
+		}
+		else if(i == 6 && scanData && scanDataLength){
+			memcpy(setupMsgData->data, scanData, scanDataLength);
+		}
+
+		ercd = nRF8001_sendSetupMessage(pnRF8001, &setupMsg);
+		if(ercd != E_OK)
+			i--;
+	}
+
+	// GATT
+	for(i = 0 ; i < numAttributes ; i++){
+		BLEAttribute* attribute = attributes[i];
+		BLEUuid* puuid = &attribute->_uuid;
+
+		if(attribute->_type == BLETypeService){
+			setupMsgData->length  = 12 + puuid->_length;
+			setupMsgData->cmd     = ACI_CMD_SETUP;
+			setupMsgData->type    = 0x20;
+			setupMsgData->offset  = gattSetupMsgOffset;
+
+			setupMsgData->data[0] = 0x04;
+			setupMsgData->data[1] = 0x04;
+			setupMsgData->data[2] = puuid->_length;
+			setupMsgData->data[3] = puuid->_length;
+			setupMsgData->data[4] = (handle >> 8) & 0xff;
+			setupMsgData->data[5] = handle & 0xff;
+			handle++;
+
+			setupMsgData->data[6] = (attribute->_type >> 8) & 0xff;
+			setupMsgData->data[7] = attribute->_type & 0xff;
+			setupMsgData->data[8] = ACI_STORE_LOCAL;
+			memcpy(&setupMsgData->data[9], puuid->_data, puuid->_length);
+			gattSetupMsgOffset += 9 + puuid->_length;
+
+			nRF8001_sendSetupMessage(pnRF8001, &setupMsg);
+		}
+		else if(attribute->_type == BLETypeCharacteristic){
+			BLECharacteristic *pcharc = (BLECharacteristic *)attribute;
+			struct pipeInfo* pipeInfo = &pnRF8001->_pipeInfo[numPiped];
+
+			memset(pipeInfo, 0, sizeof(struct pipeInfo));
+			pipeInfo->pcharc = pcharc;
+			if(pcharc->_properties){
+				numPiped++;
+				pipeInfo->startPipe = pipe;
+				if(pcharc->_properties & BLENotify){
+					pipeInfo->txPipe = pipe;
+					pipe++;
+				}
+
+				if(pcharc->_properties & BLEIndicate){
+					pipeInfo->txAckPipe = pipe;
+					pipe++;
+				}
+				if(pcharc->_properties & BLEWriteWithoutResponse){
+					pipeInfo->rxPipe = pipe;
+					pipe++;
+				}
+				if(pcharc->_properties & BLEWrite){
+					pipeInfo->rxAckPipe = pipe;
+					pipe++;
+				}
+				if(pcharc->_properties & BLERead){
+					pipeInfo->setPipe = pipe;
+					pipe++;
+				}
+			}
+
+			setupMsgData->length   = 15 + puuid->_length;
+			setupMsgData->cmd      = ACI_CMD_SETUP;
+			setupMsgData->type     = 0x20;
+			setupMsgData->offset   = gattSetupMsgOffset;
+
+			setupMsgData->data[0]  = 0x04;
+			setupMsgData->data[1]  = 0x04;
+			setupMsgData->data[2]  = 3 + puuid->_length;
+			setupMsgData->data[3]  = 3 + puuid->_length;
+
+			setupMsgData->data[4]  = (handle >> 8) & 0xff;
+			setupMsgData->data[5]  = handle & 0xff;
+			handle++;
+
+			setupMsgData->data[6]  = (pcharc->_attr._type >> 8) & 0xff;
+			setupMsgData->data[7]  = pcharc->_attr._type & 0xff;
+			setupMsgData->data[8]  = ACI_STORE_LOCAL;
+			setupMsgData->data[9]  = pcharc->_properties;
+			setupMsgData->data[10] = handle & 0xff;
+			setupMsgData->data[11] = (handle >> 8) & 0xff;
+			pipeInfo->valueHandle = handle;
+			handle++;
+
+			memcpy(&setupMsgData->data[12], puuid->_data, puuid->_length);
+
+			gattSetupMsgOffset += 12 + puuid->_length;
+
+			nRF8001_sendSetupMessage(pnRF8001, &setupMsg);
+
+			setupMsgData->length   = 12 + pcharc->_valueSize;
+			setupMsgData->cmd      = ACI_CMD_SETUP;
+			setupMsgData->type     = 0x20;
+			setupMsgData->offset   = gattSetupMsgOffset;
+
+			setupMsgData->data[0]  = 0x04;
+			setupMsgData->data[1]  = 0x00;
+			if(pcharc->_fixedLength)
+				setupMsgData->data[0] |= 0x02;
+
+			if(pcharc->_properties & BLERead)
+				setupMsgData->data[1] |= 0x04;
+			if(pcharc->_properties & (BLEWrite | BLEWriteWithoutResponse)){
+				setupMsgData->data[0] |= 0x40;
+				setupMsgData->data[1] |= 0x10;
+			}
+			if(pcharc->_properties & BLENotify)
+				setupMsgData->data[0] |= 0x10;
+			if(pcharc->_properties & BLEIndicate)
+				setupMsgData->data[0] |= 0x20;
+			setupMsgData->data[2]  = pcharc->_valueSize;
+			if(pcharc->_fixedLength)
+				setupMsgData->data[2]++;
+			setupMsgData->data[3]  = pcharc->_valueLength;
+			setupMsgData->data[4]  = (pipeInfo->valueHandle >> 8) & 0xff;
+			setupMsgData->data[5]  = pipeInfo->valueHandle & 0xff;
+			setupMsgData->data[6]  = 0x00;
+			setupMsgData->data[7]  = 0x00;
+			setupMsgData->data[8]  = 0x02;
+			memset(&setupMsgData->data[9], 0x00, pcharc->_valueSize);
+			memcpy(&setupMsgData->data[9], pcharc->_value, pcharc->_valueLength);
+
+			gattSetupMsgOffset += 9 + pcharc->_valueSize;
+
+			nRF8001_sendSetupMessage(pnRF8001, &setupMsg);
+
+			if(pcharc->_properties & (BLENotify | BLEIndicate)){
+				setupMsgData->length   = 14;
+				setupMsgData->cmd      = ACI_CMD_SETUP;
+				setupMsgData->type     = 0x20;
+				setupMsgData->offset   = gattSetupMsgOffset;
+
+				setupMsgData->data[0]  = 0x46;
+				setupMsgData->data[1]  = 0x14;
+				setupMsgData->data[2]  = 0x03;
+				setupMsgData->data[3]  = 0x02;
+				setupMsgData->data[4]  = (handle >> 8) & 0xff;
+				setupMsgData->data[5]  = handle & 0xff;
+				pipeInfo->configHandle = handle;
+				handle++;
+
+				setupMsgData->data[6]  = 0x29;
+				setupMsgData->data[7]  = 0x02;
+				setupMsgData->data[8]  = ACI_STORE_LOCAL;
+				setupMsgData->data[9]  = 0x00;
+				setupMsgData->data[10] = 0x00;
+
+				gattSetupMsgOffset += 11;
+
+				nRF8001_sendSetupMessage(pnRF8001, &setupMsg);
+			}
+		}
+		else if(attribute->_type == BLETypeDescriptor){
+			BLEDescriptor* descriptor = (BLEDescriptor *)attribute;
+
+			setupMsgData->length   = 12 + descriptor->_valueSize;
+			setupMsgData->cmd      = ACI_CMD_SETUP;
+			setupMsgData->type     = 0x20;
+			setupMsgData->offset   = gattSetupMsgOffset;
+
+			setupMsgData->data[0]  = 0x04;
+			setupMsgData->data[1]  = 0x04;
+			setupMsgData->data[2]  = descriptor->_valueSize;
+			setupMsgData->data[3]  = descriptor->_valueLength;
+			setupMsgData->data[4]  = (handle >> 8) & 0xff;
+			setupMsgData->data[5]  = handle & 0xff;
+			handle++;
+
+			setupMsgData->data[6]  = puuid->_data[1];
+			setupMsgData->data[7]  = puuid->_data[0];
+			setupMsgData->data[8]  = ACI_STORE_LOCAL;
+			memcpy(&setupMsgData->data[9], descriptor->_value, descriptor->_valueLength);
+
+			gattSetupMsgOffset += 9 + descriptor->_valueSize;
+
+			nRF8001_sendSetupMessage(pnRF8001, &setupMsg);
+		}
+	}
+	pnRF8001->_numPipeInfo = numPiped;
+
+	// terminator
+	setupMsgData->length   = 4;
+	setupMsgData->cmd      = ACI_CMD_SETUP;
+	setupMsgData->type     = 0x20;
+	setupMsgData->offset   = gattSetupMsgOffset;
+
+	setupMsgData->data[0]  = 0x00;
+
+	gattSetupMsgOffset += 6;
+
+	nRF8001_sendSetupMessage(pnRF8001, &setupMsg);
+
+	// pipes
+	for(i = 0 ; i < numPiped ; i++){
+		struct pipeInfo pipeInfo = pnRF8001->_pipeInfo[i];
+
+		setupMsgData->length   = 13;
+		setupMsgData->cmd      = ACI_CMD_SETUP;
+		setupMsgData->type     = 0x40;
+		setupMsgData->offset   = pipeSetupMsgOffet;
+
+		setupMsgData->data[0]  = 0x00;
+		setupMsgData->data[1]  = 0x00;
+		setupMsgData->data[2]  = pipeInfo.startPipe;
+		setupMsgData->data[3]  = 0x00;
+		setupMsgData->data[4]  = 0x00;
+		setupMsgData->data[5]  = 0x04;
+		setupMsgData->data[6]  = (pipeInfo.valueHandle >> 8) & 0xff;
+		setupMsgData->data[7]  = pipeInfo.valueHandle & 0xff;
+		setupMsgData->data[8]  = (pipeInfo.configHandle >> 8) & 0xff;
+		setupMsgData->data[9]  = pipeInfo.configHandle & 0xff;
+
+		if(pipeInfo.pcharc->_properties & BLEIndicate)
+			setupMsgData->data[4] |= 0x04; // TX Ack
+		if(pipeInfo.pcharc->_properties & BLENotify)
+			setupMsgData->data[4] |= 0x02; // TX
+		if(pipeInfo.pcharc->_properties & BLEWriteWithoutResponse)
+			setupMsgData->data[4] |= 0x08; // RX Ack
+		if(pipeInfo.pcharc->_properties & BLEWrite)
+			setupMsgData->data[4] |= 0x10; // RX Ack
+		if(pipeInfo.pcharc->_properties & BLERead)
+			setupMsgData->data[4] |= 0x80; // Set
+
+		pipeSetupMsgOffet += 10;
+
+		nRF8001_sendSetupMessage(pnRF8001, &setupMsg);
+	}
+	nRF8001_sendCrc(pnRF8001);
+}
+
+/*
+ *  nRF8001参照
+ */
+bool_t
+nRF8001_poll(nRF8001* pnRF8001)
+{
+	if(lib_aci_event_get(&pnRF8001->_aciState, &pnRF8001->_aciData)){
+		aci_evt_t* aciEvt = &pnRF8001->_aciData.evt;
+		int i;
+#ifdef NRF_8001_DEBUG
+		uint32_t tmp1, tmp2;
+		uint32_t tmp3, tmp4;
+
+		syslog_3(LOG_NOTICE, " nRF8001_poll [%02x][%02x][%08x]", aciEvt->evt_opcode, aciEvt->params.device_started.device_mode, aciEvt);
+#endif
+		switch(aciEvt->evt_opcode){
+		/*
+		 *  スタートイベント(リセット後)
+		 */
+		case ACI_EVT_DEVICE_STARTED: {
+			pnRF8001->_aciState.data_credit_total = aciEvt->params.device_started.credit_available;
+			switch(aciEvt->params.device_started.device_mode) {
+			case ACI_DEVICE_SETUP:
+				/*
+				 *  DEVICEセットアップ
+				 */
+#ifdef NRF_8001_DEBUG
+				syslog_0(LOG_NOTICE, "Evt Device Started: Setup");
+#endif
+				break;
+
+			case ACI_DEVICE_STANDBY:
+				/*
+				 *  DEVICEスタンバイ
+				 */
+#ifdef NRF_8001_DEBUG
+				syslog_0(LOG_NOTICE, "Evt Device Started: Standby");
+#endif
+				if(aciEvt->params.device_started.hw_error){
+					dly_tsk(20);	/* ハードウェアエラー */
+				}
+				else{
+					lib_aci_connect(0/* in seconds : 0 means forever */, ADVERTISING_INTERVAL);
+#ifdef NRF_8001_DEBUG
+					syslog_0(LOG_NOTICE, "Advertising started");
+#endif
+				}
+				break;
+			default:
+				break;
+			}
+		}
+		break;	/* ここまで、DEVICEスタート状態 */
+
+		case ACI_EVT_CMD_RSP:
+			//If an ACI command response event comes with an error -> stop
+			if(ACI_STATUS_SUCCESS != aciEvt->params.cmd_rsp.cmd_status){
+				//ACI ReadDynamicData and ACI WriteDynamicData will have status codes of
+				//TRANSACTION_CONTINUE and TRANSACTION_COMPLETE
+				//all other ACI commands will have status code of ACI_STATUS_SCUCCESS for a successful command
+#ifdef NRF_8001_DEBUG
+				syslog_2(LOG_NOTICE, "ACI Command [%02x] Evt Cmd respone: Status [%02x]",
+					aciEvt->params.cmd_rsp.cmd_opcode,
+					aciEvt->params.cmd_rsp.cmd_status);
+#endif
+			}
+			else{
+				switch (aciEvt->params.cmd_rsp.cmd_opcode) {
+				case ACI_CMD_GET_DEVICE_VERSION:
+					syslog_2(LOG_NOTICE, "VERSION configuration_id[%04x] aci_ver[%02x]",
+						aciEvt->params.cmd_rsp.params.get_device_version.configuration_id,
+						aciEvt->params.cmd_rsp.params.get_device_version.aci_version);
+					syslog_3(LOG_NOTICE, "   setup_format[%02x] setup[%08x] setp_status[%02x]",
+						aciEvt->params.cmd_rsp.params.get_device_version.setup_format,
+						aciEvt->params.cmd_rsp.params.get_device_version.setup_id,
+						aciEvt->params.cmd_rsp.params.get_device_version.setup_status);
+					break;
+
+				case ACI_CMD_GET_DEVICE_ADDRESS: {
+#ifdef NRF_8001_DEBUG
+					syslog_4(LOG_NOTICE, "nRF8001_poll ACI_CMD_GET_DEVICE_ADDRESS type(%d) [%02x][%02x][%02x]",
+						aciEvt->params.cmd_rsp.params.get_device_address.bd_addr_type,
+						aciEvt->params.cmd_rsp.params.get_device_address.bd_addr_own[5],
+						aciEvt->params.cmd_rsp.params.get_device_address.bd_addr_own[4],
+						aciEvt->params.cmd_rsp.params.get_device_address.bd_addr_own[3]);
+					syslog_3(LOG_NOTICE, "nRF8001_poll   [%02x][%02x][%02x]",
+						aciEvt->params.cmd_rsp.params.get_device_address.bd_addr_own[2],
+						aciEvt->params.cmd_rsp.params.get_device_address.bd_addr_own[1],
+						aciEvt->params.cmd_rsp.params.get_device_address.bd_addr_own[0]);
+#endif
+					if(pnRF8001->nRF8001AddressReceived){
+						pnRF8001->nRF8001AddressReceived(pnRF8001, aciEvt->params.cmd_rsp.params.get_device_address.bd_addr_own);
+					}
+					break;
+				}
+
+				case ACI_CMD_GET_BATTERY_LEVEL: {
+					float batteryLevel = aciEvt->params.cmd_rsp.params.get_battery_level.battery_level * 0.00352;
+					if(pnRF8001->nRF8001BatteryLevelReceived){
+						pnRF8001->nRF8001BatteryLevelReceived(pnRF8001, batteryLevel);
+					}
+					break;
+				}
+
+				case ACI_CMD_GET_TEMPERATURE: {
+					float temperature = aciEvt->params.cmd_rsp.params.get_temperature.temperature_value / 4.0;
+					if(pnRF8001->nRF8001TemperatureReceived){
+						pnRF8001->nRF8001TemperatureReceived(pnRF8001, temperature);
+					}
+					break;
+				}
+				default:
+					break;
+				}
+	        }
+    	    break;
+
+		case ACI_EVT_CONNECTED:
+
+#ifdef NRF_8001_DEBUG
+			syslog_3(LOG_NOTICE, "Evt Connected [%02x][%02x][%02x]",
+				aciEvt->params.connected.dev_addr[5],
+				aciEvt->params.connected.dev_addr[4],
+				aciEvt->params.connected.dev_addr[3]):
+			syslog_3(LOG_NOTICE, "              [%02x][%02x][%02x]",
+				aciEvt->params.connected.dev_addr[2],
+				aciEvt->params.connected.dev_addr[1],
+				aciEvt->params.connected.dev_addr[0]);
+#endif
+			if(pnRF8001->nRF8001Connected){
+				pnRF8001->nRF8001Connected(pnRF8001, aciEvt->params.connected.dev_addr);
+			}
+			pnRF8001->_aciState.data_credit_available = pnRF8001->_aciState.data_credit_total;
+			break;
+
+		case ACI_EVT_PIPE_STATUS:
+#ifdef NRF_8001_DEBUG
+			memcpy(&tmp1, &aciEvt->params.pipe_status.pipes_open_bitmap[0], 4);
+			memcpy(&tmp2, &aciEvt->params.pipe_status.pipes_open_bitmap[4], 4);
+			memcpy(&tmp3, &aciEvt->params.pipe_status.pipes_closed_bitmap[0], 4);
+			memcpy(&tmp4, &aciEvt->params.pipe_status.pipes_closed_bitmap[4], 4);
+			syslog_4(LOG_NOTICE, "Evt Pipe Status [%04x%04x][%04x%04x]", tmp1, tmp2, tmp3, tmp4);
+#endif
+			for(i = 0 ; i < pnRF8001->_numPipeInfo ; i++){
+				struct pipeInfo* pipeInfo = &pnRF8001->_pipeInfo[i];
+
+				if(pipeInfo->txPipe){
+					pipeInfo->txPipeOpen = lib_aci_is_pipe_available(&pnRF8001->_aciState, pipeInfo->txPipe);
+				}
+				if(pipeInfo->txAckPipe){
+					pipeInfo->txAckPipeOpen = lib_aci_is_pipe_available(&pnRF8001->_aciState, pipeInfo->txAckPipe);
+				}
+
+				bool subscribed = (pipeInfo->txPipeOpen || pipeInfo->txAckPipeOpen);
+
+				if(pipeInfo->pcharc->_subscribed != subscribed){
+					if(pnRF8001->nRF8001CharacteristicSubscribedChanged){
+						pnRF8001->nRF8001CharacteristicSubscribedChanged(pnRF8001, pipeInfo->pcharc, subscribed);
+					}
+				}
+			}
+			break;
+
+		case ACI_EVT_TIMING:
+			break;
+
+		case ACI_EVT_DISCONNECTED:
+#ifdef NRF_8001_DEBUG
+			syslog_0(LOG_NOTICE, "Evt Disconnected/Advertising timed out");
+#endif
+			// all characteristics unsubscribed on disconnect
+			for(i = 0 ; i < pnRF8001->_numPipeInfo ; i++){
+				struct pipeInfo* pipeInfo = &pnRF8001->_pipeInfo[i];
+
+				if(pipeInfo->pcharc->_subscribed){
+					if(pnRF8001->nRF8001CharacteristicSubscribedChanged){
+						pnRF8001->nRF8001CharacteristicSubscribedChanged(pnRF8001, pipeInfo->pcharc, false);
+					}
+				}
+			}
+			if(pnRF8001->nRF8001Disconnected){
+				pnRF8001->nRF8001Disconnected(pnRF8001);
+			}
+
+			lib_aci_connect(0/* in seconds  : 0 means forever */, ADVERTISING_INTERVAL);
+#ifdef NRF_8001_DEBUG
+			syslog_0(LOG_NOTICE, "Advertising started.");
+#endif
+			break;
+
+		case ACI_EVT_DATA_RECEIVED: {
+			uint8_t dataLen = aciEvt->len - 2;
+			uint8_t pipe = aciEvt->params.data_received.rx_data.pipe_number;
+#ifdef NRF_8001_DEBUG
+			syslog_1(LOG_NOTICE, "Data Received, pipe = %d", aciEvt->params.data_received.rx_data.pipe_number);
+
+			for(int i = 0 ; i < dataLen ; i++){
+				syslog_2(LOG_NOTICE, "%d:%02x", i, aciEvt->params.data_received.rx_data.aci_data[i]);
+	        }
+#endif
+			for(i = 0 ; i < pnRF8001->_numPipeInfo ; i++){
+				struct pipeInfo* pipeInfo = &pnRF8001->_pipeInfo[i];
+
+				if(pipeInfo->rxAckPipe == pipe || pipeInfo->rxPipe == pipe){
+					if(pipeInfo->rxAckPipe == pipe){
+						lib_aci_send_ack(&pnRF8001->_aciState, pipeInfo->rxAckPipe);
+					}
+					if(pnRF8001->nRF8001CharacteristicValueChanged){
+						pnRF8001->nRF8001CharacteristicValueChanged(pnRF8001, pipeInfo->pcharc, aciEvt->params.data_received.rx_data.aci_data, dataLen);
+					}
+					break;
+				}
+			}
+		}
+		break;
+
+		case ACI_EVT_DATA_CREDIT:
+			pnRF8001->_aciState.data_credit_available = pnRF8001->_aciState.data_credit_available + aciEvt->params.data_credit.credit;
+			break;
+
+		case ACI_EVT_PIPE_ERROR:
+			//See the appendix in the nRF8001 Product Specication for details on the error codes
+#ifdef NRF_8001_DEBUG
+			syslog_2(LOG_ERROR, "ACI Evt Pipe Error: Pipe #:%d, Pipe Error Code: 0x%x",
+				aciEvt->params.pipe_error.pipe_number,
+				aciEvt->params.pipe_error.error_code);
+#endif
+			//Increment the credit available as the data packet was not sent.
+			//The pipe error also represents the Attribute protocol Error Response sent from the peer and that should not be counted
+			//for the credit.
+			if(ACI_STATUS_ERROR_PEER_ATT_ERROR != aciEvt->params.pipe_error.error_code){
+				pnRF8001->_aciState.data_credit_available++;
+			}
+			break;
+
+		case ACI_EVT_HW_ERROR:
+#ifdef NRF_8001_DEBUG
+			syslog_1(LOG_ERROR, "HW error: %d", aciEvt->params.hw_error.line_num);
+
+			for(uint8_t counter = 0; counter <= (aciEvt->len - 3); counter++) {
+				syslog_1(LOG_ERROR, "[%s]", aciEvt->params.hw_error.file_name[counter]);
+			}
+#endif
+			lib_aci_connect(0/* in seconds, 0 means forever */, ADVERTISING_INTERVAL);
+#ifdef NRF_8001_DEBUG
+			syslog_0(LOG_ERROR, "Advertising started.");
+#endif
+			break;
+		default:
+			break;
+		}
+		return true;
+	}
+	else
+		return false;
+}
+
+/*
+ *  nRF8001キャラクティクス値更新
+ */
+bool_t
+nRF8001_updateCharacteristicValue(nRF8001* pnRF8001, BLECharacteristic *pcharc)
+{
+	bool_t success = true;
+	int i;
+
+	for(i = 0 ; i < pnRF8001->_numPipeInfo ; i++){
+		struct pipeInfo* pipeInfo = &pnRF8001->_pipeInfo[i];
+
+		if(pipeInfo->pcharc == pcharc){
+			if(pipeInfo->setPipe){
+				success &= lib_aci_set_local_data(&pnRF8001->_aciState, pipeInfo->setPipe, (uint8_t*)pcharc->_value, pcharc->_valueLength);
+			}
+			if(pipeInfo->txPipe && pipeInfo->txPipeOpen){
+				if(pcharc->canNotifyCharacteristic(pnRF8001, pcharc)){
+					pnRF8001->_aciState.data_credit_available--;
+					success &= lib_aci_send_data(pipeInfo->txPipe, (uint8_t*)pcharc->_value, pcharc->_valueLength);
+				}
+				else{
+					success = false;
+				}
+			}
+
+			if(pipeInfo->txAckPipe && pipeInfo->txAckPipeOpen){
+				if(pcharc->canIndicateCharacteristic(pnRF8001, pcharc)){
+					pnRF8001->_aciState.data_credit_available--;
+					success &= lib_aci_send_data(pipeInfo->txAckPipe, (uint8_t*)pcharc->_value, pcharc->_valueLength);
+				}
+				else{
+					success = false;
+				}
+			}
+			break;
+		}
+	}
+	return success;
+}
+
+/*
+ *  nRF8001 NOTIFYキャラクティクス可能判定
+ */
+bool_t
+nRF8001_canNotifyCharacteristic(nRF8001* pnRF8001, BLECharacteristic *pcharc) {
+	return (lib_aci_get_nb_available_credits(&pnRF8001->_aciState) > 0);
+}
+
+/*
+ *  nRF8001 INDICATEキャラクティクス可能判定
+ */
+bool_t
+nRF8001_canIndicateCharacteristic(nRF8001* pnRF8001, BLECharacteristic *pcharc) {
+	return (lib_aci_get_nb_available_credits(&pnRF8001->_aciState) > 0);
+}
+
+/*
+ *  nRF8001切断
+ */
+void
+nRF8001_disconnect(nRF8001* pnRF8001)
+{
+	lib_aci_disconnect(&pnRF8001->_aciState, ACI_REASON_TERMINATE);
+}
+
+/*
+ *  nRF8001アドレス要求
+ */
+void
+nRF8001_requestAddress(void)
+{
+	lib_aci_get_address();
+}
+
+/*
+ *  nRF8001温度要求
+ */
+void
+nRF8001_requestTemperature(void)
+{
+	lib_aci_get_temperature();
+}
+
+/*
+ *  nRF8001バッテリレベル要求
+ */
+void
+nRF8001_requestBatteryLevel(void)
+{
+	lib_aci_get_battery_level();
+}
+
+/*
+ *  nRF8001セットアップモード待ち
+ */
+void
+nRF8001_waitForSetupMode(nRF8001* pnRF8001)
+{
+	bool_t setupMode = false;
+
+	while(!setupMode){
+		if(lib_aci_event_get(&pnRF8001->_aciState, &pnRF8001->_aciData)){
+			aci_evt_t* aciEvt = &pnRF8001->_aciData.evt;
+
+			switch(aciEvt->evt_opcode){
+			case ACI_EVT_DEVICE_STARTED: {
+				switch(aciEvt->params.device_started.device_mode) {
+				case ACI_DEVICE_SETUP:
+					/**
+					When the device is in the setup mode
+					*/
+#ifdef NRF_8001_DEBUG
+					syslog_0(LOG_NOTICE, "Evt Device Started: Setup");
+#endif
+					setupMode = true;
+					break;
+				default:
+					break;
+				}
+				break;
+			}
+			default:
+				break;
+			}
+		}
+		else{
+			dly_tsk(1);
+		}
+	}
+}
+
+/*
+ *  nRF8001セットアップメッセージ送信
+ */
+ER
+nRF8001_sendSetupMessage(nRF8001* pnRF8001, hal_aci_data_t* data)
+{
+	bool_t setupMsgSent = false;
+	int i = 0;
+
+	pnRF8001->_crcSeed = crc_16_ccitt(pnRF8001->_crcSeed, data->buffer, data->buffer[0] + 1);
+	hal_aci_tl_send(data);
+
+	while(!setupMsgSent){
+		if(lib_aci_event_get(&pnRF8001->_aciState, &pnRF8001->_aciData)){
+			aci_evt_t* aciEvt = &pnRF8001->_aciData.evt;
+
+			if(aciEvt->evt_opcode == ACI_EVT_CMD_RSP && aciEvt->params.cmd_rsp.cmd_status == ACI_STATUS_TRANSACTION_CONTINUE){
+#ifdef NRF_8001_DEBUG
+				syslog_2(LOG_NOTICE, "Evt Cmd Rsp: Transaction Continue evt[%02x] sts[%02x]", aciEvt->evt_opcode, aciEvt->params.cmd_rsp.cmd_status);
+#endif
+				setupMsgSent = true;
+				break;
+			}
+		}
+		else{
+			dly_tsk(1);
+			i++;
+		}
+		if(i > 500)
+			return E_TMOUT;
+	}
+	return E_OK;
+}
+
+/*
+ *  nRF8001 CRC送信
+ */
+void
+nRF8001_sendCrc(nRF8001* pnRF8001)
+{
+	bool_t setupMsgSent = false;
+	hal_aci_data_t data;
+	data.status_byte = 0;
+
+	data.buffer[0]  = 3 + 3;
+	data.buffer[1]  = ACI_CMD_SETUP;
+	data.buffer[2]  = 0xf0;
+	data.buffer[3]  = 0x00;
+	data.buffer[4] = 0x03;
+	pnRF8001->_crcSeed = crc_16_ccitt(pnRF8001->_crcSeed, data.buffer, data.buffer[0] - 1);
+	data.buffer[5] = (pnRF8001->_crcSeed >> 8) & 0xff;
+	data.buffer[6] = pnRF8001->_crcSeed & 0xff;
+
+	hal_aci_tl_send(&data);
+
+	while(!setupMsgSent){
+		if(lib_aci_event_get(&pnRF8001->_aciState, &pnRF8001->_aciData)){
+			aci_evt_t* aciEvt = &pnRF8001->_aciData.evt;
+
+			switch(aciEvt->evt_opcode){
+			case ACI_EVT_CMD_RSP: {
+				switch(aciEvt->params.cmd_rsp.cmd_status) {
+				case ACI_STATUS_TRANSACTION_COMPLETE:
+#ifdef NRF_8001_DEBUG
+					syslog_0(LOG_NOTICE, "Evt Cmd Rsp: Transaction Complete");
+#endif
+					setupMsgSent = true;
+					break;
+				default:
+					break;
+				}
+			}
+			break;
+			default:
+				break;
+			}
+		}
+		else{
+			dly_tsk(1);
+		}
+	}
+}
+
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/ble_shield2.1/utility/README.md
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/ble_shield2.1/utility/README.md	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/ble_shield2.1/utility/README.md	(revision 457)
@@ -0,0 +1,3 @@
+These files are from the [@NordicSemiconductor](https://github.com/NordicSemiconductor)[ble-sdk-arduino](https://github.com/NordicSemiconductor/ble-sdk-arduino).
+
+Some file have been slightly modified.
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/ble_shield2.1/utility/aci.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/ble_shield2.1/utility/aci.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/ble_shield2.1/utility/aci.h	(revision 457)
@@ -0,0 +1,664 @@
+/* Copyright (c) 2014, Nordic Semiconductor ASA
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+/**
+ * @file
+ *
+ * @defgroup aci aci
+ * @{
+ * @ingroup lib
+ *
+ * @brief Definitions for the ACI (Application Control Interface)
+ * @remarks
+ *
+ * Flow control from application mcu to nRF8001
+ *
+ * Data flow control:
+ * The flow control is credit based and the credit is initally given using the "device started" event.
+ * A credit of more than 1 is given to the application mcu.
+ * These credits are used only after the "ACI Connected Event" is sent to the application mcu.
+ *
+ * every send_data that is used decrements the credit available by 1. This is to be tracked by the application mcu.
+ * When the credit available reaches 0, the application mcu shall not send any more send_data.
+ * Credit is returned using the "credit event", this returned credit can then be used to send more send_data.
+ * This flow control is not necessary and not available for Broadcast.
+ * The entire credit available with the external mcu expires when a "disconnected" event arrives.
+ *
+ * Command flow control:
+ * When a command is sent over the ACI, the next command shall not be sent until after a response
+ * for the command sent has arrived.
+ *
+ */
+
+#ifndef ACI_H__
+#define ACI_H__
+
+/**
+ * Define an _aci_packed_ macro we can use in structure and enumerated type
+ * declarations so that the types are sized consistently across different
+ * platforms. In particular Arduino platforms using the GCC compiler and the
+ * Nordic processors using the Keil compiler.
+ *
+ * It's really the GNU compiler platforms that need a special keyword to get
+ * tight packing of values. On GNU platforms we can use the keyword:
+ *     __attribute__((__packed__))
+ * The thing is that while this keyword does the right thing with old and new
+ * versions of the gcc (C) compiler it only works right with g++ (C++) compiler
+ * versions that are version 4 or newer.
+ */
+#ifdef __GNUC__
+#  if __GNUC__ >= 4
+#    define _aci_packed_ __attribute__((__packed__))
+#  else
+#    error "older g++ versions don't handle packed attribute in typedefs"
+#  endif
+#else
+#  define _aci_packed_
+#endif
+
+/*
+ * Define a macro that compares the size of the first parameter to the integer
+ * value of the second parameter. If they do not match, a compile time error
+ * for negative array size occurs (even gnu chokes on negative array size).
+ *
+ * This compare is done by creating a typedef for an array. No variables are
+ * created and no memory is consumed with this check. The created type is
+ * used for checking only and is not for use by any other code. The value
+ * of 10 in this macro is arbitrary, it just needs to be a value larger
+ * than one to result in a positive number for the array size.
+ */
+#define ACI_ASSERT_SIZE(x,y) typedef char x ## _assert_size_t[-1+10*(sizeof(x) == (y))]
+
+/**
+ * @def ACI_VERSION
+ * @brief Current ACI protocol version. 0 means a device that is not yet released.
+ * A numer greater than 0 refers to a specific ACI version documented and released.
+ * The ACI consists of the ACI commands, ACI events and error codes.
+ */
+#define ACI_VERSION   (0x02)
+/**
+ * @def BTLE_DEVICE_ADDRESS_SIZE
+ * @brief Size in bytes of a Bluetooth Address
+ */
+#define BTLE_DEVICE_ADDRESS_SIZE                 (6)
+/**
+ * @def ACI_PACKET_MAX_LEN
+ * @brief Maximum length in bytes of a full ACI packet, including length prefix, opcode and payload
+ */
+#define ACI_PACKET_MAX_LEN                       (32)
+/**
+ * @def ACI_ECHO_DATA_MAX_LEN
+ * @brief Maximum length in bytes of the echo data portion
+ */
+#define ACI_ECHO_DATA_MAX_LEN                    (ACI_PACKET_MAX_LEN - 3)
+/**
+ * @def ACI_DEVICE_MAX_PIPES
+ * @brief Maximum number of ACI pipes
+ */
+#define ACI_DEVICE_MAX_PIPES                       (62)
+/**
+ * @def ACI_PIPE_TX_DATA_MAX_LEN
+ * @brief Maximum length in bytes of a transmission data pipe packet
+ */
+#define ACI_PIPE_TX_DATA_MAX_LEN                   (20)
+/**
+ * @def ACI_PIPE_RX_DATA_MAX_LEN
+ * @brief Maximum length in bytes of a reception data pipe packet
+ */
+#define ACI_PIPE_RX_DATA_MAX_LEN                   (22)
+/**
+ * @def ACI_GAP_DEVNAME_MAX_LEN
+ * @brief Maximum length in bytes of the GAP device name
+ */
+#define ACI_GAP_DEVNAME_MAX_LEN                 (20)
+/**
+ * @def ACI_AD_PACKET_MAX_LEN
+ * @brief Maximum length in bytes of an AD packet
+ */
+#define ACI_AD_PACKET_MAX_LEN                   (31)
+/**
+ * @def ACI_AD_PACKET_MAX_USER_LEN
+ * @brief Maximum usable length in bytes of an AD packet
+ */
+#define ACI_AD_PACKET_MAX_USER_LEN              (31 - 3)
+/**
+ * @def ACI_PIPE_INVALID
+ * @brief Invalid pipe number
+ */
+#define ACI_PIPE_INVALID                        (0xFF)
+
+/**
+ * @enum aci_pipe_store_t
+ * @brief Storage type identifiers: local and remote
+ */
+typedef enum
+{
+  ACI_STORE_INVALID = 0x0,
+  ACI_STORE_LOCAL= 0x01,
+  ACI_STORE_REMOTE= 0x02
+} _aci_packed_ aci_pipe_store_t;
+
+/**
+ * @enum aci_pipe_type_t
+ * @brief Pipe types
+ */
+typedef enum
+{
+  ACI_TX_BROADCAST = 0x0001,
+  ACI_TX           = 0x0002,
+  ACI_TX_ACK       = 0x0004,
+  ACI_RX           = 0x0008,
+  ACI_RX_ACK       = 0x0010,
+  ACI_TX_REQ       = 0x0020,
+  ACI_RX_REQ       = 0x0040,
+  ACI_SET          = 0x0080,
+  ACI_TX_SIGN      = 0x0100,
+  ACI_RX_SIGN      = 0x0200,
+  ACI_RX_ACK_AUTO  = 0x0400
+} _aci_packed_ aci_pipe_type_t;
+
+ACI_ASSERT_SIZE(aci_pipe_type_t, 2);
+
+/**
+ * @enum aci_bd_addr_type_t
+ * @brief Bluetooth Address types
+ */
+typedef enum
+{
+  ACI_BD_ADDR_TYPE_INVALID  = 0x00,
+  ACI_BD_ADDR_TYPE_PUBLIC  = 0x01,
+  ACI_BD_ADDR_TYPE_RANDOM_STATIC  = 0x02,
+  ACI_BD_ADDR_TYPE_RANDOM_PRIVATE_RESOLVABLE  = 0x03,
+  ACI_BD_ADDR_TYPE_RANDOM_PRIVATE_UNRESOLVABLE  = 0x04
+} _aci_packed_ aci_bd_addr_type_t;
+
+/**
+ * @enum aci_device_output_power_t
+ * @brief Radio output power levels
+ */
+typedef enum
+{
+  ACI_DEVICE_OUTPUT_POWER_MINUS_18DBM = 0x00, /**< Output power set to -18dBm */
+  ACI_DEVICE_OUTPUT_POWER_MINUS_12DBM = 0x01, /**< Output power set to -12dBm */
+  ACI_DEVICE_OUTPUT_POWER_MINUS_6DBM  = 0x02, /**< Output power set to -6dBm  */
+  ACI_DEVICE_OUTPUT_POWER_0DBM  = 0x03  /**< Output power set to 0dBm   - DEFAULT*/
+} _aci_packed_ aci_device_output_power_t;
+
+/**
+ * @enum aci_device_operation_mode_t
+ * @brief Device operation modes
+ */
+typedef enum
+{
+  ACI_DEVICE_INVALID   =0x00,
+  ACI_DEVICE_TEST      =0x01,
+  ACI_DEVICE_SETUP     =0x02,
+  ACI_DEVICE_STANDBY   =0x03,
+  ACI_DEVICE_SLEEP     =0x04
+} _aci_packed_ aci_device_operation_mode_t;
+
+/**
+ * @enum aci_disconnect_reason_t
+ * @brief Reason enumeration for ACI_CMD_DISCONNECT
+ */
+typedef enum
+{
+  ACI_REASON_TERMINATE      =0x01, /**< Use this to disconnect (does a terminate request), you need to wait for the "disconnected" event */
+  ACI_REASON_BAD_TIMING     =0x02 /*<Use this to disconnect and inform the peer, that the timing on the link is not acceptable for the device, you need to wait for the "disconnected" event */
+} _aci_packed_ aci_disconnect_reason_t;
+
+/**
+ * @enum aci_test_mode_change_t
+ * @brief Device test mode control
+ */
+typedef enum
+{
+  ACI_TEST_MODE_DTM_UART    = 0x01,
+  ACI_TEST_MODE_DTM_ACI     = 0x02,
+  ACI_TEST_MODE_EXIT        = 0xFF
+
+} _aci_packed_ aci_test_mode_change_t;
+
+ACI_ASSERT_SIZE(aci_test_mode_change_t, 1);
+
+/**
+ * @enum aci_permissions_t
+ * @brief Data store permissions
+ */
+typedef enum
+{
+  ACI_PERMISSIONS_NONE               =0x00,
+  ACI_PERMISSIONS_LINK_AUTHENTICATED =0x01
+} _aci_packed_ aci_permissions_t;
+
+/**
+ * @def ACI_VS_UUID_128_MAX_COUNT
+ * @brief Maximum number of 128-bit Vendor Specific
+ *        UUIDs that can be set
+ */
+#define ACI_VS_UUID_128_MAX_COUNT  64 /** #0 reserved for invalid, #1 reservered for BT SIG and a maximum of 1024 bytes (16*64) */
+
+/**
+ * @struct aci_ll_conn_params_t
+ * @brief Link Layer Connection Parameters
+ */
+typedef struct
+{
+  uint16_t min_conn_interval;   /**< Minimum connection interval requested from peer */
+    #define ACI_PPCP_MIN_CONN_INTVL_NONE  0xFFFF
+    #define ACI_PPCP_MIN_CONN_INTVL_MIN   0x0006
+    #define ACI_PPCP_MIN_CONN_INTVL_MAX   0x0C80
+  uint16_t max_conn_interval;   /**< Maximum connection interval requested from peer */
+    #define ACI_PPCP_MAX_CONN_INTVL_NONE  0xFFFF
+    #define ACI_PPCP_MAX_CONN_INTVL_MIN   0x0006
+    #define ACI_PPCP_MAX_CONN_INTVL_MAX   0x0C80
+  uint16_t slave_latency;       /**< Connection interval latency requested from peer */
+    #define ACI_PPCP_SLAVE_LATENCY_MAX    0x03E8
+  uint16_t timeout_mult;        /**< Link supervisor timeout multiplier requested from peer */
+    #define ACI_PPCP_TIMEOUT_MULT_NONE    0xFFFF
+    #define ACI_PPCP_TIMEOUT_MULT_MIN     0x000A
+    #define ACI_PPCP_TIMEOUT_MULT_MAX     0x0C80
+} _aci_packed_ aci_ll_conn_params_t;
+
+/**
+ * @def aci_gap_ppcp_t
+ * @brief GAP Peripheral Preferred Connection Parameters
+ */
+#define aci_gap_ppcp_t aci_ll_conn_params_t
+
+/**
+ * @def ACI_AD_LOC_SVCUUID_16_MAX_COUNT
+ * @brief Maximum number of 16-bit UUIDs that can
+ *        be inserted in the Services tag of AD
+ */
+#define ACI_AD_LOC_SVCUUID_16_MAX_COUNT  5
+
+/**
+ * @def ACI_AD_LOC_SVCUUID_128_MAX_COUNT
+ * @brief Maximum number of 128-bit UUIDs that can
+ *        be inserted in the Services tag of AD
+ */
+#define ACI_AD_LOC_SVCUUID_128_MAX_COUNT  1
+
+/**
+ * @def ACI_AD_SOL_SVCUUID_16_MAX_COUNT
+ * @brief Maximum number of UUIDs that can
+ *        be inserted in the Solicited Services tag of AD
+ */
+#define ACI_AD_SOL_SVCUUID_16_MAX_COUNT  5
+
+/**
+ * @def ACI_AD_SOL_SVCUUID_128_MAX_COUNT
+ * @brief Maximum number of UUIDs that can
+ *        be inserted in the Solicited Services tag of AD
+ */
+#define ACI_AD_SOL_SVCUUID_128_MAX_COUNT  1
+
+/**
+ * @def ACI_SEC_ENCKEY_SIZE_MIN
+ * @brief Minimum encryption key size
+ */
+#define ACI_SEC_ENCKEY_SIZE_MIN        7
+/**
+ * @def ACI_SEC_ENCKEY_SIZE_MAX
+ * @brief Maximum encryption key size
+ */
+#define ACI_SEC_ENCKEY_SIZE_MAX        16
+/**
+ * @def ACI_CUSTOM_AD_TYPE_MAX_COUNT
+ * @brief Maximum number of custom ad types
+ */
+#define ACI_CUSTOM_AD_TYPE_MAX_COUNT 8
+/**
+ * @def ACI_CUSTOM_AD_TYPE_MAX_DATA_LENGTH
+ * @brief Maximum custom ad type data size
+ */
+#define ACI_CUSTOM_AD_TYPE_MAX_DATA_LENGTH 20
+
+/**
+ * @struct aci_tx_data_t
+ * @brief Generic ACI transmit data structure
+ */
+typedef struct
+{
+  uint8_t pipe_number;
+  uint8_t aci_data[ACI_PIPE_TX_DATA_MAX_LEN];
+} _aci_packed_ aci_tx_data_t;
+
+ACI_ASSERT_SIZE(aci_tx_data_t, ACI_PIPE_TX_DATA_MAX_LEN + 1);
+
+/**
+ * @struct aci_rx_data_t
+ * @brief Generic ACI receive data structure
+ */
+typedef struct
+{
+  uint8_t pipe_number;
+  uint8_t aci_data[ACI_PIPE_RX_DATA_MAX_LEN];
+} _aci_packed_ aci_rx_data_t;
+
+ACI_ASSERT_SIZE(aci_rx_data_t, ACI_PIPE_RX_DATA_MAX_LEN + 1);
+
+/**
+ * @enum aci_hw_error_t
+ * @brief Hardware Error codes
+ */
+typedef enum
+{
+  ACI_HW_ERROR_NONE     = 0x00,
+  ACI_HW_ERROR_FATAL    = 0x01
+} _aci_packed_ aci_hw_error_t;
+
+/**
+ * @enum aci_clock_accuracy_t
+ * @brief Bluetooth Low Energy Clock Accuracy
+ */
+typedef enum
+{
+  ACI_CLOCK_ACCURACY_500_PPM = 0x00,
+  ACI_CLOCK_ACCURACY_250_PPM = 0x01,
+  ACI_CLOCK_ACCURACY_150_PPM = 0x02,
+  ACI_CLOCK_ACCURACY_100_PPM = 0x03,
+  ACI_CLOCK_ACCURACY_75_PPM  = 0x04,
+  ACI_CLOCK_ACCURACY_50_PPM  = 0x05,
+  ACI_CLOCK_ACCURACY_30_PPM  = 0x06,
+  ACI_CLOCK_ACCURACY_20_PPM  = 0x07
+} _aci_packed_ aci_clock_accuracy_t;
+
+/**
+ * @enum aci_app_latency_mode_t
+ * @brief Application latency modes
+ */
+typedef enum
+{
+  ACI_APP_LATENCY_DISABLE = 0,
+  ACI_APP_LATENCY_ENABLE = 1
+} _aci_packed_ aci_app_latency_mode_t;
+
+/**
+ * @enum gatt_format_t
+ * @brief GATT format definitions
+ */
+typedef enum
+{
+  ACI_GATT_FORMAT_NONE        = 0x00, /**< No characteristic format available */
+  ACI_GATT_FORMAT_BOOLEAN     = 0x01, /**< Not Supported */
+  ACI_GATT_FORMAT_2BIT        = 0x02, /**< Not Supported */
+  ACI_GATT_FORMAT_NIBBLE      = 0x03, /**< Not Supported */
+  ACI_GATT_FORMAT_UINT8       = 0x04,
+  ACI_GATT_FORMAT_UINT12      = 0x05,
+  ACI_GATT_FORMAT_UINT16      = 0x06,
+  ACI_GATT_FORMAT_UINT24      = 0x07,
+  ACI_GATT_FORMAT_UINT32      = 0x08,
+  ACI_GATT_FORMAT_UINT48      = 0x09,
+  ACI_GATT_FORMAT_UINT64      = 0x0A,
+  ACI_GATT_FORMAT_UINT128     = 0x0B,
+  ACI_GATT_FORMAT_SINT8       = 0x0C,
+  ACI_GATT_FORMAT_SINT12      = 0x0D,
+  ACI_GATT_FORMAT_SINT16      = 0x0E,
+  ACI_GATT_FORMAT_SINT24      = 0x0F,
+  ACI_GATT_FORMAT_SINT32      = 0x10,
+  ACI_GATT_FORMAT_SINT48      = 0x11,
+  ACI_GATT_FORMAT_SINT64      = 0x12,
+  ACI_GATT_FORMAT_SINT128     = 0x13,
+  ACI_GATT_FORMAT_FLOAT32     = 0x14,
+  ACI_GATT_FORMAT_FLOAT64     = 0x15,
+  ACI_GATT_FORMAT_SFLOAT      = 0x16,
+  ACI_GATT_FORMAT_FLOAT       = 0x17,
+  ACI_GATT_FORMAT_DUINT16     = 0x18,
+  ACI_GATT_FORMAT_UTF8S       = 0x19,
+  ACI_GATT_FORMAT_UTF16S      = 0x1A,
+  ACI_GATT_FORMAT_STRUCT      = 0x1B
+} _aci_packed_ aci_gatt_format_t;
+
+/**
+ * @brief GATT Bluetooth namespace
+ */
+typedef enum
+{
+  ACI_GATT_NAMESPACE_INVALID  = 0x00,
+  ACI_GATT_NAMESPACE_BTSIG    = 0x01 /**< Bluetooth SIG */
+} _aci_packed_ aci_gatt_namespace_t;
+
+/**
+ * @brief Security key types
+ */
+typedef enum
+{
+  ACI_KEY_TYPE_INVALID  = 0x00,
+  ACI_KEY_TYPE_PASSKEY  = 0x01
+} _aci_packed_ aci_key_type_t;
+
+/**
+ * @enum aci_bond_status_code_t
+ * @brief Bond status code
+ */
+typedef enum
+{
+ /**
+  * Bonding succeeded
+  */
+  ACI_BOND_STATUS_SUCCESS                             = 0x00,
+ /**
+  * Bonding failed
+  */
+  ACI_BOND_STATUS_FAILED                              = 0x01,
+ /**
+  * Bonding error: Timeout can occur when link termination is unexpected or did not get connected OR SMP timer expired
+  */
+  ACI_BOND_STATUS_FAILED_TIMED_OUT                    = 0x02,
+ /**
+  * Bonding error: Passkey entry failed
+  */
+  ACI_BOND_STATUS_FAILED_PASSKEY_ENTRY_FAILED        = 0x81,
+ /**
+  * Bonding error: OOB unavailable
+  */
+  ACI_BOND_STATUS_FAILED_OOB_UNAVAILABLE             = 0x82,
+ /**
+  * Bonding error: Authentication request failed
+  */
+  ACI_BOND_STATUS_FAILED_AUTHENTICATION_REQ          = 0x83,
+ /**
+  * Bonding error: Confirm value failed
+  */
+  ACI_BOND_STATUS_FAILED_CONFIRM_VALUE               = 0x84,
+ /**
+  * Bonding error: Pairing unsupported
+  */
+  ACI_BOND_STATUS_FAILED_PAIRING_UNSUPPORTED         = 0x85,
+ /**
+  * Bonding error: Invalid encryption key size
+  */
+  ACI_BOND_STATUS_FAILED_ENCRYPTION_KEY_SIZE         = 0x86,
+ /**
+  * Bonding error: Unsupported SMP command
+  */
+  ACI_BOND_STATUS_FAILED_SMP_CMD_UNSUPPORTED         = 0x87,
+ /**
+  * Bonding error: Unspecified reason
+  */
+  ACI_BOND_STATUS_FAILED_UNSPECIFIED_REASON          = 0x88,
+ /**
+  * Bonding error: Too many attempts
+  */
+  ACI_BOND_STATUS_FAILED_REPEATED_ATTEMPTS           = 0x89,
+ /**
+  * Bonding error: Invalid parameters
+  */
+  ACI_BOND_STATUS_FAILED_INVALID_PARAMETERS          = 0x8A
+
+} _aci_packed_ aci_bond_status_code_t;
+
+ACI_ASSERT_SIZE(aci_bond_status_code_t, 1);
+
+/**
+ * @enum aci_bond_status_source_t
+ * @brief Source of a bond status code
+ */
+typedef enum
+{
+  ACI_BOND_STATUS_SOURCE_INVALID                  = 0x00,
+  ACI_BOND_STATUS_SOURCE_LOCAL                    = 0x01,
+  ACI_BOND_STATUS_SOURCE_REMOTE                   = 0x02
+
+} _aci_packed_ aci_bond_status_source_t;
+
+/**
+ * @enum aci_status_code_t
+ * @brief ACI status codes
+ */
+typedef enum
+{
+ /**
+  * Success
+  */
+  ACI_STATUS_SUCCESS                                        = 0x00,
+ /**
+  * Transaction continuation status
+  */
+  ACI_STATUS_TRANSACTION_CONTINUE                           = 0x01,
+ /**
+  * Transaction completed
+  */
+  ACI_STATUS_TRANSACTION_COMPLETE                           = 0x02,
+ /**
+  * Extended status, further checks needed
+  */
+  ACI_STATUS_EXTENDED                                       = 0x03,
+ /**
+  * Unknown error.
+  */
+  ACI_STATUS_ERROR_UNKNOWN                                  = 0x80,
+ /**
+  * Internal error.
+  */
+  ACI_STATUS_ERROR_INTERNAL                                 = 0x81,
+ /**
+  * Unknown command
+  */
+  ACI_STATUS_ERROR_CMD_UNKNOWN                              = 0x82,
+ /**
+  * Command invalid in the current device state
+  */
+  ACI_STATUS_ERROR_DEVICE_STATE_INVALID                     = 0x83,
+ /**
+  * Invalid length
+  */
+  ACI_STATUS_ERROR_INVALID_LENGTH                           = 0x84,
+ /**
+  * Invalid input parameters
+  */
+  ACI_STATUS_ERROR_INVALID_PARAMETER                        = 0x85,
+ /**
+  * Busy
+  */
+  ACI_STATUS_ERROR_BUSY                                     = 0x86,
+ /**
+  * Invalid data format or contents
+  */
+  ACI_STATUS_ERROR_INVALID_DATA                             = 0x87,
+ /**
+  * CRC mismatch
+  */
+  ACI_STATUS_ERROR_CRC_MISMATCH                             = 0x88,
+ /**
+  * Unsupported setup format
+  */
+  ACI_STATUS_ERROR_UNSUPPORTED_SETUP_FORMAT                 = 0x89,
+ /**
+  * Invalid sequence number during a write dynamic data sequence
+  */
+  ACI_STATUS_ERROR_INVALID_SEQ_NO                           = 0x8A,
+ /**
+  * Setup data is locked and cannot be modified
+  */
+  ACI_STATUS_ERROR_SETUP_LOCKED                             = 0x8B,
+ /**
+  * Setup error due to lock verification failure
+  */
+  ACI_STATUS_ERROR_LOCK_FAILED                              = 0x8C,
+ /**
+  * Bond required: Local Pipes need bonded/trusted peer
+  */
+  ACI_STATUS_ERROR_BOND_REQUIRED                            = 0x8D,
+ /**
+  * Command rejected as a transaction is still pending
+  */
+  ACI_STATUS_ERROR_REJECTED                                 = 0x8E,
+  /**
+  * Pipe Error Event : Data size exceeds size specified for pipe : Transmit failed
+  */
+  ACI_STATUS_ERROR_DATA_SIZE                                = 0x8F,
+ /**
+  * Pipe Error Event : Invalid pipe
+  */
+  ACI_STATUS_ERROR_PIPE_INVALID                             = 0x90,
+ /**
+  * Pipe Error Event : Credit not available
+  */
+  ACI_STATUS_ERROR_CREDIT_NOT_AVAILABLE                     = 0x91,
+ /**
+  * Pipe Error Event : Peer device has sent an error on an pipe operation on the remote characteristic
+  */
+  ACI_STATUS_ERROR_PEER_ATT_ERROR                           = 0x92,
+ /**
+  * Connection was not established before the BTLE advertising was stopped
+  */
+  ACI_STATUS_ERROR_ADVT_TIMEOUT                             = 0x93,
+ /**
+  * Peer has triggered a Security Manager Protocol Error
+  */
+  ACI_STATUS_ERROR_PEER_SMP_ERROR                           = 0x94,
+ /**
+  * Pipe Error Event : Pipe type invalid for the selected operation
+  */
+  ACI_STATUS_ERROR_PIPE_TYPE_INVALID                        = 0x95,
+ /**
+  * Pipe Error Event : Pipe state invalid for the selected operation
+  */
+  ACI_STATUS_ERROR_PIPE_STATE_INVALID                       = 0x96,
+ /**
+  * Invalid key size provided
+  */
+  ACI_STATUS_ERROR_INVALID_KEY_SIZE                         = 0x97,
+ /**
+  * Invalid key data provided
+  */
+  ACI_STATUS_ERROR_INVALID_KEY_DATA                         = 0x98,
+ /**
+  * Reserved range start
+  */
+  ACI_STATUS_RESERVED_START                                 = 0xF0,
+ /**
+  * Reserved range end
+  */
+  ACI_STATUS_RESERVED_END                                   = 0xFF
+
+} _aci_packed_ aci_status_code_t;
+
+ACI_ASSERT_SIZE(aci_status_code_t, 1);
+
+/**
+ * @}
+ */
+
+#endif // ACI_H__
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/ble_shield2.1/utility/aci_cmds.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/ble_shield2.1/utility/aci_cmds.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/ble_shield2.1/utility/aci_cmds.h	(revision 457)
@@ -0,0 +1,435 @@
+/* Copyright (c) 2014, Nordic Semiconductor ASA
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+/**
+ * @file
+ *
+ * @ingroup aci
+ *
+ * @brief Definitions for the ACI (Application Control Interface) commands
+ * @remarks
+ *
+ */
+
+#ifndef ACI_CMDS_H__
+#define ACI_CMDS_H__
+
+#include "aci.h"
+
+/**
+ * @enum aci_cmd_opcode_t
+ * @brief ACI command opcodes
+ */
+typedef enum
+{
+ /**
+  * Enter test mode
+  */
+  ACI_CMD_TEST                    = 0x01,
+ /**
+  * Echo (loopback) test command
+  */
+  ACI_CMD_ECHO                    = 0x02,
+ /**
+  * Send a BTLE DTM command to the radio
+  */
+  ACI_CMD_DTM_CMD                 = 0x03,
+  /**
+  * Put the device to sleep
+  */
+  ACI_CMD_SLEEP                   = 0x04,
+ /**
+  * Wakeup the device from deep sleep
+  */
+  ACI_CMD_WAKEUP                  = 0x05,
+ /**
+  * Replace the contents of the internal database with
+  * user provided data
+  */
+  ACI_CMD_SETUP                   = 0x06,
+ /**
+  * Read the portions of memory required to be restored after a power cycle
+  */
+  ACI_CMD_READ_DYNAMIC_DATA       = 0x07,
+ /**
+  * Write back the data retrieved using ACI_CMD_READ_DYNAMIC_DATA
+  */
+  ACI_CMD_WRITE_DYNAMIC_DATA      = 0x08,
+  /**
+  * Retrieve the device's version information
+  */
+  ACI_CMD_GET_DEVICE_VERSION      = 0x09,
+ /**
+  * Request the Bluetooth address and its type
+  */
+  ACI_CMD_GET_DEVICE_ADDRESS      = 0x0A,
+  /**
+  * Request the battery level measured by nRF8001
+  */
+  ACI_CMD_GET_BATTERY_LEVEL       = 0x0B,
+ /**
+  * Request the temperature value measured by nRF8001
+  */
+  ACI_CMD_GET_TEMPERATURE         = 0x0C,
+ /**
+  * Write to the local Attribute Database
+  */
+  ACI_CMD_SET_LOCAL_DATA          = 0x0D,
+ /**
+  * Reset the baseband and radio and go back to idle
+  */
+  ACI_CMD_RADIO_RESET          = 0x0E,
+ /**
+  * Start advertising and wait for a master connection
+  */
+  ACI_CMD_CONNECT                 = 0x0F,
+ /**
+  * Start advertising and wait for a master connection
+  */
+  ACI_CMD_BOND                    = 0x10,
+ /**
+  * Start advertising and wait for a master connection
+  */
+  ACI_CMD_DISCONNECT              = 0x11,
+ /**
+  * Throttles the Radio transmit power
+  */
+  ACI_CMD_SET_TX_POWER            = 0x12,
+ /**
+  * Trigger a connection parameter update
+  */
+  ACI_CMD_CHANGE_TIMING           = 0x13,
+ /**
+  * Open a remote pipe for data reception
+  */
+  ACI_CMD_OPEN_REMOTE_PIPE        = 0x14,
+ /**
+  * Transmit data over an open pipe
+  */
+  ACI_CMD_SEND_DATA               = 0x15,
+ /**
+  * Send an acknowledgment of received data
+  */
+  ACI_CMD_SEND_DATA_ACK           = 0x16,
+ /**
+  * Request data over an open pipe
+  */
+  ACI_CMD_REQUEST_DATA            = 0x17,
+ /**
+  * NACK a data reception
+  */
+  ACI_CMD_SEND_DATA_NACK          = 0x18,
+ /**
+  * Set application latency
+  */
+  ACI_CMD_SET_APP_LATENCY         = 0x19,
+ /**
+  * Set a security key
+  */
+  ACI_CMD_SET_KEY                 = 0x1A,
+ /**
+  * Open Advertising Pipes
+  */
+  ACI_CMD_OPEN_ADV_PIPE           = 0x1B,
+ /**
+  * Start non-connectable advertising
+  */
+  ACI_CMD_BROADCAST               = 0x1C,
+ /**
+  * Start a security request in bonding mode
+  */
+  ACI_CMD_BOND_SECURITY_REQUEST   = 0x1D,
+ /**
+  * Start Directed advertising towards a Bonded Peer
+  */
+  ACI_CMD_CONNECT_DIRECT          = 0x1E,
+ /**
+  * Close a previously opened remote pipe
+  */
+  ACI_CMD_CLOSE_REMOTE_PIPE       = 0x1F,
+ /**
+  * Invalid ACI command opcode
+  */
+  ACI_CMD_INVALID                 = 0xFF
+
+} _aci_packed_ aci_cmd_opcode_t;
+
+ACI_ASSERT_SIZE(aci_cmd_opcode_t, 1);
+
+/**
+ * @struct aci_cmd_params_test_t
+ * @brief  Structure for the ACI_CMD_TEST ACI command parameters
+ */
+typedef struct
+{
+  aci_test_mode_change_t test_mode_change; /**< enum aci_test_mode_change_t */
+} _aci_packed_ aci_cmd_params_test_t;
+
+ACI_ASSERT_SIZE(aci_cmd_params_test_t, 1);
+
+/**
+ * @struct aci_cmd_params_echo_t
+ * @brief  Structure for the ACI_CMD_ECHO ACI command parameters
+ */
+typedef struct
+{
+  uint8_t echo_data[ACI_ECHO_DATA_MAX_LEN];
+} _aci_packed_ aci_cmd_params_echo_t;
+
+ACI_ASSERT_SIZE(aci_cmd_params_echo_t, ACI_ECHO_DATA_MAX_LEN);
+
+/**
+ * @struct aci_cmd_params_dtm_cmd_t
+ * @brief  Structure for the ACI_CMD_DTM_CMD ACI command parameters
+ */
+typedef struct
+{
+  uint8_t                 cmd_msb;
+  uint8_t                 cmd_lsb;
+} _aci_packed_ aci_cmd_params_dtm_cmd_t;
+
+/**
+ * @struct aci_cmd_params_setup_t
+ * @brief  Structure for the ACI_CMD_SETUP ACI command parameters
+ */
+typedef struct
+{
+  uint8_t                 setup_data[1];
+} _aci_packed_ aci_cmd_params_setup_t;
+
+ACI_ASSERT_SIZE(aci_cmd_params_setup_t, 1);
+
+/**
+ * @struct aci_cmd_params_write_dynamic_data_t
+ * @brief  Structure for the ACI_CMD_WRITE_DYNAMIC_DATA ACI command parameters 
+ * @note Dynamic data chunk size in this command is defined to go up to ACI_PACKET_MAX_LEN - 3
+ */
+typedef struct
+{
+  uint8_t                 seq_no;
+  uint8_t                 dynamic_data[1];
+} _aci_packed_ aci_cmd_params_write_dynamic_data_t;
+
+/**
+ * @define aci_cmd_params_set_local_data_t
+ * @brief  Structure for the ACI_CMD_SET_LOCAL_DATA ACI command parameters
+ */
+typedef struct
+{
+  aci_tx_data_t tx_data;
+} _aci_packed_ aci_cmd_params_set_local_data_t;
+
+/**
+ * @struct aci_cmd_params_connect_t
+ * @brief  Structure for the ACI_CMD_CONNECT ACI command parameters
+ */
+typedef struct
+{
+  uint16_t        timeout;  /**< 0x0000 (no timeout) to 0x3FFF */
+  uint16_t        adv_interval;     /**< 16 bits of advertising interval for general discovery */
+} _aci_packed_ aci_cmd_params_connect_t;
+
+ACI_ASSERT_SIZE(aci_cmd_params_connect_t, 4);
+
+/**
+ * @define aci_cmd_params_bond_t
+ * @brief  Structure for the ACI_CMD_BOND ACI command parameters
+ */
+typedef struct
+{
+  uint16_t        timeout;  /**< 0x0000 (no timeout) to 0x3FFF */
+  uint16_t        adv_interval;     /**< 16 bits of advertising interval for general discovery */
+} _aci_packed_ aci_cmd_params_bond_t;
+
+ACI_ASSERT_SIZE(aci_cmd_params_bond_t, 4);
+
+/**
+ * @struct aci_cmd_params_disconnect_t
+ * @brief  Structure for the ACI_CMD_DISCONNECT ACI command parameters
+ */
+typedef struct
+{
+  aci_disconnect_reason_t         reason; /**< enum aci_disconnect_reason_t */
+} _aci_packed_ aci_cmd_params_disconnect_t;
+
+ACI_ASSERT_SIZE(aci_cmd_params_disconnect_t, 1);
+
+/**
+ * @struct aci_cmd_params_set_tx_power_t
+ * @brief  Structure for the ACI_CMD_SET_TX_POWER ACI command parameters
+ */
+typedef struct
+{
+  aci_device_output_power_t   device_power; /**< enum aci_device_output_power_t */
+} _aci_packed_ aci_cmd_params_set_tx_power_t;
+
+ACI_ASSERT_SIZE(aci_cmd_params_set_tx_power_t, 1);
+/**
+ * @struct aci_cmd_params_change_timing_t
+ * @brief  Structure for the ACI_CMD_CHANGE_TIMING ACI command parameters
+ */
+typedef struct
+{
+  aci_ll_conn_params_t    conn_params;
+} _aci_packed_ aci_cmd_params_change_timing_t;
+
+ACI_ASSERT_SIZE(aci_cmd_params_change_timing_t, 8);
+
+/**
+ * @struct aci_cmd_params_open_remote_pipe_t
+ * @brief  Structure for the ACI_CMD_OPEN_REMOTE_PIPE ACI command parameters
+ */
+typedef struct
+{
+  uint8_t pipe_number;
+} _aci_packed_ aci_cmd_params_open_remote_pipe_t;
+
+/**
+ * @struct aci_cmd_params_send_data_t
+ * @brief  Structure for the ACI_CMD_SEND_DATA ACI command parameters
+ */
+typedef struct
+{
+  aci_tx_data_t tx_data;
+} _aci_packed_ aci_cmd_params_send_data_t;
+
+/**
+ * @define aci_cmd_params_send_data_ack_t
+ * @brief  Structure for the ACI_CMD_SEND_DATA_ACK ACI command parameters
+ */
+typedef struct
+{
+  uint8_t pipe_number;
+} _aci_packed_ aci_cmd_params_send_data_ack_t;
+
+/**
+ * @struct aci_cmd_params_send_data_t
+ * @brief  Structure for the ACI_CMD_SEND_DATA ACI command parameters
+ */
+typedef struct
+{
+  uint8_t pipe_number;
+} _aci_packed_ aci_cmd_params_request_data_t;
+
+/**
+ * @define aci_cmd_params_send_data_nack_t
+ * @brief  Structure for the ACI_CMD_SEND_DATA_NACK ACI command parameters
+ */
+typedef struct
+{
+  uint8_t pipe_number;
+  uint8_t error_code;
+} _aci_packed_ aci_cmd_params_send_data_nack_t;
+
+ACI_ASSERT_SIZE(aci_cmd_params_send_data_nack_t, 2);
+
+/**
+ * @define aci_cmd_params_set_app_latency_t
+ * @brief  Structure for the ACI_CMD_SET_APP_LATENCY ACI command parameters
+ */
+typedef struct
+{
+  aci_app_latency_mode_t mode;
+  uint16_t latency;
+} _aci_packed_ aci_cmd_params_set_app_latency_t;
+
+ACI_ASSERT_SIZE(aci_cmd_params_set_app_latency_t, 3);
+/**
+ * @define aci_cmd_params_set_key_t
+ * @brief  Structure for the ACI_CMD_SET_KEY ACI command parameters
+ */
+typedef struct
+{
+  aci_key_type_t key_type;
+  union
+  {
+    uint8_t passkey[6];
+    uint8_t oob_key[16];
+  } key;
+} _aci_packed_ aci_cmd_params_set_key_t;
+
+ACI_ASSERT_SIZE(aci_cmd_params_set_key_t, 17);
+/**
+ * @define aci_cmd_params_open_adv_pipe_t
+ * @brief  Structure for the ACI_CMD_OPEN_ADV_PIPE ACI command parameters
+ */
+typedef struct
+{
+  uint8_t pipes[8];
+} _aci_packed_ aci_cmd_params_open_adv_pipe_t;
+
+/**
+ * @define aci_cmd_params_broadcast_t
+ * @brief  Structure for the ACI_CMD_BROADCAST ACI command parameters
+ */
+typedef struct
+{
+  uint16_t        timeout;  /**< 0x0000 (no timeout) to 0x3FFF */
+  uint16_t        adv_interval;     /**< 16 bits of advertising interval for general discovery */
+} _aci_packed_ aci_cmd_params_broadcast_t;
+
+/**
+ * @struct aci_cmd_params_close_remote_pipe_t
+ * @brief  Structure for the ACI_CMD_CLOSE_REMOTE_PIPE ACI command parameters
+ */
+typedef struct
+{
+  uint8_t pipe_number;
+} _aci_packed_ aci_cmd_params_close_remote_pipe_t;
+
+/**
+ * @struct aci_cmd_t
+ * @brief  Encapsulates a generic ACI command
+ */
+typedef struct
+{
+  uint8_t len;        /**< Length of the ACI command */
+  aci_cmd_opcode_t cmd_opcode; /**< enum aci_cmd_opcode_t -> Opcode of the ACI command */
+  union
+  {
+    aci_cmd_params_test_t                       test;
+    aci_cmd_params_echo_t                       echo;
+    aci_cmd_params_dtm_cmd_t                    dtm_cmd;
+    aci_cmd_params_setup_t                      setup;
+    aci_cmd_params_write_dynamic_data_t         write_dynamic_data;
+    aci_cmd_params_set_local_data_t             set_local_data;
+    aci_cmd_params_connect_t                    connect;
+    aci_cmd_params_bond_t                       bond;
+    aci_cmd_params_disconnect_t                 disconnect;
+    aci_cmd_params_set_tx_power_t               set_tx_power;
+    aci_cmd_params_change_timing_t              change_timing;
+    aci_cmd_params_open_remote_pipe_t           open_remote_pipe;
+    aci_cmd_params_send_data_t                  send_data;
+    aci_cmd_params_send_data_ack_t              send_data_ack;
+    aci_cmd_params_request_data_t               request_data;
+    aci_cmd_params_send_data_nack_t             send_data_nack;
+    aci_cmd_params_set_app_latency_t            set_app_latency;
+    aci_cmd_params_set_key_t                    set_key;
+    aci_cmd_params_open_adv_pipe_t              open_adv_pipe;
+    aci_cmd_params_broadcast_t                  broadcast;
+    aci_cmd_params_close_remote_pipe_t          close_remote_pipe;
+
+  } params;
+} _aci_packed_ aci_cmd_t;
+
+#endif // ACI_CMDS_H__
+
+
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/ble_shield2.1/utility/aci_evts.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/ble_shield2.1/utility/aci_evts.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/ble_shield2.1/utility/aci_evts.h	(revision 457)
@@ -0,0 +1,397 @@
+/* Copyright (c) 2014, Nordic Semiconductor ASA
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+/**
+ * @file
+ *
+ * @ingroup aci
+ *
+ * @brief Definitions for the ACI (Application Control Interface) events
+ */
+
+#ifndef ACI_EVTS_H__
+#define ACI_EVTS_H__
+
+#include "aci.h"
+
+/**
+ * @enum aci_evt_opcode_t
+ * @brief ACI event opcodes
+ */
+typedef enum
+{
+ /**
+  * Invalid event code
+  */
+  ACI_EVT_INVALID                     = 0x00,
+ /**
+  * Sent every time the device starts
+  */
+  ACI_EVT_DEVICE_STARTED              = 0x81,
+ /**
+  * Mirrors the ACI_CMD_ECHO
+  */
+  ACI_EVT_ECHO                        = 0x82,
+ /**
+  * Asynchronous hardware error event
+  */
+  ACI_EVT_HW_ERROR                  = 0x83,
+ /**
+  * Event opcode used as a event response for all commands
+  */
+  ACI_EVT_CMD_RSP                     = 0x84,
+ /**
+  * Link connected
+  */
+  ACI_EVT_CONNECTED                   = 0x85,
+ /**
+  * Link disconnected
+  */
+  ACI_EVT_DISCONNECTED                = 0x86,
+ /**
+  * Bond completion result
+  */
+  ACI_EVT_BOND_STATUS                 = 0x87,
+  /**
+  * Pipe bitmap for available pipes
+  */
+  ACI_EVT_PIPE_STATUS             = 0x88,
+ /**
+  * Sent to the application when the radio enters a connected state
+  * or when the timing of the radio connection changes
+  */
+  ACI_EVT_TIMING                      = 0x89,
+ /**
+  * Notification to the application that transmit credits are
+  * available
+  */
+  ACI_EVT_DATA_CREDIT                 = 0x8A,
+ /**
+  * Data acknowledgement event
+  */
+  ACI_EVT_DATA_ACK                    = 0x8B,
+ /**
+  * Data received notification event
+  */
+  ACI_EVT_DATA_RECEIVED               = 0x8C,
+ /**
+  * Error notification event
+  */
+  ACI_EVT_PIPE_ERROR                  = 0x8D,
+ /**
+  * Display Passkey Event
+  */
+  ACI_EVT_DISPLAY_PASSKEY             = 0x8E,
+ /**
+  * Security Key request
+  */
+  ACI_EVT_KEY_REQUEST                 = 0x8F
+
+} _aci_packed_ aci_evt_opcode_t;
+
+ACI_ASSERT_SIZE(aci_evt_opcode_t, 1);
+
+/**
+ * @struct aci_evt_params_device_started_t
+ * @brief Structure for the ACI_EVT_DEVICE_STARTED event return parameters
+ */
+typedef struct
+{
+  aci_device_operation_mode_t device_mode; /**< Mode in which the device is being started */
+  aci_hw_error_t hw_error;  /**< Hardware Error if available for the start */
+  uint8_t credit_available; /**< Flow control credit available for this specific FW build */
+} _aci_packed_ aci_evt_params_device_started_t;
+
+ACI_ASSERT_SIZE(aci_evt_params_device_started_t, 3);
+
+/**
+ * @struct aci_evt_params_hw_error_t
+ * @brief Structure for the ACI_EVT_HW_ERROR event return parameters
+ */
+typedef struct
+{
+  uint16_t line_num;
+  uint8_t file_name[20];
+} _aci_packed_ aci_evt_params_hw_error_t;
+
+ACI_ASSERT_SIZE(aci_evt_params_hw_error_t, 22);
+
+/**
+ * @struct aci_evt_cmd_rsp_params_dtm_cmd_t
+ * @brief Structure for the ACI_EVT_CMD_RSP event with opcode=ACI_CMD_DTM_CMD event return parameters
+ */
+typedef struct
+{
+  uint8_t  evt_msb;
+  uint8_t  evt_lsb;
+} _aci_packed_ aci_evt_cmd_rsp_params_dtm_cmd_t;
+
+/**
+ * @struct aci_evt_cmd_rsp_read_dynamic_data_t
+ * @brief Structure for the ACI_EVT_CMD_RSP event with opcode=ACI_CMD_READ_DYNAMIC_DATA event return parameters
+ * @note Dynamic data chunk size in this event is defined to go up to ACI_PACKET_MAX_LEN - 5
+ */
+typedef struct
+{
+  uint8_t seq_no;
+  uint8_t dynamic_data[1];
+} _aci_packed_ aci_evt_cmd_rsp_read_dynamic_data_t;
+
+/**
+ * @struct aci_evt_cmd_rsp_params_get_device_version_t
+ * @brief Structure for the ACI_EVT_CMD_RSP event with opcode=ACI_CMD_GET_DEVICE_VERSION event return parameters
+ */
+typedef struct
+{
+  uint16_t  configuration_id;
+  uint8_t   aci_version;
+  uint8_t   setup_format;
+  uint32_t  setup_id;
+  uint8_t   setup_status;
+} _aci_packed_ aci_evt_cmd_rsp_params_get_device_version_t;
+
+ACI_ASSERT_SIZE(aci_evt_cmd_rsp_params_get_device_version_t, 9);
+
+/**
+ * @struct aci_evt_cmd_rsp_params_get_device_address_t
+ * @brief Structure for the ACI_EVT_CMD_RSP event with opcode=ACI_CMD_GET_DEVICE_ADDRESS event return parameters
+ */
+typedef struct
+{
+  uint8_t  bd_addr_own[BTLE_DEVICE_ADDRESS_SIZE];
+  aci_bd_addr_type_t bd_addr_type;
+} _aci_packed_ aci_evt_cmd_rsp_params_get_device_address_t;
+
+ACI_ASSERT_SIZE(aci_evt_cmd_rsp_params_get_device_address_t, BTLE_DEVICE_ADDRESS_SIZE + 1);
+
+/**
+ * @struct aci_evt_cmd_rsp_params_get_battery_level_t
+ * @brief Structure for the ACI_EVT_CMD_RSP event with opcode=ACI_CMD_GET_BATTERY_LEVEL event return parameters
+ */
+typedef struct
+{
+  uint16_t battery_level;
+} _aci_packed_ aci_evt_cmd_rsp_params_get_battery_level_t;
+
+/**
+ * @struct aci_evt_cmd_rsp_params_get_temperature_t
+ * @brief Structure for the ACI_EVT_CMD_RSP event with opcode=ACI_CMD_GET_TEMPERATURE event return parameters
+ */
+typedef struct
+{
+  int16_t temperature_value;
+} _aci_packed_ aci_evt_cmd_rsp_params_get_temperature_t;
+
+/**
+ * @struct aci_evt_params_cmd_rsp_t
+ * @brief Structure for the ACI_EVT_CMD_RSP event return parameters
+ */
+typedef struct
+{
+  aci_cmd_opcode_t cmd_opcode; /**< Command opcode for which the event response is being sent */
+  aci_status_code_t cmd_status; /**< Status of the command that was sent. Used in the context of the command. */
+  union
+  {
+    aci_evt_cmd_rsp_params_dtm_cmd_t dtm_cmd;
+    aci_evt_cmd_rsp_read_dynamic_data_t read_dynamic_data;
+    aci_evt_cmd_rsp_params_get_device_version_t get_device_version;
+    aci_evt_cmd_rsp_params_get_device_address_t get_device_address;
+    aci_evt_cmd_rsp_params_get_battery_level_t  get_battery_level;
+    aci_evt_cmd_rsp_params_get_temperature_t    get_temperature;
+    uint8_t                                     padding[29];  
+  } params;
+} _aci_packed_ aci_evt_params_cmd_rsp_t;
+
+ACI_ASSERT_SIZE(aci_evt_params_cmd_rsp_t, 31);
+
+/**
+ * @struct aci_evt_params_connected_t
+ * @brief Structure for the ACI_EVT_CONNECTED event return parameters
+ */
+typedef struct
+{
+  aci_bd_addr_type_t dev_addr_type;
+  uint8_t  dev_addr[BTLE_DEVICE_ADDRESS_SIZE];
+  uint16_t conn_rf_interval;  /**< rf_interval = conn_rf_interval * 1.25 ms Range:0x0006 to 0x0C80 */
+  uint16_t conn_slave_rf_latency; /**< Number of RF events the slave can skip */
+  uint16_t conn_rf_timeout; /**< Timeout as a multiple of 10ms i.e timeout = conn_rf_timeout * 10ms Range: 0x000A to 0x0C80 */
+  aci_clock_accuracy_t master_clock_accuracy; /**< Clock accuracy of Bluetooth master: Enumerated list of values from 500 ppm to 20 ppm */
+} _aci_packed_ aci_evt_params_connected_t;
+
+ACI_ASSERT_SIZE(aci_evt_params_connected_t, 14);
+
+/**
+ * @struct aci_evt_params_disconnected_t
+ * @brief Structure for the ACI_EVT_DISCONNECTED event return parameters
+ */
+typedef struct
+{
+  aci_status_code_t   aci_status;
+  uint8_t btle_status;
+} _aci_packed_ aci_evt_params_disconnected_t;
+
+ACI_ASSERT_SIZE(aci_evt_params_disconnected_t, 2);
+
+/**
+ * @struct aci_evt_params_bond_status_t
+ * @brief Structure for the ACI_EVT_BOND_STATUS event return parameters
+ */
+typedef struct
+{
+  aci_bond_status_code_t status_code;
+  aci_bond_status_source_t status_source;
+  uint8_t secmode1_bitmap;
+  uint8_t secmode2_bitmap;
+  uint8_t keys_exchanged_slave;
+  uint8_t keys_exchanged_master;
+} _aci_packed_ aci_evt_params_bond_status_t;
+
+ACI_ASSERT_SIZE(aci_evt_params_bond_status_t, 6);
+
+/**
+ * @struct aci_evt_params_pipe_status_t
+ * @brief Structure for the ACI_EVT_PIPE_STATUS event return parameters
+ */
+typedef struct
+{
+  uint8_t  pipes_open_bitmap[8];
+  uint8_t  pipes_closed_bitmap[8];
+} _aci_packed_ aci_evt_params_pipe_status_t;
+
+ACI_ASSERT_SIZE(aci_evt_params_pipe_status_t, 16);
+
+/**
+ * @struct aci_evt_params_timing_t
+ * @brief Structure for the ACI_EVT_TIMING event return parameters
+ */
+typedef struct
+{
+  uint16_t conn_rf_interval;  /**< rf_interval = conn_rf_interval * 1.25 ms Range:0x0006 to 0x0C80 */
+  uint16_t conn_slave_rf_latency; /**< Number of RF events the slave can skip */
+  uint16_t conn_rf_timeout; /**< Timeout as a multiple of 10ms i.e timeout = conn_rf_timeout * 10ms Range: 0x000A to 0x0C80 */
+} _aci_packed_ aci_evt_params_timing_t;
+
+ACI_ASSERT_SIZE(aci_evt_params_timing_t, 6);
+
+/**
+ * @struct aci_evt_params_data_credit_t
+ * @brief Structure for the ACI_EVT_DATA_CREDIT event return parameters
+ */
+typedef struct
+{
+  uint8_t credit;
+} _aci_packed_ aci_evt_params_data_credit_t;
+
+/**
+ * @struct aci_evt_params_data_ack_t
+ * @brief Structure for the ACI_EVT_DATA_ACK event return parameters
+ */
+typedef struct
+{
+  uint8_t pipe_number;
+} _aci_packed_ aci_evt_params_data_ack_t;
+
+/**
+ * @struct aci_evt_params_data_received_t
+ * @brief Structure for the ACI_EVT_DATA_RECEIVED event return parameters
+ */
+typedef struct
+{
+  aci_rx_data_t rx_data;
+} _aci_packed_ aci_evt_params_data_received_t;
+
+typedef struct
+{
+  uint8_t content[1];
+} _aci_packed_ error_data_t;
+
+/**
+ * @struct aci_evt_params_pipe_error_t
+ * @brief Structure for the ACI_EVT_PIPE_ERROR event return parameters
+ */
+typedef struct
+{
+  uint8_t pipe_number;
+  uint8_t error_code;
+  union 
+  {
+    error_data_t  error_data;
+  } params;
+} _aci_packed_ aci_evt_params_pipe_error_t;
+
+/**
+ * @struct aci_evt_params_display_passkey_t
+ * @brief Structure for the ACI_EVT_DISPLAY_PASSKEY event return parameters
+ */
+typedef struct
+{
+  uint8_t passkey[6];
+} _aci_packed_ aci_evt_params_display_passkey_t;
+
+/**
+ * @struct aci_evt_params_key_request_t
+ * @brief Structure for the ACI_EVT_KEY_REQUEST event return parameters
+ */
+typedef struct
+{
+  aci_key_type_t key_type;
+} _aci_packed_ aci_evt_params_key_request_t;
+
+/**
+ * @struct aci_event_params_echo_t
+ * @brief  Structure for the ACI_EVT_ECHO ACI event parameters
+ */
+typedef struct
+{
+  uint8_t echo_data[ACI_ECHO_DATA_MAX_LEN];
+} _aci_packed_ aci_evt_params_echo_t;
+
+/**
+ * @struct aci_evt_t
+ * @brief  Encapsulates a generic ACI event
+ */
+typedef struct
+{
+  uint8_t len;
+  aci_evt_opcode_t evt_opcode;
+  union
+  {
+    aci_evt_params_device_started_t                     device_started;
+    aci_evt_params_echo_t                               echo;
+    aci_evt_params_hw_error_t                           hw_error;
+    aci_evt_params_cmd_rsp_t                            cmd_rsp;
+    aci_evt_params_connected_t                          connected;
+    aci_evt_params_disconnected_t                       disconnected;
+    aci_evt_params_bond_status_t                        bond_status;
+    aci_evt_params_pipe_status_t                        pipe_status;
+    aci_evt_params_timing_t                             timing;
+    aci_evt_params_data_credit_t                        data_credit;
+    aci_evt_params_data_ack_t                           data_ack;
+    aci_evt_params_data_received_t                      data_received;
+    aci_evt_params_pipe_error_t                         pipe_error;
+    aci_evt_params_display_passkey_t                    display_passkey;
+    aci_evt_params_key_request_t                        key_request;
+  } params;
+} _aci_packed_ aci_evt_t;
+
+ACI_ASSERT_SIZE(aci_evt_t, 33);
+
+#endif // ACI_EVTS_H__
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/ble_shield2.1/utility/aci_protocol_defines.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/ble_shield2.1/utility/aci_protocol_defines.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/ble_shield2.1/utility/aci_protocol_defines.h	(revision 457)
@@ -0,0 +1,188 @@
+/* Copyright (c) 2014, Nordic Semiconductor ASA
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+/*
+ * This file contents defines for the position of all the fields of ACI
+ * command or event messages
+ */
+
+#ifndef ACI_OFFSET_H__
+#define ACI_OFFSET_H__
+
+
+	#define OFFSET_ACI_LL_CONN_PARAMS_T_MIN_CONN_INTERVAL_LSB 0
+	#define OFFSET_ACI_LL_CONN_PARAMS_T_MIN_CONN_INTERVAL_MSB 1
+	#define OFFSET_ACI_LL_CONN_PARAMS_T_MAX_CONN_INTERVAL_LSB 2
+	#define OFFSET_ACI_LL_CONN_PARAMS_T_MAX_CONN_INTERVAL_MSB 3
+	#define OFFSET_ACI_LL_CONN_PARAMS_T_SLAVE_LATENCY_LSB 4
+	#define OFFSET_ACI_LL_CONN_PARAMS_T_SLAVE_LATENCY_MSB 5
+	#define OFFSET_ACI_LL_CONN_PARAMS_T_TIMEOUT_MULT_LSB 6
+	#define OFFSET_ACI_LL_CONN_PARAMS_T_TIMEOUT_MULT_MSB 7
+	#define OFFSET_ACI_TX_DATA_T_PIPE_NUMBER 0
+	#define OFFSET_ACI_TX_DATA_T_ACI_DATA 1
+	#define OFFSET_ACI_RX_DATA_T_PIPE_NUMBER 0
+	#define OFFSET_ACI_RX_DATA_T_ACI_DATA 1
+	#define OFFSET_ACI_CMD_PARAMS_TEST_T_TEST_MODE_CHANGE 0
+	#define OFFSET_ACI_CMD_PARAMS_ECHO_T_ECHO_DATA 0
+	#define OFFSET_ACI_CMD_PARAMS_DTM_CMD_T_CMD_MSB 0
+	#define OFFSET_ACI_CMD_PARAMS_DTM_CMD_T_CMD_LSB 1
+	#define OFFSET_ACI_CMD_PARAMS_SETUP_T_SETUP_DATA 0
+	#define OFFSET_ACI_CMD_PARAMS_WRITE_DYNAMIC_DATA_T_SEQ_NO 0
+	#define OFFSET_ACI_CMD_PARAMS_WRITE_DYNAMIC_DATA_T_DYNAMIC_DATA 1
+	#define OFFSET_ACI_CMD_PARAMS_SET_LOCAL_DATA_T_TX_DATA 0
+	#define OFFSET_ACI_CMD_PARAMS_CONNECT_T_TIMEOUT_LSB 0
+	#define OFFSET_ACI_CMD_PARAMS_CONNECT_T_TIMEOUT_MSB 1
+	#define OFFSET_ACI_CMD_PARAMS_CONNECT_T_ADV_INTERVAL_LSB 2
+	#define OFFSET_ACI_CMD_PARAMS_CONNECT_T_ADV_INTERVAL_MSB 3
+	#define OFFSET_ACI_CMD_PARAMS_BOND_T_TIMEOUT_LSB 0
+	#define OFFSET_ACI_CMD_PARAMS_BOND_T_TIMEOUT_MSB 1
+	#define OFFSET_ACI_CMD_PARAMS_BOND_T_ADV_INTERVAL_LSB 2
+	#define OFFSET_ACI_CMD_PARAMS_BOND_T_ADV_INTERVAL_MSB 3
+	#define OFFSET_ACI_CMD_PARAMS_DISCONNECT_T_REASON 0
+	#define OFFSET_ACI_CMD_PARAMS_SET_TX_POWER_T_DEVICE_POWER 0
+	#define OFFSET_ACI_CMD_PARAMS_CHANGE_TIMING_T_CONN_PARAMS 0
+	#define OFFSET_ACI_CMD_PARAMS_OPEN_REMOTE_PIPE_T_PIPE_NUMBER 0
+	#define OFFSET_ACI_CMD_PARAMS_SEND_DATA_T_TX_DATA 0
+	#define OFFSET_ACI_CMD_PARAMS_SEND_DATA_ACK_T_PIPE_NUMBER 0
+	#define OFFSET_ACI_CMD_PARAMS_REQUEST_DATA_T_PIPE_NUMBER 0
+	#define OFFSET_ACI_CMD_PARAMS_SEND_DATA_NACK_T_PIPE_NUMBER 0
+	#define OFFSET_ACI_CMD_PARAMS_SEND_DATA_NACK_T_ERROR_CODE 1
+	#define OFFSET_ACI_CMD_PARAMS_SET_APP_LATENCY_T_MODE 0
+	#define OFFSET_ACI_CMD_PARAMS_SET_APP_LATENCY_T_LATENCY_LSB 1
+	#define OFFSET_ACI_CMD_PARAMS_SET_APP_LATENCY_T_LATENCY_MSB 2
+	#define OFFSET_ACI_CMD_PARAMS_SET_KEY_T_KEY_TYPE 0
+	#define OFFSET_ACI_CMD_PARAMS_SET_KEY_T_PASSKEY 1
+	#define OFFSET_ACI_CMD_PARAMS_SET_KEY_T_OOB_KEY 1
+	#define OFFSET_ACI_CMD_PARAMS_OPEN_ADV_PIPE_T_PIPES 0
+	#define OFFSET_ACI_CMD_PARAMS_BROADCAST_T_TIMEOUT_LSB 0
+	#define OFFSET_ACI_CMD_PARAMS_BROADCAST_T_TIMEOUT_MSB 1
+	#define OFFSET_ACI_CMD_PARAMS_BROADCAST_T_ADV_INTERVAL_LSB 2
+	#define OFFSET_ACI_CMD_PARAMS_BROADCAST_T_ADV_INTERVAL_MSB 3
+	#define OFFSET_ACI_CMD_PARAMS_CLOSE_REMOTE_PIPE_T_PIPE_NUMBER 0
+	#define OFFSET_ACI_CMD_T_LEN 0
+	#define OFFSET_ACI_CMD_T_CMD_OPCODE 1
+	#define OFFSET_ACI_CMD_T_TEST 2
+	#define OFFSET_ACI_CMD_T_ECHO 2
+	#define OFFSET_ACI_CMD_T_DTM_CMD 2
+	#define OFFSET_ACI_CMD_T_SETUP 2
+	#define OFFSET_ACI_CMD_T_WRITE_DYNAMIC_DATA 2
+	#define OFFSET_ACI_CMD_T_SET_LOCAL_DATA 2
+	#define OFFSET_ACI_CMD_T_CONNECT 2
+	#define OFFSET_ACI_CMD_T_BOND 2
+	#define OFFSET_ACI_CMD_T_DISCONNECT 2
+	#define OFFSET_ACI_CMD_T_SET_TX_POWER 2
+	#define OFFSET_ACI_CMD_T_CHANGE_TIMING 2
+	#define OFFSET_ACI_CMD_T_OPEN_REMOTE_PIPE 2
+	#define OFFSET_ACI_CMD_T_SEND_DATA 2
+	#define OFFSET_ACI_CMD_T_SEND_DATA_ACK 2
+	#define OFFSET_ACI_CMD_T_REQUEST_DATA 2
+	#define OFFSET_ACI_CMD_T_SEND_DATA_NACK 2
+	#define OFFSET_ACI_CMD_T_SET_APP_LATENCY 2
+	#define OFFSET_ACI_CMD_T_SET_KEY 2
+	#define OFFSET_ACI_CMD_T_OPEN_ADV_PIPE 2
+	#define OFFSET_ACI_CMD_T_BROADCAST 2
+	#define OFFSET_ACI_CMD_T_CLOSE_REMOTE_PIPE 2
+	#define OFFSET_ACI_EVT_PARAMS_DEVICE_STARTED_T_DEVICE_MODE 0
+	#define OFFSET_ACI_EVT_PARAMS_DEVICE_STARTED_T_HW_ERROR 1
+	#define OFFSET_ACI_EVT_PARAMS_DEVICE_STARTED_T_CREDIT_AVAILABLE 2
+	#define OFFSET_ACI_EVT_PARAMS_HW_ERROR_T_LINE_NUM_LSB 0
+	#define OFFSET_ACI_EVT_PARAMS_HW_ERROR_T_LINE_NUM_MSB 1
+	#define OFFSET_ACI_EVT_PARAMS_HW_ERROR_T_FILE_NAME 2
+	#define OFFSET_ACI_EVT_CMD_RSP_PARAMS_DTM_CMD_T_EVT_MSB 0
+	#define OFFSET_ACI_EVT_CMD_RSP_PARAMS_DTM_CMD_T_EVT_LSB 1
+	#define OFFSET_ACI_EVT_CMD_RSP_READ_DYNAMIC_DATA_T_SEQ_NO 0
+	#define OFFSET_ACI_EVT_CMD_RSP_READ_DYNAMIC_DATA_T_DYNAMIC_DATA 1
+	#define OFFSET_ACI_EVT_CMD_RSP_PARAMS_GET_DEVICE_VERSION_T_CONFIGURATION_ID_LSB 0
+	#define OFFSET_ACI_EVT_CMD_RSP_PARAMS_GET_DEVICE_VERSION_T_CONFIGURATION_ID_MSB 1
+	#define OFFSET_ACI_EVT_CMD_RSP_PARAMS_GET_DEVICE_VERSION_T_ACI_VERSION 2
+	#define OFFSET_ACI_EVT_CMD_RSP_PARAMS_GET_DEVICE_VERSION_T_SETUP_FORMAT 3
+	#define OFFSET_ACI_EVT_CMD_RSP_PARAMS_GET_DEVICE_VERSION_T_SETUP_ID_LSB0 4
+	#define OFFSET_ACI_EVT_CMD_RSP_PARAMS_GET_DEVICE_VERSION_T_SETUP_ID_LSB1 5
+	#define OFFSET_ACI_EVT_CMD_RSP_PARAMS_GET_DEVICE_VERSION_T_SETUP_ID_MSB0 6
+	#define OFFSET_ACI_EVT_CMD_RSP_PARAMS_GET_DEVICE_VERSION_T_SETUP_ID_MSB1 7
+	#define OFFSET_ACI_EVT_CMD_RSP_PARAMS_GET_DEVICE_VERSION_T_SETUP_STATUS 8
+	#define OFFSET_ACI_EVT_CMD_RSP_PARAMS_GET_DEVICE_ADDRESS_T_BD_ADDR_OWN 0
+	#define OFFSET_ACI_EVT_CMD_RSP_PARAMS_GET_DEVICE_ADDRESS_T_BD_ADDR_TYPE 6
+	#define OFFSET_ACI_EVT_CMD_RSP_PARAMS_GET_BATTERY_LEVEL_T_BATTERY_LEVEL_LSB 0
+	#define OFFSET_ACI_EVT_CMD_RSP_PARAMS_GET_BATTERY_LEVEL_T_BATTERY_LEVEL_MSB 1
+	#define OFFSET_ACI_EVT_CMD_RSP_PARAMS_GET_TEMPERATURE_T_TEMPERATURE_VALUE_LSB 0
+	#define OFFSET_ACI_EVT_CMD_RSP_PARAMS_GET_TEMPERATURE_T_TEMPERATURE_VALUE_MSB 1
+	#define OFFSET_ACI_EVT_PARAMS_CMD_RSP_T_CMD_OPCODE 0
+	#define OFFSET_ACI_EVT_PARAMS_CMD_RSP_T_CMD_STATUS 1
+	#define OFFSET_ACI_EVT_PARAMS_CMD_RSP_T_DTM_CMD 2
+	#define OFFSET_ACI_EVT_PARAMS_CMD_RSP_T_READ_DYNAMIC_DATA 2
+	#define OFFSET_ACI_EVT_PARAMS_CMD_RSP_T_GET_DEVICE_VERSION 2
+	#define OFFSET_ACI_EVT_PARAMS_CMD_RSP_T_GET_DEVICE_ADDRESS 2
+	#define OFFSET_ACI_EVT_PARAMS_CMD_RSP_T_GET_BATTERY_LEVEL 2
+	#define OFFSET_ACI_EVT_PARAMS_CMD_RSP_T_GET_TEMPERATURE 2
+	#define OFFSET_ACI_EVT_PARAMS_CONNECTED_T_DEV_ADDR_TYPE 0
+	#define OFFSET_ACI_EVT_PARAMS_CONNECTED_T_DEV_ADDR 1
+	#define OFFSET_ACI_EVT_PARAMS_CONNECTED_T_CONN_RF_INTERVAL_LSB 7
+	#define OFFSET_ACI_EVT_PARAMS_CONNECTED_T_CONN_RF_INTERVAL_MSB 8
+	#define OFFSET_ACI_EVT_PARAMS_CONNECTED_T_CONN_SLAVE_RF_LATENCY_LSB 9
+	#define OFFSET_ACI_EVT_PARAMS_CONNECTED_T_CONN_SLAVE_RF_LATENCY_MSB 10
+	#define OFFSET_ACI_EVT_PARAMS_CONNECTED_T_CONN_RF_TIMEOUT_LSB 11
+	#define OFFSET_ACI_EVT_PARAMS_CONNECTED_T_CONN_RF_TIMEOUT_MSB 12
+	#define OFFSET_ACI_EVT_PARAMS_CONNECTED_T_MASTER_CLOCK_ACCURACY 13
+	#define OFFSET_ACI_EVT_PARAMS_DISCONNECTED_T_ACI_STATUS 0
+	#define OFFSET_ACI_EVT_PARAMS_DISCONNECTED_T_BTLE_STATUS 1
+	#define OFFSET_ACI_EVT_PARAMS_BOND_STATUS_T_STATUS_CODE 0
+	#define OFFSET_ACI_EVT_PARAMS_BOND_STATUS_T_STATUS_SOURCE 1
+	#define OFFSET_ACI_EVT_PARAMS_BOND_STATUS_T_SECMODE1_BITMAP 2
+	#define OFFSET_ACI_EVT_PARAMS_BOND_STATUS_T_SECMODE2_BITMAP 3
+	#define OFFSET_ACI_EVT_PARAMS_BOND_STATUS_T_KEYS_EXCHANGED_SLAVE 4
+	#define OFFSET_ACI_EVT_PARAMS_BOND_STATUS_T_KEYS_EXCHANGED_MASTER 5
+	#define OFFSET_ACI_EVT_PARAMS_PIPE_STATUS_T_PIPES_OPEN_BITMAP 0
+	#define OFFSET_ACI_EVT_PARAMS_PIPE_STATUS_T_PIPES_CLOSED_BITMAP 8
+	#define OFFSET_ACI_EVT_PARAMS_TIMING_T_CONN_RF_INTERVAL_LSB 0
+	#define OFFSET_ACI_EVT_PARAMS_TIMING_T_CONN_RF_INTERVAL_MSB 1
+	#define OFFSET_ACI_EVT_PARAMS_TIMING_T_CONN_SLAVE_RF_LATENCY_LSB 2
+	#define OFFSET_ACI_EVT_PARAMS_TIMING_T_CONN_SLAVE_RF_LATENCY_MSB 3
+	#define OFFSET_ACI_EVT_PARAMS_TIMING_T_CONN_RF_TIMEOUT_LSB 4
+	#define OFFSET_ACI_EVT_PARAMS_TIMING_T_CONN_RF_TIMEOUT_MSB 5
+	#define OFFSET_ACI_EVT_PARAMS_DATA_CREDIT_T_CREDIT 0
+	#define OFFSET_ACI_EVT_PARAMS_DATA_ACK_T_PIPE_NUMBER 0
+	#define OFFSET_ACI_EVT_PARAMS_DATA_RECEIVED_T_RX_DATA 0
+	#define OFFSET_ERROR_DATA_T_CONTENT 0
+	#define OFFSET_ACI_EVT_PARAMS_PIPE_ERROR_T_PIPE_NUMBER 0
+	#define OFFSET_ACI_EVT_PARAMS_PIPE_ERROR_T_ERROR_CODE 1
+	#define OFFSET_ACI_EVT_PARAMS_PIPE_ERROR_T_ERROR_DATA 2
+	#define OFFSET_ACI_EVT_PARAMS_DISPLAY_PASSKEY_T_PASSKEY 0
+	#define OFFSET_ACI_EVT_PARAMS_KEY_REQUEST_T_KEY_TYPE 0
+	#define OFFSET_ACI_EVT_T_LEN 0
+	#define OFFSET_ACI_EVT_T_EVT_OPCODE 1
+	#define OFFSET_ACI_EVT_T_DEVICE_STARTED 2
+	#define OFFSET_ACI_EVT_T_HW_ERROR 2
+	#define OFFSET_ACI_EVT_T_CMD_RSP 2
+	#define OFFSET_ACI_EVT_T_CONNECTED 2
+	#define OFFSET_ACI_EVT_T_DISCONNECTED 2
+	#define OFFSET_ACI_EVT_T_BOND_STATUS 2
+	#define OFFSET_ACI_EVT_T_PIPE_STATUS 2
+	#define OFFSET_ACI_EVT_T_TIMING 2
+	#define OFFSET_ACI_EVT_T_DATA_CREDIT 2
+	#define OFFSET_ACI_EVT_T_DATA_ACK 2
+	#define OFFSET_ACI_EVT_T_DATA_RECEIVED 2
+	#define OFFSET_ACI_EVT_T_PIPE_ERROR 2
+	#define OFFSET_ACI_EVT_T_DISPLAY_PASSKEY 2
+	#define OFFSET_ACI_EVT_T_KEY_REQUEST 2
+
+#endif //ACI_OFFSET_H__
+
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/ble_shield2.1/utility/aci_queue.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/ble_shield2.1/utility/aci_queue.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/ble_shield2.1/utility/aci_queue.c	(revision 457)
@@ -0,0 +1,141 @@
+/* Copyright (c) 2014, Nordic Semiconductor ASA
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+ /** @file
+@brief Implementation of a circular queue for ACI data
+*/
+
+#include "hal_aci_tl.h"
+#include "aci_queue.h"
+#include "ble_assert.h"
+
+void aci_queue_init(aci_queue_t *aci_q)
+{
+  uint8_t loop;
+
+  ble_assert(NULL != aci_q);
+
+  aci_q->head = 0;
+  aci_q->tail = 0;
+  for(loop=0; loop<ACI_QUEUE_SIZE; loop++)
+  {
+    aci_q->aci_data[loop].buffer[0] = 0x00;
+    aci_q->aci_data[loop].buffer[1] = 0x00;
+  }
+}
+
+bool aci_queue_dequeue(aci_queue_t *aci_q, hal_aci_data_t *p_data)
+{
+  ble_assert(NULL != aci_q);
+  ble_assert(NULL != p_data);
+
+  if (aci_queue_is_empty(aci_q))
+  {
+    return false;
+  }
+
+  noInterrupts();
+  memcpy((uint8_t *)p_data, (uint8_t *)&(aci_q->aci_data[aci_q->head]), sizeof(hal_aci_data_t));
+  aci_q->head = (aci_q->head + 1) % ACI_QUEUE_SIZE;
+  interrupts();
+
+  return true;
+}
+
+bool aci_queue_enqueue(aci_queue_t *aci_q, hal_aci_data_t *p_data)
+{
+  const uint8_t length = p_data->buffer[0];
+
+  ble_assert(NULL != aci_q);
+  ble_assert(NULL != p_data);
+
+  if (aci_queue_is_full(aci_q))
+  {
+    return false;
+  }
+
+  noInterrupts();
+  aci_q->aci_data[aci_q->tail].status_byte = 0;
+  memcpy((uint8_t *)&(aci_q->aci_data[aci_q->tail].buffer[0]), (uint8_t *)&p_data->buffer[0], length + 1);
+  aci_q->tail = (aci_q->tail + 1) % ACI_QUEUE_SIZE;
+  interrupts();
+
+  return true;
+}
+
+bool aci_queue_is_empty(aci_queue_t *aci_q)
+{
+  bool state = false;
+
+  ble_assert(NULL != aci_q);
+
+  //Critical section
+  noInterrupts();
+  if (aci_q->head == aci_q->tail)
+  {
+    state = true;
+  }
+  interrupts();
+
+  return state;
+}
+
+bool aci_queue_is_full(aci_queue_t *aci_q)
+{
+  uint8_t next;
+  bool state;
+
+  ble_assert(NULL != aci_q);
+
+  //This should be done in a critical section
+  noInterrupts();
+  next = (aci_q->tail + 1) % ACI_QUEUE_SIZE;
+
+  if (next == aci_q->head)
+  {
+    state = true;
+  }
+  else
+  {
+    state = false;
+  }
+
+  interrupts();
+  //end
+
+  return state;
+}
+
+bool aci_queue_peek(aci_queue_t *aci_q, hal_aci_data_t *p_data)
+{
+  ble_assert(NULL != aci_q);
+  ble_assert(NULL != p_data);
+
+  if (aci_queue_is_empty(aci_q))
+  {
+    return false;
+  }
+
+  memcpy((uint8_t *)p_data, (uint8_t *)&(aci_q->aci_data[aci_q->head]), sizeof(hal_aci_data_t));
+
+  return true;
+}
+
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/ble_shield2.1/utility/aci_queue.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/ble_shield2.1/utility/aci_queue.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/ble_shield2.1/utility/aci_queue.h	(revision 457)
@@ -0,0 +1,76 @@
+/* Copyright (c) 2014, Nordic Semiconductor ASA
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+/** @file
+ * @brief Interface for buffer.
+ */
+
+/** @defgroup aci_queue aci_queue
+@{
+@ingroup aci_queue
+
+*/
+
+#ifndef ACI_QUEUE_H__
+#define ACI_QUEUE_H__
+
+#include "aci.h"
+#include "hal_aci_tl.h"
+
+/***********************************************************************    */
+/* The ACI_QUEUE_SIZE determines the memory usage of the system.            */
+/* Successfully tested to a ACI_QUEUE_SIZE of 4 (interrupt) and 4 (polling) */
+/***********************************************************************    */
+#define ACI_QUEUE_SIZE  4
+
+/** Data type for queue of data packets to send/receive from radio.
+ *
+ *  A FIFO queue is maintained for packets. New packets are added (enqueued)
+ *  at the tail and taken (dequeued) from the head. The head variable is the
+ *  index of the next packet to dequeue while the tail variable is the index of
+ *  where the next packet should be queued.
+ */
+
+typedef struct {
+	hal_aci_data_t           aci_data[ACI_QUEUE_SIZE];
+	uint8_t                  head;
+	uint8_t                  tail;
+} aci_queue_t;
+
+void aci_queue_init(aci_queue_t *aci_q);
+
+bool aci_queue_dequeue(aci_queue_t *aci_q, hal_aci_data_t *p_data);
+bool aci_queue_dequeue_from_isr(aci_queue_t *aci_q, hal_aci_data_t *p_data);
+
+bool aci_queue_enqueue(aci_queue_t *aci_q, hal_aci_data_t *p_data);
+bool aci_queue_enqueue_from_isr(aci_queue_t *aci_q, hal_aci_data_t *p_data);
+
+bool aci_queue_is_empty(aci_queue_t *aci_q);
+bool aci_queue_is_empty_from_isr(aci_queue_t *aci_q);
+
+bool aci_queue_is_full(aci_queue_t *aci_q);
+bool aci_queue_is_full_from_isr(aci_queue_t *aci_q);
+
+bool aci_queue_peek(aci_queue_t *aci_q, hal_aci_data_t *p_data);
+bool aci_queue_peek_from_isr(aci_queue_t *aci_q, hal_aci_data_t *p_data);
+
+#endif /* ACI_QUEUE_H__ */
+/** @} */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/ble_shield2.1/utility/aci_setup.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/ble_shield2.1/utility/aci_setup.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/ble_shield2.1/utility/aci_setup.c	(revision 457)
@@ -0,0 +1,171 @@
+/* Copyright (c) 2014, Nordic Semiconductor ASA
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#include <lib_aci.h>
+#include "aci_setup.h"
+
+
+// aci_struct that will contain 
+// total initial credits
+// current credit
+// current state of the aci (setup/standby/active/sleep)
+// open remote pipe pending
+// close remote pipe pending
+// Current pipe available bitmap
+// Current pipe closed bitmap
+// Current connection interval, slave latency and link supervision timeout
+// Current State of the the GATT client (Service Discovery status)
+
+
+extern hal_aci_data_t msg_to_send;
+
+
+
+/**************************************************************************                */
+/* Utility function to fill the the ACI command queue                                      */
+/* aci_stat               Pointer to the ACI state                                         */
+/* num_cmd_offset(in/out) Offset in the Setup message array to start from                  */
+/*                        offset is updated to the new index after the queue is filled     */
+/*                        or the last message us placed in the queue                       */
+/* Returns                true if at least one message was transferred                     */
+/***************************************************************************/
+static bool aci_setup_fill(aci_state_t *aci_stat, uint8_t *num_cmd_offset)
+{
+  bool ret_val = false;
+  
+  while (*num_cmd_offset < aci_stat->aci_setup_info.num_setup_msgs)
+  {
+	//Board dependent defines
+	#if defined (__AVR__)
+		//For Arduino copy the setup ACI message from Flash to RAM.
+		memcpy_P(&msg_to_send, &(aci_stat->aci_setup_info.setup_msgs[*num_cmd_offset]), 
+				  pgm_read_byte_near(&(aci_stat->aci_setup_info.setup_msgs[*num_cmd_offset].buffer[0]))+2); 
+	#elif defined(__PIC32MX__) || defined(__STM32__)
+		//In ChipKit we store the setup messages in RAM
+		//Add 2 bytes to the length byte for status byte, length for the total number of bytes
+		memcpy(&msg_to_send, &(aci_stat->aci_setup_info.setup_msgs[*num_cmd_offset]), 
+				  (aci_stat->aci_setup_info.setup_msgs[*num_cmd_offset].buffer[0]+2)); 
+	#endif
+
+    //Put the Setup ACI message in the command queue
+    if (!hal_aci_tl_send(&msg_to_send))
+    {
+      //ACI Command Queue is full
+      // *num_cmd_offset is now pointing to the index of the Setup command that did not get sent
+      return ret_val;
+    }
+   
+    ret_val = true;
+    
+    (*num_cmd_offset)++;
+  }
+  
+  return ret_val;
+}
+
+uint8_t do_aci_setup(aci_state_t *aci_stat)
+{
+  uint8_t setup_offset         = 0;
+  uint32_t i                   = 0x0000;
+  aci_evt_t * aci_evt          = NULL;
+  aci_status_code_t cmd_status = ACI_STATUS_ERROR_CRC_MISMATCH;
+  
+  /*
+  We are using the same buffer since we are copying the contents of the buffer 
+  when queuing and immediately processing the buffer when receiving
+  */
+  hal_aci_evt_t  *aci_data = (hal_aci_evt_t *)&msg_to_send;
+  
+  /* Messages in the outgoing queue must be handled before the Setup routine can run.
+   * If it is non-empty we return. The user should then process the messages before calling
+   * do_aci_setup() again.
+   */
+  if (!lib_aci_command_queue_empty())
+  {
+    return SETUP_FAIL_COMMAND_QUEUE_NOT_EMPTY;
+  }
+  
+  /* If there are events pending from the device that are not relevant to setup, we return false
+   * so that the user can handle them. At this point we don't care what the event is,
+   * as any event is an error.
+   */
+  if (lib_aci_event_peek(aci_data))
+  {
+    return SETUP_FAIL_EVENT_QUEUE_NOT_EMPTY;
+  }
+  
+  /* Fill the ACI command queue with as many Setup messages as it will hold. */
+  aci_setup_fill(aci_stat, &setup_offset);
+  
+  while (cmd_status != ACI_STATUS_TRANSACTION_COMPLETE)
+  {
+    /* This counter is used to ensure that this function does not loop forever. When the device
+     * returns a valid response, we reset the counter.
+     */
+    if (i++ > 0xFFFFE)
+    {
+      return SETUP_FAIL_TIMEOUT;	
+    }
+    
+    if (lib_aci_event_peek(aci_data))
+    {
+      aci_evt = &(aci_data->evt);
+      
+      if (ACI_EVT_CMD_RSP != aci_evt->evt_opcode)
+      {
+        //Receiving something other than a Command Response Event is an error.
+        return SETUP_FAIL_NOT_COMMAND_RESPONSE;
+      }
+      
+      cmd_status = (aci_status_code_t) aci_evt->params.cmd_rsp.cmd_status;
+      switch (cmd_status)
+      {
+        case ACI_STATUS_TRANSACTION_CONTINUE:
+          //As the device is responding, reset guard counter
+          i = 0;
+          
+          /* As the device has processed the Setup messages we put in the command queue earlier,
+           * we can proceed to fill the queue with new messages
+           */
+          aci_setup_fill(aci_stat, &setup_offset);
+          break;
+        
+        case ACI_STATUS_TRANSACTION_COMPLETE:
+          //Break out of the while loop when this status code appears
+          break;
+        
+        default:
+          //An event with any other status code should be handled by the application
+          return SETUP_FAIL_NOT_SETUP_EVENT;
+      }
+      
+      /* If we haven't returned at this point, the event was either ACI_STATUS_TRANSACTION_CONTINUE
+       * or ACI_STATUS_TRANSACTION_COMPLETE. We don't need the event itself, so we simply
+       * remove it from the queue.
+       */
+       lib_aci_event_get (aci_stat, aci_data);
+    }
+  }
+  
+  return SETUP_SUCCESS;
+}
+  
+
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/ble_shield2.1/utility/aci_setup.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/ble_shield2.1/utility/aci_setup.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/ble_shield2.1/utility/aci_setup.h	(revision 457)
@@ -0,0 +1,44 @@
+/* Copyright (c) 2014, Nordic Semiconductor ASA
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+ 
+ 
+#ifndef H_ACI_SETUP
+#define H_ACI_SETUP
+
+#define SETUP_SUCCESS                        0
+#define SETUP_FAIL_COMMAND_QUEUE_NOT_EMPTY   1
+#define SETUP_FAIL_EVENT_QUEUE_NOT_EMPTY     2
+#define SETUP_FAIL_TIMEOUT                   3
+#define SETUP_FAIL_NOT_SETUP_EVENT           4
+#define SETUP_FAIL_NOT_COMMAND_RESPONSE      5
+
+/** @brief Setup the nRF8001 device
+ *  @details
+ *  Performs ACI Setup by transmitting the setup messages generated by nRFgo Studio to the
+ *  nRF8001, and should be called when the nRF8001 starts or resets.
+ *  Once all messages are sent, the nRF8001 will send a Device Started Event.
+ *  The function requires that the Command queue is empty when it is invoked, and will fail
+ *  otherwise.
+ *  @returns An integer indicating the reason the function terminated
+ */
+uint8_t do_aci_setup(aci_state_t *aci_stat);
+
+#endif
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/ble_shield2.1/utility/acilib.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/ble_shield2.1/utility/acilib.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/ble_shield2.1/utility/acilib.c	(revision 457)
@@ -0,0 +1,612 @@
+/* Copyright (c) 2014, Nordic Semiconductor ASA
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+/**
+ * @file
+ *
+ * @ingroup group_acilib
+ *
+ * @brief Implementation of the acilib module.
+ */
+
+
+#include "hal_platform.h"
+#include "aci.h"
+#include "aci_cmds.h"
+#include "aci_evts.h"
+#include "acilib.h"
+#include "aci_protocol_defines.h"
+#include "acilib_defs.h"
+#include "acilib_if.h"
+#include "acilib_types.h"
+
+
+void acil_encode_cmd_set_test_mode(uint8_t *buffer, aci_cmd_params_test_t *p_aci_cmd_params_test)
+{
+  *(buffer + OFFSET_ACI_CMD_T_LEN) = 2;
+  *(buffer + OFFSET_ACI_CMD_T_CMD_OPCODE) = ACI_CMD_TEST;
+  *(buffer + OFFSET_ACI_CMD_T_TEST + OFFSET_ACI_CMD_PARAMS_TEST_T_TEST_MODE_CHANGE) = p_aci_cmd_params_test->test_mode_change;
+}
+
+void acil_encode_cmd_sleep(uint8_t *buffer)
+{
+  *(buffer + OFFSET_ACI_CMD_T_LEN) = 1;
+  *(buffer + OFFSET_ACI_CMD_T_CMD_OPCODE) = ACI_CMD_SLEEP;
+}
+
+void acil_encode_cmd_get_device_version(uint8_t *buffer)
+{
+  *(buffer + OFFSET_ACI_CMD_T_LEN) = 1;
+  *(buffer + OFFSET_ACI_CMD_T_CMD_OPCODE) = ACI_CMD_GET_DEVICE_VERSION;
+}
+
+void acil_encode_cmd_set_local_data(uint8_t *buffer, aci_cmd_params_set_local_data_t *p_aci_cmd_params_set_local_data, uint8_t data_size)
+{
+  *(buffer + OFFSET_ACI_CMD_T_LEN) = MSG_SET_LOCAL_DATA_BASE_LEN + data_size;
+  *(buffer + OFFSET_ACI_CMD_T_CMD_OPCODE) = ACI_CMD_SET_LOCAL_DATA;
+  *(buffer + OFFSET_ACI_CMD_T_SET_LOCAL_DATA + OFFSET_ACI_CMD_PARAMS_SEND_DATA_T_TX_DATA + OFFSET_ACI_TX_DATA_T_PIPE_NUMBER) = p_aci_cmd_params_set_local_data->tx_data.pipe_number;
+  memcpy(buffer + OFFSET_ACI_CMD_T_SET_LOCAL_DATA + OFFSET_ACI_CMD_PARAMS_SEND_DATA_T_TX_DATA + OFFSET_ACI_TX_DATA_T_ACI_DATA,  &(p_aci_cmd_params_set_local_data->tx_data.aci_data[0]), data_size);
+}
+
+void acil_encode_cmd_connect(uint8_t *buffer, aci_cmd_params_connect_t *p_aci_cmd_params_connect)
+{
+  *(buffer + OFFSET_ACI_CMD_T_LEN) = MSG_CONNECT_LEN;
+  *(buffer + OFFSET_ACI_CMD_T_CMD_OPCODE) = ACI_CMD_CONNECT;
+  *(buffer + OFFSET_ACI_CMD_T_CONNECT + OFFSET_ACI_CMD_PARAMS_CONNECT_T_TIMEOUT_MSB) = (uint8_t)(p_aci_cmd_params_connect->timeout >> 8);
+  *(buffer + OFFSET_ACI_CMD_T_CONNECT + OFFSET_ACI_CMD_PARAMS_CONNECT_T_TIMEOUT_LSB) = (uint8_t)(p_aci_cmd_params_connect->timeout);
+  *(buffer + OFFSET_ACI_CMD_T_CONNECT + OFFSET_ACI_CMD_PARAMS_CONNECT_T_ADV_INTERVAL_MSB) = (uint8_t)(p_aci_cmd_params_connect->adv_interval >> 8);
+  *(buffer + OFFSET_ACI_CMD_T_CONNECT + OFFSET_ACI_CMD_PARAMS_CONNECT_T_ADV_INTERVAL_LSB) = (uint8_t)(p_aci_cmd_params_connect->adv_interval);
+}
+
+void acil_encode_cmd_bond(uint8_t *buffer, aci_cmd_params_bond_t *p_aci_cmd_params_bond)
+{
+  *(buffer + OFFSET_ACI_CMD_T_LEN) = MSG_BOND_LEN;
+  *(buffer + OFFSET_ACI_CMD_T_CMD_OPCODE) = ACI_CMD_BOND;
+  *(buffer + OFFSET_ACI_CMD_T_BOND + OFFSET_ACI_CMD_PARAMS_BOND_T_TIMEOUT_MSB) = (uint8_t)(p_aci_cmd_params_bond->timeout >> 8);
+  *(buffer + OFFSET_ACI_CMD_T_BOND + OFFSET_ACI_CMD_PARAMS_BOND_T_TIMEOUT_LSB) = (uint8_t)(p_aci_cmd_params_bond->timeout);
+  *(buffer + OFFSET_ACI_CMD_T_BOND + OFFSET_ACI_CMD_PARAMS_BOND_T_ADV_INTERVAL_MSB) = (uint8_t)(p_aci_cmd_params_bond->adv_interval >> 8);
+  *(buffer + OFFSET_ACI_CMD_T_BOND + OFFSET_ACI_CMD_PARAMS_BOND_T_ADV_INTERVAL_LSB) = (uint8_t)(p_aci_cmd_params_bond->adv_interval);
+}
+
+void acil_encode_cmd_disconnect(uint8_t *buffer, aci_cmd_params_disconnect_t *p_aci_cmd_params_disconnect)
+{
+  *(buffer + OFFSET_ACI_CMD_T_LEN) = MSG_DISCONNECT_LEN;
+  *(buffer + OFFSET_ACI_CMD_T_CMD_OPCODE) = ACI_CMD_DISCONNECT;
+  *(buffer + OFFSET_ACI_CMD_T_DISCONNECT + OFFSET_ACI_CMD_PARAMS_DISCONNECT_T_REASON) = (uint8_t)(p_aci_cmd_params_disconnect->reason);
+}
+
+void acil_encode_baseband_reset(uint8_t *buffer)
+{
+  *(buffer + OFFSET_ACI_CMD_T_LEN) = MSG_BASEBAND_RESET_LEN;
+  *(buffer + OFFSET_ACI_CMD_T_CMD_OPCODE) = ACI_CMD_RADIO_RESET;
+}
+
+void acil_encode_direct_connect(uint8_t *buffer)
+{
+  *(buffer + OFFSET_ACI_CMD_T_LEN) = MSG_DIRECT_CONNECT_LEN;
+  *(buffer + OFFSET_ACI_CMD_T_CMD_OPCODE) = ACI_CMD_CONNECT_DIRECT;
+}
+
+void acil_encode_cmd_wakeup(uint8_t *buffer)
+{
+  *(buffer + OFFSET_ACI_CMD_T_LEN) = MSG_WAKEUP_LEN;
+  *(buffer + OFFSET_ACI_CMD_T_CMD_OPCODE) = ACI_CMD_WAKEUP;
+}
+
+void acil_encode_cmd_set_radio_tx_power(uint8_t *buffer, aci_cmd_params_set_tx_power_t *p_aci_cmd_params_set_tx_power)
+{
+  *(buffer + OFFSET_ACI_CMD_T_LEN) = MSG_SET_RADIO_TX_POWER_LEN;
+  *(buffer + OFFSET_ACI_CMD_T_CMD_OPCODE) = ACI_CMD_SET_TX_POWER;
+  *(buffer + OFFSET_ACI_CMD_T_SET_TX_POWER + OFFSET_ACI_CMD_PARAMS_SET_TX_POWER_T_DEVICE_POWER) = (uint8_t)p_aci_cmd_params_set_tx_power->device_power;
+}
+
+void acil_encode_cmd_get_address(uint8_t *buffer)
+{
+  *(buffer + OFFSET_ACI_CMD_T_LEN) = MSG_GET_DEVICE_ADDR_LEN;
+  *(buffer + OFFSET_ACI_CMD_T_CMD_OPCODE) = ACI_CMD_GET_DEVICE_ADDRESS;
+}
+
+void acil_encode_cmd_send_data(uint8_t *buffer, aci_cmd_params_send_data_t *p_aci_cmd_params_send_data_t, uint8_t data_size)
+{
+  *(buffer + OFFSET_ACI_CMD_T_LEN) = MSG_SEND_DATA_BASE_LEN + data_size;
+  *(buffer + OFFSET_ACI_CMD_T_CMD_OPCODE) = ACI_CMD_SEND_DATA;
+  *(buffer + OFFSET_ACI_CMD_T_SEND_DATA + OFFSET_ACI_CMD_PARAMS_SEND_DATA_T_TX_DATA + OFFSET_ACI_TX_DATA_T_PIPE_NUMBER) = p_aci_cmd_params_send_data_t->tx_data.pipe_number;
+  memcpy((buffer + OFFSET_ACI_CMD_T_SEND_DATA + OFFSET_ACI_CMD_PARAMS_SEND_DATA_T_TX_DATA + OFFSET_ACI_TX_DATA_T_ACI_DATA), &(p_aci_cmd_params_send_data_t->tx_data.aci_data[0]), data_size);
+}
+
+void acil_encode_cmd_request_data(uint8_t *buffer, aci_cmd_params_request_data_t *p_aci_cmd_params_request_data)
+{
+  *(buffer + OFFSET_ACI_CMD_T_LEN) = MSG_DATA_REQUEST_LEN;
+  *(buffer + OFFSET_ACI_CMD_T_CMD_OPCODE) = ACI_CMD_REQUEST_DATA;
+  *(buffer + OFFSET_ACI_CMD_T_REQUEST_DATA + OFFSET_ACI_CMD_PARAMS_REQUEST_DATA_T_PIPE_NUMBER) = p_aci_cmd_params_request_data->pipe_number;
+}
+
+void acil_encode_cmd_open_remote_pipe(uint8_t *buffer, aci_cmd_params_open_remote_pipe_t *p_aci_cmd_params_open_remote_pipe)
+{
+  *(buffer + OFFSET_ACI_CMD_T_LEN) = MSG_OPEN_REMOTE_PIPE_LEN;
+  *(buffer + OFFSET_ACI_CMD_T_CMD_OPCODE) = ACI_CMD_OPEN_REMOTE_PIPE;
+  *(buffer + OFFSET_ACI_CMD_T_OPEN_REMOTE_PIPE + OFFSET_ACI_CMD_PARAMS_OPEN_REMOTE_PIPE_T_PIPE_NUMBER) = p_aci_cmd_params_open_remote_pipe->pipe_number;
+}
+
+void acil_encode_cmd_close_remote_pipe(uint8_t *buffer, aci_cmd_params_close_remote_pipe_t *p_aci_cmd_params_close_remote_pipe)
+{
+  *(buffer + OFFSET_ACI_CMD_T_LEN) = MSG_CLOSE_REMOTE_PIPE_LEN;
+  *(buffer + OFFSET_ACI_CMD_T_CMD_OPCODE) = ACI_CMD_CLOSE_REMOTE_PIPE;
+  *(buffer + OFFSET_ACI_CMD_T_CLOSE_REMOTE_PIPE + OFFSET_ACI_CMD_PARAMS_CLOSE_REMOTE_PIPE_T_PIPE_NUMBER) = p_aci_cmd_params_close_remote_pipe->pipe_number;
+}
+
+void acil_encode_cmd_echo_msg(uint8_t *buffer, aci_cmd_params_echo_t *p_cmd_params_echo, uint8_t msg_size)
+{
+  *(buffer + OFFSET_ACI_CMD_T_LEN) = MSG_ECHO_MSG_CMD_BASE_LEN + msg_size;
+  *(buffer + OFFSET_ACI_CMD_T_CMD_OPCODE) = ACI_CMD_ECHO;
+  memcpy((buffer + OFFSET_ACI_CMD_T_ECHO + OFFSET_ACI_CMD_PARAMS_ECHO_T_ECHO_DATA), &(p_cmd_params_echo->echo_data[0]), msg_size);
+}
+
+void acil_encode_cmd_battery_level(uint8_t *buffer)
+{
+  *(buffer + OFFSET_ACI_CMD_T_LEN) = 1;
+  *(buffer + OFFSET_ACI_CMD_T_CMD_OPCODE) = ACI_CMD_GET_BATTERY_LEVEL;
+}
+
+void acil_encode_cmd_temparature(uint8_t *buffer)
+{
+  *(buffer + OFFSET_ACI_CMD_T_LEN) = 1;
+  *(buffer + OFFSET_ACI_CMD_T_CMD_OPCODE) = ACI_CMD_GET_TEMPERATURE;
+}
+
+void acil_encode_cmd_read_dynamic_data(uint8_t *buffer)
+{
+  *(buffer + OFFSET_ACI_CMD_T_LEN) = 1;
+  *(buffer + OFFSET_ACI_CMD_T_CMD_OPCODE) = ACI_CMD_READ_DYNAMIC_DATA;
+}
+
+void acil_encode_cmd_write_dynamic_data(uint8_t *buffer, uint8_t seq_no, uint8_t* dynamic_data, uint8_t dynamic_data_size)
+{
+  *(buffer + OFFSET_ACI_CMD_T_LEN) = MSG_WRITE_DYNAMIC_DATA_BASE_LEN + dynamic_data_size;
+  *(buffer + OFFSET_ACI_CMD_T_CMD_OPCODE) = ACI_CMD_WRITE_DYNAMIC_DATA;
+  *(buffer + OFFSET_ACI_CMD_T_WRITE_DYNAMIC_DATA + OFFSET_ACI_CMD_PARAMS_WRITE_DYNAMIC_DATA_T_SEQ_NO) = seq_no;
+  memcpy((buffer + OFFSET_ACI_CMD_T_WRITE_DYNAMIC_DATA + OFFSET_ACI_CMD_PARAMS_WRITE_DYNAMIC_DATA_T_DYNAMIC_DATA), dynamic_data, dynamic_data_size);
+}
+
+void acil_encode_cmd_change_timing_req(uint8_t *buffer, aci_cmd_params_change_timing_t *p_aci_cmd_params_change_timing)
+{
+  *(buffer + OFFSET_ACI_CMD_T_LEN) = MSG_CHANGE_TIMING_LEN;
+  *(buffer + OFFSET_ACI_CMD_T_CMD_OPCODE) = ACI_CMD_CHANGE_TIMING;
+  *(buffer + OFFSET_ACI_CMD_T_CHANGE_TIMING + OFFSET_ACI_CMD_PARAMS_CHANGE_TIMING_T_CONN_PARAMS + OFFSET_ACI_LL_CONN_PARAMS_T_MIN_CONN_INTERVAL_MSB) = (uint8_t)(p_aci_cmd_params_change_timing->conn_params.min_conn_interval >> 8);
+  *(buffer + OFFSET_ACI_CMD_T_CHANGE_TIMING + OFFSET_ACI_CMD_PARAMS_CHANGE_TIMING_T_CONN_PARAMS + OFFSET_ACI_LL_CONN_PARAMS_T_MIN_CONN_INTERVAL_LSB) = (uint8_t)(p_aci_cmd_params_change_timing->conn_params.min_conn_interval);
+  *(buffer + OFFSET_ACI_CMD_T_CHANGE_TIMING + OFFSET_ACI_CMD_PARAMS_CHANGE_TIMING_T_CONN_PARAMS + OFFSET_ACI_LL_CONN_PARAMS_T_MAX_CONN_INTERVAL_MSB) = (uint8_t)(p_aci_cmd_params_change_timing->conn_params.max_conn_interval >> 8);
+  *(buffer + OFFSET_ACI_CMD_T_CHANGE_TIMING + OFFSET_ACI_CMD_PARAMS_CHANGE_TIMING_T_CONN_PARAMS + OFFSET_ACI_LL_CONN_PARAMS_T_MAX_CONN_INTERVAL_LSB) = (uint8_t)(p_aci_cmd_params_change_timing->conn_params.max_conn_interval);
+  *(buffer + OFFSET_ACI_CMD_T_CHANGE_TIMING + OFFSET_ACI_CMD_PARAMS_CHANGE_TIMING_T_CONN_PARAMS + OFFSET_ACI_LL_CONN_PARAMS_T_SLAVE_LATENCY_MSB    ) = (uint8_t)(p_aci_cmd_params_change_timing->conn_params.slave_latency >> 8);
+  *(buffer + OFFSET_ACI_CMD_T_CHANGE_TIMING + OFFSET_ACI_CMD_PARAMS_CHANGE_TIMING_T_CONN_PARAMS + OFFSET_ACI_LL_CONN_PARAMS_T_SLAVE_LATENCY_LSB    ) = (uint8_t)(p_aci_cmd_params_change_timing->conn_params.slave_latency);
+  *(buffer + OFFSET_ACI_CMD_T_CHANGE_TIMING + OFFSET_ACI_CMD_PARAMS_CHANGE_TIMING_T_CONN_PARAMS + OFFSET_ACI_LL_CONN_PARAMS_T_TIMEOUT_MULT_MSB     ) = (uint8_t)(p_aci_cmd_params_change_timing->conn_params.timeout_mult >> 8);
+  *(buffer + OFFSET_ACI_CMD_T_CHANGE_TIMING + OFFSET_ACI_CMD_PARAMS_CHANGE_TIMING_T_CONN_PARAMS + OFFSET_ACI_LL_CONN_PARAMS_T_TIMEOUT_MULT_LSB     ) = (uint8_t)(p_aci_cmd_params_change_timing->conn_params.timeout_mult);
+}
+
+void acil_encode_cmd_set_app_latency(uint8_t *buffer, aci_cmd_params_set_app_latency_t *p_aci_cmd_params_set_app_latency)
+{
+  *(buffer + OFFSET_ACI_CMD_T_LEN) = MSG_SET_APP_LATENCY_LEN;
+  *(buffer + OFFSET_ACI_CMD_T_CMD_OPCODE) = ACI_CMD_SET_APP_LATENCY;
+  *(buffer + OFFSET_ACI_CMD_T_SET_APP_LATENCY + OFFSET_ACI_CMD_PARAMS_SET_APP_LATENCY_T_MODE) = (uint8_t)( p_aci_cmd_params_set_app_latency->mode);
+  *(buffer + OFFSET_ACI_CMD_T_SET_APP_LATENCY + OFFSET_ACI_CMD_PARAMS_SET_APP_LATENCY_T_LATENCY_MSB) = (uint8_t)( p_aci_cmd_params_set_app_latency->latency>>8);
+  *(buffer + OFFSET_ACI_CMD_T_SET_APP_LATENCY + OFFSET_ACI_CMD_PARAMS_SET_APP_LATENCY_T_LATENCY_LSB) = (uint8_t)( p_aci_cmd_params_set_app_latency->latency);
+}
+
+void acil_encode_cmd_change_timing_req_GAP_PPCP(uint8_t *buffer)
+{
+  *(buffer + OFFSET_ACI_CMD_T_LEN) = MSG_CHANGE_TIMING_LEN_GAP_PPCP;
+  *(buffer + OFFSET_ACI_CMD_T_CMD_OPCODE) = ACI_CMD_CHANGE_TIMING;
+}
+
+
+void acil_encode_cmd_setup(uint8_t *buffer, aci_cmd_params_setup_t *p_aci_cmd_params_setup, uint8_t setup_data_size)
+{
+  *(buffer + OFFSET_ACI_CMD_T_LEN) = setup_data_size + MSG_SETUP_CMD_BASE_LEN;
+  *(buffer + OFFSET_ACI_CMD_T_CMD_OPCODE) = ACI_CMD_SETUP;
+  memcpy((buffer + OFFSET_ACI_CMD_T_SETUP), &(p_aci_cmd_params_setup->setup_data[0]), setup_data_size);
+}
+
+void acil_encode_cmd_dtm_cmd(uint8_t *buffer, aci_cmd_params_dtm_cmd_t *p_aci_cmd_params_dtm_cmd)
+{
+  *(buffer + OFFSET_ACI_CMD_T_LEN) = MSG_DTM_CMD;
+  *(buffer + OFFSET_ACI_CMD_T_CMD_OPCODE) = ACI_CMD_DTM_CMD;
+  *(buffer + OFFSET_ACI_CMD_T_DTM_CMD) = p_aci_cmd_params_dtm_cmd->cmd_msb;
+  *(buffer + OFFSET_ACI_CMD_T_DTM_CMD + 1) = p_aci_cmd_params_dtm_cmd->cmd_lsb;
+}
+
+void acil_encode_cmd_send_data_ack(uint8_t *buffer, const uint8_t pipe_number )
+{
+  *(buffer + OFFSET_ACI_CMD_T_LEN) = MSG_ACK_LEN;
+  *(buffer + OFFSET_ACI_CMD_T_CMD_OPCODE) = ACI_CMD_SEND_DATA_ACK;
+  *(buffer + OFFSET_ACI_CMD_T_SEND_DATA_ACK + OFFSET_ACI_CMD_PARAMS_SEND_DATA_ACK_T_PIPE_NUMBER) = pipe_number;
+}
+
+void acil_encode_cmd_send_data_nack(uint8_t *buffer, const uint8_t pipe_number, const uint8_t err_code )
+{
+  *(buffer + OFFSET_ACI_CMD_T_LEN) = MSG_NACK_LEN;
+  *(buffer + OFFSET_ACI_CMD_T_CMD_OPCODE) = ACI_CMD_SEND_DATA_NACK;
+  *(buffer + OFFSET_ACI_CMD_T_SEND_DATA_NACK + OFFSET_ACI_CMD_PARAMS_SEND_DATA_NACK_T_PIPE_NUMBER) = pipe_number;
+  *(buffer + OFFSET_ACI_CMD_T_SEND_DATA_NACK + OFFSET_ACI_CMD_PARAMS_SEND_DATA_NACK_T_ERROR_CODE) = err_code;
+}
+
+void acil_encode_cmd_bond_security_request(uint8_t *buffer)
+{
+  *(buffer + OFFSET_ACI_CMD_T_LEN) = 1;
+  *(buffer + OFFSET_ACI_CMD_T_CMD_OPCODE) = ACI_CMD_BOND_SECURITY_REQUEST;
+}
+
+void acil_encode_cmd_broadcast(uint8_t *buffer, aci_cmd_params_broadcast_t * p_aci_cmd_params_broadcast)
+{
+  *(buffer + OFFSET_ACI_CMD_T_LEN) = MSG_BROADCAST_LEN;
+  *(buffer + OFFSET_ACI_CMD_T_CMD_OPCODE) = ACI_CMD_BROADCAST;
+  *(buffer + OFFSET_ACI_CMD_T_BROADCAST + OFFSET_ACI_CMD_PARAMS_BROADCAST_T_TIMEOUT_LSB) = (p_aci_cmd_params_broadcast->timeout & 0xff);
+  *(buffer + OFFSET_ACI_CMD_T_BROADCAST + OFFSET_ACI_CMD_PARAMS_BROADCAST_T_TIMEOUT_MSB) = (uint8_t)(p_aci_cmd_params_broadcast->timeout >> 8);
+  *(buffer + OFFSET_ACI_CMD_T_BROADCAST + OFFSET_ACI_CMD_PARAMS_BROADCAST_T_ADV_INTERVAL_LSB) = (p_aci_cmd_params_broadcast->adv_interval & 0xff);
+  *(buffer + OFFSET_ACI_CMD_T_BROADCAST + OFFSET_ACI_CMD_PARAMS_BROADCAST_T_ADV_INTERVAL_MSB) = (uint8_t)(p_aci_cmd_params_broadcast->adv_interval >> 8);
+}
+  
+void acil_encode_cmd_open_adv_pipes(uint8_t *buffer, aci_cmd_params_open_adv_pipe_t * p_aci_cmd_params_open_adv_pipe)
+{
+  *(buffer + OFFSET_ACI_CMD_T_LEN) = MSG_OPEN_ADV_PIPES_LEN;
+  *(buffer + OFFSET_ACI_CMD_T_CMD_OPCODE) = ACI_CMD_OPEN_ADV_PIPE;
+  memcpy(buffer + OFFSET_ACI_CMD_T_OPEN_ADV_PIPE + OFFSET_ACI_CMD_PARAMS_OPEN_ADV_PIPE_T_PIPES, p_aci_cmd_params_open_adv_pipe->pipes, 8);
+}
+
+
+void acil_encode_cmd_set_key(uint8_t *buffer, aci_cmd_params_set_key_t *p_aci_cmd_params_set_key)
+{
+  /*
+  The length of the key is computed based on the type of key transaction.
+  - Key Reject
+  - Key type is passkey
+  */
+  uint8_t len;
+
+  switch (p_aci_cmd_params_set_key->key_type)
+  {
+    case ACI_KEY_TYPE_INVALID:
+    len = MSG_SET_KEY_REJECT_LEN;
+    break;
+    case ACI_KEY_TYPE_PASSKEY:
+    len = MSG_SET_KEY_PASSKEY_LEN;
+    break;
+    default:
+    len=0;
+    break;
+  }
+  *(buffer + OFFSET_ACI_CMD_T_LEN) = len;
+  *(buffer + OFFSET_ACI_CMD_T_CMD_OPCODE) = ACI_CMD_SET_KEY;
+  *(buffer + OFFSET_ACI_CMD_T_SET_KEY + OFFSET_ACI_CMD_PARAMS_SET_KEY_T_KEY_TYPE) = p_aci_cmd_params_set_key->key_type;
+  memcpy((buffer + OFFSET_ACI_CMD_T_SET_KEY + OFFSET_ACI_CMD_PARAMS_SET_KEY_T_PASSKEY), (uint8_t * )&(p_aci_cmd_params_set_key->key), len-2);//Reducing 2 for the opcode byte and type
+}
+
+bool acil_encode_cmd(uint8_t *buffer, aci_cmd_t *p_aci_cmd)
+{
+  bool ret_val = false;
+
+  switch((aci_cmd_opcode_t)p_aci_cmd->cmd_opcode)
+  {
+    case ACI_CMD_TEST:
+      acil_encode_cmd_set_test_mode(buffer, &(p_aci_cmd->params.test));
+      break;
+    case ACI_CMD_SLEEP:
+      acil_encode_cmd_sleep(buffer);
+      break;
+    case ACI_CMD_GET_DEVICE_VERSION:
+      acil_encode_cmd_get_device_version(buffer);
+      break;
+    case ACI_CMD_WAKEUP:
+      acil_encode_cmd_wakeup(buffer);
+      break;
+    case ACI_CMD_ECHO:
+      acil_encode_cmd_echo_msg(buffer, &(p_aci_cmd->params.echo), (p_aci_cmd->len - MSG_ECHO_MSG_CMD_BASE_LEN));
+      break;
+    case ACI_CMD_GET_BATTERY_LEVEL:
+      acil_encode_cmd_battery_level(buffer);
+      break;
+    case ACI_CMD_GET_TEMPERATURE:
+      acil_encode_cmd_temparature(buffer);
+      break;
+    case ACI_CMD_GET_DEVICE_ADDRESS:
+      acil_encode_cmd_get_address(buffer);
+      break;
+    case ACI_CMD_SET_TX_POWER:
+      acil_encode_cmd_set_radio_tx_power(buffer, &(p_aci_cmd->params.set_tx_power));
+      break;
+    case ACI_CMD_CONNECT:
+      acil_encode_cmd_connect(buffer, &(p_aci_cmd->params.connect));
+      break;
+    case ACI_CMD_BOND:
+      acil_encode_cmd_bond(buffer, &(p_aci_cmd->params.bond));
+      break;
+    case ACI_CMD_DISCONNECT:
+      acil_encode_cmd_disconnect(buffer, &(p_aci_cmd->params.disconnect));
+      break;
+    case ACI_CMD_RADIO_RESET:
+      acil_encode_baseband_reset(buffer);
+      break;
+    case ACI_CMD_CHANGE_TIMING:
+      acil_encode_cmd_change_timing_req(buffer, &(p_aci_cmd->params.change_timing));
+      break;
+    case ACI_CMD_SETUP:
+      acil_encode_cmd_setup(buffer, &(p_aci_cmd->params.setup), (p_aci_cmd->len - MSG_SETUP_CMD_BASE_LEN));
+      break;
+    case ACI_CMD_DTM_CMD:
+      acil_encode_cmd_dtm_cmd(buffer, &(p_aci_cmd->params.dtm_cmd));
+      break;
+    case ACI_CMD_READ_DYNAMIC_DATA:
+      acil_encode_cmd_read_dynamic_data(buffer);
+      break;
+    case ACI_CMD_WRITE_DYNAMIC_DATA:
+      acil_encode_cmd_write_dynamic_data(buffer, p_aci_cmd->params.write_dynamic_data.seq_no, &(p_aci_cmd->params.write_dynamic_data.dynamic_data[0]), (p_aci_cmd->len - MSG_WRITE_DYNAMIC_DATA_BASE_LEN));
+      break;
+    case ACI_CMD_OPEN_REMOTE_PIPE:
+      acil_encode_cmd_open_remote_pipe(buffer, &(p_aci_cmd->params.open_remote_pipe));
+      break;
+    case ACI_CMD_SEND_DATA:
+      acil_encode_cmd_send_data(buffer, &(p_aci_cmd->params.send_data), (p_aci_cmd->len - MSG_SEND_DATA_BASE_LEN));
+      break;
+    case ACI_CMD_SEND_DATA_ACK:
+      acil_encode_cmd_send_data_ack(buffer, p_aci_cmd->params.send_data_ack.pipe_number );
+      break;
+    case ACI_CMD_REQUEST_DATA:
+      acil_encode_cmd_request_data(buffer, &(p_aci_cmd->params.request_data));
+      break;
+    case ACI_CMD_SET_LOCAL_DATA:
+      acil_encode_cmd_set_local_data(buffer, (aci_cmd_params_set_local_data_t *)(&(p_aci_cmd->params.send_data)), (p_aci_cmd->len - MSG_SET_LOCAL_DATA_BASE_LEN));
+      break;
+    case ACI_CMD_BOND_SECURITY_REQUEST:
+      acil_encode_cmd_bond_security_request(buffer);
+      break;
+    default:
+      break;
+  }
+  return ret_val;
+}
+
+void acil_decode_evt_command_response(uint8_t *buffer_in, aci_evt_params_cmd_rsp_t *p_evt_params_cmd_rsp)
+{
+  aci_evt_cmd_rsp_params_get_device_version_t *p_device_version;
+  aci_evt_cmd_rsp_params_get_device_address_t *p_device_address;
+  aci_evt_cmd_rsp_params_get_temperature_t    *p_temperature;
+  aci_evt_cmd_rsp_params_get_battery_level_t  *p_batt_lvl;
+  aci_evt_cmd_rsp_read_dynamic_data_t         *p_read_dyn_data;
+  aci_evt_cmd_rsp_params_dtm_cmd_t            *p_dtm_evt;
+
+  p_evt_params_cmd_rsp->cmd_opcode = (aci_cmd_opcode_t)*(buffer_in + OFFSET_ACI_EVT_T_CMD_RSP + OFFSET_ACI_EVT_PARAMS_CMD_RSP_T_CMD_OPCODE);
+  p_evt_params_cmd_rsp->cmd_status = (aci_status_code_t)*(buffer_in + OFFSET_ACI_EVT_T_CMD_RSP + OFFSET_ACI_EVT_PARAMS_CMD_RSP_T_CMD_STATUS);
+
+  switch ((aci_cmd_opcode_t)p_evt_params_cmd_rsp->cmd_opcode)
+  {
+    case ACI_CMD_GET_DEVICE_VERSION:
+      p_device_version = &(p_evt_params_cmd_rsp->params.get_device_version);
+      p_device_version->configuration_id  = (uint16_t)*(buffer_in + OFFSET_ACI_EVT_T_CMD_RSP + OFFSET_ACI_EVT_PARAMS_CMD_RSP_T_GET_DEVICE_VERSION + OFFSET_ACI_EVT_CMD_RSP_PARAMS_GET_DEVICE_VERSION_T_CONFIGURATION_ID_LSB);
+      p_device_version->configuration_id |= (uint16_t)*(buffer_in + OFFSET_ACI_EVT_T_CMD_RSP + OFFSET_ACI_EVT_PARAMS_CMD_RSP_T_GET_DEVICE_VERSION + OFFSET_ACI_EVT_CMD_RSP_PARAMS_GET_DEVICE_VERSION_T_CONFIGURATION_ID_MSB) << 8;
+      p_device_version->aci_version       = *(buffer_in + OFFSET_ACI_EVT_T_CMD_RSP + OFFSET_ACI_EVT_PARAMS_CMD_RSP_T_GET_DEVICE_VERSION + OFFSET_ACI_EVT_CMD_RSP_PARAMS_GET_DEVICE_VERSION_T_ACI_VERSION);
+      p_device_version->setup_format      = *(buffer_in + OFFSET_ACI_EVT_T_CMD_RSP + OFFSET_ACI_EVT_PARAMS_CMD_RSP_T_GET_DEVICE_VERSION + OFFSET_ACI_EVT_CMD_RSP_PARAMS_GET_DEVICE_VERSION_T_SETUP_FORMAT);
+      p_device_version->setup_id          = (uint32_t)*(buffer_in + OFFSET_ACI_EVT_T_CMD_RSP + OFFSET_ACI_EVT_PARAMS_CMD_RSP_T_GET_DEVICE_VERSION + OFFSET_ACI_EVT_CMD_RSP_PARAMS_GET_DEVICE_VERSION_T_SETUP_ID_LSB0);
+      p_device_version->setup_id         |= (uint32_t)*(buffer_in + OFFSET_ACI_EVT_T_CMD_RSP + OFFSET_ACI_EVT_PARAMS_CMD_RSP_T_GET_DEVICE_VERSION + OFFSET_ACI_EVT_CMD_RSP_PARAMS_GET_DEVICE_VERSION_T_SETUP_ID_LSB1) << 8;
+      p_device_version->setup_id         |= (uint32_t)*(buffer_in + OFFSET_ACI_EVT_T_CMD_RSP + OFFSET_ACI_EVT_PARAMS_CMD_RSP_T_GET_DEVICE_VERSION + OFFSET_ACI_EVT_CMD_RSP_PARAMS_GET_DEVICE_VERSION_T_SETUP_ID_MSB0) << 16;
+      p_device_version->setup_id         |= (uint32_t)*(buffer_in + OFFSET_ACI_EVT_T_CMD_RSP + OFFSET_ACI_EVT_PARAMS_CMD_RSP_T_GET_DEVICE_VERSION + OFFSET_ACI_EVT_CMD_RSP_PARAMS_GET_DEVICE_VERSION_T_SETUP_ID_MSB1) << 24;
+      p_device_version->setup_status      = *(buffer_in + OFFSET_ACI_EVT_T_CMD_RSP + OFFSET_ACI_EVT_PARAMS_CMD_RSP_T_GET_DEVICE_VERSION + OFFSET_ACI_EVT_CMD_RSP_PARAMS_GET_DEVICE_VERSION_T_SETUP_STATUS);
+      break;
+
+    case ACI_CMD_GET_DEVICE_ADDRESS:
+      p_device_address = &(p_evt_params_cmd_rsp->params.get_device_address);
+      memcpy((uint8_t *)(p_device_address->bd_addr_own), (buffer_in + OFFSET_ACI_EVT_T_CMD_RSP+OFFSET_ACI_EVT_PARAMS_CMD_RSP_T_GET_DEVICE_ADDRESS+OFFSET_ACI_EVT_CMD_RSP_PARAMS_GET_DEVICE_ADDRESS_T_BD_ADDR_OWN), BTLE_DEVICE_ADDRESS_SIZE);
+      p_device_address->bd_addr_type = (aci_bd_addr_type_t) *(buffer_in + OFFSET_ACI_EVT_T_CMD_RSP+OFFSET_ACI_EVT_PARAMS_CMD_RSP_T_GET_DEVICE_ADDRESS+OFFSET_ACI_EVT_CMD_RSP_PARAMS_GET_DEVICE_ADDRESS_T_BD_ADDR_TYPE);
+      break;
+      
+    case ACI_CMD_GET_TEMPERATURE:
+      p_temperature = &(p_evt_params_cmd_rsp->params.get_temperature);
+      p_temperature->temperature_value =  (int16_t)*(buffer_in + OFFSET_ACI_EVT_T_CMD_RSP + OFFSET_ACI_EVT_PARAMS_CMD_RSP_T_GET_TEMPERATURE + OFFSET_ACI_EVT_CMD_RSP_PARAMS_GET_TEMPERATURE_T_TEMPERATURE_VALUE_LSB);
+      p_temperature->temperature_value |= (int16_t)*(buffer_in + OFFSET_ACI_EVT_T_CMD_RSP + OFFSET_ACI_EVT_PARAMS_CMD_RSP_T_GET_TEMPERATURE + OFFSET_ACI_EVT_CMD_RSP_PARAMS_GET_TEMPERATURE_T_TEMPERATURE_VALUE_MSB) << 8;
+      break;
+      
+    case ACI_CMD_GET_BATTERY_LEVEL:
+      p_batt_lvl = &(p_evt_params_cmd_rsp->params.get_battery_level);
+      p_batt_lvl->battery_level =  (int16_t)*(buffer_in + OFFSET_ACI_EVT_T_CMD_RSP + OFFSET_ACI_EVT_PARAMS_CMD_RSP_T_GET_BATTERY_LEVEL + OFFSET_ACI_EVT_CMD_RSP_PARAMS_GET_BATTERY_LEVEL_T_BATTERY_LEVEL_LSB);
+      p_batt_lvl->battery_level |= (int16_t)*(buffer_in + OFFSET_ACI_EVT_T_CMD_RSP + OFFSET_ACI_EVT_PARAMS_CMD_RSP_T_GET_BATTERY_LEVEL + OFFSET_ACI_EVT_CMD_RSP_PARAMS_GET_BATTERY_LEVEL_T_BATTERY_LEVEL_MSB) << 8;
+      break;
+    
+    case ACI_CMD_READ_DYNAMIC_DATA:
+      p_read_dyn_data = &(p_evt_params_cmd_rsp->params.read_dynamic_data);
+      p_read_dyn_data->seq_no =  (uint8_t)*(buffer_in + OFFSET_ACI_EVT_T_CMD_RSP + OFFSET_ACI_EVT_PARAMS_CMD_RSP_T_READ_DYNAMIC_DATA + OFFSET_ACI_EVT_CMD_RSP_READ_DYNAMIC_DATA_T_SEQ_NO);
+      memcpy((uint8_t *)(p_read_dyn_data->dynamic_data), (buffer_in + OFFSET_ACI_EVT_T_CMD_RSP + OFFSET_ACI_EVT_PARAMS_CMD_RSP_T_READ_DYNAMIC_DATA + OFFSET_ACI_CMD_PARAMS_WRITE_DYNAMIC_DATA_T_DYNAMIC_DATA), ACIL_DECODE_EVT_GET_LENGTH(buffer_in) - 3); // 3 bytes subtracted account for EventCode, CommandOpCode and Status bytes.
+      // Now that the p_read_dyn_data->dynamic_data will be pointing to memory location with enough space to accommodate upto 27 bytes of dynamic data received. This is because of the padding element in aci_evt_params_cmd_rsp_t
+      break;
+    
+    case ACI_CMD_DTM_CMD:
+      p_dtm_evt = &(p_evt_params_cmd_rsp->params.dtm_cmd);
+      p_dtm_evt->evt_msb = (uint8_t)*(buffer_in + OFFSET_ACI_EVT_T_CMD_RSP + OFFSET_ACI_EVT_PARAMS_CMD_RSP_T_DTM_CMD + OFFSET_ACI_EVT_CMD_RSP_PARAMS_DTM_CMD_T_EVT_MSB);
+      p_dtm_evt->evt_lsb = (uint8_t)*(buffer_in + OFFSET_ACI_EVT_T_CMD_RSP + OFFSET_ACI_EVT_PARAMS_CMD_RSP_T_DTM_CMD + OFFSET_ACI_EVT_CMD_RSP_PARAMS_DTM_CMD_T_EVT_LSB);
+      break;
+    default:
+      break;
+  }
+}
+
+void acil_decode_evt_device_started(uint8_t *buffer_in, aci_evt_params_device_started_t *p_evt_params_device_started)
+{
+  p_evt_params_device_started->device_mode = (aci_device_operation_mode_t) *(buffer_in + OFFSET_ACI_EVT_T_DEVICE_STARTED+OFFSET_ACI_EVT_PARAMS_DEVICE_STARTED_T_DEVICE_MODE);
+  p_evt_params_device_started->hw_error = (aci_hw_error_t) *(buffer_in + OFFSET_ACI_EVT_T_DEVICE_STARTED+OFFSET_ACI_EVT_PARAMS_DEVICE_STARTED_T_HW_ERROR);
+  p_evt_params_device_started->credit_available = *(buffer_in + OFFSET_ACI_EVT_T_DEVICE_STARTED+OFFSET_ACI_EVT_PARAMS_DEVICE_STARTED_T_CREDIT_AVAILABLE); 
+}
+
+void acil_decode_evt_pipe_status(uint8_t *buffer_in, aci_evt_params_pipe_status_t *p_aci_evt_params_pipe_status)
+{
+  memcpy((uint8_t *)p_aci_evt_params_pipe_status->pipes_open_bitmap, (buffer_in + OFFSET_ACI_EVT_T_PIPE_STATUS + OFFSET_ACI_EVT_PARAMS_PIPE_STATUS_T_PIPES_OPEN_BITMAP), 8);
+  memcpy((uint8_t *)p_aci_evt_params_pipe_status->pipes_closed_bitmap, (buffer_in + OFFSET_ACI_EVT_T_PIPE_STATUS + OFFSET_ACI_EVT_PARAMS_PIPE_STATUS_T_PIPES_CLOSED_BITMAP), 8);
+}
+
+void acil_decode_evt_disconnected(uint8_t *buffer_in, aci_evt_params_disconnected_t *p_aci_evt_params_disconnected)
+{
+  p_aci_evt_params_disconnected->aci_status = (aci_status_code_t)*(buffer_in + OFFSET_ACI_EVT_T_DISCONNECTED + OFFSET_ACI_EVT_PARAMS_DISCONNECTED_T_ACI_STATUS);
+  p_aci_evt_params_disconnected->btle_status = *(buffer_in + OFFSET_ACI_EVT_T_DISCONNECTED + OFFSET_ACI_EVT_PARAMS_DISCONNECTED_T_BTLE_STATUS);
+}
+
+void acil_decode_evt_bond_status(uint8_t *buffer_in, aci_evt_params_bond_status_t *p_aci_evt_params_bond_status)
+{
+  p_aci_evt_params_bond_status->status_code = (aci_bond_status_code_t)*(buffer_in + OFFSET_ACI_EVT_T_BOND_STATUS + OFFSET_ACI_EVT_PARAMS_BOND_STATUS_T_STATUS_CODE);
+  p_aci_evt_params_bond_status->status_source = (aci_bond_status_source_t)*(buffer_in + OFFSET_ACI_EVT_T_BOND_STATUS + OFFSET_ACI_EVT_PARAMS_BOND_STATUS_T_STATUS_SOURCE);
+  p_aci_evt_params_bond_status->secmode1_bitmap = *(buffer_in + OFFSET_ACI_EVT_T_BOND_STATUS + OFFSET_ACI_EVT_PARAMS_BOND_STATUS_T_SECMODE1_BITMAP);
+  p_aci_evt_params_bond_status->secmode2_bitmap = *(buffer_in + OFFSET_ACI_EVT_T_BOND_STATUS + OFFSET_ACI_EVT_PARAMS_BOND_STATUS_T_SECMODE2_BITMAP);
+  p_aci_evt_params_bond_status->keys_exchanged_slave = *(buffer_in + OFFSET_ACI_EVT_T_BOND_STATUS + OFFSET_ACI_EVT_PARAMS_BOND_STATUS_T_KEYS_EXCHANGED_SLAVE);
+  p_aci_evt_params_bond_status->keys_exchanged_master = *(buffer_in + OFFSET_ACI_EVT_T_BOND_STATUS + OFFSET_ACI_EVT_PARAMS_BOND_STATUS_T_KEYS_EXCHANGED_MASTER);
+}
+
+uint8_t acil_decode_evt_data_received(uint8_t *buffer_in, aci_evt_params_data_received_t *p_evt_params_data_received)
+{
+  uint8_t size = *( buffer_in + OFFSET_ACI_EVT_T_LEN) - (OFFSET_ACI_EVT_T_DATA_RECEIVED + OFFSET_ACI_RX_DATA_T_ACI_DATA) + 1 ;
+  p_evt_params_data_received->rx_data.pipe_number = *(buffer_in + OFFSET_ACI_EVT_T_DATA_RECEIVED + OFFSET_ACI_RX_DATA_T_PIPE_NUMBER);
+  memcpy((uint8_t *)p_evt_params_data_received->rx_data.aci_data, (buffer_in + OFFSET_ACI_EVT_T_DATA_RECEIVED + OFFSET_ACI_RX_DATA_T_ACI_DATA), size);
+  return size;
+}
+
+void acil_decode_evt_data_ack(uint8_t *buffer_in, aci_evt_params_data_ack_t *p_evt_params_data_ack)
+{
+  p_evt_params_data_ack->pipe_number = *(buffer_in + OFFSET_ACI_EVT_T_DATA_ACK + OFFSET_ACI_EVT_PARAMS_DATA_ACK_T_PIPE_NUMBER);
+}
+
+uint8_t acil_decode_evt_hw_error(uint8_t *buffer_in, aci_evt_params_hw_error_t *p_aci_evt_params_hw_error)
+{
+  uint8_t size = *(buffer_in + OFFSET_ACI_EVT_T_LEN) - (OFFSET_ACI_EVT_T_HW_ERROR + OFFSET_ACI_EVT_PARAMS_HW_ERROR_T_FILE_NAME) + 1;
+  p_aci_evt_params_hw_error->line_num = (uint16_t)(*(buffer_in + OFFSET_ACI_EVT_T_HW_ERROR + OFFSET_ACI_EVT_PARAMS_HW_ERROR_T_LINE_NUM_MSB)) << 8;
+  p_aci_evt_params_hw_error->line_num |= (uint16_t)*(buffer_in + OFFSET_ACI_EVT_T_HW_ERROR + OFFSET_ACI_EVT_PARAMS_HW_ERROR_T_LINE_NUM_LSB);
+  memcpy((uint8_t *)p_aci_evt_params_hw_error->file_name, (buffer_in + OFFSET_ACI_EVT_T_HW_ERROR + OFFSET_ACI_EVT_PARAMS_HW_ERROR_T_FILE_NAME), size);
+  return size;
+}
+
+void acil_decode_evt_credit(uint8_t *buffer_in, aci_evt_params_data_credit_t *p_evt_params_data_credit)
+{
+  p_evt_params_data_credit->credit = *(buffer_in + OFFSET_ACI_EVT_T_DATA_CREDIT + OFFSET_ACI_EVT_PARAMS_DATA_CREDIT_T_CREDIT);
+}
+
+void acil_decode_evt_connected(uint8_t *buffer_in, aci_evt_params_connected_t *p_aci_evt_params_connected)
+{
+  p_aci_evt_params_connected->dev_addr_type = (aci_bd_addr_type_t)*(buffer_in + OFFSET_ACI_EVT_T_CONNECTED + OFFSET_ACI_EVT_PARAMS_CONNECTED_T_DEV_ADDR_TYPE);
+  memcpy(&(p_aci_evt_params_connected->dev_addr[0]), (buffer_in + OFFSET_ACI_EVT_T_CONNECTED + OFFSET_ACI_EVT_PARAMS_CONNECTED_T_DEV_ADDR), BTLE_DEVICE_ADDRESS_SIZE);
+  p_aci_evt_params_connected->conn_rf_interval       = (uint16_t)*(buffer_in + OFFSET_ACI_EVT_T_CONNECTED + OFFSET_ACI_EVT_PARAMS_CONNECTED_T_CONN_RF_INTERVAL_MSB) << 8;
+  p_aci_evt_params_connected->conn_rf_interval      |= (uint16_t)*(buffer_in + OFFSET_ACI_EVT_T_CONNECTED + OFFSET_ACI_EVT_PARAMS_CONNECTED_T_CONN_RF_INTERVAL_LSB);
+  p_aci_evt_params_connected->conn_slave_rf_latency  = (uint16_t)*(buffer_in + OFFSET_ACI_EVT_T_CONNECTED + OFFSET_ACI_EVT_PARAMS_CONNECTED_T_CONN_SLAVE_RF_LATENCY_MSB) << 8;
+  p_aci_evt_params_connected->conn_slave_rf_latency |= (uint16_t)*(buffer_in + OFFSET_ACI_EVT_T_CONNECTED + OFFSET_ACI_EVT_PARAMS_CONNECTED_T_CONN_SLAVE_RF_LATENCY_LSB);
+  p_aci_evt_params_connected->conn_rf_timeout        = (uint16_t)*(buffer_in + OFFSET_ACI_EVT_T_CONNECTED + OFFSET_ACI_EVT_PARAMS_CONNECTED_T_CONN_RF_TIMEOUT_MSB) << 8;
+  p_aci_evt_params_connected->conn_rf_timeout       |= (uint16_t)*(buffer_in + OFFSET_ACI_EVT_T_CONNECTED + OFFSET_ACI_EVT_PARAMS_CONNECTED_T_CONN_RF_TIMEOUT_LSB);
+  p_aci_evt_params_connected->master_clock_accuracy  = (aci_clock_accuracy_t)*(buffer_in + OFFSET_ACI_EVT_T_CONNECTED + OFFSET_ACI_EVT_PARAMS_CONNECTED_T_MASTER_CLOCK_ACCURACY);
+
+}
+
+void acil_decode_evt_timing(uint8_t *buffer_in, aci_evt_params_timing_t *p_evt_params_timing)
+{
+  p_evt_params_timing->conn_rf_interval       = *(buffer_in + OFFSET_ACI_EVT_T_TIMING + OFFSET_ACI_EVT_PARAMS_TIMING_T_CONN_RF_INTERVAL_MSB) << 8;
+  p_evt_params_timing->conn_rf_interval      |= (uint16_t)*(buffer_in + OFFSET_ACI_EVT_T_TIMING + OFFSET_ACI_EVT_PARAMS_TIMING_T_CONN_RF_INTERVAL_LSB);
+  p_evt_params_timing->conn_slave_rf_latency  = (uint16_t)*(buffer_in + OFFSET_ACI_EVT_T_TIMING + OFFSET_ACI_EVT_PARAMS_TIMING_T_CONN_SLAVE_RF_LATENCY_MSB) << 8;
+  p_evt_params_timing->conn_slave_rf_latency |= (uint16_t)*(buffer_in + OFFSET_ACI_EVT_T_TIMING + OFFSET_ACI_EVT_PARAMS_TIMING_T_CONN_SLAVE_RF_LATENCY_LSB);
+  p_evt_params_timing->conn_rf_timeout        = (uint16_t)*(buffer_in + OFFSET_ACI_EVT_T_TIMING + OFFSET_ACI_EVT_PARAMS_TIMING_T_CONN_RF_TIMEOUT_MSB) << 8;
+  p_evt_params_timing->conn_rf_timeout       |= *(buffer_in + OFFSET_ACI_EVT_T_TIMING + OFFSET_ACI_EVT_PARAMS_TIMING_T_CONN_RF_TIMEOUT_LSB);
+}
+
+void acil_decode_evt_pipe_error(uint8_t *buffer_in, aci_evt_params_pipe_error_t *p_evt_params_pipe_error)
+{
+  //volatile uint8_t size = *(buffer_in + OFFSET_ACI_EVT_T_LEN) - (OFFSET_ACI_EVT_T_PIPE_ERROR + OFFSET_ACI_EVT_PARAMS_PIPE_ERROR_T_ERROR_DATA) + 1;
+  p_evt_params_pipe_error->pipe_number = *(buffer_in + OFFSET_ACI_EVT_T_PIPE_ERROR + OFFSET_ACI_EVT_PARAMS_PIPE_ERROR_T_PIPE_NUMBER);
+  p_evt_params_pipe_error->error_code = *(buffer_in + OFFSET_ACI_EVT_T_PIPE_ERROR + OFFSET_ACI_EVT_PARAMS_PIPE_ERROR_T_ERROR_CODE);
+  p_evt_params_pipe_error->params.error_data.content[0] = *(buffer_in + OFFSET_ACI_EVT_T_PIPE_ERROR + OFFSET_ACI_EVT_PARAMS_PIPE_ERROR_T_ERROR_DATA + OFFSET_ERROR_DATA_T_CONTENT);
+}
+
+void acil_decode_evt_key_request(uint8_t *buffer_in, aci_evt_params_key_request_t *p_evt_params_key_request)
+{
+  p_evt_params_key_request->key_type = (aci_key_type_t)*(buffer_in + OFFSET_ACI_EVT_T_KEY_REQUEST + OFFSET_ACI_EVT_PARAMS_KEY_REQUEST_T_KEY_TYPE);
+}
+
+uint8_t acil_decode_evt_echo(uint8_t *buffer_in, aci_evt_params_echo_t *aci_evt_params_echo)
+{
+  uint8_t size = *(buffer_in + OFFSET_ACI_EVT_T_LEN) - 1;
+  memcpy(&aci_evt_params_echo->echo_data[0], (buffer_in + OFFSET_ACI_EVT_T_EVT_OPCODE + 1), size);
+  return size;
+}
+
+void acil_decode_evt_display_passkey(uint8_t *buffer_in, aci_evt_params_display_passkey_t *p_aci_evt_params_display_passkey)
+{
+  p_aci_evt_params_display_passkey->passkey[0] = *(buffer_in + OFFSET_ACI_EVT_T_DISPLAY_PASSKEY +  OFFSET_ACI_EVT_PARAMS_DISPLAY_PASSKEY_T_PASSKEY + 0);
+  p_aci_evt_params_display_passkey->passkey[1] = *(buffer_in + OFFSET_ACI_EVT_T_DISPLAY_PASSKEY +  OFFSET_ACI_EVT_PARAMS_DISPLAY_PASSKEY_T_PASSKEY + 1);
+  p_aci_evt_params_display_passkey->passkey[2] = *(buffer_in + OFFSET_ACI_EVT_T_DISPLAY_PASSKEY +  OFFSET_ACI_EVT_PARAMS_DISPLAY_PASSKEY_T_PASSKEY + 2);
+  p_aci_evt_params_display_passkey->passkey[3] = *(buffer_in + OFFSET_ACI_EVT_T_DISPLAY_PASSKEY +  OFFSET_ACI_EVT_PARAMS_DISPLAY_PASSKEY_T_PASSKEY + 3);
+  p_aci_evt_params_display_passkey->passkey[4] = *(buffer_in + OFFSET_ACI_EVT_T_DISPLAY_PASSKEY +  OFFSET_ACI_EVT_PARAMS_DISPLAY_PASSKEY_T_PASSKEY + 4);
+  p_aci_evt_params_display_passkey->passkey[5] = *(buffer_in + OFFSET_ACI_EVT_T_DISPLAY_PASSKEY +  OFFSET_ACI_EVT_PARAMS_DISPLAY_PASSKEY_T_PASSKEY + 5);
+}
+
+bool acil_decode_evt(uint8_t *buffer_in, aci_evt_t *p_aci_evt)
+{
+  bool ret_val = true;
+
+  p_aci_evt->len = ACIL_DECODE_EVT_GET_LENGTH(buffer_in);
+  p_aci_evt->evt_opcode = (aci_evt_opcode_t)ACIL_DECODE_EVT_GET_OPCODE(buffer_in);
+
+  switch(p_aci_evt->evt_opcode)
+  {
+    case ACI_EVT_DEVICE_STARTED:
+      acil_decode_evt_device_started(buffer_in, &(p_aci_evt->params.device_started));
+      break;
+    case ACI_EVT_HW_ERROR:
+      acil_decode_evt_hw_error(buffer_in, &(p_aci_evt->params.hw_error));
+      break;
+    case ACI_EVT_CMD_RSP:
+      acil_decode_evt_command_response(buffer_in, &(p_aci_evt->params.cmd_rsp));
+      break;
+    case ACI_EVT_DATA_CREDIT:
+      acil_decode_evt_credit(buffer_in, &(p_aci_evt->params.data_credit));
+      break;
+    case ACI_EVT_CONNECTED:
+      acil_decode_evt_connected(buffer_in, &(p_aci_evt->params.connected));
+      break;
+    case ACI_EVT_PIPE_STATUS:
+      acil_decode_evt_pipe_status(buffer_in, &(p_aci_evt->params.pipe_status));
+      break;
+    case ACI_EVT_DISCONNECTED:
+      acil_decode_evt_disconnected(buffer_in, &(p_aci_evt->params.disconnected));
+      break;
+    case ACI_EVT_BOND_STATUS:
+      acil_decode_evt_bond_status(buffer_in, &(p_aci_evt->params.bond_status));
+      break;
+    case ACI_EVT_TIMING:
+      acil_decode_evt_timing(buffer_in, &(p_aci_evt->params.timing));
+      break;
+    case ACI_EVT_DATA_ACK:
+      acil_decode_evt_data_ack(buffer_in, &(p_aci_evt->params.data_ack));
+      break;
+    case ACI_EVT_DATA_RECEIVED:
+      acil_decode_evt_data_received(buffer_in, &(p_aci_evt->params.data_received));
+      break;
+    case ACI_EVT_PIPE_ERROR:
+      acil_decode_evt_pipe_error(buffer_in, &(p_aci_evt->params.pipe_error));
+      break;
+    case ACI_EVT_KEY_REQUEST:
+      acil_decode_evt_key_request(buffer_in, &(p_aci_evt->params.key_request));
+      break;
+    case ACI_EVT_DISPLAY_PASSKEY:
+      acil_decode_evt_display_passkey(buffer_in, &(p_aci_evt->params.display_passkey));     
+      break;
+    default:
+      ret_val = false;
+      break;
+  }
+  return ret_val;
+}
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/ble_shield2.1/utility/acilib.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/ble_shield2.1/utility/acilib.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/ble_shield2.1/utility/acilib.h	(revision 457)
@@ -0,0 +1,61 @@
+/* Copyright (c) 2014, Nordic Semiconductor ASA
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+/**
+ * @file
+ *
+ * @ingroup group_acilib
+ *
+ * @brief Internal prototype for acilib module.
+ */
+
+#ifndef _acilib_H_
+#define _acilib_H_
+
+#define MSG_SET_LOCAL_DATA_BASE_LEN              2
+#define MSG_CONNECT_LEN                          5
+#define MSG_BOND_LEN                             5
+#define MSG_DISCONNECT_LEN                       2
+#define MSG_BASEBAND_RESET_LEN                   1
+#define MSG_WAKEUP_LEN                           1
+#define MSG_SET_RADIO_TX_POWER_LEN               2
+#define MSG_GET_DEVICE_ADDR_LEN                  1
+#define MSG_SEND_DATA_BASE_LEN                   2
+#define MSG_DATA_REQUEST_LEN                     2
+#define MSG_OPEN_REMOTE_PIPE_LEN                 2
+#define MSG_CLOSE_REMOTE_PIPE_LEN                2
+#define MSG_DTM_CMD                              3
+#define MSG_WRITE_DYNAMIC_DATA_BASE_LEN          2
+#define MSG_SETUP_CMD_BASE_LEN                   1
+#define MSG_ECHO_MSG_CMD_BASE_LEN                1
+#define MSG_CHANGE_TIMING_LEN                    9
+#define MSG_SET_APP_LATENCY_LEN                  4
+#define MSG_CHANGE_TIMING_LEN_GAP_PPCP           1
+#define MSG_DIRECT_CONNECT_LEN                   1
+#define MSG_SET_KEY_REJECT_LEN                   2
+#define MSG_SET_KEY_PASSKEY_LEN                  8
+#define MSG_SET_KEY_OOB_LEN                      18
+#define MSG_ACK_LEN                              2
+#define MSG_NACK_LEN                             3
+#define MSG_BROADCAST_LEN                        5
+#define MSG_OPEN_ADV_PIPES_LEN                   9
+
+#endif /* _acilib_H_ */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/ble_shield2.1/utility/acilib_defs.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/ble_shield2.1/utility/acilib_defs.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/ble_shield2.1/utility/acilib_defs.h	(revision 457)
@@ -0,0 +1,37 @@
+/* Copyright (c) 2014, Nordic Semiconductor ASA
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+/**
+ * @file
+ *
+ * @ingroup group_acilib
+ *
+ * @brief Definitions for the acilib interfaces
+ */
+
+#ifndef _acilib_DEFS_H_
+#define _acilib_DEFS_H_
+
+#define ACIL_DECODE_EVT_GET_LENGTH(buffer_in) (*(buffer_in + OFFSET_ACI_EVT_T_LEN))
+
+#define ACIL_DECODE_EVT_GET_OPCODE(buffer_in) (*(buffer_in + OFFSET_ACI_EVT_T_EVT_OPCODE))
+
+#endif /* _acilib_DEFS_H_ */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/ble_shield2.1/utility/acilib_if.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/ble_shield2.1/utility/acilib_if.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/ble_shield2.1/utility/acilib_if.h	(revision 457)
@@ -0,0 +1,471 @@
+/* Copyright (c) 2014, Nordic Semiconductor ASA
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+/**
+ * @file
+ *
+ * @ingroup group_acilib
+ *
+ * @brief Prototypes for the acilib interfaces.
+ */
+
+#ifndef _acilib_IF_H_
+#define _acilib_IF_H_
+
+/** @brief Encode the ACI message for set test mode command
+ *
+ *  @param[in,out]  buffer      Pointer to ACI message buffer
+ *  @param[in]      test_mode   Pointer to the test mode in ::aci_cmd_params_test_t
+ *
+ *  @return         None
+ */
+void acil_encode_cmd_set_test_mode(uint8_t *buffer, aci_cmd_params_test_t *p_aci_cmd_params_test);
+
+/** @brief Encode the ACI message for sleep command
+ *
+ *  @param[in,out]  buffer      Pointer to ACI message buffer
+ *
+ *  @return         None
+ */
+void acil_encode_cmd_sleep(uint8_t *buffer);
+
+/** @brief Encode the ACI message for get device version
+ *
+ *  @param[in,out]  buffer      Pointer to ACI message buffer
+ *
+ *  @return         None
+ */
+void acil_encode_cmd_get_device_version(uint8_t *buffer);
+
+/** @brief Encode the ACI message for set local data
+ *
+ *  @param[in,out]  buffer                           Pointer to ACI message buffer
+ *  @param[in]      p_aci_cmd_params_set_local_data  Pointer to the local data parameters in ::aci_cmd_params_set_local_data_t
+ *  @param[in]      data_size                        Size of data message
+ *
+ *  @return         None
+ */
+void acil_encode_cmd_set_local_data(uint8_t *buffer, aci_cmd_params_set_local_data_t *p_aci_cmd_params_set_local_data, uint8_t data_size);
+
+/** @brief Encode the ACI message to connect
+ *
+ *  @param[in,out]  buffer                    Pointer to ACI message buffer
+ *  @param[in]      p_aci_cmd_params_connect  Pointer to the run parameters in ::aci_cmd_params_connect_t
+ *
+ *  @return         None
+ */
+void acil_encode_cmd_connect(uint8_t *buffer, aci_cmd_params_connect_t *p_aci_cmd_params_connect);
+
+/** @brief Encode the ACI message to bond
+ *
+ *  @param[in,out]  buffer                 Pointer to ACI message buffer
+ *  @param[in]      p_aci_cmd_params_bond  Pointer to the run parameters in ::aci_cmd_params_bond_t
+ *
+ *  @return         None
+ */
+void acil_encode_cmd_bond(uint8_t *buffer, aci_cmd_params_bond_t *p_aci_cmd_params_bond);
+
+/** @brief Encode the ACI message to disconnect
+ *
+ *  @param[in,out]  buffer                       Pointer to ACI message buffer
+ *  @param[in]      p_aci_cmd_params_disconnect  Pointer to the run parameters in ::aci_cmd_params_disconnect_t
+ *
+ *  @return         None
+ */
+void acil_encode_cmd_disconnect(uint8_t *buffer, aci_cmd_params_disconnect_t *p_aci_cmd_params_disconnect);
+
+/** @brief Encode the ACI message to baseband reset
+ *
+ *  @param[in,out]  buffer        Pointer to ACI message buffer
+ *
+ *  @return         None
+ */
+ void acil_encode_baseband_reset(uint8_t *buffer);
+
+ /** @brief Encode the ACI message for Directed Advertising
+ *
+ *  @param[in,out]  buffer        Pointer to ACI message buffer
+ *
+ *  @return         None
+ */
+ void acil_encode_direct_connect(uint8_t *buffer);
+
+/** @brief Encode the ACI message to wakeup
+ *
+ *  @param[in,out]  buffer        Pointer to ACI message buffer
+ *
+ *  @return         None
+ */
+void acil_encode_cmd_wakeup(uint8_t *buffer);
+
+/** @brief Encode the ACI message for set radio Tx power
+ *
+ *  @param[in,out]  buffer                         Pointer to ACI message buffer
+ *  @param[in]      p_aci_cmd_params_set_tx_power  Pointer to the set Tx power parameters in ::aci_cmd_params_set_tx_power_t
+ *
+ *  @return         None
+ */
+void acil_encode_cmd_set_radio_tx_power(uint8_t *buffer, aci_cmd_params_set_tx_power_t *p_aci_cmd_params_set_tx_power);
+
+/** @brief Encode the ACI message for get device address
+ *
+ *  @param[in,out]  buffer            Pointer to ACI message buffer
+ *
+ *  @return         None
+ */
+void acil_encode_cmd_get_address(uint8_t *buffer);
+
+/** @brief Encode the ACI message for send data
+ *
+ *  @param[in,out]  buffer                        Pointer to ACI message buffer
+ *  @param[in]      p_aci_cmd_params_send_data_t  Pointer to the data parameters in ::aci_cmd_params_send_data_t
+ *  @param[in]      data_size                     Size of data message
+ *
+ *  @return         None
+ */
+void acil_encode_cmd_send_data(uint8_t *buffer, aci_cmd_params_send_data_t *p_aci_cmd_params_send_data_t, uint8_t data_size);
+
+/** @brief Encode the ACI message for request data
+ *
+ *  @param[in,out]  buffer                          Pointer to ACI message buffer
+ *  @param[in]      p_aci_cmd_params_request_data   Pointer to the request data parameters in ::aci_cmd_params_request_data_t
+ *
+ *  @return         None
+ */
+void acil_encode_cmd_request_data(uint8_t *buffer, aci_cmd_params_request_data_t *p_aci_cmd_params_request_data);
+
+/** @brief Encode the ACI message for open remote pipe
+ *
+ *  @param[in,out]  buffer                              Pointer to ACI message buffer
+ *  @param[in]      p_aci_cmd_params_open_remote_pipe   Pointer to the dynamic data parameters in ::aci_cmd_params_open_remote_pipe_t
+ *
+ *  @return         None
+ */
+void acil_encode_cmd_open_remote_pipe(uint8_t *buffer, aci_cmd_params_open_remote_pipe_t *p_aci_cmd_params_open_remote_pipe);
+
+/** @brief Encode the ACI message for close remote pipe
+ *
+ *  @param[in,out]  buffer                              Pointer to ACI message buffer
+ *  @param[in]      p_aci_cmd_params_close_remote_pipe   Pointer to the dynamic data parameters in ::aci_cmd_params_close_remote_pipe_t
+ *
+ *  @return         None
+ */
+void acil_encode_cmd_close_remote_pipe(uint8_t *buffer, aci_cmd_params_close_remote_pipe_t *p_aci_cmd_params_close_remote_pipe);
+
+/** @brief Encode the ACI message for echo message
+ *
+ *  @param[in,out]  buffer             Pointer to ACI message buffer
+ *  @param[in]      p_cmd_params_echo  Pointer to the dynamic data parameters in ::aci_cmd_params_echo_t
+ *  @param[in]      msg_size           Size of the message
+ *
+ *  @return         None
+ */
+void acil_encode_cmd_echo_msg(uint8_t *buffer, aci_cmd_params_echo_t *p_cmd_params_echo, uint8_t msg_size);
+
+/** @brief Encode the ACI message to battery level
+ *
+ *  @param[in,out]  buffer  Pointer to ACI message buffer
+ *
+ *  @return         None
+ */
+void acil_encode_cmd_battery_level(uint8_t *buffer);
+
+/** @brief Encode the ACI message to temparature
+ *
+ *  @param[in,out]  buffer  Pointer to ACI message buffer
+ *
+ *  @return         None
+ */
+void acil_encode_cmd_temparature(uint8_t *buffer);
+
+/** @brief Encode the ACI message to read dynamic data
+ *
+ *  @param[in,out]  buffer  Pointer to ACI message buffer
+ *
+ *  @return         None
+ */
+void acil_encode_cmd_read_dynamic_data(uint8_t *buffer);
+
+/** @brief Encode the ACI message to change timing request
+ *
+ *  @param[in,out]  buffer  Pointer to ACI message buffer
+ *  @param[in]      p_aci_cmd_params_change_timing  Pointer to the change timing parameters in ::aci_cmd_params_change_timing_t
+ *
+ *  @return         None
+ */
+void acil_encode_cmd_change_timing_req(uint8_t *buffer, aci_cmd_params_change_timing_t *p_aci_cmd_params_change_timing);
+
+/** @brief Encode the ACI message to change timing request using the timing parameters from GAP PPCP
+ *
+ *  @param[in,out]  buffer  Pointer to ACI message buffer
+ *  @param[in]      p_aci_cmd_params_change_timing  Pointer to the change timing parameters in ::aci_cmd_params_change_timing_t
+ *
+ *  @return         None
+ */
+void acil_encode_cmd_change_timing_req_GAP_PPCP(uint8_t *buffer);
+
+
+/** @brief Encode the ACI message for write dynamic data
+ *
+ *  @param[in,out]  buffer                          Pointer to ACI message buffer
+ *  @param[in]      seq_no                          Sequence number of the dynamic data (as received in the response to @c Read Dynamic Data)
+ *  @param[in]      dynamic_data                    Pointer to the dynamic data
+ *  @param[in]      dynamic_data_size               Size of dynamic data
+ *
+ *  @return         None
+ */
+void acil_encode_cmd_write_dynamic_data(uint8_t *buffer, uint8_t seq_no, uint8_t* dynamic_data, uint8_t dynamic_data_size);
+
+/** @brief Encode the ACI message to send data acknowledgement
+ *
+ *  @param[in,out]  buffer  Pointer to ACI message buffer
+ *  @param[in]      pipe_number Pipe number for which the ack is to be sent
+ *
+ *  @return         None
+ */
+void acil_encode_cmd_send_data_ack(uint8_t *buffer, const uint8_t pipe_number);
+
+/** @brief Encode the ACI message to send negative acknowledgement
+ *
+ *  @param[in,out]  buffer  Pointer to ACI message buffer
+ *  @param[in]    pipe_number Pipe number for which the nack is to be sent
+ *  @param[in]    error_code Error code that has to be sent in the NACK
+ *
+ *  @return         None
+ */
+void acil_encode_cmd_send_data_nack(uint8_t *buffer, const uint8_t pipe_number,const uint8_t error_code);
+
+/** @brief Encode the ACI message to set the application latency
+ *
+ *  @param[in,out]  buffer  Pointer to ACI message buffer
+ *  @param[in]      p_aci_cmd_params_set_app_latency  Pointer to the set_application_latency command parameters in ::aci_cmd_params_dtm_cmd_t
+ *
+ *  @return         None
+ */
+void acil_encode_cmd_set_app_latency(uint8_t *buffer, aci_cmd_params_set_app_latency_t *p_aci_cmd_params_set_app_latency);
+
+/** @brief Encode the ACI message for setup
+ *
+ *  @param[in,out]  buffer                          Pointer to ACI message buffer
+ *  @param[in]      p_cmd_params_set_run_behaviour  Pointer to the setup data in ::aci_cmd_params_setup_t
+ *  @param[in]      setup_data_size                 Size of setup message
+ *
+ *  @return         None
+ */
+void acil_encode_cmd_setup(uint8_t *buffer, aci_cmd_params_setup_t *p_aci_cmd_params_setup, uint8_t setup_data_size);
+
+/** @brief Encode the ACI message for DTM command
+ *
+ *  @param[in,out]  buffer                          Pointer to ACI message buffer
+ *  @param[in]      p_cmd_params_set_run_behaviour  Pointer to the DTM command parameters in ::aci_cmd_params_dtm_cmd_t
+ *
+ *  @return         None
+ */
+void acil_encode_cmd_dtm_cmd(uint8_t *buffer, aci_cmd_params_dtm_cmd_t *p_aci_cmd_params_dtm_cmd);
+
+/** @brief Encode the ACI message for Set Key Request command
+ *
+ *  @param[in,out]  buffer      Pointer to ACI message buffer
+ *
+ *  @return         None
+ */
+void acil_encode_cmd_set_key(uint8_t *buffer, aci_cmd_params_set_key_t *p_aci_cmd_params_set_key);
+
+/** @brief Encode the ACI message for Bond Security Request command
+ *
+ *  @param[in,out]  buffer      Pointer to ACI message buffer
+ *
+ *  @return         None
+ */
+void acil_encode_cmd_bond_security_request(uint8_t *buffer);
+
+/** @brief Encode the ACI message
+ *
+ *  @param[in,out]  buffer      Pointer to ACI message buffer
+ *  @param[in]      p_aci_cmd   Pointer to ACI command data in ::aci_cmd_t
+ *  @param[in]      bool       
+ *
+ *  @return         bool         true, if succesful, else returns false
+ */
+bool acil_encode_cmd(uint8_t *buffer, aci_cmd_t *p_aci_cmd);
+
+/** @brief Encode the ACI message for Broadcast command
+ *
+ *  @param[in,out]  buffer      Pointer to ACI message buffer
+ *  @param[in]      p_aci_cmd   Pointer to ACI command data in ::aci_cmd_params_broadcast_t
+ *
+ *  @return         None
+ */
+void acil_encode_cmd_broadcast(uint8_t *buffer,  aci_cmd_params_broadcast_t * p_aci_cmd_params_broadcast);
+
+/** @brief Encode the ACI message for Open Adv Pipes
+ *
+ *  @param[in,out]  buffer      Pointer to ACI message buffer
+ *  @param[in]      p_aci_cmd   Pointer to ACI command data in ::aci_cmd_params_open_adv_pipe_t
+ *
+ *  @return         None
+ */
+void acil_encode_cmd_open_adv_pipes(uint8_t *buffer, aci_cmd_params_open_adv_pipe_t * p_aci_cmd_params_set_adv_svc_data);
+
+/** @brief Decode the ACI event command response
+ *
+ *  @param[in]      buffer_in  Pointer to message received
+ *  @param[in,out]  buffer     Pointer to the decoded message in ::aci_evt_params_cmd_rsp_t
+ *
+ *  @return         None
+ */
+void acil_decode_evt_command_response(uint8_t *buffer_in, aci_evt_params_cmd_rsp_t *p_evt_params_cmd_rsp);
+
+/** @brief Decode the ACI event device started
+ *
+ *  @param[in]      buffer_in  Pointer to message received
+ *  @param[in,out]  p_aci_evt  Pointer to the decoded message in ::aci_evt_params_device_started_t
+ *
+ *  @return         None
+ */
+void acil_decode_evt_device_started(uint8_t *buffer_in, aci_evt_params_device_started_t *p_evt_params_device_started);
+
+/** @brief Decode the ACI event pipe status
+ *
+ *  @param[in]      buffer_in  Pointer to message received
+ *  @param[in,out]  p_aci_evt_params_pipe_status  Pointer to the decoded message in ::aci_evt_params_pipe_status_t
+ *
+ *  @return         None
+ */
+void acil_decode_evt_pipe_status(uint8_t *buffer_in, aci_evt_params_pipe_status_t *p_aci_evt_params_pipe_status);
+
+/** @brief Decode the ACI event for disconnected
+ *
+ *  @param[in]      buffer_in                      Pointer to message received
+ *  @param[in,out]  p_aci_evt_params_disconnected  Pointer to the decoded message in ::aci_evt_params_disconnected_t
+ *
+ *  @return         None
+ */
+void acil_decode_evt_disconnected(uint8_t *buffer_in, aci_evt_params_disconnected_t *p_aci_evt_params_disconnected);
+
+/** @brief Decode the ACI event for bond status
+ *
+ *  @param[in]      buffer_in                     Pointer to message received
+ *  @param[in,out]  p_aci_evt_params_bond_status  Pointer to the decoded message in ::aci_evt_params_bond_status_t
+ *
+ *  @return         None
+ */
+void acil_decode_evt_bond_status(uint8_t *buffer_in, aci_evt_params_bond_status_t *p_aci_evt_params_bond_status);
+
+/** @brief Decode the ACI event for data received
+ *
+ *  @param[in]      buffer_in                   Pointer to message received
+ *  @param[in,out]  p_evt_params_data_received  Pointer to the decoded message in ::aci_evt_params_data_received_t
+ *
+ *  @return         size                        Received data size
+ */
+uint8_t acil_decode_evt_data_received(uint8_t *buffer_in, aci_evt_params_data_received_t *p_evt_params_data_received);
+
+/** @brief Decode the ACI event data acknowledgement
+ *
+ *  @param[in]      buffer_in               Pointer to message received
+ *  @param[in,out]  p_evt_params_data_ack   Pointer to the decoded message in ::aci_evt_params_data_ack_t
+ *
+ *  @return         None
+ */
+void acil_decode_evt_data_ack(uint8_t *buffer_in, aci_evt_params_data_ack_t *p_evt_params_data_ack);
+
+/** @brief Decode the ACI event for hardware error
+ *
+ *  @param[in]      buffer_in                  Pointer to message received
+ *  @param[in,out]  p_aci_evt_params_hw_error  Pointer to the decoded message in ::aci_evt_params_hw_error_t
+ *
+ *  @return         size                     Size of debug information
+ */
+uint8_t acil_decode_evt_hw_error(uint8_t *buffer_in, aci_evt_params_hw_error_t *p_aci_evt_params_hw_error);
+
+/** @brief Decode the ACI event data credit
+ *
+ *  @param[in]      buffer_in                 Pointer to message received
+ *  @param[in,out]  p_evt_params_data_credit  Pointer to the decoded message in ::aci_evt_params_data_credit_t
+ *
+ *  @return         None
+ */
+void acil_decode_evt_credit(uint8_t *buffer_in, aci_evt_params_data_credit_t *p_evt_params_data_credit);
+
+/** @brief Decode the ACI event for connected
+ *
+ *  @param[in]      buffer_in                   Pointer to message received
+ *  @param[in,out]  p_aci_evt_params_connected  Pointer to the decoded message in ::aci_evt_params_connected_t
+ *
+ *  @return         None
+ */
+void acil_decode_evt_connected(uint8_t *buffer_in, aci_evt_params_connected_t *p_aci_evt_params_connected);
+
+/** @brief Decode the ACI event for timing
+ *
+ *  @param[in]      buffer_in             Pointer to message received
+ *  @param[in,out]  p_evt_params_timing   Pointer to the decoded message in ::aci_evt_params_timing_t
+ *
+ *  @return         None
+ */
+void acil_decode_evt_timing(uint8_t *buffer_in, aci_evt_params_timing_t *p_evt_params_timing);
+
+/** @brief Decode the ACI event for pipe error
+ *
+ *  @param[in]      buffer_in                 Pointer to message received
+ *  @param[in,out]  p_evt_params_pipe_error   Pointer to the decoded message in ::aci_evt_params_pipe_error_t
+ *
+ */
+void acil_decode_evt_pipe_error(uint8_t *buffer_in, aci_evt_params_pipe_error_t *p_evt_params_pipe_error);
+
+/** @brief Decode the ACI event for key request
+ *
+ *  @param[in]      buffer_in               Pointer to message received
+ *  @param[in,out]  p_evt_params_key_type   Pointer to the decoded message in ::aci_evt_params_key_type_t
+ *
+ *  @return         None
+ */
+void acil_decode_evt_key_request(uint8_t *buffer_in, aci_evt_params_key_request_t *p_evt_params_key_request);
+
+/** @brief Decode the ACI event for echo
+ *
+ *  @param[in]      buffer_in    Pointer to message received
+ *  @param[in,out]  buffer_out   Pointer to the echo message (max size of buffer ::ACI_ECHO_DATA_MAX_LEN)
+ *
+ *  @return         size         Received echo message size
+ */
+uint8_t acil_decode_evt_echo(uint8_t *buffer_in, aci_evt_params_echo_t *buffer_out);
+
+/** @brief Decode the ACI event
+ *
+ *  @param[in]      buffer_in   Pointer to message received
+ *  @param[in,out]  p_aci_evt   Pointer to the decoded message in ::aci_evt_t
+ *
+ *  @return         bool         true, if succesful, else returns false
+ */
+bool acil_decode_evt(uint8_t *buffer_in, aci_evt_t *p_aci_evt);
+
+/** @brief Decode the Display Key Event
+ *
+ *  @param[in]      buffer_in   Pointer to message received
+ *  @param[in,out]  p_aci_evt   Pointer to the decoded message in ::aci_evt_params_display_passkey_t
+ *
+ *  @return         None
+ */
+void acil_decode_evt_display_passkey(uint8_t *buffer_in, aci_evt_params_display_passkey_t *p_aci_evt_params_display_passkey);
+
+#endif /* _acilib_IF_H_ */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/ble_shield2.1/utility/acilib_types.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/ble_shield2.1/utility/acilib_types.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/ble_shield2.1/utility/acilib_types.h	(revision 457)
@@ -0,0 +1,33 @@
+/* Copyright (c) 2014, Nordic Semiconductor ASA
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+/**
+ * @file
+ *
+ * @ingroup group_acilib
+ *
+ * @brief Type used in the acilib interfaces
+ */
+
+#ifndef _acilib_TYPES_H_
+#define _acilib_TYPES_H_
+
+#endif /* _acilib_TYPES_H_ */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/ble_shield2.1/utility/ble_assert.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/ble_shield2.1/utility/ble_assert.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/ble_shield2.1/utility/ble_assert.h	(revision 457)
@@ -0,0 +1,36 @@
+/* Copyright (c) 2014, Nordic Semiconductor ASA
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+ 
+ /** @file
+ * @brief Declaration of assert()
+ */
+ 
+ #ifndef BLE_ASSERT_H__
+ #define BLE_ASSERT_H__
+
+extern void __ble_assert(const char *file, uint16_t line);
+
+#define ble_assert(expr)              \
+  ((expr)                             \
+  ? ((void) 0)                        \
+  : __ble_assert (__FILE__, __LINE__))
+
+#endif /* BLE_ASSERT_H__ */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/ble_shield2.1/utility/boards.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/ble_shield2.1/utility/boards.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/ble_shield2.1/utility/boards.h	(revision 457)
@@ -0,0 +1,34 @@
+/* Copyright (c) 2014, Nordic Semiconductor ASA
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */ 
+
+/** @file
+ * @brief Defines for the different Bluetooth low energy boards
+ */
+ 
+#ifndef _BLE_BOARDS_H_
+#define _BLE_BOARDS_H_
+
+#define BOARD_DEFAULT               0 //Use this if you do not know the board you are using or you are creating a new one
+#define REDBEARLAB_SHIELD_V1_1      1 //Redbearlab Bluetooth low energy shield v1.1
+#define REDBEARLAB_SHIELD_V2012_07  1 //Identical to Redbearlab v1.1 shield
+#define REDBEARLAB_SHIELD_V2        0 //Redbearlab Bluetooth low energy shield v2.x - No special handling required for pin reset same as default
+
+#endif
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/ble_shield2.1/utility/dfu.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/ble_shield2.1/utility/dfu.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/ble_shield2.1/utility/dfu.c	(revision 457)
@@ -0,0 +1,375 @@
+#include <lib_aci.h>
+#include <ble_assert.h>
+#include <dfu.h>
+
+static uint8_t state = ST_ANY;
+static uint32_t firmware_len;
+static uint16_t notify_every;
+static uint32_t bytes_received;
+static uint16_t packets_received;
+
+static void dfu_notify (aci_state_t *aci_state);
+static bool dfu_send (aci_state_t *aci_state, uint8_t *buffer, uint8_t buffer_len);
+
+static uint8_t dfu_data_pkt_handle (aci_state_t *aci_state, aci_evt_t *aci_evt);
+static uint8_t dfu_init_pkt_handle (aci_state_t *aci_state, aci_evt_t *aci_evt);
+static uint8_t dfu_image_activate  (aci_state_t *aci_state, aci_evt_t *aci_evt);
+static uint8_t dfu_image_size_set (aci_state_t *aci_state, aci_evt_t *aci_evt);
+static uint8_t dfu_image_validate  (aci_state_t *aci_state, aci_evt_t *aci_evt);
+
+#define DEBUG
+
+enum
+{
+    OP_CODE_START_DFU            = 1,                                               /**< Value of the Op code field for 'Start DFU' command.*/
+    OP_CODE_RECEIVE_INIT         = 2,                                               /**< Value of the Op code field for 'Initialize DFU parameters' command.*/
+    OP_CODE_RECEIVE_FW           = 3,                                               /**< Value of the Op code field for 'Receive firmware image' command.*/
+    OP_CODE_VALIDATE             = 4,                                               /**< Value of the Op code field for 'Validate firmware' command.*/
+    OP_CODE_ACTIVATE_N_RESET     = 5,                                               /**< Value of the Op code field for 'Activate & Reset' command.*/
+    OP_CODE_SYS_RESET            = 6,                                               /**< Value of the Op code field for 'Reset System' command.*/
+    OP_CODE_IMAGE_SIZE_REQ       = 7,                                               /**< Value of the Op code field for 'Report received image size' command.*/
+    OP_CODE_PKT_RCPT_NOTIF_REQ   = 8,                                               /**< Value of the Op code field for 'Request packet receipt notification.*/
+    OP_CODE_RESPONSE             = 16,                                              /**< Value of the Op code field for 'Response.*/
+    OP_CODE_PKT_RCPT_NOTIF       = 17                                               /**< Value of the Op code field for 'Packets Receipt Notification'.*/
+};
+
+/* State transitions */
+
+static uint8_t dfu_begin_init (aci_state_t *aci_state, aci_evt_t *aci_evt)
+{
+  ble_assert (aci_state != NULL);
+  ble_assert (aci_evt != NULL);
+  ble_assert (state == ST_RDY);
+
+  return ST_RX_INIT_PKT;
+}
+
+static uint8_t dfu_begin_transfer (aci_state_t *aci_state, aci_evt_t *aci_evt)
+{
+  ble_assert (aci_state != NULL);
+  ble_assert (aci_evt != NULL);
+  ble_assert ((state == ST_RDY) | (state == ST_RX_INIT_PKT));
+
+  return ST_RX_DATA_PKT;
+}
+
+static uint8_t dfu_data_pkt_handle (aci_state_t *aci_state, aci_evt_t *aci_evt)
+{
+  static uint8_t response[3] = {OP_CODE_RESPONSE, BLE_DFU_RECEIVE_APP_PROCEDURE, BLE_DFU_RESP_VAL_SUCCESS};
+
+  ble_assert (aci_state != NULL);
+  ble_assert (aci_evt != NULL);
+  ble_assert (state == ST_RX_DATA_PKT);
+
+  bytes_received += aci_evt->len-2;
+  packets_received++;
+
+  /* Send notification for every N packets */
+  if (0 == (packets_received % notify_every))
+  {
+      #ifdef DEBUG
+      Serial.println(F(" Writing notification"));
+      #endif DEBUG
+
+      dfu_notify (aci_state);
+  }
+
+  if (firmware_len == bytes_received)
+  {
+    #ifdef DEBUG
+    Serial.print(F(" All bytes received ("));
+    Serial.print(bytes_received, DEC);
+    Serial.println(F(")"));
+    #endif
+
+    dfu_send (aci_state, response, 3);
+  }
+
+  return ST_RX_DATA_PKT;
+}
+
+static uint8_t dfu_image_size_set(aci_state_t *aci_state, aci_evt_t *aci_evt)
+{
+  static uint8_t response[3] = {OP_CODE_RESPONSE, BLE_DFU_START_PROCEDURE, BLE_DFU_RESP_VAL_SUCCESS};
+
+  ble_assert (aci_state != NULL);
+  ble_assert (aci_evt != NULL);
+  ble_assert (state == ST_IDLE);
+
+  firmware_len = (uint32_t)aci_evt->params.data_received.rx_data.aci_data[3] << 24 |
+                 (uint32_t)aci_evt->params.data_received.rx_data.aci_data[2] << 16 |
+                 (uint32_t)aci_evt->params.data_received.rx_data.aci_data[1] << 8  |
+                 (uint32_t)aci_evt->params.data_received.rx_data.aci_data[0];
+
+  #ifdef DEBUG
+  Serial.print(F("Received length: "));
+  Serial.println(firmware_len, DEC);
+  #endif
+
+  /* Write response */
+  dfu_send (aci_state, response, 3);
+
+  return ST_RDY;
+}
+
+static uint8_t dfu_image_activate(aci_state_t *aci_state, aci_evt_t *aci_evt)
+{
+  ble_assert (aci_state != NULL);
+  ble_assert (aci_evt != NULL);
+  ble_assert (state == ST_FW_VALID);
+
+  lib_aci_disconnect(aci_state, ACI_REASON_TERMINATE);
+
+  return ST_FW_VALID;
+}
+
+static uint8_t dfu_init_pkt_handle (aci_state_t *aci_state, aci_evt_t *aci_evt)
+{
+  ble_assert (aci_state != NULL);
+  ble_assert (aci_evt != NULL);
+  ble_assert (state == ST_RX_INIT_PKT);
+
+  return ST_RX_INIT_PKT;
+}
+
+static uint8_t dfu_image_validate (aci_state_t *aci_state, aci_evt_t *aci_evt)
+{
+  uint8_t new_state;
+  uint8_t response[3] = {OP_CODE_RESPONSE, BLE_DFU_VALIDATE_PROCEDURE};
+
+  ble_assert (aci_state != NULL);
+  ble_assert (aci_evt != NULL);
+  ble_assert (state == ST_RX_DATA_PKT);
+
+  /* TODO: Implement CRC validation */
+  if (bytes_received == firmware_len)
+  {
+    #ifdef DEBUG
+    Serial.println(F(" Validation successful"));
+    #endif
+    /* Completed successfully */
+    response[3] = BLE_DFU_RESP_VAL_SUCCESS;
+    dfu_send(aci_state, response, 3);
+
+    state = ST_FW_VALID;
+  }
+  else
+  {
+    #ifdef DEBUG
+    Serial.println(F(" Validation failed"));
+    #endif
+
+    /* CRC error */
+    response[3] = BLE_DFU_RESP_VAL_CRC_ERROR;
+    dfu_send(aci_state, response, 3);
+
+    state = ST_FW_VALID;
+  }
+
+  return state;
+}
+
+static uint8_t dfu_notification_set (aci_state_t *aci_state, aci_evt_t *aci_evt)
+{
+  ble_assert (aci_state != NULL);
+  ble_assert (aci_evt != NULL);
+
+  notify_every = (uint16_t)aci_evt->params.data_received.rx_data.aci_data[2] << 8 |
+                 (uint16_t)aci_evt->params.data_received.rx_data.aci_data[1];
+
+
+
+  #ifdef DEBUG
+  Serial.print(F(" Remote device requested notification every "));
+  Serial.print(notify_every, DEC);
+  Serial.println(F(" packets"));
+  #endif
+
+  return state;
+}
+
+dfu_transition_t trans[] = {
+	{ ST_IDLE,		    BLE_DFU_PACKET_WRITE,            &dfu_image_size_set          },
+	{ ST_RDY,		      BLE_DFU_RECEIVE_INIT_DATA,       &dfu_begin_init              },
+	{ ST_RX_INIT_PKT, BLE_DFU_PACKET_WRITE,            &dfu_init_pkt_handle         },
+  { ST_RDY,		      BLE_DFU_RECEIVE_APP_DATA,        &dfu_begin_transfer          },
+  { ST_RX_INIT_PKT,	BLE_DFU_RECEIVE_APP_DATA,        &dfu_begin_transfer          },
+	{ ST_RX_DATA_PKT,	BLE_DFU_PACKET_WRITE,            &dfu_data_pkt_handle         },
+  { ST_RX_DATA_PKT,	BLE_DFU_VALIDATE,                &dfu_image_validate          },
+  { ST_FW_VALID,    BLE_DFU_SYS_RESET,               &dfu_image_activate          },
+  { ST_FW_VALID,    BLE_DFU_ACTIVATE_N_RESET,        &dfu_image_activate          },
+  { ST_ANY,         BLE_DFU_PKT_RCPT_NOTIF_ENABLED,  &dfu_notification_set        },
+  { ST_ANY,         BLE_DFU_PKT_RCPT_NOTIF_DISABLED, &dfu_notification_set        }
+};
+
+#define TRANS_COUNT (sizeof(trans)/sizeof(*trans))
+
+/* Write receive notification */
+static void dfu_notify (aci_state_t *aci_state)
+{
+  uint8_t response[6] = {OP_CODE_PKT_RCPT_NOTIF,
+                         0,
+                         (uint8_t) bytes_received,
+                         (uint8_t) (bytes_received >> 8),
+                         (uint8_t) (bytes_received >> 16),
+                         (uint8_t) (bytes_received >> 24)
+                         };
+
+  ble_assert (aci_state != NULL);
+
+  dfu_send (aci_state, response, 6);
+}
+
+static bool dfu_send (aci_state_t *aci_state, uint8_t *buffer, uint8_t buffer_len)
+{
+	bool status = false;
+
+  ble_assert (aci_state != NULL);
+  ble_assert (buffer != NULL);
+
+	if (lib_aci_is_pipe_available(aci_state,
+                                PIPE_DEVICE_FIRMWARE_UPDATE_BLE_SERVICE_DFU_CONTROL_POINT_TX) &&
+                                (aci_state->data_credit_available >= 1))
+	{
+		status = lib_aci_send_data(PIPE_DEVICE_FIRMWARE_UPDATE_BLE_SERVICE_DFU_CONTROL_POINT_TX,
+                               buffer,
+                               buffer_len);
+		if (status)
+		{
+			aci_state->data_credit_available--;
+		}
+	}
+
+	return status;
+}
+
+static uint8_t dfu_get_event (aci_state_t *aci_state, aci_evt_t *aci_evt)
+{
+  uint8_t event;
+
+  ble_assert (aci_state != NULL);
+  ble_assert (aci_evt != NULL);
+
+  switch (aci_evt->params.data_received.rx_data.pipe_number)
+  {
+    case PIPE_DEVICE_FIRMWARE_UPDATE_BLE_SERVICE_DFU_PACKET_RX:
+      event = BLE_DFU_PACKET_WRITE;
+      break;
+
+    case PIPE_DEVICE_FIRMWARE_UPDATE_BLE_SERVICE_DFU_CONTROL_POINT_RX_ACK_AUTO:
+      #ifdef DEBUG
+      Serial.print(F("PIPE_DEVICE_FIRMWARE_UPDATE_BLE_SERVICE_DFU_CONTROL_POINT_RX_ACK_AUTO. Opcode: "));
+      Serial.println(aci_evt->params.data_received.rx_data.aci_data[0], DEC);
+      #endif
+
+      switch (aci_evt->params.data_received.rx_data.aci_data[0])
+      {
+        /* Start DFU */
+        case OP_CODE_START_DFU:
+          event = BLE_DFU_START;
+          break;
+
+        /* Initialize DFU parameters */
+        case OP_CODE_RECEIVE_INIT:
+          event = BLE_DFU_RECEIVE_INIT_DATA;
+          break;
+
+        /* Receive firmware image */
+        case OP_CODE_RECEIVE_FW:
+          event = BLE_DFU_RECEIVE_APP_DATA;
+          break;
+
+        /* Validate firmware image */
+        case OP_CODE_VALIDATE:
+          event = BLE_DFU_VALIDATE;
+          break;
+
+        /* Activate image and reset */
+        case OP_CODE_ACTIVATE_N_RESET:
+          event = BLE_DFU_ACTIVATE_N_RESET;
+          break;
+
+        /* Reset system */
+        case OP_CODE_SYS_RESET:
+          event = BLE_DFU_SYS_RESET;
+          break;
+
+        /* Report received image size */
+        case OP_CODE_IMAGE_SIZE_REQ:
+          event = BLE_DFU_BYTES_RECEIVED_SEND;
+          break;
+
+        /* Packet receipt notification request */
+        case OP_CODE_PKT_RCPT_NOTIF_REQ:
+          if (aci_evt->params.data_received.rx_data.aci_data[1] == 0)
+          {
+            event = BLE_DFU_PKT_RCPT_NOTIF_DISABLED;
+          }
+          else
+          {
+            event = BLE_DFU_PKT_RCPT_NOTIF_ENABLED;
+          }
+          break;
+
+        default:
+          event = EV_ANY;
+          break;
+      }
+      break;
+
+    default:
+      event = EV_ANY;
+  }
+  return event;
+}
+
+void dfu_initialize (void)
+{
+  #ifdef DEBUG
+  Serial.println(F(" Initializing DFU state machine"));
+  #endif
+
+  if (true)
+  {
+    state = ST_IDLE;
+  }
+  else
+  {
+    state = ST_INIT_ERROR;
+  }
+}
+
+void dfu_update (aci_state_t *aci_state, aci_evt_t *aci_evt)
+{
+  hal_aci_evt_t aci_data;
+  uint8_t event;
+  uint8_t i;
+
+  ble_assert (aci_state != NULL);
+  ble_assert (aci_evt != NULL);
+
+  event = dfu_get_event(aci_state, aci_evt);
+
+  for (i = 0; i < TRANS_COUNT; i++)
+	{
+    if ((state == trans[i].st) || (ST_ANY == trans[i].st))
+		{
+		  if ((event == trans[i].ev) || (EV_ANY == trans[i].ev))
+			{
+        #ifdef DEBUG
+        Serial.print(F("Transition (state = "));
+        Serial.print(trans[i].st);
+        Serial.print(F(", event = "));
+        Serial.print(trans[i].ev);
+        Serial.println(F(")"));
+        #endif
+
+        state = (trans[i].fn)(aci_state, aci_evt);
+        return;
+      }
+    }
+  }
+
+  /* Unhandled event */
+  ble_assert(false);
+}
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/ble_shield2.1/utility/dfu.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/ble_shield2.1/utility/dfu.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/ble_shield2.1/utility/dfu.h	(revision 457)
@@ -0,0 +1,87 @@
+#ifndef DFU_H_
+#define DFU_H_
+
+#define ST_IDLE		          0
+#define ST_INIT_ERROR       1
+#define ST_RDY		          2
+#define ST_RX_INIT_PKT	    3
+#define ST_RX_DATA_PKT	    4
+#define ST_FW_VALID         5
+#define ST_FW_INVALID       6
+#define ST_ANY	  	        255
+
+#define EV_ANY              255
+
+#define PIPE_DEVICE_FIRMWARE_UPDATE_BLE_SERVICE_DFU_PACKET_RX                   8
+#define PIPE_DEVICE_FIRMWARE_UPDATE_BLE_SERVICE_DFU_CONTROL_POINT_TX            9
+#define PIPE_DEVICE_FIRMWARE_UPDATE_BLE_SERVICE_DFU_CONTROL_POINT_RX_ACK_AUTO   10
+
+/**@brief   DFU Event type.
+ *
+ * @details This enumeration contains the types of events that will be received from the DFU Service.
+ */
+typedef enum
+{
+    BLE_DFU_START                      = 1,                            /**< The event indicating that the peer wants the application to prepare for a new firmware update. */
+    BLE_DFU_RECEIVE_INIT_DATA          = 2,                            /**< The event indicating that the peer wants the application to prepare to receive init parameters. */
+    BLE_DFU_RECEIVE_APP_DATA           = 3,                            /**< The event indicating that the peer wants the application to prepare to receive the new firmware image. */
+    BLE_DFU_VALIDATE                   = 4,                            /**< The event indicating that the peer wants the application to validate the newly received firmware image. */
+    BLE_DFU_ACTIVATE_N_RESET           = 5,                            /**< The event indicating that the peer wants the application to undergo activate new firmware and restart with new valid application */
+    BLE_DFU_SYS_RESET                  = 6,                            /**< The event indicating that the peer wants the application to undergo a reset and start the currently valid application image.*/
+    BLE_DFU_PKT_RCPT_NOTIF_ENABLED     = 7,                            /**< The event indicating that the peer has enabled packet receipt notifications. It is the responsibility of the application to call @ref ble_dfu_pkts_rcpt_notify each time the number of packets indicated by num_of_pkts field in @ref ble_dfu_evt_t is received.*/
+    BLE_DFU_PKT_RCPT_NOTIF_DISABLED    = 8,                            /**< The event indicating that the peer has disabled the packet receipt notifications.*/
+    BLE_DFU_PACKET_WRITE               = 9,                            /**< The event indicating that the peer has written a value to the 'DFU Packet' characteristic. The data received from the peer will be present in the @ref ble_dfu_pkt_write element contained within @ref ble_dfu_evt_t.*/
+    BLE_DFU_BYTES_RECEIVED_SEND        = 10                            /**< The event indicating that the peer is requesting for the number of bytes of firmware data last received by the application. It is the responsibility of the application to call @ref ble_dfu_pkts_rcpt_notify in response to this event. */
+} ble_dfu_evt_type_t;
+
+/**@brief   DFU Procedure type.
+ *
+ * @details This enumeration contains the types of DFU procedures.
+ */
+typedef enum
+{
+    BLE_DFU_START_PROCEDURE        = 1,                                 /**< DFU Start procedure.*/
+    BLE_DFU_INIT_PROCEDURE         = 2,                                 /**< DFU Initialization procedure.*/
+    BLE_DFU_RECEIVE_APP_PROCEDURE  = 3,                                 /**< Firmware receiving procedure.*/
+    BLE_DFU_VALIDATE_PROCEDURE     = 4,                                 /**< Firmware image validation procedure .*/
+    BLE_DFU_PKT_RCPT_REQ_PROCEDURE = 8                                  /**< Packet receipt notification request procedure. */
+} ble_dfu_procedure_t;
+
+/**@brief   DFU Response value type.
+ */
+typedef enum
+{
+    BLE_DFU_RESP_VAL_SUCCESS        = 1,                                /**< Success.*/
+    BLE_DFU_RESP_VAL_INVALID_STATE  = 2,                                /**< Invalid state.*/
+    BLE_DFU_RESP_VAL_NOT_SUPPORTED  = 3,                                /**< Operation not supported.*/
+    BLE_DFU_RESP_VAL_DATA_SIZE      = 4,                                /**< Data size exceeds limit.*/
+    BLE_DFU_RESP_VAL_CRC_ERROR      = 5,                                /**< CRC Error.*/
+    BLE_DFU_RESP_VAL_OPER_FAILED    = 6,                                /**< Operation failed.*/
+} ble_dfu_resp_val_t;
+
+/**
+ *  @brief FSM transition
+ *
+ * Struct that describes a transition in the FSM.
+ */
+typedef struct
+{   /**
+	 * @brief State
+	 */
+	uint8_t st;
+
+    /**
+	 * @brief Event
+	 */
+	uint8_t ev;
+
+    /**
+	 * @brief Transition function
+	 */
+	uint8_t (*fn)(aci_state_t *aci_state, aci_evt_t *aci_evt);
+} dfu_transition_t;
+
+void dfu_initialize (void);
+void dfu_update (aci_state_t *aci_state, aci_evt_t *aci_evt);
+
+#endif /* DFU_H_ */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/ble_shield2.1/utility/dtm.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/ble_shield2.1/utility/dtm.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/ble_shield2.1/utility/dtm.h	(revision 457)
@@ -0,0 +1,63 @@
+/* Copyright (c) 2014, Nordic Semiconductor ASA
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+/**
+ * @file
+ *
+ * @ingroup group_acilib
+ *
+ * @brief Internal prototype for acilib module.
+ */
+
+#ifndef DTM_H__
+#define DTM_H__
+
+/** @brief DTM command codes (upper two bits in the DTM command), use a bitwise OR with the frequency N = 0x00 - 0x27: N = (F-2402)/2 Frequency Range 2402 MHz
+to 2480 MHz*/
+#define DTM_LE_CMD_RESET            0x00
+#define DTM_LE_CMD_RECEIVER_TEST    0x40
+#define DTM_LE_CMD_TRANSMITTER_TEST 0x80
+#define DTM_LE_CMD_TEST_END         0xC0
+
+
+/** @brief Defined packet types for DTM */
+#define DTM_LE_PKT_PRBS9      0x00       /**< Bit pattern PRBS9.    */
+#define DTM_LE_PKT_0X0F       0x01       /**< Bit pattern 11110000 (LSB is the leftmost bit). */
+#define DTM_LE_PKT_0X55       0x02       /**< Bit pattern 10101010 (LSB is the leftmost bit). */
+#define DTM_LE_PKT_VENDOR     0x03       /**< Vendor specific. Nordic: continous carrier test */
+
+/** @brief Defined bit fields for DTM responses. */
+#define LE_PACKET_REPORTING_EVENT_MSB_BIT   0x80
+#define LE_TEST_STATUS_EVENT_LSB_BIT        0x01
+
+/** @brief DTM response types. */
+#define LE_TEST_STATUS_EVENT                0x00
+#define LE_TEST_PACKET_REPORT_EVENT         0x80
+
+/** @brief DTM return values. */
+#define LE_TEST_STATUS_SUCCESS              0x00
+#define LE_TEST_STATUS_FAILURE              0x01
+
+
+
+#endif //DTM_H__
+
+/** @} */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/ble_shield2.1/utility/hal_aci_tl.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/ble_shield2.1/utility/hal_aci_tl.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/ble_shield2.1/utility/hal_aci_tl.c	(revision 457)
@@ -0,0 +1,525 @@
+/* Copyright (c) 2014, Nordic Semiconductor ASA
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+/** @file
+@brief Implementation of the ACI transport layer module
+*/
+
+#include "hal_platform.h"
+#include "hal_aci_tl.h"
+#include "aci_queue.h"
+
+/*
+PIC32 supports only MSbit transfer on SPI and the nRF8001 uses LSBit
+Use the REVERSE_BITS macro to convert from MSBit to LSBit
+The outgoing command and the incoming event needs to be converted
+*/
+//Board dependent defines
+//For ChipKit as the transmission has to be reversed, the next definitions have to be added
+#ifdef __STM32__
+#define REVERSE_BITS(byte) (byte)
+#else
+#define REVERSE_BITS(byte) (((reverse_lookup[(byte & 0x0F)]) << 4) + reverse_lookup[((byte & 0xF0) >> 4)])
+static const uint8_t reverse_lookup[] = { 0, 8,  4, 12, 2, 10, 6, 14,1, 9, 5, 13,3, 11, 7, 15 };
+#endif
+
+static void m_aci_data_print(hal_aci_data_t *p_data);
+static void m_aci_event_check(void);
+static void m_aci_pins_set(aci_pins_t *a_pins_ptr);
+static inline void m_aci_reqn_disable (void);
+static inline void m_aci_reqn_enable (void);
+static void m_aci_q_flush(void);
+static bool m_aci_spi_transfer(hal_aci_data_t * data_to_send, hal_aci_data_t * received_data);
+
+static uint8_t        spi_readwrite(uint8_t aci_byte);
+
+
+static bool           aci_debug_print = false;
+
+aci_queue_t    aci_tx_q;
+aci_queue_t    aci_rx_q;
+
+static aci_pins_t	 *a_pins_local_ptr;
+
+static SPI_Handle_t *hspi;
+static int evt_taskid;
+static int aci_activate;
+
+/* Buffer used for transmission */
+uint8_t aTxBuffer[4];
+
+/* Buffer used for reception */
+uint8_t aRxBuffer[4];
+
+static uint8_t spi_transfer(uint8_t a)
+{
+  ER ercd;
+
+  aTxBuffer[0] = a;
+#if SPI_WAIT_TIME != 0
+  ercd = spi_transrecv(hspi, (uint8_t*)aTxBuffer, (uint8_t *)aRxBuffer, 1);
+#else
+  if((ercd = spi_transrecv(hspi, (uint8_t*)aTxBuffer, (uint8_t *)aRxBuffer, 1)) == E_OK)
+    ercd = spi_wait(hspi, 100);
+#endif
+  if(ercd != E_OK){
+    /* Transfer error in transmission process */
+    syslog_1(LOG_NOTICE, "## call Error_Handler(2)(%d) ##", ercd);
+  }
+  return aRxBuffer[0];
+}
+
+/*
+ *  GPIO設定関数
+ */
+static void pinMode(uint32_t no, int mode)
+{
+  Arduino_PortControlBlock *ppcb = getGpioTable(DIGITAL_PIN, no);
+  GPIO_Init_t GPIO_Init_Data;
+
+  syslog_2(LOG_NOTICE, "## pinMode(%d, %d) ##", no, mode);
+  syslog_2(LOG_NOTICE, "## [%08x](%d) ##", ppcb->giobase, ppcb->giopin);
+  if(ppcb == NULL)
+    return;
+  pinClock(no);
+  if(mode == OUTPUT){
+    GPIO_Init_Data.mode      = GPIO_MODE_OUTPUT;
+    GPIO_Init_Data.pull      = GPIO_PULLUP;
+    GPIO_Init_Data.otype     = GPIO_OTYPE_PP;
+#ifdef TOPPERS_BASE_PLATFORM_RV
+	GPIO_Init_Data.oxor  = GPIO_OUTPUT_NORMAL;
+	GPIO_Init_Data.iof   = GPIO_NOIOF;
+#else
+    GPIO_Init_Data.speed     = GPIO_SPEED_FAST;
+#endif
+    gpio_setup(ppcb->giobase, &GPIO_Init_Data, ppcb->giopin);
+  }
+  else{
+    GPIO_Init_Data.mode      = GPIO_MODE_IT_RISING_FALLING;
+    if(mode == INPUT_PULLUP)
+      GPIO_Init_Data.pull    = GPIO_PULLUP;
+    else
+      GPIO_Init_Data.pull    = GPIO_NOPULL;
+    gpio_setup(ppcb->giobase, &GPIO_Init_Data, ppcb->giopin);
+  }
+}
+
+void m_aci_data_print(hal_aci_data_t *p_data)
+{
+  const uint8_t length = p_data->buffer[0];
+  uint8_t i, j, len, data[5];
+
+  len = length % 5;
+  if(len == 0)
+    len = length;
+  else
+    len = length + 5 - len;
+  for (i=j=0; i< len; i++){
+    if(i < length)
+      data[j] = p_data->buffer[i+1];
+    else
+      data[j] = 0xff;
+    if(j == 4){
+       syslog_5(LOG_NOTICE, "%02x, %02x, %02x, %02x, %02x,", data[0], data[1], data[2], data[3], data[4]);
+       j = 0;
+    }
+    else
+       j++;
+  }
+}
+
+/*
+  Interrupt service routine called when the RDYN line goes low. Runs the SPI transfer.
+*/
+void
+m_aci_isr(void)
+{
+  if(aci_activate == 0){
+    if(evt_taskid != 0)
+      iact_tsk(evt_taskid);
+    else
+      aci_task(0);
+  }
+}
+
+void aci_task(int arg)
+{
+  hal_aci_data_t data_to_send;
+  hal_aci_data_t received_data;
+#ifdef NOACT_TASK	/* ROI DEBUG */
+	syslog_1(LOG_NOTICE, "## aci_task(%d) ##", arg);
+#endif	/* ROI DEBUG */
+
+  aci_activate = 1;
+  // Receive from queue
+  if (!aci_queue_dequeue/*_from_isr*/(&aci_tx_q, &data_to_send))
+  {
+    /* queue was empty, nothing to send */
+    data_to_send.status_byte = 0;
+    data_to_send.buffer[0] = 0;
+  }
+
+  // Receive and/or transmit data
+  if(!m_aci_spi_transfer(&data_to_send, &received_data)){
+    m_aci_reqn_enable();
+    aci_activate = 0;
+    return;
+  }
+
+  if (!aci_queue_is_full/*_from_isr*/(&aci_rx_q) && !aci_queue_is_empty/*_from_isr*/(&aci_tx_q))
+  {
+    m_aci_reqn_enable();
+  }
+
+  // Check if we received data
+  if (received_data.buffer[0] > 0)
+  {
+    if (!aci_queue_enqueue/*_from_isr*/(&aci_rx_q, &received_data))
+    {
+      /* Receive Buffer full.
+         Should never happen.
+         Spin in a while loop.
+      */
+      syslog_0(LOG_ERROR, "aci_task Buffer full !");
+      while(1);
+    }
+  }
+  aci_activate = 0;
+
+  return;
+}
+
+/*
+  Checks the RDYN line and runs the SPI transfer if required.
+*/
+static void m_aci_event_check(void)
+{
+  hal_aci_data_t data_to_send;
+  hal_aci_data_t received_data;
+
+  // No room to store incoming messages
+  if (aci_queue_is_full(&aci_rx_q))
+  {
+    return;
+  }
+
+  // If the ready line is disabled and we have pending messages outgoing we enable the request line
+  if (HIGH == digitalRead(a_pins_local_ptr->rdyn_pin))
+  {
+    if (!aci_queue_is_empty(&aci_tx_q))
+    {
+      m_aci_reqn_enable();
+    }
+
+    return;
+  }
+
+  // Receive from queue
+  if (!aci_queue_dequeue(&aci_tx_q, &data_to_send))
+  {
+    /* queue was empty, nothing to send */
+    data_to_send.status_byte = 0;
+    data_to_send.buffer[0] = 0;
+  }
+
+  // Receive and/or transmit data
+  m_aci_spi_transfer(&data_to_send, &received_data);
+
+  /* If there are messages to transmit, and we can store the reply, we request a new transfer */
+  if (!aci_queue_is_full(&aci_rx_q) && !aci_queue_is_empty(&aci_tx_q))
+  {
+    m_aci_reqn_enable();
+  }
+
+  // Check if we received data
+  if (received_data.buffer[0] > 0)
+  {
+    if (!aci_queue_enqueue(&aci_rx_q, &received_data))
+    {
+      /* Receive Buffer full.
+         Should never happen.
+         Spin in a while loop.
+      */
+      syslog_0(LOG_ERROR, "m_aci_event_check Buffer full !");
+      while(1);
+    }
+  }
+
+  return;
+}
+
+/** @brief Point the low level library at the ACI pins specified
+ *  @details
+ *  The ACI pins are specified in the application and a pointer is made available for
+ *  the low level library to use
+ */
+static void m_aci_pins_set(aci_pins_t *a_pins_ptr)
+{
+  a_pins_local_ptr = a_pins_ptr;
+}
+
+static inline void m_aci_reqn_disable (void)
+{
+  digitalWrite(a_pins_local_ptr->reqn_pin, 1);
+}
+
+static inline void m_aci_reqn_enable (void)
+{
+  digitalWrite(a_pins_local_ptr->reqn_pin, 0);
+}
+
+static void m_aci_q_flush(void)
+{
+  noInterrupts();
+  /* re-initialize aci cmd queue and aci event queue to flush them*/
+  aci_queue_init(&aci_tx_q);
+  aci_queue_init(&aci_rx_q);
+  interrupts();
+}
+
+static bool m_aci_spi_transfer(hal_aci_data_t * data_to_send, hal_aci_data_t * received_data)
+{
+  uint8_t byte_cnt;
+  uint8_t byte_sent_cnt;
+  uint8_t max_bytes;
+
+  m_aci_reqn_enable();
+
+  // Send length, receive header
+  byte_sent_cnt = 0;
+  received_data->status_byte = spi_readwrite(data_to_send->buffer[byte_sent_cnt++]);
+  // Send first byte, receive length from slave
+  received_data->buffer[0] = spi_readwrite(data_to_send->buffer[byte_sent_cnt++]);
+  if(received_data->buffer[0] == 0xff)
+    return false;
+  if (0 == data_to_send->buffer[0])
+  {
+    max_bytes = received_data->buffer[0];
+  }
+  else
+  {
+    // Set the maximum to the biggest size. One command byte is already sent
+    max_bytes = (received_data->buffer[0] > (data_to_send->buffer[0] - 1))
+                                          ? received_data->buffer[0]
+                                          : (data_to_send->buffer[0] - 1);
+  }
+
+  if (max_bytes > HAL_ACI_MAX_LENGTH)
+  {
+    max_bytes = HAL_ACI_MAX_LENGTH;
+  }
+
+  // Transmit/receive the rest of the packet
+  for (byte_cnt = 0; byte_cnt < max_bytes; byte_cnt++)
+  {
+    received_data->buffer[byte_cnt+1] =  spi_readwrite(data_to_send->buffer[byte_sent_cnt++]);
+  }
+
+  // RDYN should follow the REQN line in approx 100ns
+  m_aci_reqn_disable();
+
+  return (max_bytes > 0);
+}
+
+void hal_aci_tl_debug_print(bool enable)
+{
+	aci_debug_print = enable;
+}
+
+void hal_aci_tl_pin_reset(void)
+{
+    if (UNUSED != a_pins_local_ptr->reset_pin)
+    {
+        pinMode(a_pins_local_ptr->reset_pin, OUTPUT);
+
+        if ((REDBEARLAB_SHIELD_V1_1     == a_pins_local_ptr->board_name) ||
+            (REDBEARLAB_SHIELD_V2012_07 == a_pins_local_ptr->board_name))
+        {
+            //The reset for the Redbearlab v1.1 and v2012.07 boards are inverted and has a Power On Reset
+            //circuit that takes about 100ms to trigger the reset
+            digitalWrite(a_pins_local_ptr->reset_pin, 1);
+            delay(100);
+            digitalWrite(a_pins_local_ptr->reset_pin, 0);
+        }
+        else
+        {
+            digitalWrite(a_pins_local_ptr->reset_pin, 1);
+            digitalWrite(a_pins_local_ptr->reset_pin, 0);
+            digitalWrite(a_pins_local_ptr->reset_pin, 1);
+        }
+    }
+}
+
+bool hal_aci_tl_event_peek(hal_aci_data_t *p_aci_data)
+{
+  if (!a_pins_local_ptr->interface_is_interrupt)
+  {
+    m_aci_event_check();
+  }
+
+  if (aci_queue_peek(&aci_rx_q, p_aci_data))
+  {
+    return true;
+  }
+
+  return false;
+}
+
+bool hal_aci_tl_event_get(hal_aci_data_t *p_aci_data)
+{
+  bool was_full;
+
+  if (!a_pins_local_ptr->interface_is_interrupt && !aci_queue_is_full(&aci_rx_q))
+  {
+    m_aci_event_check();
+  }
+
+  was_full = aci_queue_is_full(&aci_rx_q);
+
+  if (aci_queue_dequeue(&aci_rx_q, p_aci_data))
+  {
+    if (aci_debug_print)
+    {
+      syslog_1(LOG_NOTICE, "EVT %d:", p_aci_data->buffer[0]);
+      m_aci_data_print(p_aci_data);
+    }
+
+    /* Attempt to pull REQN LOW since we've made room for new messages */
+    if (!aci_queue_is_full(&aci_rx_q) && !aci_queue_is_empty(&aci_tx_q))
+    {
+      m_aci_reqn_enable();
+    }
+
+    return true;
+  }
+
+  (void)(was_full);
+  return false;
+}
+
+void hal_aci_tl_init(aci_pins_t *a_pins, bool debug)
+{
+  aci_debug_print = debug;
+
+  /* Needs to be called as the first thing for proper intialization*/
+  m_aci_pins_set(a_pins);
+
+  /*
+  The SPI lines used are mapped directly to the hardware SPI
+  MISO MOSI and SCK
+  Change here if the pins are mapped differently
+
+  The SPI library assumes that the hardware pins are used
+  */
+  hspi = a_pins->spihandle;
+  evt_taskid = a_pins->event_taskid;
+
+  /* Initialize the ACI Command queue. This must be called after the delay above. */
+  aci_queue_init(&aci_tx_q);
+  aci_queue_init(&aci_rx_q);
+
+  //Configure the IO lines
+  pinMode(a_pins->rdyn_pin,		INPUT_PULLUP);
+  pinMode(a_pins->reqn_pin,		OUTPUT);
+
+  if (UNUSED != a_pins->active_pin)
+  {
+    pinMode(a_pins->active_pin,	INPUT);
+  }
+  /* Pin reset the nRF8001, required when the nRF8001 setup is being changed */
+  hal_aci_tl_pin_reset();
+
+  /* Set the nRF8001 to a known state as required by the datasheet*/
+  digitalWrite(a_pins->reqn_pin, 1);
+
+  dly_tsk(30); //Wait for the nRF8001 to get hold of its lines - the lines float for a few ms after the reset
+}
+
+bool hal_aci_tl_send(hal_aci_data_t *p_aci_cmd)
+{
+  const uint8_t length = p_aci_cmd->buffer[0];
+  bool ret_val = false;
+
+  if (length > HAL_ACI_MAX_LENGTH)
+  {
+    return false;
+  }
+
+  ret_val = aci_queue_enqueue(&aci_tx_q, p_aci_cmd);
+  if (ret_val)
+  {
+    if(!aci_queue_is_full(&aci_rx_q))
+    {
+      // Lower the REQN only when successfully enqueued
+      m_aci_reqn_enable();
+    }
+
+    if (aci_debug_print)
+    {
+      syslog_1(LOG_NOTICE, "CMD %d:", p_aci_cmd->buffer[0]);
+      m_aci_data_print(p_aci_cmd);
+    }
+  }
+
+  return ret_val;
+}
+
+static uint8_t spi_readwrite(const uint8_t aci_byte)
+{
+  //Board dependent defines
+  //For ChipKit the transmission has to be reversed
+  uint8_t tmp_bits;
+  tmp_bits = spi_transfer(REVERSE_BITS(aci_byte));
+#if 0	/* ROI DEBUG */
+	{
+		uint32_t tim;
+		get_tim(&tim);
+		syslog_5(LOG_NOTICE, "## spi_readwrite in1[%02x] in2[%02x] out1[%02x] out2[%02x] tim(%d) ##", aci_byte, REVERSE_BITS(aci_byte), tmp_bits, REVERSE_BITS(tmp_bits), tim);
+	}
+#endif	/* ROI DEBUG */
+  return REVERSE_BITS(tmp_bits);
+}
+
+bool hal_aci_tl_rx_q_empty (void)
+{
+  return aci_queue_is_empty(&aci_rx_q);
+}
+
+bool hal_aci_tl_rx_q_full (void)
+{
+  return aci_queue_is_full(&aci_rx_q);
+}
+
+bool hal_aci_tl_tx_q_empty (void)
+{
+  return aci_queue_is_empty(&aci_tx_q);
+}
+
+bool hal_aci_tl_tx_q_full (void)
+{
+  return aci_queue_is_full(&aci_tx_q);
+}
+
+void hal_aci_tl_q_flush (void)
+{
+  m_aci_q_flush();
+}
+
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/ble_shield2.1/utility/hal_aci_tl.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/ble_shield2.1/utility/hal_aci_tl.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/ble_shield2.1/utility/hal_aci_tl.h	(revision 457)
@@ -0,0 +1,191 @@
+/* Copyright (c) 2014, Nordic Semiconductor ASA
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */ 
+
+/** @file
+ * @brief Interface for hal_aci_tl.
+ */
+ 
+/** @defgroup hal_aci_tl hal_aci_tl
+@{
+@ingroup hal
+ 
+@brief Module for the ACI Transport Layer interface
+@details This module is responsible for sending and receiving messages over the ACI interface of the nRF8001 chip.
+ The hal_aci_tl_send_cmd() can be called directly to send ACI commands.
+
+
+The RDYN line is hooked to an interrupt on the MCU when the level is low.
+The SPI master clocks in the interrupt context.
+The ACI Command is taken from the head of the command queue is sent over the SPI
+and the received ACI event is placed in the tail of the event queue.
+
+*/
+ 
+#ifndef HAL_ACI_TL_H__
+#define HAL_ACI_TL_H__
+
+#include "hal_platform.h"
+#include "aci.h"
+#include "boards.h"
+
+#ifndef HAL_ACI_MAX_LENGTH
+#define HAL_ACI_MAX_LENGTH 31
+#endif
+
+/************************************************************************/
+/* Unused nRF8001 pin                                                    */
+/************************************************************************/
+#define UNUSED		    255
+
+/** Data type for ACI commands and events */
+typedef struct {
+  uint8_t status_byte;
+  uint8_t buffer[HAL_ACI_MAX_LENGTH+1];
+} _aci_packed_ hal_aci_data_t;
+
+ACI_ASSERT_SIZE(hal_aci_data_t, HAL_ACI_MAX_LENGTH + 2);
+
+/** Datatype for ACI pins and interface (polling/interrupt)*/
+typedef struct aci_pins_t
+{
+	uint8_t board_name;             //Optional : Use BOARD_DEFAULT if you do not know. See boards.h
+	uint8_t	reqn_pin;				//Required
+	uint8_t	rdyn_pin;				//Required
+//	uint8_t	mosi_pin;				//Required
+//	uint8_t	miso_pin;				//Required
+//	uint8_t	sck_pin;				//Required
+	
+//	uint8_t spi_clock_divider;      //Required : Clock divider on the SPI clock : nRF8001 supports a maximum clock of 3MHz
+	void   *spihandle;				//Required
+	
+	uint8_t	reset_pin;				//Recommended but optional - Set it to UNUSED when not connected
+	uint8_t active_pin;				//Optional - Set it to UNUSED when not connected
+	uint8_t optional_chip_sel_pin;  //Optional - Used only when the reqn line is required to be separate from the SPI chip select. Eg. Arduino DUE
+	
+	bool	interface_is_interrupt;	//Required - true = Uses interrupt on RDYN pin. false - Uses polling on RDYN pin
+	
+//	uint8_t	interrupt_number;		//Required when using interrupts, otherwise ignored
+	int     event_taskid;			//Required event taskid
+} aci_pins_t;
+
+/** @brief ACI Transport Layer initialization.
+ *  @details
+ *  This function initializes the transport layer, including configuring the SPI, creating
+ *  message queues for Commands and Events and setting up interrupt if required.
+ *  @param a_pins Pins on the MCU used to connect to the nRF8001
+ *  @param bool True if debug printing should be enabled on the Serial.
+ */
+void hal_aci_tl_init(aci_pins_t *a_pins, bool debug);
+
+/** @brief Sends an ACI command to the radio.
+ *  @details
+ *  This function sends an ACI command to the radio. This queue up the message to send and 
+ *  lower the request line. When the device lowers the ready line, @ref m_aci_spi_transfer()
+ *  will send the data.
+ *  @param aci_buffer Pointer to the message to send.
+ *  @return True if the data was successfully queued for sending, 
+ *  false if there is no more space to store messages to send.
+ */
+bool hal_aci_tl_send(hal_aci_data_t *aci_buffer);
+
+/** @brief Process pending transactions.
+ *  @details 
+ *  The library code takes care of calling this function to check if the nRF8001 RDYN line indicates a
+ *  pending transaction. It will send a pending message if there is one and return any receive message
+ *  that was pending.
+ *  @return Points to data buffer for received data. Length byte in buffer is 0 if no data received.
+ */
+hal_aci_data_t * hal_aci_tl_poll_get(void);
+
+/** @brief Get an ACI event from the event queue
+ *  @details 
+ *  Call this function from the main context to get an event from the ACI event queue
+ *  This is called by lib_aci_event_get
+ */
+bool hal_aci_tl_event_get(hal_aci_data_t *p_aci_data);
+
+/** @brief Peek an ACI event from the event queue
+ *  @details
+ *  Call this function from the main context to peek an event from the ACI event queue.
+ *  This is called by lib_aci_event_peek
+ */
+bool hal_aci_tl_event_peek(hal_aci_data_t *p_aci_data);
+
+/** @brief Enable debug printing of all ACI commands sent and ACI events received
+ *  @details
+ *  when the enable parameter is true. The debug printing is enabled on the Serial.
+ *  When the enable parameter is false. The debug printing is disabled on the Serial.
+ *  By default the debug printing is disabled.
+ */
+void hal_aci_tl_debug_print(bool enable);
+
+
+/** @brief Pin reset the nRF8001
+ *  @details
+ *  The reset line of the nF8001 needs to kept low for 200 ns.
+ *  Redbearlab shield v1.1 and v2012.07 are exceptions as they
+ *  have a Power ON Reset circuit that works differently.
+ *  The function handles the exceptions based on the board_name in aci_pins_t
+ */
+void hal_aci_tl_pin_reset(void);
+
+/** @brief Return full status of transmit queue
+ *  @details
+ *
+ */
+bool hal_aci_tl_rx_q_full(void);
+ 
+ /** @brief Return empty status of receive queue
+ *  @details
+ *
+ */
+bool hal_aci_tl_rx_q_empty(void);
+
+/** @brief Return full status of receive queue
+ *  @details
+ *
+ */
+bool hal_aci_tl_tx_q_full(void);
+ 
+ /** @brief Return empty status of transmit queue
+ *  @details
+ *
+ */
+bool hal_aci_tl_tx_q_empty(void);
+
+/** @brief Flush the ACI command Queue and the ACI Event Queue
+ *  @details
+ *  Call this function in the main thread
+ */
+void hal_aci_tl_q_flush(void);
+
+/**
+ *  added aci interrupt function
+ */
+void m_aci_isr(void);
+
+/**
+ *  added aci task function
+ */
+void aci_task(int arg);
+
+#endif // HAL_ACI_TL_H__
+/** @} */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/ble_shield2.1/utility/hal_platform.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/ble_shield2.1/utility/hal_platform.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/ble_shield2.1/utility/hal_platform.h	(revision 457)
@@ -0,0 +1,106 @@
+/* Copyright (c) 2014, Nordic Semiconductor ASA
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#ifndef PLATFORM_H__
+#define PLATFORM_H__
+
+/** @file
+* @brief 
+*/
+
+//Board dependent defines
+#if defined (__AVR__)
+    //For Arduino this AVR specific library has to be used for reading from Flash memory
+    #include <avr/pgmspace.h>
+    #include "Arduino.h"
+    #ifdef PROGMEM
+        #undef PROGMEM
+        #define PROGMEM __attribute__(( section(".progmem.data") ))
+	    #endif
+#elif defined(__PIC32MX__)
+    //For Chipkit add the following libraries.
+    #include <stdint.h>
+    #include <stdbool.h>
+    #include <string.h>
+    #include <wiring.h>
+    #include <WProgram.h>
+#else	/* GCC */
+    #include <kernel.h>
+    #include <t_syslog.h>
+    #include <t_stdlib.h>
+    #include <stdbool.h>
+    #include <stdio.h>
+    #include <string.h>
+    #include <target_syssvc.h>
+    #include "syssvc/serial.h"
+    #include "syssvc/syslog.h"
+    #include "device.h"
+    #include "pinmode.h"
+    #include "spi.h"
+
+    #define delay           dly_tsk
+    #define noInterrupts    loc_cpu
+    #define interrupts      unl_cpu
+
+    #define sil_orw_mem(a, b) sil_wrw_mem((a), sil_rew_mem(a) | (b))
+
+#define PORT_HIGH      1
+#define PORT_LOW       0
+
+#define LOW     PORT_LOW
+#define HIGH    PORT_HIGH
+
+#define INPUT   0
+#define INPUT_PULLUP 1
+#define OUTPUT  2
+
+#endif
+	
+	//For making the Serial.Print compatible between Arduino and Chipkit
+	#define F(X) (X)
+	
+	//For ChipKit neither PROGMEM or PSTR are needed for PIC32
+    #define PROGMEM
+    #define PSTR(s) (s)	
+
+    #define pgm_read_byte(x)	        (*((char *)x))
+    #define pgm_read_byte_near(x)	(*((char *)x))
+    #define pgm_read_byte_far(x)	    (*((char *)x))
+    #define pgm_read_word(x)    	    (*((short *)x))
+    #define pgm_read_word_near(x)	(*((short *)x))
+    #define pgm_read_workd_far(x)	(*((short *)x))
+
+    #define	prog_void	    const void
+    #define	prog_char	    const char
+    #define	prog_uchar	    const unsigned char
+    #define	prog_int8_t	    const int8_t
+    #define	prog_uint8_t	const uint8_t
+    #define	prog_int16_t	const int16_t
+    #define	prog_uint16_t	const uint16_t
+    #define	prog_int32_t	const int32_t
+    #define	prog_uint32_t	const uint32_t
+    #define	prog_int64_t	const int64_t
+    #define	prog_uint64_t	const uint64_t
+	
+	//Redefine the function for reading from flash in ChipKit
+	#define memcpy_P        memcpy
+
+#endif /* PLATFORM_H__ */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/ble_shield2.1/utility/lib_aci.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/ble_shield2.1/utility/lib_aci.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/ble_shield2.1/utility/lib_aci.c	(revision 457)
@@ -0,0 +1,754 @@
+/* Copyright (c) 2014, Nordic Semiconductor ASA
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+/** @file
+  @brief Implementation of the ACI library.
+ */
+
+#include "hal_platform.h"
+#include "aci.h"
+#include "aci_cmds.h"
+#include "aci_evts.h"
+#include "aci_protocol_defines.h"
+#include "acilib_defs.h"
+#include "acilib_if.h"
+#include "hal_aci_tl.h"
+#include "aci_queue.h"
+#include "lib_aci.h"
+
+
+#define LIB_ACI_DEFAULT_CREDIT_NUMBER   1
+
+/*
+Global additionally used used in aci_setup 
+*/
+hal_aci_data_t  msg_to_send;
+
+
+static services_pipe_type_mapping_t * p_services_pipe_type_map;
+static hal_aci_data_t *               p_setup_msgs;
+
+
+
+
+static bool is_request_operation_pending;
+static bool is_indicate_operation_pending;
+static bool is_open_remote_pipe_pending;
+static bool is_close_remote_pipe_pending;
+
+static uint8_t request_operation_pipe = 0;
+static uint8_t indicate_operation_pipe = 0;
+
+
+// The following structure (aci_cmd_params_open_adv_pipe) will be used to store the complete command 
+// including the pipes to be opened. 
+static aci_cmd_params_open_adv_pipe_t aci_cmd_params_open_adv_pipe; 
+
+
+
+extern aci_queue_t    aci_rx_q;
+extern aci_queue_t    aci_tx_q;
+
+bool lib_aci_is_pipe_available(aci_state_t *aci_stat, uint8_t pipe)
+{
+  uint8_t byte_idx;
+
+  byte_idx = pipe / 8;
+  if (aci_stat->pipes_open_bitmap[byte_idx] & (0x01 << (pipe % 8)))
+  {
+    return(true);
+  }
+  return(false);
+}
+
+
+bool lib_aci_is_pipe_closed(aci_state_t *aci_stat, uint8_t pipe)
+{
+  uint8_t byte_idx;
+
+  byte_idx = pipe / 8;
+  if (aci_stat->pipes_closed_bitmap[byte_idx] & (0x01 << (pipe % 8)))
+  {
+    return(true);
+  }
+  return(false);
+}
+
+
+bool lib_aci_is_discovery_finished(aci_state_t *aci_stat)
+{
+  return(aci_stat->pipes_open_bitmap[0]&0x01);
+}
+
+void lib_aci_board_init(aci_state_t *aci_stat)
+{
+	hal_aci_evt_t *aci_data = NULL;
+	aci_data = (hal_aci_evt_t *)&msg_to_send;
+					
+	if (REDBEARLAB_SHIELD_V1_1 == aci_stat->aci_pins.board_name)
+	{
+	  /*
+	  The Bluetooth low energy Arduino shield v1.1 requires about 100ms to reset.
+	  This is not required for the nRF2740, nRF2741 modules
+	  */
+	  delay(100);
+  
+	  /*
+	  Send the soft reset command to the nRF8001 to get the nRF8001 to a known state.
+	  */
+	  lib_aci_radio_reset();
+  
+	  while (1)
+	  {
+		/*Wait for the command response of the radio reset command.
+		as the nRF8001 will be in either SETUP or STANDBY after the ACI Reset Radio is processed
+		*/
+
+			
+		if (true == lib_aci_event_get(aci_stat, aci_data))
+		{
+		  aci_evt_t * aci_evt;      
+		  aci_evt = &(aci_data->evt);
+	  
+		  if (ACI_EVT_CMD_RSP == aci_evt->evt_opcode)
+		  {
+				if (ACI_STATUS_ERROR_DEVICE_STATE_INVALID == aci_evt->params.cmd_rsp.cmd_status) //in SETUP
+				{
+					//Inject a Device Started Event Setup to the ACI Event Queue
+					msg_to_send.buffer[0] = 4;    //Length
+					msg_to_send.buffer[1] = 0x81; //Device Started Event
+					msg_to_send.buffer[2] = 0x02; //Setup
+					msg_to_send.buffer[3] = 0;    //Hardware Error -> None
+					msg_to_send.buffer[4] = 2;    //Data Credit Available
+					aci_queue_enqueue(&aci_rx_q, &msg_to_send);
+				}
+				else if (ACI_STATUS_SUCCESS == aci_evt->params.cmd_rsp.cmd_status) //We are now in STANDBY
+				{
+					//Inject a Device Started Event Standby to the ACI Event Queue
+					msg_to_send.buffer[0] = 4;    //Length
+					msg_to_send.buffer[1] = 0x81; //Device Started Event
+					msg_to_send.buffer[2] = 0x03; //Standby
+					msg_to_send.buffer[3] = 0;    //Hardware Error -> None
+					msg_to_send.buffer[4] = 2;    //Data Credit Available
+					aci_queue_enqueue(&aci_rx_q, &msg_to_send);
+				}
+				else if (ACI_STATUS_ERROR_CMD_UNKNOWN == aci_evt->params.cmd_rsp.cmd_status) //We are now in TEST
+				{
+					//Inject a Device Started Event Test to the ACI Event Queue
+					msg_to_send.buffer[0] = 4;    //Length
+					msg_to_send.buffer[1] = 0x81; //Device Started Event
+					msg_to_send.buffer[2] = 0x01; //Test
+					msg_to_send.buffer[3] = 0;    //Hardware Error -> None
+					msg_to_send.buffer[4] = 0;    //Data Credit Available
+					aci_queue_enqueue(&aci_rx_q, &msg_to_send);
+				}
+				
+				//Break out of the while loop
+				break;
+		  }
+		  else
+		  {			
+			//Serial.println(F("Discard any other ACI Events"));
+		  }
+	  
+		}
+	  }		
+	}
+}
+
+
+void lib_aci_init(aci_state_t *aci_stat, bool debug)
+{
+  uint8_t i;
+
+  for (i = 0; i < PIPES_ARRAY_SIZE; i++)
+  {
+    aci_stat->pipes_open_bitmap[i]          = 0;
+    aci_stat->pipes_closed_bitmap[i]        = 0;
+    aci_cmd_params_open_adv_pipe.pipes[i]   = 0;
+  }
+  
+
+
+
+  is_request_operation_pending     = false;
+  is_indicate_operation_pending    = false; 
+  is_open_remote_pipe_pending      = false;
+  is_close_remote_pipe_pending     = false;
+
+
+
+  
+  
+  request_operation_pipe           = 0;
+  indicate_operation_pipe          = 0;
+  
+  
+  
+  p_services_pipe_type_map = aci_stat->aci_setup_info.services_pipe_type_mapping;
+  
+  p_setup_msgs             = aci_stat->aci_setup_info.setup_msgs;
+  
+  
+  hal_aci_tl_init(&aci_stat->aci_pins, debug);
+  
+  lib_aci_board_init(aci_stat);
+}
+
+
+uint8_t lib_aci_get_nb_available_credits(aci_state_t *aci_stat)
+{
+  return aci_stat->data_credit_available;
+}
+
+uint16_t lib_aci_get_cx_interval_ms(aci_state_t *aci_stat)
+{
+  uint32_t cx_rf_interval_ms_32bits;
+  uint16_t cx_rf_interval_ms;
+  
+  cx_rf_interval_ms_32bits  = aci_stat->connection_interval;
+  cx_rf_interval_ms_32bits *= 125;                      // the connection interval is given in multiples of 0.125 milliseconds
+  cx_rf_interval_ms         = cx_rf_interval_ms_32bits / 100;
+  
+  return cx_rf_interval_ms;
+}
+
+
+uint16_t lib_aci_get_cx_interval(aci_state_t *aci_stat)
+{
+  return aci_stat->connection_interval;
+}
+
+
+uint16_t lib_aci_get_slave_latency(aci_state_t *aci_stat)
+{
+  return aci_stat->slave_latency;
+}
+
+
+bool lib_aci_set_app_latency(uint16_t latency, aci_app_latency_mode_t latency_mode)
+{
+  aci_cmd_params_set_app_latency_t aci_set_app_latency;
+  
+  aci_set_app_latency.mode    = latency_mode;
+  aci_set_app_latency.latency = latency;  
+  acil_encode_cmd_set_app_latency(&(msg_to_send.buffer[0]), &aci_set_app_latency);
+  
+  return hal_aci_tl_send(&msg_to_send);
+}
+
+
+bool lib_aci_test(aci_test_mode_change_t enter_exit_test_mode)
+{
+  aci_cmd_params_test_t aci_cmd_params_test;
+  aci_cmd_params_test.test_mode_change = enter_exit_test_mode;
+  acil_encode_cmd_set_test_mode(&(msg_to_send.buffer[0]), &aci_cmd_params_test);
+  return hal_aci_tl_send(&msg_to_send);
+}
+
+
+bool lib_aci_sleep()
+{
+  acil_encode_cmd_sleep(&(msg_to_send.buffer[0]));
+  return hal_aci_tl_send(&msg_to_send);
+}
+
+
+bool lib_aci_radio_reset()
+{
+  acil_encode_baseband_reset(&(msg_to_send.buffer[0]));
+  return hal_aci_tl_send(&msg_to_send);
+}
+
+
+bool lib_aci_direct_connect()
+{
+  acil_encode_direct_connect(&(msg_to_send.buffer[0]));
+  return hal_aci_tl_send(&msg_to_send);
+}
+
+
+bool lib_aci_device_version()
+{
+  acil_encode_cmd_get_device_version(&(msg_to_send.buffer[0]));
+  return hal_aci_tl_send(&msg_to_send);
+}
+
+
+bool lib_aci_set_local_data(aci_state_t *aci_stat, uint8_t pipe, uint8_t *p_value, uint8_t size)
+{
+  aci_cmd_params_set_local_data_t aci_cmd_params_set_local_data;
+  
+  // if ((p_services_pipe_type_map[pipe-1].location != ACI_STORE_LOCAL)
+  //     ||
+  //     (size > ACI_PIPE_TX_DATA_MAX_LEN))
+  // {
+  //   return false;
+  // }
+
+  aci_cmd_params_set_local_data.tx_data.pipe_number = pipe;
+  memcpy(&(aci_cmd_params_set_local_data.tx_data.aci_data[0]), p_value, size);
+  acil_encode_cmd_set_local_data(&(msg_to_send.buffer[0]), &aci_cmd_params_set_local_data, size);
+  return hal_aci_tl_send(&msg_to_send);
+}
+
+bool lib_aci_connect(uint16_t run_timeout, uint16_t adv_interval)
+{
+  aci_cmd_params_connect_t aci_cmd_params_connect;
+  aci_cmd_params_connect.timeout      = run_timeout;
+  aci_cmd_params_connect.adv_interval = adv_interval;
+  acil_encode_cmd_connect(&(msg_to_send.buffer[0]), &aci_cmd_params_connect);
+  return hal_aci_tl_send(&msg_to_send);
+}
+
+
+bool lib_aci_disconnect(aci_state_t *aci_stat, aci_disconnect_reason_t reason)
+{
+  bool ret_val;
+  uint8_t i;
+  aci_cmd_params_disconnect_t aci_cmd_params_disconnect;
+  aci_cmd_params_disconnect.reason = reason;
+  acil_encode_cmd_disconnect(&(msg_to_send.buffer[0]), &aci_cmd_params_disconnect);
+  ret_val = hal_aci_tl_send(&msg_to_send);
+  // If we have actually sent the disconnect
+  if (ret_val)
+  {
+    // Update pipes immediately so that while the disconnect is happening,
+    // the application can't attempt sending another message
+    // If the application sends another message before we updated this
+    //    a ACI Pipe Error Event will be received from nRF8001
+    for (i=0; i < PIPES_ARRAY_SIZE; i++)
+    {
+      aci_stat->pipes_open_bitmap[i] = 0;
+      aci_stat->pipes_closed_bitmap[i] = 0;
+    }
+  }
+  return ret_val;
+}
+
+
+bool lib_aci_bond(uint16_t run_timeout, uint16_t adv_interval)
+{
+  aci_cmd_params_bond_t aci_cmd_params_bond;
+  aci_cmd_params_bond.timeout = run_timeout;
+  aci_cmd_params_bond.adv_interval = adv_interval;
+  acil_encode_cmd_bond(&(msg_to_send.buffer[0]), &aci_cmd_params_bond);
+  return hal_aci_tl_send(&msg_to_send);
+}
+
+
+bool lib_aci_wakeup()
+{
+  acil_encode_cmd_wakeup(&(msg_to_send.buffer[0]));
+  return hal_aci_tl_send(&msg_to_send);
+}
+
+
+bool lib_aci_set_tx_power(aci_device_output_power_t tx_power)
+{
+  aci_cmd_params_set_tx_power_t aci_cmd_params_set_tx_power;
+  aci_cmd_params_set_tx_power.device_power = tx_power;
+  acil_encode_cmd_set_radio_tx_power(&(msg_to_send.buffer[0]), &aci_cmd_params_set_tx_power);
+  return hal_aci_tl_send(&msg_to_send);
+}
+
+
+bool lib_aci_get_address()
+{
+  acil_encode_cmd_get_address(&(msg_to_send.buffer[0]));
+  return hal_aci_tl_send(&msg_to_send);
+}
+
+
+bool lib_aci_get_temperature()
+{
+  acil_encode_cmd_temparature(&(msg_to_send.buffer[0]));
+  return hal_aci_tl_send(&msg_to_send);
+}
+
+
+bool lib_aci_get_battery_level()
+{
+  acil_encode_cmd_battery_level(&(msg_to_send.buffer[0]));
+  return hal_aci_tl_send(&msg_to_send);
+}
+
+
+bool lib_aci_send_data(uint8_t pipe, uint8_t *p_value, uint8_t size)
+{
+  bool ret_val = false;
+  aci_cmd_params_send_data_t aci_cmd_params_send_data;
+
+  
+  // if(!((p_services_pipe_type_map[pipe-1].pipe_type == ACI_TX) ||
+  //     (p_services_pipe_type_map[pipe-1].pipe_type == ACI_TX_ACK)))
+  // {
+  //   return false;
+  // }
+
+  if (size > ACI_PIPE_TX_DATA_MAX_LEN)
+  {
+    return false;
+  }
+  {
+      aci_cmd_params_send_data.tx_data.pipe_number = pipe;
+      memcpy(&(aci_cmd_params_send_data.tx_data.aci_data[0]), p_value, size);
+      acil_encode_cmd_send_data(&(msg_to_send.buffer[0]), &aci_cmd_params_send_data, size);
+      
+      ret_val = hal_aci_tl_send(&msg_to_send);          
+  }
+  return ret_val;
+}
+
+
+bool lib_aci_request_data(aci_state_t *aci_stat, uint8_t pipe)
+{
+  bool ret_val = false;
+  aci_cmd_params_request_data_t aci_cmd_params_request_data;
+
+  if(!((p_services_pipe_type_map[pipe-1].location == ACI_STORE_REMOTE)&&(p_services_pipe_type_map[pipe-1].pipe_type == ACI_RX_REQ)))
+  {
+    return false;
+  }
+
+
+  {
+
+    {
+
+
+
+      aci_cmd_params_request_data.pipe_number = pipe;
+      acil_encode_cmd_request_data(&(msg_to_send.buffer[0]), &aci_cmd_params_request_data);
+
+      ret_val = hal_aci_tl_send(&msg_to_send);
+    }
+  }
+  return ret_val;
+}
+
+
+bool lib_aci_change_timing(uint16_t minimun_cx_interval, uint16_t maximum_cx_interval, uint16_t slave_latency, uint16_t timeout)
+{
+  aci_cmd_params_change_timing_t aci_cmd_params_change_timing;
+  aci_cmd_params_change_timing.conn_params.min_conn_interval = minimun_cx_interval;
+  aci_cmd_params_change_timing.conn_params.max_conn_interval = maximum_cx_interval;
+  aci_cmd_params_change_timing.conn_params.slave_latency     = slave_latency;    
+  aci_cmd_params_change_timing.conn_params.timeout_mult      = timeout;     
+  acil_encode_cmd_change_timing_req(&(msg_to_send.buffer[0]), &aci_cmd_params_change_timing);
+  return hal_aci_tl_send(&msg_to_send);
+}
+
+
+bool lib_aci_change_timing_GAP_PPCP()
+{
+  acil_encode_cmd_change_timing_req_GAP_PPCP(&(msg_to_send.buffer[0]));
+  return hal_aci_tl_send(&msg_to_send);
+}
+
+
+bool lib_aci_open_remote_pipe(aci_state_t *aci_stat, uint8_t pipe)
+{
+  bool ret_val = false;
+  aci_cmd_params_open_remote_pipe_t aci_cmd_params_open_remote_pipe;
+
+  if(!((p_services_pipe_type_map[pipe-1].location == ACI_STORE_REMOTE)&&
+                ((p_services_pipe_type_map[pipe-1].pipe_type == ACI_RX)||
+                (p_services_pipe_type_map[pipe-1].pipe_type == ACI_RX_ACK_AUTO)||
+                (p_services_pipe_type_map[pipe-1].pipe_type == ACI_RX_ACK))))
+  {
+    return false;
+  }
+
+  
+  {
+
+    is_request_operation_pending = true;
+    is_open_remote_pipe_pending = true;
+    request_operation_pipe = pipe;
+    aci_cmd_params_open_remote_pipe.pipe_number = pipe;
+    acil_encode_cmd_open_remote_pipe(&(msg_to_send.buffer[0]), &aci_cmd_params_open_remote_pipe);
+    ret_val = hal_aci_tl_send(&msg_to_send);
+  }
+  return ret_val;
+}
+
+
+bool lib_aci_close_remote_pipe(aci_state_t *aci_stat, uint8_t pipe)
+{
+  bool ret_val = false;
+  aci_cmd_params_close_remote_pipe_t aci_cmd_params_close_remote_pipe;
+
+  if(!((p_services_pipe_type_map[pipe-1].location == ACI_STORE_REMOTE)&&
+        ((p_services_pipe_type_map[pipe-1].pipe_type == ACI_RX)||
+         (p_services_pipe_type_map[pipe-1].pipe_type == ACI_RX_ACK_AUTO)||
+         (p_services_pipe_type_map[pipe-1].pipe_type == ACI_RX_ACK))))
+  {
+    return false;
+  }  
+
+
+  {
+
+    is_request_operation_pending = true;
+    is_close_remote_pipe_pending = true;
+    request_operation_pipe = pipe;
+    aci_cmd_params_close_remote_pipe.pipe_number = pipe;
+    acil_encode_cmd_close_remote_pipe(&(msg_to_send.buffer[0]), &aci_cmd_params_close_remote_pipe);
+    ret_val = hal_aci_tl_send(&msg_to_send);
+  }
+  return ret_val;
+}
+
+
+bool lib_aci_set_key(aci_key_type_t key_rsp_type, uint8_t *key, uint8_t len)
+{
+  aci_cmd_params_set_key_t aci_cmd_params_set_key;
+  aci_cmd_params_set_key.key_type = key_rsp_type;
+  memcpy((uint8_t*)&(aci_cmd_params_set_key.key), key, len);
+  acil_encode_cmd_set_key(&(msg_to_send.buffer[0]), &aci_cmd_params_set_key);
+  return hal_aci_tl_send(&msg_to_send);
+}
+
+
+bool lib_aci_echo_msg(uint8_t msg_size, uint8_t *p_msg_data)
+{
+  aci_cmd_params_echo_t aci_cmd_params_echo;
+  if(msg_size > (ACI_ECHO_DATA_MAX_LEN))
+  {
+    return false;
+  }
+
+  if (msg_size > (ACI_ECHO_DATA_MAX_LEN))
+  {
+    msg_size = ACI_ECHO_DATA_MAX_LEN;
+  }
+
+  memcpy(&(aci_cmd_params_echo.echo_data[0]), p_msg_data, msg_size);
+  acil_encode_cmd_echo_msg(&(msg_to_send.buffer[0]), &aci_cmd_params_echo, msg_size);
+
+  return hal_aci_tl_send(&msg_to_send);
+}
+
+
+bool lib_aci_bond_request()
+{
+  acil_encode_cmd_bond_security_request(&(msg_to_send.buffer[0]));
+  return hal_aci_tl_send(&msg_to_send);
+}
+
+bool lib_aci_event_peek(hal_aci_evt_t *p_aci_evt_data)
+{
+  return hal_aci_tl_event_peek((hal_aci_data_t *)p_aci_evt_data);
+}
+
+bool lib_aci_event_get(aci_state_t *aci_stat, hal_aci_evt_t *p_aci_evt_data)
+{
+  bool status = false;
+  
+  status = hal_aci_tl_event_get((hal_aci_data_t *)p_aci_evt_data);
+  
+  /**
+  Update the state of the ACI with the 
+  ACI Events -> Pipe Status, Disconnected, Connected, Bond Status, Pipe Error
+  */
+  if (true == status)
+  {
+    aci_evt_t * aci_evt;
+    
+    aci_evt = &p_aci_evt_data->evt;  
+    
+    switch(aci_evt->evt_opcode)
+    {
+        case ACI_EVT_PIPE_STATUS:
+            {
+                uint8_t i=0;
+                
+                for (i=0; i < PIPES_ARRAY_SIZE; i++)
+                {
+                  aci_stat->pipes_open_bitmap[i]   = aci_evt->params.pipe_status.pipes_open_bitmap[i];
+                  aci_stat->pipes_closed_bitmap[i] = aci_evt->params.pipe_status.pipes_closed_bitmap[i];
+                }
+            }
+            break;
+        
+        case ACI_EVT_DISCONNECTED:
+            {
+                uint8_t i=0;
+                
+                for (i=0; i < PIPES_ARRAY_SIZE; i++)
+                {
+                  aci_stat->pipes_open_bitmap[i] = 0;
+                  aci_stat->pipes_closed_bitmap[i] = 0;
+                }
+                aci_stat->confirmation_pending = false;
+                aci_stat->data_credit_available = aci_stat->data_credit_total;
+                
+            }
+            break;
+            
+        case ACI_EVT_TIMING:            
+                aci_stat->connection_interval = aci_evt->params.timing.conn_rf_interval;
+                aci_stat->slave_latency       = aci_evt->params.timing.conn_slave_rf_latency;
+                aci_stat->supervision_timeout = aci_evt->params.timing.conn_rf_timeout;
+            break;
+
+        default:
+            /* Need default case to avoid compiler warnings about missing enum
+             * values on some platforms.
+             */
+            break;
+
+			
+			
+    }
+  }
+  return status;
+}
+
+
+bool lib_aci_send_ack(aci_state_t *aci_stat, const uint8_t pipe)
+{
+  bool ret_val = false;
+  {
+    acil_encode_cmd_send_data_ack(&(msg_to_send.buffer[0]), pipe);
+    
+    ret_val = hal_aci_tl_send(&msg_to_send);
+  }
+  return ret_val;
+}
+
+
+bool lib_aci_send_nack(aci_state_t *aci_stat, const uint8_t pipe, const uint8_t error_code)
+{
+  bool ret_val = false;
+  
+  {
+    
+    acil_encode_cmd_send_data_nack(&(msg_to_send.buffer[0]), pipe, error_code);
+    ret_val = hal_aci_tl_send(&msg_to_send);
+  }
+  return ret_val;
+}
+
+
+bool lib_aci_broadcast(const uint16_t timeout, const uint16_t adv_interval)
+{
+  aci_cmd_params_broadcast_t aci_cmd_params_broadcast;
+  if (timeout > 16383)
+  {
+    return false;
+  }  
+  
+  // The adv_interval should be between 160 and 16384 (which translates to the advertisement 
+  // interval values 100 ms and 10.24 s.
+  if ((160 > adv_interval) || (adv_interval > 16384))
+  {
+    return false;
+  }
+
+  aci_cmd_params_broadcast.timeout = timeout;
+  aci_cmd_params_broadcast.adv_interval = adv_interval;
+  acil_encode_cmd_broadcast(&(msg_to_send.buffer[0]), &aci_cmd_params_broadcast);
+  return hal_aci_tl_send(&msg_to_send);
+}
+
+
+bool lib_aci_open_adv_pipes(const uint8_t * const adv_service_data_pipes)
+{
+  uint8_t i;
+    
+  for (i = 0; i < PIPES_ARRAY_SIZE; i++)
+  {
+    aci_cmd_params_open_adv_pipe.pipes[i] = adv_service_data_pipes[i];
+  }
+
+  acil_encode_cmd_open_adv_pipes(&(msg_to_send.buffer[0]), &aci_cmd_params_open_adv_pipe);
+  return hal_aci_tl_send(&msg_to_send);
+}
+
+bool lib_aci_open_adv_pipe(const uint8_t pipe)
+{
+  uint8_t byte_idx = pipe / 8;
+  
+  aci_cmd_params_open_adv_pipe.pipes[byte_idx] |= (0x01 << (pipe % 8));
+  acil_encode_cmd_open_adv_pipes(&(msg_to_send.buffer[0]), &aci_cmd_params_open_adv_pipe);
+  return hal_aci_tl_send(&msg_to_send);
+}
+
+
+bool lib_aci_read_dynamic_data()
+{
+  acil_encode_cmd_read_dynamic_data(&(msg_to_send.buffer[0]));
+  return hal_aci_tl_send(&msg_to_send);
+}
+
+
+bool lib_aci_write_dynamic_data(uint8_t sequence_number, uint8_t* dynamic_data, uint8_t length)
+{
+  acil_encode_cmd_write_dynamic_data(&(msg_to_send.buffer[0]), sequence_number, dynamic_data, length);
+  return hal_aci_tl_send(&msg_to_send);
+}
+
+bool lib_aci_dtm_command(uint8_t dtm_command_msbyte, uint8_t dtm_command_lsbyte)
+{
+  aci_cmd_params_dtm_cmd_t aci_cmd_params_dtm_cmd;
+  aci_cmd_params_dtm_cmd.cmd_msb = dtm_command_msbyte;
+  aci_cmd_params_dtm_cmd.cmd_lsb = dtm_command_lsbyte;
+  acil_encode_cmd_dtm_cmd(&(msg_to_send.buffer[0]), &aci_cmd_params_dtm_cmd);
+  return hal_aci_tl_send(&msg_to_send);
+}
+
+void lib_aci_flush(void)
+{
+  hal_aci_tl_q_flush();
+}
+
+void lib_aci_debug_print(bool enable)
+{
+  hal_aci_tl_debug_print(enable);
+
+}
+
+void lib_aci_pin_reset(void)
+{
+    hal_aci_tl_pin_reset();
+}
+
+bool lib_aci_event_queue_empty(void)
+{
+  return hal_aci_tl_rx_q_empty();
+}
+
+bool lib_aci_event_queue_full(void)
+{
+  return hal_aci_tl_rx_q_full();
+}
+
+bool lib_aci_command_queue_empty(void)
+{
+  return hal_aci_tl_tx_q_empty();
+}
+
+bool lib_aci_command_queue_full(void)
+{
+  return hal_aci_tl_tx_q_full();
+}
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/ble_shield2.1/utility/lib_aci.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/ble_shield2.1/utility/lib_aci.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/ble_shield2.1/utility/lib_aci.h	(revision 457)
@@ -0,0 +1,557 @@
+/* Copyright (c) 2014, Nordic Semiconductor ASA
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#ifndef LIB_ACI_H__
+#define LIB_ACI_H__
+
+/** @file
+* @brief ACI library
+*/
+
+/** @addtogroup lib_aci
+@{
+@brief Library for the logical part of the Application Controller Interface (ACI)
+*/
+
+#include "hal_platform.h"
+#include "hal_aci_tl.h"
+#include "aci_queue.h"
+#include "aci.h"
+#include "aci_cmds.h"
+#include "aci_evts.h"
+
+
+#define EVT_CMD_RESPONSE_MIN_LENGTH              3
+
+#define PIPES_ARRAY_SIZE                ((ACI_DEVICE_MAX_PIPES + 7)/8)
+
+/* Same size as a hal_aci_data_t */
+typedef struct {
+  uint8_t   debug_byte;
+  aci_evt_t evt;
+} _aci_packed_ hal_aci_evt_t;
+
+ACI_ASSERT_SIZE(hal_aci_evt_t, 34);
+
+typedef struct
+{
+  uint8_t  location; /**< enum aci_pipe_store_t */
+  aci_pipe_type_t   pipe_type;
+} services_pipe_type_mapping_t;
+
+typedef struct aci_setup_info_t
+{
+  services_pipe_type_mapping_t *services_pipe_type_mapping;
+  uint8_t                       number_of_pipes;
+  hal_aci_data_t               *setup_msgs;
+  uint8_t                       num_setup_msgs;
+} aci_setup_info_t;
+
+
+
+// aci_struct that will contain 
+// total initial credits
+// current credit
+// current state of the aci (setup/standby/active/sleep)
+// open remote pipe pending
+// close remote pipe pending
+// Current pipe available bitmap
+// Current pipe closed bitmap
+// Current connection interval, slave latency and link supervision timeout
+// Current State of the the GATT client (Service Discovery status)
+// Relationship of bond to peer address
+typedef struct aci_state_t
+{
+  aci_pins_t                    aci_pins;                               /* Pins on the MCU used to connect to the nRF8001 */ 
+  aci_setup_info_t              aci_setup_info;                         /* Data structures that are created from nRFgo Studio */
+  uint8_t                       bonded;                                 /* ( aci_bond_status_code_t ) Is the nRF8001 bonded to a peer device */
+  uint8_t                       data_credit_total;                      /* Total data credit available for the specific version of the nRF8001, total equals available when a link is established */
+  aci_device_operation_mode_t   device_state;                           /* Operating mode of the nRF8001 */
+  
+  /* */
+  
+  /* Start : Variables that are valid only when in a connection */
+  uint8_t                       data_credit_available;                  /* Available data credits at a specific point of time, ACI_EVT_DATA_CREDIT updates the available credits */
+  
+  uint16_t                      connection_interval;                    /* Multiply by 1.25 to get the connection interval in milliseconds*/
+  uint16_t                      slave_latency;                          /* Number of consecutive connection intervals that the nRF8001 is not required to transmit. Use this to save power */
+  uint16_t                      supervision_timeout;                    /* Multiply by 10 to get the supervision timeout in milliseconds */
+  
+  uint8_t                       pipes_open_bitmap[PIPES_ARRAY_SIZE];    /* Bitmap -> pipes are open and can be used for sending data over the air */
+  uint8_t                       pipes_closed_bitmap[PIPES_ARRAY_SIZE];  /* Bitmap -> pipes are closed and cannot be used for sending data over the air */
+  bool                          confirmation_pending;                   /* Attribute protocol Handle Value confirmation is pending for a Handle Value Indication
+                                                                        (ACK is pending for a TX_ACK pipe) on local GATT Server*/
+  /* End : Variables that are valid only when in a connection */                                                                        
+  
+} aci_state_t;
+
+
+
+#define DISCONNECT_REASON_CX_TIMEOUT                 0x08
+#define DISCONNECT_REASON_CX_CLOSED_BY_PEER_DEVICE   0x13
+#define DISCONNECT_REASON_POWER_LOSS                 0x14
+#define DISCONNECT_REASON_CX_CLOSED_BY_LOCAL_DEVICE  0x16
+#define DISCONNECT_REASON_ADVERTISER_TIMEOUT         0x50
+
+
+/** @name Functions for library management */
+//@{
+
+/** @brief Function to enable printing of all ACI commands sent and ACI events received
+ *  @details This function shall be used to enable or disable the debug printing.
+              Debug printing is disabled by default.
+ */
+void lib_aci_debug_print(bool enable);
+
+/** @brief Function to pin reset the nRF8001
+ *  @details Pin resets the nRF8001 also handles differences between development boards
+ */
+void lib_aci_pin_reset(void);
+
+/** @brief Initialization function.
+ *  @details This function shall be used to initialize/reset ACI Library and also Resets the 
+ *           nRF8001 by togging the reset pin of the nRF8001. This function will reset 
+ *           all the variables locally used by ACI library to their respective default values.
+ *  @param bool True if the data was successfully queued for sending, 
+ *  false if there is no more space to store messages to send.
+ */
+void lib_aci_init(aci_state_t *aci_stat, bool debug);
+
+
+/** @brief Gets the number of currently available ACI credits.
+ *  @return Number of ACI credits.
+ */
+uint8_t lib_aci_get_nb_available_credits(aci_state_t *aci_stat);
+
+/** @brief Gets the connection interval in milliseconds.
+ *  @return Connection interval in milliseconds.
+ */
+uint16_t lib_aci_get_cx_interval_ms(aci_state_t *aci_stat);
+
+/** @brief Gets the connection interval in multiple of 1.25&nbsp;ms.
+ *  @return Connection interval in multiple of 1.25&nbsp;ms.
+ */
+uint16_t lib_aci_get_cx_interval(aci_state_t *aci_stat);
+
+/** @brief Gets the current slave latency.
+ *  @return Current slave latency.
+ */
+uint16_t lib_aci_get_slave_latency(aci_state_t *aci_stat);
+
+/** @brief Checks if a given pipe is available.
+ *  @param pipe Pipe to check.
+ *  @return True if the pipe is available, otherwise false.
+ */
+bool lib_aci_is_pipe_available(aci_state_t *aci_stat, uint8_t pipe);
+
+/** @brief Checks if a given pipe is closed.
+ *  @param pipe Pipe to check.
+ *  @return True if the pipe is closed, otherwise false.
+ */
+bool lib_aci_is_pipe_closed(aci_state_t *aci_stat, uint8_t pipe);
+
+/** @brief Checks if the discovery operation is finished.
+ *  @return True if the discovery is finished.
+ */
+bool lib_aci_is_discovery_finished(aci_state_t *aci_stat);
+
+
+
+//@}
+
+/** @name ACI Commands available in all modes */
+//@{
+
+/** @brief Sets the radio in sleep mode.
+ *  @details The function sends a @c sleep command to the radio.
+ *  If the radio is advertising or connected, it sends back an error, then use lib_aci_radio_reset 
+ *  if advertising or disconnect if in a connection.
+ *  @return True if the transaction is successfully initiated.
+ */
+bool lib_aci_sleep(void);
+
+/** @brief Resets the radio.
+ *  @details The function sends a @c BasebandReset command to the radio.  
+ *  @return True if the transaction is successfully initiated.
+ */
+bool lib_aci_radio_reset(void);
+
+/** @brief Radio starts directed advertising to bonded device.
+ *  @details The function sends a @c DirectedConnect command to the radio.  
+ *  @return True if the transaction is successfully initiated.
+ */
+bool lib_aci_direct_connect(void);
+
+/** @brief Gets the radio's version.
+ *  @details This function sends a @c GetDeviceVersion command.
+ *  @return True if the transaction is successfully initiated.
+ */
+bool lib_aci_device_version(void);
+
+/** @brief Gets the device address.
+ *  @details This function sends a @c GetDeviceAddress command.
+ *  @return True if the transaction is successfully initiated.
+ */
+bool lib_aci_get_address(void);
+
+/** @brief Gets the temperature.
+ *  @details This function sends a @c GetTemperature command. lib_aci
+ *  calls the @ref lib_aci_transaction_finished_hook() function when the temperature is received.
+ *  @return True if the transaction is successfully initiated.
+ */
+bool lib_aci_get_temperature(void);
+
+/** @brief Gets the battery level.
+ *  @details This function sends a @c GetBatteryLevel command. 
+ *  @return True if the transaction is successfully initiated.
+ */
+bool lib_aci_get_battery_level(void);
+
+//@}
+
+/** @name ACI commands available in Sleep mode */
+//@{
+
+/** @brief Wakes up the radio.
+ *  @details This function sends a @c Wakeup command to wake up the radio from
+ *  sleep mode. When woken up the radio sends a @c DeviceStartedEvent and
+ *  a @c CommandResponseEvent.
+ *  @return True if the transaction is successfully initiated.
+ */
+bool lib_aci_wakeup(void);
+
+//@}
+
+/** @name ACI commands available in Active mode */
+//@{
+
+/** @brief Sets the radio in test mode.
+ *  @details This function sends a @c Test command to the radio. There are two
+ *  Test modes available:
+ *  - UART: DTM commands are received over UART.
+ *  - ACI: DTM commands are received over ACI.
+ *  The same command is used to exit the test mode When receiving
+ *  a @c DeviceStartedEvent the radio has entered the new mode.
+ *  @param enter_exit_test_mode Enter a Test mode, or exit Test mode.
+ *  @return True if the transaction is successfully initiated.
+ */
+bool lib_aci_test(aci_test_mode_change_t enter_exit_test_mode);
+
+/** @brief Sets the radio's TX power.
+ *  @details This function sends a @c SetTxPower command.
+ *  @param tx_power TX power to be used by the radio.
+ *  @return True if the transaction is successfully initiated.
+ */
+bool lib_aci_set_tx_power(aci_device_output_power_t tx_power);
+
+/** @brief Tries to connect to a peer device.
+ *  @details This function sends a @c Connect command to the radio.
+ *  @param run_timeout Maximum advertising time in seconds (0 means infinite).
+ *  @param adv_interval Advertising interval (in multiple of 0.625&nbsp;ms).
+ *  @return True if the transaction is successfully initiated.
+ */
+bool lib_aci_connect(uint16_t run_timeout, uint16_t adv_interval);
+
+/** @brief Tries to bond with a peer device.
+ *  @details This function sends a @c Bond command to the radio.
+ *  @param run_timeout Maximum advertising time in seconds (0 means infinite).
+ *  @param adv_interval Advertising interval (in multiple of 0.625&nbsp;ms).
+ *  @return True if the transaction is successfully initiated.
+ */
+bool lib_aci_bond(uint16_t run_timeout, uint16_t adv_interval);
+
+/** @brief Disconnects from peer device.
+ *  @details This function sends a @c Disconnect command to the radio.
+ *  @param reason Reason for disconnecting.
+ *  @return True if the transaction is successfully initiated.
+ */
+bool lib_aci_disconnect(aci_state_t *aci_stat, aci_disconnect_reason_t reason);
+
+/**@brief Sets Local Data.
+ *  @details
+ *  This command updates the value of the characteristic value or the characteristic descriptor stored locally on the device.
+ *  Can be called for all types of pipes as long as the data is stored locally.
+ *  @param ACI state structure
+ *  @param pipe Pipe number on which the data should be set.
+ *  @param value Pointer to the data to set.
+ *  @param size Size of the data to set.
+ *  @return True if the transaction is successfully initiated.
+*/
+bool lib_aci_set_local_data(aci_state_t *aci_stat, uint8_t pipe, uint8_t *value, uint8_t size);
+
+/** @brief Sends Broadcast message to the radio.
+ *  @details The Broadcast message starts advertisement procedure 
+ *  using the given interval with the intention of broadcasting data to a peer device.
+ *  @param timeout Time, in seconds, to advertise before exiting to standby mode (0 means infinite).
+ *  Valid values: 0 to 16383.
+ *  @param adv_interval Advertising interval (in multiple of 0.625&nbsp;ms).
+ *  Valid values: 160 to 16384 (which corresponds to an interval from 100 ms to 10.24 s).
+ *  @return True if the broadcast message is sent successfully to the radio. 
+*/
+bool lib_aci_broadcast(const uint16_t timeout, const uint16_t adv_interval);
+
+/** @name Open Advertising Pipes.  */
+
+/** @brief Sends a command to the radio to set the input pipe to be placed in Advertisement Service Data.
+ *  @details This function sends a command to the radio that places the pipe in 
+ *  advertisement service data.  To start advertising service data, call this function before
+ *  Connecting, Broadcasting or Bonding to peer. The data that should be sent in the advertisement packets 
+ *  must be set using the @c lib_aci_set_local_data function. This function can be called during 
+ *  advertising to enable/disable broadcast pipes.  
+ *  @param pipe The pipe that has to be placed in advertising service data.
+ *  @return True if the Open Adv Pipe message is sent successfully to the radio. 
+*/
+bool lib_aci_open_adv_pipe(const uint8_t pipe);
+
+
+/** @name Open Advertising Pipes  */
+
+/** @brief Sends a command to the radio to set the pipes to be placed in Advertisement Service Data.
+ *  @details This function will send a command to the radio that will set the pipes to be placed in 
+ *  advertisement Service Data.  To start advertising service data, this function should be called before
+ *  Connecting, Broadcasting or Bonding to peer. This function can be called during 
+ *  advertising to enable/disable broadcast pipes. Use this as an alternative to @ref lib_aci_open_adv_pipe 
+ *  to avoid multiple function calls for placing multiple pipes in the adv data.
+ *  @param adv_service_data_pipes Pipe bitmap, where '1' indicates that the corresponding 
+ *  Valid Values: 0000000000000000 to FEFFFFFFFFFFFF7F (See the ACI Pipe Status Evt bitmap in the nRF8001 datasheet
+ *  TX_BROADCAST pipe data is to be placed in Advertising Service Data fields
+ *  @return true if the Open Adv Pipe message was sent successfully to the radio. 
+*/
+bool lib_aci_open_adv_pipes(const uint8_t * const adv_service_data_pipes);
+
+
+//@}
+
+/** @name ACI commands available in Connected mode */
+//@{
+
+
+/** @brief Sets a given application latency.
+ *  @details This function sends a @c setApplicationLatency command. 
+ *  @return True if the transaction is successfully initiated.
+ */
+bool lib_aci_set_app_latency(uint16_t latency, aci_app_latency_mode_t latency_mode);
+
+/** @brief Opens a remote pipe.
+ *  @details This function sends an @c OpenRemotePipe command.
+ *  @param pipe Number of the pipe to open.
+ *  @return True if the transaction is successfully initiated.
+ */
+bool lib_aci_open_remote_pipe(aci_state_t *aci_stat, uint8_t pipe);
+
+/** @brief Closes a remote pipe.
+ *  @details This function sends an @c CloseRemotePipe command.
+ *  @param pipe Pipe number to close.
+ *  @return True if the transaction is successfully initiated.
+ */
+bool lib_aci_close_remote_pipe(aci_state_t *aci_stat, uint8_t pipe);
+
+/** @brief Sends data on a given pipe.
+ *  @details This function sends a @c SendData command with application data to
+ *  the radio. This function memorizes credit use, and checks that
+ *  enough credits are available.
+ *  @param pipe Pipe number on which the data should be sent.
+ *  @param value Pointer to the data to send.
+ *  @param size Size of the data to send.
+ *  @return True if the transaction is successfully initiated.
+ */
+bool lib_aci_send_data(uint8_t pipe, uint8_t *value, uint8_t size);
+
+/** @brief Requests data from a given pipe.
+ *  @details This function sends a @c RequestData command to the radio. This
+ *  function memorizes credit uses, and check that enough credits are available.
+ *  After this command, the radio sends back either a @c DataReceivedEvent
+ *  or a @c PipeErrorEvent.
+ *  @param pipe Pipe number on which the data is requested.
+ *  @return True if the transaction is successfully initiated.
+ */
+bool lib_aci_request_data(aci_state_t *aci_stat, uint8_t pipe);
+
+/** @brief Sends a L2CAP change connection parameters request.
+ *  @details This function sends a @c ChangeTiming command to the radio.  This command triggers a "L2CAP change connection parameters" request 
+ *  to the master. If the master rejects or accepts but doesn't change the connection parameters within
+ *  30 seconds, a timing event with the unchanged connection parameters is sent by the radio.
+ *  If the request is accepted and the master changes connection parameters, a timing event with
+ *  the new connection parameters is sent by the radio.
+ *  If the master doesn't reply to the request within 60 seconds, the radio disconnects.
+ *  @param minimun_cx_interval Minimum connection interval requested, in multiple of 1.25&nbsp;ms.
+ *  @param maximum_cx_interval Maximum connection interval requested, in multiple of 1.25&nbsp;ms.
+ *  @param slave_latency requested slave latency.
+ *  @param timeout requested slave timeout, in multiple of 10&nbsp;ms.
+ *  @return True if the transaction is successfully initiated.
+ */
+bool lib_aci_change_timing(uint16_t minimun_cx_interval, uint16_t maximum_cx_interval, uint16_t slave_latency, uint16_t timeout);
+
+/** @brief Sends a L2CAP change connection parameters request with the connection predefined preffered connection parameters.
+ *  @details This function sends a @c ChangeTiming command to the radio. This command triggers a "L2CAP change connection parameters" request 
+ *  to the master. If the master rejects or accepts but doesn't change the connection parameters within
+ *  30 seconds, a timing event with the unchanged connection parameters is sent by the radio.
+ *  If the request is accepted and the master changes connection parameters, a timing event with
+ *  the new connection parameters is sent by the radio.
+ *  If the master doesn't reply to the request within 60 seconds, the radio disconnects.
+ *  The timing parameters used are the Timing parameters in the GAP settings in the nRFgo Studio.
+ *  The Timing parameters as stored as the GAP Preferred Peripheral Connection Parameters.
+ *  @return True if the transaction is successfully initiated.
+ */
+bool lib_aci_change_timing_GAP_PPCP(void);
+
+/** @brief Sends acknowledgement message to peer.
+ *  @details This function sends @c SendDataAck command to radio. The radio is expected 
+ *  to send either Handle Value Confirmation or Write response depending
+ *  on whether the data is stored remotely or locally.
+ *  @param pipe Pipe number for which the acknowledgement is to be sent.
+ *  @return True if the ack was sent successfully. False otherwise.
+*/
+bool lib_aci_send_ack(aci_state_t *aci_stat, const uint8_t pipe);
+
+/** @brief Sends negative acknowledgement message to peer.
+ *  @details This function sends @c SendDataNack command to radio. The radio is expected 
+ *  to send Error Response to the peer.
+ *  @param pipe Pipe number for which the nack is to be sent.
+ *  @param error_code Error code to be sent in the NACk.
+ *  @return True if the nack was sent successfully. False otherwise.
+*/
+bool lib_aci_send_nack(aci_state_t *aci_stat, const uint8_t pipe, const uint8_t error_code);
+
+/** @brief Sends ReadDynamicData command to the host. 
+ *  @details This function sends @c ReadDynamicData command to host. The host is expected 
+ *  to send @c CommandResponse back with the dynamic data. The application is expected to 
+ *  call this function in a loop until all the dynamic data is read out from the host. 
+ *  As long as there is dynamic data to be read from the host, the command response
+ *  for this message has its status field set to ACI_STATUS_TRANSACTION_CONTINUE (0x01).
+ *  The application may chose to store this read out data in a non-volatile memory location
+ *  and later chose to write it back using the function lib_aci_write_dynamic_data.
+ *  @return True if the command was sent successfully through the ACI. False otherwise.
+*/
+bool lib_aci_read_dynamic_data(void);
+
+/** @brief Sends WriteDynamicData command to the host.
+ *  @details This function sends @c WriteDynamicData command to host. The host is expected
+ *  to send @c CommandResponse with the status of this operation. As long as the status field 
+ *  in the @c CommandResponse is ACI_STATUS_TRANSACTION_CONTINUE (0x01), the hosts expects
+ *  more dynamic data to be written. This function should ideally be called in a cycle, 
+ *  until all the stored dynamic data is sent to the host. This function should be 
+ *  called with the dynamic data obtained from the response to a @c ReadDynamicData 
+ *  (see @c lib_aci_read_dynamic_data) command.
+ *  @param sequence_number Sequence number of the dynamic data to be sent.
+ *  @param dynamic_data Pointer to the dynamic data.
+ *  @param length Length of the dynamic data.
+ *  @return True if the command was sent successfully through the ACI. False otherwise.
+*/
+bool lib_aci_write_dynamic_data(uint8_t sequence_number, uint8_t* dynamic_data, uint8_t length);
+//@}
+
+/** @name ACI commands available while connected in Bond mode */
+//@{
+
+/** @brief Sends a SMP Security Request.
+ *  @details This function send a @c BondRequest command to the radio.
+ *  This command triggers a SMP Security Request to the master. If the
+ *  master rejects with a pairing failed or if the bond timer expires the connection is closed. 
+ *  @return True if the transaction is successfully initiated.
+ */
+bool lib_aci_bond_request(void);
+
+/** @brief Set the key requested by the 8001. 
+ *  @details This function sends an @c SetKey command to the radio. 
+ *  @param key_rsp_type Type of key.
+ *  @param key Pointer to the key to set.
+ *  @param len Length of the key.
+ *  @return True if the transaction is successfully initiated.
+*/
+bool lib_aci_set_key(aci_key_type_t key_rsp_type, uint8_t *key, uint8_t len);
+
+//@}
+
+
+
+/** @name ACI commands available in Test mode */
+//@{
+
+/** @brief Sends an echo message
+ *  @details This function sends an @c Echo command to the radio. lib_aci
+ *  places the Echp ACI command in the ACI command queue
+ *  @param message_size Length of the data to send.
+ *  @param message_data Pointer to the data to send.
+ *  @return True if the transaction is successfully initiated.
+*/
+bool lib_aci_echo_msg(uint8_t message_size, uint8_t *message_data);
+
+/** @brief Sends an DTM command
+ *  @details This function sends an @c DTM command to the radio. 
+ *  @param dtm_command_msbyte Most significant byte of the DTM command.
+ *  @param dtm_command_lsbyte Least significant byte of the DTM command.
+ *  @return True if the transaction is successfully initiated.
+*/
+bool lib_aci_dtm_command(uint8_t dtm_command_msbyte, uint8_t dtm_command_lsbyte);
+
+/** @brief Gets an ACI event from the ACI Event Queue
+ *  @details This function gets an ACI event from the ACI event queue. 
+ *  The queue is updated by the SPI driver for the ACI running in the interrupt context
+ *  @param aci_stat pointer to the state of the ACI.
+ *  @param p_aci_data pointer to the ACI Event. The ACI Event received will be copied into this pointer.
+ *  @return True if an ACI Event was copied to the pointer.
+*/
+bool lib_aci_event_get(aci_state_t *aci_stat, hal_aci_evt_t * aci_evt);
+
+/** @brief Peeks an ACI event from the ACI Event Queue
+ * @details This function peeks at the top event in the ACI event queue.
+ * In polling mode, this function will query the nRF8001 for pending events, but unlike
+ * lib_aci_event_get() it will not dequeue the event from the local queue, but will instead
+ * only peek at it.
+ * @return True if an ACI Event was copied to the pointer.
+*/
+bool lib_aci_event_peek(hal_aci_evt_t *p_aci_evt_data);
+
+/** @brief Flushes the events in the ACI command queues and ACI Event queue
+ *
+*/
+void lib_aci_flush(void);
+
+/** @brief Return full status of the Event queue
+ *  @details
+ *
+ */
+ bool lib_aci_event_queue_full(void);
+ 
+ /** @brief Return empty status of the Event queue
+ *  @details
+ *
+ */
+ bool lib_aci_event_queue_empty(void);
+
+/** @brief Return full status of Command queue
+ *  @details
+ *
+ */
+ bool lib_aci_command_queue_full(void);
+ 
+ /** @brief Return empty status of Command queue
+ *  @details
+ *
+ */
+ bool lib_aci_command_queue_empty(void);
+
+//@}
+
+/** @} */
+
+#endif /* LIB_ACI_H__ */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/flash_file/Makefile.config
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/flash_file/Makefile.config	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/flash_file/Makefile.config	(revision 457)
@@ -0,0 +1,55 @@
+#
+#   TOPPERS/ASP/FMP Kernel
+#       Toyohashi Open Platform for Embedded Real-Time Systems/
+#       Advanced Standard Profile Kernel
+#
+#   Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
+#                               Toyohashi Univ. of Technology, JAPAN
+#   Copyright (C) 2003-2008 by Ryosuke Takeuchi
+#                Platform Development Center RICOH COMPANY,LTD. JAPAN
+#   Copyright (C) 2015-2017 by TOPPERS PROJECT Educational Working Group.
+#
+#   上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+#   によって公表されている GNU General Public License の Version 2 に記
+#   述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+#   を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+#   利用と呼ぶ）することを無償で許諾する．
+#   (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+#       権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+#       スコード中に含まれていること．
+#   (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+#       用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+#       者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+#       の無保証規定を掲載すること．
+#   (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+#       用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+#       と．
+#     (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+#         作権表示，この利用条件および下記の無保証規定を掲載すること．
+#     (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+#         報告すること．
+#   (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+#       害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+#
+#   本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+#   よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+#   含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+#   接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+#
+#  @(#) $Id$
+#
+ 
+#
+#  Makefile のプロセッサ依存 (flash_file用)
+#
+
+#
+#  コンパイルオプション
+#
+INCLUDES := $(INCLUDES) -I$(SRCDIR)/gdic/flash_file
+
+#
+#  SPI DRIVER(GDIC)に関する定義
+#
+SYSSVC_DIR := $(SYSSVC_DIR):$(SRCDIR)/gdic/flash_file
+SYSSVC_COBJS := $(SYSSVC_COBJS) flash_file.o
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/flash_file/flash_file.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/flash_file/flash_file.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/flash_file/flash_file.c	(revision 457)
@@ -0,0 +1,344 @@
+/*
+ *  TOPPERS/ASP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Advanced Standard Profile Kernel
+ * 
+ *  Copyright (C) 2008-2011 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ *  Copyright (C) 2015-2018 by TOPPERS PROJECT Educational Working Group.
+ * 
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+#include <kernel.h>
+#include <t_syslog.h>
+#include <t_stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <target_syssvc.h>
+#include "syssvc/serial.h"
+#include "syssvc/syslog.h"
+#include "device.h"
+#include "qspi.h"
+#include <fcntl.h>
+#include "storagedevice.h"
+#include "flash_file.h"
+
+#define MIN(a, b) ((a) > (b) ? (b) : (a))
+
+#define QSPIBUFLENGTH    512
+
+static QSPI_Handle_t *hqspi;
+static int           num_files = 0;
+static int           dirreadcount;
+static fs_descrip_t  fs_descrip_table[MAX_DESCRIP];
+static uint32_t      qspibuff[(QSPIBUFLENGTH+8)/sizeof(uint32_t)];
+
+static void  *ffs_opendir(const char *pathname);
+static int   ffs_closedir(void *dir);
+static int   ffs_readdir(void *dir, void *pdirent);
+static int   ffs_open(int devno, const char *pathname, int flags);
+static int   ffs_close(int fd);
+static int   ffs_fstat(int fd, struct stat *buf);
+static off_t ffs_lseek(int fd, off_t offset, int whence, int *res);
+static long  ffs_read(int fd, void *buf, long count, int *res);
+
+static const StorageDeviceFileFunc_t romSDeviceFunc = {
+	ffs_opendir,
+	ffs_closedir,
+	ffs_readdir,
+	0,
+	0,
+	0,
+	0,
+	0,
+	0,
+	0,
+	ffs_open,
+	ffs_close,
+	ffs_fstat,
+	ffs_lseek,
+	ffs_read,
+	0,
+	0
+};
+
+
+/*
+ *  FLASH-ROMファイル関数郡の初期化
+ */
+ER
+flash_file_init(void *h)
+{
+	StorageDevice_t *psdev;
+	int result;
+
+	num_files = 0;
+	memset(fs_descrip_table, 0, sizeof(fs_descrip_table));
+	result = SDMSetupDevice(DEFAULT_DEVNO, &psdev);
+	if(result == E_OK){
+		psdev->pdevff           = (StorageDeviceFileFunc_t *)&romSDeviceFunc;
+		psdev->_sdev_attribute |= SDEV_EMPLOY;
+		hqspi = (QSPI_Handle_t *)h;
+		return MAX_DESCRIP;
+	}
+	else
+		return 0;
+}
+
+/*
+ *  FLASH-ROMファイルの生成
+ */
+int
+create_flash_file(const char *pathname, uint32_t start, uint32_t size)
+{
+	fs_descrip_t  *fdp;
+	int           cd = -1;
+	int           i, j;
+
+	dis_dsp();			/* disable dispatch */
+	for(i = 0 ; i < MAX_DESCRIP ; i++){
+		fdp = &fs_descrip_table[i];
+		if(fdp->create == 0){
+			fdp->create   = 1;
+			fdp->inuse    = 0;
+			fdp->fp       = 0;
+			fdp->addr     = start;
+			fdp->size     = size;
+			for(j = 0 ; j < ROMFILE_SIZE && pathname[j] != 0 ; j++)
+				fdp->filename[j] = (char)pathname[j];
+			fdp->filename[j] = 0;
+			cd = i;
+			num_files++;
+			break;
+		}
+	}
+	ena_dsp();			/* enable dispatch */
+	return cd;
+}
+
+/*
+ *  FLASH-ROMファイルディレクトリオープン
+ */
+static void *
+ffs_opendir(const char *pathname)
+{
+	dirreadcount = 0;
+	return (void *)&num_files;
+}
+
+/*
+ *  FLASH-ROMファイルディレクトリクローズ
+ */
+static int
+ffs_closedir(void *dir)
+{
+	return 0;
+}
+
+/*
+ *  FLASH-ROMファイルディレクトリ読み込み
+ */
+static int
+ffs_readdir(void *dir, void *pdirent)
+{
+	fs_descrip_t   *pf;
+	struct dirent2 *pd = pdirent;
+	unsigned int   i;
+
+	if(dirreadcount >= num_files)
+		return 0;
+	else{
+		pf = &fs_descrip_table[dirreadcount];
+		pd->d_fsize = pf->size;
+		pd->d_date  = 0;
+		pd->d_time  = 0;
+		pd->d_type  = AM_RDO;
+		for(i = 0 ; i < 255 && pf->filename[i] != 0 ; i++){
+			pd->d_name[i] = pf->filename[i];
+		}
+		pd->d_name[i] = 0;
+		dirreadcount++;
+		return dirreadcount;
+	}
+}
+
+/*
+ *  FLASH-ROMファイルオープン
+ */
+static int
+ffs_open(int devno, const char *pathname, int flags)
+{
+	fs_descrip_t  *fdp = 0;
+	int           fd;
+
+	SDMGetDeviceNo(&pathname);
+	if(*pathname == '/')
+		pathname++;
+	dis_dsp();			/* disable dispatch */
+	for(fd = 0 ; fd < num_files ; fd++){
+		fdp = &fs_descrip_table[fd];
+		if(fdp->create && strcmp(pathname, fdp->filename) == 0){
+			break;
+		}
+	}
+	if(fd < num_files && (flags & 0x0f) == O_RDONLY && fdp->inuse == 0){
+		fdp->inuse = 1;
+		fdp->fp = 0;
+		ena_dsp();			/* enable dispatch */
+		return fd;
+	}
+	else{
+		ena_dsp();			/* enable dispatch */
+		return -1;
+	}
+}
+
+/*
+ *  FLASH-ROMファイルクローズ
+ */
+static int
+ffs_close(int fd)
+{
+	fs_descrip_t  *fdp;
+
+	if(fd < 0 || num_files < fd)
+		return -1;
+	fdp = &fs_descrip_table[fd];
+	if(fdp->inuse == 1){
+		fdp->inuse = 0;
+		return 0;
+	}
+	else
+		return -1;
+}
+
+/*
+ *  FLASH-ROMファイルステート取得
+ */
+static int
+ffs_fstat(int fd, struct stat *buf)
+{
+	fs_descrip_t  *fdp;
+
+	if(fd < 0 || num_files < fd)
+		return -1;
+	fdp = &fs_descrip_table[fd];
+	if(fdp->create == 1){
+		memset(buf, 0, sizeof(struct stat));
+		buf->st_size = fdp->size;
+		return 0;
+	}
+	else
+		return -1;
+}
+
+/*
+ *  FLASH-ROMファイルシーク
+ */
+static off_t
+ffs_lseek(int fd, off_t offset, int whence, int *res)
+{
+	fs_descrip_t  *fdp;
+
+	*res = -1;
+	if(fd < 0 || num_files < fd)
+		return -1;
+	fdp = &fs_descrip_table[fd];
+	if(fdp->inuse == 1){
+		switch (whence) {
+		case SEEK_SET:
+			fdp->fp = offset;
+			break;
+		case SEEK_CUR:
+			fdp->fp += offset;
+			break;
+		case SEEK_END:
+			fdp->fp = fdp->size + offset;
+			break;
+		}
+		offset = fdp->fp;
+		*res = 0;
+		return offset;
+	}
+	else
+		return -1;
+}
+
+/*
+ *  FLASH-ROMファイル読みだし
+ */
+static long
+ffs_read(int fd, void *buf, long count, int *res)
+{
+	fs_descrip_t*fdp;
+	int         readsize, length;
+	uint32_t    fp, rcount, off;
+	ER          ercd = E_OK;
+
+	*res = -1;
+	if(fd < 0 || num_files < fd)
+		return -1;
+	fdp = &fs_descrip_table[fd];
+	if(fdp->inuse == 1){
+		if(fdp->fp < fdp->size){
+			if((fdp->fp + count) <= fdp->size)
+				readsize = count;	/* all counts can be read */
+			else
+				readsize = fdp->size - fdp->fp;	/* a part of counts can be read */
+			length = readsize;
+			fp     = fdp->fp;
+			while(length > 0){
+				off = ((unsigned int)fdp->addr + fp) & 3;
+				rcount = MIN(QSPIBUFLENGTH, length);
+				ercd = qspi_read(hqspi, (void *)qspibuff, (uint32_t)(fdp->addr + fp - off), ((rcount+off+3) & ~3));
+				if(ercd != E_OK){
+					syslog_4(LOG_ERROR, "ffs_read(%d, %08x, %d, %08x) ERROR !", fd, buf, count, res);
+					break;
+				}
+				memcpy(buf, ((uint8_t *)qspibuff)+off, rcount);
+				fp  += rcount;
+				buf += rcount;
+				length -= rcount;
+			}
+			fdp->fp += readsize;
+		}
+		else
+			readsize = 0;	/* no data can be read */
+		*res = 0;
+		if(ercd == E_OK)
+			return readsize;
+		else
+			return 0;
+	}
+	else
+		return -1;
+}
+
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/flash_file/flash_file.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/flash_file/flash_file.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/flash_file/flash_file.h	(revision 457)
@@ -0,0 +1,76 @@
+/*
+ *  TOPPERS/ASP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Advanced Standard Profile Kernel
+ * 
+ *  Copyright (C) 2008-2011 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ *  Copyright (C) 2015-2018 by TOPPERS PROJECT Educational Working Group.
+ * 
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+#ifndef _FLASH_FILE_H_
+#define _FLASH_FILE_H_
+
+#include <kernel.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef MAX_DESCRIP
+#define	MAX_DESCRIP     16
+#endif
+#define ROMFILE_SIZE    27
+
+#ifndef TOPPERS_MACRO_ONLY
+
+typedef struct fs_descrip_s {
+  unsigned      create  : 1;
+  unsigned      inuse   : 1;
+  unsigned      size    : 30;
+  uint32_t      fp;
+  uint32_t      addr;
+  char          filename[ROMFILE_SIZE+1];
+} fs_descrip_t;
+
+
+extern ER  flash_file_init(void *h);
+extern int create_flash_file(const char *pathname, uint32_t start, uint32_t size);
+
+#endif /* TOPPERS_MACRO_ONLY */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _FLASHFILE_H_ */
+
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/rom_file/Makefile.config
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/rom_file/Makefile.config	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/rom_file/Makefile.config	(revision 457)
@@ -0,0 +1,49 @@
+#
+#   TOPPERS BASE PLATFORM MIDDLEWARE
+#
+#   Copyright (C) 2015-2019 by TOPPERS PROJECT Educational Working Group.
+#
+#   上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+#   によって公表されている GNU General Public License の Version 2 に記
+#   述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+#   を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+#   利用と呼ぶ）することを無償で許諾する．
+#   (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+#       権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+#       スコード中に含まれていること．
+#   (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+#       用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+#       者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+#       の無保証規定を掲載すること．
+#   (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+#       用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+#       と．
+#     (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+#         作権表示，この利用条件および下記の無保証規定を掲載すること．
+#     (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+#         報告すること．
+#   (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+#       害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+#
+#   本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+#   よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+#   含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+#   接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+#
+#  @(#) $Id$
+#
+ 
+#
+#  Makefile のプロセッサ依存 (rom_file用)
+#
+
+#
+#  コンパイルオプション
+#
+INCLUDES := $(INCLUDES) -I$(SRCDIR)/gdic/rom_file
+
+#
+#  SPI DRIVER(GDIC)に関する定義
+#
+SYSSVC_DIR := $(SYSSVC_DIR):$(SRCDIR)/gdic/rom_file
+SYSSVC_COBJS := $(SYSSVC_COBJS) rom_file.o
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/rom_file/rom_file.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/rom_file/rom_file.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/rom_file/rom_file.c	(revision 457)
@@ -0,0 +1,314 @@
+/*
+ *  TOPPERS BASE PLATFORM MIDDLEWARE
+ * 
+ *  Copyright (C) 2017-2019 by TOPPERS PROJECT
+ *                             Educational Working Group.
+ * 
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+#include <kernel.h>
+#include <t_syslog.h>
+#include <t_stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <target_syssvc.h>
+#include "syssvc/serial.h"
+#include "syssvc/syslog.h"
+#include "device.h"
+#include <fcntl.h>
+#include "storagedevice.h"
+#include "rom_file.h"
+
+
+static int           num_files = 0;
+static int           dirreadcount;
+static fs_descrip_t  fs_descrip_table[MAX_DESCRIP];
+
+static void  *romf_opendir(const char *pathname);
+static int   romf_closedir(void *dir);
+static int   romf_readdir(void *dir, void *pdirent);
+static int   romf_open(int devno, const char *pathname, int flags);
+static int   romf_close(int fd);
+static int   romf_fstat(int fd, struct stat *buf);
+static off_t romf_lseek(int fd, off_t offset, int whence, int *res);
+static long  romf_read(int fd, void *buf, long count, int *res);
+
+static const StorageDeviceFileFunc_t romfSDeviceFunc = {
+	romf_opendir,
+	romf_closedir,
+	romf_readdir,
+	0,
+	0,
+	0,
+	0,
+	0,
+	0,
+	0,
+	romf_open,
+	romf_close,
+	romf_fstat,
+	romf_lseek,
+	romf_read,
+	0,
+	0
+};
+
+
+/*
+ *  FLASH-ROMファイル関数郡の初期化
+ */
+ER
+rom_file_init(void)
+{
+	StorageDevice_t *psdev;
+	int result;
+
+	num_files = 0;
+	memset(fs_descrip_table, 0, sizeof(fs_descrip_table));
+	result = SDMSetupDevice(DEFAULT_DEVNO, &psdev);
+	if(result == E_OK){
+		psdev->pdevff           = (StorageDeviceFileFunc_t *)&romfSDeviceFunc;
+		psdev->_sdev_attribute |= SDEV_EMPLOY;
+		return MAX_DESCRIP;
+	}
+	else
+		return 0;
+}
+
+/*
+ *  ROMファイルの生成
+ */
+int
+create_rom_file(const char *pathname, uintptr_t start, uint32_t size)
+{
+	fs_descrip_t  *fdp;
+	int           cd = -1;
+	int           i;
+
+	dis_dsp();			/* disable dispatch */
+	for(i = 0 ; i < MAX_DESCRIP ; i++){
+		fdp = &fs_descrip_table[i];
+		if(fdp->create == 0){
+			fdp->create   = 1;
+			fdp->inuse    = 0;
+			fdp->fp       = 0;
+			fdp->addr     = start;
+			fdp->size     = size;
+			fdp->filename = pathname;
+			cd = i;
+			num_files++;
+			break;
+		}
+	}
+	ena_dsp();			/* enable dispatch */
+	return cd;
+}
+
+/*
+ *  FLASH-ROMファイルディレクトリオープン
+ */
+static void *
+romf_opendir(const char *pathname)
+{
+	dirreadcount = 0;
+	return (void *)&num_files;
+}
+
+/*
+ *  ROMファイルディレクトリクローズ
+ */
+static int
+romf_closedir(void *dir)
+{
+	return 0;
+}
+
+/*
+ *  ROMファイルディレクトリ読み込み
+ */
+static int
+romf_readdir(void *dir, void *pdirent)
+{
+	fs_descrip_t   *pf;
+	struct dirent2 *pd = pdirent;
+	unsigned int   i;
+
+	if(dirreadcount >= num_files)
+		return 0;
+	else{
+		pf = &fs_descrip_table[dirreadcount];
+		pd->d_fsize = pf->size;
+		pd->d_date  = 0;
+		pd->d_time  = 0;
+		pd->d_type  = AM_RDO;
+		for(i = 0 ; i < 255 && pf->filename[i] != 0 ; i++){
+			pd->d_name[i] = pf->filename[i];
+		}
+		pd->d_name[i] = 0;
+		dirreadcount++;
+		return dirreadcount;
+	}
+}
+
+/*
+ *  ROMファイルオープン
+ */
+static int
+romf_open(int devno, const char *pathname, int flags)
+{
+	fs_descrip_t  *fdp = 0;
+	int           fd;
+
+	SDMGetDeviceNo(&pathname);
+	if(*pathname == '/')
+		pathname++;
+	dis_dsp();			/* disable dispatch */
+	for(fd = 0 ; fd < num_files ; fd++){
+		fdp = &fs_descrip_table[fd];
+		if(fdp->create && strcmp(pathname, fdp->filename) == 0){
+			break;
+		}
+	}
+	if(fd < num_files && (flags & 0x0f) == O_RDONLY && fdp->inuse == 0){
+		fdp->inuse = 1;
+		fdp->fp = 0;
+		ena_dsp();			/* enable dispatch */
+		return fd;
+	}
+	else{
+		ena_dsp();			/* enable dispatch */
+		return -1;
+	}
+}
+
+/*
+ *  ROMファイルクローズ
+ */
+static int
+romf_close(int fd)
+{
+	fs_descrip_t  *fdp;
+
+	if(fd < 0 || num_files < fd)
+		return -1;
+	fdp = &fs_descrip_table[fd];
+	if(fdp->inuse == 1){
+		fdp->inuse = 0;
+		return 0;
+	}
+	else
+		return -1;
+}
+
+/*
+ *  ROMファイルステート取得
+ */
+static int
+romf_fstat(int fd, struct stat *buf)
+{
+	fs_descrip_t  *fdp;
+
+	if(fd < 0 || num_files < fd)
+		return -1;
+	fdp = &fs_descrip_table[fd];
+	if(fdp->create == 1){
+		memset(buf, 0, sizeof(struct stat));
+		buf->st_size = fdp->size;
+		return 0;
+	}
+	else
+		return -1;
+}
+
+/*
+ *  ROMファイルシーク
+ */
+static off_t
+romf_lseek(int fd, off_t offset, int whence, int *res)
+{
+	fs_descrip_t  *fdp;
+
+	*res = -1;
+	if(fd < 0 || num_files < fd)
+		return -1;
+	fdp = &fs_descrip_table[fd];
+	if(fdp->inuse == 1){
+		switch (whence) {
+		case SEEK_SET:
+			fdp->fp = offset;
+			break;
+		case SEEK_CUR:
+			fdp->fp += offset;
+			break;
+		case SEEK_END:
+			fdp->fp = fdp->size + offset;
+			break;
+		}
+		offset = fdp->fp;
+		*res = 0;
+		return offset;
+	}
+	else
+		return -1;
+}
+
+/*
+ *  ROMファイル読みだし
+ */
+static long
+romf_read(int fd, void *buf, long count, int *res)
+{
+	fs_descrip_t*fdp;
+	int         readsize;
+
+	*res = -1;
+	if(fd < 0 || num_files < fd)
+		return -1;
+	fdp = &fs_descrip_table[fd];
+	if(fdp->inuse == 1){
+		if(fdp->fp < fdp->size){
+			if((fdp->fp + count) <= fdp->size)
+				readsize = count;	/* all counts can be read */
+			else
+				readsize = fdp->size - fdp->fp;	/* a part of counts can be read */
+			memcpy(buf, ((uint8_t *)fdp->addr + fdp->fp), readsize);
+			buf += readsize;
+			fdp->fp += readsize;
+		}
+		else
+			readsize = 0;	/* no data can be read */
+		*res = 0;
+		return readsize;
+	}
+	else
+		return -1;
+}
+
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/rom_file/rom_file.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/rom_file/rom_file.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/rom_file/rom_file.h	(revision 457)
@@ -0,0 +1,72 @@
+/*
+ *  TOPPERS BASE PLATFORM MIDDLEWARE
+ * 
+ *  Copyright (C) 2017-2019 by TOPPERS PROJECT
+ *                             Educational Working Group.
+ * 
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+#ifndef _ROM_FILE_H_
+#define _ROM_FILE_H_
+
+#include <kernel.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef MAX_DESCRIP
+#define	MAX_DESCRIP     16
+#endif
+
+#ifndef TOPPERS_MACRO_ONLY
+
+typedef struct fs_descrip_s {
+  unsigned      create  : 1;
+  unsigned      inuse   : 1;
+  unsigned      size    : 30;
+  uintptr_t     fp;
+  uintptr_t     addr;
+  const char    *filename;
+} fs_descrip_t;
+
+
+extern ER  rom_file_init(void);
+extern int create_rom_file(const char *pathname, uintptr_t start, uint32_t size);
+
+#endif /* TOPPERS_MACRO_ONLY */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _ROM_FILE_H_ */
+
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/sipeed_ov2640/Makefile.config
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/sipeed_ov2640/Makefile.config	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/sipeed_ov2640/Makefile.config	(revision 457)
@@ -0,0 +1,55 @@
+#
+#   TOPPERS/ASP/FMP Kernel
+#       Toyohashi Open Platform for Embedded Real-Time Systems/
+#       Advanced Standard Profile Kernel
+#
+#   Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
+#                               Toyohashi Univ. of Technology, JAPAN
+#   Copyright (C) 2003-2008 by Ryosuke Takeuchi
+#                Platform Development Center RICOH COMPANY,LTD. JAPAN
+#   Copyright (C) 2015-2019 by TOPPERS PROJECT Educational Working Group.
+#
+#   上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+#   によって公表されている GNU General Public License の Version 2 に記
+#   述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+#   を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+#   利用と呼ぶ）することを無償で許諾する．
+#   (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+#       権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+#       スコード中に含まれていること．
+#   (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+#       用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+#       者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+#       の無保証規定を掲載すること．
+#   (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+#       用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+#       と．
+#     (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+#         作権表示，この利用条件および下記の無保証規定を掲載すること．
+#     (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+#         報告すること．
+#   (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+#       害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+#
+#   本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+#   よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+#   含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+#   接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+#
+#  @(#) $Id$
+#
+ 
+#
+#  Makefile のプロセッサ依存 (sipeed ov2640:CAMERA用)
+#
+
+#
+#  コンパイルオプション
+#
+INCLUDES := $(INCLUDES) -I$(SRCDIR)/gdic/sipeed_ov2640
+
+#
+#  SIPEED OV2640 CAMERA DRIVER(GDIC)に関する定義
+#
+SYSSVC_DIR := $(SYSSVC_DIR):$(SRCDIR)/gdic/sipeed_ov2640
+SYSSVC_COBJS := $(SYSSVC_COBJS) sipeed_ov2640.o 
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/sipeed_ov2640/ov2640_regs.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/sipeed_ov2640/ov2640_regs.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/sipeed_ov2640/ov2640_regs.h	(revision 457)
@@ -0,0 +1,212 @@
+/*
+ * This file is part of the OpenMV project.
+ * Copyright (c) 2013/2014 Ibrahim Abdelkader <i.abdalkader@gmail.com>
+ * This work is licensed under the MIT license, see the file LICENSE for details.
+ *
+ * OV2640 register definitions.
+ */
+
+#ifndef __REG_REGS_H__
+#define __REG_REGS_H__
+
+/* DSP register bank FF=0x00*/
+
+#define QS                      0x44
+#define HSIZE                   0x51
+#define VSIZE                   0x52
+#define XOFFL                   0x53
+#define YOFFL                   0x54
+#define VHYX                    0x55
+#define DPRP                    0x56
+#define TEST                    0x57
+#define ZMOW                    0x5A
+#define ZMOH                    0x5B
+#define ZMHH                    0x5C
+#define BPADDR                  0x7C
+#define BPDATA                  0x7D
+#define SIZEL                   0x8C
+#define HSIZE8                  0xC0
+#define VSIZE8                  0xC1
+#define CTRL1                   0xC3
+#define MS_SP                   0xF0
+#define SS_ID                   0xF7
+#define SS_CTRL                 0xF7
+#define MC_AL                   0xFA
+#define MC_AH                   0xFB
+#define MC_D                    0xFC
+#define P_CMD                   0xFD
+#define P_STATUS                0xFE
+
+#define CTRLI                   0x50
+#define CTRLI_LP_DP             0x80
+#define CTRLI_ROUND             0x40
+
+#define CTRL0                   0xC2
+#define CTRL0_AEC_EN            0x80
+#define CTRL0_AEC_SEL           0x40
+#define CTRL0_STAT_SEL          0x20
+#define CTRL0_VFIRST            0x10
+#define CTRL0_YUV422            0x08
+#define CTRL0_YUV_EN            0x04
+#define CTRL0_RGB_EN            0x02
+#define CTRL0_RAW_EN            0x01
+
+#define CTRL2                   0x86
+#define CTRL2_DCW_EN            0x20
+#define CTRL2_SDE_EN            0x10
+#define CTRL2_UV_ADJ_EN         0x08
+#define CTRL2_UV_AVG_EN         0x04
+#define CTRL2_CMX_EN            0x01
+
+#define CTRL3                   0x87
+#define CTRL3_BPC_EN            0x80
+#define CTRL3_WPC_EN            0x40
+#define R_DVP_SP                0xD3
+#define R_DVP_SP_AUTO_MODE      0x80
+
+#define R_BYPASS                0x05
+#define R_BYPASS_DSP_EN         0x00
+#define R_BYPASS_DSP_BYPAS      0x01
+
+#define IMAGE_MODE              0xDA
+#define IMAGE_MODE_Y8_DVP_EN    0x40
+#define IMAGE_MODE_JPEG_EN      0x10
+#define IMAGE_MODE_YUV422       0x00
+#define IMAGE_MODE_RAW10        0x04
+#define IMAGE_MODE_RGB565       0x08
+#define IMAGE_MODE_HREF_VSYNC   0x02
+#define IMAGE_MODE_LBYTE_FIRST  0x01
+#define IMAGE_MODE_GET_FMT(x)   ((x)&0xC)
+
+#define RESET                   0xE0
+#define RESET_MICROC            0x40
+#define RESET_SCCB              0x20
+#define RESET_JPEG              0x10
+#define RESET_DVP               0x04
+#define RESET_IPU               0x02
+#define RESET_CIF               0x01
+
+#define MC_BIST                 0xF9
+#define MC_BIST_RESET           0x80
+#define MC_BIST_BOOT_ROM_SEL    0x40
+#define MC_BIST_12KB_SEL        0x20
+#define MC_BIST_12KB_MASK       0x30
+#define MC_BIST_512KB_SEL       0x08
+#define MC_BIST_512KB_MASK      0x0C
+#define MC_BIST_BUSY_BIT_R      0x02
+#define MC_BIST_MC_RES_ONE_SH_W 0x02
+#define MC_BIST_LAUNCH          0x01
+
+#define BANK_SEL                0xFF
+#define BANK_SEL_DSP            0x00
+#define BANK_SEL_SENSOR         0x01
+
+/* Sensor register bank FF=0x01*/
+
+#define GAIN                0x00
+#define COM1                0x03
+#define REG_PID             0x0A
+#define REG_VER             0x0B
+#define COM4                0x0D
+#define AEC                 0x10
+
+#define CLKRC               0x11
+#define CLKRC_DOUBLE        0x80
+#define CLKRC_DIVIDER_MASK  0x3F
+
+#define COM10               0x15
+#define HSTART              0x17
+#define HSTOP               0x18
+#define VSTART              0x19
+#define VSTOP               0x1A
+#define MIDH                0x1C
+#define MIDL                0x1D
+#define AEW                 0x24
+#define AEB                 0x25
+#define REG2A               0x2A
+#define FRARL               0x2B
+#define ADDVSL              0x2D
+#define ADDVSH              0x2E
+#define YAVG                0x2F
+#define HSDY                0x30
+#define HEDY                0x31
+#define ARCOM2              0x34
+#define REG45               0x45
+#define FLL                 0x46
+#define FLH                 0x47
+#define COM19               0x48
+#define ZOOMS               0x49
+#define COM22               0x4B
+#define COM25               0x4E
+#define BD50                0x4F
+#define BD60                0x50
+#define REG5D               0x5D
+#define REG5E               0x5E
+#define REG5F               0x5F
+#define REG60               0x60
+#define HISTO_LOW           0x61
+#define HISTO_HIGH          0x62
+
+#define REG04               0x04
+#define REG04_DEFAULT       0x28
+#define REG04_HFLIP_IMG     0x80
+#define REG04_VFLIP_IMG     0x40
+#define REG04_VREF_EN       0x10
+#define REG04_HREF_EN       0x08
+#define REG04_SET(x)        (REG04_DEFAULT|x)
+
+#define REG08               0x08
+#define COM2                0x09
+#define COM2_STDBY          0x10
+#define COM2_OUT_DRIVE_1x   0x00
+#define COM2_OUT_DRIVE_2x   0x01
+#define COM2_OUT_DRIVE_3x   0x02
+#define COM2_OUT_DRIVE_4x   0x03
+
+#define COM3                0x0C
+#define COM3_DEFAULT        0x38
+#define COM3_BAND_50Hz      0x04
+#define COM3_BAND_60Hz      0x00
+#define COM3_BAND_AUTO      0x02
+#define COM3_BAND_SET(x)    (COM3_DEFAULT|x)
+
+#define COM7                0x12
+#define COM7_SRST           0x80
+#define COM7_RES_UXGA       0x00 /* UXGA */
+#define COM7_RES_SVGA       0x40 /* SVGA */
+#define COM7_RES_CIF        0x20 /* CIF  */
+#define COM7_ZOOM_EN        0x04 /* Enable Zoom */
+#define COM7_COLOR_BAR      0x02 /* Enable Color Bar Test */
+#define COM7_GET_RES(x)     ((x)&0x70)
+
+#define COM8                0x13
+#define COM8_DEFAULT        0xC0
+#define COM8_BNDF_EN        0x20 /* Enable Banding filter */
+#define COM8_AGC_EN         0x04 /* AGC Auto/Manual control selection */
+#define COM8_AEC_EN         0x01 /* Auto/Manual Exposure control */
+#define COM8_SET(x)         (COM8_DEFAULT|x)
+#define COM8_SET_AEC(r,x)   (((r)&0xFE)|((x)&1))
+
+#define COM9                0x14 /* AGC gain ceiling */
+#define COM9_DEFAULT        0x08
+#define COM9_AGC_GAIN_2x    0x00 /* AGC:    2x */
+#define COM9_AGC_GAIN_4x    0x01 /* AGC:    4x */
+#define COM9_AGC_GAIN_8x    0x02 /* AGC:    8x */
+#define COM9_AGC_GAIN_16x   0x03 /* AGC:   16x */
+#define COM9_AGC_GAIN_32x   0x04 /* AGC:   32x */
+#define COM9_AGC_GAIN_64x   0x05 /* AGC:   64x */
+#define COM9_AGC_GAIN_128x  0x06 /* AGC:  128x */
+#define COM9_AGC_SET(x)     (COM9_DEFAULT|(x<<5))
+
+#define CTRL1_AWB           0x08 /* Enable AWB */
+
+#define VV                  0x26
+#define VV_AGC_TH_SET(h,l)  ((h<<4)|(l&0x0F))
+
+#define REG32               0x32
+#define REG32_UXGA          0x36
+#define REG32_SVGA          0x09
+#define REG32_CIF           0x00
+
+#endif //__REG_REGS_H__
+
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/sipeed_ov2640/sipeed_ov2640.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/sipeed_ov2640/sipeed_ov2640.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/sipeed_ov2640/sipeed_ov2640.c	(revision 457)
@@ -0,0 +1,1102 @@
+/*
+ *  TOPPERS/ASP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Advanced Standard Profile Kernel
+ * 
+ *  Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
+ *                              Toyohashi Univ. of Technology, JAPAN
+ *  Copyright (C) 2004-2012 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ *  Copyright (C) 2015-2019 by TOPPERS PROJECT Educational Working Group.
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  $Id$
+ */
+/* 
+ *  SIPEED OV2640 CAMARA制御プログラムの本体
+ */
+
+#include <kernel.h>
+#include <t_syslog.h>
+#include <target_syssvc.h>
+#include "device.h"
+
+#include "dvp.h"
+#include "ov2640_regs.h"
+#include "stdlib.h"
+#include "math.h"
+#include "sipeed_ov2640.h"
+
+
+#define IM_MAX(a,b)     ({ __typeof__ (a) _a = (a); __typeof__ (b) _b = (b); _a > _b ? _a : _b; })
+#define IM_MIN(a,b)     ({ __typeof__ (a) _a = (a); __typeof__ (b) _b = (b); _a < _b ? _a : _b; })
+#define IM_DIV(a,b)     ({ __typeof__ (a) _a = (a); __typeof__ (b) _b = (b); _b ? (_a / _b) : 0; })
+#define IM_MOD(a,b)     ({ __typeof__ (a) _a = (a); __typeof__ (b) _b = (b); _b ? (_a % _b) : 0; })
+
+#ifndef SNAPSHOT_TIMEOUT
+#define SNAPDHOT_TIMEOUT    300
+#endif
+
+
+#define SVGA_HSIZE     (800)
+#define SVGA_VSIZE     (600)
+
+#define UXGA_HSIZE     (1600)
+#define UXGA_VSIZE     (1200)
+static const uint8_t ov2640_default[][2] = { //k210 
+	{0xff, 0x01},
+	{0x12, 0x80},
+	{0xff, 0x00},
+	{0x2c, 0xff},
+	{0x2e, 0xdf},
+	{0xff, 0x01},
+	{0x3c, 0x32},
+	{0x11, 0x00},
+	{0x09, 0x02},
+	{0x04, 0xa8},//v flip and h mirro
+	{0x13, 0xe5},
+	{0x14, 0x48},
+	{0x2c, 0x0c},
+	{0x33, 0x78},
+	{0x3a, 0x33},
+	{0x3b, 0xfb},
+	{0x3e, 0x00},
+	{0x43, 0x11},
+	{0x16, 0x10},
+	{0x39, 0x92},//test 92
+	{0x23, 0x00},
+	{0x36, 0x1a},
+	{0x07, 0xc0},
+	{0x4c, 0x00},
+	{0x48, 0x00},
+	{0x5b, 0x00},
+	{0x4a, 0x81},
+	{0x21, 0x99},
+	{0x24, 0x40},
+	{0x25, 0x38},
+	{0x26, 0x82},
+	{0x5c, 0x00},
+	{0x63, 0x00},
+	{0x46, 0x22},
+	{0x0c, 0x3c},
+	{0x61, 0x70},
+	{0x62, 0x80},
+	{0x7c, 0x05},
+	{0x20, 0x80},
+	{0x28, 0x30},
+	{0x6c, 0x00},
+	{0x6d, 0x80},
+	{0x6e, 0x00},
+	{0x70, 0x02},
+	{0x71, 0x94},
+	{0x73, 0xc1},
+	{0x5a, 0x57},
+	{0x37, 0xc0},
+	{0x4f, 0xca},
+	{0x50, 0xa8},
+	{0x5a, 0x23},
+	{0x6d, 0x00},
+	{0x3d, 0x38},
+	{0xff, 0x00},
+	{0xe5, 0x7f},
+	{0xf9, 0xc0},
+	{0x41, 0x24},
+	{0xe0, 0x14},
+	{0x76, 0xff},
+	{0x33, 0xa0},
+	{0x42, 0x20},
+	{0x43, 0x18},
+	{0x4c, 0x00},
+	{0x87, 0xd5},
+	{0x88, 0x3f},
+	{0xd7, 0x03},//[pixformat]:
+	{0xd9, 0x10},
+	{0xd3, 0x82},
+	{0xc8, 0x08},
+	{0xc9, 0x80},
+	{0x7c, 0x00},
+	{0x7d, 0x00},
+	{0x7c, 0x03},
+	{0x7d, 0x48},
+	{0x7d, 0x48},
+	{0x7c, 0x08},
+	{0x7d, 0x20},
+	{0x7d, 0x10},
+	{0x7d, 0x0e},
+	{0x90, 0x00},
+	{0x91, 0x0e},
+	{0x91, 0x1a},
+	{0x91, 0x31},
+	{0x91, 0x5a},
+	{0x91, 0x69},
+	{0x91, 0x75},
+	{0x91, 0x7e},
+	{0x91, 0x88},
+	{0x91, 0x8f},
+	{0x91, 0x96},
+	{0x91, 0xa3},
+	{0x91, 0xaf},
+	{0x91, 0xc4},
+	{0x91, 0xd7},
+	{0x91, 0xe8},
+	{0x91, 0x20},
+	{0x92, 0x00},
+	{0x93, 0x06},
+	{0x93, 0xe3},
+	{0x93, 0x05},
+	{0x93, 0x05},
+	{0x93, 0x00},
+	{0x93, 0x04},
+	{0x93, 0x00},
+	{0x93, 0x00},
+	{0x93, 0x00},
+	{0x93, 0x00},
+	{0x93, 0x00},
+	{0x93, 0x00},
+	{0x93, 0x00},
+	{0x96, 0x00},
+	{0x97, 0x08},
+	{0x97, 0x19},
+	{0x97, 0x02},
+	{0x97, 0x0c},
+	{0x97, 0x24},
+	{0x97, 0x30},
+	{0x97, 0x28},
+	{0x97, 0x26},
+	{0x97, 0x02},
+	{0x97, 0x98},
+	{0x97, 0x80},
+	{0x97, 0x00},
+	{0x97, 0x00},
+	{0xc3, 0xed},
+	{0xa4, 0x00},
+	{0xa8, 0x00},
+	{0xc5, 0x11},
+	{0xc6, 0x51},
+	{0xbf, 0x80},
+	{0xc7, 0x10},
+	{0xb6, 0x66},
+	{0xb8, 0xa5},
+	{0xb7, 0x64},
+	{0xb9, 0x7c},
+	{0xb3, 0xaf},
+	{0xb4, 0x97},
+	{0xb5, 0xff},
+	{0xb0, 0xc5},
+	{0xb1, 0x94},
+	{0xb2, 0x0f},
+	{0xc4, 0x5c},
+	{0x5a, 0xc8},
+	{0x5b, 0x96},
+	{0x5c, 0x00},
+	{0xc3, 0xed},
+	{0x7f, 0x00},
+	{0xda, 0x08},//pixformat
+	{0xe5, 0x1f},
+	{0xe1, 0x67},//pixformat
+	{0xe0, 0x00},
+	{0xdd, 0x7f},
+	{0x05, 0x00},
+#if 1	//color bar
+	{0xff, 0x01},
+	{0x12, 0x02},
+#endif
+	{0x00, 0x00}
+
+};
+static const uint8_t svga_config[][2] = { //k210 
+	{0xff, 0x01},//bank sel
+	{0x35, 0xda},//[SVGA]:
+	{0x22, 0x1a},//[SVGA]:
+	{0x37, 0xc3},//[SVGA]:
+	{0x34, 0xc0},//[SVGA]:
+	{0x06, 0x88},//[SVGA]:
+	{0x0d, 0x87},//[SVGA]:
+	{0x0e, 0x41},//[SVGA]:
+	{0x42, 0x03},//[SVGA]:
+	{0x3d, 0x34},//[SVGA]:
+	{0x12, 0x40},//[SVGA]:  COM7,COM7_RES_SVGA  SVGA
+	{0x03, 0x0f},//[SVGA]:  COM1,0x0F  
+	{0x17, 0x11},//[SVGA]:HSTART
+	{0x18, 0x43},//[SVGA]:HSTOP
+	{0x19, 0x00},//[SVGA]:VSTART
+	{0x1a, 0x4b},//[SVGA]:VSTOP
+	{0x32, 0x09},//[SVGA]:REG32
+	
+	{0xff, 0x00},//bank sel
+	{0xc0, 0x64},//[SVGA]:HSIZE8 SVGA_HSIZE>>3
+	{0xc1, 0x4b},//[SVGA]:VSIZE8 SVGA_VSIZE>>3
+	{0x8c, 0x00},//[SVGA]:SIZEL
+	{0x86, 0x3d},//[SVGA]:
+	{0x50, 0x00},//[SVGA]:CTRLI
+	{0x51, 0xc8},//[SVGA]:HSIZE
+	{0x52, 0x96},//[SVGA]:VSIZE
+	{0x53, 0x00},//[SVGA]:XOFFL
+	{0x54, 0x00},//[SVGA]:YOFFL
+	{0x55, 0x00},//[SVGA]:VHYX
+	{0xd3, 0x02},//[SVGA]:R_DVP_SP	
+};
+
+static const uint8_t uxga_regs[][2] = {
+        { BANK_SEL, BANK_SEL_SENSOR },
+        /* DSP input image resoultion and window size control */
+        { COM7,    COM7_RES_UXGA},
+        { COM1,    0x0F }, /* UXGA=0x0F, SVGA=0x0A, CIF=0x06 */
+        { REG32,   0x36 }, /* UXGA=0x36, SVGA/CIF=0x09 */
+
+        { HSTART,  0x11 }, /* UXGA=0x11, SVGA/CIF=0x11 */
+        { HSTOP,   0x75 }, /* UXGA=0x75, SVGA/CIF=0x43 */
+
+        { VSTART,  0x01 }, /* UXGA=0x01, SVGA/CIF=0x00 */
+        { VSTOP,   0x97 }, /* UXGA=0x97, SVGA/CIF=0x4b */
+        { 0x3d,    0x34 }, /* UXGA=0x34, SVGA/CIF=0x38 */
+
+        { 0x35,    0x88 },
+        { 0x22,    0x0a },
+        { 0x37,    0x40 },
+        { 0x34,    0xa0 },
+        { 0x06,    0x02 },
+        { 0x0d,    0xb7 },
+        { 0x0e,    0x01 },
+        { 0x42,    0x83 },
+
+        /* Set DSP input image size and offset.
+           The sensor output image can be scaled with OUTW/OUTH */
+        { BANK_SEL, BANK_SEL_DSP },
+        { R_BYPASS, R_BYPASS_DSP_BYPAS },
+
+        { RESET,   RESET_DVP },
+        { HSIZE8,  (UXGA_HSIZE>>3)}, /* Image Horizontal Size HSIZE[10:3] */
+        { VSIZE8,  (UXGA_VSIZE>>3)}, /* Image Vertiacl Size VSIZE[10:3] */
+
+        /* {HSIZE[11], HSIZE[2:0], VSIZE[2:0]} */
+        { SIZEL,   ((UXGA_HSIZE>>6)&0x40) | ((UXGA_HSIZE&0x7)<<3) | (UXGA_VSIZE&0x7)},
+
+        { XOFFL,   0x00 }, /* OFFSET_X[7:0] */
+        { YOFFL,   0x00 }, /* OFFSET_Y[7:0] */
+        { HSIZE,   ((UXGA_HSIZE>>2)&0xFF) }, /* H_SIZE[7:0] real/4 */
+        { VSIZE,   ((UXGA_VSIZE>>2)&0xFF) }, /* V_SIZE[7:0] real/4 */
+
+        /* V_SIZE[8]/OFFSET_Y[10:8]/H_SIZE[8]/OFFSET_X[10:8] */
+        { VHYX,    ((UXGA_VSIZE>>3)&0x80) | ((UXGA_HSIZE>>7)&0x08) },
+        { TEST,    (UXGA_HSIZE>>4)&0x80}, /* H_SIZE[9] */
+
+        { CTRL2,   CTRL2_DCW_EN | CTRL2_SDE_EN |
+            CTRL2_UV_AVG_EN | CTRL2_CMX_EN | CTRL2_UV_ADJ_EN },
+
+        /* H_DIVIDER/V_DIVIDER */
+        { CTRLI,   CTRLI_LP_DP | 0x00},
+        /* DVP prescalar */
+        { R_DVP_SP, R_DVP_SP_AUTO_MODE | 0x04},
+
+        { R_BYPASS, R_BYPASS_DSP_EN },
+        { RESET,    0x00 },
+        {0, 0},
+};
+
+static const uint8_t yuv422_regs[][2] = {
+        { BANK_SEL, BANK_SEL_DSP },
+        { RESET,   RESET_DVP},
+        { 0xD7,     0x01 },
+        { IMAGE_MODE, IMAGE_MODE_YUV422 },
+        { 0xE1,     0x67 },
+        { RESET,    0x00 },
+        {0, 0},
+};
+
+static const uint8_t rgb565_regs[][2] = {
+        { BANK_SEL,   BANK_SEL_DSP },
+        { RESET,      RESET_DVP},
+        { 0xD7,       0x03},
+        { IMAGE_MODE, IMAGE_MODE_RGB565 },
+        { 0xE1,       0x77 },
+        { RESET,      0x00 },
+        {0,           0},
+};
+
+static const uint8_t jpeg_regs[][2] = {
+        { BANK_SEL, BANK_SEL_DSP },
+        { RESET,   RESET_DVP},
+        { IMAGE_MODE, IMAGE_MODE_JPEG_EN|IMAGE_MODE_RGB565 },
+        { 0xD7,     0x03 },
+        { 0xE1,     0x77 },
+        { QS,       0x0C },
+        { RESET,    0x00 },
+        {0, 0},
+};
+
+#define NUM_BRIGHTNESS_LEVELS (5)
+static const uint8_t brightness_regs[NUM_BRIGHTNESS_LEVELS + 1][5] = {
+    { BPADDR, BPDATA, BPADDR, BPDATA, BPDATA },
+    { 0x00, 0x04, 0x09, 0x00, 0x00 }, /* -2 */
+    { 0x00, 0x04, 0x09, 0x10, 0x00 }, /* -1 */
+    { 0x00, 0x04, 0x09, 0x20, 0x00 }, /*  0 */
+    { 0x00, 0x04, 0x09, 0x30, 0x00 }, /* +1 */
+    { 0x00, 0x04, 0x09, 0x40, 0x00 }, /* +2 */
+};
+
+#define NUM_CONTRAST_LEVELS (5)
+static const uint8_t contrast_regs[NUM_CONTRAST_LEVELS + 1][7] = {
+    { BPADDR, BPDATA, BPADDR, BPDATA, BPDATA, BPDATA, BPDATA },
+    { 0x00, 0x04, 0x07, 0x20, 0x18, 0x34, 0x06 }, /* -2 */
+    { 0x00, 0x04, 0x07, 0x20, 0x1c, 0x2a, 0x06 }, /* -1 */
+    { 0x00, 0x04, 0x07, 0x20, 0x20, 0x20, 0x06 }, /*  0 */
+    { 0x00, 0x04, 0x07, 0x20, 0x24, 0x16, 0x06 }, /* +1 */
+    { 0x00, 0x04, 0x07, 0x20, 0x28, 0x0c, 0x06 }, /* +2 */
+};
+
+#define NUM_SATURATION_LEVELS (5)
+static const uint8_t saturation_regs[NUM_SATURATION_LEVELS + 1][5] = {
+    { BPADDR, BPDATA, BPADDR, BPDATA, BPDATA },
+    { 0x00, 0x02, 0x03, 0x28, 0x28 }, /* -2 */
+    { 0x00, 0x02, 0x03, 0x38, 0x38 }, /* -1 */
+    { 0x00, 0x02, 0x03, 0x48, 0x48 }, /*  0 */
+    { 0x00, 0x02, 0x03, 0x58, 0x58 }, /* +1 */
+    { 0x00, 0x02, 0x03, 0x58, 0x58 }, /* +2 */
+};
+
+static const int resolution[][2] = {
+    {0,    0   },
+    // C/SIF Resolutions
+    {88,   72  },    /* QQCIF     */
+    {176,  144 },    /* QCIF      */
+    {352,  288 },    /* CIF       */
+    {88,   60  },    /* QQSIF     */
+    {176,  120 },    /* QSIF      */
+    {352,  240 },    /* SIF       */
+    // VGA Resolutions
+    {40,   30  },    /* QQQQVGA   */
+    {80,   60  },    /* QQQVGA    */
+    {160,  120 },    /* QQVGA     */
+    {320,  240 },    /* QVGA      */
+    {640,  480 },    /* VGA       */
+    {60,   40  },    /* HQQQVGA   */
+    {120,  80  },    /* HQQVGA    */
+    {240,  160 },    /* HQVGA     */
+    // FFT Resolutions
+    {64,   32  },    /* 64x32     */
+    {64,   64  },    /* 64x64     */
+    {128,  64  },    /* 128x64    */
+    {128,  128 },    /* 128x64    */
+    // Other
+    {128,  160 },    /* LCD       */
+    {128,  160 },    /* QQVGA2    */
+    {720,  480 },    /* WVGA      */
+    {752,  480 },    /* WVGA2     */
+    {800,  600 },    /* SVGA      */
+    {1280, 1024},    /* SXGA      */
+    {1600, 1200},    /* UXGA      */
+};
+
+
+#define cambus_writeb(h, a, d)  dvp_sccb_send_data(((h)->hdvp), ((h)->_slaveAddr), (a), (d))
+
+int Sipeed_OV2640_cambus_scan_gc0328(OV2640_t *hcmr);
+int Sipeed_OV2640_dvpInitIrq(void);
+
+static int cambus_readb(OV2640_t *hcmr, uint8_t reg_addr, uint8_t *reg_data)
+{
+
+    int ret = 0;
+	*reg_data = dvp_sccb_receive_data(hcmr->hdvp, hcmr->_slaveAddr, reg_addr);
+	if(0xff == *reg_data)
+		ret = -1;
+    return ret;
+}
+
+static int reverse_u32pixel(uint32_t* addr, uint32_t length)
+{
+  if(NULL == addr)
+    return -1;
+
+  uint32_t data;
+  uint32_t* pend = addr+length;
+  for(;addr<pend;addr++)
+  {
+	  data = *(addr);
+	  *(addr) = ((data & 0x000000FF) << 24) | ((data & 0x0000FF00) << 8) | 
+                ((data & 0x00FF0000) >> 8) | ((data & 0xFF000000) >> 24) ;
+  }  //1.7ms
+  
+  
+  return 0;
+}
+
+static int cambus_read_id(OV2640_t *hcmr, uint8_t addr, uint16_t *manuf_id, uint16_t *device_id)
+{
+	dvp_sccb_send_data(hcmr->hdvp, addr, 0xFF, 0x01);
+	*manuf_id = (dvp_sccb_receive_data(hcmr->hdvp, addr, 0x1C) << 8) | dvp_sccb_receive_data(hcmr->hdvp, addr, 0x1D);
+	*device_id = (dvp_sccb_receive_data(hcmr->hdvp, addr, 0x0A) << 8) | dvp_sccb_receive_data(hcmr->hdvp, addr, 0x0B);
+	return 0;
+}
+
+static int cambus_scan(OV2640_t *hcmr)
+{
+
+	uint16_t manuf_id = 0;
+	uint16_t device_id = 0;
+    for (uint8_t addr=0x08; addr<=0x77; addr++) {
+		cambus_read_id(hcmr, addr ,&manuf_id,&device_id);
+		if(0xffff != device_id)
+		{
+			return addr ;
+		}
+    }
+    return 0;
+}
+
+
+void
+ov2640_getResolition(OV2640_t *hcmr, framesize_t frameSize)
+{
+	hcmr->_width    = resolution[frameSize][0];
+	hcmr->_height   = resolution[frameSize][1];
+}
+
+ER
+ov2640_sensor_ov_detect(OV2640_t *hcmr)
+{
+	DVP_Handle_t *hdvp = hcmr->hdvp;
+
+	/* Reset the sensor */
+	dvp_dcmi_reset(hdvp, true);
+	dly_tsk(10);
+
+	dvp_dcmi_reset(hdvp, false);
+	dly_tsk(10);
+
+	/* Probe the ov sensor */
+	hcmr->_slaveAddr = cambus_scan(hcmr);
+	if(hcmr->_slaveAddr == 0){
+		/* Sensor has been held in reset,
+		   so the reset line is active low */
+		hcmr->_resetPoliraty = ACTIVE_LOW;
+
+		/* Pull the sensor out of the reset state,systick_sleep() */
+		dvp_dcmi_reset(hdvp, true);
+		dly_tsk(10);
+
+		/* Probe again to set the slave addr */
+		hcmr->_slaveAddr = cambus_scan(hcmr);
+		if(hcmr->_slaveAddr == 0){
+			hcmr->_pwdnPoliraty = ACTIVE_LOW;
+			dvp_dcmi_powerdown(hdvp, false);
+			dly_tsk(10);
+
+			hcmr->_slaveAddr = cambus_scan(hcmr);
+			if(hcmr->_slaveAddr == 0){
+				hcmr->_resetPoliraty = ACTIVE_HIGH;
+				dvp_dcmi_reset(hdvp, false);
+				dly_tsk(10);
+
+				hcmr->_slaveAddr = cambus_scan(hcmr);
+				if(hcmr->_slaveAddr == 0){
+					//should do something?
+					return E_SYS;
+				}
+			}
+		}
+	}
+
+	// Clear sensor chip ID.
+	hcmr->_id = 0;
+
+	if(hcmr->_slaveAddr == LEPTON_ID){
+		hcmr->_id = LEPTON_ID;
+		/*set LEPTON xclk rate*/
+		/*lepton_init*/
+	}
+	else{
+		// Read ON semi sensor ID.
+		cambus_readb(hcmr, ON_CHIP_ID, &hcmr->_id);
+		if(hcmr->_id == MT9V034_ID){
+			/*set MT9V034 xclk rate*/
+			/*mt9v034_init*/
+		}
+		else{	// Read OV sensor ID.
+			cambus_readb(hcmr, OV_CHIP_ID, &hcmr->_id);
+			// Initialize sensor struct.
+			switch(hcmr->_id){
+			case OV9650_ID:
+				/*ov9650_init*/
+				break;
+			case OV2640_ID:
+				// printf("detect ov2640, id:%x\n", _slaveAddr);
+				break;
+			case OV7725_ID:
+				/*ov7725_init*/
+				break;
+			default:
+				// Sensor is not supported.
+				return E_SYS;
+			}
+		}
+	}
+	return E_OK;
+}
+
+ER
+ov2640_sensro_gc_detect(OV2640_t *hcmr)
+{
+	DVP_Handle_t *hdvp = hcmr->hdvp;
+	uint8_t id;
+
+	dvp_dcmi_powerdown(hdvp, false);//enable gc0328 要恢? normal 工作模式，需将 PWDN pin 接入低?平即可，同?写入初始化寄存器即可
+	dvp_dcmi_reset(hdvp, false);	//reset gc3028
+	dly_tsk(10);
+	dvp_dcmi_reset(hdvp, true);
+	dly_tsk(10);
+	id = ov2640_cambus_scan_gc0328(hcmr);
+	if(0 == id){
+		return E_SYS;
+	}
+	else{
+		// printf("[MAIXPY]: gc0328 id = %x\n",id); 
+		hcmr->_slaveAddr = GC0328_ADDR;
+		hcmr->_id = id;
+	}
+	return E_OK;
+}
+
+
+ER
+ov2640_reset(OV2640_t *hcmr)
+{
+	int i=0;
+	const uint8_t (*regs)[2];
+
+	/* Reset all registers */
+	cambus_writeb(hcmr, BANK_SEL, BANK_SEL_SENSOR);
+	cambus_writeb(hcmr, COM7, COM7_SRST);
+
+	/* delay n ms */
+	dly_tsk(10);
+
+	i = 0;
+	regs = ov2640_default;
+	/* Write initial regsiters */
+	while (regs[i][0]) {
+		cambus_writeb(hcmr, regs[i][0], regs[i][1]);
+		i++;
+	}
+	i = 0;
+	regs = svga_config;
+	/* Write DSP input regsiters */
+	while (regs[i][0]) {
+		cambus_writeb(hcmr, regs[i][0], regs[i][1]);
+		i++;
+	}
+	return E_OK;
+}
+
+ER
+ov2640_set_pixformat(OV2640_t *hcmr)
+{
+	int i=0;
+	const uint8_t (*regs)[2]=NULL;
+
+	/* read pixel format reg */
+	switch(hcmr->pixFormat){
+	case PIXFORMAT_RGB565:
+		regs = rgb565_regs;
+		break;
+	case PIXFORMAT_YUV422:
+	case PIXFORMAT_GRAYSCALE:
+		regs = yuv422_regs;
+		break;
+	case PIXFORMAT_JPEG:
+		regs = jpeg_regs;
+		break;
+	default:
+		return E_PAR;
+	}
+
+	/* Write initial regsiters */
+	while(regs[i][0]){
+		cambus_writeb(hcmr, regs[i][0], regs[i][1]);
+		i++;
+	}
+	switch(hcmr->pixFormat) {
+	case PIXFORMAT_RGB565:
+		hcmr->hdvp->Init.Format = DVP_FORMAT_RGB;
+		break;
+	case PIXFORMAT_YUV422:
+		hcmr->hdvp->Init.Format = DVP_FORMAT_YUY;
+		break;
+	case PIXFORMAT_GRAYSCALE:
+		hcmr->hdvp->Init.Format = DVP_FORMAT_Y;
+		break;
+	case PIXFORMAT_JPEG:
+		hcmr->hdvp->Init.Format = DVP_FORMAT_RGB;
+		break;
+	default:
+		return E_PAR;
+	}
+	dvp_set_image_format(hcmr->hdvp);
+	/* delay n ms */
+	dly_tsk(30);
+	return E_OK;
+}
+
+ER
+ov2640_set_framesize(OV2640_t *hcmr)
+{
+	uint8_t clkrc;
+	uint16_t w = hcmr->_width;
+	uint16_t h = hcmr->_height;
+	int i=0;
+	const uint8_t (*regs)[2];
+
+	if((w <= 800) && (h <= 600)){
+		clkrc =0x80;
+		regs = svga_config;
+//		regs = ov2640_config;
+	}
+	else{
+		clkrc =0x81;
+		regs = uxga_regs;
+	}
+
+	/* Disable DSP */
+	cambus_writeb(hcmr, BANK_SEL, BANK_SEL_DSP);
+	cambus_writeb(hcmr, R_BYPASS, R_BYPASS_DSP_BYPAS);
+
+	/* Set CLKRC */
+	if(clkrc == 0x81){
+		cambus_writeb(hcmr, BANK_SEL, BANK_SEL_SENSOR);
+		cambus_writeb(hcmr, CLKRC, clkrc);
+	}
+
+	/* Write DSP input regsiters */
+	while(regs[i][0]){
+		cambus_writeb(hcmr, regs[i][0], regs[i][1]);
+		i++;
+	}
+
+	 /* Write output width */
+	cambus_writeb(hcmr,0xe0,0x04 ); /* OUTH[8]/OUTW[9:8] */
+	cambus_writeb(hcmr, ZMOW, (w>>2)&0xFF); /* OUTW[7:0] (real/4) */
+	cambus_writeb(hcmr, ZMOH, (h>>2)&0xFF); /* OUTH[7:0] (real/4) */
+	cambus_writeb(hcmr, ZMHH, ((h>>8)&0x04)|((w>>10)&0x03)); /* OUTH[8]/OUTW[9:8] */
+	cambus_writeb(hcmr,0xe0,0x00 ); /* OUTH[8]/OUTW[9:8] */
+
+	/* Enable DSP */
+	cambus_writeb(hcmr, BANK_SEL, BANK_SEL_DSP);
+	cambus_writeb(hcmr, R_BYPASS, R_BYPASS_DSP_EN);
+
+	/* delay n ms */
+	dly_tsk(30);
+	hcmr->hdvp->Init.Width  = w;
+	hcmr->hdvp->Init.Height = h;
+	return dvp_set_image_size(hcmr->hdvp);
+}
+
+
+ER
+ov2640_activate(OV2640_t *hcmr, bool_t run)
+{
+	return dvp_activate(hcmr->hdvp, run);
+}
+
+int
+ov2640_id(OV2640_t *hcmr)
+{
+    return hcmr->_id;
+}
+
+ER
+ov2640_snapshot(OV2640_t *hcmr)
+{
+	DVP_Handle_t *hdvp = hcmr->hdvp;
+	int32_t timeout = SNAPDHOT_TIMEOUT;
+
+	//wait for new frame
+	hdvp->state = DVP_STATE_ACTIVATE;
+
+	while(hdvp->state != DVP_STATE_FINISH){
+		if(--timeout <= 0)
+			return E_TMOUT;
+		if(hdvp->semid != 0)
+			twai_sem(hdvp->semid, 1);
+		else
+			dly_tsk(1);
+	}
+	reverse_u32pixel((uint32_t*)hcmr->_dataBuffer, hcmr->_width * hcmr->_height/2);
+	return E_OK;
+}
+
+ER
+ov2640_cambus_scan_gc0328(OV2640_t *hcmr)
+{
+	uint8_t id;
+
+	dvp_sccb_send_data(hcmr->hdvp, GC0328_ADDR, 0xFE, 0x00);
+	id = dvp_sccb_receive_data(hcmr->hdvp, GC0328_ADDR, 0xf0);
+	if(id != 0x9d){
+		return 0;
+	}
+	return id;
+}
+
+
+ER
+ov2640_setInvert(OV2640_t *hcmr, bool_t invert)
+{
+	uint8_t reg;
+
+	cambus_readb(hcmr, BANK_SEL, &reg);
+	cambus_writeb(hcmr, BANK_SEL, reg | BANK_SEL_SENSOR);
+	cambus_readb(hcmr, REG04, &reg);
+
+	if(invert){
+		reg |= REG04_HFLIP_IMG;
+	}
+	else{
+		reg &= ~REG04_HFLIP_IMG;
+	}
+	cambus_writeb(hcmr, REG04, reg);
+    return E_OK;
+}
+
+ER
+ov2640_set_contrast(OV2640_t *hcmr, int level)
+{
+	int i;
+
+	level += (NUM_CONTRAST_LEVELS / 2 + 1);
+	if(level < 0 || level > NUM_CONTRAST_LEVELS){
+		return E_PAR;
+	}
+
+	/* Switch to DSP register bank */
+	cambus_writeb(hcmr, BANK_SEL, BANK_SEL_DSP);
+
+	/* Write contrast registers */
+    for(i = 0 ; i < sizeof(contrast_regs[0])/sizeof(contrast_regs[0][0]) ; i++){
+		cambus_writeb(hcmr, contrast_regs[0][i], contrast_regs[level][i]);
+	}
+	return E_OK;
+}
+
+ER
+ov2640_set_brightness(OV2640_t *hcmr, int level)
+{
+	int i;
+
+	level += (NUM_BRIGHTNESS_LEVELS / 2 + 1);
+	if(level < 0 || level > NUM_BRIGHTNESS_LEVELS){
+		return E_PAR;
+	}
+
+	/* Switch to DSP register bank */
+	cambus_writeb(hcmr, BANK_SEL, BANK_SEL_DSP);
+
+	/* Write brightness registers */
+	for(i = 0 ; i < sizeof(brightness_regs[0])/sizeof(brightness_regs[0][0]) ; i++){
+		cambus_writeb(hcmr, brightness_regs[0][i], brightness_regs[level][i]);
+	}
+	return E_OK;
+}
+
+ER
+ov2640_set_saturation(OV2640_t *hcmr, int level)
+{
+	int i;
+
+	level += (NUM_SATURATION_LEVELS / 2 + 1);
+	if(level < 0 || level > NUM_SATURATION_LEVELS){
+		return E_PAR;
+	}
+
+	/* Switch to DSP register bank */
+	cambus_writeb(hcmr, BANK_SEL, BANK_SEL_DSP);
+
+	/* Write contrast registers */
+	for(i = 0 ; i < sizeof(saturation_regs[0])/sizeof(saturation_regs[0][0]) ; i++){
+		cambus_writeb(hcmr, saturation_regs[0][i], saturation_regs[level][i]);
+	}
+	return E_OK;
+}
+
+ER
+ov2640_set_gainceiling(OV2640_t *hcmr, gainceiling_t gainceiling)
+{
+	/* Switch to SENSOR register bank */
+	cambus_writeb(hcmr, BANK_SEL, BANK_SEL_SENSOR);
+
+	/* Write gain ceiling register */
+	cambus_writeb(hcmr, COM9, COM9_AGC_SET(gainceiling));
+	return E_OK;
+}
+
+ER
+ov2640_set_quality(OV2640_t *hcmr, int qs)
+{
+	/* Switch to DSP register bank */
+	cambus_writeb(hcmr, BANK_SEL, BANK_SEL_DSP);
+
+	/* Write QS register */
+	cambus_writeb(hcmr, QS, qs);
+	return E_OK;
+}
+
+ER
+ov2640_set_colorbar(OV2640_t *hcmr, bool_t enable)
+{
+	uint8_t reg;
+
+    /* Switch to SENSOR register bank */
+	cambus_writeb(hcmr, BANK_SEL, BANK_SEL_SENSOR);
+
+	/* Update COM7 */
+	cambus_readb(hcmr, COM7, &reg);
+
+	if(enable){
+		reg |= COM7_COLOR_BAR;
+	}
+	else{
+		reg &= ~COM7_COLOR_BAR;
+	}
+	cambus_writeb(hcmr, COM7, reg);
+	return E_OK;
+}
+
+ER
+ov2640_set_auto_exposure(OV2640_t *hcmr, bool_t enable, int exposure_us)
+{
+	uint32_t freq = hcmr->hdvp->Init.Freq;
+	uint8_t reg;
+	int ret = 0;
+
+	cambus_readb(hcmr, BANK_SEL, &reg);
+	cambus_writeb(hcmr, BANK_SEL, reg | BANK_SEL_SENSOR);
+	cambus_readb(hcmr, COM8, &reg);
+	cambus_writeb(hcmr, COM8, COM8_SET_AEC(reg, enable));
+
+	if((!enable) && (exposure_us >= 0)){
+		int t_line = 0;
+		int pll_mult, clk_rc, exposure;
+		int t_pclk = 0;
+		cambus_readb(hcmr, COM7, &reg);
+
+		if (COM7_GET_RES(reg) == COM7_RES_UXGA) t_line = 1600 + 322;
+		if (COM7_GET_RES(reg) == COM7_RES_SVGA) t_line = 800 + 390;
+		if (COM7_GET_RES(reg) == COM7_RES_CIF) t_line = 400 + 195;
+
+		ret |= cambus_readb(hcmr, CLKRC, &reg);
+		pll_mult = (reg & CLKRC_DOUBLE) ? 2 : 1;
+		clk_rc = ((reg & CLKRC_DIVIDER_MASK) + 1) * 2;
+
+		ret |= cambus_readb(hcmr, BANK_SEL, &reg);
+		cambus_writeb(hcmr, BANK_SEL, reg & (~BANK_SEL_SENSOR));
+		ret |= cambus_readb(hcmr, IMAGE_MODE, &reg);
+
+		if (IMAGE_MODE_GET_FMT(reg) == IMAGE_MODE_YUV422) t_pclk = 2;
+		if (IMAGE_MODE_GET_FMT(reg) == IMAGE_MODE_RAW10) t_pclk = 1;
+		if (IMAGE_MODE_GET_FMT(reg) == IMAGE_MODE_RGB565) t_pclk = 2;
+
+		exposure = IM_MAX(IM_MIN(((exposure_us*(((freq/clk_rc)*pll_mult)/1000000))/t_pclk)/t_line,0xFFFF),0x0000);
+
+		ret |= cambus_readb(hcmr, BANK_SEL, &reg);
+		cambus_writeb(hcmr, BANK_SEL, reg | BANK_SEL_SENSOR);
+
+		ret |= cambus_readb(hcmr, REG04, &reg);
+		cambus_writeb(hcmr, REG04, (reg & 0xFC) | ((exposure >> 0) & 0x3));
+
+		ret |= cambus_readb(hcmr, AEC, &reg);
+		cambus_writeb(hcmr, AEC, (reg & 0x00) | ((exposure >> 2) & 0xFF));
+
+		ret |= cambus_readb(hcmr, REG04, &reg);
+		cambus_writeb(hcmr, REG04, (reg & 0xC0) | ((exposure >> 10) & 0x3F));
+	}
+	if(ret == 0)
+		return E_OK;
+	else
+		return E_SYS;
+}
+
+ER
+ov2640_get_exposure_us(OV2640_t *hcmr, int *exposure_us)
+{
+	uint32_t freq = hcmr->hdvp->Init.Freq;
+	uint8_t reg, aec_10, aec_92, aec_1510;
+	int t_line = 0;
+	int t_pclk = 0;
+	int pll_mult, clk_rc;
+	uint16_t exposure;
+	int ret = cambus_readb(hcmr, BANK_SEL, &reg);
+
+	cambus_writeb(hcmr, BANK_SEL, reg | BANK_SEL_SENSOR);
+	ret |= cambus_readb(hcmr, COM8, &reg);
+
+    // DISABLED
+    // if (reg & COM8_AEC_EN) {
+    //     ret |= cambus_writeb(_slaveAddr, COM8, reg & (~COM8_AEC_EN));
+    // }
+    // DISABLED
+
+	ret |= cambus_readb(hcmr, REG04, &aec_10);
+	ret |= cambus_readb(hcmr, AEC, &aec_92);
+	ret |= cambus_readb(hcmr, REG45, &aec_1510);
+
+    // DISABLED
+    // if (reg & COM8_AEC_EN) {
+    //     ret |= cambus_writeb(_slaveAddr, COM8, reg | COM8_AEC_EN);
+    // }
+    // DISABLED
+
+	ret |= cambus_readb(hcmr, COM7, &reg);
+
+	if (COM7_GET_RES(reg) == COM7_RES_UXGA) t_line = 1600 + 322;
+	if (COM7_GET_RES(reg) == COM7_RES_SVGA) t_line = 800 + 390;
+	if (COM7_GET_RES(reg) == COM7_RES_CIF) t_line = 400 + 195;
+
+	ret |= cambus_readb(hcmr, CLKRC, &reg);
+	pll_mult = (reg & CLKRC_DOUBLE) ? 2 : 1;
+	clk_rc = ((reg & CLKRC_DIVIDER_MASK) + 1) * 2;
+
+	ret |= cambus_readb(hcmr, BANK_SEL, &reg);
+	cambus_writeb(hcmr, BANK_SEL, reg & (~BANK_SEL_SENSOR));
+	ret |= cambus_readb(hcmr, IMAGE_MODE, &reg);
+
+	if (IMAGE_MODE_GET_FMT(reg) == IMAGE_MODE_YUV422) t_pclk = 2;
+	if (IMAGE_MODE_GET_FMT(reg) == IMAGE_MODE_RAW10) t_pclk = 1;
+	if (IMAGE_MODE_GET_FMT(reg) == IMAGE_MODE_RGB565) t_pclk = 2;
+
+	exposure = ((aec_1510 & 0x3F) << 10) + ((aec_92 & 0xFF) << 2) + ((aec_10 & 0x3) << 0);
+	*exposure_us = (exposure*t_line*t_pclk)/(((freq/clk_rc)*pll_mult)/1000000);
+	if(ret == 0)
+		return E_OK;
+	else
+		return E_SYS;
+}
+
+ER
+ov2640_set_auto_whitebal(OV2640_t *hcmr, bool_t enable, float r_gain_db, float g_gain_db, float b_gain_db)
+{
+	uint8_t reg;
+	int ret = cambus_readb(hcmr, BANK_SEL, &reg);
+	cambus_writeb(hcmr, BANK_SEL, reg & (~BANK_SEL_SENSOR));
+	ret |= cambus_readb(hcmr, CTRL1, &reg);
+	cambus_writeb(hcmr, CTRL1, (reg & (~CTRL1_AWB)) | (enable ? CTRL1_AWB : 0));
+
+	if((!enable) && (!isnanf(r_gain_db)) && (!isnanf(g_gain_db)) && (!isnanf(b_gain_db))
+                      && (!isinff(r_gain_db)) && (!isinff(g_gain_db)) && (!isinff(b_gain_db))) {
+    }
+	if(ret == 0)
+		return E_OK;
+	else
+		return E_SYS;
+}
+
+ER
+ov2640_set_vflip(OV2640_t *hcmr, bool_t enable)
+{
+	uint8_t reg;
+	int ret = cambus_readb(hcmr, BANK_SEL, &reg);
+	cambus_writeb(hcmr, BANK_SEL, reg | BANK_SEL_SENSOR);
+	ret |= cambus_readb(hcmr, REG04, &reg);
+
+	if(enable){
+		reg |= REG04_VFLIP_IMG;
+		reg |= REG04_VREF_EN;
+	}
+	else{
+		reg &= ~REG04_VFLIP_IMG;
+		reg &= ~REG04_VREF_EN;
+	}
+	cambus_writeb(hcmr, REG04, reg);
+	if(ret == 0)
+		return E_OK;
+	else
+		return E_SYS;
+}
+
+#ifdef USE_GAIN
+ER
+ov2640_set_auto_gain(OV2640_t *hcmr, bool_t enable, float gain_db, float gain_db_ceiling)
+{
+	uint8_t reg;
+
+	cambus_readb(hcmr, BANK_SEL, &reg);
+	cambus_writeb(hcmr, BANK_SEL, reg | BANK_SEL_SENSOR);
+	cambus_readb(hcmr, COM8, &reg);
+	cambus_writeb(hcmr, COM8, (reg & (~COM8_AGC_EN)) | ((enable != 0) ? COM8_AGC_EN : 0));
+
+	if((!enable) && (!isnanf(gain_db)) && (!isinff(gain_db))){
+		float gain = IM_MAX(IM_MIN(expf((gain_db / 20.0) * log(10.0)), 32.0), 1.0);
+		int gain_temp = roundf(log2(IM_MAX(gain / 2.0, 1.0)));
+		int gain_hi = 0xF >> (4 - gain_temp);
+		int gain_lo = IM_MIN(roundf(((gain / (1 << gain_temp)) - 1.0) * 16.0), 15);
+
+		cambus_writeb(hcmr, GAIN, (gain_hi << 4) | (gain_lo << 0));
+	}
+	else if(enable && (!isnanf(gain_db_ceiling)) && (!isinff(gain_db_ceiling))){
+		float gain_ceiling = IM_MAX(IM_MIN(expf((gain_db_ceiling / 20.0) * log(10.0)), 128.0), 2.0);
+
+		cambus_readb(hcmr, COM9, &reg);
+		cambus_writeb(hcmr, COM9, (reg & 0x1F) | (((int)ceilf(log2(gain_ceiling)) - 1) << 5));
+	}
+	return E_OK;
+}
+
+ER
+ov2640_get_gain_db(OV2640_t *hcmr, float *gain_db)
+{
+    uint8_t reg, gain;
+	int hi_gain;
+	float lo_gain;
+
+	cambus_readb(hcmr, BANK_SEL, &reg);
+	cambus_writeb(hcmr, BANK_SEL, reg | BANK_SEL_SENSOR);
+	cambus_readb(hcmr, COM8, &reg);
+
+    // DISABLED
+    // if (reg & COM8_AGC_EN) {
+    //     ret |= cambus_writeb(_slaveAddr, COM8, reg & (~COM8_AGC_EN));
+    // }
+    // DISABLED
+
+	cambus_readb(hcmr, GAIN, &gain);
+
+    // DISABLED
+    // if (reg & COM8_AGC_EN) {
+    //     ret |= cambus_writeb(_slaveAddr, COM8, reg | COM8_AGC_EN);
+    // }
+    // DISABLED
+
+	hi_gain = 1 << (((gain >> 7) & 1) + ((gain >> 6) & 1) + ((gain >> 5) & 1) + ((gain >> 4) & 1));
+	lo_gain = 1.0 + (((gain >> 0) & 0xF) / 16.0);
+	*gain_db = 20.0 * (log(hi_gain * lo_gain) / log(10.0));
+	return E_OK;
+}
+#endif	/* USE_GAIN */
+
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/sipeed_ov2640/sipeed_ov2640.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/sipeed_ov2640/sipeed_ov2640.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/sipeed_ov2640/sipeed_ov2640.h	(revision 457)
@@ -0,0 +1,188 @@
+/*
+ *  TOPPERS/ASP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Advanced Standard Profile Kernel
+ *
+ *  Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
+ *                              Toyohashi Univ. of Technology, JAPAN
+ *  Copyright (C) 2004-2010 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ *  Copyright (C) 2015-2019 by TOPPERS PROJECT Educational Working Group.
+ *
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ *
+ *  $Id$
+ */
+/*
+ *  SIPEED OV2640 CAMARE制御プログラムのヘッダファイル
+ */
+
+#ifndef _SIPEED_OV2640_H_
+#define _SIPEED_OV2640_H_
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+#include "kernel.h"
+#include "dvp.h"
+
+#define OV9650_ID       (0x96)
+#define OV2640_ID       (0x26)
+#define OV7725_ID       (0x77)
+#define MT9V034_ID      (0x13)
+#define LEPTON_ID       (0x54)
+#define OV_CHIP_ID      (0x0A)
+#define ON_CHIP_ID      (0x00)
+#define GC0328_ID       (0x9d)
+#define GC0328_ADDR     (0x42)
+
+#ifndef TOPPERS_MACRO_ONLY
+
+typedef enum {
+    FRAMESIZE_INVALID = 0,
+    // C/SIF Resolutions
+    FRAMESIZE_QQCIF,    // 88x72
+    FRAMESIZE_QCIF,     // 176x144
+    FRAMESIZE_CIF,      // 352x288
+    FRAMESIZE_QQSIF,    // 88x60
+    FRAMESIZE_QSIF,     // 176x120
+    FRAMESIZE_SIF,      // 352x240
+    // VGA Resolutions
+    FRAMESIZE_QQQQVGA,  // 40x30
+    FRAMESIZE_QQQVGA,   // 80x60
+    FRAMESIZE_QQVGA,    // 160x120
+    FRAMESIZE_QVGA,     // 320x240
+    FRAMESIZE_VGA,      // 640x480
+    FRAMESIZE_HQQQVGA,  // 60x40
+    FRAMESIZE_HQQVGA,   // 120x80
+    FRAMESIZE_HQVGA,    // 240x160
+    // FFT Resolutions
+    FRAMESIZE_64X32,    // 64x32
+    FRAMESIZE_64X64,    // 64x64
+    FRAMESIZE_128X64,   // 128x64
+    FRAMESIZE_128X128,  // 128x128
+    // Other
+    FRAMESIZE_LCD,      // 128x160
+    FRAMESIZE_QQVGA2,   // 128x160
+    FRAMESIZE_WVGA,     // 720x480
+    FRAMESIZE_WVGA2,    // 752x480
+    FRAMESIZE_SVGA,     // 800x600
+    FRAMESIZE_SXGA,     // 1280x1024
+    FRAMESIZE_UXGA,     // 1600x1200
+    FRAMESIZE_CUSTOM,
+} framesize_t;
+
+
+typedef enum {
+    PIXFORMAT_INVLAID = 0,
+    PIXFORMAT_BAYER,     // RAW
+    PIXFORMAT_RGB565,    // RGB565
+    PIXFORMAT_YUV422,    // YUV422
+    PIXFORMAT_GRAYSCALE, // GRAYSCALE
+    PIXFORMAT_JPEG,      // JPEG/COMPRESSED
+} pixformat_t;
+
+
+
+typedef enum {
+    GAINCEILING_2X,
+    GAINCEILING_4X,
+    GAINCEILING_8X,
+    GAINCEILING_16X,
+    GAINCEILING_32X,
+    GAINCEILING_64X,
+    GAINCEILING_128X,
+} gainceiling_t;
+
+typedef enum {
+    FRAMERATE_2FPS =0x9F,
+    FRAMERATE_8FPS =0x87,
+    FRAMERATE_15FPS=0x83,
+    FRAMERATE_30FPS=0x81,
+    FRAMERATE_60FPS=0x80,
+} framerate_t;
+
+typedef enum {
+    ACTIVE_LOW,
+    ACTIVE_HIGH,
+    ACTIVE_BINOCULAR,
+} polarity_t;
+
+typedef struct _OV2640_s {
+	DVP_Handle_t    *hdvp;
+	framesize_t     frameSize;
+	pixformat_t     pixFormat;
+
+	uint16_t        _width;
+	uint16_t        _height;
+	uint8_t         _id;
+	uint32_t        *_dataBuffer;
+	uint32_t        *_aiBuffer;
+	uint16_t        _resetPoliraty;
+	uint16_t        _pwdnPoliraty;
+	uint32_t        _slaveAddr;
+} OV2640_t;
+
+extern void ov2640_getResolition(OV2640_t *hcmr, framesize_t frameSize);
+extern ER ov2640_sensor_ov_detect(OV2640_t *hcmr);
+extern ER ov2640_sensro_gc_detect(OV2640_t *hcmr);
+extern ER ov2640_reset(OV2640_t *hcmr);
+extern ER ov2640_set_pixformat(OV2640_t *hcmr);
+extern ER ov2640_set_framesize(OV2640_t *hcmr);
+extern ER ov2640_activate(OV2640_t *hcmr, bool_t run);
+extern ER ov2640_snapshot(OV2640_t *hcmr);
+extern ER ov2640_cambus_scan_gc0328(OV2640_t *hcmr);
+extern int ov2640_id(OV2640_t *hcmr);
+
+extern ER ov2640_setInvert(OV2640_t *hcmr, bool_t invert);
+extern ER ov2640_set_contrast(OV2640_t *hcmr, int level);
+extern ER ov2640_set_brightness(OV2640_t *hcmr, int level);
+extern ER ov2640_set_saturation(OV2640_t *hcmr, int level);
+extern ER ov2640_set_gainceiling(OV2640_t *hcmr, gainceiling_t gainceiling);
+extern ER ov2640_set_quality(OV2640_t *hcmr, int qs);
+extern ER ov2640_set_colorbar(OV2640_t *hcmr, bool_t enable);
+extern ER ov2640_set_auto_exposure(OV2640_t *hcmr, bool_t enable, int exposure_us);
+extern ER ov2640_get_exposure_us(OV2640_t *hcmr, int *exposure_us);
+extern ER ov2640_set_auto_whitebal(OV2640_t *hcmr, bool_t enable, float r_gain_db, float g_gain_db, float b_gain_db);
+extern ER ov2640_set_vflip(OV2640_t *hcmr, bool_t enable);
+#ifdef USE_GAIN
+extern ER ov2640_set_auto_gain(OV2640_t *hcmr, bool_t enable, float gain_db, float gain_db_ceiling);
+extern ER ov2640_get_gain_db(OV2640_t *hcmr, float *gain_db);
+#endif	/* USE_GAIN */
+
+#endif /* TOPPERS_MACRO_ONLY */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif	/* _SIPEED_OV2640_H_ */
+
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/sipeed_st7789/Makefile.config
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/sipeed_st7789/Makefile.config	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/sipeed_st7789/Makefile.config	(revision 457)
@@ -0,0 +1,55 @@
+#
+#   TOPPERS/ASP/FMP Kernel
+#       Toyohashi Open Platform for Embedded Real-Time Systems/
+#       Advanced Standard Profile Kernel
+#
+#   Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
+#                               Toyohashi Univ. of Technology, JAPAN
+#   Copyright (C) 2003-2008 by Ryosuke Takeuchi
+#                Platform Development Center RICOH COMPANY,LTD. JAPAN
+#   Copyright (C) 2015-2019 by TOPPERS PROJECT Educational Working Group.
+#
+#   上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+#   によって公表されている GNU General Public License の Version 2 に記
+#   述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+#   を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+#   利用と呼ぶ）することを無償で許諾する．
+#   (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+#       権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+#       スコード中に含まれていること．
+#   (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+#       用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+#       者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+#       の無保証規定を掲載すること．
+#   (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+#       用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+#       と．
+#     (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+#         作権表示，この利用条件および下記の無保証規定を掲載すること．
+#     (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+#         報告すること．
+#   (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+#       害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+#
+#   本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+#   よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+#   含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+#   接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+#
+#  @(#) $Id$
+#
+ 
+#
+#  Makefile のプロセッサ依存 (sipeed st7789:LCD用)
+#
+
+#
+#  コンパイルオプション
+#
+INCLUDES := $(INCLUDES) -I$(SRCDIR)/gdic/sipeed_st7789
+
+#
+#  SIPEED ST7789 LCD DRIVER(GDIC)に関する定義
+#
+SYSSVC_DIR := $(SYSSVC_DIR):$(SRCDIR)/gdic/sipeed_st7789
+SYSSVC_COBJS := $(SYSSVC_COBJS) sipeed_st7789.o 
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/sipeed_st7789/glcd_core.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/sipeed_st7789/glcd_core.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/sipeed_st7789/glcd_core.h	(revision 457)
@@ -0,0 +1,45 @@
+/*
+ *  TOPPERS BASE PLATFORM MIDDLEWARE
+ * 
+ *  Copyright (C) 2017-2019 by TOPPERS PROJECT
+ *                             Educational Working Group.
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+#ifndef _LCD_CORE_H_
+#define _LCD_CORE_H_
+
+#include "sipeed_st7789.h"
+
+#endif /* _LCD_CORE_H_ */
+
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/sipeed_st7789/sipeed_st7789.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/sipeed_st7789/sipeed_st7789.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/sipeed_st7789/sipeed_st7789.c	(revision 457)
@@ -0,0 +1,656 @@
+/*
+ *  TOPPERS/ASP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Advanced Standard Profile Kernel
+ * 
+ *  Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
+ *                              Toyohashi Univ. of Technology, JAPAN
+ *  Copyright (C) 2004-2012 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ *  Copyright (C) 2015-2019 by TOPPERS PROJECT Educational Working Group.
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  $Id$
+ */
+/* 
+ *  SIPEED ST7789 2.4"LCD制御プログラムの本体
+ */
+
+#include <kernel.h>
+#include <t_syslog.h>
+#include <t_stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <target_syssvc.h>
+#include "syssvc/serial.h"
+#include "syssvc/syslog.h"
+#include "sipeed_st7789.h"
+
+/*
+ *  サービスコールのエラーのログ出力
+ */
+Inline void
+svc_perror(const char *file, int_t line, const char *expr, ER ercd)
+{
+	if (ercd < 0) {
+		t_perror(LOG_ERROR, file, line, expr, ercd);
+	}
+}
+
+#define	SVC_PERROR(expr)	svc_perror(__FILE__, __LINE__, #expr, (expr))
+#define ABS(X)  ((X) > 0 ? (X) : -(X))
+
+#ifndef SPI_CORE_WAIT_TIME
+#define SPI_CORE_WAIT_TIME  500
+#endif
+
+#define PORT_HIGH           1
+#define PORT_LOW            0
+
+#define MAX_BUFFER          8
+
+static uint32_t aTxBuffer[MAX_BUFFER];
+
+
+static void set_dcx_control(LCD_Handler_t *hlcd)
+{
+    gpio_set_pin(TADR_GPIO_BASE, hlcd->dcx_no, PORT_LOW);
+}
+
+static void set_dcx_data(LCD_Handler_t *hlcd)
+{
+    gpio_set_pin(TADR_GPIO_BASE, hlcd->dcx_no, PORT_HIGH);
+}
+
+/*
+ *  LCDへのコマンド送信関数
+ */
+ER
+lcd_writecommand(LCD_Handler_t *hlcd, uint8_t c)
+{
+	SPI_Handle_t *hspi = hlcd->hspi;
+	ER ercd = E_OK;
+
+	aTxBuffer[0] = c;
+    set_dcx_control(hlcd);
+	hspi->Init.DataSize = 8;
+	hspi->Init.InstLength = 8;
+	hspi->Init.AddrLength = 0;
+    ercd = spi_core_transmit(hspi, hlcd->cs_sel, (uint8_t *)(aTxBuffer), 1);
+#if SPI_WAIT_TIME == 0
+	if(ercd == E_OK)
+		ercd = spi_wait(hspi, SPI_CORE_WAIT_TIME);
+#endif
+	return ercd;
+}
+
+/*
+ *  LCDへのデータ送信関数
+ */
+ER
+lcd_writebyte(LCD_Handler_t *hlcd, uint8_t *buf, uint8_t len)
+{
+	SPI_Handle_t *hspi = hlcd->hspi;
+	uint32_t i;
+	ER ercd = E_OK;
+
+	if(len >= MAX_BUFFER)
+		return E_PAR;
+	for(i = 0 ; i < len ; i++)
+		aTxBuffer[i] = buf[i];
+
+    set_dcx_data(hlcd);
+	hspi->Init.DataSize = 8;
+	hspi->Init.InstLength = 8;
+	hspi->Init.AddrLength = 0;
+	ercd = spi_core_transmit(hspi, hlcd->cs_sel, (uint8_t *)aTxBuffer, len);
+#if SPI_WAIT_TIME == 0
+	if(ercd == E_OK)
+		ercd = spi_wait(hspi, SPI_CORE_WAIT_TIME);
+#endif
+	return ercd;
+}
+
+ER
+lcd_writebyte2(LCD_Handler_t *hlcd, uint8_t *buf, uint8_t len)
+{
+	SPI_Handle_t *hspi = hlcd->hspi;
+	ER ercd = E_OK;
+
+    set_dcx_data(hlcd);
+	hspi->Init.DataSize = 8;
+	hspi->Init.InstLength = 8;
+	hspi->Init.AddrLength = 0;
+	ercd = spi_core_transmit(hspi, hlcd->cs_sel, buf, len);
+#if SPI_WAIT_TIME == 0
+	if(ercd == E_OK)
+		ercd = spi_wait(hspi, SPI_CORE_WAIT_TIME);
+#endif
+	return ercd;
+}
+
+/*
+ *  LCDへの16ビットデータ転送
+ */
+ER
+lcd_writehalf(LCD_Handler_t *hlcd, uint32_t *buf, int cnt)
+{
+	SPI_Handle_t *hspi = hlcd->hspi;
+	ER ercd = E_OK;
+
+    set_dcx_data(hlcd);
+	hspi->Init.DataSize = 16;
+	hspi->Init.InstLength = 16;
+	hspi->Init.AddrLength = 0;
+	ercd = spi_core_transmit(hspi, hlcd->cs_sel, (uint8_t *)buf, cnt);
+#if SPI_WAIT_TIME == 0
+	if(ercd == E_OK)
+		ercd = spi_wait(hspi, SPI_CORE_WAIT_TIME);
+#endif
+	return ercd;
+}
+
+/*
+ *  LCD32ビットフィル
+ */
+ER
+lcd_filldata(LCD_Handler_t *hlcd, uint32_t *data_buf, uint32_t len)
+{
+	SPI_Handle_t *hspi = hlcd->hspi;
+	ER ercd = E_OK;
+
+    set_dcx_data(hlcd);
+	hspi->Init.DataSize = 32;
+	hspi->Init.InstLength = 0;
+	hspi->Init.AddrLength = 32;
+	ercd = spi_core_transmit_fill(hspi, hlcd->cs_sel, data_buf, len);
+#if SPI_WAIT_TIME == 0
+	if(ercd == E_OK)
+		spi_wait(hspi, SPI_CORE_WAIT_TIME);
+#endif
+	return ercd;
+}
+
+/*
+ *   SIPEED LCD初期化
+ */
+void lcd_init(LCD_Handler_t *hlcd)
+{
+	GPIO_Init_t init = {0};
+    uint8_t data = 0;
+
+	/*
+	 *  DCXピン初期化
+	 */
+	fpioa_set_function(hlcd->dcx_pin , FUNC_GPIO0 + hlcd->dcx_no);
+	init.mode = GPIO_MODE_OUTPUT;
+	init.pull = GPIO_PULLDOWN;
+    gpio_setup(TADR_GPIO_BASE, &init, hlcd->dcx_no);
+    gpio_set_pin(TADR_GPIO_BASE, hlcd->dcx_no, PORT_HIGH);
+
+	/*
+	 *  LCDリセット
+	 */
+	if(hlcd->rst_pin >= 0){
+		fpioa_set_function(hlcd->rst_pin , FUNC_GPIO0 + hlcd->rst_no);
+		init.mode = GPIO_MODE_OUTPUT;
+		init.pull = GPIO_PULLDOWN;
+		gpio_setup(TADR_GPIO_BASE, &init, hlcd->rst_no);
+		gpio_set_pin(TADR_GPIO_BASE, hlcd->rst_no, PORT_HIGH);
+
+	    gpio_set_pin(TADR_GPIO_BASE, hlcd->rst_no, 0);
+	    gpio_set_pin(TADR_GPIO_BASE, hlcd->rst_no, 1);
+	}
+
+	/*
+	 *  soft reset
+	 */
+	lcd_writecommand(hlcd, SOFTWARE_RESET);
+	dly_tsk(100);
+	/*
+	 *  exit sleep
+	 */
+	lcd_writecommand(hlcd, SLEEP_OFF);
+	dly_tsk(100);
+	/*
+	 *  pixel format
+	 */
+	lcd_writecommand(hlcd, PIXEL_FORMAT_SET);
+	data = 0x55;
+    lcd_writebyte(hlcd, &data, 1);
+	if(hlcd->dir & DIR_XY_MASK){
+		hlcd->_width = ST7789_TFTHEIGHT;
+		hlcd->_height = ST7789_TFTWIDTH;
+	}
+	else{
+		hlcd->_width = ST7789_TFTWIDTH;
+		hlcd->_height = ST7789_TFTHEIGHT;
+	}
+	hlcd->colstart = 0;
+	hlcd->rowstart = 0;
+
+	lcd_writecommand(hlcd, MEMORY_ACCESS_CTL);
+    lcd_writebyte(hlcd, (uint8_t *)&hlcd->dir, 1);
+
+	/*
+	 *  display on
+	 */
+	lcd_writecommand(hlcd, DISPALY_ON);
+	hlcd->mode = 1;
+}
+
+/*
+ *  表示ウィンドウ設定
+ */
+void
+lcd_setAddrWindow(LCD_Handler_t *hlcd,  uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1)
+{
+    uint8_t data[4] = {0};
+
+    data[0] = (uint8_t)(x0 >> 8);
+    data[1] = (uint8_t)(x0);
+    data[2] = (uint8_t)(x1 >> 8);
+    data[3] = (uint8_t)(x1);
+	lcd_writecommand(hlcd, HORIZONTAL_ADDRESS_SET);
+    lcd_writebyte(hlcd, data, 4);
+
+    data[0] = (uint8_t)(y0 >> 8);
+    data[1] = (uint8_t)(y0);
+    data[2] = (uint8_t)(y1 >> 8);
+    data[3] = (uint8_t)(y1);
+	lcd_writecommand(hlcd, VERTICAL_ADDRESS_SET);
+    lcd_writebyte(hlcd, data, 4);
+
+	SVC_PERROR(lcd_writecommand(hlcd, MEMORY_WRITE));
+}
+
+/*
+ *  RECTANGLEのフィル描画
+ *  param1  hlcd: Pointer to LCD Handler
+ *  param2  x: start X position
+ *  param3  y: start Y position
+ *  param4  w: width
+ *  param5  h: height
+ *  param6  color: color value
+ */
+void
+lcd_fillRect(LCD_Handler_t *hlcd, int16_t x, int16_t y, int16_t w, int16_t h, color_t color)
+{
+    uint32_t data = ((uint32_t)color << 16) | (uint32_t)color;
+	// rudimentary clipping (drawChar w/big text requires this)
+	if((x >= hlcd->_width) || (y >= hlcd->_height)) return;
+	if((x + w - 1) >= hlcd->_width)  w = hlcd->_width  - x;
+	if((y + h - 1) >= hlcd->_height) h = hlcd->_height - y;
+
+	lcd_setAddrWindow(hlcd, x, y, x+w-1, y+h-1);
+    SVC_PERROR(lcd_filldata(hlcd, &data, (h*w+1)/2));
+}
+
+/*
+ *  PIXEL描画
+ *  param1  hlcd: Pointer to LCD Handler
+ *  param2  x: X position
+ *  param3  y: Y position
+ *  param4  color: color value
+ */
+void
+lcd_drawPixel(LCD_Handler_t *hlcd, int16_t x, int16_t y, color_t color)
+{
+	uint32_t data = color;
+    lcd_setAddrWindow(hlcd, x, y, x, y);
+	SVC_PERROR(lcd_writehalf(hlcd, &data, 1));
+}
+
+/*
+ *  垂直方向LINEの高速描画
+ *  param1  hlcd: Pointer to LCD Handler
+ *  param2  x: start X position
+ *  param3  y: start Y position
+ *  param4  h: height
+ *  param5  color: color value
+ */
+void
+lcd_drawFastVLine(LCD_Handler_t *hlcd, int16_t x, int16_t y, int16_t h, color_t color)
+{
+    uint32_t data = ((uint32_t)color << 16) | (uint32_t)color;
+	// Rudimentary clipping
+	if(h == 0) return;
+	if((x >= hlcd->_width) || (y >= hlcd->_height)) return;
+	if((y+h-1) >= hlcd->_height) h = hlcd->_height-y;
+	lcd_setAddrWindow(hlcd, x, y, x, y+h-1);
+    SVC_PERROR(lcd_filldata(hlcd, &data, (h+1)/2));
+}
+
+/*
+ *  水平方向LINEの高速描画
+ *  param1  hlcd: Pointer to LCD Handler
+ *  param2  x: start X position
+ *  param3  y: start Y position
+ *  param4  w: width
+ *  param5  color: color value
+ */
+void lcd_drawFastHLine(LCD_Handler_t *hlcd, int16_t x, int16_t y, int16_t w, color_t color)
+{
+    uint32_t data = ((uint32_t)color << 16) | (uint32_t)color;
+	// Rudimentary clipping
+	if(w == 0) return;
+	if((x >= hlcd->_width) || (y >= hlcd->_height)) return;
+	if((x+w-1) >= hlcd->_width)  w = hlcd->_width-x;
+	lcd_setAddrWindow(hlcd, x, y, x+w-1, y);
+    SVC_PERROR(lcd_filldata(hlcd, &data, (w+1)/2));
+}
+
+/*
+ *  DRAW IMAGE LINE描画
+ *  param1  hlcd: Pointer to LCD Handler
+ *  param2  x: X position
+ *  param3  y: Y position
+ *  param4  w: width
+ *  param5  pcolor: color value
+ */
+void
+lcd_drawImageHLine(LCD_Handler_t *hlcd, int16_t x, int16_t y, uint16_t w, uint32_t *pcolor)
+{
+	if((x >= hlcd->_width) || (y >= hlcd->_height)) return;
+	if((x+w-1) >= hlcd->_width)  w = hlcd->_width-x;
+	lcd_setAddrWindow(hlcd, x, y, x+w-1, y);
+	SVC_PERROR(lcd_writehalf(hlcd, pcolor, w));
+}
+
+/*
+ *  BITMAP描画
+ *  param1  hlcd: Pointer to LCD Handler
+ *  param2  x0: Bmp X position in the LCD
+ *  param3  y0: Bmp Y position in the LCD
+ *  param4  pbmp: Pointer to Bmp picture address in the internal Flash
+ */
+void
+lcd_drawBitmap(LCD_Handler_t *hlcd, uint16_t x0, uint16_t y0, uint8_t *pbmp)
+{
+	uint32_t index = 0, width = 0, height = 0, bit_pixel = 0;
+	uint32_t input_color_mode = 0;
+	uint32_t i;
+
+	/* Get bitmap data address offset */
+	index = *(uint16_t *) (pbmp + 10);
+	index |= (*(uint16_t *) (pbmp + 12)) << 16;
+
+	/* Read bitmap width */
+	width = *(uint16_t *) (pbmp + 18);
+	width |= (*(uint16_t *) (pbmp + 20)) << 16;
+
+	/* Read bitmap height */
+	height = *(uint16_t *) (pbmp + 22);
+	height |= (*(uint16_t *) (pbmp + 24)) << 16;
+
+	/* Read bit/pixel */
+	bit_pixel = *(uint16_t *) (pbmp + 28);
+
+	/* Get the layer pixel format */
+	if ((bit_pixel/8) == 4){
+		input_color_mode = CM_ARGB8888;
+	}
+	else if ((bit_pixel/8) == 2){
+		input_color_mode = CM_RGB565;
+	}
+	else{
+		input_color_mode = CM_RGB888;
+	}
+
+	/* Bypass the bitmap header */
+	pbmp += (index + (width * (height - 1) * (bit_pixel/8)));  
+	syslog_4(LOG_NOTICE, "## input_color_mode(%d) width(%d) height(%d) bit_pixel(%d) ##", input_color_mode, width, height, bit_pixel);
+	for(index=0; index < height; index++){
+		uint8_t *p = pbmp;
+		color_t color;
+		for (i = 0; i < width; i++){
+			color  = ((p[0] & 0xf8) | (p[1] >> 5)) << 8;
+			color  |= ((p[1] << 3) & 0xE0) | ((p[2] >> 3) & 0x1F);
+			lcd_drawPixel(hlcd, x0+i, y0+index, color);
+			p += 3;
+		}
+		pbmp -= width*3;
+	}
+}
+
+/*
+ *  PICTURE描画
+ *  param1  hlcd: Pointer to LCD Handler
+ *  param2  x: Picture X position in the LCD
+ *  param3  y: Picture Y position in the LCD
+ *  param4  width:  Picture width
+ *  param5  height: Picture heigth
+ *  param6  pbmp: Pointer to picture address in the internal Flash
+ */
+void
+lcd_drawPicture(LCD_Handler_t *hlcd, uint16_t x, uint16_t y, uint16_t width, uint16_t height, uint16_t *pbmp)
+{
+	SPI_Handle_t *hspi = hlcd->hspi;
+	ER ercd = E_OK;
+
+	if((x >= hlcd->_width) || (y >= hlcd->_height)) return;
+	if((x+width-1) > hlcd->_width)  return;
+	if((y+height-1) > hlcd->_height)  return;
+
+	lcd_setAddrWindow(hlcd, x, y, x+width-1, y+height-1);
+    set_dcx_data(hlcd);
+	hspi->Init.DataSize = 32;
+	hspi->Init.InstLength = 0;
+	hspi->Init.AddrLength = 32;
+	ercd = spi_core_transmit(hspi, hlcd->cs_sel, (uint8_t *)pbmp, width * height / 2);
+#if SPI_WAIT_TIME == 0
+	if(ercd == E_OK)
+		spi_wait(hspi, SPI_CORE_WAIT_TIME);
+#endif
+	(void)(ercd);
+}
+
+/*
+ *  INVERT DISPLAY
+ *  param1  hlcd: Pointer to LCD Handler
+ *  param2  i: invert value
+ */
+void
+lcd_invertDisplay(LCD_Handler_t *hlcd, bool_t i)
+{
+	lcd_writecommand(hlcd, (i ? INVERSION_DISPALY_ON : INVERSION_DISPALY_OFF));
+}
+
+
+/*
+ *  スクリーンフィル
+ *  param1  pDrawProp: Pointer to Draw Prop
+ */
+void
+lcd_fillScreen(LCD_DrawProp_t *pDrawProp)
+{
+	lcd_fillRect(pDrawProp->hlcd, 0, 0,  pDrawProp->hlcd->_width, pDrawProp->hlcd->_height, pDrawProp->BackColor);
+}
+
+/*
+ *  RECTANGLE描画
+ *  param1  pDrawProp: Pointer to Draw Prop
+ *  param2  x: left X position
+ *  param3  y: top Y position
+ *  param4  w: width
+ *  param5  h: height
+ */
+void
+lcd_drawRect(LCD_DrawProp_t *pDrawProp, int16_t x, int16_t y, int16_t w, int16_t h)
+{
+	LCD_Handler_t *hlcd = pDrawProp->hlcd;
+	color_t color;
+
+	// rudimentary clipping (drawChar w/big text requires this)
+	if((x >= hlcd->_width) || (y >= hlcd->_height)) return;
+	if((x + w - 1) >= hlcd->_width)  w = hlcd->_width  - x;
+	if((y + h - 1) >= hlcd->_height) h = hlcd->_height - y;
+
+	color = pDrawProp->TextColor;
+	lcd_drawFastVLine(hlcd, x, y, h, color);
+	lcd_drawFastHLine(hlcd, x, y+h-1, w, color);
+	lcd_drawFastVLine(hlcd, x+w-1, y, h, color);
+	lcd_drawFastHLine(hlcd, x, y, w, color);
+}
+
+/*
+ *  円描画
+ *  param1  pDrawProp: Pointer to Draw Prop
+ *  param2  x0: X position
+ *  param3  y0: Y position
+ *  param4  Radius: Circle radius
+ */
+void
+lcd_DrawCircle(LCD_DrawProp_t *pDrawProp, uint16_t x0, uint16_t y0, uint16_t Radius)
+{
+	LCD_Handler_t *hlcd = pDrawProp->hlcd;
+ 	int32_t   decision;    /* Decision Variable */ 
+	uint32_t  current_x;   /* Current X Value */
+	uint32_t  current_y;   /* Current Y Value */
+
+	decision = 3 - (Radius << 1);
+	current_x = 0;
+	current_y = Radius;
+
+	while(current_x <= current_y){
+		lcd_drawPixel(hlcd, (x0 + current_x), (y0 - current_y), pDrawProp->TextColor);
+		lcd_drawPixel(hlcd, (x0 - current_x), (y0 - current_y), pDrawProp->TextColor);
+		lcd_drawPixel(hlcd, (x0 + current_y), (y0 - current_x), pDrawProp->TextColor);
+		lcd_drawPixel(hlcd, (x0 - current_y), (y0 - current_x), pDrawProp->TextColor);
+		lcd_drawPixel(hlcd, (x0 + current_x), (y0 + current_y), pDrawProp->TextColor);
+		lcd_drawPixel(hlcd, (x0 - current_x), (y0 + current_y), pDrawProp->TextColor);
+		lcd_drawPixel(hlcd, (x0 + current_y), (y0 + current_x), pDrawProp->TextColor);
+		lcd_drawPixel(hlcd, (x0 - current_y), (y0 + current_x), pDrawProp->TextColor);
+
+		if (decision < 0){
+			decision += (current_x << 2) + 6;
+		}
+		else{
+			decision += ((current_x - current_y) << 2) + 10;
+			current_y--;
+		}
+		current_x++;
+	}
+}
+
+/*
+ *  線描画
+ *  param1  pDrawProp: Pointer to Draw Prop
+ *  param2  x1: Point 1 X position
+ *  param3  y1: Point 1 Y position
+ *  param4  x2: Point 2 X position
+ *  param5  y2: Point 2 Y position
+ */
+void
+lcd_drawLine(LCD_DrawProp_t *pDrawProp, uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2)
+{
+	LCD_Handler_t *hlcd = pDrawProp->hlcd;
+	int16_t deltax = 0, deltay = 0, x = 0, y = 0, xinc1 = 0, xinc2 = 0, 
+	yinc1 = 0, yinc2 = 0, den = 0, num = 0, num_add = 0, num_pixels = 0, 
+	curpixel = 0;
+
+	deltax = ABS(x2 - x1);		/* The difference between the x's */
+	deltay = ABS(y2 - y1);		/* The difference between the y's */
+	x = x1;						/* Start x off at the first pixel */
+	y = y1;						/* Start y off at the first pixel */
+
+	if(x2 >= x1){				/* The x-values are increasing */
+		xinc1 = 1;
+		xinc2 = 1;
+	}
+	else{						/* The x-values are decreasing */
+		xinc1 = -1;
+		xinc2 = -1;
+	}
+
+	if(y2 >= y1){				/* The y-values are increasing */
+		yinc1 = 1;
+		yinc2 = 1;
+	}
+	else{						/* The y-values are decreasing */
+		yinc1 = -1;
+		yinc2 = -1;
+	}
+
+	if(deltax >= deltay){		/* There is at least one x-value for every y-value */
+		xinc1 = 0;				/* Don't change the x when numerator >= denominator */
+		yinc2 = 0;				/* Don't change the y for every iteration */
+		den = deltax;
+		num = deltax / 2;
+		num_add = deltay;
+		num_pixels = deltax;	/* There are more x-values than y-values */
+	}
+	else{						/* There is at least one y-value for every x-value */
+		xinc2 = 0;				/* Don't change the x for every iteration */
+		yinc1 = 0;				/* Don't change the y when numerator >= denominator */
+		den = deltay;
+		num = deltay / 2;
+		num_add = deltax;
+		num_pixels = deltay;	/* There are more y-values than x-values */
+	}
+
+	for (curpixel = 0; curpixel <= num_pixels; curpixel++){
+		lcd_drawPixel(hlcd, x, y, pDrawProp->TextColor);	/* Draw the current pixel */
+		num += num_add;			/* Increase the numerator by the top of the fraction */
+		if(num >= den){			/* Check if numerator >= denominator */
+			num -= den;			/* Calculate the new numerator value */
+			x += xinc1;			/* Change the x as appropriate */
+			y += yinc1;			/* Change the y as appropriate */
+		}
+		x += xinc2;				/* Change the x as appropriate */
+		y += yinc2;				/* Change the y as appropriate */
+	}
+}
+
+/*
+ *  PLOY-LINE描画
+ *  param1  pDrawProp: Pointer to Draw Prop
+ *  param2  Points: Pointer to the points array
+ *  param3  PointCount: Number of points
+ */
+void
+lcd_drawPolygon(LCD_DrawProp_t *pDrawProp, pPoint Points, uint16_t PointCount)
+{
+	int16_t x = 0, y = 0;
+
+	if(PointCount < 2){
+		return;
+	}
+
+	lcd_drawLine(pDrawProp, Points->X, Points->Y, (Points+PointCount-1)->X, (Points+PointCount-1)->Y);
+	while(--PointCount){
+		x = Points->X;
+		y = Points->Y;
+		Points++;
+		lcd_drawLine(pDrawProp, x, y, Points->X, Points->Y);
+	}
+}
+
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/sipeed_st7789/sipeed_st7789.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/sipeed_st7789/sipeed_st7789.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/sipeed_st7789/sipeed_st7789.h	(revision 457)
@@ -0,0 +1,262 @@
+/*
+ *  TOPPERS/ASP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Advanced Standard Profile Kernel
+ *
+ *  Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
+ *                              Toyohashi Univ. of Technology, JAPAN
+ *  Copyright (C) 2004-2010 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ *  Copyright (C) 2015-2019 by TOPPERS PROJECT Educational Working Group.
+ *
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ *
+ *  $Id$
+ */
+/*
+ *  SIPEED ST7789 2.4"LCD制御プログラムのヘッダファイル
+ */
+
+#ifndef _SIPEED_ST7789_H_
+#define _SIPEED_ST7789_H_
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+#include "device.h"
+#include "spi.h"
+
+/*
+ *  LCDカラーモード定義
+ */
+#define CM_ARGB8888         0x00000000			/* ARGB8888 color mode */
+#define CM_RGB888           0x00000001			/* RGB888 color mode */
+#define CM_RGB565           0x00000002			/* RGB565 color mode */
+
+#define ST7789_TFTWIDTH  240
+#define ST7789_TFTHEIGHT 320
+
+
+#define NO_OPERATION            0x00
+#define SOFTWARE_RESET          0x01
+#define READ_ID                 0x04
+#define READ_STATUS             0x09
+#define READ_POWER_MODE         0x0A
+#define READ_MADCTL             0x0B
+#define READ_PIXEL_FORMAT       0x0C
+#define READ_IMAGE_FORMAT       0x0D
+#define READ_SIGNAL_MODE        0x0E
+#define READ_SELT_DIAG_RESULT   0x0F
+#define SLEEP_ON                0x10
+#define SLEEP_OFF               0x11
+#define PARTIAL_DISPALY_ON      0x12
+#define NORMAL_DISPALY_ON       0x13
+#define INVERSION_DISPALY_OFF   0x20
+#define INVERSION_DISPALY_ON    0x21
+#define GAMMA_SET               0x26
+#define DISPALY_OFF             0x28
+#define DISPALY_ON              0x29
+#define HORIZONTAL_ADDRESS_SET  0x2A
+#define VERTICAL_ADDRESS_SET    0x2B
+#define MEMORY_WRITE            0x2C
+#define COLOR_SET               0x2D
+#define MEMORY_READ             0x2E
+#define PARTIAL_AREA            0x30
+#define VERTICAL_SCROL_DEFINE   0x33
+#define TEAR_EFFECT_LINE_OFF    0x34
+#define TEAR_EFFECT_LINE_ON     0x35
+#define MEMORY_ACCESS_CTL       0x36
+#define VERTICAL_SCROL_S_ADD    0x37
+#define IDLE_MODE_OFF           0x38
+#define IDLE_MODE_ON            0x39
+#define PIXEL_FORMAT_SET        0x3A
+#define WRITE_MEMORY_CONTINUE   0x3C
+#define READ_MEMORY_CONTINUE    0x3E
+#define SET_TEAR_SCANLINE       0x44
+#define GET_SCANLINE            0x45
+#define WRITE_BRIGHTNESS        0x51
+#define READ_BRIGHTNESS         0x52
+#define WRITE_CTRL_DISPALY      0x53
+#define READ_CTRL_DISPALY       0x54
+#define WRITE_BRIGHTNESS_CTL    0x55
+#define READ_BRIGHTNESS_CTL     0x56
+#define WRITE_MIN_BRIGHTNESS    0x5E
+#define READ_MIN_BRIGHTNESS     0x5F
+#define READ_ID1                0xDA
+#define READ_ID2                0xDB
+#define READ_ID3                0xDC
+#define RGB_IF_SIGNAL_CTL       0xB0
+#define NORMAL_FRAME_CTL        0xB1
+#define IDLE_FRAME_CTL          0xB2
+#define PARTIAL_FRAME_CTL       0xB3
+#define INVERSION_CTL           0xB4
+#define BLANK_PORCH_CTL         0xB5
+#define DISPALY_FUNCTION_CTL    0xB6
+#define ENTRY_MODE_SET          0xB7
+#define BACKLIGHT_CTL1          0xB8
+#define BACKLIGHT_CTL2          0xB9
+#define BACKLIGHT_CTL3          0xBA
+#define BACKLIGHT_CTL4          0xBB
+#define BACKLIGHT_CTL5          0xBC
+#define BACKLIGHT_CTL7          0xBE
+#define BACKLIGHT_CTL8          0xBF
+#define POWER_CTL1              0xC0
+#define POWER_CTL2              0xC1
+#define VCOM_CTL1               0xC5
+#define VCOM_CTL2               0xC7
+#define NV_MEMORY_WRITE         0xD0
+#define NV_MEMORY_PROTECT_KEY   0xD1
+#define NV_MEMORY_STATUS_READ   0xD2
+#define READ_ID4                0xD3
+#define POSITIVE_GAMMA_CORRECT  0xE0
+#define NEGATIVE_GAMMA_CORRECT  0xE1
+#define DIGITAL_GAMMA_CTL1      0xE2
+#define DIGITAL_GAMMA_CTL2      0xE3
+#define INTERFACE_CTL           0xF6
+
+/*
+ *  カラー定義
+ */
+#define ST7789_BLACK            0x0000
+#define ST7789_NAVY             0x000F
+#define ST7789_DARKGREEN        0x03E0
+#define ST7789_DARKCYAN         0x03EF
+#define ST7789_MAROON           0x7800
+#define ST7789_PURPLE           0x780F
+#define ST7789_OLIVE            0x7BE0
+#define ST7789_LIGHTGREY        0xC618
+#define ST7789_DARKGREY         0x7BEF
+#define ST7789_BLUE             0x001F
+#define ST7789_GREEN            0x07E0
+#define ST7789_CYAN             0x07FF
+#define ST7789_RED              0xF800
+#define ST7789_MAGENTA          0xF81F
+#define ST7789_YELLOW           0xFFE0
+#define ST7789_WHITE            0xFFFF
+#define ST7789_ORANGE           0xFD20
+#define ST7789_GREENYELLOW      0xAFE5
+#define ST7789_PINK             0xF81F
+
+/*
+ *  LCD DIRECTION
+ */
+#define DIR_XY_RLUD             0x00
+#define DIR_YX_RLUD             0x20
+#define DIR_XY_LRUD             0x40
+#define DIR_YX_LRUD             0x60
+#define DIR_XY_RLDU             0x80
+#define DIR_YX_RLDU             0xA0
+#define DIR_XY_LRDU             0xC0
+#define DIR_YX_LRDU             0xE0
+#define DIR_XY_MASK             0x20
+#define DIR_RL_MASK             0x40
+#define DIR_UD_MASK             0x80
+
+#define TRS_COLOR_T             uint32_t
+
+#ifndef TOPPERS_MACRO_ONLY
+
+
+/*
+ *  カラーの属性を定義
+ */
+typedef uint16_t   color_t;
+
+typedef struct
+{
+	SPI_Handle_t            *hspi;
+    uint16_t                _width;
+    uint16_t                _height;
+	uint16_t                colstart;
+	uint16_t                rowstart;
+	ID                      spi_lock;
+    uint8_t                 mode;
+    uint8_t                 dir;
+
+	int8_t                  dcx_pin;
+	int8_t                  rst_pin;
+	int8_t                  cs_sel;
+	uint8_t                 dcx_no;
+	uint8_t                 rst_no;
+} LCD_Handler_t;
+
+
+/*
+ *  描画構造体
+ */
+typedef struct
+{
+	LCD_Handler_t           *hlcd;
+	color_t                 TextColor;
+	color_t                 BackColor;
+	void                    *pFont;
+}LCD_DrawProp_t;
+
+typedef struct
+{
+	int16_t X;
+	int16_t Y;
+}Point, * pPoint;
+
+/*
+ *  関数のプロトタイプ宣言
+ */
+extern ER lcd_writecommand(LCD_Handler_t *hlcd, uint8_t c);
+extern ER lcd_writebyte(LCD_Handler_t *hlcd, uint8_t *buf, uint8_t len);
+extern ER lcd_writehalf(LCD_Handler_t *hlcd, uint32_t *buf, int cnt);
+extern ER lcd_filldata(LCD_Handler_t *hlcd, uint32_t *data_buf, uint32_t len);
+
+extern void lcd_init(LCD_Handler_t *hlcd);
+extern void lcd_setAddrWindow(LCD_Handler_t *hlcd, uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1);
+extern void lcd_fillRect(LCD_Handler_t *hlcd, int16_t x, int16_t y, int16_t w, int16_t h, color_t color);
+extern void lcd_pushColor(LCD_Handler_t *hlcd, color_t color);
+extern void lcd_drawPixel(LCD_Handler_t *hlcd, int16_t x, int16_t y, color_t color);
+extern void lcd_drawFastVLine(LCD_Handler_t *hlcd, int16_t x, int16_t y, int16_t h, color_t color);
+extern void lcd_drawFastHLine(LCD_Handler_t *hlcd, int16_t x, int16_t y, int16_t w, color_t color);
+extern void lcd_drawImageHLine(LCD_Handler_t *hlcd, int16_t x, int16_t y, uint16_t w, TRS_COLOR_T *pcolor);
+extern void lcd_drawBitmap(LCD_Handler_t *hlcd, uint16_t x0, uint16_t y0, uint8_t *pbmp);
+extern void lcd_drawPicture(LCD_Handler_t *hlcd, uint16_t x, uint16_t y, uint16_t width, uint16_t height, uint16_t *pbmp);
+extern void lcd_invertDisplay(LCD_Handler_t *hlcd, bool_t i);
+
+extern void lcd_fillScreen(LCD_DrawProp_t *pDrawProp);
+extern void lcd_drawRect(LCD_DrawProp_t *pDrawProp, int16_t x, int16_t y, int16_t w, int16_t h);
+extern void lcd_DrawCircle(LCD_DrawProp_t *pDrawProp, uint16_t x0, uint16_t y0, uint16_t Radius);
+extern void lcd_drawLine(LCD_DrawProp_t *pDrawProp, uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2);
+extern void lcd_drawPolygon(LCD_DrawProp_t *pDrawProp, pPoint Points, uint16_t PointCount);
+
+#endif /* TOPPERS_MACRO_ONLY */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif	/* _SIPEED_ST7789_H_ */
+
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/spi_driver/Makefile.config
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/spi_driver/Makefile.config	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/spi_driver/Makefile.config	(revision 457)
@@ -0,0 +1,55 @@
+#
+#   TOPPERS/ASP/FMP Kernel
+#       Toyohashi Open Platform for Embedded Real-Time Systems/
+#       Advanced Standard Profile Kernel
+#
+#   Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
+#                               Toyohashi Univ. of Technology, JAPAN
+#   Copyright (C) 2003-2008 by Ryosuke Takeuchi
+#                Platform Development Center RICOH COMPANY,LTD. JAPAN
+#   Copyright (C) 2015-2017 by TOPPERS PROJECT Educational Working Group.
+#
+#   上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+#   によって公表されている GNU General Public License の Version 2 に記
+#   述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+#   を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+#   利用と呼ぶ）することを無償で許諾する．
+#   (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+#       権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+#       スコード中に含まれていること．
+#   (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+#       用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+#       者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+#       の無保証規定を掲載すること．
+#   (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+#       用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+#       と．
+#     (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+#         作権表示，この利用条件および下記の無保証規定を掲載すること．
+#     (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+#         報告すること．
+#   (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+#       害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+#
+#   本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+#   よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+#   含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+#   接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+#
+#  @(#) $Id$
+#
+ 
+#
+#  Makefile のプロセッサ依存 (spi_driver:sdcard用)
+#
+
+#
+#  コンパイルオプション
+#
+INCLUDES := $(INCLUDES) -I$(SRCDIR)/gdic/spi_driver
+
+#
+#  SPI DRIVER(GDIC)に関する定義
+#
+SYSSVC_DIR := $(SYSSVC_DIR):$(SRCDIR)/gdic/spi_driver
+SYSSVC_COBJS := $(SYSSVC_COBJS) spi_driver.o
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/spi_driver/mcicmd.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/spi_driver/mcicmd.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/spi_driver/mcicmd.h	(revision 457)
@@ -0,0 +1,66 @@
+/*
+ *  TOPPERS/ASP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Advanced Standard Profile Kernel
+ * 
+ *  Copyright (C) 2008-2011 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ *  Copyright (C) 2015-2016 by TOPPERS PROJECT Educational Working Group.
+ * 
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+#ifndef _MCICMD_H_
+#define _MCICMD_H_
+
+#define MCIPCB              SDCARD_Handler_t
+#define MCIINFO             SDCARD_CardInfo_t
+
+#define SDDEV_BUS_WIDE_4B   SDMMC_BUS_WIDE_4B
+#define DMA_ALINE
+
+#define mci_ses_por         sdcard_init
+#define mci_opn_por         sdcard_open
+#define mci_cls_por         sdcard_close
+#define MciCheckCID         sdcard_checkCID
+#define MciSetAddress       sdcard_dummy
+#define MciSendCID          sdcard_sendCSD
+#define MciGetCardInfo      sdcard_getcardinfo
+#define MciSelectCard       sdcard_select_card
+#define MciConfiguration    sdcard_configuration
+#define MciSetWideBus       sdcard_dummy
+#define mci_red_blk         sdcard_blockread
+#define mci_wri_blk         sdcard_blockwrite
+#define mci_wai_trn         sdcard_wait_transfar
+
+#include "spi_driver.h"
+
+#endif
+
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/spi_driver/spi_driver.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/spi_driver/spi_driver.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/spi_driver/spi_driver.c	(revision 457)
@@ -0,0 +1,950 @@
+/*
+ *  TOPPERS/ASP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Advanced Standard Profile Kernel
+ * 
+ *  Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
+ *                              Toyohashi Univ. of Technology, JAPAN
+ *  Copyright (C) 2004-2012 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ *  Copyright (C) 2015-2019 by TOPPERS PROJECT Educational Working Group.
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  $Id$
+ */
+
+/* 
+ *  SPI用デバイスドライバ
+ */
+
+#include <kernel.h>
+#include <t_syslog.h>
+#include <t_stdlib.h>
+#include <string.h>
+#include <target_syssvc.h>
+#include "syssvc/serial.h"
+#include "syssvc/syslog.h"
+#include "device.h"
+#include "spi.h"
+#include "pinmode.h"
+#include "spi_driver.h"
+
+#define sil_orw_mem(a, b)		sil_wrw_mem((a), sil_rew_mem(a) | (b))
+#define sil_andw_mem(a, b)		sil_wrw_mem((a), sil_rew_mem(a) & ~(b))
+#define sil_modw_mem(a, b, c)	sil_wrw_mem((a), (sil_rew_mem(a) & (~b)) | (c))
+
+#define INIT_RETRY_COUNT    32
+
+#define CRC16POLY           0x1021
+
+static const uint8_t CMD0[5]   = {0x40, 0x00, 0x00, 0x00, 0x00};
+static const uint8_t CMD8[5]   = {0x48, 0x00, 0x00, 0x01, 0xAA};
+static const uint8_t CMD9[5]   = {0x49, 0x00, 0x00, 0x00, 0x00};
+static const uint8_t CMD10[5]  = {0x4A, 0x00, 0x00, 0x00, 0x00};
+static const uint8_t CMD16[5]  = {0x50, 0x00, 0x00, 0x02, 0x00};
+static const uint8_t CMD55[5]  = {0x77, 0x00, 0x00, 0x00, 0x00};
+static const uint8_t ACMD41[5] = {0x69, 0x40, 0x00, 0x00, 0x00};
+static const uint8_t CMD58[5]  = {0x7A, 0x00, 0x00, 0x00, 0x00};
+
+static bool_t           sdcard_sense = true;
+static SDCARD_Handler_t SdHandle;
+
+/* Buffer used for transmission */
+uint8_t aTxBuffer[BUFFERSIZE];
+
+/* Buffer used for reception */
+uint8_t aRxBuffer[BUFFERSIZE];
+
+#ifndef SPI_DRIVER_NOSTART
+/*
+ *  GPIO設定関数
+ */
+static void
+pinMode(uint8_t no, uint32_t otype, uint32_t pullmode)
+{
+	Arduino_PortControlBlock *pgcb = getGpioTable(DIGITAL_PIN, no);
+	GPIO_Init_t GPIO_Init_Data;
+
+	if(pgcb == NULL)
+		return;
+	pinClock(no);
+	GPIO_Init_Data.mode  = GPIO_MODE_OUTPUT;
+	GPIO_Init_Data.pull  = pullmode;
+	GPIO_Init_Data.otype = otype;
+	GPIO_Init_Data.speed = GPIO_SPEED_FAST;
+	gpio_setup(pgcb->giobase, &GPIO_Init_Data, pgcb->giopin);
+}
+
+/*
+ *  SPI初期化関数
+ */
+SPI_Handle_t *
+spi_start(SPI_Setup_t *psps)
+{
+	SPI_Init_t spi_initd;
+	SPI_Handle_t  *hspi;
+
+	/*
+	 *  CS PORT(D10-PB6)
+	 */
+	pinMode(psps->cs_pin, psps->otype, psps->pullmode);
+	/*
+	 *  RS PORT(D8-PA9)
+	 */
+	pinMode(psps->rs_pin, psps->otype, psps->pullmode);
+	/*
+	 *  RST PORT(D9-PC7)
+	 */
+	pinMode(psps->rst_pin, psps->otype, psps->pullmode);
+	/*
+	 *  CS2 PORT(D4-PB5)
+	 */
+	pinMode(psps->cs2_pin, psps->otype, psps->pullmode);
+	SdHandle.cs2_port = psps->cs2_pin;
+
+	memset(&spi_initd, 0, sizeof(SPI_Init_t));
+	spi_initd.Prescaler     = psps->baud;
+	spi_initd.Direction     = SPI_DIRECTION_2LINES;
+	spi_initd.CLKPhase      = SPI_PHASE_1EDGE;
+	spi_initd.CLKPolarity   = SPI_POLARITY_LOW;
+	spi_initd.CRC           = SPI_CRC_DISABLE;
+	spi_initd.CRCPolynomial = 7;
+	spi_initd.DataSize      = SPI_DATASIZE_8BIT;
+	spi_initd.SignBit       = SPI_DATA_MSB;
+	spi_initd.NSS           = SPI_NSS_SOFT;
+	spi_initd.TIMode        = SPI_TIMODE_DISABLE;
+	spi_initd.Mode = SPI_MODE_MASTER;
+	spi_initd.semid   = psps->spi_sem;
+	spi_initd.semlock = 0;
+
+	if((hspi = spi_init(psps->port, &spi_initd)) == NULL){
+		syslog_0(LOG_ERROR, "spi_start initialize error !");
+	}
+	return hspi;
+}
+
+/*
+ *  SPI終了関数
+ */
+void
+spi_end(SPI_Handle_t *hspi)
+{
+	spi_deinit(hspi);
+}
+#endif	/* SPI_DRIVER_NOSTART */
+
+
+/*
+ *  CRC7計算関数
+ */
+static uint8_t
+calc_CRC7(const uint8_t *data, int len)
+{
+	uint_t  i, j;
+	uint8_t crc = 0, dt;
+
+	for(i = 0; i < len; i++){
+		dt = *data++;
+		for(j = 0; j < 8; j++){
+			crc <<=1;
+			if ((crc & 0x80) ^ (dt & 0x80))
+				crc ^= 0x09;
+			dt <<= 1;
+		}
+	}
+	return ((crc & 0x7f) << 1) | 1;
+}
+
+/*
+ *  CRC16-CCITT計算関数
+ */
+static uint16_t
+calc_CRC16(const uint8_t *data, int len)
+{
+	uint16_t crc = 0;
+	int i, j;
+
+	for(i = 0; i < len; i++){
+		crc ^= (data[i]<<8);
+		for(j = 0; j < 8; j++){
+			if(crc & 0x8000)
+				crc = (crc << 1) ^ CRC16POLY;
+			else
+				crc <<= 1;
+		}
+	}
+	return crc;
+}
+
+/*
+ *  SDCARDからのデータ読み込み
+ */
+static ER
+sdcard_read(SPI_Handle_t *hspi, uint8_t *pres, int size)
+{
+	ER ercd;
+
+#if SPI_WAIT_TIME != 0
+	ercd = spi_receive(hspi, (uint8_t*)pres, size);
+#else
+	if((ercd = spi_receive(hspi, (uint8_t*)pres, size)) == E_OK){
+		ercd = spi_wait(hspi, 50);
+	}
+#endif
+	if(ercd != E_OK)
+    	syslog_1(LOG_ERROR, "sdcard_read ERROR(%d) !", ercd);
+	return ercd;
+}
+
+/*
+ *  SDCARDへのデータ書き込み
+ */
+static ER
+sdcard_write(SPI_Handle_t *hspi, uint8_t *pres, int size)
+{
+	ER ercd;
+
+#if SPI_WAIT_TIME != 0
+	ercd = spi_transmit(hspi, (uint8_t*)pres, size);
+#else
+	if((ercd = spi_transmit(hspi, (uint8_t*)pres, size)) == E_OK){
+		ercd = spi_wait(hspi, 50);
+	}
+#endif
+	if(ercd != E_OK)
+    	syslog_1(LOG_ERROR, "sdcard_write ERROR(%d) !", ercd);
+	return ercd;
+}
+
+/*
+ *  SDCARDへのコマンド送信
+ */
+static ER
+sdcard_sendcommand(SPI_Handle_t *hspi, const uint8_t *cmd, int size)
+{
+	ER ercd = E_OK;
+	uint8_t crc;
+
+	crc = calc_CRC7(cmd, size);
+	memcpy(aTxBuffer, cmd, size);
+	aTxBuffer[size] = crc;
+#if SPI_WAIT_TIME != 0
+	ercd = spi_transmit(hspi, (uint8_t*)aTxBuffer, (size+1));
+#else
+	if((ercd = spi_transmit(hspi, (uint8_t*)aTxBuffer, (size+1))) == E_OK){
+		ercd = spi_wait(hspi, 50);
+	}
+#endif
+	return ercd;
+}
+
+/*
+ *  SDCARDへのダミー書き込み
+ */
+static ER
+sdcard_dummywrite(SPI_Handle_t *hspi)
+{
+	uint8_t dummy[2];
+	dummy[0] = 0xff;
+	return sdcard_write(hspi, dummy, 1);
+}
+
+/*
+ *  SDCARDからのレスポンス受信
+ */
+static ER
+sdcard_response(SPI_Handle_t *hspi, uint8_t *pres, int size, int timeout)
+{
+	int tick, i = 0;
+
+	timeout *= 100;
+	for(tick = 0 ; tick < timeout ; tick++){
+		if(sdcard_read(hspi, aRxBuffer, 1) == E_OK){
+			pres[i] = aRxBuffer[0];
+			if((aRxBuffer[0] & 0x80) == 0){
+				i++;
+				if(i >= size)
+					return E_OK;
+			}
+		}
+		sil_dly_nse(1000*10);
+	}
+	return E_TMOUT;
+}
+
+/*
+ *  SDCARDからのデータ受信
+ */
+static ER
+sdcard_receive(SPI_Handle_t *hspi, uint8_t *pdata, int size, uint16_t *crc, int timeout)
+{
+	ER  ercd = E_OK;
+	bool_t ff_count;
+	int tick, i = 0;
+
+	for(tick = 0 ; tick < (timeout*1000) ; tick++){
+		*crc = 0xffff;
+		if((ercd = sdcard_read(hspi, aRxBuffer, 1)) == E_OK){
+			if(aRxBuffer[0] == 0xfe){
+				if((ercd = sdcard_read(hspi, pdata, size)) != E_OK)
+					return ercd;
+				ercd = E_TMOUT;
+				for(i = 0, ff_count = 0 ; i < 24 ; i++){
+					sdcard_read(hspi, aRxBuffer, 1);
+					dly_tsk(2);
+					if(aRxBuffer[0] != 0xff){
+						if(ff_count == 0)
+							*crc = aRxBuffer[0]<<8;
+						else if(ff_count == 1)
+							*crc |= aRxBuffer[0];
+						ff_count++;
+					}
+					if(i >= 1 && aRxBuffer[0] == 0xff && ff_count > 0)
+						ercd = E_OK;
+				}
+				return ercd;
+			}
+			else if(aRxBuffer[0] != 0xff){
+				syslog_2(LOG_NOTICE, "## sdcard_receive i(%d) resp[%02x] ##", i, aRxBuffer[0]);
+			}
+		}
+		sil_dly_nse(1000);
+	}
+	return E_TMOUT;
+}
+
+/*
+ *  SDCARDへのデータ送信
+ */
+static ER
+sdcard_send(SPI_Handle_t *hspi, uint8_t *pdata, int size)
+{
+	ER  ercd = E_OK;
+	uint8_t  data[4];
+	uint16_t crc;
+	int   res_count = 0;
+	int i = 0;
+
+	crc = calc_CRC16((const uint8_t *)pdata, size);
+	data[0] = 0xff;
+	data[1] = 0xfe;
+	if((ercd = sdcard_write(hspi, data, 2)) != E_OK)
+		return ercd;
+	if((ercd = sdcard_write(hspi, pdata, size)) != E_OK)
+		return ercd;
+	data[0] = crc >> 8;
+	data[1] = crc & 0xff;
+	if((ercd = sdcard_write(hspi, data, 2)) != E_OK)
+		return ercd;
+	ercd = E_TMOUT;
+	for(i = 0 ; i < 24 ; i++){
+		sdcard_read(hspi, aRxBuffer, 1);
+		dly_tsk(1);
+		if(aRxBuffer[0] != 0xff){
+			if(res_count == 0){
+				if((aRxBuffer[0] & 0x1F) == 0x05)
+					ercd = E_OK;
+				else
+					ercd = E_SYS;
+				res_count++;
+			}
+			else if(aRxBuffer[0] == 0x00)
+				res_count++;
+		}
+		else if(res_count >= 2)
+			break;
+	}
+	return ercd;
+}
+/*
+ *  SDCARD通信ロック
+ */
+static ER
+sdcard_lock(SDCARD_Handler_t *hsd)
+{
+	ER ercd = E_OK;
+	if(hsd->spi_lock != 0)
+		ercd = wai_sem(hsd->spi_lock);
+	digitalWrite(hsd->cs2_port, PORT_LOW);
+	return ercd;
+}
+
+/*
+ *  SDCARD通信アンロック
+ */
+static ER
+sdcard_unlock(SDCARD_Handler_t *hsd)
+{
+	ER ercd = E_OK;
+	digitalWrite(hsd->cs2_port, PORT_HIGH);
+	if(hsd->spi_lock != 0)
+		ercd = sig_sem(hsd->spi_lock);
+	return ercd;
+}
+
+/*
+ *  SDCARDリセット
+ */
+static ER
+sdcard_reset(SDCARD_Handler_t *hsd)
+{
+	ER ercd = E_OK;
+	uint8_t resp[2];
+	int i = 0;
+
+	if((ercd = sdcard_lock(hsd)) != E_OK){
+		return ercd;
+	}
+	for(i = 0 ; i < 20 ; i++){
+		if((ercd = sdcard_sendcommand(hsd->hspi, CMD55, sizeof(CMD55))) != E_OK)
+			continue;
+		if((ercd = sdcard_response(hsd->hspi, resp, 1, 300)) != E_OK)
+			continue;
+		if((ercd = sdcard_sendcommand(hsd->hspi, ACMD41, sizeof(ACMD41))) != E_OK)
+			continue;
+		if((ercd = sdcard_response(hsd->hspi, resp, 1, 300)) != E_OK)
+			continue;
+		if(resp[0] == 0x00)
+			break;
+		dly_tsk(40);
+	}
+	sdcard_unlock(hsd);
+	return ercd;
+}
+
+
+/*
+ *  SDCARDのSPI設定
+ */
+void
+sdcard_setspi(ID portid, SPI_Handle_t *hspi)
+{
+	SdHandle.hspi = hspi;
+}
+
+/*
+ *  SDCARDのSPI設定:改良型
+ */
+void
+sdcard_setspi2(ID portid, SPI_Handle_t *hspi, uint8_t cs_port)
+{
+	SdHandle.hspi     = hspi;
+	SdHandle.cs2_port = cs_port;
+}
+
+/*
+ *  SDCARDの初期化関数、エラーならばカードなし
+ */
+bool_t
+sdcard_init(ID portid)
+{
+	SDCARD_Handler_t *hsd = &SdHandle;
+	SPI_Handle_t *hspi;
+	uint8_t resp[8];
+	uint8_t checkno = 0;
+	ER      ercd;
+	int     i;
+
+	if(!sdcard_sense)
+		return false;
+
+	sdcard_sense = false;
+	if((hspi = hsd->hspi) == NULL)
+		return false;
+	hsd->hspi = NULL;
+
+	if((ercd = sdcard_lock(hsd)) != E_OK)
+		return false;
+	if((ercd = sdcard_sendcommand(hspi, CMD0, sizeof(CMD0))) != E_OK){
+		sdcard_unlock(hsd);
+		return false;
+	}
+	if((ercd = sdcard_response(hspi, resp, 1, 500)) != E_OK){
+		sdcard_unlock(hsd);
+		return false;
+	}
+#if 1	/* ROI DEBUG */
+	syslog_4(LOG_NOTICE, "## resp 0[%02x] 1[%02x] 2[%02x] 3[%02x] ##", resp[0], resp[1], resp[2], resp[3]);
+#endif	/* ROI DEBUG */
+	sdcard_unlock(hsd);
+	sdcard_dummywrite(hspi);
+
+	if((ercd = sdcard_lock(hsd)) != E_OK)
+		return false;
+	if((ercd = sdcard_sendcommand(hspi, CMD8, sizeof(CMD8))) == E_OK){
+		sdcard_response(hspi, resp, 1, 500);
+	}
+	if(ercd == E_OK && (resp[0] & 0x04) == 0x00){
+		ercd = sdcard_read(hspi, resp, 4);
+		if(resp[2] != 0x01 || resp[3] != 0xAA){
+			syslog_4(LOG_ERROR, "CMD8(1) ERROR [%02x][%02x][%02x][%02x] !", resp[0], resp[1], resp[2], resp[3]);
+			sdcard_unlock(hsd);
+			return false;
+		}
+	}
+	else{
+		sdcard_unlock(hsd);
+		sdcard_dummywrite(hspi);
+
+		if((ercd = sdcard_lock(hsd)) != E_OK)
+			return false;
+		checkno = 1;
+		if((ercd = sdcard_sendcommand(hspi, CMD58, sizeof(CMD58))) == E_OK){
+			ercd = sdcard_response(hspi, resp, 1, 500);
+		}
+		if(ercd == E_OK && (resp[0] & 0x04) == 0x00){
+			ercd = sdcard_read(hspi, resp, 4);
+			if(resp[2] != 0x01){
+				syslog_4(LOG_ERROR, "CMD58 ERROR [%02x][%02x][%02x][%02x] !", resp[0], resp[1], resp[2], resp[3]);
+				sdcard_unlock(hsd);
+				return false;
+			}
+		}
+		else{
+			syslog_2(LOG_ERROR, "CMD58 ERROR(%d) [%02x] !", ercd, resp[0]);
+			sdcard_unlock(hsd);
+			return false;
+		}
+	}
+	sdcard_unlock(hsd);
+	sdcard_dummywrite(hspi);
+
+	for(i = 0 ; i < 50 ; i++){	/* 5sec */
+		do{
+			if((ercd = sdcard_lock(hsd)) != E_OK)
+				return false;
+			if((ercd = sdcard_sendcommand(hspi, CMD55, sizeof(CMD55))) == E_OK){
+				if((ercd = sdcard_response(hspi, resp, 1, 500)) == E_OK){
+					sdcard_unlock(hsd);
+					sdcard_dummywrite(hspi);
+
+					if((ercd = sdcard_lock(hsd)) != E_OK)
+						return false;
+					if((ercd = sdcard_sendcommand(hspi, ACMD41, sizeof(ACMD41))) == E_OK){
+						if((ercd = sdcard_response(hspi, resp, 1, 500)) == E_OK){
+							sdcard_unlock(hsd);
+							sdcard_dummywrite(hspi);
+							break;
+						}
+					}
+				}
+			}
+			sdcard_unlock(hsd);
+			sdcard_dummywrite(hspi);
+			dly_tsk(200);
+		}while(ercd != E_OK);
+		if(resp[0] == 0x00)
+			break;
+		dly_tsk(100);
+	}
+
+	if(checkno == 1){
+		sdcard_sense = true;
+		hsd->cardtype = SD_CARD_V20;
+		hsd->hspi = hspi;
+		return true;
+	}
+
+	if((ercd = sdcard_lock(hsd)) != E_OK)
+		return false;
+	if((ercd = sdcard_sendcommand(hspi, CMD58, sizeof(CMD58))) == E_OK){
+		ercd = sdcard_response(hspi, resp, 1, 500);
+	}
+	if(ercd == E_OK && resp[0] == 0x00){
+		sdcard_sense = true;
+		ercd = sdcard_read(hspi, resp, 4);
+		if((resp[0] & 0x40) == 0)
+			hsd->cardtype = SD_CARD_V20;
+		else
+			hsd->cardtype = SD_CARD_HC;
+		hsd->hspi = hspi;
+		sdcard_unlock(hsd);
+		sdcard_dummywrite(hspi);
+		return true;
+	}
+	sdcard_unlock(hsd);
+	return false;
+}
+
+/*
+ *  SDCARDオープン
+ */
+SDCARD_Handler_t*
+sdcard_open(ID portid)
+{
+	if(SdHandle.hspi != NULL){
+		SdHandle.spi_lock    = 0;
+		SdHandle.RetryCount  = INIT_RETRY_COUNT;
+		SdHandle.read_count  = 0;
+		SdHandle.write_count = 0;
+		SdHandle.read_retry_count  = 0;
+		SdHandle.write_retry_count = 0;
+		SdHandle.read_error  = 0;
+		SdHandle.write_error = 0;
+		return &SdHandle;
+	}
+	else
+		return NULL;
+}
+
+/*
+ *  SDCARDクローズ(未処理)
+ */
+ER
+sdcard_close(SDCARD_Handler_t *hsd)
+{
+	return E_OK;
+}
+
+/*
+ *  SDカードの情報を取り込む
+ *  parameter1  hsd: SDCARDハンドラ
+ *  parameter2  pCardInfo: カードインフォ構造体へのポインタ
+ *  return      ERコード
+ */
+ER
+sdcard_getcardinfo(SDCARD_Handler_t *hsd, SDCARD_CardInfo_t *pCardInfo)
+{
+	ER ercd = E_OK;
+	uint32_t devicesize;
+	uint8_t  blocklen, mul;
+
+	pCardInfo->cardtype = (uint8_t)(hsd->cardtype);
+	pCardInfo->RCA      = (uint16_t)(hsd->RCA);
+
+	if(hsd->cardtype == SD_CARD_V11 || hsd->cardtype == SD_CARD_V20){
+		/* ブロック長を取り込む */
+		blocklen       = (uint8_t)(hsd->CSD[5] & 0x0F);
+		devicesize = (hsd->CSD[6] & 0x03) << 10;
+		devicesize |= hsd->CSD[7] << 2;
+		devicesize |= (hsd->CSD[8] & 0xC0) >> 6;
+		mul = (hsd->CSD[9] & 0x03) << 1;
+		mul |= (hsd->CSD[10] & 0x80) >> 7;
+		pCardInfo->capacity  = (devicesize + 1) ;
+		pCardInfo->capacity *= (1 << (mul + 2));
+		pCardInfo->blocksize = 1 << (blocklen);
+		pCardInfo->capacity *= pCardInfo->blocksize;
+	}
+	else if(hsd->cardtype == SD_CARD_HC){
+		devicesize = (hsd->CSD[7] & 0x3F) << 16;
+		devicesize |= (hsd->CSD[8] & 0xFF) << 8;
+		devicesize |= (hsd->CSD[9] & 0xFF);
+		pCardInfo->capacity  = (uint64_t)(devicesize + 1) << 19 /* 512 * 1024*/;
+		pCardInfo->blocksize = 512;
+	}
+	else{
+		pCardInfo->capacity  = 0;
+		pCardInfo->blocksize = 512;
+		ercd = E_OBJ;
+	}
+	pCardInfo->maxsector = pCardInfo->capacity / 512;
+	pCardInfo->status    = (uint8_t)hsd->CSD[14];
+	return ercd;
+}
+
+/*
+ *  CIDの取得
+ *  SDカードCMD2,MMCカードCMD1送信後のレスポンス受信
+ *  parameter1  hsd: SDCARDハンドラ
+ *  return      ERコード
+ */
+ER
+sdcard_checkCID(SDCARD_Handler_t *hsd)
+{
+	ER  ercd = E_OK;
+	uint8_t resp[2];
+	uint16_t crc;
+	int i, timeout = 50;
+
+	if((ercd = sdcard_lock(hsd)) != E_OK)
+		return ercd;
+	for(i = 0 ; i < INIT_RETRY_COUNT ; i++, timeout = 1000){
+	    /*
+		 *  CMD10送信
+		 */
+		if((ercd = sdcard_sendcommand(hsd->hspi, CMD10, sizeof(CMD10))) != E_OK)
+			break;
+		if((ercd = sdcard_response(hsd->hspi, resp, 1, timeout)) != E_OK)
+			continue;
+		else if(resp[0] == 0x00){
+			sdcard_receive(hsd->hspi, &hsd->CID[0], 16, &crc, 5000);
+			sdcard_unlock(hsd);
+			return ercd;
+		}
+	}
+	sdcard_unlock(hsd);
+	if(i == INIT_RETRY_COUNT)
+		ercd = E_TMOUT;
+	return ercd;
+}
+
+/*
+ *  CSD(Card Specific DATA)の取得
+ *  parameter1  hsd: SDCARDハンドラ
+ *  return      ERコード
+ */
+ER
+sdcard_sendCSD(SDCARD_Handler_t *hsd)
+{
+	ER  ercd = E_OK;
+	uint8_t resp[2];
+	uint16_t crc;
+	int i, timeout = 50;
+
+	if((ercd = sdcard_lock(hsd)) != E_OK)
+		return ercd;
+	for(i = 0 ; i < INIT_RETRY_COUNT ; i++, timeout = 1000){
+	    /*
+		 *  CMD9送信
+		 */
+		if((ercd = sdcard_sendcommand(hsd->hspi, CMD9, sizeof(CMD9))) != E_OK)
+			break;
+		if((ercd = sdcard_response(hsd->hspi, resp, 1, timeout)) != E_OK)
+			continue;
+		else if(resp[0] == 0x00){
+			sdcard_receive(hsd->hspi, &hsd->CSD[0], 16, &crc, 5000);
+			sdcard_unlock(hsd);
+			return E_OK;
+		}
+		dly_tsk(100);
+	}
+	if(i == INIT_RETRY_COUNT)
+		ercd = E_TMOUT;
+	sdcard_unlock(hsd);
+	return ercd;
+}
+
+/*
+ *  SELECT_CARDコマンドの送信(未処理)
+ *  parameter1  hsd: SDMMCハンドラ
+ *  return      ERコード
+ */
+ER
+sdcard_select_card(SDCARD_Handler_t *hsd, uint64_t addr)
+{
+	return E_OK;
+}
+
+/*
+ *  SDCARDコンフィギュレーション
+ *  parameter1  hsd: SDMMCハンドラ
+ *  return      ERコード
+ */
+ER
+sdcard_configuration(SDCARD_Handler_t *hsd)
+{
+	ER  ercd = E_OK;
+	uint8_t resp[2];
+	int     i;
+
+	if((ercd = sdcard_lock(hsd)) != E_OK)
+		return ercd;
+	for(i = 0 ; i < INIT_RETRY_COUNT ; i++){
+		if((ercd = sdcard_sendcommand(hsd->hspi, CMD16, sizeof(CMD16))) != E_OK)
+			break;
+		ercd = sdcard_response(hsd->hspi, resp, 1, 2000);
+		if(ercd == E_OK && resp[0] == 0x00)
+			break;
+		dly_tsk(100);
+	}
+	sdcard_unlock(hsd);
+	if(i == INIT_RETRY_COUNT && resp[0] != 0x04)	/* SanDisk */
+		ercd = E_TMOUT;
+	return ercd;
+}
+
+/*
+ *  SDCARDブロックREAD
+ *  parameter1  hsd: SDCARDハンドラ
+ *  parameter2  pbuf: 読み出しデータ格納領域のポインタ(uint32_t型)
+ *  parameter3  ReadAddr: カード上の読み出し位置
+ *  parameter4  blocksize: ブロックサイズ
+ *  parameter5  num: 読み出しブロック数
+ *  return      ERコード
+ */
+ER
+sdcard_blockread(SDCARD_Handler_t *hsd, uint32_t *pbuf, uint64_t ReadAddr, uint32_t blocksize, uint32_t num)
+{
+	ER  ercd = E_OK;
+	static uint8_t cmd17[8];
+	uint8_t resp[2];
+	uint32_t incsec = blocksize;
+	uint16_t crc1, crc2;
+	uint16_t crc3 = 0xffff;
+	int     no, i = 0;
+
+	hsd->read_count++;
+	if(hsd->cardtype == SD_CARD_HC){
+		blocksize = 512;
+		incsec    = 1;
+		ReadAddr /= 512;
+	}
+	for(no = 0 ; no < num ; no++){
+		for(i = 0 ; i < hsd->RetryCount ; i++){
+			if((ercd = sdcard_lock(hsd)) != E_OK){
+				return ercd;
+			}
+
+			cmd17[0] = 0x51;
+			cmd17[1] = (ReadAddr >> 24) & 0xff;
+			cmd17[2] = (ReadAddr >> 16) & 0xff;
+			cmd17[3] = (ReadAddr >> 8) & 0xff;
+			cmd17[4] = ReadAddr & 0xff;
+		    /*
+			 *  CMD17送信
+			 */
+			if((ercd = sdcard_sendcommand(hsd->hspi, cmd17, 5)) == E_OK){
+				if((ercd = sdcard_response(hsd->hspi, resp, 1, 50)) == E_OK && resp[0] == 0x00){
+					ercd = sdcard_receive(hsd->hspi, (uint8_t *)pbuf, blocksize, &crc1, 5000);
+					if(ercd == E_OK){
+						dly_tsk(5);
+						crc2 = calc_CRC16((const uint8_t *)pbuf, blocksize);
+						if(crc1 == crc2){
+							sdcard_unlock(hsd);
+							break;
+						}
+						else if(crc3 == crc2){
+							hsd->read_error++;
+							if(i > 1)
+								syslog_4(LOG_ERROR, "sdcard_blockread crc[%04x][%04x] count(%d) error(%d)  !", crc1, crc2, i, hsd->read_error);
+							sdcard_unlock(hsd);
+							break;
+							dly_tsk(100);
+						}
+						crc3 = crc2;
+					}
+				}
+			}
+			hsd->read_retry_count++;
+			sdcard_unlock(hsd);
+			dly_tsk(10);
+			sdcard_reset(hsd);
+			dly_tsk(10);
+			sdcard_configuration(hsd);
+		}
+		if(i == hsd->RetryCount && ercd == E_OK){
+			ercd = E_TMOUT;
+			break;
+		}
+		ReadAddr += incsec;
+		pbuf += (blocksize/4);
+	}
+	return ercd;
+}
+
+/*
+ *  SDCARDブロックWRITE
+ *  parameter1  hsd: SDCARDハンドラ
+ *  parameter2  pbuf: 書込みデータ格納領域のポインタ(uint32_t型)
+ *  parameter3  WritedAddr: カード上の書き込み位置
+ *  parameter4  blocksize: ブロックサイズ
+ *  parameter5  num: 書込みブロック数
+ *  return      ERコード
+ */
+ER
+sdcard_blockwrite(SDCARD_Handler_t *hsd, uint32_t *pbuf, uint64_t WriteAddr, uint32_t blocksize, uint32_t num)
+{
+	ER  ercd = E_OK;
+	static uint8_t cmd24[8];
+	uint8_t resp[2];
+	uint32_t incsec = blocksize;
+	int     no, i = 0;
+
+	hsd->write_count++;
+	if(hsd->cardtype == SD_CARD_HC){
+		blocksize  = 512;
+		incsec     = 1;
+		WriteAddr /= 512;
+	}
+	for(no = 0 ; no < num ; no++){
+		for(i = 0 ; i < hsd->RetryCount ; i++){
+			if((ercd = sdcard_lock(hsd)) != E_OK){
+				return ercd;
+			}
+
+			cmd24[0] = 0x58;
+			cmd24[1] = (WriteAddr >> 24) & 0xff;
+			cmd24[2] = (WriteAddr >> 16) & 0xff;
+			cmd24[3] = (WriteAddr >> 8) & 0xff;
+			cmd24[4] = WriteAddr & 0xff;
+		    /*
+			 *  CMD24送信
+			 */
+			if((ercd = sdcard_sendcommand(hsd->hspi, cmd24, 5)) == E_OK){
+				if((ercd = sdcard_response(hsd->hspi, resp, 1, 50)) == E_OK && resp[0] == 0x00){
+					ercd = sdcard_send(hsd->hspi, (uint8_t *)pbuf, blocksize);
+					if(ercd == E_OK){
+						sdcard_unlock(hsd);
+						break;
+					}
+				}
+			}
+			hsd->read_retry_count++;
+			sdcard_unlock(hsd);
+			dly_tsk(10);
+			sdcard_reset(hsd);
+			dly_tsk(10);
+			sdcard_configuration(hsd);
+		}
+		if(i == hsd->RetryCount && ercd == E_OK){
+			ercd = E_TMOUT;
+			break;
+		}
+		WriteAddr += incsec;
+		pbuf += (blocksize/4);
+	}
+	return ercd;
+}
+
+/*
+ *  SDCARDブロック転送終了待ち
+ *  parameter1  hsd: SDCARDハンドラ
+ *  parameter2  Timeout: タイムアウト値(1msec)
+ *  return      ERコード
+ */
+ER
+sdcard_wait_transfar(SDCARD_Handler_t *hsd, uint32_t Timeout)
+{
+	return E_OK;
+}
+
+/*
+ *  SDカードダミー処理
+ *  parameter1  hsd: SDCARDハンドラ
+ *  return      ERコード
+ */
+ER
+sdcard_dummy(SDCARD_Handler_t *hsd)
+{
+	return E_OK;
+}
+
+
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/spi_driver/spi_driver.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/spi_driver/spi_driver.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/spi_driver/spi_driver.h	(revision 457)
@@ -0,0 +1,162 @@
+/*
+ *  TOPPERS/ASP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Advanced Standard Profile Kernel
+ *
+ *  Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
+ *                              Toyohashi Univ. of Technology, JAPAN
+ *  Copyright (C) 2004-2010 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ *  Copyright (C) 2015-2016 by TOPPERS PROJECT Educational Working Group.
+ *
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ *
+ *  $Id$
+ */
+
+/*
+ *	SPIドライバのヘッダファイル
+ */
+
+#ifndef _SPI_DRIVER_H_
+#define _SPI_DRIVER_H_
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+#include "device.h"
+#include "spi.h"
+#include "pinmode.h"
+
+/*
+ *  SDカード種別定義
+ */
+#define SD_CARD_V11         0
+#define SD_CARD_V20         1
+#define SD_CARD_HC          2
+#define MMC_CARD			3
+#define SD_IO_CARD          4
+#define HS_MM_CARD          5
+#define SD_IO_COMBO_CARD    6
+#define MMC_CARD_HC         7
+
+#define PORT_HIGH           1
+#define PORT_LOW            0
+
+#define SDMODE_PROTECT      (1<<5)
+#define BUFFERSIZE          140
+
+
+#ifndef TOPPERS_MACRO_ONLY
+
+#ifndef SPI_DRIVER_NOSTART
+/*
+ *  SPI SETUP構造体定義
+ */
+typedef struct {
+	int                     port;
+	uint32_t                baud;
+	ID                      spi_sem;
+	uint8_t                 cs_pin;
+	uint8_t                 rs_pin;
+	uint8_t                 rst_pin;
+	uint8_t                 cs2_pin;
+	uint32_t                otype;
+	uint32_t                pullmode;
+} SPI_Setup_t;
+#endif	/* SPI_DRIVER_NOSTART */
+
+/*
+ *  SDCARDハンドラ構造体定義
+ */
+typedef struct {
+	SPI_Handle_t            *hspi;		/* spiハンドラ */
+	uint32_t                RetryCount;	/* リトライ回数 */
+	uint32_t                cardtype;	/* カードタイプ */
+	uint32_t                RCA;		/* RCA値 */
+	uint8_t                 CSD[16];	/* CSD値 */
+	uint8_t                 CID[16];	/* CID値 */
+	ID                      spi_lock;
+	uint32_t                cs2_port;	/* csポート */
+	volatile uint32_t       status;		/* 転送状態 */
+	uint32_t                read_count;
+	uint32_t                write_count;
+	uint32_t                read_retry_count;
+	uint32_t                write_retry_count;
+	uint32_t                read_error;
+	uint32_t                write_error;
+}SDCARD_Handler_t;
+
+/*
+ *  SDCARD情報構造体
+ */
+typedef struct {
+	uint64_t                capacity;	/* 容量(バイト) */
+	uint32_t                blocksize;	/* ブロックサイズ */
+	uint32_t                maxsector;	/* 最大セクタ数 */
+	uint16_t                RCA;		/* SD RCA */
+	uint8_t                 cardtype;	/* カード種類 */
+	uint8_t                 status;		/* ステータス */
+}SDCARD_CardInfo_t;
+
+
+/*
+ *  関数のプロトタイプ宣言
+ */
+
+#ifndef SPI_DRIVER_NOSTART
+extern SPI_Handle_t *spi_start(SPI_Setup_t *psps);
+extern void spi_end(SPI_Handle_t *hspi);
+#endif
+
+extern void sdcard_setspi(ID portid, SPI_Handle_t *hspi);
+extern void sdcard_setspi2(ID portid, SPI_Handle_t *hspi, uint8_t cs_port);
+extern bool_t sdcard_init(ID portid);
+extern SDCARD_Handler_t *sdcard_open(int id);
+extern ER sdcard_close(SDCARD_Handler_t *hsd);
+extern ER sdcard_getcardinfo(SDCARD_Handler_t *hsd, SDCARD_CardInfo_t *pCardInfo);
+extern ER sdcard_checkCID(SDCARD_Handler_t *hsd);
+extern ER sdcard_sendCSD(SDCARD_Handler_t *hsd);
+extern ER sdcard_select_card(SDCARD_Handler_t *hsd, uint64_t addr);
+extern ER sdcard_configuration(SDCARD_Handler_t *hsd);
+extern ER sdcard_blockread(SDCARD_Handler_t *hsd, uint32_t *pbuf, uint64_t ReadAddr, uint32_t blocksize, uint32_t num);
+extern ER sdcard_blockwrite(SDCARD_Handler_t *hsd, uint32_t *pbuf, uint64_t WriteAddr, uint32_t blocksize, uint32_t num);
+extern ER sdcard_wait_transfar(SDCARD_Handler_t *hsd, uint32_t Timeout);
+extern ER sdcard_dummy(SDCARD_Handler_t *hsd);
+
+#endif /* TOPPERS_MACRO_ONLY */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif	/* _SPI_DRIVER_H_ */
+
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/staudio_wm8994/Makefile.config
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/staudio_wm8994/Makefile.config	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/staudio_wm8994/Makefile.config	(revision 457)
@@ -0,0 +1,55 @@
+#
+#   TOPPERS/ASP/FMP Kernel
+#       Toyohashi Open Platform for Embedded Real-Time Systems/
+#       Advanced Standard Profile Kernel
+#
+#   Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
+#                               Toyohashi Univ. of Technology, JAPAN
+#   Copyright (C) 2003-2008 by Ryosuke Takeuchi
+#                Platform Development Center RICOH COMPANY,LTD. JAPAN
+#   Copyright (C) 2015-2018 by TOPPERS PROJECT Educational Working Group.
+#
+#   上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+#   によって公表されている GNU General Public License の Version 2 に記
+#   述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+#   を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+#   利用と呼ぶ）することを無償で許諾する．
+#   (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+#       権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+#       スコード中に含まれていること．
+#   (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+#       用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+#       者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+#       の無保証規定を掲載すること．
+#   (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+#       用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+#       と．
+#     (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+#         作権表示，この利用条件および下記の無保証規定を掲載すること．
+#     (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+#         報告すること．
+#   (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+#       害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+#
+#   本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+#   よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+#   含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+#   接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+#
+#  @(#) $Id$
+#
+ 
+#
+#  Makefile のプロセッサ依存 (wm8994用)
+#
+
+#
+#  コンパイルオプション
+#
+INCLUDES := $(INCLUDES) -I$(SRCDIR)/gdic/staudio_wm8994
+
+#
+#  USB DEVICE(GDIC)に関する定義
+#
+SYSSVC_DIR := $(SYSSVC_DIR):$(SRCDIR)/gdic/staudio_wm8994
+SYSSVC_COBJS := $(SYSSVC_COBJS) staudio_wm8994.o
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/staudio_wm8994/staudio_wm8994.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/staudio_wm8994/staudio_wm8994.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/staudio_wm8994/staudio_wm8994.c	(revision 457)
@@ -0,0 +1,2471 @@
+/*
+ *  TOPPERS BASE PLATFORM MIDDLEWARE
+ * 
+ *  Copyright (C) 2017-2018 by TOPPERS PROJECT
+ *                             Educational Working Group.
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+/**
+  ******************************************************************************
+  * @attention
+  *
+  * <h2><center>&copy; COPYRIGHT(c) 2016 STMicroelectronics</center></h2>
+  *
+  * 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 STMicroelectronics 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 "staudio_wm8994.h"
+#include <sil.h>
+#include <target_syssvc.h>
+#include <stdlib.h>
+
+/*
+ *  SIL関数のマクロ定義
+ */
+#define sil_orw_mem(a, b)		sil_wrw_mem((a), sil_rew_mem(a) | (b))
+#define sil_andw_mem(a, b)		sil_wrw_mem((a), sil_rew_mem(a) & ~(b))
+#define sil_modw_mem(a, b, c)	sil_wrw_mem((a), (sil_rew_mem(a) & (~b)) | (c))
+
+/* Uncomment this line to enable verifying data sent to codec after each write 
+   operation (for debug purpose) */
+#if !defined (VERIFY_WRITTENDATA)  
+/* #define VERIFY_WRITTENDATA */
+#endif /* VERIFY_WRITTENDATA */
+
+typedef struct
+{
+  uint16_t      *pRecBuf;       /* Pointer to record user buffer */
+  uint32_t      RecSize;        /* Size to record in mono, double size to record in stereo */
+}AUDIOIN_TypeDef;
+
+#define AUDIO_FREQUENCY_192K          ((uint32_t)192000)
+#define AUDIO_FREQUENCY_96K           ((uint32_t)96000)
+#define AUDIO_FREQUENCY_48K           ((uint32_t)48000)
+#define AUDIO_FREQUENCY_44K           ((uint32_t)44100)
+#define AUDIO_FREQUENCY_32K           ((uint32_t)32000)
+#define AUDIO_FREQUENCY_22K           ((uint32_t)22050)
+#define AUDIO_FREQUENCY_16K           ((uint32_t)16000)
+#define AUDIO_FREQUENCY_11K           ((uint32_t)11025)
+#define AUDIO_FREQUENCY_8K            ((uint32_t)8000)  
+
+/*### RECORD ###*/
+#define DFSDM_OVER_SAMPLING(__FREQUENCY__) \
+        (__FREQUENCY__ == AUDIO_FREQUENCY_8K)  ? 256 \
+      : (__FREQUENCY__ == AUDIO_FREQUENCY_11K) ? 256 \
+      : (__FREQUENCY__ == AUDIO_FREQUENCY_16K) ? 128 \
+      : (__FREQUENCY__ == AUDIO_FREQUENCY_22K) ? 128 \
+      : (__FREQUENCY__ == AUDIO_FREQUENCY_32K) ? 64 \
+      : (__FREQUENCY__ == AUDIO_FREQUENCY_44K) ? 64  \
+      : (__FREQUENCY__ == AUDIO_FREQUENCY_48K) ? 40 : 20  \
+
+#define DFSDM_CLOCK_DIVIDER(__FREQUENCY__) \
+        (__FREQUENCY__ == AUDIO_FREQUENCY_8K)  ? 24 \
+      : (__FREQUENCY__ == AUDIO_FREQUENCY_11K) ? 4 \
+      : (__FREQUENCY__ == AUDIO_FREQUENCY_16K) ? 24 \
+      : (__FREQUENCY__ == AUDIO_FREQUENCY_22K) ? 4 \
+      : (__FREQUENCY__ == AUDIO_FREQUENCY_32K) ? 24 \
+      : (__FREQUENCY__ == AUDIO_FREQUENCY_44K) ? 4  \
+      : (__FREQUENCY__ == AUDIO_FREQUENCY_48K) ? 25 : 25  \
+
+#define DFSDM_FILTER_ORDER(__FREQUENCY__) \
+        (__FREQUENCY__ == AUDIO_FREQUENCY_8K)  ? DFSDM_FILTER_SINC3_ORDER \
+      : (__FREQUENCY__ == AUDIO_FREQUENCY_11K) ? DFSDM_FILTER_SINC3_ORDER \
+      : (__FREQUENCY__ == AUDIO_FREQUENCY_16K) ? DFSDM_FILTER_SINC3_ORDER \
+      : (__FREQUENCY__ == AUDIO_FREQUENCY_22K) ? DFSDM_FILTER_SINC3_ORDER \
+      : (__FREQUENCY__ == AUDIO_FREQUENCY_32K) ? DFSDM_FILTER_SINC4_ORDER \
+      : (__FREQUENCY__ == AUDIO_FREQUENCY_44K) ? DFSDM_FILTER_SINC3_ORDER  \
+      : (__FREQUENCY__ == AUDIO_FREQUENCY_48K) ? DFSDM_FILTER_SINC3_ORDER : DFSDM_FILTER_SINC5_ORDER  \
+
+#define DFSDM_RIGHT_BIT_SHIFT(__FREQUENCY__) \
+        (__FREQUENCY__ == AUDIO_FREQUENCY_8K)  ? 8 \
+      : (__FREQUENCY__ == AUDIO_FREQUENCY_11K) ? 8 \
+      : (__FREQUENCY__ == AUDIO_FREQUENCY_16K) ? 3 \
+      : (__FREQUENCY__ == AUDIO_FREQUENCY_22K) ? 4 \
+      : (__FREQUENCY__ == AUDIO_FREQUENCY_32K) ? 7 \
+      : (__FREQUENCY__ == AUDIO_FREQUENCY_44K) ? 0  \
+      : (__FREQUENCY__ == AUDIO_FREQUENCY_48K) ? 0 : 4  \
+
+/* Saturate the record PCM sample */
+#define SaturaLH(N, L, H) (((N)<(L))?(L):(((N)>(H))?(H):(N)))
+
+
+#ifdef TOPPERS_STM32F769_DISCOVERY
+
+#define GPIO_AF3_DFSDM1         ((uint8_t)0x03U)  /* DFSDM1 Alternate Function mapping */
+
+#define AUDIO_DFSDMx_DMIC_DATIN_GPIO_CLK_ENABLE()       sil_orw_mem((uint32_t *)(TADR_RCC_BASE+TOFF_RCC_AHB1ENR), RCC_AHB1ENR_GPIOCEN)
+#define AUDIO_DFSDMx_CKOUT_DMIC_GPIO_CLK_ENABLE()       sil_orw_mem((uint32_t *)(TADR_RCC_BASE+TOFF_RCC_AHB1ENR), RCC_AHB1ENR_GPIODEN)
+
+#define AUDIO_DFSDMx_TOP_RIGHT_CHANNEL                  DFSDM_CHANNEL_0
+#define AUDIO_DFSDMx_TOP_LEFT_CHANNEL                   DFSDM_CHANNEL_1
+#define AUDIO_DFSDMx_BUTTOM_RIGHT_CHANNEL               DFSDM_CHANNEL_4
+#define AUDIO_DFSDMx_BUTTOM_LEFT_CHANNEL                DFSDM_CHANNEL_5
+
+#define AUDIO_DFSDMx_TOP_LEFT_FILTER                    TADR_DFSDM1_FILTER0_BASE
+#define AUDIO_DFSDMx_TOP_RIGHT_FILTER                   TADR_DFSDM1_FILTER1_BASE
+#define AUDIO_DFSDMx_BUTTOM_LEFT_FILTER                 TADR_DFSDM1_FILTER2_BASE
+#define AUDIO_DFSDMx_BUTTOM_RIGHT_FILTER                TADR_DFSDM1_FILTER3_BASE
+
+#define AUDIO_DFSDMx_CKOUT_DMIC_GPIO_PORT               TADR_GPIOD_BASE
+#define AUDIO_DFSDMx_CKOUT_PINNO                        3
+#define AUDIO_DFSDMx_DMIC_DATIN_GPIO_PORT               TADR_GPIOC_BASE
+#define AUDIO_DFSDMx_DMIC_DATIN1_PINNO                  3
+#define AUDIO_DFSDMx_DMIC_DATIN5_PINNO                  11
+#define AUDIO_DFSDMx_DMIC_DATIN_AF                      GPIO_AF3_DFSDM1
+#define AUDIO_DFSDMx_CKOUT_AF                           GPIO_AF3_DFSDM1
+
+#define AUDIO_DFSDMx_DMAx_BUTTOM_LEFT_STREAM            TADR_DMA2_STM6_BASE
+#define AUDIO_DFSDMx_DMAx_BUTTOM_RIGHT_STREAM           TADR_DMA2_STM7_BASE
+
+#define AUDIO_DFSDMx_DMAx_PERIPH_DATA_SIZE              DMA_PDATAALIGN_WORD
+#define AUDIO_DFSDMx_DMAx_MEM_DATA_SIZE                 DMA_MDATAALIGN_WORD
+
+#define AUDIO_DFSDMx_DMAx_CHANNEL                       DMA_CHANNEL_8
+
+
+/* RECORD */
+static STAUDIO_Handle_t     *hstaudio;
+AUDIOIN_TypeDef             hAudioIn;
+
+DFSDM_Channel_Handle_t      hAudioInTopLeftChannel;
+DFSDM_Channel_Handle_t      hAudioInTopRightChannel;
+DFSDM_Filter_Handle_t       hAudioInTopLeftFilter;
+DFSDM_Filter_Handle_t       hAudioInTopRightFilter;
+DMA_Handle_t                hDmaTopLeft;
+DMA_Handle_t                hDmaTopRight;
+
+DFSDM_Channel_Handle_t      hAudioInButtomLeftChannel;
+DFSDM_Channel_Handle_t      hAudioInButtomRightChannel;
+DFSDM_Filter_Handle_t       hAudioInButtomLeftFilter;
+DFSDM_Filter_Handle_t       hAudioInButtomRightFilter;
+DMA_Handle_t                hDmaButtomLeft;
+DMA_Handle_t                hDmaButtomRight;
+
+/* Buffers for right and left samples */
+static int32_t              *pScratchBuff[2*DEFAULT_AUDIO_IN_CHANNEL_NBR];
+static volatile int32_t     ScratchSize;
+/* Cannel number to be used: 2 channels by default */
+static uint8_t              AudioIn_ChannelNumber = DEFAULT_AUDIO_IN_CHANNEL_NBR;
+
+/* Buffers status flags */
+static uint32_t             DmaTopLeftRecHalfCplt  = 0;
+static uint32_t             DmaTopLeftRecCplt      = 0;
+static uint32_t             DmaTopRightRecHalfCplt = 0;
+static uint32_t             DmaTopRightRecCplt     = 0;
+static uint32_t             DmaButtomLeftRecHalfCplt  = 0;
+static uint32_t             DmaButtomLeftRecCplt      = 0;
+static uint32_t             DmaButtomRightRecHalfCplt = 0;
+static uint32_t             DmaButtomRightRecCplt     = 0;
+
+/* Application Buffer Trigger */
+static volatile uint32_t    AppBuffTrigger          = 0;
+static volatile uint32_t    AppBuffHalf             = 0;
+#endif
+
+
+/** @defgroup WM8994_Function_Prototypes
+  * @{
+  */
+static uint32_t wm8994_SetVolume(STAUDIO_Handle_t *haudio, uint8_t Volume);
+static uint32_t wm8994_SetMute(STAUDIO_Handle_t *haudio, uint32_t Cmd);
+
+
+/**
+  * @brief  Writes/Read a single data.
+  * @param  Addr: I2C address
+  * @param  Reg: Reg address 
+  * @param  Value: Data to be written
+  * @retval None
+  */
+static uint8_t
+CODEC_IO_Write(STAUDIO_Handle_t *haudio, uint16_t Reg, uint16_t Value)
+{
+	ER ercd;
+	uint8_t  buffer[4];
+	uint32_t result = 0;
+
+	buffer[0] = (uint8_t)(Value >> 8);
+	buffer[1] = (uint8_t)Value;
+	ercd = i2c_memwrite(haudio->hi2c, haudio->i2caddress, (uint16_t)Reg, I2C_MEMADD_SIZE_16BIT, buffer, 2, 1000);
+
+	/* Check the communication status */
+	if(ercd != E_OK){
+#if 1	/* ROI DEBUG */
+		syslog_2(LOG_NOTICE, "## I2Cx_Error(%08x, %02x) ##", haudio->hi2c, haudio->i2caddress);
+#endif	/* ROI DEBUG */
+		/* De-initialize the I2C communication bus */
+		i2c_deinit(haudio->hi2c);
+
+		/* Re-Initialize the I2C communication bus */
+		i2c_init(haudio->hi2c->i2cid, &haudio->hi2c->Init);
+	}
+
+#ifdef VERIFY_WRITTENDATA
+	{
+		uint16_t  value;
+		ercd = i2c_memread(haudio->hi2c, haudio->i2caddress, (uint16_t)Reg, I2C_MEMADD_SIZE_16BIT, buffer, 2, 1000);
+		value = (buffer[0] << 8) | buffer[1];
+		/* Verify that the data has been correctly written */
+		result = (value == Value)? 0:1;
+	}
+#endif /* VERIFY_WRITTENDATA */
+	return result;
+}
+
+/**
+  * @brief Initializes the audio codec and the control interface.
+  * @param DeviceAddr: Device address on communication Bus.   
+  * @param OutputInputDevice: can be OUTPUT_DEVICE_SPEAKER, OUTPUT_DEVICE_HEADPHONE,
+  *  OUTPUT_DEVICE_BOTH, OUTPUT_DEVICE_AUTO, INPUT_DEVICE_DIGITAL_MICROPHONE_1,
+  *  INPUT_DEVICE_DIGITAL_MICROPHONE_2, INPUT_DEVICE_DIGITAL_MIC1_MIC2, 
+  *  INPUT_DEVICE_INPUT_LINE_1 or INPUT_DEVICE_INPUT_LINE_2.
+  * @param Volume: Initial volume level (from 0 (Mute) to 100 (Max))
+  * @param AudioFreq: Audio Frequency 
+  * @retval 0 if correct communication, else wrong communication
+  */
+static uint32_t
+wm8994_Init(STAUDIO_Handle_t *haudio, uint16_t OutputInputDevice, uint8_t Volume, uint32_t AudioFreq)
+{
+	uint32_t counter = 0;
+	uint16_t output_device = OutputInputDevice & 0xFF;
+	uint16_t input_device = OutputInputDevice & 0xFF00;
+	uint16_t power_mgnt_reg_1 = 0;
+
+	/* wm8994 Errata Work-Arounds */
+	counter += CODEC_IO_Write(haudio, 0x102, 0x0003);
+	counter += CODEC_IO_Write(haudio, 0x817, 0x0000);
+	counter += CODEC_IO_Write(haudio, 0x102, 0x0000);
+
+	/* Enable VMID soft start (fast), Start-up Bias Current Enabled */
+	counter += CODEC_IO_Write(haudio, 0x39, 0x006C);
+
+	/* Enable bias generator, Enable VMID */
+	if(input_device > 0){
+		counter += CODEC_IO_Write(haudio, 0x01, 0x0013);
+	}
+	else{
+		counter += CODEC_IO_Write(haudio, 0x01, 0x0003);
+	}
+
+	/* Add Delay */
+	dly_tsk(50);
+
+	/* Path Configurations for output */
+	if(output_device > 0){
+		haudio->outputEnabled = 1;
+
+		switch(output_device){
+		case OUTPUT_DEVICE_SPEAKER:
+			/* Enable DAC1 (Left), Enable DAC1 (Right),
+			   Disable DAC2 (Left), Disable DAC2 (Right)*/
+			counter += CODEC_IO_Write(haudio, 0x05, 0x0C0C);
+
+			/* Enable the AIF1 Timeslot 0 (Left) to DAC 1 (Left) mixer path */
+			counter += CODEC_IO_Write(haudio, 0x601, 0x0000);
+
+			/* Enable the AIF1 Timeslot 0 (Right) to DAC 1 (Right) mixer path */
+			counter += CODEC_IO_Write(haudio, 0x602, 0x0000);
+
+			/* Disable the AIF1 Timeslot 1 (Left) to DAC 2 (Left) mixer path */
+			counter += CODEC_IO_Write(haudio, 0x604, 0x0002);
+
+			/* Disable the AIF1 Timeslot 1 (Right) to DAC 2 (Right) mixer path */
+			counter += CODEC_IO_Write(haudio, 0x605, 0x0002);
+			break;
+
+		case OUTPUT_DEVICE_HEADPHONE:
+			/* Disable DAC1 (Left), Disable DAC1 (Right),
+			   Enable DAC2 (Left), Enable DAC2 (Right)*/
+			counter += CODEC_IO_Write(haudio, 0x05, 0x0303);
+
+			/* Enable the AIF1 Timeslot 0 (Left) to DAC 1 (Left) mixer path */
+			counter += CODEC_IO_Write(haudio, 0x601, 0x0001);
+
+			/* Enable the AIF1 Timeslot 0 (Right) to DAC 1 (Right) mixer path */
+			counter += CODEC_IO_Write(haudio, 0x602, 0x0001);
+
+			/* Disable the AIF1 Timeslot 1 (Left) to DAC 2 (Left) mixer path */
+			counter += CODEC_IO_Write(haudio, 0x604, 0x0000);
+
+			/* Disable the AIF1 Timeslot 1 (Right) to DAC 2 (Right) mixer path */
+			counter += CODEC_IO_Write(haudio, 0x605, 0x0000);
+			break;
+
+		case OUTPUT_DEVICE_BOTH:
+			if(input_device == INPUT_DEVICE_DIGITAL_MIC1_MIC2){
+				/* Enable DAC1 (Left), Enable DAC1 (Right),
+				   also Enable DAC2 (Left), Enable DAC2 (Right)*/
+				counter += CODEC_IO_Write(haudio, 0x05, 0x0303 | 0x0C0C);
+
+				/* Enable the AIF1 Timeslot 0 (Left) to DAC 1 (Left) mixer path
+				  Enable the AIF1 Timeslot 1 (Left) to DAC 1 (Left) mixer path */
+				counter += CODEC_IO_Write(haudio, 0x601, 0x0003);
+
+				/* Enable the AIF1 Timeslot 0 (Right) to DAC 1 (Right) mixer path
+				   Enable the AIF1 Timeslot 1 (Right) to DAC 1 (Right) mixer path */
+				counter += CODEC_IO_Write(haudio, 0x602, 0x0003);
+
+				/* Enable the AIF1 Timeslot 0 (Left) to DAC 2 (Left) mixer path
+				   Enable the AIF1 Timeslot 1 (Left) to DAC 2 (Left) mixer path  */
+				counter += CODEC_IO_Write(haudio, 0x604, 0x0003);
+
+				/* Enable the AIF1 Timeslot 0 (Right) to DAC 2 (Right) mixer path
+				   Enable the AIF1 Timeslot 1 (Right) to DAC 2 (Right) mixer path */
+				counter += CODEC_IO_Write(haudio, 0x605, 0x0003);
+			}
+			else{
+				/* Enable DAC1 (Left), Enable DAC1 (Right),
+				   also Enable DAC2 (Left), Enable DAC2 (Right)*/
+				counter += CODEC_IO_Write(haudio, 0x05, 0x0303 | 0x0C0C);
+
+				/* Enable the AIF1 Timeslot 0 (Left) to DAC 1 (Left) mixer path */
+				counter += CODEC_IO_Write(haudio, 0x601, 0x0001);
+
+				/* Enable the AIF1 Timeslot 0 (Right) to DAC 1 (Right) mixer path */
+				counter += CODEC_IO_Write(haudio, 0x602, 0x0001);
+
+				/* Enable the AIF1 Timeslot 1 (Left) to DAC 2 (Left) mixer path */
+				counter += CODEC_IO_Write(haudio, 0x604, 0x0002);
+
+				/* Enable the AIF1 Timeslot 1 (Right) to DAC 2 (Right) mixer path */
+				counter += CODEC_IO_Write(haudio, 0x605, 0x0002);      
+			}
+			break;
+
+		case OUTPUT_DEVICE_AUTO :
+		default:
+			/* Disable DAC1 (Left), Disable DAC1 (Right),
+			   Enable DAC2 (Left), Enable DAC2 (Right)*/
+			counter += CODEC_IO_Write(haudio, 0x05, 0x0303);
+
+			/* Enable the AIF1 Timeslot 0 (Left) to DAC 1 (Left) mixer path */
+			counter += CODEC_IO_Write(haudio, 0x601, 0x0001);
+
+			/* Enable the AIF1 Timeslot 0 (Right) to DAC 1 (Right) mixer path */
+			counter += CODEC_IO_Write(haudio, 0x602, 0x0001);
+
+			/* Disable the AIF1 Timeslot 1 (Left) to DAC 2 (Left) mixer path */
+			counter += CODEC_IO_Write(haudio, 0x604, 0x0000);
+
+			/* Disable the AIF1 Timeslot 1 (Right) to DAC 2 (Right) mixer path */
+			counter += CODEC_IO_Write(haudio, 0x605, 0x0000);
+			break;
+		}
+	}
+	else{
+		haudio->outputEnabled = 0;
+	}
+
+	/* Path Configurations for input */
+	if(input_device > 0){
+		haudio->inputEnabled = 1;
+		switch(input_device){
+		case INPUT_DEVICE_DIGITAL_MICROPHONE_2 :
+			/* Enable AIF1ADC2 (Left), Enable AIF1ADC2 (Right)
+			 * Enable DMICDAT2 (Left), Enable DMICDAT2 (Right)
+			 * Enable Left ADC, Enable Right ADC */
+			counter += CODEC_IO_Write(haudio, 0x04, 0x0C30);
+
+			/* Enable AIF1 DRC2 Signal Detect & DRC in AIF1ADC2 Left/Right Timeslot 1 */
+			counter += CODEC_IO_Write(haudio, 0x450, 0x00DB);
+
+			/* Disable IN1L, IN1R, IN2L, IN2R, Enable Thermal sensor & shutdown */
+			counter += CODEC_IO_Write(haudio, 0x02, 0x6000);
+
+			/* Enable the DMIC2(Left) to AIF1 Timeslot 1 (Left) mixer path */
+			counter += CODEC_IO_Write(haudio, 0x608, 0x0002);
+
+			/* Enable the DMIC2(Right) to AIF1 Timeslot 1 (Right) mixer path */
+			counter += CODEC_IO_Write(haudio, 0x609, 0x0002);
+
+			/* GPIO1 pin configuration GP1_DIR = output, GP1_FN = AIF1 DRC2 signal detect */
+			counter += CODEC_IO_Write(haudio, 0x700, 0x000E);
+			break;
+
+		case INPUT_DEVICE_INPUT_LINE_1 :
+			/* IN1LN_TO_IN1L, IN1LP_TO_VMID, IN1RN_TO_IN1R, IN1RP_TO_VMID */
+			counter += CODEC_IO_Write(haudio, 0x28, 0x0011);
+
+			/* Disable mute on IN1L_TO_MIXINL and +30dB on IN1L PGA output */
+			counter += CODEC_IO_Write(haudio, 0x29, 0x0035);
+
+			/* Disable mute on IN1R_TO_MIXINL, Gain = +30dB */
+			counter += CODEC_IO_Write(haudio, 0x2A, 0x0035);
+
+			/* Enable AIF1ADC1 (Left), Enable AIF1ADC1 (Right)
+			 * Enable Left ADC, Enable Right ADC */
+			counter += CODEC_IO_Write(haudio, 0x04, 0x0303);
+
+			/* Enable AIF1 DRC1 Signal Detect & DRC in AIF1ADC1 Left/Right Timeslot 0 */
+			counter += CODEC_IO_Write(haudio, 0x440, 0x00DB);
+
+			/* Enable IN1L and IN1R, Disable IN2L and IN2R, Enable Thermal sensor & shutdown */
+			counter += CODEC_IO_Write(haudio, 0x02, 0x6350);
+
+			/* Enable the ADCL(Left) to AIF1 Timeslot 0 (Left) mixer path */
+			counter += CODEC_IO_Write(haudio, 0x606, 0x0002);
+
+			/* Enable the ADCR(Right) to AIF1 Timeslot 0 (Right) mixer path */
+			counter += CODEC_IO_Write(haudio, 0x607, 0x0002);
+
+			/* GPIO1 pin configuration GP1_DIR = output, GP1_FN = AIF1 DRC1 signal detect */
+			counter += CODEC_IO_Write(haudio, 0x700, 0x000D);
+			break;
+
+		case INPUT_DEVICE_DIGITAL_MICROPHONE_1 :
+			/* Enable AIF1ADC1 (Left), Enable AIF1ADC1 (Right)
+			 * Enable DMICDAT1 (Left), Enable DMICDAT1 (Right)
+			 * Enable Left ADC, Enable Right ADC */
+			counter += CODEC_IO_Write(haudio, 0x04, 0x030C);
+
+			/* Enable AIF1 DRC2 Signal Detect & DRC in AIF1ADC1 Left/Right Timeslot 0 */
+			counter += CODEC_IO_Write(haudio, 0x440, 0x00DB);
+
+			/* Disable IN1L, IN1R, IN2L, IN2R, Enable Thermal sensor & shutdown */
+			counter += CODEC_IO_Write(haudio, 0x02, 0x6350);
+
+			/* Enable the DMIC2(Left) to AIF1 Timeslot 0 (Left) mixer path */
+			counter += CODEC_IO_Write(haudio, 0x606, 0x0002);
+
+			/* Enable the DMIC2(Right) to AIF1 Timeslot 0 (Right) mixer path */
+			counter += CODEC_IO_Write(haudio, 0x607, 0x0002);
+
+			/* GPIO1 pin configuration GP1_DIR = output, GP1_FN = AIF1 DRC1 signal detect */
+			counter += CODEC_IO_Write(haudio, 0x700, 0x000D);
+			break;
+		case INPUT_DEVICE_DIGITAL_MIC1_MIC2 :
+			/* Enable AIF1ADC1 (Left), Enable AIF1ADC1 (Right)
+			 * Enable DMICDAT1 (Left), Enable DMICDAT1 (Right)
+			 * Enable Left ADC, Enable Right ADC */
+			counter += CODEC_IO_Write(haudio, 0x04, 0x0F3C);
+
+			/* Enable AIF1 DRC2 Signal Detect & DRC in AIF1ADC2 Left/Right Timeslot 1 */
+			counter += CODEC_IO_Write(haudio, 0x450, 0x00DB);
+
+			/* Enable AIF1 DRC2 Signal Detect & DRC in AIF1ADC1 Left/Right Timeslot 0 */
+			counter += CODEC_IO_Write(haudio, 0x440, 0x00DB);
+
+			/* Disable IN1L, IN1R, Enable IN2L, IN2R, Thermal sensor & shutdown */
+			counter += CODEC_IO_Write(haudio, 0x02, 0x63A0);
+
+			/* Enable the DMIC2(Left) to AIF1 Timeslot 0 (Left) mixer path */
+			counter += CODEC_IO_Write(haudio, 0x606, 0x0002);
+
+			/* Enable the DMIC2(Right) to AIF1 Timeslot 0 (Right) mixer path */
+			counter += CODEC_IO_Write(haudio, 0x607, 0x0002);
+
+			/* Enable the DMIC2(Left) to AIF1 Timeslot 1 (Left) mixer path */
+			counter += CODEC_IO_Write(haudio, 0x608, 0x0002);
+
+			/* Enable the DMIC2(Right) to AIF1 Timeslot 1 (Right) mixer path */
+			counter += CODEC_IO_Write(haudio, 0x609, 0x0002);
+
+			/* GPIO1 pin configuration GP1_DIR = output, GP1_FN = AIF1 DRC1 signal detect */
+			counter += CODEC_IO_Write(haudio, 0x700, 0x000D);
+			break;
+		case INPUT_DEVICE_INPUT_LINE_2 :
+		default:
+			/* Actually, no other input devices supported */
+			counter++;
+			break;
+		}
+	}
+	else{
+		haudio->inputEnabled = 0;
+	}
+
+	/*  Clock Configurations */
+	switch (AudioFreq){
+	case  AUDIO_FREQUENCY_8K:
+		/* AIF1 Sample Rate = 8 (KHz), ratio=256 */ 
+		counter += CODEC_IO_Write(haudio, 0x210, 0x0003);
+		break;
+
+	case  AUDIO_FREQUENCY_16K:
+		/* AIF1 Sample Rate = 16 (KHz), ratio=256 */ 
+		counter += CODEC_IO_Write(haudio, 0x210, 0x0033);
+		break;
+
+	case  AUDIO_FREQUENCY_32K:
+		/* AIF1 Sample Rate = 32 (KHz), ratio=256 */ 
+		counter += CODEC_IO_Write(haudio, 0x210, 0x0063);
+		break;
+
+	case  AUDIO_FREQUENCY_48K:
+		/* AIF1 Sample Rate = 48 (KHz), ratio=256 */ 
+		counter += CODEC_IO_Write(haudio, 0x210, 0x0083);
+		break;
+
+	case  AUDIO_FREQUENCY_96K:
+		/* AIF1 Sample Rate = 96 (KHz), ratio=256 */ 
+		counter += CODEC_IO_Write(haudio, 0x210, 0x00A3);
+		break;
+
+	case  AUDIO_FREQUENCY_11K:
+		/* AIF1 Sample Rate = 11.025 (KHz), ratio=256 */ 
+		counter += CODEC_IO_Write(haudio, 0x210, 0x0013);
+		break;
+
+	case  AUDIO_FREQUENCY_22K:
+		/* AIF1 Sample Rate = 22.050 (KHz), ratio=256 */ 
+		counter += CODEC_IO_Write(haudio, 0x210, 0x0043);
+		break;
+
+	case  AUDIO_FREQUENCY_44K:
+		/* AIF1 Sample Rate = 44.1 (KHz), ratio=256 */ 
+		counter += CODEC_IO_Write(haudio, 0x210, 0x0073);
+		break;
+
+	default:
+		/* AIF1 Sample Rate = 48 (KHz), ratio=256 */ 
+		counter += CODEC_IO_Write(haudio, 0x210, 0x0083);
+		break;
+	}
+
+	if(input_device == INPUT_DEVICE_DIGITAL_MIC1_MIC2){
+		/* AIF1 Word Length = 16-bits, AIF1 Format = DSP mode */
+		counter += CODEC_IO_Write(haudio, 0x300, 0x4018);    
+	}
+	else{
+		/* AIF1 Word Length = 16-bits, AIF1 Format = I2S (Default Register Value) */
+		counter += CODEC_IO_Write(haudio, 0x300, 0x4010);
+	}
+
+	/* slave mode */
+	counter += CODEC_IO_Write(haudio, 0x302, 0x0000);
+
+	/* Enable the DSP processing clock for AIF1, Enable the core clock */
+	counter += CODEC_IO_Write(haudio, 0x208, 0x000A);
+
+	/* Enable AIF1 Clock, AIF1 Clock Source = MCLK1 pin */
+	counter += CODEC_IO_Write(haudio, 0x200, 0x0001);
+
+	if(output_device > 0){	/* Audio output selected */
+		if(output_device == OUTPUT_DEVICE_HEADPHONE){
+			/* Select DAC1 (Left) to Left Headphone Output PGA (HPOUT1LVOL) path */
+			counter += CODEC_IO_Write(haudio, 0x2D, 0x0100);
+
+			/* Select DAC1 (Right) to Right Headphone Output PGA (HPOUT1RVOL) path */
+			counter += CODEC_IO_Write(haudio, 0x2E, 0x0100);    
+
+			/* Startup sequence for Headphone */
+			if(haudio->ColdStartup){
+				counter += CODEC_IO_Write(haudio,0x110,0x8100);
+
+				haudio->ColdStartup = 0;
+				/* Add Delay */
+				dly_tsk(300);
+			}
+			else{	/* Headphone Warm Start-Up */
+				counter += CODEC_IO_Write(haudio,0x110,0x8108);
+				/* Add Delay */
+				dly_tsk(50);
+			}
+
+			/* Soft un-Mute the AIF1 Timeslot 0 DAC1 path L&R */
+			counter += CODEC_IO_Write(haudio, 0x420, 0x0000);
+		}
+		/* Analog Output Configuration */
+
+		/* Enable SPKRVOL PGA, Enable SPKMIXR, Enable SPKLVOL PGA, Enable SPKMIXL */
+		counter += CODEC_IO_Write(haudio, 0x03, 0x0300);
+
+		/* Left Speaker Mixer Volume = 0dB */
+		counter += CODEC_IO_Write(haudio, 0x22, 0x0000);
+
+		/* Speaker output mode = Class D, Right Speaker Mixer Volume = 0dB ((0x23, 0x0100) = class AB)*/
+		counter += CODEC_IO_Write(haudio, 0x23, 0x0000);
+
+		/* Unmute DAC2 (Left) to Left Speaker Mixer (SPKMIXL) path,
+		   Unmute DAC2 (Right) to Right Speaker Mixer (SPKMIXR) path */
+		counter += CODEC_IO_Write(haudio, 0x36, 0x0300);
+
+		/* Enable bias generator, Enable VMID, Enable SPKOUTL, Enable SPKOUTR */
+		counter += CODEC_IO_Write(haudio, 0x01, 0x3003);
+
+		/* Headphone/Speaker Enable */
+		if(input_device == INPUT_DEVICE_DIGITAL_MIC1_MIC2){
+			/* Enable Class W, Class W Envelope Tracking = AIF1 Timeslots 0 and 1 */
+			counter += CODEC_IO_Write(haudio, 0x51, 0x0205);
+		}
+		else{
+			/* Enable Class W, Class W Envelope Tracking = AIF1 Timeslot 0 */
+			counter += CODEC_IO_Write(haudio, 0x51, 0x0005);      
+		}
+
+		/* Enable bias generator, Enable VMID, Enable HPOUT1 (Left) and Enable HPOUT1 (Right) input stages */
+		/* idem for Speaker */
+		power_mgnt_reg_1 |= 0x0303 | 0x3003;
+		counter += CODEC_IO_Write(haudio, 0x01, power_mgnt_reg_1);
+
+		/* Enable HPOUT1 (Left) and HPOUT1 (Right) intermediate stages */
+		counter += CODEC_IO_Write(haudio, 0x60, 0x0022);
+
+		/* Enable Charge Pump */
+		counter += CODEC_IO_Write(haudio, 0x4C, 0x9F25);
+
+		/* Add Delay */
+		dly_tsk(15);
+
+		/* Select DAC1 (Left) to Left Headphone Output PGA (HPOUT1LVOL) path */
+		counter += CODEC_IO_Write(haudio, 0x2D, 0x0001);
+
+		/* Select DAC1 (Right) to Right Headphone Output PGA (HPOUT1RVOL) path */
+		counter += CODEC_IO_Write(haudio, 0x2E, 0x0001);
+
+		/* Enable Left Output Mixer (MIXOUTL), Enable Right Output Mixer (MIXOUTR) */
+		/* idem for SPKOUTL and SPKOUTR */
+		counter += CODEC_IO_Write(haudio, 0x03, 0x0030 | 0x0300);
+
+		/* Enable DC Servo and trigger start-up mode on left and right channels */
+		counter += CODEC_IO_Write(haudio, 0x54, 0x0033);
+
+		/* Add Delay */
+		dly_tsk(257);
+
+		/* Enable HPOUT1 (Left) and HPOUT1 (Right) intermediate and output stages. Remove clamps */
+		counter += CODEC_IO_Write(haudio, 0x60, 0x00EE);
+
+		/* Unmutes */
+
+		/* Unmute DAC 1 (Left) */
+		counter += CODEC_IO_Write(haudio, 0x610, 0x00C0);
+
+		/* Unmute DAC 1 (Right) */
+		counter += CODEC_IO_Write(haudio, 0x611, 0x00C0);
+
+		/* Unmute the AIF1 Timeslot 0 DAC path */
+		counter += CODEC_IO_Write(haudio, 0x420, 0x0010);
+
+		/* Unmute DAC 2 (Left) */
+		counter += CODEC_IO_Write(haudio, 0x612, 0x00C0);
+
+		/* Unmute DAC 2 (Right) */
+		counter += CODEC_IO_Write(haudio, 0x613, 0x00C0);
+
+		/* Unmute the AIF1 Timeslot 1 DAC2 path */
+		counter += CODEC_IO_Write(haudio, 0x422, 0x0010);
+
+		/* Volume Control */
+		wm8994_SetVolume(haudio, Volume);
+	}
+
+	if(input_device > 0){	/* Audio input selected */
+		if((input_device == INPUT_DEVICE_DIGITAL_MICROPHONE_1) || (input_device == INPUT_DEVICE_DIGITAL_MICROPHONE_2)){
+			/* Enable Microphone bias 1 generator, Enable VMID */
+			power_mgnt_reg_1 |= 0x0013;
+			counter += CODEC_IO_Write(haudio, 0x01, power_mgnt_reg_1);
+
+			/* ADC oversample enable */
+			counter += CODEC_IO_Write(haudio, 0x620, 0x0002);
+
+			/* AIF ADC2 HPF enable, HPF cut = voice mode 1 fc=127Hz at fs=8kHz */
+			counter += CODEC_IO_Write(haudio, 0x411, 0x3800);
+		}
+		else if(input_device == INPUT_DEVICE_DIGITAL_MIC1_MIC2){
+			/* Enable Microphone bias 1 generator, Enable VMID */
+			power_mgnt_reg_1 |= 0x0013;
+			counter += CODEC_IO_Write(haudio, 0x01, power_mgnt_reg_1);
+
+			/* ADC oversample enable */
+			counter += CODEC_IO_Write(haudio, 0x620, 0x0002);
+
+			/* AIF ADC1 HPF enable, HPF cut = voice mode 1 fc=127Hz at fs=8kHz */
+			counter += CODEC_IO_Write(haudio, 0x410, 0x1800);
+
+			/* AIF ADC2 HPF enable, HPF cut = voice mode 1 fc=127Hz at fs=8kHz */
+			counter += CODEC_IO_Write(haudio, 0x411, 0x1800);      
+		}
+		else if((input_device == INPUT_DEVICE_INPUT_LINE_1) || (input_device == INPUT_DEVICE_INPUT_LINE_2)){
+			/* Disable mute on IN1L, IN1L Volume = +0dB */
+			counter += CODEC_IO_Write(haudio, 0x18, 0x000B);
+
+			/* Disable mute on IN1R, IN1R Volume = +0dB */
+			counter += CODEC_IO_Write(haudio, 0x1A, 0x000B);
+
+			/* AIF ADC1 HPF enable, HPF cut = hifi mode fc=4Hz at fs=48kHz */
+			counter += CODEC_IO_Write(haudio, 0x410, 0x1800);
+		}
+		/* Volume Control */
+		wm8994_SetVolume(haudio, Volume);
+	}
+	/* Return communication control value */
+	return counter;
+}
+
+/**
+  * @brief Pauses playing on the audio codec.
+  * @param DeviceAddr: Device address on communication Bus. 
+  * @retval 0 if correct communication, else wrong communication
+  */
+static uint32_t
+wm8994_Pause(STAUDIO_Handle_t *haudio)
+{
+	uint32_t counter = 0;
+
+	/* Pause the audio file playing */
+	/* Mute the output first */
+	counter += wm8994_SetMute(haudio, AUDIO_MUTE_ON);
+
+	/* Put the Codec in Power save mode */
+	counter += CODEC_IO_Write(haudio, 0x02, 0x01);
+	return counter;
+}
+
+/**
+  * @brief Stops audio Codec playing. It powers down the codec.
+  * @param DeviceAddr: Device address on communication Bus. 
+  * @param CodecPdwnMode: selects the  power down mode.
+  *          - CODEC_PDWN_SW: only mutes the audio codec. When resuming from this 
+  *                           mode the codec keeps the previous initialization
+  *                           (no need to re-Initialize the codec registers).
+  *          - CODEC_PDWN_HW: Physically power down the codec. When resuming from this
+  *                           mode, the codec is set to default configuration 
+  *                           (user should re-Initialize the codec in order to 
+  *                            play again the audio stream).
+  * @retval 0 if correct communication, else wrong communication
+  */
+static uint32_t
+wm8994_Stop(STAUDIO_Handle_t *haudio, uint32_t CodecPdwnMode)
+{
+	uint32_t counter = 0;
+
+	if(haudio->outputEnabled != 0){
+		/* Mute the output first */
+		counter += wm8994_SetMute(haudio, AUDIO_MUTE_ON);
+
+		if(CodecPdwnMode == CODEC_PDWN_SW){
+			/* Only output mute required*/
+		}
+		else{	/* CODEC_PDWN_HW */
+			/* Mute the AIF1 Timeslot 0 DAC1 path */
+			counter += CODEC_IO_Write(haudio, 0x420, 0x0200);
+
+			/* Mute the AIF1 Timeslot 1 DAC2 path */
+			counter += CODEC_IO_Write(haudio, 0x422, 0x0200);
+
+			/* Disable DAC1L_TO_HPOUT1L */
+			counter += CODEC_IO_Write(haudio, 0x2D, 0x0000);
+
+			/* Disable DAC1R_TO_HPOUT1R */
+			counter += CODEC_IO_Write(haudio, 0x2E, 0x0000);
+
+			/* Disable DAC1 and DAC2 */
+			counter += CODEC_IO_Write(haudio, 0x05, 0x0000);
+
+			/* Reset Codec by writing in 0x0000 address register */
+			counter += CODEC_IO_Write(haudio, 0x0000, 0x0000);
+			haudio->outputEnabled = 0;
+		}
+	}
+	return counter;
+}
+
+/**
+  * @brief Sets higher or lower the codec volume level.
+  * @param DeviceAddr: Device address on communication Bus.
+  * @param Volume: a byte value from 0 to 255 (refer to codec registers 
+  *         description for more details).
+  * @retval 0 if correct communication, else wrong communication
+  */
+static uint32_t
+wm8994_SetVolume(STAUDIO_Handle_t *haudio, uint8_t Volume)
+{
+	uint32_t counter = 0;
+	uint8_t convertedvol = VOLUME_CONVERT(Volume);
+
+	/* Output volume */
+	if(haudio->outputEnabled != 0){
+		if(convertedvol > 0x3E){
+			/* Unmute audio codec */
+			counter += wm8994_SetMute(haudio, AUDIO_MUTE_OFF);
+
+			/* Left Headphone Volume */
+			counter += CODEC_IO_Write(haudio, 0x1C, 0x3F | 0x140);
+
+			/* Right Headphone Volume */
+			counter += CODEC_IO_Write(haudio, 0x1D, 0x3F | 0x140);
+
+			/* Left Speaker Volume */
+			counter += CODEC_IO_Write(haudio, 0x26, 0x3F | 0x140);
+
+			/* Right Speaker Volume */
+			counter += CODEC_IO_Write(haudio, 0x27, 0x3F | 0x140);
+		}
+		else if(Volume == 0){
+			/* Mute audio codec */
+			counter += wm8994_SetMute(haudio, AUDIO_MUTE_ON);
+		}
+		else{
+			/* Unmute audio codec */
+			counter += wm8994_SetMute(haudio, AUDIO_MUTE_OFF);
+
+			/* Left Headphone Volume */
+			counter += CODEC_IO_Write(haudio, 0x1C, convertedvol | 0x140);
+
+			/* Right Headphone Volume */
+			counter += CODEC_IO_Write(haudio, 0x1D, convertedvol | 0x140);
+
+			/* Left Speaker Volume */
+			counter += CODEC_IO_Write(haudio, 0x26, convertedvol | 0x140);
+
+			/* Right Speaker Volume */
+			counter += CODEC_IO_Write(haudio, 0x27, convertedvol | 0x140);
+		}
+	}
+
+	/* Input volume */
+	if(haudio->inputEnabled != 0){
+		convertedvol = VOLUME_IN_CONVERT(Volume);
+
+		/* Left AIF1 ADC1 volume */
+		counter += CODEC_IO_Write(haudio, 0x400, convertedvol | 0x100);
+
+		/* Right AIF1 ADC1 volume */
+		counter += CODEC_IO_Write(haudio, 0x401, convertedvol | 0x100);
+
+		/* Left AIF1 ADC2 volume */
+		counter += CODEC_IO_Write(haudio, 0x404, convertedvol | 0x100);
+
+		/* Right AIF1 ADC2 volume */
+		counter += CODEC_IO_Write(haudio, 0x405, convertedvol | 0x100);
+	}
+	return counter;
+}
+
+/**
+  * @brief Enables or disables the mute feature on the audio codec.
+  * @param DeviceAddr: Device address on communication Bus.   
+  * @param Cmd: AUDIO_MUTE_ON to enable the mute or AUDIO_MUTE_OFF to disable the
+  *             mute mode.
+  * @retval 0 if correct communication, else wrong communication
+  */
+static uint32_t
+wm8994_SetMute(STAUDIO_Handle_t *haudio, uint32_t Cmd)
+{
+	uint32_t counter = 0;
+
+	if(haudio->outputEnabled != 0){
+		/* Set the Mute mode */
+		if(Cmd == AUDIO_MUTE_ON){
+			/* Soft Mute the AIF1 Timeslot 0 DAC1 path L&R */
+			counter += CODEC_IO_Write(haudio, 0x420, 0x0200);
+
+			/* Soft Mute the AIF1 Timeslot 1 DAC2 path L&R */
+			counter += CODEC_IO_Write(haudio, 0x422, 0x0200);
+		}
+		else{	/* AUDIO_MUTE_OFF Disable the Mute */
+			/* Unmute the AIF1 Timeslot 0 DAC1 path L&R */
+			counter += CODEC_IO_Write(haudio, 0x420, 0x0010);
+
+			/* Unmute the AIF1 Timeslot 1 DAC2 path L&R */
+			counter += CODEC_IO_Write(haudio, 0x422, 0x0010);
+		}
+	}
+	return counter;
+}
+
+/**
+  * @brief Switch dynamically (while audio file is played) the output target 
+  *         (speaker or headphone).
+  * @param DeviceAddr: Device address on communication Bus.
+  * @param Output: specifies the audio output target: OUTPUT_DEVICE_SPEAKER,
+  *         OUTPUT_DEVICE_HEADPHONE, OUTPUT_DEVICE_BOTH or OUTPUT_DEVICE_AUTO 
+  * @retval 0 if correct communication, else wrong communication
+  */
+static uint32_t
+wm8994_SetOutputMode(STAUDIO_Handle_t *haudio, uint8_t Output)
+{
+	uint32_t counter = 0;
+
+	switch(Output){
+	case OUTPUT_DEVICE_SPEAKER:
+		/* Enable DAC1 (Left), Enable DAC1 (Right), 
+		  Disable DAC2 (Left), Disable DAC2 (Right)*/
+		counter += CODEC_IO_Write(haudio, 0x05, 0x0C0C);
+
+		/* Enable the AIF1 Timeslot 0 (Left) to DAC 1 (Left) mixer path */
+		counter += CODEC_IO_Write(haudio, 0x601, 0x0000);
+
+		/* Enable the AIF1 Timeslot 0 (Right) to DAC 1 (Right) mixer path */
+		counter += CODEC_IO_Write(haudio, 0x602, 0x0000);
+
+		/* Disable the AIF1 Timeslot 1 (Left) to DAC 2 (Left) mixer path */
+		counter += CODEC_IO_Write(haudio, 0x604, 0x0002);
+
+		/* Disable the AIF1 Timeslot 1 (Right) to DAC 2 (Right) mixer path */
+		counter += CODEC_IO_Write(haudio, 0x605, 0x0002);
+		break;
+
+	case OUTPUT_DEVICE_HEADPHONE:
+		/* Disable DAC1 (Left), Disable DAC1 (Right), 
+		  Enable DAC2 (Left), Enable DAC2 (Right)*/
+		counter += CODEC_IO_Write(haudio, 0x05, 0x0303);
+
+		/* Enable the AIF1 Timeslot 0 (Left) to DAC 1 (Left) mixer path */
+		counter += CODEC_IO_Write(haudio, 0x601, 0x0001);
+
+		/* Enable the AIF1 Timeslot 0 (Right) to DAC 1 (Right) mixer path */
+		counter += CODEC_IO_Write(haudio, 0x602, 0x0001);
+
+		/* Disable the AIF1 Timeslot 1 (Left) to DAC 2 (Left) mixer path */
+		counter += CODEC_IO_Write(haudio, 0x604, 0x0000);
+
+		/* Disable the AIF1 Timeslot 1 (Right) to DAC 2 (Right) mixer path */
+		counter += CODEC_IO_Write(haudio, 0x605, 0x0000);
+		break;
+
+	case OUTPUT_DEVICE_BOTH:
+		/* Enable DAC1 (Left), Enable DAC1 (Right), 
+		 also Enable DAC2 (Left), Enable DAC2 (Right)*/
+		counter += CODEC_IO_Write(haudio, 0x05, 0x0303 | 0x0C0C);
+
+		/* Enable the AIF1 Timeslot 0 (Left) to DAC 1 (Left) mixer path */
+		counter += CODEC_IO_Write(haudio, 0x601, 0x0001);
+
+		/* Enable the AIF1 Timeslot 0 (Right) to DAC 1 (Right) mixer path */
+		counter += CODEC_IO_Write(haudio, 0x602, 0x0001);
+
+		/* Enable the AIF1 Timeslot 1 (Left) to DAC 2 (Left) mixer path */
+		counter += CODEC_IO_Write(haudio, 0x604, 0x0002);
+
+		/* Enable the AIF1 Timeslot 1 (Right) to DAC 2 (Right) mixer path */
+		counter += CODEC_IO_Write(haudio, 0x605, 0x0002);
+		break;
+
+	default:
+		/* Disable DAC1 (Left), Disable DAC1 (Right), 
+		  Enable DAC2 (Left), Enable DAC2 (Right)*/
+		counter += CODEC_IO_Write(haudio, 0x05, 0x0303);
+
+		/* Enable the AIF1 Timeslot 0 (Left) to DAC 1 (Left) mixer path */
+		counter += CODEC_IO_Write(haudio, 0x601, 0x0001);
+
+		/* Enable the AIF1 Timeslot 0 (Right) to DAC 1 (Right) mixer path */
+		counter += CODEC_IO_Write(haudio, 0x602, 0x0001);
+
+		/* Disable the AIF1 Timeslot 1 (Left) to DAC 2 (Left) mixer path */
+		counter += CODEC_IO_Write(haudio, 0x604, 0x0000);
+
+		/* Disable the AIF1 Timeslot 1 (Right) to DAC 2 (Right) mixer path */
+		counter += CODEC_IO_Write(haudio, 0x605, 0x0000);
+		break;
+	}
+	return counter;
+}
+
+/**
+  * @brief Resets wm8994 registers.
+  * @param DeviceAddr: Device address on communication Bus. 
+  * @retval 0 if correct communication, else wrong communication
+  */
+static ER
+wm8994_Reset(STAUDIO_Handle_t *haudio)
+{
+	uint32_t deviceid = 0;
+	ER ercd;
+	uint8_t  buffer[4];
+
+	/* Get the WM8994 ID. */
+	ercd = i2c_memread(haudio->hi2c, haudio->i2caddress, (uint16_t)WM8994_CHIPID_ADDR, I2C_MEMADD_SIZE_16BIT, buffer, 2, 1000);
+	if(ercd != E_OK)
+		return ercd;
+	deviceid = (buffer[0] << 8) | buffer[1];
+
+	/* wm8994 codec initialization */
+#if 1	/* ROI DEBUG */
+	syslog_2(LOG_NOTICE, "## wm8994_Reset deviceid[%08x][%08x] ##", deviceid, WM8994_ID);
+#endif	/* ROI DEBUG */
+
+	if(deviceid != WM8994_ID)
+		return E_SYS;
+
+	/* Reset Codec by writing in 0x0000 address register */
+	CODEC_IO_Write(haudio, 0x0000, 0x0000);
+	haudio->outputEnabled = 0;
+	haudio->inputEnabled  = 0;
+	haudio->ColdStartup   = 1;
+	return E_OK;
+}
+
+
+static void SAIx_Out_Init(STAUDIO_Handle_t *haudio, uint32_t AudioFreq, uint16_t framesize)
+{
+	AUDIO_Handle_t *hsai = haudio->hsai;
+
+	/* Configure SAI_Block_x 
+	  LSBFirst: Disabled 
+	  DataSize: 16 */
+	hsai->OutInit.MonoStereoMode = SAI_STEREOMODE;
+	hsai->OutInit.AudioFrequency = AudioFreq;
+	hsai->OutInit.AudioMode = SAI_MODEMASTER_TX;
+	hsai->OutInit.NoDivider = SAI_MASTERDIVIDER_ENABLE;
+	hsai->OutInit.Protocol = SAI_FREE_PROTOCOL;
+	hsai->OutInit.DataSize = SAI_DATASIZE_16;
+	hsai->OutInit.FirstBit = SAI_FIRSTBIT_MSB;
+	hsai->OutInit.Synchro = SAI_ASYNCHRONOUS;
+#if defined(TOPPERS_STM32F769_DISCOVERY) || defined(TOPPERS_STM32F7_DISCOVERY)
+	hsai->OutInit.ClockStrobing = SAI_CLOCKSTROBING_RISINGEDGE;
+	hsai->OutInit.OutputDrive = SAI_OUTPUTDRIVE_ENABLE;
+#else
+	hsai->OutInit.ClockStrobing = SAI_CLOCKSTROBING_FALLINGEDGE;
+	hsai->OutInit.OutputDrive = SAI_OUTPUTDRIVE_DISABLE;
+#endif
+	hsai->OutInit.FIFOThreshold = SAI_FIFOTHRESHOLD_1QF;
+	hsai->OutInit.SynchroExt    = SAI_SYNCEXT_DISABLE;
+	hsai->OutInit.CompandingMode= SAI_NOCOMPANDING;
+	hsai->OutInit.TriState      = SAI_OUTPUT_NOTRELEASED;
+	hsai->OutInit.Mckdiv        = 0;
+
+	/* Configure SAI_Block_x Frame 
+	  Frame Length: 64
+	  Frame active Length: 32
+	  FS Definition: Start frame + Channel Side identification
+	  FS Polarity: FS active Low
+	  FS Offset: FS asserted one bit before the first bit of slot 0 */ 
+	hsai->OutInit.FrameLength = framesize;
+	hsai->OutInit.ActiveFrameLength = framesize / 2;
+	hsai->OutInit.FSDefinition = SAI_FS_CHANNEL_IDENTIFICATION;
+	hsai->OutInit.FSPolarity = SAI_FS_ACTIVE_LOW;
+	hsai->OutInit.FSOffset = SAI_FS_BEFOREFIRSTBIT;
+
+	/* Configure SAI Block_x Slot 
+	  Slot First Bit Offset: 0
+	  Slot Size  : 16
+	  Slot Number: 4
+	  Slot Active: All slot actives */
+	hsai->OutInit.FirstBitOffset = 0;
+	hsai->OutInit.SlotSize = SAI_SLOTSIZE_DATASIZE;
+	hsai->OutInit.SlotNumber = 4; 
+	hsai->OutInit.SlotActive = CODEC_AUDIOFRAME_SLOT_0123;
+}
+
+
+/*
+ *  オーディオ出力初期化設定
+ *  param1: STAUDIOハンドラ
+ *  param2: 出力デバイス設定
+ *  param3: ボリューム設定値
+ *  param4: オーディオ周波数値
+ *  param5: フレームサイズ(バイト)
+ *  return: E_OKで正常設定
+ */
+ER
+staudio_out_init(STAUDIO_Handle_t *haudio, uint16_t OutputDevice, uint8_t Volume, uint32_t AudioFreq, uint16_t framesize)
+{
+	AUDIO_Handle_t *hsai;
+	ER   ercd = E_OK;
+
+	/* PLL clock is set depending by the AudioFreq (44.1khz vs 48khz groups) */ 
+	if(haudio->hsai == NULL){
+		haudio->hsai = audio_init(haudio->saiid);
+	}
+	else{
+		/* Disable SAI peripheral */
+		audio_disable(haudio->hsai, AUDIO_OUT_BLOCK);
+		audio_end(haudio->hsai, AUDIO_OUT_BLOCK);
+	}
+	hsai = haudio->hsai;
+	audio_clockconfig(hsai, AudioFreq, NULL);
+
+	/* SAI data transfer preparation:
+	  Prepare the Media to be used for the audio transfer from memory to SAI peripheral */
+	/* Disable SAI peripheral to allow access to SAI internal registers */
+	audio_disable(hsai, AUDIO_OUT_BLOCK);
+
+	SAIx_Out_Init(haudio, AudioFreq, framesize);
+
+	audio_start(hsai, AUDIO_OUT_BLOCK);
+
+	/* Enable SAI peripheral to generate MCLK */
+	audio_enable(hsai, AUDIO_OUT_BLOCK);
+
+	/* wm8994 codec initialization */
+	/* Reset the Codec Registers */
+	ercd = wm8994_Reset(haudio);
+	if(ercd == E_OK){
+		/* Initialize the codec internal registers */
+		wm8994_Init(haudio, OutputDevice, Volume, AudioFreq);
+	}
+	return ercd;
+}
+
+/*
+ *  オーディオ出力演奏
+ *  param1: STAUDIOハンドラ
+ *  param2: 出力バッファポインタ
+ *  param3: 出力バッファサイズ
+ *  return: E_OKで正常設定
+ */
+ER
+staudio_out_play(STAUDIO_Handle_t *haudio, uint16_t* pBuffer, uint32_t Size)
+{
+	AUDIO_Handle_t *hsai = haudio->hsai;
+
+	/* Call the audio Codec Play function */
+	if(wm8994_SetMute(haudio, AUDIO_MUTE_OFF) != 0){
+		return E_SYS;
+	}
+	else{
+		/* Update the Media layer and enable it for play */  
+		hsai->transcallback = haudio->audio_fullout_func;
+		hsai->transhalfcallback = haudio->audio_halfout_func;
+		hsai->errorcallback = haudio->audio_error_func;
+		audio_transmit(hsai, (uint8_t*) pBuffer, DMA_MAX(Size / AUDIODATA_SIZE));
+		return E_OK;
+	}
+}
+
+/*
+ *  オーディオPAUSE設定
+ *  param1: STAUDIOハンドラ
+ *  return: E_OKで正常設定
+ */
+ER
+staudio_out_pause(STAUDIO_Handle_t *haudio)
+{
+	/* Call the Audio Codec Pause/Resume function */
+	if(wm8994_Pause(haudio) != 0){
+		return E_SYS;
+	}
+	else{
+		/* Call the Media layer pause function */
+		audio_dmapause(haudio->hsai, AUDIO_OUT_BLOCK);
+		return E_OK;
+	}
+}
+
+/*
+ *  オーディオRESUME設定
+ *  param1: STAUDIOハンドラ
+ *  return: E_OKで正常設定
+ */
+ER
+staudio_out_resume(STAUDIO_Handle_t *haudio)
+{
+	/* Call the Audio Codec Pause/Resume function */
+	if(wm8994_SetMute(haudio, AUDIO_MUTE_OFF) != 0){
+		return E_SYS;
+	}
+	else{
+		/* Call the Media layer pause/resume function */
+		audio_dmaresume(haudio->hsai, AUDIO_OUT_BLOCK);
+		return E_OK;
+	}
+}
+
+/*
+ *  オーディオ出力停止設定
+ *  param1: STAUDIOハンドラ
+ *  param2: 停止設定条件
+ *  return: E_OKで正常設定
+ */
+ER
+staudio_out_stop(STAUDIO_Handle_t *haudio, uint32_t Option)
+{
+	/* Call the Media layer stop function */
+	audio_dmastop(haudio->hsai, AUDIO_OUT_BLOCK);
+
+	/* Call Audio Codec Stop function */
+	if(wm8994_Stop(haudio, Option) != 0){
+		return E_SYS;
+	}
+	else{
+		if(Option == CODEC_PDWN_HW){
+			/* Wait at least 100us */
+			dly_tsk(1);
+		}
+		return E_OK;
+	}
+}
+
+/*
+ *  オーディオボリューム設定
+ *  param1: STAUDIOハンドラ
+ *  param2: volumeパセンテージ(0%-100%)
+ *  return: E_OKで正常設定
+ */
+ER
+staudio_out_setvolume(STAUDIO_Handle_t *haudio, uint8_t Volume)
+{
+	/* Call the codec volume control function with converted volume value */
+	if(wm8994_SetVolume(haudio, Volume) != 0)
+		return E_SYS;
+	else
+		return E_OK;
+}
+
+/*
+ *  オーディオMUTE設定
+ *  param1: STAUDIOハンドラ
+ *  param2: MUTE設定コマンド(AUDIO_MUTE_ONまたはAUDIO_MUTE_OFF)
+ *  return: E_OKで正常設定
+ */
+ER
+staudio_out_setmute(STAUDIO_Handle_t *haudio, uint32_t Cmd)
+{
+	/* Call the Codec Mute function */
+	if(wm8994_SetMute(haudio, Cmd) != 0)
+		return E_SYS;
+	else
+		return E_OK;
+}
+
+/*
+ *  オーディオ出力モード設定
+ *  param1: STAUDIOハンドラ
+ *  param2: 出力モード(OUTPUT_DEVICE_SPEAKER,UTPUT_DEVICE_HEADPHONEまたはOUTPUT_DEVICE_BOTH)
+ *  return: E_OKで正常設定
+ */
+ER
+staudio_out_setoutputmode(STAUDIO_Handle_t *haudio, uint8_t Output)
+{
+	/* Call the Codec output device function */
+	if(wm8994_SetOutputMode(haudio, Output) != 0)
+		return E_SYS;
+	else
+		return E_OK;
+}
+
+/*
+ *  オーディオ周波数設定
+ *  param1: STAUDIOハンドラ
+ *  param2: 周波数値
+ *  return: E_OKで正常設定
+ */
+void
+staudio_out_setfrequency(STAUDIO_Handle_t *haudio, uint32_t AudioFreq)
+{
+	/* PLL clock is set depending by the AudioFreq (44.1khz vs 48khz groups) */ 
+	audio_clockconfig(haudio->hsai, AudioFreq, NULL);
+
+	/* Disable SAI peripheral to allow access to SAI internal registers */
+	audio_disable(haudio->hsai, AUDIO_OUT_BLOCK);
+
+	/* Update the SAI audio frequency configuration */
+	haudio->hsai->OutInit.AudioFrequency = AudioFreq;
+	audio_start(haudio->hsai, AUDIO_OUT_BLOCK);
+
+	/* Enable SAI peripheral to generate MCLK */
+	audio_enable(haudio->hsai, AUDIO_OUT_BLOCK);
+}
+
+/*
+ *  オーディオフレームスロット設定
+ *  param1: STAUDIOハンドラ
+ *  param2: フレームスロット値
+ */
+void
+staudio_out_setframeslot(STAUDIO_Handle_t *haudio, uint32_t AudioFrameSlot)
+{
+	/* Disable SAI peripheral to allow access to SAI internal registers */
+	audio_disable(haudio->hsai, AUDIO_OUT_BLOCK);
+
+	/* Update the SAI audio frame slot configuration */
+	haudio->hsai->OutInit.SlotActive = AudioFrameSlot;
+	audio_start(haudio->hsai, AUDIO_OUT_BLOCK);
+
+	/* Enable SAI peripheral to generate MCLK */
+	audio_enable(haudio->hsai, AUDIO_OUT_BLOCK);
+}
+
+/*
+ *  オーディオ出力バッファ変更
+ *  param1: STAUDIOハンドラ
+ *  param2: 出力バッファポインタ
+ *  param3: バッファサイズ
+ */
+void
+staudio_out_changebuffer(STAUDIO_Handle_t *haudio, uint16_t *pData, uint16_t Size)
+{
+	haudio->hsai->transcallback = haudio->audio_fullout_func;
+	haudio->hsai->transhalfcallback = haudio->audio_halfout_func;
+	haudio->hsai->errorcallback = haudio->audio_error_func;
+	audio_transmit(haudio->hsai, (uint8_t*)pData, Size);
+}
+
+/*
+ *  オーディオ出力処理終了
+ *  param1: STAUDIOハンドラ
+ */
+void
+staudio_out_deinit(STAUDIO_Handle_t *haudio)
+{
+	if(haudio->hsai != NULL){
+		/* Disable SAI peripheral */
+		audio_disable(haudio->hsai, AUDIO_OUT_BLOCK);
+		audio_end(haudio->hsai, AUDIO_OUT_BLOCK);
+		if(audio_status(haudio->hsai, AUDIO_IN_BLOCK) == AUDIO_STATUS_RESET){
+			/* DeInit the SAI MSP : this __weak function can be rewritten by the application */
+			audio_deinit(haudio->hsai, AUDIO_OUT_BLOCK);
+			haudio->hsai = NULL;
+		}
+	}
+}
+
+/*******************************************************************************
+                            Static Functions
+*******************************************************************************/
+/**
+  * @brief  Initializes the input Audio Codec audio interface (SAI).
+  * @param  SaiOutMode: SAI_MODEMASTER_TX (for record and playback in parallel)
+  *                     or SAI_MODEMASTER_RX (for record only).
+  * @param  SlotActive: CODEC_AUDIOFRAME_SLOT_02, CODEC_AUDIOFRAME_SLOT_13 or
+  *                     CODEC_AUDIOFRAME_SLOT_0123
+  * @param  AudioFreq: Audio frequency to be configured for the SAI peripheral.
+  * @retval None
+  */
+static void SAIx_In_Init(STAUDIO_Handle_t *haudio, uint32_t SaiOutMode, uint32_t SlotActive, uint32_t AudioFreq)
+{
+	/* Initialize the haudio_out_sai instance parameters */
+	AUDIO_Handle_t *hsai = haudio->hsai;
+
+	/* Disable SAI peripheral to allow access to SAI internal registers */
+	audio_disable(hsai, AUDIO_OUT_BLOCK);
+
+	/* Configure SAI_Block_x
+	LSBFirst: Disabled
+	DataSize: 16 */
+	hsai->OutInit.AudioFrequency = AudioFreq;
+#ifdef TOPPERS_STM32F769_DISCOVERY
+	hsai->OutInit.AudioMode = SAI_MODEMASTER_RX;
+#else
+	hsai->OutInit.AudioMode = SaiOutMode;
+#endif
+	hsai->OutInit.MonoStereoMode = SAI_STEREOMODE;
+	hsai->OutInit.NoDivider = SAI_MASTERDIVIDER_ENABLE;
+	hsai->OutInit.Protocol = SAI_FREE_PROTOCOL;
+	hsai->OutInit.DataSize = SAI_DATASIZE_16;
+	hsai->OutInit.FirstBit = SAI_FIRSTBIT_MSB;
+#if defined(TOPPERS_STM32F769_DISCOVERY) || defined(TOPPERS_STM32F7_DISCOVERY)
+	hsai->OutInit.ClockStrobing = SAI_CLOCKSTROBING_RISINGEDGE;
+	hsai->OutInit.OutputDrive = SAI_OUTPUTDRIVE_ENABLE;
+#else
+	hsai->OutInit.ClockStrobing = SAI_CLOCKSTROBING_FALLINGEDGE;
+	hsai->OutInit.OutputDrive = SAI_OUTPUTDRIVE_DISABLE;
+#endif
+	hsai->OutInit.Synchro = SAI_ASYNCHRONOUS;
+	hsai->OutInit.FIFOThreshold = SAI_FIFOTHRESHOLD_1QF;
+#if defined(TOPPERS_STM32F769_DISCOVERY)
+	hsai->OutInit.SynchroExt    = SAI_SYNCEXT_DISABLE;
+#endif
+#ifndef TOPPERS_STM32F7_DISCOVERY
+	hsai->OutInit.CompandingMode= SAI_NOCOMPANDING;
+	hsai->OutInit.TriState      = SAI_OUTPUT_NOTRELEASED;
+	hsai->OutInit.Mckdiv        = 0;
+#endif
+
+	/* Configure SAI_Block_x Frame
+	Frame Length: 64
+	Frame active Length: 32
+	FS Definition: Start frame + Channel Side identification
+	FS Polarity: FS active Low
+	FS Offset: FS asserted one bit before the first bit of slot 0 */
+	hsai->OutInit.FrameLength = 64;
+	hsai->OutInit.ActiveFrameLength = 32;
+	hsai->OutInit.FSDefinition = SAI_FS_CHANNEL_IDENTIFICATION;
+	hsai->OutInit.FSPolarity = SAI_FS_ACTIVE_LOW;
+	hsai->OutInit.FSOffset = SAI_FS_BEFOREFIRSTBIT;
+
+	/* Configure SAI Block_x Slot
+	Slot First Bit Offset: 0
+	Slot Size  : 16
+	Slot Number: 4
+	Slot Active: All slot actives */
+	hsai->OutInit.FirstBitOffset = 0;
+	hsai->OutInit.SlotSize = SAI_SLOTSIZE_DATASIZE;
+	hsai->OutInit.SlotNumber = 4;
+	hsai->OutInit.SlotActive = SlotActive;
+
+	audio_start(hsai, AUDIO_OUT_BLOCK);
+
+	/* Initialize SAI2 block B in SLAVE RX synchronous from SAI2 block A */
+	/* Initialize the haudio_in_sai Instance parameter */
+
+	/* Disable SAI peripheral to allow access to SAI internal registers */
+	audio_disable(hsai, AUDIO_IN_BLOCK);
+
+	/* Configure SAI_Block_x
+	LSBFirst: Disabled
+	DataSize: 16 */
+	hsai->InInit.AudioFrequency = AudioFreq;
+	hsai->InInit.AudioMode = SAI_MODESLAVE_RX;
+	hsai->InInit.NoDivider = SAI_MASTERDIVIDER_ENABLE;
+	hsai->InInit.Protocol = SAI_FREE_PROTOCOL;
+	hsai->InInit.DataSize = SAI_DATASIZE_16;
+	hsai->InInit.FirstBit = SAI_FIRSTBIT_MSB;
+	hsai->InInit.ClockStrobing = SAI_CLOCKSTROBING_RISINGEDGE;
+	hsai->InInit.Synchro = SAI_SYNCHRONOUS;
+	hsai->InInit.OutputDrive = SAI_OUTPUTDRIVE_DISABLE;
+	hsai->InInit.FIFOThreshold = SAI_FIFOTHRESHOLD_1QF;
+#ifdef TOPPERS_STM32F7_DISCOVERY
+	hsai->InInit.SynchroExt    = SAI_SYNCEXT_DISABLE;
+#endif
+#ifndef TOPPERS_STM32F7_DISCOVERY
+	hsai->InInit.CompandingMode= SAI_NOCOMPANDING;
+	hsai->InInit.TriState      = SAI_OUTPUT_NOTRELEASED;
+	hsai->InInit.Mckdiv        = 0;
+#endif
+
+	/* Configure SAI_Block_x Frame
+	Frame Length: 64
+	Frame active Length: 32
+	FS Definition: Start frame + Channel Side identification
+	FS Polarity: FS active Low
+	FS Offset: FS asserted one bit before the first bit of slot 0 */
+	hsai->InInit.FrameLength = 64;
+	hsai->InInit.ActiveFrameLength = 32;
+	hsai->InInit.FSDefinition = SAI_FS_CHANNEL_IDENTIFICATION;
+	hsai->InInit.FSPolarity = SAI_FS_ACTIVE_LOW;
+	hsai->InInit.FSOffset = SAI_FS_BEFOREFIRSTBIT;
+
+	/* Configure SAI Block_x Slot
+	Slot First Bit Offset: 0
+	Slot Size  : 16
+	Slot Number: 4
+	Slot Active: All slot active */
+	hsai->InInit.FirstBitOffset = 0;
+	hsai->InInit.SlotSize = SAI_SLOTSIZE_DATASIZE;
+	hsai->InInit.SlotNumber = 4;
+	hsai->InInit.SlotActive = SlotActive;
+
+	audio_start(hsai, AUDIO_IN_BLOCK);
+
+	/* Enable SAI peripheral to generate MCLK */
+	audio_enable(hsai, AUDIO_OUT_BLOCK);
+
+	/* Enable SAI peripheral */
+	audio_enable(hsai, AUDIO_IN_BLOCK);
+}
+
+
+/**
+  * @brief  Deinitializes the output Audio Codec audio interface (SAI).
+  * @retval None
+  */
+static void SAIx_In_DeInit(STAUDIO_Handle_t *haudio)
+{
+	if(haudio->hsai != NULL){
+		/* Disable SAI peripheral */
+		audio_disable(haudio->hsai, AUDIO_IN_BLOCK);
+		audio_end(haudio->hsai, AUDIO_IN_BLOCK);
+		if(audio_status(haudio->hsai, AUDIO_OUT_BLOCK) == AUDIO_STATUS_RESET){
+			/* DeInit the SAI MSP : this __weak function can be rewritten by the application */
+			audio_deinit(haudio->hsai, AUDIO_IN_BLOCK);
+			haudio->hsai = NULL;
+		}
+	}
+}
+
+
+#ifdef TOPPERS_STM32F769_DISCOVERY
+/**
+  * @brief  Regular conversion complete callback. 
+  * @note   In interrupt mode, user has to read conversion value in this function
+            using HAL_DFSDM_FilterGetRegularValue.
+  * @param  hdfsdm_filter : DFSDM filter handle.
+  * @retval None
+  */
+static void HAL_DFSDM_FilterRegConvCpltCallback(DFSDM_Filter_Handle_t *hdfsdm_filter)
+{
+	uint32_t index = 0;
+
+	if(hdfsdm_filter == &hAudioInTopLeftFilter){
+		DmaTopLeftRecCplt = 1;
+	}
+	else if(hdfsdm_filter == &hAudioInTopRightFilter){
+		DmaTopRightRecCplt = 1;
+	}
+	else if(hdfsdm_filter == &hAudioInButtomLeftFilter){
+		DmaButtomLeftRecCplt = 1;
+	}
+	else{
+		DmaButtomRightRecCplt = 1;
+	}
+
+	if(AudioIn_ChannelNumber > 2){
+		if((DmaTopLeftRecCplt == 1) && (DmaTopRightRecCplt == 1) && (DmaButtomLeftRecCplt == 1) && (DmaButtomRightRecCplt == 1)){
+			for(index = (ScratchSize/2) ; index < ScratchSize; index++){
+				hAudioIn.pRecBuf[AppBuffTrigger]     = (uint16_t)(SaturaLH((pScratchBuff[1][index] >> 8), -32760, 32760));
+				hAudioIn.pRecBuf[AppBuffTrigger + 1] = (uint16_t)(SaturaLH((pScratchBuff[0][index] >> 8), -32760, 32760));       
+				hAudioIn.pRecBuf[AppBuffTrigger + 2] = (uint16_t)(SaturaLH((pScratchBuff[3][index] >> 8), -32760, 32760));
+				hAudioIn.pRecBuf[AppBuffTrigger + 3] = (uint16_t)(SaturaLH((pScratchBuff[2][index] >> 8), -32760, 32760));      
+				AppBuffTrigger +=4;
+			}
+			DmaTopLeftRecCplt  = 0;
+			DmaTopRightRecCplt = 0;
+			DmaButtomLeftRecCplt  = 0;
+			DmaButtomRightRecCplt = 0;
+		}
+	}
+	else{
+		if((DmaTopLeftRecCplt == 1) && (DmaTopRightRecCplt == 1)){
+			for(index = (ScratchSize/2) ; index < ScratchSize; index++){
+				hAudioIn.pRecBuf[AppBuffTrigger]     = (uint16_t)(SaturaLH((pScratchBuff[1][index] >> 8), -32760, 32760));
+				hAudioIn.pRecBuf[AppBuffTrigger + 1] = (uint16_t)(SaturaLH((pScratchBuff[0][index] >> 8), -32760, 32760));
+				AppBuffTrigger +=2;
+			}
+			DmaTopLeftRecCplt  = 0;
+			DmaTopRightRecCplt = 0;  
+		}
+	}
+
+	/* Call Half Transfer Complete callback */
+	if((AppBuffTrigger == hAudioIn.RecSize/2) && (AppBuffHalf == 0)){
+		AppBuffHalf = 1;
+		if(hstaudio != NULL && hstaudio->audio_halfin_func)
+			hstaudio->audio_halfin_func(hdfsdm_filter);
+	}
+	/* Call Transfer Complete callback */
+	if(AppBuffTrigger == hAudioIn.RecSize){
+		/* Reset Application Buffer Trigger */
+		AppBuffTrigger = 0;
+		AppBuffHalf = 0; 
+		/* Call the record update function to get the next buffer to fill and its size (size is ignored) */
+		if(hstaudio != NULL && hstaudio->audio_fullin_func)
+			hstaudio->audio_fullin_func(hdfsdm_filter);
+	}
+}
+
+/**
+  * @brief  Half regular conversion complete callback. 
+  * @param  hdfsdm_filter : DFSDM filter handle.
+  * @retval None
+  */
+static void HAL_DFSDM_FilterRegConvHalfCpltCallback(DFSDM_Filter_Handle_t *hdfsdm_filter)
+{
+	uint32_t index = 0;
+
+	if(hdfsdm_filter == &hAudioInTopLeftFilter){
+		DmaTopLeftRecHalfCplt = 1;
+	}
+	else if(hdfsdm_filter == &hAudioInTopRightFilter){
+		DmaTopRightRecHalfCplt = 1;
+	}
+	else if(hdfsdm_filter == &hAudioInButtomLeftFilter){
+		DmaButtomLeftRecHalfCplt = 1;
+	}
+	else{
+		DmaButtomRightRecHalfCplt = 1;
+	}
+
+	if(AudioIn_ChannelNumber > 2){
+		if((DmaTopLeftRecHalfCplt == 1) && (DmaTopRightRecHalfCplt == 1) && (DmaButtomLeftRecHalfCplt == 1) && (DmaButtomRightRecHalfCplt == 1)){
+			for(index = 0 ; index < ScratchSize/2; index++){
+				hAudioIn.pRecBuf[AppBuffTrigger]     = (uint16_t)(SaturaLH((pScratchBuff[1][index] >> 8), -32760, 32760));
+				hAudioIn.pRecBuf[AppBuffTrigger + 1] = (uint16_t)(SaturaLH((pScratchBuff[0][index] >> 8), -32760, 32760)); 
+				hAudioIn.pRecBuf[AppBuffTrigger + 2] = (uint16_t)(SaturaLH((pScratchBuff[3][index] >> 8), -32760, 32760));
+				hAudioIn.pRecBuf[AppBuffTrigger + 3] = (uint16_t)(SaturaLH((pScratchBuff[2][index] >> 8), -32760, 32760));      
+ 				AppBuffTrigger +=4;
+			}
+			DmaTopLeftRecHalfCplt  = 0;
+			DmaTopRightRecHalfCplt = 0;
+			DmaButtomLeftRecHalfCplt  = 0;
+			DmaButtomRightRecHalfCplt = 0;
+		}
+	}
+	else{
+		if((DmaTopLeftRecHalfCplt == 1) && (DmaTopRightRecHalfCplt == 1)){
+			for(index = 0 ; index < ScratchSize/2; index++){
+				hAudioIn.pRecBuf[AppBuffTrigger]     = (uint16_t)(SaturaLH((pScratchBuff[1][index] >> 8), -32760, 32760));
+				hAudioIn.pRecBuf[AppBuffTrigger + 1] = (uint16_t)(SaturaLH((pScratchBuff[0][index] >> 8), -32760, 32760));
+				AppBuffTrigger +=2;
+			}
+			DmaTopLeftRecHalfCplt  = 0;
+			DmaTopRightRecHalfCplt = 0;
+		}
+	}
+
+	/* Call Half Transfer Complete callback */
+	if((AppBuffTrigger == hAudioIn.RecSize/2) && (AppBuffHalf == 0)){
+		AppBuffHalf = 1;
+		if(hstaudio != NULL && hstaudio->audio_halfin_func)
+			hstaudio->audio_halfin_func(hdfsdm_filter);
+	}
+	/* Call Transfer Complete callback */
+	if(AppBuffTrigger == hAudioIn.RecSize){
+		/* Reset Application Buffer Trigger */
+		AppBuffTrigger = 0;
+		AppBuffHalf = 0;
+		/* Call the record update function to get the next buffer to fill and its size (size is ignored) */
+		if(hstaudio != NULL && hstaudio->audio_fullin_func)
+			hstaudio->audio_fullin_func(hdfsdm_filter);
+	}
+}
+
+/*******************************************************************************
+                            Static Functions
+*******************************************************************************/
+/**
+  * @brief  Initialize the Digital Filter for Sigma-Delta Modulators interface (DFSDM).
+  * @param  AudioFreq: Audio frequency to be used to set correctly the DFSDM peripheral.
+  * @note   Channel output Clock Divider and Filter Oversampling are calculated as follow: 
+  *         - Clock_Divider = CLK(input DFSDM)/CLK(micro) with
+  *           1MHZ < CLK(micro) < 3.2MHZ (TYP 2.4MHZ for MP34DT01TR)
+  *         - Oversampling = CLK(input DFSDM)/(Clock_Divider * AudioFreq)  
+  * @retval AUDIO_OK if correct communication, else wrong communication
+  */
+static ER DFSDMx_Init(uint32_t AudioFreq)
+{
+	ER ercd = E_OK;
+
+	/****************************************************************************/ 
+	/********************** Channels configuration  *****************************/
+	/****************************************************************************/ 
+	/* CHANNEL 1 configuration */
+	hAudioInTopLeftChannel.state                         = DFSDM_CHANNEL_STATE_RESET;
+	hAudioInTopLeftChannel.base                          = (uint32_t)TADR_DFSDM1_CHANNEL1_BASE;
+	hAudioInTopLeftChannel.Init.OutClockActivation       = 1 /* ENABLE */;
+	hAudioInTopLeftChannel.Init.OutClockSelection        = DFSDM_CHANNEL_OUTPUT_CLOCK_AUDIO;
+	/* Set the DFSDM clock OUT audio frequency configuration */
+	hAudioInTopLeftChannel.Init.OutClockDivider          = DFSDM_CLOCK_DIVIDER(AudioFreq);
+	hAudioInTopLeftChannel.Init.InputMultiplexer         = DFSDM_CHANNEL_EXTERNAL_INPUTS;
+	hAudioInTopLeftChannel.Init.InputDataPacking         = DFSDM_CHANNEL_STANDARD_MODE;
+	hAudioInTopLeftChannel.Init.InputPins                = DFSDM_CHANNEL_SAME_CHANNEL_PINS;
+	/* Request to sample stable data for LEFT micro on Rising edge */
+	hAudioInTopLeftChannel.Init.SerialType               = DFSDM_CHANNEL_SPI_RISING;
+	hAudioInTopLeftChannel.Init.SerialSpiClock           = DFSDM_CHANNEL_SPI_CLOCK_INTERNAL;
+	hAudioInTopLeftChannel.Init.AwdFilterOrder           = DFSDM_CHANNEL_FASTSINC_ORDER;
+	hAudioInTopLeftChannel.Init.AwdOversampling          = 10;
+	hAudioInTopLeftChannel.Init.Offset                   = 0;
+	hAudioInTopLeftChannel.Init.RightBitShift            = DFSDM_RIGHT_BIT_SHIFT(AudioFreq);
+	if(E_OK != (ercd = dfsdm_channel_init(&hAudioInTopLeftChannel))){
+		return ercd;
+	}
+
+	/* CHANNEL 0 configuration */
+	hAudioInTopRightChannel.state                         = DFSDM_CHANNEL_STATE_RESET;
+	hAudioInTopRightChannel.base                          = (uint32_t)TADR_DFSDM1_CHANNEL0_BASE;
+	hAudioInTopRightChannel.Init.OutClockActivation       = 1 /* ENABLE*/;
+	hAudioInTopRightChannel.Init.OutClockSelection        = DFSDM_CHANNEL_OUTPUT_CLOCK_AUDIO;
+	/* Set the DFSDM clock OUT audio frequency configuration */
+	hAudioInTopRightChannel.Init.OutClockDivider          = DFSDM_CLOCK_DIVIDER(AudioFreq);
+	hAudioInTopRightChannel.Init.InputMultiplexer         = DFSDM_CHANNEL_EXTERNAL_INPUTS;
+	hAudioInTopRightChannel.Init.InputDataPacking         = DFSDM_CHANNEL_STANDARD_MODE;
+	hAudioInTopRightChannel.Init.InputPins                = DFSDM_CHANNEL_FOLLOWING_CHANNEL_PINS;
+	/* Request to sample stable data for RIGHT micro on Falling edge */
+	hAudioInTopRightChannel.Init.SerialType               = DFSDM_CHANNEL_SPI_FALLING;
+	hAudioInTopRightChannel.Init.SerialSpiClock           = DFSDM_CHANNEL_SPI_CLOCK_INTERNAL;
+	hAudioInTopRightChannel.Init.AwdFilterOrder           = DFSDM_CHANNEL_FASTSINC_ORDER;
+	hAudioInTopRightChannel.Init.AwdOversampling          = 10;
+	hAudioInTopRightChannel.Init.Offset                   = 0;
+	hAudioInTopRightChannel.Init.RightBitShift            = DFSDM_RIGHT_BIT_SHIFT(AudioFreq);
+	if(E_OK != (ercd = dfsdm_channel_init(&hAudioInTopRightChannel))){
+		return ercd;
+	}
+
+	if(AudioIn_ChannelNumber > 2){
+		/* CHANNEL 5 configuration */
+		hAudioInButtomLeftChannel.state                         = DFSDM_CHANNEL_STATE_RESET;
+		hAudioInButtomLeftChannel.base                          = (uint32_t)TADR_DFSDM1_CHANNEL5_BASE;
+		hAudioInButtomLeftChannel.Init.OutClockActivation       = 1 /* ENABLE */;
+		hAudioInButtomLeftChannel.Init.OutClockSelection        = DFSDM_CHANNEL_OUTPUT_CLOCK_AUDIO;
+		/* Set the DFSDM clock OUT audio frequency configuration */
+		hAudioInButtomLeftChannel.Init.OutClockDivider          = DFSDM_CLOCK_DIVIDER(AudioFreq);
+		hAudioInButtomLeftChannel.Init.InputMultiplexer         = DFSDM_CHANNEL_EXTERNAL_INPUTS;
+		hAudioInButtomLeftChannel.Init.InputDataPacking         = DFSDM_CHANNEL_STANDARD_MODE;
+		hAudioInButtomLeftChannel.Init.InputPins                = DFSDM_CHANNEL_SAME_CHANNEL_PINS;
+		/* Request to sample stable data for LEFT micro on Rising edge */
+		hAudioInButtomLeftChannel.Init.SerialType               = DFSDM_CHANNEL_SPI_RISING;
+		hAudioInButtomLeftChannel.Init.SerialSpiClock           = DFSDM_CHANNEL_SPI_CLOCK_INTERNAL;
+		hAudioInButtomLeftChannel.Init.AwdFilterOrder           = DFSDM_CHANNEL_FASTSINC_ORDER;
+		hAudioInButtomLeftChannel.Init.AwdOversampling          = 10;
+		hAudioInButtomLeftChannel.Init.Offset                   = 0;
+		hAudioInButtomLeftChannel.Init.RightBitShift            = DFSDM_RIGHT_BIT_SHIFT(AudioFreq);
+		if(E_OK != (ercd = dfsdm_channel_init(&hAudioInButtomLeftChannel))){
+			return ercd;
+		}
+
+		/* CHANNEL 4 configuration */
+		hAudioInButtomRightChannel.state                         = DFSDM_CHANNEL_STATE_RESET;
+		hAudioInButtomRightChannel.base                          = (uint32_t)TADR_DFSDM1_CHANNEL4_BASE;
+		hAudioInButtomRightChannel.Init.OutClockActivation       = 1 /* ENABLE */;
+		hAudioInButtomRightChannel.Init.OutClockSelection        = DFSDM_CHANNEL_OUTPUT_CLOCK_AUDIO;
+		/* Set the DFSDM clock OUT audio frequency configuration */
+		hAudioInButtomRightChannel.Init.OutClockDivider          = DFSDM_CLOCK_DIVIDER(AudioFreq);
+		hAudioInButtomRightChannel.Init.InputMultiplexer         = DFSDM_CHANNEL_EXTERNAL_INPUTS;
+		hAudioInButtomRightChannel.Init.InputDataPacking         = DFSDM_CHANNEL_STANDARD_MODE;
+		hAudioInButtomRightChannel.Init.InputPins                = DFSDM_CHANNEL_FOLLOWING_CHANNEL_PINS;
+		/* Request to sample stable data for RIGHT micro on Falling edge */
+		hAudioInButtomRightChannel.Init.SerialType               = DFSDM_CHANNEL_SPI_FALLING;
+		hAudioInButtomRightChannel.Init.SerialSpiClock           = DFSDM_CHANNEL_SPI_CLOCK_INTERNAL;
+		hAudioInButtomRightChannel.Init.AwdFilterOrder           = DFSDM_CHANNEL_FASTSINC_ORDER;
+		hAudioInButtomRightChannel.Init.AwdOversampling          = 10;
+		hAudioInButtomRightChannel.Init.Offset                   = 0;
+		hAudioInButtomRightChannel.Init.RightBitShift            = DFSDM_RIGHT_BIT_SHIFT(AudioFreq);
+		if(E_OK != (ercd = dfsdm_channel_init(&hAudioInButtomRightChannel))){
+			return ercd;
+		}
+	}
+	/****************************************************************************/ 
+	/********************** Filters configuration  ******************************/
+	/****************************************************************************/
+	/* FILTER 0 configuration */
+	hAudioInTopLeftFilter.state                             = DFSDM_FILTER_STATE_RESET;
+	hAudioInTopLeftFilter.base                              = (uint32_t)AUDIO_DFSDMx_TOP_LEFT_FILTER;
+	hAudioInTopLeftFilter.regconvhalfcallback               = HAL_DFSDM_FilterRegConvHalfCpltCallback;
+	hAudioInTopLeftFilter.regconvcallback                   = HAL_DFSDM_FilterRegConvCpltCallback;
+	hAudioInTopLeftFilter.Init.RegTrigger                   = DFSDM_FILTER_SW_TRIGGER;
+	hAudioInTopLeftFilter.Init.RegFastMode                  = 1 /* ENABLE */;
+	hAudioInTopLeftFilter.Init.RegDmaMode                   = 1 /* ENABLE */;
+	hAudioInTopLeftFilter.Init.InjTrigger                   = DFSDM_FILTER_SW_TRIGGER;
+	hAudioInTopLeftFilter.Init.InjScanMode                  = 1 /* ENABLE */;
+	hAudioInTopLeftFilter.Init.InjDmaMode                   = 0 /* DISABLE */;
+	hAudioInTopLeftFilter.Init.InjExtTrigger                = DFSDM_FILTER_EXT_TRIG_TIM1_TRGO;
+	hAudioInTopLeftFilter.Init.InjExtTriggerEdge            = DFSDM_FILTER_EXT_TRIG_RISING_EDGE;
+	hAudioInTopLeftFilter.Init.FilterSincOrder              = DFSDM_FILTER_ORDER(AudioFreq);
+	/* Set the DFSDM Filters Oversampling to have correct sample rate */
+	hAudioInTopLeftFilter.Init.FilterOversampling           = DFSDM_OVER_SAMPLING(AudioFreq);
+	hAudioInTopLeftFilter.Init.FilterIntOversampling        = 1;
+	if(E_OK != (ercd = dfsdm_filter_init(&hAudioInTopLeftFilter))){
+		return ercd;
+	}
+
+	/* Configure injected channel */
+	if(E_OK != (ercd = dfsdm_filter_config_reg(&hAudioInTopLeftFilter, AUDIO_DFSDMx_TOP_LEFT_CHANNEL, DFSDM_CONTINUOUS_CONV_ON))){
+		return ercd;
+	}
+
+	/* FILTER 1 configuration */
+	hAudioInTopRightFilter.state                             = DFSDM_FILTER_STATE_RESET;
+	hAudioInTopRightFilter.base                              = (uint32_t)AUDIO_DFSDMx_TOP_RIGHT_FILTER;
+	hAudioInTopRightFilter.regconvhalfcallback               = HAL_DFSDM_FilterRegConvHalfCpltCallback;
+	hAudioInTopRightFilter.regconvcallback                   = HAL_DFSDM_FilterRegConvCpltCallback;
+	hAudioInTopRightFilter.Init.RegTrigger                   = DFSDM_FILTER_SYNC_TRIGGER;
+	hAudioInTopRightFilter.Init.RegFastMode                  = 1 /* ENABLE */;
+	hAudioInTopRightFilter.Init.RegDmaMode                   = 1 /* ENABLE */;
+	hAudioInTopRightFilter.Init.InjTrigger                   = DFSDM_FILTER_SW_TRIGGER;
+	hAudioInTopRightFilter.Init.InjScanMode                  = 0 /* DISABLE */;
+	hAudioInTopRightFilter.Init.InjDmaMode                   = 0 /* DISABLE */;
+	hAudioInTopRightFilter.Init.InjExtTrigger                = DFSDM_FILTER_EXT_TRIG_TIM1_TRGO;
+	hAudioInTopRightFilter.Init.InjExtTriggerEdge            = DFSDM_FILTER_EXT_TRIG_RISING_EDGE;
+	hAudioInTopRightFilter.Init.FilterSincOrder              = DFSDM_FILTER_ORDER(AudioFreq);
+	/* Set the DFSDM Filters Oversampling to have correct sample rate */
+	hAudioInTopRightFilter.Init.FilterOversampling           = DFSDM_OVER_SAMPLING(AudioFreq);
+	hAudioInTopRightFilter.Init.FilterIntOversampling        = 1;
+	if(E_OK != (ercd = dfsdm_filter_init(&hAudioInTopRightFilter))){
+		return ercd;
+	}
+	/* Configure injected channel */
+	if(E_OK != (ercd = dfsdm_filter_config_reg(&hAudioInTopRightFilter, AUDIO_DFSDMx_TOP_RIGHT_CHANNEL, DFSDM_CONTINUOUS_CONV_ON))){
+		return ercd;
+	}
+
+	if(AudioIn_ChannelNumber > 2){
+		/* FILTER 2 configuration */
+		hAudioInButtomLeftFilter.state                             = DFSDM_FILTER_STATE_RESET;
+		hAudioInButtomLeftFilter.base                              = (uint32_t)AUDIO_DFSDMx_BUTTOM_LEFT_FILTER;
+		hAudioInButtomLeftFilter.regconvhalfcallback               = HAL_DFSDM_FilterRegConvHalfCpltCallback;
+		hAudioInButtomLeftFilter.regconvcallback                   = HAL_DFSDM_FilterRegConvCpltCallback;
+		hAudioInButtomLeftFilter.Init.RegTrigger                   = DFSDM_FILTER_SYNC_TRIGGER;
+		hAudioInButtomLeftFilter.Init.RegFastMode                  = 1 /* ENABLE */;
+		hAudioInButtomLeftFilter.Init.RegDmaMode                   = 1 /* ENABLE */;
+		hAudioInButtomLeftFilter.Init.InjTrigger                   = DFSDM_FILTER_SW_TRIGGER;
+		hAudioInButtomLeftFilter.Init.InjScanMode                  = 1 /* ENABLE */;
+		hAudioInButtomLeftFilter.Init.InjDmaMode                   = 0 /* DISABLE */;
+		hAudioInButtomLeftFilter.Init.InjExtTrigger                = DFSDM_FILTER_EXT_TRIG_TIM1_TRGO;
+		hAudioInButtomLeftFilter.Init.InjExtTriggerEdge            = DFSDM_FILTER_EXT_TRIG_RISING_EDGE;
+		hAudioInButtomLeftFilter.Init.FilterSincOrder              = DFSDM_FILTER_ORDER(AudioFreq);
+		/* Set the DFSDM Filters Oversampling to have correct sample rate */
+		hAudioInButtomLeftFilter.Init.FilterOversampling           = DFSDM_OVER_SAMPLING(AudioFreq);
+		hAudioInButtomLeftFilter.Init.FilterIntOversampling        = 1;
+		if(E_OK != (ercd = dfsdm_filter_init(&hAudioInButtomLeftFilter))){
+			return ercd;
+		}
+
+		/* Configure injected channel */
+		if(E_OK != (ercd = dfsdm_filter_config_reg(&hAudioInButtomLeftFilter, AUDIO_DFSDMx_BUTTOM_LEFT_CHANNEL, DFSDM_CONTINUOUS_CONV_ON))){
+			return ercd;
+		}
+
+		/* FILTER 3 configuration */
+		hAudioInButtomRightFilter.state                             = DFSDM_FILTER_STATE_RESET;
+		hAudioInButtomRightFilter.base                              = (uint32_t)AUDIO_DFSDMx_BUTTOM_RIGHT_FILTER;
+		hAudioInButtomRightFilter.regconvhalfcallback               = HAL_DFSDM_FilterRegConvHalfCpltCallback;
+		hAudioInButtomRightFilter.regconvcallback                   = HAL_DFSDM_FilterRegConvCpltCallback;
+		hAudioInButtomRightFilter.Init.RegTrigger                   = DFSDM_FILTER_SYNC_TRIGGER;
+		hAudioInButtomRightFilter.Init.RegFastMode                  = 1 /* ENABLE */;
+		hAudioInButtomRightFilter.Init.RegDmaMode                   = 1 /* ENABLE */;
+		hAudioInButtomRightFilter.Init.InjTrigger                   = DFSDM_FILTER_SW_TRIGGER;
+		hAudioInButtomRightFilter.Init.InjScanMode                  = 0 /* DISABLE */;
+		hAudioInButtomRightFilter.Init.InjDmaMode                   = 0 /* DISABLE */;
+		hAudioInButtomRightFilter.Init.InjExtTrigger                = DFSDM_FILTER_EXT_TRIG_TIM1_TRGO;
+		hAudioInButtomRightFilter.Init.InjExtTriggerEdge            = DFSDM_FILTER_EXT_TRIG_RISING_EDGE;
+		hAudioInButtomRightFilter.Init.FilterSincOrder              = DFSDM_FILTER_ORDER(AudioFreq);
+		/* Set the DFSDM Filters Oversampling to have correct sample rate */
+		hAudioInButtomRightFilter.Init.FilterOversampling           = DFSDM_OVER_SAMPLING(AudioFreq);
+		hAudioInButtomRightFilter.Init.FilterIntOversampling        = 1;
+		if(E_OK != (ercd = dfsdm_filter_init(&hAudioInButtomRightFilter))){
+			return ercd;
+		}
+		/* Configure injected channel */
+		if(E_OK != (ercd = dfsdm_filter_config_reg(&hAudioInButtomRightFilter, AUDIO_DFSDMx_BUTTOM_RIGHT_CHANNEL, DFSDM_CONTINUOUS_CONV_ON))){
+			return ercd;
+		}
+	}
+	return ercd;
+}
+
+/**
+  * @brief  De-initialize the Digital Filter for Sigma-Delta Modulators interface (DFSDM).
+  * @retval AUDIO_OK if correct communication, else wrong communication
+  */
+static ER DFSDMx_DeInit(void)
+{
+	ER ercd = E_OK;
+
+	/* De-initializes the DFSDM filters to allow access to DFSDM internal registers */
+	if(E_OK != (ercd = dfsdm_filter_deinit(&hAudioInTopLeftFilter))){
+		return ercd;
+	}
+	if(E_OK != (ercd = dfsdm_filter_deinit(&hAudioInTopRightFilter))){
+		return ercd;
+	}
+
+	/* De-initializes the DFSDM channels to allow access to DFSDM internal registers */
+	if(E_OK != (ercd = dfsdm_channel_deinit(&hAudioInTopLeftChannel))){
+		return ercd;
+	}
+	if(E_OK != (ercd = dfsdm_channel_deinit(&hAudioInTopRightChannel))){
+		return ercd;
+  }
+
+	if(AudioIn_ChannelNumber > 2){
+		/* De-initializes the DFSDM filters to allow access to DFSDM internal registers */        
+		if(E_OK != (ercd = dfsdm_filter_deinit(&hAudioInButtomLeftFilter))){
+			return ercd;
+		}
+		if(E_OK != (ercd = dfsdm_filter_deinit(&hAudioInButtomRightFilter))){
+			return ercd;
+		}
+
+		/* De-initializes the DFSDM channels to allow access to DFSDM internal registers */  
+		if(E_OK != (ercd = dfsdm_channel_deinit(&hAudioInButtomLeftChannel))){
+			return ercd;
+		}
+		if(E_OK != (ercd = dfsdm_channel_deinit(&hAudioInButtomRightChannel))){
+			return ercd;
+		}
+	}
+	return ercd;
+}
+
+/**
+  * @brief  Initialize the DFSDM channel MSP.
+  * @param  hdfsdm_channel : DFSDM channel handle.
+  * @retval None
+  */
+static void DFSDMx_ChannelMspInit(void)
+{
+	GPIO_Init_t  GPIO_InitStruct;
+
+	/* Enable DFSDM clock */
+	sil_orw_mem((uint32_t *)(TADR_RCC_BASE+TOFF_RCC_APB2ENR), RCC_APB2ENR_DFSDM1EN);
+
+	/* Enable GPIO clock */
+	AUDIO_DFSDMx_DMIC_DATIN_GPIO_CLK_ENABLE();
+	AUDIO_DFSDMx_CKOUT_DMIC_GPIO_CLK_ENABLE();
+
+	/* DFSDM pins configuration: DFSDM_CKOUT, DMIC_DATIN1 pins ------------------*/
+	GPIO_InitStruct.mode = GPIO_MODE_AF;
+	GPIO_InitStruct.pull = GPIO_NOPULL;
+	GPIO_InitStruct.otype = GPIO_OTYPE_PP;
+	GPIO_InitStruct.speed = GPIO_SPEED_HIGH;
+	GPIO_InitStruct.alternate = AUDIO_DFSDMx_CKOUT_AF;
+	gpio_setup((uint32_t)AUDIO_DFSDMx_CKOUT_DMIC_GPIO_PORT, &GPIO_InitStruct, AUDIO_DFSDMx_CKOUT_PINNO);
+
+	/* DFSDM pin configuration: DMIC_DATIN1 pin --------------------------------*/
+	GPIO_InitStruct.alternate = AUDIO_DFSDMx_DMIC_DATIN_AF;
+	gpio_setup((uint32_t)AUDIO_DFSDMx_DMIC_DATIN_GPIO_PORT, &GPIO_InitStruct, AUDIO_DFSDMx_DMIC_DATIN1_PINNO);
+
+	if(AudioIn_ChannelNumber > 2){
+		/* DFSDM pin configuration: DMIC_DATIN5 pin --------------------------------*/  
+		GPIO_InitStruct.alternate = AUDIO_DFSDMx_DMIC_DATIN_AF;
+		gpio_setup((uint32_t)AUDIO_DFSDMx_DMIC_DATIN_GPIO_PORT, &GPIO_InitStruct, AUDIO_DFSDMx_DMIC_DATIN5_PINNO);
+	}
+}
+
+/**
+  * @brief  Initialize the DFSDM filter MSP.
+  * @param  hdfsdm_filter : DFSDM filter handle.
+  * @retval None
+  */
+static void DFSDMx_FilterMspInit(void)
+{
+	/* Enable DFSDM clock */
+	sil_orw_mem((uint32_t *)(TADR_RCC_BASE+TOFF_RCC_APB2ENR), RCC_APB2ENR_DFSDM1EN);
+
+	/* Enable the DMA clock */
+	sil_orw_mem((uint32_t *)(TADR_RCC_BASE+TOFF_RCC_AHB1ENR), RCC_AHB1ENR_DMA2EN);
+
+	/*********** Configure DMA stream for TOP LEFT microphone *******************/
+	hDmaTopLeft.Init.Direction           = DMA_PERIPH_TO_MEMORY;
+	hDmaTopLeft.Init.PeriphInc           = DMA_PINC_DISABLE;
+	hDmaTopLeft.Init.MemInc              = DMA_MINC_ENABLE;
+	hDmaTopLeft.Init.PeriphDataAlignment = AUDIO_DFSDMx_DMAx_PERIPH_DATA_SIZE;
+	hDmaTopLeft.Init.MemDataAlignment    = AUDIO_DFSDMx_DMAx_MEM_DATA_SIZE;
+	hDmaTopLeft.Init.Mode                = DMA_CIRCULAR;
+	hDmaTopLeft.Init.Priority            = DMA_PRIORITY_HIGH;
+	hDmaTopLeft.base                     = (uint32_t)TADR_DMA2_STM4_BASE;
+	hDmaTopLeft.Init.Channel             = AUDIO_DFSDMx_DMAx_CHANNEL; 
+
+	/* Associate the DMA handle */
+	hAudioInTopLeftFilter.hdmaReg = &hDmaTopLeft;
+	hDmaTopLeft.localdata = &hAudioInTopLeftFilter;
+
+	/* Reset DMA handle state */
+	hDmaTopLeft.status = 0;
+
+	/* Configure the DMA Channel */
+	dma_init(&hDmaTopLeft);
+
+	/*********** Configure DMA stream for TOP RIGHT microphone ******************/
+	hDmaTopRight.Init.Direction           = DMA_PERIPH_TO_MEMORY;
+	hDmaTopRight.Init.PeriphInc           = DMA_PINC_DISABLE;
+	hDmaTopRight.Init.MemInc              = DMA_MINC_ENABLE;
+	hDmaTopRight.Init.PeriphDataAlignment = AUDIO_DFSDMx_DMAx_PERIPH_DATA_SIZE;
+	hDmaTopRight.Init.MemDataAlignment    = AUDIO_DFSDMx_DMAx_MEM_DATA_SIZE;
+	hDmaTopRight.Init.Mode                = DMA_CIRCULAR;
+	hDmaTopRight.Init.Priority            = DMA_PRIORITY_HIGH;  
+	hDmaTopRight.base                     = (uint32_t)TADR_DMA2_STM1_BASE;
+	hDmaTopRight.Init.Channel             = AUDIO_DFSDMx_DMAx_CHANNEL;
+
+	/* Associate the DMA handle */
+	hAudioInTopRightFilter.hdmaReg        = &hDmaTopRight;
+	hDmaTopRight.localdata                = &hAudioInTopRightFilter;
+
+	/* Reset DMA handle state */
+	hDmaTopRight.status = 0;
+
+	/* Configure the DMA Channel */
+	dma_init(&hDmaTopRight);
+
+	if(AudioIn_ChannelNumber > 2){
+		/*********** Configure DMA stream for BUTTOM LEFT microphone ****************/
+		hDmaButtomLeft.Init.Direction           = DMA_PERIPH_TO_MEMORY;
+		hDmaButtomLeft.Init.PeriphInc           = DMA_PINC_DISABLE;
+		hDmaButtomLeft.Init.MemInc              = DMA_MINC_ENABLE;
+		hDmaButtomLeft.Init.PeriphDataAlignment = AUDIO_DFSDMx_DMAx_PERIPH_DATA_SIZE;
+		hDmaButtomLeft.Init.MemDataAlignment    = AUDIO_DFSDMx_DMAx_MEM_DATA_SIZE;
+		hDmaButtomLeft.Init.Mode                = DMA_CIRCULAR;
+		hDmaButtomLeft.Init.Priority            = DMA_PRIORITY_HIGH;
+		hDmaButtomLeft.base                     = (uint32_t)AUDIO_DFSDMx_DMAx_BUTTOM_LEFT_STREAM;
+		hDmaButtomLeft.Init.Channel             = AUDIO_DFSDMx_DMAx_CHANNEL; 
+
+		/* Associate the DMA handle */
+		hAudioInButtomLeftFilter.hdmaReg        = &hDmaButtomLeft;
+		hDmaButtomLeft.localdata                = &hAudioInButtomLeftFilter;
+
+		/* Reset DMA handle state */
+		hDmaButtomLeft.status = 0;
+
+		/* Configure the DMA Channel */
+		dma_init(&hDmaButtomLeft);
+
+		/*********** Configure DMA stream for BUTTOM RIGHT microphone ***************/
+		hDmaButtomRight.Init.Direction           = DMA_PERIPH_TO_MEMORY;
+		hDmaButtomRight.Init.PeriphInc           = DMA_PINC_DISABLE;
+		hDmaButtomRight.Init.MemInc              = DMA_MINC_ENABLE;
+		hDmaButtomRight.Init.PeriphDataAlignment = AUDIO_DFSDMx_DMAx_PERIPH_DATA_SIZE;
+		hDmaButtomRight.Init.MemDataAlignment    = AUDIO_DFSDMx_DMAx_MEM_DATA_SIZE;
+		hDmaButtomRight.Init.Mode                = DMA_CIRCULAR;
+		hDmaButtomRight.Init.Priority            = DMA_PRIORITY_HIGH;  
+		hDmaButtomRight.base                     = (uint32_t)AUDIO_DFSDMx_DMAx_BUTTOM_RIGHT_STREAM;
+		hDmaButtomRight.Init.Channel             = AUDIO_DFSDMx_DMAx_CHANNEL;
+
+		/* Associate the DMA handle */
+		hAudioInButtomRightFilter.hdmaReg        = &hDmaButtomRight;
+		hDmaButtomRight.localdata                = &hAudioInButtomRightFilter;
+
+		/* Reset DMA handle state */
+		hDmaButtomRight.status = 0;
+
+		/* Configure the DMA Channel */
+		dma_init(&hDmaButtomRight);
+	}
+}
+
+/**
+  * @brief  DeInitialize the DFSDM filter MSP.
+  * @param  hdfsdm_filter : DFSDM filter handle.
+  * @retval None
+  */
+static void DFSDMx_FilterMspDeInit(void)
+{
+	/* Configure the DMA Channel */
+	dma_deinit(&hDmaTopLeft);
+	dma_deinit(&hDmaTopRight);
+	if(AudioIn_ChannelNumber > 2){
+		dma_deinit(&hDmaButtomLeft);
+		dma_deinit(&hDmaButtomRight);
+	}
+}
+
+void dfsdm1fl0_handler(void)
+{
+	dfsdm_irqhandler(&hAudioInTopLeftFilter);
+}
+
+void dfsdm1fl1_handler(void)
+{
+	dfsdm_irqhandler(&hAudioInTopRightFilter);
+}
+
+void dfsdm1fl2_handler(void)
+{
+	dfsdm_irqhandler(&hAudioInButtomLeftFilter);
+}
+
+void dfsdm1fl3_handler(void)
+{
+	dfsdm_irqhandler(&hAudioInButtomRightFilter);
+}
+
+#endif
+
+/*
+ *  オーディオ入力初期化設定
+ *  param1: STAUDIOハンドラ
+ *  param2: 入力デバイス設定
+ *  param3: オーディオ周波数値
+ *  param4: BitRes
+ *  param5: チャネル番号
+ *  return: E_OKで正常設定
+ */
+ER
+staudio_in_init(STAUDIO_Handle_t *haudio, uint16_t InputDevice, uint32_t AudioFreq, uint32_t BitRes, uint32_t ChnlNbr)
+{
+	ER       ercd = E_OK;
+	uint32_t slot_active;
+
+	haudio->InputDevice = InputDevice;
+	if(InputDevice == INPUT_DEVICE_DIGITAL_MIC){
+#ifdef TOPPERS_STM32F769_DISCOVERY
+		AudioIn_ChannelNumber = ChnlNbr;
+		/* PLL clock is set depending by the AudioFreq (44.1khz vs 48khz groups) */ 
+		dfsdm_clockconfig(AUDIO2_PORTID, AudioFreq);
+		sil_modw_mem((uint32_t *)(TADR_RCC_BASE+TOFF_RCC_DCKCFGR1), RCC_DCKCFGR1_ADFSDM1SEL, (uint32_t)(RCC_DCKCFGR1_ADFSDM1SEL));
+
+		/* Init the SAI MSP: this __weak function can be redefined by the application*/
+		/* MSP channels initialization */
+		DFSDMx_ChannelMspInit();
+		/* MSP filters initialization */
+		DFSDMx_FilterMspInit();
+
+		/* Initializes DFSDM peripheral */
+		DFSDMx_Init(AudioFreq);
+		hstaudio = haudio;
+		ercd = E_OK;
+#else
+		ercd = E_PAR;
+#endif
+	}
+	/* Only INPUT_LINE_1, MICROPHONE_1, MICROPHONE_2 and MIC1&MIC2 inputs supported */
+	else if((InputDevice != INPUT_DEVICE_INPUT_LINE_1) &&       
+		(InputDevice != INPUT_DEVICE_DIGITAL_MICROPHONE_1) &&
+		(InputDevice != INPUT_DEVICE_DIGITAL_MICROPHONE_2) &&
+		(InputDevice != INPUT_DEVICE_DIGITAL_MIC1_MIC2)){
+		ercd = E_PAR;
+	}
+	else{
+		/* PLL clock is set depending on the AudioFreq (44.1khz vs 48khz groups) */
+		if(haudio->hsai == NULL){
+			haudio->hsai = audio_init(haudio->saiid);
+		}
+		else{
+			/* Disable SAI peripheral */
+			audio_disable(haudio->hsai, AUDIO_IN_BLOCK);
+			audio_end(haudio->hsai, AUDIO_IN_BLOCK);
+		}
+		audio_clockconfig(haudio->hsai, AudioFreq, NULL); /* Clock config is shared between AUDIO IN and OUT */
+
+		/* Configure SAI in master RX mode :
+		 *   - SAI2_block_A in master RX mode
+		 *   - SAI2_block_B in slave RX mode synchronous from SAI2_block_A
+		 */
+		if(InputDevice == INPUT_DEVICE_DIGITAL_MICROPHONE_2){
+			slot_active = CODEC_AUDIOFRAME_SLOT_13;
+		}
+		else if(InputDevice == INPUT_DEVICE_DIGITAL_MIC1_MIC2){
+			slot_active = CODEC_AUDIOFRAME_SLOT_0123;
+		}
+		else{
+			slot_active = CODEC_AUDIOFRAME_SLOT_02;
+		}
+		SAIx_In_Init(haudio, SAI_MODEMASTER_RX, slot_active, AudioFreq);
+
+		/* wm8994 codec initialization */
+		ercd = wm8994_Reset(haudio);
+		if(ercd == E_OK){
+			/* Initialize the codec internal registers */
+			wm8994_Init(haudio, InputDevice, haudio->AudioInVolume, AudioFreq);
+		}
+	}
+	return ercd;
+}
+
+#ifndef TOPPERS_STM32F769_DISCOVERY
+/*
+ *  オーディオ入出力初期化設定
+ *  param1: STAUDIOハンドラ
+ *  param2: 入力デバイス設定
+ *  param3: 出力デバイス設定
+ *  param4: オーディオ周波数値
+ *  param5: BitRes
+ *  param6: チャネル番号
+ *  return: E_OKで正常設定
+ */
+ER
+staudio_in_out_init(STAUDIO_Handle_t *haudio, uint16_t InputDevice, uint16_t OutputDevice, uint32_t AudioFreq, uint32_t BitRes, uint32_t ChnlNbr)
+{
+	ER       ercd = E_OK;
+	uint32_t slot_active;
+
+	haudio->InputDevice = InputDevice;
+	/* Only INPUT_LINE_1, MICROPHONE_1, MICROPHONE_2 and MIC1&MIC2 inputs supported */
+	if ((InputDevice != INPUT_DEVICE_INPUT_LINE_1) &&       
+		(InputDevice != INPUT_DEVICE_DIGITAL_MICROPHONE_1) &&
+		(InputDevice != INPUT_DEVICE_DIGITAL_MICROPHONE_2) &&
+		(InputDevice != INPUT_DEVICE_DIGITAL_MIC1_MIC2)){
+		ercd = E_PAR;
+	}
+	else{
+		/* PLL clock is set depending on the AudioFreq (44.1khz vs 48khz groups) */
+		if(haudio->hsai == NULL){
+			haudio->hsai = audio_init(haudio->saiid);
+		}
+		else{
+			/* Disable SAI peripheral */
+			audio_disable(haudio->hsai, AUDIO_IN_BLOCK);
+			audio_end(haudio->hsai, AUDIO_IN_BLOCK);
+		}
+		audio_clockconfig(haudio->hsai, AudioFreq, NULL); /* Clock config is shared between AUDIO IN and OUT */
+
+		/* Configure SAI in master RX mode :
+		 *   - SAI2_block_A in master RX mode
+		 *   - SAI2_block_B in slave RX mode synchronous from SAI2_block_A
+		 */
+		if(InputDevice == INPUT_DEVICE_DIGITAL_MICROPHONE_2){
+			slot_active = CODEC_AUDIOFRAME_SLOT_13;
+		}
+		else if(InputDevice == INPUT_DEVICE_DIGITAL_MIC1_MIC2){
+			slot_active = CODEC_AUDIOFRAME_SLOT_0123;
+		}
+		else{
+			slot_active = CODEC_AUDIOFRAME_SLOT_02;
+		}
+		SAIx_In_Init(haudio, SAI_MODEMASTER_RX, slot_active, AudioFreq);
+
+		/* wm8994 codec initialization */
+		ercd = wm8994_Reset(haudio);
+		if(ercd == E_OK){
+			/* Initialize the codec internal registers */
+			wm8994_Init(haudio, InputDevice | OutputDevice, haudio->AudioInVolume, AudioFreq);
+		}
+	}
+	return ercd;
+}
+#endif
+
+/*
+ *  オーディオ録音開始設定
+ *  param1: STAUDIOハンドラ
+ *  param2: 入力バッファポインタ
+ *  param3: 入力バッファサイズ
+ *  return: E_OKで正常設定
+ */
+ER
+staudio_in_record(STAUDIO_Handle_t *haudio, uint16_t* pbuf, uint32_t size)
+{
+	AUDIO_Handle_t  *hsai = haudio->hsai;
+	ER ercd = E_OK;
+
+#ifdef TOPPERS_STM32F769_DISCOVERY
+	if(haudio->InputDevice == INPUT_DEVICE_DIGITAL_MIC){
+		hAudioIn.pRecBuf = pbuf;
+		hAudioIn.RecSize = size;
+		/* Reset Application Buffer Trigger */
+		AppBuffTrigger = 0;
+		AppBuffHalf = 0;
+
+		if(AudioIn_ChannelNumber > 2){
+			/* Call the Media layer start function for buttom right channel */
+			if(E_OK != (ercd = dfsdm_filterRegularStart(&hAudioInButtomRightFilter, pScratchBuff[2], ScratchSize))){
+				return ercd;
+			}
+			/* Call the Media layer start function for buttom left channel */
+			if(E_OK != (ercd = dfsdm_filterRegularStart(&hAudioInButtomLeftFilter, pScratchBuff[3], ScratchSize))){
+				return ercd;
+			}
+		}
+		/* Call the Media layer start function for top right channel */
+		if(E_OK != (ercd = dfsdm_filterRegularStart(&hAudioInTopRightFilter, pScratchBuff[0], ScratchSize))){
+			return ercd;
+		}
+		/* Call the Media layer start function for top left channel */
+		if(E_OK != (ercd = dfsdm_filterRegularStart(&hAudioInTopLeftFilter, pScratchBuff[1], ScratchSize))){
+			return ercd;
+		}
+		return ercd;
+	}
+#endif
+	/* Start the process receive DMA */
+	hsai->recevcallback = (void (*)(AUDIO_Handle_t *hsai))haudio->audio_fullin_func;
+	hsai->recevhalfcallback = (void (*)(AUDIO_Handle_t *hsai))haudio->audio_halfin_func;
+	hsai->errorcallback = haudio->audio_error_func;
+	ercd = audio_receive(hsai, (uint8_t*)pbuf, size);
+	return ercd;
+}
+
+/*
+ *  オーディオ録音停止設定
+ *  param1: STAUDIOハンドラ
+ *  param2: 終了オプション
+ *  return: E_OKで正常設定
+ */
+ER
+staudio_in_stop(STAUDIO_Handle_t *haudio, uint32_t Option)
+{
+#ifdef TOPPERS_STM32F769_DISCOVERY
+	ER ercd = E_OK;
+	if(haudio->InputDevice == INPUT_DEVICE_DIGITAL_MIC){
+		AppBuffTrigger = 0;
+		AppBuffHalf    = 0;
+		if(AudioIn_ChannelNumber > 2){
+			/* Call the Media layer stop function for buttom right channel */
+			if(E_OK != (ercd = dfsdm_filterRegularStop(&hAudioInButtomRightFilter))){
+				return ercd;
+			}
+			/* Call the Media layer stop function for buttom left channel */
+			if(E_OK != (ercd = dfsdm_filterRegularStop(&hAudioInButtomLeftFilter))){
+				return ercd;
+			}
+		}
+		/* Call the Media layer stop function for top right channel */
+		if(E_OK != (ercd = dfsdm_filterRegularStop(&hAudioInTopRightFilter))){
+			return ercd;
+		}
+		/* Call the Media layer stop function for top left channel */
+		if(E_OK != (ercd = dfsdm_filterRegularStop(&hAudioInTopLeftFilter))){
+			return ercd;
+		}
+		return ercd;
+	}
+#endif
+	/* Call the Media layer stop function */
+	audio_dmastop(haudio->hsai, AUDIO_IN_BLOCK);
+
+	/* Call Audio Codec Stop function */
+	if(wm8994_Stop(haudio, Option) != 0){
+		return E_SYS;
+	}
+	else{
+		if(Option == CODEC_PDWN_HW){
+			/* Wait at least 100us */
+			dly_tsk(1);
+		}
+		/* Return AUDIO_OK when all operations are correctly done */
+		return E_OK;
+	}
+}
+
+/*
+ *  オーディオ録音PAUSE設定
+ *  param1: STAUDIOハンドラ
+ *  return: E_OKで正常設定
+ */
+ER
+staudio_in_pause(STAUDIO_Handle_t *haudio)
+{
+#ifdef TOPPERS_STM32F769_DISCOVERY
+	ER ercd = E_OK;
+	if(haudio->InputDevice == INPUT_DEVICE_DIGITAL_MIC){
+		if(AudioIn_ChannelNumber > 2){
+			/* Call the Media layer stop function */
+			if(E_OK != (ercd = dfsdm_filterRegularStop(&hAudioInButtomRightFilter))){
+				return ercd;
+			}
+			/* Call the Media layer stop function */
+			if(E_OK != (ercd = dfsdm_filterRegularStop(&hAudioInButtomLeftFilter))){
+				return ercd;
+			}
+		}
+		/* Call the Media layer stop function */
+		if(E_OK != (ercd = dfsdm_filterRegularStop(&hAudioInTopRightFilter))){
+			return ercd;
+		}
+		/* Call the Media layer stop function */
+		if(E_OK != (ercd = dfsdm_filterRegularStop(&hAudioInTopLeftFilter))){
+			return ercd;
+		}
+		/* Return AUDIO_OK when all operations are correctly done */
+		return ercd;
+	}
+#endif
+	/* Call the Media layer pause function */
+	return audio_dmapause(haudio->hsai, AUDIO_IN_BLOCK);
+}
+
+/*
+ *  オーディオ録音RESUME設定
+ *  param1: STAUDIOハンドラ
+ *  return: E_OKで正常設定
+ */
+ER
+staudio_in_resume(STAUDIO_Handle_t *haudio)
+{
+#ifdef TOPPERS_STM32F769_DISCOVERY
+	ER ercd = E_OK;
+	if(haudio->InputDevice == INPUT_DEVICE_DIGITAL_MIC){
+		if(AudioIn_ChannelNumber > 2){
+			/* Call the Media layer start function for buttom right channel */
+			if(E_OK != (ercd = dfsdm_filterRegularStart(&hAudioInButtomRightFilter, pScratchBuff[2], ScratchSize))){
+				return ercd;
+			}
+			/* Call the Media layer start function for buttom left channel */
+			if(E_OK != (ercd = dfsdm_filterRegularStart(&hAudioInButtomLeftFilter, pScratchBuff[3], ScratchSize))){
+				return ercd;
+			}
+		}
+		/* Call the Media layer start function for top right channel */
+		if(E_OK != (ercd = dfsdm_filterRegularStart(&hAudioInTopRightFilter, pScratchBuff[0], ScratchSize))){
+			return ercd;
+		}
+		/* Call the Media layer start function for top left channel */
+		if(E_OK != (ercd = dfsdm_filterRegularStart(&hAudioInTopLeftFilter, pScratchBuff[1], ScratchSize))){
+			return ercd;
+		}
+		/* Return AUDIO_OK when all operations are correctly done */
+		return ercd;
+	}
+#endif
+	/* Call the Media layer pause/resume function */
+	return audio_dmaresume(haudio->hsai, AUDIO_IN_BLOCK);
+}
+
+/*
+ *  オーディオ録音終了設定
+ *  param1: STAUDIOハンドラ
+ */
+void
+staudio_in_deinit(STAUDIO_Handle_t *haudio)
+{
+#ifdef TOPPERS_STM32F769_DISCOVERY
+	if(haudio->InputDevice == INPUT_DEVICE_DIGITAL_MIC){
+		/* MSP filters initialization */
+		DFSDMx_FilterMspDeInit();
+		DFSDMx_DeInit();
+	}
+	else
+#endif
+	SAIx_In_DeInit(haudio);
+}
+
+#ifndef TOPPERS_STM32F769_DISCOVERY
+/*
+ *  オーディオ録音ボリューム設定
+ *  param1: STAUDIOハンドラ
+ *  param2: ボリューム値(0..100)
+ *  return: E_OKで正常設定
+ */
+ER
+staudio_in_setvolume(STAUDIO_Handle_t *haudio, uint8_t Volume)
+{
+	/* Call the codec volume control function with converted volume value */
+	if(wm8994_SetVolume(haudio, Volume) != 0){
+		return E_SYS;
+	}
+	else{
+		/* Set the Global variable AudioInVolume  */
+		haudio->AudioInVolume = Volume;
+		/* Return AUDIO_OK when all operations are correctly done */
+		return E_OK;
+	}
+}
+
+
+#else	/* TOPPERS_STM32F769_DISCOVERY  */
+/*
+ *  オーディオ録音スクラッチ領域E設定
+ *  param1: スクラッチ領域へのポインタ
+ *  param2: スクラッチ領域サイズ
+ *  return: E_OKで正常設定
+ */
+ER
+BSP_AUDIO_IN_AllocScratch(int32_t *pScratch, uint32_t size)
+{
+	uint32_t idx;
+
+	ScratchSize = (size / AudioIn_ChannelNumber);
+
+	/* copy scratch pointers */
+	for (idx = 0; idx < AudioIn_ChannelNumber; idx++){
+		pScratchBuff[idx] = (int32_t *)(pScratch + (idx * ScratchSize));
+	}
+	/* Return AUDIO_OK */
+	return E_OK;
+}
+
+/*
+ *  オーディオチャネル番号取り出し
+ *  return: チャネル番号
+ */
+uint8_t BSP_AUDIO_IN_GetChannelNumber(void)
+{
+  return AudioIn_ChannelNumber;
+}
+
+#endif
+
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/staudio_wm8994/staudio_wm8994.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/staudio_wm8994/staudio_wm8994.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/staudio_wm8994/staudio_wm8994.h	(revision 457)
@@ -0,0 +1,277 @@
+/*
+ *  TOPPERS BASE PLATFORM MIDDLEWARE
+ * 
+ *  Copyright (C) 2017-2018 by TOPPERS PROJECT
+ *                             Educational Working Group.
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+/**
+  ******************************************************************************
+  * @attention
+  *
+  * <h2><center>&copy; COPYRIGHT(c) 2016 STMicroelectronics</center></h2>
+  *
+  * 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 STMicroelectronics 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 _STAUDIO_WM8994_H_
+#define _STAUDIO_WM8994_H_
+
+#ifdef __cplusplus
+ extern "C" {
+#endif 
+
+#include <kernel.h>
+#include <t_syslog.h>
+#include <t_stdlib.h>
+#include "device.h"
+#include "i2c.h"
+#include "sai.h"
+#ifdef TOPPERS_STM32F769_DISCOVERY
+#include "dfsdm.h"
+#endif
+
+/******************************************************************************/
+/***************************  Codec User defines ******************************/
+/******************************************************************************/
+/* Codec output DEVICE */
+#define OUTPUT_DEVICE_SPEAKER                 ((uint16_t)0x0001)
+#define OUTPUT_DEVICE_HEADPHONE               ((uint16_t)0x0002)
+#define OUTPUT_DEVICE_BOTH                    ((uint16_t)0x0003)
+#define OUTPUT_DEVICE_AUTO                    ((uint16_t)0x0004)
+#define INPUT_DEVICE_DIGITAL_MICROPHONE_1     ((uint16_t)0x0100)
+#define INPUT_DEVICE_DIGITAL_MICROPHONE_2     ((uint16_t)0x0200)
+#define INPUT_DEVICE_INPUT_LINE_1             ((uint16_t)0x0300)
+#define INPUT_DEVICE_INPUT_LINE_2             ((uint16_t)0x0400)
+#define INPUT_DEVICE_DIGITAL_MIC1_MIC2        ((uint16_t)0x0800)
+
+/* MP34DT01TR digital microphone on PCB top side */
+#define INPUT_DEVICE_DIGITAL_MIC       ((uint16_t)0)
+
+/* Volume Levels values */
+#define DEFAULT_VOLMIN                0x00
+#define DEFAULT_VOLMAX                0xFF
+#define DEFAULT_VOLSTEP               0x04
+
+#define AUDIO_PAUSE                   0
+#define AUDIO_RESUME                  1
+
+/* Codec POWER DOWN modes */
+#define CODEC_PDWN_HW                 1
+#define CODEC_PDWN_SW                 2
+
+/* MUTE commands */
+#define AUDIO_MUTE_ON                 1
+#define AUDIO_MUTE_OFF                0
+
+
+#define VOLUME_CONVERT(Volume)        (((Volume) > 100)? 100:((uint8_t)(((Volume) * 63) / 100)))
+#define VOLUME_IN_CONVERT(Volume)     (((Volume) >= 100)? 239:((uint8_t)(((Volume) * 240) / 100)))
+
+/******************************************************************************/
+/****************************** REGISTER MAPPING ******************************/
+/******************************************************************************/
+/** 
+  * @brief  WM8994 ID  
+  */  
+#define  WM8994_ID    0x08994
+
+/**
+  * @brief Device ID Register: Reading from this register will indicate device 
+  *                            family ID 8994h
+  */
+#define WM8994_CHIPID_ADDR                  0x00
+
+
+/*------------------------------------------------------------------------------
+                           Audio Codec functions 
+------------------------------------------------------------------------------*/
+/**
+  * @brief Audio I2C Slave address
+  */
+#define AUDIO_I2C_ADDRESS                ((uint16_t)0x34)
+
+
+/** @defgroup BSP_Audio_Out_Option BSP Audio Out Option
+  * @{
+  */
+#define BSP_AUDIO_OUT_CIRCULARMODE      ((uint32_t)0x00000001) /* BUFFER CIRCULAR MODE */
+#define BSP_AUDIO_OUT_NORMALMODE        ((uint32_t)0x00000002) /* BUFFER NORMAL MODE   */
+#define BSP_AUDIO_OUT_STEREOMODE        ((uint32_t)0x00000004) /* STEREO MODE          */
+#define BSP_AUDIO_OUT_MONOMODE          ((uint32_t)0x00000008) /* MONO MODE            */
+/**
+  * @}
+  */
+/** @defgroup BSP_Audio_Sample_Rate BSP Audio Sample Rate
+  * @{
+  */
+#define BSP_AUDIO_FREQUENCY_96K         ((uint32_t)192000U)
+#define BSP_AUDIO_FREQUENCY_48K         ((uint32_t)48000U)
+#define BSP_AUDIO_FREQUENCY_44K         ((uint32_t)44100U)
+#define BSP_AUDIO_FREQUENCY_32K         ((uint32_t)32000U)
+#define BSP_AUDIO_FREQUENCY_22K         ((uint32_t)22050U)
+#define BSP_AUDIO_FREQUENCY_16K         ((uint32_t)16000U)
+#define BSP_AUDIO_FREQUENCY_11K         ((uint32_t)11025U)
+#define BSP_AUDIO_FREQUENCY_8K          ((uint32_t)8000U)
+
+/*------------------------------------------------------------------------------
+                          USER SAI defines parameters
+ -----------------------------------------------------------------------------*/
+/** CODEC_AudioFrame_SLOT_TDMMode In W8994 codec the Audio frame contains 4 slots : TDM Mode
+  * TDM format :
+  * +------------------|------------------|--------------------|-------------------+ 
+  * | CODEC_SLOT0 Left | CODEC_SLOT1 Left | CODEC_SLOT0 Right  | CODEC_SLOT1 Right |
+  * +------------------------------------------------------------------------------+
+  */
+/* To have 2 separate audio stream in Both headphone and speaker the 4 slot must be activated */
+#define CODEC_AUDIOFRAME_SLOT_0123          (SAI_SLOTACTIVE_0 | SAI_SLOTACTIVE_1 | SAI_SLOTACTIVE_2 | SAI_SLOTACTIVE_3)
+
+/* To have an audio stream in headphone only SAI Slot 0 and Slot 2 must be activated */ 
+#define CODEC_AUDIOFRAME_SLOT_02            SAI_SLOTACTIVE_0 | SAI_SLOTACTIVE_2 
+/* To have an audio stream in speaker only SAI Slot 1 and Slot 3 must be activated */ 
+#define CODEC_AUDIOFRAME_SLOT_13            SAI_SLOTACTIVE_1 | SAI_SLOTACTIVE_3
+
+
+#define DMA_MAX_SZE                         0xFFFF
+
+/*------------------------------------------------------------------------------
+             CONFIGURATION: Audio Driver Configuration parameters
+------------------------------------------------------------------------------*/
+
+#define AUDIODATA_SIZE                      2   /* 16-bits audio data size */
+
+/* Audio status definition */
+#define AUDIO_OK                            E_OK
+
+/* AudioFreq * DataSize (2 bytes) * NumChannels (Stereo: 2) */
+#define DEFAULT_AUDIO_IN_FREQ               BSP_AUDIO_FREQUENCY_16K
+#define DEFAULT_AUDIO_IN_BIT_RESOLUTION     ((uint8_t)16)
+#define DEFAULT_AUDIO_IN_CHANNEL_NBR        ((uint8_t)2) /* Mono = 1, Stereo = 2 */
+#define DEFAULT_AUDIO_IN_VOLUME             ((uint16_t)100)
+   
+/*------------------------------------------------------------------------------
+                    OPTIONAL Configuration defines parameters
+------------------------------------------------------------------------------*/
+
+/* Delay for the Codec to be correctly reset */
+#define CODEC_RESET_DELAY                   ((uint8_t)5)
+   
+
+/*------------------------------------------------------------------------------
+                            OUTPUT DEVICES definition
+------------------------------------------------------------------------------*/
+/* Alias on existing output devices to adapt to headphones output */
+#define OUTPUT_DEVICE_HEADPHONE1 OUTPUT_DEVICE_HEADPHONE
+#define OUTPUT_DEVICE_HEADPHONE2 OUTPUT_DEVICE_SPEAKER 
+   
+#define DMA_MAX(x)           (((x) <= DMA_MAX_SZE)? (x):DMA_MAX_SZE)
+
+/*
+ *  STMAUDIOハンドラ定義
+ *
+ */
+typedef struct STAUDIO_Handle_s {
+	I2C_Handle_t    *hi2c;
+	AUDIO_Handle_t  *hsai;
+	ID              saiid;
+	uint8_t         i2caddress;
+	uint8_t         outputEnabled;
+	uint8_t         inputEnabled;
+	uint8_t         ColdStartup;
+	uint16_t        InputDevice;
+	uint16_t        AudioInVolume;
+	void   (*audio_fullout_func)(AUDIO_Handle_t *hsai);
+	void   (*audio_halfout_func)(AUDIO_Handle_t *hsai);
+	void   (*audio_fullin_func)(void *handle);
+	void   (*audio_halfin_func)(void *handle);
+	void   (*audio_error_func)(AUDIO_Handle_t *hsai);
+} STAUDIO_Handle_t;
+
+
+extern ER staudio_out_init(STAUDIO_Handle_t *haudio, uint16_t OutputDevice, uint8_t Volume, uint32_t AudioFreq, uint16_t framesize);
+extern void staudio_out_deinit(STAUDIO_Handle_t *haudio);
+extern ER staudio_out_play(STAUDIO_Handle_t *haudio, uint16_t* pBuffer, uint32_t Size);
+extern ER staudio_out_pause(STAUDIO_Handle_t *haudio);
+extern ER staudio_out_resume(STAUDIO_Handle_t *haudio);
+extern ER staudio_out_stop(STAUDIO_Handle_t *haudio, uint32_t Option);
+extern ER staudio_out_setvolume(STAUDIO_Handle_t *haudio, uint8_t Volume);
+extern void staudio_out_setfrequency(STAUDIO_Handle_t *haudio, uint32_t AudioFreq);
+extern void staudio_out_setframeslot(STAUDIO_Handle_t *haudio, uint32_t AudioFrameSlot);
+extern ER staudio_out_setmute(STAUDIO_Handle_t *haudio, uint32_t Cmd);
+extern ER staudio_out_setoutputmode(STAUDIO_Handle_t *haudio, uint8_t Output);
+extern void staudio_out_changebuffer(STAUDIO_Handle_t *haudio, uint16_t *pData, uint16_t Size);
+
+
+extern ER staudio_in_init(STAUDIO_Handle_t *haudio, uint16_t InputDevice, uint32_t AudioFreq, uint32_t BitRes, uint32_t ChnlNbr);
+uint8_t BSP_AUDIO_IN_Init(uint32_t AudioFreq, uint32_t BitRes, uint32_t ChnlNbr);
+extern ER staudio_in_out_init(STAUDIO_Handle_t *haudio, uint16_t InputDevice, uint16_t OutputDevice, uint32_t AudioFreq, uint32_t BitRes, uint32_t ChnlNbr);
+extern void staudio_in_deinit(STAUDIO_Handle_t *haudio);
+extern ER staudio_in_record(STAUDIO_Handle_t *haudio, uint16_t* pbuf, uint32_t size);
+extern ER staudio_in_stop(STAUDIO_Handle_t *haudio, uint32_t Option);
+extern ER staudio_in_pause(STAUDIO_Handle_t *haudio);
+extern ER staudio_in_resume(STAUDIO_Handle_t *haudio);
+extern ER staudio_in_setvolume(STAUDIO_Handle_t *haudio, uint8_t Volume);
+
+#ifdef TOPPERS_STM32F769_DISCOVERY
+extern ER BSP_AUDIO_IN_AllocScratch(int32_t *pScratch, uint32_t size);
+extern uint8_t BSP_AUDIO_IN_GetChannelNumber(void);
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _STAUDIO_WM8994_H_ */
+
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/stlcd_otm8009a/Makefile.config
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/stlcd_otm8009a/Makefile.config	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/stlcd_otm8009a/Makefile.config	(revision 457)
@@ -0,0 +1,55 @@
+#
+#   TOPPERS/ASP/FMP Kernel
+#       Toyohashi Open Platform for Embedded Real-Time Systems/
+#       Advanced Standard Profile Kernel
+#
+#   Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
+#                               Toyohashi Univ. of Technology, JAPAN
+#   Copyright (C) 2003-2008 by Ryosuke Takeuchi
+#                Platform Development Center RICOH COMPANY,LTD. JAPAN
+#   Copyright (C) 2015-2018 by TOPPERS PROJECT Educational Working Group.
+#
+#   上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+#   によって公表されている GNU General Public License の Version 2 に記
+#   述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+#   を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+#   利用と呼ぶ）することを無償で許諾する．
+#   (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+#       権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+#       スコード中に含まれていること．
+#   (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+#       用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+#       者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+#       の無保証規定を掲載すること．
+#   (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+#       用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+#       と．
+#     (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+#         作権表示，この利用条件および下記の無保証規定を掲載すること．
+#     (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+#         報告すること．
+#   (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+#       害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+#
+#   本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+#   よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+#   含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+#   接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+#
+#  @(#) $Id$
+#
+ 
+#
+#  Makefile のプロセッサ依存 (otm8009a用)
+#
+
+#
+#  コンパイルオプション
+#
+INCLUDES := $(INCLUDES) -I$(SRCDIR)/gdic/stlcd_otm8009a
+
+#
+#  USB DEVICE(GDIC)に関する定義
+#
+SYSSVC_DIR := $(SYSSVC_DIR):$(SRCDIR)/gdic/stlcd_otm8009a
+SYSSVC_COBJS := $(SYSSVC_COBJS) stlcd_otm8009a.o
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/stlcd_otm8009a/glcd_core.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/stlcd_otm8009a/glcd_core.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/stlcd_otm8009a/glcd_core.h	(revision 457)
@@ -0,0 +1,45 @@
+/*
+ *  TOPPERS BASE PLATFORM MIDDLEWARE
+ * 
+ *  Copyright (C) 2017-2018 by TOPPERS PROJECT
+ *                             Educational Working Group.
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+#ifndef _LCD_CORE_H_
+#define _LCD_CORE_H_
+
+#include "stlcd_otm8009a.h"
+
+#endif /* _LCD_CORE_H_ */
+
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/stlcd_otm8009a/stlcd_otm8009a.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/stlcd_otm8009a/stlcd_otm8009a.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/stlcd_otm8009a/stlcd_otm8009a.c	(revision 457)
@@ -0,0 +1,1505 @@
+/*
+ *  TOPPERS BASE PLATFORM MIDDLEWARE
+ * 
+ *  Copyright (C) 2017-2018 by TOPPERS PROJECT
+ *                             Educational Working Group.
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+/**
+  ******************************************************************************
+  * @attention
+  *
+  * <h2><center>&copy; COPYRIGHT(c) 2016 STMicroelectronics</center></h2>
+  *
+  * 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 STMicroelectronics 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 "stlcd_otm8009a.h"
+#include "kernel_cfg.h"
+
+#define sil_orw_mem(a, b)		sil_wrw_mem((a), sil_rew_mem(a) | (b))
+#define sil_andw_mem(a, b)		sil_wrw_mem((a), sil_rew_mem(a) & ~(b))
+#define sil_modw_mem(a, b, c)	sil_wrw_mem((a), (sil_rew_mem(a) & (~b)) | (c))
+
+
+
+/** @defgroup STM32F769I-DISCOVERY_LCD_Private_Macros LCD Private Macros
+  * @{
+  */
+#define ABS(X)                 ((X) > 0 ? (X) : -(X))
+
+#define POLY_X(Z)              ((int32_t)((Points + (Z))->X))
+#define POLY_Y(Z)              ((int32_t)((Points + (Z))->Y))
+
+/*
+ * @brief Constant tables of register settings used to transmit DSI
+ * command packets as power up initialization sequence of the KoD LCD (OTM8009A LCD Driver)
+ */
+static const uint8_t lcdRegData1[]  = {0x80,0x09,0x01,0xFF};
+static const uint8_t lcdRegData2[]  = {0x80,0x09,0xFF};
+static const uint8_t lcdRegData3[]  = {0x00,0x09,0x0F,0x0E,0x07,0x10,0x0B,0x0A,0x04,0x07,0x0B,0x08,0x0F,0x10,0x0A,0x01,0xE1};
+static const uint8_t lcdRegData4[]  = {0x00,0x09,0x0F,0x0E,0x07,0x10,0x0B,0x0A,0x04,0x07,0x0B,0x08,0x0F,0x10,0x0A,0x01,0xE2};
+static const uint8_t lcdRegData5[]  = {0x79,0x79,0xD8};
+static const uint8_t lcdRegData6[]  = {0x00,0x01,0xB3};
+static const uint8_t lcdRegData7[]  = {0x85,0x01,0x00,0x84,0x01,0x00,0xCE};
+static const uint8_t lcdRegData8[]  = {0x18,0x04,0x03,0x39,0x00,0x00,0x00,0x18,0x03,0x03,0x3A,0x00,0x00,0x00,0xCE};
+static const uint8_t lcdRegData9[]  = {0x18,0x02,0x03,0x3B,0x00,0x00,0x00,0x18,0x01,0x03,0x3C,0x00,0x00,0x00,0xCE};
+static const uint8_t lcdRegData10[] = {0x01,0x01,0x20,0x20,0x00,0x00,0x01,0x02,0x00,0x00,0xCF};
+static const uint8_t lcdRegData11[] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xCB};
+static const uint8_t lcdRegData12[] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xCB};
+static const uint8_t lcdRegData13[] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xCB};
+static const uint8_t lcdRegData14[] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xCB};
+static const uint8_t lcdRegData15[] = {0x00,0x04,0x04,0x04,0x04,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xCB};
+static const uint8_t lcdRegData16[] = {0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x04,0x04,0x04,0x04,0x00,0x00,0x00,0x00,0xCB};
+static const uint8_t lcdRegData17[] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xCB};
+static const uint8_t lcdRegData18[] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xCB};
+static const uint8_t lcdRegData19[] = {0x00,0x26,0x09,0x0B,0x01,0x25,0x00,0x00,0x00,0x00,0xCC};
+static const uint8_t lcdRegData20[] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x26,0x0A,0x0C,0x02,0xCC};
+static const uint8_t lcdRegData21[] = {0x25,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xCC};
+static const uint8_t lcdRegData22[] = {0x00,0x25,0x0C,0x0A,0x02,0x26,0x00,0x00,0x00,0x00,0xCC};
+static const uint8_t lcdRegData23[] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x25,0x0B,0x09,0x01,0xCC};
+static const uint8_t lcdRegData24[] = {0x26,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xCC};
+static const uint8_t lcdRegData25[] = {0xFF,0xFF,0xFF,0xFF};
+/*
+  * CASET value (Column Address Set) : X direction LCD GRAM boundaries
+  * depending on LCD orientation mode and PASET value (Page Address Set) : Y direction
+  * LCD GRAM boundaries depending on LCD orientation mode
+  * XS[15:0] = 0x000 = 0, XE[15:0] = 0x31F = 799 for landscape mode : apply to CASET
+  * YS[15:0] = 0x000 = 0, YE[15:0] = 0x31F = 799 for portrait mode : : apply to PASET
+  */
+static const uint8_t lcdRegData27[] = {0x00, 0x00, 0x03, 0x1F, OTM8009A_CMD_CASET};
+/*
+  * XS[15:0] = 0x000 = 0, XE[15:0] = 0x1DF = 479 for portrait mode : apply to CASET
+  * YS[15:0] = 0x000 = 0, YE[15:0] = 0x1DF = 479 for landscape mode : apply to PASET
+ */
+static const uint8_t lcdRegData28[] = {0x00, 0x00, 0x01, 0xDF, OTM8009A_CMD_PASET};
+
+
+static const uint8_t ShortRegData1[]  = {OTM8009A_CMD_NOP, 0x00};
+static const uint8_t ShortRegData2[]  = {OTM8009A_CMD_NOP, 0x80};
+static const uint8_t ShortRegData3[]  = {0xC4, 0x30};
+static const uint8_t ShortRegData4[]  = {OTM8009A_CMD_NOP, 0x8A};
+static const uint8_t ShortRegData5[]  = {0xC4, 0x40};
+static const uint8_t ShortRegData6[]  = {OTM8009A_CMD_NOP, 0xB1};
+static const uint8_t ShortRegData7[]  = {0xC5, 0xA9};
+static const uint8_t ShortRegData8[]  = {OTM8009A_CMD_NOP, 0x91};
+static const uint8_t ShortRegData9[]  = {0xC5, 0x34};
+static const uint8_t ShortRegData10[] = {OTM8009A_CMD_NOP, 0xB4};
+static const uint8_t ShortRegData11[] = {0xC0, 0x50};
+static const uint8_t ShortRegData12[] = {0xD9, 0x4E};
+static const uint8_t ShortRegData13[] = {OTM8009A_CMD_NOP, 0x81};
+static const uint8_t ShortRegData14[] = {0xC1, 0x66};
+static const uint8_t ShortRegData15[] = {OTM8009A_CMD_NOP, 0xA1};
+static const uint8_t ShortRegData16[] = {0xC1, 0x08};
+static const uint8_t ShortRegData17[] = {OTM8009A_CMD_NOP, 0x92};
+static const uint8_t ShortRegData18[] = {0xC5, 0x01};
+static const uint8_t ShortRegData19[] = {OTM8009A_CMD_NOP, 0x95};
+static const uint8_t ShortRegData20[] = {OTM8009A_CMD_NOP, 0x94};
+static const uint8_t ShortRegData21[] = {0xC5, 0x33};
+static const uint8_t ShortRegData22[] = {OTM8009A_CMD_NOP, 0xA3};
+static const uint8_t ShortRegData23[] = {0xC0, 0x1B};
+static const uint8_t ShortRegData24[] = {OTM8009A_CMD_NOP, 0x82};
+static const uint8_t ShortRegData25[] = {0xC5, 0x83};
+static const uint8_t ShortRegData26[] = {0xC4, 0x83};
+static const uint8_t ShortRegData27[] = {0xC1, 0x0E};
+static const uint8_t ShortRegData28[] = {OTM8009A_CMD_NOP, 0xA6};
+static const uint8_t ShortRegData29[] = {OTM8009A_CMD_NOP, 0xA0};
+static const uint8_t ShortRegData30[] = {OTM8009A_CMD_NOP, 0xB0};
+static const uint8_t ShortRegData31[] = {OTM8009A_CMD_NOP, 0xC0};
+static const uint8_t ShortRegData32[] = {OTM8009A_CMD_NOP, 0xD0};
+static const uint8_t ShortRegData33[] = {OTM8009A_CMD_NOP, 0x90};
+static const uint8_t ShortRegData34[] = {OTM8009A_CMD_NOP, 0xE0};
+static const uint8_t ShortRegData35[] = {OTM8009A_CMD_NOP, 0xF0};
+static const uint8_t ShortRegData36[] = {OTM8009A_CMD_SLPOUT, 0x00};
+static const uint8_t ShortRegData37[] = {OTM8009A_CMD_COLMOD, OTM8009A_COLMOD_RGB565};
+static const uint8_t ShortRegData38[] = {OTM8009A_CMD_COLMOD, OTM8009A_COLMOD_RGB888};
+static const uint8_t ShortRegData39[] = {OTM8009A_CMD_MADCTR, OTM8009A_MADCTR_MODE_LANDSCAPE};
+static const uint8_t ShortRegData40[] = {OTM8009A_CMD_WRDISBV, 0x7F};
+static const uint8_t ShortRegData41[] = {OTM8009A_CMD_WRCTRLD, 0x2C};
+static const uint8_t ShortRegData42[] = {OTM8009A_CMD_WRCABC, 0x02};
+static const uint8_t ShortRegData43[] = {OTM8009A_CMD_WRCABCMB, 0xFF};
+static const uint8_t ShortRegData44[] = {OTM8009A_CMD_DISPON, 0x00};
+static const uint8_t ShortRegData45[] = {OTM8009A_CMD_RAMWR, 0x00};
+static const uint8_t ShortRegData46[] = {0xCF, 0x00};
+static const uint8_t ShortRegData47[] = {0xC5, 0x66};
+static const uint8_t ShortRegData48[] = {OTM8009A_CMD_NOP, 0xB6};
+static const uint8_t ShortRegData49[] = {0xF5, 0x06};
+
+
+/** @defgroup STM32F769I-DISCOVERY_LCD_Exported_Variables STM32F769I DISCOVERY LCD Exported Variables
+  * @{
+  */
+static DMA2D_Handle_t hdma2d_discovery;
+static LTDC_Handle_t  hltdc_discovery;
+static DSI_Handle_t   hdsi_discovery;
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */
+
+/** @defgroup STM32F769I-DISCOVERY_LCD_Private_FunctionPrototypes LCD Private FunctionPrototypes
+  * @{
+  */
+static void FillTriangle(LCD_DrawProp_t *pDrawProp, uint16_t x1, uint16_t x2, uint16_t x3, uint16_t y1, uint16_t y2, uint16_t y3);
+static void LL_FillBuffer(uint32_t LayerIndex, void *pDst, uint32_t xSize, uint32_t ySize, uint32_t OffLine, uint32_t ColorIndex);
+static void LL_ConvertLineToARGB8888(void * pSrc, void *pDst, uint32_t xSize, uint32_t ColorMode);
+/**
+  * @}
+  */
+/**
+  * @brief  DCS or Generic short/long write command
+  * @param  NbParams: Number of parameters. It indicates the write command mode:
+  *                 If inferior to 2, a long write command is performed else short.
+  * @param  pParams: Pointer to parameter values table.
+  * @retval HAL status
+  */
+static void
+DSI_IO_WriteCmd(DSI_Handle_t *hdsi, uint32_t NbrParams, uint8_t *pParams)
+{
+	if(NbrParams <= 1){
+		dsi_swrite(hdsi, LCD_OTM8009A_ID, DSI_DCS_SHORT_PKT_WRITE_P1, pParams[0], pParams[1]);
+	}
+	else{
+		dsi_lwrite(hdsi,  LCD_OTM8009A_ID, DSI_DCS_LONG_PKT_WRITE, NbrParams, pParams[NbrParams], pParams);
+	}
+}
+
+/**
+  * @brief  Initializes the LCD KoD display part by communication in DSI mode in Video Mode
+  *         with IC Display Driver OTM8009A (see IC Driver specification for more information).
+  * @param  hdsi_eval : pointer on DSI configuration structure
+  * @param  hdsivideo_handle : pointer on DSI video mode configuration structure
+  * @retval Status
+  */
+static uint8_t
+OTM8009A_Init(DSI_Handle_t *hdsi, uint32_t ColorCoding, uint32_t orientation)
+{
+	/* Enable CMD2 to access vendor specific commands                               */
+	/* Enter in command 2 mode and set EXTC to enable address shift function (0x00) */
+	DSI_IO_WriteCmd(hdsi, 0, (uint8_t *)ShortRegData1);
+	DSI_IO_WriteCmd(hdsi,  3, (uint8_t *)lcdRegData1);
+
+	/* Enter ORISE Command 2 */
+	DSI_IO_WriteCmd(hdsi, 0, (uint8_t *)ShortRegData2); /* Shift address to 0x80 */
+	DSI_IO_WriteCmd(hdsi,  2, (uint8_t *)lcdRegData2);
+
+	/////////////////////////////////////////////////////////////////////
+	/* SD_PCH_CTRL - 0xC480h - 129th parameter - Default 0x00          */
+	/* Set SD_PT                                                       */
+	/* -> Source output level during porch and non-display area to GND */
+	DSI_IO_WriteCmd(hdsi, 0, (uint8_t *)ShortRegData2);
+	DSI_IO_WriteCmd(hdsi, 0, (uint8_t *)ShortRegData3);
+	dly_tsk(10);
+	/* Not documented */
+	DSI_IO_WriteCmd(hdsi, 0, (uint8_t *)ShortRegData4);
+	DSI_IO_WriteCmd(hdsi, 0, (uint8_t *)ShortRegData5);
+	dly_tsk(10);
+	/////////////////////////////////////////////////////////////////////
+
+	/* PWR_CTRL4 - 0xC4B0h - 178th parameter - Default 0xA8 */
+	/* Set gvdd_en_test                                     */
+	/* -> enable GVDD test mode !!!                         */
+	DSI_IO_WriteCmd(hdsi, 0, (uint8_t *)ShortRegData6);
+	DSI_IO_WriteCmd(hdsi, 0, (uint8_t *)ShortRegData7);
+
+	/* PWR_CTRL2 - 0xC590h - 146th parameter - Default 0x79      */
+	/* Set pump 4 vgh voltage                                    */
+	/* -> from 15.0v down to 13.0v                               */
+	/* Set pump 5 vgh voltage                                    */
+	/* -> from -12.0v downto -9.0v                               */
+	DSI_IO_WriteCmd(hdsi, 0, (uint8_t *)ShortRegData8);
+	DSI_IO_WriteCmd(hdsi, 0, (uint8_t *)ShortRegData9);
+
+	/* P_DRV_M - 0xC0B4h - 181th parameter - Default 0x00 */
+	/* -> Column inversion                                */
+	DSI_IO_WriteCmd(hdsi, 0, (uint8_t *)ShortRegData10);
+	DSI_IO_WriteCmd(hdsi, 0, (uint8_t *)ShortRegData11);
+
+	/* VCOMDC - 0xD900h - 1st parameter - Default 0x39h */
+	/* VCOM Voltage settings                            */
+	/* -> from -1.0000v downto -1.2625v                 */
+	DSI_IO_WriteCmd(hdsi, 0, (uint8_t *)ShortRegData1);
+	DSI_IO_WriteCmd(hdsi, 0, (uint8_t *)ShortRegData12);
+
+	/* Oscillator adjustment for Idle/Normal mode (LPDT only) set to 65Hz (default is 60Hz) */
+	DSI_IO_WriteCmd(hdsi, 0, (uint8_t *)ShortRegData13);
+	DSI_IO_WriteCmd(hdsi, 0, (uint8_t *)ShortRegData14);
+
+	/* Video mode internal */
+	DSI_IO_WriteCmd(hdsi, 0, (uint8_t *)ShortRegData15);
+	DSI_IO_WriteCmd(hdsi, 0, (uint8_t *)ShortRegData16);
+
+	/* PWR_CTRL2 - 0xC590h - 147h parameter - Default 0x00 */
+	/* Set pump 4&5 x6                                     */
+	/* -> ONLY VALID when PUMP4_EN_ASDM_HV = "0"           */
+	DSI_IO_WriteCmd(hdsi, 0, (uint8_t *)ShortRegData17);
+	DSI_IO_WriteCmd(hdsi, 0, (uint8_t *)ShortRegData18);
+
+	/* PWR_CTRL2 - 0xC590h - 150th parameter - Default 0x33h */
+	/* Change pump4 clock ratio                              */
+	/* -> from 1 line to 1/2 line                            */
+	DSI_IO_WriteCmd(hdsi, 0, (uint8_t *)ShortRegData19);
+	DSI_IO_WriteCmd(hdsi, 0, (uint8_t *)ShortRegData9);
+
+	/* GVDD/NGVDD settings */
+	DSI_IO_WriteCmd(hdsi, 0, (uint8_t *)ShortRegData1);
+	DSI_IO_WriteCmd(hdsi,  2, (uint8_t *)lcdRegData5);
+
+	/* PWR_CTRL2 - 0xC590h - 149th parameter - Default 0x33h */
+	/* Rewrite the default value !                           */
+	DSI_IO_WriteCmd(hdsi, 0, (uint8_t *)ShortRegData20);
+	DSI_IO_WriteCmd(hdsi, 0, (uint8_t *)ShortRegData21);
+
+	/* Panel display timing Setting 3 */
+	DSI_IO_WriteCmd(hdsi, 0, (uint8_t *)ShortRegData22);
+	DSI_IO_WriteCmd(hdsi, 0, (uint8_t *)ShortRegData23);
+
+	/* Power control 1 */
+	DSI_IO_WriteCmd(hdsi, 0, (uint8_t *)ShortRegData24);
+	DSI_IO_WriteCmd(hdsi, 0, (uint8_t *)ShortRegData25);
+
+	/* Source driver precharge */
+	DSI_IO_WriteCmd(hdsi, 0, (uint8_t *)ShortRegData13);
+	DSI_IO_WriteCmd(hdsi, 0, (uint8_t *)ShortRegData26);
+
+	DSI_IO_WriteCmd(hdsi, 0, (uint8_t *)ShortRegData15);
+	DSI_IO_WriteCmd(hdsi, 0, (uint8_t *)ShortRegData27);
+
+	DSI_IO_WriteCmd(hdsi, 0, (uint8_t *)ShortRegData28);
+	DSI_IO_WriteCmd(hdsi,  2, (uint8_t *)lcdRegData6);
+
+	/* GOAVST */
+	DSI_IO_WriteCmd(hdsi, 0, (uint8_t *)ShortRegData2);
+	DSI_IO_WriteCmd(hdsi,  6, (uint8_t *)lcdRegData7);
+
+	DSI_IO_WriteCmd(hdsi, 0, (uint8_t *)ShortRegData29);
+	DSI_IO_WriteCmd(hdsi,  14, (uint8_t *)lcdRegData8);
+
+	DSI_IO_WriteCmd(hdsi, 0, (uint8_t *)ShortRegData30);
+	DSI_IO_WriteCmd(hdsi,  14, (uint8_t *)lcdRegData9);
+
+	DSI_IO_WriteCmd(hdsi, 0, (uint8_t *)ShortRegData31);
+	DSI_IO_WriteCmd(hdsi,  10, (uint8_t *)lcdRegData10);
+
+	DSI_IO_WriteCmd(hdsi, 0, (uint8_t *)ShortRegData32);
+	DSI_IO_WriteCmd(hdsi, 0, (uint8_t *)ShortRegData46);
+
+	DSI_IO_WriteCmd(hdsi, 0, (uint8_t *)ShortRegData2);
+	DSI_IO_WriteCmd(hdsi,  10, (uint8_t *)lcdRegData11);
+
+	DSI_IO_WriteCmd(hdsi, 0, (uint8_t *)ShortRegData33);
+	DSI_IO_WriteCmd(hdsi,  15, (uint8_t *)lcdRegData12);
+
+	DSI_IO_WriteCmd(hdsi, 0, (uint8_t *)ShortRegData29);
+	DSI_IO_WriteCmd(hdsi,  15, (uint8_t *)lcdRegData13);
+
+	DSI_IO_WriteCmd(hdsi, 0, (uint8_t *)ShortRegData30);
+	DSI_IO_WriteCmd(hdsi,  10, (uint8_t *)lcdRegData14);
+
+	DSI_IO_WriteCmd(hdsi, 0, (uint8_t *)ShortRegData31);
+	DSI_IO_WriteCmd(hdsi,  15, (uint8_t *)lcdRegData15);
+
+	DSI_IO_WriteCmd(hdsi, 0, (uint8_t *)ShortRegData32);
+	DSI_IO_WriteCmd(hdsi,  15, (uint8_t *)lcdRegData16);
+
+	DSI_IO_WriteCmd(hdsi, 0, (uint8_t *)ShortRegData34);
+	DSI_IO_WriteCmd(hdsi,  10, (uint8_t *)lcdRegData17);
+
+	DSI_IO_WriteCmd(hdsi, 0, (uint8_t *)ShortRegData35);
+	DSI_IO_WriteCmd(hdsi,  10, (uint8_t *)lcdRegData18);
+
+	DSI_IO_WriteCmd(hdsi, 0, (uint8_t *)ShortRegData2);
+	DSI_IO_WriteCmd(hdsi,  10, (uint8_t *)lcdRegData19);
+
+	DSI_IO_WriteCmd(hdsi, 0, (uint8_t *)ShortRegData33);
+	DSI_IO_WriteCmd(hdsi,  15, (uint8_t *)lcdRegData20);
+
+	DSI_IO_WriteCmd(hdsi, 0, (uint8_t *)ShortRegData29);
+	DSI_IO_WriteCmd(hdsi,  15, (uint8_t *)lcdRegData21);
+
+	DSI_IO_WriteCmd(hdsi, 0, (uint8_t *)ShortRegData30);
+	DSI_IO_WriteCmd(hdsi,  10, (uint8_t *)lcdRegData22);
+
+	DSI_IO_WriteCmd(hdsi, 0, (uint8_t *)ShortRegData31);
+	DSI_IO_WriteCmd(hdsi,  15, (uint8_t *)lcdRegData23);
+
+	DSI_IO_WriteCmd(hdsi, 0, (uint8_t *)ShortRegData32);
+	DSI_IO_WriteCmd(hdsi,  15, (uint8_t *)lcdRegData24);
+
+	/////////////////////////////////////////////////////////////////////////////
+	/* PWR_CTRL1 - 0xc580h - 130th parameter - default 0x00 */
+	/* Pump 1 min and max DM                                */
+	DSI_IO_WriteCmd(hdsi, 0, (uint8_t *)ShortRegData13);
+	DSI_IO_WriteCmd(hdsi, 0, (uint8_t *)ShortRegData47);
+	DSI_IO_WriteCmd(hdsi, 0, (uint8_t *)ShortRegData48);
+	DSI_IO_WriteCmd(hdsi, 0, (uint8_t *)ShortRegData49);
+	/////////////////////////////////////////////////////////////////////////////
+
+	/* Exit CMD2 mode */
+	DSI_IO_WriteCmd(hdsi, 0, (uint8_t *)ShortRegData1);
+	DSI_IO_WriteCmd(hdsi,  3, (uint8_t *)lcdRegData25);
+
+	/*************************************************************************** */
+	/* Standard DCS Initialization TO KEEP CAN BE DONE IN HSDT                   */
+	/*************************************************************************** */
+
+	/* NOP - goes back to DCS std command ? */
+	DSI_IO_WriteCmd(hdsi, 0, (uint8_t *)ShortRegData1);
+
+	/* Gamma correction 2.2+ table (HSDT possible) */
+	DSI_IO_WriteCmd(hdsi, 0, (uint8_t *)ShortRegData1);
+	DSI_IO_WriteCmd(hdsi,  16, (uint8_t *)lcdRegData3);
+
+	/* Gamma correction 2.2- table (HSDT possible) */
+	DSI_IO_WriteCmd(hdsi, 0, (uint8_t *)ShortRegData1);
+	DSI_IO_WriteCmd(hdsi,  16, (uint8_t *)lcdRegData4);
+
+	/* Send Sleep Out command to display : no parameter */
+	DSI_IO_WriteCmd(hdsi, 0, (uint8_t *)ShortRegData36);
+
+	/* Wait for sleep out exit */
+	dly_tsk(120);
+
+	switch(ColorCoding){
+	case OTM8009A_FORMAT_RBG565:
+		/* Set Pixel color format to RGB565 */
+		DSI_IO_WriteCmd(hdsi, 0, (uint8_t *)ShortRegData37);
+		break;
+	case OTM8009A_FORMAT_RGB888:
+		/* Set Pixel color format to RGB888 */
+		DSI_IO_WriteCmd(hdsi, 0, (uint8_t *)ShortRegData38);
+		break;
+	default:
+		break;
+	}
+
+	/* Send command to configure display in landscape orientation mode. By default
+      the orientation mode is portrait  */
+	if(orientation == OTM8009A_ORIENTATION_LANDSCAPE){
+		DSI_IO_WriteCmd(hdsi, 0, (uint8_t *)ShortRegData39);
+		DSI_IO_WriteCmd(hdsi,  4, (uint8_t *)lcdRegData27);
+		DSI_IO_WriteCmd(hdsi,  4, (uint8_t *)lcdRegData28);
+	}
+
+	/** CABC : Content Adaptive Backlight Control section start >> */
+	/* Note : defaut is 0 (lowest Brightness), 0xFF is highest Brightness, try 0x7F : intermediate value */
+	DSI_IO_WriteCmd(hdsi, 0, (uint8_t *)ShortRegData40);
+
+	/* defaut is 0, try 0x2C - Brightness Control Block, Display Dimming & BackLight on */
+	DSI_IO_WriteCmd(hdsi, 0, (uint8_t *)ShortRegData41);
+
+	/* defaut is 0, try 0x02 - image Content based Adaptive Brightness [Still Picture] */
+	DSI_IO_WriteCmd(hdsi, 0, (uint8_t *)ShortRegData42);
+
+	/* defaut is 0 (lowest Brightness), 0xFF is highest Brightness */
+	DSI_IO_WriteCmd(hdsi, 0, (uint8_t *)ShortRegData43);
+
+	/** CABC : Content Adaptive Backlight Control section end << */
+
+	/* Send Command Display On */
+	DSI_IO_WriteCmd(hdsi, 0, (uint8_t *)ShortRegData44);
+
+	/* NOP command */
+	DSI_IO_WriteCmd(hdsi, 0, (uint8_t *)ShortRegData1);
+
+	/* Send Command GRAM memory write (no parameters) : this initiates frame write via other DSI commands sent by */
+	/* DSI host from LTDC incoming pixels in video mode */
+	DSI_IO_WriteCmd(hdsi, 0, (uint8_t *)ShortRegData45);
+	return 0;
+}
+
+
+/*
+ *  LTDC/DSI割込みハンドラ
+ */
+void ltdc_handler(void)
+{
+	ltdc_irqhandler(&hltdc_discovery);
+}
+
+void dsi_handler(void)
+{
+	dsi_irqhandler(&hdsi_discovery);
+}
+
+/*
+ *  DSI/OTM8009Aスクリーンの初期化関数
+ */
+ER
+lcd_init(LCD_Handler_t *hlcd, LCD_OrientationTypeDef orientation)
+{
+	LTDC_Handle_t *hldtc = &hltdc_discovery;
+	DSI_Handle_t  *hdsi  = &hdsi_discovery;
+	uint32_t LcdClock  = 27429; /*!< LcdClk = 27429 kHz */
+
+	uint32_t laneByteClk_kHz = 0;
+	uint32_t VSA;	/*!< Vertical start active time in units of lines */
+	uint32_t VBP;	/*!< Vertical Back Porch time in units of lines */
+	uint32_t VFP;	/*!< Vertical Front Porch time in units of lines */
+	uint32_t VACT;	/*!< Vertical Active time in units of lines = imageSize Y in pixels to display */
+	uint32_t HSA;	/*!< Horizontal start active time in units of lcdClk */
+	uint32_t HBP;	/*!< Horizontal Back Porch time in units of lcdClk */
+	uint32_t HFP;	/*!< Horizontal Front Porch time in units of lcdClk */
+	uint32_t HACT;	/*!< Horizontal Active time in units of lcdClk = imageSize X in pixels to display */
+
+	/* Toggle Hardware Reset of the DSI LCD using
+	 * its XRES signal (active low) */
+	lcd_reset(hlcd);
+	hlcd->layer = LTDC_ACTIVE_LAYER_BACKGROUND;
+
+  /* Call first MSP Initialize only in case of first initialization
+  * This will set IP blocks LTDC, DSI and DMA2D
+  * - out of reset
+  * - clocked
+  * - NVIC IRQ related to IP blocks enabled
+  */
+	/** @brief Enable the LTDC clock */
+	sil_orw_mem((uint32_t *)(TADR_RCC_BASE+TOFF_RCC_APB2ENR), RCC_APB2ENR_LTDCEN);
+
+
+	/** @brief Toggle Sw reset of LTDC IP */
+	sil_orw_mem((uint32_t *)(TADR_RCC_BASE+TOFF_RCC_APB2RSTR), RCC_APB2RSTR_LTDCRST);
+	sil_andw_mem((uint32_t *)(TADR_RCC_BASE+TOFF_RCC_APB2RSTR), RCC_APB2RSTR_LTDCRST);
+
+	/** @brief Enable the DMA2D clock */
+	sil_orw_mem((uint32_t *)(TADR_RCC_BASE+TOFF_RCC_AHB1ENR), RCC_AHB1ENR_DMA2DEN);
+
+	/** @brief Toggle Sw reset of DMA2D IP */
+	sil_orw_mem((uint32_t *)(TADR_RCC_BASE+TOFF_RCC_AHB1RSTR), RCC_AHB1RSTR_DMA2DRST);
+	sil_andw_mem((uint32_t *)(TADR_RCC_BASE+TOFF_RCC_AHB1RSTR), RCC_AHB1RSTR_DMA2DRST);
+
+	/** @brief Enable DSI Host and wrapper clocks */
+	sil_orw_mem((uint32_t *)(TADR_RCC_BASE+TOFF_RCC_APB2ENR), RCC_APB2ENR_DSIEN);
+
+	/** @brief Soft Reset the DSI Host and wrapper */
+	sil_orw_mem((uint32_t *)(TADR_RCC_BASE+TOFF_RCC_APB2RSTR), RCC_APB2RSTR_DSIRST);
+	sil_andw_mem((uint32_t *)(TADR_RCC_BASE+TOFF_RCC_APB2RSTR), RCC_APB2RSTR_DSIRST);
+
+/*************************DSI Initialization***********************************/  
+
+	/* Base address of DSI Host/Wrapper registers to be set before calling De-Init */
+	hlcd->hdsi = hdsi;
+	hdsi->base = TADR_DSI_BASE;
+
+	dsi_deinit(hlcd->hdsi);
+
+	hdsi->Init.pllndiv = 100;
+	hdsi->Init.pllidf  = DSI_PLL_IN_DIV5;
+	hdsi->Init.pllodf  = DSI_PLL_OUT_DIV1;
+	laneByteClk_kHz = 62500; /* 500 MHz / 8 = 62.5 MHz = 62500 kHz */
+
+	/* Set number of Lanes */
+	hdsi->Init.NumberOfLanes = DSI_TWO_DATA_LANES;
+
+	/* TXEscapeCkdiv = f(LaneByteClk)/15.62 = 4 */
+	hdsi->Init.TXEscapeCkdiv = laneByteClk_kHz/15620;
+
+	dsi_init(hlcd->hdsi);
+
+	/* Timing parameters for all Video modes
+	 * Set Timing parameters of LTDC depending on its chosen orientation
+	 */
+	if(orientation == LCD_ORIENTATION_PORTRAIT){
+		hlcd->_width  = OTM8009A_480X800_WIDTH;  /* 480 */
+		hlcd->_height = OTM8009A_480X800_HEIGHT; /* 800 */                                
+	}
+	else{
+		/* lcd_orientation == LCD_ORIENTATION_LANDSCAPE */
+		hlcd->_width  = OTM8009A_800X480_WIDTH;  /* 800 */
+		hlcd->_height = OTM8009A_800X480_HEIGHT; /* 480 */                                
+	}
+
+	HACT = hlcd->_width;
+	VACT = hlcd->_height;
+
+	/* The following values are same for portrait and landscape orientations */
+	VSA  = OTM8009A_480X800_VSYNC;        /* 12  */
+	VBP  = OTM8009A_480X800_VBP;          /* 12  */
+	VFP  = OTM8009A_480X800_VFP;          /* 12  */
+	HSA  = OTM8009A_480X800_HSYNC;        /* 63  */
+	HBP  = OTM8009A_480X800_HBP;          /* 120 */
+	HFP  = OTM8009A_480X800_HFP;          /* 120 */   
+
+	hlcd->dsivc.VirtualChannelID = LCD_OTM8009A_ID;
+	hlcd->dsivc.ColorCoding = LCD_DSI_PIXEL_DATA_FMT_RBG888;
+	hlcd->dsivc.VSPolarity = DSI_VSYNC_ACTIVE_HIGH;
+	hlcd->dsivc.HSPolarity = DSI_HSYNC_ACTIVE_HIGH;
+	hlcd->dsivc.DEPolarity = DSI_DATA_ENABLE_ACTIVE_HIGH;  
+	hlcd->dsivc.Mode = DSI_VID_MODE_BURST; /* Mode Video burst ie : one LgP per line */
+	hlcd->dsivc.NullPacketSize = 0xFFF;
+	hlcd->dsivc.NumberOfChunks = 0;
+	hlcd->dsivc.PacketSize                = HACT; /* Value depending on display orientation choice portrait/landscape */ 
+	hlcd->dsivc.HorizontalSyncActive      = (HSA * laneByteClk_kHz)/LcdClock;
+	hlcd->dsivc.HorizontalBackPorch       = (HBP * laneByteClk_kHz)/LcdClock;
+	hlcd->dsivc.HorizontalLine            = ((HACT + HSA + HBP + HFP) * laneByteClk_kHz)/LcdClock; /* Value depending on display orientation choice portrait/landscape */
+	hlcd->dsivc.VerticalSyncActive        = VSA;
+	hlcd->dsivc.VerticalBackPorch         = VBP;
+	hlcd->dsivc.VerticalFrontPorch        = VFP;
+	hlcd->dsivc.VerticalActive            = VACT; /* Value depending on display orientation choice portrait/landscape */
+
+	/* Enable or disable sending LP command while streaming is active in video mode */
+	hlcd->dsivc.LPCommandEnable = DSI_LP_COMMAND_ENABLE; /* Enable sending commands in mode LP (Low Power) */
+
+	/* Largest packet size possible to transmit in LP mode in VSA, VBP, VFP regions */
+	/* Only useful when sending LP packets is allowed while streaming is active in video mode */
+	hlcd->dsivc.LPLargestPacketSize = 16;
+
+	/* Largest packet size possible to transmit in LP mode in HFP region during VACT period */
+	/* Only useful when sending LP packets is allowed while streaming is active in video mode */
+	hlcd->dsivc.LPVACTLargestPacketSize = 0;
+
+	/* Specify for each region of the video frame, if the transmission of command in LP mode is allowed in this region */
+	/* while streaming is active in video mode                                                                         */
+	hlcd->dsivc.LPHorizontalFrontPorchEnable = DSI_LP_HFP_ENABLE;   /* Allow sending LP commands during HFP period */
+	hlcd->dsivc.LPHorizontalBackPorchEnable  = DSI_LP_HBP_ENABLE;   /* Allow sending LP commands during HBP period */
+	hlcd->dsivc.LPVerticalActiveEnable = DSI_LP_VACT_ENABLE;  /* Allow sending LP commands during VACT period */
+	hlcd->dsivc.LPVerticalFrontPorchEnable = DSI_LP_VFP_ENABLE;   /* Allow sending LP commands during VFP period */
+	hlcd->dsivc.LPVerticalBackPorchEnable = DSI_LP_VBP_ENABLE;   /* Allow sending LP commands during VBP period */
+	hlcd->dsivc.LPVerticalSyncActiveEnable = DSI_LP_VSYNC_ENABLE; /* Allow sending LP commands during VSync = VSA period */
+
+	/* Configure DSI Video mode timings with settings set above */
+	dsi_configvideo(hlcd->hdsi, &hlcd->dsivc);
+
+/*************************End DSI Initialization*******************************/ 
+
+
+/************************LTDC Initialization***********************************/  
+
+	/* Timing Configuration */
+	hldtc->Init.HorizontalSync = (HSA - 1);
+	hldtc->Init.AccumulatedHBP = (HSA + HBP - 1);
+	hldtc->Init.AccumulatedActiveW = (hlcd->_width + HSA + HBP - 1);
+	hldtc->Init.TotalWidth = (hlcd->_width + HSA + HBP + HFP - 1);
+
+	/* Initialize the LCD pixel width and pixel height */
+	hldtc->LayerCfg->ImageWidth  = hlcd->_width;
+	hldtc->LayerCfg->ImageHeight = hlcd->_height;
+
+	/** LCD clock configuration
+	 * Note: The following values should not be changed as the PLLSAI is also used 
+	 *      to clock the USB FS
+	 * PLLSAI_VCO Input = HSE_VALUE/PLL_M = 1 Mhz 
+	 * PLLSAI_VCO Output = PLLSAI_VCO Input * PLLSAIN = 384 Mhz 
+	 * PLLLCDCLK = PLLSAI_VCO Output/PLLSAIR = 384 MHz / 7 = 54.85 MHz 
+	 * LTDC clock frequency = PLLLCDCLK / LTDC_PLLSAI_DIVR_2 = 54.85 MHz / 2 = 27.429 MHz 
+	 */
+	/* Background value */
+	hldtc->Init.Backcolor.Blue = 0;
+	hldtc->Init.Backcolor.Green = 0;
+	hldtc->Init.Backcolor.Red = 0;
+	hldtc->Init.PCPolarity = LTDC_PCPOLARITY_IPC;
+	hldtc->Init.pllsain = 384;
+	hldtc->Init.pllsair = 7;
+	hldtc->Init.saidivr = RCC_PLLSAIDIVR_2;
+	hldtc->base = TADR_LTDC_BASE;
+
+	/* Get LTDC Configuration from DSI Configuration */
+	dci_configltdc(hldtc, &hlcd->dsivc);
+
+	/* Initialize the LTDC */  
+	ltdc_init(hldtc);
+	hlcd->hltdc = hldtc;
+
+	/* Enable the DSI host and wrapper after the LTDC initialization
+	   To avoid any synchronization issue, the DSI shall be started after enabling the LTDC */
+	dsi_start(hlcd->hdsi);
+
+	/* Initialize the font */
+//	BSP_LCD_SetFont(&LCD_DEFAULT_FONT);
+
+/************************End LTDC Initialization*******************************/
+  
+  
+/***********************OTM8009A Initialization********************************/ 
+
+	/* Initialize the OTM8009A LCD Display IC Driver (KoD LCD IC Driver)
+	 *  depending on configuration set in 'hdsivideo_handle'.
+	 */
+	OTM8009A_Init(hlcd->hdsi, OTM8009A_FORMAT_RGB888, orientation);
+
+/***********************End OTM8009A Initialization****************************/ 
+	return E_OK;
+}
+
+/*
+ *  DSI/OTM8009Aスクリーンのリセット関数
+ */
+ER
+lcd_reset(LCD_Handler_t *hlcd)
+{
+	GPIO_Init_t  gpio_init_structure;
+	uint32_t base = TADR_GPIOJ_BASE;
+
+	sil_orw_mem((uint32_t *)(TADR_RCC_BASE+TOFF_RCC_AHB1ENR), RCC_AHB1ENR_GPIOJEN);
+
+    /* Configure the GPIO on PJ15 */
+    gpio_init_structure.mode  = GPIO_MODE_OUTPUT;
+    gpio_init_structure.pull  = GPIO_PULLUP;
+    gpio_init_structure.otype = GPIO_OTYPE_PP;
+    gpio_init_structure.speed = GPIO_SPEED_HIGH;
+	gpio_setup(base, &gpio_init_structure, PINPOSITION15);
+
+    sil_wrw_mem((uint32_t *)(base+TOFF_GPIO_BSRR), GPIO_PIN_15<<16);
+	sil_dly_nse(100);
+
+    dly_tsk(20); /* wait 20 ms */
+
+    /* Desactivate XRES */
+    sil_wrw_mem((uint32_t *)(base+TOFF_GPIO_BSRR), GPIO_PIN_15);
+
+    /* Wait for 10ms after releasing XRES before sending commands */
+    dly_tsk(10);
+	return E_OK;
+}
+
+
+/*
+ *  DSI/OTM8009Aスクリーンレイヤ初期化関数
+ */
+ER
+lcd_layerdefaultinit(LCD_Handler_t *hlcd, LCD_DrawProp_t *pDrawProp, uint16_t LayerIndex, uint32_t FB_Address)
+{
+    LTDC_LayerCfg_t  Layercfg;
+
+	/* Layer Init */
+	Layercfg.WindowX0 = 0;
+	Layercfg.WindowX1 = hlcd->_width;
+	Layercfg.WindowY0 = 0;
+	Layercfg.WindowY1 = hlcd->_height;
+	Layercfg.PixelFormat = LTDC_PIXEL_FORMAT_ARGB8888;
+	Layercfg.FBStartAdress = FB_Address;
+	Layercfg.Alpha = 255;
+	Layercfg.Alpha0 = 0;
+	Layercfg.Backcolor.Blue = 0;
+	Layercfg.Backcolor.Green = 0;
+	Layercfg.Backcolor.Red = 0;
+	Layercfg.BlendingFactor1 = LTDC_BLENDING_FACTOR1_PAxCA;
+	Layercfg.BlendingFactor2 = LTDC_BLENDING_FACTOR2_PAxCA;
+	Layercfg.ImageWidth = hlcd->_width;
+	Layercfg.ImageHeight = hlcd->_height;
+
+	ltdc_configlayer(hlcd->hltdc, &Layercfg, LayerIndex);
+
+	hlcd->layer = LayerIndex;
+	pDrawProp[LayerIndex].BackColor = LCD_COLOR_WHITE;
+	pDrawProp[LayerIndex].TextColor = LCD_COLOR_BLACK;
+	pDrawProp[LayerIndex].hlcd      = hlcd;
+	return E_OK;
+}
+
+/*
+ *  DSI/OTM8009Aスクリーンレイヤ表示設定関数
+ */
+void
+lcd_setlayervisible(LCD_Handler_t *hlcd, uint32_t LayerIndex, uint8_t State)
+{
+	uint32_t layer = (TADR_LTDC_LAYER1 + (LTDC_WINDOW_SIZE * LayerIndex));
+	if(State == 1){
+		sil_orw_mem((uint32_t *)(layer+TOFF_LTDCW_CR), LTDC_CR_LEN);
+	}
+	else{
+		sil_andw_mem((uint32_t *)(layer+TOFF_LTDCW_CR), LTDC_CR_LEN);
+	}
+	sil_orw_mem((uint32_t *)(TADR_LTDC_BASE+TOFF_LTDC_SRCR), LTDC_SRCR_IMR);
+}
+
+/*
+ *  DSI/OTM8009Aスクリーンレイヤ透過設定関数
+ */
+void
+lcd_settransparency(LCD_Handler_t *hlcd, uint32_t LayerIndex, uint8_t Transparency)
+{
+	ltdc_setalpha(hlcd->hltdc, Transparency, LayerIndex);
+}
+
+/*
+ *  DSI/OTM8009AスクリーンレイヤRAMアドレス設定関数
+ */
+void
+lcd_setlayeraddress(LCD_Handler_t *hlcd, uint32_t LayerIndex, uint32_t Address)
+{
+	ltdc_setaddress(hlcd->hltdc, Address, LayerIndex);
+}
+
+/*
+ *  DSI/OTM8009A表示ウィンドウ設定
+ */
+void
+lcd_setAddrWindow(LCD_Handler_t *hlcd, uint16_t LayerIndex, uint16_t Xpos, uint16_t Ypos, uint16_t Width, uint16_t Height)
+{
+	/* Reconfigure the layer size */
+	ltdc_setwindowsize(hlcd->hltdc, Width, Height, LayerIndex);
+
+	/* Reconfigure the layer position */
+	ltdc_setwindowposition(hlcd->hltdc, Xpos, Ypos, LayerIndex);
+}
+
+/**
+  * @brief  Configures and sets the color keying.
+  * @param  LayerIndex: Layer foreground or background
+  * @param  RGBValue: Color reference
+  */
+void
+lcd_setcolorkeying(LCD_Handler_t *hlcd, uint32_t LayerIndex, uint32_t RGBValue)
+{
+	/* Configure and Enable the color Keying for LCD Layer */
+	ltdc_configcolorkeying(hlcd->hltdc, RGBValue, LayerIndex);
+	ltdc_enablecolorkeying(hlcd->hltdc, LayerIndex);
+}
+
+/**
+  * @brief  Disables the color keying.
+  * @param  LayerIndex: Layer foreground or background
+  */
+void
+lcd_resetcolorkeying(LCD_Handler_t *hlcd, uint32_t LayerIndex)
+{
+	/* Disable the color Keying for LCD Layer */
+	ltdc_disablecolorkeying(hlcd->hltdc, LayerIndex);
+}
+
+/*
+ *  DSI/OTM8009Aスクリーンクリア
+ */
+void
+lcd_clear(LCD_Handler_t *hlcd, uint32_t Color)
+{
+	/* Clear the LCD */
+	LL_FillBuffer(hlcd->layer, (uint32_t *)(hlcd->hltdc->LayerCfg[hlcd->layer].FBStartAdress), hlcd->_width, hlcd->_height, 0, Color);
+}
+
+/*
+ *  PIXEL読み出し
+ *  param1  hlcd: Pointer to LCD Handler
+ *  param2  x: X position
+ *  param3  y: Y position
+ */
+uint32_t
+lcd_readPixel(LCD_Handler_t *hlcd, uint16_t Xpos, uint16_t Ypos)
+{
+	LTDC_Handle_t  *hltdc = hlcd->hltdc;
+	uint32_t ret = 0;
+
+	if(hltdc->LayerCfg[hlcd->layer].PixelFormat == LTDC_PIXEL_FORMAT_ARGB8888){
+		/* Read data value from SDRAM memory */
+		ret = *(volatile uint32_t*)(hltdc->LayerCfg[hlcd->layer].FBStartAdress + (2*(Ypos*hlcd->_width + Xpos)));
+	}
+	else if(hltdc->LayerCfg[hlcd->layer].PixelFormat == LTDC_PIXEL_FORMAT_RGB888){
+		/* Read data value from SDRAM memory */
+		ret = (*(volatile uint32_t*) (hltdc->LayerCfg[hlcd->layer].FBStartAdress + (2*(Ypos*hlcd->_width + Xpos))) & 0x00FFFFFF);
+	}
+	else if((hltdc->LayerCfg[hlcd->layer].PixelFormat == LTDC_PIXEL_FORMAT_RGB565) || \
+          (hltdc->LayerCfg[hlcd->layer].PixelFormat == LTDC_PIXEL_FORMAT_ARGB4444) || \
+          (hltdc->LayerCfg[hlcd->layer].PixelFormat == LTDC_PIXEL_FORMAT_AL88)){
+		/* Read data value from SDRAM memory */
+		ret = *(volatile uint16_t*) (hltdc->LayerCfg[hlcd->layer].FBStartAdress + (2*(Ypos*hlcd->_width + Xpos)));
+	}
+	else{
+		/* Read data value from SDRAM memory */
+		ret = *(volatile uint8_t*) (hltdc->LayerCfg[hlcd->layer].FBStartAdress + (2*(Ypos*hlcd->_width + Xpos)));
+	}
+	return ret;
+}
+
+/*
+ *  PIXEL描画
+ *  param1  hlcd: Pointer to LCD Handler
+ *  param2  x: X position
+ *  param3  y: Y position
+ *  param4  color: color value
+ */
+void
+lcd_drawPixel(LCD_Handler_t *hlcd, uint16_t Xpos, uint16_t Ypos, uint32_t RGB_Code)
+{
+	/* Write data value to all SDRAM memory */
+	*(volatile uint32_t*) (hlcd->hltdc->LayerCfg[hlcd->layer].FBStartAdress + (4*(Ypos*hlcd->_width + Xpos))) = RGB_Code;
+}
+
+/*
+ *  垂直方向LINEの高速描画
+ *  param1  hlcd: Pointer to LCD Handler
+ *  param2  x: start X position
+ *  param3  y: start Y position
+ *  param4  h: height
+ *  param5  color: color value
+ */
+void
+lcd_drawFastHLine(LCD_Handler_t *hlcd, uint16_t Xpos, uint16_t Ypos, uint16_t Length, uint32_t color)
+{
+	uint32_t  Xaddress = 0;
+
+	/* Get the line address */
+	Xaddress = (hlcd->hltdc->LayerCfg[hlcd->layer].FBStartAdress) + 4*(hlcd->_width*Ypos + Xpos);
+
+	/* Write line */
+	LL_FillBuffer(hlcd->layer, (uint32_t *)Xaddress, Length, 1, 0, color);
+}
+
+/*
+ *  水平方向LINEの高速描画
+ *  param1  hlcd: Pointer to LCD Handler
+ *  param2  x: start X position
+ *  param3  y: start Y position
+ *  param4  w: width
+ *  param5  color: color value
+ */
+void
+lcd_drawFastVLine(LCD_Handler_t *hlcd, uint16_t Xpos, uint16_t Ypos, uint16_t Length, uint32_t color)
+{
+	uint32_t  Xaddress = 0;
+
+	/* Get the line address */
+	Xaddress = (hlcd->hltdc->LayerCfg[hlcd->layer].FBStartAdress) + 4*(hlcd->_width*Ypos + Xpos);
+
+	/* Write line */
+	LL_FillBuffer(hlcd->layer, (uint32_t *)Xaddress, 1, Length, (hlcd->_width - 1), color);
+}
+
+/*
+ *  BITMAP描画
+ *  param1  hlcd: Pointer to LCD Handler
+ *  param2  x0: Bmp X position in the LCD
+ *  param3  y0: Bmp Y position in the LCD
+ *  param4  pbmp: Pointer to Bmp picture address in the internal Flash
+ */
+void
+lcd_drawBitmap(LCD_Handler_t *hlcd, uint32_t Xpos, uint32_t Ypos, uint8_t *pbmp)
+{
+	uint32_t index = 0, width = 0, height = 0, bit_pixel = 0;
+	uint32_t Address;
+	uint32_t InputColorMode = 0;
+
+	/* Get bitmap data address offset */
+	index = *(volatile uint16_t *) (pbmp + 10);
+	index |= (*(volatile uint16_t *) (pbmp + 12)) << 16;
+
+	/* Read bitmap width */
+	width = *(volatile uint16_t *) (pbmp + 18);
+	width |= (*(volatile uint16_t *) (pbmp + 20)) << 16;
+
+	/* Read bitmap height */
+	height = *(volatile uint16_t *) (pbmp + 22);
+	height |= (*(volatile uint16_t *) (pbmp + 24)) << 16;
+
+	/* Read bit/pixel */
+	bit_pixel = *(uint16_t *) (pbmp + 28);
+
+	/* Set the address */
+	Address = hlcd->hltdc->LayerCfg[hlcd->layer].FBStartAdress + (((hlcd->_width*Ypos) + Xpos)*(4));
+
+	/* Get the layer pixel format */
+	if((bit_pixel/8) == 4){
+		InputColorMode = DMA2D_ARGB8888;
+	}
+	else if((bit_pixel/8) == 2){
+		InputColorMode = DMA2D_RGB565;
+	}
+	else{
+		InputColorMode = DMA2D_RGB888;
+	}
+
+	/* Bypass the bitmap header */
+	pbmp += (index + (width * (height - 1) * (bit_pixel/8)));
+
+	/* Convert picture to ARGB8888 pixel format */
+	for(index=0; index < height; index++){
+		/* Pixel format conversion */
+		LL_ConvertLineToARGB8888((uint32_t *)pbmp, (uint32_t *)Address, width, InputColorMode);
+
+		/* Increment the source and destination buffers */
+		Address+=  (hlcd->_width*4);
+		pbmp -= width*(bit_pixel/8);
+	}
+}
+
+/*
+ *  表示オン
+ *  param1  hlcd: Pointer to LCD Handler
+ */
+void
+lcd_displayOn(LCD_Handler_t *hlcd)
+{
+    /* Send Display on DCS command to display */
+    dsi_swrite(hlcd->hdsi, hlcd->dsivc.VirtualChannelID,
+                       DSI_DCS_SHORT_PKT_WRITE_P1,
+                       OTM8009A_CMD_DISPON,
+                       0x00);
+}
+
+/*
+ *  表示オフ
+ *  param1  hlcd: Pointer to LCD Handler
+ */
+void
+lcd_displayOff(LCD_Handler_t *hlcd)
+{
+    /* Send Display off DCS Command to display */
+    dsi_swrite(hlcd->hdsi, hlcd->dsivc.VirtualChannelID,
+                       DSI_DCS_SHORT_PKT_WRITE_P1,
+                       OTM8009A_CMD_DISPOFF,
+                       0x00);
+}
+
+/**
+  * @brief  Set the brightness value 
+  * @param  BrightnessValue: [00: Min (black), 100 Max]
+  */
+void
+lcd_setbrightness(LCD_Handler_t *hlcd, uint8_t BrightnessValue)
+{
+    /* Send Display on DCS command to display */
+    dsi_swrite(hlcd->hdsi, LCD_OTM8009A_ID, 
+                       DSI_DCS_SHORT_PKT_WRITE_P1, 
+                       OTM8009A_CMD_WRDISBV, (uint16_t)(BrightnessValue * 255)/100);
+}
+
+/*
+ *  RECTANGLE塗りつぶし描画
+ *  param1  hlcd: Pointer to LCD Handler
+ *  param2  x: left X position
+ *  param3  y: top Y position
+ *  param4  w: width
+ *  param5  h: height
+ *  param6  color: color value
+ */
+void
+lcd_fillRect(LCD_Handler_t *hlcd, uint16_t Xpos, uint16_t Ypos, uint16_t Width, uint16_t Height, uint32_t color)
+{
+	uint32_t  Xaddress = 0;
+
+	/* Get the rectangle start address */
+	Xaddress = (hlcd->hltdc->LayerCfg[hlcd->layer].FBStartAdress) + 4*(hlcd->_width*Ypos + Xpos);
+
+	/* Fill the rectangle */
+	LL_FillBuffer(hlcd->layer, (uint32_t *)Xaddress, Width, Height, (hlcd->_width - Width), color);
+}
+
+
+/*
+ *  線描画
+ *  param1  pDrawProp: Pointer to Draw Prop
+ *  param2  x1: Point 1 X position
+ *  param3  y1: Point 1 Y position
+ *  param4  x2: Point 2 X position
+ *  param5  y2: Point 2 Y position
+ */
+void
+lcd_drawLine(LCD_DrawProp_t *pDrawProp, uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2)
+{
+	LCD_Handler_t *hlcd = pDrawProp->hlcd;
+	int16_t deltax = 0, deltay = 0, x = 0, y = 0, xinc1 = 0, xinc2 = 0,
+	yinc1 = 0, yinc2 = 0, den = 0, num = 0, numadd = 0, numpixels = 0,
+	curpixel = 0;
+
+	deltax = ABS(x2 - x1);        /* The difference between the x's */
+	deltay = ABS(y2 - y1);        /* The difference between the y's */
+	x = x1;                       /* Start x off at the first pixel */
+	y = y1;                       /* Start y off at the first pixel */
+
+	if(x2 >= x1){				/* The x-values are increasing */
+		xinc1 = 1;
+		xinc2 = 1;
+	}
+	else{						/* The x-values are decreasing */
+		xinc1 = -1;
+		xinc2 = -1;
+	}
+
+	if(y2 >= y1){				/* The y-values are increasing */
+		yinc1 = 1;
+		yinc2 = 1;
+	}
+	else{						/* The y-values are decreasing */
+		yinc1 = -1;
+		yinc2 = -1;
+	}
+
+	if(deltax >= deltay){		/* There is at least one x-value for every y-value */
+		xinc1 = 0;                  /* Don't change the x when numerator >= denominator */
+		yinc2 = 0;                  /* Don't change the y for every iteration */
+		den = deltax;
+		num = deltax / 2;
+		numadd = deltay;
+		numpixels = deltax;         /* There are more x-values than y-values */
+	}
+	else{							/* There is at least one y-value for every x-value */
+		xinc2 = 0;                  /* Don't change the x for every iteration */
+		yinc1 = 0;                  /* Don't change the y when numerator >= denominator */
+		den = deltay;
+		num = deltay / 2;
+		numadd = deltax;
+		numpixels = deltay;         /* There are more y-values than x-values */
+	}
+
+	for(curpixel = 0; curpixel <= numpixels; curpixel++){
+		lcd_drawPixel(hlcd, x, y, pDrawProp->TextColor);	/* Draw the current pixel */
+		num += numadd;				/* Increase the numerator by the top of the fraction */
+		if(num >= den){				/* Check if numerator >= denominator */
+			num -= den;				/* Calculate the new numerator value */
+			x += xinc1;				/* Change the x as appropriate */
+			y += yinc1;				/* Change the y as appropriate */
+		}
+		x += xinc2;					/* Change the x as appropriate */
+		y += yinc2;					/* Change the y as appropriate */
+	}
+}
+
+/*
+ *  RECTANGLE描画
+ *  param1  pDrawProp: Pointer to Draw Prop
+ *  param2  x: left X position
+ *  param3  y: top Y position
+ *  param4  w: width
+ *  param5  h: height
+ */
+void
+lcd_drawRect(LCD_DrawProp_t *pDrawProp, uint16_t Xpos, uint16_t Ypos, uint16_t Width, uint16_t Height)
+{
+	LCD_Handler_t *hlcd = pDrawProp->hlcd;
+	uint32_t      color = pDrawProp->TextColor;
+
+	/* Draw horizontal lines */
+	lcd_drawFastHLine(hlcd, Xpos, Ypos, Width, color);
+	lcd_drawFastHLine(hlcd, Xpos, (Ypos+ Height), Width, color);
+
+	/* Draw vertical lines */
+	lcd_drawFastVLine(hlcd, Xpos, Ypos, Height, color);
+	lcd_drawFastVLine(hlcd, (Xpos + Width), Ypos, Height, color);
+}
+
+/*
+ *  円描画
+ *  param1  pDrawProp: Pointer to Draw Prop
+ *  param2  x0: X position
+ *  param3  y0: Y position
+ *  param4  Radius: Circle radius
+ */
+void
+lcd_DrawCircle(LCD_DrawProp_t *pDrawProp, uint16_t Xpos, uint16_t Ypos, uint16_t Radius)
+{
+	LCD_Handler_t *hlcd = pDrawProp->hlcd;
+	uint32_t      color = pDrawProp->TextColor;
+	int32_t   D;    /* Decision Variable */
+	uint32_t  CurX; /* Current X Value */
+	uint32_t  CurY; /* Current Y Value */
+
+	D = 3 - (Radius << 1);
+	CurX = 0;
+	CurY = Radius;
+
+	while (CurX <= CurY){
+		lcd_drawPixel(hlcd, (Xpos + CurX), (Ypos - CurY), color);
+		lcd_drawPixel(hlcd, (Xpos - CurX), (Ypos - CurY), color);
+		lcd_drawPixel(hlcd, (Xpos + CurY), (Ypos - CurX), color);
+		lcd_drawPixel(hlcd, (Xpos - CurY), (Ypos - CurX), color);
+		lcd_drawPixel(hlcd, (Xpos + CurX), (Ypos + CurY), color);
+		lcd_drawPixel(hlcd, (Xpos - CurX), (Ypos + CurY), color);
+		lcd_drawPixel(hlcd, (Xpos + CurY), (Ypos + CurX), color);
+		lcd_drawPixel(hlcd, (Xpos - CurY), (Ypos + CurX), color);
+		if(D < 0){
+			D += (CurX << 2) + 6;
+		}
+		else{
+			D += ((CurX - CurY) << 2) + 10;
+			CurY--;
+		}
+		CurX++;
+	}
+}
+
+/*
+ *  楕円描画
+ *  param1  pDrawProp: Pointer to Draw Prop
+ *  param2  x0: X position
+ *  param3  y0: Y position
+ *  param4  XRadius: Ellipse X radius
+ *  param5  YRadius: Ellipse Y radius
+ */
+void
+lcd_DrawEllipse(LCD_DrawProp_t *pDrawProp, int Xpos, int Ypos, int XRadius, int YRadius)
+{
+	LCD_Handler_t *hlcd = pDrawProp->hlcd;
+	uint32_t      color = pDrawProp->TextColor;
+	int x = 0, y = -YRadius, err = 2-2*XRadius, e2;
+	float K = 0, rad1 = 0, rad2 = 0;
+
+	rad1 = XRadius;
+	rad2 = YRadius;
+
+	K = (float)(rad2/rad1);
+
+	do{
+		lcd_drawPixel(hlcd, (Xpos-(uint16_t)(x/K)), (Ypos+y), color);
+		lcd_drawPixel(hlcd, (Xpos+(uint16_t)(x/K)), (Ypos+y), color);
+		lcd_drawPixel(hlcd, (Xpos+(uint16_t)(x/K)), (Ypos-y), color);
+		lcd_drawPixel(hlcd, (Xpos-(uint16_t)(x/K)), (Ypos-y), color);
+
+		e2 = err;
+		if(e2 <= x){
+			err += ++x*2+1;
+			if (-y == x && e2 <= y)
+				e2 = 0;
+		}
+		if(e2 > y)
+			err += ++y*2+1;
+	}while (y <= 0);
+}
+
+/*
+ *  PLOY-LINE描画
+ *  param1  pDrawProp: Pointer to Draw Prop
+ *  param2  Points: Pointer to the points array
+ *  param3  PointCount: Number of points
+ */
+void
+lcd_drawPolygon(LCD_DrawProp_t *pDrawProp, pPoint Points, uint16_t PointCount)
+{
+	int16_t X = 0, Y = 0;
+
+	if(PointCount < 2){
+		return;
+	}
+
+	lcd_drawLine(pDrawProp, Points->X, Points->Y, (Points+PointCount-1)->X, (Points+PointCount-1)->Y);
+
+	while(--PointCount){
+		X = Points->X;
+		Y = Points->Y;
+		Points++;
+		lcd_drawLine(pDrawProp, X, Y, Points->X, Points->Y);
+	}
+}
+
+/*
+ *  円塗りつぶし描画
+ *  param1  pDrawProp: Pointer to Draw Prop
+ *  param2  x0: X position
+ *  param3  y0: Y position
+ *  param4  Radius: Circle radius
+ */
+void
+lcd_fillCircle(LCD_DrawProp_t *pDrawProp, uint16_t Xpos, uint16_t Ypos, uint16_t Radius)
+{
+	LCD_Handler_t *hlcd = pDrawProp->hlcd;
+	uint32_t      color = pDrawProp->TextColor;
+	int32_t  D;     /* Decision Variable */
+	uint32_t  CurX; /* Current X Value */
+	uint32_t  CurY; /* Current Y Value */
+
+	D = 3 - (Radius << 1);
+
+	CurX = 0;
+	CurY = Radius;
+
+	while (CurX <= CurY){
+		if(CurY > 0){
+			lcd_drawFastHLine(hlcd, Xpos - CurY, Ypos + CurX, 2*CurY, color);
+			lcd_drawFastHLine(hlcd, Xpos - CurY, Ypos - CurX, 2*CurY, color);
+		}
+
+		if(CurX > 0){
+			lcd_drawFastHLine(hlcd, Xpos - CurX, Ypos - CurY, 2*CurX, color);
+			lcd_drawFastHLine(hlcd, Xpos - CurX, Ypos + CurY, 2*CurX, color);
+		}
+		if(D < 0){
+			D += (CurX << 2) + 6;
+		}
+		else{
+			D += ((CurX - CurY) << 2) + 10;
+			CurY--;
+		}
+		CurX++;
+	}
+
+	lcd_DrawCircle(pDrawProp, Xpos, Ypos, Radius);
+}
+
+/*
+ *  楕円塗りつぶし描画
+ *  param1  pDrawProp: Pointer to Draw Prop
+ *  param2  x0: X position
+ *  param3  y0: Y position
+ *  param4  XRadius: Ellipse X radius
+ *  param5  YRadius: Ellipse Y radius
+ */
+void
+lcd_fillEllipse(LCD_DrawProp_t *pDrawProp, int Xpos, int Ypos, int XRadius, int YRadius)
+{
+	LCD_Handler_t *hlcd = pDrawProp->hlcd;
+	int x = 0, y = -YRadius, err = 2-2*XRadius, e2;
+	float K = 0, rad1 = 0, rad2 = 0;
+
+	rad1 = XRadius;
+	rad2 = YRadius;
+
+	K = (float)(rad2/rad1);
+
+	do{
+		lcd_drawFastHLine(hlcd, (Xpos-(uint16_t)(x/K)), (Ypos+y), (2*(uint16_t)(x/K) + 1), pDrawProp->TextColor);
+		lcd_drawFastHLine(hlcd, (Xpos-(uint16_t)(x/K)), (Ypos-y), (2*(uint16_t)(x/K) + 1), pDrawProp->TextColor);
+
+		e2 = err;
+		if(e2 <= x){
+			err += ++x*2+1;
+			if (-y == x && e2 <= y)
+				e2 = 0;
+		}
+		if(e2 > y)
+			err += ++y*2+1;
+	}while (y <= 0);
+}
+
+/*
+ *  PLOY-LINE塗りつぶし描画
+ *  param1  pDrawProp: Pointer to Draw Prop
+ *  param2  Points: Pointer to the points array
+ *  param3  PointCount: Number of points
+ */
+void
+lcd_fillPolygon(LCD_DrawProp_t *pDrawProp, pPoint Points, uint16_t PointCount)
+{
+	int16_t X = 0, Y = 0, X2 = 0, Y2 = 0, X_center = 0, Y_center = 0, X_first = 0, Y_first = 0, pixelX = 0, pixelY = 0, counter = 0;
+	uint16_t  IMAGE_LEFT = 0, IMAGE_RIGHT = 0, IMAGE_TOP = 0, IMAGE_BOTTOM = 0;
+
+	IMAGE_LEFT = IMAGE_RIGHT = Points->X;
+	IMAGE_TOP= IMAGE_BOTTOM = Points->Y;
+
+	for(counter = 1; counter < PointCount; counter++){
+		pixelX = POLY_X(counter);
+		if(pixelX < IMAGE_LEFT){
+			IMAGE_LEFT = pixelX;
+		}
+		if(pixelX > IMAGE_RIGHT){
+			IMAGE_RIGHT = pixelX;
+		}
+
+		pixelY = POLY_Y(counter);
+		if(pixelY < IMAGE_TOP){
+			IMAGE_TOP = pixelY;
+		}
+		if(pixelY > IMAGE_BOTTOM){
+			IMAGE_BOTTOM = pixelY;
+		}
+	}
+
+	if(PointCount < 2){
+		return;
+	}
+
+	X_center = (IMAGE_LEFT + IMAGE_RIGHT)/2;
+	Y_center = (IMAGE_BOTTOM + IMAGE_TOP)/2;
+
+	X_first = Points->X;
+	Y_first = Points->Y;
+
+	while(--PointCount){
+		X = Points->X;
+		Y = Points->Y;
+		Points++;
+		X2 = Points->X;
+		Y2 = Points->Y;
+
+		FillTriangle(pDrawProp, X, X2, X_center, Y, Y2, Y_center);
+		FillTriangle(pDrawProp, X, X_center, X2, Y, Y_center, Y2);
+		FillTriangle(pDrawProp, X_center, X2, X, Y_center, Y2, Y);
+	}
+
+	FillTriangle(pDrawProp, X_first, X2, X_center, Y_first, Y2, Y_center);
+	FillTriangle(pDrawProp, X_first, X_center, X2, Y_first, Y_center, Y2);
+	FillTriangle(pDrawProp, X_center, X2, X_first, Y_center, Y2, Y_first);
+}
+
+/*******************************************************************************
+                       LTDC, DMA2D and DSI BSP Routines
+*******************************************************************************/
+
+/*
+ *  トライアングルフィル
+ *  param1  pDrawProp: Pointer to Draw Prop
+ *  param2  x1: 点1 X座標始点
+ *  param3  y1: 点1 Y座標始点
+ *  param4  x2: 点2 X座標始点
+ *  param5  y2: 点2 Y座標始点
+ *  param6  x3: 点3 X座標始点
+ *  param7  y3: 点3 Y座標始点
+ */
+static void
+FillTriangle(LCD_DrawProp_t *pDrawProp, uint16_t x1, uint16_t x2, uint16_t x3, uint16_t y1, uint16_t y2, uint16_t y3)
+{
+	int16_t deltax = 0, deltay = 0, x = 0, y = 0, xinc1 = 0, xinc2 = 0,
+	yinc1 = 0, yinc2 = 0, den = 0, num = 0, numadd = 0, numpixels = 0,
+	curpixel = 0;
+
+	deltax = ABS(x2 - x1);        /* The difference between the x's */
+	deltay = ABS(y2 - y1);        /* The difference between the y's */
+	x = x1;                       /* Start x off at the first pixel */
+	y = y1;                       /* Start y off at the first pixel */
+
+	if(x2 >= x1){				/* The x-values are increasing */
+		xinc1 = 1;
+		xinc2 = 1;
+	}
+	else{						/* The x-values are decreasing */
+		xinc1 = -1;
+		xinc2 = -1;
+	}
+
+	if(y2 >= y1){				/* The y-values are increasing */
+		yinc1 = 1;
+		yinc2 = 1;
+	}
+	else{						/* The y-values are decreasing */
+		yinc1 = -1;
+		yinc2 = -1;
+	}
+
+	if(deltax >= deltay){		/* There is at least one x-value for every y-value */
+		xinc1 = 0;                  /* Don't change the x when numerator >= denominator */
+		yinc2 = 0;                  /* Don't change the y for every iteration */
+		den = deltax;
+		num = deltax / 2;
+		numadd = deltay;
+		numpixels = deltax;         /* There are more x-values than y-values */
+	}
+	else{						/* There is at least one y-value for every x-value */
+		xinc2 = 0;                  /* Don't change the x for every iteration */
+		yinc1 = 0;                  /* Don't change the y when numerator >= denominator */
+		den = deltay;
+		num = deltay / 2;
+		numadd = deltax;
+		numpixels = deltay;         /* There are more y-values than x-values */
+	}
+
+	for(curpixel = 0; curpixel <= numpixels; curpixel++){
+		lcd_drawLine(pDrawProp, x, y, x3, y3);
+
+		num += numadd;              /* Increase the numerator by the top of the fraction */
+		if(num >= den){				/* Check if numerator >= denominator */
+			num -= den;				/* Calculate the new numerator value */
+			x += xinc1;               /* Change the x as appropriate */
+			y += yinc1;               /* Change the y as appropriate */
+		}
+		x += xinc2;                 /* Change the x as appropriate */
+		y += yinc2;                 /* Change the y as appropriate */
+	}
+}
+
+/*
+ *  バッファフィル
+ *  param1  hlcd: Pointer to LCD Handler
+ *  param2  pDst:バッファ先頭ポインタ
+ *  param3  xSize: バッファ幅
+ *  param3  ySize: バッファ高さ
+ *  param4  OffLine: 出力オフセット
+ *  param5  ColorIndex: フィルカラー
+ */
+static
+void LL_FillBuffer(uint32_t LayerIndex, void *pDst, uint32_t xSize, uint32_t ySize, uint32_t OffLine, uint32_t ColorIndex)
+{
+	/* Register to memory mode with ARGB8888 as color Mode */
+	hdma2d_discovery.Init.Mode         = DMA2D_R2M;
+	hdma2d_discovery.Init.ColorMode    = CM_ARGB8888;
+	hdma2d_discovery.Init.OutputOffset = OffLine;
+
+	hdma2d_discovery.base = TADR_DMA2D_BASE;
+
+	/* DMA2D Initialization */
+	if(dma2d_init(&hdma2d_discovery) == E_OK){
+		if(dma2d_configlayer(&hdma2d_discovery, LayerIndex) == E_OK){
+			if(dma2d_start(&hdma2d_discovery, ColorIndex, (uint32_t)pDst, xSize, ySize) == E_OK){
+				/* Polling For DMA transfer */
+				dma2d_waittransfar(&hdma2d_discovery, 10);
+			}
+		}
+	}
+}
+
+/**
+  * @brief  Converts a line to an ARGB8888 pixel format.
+  * @param  pSrc: Pointer to source buffer
+  * @param  pDst: Output color
+  * @param  xSize: Buffer width
+  * @param  ColorMode: Input color mode
+  */
+static
+void LL_ConvertLineToARGB8888(void *pSrc, void *pDst, uint32_t xSize, uint32_t ColorMode)
+{
+	/* Configure the DMA2D Mode, Color Mode and output offset */
+	hdma2d_discovery.Init.Mode         = DMA2D_M2M_PFC;
+	hdma2d_discovery.Init.ColorMode    = CM_ARGB8888;
+	hdma2d_discovery.Init.OutputOffset = 0;
+
+	/* Foreground Configuration */
+	hdma2d_discovery.LayerCfg[1].AlphaMode = DMA2D_NO_MODIF_ALPHA;
+	hdma2d_discovery.LayerCfg[1].InputAlpha = 0xFF;
+	hdma2d_discovery.LayerCfg[1].InputColorMode = ColorMode;
+	hdma2d_discovery.LayerCfg[1].InputOffset = 0;
+
+	hdma2d_discovery.base = TADR_DMA2D_BASE;
+
+	/* DMA2D Initialization */
+	if(dma2d_init(&hdma2d_discovery) == E_OK){
+		if(dma2d_configlayer(&hdma2d_discovery, 1) == E_OK){
+			if(dma2d_start(&hdma2d_discovery, (uint32_t)pSrc, (uint32_t)pDst, xSize, 1) == E_OK){
+				/* Polling For DMA transfer */
+				dma2d_waittransfar(&hdma2d_discovery, 10);
+			}
+		}
+	}
+}
+
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/stlcd_otm8009a/stlcd_otm8009a.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/stlcd_otm8009a/stlcd_otm8009a.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/stlcd_otm8009a/stlcd_otm8009a.h	(revision 457)
@@ -0,0 +1,369 @@
+/*
+ *  TOPPERS BASE PLATFORM MIDDLEWARE
+ * 
+ *  Copyright (C) 2017-2018 by TOPPERS PROJECT
+ *                             Educational Working Group.
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+/**
+  ******************************************************************************
+  * @attention
+  *
+  * <h2><center>&copy; COPYRIGHT(c) 2016 STMicroelectronics</center></h2>
+  *
+  * 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 STMicroelectronics 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 _STLCD_OTM8009A_H_
+#define _STLCD_OTM8009A_H_
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+#include <kernel.h>
+#include <t_syslog.h>
+#include <t_stdlib.h>
+#include <sil.h>
+#include <target_syssvc.h>
+#include <string.h>
+
+#include "device.h"
+#include "i2c.h"
+#include "ltdc.h"
+#include "dsi.h"
+#include "dfsdm.h"
+
+
+/** @defgroup RCCEx_PLLSAI_DIVR RCCEx PLLSAI DIVR
+  * @{
+  */
+#define RCC_PLLSAIDIVR_2                ((uint32_t)0x00000000U)
+#define RCC_PLLSAIDIVR_4                RCC_DCKCFGR1_PLLSAIDIVR_0
+#define RCC_PLLSAIDIVR_8                RCC_DCKCFGR1_PLLSAIDIVR_1
+#define RCC_PLLSAIDIVR_16               RCC_DCKCFGR1_PLLSAIDIVR
+
+
+
+/**
+ *  @brief LCD_OrientationTypeDef
+ *  Possible values of Display Orientation
+ */
+#define OTM8009A_ORIENTATION_PORTRAIT    ((uint32_t)0x00) /* Portrait orientation choice of LCD screen  */
+#define OTM8009A_ORIENTATION_LANDSCAPE   ((uint32_t)0x01) /* Landscape orientation choice of LCD screen */
+
+/**
+ *  @brief  Possible values of
+ *  pixel data format (ie color coding) transmitted on DSI Data lane in DSI packets
+ */
+#define OTM8009A_FORMAT_RGB888    ((uint32_t)0x00) /* Pixel format chosen is RGB888 : 24 bpp */
+#define OTM8009A_FORMAT_RBG565    ((uint32_t)0x02) /* Pixel format chosen is RGB565 : 16 bpp */
+
+/**
+  * @brief  otm8009a_480x800 Size
+  */
+
+/* Width and Height in Portrait mode */
+#define OTM8009A_480X800_WIDTH             ((uint16_t)480)     /* LCD PIXEL WIDTH   */
+#define OTM8009A_480X800_HEIGHT            ((uint16_t)800)     /* LCD PIXEL HEIGHT  */
+
+/* Width and Height in Landscape mode */
+#define OTM8009A_800X480_WIDTH             ((uint16_t)800)     /* LCD PIXEL WIDTH   */
+#define OTM8009A_800X480_HEIGHT            ((uint16_t)480)     /* LCD PIXEL HEIGHT  */
+
+/**
+  * @brief  OTM8009A_480X800 Timing parameters for Portrait orientation mode
+  */
+#define OTM8009A_480X800_HSYNC             ((uint16_t)63)     /* Horizontal synchronization: This value is set to limit value mentionned 
+                                                                   in otm8009a spec to fit with USB functional clock configuration constraints */
+#define OTM8009A_480X800_HBP               ((uint16_t)120)     /* Horizontal back porch      */
+#define OTM8009A_480X800_HFP               ((uint16_t)120)     /* Horizontal front porch     */
+#define OTM8009A_480X800_VSYNC             ((uint16_t)12)      /* Vertical synchronization   */
+#define OTM8009A_480X800_VBP               ((uint16_t)12)      /* Vertical back porch        */
+#define OTM8009A_480X800_VFP               ((uint16_t)12)      /* Vertical front porch       */
+
+/**
+  * @brief  OTM8009A_800X480 Timing parameters for Landscape orientation mode
+  *         Same values as for Portrait mode in fact.
+  */
+#define OTM8009A_800X480_HSYNC             OTM8009A_480X800_HSYNC  /* Horizontal synchronization */
+#define OTM8009A_800X480_HBP               OTM8009A_480X800_HBP    /* Horizontal back porch      */
+#define OTM8009A_800X480_HFP               OTM8009A_480X800_HFP    /* Horizontal front porch     */
+#define OTM8009A_800X480_VSYNC             OTM8009A_480X800_VSYNC  /* Vertical synchronization   */
+#define OTM8009A_800X480_VBP               OTM8009A_480X800_VBP    /* Vertical back porch        */
+#define OTM8009A_800X480_VFP               OTM8009A_480X800_VFP    /* Vertical front porch       */
+
+
+/* List of OTM8009A used commands                                  */
+/* Detailed in OTM8009A Data Sheet 'DATA_SHEET_OTM8009A_V0 92.pdf' */
+/* Version of 14 June 2012                                         */
+#define OTM8009A_CMD_NOP                   0x00  /* NOP command      */
+#define OTM8009A_CMD_SWRESET               0x01  /* Sw reset command */
+#define OTM8009A_CMD_RDDMADCTL             0x0B  /* Read Display MADCTR command : read memory display access ctrl */
+#define OTM8009A_CMD_RDDCOLMOD             0x0C  /* Read Display pixel format */
+#define OTM8009A_CMD_SLPIN                 0x10  /* Sleep In command */
+#define OTM8009A_CMD_SLPOUT                0x11  /* Sleep Out command */
+#define OTM8009A_CMD_PTLON                 0x12  /* Partial mode On command */
+
+#define OTM8009A_CMD_DISPOFF               0x28  /* Display Off command */
+#define OTM8009A_CMD_DISPON                0x29  /* Display On command */
+
+#define OTM8009A_CMD_CASET                 0x2A  /* Column address set command */
+#define OTM8009A_CMD_PASET                 0x2B  /* Page address set command */
+
+#define OTM8009A_CMD_RAMWR                 0x2C  /* Memory (GRAM) write command */
+#define OTM8009A_CMD_RAMRD                 0x2E  /* Memory (GRAM) read command  */
+
+#define OTM8009A_CMD_PLTAR                 0x30  /* Partial area command (4 parameters) */
+
+#define OTM8009A_CMD_TEOFF                 0x34  /* Tearing Effect Line Off command : command with no parameter */
+
+#define OTM8009A_CMD_TEEON                 0x35  /* Tearing Effect Line On command : command with 1 parameter 'TELOM' */
+
+/* Parameter TELOM : Tearing Effect Line Output Mode : possible values */
+#define OTM8009A_TEEON_TELOM_VBLANKING_INFO_ONLY            0x00
+#define OTM8009A_TEEON_TELOM_VBLANKING_AND_HBLANKING_INFO   0x01
+
+#define OTM8009A_CMD_MADCTR                0x36  /* Memory Access write control command  */
+
+/* Possible used values of MADCTR */
+#define OTM8009A_MADCTR_MODE_PORTRAIT      0x00
+#define OTM8009A_MADCTR_MODE_LANDSCAPE     0x60  /* MY = 0, MX = 1, MV = 1, ML = 0, RGB = 0 */
+
+#define OTM8009A_CMD_IDMOFF                0x38  /* Idle mode Off command */
+#define OTM8009A_CMD_IDMON                 0x39  /* Idle mode On command  */
+
+#define OTM8009A_CMD_COLMOD                0x3A  /* Interface Pixel format command */
+
+/* Possible values of COLMOD parameter corresponding to used pixel formats */
+#define OTM8009A_COLMOD_RGB565             0x55
+#define OTM8009A_COLMOD_RGB888             0x77
+
+#define OTM8009A_CMD_RAMWRC                0x3C  /* Memory write continue command */
+#define OTM8009A_CMD_RAMRDC                0x3E  /* Memory read continue command  */
+
+#define OTM8009A_CMD_WRTESCN               0x44  /* Write Tearing Effect Scan line command */
+#define OTM8009A_CMD_RDSCNL                0x45  /* Read  Tearing Effect Scan line command */
+
+/* CABC Management : ie : Content Adaptive Back light Control in IC OTM8009a */
+#define OTM8009A_CMD_WRDISBV               0x51  /* Write Display Brightness command          */
+#define OTM8009A_CMD_WRCTRLD               0x53  /* Write CTRL Display command                */
+#define OTM8009A_CMD_WRCABC                0x55  /* Write Content Adaptive Brightness command */
+#define OTM8009A_CMD_WRCABCMB              0x5E  /* Write CABC Minimum Brightness command     */
+
+/**
+  * @brief  OTM8009A_480X800 frequency divider
+  */
+#define OTM8009A_480X800_FREQUENCY_DIVIDER  2   /* LCD Frequency divider      */
+
+/** 
+  * @brief  LCD FB_StartAddress
+  */
+#define LCD_FB_START_ADDRESS       ((uint32_t)0xC0000000)
+   
+/** @brief Maximum number of LTDC layers
+ */
+#define LTDC_MAX_LAYER_NUMBER             ((uint32_t) 2)
+
+/** @brief LTDC Background layer index
+ */
+#define LTDC_ACTIVE_LAYER_BACKGROUND      ((uint32_t) 0)
+
+/** @brief LTDC Foreground layer index
+ */
+#define LTDC_ACTIVE_LAYER_FOREGROUND      ((uint32_t) 1)
+
+/** @brief Number of LTDC layers
+ */
+#define LTDC_NB_OF_LAYERS                 ((uint32_t) 2)
+
+/** @brief LTDC Default used layer index
+ */
+#define LTDC_DEFAULT_ACTIVE_LAYER         LTDC_ACTIVE_LAYER_FOREGROUND
+
+/**
+  * @brief  LCD Display OTM8009A DSI Virtual Channel  ID
+  */
+#define LCD_OTM8009A_ID  ((uint32_t) 0)
+
+
+/** 
+  * @brief  LCD color  
+  */ 
+#define LCD_COLOR_BLUE          ((uint32_t)0xFF0000FF)
+#define LCD_COLOR_GREEN         ((uint32_t)0xFF00FF00)
+#define LCD_COLOR_RED           ((uint32_t)0xFFFF0000)
+#define LCD_COLOR_CYAN          ((uint32_t)0xFF00FFFF)
+#define LCD_COLOR_MAGENTA       ((uint32_t)0xFFFF00FF)
+#define LCD_COLOR_YELLOW        ((uint32_t)0xFFFFFF00)
+#define LCD_COLOR_LIGHTBLUE     ((uint32_t)0xFF8080FF)
+#define LCD_COLOR_LIGHTGREEN    ((uint32_t)0xFF80FF80)
+#define LCD_COLOR_LIGHTRED      ((uint32_t)0xFFFF8080)
+#define LCD_COLOR_LIGHTCYAN     ((uint32_t)0xFF80FFFF)
+#define LCD_COLOR_LIGHTMAGENTA  ((uint32_t)0xFFFF80FF)
+#define LCD_COLOR_LIGHTYELLOW   ((uint32_t)0xFFFFFF80)
+#define LCD_COLOR_DARKBLUE      ((uint32_t)0xFF000080)
+#define LCD_COLOR_DARKGREEN     ((uint32_t)0xFF008000)
+#define LCD_COLOR_DARKRED       ((uint32_t)0xFF800000)
+#define LCD_COLOR_DARKCYAN      ((uint32_t)0xFF008080)
+#define LCD_COLOR_DARKMAGENTA   ((uint32_t)0xFF800080)
+#define LCD_COLOR_DARKYELLOW    ((uint32_t)0xFF808000)
+#define LCD_COLOR_WHITE         ((uint32_t)0xFFFFFFFF)
+#define LCD_COLOR_LIGHTGRAY     ((uint32_t)0xFFD3D3D3)
+#define LCD_COLOR_GRAY          ((uint32_t)0xFF808080)
+#define LCD_COLOR_DARKGRAY      ((uint32_t)0xFF404040)
+#define LCD_COLOR_BLACK         ((uint32_t)0xFF000000)
+#define LCD_COLOR_BROWN         ((uint32_t)0xFFA52A2A)
+#define LCD_COLOR_ORANGE        ((uint32_t)0xFFFFA500)
+#define LCD_COLOR_TRANSPARENT   ((uint32_t)0xFF000000)
+
+/**
+ *  @brief  Possible values of
+ *  pixel data format (ie color coding) transmitted on DSI Data lane in DSI packets
+ */
+
+#define LCD_DSI_PIXEL_DATA_FMT_RBG888  DSI_RGB888 /*!< DSI packet pixel format chosen is RGB888 : 24 bpp */
+#define LCD_DSI_PIXEL_DATA_FMT_RBG565  DSI_RGB565 /*!< DSI packet pixel format chosen is RGB565 : 16 bpp */
+
+/*
+ *  LCDハンドラ構造体定義
+ */
+typedef struct
+{
+	LTDC_Handle_t           *hltdc;		/* LTDCハンドラ */
+	DSI_Handle_t            *hdsi;		/* DSIハンドラ */
+	DSI_VideoConfig_t       dsivc;		/* DSI video configハンドラ */
+	uint32_t                layer;
+	uint16_t                _width;		/* 幅ピクセル数 */
+	uint16_t				_height;	/* 高さピクセル数 */
+} LCD_Handler_t;
+
+/**
+* @brief  LCD Drawing main properties
+*/
+typedef struct
+{
+	LCD_Handler_t           *hlcd;
+	uint32_t TextColor;		/* Specifies the color of text */
+	uint32_t BackColor;		/* Specifies the background color below the text */
+	void     *pFont;		/* Specifies the font used for the text */
+
+} LCD_DrawProp_t;
+
+/**
+  * @brief  LCD Drawing point (pixel) geometric definition
+  */
+typedef struct
+{
+  int16_t X; /*!< geometric X position of drawing */
+  int16_t Y; /*!< geometric Y position of drawing */
+
+} Point;
+
+/**
+  * @brief  Pointer on LCD Drawing point (pixel) geometric definition
+  */
+typedef Point * pPoint;
+
+/**
+ *  @brief LCD_OrientationTypeDef
+ *  Possible values of Display Orientation
+ */
+typedef enum
+{
+	LCD_ORIENTATION_PORTRAIT  = 0x00, /*!< Portrait orientation choice of LCD screen  */
+	LCD_ORIENTATION_LANDSCAPE = 0x01, /*!< Landscape orientation choice of LCD screen */
+	LCD_ORIENTATION_INVALID   = 0x02  /*!< Invalid orientation choice of LCD screen   */
+} LCD_OrientationTypeDef;
+
+
+extern ER lcd_init(LCD_Handler_t *hlcd, LCD_OrientationTypeDef orientation);
+extern ER lcd_reset(LCD_Handler_t *hlcd);
+
+extern ER lcd_layerdefaultinit(LCD_Handler_t *hlcd, LCD_DrawProp_t *pDrawProp, uint16_t LayerIndex, uint32_t FB_Address);
+extern void lcd_setlayervisible(LCD_Handler_t *hlcd, uint32_t LayerIndex, uint8_t State);
+extern void lcd_settransparency(LCD_Handler_t *hlcd, uint32_t LayerIndex, uint8_t Transparency);
+extern void lcd_setlayeraddress(LCD_Handler_t *hlcd, uint32_t LayerIndex, uint32_t Address);
+extern void lcd_setcolorkeying(LCD_Handler_t *hlcd, uint32_t LayerIndex, uint32_t RGBValue);
+extern void lcd_resetcolorkeying(LCD_Handler_t *hlcd, uint32_t LayerIndex);
+
+extern void lcd_setAddrWindow(LCD_Handler_t *hlcd, uint16_t LayerIndex, uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1);
+extern void lcd_clear(LCD_Handler_t *hlcd, uint32_t Color);
+extern uint32_t lcd_readPixel(LCD_Handler_t *hlcd, uint16_t Xpos, uint16_t Ypos);
+extern void lcd_drawPixel(LCD_Handler_t *hlcd, uint16_t Xpos, uint16_t Ypos, uint32_t RGB_Code);
+extern void lcd_drawFastHLine(LCD_Handler_t *hlcd, uint16_t Xpos, uint16_t Ypos, uint16_t Length, uint32_t color);
+extern void lcd_drawFastVLine(LCD_Handler_t *hlcd, uint16_t Xpos, uint16_t Ypos, uint16_t Length, uint32_t color);
+extern void lcd_drawBitmap(LCD_Handler_t *hlcd, uint32_t Xpos, uint32_t Ypos, uint8_t *pbmp);
+extern void lcd_displayOn(LCD_Handler_t *hlcd);
+extern void lcd_displayOff(LCD_Handler_t *hlcd);
+extern void lcd_setbrightness(LCD_Handler_t *hlcd, uint8_t BrightnessValue);
+extern void lcd_fillRect(LCD_Handler_t *hlcd, uint16_t Xpos, uint16_t Ypos, uint16_t Width, uint16_t Height, uint32_t color);
+
+extern void lcd_drawLine(LCD_DrawProp_t *pDrawProp, uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2);
+extern void lcd_drawRect(LCD_DrawProp_t *pDrawProp, uint16_t Xpos, uint16_t Ypos, uint16_t Width, uint16_t Height);
+extern void lcd_DrawCircle(LCD_DrawProp_t *pDrawProp, uint16_t Xpos, uint16_t Ypos, uint16_t Radius);
+extern void lcd_DrawEllipse(LCD_DrawProp_t *pDrawProp, int Xpos, int Ypos, int XRadius, int YRadius);
+extern void lcd_drawPolygon(LCD_DrawProp_t *pDrawProp, pPoint Points, uint16_t PointCount);
+extern void lcd_fillCircle(LCD_DrawProp_t *pDrawProp, uint16_t Xpos, uint16_t Ypos, uint16_t Radius);
+extern void lcd_fillEllipse(LCD_DrawProp_t *pDrawProp, int Xpos, int Ypos, int XRadius, int YRadius);
+extern void lcd_fillPolygon(LCD_DrawProp_t *pDrawProp, pPoint Points, uint16_t PointCount);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _STLCD_OTM8009A_H_ */
+
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/stlcd_rk043fn48h/Makefile.config
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/stlcd_rk043fn48h/Makefile.config	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/stlcd_rk043fn48h/Makefile.config	(revision 457)
@@ -0,0 +1,55 @@
+#
+#   TOPPERS/ASP/FMP Kernel
+#       Toyohashi Open Platform for Embedded Real-Time Systems/
+#       Advanced Standard Profile Kernel
+#
+#   Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
+#                               Toyohashi Univ. of Technology, JAPAN
+#   Copyright (C) 2003-2008 by Ryosuke Takeuchi
+#                Platform Development Center RICOH COMPANY,LTD. JAPAN
+#   Copyright (C) 2015-2018 by TOPPERS PROJECT Educational Working Group.
+#
+#   上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+#   によって公表されている GNU General Public License の Version 2 に記
+#   述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+#   を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+#   利用と呼ぶ）することを無償で許諾する．
+#   (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+#       権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+#       スコード中に含まれていること．
+#   (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+#       用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+#       者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+#       の無保証規定を掲載すること．
+#   (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+#       用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+#       と．
+#     (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+#         作権表示，この利用条件および下記の無保証規定を掲載すること．
+#     (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+#         報告すること．
+#   (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+#       害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+#
+#   本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+#   よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+#   含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+#   接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+#
+#  @(#) $Id$
+#
+ 
+#
+#  Makefile のプロセッサ依存 (rk043fn48h用)
+#
+
+#
+#  コンパイルオプション
+#
+INCLUDES := $(INCLUDES) -I$(SRCDIR)/gdic/stlcd_rk043fn48h
+
+#
+#  USB DEVICE(GDIC)に関する定義
+#
+SYSSVC_DIR := $(SYSSVC_DIR):$(SRCDIR)/gdic/stlcd_rk043fn48h
+SYSSVC_COBJS := $(SYSSVC_COBJS) stlcd_rk043fn48h.o
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/stlcd_rk043fn48h/glcd_core.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/stlcd_rk043fn48h/glcd_core.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/stlcd_rk043fn48h/glcd_core.h	(revision 457)
@@ -0,0 +1,45 @@
+/*
+ *  TOPPERS BASE PLATFORM MIDDLEWARE
+ * 
+ *  Copyright (C) 2017-2018 by TOPPERS PROJECT
+ *                             Educational Working Group.
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+#ifndef _LCD_CORE_H_
+#define _LCD_CORE_H_
+
+#include "stlcd_rk043fn48h.h"
+
+#endif /* _LCD_CORE_H_ */
+
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/stlcd_rk043fn48h/stlcd_rk043fn48h.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/stlcd_rk043fn48h/stlcd_rk043fn48h.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/stlcd_rk043fn48h/stlcd_rk043fn48h.c	(revision 457)
@@ -0,0 +1,982 @@
+/*
+ *  TOPPERS BASE PLATFORM MIDDLEWARE
+ * 
+ *  Copyright (C) 2017-2018 by TOPPERS PROJECT
+ *                             Educational Working Group.
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+/**
+  ******************************************************************************
+  * @attention
+  *
+  * <h2><center>&copy; COPYRIGHT(c) 2016 STMicroelectronics</center></h2>
+  *
+  * 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 STMicroelectronics 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 "stlcd_rk043fn48h.h"
+#include <sil.h>
+#include <target_syssvc.h>
+
+#define sil_orw_mem(a, b)		sil_wrw_mem((a), sil_rew_mem(a) | (b))
+#define sil_andw_mem(a, b)		sil_wrw_mem((a), sil_rew_mem(a) & ~(b))
+#define sil_modw_mem(a, b, c)	sil_wrw_mem((a), (sil_rew_mem(a) & (~b)) | (c))
+
+#define POLY_X(Z)              ((int32_t)((Points + Z)->X))
+#define POLY_Y(Z)              ((int32_t)((Points + Z)->Y))
+#define ABS(X)                 ((X) > 0 ? (X) : -(X))
+
+#ifndef ENABLE
+#define ENABLE                 1
+#endif
+
+static LTDC_Handle_t  hLtdcHandler;
+static DMA2D_Handle_t hDma2dHandler;
+
+static void FillTriangle(LCD_DrawProp_t *pDrawProp, uint16_t x1, uint16_t x2, uint16_t x3, uint16_t y1, uint16_t y2, uint16_t y3);
+static void LL_FillBuffer(LCD_Handler_t *hlcd, void *pDst, uint32_t xSize, uint32_t ySize, uint32_t OffLine, uint32_t ColorIndex);
+static void LL_ConvertLineToARGB8888(void * pSrc, void *pDst, uint32_t xSize, uint32_t ColorMode);
+
+/*
+ *  LTDC/RK043FN48Hスクリーンの初期化関数
+ */
+ER
+lcd_init(LCD_Handler_t *hlcd, LCD_OrientationTypeDef orientation)
+{
+	/* The RK043FN48H LCD 480x272 is selected */
+	/* Timing Configuration */
+	hLtdcHandler.Init.HorizontalSync = (RK043FN48H_HSYNC - 1);
+	hLtdcHandler.Init.VerticalSync = (RK043FN48H_VSYNC - 1);
+	hLtdcHandler.Init.AccumulatedHBP = (RK043FN48H_HSYNC + RK043FN48H_HBP - 1);
+	hLtdcHandler.Init.AccumulatedVBP = (RK043FN48H_VSYNC + RK043FN48H_VBP - 1);
+	hLtdcHandler.Init.AccumulatedActiveH = (RK043FN48H_HEIGHT + RK043FN48H_VSYNC + RK043FN48H_VBP - 1);
+	hLtdcHandler.Init.AccumulatedActiveW = (RK043FN48H_WIDTH + RK043FN48H_HSYNC + RK043FN48H_HBP - 1);
+	hLtdcHandler.Init.TotalHeigh = (RK043FN48H_HEIGHT + RK043FN48H_VSYNC + RK043FN48H_VBP + RK043FN48H_VFP - 1);
+	hLtdcHandler.Init.TotalWidth = (RK043FN48H_WIDTH + RK043FN48H_HSYNC + RK043FN48H_HBP + RK043FN48H_HFP - 1);
+	hLtdcHandler.Init.pllsain = 192;
+	hLtdcHandler.Init.pllsair = 5;
+	hLtdcHandler.Init.saidivr = RCC_DCKCFGR1_PLLSAIDIVR_0;	/* DIV 4 */
+
+	/* Initialize the LCD pixel width and pixel height */
+	hLtdcHandler.LayerCfg[0].ImageWidth  = RK043FN48H_WIDTH;
+	hLtdcHandler.LayerCfg[0].ImageHeight = RK043FN48H_HEIGHT;
+#if MAX_LAYER_NUMBER >= 2
+	hLtdcHandler.LayerCfg[1].ImageWidth  = RK043FN48H_WIDTH;
+	hLtdcHandler.LayerCfg[1].ImageHeight = RK043FN48H_HEIGHT;
+#endif
+
+	/* Background value */
+	hLtdcHandler.Init.Backcolor.Blue = 0;
+	hLtdcHandler.Init.Backcolor.Green = 0;
+	hLtdcHandler.Init.Backcolor.Red = 0;
+
+	/* Polarity */
+	hLtdcHandler.Init.HSPolarity = LTDC_HSPOLARITY_AL;
+	hLtdcHandler.Init.VSPolarity = LTDC_VSPOLARITY_AL; 
+	hLtdcHandler.Init.DEPolarity = LTDC_DEPOLARITY_AL;  
+	hLtdcHandler.Init.PCPolarity = LTDC_PCPOLARITY_IPC;
+	hLtdcHandler.base = TADR_LTDC_BASE;
+	hlcd->_width  = RK043FN48H_WIDTH;
+	hlcd->_height = RK043FN48H_HEIGHT;
+	ltdc_init(&hLtdcHandler);
+	hlcd->hltdc = &hLtdcHandler;
+	return E_OK;
+}
+
+/*
+ *  LTDC/RK043FN48Hスクリーンレイヤ初期化関数
+ */
+ER
+lcd_layerdefaultinit(LCD_Handler_t *hlcd, LCD_DrawProp_t *pDrawProp, uint16_t LayerIndex, uint32_t FB_Address)
+{
+	LTDC_LayerCfg_t  layer_cfg;
+
+	if(LayerIndex >= MAX_LAYER_NUMBER)
+		return E_PAR;
+	/* Layer Init */
+	layer_cfg.WindowX0 = 0;
+	layer_cfg.WindowX1 = hlcd->hltdc->LayerCfg[LayerIndex].ImageWidth;
+	layer_cfg.WindowY0 = 0;
+	layer_cfg.WindowY1 = hlcd->hltdc->LayerCfg[LayerIndex].ImageHeight;
+	layer_cfg.PixelFormat = LTDC_PIXEL_FORMAT_ARGB8888;
+	layer_cfg.FBStartAdress = FB_Address;
+	layer_cfg.Alpha = 255;
+	layer_cfg.Alpha0 = 0;
+	layer_cfg.Backcolor.Blue = 0;
+	layer_cfg.Backcolor.Green = 0;
+	layer_cfg.Backcolor.Red = 0;
+	layer_cfg.BlendingFactor1 = LTDC_BLENDING_FACTOR1_CA;
+	layer_cfg.BlendingFactor2 = LTDC_BLENDING_FACTOR2_CA;
+	layer_cfg.ImageWidth = hlcd->hltdc->LayerCfg[LayerIndex].ImageWidth;
+	layer_cfg.ImageHeight = hlcd->hltdc->LayerCfg[LayerIndex].ImageHeight;
+
+	ltdc_configlayer(&hLtdcHandler, &layer_cfg, LayerIndex);
+
+	hlcd->layer = LayerIndex;
+	pDrawProp[LayerIndex].BackColor = LCD_COLOR_WHITE;
+	pDrawProp[LayerIndex].TextColor = LCD_COLOR_BLACK;
+	pDrawProp[LayerIndex].hlcd      = hlcd;
+	return E_OK;
+}
+
+/*
+ *  LTDC/RK043FN48HスクリーンRGB565レイヤ初期化関数
+ */
+ER
+lcd_layerRgb565init(LCD_Handler_t *hlcd, LCD_DrawProp_t *pDrawProp, uint16_t LayerIndex, uint32_t FB_Address)
+{
+	LTDC_LayerCfg_t  layer_cfg;
+
+	if(LayerIndex >= MAX_LAYER_NUMBER)
+		return E_PAR;
+	/* Layer Init */
+	layer_cfg.WindowX0 = 0;
+	layer_cfg.WindowX1 = hlcd->hltdc->LayerCfg[LayerIndex].ImageWidth;
+	layer_cfg.WindowY0 = 0;
+	layer_cfg.WindowY1 = hlcd->hltdc->LayerCfg[LayerIndex].ImageHeight;
+	layer_cfg.PixelFormat = LTDC_PIXEL_FORMAT_RGB565;
+	layer_cfg.FBStartAdress = FB_Address;
+	layer_cfg.Alpha = 255;
+	layer_cfg.Alpha0 = 0;
+	layer_cfg.Backcolor.Blue = 0;
+	layer_cfg.Backcolor.Green = 0;
+	layer_cfg.Backcolor.Red = 0;
+	layer_cfg.BlendingFactor1 = LTDC_BLENDING_FACTOR1_PAxCA;
+	layer_cfg.BlendingFactor2 = LTDC_BLENDING_FACTOR2_PAxCA;
+	layer_cfg.ImageWidth = hlcd->hltdc->LayerCfg[LayerIndex].ImageWidth;
+	layer_cfg.ImageHeight = hlcd->hltdc->LayerCfg[LayerIndex].ImageHeight;
+
+	ltdc_configlayer(&hLtdcHandler, &layer_cfg, LayerIndex);
+
+	hlcd->layer = LayerIndex;
+	pDrawProp[LayerIndex].BackColor = LCD_COLOR_WHITE;
+	pDrawProp[LayerIndex].TextColor = LCD_COLOR_BLACK;
+	pDrawProp[LayerIndex].hlcd      = hlcd;
+	return E_OK;
+}
+
+/*
+ *  LTDC/RK043FN48Hスクリーンレイヤ表示設定関数
+ */
+void
+lcd_setlayervisible(LCD_Handler_t *hlcd, uint32_t LayerIndex, uint8_t State)
+{
+	uint32_t layer_base = ((uint32_t)TADR_LTDC_BASE + 0x84 + (0x80 * LayerIndex));
+	if(State == ENABLE){
+		sil_orw_mem((uint32_t *)(layer_base+TOFF_LTDCW_CR), LTDC_CR_LEN);
+	}
+	else{
+		sil_andw_mem((uint32_t *)(layer_base+TOFF_LTDCW_CR), LTDC_CR_LEN);
+	}
+	sil_orw_mem((uint32_t *)(TADR_LTDC_BASE+TOFF_LTDC_SRCR), LTDC_SRCR_IMR);
+}
+
+/*
+ *  LTDC/RK043FN48Hスクリーンレイヤ透過設定関数
+*
+  * @brief  Configures the transparency.
+  * @param  LayerIndex: Layer foreground or background.
+  * @param  Transparency: Transparency
+  *           This parameter must be a number between Min_Data = 0x00 and Max_Data = 0xFF 
+  * @retval None
+  */
+void
+lcd_settransparency(LCD_Handler_t *hlcd, uint32_t LayerIndex, uint8_t Transparency)
+{
+	ltdc_setalpha(hlcd->hltdc, Transparency, LayerIndex);
+}
+
+/*
+ *  LTDC/RK043FN48HスクリーンレイヤRAMアドレス設定関数
+ */
+void
+lcd_setlayeraddress(LCD_Handler_t *hlcd, uint32_t LayerIndex, uint32_t Address)
+{
+	ltdc_setaddress(hlcd->hltdc, Address, LayerIndex);
+}
+
+/*
+ *  LTDC/RK043FN48H表示ウィンドウ設定
+ */
+void
+lcd_setAddrWindow(LCD_Handler_t *hlcd, uint16_t LayerIndex, uint16_t x0, uint16_t y0, uint16_t Width, uint16_t Height)
+{
+	/* Reconfigure the layer size */
+	ltdc_setwindowsize(hlcd->hltdc, Width, Height, LayerIndex);
+
+	/* Reconfigure the layer position */
+	ltdc_setwindowposition(hlcd->hltdc, x0, y0, LayerIndex);
+}
+
+/**
+  * @brief  Configures and sets the color keying.
+  * @param  LayerIndex: Layer foreground or background
+  * @param  RGBValue: Color reference
+  * @retval None
+  */
+void
+lcd_setcolorkeying(LCD_Handler_t *hlcd, uint32_t LayerIndex, uint32_t RGBValue)
+{
+	/* Configure and Enable the color Keying for LCD Layer */
+	ltdc_configcolorkeying(hlcd->hltdc, RGBValue, LayerIndex);
+	ltdc_enablecolorkeying(hlcd->hltdc, LayerIndex);
+}
+
+/**
+  * @brief  Disables the color keying.
+  * @param  LayerIndex: Layer foreground or background
+  * @retval None
+  */
+void
+lcd_resetcolorkeying(LCD_Handler_t *hlcd, uint32_t LayerIndex)
+{
+	/* Disable the color Keying for LCD Layer */
+	ltdc_disablecolorkeying(hlcd->hltdc, LayerIndex);
+}
+
+/*
+ *  LTDC/RK043FN48Hスクリーンクリア
+ */
+void
+lcd_clear(LCD_Handler_t *hlcd, uint32_t Color)
+{
+	LTDC_Handle_t *hltdc = hlcd->hltdc;
+	uint32_t layer = hlcd->layer;
+	uint32_t width, height;
+
+	width  = hltdc->LayerCfg[layer].ImageWidth;
+	height = hltdc->LayerCfg[layer].ImageHeight;
+ 	/* Clear the LCD */
+ 	LL_FillBuffer(hlcd, (uint32_t *)(hltdc->LayerCfg[layer].FBStartAdress), width, height, 0, Color);
+}
+
+/*
+ *  PIXEL読み出し
+ *  param1  hlcd: Pointer to LCD Handler
+ *  param2  x: X position
+ *  param3  y: Y position
+ */
+uint32_t
+lcd_readPixel(LCD_Handler_t *hlcd, uint16_t Xpos, uint16_t Ypos)
+{
+	LTDC_Handle_t *hltdc = hlcd->hltdc;
+	uint32_t layer = hlcd->layer;
+	uint32_t ret = 0;
+	uint32_t width;
+
+	width = hltdc->LayerCfg[layer].ImageWidth;
+	if(hltdc->LayerCfg[layer].PixelFormat == LTDC_PIXEL_FORMAT_ARGB8888){
+		/* Read data value from SDRAM memory */
+		ret = *(volatile uint32_t*)(hltdc->LayerCfg[layer].FBStartAdress + (2*(Ypos * width + Xpos)));
+	}
+	else if(hltdc->LayerCfg[layer].PixelFormat == LTDC_PIXEL_FORMAT_RGB888){
+		/* Read data value from SDRAM memory */
+		ret = (*(volatile uint32_t*)(hltdc->LayerCfg[layer].FBStartAdress + (2*(Ypos * width + Xpos))) & 0x00FFFFFF);
+	}
+	else if((hltdc->LayerCfg[layer].PixelFormat == LTDC_PIXEL_FORMAT_RGB565)
+			|| (hltdc->LayerCfg[layer].PixelFormat == LTDC_PIXEL_FORMAT_ARGB4444)
+			|| (hltdc->LayerCfg[layer].PixelFormat == LTDC_PIXEL_FORMAT_AL88)){
+		/* Read data value from SDRAM memory */
+		ret = *(volatile uint16_t*)(hltdc->LayerCfg[layer].FBStartAdress + (2*(Ypos * width + Xpos)));
+	}
+	else{
+		/* Read data value from SDRAM memory */
+		ret = *(volatile uint8_t*)(hltdc->LayerCfg[layer].FBStartAdress + (2*(Ypos * width + Xpos)));
+	}
+	return ret;
+}
+
+/*
+ *  PIXEL描画
+ *  param1  hlcd: Pointer to LCD Handler
+ *  param2  x: X position
+ *  param3  y: Y position
+ *  param4  color: color value
+ */
+void
+lcd_drawPixel(LCD_Handler_t *hlcd, uint16_t Xpos, uint16_t Ypos, uint32_t RGB_Code)
+{
+	LTDC_Handle_t *hltdc = hlcd->hltdc;
+	uint32_t layer = hlcd->layer;
+
+	/* Write data value to all SDRAM memory */
+	if(hltdc->LayerCfg[layer].PixelFormat == LTDC_PIXEL_FORMAT_RGB565){ /* RGB565 format */
+		*(volatile uint16_t*)(hltdc->LayerCfg[layer].FBStartAdress + (2*(Ypos*hltdc->LayerCfg[layer].ImageWidth + Xpos))) = (uint16_t)RGB_Code;
+	}
+	else{	/* ARGB8888 format */
+		*(volatile uint32_t*)(hltdc->LayerCfg[layer].FBStartAdress + (4*(Ypos*hltdc->LayerCfg[layer].ImageWidth + Xpos))) = RGB_Code;
+	}
+}
+
+/*
+ *  垂直方向LINEの高速描画
+ *  param1  hlcd: Pointer to LCD Handler
+ *  param2  x: start X position
+ *  param3  y: start Y position
+ *  param4  h: height
+ *  param5  color: color value
+ */
+void
+lcd_drawFastHLine(LCD_Handler_t *hlcd, uint16_t Xpos, uint16_t Ypos, uint16_t Length, uint32_t color)
+{
+	LTDC_Handle_t *hltdc = hlcd->hltdc;
+	uint32_t layer = hlcd->layer;
+	uint32_t Xaddress = 0, width;
+
+	width = hltdc->LayerCfg[layer].ImageWidth;
+	/* Get the line address */
+	if(hltdc->LayerCfg[layer].PixelFormat == LTDC_PIXEL_FORMAT_RGB565){	/* RGB565 format */
+		Xaddress = (hltdc->LayerCfg[layer].FBStartAdress) + 2*(width * Ypos + Xpos);
+	}
+	else{	/* ARGB8888 format */
+		Xaddress = (hltdc->LayerCfg[layer].FBStartAdress) + 4*(width * Ypos + Xpos);
+	}
+	/* Write line */
+	LL_FillBuffer(hlcd, (uint32_t *)Xaddress, Length, 1, 0, color);
+}
+
+/*
+ *  水平方向LINEの高速描画
+ *  param1  hlcd: Pointer to LCD Handler
+ *  param2  x: start X position
+ *  param3  y: start Y position
+ *  param4  w: width
+ *  param5  color: color value
+ */
+void
+lcd_drawFastVLine(LCD_Handler_t *hlcd, uint16_t Xpos, uint16_t Ypos, uint16_t Length, uint32_t color)
+{
+	LTDC_Handle_t *hltdc = hlcd->hltdc;
+	uint32_t layer = hlcd->layer;
+	uint32_t  Xaddress = 0, width;
+
+	width = hltdc->LayerCfg[layer].ImageWidth;
+	/* Get the line address */
+	if(hltdc->LayerCfg[layer].PixelFormat == LTDC_PIXEL_FORMAT_RGB565){	/* RGB565 format */
+		Xaddress = (hltdc->LayerCfg[layer].FBStartAdress) + 2*(width * Ypos + Xpos);
+	}
+	else{	/* ARGB8888 format */
+		Xaddress = (hltdc->LayerCfg[layer].FBStartAdress) + 4*(width*Ypos + Xpos);
+	}
+
+	/* Write line */
+	LL_FillBuffer(hlcd, (uint32_t *)Xaddress, 1, Length, (width - 1), color);
+}
+
+/*
+ *  BITMAP描画
+ *  param1  hlcd: Pointer to LCD Handler
+ *  param2  x0: Bmp X position in the LCD
+ *  param3  y0: Bmp Y position in the LCD
+ *  param4  pbmp: Pointer to Bmp picture address in the internal Flash
+ */
+void
+lcd_drawBitmap(LCD_Handler_t *hlcd, uint32_t Xpos, uint32_t Ypos, uint8_t *pbmp)
+{
+	LTDC_Handle_t *hltdc = hlcd->hltdc;
+	uint32_t layer = hlcd->layer;
+	uint32_t index = 0, width = 0, height = 0, bit_pixel = 0;
+	uint32_t address, iwidth;
+	uint32_t input_color_mode = 0;
+
+	iwidth = hltdc->LayerCfg[hlcd->layer].ImageWidth;
+	/* Get bitmap data address offset */
+	index = *(volatile uint16_t *) (pbmp + 10);
+	index |= (*(volatile uint16_t *) (pbmp + 12)) << 16;
+
+	/* Read bitmap width */
+	width = *(volatile uint16_t *) (pbmp + 18);
+	width |= (*(volatile uint16_t *) (pbmp + 20)) << 16;
+
+	/* Read bitmap height */
+	height = *(volatile uint16_t *) (pbmp + 22);
+	height |= (*(volatile uint16_t *) (pbmp + 24)) << 16; 
+
+	/* Read bit/pixel */
+	bit_pixel = *(uint16_t *) (pbmp + 28);
+
+	/* Set the address */
+	address = hltdc->LayerCfg[layer].FBStartAdress + (((hltdc->LayerCfg[layer].ImageWidth*Ypos) + Xpos)*(4));
+
+	/* Get the layer pixel format */
+	if((bit_pixel/8) == 4){
+		input_color_mode = CM_ARGB8888;
+	}
+	else if ((bit_pixel/8) == 2){
+		input_color_mode = CM_RGB565;
+	}
+	else{
+		input_color_mode = CM_RGB888;
+	}
+
+	/* Bypass the bitmap header */
+	pbmp += (index + (width * (height - 1) * (bit_pixel/8)));  
+
+	/* Convert picture to ARGB8888 pixel format */
+	for(index=0; index < height; index++){
+		/* Pixel format conversion */
+		LL_ConvertLineToARGB8888((uint32_t *)pbmp, (uint32_t *)address, width, input_color_mode);
+
+		/* Increment the source and destination buffers */
+		address+=  (iwidth*4);
+		pbmp -= width*(bit_pixel/8);
+	}
+}
+
+/*
+ *  RECTANGLE塗りつぶし描画
+ *  param1  hlcd: Pointer to LCD Handler
+ *  param2  x: left X position
+ *  param3  y: top Y position
+ *  param4  w: width
+ *  param5  h: height
+ *  param6  color: color value
+ */
+void
+lcd_fillRect(LCD_Handler_t *hlcd, uint16_t Xpos, uint16_t Ypos, uint16_t Width, uint16_t Height, uint32_t color)
+{
+	LTDC_Handle_t *hltdc = hlcd->hltdc;
+	uint32_t  x_address = 0;
+	uint32_t width;
+
+	width = hltdc->LayerCfg[hlcd->layer].ImageWidth;
+
+	/* Get the rectangle start address */
+	if(hltdc->LayerCfg[hlcd->layer].PixelFormat == LTDC_PIXEL_FORMAT_RGB565){	/* RGB565 format */
+		x_address = (hltdc->LayerCfg[hlcd->layer].FBStartAdress) + 2*(width * Ypos + Xpos);
+	}
+	else{	/* ARGB8888 format */
+		x_address = (hltdc->LayerCfg[hlcd->layer].FBStartAdress) + 4*(width * Ypos + Xpos);
+	}
+	/* Fill the rectangle */
+	LL_FillBuffer(hlcd, (uint32_t *)x_address, Width, Height, (width - Width), color);
+}
+
+
+/*
+ *  線描画
+ *  param1  pDrawProp: Pointer to Draw Prop
+ *  param2  x1: Point 1 X position
+ *  param3  y1: Point 1 Y position
+ *  param4  x2: Point 2 X position
+ *  param5  y2: Point 2 Y position
+ */
+void
+lcd_drawLine(LCD_DrawProp_t *pDrawProp, uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2)
+{
+	LCD_Handler_t *hlcd = pDrawProp->hlcd;
+	int16_t deltax = 0, deltay = 0, x = 0, y = 0, xinc1 = 0, xinc2 = 0, 
+	yinc1 = 0, yinc2 = 0, den = 0, num = 0, num_add = 0, num_pixels = 0, 
+	curpixel = 0;
+
+	deltax = ABS(x2 - x1);        /* The difference between the x's */
+	deltay = ABS(y2 - y1);        /* The difference between the y's */
+	x = x1;                       /* Start x off at the first pixel */
+	y = y1;                       /* Start y off at the first pixel */
+
+	if(x2 >= x1){				/* The x-values are increasing */
+		xinc1 = 1;
+		xinc2 = 1;
+	}
+	else{						/* The x-values are decreasing */
+		xinc1 = -1;
+		xinc2 = -1;
+	}
+
+	if(y2 >= y1){				/* The y-values are increasing */
+		yinc1 = 1;
+		yinc2 = 1;
+	}
+	else{						/* The y-values are decreasing */
+		yinc1 = -1;
+		yinc2 = -1;
+	}
+
+	if(deltax >= deltay){		/* There is at least one x-value for every y-value */
+		xinc1 = 0;				/* Don't change the x when numerator >= denominator */
+		yinc2 = 0;				/* Don't change the y for every iteration */
+		den = deltax;
+		num = deltax / 2;
+		num_add = deltay;
+		num_pixels = deltax;	/* There are more x-values than y-values */
+	}
+	else{						/* There is at least one y-value for every x-value */
+		xinc2 = 0;				/* Don't change the x for every iteration */
+		yinc1 = 0;				/* Don't change the y when numerator >= denominator */
+		den = deltay;
+		num = deltay / 2;
+		num_add = deltax;
+		num_pixels = deltay;	/* There are more y-values than x-values */
+	}
+
+	for(curpixel = 0; curpixel <= num_pixels; curpixel++){
+		lcd_drawPixel(hlcd, x, y, pDrawProp[hlcd->layer].TextColor);   /* Draw the current pixel */
+		num += num_add;			/* Increase the numerator by the top of the fraction */
+		if(num >= den){			/* Check if numerator >= denominator */
+			num -= den;			/* Calculate the new numerator value */
+			x += xinc1;			/* Change the x as appropriate */
+			y += yinc1;			/* Change the y as appropriate */
+		}
+		x += xinc2;				/* Change the x as appropriate */
+		y += yinc2;				/* Change the y as appropriate */
+	}
+}
+
+/*
+ *  RECTANGLE描画
+ *  param1  pDrawProp: Pointer to Draw Prop
+ *  param2  x: left X position
+ *  param3  y: top Y position
+ *  param4  w: width
+ *  param5  h: height
+ */
+void
+lcd_drawRect(LCD_DrawProp_t *pDrawProp, uint16_t Xpos, uint16_t Ypos, uint16_t Width, uint16_t Height)
+{
+	LCD_Handler_t *hlcd = pDrawProp->hlcd;
+	uint32_t      color = pDrawProp[hlcd->layer].TextColor;
+	/* Draw horizontal lines */
+	lcd_drawFastHLine(hlcd, Xpos, Ypos, Width, color);
+	lcd_drawFastHLine(hlcd, Xpos, (Ypos+ Height), Width, color);
+
+	/* Draw vertical lines */
+	lcd_drawFastVLine(hlcd, Xpos, Ypos, Height, color);
+	lcd_drawFastVLine(hlcd, (Xpos + Width), Ypos, Height, color);
+}
+
+/*
+ *  円描画
+ *  param1  pDrawProp: Pointer to Draw Prop
+ *  param2  x0: X position
+ *  param3  y0: Y position
+ *  param4  Radius: Circle radius
+ */
+void
+lcd_DrawCircle(LCD_DrawProp_t *pDrawProp, uint16_t Xpos, uint16_t Ypos, uint16_t Radius)
+{
+	LCD_Handler_t *hlcd = pDrawProp->hlcd;
+	uint32_t      color = pDrawProp[hlcd->layer].TextColor;
+	int32_t   decision;    /* Decision Variable */ 
+	uint32_t  current_x;   /* Current X Value */
+	uint32_t  current_y;   /* Current Y Value */
+
+	decision = 3 - (Radius << 1);
+	current_x = 0;
+	current_y = Radius;
+
+	while (current_x <= current_y){
+		lcd_drawPixel(hlcd, (Xpos + current_x), (Ypos - current_y), color);
+		lcd_drawPixel(hlcd, (Xpos - current_x), (Ypos - current_y), color);
+		lcd_drawPixel(hlcd, (Xpos + current_y), (Ypos - current_x), color);
+		lcd_drawPixel(hlcd, (Xpos - current_y), (Ypos - current_x), color);
+		lcd_drawPixel(hlcd, (Xpos + current_x), (Ypos + current_y), color);
+		lcd_drawPixel(hlcd, (Xpos - current_x), (Ypos + current_y), color);
+		lcd_drawPixel(hlcd, (Xpos + current_y), (Ypos + current_x), color);
+		lcd_drawPixel(hlcd, (Xpos - current_y), (Ypos + current_x), color);
+
+		if(decision < 0){
+			decision += (current_x << 2) + 6;
+		}
+		else{
+			decision += ((current_x - current_y) << 2) + 10;
+			current_y--;
+		}
+		current_x++;
+	}
+}
+
+/*
+ *  楕円描画
+ *  param1  pDrawProp: Pointer to Draw Prop
+ *  param2  x0: X position
+ *  param3  y0: Y position
+ *  param4  XRadius: Ellipse X radius
+ *  param5  YRadius: Ellipse Y radius
+ */
+void
+lcd_DrawEllipse(LCD_DrawProp_t *pDrawProp, int Xpos, int Ypos, int XRadius, int YRadius)
+{
+	LCD_Handler_t *hlcd = pDrawProp->hlcd;
+	uint32_t      color = pDrawProp[hlcd->layer].TextColor;
+	int x = 0, y = -YRadius, err = 2-2*XRadius, e2;
+	float k = 0, rad1 = 0, rad2 = 0;
+
+	rad1 = XRadius;
+	rad2 = YRadius;
+	k = (float)(rad2/rad1);
+
+	do{
+		lcd_drawPixel(hlcd, (Xpos-(uint16_t)(x/k)), (Ypos+y), color);
+		lcd_drawPixel(hlcd, (Xpos+(uint16_t)(x/k)), (Ypos+y), color);
+		lcd_drawPixel(hlcd, (Xpos+(uint16_t)(x/k)), (Ypos-y), color);
+		lcd_drawPixel(hlcd, (Xpos-(uint16_t)(x/k)), (Ypos-y), color);
+
+		e2 = err;
+		if(e2 <= x){
+			err += ++x*2+1;
+			if(-y == x && e2 <= y)
+				e2 = 0;
+		}
+		if(e2 > y)
+			err += ++y*2+1;
+	}
+	while (y <= 0);
+}
+
+/*
+ *  PLOY-LINE描画
+ *  param1  pDrawProp: Pointer to Draw Prop
+ *  param2  Points: Pointer to the points array
+ *  param3  PointCount: Number of points
+ */
+void
+lcd_drawPolygon(LCD_DrawProp_t *pDrawProp, pPoint Points, uint16_t PointCount)
+{
+	int16_t x = 0, y = 0;
+
+	if(PointCount < 2){
+		return;
+	}
+
+	lcd_drawLine(pDrawProp, Points->X, Points->Y, (Points+PointCount-1)->X, (Points+PointCount-1)->Y);
+	while(--PointCount){
+		x = Points->X;
+		y = Points->Y;
+		Points++;
+		lcd_drawLine(pDrawProp, x, y, Points->X, Points->Y);
+	}
+}
+
+/*
+ *  円塗りつぶし描画
+ *  param1  pDrawProp: Pointer to Draw Prop
+ *  param2  x0: X position
+ *  param3  y0: Y position
+ *  param4  Radius: Circle radius
+ */
+void
+lcd_fillCircle(LCD_DrawProp_t *pDrawProp, uint16_t Xpos, uint16_t Ypos, uint16_t Radius)
+{
+	LCD_Handler_t *hlcd = pDrawProp->hlcd;
+	uint32_t  color = pDrawProp->TextColor;
+	int32_t   decision;     /* Decision Variable */ 
+	uint32_t  current_x;   /* Current X Value */
+	uint32_t  current_y;   /* Current Y Value */
+
+	decision = 3 - (Radius << 1);
+	current_x = 0;
+	current_y = Radius;
+
+	while (current_x <= current_y){
+		if(current_y > 0){
+			lcd_drawFastHLine(hlcd, Xpos - current_y, Ypos + current_x, 2*current_y, color);
+			lcd_drawFastHLine(hlcd, Xpos - current_y, Ypos - current_x, 2*current_y, color);
+		}
+		if(current_x > 0){
+			lcd_drawFastHLine(hlcd, Xpos - current_x, Ypos - current_y, 2*current_x, color);
+			lcd_drawFastHLine(hlcd, Xpos - current_x, Ypos + current_y, 2*current_x, color);
+		}
+		if(decision < 0){
+			decision += (current_x << 2) + 6;
+		}
+		else{
+			decision += ((current_x - current_y) << 2) + 10;
+			current_y--;
+		}
+		current_x++;
+	}
+	lcd_DrawCircle(pDrawProp, Xpos, Ypos, Radius);
+}
+
+/*
+ *  楕円塗りつぶし描画
+ *  param1  pDrawProp: Pointer to Draw Prop
+ *  param2  x0: X position
+ *  param3  y0: Y position
+ *  param4  XRadius: Ellipse X radius
+ *  param5  YRadius: Ellipse Y radius
+ */
+void
+lcd_fillEllipse(LCD_DrawProp_t *pDrawProp, int Xpos, int Ypos, int XRadius, int YRadius)
+{
+	LCD_Handler_t *hlcd = pDrawProp->hlcd;
+	uint32_t      color = pDrawProp[hlcd->layer].TextColor;
+	int x = 0, y = -YRadius, err = 2-2*XRadius, e2;
+	float k = 0, rad1 = 0, rad2 = 0;
+
+	rad1 = XRadius;
+	rad2 = YRadius;
+	k = (float)(rad2/rad1);
+
+	do{
+		lcd_drawFastHLine(hlcd, (Xpos-(uint16_t)(x/k)), (Ypos+y), (2*(uint16_t)(x/k) + 1), color);
+		lcd_drawFastHLine(hlcd, (Xpos-(uint16_t)(x/k)), (Ypos-y), (2*(uint16_t)(x/k) + 1), color);
+
+		e2 = err;
+		if(e2 <= x){
+			err += ++x*2+1;
+			if(-y == x && e2 <= y)
+				e2 = 0;
+		}
+		if(e2 > y)
+			err += ++y*2+1;
+	}while(y <= 0);
+}
+
+/*
+ *  PLOY-LINE塗りつぶし描画
+ *  param1  pDrawProp: Pointer to Draw Prop
+ *  param2  Points: Pointer to the points array
+ *  param3  PointCount: Number of points
+ */
+void
+lcd_fillPolygon(LCD_DrawProp_t *pDrawProp, pPoint Points, uint16_t PointCount)
+{
+	int16_t X = 0, Y = 0, X2 = 0, Y2 = 0, X_center = 0, Y_center = 0, X_first = 0, Y_first = 0, pixelX = 0, pixelY = 0, counter = 0;
+	uint16_t  image_left = 0, image_right = 0, image_top = 0, image_bottom = 0;
+
+	image_left = image_right = Points->X;
+	image_top= image_bottom = Points->Y;
+
+	for(counter = 1; counter < PointCount; counter++){
+		pixelX = POLY_X(counter);
+		if(pixelX < image_left){
+			image_left = pixelX;
+		}
+		if(pixelX > image_right){
+			image_right = pixelX;
+		}
+
+		pixelY = POLY_Y(counter);
+		if(pixelY < image_top){
+			image_top = pixelY;
+		}
+		if(pixelY > image_bottom){
+			image_bottom = pixelY;
+		}
+	}
+
+	if(PointCount < 2){
+		return;
+	}
+
+	X_center = (image_left + image_right)/2;
+	Y_center = (image_bottom + image_top)/2;
+	X_first = Points->X;
+	Y_first = Points->Y;
+
+	while(--PointCount){
+		X = Points->X;
+		Y = Points->Y;
+		Points++;
+		X2 = Points->X;
+		Y2 = Points->Y;
+
+		FillTriangle(pDrawProp, X, X2, X_center, Y, Y2, Y_center);
+		FillTriangle(pDrawProp, X, X_center, X2, Y, Y_center, Y2);
+		FillTriangle(pDrawProp, X_center, X2, X, Y_center, Y2, Y);
+	}
+
+	FillTriangle(pDrawProp, X_first, X2, X_center, Y_first, Y2, Y_center);
+	FillTriangle(pDrawProp, X_first, X_center, X2, Y_first, Y_center, Y2);
+	FillTriangle(pDrawProp, X_center, X2, X_first, Y_center, Y2, Y_first);
+}
+
+
+/*******************************************************************************
+                            Static Functions
+*******************************************************************************/
+
+/*
+ *  トライアングルフィル
+ *  param1  pDrawProp: Pointer to Draw Prop
+ *  param2  x1: 点1 X座標始点
+ *  param3  y1: 点1 Y座標始点
+ *  param4  x2: 点2 X座標始点
+ *  param5  y2: 点2 Y座標始点
+ *  param6  x3: 点3 X座標始点
+ *  param7  y3: 点3 Y座標始点
+ */
+static void
+FillTriangle(LCD_DrawProp_t *pDrawProp, uint16_t x1, uint16_t x2, uint16_t x3, uint16_t y1, uint16_t y2, uint16_t y3)
+{
+	int16_t deltax = 0, deltay = 0, x = 0, y = 0, xinc1 = 0, xinc2 = 0, 
+	yinc1 = 0, yinc2 = 0, den = 0, num = 0, num_add = 0, num_pixels = 0,
+	curpixel = 0;
+
+	deltax = ABS(x2 - x1);        /* The difference between the x's */
+	deltay = ABS(y2 - y1);        /* The difference between the y's */
+	x = x1;                       /* Start x off at the first pixel */
+	y = y1;                       /* Start y off at the first pixel */
+
+	if(x2 >= x1){			/* The x-values are increasing */
+		xinc1 = 1;
+		xinc2 = 1;
+	}
+	else{					/* The x-values are decreasing */
+		xinc1 = -1;
+		xinc2 = -1;
+	}
+
+	if(y2 >= y1){			/* The y-values are increasing */
+		yinc1 = 1;
+		yinc2 = 1;
+	}
+	else{					/* The y-values are decreasing */
+		yinc1 = -1;
+		yinc2 = -1;
+	}
+
+	if(deltax >= deltay){	/* There is at least one x-value for every y-value */
+		xinc1 = 0;			/* Don't change the x when numerator >= denominator */
+		yinc2 = 0;			/* Don't change the y for every iteration */
+		den = deltax;
+		num = deltax / 2;
+		num_add = deltay;
+		num_pixels = deltax;	/* There are more x-values than y-values */
+	}
+	else{					/* There is at least one y-value for every x-value */
+		xinc2 = 0;			/* Don't change the x for every iteration */
+		yinc1 = 0;			/* Don't change the y when numerator >= denominator */
+		den = deltay;
+		num = deltay / 2;
+		num_add = deltax;
+		num_pixels = deltay;	/* There are more y-values than x-values */
+	}
+
+	for(curpixel = 0; curpixel <= num_pixels; curpixel++){
+		lcd_drawLine(pDrawProp, x, y, x3, y3);
+		num += num_add;		/* Increase the numerator by the top of the fraction */
+		if(num >= den){		/* Check if numerator >= denominator */
+			num -= den;		/* Calculate the new numerator value */
+			x += xinc1;		/* Change the x as appropriate */
+			y += yinc1;		/* Change the y as appropriate */
+		}
+		x += xinc2;			/* Change the x as appropriate */
+		y += yinc2;			/* Change the y as appropriate */
+	}
+}
+
+/*
+ *  バッファフィル
+ *  param1  hlcd: Pointer to LCD Handler
+ *  param2  pDst:バッファ先頭ポインタ
+ *  param3  xSize: バッファ幅
+ *  param3  ySize: バッファ高さ
+ *  param4  OffLine: 出力オフセット
+ *  param5  ColorIndex: フィルカラー
+ */
+static void
+LL_FillBuffer(LCD_Handler_t *hlcd, void *pDst, uint32_t xSize, uint32_t ySize, uint32_t OffLine, uint32_t ColorIndex) 
+{
+	LTDC_Handle_t *hltdc = hlcd->hltdc;
+
+	/* Register to memory mode with ARGB8888 as color Mode */ 
+	hDma2dHandler.Init.Mode         = DMA2D_R2M;
+	if(hltdc->LayerCfg[hlcd->layer].PixelFormat == LTDC_PIXEL_FORMAT_RGB565){	/* RGB565 format */ 
+		hDma2dHandler.Init.ColorMode    = DMA2D_RGB565;
+	}
+	else{	/* ARGB8888 format */
+		hDma2dHandler.Init.ColorMode    = DMA2D_ARGB8888;
+	}
+	hDma2dHandler.Init.OutputOffset = OffLine;
+
+	hDma2dHandler.base = (uint32_t)TADR_DMA2D_BASE;
+
+	/* DMA2D Initialization */
+	if(dma2d_init(&hDma2dHandler) == E_OK){
+		if(dma2d_configlayer(&hDma2dHandler, hlcd->layer) == E_OK){
+			if(dma2d_start(&hDma2dHandler, ColorIndex, (uint32_t)pDst, xSize, ySize) == E_OK){
+				/* Polling For DMA transfer */
+				dma2d_waittransfar(&hDma2dHandler, 10);
+			}
+		}
+	}
+}
+
+/**
+  * @brief  Converts a line to an ARGB8888 pixel format.
+  * @param  pSrc: Pointer to source buffer
+  * @param  pDst: Output color
+  * @param  xSize: Buffer width
+  * @param  ColorMode: Input color mode   
+  * @retval None
+  */
+static void
+LL_ConvertLineToARGB8888(void *pSrc, void *pDst, uint32_t xSize, uint32_t ColorMode)
+{
+	/* Configure the DMA2D Mode, Color Mode and output offset */
+	hDma2dHandler.Init.Mode         = DMA2D_M2M_PFC;
+	hDma2dHandler.Init.ColorMode    = DMA2D_ARGB8888;
+	hDma2dHandler.Init.OutputOffset = 0;
+
+	/* Foreground Configuration */
+	hDma2dHandler.LayerCfg[1].AlphaMode = DMA2D_NO_MODIF_ALPHA;
+	hDma2dHandler.LayerCfg[1].InputAlpha = 0xFF;
+	hDma2dHandler.LayerCfg[1].InputColorMode = ColorMode;
+	hDma2dHandler.LayerCfg[1].InputOffset = 0;
+	hDma2dHandler.base = (uint32_t)TADR_DMA2D_BASE;
+
+	/* DMA2D Initialization */
+	if(dma2d_init(&hDma2dHandler) == E_OK){
+		if(dma2d_configlayer(&hDma2dHandler, 1) == E_OK){
+			if(dma2d_start(&hDma2dHandler, (uint32_t)pSrc, (uint32_t)pDst, xSize, 1) == E_OK){
+				/* Polling For DMA transfer */
+				dma2d_waittransfar(&hDma2dHandler, 10);
+			}
+		}
+	}
+}
+
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/stlcd_rk043fn48h/stlcd_rk043fn48h.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/stlcd_rk043fn48h/stlcd_rk043fn48h.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/stlcd_rk043fn48h/stlcd_rk043fn48h.h	(revision 457)
@@ -0,0 +1,235 @@
+/*
+ *  TOPPERS BASE PLATFORM MIDDLEWARE
+ * 
+ *  Copyright (C) 2017-2018 by TOPPERS PROJECT
+ *                             Educational Working Group.
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+/**
+  ******************************************************************************
+  * @attention
+  *
+  * <h2><center>&copy; COPYRIGHT(c) 2016 STMicroelectronics</center></h2>
+  *
+  * 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 STMicroelectronics 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 _STLCD_RK043FN48H_H_
+#define _STLCD_RK043FN48H_H_
+
+#ifdef __cplusplus
+ extern "C" {
+#endif 
+
+#include <kernel.h>
+#include <t_syslog.h>
+#include <t_stdlib.h>
+#include "syssvc/serial.h"
+#include "syssvc/syslog.h"
+#include "device.h"
+#include "ltdc.h"
+
+
+
+/* Include LCD component Driver */
+/* LCD RK043FN48H-CT672B 4,3" 480x272 pixels */
+/**
+  * @brief  RK043FN48H Size
+  */
+#define  RK043FN48H_WIDTH    ((uint16_t)480)          /* LCD PIXEL WIDTH            */
+#define  RK043FN48H_HEIGHT   ((uint16_t)272)          /* LCD PIXEL HEIGHT           */
+
+/**
+  * @brief  RK043FN48H Timing
+  */
+#define  RK043FN48H_HSYNC            ((uint16_t)41)   /* Horizontal synchronization */
+#define  RK043FN48H_HBP              ((uint16_t)13)   /* Horizontal back porch      */
+#define  RK043FN48H_HFP              ((uint16_t)32)   /* Horizontal front porch     */
+#define  RK043FN48H_VSYNC            ((uint16_t)10)   /* Vertical synchronization   */
+#define  RK043FN48H_VBP              ((uint16_t)2)    /* Vertical back porch        */
+#define  RK043FN48H_VFP              ((uint16_t)2)    /* Vertical front porch       */
+
+/**
+  * @brief  RK043FN48H frequency divider
+  */
+#define  RK043FN48H_FREQUENCY_DIVIDER    5            /* LCD Frequency divider      */
+
+#define MAX_LAYER_NUMBER       2
+
+#define LTDC_ACTIVE_LAYER	     ((uint32_t)1) /* Layer 1 */
+
+/**
+  * @brief  LCD FB_StartAddress
+  */
+#define LCD_FB_START_ADDRESS       ((uint32_t)0xC0000000)
+
+/**
+  * @brief  LCD color
+  */
+#define LCD_COLOR_BLUE          ((uint32_t)0xFF0000FF)
+#define LCD_COLOR_GREEN         ((uint32_t)0xFF00FF00)
+#define LCD_COLOR_RED           ((uint32_t)0xFFFF0000)
+#define LCD_COLOR_CYAN          ((uint32_t)0xFF00FFFF)
+#define LCD_COLOR_MAGENTA       ((uint32_t)0xFFFF00FF)
+#define LCD_COLOR_YELLOW        ((uint32_t)0xFFFFFF00)
+#define LCD_COLOR_LIGHTBLUE     ((uint32_t)0xFF8080FF)
+#define LCD_COLOR_LIGHTGREEN    ((uint32_t)0xFF80FF80)
+#define LCD_COLOR_LIGHTRED      ((uint32_t)0xFFFF8080)
+#define LCD_COLOR_LIGHTCYAN     ((uint32_t)0xFF80FFFF)
+#define LCD_COLOR_LIGHTMAGENTA  ((uint32_t)0xFFFF80FF)
+#define LCD_COLOR_LIGHTYELLOW   ((uint32_t)0xFFFFFF80)
+#define LCD_COLOR_DARKBLUE      ((uint32_t)0xFF000080)
+#define LCD_COLOR_DARKGREEN     ((uint32_t)0xFF008000)
+#define LCD_COLOR_DARKRED       ((uint32_t)0xFF800000)
+#define LCD_COLOR_DARKCYAN      ((uint32_t)0xFF008080)
+#define LCD_COLOR_DARKMAGENTA   ((uint32_t)0xFF800080)
+#define LCD_COLOR_DARKYELLOW    ((uint32_t)0xFF808000)
+#define LCD_COLOR_WHITE         ((uint32_t)0xFFFFFFFF)
+#define LCD_COLOR_LIGHTGRAY     ((uint32_t)0xFFD3D3D3)
+#define LCD_COLOR_GRAY          ((uint32_t)0xFF808080)
+#define LCD_COLOR_DARKGRAY      ((uint32_t)0xFF404040)
+#define LCD_COLOR_BLACK         ((uint32_t)0xFF000000)
+#define LCD_COLOR_BROWN         ((uint32_t)0xFFA52A2A)
+#define LCD_COLOR_ORANGE        ((uint32_t)0xFFFFA500)
+#define LCD_COLOR_TRANSPARENT   ((uint32_t)0xFF000000)
+
+
+/*
+ *  LCDハンドラ構造体定義
+ */
+typedef struct
+{
+	LTDC_Handle_t           *hltdc;		/* LTDCハンドラ */
+	uint32_t                layer;
+	uint16_t                _width;		/* 幅ピクセル数 */
+	uint16_t				_height;	/* 高さピクセル数 */
+} LCD_Handler_t;
+
+/** @defgroup STM32746G_DISCOVERY_LCD_Exported_Types STM32746G_DISCOVERY_LCD Exported Types
+  * @{
+  */
+typedef struct
+{
+	LCD_Handler_t           *hlcd;
+	uint32_t TextColor;		/* Specifies the color of text */
+	uint32_t BackColor;		/* Specifies the background color below the text */
+	void     *pFont;		/* Specifies the font used for the text */
+
+} LCD_DrawProp_t;
+
+/**
+  * @brief  LCD Drawing point (pixel) geometric definition
+  */
+typedef struct
+{
+  int16_t X; /*!< geometric X position of drawing */
+  int16_t Y; /*!< geometric Y position of drawing */
+
+} Point;
+
+/**
+  * @brief  Pointer on LCD Drawing point (pixel) geometric definition
+  */
+typedef Point * pPoint;
+
+
+/**
+ *  @brief LCD_OrientationTypeDef
+ *  Possible values of Display Orientation
+ */
+typedef enum
+{
+	LCD_ORIENTATION_PORTRAIT  = 0x00, /*!< Portrait orientation choice of LCD screen  */
+	LCD_ORIENTATION_LANDSCAPE = 0x01, /*!< Landscape orientation choice of LCD screen */
+	LCD_ORIENTATION_INVALID   = 0x02  /*!< Invalid orientation choice of LCD screen   */
+} LCD_OrientationTypeDef;
+
+/** @addtogroup STM32746G_DISCOVERY_LCD_Exported_Functions
+  * @{
+  */
+extern ER lcd_init(LCD_Handler_t *hlcd, LCD_OrientationTypeDef orientation);
+extern ER lcd_layerdefaultinit(LCD_Handler_t *hlcd, LCD_DrawProp_t *pDrawProp, uint16_t LayerIndex, uint32_t FB_Address);
+extern ER lcd_layerRgb565init(LCD_Handler_t *hlcd, LCD_DrawProp_t *pDrawProp, uint16_t LayerIndex, uint32_t FB_Address);
+extern void lcd_setlayervisible(LCD_Handler_t *hlcd, uint32_t LayerIndex, uint8_t State);
+extern void lcd_settransparency(LCD_Handler_t *hlcd, uint32_t LayerIndex, uint8_t Transparency);
+extern void lcd_setlayeraddress(LCD_Handler_t *hlcd, uint32_t LayerIndex, uint32_t Address);
+extern void lcd_setcolorkeying(LCD_Handler_t *hlcd, uint32_t LayerIndex, uint32_t RGBValue);
+extern void lcd_resetcolorkeying(LCD_Handler_t *hlcd, uint32_t LayerIndex);
+
+extern void lcd_setAddrWindow(LCD_Handler_t *hlcd, uint16_t LayerIndex, uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1);
+extern void lcd_clear(LCD_Handler_t *hlcd, uint32_t Color);
+extern uint32_t lcd_readPixel(LCD_Handler_t *hlcd, uint16_t Xpos, uint16_t Ypos);
+extern void lcd_drawPixel(LCD_Handler_t *hlcd, uint16_t Xpos, uint16_t Ypos, uint32_t RGB_Code);
+extern void lcd_drawFastHLine(LCD_Handler_t *hlcd, uint16_t Xpos, uint16_t Ypos, uint16_t Length, uint32_t color);
+extern void lcd_drawFastVLine(LCD_Handler_t *hlcd, uint16_t Xpos, uint16_t Ypos, uint16_t Length, uint32_t color);
+extern void lcd_drawBitmap(LCD_Handler_t *hlcd, uint32_t Xpos, uint32_t Ypos, uint8_t *pbmp);
+extern void lcd_fillRect(LCD_Handler_t *hlcd, uint16_t Xpos, uint16_t Ypos, uint16_t Width, uint16_t Height, uint32_t color);
+
+extern void lcd_drawLine(LCD_DrawProp_t *pDrawProp, uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2);
+extern void lcd_drawRect(LCD_DrawProp_t *pDrawProp, uint16_t Xpos, uint16_t Ypos, uint16_t Width, uint16_t Height);
+extern void lcd_DrawCircle(LCD_DrawProp_t *pDrawProp, uint16_t Xpos, uint16_t Ypos, uint16_t Radius);
+extern void lcd_DrawEllipse(LCD_DrawProp_t *pDrawProp, int Xpos, int Ypos, int XRadius, int YRadius);
+extern void lcd_drawPolygon(LCD_DrawProp_t *pDrawProp, pPoint Points, uint16_t PointCount);
+extern void lcd_fillCircle(LCD_DrawProp_t *pDrawProp, uint16_t Xpos, uint16_t Ypos, uint16_t Radius);
+extern void lcd_fillEllipse(LCD_DrawProp_t *pDrawProp, int Xpos, int Ypos, int XRadius, int YRadius);
+extern void lcd_fillPolygon(LCD_DrawProp_t *pDrawProp, pPoint Points, uint16_t PointCount);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _STLCD_RK043FN48H_H_ */
+
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/stlcd_st7789h2/Makefile.config
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/stlcd_st7789h2/Makefile.config	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/stlcd_st7789h2/Makefile.config	(revision 457)
@@ -0,0 +1,55 @@
+#
+#   TOPPERS/ASP/FMP Kernel
+#       Toyohashi Open Platform for Embedded Real-Time Systems/
+#       Advanced Standard Profile Kernel
+#
+#   Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
+#                               Toyohashi Univ. of Technology, JAPAN
+#   Copyright (C) 2003-2008 by Ryosuke Takeuchi
+#                Platform Development Center RICOH COMPANY,LTD. JAPAN
+#   Copyright (C) 2015-2018 by TOPPERS PROJECT Educational Working Group.
+#
+#   上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+#   によって公表されている GNU General Public License の Version 2 に記
+#   述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+#   を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+#   利用と呼ぶ）することを無償で許諾する．
+#   (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+#       権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+#       スコード中に含まれていること．
+#   (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+#       用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+#       者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+#       の無保証規定を掲載すること．
+#   (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+#       用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+#       と．
+#     (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+#         作権表示，この利用条件および下記の無保証規定を掲載すること．
+#     (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+#         報告すること．
+#   (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+#       害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+#
+#   本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+#   よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+#   含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+#   接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+#
+#  @(#) $Id$
+#
+ 
+#
+#  Makefile のプロセッサ依存 (st7789h2用)
+#
+
+#
+#  コンパイルオプション
+#
+INCLUDES := $(INCLUDES) -I$(SRCDIR)/gdic/stlcd_st7789h2
+
+#
+#  USB DEVICE(GDIC)に関する定義
+#
+SYSSVC_DIR := $(SYSSVC_DIR):$(SRCDIR)/gdic/stlcd_st7789h2
+SYSSVC_COBJS := $(SYSSVC_COBJS) stlcd_st7789h2.o
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/stlcd_st7789h2/glcd_core.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/stlcd_st7789h2/glcd_core.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/stlcd_st7789h2/glcd_core.h	(revision 457)
@@ -0,0 +1,45 @@
+/*
+ *  TOPPERS BASE PLATFORM MIDDLEWARE
+ * 
+ *  Copyright (C) 2017-2018 by TOPPERS PROJECT
+ *                             Educational Working Group.
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+#ifndef _LCD_CORE_H_
+#define _LCD_CORE_H_
+
+#include "stlcd_st7789h2.h"
+
+#endif /* _LCD_CORE_H_ */
+
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/stlcd_st7789h2/stlcd_st7789h2.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/stlcd_st7789h2/stlcd_st7789h2.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/stlcd_st7789h2/stlcd_st7789h2.c	(revision 457)
@@ -0,0 +1,1302 @@
+/*
+ *  TOPPERS BASE PLATFORM MIDDLEWARE
+ * 
+ *  Copyright (C) 2017-2018 by TOPPERS PROJECT
+ *                             Educational Working Group.
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+/**
+  ******************************************************************************
+  * @attention
+  *
+  * <h2><center>&copy; COPYRIGHT(c) 2016 STMicroelectronics</center></h2>
+  *
+  * 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 STMicroelectronics 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 "stlcd_st7789h2.h"
+
+#define sil_orw_mem(a, b)		sil_wrw_mem((a), sil_rew_mem(a) | (b))
+#define sil_andw_mem(a, b)		sil_wrw_mem((a), sil_rew_mem(a) & ~(b))
+#define sil_modw_mem(a, b, c)	sil_wrw_mem((a), (sil_rew_mem(a) & (~b)) | (c))
+
+
+#define POLY_X(Z)              ((int32_t)((Points + Z)->X))
+#define POLY_Y(Z)              ((int32_t)((Points + Z)->Y))
+#define ABS(X)  ((X) > 0 ? (X) : -(X))      
+
+#define FMC_BANK2_BASE  ((uint32_t)(0x60000000 | 0x04000000))
+#define GPIO_AF12_FMC           ((uint8_t)0xCU)  /* FMC Alternate Function mapping                      */
+
+#define GIOD_PINMAP     (GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_4 | GPIO_PIN_5  | GPIO_PIN_7 | GPIO_PIN_8 |\
+						 GPIO_PIN_9 | GPIO_PIN_10 | GPIO_PIN_11 | GPIO_PIN_12 | GPIO_PIN_14 | GPIO_PIN_15)
+#define GIOE_PINMAP     (GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_7 | GPIO_PIN_8 | GPIO_PIN_9 |GPIO_PIN_10 |\
+						 GPIO_PIN_11 | GPIO_PIN_12 |GPIO_PIN_13 | GPIO_PIN_14 | GPIO_PIN_15)
+#define GIOF_PINMAP     (GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_3 | GPIO_PIN_4 | GPIO_PIN_5 |\
+						 GPIO_PIN_12 | GPIO_PIN_13 | GPIO_PIN_14 | GPIO_PIN_15)
+#define GIOG_PINMAP     (GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_3 | GPIO_PIN_4 | GPIO_PIN_5 | GPIO_PIN_9)
+
+
+typedef struct  {
+  uint8_t red;
+  uint8_t green;
+  uint8_t blue;
+} ST7789H2_Rgb888;
+
+#define LCD_IO_WriteData(b, r) do { \
+								  sil_wrh_mem((uint16_t *)((b)->fmc_base+2), (r)); \
+								  asm ("dsb 0xF":::"memory"); \
+							   } while(0)
+
+#define LCD_IO_WriteReg(b, r)  do { \
+								  sil_wrh_mem((uint16_t *)((b)->fmc_base), (r)); \
+								  asm ("dsb 0xF":::"memory"); \
+							   } while(0)
+
+#define LCD_IO_ReadData(b)     (uint16_t)sil_reh_mem((uint16_t *)((b)->fmc_base+2))
+
+
+/** @defgroup STM32F723E_DISCOVERY_LCD_Private_FunctionPrototypes STM32F723E Discovery Lcd Private Prototypes
+  * @{
+  */
+
+static void FillTriangle(LCD_DrawProp_t *pDrawProp, uint16_t x1, uint16_t x2, uint16_t x3, uint16_t y1, uint16_t y2, uint16_t y3);
+
+
+/**
+  * @brief  Initializes LCD low level.
+  * @retval None
+  */
+static void LCD_IO_Init(void) 
+{
+	GPIO_Init_t GPIO_Init_Data;
+	uint32_t pin, i;
+	uint32_t tmpr = 0;
+
+	/* Enable FMC clock */
+	sil_orw_mem((uint32_t *)(TADR_RCC_BASE+TOFF_RCC_AHB3ENR), RCC_AHB3ENR_FMCEN);
+
+	/* Enable FSMC clock */
+	sil_orw_mem((uint32_t *)(TADR_RCC_BASE+TOFF_RCC_AHB3ENR), RCC_AHB3ENR_FMCEN);
+	sil_orw_mem((uint32_t *)(TADR_RCC_BASE+TOFF_RCC_AHB3RSTR), RCC_AHB3RSTR_FMCRST);
+	sil_andw_mem((uint32_t *)(TADR_RCC_BASE+TOFF_RCC_AHB3RSTR), RCC_AHB3RSTR_FMCRST);
+
+	/* Enable GPIOs clock */
+	sil_orw_mem((uint32_t *)(TADR_RCC_BASE+TOFF_RCC_AHB1ENR), RCC_AHB1ENR_GPIODEN);
+	sil_orw_mem((uint32_t *)(TADR_RCC_BASE+TOFF_RCC_AHB1ENR), RCC_AHB1ENR_GPIOEEN);
+	sil_orw_mem((uint32_t *)(TADR_RCC_BASE+TOFF_RCC_AHB1ENR), RCC_AHB1ENR_GPIOFEN);
+	sil_orw_mem((uint32_t *)(TADR_RCC_BASE+TOFF_RCC_AHB1ENR), RCC_AHB1ENR_GPIOGEN);
+
+	GPIO_Init_Data.mode      = GPIO_MODE_AF;
+	GPIO_Init_Data.pull      = GPIO_PULLUP;
+	GPIO_Init_Data.otype     = GPIO_OTYPE_PP;
+	GPIO_Init_Data.speed     = GPIO_SPEED_HIGH;
+	GPIO_Init_Data.alternate = GPIO_AF12_FMC;
+
+	/* GPIOD configuration */ 
+	/* LCD_PSRAM_D2, LCD_PSRAM_D3, LCD_PSRAM_NOE, LCD_PSRAM_NWE, PSRAM_NE1, LCD_PSRAM_D13, 
+	   LCD_PSRAM_D14, LCD_PSRAM_D15, PSRAM_A16, PSRAM_A17, LCD_PSRAM_D0, LCD_PSRAM_D1 */
+	pin = GIOD_PINMAP;
+	for(i = 0 ; i < 16 ; i++){
+		if((pin & (1<<i)) != 0)
+			gpio_setup(TADR_GPIOD_BASE, &GPIO_Init_Data, i);
+	}
+
+	/* GPIOE configuration */
+	/* PSRAM_NBL0, PSRAM_NBL1, LCD_PSRAM_D4, LCD_PSRAM_D5, LCD_PSRAM_D6, LCD_PSRAM_D7, 
+	   LCD_PSRAM_D8, LCD_PSRAM_D9, LCD_PSRAM_D10, LCD_PSRAM_D11, LCD_PSRAM_D12 */
+	pin = GIOE_PINMAP;
+	for(i = 0 ; i < 16 ; i++){
+		if((pin & (1<<i)) != 0)
+			gpio_setup(TADR_GPIOE_BASE, &GPIO_Init_Data, i);
+	}
+
+	/* GPIOF configuration */
+	/* PSRAM_A0, PSRAM_A1, PSRAM_A2, PSRAM_A3, PSRAM_A4, PSRAM_A5, 
+	   PSRAM_A6, PSRAM_A7, PSRAM_A8, PSRAM_A9 */
+	pin = GIOF_PINMAP;
+	for(i = 0 ; i < 16 ; i++){
+		if((pin & (1<<i)) != 0)
+			gpio_setup(TADR_GPIOF_BASE, &GPIO_Init_Data, i);
+	}
+
+	/* GPIOG configuration */
+	/* PSRAM_A10, PSRAM_A11, PSRAM_A12, PSRAM_A13, PSRAM_A14, PSRAM_A15, LCD_NE */
+	pin = GIOG_PINMAP;
+	for(i = 0 ; i < 16 ; i++){
+		if((pin & (1<<i)) != 0)
+			gpio_setup(TADR_GPIOG_BASE, &GPIO_Init_Data, i);
+	}
+
+	/* Initialize SRAM control Interface */
+	tmpr = sil_rew_mem((uint32_t *)(TADR_FMC_R_BASE+TOFF_FMC_R_BTCR2));
+
+	/* Clear MBKEN, MUXEN, MTYP, MWID, FACCEN, BURSTEN, WAITPOL, WAITCFG, WREN,
+           WAITEN, EXTMOD, ASYNCWAIT, CBURSTRW and CCLKEN bits */
+	tmpr &= ((uint32_t)~(FMC_BCR1_MBKEN     | FMC_BCR1_MUXEN    | FMC_BCR1_MTYP    | \
+                       FMC_BCR1_MWID      | FMC_BCR1_FACCEN   | FMC_BCR1_BURSTEN | \
+                       FMC_BCR1_WAITPOL   | FMC_BCR1_CPSIZE   | FMC_BCR1_WAITCFG | \
+                       FMC_BCR1_WREN      | FMC_BCR1_WAITEN   | FMC_BCR1_EXTMOD  | \
+                       FMC_BCR1_ASYNCWAIT | FMC_BCR1_CBURSTRW | FMC_BCR1_CCLKEN  | FMC_BCR1_WFDIS));
+
+	/* Set NORSRAM device control parameters */
+	tmpr |= (uint32_t)(FMC_BCR1_MWID_0 | FMC_BCR1_WREN | FMC_BCR1_WFDIS);
+
+	sil_wrw_mem((uint32_t *)(TADR_FMC_R_BASE+TOFF_FMC_R_BTCR2), tmpr);
+
+	/* Configure synchronous mode when Continuous clock is enabled for bank2..4 */
+	sil_orw_mem((uint32_t *)(TADR_FMC_R_BASE+TOFF_FMC_R_BTCR0), FMC_BCR1_WFDIS);
+
+	/* Get the BTCR register value */
+	tmpr = sil_rew_mem((uint32_t *)(TADR_FMC_R_BASE+TOFF_FMC_R_BTCR3));
+
+	/* Clear ADDSET, ADDHLD, DATAST, BUSTURN, CLKDIV, DATLAT and ACCMOD bits */
+	tmpr &= ((uint32_t)~(FMC_BTR1_ADDSET  | FMC_BTR1_ADDHLD | FMC_BTR1_DATAST | \
+                       FMC_BTR1_BUSTURN | FMC_BTR1_CLKDIV | FMC_BTR1_DATLAT | \
+                       FMC_BTR1_ACCMOD));
+
+	/* Set FMC_NORSRAM device timing parameters */  
+	tmpr |= (uint32_t)(9 /* AddressSetupTime */                 |\
+                   ((2 /* AddressHoldTime */ ) << 4)          |\
+                   ((6 /* DataSetupTime */ ) << 8)            |\
+                   ((1 /* BusTurnAroundDuration */ ) << 16)   |\
+                   (((2 /* CLKDivision */ )-1) << 20)         |\
+                   (((2 /* DataLatency */)-2) << 24));
+
+	sil_wrw_mem((uint32_t *)(TADR_FMC_R_BASE+TOFF_FMC_R_BTCR3), tmpr);
+
+	/* Configure Clock division value (in NORSRAM bank 1) when continuous clock is enabled */
+	if((sil_rew_mem((uint32_t *)(TADR_FMC_R_BASE+TOFF_FMC_R_BTCR1)) & FMC_BCR1_CCLKEN) != 0){
+		tmpr = sil_rew_mem((uint32_t *)(TADR_FMC_R_BASE+TOFF_FMC_R_BTCR1));
+		tmpr &= ~(((uint32_t)0x0F) << 20);
+		tmpr |= (uint32_t)(((2 /* CLKDivision */ )-1) << 20);
+		sil_wrw_mem((uint32_t *)(TADR_FMC_R_BASE+TOFF_FMC_R_BTCR1), tmpr);
+	}
+
+	/* Initialize SRAM extended mode timing Interface */
+	sil_wrw_mem((uint32_t *)(TADR_FMC_R_BASE+TOFF_FMC_R_BWTR2), 0xFFFFFFFF);
+
+	/* Enable the NORSRAM device */
+	sil_orw_mem((uint32_t *)(TADR_FMC_R_BASE+TOFF_FMC_R_BTCR2), FMC_BCR1_MBKEN);
+}
+
+
+/**
+  * @brief  Writes to the selected LCD register.
+  * @param  Command: command value (or register address as named in st7789h2 doc).
+  * @param  Parameters: pointer on parameters value (if command uses one or several parameters).
+  * @param  NbParameters: number of command parameters (0 if no parameter)
+  * @retval None
+  */
+static void
+ST7789H2_WriteReg(LCD_Handler_t *hlcd, uint8_t Command, uint8_t *Parameters, uint8_t NbParameters)
+{
+	uint8_t   i;
+
+	/* Send command */
+	LCD_IO_WriteReg(hlcd, Command);
+
+	/* Send command's parameters if any */
+	for(i = 0 ; i<NbParameters; i++){
+		LCD_IO_WriteData(hlcd, Parameters[i]);
+	}
+}
+
+/**
+  * @brief  Reads the selected LCD Register.
+  * @param  Command: command value (or register address as named in st7789h2 doc).
+  * @retval Register Value.
+  */
+static uint8_t
+ST7789H2_ReadReg(LCD_Handler_t *hlcd, uint8_t Command)
+{
+	/* Send command */
+	LCD_IO_WriteReg(hlcd, Command);
+
+	/* Read dummy data */
+	LCD_IO_ReadData(hlcd);
+
+	/* Read register value */
+	return (LCD_IO_ReadData(hlcd));
+}
+
+/**
+  * @brief  Initialize the st7789h2 LCD Component.
+  * @param  None
+  * @retval None
+  */
+static void
+ST7789H2_Init(LCD_Handler_t *hlcd)
+{
+	uint8_t   parameter[14];
+
+	/* Initialize st7789h2 low level bus layer ----------------------------------*/
+	/* Sleep In Command */ 
+	ST7789H2_WriteReg(hlcd, ST7789H2_SLEEP_IN, (uint8_t*)NULL, 0); 
+	/* Wait for 10ms */
+	dly_tsk(10);
+
+	/* SW Reset Command */
+	ST7789H2_WriteReg(hlcd, 0x01, (uint8_t*)NULL, 0); 
+	/* Wait for 200ms */
+	dly_tsk(200);
+
+	/* Sleep Out Command */
+	ST7789H2_WriteReg(hlcd, ST7789H2_SLEEP_OUT, (uint8_t*)NULL, 0); 
+	/* Wait for 120ms */
+	dly_tsk(120);
+
+	/* Normal display for Driver Down side */
+	parameter[0] = 0x00;
+	ST7789H2_WriteReg(hlcd, ST7789H2_NORMAL_DISPLAY, parameter, 1);
+
+	/* Color mode 16bits/pixel */
+	parameter[0] = 0x05;
+	ST7789H2_WriteReg(hlcd, ST7789H2_COLOR_MODE, parameter, 1);
+
+	/* Display inversion On */
+	ST7789H2_WriteReg(hlcd, ST7789H2_DISPLAY_INVERSION, (uint8_t*)NULL, 0);
+
+	/* Set Column address CASET */
+	parameter[0] = 0x00;
+	parameter[1] = 0x00;
+	parameter[2] = 0x00;
+	parameter[3] = 0xEF;
+	ST7789H2_WriteReg(hlcd, ST7789H2_CASET, parameter, 4);
+	/* Set Row address RASET */
+	parameter[0] = 0x00;
+	parameter[1] = 0x00;
+	parameter[2] = 0x00;
+	parameter[3] = 0xEF;
+	ST7789H2_WriteReg(hlcd, ST7789H2_RASET, parameter, 4);
+
+	/*--------------- ST7789H2 Frame rate setting -------------------------------*/
+	/* PORCH control setting */      
+	parameter[0] = 0x0C;
+	parameter[1] = 0x0C;
+	parameter[2] = 0x00;
+	parameter[3] = 0x33;
+	parameter[4] = 0x33; 
+	ST7789H2_WriteReg(hlcd, ST7789H2_PORCH_CTRL, parameter, 5);
+
+	/* GATE control setting */
+	parameter[0] = 0x35; 
+	ST7789H2_WriteReg(hlcd, ST7789H2_GATE_CTRL, parameter, 1);
+
+	/*--------------- ST7789H2 Power setting ------------------------------------*/
+	/* VCOM setting */ 
+	parameter[0] = 0x1F;
+	ST7789H2_WriteReg(hlcd, ST7789H2_VCOM_SET, parameter, 1); 
+
+	/* LCM Control setting */
+	parameter[0] = 0x2C; 
+	ST7789H2_WriteReg(hlcd, ST7789H2_LCM_CTRL, parameter, 1);
+
+	/* VDV and VRH Command Enable */
+	parameter[0] = 0x01;
+	parameter[1] = 0xC3;
+	ST7789H2_WriteReg(hlcd, ST7789H2_VDV_VRH_EN, parameter, 2);
+
+	/* VDV Set */ 
+	parameter[0] = 0x20;
+	ST7789H2_WriteReg(hlcd, ST7789H2_VDV_SET, parameter, 1);
+
+	/* Frame Rate Control in normal mode */
+	parameter[0] = 0x0F; 
+	ST7789H2_WriteReg(hlcd, ST7789H2_FR_CTRL, parameter, 1);
+
+	/* Power Control */
+	parameter[0] = 0xA4;
+	parameter[1] = 0xA1;
+	ST7789H2_WriteReg(hlcd, ST7789H2_POWER_CTRL, parameter, 1); 
+
+	/*--------------- ST7789H2 Gamma setting ------------------------------------*/
+	/* Positive Voltage Gamma Control */ 
+	parameter[0] = 0xD0;
+	parameter[1] = 0x08;
+	parameter[2] = 0x11;
+	parameter[3] = 0x08;
+	parameter[4] = 0x0C;
+	parameter[5] = 0x15;
+	parameter[6] = 0x39;
+	parameter[7] = 0x33;
+	parameter[8] = 0x50;
+	parameter[9] = 0x36;
+	parameter[10] = 0x13;
+	parameter[11] = 0x14;
+	parameter[12] = 0x29;
+	parameter[13] = 0x2D;
+	ST7789H2_WriteReg(hlcd, ST7789H2_PV_GAMMA_CTRL, parameter, 14); 
+
+	/* Negative Voltage Gamma Control */
+	parameter[0] = 0xD0;
+	parameter[1] = 0x08;
+	parameter[2] = 0x10;
+	parameter[3] = 0x08;
+	parameter[4] = 0x06;
+	parameter[5] = 0x06;
+	parameter[6] = 0x39;
+	parameter[7] = 0x44;
+	parameter[8] = 0x51;
+	parameter[9] = 0x0B;
+	parameter[10] = 0x16;
+	parameter[11] = 0x14;
+	parameter[12] = 0x2F;
+	parameter[13] = 0x31;
+	ST7789H2_WriteReg(hlcd, ST7789H2_NV_GAMMA_CTRL, parameter, 14); 
+
+	/* Display ON command */
+	lcd_displayOn(hlcd);
+
+	/* Tearing Effect Line On: Option (00h:VSYNC Interface OFF, 01h:VSYNC Interface ON) */
+	parameter[0] = 0x00;
+	ST7789H2_WriteReg(hlcd, ST7789H2_TEARING_EFFECT, parameter, 1);
+}
+
+/**
+  * @brief  Set the Display Orientation.
+  * @param  orientation: ST7789H2_ORIENTATION_PORTRAIT, ST7789H2_ORIENTATION_LANDSCAPE
+  *                      or ST7789H2_ORIENTATION_LANDSCAPE_ROT180  
+  * @retval None
+  */
+static void
+ST7789H2_SetOrientation(LCD_Handler_t *hlcd, uint32_t orientation)
+{
+	uint8_t   parameter[6];
+
+	if(orientation == ST7789H2_ORIENTATION_LANDSCAPE){
+		parameter[0] = 0x00;
+	}
+	else if(orientation == ST7789H2_ORIENTATION_LANDSCAPE_ROT180){
+		/* Vertical Scrolling Definition */
+		/* TFA describes the Top Fixed Area */
+		parameter[0] = 0x00;
+		parameter[1] = 0x00;
+		/* VSA describes the height of the Vertical Scrolling Area */
+		parameter[2] = 0x01;
+		parameter[3] = 0xF0;
+		/* BFA describes the Bottom Fixed Area */
+		parameter[4] = 0x00;
+		parameter[5] = 0x00; 
+		ST7789H2_WriteReg(hlcd, ST7789H2_VSCRDEF, parameter, 6);
+
+		/* Vertical Scroll Start Address of RAM */
+		/* GRAM row nbr (320) - Display row nbr (240) = 80 = 0x50 */
+		parameter[0] = 0x00;
+		parameter[1] = 0x50;
+		ST7789H2_WriteReg(hlcd, ST7789H2_VSCSAD, parameter, 2);
+
+		parameter[0] = 0xC0;
+	}
+	else{
+		parameter[0] = 0x60;
+	}
+	ST7789H2_WriteReg(hlcd, ST7789H2_NORMAL_DISPLAY, parameter, 1);
+}
+
+/**
+  * @brief  Set Cursor position.
+  * @param  Xpos: specifies the X position.
+  * @param  Ypos: specifies the Y position.
+  * @retval None
+  */
+static void
+ST7789H2_SetCursor(LCD_Handler_t *hlcd, uint16_t Xpos, uint16_t Ypos)
+{
+  uint8_t   parameter[4];
+  /* CASET: Comumn Addrses Set */
+  parameter[0] = 0x00;     
+  parameter[1] = 0x00 + Xpos;
+  parameter[2] = 0x00;
+  parameter[3] = 0xEF + Xpos;
+  ST7789H2_WriteReg(hlcd, ST7789H2_CASET, parameter, 4);
+  /* RASET: Row Addrses Set */  
+  parameter[0] = 0x00;
+  parameter[1] = 0x00 + Ypos;
+  parameter[2] = 0x00;
+  parameter[3] = 0xEF + Ypos;
+  ST7789H2_WriteReg(hlcd, ST7789H2_RASET, parameter, 4);
+}
+
+/**
+  * @brief  Read pixel from LCD RAM in RGB888 format
+  * @param  Xpos: specifies the X position.
+  * @param  Ypos: specifies the Y position.
+  * @retval Each RGB pixel color components in a structure
+  */
+static ST7789H2_Rgb888
+ST7789H2_ReadPixel_rgb888(LCD_Handler_t *hlcd, uint16_t Xpos, uint16_t Ypos)
+{
+	ST7789H2_Rgb888 rgb888;
+	uint16_t         rgb888_part1, rgb888_part2;
+
+  /* In LCD RAM, pixels are 24 bits packed and read with 16 bits access
+   * Here is the pixels components arrangement in memory :
+   *       bits:  15 14 13 12 11 10 09 08 | 07 06 05 04 03 02 01 00
+   * address 0 :     red pixel 0    X  X  |   green pixel 0   X  X
+   * address 1 :    blue pixel 0    X  X  |     red pixel 1   X  X
+   * address 2 :   green pixel 1    X  X  |    blue pixel 1   X  X
+   */
+
+	/* Set Cursor */
+	ST7789H2_SetCursor(hlcd, Xpos, Ypos);
+	/* Prepare to read LCD RAM */
+	ST7789H2_WriteReg(hlcd, ST7789H2_READ_RAM, (uint8_t*)NULL, 0);   /* RAM read data command */
+	/* Dummy read */
+	LCD_IO_ReadData(hlcd);
+	/* Read first part of the RGB888 data */
+	rgb888_part1 = LCD_IO_ReadData(hlcd);
+	/* Read first part of the RGB888 data */
+	rgb888_part2 = LCD_IO_ReadData(hlcd);
+
+	/* red component */
+	rgb888.red   = (rgb888_part1 & 0xFC00) >> 8;
+	/* green component */
+	rgb888.green = (rgb888_part1 & 0x00FC) >> 0;
+	/* blue component */
+	rgb888.blue  = (rgb888_part2 & 0xFC00) >> 8;
+	return rgb888;
+}
+
+/**
+  * @brief  Displays a single picture line.
+  * @param  pdata: picture address.
+  * @param  Xpos: Image X position in the LCD
+  * @param  Ypos: Image Y position in the LCD
+  * @param  Xsize: Image X size in the LCD
+  * @retval None
+  */
+static void
+ST7789H2_DrawRGBHLine(LCD_Handler_t *hlcd, uint16_t Xpos, uint16_t Ypos, uint16_t Xsize, uint8_t *pdata)
+{
+	uint32_t i = 0;
+	uint32_t posX;
+	uint16_t *rgb565 = (uint16_t*)pdata;
+
+	/* Prepare to write to LCD RAM */
+	ST7789H2_WriteReg(hlcd, ST7789H2_WRITE_RAM, (uint8_t*)NULL, 0);   /* RAM write data command */
+
+	for(posX = Xpos ; posX < (Xsize + Xpos) ; posX++){
+		if((posX >= hlcd->winXstart) && (Ypos >= hlcd->winYstart) &&     /* Check we are in the defined window */
+			(posX <= hlcd->winXend) && (Ypos <= hlcd->winXend)){
+			if(posX != (Xsize + Xpos)){	/* When writing last pixel when size is odd, the third part is not written */
+				LCD_IO_WriteData(hlcd, rgb565[i]);
+			}
+			i++;
+		}
+	}
+}
+
+/*
+ *  ST7789H2スクリーンの初期化関数
+ */
+ER
+lcd_init(LCD_Handler_t *hlcd, uint32_t orientation)
+{ 
+	GPIO_Init_t GPIO_Init_Data;
+	uint16_t id;
+
+	hlcd->_width  = ST7789H2_LCD_PIXEL_WIDTH;
+	hlcd->_height = ST7789H2_LCD_PIXEL_HEIGHT;
+	hlcd->winXstart = 0;
+	hlcd->winYstart = 0;
+	hlcd->winXend = hlcd->_width - 1;
+	hlcd->winXend = hlcd->_height - 1;
+
+	/* Initialize LCD special pins GPIOs */
+	sil_orw_mem((uint32_t *)(TADR_RCC_BASE+TOFF_RCC_AHB1ENR), hlcd->rst_clk);
+	sil_orw_mem((uint32_t *)(TADR_RCC_BASE+TOFF_RCC_AHB1ENR), hlcd->te_clk);
+	sil_orw_mem((uint32_t *)(TADR_RCC_BASE+TOFF_RCC_AHB1ENR), hlcd->bl_clk);
+
+	GPIO_Init_Data.mode      = GPIO_MODE_OUTPUT;   /* LCD_RESET pin has to be manually controlled */
+	GPIO_Init_Data.speed     = hlcd->gpio_speed;
+	GPIO_Init_Data.pull      = hlcd->rst_pull;
+	GPIO_Init_Data.otype     = GPIO_OTYPE_PP;
+	gpio_setup(hlcd->rst_base, &GPIO_Init_Data, hlcd->rst_pin);
+	sil_wrw_mem((uint32_t *)(hlcd->rst_base+TOFF_GPIO_BSRR), (1<<hlcd->rst_pin) << 16);
+
+	/* LCD_TE GPIO configuration */
+	GPIO_Init_Data.mode      = GPIO_MODE_INPUT;        /* LCD_TE pin has to be manually managed */
+	gpio_setup(hlcd->te_base, &GPIO_Init_Data, hlcd->te_pin);
+
+	/* LCD_BL_CTRL GPIO configuration */
+	GPIO_Init_Data.mode      = GPIO_MODE_OUTPUT;   /* LCD_BL_CTRL pin has to be manually controlled */
+	GPIO_Init_Data.pull      = hlcd->bl_pull;
+	gpio_setup(hlcd->bl_base, &GPIO_Init_Data, hlcd->bl_pin);
+
+	/* Backlight control signal assertion */
+	if(hlcd->bl_active == 0)
+		sil_wrw_mem((uint32_t *)(hlcd->bl_base+TOFF_GPIO_BSRR), (1<<hlcd->bl_pin) << 16);
+	else
+		sil_wrw_mem((uint32_t *)(hlcd->bl_base+TOFF_GPIO_BSRR), (1<<hlcd->bl_pin));
+
+	/* Apply hardware reset according to procedure indicated in FRD154BP2901 documentation */
+	dly_tsk(5);   /* Reset signal asserted during 5ms  */
+	sil_wrw_mem((uint32_t *)(hlcd->rst_base+TOFF_GPIO_BSRR), (1<<hlcd->rst_pin));
+	dly_tsk(10);  /* Reset signal released during 10ms */
+	sil_wrw_mem((uint32_t *)(hlcd->rst_base+TOFF_GPIO_BSRR), (1<<hlcd->rst_pin) << 16);
+	dly_tsk(20);  /* Reset signal asserted during 20ms */
+	sil_wrw_mem((uint32_t *)(hlcd->rst_base+TOFF_GPIO_BSRR), (1<<hlcd->rst_pin));
+	dly_tsk(10);  /* Reset signal released during 10ms */
+
+	LCD_IO_Init();
+	id = ST7789H2_ReadReg(hlcd, ST7789H2_LCD_ID);
+	if(id  == ST7789H2_ID){
+		/* LCD Init */
+		ST7789H2_Init(hlcd);
+
+		if(orientation == LCD_ORIENTATION_PORTRAIT){
+			ST7789H2_SetOrientation(hlcd, LCD_ORIENTATION_PORTRAIT);
+		}
+		else if(orientation == LCD_ORIENTATION_LANDSCAPE_ROT180){
+			ST7789H2_SetOrientation(hlcd, LCD_ORIENTATION_LANDSCAPE_ROT180);
+		}
+		else{
+			/* Default landscape orientation is selected */
+		}
+		return E_OK;
+	}
+	else
+		return E_SYS;
+}
+
+/*
+ *  ST7789H2スクリーンの終了関数
+ */
+ER
+lcd_deinit(LCD_Handler_t *hlcd)
+{
+	/* Actually LcdDrv does not provide a DeInit function */
+	return E_OK;
+}
+
+/*
+ *  ST7789H2スクリーンレイヤ初期化関数
+ */
+ER
+lcd_layerdefaultinit(LCD_Handler_t *hlcd, LCD_DrawProp_t *pDrawProp, uint16_t LayerIndex, uint32_t FB_Address)
+{
+	pDrawProp->BackColor = 0xFFFF;
+	pDrawProp->TextColor = 0x0000;
+	pDrawProp->hlcd      = hlcd;
+	return E_OK;
+}
+
+/*
+ *  ST7789H2表示ウィンドウ設定
+ */
+void
+lcd_setAddrWindow(LCD_Handler_t *hlcd, uint16_t Xpos, uint16_t Ypos, uint16_t Width, uint16_t Height)
+{
+	if(Xpos < hlcd->_width){
+		hlcd->winXstart = Xpos;
+	}
+	else{
+		hlcd->winXstart = 0;
+	}
+
+	if(Ypos < hlcd->_height){
+		hlcd->winYstart = Ypos;
+	}
+	else{
+		hlcd->winYstart = 0;
+	}
+
+	if(Width  + Xpos <= hlcd->_width){
+		hlcd->winXend = Width  + Xpos - 1;
+	}
+	else{
+		hlcd->winXend = hlcd->_width - 1;
+	}
+
+	if(Height + Ypos <= hlcd->_height){
+		hlcd->winXend = Height + Ypos - 1;
+	}
+	else{
+		hlcd->winXend = hlcd->_height-1;
+	}
+}
+
+/*
+ *  ST7789H2スクリーンクリア
+ */
+void
+lcd_clear(LCD_Handler_t *hlcd, uint16_t Color)
+{
+	uint32_t counter = 0;
+	uint32_t y_size = 0;
+
+	y_size =  hlcd->_height;
+
+	for(counter = 0; counter < y_size; counter++){
+		lcd_drawFastHLine(hlcd, 0, counter, hlcd->_width, Color);
+	}
+}
+
+/*
+ *  PIXEL読み出し
+ *  param1  hlcd: Pointer to LCD Handler
+ *  param2  x: X position
+ *  param3  y: Y position
+ */
+uint16_t
+lcd_readPixel(LCD_Handler_t *hlcd, uint16_t Xpos, uint16_t Ypos)
+{
+	ST7789H2_Rgb888 rgb888;
+	uint8_t          r, g, b;
+	uint16_t         rgb565;
+
+	/* Set Cursor */
+	ST7789H2_SetCursor(hlcd, Xpos, Ypos);
+
+	/* Read RGB888 data from LCD RAM */
+	rgb888 = ST7789H2_ReadPixel_rgb888(hlcd, Xpos, Ypos);
+
+	/* Convert RGB888 to RGB565 */
+	r = ((rgb888.red & 0xF8) >> 3);    /* Extract the red component 5 most significant bits */
+	g = ((rgb888.green & 0xFC) >> 2);  /* Extract the green component 6 most significant bits */
+	b = ((rgb888.blue & 0xF8) >> 3);   /* Extract the blue component 5 most significant bits */
+
+	rgb565 = ((uint16_t)(r) << 11) + ((uint16_t)(g) << 5) + ((uint16_t)(b) << 0);
+	return (rgb565);
+}
+
+/*
+ *  PIXEL描画
+ *  param1  hlcd: Pointer to LCD Handler
+ *  param2  x: X position
+ *  param3  y: Y position
+ *  param4  color: color value
+ */
+void
+lcd_drawPixel(LCD_Handler_t *hlcd, int16_t Xpos, int16_t Ypos, uint16_t RGB_Code)
+{
+	ST7789H2_SetCursor(hlcd, Xpos, Ypos);
+
+	/* Prepare to write to LCD RAM */
+	ST7789H2_WriteReg(hlcd, ST7789H2_WRITE_RAM, (uint8_t*)NULL, 0);   /* RAM write data command */
+
+	/* Write RAM data */
+	LCD_IO_WriteData(hlcd, RGB_Code);
+}
+
+/*
+ *  垂直方向LINEの高速描画
+ *  param1  hlcd: Pointer to LCD Handler
+ *  param2  x: start X position
+ *  param3  y: start Y position
+ *  param4  h: height
+ *  param5  color: color value
+ */
+void
+lcd_drawFastHLine(LCD_Handler_t *hlcd, uint16_t Xpos, uint16_t Ypos, uint16_t Length, uint32_t color)
+{
+	uint16_t counter = 0;
+
+	/* Set Cursor */
+	ST7789H2_SetCursor(hlcd, Xpos, Ypos);
+
+	/* Prepare to write to LCD RAM */
+	ST7789H2_WriteReg(hlcd, ST7789H2_WRITE_RAM, (uint8_t*)NULL, 0);   /* RAM write data command */
+
+	/* Sent a complete line */
+	for(counter = 0; counter < Length; counter++){
+		LCD_IO_WriteData(hlcd, color);
+	}
+}
+
+/*
+ *  水平方向LINEの高速描画
+ *  param1  hlcd: Pointer to LCD Handler
+ *  param2  x: start X position
+ *  param3  y: start Y position
+ *  param4  w: width
+ *  param5  color: color value
+ */
+void
+lcd_drawFastVLine(LCD_Handler_t *hlcd, uint16_t Xpos, uint16_t Ypos, uint16_t Length, uint32_t color)
+{
+	uint16_t counter = 0;
+
+	/* Set Cursor */
+	ST7789H2_SetCursor(hlcd, Xpos, Ypos);
+
+	/* Prepare to write to LCD RAM */
+	ST7789H2_WriteReg(hlcd, ST7789H2_WRITE_RAM, (uint8_t*)NULL, 0);   /* RAM write data command */
+
+	/* Fill a complete vertical line */
+	for(counter = 0; counter < Length; counter++){
+		lcd_drawPixel(hlcd, Xpos, Ypos + counter, color);
+	}
+}
+
+/*
+ *  BITMAP描画
+ *  param1  hlcd: Pointer to LCD Handler
+ *  param2  x0: Bmp X position in the LCD
+ *  param3  y0: Bmp Y position in the LCD
+ *  param4  pbmp: Pointer to Bmp picture address in the internal Flash
+ */
+void
+lcd_drawBitmap(LCD_Handler_t *hlcd, uint16_t Xpos, uint16_t Ypos, uint8_t *pbmp)
+{
+	uint32_t height = 0;
+	uint32_t width  = 0;
+	uint32_t index = 0, size = 0;
+	uint32_t posY;
+	uint32_t nb_line = 0;
+	uint16_t Xsize = hlcd->winXend - hlcd->winXstart + 1;
+	uint16_t Ysize = hlcd->winXend - hlcd->winYstart + 1;
+
+	/* Read bitmap width */
+	width = pbmp[18] + (pbmp[19] << 8) + (pbmp[20] << 16)  + (pbmp[21] << 24);
+
+	/* Read bitmap height */
+	height = pbmp[22] + (pbmp[23] << 8) + (pbmp[24] << 16)  + (pbmp[25] << 24);
+
+	lcd_setAddrWindow(hlcd, Xpos, Ypos, width, height);
+
+	/* Read bitmap size */
+	size = *(volatile uint16_t *) (pbmp + 2);
+	size |= (*(volatile uint16_t *) (pbmp + 4)) << 16;
+	/* Get bitmap data address offset */
+	index = *(volatile uint16_t *) (pbmp + 10);
+	index |= (*(volatile uint16_t *) (pbmp + 12)) << 16;
+	size = (size - index)/2;
+	pbmp += index;
+
+	for (posY = (Ypos + Ysize); posY > Ypos; posY--){	/* In BMP files the line order is inverted */
+		/* Set Cursor */
+		ST7789H2_SetCursor(hlcd, Xpos, posY - 1);
+
+		/* Draw one line of the picture */
+		ST7789H2_DrawRGBHLine(hlcd, Xpos, posY - 1, Xsize, (pbmp + (nb_line * Xsize * 2)));
+		nb_line++;
+	}
+	lcd_setAddrWindow(hlcd, 0, 0, hlcd->_width, hlcd->_height);
+}
+
+/*
+ *  バッファコピー
+ *  param1  hlcd: Pointer to LCD Handler
+ *  param2  Xpos: コピー先X座標
+ *  param3  Ypos: コピー先Y座標
+ *  param4  Xsize: バッファ幅
+ *  param5  Ysize: バッファ高さ
+ *  param6  pdata: コピー元バッファポインタ
+ */
+void
+lcd_drawRGBImage(LCD_Handler_t *hlcd, uint16_t Xpos, uint16_t Ypos, uint16_t Xsize, uint16_t Ysize, uint8_t *pdata)
+{
+	uint32_t posY;
+	uint32_t nb_line = 0;
+
+	lcd_setAddrWindow(hlcd, Xpos, Ypos, Xsize, Ysize);
+
+	for(posY = Ypos ; posY < (Ypos + Ysize) ; posY++){
+		/* Set Cursor */
+		ST7789H2_SetCursor(hlcd, Xpos, posY);
+
+		/* Draw one line of the picture */
+		ST7789H2_DrawRGBHLine(hlcd, Xpos, posY, Xsize, (pdata + (nb_line * Xsize * 2)));
+		nb_line++;
+	}
+	lcd_setAddrWindow(hlcd, 0, 0, hlcd->_width, hlcd->_height);
+}
+
+/*
+ *  RECTANGLE塗りつぶし描画
+ *  param1  hlcd: Pointer to LCD Handler
+ *  param2  x: left X position
+ *  param3  y: top Y position
+ *  param4  w: width
+ *  param5  h: height
+ *  param6  color: color value
+ */
+void
+lcd_fillRect(LCD_Handler_t *hlcd, uint16_t Xpos, uint16_t Ypos, uint16_t Width, uint16_t Height, uint32_t color)
+{
+	do{
+		lcd_drawFastHLine(hlcd, Xpos, Ypos++, Width, color);
+	}
+	while(Height--);
+}
+
+
+/*
+ *  線描画
+ *  param1  pDrawProp: Pointer to Draw Prop
+ *  param2  x1: Point 1 X position
+ *  param3  y1: Point 1 Y position
+ *  param4  x2: Point 2 X position
+ *  param5  y2: Point 2 Y position
+ */
+void
+lcd_drawLine(LCD_DrawProp_t *pDrawProp, uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2)
+{
+	int16_t deltax = 0, deltay = 0, x = 0, y = 0, xinc1 = 0, xinc2 = 0, 
+	yinc1 = 0, yinc2 = 0, den = 0, num = 0, numadd = 0, numpixels = 0, 
+	curpixel = 0;
+
+	deltax = ABS(x2 - x1);		/* The difference between the x's */
+	deltay = ABS(y2 - y1);		/* The difference between the y's */
+	x = x1;						/* Start x off at the first pixel */
+	y = y1;						/* Start y off at the first pixel */
+
+	if(x2 >= x1){				/* The x-values are increasing */
+		xinc1 = 1;
+		xinc2 = 1;
+	}
+	else{						/* The x-values are decreasing */
+		xinc1 = -1;
+		xinc2 = -1;
+	}
+
+	if(y2 >= y1){				/* The y-values are increasing */
+		yinc1 = 1;
+		yinc2 = 1;
+	}
+	else{						/* The y-values are decreasing */
+		yinc1 = -1;
+		yinc2 = -1;
+	}
+
+	if(deltax >= deltay){		/* There is at least one x-value for every y-value */
+		xinc1 = 0;                  /* Don't change the x when numerator >= denominator */
+		yinc2 = 0;                  /* Don't change the y for every iteration */
+		den = deltax;
+		num = deltax / 2;
+		numadd = deltay;
+		numpixels = deltax;         /* There are more x-values than y-values */
+	}
+	else{						/* There is at least one y-value for every x-value */
+		xinc2 = 0;				/* Don't change the x for every iteration */
+		yinc1 = 0;				/* Don't change the y when numerator >= denominator */
+		den = deltay;
+		num = deltay / 2;
+		numadd = deltax;
+		numpixels = deltay;		/* There are more y-values than x-values */
+	}
+
+	for(curpixel = 0; curpixel <= numpixels; curpixel++){
+		lcd_drawPixel(pDrawProp->hlcd, x, y, pDrawProp->TextColor);  /* Draw the current pixel */
+		num += numadd;                            /* Increase the numerator by the top of the fraction */
+		if(num >= den){			/* Check if numerator >= denominator */
+			num -= den;			/* Calculate the new numerator value */
+			x += xinc1;			/* Change the x as appropriate */
+			y += yinc1;			/* Change the y as appropriate */
+		}
+		x += xinc2;				/* Change the x as appropriate */
+		y += yinc2;				/* Change the y as appropriate */
+	}
+}
+
+/*
+ *  RECTANGLE描画
+ *  param1  pDrawProp: Pointer to Draw Prop
+ *  param2  x: left X position
+ *  param3  y: top Y position
+ *  param4  w: width
+ *  param5  h: height
+ */
+void
+lcd_drawRect(LCD_DrawProp_t *pDrawProp, uint16_t Xpos, uint16_t Ypos, uint16_t Width, uint16_t Height)
+{
+	/* Draw horizontal lines */
+	lcd_drawFastHLine(pDrawProp->hlcd, Xpos, Ypos, Width, pDrawProp->TextColor);
+	lcd_drawFastHLine(pDrawProp->hlcd, Xpos, (Ypos+ Height), Width, pDrawProp->TextColor);
+
+	/* Draw vertical lines */
+	lcd_drawFastVLine(pDrawProp->hlcd, Xpos, Ypos, Height, pDrawProp->TextColor);
+	lcd_drawFastVLine(pDrawProp->hlcd, (Xpos + Width), Ypos, Height, pDrawProp->TextColor);
+}
+
+/*
+ *  円描画
+ *  param1  pDrawProp: Pointer to Draw Prop
+ *  param2  x0: X position
+ *  param3  y0: Y position
+ *  param4  Radius: Circle radius
+ */
+void
+lcd_DrawCircle(LCD_DrawProp_t *pDrawProp, uint16_t Xpos, uint16_t Ypos, uint16_t Radius)
+{
+	int32_t  decision;       /* Decision Variable */ 
+	uint32_t  current_x;   /* Current X Value */
+	uint32_t  current_y;   /* Current Y Value */ 
+
+	decision = 3 - (Radius << 1);
+	current_x = 0;
+	current_y = Radius;
+
+	while (current_x <= current_y){
+		lcd_drawPixel(pDrawProp->hlcd, (Xpos + current_x), (Ypos - current_y), pDrawProp->TextColor);
+		lcd_drawPixel(pDrawProp->hlcd, (Xpos - current_x), (Ypos - current_y), pDrawProp->TextColor);
+		lcd_drawPixel(pDrawProp->hlcd, (Xpos + current_y), (Ypos - current_x), pDrawProp->TextColor);
+		lcd_drawPixel(pDrawProp->hlcd, (Xpos - current_y), (Ypos - current_x), pDrawProp->TextColor);
+		lcd_drawPixel(pDrawProp->hlcd, (Xpos + current_x), (Ypos + current_y), pDrawProp->TextColor);
+		lcd_drawPixel(pDrawProp->hlcd, (Xpos - current_x), (Ypos + current_y), pDrawProp->TextColor);
+		lcd_drawPixel(pDrawProp->hlcd, (Xpos + current_y), (Ypos + current_x), pDrawProp->TextColor);
+		lcd_drawPixel(pDrawProp->hlcd, (Xpos - current_y), (Ypos + current_x), pDrawProp->TextColor);
+
+		if(decision < 0){
+			decision += (current_x << 2) + 6;
+		}
+		else{
+			decision += ((current_x - current_y) << 2) + 10;
+			current_y--;
+		}
+		current_x++;
+	}
+}
+
+/*
+ *  PLOY-LINE描画
+ *  param1  pDrawProp: Pointer to Draw Prop
+ *  param2  Points: Pointer to the points array
+ *  param3  PointCount: Number of points
+ */
+void
+lcd_drawPolygon(LCD_DrawProp_t *pDrawProp, pPoint Points, uint16_t PointCount)
+{
+	int16_t x = 0, y = 0;
+
+	if(PointCount < 2)
+		return;
+
+	lcd_drawLine(pDrawProp, Points->X, Points->Y, (Points+PointCount-1)->X, (Points+PointCount-1)->Y);
+
+	while(--PointCount){
+		x = Points->X;
+		y = Points->Y;
+		Points++;
+		lcd_drawLine(pDrawProp, x, y, Points->X, Points->Y);
+	}
+}
+
+/*
+ *  楕円描画
+ *  param1  pDrawProp: Pointer to Draw Prop
+ *  param2  x0: X position
+ *  param3  y0: Y position
+ *  param4  XRadius: Ellipse X radius
+ *  param5  YRadius: Ellipse Y radius
+ */
+void
+lcd_DrawEllipse(LCD_DrawProp_t *pDrawProp, int Xpos, int Ypos, int XRadius, int YRadius)
+{
+	LCD_Handler_t *hlcd = pDrawProp->hlcd;
+	int x = 0, y = -YRadius, err = 2-2*XRadius, e2;
+	float k = 0, rad1 = 0, rad2 = 0;
+
+	rad1 = XRadius;
+	rad2 = YRadius;
+
+	k = (float)(rad2/rad1);
+
+	do{
+		lcd_drawPixel(hlcd, (Xpos-(uint16_t)(x/k)), (Ypos+y), pDrawProp->TextColor);
+		lcd_drawPixel(hlcd, (Xpos+(uint16_t)(x/k)), (Ypos+y), pDrawProp->TextColor);
+		lcd_drawPixel(hlcd, (Xpos+(uint16_t)(x/k)), (Ypos-y), pDrawProp->TextColor);
+		lcd_drawPixel(hlcd, (Xpos-(uint16_t)(x/k)), (Ypos-y), pDrawProp->TextColor);
+
+		e2 = err;
+		if(e2 <= x){
+			err += ++x*2+1;
+			if(-y == x && e2 <= y)
+				e2 = 0;
+		}
+		if(e2 > y)
+			err += ++y*2+1;
+	}while (y <= 0);
+}
+
+/*
+ *  円塗りつぶし描画
+ *  param1  pDrawProp: Pointer to Draw Prop
+ *  param2  x0: X position
+ *  param3  y0: Y position
+ *  param4  Radius: Circle radius
+ */
+void
+lcd_fillCircle(LCD_DrawProp_t *pDrawProp, uint16_t Xpos, uint16_t Ypos, uint16_t Radius)
+{
+	LCD_Handler_t *hlcd = pDrawProp->hlcd;
+	int32_t  decision;        /* Decision Variable */ 
+	uint32_t  current_x;    /* Current X Value */
+	uint32_t  current_y;    /* Current Y Value */ 
+
+	decision = 3 - (Radius << 1);
+	current_x = 0;
+	current_y = Radius;
+
+	while(current_x <= current_y){
+		if(current_y > 0){
+			lcd_drawFastHLine(hlcd, Xpos - current_y, Ypos + current_x, 2*current_y, pDrawProp->TextColor);
+			lcd_drawFastHLine(hlcd, Xpos - current_y, Ypos - current_x, 2*current_y, pDrawProp->TextColor);
+		}
+
+		if(current_x > 0){
+			lcd_drawFastHLine(hlcd, Xpos - current_x, Ypos - current_y, 2*current_x, pDrawProp->TextColor);
+			lcd_drawFastHLine(hlcd, Xpos - current_x, Ypos + current_y, 2*current_x, pDrawProp->TextColor);
+		}
+		if(decision < 0){
+			decision += (current_x << 2) + 6;
+		}
+		else{
+			decision += ((current_x - current_y) << 2) + 10;
+			current_y--;
+		}
+		current_x++;
+	}
+	lcd_DrawCircle(pDrawProp, Xpos, Ypos, Radius);
+}
+
+/*
+ *  楕円塗りつぶし描画
+ *  param1  pDrawProp: Pointer to Draw Prop
+ *  param2  x0: X position
+ *  param3  y0: Y position
+ *  param4  XRadius: Ellipse X radius
+ *  param5  YRadius: Ellipse Y radius
+ */
+void
+lcd_fillEllipse(LCD_DrawProp_t *pDrawProp, int Xpos, int Ypos, int XRadius, int YRadius)
+{
+	LCD_Handler_t *hlcd = pDrawProp->hlcd;
+	int x = 0, y = -YRadius, err = 2-2*XRadius, e2;
+	float k = 0, rad1 = 0, rad2 = 0;
+
+	rad1 = XRadius;
+	rad2 = YRadius;
+	k = (float)(rad2/rad1);
+
+	do{
+		lcd_drawFastHLine(hlcd, (Xpos-(uint16_t)(x/k)), (Ypos+y), (2*(uint16_t)(x/k) + 1), pDrawProp->TextColor);
+		lcd_drawFastHLine(hlcd, (Xpos-(uint16_t)(x/k)), (Ypos-y), (2*(uint16_t)(x/k) + 1), pDrawProp->TextColor);
+
+		e2 = err;
+		if(e2 <= x){
+			err += ++x*2+1;
+			if(-y == x && e2 <= y)
+				e2 = 0;
+		}
+		if(e2 > y)
+			err += ++y*2+1;
+	}
+	while(y <= 0);
+}
+
+/*
+ *  PLOY-LINE塗りつぶし描画
+ *  param1  pDrawProp: Pointer to Draw Prop
+ *  param2  Points: Pointer to the points array
+ *  param3  PointCount: Number of points
+ */
+void
+lcd_fillPolygon(LCD_DrawProp_t *pDrawProp, pPoint Points, uint16_t PointCount)
+{
+	int16_t X = 0, Y = 0, X2 = 0, Y2 = 0, X_center = 0, Y_center = 0, X_first = 0, Y_first = 0, pixelX = 0, pixelY = 0, counter = 0;
+	uint16_t  IMAGE_LEFT = 0, IMAGE_RIGHT = 0, IMAGE_TOP = 0, IMAGE_BOTTOM = 0;  
+
+	IMAGE_LEFT = IMAGE_RIGHT = Points->X;
+	IMAGE_TOP= IMAGE_BOTTOM = Points->Y;
+
+	for(counter = 1; counter < PointCount; counter++){
+		pixelX = POLY_X(counter);
+		if(pixelX < IMAGE_LEFT){
+			IMAGE_LEFT = pixelX;
+		}
+		if(pixelX > IMAGE_RIGHT){
+			IMAGE_RIGHT = pixelX;
+		}
+
+		pixelY = POLY_Y(counter);
+		if(pixelY < IMAGE_TOP){
+			IMAGE_TOP = pixelY;
+		}
+		if(pixelY > IMAGE_BOTTOM){
+			IMAGE_BOTTOM = pixelY;
+		}
+	}
+
+	if(PointCount < 2){
+		return;
+	}
+
+	X_center = (IMAGE_LEFT + IMAGE_RIGHT)/2;
+	Y_center = (IMAGE_BOTTOM + IMAGE_TOP)/2;
+
+	X_first = Points->X;
+	Y_first = Points->Y;
+
+	while(--PointCount){
+		X = Points->X;
+		Y = Points->Y;
+		Points++;
+		X2 = Points->X;
+		Y2 = Points->Y;
+
+		FillTriangle(pDrawProp, X, X2, X_center, Y, Y2, Y_center);
+		FillTriangle(pDrawProp, X, X_center, X2, Y, Y_center, Y2);
+		FillTriangle(pDrawProp, X_center, X2, X, Y_center, Y2, Y);
+	}
+	FillTriangle(pDrawProp, X_first, X2, X_center, Y_first, Y2, Y_center);
+	FillTriangle(pDrawProp, X_first, X_center, X2, Y_first, Y_center, Y2);
+	FillTriangle(pDrawProp, X_center, X2, X_first, Y_center, Y2, Y_first);
+}
+
+/*
+ *  表示オン
+ *  param1  hlcd: Pointer to LCD Handler
+ */
+void
+lcd_displayOn(LCD_Handler_t *hlcd)
+{
+	/* Display ON command */
+	ST7789H2_WriteReg(hlcd, ST7789H2_DISPLAY_ON, (uint8_t*)NULL, 0);
+
+	/* Sleep Out command */
+	ST7789H2_WriteReg(hlcd, ST7789H2_SLEEP_OUT, (uint8_t*)NULL, 0);
+}
+
+/*
+ *  表示オフ
+ *  param1  hlcd: Pointer to LCD Handler
+ */
+void
+lcd_displayOff(LCD_Handler_t *hlcd)
+{
+	uint8_t   parameter[1];
+	parameter[0] = 0xFE;
+	/* Display OFF command */
+	ST7789H2_WriteReg(hlcd, ST7789H2_DISPLAY_OFF, parameter, 1);
+	/* Sleep In Command */
+	ST7789H2_WriteReg(hlcd, ST7789H2_SLEEP_IN, (uint8_t*)NULL, 0);
+	/* Wait for 10ms */
+	dly_tsk(10);
+}
+
+
+/*
+ *  トライアングルフィル
+ *  param1  pDrawProp: Pointer to Draw Prop
+ *  param2  x1: 点1 X座標始点
+ *  param3  y1: 点1 Y座標始点
+ *  param4  x2: 点2 X座標始点
+ *  param5  y2: 点2 Y座標始点
+ *  param6  x3: 点3 X座標始点
+ *  param7  y3: 点3 Y座標始点
+ */
+static void
+FillTriangle(LCD_DrawProp_t *pDrawProp, uint16_t x1, uint16_t x2, uint16_t x3, uint16_t y1, uint16_t y2, uint16_t y3)
+{
+	int16_t deltax = 0, deltay = 0, x = 0, y = 0, xinc1 = 0, xinc2 = 0, 
+	yinc1 = 0, yinc2 = 0, den = 0, num = 0, numadd = 0, numpixels = 0, 
+	curpixel = 0;
+
+	deltax = ABS(x2 - x1);	/* The difference between the x's */
+	deltay = ABS(y2 - y1);	/* The difference between the y's */
+	x = x1;					/* Start x off at the first pixel */
+	y = y1;					/* Start y off at the first pixel */
+
+	if(x2 >= x1){			/* The x-values are increasing */
+		xinc1 = 1;
+		xinc2 = 1;
+	}
+	else{					/* The x-values are decreasing */
+		xinc1 = -1;
+		xinc2 = -1;
+	}
+
+	if(y2 >= y1){			/* The y-values are increasing */
+		yinc1 = 1;
+		yinc2 = 1;
+	}
+	else{					/* The y-values are decreasing */
+		yinc1 = -1;
+		yinc2 = -1;
+	}
+
+	if(deltax >= deltay){	/* There is at least one x-value for every y-value */
+		xinc1 = 0;			/* Don't change the x when numerator >= denominator */
+		yinc2 = 0;			/* Don't change the y for every iteration */
+		den = deltax;
+		num = deltax / 2;
+		numadd = deltay;
+		numpixels = deltax;	/* There are more x-values than y-values */
+	}
+	else{					/* There is at least one y-value for every x-value */
+		xinc2 = 0;			/* Don't change the x for every iteration */
+		yinc1 = 0;			/* Don't change the y when numerator >= denominator */
+		den = deltay;
+		num = deltay / 2;
+		numadd = deltax;
+		numpixels = deltay;	/* There are more y-values than x-values */
+	}
+
+	for(curpixel = 0 ; curpixel <= numpixels ; curpixel++){
+		lcd_drawLine(pDrawProp, x, y, x3, y3);
+		num += numadd;		/* Increase the numerator by the top of the fraction */
+		if(num >= den){		/* Check if numerator >= denominator */
+			num -= den;		/* Calculate the new numerator value */
+			x += xinc1;		/* Change the x as appropriate */
+			y += yinc1;		/* Change the y as appropriate */
+		}
+		x += xinc2;			/* Change the x as appropriate */
+		y += yinc2;			/* Change the y as appropriate */
+	}
+}
+
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/stlcd_st7789h2/stlcd_st7789h2.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/stlcd_st7789h2/stlcd_st7789h2.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/stlcd_st7789h2/stlcd_st7789h2.h	(revision 457)
@@ -0,0 +1,252 @@
+/*
+ *  TOPPERS BASE PLATFORM MIDDLEWARE
+ * 
+ *  Copyright (C) 2017-2018 by TOPPERS PROJECT
+ *                             Educational Working Group.
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+/**
+  ******************************************************************************
+  * @attention
+  *
+  * <h2><center>&copy; COPYRIGHT(c) 2016 STMicroelectronics</center></h2>
+  *
+  * 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 STMicroelectronics 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 _STLCD_ST7789H2_H_
+#define _STLCD_ST7789H2_H_
+
+#ifdef __cplusplus
+ extern "C" {
+#endif 
+
+#include <kernel.h>
+#include <t_syslog.h>
+#include <t_stdlib.h>
+#include <target_syssvc.h>
+#include "device.h"
+#include "ltdc.h"
+
+
+/**
+  * @brief  ST7789H2 ID
+  */
+#define  ST7789H2_ID    0x85
+
+/**
+  * @brief  ST7789H2 Size
+  */
+#define  ST7789H2_LCD_PIXEL_WIDTH    ((uint16_t)240)
+#define  ST7789H2_LCD_PIXEL_HEIGHT   ((uint16_t)240)
+
+/**
+ *  @brief LCD_OrientationTypeDef
+ *  Possible values of Display Orientation
+ */
+#define ST7789H2_ORIENTATION_PORTRAIT         ((uint32_t)0x00) /* Portrait orientation choice of LCD screen  */
+#define ST7789H2_ORIENTATION_LANDSCAPE        ((uint32_t)0x01) /* Landscape orientation choice of LCD screen */
+#define ST7789H2_ORIENTATION_LANDSCAPE_ROT180 ((uint32_t)0x02) /* Landscape rotated 180ｰ orientation choice of LCD screen */
+
+/**
+  * @brief  ST7789H2 Registers
+  */
+#define ST7789H2_LCD_ID             0x04
+#define ST7789H2_SLEEP_IN           0x10
+#define ST7789H2_SLEEP_OUT          0x11
+#define ST7789H2_PARTIAL_DISPLAY    0x12
+#define ST7789H2_DISPLAY_INVERSION  0x21
+#define ST7789H2_DISPLAY_ON         0x29
+#define ST7789H2_WRITE_RAM          0x2C
+#define ST7789H2_READ_RAM           0x2E
+#define ST7789H2_CASET              0x2A
+#define ST7789H2_RASET              0x2B
+#define ST7789H2_VSCRDEF            0x33 /* Vertical Scroll Definition */
+#define ST7789H2_VSCSAD             0x37 /* Vertical Scroll Start Address of RAM */
+#define ST7789H2_TEARING_EFFECT     0x35
+#define ST7789H2_NORMAL_DISPLAY     0x36
+#define ST7789H2_IDLE_MODE_OFF      0x38
+#define ST7789H2_IDLE_MODE_ON       0x39
+#define ST7789H2_COLOR_MODE         0x3A
+#define ST7789H2_PORCH_CTRL         0xB2
+#define ST7789H2_GATE_CTRL          0xB7
+#define ST7789H2_VCOM_SET           0xBB
+#define ST7789H2_DISPLAY_OFF        0xBD
+#define ST7789H2_LCM_CTRL           0xC0
+#define ST7789H2_VDV_VRH_EN         0xC2
+#define ST7789H2_VDV_SET            0xC4
+#define ST7789H2_VCOMH_OFFSET_SET   0xC5
+#define ST7789H2_FR_CTRL            0xC6
+#define ST7789H2_POWER_CTRL         0xD0
+#define ST7789H2_PV_GAMMA_CTRL      0xE0
+#define ST7789H2_NV_GAMMA_CTRL      0xE1
+
+
+/*
+ *  ポリゴンポイント定義
+ */
+typedef struct
+{
+	int16_t X;
+	int16_t Y;
+}Point, *pPoint;
+
+
+#define  LCD_ORIENTATION_PORTRAIT         ((uint8_t)0x00)  /*!< Portrait orientation choice of LCD screen  */
+#define  LCD_ORIENTATION_LANDSCAPE        ((uint8_t)0x01)  /*!< Landscape orientation choice of LCD screen */
+#define  LCD_ORIENTATION_LANDSCAPE_ROT180 ((uint32_t)0x02) /*!< Landscape rotated 180ｰ orientation choice of LCD screen */
+
+
+/**
+  * @brief  LCD color
+  */
+#define LCD_COLOR_BLUE          ((uint16_t)0x001F)
+#define LCD_COLOR_GREEN         ((uint16_t)0x07E0)
+#define LCD_COLOR_RED           ((uint16_t)0xF800)
+#define LCD_COLOR_CYAN          ((uint16_t)0x07FF)
+#define LCD_COLOR_MAGENTA       ((uint16_t)0xF81F)
+#define LCD_COLOR_YELLOW        ((uint16_t)0xFFE0)
+#define LCD_COLOR_LIGHTBLUE     ((uint16_t)0x841F)
+#define LCD_COLOR_LIGHTGREEN    ((uint16_t)0x87F0)
+#define LCD_COLOR_LIGHTRED      ((uint16_t)0xFC10)
+#define LCD_COLOR_LIGHTMAGENTA  ((uint16_t)0xFC1F)
+#define LCD_COLOR_LIGHTYELLOW   ((uint16_t)0xFFF0)
+#define LCD_COLOR_DARKBLUE      ((uint16_t)0x0010)
+#define LCD_COLOR_DARKGREEN     ((uint16_t)0x0400)
+#define LCD_COLOR_DARKRED       ((uint16_t)0x8000)
+#define LCD_COLOR_DARKCYAN      ((uint16_t)0x0410)
+#define LCD_COLOR_DARKMAGENTA   ((uint16_t)0x8010)
+#define LCD_COLOR_DARKYELLOW    ((uint16_t)0x8400)
+#define LCD_COLOR_WHITE         ((uint16_t)0xFFFF)
+#define LCD_COLOR_LIGHTGRAY     ((uint16_t)0xD69A)
+#define LCD_COLOR_GRAY          ((uint16_t)0x8410)
+#define LCD_COLOR_DARKGRAY      ((uint16_t)0x4208)
+#define LCD_COLOR_BLACK         ((uint16_t)0x0000)
+#define LCD_COLOR_BROWN         ((uint16_t)0xA145)
+#define LCD_COLOR_ORANGE        ((uint16_t)0xFD20)
+
+
+/*
+ *  LCDハンドラ構造体定義
+ */
+typedef struct
+{
+	uint32_t                fmc_base;	/* FMCベースアドレス */
+	uint16_t                _width;		/* 幅ピクセル数 */
+	uint16_t				_height;	/* 高さピクセル数 */
+	uint16_t                winXstart;	/* Windows X start */
+	uint16_t                winYstart;	/* Windows Y start */
+	uint16_t                winXend;	/* Windows X end */
+	uint16_t                winYend;	/* Windows Y end */
+
+	uint32_t                rst_clk;	/* RESET CLOCK BIT */
+	uint32_t                te_clk;		/* LCD tearing effect CLOCK BIT */
+	uint32_t                bl_clk;		/* LCD Backlight control CLOCK BIT */
+	uint32_t                rst_base;	/* RESET PORT */
+	uint32_t                te_base;	/* LCD tearing effect PORT */
+	uint32_t                bl_base;	/* LCD Backlight control PORT */
+	uint32_t                gpio_speed;	/* GPIO SPEED */
+	uint32_t                rst_pull;	/* RESET PULL TYPE */
+	uint32_t                bl_pull;	/* LCD Backlight control PULL TYPE */
+	uint8_t                 rst_pin;	/* RESET PIN */
+	uint8_t                 te_pin;		/* LCD tearing effect PIN */
+	uint8_t                 bl_pin;		/* LCD Backlight control PIN */
+	uint8_t                 bl_active;
+}LCD_Handler_t;
+
+/**
+  * @}
+  */
+typedef struct 
+{
+	LCD_Handler_t           *hlcd;
+	uint32_t                TextColor;
+	uint32_t                BackColor;
+	void                    *pFont;
+}LCD_DrawProp_t;
+
+
+extern ER lcd_init(LCD_Handler_t *hlcd, uint32_t orientation);
+extern ER lcd_deinit(LCD_Handler_t *hlcd);
+
+extern ER lcd_layerdefaultinit(LCD_Handler_t *hlcd, LCD_DrawProp_t *pDrawProp, uint16_t LayerIndex, uint32_t FB_Address);
+extern void lcd_setAddrWindow(LCD_Handler_t *hlcd, uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1);
+extern void lcd_clear(LCD_Handler_t *hlcd, uint16_t Color);
+extern uint16_t lcd_readPixel(LCD_Handler_t *hlcd, uint16_t Xpos, uint16_t Ypos);
+extern void lcd_drawPixel(LCD_Handler_t *hlcd, int16_t x, int16_t y, uint16_t color);
+extern void lcd_drawFastHLine(LCD_Handler_t *hlcd, uint16_t Xpos, uint16_t Ypos, uint16_t Length, uint32_t color);
+extern void lcd_drawFastVLine(LCD_Handler_t *hlcd, uint16_t Xpos, uint16_t Ypos, uint16_t Length, uint32_t color);
+extern void lcd_drawBitmap(LCD_Handler_t *hlcd, uint16_t Xpos, uint16_t Ypos, uint8_t *pbmp);
+extern void lcd_drawRGBImage(LCD_Handler_t *hlcd, uint16_t Xpos, uint16_t Ypos, uint16_t Xsize, uint16_t Ysize, uint8_t *pdata);
+extern void lcd_displayOn(LCD_Handler_t *hlcd);
+extern void lcd_displayOff(LCD_Handler_t *hlcd);
+extern void lcd_fillRect(LCD_Handler_t *hlcd, uint16_t Xpos, uint16_t Ypos, uint16_t Width, uint16_t Height, uint32_t color);
+
+extern void lcd_drawLine(LCD_DrawProp_t *pDrawProp, uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2);
+extern void lcd_drawRect(LCD_DrawProp_t *pDrawProp, uint16_t Xpos, uint16_t Ypos, uint16_t Width, uint16_t Height);
+extern void lcd_DrawCircle(LCD_DrawProp_t *pDrawProp, uint16_t Xpos, uint16_t Ypos, uint16_t Radius);
+extern void lcd_drawPolygon(LCD_DrawProp_t *pDrawProp, pPoint Points, uint16_t PointCount);
+extern void lcd_DrawEllipse(LCD_DrawProp_t *pDrawProp, int Xpos, int Ypos, int XRadius, int YRadius);
+extern void lcd_fillCircle(LCD_DrawProp_t *pDrawProp, uint16_t Xpos, uint16_t Ypos, uint16_t Radius);
+extern void lcd_fillEllipse(LCD_DrawProp_t *pDrawProp, int Xpos, int Ypos, int XRadius, int YRadius);
+extern void lcd_fillPolygon(LCD_DrawProp_t *pDrawProp, pPoint Points, uint16_t PointCount);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _STLCD_ST7789H2_H_ */
+
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/stts_ft06x06/Makefile.config
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/stts_ft06x06/Makefile.config	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/stts_ft06x06/Makefile.config	(revision 457)
@@ -0,0 +1,55 @@
+#
+#   TOPPERS/ASP/FMP Kernel
+#       Toyohashi Open Platform for Embedded Real-Time Systems/
+#       Advanced Standard Profile Kernel
+#
+#   Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
+#                               Toyohashi Univ. of Technology, JAPAN
+#   Copyright (C) 2003-2008 by Ryosuke Takeuchi
+#                Platform Development Center RICOH COMPANY,LTD. JAPAN
+#   Copyright (C) 2015-2018 by TOPPERS PROJECT Educational Working Group.
+#
+#   上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+#   によって公表されている GNU General Public License の Version 2 に記
+#   述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+#   を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+#   利用と呼ぶ）することを無償で許諾する．
+#   (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+#       権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+#       スコード中に含まれていること．
+#   (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+#       用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+#       者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+#       の無保証規定を掲載すること．
+#   (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+#       用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+#       と．
+#     (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+#         作権表示，この利用条件および下記の無保証規定を掲載すること．
+#     (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+#         報告すること．
+#   (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+#       害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+#
+#   本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+#   よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+#   含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+#   接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+#
+#  @(#) $Id$
+#
+ 
+#
+#  Makefile のプロセッサ依存 (stts_ft06x06用)
+#
+
+#
+#  コンパイルオプション
+#
+INCLUDES := $(INCLUDES) -I$(SRCDIR)/gdic/stts_ft06x06
+
+#
+#  USB DEVICE(GDIC)に関する定義
+#
+SYSSVC_DIR := $(SYSSVC_DIR):$(SRCDIR)/gdic/stts_ft06x06
+SYSSVC_COBJS := $(SYSSVC_COBJS) stts_ft06x06.o
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/stts_ft06x06/stts_ft06x06.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/stts_ft06x06/stts_ft06x06.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/stts_ft06x06/stts_ft06x06.c	(revision 457)
@@ -0,0 +1,650 @@
+/*
+ *  TOPPERS BASE PLATFORM MIDDLEWARE
+ * 
+ *  Copyright (C) 2017-2018 by TOPPERS PROJECT
+ *                             Educational Working Group.
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+/**
+  ******************************************************************************
+  * @attention
+  *
+  * <h2><center>&copy; COPYRIGHT(c) 2016 STMicroelectronics</center></h2>
+  *
+  * 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 STMicroelectronics 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.
+  *
+  ******************************************************************************
+  */
+
+
+/* Includes ------------------------------------------------------------------*/
+#include <kernel.h>
+#include <t_syslog.h>
+#include <t_stdlib.h>
+#include <sil.h>
+#include <target_syssvc.h>
+#include "device.h"
+#include "i2c.h"
+#include "stts_ft06x06.h"
+
+#define sil_orw_mem(a, b)		sil_wrw_mem((a), sil_rew_mem(a) | (b))
+
+/**
+  * @brief TouchScreen FT6206 Slave I2C address
+  */
+#define TS_I2C_ADDRESS                   ((uint16_t)0x70)
+
+
+/* Table for touchscreen event information display on LCD : table indexed on enum @ref TS_TouchEventTypeDef information */
+char * ts_event_string_tab[TOUCH_EVENT_NB_MAX] = { "None",
+                                                   "Press down",
+                                                   "Lift up",
+                                                   "Contact"
+                                                  };
+
+/* Table for touchscreen gesture Id information display on LCD : table indexed on enum @ref TS_GestureIdTypeDef information */
+char * ts_gesture_id_string_tab[GEST_ID_NB_MAX] = { "None",
+                                                    "Move Up",
+                                                    "Move Right",
+                                                    "Move Down",
+                                                    "Move Left",
+                                                    "Zoom In",
+                                                    "Zoom Out"
+                                                  };
+
+
+
+
+/* Private functions prototypes-----------------------------------------------*/
+/**
+  * @}
+  */
+
+/** @defgroup ft6x06_Private_Functions ft6x06 Private Functions
+  * @{
+  */
+
+/**
+  * @brief  Read the ft6x06 device ID, pre initialize I2C in case of need to be
+  *         able to read the FT6206 device ID, and verify this is a FT6206.
+  * @param  DeviceAddr: I2C FT6x06 Slave address.
+  * @retval The Device ID (two bytes).
+  */
+static ER
+ft6x06_ReadID(TouchScreen_Handle_t *hts, uint8_t *ts_id)
+{
+	uint8_t read_value = 0;
+	ER ercd = E_OK;
+
+	ercd = i2c_memread(hts->hi2c, hts->I2C_Address, (uint16_t)FT6206_CHIP_ID_REG, I2C_MEMADD_SIZE_8BIT, (uint8_t*)&read_value, 1, 1000);
+	*ts_id = read_value;
+	return ercd;
+}
+
+/**
+  * @brief  Return if there is touches detected or not.
+  *         Try to detect new touches and forget the old ones (reset internal global
+  *         variables).
+  * @param  DeviceAddr: Device address on communication Bus.
+  * @retval : Number of active touches detected (can be 0, 1 or 2).
+  */
+static ER_UINT
+ft6x06_TS_DetectTouch(TouchScreen_Handle_t *hts)
+{
+	ER ercd = E_OK;
+	volatile uint8_t nbTouch = 0;
+
+	/* Read register FT6206_TD_STAT_REG to check number of touches detection */
+	ercd = i2c_memread(hts->hi2c, hts->I2C_Address, (uint16_t)FT6206_TD_STAT_REG, I2C_MEMADD_SIZE_8BIT, (uint8_t*)&nbTouch, 1, 1000);
+	/* Check the communication status */
+	if(ercd != E_OK)
+		return ercd;
+
+	nbTouch &= FT6206_TD_STAT_MASK;
+
+	if(nbTouch > FT6206_MAX_DETECTABLE_TOUCH){
+		/* If invalid number of touch detected, set it to zero */
+		nbTouch = 0;
+	}
+
+	/* Update ft6x06 driver internal global : current number of active touches */
+	hts->currActiveTouchNb = nbTouch;
+
+	/* Reset current active touch index on which to work on */
+	hts->currActiveTouchIdx = 0;
+	return nbTouch;
+}
+
+/**
+  * @brief  Get the touch screen X and Y positions values
+  *         Manage multi touch thanks to touch Index global
+  *         variable 'ft6x06_handle.currActiveTouchIdx'.
+  * @param  DeviceAddr: Device address on communication Bus.
+  * @param  X: Pointer to X position value
+  * @param  Y: Pointer to Y position value
+  * @retval None.
+  */
+static ER
+ft6x06_TS_GetXY(TouchScreen_Handle_t *hts, uint16_t *X, uint16_t *Y)
+{
+	uint8_t regAddress = 0;
+	uint8_t  dataxy[4];
+	ER ercd = E_OK;
+
+	if(hts->currActiveTouchIdx < hts->currActiveTouchNb){
+		switch(hts->currActiveTouchIdx){
+		case 0 :
+			regAddress = FT6206_P1_XH_REG;
+			break;
+		case 1 :
+			regAddress = FT6206_P2_XH_REG; 
+			break;
+
+		default :
+			break;
+ 		}
+
+		/* Read X and Y positions */
+		ercd = i2c_memread(hts->hi2c, hts->I2C_Address, (uint16_t)regAddress, I2C_MEMADD_SIZE_8BIT, dataxy, sizeof(dataxy), 1000);
+		if(ercd != E_OK)
+			return ercd;
+		/* Send back ready X position to caller */
+		*X = ((dataxy[0] & FT6206_MSB_MASK) << 8) | (dataxy[1] & FT6206_LSB_MASK);
+
+		/* Send back ready Y position to caller */
+		*Y = ((dataxy[2] & FT6206_MSB_MASK) << 8) | (dataxy[3] & FT6206_LSB_MASK);
+		hts->currActiveTouchIdx++;
+	}
+	return ercd;
+}
+
+/**** NEW FEATURES enabled when Multi-touch support is enabled ****/
+
+#if (TS_MULTI_TOUCH_SUPPORTED == 1)
+/**
+  * @brief  Get the touch detailed informations on touch number 'touchIdx' (0..1)
+  *         This touch detailed information contains :
+  *         - weight that was applied to this touch
+  *         - sub-area of the touch in the touch panel
+  *         - event of linked to the touch (press down, lift up, ...)
+  * @param  DeviceAddr: Device address on communication Bus (I2C slave address of FT6x06).
+  * @param  touchIdx : Passed index of the touch (0..1) on which we want to get the
+  *                    detailed information.
+  * @param  pWeight : Pointer to to get the weight information of 'touchIdx'.
+  * @param  pArea   : Pointer to to get the sub-area information of 'touchIdx'.
+  * @param  pEvent  : Pointer to to get the event information of 'touchIdx'.
+
+  * @retval None.
+  */
+static ER
+ft6x06_TS_GetTouchInfo(TouchScreen_Handle_t *hts,
+                            uint32_t   touchIdx,
+                            uint32_t * pWeight,
+                            uint32_t * pArea,
+                            uint32_t * pEvent)
+{
+	uint8_t regAddress = 0;
+	uint8_t dataxy[3];
+	ER ercd = E_OK;
+
+	if(touchIdx < hts->currActiveTouchNb){
+		switch(touchIdx){
+		case 0 :
+			regAddress = FT6206_P1_WEIGHT_REG;
+			break;
+		case 1 :
+			regAddress = FT6206_P2_WEIGHT_REG;
+			break;
+		default :
+			break;
+		} /* end switch(touchIdx) */
+
+		/* Read weight, area and Event Id of touch index */
+		ercd = i2c_memread(hts->hi2c, hts->I2C_Address, (uint16_t)regAddress, I2C_MEMADD_SIZE_8BIT, dataxy, sizeof(dataxy), 1000);
+
+		/* Return weight of touch index */
+		*pWeight = (dataxy[0] & FT6206_TOUCH_WEIGHT_MASK) >> FT6206_TOUCH_WEIGHT_SHIFT;
+		/* Return area of touch index */
+		*pArea = (dataxy[1] & FT6206_TOUCH_AREA_MASK) >> FT6206_TOUCH_AREA_SHIFT;
+		/* Return Event Id  of touch index */
+		*pEvent = (dataxy[2] & FT6206_TOUCH_EVT_FLAG_MASK) >> FT6206_TOUCH_EVT_FLAG_SHIFT;
+	} /* of if(touchIdx < ft6x06_handle.currActiveTouchNb) */
+	return ercd;
+}
+
+#endif /* TS_MULTI_TOUCH_SUPPORTED == 1 */
+
+#if (TS_AUTO_CALIBRATION_SUPPORTED == 1)
+/**
+  * @brief  Start TouchScreen calibration phase
+  * @param  DeviceAddr: FT6206 Device address for communication on I2C Bus.
+  * @retval Status FT6206_STATUS_OK or FT6206_STATUS_NOT_OK.
+  */
+static ER
+ft6x06_TS_Calibration(TouchScreen_Handle_t *hts)
+{
+	uint32_t nbAttempt = 0;
+	volatile uint8_t ucReadData;
+	volatile uint8_t regValue;
+	uint8_t bEndCalibration = 0;
+	ER ercd = E_OK;
+
+	/* >> Calibration sequence start */
+
+	/* Switch FT6206 back to factory mode to calibrate */
+	regValue = (FT6206_DEV_MODE_FACTORY & FT6206_DEV_MODE_MASK) << FT6206_DEV_MODE_SHIFT;
+	ercd = i2c_memwrite(hts->hi2c, hts->I2C_Address, (uint16_t)FT6206_DEV_MODE_REG, I2C_MEMADD_SIZE_8BIT, (uint8_t*)&regValue, 1, 1000);
+	if(ercd != E_OK)
+		return ercd;
+
+	/* Read back the same register FT6206_DEV_MODE_REG */
+	ercd = i2c_memread(hts->hi2c, hts->I2C_Address, (uint16_t)FT6206_GEST_ID_REG, I2C_MEMADD_SIZE_8BIT, (uint8_t*)&ucReadData, 1, 1000);
+	if(ercd != E_OK)
+		return ercd;
+
+	dly_tsk(300);	/* Wait 300 ms */
+
+	if(((ucReadData & (FT6206_DEV_MODE_MASK << FT6206_DEV_MODE_SHIFT)) >> FT6206_DEV_MODE_SHIFT) != FT6206_DEV_MODE_FACTORY ){
+		/* Return error to caller */
+		return E_OBJ;
+	}
+
+	/* Start calibration command */
+	regValue = 0x04;
+	ercd = i2c_memwrite(hts->hi2c, hts->I2C_Address, (uint16_t)FT6206_TD_STAT_REG, I2C_MEMADD_SIZE_8BIT, (uint8_t*)&regValue, 1, 1000);
+	if(ercd != E_OK)
+		return ercd;
+
+	dly_tsk(300);	/* Wait 300 ms */
+
+	/* 100 attempts to wait switch from factory mode (calibration) to working mode */
+	for (nbAttempt=0; ((nbAttempt < 100) && (!bEndCalibration)) ; nbAttempt++){
+		ercd = i2c_memread(hts->hi2c, hts->I2C_Address, (uint16_t)FT6206_DEV_MODE_REG, I2C_MEMADD_SIZE_8BIT, (uint8_t*)&ucReadData, 1, 1000);
+		if(ercd != E_OK)
+			return ercd;
+
+		ucReadData = (ucReadData & (FT6206_DEV_MODE_MASK << FT6206_DEV_MODE_SHIFT)) >> FT6206_DEV_MODE_SHIFT;
+		if(ucReadData == FT6206_DEV_MODE_WORKING){
+			/* Auto Switch to FT6206_DEV_MODE_WORKING : means calibration have ended */
+			bEndCalibration = 1; /* exit for loop */
+		}
+		dly_tsk(200);	/* Wait 200 ms */
+	}
+
+	/* Calibration sequence end << */
+	return ercd;
+}
+#endif /* TS_AUTO_CALIBRATION_SUPPORTED == 1 */
+
+/**
+  * @brief  Initializes and configures the touch screen functionalities and
+  *         configures all necessary hardware resources (GPIOs, I2C, clocks..)
+  *         with a given orientation
+  * @param  ts_SizeX : Maximum X size of the TS area on LCD
+  * @param  ts_SizeY : Maximum Y size of the TS area on LCD
+  * @param  orientation : TS_ORIENTATION_LANDSCAPE or TS_ORIENTATION_PORTRAIT
+  * @retval TS_OK if all initializations are OK. Other value if error.
+  */
+ER
+touchscreen_init(TouchScreen_Handle_t *hts, uint16_t ts_SizeX, uint16_t ts_SizeY, uint8_t orientation)
+{
+	GPIO_Init_t GPIO_Init_Data;
+	ER ercd = E_OK;
+	uint8_t ts_id = 0;
+
+	/* Note : I2C_Address is un-initialized here, but is not used at all in init function */
+	/* but the prototype of Init() is like that in template and should be respected       */
+
+	/* Initialize the communication channel to sensor (I2C) if necessary */
+	/* that is initialization is done only once after a power up         */
+	hts->tsOrientation = TS_SWAP_NONE;
+	if(hts->I2C_Address == 0)
+		hts->I2C_Address   = TS_I2C_ADDRESS;
+	hts->initialized   = false;
+	if(hts->pcb->reset_gpio_base){
+		sil_orw_mem((uint32_t *)(hts->pcb->reset_clk_base), hts->pcb->reset_clk_bit);
+		GPIO_Init_Data.mode  = hts->pcb->reset_gpio_mode;
+		GPIO_Init_Data.otype = hts->pcb->reset_gpio_otype;
+		GPIO_Init_Data.pull  = hts->pcb->reset_gpio_pull;
+		GPIO_Init_Data.speed = hts->pcb->reset_gpio_speed;
+		gpio_setup(hts->pcb->reset_gpio_base, &GPIO_Init_Data, hts->pcb->reset_gpio_pinno);
+		if(hts->pcb->reset_gpio_release == 0)
+			sil_wrw_mem((uint32_t *)(hts->pcb->reset_gpio_base+TOFF_GPIO_BSRR), (1<<hts->pcb->reset_gpio_pinno)<<16);
+		else
+			sil_wrw_mem((uint32_t *)(hts->pcb->reset_gpio_base+TOFF_GPIO_BSRR), (1<<hts->pcb->reset_gpio_pinno));
+	}
+
+	/* Scan FT6x36 TouchScreen IC controller ID register by I2C Read */
+	/* Verify this is a FT6x36, otherwise this is an error case      */
+	ercd = ft6x06_ReadID(hts, &ts_id);
+	if(ercd != E_OK)
+		return ercd;
+	if(ts_id == FT6x36_ID_VALUE){
+		/* Found FT6x36 : Initialize the TS driver structure */
+		/* Get LCD chosen orientation */
+		if(orientation == TS_ORIENTATION_PORTRAIT){
+			hts->tsOrientation = TS_SWAP_X | TS_SWAP_Y;               
+		}
+		else if(orientation == TS_ORIENTATION_LANDSCAPE_ROT180){
+			hts->tsOrientation = TS_SWAP_XY;
+		}
+		else{
+			hts->tsOrientation = TS_SWAP_XY | TS_SWAP_Y;                 
+		}
+		hts->max_width  = FT_6206_MAX_WIDTH_HEIGHT;
+		hts->max_height = FT_6206_MAX_WIDTH_HEIGHT;
+	}
+	/* Scan FT6xx6 TouchScreen IC controller ID register by I2C Read       */
+	/* Verify this is a FT6206 or FT6336G, otherwise this is an error case */
+	else if(ts_id == FT6206_ID_VALUE){
+		/* Found FT6206 : Initialize the TS driver structure */
+		/* Get LCD chosen orientation */
+		if(ts_SizeX < ts_SizeY){
+			hts->tsOrientation = TS_SWAP_NONE;
+		}
+		else{
+			hts->tsOrientation = TS_SWAP_XY | TS_SWAP_Y;
+		}
+		hts->max_width  = FT_6206_MAX_WIDTH;
+		hts->max_height = FT_6206_MAX_HEIGHT;
+	}
+
+	if(ercd == E_OK){
+		/* Software reset the TouchScreen */
+		/* Calibrate, Configure and Start the TouchScreen driver */
+#if (TS_AUTO_CALIBRATION_SUPPORTED == 1)
+		/* Hw Calibration sequence start : should be done once after each power up */
+		/* This is called internal calibration of the touch screen                 */
+		ft6x06_TS_Calibration(hts);
+#endif
+
+		/* By default set FT6206 IC in Polling mode : no INT generation on FT6206 for new touch available */
+		/* Note TS_INT is active low                                                                      */
+		ercd = touchscreen_disable_it(hts);
+			/* Configure Interrupt mode for TS_INT pin falling edge : when a new touch is available */
+			/* TS_INT pin is active on low level on new touch available */
+		if(ercd == E_OK && hts->pcb->int_gpio_base != 0){
+			exti_func[hts->pcb->int_gpio_pinno] = hts->ifunc;
+			sil_orw_mem((uint32_t *)hts->pcb->int_clk_base, hts->pcb->int_clk_bit);
+			GPIO_Init_Data.mode      = hts->pcb->int_gpio_mode;
+			GPIO_Init_Data.pull      = hts->pcb->int_gpio_pull;
+			GPIO_Init_Data.speed     = hts->pcb->int_gpio_speed;
+			gpio_setup(hts->pcb->int_gpio_base, &GPIO_Init_Data, hts->pcb->int_gpio_pinno);
+			if(hts->enable_it)
+				ercd = touchscreen_enable_it(hts);
+		}
+		if(ercd == E_OK)
+			hts->initialized = true;
+	}
+	return (ercd);
+}
+
+/**
+  * @brief  Returns status and positions of the touch screen.
+  * @param  TS_State: Pointer to touch screen current state structure
+  * @retval TS_OK if all initializations are OK. Other value if error.
+  */
+ER
+touchscreen_getstate(TouchScreen_Handle_t *hts, TS_StateTypeDef *TS_State)
+{
+	static uint32_t _x[TS_MAX_NB_TOUCH] = {0, 0};
+	static uint32_t _y[TS_MAX_NB_TOUCH] = {0, 0};
+	uint16_t tmp;
+	uint16_t Raw_x[TS_MAX_NB_TOUCH];
+	uint16_t Raw_y[TS_MAX_NB_TOUCH];
+	uint16_t xDiff;
+	uint16_t yDiff;
+	uint32_t index;
+#if (TS_MULTI_TOUCH_SUPPORTED == 1)
+	uint32_t weight = 0;
+	uint32_t area = 0;
+	uint32_t event = 0;
+#endif /* TS_MULTI_TOUCH_SUPPORTED == 1 */
+	ER ercd = E_OK;
+
+	/* Check and update the number of touches active detected */
+	ercd = ft6x06_TS_DetectTouch(hts);
+	if(ercd < 0)
+		return ercd;
+	if((TS_State->touchDetected = (uint8_t)ercd)){
+		for(index=0; index < TS_State->touchDetected; index++){
+			/* Get each touch coordinates */
+			ft6x06_TS_GetXY(hts, &(Raw_x[index]), &(Raw_y[index]));
+
+			if(hts->tsOrientation & TS_SWAP_XY){
+				tmp = Raw_x[index];
+				Raw_x[index] = Raw_y[index];
+				Raw_y[index] = tmp;
+			}
+			if(hts->tsOrientation & TS_SWAP_X){
+				Raw_x[index] = hts->max_width - 1 - Raw_x[index];
+			}
+			if(hts->tsOrientation & TS_SWAP_Y){
+				Raw_y[index] = hts->max_height - 1 - Raw_y[index];
+			}
+
+			xDiff = Raw_x[index] > _x[index]? (Raw_x[index] - _x[index]): (_x[index] - Raw_x[index]);
+			yDiff = Raw_y[index] > _y[index]? (Raw_y[index] - _y[index]): (_y[index] - Raw_y[index]);
+
+			if((xDiff + yDiff) > 5){
+				_x[index] = Raw_x[index];
+				_y[index] = Raw_y[index];
+			}
+
+			TS_State->touchX[index] = _x[index];
+			TS_State->touchY[index] = _y[index];
+
+#if (TS_MULTI_TOUCH_SUPPORTED == 1)
+
+			/* Get touch info related to the current touch */
+			ercd = ft6x06_TS_GetTouchInfo(hts, index, &weight, &area, &event);
+
+			/* Update TS_State structure */
+			TS_State->touchWeight[index] = weight;
+			TS_State->touchArea[index]   = area;
+
+			/* Remap touch event */
+			switch(event){
+			case FT6206_TOUCH_EVT_FLAG_PRESS_DOWN  :
+				TS_State->touchEventId[index] = TOUCH_EVENT_PRESS_DOWN;
+				break;
+			case FT6206_TOUCH_EVT_FLAG_LIFT_UP :
+				TS_State->touchEventId[index] = TOUCH_EVENT_LIFT_UP;
+				break;
+			case FT6206_TOUCH_EVT_FLAG_CONTACT :
+				TS_State->touchEventId[index] = TOUCH_EVENT_CONTACT;
+				break;
+			case FT6206_TOUCH_EVT_FLAG_NO_EVENT :
+				TS_State->touchEventId[index] = TOUCH_EVENT_NO_EVT;
+				break;
+			 default :
+				ercd = E_SYS;
+				break;
+			} /* of switch(event) */
+			if(ercd < 0)
+				return ercd;
+
+#endif /* TS_MULTI_TOUCH_SUPPORTED == 1 */
+
+		} /* of for(index=0; index < TS_State->touchDetected; index++) */
+
+#if (TS_MULTI_TOUCH_SUPPORTED == 1)
+		/* Get gesture Id */
+		ercd = touchscreen_get_gestureid(hts, TS_State);
+#endif /* TS_MULTI_TOUCH_SUPPORTED == 1 */
+
+	} /* end of if(TS_State->touchDetected != 0) */
+	return ercd;
+}
+
+/**
+  * @brief  Configure the FT6206 device to generate IT on given INT pin
+  *         connected to MCU as EXTI.
+  * @param  DeviceAddr: Device address on communication Bus (Slave I2C address of FT6206).
+  * @retval None
+  */
+ER
+touchscreen_enable_it(TouchScreen_Handle_t *hts)
+{
+	ER ercd;
+	uint8_t regValue = 0;
+	regValue = (FT6206_G_MODE_INTERRUPT_TRIGGER & (FT6206_G_MODE_INTERRUPT_MASK >> FT6206_G_MODE_INTERRUPT_SHIFT)) << FT6206_G_MODE_INTERRUPT_SHIFT;
+
+	/* Set interrupt trigger mode in FT6206_GMODE_REG */
+	ercd = i2c_memwrite(hts->hi2c, hts->I2C_Address, (uint16_t)FT6206_GMODE_REG, I2C_MEMADD_SIZE_8BIT, (uint8_t*)&regValue, 1, 1000);
+	return ercd;
+}
+
+/**
+  * @brief  Configure the FT6206 device to stop generating IT on the given INT pin
+  *         connected to MCU as EXTI.
+  * @param  DeviceAddr: Device address on communication Bus (Slave I2C address of FT6206).
+  * @retval None
+  */
+ER touchscreen_disable_it(TouchScreen_Handle_t *hts)
+{
+	ER  ercd;
+	uint8_t regValue = 0;
+	regValue = (FT6206_G_MODE_INTERRUPT_POLLING | (FT6206_G_MODE_INTERRUPT_MASK >> FT6206_G_MODE_INTERRUPT_SHIFT)) << FT6206_G_MODE_INTERRUPT_SHIFT;
+
+	/* Set interrupt polling mode in FT6206_GMODE_REG */
+	ercd = i2c_memwrite(hts->hi2c, hts->I2C_Address, (uint16_t)FT6206_GMODE_REG, I2C_MEMADD_SIZE_8BIT, (uint8_t*)&regValue, 1, 1000);
+	return ercd;
+}
+
+#if (TS_MULTI_TOUCH_SUPPORTED == 1)
+/**
+  * @brief  Update gesture Id following a touch detected.
+  * @param  TS_State: Pointer to touch screen current state structure
+  * @retval TS_OK if all initializations are OK. Other value if error.
+  */
+ER
+touchscreen_get_gestureid(TouchScreen_Handle_t *hts, TS_StateTypeDef *TS_State)
+{
+	uint32_t gestureId = 0;
+	volatile uint8_t ucReadData = 0;
+	ER ercd = E_OK;
+
+	/* Get gesture Id */
+	ercd = i2c_memread(hts->hi2c, hts->I2C_Address, (uint16_t)FT6206_GEST_ID_REG, I2C_MEMADD_SIZE_8BIT, (uint8_t*)&ucReadData, 1, 1000);
+	if(ercd != E_OK)
+		return ercd;
+
+	gestureId = hts->I2C_Address;
+
+	/* Remap gesture Id to a TS_GestureIdTypeDef value */
+	switch(gestureId){
+	case FT6206_GEST_ID_NO_GESTURE :
+		TS_State->gestureId = GEST_ID_NO_GESTURE;
+		break;
+	case FT6206_GEST_ID_MOVE_UP :
+		TS_State->gestureId = GEST_ID_MOVE_UP;
+		break;
+	case FT6206_GEST_ID_MOVE_RIGHT :
+		TS_State->gestureId = GEST_ID_MOVE_RIGHT;
+		break;
+	case FT6206_GEST_ID_MOVE_DOWN :
+		TS_State->gestureId = GEST_ID_MOVE_DOWN;
+		break;
+	case FT6206_GEST_ID_MOVE_LEFT :
+		TS_State->gestureId = GEST_ID_MOVE_LEFT;
+		break;
+	case FT6206_GEST_ID_ZOOM_IN :
+		TS_State->gestureId = GEST_ID_ZOOM_IN;
+		break;
+	case FT6206_GEST_ID_ZOOM_OUT :
+		TS_State->gestureId = GEST_ID_ZOOM_OUT;
+		break;
+	default :
+		ercd = E_OBJ;
+		break;
+	} /* of switch(gestureId) */
+	return ercd;
+}
+#endif /* TS_MULTI_TOUCH_SUPPORTED == 1 */
+
+
+/** @defgroup STM32F723E-DISCOVERY_TS_Private_Functions TS Private Functions
+  * @{
+  */
+
+#if (TS_MULTI_TOUCH_SUPPORTED == 1)
+/**
+  * @brief  Function used to reset all touch data before a new acquisition
+  *         of touch information.
+  * @param  TS_State: Pointer to touch screen current state structure
+  * @retval TS_OK if OK, TE_ERROR if problem found.
+  */
+ER
+touchscreen_reset_data(TS_StateTypeDef *TS_State)
+{
+	uint32_t index;
+
+	if(TS_State != (TS_StateTypeDef *)NULL){
+		TS_State->gestureId = GEST_ID_NO_GESTURE;
+		TS_State->touchDetected = 0;
+
+		for(index = 0; index < TS_MAX_NB_TOUCH; index++){
+			TS_State->touchX[index]       = 0;
+			TS_State->touchY[index]       = 0;
+			TS_State->touchArea[index]    = 0;
+			TS_State->touchEventId[index] = TOUCH_EVENT_NO_EVT;
+			TS_State->touchWeight[index]  = 0;
+		}
+		return E_OK;
+	}
+	else
+		return E_PAR;
+}
+#endif /* TS_MULTI_TOUCH_SUPPORTED == 1 */
+
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/stts_ft06x06/stts_ft06x06.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/stts_ft06x06/stts_ft06x06.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/stts_ft06x06/stts_ft06x06.h	(revision 457)
@@ -0,0 +1,400 @@
+/*
+ *  TOPPERS BASE PLATFORM MIDDLEWARE
+ * 
+ *  Copyright (C) 2017-2018 by TOPPERS PROJECT
+ *                             Educational Working Group.
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+/**
+  ******************************************************************************
+  * @attention
+  *
+  * <h2><center>&copy; COPYRIGHT(c) 2016 STMicroelectronics</center></h2>
+  *
+  * 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 STMicroelectronics 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 _STTS_FT06X06_H_
+#define _STTS_FT06X06_H_
+
+#include <kernel.h>
+#include <t_syslog.h>
+#include <t_stdlib.h>
+#include "device.h"
+#include "i2c.h"
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* Set Multi-touch as non supported */
+#ifndef TS_MULTI_TOUCH_SUPPORTED
+  #define TS_MULTI_TOUCH_SUPPORTED 0
+#endif
+
+/* Set Auto-calibration as non supported */
+#ifndef TS_AUTO_CALIBRATION_SUPPORTED
+  #define TS_AUTO_CALIBRATION_SUPPORTED 0
+#endif
+
+  /* Maximum border values of the touchscreen pad */
+#define  FT_6206_MAX_WIDTH              ((uint16_t)800)     /* Touchscreen pad max width   */
+#define  FT_6206_MAX_HEIGHT             ((uint16_t)480)     /* Touchscreen pad max height  */
+
+  /* Touchscreen pad max width and height values for FT6x36 Touch*/
+#define  FT_6206_MAX_WIDTH_HEIGHT       ((uint16_t)240)     
+
+  /* Max detectable simultaneous touches */
+#define FT6206_MAX_DETECTABLE_TOUCH     2
+
+  /**
+   * @brief : Definitions for FT6206 I2C register addresses on 8 bit
+   **/
+
+  /* Current mode register of the FT6206 (R/W) */
+#define FT6206_DEV_MODE_REG             0x00
+
+  /* Possible values of FT6206_DEV_MODE_REG */
+#define FT6206_DEV_MODE_WORKING         0x00
+#define FT6206_DEV_MODE_FACTORY         0x04
+
+#define FT6206_DEV_MODE_MASK            0x7
+#define FT6206_DEV_MODE_SHIFT           4
+
+  /* Gesture ID register */
+#define FT6206_GEST_ID_REG              0x01
+
+  /* Possible values of FT6206_GEST_ID_REG */
+#define FT6206_GEST_ID_NO_GESTURE       0x00
+#define FT6206_GEST_ID_MOVE_UP          0x10
+#define FT6206_GEST_ID_MOVE_RIGHT       0x14
+#define FT6206_GEST_ID_MOVE_DOWN        0x18
+#define FT6206_GEST_ID_MOVE_LEFT        0x1C
+#define FT6206_GEST_ID_ZOOM_IN          0x48
+#define FT6206_GEST_ID_ZOOM_OUT         0x49
+
+  /* Touch Data Status register : gives number of active touch points (0..2) */
+#define FT6206_TD_STAT_REG              0x02
+
+  /* Values related to FT6206_TD_STAT_REG */
+#define FT6206_TD_STAT_MASK             0x0F
+#define FT6206_TD_STAT_SHIFT            0x00
+
+  /* Values Pn_XH and Pn_YH related */
+#define FT6206_TOUCH_EVT_FLAG_PRESS_DOWN 0x00
+#define FT6206_TOUCH_EVT_FLAG_LIFT_UP    0x01
+#define FT6206_TOUCH_EVT_FLAG_CONTACT    0x02
+#define FT6206_TOUCH_EVT_FLAG_NO_EVENT   0x03
+
+#define FT6206_TOUCH_EVT_FLAG_SHIFT     6
+#define FT6206_TOUCH_EVT_FLAG_MASK      (3 << FT6206_TOUCH_EVT_FLAG_SHIFT)
+
+#define FT6206_MSB_MASK                 0x0F
+#define FT6206_MSB_SHIFT                0
+
+  /* Values Pn_XL and Pn_YL related */
+#define FT6206_LSB_MASK                 0xFF
+#define FT6206_LSB_SHIFT                0
+
+#define FT6206_P1_XH_REG                0x03
+#define FT6206_P1_XL_REG                0x04
+#define FT6206_P1_YH_REG                0x05
+#define FT6206_P1_YL_REG                0x06
+
+  /* Touch Pressure register value (R) */
+#define FT6206_P1_WEIGHT_REG            0x07
+
+  /* Values Pn_WEIGHT related  */
+#define FT6206_TOUCH_WEIGHT_MASK        0xFF
+#define FT6206_TOUCH_WEIGHT_SHIFT       0
+
+  /* Touch area register */
+#define FT6206_P1_MISC_REG              0x08
+
+  /* Values related to FT6206_Pn_MISC_REG */
+#define FT6206_TOUCH_AREA_MASK         (0x04 << 4)
+#define FT6206_TOUCH_AREA_SHIFT        0x04
+
+#define FT6206_P2_XH_REG               0x09
+#define FT6206_P2_XL_REG               0x0A
+#define FT6206_P2_YH_REG               0x0B
+#define FT6206_P2_YL_REG               0x0C
+#define FT6206_P2_WEIGHT_REG           0x0D
+#define FT6206_P2_MISC_REG             0x0E
+
+  /* Threshold for touch detection */
+#define FT6206_TH_GROUP_REG            0x80
+
+  /* Values FT6206_TH_GROUP_REG : threshold related  */
+#define FT6206_THRESHOLD_MASK          0xFF
+#define FT6206_THRESHOLD_SHIFT         0
+
+  /* Filter function coefficients */
+#define FT6206_TH_DIFF_REG             0x85
+
+  /* Control register */
+#define FT6206_CTRL_REG                0x86
+
+  /* Values related to FT6206_CTRL_REG */
+
+  /* Will keep the Active mode when there is no touching */
+#define FT6206_CTRL_KEEP_ACTIVE_MODE    0x00
+
+  /* Switching from Active mode to Monitor mode automatically when there is no touching */
+#define FT6206_CTRL_KEEP_AUTO_SWITCH_MONITOR_MODE  0x01
+
+  /* The time period of switching from Active mode to Monitor mode when there is no touching */
+#define FT6206_TIMEENTERMONITOR_REG     0x87
+
+  /* Report rate in Active mode */
+#define FT6206_PERIODACTIVE_REG         0x88
+
+  /* Report rate in Monitor mode */
+#define FT6206_PERIODMONITOR_REG        0x89
+
+  /* The value of the minimum allowed angle while Rotating gesture mode */
+#define FT6206_RADIAN_VALUE_REG         0x91
+
+  /* Maximum offset while Moving Left and Moving Right gesture */
+#define FT6206_OFFSET_LEFT_RIGHT_REG    0x92
+
+  /* Maximum offset while Moving Up and Moving Down gesture */
+#define FT6206_OFFSET_UP_DOWN_REG       0x93
+
+  /* Minimum distance while Moving Left and Moving Right gesture */
+#define FT6206_DISTANCE_LEFT_RIGHT_REG  0x94
+
+  /* Minimum distance while Moving Up and Moving Down gesture */
+#define FT6206_DISTANCE_UP_DOWN_REG     0x95
+
+  /* Maximum distance while Zoom In and Zoom Out gesture */
+#define FT6206_DISTANCE_ZOOM_REG        0x96
+
+  /* High 8-bit of LIB Version info */
+#define FT6206_LIB_VER_H_REG            0xA1
+
+  /* Low 8-bit of LIB Version info */
+#define FT6206_LIB_VER_L_REG            0xA2
+
+  /* Chip Selecting */
+#define FT6206_CIPHER_REG               0xA3
+
+  /* Interrupt mode register (used when in interrupt mode) */
+#define FT6206_GMODE_REG                0xA4
+
+#define FT6206_G_MODE_INTERRUPT_MASK    0x03
+#define FT6206_G_MODE_INTERRUPT_SHIFT   0x00
+
+  /* Possible values of FT6206_GMODE_REG */
+#define FT6206_G_MODE_INTERRUPT_POLLING 0x00
+#define FT6206_G_MODE_INTERRUPT_TRIGGER 0x01
+
+  /* Current power mode the FT6206 system is in (R) */
+#define FT6206_PWR_MODE_REG             0xA5
+
+  /* FT6206 firmware version */
+#define FT6206_FIRMID_REG               0xA6
+
+  /* FT6206 Chip identification register */
+#define FT6206_CHIP_ID_REG              0xA8
+
+  /*  Possible values of FT6206_CHIP_ID_REG */
+#define FT6206_ID_VALUE                 0x11
+#define FT6x36_ID_VALUE                 0xCD
+
+  /* Release code version */
+#define FT6206_RELEASE_CODE_ID_REG      0xAF
+
+  /* Current operating mode the FT6206 system is in (R) */
+#define FT6206_STATE_REG                0xBC
+
+typedef struct _TouchScreen_PortControlBlock{
+	uint32_t        reset_clk_base;
+	uint32_t        reset_clk_bit;
+	uint32_t        reset_gpio_base;
+	uint32_t        reset_gpio_pinno;
+	uint32_t        reset_gpio_mode;
+	uint32_t        reset_gpio_otype;
+	uint32_t        reset_gpio_pull;
+	uint32_t        reset_gpio_speed;
+	uint32_t        reset_gpio_release;
+
+	uint32_t        int_clk_base;
+	uint32_t        int_clk_bit;
+	uint32_t        int_gpio_base;
+	uint32_t        int_gpio_pinno;
+	uint32_t        int_gpio_mode;
+	uint32_t        int_gpio_pull;
+	uint32_t        int_gpio_speed;
+} TS_PortControlBlock;
+
+/** @typedef TouchScreen_Handle_t
+ *  TouchScreen Handle definition.
+ */
+typedef struct
+{
+	I2C_Handle_t    *hi2c;
+	const TS_PortControlBlock *pcb;
+	void            (*ifunc)(void);
+	uint8_t         initialized;
+	uint8_t         enable_it;
+	uint16_t        max_width;
+	uint16_t        max_height;
+	uint8_t         I2C_Address;
+	uint8_t         tsOrientation;
+
+	/* field holding the current number of simultaneous active touches */
+	uint8_t         currActiveTouchNb;
+
+	/* field holding the touch index currently managed */
+	uint8_t         currActiveTouchIdx;
+} TouchScreen_Handle_t;
+
+
+
+/**** NEW FEATURES enabled when Multi-touch support is enabled ****/
+
+/** @brief With FT6206 : maximum 2 touches detected simultaneously
+  */
+#define TS_MAX_NB_TOUCH                 ((uint32_t) FT6206_MAX_DETECTABLE_TOUCH)
+
+#define TS_SWAP_NONE                    ((uint8_t) 0x01)
+#define TS_SWAP_X                       ((uint8_t) 0x02)
+#define TS_SWAP_Y                       ((uint8_t) 0x04)
+#define TS_SWAP_XY                      ((uint8_t) 0x08)
+
+#define TS_ORIENTATION_PORTRAIT         ((uint8_t) 0x00)
+#define TS_ORIENTATION_LANDSCAPE        ((uint8_t) 0x01)
+#define TS_ORIENTATION_LANDSCAPE_ROT180 ((uint8_t) 0x02)
+
+/**
+*  @brief TS_StateTypeDef
+*  Define TS State structure
+*/
+typedef struct
+{
+	uint8_t         touchDetected;				/* Total number of active touches detected at last scan */
+	uint16_t        touchX[TS_MAX_NB_TOUCH];	/* Touch X[0], X[1] coordinates on 12 bits */
+	uint16_t        touchY[TS_MAX_NB_TOUCH];	/* Touch Y[0], Y[1] coordinates on 12 bits */
+
+#if (TS_MULTI_TOUCH_SUPPORTED == 1)
+	uint8_t         touchWeight[TS_MAX_NB_TOUCH];	/* Touch_Weight[0], Touch_Weight[1] : weight property of touches */
+	uint8_t         touchEventId[TS_MAX_NB_TOUCH];	/* Touch_EventId[0], Touch_EventId[1] : take value of type @ref TS_TouchEventTypeDef */
+	uint8_t         touchArea[TS_MAX_NB_TOUCH];		/* Touch_Area[0], Touch_Area[1] : touch area of each touch */
+	uint32_t        gestureId; /*!< type of gesture detected : take value of type @ref TS_GestureIdTypeDef */
+#endif  /* TS_MULTI_TOUCH_SUPPORTED == 1 */
+} TS_StateTypeDef;
+
+/**
+ *  @brief TS_GestureIdTypeDef
+ *  Define Possible managed gesture identification values returned by touch screen
+ *  driver.
+ */
+typedef enum
+{
+  GEST_ID_NO_GESTURE = 0x00, /*!< Gesture not defined / recognized */
+  GEST_ID_MOVE_UP    = 0x01, /*!< Gesture Move Up */
+  GEST_ID_MOVE_RIGHT = 0x02, /*!< Gesture Move Right */
+  GEST_ID_MOVE_DOWN  = 0x03, /*!< Gesture Move Down */
+  GEST_ID_MOVE_LEFT  = 0x04, /*!< Gesture Move Left */
+  GEST_ID_ZOOM_IN    = 0x05, /*!< Gesture Zoom In */
+  GEST_ID_ZOOM_OUT   = 0x06, /*!< Gesture Zoom Out */
+  GEST_ID_NB_MAX     = 0x07 /*!< max number of gesture id */
+} TS_GestureIdTypeDef;
+
+/**
+ *  @brief TS_TouchEventTypeDef
+ *  Define Possible touch events kind as returned values
+ *  by touch screen IC Driver.
+ */
+typedef enum
+{
+  TOUCH_EVENT_NO_EVT        = 0x00, /*!< Touch Event : undetermined */
+  TOUCH_EVENT_PRESS_DOWN    = 0x01, /*!< Touch Event Press Down */
+  TOUCH_EVENT_LIFT_UP       = 0x02, /*!< Touch Event Lift Up */
+  TOUCH_EVENT_CONTACT       = 0x03, /*!< Touch Event Contact */
+  TOUCH_EVENT_NB_MAX        = 0x04  /*!< max number of touch events kind */
+} TS_TouchEventTypeDef;
+
+/**
+ *  @brief Table for touchscreen event information display on LCD :
+ *  table indexed on enum @ref TS_TouchEventTypeDef information
+ */
+extern char * ts_event_string_tab[TOUCH_EVENT_NB_MAX];
+
+/**
+ *  @brief Table for touchscreen gesture Id information display on LCD : table indexed
+ *  on enum @ref TS_GestureIdTypeDef information
+ */
+extern char * ts_gesture_id_string_tab[GEST_ID_NB_MAX];
+
+extern ER touchscreen_init(TouchScreen_Handle_t *hts, uint16_t ts_SizeX, uint16_t ts_SizeY, uint8_t orientation);
+extern ER touchscreen_getstate(TouchScreen_Handle_t *hts, TS_StateTypeDef *TS_State);
+extern ER touchscreen_enable_it(TouchScreen_Handle_t *hts);
+extern ER touchscreen_disable_it(TouchScreen_Handle_t *hts);
+
+#if (TS_MULTI_TOUCH_SUPPORTED == 1)
+extern ER touchscreen_get_gestureid(TouchScreen_Handle_t *hts, TS_StateTypeDef *TS_State);
+extern ER touchscreen_reset_data(TS_StateTypeDef *TS_State);
+#endif /* TS_MULTI_TOUCH_SUPPORTED == 1 */
+
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _STTS_FT06X06_H_ */
+
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/stts_ft5336/Makefile.config
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/stts_ft5336/Makefile.config	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/stts_ft5336/Makefile.config	(revision 457)
@@ -0,0 +1,55 @@
+#
+#   TOPPERS/ASP/FMP Kernel
+#       Toyohashi Open Platform for Embedded Real-Time Systems/
+#       Advanced Standard Profile Kernel
+#
+#   Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
+#                               Toyohashi Univ. of Technology, JAPAN
+#   Copyright (C) 2003-2008 by Ryosuke Takeuchi
+#                Platform Development Center RICOH COMPANY,LTD. JAPAN
+#   Copyright (C) 2015-2018 by TOPPERS PROJECT Educational Working Group.
+#
+#   上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+#   によって公表されている GNU General Public License の Version 2 に記
+#   述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+#   を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+#   利用と呼ぶ）することを無償で許諾する．
+#   (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+#       権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+#       スコード中に含まれていること．
+#   (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+#       用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+#       者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+#       の無保証規定を掲載すること．
+#   (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+#       用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+#       と．
+#     (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+#         作権表示，この利用条件および下記の無保証規定を掲載すること．
+#     (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+#         報告すること．
+#   (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+#       害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+#
+#   本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+#   よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+#   含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+#   接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+#
+#  @(#) $Id$
+#
+ 
+#
+#  Makefile のプロセッサ依存 (stts_ft5336用)
+#
+
+#
+#  コンパイルオプション
+#
+INCLUDES := $(INCLUDES) -I$(SRCDIR)/gdic/stts_ft5336
+
+#
+#  USB DEVICE(GDIC)に関する定義
+#
+SYSSVC_DIR := $(SYSSVC_DIR):$(SRCDIR)/gdic/stts_ft5336
+SYSSVC_COBJS := $(SYSSVC_COBJS) stts_ft5336.o
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/stts_ft5336/stts_ft5336.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/stts_ft5336/stts_ft5336.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/stts_ft5336/stts_ft5336.c	(revision 457)
@@ -0,0 +1,574 @@
+/*
+ *  TOPPERS BASE PLATFORM MIDDLEWARE
+ * 
+ *  Copyright (C) 2017-2018 by TOPPERS PROJECT
+ *                             Educational Working Group.
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+/**
+  ******************************************************************************
+  * @attention
+  *
+  * <h2><center>&copy; COPYRIGHT(c) 2016 STMicroelectronics</center></h2>
+  *
+  * 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 STMicroelectronics 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 "stts_ft5336.h"
+
+/**
+  * @brief  Reads a single data.
+  * @param  Addr: I2C address
+  * @param  Reg: Reg address
+  * @retval Data to be read
+  */
+static uint8_t
+ft5336_IO_Read(TouchScreen_Handle_t *hts, uint8_t Reg)
+{
+	I2C_Init_t  Init;
+	uint8_t read_value = 0;
+	ER ercd = E_OK;
+
+	ercd = i2c_memread(hts->hi2c, hts->I2C_Address, (uint16_t)Reg, I2C_MEMADD_SIZE_8BIT, &read_value, 1, 1000);
+
+	/* Check the communication status */
+	if(ercd != E_OK){
+		/* De-initialize the I2C communication bus */
+		i2c_deinit(hts->hi2c);
+
+		/* Re-Initialize the I2C communication bus */
+		memcpy(&Init, &hts->hi2c->Init, sizeof(I2C_Init_t));
+		i2c_init(hts->hi2c->i2cid, &Init);
+	}
+	return read_value;
+}
+
+/**
+  * @brief  Read the ft5336 device ID, pre initialize I2C in case of need to be
+  *         able to read the FT5336 device ID, and verify this is a FT5336.
+  * @param  DeviceAddr: I2C FT5336 Slave address.
+  * @retval The Device ID (two bytes).
+  */
+static uint16_t
+ft5336_ReadID(TouchScreen_Handle_t *hts, uint16_t DeviceAddr)
+{
+	volatile uint8_t ucReadId = 0;
+	uint8_t nbReadAttempts = 0;
+	uint8_t bFoundDevice = 0; /* Device not found by default */
+
+	hts->I2C_Address = DeviceAddr;
+	/* At maximum 4 attempts to read ID : exit at first finding of the searched device ID */
+	for(nbReadAttempts = 0; ((nbReadAttempts < 3) && !(bFoundDevice)); nbReadAttempts++){
+		/* Read register FT5336_CHIP_ID_REG as DeviceID detection */
+		ucReadId = ft5336_IO_Read(hts, FT5336_CHIP_ID_REG);
+
+		/* Found the searched device ID ? */
+		if(ucReadId == FT5336_ID_VALUE){
+			/* Set device as found */
+			bFoundDevice = 1;
+		}
+	}
+	return (ucReadId);
+}
+
+/**
+  * @brief  Configure the FT5336 device to stop generating IT on the given INT pin
+  *         connected to MCU as EXTI.
+  * @param  DeviceAddr: Device address on communication Bus (Slave I2C address of FT5336).
+  * @retval None
+  */
+static void
+ft5336_TS_DisableIT(TouchScreen_Handle_t *hts)
+{
+	ER ercd = E_OK;
+	uint8_t regValue = 0;
+	regValue = (FT5336_G_MODE_INTERRUPT_POLLING & (FT5336_G_MODE_INTERRUPT_MASK >> FT5336_G_MODE_INTERRUPT_SHIFT)) << FT5336_G_MODE_INTERRUPT_SHIFT;
+
+	/* Set interrupt polling mode in FT5336_GMODE_REG */
+	ercd = i2c_memwrite(hts->hi2c, hts->I2C_Address, FT5336_GMODE_REG, I2C_MEMADD_SIZE_8BIT, &regValue, 1, 1000);
+	if(ercd != E_OK)
+		syslog_1(LOG_ERROR, "ft5336_TS_DisableIT I2C write error(%d) !", ercd);
+}
+
+/**
+  * @brief  Return if there is touches detected or not.
+  *         Try to detect new touches and forget the old ones (reset internal global
+  *         variables).
+  * @param  DeviceAddr: Device address on communication Bus.
+  * @retval : Number of active touches detected (can be 0, 1 or 2).
+  */
+static uint8_t
+ft5336_TS_DetectTouch(TouchScreen_Handle_t *hts)
+{
+	volatile uint8_t nbTouch = 0;
+
+	/* Read register FT5336_TD_STAT_REG to check number of touches detection */
+	nbTouch = ft5336_IO_Read(hts, FT5336_TD_STAT_REG);
+	nbTouch &= FT5336_TD_STAT_MASK;
+
+	if(nbTouch > FT5336_MAX_DETECTABLE_TOUCH){
+		/* If invalid number of touch detected, set it to zero */
+		nbTouch = 0;
+	}
+
+	/* Update ft5336 driver internal global : current number of active touches */
+	hts->currActiveTouchNb = nbTouch;
+
+	/* Reset current active touch index on which to work on */
+	hts->currActiveTouchIdx = 0;
+	return(nbTouch);
+}
+
+/**
+  * @brief  Get the touch screen X and Y positions values
+  *         Manage multi touch thanks to touch Index global
+  *         variable 'TouchScreen_Handle.currActiveTouchIdx'.
+  * @param  DeviceAddr: Device address on communication Bus.
+  * @param  X: Pointer to X position value
+  * @param  Y: Pointer to Y position value
+  * @retval None.
+  */
+static void
+ft5336_TS_GetXY(TouchScreen_Handle_t *hts, uint16_t *X, uint16_t *Y)
+{
+	volatile uint8_t ucReadData = 0;
+	static uint16_t coord;
+	uint8_t regAddressXLow = 0;
+	uint8_t regAddressXHigh = 0;
+	uint8_t regAddressYLow = 0;
+	uint8_t regAddressYHigh = 0;
+
+	if(hts->currActiveTouchIdx < hts->currActiveTouchNb){
+		switch(hts->currActiveTouchIdx){
+		case 0:
+			regAddressXLow  = FT5336_P1_XL_REG;
+			regAddressXHigh = FT5336_P1_XH_REG;
+			regAddressYLow  = FT5336_P1_YL_REG;
+			regAddressYHigh = FT5336_P1_YH_REG;
+			break;
+		case 1:
+			regAddressXLow  = FT5336_P2_XL_REG;
+			regAddressXHigh = FT5336_P2_XH_REG;
+			regAddressYLow  = FT5336_P2_YL_REG;
+			regAddressYHigh = FT5336_P2_YH_REG;
+			break;
+		case 2:
+			regAddressXLow  = FT5336_P3_XL_REG;
+			regAddressXHigh = FT5336_P3_XH_REG;
+			regAddressYLow  = FT5336_P3_YL_REG;
+			regAddressYHigh = FT5336_P3_YH_REG;
+			break;
+		case 3:
+			regAddressXLow  = FT5336_P4_XL_REG;
+			regAddressXHigh = FT5336_P4_XH_REG;
+			regAddressYLow  = FT5336_P4_YL_REG;
+			regAddressYHigh = FT5336_P4_YH_REG;
+			break;
+		case 4:
+			regAddressXLow  = FT5336_P5_XL_REG;
+			regAddressXHigh = FT5336_P5_XH_REG;
+			regAddressYLow  = FT5336_P5_YL_REG;
+			regAddressYHigh = FT5336_P5_YH_REG;
+			break;
+		case 5:
+			regAddressXLow  = FT5336_P6_XL_REG;
+			regAddressXHigh = FT5336_P6_XH_REG;
+			regAddressYLow  = FT5336_P6_YL_REG;
+			regAddressYHigh = FT5336_P6_YH_REG;
+			break;
+		case 6:
+			regAddressXLow  = FT5336_P7_XL_REG;
+			regAddressXHigh = FT5336_P7_XH_REG;
+			regAddressYLow  = FT5336_P7_YL_REG;
+			regAddressYHigh = FT5336_P7_YH_REG;
+			break;
+		case 7:
+			regAddressXLow  = FT5336_P8_XL_REG;
+			regAddressXHigh = FT5336_P8_XH_REG;
+			regAddressYLow  = FT5336_P8_YL_REG;
+			regAddressYHigh = FT5336_P8_YH_REG;
+			break;
+		case 8:
+			regAddressXLow  = FT5336_P9_XL_REG;
+			regAddressXHigh = FT5336_P9_XH_REG;
+			regAddressYLow  = FT5336_P9_YL_REG;
+			regAddressYHigh = FT5336_P9_YH_REG;
+			break;
+		case 9:
+			regAddressXLow  = FT5336_P10_XL_REG;
+			regAddressXHigh = FT5336_P10_XH_REG;
+			regAddressYLow  = FT5336_P10_YL_REG;
+			regAddressYHigh = FT5336_P10_YH_REG;
+			break;
+		default:
+			break;
+
+		} /* end switch(TouchScreen_Handle.currActiveTouchIdx) */
+
+		/* Read low part of X position */
+		ucReadData = ft5336_IO_Read(hts, regAddressXLow);
+		coord = (ucReadData & FT5336_TOUCH_POS_LSB_MASK) >> FT5336_TOUCH_POS_LSB_SHIFT;
+
+		/* Read high part of X position */
+		ucReadData = ft5336_IO_Read(hts, regAddressXHigh);
+		coord |= ((ucReadData & FT5336_TOUCH_POS_MSB_MASK) >> FT5336_TOUCH_POS_MSB_SHIFT) << 8;
+
+		/* Send back ready X position to caller */
+		*X = coord;
+
+		/* Read low part of Y position */
+		ucReadData = ft5336_IO_Read(hts, regAddressYLow);
+		coord = (ucReadData & FT5336_TOUCH_POS_LSB_MASK) >> FT5336_TOUCH_POS_LSB_SHIFT;
+
+		/* Read high part of Y position */
+		ucReadData = ft5336_IO_Read(hts, regAddressYHigh);
+		coord |= ((ucReadData & FT5336_TOUCH_POS_MSB_MASK) >> FT5336_TOUCH_POS_MSB_SHIFT) << 8;
+
+		/* Send back ready Y position to caller */
+		*Y = coord;
+
+		hts->currActiveTouchIdx++;	/* next call will work on next touch */
+	} /* of if(TouchScreen_Handle.currActiveTouchIdx < TouchScreen_Handle.currActiveTouchNb) */
+}
+
+
+/**** NEW FEATURES enabled when Multi-touch support is enabled ****/
+
+#if (TS_MULTI_TOUCH_SUPPORTED == 1)
+/**
+  * @brief  Get the touch detailed informations on touch number 'touchIdx' (0..1)
+  *         This touch detailed information contains :
+  *         - weight that was applied to this touch
+  *         - sub-area of the touch in the touch panel
+  *         - event of linked to the touch (press down, lift up, ...)
+  * @param  DeviceAddr: Device address on communication Bus (I2C slave address of FT5336).
+  * @param  touchIdx : Passed index of the touch (0..1) on which we want to get the
+  *                    detailed information.
+  * @param  pWeight : Pointer to to get the weight information of 'touchIdx'.
+  * @param  pArea   : Pointer to to get the sub-area information of 'touchIdx'.
+  * @param  pEvent  : Pointer to to get the event information of 'touchIdx'.
+
+  * @retval None.
+  */
+static void
+ft5336_TS_GetTouchInfo(TouchScreen_Handle_t *hts, uint32_t touchIdx, uint32_t *pWeight, uint32_t *pArea, uint32_t *pEvent)
+{
+	volatile uint8_t ucReadData = 0;
+	uint8_t regAddressXHigh = 0;
+	uint8_t regAddressPWeight = 0;
+	uint8_t regAddressPMisc = 0;
+
+	if(touchIdx < hts->currActiveTouchNb){
+		switch(touchIdx){
+		case 0:
+			regAddressXHigh   = FT5336_P1_XH_REG;
+			regAddressPWeight = FT5336_P1_WEIGHT_REG;
+			regAddressPMisc   = FT5336_P1_MISC_REG;
+			break;
+		case 1:
+			regAddressXHigh   = FT5336_P2_XH_REG;
+			regAddressPWeight = FT5336_P2_WEIGHT_REG;
+			regAddressPMisc   = FT5336_P2_MISC_REG;
+			break;
+		case 2:
+			regAddressXHigh   = FT5336_P3_XH_REG;
+			regAddressPWeight = FT5336_P3_WEIGHT_REG;
+			regAddressPMisc   = FT5336_P3_MISC_REG;
+			break;
+		case 3:
+			regAddressXHigh   = FT5336_P4_XH_REG;
+			regAddressPWeight = FT5336_P4_WEIGHT_REG;
+			regAddressPMisc   = FT5336_P4_MISC_REG;
+			break;
+		case 4:
+			regAddressXHigh   = FT5336_P5_XH_REG;
+			regAddressPWeight = FT5336_P5_WEIGHT_REG;
+			regAddressPMisc   = FT5336_P5_MISC_REG;
+			break;
+		case 5:
+			regAddressXHigh   = FT5336_P6_XH_REG;
+			regAddressPWeight = FT5336_P6_WEIGHT_REG;
+			regAddressPMisc   = FT5336_P6_MISC_REG;
+			break;
+		case 6:
+			regAddressXHigh   = FT5336_P7_XH_REG;
+			regAddressPWeight = FT5336_P7_WEIGHT_REG;
+			regAddressPMisc   = FT5336_P7_MISC_REG;
+			break;
+		case 7:
+			regAddressXHigh   = FT5336_P8_XH_REG;
+			regAddressPWeight = FT5336_P8_WEIGHT_REG;
+			regAddressPMisc   = FT5336_P8_MISC_REG;
+			break;
+		case 8:
+			regAddressXHigh   = FT5336_P9_XH_REG;
+			regAddressPWeight = FT5336_P9_WEIGHT_REG;
+			regAddressPMisc   = FT5336_P9_MISC_REG;
+			break;
+		case 9:
+			regAddressXHigh   = FT5336_P10_XH_REG;
+			regAddressPWeight = FT5336_P10_WEIGHT_REG;
+			regAddressPMisc   = FT5336_P10_MISC_REG;
+			break;
+		default:
+			break;
+		} /* end switch(touchIdx) */
+
+		/* Read Event Id of touch index */
+		ucReadData = ft5336_IO_Read(hts, regAddressXHigh);
+		*pEvent = (ucReadData & FT5336_TOUCH_EVT_FLAG_MASK) >> FT5336_TOUCH_EVT_FLAG_SHIFT;
+
+		/* Read weight of touch index */
+		ucReadData = ft5336_IO_Read(hts, regAddressPWeight);
+		*pWeight = (ucReadData & FT5336_TOUCH_WEIGHT_MASK) >> FT5336_TOUCH_WEIGHT_SHIFT;
+
+		/* Read area of touch index */
+		ucReadData = ft5336_IO_Read(hts, regAddressPMisc);
+		*pArea = (ucReadData & FT5336_TOUCH_AREA_MASK) >> FT5336_TOUCH_AREA_SHIFT;
+	} /* of if(touchIdx < TouchScreen_Handle.currActiveTouchNb) */
+}
+#endif /* TS_MULTI_TOUCH_SUPPORTED == 1 */
+
+
+/**
+  * @brief  Initializes and configures the touch screen functionalities and 
+  *         configures all necessary hardware resources (GPIOs, I2C, clocks..).
+  * @param  ts_SizeX: Maximum X size of the TS area on LCD
+  * @param  ts_SizeY: Maximum Y size of the TS area on LCD
+  * @param  orientation : TS_ORIENTATION_LANDSCAPE or TS_ORIENTATION_PORTRAIT
+  * @retval E_OK if all initializations are OK. Other value if error.
+  */
+ER
+touchscreen_init(TouchScreen_Handle_t *hts, uint16_t ts_SizeX, uint16_t ts_SizeY, uint8_t orientation)
+{
+	ER ercd  = E_OK;
+	hts->tsXBoundary = ts_SizeX;
+	hts->tsYBoundary = ts_SizeY;
+
+	/* Read ID and verify if the touch screen driver is ready */
+	if(ft5336_ReadID(hts, FT5336_I2C_SLAVE_ADDRESS) == FT5336_ID_VALUE){
+		/* Initialize the TS driver structure */
+		hts->I2C_Address = FT5336_I2C_SLAVE_ADDRESS;
+		hts->tsOrientation = TS_SWAP_XY;
+
+		/* Initialize the TS driver */
+		ft5336_TS_DisableIT(hts);
+	}
+	else
+		ercd = E_NOSPT;
+	return ercd;
+}
+
+/**
+  * @brief  Returns status and positions of the touch screen.
+  * @param  TS_State: Pointer to touch screen current state structure
+  * @retval E_OK if all initializations are OK. Other value if error.
+  */
+ER
+touchscreen_getstate(TouchScreen_Handle_t *hts, TS_StateTypeDef *TS_State)
+{
+	static uint32_t _x[TS_MAX_NB_TOUCH] = {0, 0};
+	static uint32_t _y[TS_MAX_NB_TOUCH] = {0, 0};
+	ER  ercd = E_OK;
+	uint16_t x[TS_MAX_NB_TOUCH];
+	uint16_t y[TS_MAX_NB_TOUCH];
+	uint16_t brute_x[TS_MAX_NB_TOUCH];
+	uint16_t brute_y[TS_MAX_NB_TOUCH];
+	uint16_t x_diff;
+	uint16_t y_diff;
+	uint32_t index;
+#if (TS_MULTI_TOUCH_SUPPORTED == 1)
+	uint32_t weight = 0;
+	uint32_t area = 0;
+	uint32_t event = 0;
+	uint32_t gestureId = 0;
+#endif /* TS_MULTI_TOUCH_SUPPORTED == 1 */
+
+	/* Check and update the number of touches active detected */
+	TS_State->touchDetected = ft5336_TS_DetectTouch(hts);
+
+	if(TS_State->touchDetected){
+		for(index=0; index < TS_State->touchDetected; index++){
+			/* Get each touch coordinates */
+			ft5336_TS_GetXY(hts, &(brute_x[index]), &(brute_y[index]));
+
+			if(hts->tsOrientation == TS_SWAP_NONE){
+				x[index] = brute_x[index];
+				y[index] = brute_y[index];
+			}
+			if(hts->tsOrientation & TS_SWAP_X){
+				x[index] = 4096 - brute_x[index];
+			}
+			if(hts->tsOrientation & TS_SWAP_Y){
+				y[index] = 4096 - brute_y[index];
+			}
+			if(hts->tsOrientation & TS_SWAP_XY){
+				y[index] = brute_x[index];
+				x[index] = brute_y[index];
+			}
+
+			x_diff = x[index] > _x[index]? (x[index] - _x[index]): (_x[index] - x[index]);
+			y_diff = y[index] > _y[index]? (y[index] - _y[index]): (_y[index] - y[index]);
+
+			if((x_diff + y_diff) > 5){
+				_x[index] = x[index];
+				_y[index] = y[index];
+			}
+			if(hts->I2C_Address == FT5336_I2C_SLAVE_ADDRESS){
+				TS_State->touchX[index] = x[index];
+				TS_State->touchY[index] = y[index];
+			}
+			else{
+				/* 2^12 = 4096 : indexes are expressed on a dynamic of 4096 */
+				TS_State->touchX[index] = (hts->tsXBoundary * _x[index]) >> 12;
+				TS_State->touchY[index] = (hts->tsYBoundary * _y[index]) >> 12;
+			}
+
+#if (TS_MULTI_TOUCH_SUPPORTED == 1)
+			/* Get touch info related to the current touch */
+			ft5336_TS_GetTouchInfo(hts, index, &weight, &area, &event);
+
+			/* Update TS_State structure */
+			TS_State->touchWeight[index] = weight;
+			TS_State->touchArea[index]   = area;
+
+			/* Remap touch event */
+			switch(event){
+			case FT5336_TOUCH_EVT_FLAG_PRESS_DOWN	:
+				TS_State->touchEventId[index] = TOUCH_EVENT_PRESS_DOWN;
+				break;
+			case FT5336_TOUCH_EVT_FLAG_LIFT_UP :
+				TS_State->touchEventId[index] = TOUCH_EVENT_LIFT_UP;
+				break;
+			case FT5336_TOUCH_EVT_FLAG_CONTACT :
+				TS_State->touchEventId[index] = TOUCH_EVENT_CONTACT;
+				break;
+			case FT5336_TOUCH_EVT_FLAG_NO_EVENT :
+				TS_State->touchEventId[index] = TOUCH_EVENT_NO_EVT;
+				break;
+			default:
+				ercd = E_SYS;
+				break;
+			} /* of switch(event) */
+#endif /* TS_MULTI_TOUCH_SUPPORTED == 1 */
+
+		} /* of for(index=0; index < TS_State->touchDetected; index++) */
+
+#if (TS_MULTI_TOUCH_SUPPORTED == 1)
+		/* Get gesture Id */
+		gestureId = ft5336_IO_Read(hts, FT5336_GEST_ID_REG);
+
+		/* Remap gesture Id to a TS_GestureIdTypeDef value */
+		switch(gestureId){
+		case FT5336_GEST_ID_NO_GESTURE :
+			TS_State->gestureId = GEST_ID_NO_GESTURE;
+			break;
+		case FT5336_GEST_ID_MOVE_UP :
+			TS_State->gestureId = GEST_ID_MOVE_UP;
+			break;
+		case FT5336_GEST_ID_MOVE_RIGHT :
+			TS_State->gestureId = GEST_ID_MOVE_RIGHT;
+			break;
+		case FT5336_GEST_ID_MOVE_DOWN :
+			TS_State->gestureId = GEST_ID_MOVE_DOWN;
+			break;
+		case FT5336_GEST_ID_MOVE_LEFT :
+			TS_State->gestureId = GEST_ID_MOVE_LEFT;
+			break;
+		case FT5336_GEST_ID_ZOOM_IN :
+			TS_State->gestureId = GEST_ID_ZOOM_IN;
+			break;
+		case FT5336_GEST_ID_ZOOM_OUT :
+			TS_State->gestureId = GEST_ID_ZOOM_OUT;
+			break;
+		default:
+			ercd = E_SYS;
+			break;
+		} /* of switch(gestureId) */
+#endif /* TS_MULTI_TOUCH_SUPPORTED == 1 */
+
+	} /* end of if(TS_State->touchDetected != 0) */
+	return ercd;
+}
+
+/**
+  * @brief  Function used to reset all touch data before a new acquisition
+  *         of touch information.
+  * @param  TS_State: Pointer to touch screen current state structure
+  * @retval E_OK if OK, TE_ERROR if problem found.
+  */
+ER
+touchscreen_reset_data(TS_StateTypeDef *TS_State)
+{
+	ER       ercd = E_PAR;
+	uint32_t index;
+
+	if(TS_State != (TS_StateTypeDef *)NULL){
+		TS_State->gestureId = GEST_ID_NO_GESTURE;
+		TS_State->touchDetected = 0;
+
+		for(index = 0; index < TS_MAX_NB_TOUCH; index++){
+			TS_State->touchX[index]       = 0;
+			TS_State->touchY[index]       = 0;
+			TS_State->touchArea[index]    = 0;
+			TS_State->touchEventId[index] = TOUCH_EVENT_NO_EVT;
+			TS_State->touchWeight[index]  = 0;
+		}
+		ercd = E_OK;
+	} /* of if (TS_State != (TS_StateTypeDef *)NULL) */
+	return ercd;
+}
+
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/stts_ft5336/stts_ft5336.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/stts_ft5336/stts_ft5336.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/stts_ft5336/stts_ft5336.h	(revision 457)
@@ -0,0 +1,428 @@
+/*
+ *  TOPPERS BASE PLATFORM MIDDLEWARE
+ * 
+ *  Copyright (C) 2017-2018 by TOPPERS PROJECT
+ *                             Educational Working Group.
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+/**
+  ******************************************************************************
+  * @attention
+  *
+  * <h2><center>&copy; COPYRIGHT(c) 2016 STMicroelectronics</center></h2>
+  *
+  * 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 STMicroelectronics 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 _STTS_FT5336_H_
+#define _STTS_FT5336_H_
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+#include <kernel.h>
+#include <t_syslog.h>
+#include <t_stdlib.h>
+#include "syssvc/serial.h"
+#include "syssvc/syslog.h"
+#include "device.h"
+#include "i2c.h"
+
+/* Set Multi-touch as supported */
+#if !defined(TS_MONO_TOUCH_SUPPORTED)
+#define TS_MULTI_TOUCH_SUPPORTED        1
+#endif /* TS_MONO_TOUCH_SUPPORTED */
+
+
+  /* I2C Slave address of touchscreen FocalTech FT5336 */
+#define FT5336_I2C_SLAVE_ADDRESS        0x70
+
+  /* Maximum border values of the touchscreen pad */
+#define FT5336_MAX_WIDTH                480	/* Touchscreen pad max width   */
+#define FT5336_MAX_HEIGHT               272	/* Touchscreen pad max height  */
+
+  /* Max detectable simultaneous touches */
+#define FT5336_MAX_DETECTABLE_TOUCH     0x05
+
+  /**
+   * @brief : Definitions for FT5336 I2C register addresses on 8 bit
+   **/
+
+  /* Current mode register of the FT5336 (R/W) */
+#define FT5336_DEV_MODE_REG             0x00
+
+  /* Possible values of FT5336_DEV_MODE_REG */
+#define FT5336_DEV_MODE_WORKING         0x00
+#define FT5336_DEV_MODE_FACTORY         0x04
+
+#define FT5336_DEV_MODE_MASK            0x07
+#define FT5336_DEV_MODE_SHIFT           0x04
+
+  /* Gesture ID register */
+#define FT5336_GEST_ID_REG              0x01
+
+  /* Possible values of FT5336_GEST_ID_REG */
+#define FT5336_GEST_ID_NO_GESTURE       0x00
+#define FT5336_GEST_ID_MOVE_UP          0x10
+#define FT5336_GEST_ID_MOVE_RIGHT       0x14
+#define FT5336_GEST_ID_MOVE_DOWN        0x18
+#define FT5336_GEST_ID_MOVE_LEFT        0x1C
+#define FT5336_GEST_ID_SINGLE_CLICK     0x20
+#define FT5336_GEST_ID_DOUBLE_CLICK     0x22
+#define FT5336_GEST_ID_ROTATE_CLOCKWISE 0x28
+#define FT5336_GEST_ID_ROTATE_C_CLOCKWISE 0x29
+#define FT5336_GEST_ID_ZOOM_IN          0x40
+#define FT5336_GEST_ID_ZOOM_OUT         0x49
+
+  /* Touch Data Status register : gives number of active touch points (0..5) */
+#define FT5336_TD_STAT_REG              0x02
+
+  /* Values related to FT5336_TD_STAT_REG */
+#define FT5336_TD_STAT_MASK             0x0F
+#define FT5336_TD_STAT_SHIFT            0x00
+
+  /* Values Pn_XH and Pn_YH related */
+#define FT5336_TOUCH_EVT_FLAG_PRESS_DOWN 0x00
+#define FT5336_TOUCH_EVT_FLAG_LIFT_UP   0x01
+#define FT5336_TOUCH_EVT_FLAG_CONTACT   0x02
+#define FT5336_TOUCH_EVT_FLAG_NO_EVENT  0x03
+
+#define FT5336_TOUCH_EVT_FLAG_SHIFT     0x06
+#define FT5336_TOUCH_EVT_FLAG_MASK      (3 << FT5336_TOUCH_EVT_FLAG_SHIFT)
+
+#define FT5336_TOUCH_POS_MSB_MASK       0x0F
+#define FT5336_TOUCH_POS_MSB_SHIFT      0x00
+
+  /* Values Pn_XL and Pn_YL related */
+#define FT5336_TOUCH_POS_LSB_MASK       0xFF
+#define FT5336_TOUCH_POS_LSB_SHIFT      0x00
+
+#define FT5336_P1_XH_REG                0x03
+#define FT5336_P1_XL_REG                0x04
+#define FT5336_P1_YH_REG                0x05
+#define FT5336_P1_YL_REG                0x06
+
+/* Touch Pressure register value (R) */
+#define FT5336_P1_WEIGHT_REG            0x07
+
+/* Values Pn_WEIGHT related  */
+#define FT5336_TOUCH_WEIGHT_MASK        0xFF
+#define FT5336_TOUCH_WEIGHT_SHIFT       0x00
+
+/* Touch area register */
+#define FT5336_P1_MISC_REG              0x08
+
+/* Values related to FT5336_Pn_MISC_REG */
+#define FT5336_TOUCH_AREA_MASK          (0x04 << 4)
+#define FT5336_TOUCH_AREA_SHIFT         0x04
+
+#define FT5336_P2_XH_REG                0x09
+#define FT5336_P2_XL_REG                0x0A
+#define FT5336_P2_YH_REG                0x0B
+#define FT5336_P2_YL_REG                0x0C
+#define FT5336_P2_WEIGHT_REG            0x0D
+#define FT5336_P2_MISC_REG              0x0E
+
+#define FT5336_P3_XH_REG                0x0F
+#define FT5336_P3_XL_REG                0x10
+#define FT5336_P3_YH_REG                0x11
+#define FT5336_P3_YL_REG                0x12
+#define FT5336_P3_WEIGHT_REG            0x13
+#define FT5336_P3_MISC_REG              0x14
+
+#define FT5336_P4_XH_REG                0x15
+#define FT5336_P4_XL_REG                0x16
+#define FT5336_P4_YH_REG                0x17
+#define FT5336_P4_YL_REG                0x18
+#define FT5336_P4_WEIGHT_REG            0x19
+#define FT5336_P4_MISC_REG              0x1A
+
+#define FT5336_P5_XH_REG                0x1B
+#define FT5336_P5_XL_REG                0x1C
+#define FT5336_P5_YH_REG                0x1D
+#define FT5336_P5_YL_REG                0x1E
+#define FT5336_P5_WEIGHT_REG            0x1F
+#define FT5336_P5_MISC_REG              0x20
+
+#define FT5336_P6_XH_REG                0x21
+#define FT5336_P6_XL_REG                0x22
+#define FT5336_P6_YH_REG                0x23
+#define FT5336_P6_YL_REG                0x24
+#define FT5336_P6_WEIGHT_REG            0x25
+#define FT5336_P6_MISC_REG              0x26
+
+#define FT5336_P7_XH_REG                0x27
+#define FT5336_P7_XL_REG                0x28
+#define FT5336_P7_YH_REG                0x29
+#define FT5336_P7_YL_REG                0x2A
+#define FT5336_P7_WEIGHT_REG            0x2B
+#define FT5336_P7_MISC_REG              0x2C
+
+#define FT5336_P8_XH_REG                0x2D
+#define FT5336_P8_XL_REG                0x2E
+#define FT5336_P8_YH_REG                0x2F
+#define FT5336_P8_YL_REG                0x30
+#define FT5336_P8_WEIGHT_REG            0x31
+#define FT5336_P8_MISC_REG              0x32
+
+#define FT5336_P9_XH_REG                0x33
+#define FT5336_P9_XL_REG                0x34
+#define FT5336_P9_YH_REG                0x35
+#define FT5336_P9_YL_REG                0x36
+#define FT5336_P9_WEIGHT_REG            0x37
+#define FT5336_P9_MISC_REG              0x38
+
+#define FT5336_P10_XH_REG               0x39
+#define FT5336_P10_XL_REG               0x3A
+#define FT5336_P10_YH_REG               0x3B
+#define FT5336_P10_YL_REG               0x3C
+#define FT5336_P10_WEIGHT_REG           0x3D
+#define FT5336_P10_MISC_REG             0x3E
+
+  /* Threshold for touch detection */
+#define FT5336_TH_GROUP_REG             0x80
+
+  /* Values FT5336_TH_GROUP_REG : threshold related  */
+#define FT5336_THRESHOLD_MASK           0xFF
+#define FT5336_THRESHOLD_SHIFT          0x00
+
+  /* Filter function coefficients */
+#define FT5336_TH_DIFF_REG              0x85
+
+  /* Control register */
+#define FT5336_CTRL_REG                 0x86
+
+  /* Values related to FT5336_CTRL_REG */
+
+  /* Will keep the Active mode when there is no touching */
+#define FT5336_CTRL_KEEP_ACTIVE_MODE    0x00
+
+  /* Switching from Active mode to Monitor mode automatically when there is no touching */
+#define FT5336_CTRL_KEEP_AUTO_SWITCH_MONITOR_MODE  0x01
+
+  /* The time period of switching from Active mode to Monitor mode when there is no touching */
+#define FT5336_TIMEENTERMONITOR_REG     0x87
+
+  /* Report rate in Active mode */
+#define FT5336_PERIODACTIVE_REG         0x88
+
+  /* Report rate in Monitor mode */
+#define FT5336_PERIODMONITOR_REG        0x89
+
+  /* The value of the minimum allowed angle while Rotating gesture mode */
+#define FT5336_RADIAN_VALUE_REG         0x91
+
+  /* Maximum offset while Moving Left and Moving Right gesture */
+#define FT5336_OFFSET_LEFT_RIGHT_REG    0x92
+
+  /* Maximum offset while Moving Up and Moving Down gesture */
+#define FT5336_OFFSET_UP_DOWN_REG       0x93
+
+  /* Minimum distance while Moving Left and Moving Right gesture */
+#define FT5336_DISTANCE_LEFT_RIGHT_REG  0x94
+
+  /* Minimum distance while Moving Up and Moving Down gesture */
+#define FT5336_DISTANCE_UP_DOWN_REG     0x95
+
+  /* Maximum distance while Zoom In and Zoom Out gesture */
+#define FT5336_DISTANCE_ZOOM_REG        0x96
+
+  /* High 8-bit of LIB Version info */
+#define FT5336_LIB_VER_H_REG            0xA1
+
+  /* Low 8-bit of LIB Version info */
+#define FT5336_LIB_VER_L_REG            0xA2
+
+  /* Chip Selecting */
+#define FT5336_CIPHER_REG               0xA3
+
+  /* Interrupt mode register (used when in interrupt mode) */
+#define FT5336_GMODE_REG                0xA4
+
+#define FT5336_G_MODE_INTERRUPT_MASK    0x03
+#define FT5336_G_MODE_INTERRUPT_SHIFT   0x00
+
+  /* Possible values of FT5336_GMODE_REG */
+#define FT5336_G_MODE_INTERRUPT_POLLING 0x00
+#define FT5336_G_MODE_INTERRUPT_TRIGGER 0x01
+
+  /* Current power mode the FT5336 system is in (R) */
+#define FT5336_PWR_MODE_REG             0xA5
+
+  /* FT5336 firmware version */
+#define FT5336_FIRMID_REG               0xA6
+
+  /* FT5336 Chip identification register */
+#define FT5336_CHIP_ID_REG              0xA8
+
+  /*  Possible values of FT5336_CHIP_ID_REG */
+#define FT5336_ID_VALUE                 0x51
+
+  /* Release code version */
+#define FT5336_RELEASE_CODE_ID_REG      0xAF
+
+  /* Current operating mode the FT5336 system is in (R) */
+#define FT5336_STATE_REG                0xBC
+
+
+/** @typedef TouchScreen_Handle_t
+ *  TouchScreen Handle definition.
+ */
+typedef struct
+{
+	I2C_Handle_t    *hi2c;
+	uint16_t        tsXBoundary;
+	uint16_t        tsYBoundary;
+	uint8_t         tsOrientation;
+	uint8_t         I2C_Address;
+
+	/* field holding the current number of simultaneous active touches */
+	uint8_t         currActiveTouchNb;
+
+	/* field holding the touch index currently managed */
+	uint8_t         currActiveTouchIdx;
+
+} TouchScreen_Handle_t;
+
+/** @brief With FT5336 : maximum 5 touches detected simultaneously
+  */
+#define TS_MAX_NB_TOUCH                 ((uint32_t) FT5336_MAX_DETECTABLE_TOUCH)
+
+#define TS_NO_IRQ_PENDING               ((uint8_t) 0)
+#define TS_IRQ_PENDING                  ((uint8_t) 1)
+
+#define TS_SWAP_NONE                    ((uint8_t) 0x01)
+#define TS_SWAP_X                       ((uint8_t) 0x02)
+#define TS_SWAP_Y                       ((uint8_t) 0x04)
+#define TS_SWAP_XY                      ((uint8_t) 0x08)
+
+#define TS_ORIENTATION_PORTRAIT         ((uint8_t) 0x00)
+#define TS_ORIENTATION_LANDSCAPE        ((uint8_t) 0x01)
+#define TS_ORIENTATION_LANDSCAPE_ROT180 ((uint8_t) 0x02)
+
+/**
+*  @brief TS_StateTypeDef
+*  Define TS State structure
+*/
+typedef struct
+{
+	uint8_t  touchDetected;				/* Total number of active touches detected at last scan */
+	uint16_t touchX[TS_MAX_NB_TOUCH];	/* Touch X[0], X[1] coordinates on 12 bits */
+	uint16_t touchY[TS_MAX_NB_TOUCH];	/* Touch Y[0], Y[1] coordinates on 12 bits */
+
+#if (TS_MULTI_TOUCH_SUPPORTED == 1)
+	uint8_t  touchWeight[TS_MAX_NB_TOUCH];	/* Touch_Weight[0], Touch_Weight[1] : weight property of touches */
+	uint8_t  touchEventId[TS_MAX_NB_TOUCH];	/* Touch_EventId[0], Touch_EventId[1] : take value of type @ref TS_TouchEventTypeDef */
+	uint8_t  touchArea[TS_MAX_NB_TOUCH];	/*!< Touch_Area[0], Touch_Area[1] : touch area of each touch */
+	uint32_t gestureId; /*!< type of gesture detected : take value of type @ref TS_GestureIdTypeDef */
+#endif  /* TS_MULTI_TOUCH_SUPPORTED == 1 */
+} TS_StateTypeDef;
+
+
+/**
+ *  @brief TS_GestureIdTypeDef
+ *  Define Possible managed gesture identification values returned by touch screen
+ *  driver.
+ */
+typedef enum
+{
+	GEST_ID_NO_GESTURE = 0x00, /*!< Gesture not defined / recognized */
+	GEST_ID_MOVE_UP    = 0x01, /*!< Gesture Move Up */
+	GEST_ID_MOVE_RIGHT = 0x02, /*!< Gesture Move Right */
+	GEST_ID_MOVE_DOWN  = 0x03, /*!< Gesture Move Down */
+	GEST_ID_MOVE_LEFT  = 0x04, /*!< Gesture Move Left */
+	GEST_ID_ZOOM_IN    = 0x05, /*!< Gesture Zoom In */
+	GEST_ID_ZOOM_OUT   = 0x06, /*!< Gesture Zoom Out */
+	GEST_ID_NB_MAX     = 0x07  /*!< max number of gesture id */
+} TS_GestureIdTypeDef;
+
+/**
+ *  @brief TS_TouchEventTypeDef
+ *  Define Possible touch events kind as returned values
+ *  by touch screen IC Driver.
+ */
+typedef enum
+{
+	TOUCH_EVENT_NO_EVT        = 0x00, /*!< Touch Event : undetermined */
+	TOUCH_EVENT_PRESS_DOWN    = 0x01, /*!< Touch Event Press Down */
+	TOUCH_EVENT_LIFT_UP       = 0x02, /*!< Touch Event Lift Up */
+	TOUCH_EVENT_CONTACT       = 0x03, /*!< Touch Event Contact */
+	TOUCH_EVENT_NB_MAX        = 0x04  /*!< max number of touch events kind */
+} TS_TouchEventTypeDef;
+
+/**
+ *  @brief Table for touchscreen event information display on LCD :
+ *  table indexed on enum @ref TS_TouchEventTypeDef information
+ */
+extern char * ts_event_string_tab[TOUCH_EVENT_NB_MAX];
+
+/**
+ *  @brief Table for touchscreen gesture Id information display on LCD : table indexed
+ *  on enum @ref TS_GestureIdTypeDef information
+ */
+extern char * ts_gesture_id_string_tab[GEST_ID_NB_MAX];
+
+extern ER touchscreen_init(TouchScreen_Handle_t *hts, uint16_t ts_SizeX, uint16_t ts_SizeY, uint8_t orientation);
+extern ER touchscreen_getstate(TouchScreen_Handle_t *hts, TS_StateTypeDef *TS_State);
+extern ER touchscreen_reset_data(TS_StateTypeDef *TS_State);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _STTS_FT5336_H_ */
+
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/usb_device/Makefile.config
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/usb_device/Makefile.config	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/usb_device/Makefile.config	(revision 457)
@@ -0,0 +1,55 @@
+#
+#   TOPPERS/ASP/FMP Kernel
+#       Toyohashi Open Platform for Embedded Real-Time Systems/
+#       Advanced Standard Profile Kernel
+#
+#   Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
+#                               Toyohashi Univ. of Technology, JAPAN
+#   Copyright (C) 2003-2008 by Ryosuke Takeuchi
+#                Platform Development Center RICOH COMPANY,LTD. JAPAN
+#   Copyright (C) 2015-2017 by TOPPERS PROJECT Educational Working Group.
+#
+#   上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+#   によって公表されている GNU General Public License の Version 2 に記
+#   述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+#   を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+#   利用と呼ぶ）することを無償で許諾する．
+#   (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+#       権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+#       スコード中に含まれていること．
+#   (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+#       用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+#       者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+#       の無保証規定を掲載すること．
+#   (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+#       用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+#       と．
+#     (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+#         作権表示，この利用条件および下記の無保証規定を掲載すること．
+#     (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+#         報告すること．
+#   (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+#       害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+#
+#   本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+#   よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+#   含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+#   接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+#
+#  @(#) $Id$
+#
+ 
+#
+#  Makefile のプロセッサ依存 (usb_device用)
+#
+
+#
+#  コンパイルオプション
+#
+INCLUDES := $(INCLUDES) -I$(SRCDIR)/gdic/usb_device
+
+#
+#  USB DEVICE(GDIC)に関する定義
+#
+SYSSVC_DIR := $(SYSSVC_DIR):$(SRCDIR)/gdic/usb_device
+SYSSVC_COBJS := $(SYSSVC_COBJS) usb_device_driver.o
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/usb_device/tusbd_conf.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/usb_device/tusbd_conf.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/usb_device/tusbd_conf.h	(revision 457)
@@ -0,0 +1,94 @@
+/*
+ *  TOPPERS BASE PLATFORM MIDDLEWARE
+ * 
+ *  Copyright (C) 2017-2017 by TOPPERS PROJECT
+ *                             Educational Working Group.
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+/*
+ *  TOPPERS USB DEVICE MODULE CONFIGURATION インクルードファイル
+ */
+
+#ifndef _TUSBD_CONF_H_
+#define _TUSBD_CONF_H_
+
+#include "usb_device_driver.h"
+
+#define TUSBD_MAX_NUM_INTERFACES              1
+#define TUSBD_MAX_NUM_CONFIGURATION           1
+#define TUSBD_NUM_ENDPOINT                    15
+#define TUSBD_CONFIG_SELF_POWERED             0x01
+
+#define USBD_StatusTypeDef   TUSBD_ERCODE
+#define USBD_HandleTypeDef   TUSBD_Handle_t
+#define USBD_Init            tusbdInit
+#define USBD_Start           tusbdStart
+
+extern uint8_t defaultDeviceDescriptor[];
+extern uint8_t defaultDeviceQualifierDescriptor[];
+extern uint8_t defaultLanguageIDDescriptor[];
+extern uint8_t defaultManufacturerString[];
+extern uint8_t defaultProductString[];
+extern uint8_t defaultSerialString[];
+extern uint8_t defaultConfigurationString[];
+extern uint8_t defaultInterfaceString[];
+
+#define TUSBD_DEVICE_DESCRIPTOR               defaultDeviceDescriptor
+#define TUSBD_DEVICE_QUALIFIER_DESCRIPTOR     defaultDeviceQualifierDescriptor
+#define TUSBD_LANGUAGEID_DESCRIPTOR           defaultLanguageIDDescriptor
+#define TUSBD_MANUFACTURER_STRING             defaultManufacturerString
+#define TUSBD_PRODUCT_STRING                  defaultProductString
+#define TUSBD_SERIAL_STRING                   defaultSerialString
+#define TUSBD_CONFIGURATION_STRING            defaultConfigurationString
+#define TUSBD_INTERFACE_STRING                defaultInterfaceString
+#define TUSBD_USER_STRING                     NULL
+
+#define tusbdDriverSetUSBAddress(d, a)  usbd_setDevAddress(((d)->pSysData), (a))
+#define tusbdDriverGetRxDataSize        usb_device_getrxdatasize
+
+#define tusbdDriverInit                 usb_device_init
+#define tusbdDriverDeInit               usb_device_deinit
+#define tusbdDriverStart                usb_device_start
+#define tusbdDriverStop                 usb_device_stop
+#define tusbdDriverOpenEp               usb_device_openep
+#define tusbdDriverCloseEp              usb_device_closeep
+#define tusbdDriverFlushEp              usb_device_flushep
+#define tusbdDriverStallEp              usb_device_stallep
+#define tusbdDriverClearStallEp         usb_device_clearep
+#define tusbdDriverStallConditionEp     usb_device_getstallcondition
+#define tusbdDriverStartTransmit        usb_device_transmitdata
+#define tusbdDriverSetupReceive         usb_device_startreceive
+#define tusbdDriverTestMode             usb_device_testmode
+
+#endif /* _TUSBD_CONF_H_ */
+
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/usb_device/usb_device_driver.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/usb_device/usb_device_driver.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/usb_device/usb_device_driver.c	(revision 457)
@@ -0,0 +1,498 @@
+/*
+ *  TOPPERS BASE PLATFORM MIDDLEWARE
+ * 
+ *  Copyright (C) 2017-2019 by TOPPERS PROJECT
+ *                             Educational Working Group.
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+/*
+ *  USB DEVICE HIGH DRIVERS
+ */
+
+#include "kernel_impl.h"
+#include <t_syslog.h>
+#include <t_stdlib.h>
+#include <sil.h>
+#include <target_syssvc.h>
+#include "device.h"
+
+#include "stdlib.h"
+#include "tusbd_base.h"
+#include "usb_device.h"
+
+
+#define sil_orw_mem(a, b)		sil_wrw_mem((a), sil_rew_mem(a) | (b))
+#define sil_andw_mem(a, b)		sil_wrw_mem((a), sil_rew_mem(a) & ~(b))
+#define sil_orh_mem(a, b)		sil_wrh_mem((a), sil_reh_mem(a) | (b))
+#define sil_andh_mem(a, b)		sil_wrh_mem((a), sil_reh_mem(a) & ~(b))
+
+#ifndef MAX_DEVICE_EPS
+#define MAX_DEVICE_EPS          (MAX_EPS_CHANNELS-1)
+#endif
+
+/*
+ *  SETUPSTAGE CALLBACK関数
+ */
+static void
+tusbdSetupStageCallback(USB_DEV_Handle_t *husb)
+{
+	tusbdSetupStage(husb->pDev, (uint8_t *)husb->Setup);
+}
+
+/*
+ *  DATAOUTSTAGE CALLBACK関数
+ */
+static void
+tusbdDataOutStageCallback(USB_DEV_Handle_t *husb, uint8_t epnum)
+{
+	tusbdDataOutStage(husb->pDev, epnum, husb->OUT_ep[epnum].xfer_buff);
+}
+
+/*
+ *  DATAINSTAGE CALLBACK関数
+ */
+static void
+tusbdDataInStageCallback(USB_DEV_Handle_t *husb, uint8_t epnum)
+{
+	tusbdDataInStage(husb->pDev, epnum, husb->IN_ep[epnum].xfer_buff);
+}
+
+/*
+ *  DEVICE RESET CALLBACK関数
+ */
+static void
+tusbdResetCallback(USB_DEV_Handle_t *husb)
+{
+	uint8_t speed = USB_DEVICE_SPEED_FULL;
+
+	/* Set USB Current Speed */
+	switch(husb->Init.speed){
+	case USB_SPEED_HIGH:
+		speed = USB_DEVICE_SPEED_HIGH;
+		break;
+	case USB_SPEED_FULL:
+		speed = USB_DEVICE_SPEED_FULL;
+		break;
+	default:
+		speed = USB_DEVICE_SPEED_FULL;
+		break;
+	}
+
+	/*
+	 *  DEVICEのリセット
+	 */
+	tusbdReset(husb->pDev);
+	tusbdSetSpeed(husb->pDev, speed);
+}
+
+/*
+ *  DEVICE SUSPEND CALLBACK関数
+ */
+static void
+tusbdSuspendCallback(USB_DEV_Handle_t *husb)
+{
+	tusbdSuspend(husb->pDev);
+#if 1	/* ROI DEBUG */
+	syslog_0(LOG_NOTICE, "## tusbdSuspendCallback ##");
+#endif
+  /*Enter in STOP mode */
+	if (husb->Init.low_power_enable){
+		/* Set SLEEPDEEP bit and SleepOnExit of Cortex System Control Register */
+		sil_orw_mem((uint32_t *)(TADR_SCB_BASE+TOFF_SCB_SCR), (SCB_SCR_SLEEPDEEP_Msk | SCB_SCR_SLEEPONEXIT_Msk));
+	}
+}
+
+/*
+ *  DEVICE RESUME CALLBACK関数
+ */
+static void
+tusbdResumeCallback(USB_DEV_Handle_t *husb)
+{
+	TUSBD_Handle_t *pdevice = husb->pDev;
+	if(husb->Init.low_power_enable && pdevice->dev_state == TUSBD_STATE_SUSPENDED){
+		/* Reset SLEEPDEEP bit of Cortex System Control Register */
+		sil_andw_mem((uint32_t *)(TADR_SCB_BASE+TOFF_SCB_SCR), (SCB_SCR_SLEEPDEEP_Msk | SCB_SCR_SLEEPONEXIT_Msk));
+		sysclock_config(1);
+	}
+	tusbdResume(husb->pDev);
+#if 1	/* ROI DEBUG */
+	syslog_0(LOG_NOTICE, "## tusbdResumeCallback ##");
+#endif
+}
+
+/*
+ *  DEVICE CONNECT CALLBACK関数
+ */
+static void
+tusbdConnectCallback(USB_DEV_Handle_t *husb)
+{
+	tusbdDeviceConnected(husb->pDev);
+}
+
+/*
+ *  DEVICE DISCONNECT CALLBACK関数
+ */
+static void
+tusbdDisconnectCallback(USB_DEV_Handle_t *husb)
+{
+	tusbdDeviceDisconnected(husb->pDev);
+}
+
+/*
+ *  ENDPOINT取得
+ */
+static USB_DEV_EPTypeDef *
+tusbdGetEndpoint(USB_DEV_Handle_t *husb, uint8_t addr)
+{
+	USB_DEV_EPTypeDef *ep;
+
+	if((addr & USB_DEVICE_TO_HOST) != 0){
+		ep = &husb->IN_ep[addr & 0x7F];
+	}
+	else{
+		ep = &husb->OUT_ep[addr & 0x7F];
+	}
+	ep->num   = addr & 0x7F;
+	ep->is_in = (USB_DEVICE_TO_HOST & addr) != 0;
+	return ep;
+}
+
+
+/*
+ *  USB_DEVICE HIGH DRIVER INITIALIZE
+ *  parameter1 pdevice:  USBデバイスハンドラ
+ *  return     TUSBD_ERCODE
+ */
+TUSBD_ERCODE
+usb_device_init(TUSBD_Handle_t *pdevice)
+{
+	USB_DEV_Handle_t *husb = (USB_DEV_Handle_t *)(pdevice->pSysData);
+	uint32_t i = 0;
+
+	/*
+	 *  USBハンドラに、USBデバイスハンドラをセット
+	 */
+	husb->pDev = pdevice;
+
+	/*
+	 *  コールバック関数をセット
+	 */
+	husb->devsetupstagecallback   = tusbdSetupStageCallback;
+	husb->devdataoutstagecallback = tusbdDataOutStageCallback;
+	husb->devdatainstagecallback  = tusbdDataInStageCallback;
+	husb->devsofcallback          = NULL;
+	husb->devresetcallback        = tusbdResetCallback;
+	husb->devsuspendcallback      = tusbdSuspendCallback;
+	husb->devresumecallback       = tusbdResumeCallback;
+	husb->devconnectcallback      = tusbdConnectCallback;
+	husb->devdisconnectcallback   = tusbdDisconnectCallback;
+	husb->devlpmcallback          = NULL;
+
+	/*
+	 *  エンドポイントの初期化
+	 */
+	for(i = 0 ; i < MAX_DEVICE_EPS ; i++){
+		husb->IN_ep[i].is_in = 1;
+		husb->IN_ep[i].num = i;
+		husb->IN_ep[i].type = EP_TYPE_CTRL;
+		husb->IN_ep[i].maxpacket = 0;
+		husb->IN_ep[i].xfer_buff = 0;
+		husb->IN_ep[i].xfer_len = 0;
+
+		husb->OUT_ep[i].is_in = 0;
+		husb->OUT_ep[i].num = i;
+ 		husb->OUT_ep[i].type = EP_TYPE_CTRL;
+		husb->OUT_ep[i].maxpacket = 0;
+		husb->OUT_ep[i].xfer_buff = 0;
+		husb->OUT_ep[i].xfer_len = 0;
+	}
+
+	/*
+	 *  LPMの有効化
+	 */
+	usbd_init_lpm(husb);
+	usbd_init_BCD(husb);
+
+	usbd_setupPMA(husb , 0x00 , PCD_SNG_BUF, 0x18);
+	usbd_setupPMA(husb , 0x80 , PCD_SNG_BUF, 0x58);
+	usbd_setupPMA(husb , 0x81 , PCD_SNG_BUF, 0x98);
+	usbd_setupPMA(husb , 0x82 , PCD_SNG_BUF, 0xD8);
+	return TUSBD_E_OK;
+}
+
+/*
+ *  USB_DEVICE HIGH DRIVER DE-INITIALIZE
+ *  parameter1 pdevice:  USBデバイスハンドラ
+ *  return     TUSBD_ERCODE
+  */
+TUSBD_ERCODE
+usb_device_deinit(TUSBD_Handle_t *pdevice)
+{
+	/*
+	 *  デバイス停止
+	 */
+	usb_device_stop(pdevice);
+
+	/*
+	 *  デバイスハードウェア終了
+	 */
+	usbd_deinit(pdevice->pSysData);
+	return TUSBD_E_OK;
+}
+
+/*
+ *  USB DEVICE HIGH DRIVER START
+ *  parameter1 pdevice:  USBデバイスハンドラ
+ *  return     TUSBD_ERCODE
+  */
+TUSBD_ERCODE
+usb_device_start(TUSBD_Handle_t *pdevice)
+{
+	usbd_devconnect(pdevice->pSysData);
+	return TUSBD_E_OK;
+}
+
+/*
+ *  USB DEVICE HIGH DRIVER STOP
+ *  parameter1 pdevice:  USBデバイスハンドラ
+ *  return     TUSBD_ERCODE
+  */
+TUSBD_ERCODE
+usb_device_stop(TUSBD_Handle_t *pdevice)
+{
+	usbd_devdisconnect(pdevice->pSysData);
+	return TUSBD_E_OK;
+}
+
+/*
+ *  USB DEVICE HIGH DRIVER OPEN ENDPOINT
+ *  parameter1 pdevice:  USBデバイスハンドラ
+ *  parameter2 addr:  endpointアドレス
+ *  parameter3 type:  endpointタイプ
+ *  parameter4 mps:   MAX PACKET SIZE
+ *  return     TUSBD_ERCODE
+ */
+TUSBD_ERCODE
+usb_device_openep(TUSBD_Handle_t *pdevice, uint8_t addr, uint8_t type, uint16_t mps)
+{
+	USB_DEV_Handle_t  *husb = pdevice->pSysData;
+	USB_DEV_EPTypeDef *ep;
+
+	ep = tusbdGetEndpoint(husb, addr);
+	ep->maxpacket = mps;
+	ep->type = type;
+	usbd_activateEndpoint(husb, ep);
+	return TUSBD_E_OK;
+}
+
+/*
+ *  USB DEVICE HIGH DRIVER CLOSE ENDPOINT
+ *  parameter1 pdevice:  USBデバイスハンドラ
+ *  parameter2 addr:  endpointアドレス
+ *  return     TUSBD_ERCODE
+ */
+TUSBD_ERCODE
+usb_device_closeep(TUSBD_Handle_t *pdevice, uint8_t addr)
+{
+	USB_DEV_Handle_t  *husb = pdevice->pSysData;
+	USB_DEV_EPTypeDef *ep;
+
+	ep = tusbdGetEndpoint(husb, addr);
+	usbd_deactivateEndpoint(husb, ep);
+	return TUSBD_E_OK;
+}
+
+/*
+ *  USB DEVICE HIGH DRIVER FLUSH ENDPOINT
+ *  parameter1 pdevice:  USBデバイスハンドラ
+ *  parameter2 addr:  endpointアドレス
+ *  return     TUSBD_ERCODE
+ */
+TUSBD_ERCODE
+usb_device_flushep(TUSBD_Handle_t *pdevice, uint8_t addr)
+{
+	return TUSBD_E_OK;
+}
+
+/*
+ *  USB DEVICE HIGH DRIVER STALL ENDPOINT
+ *  parameter1 pdevice:  USBデバイスハンドラ
+ *  parameter2 addr:  endpointアドレス
+ *  return     TUSBD_ERCODE
+ */
+TUSBD_ERCODE
+usb_device_stallep(TUSBD_Handle_t *pdevice, uint8_t addr)
+{
+	USB_DEV_Handle_t  *husb = pdevice->pSysData;
+	USB_DEV_EPTypeDef *ep;
+
+	ep = tusbdGetEndpoint(husb, addr);
+	ep->is_stall = 1;
+
+	usbd_epsetStall(husb, ep);
+	return TUSBD_E_OK;
+}
+
+/*
+ *  USB DEVICE HIGH DRIVER CLEAR STALL-ENDPOINT
+ *  parameter1 pdevice:  USBデバイスハンドラ
+ *  parameter2 addr:  endpointアドレス
+ *  return     TUSBD_ERCODE
+ */
+TUSBD_ERCODE
+usb_device_clearep(TUSBD_Handle_t *pdevice, uint8_t addr)
+{
+	USB_DEV_Handle_t *husb = pdevice->pSysData;
+	USB_DEV_EPTypeDef *ep;
+
+	ep = tusbdGetEndpoint(husb, addr);
+	ep->is_stall = 0;
+
+	usbd_epclearStall(husb, ep);
+	return TUSBD_E_OK; 
+}
+
+/*
+ *  USB DEVICE HIGH DRIVER GET STALL CONDITION
+ *  parameter1 pdevice:  USBデバイスハンドラ
+ *  parameter2 addr:  endpointアドレス
+ *  return     1:stall 0:not stall
+ */
+uint8_t
+usb_device_getstallcondition(TUSBD_Handle_t *pdevice, uint8_t addr)
+{
+	USB_DEV_Handle_t *husb = pdevice->pSysData;
+
+	if((addr & USB_DEVICE_TO_HOST) != 0)
+		return husb->IN_ep[addr & 0x7F].is_stall;
+	else
+		return husb->OUT_ep[addr & 0x7F].is_stall;
+}
+
+/*
+ *  USB DEVICE HIGH DRIVER TRANSMIT A DATA
+ *  parameter1 pdevice:  USBデバイスハンドラ
+ *  parameter2 addr:  endpointアドレス
+ *  parameter3 pbuf:  送信データバッファ
+ *  parameter4 size:  送信サイズ
+ *  return     TUSBD_ERCODE
+ */
+TUSBD_ERCODE
+usb_device_transmitdata(TUSBD_Handle_t *pdevice, uint8_t addr, uint8_t *pbuf, uint16_t size)
+{
+	USB_DEV_Handle_t  *husb = pdevice->pSysData;
+	USB_DEV_EPTypeDef *ep;
+
+	ep = tusbdGetEndpoint(husb, (addr | USB_DEVICE_TO_HOST));
+
+	/*
+	 *  送信データ設定
+	 */
+	ep->xfer_buff = pbuf;
+	ep->xfer_len = size;
+	ep->xfer_count = 0;
+	usbd_epstartsend(husb, ep);
+	return TUSBD_E_OK;
+}
+
+/*
+ *  USB DEVICE HIGH DRIVER START to RECEIVE
+ *  parameter1 pdevice:  USBデバイスハンドラ
+ *  parameter2 addr:  endpointアドレス
+ *  parameter3 pbuf:  受信データバッファ
+ *  parameter4 size:  受信サイズ
+ *  return     TUSBD_ERCODE
+ */
+TUSBD_ERCODE
+usb_device_startreceive(TUSBD_Handle_t *pdevice, uint8_t addr, uint8_t *pbuf, uint16_t size)
+{
+	USB_DEV_Handle_t  *husb = pdevice->pSysData;
+	USB_DEV_EPTypeDef *ep;
+
+	ep = tusbdGetEndpoint(husb, (addr & ~USB_DEVICE_TO_HOST));
+
+	/*
+	 *  受信データ設定
+	 */
+	ep->xfer_buff = pbuf;
+	ep->xfer_len = size;
+	ep->xfer_count = 0;
+	usbd_epstartreceive(husb, ep);
+	return TUSBD_E_OK;
+}
+
+/*
+ *  USB DEVICE HIGH DRIVER TEST MODE
+ *  parameter1 pdevice:  USBデバイスハンドラ
+ *  return     TUSBD_ERCODE
+ */
+TUSBD_ERCODE
+usb_device_testmode(TUSBD_Handle_t *pdevice)
+{
+	return TUSBD_E_OK;
+}
+
+/*
+ *  USB DEVICE HIGH DRIVER REMOTE WAKEUP
+ *  parameter1 pdevice:  USBデバイスハンドラ
+ *  return     TUSBD_ERCODE
+ */
+void
+usb_device_wakeup(USBD_HandleTypeDef *pdevice)
+{
+	USB_DEV_Handle_t *husb = pdevice->pSysData;
+
+	if(pdevice->dev_remote_wakeup == 1 && pdevice->dev_state == TUSBD_STATE_SUSPENDED){
+		if(husb->Init.low_power_enable){
+			/* Reset SLEEPDEEP bit of Cortex System Control Register */
+			sil_andw_mem((uint32_t *)(TADR_SCB_BASE+TOFF_SCB_SCR), (SCB_SCR_SLEEPDEEP_Msk | SCB_SCR_SLEEPONEXIT_Msk));
+			sysclock_config(1);
+		}
+		/* Activate Remote wakeup */
+		if(husb->Init.lpm_enable == 1)	/* Apply L1 Resume */
+			sil_orh_mem((uint16_t *)(husb->base+TOFF_USB_CNTR), USB_CNTR_L1RESUME);
+		else	/* Apply L2 Resume */
+		sil_orh_mem((uint16_t *)(husb->base+TOFF_USB_CNTR), USB_CNTR_RESUME);
+
+		/* Remote wakeup delay */
+		sil_dly_nse(10*1000*1000);
+
+		if(husb->Init.lpm_enable == 1)	/* Release L1 Resume */
+			sil_andh_mem((uint16_t *)(husb->base+TOFF_USB_CNTR), USB_CNTR_L1RESUME);
+		else		/* Release L2 Resume */
+			sil_andh_mem((uint16_t *)(husb->base+TOFF_USB_CNTR), USB_CNTR_RESUME);
+		/* Change remote_wakeup feature to 0*/
+		pdevice->dev_remote_wakeup = 0;
+	}
+}
+
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/usb_device/usb_device_driver.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/usb_device/usb_device_driver.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/usb_device/usb_device_driver.h	(revision 457)
@@ -0,0 +1,78 @@
+/*
+ *  TOPPERS BASE PLATFORM MIDDLEWARE
+ * 
+ *  Copyright (C) 2017-2017 by TOPPERS PROJECT
+ *                             Educational Working Group.
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+/*
+ *  STM USB DEVICE HIGH DRIVER インクルードファイル
+ */
+
+
+#ifndef _USB_DEVICE_DRIVER_H_
+#define _USB_DEVICE_DRIVER_H_
+
+#include "tusb_rtos.h"
+#include "usb_device.h"
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+#define usb_device_getrxdatasize(d, a)  (((USB_DEV_Handle_t *)((d)->pSysData))->OUT_ep[(a) & 0x7F].xfer_count)
+
+/*
+ *  STM USB DEVICE HIGH DRIVER関数プロトタイプ宣言
+ */
+extern TUSBD_ERCODE usb_device_init(TUSBD_Handle_t *pdevice);
+extern TUSBD_ERCODE usb_device_deinit(TUSBD_Handle_t *pdevice);
+extern TUSBD_ERCODE usb_device_start(TUSBD_Handle_t *pdevice);
+extern TUSBD_ERCODE usb_device_stop(TUSBD_Handle_t *pdevice);
+extern TUSBD_ERCODE usb_device_openep(TUSBD_Handle_t *pdevice, uint8_t addr, uint8_t type, uint16_t mps);
+extern TUSBD_ERCODE usb_device_closeep(TUSBD_Handle_t *pdevice, uint8_t addr);
+extern TUSBD_ERCODE usb_device_flushep(TUSBD_Handle_t *pdevice, uint8_t addr);
+extern TUSBD_ERCODE usb_device_stallep(TUSBD_Handle_t *pdevice, uint8_t addr);
+extern TUSBD_ERCODE usb_device_clearep(TUSBD_Handle_t *pdevice, uint8_t addr);
+extern uint8_t      usb_device_getstallcondition(TUSBD_Handle_t *pdevice, uint8_t addr);
+extern TUSBD_ERCODE usb_device_transmitdata(TUSBD_Handle_t *pdevice, uint8_t addr, uint8_t *pbuf, uint16_t size);
+extern TUSBD_ERCODE usb_device_startreceive(TUSBD_Handle_t *pdevice, uint8_t addr, uint8_t *pbuf, uint16_t size);
+extern TUSBD_ERCODE usb_device_testmode(TUSBD_Handle_t *pdevice);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _USB_DEVICE_DRIVER_H_ */
+
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/usb_otg/Makefile.config
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/usb_otg/Makefile.config	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/usb_otg/Makefile.config	(revision 457)
@@ -0,0 +1,63 @@
+#
+#   TOPPERS/ASP/FMP Kernel
+#       Toyohashi Open Platform for Embedded Real-Time Systems/
+#       Advanced Standard Profile Kernel
+#
+#   Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
+#                               Toyohashi Univ. of Technology, JAPAN
+#   Copyright (C) 2003-2008 by Ryosuke Takeuchi
+#                Platform Development Center RICOH COMPANY,LTD. JAPAN
+#   Copyright (C) 2015-2017 by TOPPERS PROJECT Educational Working Group.
+#
+#   上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+#   によって公表されている GNU General Public License の Version 2 に記
+#   述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+#   を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+#   利用と呼ぶ）することを無償で許諾する．
+#   (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+#       権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+#       スコード中に含まれていること．
+#   (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+#       用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+#       者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+#       の無保証規定を掲載すること．
+#   (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+#       用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+#       と．
+#     (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+#         作権表示，この利用条件および下記の無保証規定を掲載すること．
+#     (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+#         報告すること．
+#   (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+#       害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+#
+#   本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+#   よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+#   含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+#   接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+#
+#  @(#) $Id$
+#
+ 
+#
+#  Makefile のプロセッサ依存 (usb_otg:dwc2用)
+#
+
+#
+#  コンパイルオプション
+#
+INCLUDES := $(INCLUDES) -I$(SRCDIR)/gdic/usb_otg
+
+#
+#  USB OTG(GDIC)に関する定義
+#
+SYSSVC_DIR := $(SYSSVC_DIR):$(SRCDIR)/gdic/usb_otg
+ifneq ($(USB_OTG_MODE),USB_OTG_MODE_DEVICE)
+ifneq ($(USB_OTG_MODE),)
+SYSSVC_COBJS := $(SYSSVC_COBJS) dwc2_host_driver.o
+endif
+endif
+ifneq ($(USB_OTG_MODE),USB_OTG_MODE_HOST)
+SYSSVC_COBJS := $(SYSSVC_COBJS) dwc2_device_driver.o
+endif
+
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/usb_otg/dwc2_device_driver.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/usb_otg/dwc2_device_driver.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/usb_otg/dwc2_device_driver.c	(revision 457)
@@ -0,0 +1,559 @@
+/*
+ *  TOPPERS BASE PLATFORM MIDDLEWARE
+ * 
+ *  Copyright (C) 2017-2018 by TOPPERS PROJECT
+ *                             Educational Working Group.
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+/*
+ *  USB DEVICE HIGH DRIVERS
+ */
+
+#include "kernel_impl.h"
+#include <t_syslog.h>
+#include <t_stdlib.h>
+#include <sil.h>
+#include <target_syssvc.h>
+#include "device.h"
+
+#include "stdlib.h"
+#include "tusbd_base.h"
+#include "usb_otg.h"
+
+#define sil_orw_mem(a, b)		sil_wrw_mem((a), sil_rew_mem(a) | (b))
+#define sil_andw_mem(a, b)		sil_wrw_mem((a), sil_rew_mem(a) & ~(b))
+
+#ifndef MAX_DEVICE_EPS
+#define MAX_DEVICE_EPS          (MAX_EPS_CHANNELS-1)
+#endif
+
+/*
+ *  SETUPSTAGE CALLBACK関数
+ */
+static void
+tusbdSetupStageCallback(USB_OTG_Handle_t *husb)
+{
+	tusbdSetSpeed(husb->pDev, usbo_getDevSpeed(husb));
+	tusbdSetupStage(husb->pDev, (uint8_t *)husb->Setup);
+}
+
+/*
+ *  DATAOUTSTAGE CALLBACK関数
+ */
+static void
+tusbdDataOutStageCallback(USB_OTG_Handle_t *husb, uint8_t epnum)
+{
+	tusbdDataOutStage(husb->pDev, epnum, husb->OUT_ep[epnum].xfer_buff);
+}
+
+/*
+ *  DATAINSTAGE CALLBACK関数
+ */
+static void
+tusbdDataInStageCallback(USB_OTG_Handle_t *husb, uint8_t epnum)
+{
+	tusbdDataInStage(husb->pDev, epnum, husb->IN_ep[epnum].xfer_buff);
+}
+
+/*
+ *  DEVICE RESET CALLBACK関数
+ */
+static void
+tusbdResetCallback(USB_OTG_Handle_t *husb)
+{
+	uint8_t speed = USB_DEVICE_SPEED_FULL;
+
+	/* Set USB Current Speed */
+	switch(husb->Init.speed){
+	case USB_SPEED_HIGH:
+		speed = USB_DEVICE_SPEED_HIGH;
+		break;
+	case USB_SPEED_FULL:
+		speed = USB_DEVICE_SPEED_FULL;
+		break;
+	default:
+		speed = USB_DEVICE_SPEED_FULL;
+		break;
+	}
+
+	/*
+	 *  DEVICEのリセット
+	 */
+	tusbdReset(husb->pDev);
+	tusbdSetSpeed(husb->pDev, speed);
+}
+
+/*
+ *  DEVICE SUSPEND CALLBACK関数
+ */
+static void
+tusbdSuspendCallback(USB_OTG_Handle_t *husb)
+{
+	tusbdSuspend(husb->pDev);
+#if 1	/* ROI DEBUG */
+	syslog_0(LOG_NOTICE, "## tusbdSuspendCallback ##");
+#endif
+}
+
+/*
+ *  DEVICE RESUME CALLBACK関数
+ */
+static void
+tusbdResumeCallback(USB_OTG_Handle_t *husb)
+{
+	tusbdResume(husb->pDev);
+#if 1	/* ROI DEBUG */
+	syslog_0(LOG_NOTICE, "## tusbdResumeCallback ##");
+#endif
+}
+
+/*
+ *  ISOOUTCOMPLETE CALLBACK関数
+ */
+static void
+tusbdISOOUTIncompleteCallback(USB_OTG_Handle_t *husb, uint8_t epnum)
+{
+	tusbdIsoOutIncomplete(husb->pDev, epnum);
+}
+
+/*
+ *  ISOINCOMPLETE CALLBACK関数
+ */
+static void
+tusbdISOINIncompleteCallback(USB_OTG_Handle_t *husb, uint8_t epnum)
+{
+	tusbdIsoInIncomplete(husb->pDev, epnum);
+}
+
+/*
+ *  DEVICE CONNECT CALLBACK関数
+ */
+static void
+tusbdConnectCallback(USB_OTG_Handle_t *husb)
+{
+	tusbdDeviceConnected(husb->pDev);
+}
+
+/*
+ *  DEVICE DISCONNECT CALLBACK関数
+ */
+static void
+tusbdDisconnectCallback(USB_OTG_Handle_t *husb)
+{
+	tusbdDeviceDisconnected(husb->pDev);
+}
+
+/*
+ *  ENDPOINT取得
+ */
+static USB_OTG_EPTypeDef *
+tusbdGetEndpoint(USB_OTG_Handle_t *husb, uint8_t addr)
+{
+	USB_OTG_EPTypeDef *ep;
+
+	if((addr & USB_DEVICE_TO_HOST) != 0){
+		ep = &husb->IN_ep[addr & 0x7F];
+	}
+	else{
+		ep = &husb->OUT_ep[addr & 0x7F];
+	}
+	ep->num   = addr & 0x7F;
+	ep->is_in = (USB_DEVICE_TO_HOST & addr) != 0;
+	return ep;
+}
+
+
+/*
+ *  USB_OTG DWC2 HIGH DRIVER INITIALIZE
+ *  parameter1 pdevice:  USBデバイスハンドラ
+ *  return     TUSBD_ERCODE
+ */
+TUSBD_ERCODE
+dwc2_device_init(TUSBD_Handle_t *pdevice)
+{
+	USB_OTG_Handle_t *husb = (USB_OTG_Handle_t *)(pdevice->pSysData);
+	uint32_t i = 0;
+
+	/*
+	 *  USBハンドラに、USBデバイスハンドラをセット
+	 */
+	husb->pDev = pdevice;
+
+	/*
+	 *  コールバック関数をセット
+	 */
+	husb->devsetupstagecallback   = tusbdSetupStageCallback;
+	husb->devdataoutstagecallback = tusbdDataOutStageCallback;
+	husb->devdatainstagecallback  = tusbdDataInStageCallback;
+	husb->devsofcallback          = NULL;
+	husb->devresetcallback        = tusbdResetCallback;
+	husb->devsuspendcallback      = tusbdSuspendCallback;
+	husb->devresumecallback       = tusbdResumeCallback;
+	husb->devisooutcallback       = tusbdISOOUTIncompleteCallback;
+	husb->devisoincallback        = tusbdISOINIncompleteCallback;
+	husb->devconnectcallback      = tusbdConnectCallback;
+	husb->devdisconnectcallback   = tusbdDisconnectCallback;
+	husb->devlpmcallback          = NULL;
+
+	/*
+	 *  エンドポイントの初期化
+	 */
+	for(i = 0 ; i < MAX_DEVICE_EPS ; i++){
+		husb->IN_ep[i].is_in = 1;
+		husb->IN_ep[i].num = i;
+		husb->IN_ep[i].tx_fifo_num = i;
+		husb->IN_ep[i].type = EP_TYPE_CTRL;
+		husb->IN_ep[i].maxpacket = 0;
+		husb->IN_ep[i].xfer_buff = 0;
+		husb->IN_ep[i].xfer_len = 0;
+
+		husb->OUT_ep[i].is_in = 0;
+		husb->OUT_ep[i].num = i;
+		husb->OUT_ep[i].tx_fifo_num = 0;
+ 		husb->OUT_ep[i].type = EP_TYPE_CTRL;
+		husb->OUT_ep[i].maxpacket = 0;
+		husb->OUT_ep[i].xfer_buff = 0;
+		husb->OUT_ep[i].xfer_len = 0;
+	}
+
+	/*
+	 *  USBデバイスの初期化
+	 */
+	usbo_devinit(husb);
+
+	/*
+	 *  LPMの有効化
+	 */
+	usbo_init_lpm(husb);
+	return TUSBD_E_OK;
+}
+
+/*
+ *  USB_OTG DWC2 HIGH DRIVER DE-INITIALIZE
+ *  parameter1 pdevice:  USBデバイスハンドラ
+ *  return     TUSBD_ERCODE
+  */
+TUSBD_ERCODE
+dwc2_device_deinit(TUSBD_Handle_t *pdevice)
+{
+	/*
+	 *  デバイス停止
+	 */
+	dwc2_device_stop(pdevice);
+
+	/*
+	 *  デバイスハードウェア終了
+	 */
+	usbo_deinit(pdevice->pSysData);
+	return TUSBD_E_OK;
+}
+
+/*
+ *  USB_OTG DWC2 HIGH DRIVER START
+ *  parameter1 pdevice:  USBデバイスハンドラ
+ *  return     TUSBD_ERCODE
+  */
+TUSBD_ERCODE
+dwc2_device_start(TUSBD_Handle_t *pdevice)
+{
+	usbo_devconnect(pdevice->pSysData);
+	dly_tsk(3);
+	usbo_enableglobalint(pdevice->pSysData);
+	return TUSBD_E_OK;
+}
+
+/*
+ *  USB_OTG DWC2 HIGH DRIVER STOP
+ *  parameter1 pdevice:  USBデバイスハンドラ
+ *  return     TUSBD_ERCODE
+  */
+TUSBD_ERCODE
+dwc2_device_stop(TUSBD_Handle_t *pdevice)
+{
+	usbo_disableglobalint(pdevice->pSysData);
+	usbo_stopdevice(pdevice->pSysData);
+	usbo_devdisconnect(pdevice->pSysData);
+	return TUSBD_E_OK;
+}
+
+/*
+ *  USB_OTG DWC2 HIGH DRIVER OPEN ENDPOINT
+ *  parameter1 pdevice:  USBデバイスハンドラ
+ *  parameter2 addr:  endpointアドレス
+ *  parameter3 type:  endpointタイプ
+ *  parameter4 mps:   MAX PACKET SIZE
+ *  return     TUSBD_ERCODE
+ */
+TUSBD_ERCODE
+dwc2_device_openep(TUSBD_Handle_t *pdevice, uint8_t addr, uint8_t type, uint16_t mps)
+{
+	USB_OTG_Handle_t  *husb = pdevice->pSysData;
+	USB_OTG_EPTypeDef *ep;
+
+	ep = tusbdGetEndpoint(husb, addr);
+	ep->maxpacket = mps;
+	ep->type = type;
+	if(ep->is_in){
+		/* 送信FIFO設定 */
+		ep->tx_fifo_num = ep->num;
+	}
+
+	/*
+	 *  DATA PIDの初期化
+	 */
+	if (type == EP_TYPE_BULK){
+		ep->data_pid_start = 0;
+	}
+
+	usbo_activateEndpoint(husb, ep);
+	return TUSBD_E_OK;
+}
+
+/*
+ *  USB_OTG DWC2 HIGH DRIVER CLOSE ENDPOINT
+ *  parameter1 pdevice:  USBデバイスハンドラ
+ *  parameter2 addr:  endpointアドレス
+ *  return     TUSBD_ERCODE
+ */
+TUSBD_ERCODE
+dwc2_device_closeep(TUSBD_Handle_t *pdevice, uint8_t addr)
+{
+	USB_OTG_Handle_t  *husb = pdevice->pSysData;
+	USB_OTG_EPTypeDef *ep;
+
+	ep = tusbdGetEndpoint(husb, addr);
+	usbo_deactivateEndpoint(husb, ep);
+	return TUSBD_E_OK;
+}
+
+/*
+ *  USB_OTG DWC2 HIGH DRIVER FLUSH ENDPOINT
+ *  parameter1 pdevice:  USBデバイスハンドラ
+ *  parameter2 addr:  endpointアドレス
+ *  return     TUSBD_ERCODE
+ */
+TUSBD_ERCODE
+dwc2_device_flushep(TUSBD_Handle_t *pdevice, uint8_t addr)
+{
+	USB_OTG_Handle_t *husb = pdevice->pSysData;
+
+	if((addr & USB_DEVICE_TO_HOST) != 0){
+		usbo_flushTxFifo(husb, addr & 0x7F);
+	}
+	else{
+		usbo_flushRxFifo(husb);
+	}
+	return TUSBD_E_OK;
+}
+
+/*
+ *  USB_OTG DWC2 HIGH DRIVER STALL ENDPOINT
+ *  parameter1 pdevice:  USBデバイスハンドラ
+ *  parameter2 addr:  endpointアドレス
+ *  return     TUSBD_ERCODE
+ */
+TUSBD_ERCODE
+dwc2_device_stallep(TUSBD_Handle_t *pdevice, uint8_t addr)
+{
+	USB_OTG_Handle_t  *husb = pdevice->pSysData;
+	USB_OTG_EPTypeDef *ep;
+
+	ep = tusbdGetEndpoint(husb, addr);
+	ep->is_stall = 1;
+
+	usbo_epsetStall(husb, ep);
+	if((addr & 0x7FU) == 0U){
+		usbo_ep0_outstart(husb, (uint8_t *)husb->Setup);
+	}
+	return TUSBD_E_OK;
+}
+
+/*
+ *  USB_OTG DWC2 HIGH DRIVER CLEAR STALL-ENDPOINT
+ *  parameter1 pdevice:  USBデバイスハンドラ
+ *  parameter2 addr:  endpointアドレス
+ *  return     TUSBD_ERCODE
+ */
+TUSBD_ERCODE
+dwc2_device_clearep(TUSBD_Handle_t *pdevice, uint8_t addr)
+{
+	USB_OTG_Handle_t *husb = pdevice->pSysData;
+	USB_OTG_EPTypeDef *ep;
+
+	ep = tusbdGetEndpoint(husb, addr);
+	ep->is_stall = 0;
+
+	usbo_epclearStall(husb, ep);
+	return TUSBD_E_OK; 
+}
+
+/*
+ *  USB_OTG DWC2 HIGH DRIVER GET STALL CONDITION
+ *  parameter1 pdevice:  USBデバイスハンドラ
+ *  parameter2 addr:  endpointアドレス
+ *  return     1:stall 0:not stall
+ */
+uint8_t
+dwc2_device_getstallcondition(TUSBD_Handle_t *pdevice, uint8_t addr)
+{
+	USB_OTG_Handle_t *husb = pdevice->pSysData;
+
+	if((addr & USB_DEVICE_TO_HOST) != 0)
+		return husb->IN_ep[addr & 0x7F].is_stall;
+	else
+		return husb->OUT_ep[addr & 0x7F].is_stall;
+}
+
+/*
+ *  USB_OTG DWC2 HIGH DRIVER TRANSMIT A DATA
+ *  parameter1 pdevice:  USBデバイスハンドラ
+ *  parameter2 addr:  endpointアドレス
+ *  parameter3 pbuf:  送信データバッファ
+ *  parameter4 size:  送信サイズ
+ *  return     TUSBD_ERCODE
+ */
+TUSBD_ERCODE
+dwc2_device_transmitdata(TUSBD_Handle_t *pdevice, uint8_t addr, uint8_t *pbuf, uint16_t size)
+{
+	USB_OTG_Handle_t  *husb = pdevice->pSysData;
+	USB_OTG_EPTypeDef *ep;
+
+	ep = tusbdGetEndpoint(husb, (addr | USB_DEVICE_TO_HOST));
+
+	/*
+	 *  送信データ設定
+	 */
+	ep->xfer_buff = pbuf;
+	ep->xfer_len = size;
+	ep->xfer_count = 0;
+
+	if(husb->Init.dma_enable == 1)
+		ep->dma_addr = (uint32_t)pbuf;
+
+	if((addr & 0x7F) == 0U){
+		usbo_ep0startxfer(husb, ep);
+	}
+	else{
+		usbo_epstartxfer(husb, ep);
+	}
+	return TUSBD_E_OK;
+}
+
+/*
+ *  USB_OTG DWC2 HIGH DRIVER START to RECEIVE
+ *  parameter1 pdevice:  USBデバイスハンドラ
+ *  parameter2 addr:  endpointアドレス
+ *  parameter3 pbuf:  受信データバッファ
+ *  parameter4 size:  受信サイズ
+ *  return     TUSBD_ERCODE
+ */
+TUSBD_ERCODE
+dwc2_device_startreceive(TUSBD_Handle_t *pdevice, uint8_t addr, uint8_t *pbuf, uint16_t size)
+{
+	USB_OTG_Handle_t  *husb = pdevice->pSysData;
+	USB_OTG_EPTypeDef *ep;
+
+	ep = tusbdGetEndpoint(husb, (addr & ~USB_DEVICE_TO_HOST));
+
+	/*
+	 *  受信データ設定
+	 */
+	ep->xfer_buff = pbuf;
+	ep->xfer_len = size;
+	ep->xfer_count = 0;
+
+	if(husb->Init.dma_enable == 1)
+		ep->dma_addr = (uint32_t)pbuf;
+
+	if((addr & 0x7F) == 0){
+		usbo_ep0startxfer(husb, ep);
+	}
+	else{
+		usbo_epstartxfer(husb, ep);
+	}
+	return TUSBD_E_OK;
+}
+
+/*
+ *  USB_OTG DWC2 HIGH DRIVER TEST MODE
+ *  parameter1 pdevice:  USBデバイスハンドラ
+ *  return     TUSBD_ERCODE
+ */
+TUSBD_ERCODE
+dwc2_device_testmode(TUSBD_Handle_t *pdevice)
+{
+	return TUSBD_E_OK;
+}
+
+#ifndef TOPPERS_MPCORE
+/*
+ *  USB_OTG DWC2 HIGH DRIVER REMOTE WAKEUP
+ *  parameter1 pdevice:  USBデバイスハンドラ
+ *  return     TUSBD_ERCODE
+ */
+void
+dwc2_device_wakeup(USBD_HandleTypeDef *pdevice)
+{
+	USB_OTG_Handle_t *husb = pdevice->pSysData;
+
+	if(pdevice->dev_remote_wakeup == 1 && pdevice->dev_state == TUSBD_STATE_SUSPENDED){
+		if(husb->Init.low_power_enable){
+			/* Reset SLEEPDEEP bit of Cortex System Control Register */
+			sil_andw_mem((uint32_t *)(TADR_SCB_BASE+TOFF_SCB_SCR), (SCB_SCR_SLEEPDEEP_Msk | SCB_SCR_SLEEPONEXIT_Msk));
+			sysclock_config(1);
+		}
+
+		/* Ungate PHY clock */
+		sil_andw_mem((uint32_t *)(USBPGC_BASE(husb->base)), USB_OTG_PCGCCTL_STOPCLK);
+
+		/* Activate Remote wakeup */
+		if((sil_rew_mem((uint32_t *)(USBD_BASE(husb->base)+TOFF_USBD_DSTS)) & USB_OTG_DSTS_SUSPSTS) != 0){
+			/* Activate Remote wakeup signaling */
+			sil_orw_mem((uint32_t *)(USBD_BASE(husb->base)+TOFF_USBD_DCTL), USB_OTG_DCTL_RWUSIG);
+		}
+
+		/* Remote wakeup delay */
+		sil_dly_nse(10*1000*1000);
+
+		/* Disable Remote wakeup */
+		sil_andw_mem((uint32_t *)(USBD_BASE(husb->base)+TOFF_USBD_DCTL), USB_OTG_DCTL_RWUSIG);
+
+		/* change state to configured */
+		pdevice->dev_state = TUSBD_STATE_CONFIGURED;
+
+		/* Change remote_wakeup feature to 0*/
+		pdevice->dev_remote_wakeup = 0;
+	}
+}
+#endif	/* TOPPERS_MPCORE */
+
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/usb_otg/dwc2_device_driver.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/usb_otg/dwc2_device_driver.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/usb_otg/dwc2_device_driver.h	(revision 457)
@@ -0,0 +1,78 @@
+/*
+ *  TOPPERS BASE PLATFORM MIDDLEWARE
+ * 
+ *  Copyright (C) 2017-2017 by TOPPERS PROJECT
+ *                             Educational Working Group.
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+/*
+ *  DWC2 DEVICE HIGH DRIVER インクルードファイル
+ */
+
+
+#ifndef _DWC2_DEVICE_DRIVER_H_
+#define _DWC2_DEVICE_DRIVER_H_
+
+#include "tusb_rtos.h"
+#include "usb_otg.h"
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+#define dwc2_device_getrxdatasize(d, a)  (((USB_OTG_Handle_t *)((d)->pSysData))->OUT_ep[(a) & 0x7F].xfer_count)
+
+/*
+ *  DWC2 DEVICE HIGH DRIVER関数プロトタイプ宣言
+ */
+extern TUSBD_ERCODE dwc2_device_init(TUSBD_Handle_t *pdevice);
+extern TUSBD_ERCODE dwc2_device_deinit(TUSBD_Handle_t *pdevice);
+extern TUSBD_ERCODE dwc2_device_start(TUSBD_Handle_t *pdevice);
+extern TUSBD_ERCODE dwc2_device_stop(TUSBD_Handle_t *pdevice);
+extern TUSBD_ERCODE dwc2_device_openep(TUSBD_Handle_t *pdevice, uint8_t addr, uint8_t type, uint16_t mps);
+extern TUSBD_ERCODE dwc2_device_closeep(TUSBD_Handle_t *pdevice, uint8_t addr);
+extern TUSBD_ERCODE dwc2_device_flushep(TUSBD_Handle_t *pdevice, uint8_t addr);
+extern TUSBD_ERCODE dwc2_device_stallep(TUSBD_Handle_t *pdevice, uint8_t addr);
+extern TUSBD_ERCODE dwc2_device_clearep(TUSBD_Handle_t *pdevice, uint8_t addr);
+extern uint8_t      dwc2_device_getstallcondition(TUSBD_Handle_t *pdevice, uint8_t addr);
+extern TUSBD_ERCODE dwc2_device_transmitdata(TUSBD_Handle_t *pdevice, uint8_t addr, uint8_t *pbuf, uint16_t size);
+extern TUSBD_ERCODE dwc2_device_startreceive(TUSBD_Handle_t *pdevice, uint8_t addr, uint8_t *pbuf, uint16_t size);
+extern TUSBD_ERCODE dwc2_device_testmode(TUSBD_Handle_t *pdevice);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _DWC2_DEVICE_DRIVER_H_ */
+
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/usb_otg/dwc2_host_driver.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/usb_otg/dwc2_host_driver.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/usb_otg/dwc2_host_driver.c	(revision 457)
@@ -0,0 +1,456 @@
+/*
+ *  TOPPERS BASE PLATFORM MIDDLEWARE
+ * 
+ *  Copyright (C) 2017-2018 by TOPPERS PROJECT
+ *                             Educational Working Group.
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+/*
+ *  USB HOST HIGH DRIVERS
+ */
+
+#include "tusbh_base.h"
+#include "kernel_cfg.h"
+#include "usb_otg.h"
+
+/*
+ *  URBの変換テーブル
+ */
+static const uint8_t urb_table[8] = {
+	TUSBH_URB_IDLE,
+	TUSBH_URB_DONE,
+	TUSBH_URB_NOTREADY,
+	TUSBH_URB_NYET,
+	TUSBH_URB_ERROR,
+	TUSBH_URB_STALL,
+	TUSBH_URB_ERROR,
+	TUSBH_URB_ERROR
+};
+
+/*
+ *  USB HOST CLASS リンク関数
+ */
+__attribute__((weak)) void tusbhLinkHID(TUSBH_Handle_t *phost)
+{
+}
+
+__attribute__((weak)) void tusbhLinkMSC(TUSBH_Handle_t *phost)
+{
+}
+
+__attribute__((weak)) void tusbhLinkSERIAL(TUSBH_Handle_t *phost)
+{
+}
+
+__attribute__((weak)) void tusbhLinkPRT(TUSBH_Handle_t *phost)
+{
+}
+
+__attribute__((weak)) void tusbhLinkBLUETOOTH(TUSBH_Handle_t *phost)
+{
+}
+
+__attribute__((weak)) void tusbhLinkHUB(TUSBH_Handle_t *phost)
+{
+}
+
+
+
+#ifdef TOPPERS_MPCORE
+/*
+ *  IDCHANGE CALLBACK関数
+ */
+static void
+dwc2_host_idchangecallback(USB_OTG_Handle_t *hhcd)
+{
+	tusbiSendData(((TUSBH_Handle_t *)(hhcd->pHost))->connect_event, TUSBH_IDCHANGE_EVENT, 0, 1, 0);
+}
+#endif	/* TOPPERS_MPCORE */
+
+/*
+ *  CONNECT CALLBACK関数
+ */
+static void
+dwc2_host_connectcallback(USB_OTG_Handle_t *hhcd)
+{
+	tusbiSendData(((TUSBH_Handle_t *)(hhcd->pHost))->connect_event, TUSBH_CONNECT_EVENT, 0, 1, 0);
+}
+
+/*
+ *  DISCONNECT CALLBACK関数
+ */
+static void
+dwc2_host_disconnectcallback(USB_OTG_Handle_t *hhcd)
+{
+	tusbiSendData(((TUSBH_Handle_t *)(hhcd->pHost))->connect_event, TUSBH_DISCONNECT_EVENT, 0, 1, 0);
+}
+
+/*
+ *  URB CHANGE CALLBACK関数
+ */
+static void
+dwc2_host_changeurbcallback(USB_OTG_Handle_t *hhcd, uint8_t chnum, uint8_t urb_state)
+{
+	TUSBH_Handle_t *phost = hhcd->pHost;
+	uint8_t urb;
+
+	if(urb_state < 8)
+		urb = urb_table[urb_state];
+	else
+		urb = TUSBH_URB_ERROR;
+	tusbiSendData(phost->process_event, TUSBH_URB_EVENT, phost->pipes[chnum].index, chnum, urb);
+}
+
+
+/*
+ *  USB_OTG DWC2 HIGH DRIVER INITIALIZE
+ *  parameter1 phost:  USBホストハンドラ
+ *  return     TUSBH_ERCODE
+ */
+TUSBH_ERCODE
+dwc2_host_init(TUSBH_Handle_t *phost)
+{
+	USB_OTG_Handle_t *husb = (USB_OTG_Handle_t *)(phost->pSysData);
+
+	/*
+	 *  RTOSリソース設定
+	 */
+	phost->processTaskID = TUSBH_P_TASK;
+	phost->eventTaskID   = TUSBH_E_TASK;
+	phost->process_event = USBH_EVT1_DTQ;
+	phost->connect_event = USBH_EVT2_DTQ;
+	phost->numPipes = husb->Init.host_channels;
+
+	/*
+	 *  USB-OTGドライバ設定
+	 */
+	husb->pHost = phost;
+
+	/*
+	 *  コールバック関数設定
+	 */
+#ifdef TOPPERS_MPCORE
+	husb->otgidchangecallback    = dwc2_host_idchangecallback;
+#endif	/* TOPPERS_MPCORE */
+	husb->hostsofcallback        = NULL;
+	husb->hostconnectcallback    = dwc2_host_connectcallback;
+	husb->hostdisconnectcallback = dwc2_host_disconnectcallback;
+	husb->hostchangeurbcallback  = dwc2_host_changeurbcallback;
+
+	/*
+	 *  USB-OTG初期化
+	 */
+	usbo_hostinit(husb);
+
+	/*
+	 *  USBホストクラスのリンク
+	 */
+	tusbhLinkHID(phost);
+	tusbhLinkMSC(phost);
+	tusbhLinkSERIAL(phost);
+	tusbhLinkPRT(phost);
+	tusbhLinkBLUETOOTH(phost);
+	tusbhLinkHUB(phost);
+	return TUSBH_E_OK;
+}
+
+/*
+ *  USB_OTG DWC2 HIGH DRIVER DE-INITIALIZE
+ *  parameter1 phost:  USBホストハンドラ
+ *  return     TUSBH_ERCODE
+ */
+TUSBH_ERCODE
+dwc2_host_deinit(TUSBH_Handle_t *phost)
+{
+	USB_OTG_Handle_t *husb = phost->pSysData;
+
+	/*
+	 *  USB-OTG終了処理
+	 */
+	usbo_deinit(husb);
+
+#if 0	/* ROI DEBUG クロック停止なので意味がない */
+	usbo_disableglobalint(husb);
+#endif	/* ROI DEBUG */
+	return TUSBH_E_OK;
+}
+
+/*
+ *  USB_OTG DWC2 HIGH DRIVER START
+ *  parameter1 phost:  USBホストハンドラ
+ *  return     TUSBH_ERCODE
+ */
+TUSBH_ERCODE
+dwc2_host_start(TUSBH_Handle_t *phost)
+{
+	usbo_starthost(phost->pSysData);
+	usbo_enableglobalint(phost->pSysData);
+	return TUSBH_E_OK; 
+}
+
+/*
+ *  USB_OTG DWC2 HIGH DRIVER GET SPEED
+ *  parameter1 phost:  USBホストハンドラ
+ *  return     usb speed value
+ */
+uint8_t
+dwc2_host_getspeed(TUSBH_Handle_t *phost)
+{
+	uint8_t speed = USB_DEVICE_SPEED_FULL;
+
+	switch(usbo_gethostspeed(phost->pSysData)){
+	case 0:
+		speed = USB_DEVICE_SPEED_HIGH;
+		break;
+	case 2:
+		speed = USB_DEVICE_SPEED_LOW;
+		break;
+	case 1:
+	default:
+		speed = USB_DEVICE_SPEED_FULL;
+		break;
+	}
+	return speed;
+}
+
+/*
+ *  USB_OTG DWC2 HIGH DRIVER OPEN PIPE
+ *  parameter1 phost:   USBホストハンドラ
+ *  parameter2 pipe:    PIPE#
+ *  parameter3 epnum:   EP番号
+ *  parameter4 dev_addr:デバイスアドレス
+ *  parameter5 speed:   デバイススピード
+ *  parameter6 type:    エンドポイントタイプ
+ *  parameter7 eps:     MAXパケットサイズ
+ *  return     TUSBH_ERCODE
+ */
+TUSBH_ERCODE
+dwc2_host_openpipe(TUSBH_Handle_t *phost, uint8_t pipe, uint8_t epnum, uint8_t dev_addr,
+					uint8_t speed, uint8_t type, uint16_t mps)
+{
+	USB_OTG_Handle_t  *husb = (USB_OTG_Handle_t *)(phost->pSysData);
+	USB_OTG_HCTypeDef *phc = &husb->hc[pipe];
+
+	phc->dev_addr = dev_addr;
+	phc->max_packet = mps;
+	phc->ch_num = pipe;
+	phc->ep_type = type;
+	phc->ep_num = epnum & 0x7F;
+	phc->ep_is_in = ((epnum & 0x80) == 0x80);
+	phc->speed = speed;
+
+	if(usbo_hc_init(husb, pipe, epnum) == E_OK)
+		return TUSBH_E_OK;
+	else
+		return TUSBH_E_ERR;
+}
+
+/*
+ *  USB_OTG DWC2 HIGH DRIVER CLOSE PIPE
+ *  parameter1 phost:   USBホストハンドラ
+ *  parameter2 pipe:    PIPE#
+ *  return     TUSBH_ERCODE
+ */
+TUSBH_ERCODE
+dwc2_host_closepipe(TUSBH_Handle_t *phost, uint8_t pipe)
+{
+	loc_cpu();
+	usbo_hc_halt(phost->pSysData, pipe);
+	unl_cpu();
+	return TUSBH_E_OK;
+}
+
+/*
+ *  USB_OTG DWC2 HIGH DRIVER SUBMIT URB
+ *  parameter1 phost:   USBホストハンドラ
+ *  parameter2 pipe:    PIPE#
+ *  parameter3 dir:     接続方向:0Out/1:In
+ *  parameter4 token:   エンドポイント設定タイプ:0:SETUP/1:DATA
+ *  parameter5 pbuff:   通信領域へのポインタ
+ *  parameter6 length:  通信サイズ
+ *  parameter7 do_ping: DO PING設定
+ *  return     TUSBH_ERCODE
+ */
+TUSBH_ERCODE
+dwc2_host_submiturb(TUSBH_Handle_t *phost, uint8_t pipe, uint8_t dir,
+					uint8_t token, uint8_t* pbuff, uint16_t length, uint8_t do_ping)
+{
+	USB_OTG_Handle_t *husb = (USB_OTG_Handle_t *)phost->pSysData;
+
+#ifdef TOPPERS_MPCORE
+	usbo_dma_wait(husb, pipe);
+#endif	/* TOPPERS_MPCORE */
+	husb->hc[pipe].ep_is_in = dir;
+
+	if(token == 0)
+		husb->hc[pipe].data_pid = HC_PID_SETUP;
+	else
+		husb->hc[pipe].data_pid = HC_PID_DATA1;
+
+	/* Manage Data Toggle */
+	switch(husb->hc[pipe].ep_type){
+	case EP_TYPE_CTRL:
+		if(token == 1 && dir == 0){ /*send data */
+			if(length == 0){	/* For Status OUT stage, Length==0, Status Out PID = 1 */
+				husb->hc[pipe].toggle_out = 1;
+			}
+
+			/* Set the Data Toggle bit as per the Flag */
+			if(husb->hc[pipe].toggle_out == 0){	/* Put the PID 0 */
+				husb->hc[pipe].data_pid = HC_PID_DATA0;
+			}
+			else{	/* Put the PID 1 */
+				husb->hc[pipe].data_pid = HC_PID_DATA1;
+			}
+			if(husb->hc[pipe].urb_state != URB_NOTREADY){
+				husb->hc[pipe].do_ping = do_ping;
+			}
+		}
+		break;
+
+	case EP_TYPE_BULK:
+		if(dir == 0){
+			/* Set the Data Toggle bit as per the Flag */
+			if(husb->hc[pipe].toggle_out == 0){	/* Put the PID 0 */
+				husb->hc[pipe].data_pid = HC_PID_DATA0;
+			}
+			else{	/* Put the PID 1 */
+				husb->hc[pipe].data_pid = HC_PID_DATA1;
+			}
+			if(husb->hc[pipe].urb_state != URB_NOTREADY){
+				husb->hc[pipe].do_ping = do_ping;
+			}
+		}
+		else{
+			if(husb->hc[pipe].toggle_in == 0){
+				husb->hc[pipe].data_pid = HC_PID_DATA0;
+			}
+			else{
+				husb->hc[pipe].data_pid = HC_PID_DATA1;
+			}
+		}
+		break;
+	case EP_TYPE_INTR:
+		if(dir == 0){
+			/* Set the Data Toggle bit as per the Flag */
+			if(husb->hc[pipe].toggle_out == 0){	/* Put the PID 0 */
+				husb->hc[pipe].data_pid = HC_PID_DATA0;
+			}
+			else{	/* Put the PID 1 */
+				husb->hc[pipe].data_pid = HC_PID_DATA1;
+			}
+		}
+		else{
+			if(husb->hc[pipe].toggle_in == 0){
+				husb->hc[pipe].data_pid = HC_PID_DATA0;
+			}
+			else{
+				husb->hc[pipe].data_pid = HC_PID_DATA1;
+			}
+		}
+		break;
+	case EP_TYPE_ISOC: 
+		husb->hc[pipe].data_pid = HC_PID_DATA0;
+		break;
+	}
+
+	husb->hc[pipe].xfer_buff = pbuff;
+	husb->hc[pipe].xfer_len  = length;
+	husb->hc[pipe].urb_state = URB_IDLE;
+	husb->hc[pipe].xfer_count = 0;
+	husb->hc[pipe].ch_num = pipe;
+	husb->hc[pipe].state = USBO_HC_IDLE;
+
+	usbo_hc_startxfer(husb, pipe);
+	return TUSBH_E_OK;
+}
+
+/*
+ *  USB_OTG DWC2 HIGH DRIVER CHECK PIPE STATE
+ *  parameter1 phost:   USBホストハンドラ
+ *  parameter2 pipe:    PIPE#
+ *  return     TUSBH_ERCODE
+ */
+bool_t
+dwc2_host_checkpipe(TUSBH_Handle_t *phost, uint8_t pipe)
+{
+	USB_OTG_Handle_t *husb = (USB_OTG_Handle_t *)(phost->pSysData);
+
+	if(pipe < husb->Init.host_channels && husb->hc[pipe].state != USBO_HC_FAIL)
+		return true;
+	else
+		return false;
+}
+
+/*
+ *  USB_OTG DWC2 HIGH DRIVER SET PIPE TOGGLE VALUE
+ *  parameter1 phost:   USBホストハンドラ
+ *  parameter2 pipe:    PIPE#
+ *  parameter3 toggle:  トグル値
+ *  return     TUSBH_ERCODE
+ */
+TUSBH_ERCODE
+dwc2_host_settoggle(TUSBH_Handle_t *phost, uint8_t pipe, uint8_t toggle)
+{
+	USB_OTG_Handle_t *husb = (USB_OTG_Handle_t *)(phost->pSysData);
+
+	if(husb->hc[pipe].ep_is_in){
+		husb->hc[pipe].toggle_in = toggle;
+	}
+	else{
+		husb->hc[pipe].toggle_out = toggle;
+	}
+	return TUSBH_E_OK; 
+}
+
+/*
+ *  USB_OTG DWC2 HIGH DRIVER GET PIPE TOGGLE VALUE
+ *  parameter1 phost:   USBホストハンドラ
+ *  parameter2 pipe:    PIPE#
+ *  return    トグル値
+ */
+uint8_t
+dwc2_host_gettoggle(TUSBH_Handle_t *phost, uint8_t pipe)
+{
+	USB_OTG_Handle_t *husb = (USB_OTG_Handle_t *)(phost->pSysData);
+	uint8_t toggle = 0;
+
+	if(husb->hc[pipe].ep_is_in){
+		toggle = husb->hc[pipe].toggle_in;
+	}
+	else{
+		toggle = husb->hc[pipe].toggle_out;
+	}
+	return toggle;
+}
+
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/usb_otg/dwc2_host_driver.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/usb_otg/dwc2_host_driver.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/usb_otg/dwc2_host_driver.h	(revision 457)
@@ -0,0 +1,75 @@
+/*
+ *  TOPPERS BASE PLATFORM MIDDLEWARE
+ * 
+ *  Copyright (C) 2017-2017 by TOPPERS PROJECT
+ *                             Educational Working Group.
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+/*
+ *  DWC2 HIGH DRIVER インクルードファイル
+ */
+
+
+#ifndef _DWC2_HOST_DRIVER_H_
+#define _DWC2_HOST_DRIVER_H_
+
+#include "tusb_rtos.h"
+#include "usb_otg.h"
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+#define dwc2_host_gettraslength(h, n)   (((USB_OTG_Handle_t *)((h)->pSysData))->hc[(n)].xfer_count)
+
+/*
+ *  DWC2 HOST HIGH DRIVER関数プロトタイプ宣言
+ */
+extern TUSBH_ERCODE dwc2_host_init(TUSBH_Handle_t *phost);
+extern TUSBH_ERCODE dwc2_host_deinit(TUSBH_Handle_t *phost);
+extern TUSBH_ERCODE dwc2_host_start(TUSBH_Handle_t *phost);
+extern uint8_t      dwc2_host_getspeed(TUSBH_Handle_t *phost);
+
+extern TUSBH_ERCODE dwc2_host_openpipe(TUSBH_Handle_t *phost, uint8_t, uint8_t, uint8_t, uint8_t, uint8_t, uint16_t);
+extern TUSBH_ERCODE dwc2_host_closepipe(TUSBH_Handle_t *phost, uint8_t);
+extern TUSBH_ERCODE dwc2_host_submiturb(TUSBH_Handle_t *phost, uint8_t, uint8_t,  uint8_t, uint8_t*, uint16_t, uint8_t);
+extern bool_t       dwc2_host_checkpipe(TUSBH_Handle_t *phost, uint8_t pipe);
+extern TUSBH_ERCODE dwc2_host_settoggle(TUSBH_Handle_t *phost, uint8_t , uint8_t);
+extern uint8_t      dwc2_host_gettoggle(TUSBH_Handle_t *phost, uint8_t);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _DWC2_HOST_DRIVER_H_ */
+
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/usb_otg/tusbd_conf.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/usb_otg/tusbd_conf.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/usb_otg/tusbd_conf.h	(revision 457)
@@ -0,0 +1,94 @@
+/*
+ *  TOPPERS BASE PLATFORM MIDDLEWARE
+ * 
+ *  Copyright (C) 2017-2017 by TOPPERS PROJECT
+ *                             Educational Working Group.
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+/*
+ *  TOPPERS USB DEVICE MODULE CONFIGURATION インクルードファイル
+ */
+
+#ifndef _TUSBD_CONF_H_
+#define _TUSBD_CONF_H_
+
+#include "dwc2_device_driver.h"
+
+#define TUSBD_MAX_NUM_INTERFACES              1
+#define TUSBD_MAX_NUM_CONFIGURATION           1
+#define TUSBD_NUM_ENDPOINT                    15
+#define TUSBD_CONFIG_SELF_POWERED             0x01
+
+#define USBD_StatusTypeDef   TUSBD_ERCODE
+#define USBD_HandleTypeDef   TUSBD_Handle_t
+#define USBD_Init            tusbdInit
+#define USBD_Start           tusbdStart
+
+extern uint8_t defaultDeviceDescriptor[];
+extern uint8_t defaultDeviceQualifierDescriptor[];
+extern uint8_t defaultLanguageIDDescriptor[];
+extern uint8_t defaultManufacturerString[];
+extern uint8_t defaultProductString[];
+extern uint8_t defaultSerialString[];
+extern uint8_t defaultConfigurationString[];
+extern uint8_t defaultInterfaceString[];
+
+#define TUSBD_DEVICE_DESCRIPTOR               defaultDeviceDescriptor
+#define TUSBD_DEVICE_QUALIFIER_DESCRIPTOR     defaultDeviceQualifierDescriptor
+#define TUSBD_LANGUAGEID_DESCRIPTOR           defaultLanguageIDDescriptor
+#define TUSBD_MANUFACTURER_STRING             defaultManufacturerString
+#define TUSBD_PRODUCT_STRING                  defaultProductString
+#define TUSBD_SERIAL_STRING                   defaultSerialString
+#define TUSBD_CONFIGURATION_STRING            defaultConfigurationString
+#define TUSBD_INTERFACE_STRING                defaultInterfaceString
+#define TUSBD_USER_STRING                     NULL
+
+#define tusbdDriverSetUSBAddress(d, a)  usbo_setDevAddress(((d)->pSysData), (a))
+#define tusbdDriverGetRxDataSize        dwc2_device_getrxdatasize
+
+#define tusbdDriverInit                 dwc2_device_init
+#define tusbdDriverDeInit               dwc2_device_deinit
+#define tusbdDriverStart                dwc2_device_start
+#define tusbdDriverStop                 dwc2_device_stop
+#define tusbdDriverOpenEp               dwc2_device_openep
+#define tusbdDriverCloseEp              dwc2_device_closeep
+#define tusbdDriverFlushEp              dwc2_device_flushep
+#define tusbdDriverStallEp              dwc2_device_stallep
+#define tusbdDriverClearStallEp         dwc2_device_clearep
+#define tusbdDriverStallConditionEp     dwc2_device_getstallcondition
+#define tusbdDriverStartTransmit        dwc2_device_transmitdata
+#define tusbdDriverSetupReceive         dwc2_device_startreceive
+#define tusbdDriverTestMode             dwc2_device_testmode
+
+#endif /* _TUSBD_CONF_H_ */
+
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/usb_otg/tusbh_conf.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/usb_otg/tusbh_conf.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/usb_otg/tusbh_conf.h	(revision 457)
@@ -0,0 +1,63 @@
+/*
+ *  TOPPERS BASE PLATFORM MIDDLEWARE
+ * 
+ *  Copyright (C) 2017-2017 by TOPPERS PROJECT
+ *                             Educational Working Group.
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+/*
+ *  TOPPERS USB HOST MODULE CONFIGURATION インクルードファイル
+ */
+
+#ifndef _TUSBH_CONF_H_
+#define _TUSBH_CONF_H_
+
+#include "dwc2_host_driver.h"
+
+#define tusbhHDStop(h)              usbo_stophost((h)->pSysData)
+#define tusbhHDResetPort(h)         usbo_resetport((h)->pSysData)
+#define tusbhHDTrasLength           dwc2_host_gettraslength
+#define tusbhHDControlVBUS(h, s)    usbo_driveextvbus((h)->pSysData, s)
+
+#define tusbhHDInit         dwc2_host_init
+#define tusbhHDStart        dwc2_host_start
+#define tusbhHDGetSpeed     dwc2_host_getspeed
+#define tusbhHDOpenPipe     dwc2_host_openpipe
+#define tusbhHDClosePipe    dwc2_host_closepipe
+#define tsubhHDSubmitURB    dwc2_host_submiturb
+#define tusbhHDCheckPipe    dwc2_host_checkpipe
+#define tusbhHDSetToggle    dwc2_host_settoggle
+#define tusbhHDGetToggle    dwc2_host_gettoggle
+
+#endif /* _TUSBH_CONF_H_ */
+
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/include/histogram.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/include/histogram.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/include/histogram.h	(revision 457)
@@ -0,0 +1,75 @@
+/*
+ *  TOPPERS Software
+ *      Toyohashi Open Platform for Embedded Real-Time Systems
+ * 
+ *  Copyright (C) 2006-2010 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *		実行時間分布集計モジュール
+ */
+
+#ifndef TOPPERS_HISTOGRAM_H
+#define TOPPERS_HISTOGRAM_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ *  実行時間分布計測の初期化
+ */
+extern void	init_hist(ID histid, uint_t maxval, uint_t histarea[]);
+
+/*
+ *  実行時間計測の開始
+ */
+extern void	begin_measure(ID histid);
+
+/*
+ *  実行時間計測の終了
+ */
+extern void	end_measure(ID histid);
+
+/*
+ *  実行時間分布計測の表示
+ */
+extern void	print_hist(ID histid);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* TOPPERS_HISTOGRAM_H */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/include/itron.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/include/itron.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/include/itron.h	(revision 457)
@@ -0,0 +1,137 @@
+/*
+ *  TOPPERS Software
+ *      Toyohashi Open Platform for Embedded Real-Time Systems
+ * 
+ *  Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
+ *                              Toyohashi Univ. of Technology, JAPAN
+ *  Copyright (C) 2004-2010 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  $Id$
+ */
+
+/*
+ *		ITRON仕様共通規定のデータ型・定数・マクロ
+ *
+ *  このヘッダファイルは，ITRON仕様共通規定のデータ型・定数・マクロの中
+ *  で，TOPPERS共通ヘッダファイルに含まれないものの定義を含む．ITRON仕
+ *  様との互換性を必要とするアプリケーションがインクルードすることを想
+ *  定している．
+ *
+ *  アセンブリ言語のソースファイルからこのファイルをインクルードする時
+ *  は，TOPPERS_MACRO_ONLYを定義しておく．これにより，マクロ定義以外を
+ *  除くようになっている．
+ */
+
+#ifndef TOPPERS_ITRON_H
+#define TOPPERS_ITRON_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ *  TOPPERS共通ヘッダファイル
+ */
+#include "t_stddef.h"
+
+/*
+ *  ITRON仕様共通データ型
+ */
+#ifndef TOPPERS_MACRO_ONLY
+
+#ifdef INT8_MAX
+typedef	int8_t			B;			/* 符号付き8ビット整数 */
+#endif /* INT8_MAX */
+
+#ifdef UINT8_MAX
+typedef	uint8_t			UB;			/* 符号無し8ビット整数 */
+typedef	uint8_t			VB;			/* 型が定まらない8ビットの値 */
+#endif /* UINT8_MAX */
+
+typedef	int16_t			H;			/* 符号付き16ビット整数 */
+typedef	uint16_t		UH;			/* 符号無し16ビット整数 */
+typedef	uint16_t		VH;			/* 型が定まらない16ビットの値 */
+
+typedef	int32_t			W;			/* 符号付き32ビット整数 */
+typedef	uint32_t		UW;			/* 符号無し32ビット整数 */
+typedef	uint32_t		VW;			/* 型が定まらない32ビットの値 */
+
+#ifdef INT64_MAX
+typedef	int64_t			D;			/* 符号付き64ビット整数 */
+#endif /* INT64_MAX */
+
+#ifdef UINT64_MAX
+typedef	uint64_t		UD;			/* 符号無し64ビット整数 */
+typedef	uint64_t		VD;			/* 型が定まらない64ビットの値 */
+#endif /* UINT64_MAX */
+
+typedef	void			*VP;		/* 型が定まらないものへのポインタ */
+
+typedef int_t			INT;		/* 自然なサイズの符号付き整数 */
+typedef uint_t			UINT;		/* 自然なサイズの符号無し整数 */
+
+typedef bool_t			BOOL;		/* 真偽値 */
+
+typedef	intptr_t		VP_INT;		/* ポインタまたは符号付き整数 */
+
+#endif /* TOPPERS_MACRO_ONLY */
+
+/*
+ *  ITRON仕様共通定数
+ */
+#define	TRUE		true			/* 真 */
+#define	FALSE		false			/* 偽 */
+
+/*
+ *  オブジェクト属性の定義
+ */
+#define TA_HLNG			UINT_C(0x00)	/* 高級言語用インタフェース */
+#define TA_TFIFO		UINT_C(0x00)	/* タスクの待ち行列をFIFO順に */
+#define TA_MFIFO		UINT_C(0x00)	/* メッセージキューをFIFO順に */
+#define TA_WSGL			UINT_C(0x00)	/* 待ちタスクは1つのみ */
+
+/*
+ *  ネスト回数の最大値
+ */
+#define TMAX_SUSCNT		UINT_C(1)		/* 強制待ち要求ネスト数の最大値 */
+
+/*
+ *  強制待ち状態からの強制再開
+ */
+#define frsm_tsk(tskid)		rsm_tsk(tskid)
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* TOPPERS_ITRON_H */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/include/kernel.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/include/kernel.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/include/kernel.h	(revision 457)
@@ -0,0 +1,635 @@
+/*
+ *  TOPPERS/ASP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Advanced Standard Profile Kernel
+ * 
+ *  Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
+ *                              Toyohashi Univ. of Technology, JAPAN
+ *  Copyright (C) 2004-2014 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  $Id$
+ */
+
+/*
+ *		TOPPERS/ASPカーネル 標準ヘッダファイル
+ *
+ *  TOPPERS/ASPカーネルがサポートするサービスコールの宣言と，必要なデー
+ *  タ型，定数，マクロの定義を含むヘッダファイル．
+ *
+ *  アセンブリ言語のソースファイルからこのファイルをインクルードする時
+ *  は，TOPPERS_MACRO_ONLYを定義しておく．これにより，マクロ定義以外を
+ *  除くようになっている．
+ *
+ *  このファイルをインクルードする前にインクルードしておくべきファイル
+ *  はない．
+ */
+
+#ifndef TOPPERS_KERNEL_H
+#define TOPPERS_KERNEL_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ *	TOPPERS共通のデータ型・定数・マクロ
+ */
+#include <t_stddef.h>
+
+/*
+ *  ターゲット依存部
+ */
+#include "target_kernel.h"
+
+#ifndef TOPPERS_MACRO_ONLY
+
+/*
+ *  データ型の定義
+ */
+
+/*
+ *  ビットパターンやオブジェクト番号の型定義
+ */
+typedef	uint_t		TEXPTN;		/* タスク例外要因のビットパターン */
+typedef	uint_t		FLGPTN;		/* イベントフラグのビットパターン */
+typedef	uint_t		INTNO;		/* 割込み番号 */
+typedef	uint_t		INHNO;		/* 割込みハンドラ番号 */
+typedef	uint_t		EXCNO;		/* CPU例外ハンドラ番号 */
+
+/*
+ *  処理単位の型定義
+ */
+typedef void	(*TASK)(intptr_t exinf);
+typedef void	(*TEXRTN)(TEXPTN texptn, intptr_t exinf);
+typedef void	(*CYCHDR)(intptr_t exinf);
+typedef void	(*ALMHDR)(intptr_t exinf);
+typedef void	(*ISR)(intptr_t exinf);
+typedef void	(*INTHDR)(void);
+typedef void	(*EXCHDR)(void *p_excinf);
+typedef void	(*INIRTN)(intptr_t exinf);
+typedef void	(*TERRTN)(intptr_t exinf);
+
+/*
+ *  メモリ領域確保のための型定義
+ */
+#ifndef TOPPERS_STK_T
+#define TOPPERS_STK_T	intptr_t
+#endif /* TOPPERS_STK_T */
+typedef	TOPPERS_STK_T	STK_T;	/* スタック領域を確保するための型 */
+
+#ifndef TOPPERS_MPF_T
+#define TOPPERS_MPF_T	intptr_t
+#endif /* TOPPERS_MPF_T */
+typedef	TOPPERS_MPF_T	MPF_T;	/* 固定長メモリプール領域を確保するための型 */
+
+/*
+ *  メッセージヘッダの型定義
+ */
+typedef	struct t_msg {			/* メールボックスのメッセージヘッダ */
+	struct t_msg	*pk_next;
+} T_MSG;
+
+typedef	struct t_msg_pri {		/* 優先度付きメッセージヘッダ */
+	T_MSG	msgque;				/* メッセージヘッダ */
+	PRI		msgpri;				/* メッセージ優先度 */
+} T_MSG_PRI;
+
+/*
+ *  パケット形式の定義
+ */
+typedef struct t_ctsk {
+	ATR			tskatr;		/* タスク属性 */
+	intptr_t	exinf;		/* タスクの拡張情報 */
+	TASK		task;		/* タスクのメインルーチンの先頭番地 */
+	PRI			itskpri;	/* タスクの起動時優先度 */
+	SIZE		stksz;		/* タスクのスタック領域のサイズ */
+	STK_T 		*stk;		/* タスクのスタック領域の先頭番地 */
+} T_CTSK;
+
+typedef struct t_rtsk {
+	STAT	tskstat;	/* タスク状態 */
+	PRI		tskpri;		/* タスクの現在優先度 */
+	PRI		tskbpri;	/* タスクのベース優先度 */
+	STAT	tskwait;	/* 待ち要因 */
+	ID		wobjid;		/* 待ち対象のオブジェクトのID */
+	TMO		lefttmo;	/* タイムアウトするまでの時間 */
+	uint_t	actcnt;		/* 起動要求キューイング数 */
+	uint_t	wupcnt;		/* 起床要求キューイング数 */
+} T_RTSK;
+
+typedef struct t_dtex {
+	ATR		texatr;		/* タスク例外処理ルーチン属性 */
+	TEXRTN	texrtn;		/* タスク例外処理ルーチンの先頭番地 */
+} T_DTEX;
+
+typedef struct t_rtex {
+	STAT	texstat;	/* タスク例外処理の状態 */
+	TEXPTN	pndptn;		/* 保留例外要因 */
+} T_RTEX;
+
+typedef struct t_csem {
+	ATR		sematr;		/* セマフォ属性 */
+	uint_t	isemcnt;	/* セマフォの初期資源数 */
+	uint_t	maxsem;		/* セマフォの最大資源数 */
+} T_CSEM;
+
+typedef struct t_rsem {
+	ID		wtskid;		/* セマフォの待ち行列の先頭のタスクのID番号 */
+	uint_t	semcnt;		/* セマフォの現在の資源数 */
+} T_RSEM;
+
+typedef struct t_cflg {
+	ATR		flgatr;		/* イベントフラグ属性 */
+	FLGPTN	iflgptn;	/* イベントフラグの初期ビットパターン */
+} T_CFLG;
+
+typedef struct t_rflg {
+	ID		wtskid;		/* イベントフラグの待ち行列の先頭のタスクのID番号 */
+	FLGPTN	flgptn;		/* イベントフラグの現在のビットパターン */
+} T_RFLG;
+
+typedef struct t_cdtq {
+	ATR		dtqatr;		/* データキュー属性 */
+	uint_t	dtqcnt;		/* データキュー管理領域に格納できるデータ数 */
+	void 	*dtqmb;		/* データキュー管理領域の先頭番地 */
+} T_CDTQ;
+
+typedef struct t_rdtq {
+	ID		stskid;		/* データキューの送信待ち行列の先頭のタスクのID番号 */
+	ID		rtskid;		/* データキューの受信待ち行列の先頭のタスクのID番号 */
+	uint_t	sdtqcnt;	/* データキュー管理領域に格納されているデータの数 */
+} T_RDTQ;
+
+typedef struct t_cpdq {
+	ATR		pdqatr;		/* 優先度データキュー属性 */
+	uint_t	pdqcnt;		/* 優先度データキュー管理領域に格納できるデータ数 */
+	PRI		maxdpri;	/* 優先度データキューに送信できるデータ優先度の最
+						   大値 */
+	void 	*pdqmb;		/* 優先度データキュー管理領域の先頭番地 */
+} T_CPDQ;
+
+typedef struct t_rpdq {
+	ID		stskid;		/* 優先度データキューの送信待ち行列の先頭のタスク
+						   のID番号 */
+	ID		rtskid;		/* 優先度データキューの受信待ち行列の先頭のタスク
+						   のID番号 */
+	uint_t	spdqcnt;	/* 優先度データキュー管理領域に格納されているデー
+						   タの数 */
+} T_RPDQ;
+
+typedef struct t_cmbx {
+	ATR		mbxatr;		/* メールボックス属性 */
+	PRI		maxmpri;	/* 優先度メールボックスに送信できるメッセージ優先
+						   度の最大値 */
+	void 	*mprihd;	/* 優先度別のメッセージキューヘッダ領域の先頭番地 */
+} T_CMBX;
+
+typedef struct t_rmbx {
+	ID		wtskid;		/* メールボックスの待ち行列の先頭のタスクのID番号 */
+	T_MSG	*pk_msg;	/* メッセージキューの先頭につながれたメッセージ
+						   の先頭番地 */
+} T_RMBX;
+
+typedef struct t_cmtx {
+	ATR		mtxatr;		/* ミューテックス属性 */
+	PRI		ceilpri;	/* 優先度ミューテックスに送信できるメッセージ優先
+						   度の最大値 */
+	void 	*mprihd;	/* 優先度別のメッセージキューヘッダ領域の先頭番地 */
+} T_CMTX;
+
+typedef struct t_rmtx {
+	ID		htskid;		/* ミューテックスをロックしているタスクのID番号 */
+	ID		wtskid;		/* ミューテックスの待ち行列の先頭のタスクのID番号 */
+} T_RMTX;
+
+typedef struct t_cmpf {
+	ATR		mpfatr;		/* 固定長メモリプール属性 */
+	uint_t	blkcnt;		/* 獲得できる固定長メモリブロックの数 */
+	uint_t	blksz;		/* 固定長メモリブロックのサイズ */
+	MPF_T 	*mpf;		/* 固定長メモリプール領域の先頭番地 */
+	void 	*mpfmb;		/* 固定長メモリプール管理領域の先頭番地 */
+} T_CMPF;
+
+typedef struct t_rmpf {
+	ID		wtskid;		/* 固定長メモリプールの待ち行列の先頭のタスクの
+						   ID番号 */
+	uint_t	fblkcnt;	/* 固定長メモリプール領域の空きメモリ領域に割り
+						   付けることができる固定長メモリブロックの数 */
+} T_RMPF;
+
+typedef struct t_ccyc {
+	ATR			cycatr;		/* 周期ハンドラ属性 */
+	intptr_t	exinf;		/* 周期ハンドラの拡張情報 */
+	CYCHDR		cychdr;		/* 周期ハンドラの先頭番地 */
+	RELTIM		cyctim;		/* 周期ハンドラの起動周期 */
+	RELTIM		cycphs;		/* 周期ハンドラの起動位相 */
+} T_CCYC;
+
+typedef struct t_rcyc {
+	STAT	cycstat;	/* 周期ハンドラの動作状態 */
+	RELTIM	lefttim;	/* 次に周期ハンドラを起動する時刻までの相対時間 */
+} T_RCYC;
+
+typedef struct t_calm {
+	ATR			almatr;		/* アラームハンドラ属性 */
+	intptr_t	exinf;		/* アラームハンドラの拡張情報 */
+	ALMHDR		almhdr;		/* アラームハンドラの先頭番地 */
+} T_CALM;
+
+typedef struct t_ralm {
+	STAT	almstat;	/* アラームハンドラの動作状態 */
+	RELTIM	lefttim;	/* アラームハンドラを起動する時刻までの相対時間 */
+} T_RALM;
+
+typedef struct t_cisr {
+	ATR			isratr;		/* 割込みサービスルーチン属性 */
+	intptr_t	exinf;		/* 割込みサービスルーチンの拡張情報 */
+	INTNO		intno;		/* 割込みサービスルーチンを登録する割込み番号 */
+	ISR			isr;		/* 割込みサービスルーチンの先頭番地 */
+	PRI			isrpri;		/* 割込みサービスルーチン優先度 */
+} T_CISR;
+
+/*
+ *  サービスコールの宣言
+ */
+
+/*
+ *  タスク管理機能
+ */
+extern ER_ID	acre_tsk(const T_CTSK *pk_ctsk) throw();
+extern ER		del_tsk(ID tskid) throw();
+extern ER		act_tsk(ID tskid) throw();
+extern ER		iact_tsk(ID tskid) throw();
+extern ER_UINT	can_act(ID tskid) throw();
+extern ER		ext_tsk(void) throw();
+extern ER		ter_tsk(ID tskid) throw();
+extern ER		chg_pri(ID tskid, PRI tskpri) throw();
+extern ER		get_pri(ID tskid, PRI *p_tskpri) throw();
+extern ER		get_inf(intptr_t *p_exinf) throw();
+extern ER		ref_tsk(ID tskid, T_RTSK *pk_rtsk) throw();
+
+/*
+ *  タスク付属同期機能
+ */
+extern ER		slp_tsk(void) throw();
+extern ER		tslp_tsk(TMO tmout) throw();
+extern ER		wup_tsk(ID tskid) throw();
+extern ER		iwup_tsk(ID tskid) throw();
+extern ER_UINT	can_wup(ID tskid) throw();
+extern ER		rel_wai(ID tskid) throw();
+extern ER		irel_wai(ID tskid) throw();
+extern ER		sus_tsk(ID tskid) throw();
+extern ER		rsm_tsk(ID tskid) throw();
+extern ER		dly_tsk(RELTIM dlytim) throw();
+
+/*
+ *  タスク例外処理機能
+ */
+extern ER		def_tex(ID tskid, const T_DTEX *pk_dtex) throw();
+extern ER		ras_tex(ID tskid, TEXPTN rasptn) throw();
+extern ER		iras_tex(ID tskid, TEXPTN rasptn) throw();
+extern ER		dis_tex(void) throw();
+extern ER		ena_tex(void) throw();
+extern bool_t	sns_tex(void) throw();
+extern ER		ref_tex(ID tskid, T_RTEX *pk_rtex) throw();
+
+/*
+ *  同期・通信機能
+ */
+extern ER_ID	acre_sem(const T_CSEM *pk_csem) throw();
+extern ER		del_sem(ID semid) throw();
+extern ER		sig_sem(ID semid) throw();
+extern ER		isig_sem(ID semid) throw();
+extern ER		wai_sem(ID semid) throw();
+extern ER		pol_sem(ID semid) throw();
+extern ER		twai_sem(ID semid, TMO tmout) throw();
+extern ER		ini_sem(ID semid) throw();
+extern ER		ref_sem(ID semid, T_RSEM *pk_rsem) throw();
+
+extern ER_ID	acre_flg(const T_CFLG *pk_cflg) throw();
+extern ER		del_flg(ID flgid) throw();
+extern ER		set_flg(ID flgid, FLGPTN setptn) throw();
+extern ER		iset_flg(ID flgid, FLGPTN setptn) throw();
+extern ER		clr_flg(ID flgid, FLGPTN clrptn) throw();
+extern ER		wai_flg(ID flgid, FLGPTN waiptn,
+						MODE wfmode, FLGPTN *p_flgptn) throw();
+extern ER		pol_flg(ID flgid, FLGPTN waiptn,
+						MODE wfmode, FLGPTN *p_flgptn) throw();
+extern ER		twai_flg(ID flgid, FLGPTN waiptn,
+						MODE wfmode, FLGPTN *p_flgptn, TMO tmout) throw();
+extern ER		ini_flg(ID flgid) throw();
+extern ER		ref_flg(ID flgid, T_RFLG *pk_rflg) throw();
+
+extern ER_ID	acre_dtq(const T_CDTQ *pk_cdtq) throw();
+extern ER		del_dtq(ID dtqid) throw();
+extern ER		snd_dtq(ID dtqid, intptr_t data) throw();
+extern ER		psnd_dtq(ID dtqid, intptr_t data) throw();
+extern ER		ipsnd_dtq(ID dtqid, intptr_t data) throw();
+extern ER		tsnd_dtq(ID dtqid, intptr_t data, TMO tmout) throw();
+extern ER		fsnd_dtq(ID dtqid, intptr_t data) throw();
+extern ER		ifsnd_dtq(ID dtqid, intptr_t data) throw();
+extern ER		rcv_dtq(ID dtqid, intptr_t *p_data) throw();
+extern ER		prcv_dtq(ID dtqid, intptr_t *p_data) throw();
+extern ER		trcv_dtq(ID dtqid, intptr_t *p_data, TMO tmout) throw();
+extern ER		ini_dtq(ID dtqid) throw();
+extern ER		ref_dtq(ID dtqid, T_RDTQ *pk_rdtq) throw();
+
+extern ER_ID	acre_pdq(const T_CPDQ *pk_cpdq) throw();
+extern ER		del_pdq(ID pdqid) throw();
+extern ER		snd_pdq(ID pdqid, intptr_t data, PRI datapri) throw();
+extern ER		psnd_pdq(ID pdqid, intptr_t data, PRI datapri) throw();
+extern ER		ipsnd_pdq(ID pdqid, intptr_t data, PRI datapri) throw();
+extern ER		tsnd_pdq(ID pdqid, intptr_t data,
+										PRI datapri, TMO tmout) throw();
+extern ER		rcv_pdq(ID pdqid, intptr_t *p_data, PRI *p_datapri) throw();
+extern ER		prcv_pdq(ID pdqid, intptr_t *p_data, PRI *p_datapri) throw();
+extern ER		trcv_pdq(ID pdqid, intptr_t *p_data,
+										PRI *p_datapri, TMO tmout) throw();
+extern ER		ini_pdq(ID pdqid) throw();
+extern ER		ref_pdq(ID pdqid, T_RPDQ *pk_rpdq) throw();
+
+extern ER_ID	acre_mbx(const T_CMBX *pk_cmbx) throw();
+extern ER		del_mbx(ID mbxid) throw();
+extern ER		snd_mbx(ID mbxid, T_MSG *pk_msg) throw();
+extern ER		rcv_mbx(ID mbxid, T_MSG **ppk_msg) throw();
+extern ER		prcv_mbx(ID mbxid, T_MSG **ppk_msg) throw();
+extern ER		trcv_mbx(ID mbxid, T_MSG **ppk_msg, TMO tmout) throw();
+extern ER		ini_mbx(ID mbxid) throw();
+extern ER		ref_mbx(ID mbxid, T_RMBX *pk_rmbx) throw();
+
+extern ER_ID	acre_mtx(const T_CMTX *pk_cmtx) throw();
+extern ER		del_mtx(ID mtxid) throw();
+extern ER		loc_mtx(ID mtxid) throw();
+extern ER		ploc_mtx(ID mtxid) throw();
+extern ER		tloc_mtx(ID mtxid, TMO tmout) throw();
+extern ER		unl_mtx(ID mtxid) throw();
+extern ER		ini_mtx(ID mtxid) throw();
+extern ER		ref_mtx(ID mtxid, T_RMTX *pk_rmtx) throw();
+
+/*
+ *  メモリプール管理機能
+ */
+extern ER_ID	acre_mpf(const T_CMPF *pk_cmpf) throw();
+extern ER		del_mpf(ID mpfid) throw();
+extern ER		get_mpf(ID mpfid, void **p_blk) throw();
+extern ER		pget_mpf(ID mpfid, void **p_blk) throw();
+extern ER		tget_mpf(ID mpfid, void **p_blk, TMO tmout) throw();
+extern ER		rel_mpf(ID mpfid, void *blk) throw();
+extern ER		ini_mpf(ID mpfid) throw();
+extern ER		ref_mpf(ID mpfid, T_RMPF *pk_rmpf) throw();
+
+/*
+ *  時間管理機能
+ */
+extern ER		get_tim(SYSTIM *p_systim) throw();
+extern ER		get_utm(SYSUTM *p_sysutm) throw();
+
+extern ER_ID	acre_cyc(const T_CCYC *pk_ccyc) throw();
+extern ER		del_cyc(ID cycid) throw();
+extern ER		sta_cyc(ID cycid) throw();
+extern ER		stp_cyc(ID cycid) throw();
+extern ER		ref_cyc(ID cycid, T_RCYC *pk_rcyc) throw();
+
+extern ER_ID	acre_alm(const T_CALM *pk_calm) throw();
+extern ER		del_alm(ID almid) throw();
+extern ER		sta_alm(ID almid, RELTIM almtim) throw();
+extern ER		ista_alm(ID almid, RELTIM almtim) throw();
+extern ER		stp_alm(ID almid) throw();
+extern ER		istp_alm(ID almid) throw();
+extern ER		ref_alm(ID almid, T_RALM *pk_ralm) throw();
+
+/*
+ *  システム状態管理機能
+ */
+extern ER		rot_rdq(PRI tskpri) throw();
+extern ER		irot_rdq(PRI tskpri) throw();
+extern ER		get_tid(ID *p_tskid) throw();
+extern ER		iget_tid(ID *p_tskid) throw();
+extern ER		loc_cpu(void) throw();
+extern ER		iloc_cpu(void) throw();
+extern ER		unl_cpu(void) throw();
+extern ER		iunl_cpu(void) throw();
+extern ER		dis_dsp(void) throw();
+extern ER		ena_dsp(void) throw();
+extern bool_t	sns_ctx(void) throw();
+extern bool_t	sns_loc(void) throw();
+extern bool_t	sns_dsp(void) throw();
+extern bool_t	sns_dpn(void) throw();
+extern bool_t	sns_ker(void) throw();
+extern ER		ext_ker(void) throw();
+
+/*
+ *  割込み管理機能
+ */
+extern ER_ID	acre_isr(const T_CISR *pk_cisr) throw();
+extern ER		del_isr(ID isrid) throw();
+extern ER		dis_int(INTNO intno) throw();
+extern ER		ena_int(INTNO intno) throw();
+extern ER		chg_ipm(PRI intpri) throw();
+extern ER		get_ipm(PRI *p_intpri) throw();
+
+/*
+ *  CPU例外管理機能
+ */
+extern bool_t	xsns_dpn(void *p_excinf) throw();
+extern bool_t	xsns_xpn(void *p_excinf) throw();
+
+#endif /* TOPPERS_MACRO_ONLY */
+
+/*
+ *  オブジェクト属性の定義
+ */
+#define TA_ACT			UINT_C(0x02)	/* タスクを起動された状態で生成 */
+
+#define TA_TPRI			UINT_C(0x01)	/* タスクの待ち行列を優先度順に */
+#define TA_MPRI			UINT_C(0x02)	/* メッセージキューを優先度順に */
+
+#define TA_WMUL			UINT_C(0x02)	/* 複数の待ちタスク */
+#define TA_CLR			UINT_C(0x04)	/* イベントフラグのクリア指定 */
+
+#define TA_CEILING		UINT_C(0x03)	/* 優先度上限プロトコル */
+
+#define TA_STA			UINT_C(0x02)	/* 周期ハンドラを動作状態で生成 */
+
+#define TA_NONKERNEL	UINT_C(0x02)	/* カーネル管理外の割込み */
+
+#define TA_ENAINT		UINT_C(0x01)	/* 割込み要求禁止フラグをクリア */
+#define TA_EDGE			UINT_C(0x02)	/* エッジトリガ */
+
+/*
+ *  サービスコールの動作モードの定義
+ */
+#define TWF_ORW			UINT_C(0x01)	/* イベントフラグのOR待ち */
+#define TWF_ANDW		UINT_C(0x02)	/* イベントフラグのAND待ち */
+
+/*
+ *  オブジェクトの状態の定義
+ */
+#define TTS_RUN			UINT_C(0x01)	/* 実行状態 */
+#define TTS_RDY			UINT_C(0x02)	/* 実行可能状態 */
+#define TTS_WAI			UINT_C(0x04)	/* 待ち状態 */
+#define TTS_SUS			UINT_C(0x08)	/* 強制待ち状態 */
+#define TTS_WAS			UINT_C(0x0c)	/* 二重待ち状態 */
+#define TTS_DMT			UINT_C(0x10)	/* 休止状態 */
+
+#define TTW_SLP			UINT_C(0x0001)	/* 起床待ち */
+#define TTW_DLY			UINT_C(0x0002)	/* 時間経過待ち */
+#define TTW_SEM			UINT_C(0x0004)	/* セマフォの資源獲得待ち */
+#define TTW_FLG			UINT_C(0x0008)	/* イベントフラグ待ち */
+#define TTW_SDTQ		UINT_C(0x0010)	/* データキューへの送信待ち */
+#define TTW_RDTQ		UINT_C(0x0020)	/* データキューからの受信待ち */
+#define TTW_SPDQ		UINT_C(0x0100)	/* 優先度データキューへの送信待ち */
+#define TTW_RPDQ		UINT_C(0x0200)	/* 優先度データキューからの受信待ち */
+#define TTW_MBX			UINT_C(0x0040)	/* メールボックスからの受信待ち */
+#define TTW_MTX			UINT_C(0x0080)	/* ミューテックスのロック待ち状態 */
+#define TTW_MPF			UINT_C(0x2000)	/* 固定長メモリブロックの獲得待ち */
+
+#define TTEX_ENA		UINT_C(0x01)	/* タスク例外処理許可状態 */
+#define TTEX_DIS		UINT_C(0x02)	/* タスク例外処理禁止状態 */
+
+#define TCYC_STP		UINT_C(0x01)	/* 周期ハンドラが動作していない */
+#define TCYC_STA		UINT_C(0x02)	/* 周期ハンドラが動作している */
+
+#define TALM_STP		UINT_C(0x01)	/* アラームハンドラが動作していない */
+#define TALM_STA		UINT_C(0x02)	/* アラームハンドラが動作している */
+
+/*
+ *  その他の定数の定義
+ */
+#define TSK_SELF		0			/* 自タスク指定 */
+#define TSK_NONE		0			/* 該当するタスクがない */
+
+#define TPRI_SELF		0			/* 自タスクのベース優先度 */
+#define TPRI_INI		0			/* タスクの起動時優先度 */
+
+#define TIPM_ENAALL		0			/* 割込み優先度マスク全解除 */
+
+/*
+ *  構成定数とマクロ
+ */
+
+/*
+ *  サポートする機能
+ */
+#ifdef TOPPERS_TARGET_SUPPORT_DIS_INT
+#define TOPPERS_SUPPORT_DIS_INT			/* dis_intがサポートされている */
+#endif /* TOPPERS_TARGET_SUPPORT_DIS_INT */
+
+#ifdef TOPPERS_TARGET_SUPPORT_ENA_INT
+#define TOPPERS_SUPPORT_ENA_INT			/* ena_intがサポートされている */
+#endif /* TOPPERS_TARGET_SUPPORT_ENA_INT */
+
+#ifdef TOPPERS_TARGET_SUPPORT_GET_UTM
+#define TOPPERS_SUPPORT_GET_UTM			/* get_utmがサポートされている */
+#endif /* TOPPERS_TARGET_SUPPORT_GET_UTM */
+
+#define TOPPERS_SUPPORT_MUTEX			/* ミューテックス機能拡張 */
+#define TOPPERS_SUPPORT_DYNAMIC_CRE		/* 動的生成機能拡張 */
+
+/*
+ *  優先度の範囲
+ */
+#define TMIN_TPRI		1			/* タスク優先度の最小値（最高値）*/
+#define TMAX_TPRI		16			/* タスク優先度の最大値（最低値）*/
+#define TMIN_DPRI		1			/* データ優先度の最小値（最高値）*/
+#define TMAX_DPRI		16			/* データ優先度の最大値（最低値）*/
+#define TMIN_MPRI		1			/* メッセージ優先度の最小値（最高値）*/
+#define TMAX_MPRI		16			/* メッセージ優先度の最大値（最低値）*/
+#define TMIN_ISRPRI		1			/* 割込みサービスルーチン優先度の最小値 */
+#define TMAX_ISRPRI		16			/* 割込みサービスルーチン優先度の最大値 */
+
+/*
+ *  バージョン情報
+ */
+#define TKERNEL_MAKER	UINT_C(0x0118)	/* カーネルのメーカーコード */
+#define TKERNEL_PRID	UINT_C(0x0007)	/* カーネルの識別番号 */
+#define TKERNEL_SPVER	UINT_C(0xf517)	/* カーネル仕様のバージョン番号 */
+#define TKERNEL_PRVER	UINT_C(0x1093)	/* カーネルのバージョン番号 */
+
+/*
+ *  キューイング回数の最大値
+ */
+#define TMAX_ACTCNT		UINT_C(1)		/* 起動要求キューイング数の最大値 */
+#define TMAX_WUPCNT		UINT_C(1)		/* 起床要求キューイング数の最大値 */
+
+/*
+ *  ビットパターンのビット数
+ */
+#ifndef TBIT_TEXPTN					/* タスク例外要因のビット数 */
+#define TBIT_TEXPTN		(sizeof(TEXPTN) * CHAR_BIT)
+#endif /* TBIT_TEXPTN */
+
+#ifndef TBIT_FLGPTN					/* イベントフラグのビット数 */
+#define TBIT_FLGPTN		(sizeof(FLGPTN) * CHAR_BIT)
+#endif /* TBIT_FLGPTN */
+
+/*
+ *  メモリ領域確保のためのマクロ
+ *
+ *  以下のTOPPERS_COUNT_SZとTOPPERS_ROUND_SZの定義は，unitが2の巾乗であ
+ *  ることを仮定している．
+ */
+#ifndef TOPPERS_COUNT_SZ
+#define TOPPERS_COUNT_SZ(sz, unit)	(((sz) + (unit) - 1) / (unit))
+#endif /* TOPPERS_COUNT_SZ */
+#ifndef TOPPERS_ROUND_SZ
+#define TOPPERS_ROUND_SZ(sz, unit)	(((sz) + (unit) - 1) & ~((unit) - 1))
+#endif /* TOPPERS_ROUND_SZ */
+
+#define COUNT_STK_T(sz)		TOPPERS_COUNT_SZ(sz, sizeof(STK_T))
+#define ROUND_STK_T(sz)		TOPPERS_ROUND_SZ(sz, sizeof(STK_T))
+
+#define COUNT_MPF_T(blksz)	TOPPERS_COUNT_SZ(blksz, sizeof(MPF_T))
+#define ROUND_MPF_T(blksz)	TOPPERS_ROUND_SZ(blksz, sizeof(MPF_T))
+
+#define TSZ_DTQMB(dtqcnt)	(sizeof(intptr_t) * (dtqcnt))
+#define TCNT_DTQMB(dtqcnt)	TOPPERS_COUNT_SZ(TSZ_DTQMB(dtqcnt), sizeof(MB_T))
+
+#ifndef TSZ_PDQMB
+#define TSZ_PDQMB(pdqcnt)	(sizeof(intptr_t) * 3 * (pdqcnt))
+#endif /* TSZ_PDQMB */
+#define TCNT_PDQMB(pdqcnt)	TOPPERS_COUNT_SZ(TSZ_PDQMB(pdqcnt), sizeof(MB_T))
+
+#define TSZ_MPFMB(blkcnt)	(sizeof(uint_t) * (blkcnt))
+#define TCNT_MPFMB(blkcnt)	TOPPERS_COUNT_SZ(TSZ_MPFMB(blkcnt), sizeof(MB_T))
+
+/*
+ *  その他の構成定数
+ */
+#define TMAX_MAXSEM		UINT_MAX	/* セマフォの最大資源数の最大値 */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* TOPPERS_KERNEL_H */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/include/log_output.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/include/log_output.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/include/log_output.h	(revision 457)
@@ -0,0 +1,84 @@
+/*
+ *  TOPPERS Software
+ *      Toyohashi Open Platform for Embedded Real-Time Systems
+ * 
+ *  Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
+ *                              Toyohashi Univ. of Technology, JAPAN
+ *  Copyright (C) 2004-2011 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *		システムログのフォーマット出力
+ */
+
+#ifndef TOPPERS_LOG_OUTPUT_H
+#define TOPPERS_LOG_OUTPUT_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <t_syslog.h>
+
+/*
+ *  文字列整形出力
+ *
+ *  formatで指定されるフォーマット記述とp_argsで指定される引数列から作
+ *  成したメッセージを，1文字出力関数putcを用いて出力する．
+ */
+extern void	syslog_printf(const char *format, const intptr_t *p_args,
+										void (*putc)(char)) throw();
+
+/*
+ *  ログ情報の出力
+ *
+ *  p_syslogで指定されるログ情報を文字列に整形し，1文字出力関数putcを用
+ *  いて出力する．
+ */
+extern void	syslog_print(const SYSLOG *p_syslog, void (*putc)(char)) throw();
+
+/*
+ *  ログ情報喪失メッセージ文字列
+ *
+ *  lostlog個のログ情報が失われた旨のメッセージを，1文字出力関数putcを
+ *  用いて出力する．
+ */
+extern void	syslog_lostmsg(uint_t lostlog, void (*putc)(char)) throw();
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* TOPPERS_LOG_OUTPUT_H */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/include/queue.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/include/queue.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/include/queue.h	(revision 457)
@@ -0,0 +1,161 @@
+/*
+ *  TOPPERS Software
+ *      Toyohashi Open Platform for Embedded Real-Time Systems
+ * 
+ *  Copyright (C) 2000 by Embedded and Real-Time Systems Laboratory
+ *                              Toyohashi Univ. of Technology, JAPAN
+ *  Copyright (C) 2006-2011 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *		キュー操作ライブラリ
+ *
+ *  このキュー操作ライブラリでは，キューヘッダを含むリング構造のダブル
+ *  リンクキューを扱う．具体的には，キューヘッダの次エントリはキューの
+ *  先頭のエントリ，前エントリはキューの末尾のエントリとする．また，キ
+ *  ューの先頭のエントリの前エントリと，キューの末尾のエントリの次エン
+ *  トリは，キューヘッダとする．空のキューは，次エントリ，前エントリと
+ *  も自分自身を指すキューヘッダであらわす．
+ */
+
+#ifndef	TOPPERS_QUEUE_H
+#define	TOPPERS_QUEUE_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ *  キューのデータ構造の定義
+ */
+typedef struct queue {
+	struct queue *p_next;		/* 次エントリへのポインタ */
+	struct queue *p_prev;		/* 前エントリへのポインタ */
+} QUEUE;
+
+/*
+ *  キューの初期化
+ *
+ *  p_queueにはキューヘッダを指定する．
+ */
+Inline void
+queue_initialize(QUEUE *p_queue)
+{
+	p_queue->p_prev = p_queue;
+	p_queue->p_next = p_queue;
+}
+
+/*
+ *  キューの前エントリへの挿入
+ *
+ *  p_queueの前にp_entryを挿入する．p_queueにキューヘッダを指定した場
+ *  合には，キューの末尾にp_entryを挿入することになる．
+ */
+Inline void
+queue_insert_prev(QUEUE *p_queue, QUEUE *p_entry)
+{
+	p_entry->p_prev = p_queue->p_prev;
+	p_entry->p_next = p_queue;
+	p_queue->p_prev->p_next = p_entry;
+	p_queue->p_prev = p_entry;
+}
+
+/*
+ *  キューの次エントリへの挿入
+ *
+ *  p_queueの次にp_entryを挿入する．p_queueにキューヘッダを指定した場
+ *  合には，キューの先頭にp_entryを挿入することになる．
+ */
+Inline void
+queue_insert_next(QUEUE *p_queue, QUEUE *p_entry)
+{
+	p_entry->p_prev = p_queue;
+	p_entry->p_next = p_queue->p_next;
+	p_queue->p_next->p_prev = p_entry;
+	p_queue->p_next = p_entry;
+}
+
+/*
+ *  エントリの削除
+ *
+ *  p_entryをキューから削除する．
+ */
+Inline void
+queue_delete(QUEUE *p_entry)
+{
+	p_entry->p_prev->p_next = p_entry->p_next;
+	p_entry->p_next->p_prev = p_entry->p_prev;
+}
+
+/*
+ *  キューの次エントリの取出し
+ *
+ *  p_queueの次エントリをキューから削除し，削除したエントリを返す．
+ *  p_queueにキューヘッダを指定した場合には，キューの先頭のエントリを
+ *  取り出すことになる．p_queueに空のキューを指定して呼び出してはなら
+ *  ない．
+ */
+Inline QUEUE *
+queue_delete_next(QUEUE *p_queue)
+{
+	QUEUE	*p_entry;
+
+	assert(p_queue->p_next != p_queue);
+	p_entry = p_queue->p_next;
+	p_queue->p_next = p_entry->p_next;
+	p_entry->p_next->p_prev = p_queue;
+	return(p_entry);
+}
+
+/*
+ *  キューが空かどうかのチェック
+ *
+ *  p_queueにはキューヘッダを指定する．
+ */
+Inline bool_t
+queue_empty(QUEUE *p_queue)
+{
+	if (p_queue->p_next == p_queue) {
+		assert(p_queue->p_prev == p_queue);
+		return(true);
+	}
+	return(false);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* TOPPERS_QUEUE_H */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/include/sil.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/include/sil.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/include/sil.h	(revision 457)
@@ -0,0 +1,287 @@
+/*
+ *  TOPPERS Software
+ *      Toyohashi Open Platform for Embedded Real-Time Systems
+ * 
+ *  Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
+ *                              Toyohashi Univ. of Technology, JAPAN
+ *  Copyright (C) 2004-2011 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *		システムインタフェースレイヤ
+ *
+ *  システムインタフェースレイヤのサービスコールの定義・宣言とマクロな
+ *  どの定義を含むヘッダファイル．
+ *
+ *  アセンブリ言語のソースファイルからこのファイルをインクルードする時
+ *  は，TOPPERS_MACRO_ONLYを定義しておくことで，マクロ定義以外の記述を
+ *  除くことができる．
+ *
+ *  このファイルをインクルードする前にインクルードしておくべきファイル
+ *  はない．
+ */
+
+#ifndef TOPPERS_SIL_H
+#define TOPPERS_SIL_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ *	TOPPERS共通のデータ型・定数・マクロ
+ */
+#include <t_stddef.h>
+
+/*
+ *  ターゲット依存部
+ */
+#include "target_sil.h"
+
+#ifndef TOPPERS_MACRO_ONLY
+
+/*
+ *  全割込みロック状態の制御
+ *
+ *  SIL_PRE_LOC，SIL_LOC_INT()，SIL_UNL_INT()は，ターゲット依存部で用
+ *  意する．デフォルトの定義は用意していない．
+ */
+
+/*
+ *  微少時間待ち
+ */
+extern void	sil_dly_nse(ulong_t dlytim) throw();
+
+/*
+ *  エンディアンの反転
+ */
+#ifndef TOPPERS_SIL_REV_ENDIAN_UINT16
+#define	TOPPERS_SIL_REV_ENDIAN_UINT16(data) \
+				((((data) & 0xffU) << 8) | (((data) >> 8) & 0xffU))
+#endif /* TOPPERS_SIL_REV_ENDIAN_UINT16 */
+
+#ifndef TOPPERS_SIL_REV_ENDIAN_UINT32
+#define	TOPPERS_SIL_REV_ENDIAN_UINT32(data) \
+				((((data) & 0xffU) << 24) | (((data) & 0xff00U) << 8) \
+					| (((data) >> 8) & 0xff00U) | (((data) >> 24) & 0xffU))
+#endif /* TOPPERS_SIL_REV_ENDIAN_UINT32 */
+
+/*
+ *  メモリ空間アクセス関数
+ */
+#ifndef TOPPERS_OMIT_SIL_ACCESS
+
+/*
+ *  8ビット単位の読出し／書込み
+ */
+#ifdef UINT8_MAX
+
+Inline uint8_t
+sil_reb_mem(const uint8_t *mem)
+{
+	uint8_t	data;
+
+	data = *((const volatile uint8_t *) mem);
+	return(data);
+}
+
+Inline void
+sil_wrb_mem(uint8_t *mem, uint8_t data)
+{
+	*((volatile uint8_t *) mem) = data;
+}
+
+#endif /* UINT8_MAX */
+
+/*
+ *  16ビット単位の読出し／書込み
+ */
+
+Inline uint16_t
+sil_reh_mem(const uint16_t *mem)
+{
+	uint16_t	data;
+
+	data = *((const volatile uint16_t *) mem);
+	return(data);
+}
+
+Inline void
+sil_wrh_mem(uint16_t *mem, uint16_t data)
+{
+	*((volatile uint16_t *) mem) = data;
+}
+
+#ifdef SIL_ENDIAN_BIG			/* ビッグエンディアンプロセッサ */
+
+#define	sil_reh_bem(mem)		sil_reh_mem(mem)
+#define	sil_wrh_bem(mem, data)	sil_wrh_mem(mem, data)
+
+#ifndef TOPPERS_OMIT_SIL_REH_LEM
+
+Inline uint16_t
+sil_reh_lem(const uint16_t *mem)
+{
+	uint16_t	data;
+
+	data = *((const volatile uint16_t *) mem);
+	return(TOPPERS_SIL_REV_ENDIAN_UINT16(data));
+}
+
+#endif /* TOPPERS_OMIT_SIL_REH_LEM */
+#ifndef TOPPERS_OMIT_SIL_WRH_LEM
+
+Inline void
+sil_wrh_lem(uint16_t *mem, uint16_t data)
+{
+	*((volatile uint16_t *) mem) = TOPPERS_SIL_REV_ENDIAN_UINT16(data);
+}
+
+#endif /* TOPPERS_OMIT_SIL_WRH_LEM */
+#else /* SIL_ENDIAN_BIG */
+#ifdef SIL_ENDIAN_LITTLE		/* リトルエンディアンプロセッサ */
+
+#define	sil_reh_lem(mem)		sil_reh_mem(mem)
+#define	sil_wrh_lem(mem, data)	sil_wrh_mem(mem, data)
+
+#ifndef TOPPERS_OMIT_SIL_REH_BEM
+
+Inline uint16_t
+sil_reh_bem(const uint16_t *mem)
+{
+	uint16_t	data;
+
+	data = *((const volatile uint16_t *) mem);
+	return(TOPPERS_SIL_REV_ENDIAN_UINT16(data));
+}
+
+#endif /* TOPPERS_OMIT_SIL_REH_BEM */
+#ifndef TOPPERS_OMIT_SIL_WRH_BEM
+
+Inline void
+sil_wrh_bem(uint16_t *mem, uint16_t data)
+{
+	*((volatile uint16_t *) mem) = TOPPERS_SIL_REV_ENDIAN_UINT16(data);
+}
+
+#endif /* TOPPERS_OMIT_SIL_WRH_BEM */
+#else /* SIL_ENDIAN_LITTLE */
+
+#error Neither SIL_ENDIAN_BIG nor SIL_ENDIAN_LITTLE is defined.
+
+#endif /* SIL_ENDIAN_LITTLE */
+#endif /* SIL_ENDIAN_BIG */
+
+/*
+ *  32ビット単位の読出し／書込み
+ */
+
+Inline uint32_t
+sil_rew_mem(const uint32_t *mem)
+{
+	uint32_t	data;
+
+	data = *((const volatile uint32_t *) mem);
+	return(data);
+}
+
+Inline void
+sil_wrw_mem(uint32_t *mem, uint32_t data)
+{
+	*((volatile uint32_t *) mem) = data;
+}
+
+#ifdef SIL_ENDIAN_BIG			/* ビッグエンディアンプロセッサ */
+
+#define	sil_rew_bem(mem)		sil_rew_mem(mem)
+#define	sil_wrw_bem(mem, data)	sil_wrw_mem(mem, data)
+
+#ifndef TOPPERS_OMIT_SIL_REW_LEM
+
+Inline uint32_t
+sil_rew_lem(const uint32_t *mem)
+{
+	uint32_t	data;
+
+	data = *((const volatile uint32_t *) mem);
+	return(TOPPERS_SIL_REV_ENDIAN_UINT32(data));
+}
+
+#endif /* TOPPERS_OMIT_SIL_REW_LEM */
+#ifndef TOPPERS_OMIT_SIL_WRW_LEM
+
+Inline void
+sil_wrw_lem(uint32_t *mem, uint32_t data)
+{
+	*((volatile uint32_t *) mem) = TOPPERS_SIL_REV_ENDIAN_UINT32(data);
+}
+
+#endif /* TOPPERS_OMIT_SIL_WRW_LEM */
+#else /* SIL_ENDIAN_BIG */		/* リトルエンディアンプロセッサ */
+
+#define	sil_rew_lem(mem)		sil_rew_mem(mem)
+#define	sil_wrw_lem(mem, data)	sil_wrw_mem(mem, data)
+
+#ifndef TOPPERS_OMIT_SIL_REW_BEM
+
+Inline uint32_t
+sil_rew_bem(const uint32_t *mem)
+{
+	uint32_t	data;
+
+	data = *((const volatile uint32_t *) mem);
+	return(TOPPERS_SIL_REV_ENDIAN_UINT32(data));
+}
+
+#endif /* TOPPERS_OMIT_SIL_REW_BEM */
+#ifndef TOPPERS_OMIT_SIL_WRW_BEM
+
+Inline void
+sil_wrw_bem(uint32_t *mem, uint32_t data)
+{
+	*((volatile uint32_t *) mem) = TOPPERS_SIL_REV_ENDIAN_UINT32(data);
+}
+
+#endif /* TOPPERS_OMIT_SIL_WRW_BEM */
+#endif /* SIL_ENDIAN_BIG */
+#endif /* TOPPERS_OMIT_SIL_ACCESS */
+
+#endif /* TOPPERS_MACRO_ONLY */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* TOPPERS_SIL_H */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/include/t_stddef.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/include/t_stddef.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/include/t_stddef.h	(revision 457)
@@ -0,0 +1,286 @@
+/*
+ *  TOPPERS Software
+ *      Toyohashi Open Platform for Embedded Real-Time Systems
+ * 
+ *  Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
+ *                              Toyohashi Univ. of Technology, JAPAN
+ *  Copyright (C) 2004-2012 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *		TOPPERS共通ヘッダファイル
+ *
+ *  TOPPERS関連のすべてのソースファイルでインクルードすべきヘッダファイ
+ *  ル．各種のカーネルやソフトウェア部品で共通に用いることを想定してい
+ *  る．TOPPERSの各種のカーネルやソフトウェア部品で共通に用いるデータ型，
+ *  定数，マクロの定義などを含む．
+ *
+ *  アセンブリ言語のソースファイルからこのファイルをインクルードする時
+ *  は，TOPPERS_MACRO_ONLYを定義しておく．これにより，マクロ定義以外を
+ *  除くようになっている．
+ *
+ *  このファイルをインクルードする前にインクルードしておくべきファイル
+ *  はない．
+ */
+
+#ifndef TOPPERS_T_STDDEF_H
+#define TOPPERS_T_STDDEF_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ *  ターゲット依存部
+ */
+#include "target_stddef.h"
+
+/*
+ *  C言語/EC++でthrow()に対処するための定義
+ */
+#if !defined(__cplusplus) || defined(__embedded_cplusplus)
+#define throw()
+#endif
+
+#ifndef TOPPERS_MACRO_ONLY
+
+/*
+ *  ターゲット依存のデータ型のマクロのデフォルト定義
+ */
+#ifndef TOPPERS_bool
+#define TOPPERS_bool	int				/* ブール型 */
+#endif /* TOPPERS_bool */
+
+#ifndef TOPPERS_size
+#define TOPPERS_size	uintptr_t		/* サイズ型 */
+#endif /* TOPPERS_size */
+
+#ifndef TOPPERS_fp
+struct TOPPERS_dummy_t { int TOPPERS_dummy_field; };
+typedef	void			(*TOPPERS_fp_t)(struct TOPPERS_dummy_t);
+#define TOPPERS_fp		TOPPERS_fp_t	/* プログラムの起動番地 */
+#endif /* TOPPERS_fp */
+
+/*
+ *  共通データ型
+ */
+typedef TOPPERS_bool	bool_t;		/* 真偽値 */
+
+typedef signed int		int_t;		/* 自然なサイズの符号付き整数 */
+typedef unsigned int	uint_t;		/* 自然なサイズの符号無し整数 */
+
+typedef signed long		long_t;		/* 長めのサイズの符号付き整数 */
+typedef unsigned long	ulong_t;	/* 長めのサイズの符号無し整数 */
+
+typedef int_t			FN;			/* 機能コード */
+typedef	int_t			ER;			/* エラーコード */
+typedef	int_t			ID;			/* オブジェクトのID番号 */
+typedef	uint_t			ATR;		/* オブジェクトの属性 */
+typedef	uint_t			STAT;		/* オブジェクトの状態 */
+typedef	uint_t			MODE;		/* サービスコールの動作モード */
+typedef	int_t			PRI;		/* 優先度 */
+typedef	TOPPERS_size	SIZE;		/* メモリ領域のサイズ */
+
+typedef	int_t			TMO;		/* タイムアウト指定 */
+typedef	uint_t			RELTIM;		/* 相対時間 */
+typedef	ulong_t			SYSTIM;		/* システム時刻 */
+typedef	ulong_t			SYSUTM;		/* 性能評価用システム時刻 */
+
+typedef	TOPPERS_fp		FP;			/* プログラムの起動番地 */
+
+typedef	int_t			ER_BOOL;	/* エラーコードまたは真偽値 */
+typedef	int_t			ER_ID;		/* エラーコードまたはID番号 */
+typedef	int_t			ER_UINT;	/* エラーコードまたは符号無し整数 */
+
+typedef uintptr_t		MB_T;		/* 管理領域を確保するためのデータ型 */
+
+typedef	uint32_t		ACPTN;		/* アクセス許可パターン */
+typedef	struct acvct {				/* アクセス許可ベクタ */
+	ACPTN		acptn1;				/* 通常操作1のアクセス許可パターン */
+	ACPTN		acptn2;				/* 通常操作2のアクセス許可パターン */
+	ACPTN		acptn3;				/* 管理操作のアクセス許可パターン */
+	ACPTN		acptn4;				/* 参照操作のアクセス許可パターン */
+} ACVCT;
+
+#endif /* TOPPERS_MACRO_ONLY */
+
+/*
+ *  整数定数を作るマクロ
+ */
+#ifndef UINT_C
+#define UINT_C(val)		(val ## U)		/* uint_t型の定数を作るマクロ */
+#endif /* UINT_C */
+
+#ifndef ULONG_C
+#define ULONG_C(val)	(val ## UL)		/* ulong_t型の定数を作るマクロ */
+#endif /* ULONG_C */
+
+/*
+ *  一般定数
+ */
+#ifndef NULL
+#define NULL		0			/* 無効ポインタ */
+#endif /* NULL */
+
+#ifndef true
+#define true		1			/* 真 */
+#endif /* true */
+
+#ifndef false
+#define false		0			/* 偽 */
+#endif /* false */
+
+#define E_OK		0			/* 正常終了 */
+
+/*
+ *  メインエラーコード
+ */
+#define E_SYS		(-5)		/* システムエラー */
+#define E_NOSPT		(-9)		/* 未サポート機能 */
+#define E_RSFN		(-10)		/* 予約機能コード */
+#define E_RSATR		(-11)		/* 予約属性 */
+#define E_PAR		(-17)		/* パラメータエラー */
+#define E_ID		(-18)		/* 不正ID番号 */
+#define E_CTX		(-25)		/* コンテキストエラー */
+#define E_MACV		(-26)		/* メモリアクセス違反 */
+#define E_OACV		(-27)		/* オブジェクトアクセス違反 */
+#define E_ILUSE		(-28)		/* サービスコール不正使用 */
+#define E_NOMEM		(-33)		/* メモリ不足 */
+#define E_NOID		(-34)		/* ID番号不足 */
+#define E_NORES		(-35)		/* 資源不足 */
+#define E_OBJ		(-41)		/* オブジェクト状態エラー */
+#define E_NOEXS		(-42)		/* オブジェクト未生成 */
+#define E_QOVR		(-43)		/* キューイングオーバーフロー */
+#define E_RLWAI		(-49)		/* 待ち状態の強制解除 */
+#define E_TMOUT		(-50)		/* ポーリング失敗またはタイムアウト */
+#define E_DLT		(-51)		/* 待ちオブジェクトの削除 */
+#define E_CLS		(-52)		/* 待ちオブジェクトの状態変化 */
+#define E_WBLK		(-57)		/* ノンブロッキング受付け */
+#define E_BOVR		(-58)		/* バッファオーバーフロー */
+
+/*
+ *  オブジェクト属性
+ */
+#define TA_NULL		UINT_C(0)	/* オブジェクト属性を指定しない */
+
+/*
+ *  タイムアウト指定
+ */
+#define TMO_POL		0			/* ポーリング */
+#define TMO_FEVR	(-1)		/* 永久待ち */
+#define TMO_NBLK	(-2)		/* ノンブロッキング */
+
+/*
+ *  アクセス許可パターン
+ */
+#define TACP_KERNEL		(0U)	/* カーネルドメインだけにアクセスを許可 */
+#define TACP_SHARED		(~0U)	/* すべてのドメインからアクセスを許可 */
+
+/*
+ *  型に関する情報を取り出すためのマクロ
+ *
+ *  以下のALIGN_TYPEの定義は，アラインメントの単位が2の巾乗であることを
+ *  仮定している．
+ */
+#ifndef offsetof
+#define	offsetof(structure, field)	((uintptr_t) &(((structure *) 0)->field))
+#endif /* offsetof */
+
+#ifndef alignof
+#define alignof(type)	offsetof(struct { char field1; type field2; }, field2)
+#endif /* alignof */
+
+#ifndef ALIGN_TYPE				/* アラインメントのチェック */
+#define ALIGN_TYPE(addr, type) \
+						((((uintptr_t)(addr)) & (alignof(type) - 1)) == 0U)
+#endif /* ALIGN_TYPE */
+
+/*
+ *  assertマクロ
+ */
+#undef assert
+#ifndef NDEBUG
+#define assert(exp)		((void)((exp) ? 0 : (TOPPERS_assert_fail(#exp, \
+							__FILE__, __LINE__), TOPPERS_assert_abort(), 0)))
+#else /* NDEBUG */
+#define assert(exp)		((void) 0)
+#endif /* NDEBUG */
+
+#ifdef __cplusplus
+}
+#endif
+
+/*
+ *  エラーコード生成・分解マクロ
+ *
+ *  以下のマクロ定義は，符号付き整数が2の補数で表現されており，右シフト
+ *  演算子（>>）が算術シフトされることを仮定している．そうでない開発環
+ *  境では，target_stddef.hでこれらの定義を上書きしなければならない．
+ *
+ *  MERCDマクロの定義は，メインエラーコードが負であることを仮定している．
+ *  そうでない場合，2つの定義が一致しなくなる．
+ */
+#ifndef ERCD
+#define ERCD(mercd, sercd) \
+				((ER)((((uint_t)(sercd)) << 8) | (((uint_t)(mercd)) & 0xffU)))
+#endif /* ERCD */
+
+#ifndef MERCD
+#ifdef INT8_MAX
+#define MERCD(ercd)		((ER)((int8_t)(ercd)))
+#else /* INT8_MAX */
+#define MERCD(ercd)		((ER)(((uint_t) ercd) | ~0xffU))
+#endif /* INT8_MAX */
+#endif /* MERCD */
+
+#ifndef SERCD
+#define SERCD(ercd)		((ER)((ercd) >> 8))
+#endif /* SERCD */
+
+/*
+ *  アクセス許可パターン生成マクロ
+ */
+#define TACP(domid)		(1U << ((domid) - 1))	/* domidだけにアクセスを許可 */
+
+/*
+ *  相対時間（RELTIM）に指定できる最大値
+ */
+#if UINT_MAX < LONG_MAX
+#define TMAX_RELTIM		((RELTIM) UINT_MAX)
+#else /* UINT_MAX < LONG_MAX */
+#define TMAX_RELTIM		((RELTIM) LONG_MAX)
+#endif /* UINT_MAX < LONG_MAX */
+
+#endif /* TOPPERS_T_STDDEF_H */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/include/t_stdlib.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/include/t_stdlib.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/include/t_stdlib.h	(revision 457)
@@ -0,0 +1,74 @@
+/*
+ *  TOPPERS Software
+ *      Toyohashi Open Platform for Embedded Real-Time Systems
+ * 
+ *  Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
+ *                              Toyohashi Univ. of Technology, JAPAN
+ *  Copyright (C) 2004-2006 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *		基本的なライブラリ関数
+ */
+
+#ifndef TOPPERS_T_STDLIB_H
+#define TOPPERS_T_STDLIB_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ *  エラーメッセージ文字列を返す関数
+ *
+ *  ercdで指定されたエラーコードのメインエラーコードの名称（E_PAR，
+ *  E_OBJなど）の文字列を返す関数．
+ */
+extern const char	*itron_strerror(ER ercd) throw();
+
+/*
+ *  エラーメッセージのログ出力
+ *
+ *  サービスコールがエラーを返した場合に，そのファイル名，行番号，メイ
+ *  ンエラーコード等を表示するための関数．
+ */
+extern void		t_perror(uint_t prio, const char *file, int_t line,
+									const char *expr, ER ercd) throw();
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* TOPPERS_T_STDLIB_H */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/include/t_syslog.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/include/t_syslog.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/include/t_syslog.h	(revision 457)
@@ -0,0 +1,335 @@
+/*
+ *  TOPPERS/ASP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Advanced Standard Profile Kernel
+ * 
+ *  Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
+ *                              Toyohashi Univ. of Technology, JAPAN
+ *  Copyright (C) 2004-2011 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *		システムログ出力を行うための定義
+ *
+ *  システムログサービスは，システムのログ情報を出力するためのサービス
+ *  である．カーネルからのログ情報の出力にも用いるため，内部で待ち状態
+ *  にはいることはない．
+ *
+ *  ログ情報は，カーネル内のログバッファに書き込むか，低レベルの文字出
+ *  力関数を用いて出力する．どちらを使うかは，拡張サービスコールで切り
+ *  換えることができる．
+ *
+ *  ログバッファ領域がオーバフローした場合には，古いログ情報を消して上
+ *  書きする．
+ *
+ *  アセンブリ言語のソースファイルからこのファイルをインクルードする時
+ *  は，TOPPERS_MACRO_ONLYを定義しておくことで，マクロ定義以外の記述を
+ *  除くことができる．
+ *
+ *  このファイルをインクルードする前に，t_stddef.hをインクルードしてお
+ *  くことが必要である．
+ */
+
+#ifndef TOPPERS_T_SYSLOG_H
+#define TOPPERS_T_SYSLOG_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ *  ログ情報の種別の定義
+ */
+#define LOG_TYPE_COMMENT	UINT_C(0x01)	/* コメント */
+#define LOG_TYPE_ASSERT		UINT_C(0x02)	/* アサーションの失敗 */
+
+#define LOG_TYPE_INH		UINT_C(0x11)	/* 割込みハンドラ */
+#define LOG_TYPE_ISR		UINT_C(0x12)	/* 割込みサービスルーチン */
+#define LOG_TYPE_CYC		UINT_C(0x13)	/* 周期ハンドラ */
+#define LOG_TYPE_ALM		UINT_C(0x14)	/* アラームハンドラ */
+#define LOG_TYPE_OVR		UINT_C(0x15)	/* オーバランハンドラ */
+#define LOG_TYPE_EXC		UINT_C(0x16)	/* CPU例外ハンドラ */
+#define LOG_TYPE_TEX		UINT_C(0x17)	/* タスク例外処理ルーチン */
+#define LOG_TYPE_TSKSTAT	UINT_C(0x18)	/* タスク状態変化 */
+#define LOG_TYPE_DSP		UINT_C(0x19)	/* ディスパッチャ */
+#define LOG_TYPE_SVC		UINT_C(0x1a)	/* サービスコール */
+
+#define LOG_ENTER			UINT_C(0x00)	/* 入口／開始 */
+#define LOG_LEAVE			UINT_C(0x80)	/* 出口／終了 */
+
+/*
+ *  ログ情報の重要度の定義
+ */
+#define LOG_EMERG			UINT_C(0)		/* シャットダウンに値するエラー */
+#define LOG_ALERT			UINT_C(1)
+#define LOG_CRIT			UINT_C(2)
+#define LOG_ERROR			UINT_C(3)		/* システムエラー */
+#define LOG_WARNING			UINT_C(4)		/* 警告メッセージ */
+#define LOG_NOTICE			UINT_C(5)
+#define LOG_INFO			UINT_C(6)
+#define LOG_DEBUG			UINT_C(7)		/* デバッグ用メッセージ */
+
+#ifndef TOPPERS_MACRO_ONLY
+
+/*
+ *  ログ情報のデータ構造
+ */
+
+#define TMAX_LOGINFO	6
+
+typedef struct {
+	uint_t		logtype;				/* ログ情報の種別 */
+	SYSTIM		logtim;					/* ログ時刻 */
+	intptr_t	loginfo[TMAX_LOGINFO];	/* その他のログ情報 */
+} SYSLOG;
+
+/*
+ *  ログ情報の重要度のビットマップを作るためのマクロ
+ */
+#define LOG_MASK(prio)		(1U << (prio))
+#define LOG_UPTO(prio)		((1U << ((prio) + 1)) - 1)
+
+/*
+ *  パケット形式の定義
+ */
+typedef struct t_syslog_rlog {
+	uint_t	count;		/* ログバッファ中のログの数 */
+	uint_t	lost;		/* 失われたログの数 */
+	uint_t	logmask;	/* ログバッファに記録すべき重要度 */
+	uint_t	lowmask;	/* 低レベル出力すべき重要度 */
+} T_SYSLOG_RLOG;
+
+/*
+ *  ログ情報を出力するためのライブラリ関数
+ */
+
+#ifndef TOPPERS_OMIT_SYSLOG
+
+extern ER	syslog_wri_log(uint_t prio, const SYSLOG *p_syslog) throw();
+
+Inline void
+_syslog_0(uint_t prio, uint_t type)
+{
+	SYSLOG	logbuf;
+
+	logbuf.logtype = type;
+	(void) syslog_wri_log(prio, &logbuf);
+}
+
+Inline void
+_syslog_1(uint_t prio, uint_t type, intptr_t arg1)
+{
+	SYSLOG	logbuf;
+
+	logbuf.logtype = type;
+	logbuf.loginfo[0] = arg1;
+	(void) syslog_wri_log(prio, &logbuf);
+}
+
+Inline void
+_syslog_2(uint_t prio, uint_t type, intptr_t arg1, intptr_t arg2)
+{
+	SYSLOG	logbuf;
+
+	logbuf.logtype = type;
+	logbuf.loginfo[0] = arg1;
+	logbuf.loginfo[1] = arg2;
+	(void) syslog_wri_log(prio, &logbuf);
+}
+
+Inline void
+_syslog_3(uint_t prio, uint_t type, intptr_t arg1, intptr_t arg2,
+														intptr_t arg3)
+{
+	SYSLOG	logbuf;
+
+	logbuf.logtype = type;
+	logbuf.loginfo[0] = arg1;
+	logbuf.loginfo[1] = arg2;
+	logbuf.loginfo[2] = arg3;
+	(void) syslog_wri_log(prio, &logbuf);
+}
+
+Inline void
+_syslog_4(uint_t prio, uint_t type, intptr_t arg1, intptr_t arg2,
+										intptr_t arg3, intptr_t arg4)
+{
+	SYSLOG	logbuf;
+
+	logbuf.logtype = type;
+	logbuf.loginfo[0] = arg1;
+	logbuf.loginfo[1] = arg2;
+	logbuf.loginfo[2] = arg3;
+	logbuf.loginfo[3] = arg4;
+	(void) syslog_wri_log(prio, &logbuf);
+}
+
+Inline void
+_syslog_5(uint_t prio, uint_t type, intptr_t arg1, intptr_t arg2,
+							intptr_t arg3, intptr_t arg4, intptr_t arg5)
+{
+	SYSLOG	logbuf;
+
+	logbuf.logtype = type;
+	logbuf.loginfo[0] = arg1;
+	logbuf.loginfo[1] = arg2;
+	logbuf.loginfo[2] = arg3;
+	logbuf.loginfo[3] = arg4;
+	logbuf.loginfo[4] = arg5;
+	(void) syslog_wri_log(prio, &logbuf);
+}
+
+Inline void
+_syslog_6(uint_t prio, uint_t type, intptr_t arg1, intptr_t arg2,
+				intptr_t arg3, intptr_t arg4, intptr_t arg5, intptr_t arg6)
+{
+	SYSLOG	logbuf;
+
+	logbuf.logtype = type;
+	logbuf.loginfo[0] = arg1;
+	logbuf.loginfo[1] = arg2;
+	logbuf.loginfo[2] = arg3;
+	logbuf.loginfo[3] = arg4;
+	logbuf.loginfo[4] = arg5;
+	logbuf.loginfo[5] = arg6;
+	(void) syslog_wri_log(prio, &logbuf);
+}
+
+/*
+ *  ログ情報（コメント）を出力するためのライブラリ関数（vasyslog.c）
+ */
+extern void	syslog(uint_t prio, const char *format, ...) throw();
+
+#else /* TOPPERS_OMIT_SYSLOG */
+
+/*
+ *  システムログ出力を抑止する場合
+ */
+
+Inline void
+_syslog_0(uint_t prio, uint_t type)
+{
+}
+
+Inline void
+_syslog_1(uint_t prio, uint_t type, intptr_t arg1)
+{
+}
+
+Inline void
+_syslog_2(uint_t prio, uint_t type, intptr_t arg1, intptr_t arg2)
+{
+}
+
+Inline void
+_syslog_3(uint_t prio, uint_t type, intptr_t arg1, intptr_t arg2,
+														intptr_t arg3)
+{
+}
+
+Inline void
+_syslog_4(uint_t prio, uint_t type, intptr_t arg1, intptr_t arg2,
+										intptr_t arg3, intptr_t arg4)
+{
+}
+
+Inline void
+_syslog_5(uint_t prio, uint_t type, intptr_t arg1, intptr_t arg2,
+							intptr_t arg3, intptr_t arg4, intptr_t arg5)
+{
+}
+
+Inline void
+_syslog_6(uint_t prio, uint_t type, intptr_t arg1, intptr_t arg2,
+				intptr_t arg3, intptr_t arg4, intptr_t arg5, intptr_t arg6)
+{
+}
+
+Inline void
+syslog(uint_t prio, const char *format, ...)
+{
+}
+
+#endif /* TOPPERS_OMIT_SYSLOG */
+
+/*
+ *  ログ情報（コメント）を出力するためのマクロ
+ *
+ *  formatおよび後続の引数から作成したメッセージを，重大度prioでログ情
+ *  報として出力するためのマクロ．arg1～argnはintptr_t型にキャストする
+ *  ため，intptr_t型に型変換できる任意の型でよい．
+ */
+
+#define syslog_0(prio, format) \
+				_syslog_1(prio, LOG_TYPE_COMMENT, (intptr_t)(format))
+
+#define syslog_1(prio, format, arg1) \
+				_syslog_2(prio, LOG_TYPE_COMMENT, (intptr_t)(format), \
+														(intptr_t)(arg1))
+
+#define syslog_2(prio, format, arg1, arg2) \
+				_syslog_3(prio, LOG_TYPE_COMMENT, (intptr_t)(format), \
+										(intptr_t)(arg1), (intptr_t)(arg2))
+
+#define syslog_3(prio, format, arg1, arg2, arg3) \
+				_syslog_4(prio, LOG_TYPE_COMMENT, (intptr_t)(format), \
+						(intptr_t)(arg1), (intptr_t)(arg2), (intptr_t)(arg3))
+
+#define syslog_4(prio, format, arg1, arg2, arg3, arg4) \
+				_syslog_5(prio, LOG_TYPE_COMMENT, (intptr_t)(format), \
+						(intptr_t)(arg1), (intptr_t)(arg2), (intptr_t)(arg3), \
+														(intptr_t)(arg4))
+
+#define syslog_5(prio, format, arg1, arg2, arg3, arg4, arg5) \
+				_syslog_6(prio, LOG_TYPE_COMMENT, (intptr_t)(format), \
+						(intptr_t)(arg1), (intptr_t)(arg2), (intptr_t)(arg3), \
+										(intptr_t)(arg4), (intptr_t)(arg5))
+
+/*
+ *  ログ情報（アサーションの失敗）を出力するためのマクロ
+ */
+#ifndef TOPPERS_assert_fail
+#define TOPPERS_assert_fail(exp, file, line) \
+				_syslog_3(LOG_EMERG, LOG_TYPE_ASSERT, (intptr_t)(file), \
+										(intptr_t)(line), (intptr_t)(exp))
+#endif /* TOPPERS_assert_fail */
+
+#endif /* TOPPERS_MACRO_ONLY */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* TOPPERS_T_SYSLOG_H */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/include/test_lib.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/include/test_lib.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/include/test_lib.h	(revision 457)
@@ -0,0 +1,150 @@
+/*
+ *  TOPPERS Software
+ *      Toyohashi Open Platform for Embedded Real-Time Systems
+ * 
+ *  Copyright (C) 2005-2013 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  $Id$
+ */
+
+/* 
+ *		テストプログラム用ライブラリ
+ */
+
+#ifndef TOPPERS_TEST_LIB_H
+#define TOPPERS_TEST_LIB_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <t_stddef.h>
+
+/*
+ *  ターゲット依存の定義
+ */
+#include "target_test.h"
+
+/*
+ *	自己診断関数の型
+ */
+typedef ER (*BIT_FUNC)(void);
+
+/*
+ *	自己診断関数の設定
+ */
+extern void	set_bit_func(BIT_FUNC bit_func);
+
+/*
+ *  テストプログラムの開始
+ */
+extern void	test_start(char *progname);
+
+/*
+ *  システムログの出力処理
+ */
+extern void	syslog_flush(void);
+
+/*
+ *	テストプログラムの終了
+ */
+extern void	test_finish(void);
+
+/*
+ *	チェックポイント
+ */
+extern void	check_point(uint_t count);
+
+/*
+ *	完了チェックポイント
+ */
+extern void	check_finish(uint_t count);
+
+/*
+ *	条件チェック
+ */
+extern void	_check_assert(const char *expr, const char *file, int_t line);
+#define check_assert(exp) \
+	((void)(!(exp) ? (_check_assert(#exp, __FILE__, __LINE__), 0) : 0))
+
+/*
+ *	エラーコードチェック
+ */
+extern void	_check_ercd(ER ercd, const char *file, int_t line);
+#define check_ercd(ercd, expected_ercd) \
+	((void)((ercd) != (expected_ercd) ? \
+					(_check_ercd(ercd, __FILE__, __LINE__), 0) : 0))
+
+/*
+ *	システム状態のチェック
+ */
+Inline void
+check_state(bool_t ctx, bool_t loc, PRI ipm, bool_t dsp,
+										bool_t dpn, bool_t tex)
+{
+	PRI		intpri;
+	ER		ercd;
+
+	check_assert(sns_ctx() == ctx);
+	check_assert(sns_loc() == loc);
+	if (!loc) {
+		/*
+		 *  IPMのチェックは，CPUロック解除状態の場合にのみ行う．
+		 */
+		ercd = get_ipm(&intpri);
+		check_ercd(ercd, E_OK);
+		check_assert(intpri == ipm);
+	}
+	check_assert(sns_dsp() == dsp);
+	check_assert(sns_dpn() == dpn);
+	check_assert(sns_tex() == tex);
+}
+
+/*
+ *	システム状態のチェック（非タスクコンテキスト用）
+ */
+Inline void
+check_state_i(bool_t ctx, bool_t loc, bool_t dsp, bool_t dpn, bool_t tex)
+{
+	check_assert(sns_ctx() == ctx);
+	check_assert(sns_loc() == loc);
+	check_assert(sns_dsp() == dsp);
+	check_assert(sns_dpn() == dpn);
+	check_assert(sns_tex() == tex);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* TOPPERS_TEST_LIB_H */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/jpeg-9b/Makefile
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/jpeg-9b/Makefile	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/jpeg-9b/Makefile	(revision 457)
@@ -0,0 +1,100 @@
+
+ROOT_PATH = ..
+
+#
+#  ãªãã¸ã§ã¯ããã¡ã¤ã«åã®å®ç¾©
+#
+OBJNAME = libjpeg
+OBJFILE = $(OBJNAME).a
+
+ifeq ($(TARGET),)
+TARGET = stm32f7discovery_gcc
+endif
+
+CC  =	arm-none-eabi-gcc
+CXX	=	arm-none-eabi-g++
+AR  =	arm-none-eabi-ar
+NM  =	arm-none-eabi-nm
+OBJCOPY = arm-none-eabi-objcopy
+OBJDUMP = arm-none-eabi-objdump
+
+LDSCRIPT = stm32F7_rom.ld
+
+ifeq ($(MCPU),)
+MCPU = cortex-m7
+endif
+
+ifeq ($(FPU),)
+FPU = fpv4
+endif
+
+COPTS   = -mcpu=$(MCPU) -Wa,--gstabs -mthumb -mthumb-interwork -mlittle-endian
+
+ifeq ($(FPU),fpv4)
+COPTS  := $(COPTS) -mfloat-abi=softfp -mfpu=fpv4-sp-d16
+else
+COPTS  := $(COPTS) -mfloat-abi=hard -mfpu=fpv5-d16
+endif
+
+COPTS  := $(COPTS) -nostdlib -O2 -g -Wall
+CDEFS   = -DNEED_BSD_STRINGS -DTRUE=1
+
+
+INCLUDES = -I.
+
+TARGET_DIR = .
+RTOS_DIR = $(ROOT_PATH)
+UTASK_DIR = .
+vpath %.c $(UTASK_DIR)
+vpath %.S $(UTASK_DIR)
+
+COBJS = jaricom.o jcapimin.o jcapistd.o jcarith.o jccoefct.o jccolor.o \
+        jcdctmgr.o jchuff.o jcinit.o jcmainct.o jcmarker.o jcmaster.o \
+        jcomapi.o jcparam.o jcprepct.o jcsample.o jctrans.o jdapimin.o \
+        jdapistd.o jdarith.o jdatadst.o jdatasrc.o jdcoefct.o jdcolor.o \
+        jddctmgr.o jdhuff.o jdinput.o jdmainct.o jdmarker.o jdmaster.o \
+        jdmerge.o jdpostct.o jdsample.o jdtrans.o jerror.o jfdctflt.o \
+        jfdctfst.o jfdctint.o jidctflt.o jidctfst.o jidctint.o jquant1.o \
+        jquant2.o jutils.o jmemmgr.o jmemnobs.o \
+		wrppm.o
+
+AOBJS = 
+
+INCLUDES := -I$(UTASK_DIR) -I$(RTOS_DIR)/monitor  -I$(RTOS_DIR) \
+	-I$(RTOS_DIR)/target/$(TARGET) -I$(RTOS_DIR)/arch $(INCLUDES)
+CFLAGS = $(COPTS) $(CDEFS) $(INCLUDES)
+LDFLAGS := -nostdlib $(LDFLAGS)
+
+ifdef LDSCRIPT
+    LDFLAGS := $(LDFLAGS) -T $(LDSCRIPT)
+endif
+
+all:	$(OBJFILE)
+
+$(OBJFILE):	$(COBJS) $(AOBJS)
+	$(AR) -rcs $(OBJFILE) $(COBJS) $(AOBJS)
+
+$(COBJS): %.o: %.c
+	$(CC) -c $(CFLAGS) $<
+
+$(AOBJS): %.o: %.S
+	$(CC) -c $(CFLAGS) $<
+
+# rules
+
+monmain.o	: $(UTASK_DIR)/monmain.c \
+		$(TARGET_DIR)/sys_defs.h $(UTASK_DIR)/comdefs.h $(UTASK_DIR)/mondefs.h $(UTASK_DIR)/serial.h
+
+monitor.o	: $(UTASK_DIR)/monitor.c \
+		$(TARGET_DIR)/sys_defs.h $(UTASK_DIR)/comdefs.h $(UTASK_DIR)/mondefs.h $(UTASK_DIR)/serial.h
+
+common.o	: $(UTASK_DIR)/common.c \
+		$(TARGET_DIR)/sys_defs.h $(UTASK_DIR)/comdefs.h $(UTASK_DIR)/serial.h
+
+serial.o	: $(UTASK_DIR)/serial.c \
+		$(TARGET_DIR)/sys_defs.h $(UTASK_DIR)/comdefs.h $(UTASK_DIR)/serial.h
+
+clean:
+	rm -f *.o
+	rm -f $(OBJFILE)
+
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/jpeg-9b/jconfig.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/jpeg-9b/jconfig.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/jpeg-9b/jconfig.h	(revision 457)
@@ -0,0 +1,60 @@
+/* jconfig.h.  Generated from jconfig.cfg by configure.  */
+/* jconfig.cfg --- source file edited by configure script */
+/* see jconfig.txt for explanations */
+
+#define HAVE_PROTOTYPES 1
+#define HAVE_UNSIGNED_CHAR 1
+#define HAVE_UNSIGNED_SHORT 1
+/* #undef void */
+/* #undef const */
+/* #undef CHAR_IS_UNSIGNED */
+#define HAVE_STDDEF_H 1
+#define HAVE_STDLIB_H 1
+#define HAVE_LOCALE_H 1
+/* #undef NEED_BSD_STRINGS */
+/* #undef NEED_SYS_TYPES_H */
+/* #undef NEED_FAR_POINTERS */
+/* #undef NEED_SHORT_EXTERNAL_NAMES */
+/* Define this if you get warnings about undefined structures. */
+/* #undef INCOMPLETE_TYPES_BROKEN */
+
+/* Define "boolean" as unsigned char, not enum, on Windows systems. */
+#ifdef _WIN32
+#ifndef __RPCNDR_H__		/* don't conflict if rpcndr.h already read */
+typedef unsigned char boolean;
+#endif
+#ifndef FALSE			/* in case these macros already exist */
+#define FALSE	0		/* values of boolean */
+#endif
+#ifndef TRUE
+#define TRUE	1
+#endif
+#define HAVE_BOOLEAN		/* prevent jmorecfg.h from redefining it */
+#endif
+
+#ifdef JPEG_INTERNALS
+
+/* #undef RIGHT_SHIFT_IS_UNSIGNED */
+#define INLINE __inline__
+/* These are for configuring the JPEG memory manager. */
+/* #undef DEFAULT_MAX_MEM */
+/* #undef NO_MKTEMP */
+
+#endif /* JPEG_INTERNALS */
+
+#ifdef JPEG_CJPEG_DJPEG
+
+#define BMP_SUPPORTED		/* BMP image file format */
+#define GIF_SUPPORTED		/* GIF image file format */
+#define PPM_SUPPORTED		/* PBMPLUS PPM/PGM image file format */
+/* #undef RLE_SUPPORTED */
+#define TARGA_SUPPORTED		/* Targa image file format */
+
+/* #undef TWO_FILE_COMMANDLINE */
+/* #undef NEED_SIGNAL_CATCHER */
+/* #undef DONT_USE_B_MODE */
+
+/* Define this if you want percent-done progress reports from cjpeg/djpeg. */
+/* #undef PROGRESS_REPORT */
+
+#endif /* JPEG_CJPEG_DJPEG */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/kernel/Makefile.kernel
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/kernel/Makefile.kernel	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/kernel/Makefile.kernel	(revision 457)
@@ -0,0 +1,144 @@
+#
+#  TOPPERS/ASP Kernel
+#      Toyohashi Open Platform for Embedded Real-Time Systems/
+#      Advanced Standard Profile Kernel
+# 
+#  Copyright (C) 2003 by Embedded and Real-Time Systems Laboratory
+#                              Toyohashi Univ. of Technology, JAPAN
+#  Copyright (C) 2005-2010 by Embedded and Real-Time Systems Laboratory
+#              Graduate School of Information Science, Nagoya Univ., JAPAN
+# 
+#  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+#  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+#  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+#  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+#      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+#      スコード中に含まれていること．
+#  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+#      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+#      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+#      の無保証規定を掲載すること．
+#  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+#      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+#      と．
+#    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+#        作権表示，この利用条件および下記の無保証規定を掲載すること．
+#    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+#        報告すること．
+#  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+#      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+#      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+#      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+#      免責すること．
+# 
+#  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+#  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+#  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+#  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+#  の責任を負わない．
+# 
+#  @(#) $Id$
+# 
+
+#
+#		カーネルのファイル構成の定義
+#
+
+#
+#  1つのソースファイルから複数のオブジェクトファイルを生成するように作
+#  成されたソースファイルのリスト
+#
+KERNEL_FCSRCS = startup.c task.c wait.c time_event.c \
+				task_manage.c task_refer.c task_sync.c task_except.c \
+				semaphore.c eventflag.c dataqueue.c pridataq.c mailbox.c \
+				mutex.c mempfix.c time_manage.c cyclic.c alarm.c \
+				sys_manage.c interrupt.c exception.c
+
+#
+#  各ソースファイルから生成されるオブジェクトファイルのリスト
+#
+startup = sta_ker.o ext_ker.o kermem.o
+
+task = tskini.o tsksched.o tskrun.o tsknrun.o \
+		tskdmt.o tskact.o tskpri.o tskrot.o tsktex.o
+
+wait = waimake.o waicmp.o waitmo.o waitmook.o \
+		wairel.o wobjwai.o wobjwaitmo.o iniwque.o
+
+time_event = tmeini.o tmeup.o tmedown.o tmeins.o tmedel.o tmeltim.o sigtim.o
+
+task_manage = acre_tsk.o del_tsk.o act_tsk.o iact_tsk.o can_act.o \
+		ext_tsk.o ter_tsk.o chg_pri.o get_pri.o get_inf.o
+
+task_refer = ref_tsk.o
+
+task_sync = slp_tsk.o tslp_tsk.o wup_tsk.o iwup_tsk.o can_wup.o \
+		rel_wai.o irel_wai.o sus_tsk.o rsm_tsk.o dly_tsk.o
+
+task_except = def_tex.o ras_tex.o iras_tex.o dis_tex.o ena_tex.o \
+		sns_tex.o ref_tex.o
+
+semaphore = semini.o acre_sem.o del_sem.o sig_sem.o isig_sem.o \
+		wai_sem.o pol_sem.o twai_sem.o ini_sem.o ref_sem.o
+
+eventflag = flgini.o flgcnd.o acre_flg.o del_flg.o set_flg.o iset_flg.o \
+		clr_flg.o wai_flg.o pol_flg.o twai_flg.o ini_flg.o ref_flg.o
+
+dataqueue = dtqini.o dtqenq.o dtqfenq.o dtqdeq.o dtqsnd.o dtqfsnd.o dtqrcv.o \
+		acre_dtq.o del_dtq.o snd_dtq.o psnd_dtq.o ipsnd_dtq.o tsnd_dtq.o \
+		fsnd_dtq.o ifsnd_dtq.o rcv_dtq.o prcv_dtq.o trcv_dtq.o ini_dtq.o \
+		ref_dtq.o
+
+pridataq = pdqini.o pdqenq.o pdqdeq.o pdqsnd.o pdqrcv.o \
+		acre_pdq.o del_pdq.o snd_pdq.o psnd_pdq.o ipsnd_pdq.o tsnd_pdq.o \
+		rcv_pdq.o prcv_pdq.o trcv_pdq.o ini_pdq.o ref_pdq.o
+
+mailbox = mbxini.o acre_mbx.o del_mbx.o snd_mbx.o rcv_mbx.o \
+		prcv_mbx.o trcv_mbx.o ini_mbx.o ref_mbx.o
+
+mutex = mtxhook.o mtxini.o mtxchk.o mtxscan.o mtxcalc.o mtxrel.o mtxrela.o \
+		acre_mtx.o del_mtx.o loc_mtx.o ploc_mtx.o tloc_mtx.o unl_mtx.o ini_mtx.o ref_mtx.o
+
+mempfix = mpfini.o mpfget.o acre_mpf.o del_mpf.o get_mpf.o \
+		pget_mpf.o tget_mpf.o rel_mpf.o ini_mpf.o ref_mpf.o
+
+time_manage = get_tim.o get_utm.o
+
+cyclic = cycini.o acre_cyc.o del_cyc.o sta_cyc.o stp_cyc.o ref_cyc.o cyccal.o
+
+alarm = almini.o acre_alm.o del_alm.o sta_alm.o ista_alm.o stp_alm.o \
+		istp_alm.o ref_alm.o almcal.o
+
+sys_manage = rot_rdq.o irot_rdq.o get_tid.o iget_tid.o \
+		loc_cpu.o iloc_cpu.o unl_cpu.o iunl_cpu.o dis_dsp.o ena_dsp.o \
+		sns_ctx.o sns_loc.o sns_dsp.o sns_dpn.o sns_ker.o
+
+interrupt = isrini.o isrcal.o acre_isr.o del_isr.o \
+		intini.o dis_int.o ena_int.o chg_ipm.o get_ipm.o
+
+exception = excini.o xsns_dpn.o xsns_xpn.o
+
+#
+#  生成されるオブジェクトファイルの依存関係の定義
+#
+$(startup) $(startup:.o=.s) $(startup:.o=.d): startup.c
+$(task) $(task:.o=.s) $(task:.o=.d): task.c
+$(wait) $(wait:.o=.s) $(wait:.o=.d): wait.c
+$(time_event) $(time_event:.o=.s) $(time_event:.o=.d): time_event.c
+$(task_manage) $(task_manage:.o=.s) $(task_manage:.o=.d): task_manage.c
+$(task_refer) $(task_refer:.o=.s) $(task_refer:.o=.d): task_refer.c
+$(task_sync) $(task_sync:.o=.s) $(task_sync:.o=.d): task_sync.c
+$(task_except) $(task_except:.o=.s) $(task_except:.o=.d): task_except.c
+$(semaphore) $(semaphore:.o=.s) $(semaphore:.o=.d): semaphore.c
+$(eventflag) $(eventflag:.o=.s) $(eventflag:.o=.d): eventflag.c
+$(dataqueue) $(dataqueue:.o=.s) $(dataqueue:.o=.d): dataqueue.c
+$(pridataq) $(pridataq:.o=.s) $(pridataq:.o=.d): pridataq.c
+$(mailbox) $(mailbox:.o=.s) $(mailbox:.o=.d): mailbox.c
+$(mutex) $(mutex:.o=.s) $(mutex:.o=.d): mutex.c
+$(mempfix) $(mempfix:.o=.s) $(mempfix:.o=.d): mempfix.c
+$(time_manage) $(time_manage:.o=.s) $(time_manage:.o=.d): time_manage.c
+$(cyclic) $(cyclic:.o=.s) $(cyclic:.o=.d): cyclic.c
+$(alarm) $(alarm:.o=.s) $(alarm:.o=.d): alarm.c
+$(sys_manage) $(sys_manage:.o=.s) $(sys_manage:.o=.d): sys_manage.c
+$(interrupt) $(interrupt:.o=.s) $(interrupt:.o=.d): interrupt.c
+$(exception) $(exception:.o=.s) $(exception:.o=.d): exception.c
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/kernel/alarm.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/kernel/alarm.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/kernel/alarm.c	(revision 457)
@@ -0,0 +1,477 @@
+/*
+ *  TOPPERS/ASP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Advanced Standard Profile Kernel
+ * 
+ *  Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
+ *                              Toyohashi Univ. of Technology, JAPAN
+ *  Copyright (C) 2005-2014 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *		アラームハンドラ機能
+ */
+
+#include "kernel_impl.h"
+#include "check.h"
+#include "alarm.h"
+
+/*
+ *  トレースログマクロのデフォルト定義
+ */
+#ifndef LOG_ALM_ENTER
+#define LOG_ALM_ENTER(p_almcb)
+#endif /* LOG_ALM_ENTER */
+
+#ifndef LOG_ALM_LEAVE
+#define LOG_ALM_LEAVE(p_almcb)
+#endif /* LOG_ALM_LEAVE */
+
+#ifndef LOG_ACRE_ALM_ENTER
+#define LOG_ACRE_ALM_ENTER(pk_calm)
+#endif /* LOG_ACRE_ALM_ENTER */
+
+#ifndef LOG_ACRE_ALM_LEAVE
+#define LOG_ACRE_ALM_LEAVE(ercd)
+#endif /* LOG_ACRE_ALM_LEAVE */
+
+#ifndef LOG_DEL_ALM_ENTER
+#define LOG_DEL_ALM_ENTER(almid)
+#endif /* LOG_DEL_ALM_ENTER */
+
+#ifndef LOG_DEL_ALM_LEAVE
+#define LOG_DEL_ALM_LEAVE(ercd)
+#endif /* LOG_DEL_ALM_LEAVE */
+
+#ifndef LOG_STA_ALM_ENTER
+#define LOG_STA_ALM_ENTER(almid, almtim)
+#endif /* LOG_STA_ALM_ENTER */
+
+#ifndef LOG_STA_ALM_LEAVE
+#define LOG_STA_ALM_LEAVE(ercd)
+#endif /* LOG_STA_ALM_LEAVE */
+
+#ifndef LOG_ISTA_ALM_ENTER
+#define LOG_ISTA_ALM_ENTER(almid, almtim)
+#endif /* LOG_ISTA_ALM_ENTER */
+
+#ifndef LOG_ISTA_ALM_LEAVE
+#define LOG_ISTA_ALM_LEAVE(ercd)
+#endif /* LOG_ISTA_ALM_LEAVE */
+
+#ifndef LOG_STP_ALM_ENTER
+#define LOG_STP_ALM_ENTER(almid)
+#endif /* LOG_STP_ALM_ENTER */
+
+#ifndef LOG_STP_ALM_LEAVE
+#define LOG_STP_ALM_LEAVE(ercd)
+#endif /* LOG_STP_ALM_LEAVE */
+
+#ifndef LOG_ISTP_ALM_ENTER
+#define LOG_ISTP_ALM_ENTER(almid)
+#endif /* LOG_ISTP_ALM_ENTER */
+
+#ifndef LOG_ISTP_ALM_LEAVE
+#define LOG_ISTP_ALM_LEAVE(ercd)
+#endif /* LOG_ISTP_ALM_LEAVE */
+
+#ifndef LOG_REF_ALM_ENTER
+#define LOG_REF_ALM_ENTER(almid, pk_ralm)
+#endif /* LOG_REF_ALM_ENTER */
+
+#ifndef LOG_REF_ALM_LEAVE
+#define LOG_REF_ALM_LEAVE(ercd, pk_ralm)
+#endif /* LOG_REF_ALM_LEAVE */
+
+/*
+ *  アラームハンドラの数
+ */
+#define tnum_alm	((uint_t)(tmax_almid - TMIN_ALMID + 1))
+#define tnum_salm	((uint_t)(tmax_salmid - TMIN_ALMID + 1))
+
+/*
+ *  アラームハンドラIDからアラームハンドラ管理ブロックを取り出すためのマクロ
+ */
+#define INDEX_ALM(almid)	((uint_t)((almid) - TMIN_ALMID))
+#define get_almcb(almid)	(&(almcb_table[INDEX_ALM(almid)]))
+
+#ifdef TOPPERS_almini
+
+/*
+ *  使用していないアラームハンドラ管理ブロックのリスト
+ *
+ *  アラームハンドラ管理ブロックの先頭にはキューにつなぐための領域がな
+ *  いため，タイムイベントブロック（tmevtb）の領域を用いる．
+ */
+QUEUE	free_almcb;
+
+/*
+ *  アラームハンドラ機能の初期化
+ */
+void
+initialize_alarm(void)
+{
+	uint_t	i, j;
+	ALMCB	*p_almcb;
+	ALMINIB	*p_alminib;
+
+	for (i = 0; i < tnum_salm; i++) {
+		p_almcb = &(almcb_table[i]);
+		p_almcb->p_alminib = &(alminib_table[i]);
+		p_almcb->almsta = false;
+	}
+	queue_initialize(&free_almcb);
+	for (j = 0; i < tnum_alm; i++, j++) {
+		p_almcb = &(almcb_table[i]);
+		p_alminib = &(aalminib_table[j]);
+		p_alminib->almatr = TA_NOEXS;
+		p_almcb->p_alminib = ((const ALMINIB *) p_alminib);
+		queue_insert_prev(&free_almcb, ((QUEUE *) &(p_almcb->tmevtb)));
+	}
+}
+
+#endif /* TOPPERS_almini */
+
+/*
+ *  アラームハンドラの生成
+ */
+#ifdef TOPPERS_acre_alm
+
+ER_UINT
+acre_alm(const T_CALM *pk_calm)
+{
+	ALMCB	*p_almcb;
+	ALMINIB	*p_alminib;
+	ER		ercd;
+
+	LOG_ACRE_ALM_ENTER(pk_calm);
+	CHECK_TSKCTX_UNL();
+	CHECK_RSATR(pk_calm->almatr, TA_NULL);
+	CHECK_ALIGN_FUNC(pk_calm->almhdr);
+	CHECK_NONNULL_FUNC(pk_calm->almhdr);
+
+	t_lock_cpu();
+	if (tnum_alm == 0 || queue_empty(&free_almcb)) {
+		ercd = E_NOID;
+	}
+	else {
+		p_almcb = ((ALMCB *)(((char *) queue_delete_next(&free_almcb))
+												- offsetof(ALMCB, tmevtb)));
+		p_alminib = (ALMINIB *)(p_almcb->p_alminib);
+		p_alminib->almatr = pk_calm->almatr;
+		p_alminib->exinf = pk_calm->exinf;
+		p_alminib->almhdr = pk_calm->almhdr;
+
+		p_almcb->almsta = false;
+		ercd = ALMID(p_almcb);
+	}
+	t_unlock_cpu();
+
+  error_exit:
+	LOG_ACRE_ALM_LEAVE(ercd);
+	return(ercd);
+}
+
+#endif /* TOPPERS_acre_alm */
+
+/*
+ *  アラームハンドラの削除
+ */
+#ifdef TOPPERS_del_alm
+
+ER
+del_alm(ID almid)
+{
+	ALMCB	*p_almcb;
+	ALMINIB	*p_alminib;
+	ER		ercd;
+
+	LOG_DEL_ALM_ENTER(almid);
+	CHECK_TSKCTX_UNL();
+	CHECK_ALMID(almid);
+	p_almcb = get_almcb(almid);
+
+	t_lock_cpu();
+	if (p_almcb->p_alminib->almatr == TA_NOEXS) {
+		ercd = E_NOEXS;
+	}
+	else if (ALMID(p_almcb) > tmax_salmid) {
+		if (p_almcb->almsta) {
+			p_almcb->almsta = false;
+			tmevtb_dequeue(&(p_almcb->tmevtb));
+		}
+
+		p_alminib = (ALMINIB *)(p_almcb->p_alminib);
+		p_alminib->almatr = TA_NOEXS;
+		queue_insert_prev(&free_almcb, ((QUEUE *) &(p_almcb->tmevtb)));
+		ercd = E_OK;
+	}
+	else {
+		ercd = E_OBJ;
+	}
+	t_unlock_cpu();
+
+  error_exit:
+	LOG_DEL_ALM_LEAVE(ercd);
+	return(ercd);
+}
+
+#endif /* TOPPERS_del_alm */
+
+/*
+ *  アラームハンドラの動作開始
+ */
+#ifdef TOPPERS_sta_alm
+
+ER
+sta_alm(ID almid, RELTIM almtim)
+{
+	ALMCB	*p_almcb;
+	ER		ercd;
+
+	LOG_STA_ALM_ENTER(almid, almtim);
+	CHECK_TSKCTX_UNL();
+	CHECK_ALMID(almid);
+	CHECK_PAR(almtim <= TMAX_RELTIM);
+	p_almcb = get_almcb(almid);
+
+	t_lock_cpu();
+	if (p_almcb->p_alminib->almatr == TA_NOEXS) {
+		ercd = E_NOEXS;
+	}
+	else {
+		if (p_almcb->almsta) {
+			tmevtb_dequeue(&(p_almcb->tmevtb));
+		}
+		else {
+			p_almcb->almsta = true;
+		}
+		tmevtb_enqueue(&(p_almcb->tmevtb), almtim,
+									(CBACK) call_almhdr, (void *) p_almcb);
+		ercd = E_OK;
+	}
+	t_unlock_cpu();
+
+  error_exit:
+	LOG_STA_ALM_LEAVE(ercd);
+	return(ercd);
+}
+
+#endif /* TOPPERS_sta_alm */
+
+/*
+ *  アラームハンドラの動作開始（非タスクコンテキスト用）
+ */
+#ifdef TOPPERS_ista_alm
+
+ER
+ista_alm(ID almid, RELTIM almtim)
+{
+	ALMCB	*p_almcb;
+	ER		ercd;
+
+	LOG_ISTA_ALM_ENTER(almid, almtim);
+	CHECK_INTCTX_UNL();
+	CHECK_ALMID(almid);
+	CHECK_PAR(almtim <= TMAX_RELTIM);
+	p_almcb = get_almcb(almid);
+
+	i_lock_cpu();
+	if (p_almcb->p_alminib->almatr == TA_NOEXS) {
+		ercd = E_NOEXS;
+	}
+	else {
+		if (p_almcb->almsta) {
+			tmevtb_dequeue(&(p_almcb->tmevtb));
+		}
+		else {
+			p_almcb->almsta = true;
+		}
+		tmevtb_enqueue(&(p_almcb->tmevtb), almtim,
+									(CBACK) call_almhdr, (void *) p_almcb);
+		ercd = E_OK;
+	}
+	i_unlock_cpu();
+
+  error_exit:
+	LOG_ISTA_ALM_LEAVE(ercd);
+	return(ercd);
+}
+
+#endif /* TOPPERS_ista_alm */
+
+/*
+ *  アラームハンドラの動作停止
+ */
+#ifdef TOPPERS_stp_alm
+
+ER
+stp_alm(ID almid)
+{
+	ALMCB	*p_almcb;
+	ER		ercd;
+
+	LOG_STP_ALM_ENTER(almid);
+	CHECK_TSKCTX_UNL();
+	CHECK_ALMID(almid);
+	p_almcb = get_almcb(almid);
+
+	t_lock_cpu();
+	if (p_almcb->p_alminib->almatr == TA_NOEXS) {
+		ercd = E_NOEXS;
+	}
+	else {
+		if (p_almcb->almsta) {
+			p_almcb->almsta = false;
+			tmevtb_dequeue(&(p_almcb->tmevtb));
+		}
+		ercd = E_OK;
+	}
+	t_unlock_cpu();
+
+  error_exit:
+	LOG_STP_ALM_LEAVE(ercd);
+	return(ercd);
+}
+
+#endif /* TOPPERS_stp_alm */
+
+/*
+ *  アラームハンドラの動作停止（非タスクコンテキスト用）
+ */
+#ifdef TOPPERS_istp_alm
+
+ER
+istp_alm(ID almid)
+{
+	ALMCB	*p_almcb;
+	ER		ercd;
+
+	LOG_ISTP_ALM_ENTER(almid);
+	CHECK_INTCTX_UNL();
+	CHECK_ALMID(almid);
+	p_almcb = get_almcb(almid);
+
+	i_lock_cpu();
+	if (p_almcb->p_alminib->almatr == TA_NOEXS) {
+		ercd = E_NOEXS;
+	}
+	else {
+		if (p_almcb->almsta) {
+			p_almcb->almsta = false;
+			tmevtb_dequeue(&(p_almcb->tmevtb));
+		}
+		ercd = E_OK;
+	}
+	i_unlock_cpu();
+
+  error_exit:
+	LOG_ISTP_ALM_LEAVE(ercd);
+	return(ercd);
+}
+
+#endif /* TOPPERS_istp_alm */
+
+/*
+ *  アラームハンドラの状態参照
+ */
+#ifdef TOPPERS_ref_alm
+
+ER
+ref_alm(ID almid, T_RALM *pk_ralm)
+{
+	ALMCB	*p_almcb;
+	ER		ercd;
+    
+	LOG_REF_ALM_ENTER(almid, pk_ralm);
+	CHECK_TSKCTX_UNL();
+	CHECK_ALMID(almid);
+	p_almcb = get_almcb(almid);
+
+	t_lock_cpu();
+	if (p_almcb->p_alminib->almatr == TA_NOEXS) {
+		ercd = E_NOEXS;
+	}
+	else {
+		if (p_almcb->almsta) {
+			pk_ralm->almstat = TALM_STA;
+			pk_ralm->lefttim = tmevt_lefttim(&(p_almcb->tmevtb));
+		}
+		else {
+			pk_ralm->almstat = TALM_STP;
+		}
+		ercd = E_OK;
+	}
+	t_unlock_cpu();
+
+  error_exit:
+	LOG_REF_ALM_LEAVE(ercd, pk_ralm);
+	return(ercd);
+}
+
+#endif /* TOPPERS_ref_alm */
+
+/*
+ *  アラームハンドラ起動ルーチン
+ */
+#ifdef TOPPERS_almcal
+
+void
+call_almhdr(ALMCB *p_almcb)
+{
+	PRI		saved_ipm;
+
+	/*
+	 *  アラームハンドラを停止状態にする．
+	 */
+	p_almcb->almsta = false;
+
+	/*
+	 *  アラームハンドラを，CPUロック解除状態で呼び出す．
+	 */
+	saved_ipm = i_get_ipm();
+	i_unlock_cpu();
+
+	LOG_ALM_ENTER(p_almcb);
+	(*((ALMHDR)(p_almcb->p_alminib->almhdr)))(p_almcb->p_alminib->exinf);
+	LOG_ALM_LEAVE(p_almcb);
+
+	if (!i_sense_lock()) {
+		i_lock_cpu();
+	}
+	i_set_ipm(saved_ipm);
+}
+
+#endif /* TOPPERS_almcal */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/kernel/alarm.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/kernel/alarm.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/kernel/alarm.h	(revision 457)
@@ -0,0 +1,109 @@
+/*
+ *  TOPPERS/ASP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Advanced Standard Profile Kernel
+ * 
+ *  Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
+ *                              Toyohashi Univ. of Technology, JAPAN
+ *  Copyright (C) 2005-2010 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *		アラームハンドラ機能
+ */
+
+#ifndef TOPPERS_ALARM_H
+#define TOPPERS_ALARM_H
+
+#include <queue.h>
+#include "time_event.h"
+
+/*
+ *  アラームハンドラ初期化ブロック
+ */
+typedef struct alarm_handler_initialization_block {
+	ATR			almatr;			/* アラームハンドラ属性 */
+	intptr_t	exinf;			/* アラームハンドラの拡張情報 */
+	ALMHDR		almhdr;			/* アラームハンドラの起動番地 */
+} ALMINIB;
+
+/*
+ *  アラームハンドラ管理ブロック
+ */
+typedef struct alarm_handler_control_block {
+	const ALMINIB *p_alminib;	/* 初期化ブロックへのポインタ */
+	bool_t		almsta;			/* アラームハンドラの動作状態 */
+	TMEVTB		tmevtb;			/* タイムイベントブロック */
+} ALMCB;
+
+/*
+ *  使用していないアラームハンドラ管理ブロックのリスト
+ */
+extern QUEUE	free_almcb;
+
+/*
+ *  アラームハンドラIDの最大値（kernel_cfg.c）
+ */
+extern const ID	tmax_almid;
+extern const ID	tmax_salmid;
+
+/*
+ *  アラームハンドラ初期化ブロックのエリア（kernel_cfg.c）
+ */
+extern const ALMINIB	alminib_table[];
+extern ALMINIB			aalminib_table[];
+
+/*
+ *  アラームハンドラ管理ブロックのエリア（kernel_cfg.c）
+ */
+extern ALMCB	almcb_table[];
+
+/*
+ *  アラームハンドラ管理ブロックからアラームハンドラIDを取り出すための
+ *  マクロ
+ */
+#define	ALMID(p_almcb)	((ID)(((p_almcb) - almcb_table) + TMIN_ALMID))
+
+/*
+ *  アラームハンドラ機能の初期化
+ */
+extern void	initialize_alarm(void);
+
+/*
+ *  アラームハンドラ起動ルーチン
+ */
+extern void	call_almhdr(ALMCB *p_almcb);
+
+#endif /* TOPPERS_ALARM_H */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/kernel/allfunc.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/kernel/allfunc.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/kernel/allfunc.h	(revision 457)
@@ -0,0 +1,282 @@
+/*
+ *  TOPPERS/ASP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Advanced Standard Profile Kernel
+ * 
+ *  Copyright (C) 2005-2010 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *		すべての関数をコンパイルするための定義
+ */
+
+#ifndef TOPPERS_ALLFUNC_H
+#define TOPPERS_ALLFUNC_H
+
+/* startup.c */
+#define TOPPERS_sta_ker
+#define TOPPERS_ext_ker
+#define TOPPERS_kermem
+
+/* task.c */
+#define TOPPERS_tskini
+#define TOPPERS_tsksched
+#define TOPPERS_tskrun
+#define TOPPERS_tsknrun
+#define TOPPERS_tskdmt
+#define TOPPERS_tskact
+#define TOPPERS_tskpri
+#define TOPPERS_tskrot
+#define TOPPERS_tsktex
+
+/* wait.c */
+#define TOPPERS_waimake
+#define TOPPERS_waicmp
+#define TOPPERS_waitmo
+#define TOPPERS_waitmook
+#define TOPPERS_wairel
+#define TOPPERS_wobjwai
+#define TOPPERS_wobjwaitmo
+#define TOPPERS_iniwque
+
+/* time_event.c */
+#define TOPPERS_tmeini
+#define TOPPERS_tmeup
+#define TOPPERS_tmedown
+#define TOPPERS_tmeins
+#define TOPPERS_tmedel
+#define TOPPERS_tmeltim
+#define TOPPERS_sigtim
+
+/* task_manage.c */
+#define TOPPERS_acre_tsk
+#define TOPPERS_del_tsk
+#define TOPPERS_act_tsk
+#define TOPPERS_iact_tsk
+#define TOPPERS_can_act
+#define TOPPERS_ext_tsk
+#define TOPPERS_ter_tsk
+#define TOPPERS_chg_pri
+#define TOPPERS_get_pri
+#define TOPPERS_get_inf
+
+/* task_refer.c */
+#define TOPPERS_ref_tsk
+
+/* task_sync.c */
+#define TOPPERS_slp_tsk
+#define TOPPERS_tslp_tsk
+#define TOPPERS_wup_tsk
+#define TOPPERS_iwup_tsk
+#define TOPPERS_can_wup
+#define TOPPERS_rel_wai
+#define TOPPERS_irel_wai
+#define TOPPERS_sus_tsk
+#define TOPPERS_rsm_tsk
+#define TOPPERS_dly_tsk
+
+/* task_except.c */
+#define TOPPERS_def_tex
+#define TOPPERS_ras_tex
+#define TOPPERS_iras_tex
+#define TOPPERS_dis_tex
+#define TOPPERS_ena_tex
+#define TOPPERS_sns_tex
+#define TOPPERS_ref_tex
+
+/* semaphore.c */
+#define TOPPERS_semini
+#define TOPPERS_acre_sem
+#define TOPPERS_del_sem
+#define TOPPERS_sig_sem
+#define TOPPERS_isig_sem
+#define TOPPERS_wai_sem
+#define TOPPERS_pol_sem
+#define TOPPERS_twai_sem
+#define TOPPERS_ini_sem
+#define TOPPERS_ref_sem
+
+/* eventflag.c */
+#define TOPPERS_flgini
+#define TOPPERS_flgcnd
+#define TOPPERS_acre_flg
+#define TOPPERS_del_flg
+#define TOPPERS_set_flg
+#define TOPPERS_iset_flg
+#define TOPPERS_clr_flg
+#define TOPPERS_wai_flg
+#define TOPPERS_pol_flg
+#define TOPPERS_twai_flg
+#define TOPPERS_ini_flg
+#define TOPPERS_ref_flg
+
+/* dataqueue.c */
+#define TOPPERS_dtqini
+#define TOPPERS_dtqenq
+#define TOPPERS_dtqfenq
+#define TOPPERS_dtqdeq
+#define TOPPERS_dtqsnd
+#define TOPPERS_dtqfsnd
+#define TOPPERS_dtqrcv
+#define TOPPERS_acre_dtq
+#define TOPPERS_del_dtq
+#define TOPPERS_snd_dtq
+#define TOPPERS_psnd_dtq
+#define TOPPERS_ipsnd_dtq
+#define TOPPERS_tsnd_dtq
+#define TOPPERS_fsnd_dtq
+#define TOPPERS_ifsnd_dtq
+#define TOPPERS_rcv_dtq
+#define TOPPERS_prcv_dtq
+#define TOPPERS_trcv_dtq
+#define TOPPERS_ini_dtq
+#define TOPPERS_ref_dtq
+
+/* pridataq.c */
+#define TOPPERS_pdqini
+#define TOPPERS_pdqenq
+#define TOPPERS_pdqdeq
+#define TOPPERS_pdqsnd
+#define TOPPERS_pdqrcv
+#define TOPPERS_acre_pdq
+#define TOPPERS_del_pdq
+#define TOPPERS_snd_pdq
+#define TOPPERS_psnd_pdq
+#define TOPPERS_ipsnd_pdq
+#define TOPPERS_tsnd_pdq
+#define TOPPERS_rcv_pdq
+#define TOPPERS_prcv_pdq
+#define TOPPERS_trcv_pdq
+#define TOPPERS_ini_pdq
+#define TOPPERS_ref_pdq
+
+/* mailbox.c */
+#define TOPPERS_mbxini
+#define TOPPERS_acre_mbx
+#define TOPPERS_del_mbx
+#define TOPPERS_snd_mbx
+#define TOPPERS_rcv_mbx
+#define TOPPERS_prcv_mbx
+#define TOPPERS_trcv_mbx
+#define TOPPERS_ini_mbx
+#define TOPPERS_ref_mbx
+
+/* mutex.c */
+#define TOPPERS_mtxhook
+#define TOPPERS_mtxini
+#define TOPPERS_mtxchk
+#define TOPPERS_mtxscan
+#define TOPPERS_mtxcalc
+#define TOPPERS_mtxrel
+#define TOPPERS_mtxrela
+#define TOPPERS_acre_mtx
+#define TOPPERS_del_mtx
+#define TOPPERS_loc_mtx
+#define TOPPERS_ploc_mtx
+#define TOPPERS_tloc_mtx
+#define TOPPERS_unl_mtx
+#define TOPPERS_ini_mtx
+#define TOPPERS_ref_mtx
+
+/* mempfix.c */
+#define TOPPERS_mpfini
+#define TOPPERS_mpfget
+#define TOPPERS_acre_mpf
+#define TOPPERS_del_mpf
+#define TOPPERS_get_mpf
+#define TOPPERS_pget_mpf
+#define TOPPERS_tget_mpf
+#define TOPPERS_rel_mpf
+#define TOPPERS_ini_mpf
+#define TOPPERS_ref_mpf
+
+/* time_manage.c */
+#define TOPPERS_get_tim
+#define TOPPERS_get_utm
+
+/* cyclic.c */
+#define TOPPERS_cycini
+#define TOPPERS_acre_cyc
+#define TOPPERS_del_cyc
+#define TOPPERS_sta_cyc
+#define TOPPERS_stp_cyc
+#define TOPPERS_ref_cyc
+#define TOPPERS_cyccal
+
+/* alarm.c */
+#define TOPPERS_almini
+#define TOPPERS_acre_alm
+#define TOPPERS_del_alm
+#define TOPPERS_sta_alm
+#define TOPPERS_ista_alm
+#define TOPPERS_stp_alm
+#define TOPPERS_istp_alm
+#define TOPPERS_ref_alm
+#define TOPPERS_almcal
+
+/* sys_manage.c */
+#define TOPPERS_rot_rdq
+#define TOPPERS_irot_rdq
+#define TOPPERS_get_tid
+#define TOPPERS_iget_tid
+#define TOPPERS_loc_cpu
+#define TOPPERS_iloc_cpu
+#define TOPPERS_unl_cpu
+#define TOPPERS_iunl_cpu
+#define TOPPERS_dis_dsp
+#define TOPPERS_ena_dsp
+#define TOPPERS_sns_ctx
+#define TOPPERS_sns_loc
+#define TOPPERS_sns_dsp
+#define TOPPERS_sns_dpn
+#define TOPPERS_sns_ker
+
+/* interrupt.c */
+#define TOPPERS_isrini
+#define TOPPERS_isrcal
+#define TOPPERS_acre_isr
+#define TOPPERS_del_isr
+#define TOPPERS_intini
+#define TOPPERS_dis_int
+#define TOPPERS_ena_int
+#define TOPPERS_chg_ipm
+#define TOPPERS_get_ipm
+
+/* exception.c */
+#define TOPPERS_excini
+#define TOPPERS_xsns_dpn
+#define TOPPERS_xsns_xpn
+
+#endif /* TOPPERS_ALLFUNC_H */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/kernel/check.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/kernel/check.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/kernel/check.h	(revision 457)
@@ -0,0 +1,475 @@
+/*
+ *  TOPPERS/ASP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Advanced Standard Profile Kernel
+ * 
+ *  Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
+ *                              Toyohashi Univ. of Technology, JAPAN
+ *  Copyright (C) 2005-2014 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *		エラーチェック用マクロ
+ */
+
+#ifndef TOPPERS_CHECK_H
+#define TOPPERS_CHECK_H
+
+/*
+ *  予約属性エラーのチェック（E_PAR）
+ */
+#define CHECK_RSATR(atr, valid_atr) do {					\
+	if (((atr) & ~(valid_atr)) != 0U) {						\
+		ercd = E_RSATR;										\
+		goto error_exit;									\
+	}														\
+} while (false)
+
+/*
+ *  優先度の範囲の判定
+ */
+#define VALID_TPRI(tpri)	(TMIN_TPRI <= (tpri) && (tpri) <= TMAX_TPRI)
+
+#define VALID_DPRI(dpri)	(TMIN_DPRI <= (dpri) && (dpri) <= TMAX_DPRI)
+
+#define VALID_MPRI(mpri)	(TMIN_MPRI <= (mpri) && (mpri) <= TMAX_MPRI)
+
+#define VALID_ISRPRI(isrpri) \
+				(TMIN_ISRPRI <= (isrpri) && (isrpri) <= TMAX_ISRPRI)
+
+#ifndef VALID_INTPRI_CHGIPM
+#define VALID_INTPRI_CHGIPM(intpri) \
+				(TMIN_INTPRI <= (intpri) && (intpri) <= TIPM_ENAALL)
+#endif /* VALID_INTPRI_CHGIPM */
+
+/*
+ *  タスク優先度のチェック（E_PAR）
+ */
+#define CHECK_TPRI(tpri) do {								\
+	if (!VALID_TPRI(tpri)) {								\
+		ercd = E_PAR;										\
+		goto error_exit;									\
+	}														\
+} while (false)
+
+#define CHECK_TPRI_INI(tpri) do {							\
+	if (!(VALID_TPRI(tpri) || (tpri) == TPRI_INI)) {		\
+		ercd = E_PAR;										\
+		goto error_exit;									\
+	}														\
+} while (false)
+
+#define CHECK_TPRI_SELF(tpri) do {							\
+	if (!(VALID_TPRI(tpri) || (tpri) == TPRI_SELF)) {		\
+		ercd = E_PAR;										\
+		goto error_exit;									\
+	}														\
+} while (false)
+
+/*
+ *  データ優先度のチェック（E_PAR）
+ */
+#define CHECK_DPRI(dpri) do {								\
+	if (!VALID_DPRI(dpri)) {								\
+		ercd = E_PAR;										\
+		goto error_exit;									\
+	}														\
+} while (false)
+
+/*
+ *  メッセージ優先度のチェック（E_PAR）
+ */
+#define CHECK_MPRI(mpri) do {								\
+	if (!VALID_MPRI(mpri)) {								\
+		ercd = E_PAR;										\
+		goto error_exit;									\
+	}														\
+} while (false)
+
+/*
+ *  割込みサービスルーチン優先度のチェック（E_PAR）
+ */
+#define CHECK_ISRPRI(isrpri) do {							\
+	if (!VALID_ISRPRI(isrpri)) {							\
+		ercd = E_PAR;										\
+		goto error_exit;									\
+	}														\
+} while (false)
+
+/*
+ *  タイムアウト指定値のチェック（E_PAR）
+ */
+#define CHECK_TMOUT(tmout) do {								\
+	if (!(TMO_FEVR <= (tmout))) {							\
+		ercd = E_PAR;										\
+		goto error_exit;									\
+	}														\
+} while (false)
+
+/*
+ *  割込み優先度のチェック（E_PAR）
+ */
+#define CHECK_INTPRI_CHGIPM(intpri) do {					\
+	if (!VALID_INTPRI_CHGIPM(intpri)) {						\
+		ercd = E_PAR;										\
+		goto error_exit;									\
+	}														\
+} while (false)
+
+/*
+ *  割込み番号のチェック（E_PAR）
+ */
+#define CHECK_INTNO_CREISR(intno) do {						\
+	if (!VALID_INTNO_CREISR(intno)) {						\
+		ercd = E_PAR;										\
+		goto error_exit;									\
+	}														\
+} while (false)
+
+#define CHECK_INTNO_DISINT(intno) do {						\
+	if (!VALID_INTNO_DISINT(intno)) {						\
+		ercd = E_PAR;										\
+		goto error_exit;									\
+	}														\
+} while (false)
+
+/*
+ *  アラインしているかの判定
+ */
+#define ALIGNED(val, align)		((((uintptr_t)(val)) & ((align) - 1U)) == 0U)
+
+#ifdef CHECK_FUNC_ALIGN
+#define FUNC_ALIGNED(func)		ALIGNED(func, CHECK_FUNC_ALIGN)
+#else /* CHECK_FUNC_ALIGN */
+#define FUNC_ALIGNED(func)		true
+#endif /* CHECK_FUNC_ALIGN */
+
+#ifdef CHECK_STKSZ_ALIGN
+#define STKSZ_ALIGNED(stksz)	ALIGNED(stksz, CHECK_STKSZ_ALIGN)
+#else /* CHECK_STKSZ_ALIGN */
+#define STKSZ_ALIGNED(stksz)	true
+#endif /* CHECK_STKSZ_ALIGN */
+
+#ifdef CHECK_STACK_ALIGN
+#define STACK_ALIGNED(stack)	ALIGNED(stack, CHECK_STACK_ALIGN)
+#else /* CHECK_STACK_ALIGN */
+#define STACK_ALIGNED(stack)	true
+#endif /* CHECK_STACK_ALIGN */
+
+#ifdef CHECK_MPF_ALIGN
+#define MPF_ALIGNED(mpf)		ALIGNED(mpf, CHECK_MPF_ALIGN)
+#else /* CHECK_MPF_ALIGN */
+#define MPF_ALIGNED(mpf)		true
+#endif /* CHECK_MPF_ALIGN */
+
+#ifdef CHECK_MB_ALIGN
+#define MB_ALIGNED(mb)			ALIGNED(mb, CHECK_MB_ALIGN)
+#else /* CHECK_MB_ALIGN */
+#define MB_ALIGNED(mb)			true
+#endif /* CHECK_MB_ALIGN */
+
+/*
+ *  NULLでないことのチェック
+ */
+#ifdef CHECK_FUNC_NONNULL
+#define FUNC_NONNULL(func)		((func) != NULL)
+#else /* CHECK_FUNC_NONNULL */
+#define FUNC_NONNULL(func)		true
+#endif /* CHECK_FUNC_NONNULL */
+
+/*
+ *  関数の先頭番地のチェック（E_PAR）
+ */
+#define CHECK_ALIGN_FUNC(func) do {							\
+	if (!FUNC_ALIGNED(func)) {								\
+		ercd = E_PAR;										\
+		goto error_exit;									\
+	}														\
+} while (false)
+
+#define CHECK_NONNULL_FUNC(func) do {						\
+	if (!FUNC_NONNULL(func)) {								\
+		ercd = E_PAR;										\
+		goto error_exit;									\
+	}														\
+} while (false)
+
+/*
+ *  スタックサイズのチェック（E_PAR）
+ */
+#define CHECK_ALIGN_STKSZ(stksz) do {						\
+	if (!STKSZ_ALIGNED(stksz)) {							\
+		ercd = E_PAR;										\
+		goto error_exit;									\
+	}														\
+} while (false)
+
+/*
+ *  スタックの先頭番地のチェック（E_PAR）
+ */
+#define CHECK_ALIGN_STACK(stack) do {						\
+	if (!STACK_ALIGNED(stack)) {							\
+		ercd = E_PAR;										\
+		goto error_exit;									\
+	}														\
+} while (false)
+
+/*
+ *  固定長メモリプール領域の先頭番地のチェック（E_PAR）
+ */
+#define CHECK_ALIGN_MPF(mpf) do {							\
+	if (!MPF_ALIGNED(mpf)) {								\
+		ercd = E_PAR;										\
+		goto error_exit;									\
+	}														\
+} while (false)
+
+/*
+ *  管理領域の先頭番地のチェック（E_PAR）
+ */
+#define CHECK_ALIGN_MB(mb) do {								\
+	if (!MB_ALIGNED(mb)) {									\
+		ercd = E_PAR;										\
+		goto error_exit;									\
+	}														\
+} while (false)
+
+/*
+ *  その他のパラメータエラーのチェック（E_PAR）
+ */
+#define CHECK_PAR(exp) do {									\
+	if (!(exp)) {											\
+		ercd = E_PAR;										\
+		goto error_exit;									\
+	}														\
+} while (false)
+
+/*
+ *  オブジェクトIDの範囲の判定
+ */
+#define VALID_TSKID(tskid)	(TMIN_TSKID <= (tskid) && (tskid) <= tmax_tskid)
+#define VALID_SEMID(semid)	(TMIN_SEMID <= (semid) && (semid) <= tmax_semid)
+#define VALID_FLGID(flgid)	(TMIN_FLGID <= (flgid) && (flgid) <= tmax_flgid)
+#define VALID_DTQID(dtqid)	(TMIN_DTQID <= (dtqid) && (dtqid) <= tmax_dtqid)
+#define VALID_PDQID(pdqid)	(TMIN_PDQID <= (pdqid) && (pdqid) <= tmax_pdqid)
+#define VALID_MBXID(mbxid)	(TMIN_MBXID <= (mbxid) && (mbxid) <= tmax_mbxid)
+#define VALID_MTXID(mtxid)	(TMIN_MTXID <= (mtxid) && (mtxid) <= tmax_mtxid)
+#define VALID_MPFID(mpfid)	(TMIN_MPFID <= (mpfid) && (mpfid) <= tmax_mpfid)
+#define VALID_CYCID(cycid)	(TMIN_CYCID <= (cycid) && (cycid) <= tmax_cycid)
+#define VALID_ALMID(almid)	(TMIN_ALMID <= (almid) && (almid) <= tmax_almid)
+#define VALID_ISRID(isrid)	(TMIN_ISRID <= (isrid) && (isrid) <= tmax_isrid)
+
+/*
+ *  オブジェクトIDのチェック（E_ID）
+ */
+#define CHECK_TSKID(tskid) do {								\
+	if (!VALID_TSKID(tskid)) {								\
+		ercd = E_ID;										\
+		goto error_exit;									\
+	}														\
+} while (false)
+
+#define CHECK_TSKID_SELF(tskid) do {						\
+	if (!(VALID_TSKID(tskid) || (tskid) == TSK_SELF)) {		\
+		ercd = E_ID;										\
+		goto error_exit;									\
+	}														\
+} while (false)
+
+#define CHECK_SEMID(semid) do {								\
+	if (!VALID_SEMID(semid)) {								\
+		ercd = E_ID;										\
+		goto error_exit;									\
+	}														\
+} while (false)
+
+#define CHECK_FLGID(flgid) do {								\
+	if (!VALID_FLGID(flgid)) {								\
+		ercd = E_ID;										\
+		goto error_exit;									\
+	}														\
+} while (false)
+
+#define CHECK_DTQID(dtqid) do {								\
+	if (!VALID_DTQID(dtqid)) {								\
+		ercd = E_ID;										\
+		goto error_exit;									\
+	}														\
+} while (false)
+
+#define CHECK_PDQID(pdqid) do {								\
+	if (!VALID_PDQID(pdqid)) {								\
+		ercd = E_ID;										\
+		goto error_exit;									\
+	}														\
+} while (false)
+
+#define CHECK_MBXID(mbxid) do {								\
+	if (!VALID_MBXID(mbxid)) {								\
+		ercd = E_ID;										\
+		goto error_exit;									\
+	}														\
+} while (false)
+
+#define CHECK_MTXID(mtxid) do {								\
+	if (!VALID_MTXID(mtxid)) {								\
+		ercd = E_ID;										\
+		goto error_exit;									\
+	}														\
+} while (false)
+
+#define CHECK_MPFID(mpfid) do {								\
+	if (!VALID_MPFID(mpfid)) {								\
+		ercd = E_ID;										\
+		goto error_exit;									\
+	}														\
+} while (false)
+
+#define CHECK_CYCID(cycid) do {								\
+	if (!VALID_CYCID(cycid)) {								\
+		ercd = E_ID;										\
+		goto error_exit;									\
+	}														\
+} while (false)
+
+#define CHECK_ALMID(almid) do {								\
+	if (!VALID_ALMID(almid)) {								\
+		ercd = E_ID;										\
+		goto error_exit;									\
+	}														\
+} while (false)
+
+#define CHECK_ISRID(isrid) do {								\
+	if (!VALID_ISRID(isrid)) {								\
+		ercd = E_ID;										\
+		goto error_exit;									\
+	}														\
+} while (false)
+
+/*
+ *  呼出しコンテキストのチェック（E_CTX）
+ */
+#define CHECK_TSKCTX() do {									\
+	if (sense_context()) {									\
+		ercd = E_CTX;										\
+		goto error_exit;									\
+	}														\
+} while (false)
+
+#define CHECK_INTCTX() do {									\
+	if (!sense_context()) {									\
+		ercd = E_CTX;										\
+		goto error_exit;									\
+	}														\
+} while (false)
+
+/*
+ *  呼出しコンテキストとCPUロック状態のチェック（E_CTX）
+ */
+#define CHECK_TSKCTX_UNL() do {								\
+	if (sense_context() || t_sense_lock()) {				\
+		ercd = E_CTX;										\
+		goto error_exit;									\
+	}														\
+} while (false)
+
+#define CHECK_INTCTX_UNL() do {								\
+	if (!sense_context() || i_sense_lock()) {				\
+		ercd = E_CTX;										\
+		goto error_exit;									\
+	}														\
+} while (false)
+
+/*
+ *  ディスパッチ保留状態でないかのチェック（E_CTX）
+ */
+#define CHECK_DISPATCH() do {								\
+	if (sense_context() || t_sense_lock() || !dspflg) {		\
+		ercd = E_CTX;										\
+		goto error_exit;									\
+	}														\
+} while (false)
+
+/*
+ *  その他のコンテキストエラーのチェック（E_CTX）
+ */
+#define CHECK_CTX(exp) do {									\
+	if (!(exp)) {											\
+		ercd = E_CTX;										\
+		goto error_exit;									\
+	}														\
+} while (false)
+
+/*
+ *  自タスクを指定していないかのチェック（E_ILUSE）
+ */
+#define CHECK_NONSELF(p_tcb) do {							\
+	if ((p_tcb) == p_runtsk) {								\
+		ercd = E_ILUSE;										\
+		goto error_exit;									\
+	}														\
+} while (false)
+
+/*
+ *  その他の不正使用エラーのチェック（E_ILUSE）
+ */
+#define CHECK_ILUSE(exp) do {								\
+	if (!(exp)) {											\
+		ercd = E_ILUSE;										\
+		goto error_exit;									\
+	}														\
+} while (false)
+
+/*
+ *  未サポート機能エラーのチェック（E_NOSPT）
+ */
+#define CHECK_NOSPT(exp) do {								\
+	if (!(exp)) {											\
+		ercd = E_NOSPT;										\
+		goto error_exit;									\
+	}														\
+} while (false)
+
+/*
+ *  静的なオブジェクト状態エラーのチェック（E_OBJ）
+ */
+#define CHECK_OBJ(exp) do {									\
+	if (!(exp)) {											\
+		ercd = E_OBJ;										\
+		goto error_exit;									\
+	}														\
+} while (false)
+
+#endif /* TOPPERS_CHECK_H */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/kernel/cyclic.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/kernel/cyclic.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/kernel/cyclic.c	(revision 457)
@@ -0,0 +1,414 @@
+/*
+ *  TOPPERS/ASP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Advanced Standard Profile Kernel
+ * 
+ *  Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
+ *                              Toyohashi Univ. of Technology, JAPAN
+ *  Copyright (C) 2005-2014 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *		周期ハンドラ機能
+ */
+
+#include "kernel_impl.h"
+#include "check.h"
+#include "cyclic.h"
+
+/*
+ *  トレースログマクロのデフォルト定義
+ */
+#ifndef LOG_CYC_ENTER
+#define LOG_CYC_ENTER(p_cyccb)
+#endif /* LOG_CYC_ENTER */
+
+#ifndef LOG_CYC_LEAVE
+#define LOG_CYC_LEAVE(p_cyccb)
+#endif /* LOG_CYC_LEAVE */
+
+#ifndef LOG_ACRE_CYC_ENTER
+#define LOG_ACRE_CYC_ENTER(pk_ccyc)
+#endif /* LOG_ACRE_CYC_ENTER */
+
+#ifndef LOG_ACRE_CYC_LEAVE
+#define LOG_ACRE_CYC_LEAVE(ercd)
+#endif /* LOG_ACRE_CYC_LEAVE */
+
+#ifndef LOG_DEL_CYC_ENTER
+#define LOG_DEL_CYC_ENTER(cycid)
+#endif /* LOG_DEL_CYC_ENTER */
+
+#ifndef LOG_DEL_CYC_LEAVE
+#define LOG_DEL_CYC_LEAVE(ercd)
+#endif /* LOG_DEL_CYC_LEAVE */
+
+#ifndef LOG_STA_CYC_ENTER
+#define LOG_STA_CYC_ENTER(cycid)
+#endif /* LOG_STA_CYC_ENTER */
+
+#ifndef LOG_STA_CYC_LEAVE
+#define LOG_STA_CYC_LEAVE(ercd)
+#endif /* LOG_STA_CYC_LEAVE */
+
+#ifndef LOG_STP_CYC_ENTER
+#define LOG_STP_CYC_ENTER(cycid)
+#endif /* LOG_STP_CYC_ENTER */
+
+#ifndef LOG_STP_CYC_LEAVE
+#define LOG_STP_CYC_LEAVE(ercd)
+#endif /* LOG_STP_CYC_LEAVE */
+
+#ifndef LOG_REF_CYC_ENTER
+#define LOG_REF_CYC_ENTER(cycid, pk_rcyc)
+#endif /* LOG_REF_CYC_ENTER */
+
+#ifndef LOG_REF_CYC_LEAVE
+#define LOG_REF_CYC_LEAVE(ercd, pk_rcyc)
+#endif /* LOG_REF_CYC_LEAVE */
+
+/*
+ *  周期ハンドラの数
+ */
+#define tnum_cyc	((uint_t)(tmax_cycid - TMIN_CYCID + 1))
+#define tnum_scyc	((uint_t)(tmax_scycid - TMIN_CYCID + 1))
+
+/*
+ *  周期ハンドラIDから周期ハンドラ管理ブロックを取り出すためのマクロ
+ */
+#define INDEX_CYC(cycid)	((uint_t)((cycid) - TMIN_CYCID))
+#define get_cyccb(cycid)	(&(cyccb_table[INDEX_CYC(cycid)]))
+
+/*
+ *  周期ハンドラ起動のためのタイムイベントブロックの登録
+ */
+Inline void
+tmevtb_enqueue_cyc(CYCCB *p_cyccb, EVTTIM evttim)
+{
+	tmevtb_enqueue_evttim(&(p_cyccb->tmevtb), evttim,
+								(CBACK) call_cychdr, (void *) p_cyccb);
+	p_cyccb->evttim = evttim;
+}
+
+#ifdef TOPPERS_cycini
+
+/*
+ *  使用していない周期ハンドラ管理ブロックのリスト
+ *
+ *  周期ハンドラ管理ブロックの先頭にはキューにつなぐための領域がないた
+ *  め，タイムイベントブロック（tmevtb）の領域を用いる．
+ */
+QUEUE	free_cyccb;
+
+/*
+ *  周期ハンドラ機能の初期化
+ */
+void
+initialize_cyclic(void)
+{
+	uint_t	i, j;
+	CYCCB	*p_cyccb;
+	CYCINIB	*p_cycinib;
+
+	for (i = 0; i < tnum_scyc; i++) {
+		p_cyccb = &(cyccb_table[i]);
+		p_cyccb->p_cycinib = &(cycinib_table[i]);
+		if ((p_cyccb->p_cycinib->cycatr & TA_STA) != 0U) {
+			p_cyccb->cycsta = true;
+			tmevtb_enqueue_cyc(p_cyccb, (EVTTIM)(p_cyccb->p_cycinib->cycphs));
+		}
+		else {
+			p_cyccb->cycsta = false;
+		}
+	}
+	queue_initialize(&free_cyccb);
+	for (j = 0; i < tnum_cyc; i++, j++) {
+		p_cyccb = &(cyccb_table[i]);
+		p_cycinib = &(acycinib_table[j]);
+		p_cycinib->cycatr = TA_NOEXS;
+		p_cyccb->p_cycinib = ((const CYCINIB *) p_cycinib);
+		queue_insert_prev(&free_cyccb, ((QUEUE *) &(p_cyccb->tmevtb)));
+	}
+}
+
+#endif /* TOPPERS_cycini */
+
+/*
+ *  周期ハンドラの生成
+ */
+#ifdef TOPPERS_acre_cyc
+
+ER_UINT
+acre_cyc(const T_CCYC *pk_ccyc)
+{
+	CYCCB	*p_cyccb;
+	CYCINIB	*p_cycinib;
+	ER		ercd;
+
+	LOG_ACRE_CYC_ENTER(pk_ccyc);
+	CHECK_TSKCTX_UNL();
+	CHECK_RSATR(pk_ccyc->cycatr, TA_STA);
+	CHECK_ALIGN_FUNC(pk_ccyc->cychdr);
+	CHECK_NONNULL_FUNC(pk_ccyc->cychdr);
+	CHECK_PAR(0 < pk_ccyc->cyctim && pk_ccyc->cyctim <= TMAX_RELTIM);
+	CHECK_PAR(0 <= pk_ccyc->cycphs && pk_ccyc->cycphs <= TMAX_RELTIM);
+
+	t_lock_cpu();
+	if (tnum_cyc == 0 || queue_empty(&free_cyccb)) {
+		ercd = E_NOID;
+	}
+	else {
+		p_cyccb = ((CYCCB *)(((char *) queue_delete_next(&free_cyccb))
+												- offsetof(CYCCB, tmevtb)));
+		p_cycinib = (CYCINIB *)(p_cyccb->p_cycinib);
+		p_cycinib->cycatr = pk_ccyc->cycatr;
+		p_cycinib->exinf = pk_ccyc->exinf;
+		p_cycinib->cychdr = pk_ccyc->cychdr;
+		p_cycinib->cyctim = pk_ccyc->cyctim;
+		p_cycinib->cycphs = pk_ccyc->cycphs;
+
+		if ((p_cyccb->p_cycinib->cycatr & TA_STA) != 0U) {
+			p_cyccb->cycsta = true;
+			tmevtb_enqueue_cyc(p_cyccb,
+								base_time + p_cyccb->p_cycinib->cycphs);
+		}
+		else {
+			p_cyccb->cycsta = false;
+		}
+		ercd = CYCID(p_cyccb);
+	}
+	t_unlock_cpu();
+
+  error_exit:
+	LOG_ACRE_CYC_LEAVE(ercd);
+	return(ercd);
+}
+
+#endif /* TOPPERS_acre_cyc */
+
+/*
+ *  周期ハンドラの削除
+ */
+#ifdef TOPPERS_del_cyc
+
+ER
+del_cyc(ID cycid)
+{
+	CYCCB	*p_cyccb;
+	CYCINIB	*p_cycinib;
+	ER		ercd;
+
+	LOG_DEL_CYC_ENTER(cycid);
+	CHECK_TSKCTX_UNL();
+	CHECK_CYCID(cycid);
+	p_cyccb = get_cyccb(cycid);
+
+	t_lock_cpu();
+	if (p_cyccb->p_cycinib->cycatr == TA_NOEXS) {
+		ercd = E_NOEXS;
+	}
+	else if (CYCID(p_cyccb) > tmax_scycid) {
+		if (p_cyccb->cycsta) {
+			p_cyccb->cycsta = false;
+			tmevtb_dequeue(&(p_cyccb->tmevtb));
+		}
+
+		p_cycinib = (CYCINIB *)(p_cyccb->p_cycinib);
+		p_cycinib->cycatr = TA_NOEXS;
+		queue_insert_prev(&free_cyccb, ((QUEUE *) &(p_cyccb->tmevtb)));
+		ercd = E_OK;
+	}
+	else {
+		ercd = E_OBJ;
+	}
+	t_unlock_cpu();
+
+  error_exit:
+	LOG_DEL_CYC_LEAVE(ercd);
+	return(ercd);
+}
+
+#endif /* TOPPERS_del_cyc */
+
+/*
+ *  周期ハンドラの動作開始
+ */
+#ifdef TOPPERS_sta_cyc
+
+ER
+sta_cyc(ID cycid)
+{
+	CYCCB	*p_cyccb;
+	ER		ercd;
+
+	LOG_STA_CYC_ENTER(cycid);
+	CHECK_TSKCTX_UNL();
+	CHECK_CYCID(cycid);
+	p_cyccb = get_cyccb(cycid);
+
+	t_lock_cpu();
+	if (p_cyccb->p_cycinib->cycatr == TA_NOEXS) {
+		ercd = E_NOEXS;
+	}
+	else {
+		if (p_cyccb->cycsta) {
+			tmevtb_dequeue(&(p_cyccb->tmevtb));
+		}
+		else {
+			p_cyccb->cycsta = true;
+		}
+		tmevtb_enqueue_cyc(p_cyccb, base_time + p_cyccb->p_cycinib->cycphs);
+		ercd = E_OK;
+	}
+	t_unlock_cpu();
+
+  error_exit:
+	LOG_STA_CYC_LEAVE(ercd);
+	return(ercd);
+}
+
+#endif /* TOPPERS_sta_cyc */
+
+/*
+ *  周期ハンドラの動作停止
+ */
+#ifdef TOPPERS_stp_cyc
+
+ER
+stp_cyc(ID cycid)
+{
+	CYCCB	*p_cyccb;
+	ER		ercd;
+
+	LOG_STP_CYC_ENTER(cycid);
+	CHECK_TSKCTX_UNL();
+	CHECK_CYCID(cycid);
+	p_cyccb = get_cyccb(cycid);
+
+	t_lock_cpu();
+	if (p_cyccb->p_cycinib->cycatr == TA_NOEXS) {
+		ercd = E_NOEXS;
+	}
+	else {
+		if (p_cyccb->cycsta) {
+			p_cyccb->cycsta = false;
+			tmevtb_dequeue(&(p_cyccb->tmevtb));
+		}
+		ercd = E_OK;
+	}
+	t_unlock_cpu();
+
+  error_exit:
+	LOG_STP_CYC_LEAVE(ercd);
+	return(ercd);
+}
+
+#endif /* TOPPERS_stp_cyc */
+
+/*
+ *  周期ハンドラの状態参照
+ */
+#ifdef TOPPERS_ref_cyc
+
+ER
+ref_cyc(ID cycid, T_RCYC *pk_rcyc)
+{
+	CYCCB	*p_cyccb;
+	ER		ercd;
+    
+	LOG_REF_CYC_ENTER(cycid, pk_rcyc);
+	CHECK_TSKCTX_UNL();
+	CHECK_CYCID(cycid);
+	p_cyccb = get_cyccb(cycid);
+
+	t_lock_cpu();
+	if (p_cyccb->p_cycinib->cycatr == TA_NOEXS) {
+		ercd = E_NOEXS;
+	}
+	else {
+		if (p_cyccb->cycsta) {
+			pk_rcyc->cycstat = TCYC_STA;
+			pk_rcyc->lefttim = tmevt_lefttim(&(p_cyccb->tmevtb));
+		}
+		else {
+			pk_rcyc->cycstat = TCYC_STP;
+		}
+		ercd = E_OK;
+	}
+	t_unlock_cpu();
+
+  error_exit:
+	LOG_REF_CYC_LEAVE(ercd, pk_rcyc);
+	return(ercd);
+}
+
+#endif /* TOPPERS_ref_cyc */
+
+/*
+ *  周期ハンドラ起動ルーチン
+ */
+#ifdef TOPPERS_cyccal
+
+void
+call_cychdr(CYCCB *p_cyccb)
+{
+	PRI		saved_ipm;
+
+	/*
+	 *  次回の起動のためのタイムイベントブロックを登録する．
+	 *
+	 *  同じタイムティックで周期ハンドラを再度起動すべき場合には，この
+	 *  関数からsignal_timeに戻った後に，再度この関数が呼ばれることにな
+	 *  る．
+	 */
+	tmevtb_enqueue_cyc(p_cyccb, p_cyccb->evttim + p_cyccb->p_cycinib->cyctim);
+
+	/*
+	 *  周期ハンドラを，CPUロック解除状態で呼び出す．
+	 */
+	saved_ipm = i_get_ipm();
+	i_unlock_cpu();
+
+	LOG_CYC_ENTER(p_cyccb);
+	(*((CYCHDR)(p_cyccb->p_cycinib->cychdr)))(p_cyccb->p_cycinib->exinf);
+	LOG_CYC_LEAVE(p_cyccb);
+
+	if (!i_sense_lock()) {
+		i_lock_cpu();
+	}
+	i_set_ipm(saved_ipm);
+}
+
+#endif /* TOPPERS_cyccal */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/kernel/cyclic.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/kernel/cyclic.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/kernel/cyclic.h	(revision 457)
@@ -0,0 +1,111 @@
+/*
+ *  TOPPERS/ASP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Advanced Standard Profile Kernel
+ * 
+ *  Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
+ *                              Toyohashi Univ. of Technology, JAPAN
+ *  Copyright (C) 2005-2010 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *		周期ハンドラ機能
+ */
+
+#ifndef TOPPERS_CYCLIC_H
+#define TOPPERS_CYCLIC_H
+
+#include <queue.h>
+#include "time_event.h"
+
+/*
+ *  周期ハンドラ初期化ブロック
+ */
+typedef struct cyclic_handler_initialization_block {
+	ATR			cycatr;			/* 周期ハンドラ属性 */
+	intptr_t	exinf;			/* 周期ハンドラの拡張情報 */
+	CYCHDR		cychdr;			/* 周期ハンドラの起動番地 */
+	RELTIM		cyctim;			/* 周期ハンドラの起動周期 */
+	RELTIM		cycphs;			/* 周期ハンドラの起動位相 */
+} CYCINIB;
+
+/*
+ *  周期ハンドラ管理ブロック
+ */
+typedef struct cyclic_handler_control_block {
+	const CYCINIB *p_cycinib;	/* 初期化ブロックへのポインタ */
+	bool_t		cycsta;			/* 周期ハンドラの動作状態 */
+	EVTTIM		evttim;			/* 次に周期ハンドラを起動する時刻 */
+	TMEVTB		tmevtb;			/* タイムイベントブロック */
+} CYCCB;
+
+/*
+ *  使用していない周期ハンドラ管理ブロックのリスト
+ */
+extern QUEUE	free_cyccb;
+
+/*
+ *  周期ハンドラIDの最大値（kernel_cfg.c）
+ */
+extern const ID	tmax_cycid;
+extern const ID	tmax_scycid;
+
+/*
+ *  周期ハンドラ初期化ブロックのエリア（kernel_cfg.c）
+ */
+extern const CYCINIB	cycinib_table[];
+extern CYCINIB			acycinib_table[];
+
+/*
+ *  周期ハンドラ管理ブロックのエリア（kernel_cfg.c）
+ */
+extern CYCCB	cyccb_table[];
+
+/*
+ *  周期ハンドラ管理ブロックから周期ハンドラIDを取り出すためのマクロ
+ */
+#define	CYCID(p_cyccb)	((ID)(((p_cyccb) - cyccb_table) + TMIN_CYCID))
+
+/*
+ *  周期ハンドラ機能の初期化
+ */
+extern void	initialize_cyclic(void);
+
+/*
+ *  周期ハンドラ起動ルーチン
+ */
+extern void	call_cychdr(CYCCB *p_cyccb);
+
+#endif /* TOPPERS_CYCLIC_H */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/kernel/dataqueue.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/kernel/dataqueue.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/kernel/dataqueue.c	(revision 457)
@@ -0,0 +1,932 @@
+/*
+ *  TOPPERS/ASP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Advanced Standard Profile Kernel
+ * 
+ *  Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
+ *                              Toyohashi Univ. of Technology, JAPAN
+ *  Copyright (C) 2005-2017 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  $Id$
+ */
+
+/*
+ *		データキュー機能
+ */
+
+#include "kernel_impl.h"
+#include "check.h"
+#include "task.h"
+#include "wait.h"
+#include "dataqueue.h"
+
+/*
+ *  トレースログマクロのデフォルト定義
+ */
+#ifndef LOG_ACRE_DTQ_ENTER
+#define LOG_ACRE_DTQ_ENTER(pk_cdtq)
+#endif /* LOG_ACRE_DTQ_ENTER */
+
+#ifndef LOG_ACRE_DTQ_LEAVE
+#define LOG_ACRE_DTQ_LEAVE(ercd)
+#endif /* LOG_ACRE_DTQ_LEAVE */
+
+#ifndef LOG_DEL_DTQ_ENTER
+#define LOG_DEL_DTQ_ENTER(dtqid)
+#endif /* LOG_DEL_DTQ_ENTER */
+
+#ifndef LOG_DEL_DTQ_LEAVE
+#define LOG_DEL_DTQ_LEAVE(ercd)
+#endif /* LOG_DEL_DTQ_LEAVE */
+
+#ifndef LOG_SND_DTQ_ENTER
+#define LOG_SND_DTQ_ENTER(dtqid, data)
+#endif /* LOG_SND_DTQ_ENTER */
+
+#ifndef LOG_SND_DTQ_LEAVE
+#define LOG_SND_DTQ_LEAVE(ercd)
+#endif /* LOG_SND_DTQ_LEAVE */
+
+#ifndef LOG_PSND_DTQ_ENTER
+#define LOG_PSND_DTQ_ENTER(dtqid, data)
+#endif /* LOG_PSND_DTQ_ENTER */
+
+#ifndef LOG_PSND_DTQ_LEAVE
+#define LOG_PSND_DTQ_LEAVE(ercd)
+#endif /* LOG_PSND_DTQ_LEAVE */
+
+#ifndef LOG_IPSND_DTQ_ENTER
+#define LOG_IPSND_DTQ_ENTER(dtqid, data)
+#endif /* LOG_IPSND_DTQ_ENTER */
+
+#ifndef LOG_IPSND_DTQ_LEAVE
+#define LOG_IPSND_DTQ_LEAVE(ercd)
+#endif /* LOG_IPSND_DTQ_LEAVE */
+
+#ifndef LOG_TSND_DTQ_ENTER
+#define LOG_TSND_DTQ_ENTER(dtqid, data, tmout)
+#endif /* LOG_TSND_DTQ_ENTER */
+
+#ifndef LOG_TSND_DTQ_LEAVE
+#define LOG_TSND_DTQ_LEAVE(ercd)
+#endif /* LOG_TSND_DTQ_LEAVE */
+
+#ifndef LOG_FSND_DTQ_ENTER
+#define LOG_FSND_DTQ_ENTER(dtqid, data)
+#endif /* LOG_FSND_DTQ_ENTER */
+
+#ifndef LOG_FSND_DTQ_LEAVE
+#define LOG_FSND_DTQ_LEAVE(ercd)
+#endif /* LOG_FSND_DTQ_LEAVE */
+
+#ifndef LOG_IFSND_DTQ_ENTER
+#define LOG_IFSND_DTQ_ENTER(dtqid, data)
+#endif /* LOG_IFSND_DTQ_ENTER */
+
+#ifndef LOG_IFSND_DTQ_LEAVE
+#define LOG_IFSND_DTQ_LEAVE(ercd)
+#endif /* LOG_IFSND_DTQ_LEAVE */
+
+#ifndef LOG_RCV_DTQ_ENTER
+#define LOG_RCV_DTQ_ENTER(dtqid, p_data)
+#endif /* LOG_RCV_DTQ_ENTER */
+
+#ifndef LOG_RCV_DTQ_LEAVE
+#define LOG_RCV_DTQ_LEAVE(ercd, data)
+#endif /* LOG_RCV_DTQ_LEAVE */
+
+#ifndef LOG_PRCV_DTQ_ENTER
+#define LOG_PRCV_DTQ_ENTER(dtqid, p_data)
+#endif /* LOG_PRCV_DTQ_ENTER */
+
+#ifndef LOG_PRCV_DTQ_LEAVE
+#define LOG_PRCV_DTQ_LEAVE(ercd, data)
+#endif /* LOG_PRCV_DTQ_LEAVE */
+
+#ifndef LOG_TRCV_DTQ_ENTER
+#define LOG_TRCV_DTQ_ENTER(dtqid, p_data, tmout)
+#endif /* LOG_TRCV_DTQ_ENTER */
+
+#ifndef LOG_TRCV_DTQ_LEAVE
+#define LOG_TRCV_DTQ_LEAVE(ercd, data)
+#endif /* LOG_TRCV_DTQ_LEAVE */
+
+#ifndef LOG_INI_DTQ_ENTER
+#define LOG_INI_DTQ_ENTER(dtqid)
+#endif /* LOG_INI_DTQ_ENTER */
+
+#ifndef LOG_INI_DTQ_LEAVE
+#define LOG_INI_DTQ_LEAVE(ercd)
+#endif /* LOG_INI_DTQ_LEAVE */
+
+#ifndef LOG_REF_DTQ_ENTER
+#define LOG_REF_DTQ_ENTER(dtqid, pk_rdtq)
+#endif /* LOG_REF_DTQ_ENTER */
+
+#ifndef LOG_REF_DTQ_LEAVE
+#define LOG_REF_DTQ_LEAVE(ercd, pk_rdtq)
+#endif /* LOG_REF_DTQ_LEAVE */
+
+/*
+ *  データキューの数
+ */
+#define tnum_dtq	((uint_t)(tmax_dtqid - TMIN_DTQID + 1))
+#define tnum_sdtq	((uint_t)(tmax_sdtqid - TMIN_DTQID + 1))
+
+/*
+ *  データキューIDからデータキュー管理ブロックを取り出すためのマクロ
+ */
+#define INDEX_DTQ(dtqid)	((uint_t)((dtqid) - TMIN_DTQID))
+#define get_dtqcb(dtqid)	(&(dtqcb_table[INDEX_DTQ(dtqid)]))
+
+#ifdef TOPPERS_dtqini
+
+/*
+ *  使用していないデータキュー管理ブロックのリスト
+ */
+QUEUE	free_dtqcb;
+
+/*
+ *  データキュー機能の初期化
+ */
+void
+initialize_dataqueue(void)
+{
+	uint_t	i, j;
+	DTQCB	*p_dtqcb;
+	DTQINIB	*p_dtqinib;
+
+	for (i = 0; i < tnum_sdtq; i++) {
+		p_dtqcb = &(dtqcb_table[i]);
+		queue_initialize(&(p_dtqcb->swait_queue));
+		p_dtqcb->p_dtqinib = &(dtqinib_table[i]);
+		queue_initialize(&(p_dtqcb->rwait_queue));
+		p_dtqcb->count = 0U;
+		p_dtqcb->head = 0U;
+		p_dtqcb->tail = 0U;
+	}
+	queue_initialize(&free_dtqcb);
+	for (j = 0; i < tnum_dtq; i++, j++) {
+		p_dtqcb = &(dtqcb_table[i]);
+		p_dtqinib = &(adtqinib_table[j]);
+		p_dtqinib->dtqatr = TA_NOEXS;
+		p_dtqcb->p_dtqinib = ((const DTQINIB *) p_dtqinib);
+		queue_insert_prev(&free_dtqcb, &(p_dtqcb->swait_queue));
+	}
+}
+
+#endif /* TOPPERS_dtqini */
+
+/*
+ *  データキュー管理領域へのデータの格納
+ */
+#ifdef TOPPERS_dtqenq
+
+void
+enqueue_data(DTQCB *p_dtqcb, intptr_t data)
+{
+	(p_dtqcb->p_dtqinib->p_dtqmb + p_dtqcb->tail)->data = data;
+	p_dtqcb->count++;
+	p_dtqcb->tail++;
+	if (p_dtqcb->tail >= p_dtqcb->p_dtqinib->dtqcnt) {
+		p_dtqcb->tail = 0U;
+	}
+}
+
+#endif /* TOPPERS_dtqenq */
+
+/*
+ *  データキュー管理領域へのデータの強制格納
+ */
+#ifdef TOPPERS_dtqfenq
+
+void
+force_enqueue_data(DTQCB *p_dtqcb, intptr_t data)
+{
+	(p_dtqcb->p_dtqinib->p_dtqmb + p_dtqcb->tail)->data = data;
+	p_dtqcb->tail++;
+	if (p_dtqcb->tail >= p_dtqcb->p_dtqinib->dtqcnt) {
+		p_dtqcb->tail = 0U;
+	}
+	if (p_dtqcb->count < p_dtqcb->p_dtqinib->dtqcnt) {
+		p_dtqcb->count++;
+	}
+	else {
+		p_dtqcb->head = p_dtqcb->tail;
+	}
+}
+
+#endif /* TOPPERS_dtqfenq */
+
+/*
+ *  データキュー管理領域からのデータの取出し
+ */
+#ifdef TOPPERS_dtqdeq
+
+void
+dequeue_data(DTQCB *p_dtqcb, intptr_t *p_data)
+{
+	*p_data = (p_dtqcb->p_dtqinib->p_dtqmb + p_dtqcb->head)->data;
+	p_dtqcb->count--;
+	p_dtqcb->head++;
+	if (p_dtqcb->head >= p_dtqcb->p_dtqinib->dtqcnt) {
+		p_dtqcb->head = 0U;
+	}
+}
+
+#endif /* TOPPERS_dtqdeq */
+
+/*
+ *  データキューへのデータ送信
+ */
+#ifdef TOPPERS_dtqsnd
+
+bool_t
+send_data(DTQCB *p_dtqcb, intptr_t data, bool_t *p_dspreq)
+{
+	TCB		*p_tcb;
+
+	if (!queue_empty(&(p_dtqcb->rwait_queue))) {
+		p_tcb = (TCB *) queue_delete_next(&(p_dtqcb->rwait_queue));
+		((WINFO_DTQ *)(p_tcb->p_winfo))->data = data;
+		*p_dspreq = wait_complete(p_tcb);
+		return(true);
+	}
+	else if (p_dtqcb->count < p_dtqcb->p_dtqinib->dtqcnt) {
+		enqueue_data(p_dtqcb, data);
+		*p_dspreq = false;
+		return(true);
+	}
+	else {
+		return(false);
+	}
+}
+
+#endif /* TOPPERS_dtqsnd */
+
+/*
+ *  データキューへのデータ強制送信
+ */
+#ifdef TOPPERS_dtqfsnd
+
+bool_t
+force_send_data(DTQCB *p_dtqcb, intptr_t data)
+{
+	TCB		*p_tcb;
+
+	if (!queue_empty(&(p_dtqcb->rwait_queue))) {
+		p_tcb = (TCB *) queue_delete_next(&(p_dtqcb->rwait_queue));
+		((WINFO_DTQ *)(p_tcb->p_winfo))->data = data;
+		return(wait_complete(p_tcb));
+	}
+	else {
+		force_enqueue_data(p_dtqcb, data);
+		return(false);
+	}
+}
+
+#endif /* TOPPERS_dtqfsnd */
+
+/*
+ *  データキューからのデータ受信
+ */
+#ifdef TOPPERS_dtqrcv
+
+bool_t
+receive_data(DTQCB *p_dtqcb, intptr_t *p_data, bool_t *p_dspreq)
+{
+	TCB		*p_tcb;
+	intptr_t data;
+
+	if (p_dtqcb->count > 0U) {
+		dequeue_data(p_dtqcb, p_data);
+		if (!queue_empty(&(p_dtqcb->swait_queue))) {
+			p_tcb = (TCB *) queue_delete_next(&(p_dtqcb->swait_queue));
+			data = ((WINFO_DTQ *)(p_tcb->p_winfo))->data;
+			enqueue_data(p_dtqcb, data);
+			*p_dspreq = wait_complete(p_tcb);
+		}
+		else {
+			*p_dspreq = false;
+		}
+		return(true);
+	}
+	else if (!queue_empty(&(p_dtqcb->swait_queue))) {
+		p_tcb = (TCB *) queue_delete_next(&(p_dtqcb->swait_queue));
+		*p_data = ((WINFO_DTQ *)(p_tcb->p_winfo))->data;
+		*p_dspreq = wait_complete(p_tcb);
+		return(true);
+	}
+	else {
+		return(false);
+	}
+}
+
+#endif /* TOPPERS_dtqrcv */
+
+/*
+ *  データキューの生成
+ */
+#ifdef TOPPERS_acre_dtq
+
+ER_UINT
+acre_dtq(const T_CDTQ *pk_cdtq)
+{
+	DTQCB	*p_dtqcb;
+	DTQINIB	*p_dtqinib;
+	ATR		dtqatr;
+	DTQMB	*p_dtqmb;
+	ER		ercd;
+
+	LOG_ACRE_DTQ_ENTER(pk_cdtq);
+	CHECK_TSKCTX_UNL();
+	CHECK_RSATR(pk_cdtq->dtqatr, TA_TPRI);
+	if (pk_cdtq->dtqmb != NULL) {
+		CHECK_ALIGN_MB(pk_cdtq->dtqmb);
+	}
+	dtqatr = pk_cdtq->dtqatr;
+	p_dtqmb = pk_cdtq->dtqmb;
+
+	t_lock_cpu();
+	if (tnum_dtq == 0 || queue_empty(&free_dtqcb)) {
+		ercd = E_NOID;
+	}
+	else {
+		if (pk_cdtq->dtqcnt != 0 && p_dtqmb == NULL) {
+			p_dtqmb = kernel_malloc(sizeof(DTQMB) * pk_cdtq->dtqcnt);
+			dtqatr |= TA_MBALLOC;
+		}
+		if (pk_cdtq->dtqcnt != 0 && p_dtqmb == NULL) {
+			ercd = E_NOMEM;
+		}
+		else {
+			p_dtqcb = ((DTQCB *) queue_delete_next(&free_dtqcb));
+			p_dtqinib = (DTQINIB *)(p_dtqcb->p_dtqinib);
+			p_dtqinib->dtqatr = dtqatr;
+			p_dtqinib->dtqcnt = pk_cdtq->dtqcnt;
+			p_dtqinib->p_dtqmb = p_dtqmb;
+
+			queue_initialize(&(p_dtqcb->swait_queue));
+			queue_initialize(&(p_dtqcb->rwait_queue));
+			p_dtqcb->count = 0U;
+			p_dtqcb->head = 0U;
+			p_dtqcb->tail = 0U;
+			ercd = DTQID(p_dtqcb);
+		}
+	}
+	t_unlock_cpu();
+
+  error_exit:
+	LOG_ACRE_DTQ_LEAVE(ercd);
+	return(ercd);
+}
+
+#endif /* TOPPERS_acre_dtq */
+
+/*
+ *  データキューの削除
+ */
+#ifdef TOPPERS_del_dtq
+
+ER
+del_dtq(ID dtqid)
+{
+	DTQCB	*p_dtqcb;
+	DTQINIB	*p_dtqinib;
+	bool_t	dspreq;
+	ER		ercd;
+
+	LOG_DEL_DTQ_ENTER(dtqid);
+	CHECK_TSKCTX_UNL();
+	CHECK_DTQID(dtqid);
+	p_dtqcb = get_dtqcb(dtqid);
+
+	t_lock_cpu();
+	if (p_dtqcb->p_dtqinib->dtqatr == TA_NOEXS) {
+		ercd = E_NOEXS;
+	}
+	else if (DTQID(p_dtqcb) > tmax_sdtqid) {
+		dspreq = init_wait_queue(&(p_dtqcb->swait_queue));
+		if (init_wait_queue(&(p_dtqcb->rwait_queue))) {
+			dspreq = true;
+		}
+		p_dtqinib = (DTQINIB *)(p_dtqcb->p_dtqinib);
+		if ((p_dtqinib->dtqatr & TA_MBALLOC) != 0U) {
+			kernel_free(p_dtqinib->p_dtqmb);
+		}
+		p_dtqinib->dtqatr = TA_NOEXS;
+		queue_insert_prev(&free_dtqcb, &(p_dtqcb->swait_queue));
+		if (dspreq) {
+			dispatch();
+		}
+		ercd = E_OK;
+	}
+	else {
+		ercd = E_OBJ;
+	}
+	t_unlock_cpu();
+
+  error_exit:
+	LOG_DEL_DTQ_LEAVE(ercd);
+	return(ercd);
+}
+
+#endif /* TOPPERS_del_dtq */
+
+/*
+ *  データキューへの送信
+ */
+#ifdef TOPPERS_snd_dtq
+
+ER
+snd_dtq(ID dtqid, intptr_t data)
+{
+	DTQCB	*p_dtqcb;
+	WINFO_DTQ winfo_dtq;
+	bool_t	dspreq;
+	ER		ercd;
+
+	LOG_SND_DTQ_ENTER(dtqid, data);
+	CHECK_DISPATCH();
+	CHECK_DTQID(dtqid);
+	p_dtqcb = get_dtqcb(dtqid);
+
+	t_lock_cpu();
+	if (p_dtqcb->p_dtqinib->dtqatr == TA_NOEXS) {
+		ercd = E_NOEXS;
+	}
+	else if (send_data(p_dtqcb, data, &dspreq)) {
+		if (dspreq) {
+			dispatch();
+		}
+		ercd = E_OK;
+	}
+	else {
+		winfo_dtq.data = data;
+		p_runtsk->tstat = (TS_WAITING | TS_WAIT_SDTQ);
+		wobj_make_wait((WOBJCB *) p_dtqcb, (WINFO_WOBJ *) &winfo_dtq);
+		dispatch();
+		ercd = winfo_dtq.winfo.wercd;
+	}
+	t_unlock_cpu();
+
+  error_exit:
+	LOG_SND_DTQ_LEAVE(ercd);
+	return(ercd);
+}
+
+#endif /* TOPPERS_snd_dtq */
+
+/*
+ *  データキューへの送信（ポーリング）
+ */
+#ifdef TOPPERS_psnd_dtq
+
+ER
+psnd_dtq(ID dtqid, intptr_t data)
+{
+	DTQCB	*p_dtqcb;
+	bool_t	dspreq;
+	ER		ercd;
+
+	LOG_PSND_DTQ_ENTER(dtqid, data);
+	CHECK_TSKCTX_UNL();
+	CHECK_DTQID(dtqid);
+	p_dtqcb = get_dtqcb(dtqid);
+
+	t_lock_cpu();
+	if (p_dtqcb->p_dtqinib->dtqatr == TA_NOEXS) {
+		ercd = E_NOEXS;
+	}
+	else if (send_data(p_dtqcb, data, &dspreq)) {
+		if (dspreq) {
+			dispatch();
+		}
+		ercd = E_OK;
+	}
+	else {
+		ercd = E_TMOUT;
+	}
+	t_unlock_cpu();
+
+  error_exit:
+	LOG_PSND_DTQ_LEAVE(ercd);
+	return(ercd);
+}
+
+#endif /* TOPPERS_psnd_dtq */
+
+/*
+ *  データキューへの送信（ポーリング，非タスクコンテキスト用）
+ */
+#ifdef TOPPERS_ipsnd_dtq
+
+ER
+ipsnd_dtq(ID dtqid, intptr_t data)
+{
+	DTQCB	*p_dtqcb;
+	bool_t	dspreq;
+	ER		ercd;
+
+	LOG_IPSND_DTQ_ENTER(dtqid, data);
+	CHECK_INTCTX_UNL();
+	CHECK_DTQID(dtqid);
+	p_dtqcb = get_dtqcb(dtqid);
+
+	i_lock_cpu();
+	if (p_dtqcb->p_dtqinib->dtqatr == TA_NOEXS) {
+		ercd = E_NOEXS;
+	}
+	else if (send_data(p_dtqcb, data, &dspreq)) {
+		if (dspreq) {
+			reqflg = true;
+		}
+		ercd = E_OK;
+	}
+	else {
+		ercd = E_TMOUT;
+	}
+	i_unlock_cpu();
+
+  error_exit:
+	LOG_IPSND_DTQ_LEAVE(ercd);
+	return(ercd);
+}
+
+#endif /* TOPPERS_ipsnd_dtq */
+
+/*
+ *  データキューへの送信（タイムアウトあり）
+ */
+#ifdef TOPPERS_tsnd_dtq
+
+ER
+tsnd_dtq(ID dtqid, intptr_t data, TMO tmout)
+{
+	DTQCB	*p_dtqcb;
+	WINFO_DTQ winfo_dtq;
+	TMEVTB	tmevtb;
+	bool_t	dspreq;
+	ER		ercd;
+
+	LOG_TSND_DTQ_ENTER(dtqid, data, tmout);
+	CHECK_DISPATCH();
+	CHECK_DTQID(dtqid);
+	CHECK_TMOUT(tmout);
+	p_dtqcb = get_dtqcb(dtqid);
+
+	t_lock_cpu();
+	if (p_dtqcb->p_dtqinib->dtqatr == TA_NOEXS) {
+		ercd = E_NOEXS;
+	}
+	else if (send_data(p_dtqcb, data, &dspreq)) {
+		if (dspreq) {
+			dispatch();
+		}
+		ercd = E_OK;
+	}
+	else if (tmout == TMO_POL) {
+		ercd = E_TMOUT;
+	}
+	else {
+		winfo_dtq.data = data;
+		p_runtsk->tstat = (TS_WAITING | TS_WAIT_SDTQ);
+		wobj_make_wait_tmout((WOBJCB *) p_dtqcb, (WINFO_WOBJ *) &winfo_dtq,
+														&tmevtb, tmout);
+		dispatch();
+		ercd = winfo_dtq.winfo.wercd;
+	}
+	t_unlock_cpu();
+
+  error_exit:
+	LOG_TSND_DTQ_LEAVE(ercd);
+	return(ercd);
+}
+
+#endif /* TOPPERS_tsnd_dtq */
+
+/*
+ *  データキューへの強制送信
+ */
+#ifdef TOPPERS_fsnd_dtq
+
+ER
+fsnd_dtq(ID dtqid, intptr_t data)
+{
+	DTQCB	*p_dtqcb;	
+	ER		ercd;
+
+	LOG_FSND_DTQ_ENTER(dtqid, data);
+	CHECK_TSKCTX_UNL();
+	CHECK_DTQID(dtqid);
+	p_dtqcb = get_dtqcb(dtqid);
+
+	t_lock_cpu();
+	if (p_dtqcb->p_dtqinib->dtqatr == TA_NOEXS) {
+		ercd = E_NOEXS;
+	}
+	else if (!(p_dtqcb->p_dtqinib->dtqcnt > 0U)) {
+		ercd = E_ILUSE;
+	}
+	else {
+		if (force_send_data(p_dtqcb, data)) {
+			dispatch();
+		}
+		ercd = E_OK;
+	}
+	t_unlock_cpu();
+
+  error_exit:
+	LOG_FSND_DTQ_LEAVE(ercd);
+	return(ercd);
+}
+
+#endif /* TOPPERS_fsnd_dtq */
+
+/*
+ *  データキューへの強制送信（非タスクコンテキスト用）
+ */
+#ifdef TOPPERS_ifsnd_dtq
+
+ER
+ifsnd_dtq(ID dtqid, intptr_t data)
+{
+	DTQCB	*p_dtqcb;
+	ER		ercd;
+
+	LOG_IFSND_DTQ_ENTER(dtqid, data);
+	CHECK_INTCTX_UNL();
+	CHECK_DTQID(dtqid);
+	p_dtqcb = get_dtqcb(dtqid);
+
+	i_lock_cpu();
+	if (p_dtqcb->p_dtqinib->dtqatr == TA_NOEXS) {
+		ercd = E_NOEXS;
+	}
+	else if (!(p_dtqcb->p_dtqinib->dtqcnt > 0U)) {
+		ercd = E_ILUSE;
+	}
+	else {
+		if (force_send_data(p_dtqcb, data)) {
+			reqflg = true;
+		}
+		ercd = E_OK;
+	}
+	i_unlock_cpu();
+
+  error_exit:
+	LOG_IFSND_DTQ_LEAVE(ercd);
+	return(ercd);
+}
+
+#endif /* TOPPERS_ifsnd_dtq */
+
+/*
+ *  データキューからの受信
+ */
+#ifdef TOPPERS_rcv_dtq
+
+ER
+rcv_dtq(ID dtqid, intptr_t *p_data)
+{
+	DTQCB	*p_dtqcb;
+	WINFO_DTQ winfo_dtq;
+	bool_t	dspreq;
+	ER		ercd;
+
+	LOG_RCV_DTQ_ENTER(dtqid, p_data);
+	CHECK_DISPATCH();
+	CHECK_DTQID(dtqid);
+	p_dtqcb = get_dtqcb(dtqid);
+
+	t_lock_cpu();
+	if (p_dtqcb->p_dtqinib->dtqatr == TA_NOEXS) {
+		ercd = E_NOEXS;
+	}
+	else if (receive_data(p_dtqcb, p_data, &dspreq)) {
+		if (dspreq) {
+			dispatch();
+		}
+		ercd = E_OK;
+	}
+	else {
+		p_runtsk->tstat = (TS_WAITING | TS_WAIT_RDTQ);
+		make_wait(&(winfo_dtq.winfo));
+		queue_insert_prev(&(p_dtqcb->rwait_queue), &(p_runtsk->task_queue));
+		winfo_dtq.p_dtqcb = p_dtqcb;
+		LOG_TSKSTAT(p_runtsk);
+		dispatch();
+		ercd = winfo_dtq.winfo.wercd;
+		if (ercd == E_OK) {
+			*p_data = winfo_dtq.data;
+		}
+	}
+	t_unlock_cpu();
+
+  error_exit:
+	LOG_RCV_DTQ_LEAVE(ercd, *p_data);
+	return(ercd);
+}
+
+#endif /* TOPPERS_rcv_dtq */
+
+/*
+ *  データキューからの受信（ポーリング）
+ */
+#ifdef TOPPERS_prcv_dtq
+
+ER
+prcv_dtq(ID dtqid, intptr_t *p_data)
+{
+	DTQCB	*p_dtqcb;
+	bool_t	dspreq;
+	ER		ercd;
+
+	LOG_PRCV_DTQ_ENTER(dtqid, p_data);
+	CHECK_TSKCTX_UNL();
+	CHECK_DTQID(dtqid);
+	p_dtqcb = get_dtqcb(dtqid);
+
+	t_lock_cpu();
+	if (p_dtqcb->p_dtqinib->dtqatr == TA_NOEXS) {
+		ercd = E_NOEXS;
+	}
+	else if (receive_data(p_dtqcb, p_data, &dspreq)) {
+		if (dspreq) {
+			dispatch();
+		}
+		ercd = E_OK;
+	}
+	else {
+		ercd = E_TMOUT;
+	}
+	t_unlock_cpu();
+
+  error_exit:
+	LOG_PRCV_DTQ_LEAVE(ercd, *p_data);
+	return(ercd);
+}
+
+#endif /* TOPPERS_prcv_dtq */
+
+/*
+ *  データキューからの受信（タイムアウトあり）
+ */
+#ifdef TOPPERS_trcv_dtq
+
+ER
+trcv_dtq(ID dtqid, intptr_t *p_data, TMO tmout)
+{
+	DTQCB	*p_dtqcb;
+	WINFO_DTQ winfo_dtq;
+	TMEVTB	tmevtb;
+	bool_t	dspreq;
+	ER		ercd;
+
+	LOG_TRCV_DTQ_ENTER(dtqid, p_data, tmout);
+	CHECK_DISPATCH();
+	CHECK_DTQID(dtqid);
+	CHECK_TMOUT(tmout);
+	p_dtqcb = get_dtqcb(dtqid);
+
+	t_lock_cpu();
+	if (p_dtqcb->p_dtqinib->dtqatr == TA_NOEXS) {
+		ercd = E_NOEXS;
+	}
+	else if (receive_data(p_dtqcb, p_data, &dspreq)) {
+		if (dspreq) {
+			dispatch();
+		}
+		ercd = E_OK;
+	}
+	else if (tmout == TMO_POL) {
+		ercd = E_TMOUT;
+	}
+	else {
+		p_runtsk->tstat = (TS_WAITING | TS_WAIT_RDTQ);
+		make_wait_tmout(&(winfo_dtq.winfo), &tmevtb, tmout);
+		queue_insert_prev(&(p_dtqcb->rwait_queue), &(p_runtsk->task_queue));
+		winfo_dtq.p_dtqcb = p_dtqcb;
+		LOG_TSKSTAT(p_runtsk);
+		dispatch();
+		ercd = winfo_dtq.winfo.wercd;
+		if (ercd == E_OK) {
+			*p_data = winfo_dtq.data;
+		}
+	}
+	t_unlock_cpu();
+
+  error_exit:
+	LOG_TRCV_DTQ_LEAVE(ercd, *p_data);
+	return(ercd);
+}
+
+#endif /* TOPPERS_trcv_dtq */
+
+/*
+ *  データキューの再初期化
+ */
+#ifdef TOPPERS_ini_dtq
+
+ER
+ini_dtq(ID dtqid)
+{
+	DTQCB	*p_dtqcb;
+	bool_t	dspreq;
+	ER		ercd;
+    
+	LOG_INI_DTQ_ENTER(dtqid);
+	CHECK_TSKCTX_UNL();
+	CHECK_DTQID(dtqid);
+	p_dtqcb = get_dtqcb(dtqid);
+
+	t_lock_cpu();
+	if (p_dtqcb->p_dtqinib->dtqatr == TA_NOEXS) {
+		ercd = E_NOEXS;
+	}
+	else {
+		dspreq = init_wait_queue(&(p_dtqcb->swait_queue));
+		if (init_wait_queue(&(p_dtqcb->rwait_queue))) {
+			dspreq = true;
+		}
+		p_dtqcb->count = 0U;
+		p_dtqcb->head = 0U;
+		p_dtqcb->tail = 0U;
+		if (dspreq) {
+			dispatch();
+		}
+		ercd = E_OK;
+	}
+	t_unlock_cpu();
+
+  error_exit:
+	LOG_INI_DTQ_LEAVE(ercd);
+	return(ercd);
+}
+
+#endif /* TOPPERS_ini_dtq */
+
+/*
+ *  データキューの状態参照
+ */
+#ifdef TOPPERS_ref_dtq
+
+ER
+ref_dtq(ID dtqid, T_RDTQ *pk_rdtq)
+{
+	DTQCB	*p_dtqcb;
+	ER		ercd;
+    
+	LOG_REF_DTQ_ENTER(dtqid, pk_rdtq);
+	CHECK_TSKCTX_UNL();
+	CHECK_DTQID(dtqid);
+	p_dtqcb = get_dtqcb(dtqid);
+
+	t_lock_cpu();
+	if (p_dtqcb->p_dtqinib->dtqatr == TA_NOEXS) {
+		ercd = E_NOEXS;
+	}
+	else {
+		pk_rdtq->stskid = wait_tskid(&(p_dtqcb->swait_queue));
+		pk_rdtq->rtskid = wait_tskid(&(p_dtqcb->rwait_queue));
+		pk_rdtq->sdtqcnt = p_dtqcb->count;
+		ercd = E_OK;
+	}
+	t_unlock_cpu();
+
+  error_exit:
+	LOG_REF_DTQ_LEAVE(ercd, pk_rdtq);
+	return(ercd);
+}
+
+#endif /* TOPPERS_ref_dtq */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/kernel/dataqueue.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/kernel/dataqueue.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/kernel/dataqueue.h	(revision 457)
@@ -0,0 +1,166 @@
+/*
+ *  TOPPERS/ASP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Advanced Standard Profile Kernel
+ * 
+ *  Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
+ *                              Toyohashi Univ. of Technology, JAPAN
+ *  Copyright (C) 2005-2013 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *		データキュー機能
+ */
+
+#ifndef TOPPERS_DATAQUEUE_H
+#define TOPPERS_DATAQUEUE_H
+
+#include "wait.h"
+
+/*
+ *  データ管理ブロック
+ */
+typedef struct data_management_block {
+	intptr_t	data;			/* データ本体 */
+} DTQMB;
+
+/*
+ *  データキュー初期化ブロック
+ *
+ *  この構造体は，同期・通信オブジェクトの初期化ブロックの共通部分
+ *  （WOBJINIB）を拡張（オブジェクト指向言語の継承に相当）したもので，
+ *  最初のフィールドが共通になっている．
+ */
+typedef struct dataqueue_initialization_block {
+	ATR			dtqatr;			/* データキュー属性 */
+	uint_t		dtqcnt;			/* データキューの容量 */
+	DTQMB		*p_dtqmb;		/* データキュー管理領域の先頭番地 */
+} DTQINIB;
+
+/*
+ *  データキュー管理ブロック
+ *
+ *  この構造体は，同期・通信オブジェクトの管理ブロックの共通部分（WOBJCB）
+ *  を拡張（オブジェクト指向言語の継承に相当）したもので，最初の2つの
+ *  フィールドが共通になっている．
+ */
+typedef struct dataqueue_control_block {
+	QUEUE		swait_queue;	/* データキュー送信待ちキュー */
+	const DTQINIB *p_dtqinib;	/* 初期化ブロックへのポインタ */
+	QUEUE		rwait_queue;	/* データキュー受信待ちキュー */
+	uint_t		count;			/* データキュー中のデータの数 */
+	uint_t		head;			/* 最初のデータの格納場所 */
+	uint_t		tail;			/* 最後のデータの格納場所の次 */
+} DTQCB;
+
+/*
+ *  データキュー待ち情報ブロックの定義
+ *
+ *  この構造体は，同期・通信オブジェクトの待ち情報ブロックの共通部分
+ *  （WINFO_WOBJ）を拡張（オブジェクト指向言語の継承に相当）したもので，
+ *  最初の2つのフィールドが共通になっている．
+ *  データキューへの送信待ちとデータキューからの受信待ちで，同じ待ち情
+ *  報ブロックを使う．
+ */
+typedef struct dataqueue_waiting_information {
+	WINFO		winfo;			/* 標準の待ち情報ブロック */
+	DTQCB		*p_dtqcb;		/* 待っているデータキューの管理ブロック */
+	intptr_t	data;			/* 送受信データ */
+} WINFO_DTQ;
+
+/*
+ *  使用していないデータキュー管理ブロックのリスト
+ */
+extern QUEUE	free_dtqcb;
+
+/*
+ *  データキューIDの最大値（kernel_cfg.c）
+ */
+extern const ID	tmax_dtqid;
+extern const ID	tmax_sdtqid;
+
+/*
+ *  データキュー初期化ブロックのエリア（kernel_cfg.c）
+ */
+extern const DTQINIB	dtqinib_table[];
+extern DTQINIB			adtqinib_table[];
+
+/*
+ *  データキュー管理ブロックのエリア（kernel_cfg.c）
+ */
+extern DTQCB	dtqcb_table[];
+
+/*
+ *  データキュー管理ブロックからデータキューIDを取り出すためのマクロ
+ */
+#define	DTQID(p_dtqcb)	((ID)(((p_dtqcb) - dtqcb_table) + TMIN_DTQID))
+
+/*
+ *  データキュー機能の初期化
+ */
+extern void	initialize_dataqueue(void);
+
+/*
+ *  データキュー管理領域へのデータの格納
+ */
+extern void	enqueue_data(DTQCB *p_dtqcb, intptr_t data);
+
+/*
+ *  データキュー管理領域へのデータの強制格納
+ */
+extern void	force_enqueue_data(DTQCB *p_dtqcb, intptr_t data);
+
+/*
+ *  データキュー管理領域からのデータの取出し
+ */
+extern void	dequeue_data(DTQCB *p_dtqcb, intptr_t *p_data);
+
+/*
+ *  データキューへのデータ送信
+ */
+extern bool_t	send_data(DTQCB *p_dtqcb, intptr_t data, bool_t *p_dspreq);
+
+/*
+ *  データキューへのデータ強制送信
+ */
+extern bool_t	force_send_data(DTQCB *p_dtqcb, intptr_t data);
+
+/*
+ *  データキューからのデータ受信
+ */
+extern bool_t	receive_data(DTQCB *p_dtqcb, intptr_t *p_data,
+													bool_t *p_dspreq);
+
+#endif /* TOPPERS_DATAQUEUE_H */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/kernel/eventflag.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/kernel/eventflag.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/kernel/eventflag.c	(revision 457)
@@ -0,0 +1,645 @@
+/*
+ *  TOPPERS/ASP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Advanced Standard Profile Kernel
+ * 
+ *  Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
+ *                              Toyohashi Univ. of Technology, JAPAN
+ *  Copyright (C) 2005-2014 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  $Id$
+ */
+
+/*
+ *		イベントフラグ機能
+ */
+
+#include "kernel_impl.h"
+#include "check.h"
+#include "task.h"
+#include "wait.h"
+#include "eventflag.h"
+
+/*
+ *  トレースログマクロのデフォルト定義
+ */
+#ifndef LOG_ACRE_FLG_ENTER
+#define LOG_ACRE_FLG_ENTER(pk_cflg)
+#endif /* LOG_ACRE_FLG_ENTER */
+
+#ifndef LOG_ACRE_FLG_LEAVE
+#define LOG_ACRE_FLG_LEAVE(ercd)
+#endif /* LOG_ACRE_FLG_LEAVE */
+
+#ifndef LOG_DEL_FLG_ENTER
+#define LOG_DEL_FLG_ENTER(flgid)
+#endif /* LOG_DEL_FLG_ENTER */
+
+#ifndef LOG_DEL_FLG_LEAVE
+#define LOG_DEL_FLG_LEAVE(ercd)
+#endif /* LOG_DEL_FLG_LEAVE */
+
+#ifndef LOG_SET_FLG_ENTER
+#define LOG_SET_FLG_ENTER(flgid, setptn)
+#endif /* LOG_SET_FLG_ENTER */
+
+#ifndef LOG_SET_FLG_LEAVE
+#define LOG_SET_FLG_LEAVE(ercd)
+#endif /* LOG_SET_FLG_LEAVE */
+
+#ifndef LOG_ISET_FLG_ENTER
+#define LOG_ISET_FLG_ENTER(flgid, setptn)
+#endif /* LOG_ISET_FLG_ENTER */
+
+#ifndef LOG_ISET_FLG_LEAVE
+#define LOG_ISET_FLG_LEAVE(ercd)
+#endif /* LOG_ISET_FLG_LEAVE */
+
+#ifndef LOG_CLR_FLG_ENTER
+#define LOG_CLR_FLG_ENTER(flgid, clrptn)
+#endif /* LOG_CLR_FLG_ENTER */
+
+#ifndef LOG_CLR_FLG_LEAVE
+#define LOG_CLR_FLG_LEAVE(ercd)
+#endif /* LOG_CLR_FLG_LEAVE */
+
+#ifndef LOG_WAI_FLG_ENTER
+#define LOG_WAI_FLG_ENTER(flgid, waiptn, wfmode, p_flgptn)
+#endif /* LOG_WAI_FLG_ENTER */
+
+#ifndef LOG_WAI_FLG_LEAVE
+#define LOG_WAI_FLG_LEAVE(ercd, flgptn)
+#endif /* LOG_WAI_FLG_LEAVE */
+
+#ifndef LOG_POL_FLG_ENTER
+#define LOG_POL_FLG_ENTER(flgid, waiptn, wfmode, p_flgptn)
+#endif /* LOG_POL_FLG_ENTER */
+
+#ifndef LOG_POL_FLG_LEAVE
+#define LOG_POL_FLG_LEAVE(ercd, flgptn)
+#endif /* LOG_POL_FLG_LEAVE */
+
+#ifndef LOG_TWAI_FLG_ENTER
+#define LOG_TWAI_FLG_ENTER(flgid, waiptn, wfmode, p_flgptn, tmout)
+#endif /* LOG_TWAI_FLG_ENTER */
+
+#ifndef LOG_TWAI_FLG_LEAVE
+#define LOG_TWAI_FLG_LEAVE(ercd, flgptn)
+#endif /* LOG_TWAI_FLG_LEAVE */
+
+#ifndef LOG_INI_FLG_ENTER
+#define LOG_INI_FLG_ENTER(flgid)
+#endif /* LOG_INI_FLG_ENTER */
+
+#ifndef LOG_INI_FLG_LEAVE
+#define LOG_INI_FLG_LEAVE(ercd)
+#endif /* LOG_INI_FLG_LEAVE */
+
+#ifndef LOG_REF_FLG_ENTER
+#define LOG_REF_FLG_ENTER(flgid, pk_rflg)
+#endif /* LOG_REF_FLG_ENTER */
+
+#ifndef LOG_REF_FLG_LEAVE
+#define LOG_REF_FLG_LEAVE(ercd, pk_rflg)
+#endif /* LOG_REF_FLG_LEAVE */
+
+/*
+ *  イベントフラグの数
+ */
+#define tnum_flg	((uint_t)(tmax_flgid - TMIN_FLGID + 1))
+#define tnum_sflg	((uint_t)(tmax_sflgid - TMIN_FLGID + 1))
+
+/*
+ *  イベントフラグIDからイベントフラグ管理ブロックを取り出すためのマクロ
+ */
+#define INDEX_FLG(flgid)	((uint_t)((flgid) - TMIN_FLGID))
+#define get_flgcb(flgid)	(&(flgcb_table[INDEX_FLG(flgid)]))
+
+#ifdef TOPPERS_flgini
+
+/*
+ *  使用していないイベントフラグ管理ブロックのリスト
+ */
+QUEUE	free_flgcb;
+
+/*
+ *  イベントフラグ機能の初期化
+ */
+void
+initialize_eventflag(void)
+{
+	uint_t	i, j;
+	FLGCB	*p_flgcb;
+	FLGINIB	*p_flginib;
+
+	for (i = 0; i < tnum_sflg; i++) {
+		p_flgcb = &(flgcb_table[i]);
+		queue_initialize(&(p_flgcb->wait_queue));
+		p_flgcb->p_flginib = &(flginib_table[i]);
+		p_flgcb->flgptn = p_flgcb->p_flginib->iflgptn;
+	}
+	queue_initialize(&free_flgcb);
+	for (j = 0; i < tnum_flg; i++, j++) {
+		p_flgcb = &(flgcb_table[i]);
+		p_flginib = &(aflginib_table[j]);
+		p_flginib->flgatr = TA_NOEXS;
+		p_flgcb->p_flginib = ((const FLGINIB *) p_flginib);
+		queue_insert_prev(&free_flgcb, &(p_flgcb->wait_queue));
+	}
+}
+
+#endif /* TOPPERS_flgini */
+
+/*
+ *  イベントフラグ待ち解除条件のチェック
+ */
+#ifdef TOPPERS_flgcnd
+
+bool_t
+check_flg_cond(FLGCB *p_flgcb, FLGPTN waiptn, MODE wfmode, FLGPTN *p_flgptn)
+{
+	if ((wfmode & TWF_ORW) != 0U ? (p_flgcb->flgptn & waiptn) != 0U
+									: (p_flgcb->flgptn & waiptn) == waiptn) {
+		*p_flgptn = p_flgcb->flgptn;
+		if ((p_flgcb->p_flginib->flgatr & TA_CLR) != 0U) {
+			p_flgcb->flgptn = 0U;
+		}
+		return(true);
+	}
+	return(false);
+}
+
+#endif /* TOPPERS_flgcnd */
+
+/*
+ *  イベントフラグの生成
+ */
+#ifdef TOPPERS_acre_flg
+
+ER_UINT
+acre_flg(const T_CFLG *pk_cflg)
+{
+	FLGCB	*p_flgcb;
+	FLGINIB	*p_flginib;
+	ER		ercd;
+
+	LOG_ACRE_FLG_ENTER(pk_cflg);
+	CHECK_TSKCTX_UNL();
+	CHECK_RSATR(pk_cflg->flgatr, TA_TPRI|TA_WMUL|TA_CLR);
+
+	t_lock_cpu();
+	if (tnum_flg == 0 || queue_empty(&free_flgcb)) {
+		ercd = E_NOID;
+	}
+	else {
+		p_flgcb = ((FLGCB *) queue_delete_next(&free_flgcb));
+		p_flginib = (FLGINIB *)(p_flgcb->p_flginib);
+		p_flginib->flgatr = pk_cflg->flgatr;
+		p_flginib->iflgptn = pk_cflg->iflgptn;
+
+		queue_initialize(&(p_flgcb->wait_queue));
+		p_flgcb->flgptn = p_flgcb->p_flginib->iflgptn;
+		ercd = FLGID(p_flgcb);
+	}
+	t_unlock_cpu();
+
+  error_exit:
+	LOG_ACRE_FLG_LEAVE(ercd);
+	return(ercd);
+}
+
+#endif /* TOPPERS_acre_flg */
+
+/*
+ *  イベントフラグの削除
+ */
+#ifdef TOPPERS_del_flg
+
+ER
+del_flg(ID flgid)
+{
+	FLGCB	*p_flgcb;
+	FLGINIB	*p_flginib;
+	bool_t	dspreq;
+	ER		ercd;
+
+	LOG_DEL_FLG_ENTER(flgid);
+	CHECK_TSKCTX_UNL();
+	CHECK_FLGID(flgid);
+	p_flgcb = get_flgcb(flgid);
+
+	t_lock_cpu();
+	if (p_flgcb->p_flginib->flgatr == TA_NOEXS) {
+		ercd = E_NOEXS;
+	}
+	else if (FLGID(p_flgcb) > tmax_sflgid) {
+		dspreq = init_wait_queue(&(p_flgcb->wait_queue));
+		p_flginib = (FLGINIB *)(p_flgcb->p_flginib);
+		p_flginib->flgatr = TA_NOEXS;
+		queue_insert_prev(&free_flgcb, &(p_flgcb->wait_queue));
+		if (dspreq) {
+			dispatch();
+		}
+		ercd = E_OK;
+	}
+	else {
+		ercd = E_OBJ;
+	}
+	t_unlock_cpu();
+
+  error_exit:
+	LOG_DEL_FLG_LEAVE(ercd);
+	return(ercd);
+}
+
+#endif /* TOPPERS_del_flg */
+
+/*
+ *  イベントフラグのセット
+ */
+#ifdef TOPPERS_set_flg
+
+ER
+set_flg(ID flgid, FLGPTN setptn)
+{
+	FLGCB	*p_flgcb;
+	QUEUE	*p_queue;
+	TCB		*p_tcb;
+	WINFO_FLG *p_winfo_flg;
+	bool_t	dspreq = false;
+	ER		ercd;
+
+	LOG_SET_FLG_ENTER(flgid, setptn);
+	CHECK_TSKCTX_UNL();
+	CHECK_FLGID(flgid);
+	p_flgcb = get_flgcb(flgid);
+
+	t_lock_cpu();
+	if (p_flgcb->p_flginib->flgatr == TA_NOEXS) {
+		ercd = E_NOEXS;
+	}
+	else {
+		p_flgcb->flgptn |= setptn;
+		p_queue = p_flgcb->wait_queue.p_next;
+		while (p_queue != &(p_flgcb->wait_queue)) {
+			p_tcb = (TCB *) p_queue;
+			p_queue = p_queue->p_next;
+			p_winfo_flg = (WINFO_FLG *)(p_tcb->p_winfo);
+			if (check_flg_cond(p_flgcb, p_winfo_flg->waiptn,
+							p_winfo_flg->wfmode, &(p_winfo_flg->flgptn))) {
+				queue_delete(&(p_tcb->task_queue));
+				if (wait_complete(p_tcb)) {
+					dspreq = true;
+				}
+				if ((p_flgcb->p_flginib->flgatr & TA_CLR) != 0U) {
+					break;
+				}
+			}
+		}
+		if (dspreq) {
+			dispatch();
+		}
+		ercd = E_OK;
+	}
+	t_unlock_cpu();
+
+  error_exit:
+	LOG_SET_FLG_LEAVE(ercd);
+	return(ercd);
+}
+
+#endif /* TOPPERS_set_flg */
+
+/*
+ *  イベントフラグのセット（非タスクコンテキスト用）
+ */
+#ifdef TOPPERS_iset_flg
+
+ER
+iset_flg(ID flgid, FLGPTN setptn)
+{
+	FLGCB	*p_flgcb;
+	QUEUE	*p_queue;
+	TCB		*p_tcb;
+	WINFO_FLG *p_winfo_flg;
+	ER		ercd;
+
+	LOG_ISET_FLG_ENTER(flgid, setptn);
+	CHECK_INTCTX_UNL();
+	CHECK_FLGID(flgid);
+	p_flgcb = get_flgcb(flgid);
+
+	i_lock_cpu();
+	if (p_flgcb->p_flginib->flgatr == TA_NOEXS) {
+		ercd = E_NOEXS;
+	}
+	else {
+		p_flgcb->flgptn |= setptn;
+		p_queue = p_flgcb->wait_queue.p_next;
+		while (p_queue != &(p_flgcb->wait_queue)) {
+			p_tcb = (TCB *) p_queue;
+			p_queue = p_queue->p_next;
+			p_winfo_flg = (WINFO_FLG *)(p_tcb->p_winfo);
+			if (check_flg_cond(p_flgcb, p_winfo_flg->waiptn,
+							p_winfo_flg->wfmode, &(p_winfo_flg->flgptn))) {
+				queue_delete(&(p_tcb->task_queue));
+				if (wait_complete(p_tcb)) {
+					reqflg = true;
+				}
+				if ((p_flgcb->p_flginib->flgatr & TA_CLR) != 0U) {
+					break;
+				}
+			}
+		}
+		ercd = E_OK;
+	}
+	i_unlock_cpu();
+
+  error_exit:
+	LOG_ISET_FLG_LEAVE(ercd);
+	return(ercd);
+}
+
+#endif /* TOPPERS_iset_flg */
+
+/*
+ *  イベントフラグのクリア
+ */
+#ifdef TOPPERS_clr_flg
+
+ER
+clr_flg(ID flgid, FLGPTN clrptn)
+{
+	FLGCB	*p_flgcb;
+	ER		ercd;
+
+	LOG_CLR_FLG_ENTER(flgid, clrptn);
+	CHECK_TSKCTX_UNL();
+	CHECK_FLGID(flgid);
+	p_flgcb = get_flgcb(flgid);
+
+	t_lock_cpu();
+	if (p_flgcb->p_flginib->flgatr == TA_NOEXS) {
+		ercd = E_NOEXS;
+	}
+	else {
+		p_flgcb->flgptn &= clrptn; 
+		ercd = E_OK;
+	}
+	t_unlock_cpu();
+
+  error_exit:
+	LOG_CLR_FLG_LEAVE(ercd);
+	return(ercd);
+}
+
+#endif /* TOPPERS_clr_flg */
+
+/*
+ *  イベントフラグ待ち
+ */
+#ifdef TOPPERS_wai_flg
+
+ER
+wai_flg(ID flgid, FLGPTN waiptn, MODE wfmode, FLGPTN *p_flgptn)
+{
+	FLGCB	*p_flgcb;
+	WINFO_FLG winfo_flg;
+	ER		ercd;
+
+	LOG_WAI_FLG_ENTER(flgid, waiptn, wfmode, p_flgptn);
+	CHECK_DISPATCH();
+	CHECK_FLGID(flgid);
+	CHECK_PAR(waiptn != 0U);
+	CHECK_PAR(wfmode == TWF_ORW || wfmode == TWF_ANDW);
+	p_flgcb = get_flgcb(flgid);
+
+	t_lock_cpu();
+	if (p_flgcb->p_flginib->flgatr == TA_NOEXS) {
+		ercd = E_NOEXS;
+	}
+	else if ((p_flgcb->p_flginib->flgatr & TA_WMUL) == 0U
+					&& !queue_empty(&(p_flgcb->wait_queue))) {
+		ercd = E_ILUSE;
+	}
+	else if (check_flg_cond(p_flgcb, waiptn, wfmode, p_flgptn)) {
+		ercd = E_OK;
+	}
+	else {
+		winfo_flg.waiptn = waiptn;
+		winfo_flg.wfmode = wfmode;
+		p_runtsk->tstat = (TS_WAITING | TS_WAIT_FLG);
+		wobj_make_wait((WOBJCB *) p_flgcb, (WINFO_WOBJ *) &winfo_flg);
+		dispatch();
+		ercd = winfo_flg.winfo.wercd;
+		if (ercd == E_OK) {
+			*p_flgptn = winfo_flg.flgptn;
+		}
+	}
+	t_unlock_cpu();
+
+  error_exit:
+	LOG_WAI_FLG_LEAVE(ercd, *p_flgptn);
+	return(ercd);
+}
+
+#endif /* TOPPERS_wai_flg */
+
+/*
+ *  イベントフラグ待ち（ポーリング）
+ */
+#ifdef TOPPERS_pol_flg
+
+ER
+pol_flg(ID flgid, FLGPTN waiptn, MODE wfmode, FLGPTN *p_flgptn)
+{
+	FLGCB	*p_flgcb;
+	ER		ercd;
+
+	LOG_POL_FLG_ENTER(flgid, waiptn, wfmode, p_flgptn);
+	CHECK_TSKCTX_UNL();
+	CHECK_FLGID(flgid);
+	CHECK_PAR(waiptn != 0U);
+	CHECK_PAR(wfmode == TWF_ORW || wfmode == TWF_ANDW);
+	p_flgcb = get_flgcb(flgid);
+
+	t_lock_cpu();
+	if (p_flgcb->p_flginib->flgatr == TA_NOEXS) {
+		ercd = E_NOEXS;
+	}
+	else if ((p_flgcb->p_flginib->flgatr & TA_WMUL) == 0U
+					&& !queue_empty(&(p_flgcb->wait_queue))) {
+		ercd = E_ILUSE;
+	}
+	else if (check_flg_cond(p_flgcb, waiptn, wfmode, p_flgptn)) {
+		ercd = E_OK;
+	}
+	else {
+		ercd = E_TMOUT;
+	}
+	t_unlock_cpu();
+
+  error_exit:
+	LOG_POL_FLG_LEAVE(ercd, *p_flgptn);
+	return(ercd);
+}
+
+#endif /* TOPPERS_pol_flg */
+
+/*
+ *  イベントフラグ待ち（タイムアウトあり）
+ */
+#ifdef TOPPERS_twai_flg
+
+ER
+twai_flg(ID flgid, FLGPTN waiptn, MODE wfmode, FLGPTN *p_flgptn, TMO tmout)
+{
+	FLGCB	*p_flgcb;
+	WINFO_FLG winfo_flg;
+	TMEVTB	tmevtb;
+	ER		ercd;
+
+	LOG_TWAI_FLG_ENTER(flgid, waiptn, wfmode, p_flgptn, tmout);
+	CHECK_DISPATCH();
+	CHECK_FLGID(flgid);
+	CHECK_PAR(waiptn != 0U);
+	CHECK_PAR(wfmode == TWF_ORW || wfmode == TWF_ANDW);
+	CHECK_TMOUT(tmout);
+	p_flgcb = get_flgcb(flgid);
+
+	t_lock_cpu();
+	if (p_flgcb->p_flginib->flgatr == TA_NOEXS) {
+		ercd = E_NOEXS;
+	}
+	else if ((p_flgcb->p_flginib->flgatr & TA_WMUL) == 0U
+					&& !queue_empty(&(p_flgcb->wait_queue))) {
+		ercd = E_ILUSE;
+	}
+	else if (check_flg_cond(p_flgcb, waiptn, wfmode, p_flgptn)) {
+		ercd = E_OK;
+	}
+	else if (tmout == TMO_POL) {
+		ercd = E_TMOUT;
+	}
+	else {
+		winfo_flg.waiptn = waiptn;
+		winfo_flg.wfmode = wfmode;
+		p_runtsk->tstat = (TS_WAITING | TS_WAIT_FLG);
+		wobj_make_wait_tmout((WOBJCB *) p_flgcb, (WINFO_WOBJ *) &winfo_flg,
+														&tmevtb, tmout);
+		dispatch();
+		ercd = winfo_flg.winfo.wercd;
+		if (ercd == E_OK) {
+			*p_flgptn = winfo_flg.flgptn;
+		}
+	}
+	t_unlock_cpu();
+
+  error_exit:
+	LOG_TWAI_FLG_LEAVE(ercd, *p_flgptn);
+	return(ercd);
+}
+
+#endif /* TOPPERS_twai_flg */
+
+/*
+ *  イベントフラグの再初期化
+ */
+#ifdef TOPPERS_ini_flg
+
+ER
+ini_flg(ID flgid)
+{
+	FLGCB	*p_flgcb;
+	bool_t	dspreq;
+	ER		ercd;
+    
+	LOG_INI_FLG_ENTER(flgid);
+	CHECK_TSKCTX_UNL();
+	CHECK_FLGID(flgid);
+	p_flgcb = get_flgcb(flgid);
+
+	t_lock_cpu();
+	if (p_flgcb->p_flginib->flgatr == TA_NOEXS) {
+		ercd = E_NOEXS;
+	}
+	else {
+		dspreq = init_wait_queue(&(p_flgcb->wait_queue));
+		p_flgcb->flgptn = p_flgcb->p_flginib->iflgptn;
+		if (dspreq) {
+			dispatch();
+		}
+		ercd = E_OK;
+	}
+	t_unlock_cpu();
+
+  error_exit:
+	LOG_INI_FLG_LEAVE(ercd);
+	return(ercd);
+}
+
+#endif /* TOPPERS_ini_flg */
+
+/*
+ *  イベントフラグの状態参照
+ */
+#ifdef TOPPERS_ref_flg
+
+ER
+ref_flg(ID flgid, T_RFLG *pk_rflg)
+{
+	FLGCB	*p_flgcb;
+	ER		ercd;
+    
+	LOG_REF_FLG_ENTER(flgid, pk_rflg);
+	CHECK_TSKCTX_UNL();
+	CHECK_FLGID(flgid);
+	p_flgcb = get_flgcb(flgid);
+
+	t_lock_cpu();
+	if (p_flgcb->p_flginib->flgatr == TA_NOEXS) {
+		ercd = E_NOEXS;
+	}
+	else {
+		pk_rflg->wtskid = wait_tskid(&(p_flgcb->wait_queue));
+		pk_rflg->flgptn = p_flgcb->flgptn;
+		ercd = E_OK;
+	}
+	t_unlock_cpu();
+
+  error_exit:
+	LOG_REF_FLG_LEAVE(ercd, pk_rflg);
+	return(ercd);
+}
+
+#endif /* TOPPERS_ref_flg */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/kernel/eventflag.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/kernel/eventflag.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/kernel/eventflag.h	(revision 457)
@@ -0,0 +1,133 @@
+/*
+ *  TOPPERS/ASP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Advanced Standard Profile Kernel
+ * 
+ *  Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
+ *                              Toyohashi Univ. of Technology, JAPAN
+ *  Copyright (C) 2005-2012 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *		イベントフラグ機能
+ */
+
+#ifndef TOPPERS_EVENTFLAG_H
+#define TOPPERS_EVENTFLAG_H
+
+#include "wait.h"
+
+/*
+ *  イベントフラグ初期化ブロック
+ *
+ *  この構造体は，同期・通信オブジェクトの初期化ブロックの共通部分
+ *  （WOBJINIB）を拡張（オブジェクト指向言語の継承に相当）したもので，
+ *  最初のフィールドが共通になっている．
+ */
+typedef struct eventflag_initialization_block {
+	ATR			flgatr;			/* イベントフラグ属性 */
+	FLGPTN		iflgptn;		/* イベントフラグのビットパターンの初期値 */
+} FLGINIB;
+
+/*
+ *  イベントフラグ管理ブロック
+ *
+ *  この構造体は，同期・通信オブジェクトの管理ブロックの共通部分（WOBJCB）
+ *  を拡張（オブジェクト指向言語の継承に相当）したもので，最初の2つの
+ *  フィールドが共通になっている．
+ */
+typedef struct eventflag_control_block {
+	QUEUE		wait_queue;		/* イベントフラグ待ちキュー */
+	const FLGINIB *p_flginib;	/* 初期化ブロックへのポインタ */
+	FLGPTN		flgptn;			/* イベントフラグ現在パターン */
+} FLGCB;
+
+/*
+ *  イベントフラグ待ち情報ブロックの定義
+ *
+ *  この構造体は，同期・通信オブジェクトの待ち情報ブロックの共通部分
+ *  （WINFO_WOBJ）を拡張（オブジェクト指向言語の継承に相当）したもので，
+ *  最初の2つのフィールドが共通になっている．
+ *
+ *  flgptnは，waiptnおよびwfmodeと同時に使うことはないため，共用体を使
+ *  えばメモリを節約することが可能である．
+ */
+typedef struct eventflag_waiting_information {
+	WINFO		winfo;			/* 標準の待ち情報ブロック */
+	FLGCB		*p_flgcb;		/* 待っているイベントフラグの管理ブロック */
+	FLGPTN		waiptn;			/* 待ちパターン */
+	MODE		wfmode;			/* 待ちモード */
+	FLGPTN		flgptn;			/* 待ち解除時のパターン */
+} WINFO_FLG;
+
+/*
+ *  使用していないイベントフラグ管理ブロックのリスト
+ */
+extern QUEUE	free_flgcb;
+
+/*
+ *  イベントフラグIDの最大値（kernel_cfg.c）
+ */
+extern const ID	tmax_flgid;
+extern const ID	tmax_sflgid;
+
+/*
+ *  イベントフラグ初期化ブロックのエリア（kernel_cfg.c）
+ */
+extern const FLGINIB	flginib_table[];
+extern FLGINIB			aflginib_table[];
+
+/*
+ *  イベントフラグ管理ブロックのエリア（kernel_cfg.c）
+ */
+extern FLGCB	flgcb_table[];
+
+/*
+ *  イベントフラグ管理ブロックからイベントフラグIDを取り出すためのマクロ
+ */
+#define	FLGID(p_flgcb)	((ID)(((p_flgcb) - flgcb_table) + TMIN_FLGID))
+
+/*
+ *  イベントフラグ機能の初期化
+ */
+extern void	initialize_eventflag(void);
+
+/*
+ *  イベントフラグ待ち解除条件のチェック
+ */
+extern bool_t	check_flg_cond(FLGCB *p_flgcb, FLGPTN waiptn,
+								MODE wfmode, FLGPTN *p_flgptn);
+
+#endif /* TOPPERS_EVENTFLAG_H */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/kernel/exception.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/kernel/exception.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/kernel/exception.c	(revision 457)
@@ -0,0 +1,138 @@
+/*
+ *  TOPPERS/ASP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Advanced Standard Profile Kernel
+ * 
+ *  Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
+ *                              Toyohashi Univ. of Technology, JAPAN
+ *  Copyright (C) 2005-2011 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *		CPU例外管理機能
+ */
+
+#include "kernel_impl.h"
+#include "task.h"
+#include "exception.h"
+
+/*
+ *  トレースログマクロのデフォルト定義
+ */
+#ifndef LOG_XSNS_DPN_ENTER
+#define LOG_XSNS_DPN_ENTER(p_excinf)
+#endif /* LOG_XSNS_DPN_ENTER */
+
+#ifndef LOG_XSNS_DPN_LEAVE
+#define LOG_XSNS_DPN_LEAVE(state)
+#endif /* LOG_XSNS_DPN_LEAVE */
+
+#ifndef LOG_XSNS_XPN_ENTER
+#define LOG_XSNS_XPN_ENTER(p_excinf)
+#endif /* LOG_XSNS_XPN_ENTER */
+
+#ifndef LOG_XSNS_XPN_LEAVE
+#define LOG_XSNS_XPN_LEAVE(state)
+#endif /* LOG_XSNS_XPN_LEAVE */
+
+/* 
+ *  CPU例外ハンドラ管理機能の初期化
+ */
+#ifdef TOPPERS_excini
+#ifndef OMIT_INITIALIZE_EXCEPTION
+
+void
+initialize_exception(void)
+{
+	uint_t			i;
+	const EXCINIB	*p_excinib;
+
+	for (i = 0; i < tnum_excno; i++) {
+		p_excinib = &(excinib_table[i]);
+		x_define_exc(p_excinib->excno, p_excinib->exc_entry);
+	}
+}
+
+#endif /* OMIT_INITIALIZE_EXCEPTION */
+#endif /* TOPPERS_excini */
+
+/*
+ *  CPU例外の発生したコンテキストの参照
+ */
+
+/*
+ *  CPU例外発生時のディスパッチ保留状態の参照
+ *
+ *  CPU例外ハンドラ中でdisdspが変化することはないため，CPU例外が発生し
+ *  た時のdisdspを保存しておく必要はない．
+ */
+#ifdef TOPPERS_xsns_dpn
+
+bool_t
+xsns_dpn(void *p_excinf)
+{
+	bool_t	state;
+
+	LOG_XSNS_DPN_ENTER(p_excinf);
+	state = (kerflg && exc_sense_intmask(p_excinf)
+									&& !disdsp) ? false : true;
+	LOG_XSNS_DPN_LEAVE(state);
+	return(state);
+}
+
+#endif /* TOPPERS_xsns_dpn */
+
+/*
+ *  CPU例外発生時のタスク例外処理保留状態の参照
+ *
+ *  CPU例外ハンドラ中でp_runtskとp_runtsk->enatexが変化することはない
+ *  ため，CPU例外が発生した時のp_runtsk->enatexを保存しておく必要はな
+ *  い．
+ */
+#ifdef TOPPERS_xsns_xpn
+
+bool_t
+xsns_xpn(void *p_excinf)
+{
+	bool_t	state;
+
+	LOG_XSNS_XPN_ENTER(p_excinf);
+	state = (kerflg && exc_sense_intmask(p_excinf)
+									&& p_runtsk->enatex) ? false : true;
+	LOG_XSNS_XPN_LEAVE(state);
+	return(state);
+}
+
+#endif /* TOPPERS_xsns_xpn */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/kernel/exception.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/kernel/exception.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/kernel/exception.h	(revision 457)
@@ -0,0 +1,78 @@
+/*
+ *  TOPPERS/ASP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Advanced Standard Profile Kernel
+ * 
+ *  Copyright (C) 2000 by Embedded and Real-Time Systems Laboratory
+ *                              Toyohashi Univ. of Technology, JAPAN
+ *  Copyright (C) 2005-2007 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *		CPU例外管理機能
+ */
+
+#ifndef TOPPERS_EXCEPTION_H
+#define TOPPERS_EXCEPTION_H
+
+#ifndef OMIT_INITIALIZE_EXCEPTION
+
+/*
+ *  CPU例外ハンドラ初期化ブロック
+ */
+typedef struct cpu_exception_handler_initialization_block {
+	EXCNO		excno;			/* CPU例外ハンドラ番号 */
+	ATR			excatr;			/* CPU例外ハンドラ属性 */
+	FP			exc_entry;		/* CPU例外ハンドラの出入口処理の番地 */
+} EXCINIB;
+
+/*
+ *  CPU例外ハンドラ番号の数（kernel_cfg.c）
+ */
+extern const uint_t	tnum_excno;
+
+/*
+ *  CPU例外ハンドラ初期化ブロックのエリア（kernel_cfg.c）
+ */
+extern const EXCINIB	excinib_table[];
+
+#endif /* OMIT_INITIALIZE_EXCEPTION */
+
+/*
+ *  CPU例外ハンドラ管理機能の初期化
+ */
+extern void	initialize_exception(void);
+
+#endif /* TOPPERS_EXCEPTION_H */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/kernel/genoffset.tf
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/kernel/genoffset.tf	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/kernel/genoffset.tf	(revision 457)
@@ -0,0 +1,158 @@
+$ ======================================================================
+$ 
+$   TOPPERS/ASP Kernel
+$       Toyohashi Open Platform for Embedded Real-Time Systems/
+$       Advanced Standard Profile Kernel
+$ 
+$   Copyright (C) 2011-2017 by Embedded and Real-Time Systems Laboratory
+$               Graduate School of Information Science, Nagoya Univ., JAPAN
+$  
+$   上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+$   ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+$   変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+$   (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+$       権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+$       スコード中に含まれていること．
+$   (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+$       用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+$       者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+$       の無保証規定を掲載すること．
+$   (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+$       用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+$       と．
+$     (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+$         作権表示，この利用条件および下記の無保証規定を掲載すること．
+$     (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+$         報告すること．
+$   (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+$       害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+$       また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+$       由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+$       免責すること．
+$  
+$   本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+$   よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+$   に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+$   アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+$   の責任を負わない．
+$ 
+$   $Id$
+$ 
+$ =====================================================================
+
+$ 
+$  SIL_ENDIANの誤定義の検出
+$ 
+$IF SIL_ENDIAN_BIG && SIL_ENDIAN_LITTLE$
+	$ERROR$Both SIL_ENDIAN_BIG and SIL_ENDIAN_LITTLE are defined.$END$
+	$DIE()$
+$END$
+$IF !SIL_ENDIAN_BIG && !SIL_ENDIAN_LITTLE$
+	$ERROR$Neither SIL_ENDIAN_BIG nor SIL_ENDIAN_LITTLE is defined.$END$
+	$DIE()$
+$END$
+
+$ 
+$  #defineディレクティブの生成
+$ 
+$FUNCTION DEFINE$
+	#define $ARGV[1]$$TAB$$FORMAT("%d", +ARGV[2])$$NL$
+$END$
+
+$ 
+$  ビットのサーチ
+$ 
+$FUNCTION SEARCH_BIT$
+	$_val = ARGV[1]$
+	$FOREACH _val_bit RANGE(0,7)$
+		$IF (_val & 1) != 0$
+			$RESULT = _val_bit$
+		$END$
+		$_val = _val >> 1$
+	$END$
+$END$
+
+$ 
+$  ビットフィールドのオフセットとビット位置の定義の生成
+$ 
+$FUNCTION DEFINE_BIT$
+	$label = ARGV[1]$
+	$struct_size = ARGV[2]$
+	$output_size = ARGV[3]$
+
+	$top = SYMBOL(label)$
+	$IF !LENGTH(top)$
+		$ERROR$$FORMAT("label %1% not found", label)$$END$
+	$ELSE$
+		$val = 0$
+		$FOREACH i RANGE(0,struct_size-1)$
+			$tmp_val = PEEK(top + i, 1)$
+			$IF val == 0 && tmp_val != 0$
+				$val = tmp_val$
+				$offset = i$
+			$END$
+		$END$
+
+		$IF val == 0$
+			$ERROR$$FORMAT("bit not found in %1%", ARGV[1])$$END$
+		$ELSE$
+			$val_bit = SEARCH_BIT(val)$
+			$RESULT = {}$
+			$IF EQ(output_size, "W")$
+				$IF SIL_ENDIAN_BIG$
+					$val_bit = val_bit + 24 - ((offset & 0x03) << 3)$
+				$ELSE$
+					$val_bit = val_bit + ((offset & 0x03) << 3)$
+				$END$
+				$offset = offset & ~0x03$
+			$ELSE$$IF EQ(output_size, "H")$
+				$IF SIL_ENDIAN_BIG$
+					$val_bit = val_bit + 8 - ((offset & 0x01) << 3)$
+				$ELSE$
+					$val_bit = val_bit + ((offset & 0x01) << 3)$
+				$END$
+				$offset = offset & ~0x01$
+			$END$$END$
+		$END$
+
+		#define $label$$TAB$$FORMAT("%d", +offset)$$NL$
+		#define $label$_bit$TAB$$FORMAT("%d", +val_bit)$$NL$
+		#define $label$_mask$TAB$$FORMAT("0x%x", 1 << val_bit)$$NL$
+	$END$
+$END$
+
+$ 
+$  バイト配置のチェック
+$ 
+$FUNCTION MAGIC_CHECK$
+	$size = ARGV[1]$
+	$check = ARGV[2]$
+
+	$label = FORMAT("MAGIC_%d", +size)$
+	$top = SYMBOL(label)$
+	$IF !LENGTH(top)$
+		$ERROR$$FORMAT("label %1% not found", label)$$END$
+	$ELSE$
+		$FOREACH offset RANGE(1,size)$
+			$IF SIL_ENDIAN_BIG$
+				$val = PEEK(top + offset - 1, 1)$
+			$ELSE$
+				$val = PEEK(top + size - offset, 1)$
+			$END$
+			$IF val != AT(check, offset - 1)$
+				$ERROR$$FORMAT("value check of %1% failed", label)$$END$
+			$END$
+		$END$
+	$END$
+$END$
+
+$MAGIC_CHECK(1, { 0x12 })$
+$MAGIC_CHECK(2, { 0x12, 0x34 })$
+$MAGIC_CHECK(4, { 0x12, 0x34, 0x56, 0x78 })$
+
+$ 
+$  ファイルヘッダの生成
+$ 
+$FILE "offset.h"$
+/* offset.h */$NL$
+$NL$
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/kernel/interrupt.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/kernel/interrupt.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/kernel/interrupt.c	(revision 457)
@@ -0,0 +1,494 @@
+/*
+ *  TOPPERS/ASP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Advanced Standard Profile Kernel
+ * 
+ *  Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
+ *                              Toyohashi Univ. of Technology, JAPAN
+ *  Copyright (C) 2005-2012 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *		割込み管理機能
+ */
+
+#include "kernel_impl.h"
+#include "check.h"
+#include "task.h"
+#include "interrupt.h"
+
+/*
+ *  トレースログマクロのデフォルト定義
+ */
+#ifndef LOG_ISR_ENTER
+#define LOG_ISR_ENTER(intno)
+#endif /* LOG_ISR_ENTER */
+
+#ifndef LOG_ISR_LEAVE
+#define LOG_ISR_LEAVE(intno)
+#endif /* LOG_ISR_LEAVE */
+
+#ifndef LOG_ACRE_ISR_ENTER
+#define LOG_ACRE_ISR_ENTER(pk_cisr)
+#endif /* LOG_ACRE_ISR_ENTER */
+
+#ifndef LOG_ACRE_ISR_LEAVE
+#define LOG_ACRE_ISR_LEAVE(ercd)
+#endif /* LOG_ACRE_ISR_LEAVE */
+
+#ifndef LOG_DEL_ISR_ENTER
+#define LOG_DEL_ISR_ENTER(isrid)
+#endif /* LOG_DEL_ISR_ENTER */
+
+#ifndef LOG_DEL_ISR_LEAVE
+#define LOG_DEL_ISR_LEAVE(ercd)
+#endif /* LOG_DEL_ISR_LEAVE */
+
+#ifndef LOG_DIS_INT_ENTER
+#define LOG_DIS_INT_ENTER(intno)
+#endif /* LOG_DIS_INT_ENTER */
+
+#ifndef LOG_DIS_INT_LEAVE
+#define LOG_DIS_INT_LEAVE(ercd)
+#endif /* LOG_DIS_INT_LEAVE */
+
+#ifndef LOG_ENA_INT_ENTER
+#define LOG_ENA_INT_ENTER(intno)
+#endif /* LOG_ENA_INT_ENTER */
+
+#ifndef LOG_ENA_INT_LEAVE
+#define LOG_ENA_INT_LEAVE(ercd)
+#endif /* LOG_ENA_INT_LEAVE */
+
+#ifndef LOG_CHG_IPM_ENTER
+#define LOG_CHG_IPM_ENTER(intpri)
+#endif /* LOG_CHG_IPM_ENTER */
+
+#ifndef LOG_CHG_IPM_LEAVE
+#define LOG_CHG_IPM_LEAVE(ercd)
+#endif /* LOG_CHG_IPM_LEAVE */
+
+#ifndef LOG_GET_IPM_ENTER
+#define LOG_GET_IPM_ENTER(p_intpri)
+#endif /* LOG_GET_IPM_ENTER */
+
+#ifndef LOG_GET_IPM_LEAVE
+#define LOG_GET_IPM_LEAVE(ercd, intpri)
+#endif /* LOG_GET_IPM_LEAVE */
+
+/*
+ *  割込みサービスルーチンの数
+ */
+#define tnum_isr	((uint_t)(tmax_isrid - TMIN_ISRID + 1) + tnum_sisr)
+
+/*
+ *  割込みサービスルーチンIDから割込みサービスルーチン管理ブロックを取
+ *  り出すためのマクロ
+ */
+#define INDEX_ISR(isrid)	((uint_t)((isrid) - TMIN_ISRID) + tnum_sisr)
+#define get_isrcb(isrid)	(&(isrcb_table[INDEX_ISR(isrid)]))
+
+/*
+ *  割込みサービスルーチンキューへの登録
+ */
+Inline void
+enqueue_isr(QUEUE *p_isr_queue, ISRCB *p_isrcb)
+{
+	QUEUE	*p_entry;
+	PRI		isrpri = p_isrcb->p_isrinib->isrpri;
+
+	for (p_entry = p_isr_queue->p_next; p_entry != p_isr_queue;
+											p_entry = p_entry->p_next) {
+		if (isrpri < ((ISRCB *) p_entry)->p_isrinib->isrpri) {
+			break;
+		}
+	}
+	queue_insert_prev(p_entry, &(p_isrcb->isr_queue));
+}
+
+#ifdef TOPPERS_isrini
+
+/*
+ *  使用していない割込みサービスルーチン管理ブロックのリスト
+ */
+QUEUE	free_isrcb;
+
+/* 
+ *  割込みサービスルーチン機能の初期化
+ */
+void
+initialize_isr(void)
+{
+	uint_t	i, j;
+	ISRCB	*p_isrcb;
+	ISRINIB	*p_isrinib;
+
+	for (i = 0; i < tnum_isr_queue; i++) {
+		queue_initialize(&(isr_queue_table[i]));
+	}
+	for (i = 0; i < tnum_sisr; i++) {
+		p_isrcb = &(isrcb_table[i]);
+		p_isrcb->p_isrinib = &(sisrinib_table[i]);
+		enqueue_isr(p_isrcb->p_isrinib->p_isr_queue, p_isrcb);
+	}
+	queue_initialize(&free_isrcb);
+	for (j = 0; i < tnum_isr; i++, j++) {
+		p_isrcb = &(isrcb_table[i]);
+		p_isrinib = &(aisrinib_table[j]);
+		p_isrinib->isratr = TA_NOEXS;
+		p_isrcb->p_isrinib = ((const ISRINIB *) p_isrinib);
+		queue_insert_prev(&free_isrcb, &(p_isrcb->isr_queue));
+	}
+}
+
+#endif /* TOPPERS_isrini */
+
+/*
+ *  割込みサービスルーチンの呼出し
+ */
+#ifdef TOPPERS_isrcal
+
+void
+call_isr(QUEUE *p_isr_queue)
+{
+	QUEUE	*p_queue;
+	ISRINIB	*p_isrinib;
+	PRI		saved_ipm;
+
+	saved_ipm = i_get_ipm();
+	for (p_queue = p_isr_queue->p_next; p_queue != p_isr_queue;
+											p_queue = p_queue->p_next) {
+		p_isrinib = (ISRINIB *)(((ISRCB *) p_queue)->p_isrinib);
+		LOG_ISR_ENTER(p_isrinib->intno);
+		(*(p_isrinib->isr))(p_isrinib->exinf);
+		LOG_ISR_LEAVE(p_isrinib->intno);
+
+		if (p_queue->p_next != p_isr_queue) {
+			/* ISRの呼出し前の状態に戻す */
+			if (i_sense_lock()) {
+				i_unlock_cpu();
+			}
+			i_set_ipm(saved_ipm);
+		}
+	}
+}
+
+#endif /* TOPPERS_isrcal */
+
+/*
+ *  割込みサービスルーチン呼出しキューの検索
+ */
+Inline QUEUE *
+search_isr_queue(INTNO intno)
+{
+	int_t	left, right, i;
+
+	if (tnum_isr_queue == 0) {
+		return(NULL);
+	}
+
+	left = 0;
+	right = tnum_isr_queue - 1;
+	while (left < right) {
+		i = (left + right + 1) / 2;
+		if (intno < isr_queue_list[i].intno) {
+			right = i - 1;
+		}
+		else {
+			left = i;
+		}
+	}
+	if (isr_queue_list[left].intno == intno) {
+		return(isr_queue_list[left].p_isr_queue);
+	}
+	else {
+		return(NULL);
+	}
+}
+
+/*
+ *  割込みサービスルーチンの生成
+ */
+#ifdef TOPPERS_acre_isr
+
+ER_UINT
+acre_isr(const T_CISR *pk_cisr)
+{
+	ISRCB	*p_isrcb;
+	ISRINIB	*p_isrinib;
+	QUEUE	*p_isr_queue;
+	ER		ercd;
+
+	LOG_ACRE_ISR_ENTER(pk_cisr);
+	CHECK_TSKCTX_UNL();
+	CHECK_RSATR(pk_cisr->isratr, TARGET_ISRATR);
+	CHECK_INTNO_CREISR(pk_cisr->intno);
+	CHECK_ALIGN_FUNC(pk_cisr->isr);
+	CHECK_NONNULL_FUNC(pk_cisr->isr);
+	CHECK_ISRPRI(pk_cisr->isrpri);
+
+	p_isr_queue = search_isr_queue(pk_cisr->intno);
+	CHECK_OBJ(p_isr_queue != NULL);
+
+	t_lock_cpu();
+	if (tnum_isr == 0 || queue_empty(&free_isrcb)) {
+		ercd = E_NOID;
+	}
+	else {
+		p_isrcb = ((ISRCB *) queue_delete_next(&free_isrcb));
+		p_isrinib = (ISRINIB *)(p_isrcb->p_isrinib);
+		p_isrinib->isratr = pk_cisr->isratr;
+		p_isrinib->exinf = pk_cisr->exinf;
+		p_isrinib->intno = pk_cisr->intno;
+		p_isrinib->p_isr_queue = p_isr_queue;
+		p_isrinib->isr = pk_cisr->isr;
+		p_isrinib->isrpri = pk_cisr->isrpri;
+		enqueue_isr(p_isr_queue, p_isrcb);
+		ercd = ISRID(p_isrcb);
+	}
+	t_unlock_cpu();
+
+  error_exit:
+	LOG_ACRE_ISR_LEAVE(ercd);
+	return(ercd);
+}
+
+#endif /* TOPPERS_acre_isr */
+
+/*
+ *  割込みサービスルーチンの削除
+ */
+#ifdef TOPPERS_del_isr
+
+ER
+del_isr(ID isrid)
+{
+	ISRCB	*p_isrcb;
+	ISRINIB	*p_isrinib;
+	ER		ercd;
+
+	LOG_DEL_ISR_ENTER(isrid);
+	CHECK_TSKCTX_UNL();
+	CHECK_ISRID(isrid);
+	p_isrcb = get_isrcb(isrid);
+
+	t_lock_cpu();
+	if (p_isrcb->p_isrinib->isratr == TA_NOEXS) {
+		ercd = E_NOEXS;
+	}
+	else {
+		queue_delete(&(p_isrcb->isr_queue));
+		p_isrinib = (ISRINIB *)(p_isrcb->p_isrinib);
+		p_isrinib->isratr = TA_NOEXS;
+		queue_insert_prev(&free_isrcb, &(p_isrcb->isr_queue));
+		ercd = E_OK;
+	}
+	t_unlock_cpu();
+
+  error_exit:
+	LOG_DEL_ISR_LEAVE(ercd);
+	return(ercd);
+}
+
+#endif /* TOPPERS_del_isr */
+
+/* 
+ *  割込み管理機能の初期化
+ */
+#ifdef TOPPERS_intini
+#ifndef OMIT_INITIALIZE_INTERRUPT
+
+void
+initialize_interrupt(void)
+{
+	uint_t			i;
+	const INHINIB	*p_inhinib;
+	const INTINIB	*p_intinib;
+
+	for (i = 0; i < tnum_inhno; i++) {
+		p_inhinib = &(inhinib_table[i]);
+		x_define_inh(p_inhinib->inhno, p_inhinib->int_entry);
+	}
+	for (i = 0; i < tnum_intno; i++) {
+		p_intinib = &(intinib_table[i]);
+		x_config_int(p_intinib->intno, p_intinib->intatr, p_intinib->intpri);
+	}
+}
+
+#endif /* OMIT_INITIALIZE_INTERRUPT */
+#endif /* TOPPERS_intini */
+
+/*
+ *  割込みの禁止
+ */
+#ifdef TOPPERS_dis_int
+#ifdef TOPPERS_SUPPORT_DIS_INT
+
+ER
+dis_int(INTNO intno)
+{
+	bool_t	locked;
+	ER		ercd;
+
+	LOG_DIS_INT_ENTER(intno);
+	CHECK_TSKCTX();
+	CHECK_INTNO_DISINT(intno);
+
+	locked = t_sense_lock();
+	if (!locked) {
+		t_lock_cpu();
+	}
+	if (t_disable_int(intno)) {
+		ercd = E_OK;
+	}
+	else {
+		ercd = E_OBJ;
+	}
+	if (!locked) {
+		t_unlock_cpu();
+	}
+
+  error_exit:
+	LOG_DIS_INT_LEAVE(ercd);
+	return(ercd);
+}
+
+#endif /* TOPPERS_SUPPORT_DIS_INT */
+#endif /* TOPPERS_dis_int */
+
+/*
+ *  割込みの許可
+ */
+#ifdef TOPPERS_ena_int
+#ifdef TOPPERS_SUPPORT_ENA_INT
+
+ER
+ena_int(INTNO intno)
+{
+	bool_t	locked;
+	ER		ercd;
+
+	LOG_ENA_INT_ENTER(intno);
+	CHECK_TSKCTX();
+	CHECK_INTNO_DISINT(intno);
+
+	locked = t_sense_lock();
+	if (!locked) {
+		t_lock_cpu();
+	}
+	if (t_enable_int(intno)) {
+		ercd = E_OK;
+	}
+	else {
+		ercd = E_OBJ;
+	}
+	if (!locked) {
+		t_unlock_cpu();
+	}
+
+  error_exit:
+	LOG_ENA_INT_LEAVE(ercd);
+	return(ercd);
+}
+
+#endif /* TOPPERS_SUPPORT_ENA_INT */
+#endif /* TOPPERS_ena_int */
+
+/*
+ *  割込み優先度マスクの変更
+ */
+#ifdef TOPPERS_chg_ipm
+
+ER
+chg_ipm(PRI intpri)
+{
+	ER		ercd;
+
+	LOG_CHG_IPM_ENTER(intpri);
+	CHECK_TSKCTX_UNL();
+	CHECK_INTPRI_CHGIPM(intpri);
+
+	t_lock_cpu();
+	t_set_ipm(intpri);
+	if (intpri == TIPM_ENAALL) {
+		ipmflg = true;
+		if (!disdsp) {
+			dspflg = true;
+			if (p_runtsk != p_schedtsk) {
+				dispatch();
+			}
+		}
+		if (p_runtsk->enatex && p_runtsk->texptn != 0U) {
+			call_texrtn();
+		}
+	}
+	else {
+		ipmflg = false;
+		dspflg = false;
+	}
+	ercd = E_OK;
+	t_unlock_cpu();
+
+  error_exit:
+	LOG_CHG_IPM_LEAVE(ercd);
+	return(ercd);
+}
+
+#endif /* TOPPERS_chg_ipm */
+
+/*
+ *  割込み優先度マスクの参照
+ */
+#ifdef TOPPERS_get_ipm
+
+ER
+get_ipm(PRI *p_intpri)
+{
+	ER		ercd;
+
+	LOG_GET_IPM_ENTER(p_intpri);
+	CHECK_TSKCTX_UNL();
+
+	t_lock_cpu();
+	*p_intpri = t_get_ipm();
+	ercd = E_OK;
+	t_unlock_cpu();
+
+  error_exit:
+	LOG_GET_IPM_LEAVE(ercd, *p_intpri);
+	return(ercd);
+}
+
+#endif /* TOPPERS_get_ipm */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/kernel/interrupt.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/kernel/interrupt.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/kernel/interrupt.h	(revision 457)
@@ -0,0 +1,186 @@
+/*
+ *  TOPPERS/ASP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Advanced Standard Profile Kernel
+ * 
+ *  Copyright (C) 2000 by Embedded and Real-Time Systems Laboratory
+ *                              Toyohashi Univ. of Technology, JAPAN
+ *  Copyright (C) 2005-2010 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *		割込み管理機能
+ */
+
+#ifndef TOPPERS_INTERRUPT_H
+#define TOPPERS_INTERRUPT_H
+
+#include <queue.h>
+
+/*
+ *  割込みサービスルーチン初期化ブロック
+ */
+typedef struct isr_initialization_block {
+	ATR			isratr;			/* 割込みサービスルーチン属性 */
+	intptr_t	exinf;			/* 割込みサービスルーチンの拡張情報 */
+	INTNO		intno;			/* 割込みサービスルーチンを登録する割込み番号 */
+	QUEUE		*p_isr_queue;	/* 登録先割込みサービスルーチンキューの番地 */
+	ISR			isr;			/* 割込みサービスルーチンの先頭番地 */
+	PRI			isrpri;			/* 割込みサービスルーチン優先度 */
+} ISRINIB;
+
+/*
+ *  割込みサービスルーチン管理ブロック
+ */
+typedef struct isr_control_block {
+	QUEUE		isr_queue;		/* 割込みサービスルーチン呼出しキュー */
+	const ISRINIB *p_isrinib;	/* 初期化ブロックへのポインタ */
+} ISRCB;
+
+/*
+ *  割込みサービスルーチン呼出しキューを検索するためのデータ構造
+ */
+typedef struct {
+	INTNO		intno;			/* 割込み番号 */
+	QUEUE		*p_isr_queue;	/* 割込みサービスルーチン呼出しキュー */
+} ISR_ENTRY;
+
+/*
+ *  割込みサービスルーチンキューのエントリ数（kernel_cfg.c）
+ */
+extern const uint_t tnum_isr_queue;
+
+/*
+ *  割込みサービスルーチンキューリスト（kernel_cfg.c）
+ */
+extern const ISR_ENTRY isr_queue_list[];
+
+/*
+ *  割込みサービスルーチンキューのエリア（kernel_cfg.c）
+ */
+extern QUEUE isr_queue_table[];
+
+/*
+ *  使用していない割込みサービスルーチン管理ブロックのリスト
+ */
+extern QUEUE	free_isrcb;
+
+/*
+ *  割込みサービスルーチンIDの最大値（kernel_cfg.c）
+ *
+ *  静的に生成される割込みサービスルーチンはID番号を持たないため，
+ *  tmax_isridは動的に生成される割込みサービスルーチンのID番号の最大値
+ *  である．静的に生成される割込みサービスルーチンの数は，tnum_sisrに保
+ *  持する．
+ */
+extern const ID		tmax_isrid;
+extern const uint_t	tnum_sisr;
+
+/*
+ *  割込みサービスルーチン初期化ブロックのエリア（kernel_cfg.c）
+ */
+extern const ISRINIB	sisrinib_table[];
+extern ISRINIB			aisrinib_table[];
+
+/*
+ *  割込みサービスルーチン管理ブロックのエリア（kernel_cfg.c）
+ */
+extern ISRCB	isrcb_table[];
+
+/*
+ *  割込みサービスルーチン管理ブロックから割込みサービスルーチンIDを取
+ *  り出すためのマクロ
+ */
+#define	ISRID(p_isrcb)	((ID)(((p_isrcb) - isrcb_table) \
+										- tnum_sisr + TMIN_ISRID))
+
+/*
+ *  割込みサービスルーチン機能の初期化
+ */
+extern void initialize_isr(void);
+
+/*
+ *  割込みサービスルーチンの呼出し
+ */
+extern void call_isr(QUEUE *p_isr_queue);
+
+#ifndef OMIT_INITIALIZE_INTERRUPT
+
+/*
+ *  割込みハンドラ初期化ブロック
+ */
+typedef struct interrupt_handler_initialization_block {
+	INHNO		inhno;			/* 割込みハンドラ番号 */
+	ATR			inhatr;			/* 割込みハンドラ属性 */
+	FP			int_entry;		/* 割込みハンドラの出入口処理の番地 */
+} INHINIB;
+
+/*
+ *  割込み要求ライン初期化ブロック
+ */
+typedef struct interrupt_request_initialization_block {
+	INTNO		intno;			/* 割込み番号 */
+	ATR			intatr;			/* 割込み属性 */
+	PRI			intpri;			/* 割込み優先度 */
+} INTINIB;
+
+/*
+ *  割込みハンドラ番号の数（kernel_cfg.c）
+ */
+extern const uint_t	tnum_inhno;
+
+/*
+ *  割込みハンドラ初期化ブロックのエリア（kernel_cfg.c）
+ */
+extern const INHINIB	inhinib_table[];
+
+/*
+ *  割込み要求ラインの数（kernel_cfg.c）
+ */
+extern const uint_t	tnum_intno;
+
+/*
+ *  割込み要求ライン初期化ブロックのエリア（kernel_cfg.c）
+ */
+extern const INTINIB	intinib_table[];
+
+#endif /* OMIT_INITIALIZE_INTERRUPT */
+
+/*
+ *  割込み管理機能の初期化
+ */
+extern void	initialize_interrupt(void);
+
+#endif /* TOPPERS_INTERRUPT_H */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/kernel/kernel.tf
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/kernel/kernel.tf	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/kernel/kernel.tf	(revision 457)
@@ -0,0 +1,1500 @@
+$ ======================================================================
+$ 
+$   TOPPERS/ASP Kernel
+$       Toyohashi Open Platform for Embedded Real-Time Systems/
+$       Advanced Standard Profile Kernel
+$ 
+$   Copyright (C) 2007 by TAKAGI Nobuhisa
+$   Copyright (C) 2007-2015 by Embedded and Real-Time Systems Laboratory
+$               Graduate School of Information Science, Nagoya Univ., JAPAN
+$  
+$   上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+$   ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+$   変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+$   (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+$       権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+$       スコード中に含まれていること．
+$   (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+$       用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+$       者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+$       の無保証規定を掲載すること．
+$   (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+$       用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+$       と．
+$     (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+$         作権表示，この利用条件および下記の無保証規定を掲載すること．
+$     (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+$         報告すること．
+$   (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+$       害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+$       また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+$       由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+$       免責すること．
+$  
+$   本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+$   よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+$   に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+$   アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+$   の責任を負わない．
+$ 
+$   $Id$
+$  
+$ =====================================================================
+
+$ =====================================================================
+$ AID_YYYの処理
+$ =====================================================================
+
+$num_atskid = 0$
+$FOREACH i ATSK.ORDER_LIST$
+$	// notskが負の場合（E_PAR）
+	$IF ATSK.NOTSK[i] < 0$
+		$ERROR ATSK.TEXT_LINE[i]$E_PAR: $FORMAT(_("illegal %1% `%2%\' in %3%"), "notsk", ATSK.NOTSK[i], "AID_TSK")$$END$
+	$END$
+	$num_atskid = num_atskid + ATSK.NOTSK[i]$
+$END$
+$num_tskid = LENGTH(TSK.ID_LIST) + num_atskid$
+
+$num_asemid = 0$
+$FOREACH i ASEM.ORDER_LIST$
+$	// nosemが負の場合（E_PAR）
+	$IF ASEM.NOSEM[i] < 0$
+		$ERROR ASEM.TEXT_LINE[i]$E_PAR: $FORMAT(_("illegal %1% `%2%\' in %3%"), "nosem", ASEM.NOSEM[i], "AID_SEM")$$END$
+	$END$
+	$num_asemid = num_asemid + ASEM.NOSEM[i]$
+$END$
+$num_semid = LENGTH(SEM.ID_LIST) + num_asemid$
+
+$num_aflgid = 0$
+$FOREACH i AFLG.ORDER_LIST$
+$	// noflgが負の場合（E_PAR）
+	$IF AFLG.NOFLG[i] < 0$
+		$ERROR AFLG.TEXT_LINE[i]$E_PAR: $FORMAT(_("illegal %1% `%2%\' in %3%"), "noflg", AFLG.NOFLG[i], "AID_FLG")$$END$
+	$END$
+	$num_aflgid = num_aflgid + AFLG.NOFLG[i]$
+$END$
+$num_flgid = LENGTH(FLG.ID_LIST) + num_aflgid$
+
+$num_adtqid = 0$
+$FOREACH i ADTQ.ORDER_LIST$
+$	// nodtqが負の場合（E_PAR）
+	$IF ADTQ.NODTQ[i] < 0$
+		$ERROR ADTQ.TEXT_LINE[i]$E_PAR: $FORMAT(_("illegal %1% `%2%\' in %3%"), "nodtq", ADTQ.NODTQ[i], "AID_DTQ")$$END$
+	$END$
+	$num_adtqid = num_adtqid + ADTQ.NODTQ[i]$
+$END$
+$num_dtqid = LENGTH(DTQ.ID_LIST) + num_adtqid$
+
+$num_apdqid = 0$
+$FOREACH i APDQ.ORDER_LIST$
+$	// nopdqが負の場合（E_PAR）
+	$IF APDQ.NOPDQ[i] < 0$
+		$ERROR APDQ.TEXT_LINE[i]$E_PAR: $FORMAT(_("illegal %1% `%2%\' in %3%"), "nopdq", APDQ.NOPDQ[i], "AID_PDQ")$$END$
+	$END$
+	$num_apdqid = num_apdqid + APDQ.NOPDQ[i]$
+$END$
+$num_pdqid = LENGTH(PDQ.ID_LIST) + num_apdqid$
+
+$num_ambxid = 0$
+$FOREACH i AMBX.ORDER_LIST$
+$	// nombxが負の場合（E_PAR）
+	$IF AMBX.NOMBX[i] < 0$
+		$ERROR AMBX.TEXT_LINE[i]$E_PAR: $FORMAT(_("illegal %1% `%2%\' in %3%"), "nombx", AMBX.NOMBX[i], "AID_MBX")$$END$
+	$END$
+	$num_ambxid = num_ambxid + AMBX.NOMBX[i]$
+$END$
+$num_mbxid = LENGTH(MBX.ID_LIST) + num_ambxid$
+
+$num_amtxid = 0$
+$FOREACH i AMTX.ORDER_LIST$
+$	// nomtxが負の場合（E_PAR）
+	$IF AMTX.NOMTX[i] < 0$
+		$ERROR AMTX.TEXT_LINE[i]$E_PAR: $FORMAT(_("illegal %1% `%2%\' in %3%"), "nomtx", AMTX.NOMTX[i], "AID_MTX")$$END$
+	$END$
+	$num_amtxid = num_amtxid + AMTX.NOMTX[i]$
+$END$
+$num_mtxid = LENGTH(MTX.ID_LIST) + num_amtxid$
+
+$num_ampfid = 0$
+$FOREACH i AMPF.ORDER_LIST$
+$	// nompfが負の場合（E_PAR）
+	$IF AMPF.NOMPF[i] < 0$
+		$ERROR AMPF.TEXT_LINE[i]$E_PAR: $FORMAT(_("illegal %1% `%2%\' in %3%"), "nompf", AMPF.NOMPF[i], "AID_MPF")$$END$
+	$END$
+	$num_ampfid = num_ampfid + AMPF.NOMPF[i]$
+$END$
+$num_mpfid = LENGTH(MPF.ID_LIST) + num_ampfid$
+
+$num_acycid = 0$
+$FOREACH i ACYC.ORDER_LIST$
+$	// nocycが負の場合（E_PAR）
+	$IF ACYC.NOCYC[i] < 0$
+		$ERROR ACYC.TEXT_LINE[i]$E_PAR: $FORMAT(_("illegal %1% `%2%\' in %3%"), "nocyc", ACYC.NOCYC[i], "AID_CYC")$$END$
+	$END$
+	$num_acycid = num_acycid + ACYC.NOCYC[i]$
+$END$
+$num_cycid = LENGTH(CYC.ID_LIST) + num_acycid$
+
+$num_aalmid = 0$
+$FOREACH i AALM.ORDER_LIST$
+$	// noalmが負の場合（E_PAR）
+	$IF AALM.NOALM[i] < 0$
+		$ERROR AALM.TEXT_LINE[i]$E_PAR: $FORMAT(_("illegal %1% `%2%\' in %3%"), "noalm", AALM.NOALM[i], "AID_ALM")$$END$
+	$END$
+	$num_aalmid = num_aalmid + AALM.NOALM[i]$
+$END$
+$num_almid = LENGTH(ALM.ID_LIST) + num_aalmid$
+
+$num_aisrid = 0$
+$FOREACH i AISR.ORDER_LIST$
+$	// noisrが負の場合（E_PAR）
+	$IF AISR.NOISR[i] < 0$
+		$ERROR AISR.TEXT_LINE[i]$E_PAR: $FORMAT(_("illegal %1% `%2%\' in %3%"), "noisr", AISR.NOISR[i], "AID_ISR")$$END$
+	$END$
+	$num_aisrid = num_aisrid + AISR.NOISR[i]$
+$END$
+$num_isrid = num_aisrid$
+$num_isr = LENGTH(ISR.ORDER_LIST) + num_aisrid$
+
+$ =====================================================================
+$ kernel_cfg.hの生成
+$ =====================================================================
+
+$FILE "kernel_cfg.h"$
+/* kernel_cfg.h */$NL$
+#ifndef TOPPERS_KERNEL_CFG_H$NL$
+#define TOPPERS_KERNEL_CFG_H$NL$
+$NL$
+#define TNUM_TSKID	$num_tskid$$NL$
+#define TNUM_SEMID	$num_semid$$NL$
+#define TNUM_FLGID	$num_flgid$$NL$
+#define TNUM_DTQID	$num_dtqid$$NL$
+#define TNUM_PDQID	$num_pdqid$$NL$
+#define TNUM_MBXID	$num_mbxid$$NL$
+#define TNUM_MTXID	$num_mtxid$$NL$
+#define TNUM_MPFID	$num_mpfid$$NL$
+#define TNUM_CYCID	$num_cycid$$NL$
+#define TNUM_ALMID	$num_almid$$NL$
+#define TNUM_ISRID	$num_isrid$$NL$
+$NL$
+$FOREACH id TSK.ID_LIST$
+	#define $id$	$+id$$NL$
+$END$
+$FOREACH id SEM.ID_LIST$
+	#define $id$	$+id$$NL$
+$END$
+$FOREACH id FLG.ID_LIST$
+	#define $id$	$+id$$NL$
+$END$
+$FOREACH id DTQ.ID_LIST$
+	#define $id$	$+id$$NL$
+$END$
+$FOREACH id PDQ.ID_LIST$
+	#define $id$	$+id$$NL$
+$END$
+$FOREACH id MBX.ID_LIST$
+	#define $id$	$+id$$NL$
+$END$
+$FOREACH id MTX.ID_LIST$
+	#define $id$	$+id$$NL$
+$END$
+$FOREACH id MPF.ID_LIST$
+	#define $id$	$+id$$NL$
+$END$
+$FOREACH id CYC.ID_LIST$
+	#define $id$	$+id$$NL$
+$END$
+$FOREACH id ALM.ID_LIST$
+	#define $id$	$+id$$NL$
+$END$
+$NL$
+#endif /* TOPPERS_KERNEL_CFG_H */$NL$
+
+$ =====================================================================
+$ kernel_cfg.cの生成
+$ =====================================================================
+
+$FILE "kernel_cfg.c"$
+/* kernel_cfg.c */$NL$
+#include "kernel/kernel_int.h"$NL$
+#include "kernel_cfg.h"$NL$
+$NL$
+#if TKERNEL_PRID != 0x07u$NL$
+#error The kernel does not match this configuration file.$NL$
+#endif$NL$
+$NL$
+
+$ 
+$  インクルードディレクティブ（#include）
+$ 
+/*$NL$
+$SPC$*  Include Directives (#include)$NL$
+$SPC$*/$NL$
+$NL$
+$INCLUDES$
+$NL$
+
+$ 
+$  オブジェクトのID番号を保持する変数
+$ 
+$IF USE_EXTERNAL_ID$
+	/*$NL$
+	$SPC$*  Variables for Object ID$NL$
+	$SPC$*/$NL$
+	$NL$
+	$FOREACH id TSK.ID_LIST$
+		const ID $id$_id$SPC$=$SPC$$+id$;$NL$
+	$END$
+	$FOREACH id SEM.ID_LIST$
+		const ID $id$_id$SPC$=$SPC$$+id$;$NL$
+	$END$
+	$FOREACH id FLG.ID_LIST$
+		const ID $id$_id$SPC$=$SPC$$+id$;$NL$
+	$END$
+	$FOREACH id DTQ.ID_LIST$
+		const ID $id$_id$SPC$=$SPC$$+id$;$NL$
+	$END$
+	$FOREACH id PDQ.ID_LIST$
+		const ID $id$_id$SPC$=$SPC$$+id$;$NL$
+	$END$
+	$FOREACH id MBX.ID_LIST$
+		const ID $id$_id$SPC$=$SPC$$+id$;$NL$
+	$END$
+	$FOREACH id MTX.ID_LIST$
+		const ID $id$_id$SPC$=$SPC$$+id$;$NL$
+	$END$
+	$FOREACH id MPF.ID_LIST$
+		const ID $id$_id$SPC$=$SPC$$+id$;$NL$
+	$END$
+	$FOREACH id CYC.ID_LIST$
+		const ID $id$_id$SPC$=$SPC$$+id$;$NL$
+	$END$
+	$FOREACH id ALM.ID_LIST$
+		const ID $id$_id$SPC$=$SPC$$+id$;$NL$
+	$END$
+$END$
+
+$
+$  スタック領域の確保関数
+$
+$IF !ISFUNCTION("ALLOC_STACK")$
+$FUNCTION ALLOC_STACK$
+$	// 大きい方に丸めたサイズで確保する
+	static STK_T $ARGV[1]$[COUNT_STK_T($ARGV[2]$)];$NL$
+	$RESULT = FORMAT("ROUND_STK_T(%1%)", ARGV[2])$
+$END$
+$END$
+
+$ 
+$  タスク
+$ 
+/*$NL$
+$SPC$*  Task Management Functions$NL$
+$SPC$*/$NL$
+$NL$
+
+$ 静的に生成されたタスクが1個以上存在することのチェック
+$IF !LENGTH(TSK.ID_LIST)$
+	$ERROR$$FORMAT(_("no task is registered"))$$END$
+$END$
+
+$ 静的に生成されたタスクの数
+#define TNUM_STSKID	$LENGTH(TSK.ID_LIST)$$NL$
+$NL$
+
+$ タスクID番号の最大値
+const ID _kernel_tmax_tskid = (TMIN_TSKID + TNUM_TSKID - 1);$NL$
+const ID _kernel_tmax_stskid = (TMIN_TSKID + TNUM_STSKID - 1);$NL$
+$NL$
+
+$ エラーチェック
+$FOREACH tskid TSK.ID_LIST$
+$	// tskatrが（［TA_ACT］）でない場合（E_RSATR）
+	$IF (TSK.TSKATR[tskid] & ~(TA_ACT|TARGET_TSKATR)) != 0$
+		$ERROR TSK.TEXT_LINE[tskid]$E_RSATR: $FORMAT(_("illegal %1% `%2%\' of `%3%\' in %4%"), "tskatr", TSK.TSKATR[tskid], tskid, "CRE_TSK")$$END$
+	$END$
+
+$	// (TMIN_TPRI <= itskpri && itskpri <= TMAX_TPRI)でない場合（E_PAR）
+	$IF !(TMIN_TPRI <= TSK.ITSKPRI[tskid] && TSK.ITSKPRI[tskid] <= TMAX_TPRI)$
+		$ERROR TSK.TEXT_LINE[tskid]$E_PAR: $FORMAT(_("illegal %1% `%2%\' of `%3%\' in %4%"), "itskpri", TSK.ITSKPRI[tskid], tskid, "CRE_TSK")$$END$
+	$END$
+
+$ 	// texatrが（TA_NULL）でない場合（E_RSATR）
+	$IF LENGTH(TSK.TEXATR[tskid]) && TSK.TEXATR[tskid] != 0$
+		$ERROR DEF_TEX.TEXT_LINE[tskid]$E_RSATR: $FORMAT(_("illegal %1% `%2%\' of `%3%\' in %4%"), "texatr", TSK.TEXATR[tskid], tskid, "DEF_TEX")$$END$
+	$END$
+$END$
+
+$ スタック領域の生成とそれに関するエラーチェック
+$FOREACH tskid TSK.ID_LIST$
+$	// stkszが0以下か，ターゲット定義の最小値（TARGET_MIN_STKSZ）よりも
+$	// 小さい場合（E_PAR）
+	$IF TSK.STKSZ[tskid] <= 0 || (TARGET_MIN_STKSZ
+									&& TSK.STKSZ[tskid] < TARGET_MIN_STKSZ)$
+		$ERROR TSK.TEXT_LINE[tskid]$E_PAR: $FORMAT(_("too small %1% `%2%\' of `%3%\' in %4%"), "stksz", TSK.STKSZ[tskid], tskid, "CRE_TSK")$$END$
+	$END$
+
+$ 	// stkszがスタック領域のサイズとして正しくない場合（E_PAR）
+	$IF !EQ(TSK.STK[tskid], "NULL") && CHECK_STKSZ_ALIGN
+							&& (TSK.STKSZ[tskid] & (CHECK_STKSZ_ALIGN - 1))$
+		$ERROR TSK.TEXT_LINE[tskid]$E_PAR: $FORMAT(_("%1% `%2%\' of `%3%\' in %4% is not aligned"), "stksz", TSK.STKSZ[tskid], tskid, "CRE_TSK")$$END$
+	$END$
+
+	$IF EQ(TSK.STK[tskid],"NULL")$
+		$TSK.TINIB_STKSZ[tskid] = ALLOC_STACK(CONCAT("_kernel_stack_",
+												tskid), TSK.STKSZ[tskid])$
+		$TSK.TINIB_STK[tskid] = CONCAT("_kernel_stack_", tskid)$
+	$ELSE$
+		$TSK.TINIB_STKSZ[tskid] = FORMAT("(%1%)", TSK.STKSZ[tskid])$
+		$TSK.TINIB_STK[tskid] = FORMAT("(void *)(%1%)", TSK.STK[tskid])$
+	$END$
+$END$
+$NL$
+
+$ タスク初期化ブロックの生成（タスクは1個以上存在する）
+const TINIB _kernel_tinib_table[TNUM_STSKID] = {$NL$
+$JOINEACH tskid TSK.ID_LIST ",\n"$
+$	// タスク属性，拡張情報，起動番地，起動時優先度
+	$TAB${
+	$SPC$($TSK.TSKATR[tskid]$), (intptr_t)($TSK.EXINF[tskid]$),
+	$SPC$((TASK)($TSK.TASK[tskid]$)), INT_PRIORITY($TSK.ITSKPRI[tskid]$),
+
+$	// タスク初期化コンテキストブロック，スタック領域
+	$IF USE_TSKINICTXB$
+		$GENERATE_TSKINICTXB(tskid)$
+	$ELSE$
+		$SPC$$TSK.TINIB_STKSZ[tskid]$, $TSK.TINIB_STK[tskid]$,
+	$END$
+
+$	// タスク例外処理ルーチンの属性と起動番地
+	$SPC$($ALT(TSK.TEXATR[tskid],"TA_NULL")$), ($ALT(TSK.TEXRTN[tskid],"NULL")$) }
+$END$$NL$
+};$NL$
+$NL$
+
+$ 動的生成タスク用のタスク初期化ブロックの生成
+$IF num_atskid > 0$
+	TINIB _kernel_atinib_table[$num_atskid$];$NL$
+$ELSE$
+	TOPPERS_EMPTY_LABEL(TINIB, _kernel_atinib_table);$NL$
+$END$$NL$
+
+$ タスク管理ブロックの生成
+TCB _kernel_tcb_table[TNUM_TSKID];$NL$
+$NL$
+
+$ タスク生成順序テーブルの生成
+const ID _kernel_torder_table[TNUM_STSKID] = {$NL$
+$TAB$$JOINEACH tskid TSK.ORDER_LIST ", "$$tskid$$END$$NL$
+};$NL$
+$NL$
+
+$ 
+$  セマフォ
+$ 
+/*$NL$
+$SPC$*  Semaphore Functions$NL$
+$SPC$*/$NL$
+$NL$
+
+$ 静的に生成されたセマフォの数
+#define TNUM_SSEMID	$LENGTH(SEM.ID_LIST)$$NL$
+$NL$
+
+$ セマフォID番号の最大値
+const ID _kernel_tmax_semid = (TMIN_SEMID + TNUM_SEMID - 1);$NL$
+const ID _kernel_tmax_ssemid = (TMIN_SEMID + TNUM_SSEMID - 1);$NL$
+$NL$
+
+$ セマフォ初期化ブロックの生成
+$IF LENGTH(SEM.ID_LIST)$
+	const SEMINIB _kernel_seminib_table[TNUM_SSEMID] = {$NL$
+	$JOINEACH semid SEM.ID_LIST ",\n"$
+$		// sematrが（［TA_TPRI］）でない場合（E_RSATR）
+		$IF (SEM.SEMATR[semid] & ~TA_TPRI) != 0$
+			$ERROR SEM.TEXT_LINE[semid]$E_RSATR: $FORMAT(_("illegal %1% `%2%\' of `%3%\' in %4%"), "sematr", SEM.SEMATR[semid], semid, "CRE_SEM")$$END$
+		$END$
+
+$		// (0 <= isemcnt && isemcnt <= maxsem)でない場合（E_PAR）
+		$IF !(0 <= SEM.ISEMCNT[semid] && SEM.ISEMCNT[semid] <= SEM.MAXSEM[semid])$
+			$ERROR SEM.TEXT_LINE[semid]$E_PAR: $FORMAT(_("too large %1% `%2%\' of `%3%\' in %4%"), "isemcnt", SEM.ISEMCNT[semid], semid, "CRE_SEM")$$END$
+		$END$
+
+$		// (1 <= maxsem && maxsem <= TMAX_MAXSEM)でない場合（E_PAR）
+		$IF !(1 <= SEM.MAXSEM[semid] && SEM.MAXSEM[semid] <= TMAX_MAXSEM)$
+			$ERROR SEM.TEXT_LINE[semid]$E_PAR: $FORMAT(_("illegal %1% `%2%\' of `%3%\' in %4%"), "maxsem", SEM.MAXSEM[semid], semid, "CRE_SEM")$$END$
+		$END$
+
+$		// セマフォ初期化ブロック
+		$TAB${ ($SEM.SEMATR[semid]$), ($SEM.ISEMCNT[semid]$), ($SEM.MAXSEM[semid]$) }
+	$END$$NL$
+	};$NL$
+$ELSE$
+	TOPPERS_EMPTY_LABEL(const SEMINIB, _kernel_seminib_table);$NL$
+$END$$NL$
+
+$ 動的生成セマフォ用のセマフォ初期化ブロックの生成
+$IF num_asemid > 0$
+	SEMINIB _kernel_aseminib_table[$num_asemid$];$NL$
+$ELSE$
+	TOPPERS_EMPTY_LABEL(SEMINIB, _kernel_aseminib_table);$NL$
+$END$$NL$
+
+$ セマフォ管理ブロックの生成
+$IF num_semid > 0$
+	SEMCB _kernel_semcb_table[TNUM_SEMID];$NL$
+$ELSE$
+	TOPPERS_EMPTY_LABEL(SEMCB, _kernel_semcb_table);$NL$
+$END$$NL$
+
+$ 
+$  イベントフラグ
+$ 
+/*$NL$
+$SPC$*  Eventflag Functions$NL$
+$SPC$*/$NL$
+$NL$
+
+$ 静的に生成されたイベントフラグの数
+#define TNUM_SFLGID	$LENGTH(FLG.ID_LIST)$$NL$
+$NL$
+
+$ イベントフラグID番号の最大値
+const ID _kernel_tmax_flgid = (TMIN_FLGID + TNUM_FLGID - 1);$NL$
+const ID _kernel_tmax_sflgid = (TMIN_FLGID + TNUM_SFLGID - 1);$NL$
+$NL$
+
+$ イベントフラグ初期化ブロックの生成
+$IF LENGTH(FLG.ID_LIST)$
+	const FLGINIB _kernel_flginib_table[TNUM_SFLGID] = {$NL$
+	$JOINEACH flgid FLG.ID_LIST ",\n"$
+$		// flgatrが（［TA_TPRI］｜［TA_WMUL］｜［TA_CLR］）でない場合（E_RSATR）
+		$IF (FLG.FLGATR[flgid] & ~(TA_TPRI|TA_WMUL|TA_CLR)) != 0$
+			$ERROR FLG.TEXT_LINE[flgid]$E_RSATR: $FORMAT(_("illegal %1% `%2%\' of `%3%\' in %4%"), "flgatr", FLG.FLGATR[flgid], flgid, "CRE_FLG")$$END$
+		$END$
+
+$		// iflgptnがFLGPTNに格納できない場合（E_PAR）
+		$IF (FLG.IFLGPTN[flgid] & ~((1 << TBIT_FLGPTN) - 1)) != 0$
+			$ERROR FLG.TEXT_LINE[flgid]$E_PAR: $FORMAT(_("too large %1% `%2%\' of `%3%\' in %4%"), "iflgptn", FLG.IFLGPTN[flgid], flgid, "CRE_FLG")$$END$
+		$END$
+
+$		// イベントフラグ初期化ブロック
+		$TAB${ ($FLG.FLGATR[flgid]$), ($FLG.IFLGPTN[flgid]$) }
+	$END$$NL$
+	};$NL$
+$ELSE$
+	TOPPERS_EMPTY_LABEL(const FLGINIB, _kernel_flginib_table);$NL$
+$END$$NL$
+
+$ 動的生成イベントフラグ用のイベントフラグ初期化ブロックの生成
+$IF num_aflgid > 0$
+	FLGINIB _kernel_aflginib_table[$num_aflgid$];$NL$
+$ELSE$
+	TOPPERS_EMPTY_LABEL(FLGINIB, _kernel_aflginib_table);$NL$
+$END$$NL$
+
+$ イベントフラグ管理ブロックの生成
+$IF num_flgid > 0$
+	FLGCB _kernel_flgcb_table[TNUM_FLGID];$NL$
+$ELSE$
+	TOPPERS_EMPTY_LABEL(FLGCB, _kernel_flgcb_table);$NL$
+$END$$NL$
+
+$ 
+$  データキュー
+$ 
+/*$NL$
+$SPC$*  Dataqueue Functions$NL$
+$SPC$*/$NL$
+$NL$
+
+$ 静的に生成されたデータキューの数
+#define TNUM_SDTQID	$LENGTH(DTQ.ID_LIST)$$NL$
+$NL$
+
+$ データキューID番号の最大値
+const ID _kernel_tmax_dtqid = (TMIN_DTQID + TNUM_DTQID - 1);$NL$
+const ID _kernel_tmax_sdtqid = (TMIN_DTQID + TNUM_SDTQID - 1);$NL$
+$NL$
+
+$IF LENGTH(DTQ.ID_LIST)$
+	$FOREACH dtqid DTQ.ID_LIST$
+$		// dtqatrが（［TA_TPRI］）でない場合（E_RSATR）
+		$IF (DTQ.DTQATR[dtqid] & ~TA_TPRI) != 0$
+			$ERROR DTQ.TEXT_LINE[dtqid]$E_RSATR: $FORMAT(_("illegal %1% `%2%\' of `%3%\' in %4%"), "dtqatr", DTQ.DTQATR[dtqid], dtqid, "CRE_DTQ")$$END$
+		$END$
+
+$		// dtqcntが負の場合（E_PAR）
+		$IF DTQ.DTQCNT[dtqid] < 0$
+			$ERROR DTQ.TEXT_LINE[dtqid]$E_PAR: $FORMAT(_("illegal %1% `%2%\' of `%3%\' in %4%"), "dtqcnt", DTQ.DTQCNT[dtqid], dtqid, "CRE_DTQ")$$END$
+		$END$
+
+$		// dtqmbがNULLでない場合（E_NOSPT）
+		$IF !EQ(DTQ.DTQMB[dtqid], "NULL")$
+			$ERROR DTQ.TEXT_LINE[dtqid]$E_NOSPT: $FORMAT(_("illegal %1% `%2%\' of `%3%\' in %4%"), "dtqmb", DTQ.DTQMB[dtqid], dtqid, "CRE_DTQ")$$END$
+		$END$
+
+$		// データキュー管理領域
+		$IF DTQ.DTQCNT[dtqid]$
+			static DTQMB _kernel_dtqmb_$dtqid$[$DTQ.DTQCNT[dtqid]$];$NL$
+		$END$
+	$END$
+
+$	// データキュー初期化ブロックの生成
+	const DTQINIB _kernel_dtqinib_table[TNUM_SDTQID] = {$NL$
+	$JOINEACH dtqid DTQ.ID_LIST ",\n"$
+		$TAB${ ($DTQ.DTQATR[dtqid]$), ($DTQ.DTQCNT[dtqid]$), $IF DTQ.DTQCNT[dtqid]$(_kernel_dtqmb_$dtqid$)$ELSE$NULL$END$ }
+	$END$$NL$
+	};$NL$
+$ELSE$
+	TOPPERS_EMPTY_LABEL(const DTQINIB, _kernel_dtqinib_table);$NL$
+$END$$NL$
+
+$ 動的生成データキュー用のデータキュー初期化ブロックの生成
+$IF num_adtqid > 0$
+	DTQINIB _kernel_adtqinib_table[$num_adtqid$];$NL$
+$ELSE$
+	TOPPERS_EMPTY_LABEL(DTQINIB, _kernel_adtqinib_table);$NL$
+$END$$NL$
+
+$ データキュー管理ブロックの生成
+$IF num_dtqid > 0$
+	DTQCB _kernel_dtqcb_table[TNUM_DTQID];$NL$
+$ELSE$
+	TOPPERS_EMPTY_LABEL(DTQCB, _kernel_dtqcb_table);$NL$
+$END$$NL$
+
+$ 
+$  優先度データキュー
+$ 
+/*$NL$
+$SPC$*  Priority Dataqueue Functions$NL$
+$SPC$*/$NL$
+$NL$
+
+$ 静的に生成された優先度データキューの数
+#define TNUM_SPDQID	$LENGTH(PDQ.ID_LIST)$$NL$
+$NL$
+
+$ 優先度データキューID番号の最大値
+const ID _kernel_tmax_pdqid = (TMIN_PDQID + TNUM_PDQID - 1);$NL$
+const ID _kernel_tmax_spdqid = (TMIN_PDQID + TNUM_SPDQID - 1);$NL$
+$NL$
+
+$IF LENGTH(PDQ.ID_LIST)$
+	$FOREACH pdqid PDQ.ID_LIST$
+$		// pdqatrが（［TA_TPRI］）でない場合（E_RSATR）
+		$IF (PDQ.PDQATR[pdqid] & ~TA_TPRI) != 0$
+			$ERROR PDQ.TEXT_LINE[pdqid]$E_RSATR: $FORMAT(_("illegal %1% `%2%\' of `%3%\' in %4%"), "pdqatr", PDQ.PDQATR[pdqid], pdqid, "CRE_PDQ")$$END$
+		$END$
+
+$		// pdqcntが負の場合（E_PAR）
+		$IF PDQ.PDQCNT[pdqid] < 0$
+			$ERROR PDQ.TEXT_LINE[pdqid]$E_PAR: $FORMAT(_("illegal %1% `%2%\' of `%3%\' in %4%"), "pdqcnt", PDQ.PDQCNT[pdqid], pdqid, "CRE_PDQ")$$END$
+		$END$
+
+$		// (TMIN_DPRI <= maxdpri && maxdpri <= TMAX_DPRI)でない場合（E_PAR）
+		$IF !(TMIN_DPRI <= PDQ.MAXDPRI[pdqid] && PDQ.MAXDPRI[pdqid] <= TMAX_DPRI)$
+			$ERROR PDQ.TEXT_LINE[pdqid]$E_PAR: $FORMAT(_("illegal %1% `%2%\' of `%3%\' in %4%"), "maxdpri", PDQ.MAXDPRI[pdqid], pdqid, "CRE_PDQ")$$END$
+		$END$
+
+$		// pdqmbがNULLでない場合（E_NOSPT）
+		$IF !EQ(PDQ.PDQMB[pdqid], "NULL")$
+			$ERROR PDQ.TEXT_LINE[pdqid]$E_NOSPT: $FORMAT(_("illegal %1% `%2%\' of `%3%\' in %4%"), "pdqmb", PDQ.PDQMB[pdqid], pdqid, "CRE_PDQ")$$END$
+		$END$
+
+$		// 優先度データキュー管理領域
+		$IF PDQ.PDQCNT[pdqid]$
+			static PDQMB _kernel_pdqmb_$pdqid$[$PDQ.PDQCNT[pdqid]$];$NL$
+		$END$
+	$END$
+
+$	// 優先度データキュー初期化ブロックの生成
+	const PDQINIB _kernel_pdqinib_table[TNUM_SPDQID] = {$NL$
+	$JOINEACH pdqid PDQ.ID_LIST ",\n"$
+		$TAB${ ($PDQ.PDQATR[pdqid]$), ($PDQ.PDQCNT[pdqid]$), ($PDQ.MAXDPRI[pdqid]$), $IF PDQ.PDQCNT[pdqid]$(_kernel_pdqmb_$pdqid$)$ELSE$NULL$END$ }
+	$END$$NL$
+	};$NL$
+$ELSE$
+	TOPPERS_EMPTY_LABEL(const PDQINIB, _kernel_pdqinib_table);$NL$
+$END$$NL$
+
+$ 動的生成優先度データキュー用の優先度データキュー初期化ブロックの生成
+$IF num_apdqid > 0$
+	PDQINIB _kernel_apdqinib_table[$num_apdqid$];$NL$
+$ELSE$
+	TOPPERS_EMPTY_LABEL(PDQINIB, _kernel_apdqinib_table);$NL$
+$END$$NL$
+
+$ 優先度データキュー管理ブロックの生成
+$IF num_pdqid > 0$
+	PDQCB _kernel_pdqcb_table[TNUM_PDQID];$NL$
+$ELSE$
+	TOPPERS_EMPTY_LABEL(PDQCB, _kernel_pdqcb_table);$NL$
+$END$$NL$
+
+$ 
+$  メールボックス
+$ 
+/*$NL$
+$SPC$*  Mailbox Functions$NL$
+$SPC$*/$NL$
+$NL$
+
+$ 静的に生成されたメールボックスの数
+#define TNUM_SMBXID	$LENGTH(MBX.ID_LIST)$$NL$
+$NL$
+
+$ メールボックスID番号の最大値
+const ID _kernel_tmax_mbxid = (TMIN_MBXID + TNUM_MBXID - 1);$NL$
+const ID _kernel_tmax_smbxid = (TMIN_MBXID + TNUM_SMBXID - 1);$NL$
+$NL$
+
+$ メールボックス初期化ブロックの生成
+$IF LENGTH(MBX.ID_LIST)$
+	const MBXINIB _kernel_mbxinib_table[TNUM_SMBXID] = {$NL$
+	$JOINEACH mbxid MBX.ID_LIST ",\n"$
+$		// mbxatrが（［TA_TPRI］｜［TA_MPRI］）でない場合（E_RSATR）
+		$IF (MBX.MBXATR[mbxid] & ~(TA_TPRI|TA_MPRI)) != 0$
+			$ERROR MBX.TEXT_LINE[mbxid]$E_RSATR: $FORMAT(_("illegal %1% `%2%\' of `%3%\' in %4%"), "mbxatr", MBX.MBXATR[mbxid], mbxid, "CRE_MBX")$$END$
+		$END$
+
+$		// (TMIN_MPRI <= maxmpri && maxmpri <= TMAX_MPRI)でない場合（E_PAR）
+		$IF !(TMIN_MPRI <= MBX.MAXMPRI[mbxid] && MBX.MAXMPRI[mbxid] <= TMAX_MPRI)$
+			$ERROR MBX.TEXT_LINE[mbxid]$E_PAR: $FORMAT(_("illegal %1% `%2%\' of `%3%\' in %4%"), "maxmpri", MBX.MAXMPRI[mbxid], mbxid, "CRE_MBX")$$END$
+		$END$
+
+$		// mprihdがNULLでない場合（E_NOSPT）
+		$IF !EQ(MBX.MPRIHD[mbxid], "NULL")$
+			$ERROR MBX.TEXT_LINE[mbxid]$E_NOSPT: $FORMAT(_("illegal %1% `%2%\' of `%3%\' in %4%"), "mprihd", MBX.MPRIHD[mbxid], mbxid, "CRE_MBX")$$END$
+		$END$
+
+$		// メールボックス初期化ブロック
+		$TAB${ ($MBX.MBXATR[mbxid]$), ($MBX.MAXMPRI[mbxid]$) }
+	$END$$NL$
+	};$NL$
+$ELSE$
+	TOPPERS_EMPTY_LABEL(const MBXINIB, _kernel_mbxinib_table);$NL$
+$END$$NL$
+
+$ 動的生成メールボックス用のメールボックス初期化ブロックの生成
+$IF num_ambxid > 0$
+	MBXINIB _kernel_ambxinib_table[$num_ambxid$];$NL$
+$ELSE$
+	TOPPERS_EMPTY_LABEL(MBXINIB, _kernel_ambxinib_table);$NL$
+$END$$NL$
+
+$ メールボックス管理ブロックの生成
+$IF num_mbxid > 0$
+	MBXCB _kernel_mbxcb_table[TNUM_MBXID];$NL$
+$ELSE$
+	TOPPERS_EMPTY_LABEL(MBXCB, _kernel_mbxcb_table);$NL$
+$END$$NL$
+
+$ 
+$  ミューテックス
+$ 
+/*$NL$
+$SPC$*  Mutex Functions$NL$
+$SPC$*/$NL$
+$NL$
+
+$ 静的に生成されたミューテックスの数
+#define TNUM_SMTXID	$LENGTH(MTX.ID_LIST)$$NL$
+$NL$
+
+$ ミューテックスID番号の最大値
+const ID _kernel_tmax_mtxid = (TMIN_MTXID + TNUM_MTXID - 1);$NL$
+const ID _kernel_tmax_smtxid = (TMIN_MTXID + TNUM_SMTXID - 1);$NL$
+$NL$
+
+$ ミューテックス初期化ブロックの生成
+$IF LENGTH(MTX.ID_LIST)$
+	const MTXINIB _kernel_mtxinib_table[TNUM_SMTXID] = {$NL$
+	$JOINEACH mtxid MTX.ID_LIST ",\n"$
+$		// mtxatrが（［TA_TPRI｜TA_CEILING］）でない場合（E_RSATR）
+		$IF !(MTX.MTXATR[mtxid] == 0 || MTX.MTXATR[mtxid] == TA_TPRI || MTX.MTXATR[mtxid] == TA_CEILING)$
+			$ERROR MTX.TEXT_LINE[mtxid]$E_RSATR: $FORMAT(_("illegal %1% `%2%\' of `%3%\' in %4%"), "mtxatr", MTX.MTXATR[mtxid], mtxid, "CRE_MTX")$$END$
+		$END$
+
+$		// ceilpriが未指定の場合は0と見なす
+		$IF !LENGTH(MTX.CEILPRI[mtxid])$
+			$MTX.CEILPRI[mtxid] = 0$
+		$END$
+$		// (TMIN_TPRI <= ceilpri && ceilpri <= TMAX_TPRI)でない場合（E_PAR）
+		$IF MTX.MTXATR[mtxid] == TA_CEILING && (MTX.CEILPRI[mtxid] < TMIN_TPRI || TMAX_TPRI < MTX.CEILPRI[mtxid])$
+			$ERROR MTX.TEXT_LINE[mtxid]$E_PAR: $FORMAT(_("illegal %1% `%2%\' of `%3%\' in %4%"), "ceilpri", MTX.CEILPRI[mtxid], mtxid, "CRE_MTX")$$END$
+		$END$
+
+$		// ミューテックス初期化ブロック
+		$TAB${ ($MTX.MTXATR[mtxid]$), INT_PRIORITY($MTX.CEILPRI[mtxid]$) }
+	$END$$NL$
+	};$NL$
+$ELSE$
+	TOPPERS_EMPTY_LABEL(const MTXINIB, _kernel_mtxinib_table);$NL$
+$END$$NL$
+
+$ 動的生成ミューテックス用のミューテックス初期化ブロックの生成
+$IF num_amtxid > 0$
+	MTXINIB _kernel_amtxinib_table[$num_amtxid$];$NL$
+$ELSE$
+	TOPPERS_EMPTY_LABEL(MTXINIB, _kernel_amtxinib_table);$NL$
+$END$$NL$
+
+$ ミューテックス管理ブロックの生成
+$IF num_mtxid > 0$
+	MTXCB _kernel_mtxcb_table[TNUM_MTXID];$NL$
+$ELSE$
+	TOPPERS_EMPTY_LABEL(MTXCB, _kernel_mtxcb_table);$NL$
+$END$$NL$
+
+$ 
+$  固定長メモリプール
+$ 
+/*$NL$
+$SPC$*  Fixed-sized Memorypool Functions$NL$
+$SPC$*/$NL$
+$NL$
+
+$ 静的に生成された固定長メモリプールの数
+#define TNUM_SMPFID	$LENGTH(MPF.ID_LIST)$$NL$
+$NL$
+
+$ 固定長メモリプールID番号の最大値
+const ID _kernel_tmax_mpfid = (TMIN_MPFID + TNUM_MPFID - 1);$NL$
+const ID _kernel_tmax_smpfid = (TMIN_MPFID + TNUM_SMPFID - 1);$NL$
+$NL$
+
+$IF LENGTH(MPF.ID_LIST)$
+	$FOREACH mpfid MPF.ID_LIST$
+$		// mpfatrが（［TA_TPRI］）でない場合（E_RSATR）
+		$IF (MPF.MPFATR[mpfid] & ~TA_TPRI) != 0$
+			$ERROR MPF.TEXT_LINE[mpfid]$E_RSATR: $FORMAT(_("illegal %1% `%2%\' of `%3%\' in %4%"), "mpfatr", MPF.MPFATR[mpfid], mpfid, "CRE_MPF")$$END$
+		$END$
+
+$		// blkcntが0以下の場合（E_PAR）
+		$IF MPF.BLKCNT[mpfid] <= 0$
+			$ERROR MPF.TEXT_LINE[mpfid]$E_PAR: $FORMAT(_("illegal %1% `%2%\' of `%3%\' in %4%"), "blkcnt", MPF.BLKCNT[mpfid], mpfid, "CRE_MPF")$$END$
+		$END$
+
+$		// blkszが0以下の場合（E_PAR）
+		$IF MPF.BLKSZ[mpfid] <= 0$
+			$ERROR MPF.TEXT_LINE[mpfid]$E_PAR: $FORMAT(_("illegal %1% `%2%\' of `%3%\' in %4%"), "blksz", MPF.BLKSZ[mpfid], mpfid, "CRE_MPF")$$END$
+		$END$
+
+$		// 固定長メモリプール領域
+		$IF EQ(MPF.MPF[mpfid], "NULL")$
+			static MPF_T _kernel_mpf_$mpfid$[($MPF.BLKCNT[mpfid]$) * COUNT_MPF_T($MPF.BLKSZ[mpfid]$)];$NL$
+		$END$
+
+$		// mpfmbがNULLでない場合（E_NOSPT）
+		$IF !EQ(MPF.MPFMB[mpfid], "NULL")$
+			$ERROR MPF.TEXT_LINE[mpfid]$E_NOSPT: $FORMAT(_("illegal %1% `%2%\' of `%3%\' in %4%"), "mpfmb", MPF.MPFMB[mpfid], mpfid, "CRE_MPF")$$END$
+		$END$
+
+$		// 固定長メモリプール管理領域
+		static MPFMB _kernel_mpfmb_$mpfid$[$MPF.BLKCNT[mpfid]$];$NL$
+	$END$
+
+$	// 固定長メモリプール初期化ブロックの生成
+	const MPFINIB _kernel_mpfinib_table[TNUM_SMPFID] = {$NL$
+	$JOINEACH mpfid MPF.ID_LIST ",\n"$
+		$TAB${ ($MPF.MPFATR[mpfid]$), ($MPF.BLKCNT[mpfid]$), ROUND_MPF_T($MPF.BLKSZ[mpfid]$), $IF EQ(MPF.MPF[mpfid],"NULL")$(_kernel_mpf_$mpfid$)$ELSE$(void *)($MPF.MPF[mpfid]$)$END$, (_kernel_mpfmb_$mpfid$) }
+	$END$$NL$
+	};$NL$
+$ELSE$
+	TOPPERS_EMPTY_LABEL(const MPFINIB, _kernel_mpfinib_table);$NL$
+$END$$NL$
+
+$ 動的生成固定長メモリプール用の固定長メモリプール初期化ブロックの生成
+$IF num_ampfid > 0$
+	MPFINIB _kernel_ampfinib_table[$num_ampfid$];$NL$
+$ELSE$
+	TOPPERS_EMPTY_LABEL(MPFINIB, _kernel_ampfinib_table);$NL$
+$END$$NL$
+
+$ 固定長メモリプール管理ブロックの生成
+$IF num_mpfid > 0$
+	MPFCB _kernel_mpfcb_table[TNUM_MPFID];$NL$
+$ELSE$
+	TOPPERS_EMPTY_LABEL(MPFCB, _kernel_mpfcb_table);$NL$
+$END$$NL$
+
+$ 
+$  周期ハンドラ
+$ 
+/*$NL$
+$SPC$*  Cyclic Handler Functions$NL$
+$SPC$*/$NL$
+$NL$
+
+$ 静的に生成された周期ハンドラの数
+#define TNUM_SCYCID	$LENGTH(CYC.ID_LIST)$$NL$
+$NL$
+
+$ 周期ハンドラID番号の最大値
+const ID _kernel_tmax_cycid = (TMIN_CYCID + TNUM_CYCID - 1);$NL$
+const ID _kernel_tmax_scycid = (TMIN_CYCID + TNUM_SCYCID - 1);$NL$
+$NL$
+
+$ 周期ハンドラ初期化ブロックの生成
+$IF LENGTH(CYC.ID_LIST)$
+	const CYCINIB _kernel_cycinib_table[TNUM_SCYCID] = {$NL$
+	$JOINEACH cycid CYC.ID_LIST ",\n"$
+$		// cycatrが（［TA_STA］）でない場合（E_RSATR）
+		$IF (CYC.CYCATR[cycid] & ~TA_STA) != 0$
+			$ERROR CYC.TEXT_LINE[cycid]$E_RSATR: $FORMAT(_("illegal %1% `%2%\' of `%3%\' in %4%"), "cycatr", CYC.CYCATR[cycid], cycid, "CRE_CYC")$$END$
+		$END$
+
+$		// (0 < cyctim && cyctim <= TMAX_RELTIM)でない場合（E_PAR）
+		$IF !(0 < CYC.CYCTIM[cycid] && CYC.CYCTIM[cycid] <= TMAX_RELTIM)$
+			$ERROR CYC.TEXT_LINE[cycid]$E_PAR: $FORMAT(_("illegal %1% `%2%\' of `%3%\' in %4%"), "cyctim", CYC.CYCTIM[cycid], cycid, "CRE_CYC")$$END$
+		$END$
+
+$		// (0 <= cycphs && cycphs <= TMAX_RELTIM)でない場合（E_PAR）
+		$IF !(0 <= CYC.CYCPHS[cycid] && CYC.CYCPHS[cycid] <= TMAX_RELTIM)$
+			$ERROR CYC.TEXT_LINE[cycid]$E_PAR: $FORMAT(_("illegal %1% `%2%\' of `%3%\' in %4%"), "cycphs", CYC.CYCPHS[cycid], cycid, "CRE_CYC")$$END$
+		$END$
+
+$		// 警告：cycatrにTA_STAが設定されていて，(cycphs == 0)の場合
+		$IF (CYC.CYCATR[cycid] & TA_STA) != 0 && CYC.CYCPHS[cycid] == 0$
+			$WARNING CYC.TEXT_LINE[cycid]$$FORMAT(_("%1% is not recommended when %2% is set to %3% in %4%"), "cycphs==0", "TA_STA", "cycatr", "CRE_CYC")$$END$
+		$END$
+
+$		// 周期ハンドラ初期化ブロック
+		$TAB${ ($CYC.CYCATR[cycid]$), (intptr_t)($CYC.EXINF[cycid]$), ($CYC.CYCHDR[cycid]$), ($CYC.CYCTIM[cycid]$), ($CYC.CYCPHS[cycid]$) }
+	$END$$NL$
+	};$NL$
+$ELSE$
+	TOPPERS_EMPTY_LABEL(const CYCINIB, _kernel_cycinib_table);$NL$
+$END$$NL$
+
+$ 動的生成周期ハンドラ用の周期ハンドラ初期化ブロックの生成
+$IF num_acycid > 0$
+	CYCINIB _kernel_acycinib_table[$num_acycid$];$NL$
+$ELSE$
+	TOPPERS_EMPTY_LABEL(CYCINIB, _kernel_acycinib_table);$NL$
+$END$$NL$
+
+$ 周期ハンドラ管理ブロックの生成
+$IF num_cycid > 0$
+	CYCCB _kernel_cyccb_table[TNUM_CYCID];$NL$
+$ELSE$
+	TOPPERS_EMPTY_LABEL(CYCCB, _kernel_cyccb_table);$NL$
+$END$$NL$
+
+$ 
+$  アラームハンドラ
+$ 
+/*$NL$
+$SPC$*  Alarm Handler Functions$NL$
+$SPC$*/$NL$
+$NL$
+
+$ 静的に生成されたアラームハンドラの数
+#define TNUM_SALMID	$LENGTH(ALM.ID_LIST)$$NL$
+$NL$
+
+$ アラームハンドラID番号の最大値
+const ID _kernel_tmax_almid = (TMIN_ALMID + TNUM_ALMID - 1);$NL$
+const ID _kernel_tmax_salmid = (TMIN_ALMID + TNUM_SALMID - 1);$NL$
+$NL$
+
+$ アラームハンドラ初期化ブロックの生成
+$IF LENGTH(ALM.ID_LIST)$
+	const ALMINIB _kernel_alminib_table[TNUM_SALMID] = {$NL$
+	$JOINEACH almid ALM.ID_LIST ",\n"$
+$		// almatrが（TA_NULL）でない場合（E_RSATR）
+		$IF ALM.ALMATR[almid] != 0$
+			$ERROR ALM.TEXT_LINE[almid]$E_RSATR: $FORMAT(_("illegal %1% `%2%\' of `%3%\' in %4%"), "almatr", ALM.ALMATR[almid], almid, "CRE_ALM")$$END$
+		$END$
+
+$		// アラームハンドラ初期化ブロック
+		$TAB${ ($ALM.ALMATR[almid]$), (intptr_t)($ALM.EXINF[almid]$), ($ALM.ALMHDR[almid]$) }
+	$END$$NL$
+	};$NL$
+$ELSE$
+	TOPPERS_EMPTY_LABEL(const ALMINIB, _kernel_alminib_table);$NL$
+$END$$NL$
+
+$ 動的生成アラームハンドラ用のアラームハンドラ初期化ブロックの生成
+$IF num_aalmid > 0$
+	ALMINIB _kernel_aalminib_table[$num_aalmid$];$NL$
+$ELSE$
+	TOPPERS_EMPTY_LABEL(ALMINIB, _kernel_aalminib_table);$NL$
+$END$$NL$
+
+$ アラームハンドラ管理ブロックの生成
+$IF num_almid > 0$
+	ALMCB _kernel_almcb_table[TNUM_ALMID];$NL$
+$ELSE$
+	TOPPERS_EMPTY_LABEL(ALMCB, _kernel_almcb_table);$NL$
+$END$$NL$
+
+$ 
+$  割込み管理機能
+$ 
+/*$NL$
+$SPC$*  Interrupt Management Functions$NL$
+$SPC$*/$NL$
+$NL$
+
+$ 割込み番号と割込みハンドラ番号の変換テーブルの作成
+$IF LENGTH(INTNO_ATTISR_VALID) != LENGTH(INHNO_ATTISR_VALID)$
+	$ERROR$length of `INTNO_ATTISR_VALID' is different from length of `INHNO_ATTISR_VALID'$END$
+$END$
+$i = 0$
+$FOREACH intno INTNO_ATTISR_VALID$
+	$inhno = AT(INHNO_ATTISR_VALID, i)$
+	$INHNO[intno] = inhno$
+	$INTNO[inhno] = intno$
+	$i = i + 1$
+$END$
+
+$ 割込み要求ラインに関するエラーチェック
+$i = 0$
+$FOREACH intno INT.ORDER_LIST$
+$	// intnoがCFG_INTに対する割込み番号として正しくない場合（E_PAR）
+	$IF !LENGTH(FIND(INTNO_CFGINT_VALID, INT.INTNO[intno]))$
+		$ERROR INT.TEXT_LINE[intno]$E_PAR: $FORMAT(_("illegal %1% `%2%\' in %3%"), "intno", INT.INTNO[intno], "CFG_INT")$$END$
+	$END$
+
+$	// intnoがCFG_INTによって設定済みの場合（E_OBJ）
+	$j = 0$
+	$FOREACH intno2 INT.ORDER_LIST$
+		$IF j < i && INT.INTNO[intno] == INT.INTNO[intno2]$
+			$ERROR INT.TEXT_LINE[intno]$E_OBJ: $FORMAT(_("%1% `%2%\' in %3% is duplicated"), "intno", INT.INTNO[intno], "CFG_INT")$$END$
+		$END$
+		$j = j + 1$
+	$END$
+
+$	// intatrが（［TA_ENAINT］｜［TA_EDGE］）でない場合（E_RSATR）
+	$IF (INT.INTATR[intno] & ~(TA_ENAINT|TA_EDGE|TARGET_INTATR)) != 0$
+		$ERROR INT.TEXT_LINE[intno]$E_RSATR: $FORMAT(_("illegal %1% `%2%\' of %3% `%4%\' in %5%"), "intatr", INT.INTATR[intno], "intno", INT.INTNO[intno], "CFG_INT")$$END$
+	$END$
+
+$	// intpriがCFG_INTに対する割込み優先度として正しくない場合（E_PAR）
+	$IF !LENGTH(FIND(INTPRI_CFGINT_VALID, INT.INTPRI[intno]))$
+		$ERROR INT.TEXT_LINE[intno]$E_PAR: $FORMAT(_("illegal %1% `%2%\' in %3%"), "intpri", INT.INTPRI[intno], "CFG_INT")$$END$
+	$END$
+
+$	// カーネル管理に固定されているintnoに対して，intpriにTMIN_INTPRI
+$	// よりも小さい値が指定された場合（E_OBJ）
+	$IF LENGTH(FIND(INTNO_FIX_KERNEL, intno))$
+		$IF INT.INTPRI[intno] < TMIN_INTPRI$
+			$ERROR INT.TEXT_LINE[intno]$E_OBJ: $FORMAT(_("%1% `%2%\' must not have higher priority than %3%"), "intno", INT.INTNO[intno], "TMIN_INTPRI")$$END$
+		$END$
+	$END$
+
+$	// カーネル管理外に固定されているintnoに対して，intpriにTMIN_INTPRI
+$	// よりも小さい値が指定されなかった場合（E_OBJ）
+	$IF LENGTH(FIND(INTNO_FIX_NONKERNEL, intno))$
+		$IF INT.INTPRI[intno] >= TMIN_INTPRI$
+			$ERROR INT.TEXT_LINE[intno]$E_OBJ: $FORMAT(_("%1% `%2%\' must have higher priority than %3%"), "intno", INT.INTNO[intno], "TMIN_INTPRI")$$END$
+		$END$
+	$END$
+	$i = i + 1$
+$END$
+
+$ 割込みハンドラに関するエラーチェック
+$i = 0$
+$FOREACH inhno INH.ORDER_LIST$
+$	// inhnoがDEF_INHに対する割込みハンドラ番号として正しくない場合（E_PAR）
+	$IF !LENGTH(FIND(INHNO_DEFINH_VALID, INH.INHNO[inhno]))$
+		$ERROR INH.TEXT_LINE[inhno]$E_PAR: $FORMAT(_("illegal %1% `%2%\' in %3%"), "inhno", INH.INHNO[inhno], "DEF_INH")$$END$
+	$END$
+
+$	// inhnoがDEF_INHによって設定済みの場合（E_OBJ）
+	$j = 0$
+	$FOREACH inhno2 INH.ORDER_LIST$
+		$IF j < i && INH.INHNO[inhno] == INH.INHNO[inhno2]$
+			$ERROR INH.TEXT_LINE[inhno]$E_OBJ: $FORMAT(_("%1% `%2%\' in %3% is duplicated"), "inhno", INH.INHNO[inhno], "DEF_INH")$$END$
+		$END$
+		$j = j + 1$
+	$END$
+
+$	// inhatrが（TA_NULL）でない場合（E_RSATR）
+	$IF (INH.INHATR[inhno] & ~TARGET_INHATR) != 0$
+		$ERROR INH.TEXT_LINE[inhno]$E_RSATR: $FORMAT(_("illegal %1% `%2%\' of %3% `%4%\' in %5%"), "inhatr", INH.INHATR[inhno], "inhno", INH.INHNO[inhno], "DEF_INH")$$END$
+	$END$
+
+$	// カーネル管理に固定されているinhnoに対して，inhatrにTA_NONKERNEL
+$	//　が指定されている場合（E_RSATR）
+	$IF LENGTH(FIND(INHNO_FIX_KERNEL, inhno))$
+		$IF (INH.INHATR[inhno] & TA_NONKERNEL) != 0$
+			$ERROR INH.TEXT_LINE[inhno]$E_RSATR: $FORMAT(_("%1% `%2%\' must not be non-kernel interrupt"), "inhno", INH.INHNO[inhno])$$END$
+		$END$
+	$END$
+
+$	// カーネル管理外に固定されているinhnoに対して，inhatrにTA_NONKERNEL
+$	// が指定されていない場合（E_RSATR）
+	$IF LENGTH(FIND(INHNO_FIX_NONKERNEL, inhno))$
+		$IF (INH.INHATR[inhno] & TA_NONKERNEL) == 0$
+			$ERROR INH.TEXT_LINE[inhno]$E_RSATR: $FORMAT(_("%1% `%2%\' must be non-kernel interrupt"), "inhno", INH.INHNO[inhno])$$END$
+		$END$
+	$END$
+
+	$IF LENGTH(INTNO[INH.INHNO[inhno]])$
+		$intno = INTNO[INH.INHNO[inhno]]$
+$		// inhnoに対応するintnoに対するCFG_INTがない場合（E_OBJ）
+		$IF !LENGTH(INT.INTNO[intno])$
+			$ERROR INH.TEXT_LINE[inhno]$E_OBJ: $FORMAT(_("%1% `%2%\' corresponding to %3% `%4%\' is not configured with %5%"), "intno", intno, "inhno", INH.INHNO[inhno], "CFG_INT")$$END$
+		$ELSE$
+			$IF (INH.INHATR[inhno] & TA_NONKERNEL) == 0$
+$				// inhatrにTA_NONKERNELが指定されておらず，inhnoに対応
+$				// するintnoに対してCFG_INTで設定された割込み優先度が
+$				// TMIN_INTPRIよりも小さい場合（E_OBJ）
+				$IF INT.INTPRI[intno] < TMIN_INTPRI$
+					$ERROR INT.TEXT_LINE[intno]$E_OBJ: $FORMAT(_("%1% `%2%\' configured for %3% `%4%\' is higher than %5%"), "intpri", INT.INTPRI[intno], "inhno", INH.INHNO[inhno], "TMIN_INTPRI")$$END$
+				$END$
+			$ELSE$
+$				// inhatrにTA_NONKERNELが指定されており，inhnoに対応
+$				// するintnoに対してCFG_INTで設定された割込み優先度が
+$				// TMIN_INTPRI以上である場合（E_OBJ）
+				$IF INT.INTPRI[intno] >= TMIN_INTPRI$
+					$ERROR INT.TEXT_LINE[intno]$E_OBJ: $FORMAT(_("%1% `%2%\' configured for %3% `%4%\' is lower than or equal to %5%"), "intpri", INT.INTPRI[intno], "inhno", INH.INHNO[inhno], "TMIN_INTPRI")$$END$
+				$END$
+			$END$
+		$END$
+	$END$
+	$i = i + 1$
+$END$
+
+$ 割込みサービスルーチン（ISR）に関するエラーチェック
+$FOREACH order ISR.ORDER_LIST$
+$	// isratrが（TA_NULL）でない場合（E_RSATR）
+	$IF (ISR.ISRATR[order] & ~TARGET_ISRATR) != 0$
+		$ERROR ISR.TEXT_LINE[order]$E_RSATR: $FORMAT(_("illegal %1% `%2%\' in %3%"), "isratr", ISR.ISRATR[order], "ATT_ISR")$$END$
+	$END$
+
+$	// intnoがATT_ISRに対する割込み番号として正しくない場合（E_PAR）
+	$IF !LENGTH(FIND(INTNO_ATTISR_VALID, ISR.INTNO[order]))$
+		$ERROR ISR.TEXT_LINE[order]$E_PAR: $FORMAT(_("illegal %1% `%2%\' in %3%"), "intno", ISR.INTNO[order], "ATT_ISR")$$END$
+	$END$
+
+$	// (TMIN_ISRPRI <= isrpri && isrpri <= TMAX_ISRPRI)でない場合（E_PAR）
+	$IF !(TMIN_ISRPRI <= ISR.ISRPRI[order] && ISR.ISRPRI[order] <= TMAX_ISRPRI)$
+		$ERROR ISR.TEXT_LINE[order]$E_PAR: $FORMAT(_("illegal %1% `%2%\' in %3%"), "isrpri", ISR.ISRPRI[order], "ATT_ISR")$$END$
+	$END$
+$END$
+
+$FOREACH intno INTNO_ATTISR_VALID$
+	$inhno = INHNO[intno]$
+
+$	// 割込み番号intnoに対して登録されたISRのリストの作成
+	$isr_order_list = {}$
+	$FOREACH order ISR.ORDER_LIST$
+		$IF ISR.INTNO[order] == intno$
+			$isr_order_list = APPEND(isr_order_list, order)$
+			$order_for_error = order$
+		$END$
+	$END$
+
+$	// 割込み番号intnoに対して登録されたISRが存在する場合
+	$IF LENGTH(isr_order_list) > 0$
+$		// intnoに対応するinhnoに対してDEF_INHがある場合（E_OBJ）
+		$IF LENGTH(INH.INHNO[inhno])$
+			$ERROR ISR.TEXT_LINE[order_for_error]$E_OBJ: $FORMAT(_("%1% `%2%\' in %3% is duplicated with %4% `%5%\'"), "intno", ISR.INTNO[order_for_error], "ATT_ISR", "inhno", INH.INHNO[inhno])$$END$
+		$END$
+
+$		// intnoに対するCFG_INTがない場合（E_OBJ）
+		$IF !LENGTH(INT.INTNO[intno])$
+			$ERROR ISR.TEXT_LINE[order_for_error]$E_OBJ: $FORMAT(_("%1% `%2%\' is not configured with %3%"), "intno", ISR.INTNO[order_for_error], "CFG_INT")$$END$
+		$ELSE$
+$			// intnoに対してCFG_INTで設定された割込み優先度がTMIN_INTPRI
+$			// よりも小さい場合（E_OBJ）
+			$IF INT.INTPRI[intno] < TMIN_INTPRI$
+				$ERROR INT.TEXT_LINE[intno]$E_OBJ: $FORMAT(_("%1% `%2%\' configured for %3% `%4%\' is higher than %5%"), "intpri", INT.INTPRI[intno], "intno", ISR.INTNO[order_for_error], "TMIN_INTPRI")$$END$
+			$END$
+		$END$
+	$END$
+$END$
+
+$ 割込みサービスルーチン（ISR）管理のデータ構造
+$intno_isr_list = {}$
+$FOREACH intno INTNO_ATTISR_VALID$
+	$inhno = INHNO[intno]$
+	$IF LENGTH(INT.INTNO[intno]) && !LENGTH(INH.INHNO[inhno])$
+		$intno_isr_list = APPEND(intno_isr_list, intno)$
+	$END$
+$END$
+
+$INTNO_ISR = {}$
+$i = 0$
+$FOREACH intno SORT(intno_isr_list, "INT.INTNO")$
+	$INTNO_ISR = APPEND(INTNO_ISR, intno)$
+	$ISR_QUEUE_HEADER[intno] = FORMAT("&(_kernel_isr_queue_table[%d])", i)$
+	$i = i + 1$
+$END$
+
+const uint_t _kernel_tnum_isr_queue = $LENGTH(INTNO_ISR)$;$NL$
+$NL$
+
+$IF LENGTH(INTNO_ISR)$
+	const ISR_ENTRY _kernel_isr_queue_list[$LENGTH(INTNO_ISR)$] = {$NL$
+	$JOINEACH intno INTNO_ISR ",\n"$
+		$TAB${ $intno$, $ISR_QUEUE_HEADER[intno]$ }
+	$END$$NL$
+	};$NL$
+$ELSE$
+	TOPPERS_EMPTY_LABEL(QUEUE, _kernel_isr_queue_table);$NL$
+$END$$NL$
+
+$IF LENGTH(INTNO_ISR)$
+	QUEUE _kernel_isr_queue_table[$LENGTH(INTNO_ISR)$];$NL$
+$ELSE$
+	TOPPERS_EMPTY_LABEL(QUEUE, _kernel_isr_queue_table);$NL$
+$END$$NL$
+
+$ 割込みサービスルーチン（ISR）呼出しのための割込みハンドラの生成
+$FOREACH intno INTNO_ISR$
+	$inhno = INHNO[intno]$
+
+$	// DEF_INH(inhno, { TA_NULL, _kernel_inthdr_<intno> } );
+	$INH.INHNO[inhno] = inhno$
+	$INH.INHATR[inhno] = VALUE("TA_NULL", 0)$
+	$INH.INTHDR[inhno] = CONCAT("_kernel_inthdr_", intno)$
+	$INH.ORDER_LIST = APPEND(INH.ORDER_LIST, inhno)$
+
+$	// ISR用の割込みハンドラ
+	void$NL$
+	_kernel_inthdr_$intno$(void)$NL$
+	{$NL$
+	$TAB$i_begin_int($intno$);$NL$
+	$TAB$_kernel_call_isr($ISR_QUEUE_HEADER[intno]$);$NL$
+	$TAB$i_end_int($intno$);$NL$
+	}$NL$
+	$NL$
+$END$
+
+$ 割込みサービスルーチンの数
+#define TNUM_SISR	$LENGTH(ISR.ORDER_LIST)$$NL$
+#define TNUM_ISR	$LENGTH(ISR.ORDER_LIST) + num_aisrid$$NL$
+$NL$
+
+$ 割込みサービスルーチンID番号の最大値
+const ID _kernel_tmax_isrid = (TMIN_ISRID + TNUM_ISRID - 1);$NL$
+const uint_t _kernel_tnum_sisr = TNUM_SISR;$NL$
+$NL$
+
+$ 割込みサービスルーチン初期化ブロックの生成
+$IF LENGTH(ISR.ORDER_LIST)$
+	const ISRINIB _kernel_sisrinib_table[TNUM_SISR] = {$NL$
+	$JOINEACH order ISR.ORDER_LIST ",\n"$
+		$TAB${ ($ISR.ISRATR[order]$), (intptr_t)($ISR.EXINF[order]$), ($ISR.INTNO[order]$), ($ISR_QUEUE_HEADER[ISR.INTNO[order]]$), ($ISR.ISR[order]$), ($ISR.ISRPRI[order]$) }
+	$END$$NL$
+	};$NL$
+$ELSE$
+	TOPPERS_EMPTY_LABEL(const ISRINIB, _kernel_sisrinib_table);$NL$
+$END$
+$NL$
+
+$ 動的生成割込みサービスルーチン用の割込みサービスルーチン初期化ブロッ
+$ クの生成
+$IF num_aisrid > 0$
+	ISRINIB _kernel_aisrinib_table[$num_aisrid$];$NL$
+$ELSE$
+	TOPPERS_EMPTY_LABEL(ISRINIB, _kernel_aisrinib_table);$NL$
+$END$
+$NL$
+
+$ 割込みサービスルーチン管理ブロックの生成
+$IF num_isr > 0$
+	ISRCB _kernel_isrcb_table[TNUM_ISR];$NL$
+$ELSE$
+	TOPPERS_EMPTY_LABEL(ISRCB, _kernel_isrcb_table);$NL$
+$END$
+$NL$
+
+$ 
+$  割込み管理機能のための標準的な初期化情報の生成
+$ 
+$ 割込みハンドラの初期化に必要な情報
+$IF !OMIT_INITIALIZE_INTERRUPT || ALT(USE_INHINIB_TABLE,0)$
+
+$ 割込みハンドラ数
+#define TNUM_INHNO	$LENGTH(INH.ORDER_LIST)$$NL$
+const uint_t _kernel_tnum_inhno = TNUM_INHNO;$NL$
+$NL$
+$FOREACH inhno INH.ORDER_LIST$
+	$IF (INH.INHATR[inhno] & TA_NONKERNEL) == 0$
+		INTHDR_ENTRY($INH.INHNO[inhno]$, $+INH.INHNO[inhno]$, $INH.INTHDR[inhno]$)$NL$
+	$END$
+$END$
+$NL$
+
+$ 割込みハンドラ初期化ブロック
+$IF LENGTH(INH.ORDER_LIST)$
+	const INHINIB _kernel_inhinib_table[TNUM_INHNO] = {$NL$
+	$JOINEACH inhno INH.ORDER_LIST ",\n"$
+		$IF (INH.INHATR[inhno] & TA_NONKERNEL) == 0$
+			$TAB${ ($INH.INHNO[inhno]$), ($INH.INHATR[inhno]$), (FP)(INT_ENTRY($INH.INHNO[inhno]$, $INH.INTHDR[inhno]$)) }
+		$ELSE$
+			$TAB${ ($INH.INHNO[inhno]$), ($INH.INHATR[inhno]$), (FP)($INH.INTHDR[inhno]$) }
+		$END$
+	$END$$NL$
+	};$NL$
+$ELSE$
+	TOPPERS_EMPTY_LABEL(const INHINIB, _kernel_inhinib_table);$NL$
+$END$$NL$
+$END$
+
+$ 割込み要求ラインの初期化に必要な情報
+$IF !OMIT_INITIALIZE_INTERRUPT || ALT(USE_INTINIB_TABLE,0)$
+
+$ 割込み要求ライン数
+#define TNUM_INTNO	$LENGTH(INT.ORDER_LIST)$$NL$
+const uint_t _kernel_tnum_intno = TNUM_INTNO;$NL$
+$NL$
+
+$ 割込み要求ライン初期化ブロック
+$IF LENGTH(INT.ORDER_LIST)$
+	const INTINIB _kernel_intinib_table[TNUM_INTNO] = {$NL$
+	$JOINEACH intno INT.ORDER_LIST ",\n"$
+		$TAB${ ($INT.INTNO[intno]$), ($INT.INTATR[intno]$), ($INT.INTPRI[intno]$) }
+	$END$$NL$
+	};$NL$
+$ELSE$
+	TOPPERS_EMPTY_LABEL(const INTINIB, _kernel_intinib_table);$NL$
+$END$$NL$
+$END$
+
+$ 
+$  CPU例外管理機能
+$ 
+/*$NL$
+$SPC$*  CPU Exception Management Functions$NL$
+$SPC$*/$NL$
+$NL$
+
+$ CPU例外ハンドラに関するエラーチェック
+$i = 0$
+$FOREACH excno EXC.ORDER_LIST$
+$	// excnoがDEF_EXCに対するCPU例外ハンドラ番号として正しくない場合（E_PAR）
+	$IF !LENGTH(FIND(EXCNO_DEFEXC_VALID, EXC.EXCNO[excno]))$
+		$ERROR EXC.TEXT_LINE[excno]$E_PAR: $FORMAT(_("illegal %1% `%2%\' in %3%"), "excno", EXC.EXCNO[excno], "DEF_EXC")$$END$
+	$END$
+
+$	// excnoがDEF_EXCによって設定済みの場合（E_OBJ）
+	$j = 0$
+	$FOREACH excno2 EXC.ORDER_LIST$
+		$IF j < i && EXC.EXCNO[excno] == EXC.EXCNO[excno2]$
+			$ERROR EXC.TEXT_LINE[excno]$E_OBJ: $FORMAT(_("%1% `%2%\' in %3% is duplicated"), "excno", EXC.EXCNO[excno], "DEF_EXC")$$END$
+		$END$
+		$j = j + 1$
+	$END$
+
+$	// excatrが（TA_NULL）でない場合（E_RSATR）
+	$IF (EXC.EXCATR[excno] & ~TARGET_EXCATR) != 0$
+		$ERROR EXC.TEXT_LINE[excno]$E_RSATR: $FORMAT(_("illegal %1% `%2%\' of %3% `%4%\' in %5%"), "excatr", EXC.EXCATR[excno], "excno", EXC.EXCNO[excno], "DEF_EXC")$$END$
+	$END$
+	$i = i + 1$
+$END$
+
+$ CPU例外ハンドラのための標準的な初期化情報の生成
+$IF !OMIT_INITIALIZE_EXCEPTION$
+
+$ CPU例外ハンドラ数
+#define TNUM_EXCNO	$LENGTH(EXC.ORDER_LIST)$$NL$
+const uint_t _kernel_tnum_excno = TNUM_EXCNO;$NL$
+$NL$
+$FOREACH excno EXC.ORDER_LIST$
+	EXCHDR_ENTRY($EXC.EXCNO[excno]$, $+EXC.EXCNO[excno]$, $EXC.EXCHDR[excno]$)$NL$
+$END$
+$NL$
+
+$ CPU例外ハンドラ初期化ブロック
+$IF LENGTH(EXC.ORDER_LIST)$
+	const EXCINIB _kernel_excinib_table[TNUM_EXCNO] = {$NL$
+	$JOINEACH excno EXC.ORDER_LIST ",\n"$
+		$TAB${ ($EXC.EXCNO[excno]$), ($EXC.EXCATR[excno]$), (FP)(EXC_ENTRY($EXC.EXCNO[excno]$, $EXC.EXCHDR[excno]$)) }
+	$END$$NL$
+	};$NL$
+$ELSE$
+	TOPPERS_EMPTY_LABEL(const EXCINIB, _kernel_excinib_table);$NL$
+$END$$NL$
+$END$
+
+$ 
+$  非タスクコンテキスト用のスタック領域
+$ 
+/*$NL$
+$SPC$*  Stack Area for Non-task Context$NL$
+$SPC$*/$NL$
+$NL$
+
+$IF !LENGTH(ICS.ORDER_LIST)$
+$	// DEF_ICSがない場合のデフォルト値の設定
+	#ifdef DEFAULT_ISTK$NL$
+	$NL$
+	#define TOPPERS_ISTKSZ		DEFAULT_ISTKSZ$NL$
+	#define TOPPERS_ISTK		DEFAULT_ISTK$NL$
+	$NL$
+	#else /* DEAULT_ISTK */$NL$
+	$NL$
+	$istksz = ALLOC_STACK("_kernel_istack", "DEFAULT_ISTKSZ")$$NL$
+	#define TOPPERS_ISTKSZ		$istksz$$NL$
+	#define TOPPERS_ISTK		_kernel_istack$NL$
+	$NL$
+	#endif /* DEAULT_ISTK */$NL$
+$ELSE$
+
+$	// 静的API「DEF_ICS」が複数ある（E_OBJ）
+	$IF LENGTH(ICS.ORDER_LIST) > 1$
+		$ERROR$E_OBJ: $FORMAT(_("too many %1%"), "DEF_ICS")$$END$
+	$END$
+
+$	// istkszが0以下か，ターゲット定義の最小値（TARGET_MIN_ISTKSZ）よりも
+$	// 小さい場合（E_PAR）
+	$IF ICS.ISTKSZ[1] <= 0 || (TARGET_MIN_ISTKSZ
+									&& ICS.ISTKSZ[1] < TARGET_MIN_ISTKSZ)$
+		$ERROR ICS.TEXT_LINE[1]$E_PAR: $FORMAT(_("too small %1% `%2%\' in %3%"), "istksz", ICS.ISTKSZ[1], "DEF_ICS")$$END$
+	$END$
+
+$ 	// istkszがスタック領域のサイズとして正しくない場合（E_PAR）
+	$IF !EQ(ICS.ISTK[1], "NULL") && CHECK_STKSZ_ALIGN
+							&& (ICS.ISTKSZ[1] & (CHECK_STKSZ_ALIGN - 1))$
+		$ERROR ICS.TEXT_LINE[1]$E_PAR: $FORMAT(_("%1% `%2%\' in %3% is not aligned"), "istksz", ICS.ISTKSZ[1], "DEF_ICS")$$END$
+	$END$
+
+	$IF EQ(ICS.ISTK[1], "NULL")$
+$		// スタック領域の自動割付け
+		$istksz = ALLOC_STACK("_kernel_istack", ICS.ISTKSZ[1])$$NL$
+		#define TOPPERS_ISTKSZ		$istksz$$NL$
+		#define TOPPERS_ISTK		_kernel_istack$NL$
+	$ELSE$
+		#define TOPPERS_ISTKSZ		($ICS.ISTKSZ[1]$)$NL$
+		#define TOPPERS_ISTK		(void *)($ICS.ISTK[1]$)$NL$
+	$END$
+$END$
+$NL$
+
+$ 非タスクコンテキスト用のスタック領域
+const SIZE		_kernel_istksz = TOPPERS_ISTKSZ;$NL$
+STK_T *const	_kernel_istk = TOPPERS_ISTK;$NL$
+$NL$
+#ifdef TOPPERS_ISTKPT$NL$
+STK_T *const	_kernel_istkpt = TOPPERS_ISTKPT(TOPPERS_ISTK, TOPPERS_ISTKSZ);$NL$
+#endif /* TOPPERS_ISTKPT */$NL$
+$NL$
+
+$ 
+$  カーネルが割り付けるメモリ領域
+$ 
+/*$NL$
+$SPC$*  Memory Area Allocated by Kernel$NL$
+$SPC$*/$NL$
+$NL$
+
+$IF !LENGTH(KMM.ORDER_LIST)$
+$	// DEF_KMMがない場合のデフォルト値の設定
+	#define TOPPERS_KMMSZ		0$NL$
+	#define TOPPERS_KMM			NULL$NL$
+$ELSE$
+$	// 静的API「DEF_KMM」が複数ある（E_OBJ）
+	$IF LENGTH(KMM.ORDER_LIST) > 1$
+		$ERROR$E_OBJ: $FORMAT(_("too many %1%"), "DEF_KMM")$$END$
+	$END$
+
+$	// kmmszが0以下の場合（E_PAR）
+	$IF KMM.KMMSZ[1] <= 0$
+		$ERROR KMM.TEXT_LINE[1]$E_PAR: $FORMAT(_("%1% `%2%\' is zero in %3%"), "kmmsz", KMM.KMMSZ[1], "DEF_KMM")$$END$
+	$END$
+
+$ 	// kmmszがカーネルが割り付けるメモリ領域のサイズとして正しくない場合（E_PAR）
+	$IF !EQ(KMM.KMM[1], "NULL") && CHECK_MB_ALIGN
+							&& (KMM.KMMSZ[1] & (CHECK_MB_ALIGN - 1))$
+		$ERROR KMM.TEXT_LINE[1]$E_PAR: $FORMAT(_("%1% `%2%\' in %3% is not aligned"), "kmmsz", KMM.KMMSZ[1], "DEF_KMM")$$END$
+	$END$
+
+	$IF EQ(KMM.KMM[1], "NULL")$
+$		// カーネルが割り付けるメモリ領域の自動割付け
+		static MB_T					_kernel_memory[TOPPERS_COUNT_SZ($KMM.KMMSZ[1]$, sizeof(MB_T))];$NL$
+		#define TOPPERS_KMMSZ		TOPPERS_ROUND_SZ($KMM.KMMSZ[1]$, sizeof(MB_T))$NL$
+		#define TOPPERS_KMM			_kernel_memory$NL$
+	$ELSE$
+		#define TOPPERS_KMMSZ		($KMM.KMMSZ[1]$)$NL$
+		#define TOPPERS_KMM			(void *)($KMM.KMM[1]$)$NL$
+	$END$
+$END$
+$NL$
+
+$ カーネルが割り付けるメモリ領域
+const SIZE		_kernel_kmmsz = TOPPERS_KMMSZ;$NL$
+MB_T *const		_kernel_kmm = TOPPERS_KMM;$NL$
+$NL$
+
+$ 
+$  タイムイベント管理
+$ 
+/*$NL$
+$SPC$*  Time Event Management$NL$
+$SPC$*/$NL$
+$NL$
+TMEVTN   _kernel_tmevt_heap[TNUM_TSKID + TNUM_CYCID + TNUM_ALMID];$NL$
+$NL$
+
+$ 
+$  各モジュールの初期化関数
+$ 
+/*$NL$
+$SPC$*  Module Initialization Function$NL$
+$SPC$*/$NL$
+$NL$
+void$NL$
+_kernel_initialize_object(void)$NL$
+{$NL$
+$TAB$_kernel_initialize_task();$NL$
+$IF num_semid$$TAB$_kernel_initialize_semaphore();$NL$$END$
+$IF num_flgid$$TAB$_kernel_initialize_eventflag();$NL$$END$
+$IF num_dtqid$$TAB$_kernel_initialize_dataqueue();$NL$$END$
+$IF num_pdqid$$TAB$_kernel_initialize_pridataq();$NL$$END$
+$IF num_mbxid$$TAB$_kernel_initialize_mailbox();$NL$$END$
+$IF num_mpfid$$TAB$_kernel_initialize_mempfix();$NL$$END$
+$IF num_cycid$$TAB$_kernel_initialize_cyclic();$NL$$END$
+$IF num_almid$$TAB$_kernel_initialize_alarm();$NL$$END$
+$TAB$_kernel_initialize_interrupt();$NL$
+$IF num_isr$$TAB$_kernel_initialize_isr();$NL$$END$
+$TAB$_kernel_initialize_exception();$NL$
+}$NL$
+$NL$
+
+$ 
+$  初期化ルーチンの実行関数
+$ 
+/*$NL$
+$SPC$*  Initialization Routine$NL$
+$SPC$*/$NL$
+$NL$
+void$NL$
+_kernel_call_inirtn(void)$NL$
+{$NL$
+$FOREACH order INI.ORDER_LIST$
+$ 	// iniatrが（TA_NULL）でない場合（E_RSATR）
+	$IF INI.INIATR[order] != 0$
+		$ERROR INI.TEXT_LINE[order]$E_RSATR: $FORMAT(_("illegal %1% `%2%\' of %3% `%4%\' in %5%"), "iniatr", INI.INIATR[order], "inirtn", INI.INIRTN[order], "ATT_INI")$$END$
+	$END$
+	$TAB$((INIRTN)($INI.INIRTN[order]$))((intptr_t)($INI.EXINF[order]$));$NL$
+$END$
+}$NL$
+$NL$
+
+$ 
+$  終了処理ルーチンの実行関数
+$ 
+/*$NL$
+$SPC$*  Termination Routine$NL$
+$SPC$*/$NL$
+$NL$
+void$NL$
+_kernel_call_terrtn(void)$NL$
+{$NL$
+$FOREACH rorder TER.RORDER_LIST$
+$ 	// teratrが（TA_NULL）でない場合（E_RSATR）
+	$IF TER.TERATR[rorder] != 0$
+		$ERROR TER.TEXT_LINE[rorder]$E_RSATR: $FORMAT(_("illegal %1% `%2%\' of %3% `%4%\' in %5%"), "teratr", TER.TERATR[rorder], "terrtn", TER.TERRTN[rorder], "ATT_TER")$$END$
+	$END$
+	$TAB$((TERRTN)($TER.TERRTN[rorder]$))((intptr_t)($TER.EXINF[rorder]$));$NL$
+$END$
+}$NL$
+$NL$
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/kernel/kernel_api.csv
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/kernel/kernel_api.csv	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/kernel/kernel_api.csv	(revision 457)
@@ -0,0 +1,30 @@
+tsk,CRE_TSK,#tskid { .tskatr &exinf &task +itskpri .stksz &stk },,
+tsk,DEF_TEX,%tskid { .texatr &texrtn },0,1
+atsk,AID_TSK,.notsk,,
+sem,CRE_SEM,#semid { .sematr .isemcnt .maxsem },,
+asem,AID_SEM,.nosem,,
+flg,CRE_FLG,#flgid { .flgatr .iflgptn },,
+aflg,AID_FLG,.nosem,,
+dtq,CRE_DTQ,#dtqid { .dtqatr .dtqcnt &dtqmb },,
+adtq,AID_DTQ,.nodtq,,
+pdq,CRE_PDQ,#pdqid { .pdqatr .pdqcnt +maxdpri &pdqmb },,
+apdq,AID_PDQ,.nopdq,,
+mbx,CRE_MBX,#mbxid { .mbxatr +maxmpri &mprihd },,
+ambx,AID_MBX,.nombx,,
+mtx,CRE_MTX,#mtxid { .mtxatr +ceilpri? },,
+amtx,AID_MTX,.nomtx,,
+mpf,CRE_MPF,#mpfid { .mpfatr .blkcnt .blksz &mpf &mpfmb },,
+ampf,AID_MPF,.nompf,,
+cyc,CRE_CYC,#cycid { .cycatr &exinf &cychdr .cyctim .cycphs },,
+acyc,AID_CYC,.nocyc,,
+alm,CRE_ALM,#almid { .almatr &exinf &almhdr },,
+aalm,AID_ALM,.noalm,,
+int,CFG_INT,.intno { .intatr +intpri },,
+isr,ATT_ISR,{ .isratr &exinf .intno &isr +isrpri },-1,
+aisr,AID_ISR,.noisr,,
+inh,DEF_INH,.inhno { .inhatr &inthdr },,
+exc,DEF_EXC,.excno { .excatr &exchdr },,
+ics,DEF_ICS,{ .istksz &istk },-1,
+kmm,DEF_KMM,{ .kmmsz &kmm },-1,
+ini,ATT_INI,{ .iniatr &exinf &inirtn },-1,
+ter,ATT_TER,{ .teratr &exinf &terrtn },-1,
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/kernel/kernel_check.tf
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/kernel/kernel_check.tf	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/kernel/kernel_check.tf	(revision 457)
@@ -0,0 +1,212 @@
+$ ======================================================================
+$ 
+$   TOPPERS/ASP Kernel
+$       Toyohashi Open Platform for Embedded Real-Time Systems/
+$       Advanced Standard Profile Kernel
+$ 
+$   Copyright (C) 2008-2010 by Embedded and Real-Time Systems Laboratory
+$               Graduate School of Information Science, Nagoya Univ., JAPAN
+$  
+$   上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+$   ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+$   変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+$   (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+$       権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+$       スコード中に含まれていること．
+$   (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+$       用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+$       者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+$       の無保証規定を掲載すること．
+$   (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+$       用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+$       と．
+$     (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+$         作権表示，この利用条件および下記の無保証規定を掲載すること．
+$     (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+$         報告すること．
+$   (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+$       害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+$       また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+$       由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+$       免責すること．
+$  
+$   本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+$   よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+$   に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+$   アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+$   の責任を負わない．
+$ 
+$   @(#) $Id$
+$  
+$ =====================================================================
+
+$
+$  データセクションのLMAからVMAへのコピー
+$
+$FOREACH lma LMA.ORDER_LIST$
+	$start_data = SYMBOL(LMA.START_DATA[lma])$
+	$end_data = SYMBOL(LMA.END_DATA[lma])$
+	$start_idata = SYMBOL(LMA.START_IDATA[lma])$
+	$IF !LENGTH(start_data)$
+		$ERROR$$FORMAT(_("symbol '%1%' not found"), LMA.START_DATA[lma])$$END$
+	$ELIF !LENGTH(end_data)$
+		$ERROR$$FORMAT(_("symbol '%1%' not found"), LMA.END_DATA[lma])$$END$
+	$ELIF !LENGTH(start_idata)$
+		$ERROR$$FORMAT(_("symbol '%1%' not found"), LMA.START_IDATA[lma])$$END$
+	$ELSE$
+		$BCOPY(start_idata, start_data, end_data - start_data)$
+	$END$
+$END$
+
+$ 
+$  関数の先頭番地のチェック
+$ 
+$IF CHECK_FUNC_ALIGN || CHECK_FUNC_NONNULL$
+$	// タスクとタスク例外処理ルーチンの先頭番地のチェック
+	$tinib = SYMBOL("_kernel_tinib_table")$
+	$FOREACH tskid TSK.ID_LIST$
+		$task = PEEK(tinib + offsetof_TINIB_task, sizeof_FP)$
+		$IF CHECK_FUNC_ALIGN && (task & (CHECK_FUNC_ALIGN - 1)) != 0$
+			$ERROR TSK.TEXT_LINE[tskid]$E_PAR: 
+				$FORMAT(_("%1% `%2%\' of `%3%\' in %4% is not aligned"),
+				"task", TSK.TASK[tskid], tskid, "CRE_TSK")$$END$
+		$END$
+		$IF CHECK_FUNC_NONNULL && task == 0$
+			$ERROR TSK.TEXT_LINE[tskid]$E_PAR: 
+				$FORMAT(_("%1% `%2%\' of `%3%\' in %4% is null"),
+				"task", TSK.TASK[tskid], tskid, "CRE_TSK")$$END$
+		$END$
+		$texrtn = PEEK(tinib + offsetof_TINIB_texrtn, sizeof_FP)$
+		$IF CHECK_FUNC_ALIGN && (texrtn & (CHECK_FUNC_ALIGN - 1)) != 0$
+			$ERROR DEF_TEX.TEXT_LINE[tskid]$E_PAR: 
+				$FORMAT(_("%1% `%2%\' of `%3%\' in %4% is not aligned"),
+				"texrtn", TSK.TEXRTN[tskid], tskid, "DEF_TEX")$$END$
+		$END$
+		$tinib = tinib + sizeof_TINIB$
+	$END$
+
+$	// 周期ハンドラの先頭番地のチェック
+	$cycinib = SYMBOL("_kernel_cycinib_table")$
+	$FOREACH cycid CYC.ID_LIST$
+		$cychdr = PEEK(cycinib + offsetof_CYCINIB_cychdr, sizeof_FP)$
+		$IF CHECK_FUNC_ALIGN && (cychdr & (CHECK_FUNC_ALIGN - 1)) != 0$
+			$ERROR CYC.TEXT_LINE[cycid]$E_PAR: 
+				$FORMAT(_("%1% `%2%\' of `%3%\' in %4% is not aligned"),
+				"cychdr", CYC.CYCHDR[cycid], cycid, "CRE_CYC")$$END$
+		$END$
+		$IF CHECK_FUNC_NONNULL && cychdr == 0$
+			$ERROR CYC.TEXT_LINE[cycid]$E_PAR: 
+				$FORMAT(_("%1% `%2%\' of `%3%\' in %4% is null"),
+				"cychdr", CYC.CYCHDR[cycid], cycid, "CRE_CYC")$$END$
+		$END$
+		$cycinib = cycinib + sizeof_CYCINIB$
+	$END$
+
+$	// アラームハンドラの先頭番地のチェック
+	$alminib = SYMBOL("_kernel_alminib_table")$
+	$FOREACH almid ALM.ID_LIST$
+		$almhdr = PEEK(alminib + offsetof_ALMINIB_almhdr, sizeof_FP)$
+		$IF CHECK_FUNC_ALIGN && (almhdr & (CHECK_FUNC_ALIGN - 1)) != 0$
+			$ERROR ALM.TEXT_LINE[almid]$E_PAR: 
+				$FORMAT(_("%1% `%2%\' of `%3%\' in %4% is not aligned"),
+				"almhdr", ALM.ALMHDR[almid], almid, "CRE_ALM")$$END$
+		$END$
+		$IF CHECK_FUNC_NONNULL && almhdr == 0$
+			$ERROR ALM.TEXT_LINE[almid]$E_PAR: 
+				$FORMAT(_("%1% `%2%\' of `%3%\' in %4% is null"),
+				"almhdr", ALM.ALMHDR[almid], almid, "CRE_ALM")$$END$
+		$END$
+		$alminib = alminib + sizeof_ALMINIB$
+	$END$
+
+$	// 割込みサービスルーチンの先頭番地のチェック
+	$isrinib = SYMBOL("_kernel_sisrinib_table")$
+	$FOREACH order ISR.ORDER_LIST$
+		$isr = PEEK(isrinib + offsetof_ISRINIB_isr, sizeof_FP)$
+		$IF CHECK_FUNC_ALIGN && (isr & (CHECK_FUNC_ALIGN - 1)) != 0$
+			$ERROR ISR.TEXT_LINE[order]$E_PAR: 
+				$FORMAT(_("%1% `%2%\' in %4% is not aligned"),
+				"isr", ISR.ISR[order], "ATT_ISR")$$END$
+		$END$
+		$IF CHECK_FUNC_NONNULL && isr == 0$
+			$ERROR ISR.TEXT_LINE[order]$E_PAR: 
+				$FORMAT(_("%1% `%2%\' in %4% is null"),
+				"isr", ISR.ISR[order], "ATT_ISR")$$END$
+		$END$
+		$isrinib = isrinib + sizeof_ISRINIB$
+	$END$
+$END$
+
+$ 
+$  スタック領域の先頭番地のチェック
+$ 
+$IF CHECK_STACK_ALIGN || CHECK_STACK_NONNULL$
+$	// タスクのスタック領域の先頭番地のチェック
+	$tinib = SYMBOL("_kernel_tinib_table")$
+	$FOREACH tskid TSK.ID_LIST$
+		$IF USE_TSKINICTXB$
+			$stk = GET_STK_TSKINICTXB(tinib)$
+		$ELSE$
+			$stk = PEEK(tinib + offsetof_TINIB_stk, sizeof_void_ptr)$
+		$END$
+		$IF CHECK_STACK_ALIGN && (stk & (CHECK_STACK_ALIGN - 1)) != 0$
+			$ERROR TSK.TEXT_LINE[tskid]$E_PAR: 
+				$FORMAT(_("%1% `%2%\' of `%3%\' in %4% is not aligned"),
+				"stk", TSK.STK[tskid], tskid, "CRE_TSK")$$END$
+		$END$
+		$IF CHECK_STACK_NONNULL && stk == 0$
+			$ERROR TSK.TEXT_LINE[tskid]$E_PAR: 
+				$FORMAT(_("%1% `%2%\' of `%3%\' in %4% is null"),
+				"stk", TSK.STK[tskid], tskid, "CRE_TSK")$$END$
+		$END$
+		$tinib = tinib + sizeof_TINIB$
+	$END$
+
+$	// 非タスクコンテキスト用のスタック領域の先頭番地のチェック
+	$istk = PEEK(SYMBOL("_kernel_istk"), sizeof_void_ptr)$
+	$IF CHECK_STACK_ALIGN && (istk & (CHECK_STACK_ALIGN - 1)) != 0$
+		$ERROR ICS.TEXT_LINE[1]$E_PAR: 
+			$FORMAT(_("%1% `%2%\' in %3% is not aligned"),
+			"istk", ICS.ISTK[1], "DEF_ICS")$$END$
+	$END$
+	$IF CHECK_STACK_NONNULL && istk == 0$
+		$ERROR ICS.TEXT_LINE[1]$E_PAR: 
+			$FORMAT(_("%1% `%2%\' in %3% is null"),
+			"istk", ICS.ISTK[1], "DEF_ICS")$$END$
+	$END$
+$END$
+
+$ 
+$  固定長メモリプール領域の先頭番地のチェック
+$ 
+$IF CHECK_MPF_ALIGN || CHECK_MPF_NONNULL$
+$	// 固定長メモリプール領域の先頭番地のチェック
+	$mpfinib = SYMBOL("_kernel_mpfinib_table")$
+	$FOREACH mpfid MPF.ID_LIST$
+		$mpf = PEEK(mpfinib + offsetof_MPFINIB_mpf, sizeof_void_ptr)$
+		$IF CHECK_MPF_ALIGN && (mpf & (CHECK_MPF_ALIGN - 1)) != 0$
+			$ERROR MPF.TEXT_LINE[mpfid]$E_PAR: 
+				$FORMAT(_("%1% `%2%\' of `%3%\' in %4% is not aligned"),
+				"mpf", MPF.MPF[mpfid], mpfid, "CRE_MPF")$$END$
+		$END$
+		$IF CHECK_MPF_NONNULL && mpf == 0$
+			$ERROR MPF.TEXT_LINE[mpfid]$E_PAR: 
+				$FORMAT(_("%1% `%2%\' of `%3%\' in %4% is null"),
+				"mpf", MPF.MPF[mpfid], mpfid, "CRE_MPF")$$END$
+		$END$
+		$mpfinib = mpfinib + sizeof_MPFINIB$
+	$END$
+$END$
+
+$ 
+$  カーネルが割り付けるメモリ領域の先頭番地のチェック
+$ 
+$IF CHECK_MB_ALIGN$
+$	// カーネルが割り付けるメモリ領域の先頭番地のチェック
+	$kmm = PEEK(SYMBOL("_kernel_kmm"), sizeof_void_ptr)$
+	$IF CHECK_MB_ALIGN && (kmm & (CHECK_MB_ALIGN - 1)) != 0$
+		$ERROR KMM.TEXT_LINE[1]$E_PAR: 
+			$FORMAT(_("%1% `%2%\' in %3% is not aligned"),
+			"kmm", KMM.KMM[1], "DEF_KMM")$$END$
+	$END$
+$END$
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/kernel/kernel_def.csv
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/kernel/kernel_def.csv	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/kernel/kernel_def.csv	(revision 457)
@@ -0,0 +1,123 @@
+SIL_ENDIAN_BIG,#defined(SIL_ENDIAN_BIG)
+SIL_ENDIAN_LITTLE,#defined(SIL_ENDIAN_LITTLE)
+TA_NULL,TA_NULL
+TA_ACT,TA_ACT
+TA_TPRI,TA_TPRI
+TA_MPRI,TA_MPRI
+TA_WMUL,TA_WMUL
+TA_CLR,TA_CLR
+TA_CEILING,TA_CEILING
+TA_STA,TA_STA
+TA_NONKERNEL,TA_NONKERNEL
+TA_ENAINT,TA_ENAINT
+TA_EDGE,TA_EDGE
+TMIN_TPRI,TMIN_TPRI,signed
+TMAX_TPRI,TMAX_TPRI,signed
+TMIN_DPRI,TMIN_DPRI,signed
+TMAX_DPRI,TMAX_DPRI,signed
+TMIN_MPRI,TMIN_MPRI,signed
+TMAX_MPRI,TMAX_MPRI,signed
+TMIN_ISRPRI,TMIN_ISRPRI,signed
+TMAX_ISRPRI,TMAX_ISRPRI,signed
+TBIT_TEXPTN,TBIT_TEXPTN
+TBIT_FLGPTN,TBIT_FLGPTN
+TMAX_MAXSEM,TMAX_MAXSEM
+TMAX_RELTIM,TMAX_RELTIM
+TMIN_INTPRI,TMIN_INTPRI,signed
+OMIT_INITIALIZE_INTERRUPT,#defined(OMIT_INITIALIZE_INTERRUPT)
+OMIT_INITIALIZE_EXCEPTION,#defined(OMIT_INITIALIZE_EXCEPTION)
+USE_TSKINICTXB,#defined(USE_TSKINICTXB)
+TARGET_TSKATR,#defined(TARGET_TSKATR),,TARGET_TSKATR
+TARGET_INTATR,#defined(TARGET_INTATR),,TARGET_INTATR
+TARGET_INHATR,#defined(TARGET_INHATR),,TARGET_INHATR
+TARGET_ISRATR,#defined(TARGET_ISRATR),,TARGET_ISRATR
+TARGET_EXCATR,#defined(TARGET_EXCATR),,TARGET_EXCATR
+TARGET_MIN_STKSZ,#defined(TARGET_MIN_STKSZ),,TARGET_MIN_STKSZ
+TARGET_MIN_ISTKSZ,#defined(TARGET_MIN_ISTKSZ),,TARGET_MIN_ISTKSZ
+CHECK_STKSZ_ALIGN,#defined(CHECK_STKSZ_ALIGN),,CHECK_STKSZ_ALIGN
+CHECK_FUNC_ALIGN,#defined(CHECK_FUNC_ALIGN),,CHECK_FUNC_ALIGN
+CHECK_FUNC_NONNULL,#defined(CHECK_FUNC_NONNULL)
+CHECK_STACK_ALIGN,#defined(CHECK_STACK_ALIGN),,CHECK_STACK_ALIGN
+CHECK_STACK_NONNULL,#defined(CHECK_STACK_NONNULL)
+CHECK_MPF_ALIGN,#defined(CHECK_MPF_ALIGN),,CHECK_MPF_ALIGN
+CHECK_MPF_NONNULL,#defined(CHECK_MPF_NONNULL)
+CHECK_MB_ALIGN,#defined(CHECK_MB_ALIGN),,CHECK_MB_ALIGN
+sizeof_ID,sizeof(ID)
+sizeof_uint_t,sizeof(uint_t)
+sizeof_SIZE,sizeof(SIZE)
+sizeof_ATR,sizeof(ATR)
+sizeof_PRI,sizeof(PRI)
+sizeof_void_ptr,sizeof(void*)
+sizeof_VP,sizeof(void*)
+sizeof_intptr_t,sizeof(intptr_t)
+sizeof_FP,sizeof(FP)
+sizeof_INHNO,sizeof(INHNO)
+sizeof_INTNO,sizeof(INTNO)
+sizeof_EXCNO,sizeof(EXCNO)
+sizeof_TINIB,sizeof(TINIB)
+offsetof_TINIB_tskatr,"offsetof(TINIB,tskatr)"
+offsetof_TINIB_exinf,"offsetof(TINIB,exinf)"
+offsetof_TINIB_task,"offsetof(TINIB,task)"
+offsetof_TINIB_ipriority,"offsetof(TINIB,ipriority)"
+offsetof_TINIB_stksz,#!defined(USE_TSKINICTXB),,"offsetof(TINIB,stksz)"
+offsetof_TINIB_stk,#!defined(USE_TSKINICTXB),,"offsetof(TINIB,stk)"
+offsetof_TINIB_texatr,"offsetof(TINIB,texatr)"
+offsetof_TINIB_texrtn,"offsetof(TINIB,texrtn)"
+sizeof_SEMINIB,sizeof(SEMINIB)
+offsetof_SEMINIB_sematr,"offsetof(SEMINIB,sematr)"
+offsetof_SEMINIB_isemcnt,"offsetof(SEMINIB,isemcnt)"
+offsetof_SEMINIB_maxsem,"offsetof(SEMINIB,maxsem)"
+sizeof_FLGPTN,sizeof(FLGPTN)
+sizeof_FLGINIB,sizeof(FLGINIB)
+offsetof_FLGINIB_flgatr,"offsetof(FLGINIB,flgatr)"
+offsetof_FLGINIB_iflgptn,"offsetof(FLGINIB,iflgptn)"
+sizeof_DTQINIB,sizeof(DTQINIB)
+offsetof_DTQINIB_dtqatr,"offsetof(DTQINIB,dtqatr)"
+offsetof_DTQINIB_dtqcnt,"offsetof(DTQINIB,dtqcnt)"
+offsetof_DTQINIB_p_dtqmb,"offsetof(DTQINIB,p_dtqmb)"
+sizeof_PDQINIB,sizeof(PDQINIB)
+offsetof_PDQINIB_pdqatr,"offsetof(PDQINIB,pdqatr)"
+offsetof_PDQINIB_pdqcnt,"offsetof(PDQINIB,pdqcnt)"
+offsetof_PDQINIB_maxdpri,"offsetof(PDQINIB,maxdpri)"
+offsetof_PDQINIB_p_pdqmb,"offsetof(PDQINIB,p_pdqmb)"
+sizeof_MBXINIB,sizeof(MBXINIB)
+offsetof_MBXINIB_mbxatr,"offsetof(MBXINIB,mbxatr)"
+offsetof_MBXINIB_maxmpri,"offsetof(MBXINIB,maxmpri)"
+sizeof_MTXINIB,sizeof(MTXINIB)
+offsetof_MTXINIB_mtxatr,"offsetof(MTXINIB,mtxatr)"
+offsetof_MTXINIB_ceilpri,"offsetof(MTXINIB,ceilpri)"
+sizeof_MPFINIB,sizeof(MPFINIB)
+offsetof_MPFINIB_mpfatr,"offsetof(MPFINIB,mpfatr)"
+offsetof_MPFINIB_blkcnt,"offsetof(MPFINIB,blkcnt)"
+offsetof_MPFINIB_blksz,"offsetof(MPFINIB,blksz)"
+offsetof_MPFINIB_mpf,"offsetof(MPFINIB,mpf)"
+offsetof_MPFINIB_p_mpfmb,"offsetof(MPFINIB,p_mpfmb)"
+sizeof_CYCINIB,sizeof(CYCINIB)
+offsetof_CYCINIB_cycatr,"offsetof(CYCINIB,cycatr)"
+offsetof_CYCINIB_exinf,"offsetof(CYCINIB,exinf)"
+offsetof_CYCINIB_cychdr,"offsetof(CYCINIB,cychdr)"
+offsetof_CYCINIB_cyctim,"offsetof(CYCINIB,cyctim)"
+offsetof_CYCINIB_cycphs,"offsetof(CYCINIB,cycphs)"
+sizeof_ALMINIB,sizeof(ALMINIB)
+offsetof_ALMINIB_almatr,"offsetof(ALMINIB,almatr)"
+offsetof_ALMINIB_exinf,"offsetof(ALMINIB,exinf)"
+offsetof_ALMINIB_almhdr,"offsetof(ALMINIB,almhdr)"
+sizeof_ISRINIB,sizeof(ISRINIB)
+offsetof_ISRINIB_isratr,"offsetof(ISRINIB,isratr)"
+offsetof_ISRINIB_exinf,"offsetof(ISRINIB,exinf)"
+offsetof_ISRINIB_intno,"offsetof(ISRINIB,intno)"
+offsetof_ISRINIB_p_isr_queue,"offsetof(ISRINIB,p_isr_queue)"
+offsetof_ISRINIB_isr,"offsetof(ISRINIB,isr)"
+offsetof_ISRINIB_isrpri,"offsetof(ISRINIB,isrpri)"
+sizeof_INHINIB,#!defined(OMIT_INITIALIZE_INTERRUPT),,sizeof(INHINIB)
+offset_INHINIB_inhno,#!defined(OMIT_INITIALIZE_INTERRUPT),,"offsetof(INHINIB,inhno)"
+offset_INHINIB_inhatr,#!defined(OMIT_INITIALIZE_INTERRUPT),,"offsetof(INHINIB,inhatr)"
+offset_INHINIB_int_entry,#!defined(OMIT_INITIALIZE_INTERRUPT),,"offsetof(INHINIB,int_entry)"
+sizeof_INTINIB,#!defined(OMIT_INITIALIZE_INTERRUPT),,sizeof(INTINIB)
+offset_INTINIB_intno,#!defined(OMIT_INITIALIZE_INTERRUPT),,"offsetof(INTINIB,intno)"
+offset_INTINIB_intatr,#!defined(OMIT_INITIALIZE_INTERRUPT),,"offsetof(INTINIB,intatr)"
+offset_INTINIB_intpri,#!defined(OMIT_INITIALIZE_INTERRUPT),,"offsetof(INTINIB,intpri)"
+sizeof_EXCINIB,#!defined(OMIT_INITIALIZE_EXCEPTION),,sizeof(EXCINIB)
+offset_EXCINIB_excno,#!defined(OMIT_INITIALIZE_EXCEPTION),,"offsetof(EXCINIB,excno)"
+offset_EXCINIB_excatr,#!defined(OMIT_INITIALIZE_EXCEPTION),,"offsetof(EXCINIB,excatr)"
+offset_EXCINIB_exc_entry,#!defined(OMIT_INITIALIZE_EXCEPTION),,"offsetof(EXCINIB,exc_entry)"
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/kernel/kernel_impl.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/kernel/kernel_impl.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/kernel/kernel_impl.h	(revision 457)
@@ -0,0 +1,218 @@
+/*
+ *  TOPPERS/ASP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Advanced Standard Profile Kernel
+ * 
+ *  Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
+ *                              Toyohashi Univ. of Technology, JAPAN
+ *  Copyright (C) 2004-2010 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *		TOPPERS/ASPカーネル内部向け標準ヘッダファイル
+ *
+ *  このヘッダファイルは，カーネルを構成するプログラムのソースファイル
+ *  で必ずインクルードするべき標準ヘッダファイルである．
+ *
+ *  アセンブリ言語のソースファイルからこのファイルをインクルードする時
+ *  は，TOPPERS_MACRO_ONLYを定義しておく．これにより，マクロ定義以外を
+ *  除くようになっている．
+ */
+
+#ifndef TOPPERS_KERNEL_IMPL_H
+#define TOPPERS_KERNEL_IMPL_H
+
+/*
+ *  カーネルの内部識別名のリネーム
+ */
+#include "kernel_rename.h"
+
+/*
+ *  アプリケーションと共通のヘッダファイル
+ */
+#include <kernel.h>
+
+/*
+ *  システムログ機能のための定義
+ */
+#include <t_syslog.h>
+
+/*
+ *  型キャストを行うマクロの定義
+ */
+#ifndef CAST
+#define CAST(type, val)		((type)(val))
+#endif /* CAST */
+
+/*
+ *  ターゲット依存情報の定義
+ */
+#include "target_config.h"
+
+/*
+ *  すべての関数をコンパイルするための定義
+ */
+#ifdef ALLFUNC
+#include "allfunc.h"
+#endif /* ALLFUNC */
+
+/*
+ *  ビットフィールドでの符号無し整数型
+ *
+ *  8ビット以下の幅のビットフィールドで，符号無し整数値を保持したい場合
+ *  に用いるべきデータ型．ANSI Cでは，ビットフィールドのデータ型には
+ *  intとunsigned intしか許されないため，デフォルトの定義はunsigned
+ *  intとしているが，ターゲットおよびツール依存で，unsigned charまたは
+ *  unsigned shortに定義した方が効率が良い場合がある．
+ */
+#ifndef BIT_FIELD_UINT
+#define BIT_FIELD_UINT		unsigned int
+#endif /* BIT_FIELD_UINT */
+
+/*
+ *  ビットフィールドでのブール型
+ *
+ *  1ビット幅のビットフィールドで，ブール値を保持したい場合に用いるべき
+ *  データ型．デフォルトではBIT_FIELD_UINTと同一に定義しているが，ブー
+ *  ル値を保持することを明示するために別の名称としている．
+ */
+#ifndef BIT_FIELD_BOOL
+#define BIT_FIELD_BOOL		BIT_FIELD_UINT
+#endif /* BIT_FIELD_BOOL */
+
+/*
+ *  オブジェクトIDの最小値の定義
+ */
+#define TMIN_TSKID		1		/* タスクIDの最小値 */
+#define TMIN_SEMID		1		/* セマフォIDの最小値 */
+#define TMIN_FLGID		1		/* フラグIDの最小値 */
+#define TMIN_DTQID		1		/* データキューIDの最小値 */
+#define TMIN_PDQID		1		/* 優先度データキューIDの最小値 */
+#define TMIN_MBXID		1		/* メールボックスIDの最小値 */
+#define TMIN_MTXID		1		/* ミューテックスIDの最小値 */
+#define TMIN_MPFID		1		/* 固定長メモリプールIDの最小値 */
+#define TMIN_CYCID		1		/* 周期ハンドラIDの最小値 */
+#define TMIN_ALMID		1		/* アラームハンドラIDの最小値 */
+#define TMIN_ISRID		1		/* 割込みサービスルーチンIDの最小値 */
+
+/*
+ *  優先度の段階数の定義
+ */
+#define TNUM_TPRI		(TMAX_TPRI - TMIN_TPRI + 1)
+#define TNUM_MPRI		(TMAX_MPRI - TMIN_MPRI + 1)
+#define TNUM_INTPRI		(TMAX_INTPRI - TMIN_INTPRI + 1)
+
+/*
+ *  カーネル内部で使用する属性の定義
+ */
+#define TA_NOEXS		((ATR)(-1))			/* 未登録状態 */
+
+#ifndef TA_MEMALLOC
+#define TA_MEMALLOC		UINT_C(0x8000)		/* メモリ領域をカーネルで確保 */
+#endif /* TA_MEMALLOC */
+#ifndef TA_MBALLOC
+#define TA_MBALLOC		UINT_C(0x4000)		/* 管理領域をカーネルで確保 */
+#endif /* TA_MBALLOC */
+
+/*
+ *  ターゲット定義のエラーチェックマクロのデフォルト値の定義
+ */
+#ifndef TARGET_TSKATR
+#define TARGET_TSKATR		0U		/* ターゲット定義のタスク属性 */
+#endif /* TARGET_TSKATR */
+
+#ifndef TARGET_ISRATR
+#define TARGET_ISRATR		0U		/* ターゲット定義のISR属性 */
+#endif /* TARGET_ISRATR */
+
+/*
+ *  ヘッダファイルを持たないモジュールの関数・変数の宣言
+ */
+#ifndef TOPPERS_MACRO_ONLY
+
+/*
+ *  各モジュールの初期化（kernel_cfg.c）
+ */
+extern void	initialize_object(void);
+
+/*
+ *  初期化ルーチンの実行（kernel_cfg.c）
+ */
+extern void	call_inirtn(void);
+
+/*
+ *  終了処理ルーチンの実行（kernel_cfg.c）
+ */
+extern void	call_terrtn(void);
+
+/*
+ *  非タスクコンテキスト用のスタック領域（kernel_cfg.c）
+ */
+extern const SIZE	istksz;		/* スタック領域のサイズ（丸めた値） */
+extern STK_T *const	istk;		/* スタック領域の先頭番地 */
+#ifdef TOPPERS_ISTKPT
+extern STK_T *const	istkpt;		/* スタックポインタの初期値 */
+#endif /* TOPPERS_ISTKPT */
+
+/*
+ *  カーネルが割り付けるメモリ領域（kernel_cfg.c）
+ */
+extern const SIZE	kmmsz;		/* カーネルが割り付けるメモリ領域のサイズ */
+extern MB_T *const	kmm;		/* カーネルが割り付けるメモリ領域の先頭番地 */
+
+/*
+ *  カーネル動作状態フラグ（startup.c）
+ */
+extern bool_t	kerflg;
+
+/*
+ *  カーネルの起動（startup.c）
+ */
+extern void	sta_ker(void);
+
+/*
+ *  カーネルの終了処理（startup.c）
+ */
+extern void	exit_kernel(void);
+
+/*
+ *  カーネルの割り付けるメモリ領域の管理（startup.c）
+ */
+extern void initialize_kmm(void);
+extern void *kernel_malloc(SIZE size);
+extern void kernel_free(void *ptr);
+
+#endif /* TOPPERS_MACRO_ONLY */
+#endif /* TOPPERS_KERNEL_IMPL_H */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/kernel/kernel_int.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/kernel/kernel_int.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/kernel/kernel_int.h	(revision 457)
@@ -0,0 +1,84 @@
+/*
+ *  TOPPERS/ASP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Advanced Standard Profile Kernel
+ * 
+ *  Copyright (C) 2003 by Embedded and Real-Time Systems Laboratory
+ *                              Toyohashi Univ. of Technology, JAPAN
+ *  Copyright (C) 2005-2012 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *		kernel_cfg.c（およびcfg1_out.c）用ヘッダファイル
+ */
+
+#ifndef TOPPERS_KERNEL_INT_H
+#define TOPPERS_KERNEL_INT_H
+
+/*
+ *  カーネル標準ヘッダファイル
+ */
+#include "kernel_impl.h"
+
+/*
+ *  カーネルの各ヘッダファイル
+ */
+#include "task.h"
+#include "semaphore.h"
+#include "eventflag.h"
+#include "dataqueue.h"
+#include "pridataq.h"
+#include "mailbox.h"
+#include "mutex.h"
+#include "mempfix.h"
+#include "cyclic.h"
+#include "alarm.h"
+#include "interrupt.h"
+#include "exception.h"
+#include "time_event.h"
+
+/*
+ *  リネームしたシンボルを元に戻すためのヘッダファイル
+ */
+#include "kernel_unrename.h"
+
+/*
+ *  内容が空の配列を生成するためのマクロ
+ */
+#ifndef TOPPERS_EMPTY_LABEL
+#define TOPPERS_EMPTY_LABEL(type, var)		type var[0]
+#endif
+
+#endif /* TOPPERS_KERNEL_INT_H */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/kernel/kernel_rename.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/kernel/kernel_rename.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/kernel/kernel_rename.h	(revision 457)
@@ -0,0 +1,468 @@
+/* This file is generated from kernel_rename.def by genrename. */
+
+#ifndef TOPPERS_KERNEL_RENAME_H
+#define TOPPERS_KERNEL_RENAME_H
+
+/*
+ *  startup.c
+ */
+#define kerflg						_kernel_kerflg
+#define exit_kernel					_kernel_exit_kernel
+#define initialize_kmm				_kernel_initialize_kmm
+#define kernel_malloc				_kernel_kernel_malloc
+#define kernel_free					_kernel_kernel_free
+
+/*
+ *  task.c
+ */
+#define p_runtsk					_kernel_p_runtsk
+#define p_schedtsk					_kernel_p_schedtsk
+#define reqflg						_kernel_reqflg
+#define ipmflg						_kernel_ipmflg
+#define disdsp						_kernel_disdsp
+#define dspflg						_kernel_dspflg
+#define ready_queue					_kernel_ready_queue
+#define ready_primap				_kernel_ready_primap
+#define free_tcb					_kernel_free_tcb
+#define initialize_task				_kernel_initialize_task
+#define search_schedtsk				_kernel_search_schedtsk
+#define make_runnable				_kernel_make_runnable
+#define make_non_runnable			_kernel_make_non_runnable
+#define make_dormant				_kernel_make_dormant
+#define make_active					_kernel_make_active
+#define change_priority				_kernel_change_priority
+#define rotate_ready_queue			_kernel_rotate_ready_queue
+#define call_texrtn					_kernel_call_texrtn
+#define calltex						_kernel_calltex
+
+/*
+ *  wait.c
+ */
+#define make_wait_tmout				_kernel_make_wait_tmout
+#define wait_complete				_kernel_wait_complete
+#define wait_tmout					_kernel_wait_tmout
+#define wait_tmout_ok				_kernel_wait_tmout_ok
+#define wait_release				_kernel_wait_release
+#define wobj_make_wait				_kernel_wobj_make_wait
+#define wobj_make_wait_tmout		_kernel_wobj_make_wait_tmout
+#define init_wait_queue				_kernel_init_wait_queue
+
+/*
+ *  time_event.c
+ */
+#define current_time				_kernel_current_time
+#define min_time					_kernel_min_time
+#define next_time					_kernel_next_time
+#define next_subtime				_kernel_next_subtime
+#define last_index					_kernel_last_index
+#define initialize_tmevt			_kernel_initialize_tmevt
+#define tmevt_up					_kernel_tmevt_up
+#define tmevt_down					_kernel_tmevt_down
+#define tmevtb_insert				_kernel_tmevtb_insert
+#define tmevtb_delete				_kernel_tmevtb_delete
+#define tmevt_lefttim				_kernel_tmevt_lefttim
+#define signal_time					_kernel_signal_time
+
+/*
+ *  semaphore.c
+ */
+#define free_semcb					_kernel_free_semcb
+#define initialize_semaphore		_kernel_initialize_semaphore
+
+/*
+ *  eventflag.c
+ */
+#define free_flgcb					_kernel_free_flgcb
+#define initialize_eventflag		_kernel_initialize_eventflag
+#define check_flg_cond				_kernel_check_flg_cond
+
+/*
+ *  dataqueue.c
+ */
+#define free_dtqcb					_kernel_free_dtqcb
+#define initialize_dataqueue		_kernel_initialize_dataqueue
+#define enqueue_data				_kernel_enqueue_data
+#define force_enqueue_data			_kernel_force_enqueue_data
+#define dequeue_data				_kernel_dequeue_data
+#define send_data					_kernel_send_data
+#define force_send_data				_kernel_force_send_data
+#define receive_data				_kernel_receive_data
+
+/*
+ *  pridataq.c
+ */
+#define free_pdqcb					_kernel_free_pdqcb
+#define initialize_pridataq			_kernel_initialize_pridataq
+#define enqueue_pridata				_kernel_enqueue_pridata
+#define dequeue_pridata				_kernel_dequeue_pridata
+#define send_pridata				_kernel_send_pridata
+#define receive_pridata				_kernel_receive_pridata
+
+/*
+ *  mailbox.c
+ */
+#define free_mbxcb					_kernel_free_mbxcb
+#define initialize_mailbox			_kernel_initialize_mailbox
+
+/*
+ *  mutex.c
+ */
+#define free_mtxcb					_kernel_free_mtxcb
+#define mtxhook_check_ceilpri		_kernel_mtxhook_check_ceilpri
+#define mtxhook_scan_ceilmtx		_kernel_mtxhook_scan_ceilmtx
+#define mtxhook_release_all			_kernel_mtxhook_release_all
+#define initialize_mutex			_kernel_initialize_mutex
+#define mutex_check_ceilpri			_kernel_mutex_check_ceilpri
+#define mutex_scan_ceilmtx			_kernel_mutex_scan_ceilmtx
+#define mutex_calc_priority			_kernel_mutex_calc_priority
+#define mutex_release				_kernel_mutex_release
+#define mutex_release_all			_kernel_mutex_release_all
+
+/*
+ *  mempfix.c
+ */
+#define free_mpfcb					_kernel_free_mpfcb
+#define initialize_mempfix			_kernel_initialize_mempfix
+#define get_mpf_block				_kernel_get_mpf_block
+
+/*
+ *  cyclic.c
+ */
+#define free_cyccb					_kernel_free_cyccb
+#define initialize_cyclic			_kernel_initialize_cyclic
+#define call_cychdr					_kernel_call_cychdr
+
+/*
+ *  alarm.c
+ */
+#define free_almcb					_kernel_free_almcb
+#define initialize_alarm			_kernel_initialize_alarm
+#define call_almhdr					_kernel_call_almhdr
+
+/*
+ *  interrupt.c
+ */
+#define free_isrcb					_kernel_free_isrcb
+#define initialize_isr				_kernel_initialize_isr
+#define call_isr					_kernel_call_isr
+#define initialize_interrupt		_kernel_initialize_interrupt
+
+/*
+ *  exception.c
+ */
+#define initialize_exception		_kernel_initialize_exception
+
+/*
+ *  kernel_cfg.c
+ */
+#define initialize_object			_kernel_initialize_object
+#define call_inirtn					_kernel_call_inirtn
+#define call_terrtn					_kernel_call_terrtn
+#define tmax_tskid					_kernel_tmax_tskid
+#define tmax_stskid					_kernel_tmax_stskid
+#define tinib_table					_kernel_tinib_table
+#define atinib_table				_kernel_atinib_table
+#define tcb_table					_kernel_tcb_table
+#define torder_table				_kernel_torder_table
+#define tmax_semid					_kernel_tmax_semid
+#define tmax_ssemid					_kernel_tmax_ssemid
+#define seminib_table				_kernel_seminib_table
+#define aseminib_table				_kernel_aseminib_table
+#define semcb_table					_kernel_semcb_table
+#define tmax_flgid					_kernel_tmax_flgid
+#define tmax_sflgid					_kernel_tmax_sflgid
+#define flginib_table				_kernel_flginib_table
+#define aflginib_table				_kernel_aflginib_table
+#define flgcb_table					_kernel_flgcb_table
+#define tmax_dtqid					_kernel_tmax_dtqid
+#define tmax_sdtqid					_kernel_tmax_sdtqid
+#define dtqinib_table				_kernel_dtqinib_table
+#define adtqinib_table				_kernel_adtqinib_table
+#define dtqcb_table					_kernel_dtqcb_table
+#define tmax_pdqid					_kernel_tmax_pdqid
+#define tmax_spdqid					_kernel_tmax_spdqid
+#define pdqinib_table				_kernel_pdqinib_table
+#define apdqinib_table				_kernel_apdqinib_table
+#define pdqcb_table					_kernel_pdqcb_table
+#define tmax_mbxid					_kernel_tmax_mbxid
+#define tmax_smbxid					_kernel_tmax_smbxid
+#define mbxinib_table				_kernel_mbxinib_table
+#define ambxinib_table				_kernel_ambxinib_table
+#define mbxcb_table					_kernel_mbxcb_table
+#define tmax_mtxid					_kernel_tmax_mtxid
+#define tmax_smtxid					_kernel_tmax_smtxid
+#define mtxinib_table				_kernel_mtxinib_table
+#define amtxinib_table				_kernel_amtxinib_table
+#define mtxcb_table					_kernel_mtxcb_table
+#define tmax_mpfid					_kernel_tmax_mpfid
+#define tmax_smpfid					_kernel_tmax_smpfid
+#define mpfinib_table				_kernel_mpfinib_table
+#define ampfinib_table				_kernel_ampfinib_table
+#define mpfcb_table					_kernel_mpfcb_table
+#define tmax_cycid					_kernel_tmax_cycid
+#define tmax_scycid					_kernel_tmax_scycid
+#define cycinib_table				_kernel_cycinib_table
+#define acycinib_table				_kernel_acycinib_table
+#define cyccb_table					_kernel_cyccb_table
+#define tmax_almid					_kernel_tmax_almid
+#define tmax_salmid					_kernel_tmax_salmid
+#define alminib_table				_kernel_alminib_table
+#define aalminib_table				_kernel_aalminib_table
+#define almcb_table					_kernel_almcb_table
+#define tnum_isr_queue				_kernel_tnum_isr_queue
+#define isr_queue_table				_kernel_isr_queue_table
+#define isr_queue_list				_kernel_isr_queue_list
+#define tmax_isrid					_kernel_tmax_isrid
+#define tnum_sisr					_kernel_tnum_sisr
+#define sisrinib_table				_kernel_sisrinib_table
+#define aisrinib_table				_kernel_aisrinib_table
+#define isrcb_table					_kernel_isrcb_table
+#define tnum_inhno					_kernel_tnum_inhno
+#define inhinib_table				_kernel_inhinib_table
+#define tnum_intno					_kernel_tnum_intno
+#define intinib_table				_kernel_intinib_table
+#define tnum_excno					_kernel_tnum_excno
+#define excinib_table				_kernel_excinib_table
+#define tmevt_heap					_kernel_tmevt_heap
+#define istksz						_kernel_istksz
+#define istk						_kernel_istk
+#define istkpt						_kernel_istkpt
+#define kmmsz						_kernel_kmmsz
+#define kmm							_kernel_kmm
+
+
+#ifdef TOPPERS_LABEL_ASM
+
+/*
+ *  startup.c
+ */
+#define _kerflg						__kernel_kerflg
+#define _exit_kernel				__kernel_exit_kernel
+#define _initialize_kmm				__kernel_initialize_kmm
+#define _kernel_malloc				__kernel_kernel_malloc
+#define _kernel_free				__kernel_kernel_free
+
+/*
+ *  task.c
+ */
+#define _p_runtsk					__kernel_p_runtsk
+#define _p_schedtsk					__kernel_p_schedtsk
+#define _reqflg						__kernel_reqflg
+#define _ipmflg						__kernel_ipmflg
+#define _disdsp						__kernel_disdsp
+#define _dspflg						__kernel_dspflg
+#define _ready_queue				__kernel_ready_queue
+#define _ready_primap				__kernel_ready_primap
+#define _free_tcb					__kernel_free_tcb
+#define _initialize_task			__kernel_initialize_task
+#define _search_schedtsk			__kernel_search_schedtsk
+#define _make_runnable				__kernel_make_runnable
+#define _make_non_runnable			__kernel_make_non_runnable
+#define _make_dormant				__kernel_make_dormant
+#define _make_active				__kernel_make_active
+#define _change_priority			__kernel_change_priority
+#define _rotate_ready_queue			__kernel_rotate_ready_queue
+#define _call_texrtn				__kernel_call_texrtn
+#define _calltex					__kernel_calltex
+
+/*
+ *  wait.c
+ */
+#define _make_wait_tmout			__kernel_make_wait_tmout
+#define _wait_complete				__kernel_wait_complete
+#define _wait_tmout					__kernel_wait_tmout
+#define _wait_tmout_ok				__kernel_wait_tmout_ok
+#define _wait_release				__kernel_wait_release
+#define _wobj_make_wait				__kernel_wobj_make_wait
+#define _wobj_make_wait_tmout		__kernel_wobj_make_wait_tmout
+#define _init_wait_queue			__kernel_init_wait_queue
+
+/*
+ *  time_event.c
+ */
+#define _current_time				__kernel_current_time
+#define _min_time					__kernel_min_time
+#define _next_time					__kernel_next_time
+#define _next_subtime				__kernel_next_subtime
+#define _last_index					__kernel_last_index
+#define _initialize_tmevt			__kernel_initialize_tmevt
+#define _tmevt_up					__kernel_tmevt_up
+#define _tmevt_down					__kernel_tmevt_down
+#define _tmevtb_insert				__kernel_tmevtb_insert
+#define _tmevtb_delete				__kernel_tmevtb_delete
+#define _tmevt_lefttim				__kernel_tmevt_lefttim
+#define _signal_time				__kernel_signal_time
+
+/*
+ *  semaphore.c
+ */
+#define _free_semcb					__kernel_free_semcb
+#define _initialize_semaphore		__kernel_initialize_semaphore
+
+/*
+ *  eventflag.c
+ */
+#define _free_flgcb					__kernel_free_flgcb
+#define _initialize_eventflag		__kernel_initialize_eventflag
+#define _check_flg_cond				__kernel_check_flg_cond
+
+/*
+ *  dataqueue.c
+ */
+#define _free_dtqcb					__kernel_free_dtqcb
+#define _initialize_dataqueue		__kernel_initialize_dataqueue
+#define _enqueue_data				__kernel_enqueue_data
+#define _force_enqueue_data			__kernel_force_enqueue_data
+#define _dequeue_data				__kernel_dequeue_data
+#define _send_data					__kernel_send_data
+#define _force_send_data			__kernel_force_send_data
+#define _receive_data				__kernel_receive_data
+
+/*
+ *  pridataq.c
+ */
+#define _free_pdqcb					__kernel_free_pdqcb
+#define _initialize_pridataq		__kernel_initialize_pridataq
+#define _enqueue_pridata			__kernel_enqueue_pridata
+#define _dequeue_pridata			__kernel_dequeue_pridata
+#define _send_pridata				__kernel_send_pridata
+#define _receive_pridata			__kernel_receive_pridata
+
+/*
+ *  mailbox.c
+ */
+#define _free_mbxcb					__kernel_free_mbxcb
+#define _initialize_mailbox			__kernel_initialize_mailbox
+
+/*
+ *  mutex.c
+ */
+#define _free_mtxcb					__kernel_free_mtxcb
+#define _mtxhook_check_ceilpri		__kernel_mtxhook_check_ceilpri
+#define _mtxhook_scan_ceilmtx		__kernel_mtxhook_scan_ceilmtx
+#define _mtxhook_release_all		__kernel_mtxhook_release_all
+#define _initialize_mutex			__kernel_initialize_mutex
+#define _mutex_check_ceilpri		__kernel_mutex_check_ceilpri
+#define _mutex_scan_ceilmtx			__kernel_mutex_scan_ceilmtx
+#define _mutex_calc_priority		__kernel_mutex_calc_priority
+#define _mutex_release				__kernel_mutex_release
+#define _mutex_release_all			__kernel_mutex_release_all
+
+/*
+ *  mempfix.c
+ */
+#define _free_mpfcb					__kernel_free_mpfcb
+#define _initialize_mempfix			__kernel_initialize_mempfix
+#define _get_mpf_block				__kernel_get_mpf_block
+
+/*
+ *  cyclic.c
+ */
+#define _free_cyccb					__kernel_free_cyccb
+#define _initialize_cyclic			__kernel_initialize_cyclic
+#define _call_cychdr				__kernel_call_cychdr
+
+/*
+ *  alarm.c
+ */
+#define _free_almcb					__kernel_free_almcb
+#define _initialize_alarm			__kernel_initialize_alarm
+#define _call_almhdr				__kernel_call_almhdr
+
+/*
+ *  interrupt.c
+ */
+#define _free_isrcb					__kernel_free_isrcb
+#define _initialize_isr				__kernel_initialize_isr
+#define _call_isr					__kernel_call_isr
+#define _initialize_interrupt		__kernel_initialize_interrupt
+
+/*
+ *  exception.c
+ */
+#define _initialize_exception		__kernel_initialize_exception
+
+/*
+ *  kernel_cfg.c
+ */
+#define _initialize_object			__kernel_initialize_object
+#define _call_inirtn				__kernel_call_inirtn
+#define _call_terrtn				__kernel_call_terrtn
+#define _tmax_tskid					__kernel_tmax_tskid
+#define _tmax_stskid				__kernel_tmax_stskid
+#define _tinib_table				__kernel_tinib_table
+#define _atinib_table				__kernel_atinib_table
+#define _tcb_table					__kernel_tcb_table
+#define _torder_table				__kernel_torder_table
+#define _tmax_semid					__kernel_tmax_semid
+#define _tmax_ssemid				__kernel_tmax_ssemid
+#define _seminib_table				__kernel_seminib_table
+#define _aseminib_table				__kernel_aseminib_table
+#define _semcb_table				__kernel_semcb_table
+#define _tmax_flgid					__kernel_tmax_flgid
+#define _tmax_sflgid				__kernel_tmax_sflgid
+#define _flginib_table				__kernel_flginib_table
+#define _aflginib_table				__kernel_aflginib_table
+#define _flgcb_table				__kernel_flgcb_table
+#define _tmax_dtqid					__kernel_tmax_dtqid
+#define _tmax_sdtqid				__kernel_tmax_sdtqid
+#define _dtqinib_table				__kernel_dtqinib_table
+#define _adtqinib_table				__kernel_adtqinib_table
+#define _dtqcb_table				__kernel_dtqcb_table
+#define _tmax_pdqid					__kernel_tmax_pdqid
+#define _tmax_spdqid				__kernel_tmax_spdqid
+#define _pdqinib_table				__kernel_pdqinib_table
+#define _apdqinib_table				__kernel_apdqinib_table
+#define _pdqcb_table				__kernel_pdqcb_table
+#define _tmax_mbxid					__kernel_tmax_mbxid
+#define _tmax_smbxid				__kernel_tmax_smbxid
+#define _mbxinib_table				__kernel_mbxinib_table
+#define _ambxinib_table				__kernel_ambxinib_table
+#define _mbxcb_table				__kernel_mbxcb_table
+#define _tmax_mtxid					__kernel_tmax_mtxid
+#define _tmax_smtxid				__kernel_tmax_smtxid
+#define _mtxinib_table				__kernel_mtxinib_table
+#define _amtxinib_table				__kernel_amtxinib_table
+#define _mtxcb_table				__kernel_mtxcb_table
+#define _tmax_mpfid					__kernel_tmax_mpfid
+#define _tmax_smpfid				__kernel_tmax_smpfid
+#define _mpfinib_table				__kernel_mpfinib_table
+#define _ampfinib_table				__kernel_ampfinib_table
+#define _mpfcb_table				__kernel_mpfcb_table
+#define _tmax_cycid					__kernel_tmax_cycid
+#define _tmax_scycid				__kernel_tmax_scycid
+#define _cycinib_table				__kernel_cycinib_table
+#define _acycinib_table				__kernel_acycinib_table
+#define _cyccb_table				__kernel_cyccb_table
+#define _tmax_almid					__kernel_tmax_almid
+#define _tmax_salmid				__kernel_tmax_salmid
+#define _alminib_table				__kernel_alminib_table
+#define _aalminib_table				__kernel_aalminib_table
+#define _almcb_table				__kernel_almcb_table
+#define _tnum_isr_queue				__kernel_tnum_isr_queue
+#define _isr_queue_table			__kernel_isr_queue_table
+#define _isr_queue_list				__kernel_isr_queue_list
+#define _tmax_isrid					__kernel_tmax_isrid
+#define _tnum_sisr					__kernel_tnum_sisr
+#define _sisrinib_table				__kernel_sisrinib_table
+#define _aisrinib_table				__kernel_aisrinib_table
+#define _isrcb_table				__kernel_isrcb_table
+#define _tnum_inhno					__kernel_tnum_inhno
+#define _inhinib_table				__kernel_inhinib_table
+#define _tnum_intno					__kernel_tnum_intno
+#define _intinib_table				__kernel_intinib_table
+#define _tnum_excno					__kernel_tnum_excno
+#define _excinib_table				__kernel_excinib_table
+#define _tmevt_heap					__kernel_tmevt_heap
+#define _istksz						__kernel_istksz
+#define _istk						__kernel_istk
+#define _istkpt						__kernel_istkpt
+#define _kmmsz						__kernel_kmmsz
+#define _kmm						__kernel_kmm
+
+
+#endif /* TOPPERS_LABEL_ASM */
+
+#include "target_rename.h"
+
+#endif /* TOPPERS_KERNEL_RENAME_H */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/kernel/kernel_unrename.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/kernel/kernel_unrename.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/kernel/kernel_unrename.h	(revision 457)
@@ -0,0 +1,469 @@
+/* This file is generated from kernel_rename.def by genrename. */
+
+/* This file is included only when kernel_rename.h has been included. */
+#ifdef TOPPERS_KERNEL_RENAME_H
+#undef TOPPERS_KERNEL_RENAME_H
+
+/*
+ *  startup.c
+ */
+#undef kerflg
+#undef exit_kernel
+#undef initialize_kmm
+#undef kernel_malloc
+#undef kernel_free
+
+/*
+ *  task.c
+ */
+#undef p_runtsk
+#undef p_schedtsk
+#undef reqflg
+#undef ipmflg
+#undef disdsp
+#undef dspflg
+#undef ready_queue
+#undef ready_primap
+#undef free_tcb
+#undef initialize_task
+#undef search_schedtsk
+#undef make_runnable
+#undef make_non_runnable
+#undef make_dormant
+#undef make_active
+#undef change_priority
+#undef rotate_ready_queue
+#undef call_texrtn
+#undef calltex
+
+/*
+ *  wait.c
+ */
+#undef make_wait_tmout
+#undef wait_complete
+#undef wait_tmout
+#undef wait_tmout_ok
+#undef wait_release
+#undef wobj_make_wait
+#undef wobj_make_wait_tmout
+#undef init_wait_queue
+
+/*
+ *  time_event.c
+ */
+#undef current_time
+#undef min_time
+#undef next_time
+#undef next_subtime
+#undef last_index
+#undef initialize_tmevt
+#undef tmevt_up
+#undef tmevt_down
+#undef tmevtb_insert
+#undef tmevtb_delete
+#undef tmevt_lefttim
+#undef signal_time
+
+/*
+ *  semaphore.c
+ */
+#undef free_semcb
+#undef initialize_semaphore
+
+/*
+ *  eventflag.c
+ */
+#undef free_flgcb
+#undef initialize_eventflag
+#undef check_flg_cond
+
+/*
+ *  dataqueue.c
+ */
+#undef free_dtqcb
+#undef initialize_dataqueue
+#undef enqueue_data
+#undef force_enqueue_data
+#undef dequeue_data
+#undef send_data
+#undef force_send_data
+#undef receive_data
+
+/*
+ *  pridataq.c
+ */
+#undef free_pdqcb
+#undef initialize_pridataq
+#undef enqueue_pridata
+#undef dequeue_pridata
+#undef send_pridata
+#undef receive_pridata
+
+/*
+ *  mailbox.c
+ */
+#undef free_mbxcb
+#undef initialize_mailbox
+
+/*
+ *  mutex.c
+ */
+#undef free_mtxcb
+#undef mtxhook_check_ceilpri
+#undef mtxhook_scan_ceilmtx
+#undef mtxhook_release_all
+#undef initialize_mutex
+#undef mutex_check_ceilpri
+#undef mutex_scan_ceilmtx
+#undef mutex_calc_priority
+#undef mutex_release
+#undef mutex_release_all
+
+/*
+ *  mempfix.c
+ */
+#undef free_mpfcb
+#undef initialize_mempfix
+#undef get_mpf_block
+
+/*
+ *  cyclic.c
+ */
+#undef free_cyccb
+#undef initialize_cyclic
+#undef call_cychdr
+
+/*
+ *  alarm.c
+ */
+#undef free_almcb
+#undef initialize_alarm
+#undef call_almhdr
+
+/*
+ *  interrupt.c
+ */
+#undef free_isrcb
+#undef initialize_isr
+#undef call_isr
+#undef initialize_interrupt
+
+/*
+ *  exception.c
+ */
+#undef initialize_exception
+
+/*
+ *  kernel_cfg.c
+ */
+#undef initialize_object
+#undef call_inirtn
+#undef call_terrtn
+#undef tmax_tskid
+#undef tmax_stskid
+#undef tinib_table
+#undef atinib_table
+#undef tcb_table
+#undef torder_table
+#undef tmax_semid
+#undef tmax_ssemid
+#undef seminib_table
+#undef aseminib_table
+#undef semcb_table
+#undef tmax_flgid
+#undef tmax_sflgid
+#undef flginib_table
+#undef aflginib_table
+#undef flgcb_table
+#undef tmax_dtqid
+#undef tmax_sdtqid
+#undef dtqinib_table
+#undef adtqinib_table
+#undef dtqcb_table
+#undef tmax_pdqid
+#undef tmax_spdqid
+#undef pdqinib_table
+#undef apdqinib_table
+#undef pdqcb_table
+#undef tmax_mbxid
+#undef tmax_smbxid
+#undef mbxinib_table
+#undef ambxinib_table
+#undef mbxcb_table
+#undef tmax_mtxid
+#undef tmax_smtxid
+#undef mtxinib_table
+#undef amtxinib_table
+#undef mtxcb_table
+#undef tmax_mpfid
+#undef tmax_smpfid
+#undef mpfinib_table
+#undef ampfinib_table
+#undef mpfcb_table
+#undef tmax_cycid
+#undef tmax_scycid
+#undef cycinib_table
+#undef acycinib_table
+#undef cyccb_table
+#undef tmax_almid
+#undef tmax_salmid
+#undef alminib_table
+#undef aalminib_table
+#undef almcb_table
+#undef tnum_isr_queue
+#undef isr_queue_table
+#undef isr_queue_list
+#undef tmax_isrid
+#undef tnum_sisr
+#undef sisrinib_table
+#undef aisrinib_table
+#undef isrcb_table
+#undef tnum_inhno
+#undef inhinib_table
+#undef tnum_intno
+#undef intinib_table
+#undef tnum_excno
+#undef excinib_table
+#undef tmevt_heap
+#undef istksz
+#undef istk
+#undef istkpt
+#undef kmmsz
+#undef kmm
+
+
+#ifdef TOPPERS_LABEL_ASM
+
+/*
+ *  startup.c
+ */
+#undef _kerflg
+#undef _exit_kernel
+#undef _initialize_kmm
+#undef _kernel_malloc
+#undef _kernel_free
+
+/*
+ *  task.c
+ */
+#undef _p_runtsk
+#undef _p_schedtsk
+#undef _reqflg
+#undef _ipmflg
+#undef _disdsp
+#undef _dspflg
+#undef _ready_queue
+#undef _ready_primap
+#undef _free_tcb
+#undef _initialize_task
+#undef _search_schedtsk
+#undef _make_runnable
+#undef _make_non_runnable
+#undef _make_dormant
+#undef _make_active
+#undef _change_priority
+#undef _rotate_ready_queue
+#undef _call_texrtn
+#undef _calltex
+
+/*
+ *  wait.c
+ */
+#undef _make_wait_tmout
+#undef _wait_complete
+#undef _wait_tmout
+#undef _wait_tmout_ok
+#undef _wait_release
+#undef _wobj_make_wait
+#undef _wobj_make_wait_tmout
+#undef _init_wait_queue
+
+/*
+ *  time_event.c
+ */
+#undef _current_time
+#undef _min_time
+#undef _next_time
+#undef _next_subtime
+#undef _last_index
+#undef _initialize_tmevt
+#undef _tmevt_up
+#undef _tmevt_down
+#undef _tmevtb_insert
+#undef _tmevtb_delete
+#undef _tmevt_lefttim
+#undef _signal_time
+
+/*
+ *  semaphore.c
+ */
+#undef _free_semcb
+#undef _initialize_semaphore
+
+/*
+ *  eventflag.c
+ */
+#undef _free_flgcb
+#undef _initialize_eventflag
+#undef _check_flg_cond
+
+/*
+ *  dataqueue.c
+ */
+#undef _free_dtqcb
+#undef _initialize_dataqueue
+#undef _enqueue_data
+#undef _force_enqueue_data
+#undef _dequeue_data
+#undef _send_data
+#undef _force_send_data
+#undef _receive_data
+
+/*
+ *  pridataq.c
+ */
+#undef _free_pdqcb
+#undef _initialize_pridataq
+#undef _enqueue_pridata
+#undef _dequeue_pridata
+#undef _send_pridata
+#undef _receive_pridata
+
+/*
+ *  mailbox.c
+ */
+#undef _free_mbxcb
+#undef _initialize_mailbox
+
+/*
+ *  mutex.c
+ */
+#undef _free_mtxcb
+#undef _mtxhook_check_ceilpri
+#undef _mtxhook_scan_ceilmtx
+#undef _mtxhook_release_all
+#undef _initialize_mutex
+#undef _mutex_check_ceilpri
+#undef _mutex_scan_ceilmtx
+#undef _mutex_calc_priority
+#undef _mutex_release
+#undef _mutex_release_all
+
+/*
+ *  mempfix.c
+ */
+#undef _free_mpfcb
+#undef _initialize_mempfix
+#undef _get_mpf_block
+
+/*
+ *  cyclic.c
+ */
+#undef _free_cyccb
+#undef _initialize_cyclic
+#undef _call_cychdr
+
+/*
+ *  alarm.c
+ */
+#undef _free_almcb
+#undef _initialize_alarm
+#undef _call_almhdr
+
+/*
+ *  interrupt.c
+ */
+#undef _free_isrcb
+#undef _initialize_isr
+#undef _call_isr
+#undef _initialize_interrupt
+
+/*
+ *  exception.c
+ */
+#undef _initialize_exception
+
+/*
+ *  kernel_cfg.c
+ */
+#undef _initialize_object
+#undef _call_inirtn
+#undef _call_terrtn
+#undef _tmax_tskid
+#undef _tmax_stskid
+#undef _tinib_table
+#undef _atinib_table
+#undef _tcb_table
+#undef _torder_table
+#undef _tmax_semid
+#undef _tmax_ssemid
+#undef _seminib_table
+#undef _aseminib_table
+#undef _semcb_table
+#undef _tmax_flgid
+#undef _tmax_sflgid
+#undef _flginib_table
+#undef _aflginib_table
+#undef _flgcb_table
+#undef _tmax_dtqid
+#undef _tmax_sdtqid
+#undef _dtqinib_table
+#undef _adtqinib_table
+#undef _dtqcb_table
+#undef _tmax_pdqid
+#undef _tmax_spdqid
+#undef _pdqinib_table
+#undef _apdqinib_table
+#undef _pdqcb_table
+#undef _tmax_mbxid
+#undef _tmax_smbxid
+#undef _mbxinib_table
+#undef _ambxinib_table
+#undef _mbxcb_table
+#undef _tmax_mtxid
+#undef _tmax_smtxid
+#undef _mtxinib_table
+#undef _amtxinib_table
+#undef _mtxcb_table
+#undef _tmax_mpfid
+#undef _tmax_smpfid
+#undef _mpfinib_table
+#undef _ampfinib_table
+#undef _mpfcb_table
+#undef _tmax_cycid
+#undef _tmax_scycid
+#undef _cycinib_table
+#undef _acycinib_table
+#undef _cyccb_table
+#undef _tmax_almid
+#undef _tmax_salmid
+#undef _alminib_table
+#undef _aalminib_table
+#undef _almcb_table
+#undef _tnum_isr_queue
+#undef _isr_queue_table
+#undef _isr_queue_list
+#undef _tmax_isrid
+#undef _tnum_sisr
+#undef _sisrinib_table
+#undef _aisrinib_table
+#undef _isrcb_table
+#undef _tnum_inhno
+#undef _inhinib_table
+#undef _tnum_intno
+#undef _intinib_table
+#undef _tnum_excno
+#undef _excinib_table
+#undef _tmevt_heap
+#undef _istksz
+#undef _istk
+#undef _istkpt
+#undef _kmmsz
+#undef _kmm
+
+
+#endif /* TOPPERS_LABEL_ASM */
+
+#include "target_unrename.h"
+
+#endif /* TOPPERS_KERNEL_RENAME_H */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/kernel/mailbox.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/kernel/mailbox.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/kernel/mailbox.c	(revision 457)
@@ -0,0 +1,534 @@
+/*
+ *  TOPPERS/ASP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Advanced Standard Profile Kernel
+ * 
+ *  Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
+ *                              Toyohashi Univ. of Technology, JAPAN
+ *  Copyright (C) 2005-2014 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  $Id$
+ */
+
+/*
+ *		メールボックス機能
+ */
+
+#include "kernel_impl.h"
+#include "check.h"
+#include "task.h"
+#include "wait.h"
+#include "mailbox.h"
+
+/*
+ *  トレースログマクロのデフォルト定義
+ */
+#ifndef LOG_ACRE_MBX_ENTER
+#define LOG_ACRE_MBX_ENTER(pk_cmbx)
+#endif /* LOG_ACRE_MBX_ENTER */
+
+#ifndef LOG_ACRE_MBX_LEAVE
+#define LOG_ACRE_MBX_LEAVE(ercd)
+#endif /* LOG_ACRE_MBX_LEAVE */
+
+#ifndef LOG_DEL_MBX_ENTER
+#define LOG_DEL_MBX_ENTER(mbxid)
+#endif /* LOG_DEL_MBX_ENTER */
+
+#ifndef LOG_DEL_MBX_LEAVE
+#define LOG_DEL_MBX_LEAVE(ercd)
+#endif /* LOG_DEL_MBX_LEAVE */
+
+#ifndef LOG_SND_MBX_ENTER
+#define LOG_SND_MBX_ENTER(mbxid, pk_msg)
+#endif /* LOG_SND_MBX_ENTER */
+
+#ifndef LOG_SND_MBX_LEAVE
+#define LOG_SND_MBX_LEAVE(ercd)
+#endif /* LOG_SND_MBX_LEAVE */
+
+#ifndef LOG_RCV_MBX_ENTER
+#define LOG_RCV_MBX_ENTER(mbxid, ppk_msg)
+#endif /* LOG_RCV_MBX_ENTER */
+
+#ifndef LOG_RCV_MBX_LEAVE
+#define LOG_RCV_MBX_LEAVE(ercd, pk_msg)
+#endif /* LOG_RCV_MBX_LEAVE */
+
+#ifndef LOG_PRCV_MBX_ENTER
+#define LOG_PRCV_MBX_ENTER(mbxid, ppk_msg)
+#endif /* LOG_PRCV_MBX_ENTER */
+
+#ifndef LOG_PRCV_MBX_LEAVE
+#define LOG_PRCV_MBX_LEAVE(ercd, pk_msg)
+#endif /* LOG_PRCV_MBX_LEAVE */
+
+#ifndef LOG_TRCV_MBX_ENTER
+#define LOG_TRCV_MBX_ENTER(mbxid, ppk_msg, tmout)
+#endif /* LOG_TRCV_MBX_ENTER */
+
+#ifndef LOG_TRCV_MBX_LEAVE
+#define LOG_TRCV_MBX_LEAVE(ercd, pk_msg)
+#endif /* LOG_TRCV_MBX_LEAVE */
+
+#ifndef LOG_INI_MBX_ENTER
+#define LOG_INI_MBX_ENTER(mbxid)
+#endif /* LOG_INI_MBX_ENTER */
+
+#ifndef LOG_INI_MBX_LEAVE
+#define LOG_INI_MBX_LEAVE(ercd)
+#endif /* LOG_INI_MBX_LEAVE */
+
+#ifndef LOG_REF_MBX_ENTER
+#define LOG_REF_MBX_ENTER(mbxid, pk_rmbx)
+#endif /* LOG_REF_MBX_ENTER */
+
+#ifndef LOG_REF_MBX_LEAVE
+#define LOG_REF_MBX_LEAVE(ercd, pk_rmbx)
+#endif /* LOG_REF_MBX_LEAVE */
+
+/*
+ *  メールボックスの数
+ */
+#define tnum_mbx	((uint_t)(tmax_mbxid - TMIN_MBXID + 1))
+#define tnum_smbx	((uint_t)(tmax_smbxid - TMIN_MBXID + 1))
+
+/*
+ *  メールボックスIDからメールボックス管理ブロックを取り出すためのマクロ
+ */
+#define INDEX_MBX(mbxid)	((uint_t)((mbxid) - TMIN_MBXID))
+#define get_mbxcb(mbxid)	(&(mbxcb_table[INDEX_MBX(mbxid)]))
+
+#ifdef TOPPERS_mbxini
+
+/*
+ *  使用していないメールボックス管理ブロックのリスト
+ */
+QUEUE	free_mbxcb;
+
+/* 
+ *  メールボックス機能の初期化
+ */
+void
+initialize_mailbox(void)
+{
+	uint_t	i, j;
+	MBXCB	*p_mbxcb;
+	MBXINIB	*p_mbxinib;
+
+	for (i = 0; i < tnum_smbx; i++) {
+		p_mbxcb = &(mbxcb_table[i]);
+		queue_initialize(&(p_mbxcb->wait_queue));
+		p_mbxcb->p_mbxinib = &(mbxinib_table[i]);
+		p_mbxcb->pk_head = NULL;
+	}
+	queue_initialize(&free_mbxcb);
+	for (j = 0; i < tnum_mbx; i++, j++) {
+		p_mbxcb = &(mbxcb_table[i]);
+		p_mbxinib = &(ambxinib_table[j]);
+		p_mbxinib->mbxatr = TA_NOEXS;
+		p_mbxcb->p_mbxinib = ((const MBXINIB *) p_mbxinib);
+		queue_insert_prev(&free_mbxcb, &(p_mbxcb->wait_queue));
+	}
+}
+
+#endif /* TOPPERS_mbxini */
+
+/*
+ *  メッセージ優先度の取出し
+ */
+#define	MSGPRI(pk_msg)	(((T_MSG_PRI *)(pk_msg))->msgpri)
+
+/*
+ *  優先度順メッセージキューへの挿入
+ */
+Inline void
+enqueue_msg_pri(T_MSG **ppk_prevmsg_next, T_MSG *pk_msg)
+{
+	T_MSG	*pk_nextmsg;
+
+	while ((pk_nextmsg = *ppk_prevmsg_next) != NULL) {
+		if (MSGPRI(pk_nextmsg) > MSGPRI(pk_msg)) {
+			break;
+		}
+		ppk_prevmsg_next = &(pk_nextmsg->pk_next);
+	}
+	pk_msg->pk_next = pk_nextmsg;
+	*ppk_prevmsg_next = pk_msg;
+}
+
+/*
+ *  メールボックスの生成
+ */
+#ifdef TOPPERS_acre_mbx
+
+ER_UINT
+acre_mbx(const T_CMBX *pk_cmbx)
+{
+	MBXCB	*p_mbxcb;
+	MBXINIB	*p_mbxinib;
+	ER		ercd;
+
+	LOG_ACRE_MBX_ENTER(pk_cmbx);
+	CHECK_TSKCTX_UNL();
+	CHECK_RSATR(pk_cmbx->mbxatr, TA_TPRI|TA_MPRI);
+	CHECK_MPRI(pk_cmbx->maxmpri);
+	CHECK_NOSPT(pk_cmbx->mprihd == NULL);
+
+	t_lock_cpu();
+	if (tnum_mbx == 0 || queue_empty(&free_mbxcb)) {
+		ercd = E_NOID;
+	}
+	else {
+		p_mbxcb = ((MBXCB *) queue_delete_next(&free_mbxcb));
+		p_mbxinib = (MBXINIB *)(p_mbxcb->p_mbxinib);
+		p_mbxinib->mbxatr = pk_cmbx->mbxatr;
+		p_mbxinib->maxmpri = pk_cmbx->maxmpri;
+
+		queue_initialize(&(p_mbxcb->wait_queue));
+		p_mbxcb->pk_head = NULL;
+		ercd = MBXID(p_mbxcb);
+	}
+	t_unlock_cpu();
+
+  error_exit:
+	LOG_ACRE_MBX_LEAVE(ercd);
+	return(ercd);
+}
+
+#endif /* TOPPERS_acre_mbx */
+
+/*
+ *  メールボックスの削除
+ */
+#ifdef TOPPERS_del_mbx
+
+ER
+del_mbx(ID mbxid)
+{
+	MBXCB	*p_mbxcb;
+	MBXINIB	*p_mbxinib;
+	bool_t	dspreq;
+	ER		ercd;
+
+	LOG_DEL_MBX_ENTER(mbxid);
+	CHECK_TSKCTX_UNL();
+	CHECK_MBXID(mbxid);
+	p_mbxcb = get_mbxcb(mbxid);
+
+	t_lock_cpu();
+	if (p_mbxcb->p_mbxinib->mbxatr == TA_NOEXS) {
+		ercd = E_NOEXS;
+	}
+	else if (MBXID(p_mbxcb) > tmax_smbxid) {
+		dspreq = init_wait_queue(&(p_mbxcb->wait_queue));
+		p_mbxinib = (MBXINIB *)(p_mbxcb->p_mbxinib);
+		p_mbxinib->mbxatr = TA_NOEXS;
+		queue_insert_prev(&free_mbxcb, &(p_mbxcb->wait_queue));
+		if (dspreq) {
+			dispatch();
+		}
+		ercd = E_OK;
+	}
+	else {
+		ercd = E_OBJ;
+	}
+	t_unlock_cpu();
+
+  error_exit:
+	LOG_DEL_MBX_LEAVE(ercd);
+	return(ercd);
+}
+
+#endif /* TOPPERS_del_mbx */
+
+/*
+ *  メールボックスへの送信
+ */
+#ifdef TOPPERS_snd_mbx
+
+ER
+snd_mbx(ID mbxid, T_MSG *pk_msg)
+{
+	MBXCB	*p_mbxcb;
+	TCB		*p_tcb;
+	ER		ercd;
+    
+	LOG_SND_MBX_ENTER(mbxid, pk_msg);
+	CHECK_TSKCTX_UNL();
+	CHECK_MBXID(mbxid);
+	p_mbxcb = get_mbxcb(mbxid);
+
+	t_lock_cpu();
+	if (p_mbxcb->p_mbxinib->mbxatr == TA_NOEXS) {
+		ercd = E_NOEXS;
+	}
+	else if (!((p_mbxcb->p_mbxinib->mbxatr & TA_MPRI) == 0U
+				|| (TMIN_MPRI <= MSGPRI(pk_msg)
+					&& MSGPRI(pk_msg) <= p_mbxcb->p_mbxinib->maxmpri))) {
+		ercd = E_PAR;
+	}
+	else if (!queue_empty(&(p_mbxcb->wait_queue))) {
+		p_tcb = (TCB *) queue_delete_next(&(p_mbxcb->wait_queue));
+		((WINFO_MBX *)(p_tcb->p_winfo))->pk_msg = pk_msg;
+		if (wait_complete(p_tcb)) {
+			dispatch();
+		}
+		ercd = E_OK;
+	}
+	else if ((p_mbxcb->p_mbxinib->mbxatr & TA_MPRI) != 0U) {
+		enqueue_msg_pri(&(p_mbxcb->pk_head), pk_msg);
+		ercd = E_OK;
+	}
+	else {
+		pk_msg->pk_next = NULL;
+		if (p_mbxcb->pk_head != NULL) {
+			p_mbxcb->pk_last->pk_next = pk_msg;
+		}
+		else {
+			p_mbxcb->pk_head = pk_msg;
+		}
+		p_mbxcb->pk_last = pk_msg;
+		ercd = E_OK;
+	}
+	t_unlock_cpu();
+
+  error_exit:
+	LOG_SND_MBX_LEAVE(ercd);
+	return(ercd);
+}
+
+#endif /* TOPPERS_snd_mbx */
+
+/*
+ *  メールボックスからの受信
+ */
+#ifdef TOPPERS_rcv_mbx
+
+ER
+rcv_mbx(ID mbxid, T_MSG **ppk_msg)
+{
+	MBXCB	*p_mbxcb;
+	WINFO_MBX winfo_mbx;
+	ER		ercd;
+    
+	LOG_RCV_MBX_ENTER(mbxid, ppk_msg);
+	CHECK_DISPATCH();
+	CHECK_MBXID(mbxid);
+	p_mbxcb = get_mbxcb(mbxid);
+    
+	t_lock_cpu();
+	if (p_mbxcb->p_mbxinib->mbxatr == TA_NOEXS) {
+		ercd = E_NOEXS;
+	}
+	else if (p_mbxcb->pk_head != NULL) {
+		*ppk_msg = p_mbxcb->pk_head;
+		p_mbxcb->pk_head = (*ppk_msg)->pk_next;
+		ercd = E_OK;
+	}
+	else {
+		p_runtsk->tstat = (TS_WAITING | TS_WAIT_MBX);
+		wobj_make_wait((WOBJCB *) p_mbxcb, (WINFO_WOBJ *) &winfo_mbx);
+		dispatch();
+		ercd = winfo_mbx.winfo.wercd;
+		if (ercd == E_OK) {
+			*ppk_msg = winfo_mbx.pk_msg;
+		}
+	}
+	t_unlock_cpu();
+
+  error_exit:
+	LOG_RCV_MBX_LEAVE(ercd, *ppk_msg);
+	return(ercd);
+}
+
+#endif /* TOPPERS_rcv_mbx */
+
+/*
+ *  メールボックスからの受信（ポーリング）
+ */
+#ifdef TOPPERS_prcv_mbx
+
+ER
+prcv_mbx(ID mbxid, T_MSG **ppk_msg)
+{
+	MBXCB	*p_mbxcb;
+	ER		ercd;
+    
+	LOG_PRCV_MBX_ENTER(mbxid, ppk_msg);
+	CHECK_TSKCTX_UNL();
+	CHECK_MBXID(mbxid);
+	p_mbxcb = get_mbxcb(mbxid);
+    
+	t_lock_cpu();
+	if (p_mbxcb->p_mbxinib->mbxatr == TA_NOEXS) {
+		ercd = E_NOEXS;
+	}
+	else if (p_mbxcb->pk_head != NULL) {
+		*ppk_msg = p_mbxcb->pk_head;
+		p_mbxcb->pk_head = (*ppk_msg)->pk_next;
+		ercd = E_OK;
+	}
+	else {
+		ercd = E_TMOUT;
+	}
+	t_unlock_cpu();
+
+  error_exit:
+	LOG_PRCV_MBX_LEAVE(ercd, *ppk_msg);
+	return(ercd);
+}
+
+#endif /* TOPPERS_prcv_mbx */
+
+/*
+ *  メールボックスからの受信（タイムアウトあり）
+ */
+#ifdef TOPPERS_trcv_mbx
+
+ER
+trcv_mbx(ID mbxid, T_MSG **ppk_msg, TMO tmout)
+{
+	MBXCB	*p_mbxcb;
+	WINFO_MBX winfo_mbx;
+	TMEVTB	tmevtb;
+	ER		ercd;
+    
+	LOG_TRCV_MBX_ENTER(mbxid, ppk_msg, tmout);
+	CHECK_DISPATCH();
+	CHECK_MBXID(mbxid);
+	CHECK_TMOUT(tmout);
+	p_mbxcb = get_mbxcb(mbxid);
+    
+	t_lock_cpu();
+	if (p_mbxcb->p_mbxinib->mbxatr == TA_NOEXS) {
+		ercd = E_NOEXS;
+	}
+	else if (p_mbxcb->pk_head != NULL) {
+		*ppk_msg = p_mbxcb->pk_head;
+		p_mbxcb->pk_head = (*ppk_msg)->pk_next;
+		ercd = E_OK;
+	}
+	else if (tmout == TMO_POL) {
+		ercd = E_TMOUT;
+	}
+	else {
+		p_runtsk->tstat = (TS_WAITING | TS_WAIT_MBX);
+		wobj_make_wait_tmout((WOBJCB *) p_mbxcb, (WINFO_WOBJ *) &winfo_mbx,
+														&tmevtb, tmout);
+		dispatch();
+		ercd = winfo_mbx.winfo.wercd;
+		if (ercd == E_OK) {
+			*ppk_msg = winfo_mbx.pk_msg;
+		}
+	}
+	t_unlock_cpu();
+
+  error_exit:
+	LOG_TRCV_MBX_LEAVE(ercd, *ppk_msg);
+	return(ercd);
+}
+
+#endif /* TOPPERS_trcv_mbx */
+
+/*
+ *  メールボックスの再初期化
+ */
+#ifdef TOPPERS_ini_mbx
+
+ER
+ini_mbx(ID mbxid)
+{
+	MBXCB	*p_mbxcb;
+	bool_t	dspreq;
+	ER		ercd;
+    
+	LOG_INI_MBX_ENTER(mbxid);
+	CHECK_TSKCTX_UNL();
+	CHECK_MBXID(mbxid);
+	p_mbxcb = get_mbxcb(mbxid);
+
+	t_lock_cpu();
+	if (p_mbxcb->p_mbxinib->mbxatr == TA_NOEXS) {
+		ercd = E_NOEXS;
+	}
+	else {
+		dspreq = init_wait_queue(&(p_mbxcb->wait_queue));
+		p_mbxcb->pk_head = NULL;
+		if (dspreq) {
+			dispatch();
+		}
+		ercd = E_OK;
+	}
+	t_unlock_cpu();
+
+  error_exit:
+	LOG_INI_MBX_LEAVE(ercd);
+	return(ercd);
+}
+
+#endif /* TOPPERS_ini_mbx */
+
+/*
+ *  メールボックスの状態参照
+ */
+#ifdef TOPPERS_ref_mbx
+
+ER
+ref_mbx(ID mbxid, T_RMBX *pk_rmbx)
+{
+	MBXCB	*p_mbxcb;
+	ER		ercd;
+    
+	LOG_REF_MBX_ENTER(mbxid, pk_rmbx);
+	CHECK_TSKCTX_UNL();
+	CHECK_MBXID(mbxid);
+	p_mbxcb = get_mbxcb(mbxid);
+
+	t_lock_cpu();
+	if (p_mbxcb->p_mbxinib->mbxatr == TA_NOEXS) {
+		ercd = E_NOEXS;
+	}
+	else {
+		pk_rmbx->wtskid = wait_tskid(&(p_mbxcb->wait_queue));
+		pk_rmbx->pk_msg = p_mbxcb->pk_head;
+		ercd = E_OK;
+	}
+	t_unlock_cpu();
+
+  error_exit:
+	LOG_REF_MBX_LEAVE(ercd, pk_rmbx);
+	return(ercd);
+}
+
+#endif /* TOPPERS_ref_mbx */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/kernel/mailbox.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/kernel/mailbox.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/kernel/mailbox.h	(revision 457)
@@ -0,0 +1,127 @@
+/*
+ *  TOPPERS/ASP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Advanced Standard Profile Kernel
+ * 
+ *  Copyright (C) 2000 by Embedded and Real-Time Systems Laboratory
+ *                              Toyohashi Univ. of Technology, JAPAN
+ *  Copyright (C) 2005-2012 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *		メールボックス機能
+ */
+
+#ifndef TOPPERS_MAILBOX_H
+#define TOPPERS_MAILBOX_H
+
+#include "wait.h"
+
+/*
+ *  メールボックス初期化ブロック
+ *
+ *  この構造体は，同期・通信オブジェクトの初期化ブロックの共通部分
+ *  （WOBJINIB）を拡張（オブジェクト指向言語の継承に相当）したもので，
+ *  最初のフィールドが共通になっている．
+ */
+typedef struct mailbox_initialization_block {
+	ATR			mbxatr;			/* メールボックス属性 */
+	PRI			maxmpri;		/* メッセージ優先度の最大値 */
+} MBXINIB;
+
+/*
+ *  メールボックス管理ブロック
+ *
+ *  この構造体は，同期・通信オブジェクトの管理ブロックの共通部分（WOBJCB）
+ *  を拡張（オブジェクト指向言語の継承に相当）したもので，最初の2つの
+ *  フィールドが共通になっている．
+ *
+ *  メッセージキューがメッセージの優先度順の場合には，pk_lastは使わな
+ *  い．また，メッセージキューが空の場合（pk_headがNULLの場合）にも，
+ *  pk_lastは無効である．
+ */
+typedef struct mailbox_control_block {
+	QUEUE		wait_queue;		/* メールボックス待ちキュー */
+	const MBXINIB *p_mbxinib;	/* 初期化ブロックへのポインタ */
+	T_MSG		*pk_head;		/* 先頭のメッセージ */
+	T_MSG		*pk_last;		/* 末尾のメッセージ */
+} MBXCB;
+
+/*
+ *  メールボックス待ち情報ブロックの定義
+ *
+ *  この構造体は，同期・通信オブジェクトの待ち情報ブロックの共通部分
+ *  （WINFO_WOBJ）を拡張（オブジェクト指向言語の継承に相当）したもので，
+ *  最初の2つのフィールドが共通になっている．
+ */
+typedef struct mailbox_waiting_information {
+	WINFO		winfo;			/* 標準の待ち情報ブロック */
+	MBXCB		*p_mbxcb;		/* 待っているメールボックスの管理ブロック */
+	T_MSG		*pk_msg;		/* 受信したメッセージ */
+} WINFO_MBX;
+
+/*
+ *  使用していないメールボックス管理ブロックのリスト
+ */
+extern QUEUE	free_mbxcb;
+
+/*
+ *  メールボックスIDの最大値（kernel_cfg.c）
+ */
+extern const ID	tmax_mbxid;
+extern const ID	tmax_smbxid;
+
+/*
+ *  メールボックス初期化ブロックのエリア（kernel_cfg.c）
+ */
+extern const MBXINIB	mbxinib_table[];
+extern MBXINIB			ambxinib_table[];
+
+/*
+ *  メールボックス管理ブロックのエリア（kernel_cfg.c）
+ */
+extern MBXCB	mbxcb_table[];
+
+/*
+ *  メールボックス管理ブロックからメールボックスIDを取り出すためのマクロ
+ */
+#define	MBXID(p_mbxcb)	((ID)(((p_mbxcb) - mbxcb_table) + TMIN_MBXID))
+
+/*
+ *  メールボックス機能の初期化
+ */
+extern void	initialize_mailbox(void);
+
+#endif /* TOPPERS_MAILBOX_H */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/kernel/mempfix.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/kernel/mempfix.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/kernel/mempfix.c	(revision 457)
@@ -0,0 +1,588 @@
+/*
+ *  TOPPERS/ASP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Advanced Standard Profile Kernel
+ * 
+ *  Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
+ *                              Toyohashi Univ. of Technology, JAPAN
+ *  Copyright (C) 2005-2014 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  $Id$
+ */
+
+/*
+ *		固定長メモリプール機能
+ */
+
+#include "kernel_impl.h"
+#include "check.h"
+#include "task.h"
+#include "wait.h"
+#include "mempfix.h"
+
+/*
+ *  トレースログマクロのデフォルト定義
+ */
+#ifndef LOG_ACRE_MPF_ENTER
+#define LOG_ACRE_MPF_ENTER(pk_cmpf)
+#endif /* LOG_ACRE_MPF_ENTER */
+
+#ifndef LOG_ACRE_MPF_LEAVE
+#define LOG_ACRE_MPF_LEAVE(ercd)
+#endif /* LOG_ACRE_MPF_LEAVE */
+
+#ifndef LOG_DEL_MPF_ENTER
+#define LOG_DEL_MPF_ENTER(mpfid)
+#endif /* LOG_DEL_MPF_ENTER */
+
+#ifndef LOG_DEL_MPF_LEAVE
+#define LOG_DEL_MPF_LEAVE(ercd)
+#endif /* LOG_DEL_MPF_LEAVE */
+
+#ifndef LOG_GET_MPF_ENTER
+#define LOG_GET_MPF_ENTER(mpfid, p_blk)
+#endif /* LOG_GET_MPF_ENTER */
+
+#ifndef LOG_GET_MPF_LEAVE
+#define LOG_GET_MPF_LEAVE(ercd, blk)
+#endif /* LOG_GET_MPF_LEAVE */
+
+#ifndef LOG_PGET_MPF_ENTER
+#define LOG_PGET_MPF_ENTER(mpfid, p_blk)
+#endif /* LOG_PGET_MPF_ENTER */
+
+#ifndef LOG_PGET_MPF_LEAVE
+#define LOG_PGET_MPF_LEAVE(ercd, blk)
+#endif /* LOG_PGET_MPF_LEAVE */
+
+#ifndef LOG_TGET_MPF_ENTER
+#define LOG_TGET_MPF_ENTER(mpfid, p_blk, tmout)
+#endif /* LOG_TGET_MPF_ENTER */
+
+#ifndef LOG_TGET_MPF_LEAVE
+#define LOG_TGET_MPF_LEAVE(ercd, blk)
+#endif /* LOG_TGET_MPF_LEAVE */
+
+#ifndef LOG_REL_MPF_ENTER
+#define LOG_REL_MPF_ENTER(mpfid, blk)
+#endif /* LOG_REL_MPF_ENTER */
+
+#ifndef LOG_REL_MPF_LEAVE
+#define LOG_REL_MPF_LEAVE(ercd)
+#endif /* LOG_REL_MPF_LEAVE */
+
+#ifndef LOG_INI_MPF_ENTER
+#define LOG_INI_MPF_ENTER(mpfid)
+#endif /* LOG_INI_MPF_ENTER */
+
+#ifndef LOG_INI_MPF_LEAVE
+#define LOG_INI_MPF_LEAVE(ercd)
+#endif /* LOG_INI_MPF_LEAVE */
+
+#ifndef LOG_REF_MPF_ENTER
+#define LOG_REF_MPF_ENTER(mpfid, pk_rmpf)
+#endif /* LOG_REF_MPF_ENTER */
+
+#ifndef LOG_REF_MPF_LEAVE
+#define LOG_REF_MPF_LEAVE(ercd, pk_rmpf)
+#endif /* LOG_REF_MPF_LEAVE */
+
+/*
+ *  固定長メモリプールの数
+ */
+#define tnum_mpf	((uint_t)(tmax_mpfid - TMIN_MPFID + 1))
+#define tnum_smpf	((uint_t)(tmax_smpfid - TMIN_MPFID + 1))
+
+/*
+ *  固定長メモリプールIDから固定長メモリプール管理ブロックを取り出すた
+ *  めのマクロ
+ */
+#define INDEX_MPF(mpfid)	((uint_t)((mpfid) - TMIN_MPFID))
+#define get_mpfcb(mpfid)	(&(mpfcb_table[INDEX_MPF(mpfid)]))
+
+/*
+ *  特殊なインデックス値の定義
+ */
+#define INDEX_NULL		(~0U)		/* 空きブロックリストの最後 */
+#define INDEX_ALLOC		(~1U)		/* 割当て済みのブロック */
+
+#ifdef TOPPERS_mpfini
+
+/*
+ *  使用していない固定長メモリプール管理ブロックのリスト
+ */
+QUEUE	free_mpfcb;
+
+/*
+ *  固定長メモリプール機能の初期化
+ */
+void
+initialize_mempfix(void)
+{
+	uint_t	i, j;
+	MPFCB	*p_mpfcb;
+	MPFINIB	*p_mpfinib;
+
+	for (i = 0; i < tnum_smpf; i++) {
+		p_mpfcb = &(mpfcb_table[i]);
+		queue_initialize(&(p_mpfcb->wait_queue));
+		p_mpfcb->p_mpfinib = &(mpfinib_table[i]);
+		p_mpfcb->fblkcnt = p_mpfcb->p_mpfinib->blkcnt;
+		p_mpfcb->unused = 0U;
+		p_mpfcb->freelist = INDEX_NULL;
+	}
+	queue_initialize(&free_mpfcb);
+	for (j = 0; i < tnum_mpf; i++, j++) {
+		p_mpfcb = &(mpfcb_table[i]);
+		p_mpfinib = &(ampfinib_table[j]);
+		p_mpfinib->mpfatr = TA_NOEXS;
+		p_mpfcb->p_mpfinib = ((const MPFINIB *) p_mpfinib);
+		queue_insert_prev(&free_mpfcb, &(p_mpfcb->wait_queue));
+	}
+}
+
+#endif /* TOPPERS_mpfini */
+
+/*
+ *  固定長メモリプールからブロックを獲得
+ */
+#ifdef TOPPERS_mpfget
+
+void
+get_mpf_block(MPFCB *p_mpfcb, void **p_blk)
+{
+	uint_t	blkidx;
+
+	if (p_mpfcb->freelist != INDEX_NULL) {
+		blkidx = p_mpfcb->freelist;
+		p_mpfcb->freelist = (p_mpfcb->p_mpfinib->p_mpfmb + blkidx)->next;
+	}
+	else {
+		blkidx = p_mpfcb->unused;
+		p_mpfcb->unused++;
+	}
+	*p_blk = (void *)((char *)(p_mpfcb->p_mpfinib->mpf)
+								+ p_mpfcb->p_mpfinib->blksz * blkidx);
+	p_mpfcb->fblkcnt--;
+	(p_mpfcb->p_mpfinib->p_mpfmb + blkidx)->next = INDEX_ALLOC;
+}
+
+#endif /* TOPPERS_mpfget */
+
+/*
+ *  固定長メモリプールの生成
+ */
+#ifdef TOPPERS_acre_mpf
+
+ER_UINT
+acre_mpf(const T_CMPF *pk_cmpf)
+{
+	MPFCB	*p_mpfcb;
+	MPFINIB	*p_mpfinib;
+	ATR		mpfatr;
+	void	*mpf;
+	MPFMB	*p_mpfmb;
+	ER		ercd;
+
+	LOG_ACRE_MPF_ENTER(pk_cmpf);
+	CHECK_TSKCTX_UNL();
+	CHECK_RSATR(pk_cmpf->mpfatr, TA_TPRI);
+	CHECK_PAR(pk_cmpf->blkcnt != 0);
+	CHECK_PAR(pk_cmpf->blksz != 0);
+	if (pk_cmpf->mpf != NULL) {
+		CHECK_ALIGN_MPF(pk_cmpf->mpf);
+	}
+	if (pk_cmpf->mpfmb != NULL) {
+		CHECK_ALIGN_MB(pk_cmpf->mpfmb);
+	}
+	mpfatr = pk_cmpf->mpfatr;
+	mpf = pk_cmpf->mpf;
+	p_mpfmb = pk_cmpf->mpfmb;
+
+	t_lock_cpu();
+	if (tnum_mpf == 0 || queue_empty(&free_mpfcb)) {
+		ercd = E_NOID;
+	}
+	else {
+		if (mpf == NULL) {
+			mpf = kernel_malloc(ROUND_MPF_T(pk_cmpf->blksz) * pk_cmpf->blkcnt);
+			mpfatr |= TA_MEMALLOC;
+		}
+		if (mpf == NULL) {
+			ercd = E_NOMEM;
+		}
+		else {
+			if (p_mpfmb == NULL) {
+				p_mpfmb = kernel_malloc(sizeof(MPFMB) * pk_cmpf->blkcnt);
+				mpfatr |= TA_MBALLOC;
+			}
+			if (p_mpfmb == NULL) {
+				if (pk_cmpf->mpf == NULL) {
+					kernel_free(mpf);
+				}
+				ercd = E_NOMEM;
+			}
+			else {
+				p_mpfcb = ((MPFCB *) queue_delete_next(&free_mpfcb));
+				p_mpfinib = (MPFINIB *)(p_mpfcb->p_mpfinib);
+				p_mpfinib->mpfatr = mpfatr;
+				p_mpfinib->blkcnt = pk_cmpf->blkcnt;
+				p_mpfinib->blksz = ROUND_MPF_T(pk_cmpf->blksz);
+				p_mpfinib->mpf = mpf;
+				p_mpfinib->p_mpfmb = p_mpfmb;
+
+				queue_initialize(&(p_mpfcb->wait_queue));
+				p_mpfcb->fblkcnt = p_mpfcb->p_mpfinib->blkcnt;
+				p_mpfcb->unused = 0U;
+				p_mpfcb->freelist = INDEX_NULL;
+				ercd = MPFID(p_mpfcb);
+			}
+		}
+	}
+	t_unlock_cpu();
+
+  error_exit:
+	LOG_ACRE_MPF_LEAVE(ercd);
+	return(ercd);
+}
+
+#endif /* TOPPERS_acre_mpf */
+
+/*
+ *  固定長メモリプールの削除
+ */
+#ifdef TOPPERS_del_mpf
+
+ER
+del_mpf(ID mpfid)
+{
+	MPFCB	*p_mpfcb;
+	MPFINIB	*p_mpfinib;
+	bool_t	dspreq;
+	ER		ercd;
+
+	LOG_DEL_MPF_ENTER(mpfid);
+	CHECK_TSKCTX_UNL();
+	CHECK_MPFID(mpfid);
+	p_mpfcb = get_mpfcb(mpfid);
+
+	t_lock_cpu();
+	if (p_mpfcb->p_mpfinib->mpfatr == TA_NOEXS) {
+		ercd = E_NOEXS;
+	}
+	else if (MPFID(p_mpfcb) > tmax_smpfid) {
+		dspreq = init_wait_queue(&(p_mpfcb->wait_queue));
+		p_mpfinib = (MPFINIB *)(p_mpfcb->p_mpfinib);
+		if ((p_mpfinib->mpfatr & TA_MEMALLOC) != 0U) {
+			kernel_free(p_mpfinib->mpf);
+		}
+		if ((p_mpfinib->mpfatr & TA_MBALLOC) != 0U) {
+			kernel_free(p_mpfinib->p_mpfmb);
+		}
+		p_mpfinib->mpfatr = TA_NOEXS;
+		queue_insert_prev(&free_mpfcb, &(p_mpfcb->wait_queue));
+		if (dspreq) {
+			dispatch();
+		}
+		ercd = E_OK;
+	}
+	else {
+		ercd = E_OBJ;
+	}
+	t_unlock_cpu();
+
+  error_exit:
+	LOG_DEL_MPF_LEAVE(ercd);
+	return(ercd);
+}
+
+#endif /* TOPPERS_del_mpf */
+
+/*
+ *  固定長メモリブロックの獲得
+ */
+#ifdef TOPPERS_get_mpf
+
+ER
+get_mpf(ID mpfid, void **p_blk)
+{
+	MPFCB	*p_mpfcb;
+	WINFO_MPF winfo_mpf;
+	ER		ercd;
+
+	LOG_GET_MPF_ENTER(mpfid, p_blk);
+	CHECK_DISPATCH();
+	CHECK_MPFID(mpfid);
+	p_mpfcb = get_mpfcb(mpfid);
+
+	t_lock_cpu();
+	if (p_mpfcb->p_mpfinib->mpfatr == TA_NOEXS) {
+		ercd = E_NOEXS;
+	}
+	else if (p_mpfcb->fblkcnt > 0) {
+		get_mpf_block(p_mpfcb, p_blk);
+		ercd = E_OK;
+	}
+	else {
+		p_runtsk->tstat = (TS_WAITING | TS_WAIT_MPF);
+		wobj_make_wait((WOBJCB *) p_mpfcb, (WINFO_WOBJ *) &winfo_mpf);
+		dispatch();
+		ercd = winfo_mpf.winfo.wercd;
+		if (ercd == E_OK) {
+			*p_blk = winfo_mpf.blk;
+		}
+	}
+	t_unlock_cpu();
+
+  error_exit:
+	LOG_GET_MPF_LEAVE(ercd, *p_blk);
+	return(ercd);
+}
+
+#endif /* TOPPERS_get_mpf */
+
+/*
+ *  固定長メモリブロックの獲得（ポーリング）
+ */
+#ifdef TOPPERS_pget_mpf
+
+ER
+pget_mpf(ID mpfid, void **p_blk)
+{
+	MPFCB	*p_mpfcb;
+	ER		ercd;
+
+	LOG_PGET_MPF_ENTER(mpfid, p_blk);
+	CHECK_TSKCTX_UNL();
+	CHECK_MPFID(mpfid);
+	p_mpfcb = get_mpfcb(mpfid);
+
+	t_lock_cpu();
+	if (p_mpfcb->p_mpfinib->mpfatr == TA_NOEXS) {
+		ercd = E_NOEXS;
+	}
+	else if (p_mpfcb->fblkcnt > 0) {
+		get_mpf_block(p_mpfcb, p_blk);
+		ercd = E_OK;
+	}
+	else {
+		ercd = E_TMOUT;
+	}
+	t_unlock_cpu();
+
+  error_exit:
+	LOG_PGET_MPF_LEAVE(ercd, *p_blk);
+	return(ercd);
+}
+
+#endif /* TOPPERS_pget_mpf */
+
+/*
+ *  固定長メモリブロックの獲得（タイムアウトあり）
+ */
+#ifdef TOPPERS_tget_mpf
+
+ER
+tget_mpf(ID mpfid, void **p_blk, TMO tmout)
+{
+	MPFCB	*p_mpfcb;
+	WINFO_MPF winfo_mpf;
+	TMEVTB	tmevtb;
+	ER		ercd;
+
+	LOG_TGET_MPF_ENTER(mpfid, p_blk, tmout);
+	CHECK_DISPATCH();
+	CHECK_MPFID(mpfid);
+	CHECK_TMOUT(tmout);
+	p_mpfcb = get_mpfcb(mpfid);
+
+	t_lock_cpu();
+	if (p_mpfcb->p_mpfinib->mpfatr == TA_NOEXS) {
+		ercd = E_NOEXS;
+	}
+	else if (p_mpfcb->fblkcnt > 0) {
+		get_mpf_block(p_mpfcb, p_blk);
+		ercd = E_OK;
+	}
+	else if (tmout == TMO_POL) {
+		ercd = E_TMOUT;
+	}
+	else {
+		p_runtsk->tstat = (TS_WAITING | TS_WAIT_MPF);
+		wobj_make_wait_tmout((WOBJCB *) p_mpfcb, (WINFO_WOBJ *) &winfo_mpf,
+														&tmevtb, tmout);
+		dispatch();
+		ercd = winfo_mpf.winfo.wercd;
+		if (ercd == E_OK) {
+			*p_blk = winfo_mpf.blk;
+		}
+	}
+	t_unlock_cpu();
+
+  error_exit:
+	LOG_TGET_MPF_LEAVE(ercd, *p_blk);
+	return(ercd);
+}
+
+#endif /* TOPPERS_tget_mpf */
+
+/*
+ *  固定長メモリブロックの返却
+ */
+#ifdef TOPPERS_rel_mpf
+
+ER
+rel_mpf(ID mpfid, void *blk)
+{
+	MPFCB	*p_mpfcb;
+	SIZE	blkoffset;
+	uint_t	blkidx;
+	TCB		*p_tcb;
+	ER		ercd;
+    
+	LOG_REL_MPF_ENTER(mpfid, blk);
+	CHECK_TSKCTX_UNL();
+	CHECK_MPFID(mpfid);
+	p_mpfcb = get_mpfcb(mpfid);
+
+	t_lock_cpu();
+	if (p_mpfcb->p_mpfinib->mpfatr == TA_NOEXS) {
+		ercd = E_NOEXS;
+	}
+	else {
+		blkoffset = ((char *) blk) - (char *)(p_mpfcb->p_mpfinib->mpf);
+		blkidx = (uint_t)(blkoffset / p_mpfcb->p_mpfinib->blksz);
+		if (!(p_mpfcb->p_mpfinib->mpf <= blk)
+				|| !(blkoffset % p_mpfcb->p_mpfinib->blksz == 0U)
+				|| !(blkoffset / p_mpfcb->p_mpfinib->blksz < p_mpfcb->unused)
+				|| !((p_mpfcb->p_mpfinib->p_mpfmb + blkidx)->next
+															== INDEX_ALLOC)) {
+			ercd = E_PAR;
+		}
+		else if (!queue_empty(&(p_mpfcb->wait_queue))) {
+			p_tcb = (TCB *) queue_delete_next(&(p_mpfcb->wait_queue));
+			((WINFO_MPF *)(p_tcb->p_winfo))->blk = blk;
+			if (wait_complete(p_tcb)) {
+				dispatch();
+			}
+			ercd = E_OK;
+		}
+		else {
+			p_mpfcb->fblkcnt++;
+			(p_mpfcb->p_mpfinib->p_mpfmb + blkidx)->next = p_mpfcb->freelist;
+			p_mpfcb->freelist = blkidx;
+			ercd = E_OK;
+		}
+	}
+	t_unlock_cpu();
+
+  error_exit:
+	LOG_REL_MPF_LEAVE(ercd);
+	return(ercd);
+}
+
+#endif /* TOPPERS_rel_mpf */
+
+/*
+ *  固定長メモリプールの再初期化
+ */
+#ifdef TOPPERS_ini_mpf
+
+ER
+ini_mpf(ID mpfid)
+{
+	MPFCB	*p_mpfcb;
+	bool_t	dspreq;
+	ER		ercd;
+    
+	LOG_INI_MPF_ENTER(mpfid);
+	CHECK_TSKCTX_UNL();
+	CHECK_MPFID(mpfid);
+	p_mpfcb = get_mpfcb(mpfid);
+
+	t_lock_cpu();
+	if (p_mpfcb->p_mpfinib->mpfatr == TA_NOEXS) {
+		ercd = E_NOEXS;
+	}
+	else {
+		dspreq = init_wait_queue(&(p_mpfcb->wait_queue));
+		p_mpfcb->fblkcnt = p_mpfcb->p_mpfinib->blkcnt;
+		p_mpfcb->unused = 0U;
+		p_mpfcb->freelist = INDEX_NULL;
+		if (dspreq) {
+			dispatch();
+		}
+		ercd = E_OK;
+	}
+	t_unlock_cpu();
+
+  error_exit:
+	LOG_INI_MPF_LEAVE(ercd);
+	return(ercd);
+}
+
+#endif /* TOPPERS_ini_mpf */
+
+/*
+ *  固定長メモリプールの状態参照
+ */
+#ifdef TOPPERS_ref_mpf
+
+ER
+ref_mpf(ID mpfid, T_RMPF *pk_rmpf)
+{
+	MPFCB	*p_mpfcb;
+	ER		ercd;
+    
+	LOG_REF_MPF_ENTER(mpfid, pk_rmpf);
+	CHECK_TSKCTX_UNL();
+	CHECK_MPFID(mpfid);
+	p_mpfcb = get_mpfcb(mpfid);
+
+	t_lock_cpu();
+	if (p_mpfcb->p_mpfinib->mpfatr == TA_NOEXS) {
+		ercd = E_NOEXS;
+	}
+	else {
+		pk_rmpf->wtskid = wait_tskid(&(p_mpfcb->wait_queue));
+		pk_rmpf->fblkcnt = p_mpfcb->fblkcnt;
+		ercd = E_OK;
+	}
+	t_unlock_cpu();
+
+  error_exit:
+	LOG_REF_MPF_LEAVE(ercd, pk_rmpf);
+	return(ercd);
+}
+
+#endif /* TOPPERS_ref_mpf */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/kernel/mempfix.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/kernel/mempfix.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/kernel/mempfix.h	(revision 457)
@@ -0,0 +1,144 @@
+/*
+ *  TOPPERS/ASP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Advanced Standard Profile Kernel
+ * 
+ *  Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
+ *                              Toyohashi Univ. of Technology, JAPAN
+ *  Copyright (C) 2005-2012 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *		固定長メモリプール機能
+ */
+
+#ifndef TOPPERS_MEMPFIX_H
+#define TOPPERS_MEMPFIX_H
+
+#include "wait.h"
+
+/*
+ *  固定長メモリブロック管理ブロック
+ *
+ *  nextフィールドには，メモリブロックが割当て済みの場合はINDEX_ALLOCを，
+ *  未割当ての場合は次の未割当てブロックのインデックス番号を格納する．
+ *  最後の未割当てブロックの場合には，INDEX_NULLを格納する．
+ */
+typedef struct fixed_memoryblock_management_block {
+	uint_t		next;			/* 次の未割当てブロック */
+} MPFMB;
+
+/*
+ *  固定長メモリプール初期化ブロック
+ *
+ *  この構造体は，同期・通信オブジェクトの初期化ブロックの共通部分
+ *  （WOBJINIB）を拡張（オブジェクト指向言語の継承に相当）したもので，
+ *  最初のフィールドが共通になっている．
+ */
+typedef struct fixed_memorypool_initialization_block {
+	ATR			mpfatr;			/* 固定長メモリプール属性 */
+	uint_t		blkcnt;			/* メモリブロック数 */
+	uint_t		blksz;			/* メモリブロックのサイズ（丸めた値） */
+	void		*mpf;			/* 固定長メモリプール領域の先頭番地 */
+	MPFMB		*p_mpfmb;		/* 固定長メモリプール管理領域の先頭番地 */
+} MPFINIB;
+
+/*
+ *  固定長メモリプール管理ブロック
+ *
+ *  この構造体は，同期・通信オブジェクトの管理ブロックの共通部分（WOBJCB）
+ *  を拡張（オブジェクト指向言語の継承に相当）したもので，最初の2つの
+ *  フィールドが共通になっている．
+ */
+typedef struct fixed_memorypool_control_block {
+	QUEUE		wait_queue;		/* 固定長メモリプール待ちキュー */
+	const MPFINIB *p_mpfinib;	/* 初期化ブロックへのポインタ */
+	uint_t		fblkcnt;		/* 未割当てブロック数 */
+	uint_t		unused;			/* 未使用ブロックの先頭 */
+	uint_t		freelist;		/* 未割当てブロックのリスト */
+} MPFCB;
+
+/*
+ *  固定長メモリプール待ち情報ブロックの定義
+ *
+ *  この構造体は，同期・通信オブジェクトの待ち情報ブロックの共通部分
+ *  （WINFO_WOBJ）を拡張（オブジェクト指向言語の継承に相当）したもので，
+ *  最初の2つのフィールドが共通になっている．
+ */
+typedef struct fixed_memorypool_waiting_information {
+	WINFO		winfo;			/* 標準の待ち情報ブロック */
+	MPFCB		*p_mpfcb;		/* 待っている固定長メモリプールの管理ブロック*/
+	void		*blk;			/* 獲得したメモリブロック */
+} WINFO_MPF;
+
+/*
+ *  使用していない固定長メモリプール管理ブロックのリスト
+ */
+extern QUEUE	free_mpfcb;
+
+/*
+ *  固定長メモリプールIDの最大値（kernel_cfg.c）
+ */
+extern const ID	tmax_mpfid;
+extern const ID	tmax_smpfid;
+
+/*
+ *  固定長メモリプール初期化ブロックのエリア（kernel_cfg.c）
+ */
+extern const MPFINIB	mpfinib_table[];
+extern MPFINIB			ampfinib_table[];
+
+/*
+ *  固定長メモリプール管理ブロックのエリア（kernel_cfg.c）
+ */
+extern MPFCB	mpfcb_table[];
+
+/*
+ *  固定長メモリプール管理ブロックから固定長メモリプールIDを取り出すた
+ *  めのマクロ
+ */
+#define	MPFID(p_mpfcb)	((ID)(((p_mpfcb) - mpfcb_table) + TMIN_MPFID))
+
+/*
+ *  固定長メモリプール機能の初期化
+ */
+extern void	initialize_mempfix(void);
+
+/*
+ *  固定長メモリプールからブロックを獲得
+ */
+extern void	get_mpf_block(MPFCB *p_mpfcb, void **p_blk);
+
+#endif /* TOPPERS_MEMPFIX_H */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/kernel/mutex.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/kernel/mutex.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/kernel/mutex.c	(revision 457)
@@ -0,0 +1,781 @@
+/*
+ *  TOPPERS/ASP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Advanced Standard Profile Kernel
+ * 
+ *  Copyright (C) 2005-2014 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  $Id$
+ */
+
+/*
+ *		ミューテックス機能
+ */
+
+#include "kernel_impl.h"
+#include "check.h"
+#include "task.h"
+#include "wait.h"
+#include "mutex.h"
+
+/*
+ *  トレースログマクロのデフォルト定義
+ */
+#ifndef LOG_ACRE_MTX_ENTER
+#define LOG_ACRE_MTX_ENTER(mtxid)
+#endif /* LOG_ACRE_MTX_ENTER */
+
+#ifndef LOG_ACRE_MTX_LEAVE
+#define LOG_ACRE_MTX_LEAVE(ercd)
+#endif /* LOG_ACRE_MTX_LEAVE */
+
+#ifndef LOG_DEL_MTX_ENTER
+#define LOG_DEL_MTX_ENTER(mtxid)
+#endif /* LOG_DEL_MTX_ENTER */
+
+#ifndef LOG_DEL_MTX_LEAVE
+#define LOG_DEL_MTX_LEAVE(ercd)
+#endif /* LOG_DEL_MTX_LEAVE */
+
+#ifndef LOG_LOC_MTX_ENTER
+#define LOG_LOC_MTX_ENTER(mtxid)
+#endif /* LOG_LOC_MTX_ENTER */
+
+#ifndef LOG_LOC_MTX_LEAVE
+#define LOG_LOC_MTX_LEAVE(ercd)
+#endif /* LOG_LOC_MTX_LEAVE */
+
+#ifndef LOG_PLOC_MTX_ENTER
+#define LOG_PLOC_MTX_ENTER(mtxid)
+#endif /* LOG_PLOC_MTX_ENTER */
+
+#ifndef LOG_PLOC_MTX_LEAVE
+#define LOG_PLOC_MTX_LEAVE(ercd)
+#endif /* LOG_PLOC_MTX_LEAVE */
+
+#ifndef LOG_TLOC_MTX_ENTER
+#define LOG_TLOC_MTX_ENTER(mtxid, tmout)
+#endif /* LOG_TLOC_MTX_ENTER */
+
+#ifndef LOG_TLOC_MTX_LEAVE
+#define LOG_TLOC_MTX_LEAVE(ercd)
+#endif /* LOG_TLOC_MTX_LEAVE */
+
+#ifndef LOG_UNL_MTX_ENTER
+#define LOG_UNL_MTX_ENTER(mtxid)
+#endif /* LOG_UNL_MTX_ENTER */
+
+#ifndef LOG_UNL_MTX_LEAVE
+#define LOG_UNL_MTX_LEAVE(ercd)
+#endif /* LOG_UNL_MTX_LEAVE */
+
+#ifndef LOG_INI_MTX_ENTER
+#define LOG_INI_MTX_ENTER(mtxid)
+#endif /* LOG_INI_MTX_ENTER */
+
+#ifndef LOG_INI_MTX_LEAVE
+#define LOG_INI_MTX_LEAVE(ercd)
+#endif /* LOG_INI_MTX_LEAVE */
+
+#ifndef LOG_REF_MTX_ENTER
+#define LOG_REF_MTX_ENTER(mtxid, pk_rmtx)
+#endif /* LOG_REF_MTX_ENTER */
+
+#ifndef LOG_REF_MTX_LEAVE
+#define LOG_REF_MTX_LEAVE(ercd, pk_rmtx)
+#endif /* LOG_REF_MTX_LEAVE */
+
+/*
+ *  ミューテックスの数
+ */
+#define tnum_mtx	((uint_t)(tmax_mtxid - TMIN_MTXID + 1))
+#define tnum_smtx	((uint_t)(tmax_smtxid - TMIN_MTXID + 1))
+
+/*
+ *  ミューテックスIDからミューテックス管理ブロックを取り出すためのマクロ
+ */
+#define INDEX_MTX(mtxid)	((uint_t)((mtxid) - TMIN_MTXID))
+#define get_mtxcb(mtxid)	(&(mtxcb_table[INDEX_MTX(mtxid)]))
+
+/*
+ *  ミューテックス管理ブロック中のmutex_queueへのポインタから，ミューテッ
+ *  クス管理ブロックへのポインタを取り出すためのマクロ
+ */
+#define MTXCB_QUEUE(p_queue) \
+			((MTXCB *)(((char *) p_queue) - offsetof(MTXCB, mutex_queue)))
+
+/*
+ *  ミューテックスのプロトコルを判断するマクロ
+ */
+#define MTXPROTO_MASK			0x03U
+#define MTXPROTO(p_mtxcb)		((p_mtxcb)->p_mtxinib->mtxatr & MTXPROTO_MASK)
+#define MTX_CEILING(p_mtxcb)	(MTXPROTO(p_mtxcb) == TA_CEILING)
+
+/*
+ *  フックルーチン呼出し用の変数
+ */
+#ifdef TOPPERS_mtxhook
+
+bool_t	(*mtxhook_check_ceilpri)(TCB *p_tcb, uint_t bpriority) = NULL;
+bool_t	(*mtxhook_scan_ceilmtx)(TCB *p_tcb) = NULL;
+bool_t	(*mtxhook_release_all)(TCB *p_tcb) = NULL;
+
+#endif /* TOPPERS_mtxhook */
+
+/*
+ *  使用していないミューテックス管理ブロックのリスト
+ */
+QUEUE	free_mtxcb;
+
+/* 
+ *  ミューテックス機能の初期化
+ */
+#ifdef TOPPERS_mtxini
+
+void
+initialize_mutex(void)
+{
+	uint_t	i, j;
+	MTXCB	*p_mtxcb;
+	MTXINIB	*p_mtxinib;
+
+	mtxhook_check_ceilpri = mutex_check_ceilpri;
+	mtxhook_scan_ceilmtx = mutex_scan_ceilmtx;
+	mtxhook_release_all = mutex_release_all;
+
+	for (i = 0; i < tnum_smtx; i++) {
+		p_mtxcb = &(mtxcb_table[i]);
+		queue_initialize(&(p_mtxcb->wait_queue));
+		p_mtxcb->p_mtxinib = &(mtxinib_table[i]);
+		p_mtxcb->p_loctsk = NULL;
+	}
+	queue_initialize(&free_mtxcb);
+	for (j = 0; i < tnum_mtx; i++, j++) {
+		p_mtxcb = &(mtxcb_table[i]);
+		p_mtxinib = &(amtxinib_table[j]);
+		p_mtxinib->mtxatr = TA_NOEXS;
+		p_mtxcb->p_mtxinib = ((const MTXINIB *) p_mtxinib);
+		queue_insert_prev(&free_mtxcb, &(p_mtxcb->wait_queue));
+	}
+}
+
+#endif /* TOPPERS_mtxini */
+
+/* 
+ *  上限優先度違反のチェック
+ */
+#ifdef TOPPERS_mtxchk
+
+bool_t
+mutex_check_ceilpri(TCB *p_tcb, uint_t bpriority)
+{
+	QUEUE	*p_queue;
+	MTXCB	*p_mtxcb;
+
+	/*
+	 *  タスクがロックしている優先度上限ミューテックスの中で，上限優先
+	 *  度がbpriorityよりも低いものがあれば，falseを返す．
+	 */
+	p_queue = p_tcb->mutex_queue.p_next;
+	while (p_queue != &(p_tcb->mutex_queue)) {
+		p_mtxcb = MTXCB_QUEUE(p_queue);
+		if (MTX_CEILING(p_mtxcb) && bpriority < p_mtxcb->p_mtxinib->ceilpri) {
+			return(false);
+		}
+		p_queue = p_queue->p_next;
+	}
+
+	/*
+	 *  タスクが優先度上限ミューテックスのロックを待っている場合に，そ
+	 *  の上限優先度がbpriorityよりも低くければ，falseを返す．
+	 */
+	if (TSTAT_WAIT_MTX(p_tcb->tstat)) {
+		p_mtxcb = ((WINFO_MTX *)(p_tcb->p_winfo))->p_mtxcb;
+		if (MTX_CEILING(p_mtxcb) && bpriority < p_mtxcb->p_mtxinib->ceilpri) {
+			return(false);
+		}
+	}
+
+	/*
+	 *  いずれの条件にも当てはまらなければtrueを返す．
+	 */
+	return(true);
+}
+
+#endif /* TOPPERS_mtxchk */
+
+/* 
+ *  優先度上限ミューテックスをロックしているかのチェック
+ */
+#ifdef TOPPERS_mtxscan
+
+bool_t
+mutex_scan_ceilmtx(TCB *p_tcb)
+{
+	QUEUE	*p_queue;
+	MTXCB	*p_mtxcb;
+
+	p_queue = p_tcb->mutex_queue.p_next;
+	while (p_queue != &(p_tcb->mutex_queue)) {
+		p_mtxcb = MTXCB_QUEUE(p_queue);
+		if (MTX_CEILING(p_mtxcb)) {
+			return(true);
+		}
+		p_queue = p_queue->p_next;
+	}
+	return(false);
+}
+
+#endif /* TOPPERS_mtxscan */
+
+/* 
+ *  タスクの現在優先度の計算
+ */
+#ifdef TOPPERS_mtxcalc
+
+uint_t
+mutex_calc_priority(TCB *p_tcb)
+{
+	uint_t	priority;
+	QUEUE	*p_queue;
+	MTXCB	*p_mtxcb;
+
+	priority = p_tcb->bpriority;
+	p_queue = p_tcb->mutex_queue.p_next;
+	while (p_queue != &(p_tcb->mutex_queue)) {
+		p_mtxcb = MTXCB_QUEUE(p_queue);
+		if (MTX_CEILING(p_mtxcb) && p_mtxcb->p_mtxinib->ceilpri < priority) {
+			priority = p_mtxcb->p_mtxinib->ceilpri;
+		}
+		p_queue = p_queue->p_next;
+	}
+	return(priority);
+}
+
+#endif /* TOPPERS_mtxcalc */
+
+/*
+ *  要素優先度が上がる（または増える）場合の現在優先度変更処理
+ */
+Inline bool_t
+mutex_raise_priority(TCB *p_tcb, uint_t newpri)
+{
+	if (newpri < p_tcb->priority) {
+		return(change_priority(p_tcb, newpri, true));
+	}
+	return(false);
+}
+
+/*
+ *  要素優先度が下がる（または減る）場合の現在優先度変更処理
+ */
+Inline bool_t
+mutex_drop_priority(TCB *p_tcb, uint_t oldpri)
+{
+	uint_t	newpri;
+
+	if (oldpri == p_tcb->priority) {
+		newpri = mutex_calc_priority(p_tcb);
+		if (newpri != p_tcb->priority) {
+			return(change_priority(p_tcb, newpri, true));
+		}
+	}
+	return(false);
+}
+
+/*
+ *  ミューテックスをロックした場合の処理
+ */
+Inline bool_t
+mutex_acquire(TCB *p_loctsk, MTXCB *p_mtxcb)
+{
+	p_mtxcb->p_loctsk = p_loctsk;
+	queue_insert_next(&(p_loctsk->mutex_queue), &(p_mtxcb->mutex_queue));
+	if (MTX_CEILING(p_mtxcb)) {
+		return(mutex_raise_priority(p_loctsk, p_mtxcb->p_mtxinib->ceilpri));
+	}
+	return(false);
+}
+
+/*
+ *  ミューテックスのロック解除
+ */
+#ifdef TOPPERS_mtxrel
+
+bool_t
+mutex_release(MTXCB *p_mtxcb)
+{
+	TCB		*p_tcb;
+
+	if (queue_empty(&(p_mtxcb->wait_queue))) {
+		p_mtxcb->p_loctsk = NULL;
+		return(false);
+	}
+	else {
+		/*
+		 *  ミューテックス待ちキューの先頭タスク（p_tcb）に，ミューテッ
+		 *  クスをロックさせる．
+		 */
+		p_tcb = (TCB *) queue_delete_next(&(p_mtxcb->wait_queue));
+		wait_dequeue_tmevtb(p_tcb);
+		p_tcb->p_winfo->wercd = E_OK;
+
+		p_mtxcb->p_loctsk = p_tcb;
+		queue_insert_prev(&(p_tcb->mutex_queue), &(p_mtxcb->mutex_queue));
+		if (MTX_CEILING(p_mtxcb)) {
+			if (p_mtxcb->p_mtxinib->ceilpri < p_tcb->priority) {
+				p_tcb->priority = p_mtxcb->p_mtxinib->ceilpri;
+			}
+		}
+		return(make_non_wait(p_tcb));
+	}
+}
+
+#endif /* TOPPERS_mtxrel */
+
+/*
+ *  タスクがロックしているすべてのミューテックスのロック解除
+ */
+#ifdef TOPPERS_mtxrela
+
+bool_t
+mutex_release_all(TCB *p_tcb)
+{
+	MTXCB	*p_mtxcb;
+	bool_t	dspreq = false;
+
+	while (!queue_empty(&(p_tcb->mutex_queue))) {
+		p_mtxcb = MTXCB_QUEUE(p_tcb->mutex_queue.p_next);
+		queue_delete(&(p_mtxcb->mutex_queue));
+		if (mutex_release(p_mtxcb)) {
+			dspreq = true;
+		}
+	}
+	return(dspreq);
+}
+
+#endif /* TOPPERS_mtxrela */
+
+/*
+ *  ミューテックスの生成
+ */
+#ifdef TOPPERS_acre_mtx
+
+ER_UINT
+acre_mtx(const T_CMTX *pk_cmtx)
+{
+	MTXCB	*p_mtxcb;
+	MTXINIB	*p_mtxinib;
+	ATR		mtxatr;
+	PRI		ceilpri;
+	ER		ercd;
+
+	LOG_ACRE_MTX_ENTER(pk_cmtx);
+	CHECK_TSKCTX_UNL();
+
+	mtxatr = pk_cmtx->mtxatr;
+	ceilpri = pk_cmtx->ceilpri;
+
+	if (mtxatr == TA_CEILING) {
+		CHECK_PAR(VALID_TPRI(ceilpri));
+	}
+	else {
+		CHECK_RSATR(mtxatr, TA_TPRI);
+	}
+
+	t_lock_cpu();
+	if (tnum_mtx == 0 || queue_empty(&free_mtxcb)) {
+		ercd = E_NOID;
+	}
+	else {
+		p_mtxcb = ((MTXCB *) queue_delete_next(&free_mtxcb));
+		p_mtxinib = (MTXINIB *)(p_mtxcb->p_mtxinib);
+		p_mtxinib->mtxatr = mtxatr;
+		p_mtxinib->ceilpri = INT_PRIORITY(ceilpri);
+
+		queue_initialize(&(p_mtxcb->wait_queue));
+		queue_initialize(&(p_mtxcb->mutex_queue));
+		ercd = MTXID(p_mtxcb);
+	}
+	t_unlock_cpu();
+
+  error_exit:
+	LOG_ACRE_MTX_LEAVE(ercd);
+	return(ercd);
+}
+
+#endif /* TOPPERS_acre_mtx */
+
+/*
+ *  ミューテックスの削除
+ */
+#ifdef TOPPERS_del_mtx
+
+ER
+del_mtx(ID mtxid)
+{
+	MTXCB	*p_mtxcb;
+	bool_t	dspreq = false;
+	MTXINIB	*p_mtxinib;
+	TCB		*p_loctsk;
+	ER		ercd;
+
+	LOG_DEL_MTX_ENTER(mtxid);
+	CHECK_TSKCTX_UNL();
+	CHECK_MTXID(mtxid);
+	p_mtxcb = get_mtxcb(mtxid);
+
+	t_lock_cpu();
+	if (p_mtxcb->p_mtxinib->mtxatr == TA_NOEXS) {
+		ercd = E_NOEXS;
+	}
+	else if (MTXID(p_mtxcb) > tmax_smtxid) {
+		dspreq = init_wait_queue(&(p_mtxcb->wait_queue));
+		p_loctsk = p_mtxcb->p_loctsk;
+		if (p_loctsk != NULL) {
+			queue_delete(&(p_mtxcb->mutex_queue));
+			p_mtxcb->p_loctsk = NULL;
+			if (MTX_CEILING(p_mtxcb)) {
+				if (mutex_drop_priority(p_loctsk, p_mtxcb->p_mtxinib->ceilpri)) {
+					dspreq = true;
+				}
+			}
+		}
+		p_mtxinib = (MTXINIB *)(p_mtxcb->p_mtxinib);
+		p_mtxinib->mtxatr = TA_NOEXS;
+		queue_insert_prev(&free_mtxcb, &(p_mtxcb->wait_queue));
+		if (dspreq) {
+			dispatch();
+		}
+		ercd = E_OK;
+	}
+	else {
+		ercd = E_OBJ;
+	}
+	t_unlock_cpu();
+
+  error_exit:
+	LOG_DEL_MTX_LEAVE(ercd);
+	return(ercd);
+}
+
+#endif /* TOPPERS_del_mtx */
+
+/*
+ *  ミューテックスのロック
+ */
+#ifdef TOPPERS_loc_mtx
+
+ER
+loc_mtx(ID mtxid)
+{
+	MTXCB	*p_mtxcb;
+	WINFO_MTX winfo_mtx;
+	ER		ercd;
+
+	LOG_LOC_MTX_ENTER(mtxid);
+	CHECK_DISPATCH();
+	CHECK_MTXID(mtxid);
+	p_mtxcb = get_mtxcb(mtxid);
+
+	t_lock_cpu();
+	if (p_mtxcb->p_mtxinib->mtxatr == TA_NOEXS) {
+		ercd = E_NOEXS;
+	}
+	else if (MTX_CEILING(p_mtxcb)
+				&& p_runtsk->bpriority < p_mtxcb->p_mtxinib->ceilpri) {
+		ercd = E_ILUSE;
+	}
+	else if (p_mtxcb->p_loctsk == NULL) {
+		(void) mutex_acquire(p_runtsk, p_mtxcb);
+		/*
+		 *  優先度上限ミューテックスをロックした場合，p_runtskの優先度
+		 *  が上がる可能性があるが，ディスパッチが必要になることはない．
+		 */
+		assert(!(p_runtsk != p_schedtsk && dspflg));
+		ercd = E_OK;
+	}
+	else if (p_mtxcb->p_loctsk == p_runtsk) {
+		ercd = E_OBJ;
+	}
+	else {
+		p_runtsk->tstat = (TS_WAITING | TS_WAIT_MTX);
+		wobj_make_wait((WOBJCB *) p_mtxcb, (WINFO_WOBJ *) &winfo_mtx);
+		dispatch();
+		ercd = winfo_mtx.winfo.wercd;
+	}
+	t_unlock_cpu();
+
+  error_exit:
+	LOG_LOC_MTX_LEAVE(ercd);
+	return(ercd);
+}
+
+#endif /* TOPPERS_loc_mtx */
+
+/*
+ *  ミューテックスのロック（ポーリング）
+ */
+#ifdef TOPPERS_ploc_mtx
+
+ER
+ploc_mtx(ID mtxid)
+{
+	MTXCB	*p_mtxcb;
+	ER		ercd;
+
+	LOG_PLOC_MTX_ENTER(mtxid);
+	CHECK_TSKCTX_UNL();
+	CHECK_MTXID(mtxid);
+	p_mtxcb = get_mtxcb(mtxid);
+
+	t_lock_cpu();
+	if (p_mtxcb->p_mtxinib->mtxatr == TA_NOEXS) {
+		ercd = E_NOEXS;
+	}
+	else if (MTX_CEILING(p_mtxcb)
+				&& p_runtsk->bpriority < p_mtxcb->p_mtxinib->ceilpri) {
+		ercd = E_ILUSE;
+	}
+	else if (p_mtxcb->p_loctsk == NULL) {
+		(void) mutex_acquire(p_runtsk, p_mtxcb);
+		/*
+		 *  優先度上限ミューテックスをロックした場合，p_runtskの優先度
+		 *  が上がる可能性があるが，ディスパッチが必要になることはない．
+		 */
+		assert(!(p_runtsk != p_schedtsk && dspflg));
+		ercd = E_OK;
+	}
+	else if (p_mtxcb->p_loctsk == p_runtsk) {
+		ercd = E_OBJ;
+	}
+	else {
+		ercd = E_TMOUT;
+	}
+	t_unlock_cpu();
+
+  error_exit:
+	LOG_PLOC_MTX_LEAVE(ercd);
+	return(ercd);
+}
+
+#endif /* TOPPERS_ploc_mtx */
+
+/*
+ *  ミューテックスのロック（タイムアウトあり）
+ */
+#ifdef TOPPERS_tloc_mtx
+
+ER
+tloc_mtx(ID mtxid, TMO tmout)
+{
+	MTXCB	*p_mtxcb;
+	WINFO_MTX winfo_mtx;
+	TMEVTB	tmevtb;
+	ER		ercd;
+
+	LOG_TLOC_MTX_ENTER(mtxid, tmout);
+	CHECK_DISPATCH();
+	CHECK_MTXID(mtxid);
+	CHECK_TMOUT(tmout);
+	p_mtxcb = get_mtxcb(mtxid);
+
+	t_lock_cpu();
+	if (p_mtxcb->p_mtxinib->mtxatr == TA_NOEXS) {
+		ercd = E_NOEXS;
+	}
+	else if (MTX_CEILING(p_mtxcb)
+				&& p_runtsk->bpriority < p_mtxcb->p_mtxinib->ceilpri) {
+		ercd = E_ILUSE;
+	}
+	else if (p_mtxcb->p_loctsk == NULL) {
+		(void) mutex_acquire(p_runtsk, p_mtxcb);
+		/*
+		 *  優先度上限ミューテックスをロックした場合，p_runtskの優先度
+		 *  が上がる可能性があるが，ディスパッチが必要になることはない．
+		 */
+		assert(!(p_runtsk != p_schedtsk && dspflg));
+		ercd = E_OK;
+	}
+	else if (p_mtxcb->p_loctsk == p_runtsk) {
+		ercd = E_OBJ;
+	}
+	else if (tmout == TMO_POL) {
+		ercd = E_TMOUT;
+	}
+	else {
+		p_runtsk->tstat = (TS_WAITING | TS_WAIT_MTX);
+		wobj_make_wait_tmout((WOBJCB *) p_mtxcb, (WINFO_WOBJ *) &winfo_mtx,
+														&tmevtb, tmout);
+		dispatch();
+		ercd = winfo_mtx.winfo.wercd;
+	}
+	t_unlock_cpu();
+
+  error_exit:
+	LOG_TLOC_MTX_LEAVE(ercd);
+	return(ercd);
+}
+
+#endif /* TOPPERS_tloc_mtx */
+
+/*
+ *  ミューテックスのロック解除
+ */
+#ifdef TOPPERS_unl_mtx
+
+ER
+unl_mtx(ID mtxid)
+{
+	MTXCB	*p_mtxcb;
+	bool_t	dspreq = false;
+	ER		ercd;
+    
+	LOG_UNL_MTX_ENTER(mtxid);
+	CHECK_TSKCTX_UNL();
+	CHECK_MTXID(mtxid);
+	p_mtxcb = get_mtxcb(mtxid);
+
+	t_lock_cpu();
+	if (p_mtxcb->p_mtxinib->mtxatr == TA_NOEXS) {
+		ercd = E_NOEXS;
+	}
+	else if (p_mtxcb->p_loctsk != p_runtsk) {
+		ercd = E_OBJ;
+	}
+	else {
+		queue_delete(&(p_mtxcb->mutex_queue));
+		if (MTX_CEILING(p_mtxcb)) {
+			if (mutex_drop_priority(p_runtsk, p_mtxcb->p_mtxinib->ceilpri)) {
+				dspreq = true;
+			}
+		}
+		if (mutex_release(p_mtxcb)) {
+			dspreq = true;
+		}
+		if (dspreq) {
+			dispatch();
+		}
+		ercd = E_OK;
+	}
+	t_unlock_cpu();
+
+  error_exit:
+	LOG_UNL_MTX_LEAVE(ercd);
+	return(ercd);
+}
+
+#endif /* TOPPERS_unl_mtx */
+
+/*
+ *  ミューテックスの初期化
+ */
+#ifdef TOPPERS_ini_mtx
+
+ER
+ini_mtx(ID mtxid)
+{
+	MTXCB	*p_mtxcb;
+	TCB		*p_loctsk;
+	bool_t	dspreq;
+	ER		ercd;
+    
+	LOG_INI_MTX_ENTER(mtxid);
+	CHECK_TSKCTX_UNL();
+	CHECK_MTXID(mtxid);
+	p_mtxcb = get_mtxcb(mtxid);
+
+	t_lock_cpu();
+	if (p_mtxcb->p_mtxinib->mtxatr == TA_NOEXS) {
+		ercd = E_NOEXS;
+	}
+	else {
+		dspreq = init_wait_queue(&(p_mtxcb->wait_queue));
+		p_loctsk = p_mtxcb->p_loctsk;
+		if (p_loctsk != NULL) {
+			queue_delete(&(p_mtxcb->mutex_queue));
+			p_mtxcb->p_loctsk = NULL;
+			if (MTX_CEILING(p_mtxcb)) {
+				if (mutex_drop_priority(p_loctsk, p_mtxcb->p_mtxinib->ceilpri)) {
+					dspreq = true;
+				}
+			}
+		}
+		if (dspreq) {
+			dispatch();
+		}
+		ercd = E_OK;
+	}
+	t_unlock_cpu();
+
+  error_exit:
+	LOG_INI_MTX_LEAVE(ercd);
+	return(ercd);
+}
+
+#endif /* TOPPERS_ini_mtx */
+
+/*
+ *  ミューテックスの状態参照
+ */
+#ifdef TOPPERS_ref_mtx
+
+ER
+ref_mtx(ID mtxid, T_RMTX *pk_rmtx)
+{
+	MTXCB	*p_mtxcb;
+	ER		ercd;
+    
+	LOG_REF_MTX_ENTER(mtxid, pk_rmtx);
+	CHECK_TSKCTX_UNL();
+	CHECK_MTXID(mtxid);
+	p_mtxcb = get_mtxcb(mtxid);
+
+	t_lock_cpu();
+	if (p_mtxcb->p_mtxinib->mtxatr == TA_NOEXS) {
+		ercd = E_NOEXS;
+	}
+	else {
+		pk_rmtx->htskid = (p_mtxcb->p_loctsk != NULL) ? TSKID(p_mtxcb->p_loctsk)
+														: TSK_NONE;
+		pk_rmtx->wtskid = wait_tskid(&(p_mtxcb->wait_queue));
+		ercd = E_OK;
+	}
+	t_unlock_cpu();
+
+  error_exit:
+	LOG_REF_MTX_LEAVE(ercd, pk_rmtx);
+	return(ercd);
+}
+
+#endif /* TOPPERS_ref_mtx */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/kernel/mutex.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/kernel/mutex.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/kernel/mutex.h	(revision 457)
@@ -0,0 +1,174 @@
+/*
+ *  TOPPERS/ASP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Advanced Standard Profile Kernel
+ * 
+ *  Copyright (C) 2000 by Embedded and Real-Time Systems Laboratory
+ *                              Toyohashi Univ. of Technology, JAPAN
+ *  Copyright (C) 2005-2012 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *		ミューテックス機能
+ */
+
+#ifndef TOPPERS_MUTEX_H
+#define TOPPERS_MUTEX_H
+
+#include "wait.h"
+
+/*
+ *  ミューテックス初期化ブロック
+ *
+ *  この構造体は，同期・通信オブジェクトの初期化ブロックの共通部分
+ *  （WOBJINIB）を拡張（オブジェクト指向言語の継承に相当）したもので，
+ *  最初のフィールドが共通になっている．
+ */
+typedef struct mutex_initialization_block {
+	ATR			mtxatr;			/* ミューテックス属性 */
+	uint_t		ceilpri;		/* ミューテックスの上限優先度（内部表現）*/
+} MTXINIB;
+
+/*
+ *  ミューテックス管理ブロック
+ *
+ *  この構造体は，同期・通信オブジェクトの管理ブロックの共通部分（WOBJCB）
+ *  を拡張（オブジェクト指向言語の継承に相当）したもので，最初の2つの
+ *  フィールドが共通になっている．
+ */
+typedef struct mutex_control_block {
+	QUEUE		wait_queue;		/* ミューテックス待ちキュー */
+	const MTXINIB *p_mtxinib;	/* 初期化ブロックへのポインタ */
+	TCB			*p_loctsk;		/* ミューテックスをロックしているタスク */
+	QUEUE		mutex_queue;	/* ロックしているミューテックスのキュー */
+} MTXCB;
+
+/*
+ *  ミューテックス待ち情報ブロックの定義
+ *
+ *  この構造体は，同期・通信オブジェクトの待ち情報ブロックの共通部分
+ *  （WINFO_WOBJ）を拡張（オブジェクト指向言語の継承に相当）したもので，
+ *  すべてのフィールドが共通になっている．
+ */
+typedef struct mutex_waiting_information {
+	WINFO	winfo;			/* 標準の待ち情報ブロック */
+	MTXCB	*p_mtxcb;		/* 待っているミューテックスの管理ブロック */
+} WINFO_MTX;
+
+/*
+ *  使用していないミューテックス管理ブロックのリスト
+ */
+extern QUEUE	free_mtxcb;
+
+/*
+ *  ミューテックスIDの最大値（kernel_cfg.c）
+ */
+extern const ID	tmax_mtxid;
+extern const ID	tmax_smtxid;
+
+/*
+ *  ミューテックス初期化ブロックのエリア（kernel_cfg.c）
+ */
+extern const MTXINIB	mtxinib_table[];
+extern MTXINIB			amtxinib_table[];
+
+/*
+ *  ミューテックス管理ブロックのエリア（kernel_cfg.c）
+ */
+extern MTXCB	mtxcb_table[];
+
+/*
+ *  ミューテックス管理ブロックからミューテックスIDを取り出すためのマクロ
+ */
+#define	MTXID(p_mtxcb)	((ID)(((p_mtxcb) - mtxcb_table) + TMIN_MTXID))
+
+/*
+ *  ミューテックス機能の初期化
+ */
+extern void	initialize_mutex(void);
+
+/*
+ *  上限優先度違反のチェック
+ *
+ *  chg_priの中で上限優先度違反のチェックを行うために用いる関数であり，
+ *  p_tcbで指定されるタスクがロックしている優先度上限ミューテックスと，
+ *  ロックを待っている優先度上限ミューテックスの中で，上限優先度が
+ *  bpriorityよりも低いものがあればfalseを，そうでなければtrueを返す．
+ */
+extern bool_t	(*mtxhook_check_ceilpri)(TCB *p_tcb, uint_t bpriority);
+extern bool_t	mutex_check_ceilpri(TCB *p_tcb, uint_t bpriority);
+
+/* 
+ *  優先度上限ミューテックスをロックしているかのチェック
+ *
+ *  p_tcbで指定されるタスクが優先度上限ミューテックスをロックしていれば
+ *  true，そうでなければfalseを返す．
+ */
+extern bool_t	(*mtxhook_scan_ceilmtx)(TCB *p_tcb);
+extern bool_t	mutex_scan_ceilmtx(TCB *p_tcb);
+
+/* 
+ *  タスクの現在優先度の計算
+ *
+ *  p_tcbで指定されるタスクの現在優先度（に設定すべき値）を計算する．
+ */
+extern uint_t	mutex_calc_priority(TCB *p_tcb);
+
+/*
+ *  ミューテックスのロック解除
+ *
+ *  p_mtxcbで指定されるミューテックスをロック解除する．ロック解除した
+ *  ミューテックスに，ロック待ち状態のタスクがある場合には，そのタスク
+ *  にミューテックスをロックさせる．
+ */
+extern bool_t	mutex_release(MTXCB *p_mtxcb);
+
+/*
+ *  タスクがロックしているすべてのミューテックスのロック解除
+ *
+ *  p_tcbで指定されるタスクに，それがロックしているすべてのミューテック
+ *  スをロック解除させる．ロック解除したミューテックスに，ロック待ち状
+ *  態のタスクがある場合には，そのタスクにミューテックスをロックさせる．
+ *
+ *  この関数は，タスクの終了時に使われるものであるため，p_tcbで指定され
+ *  るタスクの優先度を変更する処理は行わない．ただし，この関数の中で他
+ *  のタスクの優先度が変化し，実行すべきタスクが変わることがある．その
+ *  ため，この関数から戻った後に，ディスパッチが必要か判別して，必要な
+ *  場合にはディスパッチを行わなければならない．
+ */
+extern bool_t	(*mtxhook_release_all)(TCB *p_tcb);
+extern bool_t	mutex_release_all(TCB *p_tcb);
+
+#endif /* TOPPERS_MUTEX_H */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/kernel/pridataq.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/kernel/pridataq.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/kernel/pridataq.c	(revision 457)
@@ -0,0 +1,849 @@
+/*
+ *  TOPPERS/ASP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Advanced Standard Profile Kernel
+ * 
+ *  Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
+ *                              Toyohashi Univ. of Technology, JAPAN
+ *  Copyright (C) 2005-2014 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  $Id$
+ */
+
+/*
+ *		優先度データキュー機能
+ */
+
+#include "kernel_impl.h"
+#include "check.h"
+#include "task.h"
+#include "wait.h"
+#include "pridataq.h"
+
+/*
+ *  トレースログマクロのデフォルト定義
+ */
+#ifndef LOG_ACRE_PDQ_ENTER
+#define LOG_ACRE_PDQ_ENTER(pk_cpdq)
+#endif /* LOG_ACRE_PDQ_ENTER */
+
+#ifndef LOG_ACRE_PDQ_LEAVE
+#define LOG_ACRE_PDQ_LEAVE(ercd)
+#endif /* LOG_ACRE_PDQ_LEAVE */
+
+#ifndef LOG_DEL_PDQ_ENTER
+#define LOG_DEL_PDQ_ENTER(pdqid)
+#endif /* LOG_DEL_PDQ_ENTER */
+
+#ifndef LOG_DEL_PDQ_LEAVE
+#define LOG_DEL_PDQ_LEAVE(ercd)
+#endif /* LOG_DEL_PDQ_LEAVE */
+
+#ifndef LOG_SND_PDQ_ENTER
+#define LOG_SND_PDQ_ENTER(pdqid, data, datapri)
+#endif /* LOG_SND_PDQ_ENTER */
+
+#ifndef LOG_SND_PDQ_LEAVE
+#define LOG_SND_PDQ_LEAVE(ercd)
+#endif /* LOG_SND_PDQ_LEAVE */
+
+#ifndef LOG_PSND_PDQ_ENTER
+#define LOG_PSND_PDQ_ENTER(pdqid, data, datapri)
+#endif /* LOG_PSND_PDQ_ENTER */
+
+#ifndef LOG_PSND_PDQ_LEAVE
+#define LOG_PSND_PDQ_LEAVE(ercd)
+#endif /* LOG_PSND_PDQ_LEAVE */
+
+#ifndef LOG_IPSND_PDQ_ENTER
+#define LOG_IPSND_PDQ_ENTER(pdqid, data, datapri)
+#endif /* LOG_IPSND_PDQ_ENTER */
+
+#ifndef LOG_IPSND_PDQ_LEAVE
+#define LOG_IPSND_PDQ_LEAVE(ercd)
+#endif /* LOG_IPSND_PDQ_LEAVE */
+
+#ifndef LOG_TSND_PDQ_ENTER
+#define LOG_TSND_PDQ_ENTER(pdqid, data, datapri, tmout)
+#endif /* LOG_TSND_PDQ_ENTER */
+
+#ifndef LOG_TSND_PDQ_LEAVE
+#define LOG_TSND_PDQ_LEAVE(ercd)
+#endif /* LOG_TSND_PDQ_LEAVE */
+
+#ifndef LOG_RCV_PDQ_ENTER
+#define LOG_RCV_PDQ_ENTER(pdqid, p_data, p_datapri)
+#endif /* LOG_RCV_PDQ_ENTER */
+
+#ifndef LOG_RCV_PDQ_LEAVE
+#define LOG_RCV_PDQ_LEAVE(ercd, data, datapri)
+#endif /* LOG_RCV_PDQ_LEAVE */
+
+#ifndef LOG_PRCV_PDQ_ENTER
+#define LOG_PRCV_PDQ_ENTER(pdqid, p_data, p_datapri)
+#endif /* LOG_PRCV_PDQ_ENTER */
+
+#ifndef LOG_PRCV_PDQ_LEAVE
+#define LOG_PRCV_PDQ_LEAVE(ercd, data, datapri)
+#endif /* LOG_PRCV_PDQ_LEAVE */
+
+#ifndef LOG_TRCV_PDQ_ENTER
+#define LOG_TRCV_PDQ_ENTER(pdqid, p_data, p_datapri, tmout)
+#endif /* LOG_TRCV_PDQ_ENTER */
+
+#ifndef LOG_TRCV_PDQ_LEAVE
+#define LOG_TRCV_PDQ_LEAVE(ercd, data, datapri)
+#endif /* LOG_TRCV_PDQ_LEAVE */
+
+#ifndef LOG_INI_PDQ_ENTER
+#define LOG_INI_PDQ_ENTER(pdqid)
+#endif /* LOG_INI_PDQ_ENTER */
+
+#ifndef LOG_INI_PDQ_LEAVE
+#define LOG_INI_PDQ_LEAVE(ercd)
+#endif /* LOG_INI_PDQ_LEAVE */
+
+#ifndef LOG_REF_PDQ_ENTER
+#define LOG_REF_PDQ_ENTER(pdqid, pk_rpdq)
+#endif /* LOG_REF_PDQ_ENTER */
+
+#ifndef LOG_REF_PDQ_LEAVE
+#define LOG_REF_PDQ_LEAVE(ercd, pk_rpdq)
+#endif /* LOG_REF_PDQ_LEAVE */
+
+/*
+ *  優先度データキューの数
+ */
+#define tnum_pdq	((uint_t)(tmax_pdqid - TMIN_PDQID + 1))
+#define tnum_spdq	((uint_t)(tmax_spdqid - TMIN_PDQID + 1))
+
+/*
+ *  優先度データキューIDから優先度データキュー管理ブロックを取り出すた
+ *  めのマクロ
+ */
+#define INDEX_PDQ(pdqid)	((uint_t)((pdqid) - TMIN_PDQID))
+#define get_pdqcb(pdqid)	(&(pdqcb_table[INDEX_PDQ(pdqid)]))
+
+#ifdef TOPPERS_pdqini
+
+/*
+ *  使用していない優先度データキュー管理ブロックのリスト
+ */
+QUEUE	free_pdqcb;
+
+/*
+ *  優先度データキュー機能の初期化
+ */
+void
+initialize_pridataq(void)
+{
+	uint_t	i, j;
+	PDQCB	*p_pdqcb;
+	PDQINIB	*p_pdqinib;
+
+	for (i = 0; i < tnum_spdq; i++) {
+		p_pdqcb = &(pdqcb_table[i]);
+		queue_initialize(&(p_pdqcb->swait_queue));
+		p_pdqcb->p_pdqinib = &(pdqinib_table[i]);
+		queue_initialize(&(p_pdqcb->rwait_queue));
+		p_pdqcb->count = 0U;
+		p_pdqcb->p_head = NULL;
+		p_pdqcb->unused = 0U;
+		p_pdqcb->p_freelist = NULL;
+	}
+	queue_initialize(&free_pdqcb);
+	for (j = 0; i < tnum_pdq; i++, j++) {
+		p_pdqcb = &(pdqcb_table[i]);
+		p_pdqinib = &(apdqinib_table[j]);
+		p_pdqinib->pdqatr = TA_NOEXS;
+		p_pdqcb->p_pdqinib = ((const PDQINIB *) p_pdqinib);
+		queue_insert_prev(&free_pdqcb, &(p_pdqcb->swait_queue));
+	}
+}
+
+#endif /* TOPPERS_pdqini */
+
+/*
+ *  優先度データキュー管理領域へのデータの格納
+ */
+#ifdef TOPPERS_pdqenq
+
+void
+enqueue_pridata(PDQCB *p_pdqcb, intptr_t data, PRI datapri)
+{
+	PDQMB	*p_pdqmb;
+	PDQMB	**pp_prev_next, *p_next;
+
+	if (p_pdqcb->p_freelist != NULL) {
+		p_pdqmb = p_pdqcb->p_freelist;
+		p_pdqcb->p_freelist = p_pdqmb->p_next;
+	}
+	else {
+		p_pdqmb = p_pdqcb->p_pdqinib->p_pdqmb + p_pdqcb->unused;
+		p_pdqcb->unused++;
+	}
+
+	p_pdqmb->data = data;
+	p_pdqmb->datapri = datapri;
+
+	pp_prev_next = &(p_pdqcb->p_head);
+	while ((p_next = *pp_prev_next) != NULL) {
+		if (p_next->datapri > datapri) {
+			break;
+		}
+		pp_prev_next = &(p_next->p_next);
+	}
+	p_pdqmb->p_next = p_next;
+	*pp_prev_next = p_pdqmb;
+	p_pdqcb->count++;
+}
+
+#endif /* TOPPERS_pdqenq */
+
+/*
+ *  優先度データキュー管理領域からのデータの取出し
+ */
+#ifdef TOPPERS_pdqdeq
+
+void
+dequeue_pridata(PDQCB *p_pdqcb, intptr_t *p_data, PRI *p_datapri)
+{
+	PDQMB	*p_pdqmb;
+
+	p_pdqmb = p_pdqcb->p_head;
+	p_pdqcb->p_head = p_pdqmb->p_next;
+	p_pdqcb->count--;
+
+	*p_data = p_pdqmb->data;
+	*p_datapri = p_pdqmb->datapri;
+
+	p_pdqmb->p_next = p_pdqcb->p_freelist;
+	p_pdqcb->p_freelist = p_pdqmb;
+}
+
+#endif /* TOPPERS_pdqdeq */
+
+/*
+ *  優先度データキューへのデータ送信
+ */
+#ifdef TOPPERS_pdqsnd
+
+bool_t
+send_pridata(PDQCB *p_pdqcb, intptr_t data, PRI datapri, bool_t *p_dspreq)
+{
+	TCB		*p_tcb;
+
+	if (!queue_empty(&(p_pdqcb->rwait_queue))) {
+		p_tcb = (TCB *) queue_delete_next(&(p_pdqcb->rwait_queue));
+		((WINFO_PDQ *)(p_tcb->p_winfo))->data = data;
+		((WINFO_PDQ *)(p_tcb->p_winfo))->datapri = datapri;
+		*p_dspreq = wait_complete(p_tcb);
+		return(true);
+	}
+	else if (p_pdqcb->count < p_pdqcb->p_pdqinib->pdqcnt) {
+		enqueue_pridata(p_pdqcb, data, datapri);
+		*p_dspreq = false;
+		return(true);
+	}
+	else {
+		return(false);
+	}
+}
+
+#endif /* TOPPERS_pdqsnd */
+
+/*
+ *  優先度データキューからのデータ受信
+ */
+#ifdef TOPPERS_pdqrcv
+
+bool_t
+receive_pridata(PDQCB *p_pdqcb, intptr_t *p_data,
+									PRI *p_datapri, bool_t *p_dspreq)
+{
+	TCB		*p_tcb;
+	intptr_t data;
+	PRI		datapri;
+
+	if (p_pdqcb->count > 0U) {
+		dequeue_pridata(p_pdqcb, p_data, p_datapri);
+		if (!queue_empty(&(p_pdqcb->swait_queue))) {
+			p_tcb = (TCB *) queue_delete_next(&(p_pdqcb->swait_queue));
+			data = ((WINFO_PDQ *)(p_tcb->p_winfo))->data;
+			datapri = ((WINFO_PDQ *)(p_tcb->p_winfo))->datapri;
+			enqueue_pridata(p_pdqcb, data, datapri);
+			*p_dspreq = wait_complete(p_tcb);
+		}
+		else {
+			*p_dspreq = false;
+		}
+		return(true);
+	}
+	else if (!queue_empty(&(p_pdqcb->swait_queue))) {
+		p_tcb = (TCB *) queue_delete_next(&(p_pdqcb->swait_queue));
+		*p_data = ((WINFO_PDQ *)(p_tcb->p_winfo))->data;
+		*p_datapri = ((WINFO_PDQ *)(p_tcb->p_winfo))->datapri;
+		*p_dspreq = wait_complete(p_tcb);
+		return(true);
+	}
+	else {
+		return(false);
+	}
+}
+
+#endif /* TOPPERS_pdqrcv */
+
+/*
+ *  優先度データキューの生成
+ */
+#ifdef TOPPERS_acre_pdq
+
+ER_UINT
+acre_pdq(const T_CPDQ *pk_cpdq)
+{
+	PDQCB	*p_pdqcb;
+	PDQINIB	*p_pdqinib;
+	ATR		pdqatr;
+	PDQMB	*p_pdqmb;
+	ER		ercd;
+
+	LOG_ACRE_PDQ_ENTER(pk_cpdq);
+	CHECK_TSKCTX_UNL();
+	CHECK_RSATR(pk_cpdq->pdqatr, TA_TPRI);
+	CHECK_DPRI(pk_cpdq->maxdpri);
+	if (pk_cpdq->pdqmb != NULL) {
+		CHECK_ALIGN_MB(pk_cpdq->pdqmb);
+	}
+	pdqatr = pk_cpdq->pdqatr;
+	p_pdqmb = pk_cpdq->pdqmb;
+
+	t_lock_cpu();
+	if (tnum_pdq == 0 || queue_empty(&free_pdqcb)) {
+		ercd = E_NOID;
+	}
+	else {
+		if (pk_cpdq->pdqcnt != 0 && p_pdqmb == NULL) {
+			p_pdqmb = kernel_malloc(sizeof(PDQMB) * pk_cpdq->pdqcnt);
+			pdqatr |= TA_MBALLOC;
+		}
+		if (pk_cpdq->pdqcnt != 0 && p_pdqmb == NULL) {
+			ercd = E_NOMEM;
+		}
+		else {
+			p_pdqcb = ((PDQCB *) queue_delete_next(&free_pdqcb));
+			p_pdqinib = (PDQINIB *)(p_pdqcb->p_pdqinib);
+			p_pdqinib->pdqatr = pdqatr;
+			p_pdqinib->pdqcnt = pk_cpdq->pdqcnt;
+			p_pdqinib->maxdpri = pk_cpdq->maxdpri;
+			p_pdqinib->p_pdqmb = p_pdqmb;
+
+			queue_initialize(&(p_pdqcb->swait_queue));
+			queue_initialize(&(p_pdqcb->rwait_queue));
+			p_pdqcb->count = 0U;
+			p_pdqcb->p_head = NULL;
+			p_pdqcb->unused = 0U;
+			p_pdqcb->p_freelist = NULL;
+			ercd = PDQID(p_pdqcb);
+		}
+	}
+	t_unlock_cpu();
+
+  error_exit:
+	LOG_ACRE_PDQ_LEAVE(ercd);
+	return(ercd);
+}
+
+#endif /* TOPPERS_acre_pdq */
+
+/*
+ *  優先度データキューの削除
+ */
+#ifdef TOPPERS_del_pdq
+
+ER
+del_pdq(ID pdqid)
+{
+	PDQCB	*p_pdqcb;
+	PDQINIB	*p_pdqinib;
+	bool_t	dspreq;
+	ER		ercd;
+
+	LOG_DEL_PDQ_ENTER(pdqid);
+	CHECK_TSKCTX_UNL();
+	CHECK_PDQID(pdqid);
+	p_pdqcb = get_pdqcb(pdqid);
+
+	t_lock_cpu();
+	if (p_pdqcb->p_pdqinib->pdqatr == TA_NOEXS) {
+		ercd = E_NOEXS;
+	}
+	else if (PDQID(p_pdqcb) > tmax_spdqid) {
+		dspreq = init_wait_queue(&(p_pdqcb->swait_queue));
+		if (init_wait_queue(&(p_pdqcb->rwait_queue))) {
+			dspreq = true;
+		}
+		p_pdqinib = (PDQINIB *)(p_pdqcb->p_pdqinib);
+		if ((p_pdqinib->pdqatr & TA_MBALLOC) != 0U) {
+			kernel_free(p_pdqinib->p_pdqmb);
+		}
+		p_pdqinib->pdqatr = TA_NOEXS;
+		queue_insert_prev(&free_pdqcb, &(p_pdqcb->swait_queue));
+		if (dspreq) {
+			dispatch();
+		}
+		ercd = E_OK;
+	}
+	else {
+		ercd = E_OBJ;
+	}
+	t_unlock_cpu();
+
+  error_exit:
+	LOG_DEL_PDQ_LEAVE(ercd);
+	return(ercd);
+}
+
+#endif /* TOPPERS_del_pdq */
+
+/*
+ *  優先度データキューへの送信
+ */
+#ifdef TOPPERS_snd_pdq
+
+ER
+snd_pdq(ID pdqid, intptr_t data, PRI datapri)
+{
+	PDQCB	*p_pdqcb;
+	WINFO_PDQ winfo_pdq;
+	bool_t	dspreq;
+	ER		ercd;
+
+	LOG_SND_PDQ_ENTER(pdqid, data, datapri);
+	CHECK_DISPATCH();
+	CHECK_PDQID(pdqid);
+	p_pdqcb = get_pdqcb(pdqid);
+	CHECK_PAR(TMIN_DPRI <= datapri);
+
+	t_lock_cpu();
+	if (p_pdqcb->p_pdqinib->pdqatr == TA_NOEXS) {
+		ercd = E_NOEXS;
+	}
+	else if (!(datapri <= p_pdqcb->p_pdqinib->maxdpri)) {
+		ercd = E_PAR;
+	}
+	else if (send_pridata(p_pdqcb, data, datapri, &dspreq)) {
+		if (dspreq) {
+			dispatch();
+		}
+		ercd = E_OK;
+	}
+	else {
+		winfo_pdq.data = data;
+		winfo_pdq.datapri = datapri;
+		p_runtsk->tstat = (TS_WAITING | TS_WAIT_SPDQ);
+		wobj_make_wait((WOBJCB *) p_pdqcb, (WINFO_WOBJ *) &winfo_pdq);
+		dispatch();
+		ercd = winfo_pdq.winfo.wercd;
+	}
+	t_unlock_cpu();
+
+  error_exit:
+	LOG_SND_PDQ_LEAVE(ercd);
+	return(ercd);
+}
+
+#endif /* TOPPERS_snd_pdq */
+
+/*
+ *  優先度データキューへの送信（ポーリング）
+ */
+#ifdef TOPPERS_psnd_pdq
+
+ER
+psnd_pdq(ID pdqid, intptr_t data, PRI datapri)
+{
+	PDQCB	*p_pdqcb;
+	bool_t	dspreq;
+	ER		ercd;
+
+	LOG_PSND_PDQ_ENTER(pdqid, data, datapri);
+	CHECK_TSKCTX_UNL();
+	CHECK_PDQID(pdqid);
+	p_pdqcb = get_pdqcb(pdqid);
+	CHECK_PAR(TMIN_DPRI <= datapri);
+
+	t_lock_cpu();
+	if (p_pdqcb->p_pdqinib->pdqatr == TA_NOEXS) {
+		ercd = E_NOEXS;
+	}
+	else if (!(datapri <= p_pdqcb->p_pdqinib->maxdpri)) {
+		ercd = E_PAR;
+	}
+	else if (send_pridata(p_pdqcb, data, datapri, &dspreq)) {
+		if (dspreq) {
+			dispatch();
+		}
+		ercd = E_OK;
+	}
+	else {
+		ercd = E_TMOUT;
+	}
+	t_unlock_cpu();
+
+  error_exit:
+	LOG_PSND_PDQ_LEAVE(ercd);
+	return(ercd);
+}
+
+#endif /* TOPPERS_psnd_pdq */
+
+/*
+ *  優先度データキューへの送信（ポーリング，非タスクコンテキスト用）
+ */
+#ifdef TOPPERS_ipsnd_pdq
+
+ER
+ipsnd_pdq(ID pdqid, intptr_t data, PRI datapri)
+{
+	PDQCB	*p_pdqcb;
+	bool_t	dspreq;
+	ER		ercd;
+
+	LOG_IPSND_PDQ_ENTER(pdqid, data, datapri);
+	CHECK_INTCTX_UNL();
+	CHECK_PDQID(pdqid);
+	p_pdqcb = get_pdqcb(pdqid);
+	CHECK_PAR(TMIN_DPRI <= datapri);
+
+	i_lock_cpu();
+	if (p_pdqcb->p_pdqinib->pdqatr == TA_NOEXS) {
+		ercd = E_NOEXS;
+	}
+	else if (!(datapri <= p_pdqcb->p_pdqinib->maxdpri)) {
+		ercd = E_PAR;
+	}
+	else if (send_pridata(p_pdqcb, data, datapri, &dspreq)) {
+		if (dspreq) {
+			reqflg = true;
+		}
+		ercd = E_OK;
+	}
+	else {
+		ercd = E_TMOUT;
+	}
+	i_unlock_cpu();
+
+  error_exit:
+	LOG_IPSND_PDQ_LEAVE(ercd);
+	return(ercd);
+}
+
+#endif /* TOPPERS_ipsnd_pdq */
+
+/*
+ *  優先度データキューへの送信（タイムアウトあり）
+ */
+#ifdef TOPPERS_tsnd_pdq
+
+ER
+tsnd_pdq(ID pdqid, intptr_t data, PRI datapri, TMO tmout)
+{
+	PDQCB	*p_pdqcb;
+	WINFO_PDQ winfo_pdq;
+	TMEVTB	tmevtb;
+	bool_t	dspreq;
+	ER		ercd;
+
+	LOG_TSND_PDQ_ENTER(pdqid, data, datapri, tmout);
+	CHECK_DISPATCH();
+	CHECK_PDQID(pdqid);
+	CHECK_TMOUT(tmout);
+	p_pdqcb = get_pdqcb(pdqid);
+	CHECK_PAR(TMIN_DPRI <= datapri);
+
+	t_lock_cpu();
+	if (p_pdqcb->p_pdqinib->pdqatr == TA_NOEXS) {
+		ercd = E_NOEXS;
+	}
+	else if (!(datapri <= p_pdqcb->p_pdqinib->maxdpri)) {
+		ercd = E_PAR;
+	}
+	else if (send_pridata(p_pdqcb, data, datapri, &dspreq)) {
+		if (dspreq) {
+			dispatch();
+		}
+		ercd = E_OK;
+	}
+	else if (tmout == TMO_POL) {
+		ercd = E_TMOUT;
+	}
+	else {
+		winfo_pdq.data = data;
+		winfo_pdq.datapri = datapri;
+		p_runtsk->tstat = (TS_WAITING | TS_WAIT_SPDQ);
+		wobj_make_wait_tmout((WOBJCB *) p_pdqcb, (WINFO_WOBJ *) &winfo_pdq,
+														&tmevtb, tmout);
+		dispatch();
+		ercd = winfo_pdq.winfo.wercd;
+	}
+	t_unlock_cpu();
+
+  error_exit:
+	LOG_TSND_PDQ_LEAVE(ercd);
+	return(ercd);
+}
+
+#endif /* TOPPERS_tsnd_pdq */
+
+/*
+ *  優先度データキューからの受信
+ */
+#ifdef TOPPERS_rcv_pdq
+
+ER
+rcv_pdq(ID pdqid, intptr_t *p_data, PRI *p_datapri)
+{
+	PDQCB	*p_pdqcb;
+	WINFO_PDQ winfo_pdq;
+	bool_t	dspreq;
+	ER		ercd;
+
+	LOG_RCV_PDQ_ENTER(pdqid, p_data, p_datapri);
+	CHECK_DISPATCH();
+	CHECK_PDQID(pdqid);
+	p_pdqcb = get_pdqcb(pdqid);
+
+	t_lock_cpu();
+	if (p_pdqcb->p_pdqinib->pdqatr == TA_NOEXS) {
+		ercd = E_NOEXS;
+	}
+	else if (receive_pridata(p_pdqcb, p_data, p_datapri, &dspreq)) {
+		if (dspreq) {
+			dispatch();
+		}
+		ercd = E_OK;
+	}
+	else {
+		p_runtsk->tstat = (TS_WAITING | TS_WAIT_RPDQ);
+		make_wait(&(winfo_pdq.winfo));
+		queue_insert_prev(&(p_pdqcb->rwait_queue), &(p_runtsk->task_queue));
+		winfo_pdq.p_pdqcb = p_pdqcb;
+		LOG_TSKSTAT(p_runtsk);
+		dispatch();
+		ercd = winfo_pdq.winfo.wercd;
+		if (ercd == E_OK) {
+			*p_data = winfo_pdq.data;
+			*p_datapri = winfo_pdq.datapri;
+		}
+	}
+	t_unlock_cpu();
+
+  error_exit:
+	LOG_RCV_PDQ_LEAVE(ercd, *p_data, *p_datapri);
+	return(ercd);
+}
+
+#endif /* TOPPERS_rcv_pdq */
+
+/*
+ *  優先度データキューからの受信（ポーリング）
+ */
+#ifdef TOPPERS_prcv_pdq
+
+ER
+prcv_pdq(ID pdqid, intptr_t *p_data, PRI *p_datapri)
+{
+	PDQCB	*p_pdqcb;
+	bool_t	dspreq;
+	ER		ercd;
+
+	LOG_PRCV_PDQ_ENTER(pdqid, p_data, p_datapri);
+	CHECK_TSKCTX_UNL();
+	CHECK_PDQID(pdqid);
+	p_pdqcb = get_pdqcb(pdqid);
+
+	t_lock_cpu();
+	if (p_pdqcb->p_pdqinib->pdqatr == TA_NOEXS) {
+		ercd = E_NOEXS;
+	}
+	else if (receive_pridata(p_pdqcb, p_data, p_datapri, &dspreq)) {
+		if (dspreq) {
+			dispatch();
+		}
+		ercd = E_OK;
+	}
+	else {
+		ercd = E_TMOUT;
+	}
+	t_unlock_cpu();
+
+  error_exit:
+	LOG_PRCV_PDQ_LEAVE(ercd, *p_data, *p_datapri);
+	return(ercd);
+}
+
+#endif /* TOPPERS_prcv_pdq */
+
+/*
+ *  優先度データキューからの受信（タイムアウトあり）
+ */
+#ifdef TOPPERS_trcv_pdq
+
+ER
+trcv_pdq(ID pdqid, intptr_t *p_data, PRI *p_datapri, TMO tmout)
+{
+	PDQCB	*p_pdqcb;
+	WINFO_PDQ winfo_pdq;
+	TMEVTB	tmevtb;
+	bool_t	dspreq;
+	ER		ercd;
+
+	LOG_TRCV_PDQ_ENTER(pdqid, p_data, p_datapri, tmout);
+	CHECK_DISPATCH();
+	CHECK_PDQID(pdqid);
+	CHECK_TMOUT(tmout);
+	p_pdqcb = get_pdqcb(pdqid);
+
+	t_lock_cpu();
+	if (p_pdqcb->p_pdqinib->pdqatr == TA_NOEXS) {
+		ercd = E_NOEXS;
+	}
+	else if (receive_pridata(p_pdqcb, p_data, p_datapri, &dspreq)) {
+		if (dspreq) {
+			dispatch();
+		}
+		ercd = E_OK;
+	}
+	else if (tmout == TMO_POL) {
+		ercd = E_TMOUT;
+	}
+	else {
+		p_runtsk->tstat = (TS_WAITING | TS_WAIT_RPDQ);
+		make_wait_tmout(&(winfo_pdq.winfo), &tmevtb, tmout);
+		queue_insert_prev(&(p_pdqcb->rwait_queue), &(p_runtsk->task_queue));
+		winfo_pdq.p_pdqcb = p_pdqcb;
+		LOG_TSKSTAT(p_runtsk);
+		dispatch();
+		ercd = winfo_pdq.winfo.wercd;
+		if (ercd == E_OK) {
+			*p_data = winfo_pdq.data;
+			*p_datapri = winfo_pdq.datapri;
+		}
+	}
+	t_unlock_cpu();
+
+  error_exit:
+	LOG_TRCV_PDQ_LEAVE(ercd, *p_data, *p_datapri);
+	return(ercd);
+}
+
+#endif /* TOPPERS_trcv_pdq */
+
+/*
+ *  優先度データキューの再初期化
+ */
+#ifdef TOPPERS_ini_pdq
+
+ER
+ini_pdq(ID pdqid)
+{
+	PDQCB	*p_pdqcb;
+	bool_t	dspreq;
+	ER		ercd;
+    
+	LOG_INI_PDQ_ENTER(pdqid);
+	CHECK_TSKCTX_UNL();
+	CHECK_PDQID(pdqid);
+	p_pdqcb = get_pdqcb(pdqid);
+
+	t_lock_cpu();
+	if (p_pdqcb->p_pdqinib->pdqatr == TA_NOEXS) {
+		ercd = E_NOEXS;
+	}
+	else {
+		dspreq = init_wait_queue(&(p_pdqcb->swait_queue));
+		if (init_wait_queue(&(p_pdqcb->rwait_queue))) {
+			dspreq = true;
+		}
+		p_pdqcb->count = 0U;
+		p_pdqcb->p_head = NULL;
+		p_pdqcb->unused = 0U;
+		p_pdqcb->p_freelist = NULL;
+		if (dspreq) {
+			dispatch();
+		}
+		ercd = E_OK;
+	}
+	t_unlock_cpu();
+
+  error_exit:
+	LOG_INI_PDQ_LEAVE(ercd);
+	return(ercd);
+}
+
+#endif /* TOPPERS_ini_pdq */
+
+/*
+ *  優先度データキューの状態参照
+ */
+#ifdef TOPPERS_ref_pdq
+
+ER
+ref_pdq(ID pdqid, T_RPDQ *pk_rpdq)
+{
+	PDQCB	*p_pdqcb;
+	ER		ercd;
+    
+	LOG_REF_PDQ_ENTER(pdqid, pk_rpdq);
+	CHECK_TSKCTX_UNL();
+	CHECK_PDQID(pdqid);
+	p_pdqcb = get_pdqcb(pdqid);
+
+	t_lock_cpu();
+	if (p_pdqcb->p_pdqinib->pdqatr == TA_NOEXS) {
+		ercd = E_NOEXS;
+	}
+	else {
+		pk_rpdq->stskid = wait_tskid(&(p_pdqcb->swait_queue));
+		pk_rpdq->rtskid = wait_tskid(&(p_pdqcb->rwait_queue));
+		pk_rpdq->spdqcnt = p_pdqcb->count;
+		ercd = E_OK;
+	}
+	t_unlock_cpu();
+
+  error_exit:
+	LOG_REF_PDQ_LEAVE(ercd, pk_rpdq);
+	return(ercd);
+}
+
+#endif /* TOPPERS_ref_pdq */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/kernel/pridataq.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/kernel/pridataq.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/kernel/pridataq.h	(revision 457)
@@ -0,0 +1,165 @@
+/*
+ *  TOPPERS/ASP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Advanced Standard Profile Kernel
+ * 
+ *  Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
+ *                              Toyohashi Univ. of Technology, JAPAN
+ *  Copyright (C) 2005-2013 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *		優先度データキュー機能
+ */
+
+#ifndef TOPPERS_PRIDATAQ_H
+#define TOPPERS_PRIDATAQ_H
+
+#include "wait.h"
+
+/*
+ *  優先度データ管理ブロック
+ */
+typedef struct pridata_management_block PDQMB;
+
+struct pridata_management_block {
+	PDQMB		*p_next;		/* 次のデータ */
+	intptr_t	data;			/* データ本体 */
+	PRI			datapri;		/* データ優先度 */
+};
+
+/*
+ *  優先度データキュー初期化ブロック
+ *
+ *  この構造体は，同期・通信オブジェクトの初期化ブロックの共通部分
+ *  （WOBJINIB）を拡張（オブジェクト指向言語の継承に相当）したもので，
+ *  最初のフィールドが共通になっている．
+ */
+typedef struct pridataq_initialization_block {
+	ATR			pdqatr;			/* 優先度データキュー属性 */
+	uint_t		pdqcnt;			/* 優先度データキューの容量 */
+	PRI			maxdpri;		/* データ優先度の最大値 */
+	PDQMB		*p_pdqmb;		/* 優先度データキュー管理領域の先頭番地 */
+} PDQINIB;
+
+/*
+ *  優先度データキュー管理ブロック
+ *
+ *  この構造体は，同期・通信オブジェクトの管理ブロックの共通部分（WOBJCB）
+ *  を拡張（オブジェクト指向言語の継承に相当）したもので，最初の2つの
+ *  フィールドが共通になっている．
+ */
+typedef struct pridataq_control_block {
+	QUEUE		swait_queue;	/* 優先度データキュー送信待ちキュー */
+	const PDQINIB *p_pdqinib;	/* 初期化ブロックへのポインタ */
+	QUEUE		rwait_queue;	/* 優先度データキュー受信待ちキュー */
+	uint_t		count;			/* 優先度データキュー中のデータの数 */
+	PDQMB		*p_head;		/* 最初のデータ */
+	uint_t		unused;			/* 未使用データ管理ブロックの先頭 */
+	PDQMB		*p_freelist;	/* 未割当てデータ管理ブロックのリスト */
+} PDQCB;
+
+/*
+ *  優先度データキュー待ち情報ブロックの定義
+ *
+ *  この構造体は，同期・通信オブジェクトの待ち情報ブロックの共通部分
+ *  （WINFO_WOBJ）を拡張（オブジェクト指向言語の継承に相当）したもので，
+ *  最初の2つのフィールドが共通になっている．
+ *  優先度データキューへの送信待ちと優先度データキューからの受信待ちで，
+ *  同じ待ち情報ブロックを使う．
+ */
+typedef struct pridataq_waiting_information {
+	WINFO		winfo;			/* 標準の待ち情報ブロック */
+	PDQCB		*p_pdqcb;		/* 待っている優先度データキューの管理ブロック*/
+	intptr_t	data;			/* 送受信データ */
+	PRI			datapri;		/* データ優先度 */
+} WINFO_PDQ;
+
+/*
+ *  使用していない優先度データキュー管理ブロックのリスト
+ */
+extern QUEUE	free_pdqcb;
+
+/*
+ *  優先度データキューIDの最大値（kernel_cfg.c）
+ */
+extern const ID	tmax_pdqid;
+extern const ID	tmax_spdqid;
+
+/*
+ *  優先度データキュー初期化ブロックのエリア（kernel_cfg.c）
+ */
+extern const PDQINIB	pdqinib_table[];
+extern PDQINIB			apdqinib_table[];
+
+/*
+ *  優先度データキュー管理ブロックのエリア（kernel_cfg.c）
+ */
+extern PDQCB	pdqcb_table[];
+
+/*
+ *  優先度データキュー管理ブロックから優先度データキューIDを取り出すた
+ *  めのマクロ
+ */
+#define	PDQID(p_pdqcb)	((ID)(((p_pdqcb) - pdqcb_table) + TMIN_PDQID))
+
+/*
+ *  優先度データキュー機能の初期化
+ */
+extern void	initialize_pridataq(void);
+
+/*
+ *  優先度データキュー管理領域へのデータの格納
+ */
+extern void	enqueue_pridata(PDQCB *p_pdqcb, intptr_t data, PRI datapri);
+
+/*
+ *  優先度データキュー管理領域からのデータの取出し
+ */
+extern void	dequeue_pridata(PDQCB *p_pdqcb, intptr_t *p_data, PRI *p_datapri);
+
+/*
+ *  優先度データキューへのデータ送信
+ */
+extern bool_t	send_pridata(PDQCB *p_pdqcb, intptr_t data,
+											PRI datapri, bool_t *p_dspreq);
+
+/*
+ *  優先度データキューからのデータ受信
+ */
+extern bool_t	receive_pridata(PDQCB *p_pdqcb, intptr_t *p_data,
+											PRI *p_datapri, bool_t *p_dspreq);
+
+#endif /* TOPPERS_PRIDATAQ_H */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/kernel/semaphore.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/kernel/semaphore.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/kernel/semaphore.c	(revision 457)
@@ -0,0 +1,541 @@
+/*
+ *  TOPPERS/ASP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Advanced Standard Profile Kernel
+ * 
+ *  Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
+ *                              Toyohashi Univ. of Technology, JAPAN
+ *  Copyright (C) 2005-2012 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *		セマフォ機能
+ */
+
+#include "kernel_impl.h"
+#include "check.h"
+#include "task.h"
+#include "wait.h"
+#include "semaphore.h"
+
+/*
+ *  トレースログマクロのデフォルト定義
+ */
+#ifndef LOG_ACRE_SEM_ENTER
+#define LOG_ACRE_SEM_ENTER(pk_csem)
+#endif /* LOG_ACRE_SEM_ENTER */
+
+#ifndef LOG_ACRE_SEM_LEAVE
+#define LOG_ACRE_SEM_LEAVE(ercd)
+#endif /* LOG_ACRE_SEM_LEAVE */
+
+#ifndef LOG_DEL_SEM_ENTER
+#define LOG_DEL_SEM_ENTER(semid)
+#endif /* LOG_DEL_SEM_ENTER */
+
+#ifndef LOG_DEL_SEM_LEAVE
+#define LOG_DEL_SEM_LEAVE(ercd)
+#endif /* LOG_DEL_SEM_LEAVE */
+
+#ifndef LOG_SIG_SEM_ENTER
+#define LOG_SIG_SEM_ENTER(semid)
+#endif /* LOG_SIG_SEM_ENTER */
+
+#ifndef LOG_SIG_SEM_LEAVE
+#define LOG_SIG_SEM_LEAVE(ercd)
+#endif /* LOG_SIG_SEM_LEAVE */
+
+#ifndef LOG_ISIG_SEM_ENTER
+#define LOG_ISIG_SEM_ENTER(semid)
+#endif /* LOG_ISIG_SEM_ENTER */
+
+#ifndef LOG_ISIG_SEM_LEAVE
+#define LOG_ISIG_SEM_LEAVE(ercd)
+#endif /* LOG_ISIG_SEM_LEAVE */
+
+#ifndef LOG_WAI_SEM_ENTER
+#define LOG_WAI_SEM_ENTER(semid)
+#endif /* LOG_WAI_SEM_ENTER */
+
+#ifndef LOG_WAI_SEM_LEAVE
+#define LOG_WAI_SEM_LEAVE(ercd)
+#endif /* LOG_WAI_SEM_LEAVE */
+
+#ifndef LOG_POL_SEM_ENTER
+#define LOG_POL_SEM_ENTER(semid)
+#endif /* LOG_POL_SEM_ENTER */
+
+#ifndef LOG_POL_SEM_LEAVE
+#define LOG_POL_SEM_LEAVE(ercd)
+#endif /* LOG_POL_SEM_LEAVE */
+
+#ifndef LOG_TWAI_SEM_ENTER
+#define LOG_TWAI_SEM_ENTER(semid, tmout)
+#endif /* LOG_TWAI_SEM_ENTER */
+
+#ifndef LOG_TWAI_SEM_LEAVE
+#define LOG_TWAI_SEM_LEAVE(ercd)
+#endif /* LOG_TWAI_SEM_LEAVE */
+
+#ifndef LOG_INI_SEM_ENTER
+#define LOG_INI_SEM_ENTER(semid)
+#endif /* LOG_INI_SEM_ENTER */
+
+#ifndef LOG_INI_SEM_LEAVE
+#define LOG_INI_SEM_LEAVE(ercd)
+#endif /* LOG_INI_SEM_LEAVE */
+
+#ifndef LOG_REF_SEM_ENTER
+#define LOG_REF_SEM_ENTER(semid, pk_rsem)
+#endif /* LOG_REF_SEM_ENTER */
+
+#ifndef LOG_REF_SEM_LEAVE
+#define LOG_REF_SEM_LEAVE(ercd, pk_rsem)
+#endif /* LOG_REF_SEM_LEAVE */
+
+/*
+ *  セマフォの数
+ */
+#define tnum_sem	((uint_t)(tmax_semid - TMIN_SEMID + 1))
+#define tnum_ssem	((uint_t)(tmax_ssemid - TMIN_SEMID + 1))
+
+/*
+ *  セマフォIDからセマフォ管理ブロックを取り出すためのマクロ
+ */
+#define INDEX_SEM(semid)	((uint_t)((semid) - TMIN_SEMID))
+#define get_semcb(semid)	(&(semcb_table[INDEX_SEM(semid)]))
+
+#ifdef TOPPERS_semini
+
+/*
+ *  使用していないセマフォ管理ブロックのリスト
+ */
+QUEUE	free_semcb;
+
+/* 
+ *  セマフォ機能の初期化
+ */
+void
+initialize_semaphore(void)
+{
+	uint_t	i, j;
+	SEMCB	*p_semcb;
+	SEMINIB	*p_seminib;
+
+	for (i = 0; i < tnum_ssem; i++) {
+		p_semcb = &(semcb_table[i]);
+		queue_initialize(&(p_semcb->wait_queue));
+		p_semcb->p_seminib = &(seminib_table[i]);
+		p_semcb->semcnt = p_semcb->p_seminib->isemcnt;
+	}
+	queue_initialize(&free_semcb);
+	for (j = 0; i < tnum_sem; i++, j++) {
+		p_semcb = &(semcb_table[i]);
+		p_seminib = &(aseminib_table[j]);
+		p_seminib->sematr = TA_NOEXS;
+		p_semcb->p_seminib = ((const SEMINIB *) p_seminib);
+		queue_insert_prev(&free_semcb, &(p_semcb->wait_queue));
+	}
+}
+
+#endif /* TOPPERS_semini */
+
+/*
+ *  セマフォの生成
+ */
+#ifdef TOPPERS_acre_sem
+
+ER_UINT
+acre_sem(const T_CSEM *pk_csem)
+{
+	SEMCB	*p_semcb;
+	SEMINIB	*p_seminib;
+	ER		ercd;
+
+	LOG_ACRE_SEM_ENTER(pk_csem);
+	CHECK_TSKCTX_UNL();
+	CHECK_RSATR(pk_csem->sematr, TA_TPRI);
+	CHECK_PAR(0 <= pk_csem->isemcnt && pk_csem->isemcnt <= pk_csem->maxsem);
+	CHECK_PAR(1 <= pk_csem->maxsem && pk_csem->maxsem <= TMAX_MAXSEM);
+
+	t_lock_cpu();
+	if (tnum_sem == 0 || queue_empty(&free_semcb)) {
+		ercd = E_NOID;
+	}
+	else {
+		p_semcb = ((SEMCB *) queue_delete_next(&free_semcb));
+		p_seminib = (SEMINIB *)(p_semcb->p_seminib);
+		p_seminib->sematr = pk_csem->sematr;
+		p_seminib->isemcnt = pk_csem->isemcnt;
+		p_seminib->maxsem = pk_csem->maxsem;
+
+		queue_initialize(&(p_semcb->wait_queue));
+		p_semcb->semcnt = p_semcb->p_seminib->isemcnt;
+		ercd = SEMID(p_semcb);
+	}
+	t_unlock_cpu();
+
+  error_exit:
+	LOG_ACRE_SEM_LEAVE(ercd);
+	return(ercd);
+}
+
+#endif /* TOPPERS_acre_sem */
+
+/*
+ *  セマフォの削除
+ */
+#ifdef TOPPERS_del_sem
+
+ER
+del_sem(ID semid)
+{
+	SEMCB	*p_semcb;
+	SEMINIB	*p_seminib;
+	bool_t	dspreq;
+	ER		ercd;
+
+	LOG_DEL_SEM_ENTER(semid);
+	CHECK_TSKCTX_UNL();
+	CHECK_SEMID(semid);
+	p_semcb = get_semcb(semid);
+
+	t_lock_cpu();
+	if (p_semcb->p_seminib->sematr == TA_NOEXS) {
+		ercd = E_NOEXS;
+	}
+	else if (SEMID(p_semcb) > tmax_ssemid) {
+		dspreq = init_wait_queue(&(p_semcb->wait_queue));
+		p_seminib = (SEMINIB *)(p_semcb->p_seminib);
+		p_seminib->sematr = TA_NOEXS;
+		queue_insert_prev(&free_semcb, &(p_semcb->wait_queue));
+		if (dspreq) {
+			dispatch();
+		}
+		ercd = E_OK;
+	}
+	else {
+		ercd = E_OBJ;
+	}
+	t_unlock_cpu();
+
+  error_exit:
+	LOG_DEL_SEM_LEAVE(ercd);
+	return(ercd);
+}
+
+#endif /* TOPPERS_del_sem */
+
+/*
+ *  セマフォ資源の返却
+ */
+#ifdef TOPPERS_sig_sem
+
+ER
+sig_sem(ID semid)
+{
+	SEMCB	*p_semcb;
+	TCB		*p_tcb;
+	ER		ercd;
+    
+	LOG_SIG_SEM_ENTER(semid);
+	CHECK_TSKCTX_UNL();
+	CHECK_SEMID(semid);
+	p_semcb = get_semcb(semid);
+
+	t_lock_cpu();
+	if (p_semcb->p_seminib->sematr == TA_NOEXS) {
+		ercd = E_NOEXS;
+	}
+	else if (!queue_empty(&(p_semcb->wait_queue))) {
+		p_tcb = (TCB *) queue_delete_next(&(p_semcb->wait_queue));
+		if (wait_complete(p_tcb)) {
+			dispatch();
+		}
+		ercd = E_OK;
+	}
+	else if (p_semcb->semcnt < p_semcb->p_seminib->maxsem) {
+		p_semcb->semcnt += 1;
+		ercd = E_OK;
+	}
+	else {
+		ercd = E_QOVR;
+	}
+	t_unlock_cpu();
+
+  error_exit:
+	LOG_SIG_SEM_LEAVE(ercd);
+	return(ercd);
+}
+
+#endif /* TOPPERS_sig_sem */
+
+/*
+ *  セマフォ資源の返却（非タスクコンテキスト用）
+ */
+#ifdef TOPPERS_isig_sem
+
+ER
+isig_sem(ID semid)
+{
+	SEMCB	*p_semcb;
+	TCB		*p_tcb;
+	ER		ercd;
+    
+	LOG_ISIG_SEM_ENTER(semid);
+	CHECK_INTCTX_UNL();
+	CHECK_SEMID(semid);
+	p_semcb = get_semcb(semid);
+
+	i_lock_cpu();
+	if (p_semcb->p_seminib->sematr == TA_NOEXS) {
+		ercd = E_NOEXS;
+	}
+	else if (!queue_empty(&(p_semcb->wait_queue))) {
+		p_tcb = (TCB *) queue_delete_next(&(p_semcb->wait_queue));
+		if (wait_complete(p_tcb)) {
+			reqflg = true;
+		}
+		ercd = E_OK;
+	}
+	else if (p_semcb->semcnt < p_semcb->p_seminib->maxsem) {
+		p_semcb->semcnt += 1;
+		ercd = E_OK;
+	}
+	else {
+		ercd = E_QOVR;
+	}
+	i_unlock_cpu();
+
+  error_exit:
+	LOG_ISIG_SEM_LEAVE(ercd);
+	return(ercd);
+}
+
+#endif /* TOPPERS_isig_sem */
+
+/*
+ *  セマフォ資源の獲得
+ */
+#ifdef TOPPERS_wai_sem
+
+ER
+wai_sem(ID semid)
+{
+	SEMCB	*p_semcb;
+	WINFO_SEM winfo_sem;
+	ER		ercd;
+
+	LOG_WAI_SEM_ENTER(semid);
+	CHECK_DISPATCH();
+	CHECK_SEMID(semid);
+	p_semcb = get_semcb(semid);
+
+	t_lock_cpu();
+	if (p_semcb->p_seminib->sematr == TA_NOEXS) {
+		ercd = E_NOEXS;
+	}
+	else if (p_semcb->semcnt >= 1) {
+		p_semcb->semcnt -= 1;
+		ercd = E_OK;
+	}
+	else {
+		p_runtsk->tstat = (TS_WAITING | TS_WAIT_SEM);
+		wobj_make_wait((WOBJCB *) p_semcb, (WINFO_WOBJ *) &winfo_sem);
+		dispatch();
+		ercd = winfo_sem.winfo.wercd;
+	}
+	t_unlock_cpu();
+
+  error_exit:
+	LOG_WAI_SEM_LEAVE(ercd);
+	return(ercd);
+}
+
+#endif /* TOPPERS_wai_sem */
+
+/*
+ *  セマフォ資源の獲得（ポーリング）
+ */
+#ifdef TOPPERS_pol_sem
+
+ER
+pol_sem(ID semid)
+{
+	SEMCB	*p_semcb;
+	ER		ercd;
+
+	LOG_POL_SEM_ENTER(semid);
+	CHECK_TSKCTX_UNL();
+	CHECK_SEMID(semid);
+	p_semcb = get_semcb(semid);
+
+	t_lock_cpu();
+	if (p_semcb->p_seminib->sematr == TA_NOEXS) {
+		ercd = E_NOEXS;
+	}
+	else if (p_semcb->semcnt >= 1) {
+		p_semcb->semcnt -= 1;
+		ercd = E_OK;
+	}
+	else {
+		ercd = E_TMOUT;
+	}
+	t_unlock_cpu();
+
+  error_exit:
+	LOG_POL_SEM_LEAVE(ercd);
+	return(ercd);
+}
+
+#endif /* TOPPERS_pol_sem */
+
+/*
+ *  セマフォ資源の獲得（タイムアウトあり）
+ */
+#ifdef TOPPERS_twai_sem
+
+ER
+twai_sem(ID semid, TMO tmout)
+{
+	SEMCB	*p_semcb;
+	WINFO_SEM winfo_sem;
+	TMEVTB	tmevtb;
+	ER		ercd;
+
+	LOG_TWAI_SEM_ENTER(semid, tmout);
+	CHECK_DISPATCH();
+	CHECK_SEMID(semid);
+	CHECK_TMOUT(tmout);
+	p_semcb = get_semcb(semid);
+
+	t_lock_cpu();
+	if (p_semcb->p_seminib->sematr == TA_NOEXS) {
+		ercd = E_NOEXS;
+	}
+	else if (p_semcb->semcnt >= 1) {
+		p_semcb->semcnt -= 1;
+		ercd = E_OK;
+	}
+	else if (tmout == TMO_POL) {
+		ercd = E_TMOUT;
+	}
+	else {
+		p_runtsk->tstat = (TS_WAITING | TS_WAIT_SEM);
+		wobj_make_wait_tmout((WOBJCB *) p_semcb, (WINFO_WOBJ *) &winfo_sem,
+														&tmevtb, tmout);
+		dispatch();
+		ercd = winfo_sem.winfo.wercd;
+	}
+	t_unlock_cpu();
+
+  error_exit:
+	LOG_TWAI_SEM_LEAVE(ercd);
+	return(ercd);
+}
+
+#endif /* TOPPERS_twai_sem */
+
+/*
+ *  セマフォの再初期化
+ */
+#ifdef TOPPERS_ini_sem
+
+ER
+ini_sem(ID semid)
+{
+	SEMCB	*p_semcb;
+	bool_t	dspreq;
+	ER		ercd;
+    
+	LOG_INI_SEM_ENTER(semid);
+	CHECK_TSKCTX_UNL();
+	CHECK_SEMID(semid);
+	p_semcb = get_semcb(semid);
+
+	t_lock_cpu();
+	if (p_semcb->p_seminib->sematr == TA_NOEXS) {
+		ercd = E_NOEXS;
+	}
+	else {
+		dspreq = init_wait_queue(&(p_semcb->wait_queue));
+		p_semcb->semcnt = p_semcb->p_seminib->isemcnt;
+		if (dspreq) {
+			dispatch();
+		}
+		ercd = E_OK;
+	}
+	t_unlock_cpu();
+
+  error_exit:
+	LOG_INI_SEM_LEAVE(ercd);
+	return(ercd);
+}
+
+#endif /* TOPPERS_ini_sem */
+
+/*
+ *  セマフォの状態参照
+ */
+#ifdef TOPPERS_ref_sem
+
+ER
+ref_sem(ID semid, T_RSEM *pk_rsem)
+{
+	SEMCB	*p_semcb;
+	ER		ercd;
+    
+	LOG_REF_SEM_ENTER(semid, pk_rsem);
+	CHECK_TSKCTX_UNL();
+	CHECK_SEMID(semid);
+	p_semcb = get_semcb(semid);
+
+	t_lock_cpu();
+	if (p_semcb->p_seminib->sematr == TA_NOEXS) {
+		ercd = E_NOEXS;
+	}
+	else {
+		pk_rsem->wtskid = wait_tskid(&(p_semcb->wait_queue));
+		pk_rsem->semcnt = p_semcb->semcnt;
+		ercd = E_OK;
+	}
+	t_unlock_cpu();
+
+  error_exit:
+	LOG_REF_SEM_LEAVE(ercd, pk_rsem);
+	return(ercd);
+}
+
+#endif /* TOPPERS_ref_sem */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/kernel/semaphore.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/kernel/semaphore.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/kernel/semaphore.h	(revision 457)
@@ -0,0 +1,122 @@
+/*
+ *  TOPPERS/ASP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Advanced Standard Profile Kernel
+ * 
+ *  Copyright (C) 2000 by Embedded and Real-Time Systems Laboratory
+ *                              Toyohashi Univ. of Technology, JAPAN
+ *  Copyright (C) 2005-2012 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *		セマフォ機能
+ */
+
+#ifndef TOPPERS_SEMAPHORE_H
+#define TOPPERS_SEMAPHORE_H
+
+#include "wait.h"
+
+/*
+ *  セマフォ初期化ブロック
+ *
+ *  この構造体は，同期・通信オブジェクトの初期化ブロックの共通部分
+ *  （WOBJINIB）を拡張（オブジェクト指向言語の継承に相当）したもので，
+ *  最初のフィールドが共通になっている．
+ */
+typedef struct semaphore_initialization_block {
+	ATR			sematr;			/* セマフォ属性 */
+	uint_t		isemcnt;		/* セマフォの資源数の初期値 */
+	uint_t		maxsem;			/* セマフォの最大資源数 */
+} SEMINIB;
+
+/*
+ *  セマフォ管理ブロック
+ *
+ *  この構造体は，同期・通信オブジェクトの管理ブロックの共通部分（WOBJCB）
+ *  を拡張（オブジェクト指向言語の継承に相当）したもので，最初の2つの
+ *  フィールドが共通になっている．
+ */
+typedef struct semaphore_control_block {
+	QUEUE		wait_queue;		/* セマフォ待ちキュー */
+	const SEMINIB *p_seminib;	/* 初期化ブロックへのポインタ */
+	uint_t		semcnt;			/* セマフォ現在カウント値 */
+} SEMCB;
+
+/*
+ *  セマフォ待ち情報ブロックの定義
+ *
+ *  この構造体は，同期・通信オブジェクトの待ち情報ブロックの共通部分
+ *  （WINFO_WOBJ）を拡張（オブジェクト指向言語の継承に相当）したもので，
+ *  すべてのフィールドが共通になっている．
+ */
+typedef struct semaphore_waiting_information {
+	WINFO	winfo;			/* 標準の待ち情報ブロック */
+	SEMCB	*p_semcb;		/* 待っているセマフォの管理ブロック */
+} WINFO_SEM;
+
+/*
+ *  使用していないセマフォ管理ブロックのリスト
+ */
+extern QUEUE	free_semcb;
+
+/*
+ *  セマフォIDの最大値（kernel_cfg.c）
+ */
+extern const ID	tmax_semid;
+extern const ID	tmax_ssemid;
+
+/*
+ *  セマフォ初期化ブロックのエリア（kernel_cfg.c）
+ */
+extern const SEMINIB	seminib_table[];
+extern SEMINIB			aseminib_table[];
+
+/*
+ *  セマフォ管理ブロックのエリア（kernel_cfg.c）
+ */
+extern SEMCB	semcb_table[];
+
+/*
+ *  セマフォ管理ブロックからセマフォIDを取り出すためのマクロ
+ */
+#define	SEMID(p_semcb)	((ID)(((p_semcb) - semcb_table) + TMIN_SEMID))
+
+/*
+ *  セマフォ機能の初期化
+ */
+extern void	initialize_semaphore(void);
+
+#endif /* TOPPERS_SEMAPHORE_H */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/kernel/startup.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/kernel/startup.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/kernel/startup.c	(revision 457)
@@ -0,0 +1,210 @@
+/*
+ *  TOPPERS/ASP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Advanced Standard Profile Kernel
+ * 
+ *  Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
+ *                              Toyohashi Univ. of Technology, JAPAN
+ *  Copyright (C) 2005-2010 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *		カーネルの初期化と終了処理
+ */
+
+#include "kernel_impl.h"
+#include "time_event.h"
+#include <sil.h>
+
+/*
+ *  トレースログマクロのデフォルト定義
+ */
+#ifndef LOG_KER_ENTER
+#define LOG_KER_ENTER()
+#endif /* LOG_KER_ENTER */
+
+#ifndef LOG_KER_LEAVE
+#define LOG_KER_LEAVE()
+#endif /* LOG_KER_LEAVE */
+
+#ifndef LOG_EXT_KER_ENTER
+#define LOG_EXT_KER_ENTER()
+#endif /* LOG_EXT_KER_ENTER */
+
+#ifndef LOG_EXT_KER_LEAVE
+#define LOG_EXT_KER_LEAVE(ercd)
+#endif /* LOG_EXT_KER_LEAVE */
+
+#ifdef TOPPERS_sta_ker
+
+/*
+ *  カーネル動作状態フラグ
+ *
+ *  スタートアップルーチンで，false（＝0）に初期化されることを期待して
+ *  いる．
+ */
+bool_t	kerflg = false;
+
+/*
+ *  カーネルの起動
+ */
+void
+sta_ker(void)
+{
+	/*
+	 *  ターゲット依存の初期化
+	 */
+	target_initialize();
+
+	/*
+	 *  各モジュールの初期化
+	 *
+	 *  タイムイベント管理モジュールは他のモジュールより先に初期化
+	 *  する必要がある．
+	 */
+	initialize_kmm();
+	initialize_tmevt();
+	initialize_object();
+
+	/*
+	 *  初期化ルーチンの実行
+	 */ 
+	call_inirtn();
+
+	/*
+	 *  カーネル動作の開始
+	 */
+	kerflg = true;
+	LOG_KER_ENTER();
+	start_dispatch();
+	assert(0);
+}
+
+#endif /* TOPPERS_sta_ker */
+
+/*
+ *  カーネルの終了
+ */
+#ifdef TOPPERS_ext_ker
+
+ER
+ext_ker(void)
+{
+	SIL_PRE_LOC;
+
+	LOG_EXT_KER_ENTER();
+
+	/*
+	 *  割込みロック状態に移行
+	 */
+	SIL_LOC_INT();
+
+	/*
+	 *  カーネル動作の終了
+	 */
+	LOG_KER_LEAVE();
+	kerflg = false;
+
+	/*
+	 *  カーネルの終了処理の呼出し
+	 *
+	 *  非タスクコンテキストに切り換えて，exit_kernelを呼び出す．
+	 */
+	call_exit_kernel();
+
+	/*
+	 *  コンパイラの警告対策（ここへ来ることはないはず）
+	 */
+	SIL_UNL_INT();
+	LOG_EXT_KER_LEAVE(E_SYS);
+	return(E_SYS);
+}
+
+/*
+ *  カーネルの終了処理
+ */
+void
+exit_kernel(void)
+{
+	/*
+	 *  終了処理ルーチンの実行
+	 */
+	call_terrtn();
+
+	/*
+	 *  ターゲット依存の終了処理
+	 */
+	target_exit();
+	assert(0);
+}
+
+#endif /* TOPPERS_ext_ker */
+
+/*
+ *  カーネルの割り付けるメモリ領域の管理
+ *
+ *  メモリ領域を先頭から順に割り当て，解放されたメモリ領域を再利用しな
+ *  いメモリ管理モジュール．
+ */
+#ifdef TOPPERS_kermem
+#ifndef OMIT_KMM_ALLOCONLY
+
+static void	*kmm_brk;
+
+void
+initialize_kmm(void)
+{
+	kmm_brk = ((char *) kmm) + kmmsz;
+}
+
+void *
+kernel_malloc(SIZE size)
+{
+	if (((char *) kmm_brk) - ((char *) kmm) >= size) {
+		kmm_brk = ((char *) kmm_brk) - size;
+		return(kmm_brk);
+	}
+	else {
+		return(NULL);
+	}
+}
+
+void
+kernel_free(void *ptr)
+{
+}
+
+#endif /* OMIT_KMM_ALLOCONLY */
+#endif /* TOPPERS_kermem */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/kernel/sys_manage.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/kernel/sys_manage.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/kernel/sys_manage.c	(revision 457)
@@ -0,0 +1,535 @@
+/*
+ *  TOPPERS/ASP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Advanced Standard Profile Kernel
+ * 
+ *  Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
+ *                              Toyohashi Univ. of Technology, JAPAN
+ *  Copyright (C) 2005-2010 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *		システム状態管理機能
+ */
+
+#include "kernel_impl.h"
+#include "check.h"
+#include "task.h"
+
+/*
+ *  トレースログマクロのデフォルト定義
+ */
+#ifndef LOG_ROT_RDQ_ENTER
+#define LOG_ROT_RDQ_ENTER(tskpri)
+#endif /* LOG_ROT_RDQ_ENTER */
+
+#ifndef LOG_ROT_RDQ_LEAVE
+#define LOG_ROT_RDQ_LEAVE(ercd)
+#endif /* LOG_ROT_RDQ_LEAVE */
+
+#ifndef LOG_IROT_RDQ_ENTER
+#define LOG_IROT_RDQ_ENTER(tskpri)
+#endif /* LOG_IROT_RDQ_ENTER */
+
+#ifndef LOG_IROT_RDQ_LEAVE
+#define LOG_IROT_RDQ_LEAVE(ercd)
+#endif /* LOG_IROT_RDQ_LEAVE */
+
+#ifndef LOG_GET_TID_ENTER
+#define LOG_GET_TID_ENTER(p_tskid)
+#endif /* LOG_GET_TID_ENTER */
+
+#ifndef LOG_GET_TID_LEAVE
+#define LOG_GET_TID_LEAVE(ercd, tskid)
+#endif /* LOG_GET_TID_LEAVE */
+
+#ifndef LOG_IGET_TID_ENTER
+#define LOG_IGET_TID_ENTER(p_tskid)
+#endif /* LOG_IGET_TID_ENTER */
+
+#ifndef LOG_IGET_TID_LEAVE
+#define LOG_IGET_TID_LEAVE(ercd, tskid)
+#endif /* LOG_IGET_TID_LEAVE */
+
+#ifndef LOG_LOC_CPU_ENTER
+#define LOG_LOC_CPU_ENTER()
+#endif /* LOG_LOC_CPU_ENTER */
+
+#ifndef LOG_LOC_CPU_LEAVE
+#define LOG_LOC_CPU_LEAVE(ercd)
+#endif /* LOG_LOC_CPU_LEAVE */
+
+#ifndef LOG_ILOC_CPU_ENTER
+#define LOG_ILOC_CPU_ENTER()
+#endif /* LOG_ILOC_CPU_ENTER */
+
+#ifndef LOG_ILOC_CPU_LEAVE
+#define LOG_ILOC_CPU_LEAVE(ercd)
+#endif /* LOG_ILOC_CPU_LEAVE */
+
+#ifndef LOG_UNL_CPU_ENTER
+#define LOG_UNL_CPU_ENTER()
+#endif /* LOG_UNL_CPU_ENTER */
+
+#ifndef LOG_UNL_CPU_LEAVE
+#define LOG_UNL_CPU_LEAVE(ercd)
+#endif /* LOG_UNL_CPU_LEAVE */
+
+#ifndef LOG_IUNL_CPU_ENTER
+#define LOG_IUNL_CPU_ENTER()
+#endif /* LOG_IUNL_CPU_ENTER */
+
+#ifndef LOG_IUNL_CPU_LEAVE
+#define LOG_IUNL_CPU_LEAVE(ercd)
+#endif /* LOG_IUNL_CPU_LEAVE */
+
+#ifndef LOG_DIS_DSP_ENTER
+#define LOG_DIS_DSP_ENTER()
+#endif /* LOG_DIS_DSP_ENTER */
+
+#ifndef LOG_DIS_DSP_LEAVE
+#define LOG_DIS_DSP_LEAVE(ercd)
+#endif /* LOG_DIS_DSP_LEAVE */
+
+#ifndef LOG_ENA_DSP_ENTER
+#define LOG_ENA_DSP_ENTER()
+#endif /* LOG_ENA_DSP_ENTER */
+
+#ifndef LOG_ENA_DSP_LEAVE
+#define LOG_ENA_DSP_LEAVE(ercd)
+#endif /* LOG_ENA_DSP_LEAVE */
+
+#ifndef LOG_SNS_CTX_ENTER
+#define LOG_SNS_CTX_ENTER()
+#endif /* LOG_SNS_CTX_ENTER */
+
+#ifndef LOG_SNS_CTX_LEAVE
+#define LOG_SNS_CTX_LEAVE(state)
+#endif /* LOG_SNS_CTX_LEAVE */
+
+#ifndef LOG_SNS_LOC_ENTER
+#define LOG_SNS_LOC_ENTER()
+#endif /* LOG_SNS_LOC_ENTER */
+
+#ifndef LOG_SNS_LOC_LEAVE
+#define LOG_SNS_LOC_LEAVE(state)
+#endif /* LOG_SNS_LOC_LEAVE */
+
+#ifndef LOG_SNS_DSP_ENTER
+#define LOG_SNS_DSP_ENTER()
+#endif /* LOG_SNS_DSP_ENTER */
+
+#ifndef LOG_SNS_DSP_LEAVE
+#define LOG_SNS_DSP_LEAVE(state)
+#endif /* LOG_SNS_DSP_LEAVE */
+
+#ifndef LOG_SNS_DPN_ENTER
+#define LOG_SNS_DPN_ENTER()
+#endif /* LOG_SNS_DPN_ENTER */
+
+#ifndef LOG_SNS_DPN_LEAVE
+#define LOG_SNS_DPN_LEAVE(state)
+#endif /* LOG_SNS_DPN_LEAVE */
+
+#ifndef LOG_SNS_KER_ENTER
+#define LOG_SNS_KER_ENTER()
+#endif /* LOG_SNS_KER_ENTER */
+
+#ifndef LOG_SNS_KER_LEAVE
+#define LOG_SNS_KER_LEAVE(state)
+#endif /* LOG_SNS_KER_LEAVE */
+
+/*
+ *  タスクの優先順位の回転
+ */
+#ifdef TOPPERS_rot_rdq
+
+ER
+rot_rdq(PRI tskpri)
+{
+	uint_t	pri;
+	ER		ercd;
+
+	LOG_ROT_RDQ_ENTER(tskpri);
+	CHECK_TSKCTX_UNL();
+	CHECK_TPRI_SELF(tskpri);
+
+	t_lock_cpu();
+	pri = (tskpri == TPRI_SELF) ? p_runtsk->bpriority : INT_PRIORITY(tskpri);
+	if (rotate_ready_queue(pri)) {
+		dispatch();
+	}
+	ercd = E_OK;
+	t_unlock_cpu();
+
+  error_exit:
+	LOG_ROT_RDQ_LEAVE(ercd);
+	return(ercd);
+}
+
+#endif /* TOPPERS_rot_rdq */
+
+/*
+ *  タスクの優先順位の回転（非タスクコンテキスト用）
+ */
+#ifdef TOPPERS_irot_rdq
+
+ER
+irot_rdq(PRI tskpri)
+{
+	ER		ercd;
+
+	LOG_IROT_RDQ_ENTER(tskpri);
+	CHECK_INTCTX_UNL();
+	CHECK_TPRI(tskpri);
+
+	i_lock_cpu();
+	if (rotate_ready_queue(INT_PRIORITY(tskpri))) {
+		reqflg = true;
+	}
+	ercd = E_OK;
+	i_unlock_cpu();
+
+  error_exit:
+	LOG_IROT_RDQ_LEAVE(ercd);
+	return(ercd);
+}
+
+#endif /* TOPPERS_irot_rdq */
+
+/*
+ *  実行状態のタスクIDの参照
+ */
+#ifdef TOPPERS_get_tid
+
+ER
+get_tid(ID *p_tskid)
+{
+	ER		ercd;
+
+	LOG_GET_TID_ENTER(p_tskid);
+	CHECK_TSKCTX_UNL();
+
+	t_lock_cpu();
+	*p_tskid = TSKID(p_runtsk);
+	ercd = E_OK;
+	t_unlock_cpu();
+
+  error_exit:
+	LOG_GET_TID_LEAVE(ercd, *p_tskid);
+	return(ercd);
+}
+
+#endif /* TOPPERS_get_tid */
+
+/*
+ *  実行状態のタスクIDの参照（非タスクコンテキスト用）
+ */
+#ifdef TOPPERS_iget_tid
+
+ER
+iget_tid(ID *p_tskid)
+{
+	ER		ercd;
+
+	LOG_IGET_TID_ENTER(p_tskid);
+	CHECK_INTCTX_UNL();
+
+	i_lock_cpu();
+	*p_tskid = (p_runtsk == NULL) ? TSK_NONE : TSKID(p_runtsk);
+	ercd = E_OK;
+	i_unlock_cpu();
+
+  error_exit:
+	LOG_IGET_TID_LEAVE(ercd, *p_tskid);
+	return(ercd);
+}
+
+#endif /* TOPPERS_iget_tid */
+
+/*
+ *  CPUロック状態への移行
+ */
+#ifdef TOPPERS_loc_cpu
+
+ER
+loc_cpu(void)
+{
+	ER		ercd;
+
+	LOG_LOC_CPU_ENTER();
+	CHECK_TSKCTX();
+
+	if (!t_sense_lock()) {
+		t_lock_cpu();
+	}
+	ercd = E_OK;
+
+  error_exit:
+	LOG_LOC_CPU_LEAVE(ercd);
+	return(ercd);
+}
+
+#endif /* TOPPERS_loc_cpu */
+
+/*
+ *  CPUロック状態への移行（非タスクコンテキスト用）
+ */
+#ifdef TOPPERS_iloc_cpu
+
+ER
+iloc_cpu(void)
+{
+	ER		ercd;
+
+	LOG_ILOC_CPU_ENTER();
+	CHECK_INTCTX();
+
+	if (!i_sense_lock()) {
+		i_lock_cpu();
+	}
+	ercd = E_OK;
+
+  error_exit:
+	LOG_ILOC_CPU_LEAVE(ercd);
+	return(ercd);
+}
+
+#endif /* TOPPERS_iloc_cpu */
+
+/*
+ *  CPUロック状態の解除
+ *
+ *  CPUロック中は，ディスパッチが必要となるサービスコールを呼び出すこ
+ *  とはできないため，CPUロック状態の解除時にディスパッチャを起動する
+ *  必要はない．
+ */
+#ifdef TOPPERS_unl_cpu
+
+ER
+unl_cpu(void)
+{
+	ER		ercd;
+
+	LOG_UNL_CPU_ENTER();
+	CHECK_TSKCTX();
+
+	if (t_sense_lock()) {
+		t_unlock_cpu();
+	}
+	ercd = E_OK;
+
+  error_exit:
+	LOG_UNL_CPU_LEAVE(ercd);
+	return(ercd);
+}
+
+#endif /* TOPPERS_unl_cpu */
+
+/*
+ *  CPUロック状態の解除（非タスクコンテキスト用）
+ *
+ *  CPUロック中は，ディスパッチが必要となるサービスコールを呼び出すこ
+ *  とはできないため，CPUロック状態の解除時にディスパッチャの起動を要
+ *  求する必要はない．
+ */
+#ifdef TOPPERS_iunl_cpu
+
+ER
+iunl_cpu(void)
+{
+	ER		ercd;
+
+	LOG_IUNL_CPU_ENTER();
+	CHECK_INTCTX();
+
+	if (i_sense_lock()) {
+		i_unlock_cpu();
+	}
+	ercd = E_OK;
+
+  error_exit:
+	LOG_IUNL_CPU_LEAVE(ercd);
+	return(ercd);
+}
+
+#endif /* TOPPERS_iunl_cpu */
+
+/*
+ *  ディスパッチの禁止
+ */
+#ifdef TOPPERS_dis_dsp
+
+ER
+dis_dsp(void)
+{
+	ER		ercd;
+
+	LOG_DIS_DSP_ENTER();
+	CHECK_TSKCTX_UNL();
+
+	t_lock_cpu();
+	disdsp = true;
+	dspflg = false;
+	ercd = E_OK;
+	t_unlock_cpu();
+
+  error_exit:
+	LOG_DIS_DSP_LEAVE(ercd);
+	return(ercd);
+}
+
+#endif /* TOPPERS_dis_dsp */
+
+/*
+ *  ディスパッチの許可
+ */
+#ifdef TOPPERS_ena_dsp
+
+ER
+ena_dsp(void)
+{
+	ER		ercd;
+
+	LOG_ENA_DSP_ENTER();
+	CHECK_TSKCTX_UNL();
+
+	t_lock_cpu();
+	disdsp = false;
+	if (ipmflg) {
+		dspflg = true;
+		if (p_runtsk != p_schedtsk) {
+			dispatch();
+		}
+	}
+	ercd = E_OK;
+	t_unlock_cpu();
+
+  error_exit:
+	LOG_ENA_DSP_LEAVE(ercd);
+	return(ercd);
+}
+
+#endif /* TOPPERS_ena_dsp */
+
+/*
+ *  コンテキストの参照
+ */
+#ifdef TOPPERS_sns_ctx
+
+bool_t
+sns_ctx(void)
+{
+	bool_t	state;
+
+	LOG_SNS_CTX_ENTER();
+	state = sense_context() ? true : false;
+	LOG_SNS_CTX_LEAVE(state);
+	return(state);
+}
+
+#endif /* TOPPERS_sns_ctx */
+
+/*
+ *  CPUロック状態の参照
+ */
+#ifdef TOPPERS_sns_loc
+
+bool_t
+sns_loc(void)
+{
+	bool_t	state;
+
+	LOG_SNS_LOC_ENTER();
+	state = x_sense_lock() ? true : false;
+	LOG_SNS_LOC_LEAVE(state);
+	return(state);
+}
+
+#endif /* TOPPERS_sns_loc */
+
+/*
+ *  ディスパッチ禁止状態の参照
+ */
+#ifdef TOPPERS_sns_dsp
+
+bool_t
+sns_dsp(void)
+{
+	bool_t	state;
+
+	LOG_SNS_DSP_ENTER();
+	state = disdsp;
+	LOG_SNS_DSP_LEAVE(state);
+	return(state);
+}
+
+#endif /* TOPPERS_sns_dsp */
+
+/*
+ *  ディスパッチ保留状態の参照
+ */
+#ifdef TOPPERS_sns_dpn
+
+bool_t
+sns_dpn(void)
+{
+	bool_t	state;
+
+	LOG_SNS_DPN_ENTER();
+	state = (sense_context() || t_sense_lock() || !dspflg) ? true : false;
+	LOG_SNS_DPN_LEAVE(state);
+	return(state);
+}
+
+#endif /* TOPPERS_sns_dpn */
+
+/*
+ *  カーネル非動作状態の参照
+ */
+#ifdef TOPPERS_sns_ker
+
+bool_t
+sns_ker(void)
+{
+	bool_t	state;
+
+	LOG_SNS_KER_ENTER();
+	state = kerflg ? false : true;
+	LOG_SNS_KER_LEAVE(state);
+	return(state);
+}
+
+#endif /* TOPPERS_sns_ker */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/kernel/task.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/kernel/task.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/kernel/task.c	(revision 457)
@@ -0,0 +1,505 @@
+/*
+ *  TOPPERS/ASP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Advanced Standard Profile Kernel
+ * 
+ *  Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
+ *                              Toyohashi Univ. of Technology, JAPAN
+ *  Copyright (C) 2005-2011 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  $Id$
+ */
+
+/*
+ *		タスク管理モジュール
+ */
+
+#include "kernel_impl.h"
+#include "wait.h"
+#include "task.h"
+
+/*
+ *  トレースログマクロのデフォルト定義
+ */
+#ifndef LOG_TEX_ENTER
+#define LOG_TEX_ENTER(p_tcb, texptn)
+#endif /* LOG_TEX_ENTER */
+
+#ifndef LOG_TEX_LEAVE
+#define LOG_TEX_LEAVE(p_tcb)
+#endif /* LOG_TEX_LEAVE */
+
+#ifdef TOPPERS_tskini
+
+/*
+ *  実行状態のタスク
+ */
+TCB		*p_runtsk;
+
+/*
+ *  最高優先順位のタスク
+ */
+TCB		*p_schedtsk;
+
+/*
+ *  タスクディスパッチ／タスク例外処理ルーチン起動要求フラグ
+ */
+bool_t	reqflg;
+
+/*
+ *  割込み優先度マスク全解除状態
+ */
+bool_t	ipmflg;
+
+/*
+ *  ディスパッチ禁止状態
+ */
+bool_t	disdsp;
+
+/*
+ *  タスクディスパッチ可能状態
+ */
+bool_t	dspflg;
+
+/*
+ *  レディキュー
+ */
+QUEUE	ready_queue[TNUM_TPRI];
+
+/*
+ *  レディキューサーチのためのビットマップ
+ */
+uint16_t	ready_primap;
+
+/*
+ *  使用していないTCBのリスト
+ */
+QUEUE	free_tcb;
+
+/*
+ *  タスク管理モジュールの初期化
+ */
+void
+initialize_task(void)
+{
+	uint_t	i, j;
+	TCB		*p_tcb;
+	TINIB	*p_tinib;
+
+	p_runtsk = NULL;
+	p_schedtsk = NULL;
+	reqflg = false;
+	ipmflg = true;
+	disdsp = false;
+	dspflg = true;
+
+	for (i = 0; i < TNUM_TPRI; i++) {
+		queue_initialize(&(ready_queue[i]));
+	}
+	ready_primap = 0U;
+
+	for (i = 0; i < tnum_stsk; i++) {
+		j = INDEX_TSK(torder_table[i]);
+		p_tcb = &(tcb_table[j]);
+		p_tcb->p_tinib = &(tinib_table[j]);
+		p_tcb->actque = false;
+		make_dormant(p_tcb);
+		queue_initialize(&(p_tcb->mutex_queue));
+		if ((p_tcb->p_tinib->tskatr & TA_ACT) != 0U) {
+			(void) make_active(p_tcb);
+		}
+	}
+	queue_initialize(&free_tcb);
+	for (j = 0; i < tnum_tsk; i++, j++) {
+		p_tcb = &(tcb_table[i]);
+		p_tinib = &(atinib_table[j]);
+		p_tinib->tskatr = TA_NOEXS;
+		p_tcb->p_tinib = ((const TINIB *) p_tinib);
+		queue_insert_prev(&free_tcb, &(p_tcb->task_queue));
+	}
+}
+
+#endif /* TOPPERS_tskini */
+
+/*
+ *  ビットマップサーチ関数
+ *
+ *  bitmap内の1のビットの内，最も下位（右）のものをサーチし，そのビッ
+ *  ト番号を返す．ビット番号は，最下位ビットを0とする．bitmapに0を指定
+ *  してはならない．この関数では，bitmapが16ビットであることを仮定し，
+ *  uint16_t型としている．
+ *
+ *  ビットサーチ命令を持つプロセッサでは，ビットサーチ命令を使うように
+ *  書き直した方が効率が良い場合がある．このような場合には，ターゲット
+ *  依存部でビットサーチ命令を使ったbitmap_searchを定義し，
+ *  OMIT_BITMAP_SEARCHをマクロ定義すればよい．また，ビットサーチ命令の
+ *  サーチ方向が逆などの理由で優先度とビットとの対応を変更したい場合に
+ *  は，PRIMAP_BITをマクロ定義すればよい．
+ *
+ *  また，ライブラリにffsがあるなら，次のように定義してライブラリ関数を
+ *  使った方が効率が良い可能性もある．
+ *		#define	bitmap_search(bitmap) (ffs(bitmap) - 1)
+ */
+#ifndef PRIMAP_BIT
+#define	PRIMAP_BIT(pri)		(1U << (pri))
+#endif /* PRIMAP_BIT */
+
+#ifndef OMIT_BITMAP_SEARCH
+
+static const unsigned char bitmap_search_table[] = { 0, 1, 0, 2, 0, 1, 0,
+												3, 0, 1, 0, 2, 0, 1, 0 };
+
+Inline uint_t
+bitmap_search(uint16_t bitmap)
+{
+	uint_t	n = 0U;
+
+	assert(bitmap != 0U);
+	if ((bitmap & 0x00ffU) == 0U) {
+		bitmap >>= 8;
+		n += 8;
+	}
+	if ((bitmap & 0x0fU) == 0U) {
+		bitmap >>= 4;
+		n += 4;
+	}
+	return(n + bitmap_search_table[(bitmap & 0x0fU) - 1]);
+}
+
+#endif /* OMIT_BITMAP_SEARCH */
+
+/*
+ *  優先度ビットマップが空かのチェック
+ */
+Inline bool_t
+primap_empty(void)
+{
+	return(ready_primap == 0U);
+}
+
+/*
+ *  優先度ビットマップのサーチ
+ */
+Inline uint_t
+primap_search(void)
+{
+	return(bitmap_search(ready_primap));
+}
+
+/*
+ *  優先度ビットマップのセット
+ */
+Inline void
+primap_set(uint_t pri)
+{
+	ready_primap |= PRIMAP_BIT(pri);
+}
+
+/*
+ *  優先度ビットマップのクリア
+ */
+Inline void
+primap_clear(uint_t pri)
+{
+	ready_primap &= ~PRIMAP_BIT(pri);
+}
+
+/*
+ *  最高優先順位タスクのサーチ
+ */
+#ifdef TOPPERS_tsksched
+
+TCB *
+search_schedtsk(void)
+{
+	uint_t	schedpri;
+
+	schedpri = primap_search();
+	return((TCB *)(ready_queue[schedpri].p_next));
+}
+
+#endif /* TOPPERS_tsksched */
+
+/*
+ *  実行できる状態への遷移
+ *
+ *  最高優先順位のタスクを更新するのは，実行できるタスクがなかった場合
+ *  と，p_tcbの優先度が最高優先順位のタスクの優先度よりも高い場合であ
+ *  る．
+ */
+#ifdef TOPPERS_tskrun
+
+bool_t
+make_runnable(TCB *p_tcb)
+{
+	uint_t	pri = p_tcb->priority;
+
+	queue_insert_prev(&(ready_queue[pri]), &(p_tcb->task_queue));
+	primap_set(pri);
+
+	if (p_schedtsk == (TCB *) NULL || pri < p_schedtsk->priority) {
+		p_schedtsk = p_tcb;
+		return(dspflg);
+	}
+	return(false);
+}
+
+#endif /* TOPPERS_tskrun */
+
+/*
+ *  実行できる状態から他の状態への遷移
+ *
+ *  最高優先順位のタスクを更新するのは，p_tcbが最高優先順位のタスクで
+ *  あった場合である．p_tcbと同じ優先度のタスクが他にある場合は，p_tcb
+ *  の次のタスクが最高優先順位になる．そうでない場合は，レディキューを
+ *  サーチする必要がある．
+ */
+#ifdef TOPPERS_tsknrun
+
+bool_t
+make_non_runnable(TCB *p_tcb)
+{
+	uint_t	pri = p_tcb->priority;
+	QUEUE	*p_queue = &(ready_queue[pri]);
+
+	queue_delete(&(p_tcb->task_queue));
+	if (queue_empty(p_queue)) {
+		primap_clear(pri);
+		if (p_schedtsk == p_tcb) {
+			p_schedtsk = primap_empty() ? (TCB *) NULL : search_schedtsk();
+			return(dspflg);
+		}
+	}
+	else {
+		if (p_schedtsk == p_tcb) {
+			p_schedtsk = (TCB *)(p_queue->p_next);
+			return(dspflg);
+		}
+	}
+	return(false);
+}
+
+#endif /* TOPPERS_tsknrun */
+
+/*
+ *  休止状態への遷移
+ */
+#ifdef TOPPERS_tskdmt
+
+void
+make_dormant(TCB *p_tcb)
+{
+	p_tcb->tstat = TS_DORMANT;
+	p_tcb->bpriority = p_tcb->p_tinib->ipriority;
+	p_tcb->priority = p_tcb->p_tinib->ipriority;
+	p_tcb->wupque = false;
+	p_tcb->enatex = false;
+	p_tcb->texptn = 0U;
+	LOG_TSKSTAT(p_tcb);
+}
+
+#endif /* TOPPERS_tskdmt */
+
+/*
+ *  休止状態から実行できる状態への遷移
+ */
+#ifdef TOPPERS_tskact
+
+bool_t
+make_active(TCB *p_tcb)
+{
+	activate_context(p_tcb);
+	p_tcb->tstat = TS_RUNNABLE;
+	LOG_TSKSTAT(p_tcb);
+	return(make_runnable(p_tcb));
+}
+
+#endif /* TOPPERS_tskact */
+
+/*
+ *  タスクの優先度の変更
+ *
+ *  タスクが実行できる状態の場合には，レディキューの中での位置を変更す
+ *  る．オブジェクトの待ちキューの中で待ち状態になっている場合には，待
+ *  ちキューの中での位置を変更する．
+ *
+ *  最高優先順位のタスクを更新するのは，(1) p_tcbが最高優先順位のタス
+ *  クであって，その優先度を下げた場合，(2) p_tcbが最高優先順位のタス
+ *  クではなく，変更後の優先度が最高優先順位のタスクの優先度よりも高い
+ *  場合である．(1)の場合には，レディキューをサーチする必要がある．
+ */
+#ifdef TOPPERS_tskpri
+
+bool_t
+change_priority(TCB *p_tcb, uint_t newpri, bool_t mtxmode)
+{
+	uint_t	oldpri;
+
+	oldpri = p_tcb->priority;
+	p_tcb->priority = newpri;
+
+	if (TSTAT_RUNNABLE(p_tcb->tstat)) {
+		/*
+		 *  タスクが実行できる状態の場合
+		 */
+		queue_delete(&(p_tcb->task_queue));
+		if (queue_empty(&(ready_queue[oldpri]))) {
+			primap_clear(oldpri);
+		}
+		if (mtxmode) {
+			queue_insert_next(&(ready_queue[newpri]), &(p_tcb->task_queue));
+		}
+		else {
+			queue_insert_prev(&(ready_queue[newpri]), &(p_tcb->task_queue));
+		}
+		primap_set(newpri);
+
+		if (p_schedtsk == p_tcb) {
+			if (newpri >= oldpri) {
+				p_schedtsk = search_schedtsk();
+				return(p_schedtsk != p_tcb && dspflg);
+			}
+		}
+		else {
+			if (mtxmode ? newpri <= p_schedtsk->priority
+						: newpri < p_schedtsk->priority) {
+				p_schedtsk = p_tcb;
+				return(dspflg);
+			}
+		}
+	}
+	else {
+		if (TSTAT_WAIT_WOBJCB(p_tcb->tstat)) {
+			/*
+			 *  タスクが，同期・通信オブジェクトの管理ブロックの共通部
+			 *  分（WOBJCB）の待ちキューにつながれている場合
+			 */
+			wobj_change_priority(((WINFO_WOBJ *)(p_tcb->p_winfo))->p_wobjcb,
+																	p_tcb);
+		}
+	}
+	return(false);
+}
+
+#endif /* TOPPERS_tskpri */
+
+/*
+ *  レディキューの回転
+ *
+ *  最高優先順位のタスクを更新するのは，最高優先順位のタスクがタスクキ
+ *  ューの末尾に移動した場合である．
+ */
+#ifdef TOPPERS_tskrot
+
+bool_t
+rotate_ready_queue(uint_t pri)
+{
+	QUEUE	*p_queue = &(ready_queue[pri]);
+	QUEUE	*p_entry;
+
+	if (!queue_empty(p_queue) && p_queue->p_next->p_next != p_queue) {
+		p_entry = queue_delete_next(p_queue);
+		queue_insert_prev(p_queue, p_entry);
+		if (p_schedtsk == (TCB *) p_entry) {
+			p_schedtsk = (TCB *)(p_queue->p_next);
+			return(dspflg);
+		}
+	}
+	return(false);
+}
+
+#endif /* TOPPERS_tskrot */
+
+/*
+ *  タスク例外処理ルーチンの呼出し
+ *
+ *  ASPカーネルでは，タスク例外処理ルーチン内でCPUロック状態に遷移し，
+ *  元の状態に戻さずにリターンした場合，カーネルが元の状態に戻す．
+ */
+#ifdef TOPPERS_tsktex
+
+void
+call_texrtn(void)
+{
+	TEXPTN	texptn;
+	bool_t	saved_disdsp;
+
+	saved_disdsp = disdsp;
+	p_runtsk->enatex = false;
+	do {
+		texptn = p_runtsk->texptn;
+		p_runtsk->texptn = 0U;
+
+		t_unlock_cpu();
+		LOG_TEX_ENTER(p_runtsk, texptn);
+		(*((TEXRTN)(p_runtsk->p_tinib->texrtn)))(texptn,
+												p_runtsk->p_tinib->exinf);
+		LOG_TEX_LEAVE(p_runtsk);
+		if (!t_sense_lock()) {
+			t_lock_cpu();
+		}
+		if (!ipmflg) {
+			t_set_ipm(TIPM_ENAALL);
+			ipmflg = true;
+		}
+		disdsp = saved_disdsp;
+		dspflg = !disdsp;
+		p_runtsk->enatex = false;
+		if (p_runtsk != p_schedtsk && dspflg) {
+			/*
+			 *  ここでdispatchを呼び出す処理は，相互再帰呼出しになって
+			 *  いるが，dispatchを呼ぶ前にp_runtsk->enatexをfalseにして
+			 *  おけば支障がない．その理由については，「TOPPERS/ASP カー
+			 *  ネル 設計メモ」を参照のこと．
+			 */
+			dispatch();
+		}
+	} while (p_runtsk->texptn != 0U);
+	p_runtsk->enatex = true;
+}
+
+/*
+ *  タスク例外処理ルーチンの起動
+ */
+#ifndef OMIT_CALLTEX
+
+void
+calltex(void)
+{
+	if (p_runtsk->enatex && p_runtsk->texptn != 0U && ipmflg) {
+		call_texrtn();
+	}
+}
+
+#endif /* OMIT_CALLTEX */
+#endif /* TOPPERS_tsktex */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/kernel/task.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/kernel/task.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/kernel/task.h	(revision 457)
@@ -0,0 +1,498 @@
+/*
+ *  TOPPERS/ASP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Advanced Standard Profile Kernel
+ * 
+ *  Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
+ *                              Toyohashi Univ. of Technology, JAPAN
+ *  Copyright (C) 2005-2010 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  $Id$
+ */
+
+/*
+ *		タスク管理モジュール
+ */
+
+#ifndef TOPPERS_TASK_H
+#define TOPPERS_TASK_H
+
+#include <queue.h>
+#include "time_event.h"
+
+/*
+ *  トレースログマクロのデフォルト定義
+ */
+#ifndef LOG_TSKSTAT
+#define LOG_TSKSTAT(p_tcb)
+#endif /* LOG_TSKSTAT */
+
+/*
+ *  タスク優先度の内部表現・外部表現変換マクロ
+ */
+#define INT_PRIORITY(x)		((uint_t)((x) - TMIN_TPRI))
+#define EXT_TSKPRI(x)		((PRI)(x) + TMIN_TPRI)
+
+/*
+ *  タスク状態の内部表現
+ *
+ *  TCB中のタスク状態では，実行状態（RUNNING）と実行可能状態（READY）
+ *  は区別しない．両状態を総称して，実行できる状態（RUNNABLE）と呼ぶ．
+ *  二重待ち状態は，(TS_WAITING | TS_SUSPENDED)で表す．TS_WAIT_???は待
+ *  ち要因を表し，待ち状態（二重待ち状態を含む）の場合にのみ設定する．
+ */
+#define TS_DORMANT		0x00U			/* 休止状態 */
+#define TS_RUNNABLE		0x01U			/* 実行できる状態 */
+#define TS_WAITING		0x02U			/* 待ち状態 */
+#define TS_SUSPENDED	0x04U			/* 強制待ち状態 */
+
+#define TS_WAIT_DLY		(0x00U << 3)	/* 時間経過待ち */
+#define TS_WAIT_SLP		(0x01U << 3)	/* 起床待ち */
+#define TS_WAIT_RDTQ	(0x02U << 3)	/* データキューからの受信待ち */
+#define TS_WAIT_RPDQ	(0x03U << 3)	/* 優先度データキューからの受信待ち */
+#define TS_WAIT_SEM		(0x04U << 3)	/* セマフォ資源の獲得待ち */
+#define TS_WAIT_FLG		(0x05U << 3)	/* イベントフラグ待ち */
+#define TS_WAIT_SDTQ	(0x06U << 3)	/* データキューへの送信待ち */
+#define TS_WAIT_SPDQ	(0x07U << 3)	/* 優先度データキューへの送信待ち */
+#define TS_WAIT_MBX		(0x08U << 3)	/* メールボックスからの受信待ち */
+#define TS_WAIT_MPF		(0x09U << 3)	/* 固定長メモリブロックの獲得待ち */
+#define TS_WAIT_MTX		(0x0aU << 3)	/* ミューテックスのロック待ち */
+
+/*
+ *  タスク状態判別マクロ
+ *
+ *  TSTAT_DORMANTはタスクが休止状態であるかどうかを，TSTAT_RUNNABLEは
+ *  タスクが実行できる状態であるかどうかを判別する．TSTAT_WAITINGは待
+ *  ち状態と二重待ち状態のいずれかであるかどうかを，TSTAT_SUSPENDEDは
+ *  強制待ち状態と二重待ち状態のいずれかであるかどうかを判別する．
+ */
+#define TSTAT_DORMANT(tstat)	((tstat) == TS_DORMANT)
+#define TSTAT_RUNNABLE(tstat)	(((tstat) & TS_RUNNABLE) != 0U)
+#define TSTAT_WAITING(tstat)	(((tstat) & TS_WAITING) != 0U)
+#define TSTAT_SUSPENDED(tstat)	(((tstat) & TS_SUSPENDED) != 0U)
+
+/*
+ *  タスク待ち要因判別マクロ
+ *
+ *  TSTAT_WAIT_SLPはタスクが起床待ちであるかどうかを，TSTAT_WAIT_WOBJ
+ *  はタスクが同期・通信オブジェクトに対する待ちであるか（言い換えると，
+ *  同期通信オブジェクトの待ちキューにつながれているか）どうかを判別す
+ *  る．また，TSTAT_WAIT_WOBJCBはタスクが同期・通信オブジェクトの管理
+ *  ブロックの共通部分（WOBJCB）の待ちキューにつながれているかどうかを
+ *  判別する．
+ *
+ *  TSTAT_WAIT_SLPは，任意のタスク状態の中から，タスクが起床待ちである
+ *  ことを判別できる．すなわち，TSTAT_WAITINGにより待ち状態であることを
+ *  判別せずに，TSTAT_SLPだけを用いて起床待ち状態であることを判別できる．
+ *  これを効率的に実現するために，TS_WAIT_SLPの値を，(0x00U << 3)ではな
+ *  く(0x01U << 3)としている．そのため，タスクが時間経過待ち状態である
+ *  ことを判別するためのTSTAT_WAIT_DLYを，TSTAT_WAIT_SLPと同様の方法で
+ *  実現することはできない．
+ */
+#define TS_WAIT_MASK	(0x0fU << 3)	/* 待ち要因の取出しマスク */
+
+#define TSTAT_WAIT_SLP(tstat)		(((tstat) & TS_WAIT_MASK) == TS_WAIT_SLP)
+#define TSTAT_WAIT_WOBJ(tstat)		(((tstat) & TS_WAIT_MASK) >= TS_WAIT_RDTQ)
+#define TSTAT_WAIT_WOBJCB(tstat)	(((tstat) & TS_WAIT_MASK) >= TS_WAIT_SEM)
+#define TSTAT_WAIT_MTX(tstat)		(((tstat) & TS_WAIT_MASK) == TS_WAIT_MTX)
+
+/*
+ *  待ち情報ブロック（WINFO）の定義
+ *
+ *  タスクが待ち状態の間は，TCBおよびそのp_winfoで指されるWINFOを次の
+ *  ように設定しなければならない．
+ *
+ *  (a) TCBのタスク状態を待ち状態（TS_WAITING）にする．その際に，待ち
+ *  要因（TS_WAIT_???）も設定する．
+ *
+ *  (b) タイムアウトを監視するために，タイムイベントブロックを登録する．
+ *  登録するタイムイベントブロックは，待ちに入るサービスコール処理関数
+ *  のローカル変数として確保し，それへのポインタをWINFOのp_tmevtbに記
+ *  憶する．タイムアウトの監視が必要ない場合（永久待ちの場合）には，
+ *  p_tmevtbをNULLにする．
+ *
+ *  同期・通信オブジェクトに対する待ち状態の場合には，標準のWINFOに
+ *  p_wobjcbフィールドを追加した構造体（WINFO_WOBJ，wait.hで定義）を使
+ *  う．また，以下の(c)～(e)の設定を行う必要がある．同期・通信オブジェ
+ *  クトに関係しない待ち（起床待ち，時間経過待ち）の場合には，(c)～(e)
+ *  は必要ない．
+ *
+ *  (c) TCBを待ち対象の同期・通信オブジェクトの待ちキューにつなぐ．待
+ *  ちキューにつなぐために，task_queueを使う．
+ *
+ *  (d) 待ち対象の同期・通信オブジェクトの管理ブロックへのポインタを，
+ *  WINFO_WOBJのp_wobjcbに記憶する．
+ *
+ *  (e) 待ち対象の同期・通信オブジェクトに依存して記憶することが必要な
+ *  情報がある場合には，WINFO_WOBJに必要な情報のためのフィールドを追加
+ *  した構造体を定義し，WINFO_WOBJの代わりに用いる．
+ *
+ *  待ち状態を解除する際には，待ち解除したタスクに対する返値をWINFOの
+ *  wercdに設定する．wercdが必要なのは待ち解除以降であるのに対して，
+ *  p_tmevtbは待ち解除後は必要ないため，メモリ節約のために共用体を使っ
+ *  ている．そのため，wercdへエラーコードを設定するのは，タイムイベント
+ *  ブロックを登録解除した後にしなければならない．
+ */
+typedef union waiting_information {
+	ER		wercd;			/* 待ち解除時のエラーコード */
+	TMEVTB	*p_tmevtb;		/* 待ち状態用のタイムイベントブロック */
+} WINFO;
+
+/*
+ *  タスク初期化ブロック
+ *
+ *  タスクに関する情報を，値が変わらないためにROMに置ける部分（タスク
+ *  初期化ブロック）と，値が変化するためにRAMに置かなければならない部
+ *  分（タスク管理ブロック，TCB）に分離し，TCB内に対応するタスク初期化
+ *  ブロックを指すポインタを入れる．タスク初期化ブロック内に対応する
+ *  TCBを指すポインタを入れる方法の方が，RAMの節約の観点からは望ましい
+ *  が，実行効率が悪くなるために採用していない．他のオブジェクトについ
+ *  ても同様に扱う．
+ *
+ *  タスク初期化ブロックには，DEF_TEXで定義されるタスク例外処理ルーチ
+ *  ンに関する情報も含む．
+ */
+typedef struct task_initialization_block {
+	ATR			tskatr;			/* タスク属性 */
+	intptr_t	exinf;			/* タスクの拡張情報 */
+	TASK		task;			/* タスクの起動番地 */
+	uint_t		ipriority;		/* タスクの起動時優先度（内部表現） */
+
+#ifdef USE_TSKINICTXB
+	TSKINICTXB	tskinictxb;		/* タスク初期化コンテキストブロック */
+#else /* USE_TSKINICTXB */
+	SIZE		stksz;			/* スタック領域のサイズ（丸めた値） */
+	void		*stk;			/* スタック領域の先頭番地 */
+#endif /* USE_TSKINICTXB */
+
+	ATR			texatr;			/* タスク例外処理ルーチン属性 */
+	TEXRTN		texrtn;			/* タスク例外処理ルーチンの起動番地 */
+} TINIB;
+
+/*
+ *  TCB中のフィールドのビット幅の定義
+ *
+ *  プロセッサによっては，TCB中のフィールドのビット幅でメモリ使用量と
+ *  性能がトレードオフになるため，ターゲット依存にフィールドのビット幅
+ *  を変更することを許している．
+ */
+#ifndef TBIT_TCB_PRIORITY
+#define	TBIT_TCB_PRIORITY		8		/* priorityフィールドのビット幅 */
+#endif /* TBIT_TCB_PRIORITY */
+
+/*
+ *  タスク管理ブロック（TCB）
+ *
+ *  ASPカーネルでは，タスクの起動要求キューイング数の最大値（TMAX_ACTCNT）
+ *  と起床要求キューイング数の最大値（TMAX_WUPCNT）は1に固定されている
+ *  ため，キューイングされているかどうかの真偽値で表現することができる．
+ *  また，強制待ち要求ネスト数の最大値（TMAX_SUSCNT）が1に固定されてい
+ *  るので，強制待ち要求ネスト数（suscnt）は必要ない．
+ *
+ *  TCBのいくつかのフィールドは，特定のタスク状態でのみ有効な値を保持し，
+ *  それ以外の場合は値が保証されない（よって，参照してはならない）．各
+ *  フィールドが有効な値を保持する条件は次の通り．
+ *
+ *  ・初期化後は常に有効：
+ *  		p_tinib，tstat，actque
+ *  ・休止状態以外で有効（休止状態では初期値になっている）：
+ *  		bpriority，priority，wupque，enatex，texptn，mutex_queue
+ *  ・待ち状態（二重待ち状態を含む）で有効：
+ *  		p_winfo
+ *  ・実行できる状態と同期・通信オブジェクトに対する待ち状態で有効：
+ *  		task_queue
+ *  ・実行可能状態，待ち状態，強制待ち状態，二重待ち状態で有効：
+ *  		tskctxb
+ */
+typedef struct task_control_block {
+	QUEUE			task_queue;		/* タスクキュー */
+	const TINIB		*p_tinib;		/* 初期化ブロックへのポインタ */
+
+#ifdef UINT8_MAX
+	uint8_t			tstat;			/* タスク状態（内部表現）*/
+#else /* UINT8_MAX */
+	BIT_FIELD_UINT	tstat : 8;		/* タスク状態（内部表現）*/
+#endif /* UINT8_MAX */
+#if defined(UINT8_MAX) && (TBIT_TCB_PRIORITY == 8)
+	uint8_t			bpriority;		/* ベース優先度（内部表現）*/
+	uint8_t			priority;		/* 現在の優先度（内部表現）*/
+#else /* defined(UINT8_MAX) && (TBIT_TCB_PRIORITY == 8) */
+	BIT_FIELD_UINT	bpriority : TBIT_TCB_PRIORITY;
+									/* ベース優先度（内部表現）*/
+	BIT_FIELD_UINT	priority : TBIT_TCB_PRIORITY;
+									/* 現在の優先度（内部表現）*/
+#endif /* defined(UINT8_MAX) && (TBIT_TCB_PRIORITY == 8) */
+	BIT_FIELD_BOOL	actque : 1;		/* 起動要求キューイング */
+	BIT_FIELD_BOOL	wupque : 1;		/* 起床要求キューイング */
+	BIT_FIELD_BOOL	enatex : 1;		/* タスク例外処理許可状態 */
+
+	TEXPTN			texptn;			/* 保留例外要因 */
+	WINFO			*p_winfo;		/* 待ち情報ブロックへのポインタ */
+	QUEUE			mutex_queue;	/* ロックしているミューテックスのキュー */
+	TSKCTXB			tskctxb;		/* タスクコンテキストブロック */
+} TCB;
+
+/*
+ *  実行状態のタスク
+ *
+ *  実行状態のタスク（＝プロセッサがコンテキストを持っているタスク）の
+ *  TCBを指すポインタ．実行状態のタスクがない場合はNULLにする．
+ *
+ *  サービスコールの処理中で，自タスク（サービスコールを呼び出したタス
+ *  ク）に関する情報を参照する場合はp_runtskを使う．p_runtskを書き換え
+ *  るのは，ディスパッチャ（と初期化処理）のみである．
+ */
+extern TCB	*p_runtsk;
+
+/*
+ *  最高優先順位のタスク
+ *
+ *  実行できるタスクの中で最高優先順位のタスクのTCBを指すポインタ．実
+ *  行できるタスクがない場合はNULLにする．
+ *
+ *  ディスパッチ禁止状態など，ディスパッチが保留されている間はp_runtsk
+ *  と一致しているとは限らない．
+ */
+extern TCB	*p_schedtsk;
+
+/*
+ *  ディスパッチ／タスク例外処理ルーチン起動要求フラグ
+ *
+ *  割込みハンドラ／CPU例外ハンドラの出口処理に，ディスパッチまたは
+ *  タスク例外処理ルーチンの起動を要求することを示すフラグ．
+ */
+extern bool_t	reqflg;
+
+/*
+ *  割込み優先度マスク全解除状態
+ *
+ *  割込み優先度マスク全解除状態であることを示すフラグ．
+ */
+extern bool_t	ipmflg;
+
+/*
+ *  ディスパッチ禁止状態
+ *
+ *  ディスパッチ禁止状態であることを示すフラグ．
+ */
+extern bool_t	disdsp;
+
+/*
+ *  タスクディスパッチ可能状態
+ *
+ *  割込み優先度マスク全解除状態であり，ディスパッチ許可状態である（ディ
+ *  スパッチ禁止状態でない）ことを示すフラグ．
+ */
+extern bool_t	dspflg;
+
+/*
+ *  レディキュー
+ *
+ *  レディキューは，実行できる状態のタスクを管理するためのキューである．
+ *  実行状態のタスクも管理しているため，レディ（実行可能）キューという
+ *  名称は正確ではないが，レディキューという名称が定着しているため，こ
+ *  の名称で呼ぶことにする．
+ *
+ *  レディキューは，優先度ごとのタスクキューで構成されている．タスクの
+ *  TCBは，該当する優先度のキューに登録される．
+ */
+extern QUEUE	ready_queue[TNUM_TPRI];
+
+/*
+ *  レディキューサーチのためのビットマップ
+ *
+ *  レディキューのサーチを効率よく行うために，優先度ごとのタスクキュー
+ *  にタスクが入っているかどうかを示すビットマップを用意している．ビッ
+ *  トマップを使うことで，メモリアクセスの回数を減らすことができるが，
+ *  ビット操作命令が充実していないプロセッサで，優先度の段階数が少ない
+ *  場合には，ビットマップ操作のオーバーヘッドのために，逆に効率が落ち
+ *  る可能性もある．
+ *
+ *  優先度が16段階であることを仮定しているため，uint16_t型としている．
+ */
+extern uint16_t	ready_primap;
+
+/*
+ *  使用していないTCBのリスト
+ */
+extern QUEUE	free_tcb;
+
+/*
+ *  タスクIDの最大値（kernel_cfg.c）
+ */
+extern const ID	tmax_tskid;
+extern const ID	tmax_stskid;
+
+/*
+ *  タスク初期化ブロックのエリア（kernel_cfg.c）
+ */
+extern const TINIB	tinib_table[];
+extern TINIB		atinib_table[];
+
+/*
+ *  タスク生成順序テーブル（kernel_cfg.c）
+ */
+extern const ID	torder_table[];
+
+/*
+ *  TCBのエリア（kernel_cfg.c）
+ */
+extern TCB	tcb_table[];
+
+/*
+ *  タスクの数
+ */
+#define tnum_tsk	((uint_t)(tmax_tskid - TMIN_TSKID + 1))
+#define tnum_stsk	((uint_t)(tmax_stskid - TMIN_TSKID + 1))
+
+/*
+ *  タスクIDからTCBを取り出すためのマクロ
+ */
+#define INDEX_TSK(tskid)	((uint_t)((tskid) - TMIN_TSKID))
+#define get_tcb(tskid)		(&(tcb_table[INDEX_TSK(tskid)]))
+#define get_tcb_self(tskid)	((tskid) == TSK_SELF ? p_runtsk : get_tcb(tskid))
+
+/*
+ *  TCBからタスクIDを取り出すためのマクロ
+ */
+#define	TSKID(p_tcb)	((ID)(((p_tcb) - tcb_table) + TMIN_TSKID))
+
+/*
+ *  タスク管理モジュールの初期化
+ */
+extern void	initialize_task(void);
+
+/*
+ *  最高優先順位タスクのサーチ
+ *
+ *  レディキュー中の最高優先順位のタスクをサーチし，そのTCBへのポインタ
+ *  を返す．レディキューが空の場合には，この関数を呼び出してはならない．
+ */
+extern TCB	*search_schedtsk(void);
+
+/*
+ *  実行できる状態への遷移
+ *
+ *  p_tcbで指定されるタスクをレディキューに挿入する．レディキューに挿入
+ *  したタスクの優先度が，最高優先順位のタスクの優先度よりも高い場合は，
+ *  最高優先順位のタスクを更新し，ディスパッチ許可状態であればtrueを返
+ *  す．そうでない場合はfalseを返す．
+ */
+extern bool_t	make_runnable(TCB *p_tcb);
+
+/*
+ *  実行できる状態から他の状態への遷移
+ *
+ *  p_tcbで指定されるタスクをレディキューから削除する．p_tcbで指定した
+ *  タスクが最高優先順位のタスクであった場合には，最高優先順位のタスク
+ *  を設定しなおし，ディスパッチ許可状態であればtrueを返す．そうでない
+ *  場合はfalseを返す．タスクの状態は更新しない．
+ */
+extern bool_t	make_non_runnable(TCB *p_tcb);
+
+/*
+ *  休止状態への遷移
+ *
+ *  p_tcbで指定されるタスクの状態を休止状態とする．また，タスクの起動
+ *  時に初期化すべき変数の初期化と，タスク起動のためのコンテキストを設
+ *  定する．
+ */
+extern void	make_dormant(TCB *p_tcb);
+
+/*
+ *  休止状態から実行できる状態への遷移
+ *
+ *  p_tcbで指定されるタスクの状態を休止状態から実行できる状態とする．
+ *  実行できる状態に遷移したタスクへのディスパッチが必要な場合はtrue，
+ *  そうでない場合はfalseを返す．
+ */
+extern bool_t	make_active(TCB *p_tcb);
+
+/*
+ *  タスクの優先度の変更
+ *
+ *  p_tcbで指定されるタスクの優先度をnewpri（内部表現）に変更する．また，
+ *  必要な場合には最高優先順位のタスクを更新し，ディスパッチ許可状態で
+ *  あればtrueを返す．そうでない場合はfalseを返す．
+ *
+ *  p_tcbで指定されるタスクの優先順位は，mtxmodeがfalseの時は同じ優先度
+ *  のタスクの中で最低，mtxmodeがtrueの時は同じ優先度のタスクの中で最高
+ *  とする．
+ */
+extern bool_t	change_priority(TCB *p_tcb, uint_t newpri, bool_t mtxmode);
+
+/*
+ *  レディキューの回転
+ *
+ *  レディキュー中の，priで指定される優先度のタスクキューを回転させる．
+ *  また，必要な場合には最高優先順位のタスクを変更し，ディスパッチが保
+ *  留されていなければtrueを返す．そうでない場合はfalseを返す．
+ */
+extern bool_t	rotate_ready_queue(uint_t pri);
+
+/*
+ *  タスク例外処理ルーチンの呼出し
+ *
+ *  タスク例外処理ルーチンを呼び出す．呼び出す前に，実行状態のタスクの
+ *  保留例外要因をクリアし，タスク例外処理禁止状態にし，CPUロックを解
+ *  除する．
+ *
+ *  タスク例外処理ルーチンから戻ると，まずCPUロック状態に戻し，その間
+ *  に保留例外要因が0でなくなっていれば，再びタスク例外処理ルーチンを
+ *  呼び出す．保留例外要因が0の場合には，例外処理許可状態にして関数か
+ *  らリターンする．
+ *
+ *  この関数は，実行状態のタスクが，タスク例外処理許可状態（enatexが
+ *  true）で，保留例外要因が0でない（texptnが0でない）場合に呼び出すこ
+ *  とを想定している．この関数は，CPUロック状態で呼び出さなければなら
+ *  ない．
+ */
+extern void	call_texrtn(void);
+
+/*
+ *  タスク例外処理ルーチンの起動
+ *
+ *  実行状態のタスクがタスク例外処理ルーチンの起動条件を満たしていれば，
+ *  タスク例外処理ルーチンを呼び出す．CPU例外処理ルーチンを呼び出す時
+ *  は，一時的にCPUロックを解除する．
+ *
+ *  この関数は，ディスパッチャや割込みハンドラ／CPU例外ハンドラの出口
+ *  処理から呼び出されることを想定している．この関数は，CPUロック状態
+ *  で呼び出さなければならない．
+ *
+ *  実行効率を上げるために，この関数をターゲット依存部で記述してもよい．
+ *  その場合には，OMIT_CALLTEXをマクロ定義する．
+ */
+extern void	calltex(void);
+
+#endif /* TOPPERS_TASK_H */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/kernel/task_except.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/kernel/task_except.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/kernel/task_except.c	(revision 457)
@@ -0,0 +1,368 @@
+/*
+ *  TOPPERS/ASP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Advanced Standard Profile Kernel
+ * 
+ *  Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
+ *                              Toyohashi Univ. of Technology, JAPAN
+ *  Copyright (C) 2005-2014 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  $Id$
+ */
+
+/*
+ *		タスク例外処理機能
+ */
+
+#include "kernel_impl.h"
+#include "check.h"
+#include "task.h"
+
+/*
+ *  トレースログマクロのデフォルト定義
+ */
+#ifndef LOG_DEF_TEX_ENTER
+#define LOG_DEF_TEX_ENTER(tskid, pk_dtex)
+#endif /* LOG_DEF_TEX_ENTER */
+
+#ifndef LOG_DEF_TEX_LEAVE
+#define LOG_DEF_TEX_LEAVE(ercd)
+#endif /* LOG_DEF_TEX_LEAVE */
+
+#ifndef LOG_RAS_TEX_ENTER
+#define LOG_RAS_TEX_ENTER(tskid, rasptn)
+#endif /* LOG_RAS_TEX_ENTER */
+
+#ifndef LOG_RAS_TEX_LEAVE
+#define LOG_RAS_TEX_LEAVE(ercd)
+#endif /* LOG_RAS_TEX_LEAVE */
+
+#ifndef LOG_IRAS_TEX_ENTER
+#define LOG_IRAS_TEX_ENTER(tskid, rasptn)
+#endif /* LOG_IRAS_TEX_ENTER */
+
+#ifndef LOG_IRAS_TEX_LEAVE
+#define LOG_IRAS_TEX_LEAVE(ercd)
+#endif /* LOG_IRAS_TEX_LEAVE */
+
+#ifndef LOG_DIS_TEX_ENTER
+#define LOG_DIS_TEX_ENTER()
+#endif /* LOG_DIS_TEX_ENTER */
+
+#ifndef LOG_DIS_TEX_LEAVE
+#define LOG_DIS_TEX_LEAVE(ercd)
+#endif /* LOG_DIS_TEX_LEAVE */
+
+#ifndef LOG_ENA_TEX_ENTER
+#define LOG_ENA_TEX_ENTER()
+#endif /* LOG_ENA_TEX_ENTER */
+
+#ifndef LOG_ENA_TEX_LEAVE
+#define LOG_ENA_TEX_LEAVE(ercd)
+#endif /* LOG_ENA_TEX_LEAVE */
+
+#ifndef LOG_SNS_TEX_ENTER
+#define LOG_SNS_TEX_ENTER()
+#endif /* LOG_SNS_TEX_ENTER */
+
+#ifndef LOG_SNS_TEX_LEAVE
+#define LOG_SNS_TEX_LEAVE(state)
+#endif /* LOG_SNS_TEX_LEAVE */
+
+#ifndef LOG_REF_TEX_ENTER
+#define LOG_REF_TEX_ENTER(tskid, pk_rtex)
+#endif /* LOG_REF_TEX_ENTER */
+
+#ifndef LOG_REF_TEX_LEAVE
+#define LOG_REF_TEX_LEAVE(ercd, pk_rtex)
+#endif /* LOG_REF_TEX_LEAVE */
+
+/*
+ *  タスク例外処理ルーチンの定義
+ */
+#ifdef TOPPERS_def_tex
+
+ER_UINT
+def_tex(ID tskid, const T_DTEX *pk_dtex)
+{
+	TCB		*p_tcb;
+	TINIB	*p_tinib;
+	ER		ercd;
+
+	LOG_DEF_TEX_ENTER(tskid, pk_dtex);
+	CHECK_TSKCTX_UNL();
+	CHECK_TSKID_SELF(tskid);
+	CHECK_RSATR(pk_dtex->texatr, TA_NULL);
+	if (pk_dtex->texrtn != NULL) {
+		CHECK_ALIGN_FUNC(pk_dtex->texrtn);
+		CHECK_NONNULL_FUNC(pk_dtex->texrtn);
+	}
+	p_tcb = get_tcb_self(tskid);
+	p_tinib = (TINIB *)(p_tcb->p_tinib);
+
+	t_lock_cpu();
+	if (p_tcb->p_tinib->tskatr == TA_NOEXS) {
+		ercd = E_NOEXS;
+	}
+	else if (TSKID(p_tcb) > tmax_stskid) {
+		if (pk_dtex->texrtn != NULL) {
+			if (p_tinib->texrtn != NULL) {
+				ercd = E_OBJ;
+			}
+			else {
+				p_tinib->texatr = pk_dtex->texatr;
+				p_tinib->texrtn = pk_dtex->texrtn;
+				ercd = E_OK;
+			}
+		}
+		else {
+			if (p_tinib->texrtn != NULL) {
+				p_tinib->texrtn = NULL;
+				p_tcb->enatex = false;
+				p_tcb->texptn = 0U;
+				ercd = E_OK;
+			}
+			else {
+				ercd = E_OBJ;
+			}
+		}
+	}
+	else {
+		ercd = E_OBJ;
+	}
+	t_unlock_cpu();
+
+  error_exit:
+	LOG_DEF_TEX_LEAVE(ercd);
+	return(ercd);
+}
+
+#endif /* TOPPERS_def_tex */
+
+/*
+ *  タスク例外処理の要求
+ */
+#ifdef TOPPERS_ras_tex
+
+ER
+ras_tex(ID tskid, TEXPTN rasptn)
+{
+	TCB		*p_tcb;
+	ER		ercd;
+
+	LOG_RAS_TEX_ENTER(tskid, rasptn);
+	CHECK_TSKCTX_UNL();
+	CHECK_TSKID_SELF(tskid);
+	CHECK_PAR(rasptn != 0U);
+	p_tcb = get_tcb_self(tskid);
+
+	t_lock_cpu();
+	if (p_tcb->p_tinib->tskatr == TA_NOEXS) {
+		ercd = E_NOEXS;
+	}
+	else if (TSTAT_DORMANT(p_tcb->tstat) || p_tcb->p_tinib->texrtn == NULL) {
+		ercd = E_OBJ;
+	}
+	else {
+		p_tcb->texptn |= rasptn;
+		if (p_tcb == p_runtsk && p_runtsk->enatex && ipmflg) {
+			call_texrtn();
+		}
+		ercd = E_OK;
+	}
+	t_unlock_cpu();
+
+  error_exit:
+	LOG_RAS_TEX_LEAVE(ercd);
+	return(ercd);
+}
+
+#endif /* TOPPERS_ras_tex */
+
+/*
+ *  タスク例外処理の要求（非タスクコンテキスト用）
+ */
+#ifdef TOPPERS_iras_tex
+
+ER
+iras_tex(ID tskid, TEXPTN rasptn)
+{
+	TCB		*p_tcb;
+	ER		ercd;
+
+	LOG_IRAS_TEX_ENTER(tskid, rasptn);
+	CHECK_INTCTX_UNL();
+	CHECK_TSKID(tskid);
+	CHECK_PAR(rasptn != 0U);
+	p_tcb = get_tcb(tskid);
+
+	i_lock_cpu();
+	if (p_tcb->p_tinib->tskatr == TA_NOEXS) {
+		ercd = E_NOEXS;
+	}
+	else if (TSTAT_DORMANT(p_tcb->tstat) || p_tcb->p_tinib->texrtn == NULL) {
+		ercd = E_OBJ;
+	}
+	else {
+		p_tcb->texptn |= rasptn;
+		if (p_tcb == p_runtsk && p_runtsk->enatex && ipmflg) {
+			reqflg = true;
+		}
+		ercd = E_OK;
+	}
+	i_unlock_cpu();
+
+  error_exit:
+	LOG_IRAS_TEX_LEAVE(ercd);
+	return(ercd);
+}
+
+#endif /* TOPPERS_iras_tex */
+
+/*
+ *  タスク例外処理の禁止
+ */
+#ifdef TOPPERS_dis_tex
+
+ER
+dis_tex(void)
+{
+	ER		ercd;
+
+	LOG_DIS_TEX_ENTER();
+	CHECK_TSKCTX_UNL();
+
+	t_lock_cpu();
+	if (p_runtsk->p_tinib->texrtn == NULL) {
+		ercd = E_OBJ;
+	}
+	else {
+		p_runtsk->enatex = false;
+		ercd = E_OK;
+	}
+	t_unlock_cpu();
+
+  error_exit:
+	LOG_DIS_TEX_LEAVE(ercd);
+	return(ercd);
+}
+
+#endif /* TOPPERS_dis_tex */
+
+/*
+ *  タスク例外処理の許可
+ */
+#ifdef TOPPERS_ena_tex
+
+ER
+ena_tex(void)
+{
+	ER		ercd;
+
+	LOG_ENA_TEX_ENTER();
+	CHECK_TSKCTX_UNL();
+
+	t_lock_cpu();
+	if (p_runtsk->p_tinib->texrtn == NULL) {
+		ercd = E_OBJ;
+	}
+	else {
+		p_runtsk->enatex = true;
+		if (p_runtsk->texptn != 0U && ipmflg) {
+			call_texrtn();
+		}
+		ercd = E_OK;
+	}
+	t_unlock_cpu();
+
+  error_exit:
+	LOG_ENA_TEX_LEAVE(ercd);
+	return(ercd);
+}
+
+#endif /* TOPPERS_ena_tex */
+
+/*
+ *  タスク例外処理禁止状態の参照
+ */
+#ifdef TOPPERS_sns_tex
+
+bool_t
+sns_tex(void)
+{
+	bool_t	state;
+
+	LOG_SNS_TEX_ENTER();
+	state = (p_runtsk != NULL && p_runtsk->enatex) ? false : true;
+	LOG_SNS_TEX_LEAVE(state);
+	return(state);
+}
+
+#endif /* TOPPERS_sns_tex */
+
+/*
+ *  タスク例外処理の状態参照
+ */
+#ifdef TOPPERS_ref_tex
+
+ER
+ref_tex(ID tskid, T_RTEX *pk_rtex)
+{
+	TCB		*p_tcb;
+	ER		ercd;
+
+	LOG_REF_TEX_ENTER(tskid, pk_rtex);
+	CHECK_TSKCTX_UNL();
+	CHECK_TSKID_SELF(tskid);
+	p_tcb = get_tcb_self(tskid);
+
+	t_lock_cpu();
+	if (p_tcb->p_tinib->tskatr == TA_NOEXS) {
+		ercd = E_NOEXS;
+	}
+	else if (TSTAT_DORMANT(p_tcb->tstat) || p_tcb->p_tinib->texrtn == NULL) {
+		ercd = E_OBJ;
+	}
+	else {
+		pk_rtex->texstat = (p_tcb->enatex) ? TTEX_ENA : TTEX_DIS;
+		pk_rtex->pndptn = p_tcb->texptn;
+		ercd = E_OK;
+	}
+	t_unlock_cpu();
+
+  error_exit:
+	LOG_REF_TEX_LEAVE(ercd, pk_rtex);
+	return(ercd);
+}
+
+#endif /* TOPPERS_ref_tex */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/kernel/task_manage.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/kernel/task_manage.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/kernel/task_manage.c	(revision 457)
@@ -0,0 +1,615 @@
+/*
+ *  TOPPERS/ASP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Advanced Standard Profile Kernel
+ * 
+ *  Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
+ *                              Toyohashi Univ. of Technology, JAPAN
+ *  Copyright (C) 2005-2017 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  $Id$
+ */
+
+/*
+ *		タスク管理機能
+ */
+
+#include "kernel_impl.h"
+#include "check.h"
+#include "task.h"
+#include "wait.h"
+#include "mutex.h"
+
+/*
+ *  トレースログマクロのデフォルト定義
+ */
+#ifndef LOG_ACRE_TSK_ENTER
+#define LOG_ACRE_TSK_ENTER(pk_ctsk)
+#endif /* LOG_ACRE_TSK_ENTER */
+
+#ifndef LOG_ACRE_TSK_LEAVE
+#define LOG_ACRE_TSK_LEAVE(ercd)
+#endif /* LOG_ACRE_TSK_LEAVE */
+
+#ifndef LOG_DEL_TSK_ENTER
+#define LOG_DEL_TSK_ENTER(tskid)
+#endif /* LOG_DEL_TSK_ENTER */
+
+#ifndef LOG_DEL_TSK_LEAVE
+#define LOG_DEL_TSK_LEAVE(ercd)
+#endif /* LOG_DEL_TSK_LEAVE */
+
+#ifndef LOG_ACT_TSK_ENTER
+#define LOG_ACT_TSK_ENTER(tskid)
+#endif /* LOG_ACT_TSK_ENTER */
+
+#ifndef LOG_ACT_TSK_LEAVE
+#define LOG_ACT_TSK_LEAVE(ercd)
+#endif /* LOG_ACT_TSK_LEAVE */
+
+#ifndef LOG_IACT_TSK_ENTER
+#define LOG_IACT_TSK_ENTER(tskid)
+#endif /* LOG_IACT_TSK_ENTER */
+
+#ifndef LOG_IACT_TSK_LEAVE
+#define LOG_IACT_TSK_LEAVE(ercd)
+#endif /* LOG_IACT_TSK_LEAVE */
+
+#ifndef LOG_CAN_ACT_ENTER
+#define LOG_CAN_ACT_ENTER(tskid)
+#endif /* LOG_CAN_ACT_ENTER */
+
+#ifndef LOG_CAN_ACT_LEAVE
+#define LOG_CAN_ACT_LEAVE(ercd)
+#endif /* LOG_CAN_ACT_LEAVE */
+
+#ifndef LOG_EXT_TSK_ENTER
+#define LOG_EXT_TSK_ENTER()
+#endif /* LOG_EXT_TSK_ENTER */
+
+#ifndef LOG_EXT_TSK_LEAVE
+#define LOG_EXT_TSK_LEAVE(ercd)
+#endif /* LOG_EXT_TSK_LEAVE */
+
+#ifndef LOG_TER_TSK_ENTER
+#define LOG_TER_TSK_ENTER(tskid)
+#endif /* LOG_TER_TSK_ENTER */
+
+#ifndef LOG_TER_TSK_LEAVE
+#define LOG_TER_TSK_LEAVE(ercd)
+#endif /* LOG_TER_TSK_LEAVE */
+
+#ifndef LOG_CHG_PRI_ENTER
+#define LOG_CHG_PRI_ENTER(tskid, tskpri)
+#endif /* LOG_CHG_PRI_ENTER */
+
+#ifndef LOG_CHG_PRI_LEAVE
+#define LOG_CHG_PRI_LEAVE(ercd)
+#endif /* LOG_CHG_PRI_LEAVE */
+
+#ifndef LOG_GET_PRI_ENTER
+#define LOG_GET_PRI_ENTER(tskid, p_tskpri)
+#endif /* LOG_GET_PRI_ENTER */
+
+#ifndef LOG_GET_PRI_LEAVE
+#define LOG_GET_PRI_LEAVE(ercd, tskpri)
+#endif /* LOG_GET_PRI_LEAVE */
+
+#ifndef LOG_GET_INF_ENTER
+#define LOG_GET_INF_ENTER(p_exinf)
+#endif /* LOG_GET_INF_ENTER */
+
+#ifndef LOG_GET_INF_LEAVE
+#define LOG_GET_INF_LEAVE(ercd, exinf)
+#endif /* LOG_GET_INF_LEAVE */
+
+/*
+ *  タスクの生成
+ */
+#ifdef TOPPERS_acre_tsk
+
+#ifndef TARGET_MIN_STKSZ
+#define TARGET_MIN_STKSZ	1U		/* 未定義の場合は0でないことをチェック */
+#endif /* TARGET_MIN_STKSZ */
+
+ER_UINT
+acre_tsk(const T_CTSK *pk_ctsk)
+{
+	TCB		*p_tcb;
+	TINIB	*p_tinib;
+	ATR		tskatr;
+	SIZE	stksz;
+	void	*stk;
+	ER		ercd;
+
+	LOG_ACRE_TSK_ENTER(pk_ctsk);
+	CHECK_TSKCTX_UNL();
+	CHECK_RSATR(pk_ctsk->tskatr, TA_ACT|TARGET_TSKATR);
+	CHECK_ALIGN_FUNC(pk_ctsk->task);
+	CHECK_NONNULL_FUNC(pk_ctsk->task);
+	CHECK_TPRI(pk_ctsk->itskpri);
+	CHECK_PAR(pk_ctsk->stksz >= TARGET_MIN_STKSZ);
+	if (pk_ctsk->stk != NULL) {
+		CHECK_ALIGN_STKSZ(pk_ctsk->stksz);
+		CHECK_ALIGN_STACK(pk_ctsk->stk);
+	}
+	tskatr = pk_ctsk->tskatr;
+	stksz = pk_ctsk->stksz;
+	stk = pk_ctsk->stk;
+
+	t_lock_cpu();
+	if (queue_empty(&free_tcb)) {
+		ercd = E_NOID;
+	}
+	else {
+		if (stk == NULL) {
+			stksz = ROUND_STK_T(stksz);
+			stk = kernel_malloc(stksz);
+			tskatr |= TA_MEMALLOC;
+		}
+		if (stk == NULL) {
+			ercd = E_NOMEM;
+		}
+		else {
+			p_tcb = ((TCB *) queue_delete_next(&free_tcb));
+			p_tinib = (TINIB *)(p_tcb->p_tinib);
+			p_tinib->tskatr = tskatr;
+			p_tinib->exinf = pk_ctsk->exinf;
+			p_tinib->task = pk_ctsk->task;
+			p_tinib->ipriority = INT_PRIORITY(pk_ctsk->itskpri);
+#ifdef USE_TSKINICTXB
+			init_tskinictxb(&(p_tinib->tskinictxb), stk, pk_ctsk);
+#else /* USE_TSKINICTXB */
+			p_tinib->stksz = stksz;
+			p_tinib->stk = stk;
+#endif /* USE_TSKINICTXB */
+			p_tinib->texatr = TA_NULL;
+			p_tinib->texrtn = NULL;
+
+			p_tcb->actque = false;
+			make_dormant(p_tcb);
+			if ((p_tcb->p_tinib->tskatr & TA_ACT) != 0U) {
+				if (make_active(p_tcb)) {
+					dispatch();
+				}
+			}
+			ercd = TSKID(p_tcb);
+		}
+	}
+	t_unlock_cpu();
+
+  error_exit:
+	LOG_ACRE_TSK_LEAVE(ercd);
+	return(ercd);
+}
+
+#endif /* TOPPERS_acre_tsk */
+
+/*
+ *  タスクの削除
+ */
+#ifdef TOPPERS_del_tsk
+
+ER
+del_tsk(ID tskid)
+{
+	TCB		*p_tcb;
+	TINIB	*p_tinib;
+	ER		ercd;
+
+	LOG_DEL_TSK_ENTER(tskid);
+	CHECK_TSKCTX_UNL();
+	CHECK_TSKID(tskid);
+	p_tcb = get_tcb(tskid);
+
+	t_lock_cpu();
+	if (p_tcb->p_tinib->tskatr == TA_NOEXS) {
+		ercd = E_NOEXS;
+	}
+	else if (TSKID(p_tcb) > tmax_stskid && TSTAT_DORMANT(p_tcb->tstat)) {
+		p_tinib = (TINIB *)(p_tcb->p_tinib);
+#ifdef USE_TSKINICTXB
+		term_tskinictxb(&(p_tinib->tskinictxb));
+#else /* USE_TSKINICTXB */
+		if ((p_tinib->tskatr & TA_MEMALLOC) != 0U) {
+			kernel_free(p_tinib->stk);
+		}
+#endif /* USE_TSKINICTXB */
+		p_tinib->tskatr = TA_NOEXS;
+		queue_insert_prev(&free_tcb, &(p_tcb->task_queue));
+		ercd = E_OK;
+	}
+	else {
+		ercd = E_OBJ;
+	}
+	t_unlock_cpu();
+
+  error_exit:
+	LOG_DEL_TSK_LEAVE(ercd);
+	return(ercd);
+}
+
+#endif /* TOPPERS_del_tsk */
+
+/*
+ *  タスクの起動
+ */
+#ifdef TOPPERS_act_tsk
+
+ER
+act_tsk(ID tskid)
+{
+	TCB		*p_tcb;
+	ER		ercd;
+
+	LOG_ACT_TSK_ENTER(tskid);
+	CHECK_TSKCTX_UNL();
+	CHECK_TSKID_SELF(tskid);
+	p_tcb = get_tcb_self(tskid);
+
+	t_lock_cpu();
+	if (p_tcb->p_tinib->tskatr == TA_NOEXS) {
+		ercd = E_NOEXS;
+	}
+	else if (TSTAT_DORMANT(p_tcb->tstat)) {
+		if (make_active(p_tcb)) {
+			dispatch();
+		}
+		ercd = E_OK;
+	}
+	else if (!(p_tcb->actque)) {
+		p_tcb->actque = true;
+		ercd = E_OK;
+	}
+	else {
+		ercd = E_QOVR;
+	}
+	t_unlock_cpu();
+
+  error_exit:
+	LOG_ACT_TSK_LEAVE(ercd);
+	return(ercd);
+}
+
+#endif /* TOPPERS_act_tsk */
+
+/*
+ *  タスクの起動（非タスクコンテキスト用）
+ */
+#ifdef TOPPERS_iact_tsk
+
+ER
+iact_tsk(ID tskid)
+{
+	TCB		*p_tcb;
+	ER		ercd;
+
+	LOG_IACT_TSK_ENTER(tskid);
+	CHECK_INTCTX_UNL();
+	CHECK_TSKID(tskid);
+	p_tcb = get_tcb(tskid);
+
+	i_lock_cpu();
+	if (p_tcb->p_tinib->tskatr == TA_NOEXS) {
+		ercd = E_NOEXS;
+	}
+	else if (TSTAT_DORMANT(p_tcb->tstat)) {
+		if (make_active(p_tcb)) {
+			reqflg = true;
+		}
+		ercd = E_OK;
+	}
+	else if (!(p_tcb->actque)) {
+		p_tcb->actque = true;
+		ercd = E_OK;
+	}
+	else {
+		ercd = E_QOVR;
+	}
+	i_unlock_cpu();
+
+  error_exit:
+	LOG_IACT_TSK_LEAVE(ercd);
+	return(ercd);
+}
+
+#endif /* TOPPERS_iact_tsk */
+
+/*
+ *  タスク起動要求のキャンセル
+ */
+#ifdef TOPPERS_can_act
+
+ER_UINT
+can_act(ID tskid)
+{
+	TCB		*p_tcb;
+	ER_UINT	ercd;
+
+	LOG_CAN_ACT_ENTER(tskid);
+	CHECK_TSKCTX_UNL();
+	CHECK_TSKID_SELF(tskid);
+	p_tcb = get_tcb_self(tskid);
+
+	t_lock_cpu();
+	if (p_tcb->p_tinib->tskatr == TA_NOEXS) {
+		ercd = E_NOEXS;
+	}
+	else {
+		ercd = p_tcb->actque ? 1 : 0;
+		p_tcb->actque = false;
+	}
+	t_unlock_cpu();
+
+  error_exit:
+	LOG_CAN_ACT_LEAVE(ercd);
+	return(ercd);
+}
+
+#endif /* TOPPERS_can_act */
+
+/*
+ *  自タスクの終了
+ */
+#ifdef TOPPERS_ext_tsk
+
+ER
+ext_tsk(void)
+{
+	ER		ercd;
+
+	LOG_EXT_TSK_ENTER();
+	CHECK_TSKCTX();
+
+	if (t_sense_lock()) {
+		/*
+		 *  CPUロック状態でext_tskが呼ばれた場合は，CPUロックを解除し
+		 *  てからタスクを終了する．実装上は，サービスコール内でのCPU
+		 *  ロックを省略すればよいだけ．
+		 */
+	}
+	else {
+		t_lock_cpu();
+	}
+	if (disdsp) {
+		/*
+		 *  ディスパッチ禁止状態でext_tskが呼ばれた場合は，ディスパッ
+		 *  チ許可状態にしてからタスクを終了する．
+		 */
+		disdsp = false;
+	}
+	if (!ipmflg) {
+		/*
+		 *  割込み優先度マスク（IPM）がTIPM_ENAALL以外の状態でext_tsk
+		 *  が呼ばれた場合は，IPMをTIPM_ENAALLにしてからタスクを終了す
+		 *  る．
+		 */
+		t_set_ipm(TIPM_ENAALL);
+		ipmflg = true;
+	}
+	dspflg = true;
+
+	(void) make_non_runnable(p_runtsk);
+	if (!queue_empty(&(p_runtsk->mutex_queue))) {
+		(void) (*mtxhook_release_all)(p_runtsk);
+	}
+	make_dormant(p_runtsk);
+	if (p_runtsk->actque) {
+		p_runtsk->actque = false;
+		(void) make_active(p_runtsk);
+	}
+	exit_and_dispatch();
+	ercd = E_SYS;
+
+  error_exit:
+	LOG_EXT_TSK_LEAVE(ercd);
+	return(ercd);
+}
+
+#endif /* TOPPERS_ext_tsk */
+
+/*
+ *  タスクの強制終了
+ */
+#ifdef TOPPERS_ter_tsk
+
+ER
+ter_tsk(ID tskid)
+{
+	TCB		*p_tcb;
+	bool_t	dspreq = false;
+	ER		ercd;
+
+	LOG_TER_TSK_ENTER(tskid);
+	CHECK_TSKCTX_UNL();
+	CHECK_TSKID(tskid);
+	p_tcb = get_tcb(tskid);
+	CHECK_NONSELF(p_tcb);
+
+	t_lock_cpu();
+	if (p_tcb->p_tinib->tskatr == TA_NOEXS) {
+		ercd = E_NOEXS;
+	}
+	else if (TSTAT_DORMANT(p_tcb->tstat)) {
+		ercd = E_OBJ;
+	}
+	else {
+		if (TSTAT_RUNNABLE(p_tcb->tstat)) {
+			/*
+			 *  p_tcbは自タスクでないため，（シングルプロセッサでは）実
+			 *  行状態でなく，make_non_runnable(p_tcb)でタスクディスパッ
+			 *  チが必要になることはない．
+			 */
+			(void) make_non_runnable(p_tcb);
+		}
+		else if (TSTAT_WAITING(p_tcb->tstat)) {
+			wait_dequeue_wobj(p_tcb);
+			wait_dequeue_tmevtb(p_tcb);
+		}
+		if (!queue_empty(&(p_tcb->mutex_queue))) {
+			if ((*mtxhook_release_all)(p_tcb)) {
+				dspreq = true;
+			}
+		}
+		make_dormant(p_tcb);
+		if (p_tcb->actque) {
+			p_tcb->actque = false;
+			if (make_active(p_tcb)) {
+				dspreq = true;
+			}
+		}
+		if (dspreq) {
+			dispatch();
+		}
+		ercd = E_OK;
+	}
+	t_unlock_cpu();
+
+  error_exit:
+	LOG_TER_TSK_LEAVE(ercd);
+	return(ercd);
+}
+
+#endif /* TOPPERS_ter_tsk */
+
+/*
+ *  タスクのベース優先度の変更
+ */
+#ifdef TOPPERS_chg_pri
+
+ER
+chg_pri(ID tskid, PRI tskpri)
+{
+	TCB		*p_tcb;
+	uint_t	newbpri;
+	ER		ercd;
+
+	LOG_CHG_PRI_ENTER(tskid, tskpri);
+	CHECK_TSKCTX_UNL();
+	CHECK_TSKID_SELF(tskid);
+	CHECK_TPRI_INI(tskpri);
+	p_tcb = get_tcb_self(tskid);
+
+	t_lock_cpu();
+	if (p_tcb->p_tinib->tskatr == TA_NOEXS) {
+		ercd = E_NOEXS;
+	}
+	else if (TSTAT_DORMANT(p_tcb->tstat)) {
+		ercd = E_OBJ;
+	}
+	else if ((!queue_empty(&(p_tcb->mutex_queue))
+										|| TSTAT_WAIT_MTX(p_tcb->tstat))
+						&& !((*mtxhook_check_ceilpri)(p_tcb, newbpri))) {
+		ercd = E_ILUSE;
+	}
+	else {
+		newbpri = (tskpri == TPRI_INI) ? p_tcb->p_tinib->ipriority
+											: INT_PRIORITY(tskpri);
+		p_tcb->bpriority = newbpri;
+		if (queue_empty(&(p_tcb->mutex_queue))
+								|| !((*mtxhook_scan_ceilmtx)(p_tcb))) {
+			if (change_priority(p_tcb, newbpri, false)) {
+				dispatch();
+			}
+		}
+		ercd = E_OK;
+	}
+	t_unlock_cpu();
+
+  error_exit:
+	LOG_CHG_PRI_LEAVE(ercd);
+	return(ercd);
+}
+
+#endif /* TOPPERS_chg_pri */
+
+/*
+ *  タスク優先度の参照
+ */
+#ifdef TOPPERS_get_pri
+
+ER
+get_pri(ID tskid, PRI *p_tskpri)
+{
+	TCB		*p_tcb;
+	ER		ercd;
+
+	LOG_GET_PRI_ENTER(tskid, p_tskpri);
+	CHECK_TSKCTX_UNL();
+	CHECK_TSKID_SELF(tskid);
+	p_tcb = get_tcb_self(tskid);
+
+	t_lock_cpu();
+	if (p_tcb->p_tinib->tskatr == TA_NOEXS) {
+		ercd = E_NOEXS;
+	}
+	else if (TSTAT_DORMANT(p_tcb->tstat)) {
+		ercd = E_OBJ;
+	}
+	else {
+		*p_tskpri = EXT_TSKPRI(p_tcb->priority);
+		ercd = E_OK;
+	}
+	t_unlock_cpu();
+
+  error_exit:
+	LOG_GET_PRI_LEAVE(ercd, *p_tskpri);
+	return(ercd);
+}
+
+#endif /* TOPPERS_get_pri */
+
+/*
+ *  自タスクの拡張情報の参照
+ */
+#ifdef TOPPERS_get_inf
+
+ER
+get_inf(intptr_t *p_exinf)
+{
+	ER		ercd;
+
+	LOG_GET_INF_ENTER(p_exinf);
+	CHECK_TSKCTX_UNL();
+
+	t_lock_cpu();
+	*p_exinf = p_runtsk->p_tinib->exinf;
+	ercd = E_OK;
+	t_unlock_cpu();
+
+  error_exit:
+	LOG_GET_INF_LEAVE(ercd, *p_exinf);
+	return(ercd);
+}
+
+#endif /* TOPPERS_get_inf */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/kernel/task_refer.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/kernel/task_refer.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/kernel/task_refer.c	(revision 457)
@@ -0,0 +1,215 @@
+/*
+ *  TOPPERS/ASP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Advanced Standard Profile Kernel
+ * 
+ *  Copyright (C) 2005-2014 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  $Id$
+ */
+
+/*
+ *		タスクの状態参照機能
+ */
+
+#include "kernel_impl.h"
+#include "check.h"
+#include "task.h"
+#include "wait.h"
+#include "semaphore.h"
+#include "eventflag.h"
+#include "dataqueue.h"
+#include "pridataq.h"
+#include "mailbox.h"
+#include "mutex.h"
+#include "mempfix.h"
+#include "time_event.h"
+
+/*
+ *  トレースログマクロのデフォルト定義
+ */
+#ifndef LOG_REF_TSK_ENTER
+#define LOG_REF_TSK_ENTER(tskid, pk_rtsk)
+#endif /* LOG_REF_TSK_ENTER */
+
+#ifndef LOG_REF_TSK_LEAVE
+#define LOG_REF_TSK_LEAVE(ercd, pk_rtsk)
+#endif /* LOG_REF_TSK_LEAVE */
+
+/*
+ *  タスクの状態参照
+ */
+#ifdef TOPPERS_ref_tsk
+
+ER
+ref_tsk(ID tskid, T_RTSK *pk_rtsk)
+{
+	TCB		*p_tcb;
+	uint_t	tstat;
+	ER		ercd;
+
+	LOG_REF_TSK_ENTER(tskid, pk_rtsk);
+	CHECK_TSKCTX_UNL();
+	CHECK_TSKID_SELF(tskid);
+	p_tcb = get_tcb_self(tskid);
+
+	t_lock_cpu();
+	if (p_tcb->p_tinib->tskatr == TA_NOEXS) {
+		ercd = E_NOEXS;
+	}
+	else {
+		tstat = p_tcb->tstat;
+		if (TSTAT_DORMANT(tstat)) {
+			/*
+	 		 *  対象タスクが休止状態の場合
+			 */
+			pk_rtsk->tskstat = TTS_DMT;
+		}
+		else {
+			/*
+	 		 *  タスク状態の取出し
+			 */
+			if (TSTAT_SUSPENDED(tstat)) {
+				if (TSTAT_WAITING(tstat)) {
+					pk_rtsk->tskstat = TTS_WAS;
+				}
+				else {
+					pk_rtsk->tskstat = TTS_SUS;
+				}
+			}
+			else if (TSTAT_WAITING(tstat)) {
+				pk_rtsk->tskstat = TTS_WAI;
+			}
+			else if (p_tcb == p_runtsk) {
+				pk_rtsk->tskstat = TTS_RUN;
+			}
+			else {
+				pk_rtsk->tskstat = TTS_RDY;
+			}
+
+			/*
+	 		 *  現在優先度とベース優先度の取出し
+			 */
+			pk_rtsk->tskpri = EXT_TSKPRI(p_tcb->priority);
+		pk_rtsk->tskbpri = EXT_TSKPRI(p_tcb->bpriority);
+
+			if (TSTAT_WAITING(tstat)) {
+				/*
+		 		 *  待ち要因と待ち対象のオブジェクトのIDの取出し
+				 */
+				switch (tstat & TS_WAIT_MASK) {
+				case TS_WAIT_SLP:
+					pk_rtsk->tskwait = TTW_SLP;
+					break;
+				case TS_WAIT_DLY:
+					pk_rtsk->tskwait = TTW_DLY;
+					break;
+				case TS_WAIT_SEM:
+					pk_rtsk->tskwait = TTW_SEM;
+					pk_rtsk->wobjid = SEMID(((WINFO_SEM *)(p_tcb->p_winfo))
+																->p_semcb);
+					break;
+				case TS_WAIT_FLG:
+					pk_rtsk->tskwait = TTW_FLG;
+					pk_rtsk->wobjid = FLGID(((WINFO_FLG *)(p_tcb->p_winfo))
+																->p_flgcb);
+					break;
+				case TS_WAIT_SDTQ:
+					pk_rtsk->tskwait = TTW_SDTQ;
+					pk_rtsk->wobjid = DTQID(((WINFO_DTQ *)(p_tcb->p_winfo))
+																->p_dtqcb);
+					break;
+				case TS_WAIT_RDTQ:
+					pk_rtsk->tskwait = TTW_RDTQ;
+					pk_rtsk->wobjid = DTQID(((WINFO_DTQ *)(p_tcb->p_winfo))
+																->p_dtqcb);
+					break;
+				case TS_WAIT_SPDQ:
+					pk_rtsk->tskwait = TTW_SPDQ;
+					pk_rtsk->wobjid = PDQID(((WINFO_PDQ *)(p_tcb->p_winfo))
+																->p_pdqcb);
+					break;
+				case TS_WAIT_RPDQ:
+					pk_rtsk->tskwait = TTW_RPDQ;
+					pk_rtsk->wobjid = PDQID(((WINFO_PDQ *)(p_tcb->p_winfo))
+																->p_pdqcb);
+					break;
+				case TS_WAIT_MBX:
+					pk_rtsk->tskwait = TTW_MBX;
+					pk_rtsk->wobjid = MBXID(((WINFO_MBX *)(p_tcb->p_winfo))
+																->p_mbxcb);
+					break;
+			case TS_WAIT_MTX:
+				pk_rtsk->tskwait = TTW_MTX;
+				pk_rtsk->wobjid = MTXID(((WINFO_MTX *)(p_tcb->p_winfo))
+																->p_mtxcb);
+				break;
+				case TS_WAIT_MPF:
+					pk_rtsk->tskwait = TTW_MPF;
+					pk_rtsk->wobjid = MPFID(((WINFO_MPF *)(p_tcb->p_winfo))
+																->p_mpfcb);
+					break;
+				}
+
+				/*
+		 		 *  タイムアウトするまでの時間の取出し
+				 */
+				if (p_tcb->p_winfo->p_tmevtb != NULL) {
+					pk_rtsk->lefttmo
+							= (TMO) tmevt_lefttim(p_tcb->p_winfo->p_tmevtb);
+				}
+				else {
+					pk_rtsk->lefttmo = TMO_FEVR;
+				}
+			}
+
+			/*
+	 		 *  起床要求キューイング数の取出し
+			 */
+			pk_rtsk->wupcnt = p_tcb->wupque ? 1U : 0U;
+		}
+
+		/*
+		 *  起動要求キューイング数の取出し
+		 */
+		pk_rtsk->actcnt = p_tcb->actque ? 1U : 0U;
+		ercd = E_OK;
+	}
+	t_unlock_cpu();
+
+  error_exit:
+	LOG_REF_TSK_LEAVE(ercd, pk_rtsk);
+	return(ercd);
+}
+
+#endif /* TOPPERS_ref_tsk */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/kernel/task_sync.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/kernel/task_sync.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/kernel/task_sync.c	(revision 457)
@@ -0,0 +1,552 @@
+/*
+ *  TOPPERS/ASP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Advanced Standard Profile Kernel
+ * 
+ *  Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
+ *                              Toyohashi Univ. of Technology, JAPAN
+ *  Copyright (C) 2005-2010 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *		タスク付属同期機能
+ */
+
+#include "kernel_impl.h"
+#include "check.h"
+#include "task.h"
+#include "wait.h"
+
+/*
+ *  トレースログマクロのデフォルト定義
+ */
+#ifndef LOG_SLP_TSK_ENTER
+#define LOG_SLP_TSK_ENTER()
+#endif /* LOG_SLP_TSK_ENTER */
+
+#ifndef LOG_SLP_TSK_LEAVE
+#define LOG_SLP_TSK_LEAVE(ercd)
+#endif /* LOG_SLP_TSK_LEAVE */
+
+#ifndef LOG_TSLP_TSK_ENTER
+#define LOG_TSLP_TSK_ENTER(tmout)
+#endif /* LOG_TSLP_TSK_ENTER */
+
+#ifndef LOG_TSLP_TSK_LEAVE
+#define LOG_TSLP_TSK_LEAVE(ercd)
+#endif /* LOG_TSLP_TSK_LEAVE */
+
+#ifndef LOG_WUP_TSK_ENTER
+#define LOG_WUP_TSK_ENTER(tskid)
+#endif /* LOG_WUP_TSK_ENTER */
+
+#ifndef LOG_WUP_TSK_LEAVE
+#define LOG_WUP_TSK_LEAVE(ercd)
+#endif /* LOG_WUP_TSK_LEAVE */
+
+#ifndef LOG_IWUP_TSK_ENTER
+#define LOG_IWUP_TSK_ENTER(tskid)
+#endif /* LOG_IWUP_TSK_ENTER */
+
+#ifndef LOG_IWUP_TSK_LEAVE
+#define LOG_IWUP_TSK_LEAVE(ercd)
+#endif /* LOG_IWUP_TSK_LEAVE */
+
+#ifndef LOG_CAN_WUP_ENTER
+#define LOG_CAN_WUP_ENTER(tskid)
+#endif /* LOG_CAN_WUP_ENTER */
+
+#ifndef LOG_CAN_WUP_LEAVE
+#define LOG_CAN_WUP_LEAVE(ercd)
+#endif /* LOG_CAN_WUP_LEAVE */
+
+#ifndef LOG_REL_WAI_ENTER
+#define LOG_REL_WAI_ENTER(tskid)
+#endif /* LOG_REL_WAI_ENTER */
+
+#ifndef LOG_REL_WAI_LEAVE
+#define LOG_REL_WAI_LEAVE(ercd)
+#endif /* LOG_REL_WAI_LEAVE */
+
+#ifndef LOG_IREL_WAI_ENTER
+#define LOG_IREL_WAI_ENTER(tskid)
+#endif /* LOG_IREL_WAI_ENTER */
+
+#ifndef LOG_IREL_WAI_LEAVE
+#define LOG_IREL_WAI_LEAVE(ercd)
+#endif /* LOG_IREL_WAI_LEAVE */
+
+#ifndef LOG_SUS_TSK_ENTER
+#define LOG_SUS_TSK_ENTER(tskid)
+#endif /* LOG_SUS_TSK_ENTER */
+
+#ifndef LOG_SUS_TSK_LEAVE
+#define LOG_SUS_TSK_LEAVE(ercd)
+#endif /* LOG_SUS_TSK_LEAVE */
+
+#ifndef LOG_RSM_TSK_ENTER
+#define LOG_RSM_TSK_ENTER(tskid)
+#endif /* LOG_RSM_TSK_ENTER */
+
+#ifndef LOG_RSM_TSK_LEAVE
+#define LOG_RSM_TSK_LEAVE(ercd)
+#endif /* LOG_RSM_TSK_LEAVE */
+
+#ifndef LOG_DLY_TSK_ENTER
+#define LOG_DLY_TSK_ENTER(dlytim)
+#endif /* LOG_DLY_TSK_ENTER */
+
+#ifndef LOG_DLY_TSK_LEAVE
+#define LOG_DLY_TSK_LEAVE(ercd)
+#endif /* LOG_DLY_TSK_LEAVE */
+
+/*
+ *  起床待ち
+ */
+#ifdef TOPPERS_slp_tsk
+
+ER
+slp_tsk(void)
+{
+	WINFO	winfo;
+	ER		ercd;
+
+	LOG_SLP_TSK_ENTER();
+	CHECK_DISPATCH();
+
+	t_lock_cpu();
+	if (p_runtsk->wupque) {
+		p_runtsk->wupque = false;
+		ercd = E_OK;
+	}
+	else {
+		p_runtsk->tstat = (TS_WAITING | TS_WAIT_SLP);
+		make_wait(&winfo);
+		LOG_TSKSTAT(p_runtsk);
+		dispatch();
+		ercd = winfo.wercd;
+	}
+	t_unlock_cpu();
+
+  error_exit:
+	LOG_SLP_TSK_LEAVE(ercd);
+	return(ercd);
+}
+
+#endif /* TOPPERS_slp_tsk */
+
+/*
+ *  起床待ち（タイムアウトあり）
+ */
+#ifdef TOPPERS_tslp_tsk
+
+ER
+tslp_tsk(TMO tmout)
+{
+	WINFO	winfo;
+	TMEVTB	tmevtb;
+	ER		ercd;
+
+	LOG_TSLP_TSK_ENTER(tmout);
+	CHECK_DISPATCH();
+	CHECK_TMOUT(tmout);
+
+	t_lock_cpu();
+	if (p_runtsk->wupque) {
+		p_runtsk->wupque = false;
+		ercd = E_OK;
+	}
+	else if (tmout == TMO_POL) {
+		ercd = E_TMOUT;
+	}
+	else {
+		p_runtsk->tstat = (TS_WAITING | TS_WAIT_SLP);
+		make_wait_tmout(&winfo, &tmevtb, tmout);
+		LOG_TSKSTAT(p_runtsk);
+		dispatch();
+		ercd = winfo.wercd;
+	}
+	t_unlock_cpu();
+
+  error_exit:
+	LOG_TSLP_TSK_LEAVE(ercd);
+	return(ercd);
+}
+
+#endif /* TOPPERS_tslp_tsk */
+
+/*
+ *  タスクの起床
+ */
+#ifdef TOPPERS_wup_tsk
+
+ER
+wup_tsk(ID tskid)
+{
+	TCB		*p_tcb;
+	ER		ercd;
+
+	LOG_WUP_TSK_ENTER(tskid);
+	CHECK_TSKCTX_UNL();
+	CHECK_TSKID_SELF(tskid);
+	p_tcb = get_tcb_self(tskid);
+
+	t_lock_cpu();
+	if (p_tcb->p_tinib->tskatr == TA_NOEXS) {
+		ercd = E_NOEXS;
+	}
+	else if (TSTAT_DORMANT(p_tcb->tstat)) {
+		ercd = E_OBJ;
+	}
+	else if (TSTAT_WAIT_SLP(p_tcb->tstat)) {
+		if (wait_complete(p_tcb)) {
+			dispatch();
+		}
+		ercd = E_OK;
+	}
+	else if (!(p_tcb->wupque)) {
+		p_tcb->wupque = true;
+		ercd = E_OK;
+	}
+	else {
+		ercd = E_QOVR;
+	}
+	t_unlock_cpu();
+
+  error_exit:
+	LOG_WUP_TSK_LEAVE(ercd);
+	return(ercd);
+}
+
+#endif /* TOPPERS_wup_tsk */
+
+/*
+ *  タスクの起床（非タスクコンテキスト用）
+ */
+#ifdef TOPPERS_iwup_tsk
+
+ER
+iwup_tsk(ID tskid)
+{
+	TCB		*p_tcb;
+	ER		ercd;
+
+	LOG_IWUP_TSK_ENTER(tskid);
+	CHECK_INTCTX_UNL();
+	CHECK_TSKID(tskid);
+	p_tcb = get_tcb(tskid);
+
+	i_lock_cpu();
+	if (p_tcb->p_tinib->tskatr == TA_NOEXS) {
+		ercd = E_NOEXS;
+	}
+	else if (TSTAT_DORMANT(p_tcb->tstat)) {
+		ercd = E_OBJ;
+	}
+	else if (TSTAT_WAIT_SLP(p_tcb->tstat)) {
+		if (wait_complete(p_tcb)) {
+			reqflg = true;
+		}
+		ercd = E_OK;
+	}
+	else if (!(p_tcb->wupque)) {
+		p_tcb->wupque = true;
+		ercd = E_OK;
+	}
+	else {
+		ercd = E_QOVR;
+	}
+	i_unlock_cpu();
+
+  error_exit:
+	LOG_IWUP_TSK_LEAVE(ercd);
+	return(ercd);
+}
+
+#endif /* TOPPERS_iwup_tsk */
+
+/*
+ *  タスク起床要求のキャンセル
+ */
+#ifdef TOPPERS_can_wup
+
+ER_UINT
+can_wup(ID tskid)
+{
+	TCB		*p_tcb;
+	ER_UINT	ercd;
+
+	LOG_CAN_WUP_ENTER(tskid);
+	CHECK_TSKCTX_UNL();
+	CHECK_TSKID_SELF(tskid);
+	p_tcb = get_tcb_self(tskid);
+
+	t_lock_cpu();
+	if (p_tcb->p_tinib->tskatr == TA_NOEXS) {
+		ercd = E_NOEXS;
+	}
+	else if (TSTAT_DORMANT(p_tcb->tstat)) {
+		ercd = E_OBJ;
+	}
+	else {
+		ercd = p_tcb->wupque ? 1 : 0;
+		p_tcb->wupque = false;
+	}
+	t_unlock_cpu();
+
+  error_exit:
+	LOG_CAN_WUP_LEAVE(ercd);
+	return(ercd);
+}
+
+#endif /* TOPPERS_can_wup */
+
+/*
+ *  待ち状態の強制解除
+ */
+#ifdef TOPPERS_rel_wai
+
+ER
+rel_wai(ID tskid)
+{
+	TCB		*p_tcb;
+	ER		ercd;
+
+	LOG_REL_WAI_ENTER(tskid);
+	CHECK_TSKCTX_UNL();
+	CHECK_TSKID(tskid);
+	p_tcb = get_tcb(tskid);
+
+	t_lock_cpu();
+	if (p_tcb->p_tinib->tskatr == TA_NOEXS) {
+		ercd = E_NOEXS;
+	}
+	else if (!TSTAT_WAITING(p_tcb->tstat)) {
+		ercd = E_OBJ;
+	}
+	else {
+		if (wait_release(p_tcb)) {
+			dispatch();
+		}
+		ercd = E_OK;
+	}
+	t_unlock_cpu();
+
+  error_exit:
+	LOG_REL_WAI_LEAVE(ercd);
+	return(ercd);
+}
+
+#endif /* TOPPERS_rel_wai */
+
+/*
+ *  待ち状態の強制解除（非タスクコンテキスト用）
+ */
+#ifdef TOPPERS_irel_wai
+
+ER
+irel_wai(ID tskid)
+{
+	TCB		*p_tcb;
+	ER		ercd;
+
+	LOG_IREL_WAI_ENTER(tskid);
+	CHECK_INTCTX_UNL();
+	CHECK_TSKID(tskid);
+	p_tcb = get_tcb(tskid);
+
+	i_lock_cpu();
+	if (p_tcb->p_tinib->tskatr == TA_NOEXS) {
+		ercd = E_NOEXS;
+	}
+	else if (!TSTAT_WAITING(p_tcb->tstat)) {
+		ercd = E_OBJ;
+	}
+	else {
+		if (wait_release(p_tcb)) {
+			reqflg = true;
+		}
+		ercd = E_OK;
+	}
+	i_unlock_cpu();
+
+  error_exit:
+	LOG_IREL_WAI_LEAVE(ercd);
+	return(ercd);
+}
+
+#endif /* TOPPERS_irel_wai */
+
+/*
+ *  強制待ち状態への移行
+ */
+#ifdef TOPPERS_sus_tsk
+
+ER
+sus_tsk(ID tskid)
+{
+	TCB		*p_tcb;
+	ER		ercd;
+
+	LOG_SUS_TSK_ENTER(tskid);
+	CHECK_TSKCTX_UNL();
+	CHECK_TSKID_SELF(tskid);
+	p_tcb = get_tcb_self(tskid);
+
+	t_lock_cpu();
+	if (p_tcb == p_runtsk && !dspflg) {
+		ercd = E_CTX;
+	}
+	else if (p_tcb->p_tinib->tskatr == TA_NOEXS) {
+		ercd = E_NOEXS;
+	}
+	else if (TSTAT_DORMANT(p_tcb->tstat)) {
+		ercd = E_OBJ;
+	}
+	else if (TSTAT_RUNNABLE(p_tcb->tstat)) {
+		/*
+		 *  実行できる状態から強制待ち状態への遷移
+		 */
+		p_tcb->tstat = TS_SUSPENDED;
+		LOG_TSKSTAT(p_tcb);
+		if (make_non_runnable(p_tcb)) {
+			dispatch();
+		}
+		ercd = E_OK;
+	}
+	else if (TSTAT_SUSPENDED(p_tcb->tstat)) {
+		ercd = E_QOVR;
+	}
+	else {
+		/*
+		 *  待ち状態から二重待ち状態への遷移
+		 */
+		p_tcb->tstat |= TS_SUSPENDED;
+		LOG_TSKSTAT(p_tcb);
+		ercd = E_OK;
+	}
+	t_unlock_cpu();
+
+  error_exit:
+	LOG_SUS_TSK_LEAVE(ercd);
+	return(ercd);
+}
+
+#endif /* TOPPERS_sus_tsk */
+
+/*
+ *  強制待ち状態からの再開
+ */
+#ifdef TOPPERS_rsm_tsk
+
+ER
+rsm_tsk(ID tskid)
+{
+	TCB		*p_tcb;
+	ER		ercd;
+
+	LOG_RSM_TSK_ENTER(tskid);
+	CHECK_TSKCTX_UNL();
+	CHECK_TSKID(tskid);
+	p_tcb = get_tcb(tskid);
+
+	t_lock_cpu();
+	if (p_tcb->p_tinib->tskatr == TA_NOEXS) {
+		ercd = E_NOEXS;
+	}
+	else if (!TSTAT_SUSPENDED(p_tcb->tstat)) {
+		ercd = E_OBJ;
+	}
+	else if (!TSTAT_WAITING(p_tcb->tstat)) {
+		/*
+		 *  強制待ち状態から実行できる状態への遷移
+		 */
+		p_tcb->tstat = TS_RUNNABLE;
+		LOG_TSKSTAT(p_tcb);
+		if (make_runnable(p_tcb)) {
+			dispatch();
+		}
+		ercd = E_OK;
+	}
+	else {
+		/*
+		 *  二重待ち状態から待ち状態への遷移
+		 */
+		p_tcb->tstat &= ~TS_SUSPENDED;
+		LOG_TSKSTAT(p_tcb);
+		ercd = E_OK;
+	}
+	t_unlock_cpu();
+
+  error_exit:
+	LOG_RSM_TSK_LEAVE(ercd);
+	return(ercd);
+}
+
+#endif /* TOPPERS_rsm_tsk */
+
+/*
+ *  自タスクの遅延
+ */
+#ifdef TOPPERS_dly_tsk
+
+ER
+dly_tsk(RELTIM dlytim)
+{
+	WINFO	winfo;
+	TMEVTB	tmevtb;
+	ER		ercd;
+
+	LOG_DLY_TSK_ENTER(dlytim);
+	CHECK_DISPATCH();
+	CHECK_PAR(dlytim <= TMAX_RELTIM);
+
+	t_lock_cpu();
+	p_runtsk->tstat = (TS_WAITING | TS_WAIT_DLY);
+	(void) make_non_runnable(p_runtsk);
+	p_runtsk->p_winfo = &winfo;
+	winfo.p_tmevtb = &tmevtb;
+	tmevtb_enqueue(&tmevtb, dlytim, (CBACK) wait_tmout_ok, (void *) p_runtsk);
+	LOG_TSKSTAT(p_runtsk);
+	dispatch();
+	ercd = winfo.wercd;
+	t_unlock_cpu();
+
+  error_exit:
+	LOG_DLY_TSK_LEAVE(ercd);
+	return(ercd);
+}
+
+#endif /* TOPPERS_dly_tsk */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/kernel/time_event.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/kernel/time_event.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/kernel/time_event.c	(revision 457)
@@ -0,0 +1,399 @@
+/*
+ *  TOPPERS/ASP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Advanced Standard Profile Kernel
+ * 
+ *  Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
+ *                              Toyohashi Univ. of Technology, JAPAN
+ *  Copyright (C) 2005-2013 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  $Id$
+ */
+
+/*
+ *		タイムイベント管理モジュール
+ */
+
+#include "kernel_impl.h"
+#include "time_event.h"
+
+/*
+ *  タイムイベントヒープ操作マクロ
+ */
+#define	PARENT(index)		((index) >> 1)		/* 親ノードを求める */
+#define	LCHILD(index)		((index) << 1)		/* 左の子ノードを求める */
+#define	TMEVT_NODE(index)	(tmevt_heap[(index) - 1])
+
+/*
+ *  イベント発生時刻比較マクロ
+ *
+ *  イベント発生時刻は，min_timeからの相対値で比較する．すなわち，
+ *  min_timeを最小値（最も近い時刻），mit_time-1が最大値（最も遠い時刻）
+ *  とみなして比較する．
+ */
+#define	EVTTIM_LT(t1, t2) (((t1) - min_time) < ((t2) - min_time))
+#define	EVTTIM_LE(t1, t2) (((t1) - min_time) <= ((t2) - min_time))
+
+#ifdef TOPPERS_tmeini
+
+/*
+ *  現在のシステム時刻（単位: 1ミリ秒）
+ *
+ *  厳密には，前のタイムティックのシステム時刻．
+ */
+EVTTIM	current_time;
+
+/*
+ *  タイムイベントヒープ中で有効な最小のシステム時刻（単位: 1ミリ秒）
+ */
+EVTTIM	min_time;
+
+/*
+ *  次のタイムティックのシステム時刻（単位: 1ミリ秒）
+ */
+EVTTIM	next_time;
+
+/*
+ *  システム時刻積算用変数（単位: 1/TIC_DENOミリ秒）
+ */
+#if TIC_DENO != 1U
+uint_t	next_subtime;
+#endif /* TIC_DENO != 1U */
+
+/*
+ *  タイムイベントヒープの最後の使用領域のインデックス
+ */
+uint_t	last_index;
+
+/*
+ *  タイマモジュールの初期化
+ */
+void
+initialize_tmevt(void)
+{
+	current_time = 0U;
+	min_time = 0U;
+	next_time = current_time + TIC_NUME / TIC_DENO;
+#if TIC_DENO != 1U
+	next_subtime = TIC_NUME % TIC_DENO;
+#endif /* TIC_DENO != 1U */
+	last_index = 0U;
+}
+
+#endif /* TOPPERS_tmeini */
+
+/*
+ *  タイムイベントの挿入位置を上向きに探索
+ *
+ *  時刻timeに発生するタイムイベントを挿入するノードを空けるために，
+ *  ヒープの上に向かって空ノードを移動させる．移動前の空ノードの位置を
+ *  indexに渡すと，移動後の空ノードの位置（すなわち挿入位置）を返す．
+ */
+#ifdef TOPPERS_tmeup
+
+uint_t
+tmevt_up(uint_t index, EVTTIM time)
+{
+	uint_t	parent;
+
+	while (index > 1) {
+		/*
+		 *  親ノードのイベント発生時刻の方が早い（または同じ）ならば，
+		 *  indexが挿入位置なのでループを抜ける．
+		 */
+		parent = PARENT(index);
+		if (EVTTIM_LE(TMEVT_NODE(parent).time, time)) {
+			break;
+		}
+
+		/*
+		 *  親ノードをindexの位置に移動させる．
+		 */
+		TMEVT_NODE(index) = TMEVT_NODE(parent);
+		TMEVT_NODE(index).p_tmevtb->index = index;
+
+		/*
+		 *  indexを親ノードの位置に更新．
+		 */
+		index = parent;
+	}
+	return(index);
+}
+
+#endif /* TOPPERS_tmeup */
+
+/*
+ *  タイムイベントの挿入位置を下向きに探索
+ *
+ *  時刻timeに発生するタイムイベントを挿入するノードを空けるために，
+ *  ヒープの下に向かって空ノードを移動させる．移動前の空ノードの位置を 
+ *  indexに渡すと，移動後の空ノードの位置（すなわち挿入位置）を返す．
+ */
+#ifdef TOPPERS_tmedown
+
+uint_t
+tmevt_down(uint_t index, EVTTIM time)
+{
+	uint_t	child;
+
+	while ((child = LCHILD(index)) <= last_index) {
+		/*
+		 *  左右の子ノードのイベント発生時刻を比較し，早い方の子ノード
+		 *  の位置をchildに設定する．以下の子ノードは，ここで選ばれた方
+		 *  の子ノードのこと．
+		 */
+		if (child + 1 <= last_index
+						&& EVTTIM_LT(TMEVT_NODE(child + 1).time,
+										TMEVT_NODE(child).time)) {
+			child = child + 1;
+		}
+
+		/*
+		 *  子ノードのイベント発生時刻の方が遅い（または同じ）ならば，
+		 *  indexが挿入位置なのでループを抜ける．
+		 */
+		if (EVTTIM_LE(time, TMEVT_NODE(child).time)) {
+			break;
+		}
+
+		/*
+		 *  子ノードをindexの位置に移動させる．
+		 */
+		TMEVT_NODE(index) = TMEVT_NODE(child);
+		TMEVT_NODE(index).p_tmevtb->index = index;
+
+		/*
+		 *  indexを子ノードの位置に更新．
+		 */
+		index = child;
+	}
+	return(index);
+}
+
+#endif /* TOPPERS_tmedown */
+
+/*
+ *  タイムイベントヒープへの登録
+ *
+ *  p_tmevtbで指定したタイムイベントブロックを，timeで指定した時間が経
+ *  過後にイベントが発生するように，タイムイベントヒープに登録する．
+ */
+#ifdef TOPPERS_tmeins
+
+void
+tmevtb_insert(TMEVTB *p_tmevtb, EVTTIM time)
+{
+	uint_t	index;
+
+	/*
+	 *  last_indexをインクリメントし，そこから上に挿入位置を探す．
+	 */
+	index = tmevt_up(++last_index, time);
+
+	/*
+	 *  タイムイベントをindexの位置に挿入する．
+	 */ 
+	TMEVT_NODE(index).time = time;
+	TMEVT_NODE(index).p_tmevtb = p_tmevtb;
+	p_tmevtb->index = index;
+}
+
+#endif /* TOPPERS_tmeins */
+
+/*
+ *  タイムイベントヒープからの削除
+ */
+#ifdef TOPPERS_tmedel
+
+void
+tmevtb_delete(TMEVTB *p_tmevtb)
+{
+	uint_t	index = p_tmevtb->index;
+	uint_t	parent;
+	EVTTIM	event_time = TMEVT_NODE(last_index).time;
+
+	/*
+	 *  削除によりタイムイベントヒープが空になる場合は何もしない．
+	 */
+	if (--last_index == 0) {
+		return;
+	}
+
+	/*
+	 *  削除したノードの位置に最後のノード（last_index+1の位置のノード）
+	 *  を挿入し，それを適切な位置へ移動させる．実際には，最後のノード
+	 *  を実際に挿入するのではなく，削除したノードの位置が空ノードにな
+	 *  るので，最後のノードを挿入すべき位置へ向けて空ノードを移動させ
+	 *  る．
+	 *  最後のノードのイベント発生時刻が，削除したノードの親ノードのイ
+	 *  ベント発生時刻より前の場合には，上に向かって挿入位置を探す．そ
+	 *  うでない場合には，下に向かって探す．
+	 */
+	if (index > 1 && EVTTIM_LT(event_time,
+								TMEVT_NODE(parent = PARENT(index)).time)) {
+		/*
+		 *  親ノードをindexの位置に移動させる．
+		 */
+		TMEVT_NODE(index) = TMEVT_NODE(parent);
+		TMEVT_NODE(index).p_tmevtb->index = index;
+
+		/*
+		 *  削除したノードの親ノードから上に向かって挿入位置を探す．
+		 */
+		index = tmevt_up(parent, event_time);
+	}
+	else {
+		/*
+		 *  削除したノードから下に向かって挿入位置を探す．
+		 */
+		index = tmevt_down(index, event_time);
+	}
+
+	/*
+	 *  最後のノードをindexの位置に挿入する．
+	 */ 
+	TMEVT_NODE(index) = TMEVT_NODE(last_index + 1);
+	TMEVT_NODE(index).p_tmevtb->index = index;
+}
+
+#endif /* TOPPERS_tmedel */
+
+/*
+ *  タイムイベントヒープの先頭のノードの削除
+ */
+Inline void
+tmevtb_delete_top(void)
+{
+	uint_t	index;
+	EVTTIM	event_time = TMEVT_NODE(last_index).time;
+
+	/*
+	 *  削除によりタイムイベントヒープが空になる場合は何もしない．
+	 */
+	if (--last_index == 0) {
+		return;
+	}
+
+	/*
+	 *  ルートノードに最後のノード（last_index + 1 の位置のノード）を
+	 *  挿入し，それを適切な位置へ移動させる．実際には，最後のノードを
+	 *  実際に挿入するのではなく，ルートノードが空ノードになるので，最
+	 *  後のノードを挿入すべき位置へ向けて空ノードを移動させる．
+	 */
+	index = tmevt_down(1, event_time);
+
+	/*
+	 *  最後のノードをindexの位置に挿入する．
+	 */ 
+	TMEVT_NODE(index) = TMEVT_NODE(last_index + 1);
+	TMEVT_NODE(index).p_tmevtb->index = index;
+}
+
+/*
+ *  タイムイベントまでの残り時間の計算
+ */
+#ifdef TOPPERS_tmeltim
+
+RELTIM
+tmevt_lefttim(TMEVTB *p_tmevtb)
+{
+	EVTTIM	time;
+
+	time = TMEVT_NODE(p_tmevtb->index).time;
+	if (EVTTIM_LE(time, next_time)) {
+		/*
+		 *  次のタイムティックで処理される場合には0を返す．
+		 */
+		return(0U);
+	}
+	else {
+		return((RELTIM)(time - base_time));
+	}
+}
+
+#endif /* TOPPERS_tmeltim */
+
+/*
+ *  タイムティックの供給
+ */
+#ifdef TOPPERS_sigtim
+
+void
+signal_time(void)
+{
+	TMEVTB	*p_tmevtb;
+
+	assert(sense_context());
+	assert(!i_sense_lock());
+
+	i_lock_cpu();
+
+	/*
+	 *  current_timeを更新する．
+	 */
+	current_time = next_time;
+
+	/*
+	 *  next_time，next_subtimeを更新する．
+	 */
+#if TIC_DENO == 1U
+	next_time = current_time + TIC_NUME;
+#else /* TIC_DENO == 1U */
+	next_subtime += TIC_NUME % TIC_DENO;
+	next_time = current_time + TIC_NUME / TIC_DENO;
+	if (next_subtime >= TIC_DENO) {
+		next_subtime -= TIC_DENO;
+		next_time += 1U;
+	}
+#endif /* TIC_DENO == 1U */
+
+	/*
+	 *  current_timeよりイベント発生時刻の早い（または同じ）タイムイベ
+	 *  ントを，タイムイベントヒープから削除し，コールバック関数を呼び
+	 *  出す．
+	 */
+	while (last_index > 0 && EVTTIM_LE(TMEVT_NODE(1).time, current_time)) {
+		p_tmevtb = TMEVT_NODE(1).p_tmevtb;
+		tmevtb_delete_top();
+		(*(p_tmevtb->callback))(p_tmevtb->arg);
+	}
+
+	/*
+	 *  min_timeを更新する．
+	 */
+	min_time = current_time;
+
+	i_unlock_cpu();
+}
+
+#endif /* TOPPERS_sigtim */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/kernel/time_event.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/kernel/time_event.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/kernel/time_event.h	(revision 457)
@@ -0,0 +1,200 @@
+/*
+ *  TOPPERS/ASP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Advanced Standard Profile Kernel
+ * 
+ *  Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
+ *                              Toyohashi Univ. of Technology, JAPAN
+ *  Copyright (C) 2005-2010 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  $Id$
+ */
+
+/*
+ *		タイムイベント管理モジュール
+ */
+
+#ifndef TOPPERS_TIME_EVENT_H
+#define TOPPERS_TIME_EVENT_H
+
+/*
+ *  イベント発生時刻のデータ型の定義
+ *
+ *  EVTTIMは，RELTIMとして指定できる範囲よりも広い範囲を表現できる必要
+ *  がある．μITRON4.0仕様のスタンダードプロファイルでは，RELTIMが16ビッ
+ *  ト以上でなければならないため，EVTTIMは17ビット以上であることが必要
+ *  である．そのため，16ビットになる場合があるuint_tではなく，ulong_tに
+ *  定義している．
+ */
+typedef ulong_t	EVTTIM;
+
+/* 
+ *  タイムイベントブロックのデータ型の定義
+ */
+typedef void	(*CBACK)(void *);	/* コールバック関数の型 */
+
+typedef struct time_event_block {
+	uint_t	index;			/* タイムイベントヒープ中での位置 */
+	CBACK	callback;		/* コールバック関数 */
+	void	*arg;			/* コールバック関数へ渡す引数 */
+} TMEVTB;
+
+/*
+ *  タイムイベントヒープ中のノードのデータ型の定義
+ */
+typedef struct time_event_node {
+	EVTTIM	time;			/* イベント発生時刻 */
+	TMEVTB	*p_tmevtb;		/* 対応するタイムイベントブロック */
+} TMEVTN;
+
+/*
+ *  タイムイベントヒープ（kernel_cfg.c）
+ */
+extern TMEVTN	tmevt_heap[];
+
+/*
+ *  現在のシステム時刻（単位: 1ミリ秒）
+ *
+ *  システム起動時に0に初期化され，以降，タイムティックが供給される度に
+ *  単調に増加する．
+ */
+extern EVTTIM	current_time;
+
+/*
+ *  タイムイベントヒープ中で有効な最小のシステム時刻（単位: 1ミリ秒）
+ */
+extern EVTTIM	min_time;
+
+/*
+ *  次のタイムティックのシステム時刻（単位: 1ミリ秒）
+ */
+extern EVTTIM	next_time;
+
+/*
+ *  システム時刻積算用変数（単位: 1/TIC_DENOミリ秒）
+ *
+ *  次のタイムティックのシステム時刻の下位桁を示す（上位桁はnext_time）．
+ *  TIC_DENOが1の時は，下位桁は常に0であるため，この変数は必要ない．
+ */
+#if TIC_DENO != 1U
+extern uint_t	next_subtime;
+#endif /* TIC_DENO != 1U */
+
+/*
+ *  相対時間の基準時刻（単位: 1ミリ秒）
+ *
+ *  次のタイムティックのシステム時刻を切り上げた時刻．TIC_DENOが1の時
+ *  は，next_timeに一致する．
+ */
+#if TIC_DENO == 1U
+#define	base_time	(next_time)
+#else /* TIC_DENO == 1U */
+#define	base_time	(next_time + (next_subtime > 0U ? 1U : 0U))
+#endif /* TIC_DENO == 1U */
+
+/*
+ *  タイムイベントヒープの最後の使用領域のインデックス
+ *
+ *  タイムイベントヒープに登録されているタイムイベントの数に一致する．
+ */
+extern uint_t	last_index;
+
+/*
+ *  タイムイベント管理モジュールの初期化
+ */
+extern void	initialize_tmevt(void);
+
+/*
+ *  タイムイベントの挿入位置の探索
+ */
+extern uint_t	tmevt_up(uint_t index, EVTTIM time);
+extern uint_t	tmevt_down(uint_t index, EVTTIM time);
+
+/*
+ *  タイムイベントヒープへの登録と削除
+ */
+extern void	tmevtb_insert(TMEVTB *p_tmevtb, EVTTIM time);
+extern void	tmevtb_delete(TMEVTB *p_tmevtb);
+
+/*
+ *  タイムイベントブロックの登録（相対時間指定）
+ *
+ *  timeで指定した相対時間が経過した後に，argを引数としてcallbackが呼
+ *  び出されるように，p_tmevtbで指定したタイムイベントブロックを登録す
+ *  る．
+ *  
+ */
+Inline void
+tmevtb_enqueue(TMEVTB *p_tmevtb, RELTIM time, CBACK callback, void *arg)
+{
+	assert(time <= TMAX_RELTIM);
+
+	p_tmevtb->callback = callback;
+	p_tmevtb->arg = arg;
+	tmevtb_insert(p_tmevtb, base_time + time);
+}
+
+/*
+ *  タイムイベントブロックの登録（イベント発生時刻指定）
+ *
+ *  timeで指定したイベント発生時刻に，argを引数としてcallbackが呼び出
+ *  されるように，p_tmevtbで指定したタイムイベントブロックを登録する．
+ */
+Inline void
+tmevtb_enqueue_evttim(TMEVTB *p_tmevtb, EVTTIM time, CBACK callback, void *arg)
+{
+	p_tmevtb->callback = callback;
+	p_tmevtb->arg = arg;
+	tmevtb_insert(p_tmevtb, time);
+}
+
+/*
+ *  タイムイベントブロックの登録解除
+ */
+Inline void
+tmevtb_dequeue(TMEVTB *p_tmevtb)
+{
+	tmevtb_delete(p_tmevtb);
+}
+
+/*
+ *  タイムイベントまでの残り時間の計算
+ */
+extern RELTIM	tmevt_lefttim(TMEVTB *p_tmevtb);
+
+/*
+ *  タイムティックの供給
+ */
+extern void	signal_time(void);
+
+#endif /* TOPPERS_TIME_EVENT_H */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/kernel/time_manage.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/kernel/time_manage.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/kernel/time_manage.c	(revision 457)
@@ -0,0 +1,144 @@
+/*
+ *  TOPPERS/ASP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Advanced Standard Profile Kernel
+ * 
+ *  Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
+ *                              Toyohashi Univ. of Technology, JAPAN
+ *  Copyright (C) 2005-2010 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  $Id$
+ */
+
+/*
+ *		システム時刻管理機能
+ */
+
+#include "kernel_impl.h"
+#include "check.h"
+#include "time_event.h"
+
+/*
+ *  トレースログマクロのデフォルト定義
+ */
+#ifndef LOG_GET_TIM_ENTER
+#define LOG_GET_TIM_ENTER(p_systim)
+#endif /* LOG_GET_TIM_ENTER */
+
+#ifndef LOG_GET_TIM_LEAVE
+#define LOG_GET_TIM_LEAVE(ercd, systim)
+#endif /* LOG_GET_TIM_LEAVE */
+
+#ifndef LOG_GET_UTM_ENTER
+#define LOG_GET_UTM_ENTER(p_sysutm)
+#endif /* LOG_GET_UTM_ENTER */
+
+#ifndef LOG_GET_UTM_LEAVE
+#define LOG_GET_UTM_LEAVE(ercd, sysutm)
+#endif /* LOG_GET_UTM_LEAVE */
+
+/*
+ *  システム時刻の参照
+ */
+#ifdef TOPPERS_get_tim
+
+ER
+get_tim(SYSTIM *p_systim)
+{
+	ER		ercd;
+
+	LOG_GET_TIM_ENTER(p_systim);
+	CHECK_TSKCTX_UNL();
+
+	t_lock_cpu();
+	*p_systim = current_time;
+	ercd = E_OK;
+	t_unlock_cpu();
+
+  error_exit:
+	LOG_GET_TIM_LEAVE(ercd, *p_systim);
+	return(ercd);
+}
+
+#endif /* TOPPERS_get_tim */
+
+/*
+ *  性能評価用システム時刻の参照
+ */
+#ifdef TOPPERS_get_utm
+#ifdef TOPPERS_SUPPORT_GET_UTM
+#ifndef OMIT_GET_UTM
+#include "target_timer.h"
+
+ER
+get_utm(SYSUTM *p_sysutm)
+{
+	SYSUTM	utime;
+	SYSTIM	time;
+#if TIC_DENO != 1
+	uint_t	subtime;
+#endif /* TIC_DENO != 1 */
+	CLOCK	clock1, clock2;
+	bool_t	ireq;
+	SIL_PRE_LOC;
+
+	LOG_GET_UTM_ENTER(p_sysutm);
+
+	SIL_LOC_INT();
+	time = next_time;
+#if TIC_DENO != 1
+	subtime = next_subtime;
+#endif /* TIC_DENO != 1 */
+	clock1 = target_timer_get_current();
+	ireq = target_timer_probe_int();
+	clock2 = target_timer_get_current();
+	SIL_UNL_INT();
+
+	utime = ((SYSUTM) time) * 1000U;
+#if TIC_DENO != 1
+	utime += subtime * 1000U / TIC_DENO;
+#endif /* TIC_DENO != 1 */
+
+	if (!ireq || clock1 > clock2) {
+		utime -= TIC_NUME * 1000U / TIC_DENO;
+	}
+	utime += TO_USEC(clock1);
+	*p_sysutm = utime;
+
+	LOG_GET_UTM_LEAVE(E_OK, *p_sysutm);
+	return(E_OK);
+}
+
+#endif /* OMIT_GET_UTM */
+#endif /* TOPPERS_SUPPORT_GET_UTM */
+#endif /* TOPPERS_get_utm */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/kernel/wait.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/kernel/wait.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/kernel/wait.c	(revision 457)
@@ -0,0 +1,213 @@
+/*
+ *  TOPPERS/ASP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Advanced Standard Profile Kernel
+ * 
+ *  Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
+ *                              Toyohashi Univ. of Technology, JAPAN
+ *  Copyright (C) 2005-2010 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *		待ち状態管理モジュール
+ */
+
+#include "kernel_impl.h"
+#include "wait.h"
+
+/*
+ *  待ち状態への遷移（タイムアウト指定）
+ */
+#ifdef TOPPERS_waimake
+
+void
+make_wait_tmout(WINFO *p_winfo, TMEVTB *p_tmevtb, TMO tmout)
+{
+	(void) make_non_runnable(p_runtsk);
+	p_runtsk->p_winfo = p_winfo;
+	if (tmout > 0) {
+		p_winfo->p_tmevtb = p_tmevtb;
+		tmevtb_enqueue(p_tmevtb, (RELTIM) tmout,
+						(CBACK) wait_tmout, (void *) p_runtsk);
+	}
+	else {
+		assert(tmout == TMO_FEVR);
+		p_winfo->p_tmevtb = NULL;
+	}
+}
+
+#endif /* TOPPERS_waimake */
+
+/*
+ *  待ち解除
+ */
+#ifdef TOPPERS_waicmp
+
+bool_t
+wait_complete(TCB *p_tcb)
+{
+	wait_dequeue_tmevtb(p_tcb);
+	p_tcb->p_winfo->wercd = E_OK;
+	return(make_non_wait(p_tcb));
+}
+
+#endif /* TOPPERS_waicmp */
+
+/*
+ *  タイムアウトに伴う待ち解除
+ */
+#ifdef TOPPERS_waitmo
+
+void
+wait_tmout(TCB *p_tcb)
+{
+	wait_dequeue_wobj(p_tcb);
+	p_tcb->p_winfo->wercd = E_TMOUT;
+	if (make_non_wait(p_tcb)) {
+		reqflg = true;
+	}
+
+	/*
+	 *  ここで優先度の高い割込みを受け付ける．
+	 */
+	i_unlock_cpu();
+	i_lock_cpu();
+}
+
+#endif /* TOPPERS_waitmo */
+#ifdef TOPPERS_waitmook
+
+void
+wait_tmout_ok(TCB *p_tcb)
+{
+	p_tcb->p_winfo->wercd = E_OK;
+	if (make_non_wait(p_tcb)) {
+		reqflg = true;
+	}
+
+	/*
+	 *  ここで優先度の高い割込みを受け付ける．
+	 */
+	i_unlock_cpu();
+	i_lock_cpu();
+}
+
+#endif /* TOPPERS_waitmook */
+
+/*
+ *  待ち状態の強制解除
+ */
+#ifdef TOPPERS_wairel
+
+bool_t
+wait_release(TCB *p_tcb)
+{
+	wait_dequeue_wobj(p_tcb);
+	wait_dequeue_tmevtb(p_tcb);
+	p_tcb->p_winfo->wercd = E_RLWAI;
+	return(make_non_wait(p_tcb));
+}
+
+#endif /* TOPPERS_wairel */
+
+/*
+ *  実行中のタスクの同期・通信オブジェクトの待ちキューへの挿入
+ *
+ *  実行中のタスクを，同期・通信オブジェクトの待ちキューへ挿入する．オ
+ *  ブジェクトの属性に応じて，FIFO順またはタスク優先度順で挿入する．
+ */
+Inline void
+wobj_queue_insert(WOBJCB *p_wobjcb)
+{
+	if ((p_wobjcb->p_wobjinib->wobjatr & TA_TPRI) != 0U) {
+		queue_insert_tpri(&(p_wobjcb->wait_queue), p_runtsk);
+	}
+	else {
+		queue_insert_prev(&(p_wobjcb->wait_queue), &(p_runtsk->task_queue));
+	}
+}
+
+/*
+ *  同期・通信オブジェクトに対する待ち状態への遷移
+ */
+#ifdef TOPPERS_wobjwai
+
+void
+wobj_make_wait(WOBJCB *p_wobjcb, WINFO_WOBJ *p_winfo_wobj)
+{
+	make_wait(&(p_winfo_wobj->winfo));
+	wobj_queue_insert(p_wobjcb);
+	p_winfo_wobj->p_wobjcb = p_wobjcb;
+	LOG_TSKSTAT(p_runtsk);
+}
+
+#endif /* TOPPERS_wobjwai */
+#ifdef TOPPERS_wobjwaitmo
+
+void
+wobj_make_wait_tmout(WOBJCB *p_wobjcb, WINFO_WOBJ *p_winfo_wobj,
+								TMEVTB *p_tmevtb, TMO tmout)
+{
+	make_wait_tmout(&(p_winfo_wobj->winfo), p_tmevtb, tmout);
+	wobj_queue_insert(p_wobjcb);
+	p_winfo_wobj->p_wobjcb = p_wobjcb;
+	LOG_TSKSTAT(p_runtsk);
+}
+
+#endif /* TOPPERS_wobjwaitmo */
+
+/*
+ *  待ちキューの初期化
+ */
+#ifdef TOPPERS_iniwque
+
+bool_t
+init_wait_queue(QUEUE *p_wait_queue)
+{
+	TCB		*p_tcb;
+	bool_t	dspreq = false;
+
+	while (!queue_empty(p_wait_queue)) {
+		p_tcb = (TCB *) queue_delete_next(p_wait_queue);
+		wait_dequeue_tmevtb(p_tcb);
+		p_tcb->p_winfo->wercd = E_DLT;
+		if (make_non_wait(p_tcb)) {
+			dspreq = true;
+		}
+	}
+	return(dspreq);
+}
+
+#endif /* TOPPERS_iniwque */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/kernel/wait.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/kernel/wait.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/kernel/wait.h	(revision 457)
@@ -0,0 +1,288 @@
+/*
+ *  TOPPERS/ASP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Advanced Standard Profile Kernel
+ * 
+ *  Copyright (C) 2000 by Embedded and Real-Time Systems Laboratory
+ *                              Toyohashi Univ. of Technology, JAPAN
+ *  Copyright (C) 2005-2011 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *		待ち状態管理モジュール
+ */
+
+#ifndef TOPPERS_WAIT_H
+#define TOPPERS_WAIT_H
+
+#include "task.h"
+#include "time_event.h"
+
+/*
+ *  タスクの優先度順の待ちキューへの挿入
+ *
+ *  p_tcbで指定されるタスクを，タスク優先度順のキューp_queueに挿入する．
+ *  キューの中に同じ優先度のタスクがある場合には，その最後に挿入する．
+ */
+Inline void
+queue_insert_tpri(QUEUE *p_queue, TCB *p_tcb)
+{
+	QUEUE	*p_entry;
+	uint_t	pri = p_tcb->priority;
+
+	for (p_entry = p_queue->p_next; p_entry != p_queue;
+										p_entry = p_entry->p_next) {
+		if (pri < ((TCB *) p_entry)->priority) {
+			break;
+		}
+	}
+	queue_insert_prev(p_entry, &(p_tcb->task_queue));
+}
+
+/*
+ *  待ち状態への遷移
+ *
+ *  実行中のタスクを待ち状態に遷移させる．具体的には，実行中のタスクを
+ *  レディキューから削除し，TCBのp_winfoフィールド，WINFOのp_tmevtbフィー
+ *  ルドを設定する．
+ */
+Inline void
+make_wait(WINFO *p_winfo)
+{
+	(void) make_non_runnable(p_runtsk);
+	p_runtsk->p_winfo = p_winfo;
+	p_winfo->p_tmevtb = NULL;
+}
+
+/*
+ *  待ち状態への遷移（タイムアウト指定）
+ *
+ *  実行中のタスクを，タイムアウト指定付きで待ち状態に遷移させる．具体
+ *  的には，実行中のタスクをレディキューから削除し，TCBのp_winfoフィー
+ *  ルド，WINFOのp_tmevtbフィールドを設定する．また，タイムイベントブ
+ *  ロックを登録する．
+ */
+extern void	make_wait_tmout(WINFO *p_winfo, TMEVTB *p_tmevtb, TMO tmout);
+
+/*
+ *  待ち解除のためのタスク状態の更新
+ *
+ *  p_tcbで指定されるタスクを，待ち解除するようタスク状態を更新する．
+ *  待ち解除するタスクが実行できる状態になる場合は，レディキューにつな
+ *  ぐ．また，ディスパッチが必要な場合にはtrueを返す．
+ */
+Inline bool_t
+make_non_wait(TCB *p_tcb)
+{
+	assert(TSTAT_WAITING(p_tcb->tstat));
+
+	if (!TSTAT_SUSPENDED(p_tcb->tstat)) {
+		/*
+		 *  待ち状態から実行できる状態への遷移
+		 */
+		p_tcb->tstat = TS_RUNNABLE;
+		LOG_TSKSTAT(p_tcb);
+		return(make_runnable(p_tcb));
+	}
+	else {
+		/*
+		 *  二重待ち状態から強制待ち状態への遷移
+		 */
+		p_tcb->tstat = TS_SUSPENDED;
+		LOG_TSKSTAT(p_tcb);
+		return(false);
+	}
+}
+
+/*
+ *  オブジェクト待ちキューからの削除
+ *
+ *  p_tcbで指定されるタスクが，同期・通信オブジェクトの待ちキューにつ
+ *  ながれていれば，待ちキューから削除する．
+ */
+Inline void
+wait_dequeue_wobj(TCB *p_tcb)
+{
+	if (TSTAT_WAIT_WOBJ(p_tcb->tstat)) {
+		queue_delete(&(p_tcb->task_queue));
+	}
+}
+
+/*
+ *  時間待ちのためのタイムイベントブロックの登録解除
+ *
+ *  p_tcbで指定されるタスクに対して，時間待ちのためのタイムイベントブ
+ *  ロックが登録されていれば，それを登録解除する．
+ */
+Inline void
+wait_dequeue_tmevtb(TCB *p_tcb)
+{
+	if (p_tcb->p_winfo->p_tmevtb != NULL) {
+		tmevtb_dequeue(p_tcb->p_winfo->p_tmevtb);
+	}
+}
+
+/*
+ *  待ち解除
+ *
+ *  p_tcbで指定されるタスクの待ち状態を解除する．具体的には，タイムイ
+ *  ベントブロックが登録されていれば，それを登録解除する．また，タスク
+ *  状態を更新し，待ち解除したタスクからの返値をE_OKとする．待ちキュー
+ *  からの削除は行わない．待ち解除したタスクへのディスパッチが必要な場
+ *  合にはtrueを返す．
+ */
+extern bool_t	wait_complete(TCB *p_tcb);
+
+/*
+ *  タイムアウトに伴う待ち解除
+ *
+ *  p_tcbで指定されるタスクが，待ちキューにつながれていれば待ちキュー
+ *  から削除し，タスク状態を更新する．また，待ち解除したタスクからの返
+ *  値を，wait_tmoutではE_TMOUT，wait_tmout_okではE_OKとする．待ち解除
+ *  したタスクへのディスパッチが必要な時は，reqflgをtrueにする．
+ *
+ *  wait_tmout_okは，dly_tskで使うためのもので，待ちキューから削除する
+ *  処理を行わない．
+ *
+ *  いずれの関数も，タイムイベントのコールバック関数として用いるための
+ *  もので，割込みハンドラから呼び出されることを想定している．
+ */
+extern void	wait_tmout(TCB *p_tcb);
+extern void	wait_tmout_ok(TCB *p_tcb);
+
+/*
+ *  待ち状態の強制解除
+ *
+ *  p_tcbで指定されるタスクの待ち状態を強制的に解除する．具体的には，
+ *  タスクが待ちキューにつながれていれば待ちキューから削除し，タイムイ
+ *  ベントブロックが登録されていればそれを登録解除する．また，タスクの
+ *  状態を更新し，待ち解除したタスクからの返値をE_RLWAIとする．また，
+ *  待ち解除したタスクへのディスパッチが必要な場合にはtrueを返す．
+ */
+extern bool_t	wait_release(TCB *p_tcb);
+
+/*
+ *  待ちキューの先頭のタスクID
+ *
+ *  p_wait_queueで指定した待ちキューの先頭のタスクIDを返す．待ちキュー
+ *  が空の場合には，TSK_NONEを返す．
+ */
+Inline ID
+wait_tskid(QUEUE *p_wait_queue)
+{
+	if (!queue_empty(p_wait_queue)) {
+		return(TSKID((TCB *) p_wait_queue->p_next));
+	}
+	else {
+		return(TSK_NONE);
+	}
+}
+
+/*
+ *  同期・通信オブジェクトの管理ブロックの共通部分操作ルーチン
+ *
+ *  同期・通信オブジェクトの初期化ブロックと管理ブロックの先頭部分は共
+ *  通になっている．以下は，その共通部分を扱うための型およびルーチン群
+ *  である．
+ *
+ *  複数の待ちキューを持つ同期・通信オブジェクトの場合，先頭以外の待ち
+ *  キューを操作する場合には，これらのルーチンは使えない．また，オブジェ
+ *  クト属性のTA_TPRIビットを参照するので，このビットを他の目的に使って
+ *  いる場合も，これらのルーチンは使えない．
+ */
+
+/*
+ *  同期・通信オブジェクトの初期化ブロックの共通部分
+ */
+typedef struct wait_object_initialization_block {
+	ATR			wobjatr;		/* オブジェクト属性 */
+} WOBJINIB;
+
+/*
+ *  同期・通信オブジェクトの管理ブロックの共通部分
+ */
+typedef struct wait_object_control_block {
+	QUEUE		wait_queue;		/* 待ちキュー */
+	const WOBJINIB *p_wobjinib;	/* 初期化ブロックへのポインタ */
+} WOBJCB;
+
+/*
+ *  同期・通信オブジェクトの待ち情報ブロックの共通部分
+ *
+ *  この構造体は，待ち情報ブロック（WINFO）を拡張（オブジェクト指向言
+ *  語の継承に相当）したものであるが，WINFOが共用体で定義されているた
+ *  めに，1つのフィールドとして含めている．
+ */
+typedef struct wait_object_waiting_information {
+	WINFO	winfo;			/* 標準の待ち情報ブロック */
+	WOBJCB	*p_wobjcb;		/* 待ちオブジェクトの管理ブロック */
+} WINFO_WOBJ;
+
+/*
+ *  同期・通信オブジェクトに対する待ち状態への遷移
+ *  
+ *  実行中のタスクを待ち状態に遷移させ，同期・通信オブジェクトの待ちキュー
+ *  につなぐ．また，待ち情報ブロック（WINFO）のp_wobjcbを設定する．
+ *  wobj_make_wait_tmoutは，タイムイベントブロックの登録も行う．
+ */
+extern void	wobj_make_wait(WOBJCB *p_wobjcb, WINFO_WOBJ *p_winfo);
+extern void	wobj_make_wait_tmout(WOBJCB *p_wobjcb, WINFO_WOBJ *p_winfo,
+											TMEVTB *p_tmevtb, TMO tmout);
+
+/*
+ *  タスク優先度変更時の処理
+ *
+ *  同期・通信オブジェクトに対する待ち状態にあるタスクの優先度が変更さ
+ *  れた場合に，待ちキューの中でのタスクの位置を修正する．
+ */
+Inline void
+wobj_change_priority(WOBJCB *p_wobjcb, TCB *p_tcb)
+{
+	if ((p_wobjcb->p_wobjinib->wobjatr & TA_TPRI) != 0U) {
+		queue_delete(&(p_tcb->task_queue));
+		queue_insert_tpri(&(p_wobjcb->wait_queue), p_tcb);
+	}
+}
+
+/*
+ *  待ちキューの初期化
+ *
+ *  待ちキューにつながれているタスクをすべて待ち解除する．待ち解除した
+ *  タスクからの返値は，E_DLTとする．待ち解除したタスクへのディスパッチ
+ *  が必要な場合はtrue，そうでない場合はfalseを返す．
+ */
+extern bool_t	init_wait_queue(QUEUE *p_wait_queue);
+
+#endif /* TOPPERS_WAIT_H */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/libmad-0.15.1b/Makefile
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/libmad-0.15.1b/Makefile	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/libmad-0.15.1b/Makefile	(revision 457)
@@ -0,0 +1,93 @@
+
+ROOT_PATH = ..
+
+#
+#  ãªãã¸ã§ã¯ããã¡ã¤ã«åã®å®ç¾©
+#
+OBJNAME = libmad
+OBJFILE = $(OBJNAME).a
+
+ifeq ($(TARGET),)
+TARGET = stm32f7discovery_gcc
+endif
+
+CC  =	arm-none-eabi-gcc
+CXX	=	arm-none-eabi-g++
+AR  =	arm-none-eabi-ar
+NM  =	arm-none-eabi-nm
+OBJCOPY = arm-none-eabi-objcopy
+OBJDUMP = arm-none-eabi-objdump
+
+LDSCRIPT = stm32F7_rom.ld
+
+ifeq ($(MCPU),)
+MCPU = cortex-m7
+endif
+
+ifeq ($(FPU),)
+FPU = fpv4
+endif
+
+COPTS   = -mcpu=$(MCPU) -Wa,--gstabs -mthumb -mthumb-interwork -mlittle-endian
+
+ifeq ($(FPU),fpv4)
+COPTS  := $(COPTS) -mfloat-abi=softfp -mfpu=fpv4-sp-d16
+else
+COPTS  := $(COPTS) -mfloat-abi=hard -mfpu=fpv5-d16
+endif
+
+COPTS  := $(COPTS) -nostdlib -O2 -g -Wall
+CDEFS   = -DASO_ZEROCHECK -DHAVE_CONFIG_H -DFPM_64BIT
+
+
+INCLUDES = -I.
+
+TARGET_DIR = .
+RTOS_DIR = $(ROOT_PATH)
+UTASK_DIR = .
+vpath %.c $(UTASK_DIR)
+vpath %.S $(UTASK_DIR)
+
+COBJS = bit.o decoder.o fixed.o frame.o huffman.o layer3.o \
+        layer12.o stream.o synth.o timer.o version.o
+
+AOBJS = 
+
+INCLUDES := -I$(UTASK_DIR) -I$(RTOS_DIR)/monitor  -I$(RTOS_DIR) \
+	-I$(RTOS_DIR)/target/$(TARGET) -I$(RTOS_DIR)/arch $(INCLUDES)
+CFLAGS = $(COPTS) $(CDEFS) $(INCLUDES)
+LDFLAGS := -nostdlib $(LDFLAGS)
+
+ifdef LDSCRIPT
+    LDFLAGS := $(LDFLAGS) -T $(LDSCRIPT)
+endif
+
+all:	$(OBJFILE)
+
+$(OBJFILE):	$(COBJS) $(AOBJS)
+	$(AR) -rcs $(OBJFILE) $(COBJS) $(AOBJS)
+
+$(COBJS): %.o: %.c
+	$(CC) -c $(CFLAGS) $<
+
+$(AOBJS): %.o: %.S
+	$(CC) -c $(CFLAGS) $<
+
+# rules
+
+monmain.o	: $(UTASK_DIR)/monmain.c \
+		$(TARGET_DIR)/sys_defs.h $(UTASK_DIR)/comdefs.h $(UTASK_DIR)/mondefs.h $(UTASK_DIR)/serial.h
+
+monitor.o	: $(UTASK_DIR)/monitor.c \
+		$(TARGET_DIR)/sys_defs.h $(UTASK_DIR)/comdefs.h $(UTASK_DIR)/mondefs.h $(UTASK_DIR)/serial.h
+
+common.o	: $(UTASK_DIR)/common.c \
+		$(TARGET_DIR)/sys_defs.h $(UTASK_DIR)/comdefs.h $(UTASK_DIR)/serial.h
+
+serial.o	: $(UTASK_DIR)/serial.c \
+		$(TARGET_DIR)/sys_defs.h $(UTASK_DIR)/comdefs.h $(UTASK_DIR)/serial.h
+
+clean:
+	rm -f *.o
+	rm -f $(OBJFILE)
+
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/libmad-0.15.1b/config.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/libmad-0.15.1b/config.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/libmad-0.15.1b/config.h	(revision 457)
@@ -0,0 +1,138 @@
+/* config.h.  Generated by configure.  */
+/* config.h.in.  Generated from configure.ac by autoheader.  */
+
+/* Define to enable diagnostic debugging support. */
+/* #undef DEBUG */
+
+/* Define to enable experimental code. */
+/* #undef EXPERIMENTAL */
+
+/* Define to 1 if you have the <assert.h> header file. */
+//#define HAVE_ASSERT_H 1 (ROI DEBUG)
+
+/* Define to 1 if you have the <dlfcn.h> header file. */
+#define HAVE_DLFCN_H 1
+
+/* Define to 1 if you have the <errno.h> header file. */
+#define HAVE_ERRNO_H 1
+
+/* Define to 1 if you have the `fcntl' function. */
+#define HAVE_FCNTL 1
+
+/* Define to 1 if you have the <fcntl.h> header file. */
+#define HAVE_FCNTL_H 1
+
+/* Define to 1 if you have the `fork' function. */
+//#define HAVE_FORK 1 (ROI DEBUG)
+
+/* Define to 1 if you have the <inttypes.h> header file. */
+/* #undef HAVE_INTTYPES_H */
+
+/* Define to 1 if you have the <limits.h> header file. */
+#define HAVE_LIMITS_H 1
+
+/* Define if your MIPS CPU supports a 2-operand MADD16 instruction. */
+/* #undef HAVE_MADD16_ASM */
+
+/* Define if your MIPS CPU supports a 2-operand MADD instruction. */
+/* #undef HAVE_MADD_ASM */
+
+/* Define to 1 if you have the <memory.h> header file. */
+#define HAVE_MEMORY_H 1
+
+/* Define to 1 if you have the `pipe' function. */
+//#define HAVE_PIPE 1 (ROI DEBUG)
+
+/* Define to 1 if you have the <stdint.h> header file. */
+/* #undef HAVE_STDINT_H */
+
+/* Define to 1 if you have the <stdlib.h> header file. */
+#define HAVE_STDLIB_H 1
+
+/* Define to 1 if you have the <strings.h> header file. */
+#define HAVE_STRINGS_H 1
+
+/* Define to 1 if you have the <string.h> header file. */
+#define HAVE_STRING_H 1
+
+/* Define to 1 if you have the <sys/stat.h> header file. */
+#define HAVE_SYS_STAT_H 1
+
+/* Define to 1 if you have the <sys/types.h> header file. */
+#define HAVE_SYS_TYPES_H 1
+
+/* Define to 1 if you have <sys/wait.h> that is POSIX.1 compatible. */
+#define HAVE_SYS_WAIT_H 1
+
+/* Define to 1 if you have the <unistd.h> header file. */
+#define HAVE_UNISTD_H 1
+
+/* Define to 1 if you have the `waitpid' function. */
+#define HAVE_WAITPID 1
+
+/* Define to disable debugging assertions. */
+/* #undef NDEBUG */
+
+/* Define to optimize for accuracy over speed. */
+/* #undef OPT_ACCURACY */
+
+/* Define to optimize for speed over accuracy. */
+/* #undef OPT_SPEED */
+
+/* Define to enable a fast subband synthesis approximation optimization. */
+/* #undef OPT_SSO */
+
+/* Define to influence a strict interpretation of the ISO/IEC standards, even
+   if this is in opposition with best accepted practices. */
+/* #undef OPT_STRICT */
+
+/* Name of package */
+#define PACKAGE "libmad"
+
+/* Define to the address where bug reports for this package should be sent. */
+#define PACKAGE_BUGREPORT "support@underbit.com"
+
+/* Define to the full name of this package. */
+#define PACKAGE_NAME "MPEG Audio Decoder"
+
+/* Define to the full name and version of this package. */
+#define PACKAGE_STRING "MPEG Audio Decoder 0.15.1b"
+
+/* Define to the one symbol short name of this package. */
+#define PACKAGE_TARNAME "libmad"
+
+/* Define to the version of this package. */
+#define PACKAGE_VERSION "0.15.1b"
+
+/* The size of a `int', as computed by sizeof. */
+#define SIZEOF_INT 4
+
+/* The size of a `long', as computed by sizeof. */
+#define SIZEOF_LONG 4
+
+/* The size of a `long long', as computed by sizeof. */
+#define SIZEOF_LONG_LONG 8
+
+/* Define to 1 if you have the ANSI C header files. */
+#define STDC_HEADERS 1
+
+/* Version number of package */
+#define VERSION "0.15.1b"
+
+/* Define to 1 if your processor stores words with the most significant byte
+   first (like Motorola and SPARC, unlike Intel and VAX). */
+/* #undef WORDS_BIGENDIAN */
+
+/* Define to empty if `const' does not conform to ANSI C. */
+/* #undef const */
+
+#define memcpy(a, b, c)   bcopy2(b, a, c)
+
+/* Define to `__inline__' or `__inline' if that's what the C compiler
+   calls it, or to nothing if 'inline' is not supported under any name.  */
+#ifndef __cplusplus
+/* #undef inline */
+#endif
+
+/* Define to `int' if <sys/types.h> does not define. */
+/* #undef pid_t */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/library/histogram.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/library/histogram.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/library/histogram.c	(revision 457)
@@ -0,0 +1,189 @@
+/*
+ *  TOPPERS Software
+ *      Toyohashi Open Platform for Embedded Real-Time Systems
+ * 
+ *  Copyright (C) 2006-2011 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *		実行時間分布集計モジュール
+ */
+
+#include <kernel.h>
+#include <t_syslog.h>
+#include <test_lib.h>
+#include <histogram.h>
+#include "target_test.h"
+
+/*
+ *  実行時間分布計測の数
+ */
+#ifndef TNUM_HIST
+#define TNUM_HIST		10
+#endif /* TNUM_HIST */
+
+/*
+ *  ターゲット依存部で設定変更するためのマクロ
+ */
+#ifndef HISTTIM						/* 実行時間計測用の時刻のデータ型 */
+#define HISTTIM			SYSUTM
+#endif /* HISTTIM */
+
+#ifndef HIST_GET_TIM				/* 実行時間計測用の現在時刻の取得 */
+#ifndef TOPPERS_SUPPORT_GET_UTM
+#error get_utm is not supported.
+#endif /* TOPPERS_SUPPORT_GET_UTM */
+#define HIST_GET_TIM(p_time)	((void) get_utm(p_time))
+#endif /* HIST_GET_TIM */
+
+#ifndef HIST_CONV_TIM				/* 時刻の差から実行時間への変換 */
+#define HIST_CONV_TIM(time)		((uint_t)(time))
+#endif /* HIST_CONV_TIM */
+
+#ifndef HIST_BM_HOOK				/* 実行時間計測直前に行うべき処理 */
+#define HIST_BM_HOOK()			((void) 0)
+#endif
+
+/*
+ *  実行時間分布計測管理ブロック
+ */
+typedef struct histogram_control_block {
+	HISTTIM		begin_time;			/* 計測開始時刻 */
+	uint_t		maxval;				/* 分布を記録する最大時間 */
+	uint_t		*histarea;			/* 分布を記録するメモリ領域 */
+	uint_t		over;				/* 最大時間を超えた度数 */
+	uint_t		under;				/* 時間の逆転が疑われる度数 */
+} HISTCB;
+
+/*
+ *  実行時間分布計測管理ブロックのエリア
+ */
+static HISTCB	histcb_table[TNUM_HIST];
+
+/*
+ *  実行時間分布計測IDの最小値と最大値
+ */
+#define TMIN_HISTID		1
+#define TMAX_HISTID		(TMIN_HISTID + TNUM_HIST - 1)
+
+/*
+ *  実行時間分布計測の初期化
+ */
+void
+init_hist(ID histid, uint_t maxval, uint_t histarea[])
+{
+	HISTCB	*p_histcb;
+	uint_t	i;
+
+	assert(TMIN_HISTID <= histid && histid <= TMAX_HISTID);
+	p_histcb = &(histcb_table[histid - TMIN_HISTID]);
+
+	for (i = 0; i <= maxval; i++) {
+		histarea[i] = 0U;
+	}
+	p_histcb->maxval = maxval;
+	p_histcb->histarea = histarea;
+	p_histcb->over = 0U;
+	p_histcb->under = 0U;
+}
+
+/*
+ *  実行時間計測の開始
+ */
+void
+begin_measure(ID histid)
+{
+	HISTCB	*p_histcb;
+
+	assert(TMIN_HISTID <= histid && histid <= TMAX_HISTID);
+	p_histcb = &(histcb_table[histid - TMIN_HISTID]);
+
+	HIST_BM_HOOK();
+	HIST_GET_TIM(&(p_histcb->begin_time));
+}
+
+/*
+ *  実行時間計測の終了
+ */
+void
+end_measure(ID histid)
+{
+	HISTCB	*p_histcb;
+	HISTTIM	end_time;
+	uint_t	val;
+
+	HIST_GET_TIM(&end_time);
+
+	assert(TMIN_HISTID <= histid && histid <= TMAX_HISTID);
+	p_histcb = &(histcb_table[histid - TMIN_HISTID]);
+
+	val = HIST_CONV_TIM(end_time - p_histcb->begin_time);
+	if (val <= p_histcb->maxval) {
+		p_histcb->histarea[val]++;
+	}
+	else if (val <= ((uint_t) INT_MAX)) {
+		p_histcb->over++;
+	}
+	else {
+		p_histcb->under++;
+	}
+}
+
+/*
+ *  実行時間分布計測の表示
+ */
+void
+print_hist(ID histid)
+{
+	HISTCB	*p_histcb;
+	uint_t	i;
+
+	assert(TMIN_HISTID <= histid && histid <= TMAX_HISTID);
+	p_histcb = &(histcb_table[histid - TMIN_HISTID]);
+
+	for (i = 0; i <= p_histcb->maxval; i++) {
+		if (p_histcb->histarea[i] > 0) {
+			syslog_2(LOG_NOTICE, "%d : %d", i, p_histcb->histarea[i]);
+			syslog_flush();
+		}
+	}
+	if (p_histcb->over > 0) {
+		syslog_2(LOG_NOTICE, "> %d : %d", p_histcb->maxval, p_histcb->over);
+	}
+	if (p_histcb->under > 0) {
+		syslog_1(LOG_NOTICE, "> INT_MAX : %d", p_histcb->under);
+	}
+	syslog_flush();
+}
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/library/log_output.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/library/log_output.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/library/log_output.c	(revision 457)
@@ -0,0 +1,200 @@
+/*
+ *  TOPPERS Software
+ *      Toyohashi Open Platform for Embedded Real-Time Systems
+ * 
+ *  Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
+ *                              Toyohashi Univ. of Technology, JAPAN
+ *  Copyright (C) 2004-2011 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *		システムログのフォーマット出力
+ */
+
+#include <t_stddef.h>
+#include <t_syslog.h>
+#include <log_output.h>
+
+/*
+ *  数値を文字列に変換
+ */
+#define CONVERT_BUFLEN	((sizeof(uintptr_t) * CHAR_BIT + 2) / 3)
+										/* uintptr_t型の数値の最大文字数 */
+static void
+convert(uintptr_t val, uint_t radix, const char *radchar,
+			uint_t width, bool_t minus, bool_t padzero, void (*putc)(char))
+{
+	char	buf[CONVERT_BUFLEN];
+	uint_t	i, j;
+
+	i = 0U;
+	do {
+		buf[i++] = radchar[val % radix];
+		val /= radix;
+	} while (i < CONVERT_BUFLEN && val != 0);
+
+	if (minus && width > 0) {
+		width -= 1;
+	}
+	if (minus && padzero) {
+		(*putc)('-');
+	}
+	for (j = i; j < width; j++) {
+		(*putc)(padzero ? '0' : ' ');
+	}
+	if (minus && !padzero) {
+		(*putc)('-');
+	}
+	while (i > 0U) {
+		(*putc)(buf[--i]);
+	}
+}
+
+/*
+ *  文字列整形出力
+ */
+static const char raddec[] = "0123456789";
+static const char radhex[] = "0123456789abcdef";
+static const char radHEX[] = "0123456789ABCDEF";
+
+void
+syslog_printf(const char *format, const intptr_t *p_args, void (*putc)(char))
+{
+	char		c;
+	uint_t		width;
+	bool_t		padzero;
+	intptr_t	val;
+	const char	*str;
+
+	while ((c = *format++) != '\0') {
+		if (c != '%') {
+			(*putc)(c);
+			continue;
+		}
+
+		width = 0U;
+		padzero = false;
+		if ((c = *format++) == '0') {
+			padzero = true;
+			c = *format++;
+		}
+		while ('0' <= c && c <= '9') {
+			width = width * 10U + c - '0';
+			c = *format++;
+		}
+		if (c == 'l') {
+			c = *format++;
+		}
+		switch (c) {
+		case 'd':
+			val = (intptr_t)(*p_args++);
+			if (val >= 0) {
+				convert((uintptr_t) val, 10U, raddec,
+										width, false, padzero, putc);
+			}
+			else {
+				convert((uintptr_t)(-val), 10U, raddec,
+										width, true, padzero, putc);
+			}
+			break;
+		case 'u':
+			val = (intptr_t)(*p_args++);
+			convert((uintptr_t) val, 10U, raddec, width, false, padzero, putc);
+			break;
+		case 'x':
+		case 'p':
+			val = (intptr_t)(*p_args++);
+			convert((uintptr_t) val, 16U, radhex, width, false, padzero, putc);
+			break;
+		case 'X':
+			val = (intptr_t)(*p_args++);
+			convert((uintptr_t) val, 16U, radHEX, width, false, padzero, putc);
+			break;
+		case 'c':
+			(*putc)((char)(intptr_t)(*p_args++));
+			break;
+		case 's':
+			str = (const char *)(*p_args++);
+			while ((c = *str++) != '\0') {
+				(*putc)(c);
+			}
+			break;
+		case '%':
+			(*putc)('%');
+			break;
+		case '\0':
+			format--;
+			break;
+		default:
+			break;
+		}
+	}
+}
+
+/*
+ *  ログ情報の出力
+ */
+void
+syslog_print(const SYSLOG *p_syslog, void (*putc)(char))
+{
+	switch (p_syslog->logtype) {
+	case LOG_TYPE_COMMENT:
+		syslog_printf((const char *)(p_syslog->loginfo[0]),
+								&(p_syslog->loginfo[1]), putc);
+		break;
+	case LOG_TYPE_ASSERT:
+		syslog_printf("%s:%u: Assertion `%s' failed.",
+								&(p_syslog->loginfo[0]), putc);
+		break;
+	default:
+		/*
+		 *  他の種別のログ情報には対応していない．
+		 */
+		break;
+	}
+}
+
+/*
+ *  ログ情報喪失メッセージの出力
+ */
+void
+syslog_lostmsg(uint_t lostlog, void (*putc)(char))
+{
+	intptr_t	lostinfo[1];
+
+	lostinfo[0] = (intptr_t) lostlog;
+	syslog_printf("%d messages are lost.", lostinfo, putc);
+	(*putc)('\n');
+}
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/library/strerror.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/library/strerror.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/library/strerror.c	(revision 457)
@@ -0,0 +1,110 @@
+/*
+ *  TOPPERS Software
+ *      Toyohashi Open Platform for Embedded Real-Time Systems
+ * 
+ *  Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
+ *                              Toyohashi Univ. of Technology, JAPAN
+ *  Copyright (C) 2004-2010 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *		エラーメッセージ文字列を返す関数
+ */
+
+#include <t_stddef.h>
+#include <t_stdlib.h>
+
+const char *
+itron_strerror(ER ercd)
+{
+	switch (MERCD(ercd)) {
+	case E_OK:
+		return("E_OK");
+
+	case E_SYS:
+		return("E_SYS");
+	case E_NOSPT:
+		return("E_NOSPT");
+	case E_RSFN:
+		return("E_RSFN");
+	case E_RSATR:
+		return("E_RSATR");
+
+	case E_PAR:
+		return("E_PAR");
+	case E_ID:
+		return("E_ID");
+
+	case E_CTX:
+		return("E_CTX");
+	case E_MACV:
+		return("E_MACV");
+	case E_OACV:
+		return("E_OACV");
+	case E_ILUSE:
+		return("E_ILUSE");
+
+	case E_NOMEM:
+		return("E_NOMEM");
+	case E_NOID:
+		return("E_NOID");
+	case E_NORES:
+		return("E_NORES");
+
+	case E_OBJ:
+		return("E_OBJ");
+	case E_NOEXS:
+		return("E_NOEXS");
+	case E_QOVR:
+		return("E_QOVR");
+
+	case E_RLWAI:
+		return("E_RLWAI");
+	case E_TMOUT:
+		return("E_TMOUT");
+	case E_DLT:
+		return("E_DLT");
+	case E_CLS:
+		return("E_CLS");
+
+	case E_WBLK:
+		return("E_WBLK");
+	case E_BOVR:
+		return("E_BOVR");
+
+	default:
+		return("unknown error");
+	}
+}
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/library/t_perror.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/library/t_perror.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/library/t_perror.c	(revision 457)
@@ -0,0 +1,56 @@
+/*
+ *  TOPPERS Software
+ *      Toyohashi Open Platform for Embedded Real-Time Systems
+ * 
+ *  Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
+ *                              Toyohashi Univ. of Technology, JAPAN
+ *  Copyright (C) 2004-2006 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *		エラーメッセージの出力
+ */
+
+#include <t_stddef.h>
+#include <t_syslog.h>
+#include <t_stdlib.h>
+
+void
+t_perror(uint_t prio, const char *file, int_t line, const char *expr, ER ercd)
+{
+	syslog_5(prio, "%s (%d) reported by `%s' in line %d of `%s'.",
+						itron_strerror(ercd), SERCD(ercd), expr, line, file);
+
+}
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/library/test_lib.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/library/test_lib.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/library/test_lib.c	(revision 457)
@@ -0,0 +1,203 @@
+/*
+ *  TOPPERS Software
+ *      Toyohashi Open Platform for Embedded Real-Time Systems
+ * 
+ *  Copyright (C) 2005-2013 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  $Id$
+ */
+
+/* 
+ *		テストプログラム用ライブラリ
+ */
+
+#include <kernel.h>
+#include <sil.h>
+#include <t_syslog.h>
+#include <t_stdlib.h>
+#include <log_output.h>
+#include "syssvc/syslog.h"
+#include "target_syssvc.h"
+#include <test_lib.h>
+
+/*
+ *	チェックポイント
+ */
+static uint_t	check_count = 0u;
+
+/*
+ *	自己診断関数
+ */
+static BIT_FUNC	check_bit_func = NULL;
+
+/*
+ *	自己診断関数の設定
+ */
+void
+set_bit_func(BIT_FUNC bit_func)
+{
+	check_bit_func = bit_func;
+}
+
+/*
+ *  テストプログラムの開始
+ */
+void
+test_start(char *progname)
+{
+	syslog_1(LOG_NOTICE, "Test program: %s", progname);
+}
+
+/*
+ *  システムログの出力処理
+ */
+void
+syslog_flush(void)
+{
+	SYSLOG	logbuf;
+	ER_UINT	rercd;
+
+	/*
+	 *  ログバッファに記録されたログ情報を，低レベル出力機能を用いて出
+	 *  力する．
+	 */
+	while ((rercd = syslog_rea_log(&logbuf)) >= 0) {
+		if (rercd > 0) {
+			syslog_lostmsg((uint_t) rercd, target_fput_log);
+		}
+		if (logbuf.logtype >= LOG_TYPE_COMMENT) {
+			syslog_print(&logbuf, target_fput_log);
+			target_fput_log('\n');
+		}
+	}
+}
+
+/*
+ *	テストプログラムの終了
+ */
+void
+test_finish(void)
+{
+	SIL_PRE_LOC;
+
+	SIL_LOC_INT();
+	syslog_flush();
+	(void) ext_ker();
+
+	/* ここへ来ることはないはず */
+	SIL_UNL_INT();
+}
+
+/*
+ *	チェックポイント
+ */
+void
+check_point(uint_t count)
+{
+	bool_t	errorflag = false;
+	ER		rercd;
+	SIL_PRE_LOC;
+
+	/*
+	 *  割込みロック状態に
+	 */
+	SIL_LOC_INT();
+
+	/*
+	 *  シーケンスチェック
+	 */
+	if (++check_count == count) {
+		syslog_1(LOG_NOTICE, "Check point %d passed.", count);
+	}
+	else {
+		syslog_1(LOG_ERROR, "## Unexpected check point %d.", count);
+		errorflag = true;
+	}
+
+	/*
+	 *  カーネルの内部状態の検査
+	 */
+	if (check_bit_func != NULL) {
+		rercd = (*check_bit_func)();
+		if (rercd < 0) {
+			syslog_2(LOG_ERROR, "## Internal inconsistency detected (%s, %d).",
+								itron_strerror(rercd), SERCD(rercd));
+			errorflag = true;
+		}
+	}
+
+	/*
+	 *  エラーが検出された場合は，テストプログラムを終了する．
+	 */
+	if (errorflag) {
+		test_finish();
+	}
+
+	/*
+	 *  割込みロック状態を解除
+	 */
+	SIL_UNL_INT();
+}
+
+/*
+ *	完了チェックポイント
+ */
+void
+check_finish(uint_t count)
+{
+	check_point(count);
+	syslog_0(LOG_NOTICE, "All check points passed.");
+	test_finish();
+}
+
+/*
+ *	条件チェックのエラー処理
+ */
+void
+_check_assert(const char *expr, const char *file, int_t line)
+{
+	syslog_3(LOG_ERROR, "## Assertion `%s' failed at %s:%u.",
+								expr, file, line);
+	test_finish();
+}
+
+/*
+ *	エラーコードチェックのエラー処理
+ */
+void
+_check_ercd(ER ercd, const char *file, int_t line)
+{
+	syslog_3(LOG_ERROR, "## Unexpected error %s detected at %s:%u.",
+								itron_strerror(ercd), file, line);
+	test_finish();
+}
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/library/vasyslog.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/library/vasyslog.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/library/vasyslog.c	(revision 457)
@@ -0,0 +1,111 @@
+/*
+ *  TOPPERS Software
+ *      Toyohashi Open Platform for Embedded Real-Time Systems
+ * 
+ *  Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
+ *                              Toyohashi Univ. of Technology, JAPAN
+ *  Copyright (C) 2004-2011 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *		可変数引数のシステムログライブラリ
+ */
+
+#include <t_stddef.h>
+#include <t_syslog.h>
+#include <stdarg.h>
+
+#ifndef TOPPERS_OMIT_SYSLOG
+
+void
+syslog(uint_t prio, const char *format, ...)
+{
+	SYSLOG	logbuf;
+	va_list	ap;
+	uint_t	i;
+	char	c;
+	bool_t	lflag;
+
+	logbuf.logtype = LOG_TYPE_COMMENT;
+	logbuf.loginfo[0] = (intptr_t) format;
+	i = 1U;
+	va_start(ap, format);
+
+	while ((c = *format++) != '\0' && i < TMAX_LOGINFO) {
+		if (c != '%') {
+			continue;
+		}
+
+		lflag = false;
+		c = *format++;
+		while ('0' <= c && c <= '9') {
+			c = *format++;
+		}
+		if (c == 'l') {
+			lflag = true;
+			c = *format++;
+		}
+		switch (c) {
+		case 'd':
+			logbuf.loginfo[i++] = lflag ? (intptr_t) va_arg(ap, long_t)
+										: (intptr_t) va_arg(ap, int_t);
+			break;
+		case 'u':
+		case 'x':
+		case 'X':
+			logbuf.loginfo[i++] = lflag ? (intptr_t) va_arg(ap, ulong_t)
+										: (intptr_t) va_arg(ap, uint_t);
+			break;
+		case 'p':
+			logbuf.loginfo[i++] = (intptr_t) va_arg(ap, void *);
+			break;
+		case 'c':
+			logbuf.loginfo[i++] = (intptr_t) va_arg(ap, int);
+			break;
+		case 's':
+			logbuf.loginfo[i++] = (intptr_t) va_arg(ap, const char *);
+			break;
+		case '\0':
+			format--;
+			break;
+		default:
+			break;
+		}
+	}
+	va_end(ap);
+	(void) syslog_wri_log(prio, &logbuf);
+}
+
+#endif /* TOPPERS_OMIT_SYSLOG */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/Makefile.config
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/Makefile.config	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/Makefile.config	(revision 457)
@@ -0,0 +1,87 @@
+#
+#   TOPPERS/ASP/FMP Kernel
+#       Toyohashi Open Platform for Embedded Real-Time Systems/
+#       Advanced Standard Profile Kernel
+#
+#   Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
+#                               Toyohashi Univ. of Technology, JAPAN
+#   Copyright (C) 2003-2008 by Ryosuke Takeuchi
+#                Platform Development Center RICOH COMPANY,LTD. JAPAN
+#   Copyright (C) 2015-2019 by TOPPERS PROJECT Educational Working Group.
+#
+#   上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+#   によって公表されている GNU General Public License の Version 2 に記
+#   述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+#   を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+#   利用と呼ぶ）することを無償で許諾する．
+#   (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+#       権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+#       スコード中に含まれていること．
+#   (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+#       用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+#       者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+#       の無保証規定を掲載すること．
+#   (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+#       用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+#       と．
+#     (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+#         作権表示，この利用条件および下記の無保証規定を掲載すること．
+#     (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+#         報告すること．
+#   (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+#       害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+#
+#   本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+#   よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+#   含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+#   接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+#
+#  @(#) $Id$
+#
+ 
+#
+#  Makefile のプロセッサ依存 (lwip用)
+#
+
+#
+#  コンパイルオプション
+#
+INCLUDES := $(INCLUDES) -I$(SRCDIR)/lwip -I$(SRCDIR)/lwip/lwip-2.1.2/src/include \
+		-I$(SRCDIR)/lwip/contrib-2.1.0/ports/toppers/include -I$(SRCDIR)/lwip/contrib-2.1.0
+SYSSVC_CFLAGS := $(SYSSVC_CFLAGS) -DETHARP_SUPPORT_STATIC_ENTRIES=1
+
+#
+#  LWIPミドルウェアに関する定義
+#
+SYSSVC_DIR := $(SYSSVC_DIR):\
+		$(SRCDIR)/lwip/lwip-2.1.2/src/core:$(SRCDIR)/lwip/lwip-2.1.2/src/core/ipv4:$(SRCDIR)/lwip/lwip-2.1.2/src/core/ipv6:\
+		$(SRCDIR)/lwip/lwip-2.1.2/src/netif:$(SRCDIR)/lwip/lwip-2.1.2/src/netif/ppp:$(SRCDIR)/lwip/lwip-2.1.2/src/netif/ppp/polarssl:\
+		$(SRCDIR)/lwip/lwip-2.1.2/src/api:$(SRCDIR)/lwip/lwip-2.1.2/src/apps/snmp:$(SRCDIR)/lwip/lwip-2.1.2/src/apps/mdns:\
+		$(SRCDIR)/lwip/lwip-2.1.2/src/apps/tftp:$(SRCDIR)/lwip/lwip-2.1.2/src/apps/sntp:$(SRCDIR)/lwip/lwip-2.1.2/src/apps/netbiosns:\
+		$(SRCDIR)/lwip/lwip-2.1.2/src/apps/http:\
+		$(SRCDIR)/lwip/contrib-2.1.0/examples/snmp/snmp_private_mib:$(SRCDIR)/lwip/contrib-2.1.0/apps/ping:\
+		$(SRCDIR)/lwip/contrib-2.1.0/apps/chargen:$(SRCDIR)/lwip/contrib-2.1.0/apps/udpecho:\
+		$(SRCDIR)/lwip/contrib-2.1.0/apps/tcpecho:$(SRCDIR)/lwip/contrib-2.1.0/apps/netio:\
+		$(SRCDIR)/lwip/contrib-2.1.0/apps/shell:$(SRCDIR)/lwip/contrib-2.1.0/ports/toppers 
+
+SYSSVC_COBJS := $(SYSSVC_COBJS) init.o netif.o ip.o tcp.o tcp_in.o tcp_out.o udp.o dns.o raw.o inet_chksum.o \
+	def.o stats.o pbuf.o mem.o memp.o timeouts.o etharp.o ip4.o ip4_addr.o ip4_frag.o icmp.o igmp.o dhcp.o autoip.o \
+	ethip6.o ip6.o ip6_addr.o ip6_frag.o icmp6.o mld6.o nd6.o inet6.o ethernet.o slipif.o \
+	tcpip.o sockets.o err.o netbuf.o api_lib.o api_msg.o if_api.o netifapi.o netdb.o \
+	snmp_core.o snmp_mib2.o snmp_mib2_ip.o snmp_mib2_system.o snmp_mib2_interfaces.o snmp_mib2_icmp.o snmp_mib2_tcp.o snmp_mib2_udp.o snmp_mib2_snmp.o \
+	snmp_traps.o snmp_threadsync.o snmp_scalar.o snmp_table.o snmp_asn1.o snmp_pbuf_stream.o snmp_netconn.o snmp_msg.o \
+	mdns.o tftp_server.o sntp.o netbiosns.o httpd.o fs.o \
+	sys_arch.o snprintf.o
+
+ifdef WIFIIF
+SYSSVC_COBJS := $(SYSSVC_COBJS) wifiif.o
+else
+SYSSVC_COBJS := $(SYSSVC_COBJS) ethernetif.o
+endif
+
+# PPP
+#	ppp.o pppoe.o pppos.o pppol2tp.o ccp.o lcp.o fsm.o utils.o auth.o magic.o upap.o chap_ms.o chap-md5.o chap-new.o mppe.o pppcrypt.o ipcp.o ipv6cp.o vj.o
+#	arc4.o md4.o md5.o sha1.o des.o
+#	
+
+
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/Coverity/coverity.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/Coverity/coverity.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/Coverity/coverity.c	(revision 457)
@@ -0,0 +1,106 @@
+typedef unsigned char err_t;
+typedef unsigned int u32_t;
+typedef unsigned short u16_t;
+typedef unsigned char u8_t;
+typedef void sys_sem_t;
+typedef void sys_mutex_t;
+typedef size_t mem_size_t;
+typedef size_t memp_t;
+struct pbuf;
+struct netif;
+
+void* mem_malloc(mem_size_t size)
+{
+  __coverity_alloc__(size);
+}
+void mem_free(void* mem)
+{
+  __coverity_free__(mem);
+}
+
+void* memp_malloc(memp_t type)
+{
+  __coverity_alloc_nosize__();  
+}
+void memp_free(memp_t type, void* mem)
+{
+  __coverity_free__(mem);  
+}
+
+void sys_mutex_lock(sys_mutex_t* mutex)
+{
+  __coverity_exclusive_lock_acquire__(mutex);
+}
+void sys_mutex_unlock(sys_mutex_t* mutex)
+{
+  __coverity_exclusive_lock_release__(mutex);
+}
+
+u32_t sys_arch_sem_wait(sys_sem_t *sem, u32_t timeout)
+{
+  __coverity_recursive_lock_acquire__(sem);
+}
+void sys_sem_signal(sys_sem_t *sem)
+{
+  __coverity_recursive_lock_release__(sem);
+}
+
+err_t ethernet_input(struct pbuf *p, struct netif *inp)
+{
+  __coverity_tainted_string_sink_content__(p); 
+}
+err_t tcpip_input(struct pbuf *p, struct netif *inp)
+{
+  __coverity_tainted_string_sink_content__(p); 
+}
+err_t ip_input(struct pbuf *p, struct netif *inp)
+{
+  __coverity_tainted_string_sink_content__(p); 
+}
+err_t ip4_input(struct pbuf *p, struct netif *inp)
+{
+  __coverity_tainted_string_sink_content__(p); 
+}
+err_t ip6_input(struct pbuf *p, struct netif *inp)
+{
+  __coverity_tainted_string_sink_content__(p); 
+}
+
+err_t pbuf_take(struct pbuf *buf, const void *dataptr, u16_t len)
+{
+  __coverity_tainted_string_argument__(buf);
+  __coverity_tainted_data_argument__(buf);
+}
+err_t pbuf_take_at(struct pbuf *buf, const void *dataptr, u16_t len, u16_t offset)
+{
+  __coverity_tainted_string_argument__(buf);
+  __coverity_tainted_data_argument__(buf);
+}
+err_t pbuf_copy(struct pbuf *p_to, struct pbuf *p_from)
+{
+  __coverity_tainted_data_transitive__(p_to, p_from);
+}
+u16_t pbuf_copy_partial(struct pbuf *p, void *dataptr, u16_t len, u16_t offset)
+{
+  __coverity_tainted_string_argument__(dataptr);
+  __coverity_tainted_data_argument__(dataptr);
+}
+u8_t pbuf_get_at(struct pbuf* p, u16_t offset)
+{
+  __coverity_tainted_data_return__();
+}
+
+void abort(void)
+{
+  __coverity_panic__();
+}
+
+int check_path(char* path, size_t size)
+{
+  if (size) {
+    __coverity_tainted_data_sanitize__(path);
+    return 1;
+  } else {
+    return 0;
+  }
+}
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/Filelists.cmake
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/Filelists.cmake	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/Filelists.cmake	(revision 457)
@@ -0,0 +1,56 @@
+# This file is indended to be included in end-user CMakeLists.txt
+# include(/path/to/Filelists.cmake)
+# It assumes the variable LWIP_CONTRIB_DIR is defined pointing to the
+# root path of lwIP contrib sources.
+#
+# This file is NOT designed (on purpose) to be used as cmake
+# subdir via add_subdirectory()
+# The intention is to provide greater flexibility to users to 
+# create their own targets using the *_SRCS variables.
+
+set(lwipcontribexamples_SRCS
+    ${LWIP_CONTRIB_DIR}/examples/httpd/fs_example/fs_example.c
+    ${LWIP_CONTRIB_DIR}/examples/httpd/ssi_example/ssi_example.c
+    ${LWIP_CONTRIB_DIR}/examples/lwiperf/lwiperf_example.c
+    ${LWIP_CONTRIB_DIR}/examples/mdns/mdns_example.c
+    ${LWIP_CONTRIB_DIR}/examples/mqtt/mqtt_example.c
+    ${LWIP_CONTRIB_DIR}/examples/ppp/pppos_example.c
+    ${LWIP_CONTRIB_DIR}/examples/snmp/snmp_private_mib/lwip_prvmib.c
+    ${LWIP_CONTRIB_DIR}/examples/snmp/snmp_v3/snmpv3_dummy.c
+    ${LWIP_CONTRIB_DIR}/examples/snmp/snmp_example.c
+    ${LWIP_CONTRIB_DIR}/examples/sntp/sntp_example.c
+    ${LWIP_CONTRIB_DIR}/examples/tftp/tftp_example.c
+)
+add_library(lwipcontribexamples EXCLUDE_FROM_ALL ${lwipcontribexamples_SRCS})
+target_compile_options(lwipcontribexamples PRIVATE ${LWIP_COMPILER_FLAGS})
+target_compile_definitions(lwipcontribexamples PRIVATE ${LWIP_DEFINITIONS} ${LWIP_MBEDTLS_DEFINITIONS})
+target_include_directories(lwipcontribexamples PRIVATE ${LWIP_INCLUDE_DIRS} ${LWIP_MBEDTLS_INCLUDE_DIRS})
+
+set(lwipcontribapps_SRCS
+    ${LWIP_CONTRIB_DIR}/apps/httpserver/httpserver-netconn.c
+    ${LWIP_CONTRIB_DIR}/apps/chargen/chargen.c
+    ${LWIP_CONTRIB_DIR}/apps/udpecho/udpecho.c
+    ${LWIP_CONTRIB_DIR}/apps/tcpecho/tcpecho.c
+    ${LWIP_CONTRIB_DIR}/apps/shell/shell.c
+    ${LWIP_CONTRIB_DIR}/apps/udpecho_raw/udpecho_raw.c
+    ${LWIP_CONTRIB_DIR}/apps/tcpecho_raw/tcpecho_raw.c
+    ${LWIP_CONTRIB_DIR}/apps/netio/netio.c
+    ${LWIP_CONTRIB_DIR}/apps/ping/ping.c
+    ${LWIP_CONTRIB_DIR}/apps/socket_examples/socket_examples.c
+    ${LWIP_CONTRIB_DIR}/apps/rtp/rtp.c
+)
+add_library(lwipcontribapps EXCLUDE_FROM_ALL ${lwipcontribapps_SRCS})
+target_compile_options(lwipcontribapps PRIVATE ${LWIP_COMPILER_FLAGS})
+target_compile_definitions(lwipcontribapps PRIVATE ${LWIP_DEFINITIONS} ${LWIP_MBEDTLS_DEFINITIONS})
+target_include_directories(lwipcontribapps PRIVATE ${LWIP_INCLUDE_DIRS} ${LWIP_MBEDTLS_INCLUDE_DIRS})
+
+set(lwipcontribaddons_SRCS
+    ${LWIP_CONTRIB_DIR}/addons/tcp_isn/tcp_isn.c
+    ${LWIP_CONTRIB_DIR}/addons/ipv6_static_routing/ip6_route_table.c
+#    ${LWIP_CONTRIB_DIR}/addons/netconn/external_resolve/dnssd.c
+#    ${LWIP_CONTRIB_DIR}/addons/tcp_md5/tcp_md5.c
+)
+add_library(lwipcontribaddons EXCLUDE_FROM_ALL ${lwipcontribaddons_SRCS})
+target_compile_options(lwipcontribaddons PRIVATE ${LWIP_COMPILER_FLAGS})
+target_compile_definitions(lwipcontribaddons PRIVATE ${LWIP_DEFINITIONS} ${LWIP_MBEDTLS_DEFINITIONS})
+target_include_directories(lwipcontribaddons PRIVATE ${LWIP_INCLUDE_DIRS} ${LWIP_MBEDTLS_INCLUDE_DIRS})
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/Filelists.mk
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/Filelists.mk	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/Filelists.mk	(revision 457)
@@ -0,0 +1,56 @@
+#
+# Copyright (c) 2001, 2002 Swedish Institute of Computer Science.
+# 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. The name of the author may not be used to endorse or promote products
+#    derived from this software without specific prior written permission. 
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+#
+# This file is part of the lwIP TCP/IP stack.
+# 
+# Author: Adam Dunkels <adam@sics.se>
+#
+
+# CONTRIBAPPFILES: Contrib Applications.
+CONTRIBAPPFILES=$(CONTRIBDIR)/apps/httpserver/httpserver-netconn.c \
+	$(CONTRIBDIR)/apps/chargen/chargen.c \
+	$(CONTRIBDIR)/apps/udpecho/udpecho.c \
+	$(CONTRIBDIR)/apps/tcpecho/tcpecho.c \
+	$(CONTRIBDIR)/apps/shell/shell.c \
+	$(CONTRIBDIR)/apps/udpecho_raw/udpecho_raw.c \
+	$(CONTRIBDIR)/apps/tcpecho_raw/tcpecho_raw.c \
+	$(CONTRIBDIR)/apps/netio/netio.c \
+	$(CONTRIBDIR)/apps/ping/ping.c \
+	$(CONTRIBDIR)/apps/socket_examples/socket_examples.c \
+	$(CONTRIBDIR)/apps/rtp/rtp.c \
+	$(CONTRIBDIR)/examples/httpd/fs_example/fs_example.c \
+	$(CONTRIBDIR)/examples/httpd/ssi_example/ssi_example.c \
+	$(CONTRIBDIR)/examples/lwiperf/lwiperf_example.c \
+	$(CONTRIBDIR)/examples/mdns/mdns_example.c \
+	$(CONTRIBDIR)/examples/mqtt/mqtt_example.c \
+	$(CONTRIBDIR)/examples/ppp/pppos_example.c \
+	$(CONTRIBDIR)/examples/snmp/snmp_private_mib/lwip_prvmib.c \
+	$(CONTRIBDIR)/examples/snmp/snmp_v3/snmpv3_dummy.c \
+	$(CONTRIBDIR)/examples/snmp/snmp_example.c \
+	$(CONTRIBDIR)/examples/sntp/sntp_example.c \
+	$(CONTRIBDIR)/examples/tftp/tftp_example.c \
+	$(CONTRIBDIR)/addons/tcp_isn/tcp_isn.c \
+	$(CONTRIBDIR)/addons/ipv6_static_routing/ip6_route_table.c
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/addons/ipv6_static_routing/README
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/addons/ipv6_static_routing/README	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/addons/ipv6_static_routing/README	(revision 457)
@@ -0,0 +1,43 @@
+A simple routing table implementation for addition, deletion and lookup of IPv6 routes.ï¾ï£°
+
+APIs are:
+1) s8_t ip6_add_route_entry(struct ip6_prefix *ip6_prefix,
+ï¾ï£° ï¾ï£° ï¾ï£° ï¾ï£° ï¾ï£° ï¾ï£° ï¾ï£° ï¾ï£° ï¾ï£° ï¾ï£° ï¾ï£° ï¾ï£° ï¾ï£° ï¾ï£° struct netif *netif,
+ï¾ï£° ï¾ï£° ï¾ï£° ï¾ï£° ï¾ï£° ï¾ï£° ï¾ï£° ï¾ï£° ï¾ï£° ï¾ï£° ï¾ï£° ï¾ï£° ï¾ï£° ï¾ï£° ip6_addr_t *gateway,
+ï¾ï£° ï¾ï£° ï¾ï£° ï¾ï£° ï¾ï£° ï¾ï£° ï¾ï£° ï¾ï£° ï¾ï£° ï¾ï£° ï¾ï£° ï¾ï£° ï¾ï£° ï¾ï£° s8_t *index);
+
+2) err_t ip6_remove_route_entry(struct ip6_prefix *ip6_prefix);
+
+3) s8_t ip6_find_route_entry(ip6_addr_t *ip6_dest_addr);
+
+4) struct netif *ip6_static_route(ip6_addr_t *src, ip6_addr_t *dest);
+
+5) ip6_addr_t *ip6_get_gateway(struct netif *netif, ip6_addr_t *dest);
+
+6) struct ip6_route_entry *ip6_get_route_table(void);
+
+For route lookup from the table, Theï¾ï£°LWIP_HOOK_IP6_ROUTE hook in ip6_route(..) of ip6.c
+could be assigned to the ip6_static_route() API of this implementation to return the 
+appropriate netif.
+
+-- The application can add routes using the API ip6_add_route_entry(..).ï¾ï£°
+ï¾ï£° ï¾ï£°This API adds the ip6 prefix route into the static route table while
+ï¾ï£° ï¾ï£°keeping all entries sorted in decreasing order of prefix length.
+ï¾ï£° ï¾ï£°Subsequently, a linear search down the list can be performed to retrieve a
+ï¾ï£° ï¾ï£°matching route entry for a Longest Prefix Match.
+ï¾ï£° ï¾ï£°The prefix length is expected to be at an 8-bit boundary. While this isï¾ï£°
+ï¾ï£° ï¾ï£°a limitation, it would serve most practical purposes.
+
+-- The application can remove routes using the API ip6_remove_route_entry(..).
+
+-- The application can find a route entry for a specific address using theï¾ï£°
+ï¾ï£° ï¾ï£°ip6_find_route_entry() function which returns the index of the found entry.ï¾ï£°
+ï¾ï£° ï¾ï£°This is used internally by the route lookup function ip6_static_route() API.
+
+-- To fetch the gateway IPv6 address for a specific destination IPv6ï¾ï£°
+ï¾ï£° ï¾ï£°address and target netif, the application can call ip6_get_gateway(..).
+   This API could be assigned to the LWIP_HOOK_ND6_GET_GW() if a gateway has
+   been added as part of the ip6_add_route_entry().
+
+-- To fetch a pointer to the head of the table, the application can callï¾ï£°
+ï¾ï£° ï¾ï£°ip6_get_route_table().
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/addons/ipv6_static_routing/ip6_route_table.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/addons/ipv6_static_routing/ip6_route_table.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/addons/ipv6_static_routing/ip6_route_table.c	(revision 457)
@@ -0,0 +1,248 @@
+/**
+ * @file
+ * IPv6 static route table.
+ */
+
+/*
+ * Copyright (c) 2015 Nest Labs, Inc.
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * Author: Pradip De <pradipd@google.com>
+ *
+ *
+ * Please coordinate changes and requests with Pradip De
+ * <pradipd@google.com>
+ */
+
+#include "lwip/opt.h"
+
+#if LWIP_IPV6  /* don't build if not configured for use in lwipopts.h */
+
+#include "ip6_route_table.h"
+#include "lwip/def.h"
+#include "lwip/mem.h"
+#include "lwip/netif.h"
+#include "lwip/ip6.h"
+#include "lwip/ip6_addr.h"
+#include "lwip/nd6.h"
+#include "lwip/debug.h"
+#include "lwip/stats.h"
+
+#include "string.h"
+
+static struct ip6_route_entry static_route_table[LWIP_IPV6_NUM_ROUTE_ENTRIES];
+
+/**
+ * Add the ip6 prefix route and target netif into the static route table while
+ * keeping all entries sorted in decreasing order of prefix length.
+ * 1. Search from the last entry up to find the correct slot to insert while
+ *    moving entries one position down to create room.
+ * 2. Insert into empty slot created.
+ *
+ * Subsequently, a linear search down the list can be performed to retrieve a
+ * matching route entry for a Longest Prefix Match.
+ *
+ * @param ip6_prefix the route prefix entry to add.
+ * @param netif pointer to target netif.
+ * @param gateway the gateway address to use to send through. Has to be link local.
+ * @param idx return value argument of index where route entry was added in table.
+ * @return ERR_OK  if addition was successful.
+ *         ERR_MEM if table is already full.
+ *         ERR_ARG if passed argument is bad or route already exists in table.
+ */
+err_t
+ip6_add_route_entry(const struct ip6_prefix *ip6_prefix, struct netif *netif, const ip6_addr_t *gateway, s8_t *idx)
+{
+  s8_t i = -1;
+  err_t retval = ERR_OK;
+
+  if (!ip6_prefix_valid(ip6_prefix->prefix_len) || (netif == NULL)) {
+    retval = ERR_ARG;
+    goto exit;
+  }
+
+  /* Check if an entry already exists with matching prefix; If so, replace it. */
+  for (i = 0; i < LWIP_IPV6_NUM_ROUTE_ENTRIES; i++) {
+    if ((ip6_prefix->prefix_len == static_route_table[i].prefix.prefix_len) &&
+        memcmp(&ip6_prefix->addr, &static_route_table[i].prefix.addr,
+               ip6_prefix->prefix_len / 8) == 0) {
+      /* Prefix matches; replace the netif with the one being added. */
+      goto insert;
+    }
+  }
+
+  /* Check if the table is full */
+  if (static_route_table[LWIP_IPV6_NUM_ROUTE_ENTRIES - 1].netif != NULL) {
+    retval = ERR_MEM;
+    goto exit;
+  }
+
+  /* Shift all entries down the table until slot is found */
+  for (i = LWIP_IPV6_NUM_ROUTE_ENTRIES - 1;
+       i > 0 && (ip6_prefix->prefix_len > static_route_table[i - 1].prefix.prefix_len); i--) {
+    SMEMCPY(&static_route_table[i], &static_route_table[i - 1], sizeof(struct ip6_route_entry));
+  }
+
+insert:
+  /* Insert into the slot selected */
+  SMEMCPY(&static_route_table[i].prefix, ip6_prefix, sizeof(struct ip6_prefix));
+  static_route_table[i].netif = netif;
+
+  /* Add gateway to route table */
+  static_route_table[i].gateway = gateway;
+
+  if (idx != NULL) {
+    *idx = i;
+  }
+
+exit:
+  return retval;
+}
+
+/**
+ * Removes the route entry from the static route table.
+ *
+ * @param ip6_prefix the route prefix entry to delete.
+ */
+void
+ip6_remove_route_entry(const struct ip6_prefix *ip6_prefix)
+{
+  int i, pos = -1;
+
+  for (i = 0; i < LWIP_IPV6_NUM_ROUTE_ENTRIES; i++) {
+    /* compare prefix to find position to delete */
+    if (ip6_prefix->prefix_len == static_route_table[i].prefix.prefix_len &&
+        memcmp(&ip6_prefix->addr, &static_route_table[i].prefix.addr,
+               ip6_prefix->prefix_len / 8) == 0) {
+      pos = i;
+      break;
+    }
+  }
+
+  if (pos >= 0) {
+    /* Shift everything beyond pos one slot up */
+    for (i = pos; i < LWIP_IPV6_NUM_ROUTE_ENTRIES - 1; i++) {
+      SMEMCPY(&static_route_table[i], &static_route_table[i+1], sizeof(struct ip6_route_entry));
+      if (static_route_table[i].netif == NULL) {
+        break;
+      }
+    }
+    /* Zero the remaining entries */
+    for (; i < LWIP_IPV6_NUM_ROUTE_ENTRIES; i++) {
+      ip6_addr_set_zero((&static_route_table[i].prefix.addr));
+      static_route_table[i].netif = NULL;
+    }
+  }
+}
+
+/**
+ * Finds the appropriate route entry in the static route table corresponding to the given
+ * destination IPv6 address. Since the entries in the route table are kept sorted in decreasing
+ * order of prefix length, a linear search down the list is performed to retrieve a matching
+ * index.
+ *
+ * @param ip6_dest_addr the destination address to match
+ * @return the idx of the found route entry; -1 if not found.
+ */
+s8_t
+ip6_find_route_entry(const ip6_addr_t *ip6_dest_addr)
+{
+  s8_t i, idx = -1;
+
+  /* Search prefix in the sorted(decreasing order of prefix length) list */
+  for(i = 0; i < LWIP_IPV6_NUM_ROUTE_ENTRIES; i++) {
+    if (memcmp(ip6_dest_addr, &static_route_table[i].prefix.addr,
+        static_route_table[i].prefix.prefix_len / 8) == 0) {
+      idx = i;
+      break;
+    }
+  }
+
+  return idx;
+}
+
+/**
+ * Finds the appropriate network interface for a given IPv6 address from a routing table with
+ * static IPv6 routes.
+ *
+ * @param src the source IPv6 address, if known
+ * @param dest the destination IPv6 address for which to find the route
+ * @return the netif on which to send to reach dest
+ */
+struct netif *
+ip6_static_route(const ip6_addr_t *src, const ip6_addr_t *dest)
+{
+  int i;
+
+  LWIP_UNUSED_ARG(src);
+
+  /* Perform table lookup */
+  i = ip6_find_route_entry(dest);
+
+  if (i >= 0) {
+    return static_route_table[i].netif;
+  } else {
+    return NULL;
+  }
+}
+
+/**
+ * Finds the gateway IP6 address for a given destination IPv6 address and target netif
+ * from a routing table with static IPv6 routes.
+ *
+ * @param netif the netif used for sending
+ * @param dest the destination IPv6 address
+ * @return the ip6 address of the gateway to forward packet to
+ */
+const ip6_addr_t *
+ip6_get_gateway(struct netif *netif, const ip6_addr_t *dest)
+{
+  const ip6_addr_t *ret_gw = NULL;
+  const int i = ip6_find_route_entry(dest);
+
+  LWIP_UNUSED_ARG(netif);
+  
+  if (i >= 0) {
+    if (static_route_table[i].gateway != NULL) {
+      ret_gw = static_route_table[i].gateway;
+    }
+  }
+
+  return ret_gw;
+}
+
+/**
+ * Returns the top of the route table.
+ * This should be used for debug printing only.
+ *
+ * @return the top of the route table.
+ */
+const struct ip6_route_entry *
+ip6_get_route_table(void)
+{
+    return static_route_table;
+}
+
+#endif /* LWIP_IPV6 */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/addons/ipv6_static_routing/ip6_route_table.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/addons/ipv6_static_routing/ip6_route_table.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/addons/ipv6_static_routing/ip6_route_table.h	(revision 457)
@@ -0,0 +1,94 @@
+/**
+ * @file
+ *
+ * IPv6 static route table.
+ */
+
+/*
+ * Copyright (c) 2015 Nest Labs, Inc.
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * Author: Pradip De <pradipd@google.com>
+ *
+ *
+ * Please coordinate changes and requests with Pradip De
+ * <pradipd@google.com>
+ */
+
+#ifndef __LWIP_IP6_ROUTE_TABLE_H__
+#define __LWIP_IP6_ROUTE_TABLE_H__
+
+#include "lwip/opt.h"
+
+#if LWIP_IPV6  /* don't build if not configured for use in lwipopts.h */
+
+#include "lwip/ip6_addr.h"
+#include "lwip/err.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct netif;
+  
+/**
+ * LWIP_IPV6_NUM_ROUTES: Number of IPV6 routes that can be kept in the static route table.
+ */
+#ifndef LWIP_IPV6_NUM_ROUTE_ENTRIES
+#define LWIP_IPV6_NUM_ROUTE_ENTRIES         (8)
+#endif
+
+#define IP6_MAX_PREFIX_LEN                  (128)
+#define IP6_PREFIX_ALLOWED_GRANULARITY      (8)
+/* Prefix length cannot be greater than 128 bits and needs to be at a byte boundary */
+#define ip6_prefix_valid(prefix_len)        (((prefix_len) <= IP6_MAX_PREFIX_LEN) &&                 \
+                                             (((prefix_len) % IP6_PREFIX_ALLOWED_GRANULARITY) == 0))
+
+struct ip6_prefix {
+  ip6_addr_t addr;
+  u8_t prefix_len; /* prefix length in bits at byte boundaries */
+};
+
+struct ip6_route_entry {
+  struct ip6_prefix prefix;
+  struct netif *netif;
+  const ip6_addr_t *gateway;
+};
+
+err_t ip6_add_route_entry(const struct ip6_prefix *ip6_prefix, struct netif *netif,
+                          const ip6_addr_t *gateway, s8_t *idx);
+void ip6_remove_route_entry(const struct ip6_prefix *ip6_prefix);
+s8_t ip6_find_route_entry(const ip6_addr_t *ip6_dest_addr);
+struct netif *ip6_static_route(const ip6_addr_t *src, const ip6_addr_t *dest);
+const ip6_addr_t *ip6_get_gateway(struct netif *netif, const ip6_addr_t *dest);
+const struct ip6_route_entry *ip6_get_route_table(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LWIP_IPV6 */
+
+#endif /* __LWIP_IP6_ROUTE_TABLE_H__ */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/addons/netconn/external_resolve/dnssd.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/addons/netconn/external_resolve/dnssd.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/addons/netconn/external_resolve/dnssd.c	(revision 457)
@@ -0,0 +1,164 @@
+/**
+ * @file
+ * DNS-SD APIs used by LWIP_HOOK_NETCONN_EXTERNAL_RESOLVE
+ *
+ * This implementation assumes the DNS-SD API implementation (most likely provided by
+ * mDNSResponder) is implemented in the same process space as LwIP and can directly
+ * invoke the callback for DNSServiceGetAddrInfo.  This is the typical deployment in
+ * an embedded environment where as a traditional OS requires pumping the callback results
+ * through an IPC mechanism (see DNSServiceRefSockFD/DNSServiceProcessResult)
+ *
+ * @defgroup dnssd DNS-SD
+ * @ingroup dns
+ */
+
+/*
+ * Copyright (c) 2017 Joel Cunningham, Garmin International, Inc. <joel.cunningham@garmin.com>
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Joel Cunningham <joel.cunningham@me.com>
+ *
+ */
+#include "lwip/opt.h"
+
+#include "lwip/err.h"
+#include "lwip/inet.h"
+#include "lwip/sockets.h"
+#include "lwip/sys.h"
+
+#include "dnssd.h"
+
+/* External headers */
+#include <string.h>
+#include <dns_sd.h>
+
+/* This timeout should allow for multiple queries.
+mDNSResponder has the following query timeline:
+  Query 1: time = 0s
+  Query 2: time = 1s
+  Query 3: time = 4s
+*/
+#define GETADDR_TIMEOUT_MS  5000
+#define LOCAL_DOMAIN        ".local"
+
+/* Only consume .local hosts */
+#ifndef CONSUME_LOCAL_ONLY
+#define CONSUME_LOCAL_ONLY  1
+#endif
+
+struct addr_clbk_msg {
+  sys_sem_t sem;
+  struct sockaddr_storage addr;
+  err_t err;
+};
+
+static void addr_info_callback(DNSServiceRef ref, DNSServiceFlags flags, u32_t interface_index,
+                               DNSServiceErrorType error_code, char const* hostname,
+                               const struct sockaddr* address, u32_t ttl, void* context);
+
+int
+lwip_dnssd_gethostbyname(const char *name, ip_addr_t *addr, u8_t addrtype, err_t *err)
+{
+  DNSServiceErrorType result;
+  DNSServiceRef ref;
+  struct addr_clbk_msg msg;
+  char *p;
+
+  /* @todo: use with IPv6 */
+  LWIP_UNUSED_ARG(addrtype);
+
+#if CONSUME_LOCAL_ONLY
+  /* check if this is a .local host. If it is, then we consume the query */
+  p = strstr(name, LOCAL_DOMAIN);
+  if (p == NULL) {
+    return 0; /* not consumed */
+  }
+  p += (sizeof(LOCAL_DOMAIN) - 1);
+  /* check to make sure .local isn't a substring (only allow .local\0 or .local.\0) */
+  if ((*p != '.' && *p != '\0') ||
+      (*p == '.' && *(p + 1) != '\0')) {
+    return 0; /* not consumed */
+  }
+#endif /* CONSUME_LOCAL_ONLY */
+
+  msg.err = sys_sem_new(&msg.sem, 0);
+  if (msg.err != ERR_OK) {
+    goto query_done;
+  }
+
+  msg.err = ERR_TIMEOUT;
+  result = DNSServiceGetAddrInfo(&ref, 0, 0, kDNSServiceProtocol_IPv4, name, addr_info_callback, &msg);
+  if (result == kDNSServiceErr_NoError) {
+    sys_arch_sem_wait(&msg.sem, GETADDR_TIMEOUT_MS);
+    DNSServiceRefDeallocate(ref);
+
+    /* We got a response */
+    if (msg.err == ERR_OK) {
+      struct sockaddr_in* addr_in = (struct sockaddr_in *)&msg.addr;
+      if (addr_in->sin_family == AF_INET) {
+        inet_addr_to_ip4addr(ip_2_ip4(addr), &addr_in->sin_addr);
+      } else {
+        /* @todo add IPv6 support */
+        msg.err = ERR_VAL;
+      }
+    }
+  }
+  sys_sem_free(&msg.sem);
+
+/* Query has been consumed and is finished */
+query_done:
+*err = msg.err;
+return 1;
+}
+
+static void
+addr_info_callback(DNSServiceRef ref, DNSServiceFlags flags, u32_t interface_index,
+                   DNSServiceErrorType error_code, char const* hostname,
+                   const struct sockaddr* address, u32_t ttl, void* context)
+{
+  struct addr_clbk_msg* msg = (struct addr_clbk_msg*)context;
+  struct sockaddr_in*  addr_in = (struct sockaddr_in *)address;
+
+  LWIP_UNUSED_ARG(ref);
+  LWIP_UNUSED_ARG(flags);
+  LWIP_UNUSED_ARG(interface_index);
+  LWIP_UNUSED_ARG(hostname);
+  LWIP_UNUSED_ARG(ttl);
+  LWIP_UNUSED_ARG(context);
+
+  if ((error_code == kDNSServiceErr_NoError) &&
+      (addr_in->sin_family == AF_INET)) {
+    MEMCPY(&msg->addr, addr_in, sizeof(*addr_in));
+    msg->err = ERR_OK;
+  }
+  else {
+   /* @todo add IPv6 support */
+   msg->err = ERR_VAL;
+  }
+
+  sys_sem_signal(&msg->sem);
+} /* addr_info_callback() */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/addons/netconn/external_resolve/dnssd.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/addons/netconn/external_resolve/dnssd.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/addons/netconn/external_resolve/dnssd.h	(revision 457)
@@ -0,0 +1,50 @@
+/**
+ * @file
+ * DNS-SD APIs used by LWIP_HOOK_NETCONN_EXTERNAL_RESOLVE
+ *
+ * @defgroup dnssd DNS-SD
+ * @ingroup dns
+ */
+
+/*
+ * Copyright (c) 2017 Joel Cunningham, Garmin International, Inc. <joel.cunningham@garmin.com>
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Joel Cunningham <joel.cunningham@me.com>
+ *
+ */
+#include "lwip/opt.h"
+
+#ifndef LWIP_HDR_DNSSD_H
+#define LWIP_HDR_DNSSD_H
+
+#include "lwip/err.h"
+#include "lwip/ip_addr.h"
+
+int lwip_dnssd_gethostbyname(const char *name, ip_addr_t *addr, u8_t addrtype, err_t *err);
+
+#endif /* LWIP_HDR_DNSSD_H */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/addons/tcp_isn/tcp_isn.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/addons/tcp_isn/tcp_isn.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/addons/tcp_isn/tcp_isn.c	(revision 457)
@@ -0,0 +1,182 @@
+/**
+ * @file
+ *
+ * Reference implementation of the TCP ISN algorithm standardized in RFC 6528.
+ * Produce TCP Initial Sequence Numbers by combining an MD5-generated hash
+ * based on the new TCP connection's identity and a stable secret, with the
+ * current time at 4-microsecond granularity.
+ *
+ * Specifically, the implementation uses MD5 to compute a hash of the input
+ * buffer, which contains both the four-tuple of the new TCP connection (local
+ * and remote IP address and port), as well as a 16-byte secret to make the
+ * results unpredictable to external parties.  The secret must be given at
+ * initialization time and should ideally remain the same across system
+ * reboots.  To be sure: the spoofing-resistance of the resulting ISN depends
+ * mainly on the strength of the supplied secret!
+ *
+ * The implementation takes 32 bits from the computed hash, and adds to it the
+ * current time, in 4-microsecond units.  The current time is computed from a
+ * boot time given at initialization, and the current uptime as provided by
+ * sys_now().  Thus, it assumes that sys_now() returns a time value that is
+ * relative to the boot time, i.e., that it starts at 0 at system boot, and
+ * only ever increases monotonically.
+ *
+ * For efficiency reasons, a single MD5 input buffer is used, and partially
+ * filled in at initialization time.  Specifically, of this 64-byte buffer, the
+ * first 36 bytes are used for the four-way TCP tuple data, followed by the
+ * 16-byte secret, followed by 12-byte zero padding.  The 64-byte size of the
+ * buffer should achieve the best performance for the actual MD5 computation.
+ *
+ * Basic usage:
+ *
+ * 1. in your lwipopts.h, add the following lines:
+ *
+ *    #include <lwip/arch.h>
+ *    struct ip_addr;
+ *    u32_t lwip_hook_tcp_isn(const struct ip_addr *local_ip, u16_t local_port,
+ *      const struct ip_addr *remote_ip, u16_t remote_port);
+ *   "#define LWIP_HOOK_TCP_ISN lwip_hook_tcp_isn";
+ *
+ * 2. from your own code, call lwip_init_tcp_isn() at initialization time, with
+ *    appropriate parameters.
+ */
+
+/*
+ * Copyright (c) 2016 The MINIX 3 Project.
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * Author: David van Moolenbroek <david@minix3.org>
+ */
+
+#include "tcp_isn.h"
+#include "lwip/ip_addr.h"
+#include "lwip/sys.h"
+#include <string.h>
+
+#ifdef LWIP_HOOK_TCP_ISN
+
+/* pull in md5 of ppp? */
+#include "netif/ppp/ppp_opts.h"
+#if !PPP_SUPPORT || (!LWIP_USE_EXTERNAL_POLARSSL && !LWIP_USE_EXTERNAL_MBEDTLS)
+#undef  LWIP_INCLUDED_POLARSSL_MD5
+#define LWIP_INCLUDED_POLARSSL_MD5 1
+#include "netif/ppp/polarssl/md5.h"
+#endif
+
+static u8_t input[64];
+static u32_t base_time;
+
+/**
+ * Initialize the TCP ISN module, with the boot time and a secret.
+ *
+ * @param boot_time Wall clock boot time of the system, in seconds.
+ * @param secret_16_bytes A 16-byte secret used to randomize the TCP ISNs.
+ */
+void
+lwip_init_tcp_isn(u32_t boot_time, const u8_t *secret_16_bytes)
+{
+  /* Initialize the input buffer with the secret and trailing zeroes. */
+  memset(input, 0, sizeof(input));
+
+  MEMCPY(&input[36], secret_16_bytes, 16);
+
+  /* Save the boot time in 4-us units. Overflow is no problem here. */
+  base_time = boot_time * 250000;
+}
+
+/**
+ * Hook to generate an Initial Sequence Number (ISN) for a new TCP connection.
+ *
+ * @param local_ip The local IP address.
+ * @param local_port The local port number, in host-byte order.
+ * @param remote_ip The remote IP address.
+ * @param remote_port The remote port number, in host-byte order.
+ * @return The ISN to use for the new TCP connection.
+ */
+u32_t
+lwip_hook_tcp_isn(const ip_addr_t *local_ip, u16_t local_port,
+    const ip_addr_t *remote_ip, u16_t remote_port)
+{
+  md5_context ctx;
+  u8_t output[16];
+  u32_t isn;
+
+#if LWIP_IPV4 && LWIP_IPV6
+  if (IP_IS_V6(local_ip))
+#endif /* LWIP_IPV4 && LWIP_IPV6 */
+#if LWIP_IPV6
+  {
+    const ip6_addr_t *local_ip6, *remote_ip6;
+
+    local_ip6  = ip_2_ip6(local_ip);
+    remote_ip6 = ip_2_ip6(remote_ip);
+
+    SMEMCPY(&input[0],  &local_ip6->addr,  16);
+    SMEMCPY(&input[16], &remote_ip6->addr, 16);
+  }
+#endif /* LWIP_IPV6 */
+#if LWIP_IPV4 && LWIP_IPV6
+  else
+#endif /* LWIP_IPV4 && LWIP_IPV6 */
+#if LWIP_IPV4
+  {
+    const ip4_addr_t *local_ip4, *remote_ip4;
+
+    local_ip4  = ip_2_ip4(local_ip);
+    remote_ip4 = ip_2_ip4(remote_ip);
+
+    /* Represent IPv4 addresses as IPv4-mapped IPv6 addresses, to ensure that
+     * the IPv4 and IPv6 address spaces are completely disjoint. */
+    memset(&input[0], 0, 10);
+    input[10] = 0xff;
+    input[11] = 0xff;
+    SMEMCPY(&input[12], &local_ip4->addr, 4);
+    memset(&input[16], 0, 10);
+    input[26] = 0xff;
+    input[27] = 0xff;
+    SMEMCPY(&input[28], &remote_ip4->addr, 4);
+  }   
+#endif /* LWIP_IPV4 */
+
+  input[32] = (u8_t)(local_port >> 8);
+  input[33] = (u8_t)(local_port & 0xff);
+  input[34] = (u8_t)(remote_port >> 8);
+  input[35] = (u8_t)(remote_port & 0xff);
+
+  /* The secret and padding are already filled in. */
+
+  /* Generate the hash, using MD5. */
+  md5_starts(&ctx);
+  md5_update(&ctx, input, sizeof(input));
+  md5_finish(&ctx, output);
+
+  /* Arbitrarily take the first 32 bits from the generated hash. */
+  MEMCPY(&isn, output, sizeof(isn));
+
+  /* Add the current time in 4-microsecond units. */
+  return isn + base_time + sys_now() * 250;
+}
+
+#endif /* LWIP_HOOK_TCP_ISN */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/addons/tcp_isn/tcp_isn.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/addons/tcp_isn/tcp_isn.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/addons/tcp_isn/tcp_isn.h	(revision 457)
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2016 The MINIX 3 Project.
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * Author: David van Moolenbroek <david@minix3.org>
+ */
+
+#ifndef LWIP_HDR_CONTRIB_ADDONS_TCP_ISN_H
+#define LWIP_HDR_CONTRIB_ADDONS_TCP_ISN_H
+
+#include "lwip/opt.h"
+#include "lwip/ip_addr.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void lwip_init_tcp_isn(u32_t boot_time, const u8_t *secret_16_bytes);
+u32_t lwip_hook_tcp_isn(const ip_addr_t *local_ip, u16_t local_port,
+                        const ip_addr_t *remote_ip, u16_t remote_port);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LWIP_HDR_CONTRIB_ADDONS_TCP_ISN_H */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/addons/tcp_md5/README
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/addons/tcp_md5/README	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/addons/tcp_md5/README	(revision 457)
@@ -0,0 +1,27 @@
+This folder provides an example implementation of how to add custom tcp header
+options and custom socket options.
+
+It does this by implementing the (seldom used) tcp md5 signature.
+
+To enable it, add an LWIP_HOOK_FILENAME hook file, include tcp_md5.h in it and
+define these hooks:
+
+  #define LWIP_HOOK_TCP_INPACKET_PCB(pcb, hdr, optlen, opt1len, opt2, p) tcp_md5_check_inpacket(pcb, hdr, optlen, opt1len, opt2, p)
+  #define LWIP_HOOK_TCP_OPT_LENGTH_SEGMENT(pcb, internal_len)            tcp_md5_get_additional_option_length(pcb, internal_len)
+  #define LWIP_HOOK_TCP_ADD_TX_OPTIONS(p, hdr, pcb, opts)                tcp_md5_add_tx_options(p, hdr, pcb,  opts)
+  #define LWIP_HOOK_SOCKETS_SETSOCKOPT(s, sock, level, optname, optval, optlen, err) tcp_md5_setsockopt_hook(sock, level, optname, optval, optlen, err)
+
+Then, in your sockets application, enable md5 signature on a socket like this:
+
+  struct tcp_md5sig md5;
+  struct sockaddr_storage addr_remote; /* Initialize this to remote address and port */
+  memcpy(&md5.tcpm_addr, &addr_remote, sizeof(addr_remote));
+  strcpy(md5.tcpm_key, key); /* this is the md5 key per connection */
+  md5.tcpm_keylen = strlen(key);
+  if ((ret = setsockopt(sockfd, IPPROTO_TCP, TCP_MD5SIG, &md5, sizeof(md5))) < 0) {
+    perror("setsockopt TCP_MD5SIG");
+    return;
+  }
+
+After that, your connection (client) or all incoming connections (server) require
+tcp md5 signatures.
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/addons/tcp_md5/tcp_md5.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/addons/tcp_md5/tcp_md5.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/addons/tcp_md5/tcp_md5.c	(revision 457)
@@ -0,0 +1,534 @@
+/**
+ * @file: An implementation of TCP MD5 signatures by using various hooks in
+ * lwIP to implement custom tcp options and custom socket options.
+ */
+
+/*
+ * Copyright (c) 2018 Simon Goldschmidt
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * Author: Simon Goldschmidt <goldsimon@gmx.de>
+ */
+
+#include "tcp_md5.h"
+#include "lwip/ip_addr.h"
+#include "lwip/sys.h"
+#include "lwip/prot/tcp.h"
+#include "lwip/priv/tcp_priv.h"
+#include "lwip/sockets.h"
+#include "lwip/priv/sockets_priv.h"
+#include "lwip/api.h"
+#include <string.h>
+
+/* pull in md5 of ppp? */
+#include "netif/ppp/ppp_opts.h"
+#if !PPP_SUPPORT || (!LWIP_USE_EXTERNAL_POLARSSL && !LWIP_USE_EXTERNAL_MBEDTLS)
+#undef  LWIP_INCLUDED_POLARSSL_MD5
+#define LWIP_INCLUDED_POLARSSL_MD5 1
+#include "netif/ppp/polarssl/md5.h"
+#endif
+
+#if !LWIP_TCP_PCB_NUM_EXT_ARGS
+#error tcp_md5 needs LWIP_TCP_PCB_NUM_EXT_ARGS
+#endif
+
+#define LWIP_TCP_OPT_MD5          19 /* number of the md5 option */
+#define LWIP_TCP_OPT_LEN_MD5      18 /* length of the md5 option */
+#define LWIP_TCP_OPT_LEN_MD5_OUT  20 /* 18 + alignment */
+
+#define LWIP_TCP_MD5_DIGEST_LEN   16
+
+/* This keeps the md5 state internally */
+struct tcp_md5_conn_info {
+  struct tcp_md5_conn_info *next;
+  ip_addr_t remote_addr;
+  u16_t remote_port;
+  u8_t key[TCP_MD5SIG_MAXKEYLEN];
+  u16_t key_len;
+};
+
+/* Callback function prototypes: */
+static void tcp_md5_extarg_destroy(u8_t id, void *data);
+static err_t tcp_md5_extarg_passive_open(u8_t id, struct tcp_pcb_listen *lpcb, struct tcp_pcb *cpcb);
+/* Define our tcp ext arg callback structure: */
+const struct tcp_ext_arg_callbacks tcp_md5_ext_arg_callbacks = {
+  tcp_md5_extarg_destroy,
+  tcp_md5_extarg_passive_open
+};
+
+static u8_t tcp_md5_extarg_id = LWIP_TCP_PCB_NUM_EXT_ARG_ID_INVALID;
+static u8_t tcp_md5_opts_buf[40];
+
+/** Initialize this module (allocates a tcp ext arg id) */
+void
+tcp_md5_init(void)
+{
+  tcp_md5_extarg_id = tcp_ext_arg_alloc_id();
+}
+
+/* Create a conn-info structure that holds the md5 state per connection */
+static struct tcp_md5_conn_info *
+tcp_md5_conn_info_alloc(void)
+{
+  return (struct tcp_md5_conn_info *)mem_malloc(sizeof(struct tcp_md5_conn_info));
+}
+
+/* Frees a conn-info structure that holds the md5 state per connection */
+static void
+tcp_md5_conn_info_free(struct tcp_md5_conn_info *info)
+{
+  mem_free(info);
+}
+
+/* A pcb is about to be destroyed. Free its extdata */
+static void
+tcp_md5_extarg_destroy(u8_t id, void *data)
+{
+  struct tcp_md5_conn_info *iter;
+
+  LWIP_ASSERT("tcp_md5_extarg_id != LWIP_TCP_PCB_NUM_EXT_ARG_ID_INVALID",
+    tcp_md5_extarg_id != LWIP_TCP_PCB_NUM_EXT_ARG_ID_INVALID);
+  LWIP_ASSERT("id == tcp_md5_extarg_id", id == tcp_md5_extarg_id);
+  LWIP_UNUSED_ARG(id);
+
+  iter = (struct tcp_md5_conn_info *)data;
+  while (iter != NULL) {
+    struct tcp_md5_conn_info *info = iter;
+    iter = iter->next;
+    tcp_md5_conn_info_free(info);
+  }
+}
+
+/* Try to find an md5 connection info for the specified remote connection */
+static struct tcp_md5_conn_info *
+tcp_md5_get_info(const struct tcp_pcb *pcb, const ip_addr_t *remote_ip, u16_t remote_port)
+{
+  if (pcb != NULL) {
+    struct tcp_md5_conn_info *info = (struct tcp_md5_conn_info *)tcp_ext_arg_get(pcb, tcp_md5_extarg_id);
+    while (info != NULL) {
+      if (ip_addr_cmp(&info->remote_addr, remote_ip)) {
+        if (info->remote_port == remote_port) {
+          return info;
+        }
+      }
+      info = info->next;
+    }
+  }
+  return NULL;
+}
+
+/* Passive open: copy md5 connection info from listen pcb to connection pcb
+ * or return error (connection will be closed)
+ */
+static err_t
+tcp_md5_extarg_passive_open(u8_t id, struct tcp_pcb_listen *lpcb, struct tcp_pcb *cpcb)
+{
+  struct tcp_md5_conn_info *iter;
+
+  LWIP_ASSERT("lpcb != NULL", lpcb != NULL);
+  LWIP_ASSERT("cpcb != NULL", cpcb != NULL);
+  LWIP_ASSERT("tcp_md5_extarg_id != LWIP_TCP_PCB_NUM_EXT_ARG_ID_INVALID",
+    tcp_md5_extarg_id != LWIP_TCP_PCB_NUM_EXT_ARG_ID_INVALID);
+  LWIP_ASSERT("id == tcp_md5_extarg_id", id == tcp_md5_extarg_id);
+  LWIP_UNUSED_ARG(id);
+
+  iter = (struct tcp_md5_conn_info *)tcp_ext_arg_get((struct tcp_pcb *)lpcb, id);
+  while (iter != NULL) {
+    if (iter->remote_port == cpcb->remote_port) {
+      if (ip_addr_cmp(&iter->remote_addr, &cpcb->remote_ip)) {
+        struct tcp_md5_conn_info *info = tcp_md5_conn_info_alloc();
+        if (info != NULL) {
+          memcpy(info, iter, sizeof(struct tcp_md5_conn_info));
+          tcp_ext_arg_set(cpcb, id, info);
+          tcp_ext_arg_set_callbacks(cpcb, id, &tcp_md5_ext_arg_callbacks);
+          return ERR_OK;
+        } else {
+          return ERR_MEM;
+        }
+      }
+    }
+    iter = iter->next;
+  }
+  /* remote connection not found */
+  return ERR_VAL;
+}
+
+/* Parse tcp header options and return 1 if an md5 signature option was found */
+static int
+tcp_md5_parseopt(const u8_t *opts, u16_t optlen, u8_t *md5_digest_out)
+{
+  u8_t data;
+  u16_t optidx;
+
+  /* Parse the TCP MSS option, if present. */
+  if (optlen != 0) {
+    for (optidx = 0; optidx < optlen; ) {
+      u8_t opt = opts[optidx++];
+      switch (opt) {
+        case LWIP_TCP_OPT_EOL:
+          /* End of options. */
+          LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_parseopt: EOL\n"));
+          return 0;
+        case LWIP_TCP_OPT_NOP:
+          /* NOP option. */
+          LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_parseopt: NOP\n"));
+          break;
+        case LWIP_TCP_OPT_MD5:
+          LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_parseopt: MD5\n"));
+          if (opts[optidx++] != LWIP_TCP_OPT_LEN_MD5 || (optidx - 2 + LWIP_TCP_OPT_LEN_MD5) > optlen) {
+            /* Bad length */
+            LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_parseopt: bad length\n"));
+            return 0;
+          }
+          /* An MD5 option with the right option length. */
+          memcpy(md5_digest_out, &opts[optidx], LWIP_TCP_MD5_DIGEST_LEN);
+          /* no need to process the options further */
+          return 1;
+          break;
+        default:
+          LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_parseopt: other\n"));
+          data = opts[optidx++];
+          if (data < 2) {
+            LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_parseopt: bad length\n"));
+            /* If the length field is zero, the options are malformed
+               and we don't process them further. */
+            return 0;
+          }
+          /* All other options have a length field, so that we easily
+             can skip past them. */
+          optidx += data - 2;
+      }
+    }
+  }
+  return 0;
+}
+
+/* Get tcp options into contiguous memory. May be required if input pbufs
+ * are chained.
+ */
+static const u8_t*
+tcp_md5_options_singlebuf(struct tcp_hdr *hdr, u16_t optlen, u16_t opt1len, u8_t *opt2)
+{
+  const u8_t *opts;
+  LWIP_ASSERT("hdr != NULL", hdr != NULL);
+  LWIP_ASSERT("optlen >= opt1len", optlen >= opt1len);
+  opts = (const u8_t *)hdr + TCP_HLEN;
+  if (optlen == opt1len) {
+    /* arleady in one piece */
+    return opts;
+  }
+  if (optlen > sizeof(tcp_md5_opts_buf)) {
+    /* options too long */
+    return NULL;
+  }
+  LWIP_ASSERT("opt2 != NULL", opt2 != NULL);
+  /* copy first part */
+  memcpy(tcp_md5_opts_buf, opts, opt1len);
+  /* copy second part */
+  memcpy(&tcp_md5_opts_buf[opt1len], opt2, optlen - opt1len);
+  return tcp_md5_opts_buf;
+}
+
+/* Create the md5 digest for a given segment */
+static int
+tcp_md5_create_digest(const ip_addr_t *ip_src, const ip_addr_t *ip_dst, const struct tcp_hdr *hdr,
+                      const u8_t *key, size_t key_len, u8_t *digest_out, struct pbuf *p)
+{
+  md5_context ctx;
+  u8_t tmp8;
+  u16_t tmp16;
+  const size_t addr_len = IP_ADDR_RAW_SIZE(*ip_src);
+
+  if (p != NULL) {
+    LWIP_ASSERT("pbuf must not point to tcp header here!", (const void *)hdr != p->payload);
+  }
+
+  /* Generate the hash, using MD5. */
+  md5_starts(&ctx);
+  /* 1. the TCP pseudo-header (in the order: source IP address,
+          destination IP address, zero-padded protocol number, and
+          segment length) */
+  md5_update(&ctx, (const unsigned char*)ip_src, addr_len);
+  md5_update(&ctx, (const unsigned char*)ip_dst, addr_len);
+  tmp8 = 0; /* zero-padded */
+  md5_update(&ctx, &tmp8, 1);
+  tmp8 = IP_PROTO_TCP;
+  md5_update(&ctx, &tmp8, 1);
+  tmp16 = lwip_htons(TCPH_HDRLEN_BYTES(hdr) + (p ? p->tot_len : 0));
+  md5_update(&ctx, (const unsigned char*)&tmp16, 2);
+  /* 2. the TCP header, excluding options, and assuming a checksum of
+          zero */
+  md5_update(&ctx, (const unsigned char*)hdr, sizeof(struct tcp_hdr));
+  /* 3. the TCP segment data (if any) */
+  if ((p != NULL) && (p->tot_len != 0)) {
+    struct pbuf *q;
+    for (q = p; q != NULL; q = q->next) {
+      md5_update(&ctx, (const unsigned char*)q->payload, q->len);
+    }
+  }
+  /* 4. an independently-specified key or password, known to both TCPs
+          and presumably connection-specific */
+  md5_update(&ctx, key, key_len);
+
+  md5_finish(&ctx, digest_out);
+  return 1;
+}
+
+/* Duplicate a tcp header and make sure the fields are in network byte order */
+static void
+tcp_md5_dup_tcphdr(struct tcp_hdr *tcphdr_copy, const struct tcp_hdr *tcphdr_in, int tcphdr_in_is_host_order)
+{
+  memcpy(tcphdr_copy, tcphdr_in, sizeof(struct tcp_hdr));
+  tcphdr_copy->chksum = 0; /* checksum is zero for the pseudo header */
+  if (tcphdr_in_is_host_order) {
+    /* lwIP writes the TCP header values back to the buffer, we need to invert that here: */
+    tcphdr_copy->src = lwip_htons(tcphdr_copy->src);
+    tcphdr_copy->dest = lwip_htons(tcphdr_copy->dest);
+    tcphdr_copy->seqno = lwip_htonl(tcphdr_copy->seqno);
+    tcphdr_copy->ackno = lwip_htonl(tcphdr_copy->ackno);
+    tcphdr_copy->wnd = lwip_htons(tcphdr_copy->wnd);
+    tcphdr_copy->urgp = lwip_htons(tcphdr_copy->urgp);
+  }
+}
+
+/* Check if md5 is enabled on a given pcb */
+static int
+tcp_md5_is_enabled_on_pcb(const struct tcp_pcb *pcb)
+{
+  if (tcp_md5_extarg_id != LWIP_TCP_PCB_NUM_EXT_ARG_ID_INVALID) {
+    struct tcp_md5_conn_info *info = (struct tcp_md5_conn_info *)tcp_ext_arg_get(pcb, tcp_md5_extarg_id);
+    if (info != NULL) {
+      return 1;
+    }
+  }
+  return 0;
+}
+
+/* Check if md5 is enabled on a given listen pcb */
+static int
+tcp_md5_is_enabled_on_lpcb(const struct tcp_pcb_listen *lpcb)
+{
+  /* same as for connection pcbs */
+  return tcp_md5_is_enabled_on_pcb((const struct tcp_pcb *)lpcb);
+}
+
+/* Hook implementation for LWIP_HOOK_TCP_OPT_LENGTH_SEGMENT */
+u8_t
+tcp_md5_get_additional_option_length(const struct tcp_pcb *pcb, u8_t internal_option_length)
+{
+  if ((pcb != NULL) && tcp_md5_is_enabled_on_pcb(pcb)) {
+    u8_t new_option_length = internal_option_length + LWIP_TCP_OPT_LEN_MD5_OUT;
+    LWIP_ASSERT("overflow", new_option_length > internal_option_length);
+    LWIP_ASSERT("options too long", new_option_length <= TCP_MAX_OPTION_BYTES);
+    return new_option_length;
+  }
+  return internal_option_length;
+}
+
+/* Hook implementation for LWIP_HOOK_TCP_INPACKET_PCB when called for listen pcbs */
+static err_t
+tcp_md5_check_listen(struct tcp_pcb_listen* lpcb, struct tcp_hdr *hdr, u16_t optlen, u16_t opt1len, u8_t *opt2)
+{
+  LWIP_ASSERT("lpcb != NULL", lpcb != NULL);
+
+  if (tcp_md5_is_enabled_on_lpcb(lpcb)) {
+    const u8_t *opts;
+    u8_t digest_received[LWIP_TCP_MD5_DIGEST_LEN];
+    u8_t digest_calculated[LWIP_TCP_MD5_DIGEST_LEN];
+    const struct tcp_md5_conn_info *info = tcp_md5_get_info((struct tcp_pcb *)lpcb, ip_current_src_addr(), hdr->src);
+    if (info != NULL) {
+      opts = tcp_md5_options_singlebuf(hdr, optlen, opt1len, opt2);
+      if (opts != NULL) {
+        if (tcp_md5_parseopt(opts, optlen, digest_received)) {
+          struct tcp_hdr tcphdr_copy;
+          tcp_md5_dup_tcphdr(&tcphdr_copy, hdr, 1);
+          if (tcp_md5_create_digest(ip_current_src_addr(), ip_current_dest_addr(), &tcphdr_copy, info->key, info->key_len, digest_calculated, NULL)) {
+            /* everything set up, compare the digests */
+            if (!memcmp(digest_received, digest_calculated, LWIP_TCP_MD5_DIGEST_LEN)) {
+              /* equal */
+              return ERR_OK;
+            }
+            /* not equal */
+          }
+        }
+      }
+    }
+    /* md5 enabled on this pcb but no match or other error -> fail */
+    return ERR_VAL;
+  }
+  return ERR_OK;
+}
+
+/* Hook implementation for LWIP_HOOK_TCP_INPACKET_PCB */
+err_t
+tcp_md5_check_inpacket(struct tcp_pcb* pcb, struct tcp_hdr *hdr, u16_t optlen, u16_t opt1len, u8_t *opt2, struct pbuf *p)
+{
+  LWIP_ASSERT("pcb != NULL", pcb != NULL);
+
+  if (pcb->state == LISTEN) {
+    return tcp_md5_check_listen((struct tcp_pcb_listen *)pcb, hdr, optlen, opt1len, opt2);
+  }
+
+  if (tcp_md5_is_enabled_on_pcb(pcb)) {
+    const struct tcp_md5_conn_info *info = tcp_md5_get_info(pcb, ip_current_src_addr(), hdr->src);
+    if (info != NULL) {
+      const u8_t *opts;
+      u8_t digest_received[LWIP_TCP_MD5_DIGEST_LEN];
+      u8_t digest_calculated[LWIP_TCP_MD5_DIGEST_LEN];
+      opts = tcp_md5_options_singlebuf(hdr, optlen, opt1len, opt2);
+      if (opts != NULL) {
+        if (tcp_md5_parseopt(opts, optlen, digest_received)) {
+          struct tcp_hdr hdr_copy;
+          tcp_md5_dup_tcphdr(&hdr_copy, hdr, 1);
+          if (tcp_md5_create_digest(&pcb->remote_ip, &pcb->local_ip, &hdr_copy, info->key, info->key_len, digest_calculated, p)) {
+            /* everything set up, compare the digests */
+            if (!memcmp(digest_received, digest_calculated, LWIP_TCP_MD5_DIGEST_LEN)) {
+              /* equal */
+              return ERR_OK;
+            }
+            /* not equal */
+          }
+        }
+      }
+    }
+    /* md5 enabled on this pcb but no match or other error -> fail */
+    return ERR_VAL;
+  }
+  return ERR_OK;
+}
+
+/* Hook implementation for LWIP_HOOK_TCP_ADD_TX_OPTIONS */
+u32_t *
+tcp_md5_add_tx_options(struct pbuf *p, struct tcp_hdr *hdr, const struct tcp_pcb *pcb, u32_t *opts)
+{
+  LWIP_ASSERT("p != NULL", p != NULL);
+  LWIP_ASSERT("hdr != NULL", hdr != NULL);
+  LWIP_ASSERT("pcb != NULL", pcb != NULL);
+  LWIP_ASSERT("opts != NULL", opts != NULL);
+
+  if (tcp_md5_is_enabled_on_pcb(pcb)) {
+    u8_t digest_calculated[LWIP_TCP_MD5_DIGEST_LEN];
+    u32_t *opts_ret = opts + 5; /* we use 20 bytes: 2 bytes padding + 18 bytes for this option */
+    u8_t *ptr = (u8_t*)opts;
+
+    const struct tcp_md5_conn_info *info = tcp_md5_get_info(pcb, &pcb->remote_ip, pcb->remote_port);
+    if (info != NULL) {
+      struct tcp_hdr hdr_copy;
+      size_t hdrsize = TCPH_HDRLEN_BYTES(hdr);
+      tcp_md5_dup_tcphdr(&hdr_copy, hdr, 0);
+      /* p->payload points to the tcp header */
+      LWIP_ASSERT("p->payload == hdr", p->payload == hdr);
+      if (!pbuf_remove_header(p, hdrsize)) {
+        u8_t ret;
+        if (!tcp_md5_create_digest(&pcb->local_ip, &pcb->remote_ip, &hdr_copy, info->key, info->key_len, digest_calculated, p)) {
+          info = NULL;
+        }
+        ret = pbuf_add_header_force(p, hdrsize);
+        LWIP_ASSERT("tcp_md5_add_tx_options: pbuf_add_header_force failed", !ret);
+        LWIP_UNUSED_ARG(ret);
+      } else  {
+        LWIP_ASSERT("error", 0);
+      }
+    }
+    if (info == NULL) {
+      /* create an invalid signature by zeroing the digest */
+      memset(&digest_calculated, 0, sizeof(digest_calculated));
+    }
+
+    *ptr++ = LWIP_TCP_OPT_NOP;
+    *ptr++ = LWIP_TCP_OPT_NOP;
+    *ptr++ = LWIP_TCP_OPT_MD5;
+    *ptr++ = LWIP_TCP_OPT_LEN_MD5;
+    memcpy(ptr, digest_calculated, LWIP_TCP_MD5_DIGEST_LEN);
+    ptr += LWIP_TCP_MD5_DIGEST_LEN;
+    LWIP_ASSERT("ptr == opts_ret", ptr == (u8_t *)opts_ret);
+    return opts_ret;
+  }
+  return opts;
+}
+
+/* Hook implementation for LWIP_HOOK_SOCKETS_SETSOCKOPT */
+int
+tcp_md5_setsockopt_hook(struct lwip_sock *sock, int level, int optname, const void *optval, socklen_t optlen, int *err)
+{
+  LWIP_ASSERT("sock != NULL", sock != NULL);
+  LWIP_ASSERT("err != NULL", err != NULL);
+
+  if ((level == IPPROTO_TCP) && (optname == TCP_MD5SIG)) {
+    const struct tcp_md5sig *md5 = (const struct tcp_md5sig*)optval;
+    if ((optval == NULL) || (optlen < sizeof(struct tcp_md5sig))) {
+      *err = EINVAL;
+    } else {
+      if (sock->conn && (NETCONNTYPE_GROUP(netconn_type(sock->conn)) == NETCONN_TCP) && (sock->conn->pcb.tcp != NULL)) {
+        if (tcp_md5_extarg_id == LWIP_TCP_PCB_NUM_EXT_ARG_ID_INVALID) {
+          /* not initialized */
+          *err = EINVAL;
+        } else {
+          struct tcp_md5_conn_info *info = tcp_md5_conn_info_alloc();
+          if (info == NULL) {
+            *err = ENOMEM;
+          } else {
+            int addr_valid = 0;
+            /* OK, fill and link this request */
+            memcpy(info->key, md5->tcpm_key, TCP_MD5SIG_MAXKEYLEN);
+            info->key_len = md5->tcpm_keylen;
+            memset(&info->remote_addr, 0, sizeof(info->remote_addr));
+            if (md5->tcpm_addr.ss_family == AF_INET) {
+#if LWIP_IPV4
+              const struct sockaddr_in *sin = (const struct sockaddr_in *)&md5->tcpm_addr;
+              memcpy(&info->remote_addr, &sin->sin_addr, sizeof(sin->sin_addr));
+              IP_SET_TYPE_VAL(info->remote_addr, IPADDR_TYPE_V4);
+              info->remote_port = lwip_htons(sin->sin_port);
+              addr_valid = 1;
+#endif /* LWIP_IPV4 */
+            } else if (md5->tcpm_addr.ss_family == AF_INET6) {
+#if LWIP_IPV6
+              const struct sockaddr_in6 *sin6 = (const struct sockaddr_in6 *)&md5->tcpm_addr;
+              memcpy(&info->remote_addr, &sin6->sin6_addr, sizeof(sin6->sin6_addr));
+              IP_SET_TYPE_VAL(info->remote_addr, IPADDR_TYPE_V6);
+              info->remote_port = lwip_htons(sin6->sin6_port);
+              addr_valid = 1;
+#endif /* LWIP_IPV6 */
+            }
+            if (addr_valid) {
+              /* store it */
+              tcp_ext_arg_set_callbacks(sock->conn->pcb.tcp, tcp_md5_extarg_id, &tcp_md5_ext_arg_callbacks);
+              info->next = (struct tcp_md5_conn_info *)tcp_ext_arg_get(sock->conn->pcb.tcp, tcp_md5_extarg_id);
+              tcp_ext_arg_set(sock->conn->pcb.tcp, tcp_md5_extarg_id, info);
+            } else {
+              *err = EINVAL;
+              tcp_md5_conn_info_free(info);
+            }
+          }
+        }
+      } else {
+        /* not a tcp netconn */
+        *err = EINVAL;
+      }
+    }
+    return 1;
+  }
+  return 0;
+}
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/addons/tcp_md5/tcp_md5.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/addons/tcp_md5/tcp_md5.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/addons/tcp_md5/tcp_md5.h	(revision 457)
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 2018 Simon Goldschmidt
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * Author: Simon Goldschmidt <goldsimon@gmx.de>
+ *
+ * To use the hooks in this file, make sure this file is included in LWIP_HOOK_FILENAME
+ * and define these hooks:
+ *
+ * #define LWIP_HOOK_TCP_INPACKET_PCB(pcb, hdr, optlen, opt1len, opt2, p) tcp_md5_check_inpacket(pcb, hdr, optlen, opt1len, opt2, p)
+ * #define LWIP_HOOK_TCP_OPT_LENGTH_SEGMENT(pcb, internal_len)            tcp_md5_get_additional_option_length(pcb, internal_len)
+ * #define LWIP_HOOK_TCP_ADD_TX_OPTIONS(p, hdr, pcb, opts)                tcp_md5_add_tx_options(p, hdr, pcb,  opts)
+ *
+ * #define LWIP_HOOK_SOCKETS_SETSOCKOPT(s, sock, level, optname, optval, optlen, err) tcp_md5_setsockopt_hook(sock, level, optname, optval, optlen, err)
+ */
+
+#ifndef LWIP_HDR_CONTRIB_ADDONS_TCP_MD5_H
+#define LWIP_HDR_CONTRIB_ADDONS_TCP_MD5_H
+
+#include "lwip/opt.h"
+#include "lwip/ip_addr.h"
+#include "lwip/err.h"
+
+#include "lwip/priv/sockets_priv.h"
+#include "lwip/priv/tcp_priv.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* setsockopt definitions and structs: */
+
+/* This is the optname (for level = IPPROTO_TCP) */
+#ifndef TCP_MD5SIG
+#define TCP_MD5SIG 14
+#endif
+
+#define TCP_MD5SIG_MAXKEYLEN 80
+
+/* This is the optval type */
+struct tcp_md5sig {
+  struct  sockaddr_storage tcpm_addr;
+  u16_t   __tcpm_pad1;
+  u16_t   tcpm_keylen;
+  u32_t   __tcpm_pad2;
+  u8_t    tcpm_key[TCP_MD5SIG_MAXKEYLEN];
+};
+
+/* socket setsockopt hook: */
+int tcp_md5_setsockopt_hook(struct lwip_sock *sock, int level, int optname, const void *optval, u32_t optlen, int *err);
+
+/* Internal hook functions */
+void tcp_md5_init(void);
+err_t tcp_md5_check_inpacket(struct tcp_pcb* pcb, struct tcp_hdr *hdr, u16_t optlen, u16_t opt1len, u8_t *opt2, struct pbuf *p);
+u8_t tcp_md5_get_additional_option_length(const struct tcp_pcb *pcb, u8_t internal_option_length);
+u32_t *tcp_md5_add_tx_options(struct pbuf *p, struct tcp_hdr *hdr, const struct tcp_pcb *pcb, u32_t *opts);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LWIP_HDR_CONTRIB_ADDONS_TCP_MD5_H */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/CCodeGeneration/CCodeGeneration.csproj
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/CCodeGeneration/CCodeGeneration.csproj	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/CCodeGeneration/CCodeGeneration.csproj	(revision 457)
@@ -0,0 +1,67 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+    <ProductVersion>8.0.30703</ProductVersion>
+    <SchemaVersion>2.0</SchemaVersion>
+    <ProjectGuid>{7DA7C0AB-0982-4BF5-9324-F59A7A08D65B}</ProjectGuid>
+    <OutputType>Library</OutputType>
+    <AppDesignerFolder>Properties</AppDesignerFolder>
+    <RootNamespace>CCodeGeneration</RootNamespace>
+    <AssemblyName>CCodeGeneration</AssemblyName>
+    <TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
+    <FileAlignment>512</FileAlignment>
+    <TargetFrameworkProfile />
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+    <DebugSymbols>true</DebugSymbols>
+    <DebugType>full</DebugType>
+    <Optimize>false</Optimize>
+    <OutputPath>bin\Debug\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+    <DebugType>pdbonly</DebugType>
+    <Optimize>true</Optimize>
+    <OutputPath>bin\Release\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+  </PropertyGroup>
+  <ItemGroup>
+    <Reference Include="System" />
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="CFile.cs" />
+    <Compile Include="Code.cs" />
+    <Compile Include="CodeContainerBase.cs" />
+    <Compile Include="CodeElement.cs" />
+    <Compile Include="Comment.cs" />
+    <Compile Include="EmptyLine.cs" />
+    <Compile Include="Function.cs" />
+    <Compile Include="CGenerator.cs" />
+    <Compile Include="IfThenElse.cs" />
+    <Compile Include="PlainText.cs" />
+    <Compile Include="Switch.cs" />
+    <Compile Include="PP_If.cs" />
+    <Compile Include="PP_Ifdef.cs" />
+    <Compile Include="PP_Include.cs" />
+    <Compile Include="FunctionDeclaration.cs" />
+    <Compile Include="PP_Macro.cs" />
+    <Compile Include="Properties\AssemblyInfo.cs" />
+    <Compile Include="VariableDeclaration.cs" />
+    <Compile Include="VariablePrototype.cs" />
+    <Compile Include="VariableType.cs" />
+  </ItemGroup>
+  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
+       Other similar extension points exist, see Microsoft.Common.targets.
+  <Target Name="BeforeBuild">
+  </Target>
+  <Target Name="AfterBuild">
+  </Target>
+  -->
+</Project>
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/CCodeGeneration/CFile.cs
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/CCodeGeneration/CFile.cs	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/CCodeGeneration/CFile.cs	(revision 457)
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Martin Hentschel <info@cl-soft.de>
+ *
+ */
+
+using System;
+
+namespace CCodeGeneration
+{
+	public class CFile: CodeContainerBase
+	{
+		public CFile()
+		{
+			base.IncreaseLevel = false;
+		}
+
+		public void Save(CGenerator generator)
+		{
+			if (generator == null)
+			{
+				throw new ArgumentNullException("generator");
+			}
+
+			this.GenerateCode(0, generator);
+		}
+	}
+}
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/CCodeGeneration/CGenerator.cs
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/CCodeGeneration/CGenerator.cs	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/CCodeGeneration/CGenerator.cs	(revision 457)
@@ -0,0 +1,119 @@
+/*
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Martin Hentschel <info@cl-soft.de>
+ *
+ */
+
+using System;
+using System.IO;
+
+namespace CCodeGeneration
+{
+	public class CGenerator
+	{
+		public TextWriter OutputStream { get; private set; }
+		public string File { get; private set; }
+		public uint IndentCount { get; private set; }
+		public string IndentChar { get; private set; }
+		public string NewLine { get; private set; }
+
+		public CGenerator(System.IO.TextWriter outputStream, string file, uint indentCount, string indentChar, string newLine)
+		{
+			this.OutputStream = outputStream;
+			this.File     = file;
+			this.IndentCount  = indentCount;
+			this.IndentChar   = indentChar;
+			this.NewLine      = newLine;
+		}
+
+		public string FileName
+		{
+			get
+			{
+				if (!String.IsNullOrWhiteSpace(this.File))
+				{
+					return Path.GetFileName(this.File);
+				}
+
+				return null;
+			}
+		}
+
+		public void WriteSequence(string value, uint repetitions)
+		{
+			while (repetitions > 0)
+			{
+				this.OutputStream.Write(value);
+				repetitions--;
+			}
+		}
+
+		public void IndentLine(int level)
+		{
+			while (level > 0)
+			{
+				WriteSequence(this.IndentChar, this.IndentCount);
+				level--;
+			}
+		}
+
+		public void WriteNewLine()
+		{
+			this.OutputStream.Write(this.NewLine);
+		}
+
+		public void WriteMultilineString(string value, int level = 0)
+		{
+			if (String.IsNullOrEmpty(value))
+			{
+				return;
+			}
+
+			// only \n and \r\n are recognized as linebreaks
+			string[] lines = value.Split(new char[] { '\n' }, StringSplitOptions.None);
+
+			for (int l = 0; l < (lines.Length - 1); l++)
+			{
+				if (lines[l].EndsWith("\r"))
+				{
+					this.OutputStream.Write(lines[l].Substring(0, lines[l].Length-1));
+				}
+				else
+				{
+					this.OutputStream.Write(lines[l]);
+				}
+
+				this.WriteNewLine();
+				this.IndentLine(level);
+			}
+
+			this.OutputStream.Write(lines[lines.Length - 1]);
+		}
+	}
+}
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/CCodeGeneration/Code.cs
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/CCodeGeneration/Code.cs	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/CCodeGeneration/Code.cs	(revision 457)
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Martin Hentschel <info@cl-soft.de>
+ *
+ */
+
+namespace CCodeGeneration
+{
+	public class Code: CodeElement
+	{
+		public string Code_ { get; set; }
+
+		public Code()
+		{
+		}
+
+		public Code(string code)
+		{
+			this.Code_ = code;
+		}
+
+		public override void GenerateCode(int level, CGenerator generator)
+		{
+			generator.IndentLine(level);
+			generator.WriteMultilineString(this.Code_, level);
+			generator.WriteNewLine();
+		}
+
+	}
+}
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/CCodeGeneration/CodeContainerBase.cs
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/CCodeGeneration/CodeContainerBase.cs	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/CCodeGeneration/CodeContainerBase.cs	(revision 457)
@@ -0,0 +1,139 @@
+/*
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Martin Hentschel <info@cl-soft.de>
+ *
+ */
+
+using System.Collections.Generic;
+using System;
+
+namespace CCodeGeneration
+{
+	public class CodeContainerBase: CodeElement
+	{
+		private readonly List<CodeElement> declarations = new List<CodeElement>();
+		private readonly List<CodeElement> innerElements = new List<CodeElement>();
+		private bool increaseLevel = true;
+
+		public List<CodeElement> Declarations
+		{
+			get { return this.declarations; }
+		}
+
+		public List<CodeElement> InnerElements
+		{
+			get { return this.innerElements; }
+		}
+
+		protected bool IncreaseLevel
+		{
+			get { return this.increaseLevel; }
+			set { this.increaseLevel = value; }
+		}
+
+		public void AddElements(IList<CodeElement> elements, params CodeElement[] spacerElements)
+		{
+			if (elements != null)
+			{
+				if ((spacerElements == null) || (spacerElements.Length == 0))
+				{
+					this.innerElements.AddRange(elements);
+				}
+				else
+				{
+					bool spacerAdded = false;
+
+					foreach (CodeElement element in elements)
+					{
+						this.innerElements.Add(element);
+						this.innerElements.AddRange(spacerElements);
+						spacerAdded = true;
+					}
+
+					if (spacerAdded)
+					{
+						// remove last spacer again
+						this.innerElements.RemoveRange(this.innerElements.Count - spacerElements.Length, spacerElements.Length);
+					}					
+				}
+			}
+		}
+ 
+		public CodeElement AddElement(CodeElement element)
+		{
+			if (element != null)
+			{
+				this.innerElements.Add(element);
+			}
+
+			return element;
+		}
+
+		public Code AddCode(string code)
+		{
+			return this.AddElement(new Code(code)) as Code;
+		}
+
+		public Code AddCodeFormat(string codeFormat, params object[] args)
+		{
+			return this.AddElement(new Code(String.Format(codeFormat, args))) as Code;
+		}
+
+		public CodeElement AddDeclaration(CodeElement declaration)
+		{
+			if (declaration != null)
+			{
+				this.declarations.Add(declaration);
+			}
+
+			return declaration;
+		}
+
+		public override void GenerateCode(int level, CGenerator generator)
+		{
+			if (this.increaseLevel)
+				level++;
+
+			if (this.declarations.Count > 0)
+			{
+				foreach (CodeElement element in this.declarations)
+				{
+					element.GenerateCode(level, generator);
+				}
+
+				EmptyLine.SingleLine.GenerateCode(level, generator);
+			}
+
+			foreach (CodeElement element in this.innerElements)
+			{
+				element.GenerateCode(level, generator);
+			}
+		}
+	}
+}
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/CCodeGeneration/CodeElement.cs
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/CCodeGeneration/CodeElement.cs	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/CCodeGeneration/CodeElement.cs	(revision 457)
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Martin Hentschel <info@cl-soft.de>
+ *
+ */
+
+namespace CCodeGeneration
+{
+	public class CodeElement
+	{
+		public virtual void GenerateCode(int level, CGenerator generator)
+		{
+		}
+	}
+}
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/CCodeGeneration/Comment.cs
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/CCodeGeneration/Comment.cs	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/CCodeGeneration/Comment.cs	(revision 457)
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Martin Hentschel <info@cl-soft.de>
+ *
+ */
+
+namespace CCodeGeneration
+{
+	public class Comment: CodeElement
+	{
+		public const string CommentStart = "/*";
+		public const string CommentEnd = "*/";
+
+		public string Comment_ { get; set; }
+		public bool SingleLine { get; set; }
+
+		public Comment()
+		{
+		}
+
+		public Comment(string comment, bool singleLine = false)
+		{
+			this.Comment_   = comment;
+			this.SingleLine = singleLine;
+		}
+
+		public override void GenerateCode(int level, CGenerator generator)
+		{
+			generator.IndentLine(level);
+			generator.OutputStream.Write(CommentStart);
+
+			if (!this.SingleLine)
+			{
+				generator.WriteNewLine();
+				generator.IndentLine(level);
+				generator.WriteMultilineString(this.Comment_, level);
+				generator.WriteNewLine();
+				generator.IndentLine(level);
+			}
+			else
+			{
+				generator.OutputStream.Write(" " + Comment_ + " ");
+			}
+
+			generator.OutputStream.Write(CommentEnd);
+			generator.WriteNewLine();
+		}
+	}
+}
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/CCodeGeneration/EmptyLine.cs
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/CCodeGeneration/EmptyLine.cs	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/CCodeGeneration/EmptyLine.cs	(revision 457)
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Martin Hentschel <info@cl-soft.de>
+ *
+ */
+
+namespace CCodeGeneration
+{
+	public class EmptyLine : CodeElement
+	{
+		public static readonly EmptyLine SingleLine = new EmptyLine();
+		public static readonly EmptyLine TwoLines = new EmptyLine(2);
+		public static readonly EmptyLine ThreeLines = new EmptyLine(3);
+
+		public uint Count { get; set; }
+
+		public EmptyLine()
+		{
+			this.Count = 1;
+		}
+
+		public EmptyLine(uint count)
+		{
+			this.Count = count;
+		}
+
+		public override void GenerateCode(int level, CGenerator generator)
+		{
+			uint c = this.Count;
+
+			while (c > 0)
+			{
+				generator.WriteNewLine();
+				c--;
+			}
+		}
+	}
+}
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/CCodeGeneration/Function.cs
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/CCodeGeneration/Function.cs	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/CCodeGeneration/Function.cs	(revision 457)
@@ -0,0 +1,129 @@
+/*
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Martin Hentschel <info@cl-soft.de>
+ *
+ */
+
+using System;
+using System.Collections.Generic;
+
+namespace CCodeGeneration
+{
+	public class Function: CodeContainerBase
+	{
+		public string Name { get; set; }
+		public bool IsStatic { get; set; }
+
+		private readonly List<VariableType> parameter = new List<VariableType>();
+		private VariableType returnType = VariableType.Void;
+
+		public Function()
+		{
+		}
+
+		public Function(string name, bool isStatic = false)
+		{
+			this.Name = name;
+			this.IsStatic = isStatic;
+		}
+
+		public List<VariableType> Parameter
+		{
+			get { return this.parameter; }
+		}
+
+		public VariableType ReturnType
+		{
+			get { return this.returnType; }
+			set
+			{
+				if (value == null)
+				{
+					throw new ArgumentNullException("ReturnValue");
+				}
+				this.returnType = value;
+			}
+		}
+
+		public static Function FromDeclaration(FunctionDeclaration decl)
+		{
+			Function result = new Function(decl.Name, decl.IsStatic);
+			result.ReturnType = decl.ReturnType.Clone() as VariableType;
+
+			foreach (VariableType param in decl.Parameter)
+			{
+				result.parameter.Add(param.Clone() as VariableType);
+			}
+
+			return result;
+		}
+
+		public override void GenerateCode(int level, CGenerator generator)
+		{
+			generator.IndentLine(level);
+
+			if (this.IsStatic)
+			{
+				generator.OutputStream.Write("static ");
+			}
+
+			this.returnType.GenerateCode(generator);
+			generator.OutputStream.Write(" " + this.Name + "(");
+
+			if (this.Parameter.Count > 0)
+			{
+				for (int i = 0; i < this.parameter.Count; i++)
+				{
+					this.parameter[i].GenerateCode(generator);
+
+					if (i < (this.parameter.Count - 1))
+					{
+						generator.OutputStream.Write(", ");
+					}
+				}
+			}
+			else
+			{
+				generator.OutputStream.Write("void");
+			}
+
+			generator.OutputStream.Write(")");
+			generator.WriteNewLine();
+			generator.IndentLine(level);
+			generator.OutputStream.Write("{");
+			generator.WriteNewLine();
+
+			base.GenerateCode(level, generator);
+
+			generator.IndentLine(level);
+			generator.OutputStream.Write("}");
+			generator.WriteNewLine();
+		}
+	}
+}
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/CCodeGeneration/FunctionDeclaration.cs
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/CCodeGeneration/FunctionDeclaration.cs	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/CCodeGeneration/FunctionDeclaration.cs	(revision 457)
@@ -0,0 +1,114 @@
+/*
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Martin Hentschel <info@cl-soft.de>
+ *
+ */
+
+using System;
+using System.Collections.Generic;
+
+namespace CCodeGeneration
+{
+	public class FunctionDeclaration: CodeElement
+	{
+		public string Name { get; set; }
+		public bool IsStatic { get; set; }
+		public bool IsExtern { get; set; }
+
+		private readonly List<VariableType> parameter = new List<VariableType>();
+		private VariableType returnType = VariableType.Void;
+
+		public FunctionDeclaration()
+		{
+		}
+
+		public FunctionDeclaration(string name, bool isStatic = false, bool isExtern = false)
+		{
+			this.Name = name;
+			this.IsStatic = isStatic;
+			this.IsExtern = isExtern;
+		}
+
+		public List<VariableType> Parameter
+		{
+			get { return this.parameter; }
+		}
+
+		public VariableType ReturnType
+		{
+			get { return this.returnType; }
+			set
+			{
+				if (value == null)
+				{
+					throw new ArgumentNullException("ReturnValue");
+				}
+				this.returnType = value;
+			}
+		}
+
+		public override void GenerateCode(int level, CGenerator generator)
+		{
+			generator.IndentLine(level);
+
+			if (this.IsExtern)
+			{
+				generator.OutputStream.Write("extern ");
+			}
+
+			if (this.IsStatic)
+			{
+				generator.OutputStream.Write("static ");
+			}
+
+			this.returnType.GenerateCode(generator);
+			generator.OutputStream.Write(" " + this.Name + "(");
+
+			if (this.Parameter.Count > 0)
+			{
+				for (int i = 0; i < this.parameter.Count; i++)
+				{
+					this.parameter[i].GenerateCode(generator);
+
+					if (i < (this.parameter.Count - 1))
+					{
+						generator.OutputStream.Write(", ");
+					}
+				}
+			}
+			else
+			{
+				generator.OutputStream.Write("void");
+			}
+
+			generator.OutputStream.Write(");");
+			generator.WriteNewLine();
+		}
+	}
+}
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/CCodeGeneration/IfThenElse.cs
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/CCodeGeneration/IfThenElse.cs	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/CCodeGeneration/IfThenElse.cs	(revision 457)
@@ -0,0 +1,137 @@
+/*
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Martin Hentschel <info@cl-soft.de>
+ *
+ */
+
+using System;
+using System.Collections.Generic;
+
+namespace CCodeGeneration
+{
+	public class ElseIf : CodeContainerBase
+	{
+		public string Condition { get; set; }
+
+		public ElseIf()
+		{
+		}
+
+		public ElseIf(string condition)
+		{
+			this.Condition = condition;
+		}
+
+		public override void GenerateCode(int level, CGenerator generator)
+		{
+			if (!String.IsNullOrWhiteSpace(this.Condition))
+			{
+				generator.IndentLine(level);
+				generator.OutputStream.Write(String.Format("else if ({0})", this.Condition));
+				generator.WriteNewLine();
+				generator.IndentLine(level);
+				generator.OutputStream.Write("{");
+				generator.WriteNewLine();
+
+				base.GenerateCode(level, generator);
+
+				generator.IndentLine(level);
+				generator.OutputStream.Write("}");
+				generator.WriteNewLine();
+			}
+		}
+	}
+
+	public class IfThenElse: CodeContainerBase
+	{
+		public string Condition { get; set; }
+
+		private List<ElseIf> elseIf = new List<ElseIf>();
+		private CodeContainerBase else_ = new CodeContainerBase();
+
+		public IfThenElse()
+		{
+		}
+
+		public IfThenElse(string condition)
+		{
+			this.Condition = condition;
+		}
+
+		public List<ElseIf> ElseIf
+		{
+			get { return this.elseIf; }
+		}
+
+		public CodeContainerBase Else
+		{
+			get { return this.else_; }
+		}
+
+		public override void GenerateCode(int level, CGenerator generator)
+		{
+			if (!String.IsNullOrWhiteSpace(this.Condition))
+			{
+				generator.IndentLine(level);
+				generator.OutputStream.Write(String.Format("if ({0})", this.Condition));
+				generator.WriteNewLine();
+				generator.IndentLine(level);
+				generator.OutputStream.Write("{");
+				generator.WriteNewLine();
+
+				base.GenerateCode(level, generator);
+
+				generator.IndentLine(level);
+				generator.OutputStream.Write("}");
+				generator.WriteNewLine();
+
+				foreach (ElseIf elif in this.elseIf)
+				{
+					elif.GenerateCode(level, generator);
+				}
+
+				if (this.else_.InnerElements.Count > 0)
+				{
+					generator.IndentLine(level);
+					generator.OutputStream.Write("else");
+					generator.WriteNewLine();
+					generator.IndentLine(level);
+					generator.OutputStream.Write("{");
+					generator.WriteNewLine();
+
+					this.else_.GenerateCode(level, generator);
+
+					generator.IndentLine(level);
+					generator.OutputStream.Write("}");
+					generator.WriteNewLine();
+				}
+			}
+		}
+	}
+}
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/CCodeGeneration/PP_If.cs
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/CCodeGeneration/PP_If.cs	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/CCodeGeneration/PP_If.cs	(revision 457)
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Martin Hentschel <info@cl-soft.de>
+ *
+ */
+
+using System;
+
+namespace CCodeGeneration
+{
+	public class PP_If: CodeContainerBase
+	{
+		public string Condition { get; set; }
+
+		public PP_If()
+		{
+			base.IncreaseLevel = false;
+		}
+
+		public PP_If(string condition)
+			: this()
+		{
+			this.Condition = condition;
+		}
+
+
+		public override void GenerateCode(int level, CGenerator generator)
+		{
+			if (!String.IsNullOrWhiteSpace(this.Condition))
+			{
+				generator.OutputStream.Write("#if " + this.Condition);
+				generator.WriteNewLine();
+
+				base.GenerateCode(level, generator);
+
+				generator.OutputStream.Write("#endif /* " + this.Condition + " */");
+				generator.WriteNewLine();
+			}
+		}
+	}
+}
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/CCodeGeneration/PP_Ifdef.cs
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/CCodeGeneration/PP_Ifdef.cs	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/CCodeGeneration/PP_Ifdef.cs	(revision 457)
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Martin Hentschel <info@cl-soft.de>
+ *
+ */
+
+using System;
+
+namespace CCodeGeneration
+{
+	public class PP_Ifdef: CodeContainerBase
+	{
+		public string Macro { get; set; }
+		public bool Inverted { get; set; }
+
+		public PP_Ifdef()
+		{
+			base.IncreaseLevel = false;
+		}
+
+		public PP_Ifdef(string macro, bool inverted = false)
+			: this()
+		{
+			this.Macro = macro;
+			this.Inverted = inverted;
+		}
+
+
+		public override void GenerateCode(int level, CGenerator generator)
+		{
+			if (!String.IsNullOrWhiteSpace(this.Macro))
+			{
+				if (this.Inverted)
+				{
+					generator.OutputStream.Write("#ifndef " + this.Macro);
+				}
+				else
+				{
+					generator.OutputStream.Write("#ifdef " + this.Macro);
+				}
+				generator.WriteNewLine();
+
+				base.GenerateCode(level, generator);
+
+				generator.OutputStream.Write("#endif /* " + this.Macro + " */");
+				generator.WriteNewLine();
+			}
+		}
+	}
+}
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/CCodeGeneration/PP_Include.cs
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/CCodeGeneration/PP_Include.cs	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/CCodeGeneration/PP_Include.cs	(revision 457)
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Martin Hentschel <info@cl-soft.de>
+ *
+ */
+
+using System;
+
+namespace CCodeGeneration
+{
+	public class PP_Include : CodeElement
+	{
+		public string File { get; set; }
+		public bool IsLocal { get; set; }
+
+		public PP_Include()
+		{
+			this.IsLocal = true;				 
+		}
+
+		public PP_Include(string file, bool isLocal = true)
+		{
+			this.File = file;
+			this.IsLocal = isLocal;
+		}
+
+		public override void GenerateCode(int level, CGenerator generator)
+		{
+			if (!String.IsNullOrWhiteSpace(this.File))
+			{
+				// includes are never indented
+				if (this.IsLocal)
+				{
+					generator.OutputStream.Write("#include \"" + this.File + "\"");
+				}
+				else
+				{
+					generator.OutputStream.Write("#include <" + this.File + ">");
+				}
+
+				generator.WriteNewLine();			
+			}
+		}
+	}
+}
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/CCodeGeneration/PP_Macro.cs
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/CCodeGeneration/PP_Macro.cs	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/CCodeGeneration/PP_Macro.cs	(revision 457)
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Martin Hentschel <info@cl-soft.de>
+ *
+ */
+
+namespace CCodeGeneration
+{
+	public class PP_Macro: CodeElement
+	{
+		public string Name { get; set; }
+		public string Value { get; set; }
+
+		public PP_Macro()
+		{
+		}
+
+		public PP_Macro(string name, string value)
+		{
+			this.Name  = name;
+			this.Value = value;
+		}
+
+		
+		public override void GenerateCode(int level, CGenerator generator)
+		{
+			// macros are not indented at all
+			generator.OutputStream.Write("#define " + this.Name + " ");
+			generator.WriteMultilineString(this.Value);
+			generator.WriteNewLine();
+		}
+	}
+}
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/CCodeGeneration/PlainText.cs
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/CCodeGeneration/PlainText.cs	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/CCodeGeneration/PlainText.cs	(revision 457)
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Martin Hentschel <info@cl-soft.de>
+ *
+ */
+
+namespace CCodeGeneration
+{
+	public class PlainText : CodeElement
+	{
+		public string Value { get; set; }
+
+		public PlainText(string value)
+		{
+			this.Value = value;
+		}
+
+		public override void GenerateCode(int level, CGenerator generator)
+		{
+			generator.WriteMultilineString(this.Value);
+		}
+	}
+}
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/CCodeGeneration/Properties/AssemblyInfo.cs
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/CCodeGeneration/Properties/AssemblyInfo.cs	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/CCodeGeneration/Properties/AssemblyInfo.cs	(revision 457)
@@ -0,0 +1,36 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// Allgemeine Informationen uber eine Assembly werden uber die folgenden 
+// Attribute gesteuert. Andern Sie diese Attributwerte, um die Informationen zu andern,
+// die mit einer Assembly verknupft sind.
+[assembly: AssemblyTitle("CCodeGeneration")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("CCodeGeneration")]
+[assembly: AssemblyCopyright("Copyright c  2015")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Durch Festlegen von ComVisible auf "false" werden die Typen in dieser Assembly unsichtbar 
+// fur COM-Komponenten. Wenn Sie auf einen Typ in dieser Assembly von 
+// COM zugreifen mussen, legen Sie das ComVisible-Attribut fur diesen Typ auf "true" fest.
+[assembly: ComVisible(false)]
+
+// Die folgende GUID bestimmt die ID der Typbibliothek, wenn dieses Projekt fur COM verfugbar gemacht wird
+[assembly: Guid("8f07a0fa-86f4-48a0-97c7-f94fc5c3f103")]
+
+// Versionsinformationen fur eine Assembly bestehen aus den folgenden vier Werten:
+//
+//      Hauptversion
+//      Nebenversion 
+//      Buildnummer
+//      Revision
+//
+// Sie konnen alle Werte angeben oder die standardmasigen Build- und Revisionsnummern 
+// ubernehmen, indem Sie "*" eingeben:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/CCodeGeneration/Switch.cs
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/CCodeGeneration/Switch.cs	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/CCodeGeneration/Switch.cs	(revision 457)
@@ -0,0 +1,146 @@
+/*
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Martin Hentschel <info@cl-soft.de>
+ *
+ */
+
+using System;
+using System.Collections.Generic;
+
+namespace CCodeGeneration
+{
+	public class SwitchCase : CodeContainerBase
+	{
+		public string Value { get; set; }
+
+		public SwitchCase()
+		{
+		}
+
+		public SwitchCase(string value)
+		{
+			this.Value = value;
+		}
+
+		public bool IsDefault
+		{
+			get { return (this.Value.ToLowerInvariant() == "default"); }
+		}
+
+		public static SwitchCase GenerateDefault()
+		{
+			return new SwitchCase("default");
+		}
+
+		public override void GenerateCode(int level, CGenerator generator)
+		{
+			if (!String.IsNullOrWhiteSpace(this.Value))
+			{
+				generator.IndentLine(level);
+				if (this.IsDefault)
+				{
+					generator.OutputStream.Write("default:");
+				}
+				else
+				{
+					generator.OutputStream.Write(String.Format("case {0}:", this.Value));
+				}
+				generator.WriteNewLine();
+				generator.IndentLine(level + 1);
+				generator.OutputStream.Write("{");
+				generator.WriteNewLine();
+
+				base.GenerateCode(level + 1, generator);
+
+				generator.IndentLine(level + 1);
+				generator.OutputStream.Write("}");
+				generator.WriteNewLine();
+
+				generator.IndentLine(level + 1);
+				generator.OutputStream.Write("break;");
+				generator.WriteNewLine();
+			}
+		}
+	}
+
+	public class Switch: CodeElement
+	{
+		public string SwitchVar { get; set; }
+
+		private List<SwitchCase> switches = new List<SwitchCase>();
+
+		public Switch()
+		{
+		}
+
+		public Switch(string switchVar)
+		{
+			this.SwitchVar = switchVar;
+		}
+
+		public List<SwitchCase> Switches
+		{
+			get { return this.switches; }
+		}
+
+		public override void GenerateCode(int level, CGenerator generator)
+		{
+			if (!String.IsNullOrWhiteSpace(this.SwitchVar))
+			{
+				generator.IndentLine(level);
+				generator.OutputStream.Write(String.Format("switch ({0})", this.SwitchVar));
+				generator.WriteNewLine();
+				generator.IndentLine(level);
+				generator.OutputStream.Write("{");
+				generator.WriteNewLine();
+
+				SwitchCase defaultCase = null; // generate 'default' always as last case
+				foreach (SwitchCase switchCase in this.switches)
+				{
+					if (switchCase.IsDefault)
+					{
+						defaultCase = switchCase;
+					}
+					else
+					{
+						switchCase.GenerateCode(level + 1, generator);
+					}
+				}
+				if (defaultCase != null)
+				{
+					defaultCase.GenerateCode(level + 1, generator);
+				}
+
+				generator.IndentLine(level);
+				generator.OutputStream.Write("}");
+				generator.WriteNewLine();
+			}
+		}
+	}
+}
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/CCodeGeneration/VariableDeclaration.cs
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/CCodeGeneration/VariableDeclaration.cs	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/CCodeGeneration/VariableDeclaration.cs	(revision 457)
@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Martin Hentschel <info@cl-soft.de>
+ *
+ */
+
+using System;
+
+namespace CCodeGeneration
+{
+	public class VariableDeclaration : CodeElement
+	{
+		public VariableType Type { get; set; }
+		public string InitialValue { get; set; }
+		public bool IsStatic { get; set; }
+
+		public VariableDeclaration()
+			: base()
+		{
+		}
+
+		public VariableDeclaration(VariableType type, string initialValue = null, bool isStatic = false) :
+			base()
+		{
+			this.Type         = type;
+			this.InitialValue = initialValue;
+			this.IsStatic     = isStatic;
+		}
+
+		public override void GenerateCode(int level, CGenerator generator)
+		{
+			if (this.Type != null)
+			{
+				generator.IndentLine(level);
+
+				if (this.IsStatic)
+				{
+					generator.OutputStream.Write("static ");
+				}
+
+				// declare the variable
+				this.Type.GenerateCode(generator);
+
+				if (!String.IsNullOrWhiteSpace(this.InitialValue))
+				{
+					// add initialization value
+					generator.OutputStream.Write(" = ");
+					generator.WriteMultilineString(this.InitialValue, level);
+				}
+
+				generator.OutputStream.Write(";");
+				generator.WriteNewLine();
+			}
+		}
+	}
+}
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/CCodeGeneration/VariablePrototype.cs
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/CCodeGeneration/VariablePrototype.cs	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/CCodeGeneration/VariablePrototype.cs	(revision 457)
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Martin Hentschel <info@cl-soft.de>
+ *
+ */
+
+namespace CCodeGeneration
+{
+	public class VariablePrototype : CodeElement
+	{
+		public VariableType Type { get; set; }
+
+		public VariablePrototype()
+			: base()
+		{
+		}
+
+		public VariablePrototype(VariableType type) :
+			base()
+		{
+			Type = type;
+		}
+
+		public static VariablePrototype FromVariableDeclaration(VariableDeclaration declaration)
+		{
+			return new VariablePrototype(declaration.Type);
+		}
+
+
+		public override void GenerateCode(int level, CGenerator generator)
+		{
+			if (this.Type != null)
+			{
+				generator.IndentLine(level);
+
+				generator.OutputStream.Write("extern ");
+
+				// declare the variable
+				this.Type.GenerateCode(generator);
+
+				generator.OutputStream.Write(";");
+				generator.WriteNewLine();
+			}
+		}
+
+	}
+}
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/CCodeGeneration/VariableType.cs
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/CCodeGeneration/VariableType.cs	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/CCodeGeneration/VariableType.cs	(revision 457)
@@ -0,0 +1,130 @@
+/*
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Martin Hentschel <info@cl-soft.de>
+ *
+ */
+
+using System;
+using System.Text;
+
+namespace CCodeGeneration
+{
+	public enum ConstType
+	{
+		None,
+		Value,
+		Indirection,
+		Both
+	}
+
+	public class VariableType : ICloneable
+	{
+		public const string VoidString = "void";
+		public static readonly VariableType Void = new VariableType(null, "void");
+
+		public string Name { get; set; }
+		public string Type { get; set; }
+		public string Indirection { get; set; }
+		public ConstType Const { get; set; }
+		public string ArraySpecifier { get; set; }
+
+		public VariableType()
+		{
+		}
+
+		public VariableType(string name, string type, string indirection = null, ConstType const_ = ConstType.None, string arraySpecifier = null)
+		{
+			this.Name           = name;
+			this.Type           = type;
+			this.Indirection    = indirection;
+			this.Const          = const_;
+			this.ArraySpecifier = arraySpecifier;
+		}
+
+		public void GenerateCode(CGenerator generator)
+		{
+			if (!String.IsNullOrWhiteSpace(this.Type))
+			{
+				generator.OutputStream.Write(this.ToString().Trim());
+			}
+		}
+
+		public override string ToString()
+		{
+			if (!String.IsNullOrWhiteSpace(this.Type))
+			{
+				StringBuilder vt = new StringBuilder();
+
+				if ((this.Const == ConstType.Value) || (this.Const == ConstType.Both))
+				{
+					vt.Append("const ");
+				}
+
+				vt.Append(this.Type);
+				vt.Append(" ");
+
+				if (!String.IsNullOrWhiteSpace(this.Indirection))
+				{
+					vt.Append(this.Indirection);
+				}
+
+				if ((this.Const == ConstType.Indirection) || (this.Const == ConstType.Both))
+				{
+					vt.Append("const ");
+				}
+
+				if (!String.IsNullOrWhiteSpace(this.Name))
+				{
+					vt.Append(this.Name);
+				}
+
+				if (this.ArraySpecifier != null)
+				{
+					vt.Append("[");
+					vt.Append(this.ArraySpecifier);
+					vt.Append("]");
+				}
+
+				return vt.ToString().Trim();
+			}
+
+			return base.ToString();
+		}
+
+		#region ICloneable Member
+
+		public object Clone()
+		{
+			// we only have value types as members -> simply use .net base function
+			return this.MemberwiseClone();
+		}
+
+		#endregion
+	}
+}
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/LwipMibCompiler.sln
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/LwipMibCompiler.sln	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/LwipMibCompiler.sln	(revision 457)
@@ -0,0 +1,47 @@
+
+Microsoft Visual Studio Solution File, Format Version 11.00
+# Visual Studio 2010
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LwipMibCompiler", "LwipMibCompiler\LwipMibCompiler.csproj", "{C25D5640-D999-49BD-82E0-A1975296A91E}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LwipSnmpCodeGeneration", "LwipSnmpCodeGeneration\LwipSnmpCodeGeneration.csproj", "{AABCAB90-1540-45D4-A159-14831A54E9A3}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CCodeGeneration", "CCodeGeneration\CCodeGeneration.csproj", "{7DA7C0AB-0982-4BF5-9324-F59A7A08D65B}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SharpSnmpLib.Mib", "SharpSnmpLib\SharpSnmpLib.Mib.csproj", "{CBE20411-5DB7-487D-825D-7694267BB6F5}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MibViewer", "MibViewer\MibViewer.csproj", "{86CC0B65-7985-4017-A252-0A7A18DCAEF3}"
+EndProject
+Global
+	GlobalSection(SolutionConfigurationPlatforms) = preSolution
+		Debug|Any CPU = Debug|Any CPU
+		Release|Any CPU = Release|Any CPU
+	EndGlobalSection
+	GlobalSection(ProjectConfigurationPlatforms) = postSolution
+		{7DA7C0AB-0982-4BF5-9324-F59A7A08D65B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{7DA7C0AB-0982-4BF5-9324-F59A7A08D65B}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{7DA7C0AB-0982-4BF5-9324-F59A7A08D65B}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{7DA7C0AB-0982-4BF5-9324-F59A7A08D65B}.Release|Any CPU.Build.0 = Release|Any CPU
+		{86CC0B65-7985-4017-A252-0A7A18DCAEF3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{86CC0B65-7985-4017-A252-0A7A18DCAEF3}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{86CC0B65-7985-4017-A252-0A7A18DCAEF3}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{86CC0B65-7985-4017-A252-0A7A18DCAEF3}.Release|Any CPU.Build.0 = Release|Any CPU
+		{AABCAB90-1540-45D4-A159-14831A54E9A3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{AABCAB90-1540-45D4-A159-14831A54E9A3}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{AABCAB90-1540-45D4-A159-14831A54E9A3}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{AABCAB90-1540-45D4-A159-14831A54E9A3}.Release|Any CPU.Build.0 = Release|Any CPU
+		{C25D5640-D999-49BD-82E0-A1975296A91E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{C25D5640-D999-49BD-82E0-A1975296A91E}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{C25D5640-D999-49BD-82E0-A1975296A91E}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{C25D5640-D999-49BD-82E0-A1975296A91E}.Release|Any CPU.Build.0 = Release|Any CPU
+		{CBE20411-5DB7-487D-825D-7694267BB6F5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{CBE20411-5DB7-487D-825D-7694267BB6F5}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{CBE20411-5DB7-487D-825D-7694267BB6F5}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{CBE20411-5DB7-487D-825D-7694267BB6F5}.Release|Any CPU.Build.0 = Release|Any CPU
+	EndGlobalSection
+	GlobalSection(MonoDevelopProperties) = preSolution
+		StartupItem = LwipMibCompiler\LwipMibCompiler.csproj
+	EndGlobalSection
+	GlobalSection(SolutionProperties) = preSolution
+		HideSolutionNode = FALSE
+	EndGlobalSection
+EndGlobal
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/LwipMibCompiler/LwipMibCompiler.csproj
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/LwipMibCompiler/LwipMibCompiler.csproj	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/LwipMibCompiler/LwipMibCompiler.csproj	(revision 457)
@@ -0,0 +1,73 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+    <ProductVersion>8.0.30703</ProductVersion>
+    <SchemaVersion>2.0</SchemaVersion>
+    <ProjectGuid>{C25D5640-D999-49BD-82E0-A1975296A91E}</ProjectGuid>
+    <OutputType>Exe</OutputType>
+    <AppDesignerFolder>Properties</AppDesignerFolder>
+    <RootNamespace>LwipMibCompiler</RootNamespace>
+    <AssemblyName>LwipMibCompiler</AssemblyName>
+    <TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
+    <FileAlignment>512</FileAlignment>
+    <TargetFrameworkProfile />
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|AnyCPU'">
+    <DebugSymbols>true</DebugSymbols>
+    <OutputPath>bin\Debug\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <DebugType>full</DebugType>
+    <PlatformTarget>AnyCPU</PlatformTarget>
+    <ErrorReport>prompt</ErrorReport>
+    <CodeAnalysisIgnoreBuiltInRuleSets>false</CodeAnalysisIgnoreBuiltInRuleSets>
+    <CodeAnalysisIgnoreBuiltInRules>false</CodeAnalysisIgnoreBuiltInRules>
+    <WarningLevel>4</WarningLevel>
+    <Optimize>false</Optimize>
+    <UseVSHostingProcess>false</UseVSHostingProcess>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|AnyCPU'">
+    <OutputPath>bin\Release\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <Optimize>true</Optimize>
+    <DebugType>pdbonly</DebugType>
+    <PlatformTarget>AnyCPU</PlatformTarget>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+    <UseVSHostingProcess>false</UseVSHostingProcess>
+  </PropertyGroup>
+  <ItemGroup>
+    <Reference Include="System" />
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="Program.cs" />
+    <Compile Include="Properties\AssemblyInfo.cs" />
+  </ItemGroup>
+  <ItemGroup>
+    <None Include="app.config" />
+  </ItemGroup>
+  <ItemGroup>
+    <ProjectReference Include="..\CCodeGeneration\CCodeGeneration.csproj">
+      <Project>{7DA7C0AB-0982-4BF5-9324-F59A7A08D65B}</Project>
+      <Name>CCodeGeneration</Name>
+    </ProjectReference>
+    <ProjectReference Include="..\LwipSnmpCodeGeneration\LwipSnmpCodeGeneration.csproj">
+      <Project>{AABCAB90-1540-45D4-A159-14831A54E9A3}</Project>
+      <Name>LwipSnmpCodeGeneration</Name>
+    </ProjectReference>
+    <ProjectReference Include="..\SharpSnmpLib\SharpSnmpLib.Mib.csproj">
+      <Project>{CBE20411-5DB7-487D-825D-7694267BB6F5}</Project>
+      <Name>SharpSnmpLib.Mib</Name>
+    </ProjectReference>
+  </ItemGroup>
+  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+  <PropertyGroup />
+  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
+       Other similar extension points exist, see Microsoft.Common.targets.
+  <Target Name="BeforeBuild">
+  </Target>
+  <Target Name="AfterBuild">
+  </Target>
+  -->
+</Project>
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/LwipMibCompiler/Program.cs
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/LwipMibCompiler/Program.cs	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/LwipMibCompiler/Program.cs	(revision 457)
@@ -0,0 +1,480 @@
+/*
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Martin Hentschel <info@cl-soft.de>
+ *
+ */
+
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Reflection;
+using System.Text.RegularExpressions;
+using CCodeGeneration;
+using Lextm.SharpSnmpLib.Mib;
+using Lextm.SharpSnmpLib.Mib.Elements.Entities;
+using Lextm.SharpSnmpLib.Mib.Elements.Types;
+using LwipSnmpCodeGeneration;
+
+namespace LwipMibCompiler
+{
+	class Program
+	{
+		private static readonly Regex _alphaNumericRegex = new Regex("[^a-zA-Z0-9]");
+
+		static void Main(string[] args)
+		{
+			Console.WriteLine("lwIP MIB Compiler");
+			Console.WriteLine("");
+
+			// check args
+			if ((args.Length < 2) || String.IsNullOrWhiteSpace(args[0]) || String.IsNullOrWhiteSpace(args[1]))
+			{
+				PrintUsage();
+				return;
+			}
+
+			string mibFile = args[0];
+			if (!File.Exists(mibFile))
+			{
+				Console.WriteLine(String.Format("Unable to find file '{0}'!", mibFile));
+			}
+
+			string destFile = args[1];
+			string destHeaderFile;
+
+			if (Directory.Exists(destFile))
+			{
+				// only directory passed -> create dest filename from mib filename
+				string mibFileName = Path.GetFileNameWithoutExtension(mibFile).ToLowerInvariant();
+				destFile = Path.Combine(destFile, mibFileName + ".c");
+			}
+			
+			string destFileExt = Path.GetExtension(destFile);
+			if (!String.IsNullOrEmpty(destFileExt))
+			{
+				destHeaderFile = destFile.Substring(0, destFile.Length - destFileExt.Length);
+			}
+			else
+			{
+				destHeaderFile = destFile;
+			}
+			destHeaderFile += ".h";
+
+			for (int i=2; i<args.Length; i++)
+			{
+				if (!String.IsNullOrWhiteSpace(args[i]) && Directory.Exists(args[i]))
+				{
+					MibTypesResolver.RegisterResolver(new FileSystemMibResolver(args[i], true));
+				}
+			}
+
+			
+			// read and resolve MIB
+			Console.WriteLine(" Reading MIB file...");
+			
+			MibDocument md = new MibDocument(mibFile);
+			MibTypesResolver.ResolveTypes(md.Modules[0]);
+			MibTree mt = new MibTree(md.Modules[0] as MibModule);
+
+			if (mt.Root.Count == 0)
+			{
+				Console.WriteLine("No root element found inside MIB!");
+				return;
+			}
+
+			MibCFile generatedFile = new MibCFile();
+			MibHeaderFile generatedHeaderFile = new MibHeaderFile();
+
+			foreach (MibTreeNode mibTreeNode in mt.Root)
+			{
+				// create LWIP object tree from MIB structure
+				Console.WriteLine(" Creating lwIP object tree " + mibTreeNode.Entity.Name);
+
+				SnmpMib snmpMib = new SnmpMib();
+				snmpMib.Oid = mibTreeNode.Entity.Value;
+				snmpMib.BaseOid = MibTypesResolver.ResolveOid(mibTreeNode.Entity).GetOidValues();
+				snmpMib.Name = mibTreeNode.Entity.Name;
+
+				ProcessMibTreeNode(mibTreeNode, snmpMib);
+
+				// let the tree transform itself depending on node structure
+				snmpMib.Analyze();
+
+				if (snmpMib.ChildNodes.Count != 0)
+				{
+					// generate code from LWIP object tree
+					Console.WriteLine(" Generating code " + snmpMib.Name);
+					snmpMib.Generate(generatedFile, generatedHeaderFile);
+				}
+			}
+
+			string preservedCode = MibCFile.GetPreservedCode(destFile);
+			if (!string.IsNullOrEmpty(preservedCode))
+			{
+				generatedFile.PreservedCode.Add(new PlainText(preservedCode));
+			}
+			else
+			{
+				generatedFile.PreservedCode.AddRange(generatedFile.Implementation);
+			}
+			generatedFile.Implementation.Clear();
+
+
+			using (StreamWriter fileWriter = new StreamWriter(destHeaderFile))
+			{
+				CGenerator cGenerator = new CGenerator(fileWriter, destHeaderFile, 3, " ", Environment.NewLine);
+				generatedHeaderFile.Save(cGenerator);
+			}
+			using (StreamWriter fileWriter = new StreamWriter(destFile))
+			{
+				CGenerator cGenerator = new CGenerator(fileWriter, destFile, 3, " ", Environment.NewLine);
+				generatedFile.Save(cGenerator);
+			}
+
+			Console.WriteLine(" Done");
+		}
+
+		private static void PrintUsage()
+		{
+			string codeBase = Assembly.GetExecutingAssembly().CodeBase;
+			string appName = Path.GetFileName(codeBase);
+
+			Console.WriteLine("Usage:");
+			Console.WriteLine(String.Format("  {0} <source MIB file> <dest C file> [<search path 1 for referred MIB's> <search path 2 for referred MIB's> ...]", appName));
+			Console.WriteLine("");
+			Console.WriteLine("    <source MIB file>");
+			Console.WriteLine("      Path and filename of MIB file to convert.");
+			Console.WriteLine("");
+			Console.WriteLine("    <dest C file>");
+			Console.WriteLine("      Destination path and file. If a path is passed only, filename is auto");
+			Console.WriteLine("      generated from MIB file name.");
+			Console.WriteLine("");
+			Console.WriteLine("    <search path X for referred MIB's>");
+			Console.WriteLine("      It's important to provide all referred MIB's in order to correctly ");
+			Console.WriteLine("      resolve all used types.");
+			Console.WriteLine("");
+		}
+
+
+		#region Generation of LWIP Object Tree
+
+		private static void ProcessMibTreeNode(MibTreeNode mibTreeNode, SnmpTreeNode assignedSnmpNode)
+		{
+			foreach (MibTreeNode mtn in mibTreeNode.ChildNodes)
+			{
+				// in theory container nodes may also be scalars or tables at the same time (for now only process real containers)
+				if (mtn.NodeType == MibTreeNodeType.Container)
+				{
+					SnmpTreeNode snmpTreeNode = GenerateSnmpTreeNode(mtn, assignedSnmpNode);
+					assignedSnmpNode.ChildNodes.Add(snmpTreeNode);
+
+					ProcessMibTreeNode(mtn, snmpTreeNode);
+				}
+				else if ((mtn.NodeType & MibTreeNodeType.Scalar) != 0)
+				{
+					SnmpScalarNode snmpScalarNode = GenerateSnmpScalarNode(mtn, assignedSnmpNode);
+					if (snmpScalarNode != null)
+					{
+						assignedSnmpNode.ChildNodes.Add(snmpScalarNode);
+					}
+				}
+				else if ((mtn.NodeType & MibTreeNodeType.Table) != 0)
+				{
+					SnmpTableNode snmpTableNode = GenerateSnmpTableNode(mtn, assignedSnmpNode);
+					if (snmpTableNode != null)
+					{
+						assignedSnmpNode.ChildNodes.Add(snmpTableNode);
+					}
+				}
+			}
+		}
+
+		private static SnmpTreeNode GenerateSnmpTreeNode(MibTreeNode mibTreeNode, SnmpTreeNode parentNode)
+		{
+			SnmpTreeNode result = new SnmpTreeNode(parentNode);
+			result.Name    = _alphaNumericRegex.Replace (mibTreeNode.Entity.Name, "");
+			result.Oid     = mibTreeNode.Entity.Value;
+			result.FullOid = MibTypesResolver.ResolveOid(mibTreeNode.Entity).GetOidString();
+
+			return result;
+		}
+
+		private static SnmpScalarNode GenerateSnmpScalarNode(MibTreeNode mibTreeNode, SnmpTreeNode parentNode, bool ignoreAccessibleFlag = false)
+		{
+			ObjectType ote = mibTreeNode.Entity as ObjectType;
+			if (ote != null)
+			{
+				return GenerateSnmpScalarNode(ote, parentNode, ignoreAccessibleFlag);
+			}
+
+			return null;
+		}
+
+		private static SnmpScalarNode GenerateSnmpScalarNode(ObjectType ote, SnmpTreeNode parentNode, bool ignoreAccessibleFlag = false)
+		{
+			SnmpScalarNode result;
+
+			ITypeAssignment mibType = ote.BaseType;
+			IntegerType it = (mibType as IntegerType);
+			if (it != null)
+			{
+				if (ote.ReferredType.Name == Symbol.TruthValue.ToString())
+				{
+					result = new SnmpScalarNodeTruthValue(parentNode);
+				}
+				else if ((it.Type == IntegerType.Types.Integer) || (it.Type == IntegerType.Types.Integer32))
+				{
+					result = new SnmpScalarNodeInt(parentNode);
+				}
+				else
+				{
+					Console.WriteLine(String.Format("Unsupported IntegerType '{0}'!", it.Type));
+					return null;
+				}
+				if (it.IsEnumeration)
+				{
+					result.Restrictions.AddRange(CreateRestrictions(it.Enumeration));
+				}
+				else
+				{
+					result.Restrictions.AddRange(CreateRestrictions(it.Ranges));
+				}
+			}
+			else
+			{
+				UnsignedType ut = (mibType as UnsignedType);
+				if (ut != null)
+				{
+					if ((ut.Type == UnsignedType.Types.Unsigned32) ||
+							  (ut.Type == UnsignedType.Types.Gauge32))
+					{
+						result = new SnmpScalarNodeUint(SnmpDataType.Gauge, parentNode);
+					}
+					else if (ut.Type == UnsignedType.Types.Counter32)
+					{
+						result = new SnmpScalarNodeUint(SnmpDataType.Counter, parentNode);
+					}
+					else if (ut.Type == UnsignedType.Types.TimeTicks)
+					{
+						result = new SnmpScalarNodeUint(SnmpDataType.TimeTicks, parentNode);
+					}
+					else if (ut.Type == UnsignedType.Types.Counter64)
+					{
+						result = new SnmpScalarNodeCounter64(parentNode);
+						if ((ut.Ranges != null) && (ut.Ranges.Count > 0))
+						{
+							Console.WriteLine(String.Format("Generation of ranges is not supported for Counter64 type!"));
+							return null;
+						}
+					}
+					else
+					{
+						Console.WriteLine(String.Format("Unsupported UnsignedType '{0}'!", ut.Type));
+						return null;
+					}
+					result.Restrictions.AddRange(CreateRestrictions(ut.Ranges));
+				}
+				else if (mibType is IpAddressType)
+				{
+					result = new SnmpScalarNodeOctetString(SnmpDataType.IpAddress, parentNode);
+					result.Restrictions.AddRange(CreateRestrictions((mibType as OctetStringType).Size));
+				}
+				else if (mibType is OpaqueType)
+				{
+					result = new SnmpScalarNodeOctetString(SnmpDataType.Opaque, parentNode);
+					result.Restrictions.AddRange(CreateRestrictions((mibType as OctetStringType).Size));
+				}
+				else if (mibType is OctetStringType)
+				{
+					result = new SnmpScalarNodeOctetString(SnmpDataType.OctetString, parentNode);
+					result.Restrictions.AddRange(CreateRestrictions((mibType as OctetStringType).Size));
+				}
+				else if (mibType is ObjectIdentifierType)
+				{
+					result = new SnmpScalarNodeObjectIdentifier(parentNode);
+				}
+				else if (mibType is BitsType)
+				{
+					result = new SnmpScalarNodeBits(parentNode, (uint)((mibType as BitsType).Map.GetHighestValue() + 1));
+					result.Restrictions.AddRange(CreateRestrictions(mibType as BitsType));
+				}
+				else
+				{
+					TypeAssignment ta = mibType as TypeAssignment;
+					if (ta != null)
+					{
+						Console.WriteLine(String.Format("Unsupported BaseType: Module='{0}', Name='{1}', Type='{2}'!", ta.Module.Name, ta.Name, ta.Type));
+					}
+					else
+					{
+						Console.WriteLine(String.Format("Unsupported BaseType: Module='{0}', Name='{1}'!", mibType.Module, mibType.Name));
+					}
+					
+					return null;
+				}
+			}
+
+			result.Name = _alphaNumericRegex.Replace(ote.Name, "");
+			result.Oid  = ote.Value;
+
+			if (ote.Access == MaxAccess.readWrite)
+			{
+				result.AccessMode = SnmpAccessMode.ReadWrite;
+			}
+			else if (ote.Access == MaxAccess.readOnly)
+			{
+				result.AccessMode = SnmpAccessMode.ReadOnly;
+			}
+			else if (ote.Access == MaxAccess.readCreate)
+			{
+				result.AccessMode = SnmpAccessMode.ReadOnly;
+			}
+			else if (ignoreAccessibleFlag && (ote.Access == MaxAccess.notAccessible))
+			{
+				result.AccessMode = SnmpAccessMode.NotAccessible;
+			}
+			else
+			{
+				// not accessible or unsupported accress type
+				return null;
+			}
+
+			return result;
+		}
+
+		private static IEnumerable<IRestriction> CreateRestrictions(ValueRanges ranges)
+		{
+			List<IRestriction> result = new List<IRestriction>();
+
+			if (ranges != null)
+			{
+				foreach (ValueRange range in ranges)
+				{
+					if (!range.End.HasValue)
+					{
+						result.Add(new IsEqualRestriction(range.Start));
+					}
+					else
+					{
+						result.Add(new IsInRangeRestriction(range.Start, range.End.Value));
+					}
+				}
+			}
+
+			return result;
+		}
+
+		private static IEnumerable<IRestriction> CreateRestrictions(ValueMap map)
+		{
+			if ((map != null) && (map.Count > 0))
+			{
+				return CreateRestrictions(map.GetContinousRanges());
+			}
+
+			return new List<IRestriction>();
+		}
+
+		private static IEnumerable<IRestriction> CreateRestrictions(BitsType bt)
+		{
+			List<IRestriction> result = new List<IRestriction>();
+
+			if ((bt != null) && (bt.Map != null))
+			{
+				result.Add(new BitMaskRestriction(bt.Map.GetBitMask()));
+			}
+
+			return result;
+		}
+
+		private static SnmpTableNode GenerateSnmpTableNode(MibTreeNode mibTreeNode, SnmpTreeNode parentNode)
+		{
+			SnmpTableNode result = new SnmpTableNode(parentNode);
+			result.Name = mibTreeNode.Entity.Name;
+			result.Oid  = mibTreeNode.Entity.Value;
+
+			// expect exactly one row entry
+			if ((mibTreeNode.ChildNodes.Count != 1) || ((mibTreeNode.ChildNodes[0].NodeType & MibTreeNodeType.TableRow) == 0) || (mibTreeNode.ChildNodes[0].Entity.Value != 1))
+			{
+				Console.WriteLine("Found table with unsupported properties! Table needs exactly one (fixed) TableRow with OID=1 ! (" + mibTreeNode.Entity.Name + ")");
+				return null;
+			}
+
+			MibTreeNode rowNode = mibTreeNode.ChildNodes[0];
+			
+			ObjectType rot = rowNode.Entity as ObjectType;
+			if (rot != null)
+			{
+				if (!String.IsNullOrWhiteSpace(rot.Augments))
+				{
+					result.AugmentedTableRow = rot.Augments;
+
+					// the indeces from another table shall be used because this table is only an extension of it
+					rot = MibTypesResolver.ResolveDeclaration(rot.Module, rot.Augments) as ObjectType;
+				}
+
+				if (rot.Indices != null)
+				{
+					foreach (string index in rot.Indices)
+					{
+						ObjectType indexEntity = MibTypesResolver.ResolveDeclaration(rot.Module, index) as ObjectType;
+						if (indexEntity == null)
+						{
+							Console.WriteLine(String.Format("Could not resolve index '{0}' for table '{1}'! Table omitted!", index, result.Name));
+							return null;
+						}
+
+						result.IndexNodes.Add(GenerateSnmpScalarNode(indexEntity, parentNode, ignoreAccessibleFlag: true));
+					}
+				}
+			}
+
+			if (result.IndexNodes.Count == 0)
+			{
+				// a table cannot be used without index
+				Console.WriteLine("Found table without any index column ! (" + mibTreeNode.Entity.Name + ")");
+				return null;
+			}
+
+			// add child nodes
+			foreach (MibTreeNode cellNode in rowNode.ChildNodes)
+			{
+				SnmpScalarNode ssn = GenerateSnmpScalarNode(cellNode, parentNode);
+				if (ssn != null)
+				{
+					result.CellNodes.Add(ssn);
+				}
+			}
+
+			return result;
+		}
+
+		#endregion
+
+	}
+}
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/LwipMibCompiler/Properties/AssemblyInfo.cs
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/LwipMibCompiler/Properties/AssemblyInfo.cs	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/LwipMibCompiler/Properties/AssemblyInfo.cs	(revision 457)
@@ -0,0 +1,36 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// Allgemeine Informationen uber eine Assembly werden uber die folgenden 
+// Attribute gesteuert. Andern Sie diese Attributwerte, um die Informationen zu andern,
+// die mit einer Assembly verknupft sind.
+[assembly: AssemblyTitle("ConsoleApplication28")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("ConsoleApplication28")]
+[assembly: AssemblyCopyright("Copyright c  2015")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Durch Festlegen von ComVisible auf "false" werden die Typen in dieser Assembly unsichtbar 
+// fur COM-Komponenten. Wenn Sie auf einen Typ in dieser Assembly von 
+// COM zugreifen mussen, legen Sie das ComVisible-Attribut fur diesen Typ auf "true" fest.
+[assembly: ComVisible(false)]
+
+// Die folgende GUID bestimmt die ID der Typbibliothek, wenn dieses Projekt fur COM verfugbar gemacht wird
+[assembly: Guid("0abf7541-6a96-43cd-9e24-462e074b2c96")]
+
+// Versionsinformationen fur eine Assembly bestehen aus den folgenden vier Werten:
+//
+//      Hauptversion
+//      Nebenversion 
+//      Buildnummer
+//      Revision
+//
+// Sie konnen alle Werte angeben oder die standardmasigen Build- und Revisionsnummern 
+// ubernehmen, indem Sie "*" eingeben:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/LwipMibCompiler/app.config
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/LwipMibCompiler/app.config	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/LwipMibCompiler/app.config	(revision 457)
@@ -0,0 +1,3 @@
+<?xml version="1.0"?>
+<configuration>
+<startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/></startup></configuration>
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/LwipSnmpCodeGeneration/IRestriction.cs
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/LwipSnmpCodeGeneration/IRestriction.cs	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/LwipSnmpCodeGeneration/IRestriction.cs	(revision 457)
@@ -0,0 +1,120 @@
+/*
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Martin Hentschel <info@cl-soft.de>
+ *
+ */
+
+using System;
+
+namespace LwipSnmpCodeGeneration
+{
+	public interface IRestriction
+	{
+		string GetCheckCodeValid(string varNameToCheck);
+		string GetCheckCodeInvalid(string varNameToCheck);
+	}
+
+	public class BitMaskRestriction : IRestriction
+	{
+		UInt32 mask;
+
+		public BitMaskRestriction(UInt32 mask)
+		{
+			this.mask = mask;
+		}
+
+		public string GetCheckCodeValid(string varNameToCheck)
+		{
+			return String.Format("(({0} & {1}) == {0})", varNameToCheck, this.mask);
+		}
+
+		public string GetCheckCodeInvalid(string varNameToCheck)
+		{
+			return String.Format("(({0} & {1}) != {0})", varNameToCheck, this.mask);
+		}
+	}
+
+	public class IsEqualRestriction : IRestriction
+	{
+		private Int64 value;
+
+		public IsEqualRestriction(Int64 value)
+		{
+			this.value = value;
+		}
+
+		public long Value
+		{
+			get { return value; }
+		}
+
+		public string GetCheckCodeValid(string varNameToCheck)
+		{
+			return String.Format("({0} == {1})", varNameToCheck, this.value);
+		}
+
+		public string GetCheckCodeInvalid(string varNameToCheck)
+		{
+			return String.Format("({0} != {1})", varNameToCheck, this.value);
+		}
+	}
+
+	public class IsInRangeRestriction : IRestriction
+	{
+		private Int64 rangeStart;
+		private Int64 rangeEnd;
+
+		public IsInRangeRestriction(Int64 rangeStart, Int64 rangeEnd)
+		{
+			this.rangeStart = rangeStart;
+			this.rangeEnd   = rangeEnd;
+		}
+
+		public long RangeStart
+		{
+			get { return this.rangeStart; }
+		}
+
+		public long RangeEnd
+		{
+			get { return this.rangeEnd; }
+		}
+
+		public string GetCheckCodeValid(string varNameToCheck)
+		{
+			return String.Format("(({0} >= {1}) && ({0} <= {2}))", varNameToCheck, this.rangeStart, this.rangeEnd);
+		}
+
+		public string GetCheckCodeInvalid(string varNameToCheck)
+		{
+			return String.Format("(({0} < {1}) || ({0} > {2}))", varNameToCheck, this.rangeStart, this.rangeEnd);
+		}
+	}
+
+}
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/LwipSnmpCodeGeneration/LwipSnmp.cs
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/LwipSnmpCodeGeneration/LwipSnmp.cs	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/LwipSnmpCodeGeneration/LwipSnmp.cs	(revision 457)
@@ -0,0 +1,199 @@
+/*
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Martin Hentschel <info@cl-soft.de>
+ *
+ */
+
+using System;
+
+namespace LwipSnmpCodeGeneration
+{
+	public static class LwipOpts
+	{
+		public static bool GenerateEmptyFolders = false;
+		/// <summary>
+		/// If a tree node only has scalar nodes as child nodes, it is replaced by
+		/// a single scalar array node in order to save memory and have only one single get/test/set method for all scalars.
+		/// </summary>
+		public static bool GenerateScalarArrays = true;
+		/// <summary>
+		/// If a tree node has multiple scalars as subnodes as well as other treenodes it
+		/// defines a single get/test/set method for all scalar child node.
+		/// (without other treenodes as child it would have been converted to scalar array node).
+		/// </summary>
+		public static bool GenerateSingleAccessMethodsForTreeNodeScalars = GenerateScalarArrays;
+	}
+
+	public static class LwipDefs
+	{
+		public const string Null        = "NULL";
+		public const string Vt_U8       = "u8_t";
+		public const string Vt_U16      = "u16_t";
+		public const string Vt_U32      = "u32_t";
+		public const string Vt_S8       = "s8_t";
+		public const string Vt_S16      = "s16_t";
+		public const string Vt_S32      = "s32_t";
+		public const string Vt_Snmp_err = "snmp_err_t";
+
+		public const string Incl_SnmpOpts = "lwip/apps/snmp_opts.h";
+		public const string Opt_SnmpEnabled = "LWIP_SNMP";
+
+		public const string Vt_StMib                = "struct snmp_mib";
+		public const string Vt_StObjectId           = "struct snmp_obj_id";
+		public const string Vt_StNode               = "struct snmp_node";
+		public const string Vt_StNodeInstance       = "struct snmp_node_instance";
+		public const string Vt_StTreeNode           = "struct snmp_tree_node";
+		public const string Vt_StScalarNode         = "struct snmp_scalar_node";
+		public const string Vt_StScalarArrayNode    = "struct snmp_scalar_array_node";
+		public const string Vt_StScalarArrayNodeDef = "struct snmp_scalar_array_node_def";
+		public const string Vt_StTableNode          = "struct snmp_table_node";
+		public const string Vt_StTableColumnDef     = "struct snmp_table_col_def";
+		public const string Vt_StNextOidState       = "struct snmp_next_oid_state";
+
+		public const string Def_NodeAccessReadOnly      = "SNMP_NODE_INSTANCE_READ_ONLY";
+		public const string Def_NodeAccessReadWrite     = "SNMP_NODE_INSTANCE_READ_WRITE";
+		public const string Def_NodeAccessWriteOnly     = "SNMP_NODE_INSTANCE_WRITE_ONLY";
+		public const string Def_NodeAccessNotAccessible = "SNMP_NODE_INSTANCE_NOT_ACCESSIBLE";
+
+		public const string Def_ErrorCode_Ok             = "SNMP_ERR_NOERROR";
+		public const string Def_ErrorCode_WrongValue     = "SNMP_ERR_WRONGVALUE";
+		public const string Def_ErrorCode_NoSuchInstance = "SNMP_ERR_NOSUCHINSTANCE";
+
+		public const string FnctSuffix_GetValue        = "_get_value";
+		public const string FnctSuffix_SetTest         = "_set_test";
+		public const string FnctSuffix_SetValue        = "_set_value";
+		public const string FnctSuffix_GetInstance     = "_get_instance";
+		public const string FnctSuffix_GetNextInstance = "_get_next_instance";
+
+		public const string FnctName_SetTest_Ok         = "snmp_set_test_ok";
+
+		public static string GetLwipDefForSnmpAccessMode(SnmpAccessMode am)
+		{
+			switch (am)
+			{
+				case SnmpAccessMode.ReadOnly: return Def_NodeAccessReadOnly;
+				case SnmpAccessMode.ReadWrite: return Def_NodeAccessReadWrite;
+				case SnmpAccessMode.NotAccessible: return Def_NodeAccessNotAccessible;
+				case SnmpAccessMode.WriteOnly: return Def_NodeAccessWriteOnly;
+				default: throw new NotSupportedException("Unknown SnmpAccessMode!");
+			}
+		}
+
+		public static string GetAsn1DefForSnmpDataType(SnmpDataType dt)
+		{
+			switch (dt)
+			{
+				// primitive
+				case SnmpDataType.Null:
+					return "SNMP_ASN1_TYPE_NULL";
+				case SnmpDataType.Bits:
+				case SnmpDataType.OctetString:
+					return "SNMP_ASN1_TYPE_OCTET_STRING";
+				case SnmpDataType.ObjectIdentifier:
+					return "SNMP_ASN1_TYPE_OBJECT_ID";				
+				case SnmpDataType.Integer:
+					return "SNMP_ASN1_TYPE_INTEGER";
+
+				// application
+				case SnmpDataType.IpAddress:
+					return "SNMP_ASN1_TYPE_IPADDR";
+				case SnmpDataType.Counter:
+					return "SNMP_ASN1_TYPE_COUNTER";
+				case SnmpDataType.Gauge:
+					return "SNMP_ASN1_TYPE_GAUGE";
+				case SnmpDataType.TimeTicks:
+					return "SNMP_ASN1_TYPE_TIMETICKS";
+				case SnmpDataType.Opaque:
+					return "SNMP_ASN1_TYPE_OPAQUE";
+				case SnmpDataType.Counter64:
+					return "SNMP_ASN1_TYPE_COUNTER64";
+				default:
+					throw new NotSupportedException("Unknown SnmpDataType!");
+			}
+		}
+
+		public static string GetLengthForSnmpDataType(SnmpDataType dt)
+		{
+			switch (dt)
+			{
+				case SnmpDataType.Null:
+					return "0";
+
+				case SnmpDataType.Integer:
+				case SnmpDataType.Counter:
+				case SnmpDataType.IpAddress:
+				case SnmpDataType.Gauge:
+				case SnmpDataType.TimeTicks:
+					return "4";
+
+				case SnmpDataType.Counter64:
+					return "8";
+
+				case SnmpDataType.OctetString:
+				case SnmpDataType.ObjectIdentifier:
+				case SnmpDataType.Bits:
+				case SnmpDataType.Opaque:
+					return null;
+
+				default:
+					throw new NotSupportedException("Unknown SnmpDataType!");
+			}
+		}
+	}
+
+	public enum SnmpDataType
+	{
+		Null,
+
+		Integer, // INTEGER, Integer32
+
+		Counter, // Counter, Counter32
+		Gauge,  // Gauge, Gauge32, Unsigned32
+		TimeTicks,
+
+		Counter64,
+
+		OctetString,
+		Opaque,
+		Bits,
+
+		ObjectIdentifier,
+		
+		IpAddress,
+	}
+
+	public enum SnmpAccessMode
+	{
+		ReadOnly,
+		ReadWrite,
+		WriteOnly,
+		NotAccessible
+	}
+
+}
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/LwipSnmpCodeGeneration/LwipSnmpCodeGeneration.csproj
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/LwipSnmpCodeGeneration/LwipSnmpCodeGeneration.csproj	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/LwipSnmpCodeGeneration/LwipSnmpCodeGeneration.csproj	(revision 457)
@@ -0,0 +1,72 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+    <ProductVersion>8.0.30703</ProductVersion>
+    <SchemaVersion>2.0</SchemaVersion>
+    <ProjectGuid>{AABCAB90-1540-45D4-A159-14831A54E9A3}</ProjectGuid>
+    <OutputType>Library</OutputType>
+    <AppDesignerFolder>Properties</AppDesignerFolder>
+    <RootNamespace>LwipSnmpCodeGeneration</RootNamespace>
+    <AssemblyName>LwipSnmpCodeGeneration</AssemblyName>
+    <TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
+    <FileAlignment>512</FileAlignment>
+    <TargetFrameworkProfile />
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+    <DebugSymbols>true</DebugSymbols>
+    <DebugType>full</DebugType>
+    <Optimize>false</Optimize>
+    <OutputPath>bin\Debug\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+    <DebugType>pdbonly</DebugType>
+    <Optimize>true</Optimize>
+    <OutputPath>bin\Release\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+  </PropertyGroup>
+  <ItemGroup>
+    <Reference Include="System" />
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="IRestriction.cs" />
+    <Compile Include="SnmpScalarNodeCounter64.cs" />
+    <Compile Include="SnmpScalarNodeTruthValue.cs" />
+    <Compile Include="SnmpScalarAggregationNode.cs" />
+    <Compile Include="SnmpTableNode.cs" />
+    <Compile Include="SnmpScalarArrayNode.cs" />
+    <Compile Include="MibHeaderFile.cs" />
+    <Compile Include="SnmpScalarNodeBits.cs" />
+    <Compile Include="SnmpMib.cs" />
+    <Compile Include="SnmpScalarNodeInt.cs" />
+    <Compile Include="SnmpScalarNodeObjectIdentifier.cs" />
+    <Compile Include="SnmpScalarNodeOctetString.cs" />
+    <Compile Include="SnmpScalarNodeUint.cs" />
+    <Compile Include="SnmpTreeNode.cs" />
+    <Compile Include="LwipSnmp.cs" />
+    <Compile Include="MibCFile.cs" />
+    <Compile Include="Properties\AssemblyInfo.cs" />
+    <Compile Include="SnmpNode.cs" />
+    <Compile Include="SnmpScalarNode.cs" />
+  </ItemGroup>
+  <ItemGroup>
+    <ProjectReference Include="..\CCodeGeneration\CCodeGeneration.csproj">
+      <Project>{7DA7C0AB-0982-4BF5-9324-F59A7A08D65B}</Project>
+      <Name>CCodeGeneration</Name>
+    </ProjectReference>
+  </ItemGroup>
+  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
+       Other similar extension points exist, see Microsoft.Common.targets.
+  <Target Name="BeforeBuild">
+  </Target>
+  <Target Name="AfterBuild">
+  </Target>
+  -->
+</Project>
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/LwipSnmpCodeGeneration/MibCFile.cs
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/LwipSnmpCodeGeneration/MibCFile.cs	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/LwipSnmpCodeGeneration/MibCFile.cs	(revision 457)
@@ -0,0 +1,196 @@
+/*
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Martin Hentschel <info@cl-soft.de>
+ *
+ */
+
+using System.Collections.Generic;
+using CCodeGeneration;
+using System;
+using System.IO;
+
+namespace LwipSnmpCodeGeneration
+{
+	public class MibCFile
+	{
+		#region Fields
+
+		private const string PreservedSectionMarker = "LWIP MIB generator - preserved section begin";
+		private const string PreservedSectionHeader = 
+			"+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n" +
+			PreservedSectionMarker + "\n" +
+			"Code below is preserved on regeneration. Remove these comment lines to regenerate code.\n" +
+			"+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++";
+
+		private readonly List<CodeElement> includes = new List<CodeElement>();
+		private readonly List<CodeElement> defines = new List<CodeElement>();
+		private readonly List<CodeElement> declarations = new List<CodeElement>();
+		private readonly List<CodeElement> implementation = new List<CodeElement>();
+		private readonly List<CodeElement> preservedCode = new List<CodeElement>();
+
+		#endregion
+
+		public MibCFile()
+		{
+		}
+
+		#region Accessors
+
+		public List<CodeElement> Includes
+		{
+			get { return this.includes; }
+		}
+
+		public List<CodeElement> Defines
+		{
+			get { return this.defines; }
+		}
+
+		public List<CodeElement> Declarations
+		{
+			get { return this.declarations; }
+		}
+
+		public List<CodeElement> Implementation
+		{
+			get { return this.implementation; }
+		}
+
+		public List<CodeElement> PreservedCode
+		{
+			get { return this.preservedCode; }
+		}
+
+		#endregion
+
+		#region Methods
+
+		public void Save(CGenerator cGenerator)
+		{
+			CFile cFile = new CFile();
+
+			cFile.AddElement(new Comment("Generated by LwipMibCompiler"));
+			cFile.AddElement(EmptyLine.SingleLine);
+
+			cFile.AddElement(new PP_Include(LwipDefs.Incl_SnmpOpts));
+			CodeContainerBase e = cFile.AddElement(new PP_If(LwipDefs.Opt_SnmpEnabled)) as CodeContainerBase;
+			e.AddElement(EmptyLine.SingleLine);
+
+			// include header file
+			string file = cGenerator.FileName;
+			if (!String.IsNullOrWhiteSpace(file))
+			{
+				string ext = System.IO.Path.GetExtension(file);
+
+				string headerFile = !String.IsNullOrEmpty(ext) ? file.Substring(0, file.Length - ext.Length) : file;
+				headerFile += ".h";
+
+				e.AddElement(new PP_Include(headerFile));								
+			}
+
+			// include common snmp files
+			e.AddElement(new PP_Include("lwip/apps/snmp.h"));
+			e.AddElement(new PP_Include("lwip/apps/snmp_core.h"));
+			e.AddElement(new PP_Include("lwip/apps/snmp_scalar.h"));
+			e.AddElement(new PP_Include("lwip/apps/snmp_table.h"));
+
+			if (this.includes.Count > 0)
+			{
+				e.AddElement(EmptyLine.SingleLine);
+				e.AddElements(this.includes);
+			}
+
+			if (this.defines.Count > 0)
+			{
+				e.AddElement(EmptyLine.SingleLine);
+				e.AddElements(this.defines);
+			}
+
+			if (this.declarations.Count > 0)
+			{
+				e.AddElement(EmptyLine.TwoLines);
+				e.AddElements(this.declarations);
+			}
+
+			if (this.implementation.Count > 0)
+			{
+				e.AddElement(EmptyLine.TwoLines);
+				e.AddElements(this.implementation);
+			}
+
+			if (this.preservedCode.Count > 0)
+			{
+				e.AddElement(EmptyLine.TwoLines);
+				e.AddElement(new Comment(PreservedSectionHeader));
+				e.AddElement(EmptyLine.SingleLine);
+				e.AddElements(this.preservedCode);
+			}
+
+			cFile.Save(cGenerator);
+		}
+
+		public static string GetPreservedCode(string file)
+		{
+			if (File.Exists(file))
+			{
+				using (StreamReader fileStream = new StreamReader(file))
+				{
+					while (!fileStream.EndOfStream)
+					{
+						string line = fileStream.ReadLine();
+						if (line == PreservedSectionMarker)
+						{
+							break;
+						}
+					}
+
+					if (!fileStream.EndOfStream)
+					{
+						// skip the rest of the comment + spacer line
+						fileStream.ReadLine(); // "Code below is preserved...
+						fileStream.ReadLine(); // "+++++++++++++++++++++++...
+						fileStream.ReadLine(); // */
+						fileStream.ReadLine(); //
+
+						string preservedCode = fileStream.ReadToEnd();
+
+						int lastEndif    = preservedCode.LastIndexOf("#endif", StringComparison.Ordinal);
+						preservedCode    = preservedCode.Remove(lastEndif);
+
+						return preservedCode;
+					}
+				}
+			}
+
+			return null;
+		}
+
+		#endregion
+	}
+}
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/LwipSnmpCodeGeneration/MibHeaderFile.cs
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/LwipSnmpCodeGeneration/MibHeaderFile.cs	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/LwipSnmpCodeGeneration/MibHeaderFile.cs	(revision 457)
@@ -0,0 +1,129 @@
+/*
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Martin Hentschel <info@cl-soft.de>
+ *
+ */
+
+using System.Collections.Generic;
+using System.Text.RegularExpressions;
+using CCodeGeneration;
+
+namespace LwipSnmpCodeGeneration
+{
+	public class MibHeaderFile
+	{
+
+		#region Fields
+
+		private readonly List<CodeElement> defines = new List<CodeElement>();
+		private readonly List<CodeElement> includes = new List<CodeElement>();
+		private readonly List<CodeElement> functionDeclarations = new List<CodeElement>();
+		private readonly List<CodeElement> variableDeclarations = new List<CodeElement>();
+
+		#endregion
+
+		public MibHeaderFile()
+		{
+		}
+
+		#region Accessors
+
+		public List<CodeElement> Defines
+		{
+			get { return this.defines; }
+		}
+
+		public List<CodeElement> Includes
+		{
+			get { return this.includes; }
+		}
+
+		public List<CodeElement> FunctionDeclarations
+		{
+			get { return this.functionDeclarations; }
+		}
+
+		public List<CodeElement> VariableDeclarations
+		{
+			get { return this.variableDeclarations; }
+		}
+
+		#endregion
+
+		#region Methods
+
+		public void Save(CGenerator cGenerator)
+		{
+			CFile cFile = new CFile();
+
+			cFile.AddElement(new Comment("Generated by LwipMibCompiler"));
+			cFile.AddElement(EmptyLine.SingleLine);
+			
+			string headerDefine = cGenerator.FileName;
+			headerDefine = new Regex("[^a-zA-Z0-9]").Replace(headerDefine, "_");
+			headerDefine = headerDefine.ToUpperInvariant();
+
+			CodeContainerBase e = cFile.AddElement(new PP_Ifdef(headerDefine, inverted: true)) as CodeContainerBase;
+			e.AddElement(new PP_Macro(headerDefine, headerDefine));
+			e.AddElement(EmptyLine.SingleLine);
+
+			e.AddElement(new PP_Include(LwipDefs.Incl_SnmpOpts));
+			e = e.AddElement(new PP_If(LwipDefs.Opt_SnmpEnabled)) as CodeContainerBase;
+			e.AddElement(EmptyLine.SingleLine);
+
+			CodeContainerBase cplusplusopen = e.AddElement(new PP_Ifdef("__cplusplus")) as CodeContainerBase;
+			cplusplusopen.AddElement(new Code("extern \"C\" {"));
+			e.AddElement(EmptyLine.SingleLine);
+
+			if (this.includes.Count > 0)
+			{
+				e.AddElements(this.includes);
+				e.AddElement(EmptyLine.SingleLine);
+			}
+
+			if (this.defines.Count > 0)
+			{
+				e.AddElements(this.defines);
+				e.AddElement(EmptyLine.SingleLine);
+			}
+			
+			e.AddElements(this.functionDeclarations, EmptyLine.SingleLine);
+			e.AddElements(this.variableDeclarations, EmptyLine.SingleLine);
+
+			e.AddElement(EmptyLine.SingleLine);
+			CodeContainerBase cplusplusclose = e.AddElement(new PP_Ifdef("__cplusplus")) as CodeContainerBase;
+			cplusplusclose.AddElement(new Code("}"));
+
+			e.AddElement(EmptyLine.SingleLine);
+			cFile.Save(cGenerator);
+		}
+
+		#endregion
+	}
+}
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/LwipSnmpCodeGeneration/Properties/AssemblyInfo.cs
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/LwipSnmpCodeGeneration/Properties/AssemblyInfo.cs	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/LwipSnmpCodeGeneration/Properties/AssemblyInfo.cs	(revision 457)
@@ -0,0 +1,36 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// Allgemeine Informationen uber eine Assembly werden uber die folgenden 
+// Attribute gesteuert. Andern Sie diese Attributwerte, um die Informationen zu andern,
+// die mit einer Assembly verknupft sind.
+[assembly: AssemblyTitle("LwipSnmpCodeGeneration")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("LwipSnmpCodeGeneration")]
+[assembly: AssemblyCopyright("Copyright c  2015")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Durch Festlegen von ComVisible auf "false" werden die Typen in dieser Assembly unsichtbar 
+// fur COM-Komponenten. Wenn Sie auf einen Typ in dieser Assembly von 
+// COM zugreifen mussen, legen Sie das ComVisible-Attribut fur diesen Typ auf "true" fest.
+[assembly: ComVisible(false)]
+
+// Die folgende GUID bestimmt die ID der Typbibliothek, wenn dieses Projekt fur COM verfugbar gemacht wird
+[assembly: Guid("8cfbbb8b-dfbb-4dd5-80c9-e07845dd58c9")]
+
+// Versionsinformationen fur eine Assembly bestehen aus den folgenden vier Werten:
+//
+//      Hauptversion
+//      Nebenversion 
+//      Buildnummer
+//      Revision
+//
+// Sie konnen alle Werte angeben oder die standardmasigen Build- und Revisionsnummern 
+// ubernehmen, indem Sie "*" eingeben:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/LwipSnmpCodeGeneration/SnmpMib.cs
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/LwipSnmpCodeGeneration/SnmpMib.cs	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/LwipSnmpCodeGeneration/SnmpMib.cs	(revision 457)
@@ -0,0 +1,97 @@
+/*
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Martin Hentschel <info@cl-soft.de>
+ *
+ */
+
+using System;
+using System.Text;
+using CCodeGeneration;
+
+namespace LwipSnmpCodeGeneration
+{
+	public class SnmpMib : SnmpTreeNode
+	{
+		public uint[] BaseOid { get; set; }
+
+		public SnmpMib()
+			: base(null)
+		{
+		}
+
+		public SnmpMib(uint[] baseOid)
+			: base(null)
+		{
+			this.BaseOid = baseOid;
+		}
+
+		public override string FullNodeName
+		{
+			get { return this.Name.ToLowerInvariant() + "_root"; }
+		}
+
+		public override void GenerateCode(MibCFile mibFile)
+		{
+			base.GenerateCode(mibFile);
+
+			System.Diagnostics.Debug.Assert((this.BaseOid != null) && (this.BaseOid.Length > 0));
+			
+			// create and add BaseOID declarations
+			StringBuilder boidInitialization = new StringBuilder("{");
+			foreach (uint t in this.BaseOid)
+			{
+				boidInitialization.Append(t);
+				boidInitialization.Append(",");
+			}
+			boidInitialization.Length -= 1;
+			boidInitialization.Append("}");
+
+			VariableDeclaration boidDecl = new VariableDeclaration(
+				new VariableType(this.Name.ToLowerInvariant() + "_base_oid", LwipDefs.Vt_U32, null, ConstType.Value, String.Empty),
+				boidInitialization.ToString(), true);
+
+			mibFile.Declarations.Add(boidDecl);
+			mibFile.Declarations.Add(GetExportDeclaration());
+		}
+
+		public override void GenerateHeaderCode(MibHeaderFile mibHeaderFile)
+		{
+			mibHeaderFile.Includes.Add(new PP_Include("lwip/apps/snmp_core.h"));
+
+			mibHeaderFile.VariableDeclarations.Add(VariablePrototype.FromVariableDeclaration(GetExportDeclaration()));
+		}
+
+		VariableDeclaration GetExportDeclaration()
+		{
+			return new VariableDeclaration(
+				new VariableType(this.Name.ToLowerInvariant(), LwipDefs.Vt_StMib, null, ConstType.Value),
+				String.Format("{{{0}_base_oid, LWIP_ARRAYSIZE({0}_base_oid), &{1}.node}}", this.Name.ToLowerInvariant(), this.FullNodeName));
+		}
+	}
+}
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/LwipSnmpCodeGeneration/SnmpNode.cs
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/LwipSnmpCodeGeneration/SnmpNode.cs	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/LwipSnmpCodeGeneration/SnmpNode.cs	(revision 457)
@@ -0,0 +1,119 @@
+/*
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Martin Hentschel <info@cl-soft.de>
+ *
+ */
+
+using System;
+using System.Text.RegularExpressions;
+using CCodeGeneration;
+
+namespace LwipSnmpCodeGeneration
+{
+	public abstract class SnmpNode
+	{
+		public static readonly Regex NameValidationRegex = new Regex(@"^\w+$");
+
+		private string name;
+		private readonly SnmpTreeNode parentNode;
+
+		protected SnmpNode(SnmpTreeNode parentNode)
+		{
+			this.parentNode = parentNode;
+		}
+
+		public SnmpTreeNode ParentNode
+		{
+			get { return this.parentNode; }
+		}
+
+		public virtual uint Oid { get; set; }
+
+		public abstract string FullNodeName
+		{
+			get;
+		}
+
+		public virtual string Name
+		{
+			get { return this.name; }
+			set
+			{
+				if (value != this.name)
+				{
+					// check for valid name
+					if (!NameValidationRegex.IsMatch(value))
+					{
+						throw new ArgumentOutOfRangeException("Name");
+					}
+
+					this.name = value;
+				}
+			}
+		}
+
+		public virtual void Generate(MibCFile generatedFile, MibHeaderFile generatedHeaderFile)
+		{
+			int declCount = generatedFile.Declarations.Count;
+			int implCount = generatedFile.Implementation.Count;
+
+			this.GenerateHeaderCode(generatedHeaderFile);
+			this.GenerateCode(generatedFile);
+
+			if (generatedFile.Declarations.Count != declCount)
+			{
+				generatedFile.Declarations.Add(EmptyLine.SingleLine);
+			}
+			if (generatedFile.Implementation.Count != implCount)
+			{
+				generatedFile.Implementation.Add(EmptyLine.SingleLine);
+			}
+		}
+
+		public abstract void GenerateCode(MibCFile mibFile);
+
+		public virtual void GenerateHeaderCode(MibHeaderFile mibHeaderFile)
+		{
+		}
+
+		/// <summary>
+		/// Called after node structure creation is completed and before code is created.
+		/// Offers the possibility to perform operations depending on properties/subnodes.
+		/// If the node shall be transformed to another node(-type) than the own instance
+		/// may be replaced on parent node by the transformed instance.
+		/// Calling sequence is always from leafs up to root. So a tree node can assume
+		/// that the analyze method was already called on all child nodes.
+		/// E.g. a tree node only has scalar sub nodes -> it transforms itself to a scalar array node
+		/// </summary>
+		/// <returns>The transformed node or null if nothing shall be changed in parent structure.</returns>
+		public virtual void Analyze()
+		{
+		}
+	}
+}
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/LwipSnmpCodeGeneration/SnmpScalarAggregationNode.cs
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/LwipSnmpCodeGeneration/SnmpScalarAggregationNode.cs	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/LwipSnmpCodeGeneration/SnmpScalarAggregationNode.cs	(revision 457)
@@ -0,0 +1,293 @@
+/*
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Martin Hentschel <info@cl-soft.de>
+ *
+ */
+
+using System.Collections.Generic;
+using System.Globalization;
+using CCodeGeneration;
+
+namespace LwipSnmpCodeGeneration
+{
+	public abstract class SnmpScalarAggregationNode: SnmpNode
+	{
+		private bool getMethodRequired  = false;
+		private bool testMethodRequired = false;
+		private bool setMethodRequired  = false;
+
+		protected SnmpScalarAggregationNode(SnmpTreeNode parentNode)
+			: base(parentNode)
+		{
+		}
+
+		protected virtual string GetMethodName
+		{
+			get { return this.FullNodeName + LwipDefs.FnctSuffix_GetValue; }
+		}
+
+		protected bool GetMethodRequired
+		{
+			get { return this.getMethodRequired; }
+		}
+
+		protected virtual string TestMethodName
+		{
+			get { return this.FullNodeName + LwipDefs.FnctSuffix_SetTest; }
+		}
+
+		protected bool TestMethodRequired
+		{
+			get { return this.testMethodRequired; }
+		}
+
+		protected virtual string SetMethodName
+		{
+			get { return this.FullNodeName + LwipDefs.FnctSuffix_SetValue; }
+		}
+
+		protected bool SetMethodRequired
+		{
+			get { return this.setMethodRequired; }
+		}
+
+		protected abstract IEnumerable<SnmpScalarNode> AggregatedScalarNodes
+		{
+			get;
+		}
+
+		public override void Analyze()
+		{
+			base.Analyze();
+
+			this.getMethodRequired  = false;
+			this.testMethodRequired = false;
+			this.setMethodRequired  = false;
+
+			foreach (SnmpScalarNode scalarNode in this.AggregatedScalarNodes)
+			{
+				if ((scalarNode.AccessMode == SnmpAccessMode.ReadOnly) || (scalarNode.AccessMode == SnmpAccessMode.ReadWrite))
+				{
+					this.getMethodRequired = true;
+				}
+				if ((scalarNode.AccessMode == SnmpAccessMode.WriteOnly) || (scalarNode.AccessMode == SnmpAccessMode.ReadWrite))
+				{
+					this.testMethodRequired = true;
+					this.setMethodRequired = true;
+				}
+
+				if (this.getMethodRequired && this.setMethodRequired)
+				{
+					break;
+				}
+			}
+		}
+
+		protected void GenerateAggregatedCode(MibCFile mibFile, VariableType instanceType, string switchSelector, bool generateDeclarations = true, bool generateImplementations = true)
+		{
+			if (this.getMethodRequired)
+			{
+				FunctionDeclaration getMethodDecl = new FunctionDeclaration(this.GetMethodName, isStatic: true);
+				getMethodDecl.Parameter.Add(instanceType);
+				getMethodDecl.Parameter.Add(new VariableType("value", VariableType.VoidString, "*"));
+				getMethodDecl.ReturnType = new VariableType(null, LwipDefs.Vt_S16);
+
+				if (generateDeclarations)
+				{
+					mibFile.Declarations.Add(getMethodDecl);
+				}
+				if (generateImplementations)
+				{
+					Function getMethod = Function.FromDeclaration(getMethodDecl);
+					GenerateGetMethodCode(getMethod, switchSelector);
+					mibFile.Implementation.Add(getMethod);
+				}
+			}
+	
+			if (this.testMethodRequired)
+			{
+				FunctionDeclaration testMethodDecl = new FunctionDeclaration(this.TestMethodName, isStatic: true);
+				testMethodDecl.Parameter.Add(instanceType);
+				testMethodDecl.Parameter.Add(new VariableType("len", LwipDefs.Vt_U16));
+				testMethodDecl.Parameter.Add(new VariableType("value", VariableType.VoidString, "*"));
+				testMethodDecl.ReturnType = new VariableType(null, LwipDefs.Vt_Snmp_err);
+
+				if (generateDeclarations)
+				{
+					mibFile.Declarations.Add(testMethodDecl);
+				}
+				if (generateImplementations)
+				{
+					Function testMethod = Function.FromDeclaration(testMethodDecl);
+					GenerateTestMethodCode(testMethod, switchSelector);
+					mibFile.Implementation.Add(testMethod);
+				}
+			}
+
+			if (this.setMethodRequired)
+			{
+				FunctionDeclaration setMethodDecl = new FunctionDeclaration(this.SetMethodName, isStatic: true);
+				setMethodDecl.Parameter.Add(instanceType);
+				setMethodDecl.Parameter.Add(new VariableType("len", LwipDefs.Vt_U16));
+				setMethodDecl.Parameter.Add(new VariableType("value", VariableType.VoidString, "*"));
+				setMethodDecl.ReturnType = new VariableType(null, LwipDefs.Vt_Snmp_err);
+				
+				if (generateDeclarations)
+				{
+					mibFile.Declarations.Add(setMethodDecl);
+				}
+				if (generateImplementations)
+				{
+					Function setMethod = Function.FromDeclaration(setMethodDecl);
+					GenerateSetMethodCode(setMethod, switchSelector);
+					mibFile.Implementation.Add(setMethod);
+				}
+			}
+		}
+
+		protected virtual void GenerateGetMethodCode(Function getMethod, string switchSelector)
+		{
+			VariableDeclaration returnValue = new VariableDeclaration((VariableType)getMethod.ReturnType.Clone());
+			returnValue.Type.Name = "value_len";
+			getMethod.Declarations.Add(returnValue);
+			Switch sw = new Switch(switchSelector);
+
+			bool valueVarUsed = false;
+
+			foreach (SnmpScalarNode scalarNode in this.AggregatedScalarNodes)
+			{
+				if ((scalarNode.AccessMode == SnmpAccessMode.ReadOnly) || (scalarNode.AccessMode == SnmpAccessMode.ReadWrite))
+				{
+					SwitchCase sc = new SwitchCase(scalarNode.Oid.ToString(CultureInfo.InvariantCulture));
+					sc.Declarations.Add(new Comment(scalarNode.Name, singleLine: true));
+
+					scalarNode.GenerateGetMethodCode(sc, getMethod.Parameter[1].Name, ref valueVarUsed, returnValue.Type.Name);
+
+					sw.Switches.Add(sc);
+				}
+			}
+
+			SwitchCase scd = SwitchCase.GenerateDefault();
+			scd.AddCodeFormat("LWIP_DEBUGF(SNMP_MIB_DEBUG,(\"{0}(): unknown id: %\"S32_F\"\\n\", {1}));", getMethod.Name, switchSelector);
+			scd.AddCodeFormat("{0} = 0;", returnValue.Type.Name);
+			sw.Switches.Add(scd);
+
+			if (!valueVarUsed)
+			{
+				getMethod.AddCodeFormat("LWIP_UNUSED_ARG({0});", getMethod.Parameter[1].Name);
+			}
+
+			getMethod.AddElement(sw);
+
+			getMethod.AddCodeFormat("return {0};", returnValue.Type.Name);
+		}
+
+		protected virtual void GenerateTestMethodCode(Function testMethod, string switchSelector)
+		{
+			VariableDeclaration returnValue = new VariableDeclaration((VariableType)testMethod.ReturnType.Clone(), LwipDefs.Def_ErrorCode_WrongValue);
+			returnValue.Type.Name = "err";
+			testMethod.Declarations.Add(returnValue);
+			Switch sw = new Switch(switchSelector);
+
+			bool valueVarUsed = false;
+			bool lenVarUsed = false;
+
+			foreach (SnmpScalarNode scalarNode in this.AggregatedScalarNodes)
+			{
+				if ((scalarNode.AccessMode == SnmpAccessMode.WriteOnly) || (scalarNode.AccessMode == SnmpAccessMode.ReadWrite))
+				{
+					SwitchCase sc = new SwitchCase(scalarNode.Oid.ToString(CultureInfo.InvariantCulture));
+					sc.Declarations.Add(new Comment(scalarNode.Name, singleLine: true));
+
+					scalarNode.GenerateTestMethodCode(sc, testMethod.Parameter[2].Name, ref valueVarUsed, testMethod.Parameter[1].Name, ref lenVarUsed, returnValue.Type.Name);
+
+					sw.Switches.Add(sc);
+				}
+			}
+
+			SwitchCase scd = SwitchCase.GenerateDefault();
+			scd.AddCodeFormat("LWIP_DEBUGF(SNMP_MIB_DEBUG,(\"{0}(): unknown id: %\"S32_F\"\\n\", {1}));", testMethod.Name, switchSelector);
+			sw.Switches.Add(scd);
+
+			if (!valueVarUsed)
+			{
+				testMethod.AddCodeFormat("LWIP_UNUSED_ARG({0});", testMethod.Parameter[2].Name);
+			}
+			if (!lenVarUsed)
+			{
+				testMethod.AddCodeFormat("LWIP_UNUSED_ARG({0});", testMethod.Parameter[1].Name);
+			}
+
+			testMethod.AddElement(sw);
+
+			testMethod.AddCodeFormat("return {0};", returnValue.Type.Name);
+		}
+
+		protected virtual void GenerateSetMethodCode(Function setMethod, string switchSelector)
+		{
+			VariableDeclaration returnValue = new VariableDeclaration((VariableType)setMethod.ReturnType.Clone(), LwipDefs.Def_ErrorCode_Ok);
+			returnValue.Type.Name = "err";
+			setMethod.Declarations.Add(returnValue);
+			Switch sw = new Switch(switchSelector);
+
+			bool valueVarUsed = false;
+			bool lenVarUsed = false;
+			
+			foreach (SnmpScalarNode scalarNode in this.AggregatedScalarNodes)
+			{
+				if ((scalarNode.AccessMode == SnmpAccessMode.WriteOnly) || (scalarNode.AccessMode == SnmpAccessMode.ReadWrite))
+				{
+					SwitchCase sc = new SwitchCase(scalarNode.Oid.ToString(CultureInfo.InvariantCulture));
+					sc.Declarations.Add(new Comment(scalarNode.Name, singleLine: true));
+
+					scalarNode.GenerateSetMethodCode(sc, setMethod.Parameter[2].Name, ref valueVarUsed, setMethod.Parameter[1].Name, ref lenVarUsed, returnValue.Type.Name);
+
+					sw.Switches.Add(sc);
+				}
+			}
+
+			SwitchCase scd = SwitchCase.GenerateDefault();
+			scd.AddCodeFormat("LWIP_DEBUGF(SNMP_MIB_DEBUG,(\"{0}(): unknown id: %\"S32_F\"\\n\", {1}));", setMethod.Name, switchSelector);
+			sw.Switches.Add(scd);
+
+			if (!valueVarUsed)
+			{
+				setMethod.AddCodeFormat("LWIP_UNUSED_ARG({0});", setMethod.Parameter[2].Name);
+			}
+			if (!lenVarUsed)
+			{
+				setMethod.AddCodeFormat("LWIP_UNUSED_ARG({0});", setMethod.Parameter[1].Name);
+			}
+
+			setMethod.AddElement(sw);
+
+			setMethod.AddCodeFormat("return {0};", returnValue.Type.Name);
+		}
+	}
+}
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/LwipSnmpCodeGeneration/SnmpScalarArrayNode.cs
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/LwipSnmpCodeGeneration/SnmpScalarArrayNode.cs	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/LwipSnmpCodeGeneration/SnmpScalarArrayNode.cs	(revision 457)
@@ -0,0 +1,105 @@
+/*
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Martin Hentschel <info@cl-soft.de>
+ *
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+using CCodeGeneration;
+
+namespace LwipSnmpCodeGeneration
+{
+	public class SnmpScalarArrayNode : SnmpScalarAggregationNode
+	{
+		private readonly List<SnmpScalarNode> scalarNodes;
+
+		public SnmpScalarArrayNode(List<SnmpScalarNode> scalarNodes, SnmpTreeNode parentNode)
+			: base(parentNode)
+		{
+			this.scalarNodes = scalarNodes;
+		}
+
+		public override string FullNodeName
+		{
+			get { return this.Name.ToLowerInvariant() + "_scalars"; }
+		}
+
+		protected override IEnumerable<SnmpScalarNode> AggregatedScalarNodes
+		{
+			get { return this.scalarNodes; }
+		}
+
+		public override void GenerateCode(MibCFile mibFile)
+		{
+			VariableType instanceType = new VariableType("node", LwipDefs.Vt_StScalarArrayNodeDef, "*", ConstType.Value);
+			GenerateAggregatedCode(
+				mibFile,
+				instanceType,
+				instanceType.Name + "->oid");
+
+
+			// create and add node definitions
+			StringBuilder nodeDefs = new StringBuilder();
+			foreach (SnmpScalarNode scalarNode in this.scalarNodes)
+			{
+				nodeDefs.AppendFormat("  {{{0}, {1}, {2}}}, /* {3} */ \n",
+					scalarNode.Oid,
+					LwipDefs.GetAsn1DefForSnmpDataType(scalarNode.DataType),
+					LwipDefs.GetLwipDefForSnmpAccessMode(scalarNode.AccessMode),
+					scalarNode.Name);
+			}
+			if (nodeDefs.Length > 0)
+				nodeDefs.Length--;
+
+			VariableDeclaration nodeDefsDecl = new VariableDeclaration(
+				new VariableType(this.FullNodeName + "_nodes", LwipDefs.Vt_StScalarArrayNodeDef, null, ConstType.Value, String.Empty),
+				"{\n" + nodeDefs + "\n}" ,
+				isStatic: true);
+
+			mibFile.Declarations.Add(nodeDefsDecl);
+
+
+			// create and add node declaration
+			string nodeInitialization = String.Format("SNMP_SCALAR_CREATE_ARRAY_NODE({0}, {1}, {2}, {3}, {4})",
+				this.Oid,
+				nodeDefsDecl.Type.Name,
+				(this.GetMethodRequired) ? this.GetMethodName : LwipDefs.Null,
+				(this.TestMethodRequired) ? this.TestMethodName : LwipDefs.Null,
+				(this.SetMethodRequired) ? this.SetMethodName : LwipDefs.Null
+				);
+
+			mibFile.Declarations.Add(new VariableDeclaration(
+				new VariableType(this.FullNodeName, LwipDefs.Vt_StScalarArrayNode, null, ConstType.Value),
+				nodeInitialization,
+				isStatic: true));
+		}
+	}
+}
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/LwipSnmpCodeGeneration/SnmpScalarNode.cs
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/LwipSnmpCodeGeneration/SnmpScalarNode.cs	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/LwipSnmpCodeGeneration/SnmpScalarNode.cs	(revision 457)
@@ -0,0 +1,395 @@
+/*
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Martin Hentschel <info@cl-soft.de>
+ *
+ */
+
+using System;
+using System.Collections.Generic;
+using CCodeGeneration;
+
+namespace LwipSnmpCodeGeneration
+{
+	public class SnmpScalarNode: SnmpNode
+	{
+		protected const string LocalValueName = "v"; // name of (casted) local value variable
+
+		private SnmpDataType dataType;
+		private SnmpAccessMode accessMode;
+		private readonly List<IRestriction> restrictions = new List<IRestriction>();
+
+		private bool   useExternalMethods = false;
+		private string externalGetMethod;
+		private string externalTestMethod;
+		private string externalSetMethod;
+
+
+		public SnmpScalarNode(SnmpTreeNode parentNode)
+			: base(parentNode)
+		{
+		}
+
+		public override string FullNodeName
+		{
+			get { return this.Name.ToLowerInvariant() + "_scalar"; }
+		}
+
+		public SnmpDataType DataType
+		{
+			get { return this.dataType; }
+			set { this.dataType = value; }
+		}
+
+		public List<IRestriction> Restrictions
+		{
+			get { return this.restrictions; }
+		}
+
+		public SnmpAccessMode AccessMode
+		{
+			get { return this.accessMode; }
+			set { this.accessMode = value; }
+		}
+
+		public virtual string FixedValueLength
+		{
+			get { return null; }
+		}
+
+		/// <summary>
+		/// If scalar is used as a table index its value becomes part of the OID. This value returns how many OID parts are required to represent this value.
+		/// </summary>
+		public virtual int OidRepresentationLen
+		{
+			get { return -1; }
+		}
+
+		public bool UseExternalMethods
+		{
+			get { return this.useExternalMethods; }
+			set { this.useExternalMethods = value; }
+		}
+
+		public string ExternalGetMethod
+		{
+			get { return this.externalGetMethod; }
+			set { this.externalGetMethod = value; }
+		}
+		public string ExternalTestMethod
+		{
+			get { return this.externalTestMethod; }
+			set { this.externalTestMethod = value; }
+		}
+		public string ExternalSetMethod
+		{
+			get { return this.externalSetMethod; }
+			set { this.externalSetMethod = value; }
+		}
+
+		public override void GenerateCode(MibCFile mibFile)
+		{
+			string getMethodName;
+			string testMethodName;
+			string setMethodName;
+
+			if (this.useExternalMethods)
+			{
+				getMethodName  = this.externalGetMethod;
+				testMethodName = this.externalTestMethod;
+				setMethodName  = this.externalSetMethod;
+			}
+			else
+			{
+				getMethodName  = LwipDefs.Null;
+				testMethodName = LwipDefs.Null;
+				setMethodName  = LwipDefs.Null;
+				
+				if ((this.accessMode == SnmpAccessMode.ReadWrite) || (this.accessMode == SnmpAccessMode.ReadOnly))
+				{
+					FunctionDeclaration  getMethodDecl = new FunctionDeclaration(this.Name + LwipDefs.FnctSuffix_GetValue, isStatic: true);
+					getMethodDecl.Parameter.Add(new VariableType("instance", LwipDefs.Vt_StNodeInstance, "*"));
+					getMethodDecl.Parameter.Add(new VariableType("value", VariableType.VoidString, "*"));
+					getMethodDecl.ReturnType = new VariableType(null, LwipDefs.Vt_S16);
+					mibFile.Declarations.Add(getMethodDecl);
+
+					Function getMethod = Function.FromDeclaration(getMethodDecl);
+					getMethodName = getMethod.Name;
+
+					VariableDeclaration returnValue = new VariableDeclaration((VariableType)getMethod.ReturnType.Clone());
+					returnValue.Type.Name = "value_len";
+					getMethod.Declarations.Add(returnValue);
+					getMethod.AddCodeFormat("LWIP_UNUSED_ARG({0});", getMethod.Parameter[0].Name);
+
+					bool valueVarUsed = false;
+					GenerateGetMethodCode(getMethod, getMethod.Parameter[1].Name, ref valueVarUsed, returnValue.Type.Name);
+					if (!valueVarUsed)
+					{
+						getMethod.AddCodeFormat("LWIP_UNUSED_ARG({0});", getMethod.Parameter[1].Name);
+					}
+
+					getMethod.AddCodeFormat("return {0};", returnValue.Type.Name);
+
+					mibFile.Implementation.Add(getMethod);
+				}
+
+				if ((this.accessMode == SnmpAccessMode.ReadWrite) || (this.accessMode == SnmpAccessMode.WriteOnly))
+				{
+					bool valueVarUsed;
+					bool lenVarUsed;
+					VariableDeclaration returnValue;
+
+					if (this.restrictions.Count > 0)
+					{
+						FunctionDeclaration testMethodDecl = new FunctionDeclaration(this.Name + LwipDefs.FnctSuffix_SetTest, isStatic: true);
+						testMethodDecl.Parameter.Add(new VariableType("instance", LwipDefs.Vt_StNodeInstance, "*"));
+						testMethodDecl.Parameter.Add(new VariableType("len", LwipDefs.Vt_U16));
+						testMethodDecl.Parameter.Add(new VariableType("value", VariableType.VoidString, "*"));
+						testMethodDecl.ReturnType = new VariableType(null, LwipDefs.Vt_Snmp_err);
+						mibFile.Declarations.Add(testMethodDecl);
+
+						Function testMethod = Function.FromDeclaration(testMethodDecl);
+						testMethodName = testMethod.Name;
+
+						returnValue = new VariableDeclaration((VariableType)testMethod.ReturnType.Clone(), LwipDefs.Def_ErrorCode_WrongValue);
+						returnValue.Type.Name = "err";
+						testMethod.Declarations.Add(returnValue);
+						testMethod.AddCodeFormat("LWIP_UNUSED_ARG({0});", testMethod.Parameter[0].Name);
+
+						valueVarUsed = false;
+						lenVarUsed = false;
+
+						GenerateTestMethodCode(testMethod, testMethod.Parameter[2].Name, ref valueVarUsed, testMethod.Parameter[1].Name, ref lenVarUsed, returnValue.Type.Name);
+
+						if (!valueVarUsed)
+						{
+							testMethod.AddCodeFormat("LWIP_UNUSED_ARG({0});", testMethod.Parameter[2].Name);
+						}
+						if (!lenVarUsed)
+						{
+							testMethod.AddCodeFormat("LWIP_UNUSED_ARG({0});", testMethod.Parameter[1].Name);
+						}
+
+						testMethod.AddCodeFormat("return {0};", returnValue.Type.Name);
+
+						mibFile.Implementation.Add(testMethod);
+
+					}
+					else
+					{
+						testMethodName = LwipDefs.FnctName_SetTest_Ok;
+					}
+
+					FunctionDeclaration setMethodDecl  = null;
+					setMethodDecl = new FunctionDeclaration(this.Name + LwipDefs.FnctSuffix_SetValue, isStatic: true);
+					setMethodDecl.Parameter.Add(new VariableType("instance", LwipDefs.Vt_StNodeInstance, "*"));
+					setMethodDecl.Parameter.Add(new VariableType("len", LwipDefs.Vt_U16));
+					setMethodDecl.Parameter.Add(new VariableType("value", VariableType.VoidString, "*"));
+					setMethodDecl.ReturnType = new VariableType(null, LwipDefs.Vt_Snmp_err);
+					mibFile.Declarations.Add(setMethodDecl);
+
+					Function setMethod = Function.FromDeclaration(setMethodDecl);
+					setMethodName = setMethod.Name;
+
+					returnValue = new VariableDeclaration((VariableType)setMethod.ReturnType.Clone(), LwipDefs.Def_ErrorCode_Ok);
+					returnValue.Type.Name = "err";
+					setMethod.Declarations.Add(returnValue);
+					setMethod.AddCodeFormat("LWIP_UNUSED_ARG({0});", setMethod.Parameter[0].Name);
+
+					valueVarUsed = false;
+					lenVarUsed = false;
+
+					GenerateSetMethodCode(setMethod, setMethod.Parameter[2].Name, ref valueVarUsed, setMethod.Parameter[1].Name, ref lenVarUsed, returnValue.Type.Name);
+
+					if (!valueVarUsed)
+					{
+						setMethod.AddCodeFormat("LWIP_UNUSED_ARG({0});", setMethod.Parameter[2].Name);
+					}
+					if (!lenVarUsed)
+					{
+						setMethod.AddCodeFormat("LWIP_UNUSED_ARG({0});", setMethod.Parameter[1].Name);
+					}
+
+					setMethod.AddCodeFormat("return {0};", returnValue.Type.Name);
+
+					mibFile.Implementation.Add(setMethod);
+				}
+			}
+
+			// create and add node declaration
+			string nodeInitialization;
+			if (this.accessMode == SnmpAccessMode.ReadOnly)
+			{
+				nodeInitialization = String.Format("SNMP_SCALAR_CREATE_NODE_READONLY({0}, {1}, {2})",
+					this.Oid,
+					LwipDefs.GetAsn1DefForSnmpDataType(this.dataType),
+					getMethodName);
+			}
+			else
+			{
+				nodeInitialization = String.Format("SNMP_SCALAR_CREATE_NODE({0}, {1}, {2}, {3}, {4}, {5})",
+					this.Oid,
+					LwipDefs.GetLwipDefForSnmpAccessMode(this.accessMode),
+					LwipDefs.GetAsn1DefForSnmpDataType(this.dataType),
+					getMethodName,
+					testMethodName,
+					setMethodName);
+			}
+
+			mibFile.Declarations.Add(new VariableDeclaration(
+				new VariableType(this.FullNodeName, LwipDefs.Vt_StScalarNode, null, ConstType.Value),
+				nodeInitialization, isStatic: true));
+		}
+
+		public virtual void GenerateGetMethodCode(CodeContainerBase container, string valueVarName, ref bool valueVarUsed, string retLenVarName)
+		{
+			bool localValueVarUsed;
+			if (GenerateValueDeclaration(container, LocalValueName, valueVarName))
+			{
+				valueVarUsed = true;
+				localValueVarUsed = false;
+			}
+			else
+			{
+				localValueVarUsed = true;  // do not generate UNUSED_ARG code
+			}
+
+			if (this.FixedValueLength == null)
+			{
+				// check that value with variable length fits into buffer
+				container.AddElement(new Comment(String.Format("TODO: take care that value with variable length fits into buffer: ({0} <= SNMP_MAX_VALUE_SIZE)", retLenVarName), singleLine: true));
+			}
+
+			GenerateGetMethodCodeCore(container, LocalValueName, ref localValueVarUsed, retLenVarName);
+			if (!localValueVarUsed)
+			{
+				container.AddCode(String.Format("LWIP_UNUSED_ARG({0});", LocalValueName));
+			}
+		}
+
+		protected virtual void GenerateGetMethodCodeCore(CodeContainerBase container, string localValueVarName, ref bool localValueVarUsed, string retLenVarName)
+		{
+			container.AddElement(new Comment(String.Format("TODO: put requested value to '*{0}' here", localValueVarName), singleLine: true));
+			container.AddCodeFormat("{0} = {1};", 
+				retLenVarName,
+				(!String.IsNullOrWhiteSpace(this.FixedValueLength)) ? this.FixedValueLength : "0");
+		}
+
+		public virtual void GenerateTestMethodCode(CodeContainerBase container, string valueVarName, ref bool valueVarUsed, string lenVarName, ref bool lenVarUsed, string retErrVarName)
+		{
+			if (this.Restrictions.Count > 0)
+			{
+				bool localVarUsed;
+				if (GenerateValueDeclaration(container, LocalValueName, valueVarName))
+				{
+					valueVarUsed = true;
+					localVarUsed = false;
+				}
+				else
+				{
+					localVarUsed = true;  // do not generate UNUSED_ARG code
+				}
+
+				if (!String.IsNullOrWhiteSpace(this.FixedValueLength))
+				{
+					// check for fixed value
+					container.AddCodeFormat("LWIP_ASSERT(\"Invalid length for datatype\", ({0} == {1}));", lenVarName, this.FixedValueLength);
+					lenVarUsed = true;
+				}
+
+				GenerateTestMethodCodeCore(container, LocalValueName, ref localVarUsed, lenVarName, ref lenVarUsed, retErrVarName);
+
+				if (!localVarUsed)
+				{
+					container.AddCode(String.Format("LWIP_UNUSED_ARG({0});", LocalValueName));
+				}
+			}
+			else
+			{
+				container.AddCodeFormat("{0} = {1};", retErrVarName, LwipDefs.Def_ErrorCode_Ok);
+			}
+		}
+
+		protected virtual void GenerateTestMethodCodeCore(CodeContainerBase container, string localValueVarName, ref bool localValueVarUsed, string lenVarName, ref bool lenVarUsed, string retErrVarName)
+		{
+			container.AddElement(new Comment(String.Format("TODO: test new value here:\nif (*{0} == ) {1} = {2};", localValueVarName, retErrVarName, LwipDefs.Def_ErrorCode_Ok)));
+		}
+
+		public virtual void GenerateSetMethodCode(CodeContainerBase container, string valueVarName, ref bool valueVarUsed, string lenVarName, ref bool lenVarUsed, string retErrVarName)
+		{
+			bool localVarUsed;
+			if (GenerateValueDeclaration(container, LocalValueName, valueVarName))
+			{
+				valueVarUsed = true;
+				localVarUsed = false;
+			}
+			else
+			{
+				localVarUsed = true; // do not generate UNUSED_ARG code
+			}
+
+			GenerateSetMethodCodeCore(container, LocalValueName, ref localVarUsed, lenVarName, ref lenVarUsed, retErrVarName);
+
+			if (!localVarUsed)
+			{
+				container.AddCode(String.Format("LWIP_UNUSED_ARG({0});", LocalValueName));
+			}
+		}
+
+		protected virtual void GenerateSetMethodCodeCore(CodeContainerBase container, string localValueVarName, ref bool localValueVarUsed, string lenVarName, ref bool lenVarUsed, string retErrVarName)
+		{
+			container.AddElement(new Comment(String.Format("TODO: store new value contained in '*{0}' here", localValueVarName), singleLine: true)); 
+		}
+
+
+		protected virtual bool GenerateValueDeclaration(CodeContainerBase container, string variableName, string sourceName)
+		{
+			container.AddDeclaration(new VariableDeclaration(
+				new VariableType(variableName, LwipDefs.Vt_U8, "*"),
+				"(" + new VariableType(null, LwipDefs.Vt_U8, "*") + ")" + sourceName));
+
+			return true;
+		}
+
+		public static SnmpScalarNode CreateFromDatatype(SnmpDataType dataType, SnmpTreeNode parentNode)
+		{
+			switch (dataType)
+			{
+				case SnmpDataType.Integer:
+					return new SnmpScalarNodeInt(parentNode);
+
+				case SnmpDataType.Gauge:
+				case SnmpDataType.Counter:
+				case SnmpDataType.TimeTicks:
+					return new SnmpScalarNodeUint(dataType, parentNode);
+			}
+
+			return new SnmpScalarNode(parentNode);
+		}
+	}
+}
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/LwipSnmpCodeGeneration/SnmpScalarNodeBits.cs
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/LwipSnmpCodeGeneration/SnmpScalarNodeBits.cs	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/LwipSnmpCodeGeneration/SnmpScalarNodeBits.cs	(revision 457)
@@ -0,0 +1,121 @@
+/*
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Martin Hentschel <info@cl-soft.de>
+ *
+ */
+
+using System;
+using System.Text;
+using CCodeGeneration;
+
+namespace LwipSnmpCodeGeneration
+{
+	public class SnmpScalarNodeBits : SnmpScalarNode
+	{
+		private readonly uint bitCount;
+
+		public SnmpScalarNodeBits(SnmpTreeNode parentNode, uint bitCount)
+			: base(parentNode)
+		{
+			this.DataType = SnmpDataType.Bits;
+			this.bitCount = bitCount;
+		}
+
+		public override void GenerateGetMethodCode(CodeContainerBase container, string valueVarName, ref bool valueVarUsed, string retLenVarName)
+		{
+			container.AddCode(String.Format(
+				"{0} = snmp_encode_bits(({1} *){2}, SNMP_MAX_VALUE_SIZE, 0 /* TODO: pass real value here */, {3});",
+				retLenVarName, 
+				LwipDefs.Vt_U8,
+				valueVarName,
+				this.bitCount));
+			
+			valueVarUsed = true;
+		}
+
+		public override void GenerateTestMethodCode(CodeContainerBase container, string valueVarName, ref bool valueVarUsed, string lenVarName, ref bool lenVarUsed, string retErrVarName)
+		{
+			if (this.Restrictions.Count > 0)
+			{
+				const string bitVarName = "bits";
+
+				container.Declarations.Add(new VariableDeclaration(new VariableType(bitVarName, LwipDefs.Vt_U32)));
+
+				IfThenElse ite = new IfThenElse(String.Format(
+					"snmp_decode_bits(({0} *){1}, {2}, &{3}) == ERR_OK",
+					LwipDefs.Vt_U8,
+					valueVarName,
+					lenVarName,
+					bitVarName));
+
+				valueVarUsed = true;
+				lenVarUsed = true;
+
+				StringBuilder innerIfCond = new StringBuilder();
+				foreach (IRestriction restriction in this.Restrictions)
+				{
+					innerIfCond.Append(restriction.GetCheckCodeValid(bitVarName));
+					innerIfCond.Append(" || ");
+				}
+
+				innerIfCond.Length -= 4;
+
+				IfThenElse innerIte = new IfThenElse(innerIfCond.ToString());
+				innerIte.AddCode(String.Format("{0} = {1};", retErrVarName, LwipDefs.Def_ErrorCode_Ok));
+				ite.AddElement(innerIte);
+				container.AddElement(ite);
+			}
+			else
+			{
+				base.GenerateTestMethodCode(container, valueVarName, ref valueVarUsed, lenVarName, ref lenVarUsed, retErrVarName);
+			}
+		}
+
+		public override void GenerateSetMethodCode(CodeContainerBase container, string valueVarName, ref bool valueVarUsed, string lenVarName, ref bool lenVarUsed, string retErrVarName)
+		{
+			const string bitVarName = "bits";
+
+			container.Declarations.Add(new VariableDeclaration(new VariableType(bitVarName, LwipDefs.Vt_U32)));
+
+			IfThenElse ite = new IfThenElse(String.Format(
+				"snmp_decode_bits(({0} *){1}, {2}, &{3}) == ERR_OK",
+				LwipDefs.Vt_U8,
+				valueVarName,
+				lenVarName,
+				bitVarName));
+
+			valueVarUsed = true;
+			lenVarUsed = true;
+
+			ite.AddElement(new Comment(String.Format("TODO: store new value contained in '{0}' here", bitVarName), singleLine: true));
+
+			container.AddElement(ite);
+		}
+	}
+}
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/LwipSnmpCodeGeneration/SnmpScalarNodeCounter64.cs
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/LwipSnmpCodeGeneration/SnmpScalarNodeCounter64.cs	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/LwipSnmpCodeGeneration/SnmpScalarNodeCounter64.cs	(revision 457)
@@ -0,0 +1,72 @@
+/*
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Martin Hentschel <info@cl-soft.de>
+ *
+ */
+
+using System;
+using System.Text;
+using CCodeGeneration;
+
+namespace LwipSnmpCodeGeneration
+{
+	public class SnmpScalarNodeCounter64 : SnmpScalarNode
+	{
+		public SnmpScalarNodeCounter64(SnmpTreeNode parentNode)
+			: base(parentNode)
+		{
+			this.DataType = SnmpDataType.Counter64;
+		}
+
+		protected override bool GenerateValueDeclaration(CodeContainerBase container, string variableName, string sourceName)
+		{
+			container.AddDeclaration(new VariableDeclaration(
+				new VariableType(variableName + "_high", LwipDefs.Vt_U32, "*"),
+				"(" + new VariableType(null, LwipDefs.Vt_U32, "*").ToString() + ")" + sourceName));
+			container.AddDeclaration(new VariableDeclaration(
+				new VariableType(variableName + "_low", LwipDefs.Vt_U32, "*"),
+				variableName + "_high + 1"));
+
+			container.AddCode(String.Format("LWIP_UNUSED_ARG({0}_high);", variableName));
+			container.AddCode(String.Format("LWIP_UNUSED_ARG({0}_low);", variableName));
+
+			return false;
+		}
+
+		public override string FixedValueLength
+		{
+			get { return String.Format("(2 * sizeof({0}))", LwipDefs.Vt_U32); }
+		}
+
+		public override int OidRepresentationLen
+		{
+			get { return 1; }
+		}
+	}
+}
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/LwipSnmpCodeGeneration/SnmpScalarNodeInt.cs
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/LwipSnmpCodeGeneration/SnmpScalarNodeInt.cs	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/LwipSnmpCodeGeneration/SnmpScalarNodeInt.cs	(revision 457)
@@ -0,0 +1,86 @@
+/*
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Martin Hentschel <info@cl-soft.de>
+ *
+ */
+
+using System;
+using System.Text;
+using CCodeGeneration;
+
+namespace LwipSnmpCodeGeneration
+{
+	public class SnmpScalarNodeInt : SnmpScalarNode
+	{
+		public SnmpScalarNodeInt(SnmpTreeNode parentNode)
+			: base(parentNode)
+		{
+			this.DataType = SnmpDataType.Integer;
+		}
+
+		protected override void GenerateTestMethodCodeCore(CodeContainerBase container, string localValueVarName, ref bool localValueVarUsed, string lenVarName, ref bool lenVarUsed, string retErrVarName)
+		{
+			System.Diagnostics.Trace.Assert(this.Restrictions.Count > 0);
+
+			StringBuilder ifCond = new StringBuilder();
+			foreach (IRestriction restriction in this.Restrictions)
+			{
+				ifCond.Append(restriction.GetCheckCodeValid("*" + localValueVarName));
+				ifCond.Append(" || ");
+
+				localValueVarUsed = true;
+			}
+
+			ifCond.Length -= 4;
+
+			IfThenElse ite = new IfThenElse(ifCond.ToString());
+			ite.AddCode(String.Format("{0} = {1};", retErrVarName, LwipDefs.Def_ErrorCode_Ok));
+			container.AddElement(ite);
+		}
+
+		protected override bool GenerateValueDeclaration(CodeContainerBase container, string variableName, string sourceName)
+		{
+			container.AddDeclaration(new VariableDeclaration(
+				new VariableType(variableName, LwipDefs.Vt_S32, "*"),
+				"(" + new VariableType(null, LwipDefs.Vt_S32, "*") + ")" + sourceName));
+
+			return true;
+		}
+
+		public override string FixedValueLength
+		{
+			get { return String.Format("sizeof({0})", LwipDefs.Vt_S32); }
+		}
+
+		public override int OidRepresentationLen
+		{
+			get { return 1; }
+		}
+	}
+}
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/LwipSnmpCodeGeneration/SnmpScalarNodeObjectIdentifier.cs
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/LwipSnmpCodeGeneration/SnmpScalarNodeObjectIdentifier.cs	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/LwipSnmpCodeGeneration/SnmpScalarNodeObjectIdentifier.cs	(revision 457)
@@ -0,0 +1,90 @@
+/*
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Martin Hentschel <info@cl-soft.de>
+ *
+ */
+
+using System;
+using CCodeGeneration;
+
+namespace LwipSnmpCodeGeneration
+{
+	public class SnmpScalarNodeObjectIdentifier: SnmpScalarNode
+	{
+		public SnmpScalarNodeObjectIdentifier(SnmpTreeNode parentNode)
+			: base(parentNode)
+		{
+			this.DataType = SnmpDataType.ObjectIdentifier;
+		}
+
+		protected override bool GenerateValueDeclaration(CodeContainerBase container, string variableName, string sourceName)
+		{
+			container.AddDeclaration(new VariableDeclaration(
+				new VariableType(variableName, LwipDefs.Vt_U32, "*"),
+				"(" + new VariableType(null, LwipDefs.Vt_U32, "*") + ")" + sourceName));
+
+			return true;
+		}
+
+		protected override void GenerateGetMethodCodeCore(CodeContainerBase container, string localValueVarName, ref bool localValueVarUsed, string retLenVarName)
+		{
+			container.AddElement(new Comment(String.Format("TODO: put requested value to '*{0}' here. '{0}' has to be interpreted as {1}[]", localValueVarName, LwipDefs.Vt_U32), singleLine: true));
+			container.AddElement(EmptyLine.SingleLine);
+			container.AddCode(String.Format("{0} = 0; // TODO: return real value length here (should be 'numOfElements * sizeof({1})')", retLenVarName, LwipDefs.Vt_U32));
+		}
+
+		protected override void GenerateTestMethodCodeCore(CodeContainerBase container, string localValueVarName, ref bool localValueVarUsed, string lenVarName, ref bool lenVarUsed, string retErrVarName)
+		{
+			VariableDeclaration objIdLenVar = new VariableDeclaration(
+				new VariableType(localValueVarName + "_len", LwipDefs.Vt_U8),
+				String.Format("{0} / sizeof({1})", lenVarName, LwipDefs.Vt_U32));
+			lenVarUsed = true;
+
+			container.Declarations.Add(objIdLenVar);
+
+			base.GenerateTestMethodCodeCore(container, localValueVarName, ref localValueVarUsed, lenVarName, ref lenVarUsed, retErrVarName);
+
+			container.AddCode(String.Format("LWIP_UNUSED_ARG({0});", objIdLenVar.Type.Name));
+		}
+
+		protected override void GenerateSetMethodCodeCore(CodeContainerBase container, string localValueVarName, ref bool localValueVarUsed, string lenVarName, ref bool lenVarUsed, string retErrVarName)
+		{
+			VariableDeclaration objIdLenVar = new VariableDeclaration(
+				new VariableType(localValueVarName + "_len", LwipDefs.Vt_U8),
+				String.Format("{0} / sizeof({1})", lenVarName, LwipDefs.Vt_U32));
+			lenVarUsed = true;
+
+			container.Declarations.Add(objIdLenVar);
+
+			base.GenerateSetMethodCodeCore(container, localValueVarName, ref localValueVarUsed, lenVarName, ref lenVarUsed, retErrVarName);
+
+			container.AddCode(String.Format("LWIP_UNUSED_ARG({0});", objIdLenVar.Type.Name));
+		}
+	}
+}
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/LwipSnmpCodeGeneration/SnmpScalarNodeOctetString.cs
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/LwipSnmpCodeGeneration/SnmpScalarNodeOctetString.cs	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/LwipSnmpCodeGeneration/SnmpScalarNodeOctetString.cs	(revision 457)
@@ -0,0 +1,118 @@
+/*
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Martin Hentschel <info@cl-soft.de>
+ *
+ */
+
+using System;
+using System.Text;
+using CCodeGeneration;
+
+namespace LwipSnmpCodeGeneration
+{
+	public class SnmpScalarNodeOctetString : SnmpScalarNode
+	{
+		public SnmpScalarNodeOctetString(SnmpDataType dataType, SnmpTreeNode parentNode)
+			: base(parentNode)
+		{
+			System.Diagnostics.Debug.Assert(
+				(dataType == SnmpDataType.OctetString) || 
+				 (dataType == SnmpDataType.Opaque) || 
+				 (dataType == SnmpDataType.IpAddress));
+
+			this.DataType = dataType;
+		}
+
+		protected override void GenerateGetMethodCodeCore(CodeContainerBase container, string localValueVarName, ref bool localValueVarUsed, string retLenVarName)
+		{
+			if (this.Restrictions.Count > 0)
+			{
+				StringBuilder ifCond = new StringBuilder();
+				foreach (IRestriction restriction in this.Restrictions)
+				{
+					ifCond.Append(restriction.GetCheckCodeValid(retLenVarName));
+					ifCond.Append(" || ");
+				}
+
+				ifCond.Length -= 4;
+				container.AddElement(new Comment("TODO: take care of len restrictions defined in MIB: " + ifCond, singleLine: true));
+			}
+			base.GenerateGetMethodCodeCore(container, localValueVarName, ref localValueVarUsed, retLenVarName);
+		}
+
+		protected override void GenerateTestMethodCodeCore(CodeContainerBase container, string localValueVarName, ref bool localValueVarUsed, string lenVarName, ref bool lenVarUsed, string retErrVarName)
+		{
+			System.Diagnostics.Trace.Assert(this.Restrictions.Count > 0);
+
+			// checks refer to length of octet string
+			StringBuilder ifCond = new StringBuilder();
+			foreach (IRestriction restriction in this.Restrictions)
+			{
+				ifCond.Append(restriction.GetCheckCodeValid(lenVarName));
+				ifCond.Append(" || ");
+
+				lenVarUsed = true;
+			}
+
+			ifCond.Length -= 4;
+
+			IfThenElse ite = new IfThenElse(ifCond.ToString());
+			ite.AddCode(String.Format("{0} = {1};", retErrVarName, LwipDefs.Def_ErrorCode_Ok));
+			container.AddElement(ite);
+		}
+
+		public override int OidRepresentationLen
+		{
+			get
+			{
+				// check restrictions if we are set to one fixed length
+				if ((this.Restrictions != null) && (this.Restrictions.Count > 0))
+				{
+					foreach (IRestriction restriction in this.Restrictions)
+					{
+						if (restriction is IsInRangeRestriction)
+						{
+							if ((restriction as IsInRangeRestriction).RangeStart == (restriction as IsInRangeRestriction).RangeEnd)
+							{
+								return (int)(restriction as IsInRangeRestriction).RangeStart;
+							}
+						}
+						else if (restriction is IsEqualRestriction)
+						{
+							return (int)(restriction as IsEqualRestriction).Value;
+						}
+					}
+				}
+
+				return -1; // variable length
+			}
+		}
+
+	}
+}
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/LwipSnmpCodeGeneration/SnmpScalarNodeTruthValue.cs
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/LwipSnmpCodeGeneration/SnmpScalarNodeTruthValue.cs	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/LwipSnmpCodeGeneration/SnmpScalarNodeTruthValue.cs	(revision 457)
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Martin Hentschel <info@cl-soft.de>
+ *
+ */
+
+using System;
+using CCodeGeneration;
+
+namespace LwipSnmpCodeGeneration
+{
+	public class SnmpScalarNodeTruthValue : SnmpScalarNodeInt
+	{
+		public SnmpScalarNodeTruthValue(SnmpTreeNode parentNode)
+			: base(parentNode)
+		{
+		}
+
+		protected override void GenerateGetMethodCodeCore(CodeContainerBase container, string localValueVarName, ref bool localValueVarUsed, string retLenVarName)
+		{
+			container.AddCodeFormat("snmp_encode_truthvalue({0}, /* TODO: put requested bool value here */ 0);", localValueVarName);
+			localValueVarUsed = true;
+			
+			container.AddCode(String.Format("{0} = {1};",
+				retLenVarName,
+				(!String.IsNullOrWhiteSpace(this.FixedValueLength)) ? this.FixedValueLength : "0"));
+		}
+
+		protected override void GenerateSetMethodCodeCore(CodeContainerBase container, string localValueVarName, ref bool localValueVarUsed, string lenVarName, ref bool lenVarUsed, string retErrVarName)
+		{
+			VariableType truthVar = new VariableType("bool_value", LwipDefs.Vt_U8);
+			container.Declarations.Add(new VariableDeclaration(truthVar));
+
+			container.AddCodeFormat("snmp_decode_truthvalue({0}, &{1});", localValueVarName, truthVar.Name);
+			localValueVarUsed = true;
+
+			container.AddElement(new Comment(String.Format("TODO: store new value contained in '{0}' here", truthVar.Name), singleLine: true)); 
+		}
+	}
+}
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/LwipSnmpCodeGeneration/SnmpScalarNodeUint.cs
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/LwipSnmpCodeGeneration/SnmpScalarNodeUint.cs	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/LwipSnmpCodeGeneration/SnmpScalarNodeUint.cs	(revision 457)
@@ -0,0 +1,91 @@
+/*
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Martin Hentschel <info@cl-soft.de>
+ *
+ */
+
+using System;
+using System.Text;
+using CCodeGeneration;
+
+namespace LwipSnmpCodeGeneration
+{
+	public class SnmpScalarNodeUint : SnmpScalarNode
+	{
+		public SnmpScalarNodeUint(SnmpDataType dataType, SnmpTreeNode parentNode)
+			: base(parentNode)
+		{
+			System.Diagnostics.Debug.Assert(
+				(dataType == SnmpDataType.Counter) || 
+				 (dataType == SnmpDataType.Gauge) || 
+				 (dataType == SnmpDataType.TimeTicks));
+
+			this.DataType = dataType;
+		}
+
+		protected override void GenerateTestMethodCodeCore(CodeContainerBase container, string localValueVarName, ref bool localValueVarUsed, string lenVarName, ref bool lenVarUsed, string retErrVarName)
+		{
+			System.Diagnostics.Trace.Assert(this.Restrictions.Count > 0);
+
+			StringBuilder ifCond = new StringBuilder();
+			foreach (IRestriction restriction in this.Restrictions)
+			{
+				ifCond.Append(restriction.GetCheckCodeValid("*" + localValueVarName));
+				ifCond.Append(" || ");
+
+				localValueVarUsed = true;
+			}
+
+			ifCond.Length -= 4;
+
+			IfThenElse ite = new IfThenElse(ifCond.ToString());
+			ite.AddCode(String.Format("{0} = {1};", retErrVarName, LwipDefs.Def_ErrorCode_Ok));
+			container.AddElement(ite);
+		}
+
+		protected override bool GenerateValueDeclaration(CodeContainerBase container, string variableName, string sourceName)
+		{
+			container.AddDeclaration(new VariableDeclaration(
+				new VariableType(variableName, LwipDefs.Vt_U32, "*"),
+				"(" + new VariableType(null, LwipDefs.Vt_U32, "*") + ")" + sourceName));
+
+			return true;
+		}
+
+		public override string FixedValueLength
+		{
+			get { return String.Format("sizeof({0})", LwipDefs.Vt_U32); }
+		}
+
+		public override int OidRepresentationLen
+		{
+			get { return 1; }
+		}
+	}
+}
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/LwipSnmpCodeGeneration/SnmpTableNode.cs
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/LwipSnmpCodeGeneration/SnmpTableNode.cs	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/LwipSnmpCodeGeneration/SnmpTableNode.cs	(revision 457)
@@ -0,0 +1,332 @@
+/*
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Martin Hentschel <info@cl-soft.de>
+ *
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+using CCodeGeneration;
+
+namespace LwipSnmpCodeGeneration
+{
+	public class SnmpTableNode: SnmpScalarAggregationNode
+	{
+		private readonly List<SnmpScalarNode> cellNodes = new List<SnmpScalarNode>();
+		private readonly List<SnmpScalarNode> indexNodes = new List<SnmpScalarNode>();
+		private string augmentedTableRow = null;
+
+
+		public SnmpTableNode(SnmpTreeNode parentNode)
+			: base(parentNode)
+		{
+		}
+
+		public List<SnmpScalarNode> CellNodes
+		{
+			get { return cellNodes; }
+		}
+
+		public List<SnmpScalarNode> IndexNodes
+		{
+			get { return indexNodes; }
+		}
+
+		public string AugmentedTableRow
+		{
+			get { return this.augmentedTableRow; }
+			set { this.augmentedTableRow = value; }
+		}
+
+		public override string FullNodeName
+		{
+			get
+			{
+				string result = this.Name.ToLowerInvariant();
+				if (!result.Contains("table"))
+				{
+					result += "_table";
+				}
+
+				return result;				
+			}
+		}
+
+		protected override IEnumerable<SnmpScalarNode> AggregatedScalarNodes
+		{
+			get { return this.cellNodes; }
+		}
+
+		public override void GenerateCode(MibCFile mibFile)
+		{
+			FunctionDeclaration getInstanceMethodDecl = new FunctionDeclaration(this.FullNodeName + LwipDefs.FnctSuffix_GetInstance, isStatic: true);
+			getInstanceMethodDecl.Parameter.Add(new VariableType("column", LwipDefs.Vt_U32, "*", ConstType.Value));
+			getInstanceMethodDecl.Parameter.Add(new VariableType("row_oid", LwipDefs.Vt_U32, "*", ConstType.Value));
+			getInstanceMethodDecl.Parameter.Add(new VariableType("row_oid_len", LwipDefs.Vt_U8, ""));
+			getInstanceMethodDecl.Parameter.Add(new VariableType("cell_instance", LwipDefs.Vt_StNodeInstance, "*"));
+			getInstanceMethodDecl.ReturnType = new VariableType(null, LwipDefs.Vt_Snmp_err);
+			mibFile.Declarations.Add(getInstanceMethodDecl);
+
+			Function getInstanceMethod = Function.FromDeclaration(getInstanceMethodDecl);
+			GenerateGetInstanceMethodCode(getInstanceMethod);
+			mibFile.Implementation.Add(getInstanceMethod);
+
+
+			FunctionDeclaration getNextInstanceMethodDecl = new FunctionDeclaration(this.FullNodeName + LwipDefs.FnctSuffix_GetNextInstance, isStatic: true);
+			getNextInstanceMethodDecl.Parameter.Add(new VariableType("column", LwipDefs.Vt_U32, "*", ConstType.Value));
+			getNextInstanceMethodDecl.Parameter.Add(new VariableType("row_oid", LwipDefs.Vt_StObjectId, "*"));
+			getNextInstanceMethodDecl.Parameter.Add(new VariableType("cell_instance", LwipDefs.Vt_StNodeInstance, "*"));
+			getNextInstanceMethodDecl.ReturnType = new VariableType(null, LwipDefs.Vt_Snmp_err);
+			mibFile.Declarations.Add(getNextInstanceMethodDecl);
+
+			Function getNextInstanceMethod = Function.FromDeclaration(getNextInstanceMethodDecl);
+			GenerateGetNextInstanceMethodCode(getNextInstanceMethod);
+			mibFile.Implementation.Add(getNextInstanceMethod);
+
+			
+			VariableType instanceType = new VariableType("cell_instance", LwipDefs.Vt_StNodeInstance, "*");
+			GenerateAggregatedCode(
+				mibFile,
+				instanceType,
+				String.Format("SNMP_TABLE_GET_COLUMN_FROM_OID({0}->instance_oid.id)", instanceType.Name));
+
+
+			#region create and add column/table definitions
+
+			StringBuilder colDefs = new StringBuilder();
+			foreach (SnmpScalarNode colNode in this.cellNodes)
+			{
+				colDefs.AppendFormat("  {{{0}, {1}, {2}}}, /* {3} */ \n",
+					colNode.Oid,
+					LwipDefs.GetAsn1DefForSnmpDataType(colNode.DataType),
+					LwipDefs.GetLwipDefForSnmpAccessMode(colNode.AccessMode),
+					colNode.Name);
+			}
+			if (colDefs.Length > 0)
+			{
+				colDefs.Length--;
+			}
+
+			VariableDeclaration colDefsDecl = new VariableDeclaration(
+				new VariableType(this.FullNodeName + "_columns", LwipDefs.Vt_StTableColumnDef, null, ConstType.Value, String.Empty),
+				"{\n" + colDefs + "\n}",
+				isStatic: true);
+
+			mibFile.Declarations.Add(colDefsDecl);
+
+			string nodeInitialization = String.Format("SNMP_TABLE_CREATE({0}, {1}, {2}, {3}, {4}, {5}, {6})",
+				this.Oid,
+				colDefsDecl.Type.Name,
+				getInstanceMethodDecl.Name, getNextInstanceMethodDecl.Name,
+				(this.GetMethodRequired) ? this.GetMethodName : LwipDefs.Null,
+				(this.TestMethodRequired) ? this.TestMethodName : LwipDefs.Null,
+				(this.SetMethodRequired) ? this.SetMethodName : LwipDefs.Null
+				);
+
+			mibFile.Declarations.Add(new VariableDeclaration(
+				new VariableType(this.FullNodeName, LwipDefs.Vt_StTableNode, null, ConstType.Value),
+				nodeInitialization,
+				isStatic: true));
+							
+			#endregion
+		}
+
+		protected virtual void GenerateGetInstanceMethodCode(Function getInstanceMethod)
+		{
+			VariableDeclaration returnValue = new VariableDeclaration((VariableType)getInstanceMethod.ReturnType.Clone(), LwipDefs.Def_ErrorCode_NoSuchInstance);
+			returnValue.Type.Name = "err";
+			getInstanceMethod.Declarations.Add(returnValue);
+
+			int instanceOidLength = 0;
+			StringBuilder indexColumns = new StringBuilder();
+			foreach (SnmpScalarNode indexNode in this.indexNodes)
+			{
+				if (instanceOidLength >= 0)
+				{
+					if (indexNode.OidRepresentationLen >= 0)
+					{
+						instanceOidLength += indexNode.OidRepresentationLen;
+					}
+					else
+					{
+						// at least one index column has a variable length -> we cannot perform a static check
+						instanceOidLength = -1;
+					}
+				}
+
+				indexColumns.AppendFormat(
+					" {0} ({1}, OID length = {2})\n",
+					indexNode.Name,
+					indexNode.DataType,
+					(indexNode.OidRepresentationLen >= 0) ? indexNode.OidRepresentationLen.ToString() : "variable");
+			}
+			if (indexColumns.Length > 0)
+			{
+				indexColumns.Length--;
+
+				getInstanceMethod.Declarations.Insert(0, new Comment(String.Format(
+					"The instance OID of this table consists of following (index) column(s):\n{0}",
+					indexColumns)));
+			}
+
+			string augmentsHint = "";
+			if (!String.IsNullOrWhiteSpace(this.augmentedTableRow))
+			{
+				augmentsHint = String.Format(
+					"This table augments table '{0}'! Index columns therefore belong to table '{0}'!\n" + 
+					"You may simply call the '*{1}' method of this table.\n\n",
+					(this.augmentedTableRow.ToLowerInvariant().EndsWith("entry")) ? this.augmentedTableRow.Substring(0, this.augmentedTableRow.Length-5) : this.augmentedTableRow,
+					LwipDefs.FnctSuffix_GetInstance);
+			}
+
+			CodeContainerBase ccb = getInstanceMethod;
+			if (instanceOidLength > 0)
+			{
+				IfThenElse ite = new IfThenElse(String.Format("{0} == {1}", getInstanceMethod.Parameter[2].Name, instanceOidLength));
+				getInstanceMethod.AddElement(ite);
+				ccb = ite;
+			}
+
+			ccb.AddCodeFormat("LWIP_UNUSED_ARG({0});", getInstanceMethod.Parameter[0].Name);
+			ccb.AddCodeFormat("LWIP_UNUSED_ARG({0});", getInstanceMethod.Parameter[1].Name);
+			if (instanceOidLength <= 0)
+			{
+				ccb.AddCodeFormat("LWIP_UNUSED_ARG({0});", getInstanceMethod.Parameter[2].Name);
+			}
+			ccb.AddCodeFormat("LWIP_UNUSED_ARG({0});", getInstanceMethod.Parameter[3].Name);
+
+			ccb.AddElement(new Comment(String.Format(
+				"TODO: check if '{0}'/'{1}' params contain a valid instance oid for a row\n" +
+				"If so, set '{2} = {3};'\n\n" + 
+				"snmp_oid_* methods may be used for easier processing of oid\n\n" + 
+				"{4}" + 
+				"In order to avoid decoding OID a second time in subsequent get_value/set_test/set_value methods,\n" +
+				"you may store an arbitrary value (like a pointer to target value object) in '{5}->reference'/'{5}->reference_len'.\n" +
+				"But be aware that not always a subsequent method is called -> Do NOT allocate memory here and try to release it in subsequent methods!\n\n" +
+				"You also may replace function pointers in '{5}' param for get/test/set methods which contain the default values from table definition,\n" +
+				"in order to provide special methods, for the currently processed cell. Changed pointers are only valid for current request.",
+				getInstanceMethod.Parameter[1].Name,
+				getInstanceMethod.Parameter[2].Name,
+				returnValue.Type.Name,
+				LwipDefs.Def_ErrorCode_Ok,
+				augmentsHint,
+				getInstanceMethod.Parameter[3].Name
+				)));
+
+			getInstanceMethod.AddCodeFormat("return {0};", returnValue.Type.Name);
+		}
+
+		protected virtual void GenerateGetNextInstanceMethodCode(Function getNextInstanceMethod)
+		{
+			getNextInstanceMethod.AddCodeFormat("LWIP_UNUSED_ARG({0});", getNextInstanceMethod.Parameter[0].Name);
+			getNextInstanceMethod.AddCodeFormat("LWIP_UNUSED_ARG({0});", getNextInstanceMethod.Parameter[1].Name);
+			getNextInstanceMethod.AddCodeFormat("LWIP_UNUSED_ARG({0});", getNextInstanceMethod.Parameter[2].Name);
+
+			VariableDeclaration returnValue = new VariableDeclaration((VariableType)getNextInstanceMethod.ReturnType.Clone(), LwipDefs.Def_ErrorCode_NoSuchInstance);
+			returnValue.Type.Name = "err";
+			getNextInstanceMethod.Declarations.Add(returnValue);
+
+			StringBuilder indexColumns = new StringBuilder();
+			foreach (SnmpScalarNode indexNode in this.indexNodes)
+			{
+				indexColumns.AppendFormat(
+					" {0} ({1}, OID length = {2})\n",
+					indexNode.Name,
+					indexNode.DataType,
+					(indexNode.OidRepresentationLen >= 0) ? indexNode.OidRepresentationLen.ToString() : "variable");
+			}
+			if (indexColumns.Length > 0)
+			{
+				indexColumns.Length--;
+
+				getNextInstanceMethod.Declarations.Insert(0, new Comment(String.Format(
+					"The instance OID of this table consists of following (index) column(s):\n{0}",
+					indexColumns)));
+			}
+
+			string augmentsHint = "";
+			if (!String.IsNullOrWhiteSpace(this.augmentedTableRow))
+			{
+				augmentsHint = String.Format(
+					"This table augments table '{0}'! Index columns therefore belong to table '{0}'!\n" + 
+					"You may simply call the '*{1}' method of this table.\n\n",
+					(this.augmentedTableRow.ToLowerInvariant().EndsWith("entry")) ? this.augmentedTableRow.Substring(0, this.augmentedTableRow.Length-5) : this.augmentedTableRow,
+					LwipDefs.FnctSuffix_GetNextInstance);
+			}
+
+			getNextInstanceMethod.AddElement(new Comment(String.Format(
+				"TODO: analyze '{0}->id'/'{0}->len' and return the subsequent row instance\n" +
+				"Be aware that '{0}->id'/'{0}->len' must not point to a valid instance or have correct instance length.\n" +
+				"If '{0}->len' is 0, return the first instance. If '{0}->len' is longer than expected, cut superfluous OID parts.\n" +
+				"If a valid next instance is found, store it in '{0}->id'/'{0}->len' and set '{1} = {2};'\n\n" + 
+				"snmp_oid_* methods may be used for easier processing of oid\n\n" + 
+				"{3}" + 
+				"In order to avoid decoding OID a second time in subsequent get_value/set_test/set_value methods,\n" +
+				"you may store an arbitrary value (like a pointer to target value object) in '{4}->reference'/'{4}->reference_len'.\n" +
+				"But be aware that not always a subsequent method is called -> Do NOT allocate memory here and try to release it in subsequent methods!\n\n" +
+				"You also may replace function pointers in '{4}' param for get/test/set methods which contain the default values from table definition,\n" +
+				"in order to provide special methods, for the currently processed cell. Changed pointers are only valid for current request.",
+				getNextInstanceMethod.Parameter[1].Name,
+				returnValue.Type.Name,
+				LwipDefs.Def_ErrorCode_Ok,
+				augmentsHint,
+				getNextInstanceMethod.Parameter[2].Name
+				)));
+
+			getNextInstanceMethod.AddElement(new Comment(String.Format(
+				"For easier processing and getting the next instance, you may use the 'snmp_next_oid_*' enumerator.\n" +
+				"Simply pass all known instance OID's to it and it returns the next valid one:\n\n" +
+				"{0} state;\n" +
+				"{1} result_buf;\n" +
+				"snmp_next_oid_init(&state, {2}->id, {2}->len, result_buf.id, SNMP_MAX_OBJ_ID_LEN);\n" + 
+				"while ({{not all instances passed}}) {{\n" + 
+				"  {1} test_oid;\n" + 
+				"  {{fill test_oid to create instance oid for next instance}}\n" + 
+				"  snmp_next_oid_check(&state, test_oid.id, test_oid.len, {{target_data_ptr}});\n" + 
+				"}}\n" + 
+				"if(state.status == SNMP_NEXT_OID_STATUS_SUCCESS) {{\n" + 
+				"  snmp_oid_assign(row_oid, state.next_oid, state.next_oid_len);\n" +
+				"  {3}->reference.ptr = state.reference; //==target_data_ptr, for usage in subsequent get/test/set\n" + 
+				"  {4} = {5};\n" + 
+				"}}"
+				,
+				LwipDefs.Vt_StNextOidState,
+				LwipDefs.Vt_StObjectId,
+				getNextInstanceMethod.Parameter[1].Name,
+				getNextInstanceMethod.Parameter[2].Name,
+				returnValue.Type.Name,
+				LwipDefs.Def_ErrorCode_Ok
+				)));
+
+			getNextInstanceMethod.AddCodeFormat("return {0};", returnValue.Type.Name);
+		}
+
+	}
+}
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/LwipSnmpCodeGeneration/SnmpTreeNode.cs
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/LwipSnmpCodeGeneration/SnmpTreeNode.cs	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/LwipSnmpCodeGeneration/SnmpTreeNode.cs	(revision 457)
@@ -0,0 +1,242 @@
+/*
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Martin Hentschel <info@cl-soft.de>
+ *
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+using CCodeGeneration;
+
+namespace LwipSnmpCodeGeneration
+{
+	public class SnmpTreeNode: SnmpScalarAggregationNode
+	{
+		private readonly List<SnmpNode> childNodes       = new List<SnmpNode>();
+		private readonly List<SnmpScalarNode> childScalarNodes = new List<SnmpScalarNode>();
+		private string fullOid = "";
+
+		public SnmpTreeNode(SnmpTreeNode parentNode)
+			: base(parentNode)
+		{
+		}
+
+		public override string FullNodeName
+		{
+			get { return this.Name.ToLowerInvariant() + "_treenode"; }
+		}
+
+		public string FullOid
+		{
+			get { return this.fullOid; }
+			set { this.fullOid = value; }
+		}
+
+		public List<SnmpNode> ChildNodes
+		{
+			get { return this.childNodes; }
+		}
+
+		protected override IEnumerable<SnmpScalarNode> AggregatedScalarNodes
+		{
+			get { return this.childScalarNodes; }
+		}
+
+		private void GenerateAggregatedCode(MibCFile mibFile, bool generateDeclarations, bool generateImplementations)
+		{
+			VariableType instanceType = new VariableType("instance", LwipDefs.Vt_StNodeInstance, "*");
+			base.GenerateAggregatedCode(
+				mibFile,
+				instanceType,
+				String.Format("{0}->node->oid", instanceType.Name),
+				generateDeclarations,
+				generateImplementations);
+		}
+
+		private void GenerateAggregateMethodDeclarations(MibCFile mibFile)
+		{
+			if (LwipOpts.GenerateSingleAccessMethodsForTreeNodeScalars && (this.childScalarNodes.Count > 1))
+			{
+				GenerateAggregatedCode(mibFile, true, false);
+			}
+		}
+
+		public override void GenerateCode(MibCFile mibFile)
+		{
+			string nodeInitialization;
+
+			if (LwipOpts.GenerateSingleAccessMethodsForTreeNodeScalars && (this.childScalarNodes.Count > 1))
+			{
+				GenerateAggregatedCode(mibFile, false, true);
+			}
+
+			// create and add node declaration
+			if (this.childNodes.Count > 0)
+			{
+				StringBuilder subnodeArrayInitialization = new StringBuilder();
+
+				for (int i=0; i<this.childNodes.Count; i++)
+				{
+					subnodeArrayInitialization.Append("  &");
+					subnodeArrayInitialization.Append(this.childNodes[i].FullNodeName);
+					subnodeArrayInitialization.Append(".node");
+					if (!(this.childNodes[i] is SnmpTreeNode))
+					{
+						subnodeArrayInitialization.Append(".node");
+					}
+
+					if (i < (this.childNodes.Count - 1))
+					{
+						subnodeArrayInitialization.Append(",\n");
+					}
+				}
+
+				VariableDeclaration subnodeArray = new VariableDeclaration(
+					new VariableType(this.Name.ToLowerInvariant() + "_subnodes", LwipDefs.Vt_StNode, "*", ConstType.Both, String.Empty),
+					"{\n" + subnodeArrayInitialization + "\n}",
+					isStatic: true);
+
+				mibFile.Declarations.Add(subnodeArray);
+
+				nodeInitialization = String.Format("SNMP_CREATE_TREE_NODE({0}, {1})", this.Oid, subnodeArray.Type.Name);
+			}
+			else
+			{
+				nodeInitialization = String.Format("SNMP_CREATE_EMPTY_TREE_NODE({0})", this.Oid);
+			}
+
+			mibFile.Declarations.Add(new VariableDeclaration(
+				new VariableType(this.FullNodeName, LwipDefs.Vt_StTreeNode, null, ConstType.Value),
+				nodeInitialization,
+				isStatic: true));
+		}
+
+		public override void Analyze()
+		{
+			this.childScalarNodes.Clear();
+
+			// delegate analyze (don't use enumerator because the child node may change our child collection by e.g. removing or replacing itself)
+			for (int i=this.ChildNodes.Count-1; i>=0; i--)
+			{
+				this.ChildNodes[i].Analyze();
+			}
+
+			// collect scalar nodes
+			foreach (SnmpNode childNode in this.childNodes)
+			{
+				SnmpScalarNode scalarNode = childNode as SnmpScalarNode;
+				if (scalarNode != null)
+				{
+					this.childScalarNodes.Add(scalarNode);
+				}
+			}
+
+			base.Analyze();
+
+			// check if we can merge this node to a scalar array node (all childs need to be scalars)
+			if (this.childNodes.Count > 0)
+			{
+				if (LwipOpts.GenerateScalarArrays && (this.childScalarNodes.Count == this.childNodes.Count) && (this.ParentNode != null))
+				{
+					SnmpScalarArrayNode scalarArrayNode = new SnmpScalarArrayNode(this.childScalarNodes, this.ParentNode);
+					scalarArrayNode.Oid  = this.Oid;
+					scalarArrayNode.Name = this.Name;
+					scalarArrayNode.Analyze();
+
+					for (int i=0; i<this.ParentNode.ChildNodes.Count; i++)
+					{
+						if (this.ParentNode.ChildNodes[i] == this)
+						{
+							this.ParentNode.ChildNodes.RemoveAt(i);
+							this.ParentNode.ChildNodes.Insert(i, scalarArrayNode);
+							break;
+						}
+					}
+				}
+				else if (LwipOpts.GenerateSingleAccessMethodsForTreeNodeScalars && (this.childScalarNodes.Count > 1))
+				{
+					foreach (SnmpScalarNode scalarNode in this.childScalarNodes)
+					{
+						scalarNode.UseExternalMethods = true;
+						scalarNode.ExternalGetMethod  = this.GetMethodName;
+						scalarNode.ExternalTestMethod = this.TestMethodName;
+						scalarNode.ExternalSetMethod  = this.SetMethodName;
+					}
+				}
+			}
+			else // if (this.childNodes.Count == 0)
+			{
+				if (!LwipOpts.GenerateEmptyFolders && (this.ParentNode != null))
+				{
+					// do not generate this empty folder because it only waste (static) memory
+					for (int i=0; i<this.ParentNode.ChildNodes.Count; i++)
+					{
+						if (this.ParentNode.ChildNodes[i] == this)
+						{
+							this.ParentNode.ChildNodes.RemoveAt(i);
+							break;
+						}
+					}
+				}
+			}
+		}
+
+		public override void Generate(MibCFile generatedFile, MibHeaderFile generatedHeaderFile)
+		{
+			// generate code of child nodes
+			foreach (SnmpNode childNode in this.childNodes)
+			{
+				if (childNode is SnmpTreeNode)
+				{
+					childNode.Generate(generatedFile, generatedHeaderFile);
+				}
+			}
+
+			Comment dividerComment = new Comment(
+				String.Format("--- {0} {1} -----------------------------------------------------", this.Name, this.fullOid),
+				singleLine: true);
+
+			generatedFile.Declarations.Add(dividerComment);
+			generatedFile.Implementation.Add(dividerComment);
+
+			this.GenerateAggregateMethodDeclarations(generatedFile);
+
+			foreach (SnmpNode childNode in this.childNodes)
+			{
+				if (!(childNode is SnmpTreeNode))
+				{
+					childNode.Generate(generatedFile, generatedHeaderFile);
+				}
+			}
+
+			base.Generate(generatedFile, generatedHeaderFile);
+		}
+	}
+}
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/MibViewer/FormMain.Designer.cs
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/MibViewer/FormMain.Designer.cs	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/MibViewer/FormMain.Designer.cs	(revision 457)
@@ -0,0 +1,166 @@
+namespace LwipMibViewer
+{
+	partial class FormMain
+	{
+		/// <summary>
+		/// Erforderliche Designervariable.
+		/// </summary>
+		private System.ComponentModel.IContainer components = null;
+
+		/// <summary>
+		/// Verwendete Ressourcen bereinigen.
+		/// </summary>
+		/// <param name="disposing">True, wenn verwaltete Ressourcen geloscht werden sollen; andernfalls False.</param>
+		protected override void Dispose(bool disposing)
+		{
+			if (disposing && (components != null))
+			{
+				components.Dispose();
+			}
+			base.Dispose(disposing);
+		}
+
+		#region Vom Windows Form-Designer generierter Code
+
+		/// <summary>
+		/// Erforderliche Methode fur die Designerunterstutzung.
+		/// Der Inhalt der Methode darf nicht mit dem Code-Editor geandert werden.
+		/// </summary>
+		private void InitializeComponent()
+		{
+            this.components = new System.ComponentModel.Container();
+            System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(FormMain));
+            this.treeMib = new System.Windows.Forms.TreeView();
+            this.imagelistTreeNodeImages = new System.Windows.Forms.ImageList(this.components);
+            this.splitContainerMain = new System.Windows.Forms.SplitContainer();
+            this.listviewNodeDetails = new System.Windows.Forms.ListView();
+            this.columnHeader1 = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
+            this.columnHeader2 = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
+            this.toolStripMain = new System.Windows.Forms.ToolStrip();
+            this.toolbuttonOpenMib = new System.Windows.Forms.ToolStripButton();
+            this.dialogOpenMib = new System.Windows.Forms.OpenFileDialog();
+            ((System.ComponentModel.ISupportInitialize)(this.splitContainerMain)).BeginInit();
+            this.splitContainerMain.Panel1.SuspendLayout();
+            this.splitContainerMain.Panel2.SuspendLayout();
+            this.splitContainerMain.SuspendLayout();
+            this.toolStripMain.SuspendLayout();
+            this.SuspendLayout();
+            // 
+            // treeMib
+            // 
+            this.treeMib.Dock = System.Windows.Forms.DockStyle.Fill;
+            this.treeMib.ImageIndex = 0;
+            this.treeMib.ImageList = this.imagelistTreeNodeImages;
+            this.treeMib.Location = new System.Drawing.Point(0, 0);
+            this.treeMib.Name = "treeMib";
+            this.treeMib.SelectedImageIndex = 0;
+            this.treeMib.Size = new System.Drawing.Size(1028, 418);
+            this.treeMib.TabIndex = 0;
+            this.treeMib.AfterSelect += new System.Windows.Forms.TreeViewEventHandler(this.treeMib_AfterSelect);
+            // 
+            // imagelistTreeNodeImages
+            // 
+            this.imagelistTreeNodeImages.ImageStream = ((System.Windows.Forms.ImageListStreamer)(resources.GetObject("imagelistTreeNodeImages.ImageStream")));
+            this.imagelistTreeNodeImages.TransparentColor = System.Drawing.Color.Transparent;
+            this.imagelistTreeNodeImages.Images.SetKeyName(0, "ntimgContainer");
+            this.imagelistTreeNodeImages.Images.SetKeyName(1, "ntimgTable");
+            this.imagelistTreeNodeImages.Images.SetKeyName(2, "ntimgRow");
+            this.imagelistTreeNodeImages.Images.SetKeyName(3, "ntimgColumn");
+            this.imagelistTreeNodeImages.Images.SetKeyName(4, "ntimgScalar");
+            this.imagelistTreeNodeImages.Images.SetKeyName(5, "ntimgUnknown");
+            // 
+            // splitContainerMain
+            // 
+            this.splitContainerMain.Dock = System.Windows.Forms.DockStyle.Fill;
+            this.splitContainerMain.Location = new System.Drawing.Point(0, 25);
+            this.splitContainerMain.Name = "splitContainerMain";
+            this.splitContainerMain.Orientation = System.Windows.Forms.Orientation.Horizontal;
+            // 
+            // splitContainerMain.Panel1
+            // 
+            this.splitContainerMain.Panel1.Controls.Add(this.treeMib);
+            // 
+            // splitContainerMain.Panel2
+            // 
+            this.splitContainerMain.Panel2.Controls.Add(this.listviewNodeDetails);
+            this.splitContainerMain.Size = new System.Drawing.Size(1028, 625);
+            this.splitContainerMain.SplitterDistance = 418;
+            this.splitContainerMain.TabIndex = 1;
+            // 
+            // listviewNodeDetails
+            // 
+            this.listviewNodeDetails.Columns.AddRange(new System.Windows.Forms.ColumnHeader[] {
+            this.columnHeader1,
+            this.columnHeader2});
+            this.listviewNodeDetails.Dock = System.Windows.Forms.DockStyle.Fill;
+            this.listviewNodeDetails.FullRowSelect = true;
+            this.listviewNodeDetails.HeaderStyle = System.Windows.Forms.ColumnHeaderStyle.None;
+            this.listviewNodeDetails.Location = new System.Drawing.Point(0, 0);
+            this.listviewNodeDetails.Name = "listviewNodeDetails";
+            this.listviewNodeDetails.Size = new System.Drawing.Size(1028, 203);
+            this.listviewNodeDetails.TabIndex = 0;
+            this.listviewNodeDetails.UseCompatibleStateImageBehavior = false;
+            this.listviewNodeDetails.View = System.Windows.Forms.View.Details;
+            // 
+            // columnHeader1
+            // 
+            this.columnHeader1.Text = "";
+            this.columnHeader1.Width = 150;
+            // 
+            // columnHeader2
+            // 
+            this.columnHeader2.Text = "";
+            this.columnHeader2.Width = 777;
+            // 
+            // toolStripMain
+            // 
+            this.toolStripMain.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
+            this.toolbuttonOpenMib});
+            this.toolStripMain.Location = new System.Drawing.Point(0, 0);
+            this.toolStripMain.Name = "toolStripMain";
+            this.toolStripMain.Size = new System.Drawing.Size(1028, 25);
+            this.toolStripMain.TabIndex = 2;
+            // 
+            // toolbuttonOpenMib
+            // 
+            this.toolbuttonOpenMib.Image = ((System.Drawing.Image)(resources.GetObject("toolbuttonOpenMib.Image")));
+            this.toolbuttonOpenMib.Name = "toolbuttonOpenMib";
+            this.toolbuttonOpenMib.Size = new System.Drawing.Size(65, 22);
+            this.toolbuttonOpenMib.Text = "Open...";
+            this.toolbuttonOpenMib.Click += new System.EventHandler(this.toolbuttonOpenMib_Click);
+            // 
+            // FormMain
+            // 
+            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+            this.ClientSize = new System.Drawing.Size(1028, 650);
+            this.Controls.Add(this.splitContainerMain);
+            this.Controls.Add(this.toolStripMain);
+            this.Name = "FormMain";
+            this.Text = "MIB Viewer";
+            this.WindowState = System.Windows.Forms.FormWindowState.Maximized;
+            this.splitContainerMain.Panel1.ResumeLayout(false);
+            this.splitContainerMain.Panel2.ResumeLayout(false);
+            ((System.ComponentModel.ISupportInitialize)(this.splitContainerMain)).EndInit();
+            this.splitContainerMain.ResumeLayout(false);
+            this.toolStripMain.ResumeLayout(false);
+            this.toolStripMain.PerformLayout();
+            this.ResumeLayout(false);
+            this.PerformLayout();
+
+		}
+
+		#endregion
+
+		private System.Windows.Forms.TreeView treeMib;
+        private System.Windows.Forms.SplitContainer splitContainerMain;
+        private System.Windows.Forms.ListView listviewNodeDetails;
+        private System.Windows.Forms.ColumnHeader columnHeader1;
+        private System.Windows.Forms.ColumnHeader columnHeader2;
+        private System.Windows.Forms.ImageList imagelistTreeNodeImages;
+        private System.Windows.Forms.ToolStrip toolStripMain;
+        private System.Windows.Forms.ToolStripButton toolbuttonOpenMib;
+        private System.Windows.Forms.OpenFileDialog dialogOpenMib;
+	}
+}
+
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/MibViewer/FormMain.cs
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/MibViewer/FormMain.cs	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/MibViewer/FormMain.cs	(revision 457)
@@ -0,0 +1,217 @@
+/*
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Martin Hentschel <info@cl-soft.de>
+ *
+ */
+
+using System.Windows.Forms;
+using Lextm.SharpSnmpLib.Mib;
+using Lextm.SharpSnmpLib.Mib.Elements;
+using Lextm.SharpSnmpLib.Mib.Elements.Types;
+using Lextm.SharpSnmpLib.Mib.Elements.Entities;
+using System.IO;
+
+namespace LwipMibViewer
+{
+	public partial class FormMain : Form
+	{
+		readonly ListViewGroup listviewgroupAbstract;
+		readonly ListViewGroup listviewgroupElement;
+		readonly ListViewGroup listviewgroupBaseType;
+		readonly ListViewGroup listviewgroupTypeChain;
+
+		public FormMain()
+		{
+			this.Font = SystemInformation.MenuFont;
+			InitializeComponent();
+
+			this.listviewgroupAbstract = new ListViewGroup("Abstract", System.Windows.Forms.HorizontalAlignment.Left);
+			this.listviewgroupElement = new ListViewGroup("Element Properties", System.Windows.Forms.HorizontalAlignment.Left);
+			this.listviewgroupBaseType = new ListViewGroup("Element Base Type", System.Windows.Forms.HorizontalAlignment.Left);
+			this.listviewgroupTypeChain = new ListViewGroup("Element Type Chain", System.Windows.Forms.HorizontalAlignment.Left);
+			this.listviewNodeDetails.Groups.AddRange(new System.Windows.Forms.ListViewGroup[] {
+					 listviewgroupAbstract,
+					 listviewgroupElement,
+					 listviewgroupBaseType,
+					 listviewgroupTypeChain});
+
+			try
+			{
+				DirectoryInfo dirInfo = new DirectoryInfo(Path.GetDirectoryName(Application.ExecutablePath));
+				if (dirInfo != null)
+				{
+					dirInfo = dirInfo.Parent;
+					if (dirInfo != null)
+					{
+						dirInfo = dirInfo.Parent;
+						if (dirInfo != null)
+						{
+							dirInfo = new DirectoryInfo(Path.Combine(dirInfo.FullName, "Mibs"));
+							if (dirInfo.Exists)
+							{
+								MibTypesResolver.RegisterResolver(new FileSystemMibResolver(dirInfo.FullName, true));
+							}
+						}
+					}
+				}
+			}
+			catch
+			{ }
+		}
+
+		#region GUI Event Handler
+
+		private void toolbuttonOpenMib_Click(object sender, System.EventArgs e)
+		{
+			if (this.dialogOpenMib.ShowDialog() == DialogResult.OK)
+			{
+				OpenMib(this.dialogOpenMib.FileName);
+			}
+		}
+
+		private void treeMib_AfterSelect(object sender, TreeViewEventArgs e)
+		{
+			listviewNodeDetails.Items.Clear();
+
+			if (e.Node != null)
+			{
+				MibTreeNode mtn = e.Node.Tag as MibTreeNode;
+				if (mtn != null)
+				{
+					listviewNodeDetails.Items.Add(new ListViewItem(new string[] { "Abstract", mtn.NodeType.ToString() }, this.listviewgroupAbstract));
+
+					listviewNodeDetails.Items.Add(new ListViewItem(new string[] { "Module", (mtn.Entity.Module != null) ? mtn.Entity.Module.Name : "" }, this.listviewgroupElement));
+					listviewNodeDetails.Items.Add(new ListViewItem(new string[] { "Type", mtn.Entity.GetType().Name }, this.listviewgroupElement));
+					listviewNodeDetails.Items.Add(new ListViewItem(new string[] { "Name", mtn.Entity.Name }, this.listviewgroupElement));
+					listviewNodeDetails.Items.Add(new ListViewItem(new string[] { "Description", mtn.Entity.Description }, this.listviewgroupElement));
+					listviewNodeDetails.Items.Add(new ListViewItem(new string[] { "OID", mtn.Entity.Value.ToString() }, this.listviewgroupElement));
+					listviewNodeDetails.Items.Add(new ListViewItem(new string[] { "Full OID", MibTypesResolver.ResolveOid(mtn.Entity).GetOidString() }, this.listviewgroupElement));
+					if (mtn.Entity is ObjectType)
+					{
+						listviewNodeDetails.Items.Add(new ListViewItem(new string[] { "Access", (mtn.Entity as ObjectType).Access.ToString() }, this.listviewgroupElement));
+					}
+
+					ITypeReferrer tr = mtn.Entity as ITypeReferrer;
+					if (tr != null)
+					{
+						ShowTypeDetails(listviewNodeDetails, this.listviewgroupBaseType, tr.BaseType);
+						ShowTypeChain(listviewNodeDetails, tr.ReferredType);
+					}
+				}
+			}
+		}
+
+		#endregion
+
+		#region Methods
+
+		private void OpenMib(string file)
+		{
+			try
+			{
+				MibDocument md = new MibDocument(file);
+				MibTypesResolver.ResolveTypes(md.Modules[0]);
+
+				this.treeMib.Nodes.Clear();
+				this.listviewNodeDetails.Items.Clear();
+
+				MibTree mt = new MibTree(md.Modules[0] as MibModule);
+				foreach (MibTreeNode mibTreeNode in mt.Root)
+				{
+					AddNode(mibTreeNode, this.treeMib.Nodes);
+
+					foreach (TreeNode node in this.treeMib.Nodes)
+					{
+						node.Expand();
+					}
+				}
+			}
+			catch
+			{
+			}
+		}
+
+		private void AddNode(MibTreeNode mibNode, TreeNodeCollection parentNodes)
+		{
+			int imgIndex = 5; //unknown
+			if ((mibNode.NodeType & MibTreeNodeType.Table) != 0)
+			{
+				imgIndex = 1;
+			}
+			else if ((mibNode.NodeType & MibTreeNodeType.TableRow) != 0)
+			{
+				imgIndex = 2;
+			}
+			else if ((mibNode.NodeType & MibTreeNodeType.TableCell) != 0)
+			{
+				imgIndex = 3;
+			}
+			else if ((mibNode.NodeType & MibTreeNodeType.Scalar) != 0)
+			{
+				imgIndex = 4;
+			}
+			else if ((mibNode.NodeType & MibTreeNodeType.Container) != 0)
+			{
+				imgIndex = 0;
+			}
+
+			TreeNode newNode = new TreeNode(mibNode.Entity.Name, imgIndex, imgIndex);
+			newNode.Tag = mibNode;
+
+			parentNodes.Add(newNode);
+
+			foreach (MibTreeNode child in mibNode.ChildNodes)
+			{
+				AddNode(child, newNode.Nodes);
+			}
+		}
+
+		private void ShowTypeChain(ListView lv, ITypeAssignment type)
+		{
+			ShowTypeDetails(lv, this.listviewgroupTypeChain, type);
+
+			ITypeReferrer tr = type as ITypeReferrer;
+			if ((tr != null) && (tr.ReferredType != null))
+			{
+				lv.Items.Add(new ListViewItem(new string[] { " >>>", "" }, this.listviewgroupTypeChain));
+				ShowTypeChain(listviewNodeDetails, tr.ReferredType);
+			}
+		}
+
+		private void ShowTypeDetails(ListView lv, ListViewGroup lvg, ITypeAssignment type)
+		{
+			lv.Items.Add(new ListViewItem(new string[] { "Module", (type.Module != null) ? type.Module.Name : "" }, lvg));
+			lv.Items.Add(new ListViewItem(new string[] { "Type", type.GetType().Name }, lvg));
+			lv.Items.Add(new ListViewItem(new string[] { "Name", type.Name }, lvg));
+		}
+
+		#endregion
+
+	}
+}
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/MibViewer/FormMain.resx
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/MibViewer/FormMain.resx	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/MibViewer/FormMain.resx	(revision 457)
@@ -0,0 +1,298 @@
+<?xml version="1.0" encoding="utf-8"?>
+<root>
+  <!-- 
+    Microsoft ResX Schema 
+    
+    Version 2.0
+    
+    The primary goals of this format is to allow a simple XML format 
+    that is mostly human readable. The generation and parsing of the 
+    various data types are done through the TypeConverter classes 
+    associated with the data types.
+    
+    Example:
+    
+    ... ado.net/XML headers & schema ...
+    <resheader name="resmimetype">text/microsoft-resx</resheader>
+    <resheader name="version">2.0</resheader>
+    <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
+    <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
+    <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
+    <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
+    <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
+        <value>[base64 mime encoded serialized .NET Framework object]</value>
+    </data>
+    <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
+        <comment>This is a comment</comment>
+    </data>
+                
+    There are any number of "resheader" rows that contain simple 
+    name/value pairs.
+    
+    Each data row contains a name, and value. The row also contains a 
+    type or mimetype. Type corresponds to a .NET class that support 
+    text/value conversion through the TypeConverter architecture. 
+    Classes that don't support this are serialized and stored with the 
+    mimetype set.
+    
+    The mimetype is used for serialized objects, and tells the 
+    ResXResourceReader how to depersist the object. This is currently not 
+    extensible. For a given mimetype the value must be set accordingly:
+    
+    Note - application/x-microsoft.net.object.binary.base64 is the format 
+    that the ResXResourceWriter will generate, however the reader can 
+    read any of the formats listed below.
+    
+    mimetype: application/x-microsoft.net.object.binary.base64
+    value   : The object must be serialized with 
+            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
+            : and then encoded with base64 encoding.
+    
+    mimetype: application/x-microsoft.net.object.soap.base64
+    value   : The object must be serialized with 
+            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
+            : and then encoded with base64 encoding.
+
+    mimetype: application/x-microsoft.net.object.bytearray.base64
+    value   : The object must be serialized into a byte array 
+            : using a System.ComponentModel.TypeConverter
+            : and then encoded with base64 encoding.
+    -->
+  <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
+    <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
+    <xsd:element name="root" msdata:IsDataSet="true">
+      <xsd:complexType>
+        <xsd:choice maxOccurs="unbounded">
+          <xsd:element name="metadata">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" />
+              </xsd:sequence>
+              <xsd:attribute name="name" use="required" type="xsd:string" />
+              <xsd:attribute name="type" type="xsd:string" />
+              <xsd:attribute name="mimetype" type="xsd:string" />
+              <xsd:attribute ref="xml:space" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="assembly">
+            <xsd:complexType>
+              <xsd:attribute name="alias" type="xsd:string" />
+              <xsd:attribute name="name" type="xsd:string" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="data">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+                <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
+              <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
+              <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
+              <xsd:attribute ref="xml:space" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="resheader">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" use="required" />
+            </xsd:complexType>
+          </xsd:element>
+        </xsd:choice>
+      </xsd:complexType>
+    </xsd:element>
+  </xsd:schema>
+  <resheader name="resmimetype">
+    <value>text/microsoft-resx</value>
+  </resheader>
+  <resheader name="version">
+    <value>2.0</value>
+  </resheader>
+  <resheader name="reader">
+    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+  <resheader name="writer">
+    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+  <metadata name="imagelistTreeNodeImages.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
+    <value>17, 17</value>
+  </metadata>
+  <data name="imagelistTreeNodeImages.ImageStream" mimetype="application/x-microsoft.net.object.binary.base64">
+    <value>
+        AAEAAAD/////AQAAAAAAAAAMAgAAAFdTeXN0ZW0uV2luZG93cy5Gb3JtcywgVmVyc2lvbj00LjAuMC4w
+        LCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI3N2E1YzU2MTkzNGUwODkFAQAAACZTeXN0
+        ZW0uV2luZG93cy5Gb3Jtcy5JbWFnZUxpc3RTdHJlYW1lcgEAAAAERGF0YQcCAgAAAAkDAAAADwMAAABo
+        IQAAAk1TRnQBSQFMAgEBBgEAARABAAEQAQABEAEAARABAAT/ASEBAAj/AUIBTQE2BwABNgMAASgDAAFA
+        AwABIAMAAQEBAAEgBgABIBIAAwQBBQMWAR4DIgEyAzEBTwJGAUQBhwMvAUsDHgErAxsBJgMYASIDFQEd
+        AxIBGAMNARIDCgENAwcBCQMEAQUDAQECAwQBBQMWAR4DIgEyAzEBTgJGAUQBhwMvAUsDHgErAxsBJgMb
+        ASYDIQExAyEBMAMdASoDGwEmAxgBIQMLAQ8DAQECgAADAgEDAwwBEAMrAUMCRgFEAYIC/wHwAf8CRgFE
+        AYIDKgFAAw8BFAMNAREDCwEPAwkBDAMHAQoDBQEHAwQBBQMCAQMDAAEBAwIBAwMLAQ8DKwFDAkYBRAGC
+        Av8B8AH/AkYBRAGCAyoBQAMOARMDEgEZAT0COwFpAVwBRQFCAawBZwE+AToBxAFaAUUBQwGqATwBOwE6
+        AWYDEAEWAwABAYQAAx4BKwJEAUIBewL/AfAB/wLpAdoD/wHxAf8CRAFCAXsDHgErJAADHgErAkQBQgF7
+        Av8B8AH/AukB2gP/AfEB/wJEAUIBewMeASsBLgItAUcBdwFHATwByQG7AVQBPQHxA+4B/wG7AVMBPAHx
+        AXcBRgE8AckBLgItAUeEAAMdASoCRAFCAXcC/wHwAf8B6wHdAbEB/wH3AcEBNwH/Ae0B3wGzA/8B8gH/
+        AkQBQgF3Ax0BKhwAAx0BKgJEAUIBdwL/AfAB/wLpAdoB/wLqAdwB/wLrAd4D/wHyAf8CRAFCAXcBZAFJ
+        AUIBrwG2AVkBQQHxAc0BVAEyAf8BvQF5AWIB/wHFAVABLgH/AbEBUQE1AfEBXAFIAUQBn4QAAkMBQQF2
+        Av8B8AH/AukB2gH/AecBqwEhAf8B5wGrASEB/wHnAasBIQH/AeoB2wGwA/8B9AH/AkMBQQF2Ax0BKhgA
+        AkMBQQF2Av8B8AH/AukB2gH/AuoB3AH/AusB3gH/AuwB3wH/Au0B4QP/AfQB/wGAAUQBMQHaAc4BcAFN
+        AfwBugFMASoB/wPSAf8BvgGLAXgB/wG7AVIBMgH8AW8BSQE/AbqEAAMdASkCQwFBAXQC/wHxAf8B5wHX
+        AasB/wHXAZYBDAH/AdcBlgEMAf8B1wGWAQwB/wHoAdgBrgP/AfUB/wJDAUEBdAMdASkUAAMdASkCQwFB
+        AXQC/wHxAf8C6wHeAf8C7AHfAf8C7QHhAf8C7gHjAf8C7wHlAf8BzQF5AV4B/wHOAXcBWAH3AbwBVAEy
+        Af8BtAFMASoB/wPmAf8BtwFlAUsB8AFdAUkBRAGdiAADHQEpAkIBQQFyAv8B8gH/AeUB1AGpAf8BzQGJ
+        AQAB/wHNAYkBAAH/Ac0BiQEAAf8B6AHXAa8D/wH3Af8CQgFBAXIDHAEoFAADHQEpAkIBQQFyAv8B8gH/
+        Au0B4QH/Au4B4wH/Au8B5QH/AvAB5wH/AeABuwGqAf8BzgFpAUgB/wHjAcsBwQH5BP8B3gHHAb0B9QF+
+        AU8BQgHEAi0BLAFFjAADHAEoAkEBQAFxAv8B9AH/AecB1gGsAf8B0QGOAQQB/wHRAY4BBAH/AdEBjgEE
+        Af8B7AHbAbMD/wH4Af8CQQFAAXEDHAEoFAADHAEoAkEBQAFxAv8B9AH/Au8B5QH/AvAB5wH/AvEB6QH/
+        AvMB6gH/AeQBvgGsAf8B1AGBAWIB/wGGAUoBNAHXAWYBTQFEAaoCLQEsAUWUAAMcAScCQQFAAW8C/wH1
+        Af8B7AHcAbMB/wHfAaEBFwH/Ad8BoQEXAf8B3wGhARcB/wHxAeIBuwP/AfoB/wJBAUABbwMcAScUAAMc
+        AScCQQFAAW8C/wH1Af8C8QHpAf8C8wHqAf8C9AHsAf8C9QHuAf8C9gHwA/8B+gH/AkEBQAFvAxwBJ5gA
+        AxwBJwJAAT8BbQL/AfcB/wHyAeMBuwH/AfABuAEuAf8B8AG4AS4B/wHwAbgBLgH/AvgB9AP/AfsB/wJA
+        AT8BbQMcAScUAAMcAScCQAE/AW0C/wH3Af8C9AHsAf8C9QHuAf8C9gHwAf8C9wHyAf8C+AH0A/8B+wH/
+        AkABPwFtAxwBJ5gAAxsBJgJAAT8BbAL/AfgB/wH3AeoBwwH/Af0ByQE/Af8B+QHsAccB/wL7AfcB/wL8
+        AfkD/wH8Af8CQAE/AWwDGwEmFAADGwEmAkABPwFsAv8B+AH/AvYB8AH/AvcB8gH/AvgB9AH/AvsB9wH/
+        AvwB+QP/AfwB/wJAAT8BbAMbASaYAAMbASYCPwE+AWsC/wH6Af8C+AH0Af8C+wH3Af8C3wHVAf8CyQG5
+        Af8C4AHWA/8B/gH/Aj8BPgFrGAADGwEmAj8BPgFrAv8B+gH/AvgB9AH/AvsB9wH/At8B1QH/AskBuQH/
+        AuAB1gP/Af4B/wI/AT4Ba5wAAxoBJQI/AT0BaQL/AfsB/wL8AfkB/wK8AawB/wQAArwBrAP/Af4B/wI/
+        AT0BaRwAAxoBJQI/AT0BaQL/AfsB/wL8AfkB/wK8AawB/wQAArwBrAP/Af4B/wI/AT0BaaAAAxoBJQI+
+        AT0BaAL/AfwB/wLLAcEB/wKgAZAB/wLLAcED/wH+Af8CPgE9AWggAAMaASUCPgE9AWgC/wH8Af8CywHB
+        Af8CoAGQAf8CywHBA/8B/gH/Aj4BPQFopAADGgElAj4BPQFnAv8B/gP/Af4D/wH+Bf8CPgE9AWckAAMa
+        ASUCPgE9AWcC/wH+A/8B/gP/Af4F/wI+AT0BZ6gAAxoBJAI+AT0BZgI+AT0BZgI+AT0BZgI+AT0BZgMx
+        AU0oAAMaASQCPgE9AWYCPgE9AWYCPgE9AWYCPgE9AWYDMQFNlAADIQEwAUABRgFIAXwBQwFOAVIBkgMF
+        AQccAAMHAQkDEAEWAxMBGgMTARoDEwEaAxMBGgMTARoDEwEaAxMBGgMTARoDEwEaAxMBGgMTARoDEwEa
+        AxABFgMHAQkDBwEJAxABFgMTARoDEwEaAxMBGgMTARoDEwEaAxMBGgMTARoDEwEaAxMBGgMTARoDEwEa
+        AxMBGgMQARYDBwEJAwcBCQMQARYDEwEaAxMBGgMTARoDEwEaAxMBGgMTARoDEwEaAxMBGgMTARoDEwEa
+        AxMBGgMTARoDEAEWAwcBCQwAAjIBMwFQAUMBUQFXAZkBRQFkAXQBwAFYAYsBogHgATwBWAFqAcEDEwEa
+        AwUBBxgAAjwBOwFpAkYBRAGHAkYBRAGHAkYBRAGHAkYBRAGHAkYBRAGHAkYBRAGHAkYBRAGHAkYBRAGH
+        AkYBRAGHAkYBRAGHAkYBRAGHAkYBRAGHAkYBRAGHAkYBRAGHAjwBOwFpAjkBNAFpAkABNwGHAkABNwGH
+        AkABNwGHAkABNwGHAkABNwGHAkABNwGHAkABNwGHAkABNwGHAkABNwGHAkABNwGHAkABNwGHAkABNwGH
+        AkABNwGHAkABNwGHAjkBNAFpAjwBOwFpAkYBRAGHAkYBRAGHAkYBRAGHAkYBRAGHAkYBRAGHAkYBRAGH
+        AkYBRAGHAkYBRAGHAkYBRAGHAkYBRAGHAkYBRAGHAkYBRAGHAkYBRAGHAkYBRAGHAjwBOwFpAw0BEQMa
+        ASQBRAFNAVEBmAE8AYkBrAHyAWcBrwHTAfoBggHLAewB/wGFAc4B7gH/ARUBWwGCAe8BOgFXAWYBxAE6
+        AVcBZgHEAT4BWgFqAb4BPgFaAWoBvgE+AVoBagG+AUQBTQFRAZgDGgEkAw0BEQJGAUMBgQL5AekB/wLz
+        AeIB/wLzAeIB/wLzAeIB/wLzAeIB/wLzAeIB/wLzAeIB/wLzAeIB/wLzAeIB/wLzAeIB/wLzAeIB/wLz
+        AeIB/wLzAeIB/wL5AekB/wJGAUMBgQJDAToBgQL5AekB/wLzAeIB/wLzAeIB/wLzAeIB/wLzAeIB/wLz
+        AeIB/wLzAeIB/wLzAeIB/wLzAeIB/wLzAeIB/wLzAeIB/wLzAeIB/wLzAeIB/wL5AekB/wJDAToBgQJG
+        AUMBgQL5AekB/wLzAeIB/wLzAeIB/wLzAeIB/wLzAeIB/wLzAeIB/wLzAeIB/wLzAeIB/wLzAeIB/wLz
+        AeIB/wLzAeIB/wLzAeIB/wLzAeIB/wL5AekB/wJGAUMBgQMHAQkDDQESAUIBWwFmAbIBiAHQAe8B/wF9
+        AcoB6QH/AX0BygHpAf8BhwHQAe8B/wEkAXsBqQH/AX0BvAHbAf8BfQG8AdsB/wGNAdEB8wH/AY0B0QHz
+        Af8BkAHUAfUB/wFCAVsBZgGyATACMQFNAwcBCQJEAUMBegL0AeQC/wHMAUIB/wH+AcsBQQH/AewB0gGG
+        Af8C2gHJAf8C2AHHAf8C1gHFAf8C1AHDAf8C0wHCAf8C0QHAAf8CzwG+Af8CzgG9Af8CzQG8Af8C9AHk
+        Af8CRAFDAXoCRgE+AXoC9AHkAv8BzAFDAf8B/gHLAUIB/wHsAdIBhgH/AtoByQH/AtgBxwH/AtYBxQH/
+        AtQBwwH/AtMBwgH/AtEBwAH/As8BvgH/As4BvQH/As0BvAH/AvQB5AH/AkYBPgF6AkQBQwF6AvQB5AL/
+        AcwBQgH/Af4BywFBAf8B7AHSAYYB/wLaAckB/wLYAccB/wHnAWEBPwH/AecBYQE/Af8B5wFhAT8B/wHn
+        AWEBPwH/As8BvgH/As4BvQH/As0BvAH/AvQB5AH/AkQBQwF6CAABQwFXAWABpAGKAdMB8AH/AYIBzQHr
+        Af8BggHNAesB/wGKAdMB8AH/ASQBfAGrAf8BegG5AdgB/wF6AbkB2AH/AYoBzgHwAf8BigHOAfAB/wGP
+        AdMB9AH/AfQBtgEsAf8BQwFXAWABpAQAAkQBQgF3AvUB5gL/AcwBQgL/Ae4BiAH/AewB0gGGAf8C9QHu
+        Af8C9QHuAf8C1gHFAf8C9QHuAf8C9QHuAf8C0QHAAf8C9QHuAf8C9QHuAf8CzQG8Af8C9QHmAf8CRAFC
+        AXcCRwE/AXcC9QHmAv8BzAFDAv8B7gGIAf8B7AHSAYYB/wL1Ae4B/wL1Ae4B/wLWAcUB/wL1Ae4B/wL1
+        Ae4B/wLRAcAB/wL1Ae4B/wL1Ae4B/wLNAbwB/wL1AeYB/wJHAT8BdwJEAUIBdwL1AeYC/wHMAUIC/wHu
+        AYgB/wHsAdIBhgH/AvUB7gH/AvUB7gH/AdkBWAE2Af8B8gHJAbgB/wHyAckBuAH/AdkBWAE2Af8C9QHu
+        Af8C9QHuAf8CzQG8Af8C9QHmAf8CRAFCAXcIAAFDAVUBXgGeAY4B1gHyAf8BhwHQAe0B/wGHAdAB7QH/
+        AY4B1gHyAf8BJgGCAa8B/wF7AboB2AH/AXsBugHYAf8BiwHPAfEB/wGLAc8B8QH/AZEB1QH1Af8B/gHJ
+        AT8B/wFDAVUBXgGeBAACQwFBAXUC9gHpAv8BzAFCAf8B/gHLAUEB/wHsAdIBhgH/AtoByQH/AtgBxwH/
+        AtwBzAH/AtQBwwH/AtMBwgH/AtgByAH/As8BvgH/As4BvQH/As0BvAH/AvYB6QH/AkMBQQF1AkcBPwF1
+        AvYB6QL/AcwBQwH/Af4BywFCAf8B7AHSAYYB/wLaAckB/wLYAccB/wLcAcwB/wLUAcMB/wLTAcIB/wLY
+        AcgB/wLPAb4B/wLOAb0B/wLNAbwB/wL2AekB/wJHAT8BdQJDAUEBdQL2AekC/wHMAUIB/wH+AcsBQQH/
+        AewB0gGGAf8C2gHJAf8C2AHHAf8ByAFPAS0B/wHeAbYBngH/Ad4BtQGdAf8ByAFPAS0B/wLPAb4B/wLO
+        Ab0B/wLNAbwB/wL2AekB/wJDAUEBdQgAAUQBVQFdAZsBkgHaAfQB/wGLAdQB8AH/AYsB1AHwAf8BkgHa
+        AfQB/wEpAYUBswH/AX0BvAHaAf8BfQG8AdoB/wGNAdEB8wH/AY0B0QHzAf8BkwHXAfYB/wLrAd0B/wFE
+        AVUBXQGbBAACQgFBAXMC9wHrAv8BzAFCAv8B7gGIAf8B7AHSAYYB/wL3AfEB/wL3AfEB/wLWAcUB/wL3
+        AfEB/wL3AfEB/wLRAcAB/wL3AfEB/wL3AfEB/wLNAbwB/wL3AesB/wJCAUEBcwJHAT8BcwL3AesC/wHM
+        AUMC/wHuAYgB/wHsAdIBhgH/AvcB8QH/AvcB8QH/AtYBxQH/AvcB8QH/AvcB8QH/AtEBwAH/AvcB8QH/
+        AvcB8QH/As0BvAH/AvcB6wH/AkcBPwFzAkIBQQFzAvcB6wL/AcwBQgL/Ae4BiAH/AewB0gGGAf8C9wHx
+        Af8C9wHxAf8BuAFHASUB/wHzAcsBuQH/AfMBywG5Af8BuAFHASUB/wL3AfEB/wL3AfEB/wLNAbwB/wL3
+        AesB/wJCAUEBcwgAAUQBUwFbApcB3gH2Af8BkAHYAfIB/wGQAdgB8gH/AZcB3gH2Af8BKwGJAbcB/wGA
+        Ab0B3AH/AYABvQHcAf8BjwHTAfUB/wGPAdMB9QH/AZUB2QH4Af8C9QHuAf8BRAFTAVsBlwQAAkIBQQFy
+        AvgB7gL/AcwBQgH/Af4BywFBAf8B7AHSAYYB/wLaAckB/wLYAccB/wLdAc4B/wLUAcMB/wLTAcIB/wLZ
+        AcoB/wLPAb4B/wLOAb0B/wLNAbwB/wL4Ae4B/wJCAUEBcgJIAUABcgL4Ae4B/wHsAYYBYwH/AeIBewFZ
+        Af8B1AFuAUwB/wHEAWABPgH/AbYBUgEwAf8BrQFHASUB/wGrAUMBIQH/AbEBRAEiAf8BvQFKASgB/wHM
+        AVIBMAH/AdsBWgE4Af8B6AFiAUAB/wL4Ae4B/wJIAUABcgJCAUEBcgL4Ae4C/wHMAUIB/wH+AcsBQQH/
+        AewB0gGGAf8C2gHJAf8C2AHHAf8BrQFCASAB/wHeAbYBngH/Ad4BtQGdAf8BrQFCASAB/wLPAb4B/wLO
+        Ab0B/wLNAbwB/wL4Ae4B/wJCAUEBcggAAUQBUwFaAZQBmwHhAfcB/wGUAdsB9AH/AZQB2wH0Af8BmwHh
+        AfcB/wEuAY0BvAH/AYEBvgHdAf8BgQG+Ad0B/wGQAdQB9gH/AZAB1AH2Af8BlwHbAfkB/wL+Af0B/wFE
+        AVMBWgGUBAACQQFAAXAC+QHxAv8BzAFCAv8B7gGIAf8B7AHSAYYB/wL5AfUB/wL5AfUB/wLWAcUB/wL5
+        AfUB/wL5AfUB/wLRAcAB/wL5AfUB/wL5AfUB/wLNAbwB/wL5AfEB/wJBAUABcAJHAUABcAL5AfEB/wHs
+        AYYBYwH/AfgBxQF5Af8B7QG1AXgB/wH1AcwBvAH/AfUBzAG8Af8B4AG3AZ8B/wH1AcwBvAH/AfUBzAG8
+        Af8B3QG0AZwB/wH1AcwBvAH/AfUBzAG8Af8B6AFiAUAB/wL5AfEB/wJHAUABcAJBAUABcAL5AfEC/wHM
+        AUIC/wHuAYgB/wHsAdIBhgH/AvkB9QH/AvkB9QH/AasBRAEiAf8B9QHMAbwB/wH1AcwBvAH/AasBRAEi
+        Af8C+QH1Af8C+QH1Af8CzQG8Af8C+QHxAf8CQQFAAXAIAAFEAVEBVwGQAZ4B5QH5Af8BmAHfAfYB/wGY
+        Ad8B9gH/AZ4B5QH5Af8BMAGQAcAB/wGDAcAB3wH/AYMBwAHfAf8BkgHWAfgB/wGSAdYB+AH/AZkB3QH6
+        Af8BRAFRAVcBkAMjATMEAAJBAUABbgL7AfQC/wHMAUIB/wH+AcsBQQH/AewB0gGGAf8C2gHJAf8C2AHH
+        Af8C3gHQAf8C1AHDAf8C0wHCAf8C2gHMAf8CzwG+Af8CzgG9Af8CzQG8Af8C+wH0Af8CQQFAAW4CRwFA
+        AW4C+wH0Af8B7AGGAWMB/wHiAXsBWQH/AdQBbgFMAf8BxAFgAT4B/wG2AVIBMAH/Aa0BRwElAf8BqwFD
+        ASEB/wGxAUQBIgH/Ab0BSgEoAf8BzAFSATAB/wHbAVoBOAH/AegBYgFAAf8C+wH0Af8CRwFAAW4CQQFA
+        AW4C+wH0Av8BzAFCAf8B/gHLAUEB/wHsAdIBhgH/AtoByQH/AtgBxwH/AbIBTAEqAf8B3gG2AZ4B/wHe
+        AbUBnQH/AbIBTAEqAf8CzwG+Af8CzgG9Af8CzQG8Af8C+wH0Af8CQQFAAW4IAAFDAU8BVQGNAaMB6AH7
+        Af8BnQHjAfkB/wGdAeMB+QH/AaMB6AH7Af8BMwGUAcUB/wGFAcIB4QH/AYUBwgHhAf8BlAHYAfoB/wGU
+        AdgB+gH/AZsB3wH8Af8BQwFPAVUBjQgAAkABPwFtAvwB9wL/AcwBQgL/Ae4BiAH/AewB0gGGAf8C/AH6
+        Af8C/AH6Af8C1gHFAf8C/AH6Af8C/AH6Af8C0QHAAf8C/AH6Af8C/AH6Af8CzQG8Af8C/AH3Af8CQAE/
+        AW0CRwFAAW0C/AH3Av8BzAFDAv8B7gGIAf8B7AHSAYYB/wL8AfoB/wL8AfoB/wLWAcUB/wL8AfoB/wL8
+        AfoB/wLRAcAB/wL8AfoB/wL8AfoB/wLNAbwB/wL8AfcB/wJHAUABbQJAAT8BbQL8AfcC/wHMAUIC/wHu
+        AYgB/wHsAdIBhgH/AvwB+gH/AvwB+gH/AcABWgE4Af8B9gHOAb8B/wH2Ac4BvwH/AcABWgE4Af8C/AH6
+        Af8C/AH6Af8CzQG8Af8C/AH3Af8CQAE/AW0IAAFDAU8BVAGKAaYB6wH8Af8BoQHmAfsB/wGhAeYB+wH/
+        AaYB6wH8Af8BOgGdAc8B/wGHAcQB4gH/AYcBxAHiAf8BlgHaAfwB/wGWAdoB/AH/AZ4B4gH9Af8BQwFP
+        AVQBiggAAj8BPgFrAv0B+QL/AcwBQgH/Af4BywFBAf8B9QHOAWIB/wHrAdIBhQH/AekB0AGDAf8B5wHO
+        AYEB/wHlAcwBgAH/AeQBywF8Af8B4gHJAXoB/wHgAccBeAH/Ad8BxgF3Af8B3gHFAXYB/wL9AfkB/wI/
+        AT4BawJHAUABawL9AfkC/wHMAUMB/wH+AcsBQgH/AfUBzgFjAf8B6wHSAYUB/wHpAdABgwH/AecBzgGB
+        Af8B5QHMAYAB/wHkAcsBfQH/AeIByQF7Af8B4AHHAXkB/wHfAcYBeAH/Ad4BxQF3Af8C/QH5Af8CRwFA
+        AWsCPwE+AWsC/QH5Av8BzAFCAf8B/gHLAUEB/wH1Ac4BYgH/AesB0gGFAf8B6QHQAYMB/wHRAWoBSAH/
+        AekBsQF0Af8B6AGwAXMB/wHRAWoBSAH/AeABxwF4Af8B3wHGAXcB/wHeAcUBdgH/Av0B+QH/Aj8BPgFr
+        CAABQgFNAVIBhwGpAe4B/QH/AaQB6QH8Af8BpAHpAfwB/wGqAe8B/QH/AUABoQHRAf8BkAHRAfEB/wGW
+        AdoB+wH/AZcB2wH9Af8BlwHbAf0B/wGfAeMB/gH/AUIBTQFSAYcIAAI/AT4BagL+AfwC/wHMAUIC/wHu
+        AYgB/wH9AcoBQAH/AfwB6wGFAf8B+wHqAYQB/wH4AcUBOwH/AfYB5QF9Af8B9AHjAXsB/wHzAcABNgH/
+        AfEB4AF4Af8B7wHeAXYB/wHvAbwBMgH/Av4B/AH/Aj8BPgFqAkcBQAFqAv4B/AL/AcwBQwL/Ae4BiAH/
+        Af0BygFBAf8B/AHrAYUB/wH7AeoBhAH/AfgBxQE8Af8B9gHlAX4B/wH0AeMBfAH/AfMBwAE3Af8B8QHg
+        AXkB/wHvAd4BdwH/Ae8BvAEzAf8C/gH8Af8CRwFAAWoCPwE+AWoC/gH8Av8BzAFCAv8B7gGIAf8B/QHK
+        AUAB/wH8AesBhQH/AfsB6gGEAf8B4QF5AVcB/wHzAcABcwH/AfIBvwFyAf8B4QF5AVcB/wHxAeABeAH/
+        Ae8B3gF2Af8B7wG8ATIB/wL+AfwB/wI/AT4BaggAAUMBTAFSAYUBrQHxAv8BqwHvAf4B/wGVAeIB+AH/
+        AWwByQHtAf8BRgGpAdkB/wGYAdwB/gH/AZgB3AH+Af8BmAHcAf4B/wGYAdwB/gH/AaEB5QL/AUMBTAFS
+        AYUIAAI+AT0BaAL/Af4C/wHMAUIB/wH+AcsBQQH/Af0BygFAAf8B/AHJAT8B/wH6AccBPQH/AfgBxQE7
+        Af8B9gHDAToB/wH1AcIBOAH/AfMBwAE2Af8B8QG+ATQB/wHwAb0BMwH/Ae8BvAEyA/8B/gH/Aj4BPQFo
+        AkcBQAFoAv8B/gL/AcwBQwH/Af4BywFCAf8B/QHKAUEB/wH8AckBQAH/AfoBxwE+Af8B+AHFATwB/wH2
+        AcMBOwH/AfUBwgE5Af8B8wHAATcB/wHxAb4BNQH/AfABvQE0Af8B7wG8ATMD/wH+Af8CRwFAAWgCPgE9
+        AWgC/wH+Av8BzAFCAf8B/gHLAUEB/wH9AcoBQAH/AfwByQE/Af8B+gHHAT0B/wHsAYYBYgH/AewBhgFi
+        Af8B7AGGAWIB/wHsAYYBYgH/AfEBvgE0Af8B8AG9ATMB/wHvAbwBMgP/Af4B/wI+AT0BaAgAAUMBTAFQ
+        AYMBiAHcAfQB/wFeAcAB6QH/AV0BvwHqAf8BgAHTAfQB/wGcAeMB/QH/AaIB5gL/AaIB5gL/AaIB5gL/
+        AaIB5gL/AaYB6gL/AUMBTAFQAYMIAAI+AT0BZzj/Aj4BPQFnAkcBQAFnOP8CRwFAAWcCPgE9AWc4/wI+
+        AT0BZwgAATkBOwE9AWEBQgFLAU8BgQFCAUsBTwGBAUIBSwFPAYEBQgFLAU8BgQFCAUsBTwGBAUIBSwFP
+        AYEBQgFLAU8BgQFCAUsBTwGBAUIBSwFPAYEBQgFLAU8BgQE5ATsBPQFhCAADMQFNAj4BPQFmAj4BPQFm
+        Aj4BPQFmAj4BPQFmAj4BPQFmAj4BPQFmAj4BPQFmAj4BPQFmAj4BPQFmAj4BPQFmAj4BPQFmAj4BPQFm
+        Aj4BPQFmAj4BPQFmAzEBTQI3ATQBTQJHAUABZgJHAUABZgJHAUABZgJHAUABZgJHAUABZgJHAUABZgJH
+        AUABZgJHAUABZgJHAUABZgJHAUABZgJHAUABZgJHAUABZgJHAUABZgJHAUABZgI3ATQBTQMxAU0CPgE9
+        AWYCPgE9AWYCPgE9AWYCPgE9AWYCPgE9AWYCPgE9AWYCPgE9AWYCPgE9AWYCPgE9AWYCPgE9AWYCPgE9
+        AWYCPgE9AWYCPgE9AWYCPgE9AWYDMQFNAUIBTQE+BwABPgMAASgDAAFAAwABIAMAAQEBAAEBBgABARYA
+        A/8RAAGAAf8BgAEBBQABfwEAAQEFAAE/AQABAQUAAR8BAAEBBAABgAEPAYABAQQAAcABBwHAAQMEAAHg
+        AQMB4AEDBAAB8AEBAfABAQQAAfgBAAH4BQAB/AEAAfwFAAH+AQgB/gEIBAAB/wEAAf8FAAH/AYAB/wGA
+        BAAB/wHAAf8BwAQAAfgBfwYAAeABPxYAAcABAQYAAcABAQYAAcABAQYAAcABAQYAAcABAQYAAcABAQYA
+        AcABAwYAAcABAwYAAcABAwYAAcABAwYAAcABAwYAAcABAwYACw==
+</value>
+  </data>
+  <metadata name="toolStripMain.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
+    <value>211, 17</value>
+  </metadata>
+  <assembly alias="System.Drawing" name="System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
+  <data name="toolbuttonOpenMib.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+    <value>
+        iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
+        YQUAAAAJcEhZcwAADsIAAA7CARUoSoAAAAK6SURBVDhPjZNbSNNRHMfPU9DtwR71oZf5IgkF0YMEEYb2
+        EGgG5YNgGQmGSUoYimbel5KKmlM0u3jJSpv3ad7WnGkzb2yO4bByF3WuuTnnnLv47Zw/9YclQQc+/L//
+        P+d8/r/f+Z8/Ib/HjJDcmhaS3P+Bzf2zjr8qiki+QyuE6dNNbIzFw6F8DJ++AVh97c9GK9jcA4LJAlKI
+        rQ7sW9/DpauGZSoFg6JwfJSU+TE0XIXOgqCaAwJ5ASn2bb6F19TM4bO+w4z4HgwWC9YcDugpK3Y7umQy
+        FOZEDMRkZQX7SWS5pMRrboVn9RUHy1/aEqDSajGn0WDZbIZ6bQ0t/f1gIzojI8lPMvaIPPWsN2FP/5yD
+        ZdmLWLwUi/FhZASSqSlOUtXczBMcGZnFVzGUTSr2jI1wfq/lYHms4Tqkc3MYnZ2F0mDAqs3GV8LaiUhN
+        TeYFA5mkenelHg5tNQfLw3UxaOrpQZdUiu7xca5/Mc0do6PQb28jPDk5hRf0PiQi5zcR7JoKDpYHaqIg
+        VyohW1jg+lcZjVwlCzod1p1OXEhMvM8LOtNJvWOpEjZVKQfL/ZVX0NrXh165HP2Tk5hQqzGuUmFQocCm
+        y4XzCQlpvKA9jTTa1WWwzBdzsNxdfhmfFxcxQRct0Q3UmEzY2t2FdWcHdrcb5+LiHvCC1hTSbFOWwDyT
+        x8GyuDQCbRIJ3tBPp6CfU0pbcdA3M4mDCs7ExqYzwWHKibo7pNs6T4+yIofDSqtof3IJBtqzTq+Hx+uF
+        y+OBky5kkh2aT0VFZTNBAEWQFEFqhyvO2pclSe6f03nYnC1EW9FFGOnGGSi+/X14KW6fD3tUtkdzYFiY
+        0O801iWSaNFtUteWGST92nL1R/q1Q7ojAkHV0ZCQkuOhocV/c0wguHvgn2APyuPJ6dI4kpV/gzyjtycp
+        gf8g4Begs1B6Kbj3cQAAAABJRU5ErkJggg==
+</value>
+  </data>
+  <metadata name="dialogOpenMib.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
+    <value>337, 17</value>
+  </metadata>
+</root>
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/MibViewer/MibViewer.csproj
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/MibViewer/MibViewer.csproj	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/MibViewer/MibViewer.csproj	(revision 457)
@@ -0,0 +1,94 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+    <ProductVersion>8.0.30703</ProductVersion>
+    <SchemaVersion>2.0</SchemaVersion>
+    <ProjectGuid>{86CC0B65-7985-4017-A252-0A7A18DCAEF3}</ProjectGuid>
+    <OutputType>WinExe</OutputType>
+    <AppDesignerFolder>Properties</AppDesignerFolder>
+    <RootNamespace>LwipMibViewer</RootNamespace>
+    <AssemblyName>MibViewer</AssemblyName>
+    <TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
+    <FileAlignment>512</FileAlignment>
+    <TargetFrameworkProfile />
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|AnyCPU'">
+    <DebugSymbols>true</DebugSymbols>
+    <OutputPath>bin\Debug\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <DebugType>full</DebugType>
+    <ErrorReport>prompt</ErrorReport>
+    <CodeAnalysisIgnoreBuiltInRuleSets>true</CodeAnalysisIgnoreBuiltInRuleSets>
+    <CodeAnalysisIgnoreBuiltInRules>true</CodeAnalysisIgnoreBuiltInRules>
+    <WarningLevel>4</WarningLevel>
+    <Optimize>false</Optimize>
+    <UseVSHostingProcess>false</UseVSHostingProcess>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|AnyCPU'">
+    <OutputPath>bin\Release\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <Optimize>true</Optimize>
+    <DebugType>pdbonly</DebugType>
+    <PlatformTarget>AnyCPU</PlatformTarget>
+    <ErrorReport>prompt</ErrorReport>
+    <CodeAnalysisIgnoreBuiltInRuleSets>true</CodeAnalysisIgnoreBuiltInRuleSets>
+    <CodeAnalysisIgnoreBuiltInRules>true</CodeAnalysisIgnoreBuiltInRules>
+    <WarningLevel>4</WarningLevel>
+    <UseVSHostingProcess>false</UseVSHostingProcess>
+  </PropertyGroup>
+  <ItemGroup>
+    <Reference Include="System" />
+    <Reference Include="System.Drawing" />
+    <Reference Include="System.Windows.Forms" />
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="FormMain.cs">
+      <SubType>Form</SubType>
+    </Compile>
+    <Compile Include="FormMain.Designer.cs">
+      <DependentUpon>FormMain.cs</DependentUpon>
+    </Compile>
+    <Compile Include="Program.cs" />
+    <Compile Include="Properties\AssemblyInfo.cs" />
+    <EmbeddedResource Include="FormMain.resx">
+      <DependentUpon>FormMain.cs</DependentUpon>
+    </EmbeddedResource>
+    <EmbeddedResource Include="Properties\Resources.resx">
+      <Generator>ResXFileCodeGenerator</Generator>
+      <LastGenOutput>Resources.Designer.cs</LastGenOutput>
+      <SubType>Designer</SubType>
+    </EmbeddedResource>
+    <Compile Include="Properties\Resources.Designer.cs">
+      <AutoGen>True</AutoGen>
+      <DependentUpon>Resources.resx</DependentUpon>
+      <DesignTime>True</DesignTime>
+    </Compile>
+    <None Include="app.config" />
+    <None Include="Properties\Settings.settings">
+      <Generator>SettingsSingleFileGenerator</Generator>
+      <LastGenOutput>Settings.Designer.cs</LastGenOutput>
+    </None>
+    <Compile Include="Properties\Settings.Designer.cs">
+      <AutoGen>True</AutoGen>
+      <DependentUpon>Settings.settings</DependentUpon>
+      <DesignTimeSharedInput>True</DesignTimeSharedInput>
+    </Compile>
+  </ItemGroup>
+  <ItemGroup>
+    <ProjectReference Include="..\SharpSnmpLib\SharpSnmpLib.Mib.csproj">
+      <Project>{CBE20411-5DB7-487D-825D-7694267BB6F5}</Project>
+      <Name>SharpSnmpLib.Mib</Name>
+    </ProjectReference>
+  </ItemGroup>
+  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+  <PropertyGroup />
+  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
+       Other similar extension points exist, see Microsoft.Common.targets.
+  <Target Name="BeforeBuild">
+  </Target>
+  <Target Name="AfterBuild">
+  </Target>
+  -->
+</Project>
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/MibViewer/Program.cs
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/MibViewer/Program.cs	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/MibViewer/Program.cs	(revision 457)
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Martin Hentschel <info@cl-soft.de>
+ *
+ */
+
+using System;
+using System.Windows.Forms;
+
+namespace LwipMibViewer
+{
+	static class Program
+	{
+		/// <summary>
+		/// Der Haupteinstiegspunkt fur die Anwendung.
+		/// </summary>
+		[STAThread]
+		static void Main()
+		{
+			Application.EnableVisualStyles();
+			Application.SetCompatibleTextRenderingDefault(false);
+			Application.Run(new FormMain());
+		}
+	}
+}
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/MibViewer/Properties/AssemblyInfo.cs
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/MibViewer/Properties/AssemblyInfo.cs	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/MibViewer/Properties/AssemblyInfo.cs	(revision 457)
@@ -0,0 +1,36 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// Allgemeine Informationen uber eine Assembly werden uber die folgenden 
+// Attribute gesteuert. Andern Sie diese Attributwerte, um die Informationen zu andern,
+// die mit einer Assembly verknupft sind.
+[assembly: AssemblyTitle("LwipMibViewer")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("LwipMibViewer")]
+[assembly: AssemblyCopyright("Copyright c  2015")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Durch Festlegen von ComVisible auf "false" werden die Typen in dieser Assembly unsichtbar 
+// fur COM-Komponenten. Wenn Sie auf einen Typ in dieser Assembly von 
+// COM zugreifen mussen, legen Sie das ComVisible-Attribut fur diesen Typ auf "true" fest.
+[assembly: ComVisible(false)]
+
+// Die folgende GUID bestimmt die ID der Typbibliothek, wenn dieses Projekt fur COM verfugbar gemacht wird
+[assembly: Guid("7ffbd1c1-1c64-45bb-b243-2400446c649d")]
+
+// Versionsinformationen fur eine Assembly bestehen aus den folgenden vier Werten:
+//
+//      Hauptversion
+//      Nebenversion 
+//      Buildnummer
+//      Revision
+//
+// Sie konnen alle Werte angeben oder die standardmasigen Build- und Revisionsnummern 
+// ubernehmen, indem Sie "*" eingeben:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/MibViewer/Properties/Resources.Designer.cs
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/MibViewer/Properties/Resources.Designer.cs	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/MibViewer/Properties/Resources.Designer.cs	(revision 457)
@@ -0,0 +1,63 @@
+//------------------------------------------------------------------------------
+// <auto-generated>
+//     Dieser Code wurde von einem Tool generiert.
+//     Laufzeitversion:4.0.30319.225
+//
+//     Anderungen an dieser Datei konnen falsches Verhalten verursachen und gehen verloren, wenn
+//     der Code erneut generiert wird.
+// </auto-generated>
+//------------------------------------------------------------------------------
+
+namespace LwipMibViewer.Properties {
+    using System;
+    
+    
+    /// <summary>
+    ///   Eine stark typisierte Ressourcenklasse zum Suchen von lokalisierten Zeichenfolgen usw.
+    /// </summary>
+    // Diese Klasse wurde von der StronglyTypedResourceBuilder automatisch generiert
+    // -Klasse uber ein Tool wie ResGen oder Visual Studio automatisch generiert.
+    // Um einen Member hinzuzufugen oder zu entfernen, bearbeiten Sie die .ResX-Datei und fuhren dann ResGen
+    // mit der /str-Option erneut aus, oder Sie erstellen Ihr VS-Projekt neu.
+    [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+    [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
+    internal class Resources {
+        
+        private static global::System.Resources.ResourceManager resourceMan;
+        
+        private static global::System.Globalization.CultureInfo resourceCulture;
+        
+        [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
+        internal Resources() {
+        }
+        
+        /// <summary>
+        ///   Gibt die zwischengespeicherte ResourceManager-Instanz zuruck, die von dieser Klasse verwendet wird.
+        /// </summary>
+        [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
+        internal static global::System.Resources.ResourceManager ResourceManager {
+            get {
+                if (object.ReferenceEquals(resourceMan, null)) {
+                    global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("LwipMibViewer.Properties.Resources", typeof(Resources).Assembly);
+                    resourceMan = temp;
+                }
+                return resourceMan;
+            }
+        }
+        
+        /// <summary>
+        ///   Uberschreibt die CurrentUICulture-Eigenschaft des aktuellen Threads fur alle
+        ///   Ressourcenzuordnungen, die diese stark typisierte Ressourcenklasse verwenden.
+        /// </summary>
+        [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
+        internal static global::System.Globalization.CultureInfo Culture {
+            get {
+                return resourceCulture;
+            }
+            set {
+                resourceCulture = value;
+            }
+        }
+    }
+}
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/MibViewer/Properties/Resources.resx
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/MibViewer/Properties/Resources.resx	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/MibViewer/Properties/Resources.resx	(revision 457)
@@ -0,0 +1,117 @@
+<?xml version="1.0" encoding="utf-8"?>
+<root>
+  <!-- 
+    Microsoft ResX Schema 
+    
+    Version 2.0
+    
+    The primary goals of this format is to allow a simple XML format 
+    that is mostly human readable. The generation and parsing of the 
+    various data types are done through the TypeConverter classes 
+    associated with the data types.
+    
+    Example:
+    
+    ... ado.net/XML headers & schema ...
+    <resheader name="resmimetype">text/microsoft-resx</resheader>
+    <resheader name="version">2.0</resheader>
+    <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
+    <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
+    <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
+    <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
+    <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
+        <value>[base64 mime encoded serialized .NET Framework object]</value>
+    </data>
+    <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
+        <comment>This is a comment</comment>
+    </data>
+                
+    There are any number of "resheader" rows that contain simple 
+    name/value pairs.
+    
+    Each data row contains a name, and value. The row also contains a 
+    type or mimetype. Type corresponds to a .NET class that support 
+    text/value conversion through the TypeConverter architecture. 
+    Classes that don't support this are serialized and stored with the 
+    mimetype set.
+    
+    The mimetype is used for serialized objects, and tells the 
+    ResXResourceReader how to depersist the object. This is currently not 
+    extensible. For a given mimetype the value must be set accordingly:
+    
+    Note - application/x-microsoft.net.object.binary.base64 is the format 
+    that the ResXResourceWriter will generate, however the reader can 
+    read any of the formats listed below.
+    
+    mimetype: application/x-microsoft.net.object.binary.base64
+    value   : The object must be serialized with 
+            : System.Serialization.Formatters.Binary.BinaryFormatter
+            : and then encoded with base64 encoding.
+    
+    mimetype: application/x-microsoft.net.object.soap.base64
+    value   : The object must be serialized with 
+            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
+            : and then encoded with base64 encoding.
+
+    mimetype: application/x-microsoft.net.object.bytearray.base64
+    value   : The object must be serialized into a byte array 
+            : using a System.ComponentModel.TypeConverter
+            : and then encoded with base64 encoding.
+    -->
+  <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
+    <xsd:element name="root" msdata:IsDataSet="true">
+      <xsd:complexType>
+        <xsd:choice maxOccurs="unbounded">
+          <xsd:element name="metadata">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" />
+              <xsd:attribute name="type" type="xsd:string" />
+              <xsd:attribute name="mimetype" type="xsd:string" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="assembly">
+            <xsd:complexType>
+              <xsd:attribute name="alias" type="xsd:string" />
+              <xsd:attribute name="name" type="xsd:string" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="data">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+                <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" msdata:Ordinal="1" />
+              <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
+              <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="resheader">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" use="required" />
+            </xsd:complexType>
+          </xsd:element>
+        </xsd:choice>
+      </xsd:complexType>
+    </xsd:element>
+  </xsd:schema>
+  <resheader name="resmimetype">
+    <value>text/microsoft-resx</value>
+  </resheader>
+  <resheader name="version">
+    <value>2.0</value>
+  </resheader>
+  <resheader name="reader">
+    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+  <resheader name="writer">
+    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+</root>
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/MibViewer/Properties/Settings.Designer.cs
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/MibViewer/Properties/Settings.Designer.cs	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/MibViewer/Properties/Settings.Designer.cs	(revision 457)
@@ -0,0 +1,26 @@
+//------------------------------------------------------------------------------
+// <auto-generated>
+//     Dieser Code wurde von einem Tool generiert.
+//     Laufzeitversion:4.0.30319.225
+//
+//     Anderungen an dieser Datei konnen falsches Verhalten verursachen und gehen verloren, wenn
+//     der Code erneut generiert wird.
+// </auto-generated>
+//------------------------------------------------------------------------------
+
+namespace LwipMibViewer.Properties {
+    
+    
+    [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
+    [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "10.0.0.0")]
+    internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
+        
+        private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
+        
+        public static Settings Default {
+            get {
+                return defaultInstance;
+            }
+        }
+    }
+}
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/MibViewer/Properties/Settings.settings
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/MibViewer/Properties/Settings.settings	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/MibViewer/Properties/Settings.settings	(revision 457)
@@ -0,0 +1,7 @@
+<?xml version='1.0' encoding='utf-8'?>
+<SettingsFile xmlns="http://schemas.microsoft.com/VisualStudio/2004/01/settings" CurrentProfile="(Default)">
+  <Profiles>
+    <Profile Name="(Default)" />
+  </Profiles>
+  <Settings />
+</SettingsFile>
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/MibViewer/app.config
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/MibViewer/app.config	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/MibViewer/app.config	(revision 457)
@@ -0,0 +1,3 @@
+<?xml version="1.0"?>
+<configuration>
+<startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/></startup></configuration>
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/Mibs/IANA-ADDRESS-FAMILY-NUMBERS-MIB
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/Mibs/IANA-ADDRESS-FAMILY-NUMBERS-MIB	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/Mibs/IANA-ADDRESS-FAMILY-NUMBERS-MIB	(revision 457)
@@ -0,0 +1,131 @@
+
+
+  IANA-ADDRESS-FAMILY-NUMBERS-MIB DEFINITIONS ::= BEGIN
+
+  IMPORTS
+      MODULE-IDENTITY,
+      mib-2                               FROM SNMPv2-SMI
+      TEXTUAL-CONVENTION                  FROM SNMPv2-TC;
+
+  ianaAddressFamilyNumbers MODULE-IDENTITY
+      LAST-UPDATED "200203140000Z"  -- March 14, 2002
+      ORGANIZATION "IANA"
+      CONTACT-INFO
+          "Postal:    Internet Assigned Numbers Authority
+                      Internet Corporation for Assigned Names
+		      and Numbers
+                      4676 Admiralty Way, Suite 330
+                      Marina del Rey, CA 90292-6601
+                      USA
+
+          Tel:    +1  310-823-9358
+          E-Mail: iana&iana.org"
+      DESCRIPTION
+          "The MIB module defines the AddressFamilyNumbers
+          textual convention."
+
+      -- revision history
+
+      REVISION     "200203140000Z"  -- March 14, 2002
+      DESCRIPTION  "AddressFamilyNumbers assignment 22 to 
+                   fibreChannelWWPN. AddressFamilyNumbers 
+                   assignment 23 to fibreChannelWWNN.
+                   AddressFamilyNumers assignment 24 to gwid."
+
+      REVISION     "200009080000Z"  -- September 8, 2000
+      DESCRIPTION  "AddressFamilyNumbers assignment 19 to xtpOverIpv4.  
+                   AddressFamilyNumbers assignment 20 to xtpOverIpv6.  
+                   AddressFamilyNumbers assignment 21 to xtpNativeModeXTP."
+
+      REVISION     "200003010000Z"  -- March 1, 2000
+      DESCRIPTION  "AddressFamilyNumbers assignment 17 to distinguishedName. 
+                   AddressFamilyNumbers assignment 18 to asNumber."
+
+      REVISION     "200002040000Z"  -- February 4, 2000
+      DESCRIPTION  "AddressFamilyNumbers assignment 16 to dns."
+
+      REVISION     "9908260000Z"  -- August 26, 1999
+      DESCRIPTION  "Initial version, published as RFC 2677."
+
+      ::= { mib-2 72 }
+
+
+  AddressFamilyNumbers ::= TEXTUAL-CONVENTION
+
+      STATUS       current
+      DESCRIPTION
+          "The definition of this textual convention with the
+          addition of newly assigned values is published
+          periodically by the IANA, in either the Assigned
+          Numbers RFC, or some derivative of it specific to
+          Internet Network Management number assignments.
+          (The latest arrangements can be obtained by
+          contacting the IANA.)
+
+          The enumerations are described as:
+
+          other(0),    -- none of the following
+          ipV4(1),     -- IP Version 4
+          ipV6(2),     -- IP Version 6
+          nsap(3),     -- NSAP
+          hdlc(4),     -- (8-bit multidrop)
+          bbn1822(5),
+          all802(6),   -- (includes all 802 media
+                       --   plus Ethernet 'canonical format')
+          e163(7),
+          e164(8),     -- (SMDS, Frame Relay, ATM)
+          f69(9),      -- (Telex)
+          x121(10),    -- (X.25, Frame Relay)
+          ipx(11),     -- IPX (Internet Protocol Exchange)
+          appleTalk(12),  -- Apple Talk
+          decnetIV(13),   -- DEC Net Phase IV
+          banyanVines(14),  -- Banyan Vines
+          e164withNsap(15),
+                       -- (E.164 with NSAP format subaddress)
+          dns(16),     -- (Domain Name System)
+          distinguishedName(17), -- (Distinguished Name, per X.500)
+          asNumber(18), -- (16-bit quantity, per the AS number space)
+          xtpOverIpv4(19),  -- XTP over IP version 4
+          xtpOverIpv6(20),  -- XTP over IP version 6
+          xtpNativeModeXTP(21),  -- XTP native mode XTP
+          fibreChannelWWPN(22),  -- Fibre Channel World-Wide Port Name 
+          fibreChannelWWNN(23),  -- Fibre Channel World-Wide Node Name
+          gwid(24),    -- Gateway Identifier 
+          afi(25),  -- AFI for L2VPN information
+          reserved(65535)
+
+
+
+          Requests for new values should be made to IANA via
+          email (iana&iana.org)."
+
+      SYNTAX  INTEGER {
+                  other(0),
+                  ipV4(1),
+                  ipV6(2),
+                  nsap(3),
+                  hdlc(4),
+                  bbn1822(5),
+                  all802(6),
+                  e163(7),
+                  e164(8),
+                  f69(9),
+                  x121(10),
+                  ipx(11),
+                  appleTalk(12),
+                  decnetIV(13),
+                  banyanVines(14),
+                  e164withNsap(15),
+                  dns(16),
+                  distinguishedName(17), -- (Distinguished Name, per X.500)
+                  asNumber(18), -- (16-bit quantity, per the AS number space)
+                  xtpOverIpv4(19),
+                  xtpOverIpv6(20),
+                  xtpNativeModeXTP(21),
+                  fibreChannelWWPN(22),
+                  fibreChannelWWNN(23),
+                  gwid(24),
+                  afi(25),
+                  reserved(65535)
+              }
+      END
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/Mibs/IANA-CHARSET-MIB
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/Mibs/IANA-CHARSET-MIB	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/Mibs/IANA-CHARSET-MIB	(revision 457)
@@ -0,0 +1,345 @@
+IANA-CHARSET-MIB DEFINITIONS ::= BEGIN
+--  http://www.iana.org/assignments/ianacharset-mib
+
+IMPORTS
+    MODULE-IDENTITY,
+        mib-2
+            FROM SNMPv2-SMI                              -- [RFC2578]
+    TEXTUAL-CONVENTION
+            FROM SNMPv2-TC;                              -- [RFC2579]
+
+ianaCharsetMIB MODULE-IDENTITY
+    LAST-UPDATED    "200705140000Z"
+    ORGANIZATION    "IANA"
+    CONTACT-INFO    "       Internet Assigned Numbers Authority
+
+                    Postal: ICANN
+                            4676 Admiralty Way, Suite 330
+                            Marina del Rey, CA 90292
+
+                    Tel:    +1 310 823 9358
+                    E-Mail: iana&iana.org"
+
+    DESCRIPTION     "This MIB module defines the IANACharset
+                    TEXTUAL-CONVENTION.  The IANACharset TC is used to
+                    specify the encoding of string objects defined in
+                    a MIB.
+
+                    Each version of this MIB will be released based on
+                    the IANA Charset Registry file (see RFC 2978) at
+                    http://www.iana.org/assignments/character-sets.
+
+                    Note:  The IANACharset TC, originally defined in
+                    RFC 1759, was inaccurately named CodedCharSet.
+
+                    Note:  Best practice is to define new MIB string
+                    objects with invariant UTF-8 (RFC 3629) syntax
+                    using the SnmpAdminString TC (defined in RFC 3411)
+                    in accordance with IETF Policy on Character Sets and
+                    Languages (RFC 2277).
+
+                    Copyright (C) The Internet Society (2004).  The
+                    initial version of this MIB module was published
+                    in RFC 3808; for full legal notices see the RFC
+                    itself.  Supplementary information may be
+                    available on
+                    http://www.ietf.org/copyrights/ianamib.html."
+
+    --  revision history
+    
+    REVISION        "200705140000Z"
+    DESCRIPTION     "Registration of new charset 2107."
+
+    REVISION        "200612070000Z"
+    DESCRIPTION     "Registration of new charsets numbered 118, 119, 
+                    and 2106."
+
+    REVISION        "200406080000Z"
+    DESCRIPTION     "Original version transferred from Printer MIB,
+                    generated from the IANA maintained assignments
+                    http://www.iana.org/assignments/character-sets."
+
+    ::= { mib-2 106 }
+
+IANACharset ::= TEXTUAL-CONVENTION
+    STATUS  current
+    DESCRIPTION
+        "Specifies an IANA registered 'charset' - coded character set
+        (CCS) plus optional character encoding scheme (CES) - terms
+        defined in 'IANA Charset Registration Procedures' (RFC 2978).
+
+        Objects of this syntax are used to specify the encoding for
+        string objects defined in one or more MIBs.  For example, the
+        prtLocalizationCharacterSet, prtInterpreterDefaultCharSetIn, and
+        prtInterpreterDefaultCharSetOut objects defined in Printer MIB.
+
+        The current list of 'charset' names and enumerated values
+        is contained in the IANA Character Set Registry at:
+
+           http://www.iana.org/assignments/character-sets
+
+        Enum names are derived from the IANA Charset Registry 'Alias'
+        fields that begin with 'cs' (for character set).
+        Enum values are derived from the parallel 'MIBenum' fields."
+    SYNTAX  INTEGER {
+        other(1),   -- used if the designated
+                    -- character set is not currently
+                    -- registered by IANA
+        unknown(2), -- used as a default value
+        csASCII(3),
+        csISOLatin1(4),
+        csISOLatin2(5),
+        csISOLatin3(6),
+        csISOLatin4(7),
+        csISOLatinCyrillic(8),
+        csISOLatinArabic(9),
+        csISOLatinGreek(10),
+        csISOLatinHebrew(11),
+        csISOLatin5(12),
+        csISOLatin6(13),
+        csISOTextComm(14),
+        csHalfWidthKatakana(15),
+        csJISEncoding(16),
+        csShiftJIS(17),
+        csEUCPkdFmtJapanese(18),
+        csEUCFixWidJapanese(19),
+        csISO4UnitedKingdom(20),
+        csISO11SwedishForNames(21),
+        csISO15Italian(22),
+        csISO17Spanish(23),
+        csISO21German(24),
+        csISO60DanishNorwegian(25),
+        csISO69French(26),
+        csISO10646UTF1(27),
+        csISO646basic1983(28),
+        csINVARIANT(29),
+        csISO2IntlRefVersion(30),
+        csNATSSEFI(31),
+        csNATSSEFIADD(32),
+        csNATSDANO(33),
+        csNATSDANOADD(34),
+        csISO10Swedish(35),
+        csKSC56011987(36),
+        csISO2022KR(37),
+        csEUCKR(38),
+        csISO2022JP(39),
+        csISO2022JP2(40),
+        csISO13JISC6220jp(41),
+        csISO14JISC6220ro(42),
+        csISO16Portuguese(43),
+        csISO18Greek7Old(44),
+        csISO19LatinGreek(45),
+        csISO25French(46),
+        csISO27LatinGreek1(47),
+        csISO5427Cyrillic(48),
+        csISO42JISC62261978(49),
+        csISO47BSViewdata(50),
+        csISO49INIS(51),
+        csISO50INIS8(52),
+        csISO51INISCyrillic(53),
+        csISO54271981(54),
+        csISO5428Greek(55),
+        csISO57GB1988(56),
+        csISO58GB231280(57),
+        csISO61Norwegian2(58),
+        csISO70VideotexSupp1(59),
+        csISO84Portuguese2(60),
+        csISO85Spanish2(61),
+        csISO86Hungarian(62),
+        csISO87JISX0208(63),
+        csISO88Greek7(64),
+        csISO89ASMO449(65),
+        csISO90(66),
+        csISO91JISC62291984a(67),
+        csISO92JISC62991984b(68),
+        csISO93JIS62291984badd(69),
+        csISO94JIS62291984hand(70),
+        csISO95JIS62291984handadd(71),
+        csISO96JISC62291984kana(72),
+        csISO2033(73),
+        csISO99NAPLPS(74),
+        csISO102T617bit(75),
+        csISO103T618bit(76),
+        csISO111ECMACyrillic(77),
+        csa71(78),
+        csa72(79),
+        csISO123CSAZ24341985gr(80),
+        csISO88596E(81),
+        csISO88596I(82),
+        csISO128T101G2(83),
+        csISO88598E(84),
+        csISO88598I(85),
+        csISO139CSN369103(86),
+        csISO141JUSIB1002(87),
+        csISO143IECP271(88),
+        csISO146Serbian(89),
+        csISO147Macedonian(90),
+        csISO150(91),
+        csISO151Cuba(92),
+        csISO6937Add(93),
+        csISO153GOST1976874(94),
+        csISO8859Supp(95),
+        csISO10367Box(96),
+        csISO158Lap(97),
+        csISO159JISX02121990(98),
+        csISO646Danish(99),
+        csUSDK(100),
+        csDKUS(101),
+        csKSC5636(102),
+        csUnicode11UTF7(103),
+        csISO2022CN(104),
+        csISO2022CNEXT(105),
+        csUTF8(106),
+        csISO885913(109),
+        csISO885914(110),
+        csISO885915(111),
+        csISO885916(112),
+        csGBK(113),
+        csGB18030(114),
+        csOSDEBCDICDF0415(115),
+        csOSDEBCDICDF03IRV(116),
+        csOSDEBCDICDF041(117),
+        csISO115481(118),
+        csKZ1048(119),
+        csUnicode(1000),
+        csUCS4(1001),
+        csUnicodeASCII(1002),
+        csUnicodeLatin1(1003),
+        csUnicodeIBM1261(1005),
+        csUnicodeIBM1268(1006),
+        csUnicodeIBM1276(1007),
+        csUnicodeIBM1264(1008),
+        csUnicodeIBM1265(1009),
+        csUnicode11(1010),
+        csSCSU(1011),
+        csUTF7(1012),
+        csUTF16BE(1013),
+        csUTF16LE(1014),
+        csUTF16(1015),
+        csCESU8(1016),
+        csUTF32(1017),
+        csUTF32BE(1018),
+        csUTF32LE(1019),
+        csBOCU1(1020),
+        csWindows30Latin1(2000),
+        csWindows31Latin1(2001),
+        csWindows31Latin2(2002),
+        csWindows31Latin5(2003),
+        csHPRoman8(2004),
+        csAdobeStandardEncoding(2005),
+        csVenturaUS(2006),
+        csVenturaInternational(2007),
+        csDECMCS(2008),
+        csPC850Multilingual(2009),
+        csPCp852(2010),
+        csPC8CodePage437(2011),
+        csPC8DanishNorwegian(2012),
+        csPC862LatinHebrew(2013),
+        csPC8Turkish(2014),
+        csIBMSymbols(2015),
+        csIBMThai(2016),
+        csHPLegal(2017),
+        csHPPiFont(2018),
+        csHPMath8(2019),
+        csHPPSMath(2020),
+        csHPDesktop(2021),
+        csVenturaMath(2022),
+        csMicrosoftPublishing(2023),
+        csWindows31J(2024),
+        csGB2312(2025),
+        csBig5(2026),
+        csMacintosh(2027),
+        csIBM037(2028),
+        csIBM038(2029),
+        csIBM273(2030),
+        csIBM274(2031),
+        csIBM275(2032),
+        csIBM277(2033),
+        csIBM278(2034),
+        csIBM280(2035),
+        csIBM281(2036),
+        csIBM284(2037),
+        csIBM285(2038),
+        csIBM290(2039),
+        csIBM297(2040),
+        csIBM420(2041),
+        csIBM423(2042),
+        csIBM424(2043),
+        csIBM500(2044),
+        csIBM851(2045),
+        csIBM855(2046),
+        csIBM857(2047),
+        csIBM860(2048),
+        csIBM861(2049),
+        csIBM863(2050),
+        csIBM864(2051),
+        csIBM865(2052),
+        csIBM868(2053),
+        csIBM869(2054),
+        csIBM870(2055),
+        csIBM871(2056),
+        csIBM880(2057),
+        csIBM891(2058),
+        csIBM903(2059),
+        csIBBM904(2060),
+        csIBM905(2061),
+        csIBM918(2062),
+        csIBM1026(2063),
+        csIBMEBCDICATDE(2064),
+        csEBCDICATDEA(2065),
+        csEBCDICCAFR(2066),
+        csEBCDICDKNO(2067),
+        csEBCDICDKNOA(2068),
+        csEBCDICFISE(2069),
+        csEBCDICFISEA(2070),
+        csEBCDICFR(2071),
+        csEBCDICIT(2072),
+        csEBCDICPT(2073),
+        csEBCDICES(2074),
+        csEBCDICESA(2075),
+        csEBCDICESS(2076),
+        csEBCDICUK(2077),
+        csEBCDICUS(2078),
+        csUnknown8BiT(2079),
+        csMnemonic(2080),
+        csMnem(2081),
+        csVISCII(2082),
+        csVIQR(2083),
+        csKOI8R(2084),
+        csHZGB2312(2085),
+        csIBM866(2086),
+        csPC775Baltic(2087),
+        csKOI8U(2088),
+        csIBM00858(2089),
+        csIBM00924(2090),
+        csIBM01140(2091),
+        csIBM01141(2092),
+        csIBM01142(2093),
+        csIBM01143(2094),
+        csIBM01144(2095),
+        csIBM01145(2096),
+        csIBM01146(2097),
+        csIBM01147(2098),
+        csIBM01148(2099),
+        csIBM01149(2100),
+        csBig5HKSCS(2101),
+        csIBM1047(2102),
+        csPTCP154(2103),
+        csAmiga1251(2104),
+        csKOI7switched(2105),
+        csBRF(2106),
+        csTSCII(2107),
+        cswindows1250(2250),
+        cswindows1251(2251),
+        cswindows1252(2252),
+        cswindows1253(2253),
+        cswindows1254(2254),
+        cswindows1255(2255),
+        cswindows1256(2256),
+        cswindows1257(2257),
+        cswindows1258(2258),
+        csTIS620(2259),
+        reserved(3000)
+    }
+END
+
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/Mibs/IANA/IANA-ITU-ALARM-TC-MIB
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/Mibs/IANA/IANA-ITU-ALARM-TC-MIB	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/Mibs/IANA/IANA-ITU-ALARM-TC-MIB	(revision 457)
@@ -0,0 +1,333 @@
+IANA-ITU-ALARM-TC-MIB DEFINITIONS ::= BEGIN
+
+   IMPORTS
+      MODULE-IDENTITY, mib-2       FROM SNMPv2-SMI
+      TEXTUAL-CONVENTION           FROM SNMPv2-TC;
+
+    ianaItuAlarmNumbers MODULE-IDENTITY
+        LAST-UPDATED "200409090000Z"  -- September 09, 2004
+        ORGANIZATION "IANA"
+        CONTACT-INFO
+            "Postal:    Internet Assigned Numbers Authority
+                        Internet Corporation for Assigned Names
+                        and Numbers
+                        4676 Admiralty Way, Suite 330
+                        Marina del Rey, CA 90292-6601
+                        USA
+
+            Tel:    +1  310-823-9358
+            E-Mail: iana&iana.org"
+        DESCRIPTION
+            "The MIB module defines the ITU Alarm
+            textual convention for objects expected to require
+            regular extension.
+
+            Copyright (C) The Internet Society (2004).  The
+            initial version of this MIB module was published
+            in RFC 3877. For full legal notices see the RFC
+            itself. Supplementary information may be available on:
+                 http://www.ietf.org/copyrights/ianamib.html"
+         REVISION    "200409090000Z"
+         DESCRIPTION
+             "Initial version, published as RFC 3877."
+        ::= { mib-2 119 } 
+
+
+   IANAItuProbableCause ::= TEXTUAL-CONVENTION
+       STATUS current
+       DESCRIPTION
+           "ITU-T probable cause values. Duplicate values defined in
+            X.733 are appended with X733 to ensure syntactic uniqueness.
+            Probable cause value 0 is reserved for special purposes.
+
+            The Internet Assigned Number Authority (IANA) is responsible
+            for the assignment of the enumerations in this TC.
+            IANAItuProbableCause value of 0 is reserved for special
+            purposes and MUST NOT be assigned.
+
+            Values of IANAItuProbableCause in the range 1 to 1023 are
+            reserved for causes that correspond to ITU-T probable cause.
+
+            All other requests for new causes will be handled on a
+            first-come, first served basis and will be assigned
+            enumeration values starting with 1025.
+
+            Request should  come in the form of well-formed
+            SMI [RFC2578] for enumeration names that are unique and
+            sufficiently descriptive.
+
+            While some effort will be taken to ensure that new probable
+            causes do not conceptually duplicate existing probable
+            causes it is acknowledged that the existence of conceptual
+            duplicates in the starting probable cause list is an known
+            industry reality.
+
+            To aid IANA in the administration of probable cause names
+            and values, the OPS Area Director will appoint one or more
+            experts to help review requests.
+
+            See http://www.iana.org"
+       REFERENCE
+           "ITU Recommendation M.3100, 'Generic Network Information
+               Model', 1995
+            ITU Recommendation X.733, 'Information Technology - Open
+               Systems Interconnection - System Management: Alarm
+               Reporting Function', 1992
+            ITU Recommendation X.736, 'Information Technology - Open
+               Systems Interconnection - System Management: Security
+               Alarm Reporting Function', 1992"
+
+       SYNTAX         INTEGER
+               {
+               -- The following probable causes were defined in M.3100
+                aIS  (1),
+                callSetUpFailure  (2),
+                degradedSignal  (3),
+                farEndReceiverFailure  (4),
+                framingError  (5),
+                lossOfFrame (6),
+                lossOfPointer  (7),
+                lossOfSignal  (8),
+                payloadTypeMismatch (9),
+                transmissionError (10),
+                remoteAlarmInterface (11),
+                excessiveBER  (12),
+                pathTraceMismatch  (13),
+                unavailable  (14),
+                signalLabelMismatch (15),
+                lossOfMultiFrame (16),
+                receiveFailure (17),
+                transmitFailure (18),
+                modulationFailure (19),
+                demodulationFailure (20),
+                broadcastChannelFailure (21),
+                connectionEstablishmentError (22),
+                invalidMessageReceived (23),
+                localNodeTransmissionError (24),
+                remoteNodeTransmissionError (25),
+                routingFailure (26),
+    --Values 27-50 are reserved for communications alarm related
+    --probable causes
+    -- The following are used with equipment alarm.
+                backplaneFailure (51),
+                dataSetProblem  (52),
+                equipmentIdentifierDuplication  (53),
+                externalIFDeviceProblem  (54),
+                lineCardProblem (55),
+                multiplexerProblem  (56),
+                nEIdentifierDuplication  (57),
+                powerProblem  (58),
+                processorProblem  (59),
+                protectionPathFailure  (60),
+                receiverFailure  (61),
+                replaceableUnitMissing  (62),
+                replaceableUnitTypeMismatch (63),
+                synchronizationSourceMismatch  (64),
+                terminalProblem   (65),
+                timingProblem   (66),
+                transmitterFailure  (67),
+                trunkCardProblem  (68),
+                replaceableUnitProblem  (69),
+                realTimeClockFailure (70),
+    --An equipment alarm to be issued if the system detects that the
+    --real time clock has failed
+                antennaFailure (71),
+                batteryChargingFailure (72),
+                diskFailure (73),
+                frequencyHoppingFailure (74),
+                iODeviceError (75),
+                lossOfSynchronisation (76),
+                lossOfRedundancy (77),
+                powerSupplyFailure (78),
+                signalQualityEvaluationFailure (79),
+                tranceiverFailure (80),
+                protectionMechanismFailure (81),
+                protectingResourceFailure (82),
+    -- Values 83-100 are reserved for equipment alarm related probable
+    -- causes
+    -- The following are used with environmental alarm.
+                airCompressorFailure  (101),
+                airConditioningFailure  (102),
+                airDryerFailure   (103),
+                batteryDischarging  (104),
+                batteryFailure   (105),
+                commercialPowerFailure  (106),
+                coolingFanFailure  (107),
+                engineFailure  (108),
+                fireDetectorFailure  (109),
+                fuseFailure  (110),
+                generatorFailure  (111),
+                lowBatteryThreshold (112),
+                pumpFailure  (113),
+                rectifierFailure  (114),
+                rectifierHighVoltage  (115),
+                rectifierLowFVoltage  (116),
+                ventilationsSystemFailure  (117),
+                enclosureDoorOpen  (118),
+                explosiveGas  (119),
+                fire (120),
+                flood   (121),
+                highHumidity  (122),
+                highTemperature  (123),
+                highWind  (124),
+                iceBuildUp  (125),
+                intrusionDetection  (126),
+                lowFuel  (127),
+                lowHumidity  (128),
+                lowCablePressure  (129),
+                lowTemperatue  (130),
+                lowWater  (131),
+                smoke  (132),
+                toxicGas  (133),
+                coolingSystemFailure (134),
+                externalEquipmentFailure (135),
+                externalPointFailure (136),
+    -- Values 137-150 are reserved for environmental alarm related
+    -- probable causes
+    -- The following are used with Processing error alarm.
+                storageCapacityProblem (151),
+                memoryMismatch  (152),
+                corruptData  (153),
+                outOfCPUCycles   (154),
+                sfwrEnvironmentProblem  (155),
+                sfwrDownloadFailure  (156),
+                lossOfRealTimel (157),
+    --A processing error alarm to be issued after the system has
+    --reinitialised. This will indicate
+    --to the management systems that the view they have of the managed
+    --system may no longer
+    --be valid. Usage example: The managed
+    --system issues this alarm after a reinitialization with severity
+    --warning to inform the
+    --management system about the event. No clearing notification will
+    --be sent.
+                applicationSubsystemFailure (158),
+                configurationOrCustomisationError (159),
+                databaseInconsistency (160),
+                fileError (161),
+                outOfMemory (162),
+                softwareError (163),
+                timeoutExpired (164),
+                underlayingResourceUnavailable (165),
+                versionMismatch (166),
+    --Values 168-200 are reserved for processing error alarm related
+    -- probable causes.
+                bandwidthReduced (201),
+                congestion (202),
+                excessiveErrorRate (203),
+                excessiveResponseTime (204),
+                excessiveRetransmissionRate (205),
+                reducedLoggingCapability (206),
+                systemResourcesOverload (207 ),
+                -- The following were defined X.733
+                adapterError (500),
+                applicationSubsystemFailture (501),
+                bandwidthReducedX733 (502),
+                callEstablishmentError (503),
+                communicationsProtocolError (504),
+                communicationsSubsystemFailure (505),
+                configurationOrCustomizationError (506),
+                congestionX733 (507),
+                coruptData (508),
+                cpuCyclesLimitExceeded (509),
+                dataSetOrModemError (510),
+                degradedSignalX733 (511),
+                dteDceInterfaceError (512),
+                enclosureDoorOpenX733 (513),
+                equipmentMalfunction (514),
+                excessiveVibration (515),
+                fileErrorX733 (516),
+                fireDetected (517),
+                framingErrorX733 (518),
+                heatingVentCoolingSystemProblem (519),
+                humidityUnacceptable (520),
+                inputOutputDeviceError (521),
+                inputDeviceError (522),
+                lanError (523),
+                leakDetected (524),
+                localNodeTransmissionErrorX733 (525),
+                lossOfFrameX733 (526),
+                lossOfSignalX733 (527),
+                materialSupplyExhausted (528),
+                multiplexerProblemX733 (529),
+                outOfMemoryX733 (530),
+                ouputDeviceError (531),
+                performanceDegraded (532),
+                powerProblems (533),
+                pressureUnacceptable (534),
+                processorProblems (535),
+                pumpFailureX733 (536),
+                queueSizeExceeded (537),
+                receiveFailureX733 (538),
+                receiverFailureX733 (539),
+                remoteNodeTransmissionErrorX733 (540),
+                resourceAtOrNearingCapacity (541),
+                responseTimeExecessive (542),
+                retransmissionRateExcessive (543),
+                softwareErrorX733 (544),
+                softwareProgramAbnormallyTerminated (545),
+                softwareProgramError (546),
+                storageCapacityProblemX733 (547),
+                temperatureUnacceptable (548),
+                thresholdCrossed (549),
+                timingProblemX733 (550),
+                toxicLeakDetected (551),
+                transmitFailureX733 (552),
+                transmiterFailure (553),
+                underlyingResourceUnavailable (554),
+                versionMismatchX733 (555),
+                -- The following are defined in X.736
+                authenticationFailure (600),
+                breachOfConfidentiality (601),
+                cableTamper (602),
+                delayedInformation (603),
+                denialOfService (604),
+                duplicateInformation (605),
+                informationMissing (606),
+                informationModificationDetected (607),
+                informationOutOfSequence (608),
+                keyExpired (609),
+                nonRepudiationFailure (610),
+                outOfHoursActivity (611),
+                outOfService (612),
+                proceduralError (613),
+                unauthorizedAccessAttempt (614),
+                unexpectedInformation (615),
+
+                other (1024)
+                }
+
+   IANAItuEventType ::= TEXTUAL-CONVENTION
+       STATUS current
+       DESCRIPTION
+               "The ITU event Type values.
+
+               The Internet Assigned Number Authority (IANA) is
+               responsible for the assignment of the enumerations
+               in this TC.
+
+               Request should  come in the form of well-formed
+               SMI [RFC2578] for enumeration names that are unique
+               and sufficiently descriptive.
+
+               See http://www.iana.org "
+       REFERENCE
+              "ITU Recommendation X.736, 'Information Technology - Open
+               Systems Interconnection - System Management: Security
+               Alarm Reporting Function', 1992"
+       SYNTAX         INTEGER
+              {
+              other (1),
+              communicationsAlarm (2),
+              qualityOfServiceAlarm (3),
+              processingErrorAlarm (4),
+              equipmentAlarm (5),
+              environmentalAlarm (6),
+              integrityViolation (7),
+              operationalViolation (8),
+              physicalViolation (9),
+              securityServiceOrMechanismViolation (10),
+              timeDomainViolation (11)
+              }
+
+   END
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/Mibs/IANA/IANA-LANGUAGE-MIB
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/Mibs/IANA/IANA-LANGUAGE-MIB	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/Mibs/IANA/IANA-LANGUAGE-MIB	(revision 457)
@@ -0,0 +1,127 @@
+
+   IANA-LANGUAGE-MIB DEFINITIONS ::= BEGIN
+
+   IMPORTS
+       MODULE-IDENTITY, OBJECT-IDENTITY, mib-2
+           FROM SNMPv2-SMI;
+
+   ianaLanguages MODULE-IDENTITY
+       LAST-UPDATED "200005100000Z"  -- May 10, 2000
+       ORGANIZATION "IANA"
+       CONTACT-INFO
+           "Internet Assigned Numbers Authority (IANA)
+
+            Postal: ICANN
+                    4676 Admiralty Way, Suite 330
+                    Marina del Rey, CA 90292
+
+            Tel:    +1 310 823 9358 x20
+            E-Mail: iana&iana.org"
+       DESCRIPTION
+           "The MIB module registers object identifier values for
+            well-known programming and scripting languages. Every
+            language registration MUST describe the format used
+            when transferring scripts written in this language.
+
+            Any additions or changes to the contents of this MIB
+            module require Designated Expert Review as defined in
+            the Guidelines for Writing IANA Considerations Section
+            document. The Designated Expert will be selected by
+            the IESG Area Director of the OPS Area.
+
+            Note, this module does not have to register all possible
+            languages since languages are identified by object
+            identifier values. It is therefore possible to registered 
+            languages in private OID trees. The references given below are not
+            normative with regard to the language version. Other
+            references might be better suited to describe some newer 
+            versions of this language. The references are only
+            provided as `a pointer into the right direction'."
+
+    -- Revision log, in reverse chronological order
+
+       REVISION    "200005100000Z" -- May 10, 2000
+       DESCRIPTION "Import mib-2 instead of experimental, so that
+                    this module compiles"
+
+       REVISION    "199909090900Z" -- September 9, 1999
+       DESCRIPTION "Initial version as published at time of
+                    publication of RFC 2591."
+
+       ::= { mib-2 73 }
+
+
+   ianaLangJavaByteCode OBJECT-IDENTITY
+       STATUS  current
+       DESCRIPTION
+           "Java byte code to be processed by a Java virtual machine.
+            A script written in Java byte code is transferred by using
+            the Java archive file format (JAR)."
+       REFERENCE
+           "The Java Virtual Machine Specification.
+            ISBN 0-201-63452-X"
+       ::= { ianaLanguages 1 }
+
+   ianaLangTcl OBJECT-IDENTITY
+       STATUS  current
+       DESCRIPTION
+           "The Tool Command Language (Tcl). A script written in the
+            Tcl language is transferred in Tcl source code format."
+       REFERENCE
+           "Tcl and the Tk Toolkit.
+            ISBN 0-201-63337-X"
+       ::= { ianaLanguages 2 }
+
+   ianaLangPerl OBJECT-IDENTITY
+       STATUS  current
+       DESCRIPTION
+           "The Perl language. A script written in the Perl language
+            is transferred in Perl source code format."
+       REFERENCE
+           "Programming Perl.
+            ISBN 1-56592-149-6"
+       ::= { ianaLanguages 3 }
+
+   ianaLangScheme OBJECT-IDENTITY
+       STATUS  current
+       DESCRIPTION
+           "The Scheme language. A script written in the Scheme
+            language is transferred in Scheme source code format."
+       REFERENCE
+           "The Revised^4 Report on the Algorithmic Language Scheme.
+            MIT Press"
+       ::= { ianaLanguages 4 }
+
+   ianaLangSRSL OBJECT-IDENTITY
+       STATUS  current
+       DESCRIPTION
+           "The SNMP Script Language defined by SNMP Research. A
+            script written in the SNMP Script Language is transferred
+            in the SNMP Script Language source code format."
+       ::= { ianaLanguages 5 }
+
+   ianaLangPSL OBJECT-IDENTITY
+       STATUS  current
+       DESCRIPTION
+           "The Patrol Script Language defined by BMC Software. A script
+            written in the Patrol Script Language is transferred in the
+            Patrol Script Language source code format."
+       REFERENCE
+           "PATROL Script Language Reference Manual, Version 3.0,
+            November 30, 1995. BMC Software, Inc. 2101 City West Blvd.,
+            Houston, Texas 77042."
+       ::= { ianaLanguages 6 }
+
+   ianaLangSMSL OBJECT-IDENTITY
+       STATUS  current
+       DESCRIPTION
+           "The Systems Management Scripting Language. A script written
+            in the SMSL language is transferred in the SMSL source code
+            format."
+       REFERENCE
+           "ISO/ITU Command Sequencer.
+            ISO 10164-21 or ITU X.753"
+       ::= { ianaLanguages 7 }
+
+   END
+
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/Mibs/IANA/IANA-MALLOC-MIB
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/Mibs/IANA/IANA-MALLOC-MIB	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/Mibs/IANA/IANA-MALLOC-MIB	(revision 457)
@@ -0,0 +1,67 @@
+
+IANA-MALLOC-MIB DEFINITIONS ::= BEGIN
+
+IMPORTS
+    MODULE-IDENTITY, mib-2           FROM SNMPv2-SMI
+    TEXTUAL-CONVENTION               FROM SNMPv2-TC;
+
+ianaMallocMIB MODULE-IDENTITY
+    LAST-UPDATED "200301271200Z" -- January 27, 2003
+    ORGANIZATION "IANA"
+    CONTACT-INFO
+            " Internet Assigned Numbers Authority
+              Internet Corporation for Assigned Names and Numbers
+              4676 Admiralty Way, Suite 330
+              Marina del Rey, CA 90292-6601
+
+              Phone: +1 310 823 9358
+              EMail: iana&iana.org"
+    DESCRIPTION
+            "This MIB module defines the IANAscopeSource and
+            IANAmallocRangeSource textual conventions for use in MIBs
+            which need to identify ways of learning multicast scope and
+            range information.
+
+            Any additions or changes to the contents of this MIB module
+            require either publication of an RFC, or Designated Expert
+            Review as defined in the Guidelines for Writing IANA
+            Considerations Section document.  The Designated Expert will
+            be selected by the IESG Area Director(s) of the Transport
+            Area."
+
+    -- revision log
+
+    REVISION     "200301271200Z" -- January 27, 2003
+    DESCRIPTION
+            "Initial version."
+    ::= { mib-2 102 } 
+
+IANAscopeSource ::= TEXTUAL-CONVENTION
+   STATUS  current
+   DESCRIPTION
+            "The source of multicast scope information."
+   SYNTAX  INTEGER {
+              other(1),  -- none of the following
+              manual(2), -- statically configured
+              local(3),  -- automatically added by the system,
+                         -- such as a Source-Specific Multicast
+                         -- scope
+              mzap(4),   -- MZAP
+              madcap(5)  -- MADCAP
+           }
+
+IANAmallocRangeSource ::= TEXTUAL-CONVENTION
+   STATUS  current
+   DESCRIPTION
+            "The source of multicast address allocation range
+            information."
+   SYNTAX  INTEGER {
+              other(1),  -- none of the following
+              manual(2), -- statically configured
+              local(3)   -- automatically added by the system,
+                         -- such as a Source-Specific Multicast
+                         -- range
+           }
+
+END
+
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/Mibs/IANA/IANA-MAU-MIB
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/Mibs/IANA/IANA-MAU-MIB	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/Mibs/IANA/IANA-MAU-MIB	(revision 457)
@@ -0,0 +1,770 @@
+IANA-MAU-MIB DEFINITIONS ::= BEGIN
+
+     IMPORTS
+       MODULE-IDENTITY, OBJECT-IDENTITY, mib-2
+         FROM SNMPv2-SMI
+       TEXTUAL-CONVENTION
+         FROM SNMPv2-TC
+       ;
+
+     ianaMauMIB MODULE-IDENTITY
+       LAST-UPDATED "200704210000Z"  -- April 21, 2007
+       ORGANIZATION "IANA"
+       CONTACT-INFO "        Internet Assigned Numbers Authority
+
+                     Postal: ICANN
+                             4676 Admiralty Way, Suite 330
+                             Marina del Rey, CA 90292
+
+                        Tel: +1-310-823-9358
+                      EMail: iana&iana.org"
+
+       DESCRIPTION
+         "This MIB module defines dot3MauType OBJECT-IDENTITIES and
+         IANAifMauListBits, IANAifMauMediaAvailable,
+         IANAifMauAutoNegCapBits, and IANAifJackType
+
+         TEXTUAL-CONVENTIONs, specifying enumerated values of the
+         ifMauTypeListBits, ifMauMediaAvailable / rpMauMediaAvailable,
+         ifMauAutoNegCapabilityBits / ifMauAutoNegCapAdvertisedBits /
+         ifMauAutoNegCapReceivedBits and ifJackType / rpJackType objects
+         respectively, defined in the MAU-MIB.
+
+         It is intended that each new MAU type, Media Availability
+         state, Auto Negotiation capability and/or Jack type defined by
+         the IEEE 802.3 working group and approved for publication in a
+         revision of IEEE Std 802.3 will be added to this MIB module,
+         provided that it is suitable for being managed by the base
+         objects in the MAU-MIB.  An Expert Review, as defined in
+         RFC 2434 [RFC2434], is REQUIRED for such additions.
+
+         The following reference is used throughout this MIB module:
+
+         [IEEE802.3] refers to:
+            IEEE Std 802.3, 2005 Edition: 'IEEE Standard for
+            Information technology - Telecommunications and information
+            exchange between systems - Local and metropolitan area
+            networks - Specific requirements -
+            Part 3: Carrier sense multiple access with collision
+            detection (CSMA/CD) access method and physical layer
+            specifications'.
+
+         This reference should be updated as appropriate when new
+         MAU types, Media Availability states, Auto Negotiation
+         capabilities, and/or Jack types are added to this MIB module.
+
+         Copyright (C) The IETF Trust (2007).
+         The initial version of this MIB module was published in
+         RFC 4836; for full legal notices see the RFC itself.
+         Supplementary information may be available at:
+         http://www.ietf.org/copyrights/ianamib.html"
+
+       REVISION     "200704210000Z"  -- April 21, 2007
+       DESCRIPTION  "Initial version of this MIB as published in
+                     RFC 4836."
+       ::= { mib-2 154 }
+
+     -- Textual Conventions
+
+     IANAifMauTypeListBits ::= TEXTUAL-CONVENTION
+       STATUS       current
+       DESCRIPTION
+         "This data type is used as the syntax of the ifMauTypeListBits
+         object in the (updated) definition of MAU-MIB's ifMauTable.
+
+         The most recent version of this textual convention is available
+         in the online version of this MIB module on the IANA web site.
+
+         Requests for new values should be made to IANA via email
+         (iana&iana.org).
+
+         Note that changes in this textual convention SHALL be
+         synchronized with relevant changes in the dot3MauType
+         OBJECT-IDENTITIES."
+       REFERENCE
+         "[IEEE802.3], Section 30.5.1.1.2"
+       SYNTAX       BITS {
+              bOther(0),          -- other or unknown
+              bAUI(1),            -- AUI
+              b10base5(2),        -- 10BASE-5
+              bFoirl(3),          -- FOIRL
+
+              b10base2(4),        -- 10BASE-2
+              b10baseT(5),        -- 10BASE-T duplex mode unknown
+              b10baseFP(6),       -- 10BASE-FP
+              b10baseFB(7),       -- 10BASE-FB
+              b10baseFL(8),       -- 10BASE-FL duplex mode unknown
+              b10broad36(9),      -- 10BROAD36
+              b10baseTHD(10),     -- 10BASE-T  half duplex mode
+              b10baseTFD(11),     -- 10BASE-T  full duplex mode
+              b10baseFLHD(12),    -- 10BASE-FL half duplex mode
+              b10baseFLFD(13),    -- 10BASE-FL full duplex mode
+              b100baseT4(14),     -- 100BASE-T4
+              b100baseTXHD(15),   -- 100BASE-TX half duplex mode
+              b100baseTXFD(16),   -- 100BASE-TX full duplex mode
+              b100baseFXHD(17),   -- 100BASE-FX half duplex mode
+              b100baseFXFD(18),   -- 100BASE-FX full duplex mode
+              b100baseT2HD(19),   -- 100BASE-T2 half duplex mode
+              b100baseT2FD(20),   -- 100BASE-T2 full duplex mode
+
+              b1000baseXHD(21),   -- 1000BASE-X half duplex mode
+              b1000baseXFD(22),   -- 1000BASE-X full duplex mode
+              b1000baseLXHD(23),  -- 1000BASE-LX half duplex mode
+              b1000baseLXFD(24),  -- 1000BASE-LX full duplex mode
+              b1000baseSXHD(25),  -- 1000BASE-SX half duplex mode
+              b1000baseSXFD(26),  -- 1000BASE-SX full duplex mode
+              b1000baseCXHD(27),  -- 1000BASE-CX half duplex mode
+              b1000baseCXFD(28),  -- 1000BASE-CX full duplex mode
+              b1000baseTHD(29),   -- 1000BASE-T half duplex mode
+              b1000baseTFD(30),   -- 1000BASE-T full duplex mode
+
+              b10GbaseX(31),      -- 10GBASE-X
+              b10GbaseLX4(32),    -- 10GBASE-LX4
+
+              b10GbaseR(33),      -- 10GBASE-R
+              b10GbaseER(34),     -- 10GBASE-ER
+              b10GbaseLR(35),     -- 10GBASE-LR
+              b10GbaseSR(36),     -- 10GBASE-SR
+              b10GbaseW(37),      -- 10GBASE-W
+              b10GbaseEW(38),     -- 10GBASE-EW
+              b10GbaseLW(39),     -- 10GBASE-LW
+              b10GbaseSW(40),     -- 10GBASE-SW
+              -- new since RFC 3636
+              b10GbaseCX4(41),    -- 10GBASE-CX4
+              b2BaseTL(42),       -- 2BASE-TL
+              b10PassTS(43),      -- 10PASS-TS
+              b100BaseBX10D(44),  -- 100BASE-BX10D
+              b100BaseBX10U(45),  -- 100BASE-BX10U
+              b100BaseLX10(46),   -- 100BASE-LX10
+              b1000BaseBX10D(47), -- 1000BASE-BX10D
+              b1000BaseBX10U(48), -- 1000BASE-BX10U
+              b1000BaseLX10(49),  -- 1000BASE-LX10
+              b1000BasePX10D(50), -- 1000BASE-PX10D
+              b1000BasePX10U(51), -- 1000BASE-PX10U
+              b1000BasePX20D(52), -- 1000BASE-PX20D
+              b1000BasePX20U(53)  -- 1000BASE-PX20U
+         }
+
+     IANAifMauMediaAvailable ::= TEXTUAL-CONVENTION
+       STATUS       current
+       DESCRIPTION
+         "This data type is used as the syntax of the
+         ifMauMediaAvailable and rpMauMediaAvailable objects in the
+         (updated) definition of MAU-MIB's ifMauTable and rpMauTable
+         respectively.
+
+         Possible values are:
+           other(1)             - undefined (not listed below)
+           unknown(2)           - MAU's true state is unknown; e.g.,
+                                  during initialization
+           available(3)         - link, light, or loopback is normal
+           notAvailable(4)      - link loss, low light, or no loopback
+           remoteFault(5)       - a fault has been detected at the
+                                  remote end of the link.  This value
+                                  applies to 10BASE-FB, 100BASE-T4 Far
+                                  End Fault Indication and non-specified
+                                  remote faults from a system running
+                                  auto-negotiation
+           invalidSignal(6)     - invalid signal has been received from
+                                  the other end of the link, 10BASE-FB
+                                  only
+           remoteJabber(7)      - remote fault, due to jabber
+
+           remoteLinkLoss(8)    - remote fault, due to link loss
+           remoteTest(9)        - remote fault, due to test
+           offline(10)          - offline, Clause 37 Auto-Negotiation
+                                  only
+           autoNegError(11)     - Auto-Negotiation Error, Clause 37
+                                  Auto-Negotiation only
+           pmdLinkFault(12)     - PMA/PMD receive link fault.  In case
+                                  of PAF (2BASE-TL / 10PASS-TS PHYs),
+                                  all PMEs in the aggregation group have
+                                  detected a link fault
+           wisFrameLoss(13)     - WIS loss of frame, 10GBASE-W only
+           wisSignalLoss(14)    - WIS loss of signal, 10GBASE-W only
+           pcsLinkFault(15)     - PCS receive link fault
+           excessiveBER(16)     - PCS Bit Error Ratio monitor
+                                  reporting excessive error ratio
+           dxsLinkFault(17)     - DTE XGXS receive link fault, XAUI only
+           pxsLinkFault(18)     - PHY XGXS receive link fault, XAUI only
+           availableReduced(19) - link normal, reduced bandwidth,
+                                  2BASE-TL / 10PASS-TS only
+           ready(20)            - at least one PME in the aggregation
+                                  group is detecting handshake tones,
+                                  2BASE-TL / 10PASS-TS only
+
+         If the MAU is a 10M b/s link or fiber type (FOIRL, 10BASE-T,
+         10BASE-F), then this is equivalent to the link test fail
+         state/low light function.  For an AUI, 10BASE2, 10BASE5, or
+         10BROAD36 MAU, this indicates whether loopback is detected on
+         the DI circuit.  The value of this attribute persists between
+         packets for MAU types AUI, 10BASE5, 10BASE2, 10BROAD36, and
+         10BASEFP.
+
+         At power-up or following a reset, the Media Available state
+         will be unknown(2) for AUI, 10BASE5, 10BASE2, 10BROAD36, and
+         10BASE-FP MAUs.  For these MAUs loopback will be tested on each
+         transmission during which no collision is detected.
+         If DI is receiving input when DO returns to IDL after a
+         transmission and there has been no collision during the
+         transmission, then loopback will be detected.  The Media
+         Available state will only change during noncollided
+         transmissions for AUI, 10BASE2, 10BASE5, 10BROAD36, and
+         10BASE-FP MAUs.
+
+         For 100BASE-T2, 100BASE-T4, 100BASE-TX, 100BASE-FX,
+         100BASE-LX10, and 100BASE-BX10 PHYs the enumerations match the
+         states within the link integrity state diagram.
+         Any MAU that implements management of [IEEE802.3] Clause
+         28 Auto-Negotiation, will map remote fault indication to
+         remoteFault(5).
+
+         Any MAU that implements management of Clause 37
+         Auto-Negotiation, will map the received RF1 and RF2 bits as
+         follows: Offline maps to offline(10), Link_Failure maps to
+         remoteFault(5), and Auto-Negotiation Error maps to
+         autoNegError(11).
+
+         The value remoteFault(5) applies to 10BASE-FB remote
+         fault indication, the 100BASE-X far-end fault indication, and
+         nonspecified remote faults from a system running Clause 28
+         Auto-Negotiation.
+
+         The value remoteJabber(7), remoteLink loss(8), or remoteTest(9)
+         SHOULD be used instead of remoteFault(5) where the reason for
+         remote fault is identified in the remote signaling protocol.
+         Where a Clause 22 MII or Clause 35 GMII is present, a logic
+         one in the remote fault bit maps to the value remoteFault(5),
+         a logic zero in the link status bit maps to the enumeration
+         notAvailable(4).  The value notAvailable(4) takes precedence
+         over remoteFault(5).
+
+         For 2BASE-TL and 10PASS-TS PHYs, the value unknown(2) maps to
+         the condition where the PHY (PCS with connected PMEs) is
+         initializing, the value ready(20) maps to the condition where
+         the interface is down and at least one PME in the aggregation
+         group is ready for handshake, the value available(3) maps to
+         the condition where all the PMEs in the aggregation group are
+         up, the value notAvailable(4) maps to the condition where all
+         the PMEs in the aggregation group are down and no handshake
+         tones are detected, the value availableReduced(19) maps to the
+         condition where the interface is up, a link fault is detected
+         at the receive direction by one or more PMEs in the
+         aggregation group, but at least one PME is up and the
+         enumeration pmdLinkFault(12) maps to the condition where a link
+         fault is detected at the receive direction by all of the PMEs
+         in the aggregation group.
+
+         For 10 Gb/s the enumerations map to value of the link_fault
+         variable within the Link Fault Signaling state diagram
+         as follows: the value OK maps to the value available(3),
+         the value Local Fault maps to the value notAvailable(4),
+         and the value Remote Fault maps to the value remoteFault(5).
+         The value pmdLinkFault(12), wisFrameLoss(13),
+         wisSignalLoss(14), pcsLinkFault(15), excessiveBER(16), or
+         dxsLinkFault(17) SHOULD be used instead of the value
+         notAvailable(4), where the reason for the Local Fault state can
+         be identified through the use of the Clause 45 MDIO Interface.
+         Where multiple reasons for the Local Fault state can be
+         identified, only the highest precedence error SHOULD be
+
+         reported.  This precedence in descending order is as follows:
+
+           pxsLinkFault
+           pmdLinkFault
+           wisFrameLoss
+           wisSignalLoss
+           pcsLinkFault
+           excessiveBER
+           dxsLinkFault.
+
+         Where a Clause 45 MDIO interface is present a logic zero in
+         the PMA/PMD Receive link status bit ([IEEE802.3]
+         Section 45.2.1.2.2) maps to the value pmdLinkFault(12),
+         logic one in the LOF status bit (Section 45.2.2.10.4) maps
+         to the value wisFrameLoss(13), a logic one in the LOS
+         status bit (Section 45.2.2.10.5) maps to the value
+         wisSignalLoss, a logic zero in the PCS Receive
+         link status bit (Section 45.2.3.2.2) maps to the value
+         pcsLinkFault(15), a logic one in the 10GBASE-R PCS Latched
+         high BER status bit (Section 45.2.3.12.2) maps to the value
+         excessiveBER, a logic zero in the DTE XS receive link status
+         bit (Section 45.2.5.2.2) maps to the value dxsLinkFault(17)
+         and a logic zero in the PHY XS transmit link status bit
+         (Section 45.2.4.2.2) maps to the value pxsLinkFault(18).
+
+         The most recent version of this textual convention is available
+         in the online version of this MIB module on the IANA web site.
+
+         Requests for new values should be made to IANA via email
+         (iana&iana.org)."
+       REFERENCE
+         "[IEEE802.3], Section 30.5.1.1.4"
+       SYNTAX       INTEGER {
+              other(1),
+              unknown(2),
+              available(3),
+              notAvailable(4),
+              remoteFault(5),
+              invalidSignal(6),
+              remoteJabber(7),
+              remoteLinkLoss(8),
+              remoteTest(9),
+              offline(10),
+              autoNegError(11),
+              pmdLinkFault(12),
+              wisFrameLoss(13),
+              wisSignalLoss(14),
+              pcsLinkFault(15),
+
+              excessiveBER(16),
+              dxsLinkFault(17),
+              pxsLinkFault(18),
+              availableReduced(19),
+              ready(20)
+         }
+
+     IANAifMauAutoNegCapBits ::= TEXTUAL-CONVENTION
+       STATUS       current
+       DESCRIPTION
+         "This data type is used as the syntax of the
+         ifMauAutoNegCapabilityBits, ifMauAutoNegCapAdvertisedBits, and
+         ifMauAutoNegCapReceivedBits objects in the (updated) definition
+         of MAU-MIB's ifMauAutoNegTable.
+
+         The most recent version of this textual convention is available
+         in the online version of this MIB module on the IANA web site.
+
+         Requests for new values should be made to IANA via email
+         (iana&iana.org)."
+       REFERENCE
+         "[IEEE802.3], Section 30.6.1.1.5"
+       SYNTAX       BITS {
+              bOther(0),          -- other or unknown
+              b10baseT(1),        -- 10BASE-T  half duplex mode
+              b10baseTFD(2),      -- 10BASE-T  full duplex mode
+              b100baseT4(3),      -- 100BASE-T4
+              b100baseTX(4),      -- 100BASE-TX half duplex mode
+              b100baseTXFD(5),    -- 100BASE-TX full duplex mode
+              b100baseT2(6),      -- 100BASE-T2 half duplex mode
+              b100baseT2FD(7),    -- 100BASE-T2 full duplex mode
+              bFdxPause(8),       -- PAUSE for full-duplex links
+              bFdxAPause(9),      -- Asymmetric PAUSE for full-duplex
+                                  --     links
+              bFdxSPause(10),     -- Symmetric PAUSE for full-duplex
+                                  --     links
+              bFdxBPause(11),     -- Asymmetric and Symmetric PAUSE for
+                                  --     full-duplex links
+              b1000baseX(12),     -- 1000BASE-X, -LX, -SX, -CX half
+                                  --     duplex mode
+              b1000baseXFD(13),   -- 1000BASE-X, -LX, -SX, -CX full
+                                  --     duplex mode
+              b1000baseT(14),     -- 1000BASE-T half duplex mode
+              b1000baseTFD(15)    -- 1000BASE-T full duplex mode
+         }
+
+     IANAifJackType ::= TEXTUAL-CONVENTION
+       STATUS       current
+
+       DESCRIPTION
+         "Common enumeration values for repeater and interface MAU
+         jack types.  This data type is used as the syntax of the
+         ifJackType and rpJackType objects in the (updated) definition
+         of MAU-MIB's ifJackTable and rpJackTable respectively.
+
+         Possible values are:
+              other(1)          - undefined or unknown
+              rj45(2)           - RJ45
+              rj45S(3)          - RJ45 shielded
+              db9(4)            - DB9
+              bnc(5)            - BNC
+              fAUI(6)           - AUI female
+              mAUI(7)           - AUI male
+              fiberSC(8)        - SC fiber
+              fiberMIC(9)       - MIC fiber
+              fiberST(10)       - ST fiber
+              telco(11)         - Telco
+              mtrj(12)          - MT-RJ fiber
+              hssdc(13)         - fiber channel style-2
+              fiberLC(14)       - LC fiber
+              cx4(15)           - IB4X for 10GBASE-CX4
+
+         The most recent version of this textual convention is available
+         in the online version of this MIB module on the IANA web site.
+
+         Requests for new values should be made to IANA via email
+         (iana&iana.org)."
+       SYNTAX       INTEGER {
+              other(1),
+              rj45(2),
+              rj45S(3),
+              db9(4),
+              bnc(5),
+              fAUI(6),
+              mAUI(7),
+              fiberSC(8),
+              fiberMIC(9),
+              fiberST(10),
+              telco(11),
+              mtrj(12),
+              hssdc(13),
+              fiberLC(14),
+              -- new since RFC 3636
+              cx4(15)
+         }
+
+     -- OBJECT IDENTITIES for MAU types
+
+     --  (see rpMauType and ifMauType of MAU-MIB for usage)
+     -- The following definitions has been moved from RFC 3636 and
+     -- no longer appear in its revision.
+
+     dot3MauType OBJECT IDENTIFIER ::= { mib-2 snmpDot3MauMgt(26) 4 }
+
+     dot3MauTypeAUI OBJECT-IDENTITY
+       STATUS      current
+       DESCRIPTION "no internal MAU, view from AUI"
+       REFERENCE   "[IEEE802.3], Section 7"
+       ::= { dot3MauType 1 }
+
+     dot3MauType10Base5 OBJECT-IDENTITY
+       STATUS      current
+       DESCRIPTION "thick coax MAU"
+       REFERENCE   "[IEEE802.3], Section 7"
+       ::= { dot3MauType 2 }
+
+     dot3MauTypeFoirl OBJECT-IDENTITY
+       STATUS      current
+       DESCRIPTION "FOIRL MAU"
+       REFERENCE   "[IEEE802.3], Section 9.9"
+       ::= { dot3MauType 3 }
+
+     dot3MauType10Base2 OBJECT-IDENTITY
+       STATUS      current
+       DESCRIPTION "thin coax MAU"
+       REFERENCE   "[IEEE802.3], Section 10"
+       ::= { dot3MauType 4 }
+
+     dot3MauType10BaseT OBJECT-IDENTITY
+       STATUS      current
+       DESCRIPTION "UTP MAU.
+                   Note that it is strongly recommended that
+                   agents return either dot3MauType10BaseTHD or
+                   dot3MauType10BaseTFD if the duplex mode is
+                   known.  However, management applications should
+                   be prepared to receive this MAU type value from
+                   older agent implementations."
+       REFERENCE   "[IEEE802.3], Section 14"
+       ::= { dot3MauType 5 }
+
+     dot3MauType10BaseFP OBJECT-IDENTITY
+       STATUS      current
+       DESCRIPTION "passive fiber MAU"
+       REFERENCE   "[IEEE802.3], Section 16"
+       ::= { dot3MauType 6 }
+
+     dot3MauType10BaseFB OBJECT-IDENTITY
+       STATUS      current
+       DESCRIPTION "sync fiber MAU"
+       REFERENCE   "[IEEE802.3], Section 17"
+       ::= { dot3MauType 7 }
+
+     dot3MauType10BaseFL OBJECT-IDENTITY
+       STATUS      current
+       DESCRIPTION "async fiber MAU.
+                   Note that it is strongly recommended that
+                   agents return either dot3MauType10BaseFLHD or
+                   dot3MauType10BaseFLFD if the duplex mode is
+                   known.  However, management applications should
+                   be prepared to receive this MAU type value from
+                   older agent implementations."
+       REFERENCE   "[IEEE802.3], Section 18"
+       ::= { dot3MauType 8 }
+
+     dot3MauType10Broad36 OBJECT-IDENTITY
+       STATUS      current
+       DESCRIPTION "broadband DTE MAU.
+                   Note that 10BROAD36 MAUs can be attached to
+                   interfaces but not to repeaters."
+       REFERENCE   "[IEEE802.3], Section 11"
+       ::= { dot3MauType 9 }
+
+     ------ new since RFC 1515:
+     dot3MauType10BaseTHD OBJECT-IDENTITY
+       STATUS      current
+       DESCRIPTION "UTP MAU, half duplex mode"
+       REFERENCE   "[IEEE802.3], Section 14"
+       ::= { dot3MauType 10 }
+
+     dot3MauType10BaseTFD OBJECT-IDENTITY
+       STATUS      current
+       DESCRIPTION "UTP MAU, full duplex mode"
+       REFERENCE   "[IEEE802.3], Section 14"
+       ::= { dot3MauType 11 }
+
+     dot3MauType10BaseFLHD OBJECT-IDENTITY
+       STATUS      current
+       DESCRIPTION "async fiber MAU, half duplex mode"
+       REFERENCE   "[IEEE802.3], Section 18"
+       ::= { dot3MauType 12 }
+
+     dot3MauType10BaseFLFD OBJECT-IDENTITY
+       STATUS      current
+       DESCRIPTION "async fiber MAU, full duplex mode"
+
+       REFERENCE   "[IEEE802.3], Section 18"
+       ::= { dot3MauType 13 }
+
+     dot3MauType100BaseT4 OBJECT-IDENTITY
+       STATUS      current
+       DESCRIPTION "4 pair category 3 UTP"
+       REFERENCE   "[IEEE802.3], Section 23"
+       ::= { dot3MauType 14 }
+
+     dot3MauType100BaseTXHD OBJECT-IDENTITY
+       STATUS      current
+       DESCRIPTION "2 pair category 5 UTP, half duplex mode"
+       REFERENCE   "[IEEE802.3], Section 25"
+       ::= { dot3MauType 15 }
+
+     dot3MauType100BaseTXFD OBJECT-IDENTITY
+       STATUS      current
+       DESCRIPTION "2 pair category 5 UTP, full duplex mode"
+       REFERENCE   "[IEEE802.3], Section 25"
+       ::= { dot3MauType 16 }
+
+     dot3MauType100BaseFXHD OBJECT-IDENTITY
+       STATUS      current
+       DESCRIPTION "X fiber over PMT, half duplex mode"
+       REFERENCE   "[IEEE802.3], Section 26"
+       ::= { dot3MauType 17 }
+
+     dot3MauType100BaseFXFD OBJECT-IDENTITY
+       STATUS      current
+       DESCRIPTION "X fiber over PMT, full duplex mode"
+       REFERENCE   "[IEEE802.3], Section 26"
+       ::= { dot3MauType 18 }
+
+     dot3MauType100BaseT2HD OBJECT-IDENTITY
+       STATUS      current
+       DESCRIPTION "2 pair category 3 UTP, half duplex mode"
+       REFERENCE   "[IEEE802.3], Section 32"
+       ::= { dot3MauType 19 }
+
+     dot3MauType100BaseT2FD OBJECT-IDENTITY
+       STATUS      current
+       DESCRIPTION "2 pair category 3 UTP, full duplex mode"
+       REFERENCE   "[IEEE802.3], Section 32"
+       ::= { dot3MauType 20 }
+
+     ------ new since RFC 2239:
+     dot3MauType1000BaseXHD OBJECT-IDENTITY
+       STATUS      current
+
+       DESCRIPTION "PCS/PMA, unknown PMD, half duplex mode"
+       REFERENCE   "[IEEE802.3], Section 36"
+       ::= { dot3MauType 21 }
+
+     dot3MauType1000BaseXFD OBJECT-IDENTITY
+       STATUS      current
+       DESCRIPTION "PCS/PMA, unknown PMD, full duplex mode"
+       REFERENCE   "[IEEE802.3], Section 36"
+       ::= { dot3MauType 22 }
+
+     dot3MauType1000BaseLXHD OBJECT-IDENTITY
+       STATUS      current
+       DESCRIPTION "Fiber over long-wavelength laser, half duplex
+                   mode"
+       REFERENCE   "[IEEE802.3], Section 38"
+       ::= { dot3MauType 23 }
+
+     dot3MauType1000BaseLXFD OBJECT-IDENTITY
+       STATUS      current
+       DESCRIPTION "Fiber over long-wavelength laser, full duplex
+                   mode"
+       REFERENCE   "[IEEE802.3], Section 38"
+       ::= { dot3MauType 24 }
+
+     dot3MauType1000BaseSXHD OBJECT-IDENTITY
+       STATUS      current
+       DESCRIPTION "Fiber over short-wavelength laser, half
+                   duplex mode"
+       REFERENCE   "[IEEE802.3], Section 38"
+       ::= { dot3MauType 25 }
+
+     dot3MauType1000BaseSXFD OBJECT-IDENTITY
+       STATUS      current
+       DESCRIPTION "Fiber over short-wavelength laser, full
+                   duplex mode"
+       REFERENCE   "[IEEE802.3], Section 38"
+       ::= { dot3MauType 26 }
+
+     dot3MauType1000BaseCXHD OBJECT-IDENTITY
+       STATUS      current
+       DESCRIPTION "Copper over 150-Ohm balanced cable, half
+                   duplex mode"
+       REFERENCE   "[IEEE802.3], Section 39"
+       ::= { dot3MauType 27 }
+
+     dot3MauType1000BaseCXFD OBJECT-IDENTITY
+       STATUS      current
+       DESCRIPTION "Copper over 150-Ohm balanced cable, full
+
+                   duplex mode"
+       REFERENCE   "[IEEE802.3], Section 39"
+       ::= { dot3MauType 28 }
+
+     dot3MauType1000BaseTHD OBJECT-IDENTITY
+       STATUS      current
+       DESCRIPTION "Four-pair Category 5 UTP, half duplex mode"
+       REFERENCE   "[IEEE802.3], Section 40"
+       ::= { dot3MauType 29 }
+
+     dot3MauType1000BaseTFD OBJECT-IDENTITY
+       STATUS      current
+       DESCRIPTION "Four-pair Category 5 UTP, full duplex mode"
+       REFERENCE   "[IEEE802.3], Section 40"
+       ::= { dot3MauType 30 }
+
+     ------ new since RFC 2668:
+     dot3MauType10GigBaseX OBJECT-IDENTITY
+       STATUS      current
+       DESCRIPTION "X PCS/PMA, unknown PMD."
+       REFERENCE   "[IEEE802.3], Section 48"
+       ::= { dot3MauType 31 }
+
+     dot3MauType10GigBaseLX4 OBJECT-IDENTITY
+       STATUS      current
+       DESCRIPTION "X fiber over WWDM optics"
+       REFERENCE   "[IEEE802.3], Section 53"
+       ::= { dot3MauType 32 }
+
+     dot3MauType10GigBaseR OBJECT-IDENTITY
+       STATUS      current
+       DESCRIPTION "R PCS/PMA, unknown PMD."
+       REFERENCE   "[IEEE802.3], Section 49"
+       ::= { dot3MauType 33 }
+
+     dot3MauType10GigBaseER OBJECT-IDENTITY
+       STATUS      current
+       DESCRIPTION "R fiber over 1550 nm optics"
+       REFERENCE   "[IEEE802.3], Section 52"
+       ::= { dot3MauType 34 }
+
+     dot3MauType10GigBaseLR OBJECT-IDENTITY
+       STATUS      current
+       DESCRIPTION "R fiber over 1310 nm optics"
+       REFERENCE   "[IEEE802.3], Section 52"
+       ::= { dot3MauType 35 }
+
+     dot3MauType10GigBaseSR OBJECT-IDENTITY
+
+       STATUS      current
+       DESCRIPTION "R fiber over 850 nm optics"
+       REFERENCE   "[IEEE802.3], Section 52"
+       ::= { dot3MauType 36 }
+
+     dot3MauType10GigBaseW OBJECT-IDENTITY
+       STATUS      current
+       DESCRIPTION "W PCS/PMA, unknown PMD."
+       REFERENCE   "[IEEE802.3], Section 49 and 50"
+       ::= { dot3MauType 37 }
+
+     dot3MauType10GigBaseEW OBJECT-IDENTITY
+       STATUS      current
+       DESCRIPTION "W fiber over 1550 nm optics"
+       REFERENCE   "[IEEE802.3], Section 52"
+       ::= { dot3MauType 38 }
+
+     dot3MauType10GigBaseLW OBJECT-IDENTITY
+       STATUS      current
+       DESCRIPTION "W fiber over 1310 nm optics"
+       REFERENCE   "[IEEE802.3], Section 52"
+       ::= { dot3MauType 39 }
+
+     dot3MauType10GigBaseSW OBJECT-IDENTITY
+       STATUS      current
+       DESCRIPTION "W fiber over 850 nm optics"
+       REFERENCE   "[IEEE802.3], Section 52"
+       ::= { dot3MauType 40 }
+
+     ------ new since RFC 3636:
+     dot3MauType10GigBaseCX4 OBJECT-IDENTITY
+       STATUS      current
+       DESCRIPTION "X copper over 8 pair 100-Ohm balanced cable"
+       REFERENCE   "[IEEE802.3], Section 54"
+       ::= { dot3MauType 41 }
+
+     dot3MauType2BaseTL OBJECT-IDENTITY
+       STATUS      current
+       DESCRIPTION "Voice grade UTP copper, up to 2700m, optional PAF"
+       REFERENCE   "[IEEE802.3], Sections 61 and 63"
+       ::= { dot3MauType 42 }
+
+     dot3MauType10PassTS OBJECT-IDENTITY
+       STATUS      current
+       DESCRIPTION "Voice grade UTP copper, up to 750m, optional PAF"
+       REFERENCE   "[IEEE802.3], Sections 61 and 62"
+       ::= { dot3MauType 43 }
+
+     dot3MauType100BaseBX10D OBJECT-IDENTITY
+       STATUS      current
+       DESCRIPTION "One single-mode fiber OLT, long wavelength, 10km"
+       REFERENCE   "[IEEE802.3], Section 58"
+       ::= { dot3MauType 44 }
+
+     dot3MauType100BaseBX10U OBJECT-IDENTITY
+       STATUS      current
+       DESCRIPTION "One single-mode fiber ONU, long wavelength, 10km"
+       REFERENCE   "[IEEE802.3], Section 58"
+       ::= { dot3MauType 45 }
+
+     dot3MauType100BaseLX10 OBJECT-IDENTITY
+       STATUS      current
+       DESCRIPTION "Two single-mode fibers, long wavelength, 10km"
+       REFERENCE   "[IEEE802.3], Section 58"
+       ::= { dot3MauType 46 }
+
+     dot3MauType1000BaseBX10D OBJECT-IDENTITY
+       STATUS      current
+       DESCRIPTION "One single-mode fiber OLT, long wavelength, 10km"
+       REFERENCE   "[IEEE802.3], Section 59"
+       ::= { dot3MauType 47 }
+
+     dot3MauType1000BaseBX10U OBJECT-IDENTITY
+       STATUS      current
+       DESCRIPTION "One single-mode fiber ONU, long wavelength, 10km"
+       REFERENCE   "[IEEE802.3], Section 59"
+       ::= { dot3MauType 48 }
+
+     dot3MauType1000BaseLX10 OBJECT-IDENTITY
+       STATUS      current
+       DESCRIPTION "Two sigle-mode fiber, long wavelength, 10km"
+       REFERENCE   "[IEEE802.3], Section 59"
+       ::= { dot3MauType 49 }
+
+     dot3MauType1000BasePX10D OBJECT-IDENTITY
+       STATUS      current
+       DESCRIPTION "One single-mode fiber EPON OLT, 10km"
+       REFERENCE   "[IEEE802.3], Section 60"
+       ::= { dot3MauType 50 }
+
+     dot3MauType1000BasePX10U OBJECT-IDENTITY
+       STATUS      current
+       DESCRIPTION "One single-mode fiber EPON ONU, 10km"
+       REFERENCE   "[IEEE802.3], Section 60"
+       ::= { dot3MauType 51 }
+
+     dot3MauType1000BasePX20D OBJECT-IDENTITY
+       STATUS      current
+       DESCRIPTION "One single-mode fiber EPON OLT, 20km"
+       REFERENCE   "[IEEE802.3], Section 60"
+       ::= { dot3MauType 52 }
+
+     dot3MauType1000BasePX20U OBJECT-IDENTITY
+       STATUS      current
+       DESCRIPTION "One single-mode fiber EPON ONU, 20km"
+       REFERENCE   "[IEEE802.3], Section 60"
+       ::= { dot3MauType 53 }
+
+END
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/Mibs/IANA/IANA-PRINTER-MIB
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/Mibs/IANA/IANA-PRINTER-MIB	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/Mibs/IANA/IANA-PRINTER-MIB	(revision 457)
@@ -0,0 +1,1319 @@
+IANA-PRINTER-MIB DEFINITIONS ::= BEGIN
+ -- http://www.iana.org/assignments/ianaprinter-mib
+
+IMPORTS
+    MODULE-IDENTITY,
+        mib-2
+            FROM SNMPv2-SMI                              -- [RFC2578]
+    TEXTUAL-CONVENTION
+            FROM SNMPv2-TC;                              -- [RFC2579]
+
+ianaPrinterMIB MODULE-IDENTITY
+    LAST-UPDATED  "200509140000Z" -- September 14, 2005
+
+    ORGANIZATION  "IANA"
+    CONTACT-INFO  "Internet Assigned Numbers Authority
+                  Postal: ICANN
+                          4676 Admiralty Way, Suite 330
+                          Marina del Rey, CA 90292
+
+                  Tel:    +1 310 823 9358
+                  E-Mail: iana&iana.org"
+
+    DESCRIPTION   "This MIB module defines a set of printing-related
+                  TEXTUAL-CONVENTIONs for use in Printer MIB (RFC 3805),
+                  Finisher MIB (RFC 3806), and other MIBs which need to
+                  specify printing mechanism details.
+
+                  Any additions or changes to the contents of this MIB
+                  module require either publication of an RFC, or
+                  Designated Expert Review as defined in RFC 2434,
+                  Guidelines for Writing an IANA Considerations Section
+                  in RFCs.  The Designated Expert will be selected by
+                  the IESG Area Director(s) of the Applications Area.
+
+                  Copyright (C) The Internet Society (2004). The
+                  initial version of this MIB module was published
+                  in RFC 3805.  For full legal notices see the RFC
+                  itself or see:
+                  http://www.ietf.org/copyrights/ianamib.html"
+
+    REVISION      "200509140000Z"  -- September 14, 2005
+    DESCRIPTION   "Updates to include missing 'unknown' values
+	               for PrtCoverStatusTC, PrtChannelTypeTC, 
+                   PrtAlertGroupTC and removal of comment for
+                   for PrtAlertGroupTC."
+
+    REVISION      "200406020000Z"  -- June 2, 2004
+    DESCRIPTION   "Original version, published in coordination
+                  with Printer MIB (RFC 3805)."
+    ::= { mib-2 109 }
+
+--
+-- Generic TEXTUAL-CONVENTIONs
+--
+
+PrtCoverStatusTC ::= TEXTUAL-CONVENTION
+    -- This TC was extracted from prtCoverStatus in RFC 1759.
+    STATUS    current
+    DESCRIPTION
+        "Values for encoding the state of a particular cover or
+        access panel on the printer case or enclosure."
+    SYNTAX    INTEGER {
+                  other(1),
+                  unknown(2),
+                  coverOpen(3),
+                  coverClosed(4),
+                  interlockOpen(5),
+                  interlockClosed(6)
+
+                  }
+
+--
+-- General Group TEXTUAL-CONVENTIONs
+--
+
+PrtGeneralResetTC ::= TEXTUAL-CONVENTION
+    -- This TC was extracted from prtGeneralReset in RFC 1759.
+    STATUS    current
+    DESCRIPTION
+        "Values for reading and writing the prtGeneralReset object.
+
+        If a device does not have NVRAM, the device shall none the
+        less respond to a SET with the value resetToNVRAM(5) with a
+        sort of warm reset that resets the device to implementation-
+        defined state that is preferably under control of the system
+        administrator by some means outside the scope of the Printer
+        MIB specification."
+
+    SYNTAX    INTEGER {
+                  notResetting(3),
+                  powerCycleReset(4), -- Cold Start
+                  resetToNVRAM(5), -- Warm Start
+                  resetToFactoryDefaults(6) -- Reset contents of
+                                            -- NVRAM to factory
+                                            -- defaults
+                  }
+--
+-- Channel Group TEXTUAL-CONVENTIONs
+--
+
+PrtChannelTypeTC ::= TEXTUAL-CONVENTION
+    -- This TC was extracted from prtChannelType in RFC 1759.
+    STATUS    current
+    DESCRIPTION
+        "This enumeration indicates the type of channel that is
+        receiving jobs."
+    SYNTAX    INTEGER {
+                  other(1),
+                  unknown(2),
+                  chSerialPort(3),
+                  chParallelPort(4),
+                  chIEEE1284Port(5),
+                  chSCSIPort(6),
+                  chAppleTalkPAP(7),
+                      -- AppleTalk Printer
+                      -- Access Protocol (PAP)
+                      --
+                      -- prtChannelInformation entry:
+
+                      --
+                      -- Printer Name
+                      --   Keyword:      Name
+                      --   Syntax:       Name
+                      --   Status:       Optional
+                      --   Multiplicity: Single
+                      --   Description:  The name of the printer
+                      --     within the AppleTalk naming scope
+                  chLPDServer(8),
+                      -- prtChannelInformation entry:
+                      --
+                      -- Printer queue name
+                      --   Keyword:      Queue
+                      --   Syntax:       Name
+                      --   Status:       Mandatory
+                      --   Multiplicity: Single
+                      --   Description: queue name as
+                      --     defined in [RFC1179].
+                  chNetwareRPrinter(9),
+                      -- Novell, Inc.
+                      -- For each entry of this type, the
+                      -- prtChannelInformation must have a pair of
+                      -- keywords.  For Netware 3.x channels this must
+                      -- be a (PServer, Printer) pair.  For Netware
+                      -- 4.x channels and for IntranetWare channels
+                      -- this must be a (NDSTree, NDSPrinter) pair.
+                      --
+                      -- prtChannelInformation entries:
+
+                      -- Print Server Name
+                      --   Keyword:      PServer
+                      --   Syntax:       Name
+                      --   Status:       Mandatory
+                      --   Multiplicity: Single
+                      --   Description:  The Pserver's SAP name
+                      --
+                      -- Printer Number
+                      --   Keyword:      Printer
+                      --   Syntax:       Integer
+                      --   Status:       Mandatory
+                      --   Multiplicity: Single
+                      --   Description:  The printer number
+                      --
+                      -- NDSTree
+                      --   Keyword:      NDSTree
+                      --   Syntax:       Name
+                      --   Multiplicity: Single
+                      --   Description:  The tree's SAP name
+
+                      --
+                      -- NDS Printer object
+                      --   Keyword:      NDSPrinter
+                      --   Syntax:       Text (Unicode)
+                      --   Status:       Mandatory
+                      --   Multiplicity: Single
+                      --   Description:  The fully qualified
+                      --                 name of the Printer
+                      --
+                      -- In the Netware 3.x environment, the
+                      -- client checks the Bindery object
+                      -- representing the named PServer.  The
+                      -- client then checks for queues which
+                      -- are associated with the numbered
+                      -- printer.  In the 4.x and IntraNetware
+                      -- environment, the client looks up the
+                      -- queues which are associated with the
+                      -- NDS Printer Object in the named Tree.
+                      -- Depending on client access rights to
+                      -- those queues, the client submits jobs
+                      -- to the appropriate queue.
+                  chNetwarePServer(10),
+                      -- Novell,Inc.
+                      -- For each entry of this type, the
+                      -- prtChannelInformation must have a pair
+                      -- of keywords.  For Netware 3.x channels
+                      -- this must be a (Server, PServer) pair.
+                      -- For Netware 4.x and IntranetWare
+                      -- channels, this must be a
+                      -- (NDSTree, NDSPServer) pair.
+                      --
+                      -- prtChannelInformation entries:
+                      --
+                      -- Server Name
+                      --   Keyword:      Server
+                      --   Syntax:       Name
+                      --   Status:       Mandatory
+                      --   Multiplicity: Single
+                      --   Description:  The SAP name of the
+                      --   server for which the PServer is defined.
+                      --
+                      -- PServer
+                      --   Keyword:      PServer
+                      --   Syntax:       Name
+                      --   Status:       Mandatory
+                      --   Multiplicity: Single
+                      --   Description:  The bindery name of
+                      --                 the PServer
+
+                      --
+                      -- NDS Tree
+                      --   Keyword:      NDSTree
+                      --   Syntax:       Name
+                      --   Status:       Mandatory
+                      --   Multiplicity: Single
+                      --   Description:  The NDS Tree name
+                      --
+                      -- PServer
+                      --   Keyword:      NDSPServer
+                      --   Syntax:       Text (Unicode)
+                      --   Status:       Mandatory
+                      --   Multiplicity: Single
+                      --   Description:  The fully qualified
+                      --     name of the PServer object in the tree.
+                      --
+                      -- In the 3.x environment, the client
+                      -- checks the bindery object
+                      -- representing the named PServer on the
+                      -- named Server.  In the 4.x and
+                      -- IntranetWare environment,
+                      -- the client checks the NDS object
+                      -- representing the named PServer in the
+                      -- named Tree.  In either case, the
+                      -- client then checks for all queues
+                      -- associated with the Pserver object.
+                      -- Depending on client access rights
+                      -- to those queues, the client submits
+                      -- jobs to the appropriate queue.
+                  chPort9100(11),
+                      -- DEPRECATED
+                      -- (see chPortTCP - 37; chBidirPortTCP - 38)
+                  chAppSocket(12),
+                      -- A bi-directional, LPD-like, protocol using
+                      -- 9101 for control and 9100 for data.
+                      -- Adobe Systems, Inc.
+                  chFTP(13),         -- [RFC959]
+                  chTFTP(14),        -- [RFC1350]
+                  chDLCLLCPort(15),
+                  chIBM3270(16),     -- IBM Coax
+                  chIBM5250(17),     -- IBM Twinax
+                  chFax(18),
+                  chIEEE1394(19),
+                  chTransport1(20),
+                      -- TCP port 35, for reserved TCP port list see
+                      -- [RFC3232].  This RFC should also be
+                      -- referenced for other channel
+                      -- enumerations utilizing TCP port
+
+                      -- numbers 0 through 1024.
+                  chCPAP(21),      -- TCP port 170
+                      -- Digital Equipment Corp.
+                  chDCERemoteProcCall(22), -- OSF
+                      -- DEPRECATED
+                  chONCRemoteProcCall(23), -- SUN Microsystems
+                      -- DEPRECATED
+                  chOLE(24),         -- Microsoft
+                      -- DEPRECATED
+                  chNamedPipe(25),
+                  chPCPrint(26),   -- Banyan
+                  chServerMessageBlock(27),
+                      -- File/Print sharing protocol used by
+                      -- various network operating systems
+                      -- from IBM 3Com, Microsoft and others
+                      --
+                      -- prtChannelInformation entry:
+                      --
+                      -- Service Name
+                      --   Keyword:      Name
+                      --   Syntax:       Name
+                      --   Status:       Optional
+                      --   Multiplicity: Single
+                      --   Description:  The service name of
+                      --                 the printer
+                  chDPMF(28),   -- IBM Infoprint
+                  chDLLAPI(29), -- Microsoft
+                      -- DEPRECATED
+                  chVxDAPI(30), -- Microsoft
+                      -- DEPRECATED
+                  chSystemObjectManager(31), -- IBM
+                  chDECLAT(32),
+                      -- Digital Equipment Corp.
+                      --
+                      -- prtChannelInformation entries:
+                      --
+                      -- Port Name
+                      --   Keyword:      Port
+                      --   Syntax:       Name
+                      --   Status:       Conditionally
+                      --                 Mandatory
+                      --                 (see note below)
+                      --   Multiplicity: Single
+                      --   Description:  LAT port name
+                      --
+                      -- Service Name
+                      --   Keyword:      Service
+                      --   Syntax:       Name
+
+                      --   Status:       Conditionally
+                      --                 Mandatory
+                      --   Multiplicity: Single
+                      --   Description:  LAT service name
+                      --
+                      -- The LAT channel may be
+                      -- identified by either a port or
+                      -- service, so either a
+                      -- Port or Service entry must be
+                      -- specified, but not both.
+                  chNPAP(33),
+                  chUSB(34), -- Not in RFC 1759
+                             -- Universal Serial Bus
+                  chIRDA(35), -- Not in RFC 1759
+                              -- Infrared Data Assoc. Prot.
+                  chPrintXChange(36),  -- Not in RFC 1759
+                                       -- PrintXChange Protocol
+                  chPortTCP(37),  -- Not in RFC 1759
+                      -- A unidirectional "raw" TCP
+                      -- channel that uses an administratively
+                      -- assigned TCP port address.
+                      --
+                      -- prtChannelInformation entry:
+                      --
+                      -- Port Number
+                      --   Keyword:      Port
+                      --   Syntax:       decimal number
+                      --   Status:       Mandatory
+                      --   Multiplicity: Single
+                      --   Description:  TCP port number
+                  chBidirPortTCP(38),  -- Not in RFC 1759
+                      -- A bi-directional version of chPortTCP
+                      --
+                      -- prtChannelInformation entries:
+                      -- (See chPortTCP)
+                  chUNPP(39),  -- Not in RFC 1759
+                      -- Universal Network Printing
+                      -- Protocol(UNPP). A bi-directional,
+                      -- multiport network printing
+                      -- application protocol available on
+                      -- multiple transport protocols.
+                      -- Underscore, Inc.
+                      -- Contact: info&underscore.com
+                  chAppleTalkADSP(40),  -- Not in RFC 1759
+                      -- AppleTalk Data Stream Protocol.
+                      -- ADSP is part of the AppleTalk
+                      -- suite of protocols.
+                      -- It is a symmetric, connection-
+
+                      -- oriented protocol that makes
+                      -- possible the establishment
+                      -- and maintenance of full-duplex
+                      -- streams of data bytes between
+                      -- two sockets in an AppleTalk
+                      -- internet.
+                      -- See [APPLEMAC].
+                  chPortSPX(41),  -- Not in RFC 1759
+                      -- Sequenced Packet Exchange (SPX)
+                      -- socket.
+                      -- Novell, Inc. Similar to TCP, a
+                      -- bi-directional data pipe using
+                      -- Novell SPX as a transport.
+                      --
+                      -- prtChannelInformation entries:
+                      --
+                      -- Network Number
+                      --   Keyword:      Net
+                      --   Syntax:       HexString
+                      --   Status:       Mandatory
+                      --   Multiplicity: Single
+                      --   Description:  The network number
+                      --
+                      -- Node Number
+                      --   Keyword:      Node
+                      --   Syntax:       HexString
+                      --   Status:       Mandatory
+                      --   Multiplicity: Single
+                      --   Description:  The node number
+                      --
+                      -- Socket Number
+                      --   Keyword:      Socket
+                      --   Syntax:       HexString
+                      --   Status:       Mandatory
+                      --   Multiplicity: Single
+                      --   Description:  The SPX socket number
+                      --
+                      -- There must be exactly one "Net" and
+                      -- one "Node" and one "Socket" entry.  A
+                      -- HexString is a binary value
+                      -- represented as a string of
+                      -- ASCII characters using hexadecimal
+                      -- notation.
+                  chPortHTTP(42),  -- Not in RFC 1759
+                      -- Hypertext Transfer Protocol. See [RFC1945]
+                      -- and [RFC2616].
+                  chNDPS(43),  -- Not in RFC 1759
+                      -- Novell, Inc.
+
+                      --
+                      -- prtChannelInformation entry:
+                      --
+                      -- Printer Agent Name
+                      --   Keyword:      PA
+                      --   Syntax:       Name
+                      --   Status:       Mandatory
+                      --   Multiplicity: Single
+                      --   Description:  The NDPS Printer
+                      --                 Agent Name
+                  chIPP(44),  -- Not in RFC 1759
+                      -- Internet Printing Protocol (IPP),
+                      -- (IPP/1.1 - see [RFC2910] and [RFC2911])
+                      -- also applies to all future versions of IPP.
+                      --
+                      -- IPP Printer URI
+                      --   Keyword:      URI
+                      --   Syntax:       URI (Unicode UTF-8 per
+                      --                 [RFC2396])
+                      --   Status:       Mandatory
+                      --   Multiplicity: Single
+                      --   Default:      not applicable
+                      --   Description:  URI of this IPP Printer
+                      --     within Internet naming scope.  Unicode
+                      --     UTF-8 [RFC3629] string with
+                      --     hexadecimal escapes for any non-ASCII
+                      --     characters (per [RFC2396]).
+                      --   Conformance: An IPP Printer shall list all
+                      --     IPP URI it supports (one per IPP Channel
+                      --     entry).  If a URI contains the 'http:'
+                      --     scheme it must have an explicit port.
+                      --   See: [RFC3629], [RFC2396], [RFC2910],
+                     --     [RFC2911].
+                      --
+                      -- IPP Printer Client Authentication
+                      --   Keyword:      Auth
+                      --   Syntax:       Keyword
+                      --   Status:       Optional
+                      --   Multiplicity: Single
+                      --   Default:      'none'
+                      --   Description:  A client authentication
+                      --     mechanism supported for this IPP Printer
+                      --     URI:
+                      --       'none'
+                      --         no client authentication mechanism
+                      --       'requesting-user-name'
+                      --         authenticated user in 'requesting-
+                      --         user-name'
+
+                      --       'basic'
+                      --         authenticated user via HTTP Basic
+                      --         mechanism
+                      --       'digest'
+                      --         authenticated user via HTTP Digest
+                      --         mechanism
+                      --       'certificate'
+                      --         authenticated user via certificate
+                      --         mechanism
+                      --   Conformance: An IPP Printer should list
+                      --     all IPP client authentication mechanisms
+                      --     it supports (one per IPP Channel entry).
+                      --     See: [RFC2911] and [RFC2910].
+                      --
+                      -- IPP Printer Security
+                      --   Keyword:      Security
+                      --   Syntax:       Keyword
+                      --   Status:       Optional
+                      --   Multiplicity: Single
+                      --   Default:      'none'
+                      --   Description:  A security mechanism
+                      --     supported for this IPP Printer URI:
+                      --     'none'
+                      --       no security mechanism
+                      --     'ssl3'
+                      --       SSL3 secure communications channel
+                      --       protocol
+                      --     'tls'
+                      --       TLS secure communications channel
+                      --       protocol
+                      --   Conformance: An IPP Printer should list
+                      --     all IPP security mechanisms it supports
+                      --     (one per IPP Channel entry).
+                      --   See: [RFC2246], [RFC2911].
+                      --
+                      -- IPP Printer Protocol Version
+                      --   Keyword:      Version
+                      --   Syntax:       Keyword
+                      --   Status:       Optional
+                      --   Multiplicity: Multiple
+                      --   Default:      '1.1'
+                      --   Description:  All of the IPP protocol
+                      --     versions (major.minor) supported for
+                      --     this IPP Printer URI:
+                      --     '1.0'
+                      --       IPP/1.0 conforming Printer
+                      --     '1.1'
+                      --       IPP/1.1 conforming Printer
+
+                      --   Conformance:  An IPP Printer should list
+                      --     all IPP versions it supports (all listed
+                      --     in each IPP Channel entry).  An IPP
+                      --     Client should select the highest
+                      --     numbered version the IPP Client supports
+                      --     for use in all IPP Requests (for optimum
+                      --     interworking).
+                      --   See: [RFC2911].
+                  chSMTP(45)
+                      -- Print Job submission via Simple Mail
+                      -- Transfer Protocol (SMTP) - see [RFC2821]
+                      --
+                      -- prtChannelInformation entry:
+                      --
+                      --   Keyword:      Mailto
+                      --   Syntax:       Name
+                      --   Status:       Mandatory
+                      --   Multiplicity: Single
+                      --   Default:      not applicable
+                      --   Description:  The SMTP URL of the printer.
+}
+
+--
+-- Interpreter Group TEXTUAL-CONVENTIONs
+--
+
+PrtInterpreterLangFamilyTC ::= TEXTUAL-CONVENTION
+    -- This TC was extracted from prtInterpreterLangFamily in RFC 1759.
+    STATUS    current
+    DESCRIPTION
+        "This enumeration indicates the type of interpreter that is
+        receiving jobs."
+    SYNTAX    INTEGER {
+        other(1),
+        unknown(2),          -- Not in RFC 1759
+        langPCL(3),          -- PCL.  Starting with PCL version 5,
+                             -- HP-GL/2 is included as part of the
+                             -- PCL language.
+                             -- PCL and HP-GL/2 are registered
+                             -- trademarks of Hewlett-Packard
+                             -- Company.
+        langHPGL(4),         -- Hewlett-Packard Graphics Language.
+                             -- HP-GL is a registered trademark of
+                             -- Hewlett-Packard Company.
+        langPJL(5),          -- Peripheral Job Language.  Appears in
+                             -- the data stream between data intended
+                             -- for a page description language.
+                             -- Hewlett-Packard Co.
+
+        langPS(6),           -- PostScript (tm) Language
+                             -- Postscript - a trademark of Adobe
+                             -- Systems Incorporated which may be
+                             -- registered in certain jurisdictions
+        langIPDS(7),         -- Intelligent Printer Data Stream
+                             -- Bi-directional print data stream for
+                             -- documents consisting of data objects
+                             -- (text, image, graphics, bar codes),
+                             -- resources (fonts, overlays) and page,
+                             -- form and finishing instructions.
+                             -- Facilitates system level device
+                             -- control, document tracking and error
+                             -- recovery throughout the print
+                             -- process.
+                             -- IBM Corporation.
+        langPPDS(8),         -- IBM Personal Printer Data Stream.
+                             -- Originally called IBM ASCII, the name
+                             -- was changed to PPDS when the Laser
+                             -- Printer was introduced in 1989.
+                             -- Lexmark International, Inc.
+        langEscapeP(9),      -- Epson Corp.
+        langEpson(10),
+        langDDIF(11),        -- Digital Document Interchange Format
+                             -- Digital Equipment Corp., Maynard MA
+        langInterpress(12),
+                             -- Xerox Corp.
+        langISO6429(13),     -- ISO 6429.  Control functions for
+                             -- Coded Character Sets (has ASCII
+                             -- control characters, plus additional
+                             -- controls for
+                             -- character imaging devices.)
+        langLineData(14),    -- line-data:  Lines of data as
+                             -- separate ASCII or EBCDIC records
+                             -- and containing no control functions
+                             -- (no CR, LF, HT, FF, etc.)
+                             -- For use with traditional line
+                             -- printers.  May use CR and/or LF to
+                             -- delimit lines, instead of records.
+                             -- See ISO 10175 Document Printing
+                             -- Application (DPA) [ISO10175].
+        langMODCA(15),       -- Mixed Object Document Content
+                             -- Architecture
+                             -- Definitions that allow the
+                             -- composition, interchange, and
+                             -- presentation of final form
+                             -- documents as a collection of data
+                             -- objects (text, image, graphics, bar
+                             -- codes), resources (fonts, overlays)
+
+                             -- and page, form and finishing
+                             -- instructions.
+                             -- IBM Corporation.
+        langREGIS(16),       -- Remote Graphics Instruction Set,
+                             -- Digital Equipment Corp., Maynard MA
+        langSCS(17),         -- SNA Character String
+                             -- Bi-directional print data stream for
+                             -- SNA LU-1 mode of communication.
+                             -- IBM
+        langSPDL(18),        -- ISO 10180 Standard Page Description
+                             -- Language
+                             -- ISO Standard
+        langTEK4014(19),     -- Tektronix Corp.
+        langPDS(20),
+        langIGP(21),         -- Printronix Corp.
+        langCodeV(22),       -- Magnum Code-V, Image and printer
+                             -- control language used to control
+                             -- impact/dot-matrix printers.
+                             -- QMS, Inc., Mobile AL
+        langDSCDSE(23),      -- DSC-DSE:  Data Stream Compatible and
+                             -- Emulation Bi-directional print data
+                             -- stream for non-SNA (DSC) and SNA LU-3
+                             -- 3270 controller (DSE) communications
+                             -- IBM
+        langWPS(24),         -- Windows Printing System, Resource
+                             -- based command/data stream used by
+                             -- Microsoft At Work Peripherals.
+                             -- Developed by the Microsoft
+                             -- Corporation.
+        langLN03(25),        -- Early DEC-PPL3, Digital Equipment
+                             -- Corp.
+        langCCITT(26),
+        langQUIC(27),        -- QUIC (Quality Information Code), Page
+                             -- Description Language for laser
+                             -- printers.  Included graphics, printer
+                             -- control capability and emulation of
+                             -- other well-known printer.
+                             -- QMS, Inc.
+        langCPAP(28),        -- Common Printer Access Protocol
+                             -- Digital Equipment Corp.
+        langDecPPL(29),      -- Digital ANSI-Compliant Printing
+                             -- Protocol
+                             -- (DEC-PPL)
+                             -- Digital Equipment Corp.
+        langSimpleText(30),
+                             -- simple-text:  character coded data,
+                             -- including NUL, CR , LF, HT, and FF
+                             -- control characters.  See ISO 10175
+
+                             -- Document Printing Application (DPA)
+                             -- [ISO10175].
+        langNPAP(31),        -- Network Printer Alliance Protocol
+                             -- (NPAP).  This protocol has been
+                             -- superseded by the IEEE 1284.1 TIPSI
+                             -- Std (ref. LangTIPSI(49)).
+        langDOC(32),         -- Document Option Commands, Appears in
+                             -- the data stream between data
+                             -- intended for a page description.
+                             -- QMS, Inc.
+        langimPress(33),     -- imPRESS, Page description language
+                             -- originally developed for the
+                             -- ImageServer product line. A binary
+                             -- language providing representations
+                             -- of text, simple graphics, and some
+                             -- large forms (simple
+                             -- bit-map and CCITT group 3/4
+                             -- encoded).The
+                             -- language was intended to be sent over
+                             -- an 8-bit channel and supported early
+                             -- document preparation languages (e.g.,
+                             -- TeX and TROFF).
+                             -- QMS, Inc.
+        langPinwriter(34),
+                             -- 24 wire dot matrix printer  for
+                             -- USA, Europe, and Asia except
+                             -- Japan.
+                             -- More widely used in Germany, and
+                             -- some Asian countries than in US.
+                             -- NEC
+        langNPDL(35),        -- Page printer  for Japanese market.
+                             -- NEC
+        langNEC201PL(36),    -- Serial printer language used in
+                             -- the Japanese market.
+                             -- NEC
+        langAutomatic(37),
+                             -- Automatic PDL sensing.  Automatic
+                             -- sensing of the interpreter
+                             -- language family by the printer
+                             -- examining the document content.
+                             -- Which actual interpreter language
+                             -- families are sensed depends on
+                             -- the printer implementation.
+        langPages(38),       -- Page printer Advanced Graphic
+                             -- Escape Set
+                             -- IBM Japan
+        langLIPS(39),        -- LBP Image Processing System
+        langTIFF(40),        -- Tagged Image File Format (Aldus)
+
+        langDiagnostic(41),
+                             -- A hex dump of the input to the
+                             -- interpreter
+        langPSPrinter(42),
+                             -- The PostScript Language used for
+                             -- control (with any PDLs)
+                             -- Adobe Systems Incorporated
+        langCaPSL(43),       -- Canon Print Systems Language
+        langEXCL(44),        -- Extended Command Language
+                             -- Talaris Systems Inc.
+        langLCDS(45),        -- Line Conditioned Data Stream
+                             -- Xerox Corporation
+        langXES(46),         -- Xerox Escape Sequences
+                             -- Xerox Corporation
+        langPCLXL(47),       -- Not in RFC 1759
+                             -- Printer Control Language. Extended
+                             -- language features for printing, and
+                             -- printer control.
+                             -- Hewlett-Packard Co.
+        langART(48),         -- Not in RFC 1759
+                             -- Advanced Rendering Tools (ART).
+                             -- Page Description language
+                             -- originally developed for the Laser
+                             -- Press printers.
+                             -- Technical reference manual: "ART IV
+                             -- Reference Manual", No F33M.
+                             -- Fuji Xerox Co., Ltd.
+        langTIPSI(49),       -- Not in RFC 1759
+                             -- Transport Independent Printer
+                             -- System Interface (ref. IEEE Std.
+                             -- 1284.1)
+        langPrescribe(50),   -- Not in RFC 1759
+                             -- Page description and printer
+                             -- control language. It can be
+                             -- described with ordinary ASCII
+                             -- Technical reference manual:
+                             -- "PRESCRIBE II Programming Manual"
+        langLinePrinter(51), -- Not in RFC 1759
+                             -- A simple-text character stream which
+                             -- supports the control codes LF, VT,
+                             -- FF, and plus Centronics or
+                             -- Dataproducts Vertical Format Unit
+                             -- (VFU) language is commonly used on
+                             -- many older model line and matrix
+                             -- printers.
+        langIDP(52),         -- Not in RFC 1759
+                             -- Imaging Device Protocol
+                             -- Apple Computer.
+
+        langXJCL(53),        -- Not in RFC 1759
+                             -- Xerox Job Control Language (JCL).
+                             -- A Job Control language originally
+                             -- developed for the LaserPress printers
+                             -- and is capable of switching PDLs.
+                             -- Technical reference manual:
+                             -- "ART IV Reference Manual", No F33M.
+                             -- Fuji Xerox Co., Ltd.
+        langPDF(54),         -- Not in RFC 1759
+                             -- Adobe Portable Document Format
+                             -- Adobe Systems, Inc.
+        langRPDL(55),        -- Not in RFC 1759
+                             -- Ricoh Page Description Language for
+                             -- printers.
+                             -- Technical manual "RPDL command
+                             -- reference" No.307029
+                             -- RICOH, Co. LTD
+        langIntermecIPL(56), -- Not in RFC 1759
+                             -- Intermec Printer Language for label
+                             -- printers.
+                             -- Technical Manual: "IPL Programmers
+                             -- Reference Manual"
+                             -- Intermec Corporation
+        langUBIFingerprint(57),  -- Not in RFC 1759
+                             -- An intelligent basic-like programming
+                             -- language for label printers.
+                             -- Reference Manual: "UBI Fingerprint
+                             -- 7.1", No. 1-960434-00
+                             -- United Barcode Industries
+        langUBIDirectProtocol(58),  -- Not in RFC 1759
+                             -- An intelligent control language for
+                             -- label printers.
+                             -- Programmers guide: " UBI Direct
+                             -- Protocol", No. 1-960419-00
+                             -- United Barcode Industries
+        langFujitsu(59),     -- Not in RFC 1759
+                             -- Fujitsu Printer Language
+                             -- Reference Manual:
+                             -- "FM Printer Sequence" No. 80HP-0770
+                             -- FUJITSU LIMITED
+        langCGM(60),         -- Not in RFC 1759
+                             -- Computer Graphics Metafile
+                             -- MIME type 'image/cgm'
+        langJPEG(61),        -- Not in RFC 1759
+                             -- Joint Photographic Experts Group
+                             -- MIME type 'image/jpeg'
+        langCALS1(62),       -- Not in RFC 1759
+                             -- US DOD CALS1 (see MIL-STD-1840)
+
+                             -- MIME type 'application/cals-1840'
+        langCALS2(63),       -- Not in RFC 1759
+                             -- US DOD CALS2 (see MIL-STD-1840)
+                             -- MIME type 'application/cals-1840'
+        langNIRS(64),        -- Not in RFC 1759
+                             -- US DOD NIRS (see MIL-STD-1840)
+                             -- MIME type 'application/cals-1840'
+        langC4(65)           -- Not in RFC 1759
+                             -- US DOD C4 (see MIL-STD-1840)
+                             -- MIME type 'application/cals-1840'
+}
+
+--
+-- Input/Output Group TEXTUAL-CONVENTIONs
+--
+
+PrtInputTypeTC ::= TEXTUAL-CONVENTION
+    -- This TC was extracted from prtInputType in RFC 1759.
+    STATUS    current
+    DESCRIPTION
+        "The type of technology (discriminated primarily according to
+        feeder mechanism type) employed by a specific component or
+        components."
+    SYNTAX    INTEGER {
+                  other(1),
+                  unknown(2),
+                  sheetFeedAutoRemovableTray(3),
+                  sheetFeedAutoNonRemovableTray(4),
+                  sheetFeedManual(5),
+                  continuousRoll(6),
+                  continuousFanFold(7)
+                  }
+
+PrtOutputTypeTC ::= TEXTUAL-CONVENTION
+    -- This TC was extracted from prtOutputType in RFC 1759.
+    STATUS    current
+    DESCRIPTION
+        "The Type of technology supported by this output subunit."
+    SYNTAX    INTEGER {
+                  other(1),
+                  unknown(2),
+                  removableBin(3),
+                  unRemovableBin(4),
+                  continuousRollDevice(5),
+                  mailBox(6),
+                  continuousFanFold(7)
+                  }
+
+--
+-- Marker Group TEXTUAL-CONVENTIONs
+--
+
+PrtMarkerMarkTechTC ::= TEXTUAL-CONVENTION
+    -- This TC was extracted from prtMarkerMarkTech in RFC 1759.
+    STATUS    current
+    DESCRIPTION
+        "The type of marking technology used for this marking
+        subunit."
+    SYNTAX    INTEGER {
+                  other(1),
+                  unknown(2),
+                  electrophotographicLED(3),
+                  electrophotographicLaser(4),
+                  electrophotographicOther(5),
+                  impactMovingHeadDotMatrix9pin(6),
+                  impactMovingHeadDotMatrix24pin(7),
+                  impactMovingHeadDotMatrixOther(8),
+                  impactMovingHeadFullyFormed(9),
+                  impactBand(10),
+                  impactOther(11),
+                  inkjetAqueous(12),
+                  inkjetSolid(13),
+                  inkjetOther(14),
+                  pen(15),
+                  thermalTransfer(16),
+                  thermalSensitive(17),
+                  thermalDiffusion(18),
+                  thermalOther(19),
+                  electroerosion(20),
+                  electrostatic(21),
+                  photographicMicrofiche(22),
+                  photographicImagesetter(23),
+                  photographicOther(24),
+                  ionDeposition(25),
+                  eBeam(26),
+                  typesetter(27)
+                  }
+
+PrtMarkerSuppliesTypeTC ::= TEXTUAL-CONVENTION
+    -- This TC was extracted from prtMarkerSuppliesType in RFC 1759.
+    STATUS    current
+    DESCRIPTION
+        "The type of this supply."
+    SYNTAX    INTEGER {
+                  other(1),
+                  unknown(2),
+
+                -- Values for Printer MIB
+                  toner(3),
+                  wasteToner(4),
+                  ink(5),
+                  inkCartridge(6),
+                  inkRibbon(7),
+                  wasteInk(8),
+                  opc(9),               -- photo conductor
+                  developer(10),
+                  fuserOil(11),
+                  solidWax(12),
+                  ribbonWax(13),
+                  wasteWax(14),
+                  fuser(15),            -- Not in RFC 1759
+                  coronaWire(16),       -- Not in RFC 1759
+                  fuserOilWick(17),     -- Not in RFC 1759
+                  cleanerUnit(18),      -- Not in RFC 1759
+                  fuserCleaningPad(19), -- Not in RFC 1759
+                  transferUnit(20),     -- Not in RFC 1759
+                  tonerCartridge(21),   -- Not in RFC 1759
+                  fuserOiler(22),       -- Not in RFC 1759
+                -- End of values for Printer MIB
+                -- Values for Finisher MIB
+                  water(23),            -- Not in RFC 1759
+                  wasteWater(24),       -- Not in RFC 1759
+                  glueWaterAdditive(25),-- Not in RFC 1759
+                  wastePaper(26),       -- Not in RFC 1759
+                  bindingSupply(27),    -- Not in RFC 1759
+                  bandingSupply(28),    -- Not in RFC 1759
+                  stitchingWire(29),    -- Not in RFC 1759
+                  shrinkWrap(30),       -- Not in RFC 1759
+                  paperWrap(31),        -- Not in RFC 1759
+                  staples(32),          -- Not in RFC 1759
+                  inserts(33),          -- Not in RFC 1759
+                  covers(34)            -- Not in RFC 1759
+                -- End of values for Finisher MIB
+                  }
+
+--
+-- Media Path TEXTUAL-CONVENTIONs
+--
+
+PrtMediaPathTypeTC ::= TEXTUAL-CONVENTION
+    -- This TC was extracted from prtMediaPathType in RFC 1759.
+    STATUS    current
+    DESCRIPTION
+        "The type of the media path for this media path."
+    SYNTAX    INTEGER {
+
+                  other(1),
+                  unknown(2),
+                  longEdgeBindingDuplex(3),
+                  shortEdgeBindingDuplex(4),
+                  simplex(5)
+                  }
+
+--
+-- Console Group TEXTUAL-CONVENTIONs
+--
+
+PrtConsoleColorTC ::= TEXTUAL-CONVENTION
+    -- This TC was extracted from prtConsoleColor in RFC 1759.
+    STATUS     current
+    DESCRIPTION
+        "The color of this light."
+    SYNTAX    INTEGER {
+                  other(1),
+                  unknown(2),
+                  white(3),
+                  red(4),
+                  green(5),
+                  blue(6),
+                  cyan(7),
+                  magenta(8),
+                  yellow(9),
+                  orange(10)        -- Not in RFC 1759
+                  }
+
+PrtConsoleDisableTC ::= TEXTUAL-CONVENTION
+    -- This TC was extracted from prtConsoleDisable in RFC 1759.
+    STATUS     current
+    DESCRIPTION
+        "This value indicates whether or not input is accepted from
+        the operator console.  A value of 'enabled' indicates that
+        input is accepted from the console, and a value of 'disabled'
+        indicates that input is not accepted from the console. "
+    SYNTAX    INTEGER {
+                  enabled(3),
+                  disabled(4)
+                  }
+
+--
+-- Alert Group TEXTUAL-CONVENTIONs
+--
+
+PrtAlertTrainingLevelTC ::= TEXTUAL-CONVENTION
+    -- This TC was extracted from prtAlertTrainingLevel in RFC 1759.
+
+    STATUS    current
+    DESCRIPTION
+        "The level of training required to handle this alert, if
+        human intervention is required.  The noInterventionRequired
+        value should be used if the event does not require any human
+        intervention.  The training level is an enumeration that is
+        determined and assigned by the printer manufacturer based on
+        the information or training required to handle this alert.
+        The printer will break alerts into these different training
+        levels.  It is the responsibility of a management application
+        in the system to determine how a particular alert is handled
+        and how and to whom that alert is routed.  The following are
+        the four training levels of alerts:
+
+        Field Service - Alerts that typically require advanced
+            training and technical knowledge of the printer and its
+            subunits.  An example of a technical person would be a
+            manufacturer's Field Service representative, or other
+            person formally trained by the manufacturer or similar
+            representative.
+        Trained - Alerts that require an intermediate or moderate
+            knowledge of the printer and its subunits.  A typical
+            example of such an alert is replacing a toner cartridge.
+        Untrained -     Alerts that can be fixed without prior
+            training either because the action to correct the alert
+            is obvious or the printer can help the untrained person
+            fix the problem.  A typical example of such an alert is
+            reloading paper trays or emptying output bins on a low
+            end printer.
+        Management -    Alerts that have to do with overall operation
+            of and configuration of the printer.  Examples of such
+            management events are configuration change of subunits."
+    SYNTAX    INTEGER {
+                  other(1),
+                  unknown(2),
+                  untrained(3),
+                  trained(4),
+                  fieldService(5),
+                  management(6),
+                  noInterventionRequired(7)  -- Not in RFC 1759
+                 }
+
+PrtAlertGroupTC ::= TEXTUAL-CONVENTION
+    -- Values in the range 1 to 29 must not be IANA-assigned without
+    -- re-publishing Printer MIB.
+    -- Values of 30 and greater are for use in MIBs that augment
+    -- the Printer MIB, such as the Finisher MIB.
+    -- This TC extracted from prtAlertGroup in RFC 1759.
+
+    STATUS    current
+    DESCRIPTION
+        "The type of subunit within the printer model that this alert
+        is related.  Input, output, and markers are examples of
+        printer model groups, i.e., examples of types of subunits.
+        Wherever possible, the enumerations match the sub-identifier
+        that identifies the relevant table in the Printer MIB.
+
+        NOTE: Alert type codes have been added for the Host Resources
+        MIB storage table and device table.  These additional types
+        are for situations in which the printer's storage and device
+        objects must generate alerts (and possibly traps for critical
+        alerts)."
+    SYNTAX    INTEGER {
+                  other(1),
+                  unknown(2),
+                -- Values for Host Resources MIB
+                  hostResourcesMIBStorageTable(3),
+                  hostResourcesMIBDeviceTable(4),
+                -- Values for Printer MIB
+                  generalPrinter(5),
+                  cover(6),
+                  localization(7),
+                  input(8),
+                  output(9),
+                  marker(10),
+                  markerSupplies(11),
+                  markerColorant(12),
+                  mediaPath(13),
+                  channel(14),
+                  interpreter(15),
+                  consoleDisplayBuffer(16),
+                  consoleLights(17),
+                  alert(18),                   -- Not in RFC 1759
+                -- Values (5) to (29) reserved for Printer MIB
+                -- Values for Finisher MIB
+                  finDevice(30),               -- Not in RFC 1759
+                  finSupply(31),               -- Not in RFC 1759
+                  finSupplyMediaInput(32),     -- Not in RFC 1759
+                  finAttribute(33)             -- Not in RFC 1759
+                -- Values (30) to (39) reserved for Finisher MIB
+                  }
+
+PrtAlertCodeTC ::= TEXTUAL-CONVENTION
+    -- This TC was extracted from prtAlertCode in RFC 1759.
+    STATUS    current
+    DESCRIPTION
+        "The code that describes the type of alert for this entry in
+
+        the table.  Binary change event alerts describe states of the
+        subunit while unary change event alerts describe a single
+        event.  The same alert code can be used for a binary change
+        event or a unary change event, depending on implementation.
+        Also, the same alert code can be used to indicate a critical
+        or non-critical (warning) alert, depending on implementation.
+        The value of prtAlertSeverityLevel specifies binary vs. unary
+        and critical vs. non-critical for each event for the
+        implementation.
+
+        While there are some specific codes for many subunits, the
+        generic codes should be used for most subunit alerts.  The
+        network management station can then query the subunit
+        specified by prtAlertGroup to determine further subunit
+        status and other subunit information.
+
+        An agent shall not add two entries to the alert table for the
+        same event, one containing a generic event code and the other
+        containing a specific event code; the agent shall add only
+        one entry in the alert table for each event; either generic
+        (preferred) or specific, not both.
+
+        Implementation of the unary change event
+        alertRemovalOfBinaryChangeEntry(1801) is optional.  When
+        implemented, this alert code shall indicate to network
+        management stations that the trailing edge of a binary change
+        event has occurred and the corresponding alert entry has been
+        removed from the alert table.  As with all events, the
+        alertRemovalOfBinaryChangeEntry(1801) alert shall be placed
+        at the end of the alert table.  Such an alert table entry
+        shall specify the following information:
+
+        prtAlertSeverityLevel   warningUnaryChangeEvent(4)
+        prtAlertTrainingLevel   noInterventionRequired(7)
+        prtAlertGroup           alert(18)
+        prtAlertGroupIndex      the index of the row in the
+                                alert table of the binary
+                                change event that this event
+                                has removed.
+        prtAlertLocation        unknown (-2)
+        prtAlertCode            alertRemovalOfBinaryChangeEntry(1801)
+        prtAlertDescription     <description or null string>
+        prtAlertTime            the value of sysUpTime at
+                                the time of the removal of the
+                                binary change event from the
+                                alert table.
+
+        Optionally, the agent may generate a trap coincident with
+
+        removing the binary change event and placing the unary change
+        event alertRemovalOfBinaryChangeEntry(1801) in the alert
+        table.  For such a trap, the prtAlertIndex sent with the above
+        trap parameters shall be the index of the
+        alertRemovalOfBinaryChangeEvent row that was added to the
+        prtAlertTable; not the index of the row that was removed from
+        the prtAlertTable."
+    SYNTAX    INTEGER {
+                  other(1),
+                      -- an event that is not represented
+                      -- by one of the alert codes
+                      -- specified below.
+                  unknown(2),
+                      -- The following generic codes are common to
+                      -- multiple groups.  The NMS may examine the
+                      -- prtAlertGroup object to determine what group
+                      -- to query for further information.
+                  coverOpen(3),
+                  coverClosed(4),
+                  interlockOpen(5),
+                  interlockClosed(6),
+                  configurationChange(7),
+                  jam(8),
+                  subunitMissing(9),           -- Not in RFC 1759
+                      -- The subunit tray, bin, etc.
+                      -- has been removed.
+                  subunitLifeAlmostOver(10),   -- Not in RFC 1759
+                  subunitLifeOver(11),         -- Not in RFC 1759
+                  subunitAlmostEmpty(12),      -- Not in RFC 1759
+                  subunitEmpty(13),            -- Not in RFC 1759
+                  subunitAlmostFull(14),       -- Not in RFC 1759
+                  subunitFull(15),             -- Not in RFC 1759
+                  subunitNearLimit(16),        -- Not in RFC 1759
+                  subunitAtLimit(17),          -- Not in RFC 1759
+                  subunitOpened(18),           -- Not in RFC 1759
+                  subunitClosed(19),           -- Not in RFC 1759
+                  subunitTurnedOn(20),         -- Not in RFC 1759
+                  subunitTurnedOff(21),        -- Not in RFC 1759
+                  subunitOffline(22),          -- Not in RFC 1759
+                  subunitPowerSaver(23),       -- Not in RFC 1759
+                  subunitWarmingUp(24),        -- Not in RFC 1759
+                  subunitAdded(25),            -- Not in RFC 1759
+                  subunitRemoved(26),          -- Not in RFC 1759
+                  subunitResourceAdded(27),    -- Not in RFC 1759
+                  subunitResourceRemoved(28),  -- Not in RFC 1759
+                  subunitRecoverableFailure(29),
+                                               -- Not in RFC 1759
+                  subunitUnrecoverableFailure(30),
+
+                                               -- Not in RFC 1759
+                  subunitRecoverableStorageError(31),
+                                               -- Not in RFC 1759
+                  subunitUnrecoverableStorageError(32),
+                                               -- Not in RFC 1759
+                  subunitMotorFailure(33),     -- Not in RFC 1759
+                  subunitMemoryExhausted(34),  -- Not in RFC 1759
+                  subunitUnderTemperature(35), -- Not in RFC 1759
+                  subunitOverTemperature(36),  -- Not in RFC 1759
+                  subunitTimingFailure(37),    -- Not in RFC 1759
+                  subunitThermistorFailure(38), -- Not in RFC 1759
+
+                -- General Printer group
+                  doorOpen(501),    -- DEPRECATED
+                                    -- Use coverOpened(3)
+                  doorClosed(502),  -- DEPRECATED
+                                    -- Use coverClosed(4)
+                  powerUp(503),
+                  powerDown(504),
+                  printerNMSReset(505),        -- Not in RFC 1759
+                      -- The printer has been reset by some
+                      -- network management station(NMS)
+                      -- writing into 'prtGeneralReset'.
+                  printerManualReset(506),     -- Not in RFC 1759
+                      -- The printer has been reset manually.
+                  printerReadyToPrint(507),    -- Not in RFC 1759
+                      -- The printer is ready to print. (i.e.,
+                      -- not warming up, not in power save
+                      -- state, not adjusting print quality,
+                      -- etc.).
+
+                -- Input Group
+                  inputMediaTrayMissing(801),
+                  inputMediaSizeChange(802),
+                  inputMediaWeightChange(803),
+                  inputMediaTypeChange(804),
+                  inputMediaColorChange(805),
+                  inputMediaFormPartsChange(806),
+                  inputMediaSupplyLow(807),
+                  inputMediaSupplyEmpty(808),
+                  inputMediaChangeRequest(809), -- Not in RFC 1759
+                      -- An interpreter has detected that a
+                      -- different medium is need in this input
+                      -- tray subunit.  The prtAlertDescription may
+                      -- be used to convey a human readable
+                      -- description of the medium required to
+                      -- satisfy the request.
+                  inputManualInputRequest(810), -- Not in RFC 1759
+
+                      -- An interpreter has detected that manual
+                      -- input is required in this subunit.  The
+                      -- prtAlertDescription may be used to convey
+                      -- a human readable description of the medium
+                      -- required to satisfy the request.
+                  inputTrayPositionFailure(811), -- Not in RFC 1759
+                      -- The input tray failed to position correctly.
+                  inputTrayElevationFailure(812),
+                                        -- Not in RFC 1759
+                  inputCannotFeedSizeSelected(813),
+                                        -- Not in RFC 1759
+                -- Output Group
+                  outputMediaTrayMissing(901),
+                  outputMediaTrayAlmostFull(902),
+                  outputMediaTrayFull(903),
+                  outputMailboxSelectFailure(904),
+                                        -- Not in RFC 1759
+                -- Marker group
+                  markerFuserUnderTemperature(1001),
+                  markerFuserOverTemperature(1002),
+                  markerFuserTimingFailure(1003),
+                                        -- Not in RFC 1759
+                  markerFuserThermistorFailure(1004),
+                                        -- Not in RFC 1759
+                  markerAdjustingPrintQuality(1005),
+                                        -- Not in RFC 1759
+                -- Marker Supplies group
+                  markerTonerEmpty(1101),
+                  markerInkEmpty(1102),
+                  markerPrintRibbonEmpty(1103),
+                  markerTonerAlmostEmpty(1104),
+                  markerInkAlmostEmpty(1105),
+                  markerPrintRibbonAlmostEmpty(1106),
+                  markerWasteTonerReceptacleAlmostFull(1107),
+                  markerWasteInkReceptacleAlmostFull(1108),
+                  markerWasteTonerReceptacleFull(1109),
+                  markerWasteInkReceptacleFull(1110),
+                  markerOpcLifeAlmostOver(1111),
+                  markerOpcLifeOver(1112),
+                  markerDeveloperAlmostEmpty(1113),
+                  markerDeveloperEmpty(1114),
+                  markerTonerCartridgeMissing(1115),
+                                        -- Not in RFC 1759
+                -- Media Path Device Group
+                  mediaPathMediaTrayMissing(1301),
+                  mediaPathMediaTrayAlmostFull(1302),
+                  mediaPathMediaTrayFull(1303),
+                  mediaPathCannotDuplexMediaSelected(1304),
+
+                                        -- Not in RFC 1759
+                -- Interpreter Group
+                  interpreterMemoryIncrease(1501),
+                  interpreterMemoryDecrease(1502),
+                  interpreterCartridgeAdded(1503),
+                  interpreterCartridgeDeleted(1504),
+                  interpreterResourceAdded(1505),
+                  interpreterResourceDeleted(1506),
+                  interpreterResourceUnavailable(1507),
+                  interpreterComplexPageEncountered(1509),
+                                        -- Not in RFC 1759
+                      -- The interpreter has encountered a page
+                      -- that is too complex for the resources that
+                      -- are available.
+                -- Alert Group
+                  alertRemovalOfBinaryChangeEntry(1801)
+                                        -- Not in RFC 1759
+                      -- A binary change event entry has been
+                      -- removed from the alert table.  This unary
+                      -- change alert table entry is added to the
+                      -- end of the alert table.
+                  }
+END
+
+
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/Mibs/IANA/IANA-RTPROTO-MIB
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/Mibs/IANA/IANA-RTPROTO-MIB	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/Mibs/IANA/IANA-RTPROTO-MIB	(revision 457)
@@ -0,0 +1,92 @@
+
+IANA-RTPROTO-MIB DEFINITIONS ::= BEGIN
+
+IMPORTS
+    MODULE-IDENTITY, mib-2           FROM SNMPv2-SMI
+    TEXTUAL-CONVENTION               FROM SNMPv2-TC;
+
+ianaRtProtoMIB  MODULE-IDENTITY
+    LAST-UPDATED "200009260000Z" -- September 26, 2000
+    ORGANIZATION "IANA"
+    CONTACT-INFO
+            " Internet Assigned Numbers Authority
+              Internet Corporation for Assigned Names and Numbers
+              4676 Admiralty Way, Suite 330
+              Marina del Rey, CA 90292-6601
+
+              Phone: +1 310 823 9358
+              EMail: iana&iana.org"
+    DESCRIPTION
+            "This MIB module defines the IANAipRouteProtocol and
+            IANAipMRouteProtocol textual conventions for use in MIBs
+            which need to identify unicast or multicast routing
+            mechanisms.
+
+            Any additions or changes to the contents of this MIB module
+            require either publication of an RFC, or Designated Expert
+            Review as defined in RFC 2434, Guidelines for Writing an
+            IANA Considerations Section in RFCs.  The Designated Expert 
+            will be selected by the IESG Area Director(s) of the Routing
+            Area."
+
+    REVISION     "200009260000Z"  -- September 26, 2000 
+    DESCRIPTION  "Original version, published in coordination
+                 with RFC 2932."
+
+    ::= { mib-2 84 }
+
+IANAipRouteProtocol ::= TEXTUAL-CONVENTION
+   STATUS      current
+
+   DESCRIPTION
+            "A mechanism for learning routes.  Inclusion of values for
+            routing protocols is not intended to imply that those
+            protocols need be supported."
+   SYNTAX      INTEGER {
+                other     (1),  -- not specified
+                local     (2),  -- local interface
+                netmgmt   (3),  -- static route
+                icmp      (4),  -- result of ICMP Redirect
+
+                        -- the following are all dynamic
+                        -- routing protocols
+
+                egp        (5),  -- Exterior Gateway Protocol
+                ggp        (6),  -- Gateway-Gateway Protocol
+                hello      (7),  -- FuzzBall HelloSpeak
+                rip        (8),  -- Berkeley RIP or RIP-II
+                isIs       (9),  -- Dual IS-IS
+                esIs       (10), -- ISO 9542
+                ciscoIgrp  (11), -- Cisco IGRP
+                bbnSpfIgp  (12), -- BBN SPF IGP
+                ospf       (13), -- Open Shortest Path First
+                bgp        (14), -- Border Gateway Protocol
+                idpr       (15), -- InterDomain Policy Routing
+                ciscoEigrp (16), -- Cisco EIGRP
+                dvmrp      (17)  -- DVMRP
+               }
+
+IANAipMRouteProtocol ::= TEXTUAL-CONVENTION
+   STATUS      current
+   DESCRIPTION
+            "The multicast routing protocol.  Inclusion of values for
+            multicast routing protocols is not intended to imply that
+            those protocols need be supported."
+   SYNTAX      INTEGER {
+                   other(1),          -- none of the following
+                   local(2),          -- e.g., manually configured
+                   netmgmt(3),        -- set via net.mgmt protocol
+                   dvmrp(4),
+                   mospf(5),
+                   pimSparseDense(6), -- PIMv1, both DM and SM
+                   cbt(7),
+                   pimSparseMode(8),  -- PIM-SM
+                   pimDenseMode(9),   -- PIM-DM
+                   igmpOnly(10),
+                   bgmp(11),
+                   msdp(12)
+               }
+
+END
+
+
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/Mibs/IANA/IANATn3270eTC-MIB
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/Mibs/IANA/IANATn3270eTC-MIB	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/Mibs/IANA/IANATn3270eTC-MIB	(revision 457)
@@ -0,0 +1,306 @@
+
+  IANATn3270eTC-MIB DEFINITIONS ::= BEGIN
+
+ IMPORTS
+      MODULE-IDENTITY, mib-2
+          FROM SNMPv2-SMI
+      TEXTUAL-CONVENTION
+          FROM SNMPv2-TC;
+
+    ianaTn3270eTcMib MODULE-IDENTITY
+        LAST-UPDATED "200005100000Z"  -- May 10, 2000
+        ORGANIZATION "IANA"
+        CONTACT-INFO
+            "Internet Assigned Numbers Authority
+
+             Postal: ICANN
+                     4676 Admiralty Way, Suite 330
+                     Marina del Rey, CA 90292
+
+             Tel:    +1  310 823 9358 x20
+             E-Mail: iana&iana.org"
+        DESCRIPTION
+            "This module defines a set of textual conventions
+            for use by the TN3270E-MIB and the TN3270E-RT-MIB.
+
+            Any additions or changes to the contents of this
+            MIB module must first be discussed on the tn3270e
+            working group list at: tn3270e&list.nih.gov
+            and approved by one of the following TN3270E
+            working group contacts:
+
+                Ed Bailey (co-chair) - elbailey&us.ibm.com
+                Michael Boe (co-chair) - mboe&cisco.com
+                Ken White - kennethw&vnet.ibm.com
+                Robert Moore - remoore&us.ibm.com
+
+            The above list of contacts can be altered with
+            the approval of the two co-chairs.
+
+            The Textual Conventions defined within this MIB have
+            no security issues associated with them unless
+            explicitly stated in their corresponding
+            DESCRIPTION clause."
+
+     -- revision log, in reverse chronological order
+
+        REVISION    "200005100000Z"  -- May 10, 2000
+        DESCRIPTION "Fix to import mib-2 instead of experimental."
+
+        REVISION    "199909011000Z"  -- September 1, 1999
+        DESCRIPTION
+            "Initial version transferred from the TN3270E
+            working group to IANA."
+
+        ::= { mib-2 61 }
+
+
+  -- Textual Conventions
+
+  IANATn3270eAddrType ::= TEXTUAL-CONVENTION
+      STATUS current
+      DESCRIPTION
+          "The textual convention for defining the type of a
+          client address.  The enumeration value unknown(0) is
+          also used to indicate that no actual address is present."
+      SYNTAX INTEGER {
+                      unknown(0),
+                      ipv4(1),
+                      ipv6(2)
+                     }
+
+  IANATn3270eAddress ::= TEXTUAL-CONVENTION
+      STATUS current
+      DESCRIPTION
+          "Denotes a client address.  The type of client address is
+          determined by use of the IANATn3270eAddrType textual
+convention.
+          The length in octets of a IANATn3270eAddress object is:
+
+            IANATn3270eAddrType   Address Length
+            +++++++++++++++++++   ++++++++++++++
+                     unknown(0)   not specified or unknown; the
+                                  actual length of the
+                                  IANATn3270eAddress octet string
+                                  indicates if an address
+                                  is present
+                        ipv4(1)   4 OCTETS
+                        ipv6(2)   16 OCTETS
+
+          This textual convention is similar to the TAddress
+          TC defined by RFC1903 except that it allows a
+          zero-length octet string and is not a full transport
+          layer address."
+      SYNTAX OCTET STRING (SIZE (0..255))
+
+  IANATn3270eClientType ::= TEXTUAL-CONVENTION
+      STATUS current
+      DESCRIPTION
+          "The textual convention for defining the set of
+           enumerations used by tn3270eTcpConnClientIdFormat
+           in the TN3270E-MIB:
+
+           ENUMERATION        OCTETs  DESCRIPTION
+
+           none(1)              0     Not specified
+           other(2)           1..512  Implementation specific
+           ipv4(3)              6     4-octet IP Address plus
+                                      2-octet TCP Port
+           ipv6(4)              18    16-octet IPv6 Address
+                                      plus 2-octet TCP Port
+           domainName(5)      1..512  The DNS name of a
+                                      client.
+           truncDomainName(6) 1..512  The (truncated) DNS name
+                                      of a client.
+           string(7)          1..512  Unknown Utf8String
+           certificate(8)     1..512  certificate
+           userId(9)          1..8    Client's userid
+           x509dn(10)         1..512  X.509 Distinguished Name
+
+           Representation of a certificate(8) may be lead to
+           a security exposure and is NOT RECOMMENDED without
+           adequate security."
+      SYNTAX INTEGER {
+                      none(1),
+                      other(2),
+                      ipv4(3),
+                      ipv6(4),
+                      domainName(5),
+                      truncDomainName(6),
+                      string(7),
+                      certificate(8),
+                      userId(9),
+                      x509dn(10)
+                     }
+
+  IANATn3270Functions ::= TEXTUAL-CONVENTION
+      STATUS current
+      DESCRIPTION
+          "This textual convention reflects the current set of
+          TN3270 and TN3270E functions that can be negotiated
+          between a server and its client:
+
+          RFC856
+          transmitBinary  The sender of this command REQUESTS
+                          permission to begin transmitting, or
+                          confirms that it will now begin
+                          transmitting characters which are to
+                          be interpreted as 8 bits of binary
+                          data by the receiver of the data.
+          RFC860
+          timingMark      The sender of this command REQUESTS
+                          that the receiver of this command
+                          return a WILL TIMING-MARK in the data
+                          stream at the 'appropriate place'.
+          RFC885
+          endOfRecord     The sender of this command requests
+                          permission to begin transmission of
+                          the Telnet END-OF-RECORD (EOR) code
+                          when transmitting data characters, or
+                          the sender of this command confirms it
+                          will now begin transmission of EORs
+                          with transmitted data characters.
+          RFC1091
+          terminalType    Sender is willing to send terminal
+                          type information in a subsequent
+                          sub-negotiation.
+
+          RFC1041
+          tn3270Regime    Sender is willing to send list of
+                          supported 3270 Regimes in a
+                          subsequent sub-negotiation.
+          RFC2355
+          scsCtlCodes     (Printer sessions only).  Allows the
+                          use of the SNA Character Stream (SCS)
+                          and SCS control codes on the session.
+                          SCS is used with LU type 1 SNA sessions.
+          dataStreamCtl   (Printer sessions only).  Allows the use
+                          of the standard 3270 data stream.  This
+                          corresponds to LU type 3 SNA sessions.
+          responses       Provides support for positive and
+                          negative response handling.  Allows the
+                          server to reflect to the client any and
+                          all definite, exception, and no response
+                          requests sent by the host application.
+          bindImage       Allows the server to send the SNA Bind
+                          image and Unbind notification to the
+                          client.
+          sysreq          Allows the client and server to emulate
+                          some (or all, depending on the server) of
+                          the functions of the SYSREQ key in an SNA
+                          environment."
+      SYNTAX BITS {
+                   transmitBinary(0),-- rfc856
+                   timemark(1),      -- rfc860
+                   endOfRecord(2),   -- rfc885
+                   terminalType(3),  -- rfc1091
+                   tn3270Regime(4),  -- rfc1041
+                   scsCtlCodes(5),   -- rfc2355
+                   dataStreamCtl(6), -- rfc2355
+                   responses(7),     -- rfc2355
+                   bindImage(8),     -- rfc2355
+                   sysreq(9)         -- rfc2355
+                  }
+
+  IANATn3270ResourceType ::= TEXTUAL-CONVENTION
+      STATUS current
+      DESCRIPTION
+          "The type of resource defined by a resource pool.  Refer
+          to tn3270eResPoolTable."
+      SYNTAX INTEGER {
+                      other(1),
+                      terminal(2),
+                      printer(3),
+                      terminalOrPrinter(4)
+                     }
+
+  IANATn3270DeviceType ::= TEXTUAL-CONVENTION
+      STATUS current
+      DESCRIPTION
+          "This textual convention defines the list of device
+          types that can be set, as defined by RFC 2355."
+      SYNTAX INTEGER {
+                   -- terminals
+                      ibm3278d2(1),    -- (24 row x 80 col display)
+                      ibm3278d2E(2),   -- (24 row x 80 col display)
+                      ibm3278d3(3),    -- (32 row x 80 col display)
+                      ibm3278d3E(4),   -- (32 row x 80 col display)
+                      ibm3278d4(5),    -- (43 row x 80 col display)
+                      ibm3278d4E(6),   -- (43 row x 80 col display)
+                      ibm3278d5(7),    -- (27 row x 132 col display)
+                      ibm3278d5E(8),   -- (27 row x 132 col display)
+                      ibmDynamic(9),   -- (no pre-defined display size)
+
+                   -- printers
+                      ibm3287d1(10),
+
+                      unknown(100)
+                     }
+
+  IANATn3270eLogData ::= TEXTUAL-CONVENTION
+      STATUS current
+      DESCRIPTION
+        "An octet string representing log data as pertaining to
+        either a TN3270 or TN3270E Session as reported from a
+        TN3270E Server. Log data is stored in an octet string
+        in time order (from earliest to latest).
+
+        Each log element has the following form:
+
+        +------+----+---------+------------+
+        !length!type!TimeStamp! data       !
+        +------+----+---------+------------+
+
+        where
+
+        length    = one-octet length of the data portion of the
+                    trace element, not including the length,
+                    type, and TimeStamp fields
+        type      = one-octet code point characterizing the data.
+        TimeStamp = A 4-octet field representing the number of
+                    TimeTicks since the TN3270E server was last
+                    activated.  The server's last activation time
+                    is available in the tn3270eSrvrConfLastActTime
+                    object in the TN3270E MIB, which has the
+                    syntax DateAndTime.
+        data      = initial part of a PDU.
+
+        length   type
+
+          0-255  x'00' - unknown
+          0      x'01' - inactivity timer expired
+          0      x'02' - dynamic timer expired
+          0      x'03' - actlu req
+          0      x'04' - bind req
+          0      x'05' - clear req
+          0      x'06' - dactlu req
+          0      x'07' - warm actpu req
+          0      x'08' - sdt req
+          0      x'09' - unbind req
+          0      x'0A' - notify resp
+          0      x'0B' - reply PSID neg rsp
+          0      x'0C' - reply PSID pos rsp
+          0      x'0D' - unbind rsp
+          0      x'0E' - hierarchical reset
+          0      x'0F' - client connect req
+          0      x'10' - client disconnect req
+          0      x'11' - timingmark received
+          0      x'12' - flowControl timer expired
+          0      x'13' - neg rsp to host
+          0      x'14' - neg rsp from host
+          0      x'15' - data contention
+          0      x'16' - no buffer to send SNA data
+          0      x'17' - receive response while inbound
+          0      x'18' - client protocol error
+          0      x'19' - badClientSequenceReceived
+          1-255  x'1A' - utf8String
+          2      x'1B' - hexCode, implementation dependent
+
+          Log element entries have a minimum length of 6 octets.
+          The zero-length string indicates that no log data is
+          available."
+      SYNTAX OCTET STRING (SIZE (0 | 6..2048))
+
+  END
+
+
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/Mibs/IANA/IANAifType-MIB
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/Mibs/IANA/IANAifType-MIB	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/Mibs/IANA/IANAifType-MIB	(revision 457)
@@ -0,0 +1,572 @@
+   IANAifType-MIB DEFINITIONS ::= BEGIN
+
+   IMPORTS
+       MODULE-IDENTITY, mib-2      FROM SNMPv2-SMI
+       TEXTUAL-CONVENTION          FROM SNMPv2-TC;
+
+   ianaifType MODULE-IDENTITY
+       LAST-UPDATED "200709130000Z"  -- September 13, 2007
+       ORGANIZATION "IANA"
+       CONTACT-INFO "        Internet Assigned Numbers Authority
+
+                     Postal: ICANN
+                             4676 Admiralty Way, Suite 330
+                             Marina del Rey, CA 90292
+
+                     Tel:    +1 310 823 9358
+                     E-Mail: iana&iana.org"
+
+       DESCRIPTION  "This MIB module defines the IANAifType Textual
+                     Convention, and thus the enumerated values of
+                     the ifType object defined in MIB-II's ifTable."
+
+       REVISION     "200709130000Z"  -- September 13, 2007
+       DESCRIPTION  "Registration of new IANAifTypes 243 and 244."
+
+       REVISION     "200705290000Z"  -- May 29, 2007
+       DESCRIPTION  "Changed the description for IANAifType 228."
+
+       REVISION     "200703080000Z"  -- March 08, 2007
+       DESCRIPTION  "Registration of new IANAifType 242."
+
+       REVISION     "200701230000Z"  -- January 23, 2007
+       DESCRIPTION  "Registration of new IANAifTypes 239, 240, and 241." 
+
+       REVISION     "200610170000Z"  -- October 17, 2006
+       DESCRIPTION  "Deprecated/Obsoleted IANAifType 230.  Registration of 
+                     IANAifType 238." 
+
+       REVISION     "200609250000Z"  -- September 25, 2006
+       DESCRIPTION  "Changed the description for IANA ifType 
+                     184 and added new IANA ifType 237."  
+
+       REVISION     "200608170000Z"  -- August 17, 2006
+       DESCRIPTION  "Changed the descriptions for IANAifTypes
+                     20 and 21."   
+
+       REVISION     "200608110000Z"  -- August 11, 2006
+       DESCRIPTION  "Changed the descriptions for IANAifTypes
+                     7, 11, 62, 69, and 117."   
+
+       REVISION     "200607250000Z"  -- July 25, 2006
+       DESCRIPTION  "Registration of new IANA ifType 236."
+
+       REVISION     "200606140000Z"  -- June 14, 2006
+       DESCRIPTION  "Registration of new IANA ifType 235."
+
+       REVISION     "200603310000Z"  -- March 31, 2006
+       DESCRIPTION  "Registration of new IANA ifType 234."
+	   
+       REVISION     "200603300000Z"  -- March 30, 2006
+       DESCRIPTION  "Registration of new IANA ifType 233."
+       
+       REVISION     "200512220000Z"  -- December 22, 2005
+       DESCRIPTION  "Registration of new IANA ifTypes 231 and 232."
+	   
+       REVISION     "200510100000Z"  -- October 10, 2005
+       DESCRIPTION  "Registration of new IANA ifType 230."
+
+       REVISION     "200509090000Z"  -- September 09, 2005
+       DESCRIPTION  "Registration of new IANA ifType 229."
+
+       REVISION     "200505270000Z"  -- May 27, 2005
+       DESCRIPTION  "Registration of new IANA ifType 228."
+
+       REVISION     "200503030000Z"  -- March 3, 2005
+       DESCRIPTION  "Added the IANAtunnelType TC and deprecated
+	                 IANAifType sixToFour (215) per RFC4087."
+
+       REVISION     "200411220000Z"  -- November 22, 2004
+       DESCRIPTION  "Registration of new IANA ifType 227 per RFC4631."
+
+       REVISION     "200406170000Z"  -- June 17, 2004
+       DESCRIPTION  "Registration of new IANA ifType 226."
+
+       REVISION     "200405120000Z"  -- May 12, 2004
+       DESCRIPTION  "Added description for IANAifType 6, and 
+	                 changed the descriptions for IANAifTypes
+                     180, 181, and 182."
+
+       REVISION     "200405070000Z"  -- May 7, 2004
+       DESCRIPTION  "Registration of new IANAifType 225."
+
+       REVISION     "200308250000Z"  -- Aug 25, 2003
+       DESCRIPTION  "Deprecated IANAifTypes 7 and 11. Obsoleted
+                     IANAifTypes 62, 69, and 117.  ethernetCsmacd (6)
+                     should be used instead of these values"
+
+       REVISION     "200308180000Z"  -- Aug 18, 2003
+       DESCRIPTION  "Registration of new IANAifType
+                     224."
+
+       REVISION     "200308070000Z"  -- Aug 7, 2003
+       DESCRIPTION  "Registration of new IANAifTypes
+                     222 and 223."
+
+       REVISION     "200303180000Z"  -- Mar 18, 2003
+       DESCRIPTION  "Registration of new IANAifType
+                     221."
+
+       REVISION     "200301130000Z"  -- Jan 13, 2003
+       DESCRIPTION  "Registration of new IANAifType
+                     220."
+
+       REVISION     "200210170000Z"  -- Oct 17, 2002
+       DESCRIPTION  "Registration of new IANAifType
+                     219."
+	   
+       REVISION     "200207160000Z"  -- Jul 16, 2002
+       DESCRIPTION  "Registration of new IANAifTypes
+                     217 and 218."
+
+       REVISION     "200207100000Z"  -- Jul 10, 2002
+       DESCRIPTION  "Registration of new IANAifTypes
+                     215 and 216."
+
+       REVISION     "200206190000Z"  -- Jun 19, 2002
+       DESCRIPTION  "Registration of new IANAifType
+                     214."
+	   
+       REVISION     "200201040000Z"  -- Jan 4, 2002
+       DESCRIPTION  "Registration of new IANAifTypes
+                     211, 212 and 213."
+
+       REVISION     "200112200000Z"  -- Dec 20, 2001
+       DESCRIPTION  "Registration of new IANAifTypes
+                     209 and 210."
+
+       REVISION     "200111150000Z"  -- Nov 15, 2001
+       DESCRIPTION  "Registration of new IANAifTypes
+                     207 and 208."
+
+
+       REVISION     "200111060000Z"  -- Nov 6, 2001
+       DESCRIPTION  "Registration of new IANAifType
+                     206."
+
+
+       REVISION     "200111020000Z"  -- Nov 2, 2001
+       DESCRIPTION  "Registration of new IANAifType
+                     205."
+
+
+       REVISION     "200110160000Z"  -- Oct 16, 2001
+       DESCRIPTION  "Registration of new IANAifTypes
+                     199, 200, 201, 202, 203, and 204."
+
+
+       REVISION     "200109190000Z"  -- Sept 19, 2001
+       DESCRIPTION  "Registration of new IANAifType
+                     198."
+
+       REVISION     "200105110000Z"  -- May 11, 2001
+       DESCRIPTION  "Registration of new IANAifType
+                     197."
+
+       
+       REVISION     "200101120000Z"  -- Jan 12, 2001
+       DESCRIPTION  "Registration of new IANAifTypes
+                     195 and 196."
+
+       REVISION     "200012190000Z"  -- Dec 19, 2000
+       DESCRIPTION  "Registration of new IANAifTypes
+                     193 and 194."
+
+       REVISION     "200012070000Z"  -- Dec 07, 2000
+       DESCRIPTION  "Registration of new IANAifTypes
+                     191 and 192."
+
+       REVISION     "200012040000Z"  -- Dec 04, 2000
+       DESCRIPTION  "Registration of new IANAifType
+                     190."
+
+       REVISION     "200010170000Z"  -- Oct 17, 2000
+       DESCRIPTION  "Registration of new IANAifTypes
+                     188 and 189."  
+
+       REVISION     "200010020000Z"  -- Oct 02, 2000
+       DESCRIPTION  "Registration of new IANAifType 187." 
+
+       REVISION     "200009010000Z"  -- Sept 01, 2000
+       DESCRIPTION  "Registration of new IANAifTypes
+                     184, 185, and 186."			
+
+       REVISION     "200008240000Z"  -- Aug 24, 2000
+       DESCRIPTION  "Registration of new IANAifType 183." 
+
+       REVISION     "200008230000Z"  -- Aug 23, 2000
+       DESCRIPTION  "Registration of new IANAifTypes
+                     174-182."
+
+       REVISION     "200008220000Z"  -- Aug 22, 2000
+       DESCRIPTION  "Registration of new IANAifTypes 170,
+                     171, 172 and 173."
+
+       REVISION     "200004250000Z"  -- Apr 25, 2000
+       DESCRIPTION  "Registration of new IANAifTypes 168 and 169."       
+	
+       REVISION     "200003060000Z"  -- Mar 6, 2000
+       DESCRIPTION  "Fixed a missing semi-colon in the IMPORT.
+                     Also cleaned up the REVISION log a bit.
+                     It is not complete, but from now on it will
+                     be maintained and kept up to date with each
+                     change to this MIB module."
+
+       REVISION     "199910081430Z"  -- Oct 08, 1999
+       DESCRIPTION  "Include new name assignments up to cnr(85).
+                     This is the first version available via the WWW
+                     at: ftp://ftp.isi.edu/mib/ianaiftype.mib"
+
+       REVISION     "199401310000Z"  -- Jan 31, 1994
+       DESCRIPTION  "Initial version of this MIB as published in
+                     RFC 1573."
+
+       ::= { mib-2 30 }
+
+
+   IANAifType ::= TEXTUAL-CONVENTION
+       STATUS       current
+       DESCRIPTION
+               "This data type is used as the syntax of the ifType
+               object in the (updated) definition of MIB-II's
+               ifTable.
+
+               The definition of this textual convention with the
+               addition of newly assigned values is published
+               periodically by the IANA, in either the Assigned
+               Numbers RFC, or some derivative of it specific to
+               Internet Network Management number assignments.  (The
+               latest arrangements can be obtained by contacting the
+               IANA.)
+
+               Requests for new values should be made to IANA via
+               email (iana&iana.org).
+
+               The relationship between the assignment of ifType
+               values and of OIDs to particular media-specific MIBs
+               is solely the purview of IANA and is subject to change
+               without notice.  Quite often, a media-specific MIB's
+               OID-subtree assignment within MIB-II's 'transmission'
+               subtree will be the same as its ifType value.
+               However, in some circumstances this will not be the
+               case, and implementors must not pre-assume any
+               specific relationship between ifType values and
+               transmission subtree OIDs."
+       SYNTAX  INTEGER {
+                   other(1),          -- none of the following
+                   regular1822(2),
+                   hdh1822(3),
+                   ddnX25(4),
+                   rfc877x25(5),
+                   ethernetCsmacd(6), -- for all ethernet-like interfaces,
+                                      -- regardless of speed, as per RFC3635
+                   iso88023Csmacd(7), -- Deprecated via RFC3635
+                                      -- ethernetCsmacd (6) should be used instead
+                   iso88024TokenBus(8),
+                   iso88025TokenRing(9),
+                   iso88026Man(10),
+                   starLan(11), -- Deprecated via RFC3635
+                                -- ethernetCsmacd (6) should be used instead
+                   proteon10Mbit(12),
+                   proteon80Mbit(13),
+                   hyperchannel(14),
+                   fddi(15),
+                   lapb(16),
+                   sdlc(17),
+                   ds1(18),            -- DS1-MIB
+                   e1(19),             -- Obsolete see DS1-MIB
+                   basicISDN(20),              -- no longer used
+                                               -- see also RFC2127
+                   primaryISDN(21),            -- no longer used
+                                               -- see also RFC2127
+                   propPointToPointSerial(22), -- proprietary serial
+                   ppp(23),
+                   softwareLoopback(24),
+                   eon(25),            -- CLNP over IP 
+                   ethernet3Mbit(26),
+                   nsip(27),           -- XNS over IP
+                   slip(28),           -- generic SLIP
+                   ultra(29),          -- ULTRA technologies
+                   ds3(30),            -- DS3-MIB
+                   sip(31),            -- SMDS, coffee
+                   frameRelay(32),     -- DTE only. 
+                   rs232(33),
+                   para(34),           -- parallel-port
+                   arcnet(35),         -- arcnet
+                   arcnetPlus(36),     -- arcnet plus
+                   atm(37),            -- ATM cells
+                   miox25(38),
+                   sonet(39),          -- SONET or SDH 
+                   x25ple(40),
+                   iso88022llc(41),
+                   localTalk(42),
+                   smdsDxi(43),
+                   frameRelayService(44),  -- FRNETSERV-MIB
+                   v35(45),
+                   hssi(46),
+                   hippi(47),
+                   modem(48),          -- Generic modem
+                   aal5(49),           -- AAL5 over ATM
+                   sonetPath(50),
+                   sonetVT(51),
+                   smdsIcip(52),       -- SMDS InterCarrier Interface
+                   propVirtual(53),    -- proprietary virtual/internal
+                   propMultiplexor(54),-- proprietary multiplexing
+                   ieee80212(55),      -- 100BaseVG
+                   fibreChannel(56),   -- Fibre Channel
+                   hippiInterface(57), -- HIPPI interfaces     
+                   frameRelayInterconnect(58), -- Obsolete use either
+                                       -- frameRelay(32) or 
+                                       -- frameRelayService(44).
+                   aflane8023(59),     -- ATM Emulated LAN for 802.3
+                   aflane8025(60),     -- ATM Emulated LAN for 802.5
+                   cctEmul(61),        -- ATM Emulated circuit          
+                   fastEther(62),      -- Obsoleted via RFC3635
+                                       -- ethernetCsmacd (6) should be used instead
+                   isdn(63),           -- ISDN and X.25           
+                   v11(64),            -- CCITT V.11/X.21             
+                   v36(65),            -- CCITT V.36                  
+                   g703at64k(66),      -- CCITT G703 at 64Kbps
+                   g703at2mb(67),      -- Obsolete see DS1-MIB
+                   qllc(68),           -- SNA QLLC                    
+                   fastEtherFX(69),    -- Obsoleted via RFC3635
+                                       -- ethernetCsmacd (6) should be used instead
+                   channel(70),        -- channel                     
+                   ieee80211(71),      -- radio spread spectrum       
+                   ibm370parChan(72),  -- IBM System 360/370 OEMI Channel
+                   escon(73),          -- IBM Enterprise Systems Connection
+                   dlsw(74),           -- Data Link Switching
+                   isdns(75),          -- ISDN S/T interface
+                   isdnu(76),          -- ISDN U interface
+                   lapd(77),           -- Link Access Protocol D
+                   ipSwitch(78),       -- IP Switching Objects
+                   rsrb(79),           -- Remote Source Route Bridging
+                   atmLogical(80),     -- ATM Logical Port
+                   ds0(81),            -- Digital Signal Level 0
+                   ds0Bundle(82),      -- group of ds0s on the same ds1
+                   bsc(83),            -- Bisynchronous Protocol
+                   async(84),          -- Asynchronous Protocol
+                   cnr(85),            -- Combat Net Radio
+                   iso88025Dtr(86),    -- ISO 802.5r DTR
+                   eplrs(87),          -- Ext Pos Loc Report Sys
+                   arap(88),           -- Appletalk Remote Access Protocol
+                   propCnls(89),       -- Proprietary Connectionless Protocol
+                   hostPad(90),        -- CCITT-ITU X.29 PAD Protocol
+                   termPad(91),        -- CCITT-ITU X.3 PAD Facility
+                   frameRelayMPI(92),  -- Multiproto Interconnect over FR
+                   x213(93),           -- CCITT-ITU X213
+                   adsl(94),           -- Asymmetric Digital Subscriber Loop
+                   radsl(95),          -- Rate-Adapt. Digital Subscriber Loop
+                   sdsl(96),           -- Symmetric Digital Subscriber Loop
+                   vdsl(97),           -- Very H-Speed Digital Subscrib. Loop
+                   iso88025CRFPInt(98), -- ISO 802.5 CRFP
+                   myrinet(99),        -- Myricom Myrinet
+                   voiceEM(100),       -- voice recEive and transMit
+                   voiceFXO(101),      -- voice Foreign Exchange Office
+                   voiceFXS(102),      -- voice Foreign Exchange Station
+                   voiceEncap(103),    -- voice encapsulation
+                   voiceOverIp(104),   -- voice over IP encapsulation
+                   atmDxi(105),        -- ATM DXI
+                   atmFuni(106),       -- ATM FUNI
+                   atmIma (107),       -- ATM IMA		   
+                   pppMultilinkBundle(108), -- PPP Multilink Bundle
+                   ipOverCdlc (109),   -- IBM ipOverCdlc
+                   ipOverClaw (110),   -- IBM Common Link Access to Workstn
+                   stackToStack (111), -- IBM stackToStack
+                   virtualIpAddress (112), -- IBM VIPA
+                   mpc (113),          -- IBM multi-protocol channel support
+                   ipOverAtm (114),    -- IBM ipOverAtm
+                   iso88025Fiber (115), -- ISO 802.5j Fiber Token Ring
+                   tdlc (116),	       -- IBM twinaxial data link control
+                   gigabitEthernet (117), -- Obsoleted via RFC3635
+                                          -- ethernetCsmacd (6) should be used instead
+                   hdlc (118),         -- HDLC
+                   lapf (119),	       -- LAP F
+                   v37 (120),	       -- V.37
+                   x25mlp (121),       -- Multi-Link Protocol
+                   x25huntGroup (122), -- X25 Hunt Group
+                   trasnpHdlc (123),   -- Transp HDLC
+                   interleave (124),   -- Interleave channel
+                   fast (125),         -- Fast channel
+                   ip (126),	       -- IP (for APPN HPR in IP networks)
+                   docsCableMaclayer (127),  -- CATV Mac Layer
+                   docsCableDownstream (128), -- CATV Downstream interface
+                   docsCableUpstream (129),  -- CATV Upstream interface
+                   a12MppSwitch (130), -- Avalon Parallel Processor
+                   tunnel (131),       -- Encapsulation interface
+                   coffee (132),       -- coffee pot
+                   ces (133),          -- Circuit Emulation Service
+                   atmSubInterface (134), -- ATM Sub Interface
+                   l2vlan (135),       -- Layer 2 Virtual LAN using 802.1Q
+                   l3ipvlan (136),     -- Layer 3 Virtual LAN using IP
+                   l3ipxvlan (137),    -- Layer 3 Virtual LAN using IPX
+                   digitalPowerline (138), -- IP over Power Lines	
+                   mediaMailOverIp (139), -- Multimedia Mail over IP
+                   dtm (140),        -- Dynamic syncronous Transfer Mode
+                   dcn (141),    -- Data Communications Network
+                   ipForward (142),    -- IP Forwarding Interface
+                   msdsl (143),       -- Multi-rate Symmetric DSL
+                   ieee1394 (144), -- IEEE1394 High Performance Serial Bus
+                   if-gsn (145),       --   HIPPI-6400 
+                   dvbRccMacLayer (146), -- DVB-RCC MAC Layer
+                   dvbRccDownstream (147),  -- DVB-RCC Downstream Channel
+                   dvbRccUpstream (148),  -- DVB-RCC Upstream Channel
+                   atmVirtual (149),   -- ATM Virtual Interface
+                   mplsTunnel (150),   -- MPLS Tunnel Virtual Interface
+                   srp (151),	-- Spatial Reuse Protocol	
+                   voiceOverAtm (152),  -- Voice Over ATM
+                   voiceOverFrameRelay (153),   -- Voice Over Frame Relay 
+                   idsl (154),		-- Digital Subscriber Loop over ISDN
+                   compositeLink (155),  -- Avici Composite Link Interface
+                   ss7SigLink (156),     -- SS7 Signaling Link 
+                   propWirelessP2P (157),  --  Prop. P2P wireless interface
+                   frForward (158),    -- Frame Forward Interface
+                   rfc1483 (159),	-- Multiprotocol over ATM AAL5
+                   usb (160),		-- USB Interface
+                   ieee8023adLag (161),  -- IEEE 802.3ad Link Aggregate
+                   bgppolicyaccounting (162), -- BGP Policy Accounting
+                   frf16MfrBundle (163), -- FRF .16 Multilink Frame Relay 
+                   h323Gatekeeper (164), -- H323 Gatekeeper
+                   h323Proxy (165), -- H323 Voice and Video Proxy
+                   mpls (166), -- MPLS                   
+                   mfSigLink (167), -- Multi-frequency signaling link
+                   hdsl2 (168), -- High Bit-Rate DSL - 2nd generation
+                   shdsl (169), -- Multirate HDSL2
+                   ds1FDL (170), -- Facility Data Link 4Kbps on a DS1
+                   pos (171), -- Packet over SONET/SDH Interface
+                   dvbAsiIn (172), -- DVB-ASI Input
+                   dvbAsiOut (173), -- DVB-ASI Output 
+                   plc (174), -- Power Line Communtications
+                   nfas (175), -- Non Facility Associated Signaling
+                   tr008 (176), -- TR008
+                   gr303RDT (177), -- Remote Digital Terminal
+                   gr303IDT (178), -- Integrated Digital Terminal
+                   isup (179), -- ISUP
+                   propDocsWirelessMaclayer (180), -- Cisco proprietary Maclayer
+                   propDocsWirelessDownstream (181), -- Cisco proprietary Downstream
+                   propDocsWirelessUpstream (182), -- Cisco proprietary Upstream
+                   hiperlan2 (183), -- HIPERLAN Type 2 Radio Interface
+                   propBWAp2Mp (184), -- PropBroadbandWirelessAccesspt2multipt
+                             -- use of this iftype for IEEE 802.16 WMAN
+                             -- interfaces as per IEEE Std 802.16f is
+                             -- deprecated and ifType 237 should be used instead.
+                   sonetOverheadChannel (185), -- SONET Overhead Channel
+                   digitalWrapperOverheadChannel (186), -- Digital Wrapper
+                   aal2 (187), -- ATM adaptation layer 2
+                   radioMAC (188), -- MAC layer over radio links
+                   atmRadio (189), -- ATM over radio links   
+                   imt (190), -- Inter Machine Trunks
+                   mvl (191), -- Multiple Virtual Lines DSL
+                   reachDSL (192), -- Long Reach DSL
+                   frDlciEndPt (193), -- Frame Relay DLCI End Point
+                   atmVciEndPt (194), -- ATM VCI End Point
+                   opticalChannel (195), -- Optical Channel
+                   opticalTransport (196), -- Optical Transport
+                   propAtm (197), --  Proprietary ATM       
+                   voiceOverCable (198), -- Voice Over Cable Interface
+                   infiniband (199), -- Infiniband
+                   teLink (200), -- TE Link
+                   q2931 (201), -- Q.2931
+                   virtualTg (202), -- Virtual Trunk Group
+                   sipTg (203), -- SIP Trunk Group
+                   sipSig (204), -- SIP Signaling   
+                   docsCableUpstreamChannel (205), -- CATV Upstream Channel
+                   econet (206), -- Acorn Econet
+                   pon155 (207), -- FSAN 155Mb Symetrical PON interface
+                   pon622 (208), -- FSAN622Mb Symetrical PON interface
+                   bridge (209), -- Transparent bridge interface
+                   linegroup (210), -- Interface common to multiple lines		   
+                   voiceEMFGD (211), -- voice E&M Feature Group D
+                   voiceFGDEANA (212), -- voice FGD Exchange Access North American
+                   voiceDID (213), -- voice Direct Inward Dialing
+                   mpegTransport (214), -- MPEG transport interface
+                   sixToFour (215), -- 6to4 interface (DEPRECATED)
+                   gtp (216), -- GTP (GPRS Tunneling Protocol)
+                   pdnEtherLoop1 (217), -- Paradyne EtherLoop 1
+                   pdnEtherLoop2 (218), -- Paradyne EtherLoop 2
+                   opticalChannelGroup (219), -- Optical Channel Group
+                   homepna (220), -- HomePNA ITU-T G.989				   
+                   gfp (221), -- Generic Framing Procedure (GFP)
+                   ciscoISLvlan (222), -- Layer 2 Virtual LAN using Cisco ISL
+                   actelisMetaLOOP (223), -- Acteleis proprietary MetaLOOP High Speed Link 
+                   fcipLink (224), -- FCIP Link 
+                   rpr (225), -- Resilient Packet Ring Interface Type
+                   qam (226), -- RF Qam Interface
+                   lmp (227), -- Link Management Protocol
+                   cblVectaStar (228), -- Cambridge Broadband Networks Limited VectaStar
+                   docsCableMCmtsDownstream (229), -- CATV Modular CMTS Downstream Interface
+                   adsl2 (230), -- Asymmetric Digital Subscriber Loop Version 2 
+                                -- (DEPRECATED/OBSOLETED - please use adsl2plus 238 instead)
+                   macSecControlledIF (231), -- MACSecControlled 
+                   macSecUncontrolledIF (232), -- MACSecUncontrolled
+                   aviciOpticalEther (233), -- Avici Optical Ethernet Aggregate
+                   atmbond (234), -- atmbond
+                   voiceFGDOS (235), -- voice FGD Operator Services
+                   mocaVersion1 (236), -- MultiMedia over Coax Alliance (MoCA) Interface
+                             -- as documented in information provided privately to IANA
+                   ieee80216WMAN (237), -- IEEE 802.16 WMAN interface
+                   adsl2plus (238), -- Asymmetric Digital Subscriber Loop Version 2, 
+                                   -- Version 2 Plus and all variants
+                   dvbRcsMacLayer (239), -- DVB-RCS MAC Layer
+                   dvbTdm (240), -- DVB Satellite TDM
+                   dvbRcsTdma (241), -- DVB-RCS TDMA
+                   x86Laps (242), -- LAPS based on ITU-T X.86/Y.1323
+                   wwanPP (243), -- 3GPP WWAN
+                   wwanPP2 (244) -- 3GPP2 WWAN
+                   }
+
+IANAtunnelType ::= TEXTUAL-CONVENTION
+    STATUS     current
+    DESCRIPTION
+            "The encapsulation method used by a tunnel. The value
+            direct indicates that a packet is encapsulated
+            directly within a normal IP header, with no
+            intermediate header, and unicast to the remote tunnel
+            endpoint (e.g., an RFC 2003 IP-in-IP tunnel, or an RFC
+            1933 IPv6-in-IPv4 tunnel). The value minimal indicates
+            that a Minimal Forwarding Header (RFC 2004) is
+            inserted between the outer header and the payload
+            packet. The value UDP indicates that the payload
+            packet is encapsulated within a normal UDP packet
+            (e.g., RFC 1234).
+
+            The values sixToFour, sixOverFour, and isatap
+            indicates that an IPv6 packet is encapsulated directly
+            within an IPv4 header, with no intermediate header,
+            and unicast to the destination determined by the 6to4,
+            6over4, or ISATAP protocol.
+
+            The remaining protocol-specific values indicate that a
+            header of the protocol of that name is inserted
+            between the outer header and the payload header.
+
+            The assignment policy for IANAtunnelType values is
+            identical to the policy for assigning IANAifType
+            values."
+    SYNTAX     INTEGER {
+                   other(1),        -- none of the following
+                   direct(2),       -- no intermediate header
+                   gre(3),          -- GRE encapsulation
+                   minimal(4),      -- Minimal encapsulation
+                   l2tp(5),         -- L2TP encapsulation
+                   pptp(6),         -- PPTP encapsulation
+                   l2f(7),          -- L2F encapsulation
+                   udp(8),          -- UDP encapsulation
+                   atmp(9),         -- ATMP encapsulation
+                   msdp(10),        -- MSDP encapsulation
+                   sixToFour(11),   -- 6to4 encapsulation
+                   sixOverFour(12), -- 6over4 encapsulation
+                   isatap(13),      -- ISATAP encapsulation
+                   teredo(14)       -- Teredo encapsulation
+               }
+
+   END
+
+
+
+
+
+
+
+
+
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/Mibs/IF-MIB
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/Mibs/IF-MIB	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/Mibs/IF-MIB	(revision 457)
@@ -0,0 +1,1899 @@
+IF-MIB DEFINITIONS ::= BEGIN
+
+IMPORTS
+    MODULE-IDENTITY, OBJECT-TYPE, Counter32, Gauge32, Counter64,
+    Integer32, TimeTicks, mib-2,
+    NOTIFICATION-TYPE                        FROM SNMPv2-SMI
+    TEXTUAL-CONVENTION, DisplayString,
+    PhysAddress, TruthValue, RowStatus,
+    TimeStamp, AutonomousType, TestAndIncr   FROM SNMPv2-TC
+    MODULE-COMPLIANCE, OBJECT-GROUP,
+    NOTIFICATION-GROUP                       FROM SNMPv2-CONF
+    snmpTraps                                FROM SNMPv2-MIB
+    IANAifType                               FROM IANAifType-MIB;
+
+
+ifMIB MODULE-IDENTITY
+    LAST-UPDATED "200006140000Z"
+    ORGANIZATION "IETF Interfaces MIB Working Group"
+    CONTACT-INFO
+            "   Keith McCloghrie
+                Cisco Systems, Inc.
+                170 West Tasman Drive
+                San Jose, CA  95134-1706
+                US
+
+                408-526-5260
+                kzm@cisco.com"
+    DESCRIPTION
+            "The MIB module to describe generic objects for network
+            interface sub-layers.  This MIB is an updated version of
+            MIB-II's ifTable, and incorporates the extensions defined in
+            RFC 1229."
+
+
+    REVISION      "200006140000Z"
+    DESCRIPTION
+            "Clarifications agreed upon by the Interfaces MIB WG, and
+            published as RFC 2863."
+    REVISION      "199602282155Z"
+    DESCRIPTION
+            "Revisions made by the Interfaces MIB WG, and published in
+            RFC 2233."
+    REVISION      "199311082155Z"
+    DESCRIPTION
+            "Initial revision, published as part of RFC 1573."
+    ::= { mib-2 31 }
+
+
+ifMIBObjects OBJECT IDENTIFIER ::= { ifMIB 1 }
+
+interfaces   OBJECT IDENTIFIER ::= { mib-2 2 }
+
+--
+-- Textual Conventions
+--
+
+
+-- OwnerString has the same semantics as used in RFC 1271
+
+OwnerString ::= TEXTUAL-CONVENTION
+    DISPLAY-HINT "255a"
+    STATUS       deprecated
+    DESCRIPTION
+            "This data type is used to model an administratively
+            assigned name of the owner of a resource.  This information
+            is taken from the NVT ASCII character set.  It is suggested
+            that this name contain one or more of the following: ASCII
+            form of the manager station's transport address, management
+            station name (e.g., domain name), network management
+            personnel's name, location, or phone number.  In some cases
+            the agent itself will be the owner of an entry.  In these
+            cases, this string shall be set to a string starting with
+            'agent'."
+    SYNTAX       OCTET STRING (SIZE(0..255))
+
+-- InterfaceIndex contains the semantics of ifIndex and should be used
+-- for any objects defined in other MIB modules that need these semantics.
+
+InterfaceIndex ::= TEXTUAL-CONVENTION
+    DISPLAY-HINT "d"
+    STATUS       current
+    DESCRIPTION
+
+
+            "A unique value, greater than zero, for each interface or
+            interface sub-layer in the managed system.  It is
+            recommended that values are assigned contiguously starting
+            from 1.  The value for each interface sub-layer must remain
+            constant at least from one re-initialization of the entity's
+            network management system to the next re-initialization."
+    SYNTAX       Integer32 (1..2147483647)
+
+InterfaceIndexOrZero ::= TEXTUAL-CONVENTION
+    DISPLAY-HINT "d"
+    STATUS       current
+    DESCRIPTION
+            "This textual convention is an extension of the
+            InterfaceIndex convention.  The latter defines a greater
+            than zero value used to identify an interface or interface
+            sub-layer in the managed system.  This extension permits the
+            additional value of zero.  the value zero is object-specific
+            and must therefore be defined as part of the description of
+            any object which uses this syntax.  Examples of the usage of
+            zero might include situations where interface was unknown,
+            or when none or all interfaces need to be referenced."
+    SYNTAX       Integer32 (0..2147483647)
+
+ifNumber  OBJECT-TYPE
+    SYNTAX      Integer32
+    MAX-ACCESS  read-only
+    STATUS      current
+    DESCRIPTION
+            "The number of network interfaces (regardless of their
+            current state) present on this system."
+    ::= { interfaces 1 }
+
+ifTableLastChange  OBJECT-TYPE
+    SYNTAX      TimeTicks
+    MAX-ACCESS  read-only
+    STATUS      current
+    DESCRIPTION
+            "The value of sysUpTime at the time of the last creation or
+            deletion of an entry in the ifTable.  If the number of
+            entries has been unchanged since the last re-initialization
+            of the local network management subsystem, then this object
+            contains a zero value."
+    ::= { ifMIBObjects 5 }
+
+
+-- the Interfaces table
+
+-- The Interfaces table contains information on the entity's
+
+
+-- interfaces.  Each sub-layer below the internetwork-layer
+-- of a network interface is considered to be an interface.
+
+ifTable OBJECT-TYPE
+    SYNTAX      SEQUENCE OF IfEntry
+    MAX-ACCESS  not-accessible
+    STATUS      current
+    DESCRIPTION
+            "A list of interface entries.  The number of entries is
+            given by the value of ifNumber."
+    ::= { interfaces 2 }
+
+ifEntry OBJECT-TYPE
+    SYNTAX      IfEntry
+    MAX-ACCESS  not-accessible
+    STATUS      current
+    DESCRIPTION
+            "An entry containing management information applicable to a
+            particular interface."
+    INDEX   { ifIndex }
+    ::= { ifTable 1 }
+
+IfEntry ::=
+    SEQUENCE {
+        ifIndex                 InterfaceIndex,
+        ifDescr                 DisplayString,
+        ifType                  IANAifType,
+        ifMtu                   Integer32,
+        ifSpeed                 Gauge32,
+        ifPhysAddress           PhysAddress,
+        ifAdminStatus           INTEGER,
+        ifOperStatus            INTEGER,
+        ifLastChange            TimeTicks,
+        ifInOctets              Counter32,
+        ifInUcastPkts           Counter32,
+        ifInNUcastPkts          Counter32,  -- deprecated
+        ifInDiscards            Counter32,
+        ifInErrors              Counter32,
+        ifInUnknownProtos       Counter32,
+        ifOutOctets             Counter32,
+        ifOutUcastPkts          Counter32,
+        ifOutNUcastPkts         Counter32,  -- deprecated
+        ifOutDiscards           Counter32,
+        ifOutErrors             Counter32,
+        ifOutQLen               Gauge32,    -- deprecated
+        ifSpecific              OBJECT IDENTIFIER -- deprecated
+    }
+
+
+
+ifIndex OBJECT-TYPE
+    SYNTAX      InterfaceIndex
+    MAX-ACCESS  read-only
+    STATUS      current
+    DESCRIPTION
+            "A unique value, greater than zero, for each interface.  It
+            is recommended that values are assigned contiguously
+            starting from 1.  The value for each interface sub-layer
+            must remain constant at least from one re-initialization of
+            the entity's network management system to the next re-
+            initialization."
+    ::= { ifEntry 1 }
+
+ifDescr OBJECT-TYPE
+    SYNTAX      DisplayString (SIZE (0..255))
+    MAX-ACCESS  read-only
+    STATUS      current
+    DESCRIPTION
+            "A textual string containing information about the
+            interface.  This string should include the name of the
+            manufacturer, the product name and the version of the
+            interface hardware/software."
+    ::= { ifEntry 2 }
+
+ifType OBJECT-TYPE
+    SYNTAX      IANAifType
+    MAX-ACCESS  read-only
+    STATUS      current
+    DESCRIPTION
+            "The type of interface.  Additional values for ifType are
+            assigned by the Internet Assigned Numbers Authority (IANA),
+            through updating the syntax of the IANAifType textual
+            convention."
+    ::= { ifEntry 3 }
+
+ifMtu OBJECT-TYPE
+    SYNTAX      Integer32
+    MAX-ACCESS  read-only
+    STATUS      current
+    DESCRIPTION
+            "The size of the largest packet which can be sent/received
+            on the interface, specified in octets.  For interfaces that
+            are used for transmitting network datagrams, this is the
+            size of the largest network datagram that can be sent on the
+            interface."
+    ::= { ifEntry 4 }
+
+ifSpeed OBJECT-TYPE
+
+
+    SYNTAX      Gauge32
+    MAX-ACCESS  read-only
+    STATUS      current
+    DESCRIPTION
+            "An estimate of the interface's current bandwidth in bits
+            per second.  For interfaces which do not vary in bandwidth
+            or for those where no accurate estimation can be made, this
+            object should contain the nominal bandwidth.  If the
+            bandwidth of the interface is greater than the maximum value
+            reportable by this object then this object should report its
+            maximum value (4,294,967,295) and ifHighSpeed must be used
+            to report the interace's speed.  For a sub-layer which has
+            no concept of bandwidth, this object should be zero."
+    ::= { ifEntry 5 }
+
+ifPhysAddress OBJECT-TYPE
+    SYNTAX      PhysAddress
+    MAX-ACCESS  read-only
+    STATUS      current
+    DESCRIPTION
+            "The interface's address at its protocol sub-layer.  For
+            example, for an 802.x interface, this object normally
+            contains a MAC address.  The interface's media-specific MIB
+            must define the bit and byte ordering and the format of the
+            value of this object.  For interfaces which do not have such
+            an address (e.g., a serial line), this object should contain
+            an octet string of zero length."
+    ::= { ifEntry 6 }
+
+ifAdminStatus OBJECT-TYPE
+    SYNTAX  INTEGER {
+                up(1),       -- ready to pass packets
+                down(2),
+                testing(3)   -- in some test mode
+            }
+    MAX-ACCESS  read-write
+    STATUS      current
+    DESCRIPTION
+            "The desired state of the interface.  The testing(3) state
+            indicates that no operational packets can be passed.  When a
+            managed system initializes, all interfaces start with
+            ifAdminStatus in the down(2) state.  As a result of either
+            explicit management action or per configuration information
+            retained by the managed system, ifAdminStatus is then
+            changed to either the up(1) or testing(3) states (or remains
+            in the down(2) state)."
+    ::= { ifEntry 7 }
+
+
+
+ifOperStatus OBJECT-TYPE
+    SYNTAX  INTEGER {
+                up(1),        -- ready to pass packets
+                down(2),
+                testing(3),   -- in some test mode
+                unknown(4),   -- status can not be determined
+                              -- for some reason.
+                dormant(5),
+                notPresent(6),    -- some component is missing
+                lowerLayerDown(7) -- down due to state of
+                                  -- lower-layer interface(s)
+            }
+    MAX-ACCESS  read-only
+    STATUS      current
+    DESCRIPTION
+            "The current operational state of the interface.  The
+            testing(3) state indicates that no operational packets can
+            be passed.  If ifAdminStatus is down(2) then ifOperStatus
+            should be down(2).  If ifAdminStatus is changed to up(1)
+            then ifOperStatus should change to up(1) if the interface is
+            ready to transmit and receive network traffic; it should
+            change to dormant(5) if the interface is waiting for
+            external actions (such as a serial line waiting for an
+            incoming connection); it should remain in the down(2) state
+            if and only if there is a fault that prevents it from going
+            to the up(1) state; it should remain in the notPresent(6)
+            state if the interface has missing (typically, hardware)
+            components."
+    ::= { ifEntry 8 }
+
+ifLastChange OBJECT-TYPE
+    SYNTAX      TimeTicks
+    MAX-ACCESS  read-only
+    STATUS      current
+    DESCRIPTION
+            "The value of sysUpTime at the time the interface entered
+            its current operational state.  If the current state was
+            entered prior to the last re-initialization of the local
+            network management subsystem, then this object contains a
+            zero value."
+    ::= { ifEntry 9 }
+
+ifInOctets OBJECT-TYPE
+    SYNTAX      Counter32
+    MAX-ACCESS  read-only
+    STATUS      current
+    DESCRIPTION
+            "The total number of octets received on the interface,
+
+
+            including framing characters.
+
+            Discontinuities in the value of this counter can occur at
+            re-initialization of the management system, and at other
+            times as indicated by the value of
+            ifCounterDiscontinuityTime."
+    ::= { ifEntry 10 }
+
+ifInUcastPkts OBJECT-TYPE
+    SYNTAX      Counter32
+    MAX-ACCESS  read-only
+    STATUS      current
+    DESCRIPTION
+            "The number of packets, delivered by this sub-layer to a
+            higher (sub-)layer, which were not addressed to a multicast
+            or broadcast address at this sub-layer.
+
+            Discontinuities in the value of this counter can occur at
+            re-initialization of the management system, and at other
+            times as indicated by the value of
+            ifCounterDiscontinuityTime."
+    ::= { ifEntry 11 }
+
+ifInNUcastPkts OBJECT-TYPE
+    SYNTAX  Counter32
+    MAX-ACCESS  read-only
+    STATUS      deprecated
+    DESCRIPTION
+            "The number of packets, delivered by this sub-layer to a
+            higher (sub-)layer, which were addressed to a multicast or
+            broadcast address at this sub-layer.
+
+            Discontinuities in the value of this counter can occur at
+            re-initialization of the management system, and at other
+            times as indicated by the value of
+            ifCounterDiscontinuityTime.
+
+            This object is deprecated in favour of ifInMulticastPkts and
+            ifInBroadcastPkts."
+    ::= { ifEntry 12 }
+
+ifInDiscards OBJECT-TYPE
+    SYNTAX      Counter32
+    MAX-ACCESS  read-only
+    STATUS      current
+    DESCRIPTION
+            "The number of inbound packets which were chosen to be
+            discarded even though no errors had been detected to prevent
+
+
+            their being deliverable to a higher-layer protocol.  One
+            possible reason for discarding such a packet could be to
+            free up buffer space.
+
+            Discontinuities in the value of this counter can occur at
+            re-initialization of the management system, and at other
+            times as indicated by the value of
+            ifCounterDiscontinuityTime."
+    ::= { ifEntry 13 }
+
+ifInErrors OBJECT-TYPE
+    SYNTAX      Counter32
+    MAX-ACCESS  read-only
+    STATUS      current
+    DESCRIPTION
+            "For packet-oriented interfaces, the number of inbound
+            packets that contained errors preventing them from being
+            deliverable to a higher-layer protocol.  For character-
+            oriented or fixed-length interfaces, the number of inbound
+            transmission units that contained errors preventing them
+            from being deliverable to a higher-layer protocol.
+
+            Discontinuities in the value of this counter can occur at
+            re-initialization of the management system, and at other
+            times as indicated by the value of
+            ifCounterDiscontinuityTime."
+    ::= { ifEntry 14 }
+
+ifInUnknownProtos OBJECT-TYPE
+    SYNTAX      Counter32
+    MAX-ACCESS  read-only
+    STATUS      current
+    DESCRIPTION
+            "For packet-oriented interfaces, the number of packets
+            received via the interface which were discarded because of
+            an unknown or unsupported protocol.  For character-oriented
+            or fixed-length interfaces that support protocol
+            multiplexing the number of transmission units received via
+            the interface which were discarded because of an unknown or
+            unsupported protocol.  For any interface that does not
+            support protocol multiplexing, this counter will always be
+            0.
+
+            Discontinuities in the value of this counter can occur at
+            re-initialization of the management system, and at other
+            times as indicated by the value of
+            ifCounterDiscontinuityTime."
+    ::= { ifEntry 15 }
+
+
+ifOutOctets OBJECT-TYPE
+    SYNTAX      Counter32
+    MAX-ACCESS  read-only
+    STATUS      current
+    DESCRIPTION
+            "The total number of octets transmitted out of the
+            interface, including framing characters.
+
+            Discontinuities in the value of this counter can occur at
+            re-initialization of the management system, and at other
+            times as indicated by the value of
+            ifCounterDiscontinuityTime."
+    ::= { ifEntry 16 }
+
+ifOutUcastPkts OBJECT-TYPE
+    SYNTAX      Counter32
+    MAX-ACCESS  read-only
+    STATUS      current
+    DESCRIPTION
+            "The total number of packets that higher-level protocols
+            requested be transmitted, and which were not addressed to a
+            multicast or broadcast address at this sub-layer, including
+            those that were discarded or not sent.
+
+            Discontinuities in the value of this counter can occur at
+            re-initialization of the management system, and at other
+            times as indicated by the value of
+            ifCounterDiscontinuityTime."
+    ::= { ifEntry 17 }
+
+ifOutNUcastPkts OBJECT-TYPE
+    SYNTAX      Counter32
+    MAX-ACCESS  read-only
+    STATUS      deprecated
+    DESCRIPTION
+            "The total number of packets that higher-level protocols
+            requested be transmitted, and which were addressed to a
+            multicast or broadcast address at this sub-layer, including
+            those that were discarded or not sent.
+
+            Discontinuities in the value of this counter can occur at
+            re-initialization of the management system, and at other
+            times as indicated by the value of
+            ifCounterDiscontinuityTime.
+
+            This object is deprecated in favour of ifOutMulticastPkts
+            and ifOutBroadcastPkts."
+    ::= { ifEntry 18 }
+
+
+ifOutDiscards OBJECT-TYPE
+    SYNTAX      Counter32
+    MAX-ACCESS  read-only
+    STATUS      current
+    DESCRIPTION
+            "The number of outbound packets which were chosen to be
+            discarded even though no errors had been detected to prevent
+            their being transmitted.  One possible reason for discarding
+            such a packet could be to free up buffer space.
+
+            Discontinuities in the value of this counter can occur at
+            re-initialization of the management system, and at other
+            times as indicated by the value of
+            ifCounterDiscontinuityTime."
+    ::= { ifEntry 19 }
+
+ifOutErrors OBJECT-TYPE
+    SYNTAX      Counter32
+    MAX-ACCESS  read-only
+    STATUS      current
+    DESCRIPTION
+            "For packet-oriented interfaces, the number of outbound
+            packets that could not be transmitted because of errors.
+            For character-oriented or fixed-length interfaces, the
+            number of outbound transmission units that could not be
+            transmitted because of errors.
+
+            Discontinuities in the value of this counter can occur at
+            re-initialization of the management system, and at other
+            times as indicated by the value of
+            ifCounterDiscontinuityTime."
+    ::= { ifEntry 20 }
+
+ifOutQLen OBJECT-TYPE
+    SYNTAX      Gauge32
+    MAX-ACCESS  read-only
+    STATUS      deprecated
+    DESCRIPTION
+            "The length of the output packet queue (in packets)."
+    ::= { ifEntry 21 }
+
+ifSpecific OBJECT-TYPE
+    SYNTAX      OBJECT IDENTIFIER
+    MAX-ACCESS  read-only
+    STATUS      deprecated
+    DESCRIPTION
+            "A reference to MIB definitions specific to the particular
+            media being used to realize the interface.  It is
+
+
+            recommended that this value point to an instance of a MIB
+            object in the media-specific MIB, i.e., that this object
+            have the semantics associated with the InstancePointer
+            textual convention defined in RFC 2579.  In fact, it is
+            recommended that the media-specific MIB specify what value
+            ifSpecific should/can take for values of ifType.  If no MIB
+            definitions specific to the particular media are available,
+            the value should be set to the OBJECT IDENTIFIER { 0 0 }."
+    ::= { ifEntry 22 }
+
+
+
+--
+--   Extension to the interface table
+--
+-- This table replaces the ifExtnsTable table.
+--
+
+ifXTable        OBJECT-TYPE
+    SYNTAX      SEQUENCE OF IfXEntry
+    MAX-ACCESS  not-accessible
+    STATUS      current
+    DESCRIPTION
+            "A list of interface entries.  The number of entries is
+            given by the value of ifNumber.  This table contains
+            additional objects for the interface table."
+    ::= { ifMIBObjects 1 }
+
+ifXEntry        OBJECT-TYPE
+    SYNTAX      IfXEntry
+    MAX-ACCESS  not-accessible
+    STATUS      current
+    DESCRIPTION
+            "An entry containing additional management information
+            applicable to a particular interface."
+    AUGMENTS    { ifEntry }
+    ::= { ifXTable 1 }
+
+IfXEntry ::=
+    SEQUENCE {
+        ifName                  DisplayString,
+        ifInMulticastPkts       Counter32,
+        ifInBroadcastPkts       Counter32,
+        ifOutMulticastPkts      Counter32,
+        ifOutBroadcastPkts      Counter32,
+        ifHCInOctets            Counter64,
+        ifHCInUcastPkts         Counter64,
+        ifHCInMulticastPkts     Counter64,
+
+
+        ifHCInBroadcastPkts     Counter64,
+        ifHCOutOctets           Counter64,
+        ifHCOutUcastPkts        Counter64,
+        ifHCOutMulticastPkts    Counter64,
+        ifHCOutBroadcastPkts    Counter64,
+        ifLinkUpDownTrapEnable  INTEGER,
+        ifHighSpeed             Gauge32,
+        ifPromiscuousMode       TruthValue,
+        ifConnectorPresent      TruthValue,
+        ifAlias                 DisplayString,
+        ifCounterDiscontinuityTime TimeStamp
+    }
+
+
+ifName OBJECT-TYPE
+    SYNTAX      DisplayString
+    MAX-ACCESS  read-only
+    STATUS      current
+    DESCRIPTION
+            "The textual name of the interface.  The value of this
+            object should be the name of the interface as assigned by
+            the local device and should be suitable for use in commands
+            entered at the device's `console'.  This might be a text
+            name, such as `le0' or a simple port number, such as `1',
+            depending on the interface naming syntax of the device.  If
+            several entries in the ifTable together represent a single
+            interface as named by the device, then each will have the
+            same value of ifName.  Note that for an agent which responds
+            to SNMP queries concerning an interface on some other
+            (proxied) device, then the value of ifName for such an
+            interface is the proxied device's local name for it.
+
+            If there is no local name, or this object is otherwise not
+            applicable, then this object contains a zero-length string."
+    ::= { ifXEntry 1 }
+
+ifInMulticastPkts OBJECT-TYPE
+    SYNTAX      Counter32
+    MAX-ACCESS  read-only
+    STATUS      current
+    DESCRIPTION
+            "The number of packets, delivered by this sub-layer to a
+            higher (sub-)layer, which were addressed to a multicast
+            address at this sub-layer.  For a MAC layer protocol, this
+            includes both Group and Functional addresses.
+
+            Discontinuities in the value of this counter can occur at
+            re-initialization of the management system, and at other
+
+
+            times as indicated by the value of
+            ifCounterDiscontinuityTime."
+    ::= { ifXEntry 2 }
+
+ifInBroadcastPkts OBJECT-TYPE
+    SYNTAX      Counter32
+    MAX-ACCESS  read-only
+    STATUS      current
+    DESCRIPTION
+            "The number of packets, delivered by this sub-layer to a
+            higher (sub-)layer, which were addressed to a broadcast
+            address at this sub-layer.
+
+            Discontinuities in the value of this counter can occur at
+            re-initialization of the management system, and at other
+            times as indicated by the value of
+            ifCounterDiscontinuityTime."
+    ::= { ifXEntry 3 }
+
+ifOutMulticastPkts OBJECT-TYPE
+    SYNTAX      Counter32
+    MAX-ACCESS  read-only
+    STATUS      current
+    DESCRIPTION
+            "The total number of packets that higher-level protocols
+            requested be transmitted, and which were addressed to a
+            multicast address at this sub-layer, including those that
+            were discarded or not sent.  For a MAC layer protocol, this
+            includes both Group and Functional addresses.
+
+            Discontinuities in the value of this counter can occur at
+            re-initialization of the management system, and at other
+            times as indicated by the value of
+            ifCounterDiscontinuityTime."
+    ::= { ifXEntry 4 }
+
+ifOutBroadcastPkts OBJECT-TYPE
+    SYNTAX      Counter32
+    MAX-ACCESS  read-only
+    STATUS      current
+    DESCRIPTION
+            "The total number of packets that higher-level protocols
+            requested be transmitted, and which were addressed to a
+            broadcast address at this sub-layer, including those that
+            were discarded or not sent.
+
+            Discontinuities in the value of this counter can occur at
+            re-initialization of the management system, and at other
+
+
+            times as indicated by the value of
+            ifCounterDiscontinuityTime."
+    ::= { ifXEntry 5 }
+
+--
+-- High Capacity Counter objects.  These objects are all
+-- 64 bit versions of the "basic" ifTable counters.  These
+-- objects all have the same basic semantics as their 32-bit
+-- counterparts, however, their syntax has been extended
+-- to 64 bits.
+--
+
+ifHCInOctets OBJECT-TYPE
+    SYNTAX      Counter64
+    MAX-ACCESS  read-only
+    STATUS      current
+    DESCRIPTION
+            "The total number of octets received on the interface,
+            including framing characters.  This object is a 64-bit
+            version of ifInOctets.
+
+            Discontinuities in the value of this counter can occur at
+            re-initialization of the management system, and at other
+            times as indicated by the value of
+            ifCounterDiscontinuityTime."
+    ::= { ifXEntry 6 }
+
+ifHCInUcastPkts OBJECT-TYPE
+    SYNTAX      Counter64
+    MAX-ACCESS  read-only
+    STATUS      current
+    DESCRIPTION
+            "The number of packets, delivered by this sub-layer to a
+            higher (sub-)layer, which were not addressed to a multicast
+            or broadcast address at this sub-layer.  This object is a
+            64-bit version of ifInUcastPkts.
+
+            Discontinuities in the value of this counter can occur at
+            re-initialization of the management system, and at other
+            times as indicated by the value of
+            ifCounterDiscontinuityTime."
+    ::= { ifXEntry 7 }
+
+ifHCInMulticastPkts OBJECT-TYPE
+    SYNTAX      Counter64
+    MAX-ACCESS  read-only
+    STATUS      current
+    DESCRIPTION
+
+
+            "The number of packets, delivered by this sub-layer to a
+            higher (sub-)layer, which were addressed to a multicast
+            address at this sub-layer.  For a MAC layer protocol, this
+            includes both Group and Functional addresses.  This object
+            is a 64-bit version of ifInMulticastPkts.
+
+            Discontinuities in the value of this counter can occur at
+            re-initialization of the management system, and at other
+            times as indicated by the value of
+            ifCounterDiscontinuityTime."
+    ::= { ifXEntry 8 }
+
+ifHCInBroadcastPkts OBJECT-TYPE
+    SYNTAX      Counter64
+    MAX-ACCESS  read-only
+    STATUS      current
+    DESCRIPTION
+            "The number of packets, delivered by this sub-layer to a
+            higher (sub-)layer, which were addressed to a broadcast
+            address at this sub-layer.  This object is a 64-bit version
+            of ifInBroadcastPkts.
+
+            Discontinuities in the value of this counter can occur at
+            re-initialization of the management system, and at other
+            times as indicated by the value of
+            ifCounterDiscontinuityTime."
+    ::= { ifXEntry 9 }
+
+ifHCOutOctets OBJECT-TYPE
+    SYNTAX      Counter64
+    MAX-ACCESS  read-only
+    STATUS      current
+    DESCRIPTION
+            "The total number of octets transmitted out of the
+            interface, including framing characters.  This object is a
+            64-bit version of ifOutOctets.
+
+            Discontinuities in the value of this counter can occur at
+            re-initialization of the management system, and at other
+            times as indicated by the value of
+            ifCounterDiscontinuityTime."
+    ::= { ifXEntry 10 }
+
+ifHCOutUcastPkts OBJECT-TYPE
+    SYNTAX      Counter64
+    MAX-ACCESS  read-only
+    STATUS      current
+    DESCRIPTION
+
+
+            "The total number of packets that higher-level protocols
+            requested be transmitted, and which were not addressed to a
+            multicast or broadcast address at this sub-layer, including
+            those that were discarded or not sent.  This object is a
+            64-bit version of ifOutUcastPkts.
+
+            Discontinuities in the value of this counter can occur at
+            re-initialization of the management system, and at other
+            times as indicated by the value of
+            ifCounterDiscontinuityTime."
+    ::= { ifXEntry 11 }
+
+ifHCOutMulticastPkts OBJECT-TYPE
+    SYNTAX      Counter64
+    MAX-ACCESS  read-only
+    STATUS      current
+    DESCRIPTION
+            "The total number of packets that higher-level protocols
+            requested be transmitted, and which were addressed to a
+            multicast address at this sub-layer, including those that
+            were discarded or not sent.  For a MAC layer protocol, this
+            includes both Group and Functional addresses.  This object
+            is a 64-bit version of ifOutMulticastPkts.
+
+            Discontinuities in the value of this counter can occur at
+            re-initialization of the management system, and at other
+            times as indicated by the value of
+            ifCounterDiscontinuityTime."
+    ::= { ifXEntry 12 }
+
+ifHCOutBroadcastPkts OBJECT-TYPE
+    SYNTAX      Counter64
+    MAX-ACCESS  read-only
+    STATUS      current
+    DESCRIPTION
+            "The total number of packets that higher-level protocols
+            requested be transmitted, and which were addressed to a
+            broadcast address at this sub-layer, including those that
+            were discarded or not sent.  This object is a 64-bit version
+            of ifOutBroadcastPkts.
+
+            Discontinuities in the value of this counter can occur at
+            re-initialization of the management system, and at other
+            times as indicated by the value of
+            ifCounterDiscontinuityTime."
+    ::= { ifXEntry 13 }
+
+ifLinkUpDownTrapEnable  OBJECT-TYPE
+
+
+    SYNTAX      INTEGER { enabled(1), disabled(2) }
+    MAX-ACCESS  read-write
+    STATUS      current
+    DESCRIPTION
+            "Indicates whether linkUp/linkDown traps should be generated
+            for this interface.
+
+            By default, this object should have the value enabled(1) for
+            interfaces which do not operate on 'top' of any other
+            interface (as defined in the ifStackTable), and disabled(2)
+            otherwise."
+    ::= { ifXEntry 14 }
+
+ifHighSpeed OBJECT-TYPE
+    SYNTAX      Gauge32
+    MAX-ACCESS  read-only
+    STATUS      current
+    DESCRIPTION
+            "An estimate of the interface's current bandwidth in units
+            of 1,000,000 bits per second.  If this object reports a
+            value of `n' then the speed of the interface is somewhere in
+            the range of `n-500,000' to `n+499,999'.  For interfaces
+            which do not vary in bandwidth or for those where no
+            accurate estimation can be made, this object should contain
+            the nominal bandwidth.  For a sub-layer which has no concept
+            of bandwidth, this object should be zero."
+    ::= { ifXEntry 15 }
+
+ifPromiscuousMode  OBJECT-TYPE
+    SYNTAX      TruthValue
+    MAX-ACCESS  read-write
+    STATUS      current
+    DESCRIPTION
+            "This object has a value of false(2) if this interface only
+            accepts packets/frames that are addressed to this station.
+            This object has a value of true(1) when the station accepts
+            all packets/frames transmitted on the media.  The value
+            true(1) is only legal on certain types of media.  If legal,
+            setting this object to a value of true(1) may require the
+            interface to be reset before becoming effective.
+
+            The value of ifPromiscuousMode does not affect the reception
+            of broadcast and multicast packets/frames by the interface."
+    ::= { ifXEntry 16 }
+
+ifConnectorPresent   OBJECT-TYPE
+    SYNTAX      TruthValue
+    MAX-ACCESS  read-only
+
+
+    STATUS      current
+    DESCRIPTION
+            "This object has the value 'true(1)' if the interface
+            sublayer has a physical connector and the value 'false(2)'
+            otherwise."
+    ::= { ifXEntry 17 }
+
+ifAlias   OBJECT-TYPE
+    SYNTAX      DisplayString (SIZE(0..64))
+    MAX-ACCESS  read-write
+    STATUS      current
+    DESCRIPTION
+            "This object is an 'alias' name for the interface as
+            specified by a network manager, and provides a non-volatile
+            'handle' for the interface.
+
+            On the first instantiation of an interface, the value of
+            ifAlias associated with that interface is the zero-length
+            string.  As and when a value is written into an instance of
+            ifAlias through a network management set operation, then the
+            agent must retain the supplied value in the ifAlias instance
+            associated with the same interface for as long as that
+            interface remains instantiated, including across all re-
+            initializations/reboots of the network management system,
+            including those which result in a change of the interface's
+            ifIndex value.
+
+            An example of the value which a network manager might store
+            in this object for a WAN interface is the (Telco's) circuit
+            number/identifier of the interface.
+
+            Some agents may support write-access only for interfaces
+            having particular values of ifType.  An agent which supports
+            write access to this object is required to keep the value in
+            non-volatile storage, but it may limit the length of new
+            values depending on how much storage is already occupied by
+            the current values for other interfaces."
+    ::= { ifXEntry 18 }
+
+ifCounterDiscontinuityTime OBJECT-TYPE
+    SYNTAX      TimeStamp
+    MAX-ACCESS  read-only
+    STATUS      current
+    DESCRIPTION
+            "The value of sysUpTime on the most recent occasion at which
+            any one or more of this interface's counters suffered a
+            discontinuity.  The relevant counters are the specific
+            instances associated with this interface of any Counter32 or
+
+
+            Counter64 object contained in the ifTable or ifXTable.  If
+            no such discontinuities have occurred since the last re-
+            initialization of the local management subsystem, then this
+            object contains a zero value."
+    ::= { ifXEntry 19 }
+
+--           The Interface Stack Group
+--
+-- Implementation of this group is optional, but strongly recommended
+-- for all systems
+--
+
+ifStackTable  OBJECT-TYPE
+     SYNTAX        SEQUENCE OF IfStackEntry
+     MAX-ACCESS    not-accessible
+     STATUS        current
+     DESCRIPTION
+            "The table containing information on the relationships
+            between the multiple sub-layers of network interfaces.  In
+            particular, it contains information on which sub-layers run
+            'on top of' which other sub-layers, where each sub-layer
+            corresponds to a conceptual row in the ifTable.  For
+            example, when the sub-layer with ifIndex value x runs over
+            the sub-layer with ifIndex value y, then this table
+            contains:
+
+              ifStackStatus.x.y=active
+
+            For each ifIndex value, I, which identifies an active
+            interface, there are always at least two instantiated rows
+            in this table associated with I.  For one of these rows, I
+            is the value of ifStackHigherLayer; for the other, I is the
+            value of ifStackLowerLayer.  (If I is not involved in
+            multiplexing, then these are the only two rows associated
+            with I.)
+
+            For example, two rows exist even for an interface which has
+            no others stacked on top or below it:
+
+              ifStackStatus.0.x=active
+              ifStackStatus.x.0=active "
+     ::= { ifMIBObjects 2 }
+
+
+ifStackEntry  OBJECT-TYPE
+     SYNTAX        IfStackEntry
+     MAX-ACCESS    not-accessible
+     STATUS        current
+
+
+     DESCRIPTION
+            "Information on a particular relationship between two sub-
+            layers, specifying that one sub-layer runs on 'top' of the
+            other sub-layer.  Each sub-layer corresponds to a conceptual
+            row in the ifTable."
+     INDEX { ifStackHigherLayer, ifStackLowerLayer }
+     ::= { ifStackTable 1 }
+
+
+IfStackEntry ::=
+    SEQUENCE {
+        ifStackHigherLayer  InterfaceIndexOrZero,
+        ifStackLowerLayer   InterfaceIndexOrZero,
+        ifStackStatus       RowStatus
+     }
+
+
+ifStackHigherLayer  OBJECT-TYPE
+     SYNTAX        InterfaceIndexOrZero
+     MAX-ACCESS    not-accessible
+     STATUS        current
+     DESCRIPTION
+            "The value of ifIndex corresponding to the higher sub-layer
+            of the relationship, i.e., the sub-layer which runs on 'top'
+            of the sub-layer identified by the corresponding instance of
+            ifStackLowerLayer.  If there is no higher sub-layer (below
+            the internetwork layer), then this object has the value 0."
+     ::= { ifStackEntry 1 }
+
+
+ifStackLowerLayer  OBJECT-TYPE
+     SYNTAX        InterfaceIndexOrZero
+     MAX-ACCESS    not-accessible
+     STATUS        current
+     DESCRIPTION
+            "The value of ifIndex corresponding to the lower sub-layer
+            of the relationship, i.e., the sub-layer which runs 'below'
+            the sub-layer identified by the corresponding instance of
+            ifStackHigherLayer.  If there is no lower sub-layer, then
+            this object has the value 0."
+     ::= { ifStackEntry 2 }
+
+
+ifStackStatus  OBJECT-TYPE
+    SYNTAX         RowStatus
+    MAX-ACCESS     read-create
+    STATUS         current
+    DESCRIPTION
+
+
+            "The status of the relationship between two sub-layers.
+
+            Changing the value of this object from 'active' to
+            'notInService' or 'destroy' will likely have consequences up
+            and down the interface stack.  Thus, write access to this
+            object is likely to be inappropriate for some types of
+            interfaces, and many implementations will choose not to
+            support write-access for any type of interface."
+    ::= { ifStackEntry 3 }
+
+ifStackLastChange OBJECT-TYPE
+    SYNTAX         TimeTicks
+    MAX-ACCESS     read-only
+    STATUS         current
+    DESCRIPTION
+            "The value of sysUpTime at the time of the last change of
+            the (whole) interface stack.  A change of the interface
+            stack is defined to be any creation, deletion, or change in
+            value of any instance of ifStackStatus.  If the interface
+            stack has been unchanged since the last re-initialization of
+            the local network management subsystem, then this object
+            contains a zero value."
+    ::= { ifMIBObjects 6 }
+
+
+--   Generic Receive Address Table
+--
+-- This group of objects is mandatory for all types of
+-- interfaces which can receive packets/frames addressed to
+-- more than one address.
+--
+-- This table replaces the ifExtnsRcvAddr table.  The main
+-- difference is that this table makes use of the RowStatus
+-- textual convention, while ifExtnsRcvAddr did not.
+
+ifRcvAddressTable  OBJECT-TYPE
+    SYNTAX      SEQUENCE OF IfRcvAddressEntry
+    MAX-ACCESS  not-accessible
+    STATUS      current
+    DESCRIPTION
+            "This table contains an entry for each address (broadcast,
+            multicast, or uni-cast) for which the system will receive
+            packets/frames on a particular interface, except as follows:
+
+            - for an interface operating in promiscuous mode, entries
+            are only required for those addresses for which the system
+            would receive frames were it not operating in promiscuous
+            mode.
+
+
+            - for 802.5 functional addresses, only one entry is
+            required, for the address which has the functional address
+            bit ANDed with the bit mask of all functional addresses for
+            which the interface will accept frames.
+
+            A system is normally able to use any unicast address which
+            corresponds to an entry in this table as a source address."
+    ::= { ifMIBObjects 4 }
+
+ifRcvAddressEntry  OBJECT-TYPE
+    SYNTAX      IfRcvAddressEntry
+    MAX-ACCESS  not-accessible
+    STATUS      current
+    DESCRIPTION
+            "A list of objects identifying an address for which the
+            system will accept packets/frames on the particular
+            interface identified by the index value ifIndex."
+    INDEX  { ifIndex, ifRcvAddressAddress }
+    ::= { ifRcvAddressTable 1 }
+
+IfRcvAddressEntry ::=
+    SEQUENCE {
+        ifRcvAddressAddress   PhysAddress,
+        ifRcvAddressStatus    RowStatus,
+        ifRcvAddressType      INTEGER
+    }
+
+ifRcvAddressAddress OBJECT-TYPE
+    SYNTAX      PhysAddress
+    MAX-ACCESS  not-accessible
+    STATUS      current
+    DESCRIPTION
+            "An address for which the system will accept packets/frames
+            on this entry's interface."
+    ::= { ifRcvAddressEntry 1 }
+
+ifRcvAddressStatus OBJECT-TYPE
+    SYNTAX      RowStatus
+    MAX-ACCESS  read-create
+    STATUS      current
+    DESCRIPTION
+            "This object is used to create and delete rows in the
+            ifRcvAddressTable."
+
+    ::= { ifRcvAddressEntry 2 }
+
+ifRcvAddressType OBJECT-TYPE
+    SYNTAX      INTEGER {
+
+
+                    other(1),
+                    volatile(2),
+                    nonVolatile(3)
+                }
+
+    MAX-ACCESS  read-create
+    STATUS      current
+    DESCRIPTION
+            "This object has the value nonVolatile(3) for those entries
+            in the table which are valid and will not be deleted by the
+            next restart of the managed system.  Entries having the
+            value volatile(2) are valid and exist, but have not been
+            saved, so that will not exist after the next restart of the
+            managed system.  Entries having the value other(1) are valid
+            and exist but are not classified as to whether they will
+            continue to exist after the next restart."
+
+    DEFVAL  { volatile }
+    ::= { ifRcvAddressEntry 3 }
+
+-- definition of interface-related traps.
+
+linkDown NOTIFICATION-TYPE
+    OBJECTS { ifIndex, ifAdminStatus, ifOperStatus }
+    STATUS  current
+    DESCRIPTION
+            "A linkDown trap signifies that the SNMP entity, acting in
+            an agent role, has detected that the ifOperStatus object for
+            one of its communication links is about to enter the down
+            state from some other state (but not from the notPresent
+            state).  This other state is indicated by the included value
+            of ifOperStatus."
+    ::= { snmpTraps 3 }
+
+linkUp NOTIFICATION-TYPE
+    OBJECTS { ifIndex, ifAdminStatus, ifOperStatus }
+    STATUS  current
+    DESCRIPTION
+            "A linkUp trap signifies that the SNMP entity, acting in an
+            agent role, has detected that the ifOperStatus object for
+            one of its communication links left the down state and
+            transitioned into some other state (but not into the
+            notPresent state).  This other state is indicated by the
+            included value of ifOperStatus."
+    ::= { snmpTraps 4 }
+
+-- conformance information
+
+
+
+ifConformance OBJECT IDENTIFIER ::= { ifMIB 2 }
+
+ifGroups      OBJECT IDENTIFIER ::= { ifConformance 1 }
+ifCompliances OBJECT IDENTIFIER ::= { ifConformance 2 }
+
+
+-- compliance statements
+
+ifCompliance3 MODULE-COMPLIANCE
+    STATUS  current
+    DESCRIPTION
+            "The compliance statement for SNMP entities which have
+            network interfaces."
+
+    MODULE  -- this module
+        MANDATORY-GROUPS { ifGeneralInformationGroup,
+                           linkUpDownNotificationsGroup }
+
+-- The groups:
+--        ifFixedLengthGroup
+--        ifHCFixedLengthGroup
+--        ifPacketGroup
+--        ifHCPacketGroup
+--        ifVHCPacketGroup
+-- are mutually exclusive; at most one of these groups is implemented
+-- for a particular interface.  When any of these groups is implemented
+-- for a particular interface, then ifCounterDiscontinuityGroup must
+-- also be implemented for that interface.
+
+
+        GROUP       ifFixedLengthGroup
+        DESCRIPTION
+            "This group is mandatory for those network interfaces which
+            are character-oriented or transmit data in fixed-length
+            transmission units, and for which the value of the
+            corresponding instance of ifSpeed is less than or equal to
+            20,000,000 bits/second."
+
+        GROUP       ifHCFixedLengthGroup
+        DESCRIPTION
+            "This group is mandatory for those network interfaces which
+            are character-oriented or transmit data in fixed-length
+            transmission units, and for which the value of the
+            corresponding instance of ifSpeed is greater than 20,000,000
+            bits/second."
+
+        GROUP       ifPacketGroup
+        DESCRIPTION
+
+
+            "This group is mandatory for those network interfaces which
+            are packet-oriented, and for which the value of the
+            corresponding instance of ifSpeed is less than or equal to
+            20,000,000 bits/second."
+
+        GROUP       ifHCPacketGroup
+        DESCRIPTION
+            "This group is mandatory only for those network interfaces
+            which are packet-oriented and for which the value of the
+            corresponding instance of ifSpeed is greater than 20,000,000
+            bits/second but less than or equal to 650,000,000
+            bits/second."
+
+        GROUP       ifVHCPacketGroup
+        DESCRIPTION
+            "This group is mandatory only for those network interfaces
+            which are packet-oriented and for which the value of the
+            corresponding instance of ifSpeed is greater than
+            650,000,000 bits/second."
+
+
+        GROUP       ifCounterDiscontinuityGroup
+        DESCRIPTION
+            "This group is mandatory for those network interfaces that
+            are required to maintain counters (i.e., those for which one
+            of the ifFixedLengthGroup, ifHCFixedLengthGroup,
+            ifPacketGroup, ifHCPacketGroup, or ifVHCPacketGroup is
+            mandatory)."
+
+
+        GROUP       ifRcvAddressGroup
+        DESCRIPTION
+            "The applicability of this group MUST be defined by the
+            media-specific MIBs.  Media-specific MIBs must define the
+            exact meaning, use, and semantics of the addresses in this
+            group."
+
+        OBJECT      ifLinkUpDownTrapEnable
+        MIN-ACCESS  read-only
+        DESCRIPTION
+            "Write access is not required."
+
+        OBJECT      ifPromiscuousMode
+        MIN-ACCESS  read-only
+        DESCRIPTION
+            "Write access is not required."
+
+        OBJECT       ifAdminStatus
+
+
+        SYNTAX       INTEGER { up(1), down(2) }
+        MIN-ACCESS   read-only
+        DESCRIPTION
+            "Write access is not required, nor is support for the value
+            testing(3)."
+
+        OBJECT       ifAlias
+        MIN-ACCESS   read-only
+        DESCRIPTION
+            "Write access is not required."
+
+    ::= { ifCompliances 3 }
+
+-- units of conformance
+
+ifGeneralInformationGroup    OBJECT-GROUP
+    OBJECTS { ifIndex, ifDescr, ifType, ifSpeed, ifPhysAddress,
+              ifAdminStatus, ifOperStatus, ifLastChange,
+              ifLinkUpDownTrapEnable, ifConnectorPresent,
+              ifHighSpeed, ifName, ifNumber, ifAlias,
+              ifTableLastChange }
+    STATUS  current
+    DESCRIPTION
+            "A collection of objects providing information applicable to
+            all network interfaces."
+    ::= { ifGroups 10 }
+
+-- the following five groups are mutually exclusive; at most
+-- one of these groups is implemented for any interface
+
+ifFixedLengthGroup    OBJECT-GROUP
+    OBJECTS { ifInOctets, ifOutOctets, ifInUnknownProtos,
+              ifInErrors, ifOutErrors }
+    STATUS  current
+    DESCRIPTION
+            "A collection of objects providing information specific to
+            non-high speed (non-high speed interfaces transmit and
+            receive at speeds less than or equal to 20,000,000
+            bits/second) character-oriented or fixed-length-transmission
+            network interfaces."
+    ::= { ifGroups 2 }
+
+ifHCFixedLengthGroup    OBJECT-GROUP
+    OBJECTS { ifHCInOctets, ifHCOutOctets,
+              ifInOctets, ifOutOctets, ifInUnknownProtos,
+              ifInErrors, ifOutErrors }
+    STATUS  current
+    DESCRIPTION
+
+
+            "A collection of objects providing information specific to
+            high speed (greater than 20,000,000 bits/second) character-
+            oriented or fixed-length-transmission network interfaces."
+    ::= { ifGroups 3 }
+
+ifPacketGroup    OBJECT-GROUP
+    OBJECTS { ifInOctets, ifOutOctets, ifInUnknownProtos,
+              ifInErrors, ifOutErrors,
+              ifMtu, ifInUcastPkts, ifInMulticastPkts,
+              ifInBroadcastPkts, ifInDiscards,
+              ifOutUcastPkts, ifOutMulticastPkts,
+              ifOutBroadcastPkts, ifOutDiscards,
+              ifPromiscuousMode }
+    STATUS  current
+    DESCRIPTION
+            "A collection of objects providing information specific to
+            non-high speed (non-high speed interfaces transmit and
+            receive at speeds less than or equal to 20,000,000
+            bits/second) packet-oriented network interfaces."
+    ::= { ifGroups 4 }
+
+ifHCPacketGroup    OBJECT-GROUP
+    OBJECTS { ifHCInOctets, ifHCOutOctets,
+              ifInOctets, ifOutOctets, ifInUnknownProtos,
+              ifInErrors, ifOutErrors,
+              ifMtu, ifInUcastPkts, ifInMulticastPkts,
+              ifInBroadcastPkts, ifInDiscards,
+              ifOutUcastPkts, ifOutMulticastPkts,
+              ifOutBroadcastPkts, ifOutDiscards,
+              ifPromiscuousMode }
+    STATUS  current
+    DESCRIPTION
+            "A collection of objects providing information specific to
+            high speed (greater than 20,000,000 bits/second but less
+            than or equal to 650,000,000 bits/second) packet-oriented
+            network interfaces."
+    ::= { ifGroups 5 }
+
+ifVHCPacketGroup    OBJECT-GROUP
+    OBJECTS { ifHCInUcastPkts, ifHCInMulticastPkts,
+              ifHCInBroadcastPkts, ifHCOutUcastPkts,
+              ifHCOutMulticastPkts, ifHCOutBroadcastPkts,
+              ifHCInOctets, ifHCOutOctets,
+              ifInOctets, ifOutOctets, ifInUnknownProtos,
+              ifInErrors, ifOutErrors,
+              ifMtu, ifInUcastPkts, ifInMulticastPkts,
+              ifInBroadcastPkts, ifInDiscards,
+              ifOutUcastPkts, ifOutMulticastPkts,
+
+
+              ifOutBroadcastPkts, ifOutDiscards,
+              ifPromiscuousMode }
+    STATUS  current
+    DESCRIPTION
+            "A collection of objects providing information specific to
+            higher speed (greater than 650,000,000 bits/second) packet-
+            oriented network interfaces."
+    ::= { ifGroups 6 }
+
+ifRcvAddressGroup    OBJECT-GROUP
+    OBJECTS { ifRcvAddressStatus, ifRcvAddressType }
+    STATUS  current
+    DESCRIPTION
+            "A collection of objects providing information on the
+            multiple addresses which an interface receives."
+    ::= { ifGroups 7 }
+
+ifStackGroup2    OBJECT-GROUP
+    OBJECTS { ifStackStatus, ifStackLastChange }
+    STATUS  current
+    DESCRIPTION
+            "A collection of objects providing information on the
+            layering of MIB-II interfaces."
+    ::= { ifGroups 11 }
+
+ifCounterDiscontinuityGroup  OBJECT-GROUP
+    OBJECTS { ifCounterDiscontinuityTime }
+    STATUS  current
+    DESCRIPTION
+            "A collection of objects providing information specific to
+            interface counter discontinuities."
+    ::= { ifGroups 13 }
+
+linkUpDownNotificationsGroup  NOTIFICATION-GROUP
+    NOTIFICATIONS { linkUp, linkDown }
+    STATUS  current
+    DESCRIPTION
+            "The notifications which indicate specific changes in the
+            value of ifOperStatus."
+    ::= { ifGroups 14 }
+
+-- Deprecated Definitions - Objects
+
+
+--
+--    The Interface Test Table
+--
+-- This group of objects is optional.  However, a media-specific
+
+
+-- MIB may make implementation of this group mandatory.
+--
+-- This table replaces the ifExtnsTestTable
+--
+
+ifTestTable   OBJECT-TYPE
+    SYNTAX      SEQUENCE OF IfTestEntry
+    MAX-ACCESS  not-accessible
+    STATUS      deprecated
+    DESCRIPTION
+            "This table contains one entry per interface.  It defines
+            objects which allow a network manager to instruct an agent
+            to test an interface for various faults.  Tests for an
+            interface are defined in the media-specific MIB for that
+            interface.  After invoking a test, the object ifTestResult
+            can be read to determine the outcome.  If an agent can not
+            perform the test, ifTestResult is set to so indicate.  The
+            object ifTestCode can be used to provide further test-
+            specific or interface-specific (or even enterprise-specific)
+            information concerning the outcome of the test.  Only one
+            test can be in progress on each interface at any one time.
+            If one test is in progress when another test is invoked, the
+            second test is rejected.  Some agents may reject a test when
+            a prior test is active on another interface.
+
+            Before starting a test, a manager-station must first obtain
+            'ownership' of the entry in the ifTestTable for the
+            interface to be tested.  This is accomplished with the
+            ifTestId and ifTestStatus objects as follows:
+
+          try_again:
+              get (ifTestId, ifTestStatus)
+              while (ifTestStatus != notInUse)
+                  /*
+                   * Loop while a test is running or some other
+                   * manager is configuring a test.
+                   */
+                  short delay
+                  get (ifTestId, ifTestStatus)
+              }
+
+              /*
+               * Is not being used right now -- let's compete
+               * to see who gets it.
+               */
+              lock_value = ifTestId
+
+              if ( set(ifTestId = lock_value, ifTestStatus = inUse,
+
+
+                       ifTestOwner = 'my-IP-address') == FAILURE)
+                  /*
+                   * Another manager got the ifTestEntry -- go
+                   * try again
+                   */
+                  goto try_again;
+
+              /*
+               * I have the lock
+               */
+              set up any test parameters.
+
+              /*
+               * This starts the test
+               */
+              set(ifTestType = test_to_run);
+
+              wait for test completion by polling ifTestResult
+
+              when test completes, agent sets ifTestResult
+                   agent also sets ifTestStatus = 'notInUse'
+
+              retrieve any additional test results, and ifTestId
+
+              if (ifTestId == lock_value+1) results are valid
+
+            A manager station first retrieves the value of the
+            appropriate ifTestId and ifTestStatus objects, periodically
+            repeating the retrieval if necessary, until the value of
+            ifTestStatus is 'notInUse'.  The manager station then tries
+            to set the same ifTestId object to the value it just
+            retrieved, the same ifTestStatus object to 'inUse', and the
+            corresponding ifTestOwner object to a value indicating
+            itself.  If the set operation succeeds then the manager has
+            obtained ownership of the ifTestEntry, and the value of the
+            ifTestId object is incremented by the agent (per the
+            semantics of TestAndIncr).  Failure of the set operation
+            indicates that some other manager has obtained ownership of
+            the ifTestEntry.
+
+            Once ownership is obtained, any test parameters can be
+            setup, and then the test is initiated by setting ifTestType.
+            On completion of the test, the agent sets ifTestStatus to
+            'notInUse'.  Once this occurs, the manager can retrieve the
+            results.  In the (rare) event that the invocation of tests
+            by two network managers were to overlap, then there would be
+            a possibility that the first test's results might be
+            overwritten by the second test's results prior to the first
+
+
+            results being read.  This unlikely circumstance can be
+            detected by a network manager retrieving ifTestId at the
+            same time as retrieving the test results, and ensuring that
+            the results are for the desired request.
+
+            If ifTestType is not set within an abnormally long period of
+            time after ownership is obtained, the agent should time-out
+            the manager, and reset the value of the ifTestStatus object
+            back to 'notInUse'.  It is suggested that this time-out
+            period be 5 minutes.
+
+            In general, a management station must not retransmit a
+            request to invoke a test for which it does not receive a
+            response; instead, it properly inspects an agent's MIB to
+            determine if the invocation was successful.  Only if the
+            invocation was unsuccessful, is the invocation request
+            retransmitted.
+
+            Some tests may require the interface to be taken off-line in
+            order to execute them, or may even require the agent to
+            reboot after completion of the test.  In these
+            circumstances, communication with the management station
+            invoking the test may be lost until after completion of the
+            test.  An agent is not required to support such tests.
+            However, if such tests are supported, then the agent should
+            make every effort to transmit a response to the request
+            which invoked the test prior to losing communication.  When
+            the agent is restored to normal service, the results of the
+            test are properly made available in the appropriate objects.
+            Note that this requires that the ifIndex value assigned to
+            an interface must be unchanged even if the test causes a
+            reboot.  An agent must reject any test for which it cannot,
+            perhaps due to resource constraints, make available at least
+            the minimum amount of information after that test
+            completes."
+    ::= { ifMIBObjects 3 }
+
+ifTestEntry OBJECT-TYPE
+    SYNTAX       IfTestEntry
+    MAX-ACCESS   not-accessible
+    STATUS       deprecated
+    DESCRIPTION
+            "An entry containing objects for invoking tests on an
+            interface."
+    AUGMENTS  { ifEntry }
+    ::= { ifTestTable 1 }
+
+IfTestEntry ::=
+
+
+    SEQUENCE {
+        ifTestId           TestAndIncr,
+        ifTestStatus       INTEGER,
+        ifTestType         AutonomousType,
+        ifTestResult       INTEGER,
+        ifTestCode         OBJECT IDENTIFIER,
+        ifTestOwner        OwnerString
+    }
+
+ifTestId         OBJECT-TYPE
+    SYNTAX       TestAndIncr
+    MAX-ACCESS   read-write
+    STATUS       deprecated
+    DESCRIPTION
+            "This object identifies the current invocation of the
+            interface's test."
+    ::= { ifTestEntry 1 }
+
+ifTestStatus     OBJECT-TYPE
+    SYNTAX       INTEGER { notInUse(1), inUse(2) }
+    MAX-ACCESS   read-write
+    STATUS       deprecated
+    DESCRIPTION
+            "This object indicates whether or not some manager currently
+            has the necessary 'ownership' required to invoke a test on
+            this interface.  A write to this object is only successful
+            when it changes its value from 'notInUse(1)' to 'inUse(2)'.
+            After completion of a test, the agent resets the value back
+            to 'notInUse(1)'."
+    ::= { ifTestEntry 2 }
+
+ifTestType       OBJECT-TYPE
+    SYNTAX       AutonomousType
+    MAX-ACCESS   read-write
+    STATUS       deprecated
+    DESCRIPTION
+            "A control variable used to start and stop operator-
+            initiated interface tests.  Most OBJECT IDENTIFIER values
+            assigned to tests are defined elsewhere, in association with
+            specific types of interface.  However, this document assigns
+            a value for a full-duplex loopback test, and defines the
+            special meanings of the subject identifier:
+
+                noTest  OBJECT IDENTIFIER ::= { 0 0 }
+
+            When the value noTest is written to this object, no action
+            is taken unless a test is in progress, in which case the
+            test is aborted.  Writing any other value to this object is
+
+
+            only valid when no test is currently in progress, in which
+            case the indicated test is initiated.
+
+            When read, this object always returns the most recent value
+            that ifTestType was set to.  If it has not been set since
+            the last initialization of the network management subsystem
+            on the agent, a value of noTest is returned."
+    ::= { ifTestEntry 3 }
+
+ifTestResult  OBJECT-TYPE
+    SYNTAX       INTEGER {
+                     none(1),          -- no test yet requested
+                     success(2),
+                     inProgress(3),
+                     notSupported(4),
+                     unAbleToRun(5),   -- due to state of system
+                     aborted(6),
+                     failed(7)
+                 }
+    MAX-ACCESS   read-only
+    STATUS       deprecated
+    DESCRIPTION
+            "This object contains the result of the most recently
+            requested test, or the value none(1) if no tests have been
+            requested since the last reset.  Note that this facility
+            provides no provision for saving the results of one test
+            when starting another, as could be required if used by
+            multiple managers concurrently."
+    ::= { ifTestEntry 4 }
+
+ifTestCode  OBJECT-TYPE
+    SYNTAX       OBJECT IDENTIFIER
+    MAX-ACCESS   read-only
+    STATUS       deprecated
+    DESCRIPTION
+            "This object contains a code which contains more specific
+            information on the test result, for example an error-code
+            after a failed test.  Error codes and other values this
+            object may take are specific to the type of interface and/or
+            test.  The value may have the semantics of either the
+            AutonomousType or InstancePointer textual conventions as
+            defined in RFC 2579.  The identifier:
+
+                testCodeUnknown  OBJECT IDENTIFIER ::= { 0 0 }
+
+            is defined for use if no additional result code is
+            available."
+    ::= { ifTestEntry 5 }
+
+
+ifTestOwner      OBJECT-TYPE
+    SYNTAX       OwnerString
+    MAX-ACCESS   read-write
+    STATUS       deprecated
+    DESCRIPTION
+            "The entity which currently has the 'ownership' required to
+            invoke a test on this interface."
+    ::= { ifTestEntry 6 }
+
+-- Deprecated Definitions - Groups
+
+
+ifGeneralGroup    OBJECT-GROUP
+    OBJECTS { ifDescr, ifType, ifSpeed, ifPhysAddress,
+              ifAdminStatus, ifOperStatus, ifLastChange,
+              ifLinkUpDownTrapEnable, ifConnectorPresent,
+              ifHighSpeed, ifName }
+    STATUS  deprecated
+    DESCRIPTION
+            "A collection of objects deprecated in favour of
+            ifGeneralInformationGroup."
+    ::= { ifGroups 1 }
+
+
+ifTestGroup    OBJECT-GROUP
+    OBJECTS { ifTestId, ifTestStatus, ifTestType,
+              ifTestResult, ifTestCode, ifTestOwner }
+    STATUS  deprecated
+    DESCRIPTION
+            "A collection of objects providing the ability to invoke
+            tests on an interface."
+    ::= { ifGroups 8 }
+
+
+ifStackGroup    OBJECT-GROUP
+    OBJECTS { ifStackStatus }
+    STATUS  deprecated
+    DESCRIPTION
+            "The previous collection of objects providing information on
+            the layering of MIB-II interfaces."
+    ::= { ifGroups 9 }
+
+
+ifOldObjectsGroup    OBJECT-GROUP
+    OBJECTS { ifInNUcastPkts, ifOutNUcastPkts,
+              ifOutQLen, ifSpecific }
+    STATUS  deprecated
+    DESCRIPTION
+
+
+            "The collection of objects deprecated from the original MIB-
+            II interfaces group."
+    ::= { ifGroups 12 }
+
+-- Deprecated Definitions - Compliance
+
+ifCompliance MODULE-COMPLIANCE
+    STATUS  deprecated
+    DESCRIPTION
+            "A compliance statement defined in a previous version of
+            this MIB module, for SNMP entities which have network
+            interfaces."
+
+    MODULE  -- this module
+        MANDATORY-GROUPS { ifGeneralGroup, ifStackGroup }
+
+        GROUP       ifFixedLengthGroup
+        DESCRIPTION
+            "This group is mandatory for all network interfaces which
+            are character-oriented or transmit data in fixed-length
+            transmission units."
+
+        GROUP       ifHCFixedLengthGroup
+        DESCRIPTION
+            "This group is mandatory only for those network interfaces
+            which are character-oriented or transmit data in fixed-
+            length transmission units, and for which the value of the
+            corresponding instance of ifSpeed is greater than 20,000,000
+            bits/second."
+
+        GROUP       ifPacketGroup
+        DESCRIPTION
+            "This group is mandatory for all network interfaces which
+            are packet-oriented."
+
+        GROUP       ifHCPacketGroup
+        DESCRIPTION
+            "This group is mandatory only for those network interfaces
+            which are packet-oriented and for which the value of the
+            corresponding instance of ifSpeed is greater than
+            650,000,000 bits/second."
+
+        GROUP       ifTestGroup
+        DESCRIPTION
+            "This group is optional.  Media-specific MIBs which require
+            interface tests are strongly encouraged to use this group
+            for invoking tests and reporting results.  A medium specific
+            MIB which has mandatory tests may make implementation of
+
+
+            this group mandatory."
+
+        GROUP       ifRcvAddressGroup
+        DESCRIPTION
+            "The applicability of this group MUST be defined by the
+            media-specific MIBs.  Media-specific MIBs must define the
+            exact meaning, use, and semantics of the addresses in this
+            group."
+
+        OBJECT      ifLinkUpDownTrapEnable
+        MIN-ACCESS  read-only
+        DESCRIPTION
+            "Write access is not required."
+
+        OBJECT      ifPromiscuousMode
+        MIN-ACCESS  read-only
+        DESCRIPTION
+            "Write access is not required."
+
+        OBJECT      ifStackStatus
+        SYNTAX      INTEGER { active(1) } -- subset of RowStatus
+        MIN-ACCESS  read-only
+        DESCRIPTION
+            "Write access is not required, and only one of the six
+            enumerated values for the RowStatus textual convention need
+            be supported, specifically: active(1)."
+
+        OBJECT       ifAdminStatus
+        SYNTAX       INTEGER { up(1), down(2) }
+        MIN-ACCESS   read-only
+        DESCRIPTION
+            "Write access is not required, nor is support for the value
+            testing(3)."
+    ::= { ifCompliances 1 }
+
+ifCompliance2 MODULE-COMPLIANCE
+    STATUS      deprecated
+    DESCRIPTION
+            "A compliance statement defined in a previous version of
+            this MIB module, for SNMP entities which have network
+            interfaces."
+
+    MODULE  -- this module
+        MANDATORY-GROUPS { ifGeneralInformationGroup, ifStackGroup2,
+                           ifCounterDiscontinuityGroup }
+
+        GROUP       ifFixedLengthGroup
+        DESCRIPTION
+
+
+            "This group is mandatory for all network interfaces which
+            are character-oriented or transmit data in fixed-length
+            transmission units."
+
+        GROUP       ifHCFixedLengthGroup
+        DESCRIPTION
+            "This group is mandatory only for those network interfaces
+            which are character-oriented or transmit data in fixed-
+            length transmission units, and for which the value of the
+            corresponding instance of ifSpeed is greater than 20,000,000
+            bits/second."
+
+        GROUP       ifPacketGroup
+        DESCRIPTION
+            "This group is mandatory for all network interfaces which
+            are packet-oriented."
+
+        GROUP       ifHCPacketGroup
+        DESCRIPTION
+            "This group is mandatory only for those network interfaces
+            which are packet-oriented and for which the value of the
+            corresponding instance of ifSpeed is greater than
+            650,000,000 bits/second."
+
+        GROUP       ifRcvAddressGroup
+        DESCRIPTION
+            "The applicability of this group MUST be defined by the
+            media-specific MIBs.  Media-specific MIBs must define the
+            exact meaning, use, and semantics of the addresses in this
+            group."
+
+        OBJECT      ifLinkUpDownTrapEnable
+        MIN-ACCESS  read-only
+        DESCRIPTION
+            "Write access is not required."
+
+        OBJECT      ifPromiscuousMode
+        MIN-ACCESS  read-only
+        DESCRIPTION
+            "Write access is not required."
+
+        OBJECT      ifStackStatus
+        SYNTAX      INTEGER { active(1) } -- subset of RowStatus
+        MIN-ACCESS  read-only
+        DESCRIPTION
+            "Write access is not required, and only one of the six
+            enumerated values for the RowStatus textual convention need
+            be supported, specifically: active(1)."
+
+
+        OBJECT       ifAdminStatus
+        SYNTAX       INTEGER { up(1), down(2) }
+        MIN-ACCESS   read-only
+        DESCRIPTION
+            "Write access is not required, nor is support for the value
+            testing(3)."
+
+        OBJECT       ifAlias
+        MIN-ACCESS   read-only
+        DESCRIPTION
+            "Write access is not required."
+
+    ::= { ifCompliances 2 }
+
+END
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/Mibs/INET-ADDRESS-MIB
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/Mibs/INET-ADDRESS-MIB	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/Mibs/INET-ADDRESS-MIB	(revision 457)
@@ -0,0 +1,421 @@
+INET-ADDRESS-MIB DEFINITIONS ::= BEGIN
+
+IMPORTS
+    MODULE-IDENTITY, mib-2, Unsigned32 FROM SNMPv2-SMI
+    TEXTUAL-CONVENTION                 FROM SNMPv2-TC;
+
+inetAddressMIB MODULE-IDENTITY
+    LAST-UPDATED "200502040000Z"
+    ORGANIZATION
+        "IETF Operations and Management Area"
+    CONTACT-INFO
+        "Juergen Schoenwaelder (Editor)
+         International University Bremen
+         P.O. Box 750 561
+         28725 Bremen, Germany
+
+         Phone: +49 421 200-3587
+         EMail: j.schoenwaelder@iu-bremen.de
+
+         Send comments to <ietfmibs@ops.ietf.org>."
+    DESCRIPTION
+        "This MIB module defines textual conventions for
+         representing Internet addresses.  An Internet
+         address can be an IPv4 address, an IPv6 address,
+         or a DNS domain name.  This module also defines
+         textual conventions for Internet port numbers,
+         autonomous system numbers, and the length of an
+         Internet address prefix.
+
+         Copyright (C) The Internet Society (2005).  This version
+         of this MIB module is part of RFC 4001, see the RFC
+         itself for full legal notices."
+    REVISION     "200502040000Z"
+    DESCRIPTION
+        "Third version, published as RFC 4001.  This revision
+         introduces the InetZoneIndex, InetScopeType, and
+         InetVersion textual conventions."
+    REVISION     "200205090000Z"
+    DESCRIPTION
+        "Second version, published as RFC 3291.  This
+         revision contains several clarifications and
+         introduces several new textual conventions:
+         InetAddressPrefixLength, InetPortNumber,
+         InetAutonomousSystemNumber, InetAddressIPv4z,
+         and InetAddressIPv6z."
+    REVISION     "200006080000Z"
+
+
+
+    DESCRIPTION
+        "Initial version, published as RFC 2851."
+    ::= { mib-2 76 }
+
+InetAddressType ::= TEXTUAL-CONVENTION
+    STATUS      current
+    DESCRIPTION
+        "A value that represents a type of Internet address.
+
+         unknown(0)  An unknown address type.  This value MUST
+                     be used if the value of the corresponding
+                     InetAddress object is a zero-length string.
+                     It may also be used to indicate an IP address
+                     that is not in one of the formats defined
+                     below.
+
+         ipv4(1)     An IPv4 address as defined by the
+                     InetAddressIPv4 textual convention.
+
+         ipv6(2)     An IPv6 address as defined by the
+                     InetAddressIPv6 textual convention.
+
+         ipv4z(3)    A non-global IPv4 address including a zone
+                     index as defined by the InetAddressIPv4z
+                     textual convention.
+
+         ipv6z(4)    A non-global IPv6 address including a zone
+                     index as defined by the InetAddressIPv6z
+                     textual convention.
+
+         dns(16)     A DNS domain name as defined by the
+                     InetAddressDNS textual convention.
+
+         Each definition of a concrete InetAddressType value must be
+         accompanied by a definition of a textual convention for use
+         with that InetAddressType.
+
+         To support future extensions, the InetAddressType textual
+         convention SHOULD NOT be sub-typed in object type definitions.
+         It MAY be sub-typed in compliance statements in order to
+         require only a subset of these address types for a compliant
+         implementation.
+
+         Implementations must ensure that InetAddressType objects
+         and any dependent objects (e.g., InetAddress objects) are
+         consistent.  An inconsistentValue error must be generated
+         if an attempt to change an InetAddressType object would,
+         for example, lead to an undefined InetAddress value.  In
+
+
+
+         particular, InetAddressType/InetAddress pairs must be
+         changed together if the address type changes (e.g., from
+         ipv6(2) to ipv4(1))."
+    SYNTAX       INTEGER {
+                     unknown(0),
+                     ipv4(1),
+                     ipv6(2),
+                     ipv4z(3),
+                     ipv6z(4),
+                     dns(16)
+                 }
+
+InetAddress ::= TEXTUAL-CONVENTION
+    STATUS      current
+    DESCRIPTION
+        "Denotes a generic Internet address.
+
+         An InetAddress value is always interpreted within the context
+         of an InetAddressType value.  Every usage of the InetAddress
+         textual convention is required to specify the InetAddressType
+         object that provides the context.  It is suggested that the
+         InetAddressType object be logically registered before the
+         object(s) that use the InetAddress textual convention, if
+         they appear in the same logical row.
+
+         The value of an InetAddress object must always be
+         consistent with the value of the associated InetAddressType
+         object.  Attempts to set an InetAddress object to a value
+         inconsistent with the associated InetAddressType
+         must fail with an inconsistentValue error.
+
+         When this textual convention is used as the syntax of an
+         index object, there may be issues with the limit of 128
+         sub-identifiers specified in SMIv2, STD 58.  In this case,
+         the object definition MUST include a 'SIZE' clause to
+         limit the number of potential instance sub-identifiers;
+         otherwise the applicable constraints MUST be stated in
+         the appropriate conceptual row DESCRIPTION clauses, or
+         in the surrounding documentation if there is no single
+         DESCRIPTION clause that is appropriate."
+    SYNTAX       OCTET STRING (SIZE (0..255))
+
+InetAddressIPv4 ::= TEXTUAL-CONVENTION
+    DISPLAY-HINT "1d.1d.1d.1d"
+    STATUS       current
+    DESCRIPTION
+        "Represents an IPv4 network address:
+
+
+
+
+           Octets   Contents         Encoding
+            1-4     IPv4 address     network-byte order
+
+         The corresponding InetAddressType value is ipv4(1).
+
+         This textual convention SHOULD NOT be used directly in object
+         definitions, as it restricts addresses to a specific format.
+         However, if it is used, it MAY be used either on its own or in
+         conjunction with InetAddressType, as a pair."
+    SYNTAX       OCTET STRING (SIZE (4))
+
+InetAddressIPv6 ::= TEXTUAL-CONVENTION
+    DISPLAY-HINT "2x:2x:2x:2x:2x:2x:2x:2x"
+    STATUS       current
+    DESCRIPTION
+        "Represents an IPv6 network address:
+
+           Octets   Contents         Encoding
+            1-16    IPv6 address     network-byte order
+
+         The corresponding InetAddressType value is ipv6(2).
+
+         This textual convention SHOULD NOT be used directly in object
+         definitions, as it restricts addresses to a specific format.
+         However, if it is used, it MAY be used either on its own or in
+         conjunction with InetAddressType, as a pair."
+    SYNTAX       OCTET STRING (SIZE (16))
+
+InetAddressIPv4z ::= TEXTUAL-CONVENTION
+    DISPLAY-HINT "1d.1d.1d.1d%4d"
+    STATUS       current
+    DESCRIPTION
+        "Represents a non-global IPv4 network address, together
+         with its zone index:
+
+           Octets   Contents         Encoding
+            1-4     IPv4 address     network-byte order
+            5-8     zone index       network-byte order
+
+         The corresponding InetAddressType value is ipv4z(3).
+
+         The zone index (bytes 5-8) is used to disambiguate identical
+         address values on nodes that have interfaces attached to
+         different zones of the same scope.  The zone index may contain
+         the special value 0, which refers to the default zone for each
+         scope.
+
+         This textual convention SHOULD NOT be used directly in object
+
+
+
+         definitions, as it restricts addresses to a specific format.
+         However, if it is used, it MAY be used either on its own or in
+         conjunction with InetAddressType, as a pair."
+    SYNTAX       OCTET STRING (SIZE (8))
+
+InetAddressIPv6z ::= TEXTUAL-CONVENTION
+    DISPLAY-HINT "2x:2x:2x:2x:2x:2x:2x:2x%4d"
+    STATUS       current
+    DESCRIPTION
+        "Represents a non-global IPv6 network address, together
+         with its zone index:
+
+           Octets   Contents         Encoding
+            1-16    IPv6 address     network-byte order
+           17-20    zone index       network-byte order
+
+         The corresponding InetAddressType value is ipv6z(4).
+
+         The zone index (bytes 17-20) is used to disambiguate
+         identical address values on nodes that have interfaces
+         attached to different zones of the same scope.  The zone index
+         may contain the special value 0, which refers to the default
+         zone for each scope.
+
+         This textual convention SHOULD NOT be used directly in object
+         definitions, as it restricts addresses to a specific format.
+         However, if it is used, it MAY be used either on its own or in
+         conjunction with InetAddressType, as a pair."
+    SYNTAX       OCTET STRING (SIZE (20))
+
+InetAddressDNS ::= TEXTUAL-CONVENTION
+    DISPLAY-HINT "255a"
+    STATUS       current
+    DESCRIPTION
+        "Represents a DNS domain name.  The name SHOULD be fully
+         qualified whenever possible.
+
+         The corresponding InetAddressType is dns(16).
+
+         The DESCRIPTION clause of InetAddress objects that may have
+         InetAddressDNS values MUST fully describe how (and when)
+         these names are to be resolved to IP addresses.
+
+         The resolution of an InetAddressDNS value may require to
+         query multiple DNS records (e.g., A for IPv4 and AAAA for
+         IPv6).  The order of the resolution process and which DNS
+         record takes precedence depends on the configuration of the
+         resolver.
+
+
+
+         This textual convention SHOULD NOT be used directly in object
+         definitions, as it restricts addresses to a specific format.
+         However, if it is used, it MAY be used either on its own or in
+         conjunction with InetAddressType, as a pair."
+    SYNTAX       OCTET STRING (SIZE (1..255))
+
+InetAddressPrefixLength ::= TEXTUAL-CONVENTION
+    DISPLAY-HINT "d"
+    STATUS       current
+    DESCRIPTION
+        "Denotes the length of a generic Internet network address
+         prefix.  A value of n corresponds to an IP address mask
+         that has n contiguous 1-bits from the most significant
+         bit (MSB), with all other bits set to 0.
+
+         An InetAddressPrefixLength value is always interpreted within
+         the context of an InetAddressType value.  Every usage of the
+         InetAddressPrefixLength textual convention is required to
+         specify the InetAddressType object that provides the
+         context.  It is suggested that the InetAddressType object be
+         logically registered before the object(s) that use the
+         InetAddressPrefixLength textual convention, if they appear
+         in the same logical row.
+
+         InetAddressPrefixLength values larger than
+         the maximum length of an IP address for a specific
+         InetAddressType are treated as the maximum significant
+         value applicable for the InetAddressType.  The maximum
+         significant value is 32 for the InetAddressType
+         'ipv4(1)' and 'ipv4z(3)' and 128 for the InetAddressType
+         'ipv6(2)' and 'ipv6z(4)'.  The maximum significant value
+         for the InetAddressType 'dns(16)' is 0.
+
+         The value zero is object-specific and must be defined as
+         part of the description of any object that uses this
+         syntax.  Examples of the usage of zero might include
+         situations where the Internet network address prefix
+         is unknown or does not apply.
+
+         The upper bound of the prefix length has been chosen to
+         be consistent with the maximum size of an InetAddress."
+    SYNTAX       Unsigned32 (0..2040)
+
+InetPortNumber ::= TEXTUAL-CONVENTION
+    DISPLAY-HINT "d"
+    STATUS       current
+    DESCRIPTION
+        "Represents a 16 bit port number of an Internet transport
+
+
+
+         layer protocol.  Port numbers are assigned by IANA.  A
+         current list of all assignments is available from
+         <http://www.iana.org/>.
+
+         The value zero is object-specific and must be defined as
+         part of the description of any object that uses this
+         syntax.  Examples of the usage of zero might include
+         situations where a port number is unknown, or when the
+         value zero is used as a wildcard in a filter."
+    REFERENCE   "STD 6 (RFC 768), STD 7 (RFC 793) and RFC 2960"
+    SYNTAX       Unsigned32 (0..65535)
+
+InetAutonomousSystemNumber ::= TEXTUAL-CONVENTION
+    DISPLAY-HINT "d"
+    STATUS       current
+    DESCRIPTION
+        "Represents an autonomous system number that identifies an
+         Autonomous System (AS).  An AS is a set of routers under a
+         single technical administration, using an interior gateway
+         protocol and common metrics to route packets within the AS,
+         and using an exterior gateway protocol to route packets to
+         other ASes'.  IANA maintains the AS number space and has
+         delegated large parts to the regional registries.
+
+         Autonomous system numbers are currently limited to 16 bits
+         (0..65535).  There is, however, work in progress to enlarge the
+         autonomous system number space to 32 bits.  Therefore, this
+         textual convention uses an Unsigned32 value without a
+         range restriction in order to support a larger autonomous
+         system number space."
+    REFERENCE   "RFC 1771, RFC 1930"
+    SYNTAX       Unsigned32
+
+InetScopeType ::= TEXTUAL-CONVENTION
+    STATUS       current
+    DESCRIPTION
+        "Represents a scope type.  This textual convention can be used
+         in cases where a MIB has to represent different scope types
+         and there is no context information, such as an InetAddress
+         object, that implicitly defines the scope type.
+
+         Note that not all possible values have been assigned yet, but
+         they may be assigned in future revisions of this specification.
+         Applications should therefore be able to deal with values
+         not yet assigned."
+    REFERENCE   "RFC 3513"
+    SYNTAX       INTEGER {
+                     -- reserved(0),
+
+
+
+                     interfaceLocal(1),
+                     linkLocal(2),
+                     subnetLocal(3),
+                     adminLocal(4),
+                     siteLocal(5), -- site-local unicast addresses
+                                   -- have been deprecated by RFC 3879
+                     -- unassigned(6),
+                     -- unassigned(7),
+                     organizationLocal(8),
+                     -- unassigned(9),
+                     -- unassigned(10),
+                     -- unassigned(11),
+                     -- unassigned(12),
+                     -- unassigned(13),
+                     global(14)
+                     -- reserved(15)
+                 }
+
+InetZoneIndex ::= TEXTUAL-CONVENTION
+    DISPLAY-HINT "d"
+    STATUS       current
+    DESCRIPTION
+        "A zone index identifies an instance of a zone of a
+         specific scope.
+
+         The zone index MUST disambiguate identical address
+         values.  For link-local addresses, the zone index will
+         typically be the interface index (ifIndex as defined in the
+         IF-MIB) of the interface on which the address is configured.
+
+         The zone index may contain the special value 0, which refers
+         to the default zone.  The default zone may be used in cases
+         where the valid zone index is not known (e.g., when a
+         management application has to write a link-local IPv6
+         address without knowing the interface index value).  The
+         default zone SHOULD NOT be used as an easy way out in
+         cases where the zone index for a non-global IPv6 address
+         is known."
+    REFERENCE   "RFC4007"
+    SYNTAX       Unsigned32
+
+InetVersion ::= TEXTUAL-CONVENTION
+    STATUS  current
+    DESCRIPTION
+        "A value representing a version of the IP protocol.
+
+         unknown(0)  An unknown or unspecified version of the IP
+                     protocol.
+
+
+
+         ipv4(1)     The IPv4 protocol as defined in RFC 791 (STD 5).
+
+         ipv6(2)     The IPv6 protocol as defined in RFC 2460.
+
+         Note that this textual convention SHOULD NOT be used to
+         distinguish different address types associated with IP
+         protocols.  The InetAddressType has been designed for this
+         purpose."
+    REFERENCE   "RFC 791, RFC 2460"
+    SYNTAX       INTEGER {
+                     unknown(0),
+                     ipv4(1),
+                     ipv6(2)
+                 }
+END
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/Mibs/IP-MIB
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/Mibs/IP-MIB	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/Mibs/IP-MIB	(revision 457)
@@ -0,0 +1,5254 @@
+IP-MIB DEFINITIONS ::= BEGIN
+
+IMPORTS
+    MODULE-IDENTITY, OBJECT-TYPE,
+    Integer32, Counter32, IpAddress,
+    mib-2, Unsigned32, Counter64,
+    zeroDotZero                        FROM SNMPv2-SMI
+    PhysAddress, TruthValue,
+    TimeStamp, RowPointer,
+    TEXTUAL-CONVENTION, TestAndIncr,
+    RowStatus, StorageType             FROM SNMPv2-TC
+    MODULE-COMPLIANCE, OBJECT-GROUP    FROM SNMPv2-CONF
+    InetAddress, InetAddressType,
+    InetAddressPrefixLength,
+    InetVersion, InetZoneIndex         FROM INET-ADDRESS-MIB
+    InterfaceIndex                     FROM IF-MIB;
+
+ipMIB MODULE-IDENTITY
+    LAST-UPDATED "200602020000Z"
+    ORGANIZATION "IETF IPv6 MIB Revision Team"
+    CONTACT-INFO
+           "Editor:
+
+
+
+            Shawn A. Routhier
+            Interworking Labs
+            108 Whispering Pines Dr. Suite 235
+            Scotts Valley, CA 95066
+            USA
+            EMail: <sar@iwl.com>"
+    DESCRIPTION
+           "The MIB module for managing IP and ICMP implementations, but
+            excluding their management of IP routes.
+
+            Copyright (C) The Internet Society (2006).  This version of
+            this MIB module is part of RFC 4293; see the RFC itself for
+            full legal notices."
+
+    REVISION      "200602020000Z"
+    DESCRIPTION
+           "The IP version neutral revision with added IPv6 objects for
+            ND, default routers, and router advertisements.  As well as
+            being the successor to RFC 2011, this MIB is also the
+            successor to RFCs 2465 and 2466.  Published as RFC 4293."
+
+    REVISION      "199411010000Z"
+    DESCRIPTION
+           "A separate MIB module (IP-MIB) for IP and ICMP management
+            objects.  Published as RFC 2011."
+
+    REVISION      "199103310000Z"
+    DESCRIPTION
+           "The initial revision of this MIB module was part of MIB-II,
+            which was published as RFC 1213."
+    ::= { mib-2 48}
+
+--
+-- The textual conventions we define and use in this MIB.
+--
+
+IpAddressOriginTC ::= TEXTUAL-CONVENTION
+    STATUS     current
+    DESCRIPTION
+           "The origin of the address.
+
+            manual(2) indicates that the address was manually configured
+            to a specified address, e.g., by user configuration.
+
+            dhcp(4) indicates an address that was assigned to this
+            system by a DHCP server.
+
+            linklayer(5) indicates an address created by IPv6 stateless
+
+
+
+            auto-configuration.
+
+            random(6) indicates an address chosen by the system at
+            random, e.g., an IPv4 address within 169.254/16, or an RFC
+            3041 privacy address."
+    SYNTAX     INTEGER {
+        other(1),
+        manual(2),
+        dhcp(4),
+        linklayer(5),
+        random(6)
+    }
+
+IpAddressStatusTC ::= TEXTUAL-CONVENTION
+    STATUS     current
+    DESCRIPTION
+           "The status of an address.  Most of the states correspond to
+            states from the IPv6 Stateless Address Autoconfiguration
+            protocol.
+
+            The preferred(1) state indicates that this is a valid
+            address that can appear as the destination or source address
+            of a packet.
+
+            The deprecated(2) state indicates that this is a valid but
+            deprecated address that should no longer be used as a source
+            address in new communications, but packets addressed to such
+            an address are processed as expected.
+
+            The invalid(3) state indicates that this isn't a valid
+            address and it shouldn't appear as the destination or source
+            address of a packet.
+
+            The inaccessible(4) state indicates that the address is not
+            accessible because the interface to which this address is
+            assigned is not operational.
+
+            The unknown(5) state indicates that the status cannot be
+            determined for some reason.
+
+            The tentative(6) state indicates that the uniqueness of the
+            address on the link is being verified.  Addresses in this
+            state should not be used for general communication and
+            should only be used to determine the uniqueness of the
+            address.
+
+            The duplicate(7) state indicates the address has been
+            determined to be non-unique on the link and so must not be
+
+
+
+            used.
+
+            The optimistic(8) state indicates the address is available
+            for use, subject to restrictions, while its uniqueness on
+            a link is being verified.
+
+            In the absence of other information, an IPv4 address is
+            always preferred(1)."
+    REFERENCE "RFC 2462"
+    SYNTAX     INTEGER {
+        preferred(1),
+        deprecated(2),
+        invalid(3),
+        inaccessible(4),
+        unknown(5),
+        tentative(6),
+        duplicate(7),
+        optimistic(8)
+    }
+
+IpAddressPrefixOriginTC ::= TEXTUAL-CONVENTION
+    STATUS     current
+    DESCRIPTION
+           "The origin of this prefix.
+
+            manual(2) indicates a prefix that was manually configured.
+
+            wellknown(3) indicates a well-known prefix, e.g., 169.254/16
+            for IPv4 auto-configuration or fe80::/10 for IPv6 link-local
+            addresses.  Well known prefixes may be assigned by IANA,
+            the address registries, or by specification in a standards
+            track RFC.
+
+            dhcp(4) indicates a prefix that was assigned by a DHCP
+            server.
+
+            routeradv(5) indicates a prefix learned from a router
+            advertisement.
+
+            Note: while IpAddressOriginTC and IpAddressPrefixOriginTC
+            are similar, they are not identical.  The first defines how
+            an address was created, while the second defines how a
+            prefix was found."
+    SYNTAX     INTEGER {
+        other(1),
+        manual(2),
+        wellknown(3),
+        dhcp(4),
+
+
+
+        routeradv(5)
+    }
+
+Ipv6AddressIfIdentifierTC ::= TEXTUAL-CONVENTION
+     DISPLAY-HINT "2x:"
+     STATUS       current
+     DESCRIPTION
+       "This data type is used to model IPv6 address
+       interface identifiers.  This is a binary string
+       of up to 8 octets in network byte-order."
+     SYNTAX      OCTET STRING (SIZE (0..8))
+
+--
+-- the IP general group
+-- some objects that affect all of IPv4
+--
+
+ip       OBJECT IDENTIFIER ::= { mib-2 4 }
+
+ipForwarding OBJECT-TYPE
+    SYNTAX     INTEGER {
+                    forwarding(1),    -- acting as a router
+                    notForwarding(2)  -- NOT acting as a router
+               }
+    MAX-ACCESS read-write
+    STATUS     current
+    DESCRIPTION
+           "The indication of whether this entity is acting as an IPv4
+            router in respect to the forwarding of datagrams received
+            by, but not addressed to, this entity.  IPv4 routers forward
+            datagrams.  IPv4 hosts do not (except those source-routed
+            via the host).
+
+            When this object is written, the entity should save the
+            change to non-volatile storage and restore the object from
+            non-volatile storage upon re-initialization of the system.
+            Note: a stronger requirement is not used because this object
+            was previously defined."
+    ::= { ip 1 }
+
+ipDefaultTTL OBJECT-TYPE
+    SYNTAX     Integer32 (1..255)
+    MAX-ACCESS read-write
+    STATUS     current
+    DESCRIPTION
+           "The default value inserted into the Time-To-Live field of
+            the IPv4 header of datagrams originated at this entity,
+            whenever a TTL value is not supplied by the transport layer
+
+
+
+            protocol.
+
+            When this object is written, the entity should save the
+            change to non-volatile storage and restore the object from
+            non-volatile storage upon re-initialization of the system.
+            Note: a stronger requirement is not used because this object
+            was previously defined."
+    ::= { ip 2 }
+
+ipReasmTimeout OBJECT-TYPE
+    SYNTAX     Integer32
+    UNITS      "seconds"
+    MAX-ACCESS read-only
+    STATUS     current
+    DESCRIPTION
+           "The maximum number of seconds that received fragments are
+            held while they are awaiting reassembly at this entity."
+    ::= { ip 13 }
+
+--
+-- the IPv6 general group
+-- Some objects that affect all of IPv6
+--
+
+ipv6IpForwarding OBJECT-TYPE
+    SYNTAX     INTEGER {
+                    forwarding(1),    -- acting as a router
+                    notForwarding(2)  -- NOT acting as a router
+               }
+    MAX-ACCESS read-write
+    STATUS     current
+    DESCRIPTION
+           "The indication of whether this entity is acting as an IPv6
+            router on any interface in respect to the forwarding of
+            datagrams received by, but not addressed to, this entity.
+            IPv6 routers forward datagrams.  IPv6 hosts do not (except
+            those source-routed via the host).
+
+            When this object is written, the entity SHOULD save the
+            change to non-volatile storage and restore the object from
+            non-volatile storage upon re-initialization of the system."
+    ::= { ip 25 }
+
+ipv6IpDefaultHopLimit OBJECT-TYPE
+    SYNTAX     Integer32 (0..255)
+    MAX-ACCESS read-write
+    STATUS     current
+    DESCRIPTION
+
+
+
+           "The default value inserted into the Hop Limit field of the
+            IPv6 header of datagrams originated at this entity whenever
+            a Hop Limit value is not supplied by the transport layer
+            protocol.
+
+            When this object is written, the entity SHOULD save the
+            change to non-volatile storage and restore the object from
+            non-volatile storage upon re-initialization of the system."
+    REFERENCE "RFC 2461 Section 6.3.2"
+    ::= { ip 26 }
+
+--
+-- IPv4 Interface Table
+--
+
+ipv4InterfaceTableLastChange OBJECT-TYPE
+    SYNTAX     TimeStamp
+    MAX-ACCESS read-only
+    STATUS     current
+    DESCRIPTION
+           "The value of sysUpTime on the most recent occasion at which
+            a row in the ipv4InterfaceTable was added or deleted, or
+            when an ipv4InterfaceReasmMaxSize or an
+            ipv4InterfaceEnableStatus object was modified.
+
+            If new objects are added to the ipv4InterfaceTable that
+            require the ipv4InterfaceTableLastChange to be updated when
+            they are modified, they must specify that requirement in
+            their description clause."
+    ::= { ip 27 }
+
+ipv4InterfaceTable OBJECT-TYPE
+    SYNTAX     SEQUENCE OF Ipv4InterfaceEntry
+    MAX-ACCESS not-accessible
+    STATUS     current
+    DESCRIPTION
+           "The table containing per-interface IPv4-specific
+            information."
+    ::= { ip 28 }
+
+ipv4InterfaceEntry OBJECT-TYPE
+    SYNTAX     Ipv4InterfaceEntry
+    MAX-ACCESS not-accessible
+    STATUS     current
+    DESCRIPTION
+           "An entry containing IPv4-specific information for a specific
+            interface."
+    INDEX { ipv4InterfaceIfIndex }
+
+
+
+    ::= { ipv4InterfaceTable 1 }
+
+Ipv4InterfaceEntry ::= SEQUENCE {
+        ipv4InterfaceIfIndex         InterfaceIndex,
+        ipv4InterfaceReasmMaxSize    Integer32,
+        ipv4InterfaceEnableStatus    INTEGER,
+        ipv4InterfaceRetransmitTime  Unsigned32
+    }
+
+ipv4InterfaceIfIndex OBJECT-TYPE
+    SYNTAX     InterfaceIndex
+    MAX-ACCESS not-accessible
+    STATUS     current
+    DESCRIPTION
+           "The index value that uniquely identifies the interface to
+            which this entry is applicable.  The interface identified by
+            a particular value of this index is the same interface as
+            identified by the same value of the IF-MIB's ifIndex."
+    ::= { ipv4InterfaceEntry 1 }
+
+ipv4InterfaceReasmMaxSize OBJECT-TYPE
+    SYNTAX     Integer32 (0..65535)
+    MAX-ACCESS read-only
+    STATUS     current
+    DESCRIPTION
+           "The size of the largest IPv4 datagram that this entity can
+            re-assemble from incoming IPv4 fragmented datagrams received
+            on this interface."
+    ::= { ipv4InterfaceEntry 2 }
+
+ipv4InterfaceEnableStatus OBJECT-TYPE
+    SYNTAX     INTEGER {
+                 up(1),
+                 down(2)
+    }
+    MAX-ACCESS read-write
+    STATUS     current
+    DESCRIPTION
+           "The indication of whether IPv4 is enabled (up) or disabled
+            (down) on this interface.  This object does not affect the
+            state of the interface itself, only its connection to an
+            IPv4 stack.  The IF-MIB should be used to control the state
+            of the interface."
+    ::= { ipv4InterfaceEntry 3 }
+
+ipv4InterfaceRetransmitTime OBJECT-TYPE
+    SYNTAX     Unsigned32
+    UNITS      "milliseconds"
+
+
+
+    MAX-ACCESS read-only
+    STATUS     current
+    DESCRIPTION
+           "The time between retransmissions of ARP requests to a
+            neighbor when resolving the address or when probing the
+            reachability of a neighbor."
+    REFERENCE "RFC 1122"
+    DEFVAL { 1000 }
+    ::= { ipv4InterfaceEntry 4 }
+
+--
+-- v6 interface table
+--
+
+ipv6InterfaceTableLastChange OBJECT-TYPE
+    SYNTAX     TimeStamp
+    MAX-ACCESS read-only
+    STATUS     current
+    DESCRIPTION
+           "The value of sysUpTime on the most recent occasion at which
+            a row in the ipv6InterfaceTable was added or deleted or when
+            an ipv6InterfaceReasmMaxSize, ipv6InterfaceIdentifier,
+            ipv6InterfaceEnableStatus, ipv6InterfaceReachableTime,
+            ipv6InterfaceRetransmitTime, or ipv6InterfaceForwarding
+            object was modified.
+
+            If new objects are added to the ipv6InterfaceTable that
+            require the ipv6InterfaceTableLastChange to be updated when
+            they are modified, they must specify that requirement in
+            their description clause."
+    ::= { ip 29 }
+
+ipv6InterfaceTable OBJECT-TYPE
+    SYNTAX     SEQUENCE OF Ipv6InterfaceEntry
+    MAX-ACCESS not-accessible
+    STATUS     current
+    DESCRIPTION
+           "The table containing per-interface IPv6-specific
+            information."
+    ::= { ip 30 }
+
+ipv6InterfaceEntry OBJECT-TYPE
+    SYNTAX     Ipv6InterfaceEntry
+    MAX-ACCESS not-accessible
+    STATUS     current
+    DESCRIPTION
+           "An entry containing IPv6-specific information for a given
+            interface."
+
+
+
+    INDEX { ipv6InterfaceIfIndex }
+    ::= { ipv6InterfaceTable 1 }
+
+Ipv6InterfaceEntry ::= SEQUENCE {
+        ipv6InterfaceIfIndex         InterfaceIndex,
+        ipv6InterfaceReasmMaxSize    Unsigned32,
+        ipv6InterfaceIdentifier      Ipv6AddressIfIdentifierTC,
+        ipv6InterfaceEnableStatus    INTEGER,
+        ipv6InterfaceReachableTime   Unsigned32,
+        ipv6InterfaceRetransmitTime  Unsigned32,
+        ipv6InterfaceForwarding      INTEGER
+    }
+
+ipv6InterfaceIfIndex OBJECT-TYPE
+    SYNTAX     InterfaceIndex
+    MAX-ACCESS not-accessible
+    STATUS     current
+    DESCRIPTION
+           "The index value that uniquely identifies the interface to
+            which this entry is applicable.  The interface identified by
+            a particular value of this index is the same interface as
+            identified by the same value of the IF-MIB's ifIndex."
+    ::= { ipv6InterfaceEntry 1 }
+
+ipv6InterfaceReasmMaxSize OBJECT-TYPE
+    SYNTAX     Unsigned32 (1500..65535)
+    UNITS      "octets"
+    MAX-ACCESS read-only
+    STATUS     current
+    DESCRIPTION
+           "The size of the largest IPv6 datagram that this entity can
+            re-assemble from incoming IPv6 fragmented datagrams received
+            on this interface."
+    ::= { ipv6InterfaceEntry 2 }
+
+ipv6InterfaceIdentifier OBJECT-TYPE
+    SYNTAX     Ipv6AddressIfIdentifierTC
+    MAX-ACCESS read-only
+    STATUS     current
+    DESCRIPTION
+           "The Interface Identifier for this interface.  The Interface
+            Identifier is combined with an address prefix to form an
+            interface address.
+
+            By default, the Interface Identifier is auto-configured
+            according to the rules of the link type to which this
+            interface is attached.
+
+
+
+
+            A zero length identifier may be used where appropriate.  One
+            possible example is a loopback interface."
+    ::= { ipv6InterfaceEntry 3 }
+
+-- This object ID is reserved as it was used in earlier versions of
+-- the MIB module.  In theory, OIDs are not assigned until the
+-- specification is released as an RFC; however, as some companies
+-- may have shipped code based on earlier versions of the MIB, it
+-- seems best to reserve this OID.  This OID had been
+-- ipv6InterfacePhysicalAddress.
+-- ::= { ipv6InterfaceEntry 4}
+
+ipv6InterfaceEnableStatus OBJECT-TYPE
+    SYNTAX     INTEGER {
+                 up(1),
+                 down(2)
+    }
+    MAX-ACCESS read-write
+    STATUS     current
+    DESCRIPTION
+           "The indication of whether IPv6 is enabled (up) or disabled
+            (down) on this interface.  This object does not affect the
+            state of the interface itself, only its connection to an
+            IPv6 stack.  The IF-MIB should be used to control the state
+            of the interface.
+
+            When this object is written, the entity SHOULD save the
+            change to non-volatile storage and restore the object from
+            non-volatile storage upon re-initialization of the system."
+    ::= { ipv6InterfaceEntry 5 }
+
+ipv6InterfaceReachableTime OBJECT-TYPE
+    SYNTAX     Unsigned32
+    UNITS      "milliseconds"
+    MAX-ACCESS read-only
+    STATUS     current
+    DESCRIPTION
+           "The time a neighbor is considered reachable after receiving
+            a reachability confirmation."
+    REFERENCE "RFC 2461, Section 6.3.2"
+    ::= { ipv6InterfaceEntry 6 }
+
+ipv6InterfaceRetransmitTime OBJECT-TYPE
+    SYNTAX     Unsigned32
+    UNITS      "milliseconds"
+    MAX-ACCESS read-only
+    STATUS     current
+    DESCRIPTION
+
+
+
+           "The time between retransmissions of Neighbor Solicitation
+            messages to a neighbor when resolving the address or when
+            probing the reachability of a neighbor."
+    REFERENCE "RFC 2461, Section 6.3.2"
+    ::= { ipv6InterfaceEntry 7 }
+
+ipv6InterfaceForwarding OBJECT-TYPE
+    SYNTAX     INTEGER {
+                    forwarding(1),    -- acting as a router
+                    notForwarding(2)  -- NOT acting as a router
+               }
+    MAX-ACCESS read-write
+    STATUS     current
+    DESCRIPTION
+           "The indication of whether this entity is acting as an IPv6
+            router on this interface with respect to the forwarding of
+            datagrams received by, but not addressed to, this entity.
+            IPv6 routers forward datagrams.  IPv6 hosts do not (except
+            those source-routed via the host).
+
+            This object is constrained by ipv6IpForwarding and is
+            ignored if ipv6IpForwarding is set to notForwarding.  Those
+            systems that do not provide per-interface control of the
+            forwarding function should set this object to forwarding for
+            all interfaces and allow the ipv6IpForwarding object to
+            control the forwarding capability.
+
+            When this object is written, the entity SHOULD save the
+            change to non-volatile storage and restore the object from
+            non-volatile storage upon re-initialization of the system."
+    ::= { ipv6InterfaceEntry 8 }
+
+--
+-- Per-Interface or System-Wide IP statistics.
+--
+-- The following two tables, ipSystemStatsTable and ipIfStatsTable,
+-- are intended to provide the same counters at different granularities.
+-- The ipSystemStatsTable provides system wide counters aggregating
+-- the traffic counters for all interfaces for a given address type.
+-- The ipIfStatsTable provides the same counters but for specific
+-- interfaces rather than as an aggregate.
+--
+-- Note well: If a system provides both system-wide and interface-
+-- specific values, the system-wide value may not be equal to the sum
+-- of the interface-specific values across all interfaces due to e.g.,
+-- dynamic interface creation/deletion.
+--
+-- Note well: Both of these tables contain some items that are
+
+
+
+-- represented by two objects, representing the value in either 32
+-- or 64 bits.  For those objects, the 32-bit value MUST be the low
+-- order 32 bits of the 64-bit value.  Also note that the 32-bit
+-- counters must be included when the 64-bit counters are included.
+
+ipTrafficStats OBJECT IDENTIFIER ::= { ip 31 }
+
+ipSystemStatsTable OBJECT-TYPE
+    SYNTAX     SEQUENCE OF IpSystemStatsEntry
+    MAX-ACCESS not-accessible
+    STATUS     current
+    DESCRIPTION
+           "The table containing system wide, IP version specific
+            traffic statistics.  This table and the ipIfStatsTable
+            contain similar objects whose difference is in their
+            granularity.  Where this table contains system wide traffic
+            statistics, the ipIfStatsTable contains the same statistics
+            but counted on a per-interface basis."
+    ::= { ipTrafficStats 1 }
+
+ipSystemStatsEntry OBJECT-TYPE
+    SYNTAX     IpSystemStatsEntry
+    MAX-ACCESS not-accessible
+    STATUS     current
+    DESCRIPTION
+           "A statistics entry containing system-wide objects for a
+            particular IP version."
+    INDEX { ipSystemStatsIPVersion }
+    ::= { ipSystemStatsTable 1 }
+
+IpSystemStatsEntry ::= SEQUENCE {
+        ipSystemStatsIPVersion           InetVersion,
+        ipSystemStatsInReceives          Counter32,
+        ipSystemStatsHCInReceives        Counter64,
+        ipSystemStatsInOctets            Counter32,
+        ipSystemStatsHCInOctets          Counter64,
+        ipSystemStatsInHdrErrors         Counter32,
+        ipSystemStatsInNoRoutes          Counter32,
+        ipSystemStatsInAddrErrors        Counter32,
+        ipSystemStatsInUnknownProtos     Counter32,
+        ipSystemStatsInTruncatedPkts     Counter32,
+        ipSystemStatsInForwDatagrams     Counter32,
+        ipSystemStatsHCInForwDatagrams   Counter64,
+        ipSystemStatsReasmReqds          Counter32,
+        ipSystemStatsReasmOKs            Counter32,
+        ipSystemStatsReasmFails          Counter32,
+        ipSystemStatsInDiscards          Counter32,
+        ipSystemStatsInDelivers          Counter32,
+
+
+
+        ipSystemStatsHCInDelivers        Counter64,
+        ipSystemStatsOutRequests         Counter32,
+        ipSystemStatsHCOutRequests       Counter64,
+        ipSystemStatsOutNoRoutes         Counter32,
+        ipSystemStatsOutForwDatagrams    Counter32,
+        ipSystemStatsHCOutForwDatagrams  Counter64,
+        ipSystemStatsOutDiscards         Counter32,
+        ipSystemStatsOutFragReqds        Counter32,
+        ipSystemStatsOutFragOKs          Counter32,
+        ipSystemStatsOutFragFails        Counter32,
+        ipSystemStatsOutFragCreates      Counter32,
+        ipSystemStatsOutTransmits        Counter32,
+        ipSystemStatsHCOutTransmits      Counter64,
+        ipSystemStatsOutOctets           Counter32,
+        ipSystemStatsHCOutOctets         Counter64,
+        ipSystemStatsInMcastPkts         Counter32,
+        ipSystemStatsHCInMcastPkts       Counter64,
+        ipSystemStatsInMcastOctets       Counter32,
+        ipSystemStatsHCInMcastOctets     Counter64,
+        ipSystemStatsOutMcastPkts        Counter32,
+        ipSystemStatsHCOutMcastPkts      Counter64,
+        ipSystemStatsOutMcastOctets      Counter32,
+        ipSystemStatsHCOutMcastOctets    Counter64,
+        ipSystemStatsInBcastPkts         Counter32,
+        ipSystemStatsHCInBcastPkts       Counter64,
+        ipSystemStatsOutBcastPkts        Counter32,
+        ipSystemStatsHCOutBcastPkts      Counter64,
+        ipSystemStatsDiscontinuityTime   TimeStamp,
+        ipSystemStatsRefreshRate         Unsigned32
+    }
+
+ipSystemStatsIPVersion OBJECT-TYPE
+    SYNTAX     InetVersion
+    MAX-ACCESS not-accessible
+    STATUS     current
+    DESCRIPTION
+           "The IP version of this row."
+    ::= { ipSystemStatsEntry 1 }
+
+-- This object ID is reserved to allow the IDs for this table's objects
+-- to align with the objects in the ipIfStatsTable.
+-- ::= { ipSystemStatsEntry 2 }
+
+ipSystemStatsInReceives OBJECT-TYPE
+    SYNTAX     Counter32
+    MAX-ACCESS read-only
+    STATUS     current
+    DESCRIPTION
+
+
+
+           "The total number of input IP datagrams received, including
+            those received in error.
+
+            Discontinuities in the value of this counter can occur at
+            re-initialization of the management system, and at other
+            times as indicated by the value of
+            ipSystemStatsDiscontinuityTime."
+    ::= { ipSystemStatsEntry 3 }
+
+ipSystemStatsHCInReceives OBJECT-TYPE
+    SYNTAX     Counter64
+    MAX-ACCESS read-only
+    STATUS     current
+    DESCRIPTION
+           "The total number of input IP datagrams received, including
+            those received in error.  This object counts the same
+            datagrams as ipSystemStatsInReceives, but allows for larger
+            values.
+
+            Discontinuities in the value of this counter can occur at
+            re-initialization of the management system, and at other
+            times as indicated by the value of
+            ipSystemStatsDiscontinuityTime."
+    ::= { ipSystemStatsEntry 4 }
+
+ipSystemStatsInOctets OBJECT-TYPE
+    SYNTAX     Counter32
+    MAX-ACCESS read-only
+    STATUS     current
+    DESCRIPTION
+           "The total number of octets received in input IP datagrams,
+            including those received in error.  Octets from datagrams
+            counted in ipSystemStatsInReceives MUST be counted here.
+
+            Discontinuities in the value of this counter can occur at
+            re-initialization of the management system, and at other
+            times as indicated by the value of
+            ipSystemStatsDiscontinuityTime."
+    ::= { ipSystemStatsEntry 5 }
+
+ipSystemStatsHCInOctets OBJECT-TYPE
+    SYNTAX     Counter64
+    MAX-ACCESS read-only
+    STATUS     current
+    DESCRIPTION
+           "The total number of octets received in input IP datagrams,
+            including those received in error.  This object counts the
+            same octets as ipSystemStatsInOctets, but allows for larger
+
+
+
+            values.
+
+            Discontinuities in the value of this counter can occur at
+            re-initialization of the management system, and at other
+            times as indicated by the value of
+            ipSystemStatsDiscontinuityTime."
+    ::= { ipSystemStatsEntry 6 }
+
+ipSystemStatsInHdrErrors OBJECT-TYPE
+    SYNTAX     Counter32
+    MAX-ACCESS read-only
+    STATUS     current
+    DESCRIPTION
+           "The number of input IP datagrams discarded due to errors in
+            their IP headers, including version number mismatch, other
+            format errors, hop count exceeded, errors discovered in
+            processing their IP options, etc.
+
+            Discontinuities in the value of this counter can occur at
+            re-initialization of the management system, and at other
+            times as indicated by the value of
+            ipSystemStatsDiscontinuityTime."
+    ::= { ipSystemStatsEntry 7 }
+
+ipSystemStatsInNoRoutes OBJECT-TYPE
+    SYNTAX     Counter32
+    MAX-ACCESS read-only
+    STATUS     current
+    DESCRIPTION
+           "The number of input IP datagrams discarded because no route
+            could be found to transmit them to their destination.
+
+            Discontinuities in the value of this counter can occur at
+            re-initialization of the management system, and at other
+            times as indicated by the value of
+            ipSystemStatsDiscontinuityTime."
+    ::= { ipSystemStatsEntry 8 }
+
+ipSystemStatsInAddrErrors OBJECT-TYPE
+    SYNTAX     Counter32
+    MAX-ACCESS read-only
+    STATUS     current
+    DESCRIPTION
+           "The number of input IP datagrams discarded because the IP
+            address in their IP header's destination field was not a
+            valid address to be received at this entity.  This count
+            includes invalid addresses (e.g., ::0).  For entities
+            that are not IP routers and therefore do not forward
+
+
+
+            datagrams, this counter includes datagrams discarded
+            because the destination address was not a local address.
+
+            Discontinuities in the value of this counter can occur at
+            re-initialization of the management system, and at other
+            times as indicated by the value of
+            ipSystemStatsDiscontinuityTime."
+    ::= { ipSystemStatsEntry 9 }
+
+ipSystemStatsInUnknownProtos OBJECT-TYPE
+    SYNTAX     Counter32
+    MAX-ACCESS read-only
+    STATUS     current
+    DESCRIPTION
+           "The number of locally-addressed IP datagrams received
+            successfully but discarded because of an unknown or
+            unsupported protocol.
+
+            When tracking interface statistics, the counter of the
+            interface to which these datagrams were addressed is
+            incremented.  This interface might not be the same as the
+            input interface for some of the datagrams.
+
+            Discontinuities in the value of this counter can occur at
+            re-initialization of the management system, and at other
+            times as indicated by the value of
+            ipSystemStatsDiscontinuityTime."
+    ::= { ipSystemStatsEntry 10 }
+
+ipSystemStatsInTruncatedPkts OBJECT-TYPE
+    SYNTAX     Counter32
+    MAX-ACCESS read-only
+    STATUS     current
+    DESCRIPTION
+           "The number of input IP datagrams discarded because the
+            datagram frame didn't carry enough data.
+
+            Discontinuities in the value of this counter can occur at
+            re-initialization of the management system, and at other
+            times as indicated by the value of
+            ipSystemStatsDiscontinuityTime."
+    ::= { ipSystemStatsEntry 11 }
+
+ipSystemStatsInForwDatagrams OBJECT-TYPE
+    SYNTAX     Counter32
+    MAX-ACCESS read-only
+    STATUS     current
+    DESCRIPTION
+
+
+
+           "The number of input datagrams for which this entity was not
+            their final IP destination and for which this entity
+            attempted to find a route to forward them to that final
+            destination.  In entities that do not act as IP routers,
+            this counter will include only those datagrams that were
+            Source-Routed via this entity, and the Source-Route
+            processing was successful.
+
+            When tracking interface statistics, the counter of the
+            incoming interface is incremented for each datagram.
+
+            Discontinuities in the value of this counter can occur at
+            re-initialization of the management system, and at other
+            times as indicated by the value of
+            ipSystemStatsDiscontinuityTime."
+    ::= { ipSystemStatsEntry 12 }
+
+ipSystemStatsHCInForwDatagrams OBJECT-TYPE
+    SYNTAX     Counter64
+    MAX-ACCESS read-only
+    STATUS     current
+    DESCRIPTION
+           "The number of input datagrams for which this entity was not
+            their final IP destination and for which this entity
+            attempted to find a route to forward them to that final
+            destination.  This object counts the same packets as
+            ipSystemStatsInForwDatagrams, but allows for larger values.
+
+            Discontinuities in the value of this counter can occur at
+            re-initialization of the management system, and at other
+            times as indicated by the value of
+            ipSystemStatsDiscontinuityTime."
+    ::= { ipSystemStatsEntry 13 }
+
+ipSystemStatsReasmReqds OBJECT-TYPE
+    SYNTAX     Counter32
+    MAX-ACCESS read-only
+    STATUS     current
+    DESCRIPTION
+           "The number of IP fragments received that needed to be
+            reassembled at this interface.
+
+            When tracking interface statistics, the counter of the
+            interface to which these fragments were addressed is
+            incremented.  This interface might not be the same as the
+            input interface for some of the fragments.
+
+            Discontinuities in the value of this counter can occur at
+
+
+
+            re-initialization of the management system, and at other
+            times as indicated by the value of
+            ipSystemStatsDiscontinuityTime."
+    ::= { ipSystemStatsEntry 14 }
+
+ipSystemStatsReasmOKs OBJECT-TYPE
+    SYNTAX     Counter32
+    MAX-ACCESS read-only
+    STATUS     current
+    DESCRIPTION
+           "The number of IP datagrams successfully reassembled.
+
+            When tracking interface statistics, the counter of the
+            interface to which these datagrams were addressed is
+            incremented.  This interface might not be the same as the
+            input interface for some of the datagrams.
+
+            Discontinuities in the value of this counter can occur at
+            re-initialization of the management system, and at other
+            times as indicated by the value of
+            ipSystemStatsDiscontinuityTime."
+    ::= { ipSystemStatsEntry 15 }
+
+ipSystemStatsReasmFails OBJECT-TYPE
+    SYNTAX     Counter32
+    MAX-ACCESS read-only
+    STATUS     current
+    DESCRIPTION
+           "The number of failures detected by the IP re-assembly
+            algorithm (for whatever reason: timed out, errors, etc.).
+            Note that this is not necessarily a count of discarded IP
+            fragments since some algorithms (notably the algorithm in
+            RFC 815) can lose track of the number of fragments by
+            combining them as they are received.
+
+            When tracking interface statistics, the counter of the
+            interface to which these fragments were addressed is
+            incremented.  This interface might not be the same as the
+            input interface for some of the fragments.
+
+            Discontinuities in the value of this counter can occur at
+            re-initialization of the management system, and at other
+            times as indicated by the value of
+            ipSystemStatsDiscontinuityTime."
+    ::= { ipSystemStatsEntry 16 }
+
+ipSystemStatsInDiscards OBJECT-TYPE
+    SYNTAX     Counter32
+
+
+
+    MAX-ACCESS read-only
+    STATUS     current
+    DESCRIPTION
+           "The number of input IP datagrams for which no problems were
+            encountered to prevent their continued processing, but
+            were discarded (e.g., for lack of buffer space).  Note that
+            this counter does not include any datagrams discarded while
+            awaiting re-assembly.
+
+            Discontinuities in the value of this counter can occur at
+            re-initialization of the management system, and at other
+            times as indicated by the value of
+            ipSystemStatsDiscontinuityTime."
+    ::= { ipSystemStatsEntry 17 }
+
+ipSystemStatsInDelivers OBJECT-TYPE
+    SYNTAX     Counter32
+    MAX-ACCESS read-only
+    STATUS     current
+    DESCRIPTION
+           "The total number of datagrams successfully delivered to IP
+            user-protocols (including ICMP).
+
+            When tracking interface statistics, the counter of the
+            interface to which these datagrams were addressed is
+            incremented.  This interface might not be the same as the
+            input interface for some of the datagrams.
+
+            Discontinuities in the value of this counter can occur at
+            re-initialization of the management system, and at other
+            times as indicated by the value of
+            ipSystemStatsDiscontinuityTime."
+    ::= { ipSystemStatsEntry 18 }
+
+ipSystemStatsHCInDelivers OBJECT-TYPE
+    SYNTAX     Counter64
+    MAX-ACCESS read-only
+    STATUS     current
+    DESCRIPTION
+           "The total number of datagrams successfully delivered to IP
+            user-protocols (including ICMP).  This object counts the
+            same packets as ipSystemStatsInDelivers, but allows for
+            larger values.
+
+            Discontinuities in the value of this counter can occur at
+            re-initialization of the management system, and at other
+            times as indicated by the value of
+            ipSystemStatsDiscontinuityTime."
+
+
+
+    ::= { ipSystemStatsEntry 19 }
+
+ipSystemStatsOutRequests OBJECT-TYPE
+    SYNTAX     Counter32
+    MAX-ACCESS read-only
+    STATUS     current
+    DESCRIPTION
+           "The total number of IP datagrams that local IP user-
+            protocols (including ICMP) supplied to IP in requests for
+            transmission.  Note that this counter does not include any
+            datagrams counted in ipSystemStatsOutForwDatagrams.
+
+            Discontinuities in the value of this counter can occur at
+            re-initialization of the management system, and at other
+            times as indicated by the value of
+            ipSystemStatsDiscontinuityTime."
+    ::= { ipSystemStatsEntry 20 }
+
+ipSystemStatsHCOutRequests OBJECT-TYPE
+    SYNTAX     Counter64
+    MAX-ACCESS read-only
+    STATUS     current
+    DESCRIPTION
+           "The total number of IP datagrams that local IP user-
+            protocols (including ICMP) supplied to IP in requests for
+            transmission.  This object counts the same packets as
+            ipSystemStatsOutRequests, but allows for larger values.
+
+            Discontinuities in the value of this counter can occur at
+            re-initialization of the management system, and at other
+            times as indicated by the value of
+            ipSystemStatsDiscontinuityTime."
+    ::= { ipSystemStatsEntry 21 }
+
+ipSystemStatsOutNoRoutes OBJECT-TYPE
+    SYNTAX     Counter32
+    MAX-ACCESS read-only
+    STATUS     current
+    DESCRIPTION
+           "The number of locally generated IP datagrams discarded
+            because no route could be found to transmit them to their
+            destination.
+
+            Discontinuities in the value of this counter can occur at
+            re-initialization of the management system, and at other
+            times as indicated by the value of
+            ipSystemStatsDiscontinuityTime."
+    ::= { ipSystemStatsEntry 22 }
+
+
+
+ipSystemStatsOutForwDatagrams OBJECT-TYPE
+    SYNTAX     Counter32
+    MAX-ACCESS read-only
+    STATUS     current
+    DESCRIPTION
+           "The number of datagrams for which this entity was not their
+            final IP destination and for which it was successful in
+            finding a path to their final destination.  In entities
+            that do not act as IP routers, this counter will include
+            only those datagrams that were Source-Routed via this
+            entity, and the Source-Route processing was successful.
+
+            When tracking interface statistics, the counter of the
+            outgoing interface is incremented for a successfully
+            forwarded datagram.
+
+            Discontinuities in the value of this counter can occur at
+            re-initialization of the management system, and at other
+            times as indicated by the value of
+            ipSystemStatsDiscontinuityTime."
+    ::= { ipSystemStatsEntry 23 }
+
+ipSystemStatsHCOutForwDatagrams OBJECT-TYPE
+    SYNTAX     Counter64
+    MAX-ACCESS read-only
+    STATUS     current
+    DESCRIPTION
+           "The number of datagrams for which this entity was not their
+            final IP destination and for which it was successful in
+            finding a path to their final destination.  This object
+            counts the same packets as ipSystemStatsOutForwDatagrams,
+            but allows for larger values.
+
+            Discontinuities in the value of this counter can occur at
+            re-initialization of the management system, and at other
+            times as indicated by the value of
+            ipSystemStatsDiscontinuityTime."
+    ::= { ipSystemStatsEntry 24 }
+
+ipSystemStatsOutDiscards OBJECT-TYPE
+    SYNTAX     Counter32
+    MAX-ACCESS read-only
+    STATUS     current
+    DESCRIPTION
+           "The number of output IP datagrams for which no problem was
+            encountered to prevent their transmission to their
+            destination, but were discarded (e.g., for lack of
+            buffer space).  Note that this counter would include
+
+
+
+            datagrams counted in ipSystemStatsOutForwDatagrams if any
+            such datagrams met this (discretionary) discard criterion.
+
+            Discontinuities in the value of this counter can occur at
+            re-initialization of the management system, and at other
+            times as indicated by the value of
+            ipSystemStatsDiscontinuityTime."
+    ::= { ipSystemStatsEntry 25 }
+
+ipSystemStatsOutFragReqds OBJECT-TYPE
+    SYNTAX     Counter32
+    MAX-ACCESS read-only
+    STATUS     current
+    DESCRIPTION
+           "The number of IP datagrams that would require fragmentation
+            in order to be transmitted.
+
+            When tracking interface statistics, the counter of the
+            outgoing interface is incremented for a successfully
+            fragmented datagram.
+
+            Discontinuities in the value of this counter can occur at
+            re-initialization of the management system, and at other
+            times as indicated by the value of
+            ipSystemStatsDiscontinuityTime."
+    ::= { ipSystemStatsEntry 26 }
+
+ipSystemStatsOutFragOKs OBJECT-TYPE
+    SYNTAX     Counter32
+    MAX-ACCESS read-only
+    STATUS     current
+    DESCRIPTION
+           "The number of IP datagrams that have been successfully
+            fragmented.
+
+            When tracking interface statistics, the counter of the
+            outgoing interface is incremented for a successfully
+            fragmented datagram.
+
+            Discontinuities in the value of this counter can occur at
+            re-initialization of the management system, and at other
+            times as indicated by the value of
+            ipSystemStatsDiscontinuityTime."
+    ::= { ipSystemStatsEntry 27 }
+
+ipSystemStatsOutFragFails OBJECT-TYPE
+    SYNTAX     Counter32
+    MAX-ACCESS read-only
+
+
+
+    STATUS     current
+    DESCRIPTION
+           "The number of IP datagrams that have been discarded because
+            they needed to be fragmented but could not be.  This
+            includes IPv4 packets that have the DF bit set and IPv6
+            packets that are being forwarded and exceed the outgoing
+            link MTU.
+
+            When tracking interface statistics, the counter of the
+            outgoing interface is incremented for an unsuccessfully
+            fragmented datagram.
+
+            Discontinuities in the value of this counter can occur at
+            re-initialization of the management system, and at other
+            times as indicated by the value of
+            ipSystemStatsDiscontinuityTime."
+    ::= { ipSystemStatsEntry 28 }
+
+ipSystemStatsOutFragCreates OBJECT-TYPE
+    SYNTAX     Counter32
+    MAX-ACCESS read-only
+    STATUS     current
+    DESCRIPTION
+           "The number of output datagram fragments that have been
+            generated as a result of IP fragmentation.
+
+            When tracking interface statistics, the counter of the
+            outgoing interface is incremented for a successfully
+            fragmented datagram.
+
+            Discontinuities in the value of this counter can occur at
+            re-initialization of the management system, and at other
+            times as indicated by the value of
+            ipSystemStatsDiscontinuityTime."
+    ::= { ipSystemStatsEntry 29 }
+
+ipSystemStatsOutTransmits OBJECT-TYPE
+    SYNTAX     Counter32
+    MAX-ACCESS read-only
+    STATUS     current
+    DESCRIPTION
+           "The total number of IP datagrams that this entity supplied
+            to the lower layers for transmission.  This includes
+            datagrams generated locally and those forwarded by this
+            entity.
+
+            Discontinuities in the value of this counter can occur at
+            re-initialization of the management system, and at other
+
+
+
+            times as indicated by the value of
+            ipSystemStatsDiscontinuityTime."
+    ::= { ipSystemStatsEntry 30 }
+
+ipSystemStatsHCOutTransmits OBJECT-TYPE
+    SYNTAX     Counter64
+    MAX-ACCESS read-only
+    STATUS     current
+    DESCRIPTION
+           "The total number of IP datagrams that this entity supplied
+            to the lower layers for transmission.  This object counts
+            the same datagrams as ipSystemStatsOutTransmits, but allows
+            for larger values.
+
+            Discontinuities in the value of this counter can occur at
+            re-initialization of the management system, and at other
+            times as indicated by the value of
+            ipSystemStatsDiscontinuityTime."
+    ::= { ipSystemStatsEntry 31 }
+
+ipSystemStatsOutOctets OBJECT-TYPE
+    SYNTAX     Counter32
+    MAX-ACCESS read-only
+    STATUS     current
+    DESCRIPTION
+           "The total number of octets in IP datagrams delivered to the
+            lower layers for transmission.  Octets from datagrams
+            counted in ipSystemStatsOutTransmits MUST be counted here.
+
+            Discontinuities in the value of this counter can occur at
+            re-initialization of the management system, and at other
+            times as indicated by the value of
+            ipSystemStatsDiscontinuityTime."
+    ::= { ipSystemStatsEntry 32 }
+
+ipSystemStatsHCOutOctets OBJECT-TYPE
+    SYNTAX     Counter64
+    MAX-ACCESS read-only
+    STATUS     current
+    DESCRIPTION
+           "The total number of octets in IP datagrams delivered to the
+            lower layers for transmission.  This objects counts the same
+            octets as ipSystemStatsOutOctets, but allows for larger
+            values.
+
+            Discontinuities in the value of this counter can occur at
+            re-initialization of the management system, and at other
+            times as indicated by the value of
+
+
+
+            ipSystemStatsDiscontinuityTime."
+    ::= { ipSystemStatsEntry 33 }
+
+ipSystemStatsInMcastPkts OBJECT-TYPE
+    SYNTAX     Counter32
+    MAX-ACCESS read-only
+    STATUS     current
+    DESCRIPTION
+           "The number of IP multicast datagrams received.
+
+            Discontinuities in the value of this counter can occur at
+            re-initialization of the management system, and at other
+            times as indicated by the value of
+            ipSystemStatsDiscontinuityTime."
+    ::= { ipSystemStatsEntry 34 }
+
+ipSystemStatsHCInMcastPkts OBJECT-TYPE
+    SYNTAX     Counter64
+    MAX-ACCESS read-only
+    STATUS     current
+    DESCRIPTION
+           "The number of IP multicast datagrams received.  This object
+            counts the same datagrams as ipSystemStatsInMcastPkts but
+            allows for larger values.
+
+            Discontinuities in the value of this counter can occur at
+            re-initialization of the management system, and at other
+            times as indicated by the value of
+            ipSystemStatsDiscontinuityTime."
+    ::= { ipSystemStatsEntry 35 }
+
+ipSystemStatsInMcastOctets OBJECT-TYPE
+    SYNTAX     Counter32
+    MAX-ACCESS read-only
+    STATUS     current
+    DESCRIPTION
+           "The total number of octets received in IP multicast
+            datagrams.  Octets from datagrams counted in
+            ipSystemStatsInMcastPkts MUST be counted here.
+
+            Discontinuities in the value of this counter can occur at
+            re-initialization of the management system, and at other
+            times as indicated by the value of
+            ipSystemStatsDiscontinuityTime."
+    ::= { ipSystemStatsEntry 36 }
+
+ipSystemStatsHCInMcastOctets OBJECT-TYPE
+    SYNTAX     Counter64
+
+
+
+    MAX-ACCESS read-only
+    STATUS     current
+    DESCRIPTION
+           "The total number of octets received in IP multicast
+            datagrams.  This object counts the same octets as
+            ipSystemStatsInMcastOctets, but allows for larger values.
+
+            Discontinuities in the value of this counter can occur at
+            re-initialization of the management system, and at other
+            times as indicated by the value of
+            ipSystemStatsDiscontinuityTime."
+    ::= { ipSystemStatsEntry 37 }
+
+ipSystemStatsOutMcastPkts OBJECT-TYPE
+    SYNTAX     Counter32
+    MAX-ACCESS read-only
+    STATUS     current
+    DESCRIPTION
+           "The number of IP multicast datagrams transmitted.
+
+            Discontinuities in the value of this counter can occur at
+            re-initialization of the management system, and at other
+            times as indicated by the value of
+            ipSystemStatsDiscontinuityTime."
+    ::= { ipSystemStatsEntry 38 }
+
+ipSystemStatsHCOutMcastPkts OBJECT-TYPE
+    SYNTAX     Counter64
+    MAX-ACCESS read-only
+    STATUS     current
+    DESCRIPTION
+           "The number of IP multicast datagrams transmitted.  This
+            object counts the same datagrams as
+            ipSystemStatsOutMcastPkts, but allows for larger values.
+
+            Discontinuities in the value of this counter can occur at
+            re-initialization of the management system, and at other
+            times as indicated by the value of
+            ipSystemStatsDiscontinuityTime."
+    ::= { ipSystemStatsEntry 39 }
+
+ipSystemStatsOutMcastOctets OBJECT-TYPE
+    SYNTAX     Counter32
+    MAX-ACCESS read-only
+    STATUS     current
+    DESCRIPTION
+           "The total number of octets transmitted in IP multicast
+            datagrams.  Octets from datagrams counted in
+
+
+
+            ipSystemStatsOutMcastPkts MUST be counted here.
+
+            Discontinuities in the value of this counter can occur at
+            re-initialization of the management system, and at other
+            times as indicated by the value of
+            ipSystemStatsDiscontinuityTime."
+    ::= { ipSystemStatsEntry 40 }
+
+ipSystemStatsHCOutMcastOctets OBJECT-TYPE
+    SYNTAX     Counter64
+    MAX-ACCESS read-only
+    STATUS     current
+    DESCRIPTION
+           "The total number of octets transmitted in IP multicast
+            datagrams.  This object counts the same octets as
+            ipSystemStatsOutMcastOctets, but allows for larger values.
+
+            Discontinuities in the value of this counter can occur at
+            re-initialization of the management system, and at other
+            times as indicated by the value of
+            ipSystemStatsDiscontinuityTime."
+    ::= { ipSystemStatsEntry 41 }
+
+ipSystemStatsInBcastPkts OBJECT-TYPE
+    SYNTAX     Counter32
+    MAX-ACCESS read-only
+    STATUS     current
+    DESCRIPTION
+           "The number of IP broadcast datagrams received.
+
+            Discontinuities in the value of this counter can occur at
+            re-initialization of the management system, and at other
+            times as indicated by the value of
+            ipSystemStatsDiscontinuityTime."
+    ::= { ipSystemStatsEntry 42 }
+
+ipSystemStatsHCInBcastPkts OBJECT-TYPE
+    SYNTAX     Counter64
+    MAX-ACCESS read-only
+    STATUS     current
+    DESCRIPTION
+           "The number of IP broadcast datagrams received.  This object
+            counts the same datagrams as ipSystemStatsInBcastPkts but
+            allows for larger values.
+
+            Discontinuities in the value of this counter can occur at
+            re-initialization of the management system, and at other
+            times as indicated by the value of
+
+
+
+            ipSystemStatsDiscontinuityTime."
+    ::= { ipSystemStatsEntry 43 }
+
+ipSystemStatsOutBcastPkts OBJECT-TYPE
+    SYNTAX     Counter32
+    MAX-ACCESS read-only
+    STATUS     current
+    DESCRIPTION
+           "The number of IP broadcast datagrams transmitted.
+
+            Discontinuities in the value of this counter can occur at
+            re-initialization of the management system, and at other
+            times as indicated by the value of
+            ipSystemStatsDiscontinuityTime."
+    ::= { ipSystemStatsEntry 44 }
+
+ipSystemStatsHCOutBcastPkts OBJECT-TYPE
+    SYNTAX     Counter64
+    MAX-ACCESS read-only
+    STATUS     current
+    DESCRIPTION
+           "The number of IP broadcast datagrams transmitted.  This
+            object counts the same datagrams as
+            ipSystemStatsOutBcastPkts, but allows for larger values.
+
+            Discontinuities in the value of this counter can occur at
+            re-initialization of the management system, and at other
+            times as indicated by the value of
+            ipSystemStatsDiscontinuityTime."
+    ::= { ipSystemStatsEntry 45 }
+
+ipSystemStatsDiscontinuityTime OBJECT-TYPE
+    SYNTAX     TimeStamp
+    MAX-ACCESS read-only
+    STATUS     current
+    DESCRIPTION
+           "The value of sysUpTime on the most recent occasion at which
+            any one or more of this entry's counters suffered a
+            discontinuity.
+
+            If no such discontinuities have occurred since the last re-
+            initialization of the local management subsystem, then this
+            object contains a zero value."
+    ::= { ipSystemStatsEntry 46 }
+
+ipSystemStatsRefreshRate OBJECT-TYPE
+    SYNTAX     Unsigned32
+    UNITS      "milli-seconds"
+
+
+
+    MAX-ACCESS read-only
+    STATUS     current
+    DESCRIPTION
+           "The minimum reasonable polling interval for this entry.
+            This object provides an indication of the minimum amount of
+            time required to update the counters in this entry."
+    ::= { ipSystemStatsEntry 47 }
+
+ipIfStatsTableLastChange OBJECT-TYPE
+    SYNTAX     TimeStamp
+    MAX-ACCESS read-only
+    STATUS     current
+    DESCRIPTION
+           "The value of sysUpTime on the most recent occasion at which
+            a row in the ipIfStatsTable was added or deleted.
+
+            If new objects are added to the ipIfStatsTable that require
+            the ipIfStatsTableLastChange to be updated when they are
+            modified, they must specify that requirement in their
+            description clause."
+    ::= { ipTrafficStats 2 }
+
+ipIfStatsTable OBJECT-TYPE
+    SYNTAX     SEQUENCE OF IpIfStatsEntry
+    MAX-ACCESS not-accessible
+    STATUS     current
+    DESCRIPTION
+           "The table containing per-interface traffic statistics.  This
+            table and the ipSystemStatsTable contain similar objects
+            whose difference is in their granularity.  Where this table
+            contains per-interface statistics, the ipSystemStatsTable
+            contains the same statistics, but counted on a system wide
+            basis."
+    ::= { ipTrafficStats 3 }
+
+ipIfStatsEntry OBJECT-TYPE
+    SYNTAX     IpIfStatsEntry
+    MAX-ACCESS not-accessible
+    STATUS     current
+    DESCRIPTION
+           "An interface statistics entry containing objects for a
+            particular interface and version of IP."
+    INDEX { ipIfStatsIPVersion, ipIfStatsIfIndex }
+    ::= { ipIfStatsTable 1 }
+
+IpIfStatsEntry ::= SEQUENCE {
+        ipIfStatsIPVersion           InetVersion,
+        ipIfStatsIfIndex             InterfaceIndex,
+
+
+
+        ipIfStatsInReceives          Counter32,
+        ipIfStatsHCInReceives        Counter64,
+        ipIfStatsInOctets            Counter32,
+        ipIfStatsHCInOctets          Counter64,
+        ipIfStatsInHdrErrors         Counter32,
+        ipIfStatsInNoRoutes          Counter32,
+        ipIfStatsInAddrErrors        Counter32,
+        ipIfStatsInUnknownProtos     Counter32,
+        ipIfStatsInTruncatedPkts     Counter32,
+        ipIfStatsInForwDatagrams     Counter32,
+        ipIfStatsHCInForwDatagrams   Counter64,
+        ipIfStatsReasmReqds          Counter32,
+        ipIfStatsReasmOKs            Counter32,
+        ipIfStatsReasmFails          Counter32,
+        ipIfStatsInDiscards          Counter32,
+        ipIfStatsInDelivers          Counter32,
+        ipIfStatsHCInDelivers        Counter64,
+        ipIfStatsOutRequests         Counter32,
+        ipIfStatsHCOutRequests       Counter64,
+        ipIfStatsOutForwDatagrams    Counter32,
+        ipIfStatsHCOutForwDatagrams  Counter64,
+        ipIfStatsOutDiscards         Counter32,
+        ipIfStatsOutFragReqds        Counter32,
+        ipIfStatsOutFragOKs          Counter32,
+        ipIfStatsOutFragFails        Counter32,
+        ipIfStatsOutFragCreates      Counter32,
+        ipIfStatsOutTransmits        Counter32,
+        ipIfStatsHCOutTransmits      Counter64,
+        ipIfStatsOutOctets           Counter32,
+        ipIfStatsHCOutOctets         Counter64,
+        ipIfStatsInMcastPkts         Counter32,
+        ipIfStatsHCInMcastPkts       Counter64,
+        ipIfStatsInMcastOctets       Counter32,
+        ipIfStatsHCInMcastOctets     Counter64,
+        ipIfStatsOutMcastPkts        Counter32,
+        ipIfStatsHCOutMcastPkts      Counter64,
+        ipIfStatsOutMcastOctets      Counter32,
+        ipIfStatsHCOutMcastOctets    Counter64,
+        ipIfStatsInBcastPkts         Counter32,
+        ipIfStatsHCInBcastPkts       Counter64,
+        ipIfStatsOutBcastPkts        Counter32,
+        ipIfStatsHCOutBcastPkts      Counter64,
+        ipIfStatsDiscontinuityTime   TimeStamp,
+        ipIfStatsRefreshRate         Unsigned32
+    }
+
+ipIfStatsIPVersion OBJECT-TYPE
+    SYNTAX     InetVersion
+
+
+
+    MAX-ACCESS not-accessible
+    STATUS     current
+    DESCRIPTION
+           "The IP version of this row."
+    ::= { ipIfStatsEntry 1 }
+
+ipIfStatsIfIndex OBJECT-TYPE
+    SYNTAX     InterfaceIndex
+    MAX-ACCESS not-accessible
+    STATUS     current
+    DESCRIPTION
+           "The index value that uniquely identifies the interface to
+            which this entry is applicable.  The interface identified by
+            a particular value of this index is the same interface as
+            identified by the same value of the IF-MIB's ifIndex."
+    ::= { ipIfStatsEntry 2 }
+
+ipIfStatsInReceives OBJECT-TYPE
+    SYNTAX     Counter32
+    MAX-ACCESS read-only
+    STATUS     current
+    DESCRIPTION
+           "The total number of input IP datagrams received, including
+            those received in error.
+
+            Discontinuities in the value of this counter can occur at
+            re-initialization of the management system, and at other
+            times as indicated by the value of
+            ipIfStatsDiscontinuityTime."
+    ::= { ipIfStatsEntry 3 }
+
+ipIfStatsHCInReceives OBJECT-TYPE
+    SYNTAX     Counter64
+    MAX-ACCESS read-only
+    STATUS     current
+    DESCRIPTION
+           "The total number of input IP datagrams received, including
+            those received in error.  This object counts the same
+            datagrams as ipIfStatsInReceives, but allows for larger
+            values.
+
+            Discontinuities in the value of this counter can occur at
+            re-initialization of the management system, and at other
+            times as indicated by the value of
+            ipIfStatsDiscontinuityTime."
+    ::= { ipIfStatsEntry 4 }
+
+ipIfStatsInOctets OBJECT-TYPE
+
+
+
+    SYNTAX     Counter32
+    MAX-ACCESS read-only
+    STATUS     current
+    DESCRIPTION
+           "The total number of octets received in input IP datagrams,
+            including those received in error.  Octets from datagrams
+            counted in ipIfStatsInReceives MUST be counted here.
+
+            Discontinuities in the value of this counter can occur at
+            re-initialization of the management system, and at other
+            times as indicated by the value of
+            ipIfStatsDiscontinuityTime."
+    ::= { ipIfStatsEntry 5 }
+
+ipIfStatsHCInOctets OBJECT-TYPE
+    SYNTAX     Counter64
+    MAX-ACCESS read-only
+    STATUS     current
+    DESCRIPTION
+           "The total number of octets received in input IP datagrams,
+            including those received in error.  This object counts the
+            same octets as ipIfStatsInOctets, but allows for larger
+            values.
+
+            Discontinuities in the value of this counter can occur at
+            re-initialization of the management system, and at other
+            times as indicated by the value of
+            ipIfStatsDiscontinuityTime."
+    ::= { ipIfStatsEntry 6 }
+
+ipIfStatsInHdrErrors OBJECT-TYPE
+    SYNTAX     Counter32
+    MAX-ACCESS read-only
+    STATUS     current
+    DESCRIPTION
+           "The number of input IP datagrams discarded due to errors in
+            their IP headers, including version number mismatch, other
+            format errors, hop count exceeded, errors discovered in
+            processing their IP options, etc.
+
+            Discontinuities in the value of this counter can occur at
+            re-initialization of the management system, and at other
+            times as indicated by the value of
+            ipIfStatsDiscontinuityTime."
+    ::= { ipIfStatsEntry 7 }
+
+ipIfStatsInNoRoutes OBJECT-TYPE
+    SYNTAX     Counter32
+
+
+
+    MAX-ACCESS read-only
+    STATUS     current
+    DESCRIPTION
+           "The number of input IP datagrams discarded because no route
+            could be found to transmit them to their destination.
+
+            Discontinuities in the value of this counter can occur at
+            re-initialization of the management system, and at other
+            times as indicated by the value of
+            ipIfStatsDiscontinuityTime."
+    ::= { ipIfStatsEntry 8 }
+
+ipIfStatsInAddrErrors OBJECT-TYPE
+    SYNTAX     Counter32
+    MAX-ACCESS read-only
+    STATUS     current
+    DESCRIPTION
+           "The number of input IP datagrams discarded because the IP
+            address in their IP header's destination field was not a
+            valid address to be received at this entity.  This count
+            includes invalid addresses (e.g., ::0).  For entities that
+            are not IP routers and therefore do not forward datagrams,
+            this counter includes datagrams discarded because the
+            destination address was not a local address.
+
+            Discontinuities in the value of this counter can occur at
+            re-initialization of the management system, and at other
+            times as indicated by the value of
+            ipIfStatsDiscontinuityTime."
+    ::= { ipIfStatsEntry 9 }
+
+ipIfStatsInUnknownProtos OBJECT-TYPE
+    SYNTAX     Counter32
+    MAX-ACCESS read-only
+    STATUS     current
+    DESCRIPTION
+           "The number of locally-addressed IP datagrams received
+            successfully but discarded because of an unknown or
+            unsupported protocol.
+
+            When tracking interface statistics, the counter of the
+            interface to which these datagrams were addressed is
+            incremented.  This interface might not be the same as the
+            input interface for some of the datagrams.
+
+            Discontinuities in the value of this counter can occur at
+            re-initialization of the management system, and at other
+            times as indicated by the value of
+
+
+
+            ipIfStatsDiscontinuityTime."
+    ::= { ipIfStatsEntry 10 }
+
+ipIfStatsInTruncatedPkts OBJECT-TYPE
+    SYNTAX     Counter32
+    MAX-ACCESS read-only
+    STATUS     current
+    DESCRIPTION
+           "The number of input IP datagrams discarded because the
+            datagram frame didn't carry enough data.
+
+            Discontinuities in the value of this counter can occur at
+            re-initialization of the management system, and at other
+            times as indicated by the value of
+            ipIfStatsDiscontinuityTime."
+    ::= { ipIfStatsEntry 11 }
+
+ipIfStatsInForwDatagrams OBJECT-TYPE
+    SYNTAX     Counter32
+    MAX-ACCESS read-only
+    STATUS     current
+    DESCRIPTION
+           "The number of input datagrams for which this entity was not
+            their final IP destination and for which this entity
+            attempted to find a route to forward them to that final
+            destination.  In entities that do not act as IP routers,
+            this counter will include only those datagrams that were
+            Source-Routed via this entity, and the Source-Route
+            processing was successful.
+
+            When tracking interface statistics, the counter of the
+            incoming interface is incremented for each datagram.
+
+            Discontinuities in the value of this counter can occur at
+            re-initialization of the management system, and at other
+            times as indicated by the value of
+            ipIfStatsDiscontinuityTime."
+    ::= { ipIfStatsEntry 12 }
+
+ipIfStatsHCInForwDatagrams OBJECT-TYPE
+    SYNTAX     Counter64
+    MAX-ACCESS read-only
+    STATUS     current
+    DESCRIPTION
+           "The number of input datagrams for which this entity was not
+            their final IP destination and for which this entity
+            attempted to find a route to forward them to that final
+            destination.  This object counts the same packets as
+
+
+
+            ipIfStatsInForwDatagrams, but allows for larger values.
+
+            Discontinuities in the value of this counter can occur at
+            re-initialization of the management system, and at other
+            times as indicated by the value of
+            ipIfStatsDiscontinuityTime."
+    ::= { ipIfStatsEntry 13 }
+
+ipIfStatsReasmReqds OBJECT-TYPE
+    SYNTAX     Counter32
+    MAX-ACCESS read-only
+    STATUS     current
+    DESCRIPTION
+           "The number of IP fragments received that needed to be
+            reassembled at this interface.
+
+            When tracking interface statistics, the counter of the
+            interface to which these fragments were addressed is
+            incremented.  This interface might not be the same as the
+            input interface for some of the fragments.
+
+            Discontinuities in the value of this counter can occur at
+            re-initialization of the management system, and at other
+            times as indicated by the value of
+            ipIfStatsDiscontinuityTime."
+    ::= { ipIfStatsEntry 14 }
+
+ipIfStatsReasmOKs OBJECT-TYPE
+    SYNTAX     Counter32
+    MAX-ACCESS read-only
+    STATUS     current
+    DESCRIPTION
+           "The number of IP datagrams successfully reassembled.
+
+            When tracking interface statistics, the counter of the
+            interface to which these datagrams were addressed is
+            incremented.  This interface might not be the same as the
+            input interface for some of the datagrams.
+
+            Discontinuities in the value of this counter can occur at
+            re-initialization of the management system, and at other
+            times as indicated by the value of
+            ipIfStatsDiscontinuityTime."
+    ::= { ipIfStatsEntry 15 }
+
+ipIfStatsReasmFails OBJECT-TYPE
+    SYNTAX     Counter32
+    MAX-ACCESS read-only
+
+
+
+    STATUS     current
+    DESCRIPTION
+           "The number of failures detected by the IP re-assembly
+            algorithm (for whatever reason: timed out, errors, etc.).
+            Note that this is not necessarily a count of discarded IP
+            fragments since some algorithms (notably the algorithm in
+            RFC 815) can lose track of the number of fragments by
+            combining them as they are received.
+
+            When tracking interface statistics, the counter of the
+            interface to which these fragments were addressed is
+            incremented.  This interface might not be the same as the
+            input interface for some of the fragments.
+
+            Discontinuities in the value of this counter can occur at
+            re-initialization of the management system, and at other
+            times as indicated by the value of
+            ipIfStatsDiscontinuityTime."
+    ::= { ipIfStatsEntry 16 }
+
+ipIfStatsInDiscards OBJECT-TYPE
+    SYNTAX     Counter32
+    MAX-ACCESS read-only
+    STATUS     current
+    DESCRIPTION
+           "The number of input IP datagrams for which no problems were
+            encountered to prevent their continued processing, but
+            were discarded (e.g., for lack of buffer space).  Note that
+            this counter does not include any datagrams discarded while
+            awaiting re-assembly.
+
+            Discontinuities in the value of this counter can occur at
+            re-initialization of the management system, and at other
+            times as indicated by the value of
+            ipIfStatsDiscontinuityTime."
+    ::= { ipIfStatsEntry 17 }
+
+ipIfStatsInDelivers OBJECT-TYPE
+    SYNTAX     Counter32
+    MAX-ACCESS read-only
+    STATUS     current
+    DESCRIPTION
+           "The total number of datagrams successfully delivered to IP
+            user-protocols (including ICMP).
+
+            When tracking interface statistics, the counter of the
+            interface to which these datagrams were addressed is
+            incremented.  This interface might not be the same as the
+
+
+
+            input interface for some of the datagrams.
+
+            Discontinuities in the value of this counter can occur at
+            re-initialization of the management system, and at other
+            times as indicated by the value of
+            ipIfStatsDiscontinuityTime."
+    ::= { ipIfStatsEntry 18 }
+
+ipIfStatsHCInDelivers OBJECT-TYPE
+    SYNTAX     Counter64
+    MAX-ACCESS read-only
+    STATUS     current
+    DESCRIPTION
+           "The total number of datagrams successfully delivered to IP
+            user-protocols (including ICMP).  This object counts the
+            same packets as ipIfStatsInDelivers, but allows for larger
+            values.
+
+            Discontinuities in the value of this counter can occur at
+            re-initialization of the management system, and at other
+            times as indicated by the value of
+            ipIfStatsDiscontinuityTime."
+    ::= { ipIfStatsEntry 19 }
+
+ipIfStatsOutRequests OBJECT-TYPE
+    SYNTAX     Counter32
+    MAX-ACCESS read-only
+    STATUS     current
+    DESCRIPTION
+           "The total number of IP datagrams that local IP user-
+            protocols (including ICMP) supplied to IP in requests for
+            transmission.  Note that this counter does not include any
+            datagrams counted in ipIfStatsOutForwDatagrams.
+
+            Discontinuities in the value of this counter can occur at
+            re-initialization of the management system, and at other
+            times as indicated by the value of
+            ipIfStatsDiscontinuityTime."
+    ::= { ipIfStatsEntry 20 }
+
+ipIfStatsHCOutRequests OBJECT-TYPE
+    SYNTAX     Counter64
+    MAX-ACCESS read-only
+    STATUS     current
+    DESCRIPTION
+           "The total number of IP datagrams that local IP user-
+            protocols (including ICMP) supplied to IP in requests for
+            transmission.  This object counts the same packets as
+
+
+
+            ipIfStatsOutRequests, but allows for larger values.
+
+            Discontinuities in the value of this counter can occur at
+            re-initialization of the management system, and at other
+            times as indicated by the value of
+            ipIfStatsDiscontinuityTime."
+    ::= { ipIfStatsEntry 21 }
+
+-- This object ID is reserved to allow the IDs for this table's objects
+-- to align with the objects in the ipSystemStatsTable.
+-- ::= {ipIfStatsEntry 22}
+
+ipIfStatsOutForwDatagrams OBJECT-TYPE
+    SYNTAX     Counter32
+    MAX-ACCESS read-only
+    STATUS     current
+    DESCRIPTION
+           "The number of datagrams for which this entity was not their
+            final IP destination and for which it was successful in
+            finding a path to their final destination.  In entities
+            that do not act as IP routers, this counter will include
+            only those datagrams that were Source-Routed via this
+            entity, and the Source-Route processing was successful.
+
+            When tracking interface statistics, the counter of the
+            outgoing interface is incremented for a successfully
+            forwarded datagram.
+
+            Discontinuities in the value of this counter can occur at
+            re-initialization of the management system, and at other
+            times as indicated by the value of
+            ipIfStatsDiscontinuityTime."
+    ::= { ipIfStatsEntry 23 }
+
+ipIfStatsHCOutForwDatagrams OBJECT-TYPE
+    SYNTAX     Counter64
+    MAX-ACCESS read-only
+    STATUS     current
+    DESCRIPTION
+           "The number of datagrams for which this entity was not their
+            final IP destination and for which it was successful in
+            finding a path to their final destination.  This object
+            counts the same packets as ipIfStatsOutForwDatagrams, but
+            allows for larger values.
+
+            Discontinuities in the value of this counter can occur at
+            re-initialization of the management system, and at other
+            times as indicated by the value of
+
+
+
+            ipIfStatsDiscontinuityTime."
+    ::= { ipIfStatsEntry 24 }
+
+ipIfStatsOutDiscards OBJECT-TYPE
+    SYNTAX     Counter32
+    MAX-ACCESS read-only
+    STATUS     current
+    DESCRIPTION
+           "The number of output IP datagrams for which no problem was
+            encountered to prevent their transmission to their
+            destination, but were discarded (e.g., for lack of
+            buffer space).  Note that this counter would include
+            datagrams counted in ipIfStatsOutForwDatagrams if any such
+            datagrams met this (discretionary) discard criterion.
+
+            Discontinuities in the value of this counter can occur at
+            re-initialization of the management system, and at other
+            times as indicated by the value of
+            ipIfStatsDiscontinuityTime."
+    ::= { ipIfStatsEntry 25 }
+
+ipIfStatsOutFragReqds OBJECT-TYPE
+    SYNTAX     Counter32
+    MAX-ACCESS read-only
+    STATUS     current
+    DESCRIPTION
+           "The number of IP datagrams that would require fragmentation
+            in order to be transmitted.
+
+            When tracking interface statistics, the counter of the
+            outgoing interface is incremented for a successfully
+            fragmented datagram.
+
+            Discontinuities in the value of this counter can occur at
+            re-initialization of the management system, and at other
+            times as indicated by the value of
+            ipIfStatsDiscontinuityTime."
+    ::= { ipIfStatsEntry 26 }
+
+ipIfStatsOutFragOKs OBJECT-TYPE
+    SYNTAX     Counter32
+    MAX-ACCESS read-only
+    STATUS     current
+    DESCRIPTION
+           "The number of IP datagrams that have been successfully
+            fragmented.
+
+            When tracking interface statistics, the counter of the
+
+
+
+            outgoing interface is incremented for a successfully
+            fragmented datagram.
+
+            Discontinuities in the value of this counter can occur at
+            re-initialization of the management system, and at other
+            times as indicated by the value of
+            ipIfStatsDiscontinuityTime."
+    ::= { ipIfStatsEntry 27 }
+
+ipIfStatsOutFragFails OBJECT-TYPE
+    SYNTAX     Counter32
+    MAX-ACCESS read-only
+    STATUS     current
+    DESCRIPTION
+           "The number of IP datagrams that have been discarded because
+            they needed to be fragmented but could not be.  This
+            includes IPv4 packets that have the DF bit set and IPv6
+            packets that are being forwarded and exceed the outgoing
+            link MTU.
+
+            When tracking interface statistics, the counter of the
+            outgoing interface is incremented for an unsuccessfully
+            fragmented datagram.
+
+            Discontinuities in the value of this counter can occur at
+            re-initialization of the management system, and at other
+            times as indicated by the value of
+            ipIfStatsDiscontinuityTime."
+    ::= { ipIfStatsEntry 28 }
+
+ipIfStatsOutFragCreates OBJECT-TYPE
+    SYNTAX     Counter32
+    MAX-ACCESS read-only
+    STATUS     current
+    DESCRIPTION
+           "The number of output datagram fragments that have been
+            generated as a result of IP fragmentation.
+
+            When tracking interface statistics, the counter of the
+            outgoing interface is incremented for a successfully
+            fragmented datagram.
+
+            Discontinuities in the value of this counter can occur at
+            re-initialization of the management system, and at other
+            times as indicated by the value of
+            ipIfStatsDiscontinuityTime."
+    ::= { ipIfStatsEntry 29 }
+
+
+
+
+ipIfStatsOutTransmits OBJECT-TYPE
+    SYNTAX     Counter32
+    MAX-ACCESS read-only
+    STATUS     current
+    DESCRIPTION
+           "The total number of IP datagrams that this entity supplied
+            to the lower layers for transmission.  This includes
+            datagrams generated locally and those forwarded by this
+            entity.
+
+            Discontinuities in the value of this counter can occur at
+            re-initialization of the management system, and at other
+            times as indicated by the value of
+            ipIfStatsDiscontinuityTime."
+    ::= { ipIfStatsEntry 30 }
+
+ipIfStatsHCOutTransmits OBJECT-TYPE
+    SYNTAX     Counter64
+    MAX-ACCESS read-only
+    STATUS     current
+    DESCRIPTION
+           "The total number of IP datagrams that this entity supplied
+            to the lower layers for transmission.  This object counts
+            the same datagrams as ipIfStatsOutTransmits, but allows for
+            larger values.
+
+            Discontinuities in the value of this counter can occur at
+            re-initialization of the management system, and at other
+            times as indicated by the value of
+            ipIfStatsDiscontinuityTime."
+    ::= { ipIfStatsEntry 31 }
+
+ipIfStatsOutOctets OBJECT-TYPE
+    SYNTAX     Counter32
+    MAX-ACCESS read-only
+    STATUS     current
+    DESCRIPTION
+           "The total number of octets in IP datagrams delivered to the
+            lower layers for transmission.  Octets from datagrams
+            counted in ipIfStatsOutTransmits MUST be counted here.
+
+            Discontinuities in the value of this counter can occur at
+            re-initialization of the management system, and at other
+            times as indicated by the value of
+            ipIfStatsDiscontinuityTime."
+    ::= { ipIfStatsEntry 32 }
+
+ipIfStatsHCOutOctets OBJECT-TYPE
+
+
+
+    SYNTAX     Counter64
+    MAX-ACCESS read-only
+    STATUS     current
+    DESCRIPTION
+           "The total number of octets in IP datagrams delivered to the
+            lower layers for transmission.  This objects counts the same
+            octets as ipIfStatsOutOctets, but allows for larger values.
+
+            Discontinuities in the value of this counter can occur at
+            re-initialization of the management system, and at other
+            times as indicated by the value of
+            ipIfStatsDiscontinuityTime."
+    ::= { ipIfStatsEntry 33 }
+
+ipIfStatsInMcastPkts OBJECT-TYPE
+    SYNTAX     Counter32
+    MAX-ACCESS read-only
+    STATUS     current
+    DESCRIPTION
+           "The number of IP multicast datagrams received.
+
+            Discontinuities in the value of this counter can occur at
+            re-initialization of the management system, and at other
+            times as indicated by the value of
+            ipIfStatsDiscontinuityTime."
+    ::= { ipIfStatsEntry 34 }
+
+ipIfStatsHCInMcastPkts OBJECT-TYPE
+    SYNTAX     Counter64
+    MAX-ACCESS read-only
+    STATUS     current
+    DESCRIPTION
+           "The number of IP multicast datagrams received.  This object
+            counts the same datagrams as ipIfStatsInMcastPkts, but
+            allows for larger values.
+
+            Discontinuities in the value of this counter can occur at
+            re-initialization of the management system, and at other
+            times as indicated by the value of
+            ipIfStatsDiscontinuityTime."
+    ::= { ipIfStatsEntry 35 }
+
+ipIfStatsInMcastOctets OBJECT-TYPE
+    SYNTAX     Counter32
+    MAX-ACCESS read-only
+    STATUS     current
+    DESCRIPTION
+           "The total number of octets received in IP multicast
+
+
+
+            datagrams.  Octets from datagrams counted in
+            ipIfStatsInMcastPkts MUST be counted here.
+
+            Discontinuities in the value of this counter can occur at
+            re-initialization of the management system, and at other
+            times as indicated by the value of
+            ipIfStatsDiscontinuityTime."
+    ::= { ipIfStatsEntry 36 }
+
+ipIfStatsHCInMcastOctets OBJECT-TYPE
+    SYNTAX     Counter64
+    MAX-ACCESS read-only
+    STATUS     current
+    DESCRIPTION
+           "The total number of octets received in IP multicast
+            datagrams.  This object counts the same octets as
+            ipIfStatsInMcastOctets, but allows for larger values.
+
+            Discontinuities in the value of this counter can occur at
+            re-initialization of the management system, and at other
+            times as indicated by the value of
+            ipIfStatsDiscontinuityTime."
+    ::= { ipIfStatsEntry 37 }
+
+ipIfStatsOutMcastPkts OBJECT-TYPE
+    SYNTAX     Counter32
+    MAX-ACCESS read-only
+    STATUS     current
+    DESCRIPTION
+           "The number of IP multicast datagrams transmitted.
+
+            Discontinuities in the value of this counter can occur at
+            re-initialization of the management system, and at other
+            times as indicated by the value of
+            ipIfStatsDiscontinuityTime."
+    ::= { ipIfStatsEntry 38 }
+
+ipIfStatsHCOutMcastPkts OBJECT-TYPE
+    SYNTAX     Counter64
+    MAX-ACCESS read-only
+    STATUS     current
+    DESCRIPTION
+           "The number of IP multicast datagrams transmitted.  This
+            object counts the same datagrams as ipIfStatsOutMcastPkts,
+            but allows for larger values.
+
+            Discontinuities in the value of this counter can occur at
+            re-initialization of the management system, and at other
+
+
+
+            times as indicated by the value of
+            ipIfStatsDiscontinuityTime."
+    ::= { ipIfStatsEntry 39 }
+
+ipIfStatsOutMcastOctets OBJECT-TYPE
+    SYNTAX     Counter32
+    MAX-ACCESS read-only
+    STATUS     current
+    DESCRIPTION
+           "The total number of octets transmitted in IP multicast
+            datagrams.  Octets from datagrams counted in
+            ipIfStatsOutMcastPkts MUST be counted here.
+
+            Discontinuities in the value of this counter can occur at
+            re-initialization of the management system, and at other
+            times as indicated by the value of
+            ipIfStatsDiscontinuityTime."
+    ::= { ipIfStatsEntry 40 }
+
+ipIfStatsHCOutMcastOctets OBJECT-TYPE
+    SYNTAX     Counter64
+    MAX-ACCESS read-only
+    STATUS     current
+    DESCRIPTION
+           "The total number of octets transmitted in IP multicast
+            datagrams.  This object counts the same octets as
+            ipIfStatsOutMcastOctets, but allows for larger values.
+
+            Discontinuities in the value of this counter can occur at
+            re-initialization of the management system, and at other
+            times as indicated by the value of
+            ipIfStatsDiscontinuityTime."
+    ::= { ipIfStatsEntry 41 }
+
+ipIfStatsInBcastPkts OBJECT-TYPE
+    SYNTAX     Counter32
+    MAX-ACCESS read-only
+    STATUS     current
+    DESCRIPTION
+           "The number of IP broadcast datagrams received.
+
+            Discontinuities in the value of this counter can occur at
+            re-initialization of the management system, and at other
+            times as indicated by the value of
+            ipIfStatsDiscontinuityTime."
+    ::= { ipIfStatsEntry 42 }
+
+ipIfStatsHCInBcastPkts OBJECT-TYPE
+
+
+
+    SYNTAX     Counter64
+    MAX-ACCESS read-only
+    STATUS     current
+    DESCRIPTION
+           "The number of IP broadcast datagrams received.  This object
+            counts the same datagrams as ipIfStatsInBcastPkts, but
+            allows for larger values.
+
+            Discontinuities in the value of this counter can occur at
+            re-initialization of the management system, and at other
+            times as indicated by the value of
+            ipIfStatsDiscontinuityTime."
+    ::= { ipIfStatsEntry 43 }
+
+ipIfStatsOutBcastPkts OBJECT-TYPE
+    SYNTAX     Counter32
+    MAX-ACCESS read-only
+    STATUS     current
+    DESCRIPTION
+           "The number of IP broadcast datagrams transmitted.
+
+            Discontinuities in the value of this counter can occur at
+            re-initialization of the management system, and at other
+            times as indicated by the value of
+            ipIfStatsDiscontinuityTime."
+    ::= { ipIfStatsEntry 44 }
+
+ipIfStatsHCOutBcastPkts OBJECT-TYPE
+    SYNTAX     Counter64
+    MAX-ACCESS read-only
+    STATUS     current
+    DESCRIPTION
+           "The number of IP broadcast datagrams transmitted.  This
+            object counts the same datagrams as ipIfStatsOutBcastPkts,
+            but allows for larger values.
+
+            Discontinuities in the value of this counter can occur at
+            re-initialization of the management system, and at other
+            times as indicated by the value of
+            ipIfStatsDiscontinuityTime."
+    ::= { ipIfStatsEntry 45 }
+
+ipIfStatsDiscontinuityTime OBJECT-TYPE
+    SYNTAX     TimeStamp
+    MAX-ACCESS read-only
+    STATUS     current
+    DESCRIPTION
+           "The value of sysUpTime on the most recent occasion at which
+
+
+
+            any one or more of this entry's counters suffered a
+            discontinuity.
+
+            If no such discontinuities have occurred since the last re-
+            initialization of the local management subsystem, then this
+            object contains a zero value."
+    ::= { ipIfStatsEntry 46 }
+
+ipIfStatsRefreshRate OBJECT-TYPE
+    SYNTAX     Unsigned32
+    UNITS "milli-seconds"
+    MAX-ACCESS read-only
+    STATUS     current
+    DESCRIPTION
+           "The minimum reasonable polling interval for this entry.
+            This object provides an indication of the minimum amount of
+            time required to update the counters in this entry."
+    ::= { ipIfStatsEntry 47 }
+
+--
+-- Internet Address Prefix table
+--
+
+ipAddressPrefixTable OBJECT-TYPE
+    SYNTAX     SEQUENCE OF IpAddressPrefixEntry
+    MAX-ACCESS not-accessible
+    STATUS     current
+    DESCRIPTION
+           "This table allows the user to determine the source of an IP
+            address or set of IP addresses, and allows other tables to
+            share the information via pointer rather than by copying.
+
+            For example, when the node configures both a unicast and
+            anycast address for a prefix, the ipAddressPrefix objects
+            for those addresses will point to a single row in this
+            table.
+
+            This table primarily provides support for IPv6 prefixes, and
+            several of the objects are less meaningful for IPv4.  The
+            table continues to allow IPv4 addresses to allow future
+            flexibility.  In order to promote a common configuration,
+            this document includes suggestions for default values for
+            IPv4 prefixes.  Each of these values may be overridden if an
+            object is meaningful to the node.
+
+            All prefixes used by this entity should be included in this
+            table independent of how the entity learned the prefix.
+            (This table isn't limited to prefixes learned from router
+
+
+
+            advertisements.)"
+    ::= { ip 32 }
+
+ipAddressPrefixEntry OBJECT-TYPE
+    SYNTAX     IpAddressPrefixEntry
+    MAX-ACCESS not-accessible
+    STATUS     current
+    DESCRIPTION
+           "An entry in the ipAddressPrefixTable."
+    INDEX    { ipAddressPrefixIfIndex, ipAddressPrefixType,
+               ipAddressPrefixPrefix, ipAddressPrefixLength }
+    ::= { ipAddressPrefixTable 1 }
+
+IpAddressPrefixEntry ::= SEQUENCE {
+        ipAddressPrefixIfIndex               InterfaceIndex,
+        ipAddressPrefixType                  InetAddressType,
+        ipAddressPrefixPrefix                InetAddress,
+        ipAddressPrefixLength                InetAddressPrefixLength,
+        ipAddressPrefixOrigin                IpAddressPrefixOriginTC,
+        ipAddressPrefixOnLinkFlag            TruthValue,
+        ipAddressPrefixAutonomousFlag        TruthValue,
+        ipAddressPrefixAdvPreferredLifetime  Unsigned32,
+        ipAddressPrefixAdvValidLifetime      Unsigned32
+    }
+
+ipAddressPrefixIfIndex OBJECT-TYPE
+    SYNTAX     InterfaceIndex
+    MAX-ACCESS not-accessible
+    STATUS     current
+    DESCRIPTION
+           "The index value that uniquely identifies the interface on
+            which this prefix is configured.  The interface identified
+            by a particular value of this index is the same interface as
+            identified by the same value of the IF-MIB's ifIndex."
+    ::= { ipAddressPrefixEntry 1 }
+
+ipAddressPrefixType OBJECT-TYPE
+    SYNTAX     InetAddressType
+    MAX-ACCESS not-accessible
+    STATUS     current
+    DESCRIPTION
+           "The address type of ipAddressPrefix."
+    ::= { ipAddressPrefixEntry 2 }
+
+ipAddressPrefixPrefix OBJECT-TYPE
+    SYNTAX     InetAddress
+    MAX-ACCESS not-accessible
+    STATUS     current
+
+
+
+    DESCRIPTION
+           "The address prefix.  The address type of this object is
+            specified in ipAddressPrefixType.  The length of this object
+            is the standard length for objects of that type (4 or 16
+            bytes).  Any bits after ipAddressPrefixLength must be zero.
+
+            Implementors need to be aware that, if the size of
+            ipAddressPrefixPrefix exceeds 114 octets, then OIDS of
+            instances of columns in this row will have more than 128
+            sub-identifiers and cannot be accessed using SNMPv1,
+            SNMPv2c, or SNMPv3."
+    ::= { ipAddressPrefixEntry 3 }
+
+ipAddressPrefixLength OBJECT-TYPE
+    SYNTAX     InetAddressPrefixLength
+    MAX-ACCESS not-accessible
+    STATUS     current
+    DESCRIPTION
+           "The prefix length associated with this prefix.
+
+            The value 0 has no special meaning for this object.  It
+            simply refers to address '::/0'."
+    ::= { ipAddressPrefixEntry 4 }
+
+ipAddressPrefixOrigin OBJECT-TYPE
+    SYNTAX     IpAddressPrefixOriginTC
+    MAX-ACCESS read-only
+    STATUS     current
+    DESCRIPTION
+           "The origin of this prefix."
+    ::= { ipAddressPrefixEntry 5 }
+
+ipAddressPrefixOnLinkFlag OBJECT-TYPE
+    SYNTAX     TruthValue
+    MAX-ACCESS read-only
+    STATUS     current
+    DESCRIPTION
+           "This object has the value 'true(1)', if this prefix can be
+            used for on-link determination; otherwise, the value is
+            'false(2)'.
+
+            The default for IPv4 prefixes is 'true(1)'."
+    REFERENCE "For IPv6 RFC 2461, especially sections 2 and 4.6.2 and
+               RFC 2462"
+    ::= { ipAddressPrefixEntry 6 }
+
+ipAddressPrefixAutonomousFlag OBJECT-TYPE
+    SYNTAX     TruthValue
+
+
+
+    MAX-ACCESS read-only
+    STATUS     current
+    DESCRIPTION
+           "Autonomous address configuration flag.  When true(1),
+            indicates that this prefix can be used for autonomous
+            address configuration (i.e., can be used to form a local
+            interface address).  If false(2), it is not used to auto-
+            configure a local interface address.
+
+            The default for IPv4 prefixes is 'false(2)'."
+    REFERENCE "For IPv6 RFC 2461, especially sections 2 and 4.6.2 and
+               RFC 2462"
+    ::= { ipAddressPrefixEntry 7 }
+
+ipAddressPrefixAdvPreferredLifetime OBJECT-TYPE
+    SYNTAX     Unsigned32
+    UNITS      "seconds"
+    MAX-ACCESS read-only
+    STATUS     current
+    DESCRIPTION
+           "The remaining length of time, in seconds, that this prefix
+            will continue to be preferred, i.e., time until deprecation.
+
+            A value of 4,294,967,295 represents infinity.
+
+            The address generated from a deprecated prefix should no
+            longer be used as a source address in new communications,
+            but packets received on such an interface are processed as
+            expected.
+
+            The default for IPv4 prefixes is 4,294,967,295 (infinity)."
+    REFERENCE "For IPv6 RFC 2461, especially sections 2 and 4.6.2 and
+               RFC 2462"
+    ::= { ipAddressPrefixEntry 8 }
+
+ipAddressPrefixAdvValidLifetime OBJECT-TYPE
+    SYNTAX     Unsigned32
+    UNITS       "seconds"
+    MAX-ACCESS read-only
+    STATUS     current
+    DESCRIPTION
+           "The remaining length of time, in seconds, that this prefix
+            will continue to be valid, i.e., time until invalidation.  A
+            value of 4,294,967,295 represents infinity.
+
+            The address generated from an invalidated prefix should not
+            appear as the destination or source address of a packet.
+
+
+
+
+            The default for IPv4 prefixes is 4,294,967,295 (infinity)."
+    REFERENCE "For IPv6 RFC 2461, especially sections 2 and 4.6.2 and
+               RFC 2462"
+    ::= { ipAddressPrefixEntry 9 }
+
+--
+-- Internet Address Table
+--
+
+ipAddressSpinLock OBJECT-TYPE
+    SYNTAX     TestAndIncr
+    MAX-ACCESS read-write
+    STATUS     current
+    DESCRIPTION
+           "An advisory lock used to allow cooperating SNMP managers to
+            coordinate their use of the set operation in creating or
+            modifying rows within this table.
+
+            In order to use this lock to coordinate the use of set
+            operations, managers should first retrieve
+            ipAddressTableSpinLock.  They should then determine the
+            appropriate row to create or modify.  Finally, they should
+            issue the appropriate set command, including the retrieved
+            value of ipAddressSpinLock.  If another manager has altered
+            the table in the meantime, then the value of
+            ipAddressSpinLock will have changed, and the creation will
+            fail as it will be specifying an incorrect value for
+            ipAddressSpinLock.  It is suggested, but not required, that
+            the ipAddressSpinLock be the first var bind for each set of
+            objects representing a 'row' in a PDU."
+    ::= { ip 33 }
+
+ipAddressTable OBJECT-TYPE
+    SYNTAX     SEQUENCE OF IpAddressEntry
+    MAX-ACCESS not-accessible
+    STATUS     current
+    DESCRIPTION
+           "This table contains addressing information relevant to the
+            entity's interfaces.
+
+            This table does not contain multicast address information.
+            Tables for such information should be contained in multicast
+            specific MIBs, such as RFC 3019.
+
+            While this table is writable, the user will note that
+            several objects, such as ipAddressOrigin, are not.  The
+            intention in allowing a user to write to this table is to
+            allow them to add or remove any entry that isn't
+
+
+
+            permanent.  The user should be allowed to modify objects
+            and entries when that would not cause inconsistencies
+            within the table.  Allowing write access to objects, such
+            as ipAddressOrigin, could allow a user to insert an entry
+            and then label it incorrectly.
+
+            Note well: When including IPv6 link-local addresses in this
+            table, the entry must use an InetAddressType of 'ipv6z' in
+            order to differentiate between the possible interfaces."
+    ::= { ip 34 }
+
+ipAddressEntry OBJECT-TYPE
+    SYNTAX     IpAddressEntry
+    MAX-ACCESS not-accessible
+    STATUS     current
+    DESCRIPTION
+           "An address mapping for a particular interface."
+    INDEX { ipAddressAddrType, ipAddressAddr }
+    ::= { ipAddressTable 1 }
+
+IpAddressEntry ::= SEQUENCE {
+        ipAddressAddrType     InetAddressType,
+        ipAddressAddr         InetAddress,
+        ipAddressIfIndex      InterfaceIndex,
+        ipAddressType         INTEGER,
+        ipAddressPrefix       RowPointer,
+        ipAddressOrigin       IpAddressOriginTC,
+        ipAddressStatus       IpAddressStatusTC,
+        ipAddressCreated      TimeStamp,
+        ipAddressLastChanged  TimeStamp,
+        ipAddressRowStatus    RowStatus,
+        ipAddressStorageType  StorageType
+    }
+
+ipAddressAddrType OBJECT-TYPE
+    SYNTAX     InetAddressType
+    MAX-ACCESS not-accessible
+    STATUS     current
+    DESCRIPTION
+           "The address type of ipAddressAddr."
+    ::= { ipAddressEntry 1 }
+
+ipAddressAddr OBJECT-TYPE
+    SYNTAX     InetAddress
+    MAX-ACCESS not-accessible
+    STATUS     current
+    DESCRIPTION
+           "The IP address to which this entry's addressing information
+
+
+
+            pertains.  The address type of this object is specified in
+            ipAddressAddrType.
+
+            Implementors need to be aware that if the size of
+            ipAddressAddr exceeds 116 octets, then OIDS of instances of
+            columns in this row will have more than 128 sub-identifiers
+            and cannot be accessed using SNMPv1, SNMPv2c, or SNMPv3."
+    ::= { ipAddressEntry 2 }
+
+ipAddressIfIndex OBJECT-TYPE
+    SYNTAX     InterfaceIndex
+    MAX-ACCESS read-create
+    STATUS     current
+    DESCRIPTION
+           "The index value that uniquely identifies the interface to
+            which this entry is applicable.  The interface identified by
+            a particular value of this index is the same interface as
+            identified by the same value of the IF-MIB's ifIndex."
+    ::= { ipAddressEntry 3 }
+
+ipAddressType OBJECT-TYPE
+    SYNTAX     INTEGER {
+                 unicast(1),
+                 anycast(2),
+                 broadcast(3)
+    }
+    MAX-ACCESS read-create
+    STATUS     current
+    DESCRIPTION
+           "The type of address.  broadcast(3) is not a valid value for
+            IPv6 addresses (RFC 3513)."
+    DEFVAL { unicast }
+    ::= { ipAddressEntry 4 }
+
+ipAddressPrefix OBJECT-TYPE
+    SYNTAX     RowPointer
+    MAX-ACCESS read-only
+    STATUS     current
+    DESCRIPTION
+           "A pointer to the row in the prefix table to which this
+            address belongs.  May be { 0 0 } if there is no such row."
+    DEFVAL { zeroDotZero }
+    ::= { ipAddressEntry 5 }
+
+ipAddressOrigin OBJECT-TYPE
+    SYNTAX     IpAddressOriginTC
+    MAX-ACCESS read-only
+    STATUS     current
+
+
+
+    DESCRIPTION
+           "The origin of the address."
+    ::= { ipAddressEntry 6 }
+
+ipAddressStatus OBJECT-TYPE
+    SYNTAX     IpAddressStatusTC
+    MAX-ACCESS read-create
+    STATUS     current
+    DESCRIPTION
+           "The status of the address, describing if the address can be
+            used for communication.
+
+            In the absence of other information, an IPv4 address is
+            always preferred(1)."
+    DEFVAL { preferred }
+    ::= { ipAddressEntry 7 }
+
+ipAddressCreated OBJECT-TYPE
+    SYNTAX     TimeStamp
+    MAX-ACCESS read-only
+    STATUS     current
+    DESCRIPTION
+           "The value of sysUpTime at the time this entry was created.
+            If this entry was created prior to the last re-
+            initialization of the local network management subsystem,
+            then this object contains a zero value."
+    ::= { ipAddressEntry 8 }
+
+ipAddressLastChanged OBJECT-TYPE
+    SYNTAX     TimeStamp
+    MAX-ACCESS read-only
+    STATUS     current
+    DESCRIPTION
+           "The value of sysUpTime at the time this entry was last
+            updated.  If this entry was updated prior to the last re-
+            initialization of the local network management subsystem,
+            then this object contains a zero value."
+    ::= { ipAddressEntry 9 }
+
+ipAddressRowStatus OBJECT-TYPE
+    SYNTAX     RowStatus
+    MAX-ACCESS read-create
+    STATUS     current
+    DESCRIPTION
+           "The status of this conceptual row.
+
+            The RowStatus TC requires that this DESCRIPTION clause
+            states under which circumstances other objects in this row
+
+
+
+            can be modified.  The value of this object has no effect on
+            whether other objects in this conceptual row can be
+            modified.
+
+            A conceptual row can not be made active until the
+            ipAddressIfIndex has been set to a valid index."
+    ::= { ipAddressEntry 10 }
+
+ipAddressStorageType OBJECT-TYPE
+    SYNTAX     StorageType
+    MAX-ACCESS read-create
+    STATUS     current
+    DESCRIPTION
+           "The storage type for this conceptual row.  If this object
+            has a value of 'permanent', then no other objects are
+            required to be able to be modified."
+    DEFVAL { volatile }
+    ::= { ipAddressEntry 11 }
+
+--
+-- the Internet Address Translation table
+--
+
+ipNetToPhysicalTable OBJECT-TYPE
+    SYNTAX     SEQUENCE OF IpNetToPhysicalEntry
+    MAX-ACCESS not-accessible
+    STATUS     current
+    DESCRIPTION
+           "The IP Address Translation table used for mapping from IP
+            addresses to physical addresses.
+
+            The Address Translation tables contain the IP address to
+            'physical' address equivalences.  Some interfaces do not use
+            translation tables for determining address equivalences
+            (e.g., DDN-X.25 has an algorithmic method); if all
+            interfaces are of this type, then the Address Translation
+            table is empty, i.e., has zero entries.
+
+            While many protocols may be used to populate this table, ARP
+            and Neighbor Discovery are the most likely
+            options."
+    REFERENCE "RFC 826 and RFC 2461"
+    ::= { ip 35 }
+
+ipNetToPhysicalEntry OBJECT-TYPE
+    SYNTAX     IpNetToPhysicalEntry
+    MAX-ACCESS not-accessible
+    STATUS     current
+
+
+
+    DESCRIPTION
+           "Each entry contains one IP address to `physical' address
+            equivalence."
+    INDEX       { ipNetToPhysicalIfIndex,
+                  ipNetToPhysicalNetAddressType,
+                  ipNetToPhysicalNetAddress }
+    ::= { ipNetToPhysicalTable 1 }
+
+IpNetToPhysicalEntry ::= SEQUENCE {
+        ipNetToPhysicalIfIndex         InterfaceIndex,
+        ipNetToPhysicalNetAddressType  InetAddressType,
+        ipNetToPhysicalNetAddress      InetAddress,
+        ipNetToPhysicalPhysAddress     PhysAddress,
+        ipNetToPhysicalLastUpdated     TimeStamp,
+        ipNetToPhysicalType            INTEGER,
+        ipNetToPhysicalState           INTEGER,
+        ipNetToPhysicalRowStatus       RowStatus
+    }
+
+ipNetToPhysicalIfIndex OBJECT-TYPE
+    SYNTAX     InterfaceIndex
+    MAX-ACCESS not-accessible
+    STATUS     current
+    DESCRIPTION
+           "The index value that uniquely identifies the interface to
+            which this entry is applicable.  The interface identified by
+            a particular value of this index is the same interface as
+            identified by the same value of the IF-MIB's ifIndex."
+    ::= { ipNetToPhysicalEntry 1 }
+
+ipNetToPhysicalNetAddressType OBJECT-TYPE
+    SYNTAX     InetAddressType
+    MAX-ACCESS not-accessible
+    STATUS     current
+    DESCRIPTION
+           "The type of ipNetToPhysicalNetAddress."
+    ::= { ipNetToPhysicalEntry 2 }
+
+ipNetToPhysicalNetAddress OBJECT-TYPE
+    SYNTAX     InetAddress
+    MAX-ACCESS not-accessible
+    STATUS     current
+    DESCRIPTION
+           "The IP Address corresponding to the media-dependent
+            `physical' address.  The address type of this object is
+            specified in ipNetToPhysicalAddressType.
+
+            Implementors need to be aware that if the size of
+
+
+
+            ipNetToPhysicalNetAddress exceeds 115 octets, then OIDS of
+            instances of columns in this row will have more than 128
+            sub-identifiers and cannot be accessed using SNMPv1,
+            SNMPv2c, or SNMPv3."
+    ::= { ipNetToPhysicalEntry 3 }
+
+ipNetToPhysicalPhysAddress OBJECT-TYPE
+    SYNTAX     PhysAddress (SIZE(0..65535))
+    MAX-ACCESS read-create
+    STATUS     current
+    DESCRIPTION
+           "The media-dependent `physical' address.
+
+            As the entries in this table are typically not persistent
+            when this object is written the entity SHOULD NOT save the
+            change to non-volatile storage."
+    ::= { ipNetToPhysicalEntry 4 }
+
+ipNetToPhysicalLastUpdated OBJECT-TYPE
+    SYNTAX     TimeStamp
+    MAX-ACCESS read-only
+    STATUS     current
+    DESCRIPTION
+           "The value of sysUpTime at the time this entry was last
+            updated.  If this entry was updated prior to the last re-
+            initialization of the local network management subsystem,
+            then this object contains a zero value."
+    ::= { ipNetToPhysicalEntry 5 }
+
+ipNetToPhysicalType OBJECT-TYPE
+    SYNTAX     INTEGER {
+                other(1),        -- none of the following
+                invalid(2),      -- an invalidated mapping
+                dynamic(3),
+                static(4),
+                local(5)         -- local interface
+            }
+    MAX-ACCESS read-create
+    STATUS     current
+    DESCRIPTION
+           "The type of mapping.
+
+            Setting this object to the value invalid(2) has the effect
+            of invalidating the corresponding entry in the
+            ipNetToPhysicalTable.  That is, it effectively dis-
+            associates the interface identified with said entry from the
+            mapping identified with said entry.  It is an
+            implementation-specific matter as to whether the agent
+
+
+
+            removes an invalidated entry from the table.  Accordingly,
+            management stations must be prepared to receive tabular
+            information from agents that corresponds to entries not
+            currently in use.  Proper interpretation of such entries
+            requires examination of the relevant ipNetToPhysicalType
+            object.
+
+            The 'dynamic(3)' type indicates that the IP address to
+            physical addresses mapping has been dynamically resolved
+            using e.g., IPv4 ARP or the IPv6 Neighbor Discovery
+            protocol.
+
+            The 'static(4)' type indicates that the mapping has been
+            statically configured.  Both of these refer to entries that
+            provide mappings for other entities addresses.
+
+            The 'local(5)' type indicates that the mapping is provided
+            for an entity's own interface address.
+
+            As the entries in this table are typically not persistent
+            when this object is written the entity SHOULD NOT save the
+            change to non-volatile storage."
+    DEFVAL { static }
+    ::= { ipNetToPhysicalEntry 6 }
+
+ipNetToPhysicalState OBJECT-TYPE
+    SYNTAX     INTEGER {
+                     reachable(1), -- confirmed reachability
+
+                     stale(2),     -- unconfirmed reachability
+
+                     delay(3),     -- waiting for reachability
+                                   -- confirmation before entering
+                                   -- the probe state
+
+                     probe(4),     -- actively probing
+
+                     invalid(5),   -- an invalidated mapping
+
+                     unknown(6),   -- state can not be determined
+                                   -- for some reason.
+
+                     incomplete(7) -- address resolution is being
+                                   -- performed.
+                    }
+    MAX-ACCESS read-only
+    STATUS     current
+    DESCRIPTION
+
+
+
+           "The Neighbor Unreachability Detection state for the
+            interface when the address mapping in this entry is used.
+            If Neighbor Unreachability Detection is not in use (e.g. for
+            IPv4), this object is always unknown(6)."
+    REFERENCE "RFC 2461"
+    ::= { ipNetToPhysicalEntry 7 }
+
+ipNetToPhysicalRowStatus OBJECT-TYPE
+    SYNTAX     RowStatus
+    MAX-ACCESS read-create
+    STATUS     current
+    DESCRIPTION
+           "The status of this conceptual row.
+
+            The RowStatus TC requires that this DESCRIPTION clause
+            states under which circumstances other objects in this row
+            can be modified.  The value of this object has no effect on
+            whether other objects in this conceptual row can be
+            modified.
+
+            A conceptual row can not be made active until the
+            ipNetToPhysicalPhysAddress object has been set.
+
+            Note that if the ipNetToPhysicalType is set to 'invalid',
+            the managed node may delete the entry independent of the
+            state of this object."
+    ::= { ipNetToPhysicalEntry 8 }
+
+--
+-- The IPv6 Scope Zone Index Table.
+--
+
+ipv6ScopeZoneIndexTable OBJECT-TYPE
+    SYNTAX     SEQUENCE OF Ipv6ScopeZoneIndexEntry
+    MAX-ACCESS not-accessible
+    STATUS     current
+    DESCRIPTION
+           "The table used to describe IPv6 unicast and multicast scope
+            zones.
+
+            For those objects that have names rather than numbers, the
+            names were chosen to coincide with the names used in the
+            IPv6 address architecture document. "
+    REFERENCE "Section 2.7 of RFC 4291"
+    ::= { ip 36 }
+
+ipv6ScopeZoneIndexEntry OBJECT-TYPE
+    SYNTAX     Ipv6ScopeZoneIndexEntry
+
+
+
+    MAX-ACCESS not-accessible
+    STATUS     current
+    DESCRIPTION
+           "Each entry contains the list of scope identifiers on a given
+            interface."
+    INDEX { ipv6ScopeZoneIndexIfIndex }
+    ::= { ipv6ScopeZoneIndexTable 1 }
+
+Ipv6ScopeZoneIndexEntry ::= SEQUENCE {
+        ipv6ScopeZoneIndexIfIndex            InterfaceIndex,
+        ipv6ScopeZoneIndexLinkLocal          InetZoneIndex,
+        ipv6ScopeZoneIndex3                  InetZoneIndex,
+        ipv6ScopeZoneIndexAdminLocal         InetZoneIndex,
+        ipv6ScopeZoneIndexSiteLocal          InetZoneIndex,
+        ipv6ScopeZoneIndex6                  InetZoneIndex,
+        ipv6ScopeZoneIndex7                  InetZoneIndex,
+        ipv6ScopeZoneIndexOrganizationLocal  InetZoneIndex,
+        ipv6ScopeZoneIndex9                  InetZoneIndex,
+        ipv6ScopeZoneIndexA                  InetZoneIndex,
+        ipv6ScopeZoneIndexB                  InetZoneIndex,
+        ipv6ScopeZoneIndexC                  InetZoneIndex,
+        ipv6ScopeZoneIndexD                  InetZoneIndex
+    }
+
+ipv6ScopeZoneIndexIfIndex OBJECT-TYPE
+    SYNTAX     InterfaceIndex
+    MAX-ACCESS not-accessible
+    STATUS     current
+    DESCRIPTION
+           "The index value that uniquely identifies the interface to
+            which these scopes belong.  The interface identified by a
+            particular value of this index is the same interface as
+            identified by the same value of the IF-MIB's ifIndex."
+    ::= { ipv6ScopeZoneIndexEntry 1 }
+
+ipv6ScopeZoneIndexLinkLocal OBJECT-TYPE
+    SYNTAX     InetZoneIndex
+    MAX-ACCESS read-only
+    STATUS     current
+    DESCRIPTION
+           "The zone index for the link-local scope on this interface."
+    ::= { ipv6ScopeZoneIndexEntry 2 }
+
+ipv6ScopeZoneIndex3 OBJECT-TYPE
+    SYNTAX     InetZoneIndex
+    MAX-ACCESS read-only
+    STATUS     current
+    DESCRIPTION
+
+
+
+           "The zone index for scope 3 on this interface."
+    ::= { ipv6ScopeZoneIndexEntry 3 }
+
+ipv6ScopeZoneIndexAdminLocal OBJECT-TYPE
+    SYNTAX     InetZoneIndex
+    MAX-ACCESS read-only
+    STATUS     current
+    DESCRIPTION
+           "The zone index for the admin-local scope on this interface."
+    ::= { ipv6ScopeZoneIndexEntry 4 }
+
+ipv6ScopeZoneIndexSiteLocal OBJECT-TYPE
+    SYNTAX     InetZoneIndex
+    MAX-ACCESS read-only
+    STATUS     current
+    DESCRIPTION
+           "The zone index for the site-local scope on this interface."
+    ::= { ipv6ScopeZoneIndexEntry 5 }
+
+ipv6ScopeZoneIndex6 OBJECT-TYPE
+    SYNTAX     InetZoneIndex
+    MAX-ACCESS read-only
+    STATUS     current
+    DESCRIPTION
+           "The zone index for scope 6 on this interface."
+    ::= { ipv6ScopeZoneIndexEntry 6 }
+
+ipv6ScopeZoneIndex7 OBJECT-TYPE
+    SYNTAX     InetZoneIndex
+    MAX-ACCESS read-only
+    STATUS     current
+    DESCRIPTION
+           "The zone index for scope 7 on this interface."
+    ::= { ipv6ScopeZoneIndexEntry 7 }
+
+ipv6ScopeZoneIndexOrganizationLocal OBJECT-TYPE
+    SYNTAX     InetZoneIndex
+    MAX-ACCESS read-only
+    STATUS     current
+    DESCRIPTION
+           "The zone index for the organization-local scope on this
+            interface."
+    ::= { ipv6ScopeZoneIndexEntry 8 }
+
+ipv6ScopeZoneIndex9 OBJECT-TYPE
+    SYNTAX     InetZoneIndex
+    MAX-ACCESS read-only
+    STATUS     current
+
+
+
+    DESCRIPTION
+           "The zone index for scope 9 on this interface."
+    ::= { ipv6ScopeZoneIndexEntry 9 }
+
+ipv6ScopeZoneIndexA OBJECT-TYPE
+    SYNTAX     InetZoneIndex
+    MAX-ACCESS read-only
+    STATUS     current
+    DESCRIPTION
+           "The zone index for scope A on this interface."
+    ::= { ipv6ScopeZoneIndexEntry 10 }
+
+ipv6ScopeZoneIndexB OBJECT-TYPE
+    SYNTAX     InetZoneIndex
+    MAX-ACCESS read-only
+    STATUS     current
+    DESCRIPTION
+           "The zone index for scope B on this interface."
+    ::= { ipv6ScopeZoneIndexEntry 11 }
+
+ipv6ScopeZoneIndexC OBJECT-TYPE
+    SYNTAX     InetZoneIndex
+    MAX-ACCESS read-only
+    STATUS     current
+    DESCRIPTION
+           "The zone index for scope C on this interface."
+    ::= { ipv6ScopeZoneIndexEntry 12 }
+
+ipv6ScopeZoneIndexD OBJECT-TYPE
+    SYNTAX     InetZoneIndex
+    MAX-ACCESS read-only
+    STATUS     current
+    DESCRIPTION
+           "The zone index for scope D on this interface."
+    ::= { ipv6ScopeZoneIndexEntry 13 }
+
+--
+-- The Default Router Table
+-- This table simply lists the default routers; for more information
+-- about routing tables, see the routing MIBs
+--
+
+ipDefaultRouterTable OBJECT-TYPE
+    SYNTAX     SEQUENCE OF IpDefaultRouterEntry
+    MAX-ACCESS not-accessible
+    STATUS     current
+    DESCRIPTION
+           "The table used to describe the default routers known to this
+
+
+
+            entity."
+    ::= { ip 37 }
+
+ipDefaultRouterEntry OBJECT-TYPE
+    SYNTAX     IpDefaultRouterEntry
+    MAX-ACCESS not-accessible
+    STATUS     current
+    DESCRIPTION
+           "Each entry contains information about a default router known
+            to this entity."
+    INDEX {ipDefaultRouterAddressType, ipDefaultRouterAddress,
+           ipDefaultRouterIfIndex}
+    ::= { ipDefaultRouterTable 1 }
+
+IpDefaultRouterEntry ::= SEQUENCE {
+        ipDefaultRouterAddressType  InetAddressType,
+        ipDefaultRouterAddress      InetAddress,
+        ipDefaultRouterIfIndex      InterfaceIndex,
+        ipDefaultRouterLifetime     Unsigned32,
+        ipDefaultRouterPreference   INTEGER
+    }
+
+ipDefaultRouterAddressType OBJECT-TYPE
+    SYNTAX     InetAddressType
+    MAX-ACCESS not-accessible
+    STATUS     current
+    DESCRIPTION
+           "The address type for this row."
+    ::= { ipDefaultRouterEntry 1 }
+
+ipDefaultRouterAddress OBJECT-TYPE
+    SYNTAX     InetAddress
+    MAX-ACCESS not-accessible
+    STATUS     current
+    DESCRIPTION
+           "The IP address of the default router represented by this
+            row.  The address type of this object is specified in
+            ipDefaultRouterAddressType.
+
+            Implementers need to be aware that if the size of
+            ipDefaultRouterAddress exceeds 115 octets, then OIDS of
+            instances of columns in this row will have more than 128
+            sub-identifiers and cannot be accessed using SNMPv1,
+            SNMPv2c, or SNMPv3."
+    ::= { ipDefaultRouterEntry 2 }
+
+ipDefaultRouterIfIndex OBJECT-TYPE
+    SYNTAX     InterfaceIndex
+
+
+
+    MAX-ACCESS not-accessible
+    STATUS     current
+    DESCRIPTION
+           "The index value that uniquely identifies the interface by
+            which the router can be reached.  The interface identified
+            by a particular value of this index is the same interface as
+            identified by the same value of the IF-MIB's ifIndex."
+    ::= { ipDefaultRouterEntry 3 }
+
+ipDefaultRouterLifetime OBJECT-TYPE
+    SYNTAX     Unsigned32 (0..65535)
+    UNITS      "seconds"
+    MAX-ACCESS read-only
+    STATUS     current
+    DESCRIPTION
+           "The remaining length of time, in seconds, that this router
+            will continue to be useful as a default router.  A value of
+            zero indicates that it is no longer useful as a default
+            router.  It is left to the implementer of the MIB as to
+            whether a router with a lifetime of zero is removed from the
+            list.
+
+            For IPv6, this value should be extracted from the router
+            advertisement messages."
+    REFERENCE "For IPv6 RFC 2462 sections 4.2 and 6.3.4"
+    ::= { ipDefaultRouterEntry 4 }
+
+ipDefaultRouterPreference OBJECT-TYPE
+    SYNTAX     INTEGER {
+                     reserved (-2),
+                     low (-1),
+                     medium (0),
+                     high (1)
+                    }
+    MAX-ACCESS read-only
+    STATUS     current
+    DESCRIPTION
+           "An indication of preference given to this router as a
+            default router as described in he Default Router
+            Preferences document.  Treating the value as a
+            2 bit signed integer allows for simple arithmetic
+            comparisons.
+
+            For IPv4 routers or IPv6 routers that are not using the
+            updated router advertisement format, this object is set to
+            medium (0)."
+    REFERENCE "RFC 4291, section 2.1"
+    ::= { ipDefaultRouterEntry 5 }
+
+
+
+--
+-- Configuration information for constructing router advertisements
+--
+
+ipv6RouterAdvertSpinLock OBJECT-TYPE
+    SYNTAX     TestAndIncr
+    MAX-ACCESS read-write
+    STATUS     current
+    DESCRIPTION
+           "An advisory lock used to allow cooperating SNMP managers to
+            coordinate their use of the set operation in creating or
+            modifying rows within this table.
+
+            In order to use this lock to coordinate the use of set
+            operations, managers should first retrieve
+            ipv6RouterAdvertSpinLock.  They should then determine the
+            appropriate row to create or modify.  Finally, they should
+            issue the appropriate set command including the retrieved
+            value of ipv6RouterAdvertSpinLock.  If another manager has
+            altered the table in the meantime, then the value of
+            ipv6RouterAdvertSpinLock will have changed and the creation
+            will fail as it will be specifying an incorrect value for
+            ipv6RouterAdvertSpinLock.  It is suggested, but not
+            required, that the ipv6RouterAdvertSpinLock be the first var
+            bind for each set of objects representing a 'row' in a PDU."
+    ::= { ip 38 }
+
+ipv6RouterAdvertTable OBJECT-TYPE
+    SYNTAX     SEQUENCE OF Ipv6RouterAdvertEntry
+    MAX-ACCESS not-accessible
+    STATUS     current
+    DESCRIPTION
+           "The table containing information used to construct router
+            advertisements."
+    ::= { ip 39 }
+
+ipv6RouterAdvertEntry OBJECT-TYPE
+    SYNTAX     Ipv6RouterAdvertEntry
+    MAX-ACCESS not-accessible
+    STATUS     current
+    DESCRIPTION
+           "An entry containing information used to construct router
+            advertisements.
+
+            Information in this table is persistent, and when this
+            object is written, the entity SHOULD save the change to
+            non-volatile storage."
+    INDEX { ipv6RouterAdvertIfIndex }
+
+
+
+    ::= { ipv6RouterAdvertTable 1 }
+
+Ipv6RouterAdvertEntry ::= SEQUENCE {
+        ipv6RouterAdvertIfIndex          InterfaceIndex,
+        ipv6RouterAdvertSendAdverts      TruthValue,
+        ipv6RouterAdvertMaxInterval      Unsigned32,
+        ipv6RouterAdvertMinInterval      Unsigned32,
+        ipv6RouterAdvertManagedFlag      TruthValue,
+        ipv6RouterAdvertOtherConfigFlag  TruthValue,
+        ipv6RouterAdvertLinkMTU          Unsigned32,
+        ipv6RouterAdvertReachableTime    Unsigned32,
+        ipv6RouterAdvertRetransmitTime   Unsigned32,
+        ipv6RouterAdvertCurHopLimit      Unsigned32,
+        ipv6RouterAdvertDefaultLifetime  Unsigned32,
+        ipv6RouterAdvertRowStatus        RowStatus
+    }
+
+ipv6RouterAdvertIfIndex OBJECT-TYPE
+    SYNTAX     InterfaceIndex
+    MAX-ACCESS not-accessible
+    STATUS     current
+    DESCRIPTION
+           "The index value that uniquely identifies the interface on
+            which router advertisements constructed with this
+            information will be transmitted.  The interface identified
+            by a particular value of this index is the same interface as
+            identified by the same value of the IF-MIB's ifIndex."
+    ::= { ipv6RouterAdvertEntry 1 }
+
+ipv6RouterAdvertSendAdverts OBJECT-TYPE
+    SYNTAX     TruthValue
+    MAX-ACCESS read-create
+    STATUS     current
+    DESCRIPTION
+           "A flag indicating whether the router sends periodic
+            router advertisements and responds to router solicitations
+            on this interface."
+    REFERENCE "RFC 2461 Section 6.2.1"
+    DEFVAL { false }
+    ::= { ipv6RouterAdvertEntry 2 }
+
+ipv6RouterAdvertMaxInterval OBJECT-TYPE
+    SYNTAX     Unsigned32 (4..1800)
+    UNITS      "seconds"
+    MAX-ACCESS read-create
+    STATUS     current
+    DESCRIPTION
+           "The maximum time allowed between sending unsolicited router
+
+
+
+            advertisements from this interface."
+    REFERENCE "RFC 2461 Section 6.2.1"
+    DEFVAL { 600 }
+    ::= { ipv6RouterAdvertEntry 3 }
+
+ipv6RouterAdvertMinInterval OBJECT-TYPE
+    SYNTAX     Unsigned32 (3..1350)
+    UNITS      "seconds"
+    MAX-ACCESS read-create
+    STATUS     current
+    DESCRIPTION
+           "The minimum time allowed between sending unsolicited router
+            advertisements from this interface.
+
+            The default is 0.33 * ipv6RouterAdvertMaxInterval, however,
+            in the case of a low value for ipv6RouterAdvertMaxInterval,
+            the minimum value for this object is restricted to 3."
+    REFERENCE "RFC 2461 Section 6.2.1"
+    ::= { ipv6RouterAdvertEntry 4 }
+
+ipv6RouterAdvertManagedFlag OBJECT-TYPE
+    SYNTAX     TruthValue
+    MAX-ACCESS read-create
+    STATUS     current
+    DESCRIPTION
+           "The true/false value to be placed into the 'managed address
+            configuration' flag field in router advertisements sent from
+            this interface."
+    REFERENCE "RFC 2461 Section 6.2.1"
+    DEFVAL { false }
+    ::= { ipv6RouterAdvertEntry 5 }
+
+ipv6RouterAdvertOtherConfigFlag OBJECT-TYPE
+    SYNTAX     TruthValue
+    MAX-ACCESS read-create
+    STATUS     current
+    DESCRIPTION
+           "The true/false value to be placed into the 'other stateful
+            configuration' flag field in router advertisements sent from
+            this interface."
+    REFERENCE "RFC 2461 Section 6.2.1"
+    DEFVAL { false }
+    ::= { ipv6RouterAdvertEntry 6 }
+
+ipv6RouterAdvertLinkMTU OBJECT-TYPE
+    SYNTAX     Unsigned32
+    MAX-ACCESS read-create
+    STATUS     current
+
+
+
+    DESCRIPTION
+           "The value to be placed in MTU options sent by the router on
+            this interface.
+
+            A value of zero indicates that no MTU options are sent."
+    REFERENCE "RFC 2461 Section 6.2.1"
+    DEFVAL { 0 }
+    ::= { ipv6RouterAdvertEntry 7 }
+
+ipv6RouterAdvertReachableTime OBJECT-TYPE
+    SYNTAX     Unsigned32 (0..3600000)
+    UNITS      "milliseconds"
+    MAX-ACCESS read-create
+    STATUS     current
+    DESCRIPTION
+           "The value to be placed in the reachable time field in router
+            advertisement messages sent from this interface.
+
+            A value of zero in the router advertisement indicates that
+            the advertisement isn't specifying a value for reachable
+            time."
+    REFERENCE "RFC 2461 Section 6.2.1"
+    DEFVAL { 0 }
+    ::= { ipv6RouterAdvertEntry 8 }
+
+ipv6RouterAdvertRetransmitTime OBJECT-TYPE
+    SYNTAX     Unsigned32
+    UNITS      "milliseconds"
+    MAX-ACCESS read-create
+    STATUS     current
+    DESCRIPTION
+           "The value to be placed in the retransmit timer field in
+            router advertisements sent from this interface.
+
+            A value of zero in the router advertisement indicates that
+            the advertisement isn't specifying a value for retrans
+            time."
+    REFERENCE "RFC 2461 Section 6.2.1"
+    DEFVAL { 0 }
+    ::= { ipv6RouterAdvertEntry 9 }
+
+ipv6RouterAdvertCurHopLimit OBJECT-TYPE
+    SYNTAX     Unsigned32 (0..255)
+    MAX-ACCESS read-create
+    STATUS     current
+    DESCRIPTION
+           "The default value to be placed in the current hop limit
+            field in router advertisements sent from this interface.
+
+
+
+            The value should be set to the current diameter of the
+            Internet.
+
+            A value of zero in the router advertisement indicates that
+            the advertisement isn't specifying a value for curHopLimit.
+
+            The default should be set to the value specified in the IANA
+            web pages (www.iana.org) at the time of implementation."
+    REFERENCE "RFC 2461 Section 6.2.1"
+    ::= { ipv6RouterAdvertEntry 10 }
+
+ipv6RouterAdvertDefaultLifetime OBJECT-TYPE
+    SYNTAX     Unsigned32 (0|4..9000)
+    UNITS      "seconds"
+    MAX-ACCESS read-create
+    STATUS     current
+    DESCRIPTION
+           "The value to be placed in the router lifetime field of
+            router advertisements sent from this interface.  This value
+            MUST be either 0 or between ipv6RouterAdvertMaxInterval and
+            9000 seconds.
+
+            A value of zero indicates that the router is not to be used
+            as a default router.
+
+            The default is 3 * ipv6RouterAdvertMaxInterval."
+    REFERENCE "RFC 2461 Section 6.2.1"
+    ::= { ipv6RouterAdvertEntry 11 }
+
+ipv6RouterAdvertRowStatus OBJECT-TYPE
+    SYNTAX     RowStatus
+    MAX-ACCESS read-create
+    STATUS     current
+    DESCRIPTION
+           "The status of this conceptual row.
+
+            As all objects in this conceptual row have default values, a
+            row can be created and made active by setting this object
+            appropriately.
+
+            The RowStatus TC requires that this DESCRIPTION clause
+            states under which circumstances other objects in this row
+            can be modified.  The value of this object has no effect on
+            whether other objects in this conceptual row can be
+            modified."
+    ::= { ipv6RouterAdvertEntry 12 }
+
+--
+
+
+
+-- ICMP section
+--
+
+icmp     OBJECT IDENTIFIER ::= { mib-2 5 }
+
+--
+-- ICMP non-message-specific counters
+--
+
+-- These object IDs are reserved, as they were used in earlier
+-- versions of the MIB module.  In theory, OIDs are not assigned
+-- until the specification is released as an RFC; however, as some
+-- companies may have shipped code based on earlier versions of
+-- the MIB, it seems best to reserve these OIDs.
+-- ::= { icmp 27 }
+-- ::= { icmp 28 }
+
+icmpStatsTable OBJECT-TYPE
+    SYNTAX     SEQUENCE OF IcmpStatsEntry
+    MAX-ACCESS not-accessible
+    STATUS     current
+    DESCRIPTION
+           "The table of generic system-wide ICMP counters."
+    ::= { icmp 29 }
+
+icmpStatsEntry OBJECT-TYPE
+    SYNTAX     IcmpStatsEntry
+    MAX-ACCESS not-accessible
+    STATUS     current
+    DESCRIPTION
+           "A conceptual row in the icmpStatsTable."
+    INDEX    { icmpStatsIPVersion }
+    ::= { icmpStatsTable 1 }
+
+IcmpStatsEntry ::= SEQUENCE {
+        icmpStatsIPVersion  InetVersion,
+        icmpStatsInMsgs     Counter32,
+        icmpStatsInErrors   Counter32,
+        icmpStatsOutMsgs    Counter32,
+        icmpStatsOutErrors  Counter32
+    }
+
+icmpStatsIPVersion OBJECT-TYPE
+    SYNTAX     InetVersion
+    MAX-ACCESS not-accessible
+    STATUS     current
+    DESCRIPTION
+           "The IP version of the statistics."
+
+
+
+    ::= { icmpStatsEntry 1 }
+
+icmpStatsInMsgs OBJECT-TYPE
+    SYNTAX     Counter32
+    MAX-ACCESS read-only
+    STATUS     current
+    DESCRIPTION
+           "The total number of ICMP messages that the entity received.
+            Note that this counter includes all those counted by
+            icmpStatsInErrors."
+    ::= { icmpStatsEntry 2 }
+
+icmpStatsInErrors OBJECT-TYPE
+    SYNTAX     Counter32
+    MAX-ACCESS read-only
+    STATUS     current
+    DESCRIPTION
+           "The number of ICMP messages that the entity received but
+            determined as having ICMP-specific errors (bad ICMP
+            checksums, bad length, etc.)."
+    ::= { icmpStatsEntry 3 }
+
+icmpStatsOutMsgs OBJECT-TYPE
+    SYNTAX     Counter32
+    MAX-ACCESS read-only
+    STATUS     current
+    DESCRIPTION
+           "The total number of ICMP messages that the entity attempted
+            to send.  Note that this counter includes all those counted
+            by icmpStatsOutErrors."
+    ::= { icmpStatsEntry 4 }
+
+icmpStatsOutErrors OBJECT-TYPE
+    SYNTAX     Counter32
+    MAX-ACCESS read-only
+    STATUS     current
+    DESCRIPTION
+           "The number of ICMP messages that this entity did not send
+            due to problems discovered within ICMP, such as a lack of
+            buffers.  This value should not include errors discovered
+            outside the ICMP layer, such as the inability of IP to route
+            the resultant datagram.  In some implementations, there may
+            be no types of error that contribute to this counter's
+            value."
+    ::= { icmpStatsEntry 5 }
+
+--
+-- per-version, per-message type ICMP counters
+
+
+
+--
+
+icmpMsgStatsTable OBJECT-TYPE
+    SYNTAX     SEQUENCE OF IcmpMsgStatsEntry
+    MAX-ACCESS not-accessible
+    STATUS     current
+    DESCRIPTION
+           "The table of system-wide per-version, per-message type ICMP
+            counters."
+    ::= { icmp 30 }
+
+icmpMsgStatsEntry OBJECT-TYPE
+    SYNTAX     IcmpMsgStatsEntry
+    MAX-ACCESS not-accessible
+    STATUS     current
+    DESCRIPTION
+           "A conceptual row in the icmpMsgStatsTable.
+
+            The system should track each ICMP type value, even if that
+            ICMP type is not supported by the system.  However, a
+            given row need not be instantiated unless a message of that
+            type has been processed, i.e., the row for
+            icmpMsgStatsType=X MAY be instantiated before but MUST be
+            instantiated after the first message with Type=X is
+            received or transmitted.  After receiving or transmitting
+            any succeeding messages with Type=X, the relevant counter
+            must be incremented."
+    INDEX { icmpMsgStatsIPVersion, icmpMsgStatsType }
+    ::= { icmpMsgStatsTable 1 }
+
+IcmpMsgStatsEntry ::= SEQUENCE {
+        icmpMsgStatsIPVersion  InetVersion,
+        icmpMsgStatsType       Integer32,
+        icmpMsgStatsInPkts     Counter32,
+        icmpMsgStatsOutPkts    Counter32
+    }
+
+icmpMsgStatsIPVersion OBJECT-TYPE
+    SYNTAX     InetVersion
+    MAX-ACCESS not-accessible
+    STATUS     current
+    DESCRIPTION
+           "The IP version of the statistics."
+    ::= { icmpMsgStatsEntry 1 }
+
+icmpMsgStatsType OBJECT-TYPE
+    SYNTAX     Integer32 (0..255)
+    MAX-ACCESS not-accessible
+
+
+
+    STATUS     current
+    DESCRIPTION
+           "The ICMP type field of the message type being counted by
+            this row.
+
+            Note that ICMP message types are scoped by the address type
+            in use."
+    REFERENCE "http://www.iana.org/assignments/icmp-parameters and
+               http://www.iana.org/assignments/icmpv6-parameters"
+    ::= { icmpMsgStatsEntry 2 }
+
+icmpMsgStatsInPkts OBJECT-TYPE
+    SYNTAX     Counter32
+    MAX-ACCESS read-only
+    STATUS     current
+    DESCRIPTION
+           "The number of input packets for this AF and type."
+    ::= { icmpMsgStatsEntry 3 }
+
+icmpMsgStatsOutPkts OBJECT-TYPE
+    SYNTAX     Counter32
+    MAX-ACCESS read-only
+    STATUS     current
+    DESCRIPTION
+           "The number of output packets for this AF and type."
+    ::= { icmpMsgStatsEntry 4 }
+--
+-- conformance information
+--
+
+ipMIBConformance OBJECT IDENTIFIER ::= { ipMIB 2 }
+
+ipMIBCompliances OBJECT IDENTIFIER ::= { ipMIBConformance 1 }
+ipMIBGroups      OBJECT IDENTIFIER ::= { ipMIBConformance 2 }
+
+-- compliance statements
+ipMIBCompliance2 MODULE-COMPLIANCE
+    STATUS     current
+    DESCRIPTION
+            "The compliance statement for systems that implement IP -
+             either IPv4 or IPv6.
+
+            There are a number of INDEX objects that cannot be
+            represented in the form of OBJECT clauses in SMIv2, but
+            for which we have the following compliance requirements,
+            expressed in OBJECT clause form in this description
+            clause:
+
+
+
+
+            -- OBJECT        ipSystemStatsIPVersion
+            -- SYNTAX        InetVersion {ipv4(1), ipv6(2)}
+            -- DESCRIPTION
+            --     This MIB requires support for only IPv4 and IPv6
+            --     versions.
+            --
+            -- OBJECT        ipIfStatsIPVersion
+            -- SYNTAX        InetVersion {ipv4(1), ipv6(2)}
+            -- DESCRIPTION
+            --     This MIB requires support for only IPv4 and IPv6
+            --     versions.
+            --
+            -- OBJECT        icmpStatsIPVersion
+            -- SYNTAX        InetVersion {ipv4(1), ipv6(2)}
+            -- DESCRIPTION
+            --     This MIB requires support for only IPv4 and IPv6
+            --     versions.
+            --
+            -- OBJECT        icmpMsgStatsIPVersion
+            -- SYNTAX        InetVersion {ipv4(1), ipv6(2)}
+            -- DESCRIPTION
+            --     This MIB requires support for only IPv4 and IPv6
+            --     versions.
+            --
+            -- OBJECT        ipAddressPrefixType
+            -- SYNTAX        InetAddressType {ipv4(1), ipv6(2)}
+            -- DESCRIPTION
+            --     This MIB requires support for only global IPv4 and
+            --     IPv6 address types.
+            --
+            -- OBJECT        ipAddressPrefixPrefix
+            -- SYNTAX        InetAddress (Size(4 | 16))
+            -- DESCRIPTION
+            --     This MIB requires support for only global IPv4 and
+            --     IPv6 addresses and so the size can be either 4 or
+            --     16 bytes.
+            --
+            -- OBJECT        ipAddressAddrType
+            -- SYNTAX        InetAddressType {ipv4(1), ipv6(2),
+            --                                ipv4z(3), ipv6z(4)}
+            -- DESCRIPTION
+            --     This MIB requires support for only global and
+            --     non-global IPv4 and IPv6 address types.
+            --
+            -- OBJECT        ipAddressAddr
+            -- SYNTAX        InetAddress (Size(4 | 8 | 16 | 20))
+            -- DESCRIPTION
+            --     This MIB requires support for only global and
+
+
+
+            --     non-global IPv4 and IPv6 addresses and so the size
+            --     can be 4, 8, 16, or 20 bytes.
+            --
+            -- OBJECT        ipNetToPhysicalNetAddressType
+            -- SYNTAX        InetAddressType {ipv4(1), ipv6(2),
+            --                                ipv4z(3), ipv6z(4)}
+            -- DESCRIPTION
+            --     This MIB requires support for only global and
+            --     non-global IPv4 and IPv6 address types.
+            --
+            -- OBJECT        ipNetToPhysicalNetAddress
+            -- SYNTAX        InetAddress (Size(4 | 8 | 16 | 20))
+            -- DESCRIPTION
+            --     This MIB requires support for only global and
+            --     non-global IPv4 and IPv6 addresses and so the size
+            --     can be 4, 8, 16, or 20 bytes.
+            --
+            -- OBJECT        ipDefaultRouterAddressType
+            -- SYNTAX        InetAddressType {ipv4(1), ipv6(2),
+            --                                ipv4z(3), ipv6z(4)}
+            -- DESCRIPTION
+            --     This MIB requires support for only global and
+            --     non-global IPv4 and IPv6 address types.
+            --
+            -- OBJECT        ipDefaultRouterAddress
+            -- SYNTAX        InetAddress (Size(4 | 8 | 16 | 20))
+            -- DESCRIPTION
+            --     This MIB requires support for only global and
+            --     non-global IPv4 and IPv6 addresses and so the size
+            --     can be 4, 8, 16, or 20 bytes."
+
+    MODULE -- this module
+
+    MANDATORY-GROUPS { ipSystemStatsGroup,   ipAddressGroup,
+                       ipNetToPhysicalGroup, ipDefaultRouterGroup,
+                       icmpStatsGroup }
+
+    GROUP ipSystemStatsHCOctetGroup
+    DESCRIPTION
+           "This group is mandatory for systems that have an aggregate
+            bandwidth of greater than 20MB.  Including this group does
+            not allow an entity to neglect the 32 bit versions of these
+            objects."
+
+    GROUP ipSystemStatsHCPacketGroup
+    DESCRIPTION
+           "This group is mandatory for systems that have an aggregate
+            bandwidth of greater than 650MB.  Including this group
+
+
+
+            does not allow an entity to neglect the 32 bit versions of
+            these objects."
+
+    GROUP ipIfStatsGroup
+    DESCRIPTION
+           "This group is optional for all systems."
+
+    GROUP ipIfStatsHCOctetGroup
+    DESCRIPTION
+           "This group is mandatory for systems that include the
+            ipIfStatsGroup and include links with bandwidths of greater
+            than 20MB.  Including this group does not allow an entity to
+            neglect the 32 bit versions of these objects."
+
+    GROUP ipIfStatsHCPacketGroup
+    DESCRIPTION
+           "This group is mandatory for systems that include the
+            ipIfStatsGroup and include links with bandwidths of greater
+            than 650MB.  Including this group does not allow an entity
+            to neglect the 32 bit versions of these objects."
+
+    GROUP ipv4GeneralGroup
+    DESCRIPTION
+           "This group is mandatory for all systems supporting IPv4."
+
+    GROUP ipv4IfGroup
+    DESCRIPTION
+           "This group is mandatory for all systems supporting IPv4."
+
+    GROUP ipv4SystemStatsGroup
+    DESCRIPTION
+           "This group is mandatory for all systems supporting IPv4."
+
+    GROUP ipv4SystemStatsHCPacketGroup
+    DESCRIPTION
+           "This group is mandatory for all systems supporting IPv4 and
+            that have an aggregate bandwidth of greater than 650MB.
+            Including this group does not allow an entity to neglect the
+            32 bit versions of these objects."
+
+    GROUP ipv4IfStatsGroup
+    DESCRIPTION
+           "This group is mandatory for all systems supporting IPv4 and
+            including the ipIfStatsGroup."
+
+    GROUP ipv4IfStatsHCPacketGroup
+    DESCRIPTION
+           "This group is mandatory for all systems supporting IPv4 and
+
+
+
+            including the ipIfStatsHCPacketGroup.  Including this group
+            does not allow an entity to neglect the 32 bit versions of
+            these objects."
+
+    GROUP ipv6GeneralGroup2
+    DESCRIPTION
+           "This group is mandatory for all systems supporting IPv6."
+
+    GROUP ipv6IfGroup
+    DESCRIPTION
+           "This group is mandatory for all systems supporting IPv6."
+
+    GROUP ipAddressPrefixGroup
+    DESCRIPTION
+           "This group is mandatory for all systems supporting IPv6."
+
+    GROUP ipv6ScopeGroup
+    DESCRIPTION
+           "This group is mandatory for all systems supporting IPv6."
+
+    GROUP ipv6RouterAdvertGroup
+    DESCRIPTION
+           "This group is mandatory for all IPv6 routers."
+
+    GROUP ipLastChangeGroup
+    DESCRIPTION
+           "This group is optional for all agents."
+
+    OBJECT     ipv6IpForwarding
+    MIN-ACCESS read-only
+    DESCRIPTION
+           "An agent is not required to provide write access to this
+            object."
+
+    OBJECT     ipv6IpDefaultHopLimit
+    MIN-ACCESS read-only
+    DESCRIPTION
+           "An agent is not required to provide write access to this
+            object."
+
+    OBJECT     ipv4InterfaceEnableStatus
+    MIN-ACCESS read-only
+    DESCRIPTION
+           "An agent is not required to provide write access to this
+            object."
+
+    OBJECT     ipv6InterfaceEnableStatus
+    MIN-ACCESS read-only
+
+
+
+    DESCRIPTION
+           "An agent is not required to provide write access to this
+            object."
+
+    OBJECT     ipv6InterfaceForwarding
+    MIN-ACCESS read-only
+    DESCRIPTION
+           "An agent is not required to provide write access to this
+            object."
+
+    OBJECT     ipAddressSpinLock
+    MIN-ACCESS not-accessible
+    DESCRIPTION
+           "An agent is not required to provide write access to this
+            object.  However, if an agent provides write access to any
+            of the other objects in the ipAddressGroup, it SHOULD
+            provide write access to this object as well."
+
+    OBJECT     ipAddressIfIndex
+    MIN-ACCESS read-only
+    DESCRIPTION
+           "An agent is not required to provide write or create access
+            to this object."
+
+    OBJECT     ipAddressType
+    MIN-ACCESS read-only
+    DESCRIPTION
+           "An agent is not required to provide write or create access
+            to this object."
+
+    OBJECT     ipAddressStatus
+    MIN-ACCESS read-only
+    DESCRIPTION
+           "An agent is not required to provide write or create access
+            to this object."
+
+    OBJECT     ipAddressRowStatus
+    SYNTAX     RowStatus { active(1) }
+    MIN-ACCESS read-only
+    DESCRIPTION
+           "An agent is not required to provide write or create access
+            to this object."
+
+    OBJECT     ipAddressStorageType
+    MIN-ACCESS read-only
+    DESCRIPTION
+           "An agent is not required to provide write or create access
+            to this object.
+
+
+
+            If an agent allows this object to be written or created, it
+            is not required to allow this object to be set to readOnly,
+            permanent, or nonVolatile."
+
+    OBJECT     ipNetToPhysicalPhysAddress
+    MIN-ACCESS read-only
+    DESCRIPTION
+           "An agent is not required to provide write or create access
+            to this object."
+
+    OBJECT     ipNetToPhysicalType
+    MIN-ACCESS read-only
+    DESCRIPTION
+           "An agent is not required to provide write or create access
+            to this object."
+
+    OBJECT     ipv6RouterAdvertSpinLock
+    MIN-ACCESS read-only
+    DESCRIPTION
+           "An agent is not required to provide write access to this
+            object.  However, if an agent provides write access to
+            any of the other objects in the ipv6RouterAdvertGroup, it
+            SHOULD provide write access to this object as well."
+
+    OBJECT     ipv6RouterAdvertSendAdverts
+    MIN-ACCESS read-only
+    DESCRIPTION
+           "An agent is not required to provide write access to this
+            object."
+
+    OBJECT     ipv6RouterAdvertMaxInterval
+    MIN-ACCESS read-only
+    DESCRIPTION
+           "An agent is not required to provide write access to this
+            object."
+
+    OBJECT     ipv6RouterAdvertMinInterval
+    MIN-ACCESS read-only
+    DESCRIPTION
+           "An agent is not required to provide write access to this
+            object."
+
+    OBJECT     ipv6RouterAdvertManagedFlag
+    MIN-ACCESS read-only
+    DESCRIPTION
+           "An agent is not required to provide write access to this
+            object."
+
+
+
+
+    OBJECT     ipv6RouterAdvertOtherConfigFlag
+    MIN-ACCESS read-only
+    DESCRIPTION
+           "An agent is not required to provide write access to this
+            object."
+
+    OBJECT     ipv6RouterAdvertLinkMTU
+    MIN-ACCESS read-only
+    DESCRIPTION
+           "An agent is not required to provide write access to this
+            object."
+
+    OBJECT     ipv6RouterAdvertReachableTime
+    MIN-ACCESS read-only
+    DESCRIPTION
+           "An agent is not required to provide write access to this
+            object."
+
+    OBJECT     ipv6RouterAdvertRetransmitTime
+    MIN-ACCESS read-only
+    DESCRIPTION
+           "An agent is not required to provide write access to this
+            object."
+
+    OBJECT     ipv6RouterAdvertCurHopLimit
+    MIN-ACCESS read-only
+    DESCRIPTION
+           "An agent is not required to provide write access to this
+            object."
+
+    OBJECT     ipv6RouterAdvertDefaultLifetime
+    MIN-ACCESS read-only
+    DESCRIPTION
+           "An agent is not required to provide write access to this
+            object."
+
+    OBJECT     ipv6RouterAdvertRowStatus
+    MIN-ACCESS read-only
+    DESCRIPTION
+           "An agent is not required to provide write or create access
+            to this object."
+
+    ::= { ipMIBCompliances 2 }
+
+-- units of conformance
+
+ipv4GeneralGroup OBJECT-GROUP
+    OBJECTS   { ipForwarding, ipDefaultTTL, ipReasmTimeout }
+
+
+
+    STATUS     current
+    DESCRIPTION
+           "The group of IPv4-specific objects for basic management of
+            IPv4 entities."
+    ::= { ipMIBGroups 3 }
+
+ipv4IfGroup OBJECT-GROUP
+    OBJECTS   { ipv4InterfaceReasmMaxSize, ipv4InterfaceEnableStatus,
+                ipv4InterfaceRetransmitTime }
+    STATUS     current
+    DESCRIPTION
+           "The group of IPv4-specific objects for basic management of
+            IPv4 interfaces."
+    ::= { ipMIBGroups 4 }
+
+ipv6GeneralGroup2 OBJECT-GROUP
+    OBJECTS { ipv6IpForwarding, ipv6IpDefaultHopLimit }
+    STATUS     current
+    DESCRIPTION
+           "The IPv6 group of objects providing for basic management of
+            IPv6 entities."
+    ::= { ipMIBGroups 5 }
+
+ipv6IfGroup OBJECT-GROUP
+    OBJECTS   { ipv6InterfaceReasmMaxSize,   ipv6InterfaceIdentifier,
+                ipv6InterfaceEnableStatus,   ipv6InterfaceReachableTime,
+                ipv6InterfaceRetransmitTime, ipv6InterfaceForwarding }
+    STATUS     current
+    DESCRIPTION
+           "The group of IPv6-specific objects for basic management of
+            IPv6 interfaces."
+    ::= { ipMIBGroups 6 }
+
+ipLastChangeGroup OBJECT-GROUP
+    OBJECTS   { ipv4InterfaceTableLastChange,
+                ipv6InterfaceTableLastChange,
+                ipIfStatsTableLastChange }
+    STATUS     current
+    DESCRIPTION
+           "The last change objects associated with this MIB.  These
+            objects are optional for all agents.  They SHOULD be
+            implemented on agents where it is possible to determine the
+            proper values.  Where it is not possible to determine the
+            proper values, for example when the tables are split amongst
+            several sub-agents using AgentX, the agent MUST NOT
+            implement these objects to return an incorrect or static
+            value."
+    ::= { ipMIBGroups 7 }
+
+
+
+ipSystemStatsGroup OBJECT-GROUP
+    OBJECTS   { ipSystemStatsInReceives,
+                ipSystemStatsInOctets,
+                ipSystemStatsInHdrErrors,
+                ipSystemStatsInNoRoutes,
+                ipSystemStatsInAddrErrors,
+                ipSystemStatsInUnknownProtos,
+                ipSystemStatsInTruncatedPkts,
+                ipSystemStatsInForwDatagrams,
+                ipSystemStatsReasmReqds,
+                ipSystemStatsReasmOKs,
+                ipSystemStatsReasmFails,
+                ipSystemStatsInDiscards,
+                ipSystemStatsInDelivers,
+                ipSystemStatsOutRequests,
+                ipSystemStatsOutNoRoutes,
+                ipSystemStatsOutForwDatagrams,
+                ipSystemStatsOutDiscards,
+                ipSystemStatsOutFragReqds,
+                ipSystemStatsOutFragOKs,
+                ipSystemStatsOutFragFails,
+                ipSystemStatsOutFragCreates,
+                ipSystemStatsOutTransmits,
+                ipSystemStatsOutOctets,
+                ipSystemStatsInMcastPkts,
+                ipSystemStatsInMcastOctets,
+                ipSystemStatsOutMcastPkts,
+                ipSystemStatsOutMcastOctets,
+                ipSystemStatsDiscontinuityTime,
+                ipSystemStatsRefreshRate }
+    STATUS     current
+    DESCRIPTION
+           "IP system wide statistics."
+    ::= { ipMIBGroups 8 }
+
+ipv4SystemStatsGroup OBJECT-GROUP
+    OBJECTS   { ipSystemStatsInBcastPkts, ipSystemStatsOutBcastPkts }
+    STATUS     current
+    DESCRIPTION
+           "IPv4 only system wide statistics."
+    ::= { ipMIBGroups 9 }
+
+ipSystemStatsHCOctetGroup OBJECT-GROUP
+    OBJECTS   { ipSystemStatsHCInOctets,
+                ipSystemStatsHCOutOctets,
+                ipSystemStatsHCInMcastOctets,
+                ipSystemStatsHCOutMcastOctets
+}
+
+
+
+    STATUS     current
+    DESCRIPTION
+           "IP system wide statistics for systems that may overflow the
+            standard octet counters within 1 hour."
+    ::= { ipMIBGroups 10 }
+
+ipSystemStatsHCPacketGroup OBJECT-GROUP
+    OBJECTS   { ipSystemStatsHCInReceives,
+                ipSystemStatsHCInForwDatagrams,
+                ipSystemStatsHCInDelivers,
+                ipSystemStatsHCOutRequests,
+                ipSystemStatsHCOutForwDatagrams,
+                ipSystemStatsHCOutTransmits,
+                ipSystemStatsHCInMcastPkts,
+                ipSystemStatsHCOutMcastPkts
+}
+    STATUS     current
+    DESCRIPTION
+           "IP system wide statistics for systems that may overflow the
+            standard packet counters within 1 hour."
+    ::= { ipMIBGroups 11 }
+
+ipv4SystemStatsHCPacketGroup OBJECT-GROUP
+    OBJECTS   { ipSystemStatsHCInBcastPkts,
+                ipSystemStatsHCOutBcastPkts }
+    STATUS     current
+    DESCRIPTION
+           "IPv4 only system wide statistics for systems that may
+            overflow the standard packet counters within 1 hour."
+    ::= { ipMIBGroups 12 }
+
+ipIfStatsGroup OBJECT-GROUP
+    OBJECTS   { ipIfStatsInReceives,        ipIfStatsInOctets,
+                ipIfStatsInHdrErrors,       ipIfStatsInNoRoutes,
+                ipIfStatsInAddrErrors,      ipIfStatsInUnknownProtos,
+                ipIfStatsInTruncatedPkts,   ipIfStatsInForwDatagrams,
+                ipIfStatsReasmReqds,        ipIfStatsReasmOKs,
+                ipIfStatsReasmFails,        ipIfStatsInDiscards,
+                ipIfStatsInDelivers,        ipIfStatsOutRequests,
+                ipIfStatsOutForwDatagrams,  ipIfStatsOutDiscards,
+                ipIfStatsOutFragReqds,      ipIfStatsOutFragOKs,
+                ipIfStatsOutFragFails,      ipIfStatsOutFragCreates,
+                ipIfStatsOutTransmits,      ipIfStatsOutOctets,
+                ipIfStatsInMcastPkts,       ipIfStatsInMcastOctets,
+                ipIfStatsOutMcastPkts,      ipIfStatsOutMcastOctets,
+                ipIfStatsDiscontinuityTime, ipIfStatsRefreshRate }
+    STATUS     current
+    DESCRIPTION
+
+
+
+           "IP per-interface statistics."
+    ::= { ipMIBGroups 13 }
+
+ipv4IfStatsGroup OBJECT-GROUP
+    OBJECTS   { ipIfStatsInBcastPkts, ipIfStatsOutBcastPkts }
+    STATUS     current
+    DESCRIPTION
+           "IPv4 only per-interface statistics."
+    ::= { ipMIBGroups 14 }
+
+ipIfStatsHCOctetGroup OBJECT-GROUP
+    OBJECTS   { ipIfStatsHCInOctets,      ipIfStatsHCOutOctets,
+                ipIfStatsHCInMcastOctets, ipIfStatsHCOutMcastOctets }
+    STATUS     current
+    DESCRIPTION
+           "IP per-interfaces statistics for systems that include
+            interfaces that may overflow the standard octet
+            counters within 1 hour."
+    ::= { ipMIBGroups 15 }
+
+ipIfStatsHCPacketGroup OBJECT-GROUP
+    OBJECTS   { ipIfStatsHCInReceives,       ipIfStatsHCInForwDatagrams,
+                ipIfStatsHCInDelivers,       ipIfStatsHCOutRequests,
+                ipIfStatsHCOutForwDatagrams, ipIfStatsHCOutTransmits,
+                ipIfStatsHCInMcastPkts,      ipIfStatsHCOutMcastPkts }
+    STATUS     current
+    DESCRIPTION
+           "IP per-interfaces statistics for systems that include
+            interfaces that may overflow the standard packet counters
+            within 1 hour."
+    ::= { ipMIBGroups 16 }
+
+ipv4IfStatsHCPacketGroup OBJECT-GROUP
+    OBJECTS   { ipIfStatsHCInBcastPkts, ipIfStatsHCOutBcastPkts }
+    STATUS     current
+    DESCRIPTION
+           "IPv4 only per-interface statistics for systems that include
+            interfaces that may overflow the standard packet counters
+            within 1 hour."
+    ::= { ipMIBGroups 17 }
+
+ipAddressPrefixGroup OBJECT-GROUP
+    OBJECTS   { ipAddressPrefixOrigin,
+                ipAddressPrefixOnLinkFlag,
+                ipAddressPrefixAutonomousFlag,
+                ipAddressPrefixAdvPreferredLifetime,
+                ipAddressPrefixAdvValidLifetime }
+    STATUS     current
+
+
+
+    DESCRIPTION
+           "The group of objects for providing information about address
+            prefixes used by this node."
+    ::= { ipMIBGroups 18 }
+
+ipAddressGroup OBJECT-GROUP
+    OBJECTS   { ipAddressSpinLock,  ipAddressIfIndex,
+                ipAddressType,      ipAddressPrefix,
+                ipAddressOrigin,    ipAddressStatus,
+                ipAddressCreated,   ipAddressLastChanged,
+                ipAddressRowStatus, ipAddressStorageType }
+    STATUS     current
+    DESCRIPTION
+           "The group of objects for providing information about the
+            addresses relevant to this entity's interfaces."
+    ::= { ipMIBGroups 19 }
+
+ipNetToPhysicalGroup OBJECT-GROUP
+    OBJECTS   { ipNetToPhysicalPhysAddress, ipNetToPhysicalLastUpdated,
+                ipNetToPhysicalType,        ipNetToPhysicalState,
+                ipNetToPhysicalRowStatus }
+    STATUS     current
+    DESCRIPTION
+           "The group of objects for providing information about the
+            mappings of network address to physical address known to
+            this node."
+    ::= { ipMIBGroups 20 }
+
+ipv6ScopeGroup OBJECT-GROUP
+    OBJECTS   { ipv6ScopeZoneIndexLinkLocal,
+                ipv6ScopeZoneIndex3,
+                ipv6ScopeZoneIndexAdminLocal,
+                ipv6ScopeZoneIndexSiteLocal,
+                ipv6ScopeZoneIndex6,
+                ipv6ScopeZoneIndex7,
+                ipv6ScopeZoneIndexOrganizationLocal,
+                ipv6ScopeZoneIndex9,
+                ipv6ScopeZoneIndexA,
+                ipv6ScopeZoneIndexB,
+                ipv6ScopeZoneIndexC,
+                ipv6ScopeZoneIndexD }
+    STATUS     current
+    DESCRIPTION
+           "The group of objects for managing IPv6 scope zones."
+    ::= { ipMIBGroups 21 }
+
+ipDefaultRouterGroup OBJECT-GROUP
+    OBJECTS   { ipDefaultRouterLifetime, ipDefaultRouterPreference }
+
+
+
+    STATUS     current
+    DESCRIPTION
+           "The group of objects for providing information about default
+            routers known to this node."
+    ::= { ipMIBGroups 22 }
+
+ipv6RouterAdvertGroup OBJECT-GROUP
+    OBJECTS   { ipv6RouterAdvertSpinLock,
+                ipv6RouterAdvertSendAdverts,
+                ipv6RouterAdvertMaxInterval,
+                ipv6RouterAdvertMinInterval,
+                ipv6RouterAdvertManagedFlag,
+                ipv6RouterAdvertOtherConfigFlag,
+                ipv6RouterAdvertLinkMTU,
+                ipv6RouterAdvertReachableTime,
+                ipv6RouterAdvertRetransmitTime,
+                ipv6RouterAdvertCurHopLimit,
+                ipv6RouterAdvertDefaultLifetime,
+                ipv6RouterAdvertRowStatus
+}
+    STATUS     current
+    DESCRIPTION
+           "The group of objects for controlling information advertised
+            by IPv6 routers."
+    ::= { ipMIBGroups 23 }
+
+icmpStatsGroup OBJECT-GROUP
+    OBJECTS   {icmpStatsInMsgs,    icmpStatsInErrors,
+               icmpStatsOutMsgs,   icmpStatsOutErrors,
+               icmpMsgStatsInPkts, icmpMsgStatsOutPkts }
+    STATUS     current
+    DESCRIPTION
+           "The group of objects providing ICMP statistics."
+    ::= { ipMIBGroups 24 }
+
+--
+-- Deprecated objects
+--
+
+ipInReceives OBJECT-TYPE
+    SYNTAX     Counter32
+    MAX-ACCESS read-only
+    STATUS     deprecated
+    DESCRIPTION
+           "The total number of input datagrams received from
+            interfaces, including those received in error.
+
+            This object has been deprecated, as a new IP version-neutral
+
+
+
+            table has been added.  It is loosely replaced by
+            ipSystemStatsInRecieves."
+    ::= { ip 3 }
+
+ipInHdrErrors OBJECT-TYPE
+    SYNTAX     Counter32
+    MAX-ACCESS read-only
+    STATUS     deprecated
+    DESCRIPTION
+           "The number of input datagrams discarded due to errors in
+            their IPv4 headers, including bad checksums, version number
+            mismatch, other format errors, time-to-live exceeded, errors
+            discovered in processing their IPv4 options, etc.
+
+            This object has been deprecated as a new IP version-neutral
+            table has been added.  It is loosely replaced by
+            ipSystemStatsInHdrErrors."
+    ::= { ip 4 }
+
+ipInAddrErrors OBJECT-TYPE
+    SYNTAX     Counter32
+    MAX-ACCESS read-only
+    STATUS     deprecated
+    DESCRIPTION
+           "The number of input datagrams discarded because the IPv4
+            address in their IPv4 header's destination field was not a
+            valid address to be received at this entity.  This count
+            includes invalid addresses (e.g., 0.0.0.0) and addresses of
+            unsupported Classes (e.g., Class E).  For entities which are
+            not IPv4 routers, and therefore do not forward datagrams,
+            this counter includes datagrams discarded because the
+            destination address was not a local address.
+
+            This object has been deprecated, as a new IP version-neutral
+            table has been added.  It is loosely replaced by
+            ipSystemStatsInAddrErrors."
+    ::= { ip 5 }
+
+ipForwDatagrams OBJECT-TYPE
+    SYNTAX     Counter32
+    MAX-ACCESS read-only
+    STATUS     deprecated
+    DESCRIPTION
+           "The number of input datagrams for which this entity was not
+            their final IPv4 destination, as a result of which an
+            attempt was made to find a route to forward them to that
+            final destination.  In entities which do not act as IPv4
+            routers, this counter will include only those packets which
+
+
+
+            were Source-Routed via this entity, and the Source-Route
+            option processing was successful.
+
+            This object has been deprecated, as a new IP version-neutral
+            table has been added.  It is loosely replaced by
+            ipSystemStatsInForwDatagrams."
+    ::= { ip 6 }
+
+ipInUnknownProtos OBJECT-TYPE
+    SYNTAX     Counter32
+    MAX-ACCESS read-only
+    STATUS     deprecated
+    DESCRIPTION
+           "The number of locally-addressed datagrams received
+            successfully but discarded because of an unknown or
+            unsupported protocol.
+
+            This object has been deprecated, as a new IP version-neutral
+            table has been added.  It is loosely replaced by
+            ipSystemStatsInUnknownProtos."
+    ::= { ip 7 }
+
+ipInDiscards OBJECT-TYPE
+    SYNTAX     Counter32
+    MAX-ACCESS read-only
+    STATUS     deprecated
+    DESCRIPTION
+           "The number of input IPv4 datagrams for which no problems
+            were encountered to prevent their continued processing, but
+            which were discarded (e.g., for lack of buffer space).  Note
+            that this counter does not include any datagrams discarded
+            while awaiting re-assembly.
+
+            This object has been deprecated, as a new IP version-neutral
+            table has been added.  It is loosely replaced by
+            ipSystemStatsInDiscards."
+    ::= { ip 8 }
+
+ipInDelivers OBJECT-TYPE
+    SYNTAX     Counter32
+    MAX-ACCESS read-only
+    STATUS     deprecated
+    DESCRIPTION
+           "The total number of input datagrams successfully delivered
+            to IPv4 user-protocols (including ICMP).
+
+            This object has been deprecated as a new IP version neutral
+            table has been added.  It is loosely replaced by
+
+
+
+            ipSystemStatsIndelivers."
+    ::= { ip 9 }
+
+ipOutRequests OBJECT-TYPE
+    SYNTAX     Counter32
+    MAX-ACCESS read-only
+    STATUS     deprecated
+    DESCRIPTION
+           "The total number of IPv4 datagrams which local IPv4 user
+            protocols (including ICMP) supplied to IPv4 in requests for
+            transmission.  Note that this counter does not include any
+            datagrams counted in ipForwDatagrams.
+
+            This object has been deprecated, as a new IP version-neutral
+            table has been added.  It is loosely replaced by
+            ipSystemStatsOutRequests."
+    ::= { ip 10 }
+
+ipOutDiscards OBJECT-TYPE
+    SYNTAX     Counter32
+    MAX-ACCESS read-only
+    STATUS     deprecated
+    DESCRIPTION
+           "The number of output IPv4 datagrams for which no problem was
+            encountered to prevent their transmission to their
+            destination, but which were discarded (e.g., for lack of
+            buffer space).  Note that this counter would include
+            datagrams counted in ipForwDatagrams if any such packets met
+            this (discretionary) discard criterion.
+
+            This object has been deprecated, as a new IP version-neutral
+            table has been added.  It is loosely replaced by
+            ipSystemStatsOutDiscards."
+    ::= { ip 11 }
+
+ipOutNoRoutes OBJECT-TYPE
+    SYNTAX     Counter32
+    MAX-ACCESS read-only
+    STATUS     deprecated
+    DESCRIPTION
+           "The number of IPv4 datagrams discarded because no route
+            could be found to transmit them to their destination.  Note
+            that this counter includes any packets counted in
+            ipForwDatagrams which meet this `no-route' criterion.  Note
+            that this includes any datagrams which a host cannot route
+            because all of its default routers are down.
+
+            This object has been deprecated, as a new IP version-neutral
+
+
+
+            table has been added.  It is loosely replaced by
+            ipSystemStatsOutNoRoutes."
+    ::= { ip 12 }
+
+ipReasmReqds OBJECT-TYPE
+    SYNTAX     Counter32
+    MAX-ACCESS read-only
+    STATUS     deprecated
+    DESCRIPTION
+           "The number of IPv4 fragments received which needed to be
+            reassembled at this entity.
+
+            This object has been deprecated, as a new IP version-neutral
+            table has been added.  It is loosely replaced by
+            ipSystemStatsReasmReqds."
+    ::= { ip 14 }
+
+ipReasmOKs OBJECT-TYPE
+    SYNTAX     Counter32
+    MAX-ACCESS read-only
+    STATUS     deprecated
+    DESCRIPTION
+           "The number of IPv4 datagrams successfully re-assembled.
+
+            This object has been deprecated, as a new IP version-neutral
+            table has been added.  It is loosely replaced by
+            ipSystemStatsReasmOKs."
+    ::= { ip 15 }
+
+ipReasmFails OBJECT-TYPE
+    SYNTAX     Counter32
+    MAX-ACCESS read-only
+    STATUS     deprecated
+    DESCRIPTION
+           "The number of failures detected by the IPv4 re-assembly
+            algorithm (for whatever reason: timed out, errors, etc).
+            Note that this is not necessarily a count of discarded IPv4
+            fragments since some algorithms (notably the algorithm in
+            RFC 815) can lose track of the number of fragments by
+            combining them as they are received.
+
+            This object has been deprecated, as a new IP version-neutral
+            table has been added.  It is loosely replaced by
+            ipSystemStatsReasmFails."
+    ::= { ip 16 }
+
+ipFragOKs OBJECT-TYPE
+    SYNTAX     Counter32
+
+
+
+    MAX-ACCESS read-only
+    STATUS     deprecated
+    DESCRIPTION
+           "The number of IPv4 datagrams that have been successfully
+            fragmented at this entity.
+
+            This object has been deprecated, as a new IP version-neutral
+            table has been added.  It is loosely replaced by
+            ipSystemStatsOutFragOKs."
+    ::= { ip 17 }
+
+ipFragFails OBJECT-TYPE
+    SYNTAX     Counter32
+    MAX-ACCESS read-only
+    STATUS     deprecated
+    DESCRIPTION
+           "The number of IPv4 datagrams that have been discarded
+            because they needed to be fragmented at this entity but
+            could not be, e.g., because their Don't Fragment flag was
+            set.
+
+            This object has been deprecated, as a new IP version-neutral
+            table has been added.  It is loosely replaced by
+            ipSystemStatsOutFragFails."
+    ::= { ip 18 }
+
+ipFragCreates OBJECT-TYPE
+    SYNTAX     Counter32
+    MAX-ACCESS read-only
+    STATUS     deprecated
+    DESCRIPTION
+           "The number of IPv4 datagram fragments that have been
+            generated as a result of fragmentation at this entity.
+
+            This object has been deprecated as a new IP version neutral
+            table has been added.  It is loosely replaced by
+            ipSystemStatsOutFragCreates."
+    ::= { ip 19 }
+
+ipRoutingDiscards OBJECT-TYPE
+    SYNTAX     Counter32
+    MAX-ACCESS read-only
+    STATUS     deprecated
+    DESCRIPTION
+           "The number of routing entries which were chosen to be
+            discarded even though they are valid.  One possible reason
+            for discarding such an entry could be to free-up buffer
+            space for other routing entries.
+
+
+
+            This object was defined in pre-IPv6 versions of the IP MIB.
+            It was implicitly IPv4 only, but the original specifications
+            did not indicate this protocol restriction.  In order to
+            clarify the specifications, this object has been deprecated
+            and a similar, but more thoroughly clarified, object has
+            been added to the IP-FORWARD-MIB."
+    ::= { ip 23 }
+
+-- the deprecated IPv4 address table
+
+ipAddrTable OBJECT-TYPE
+    SYNTAX     SEQUENCE OF IpAddrEntry
+    MAX-ACCESS not-accessible
+    STATUS     deprecated
+    DESCRIPTION
+           "The table of addressing information relevant to this
+            entity's IPv4 addresses.
+
+            This table has been deprecated, as a new IP version-neutral
+            table has been added.  It is loosely replaced by the
+            ipAddressTable although several objects that weren't deemed
+            useful weren't carried forward while another
+            (ipAdEntReasmMaxSize) was moved to the ipv4InterfaceTable."
+    ::= { ip 20 }
+
+ipAddrEntry OBJECT-TYPE
+    SYNTAX     IpAddrEntry
+    MAX-ACCESS not-accessible
+    STATUS     deprecated
+    DESCRIPTION
+           "The addressing information for one of this entity's IPv4
+            addresses."
+    INDEX      { ipAdEntAddr }
+    ::= { ipAddrTable 1 }
+
+IpAddrEntry ::= SEQUENCE {
+        ipAdEntAddr          IpAddress,
+        ipAdEntIfIndex       INTEGER,
+        ipAdEntNetMask       IpAddress,
+        ipAdEntBcastAddr     INTEGER,
+        ipAdEntReasmMaxSize  INTEGER
+    }
+
+ipAdEntAddr OBJECT-TYPE
+    SYNTAX     IpAddress
+    MAX-ACCESS read-only
+    STATUS     deprecated
+    DESCRIPTION
+
+
+
+           "The IPv4 address to which this entry's addressing
+            information pertains."
+    ::= { ipAddrEntry 1 }
+
+ipAdEntIfIndex OBJECT-TYPE
+    SYNTAX     INTEGER (1..2147483647)
+    MAX-ACCESS read-only
+    STATUS     deprecated
+    DESCRIPTION
+           "The index value which uniquely identifies the interface to
+            which this entry is applicable.  The interface identified by
+            a particular value of this index is the same interface as
+            identified by the same value of the IF-MIB's ifIndex."
+    ::= { ipAddrEntry 2 }
+
+ipAdEntNetMask OBJECT-TYPE
+    SYNTAX     IpAddress
+    MAX-ACCESS read-only
+    STATUS     deprecated
+    DESCRIPTION
+           "The subnet mask associated with the IPv4 address of this
+            entry.  The value of the mask is an IPv4 address with all
+            the network bits set to 1 and all the hosts bits set to 0."
+    ::= { ipAddrEntry 3 }
+
+ipAdEntBcastAddr OBJECT-TYPE
+    SYNTAX     INTEGER (0..1)
+    MAX-ACCESS read-only
+    STATUS     deprecated
+    DESCRIPTION
+           "The value of the least-significant bit in the IPv4 broadcast
+            address used for sending datagrams on the (logical)
+            interface associated with the IPv4 address of this entry.
+            For example, when the Internet standard all-ones broadcast
+            address is used, the value will be 1.  This value applies to
+            both the subnet and network broadcast addresses used by the
+            entity on this (logical) interface."
+    ::= { ipAddrEntry 4 }
+
+ipAdEntReasmMaxSize OBJECT-TYPE
+    SYNTAX     INTEGER (0..65535)
+    MAX-ACCESS read-only
+    STATUS     deprecated
+    DESCRIPTION
+           "The size of the largest IPv4 datagram which this entity can
+            re-assemble from incoming IPv4 fragmented datagrams received
+            on this interface."
+    ::= { ipAddrEntry 5 }
+
+
+
+-- the deprecated IPv4 Address Translation table
+
+-- The Address Translation tables contain the IpAddress to
+-- "physical" address equivalences.  Some interfaces do not
+-- use translation tables for determining address
+-- equivalences (e.g., DDN-X.25 has an algorithmic method);
+-- if all interfaces are of this type, then the Address
+-- Translation table is empty, i.e., has zero entries.
+
+ipNetToMediaTable OBJECT-TYPE
+    SYNTAX     SEQUENCE OF IpNetToMediaEntry
+    MAX-ACCESS not-accessible
+    STATUS     deprecated
+    DESCRIPTION
+           "The IPv4 Address Translation table used for mapping from
+            IPv4 addresses to physical addresses.
+
+            This table has been deprecated, as a new IP version-neutral
+            table has been added.  It is loosely replaced by the
+            ipNetToPhysicalTable."
+    ::= { ip 22 }
+
+ipNetToMediaEntry OBJECT-TYPE
+    SYNTAX     IpNetToMediaEntry
+    MAX-ACCESS not-accessible
+    STATUS     deprecated
+    DESCRIPTION
+           "Each entry contains one IpAddress to `physical' address
+            equivalence."
+    INDEX       { ipNetToMediaIfIndex,
+                  ipNetToMediaNetAddress }
+    ::= { ipNetToMediaTable 1 }
+
+IpNetToMediaEntry ::= SEQUENCE {
+        ipNetToMediaIfIndex      INTEGER,
+        ipNetToMediaPhysAddress  PhysAddress,
+        ipNetToMediaNetAddress   IpAddress,
+        ipNetToMediaType         INTEGER
+    }
+
+ipNetToMediaIfIndex OBJECT-TYPE
+    SYNTAX     INTEGER (1..2147483647)
+    MAX-ACCESS read-create
+    STATUS     deprecated
+    DESCRIPTION
+           "The interface on which this entry's equivalence is
+            effective.  The interface identified by a particular value
+            of this index is the same interface as identified by the
+
+
+
+            same value of the IF-MIB's ifIndex.
+
+            This object predates the rule limiting index objects to a
+            max access value of 'not-accessible' and so continues to use
+            a value of 'read-create'."
+    ::= { ipNetToMediaEntry 1 }
+
+ipNetToMediaPhysAddress OBJECT-TYPE
+    SYNTAX     PhysAddress (SIZE(0..65535))
+    MAX-ACCESS read-create
+    STATUS     deprecated
+    DESCRIPTION
+           "The media-dependent `physical' address.  This object should
+            return 0 when this entry is in the 'incomplete' state.
+
+            As the entries in this table are typically not persistent
+            when this object is written the entity should not save the
+            change to non-volatile storage.  Note: a stronger
+            requirement is not used because this object was previously
+            defined."
+    ::= { ipNetToMediaEntry 2 }
+
+ipNetToMediaNetAddress OBJECT-TYPE
+    SYNTAX     IpAddress
+    MAX-ACCESS read-create
+    STATUS     deprecated
+    DESCRIPTION
+           "The IpAddress corresponding to the media-dependent
+            `physical' address.
+
+            This object predates the rule limiting index objects to a
+            max access value of 'not-accessible' and so continues to use
+            a value of 'read-create'."
+    ::= { ipNetToMediaEntry 3 }
+
+ipNetToMediaType OBJECT-TYPE
+    SYNTAX     INTEGER {
+                other(1),        -- none of the following
+                invalid(2),      -- an invalidated mapping
+                dynamic(3),
+                static(4)
+            }
+    MAX-ACCESS read-create
+    STATUS     deprecated
+    DESCRIPTION
+           "The type of mapping.
+
+            Setting this object to the value invalid(2) has the effect
+
+
+
+            of invalidating the corresponding entry in the
+            ipNetToMediaTable.  That is, it effectively dis-associates
+            the interface identified with said entry from the mapping
+            identified with said entry.  It is an implementation-
+            specific matter as to whether the agent removes an
+            invalidated entry from the table.  Accordingly, management
+            stations must be prepared to receive tabular information
+            from agents that corresponds to entries not currently in
+            use.  Proper interpretation of such entries requires
+            examination of the relevant ipNetToMediaType object.
+
+            As the entries in this table are typically not persistent
+            when this object is written the entity should not save the
+            change to non-volatile storage.  Note: a stronger
+            requirement is not used because this object was previously
+            defined."
+    ::= { ipNetToMediaEntry 4 }
+
+-- the deprecated ICMP group
+
+icmpInMsgs OBJECT-TYPE
+    SYNTAX     Counter32
+    MAX-ACCESS read-only
+    STATUS     deprecated
+    DESCRIPTION
+           "The total number of ICMP messages which the entity received.
+            Note that this counter includes all those counted by
+            icmpInErrors.
+
+            This object has been deprecated, as a new IP version-neutral
+            table has been added.  It is loosely replaced by
+            icmpStatsInMsgs."
+    ::= { icmp 1 }
+
+icmpInErrors OBJECT-TYPE
+    SYNTAX     Counter32
+    MAX-ACCESS read-only
+    STATUS     deprecated
+    DESCRIPTION
+           "The number of ICMP messages which the entity received but
+            determined as having ICMP-specific errors (bad ICMP
+            checksums, bad length, etc.).
+
+            This object has been deprecated, as a new IP version-neutral
+            table has been added.  It is loosely replaced by
+            icmpStatsInErrors."
+    ::= { icmp 2 }
+
+
+
+
+icmpInDestUnreachs OBJECT-TYPE
+    SYNTAX     Counter32
+    MAX-ACCESS read-only
+    STATUS     deprecated
+    DESCRIPTION
+           "The number of ICMP Destination Unreachable messages
+            received.
+
+            This object has been deprecated, as a new IP version-neutral
+            table has been added.  It is loosely replaced by a column in
+            the icmpMsgStatsTable."
+    ::= { icmp 3 }
+
+icmpInTimeExcds OBJECT-TYPE
+    SYNTAX     Counter32
+    MAX-ACCESS read-only
+    STATUS     deprecated
+    DESCRIPTION
+           "The number of ICMP Time Exceeded messages received.
+
+            This object has been deprecated, as a new IP version-neutral
+            table has been added.  It is loosely replaced by a column in
+            the icmpMsgStatsTable."
+    ::= { icmp 4 }
+
+icmpInParmProbs OBJECT-TYPE
+    SYNTAX     Counter32
+    MAX-ACCESS read-only
+    STATUS     deprecated
+    DESCRIPTION
+           "The number of ICMP Parameter Problem messages received.
+
+            This object has been deprecated, as a new IP version-neutral
+            table has been added.  It is loosely replaced by a column in
+            the icmpMsgStatsTable."
+    ::= { icmp 5 }
+
+icmpInSrcQuenchs OBJECT-TYPE
+    SYNTAX     Counter32
+    MAX-ACCESS read-only
+    STATUS     deprecated
+    DESCRIPTION
+           "The number of ICMP Source Quench messages received.
+
+            This object has been deprecated, as a new IP version-neutral
+            table has been added.  It is loosely replaced by a column in
+            the icmpMsgStatsTable."
+    ::= { icmp 6 }
+
+
+
+icmpInRedirects OBJECT-TYPE
+    SYNTAX     Counter32
+    MAX-ACCESS read-only
+    STATUS     deprecated
+    DESCRIPTION
+           "The number of ICMP Redirect messages received.
+
+            This object has been deprecated, as a new IP version-neutral
+            table has been added.  It is loosely replaced by a column in
+            the icmpMsgStatsTable."
+    ::= { icmp 7 }
+
+icmpInEchos OBJECT-TYPE
+    SYNTAX     Counter32
+    MAX-ACCESS read-only
+    STATUS     deprecated
+    DESCRIPTION
+           "The number of ICMP Echo (request) messages received.
+
+            This object has been deprecated, as a new IP version-neutral
+            table has been added.  It is loosely replaced by a column in
+            the icmpMsgStatsTable."
+    ::= { icmp 8 }
+
+icmpInEchoReps OBJECT-TYPE
+    SYNTAX     Counter32
+    MAX-ACCESS read-only
+    STATUS     deprecated
+    DESCRIPTION
+           "The number of ICMP Echo Reply messages received.
+
+            This object has been deprecated, as a new IP version-neutral
+            table has been added.  It is loosely replaced by a column in
+            the icmpMsgStatsTable."
+    ::= { icmp 9 }
+
+icmpInTimestamps OBJECT-TYPE
+    SYNTAX     Counter32
+    MAX-ACCESS read-only
+    STATUS     deprecated
+    DESCRIPTION
+           "The number of ICMP Timestamp (request) messages received.
+
+            This object has been deprecated, as a new IP version-neutral
+            table has been added.  It is loosely replaced by a column in
+            the icmpMsgStatsTable."
+    ::= { icmp 10 }
+
+
+
+
+icmpInTimestampReps OBJECT-TYPE
+    SYNTAX     Counter32
+    MAX-ACCESS read-only
+    STATUS     deprecated
+    DESCRIPTION
+           "The number of ICMP Timestamp Reply messages received.
+
+            This object has been deprecated, as a new IP version-neutral
+            table has been added.  It is loosely replaced by a column in
+            the icmpMsgStatsTable."
+    ::= { icmp 11 }
+
+icmpInAddrMasks OBJECT-TYPE
+    SYNTAX     Counter32
+    MAX-ACCESS read-only
+    STATUS     deprecated
+    DESCRIPTION
+           "The number of ICMP Address Mask Request messages received.
+
+            This object has been deprecated, as a new IP version-neutral
+            table has been added.  It is loosely replaced by a column in
+            the icmpMsgStatsTable."
+    ::= { icmp 12 }
+
+icmpInAddrMaskReps OBJECT-TYPE
+    SYNTAX     Counter32
+    MAX-ACCESS read-only
+    STATUS     deprecated
+    DESCRIPTION
+           "The number of ICMP Address Mask Reply messages received.
+
+            This object has been deprecated, as a new IP version-neutral
+            table has been added.  It is loosely replaced by a column in
+            the icmpMsgStatsTable."
+    ::= { icmp 13 }
+
+icmpOutMsgs OBJECT-TYPE
+    SYNTAX     Counter32
+    MAX-ACCESS read-only
+    STATUS     deprecated
+    DESCRIPTION
+           "The total number of ICMP messages which this entity
+            attempted to send.  Note that this counter includes all
+            those counted by icmpOutErrors.
+
+            This object has been deprecated, as a new IP version-neutral
+            table has been added.  It is loosely replaced by
+            icmpStatsOutMsgs."
+
+
+
+    ::= { icmp 14 }
+
+icmpOutErrors OBJECT-TYPE
+    SYNTAX     Counter32
+    MAX-ACCESS read-only
+    STATUS     deprecated
+    DESCRIPTION
+           "The number of ICMP messages which this entity did not send
+            due to problems discovered within ICMP, such as a lack of
+            buffers.  This value should not include errors discovered
+            outside the ICMP layer, such as the inability of IP to route
+            the resultant datagram.  In some implementations, there may
+            be no types of error which contribute to this counter's
+            value.
+
+            This object has been deprecated, as a new IP version-neutral
+            table has been added.  It is loosely replaced by
+            icmpStatsOutErrors."
+    ::= { icmp 15 }
+
+icmpOutDestUnreachs OBJECT-TYPE
+    SYNTAX     Counter32
+    MAX-ACCESS read-only
+    STATUS     deprecated
+    DESCRIPTION
+           "The number of ICMP Destination Unreachable messages sent.
+
+            This object has been deprecated, as a new IP version-neutral
+            table has been added.  It is loosely replaced by a column in
+            the icmpMsgStatsTable."
+    ::= { icmp 16 }
+
+icmpOutTimeExcds OBJECT-TYPE
+    SYNTAX     Counter32
+    MAX-ACCESS read-only
+    STATUS     deprecated
+    DESCRIPTION
+           "The number of ICMP Time Exceeded messages sent.
+
+            This object has been deprecated, as a new IP version-neutral
+            table has been added.  It is loosely replaced by a column in
+            the icmpMsgStatsTable."
+    ::= { icmp 17 }
+
+icmpOutParmProbs OBJECT-TYPE
+    SYNTAX     Counter32
+    MAX-ACCESS read-only
+    STATUS     deprecated
+
+
+
+    DESCRIPTION
+           "The number of ICMP Parameter Problem messages sent.
+
+            This object has been deprecated, as a new IP version-neutral
+            table has been added.  It is loosely replaced by a column in
+            the icmpMsgStatsTable."
+    ::= { icmp 18 }
+
+icmpOutSrcQuenchs OBJECT-TYPE
+    SYNTAX     Counter32
+    MAX-ACCESS read-only
+    STATUS     deprecated
+    DESCRIPTION
+           "The number of ICMP Source Quench messages sent.
+
+            This object has been deprecated, as a new IP version-neutral
+            table has been added.  It is loosely replaced by a column in
+            the icmpMsgStatsTable."
+    ::= { icmp 19 }
+
+icmpOutRedirects OBJECT-TYPE
+    SYNTAX     Counter32
+    MAX-ACCESS read-only
+    STATUS     deprecated
+    DESCRIPTION
+           "The number of ICMP Redirect messages sent.  For a host, this
+            object will always be zero, since hosts do not send
+            redirects.
+
+            This object has been deprecated, as a new IP version-neutral
+            table has been added.  It is loosely replaced by a column in
+            the icmpMsgStatsTable."
+    ::= { icmp 20 }
+
+icmpOutEchos OBJECT-TYPE
+    SYNTAX     Counter32
+    MAX-ACCESS read-only
+    STATUS     deprecated
+    DESCRIPTION
+           "The number of ICMP Echo (request) messages sent.
+
+            This object has been deprecated, as a new IP version-neutral
+            table has been added.  It is loosely replaced by a column in
+            the icmpMsgStatsTable."
+    ::= { icmp 21 }
+
+icmpOutEchoReps OBJECT-TYPE
+    SYNTAX     Counter32
+
+
+
+    MAX-ACCESS read-only
+    STATUS     deprecated
+    DESCRIPTION
+           "The number of ICMP Echo Reply messages sent.
+
+            This object has been deprecated, as a new IP version-neutral
+            table has been added.  It is loosely replaced by a column in
+            the icmpMsgStatsTable."
+    ::= { icmp 22 }
+
+icmpOutTimestamps OBJECT-TYPE
+    SYNTAX     Counter32
+    MAX-ACCESS read-only
+    STATUS     deprecated
+    DESCRIPTION
+           "The number of ICMP Timestamp (request) messages sent.
+
+            This object has been deprecated, as a new IP version-neutral
+            table has been added.  It is loosely replaced by a column in
+            the icmpMsgStatsTable."
+    ::= { icmp 23 }
+
+icmpOutTimestampReps OBJECT-TYPE
+    SYNTAX     Counter32
+    MAX-ACCESS read-only
+    STATUS     deprecated
+    DESCRIPTION
+           "The number of ICMP Timestamp Reply messages sent.
+
+            This object has been deprecated, as a new IP version-neutral
+            table has been added.  It is loosely replaced by a column in
+            the icmpMsgStatsTable."
+    ::= { icmp 24 }
+
+icmpOutAddrMasks OBJECT-TYPE
+    SYNTAX     Counter32
+    MAX-ACCESS read-only
+    STATUS     deprecated
+    DESCRIPTION
+           "The number of ICMP Address Mask Request messages sent.
+
+            This object has been deprecated, as a new IP version-neutral
+            table has been added.  It is loosely replaced by a column in
+            the icmpMsgStatsTable."
+    ::= { icmp 25 }
+
+icmpOutAddrMaskReps OBJECT-TYPE
+    SYNTAX     Counter32
+
+
+
+    MAX-ACCESS read-only
+    STATUS     deprecated
+    DESCRIPTION
+           "The number of ICMP Address Mask Reply messages sent.
+
+            This object has been deprecated, as a new IP version-neutral
+            table has been added.  It is loosely replaced by a column in
+            the icmpMsgStatsTable."
+    ::= { icmp 26 }
+
+-- deprecated conformance information
+-- deprecated compliance statements
+
+ipMIBCompliance MODULE-COMPLIANCE
+    STATUS     deprecated
+    DESCRIPTION
+           "The compliance statement for systems that implement only
+            IPv4.  For version-independence, this compliance statement
+            is deprecated in favor of ipMIBCompliance2."
+    MODULE  -- this module
+        MANDATORY-GROUPS { ipGroup,
+                           icmpGroup }
+    ::= { ipMIBCompliances 1 }
+
+-- deprecated units of conformance
+
+ipGroup OBJECT-GROUP
+    OBJECTS   { ipForwarding,           ipDefaultTTL,
+                ipInReceives,           ipInHdrErrors,
+                ipInAddrErrors,         ipForwDatagrams,
+                ipInUnknownProtos,      ipInDiscards,
+                ipInDelivers,           ipOutRequests,
+                ipOutDiscards,          ipOutNoRoutes,
+                ipReasmTimeout,         ipReasmReqds,
+                ipReasmOKs,             ipReasmFails,
+                ipFragOKs,              ipFragFails,
+                ipFragCreates,          ipAdEntAddr,
+                ipAdEntIfIndex,         ipAdEntNetMask,
+                ipAdEntBcastAddr,       ipAdEntReasmMaxSize,
+                ipNetToMediaIfIndex,    ipNetToMediaPhysAddress,
+                ipNetToMediaNetAddress, ipNetToMediaType,
+                ipRoutingDiscards
+}
+    STATUS     deprecated
+    DESCRIPTION
+           "The ip group of objects providing for basic management of IP
+            entities, exclusive of the management of IP routes.
+
+
+
+
+            As part of the version independence, this group has been
+            deprecated.  "
+    ::= { ipMIBGroups 1 }
+
+icmpGroup OBJECT-GROUP
+    OBJECTS   { icmpInMsgs,          icmpInErrors,
+                icmpInDestUnreachs,  icmpInTimeExcds,
+                icmpInParmProbs,     icmpInSrcQuenchs,
+                icmpInRedirects,     icmpInEchos,
+                icmpInEchoReps,      icmpInTimestamps,
+                icmpInTimestampReps, icmpInAddrMasks,
+                icmpInAddrMaskReps,  icmpOutMsgs,
+                icmpOutErrors,       icmpOutDestUnreachs,
+                icmpOutTimeExcds,    icmpOutParmProbs,
+                icmpOutSrcQuenchs,   icmpOutRedirects,
+                icmpOutEchos,        icmpOutEchoReps,
+                icmpOutTimestamps,   icmpOutTimestampReps,
+                icmpOutAddrMasks,    icmpOutAddrMaskReps }
+    STATUS     deprecated
+    DESCRIPTION
+           "The icmp group of objects providing ICMP statistics.
+
+            As part of the version independence, this group has been
+            deprecated.  "
+    ::= { ipMIBGroups 2 }
+
+END
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/Mibs/RFC-1212
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/Mibs/RFC-1212	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/Mibs/RFC-1212	(revision 457)
@@ -0,0 +1,75 @@
+RFC-1212 DEFINITIONS ::= BEGIN
+
+          IMPORTS
+              ObjectName
+                  FROM RFC1155-SMI;
+--            DisplayString
+--                FROM RFC1158-MIB;
+
+          OBJECT-TYPE MACRO ::=
+          BEGIN
+              TYPE NOTATION ::=
+                                          -- must conform to
+                                          -- RFC1155's ObjectSyntax
+                                "SYNTAX" type(ObjectSyntax)
+                                "ACCESS" Access
+                                "STATUS" Status
+                                DescrPart
+                                ReferPart
+                                IndexPart
+                                DefValPart
+              VALUE NOTATION ::= value (VALUE ObjectName)
+
+              Access ::= "read-only"
+                              | "read-write"
+                              | "write-only"
+                              | "not-accessible"
+              Status ::= "mandatory"
+                              | "optional"
+                              | "obsolete"
+                              | "deprecated"
+
+              DescrPart ::=
+                         "DESCRIPTION" value (description DisplayString)
+                              | empty
+
+              ReferPart ::=
+                         "REFERENCE" value (reference DisplayString)
+                              | empty
+
+              IndexPart ::=
+                         "INDEX" "{" IndexTypes "}"
+                              | empty
+              IndexTypes ::=
+                         IndexType | IndexTypes "," IndexType
+              IndexType ::=
+                                  -- if indexobject, use the SYNTAX
+                                  -- value of the correspondent
+                                  -- OBJECT-TYPE invocation
+                         value (indexobject ObjectName)
+                                  -- otherwise use named SMI type
+                                  -- must conform to IndexSyntax below
+                              | type (indextype)
+
+              DefValPart ::=
+                         "DEFVAL" "{" value (defvalue ObjectSyntax) "}"
+                              | empty
+
+          END
+
+          IndexSyntax ::=
+              CHOICE {
+                  number
+                      INTEGER (0..MAX),
+                  string
+                      OCTET STRING,
+                  object
+                      OBJECT IDENTIFIER,
+                  address
+                      NetworkAddress,
+                  ipAddress
+                      IpAddress
+              }
+
+END
+
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/Mibs/RFC-1215
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/Mibs/RFC-1215	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/Mibs/RFC-1215	(revision 457)
@@ -0,0 +1,34 @@
+RFC-1215 DEFINITIONS ::= BEGIN
+
+  IMPORTS
+      ObjectName
+          FROM RFC1155-SMI;
+
+  TRAP-TYPE MACRO ::=
+  BEGIN
+      TYPE NOTATION ::= "ENTERPRISE" value
+                            (enterprise OBJECT IDENTIFIER)
+                        VarPart
+                        DescrPart
+                        ReferPart
+      VALUE NOTATION ::= value (VALUE INTEGER)
+
+      VarPart ::=
+                 "VARIABLES" "{" VarTypes "}"
+                      | empty
+      VarTypes ::=
+                 VarType | VarTypes "," VarType
+      VarType ::=
+                 value (vartype ObjectName)
+
+      DescrPart ::=
+                 "DESCRIPTION" value (description DisplayString)
+                      | empty
+
+      ReferPart ::=
+                 "REFERENCE" value (reference DisplayString)
+                      | empty
+
+  END
+
+END
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/Mibs/RFC1065-SMI
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/Mibs/RFC1065-SMI	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/Mibs/RFC1065-SMI	(revision 457)
@@ -0,0 +1,132 @@
+RFC1065-SMI DEFINITIONS ::= BEGIN
+
+EXPORTS -- EVERYTHING
+        internet, directory, mgmt,
+        experimental, private, enterprises,
+        OBJECT-TYPE, ObjectName, ObjectSyntax, SimpleSyntax,
+        ApplicationSyntax, NetworkAddress, IpAddress,
+        Counter, Gauge, TimeTicks, Opaque;
+
+ -- the path to the root
+
+ internet      OBJECT IDENTIFIER ::= { iso org(3) dod(6) 1 }
+
+ directory     OBJECT IDENTIFIER ::= { internet 1 }
+
+ mgmt          OBJECT IDENTIFIER ::= { internet 2 }
+
+ experimental  OBJECT IDENTIFIER ::= { internet 3 }
+
+ private       OBJECT IDENTIFIER ::= { internet 4 }
+ enterprises   OBJECT IDENTIFIER ::= { private 1 }
+
+
+ -- definition of object types
+
+ OBJECT-TYPE MACRO ::=
+ BEGIN
+     TYPE NOTATION ::= "SYNTAX" type (TYPE ObjectSyntax)
+                       "ACCESS" Access
+                       "STATUS" Status
+     VALUE NOTATION ::= value (VALUE ObjectName)
+
+     Access ::= "read-only"
+                     | "read-write"
+                     | "write-only"
+                     | "not-accessible"
+     Status ::= "mandatory"
+                     | "optional"
+                     | "obsolete"
+ END
+
+    -- names of objects in the MIB
+
+    ObjectName ::=
+        OBJECT IDENTIFIER
+
+
+
+    -- syntax of objects in the MIB
+
+    ObjectSyntax ::=
+        CHOICE {
+            simple
+                SimpleSyntax,
+
+    -- note that simple SEQUENCEs are not directly
+    -- mentioned here to keep things simple (i.e.,
+    -- prevent mis-use).  However, application-wide
+    -- types which are IMPLICITly encoded simple
+    -- SEQUENCEs may appear in the following CHOICE
+
+               application-wide
+                   ApplicationSyntax
+           }
+
+       SimpleSyntax ::=
+           CHOICE {
+               number
+                   INTEGER,
+
+               string
+                   OCTET STRING,
+
+               object
+                   OBJECT IDENTIFIER,
+
+               empty
+                   NULL
+           }
+
+       ApplicationSyntax ::=
+           CHOICE {
+               address
+                   NetworkAddress,
+
+               counter
+                   Counter,
+
+               gauge
+                   Gauge,
+
+               ticks
+                   TimeTicks,
+
+               arbitrary
+                   Opaque
+
+
+       -- other application-wide types, as they are
+       -- defined, will be added here
+           }
+
+
+       -- application-wide types
+
+       NetworkAddress ::=
+           CHOICE {
+               internet
+                   IpAddress
+           }
+
+       IpAddress ::=
+           [APPLICATION 0]          -- in network-byte order
+               IMPLICIT OCTET STRING (SIZE (4))
+
+       Counter ::=
+           [APPLICATION 1]
+               IMPLICIT INTEGER (0..4294967295)
+
+       Gauge ::=
+           [APPLICATION 2]
+               IMPLICIT INTEGER (0..4294967295)
+
+       TimeTicks ::=
+           [APPLICATION 3]
+               IMPLICIT INTEGER
+
+       Opaque ::=
+           [APPLICATION 4]          -- arbitrary ASN.1 value,
+               IMPLICIT OCTET STRING   --   "double-wrapped"
+
+       END
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/Mibs/RFC1155-SMI
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/Mibs/RFC1155-SMI	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/Mibs/RFC1155-SMI	(revision 457)
@@ -0,0 +1,129 @@
+RFC1155-SMI DEFINITIONS ::= BEGIN
+
+EXPORTS -- EVERYTHING
+        internet, directory, mgmt,
+        experimental, private, enterprises,
+        OBJECT-TYPE, ObjectName, ObjectSyntax, SimpleSyntax,
+        ApplicationSyntax, NetworkAddress, IpAddress,
+        Counter, Gauge, TimeTicks, Opaque;
+
+ -- the path to the root
+
+ internet      OBJECT IDENTIFIER ::= { iso org(3) dod(6) 1 }
+
+ directory     OBJECT IDENTIFIER ::= { internet 1 }
+
+ mgmt          OBJECT IDENTIFIER ::= { internet 2 }
+
+ experimental  OBJECT IDENTIFIER ::= { internet 3 }
+
+ private       OBJECT IDENTIFIER ::= { internet 4 }
+ enterprises   OBJECT IDENTIFIER ::= { private 1 }
+
+
+ -- definition of object types
+
+ OBJECT-TYPE MACRO ::=
+ BEGIN
+     TYPE NOTATION ::= "SYNTAX" type (TYPE ObjectSyntax)
+                       "ACCESS" Access
+                       "STATUS" Status
+     VALUE NOTATION ::= value (VALUE ObjectName)
+
+     Access ::= "read-only"
+                     | "read-write"
+                     | "write-only"
+                     | "not-accessible"
+     Status ::= "mandatory"
+                     | "optional"
+                     | "obsolete"
+ END
+
+    -- names of objects in the MIB
+
+    ObjectName ::=
+        OBJECT IDENTIFIER
+
+    -- syntax of objects in the MIB
+
+    ObjectSyntax ::=
+        CHOICE {
+            simple
+                SimpleSyntax,
+
+    -- note that simple SEQUENCEs are not directly
+    -- mentioned here to keep things simple (i.e.,
+    -- prevent mis-use).  However, application-wide
+    -- types which are IMPLICITly encoded simple
+    -- SEQUENCEs may appear in the following CHOICE
+
+            application-wide
+                ApplicationSyntax
+        }
+
+       SimpleSyntax ::=
+           CHOICE {
+               number
+                   INTEGER,
+
+               string
+                   OCTET STRING,
+
+               object
+                   OBJECT IDENTIFIER,
+
+               empty
+                   NULL
+           }
+
+       ApplicationSyntax ::=
+           CHOICE {
+               address
+                   NetworkAddress,
+
+               counter
+                   Counter,
+
+               gauge
+                   Gauge,
+
+               ticks
+                   TimeTicks,
+
+               arbitrary
+                   Opaque
+
+       -- other application-wide types, as they are
+       -- defined, will be added here
+           }
+
+
+       -- application-wide types
+
+       NetworkAddress ::=
+           CHOICE {
+               internet
+                   IpAddress
+           }
+
+       IpAddress ::=
+           [APPLICATION 0]          -- in network-byte order
+               IMPLICIT OCTET STRING (SIZE (4))
+
+       Counter ::=
+           [APPLICATION 1]
+               IMPLICIT INTEGER (0..4294967295)
+
+       Gauge ::=
+           [APPLICATION 2]
+               IMPLICIT INTEGER (0..4294967295)
+
+       TimeTicks ::=
+           [APPLICATION 3]
+               IMPLICIT INTEGER (0..4294967295)
+
+       Opaque ::=
+           [APPLICATION 4]          -- arbitrary ASN.1 value,
+               IMPLICIT OCTET STRING   --   "double-wrapped"
+
+       END
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/Mibs/RFC1158-MIB
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/Mibs/RFC1158-MIB	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/Mibs/RFC1158-MIB	(revision 457)
@@ -0,0 +1,1493 @@
+RFC1158-MIB DEFINITIONS ::= BEGIN
+
+IMPORTS
+        mgmt, OBJECT-TYPE, NetworkAddress, IpAddress,
+        Counter, Gauge, TimeTicks
+            FROM RFC1155-SMI;
+
+DisplayString ::=
+            OCTET STRING
+
+mib-2      OBJECT IDENTIFIER ::= { mgmt 1 }    -- MIB-II
+           -- (same prefix as MIB-I)
+
+system     OBJECT IDENTIFIER ::= { mib-2 1 }
+interfaces OBJECT IDENTIFIER ::= { mib-2 2 }
+at         OBJECT IDENTIFIER ::= { mib-2 3 }
+ip         OBJECT IDENTIFIER ::= { mib-2 4 }
+icmp       OBJECT IDENTIFIER ::= { mib-2 5 }
+tcp        OBJECT IDENTIFIER ::= { mib-2 6 }
+udp        OBJECT IDENTIFIER ::= { mib-2 7 }
+egp        OBJECT IDENTIFIER ::= { mib-2 8 }
+-- cmot    OBJECT IDENTIFIER ::= { mib-2 9 }
+transmission OBJECT IDENTIFIER ::= { mib-2 10 }
+snmp       OBJECT IDENTIFIER ::= { mib-2 11 }
+
+
+-- object types
+
+-- the System group
+
+sysDescr OBJECT-TYPE
+        SYNTAX  DisplayString (SIZE (0..255))
+        ACCESS  read-only
+        STATUS  mandatory
+        ::= { system 1 }
+
+sysObjectID OBJECT-TYPE
+        SYNTAX  OBJECT IDENTIFIER
+        ACCESS  read-only
+        STATUS  mandatory
+        ::= { system 2 }
+
+sysUpTime OBJECT-TYPE
+        SYNTAX  TimeTicks
+        ACCESS  read-only
+        STATUS  mandatory
+        ::= { system 3 }
+
+sysContact OBJECT-TYPE
+        SYNTAX  DisplayString (SIZE (0..255))
+        ACCESS  read-write
+        STATUS  mandatory
+        ::= { system 4 }
+
+sysName OBJECT-TYPE
+        SYNTAX  DisplayString (SIZE (0..255))
+        ACCESS  read-write
+        STATUS  mandatory
+        ::= { system 5 }
+
+sysLocation OBJECT-TYPE
+        SYNTAX  DisplayString (SIZE (0..255))
+        ACCESS  read-only
+        STATUS  mandatory
+        ::= { system 6 }
+
+sysServices OBJECT-TYPE
+        SYNTAX  INTEGER (0..127)
+        ACCESS  read-only
+        STATUS  mandatory
+        ::= { system 7 }
+
+
+-- the Interfaces group
+
+ifNumber OBJECT-TYPE
+        SYNTAX  INTEGER
+        ACCESS  read-only
+        STATUS  mandatory
+        ::= { interfaces 1 }
+
+-- the Interfaces table
+
+ifTable OBJECT-TYPE
+        SYNTAX  SEQUENCE OF IfEntry
+        ACCESS  read-only
+        STATUS  mandatory
+        ::= { interfaces 2 }
+
+ifEntry OBJECT-TYPE
+        SYNTAX  IfEntry
+        ACCESS  read-only
+        STATUS  mandatory
+        ::= { ifTable 1 }
+
+IfEntry ::= SEQUENCE {
+    ifIndex
+        INTEGER,
+    ifDescr
+        DisplayString,
+    ifType
+        INTEGER,
+    ifMtu
+        INTEGER,
+    ifSpeed
+        Gauge,
+    ifPhysAddress
+        OCTET STRING,
+    ifAdminStatus
+        INTEGER,
+    ifOperStatus
+        INTEGER,
+    ifLastChange
+        TimeTicks,
+    ifInOctets
+        Counter,
+    ifInUcastPkts
+        Counter,
+    ifInNUcastPkts
+        Counter,
+    ifInDiscards
+        Counter,
+    ifInErrors
+        Counter,
+    ifInUnknownProtos
+        Counter,
+    ifOutOctets
+        Counter,
+    ifOutUcastPkts
+        Counter,
+    ifOutNUcastPkts
+        Counter,
+    ifOutDiscards
+        Counter,
+    ifOutErrors
+        Counter,
+    ifOutQLen
+        Gauge,
+    ifSpecific
+        OBJECT IDENTIFIER
+}
+
+ifIndex OBJECT-TYPE
+        SYNTAX  INTEGER
+        ACCESS  read-only
+        STATUS  mandatory
+        ::= { ifEntry 1 }
+
+ifDescr OBJECT-TYPE
+        SYNTAX  DisplayString (SIZE (0..255))
+        ACCESS  read-only
+        STATUS  mandatory
+        ::= { ifEntry 2 }
+
+ifType OBJECT-TYPE
+        SYNTAX  INTEGER {
+                    other(1),             -- none of the
+                                          -- following
+                    regular1822(2),
+                    hdh1822(3),
+                    ddn-x25(4),
+                    rfc877-x25(5),
+                    ethernet-csmacd(6),
+                    iso88023-csmacd(7),
+                    iso88024-tokenBus(8),
+                    iso88025-tokenRing(9),
+                    iso88026-man(10),
+                    starLan(11),
+                    proteon-10Mbit(12),
+                    proteon-80Mbit(13),
+                    hyperchannel(14),
+                    fddi(15),
+                    lapb(16),
+                    sdlc(17),
+                    t1-carrier(18),
+                    cept(19),        -- european
+                                     --equivalent of T-1
+                    basicISDN(20),
+                    primaryISDN(21),
+                                          -- proprietary
+                                          -- serial
+                    propPointToPointSerial(22),
+                    terminalServer-asyncPort(23),
+                    softwareLoopback(24),
+                    eon(25),              -- CLNP over IP
+                    ethernet-3Mbit(26),
+                    nsip(27),             -- XNS over IP
+                    slip(28)              -- generic SLIP
+            }
+        ACCESS  read-only
+        STATUS  mandatory
+        ::= { ifEntry 3 }
+
+ifMtu OBJECT-TYPE
+        SYNTAX  INTEGER
+        ACCESS  read-only
+        STATUS  mandatory
+        ::= { ifEntry 4 }
+
+ifSpeed OBJECT-TYPE
+        SYNTAX  Gauge
+        ACCESS  read-only
+        STATUS  mandatory
+        ::= { ifEntry 5 }
+
+ifPhysAddress OBJECT-TYPE
+        SYNTAX  OCTET STRING
+        ACCESS  read-only
+        STATUS  mandatory
+        ::= { ifEntry 6 }
+
+ifAdminStatus OBJECT-TYPE
+        SYNTAX  INTEGER {
+                    up(1),     -- ready to pass packets
+                    down(2),
+                    testing(3) -- in some test mode
+                }
+        ACCESS  read-write
+        STATUS  mandatory
+        ::= { ifEntry 7 }
+
+ifOperStatus OBJECT-TYPE
+        SYNTAX  INTEGER {
+                    up(1),     -- ready to pass packets
+                    down(2),
+                    testing(3) -- in some test mode
+                }
+        ACCESS  read-only
+        STATUS  mandatory
+        ::= { ifEntry 8 }
+
+ifLastChange OBJECT-TYPE
+        SYNTAX  TimeTicks
+        ACCESS  read-only
+        STATUS  mandatory
+        ::= { ifEntry 9 }
+
+ifInOctets OBJECT-TYPE
+        SYNTAX  Counter
+        ACCESS  read-only
+        STATUS  mandatory
+        ::= { ifEntry 10 }
+
+ifInUcastPkts OBJECT-TYPE
+        SYNTAX  Counter
+        ACCESS  read-only
+        STATUS  mandatory
+        ::=  { ifEntry 11 }
+
+ifInNUcastPkts OBJECT-TYPE
+        SYNTAX  Counter
+        ACCESS  read-only
+        STATUS  mandatory
+        ::= { ifEntry 12 }
+
+ifInDiscards OBJECT-TYPE
+        SYNTAX  Counter
+        ACCESS  read-only
+        STATUS  mandatory
+        ::= { ifEntry 13 }
+
+ifInErrors OBJECT-TYPE
+        SYNTAX  Counter
+        ACCESS  read-only
+        STATUS  mandatory
+        ::= { ifEntry 14 }
+
+ifInUnknownProtos OBJECT-TYPE
+        SYNTAX  Counter
+        ACCESS  read-only
+        STATUS  mandatory
+        ::= { ifEntry 15 }
+
+ifOutOctets OBJECT-TYPE
+        SYNTAX  Counter
+        ACCESS  read-only
+        STATUS  mandatory
+        ::= { ifEntry 16 }
+
+ifOutUcastPkts OBJECT-TYPE
+        SYNTAX  Counter
+        ACCESS  read-only
+        STATUS  mandatory
+        ::= { ifEntry 17 }
+
+ifOutNUcastPkts OBJECT-TYPE
+        SYNTAX  Counter
+        ACCESS  read-only
+        STATUS  mandatory
+        ::= { ifEntry 18 }
+
+ifOutDiscards OBJECT-TYPE
+        SYNTAX  Counter
+        ACCESS  read-only
+        STATUS  mandatory
+        ::= { ifEntry 19 }
+
+ifOutErrors OBJECT-TYPE
+        SYNTAX  Counter
+        ACCESS  read-only
+        STATUS  mandatory
+        ::= { ifEntry 20 }
+
+ifOutQLen OBJECT-TYPE
+        SYNTAX  Gauge
+        ACCESS  read-only
+        STATUS  mandatory
+        ::= { ifEntry 21 }
+
+ifSpecific OBJECT-TYPE
+        SYNTAX  OBJECT IDENTIFIER
+        ACCESS  read-only
+        STATUS  mandatory
+        ::= { ifEntry 22 }
+
+nullSpecific OBJECT IDENTIFIER ::= { 0 0 }
+
+-- the Address Translation group (deprecated)
+
+atTable OBJECT-TYPE
+        SYNTAX  SEQUENCE OF AtEntry
+        ACCESS  read-write
+        STATUS  deprecated
+        ::= { at 1 }
+
+atEntry OBJECT-TYPE
+        SYNTAX  AtEntry
+        ACCESS  read-write
+        STATUS  deprecated
+        ::= { atTable 1 }
+
+AtEntry ::= SEQUENCE {
+    atIfIndex
+        INTEGER,
+    atPhysAddress
+        OCTET STRING,
+    atNetAddress
+        NetworkAddress
+}
+
+atIfIndex OBJECT-TYPE
+        SYNTAX  INTEGER
+        ACCESS  read-write
+        STATUS  deprecated
+        ::= { atEntry 1 }
+
+atPhysAddress OBJECT-TYPE
+        SYNTAX  OCTET STRING
+        ACCESS  read-write
+        STATUS  deprecated
+        ::= { atEntry 2 }
+
+atNetAddress OBJECT-TYPE
+        SYNTAX  NetworkAddress
+        ACCESS  read-write
+        STATUS  deprecated
+        ::= { atEntry 3 }
+
+
+-- the IP group
+
+ipForwarding OBJECT-TYPE
+        SYNTAX  INTEGER {
+                    gateway(1), -- entity forwards
+                                -- datagrams
+                    host(2)     -- entity does NOT
+                                -- forward datagrams
+                }
+        ACCESS  read-write
+        STATUS  mandatory
+        ::= { ip 1 }
+
+ipDefaultTTL OBJECT-TYPE
+        SYNTAX  INTEGER
+        ACCESS  read-write
+        STATUS  mandatory
+        ::= { ip 2 }
+
+ipInReceives OBJECT-TYPE
+        SYNTAX  Counter
+        ACCESS  read-only
+        STATUS  mandatory
+        ::= { ip 3 }
+
+ipInHdrErrors OBJECT-TYPE
+        SYNTAX  Counter
+        ACCESS  read-only
+        STATUS  mandatory
+        ::= { ip 4 }
+
+ipInAddrErrors OBJECT-TYPE
+        SYNTAX  Counter
+        ACCESS  read-only
+        STATUS  mandatory
+        ::= { ip 5 }
+
+ipForwDatagrams OBJECT-TYPE
+        SYNTAX  Counter
+        ACCESS  read-only
+        STATUS  mandatory
+        ::= { ip 6 }
+
+ipInUnknownProtos OBJECT-TYPE
+        SYNTAX  Counter
+        ACCESS  read-only
+        STATUS  mandatory
+        ::= { ip 7 }
+
+ipInDiscards OBJECT-TYPE
+        SYNTAX  Counter
+        ACCESS  read-only
+        STATUS  mandatory
+        ::= { ip 8 }
+
+ipInDelivers OBJECT-TYPE
+        SYNTAX  Counter
+        ACCESS  read-only
+        STATUS  mandatory
+        ::= { ip 9 }
+
+ipOutRequests OBJECT-TYPE
+        SYNTAX  Counter
+        ACCESS  read-only
+        STATUS  mandatory
+        ::= { ip 10 }
+
+ipOutDiscards OBJECT-TYPE
+        SYNTAX  Counter
+        ACCESS  read-only
+        STATUS  mandatory
+        ::= { ip 11 }
+
+ipOutNoRoutes OBJECT-TYPE
+        SYNTAX  Counter
+        ACCESS  read-only
+        STATUS  mandatory
+        ::= { ip 12 }
+
+ipReasmTimeout OBJECT-TYPE
+        SYNTAX  INTEGER
+        ACCESS  read-only
+        STATUS  mandatory
+        ::= { ip 13 }
+
+ipReasmReqds OBJECT-TYPE
+        SYNTAX  Counter
+        ACCESS  read-only
+        STATUS  mandatory
+        ::= { ip 14 }
+
+ipReasmOKs OBJECT-TYPE
+        SYNTAX  Counter
+        ACCESS  read-only
+        STATUS  mandatory
+        ::= { ip 15 }
+
+ipReasmFails OBJECT-TYPE
+        SYNTAX  Counter
+        ACCESS  read-only
+        STATUS  mandatory
+        ::= { ip 16 }
+
+ipFragOKs OBJECT-TYPE
+        SYNTAX  Counter
+        ACCESS  read-only
+        STATUS  mandatory
+        ::= { ip 17 }
+
+ipFragFails OBJECT-TYPE
+        SYNTAX  Counter
+        ACCESS  read-only
+        STATUS  mandatory
+        ::= { ip 18 }
+
+ipFragCreates OBJECT-TYPE
+        SYNTAX  Counter
+        ACCESS  read-only
+        STATUS  mandatory
+        ::= { ip 19 }
+
+-- the IP Interface table
+
+ipAddrTable OBJECT-TYPE
+        SYNTAX  SEQUENCE OF IpAddrEntry
+        ACCESS  read-only
+        STATUS  mandatory
+        ::= { ip 20 }
+
+ipAddrEntry OBJECT-TYPE
+        SYNTAX  IpAddrEntry
+        ACCESS  read-only
+        STATUS  mandatory
+        ::= { ipAddrTable 1 }
+
+IpAddrEntry ::= SEQUENCE {
+    ipAdEntAddr
+        IpAddress,
+    ipAdEntIfIndex
+        INTEGER,
+    ipAdEntNetMask
+        IpAddress,
+    ipAdEntBcastAddr
+        INTEGER,
+    ipAdEntReasmMaxSize
+        INTEGER (0..65535)
+}
+
+ipAdEntAddr OBJECT-TYPE
+        SYNTAX  IpAddress
+        ACCESS  read-only
+        STATUS  mandatory
+        ::=  { ipAddrEntry 1 }
+
+ipAdEntIfIndex OBJECT-TYPE
+        SYNTAX  INTEGER
+        ACCESS  read-only
+        STATUS  mandatory
+        ::=  { ipAddrEntry 2 }
+
+ipAdEntNetMask OBJECT-TYPE
+        SYNTAX  IpAddress
+        ACCESS  read-only
+        STATUS  mandatory
+        ::=  { ipAddrEntry 3 }
+
+ipAdEntBcastAddr OBJECT-TYPE
+        SYNTAX  INTEGER
+        ACCESS  read-only
+        STATUS  mandatory
+        ::= { ipAddrEntry 4 }
+
+ipAdEntReasmMaxSize OBJECT-TYPE
+        SYNTAX  INTEGER (0..65535)
+        ACCESS  read-only
+        STATUS  mandatory
+        ::= { ipAddrEntry 5 }
+
+-- the IP Routing table
+
+ipRoutingTable OBJECT-TYPE
+        SYNTAX  SEQUENCE OF IpRouteEntry
+        ACCESS  read-write
+        STATUS  mandatory
+        ::= { ip 21 }
+
+ipRouteEntry OBJECT-TYPE
+        SYNTAX  IpRouteEntry
+        ACCESS  read-write
+        STATUS  mandatory
+        ::= { ipRoutingTable 1 }
+
+IpRouteEntry ::= SEQUENCE {
+    ipRouteDest
+        IpAddress,
+    ipRouteIfIndex
+        INTEGER,
+    ipRouteMetric1
+        INTEGER,
+    ipRouteMetric2
+        INTEGER,
+    ipRouteMetric3
+        INTEGER,
+    ipRouteMetric4
+        INTEGER,
+    ipRouteNextHop
+        IpAddress,
+    ipRouteType
+        INTEGER,
+    ipRouteProto
+        INTEGER,
+    ipRouteAge
+        INTEGER,
+    ipRouteMask
+        IpAddress
+}
+
+ipRouteDest OBJECT-TYPE
+        SYNTAX  IpAddress
+        ACCESS  read-write
+        STATUS  mandatory
+        ::= { ipRouteEntry 1 }
+
+ipRouteIfIndex  OBJECT-TYPE
+        SYNTAX  INTEGER
+        ACCESS  read-write
+        STATUS  mandatory
+        ::= { ipRouteEntry 2 }
+
+ipRouteMetric1 OBJECT-TYPE
+        SYNTAX  INTEGER
+        ACCESS  read-write
+        STATUS  mandatory
+        ::= { ipRouteEntry 3 }
+
+ipRouteMetric2 OBJECT-TYPE
+        SYNTAX  INTEGER
+        ACCESS  read-write
+        STATUS  mandatory
+        ::= { ipRouteEntry 4 }
+
+ipRouteMetric3 OBJECT-TYPE
+        SYNTAX  INTEGER
+        ACCESS  read-write
+        STATUS  mandatory
+        ::= { ipRouteEntry 5 }
+
+ipRouteMetric4 OBJECT-TYPE
+        SYNTAX  INTEGER
+        ACCESS  read-write
+        STATUS  mandatory
+        ::= { ipRouteEntry 6 }
+
+ipRouteNextHop OBJECT-TYPE
+        SYNTAX  IpAddress
+        ACCESS  read-write
+        STATUS  mandatory
+        ::= { ipRouteEntry 7 }
+
+ipRouteType OBJECT-TYPE
+        SYNTAX  INTEGER {
+                    other(1),    -- none of the following
+
+                    invalid(2),  -- an invalidated route
+
+                                 -- route to directly
+                    direct(3),   -- connected
+                                 -- (sub-)network
+
+                                 -- route to a non-local
+                    remote(4)    -- host/network/
+                                 -- sub-network
+            }
+        ACCESS  read-write
+        STATUS  mandatory
+        ::= { ipRouteEntry 8 }
+
+ipRouteProto OBJECT-TYPE
+        SYNTAX  INTEGER {
+                    other(1),    -- none of the following
+
+                                 -- non-protocol
+                                 -- information
+
+                                 --   e.g., manually
+                    local(2),    --   configured entries
+
+                                 -- set via a network
+                    netmgmt(3),  --   management protocol
+
+                                 -- obtained via ICMP,
+                    icmp(4),     --   e.g., Redirect
+
+                                 -- the following are
+                                 -- gateway routing
+                                 -- protocols
+                    egp(5),
+                    ggp(6),
+                    hello(7),
+                    rip(8),
+                    is-is(9),
+                    es-is(10),
+                    ciscoIgrp(11),
+                    bbnSpfIgp(12),
+                    ospf(13),
+                    bgp(14)
+            }
+        ACCESS  read-only
+        STATUS  mandatory
+        ::= { ipRouteEntry 9 }
+
+ipRouteAge OBJECT-TYPE
+        SYNTAX  INTEGER
+        ACCESS  read-write
+        STATUS  mandatory
+        ::= { ipRouteEntry 10 }
+
+ipRouteMask OBJECT-TYPE
+        SYNTAX  IpAddress
+        ACCESS  read-write
+        STATUS  mandatory
+        ::= { ipRouteEntry 11 }
+
+-- the IP Address Translation tables
+
+ipNetToMediaTable OBJECT-TYPE
+        SYNTAX  SEQUENCE OF IpNetToMediaEntry
+        ACCESS  read-write
+        STATUS  mandatory
+        ::= { ip 22 }
+
+ipNetToMediaEntry OBJECT-TYPE
+        SYNTAX  IpNetToMediaEntry
+        ACCESS  read-write
+        STATUS  mandatory
+        ::= { ipNetToMediaTable 1 }
+
+IpNetToMediaEntry ::= SEQUENCE {
+    ipNetToMediaIfIndex
+        INTEGER,
+    ipNetToMediaPhysAddress
+        OCTET STRING,
+    ipNetToMediaNetAddress
+        IpAddress,
+    ipNetToMediaType
+        INTEGER
+}
+
+ipNetToMediaIfIndex OBJECT-TYPE
+        SYNTAX  INTEGER
+        ACCESS  read-write
+        STATUS  mandatory
+        ::= { ipNetToMediaEntry 1 }
+
+ipNetToMediaPhysAddress OBJECT-TYPE
+        SYNTAX  OCTET STRING
+        ACCESS  read-write
+        STATUS  mandatory
+        ::= { ipNetToMediaEntry 2 }
+
+ipNetToMediaNetAddress OBJECT-TYPE
+        SYNTAX  IpAddress
+        ACCESS  read-write
+        STATUS  mandatory
+        ::= { ipNetToMediaEntry 3 }
+
+ipNetToMediaType OBJECT-TYPE
+        SYNTAX  INTEGER {
+                    other(1),   -- none of the following
+
+                    invalid(2), -- an invalidated mapping
+                    dynamic(3), -- connected (sub-)network
+
+                    static(4)
+            }
+        ACCESS  read-write
+        STATUS  mandatory
+        ::= { ipNetToMediaEntry 4 }
+
+-- the ICMP group
+
+icmpInMsgs OBJECT-TYPE
+        SYNTAX  Counter
+        ACCESS  read-only
+        STATUS  mandatory
+        ::= { icmp 1 }
+
+icmpInErrors OBJECT-TYPE
+        SYNTAX  Counter
+        ACCESS  read-only
+        STATUS  mandatory
+        ::= { icmp 2 }
+
+icmpInDestUnreachs OBJECT-TYPE
+        SYNTAX  Counter
+        ACCESS  read-only
+        STATUS  mandatory
+        ::= { icmp 3 }
+
+icmpInTimeExcds OBJECT-TYPE
+        SYNTAX  Counter
+        ACCESS  read-only
+        STATUS  mandatory
+        ::= { icmp 4 }
+
+icmpInParmProbs OBJECT-TYPE
+        SYNTAX  Counter
+        ACCESS  read-only
+        STATUS  mandatory
+        ::= { icmp 5 }
+
+icmpInSrcQuenchs OBJECT-TYPE
+        SYNTAX  Counter
+        ACCESS  read-only
+        STATUS  mandatory
+        ::= { icmp 6 }
+
+icmpInRedirects OBJECT-TYPE
+        SYNTAX  Counter
+        ACCESS  read-only
+        STATUS  mandatory
+        ::= { icmp 7 }
+
+icmpInEchos OBJECT-TYPE
+        SYNTAX  Counter
+        ACCESS  read-only
+        STATUS  mandatory
+        ::= { icmp 8 }
+
+icmpInEchoReps OBJECT-TYPE
+        SYNTAX  Counter
+        ACCESS  read-only
+        STATUS  mandatory
+        ::= { icmp 9 }
+
+icmpInTimestamps OBJECT-TYPE
+        SYNTAX  Counter
+        ACCESS  read-only
+        STATUS  mandatory
+        ::= { icmp 10 }
+
+icmpInTimestampReps OBJECT-TYPE
+        SYNTAX  Counter
+        ACCESS  read-only
+        STATUS  mandatory
+        ::= { icmp 11 }
+
+icmpInAddrMasks OBJECT-TYPE
+        SYNTAX  Counter
+        ACCESS  read-only
+        STATUS  mandatory
+        ::= { icmp 12 }
+
+icmpInAddrMaskReps OBJECT-TYPE
+        SYNTAX  Counter
+        ACCESS  read-only
+        STATUS  mandatory
+        ::= { icmp 13 }
+
+icmpOutMsgs OBJECT-TYPE
+        SYNTAX  Counter
+        ACCESS  read-only
+        STATUS  mandatory
+        ::= { icmp 14 }
+
+icmpOutErrors OBJECT-TYPE
+        SYNTAX  Counter
+        ACCESS  read-only
+        STATUS  mandatory
+        ::= { icmp 15 }
+
+icmpOutDestUnreachs OBJECT-TYPE
+        SYNTAX  Counter
+        ACCESS  read-only
+        STATUS  mandatory
+        ::= { icmp 16 }
+
+icmpOutTimeExcds OBJECT-TYPE
+        SYNTAX  Counter
+        ACCESS  read-only
+        STATUS  mandatory
+        ::= { icmp 17 }
+
+icmpOutParmProbs OBJECT-TYPE
+        SYNTAX  Counter
+        ACCESS  read-only
+        STATUS  mandatory
+        ::= { icmp 18 }
+
+icmpOutSrcQuenchs OBJECT-TYPE
+        SYNTAX  Counter
+        ACCESS  read-only
+        STATUS  mandatory
+        ::= { icmp 19 }
+
+icmpOutRedirects OBJECT-TYPE
+        SYNTAX  Counter
+        ACCESS  read-only
+        STATUS  mandatory
+        ::= { icmp 20 }
+
+icmpOutEchos OBJECT-TYPE
+        SYNTAX  Counter
+        ACCESS  read-only
+        STATUS  mandatory
+        ::= { icmp 21 }
+
+icmpOutEchoReps OBJECT-TYPE
+        SYNTAX  Counter
+        ACCESS  read-only
+        STATUS  mandatory
+        ::= { icmp 22 }
+
+icmpOutTimestamps OBJECT-TYPE
+        SYNTAX  Counter
+        ACCESS  read-only
+        STATUS  mandatory
+        ::= { icmp 23 }
+
+icmpOutTimestampReps OBJECT-TYPE
+        SYNTAX  Counter
+        ACCESS  read-only
+        STATUS  mandatory
+        ::= { icmp 24 }
+
+icmpOutAddrMasks OBJECT-TYPE
+        SYNTAX  Counter
+        ACCESS  read-only
+        STATUS  mandatory
+        ::= { icmp 25 }
+
+icmpOutAddrMaskReps OBJECT-TYPE
+        SYNTAX  Counter
+        ACCESS  read-only
+        STATUS  mandatory
+        ::= { icmp 26 }
+
+
+-- the TCP group
+
+tcpRtoAlgorithm OBJECT-TYPE
+        SYNTAX  INTEGER {
+                    other(1),    -- none of the following
+                    constant(2), -- a constant rto
+                    rsre(3),     -- MIL-STD-1778,
+                                 -- Appendix B
+                    vanj(4)      -- Van Jacobson's
+                                 -- algorithm
+                }
+        ACCESS  read-only
+        STATUS  mandatory
+        ::= { tcp 1 }
+
+tcpRtoMin OBJECT-TYPE
+        SYNTAX  INTEGER
+        ACCESS  read-only
+        STATUS  mandatory
+        ::= { tcp 2 }
+
+tcpRtoMax OBJECT-TYPE
+        SYNTAX  INTEGER
+        ACCESS  read-only
+        STATUS  mandatory
+        ::= { tcp 3 }
+
+tcpMaxConn OBJECT-TYPE
+        SYNTAX  INTEGER
+        ACCESS  read-only
+        STATUS  mandatory
+        ::= { tcp 4 }
+
+tcpActiveOpens OBJECT-TYPE
+        SYNTAX  Counter
+        ACCESS  read-only
+        STATUS  mandatory
+        ::= { tcp 5 }
+
+tcpPassiveOpens OBJECT-TYPE
+        SYNTAX  Counter
+        ACCESS  read-only
+        STATUS  mandatory
+        ::= { tcp 6 }
+
+tcpAttemptFails OBJECT-TYPE
+        SYNTAX  Counter
+        ACCESS  read-only
+        STATUS  mandatory
+        ::= { tcp 7 }
+
+tcpEstabResets OBJECT-TYPE
+        SYNTAX  Counter
+        ACCESS  read-only
+        STATUS  mandatory
+        ::= { tcp 8 }
+
+tcpCurrEstab OBJECT-TYPE
+        SYNTAX  Gauge
+        ACCESS  read-only
+        STATUS  mandatory
+        ::= { tcp 9 }
+
+tcpInSegs OBJECT-TYPE
+        SYNTAX  Counter
+        ACCESS  read-only
+        STATUS  mandatory
+        ::= { tcp 10 }
+
+tcpOutSegs OBJECT-TYPE
+        SYNTAX  Counter
+        ACCESS  read-only
+        STATUS  mandatory
+        ::= { tcp 11 }
+
+tcpRetransSegs OBJECT-TYPE
+        SYNTAX  Counter
+        ACCESS  read-only
+        STATUS  mandatory
+        ::= { tcp 12 }
+
+-- the TCP connections table
+
+tcpConnTable OBJECT-TYPE
+        SYNTAX  SEQUENCE OF TcpConnEntry
+        ACCESS  read-only
+        STATUS  mandatory
+        ::= { tcp 13 }
+
+tcpConnEntry OBJECT-TYPE
+        SYNTAX  TcpConnEntry
+        ACCESS  read-only
+        STATUS  mandatory
+        ::= { tcpConnTable 1 }
+
+TcpConnEntry ::= SEQUENCE {
+    tcpConnState
+        INTEGER,
+    tcpConnLocalAddress
+        IpAddress,
+    tcpConnLocalPort
+        INTEGER (0..65535),
+    tcpConnRemAddress
+        IpAddress,
+    tcpConnRemPort
+        INTEGER (0..65535)
+}
+
+tcpConnState OBJECT-TYPE
+        SYNTAX  INTEGER {
+                    closed(1),
+                    listen(2),
+                    synSent(3),
+                    synReceived(4),
+                    established(5),
+                    finWait1(6),
+                    finWait2(7),
+                    closeWait(8),
+                    lastAck(9),
+                    closing(10),
+                    timeWait(11)
+                }
+        ACCESS  read-only
+        STATUS  mandatory
+        ::= { tcpConnEntry 1 }
+
+tcpConnLocalAddress OBJECT-TYPE
+        SYNTAX  IpAddress
+        ACCESS  read-only
+        STATUS  mandatory
+        ::= { tcpConnEntry 2 }
+
+tcpConnLocalPort OBJECT-TYPE
+        SYNTAX  INTEGER (0..65535)
+        ACCESS  read-only
+        STATUS  mandatory
+        ::= { tcpConnEntry 3 }
+
+tcpConnRemAddress OBJECT-TYPE
+        SYNTAX  IpAddress
+        ACCESS  read-only
+        STATUS  mandatory
+        ::= { tcpConnEntry 4 }
+
+tcpConnRemPort OBJECT-TYPE
+        SYNTAX  INTEGER (0..65535)
+        ACCESS  read-only
+        STATUS  mandatory
+        ::= { tcpConnEntry 5 }
+
+-- additional TCP variables
+
+tcpInErrs OBJECT-TYPE
+        SYNTAX  Counter
+        ACCESS  read-only
+        STATUS  mandatory
+        ::= { tcp 14 }
+
+tcpOutRsts OBJECT-TYPE
+        SYNTAX  Counter
+        ACCESS  read-only
+        STATUS  mandatory
+        ::= { tcp 15 }
+
+
+-- the UDP group
+
+udpInDatagrams OBJECT-TYPE
+        SYNTAX  Counter
+        ACCESS  read-only
+        STATUS  mandatory
+        ::= { udp 1 }
+
+udpNoPorts OBJECT-TYPE
+        SYNTAX  Counter
+        ACCESS  read-only
+        STATUS  mandatory
+        ::= { udp 2 }
+
+udpInErrors OBJECT-TYPE
+        SYNTAX  Counter
+        ACCESS  read-only
+        STATUS  mandatory
+        ::= { udp 3 }
+
+udpOutDatagrams OBJECT-TYPE
+        SYNTAX  Counter
+        ACCESS  read-only
+        STATUS  mandatory
+        ::= { udp 4 }
+
+-- the UDP listener table
+
+udpTable OBJECT-TYPE
+        SYNTAX  SEQUENCE OF UdpEntry
+        ACCESS  read-only
+        STATUS  mandatory
+        ::= { udp 5 }
+
+udpEntry OBJECT-TYPE
+        SYNTAX  UdpEntry
+        ACCESS  read-only
+        STATUS  mandatory
+        ::= { udpTable 1 }
+
+UdpEntry ::= SEQUENCE {
+    udpLocalAddress
+        IpAddress,
+    udpLocalPort
+        INTEGER (0..65535)
+}
+
+udpLocalAddress OBJECT-TYPE
+        SYNTAX  IpAddress
+        ACCESS  read-only
+        STATUS  mandatory
+        ::= { udpEntry 1 }
+
+udpLocalPort OBJECT-TYPE
+        SYNTAX  INTEGER (0..65535)
+        ACCESS  read-only
+        STATUS  mandatory
+        ::= { udpEntry 2 }
+
+-- the EGP group
+
+egpInMsgs OBJECT-TYPE
+        SYNTAX  Counter
+        ACCESS  read-only
+        STATUS  mandatory
+        ::= { egp 1 }
+
+egpInErrors OBJECT-TYPE
+        SYNTAX  Counter
+        ACCESS  read-only
+        STATUS  mandatory
+        ::= { egp 2 }
+
+egpOutMsgs OBJECT-TYPE
+        SYNTAX  Counter
+        ACCESS  read-only
+        STATUS  mandatory
+        ::= { egp 3 }
+
+egpOutErrors OBJECT-TYPE
+        SYNTAX  Counter
+        ACCESS  read-only
+        STATUS  mandatory
+        ::= { egp 4 }
+
+-- the EGP Neighbor table
+
+egpNeighTable OBJECT-TYPE
+        SYNTAX  SEQUENCE OF EgpNeighEntry
+        ACCESS  read-only
+        STATUS  mandatory
+        ::= { egp 5 }
+
+egpNeighEntry OBJECT-TYPE
+        SYNTAX  EgpNeighEntry
+        ACCESS  read-only
+        STATUS  mandatory
+        ::= { egpNeighTable 1 }
+
+EgpNeighEntry ::= SEQUENCE {
+    egpNeighState
+        INTEGER,
+    egpNeighAddr
+        IpAddress,
+    egpNeighAs
+        INTEGER,
+    egpNeighInMsgs
+        Counter,
+    egpNeighInErrs
+        Counter,
+    egpNeighOutMsgs
+        Counter,
+    egpNeighOutErrs
+        Counter,
+    egpNeighInErrMsgs
+        Counter,
+    egpNeighOutErrMsgs
+        Counter,
+    egpNeighStateUps
+        Counter,
+    egpNeighStateDowns
+        Counter,
+    egpNeighIntervalHello
+        INTEGER,
+    egpNeighIntervalPoll
+        INTEGER,
+    egpNeighMode
+        INTEGER,
+    egpNeighEventTrigger
+        INTEGER
+}
+
+egpNeighState OBJECT-TYPE
+        SYNTAX  INTEGER {
+                    idle(1),
+                    acquisition(2),
+                    down(3),
+                    up(4),
+                    cease(5)
+                }
+        ACCESS  read-only
+        STATUS  mandatory
+        ::= { egpNeighEntry 1 }
+
+egpNeighAddr OBJECT-TYPE
+        SYNTAX  IpAddress
+        ACCESS  read-only
+        STATUS  mandatory
+        ::= { egpNeighEntry 2 }
+
+egpNeighAs OBJECT-TYPE
+        SYNTAX  INTEGER
+        ACCESS  read-only
+        STATUS  mandatory
+        ::= { egpNeighEntry 3 }
+
+egpNeighInMsgs OBJECT-TYPE
+        SYNTAX  Counter
+        ACCESS  read-only
+        STATUS  mandatory
+        ::= { egpNeighEntry 4 }
+
+egpNeighInErrs OBJECT-TYPE
+        SYNTAX  Counter
+        ACCESS  read-only
+        STATUS  mandatory
+        ::= { egpNeighEntry 5 }
+
+egpNeighOutMsgs OBJECT-TYPE
+        SYNTAX  Counter
+        ACCESS  read-only
+        STATUS  mandatory
+        ::= { egpNeighEntry 6 }
+
+egpNeighOutErrs OBJECT-TYPE
+        SYNTAX  Counter
+        ACCESS  read-only
+        STATUS  mandatory
+        ::= { egpNeighEntry 7 }
+
+egpNeighInErrMsgs OBJECT-TYPE
+        SYNTAX  Counter
+        ACCESS  read-only
+        STATUS  mandatory
+        ::= { egpNeighEntry 8 }
+
+egpNeighOutErrMsgs OBJECT-TYPE
+        SYNTAX  Counter
+        ACCESS  read-only
+        STATUS  mandatory
+        ::= { egpNeighEntry 9 }
+
+egpNeighStateUps OBJECT-TYPE
+        SYNTAX  Counter
+        ACCESS  read-only
+        STATUS  mandatory
+        ::= { egpNeighEntry 10 }
+
+egpNeighStateDowns OBJECT-TYPE
+        SYNTAX  Counter
+        ACCESS  read-only
+        STATUS  mandatory
+        ::= { egpNeighEntry 11 }
+
+egpNeighIntervalHello OBJECT-TYPE
+        SYNTAX  INTEGER
+        ACCESS  read-only
+        STATUS  mandatory
+        ::= { egpNeighEntry 12 }
+
+egpNeighIntervalPoll OBJECT-TYPE
+        SYNTAX  INTEGER
+        ACCESS  read-only
+        STATUS  mandatory
+        ::= { egpNeighEntry 13 }
+
+egpNeighMode OBJECT-TYPE
+        SYNTAX  INTEGER {
+                    active(1),
+                    passive(2)
+                }
+        ACCESS  read-only
+        STATUS  mandatory
+        ::= { egpNeighEntry 14 }
+
+egpNeighEventTrigger OBJECT-TYPE
+        SYNTAX  INTEGER {
+                    start(1),
+                    stop(2)
+                }
+        ACCESS  read-write
+        STATUS  mandatory
+        ::= { egpNeighEntry 15 }
+
+-- additional EGP variables
+
+egpAs OBJECT-TYPE
+        SYNTAX  INTEGER
+        ACCESS  read-only
+        STATUS  mandatory
+        ::= { egp 6 }
+
+
+-- the Transmission group (empty at present)
+
+-- the SNMP group
+
+snmpInPkts OBJECT-TYPE
+        SYNTAX  Counter
+        ACCESS  read-only
+        STATUS  mandatory
+        ::=  { snmp 1 }
+
+snmpOutPkts OBJECT-TYPE
+        SYNTAX  Counter
+        ACCESS  read-only
+        STATUS  mandatory
+        ::=  { snmp 2 }
+
+snmpInBadVersions OBJECT-TYPE
+        SYNTAX  Counter
+        ACCESS  read-only
+        STATUS  mandatory
+        ::=  { snmp 3 }
+
+snmpInBadCommunityNames OBJECT-TYPE
+        SYNTAX  Counter
+        ACCESS  read-only
+        STATUS  mandatory
+        ::=  { snmp 4 }
+
+snmpInBadCommunityUses OBJECT-TYPE
+        SYNTAX  Counter
+        ACCESS  read-only
+        STATUS  mandatory
+        ::=  { snmp 5 }
+
+snmpInASNParseErrs OBJECT-TYPE
+        SYNTAX  Counter
+        ACCESS  read-only
+        STATUS  mandatory
+        ::=  { snmp 6 }
+
+snmpInBadTypes OBJECT-TYPE
+        SYNTAX  Counter
+        ACCESS  read-only
+        STATUS  mandatory
+        ::=  { snmp 7 }
+
+snmpInTooBigs OBJECT-TYPE
+        SYNTAX  Counter
+        ACCESS  read-only
+        STATUS  mandatory
+        ::=  { snmp 8 }
+
+snmpInNoSuchNames OBJECT-TYPE
+        SYNTAX  Counter
+        ACCESS  read-only
+        STATUS  mandatory
+        ::=  { snmp 9 }
+
+snmpInBadValues OBJECT-TYPE
+        SYNTAX  Counter
+        ACCESS  read-only
+        STATUS  mandatory
+        ::=  { snmp 10 }
+
+snmpInReadOnlys OBJECT-TYPE
+        SYNTAX  Counter
+        ACCESS  read-only
+        STATUS  mandatory
+        ::=  { snmp 11 }
+
+snmpInGenErrs OBJECT-TYPE
+        SYNTAX  Counter
+        ACCESS  read-only
+        STATUS  mandatory
+        ::=  { snmp 12 }
+
+snmpInTotalReqVars OBJECT-TYPE
+        SYNTAX  Counter
+        ACCESS  read-only
+        STATUS  mandatory
+        ::=  { snmp 13 }
+
+snmpInTotalSetVars OBJECT-TYPE
+        SYNTAX  Counter
+        ACCESS  read-only
+        STATUS  mandatory
+        ::=  { snmp 14 }
+
+snmpInGetRequests OBJECT-TYPE
+        SYNTAX  Counter
+        ACCESS  read-only
+        STATUS  mandatory
+        ::=  { snmp 15 }
+
+snmpInGetNexts OBJECT-TYPE
+        SYNTAX  Counter
+        ACCESS  read-only
+        STATUS  mandatory
+        ::=  { snmp 16 }
+
+snmpInSetRequests OBJECT-TYPE
+        SYNTAX  Counter
+        ACCESS  read-only
+        STATUS  mandatory
+        ::=  { snmp 17 }
+
+snmpInGetResponses OBJECT-TYPE
+        SYNTAX  Counter
+        ACCESS  read-only
+        STATUS  mandatory
+        ::=  { snmp 18 }
+
+snmpInTraps OBJECT-TYPE
+        SYNTAX  Counter
+        ACCESS  read-only
+        STATUS  mandatory
+        ::=  { snmp 19 }
+
+snmpOutTooBigs OBJECT-TYPE
+        SYNTAX  Counter
+        ACCESS  read-only
+        STATUS  mandatory
+        ::=  { snmp 20 }
+
+snmpOutNoSuchNames OBJECT-TYPE
+        SYNTAX  Counter
+        ACCESS  read-only
+        STATUS  mandatory
+        ::=  { snmp 21 }
+
+snmpOutBadValues OBJECT-TYPE
+        SYNTAX  Counter
+        ACCESS  read-only
+        STATUS  mandatory
+        ::=  { snmp 22 }
+
+snmpOutReadOnlys OBJECT-TYPE
+        SYNTAX  Counter
+        ACCESS  read-only
+        STATUS  mandatory
+        ::=  { snmp 23 }
+
+snmpOutGenErrs OBJECT-TYPE
+        SYNTAX  Counter
+        ACCESS  read-only
+        STATUS  mandatory
+        ::=  { snmp 24 }
+
+snmpOutGetRequests OBJECT-TYPE
+        SYNTAX  Counter
+        ACCESS  read-only
+        STATUS  mandatory
+        ::=  { snmp 25 }
+
+snmpOutGetNexts OBJECT-TYPE
+        SYNTAX  Counter
+        ACCESS  read-only
+        STATUS  mandatory
+        ::=  { snmp 26 }
+
+snmpOutSetRequests OBJECT-TYPE
+        SYNTAX  Counter
+        ACCESS  read-only
+        STATUS  mandatory
+        ::=  { snmp 27 }
+
+snmpOutGetResponses OBJECT-TYPE
+        SYNTAX  Counter
+        ACCESS  read-only
+        STATUS  mandatory
+        ::=  { snmp 28 }
+
+snmpOutTraps OBJECT-TYPE
+        SYNTAX  Counter
+        ACCESS  read-only
+        STATUS  mandatory
+        ::=  { snmp 29 }
+
+snmpEnableAuthTraps OBJECT-TYPE
+        SYNTAX  INTEGER {
+                    enabled(1),
+                    disabled(2)
+                }
+        ACCESS  read-write
+        STATUS  mandatory
+        ::=  { snmp 30 }
+
+END
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/Mibs/RFC1213-MIB
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/Mibs/RFC1213-MIB	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/Mibs/RFC1213-MIB	(revision 457)
@@ -0,0 +1,2621 @@
+RFC1213-MIB DEFINITIONS ::= BEGIN
+
+IMPORTS
+        mgmt, NetworkAddress, IpAddress, Counter, Gauge,
+                TimeTicks
+            FROM RFC1155-SMI
+        OBJECT-TYPE
+                FROM RFC-1212;
+
+--  This MIB module uses the extended OBJECT-TYPE macro as
+--  defined in [14];
+
+
+--  MIB-II (same prefix as MIB-I)
+
+mib-2      OBJECT IDENTIFIER ::= { mgmt 1 }
+
+-- textual conventions
+
+DisplayString ::=
+    OCTET STRING
+-- This data type is used to model textual information taken
+-- from the NVT ASCII character set.  By convention, objects
+-- with this syntax are declared as having
+
+--
+--      SIZE (0..255)
+
+PhysAddress ::=
+    OCTET STRING
+-- This data type is used to model media addresses.  For many
+-- types of media, this will be in a binary representation.
+-- For example, an ethernet address would be represented as
+-- a string of 6 octets.
+
+
+-- groups in MIB-II
+
+system       OBJECT IDENTIFIER ::= { mib-2 1 }
+
+interfaces   OBJECT IDENTIFIER ::= { mib-2 2 }
+
+at           OBJECT IDENTIFIER ::= { mib-2 3 }
+
+ip           OBJECT IDENTIFIER ::= { mib-2 4 }
+
+icmp         OBJECT IDENTIFIER ::= { mib-2 5 }
+
+tcp          OBJECT IDENTIFIER ::= { mib-2 6 }
+
+udp          OBJECT IDENTIFIER ::= { mib-2 7 }
+
+egp          OBJECT IDENTIFIER ::= { mib-2 8 }
+
+-- historical (some say hysterical)
+-- cmot      OBJECT IDENTIFIER ::= { mib-2 9 }
+
+transmission OBJECT IDENTIFIER ::= { mib-2 10 }
+
+snmp         OBJECT IDENTIFIER ::= { mib-2 11 }
+
+
+-- the System group
+
+-- Implementation of the System group is mandatory for all
+-- systems.  If an agent is not configured to have a value
+-- for any of these variables, a string of length 0 is
+-- returned.
+
+sysDescr OBJECT-TYPE
+    SYNTAX  DisplayString (SIZE (0..255))
+    ACCESS  read-only
+    STATUS  mandatory
+    DESCRIPTION
+            "A textual description of the entity.  This value
+            should include the full name and version
+            identification of the system's hardware type,
+            software operating-system, and networking
+            software.  It is mandatory that this only contain
+            printable ASCII characters."
+    ::= { system 1 }
+
+sysObjectID OBJECT-TYPE
+    SYNTAX  OBJECT IDENTIFIER
+    ACCESS  read-only
+    STATUS  mandatory
+    DESCRIPTION
+            "The vendor's authoritative identification of the
+            network management subsystem contained in the
+            entity.  This value is allocated within the SMI
+            enterprises subtree (1.3.6.1.4.1) and provides an
+            easy and unambiguous means for determining `what
+            kind of box' is being managed.  For example, if
+            vendor `Flintstones, Inc.' was assigned the
+            subtree 1.3.6.1.4.1.4242, it could assign the
+            identifier 1.3.6.1.4.1.4242.1.1 to its `Fred
+            Router'."
+    ::= { system 2 }
+
+sysUpTime OBJECT-TYPE
+    SYNTAX  TimeTicks
+    ACCESS  read-only
+    STATUS  mandatory
+    DESCRIPTION
+            "The time (in hundredths of a second) since the
+            network management portion of the system was last
+            re-initialized."
+    ::= { system 3 }
+
+sysContact OBJECT-TYPE
+    SYNTAX  DisplayString (SIZE (0..255))
+    ACCESS  read-write
+    STATUS  mandatory
+    DESCRIPTION
+            "The textual identification of the contact person
+            for this managed node, together with information
+            on how to contact this person."
+    ::= { system 4 }
+
+sysName OBJECT-TYPE
+    SYNTAX  DisplayString (SIZE (0..255))
+    ACCESS  read-write
+    STATUS  mandatory
+    DESCRIPTION
+            "An administratively-assigned name for this
+            managed node.  By convention, this is the node's
+            fully-qualified domain name."
+    ::= { system 5 }
+
+sysLocation OBJECT-TYPE
+    SYNTAX  DisplayString (SIZE (0..255))
+    ACCESS  read-write
+    STATUS  mandatory
+    DESCRIPTION
+            "The physical location of this node (e.g.,
+            `telephone closet, 3rd floor')."
+    ::= { system 6 }
+
+sysServices OBJECT-TYPE
+    SYNTAX  INTEGER (0..127)
+    ACCESS  read-only
+    STATUS  mandatory
+    DESCRIPTION
+            "A value which indicates the set of services that
+            this entity primarily offers.
+
+            The value is a sum.  This sum initially takes the
+            value zero, Then, for each layer, L, in the range
+            1 through 7, that this node performs transactions
+            for, 2 raised to (L - 1) is added to the sum.  For
+            example, a node which performs primarily routing
+            functions would have a value of 4 (2^(3-1)).  In
+            contrast, a node which is a host offering
+            application services would have a value of 72
+            (2^(4-1) + 2^(7-1)).  Note that in the context of
+            the Internet suite of protocols, values should be
+            calculated accordingly:
+
+                 layer  functionality
+                     1  physical (e.g., repeaters)
+                     2  datalink/subnetwork (e.g., bridges)
+                     3  internet (e.g., IP gateways)
+                     4  end-to-end  (e.g., IP hosts)
+                     7  applications (e.g., mail relays)
+
+            For systems including OSI protocols, layers 5 and
+            6 may also be counted."
+    ::= { system 7 }
+
+-- the Interfaces group
+
+-- Implementation of the Interfaces group is mandatory for
+-- all systems.
+
+ifNumber OBJECT-TYPE
+    SYNTAX  INTEGER
+    ACCESS  read-only
+    STATUS  mandatory
+    DESCRIPTION
+            "The number of network interfaces (regardless of
+            their current state) present on this system."
+    ::= { interfaces 1 }
+
+
+-- the Interfaces table
+
+-- The Interfaces table contains information on the entity's
+-- interfaces.  Each interface is thought of as being
+-- attached to a `subnetwork'.  Note that this term should
+-- not be confused with `subnet' which refers to an
+-- addressing partitioning scheme used in the Internet suite
+-- of protocols.
+
+ifTable OBJECT-TYPE
+    SYNTAX  SEQUENCE OF IfEntry
+    ACCESS  not-accessible
+    STATUS  mandatory
+    DESCRIPTION
+            "A list of interface entries.  The number of
+            entries is given by the value of ifNumber."
+    ::= { interfaces 2 }
+
+ifEntry OBJECT-TYPE
+    SYNTAX  IfEntry
+    ACCESS  not-accessible
+    STATUS  mandatory
+    DESCRIPTION
+            "An interface entry containing objects at the
+            subnetwork layer and below for a particular
+            interface."
+    INDEX   { ifIndex }
+    ::= { ifTable 1 }
+
+IfEntry ::=
+    SEQUENCE {
+        ifIndex
+            INTEGER,
+        ifDescr
+            DisplayString,
+        ifType
+            INTEGER,
+        ifMtu
+            INTEGER,
+        ifSpeed
+            Gauge,
+        ifPhysAddress
+            PhysAddress,
+        ifAdminStatus
+            INTEGER,
+        ifOperStatus
+            INTEGER,
+        ifLastChange
+            TimeTicks,
+        ifInOctets
+            Counter,
+        ifInUcastPkts
+            Counter,
+        ifInNUcastPkts
+            Counter,
+        ifInDiscards
+            Counter,
+        ifInErrors
+            Counter,
+        ifInUnknownProtos
+            Counter,
+        ifOutOctets
+            Counter,
+        ifOutUcastPkts
+            Counter,
+        ifOutNUcastPkts
+            Counter,
+        ifOutDiscards
+            Counter,
+        ifOutErrors
+            Counter,
+        ifOutQLen
+            Gauge,
+        ifSpecific
+            OBJECT IDENTIFIER
+    }
+
+ifIndex OBJECT-TYPE
+    SYNTAX  INTEGER
+    ACCESS  read-only
+    STATUS  mandatory
+    DESCRIPTION
+            "A unique value for each interface.  Its value
+            ranges between 1 and the value of ifNumber.  The
+            value for each interface must remain constant at
+            least from one re-initialization of the entity's
+            network management system to the next re-
+            initialization."
+    ::= { ifEntry 1 }
+
+ifDescr OBJECT-TYPE
+    SYNTAX  DisplayString (SIZE (0..255))
+    ACCESS  read-only
+    STATUS  mandatory
+    DESCRIPTION
+            "A textual string containing information about the
+            interface.  This string should include the name of
+            the manufacturer, the product name and the version
+            of the hardware interface."
+    ::= { ifEntry 2 }
+
+ifType OBJECT-TYPE
+    SYNTAX  INTEGER {
+                other(1),          -- none of the following
+                regular1822(2),
+                hdh1822(3),
+                ddn-x25(4),
+                rfc877-x25(5),
+                ethernet-csmacd(6),
+                iso88023-csmacd(7),
+                iso88024-tokenBus(8),
+                iso88025-tokenRing(9),
+                iso88026-man(10),
+                starLan(11),
+                proteon-10Mbit(12),
+                proteon-80Mbit(13),
+                hyperchannel(14),
+                fddi(15),
+                lapb(16),
+                sdlc(17),
+                ds1(18),           -- T-1
+                e1(19),            -- european equiv. of T-1
+                basicISDN(20),
+                primaryISDN(21),   -- proprietary serial
+                propPointToPointSerial(22),
+                ppp(23),
+                softwareLoopback(24),
+                eon(25),            -- CLNP over IP [11]
+                ethernet-3Mbit(26),
+                nsip(27),           -- XNS over IP
+                slip(28),           -- generic SLIP
+                ultra(29),          -- ULTRA technologies
+                ds3(30),            -- T-3
+                sip(31),            -- SMDS
+                frame-relay(32)
+            }
+    ACCESS  read-only
+    STATUS  mandatory
+    DESCRIPTION
+            "The type of interface, distinguished according to
+            the physical/link protocol(s) immediately `below'
+            the network layer in the protocol stack."
+    ::= { ifEntry 3 }
+
+ifMtu OBJECT-TYPE
+    SYNTAX  INTEGER
+    ACCESS  read-only
+    STATUS  mandatory
+    DESCRIPTION
+            "The size of the largest datagram which can be
+            sent/received on the interface, specified in
+            octets.  For interfaces that are used for
+            transmitting network datagrams, this is the size
+            of the largest network datagram that can be sent
+            on the interface."
+    ::= { ifEntry 4 }
+
+ifSpeed OBJECT-TYPE
+    SYNTAX  Gauge
+    ACCESS  read-only
+    STATUS  mandatory
+    DESCRIPTION
+            "An estimate of the interface's current bandwidth
+            in bits per second.  For interfaces which do not
+            vary in bandwidth or for those where no accurate
+            estimation can be made, this object should contain
+            the nominal bandwidth."
+    ::= { ifEntry 5 }
+
+ifPhysAddress OBJECT-TYPE
+    SYNTAX  PhysAddress
+    ACCESS  read-only
+    STATUS  mandatory
+    DESCRIPTION
+            "The interface's address at the protocol layer
+            immediately `below' the network layer in the
+            protocol stack.  For interfaces which do not have
+            such an address (e.g., a serial line), this object
+            should contain an octet string of zero length."
+    ::= { ifEntry 6 }
+
+ifAdminStatus OBJECT-TYPE
+    SYNTAX  INTEGER {
+                up(1),       -- ready to pass packets
+                down(2),
+                testing(3)   -- in some test mode
+            }
+    ACCESS  read-write
+    STATUS  mandatory
+    DESCRIPTION
+            "The desired state of the interface.  The
+            testing(3) state indicates that no operational
+            packets can be passed."
+    ::= { ifEntry 7 }
+
+ifOperStatus OBJECT-TYPE
+    SYNTAX  INTEGER {
+                up(1),       -- ready to pass packets
+                down(2),
+                testing(3)   -- in some test mode
+            }
+    ACCESS  read-only
+    STATUS  mandatory
+    DESCRIPTION
+            "The current operational state of the interface.
+            The testing(3) state indicates that no operational
+            packets can be passed."
+    ::= { ifEntry 8 }
+
+ifLastChange OBJECT-TYPE
+    SYNTAX  TimeTicks
+    ACCESS  read-only
+    STATUS  mandatory
+    DESCRIPTION
+            "The value of sysUpTime at the time the interface
+            entered its current operational state.  If the
+            current state was entered prior to the last re-
+            initialization of the local network management
+            subsystem, then this object contains a zero
+            value."
+    ::= { ifEntry 9 }
+
+ifInOctets OBJECT-TYPE
+    SYNTAX  Counter
+    ACCESS  read-only
+    STATUS  mandatory
+    DESCRIPTION
+            "The total number of octets received on the
+            interface, including framing characters."
+    ::= { ifEntry 10 }
+
+ifInUcastPkts OBJECT-TYPE
+    SYNTAX  Counter
+    ACCESS  read-only
+    STATUS  mandatory
+    DESCRIPTION
+            "The number of subnetwork-unicast packets
+            delivered to a higher-layer protocol."
+    ::= { ifEntry 11 }
+
+ifInNUcastPkts OBJECT-TYPE
+    SYNTAX  Counter
+    ACCESS  read-only
+    STATUS  mandatory
+    DESCRIPTION
+            "The number of non-unicast (i.e., subnetwork-
+            broadcast or subnetwork-multicast) packets
+            delivered to a higher-layer protocol."
+    ::= { ifEntry 12 }
+
+ifInDiscards OBJECT-TYPE
+    SYNTAX  Counter
+    ACCESS  read-only
+    STATUS  mandatory
+    DESCRIPTION
+            "The number of inbound packets which were chosen
+            to be discarded even though no errors had been
+            detected to prevent their being deliverable to a
+            higher-layer protocol.  One possible reason for
+            discarding such a packet could be to free up
+            buffer space."
+    ::= { ifEntry 13 }
+
+ifInErrors OBJECT-TYPE
+    SYNTAX  Counter
+    ACCESS  read-only
+    STATUS  mandatory
+    DESCRIPTION
+            "The number of inbound packets that contained
+            errors preventing them from being deliverable to a
+            higher-layer protocol."
+    ::= { ifEntry 14 }
+
+ifInUnknownProtos OBJECT-TYPE
+    SYNTAX  Counter
+    ACCESS  read-only
+    STATUS  mandatory
+    DESCRIPTION
+            "The number of packets received via the interface
+            which were discarded because of an unknown or
+            unsupported protocol."
+    ::= { ifEntry 15 }
+
+ifOutOctets OBJECT-TYPE
+    SYNTAX  Counter
+    ACCESS  read-only
+    STATUS  mandatory
+    DESCRIPTION
+            "The total number of octets transmitted out of the
+            interface, including framing characters."
+    ::= { ifEntry 16 }
+
+ifOutUcastPkts OBJECT-TYPE
+    SYNTAX  Counter
+    ACCESS  read-only
+    STATUS  mandatory
+    DESCRIPTION
+            "The total number of packets that higher-level
+            protocols requested be transmitted to a
+            subnetwork-unicast address, including those that
+            were discarded or not sent."
+    ::= { ifEntry 17 }
+
+ifOutNUcastPkts OBJECT-TYPE
+    SYNTAX  Counter
+    ACCESS  read-only
+    STATUS  mandatory
+    DESCRIPTION
+            "The total number of packets that higher-level
+            protocols requested be transmitted to a non-
+            unicast (i.e., a subnetwork-broadcast or
+            subnetwork-multicast) address, including those
+            that were discarded or not sent."
+    ::= { ifEntry 18 }
+
+ifOutDiscards OBJECT-TYPE
+    SYNTAX  Counter
+    ACCESS  read-only
+    STATUS  mandatory
+    DESCRIPTION
+            "The number of outbound packets which were chosen
+            to be discarded even though no errors had been
+            detected to prevent their being transmitted.  One
+            possible reason for discarding such a packet could
+            be to free up buffer space."
+    ::= { ifEntry 19 }
+
+ifOutErrors OBJECT-TYPE
+    SYNTAX  Counter
+    ACCESS  read-only
+    STATUS  mandatory
+    DESCRIPTION
+            "The number of outbound packets that could not be
+            transmitted because of errors."
+    ::= { ifEntry 20 }
+
+ifOutQLen OBJECT-TYPE
+    SYNTAX  Gauge
+    ACCESS  read-only
+    STATUS  mandatory
+    DESCRIPTION
+            "The length of the output packet queue (in
+            packets)."
+    ::= { ifEntry 21 }
+
+ifSpecific OBJECT-TYPE
+    SYNTAX  OBJECT IDENTIFIER
+    ACCESS  read-only
+    STATUS  mandatory
+    DESCRIPTION
+            "A reference to MIB definitions specific to the
+            particular media being used to realize the
+            interface.  For example, if the interface is
+            realized by an ethernet, then the value of this
+            object refers to a document defining objects
+            specific to ethernet.  If this information is not
+            present, its value should be set to the OBJECT
+            IDENTIFIER { 0 0 }, which is a syntatically valid
+            object identifier, and any conformant
+            implementation of ASN.1 and BER must be able to
+            generate and recognize this value."
+    ::= { ifEntry 22 }
+
+
+-- the Address Translation group
+
+-- Implementation of the Address Translation group is
+-- mandatory for all systems.  Note however that this group
+-- is deprecated by MIB-II. That is, it is being included
+
+-- solely for compatibility with MIB-I nodes, and will most
+-- likely be excluded from MIB-III nodes.  From MIB-II and
+-- onwards, each network protocol group contains its own
+-- address translation tables.
+
+-- The Address Translation group contains one table which is
+-- the union across all interfaces of the translation tables
+-- for converting a NetworkAddress (e.g., an IP address) into
+-- a subnetwork-specific address.  For lack of a better term,
+-- this document refers to such a subnetwork-specific address
+-- as a `physical' address.
+
+-- Examples of such translation tables are: for broadcast
+-- media where ARP is in use, the translation table is
+-- equivalent to the ARP cache; or, on an X.25 network where
+-- non-algorithmic translation to X.121 addresses is
+-- required, the translation table contains the
+-- NetworkAddress to X.121 address equivalences.
+
+atTable OBJECT-TYPE
+    SYNTAX  SEQUENCE OF AtEntry
+    ACCESS  not-accessible
+    STATUS  deprecated
+    DESCRIPTION
+            "The Address Translation tables contain the
+            NetworkAddress to `physical' address equivalences.
+            Some interfaces do not use translation tables for
+            determining address equivalences (e.g., DDN-X.25
+            has an algorithmic method); if all interfaces are
+            of this type, then the Address Translation table
+            is empty, i.e., has zero entries."
+    ::= { at 1 }
+
+atEntry OBJECT-TYPE
+    SYNTAX  AtEntry
+    ACCESS  not-accessible
+    STATUS  deprecated
+    DESCRIPTION
+            "Each entry contains one NetworkAddress to
+            `physical' address equivalence."
+    INDEX   { atIfIndex,
+              atNetAddress }
+    ::= { atTable 1 }
+
+AtEntry ::=
+    SEQUENCE {
+        atIfIndex
+            INTEGER,
+        atPhysAddress
+            PhysAddress,
+        atNetAddress
+            NetworkAddress
+    }
+
+atIfIndex OBJECT-TYPE
+    SYNTAX  INTEGER
+    ACCESS  read-write
+    STATUS  deprecated
+    DESCRIPTION
+            "The interface on which this entry's equivalence
+            is effective.  The interface identified by a
+            particular value of this index is the same
+            interface as identified by the same value of
+            ifIndex."
+    ::= { atEntry 1 }
+
+atPhysAddress OBJECT-TYPE
+    SYNTAX  PhysAddress
+    ACCESS  read-write
+    STATUS  deprecated
+    DESCRIPTION
+            "The media-dependent `physical' address.
+
+            Setting this object to a null string (one of zero
+            length) has the effect of invaliding the
+            corresponding entry in the atTable object.  That
+            is, it effectively dissasociates the interface
+            identified with said entry from the mapping
+            identified with said entry.  It is an
+            implementation-specific matter as to whether the
+            agent removes an invalidated entry from the table.
+            Accordingly, management stations must be prepared
+            to receive tabular information from agents that
+            corresponds to entries not currently in use.
+            Proper interpretation of such entries requires
+            examination of the relevant atPhysAddress object."
+    ::= { atEntry 2 }
+
+atNetAddress OBJECT-TYPE
+    SYNTAX  NetworkAddress
+    ACCESS  read-write
+    STATUS  deprecated
+    DESCRIPTION
+            "The NetworkAddress (e.g., the IP address)
+            corresponding to the media-dependent `physical'
+            address."
+    ::= { atEntry 3 }
+
+
+-- the IP group
+
+-- Implementation of the IP group is mandatory for all
+-- systems.
+
+ipForwarding OBJECT-TYPE
+    SYNTAX  INTEGER {
+                forwarding(1),    -- acting as a gateway
+                not-forwarding(2) -- NOT acting as a gateway
+            }
+    ACCESS  read-write
+    STATUS  mandatory
+    DESCRIPTION
+            "The indication of whether this entity is acting
+            as an IP gateway in respect to the forwarding of
+            datagrams received by, but not addressed to, this
+            entity.  IP gateways forward datagrams.  IP hosts
+            do not (except those source-routed via the host).
+
+            Note that for some managed nodes, this object may
+            take on only a subset of the values possible.
+            Accordingly, it is appropriate for an agent to
+            return a `badValue' response if a management
+            station attempts to change this object to an
+            inappropriate value."
+    ::= { ip 1 }
+
+ipDefaultTTL OBJECT-TYPE
+    SYNTAX  INTEGER
+    ACCESS  read-write
+    STATUS  mandatory
+    DESCRIPTION
+            "The default value inserted into the Time-To-Live
+            field of the IP header of datagrams originated at
+            this entity, whenever a TTL value is not supplied
+            by the transport layer protocol."
+    ::= { ip 2 }
+
+ipInReceives OBJECT-TYPE
+    SYNTAX  Counter
+    ACCESS  read-only
+    STATUS  mandatory
+    DESCRIPTION
+            "The total number of input datagrams received from
+            interfaces, including those received in error."
+    ::= { ip 3 }
+
+ipInHdrErrors OBJECT-TYPE
+    SYNTAX  Counter
+    ACCESS  read-only
+    STATUS  mandatory
+    DESCRIPTION
+            "The number of input datagrams discarded due to
+            errors in their IP headers, including bad
+            checksums, version number mismatch, other format
+            errors, time-to-live exceeded, errors discovered
+            in processing their IP options, etc."
+    ::= { ip 4 }
+
+ipInAddrErrors OBJECT-TYPE
+    SYNTAX  Counter
+    ACCESS  read-only
+    STATUS  mandatory
+    DESCRIPTION
+            "The number of input datagrams discarded because
+            the IP address in their IP header's destination
+            field was not a valid address to be received at
+            this entity.  This count includes invalid
+            addresses (e.g., 0.0.0.0) and addresses of
+            unsupported Classes (e.g., Class E).  For entities
+            which are not IP Gateways and therefore do not
+            forward datagrams, this counter includes datagrams
+            discarded because the destination address was not
+            a local address."
+    ::= { ip 5 }
+
+ipForwDatagrams OBJECT-TYPE
+    SYNTAX  Counter
+    ACCESS  read-only
+    STATUS  mandatory
+    DESCRIPTION
+            "The number of input datagrams for which this
+            entity was not their final IP destination, as a
+            result of which an attempt was made to find a
+            route to forward them to that final destination.
+            In entities which do not act as IP Gateways, this
+            counter will include only those packets which were
+            Source-Routed via this entity, and the Source-
+            Route option processing was successful."
+    ::= { ip 6 }
+
+ipInUnknownProtos OBJECT-TYPE
+    SYNTAX  Counter
+    ACCESS  read-only
+    STATUS  mandatory
+    DESCRIPTION
+            "The number of locally-addressed datagrams
+            received successfully but discarded because of an
+            unknown or unsupported protocol."
+    ::= { ip 7 }
+
+ipInDiscards OBJECT-TYPE
+    SYNTAX  Counter
+    ACCESS  read-only
+    STATUS  mandatory
+    DESCRIPTION
+            "The number of input IP datagrams for which no
+            problems were encountered to prevent their
+            continued processing, but which were discarded
+            (e.g., for lack of buffer space).  Note that this
+            counter does not include any datagrams discarded
+            while awaiting re-assembly."
+    ::= { ip 8 }
+
+ipInDelivers OBJECT-TYPE
+    SYNTAX  Counter
+    ACCESS  read-only
+    STATUS  mandatory
+    DESCRIPTION
+            "The total number of input datagrams successfully
+            delivered to IP user-protocols (including ICMP)."
+    ::= { ip 9 }
+
+ipOutRequests OBJECT-TYPE
+    SYNTAX  Counter
+    ACCESS  read-only
+    STATUS  mandatory
+    DESCRIPTION
+            "The total number of IP datagrams which local IP
+            user-protocols (including ICMP) supplied to IP in
+            requests for transmission.  Note that this counter
+            does not include any datagrams counted in
+            ipForwDatagrams."
+    ::= { ip 10 }
+
+ipOutDiscards OBJECT-TYPE
+    SYNTAX  Counter
+    ACCESS  read-only
+    STATUS  mandatory
+    DESCRIPTION
+            "The number of output IP datagrams for which no
+            problem was encountered to prevent their
+            transmission to their destination, but which were
+            discarded (e.g., for lack of buffer space).  Note
+            that this counter would include datagrams counted
+            in ipForwDatagrams if any such packets met this
+            (discretionary) discard criterion."
+    ::= { ip 11 }
+
+ipOutNoRoutes OBJECT-TYPE
+    SYNTAX  Counter
+    ACCESS  read-only
+    STATUS  mandatory
+    DESCRIPTION
+            "The number of IP datagrams discarded because no
+            route could be found to transmit them to their
+            destination.  Note that this counter includes any
+            packets counted in ipForwDatagrams which meet this
+            `no-route' criterion.  Note that this includes any
+            datagarms which a host cannot route because all of
+            its default gateways are down."
+    ::= { ip 12 }
+
+ipReasmTimeout OBJECT-TYPE
+    SYNTAX  INTEGER
+    ACCESS  read-only
+    STATUS  mandatory
+    DESCRIPTION
+            "The maximum number of seconds which received
+            fragments are held while they are awaiting
+            reassembly at this entity."
+    ::= { ip 13 }
+
+ipReasmReqds OBJECT-TYPE
+    SYNTAX  Counter
+    ACCESS  read-only
+    STATUS  mandatory
+    DESCRIPTION
+            "The number of IP fragments received which needed
+            to be reassembled at this entity."
+    ::= { ip 14 }
+
+ipReasmOKs OBJECT-TYPE
+    SYNTAX  Counter
+    ACCESS  read-only
+    STATUS  mandatory
+    DESCRIPTION
+            "The number of IP datagrams successfully re-
+            assembled."
+    ::= { ip 15 }
+
+ipReasmFails OBJECT-TYPE
+    SYNTAX  Counter
+    ACCESS  read-only
+    STATUS  mandatory
+    DESCRIPTION
+            "The number of failures detected by the IP re-
+            assembly algorithm (for whatever reason: timed
+            out, errors, etc).  Note that this is not
+            necessarily a count of discarded IP fragments
+            since some algorithms (notably the algorithm in
+            RFC 815) can lose track of the number of fragments
+            by combining them as they are received."
+    ::= { ip 16 }
+
+ipFragOKs OBJECT-TYPE
+    SYNTAX  Counter
+    ACCESS  read-only
+    STATUS  mandatory
+    DESCRIPTION
+            "The number of IP datagrams that have been
+            successfully fragmented at this entity."
+    ::= { ip 17 }
+
+ipFragFails OBJECT-TYPE
+    SYNTAX  Counter
+    ACCESS  read-only
+    STATUS  mandatory
+    DESCRIPTION
+            "The number of IP datagrams that have been
+            discarded because they needed to be fragmented at
+            this entity but could not be, e.g., because their
+            Don't Fragment flag was set."
+    ::= { ip 18 }
+
+ipFragCreates OBJECT-TYPE
+    SYNTAX  Counter
+    ACCESS  read-only
+    STATUS  mandatory
+    DESCRIPTION
+            "The number of IP datagram fragments that have
+            been generated as a result of fragmentation at
+            this entity."
+    ::= { ip 19 }
+
+-- the IP address table
+
+-- The IP address table contains this entity's IP addressing
+-- information.
+
+ipAddrTable OBJECT-TYPE
+    SYNTAX  SEQUENCE OF IpAddrEntry
+    ACCESS  not-accessible
+    STATUS  mandatory
+    DESCRIPTION
+            "The table of addressing information relevant to
+            this entity's IP addresses."
+    ::= { ip 20 }
+
+ipAddrEntry OBJECT-TYPE
+    SYNTAX  IpAddrEntry
+    ACCESS  not-accessible
+    STATUS  mandatory
+    DESCRIPTION
+            "The addressing information for one of this
+            entity's IP addresses."
+    INDEX   { ipAdEntAddr }
+    ::= { ipAddrTable 1 }
+
+IpAddrEntry ::=
+    SEQUENCE {
+        ipAdEntAddr
+            IpAddress,
+        ipAdEntIfIndex
+            INTEGER,
+        ipAdEntNetMask
+            IpAddress,
+        ipAdEntBcastAddr
+            INTEGER,
+        ipAdEntReasmMaxSize
+            INTEGER (0..65535)
+    }
+
+ipAdEntAddr OBJECT-TYPE
+    SYNTAX  IpAddress
+    ACCESS  read-only
+    STATUS  mandatory
+    DESCRIPTION
+            "The IP address to which this entry's addressing
+            information pertains."
+    ::= { ipAddrEntry 1 }
+
+ipAdEntIfIndex OBJECT-TYPE
+    SYNTAX  INTEGER
+    ACCESS  read-only
+    STATUS  mandatory
+    DESCRIPTION
+            "The index value which uniquely identifies the
+            interface to which this entry is applicable.  The
+            interface identified by a particular value of this
+            index is the same interface as identified by the
+            same value of ifIndex."
+    ::= { ipAddrEntry 2 }
+
+ipAdEntNetMask OBJECT-TYPE
+    SYNTAX  IpAddress
+    ACCESS  read-only
+    STATUS  mandatory
+    DESCRIPTION
+            "The subnet mask associated with the IP address of
+            this entry.  The value of the mask is an IP
+            address with all the network bits set to 1 and all
+            the hosts bits set to 0."
+    ::= { ipAddrEntry 3 }
+
+ipAdEntBcastAddr OBJECT-TYPE
+    SYNTAX  INTEGER
+    ACCESS  read-only
+    STATUS  mandatory
+    DESCRIPTION
+            "The value of the least-significant bit in the IP
+            broadcast address used for sending datagrams on
+            the (logical) interface associated with the IP
+            address of this entry.  For example, when the
+            Internet standard all-ones broadcast address is
+            used, the value will be 1.  This value applies to
+            both the subnet and network broadcasts addresses
+            used by the entity on this (logical) interface."
+    ::= { ipAddrEntry 4 }
+
+ipAdEntReasmMaxSize OBJECT-TYPE
+    SYNTAX  INTEGER (0..65535)
+    ACCESS  read-only
+    STATUS  mandatory
+    DESCRIPTION
+            "The size of the largest IP datagram which this
+            entity can re-assemble from incoming IP fragmented
+            datagrams received on this interface."
+    ::= { ipAddrEntry 5 }
+
+-- the IP routing table
+
+-- The IP routing table contains an entry for each route
+-- presently known to this entity.
+
+ipRouteTable OBJECT-TYPE
+    SYNTAX  SEQUENCE OF IpRouteEntry
+    ACCESS  not-accessible
+    STATUS  mandatory
+    DESCRIPTION
+            "This entity's IP Routing table."
+    ::= { ip 21 }
+
+ipRouteEntry OBJECT-TYPE
+    SYNTAX  IpRouteEntry
+    ACCESS  not-accessible
+    STATUS  mandatory
+    DESCRIPTION
+            "A route to a particular destination."
+    INDEX   { ipRouteDest }
+    ::= { ipRouteTable 1 }
+
+IpRouteEntry ::=
+    SEQUENCE {
+        ipRouteDest
+            IpAddress,
+        ipRouteIfIndex
+            INTEGER,
+        ipRouteMetric1
+            INTEGER,
+        ipRouteMetric2
+            INTEGER,
+        ipRouteMetric3
+            INTEGER,
+        ipRouteMetric4
+            INTEGER,
+        ipRouteNextHop
+            IpAddress,
+        ipRouteType
+            INTEGER,
+        ipRouteProto
+            INTEGER,
+        ipRouteAge
+            INTEGER,
+        ipRouteMask
+            IpAddress,
+        ipRouteMetric5
+            INTEGER,
+        ipRouteInfo
+            OBJECT IDENTIFIER
+    }
+
+ipRouteDest OBJECT-TYPE
+    SYNTAX  IpAddress
+    ACCESS  read-write
+    STATUS  mandatory
+    DESCRIPTION
+            "The destination IP address of this route.  An
+            entry with a value of 0.0.0.0 is considered a
+            default route.  Multiple routes to a single
+            destination can appear in the table, but access to
+            such multiple entries is dependent on the table-
+            access mechanisms defined by the network
+            management protocol in use."
+    ::= { ipRouteEntry 1 }
+
+ipRouteIfIndex OBJECT-TYPE
+    SYNTAX  INTEGER
+    ACCESS  read-write
+    STATUS  mandatory
+    DESCRIPTION
+            "The index value which uniquely identifies the
+            local interface through which the next hop of this
+            route should be reached.  The interface identified
+            by a particular value of this index is the same
+            interface as identified by the same value of
+            ifIndex."
+    ::= { ipRouteEntry 2 }
+
+ipRouteMetric1 OBJECT-TYPE
+    SYNTAX  INTEGER
+    ACCESS  read-write
+    STATUS  mandatory
+    DESCRIPTION
+            "The primary routing metric for this route.  The
+            semantics of this metric are determined by the
+            routing-protocol specified in the route's
+            ipRouteProto value.  If this metric is not used,
+            its value should be set to -1."
+    ::= { ipRouteEntry 3 }
+
+ipRouteMetric2 OBJECT-TYPE
+    SYNTAX  INTEGER
+    ACCESS  read-write
+    STATUS  mandatory
+    DESCRIPTION
+            "An alternate routing metric for this route.  The
+            semantics of this metric are determined by the
+            routing-protocol specified in the route's
+            ipRouteProto value.  If this metric is not used,
+            its value should be set to -1."
+    ::= { ipRouteEntry 4 }
+
+ipRouteMetric3 OBJECT-TYPE
+    SYNTAX  INTEGER
+    ACCESS  read-write
+    STATUS  mandatory
+    DESCRIPTION
+            "An alternate routing metric for this route.  The
+            semantics of this metric are determined by the
+            routing-protocol specified in the route's
+            ipRouteProto value.  If this metric is not used,
+            its value should be set to -1."
+    ::= { ipRouteEntry 5 }
+
+ipRouteMetric4 OBJECT-TYPE
+    SYNTAX  INTEGER
+    ACCESS  read-write
+    STATUS  mandatory
+    DESCRIPTION
+            "An alternate routing metric for this route.  The
+            semantics of this metric are determined by the
+            routing-protocol specified in the route's
+            ipRouteProto value.  If this metric is not used,
+            its value should be set to -1."
+    ::= { ipRouteEntry 6 }
+
+ipRouteNextHop OBJECT-TYPE
+    SYNTAX  IpAddress
+    ACCESS  read-write
+    STATUS  mandatory
+    DESCRIPTION
+            "The IP address of the next hop of this route.
+            (In the case of a route bound to an interface
+            which is realized via a broadcast media, the value
+            of this field is the agent's IP address on that
+            interface.)"
+    ::= { ipRouteEntry 7 }
+
+ipRouteType OBJECT-TYPE
+    SYNTAX  INTEGER {
+                other(1),        -- none of the following
+
+                invalid(2),      -- an invalidated route
+
+                                 -- route to directly
+                direct(3),       -- connected (sub-)network
+
+                                 -- route to a non-local
+                indirect(4)      -- host/network/sub-network
+            }
+    ACCESS  read-write
+    STATUS  mandatory
+    DESCRIPTION
+            "The type of route.  Note that the values
+            direct(3) and indirect(4) refer to the notion of
+            direct and indirect routing in the IP
+            architecture.
+
+            Setting this object to the value invalid(2) has
+            the effect of invalidating the corresponding entry
+            in the ipRouteTable object.  That is, it
+            effectively dissasociates the destination
+            identified with said entry from the route
+            identified with said entry.  It is an
+            implementation-specific matter as to whether the
+            agent removes an invalidated entry from the table.
+            Accordingly, management stations must be prepared
+            to receive tabular information from agents that
+            corresponds to entries not currently in use.
+            Proper interpretation of such entries requires
+            examination of the relevant ipRouteType object."
+    ::= { ipRouteEntry 8 }
+
+ipRouteProto OBJECT-TYPE
+    SYNTAX  INTEGER {
+                other(1),       -- none of the following
+
+                                -- non-protocol information,
+                                -- e.g., manually configured
+                local(2),       -- entries
+
+                                -- set via a network
+                netmgmt(3),     -- management protocol
+
+                                -- obtained via ICMP,
+                icmp(4),        -- e.g., Redirect
+
+                                -- the remaining values are
+                                -- all gateway routing
+                                -- protocols
+                egp(5),
+                ggp(6),
+                hello(7),
+                rip(8),
+                is-is(9),
+                es-is(10),
+                ciscoIgrp(11),
+                bbnSpfIgp(12),
+                ospf(13),
+                bgp(14)
+            }
+    ACCESS  read-only
+    STATUS  mandatory
+    DESCRIPTION
+            "The routing mechanism via which this route was
+            learned.  Inclusion of values for gateway routing
+            protocols is not intended to imply that hosts
+            should support those protocols."
+    ::= { ipRouteEntry 9 }
+
+ipRouteAge OBJECT-TYPE
+    SYNTAX  INTEGER
+    ACCESS  read-write
+    STATUS  mandatory
+    DESCRIPTION
+            "The number of seconds since this route was last
+            updated or otherwise determined to be correct.
+            Note that no semantics of `too old' can be implied
+            except through knowledge of the routing protocol
+            by which the route was learned."
+    ::= { ipRouteEntry 10 }
+
+ipRouteMask OBJECT-TYPE
+    SYNTAX  IpAddress
+    ACCESS  read-write
+    STATUS  mandatory
+    DESCRIPTION
+            "Indicate the mask to be logical-ANDed with the
+            destination address before being compared to the
+            value in the ipRouteDest field.  For those systems
+            that do not support arbitrary subnet masks, an
+            agent constructs the value of the ipRouteMask by
+            determining whether the value of the correspondent
+            ipRouteDest field belong to a class-A, B, or C
+            network, and then using one of:
+
+                 mask           network
+                 255.0.0.0      class-A
+                 255.255.0.0    class-B
+                 255.255.255.0  class-C
+            If the value of the ipRouteDest is 0.0.0.0 (a
+            default route), then the mask value is also
+            0.0.0.0.  It should be noted that all IP routing
+            subsystems implicitly use this mechanism."
+    ::= { ipRouteEntry 11 }
+
+ipRouteMetric5 OBJECT-TYPE
+    SYNTAX  INTEGER
+    ACCESS  read-write
+    STATUS  mandatory
+    DESCRIPTION
+            "An alternate routing metric for this route.  The
+            semantics of this metric are determined by the
+            routing-protocol specified in the route's
+            ipRouteProto value.  If this metric is not used,
+            its value should be set to -1."
+    ::= { ipRouteEntry 12 }
+
+ipRouteInfo OBJECT-TYPE
+    SYNTAX  OBJECT IDENTIFIER
+    ACCESS  read-only
+    STATUS  mandatory
+    DESCRIPTION
+            "A reference to MIB definitions specific to the
+            particular routing protocol which is responsible
+            for this route, as determined by the value
+            specified in the route's ipRouteProto value.  If
+            this information is not present, its value should
+            be set to the OBJECT IDENTIFIER { 0 0 }, which is
+            a syntatically valid object identifier, and any
+            conformant implementation of ASN.1 and BER must be
+            able to generate and recognize this value."
+    ::= { ipRouteEntry 13 }
+
+
+-- the IP Address Translation table
+
+-- The IP address translation table contain the IpAddress to
+-- `physical' address equivalences.  Some interfaces do not
+-- use translation tables for determining address
+-- equivalences (e.g., DDN-X.25 has an algorithmic method);
+-- if all interfaces are of this type, then the Address
+-- Translation table is empty, i.e., has zero entries.
+
+ipNetToMediaTable OBJECT-TYPE
+    SYNTAX  SEQUENCE OF IpNetToMediaEntry
+    ACCESS  not-accessible
+    STATUS  mandatory
+    DESCRIPTION
+            "The IP Address Translation table used for mapping
+            from IP addresses to physical addresses."
+    ::= { ip 22 }
+
+ipNetToMediaEntry OBJECT-TYPE
+    SYNTAX  IpNetToMediaEntry
+    ACCESS  not-accessible
+    STATUS  mandatory
+    DESCRIPTION
+            "Each entry contains one IpAddress to `physical'
+            address equivalence."
+    INDEX   { ipNetToMediaIfIndex,
+              ipNetToMediaNetAddress }
+    ::= { ipNetToMediaTable 1 }
+
+IpNetToMediaEntry ::=
+    SEQUENCE {
+        ipNetToMediaIfIndex
+            INTEGER,
+        ipNetToMediaPhysAddress
+            PhysAddress,
+        ipNetToMediaNetAddress
+            IpAddress,
+        ipNetToMediaType
+            INTEGER
+    }
+
+ipNetToMediaIfIndex OBJECT-TYPE
+    SYNTAX  INTEGER
+    ACCESS  read-write
+    STATUS  mandatory
+    DESCRIPTION
+            "The interface on which this entry's equivalence
+            is effective.  The interface identified by a
+            particular value of this index is the same
+            interface as identified by the same value of
+            ifIndex."
+    ::= { ipNetToMediaEntry 1 }
+
+ipNetToMediaPhysAddress OBJECT-TYPE
+    SYNTAX  PhysAddress
+    ACCESS  read-write
+    STATUS  mandatory
+    DESCRIPTION
+            "The media-dependent `physical' address."
+    ::= { ipNetToMediaEntry 2 }
+
+ipNetToMediaNetAddress OBJECT-TYPE
+    SYNTAX  IpAddress
+    ACCESS  read-write
+    STATUS  mandatory
+    DESCRIPTION
+            "The IpAddress corresponding to the media-
+            dependent `physical' address."
+    ::= { ipNetToMediaEntry 3 }
+
+ipNetToMediaType OBJECT-TYPE
+    SYNTAX  INTEGER {
+                other(1),        -- none of the following
+                invalid(2),      -- an invalidated mapping
+                dynamic(3),
+                static(4)
+            }
+    ACCESS  read-write
+    STATUS  mandatory
+    DESCRIPTION
+            "The type of mapping.
+
+            Setting this object to the value invalid(2) has
+            the effect of invalidating the corresponding entry
+            in the ipNetToMediaTable.  That is, it effectively
+            dissasociates the interface identified with said
+            entry from the mapping identified with said entry.
+            It is an implementation-specific matter as to
+            whether the agent removes an invalidated entry
+            from the table.  Accordingly, management stations
+            must be prepared to receive tabular information
+            from agents that corresponds to entries not
+            currently in use.  Proper interpretation of such
+            entries requires examination of the relevant
+            ipNetToMediaType object."
+    ::= { ipNetToMediaEntry 4 }
+
+
+-- additional IP objects
+
+ipRoutingDiscards OBJECT-TYPE
+    SYNTAX  Counter
+    ACCESS  read-only
+    STATUS  mandatory
+    DESCRIPTION
+            "The number of routing entries which were chosen
+            to be discarded even though they are valid.  One
+            possible reason for discarding such an entry could
+            be to free-up buffer space for other routing
+            entries."
+    ::= { ip 23 }
+
+
+-- the ICMP group
+
+-- Implementation of the ICMP group is mandatory for all
+-- systems.
+
+icmpInMsgs OBJECT-TYPE
+    SYNTAX  Counter
+    ACCESS  read-only
+    STATUS  mandatory
+    DESCRIPTION
+            "The total number of ICMP messages which the
+            entity received.  Note that this counter includes
+            all those counted by icmpInErrors."
+    ::= { icmp 1 }
+
+icmpInErrors OBJECT-TYPE
+    SYNTAX  Counter
+    ACCESS  read-only
+    STATUS  mandatory
+    DESCRIPTION
+            "The number of ICMP messages which the entity
+            received but determined as having ICMP-specific
+            errors (bad ICMP checksums, bad length, etc.)."
+    ::= { icmp 2 }
+
+icmpInDestUnreachs OBJECT-TYPE
+    SYNTAX  Counter
+    ACCESS  read-only
+    STATUS  mandatory
+    DESCRIPTION
+            "The number of ICMP Destination Unreachable
+            messages received."
+    ::= { icmp 3 }
+
+icmpInTimeExcds OBJECT-TYPE
+    SYNTAX  Counter
+    ACCESS  read-only
+    STATUS  mandatory
+    DESCRIPTION
+            "The number of ICMP Time Exceeded messages
+            received."
+    ::= { icmp 4 }
+
+icmpInParmProbs OBJECT-TYPE
+    SYNTAX  Counter
+    ACCESS  read-only
+    STATUS  mandatory
+    DESCRIPTION
+            "The number of ICMP Parameter Problem messages
+            received."
+    ::= { icmp 5 }
+
+icmpInSrcQuenchs OBJECT-TYPE
+    SYNTAX  Counter
+    ACCESS  read-only
+    STATUS  mandatory
+    DESCRIPTION
+            "The number of ICMP Source Quench messages
+            received."
+    ::= { icmp 6 }
+
+icmpInRedirects OBJECT-TYPE
+    SYNTAX  Counter
+    ACCESS  read-only
+    STATUS  mandatory
+    DESCRIPTION
+            "The number of ICMP Redirect messages received."
+    ::= { icmp 7 }
+
+icmpInEchos OBJECT-TYPE
+    SYNTAX  Counter
+    ACCESS  read-only
+    STATUS  mandatory
+    DESCRIPTION
+            "The number of ICMP Echo (request) messages
+            received."
+    ::= { icmp 8 }
+
+icmpInEchoReps OBJECT-TYPE
+    SYNTAX  Counter
+    ACCESS  read-only
+    STATUS  mandatory
+    DESCRIPTION
+            "The number of ICMP Echo Reply messages received."
+    ::= { icmp 9 }
+
+icmpInTimestamps OBJECT-TYPE
+    SYNTAX  Counter
+    ACCESS  read-only
+    STATUS  mandatory
+    DESCRIPTION
+            "The number of ICMP Timestamp (request) messages
+            received."
+    ::= { icmp 10 }
+
+icmpInTimestampReps OBJECT-TYPE
+    SYNTAX  Counter
+    ACCESS  read-only
+    STATUS  mandatory
+    DESCRIPTION
+            "The number of ICMP Timestamp Reply messages
+            received."
+    ::= { icmp 11 }
+
+icmpInAddrMasks OBJECT-TYPE
+    SYNTAX  Counter
+    ACCESS  read-only
+    STATUS  mandatory
+    DESCRIPTION
+            "The number of ICMP Address Mask Request messages
+            received."
+    ::= { icmp 12 }
+
+icmpInAddrMaskReps OBJECT-TYPE
+    SYNTAX  Counter
+    ACCESS  read-only
+    STATUS  mandatory
+    DESCRIPTION
+            "The number of ICMP Address Mask Reply messages
+            received."
+    ::= { icmp 13 }
+
+icmpOutMsgs OBJECT-TYPE
+    SYNTAX  Counter
+    ACCESS  read-only
+    STATUS  mandatory
+    DESCRIPTION
+            "The total number of ICMP messages which this
+            entity attempted to send.  Note that this counter
+            includes all those counted by icmpOutErrors."
+    ::= { icmp 14 }
+
+icmpOutErrors OBJECT-TYPE
+    SYNTAX  Counter
+    ACCESS  read-only
+    STATUS  mandatory
+    DESCRIPTION
+            "The number of ICMP messages which this entity did
+            not send due to problems discovered within ICMP
+            such as a lack of buffers.  This value should not
+            include errors discovered outside the ICMP layer
+            such as the inability of IP to route the resultant
+            datagram.  In some implementations there may be no
+            types of error which contribute to this counter's
+            value."
+    ::= { icmp 15 }
+
+icmpOutDestUnreachs OBJECT-TYPE
+    SYNTAX  Counter
+    ACCESS  read-only
+    STATUS  mandatory
+    DESCRIPTION
+            "The number of ICMP Destination Unreachable
+            messages sent."
+    ::= { icmp 16 }
+
+icmpOutTimeExcds OBJECT-TYPE
+    SYNTAX  Counter
+    ACCESS  read-only
+    STATUS  mandatory
+    DESCRIPTION
+            "The number of ICMP Time Exceeded messages sent."
+    ::= { icmp 17 }
+
+icmpOutParmProbs OBJECT-TYPE
+    SYNTAX  Counter
+    ACCESS  read-only
+    STATUS  mandatory
+    DESCRIPTION
+            "The number of ICMP Parameter Problem messages
+            sent."
+    ::= { icmp 18 }
+
+icmpOutSrcQuenchs OBJECT-TYPE
+    SYNTAX  Counter
+    ACCESS  read-only
+    STATUS  mandatory
+    DESCRIPTION
+            "The number of ICMP Source Quench messages sent."
+    ::= { icmp 19 }
+
+icmpOutRedirects OBJECT-TYPE
+    SYNTAX  Counter
+    ACCESS  read-only
+    STATUS  mandatory
+    DESCRIPTION
+            "The number of ICMP Redirect messages sent.  For a
+            host, this object will always be zero, since hosts
+            do not send redirects."
+    ::= { icmp 20 }
+
+icmpOutEchos OBJECT-TYPE
+    SYNTAX  Counter
+    ACCESS  read-only
+    STATUS  mandatory
+    DESCRIPTION
+            "The number of ICMP Echo (request) messages sent."
+    ::= { icmp 21 }
+
+icmpOutEchoReps OBJECT-TYPE
+    SYNTAX  Counter
+    ACCESS  read-only
+    STATUS  mandatory
+    DESCRIPTION
+            "The number of ICMP Echo Reply messages sent."
+    ::= { icmp 22 }
+
+icmpOutTimestamps OBJECT-TYPE
+    SYNTAX  Counter
+    ACCESS  read-only
+    STATUS  mandatory
+    DESCRIPTION
+            "The number of ICMP Timestamp (request) messages
+            sent."
+    ::= { icmp 23 }
+
+icmpOutTimestampReps OBJECT-TYPE
+    SYNTAX  Counter
+    ACCESS  read-only
+    STATUS  mandatory
+    DESCRIPTION
+            "The number of ICMP Timestamp Reply messages
+            sent."
+    ::= { icmp 24 }
+
+icmpOutAddrMasks OBJECT-TYPE
+    SYNTAX  Counter
+    ACCESS  read-only
+    STATUS  mandatory
+    DESCRIPTION
+            "The number of ICMP Address Mask Request messages
+            sent."
+    ::= { icmp 25 }
+
+icmpOutAddrMaskReps OBJECT-TYPE
+    SYNTAX  Counter
+    ACCESS  read-only
+    STATUS  mandatory
+    DESCRIPTION
+            "The number of ICMP Address Mask Reply messages
+            sent."
+    ::= { icmp 26 }
+
+
+-- the TCP group
+
+-- Implementation of the TCP group is mandatory for all
+-- systems that implement the TCP.
+
+-- Note that instances of object types that represent
+-- information about a particular TCP connection are
+-- transient; they persist only as long as the connection
+-- in question.
+
+tcpRtoAlgorithm OBJECT-TYPE
+    SYNTAX  INTEGER {
+                other(1),    -- none of the following
+
+                constant(2), -- a constant rto
+                rsre(3),     -- MIL-STD-1778, Appendix B
+                vanj(4)      -- Van Jacobson's algorithm [10]
+            }
+    ACCESS  read-only
+    STATUS  mandatory
+    DESCRIPTION
+            "The algorithm used to determine the timeout value
+            used for retransmitting unacknowledged octets."
+    ::= { tcp 1 }
+
+tcpRtoMin OBJECT-TYPE
+    SYNTAX  INTEGER
+    ACCESS  read-only
+    STATUS  mandatory
+    DESCRIPTION
+            "The minimum value permitted by a TCP
+            implementation for the retransmission timeout,
+            measured in milliseconds.  More refined semantics
+            for objects of this type depend upon the algorithm
+            used to determine the retransmission timeout.  In
+            particular, when the timeout algorithm is rsre(3),
+            an object of this type has the semantics of the
+            LBOUND quantity described in RFC 793."
+    ::= { tcp 2 }
+
+
+tcpRtoMax OBJECT-TYPE
+    SYNTAX  INTEGER
+    ACCESS  read-only
+    STATUS  mandatory
+    DESCRIPTION
+            "The maximum value permitted by a TCP
+            implementation for the retransmission timeout,
+            measured in milliseconds.  More refined semantics
+            for objects of this type depend upon the algorithm
+            used to determine the retransmission timeout.  In
+            particular, when the timeout algorithm is rsre(3),
+            an object of this type has the semantics of the
+            UBOUND quantity described in RFC 793."
+    ::= { tcp 3 }
+
+tcpMaxConn OBJECT-TYPE
+    SYNTAX  INTEGER
+    ACCESS  read-only
+    STATUS  mandatory
+    DESCRIPTION
+            "The limit on the total number of TCP connections
+            the entity can support.  In entities where the
+            maximum number of connections is dynamic, this
+            object should contain the value -1."
+    ::= { tcp 4 }
+
+tcpActiveOpens OBJECT-TYPE
+    SYNTAX  Counter
+    ACCESS  read-only
+    STATUS  mandatory
+    DESCRIPTION
+            "The number of times TCP connections have made a
+            direct transition to the SYN-SENT state from the
+            CLOSED state."
+    ::= { tcp 5 }
+
+tcpPassiveOpens OBJECT-TYPE
+    SYNTAX  Counter
+    ACCESS  read-only
+    STATUS  mandatory
+    DESCRIPTION
+            "The number of times TCP connections have made a
+            direct transition to the SYN-RCVD state from the
+            LISTEN state."
+    ::= { tcp 6 }
+
+tcpAttemptFails OBJECT-TYPE
+    SYNTAX  Counter
+    ACCESS  read-only
+    STATUS  mandatory
+    DESCRIPTION
+            "The number of times TCP connections have made a
+            direct transition to the CLOSED state from either
+            the SYN-SENT state or the SYN-RCVD state, plus the
+            number of times TCP connections have made a direct
+            transition to the LISTEN state from the SYN-RCVD
+            state."
+    ::= { tcp 7 }
+
+tcpEstabResets OBJECT-TYPE
+    SYNTAX  Counter
+    ACCESS  read-only
+    STATUS  mandatory
+    DESCRIPTION
+            "The number of times TCP connections have made a
+            direct transition to the CLOSED state from either
+            the ESTABLISHED state or the CLOSE-WAIT state."
+    ::= { tcp 8 }
+
+tcpCurrEstab OBJECT-TYPE
+    SYNTAX  Gauge
+    ACCESS  read-only
+    STATUS  mandatory
+    DESCRIPTION
+            "The number of TCP connections for which the
+            current state is either ESTABLISHED or CLOSE-
+            WAIT."
+    ::= { tcp 9 }
+
+tcpInSegs OBJECT-TYPE
+    SYNTAX  Counter
+    ACCESS  read-only
+    STATUS  mandatory
+    DESCRIPTION
+            "The total number of segments received, including
+            those received in error.  This count includes
+            segments received on currently established
+            connections."
+    ::= { tcp 10 }
+
+tcpOutSegs OBJECT-TYPE
+    SYNTAX  Counter
+    ACCESS  read-only
+    STATUS  mandatory
+    DESCRIPTION
+            "The total number of segments sent, including
+            those on current connections but excluding those
+            containing only retransmitted octets."
+    ::= { tcp 11 }
+
+tcpRetransSegs OBJECT-TYPE
+    SYNTAX  Counter
+    ACCESS  read-only
+    STATUS  mandatory
+    DESCRIPTION
+            "The total number of segments retransmitted - that
+            is, the number of TCP segments transmitted
+            containing one or more previously transmitted
+            octets."
+    ::= { tcp 12 }
+
+
+-- the TCP Connection table
+
+-- The TCP connection table contains information about this
+-- entity's existing TCP connections.
+
+tcpConnTable OBJECT-TYPE
+    SYNTAX  SEQUENCE OF TcpConnEntry
+    ACCESS  not-accessible
+    STATUS  mandatory
+    DESCRIPTION
+            "A table containing TCP connection-specific
+            information."
+    ::= { tcp 13 }
+
+tcpConnEntry OBJECT-TYPE
+    SYNTAX  TcpConnEntry
+    ACCESS  not-accessible
+    STATUS  mandatory
+    DESCRIPTION
+            "Information about a particular current TCP
+            connection.  An object of this type is transient,
+            in that it ceases to exist when (or soon after)
+            the connection makes the transition to the CLOSED
+            state."
+    INDEX   { tcpConnLocalAddress,
+              tcpConnLocalPort,
+              tcpConnRemAddress,
+              tcpConnRemPort }
+    ::= { tcpConnTable 1 }
+
+TcpConnEntry ::=
+    SEQUENCE {
+        tcpConnState
+            INTEGER,
+        tcpConnLocalAddress
+            IpAddress,
+        tcpConnLocalPort
+            INTEGER (0..65535),
+        tcpConnRemAddress
+            IpAddress,
+        tcpConnRemPort
+            INTEGER (0..65535)
+    }
+
+tcpConnState OBJECT-TYPE
+    SYNTAX  INTEGER {
+                closed(1),
+                listen(2),
+                synSent(3),
+                synReceived(4),
+                established(5),
+                finWait1(6),
+                finWait2(7),
+                closeWait(8),
+                lastAck(9),
+                closing(10),
+                timeWait(11),
+                deleteTCB(12)
+            }
+    ACCESS  read-write
+    STATUS  mandatory
+    DESCRIPTION
+            "The state of this TCP connection.
+
+            The only value which may be set by a management
+            station is deleteTCB(12).  Accordingly, it is
+            appropriate for an agent to return a `badValue'
+            response if a management station attempts to set
+            this object to any other value.
+
+            If a management station sets this object to the
+            value deleteTCB(12), then this has the effect of
+            deleting the TCB (as defined in RFC 793) of the
+            corresponding connection on the managed node,
+            resulting in immediate termination of the
+            connection.
+
+            As an implementation-specific option, a RST
+            segment may be sent from the managed node to the
+            other TCP endpoint (note however that RST segments
+            are not sent reliably)."
+    ::= { tcpConnEntry 1 }
+
+tcpConnLocalAddress OBJECT-TYPE
+    SYNTAX  IpAddress
+    ACCESS  read-only
+    STATUS  mandatory
+    DESCRIPTION
+            "The local IP address for this TCP connection.  In
+            the case of a connection in the listen state which
+            is willing to accept connections for any IP
+            interface associated with the node, the value
+            0.0.0.0 is used."
+    ::= { tcpConnEntry 2 }
+
+tcpConnLocalPort OBJECT-TYPE
+    SYNTAX  INTEGER (0..65535)
+    ACCESS  read-only
+    STATUS  mandatory
+    DESCRIPTION
+            "The local port number for this TCP connection."
+    ::= { tcpConnEntry 3 }
+
+tcpConnRemAddress OBJECT-TYPE
+    SYNTAX  IpAddress
+    ACCESS  read-only
+    STATUS  mandatory
+    DESCRIPTION
+            "The remote IP address for this TCP connection."
+    ::= { tcpConnEntry 4 }
+
+tcpConnRemPort OBJECT-TYPE
+    SYNTAX  INTEGER (0..65535)
+    ACCESS  read-only
+    STATUS  mandatory
+    DESCRIPTION
+            "The remote port number for this TCP connection."
+    ::= { tcpConnEntry 5 }
+
+
+-- additional TCP objects
+
+tcpInErrs OBJECT-TYPE
+    SYNTAX  Counter
+    ACCESS  read-only
+    STATUS  mandatory
+    DESCRIPTION
+            "The total number of segments received in error
+            (e.g., bad TCP checksums)."
+    ::= { tcp 14 }
+
+tcpOutRsts OBJECT-TYPE
+    SYNTAX  Counter
+    ACCESS  read-only
+    STATUS  mandatory
+    DESCRIPTION
+            "The number of TCP segments sent containing the
+            RST flag."
+    ::= { tcp 15 }
+
+
+-- the UDP group
+
+-- Implementation of the UDP group is mandatory for all
+-- systems which implement the UDP.
+
+udpInDatagrams OBJECT-TYPE
+    SYNTAX  Counter
+    ACCESS  read-only
+    STATUS  mandatory
+    DESCRIPTION
+            "The total number of UDP datagrams delivered to
+            UDP users."
+    ::= { udp 1 }
+
+udpNoPorts OBJECT-TYPE
+    SYNTAX  Counter
+    ACCESS  read-only
+    STATUS  mandatory
+    DESCRIPTION
+            "The total number of received UDP datagrams for
+            which there was no application at the destination
+            port."
+    ::= { udp 2 }
+
+udpInErrors OBJECT-TYPE
+    SYNTAX  Counter
+    ACCESS  read-only
+    STATUS  mandatory
+    DESCRIPTION
+            "The number of received UDP datagrams that could
+            not be delivered for reasons other than the lack
+            of an application at the destination port."
+    ::= { udp 3 }
+
+udpOutDatagrams OBJECT-TYPE
+    SYNTAX  Counter
+    ACCESS  read-only
+    STATUS  mandatory
+    DESCRIPTION
+            "The total number of UDP datagrams sent from this
+            entity."
+    ::= { udp 4 }
+
+
+-- the UDP Listener table
+
+-- The UDP listener table contains information about this
+-- entity's UDP end-points on which a local application is
+-- currently accepting datagrams.
+
+udpTable OBJECT-TYPE
+    SYNTAX  SEQUENCE OF UdpEntry
+    ACCESS  not-accessible
+    STATUS  mandatory
+    DESCRIPTION
+            "A table containing UDP listener information."
+    ::= { udp 5 }
+
+udpEntry OBJECT-TYPE
+    SYNTAX  UdpEntry
+    ACCESS  not-accessible
+    STATUS  mandatory
+    DESCRIPTION
+            "Information about a particular current UDP
+            listener."
+    INDEX   { udpLocalAddress, udpLocalPort }
+    ::= { udpTable 1 }
+
+UdpEntry ::=
+    SEQUENCE {
+        udpLocalAddress
+            IpAddress,
+        udpLocalPort
+            INTEGER (0..65535)
+    }
+
+udpLocalAddress OBJECT-TYPE
+    SYNTAX  IpAddress
+    ACCESS  read-only
+    STATUS  mandatory
+    DESCRIPTION
+            "The local IP address for this UDP listener.  In
+            the case of a UDP listener which is willing to
+            accept datagrams for any IP interface associated
+            with the node, the value 0.0.0.0 is used."
+    ::= { udpEntry 1 }
+
+udpLocalPort OBJECT-TYPE
+    SYNTAX  INTEGER (0..65535)
+    ACCESS  read-only
+    STATUS  mandatory
+    DESCRIPTION
+            "The local port number for this UDP listener."
+    ::= { udpEntry 2 }
+
+
+-- the EGP group
+
+-- Implementation of the EGP group is mandatory for all
+-- systems which implement the EGP.
+
+egpInMsgs OBJECT-TYPE
+    SYNTAX  Counter
+    ACCESS  read-only
+    STATUS  mandatory
+    DESCRIPTION
+            "The number of EGP messages received without
+            error."
+    ::= { egp 1 }
+
+egpInErrors OBJECT-TYPE
+    SYNTAX  Counter
+    ACCESS  read-only
+    STATUS  mandatory
+    DESCRIPTION
+            "The number of EGP messages received that proved
+            to be in error."
+    ::= { egp 2 }
+
+egpOutMsgs OBJECT-TYPE
+    SYNTAX  Counter
+    ACCESS  read-only
+    STATUS  mandatory
+    DESCRIPTION
+            "The total number of locally generated EGP
+            messages."
+    ::= { egp 3 }
+
+egpOutErrors OBJECT-TYPE
+    SYNTAX  Counter
+    ACCESS  read-only
+    STATUS  mandatory
+    DESCRIPTION
+            "The number of locally generated EGP messages not
+            sent due to resource limitations within an EGP
+            entity."
+    ::= { egp 4 }
+
+
+-- the EGP Neighbor table
+
+-- The EGP neighbor table contains information about this
+-- entity's EGP neighbors.
+
+egpNeighTable OBJECT-TYPE
+    SYNTAX  SEQUENCE OF EgpNeighEntry
+    ACCESS  not-accessible
+    STATUS  mandatory
+    DESCRIPTION
+            "The EGP neighbor table."
+    ::= { egp 5 }
+
+egpNeighEntry OBJECT-TYPE
+    SYNTAX  EgpNeighEntry
+    ACCESS  not-accessible
+    STATUS  mandatory
+    DESCRIPTION
+            "Information about this entity's relationship with
+            a particular EGP neighbor."
+    INDEX   { egpNeighAddr }
+    ::= { egpNeighTable 1 }
+
+EgpNeighEntry ::=
+    SEQUENCE {
+        egpNeighState
+            INTEGER,
+        egpNeighAddr
+            IpAddress,
+        egpNeighAs
+            INTEGER,
+        egpNeighInMsgs
+            Counter,
+        egpNeighInErrs
+            Counter,
+        egpNeighOutMsgs
+            Counter,
+        egpNeighOutErrs
+            Counter,
+        egpNeighInErrMsgs
+            Counter,
+        egpNeighOutErrMsgs
+            Counter,
+        egpNeighStateUps
+            Counter,
+        egpNeighStateDowns
+            Counter,
+        egpNeighIntervalHello
+            INTEGER,
+        egpNeighIntervalPoll
+            INTEGER,
+        egpNeighMode
+            INTEGER,
+        egpNeighEventTrigger
+            INTEGER
+    }
+
+egpNeighState OBJECT-TYPE
+    SYNTAX  INTEGER {
+                idle(1),
+                acquisition(2),
+                down(3),
+                up(4),
+                cease(5)
+            }
+    ACCESS  read-only
+    STATUS  mandatory
+    DESCRIPTION
+            "The EGP state of the local system with respect to
+            this entry's EGP neighbor.  Each EGP state is
+            represented by a value that is one greater than
+            the numerical value associated with said state in
+            RFC 904."
+    ::= { egpNeighEntry 1 }
+
+egpNeighAddr OBJECT-TYPE
+    SYNTAX  IpAddress
+    ACCESS  read-only
+    STATUS  mandatory
+    DESCRIPTION
+            "The IP address of this entry's EGP neighbor."
+    ::= { egpNeighEntry 2 }
+
+egpNeighAs OBJECT-TYPE
+    SYNTAX  INTEGER
+    ACCESS  read-only
+    STATUS  mandatory
+    DESCRIPTION
+            "The autonomous system of this EGP peer.  Zero
+            should be specified if the autonomous system
+            number of the neighbor is not yet known."
+    ::= { egpNeighEntry 3 }
+
+egpNeighInMsgs OBJECT-TYPE
+    SYNTAX  Counter
+    ACCESS  read-only
+    STATUS  mandatory
+    DESCRIPTION
+            "The number of EGP messages received without error
+            from this EGP peer."
+    ::= { egpNeighEntry 4 }
+
+egpNeighInErrs OBJECT-TYPE
+    SYNTAX  Counter
+    ACCESS  read-only
+    STATUS  mandatory
+    DESCRIPTION
+            "The number of EGP messages received from this EGP
+            peer that proved to be in error (e.g., bad EGP
+            checksum)."
+    ::= { egpNeighEntry 5 }
+
+egpNeighOutMsgs OBJECT-TYPE
+    SYNTAX  Counter
+    ACCESS  read-only
+    STATUS  mandatory
+    DESCRIPTION
+            "The number of locally generated EGP messages to
+            this EGP peer."
+    ::= { egpNeighEntry 6 }
+
+egpNeighOutErrs OBJECT-TYPE
+    SYNTAX  Counter
+    ACCESS  read-only
+    STATUS  mandatory
+    DESCRIPTION
+            "The number of locally generated EGP messages not
+            sent to this EGP peer due to resource limitations
+            within an EGP entity."
+    ::= { egpNeighEntry 7 }
+
+egpNeighInErrMsgs OBJECT-TYPE
+    SYNTAX  Counter
+    ACCESS  read-only
+    STATUS  mandatory
+    DESCRIPTION
+            "The number of EGP-defined error messages received
+            from this EGP peer."
+    ::= { egpNeighEntry 8 }
+
+egpNeighOutErrMsgs OBJECT-TYPE
+    SYNTAX  Counter
+    ACCESS  read-only
+    STATUS  mandatory
+    DESCRIPTION
+            "The number of EGP-defined error messages sent to
+            this EGP peer."
+    ::= { egpNeighEntry 9 }
+
+egpNeighStateUps OBJECT-TYPE
+    SYNTAX  Counter
+    ACCESS  read-only
+    STATUS  mandatory
+    DESCRIPTION
+            "The number of EGP state transitions to the UP
+            state with this EGP peer."
+    ::= { egpNeighEntry 10 }
+
+egpNeighStateDowns OBJECT-TYPE
+    SYNTAX  Counter
+    ACCESS  read-only
+    STATUS  mandatory
+    DESCRIPTION
+            "The number of EGP state transitions from the UP
+            state to any other state with this EGP peer."
+    ::= { egpNeighEntry 11 }
+
+egpNeighIntervalHello OBJECT-TYPE
+    SYNTAX  INTEGER
+    ACCESS  read-only
+    STATUS  mandatory
+    DESCRIPTION
+            "The interval between EGP Hello command
+            retransmissions (in hundredths of a second).  This
+            represents the t1 timer as defined in RFC 904."
+    ::= { egpNeighEntry 12 }
+
+egpNeighIntervalPoll OBJECT-TYPE
+    SYNTAX  INTEGER
+    ACCESS  read-only
+    STATUS  mandatory
+    DESCRIPTION
+            "The interval between EGP poll command
+            retransmissions (in hundredths of a second).  This
+            represents the t3 timer as defined in RFC 904."
+    ::= { egpNeighEntry 13 }
+
+egpNeighMode OBJECT-TYPE
+    SYNTAX  INTEGER { active(1), passive(2) }
+    ACCESS  read-only
+    STATUS  mandatory
+    DESCRIPTION
+            "The polling mode of this EGP entity, either
+            passive or active."
+    ::= { egpNeighEntry 14 }
+
+egpNeighEventTrigger OBJECT-TYPE
+    SYNTAX  INTEGER { start(1), stop(2) }
+    ACCESS  read-write
+    STATUS  mandatory
+    DESCRIPTION
+            "A control variable used to trigger operator-
+            initiated Start and Stop events.  When read, this
+            variable always returns the most recent value that
+            egpNeighEventTrigger was set to.  If it has not
+            been set since the last initialization of the
+            network management subsystem on the node, it
+            returns a value of `stop'.
+
+            When set, this variable causes a Start or Stop
+            event on the specified neighbor, as specified on
+            pages 8-10 of RFC 904.  Briefly, a Start event
+            causes an Idle peer to begin neighbor acquisition
+            and a non-Idle peer to reinitiate neighbor
+            acquisition.  A stop event causes a non-Idle peer
+            to return to the Idle state until a Start event
+            occurs, either via egpNeighEventTrigger or
+            otherwise."
+    ::= { egpNeighEntry 15 }
+
+
+-- additional EGP objects
+
+egpAs OBJECT-TYPE
+    SYNTAX  INTEGER
+    ACCESS  read-only
+    STATUS  mandatory
+    DESCRIPTION
+            "The autonomous system number of this EGP entity."
+    ::= { egp 6 }
+
+-- the Transmission group
+
+-- Based on the transmission media underlying each interface
+-- on a system, the corresponding portion of the Transmission
+-- group is mandatory for that system.
+
+-- When Internet-standard definitions for managing
+-- transmission media are defined, the transmission group is
+-- used to provide a prefix for the names of those objects.
+
+-- Typically, such definitions reside in the experimental
+-- portion of the MIB until they are "proven", then as a
+-- part of the Internet standardization process, the
+-- definitions are accordingly elevated and a new object
+-- identifier, under the transmission group is defined. By
+-- convention, the name assigned is:
+--
+--     type OBJECT IDENTIFIER    ::= { transmission number }
+--
+-- where "type" is the symbolic value used for the media in
+-- the ifType column of the ifTable object, and "number" is
+-- the actual integer value corresponding to the symbol.
+
+
+-- the SNMP group
+
+-- Implementation of the SNMP group is mandatory for all
+-- systems which support an SNMP protocol entity.  Some of
+-- the objects defined below will be zero-valued in those
+-- SNMP implementations that are optimized to support only
+-- those functions specific to either a management agent or
+-- a management station.  In particular, it should be
+-- observed that the objects below refer to an SNMP entity,
+-- and there may be several SNMP entities residing on a
+-- managed node (e.g., if the node is hosting acting as
+-- a management station).
+
+snmpInPkts OBJECT-TYPE
+    SYNTAX  Counter
+    ACCESS  read-only
+    STATUS  mandatory
+    DESCRIPTION
+            "The total number of Messages delivered to the
+            SNMP entity from the transport service."
+    ::= { snmp 1 }
+
+snmpOutPkts OBJECT-TYPE
+    SYNTAX  Counter
+    ACCESS  read-only
+    STATUS  mandatory
+    DESCRIPTION
+            "The total number of SNMP Messages which were
+            passed from the SNMP protocol entity to the
+            transport service."
+    ::= { snmp 2 }
+
+snmpInBadVersions OBJECT-TYPE
+    SYNTAX  Counter
+    ACCESS  read-only
+    STATUS  mandatory
+    DESCRIPTION
+            "The total number of SNMP Messages which were
+            delivered to the SNMP protocol entity and were for
+            an unsupported SNMP version."
+    ::= { snmp 3 }
+
+snmpInBadCommunityNames OBJECT-TYPE
+    SYNTAX  Counter
+    ACCESS  read-only
+    STATUS  mandatory
+    DESCRIPTION
+            "The total number of SNMP Messages delivered to
+            the SNMP protocol entity which used a SNMP
+            community name not known to said entity."
+    ::= { snmp 4 }
+
+snmpInBadCommunityUses OBJECT-TYPE
+    SYNTAX  Counter
+    ACCESS  read-only
+    STATUS  mandatory
+    DESCRIPTION
+            "The total number of SNMP Messages delivered to
+            the SNMP protocol entity which represented an SNMP
+            operation which was not allowed by the SNMP
+            community named in the Message."
+    ::= { snmp 5 }
+
+snmpInASNParseErrs OBJECT-TYPE
+    SYNTAX  Counter
+    ACCESS  read-only
+    STATUS  mandatory
+    DESCRIPTION
+            "The total number of ASN.1 or BER errors
+            encountered by the SNMP protocol entity when
+            decoding received SNMP Messages."
+    ::= { snmp 6 }
+
+-- { snmp 7 } is not used
+
+snmpInTooBigs OBJECT-TYPE
+    SYNTAX  Counter
+    ACCESS  read-only
+    STATUS  mandatory
+    DESCRIPTION
+            "The total number of SNMP PDUs which were
+            delivered to the SNMP protocol entity and for
+            which the value of the error-status field is
+            `tooBig'."
+    ::= { snmp 8 }
+
+snmpInNoSuchNames OBJECT-TYPE
+    SYNTAX  Counter
+    ACCESS  read-only
+    STATUS  mandatory
+    DESCRIPTION
+            "The total number of SNMP PDUs which were
+            delivered to the SNMP protocol entity and for
+            which the value of the error-status field is
+            `noSuchName'."
+    ::= { snmp 9 }
+
+snmpInBadValues OBJECT-TYPE
+    SYNTAX  Counter
+    ACCESS  read-only
+    STATUS  mandatory
+    DESCRIPTION
+            "The total number of SNMP PDUs which were
+            delivered to the SNMP protocol entity and for
+            which the value of the error-status field is
+            `badValue'."
+    ::= { snmp 10 }
+
+snmpInReadOnlys OBJECT-TYPE
+    SYNTAX  Counter
+    ACCESS  read-only
+    STATUS  mandatory
+    DESCRIPTION
+            "The total number valid SNMP PDUs which were
+            delivered to the SNMP protocol entity and for
+            which the value of the error-status field is
+            `readOnly'.  It should be noted that it is a
+            protocol error to generate an SNMP PDU which
+            contains the value `readOnly' in the error-status
+            field, as such this object is provided as a means
+            of detecting incorrect implementations of the
+            SNMP."
+    ::= { snmp 11 }
+
+snmpInGenErrs OBJECT-TYPE
+    SYNTAX  Counter
+    ACCESS  read-only
+    STATUS  mandatory
+    DESCRIPTION
+            "The total number of SNMP PDUs which were
+            delivered to the SNMP protocol entity and for
+            which the value of the error-status field is
+            `genErr'."
+    ::= { snmp 12 }
+
+snmpInTotalReqVars OBJECT-TYPE
+    SYNTAX  Counter
+    ACCESS  read-only
+    STATUS  mandatory
+    DESCRIPTION
+            "The total number of MIB objects which have been
+            retrieved successfully by the SNMP protocol entity
+            as the result of receiving valid SNMP Get-Request
+            and Get-Next PDUs."
+    ::= { snmp 13 }
+
+snmpInTotalSetVars OBJECT-TYPE
+    SYNTAX  Counter
+    ACCESS  read-only
+    STATUS  mandatory
+    DESCRIPTION
+            "The total number of MIB objects which have been
+            altered successfully by the SNMP protocol entity
+            as the result of receiving valid SNMP Set-Request
+            PDUs."
+    ::= { snmp 14 }
+
+snmpInGetRequests OBJECT-TYPE
+    SYNTAX  Counter
+    ACCESS  read-only
+    STATUS  mandatory
+    DESCRIPTION
+            "The total number of SNMP Get-Request PDUs which
+            have been accepted and processed by the SNMP
+            protocol entity."
+    ::= { snmp 15 }
+
+snmpInGetNexts OBJECT-TYPE
+    SYNTAX  Counter
+    ACCESS  read-only
+    STATUS  mandatory
+    DESCRIPTION
+            "The total number of SNMP Get-Next PDUs which have
+            been accepted and processed by the SNMP protocol
+            entity."
+    ::= { snmp 16 }
+
+snmpInSetRequests OBJECT-TYPE
+    SYNTAX  Counter
+    ACCESS  read-only
+    STATUS  mandatory
+    DESCRIPTION
+            "The total number of SNMP Set-Request PDUs which
+            have been accepted and processed by the SNMP
+            protocol entity."
+    ::= { snmp 17 }
+
+snmpInGetResponses OBJECT-TYPE
+    SYNTAX  Counter
+    ACCESS  read-only
+    STATUS  mandatory
+    DESCRIPTION
+            "The total number of SNMP Get-Response PDUs which
+            have been accepted and processed by the SNMP
+            protocol entity."
+    ::= { snmp 18 }
+
+snmpInTraps OBJECT-TYPE
+    SYNTAX  Counter
+    ACCESS  read-only
+    STATUS  mandatory
+    DESCRIPTION
+            "The total number of SNMP Trap PDUs which have
+            been accepted and processed by the SNMP protocol
+            entity."
+    ::= { snmp 19 }
+
+snmpOutTooBigs OBJECT-TYPE
+    SYNTAX  Counter
+    ACCESS  read-only
+    STATUS  mandatory
+    DESCRIPTION
+            "The total number of SNMP PDUs which were
+            generated by the SNMP protocol entity and for
+            which the value of the error-status field is
+            `tooBig.'"
+    ::= { snmp 20 }
+
+snmpOutNoSuchNames OBJECT-TYPE
+    SYNTAX  Counter
+    ACCESS  read-only
+    STATUS  mandatory
+    DESCRIPTION
+            "The total number of SNMP PDUs which were
+            generated by the SNMP protocol entity and for
+            which the value of the error-status is
+            `noSuchName'."
+    ::= { snmp 21 }
+
+snmpOutBadValues OBJECT-TYPE
+    SYNTAX  Counter
+    ACCESS  read-only
+    STATUS  mandatory
+    DESCRIPTION
+            "The total number of SNMP PDUs which were
+            generated by the SNMP protocol entity and for
+            which the value of the error-status field is
+            `badValue'."
+    ::= { snmp 22 }
+
+-- { snmp 23 } is not used
+
+snmpOutGenErrs OBJECT-TYPE
+    SYNTAX  Counter
+    ACCESS  read-only
+    STATUS  mandatory
+    DESCRIPTION
+            "The total number of SNMP PDUs which were
+            generated by the SNMP protocol entity and for
+            which the value of the error-status field is
+            `genErr'."
+    ::= { snmp 24 }
+
+snmpOutGetRequests OBJECT-TYPE
+    SYNTAX  Counter
+    ACCESS  read-only
+    STATUS  mandatory
+    DESCRIPTION
+            "The total number of SNMP Get-Request PDUs which
+            have been generated by the SNMP protocol entity."
+    ::= { snmp 25 }
+
+snmpOutGetNexts OBJECT-TYPE
+    SYNTAX  Counter
+    ACCESS  read-only
+    STATUS  mandatory
+    DESCRIPTION
+            "The total number of SNMP Get-Next PDUs which have
+            been generated by the SNMP protocol entity."
+    ::= { snmp 26 }
+
+snmpOutSetRequests OBJECT-TYPE
+    SYNTAX  Counter
+    ACCESS  read-only
+    STATUS  mandatory
+    DESCRIPTION
+            "The total number of SNMP Set-Request PDUs which
+            have been generated by the SNMP protocol entity."
+    ::= { snmp 27 }
+
+snmpOutGetResponses OBJECT-TYPE
+    SYNTAX  Counter
+    ACCESS  read-only
+    STATUS  mandatory
+    DESCRIPTION
+            "The total number of SNMP Get-Response PDUs which
+            have been generated by the SNMP protocol entity."
+    ::= { snmp 28 }
+
+snmpOutTraps OBJECT-TYPE
+    SYNTAX  Counter
+    ACCESS  read-only
+    STATUS  mandatory
+    DESCRIPTION
+            "The total number of SNMP Trap PDUs which have
+            been generated by the SNMP protocol entity."
+    ::= { snmp 29 }
+
+snmpEnableAuthenTraps OBJECT-TYPE
+    SYNTAX  INTEGER { enabled(1), disabled(2) }
+    ACCESS  read-write
+    STATUS  mandatory
+    DESCRIPTION
+            "Indicates whether the SNMP agent process is
+            permitted to generate authentication-failure
+            traps.  The value of this object overrides any
+            configuration information; as such, it provides a
+            means whereby all authentication-failure traps may
+            be disabled.
+
+            Note that it is strongly recommended that this
+            object be stored in non-volatile memory so that it
+            remains constant between re-initializations of the
+            network management system."
+    ::= { snmp 30 }
+
+END
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/Mibs/SNMPv2-CONF
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/Mibs/SNMPv2-CONF	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/Mibs/SNMPv2-CONF	(revision 457)
@@ -0,0 +1,318 @@
+SNMPv2-CONF DEFINITIONS ::= BEGIN
+
+IMPORTS ObjectName, NotificationName, ObjectSyntax
+                                               FROM SNMPv2-SMI;
+
+-- definitions for conformance groups
+
+OBJECT-GROUP MACRO ::=
+BEGIN
+    TYPE NOTATION ::=
+                  ObjectsPart
+                  "STATUS" Status
+                  "DESCRIPTION" Text
+                  ReferPart
+
+    VALUE NOTATION ::=
+                  value(VALUE OBJECT IDENTIFIER)
+
+    ObjectsPart ::=
+                  "OBJECTS" "{" Objects "}"
+    Objects ::=
+                  Object
+                | Objects "," Object
+    Object ::=
+                  value(ObjectName)
+
+    Status ::=
+                  "current"
+                | "deprecated"
+                | "obsolete"
+
+    ReferPart ::=
+                  "REFERENCE" Text
+                | empty
+
+    -- a character string as defined in [2]
+    Text ::= value(IA5String)
+END
+
+-- more definitions for conformance groups
+
+NOTIFICATION-GROUP MACRO ::=
+BEGIN
+    TYPE NOTATION ::=
+                  NotificationsPart
+                  "STATUS" Status
+                  "DESCRIPTION" Text
+                  ReferPart
+
+    VALUE NOTATION ::=
+                  value(VALUE OBJECT IDENTIFIER)
+
+    NotificationsPart ::=
+                  "NOTIFICATIONS" "{" Notifications "}"
+    Notifications ::=
+                  Notification
+                | Notifications "," Notification
+    Notification ::=
+                  value(NotificationName)
+
+    Status ::=
+                  "current"
+                | "deprecated"
+                | "obsolete"
+
+    ReferPart ::=
+                  "REFERENCE" Text
+                | empty
+
+    -- a character string as defined in [2]
+    Text ::= value(IA5String)
+END
+
+-- definitions for compliance statements
+
+MODULE-COMPLIANCE MACRO ::=
+BEGIN
+    TYPE NOTATION ::=
+                  "STATUS" Status
+                  "DESCRIPTION" Text
+                  ReferPart
+                  ModulePart
+
+    VALUE NOTATION ::=
+                  value(VALUE OBJECT IDENTIFIER)
+
+    Status ::=
+                  "current"
+                | "deprecated"
+                | "obsolete"
+
+    ReferPart ::=
+                  "REFERENCE" Text
+                | empty
+
+    ModulePart ::=
+                  Modules
+    Modules ::=
+                  Module
+                | Modules Module
+    Module ::=
+                  -- name of module --
+                  "MODULE" ModuleName
+                  MandatoryPart
+                  CompliancePart
+
+    ModuleName ::=
+                  -- identifier must start with uppercase letter
+                  identifier ModuleIdentifier
+                  -- must not be empty unless contained
+                  -- in MIB Module
+                | empty
+    ModuleIdentifier ::=
+                  value(OBJECT IDENTIFIER)
+                | empty
+
+    MandatoryPart ::=
+                  "MANDATORY-GROUPS" "{" Groups "}"
+                | empty
+
+    Groups ::=
+                  Group
+                | Groups "," Group
+    Group ::=
+                  value(OBJECT IDENTIFIER)
+
+    CompliancePart ::=
+                  Compliances
+                | empty
+
+    Compliances ::=
+                  Compliance
+                | Compliances Compliance
+    Compliance ::=
+                  ComplianceGroup
+                | Object
+
+    ComplianceGroup ::=
+                  "GROUP" value(OBJECT IDENTIFIER)
+                  "DESCRIPTION" Text
+
+    Object ::=
+                  "OBJECT" value(ObjectName)
+                  SyntaxPart
+                  WriteSyntaxPart
+                  AccessPart
+                  "DESCRIPTION" Text
+
+    -- must be a refinement for object's SYNTAX clause
+    SyntaxPart ::= "SYNTAX" Syntax
+                | empty
+
+    -- must be a refinement for object's SYNTAX clause
+    WriteSyntaxPart ::= "WRITE-SYNTAX" Syntax
+                | empty
+
+    Syntax ::=    -- Must be one of the following:
+                       -- a base type (or its refinement),
+                       -- a textual convention (or its refinement), or
+                       -- a BITS pseudo-type
+                  type
+                | "BITS" "{" NamedBits "}"
+
+    NamedBits ::= NamedBit
+                | NamedBits "," NamedBit
+
+    NamedBit ::= identifier "(" number ")" -- number is nonnegative
+
+    AccessPart ::=
+                  "MIN-ACCESS" Access
+                | empty
+    Access ::=
+                  "not-accessible"
+                | "accessible-for-notify"
+                | "read-only"
+                | "read-write"
+                | "read-create"
+
+    -- a character string as defined in [2]
+    Text ::= value(IA5String)
+END
+
+-- definitions for capabilities statements
+
+AGENT-CAPABILITIES MACRO ::=
+BEGIN
+    TYPE NOTATION ::=
+                  "PRODUCT-RELEASE" Text
+                  "STATUS" Status
+                  "DESCRIPTION" Text
+                  ReferPart
+                  ModulePart
+
+    VALUE NOTATION ::=
+                  value(VALUE OBJECT IDENTIFIER)
+
+    Status ::=
+                  "current"
+                | "obsolete"
+
+    ReferPart ::=
+                  "REFERENCE" Text
+                | empty
+
+    ModulePart ::=
+                  Modules
+                | empty
+    Modules ::=
+                  Module
+                | Modules Module
+    Module ::=
+                  -- name of module --
+                  "SUPPORTS" ModuleName
+                  "INCLUDES" "{" Groups "}"
+                  VariationPart
+
+    ModuleName ::=
+                  -- identifier must start with uppercase letter
+                  identifier ModuleIdentifier
+    ModuleIdentifier ::=
+                  value(OBJECT IDENTIFIER)
+                | empty
+
+    Groups ::=
+                  Group
+                | Groups "," Group
+    Group ::=
+                  value(OBJECT IDENTIFIER)
+
+    VariationPart ::=
+                  Variations
+                | empty
+    Variations ::=
+                  Variation
+                | Variations Variation
+
+    Variation ::=
+                  ObjectVariation
+                | NotificationVariation
+
+    NotificationVariation ::=
+                  "VARIATION" value(NotificationName)
+                  AccessPart
+                  "DESCRIPTION" Text
+
+    ObjectVariation ::=
+                  "VARIATION" value(ObjectName)
+                  SyntaxPart
+                  WriteSyntaxPart
+                  AccessPart
+                  CreationPart
+                  DefValPart
+                  "DESCRIPTION" Text
+
+    -- must be a refinement for object's SYNTAX clause
+    SyntaxPart ::= "SYNTAX" Syntax
+                | empty
+
+    WriteSyntaxPart ::= "WRITE-SYNTAX" Syntax
+                | empty
+
+    Syntax ::=    -- Must be one of the following:
+                       -- a base type (or its refinement),
+                       -- a textual convention (or its refinement), or
+                       -- a BITS pseudo-type
+                  type
+                | "BITS" "{" NamedBits "}"
+
+    NamedBits ::= NamedBit
+                | NamedBits "," NamedBit
+
+    NamedBit ::= identifier "(" number ")" -- number is nonnegative
+
+    AccessPart ::=
+                  "ACCESS" Access
+                | empty
+
+    Access ::=
+                  "not-implemented"
+                -- only "not-implemented" for notifications
+                | "accessible-for-notify"
+                | "read-only"
+                | "read-write"
+                | "read-create"
+                -- following is for backward-compatibility only
+                | "write-only"
+
+    CreationPart ::=
+                  "CREATION-REQUIRES" "{" Cells "}"
+                | empty
+    Cells ::=
+                  Cell
+                | Cells "," Cell
+    Cell ::=
+                  value(ObjectName)
+
+    DefValPart ::= "DEFVAL" "{" Defvalue "}"
+                | empty
+
+    Defvalue ::=  -- must be valid for the object's syntax
+                  -- in this macro's SYNTAX clause, if present,
+                  -- or if not, in object's OBJECT-TYPE macro
+                  value(ObjectSyntax)
+                | "{" BitsValue "}"
+
+    BitsValue ::= BitNames
+                | empty
+
+    BitNames ::=  BitName
+                | BitNames "," BitName
+
+    BitName ::= identifier
+
+    -- a character string as defined in [2]
+    Text ::= value(IA5String)
+END
+
+END
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/Mibs/SNMPv2-MIB
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/Mibs/SNMPv2-MIB	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/Mibs/SNMPv2-MIB	(revision 457)
@@ -0,0 +1,903 @@
+SNMPv2-MIB DEFINITIONS ::= BEGIN
+
+IMPORTS
+    MODULE-IDENTITY, OBJECT-TYPE, NOTIFICATION-TYPE,
+    TimeTicks, Counter32, snmpModules, mib-2
+        FROM SNMPv2-SMI
+    DisplayString, TestAndIncr, TimeStamp
+
+
+
+        FROM SNMPv2-TC
+    MODULE-COMPLIANCE, OBJECT-GROUP, NOTIFICATION-GROUP
+        FROM SNMPv2-CONF;
+
+snmpMIB MODULE-IDENTITY
+    LAST-UPDATED "200210160000Z"
+    ORGANIZATION "IETF SNMPv3 Working Group"
+    CONTACT-INFO
+            "WG-EMail:   snmpv3@lists.tislabs.com
+             Subscribe:  snmpv3-request@lists.tislabs.com
+
+             Co-Chair:   Russ Mundy
+                         Network Associates Laboratories
+             postal:     15204 Omega Drive, Suite 300
+                         Rockville, MD 20850-4601
+                         USA
+             EMail:      mundy@tislabs.com
+             phone:      +1 301 947-7107
+
+             Co-Chair:   David Harrington
+                         Enterasys Networks
+             postal:     35 Industrial Way
+                         P. O. Box 5005
+                         Rochester, NH 03866-5005
+                         USA
+             EMail:      dbh@enterasys.com
+             phone:      +1 603 337-2614
+
+             Editor:     Randy Presuhn
+                         BMC Software, Inc.
+             postal:     2141 North First Street
+                         San Jose, CA 95131
+                         USA
+             EMail:      randy_presuhn@bmc.com
+             phone:      +1 408 546-1006"
+    DESCRIPTION
+            "The MIB module for SNMP entities.
+
+             Copyright (C) The Internet Society (2002). This
+             version of this MIB module is part of RFC 3418;
+             see the RFC itself for full legal notices.
+            "
+    REVISION      "200210160000Z"
+    DESCRIPTION
+            "This revision of this MIB module was published as
+             RFC 3418."
+    REVISION      "199511090000Z"
+    DESCRIPTION
+
+
+
+            "This revision of this MIB module was published as
+             RFC 1907."
+    REVISION      "199304010000Z"
+    DESCRIPTION
+            "The initial revision of this MIB module was published
+            as RFC 1450."
+    ::= { snmpModules 1 }
+
+snmpMIBObjects OBJECT IDENTIFIER ::= { snmpMIB 1 }
+
+--  ::= { snmpMIBObjects 1 }        this OID is obsolete
+--  ::= { snmpMIBObjects 2 }        this OID is obsolete
+--  ::= { snmpMIBObjects 3 }        this OID is obsolete
+
+-- the System group
+--
+-- a collection of objects common to all managed systems.
+
+system   OBJECT IDENTIFIER ::= { mib-2 1 }
+
+sysDescr OBJECT-TYPE
+    SYNTAX      DisplayString (SIZE (0..255))
+    MAX-ACCESS  read-only
+    STATUS      current
+    DESCRIPTION
+            "A textual description of the entity.  This value should
+            include the full name and version identification of
+            the system's hardware type, software operating-system,
+            and networking software."
+    ::= { system 1 }
+
+sysObjectID OBJECT-TYPE
+    SYNTAX      OBJECT IDENTIFIER
+    MAX-ACCESS  read-only
+    STATUS      current
+    DESCRIPTION
+            "The vendor's authoritative identification of the
+            network management subsystem contained in the entity.
+            This value is allocated within the SMI enterprises
+            subtree (1.3.6.1.4.1) and provides an easy and
+            unambiguous means for determining `what kind of box' is
+            being managed.  For example, if vendor `Flintstones,
+            Inc.' was assigned the subtree 1.3.6.1.4.1.424242,
+            it could assign the identifier 1.3.6.1.4.1.424242.1.1
+            to its `Fred Router'."
+    ::= { system 2 }
+
+sysUpTime OBJECT-TYPE
+
+
+
+    SYNTAX      TimeTicks
+    MAX-ACCESS  read-only
+    STATUS      current
+    DESCRIPTION
+            "The time (in hundredths of a second) since the
+            network management portion of the system was last
+            re-initialized."
+    ::= { system 3 }
+
+sysContact OBJECT-TYPE
+    SYNTAX      DisplayString (SIZE (0..255))
+    MAX-ACCESS  read-write
+    STATUS      current
+    DESCRIPTION
+            "The textual identification of the contact person for
+            this managed node, together with information on how
+            to contact this person.  If no contact information is
+            known, the value is the zero-length string."
+    ::= { system 4 }
+
+sysName OBJECT-TYPE
+    SYNTAX      DisplayString (SIZE (0..255))
+    MAX-ACCESS  read-write
+    STATUS      current
+    DESCRIPTION
+            "An administratively-assigned name for this managed
+            node.  By convention, this is the node's fully-qualified
+            domain name.  If the name is unknown, the value is
+            the zero-length string."
+    ::= { system 5 }
+
+sysLocation OBJECT-TYPE
+    SYNTAX      DisplayString (SIZE (0..255))
+    MAX-ACCESS  read-write
+    STATUS      current
+    DESCRIPTION
+            "The physical location of this node (e.g., 'telephone
+            closet, 3rd floor').  If the location is unknown, the
+            value is the zero-length string."
+    ::= { system 6 }
+
+sysServices OBJECT-TYPE
+    SYNTAX      INTEGER (0..127)
+    MAX-ACCESS  read-only
+    STATUS      current
+    DESCRIPTION
+            "A value which indicates the set of services that this
+            entity may potentially offer.  The value is a sum.
+
+
+
+            This sum initially takes the value zero. Then, for
+            each layer, L, in the range 1 through 7, that this node
+            performs transactions for, 2 raised to (L - 1) is added
+            to the sum.  For example, a node which performs only
+            routing functions would have a value of 4 (2^(3-1)).
+            In contrast, a node which is a host offering application
+            services would have a value of 72 (2^(4-1) + 2^(7-1)).
+            Note that in the context of the Internet suite of
+            protocols, values should be calculated accordingly:
+
+                 layer      functionality
+                   1        physical (e.g., repeaters)
+                   2        datalink/subnetwork (e.g., bridges)
+                   3        internet (e.g., supports the IP)
+                   4        end-to-end  (e.g., supports the TCP)
+                   7        applications (e.g., supports the SMTP)
+
+            For systems including OSI protocols, layers 5 and 6
+            may also be counted."
+    ::= { system 7 }
+
+-- object resource information
+--
+-- a collection of objects which describe the SNMP entity's
+-- (statically and dynamically configurable) support of
+-- various MIB modules.
+
+sysORLastChange OBJECT-TYPE
+    SYNTAX     TimeStamp
+    MAX-ACCESS read-only
+    STATUS     current
+    DESCRIPTION
+            "The value of sysUpTime at the time of the most recent
+            change in state or value of any instance of sysORID."
+    ::= { system 8 }
+
+sysORTable OBJECT-TYPE
+    SYNTAX     SEQUENCE OF SysOREntry
+    MAX-ACCESS not-accessible
+    STATUS     current
+    DESCRIPTION
+            "The (conceptual) table listing the capabilities of
+            the local SNMP application acting as a command
+            responder with respect to various MIB modules.
+            SNMP entities having dynamically-configurable support
+            of MIB modules will have a dynamically-varying number
+            of conceptual rows."
+    ::= { system 9 }
+
+
+
+sysOREntry OBJECT-TYPE
+    SYNTAX     SysOREntry
+    MAX-ACCESS not-accessible
+    STATUS     current
+    DESCRIPTION
+            "An entry (conceptual row) in the sysORTable."
+    INDEX      { sysORIndex }
+    ::= { sysORTable 1 }
+
+SysOREntry ::= SEQUENCE {
+    sysORIndex     INTEGER,
+    sysORID        OBJECT IDENTIFIER,
+    sysORDescr     DisplayString,
+    sysORUpTime    TimeStamp
+}
+
+sysORIndex OBJECT-TYPE
+    SYNTAX     INTEGER (1..2147483647)
+    MAX-ACCESS not-accessible
+    STATUS     current
+    DESCRIPTION
+            "The auxiliary variable used for identifying instances
+            of the columnar objects in the sysORTable."
+    ::= { sysOREntry 1 }
+
+sysORID OBJECT-TYPE
+    SYNTAX     OBJECT IDENTIFIER
+    MAX-ACCESS read-only
+    STATUS     current
+    DESCRIPTION
+            "An authoritative identification of a capabilities
+            statement with respect to various MIB modules supported
+            by the local SNMP application acting as a command
+            responder."
+    ::= { sysOREntry 2 }
+
+sysORDescr OBJECT-TYPE
+    SYNTAX     DisplayString
+    MAX-ACCESS read-only
+    STATUS     current
+    DESCRIPTION
+            "A textual description of the capabilities identified
+            by the corresponding instance of sysORID."
+    ::= { sysOREntry 3 }
+
+sysORUpTime OBJECT-TYPE
+    SYNTAX     TimeStamp
+    MAX-ACCESS read-only
+
+
+
+    STATUS     current
+    DESCRIPTION
+            "The value of sysUpTime at the time this conceptual
+            row was last instantiated."
+    ::= { sysOREntry 4 }
+
+
+-- the SNMP group
+--
+-- a collection of objects providing basic instrumentation and
+-- control of an SNMP entity.
+
+snmp     OBJECT IDENTIFIER ::= { mib-2 11 }
+
+snmpInPkts OBJECT-TYPE
+    SYNTAX     Counter32
+    MAX-ACCESS read-only
+    STATUS     current
+    DESCRIPTION
+            "The total number of messages delivered to the SNMP
+            entity from the transport service."
+    ::= { snmp 1 }
+
+snmpInBadVersions OBJECT-TYPE
+    SYNTAX     Counter32
+    MAX-ACCESS read-only
+    STATUS     current
+    DESCRIPTION
+            "The total number of SNMP messages which were delivered
+            to the SNMP entity and were for an unsupported SNMP
+            version."
+    ::= { snmp 3 }
+
+snmpInBadCommunityNames OBJECT-TYPE
+    SYNTAX     Counter32
+    MAX-ACCESS read-only
+    STATUS     current
+    DESCRIPTION
+           "The total number of community-based SNMP messages (for
+           example,  SNMPv1) delivered to the SNMP entity which
+           used an SNMP community name not known to said entity.
+           Also, implementations which authenticate community-based
+           SNMP messages using check(s) in addition to matching
+           the community name (for example, by also checking
+           whether the message originated from a transport address
+           allowed to use a specified community name) MAY include
+           in this value the number of messages which failed the
+           additional check(s).  It is strongly RECOMMENDED that
+
+
+
+           the documentation for any security model which is used
+           to authenticate community-based SNMP messages specify
+           the precise conditions that contribute to this value."
+    ::= { snmp 4 }
+
+snmpInBadCommunityUses OBJECT-TYPE
+    SYNTAX     Counter32
+    MAX-ACCESS read-only
+    STATUS     current
+    DESCRIPTION
+           "The total number of community-based SNMP messages (for
+           example, SNMPv1) delivered to the SNMP entity which
+           represented an SNMP operation that was not allowed for
+           the SNMP community named in the message.  The precise
+           conditions under which this counter is incremented
+           (if at all) depend on how the SNMP entity implements
+           its access control mechanism and how its applications
+           interact with that access control mechanism.  It is
+           strongly RECOMMENDED that the documentation for any
+           access control mechanism which is used to control access
+           to and visibility of MIB instrumentation specify the
+           precise conditions that contribute to this value."
+    ::= { snmp 5 }
+
+snmpInASNParseErrs OBJECT-TYPE
+    SYNTAX     Counter32
+    MAX-ACCESS read-only
+    STATUS     current
+    DESCRIPTION
+            "The total number of ASN.1 or BER errors encountered by
+            the SNMP entity when decoding received SNMP messages."
+    ::= { snmp 6 }
+
+snmpEnableAuthenTraps OBJECT-TYPE
+    SYNTAX      INTEGER { enabled(1), disabled(2) }
+    MAX-ACCESS  read-write
+    STATUS      current
+    DESCRIPTION
+            "Indicates whether the SNMP entity is permitted to
+            generate authenticationFailure traps.  The value of this
+            object overrides any configuration information; as such,
+            it provides a means whereby all authenticationFailure
+            traps may be disabled.
+
+            Note that it is strongly recommended that this object
+            be stored in non-volatile memory so that it remains
+            constant across re-initializations of the network
+            management system."
+
+
+
+    ::= { snmp 30 }
+
+snmpSilentDrops OBJECT-TYPE
+    SYNTAX     Counter32
+    MAX-ACCESS read-only
+    STATUS     current
+    DESCRIPTION
+           "The total number of Confirmed Class PDUs (such as
+           GetRequest-PDUs, GetNextRequest-PDUs,
+           GetBulkRequest-PDUs, SetRequest-PDUs, and
+           InformRequest-PDUs) delivered to the SNMP entity which
+           were silently dropped because the size of a reply
+           containing an alternate Response Class PDU (such as a
+           Response-PDU) with an empty variable-bindings field
+           was greater than either a local constraint or the
+           maximum message size associated with the originator of
+           the request."
+    ::= { snmp 31 }
+
+snmpProxyDrops OBJECT-TYPE
+    SYNTAX     Counter32
+    MAX-ACCESS read-only
+    STATUS     current
+    DESCRIPTION
+            "The total number of Confirmed Class PDUs
+            (such as GetRequest-PDUs, GetNextRequest-PDUs,
+            GetBulkRequest-PDUs, SetRequest-PDUs, and
+            InformRequest-PDUs) delivered to the SNMP entity which
+            were silently dropped because the transmission of
+            the (possibly translated) message to a proxy target
+            failed in a manner (other than a time-out) such that
+            no Response Class PDU (such as a Response-PDU) could
+            be returned."
+    ::= { snmp 32 }
+
+-- information for notifications
+--
+-- a collection of objects which allow the SNMP entity, when
+-- supporting a notification originator application,
+-- to be configured to generate SNMPv2-Trap-PDUs.
+
+snmpTrap       OBJECT IDENTIFIER ::= { snmpMIBObjects 4 }
+
+snmpTrapOID OBJECT-TYPE
+    SYNTAX     OBJECT IDENTIFIER
+    MAX-ACCESS accessible-for-notify
+    STATUS     current
+    DESCRIPTION
+
+
+
+            "The authoritative identification of the notification
+            currently being sent.  This variable occurs as
+            the second varbind in every SNMPv2-Trap-PDU and
+            InformRequest-PDU."
+    ::= { snmpTrap 1 }
+
+--  ::= { snmpTrap 2 }   this OID is obsolete
+
+snmpTrapEnterprise OBJECT-TYPE
+    SYNTAX     OBJECT IDENTIFIER
+    MAX-ACCESS accessible-for-notify
+    STATUS     current
+    DESCRIPTION
+            "The authoritative identification of the enterprise
+            associated with the trap currently being sent.  When an
+            SNMP proxy agent is mapping an RFC1157 Trap-PDU
+            into a SNMPv2-Trap-PDU, this variable occurs as the
+            last varbind."
+    ::= { snmpTrap 3 }
+
+--  ::= { snmpTrap 4 }   this OID is obsolete
+
+
+-- well-known traps
+
+snmpTraps      OBJECT IDENTIFIER ::= { snmpMIBObjects 5 }
+
+coldStart NOTIFICATION-TYPE
+    STATUS  current
+    DESCRIPTION
+            "A coldStart trap signifies that the SNMP entity,
+            supporting a notification originator application, is
+            reinitializing itself and that its configuration may
+            have been altered."
+    ::= { snmpTraps 1 }
+
+warmStart NOTIFICATION-TYPE
+    STATUS  current
+    DESCRIPTION
+            "A warmStart trap signifies that the SNMP entity,
+            supporting a notification originator application,
+            is reinitializing itself such that its configuration
+            is unaltered."
+    ::= { snmpTraps 2 }
+
+-- Note the linkDown NOTIFICATION-TYPE ::= { snmpTraps 3 }
+-- and the linkUp NOTIFICATION-TYPE ::= { snmpTraps 4 }
+-- are defined in RFC 2863 [RFC2863]
+
+
+
+authenticationFailure NOTIFICATION-TYPE
+    STATUS  current
+    DESCRIPTION
+            "An authenticationFailure trap signifies that the SNMP
+             entity has received a protocol message that is not
+             properly authenticated.  While all implementations
+             of SNMP entities MAY be capable of generating this
+             trap, the snmpEnableAuthenTraps object indicates
+             whether this trap will be generated."
+    ::= { snmpTraps 5 }
+
+-- Note the egpNeighborLoss notification is defined
+-- as { snmpTraps 6 } in RFC 1213
+
+-- the set group
+--
+-- a collection of objects which allow several cooperating
+-- command generator applications to coordinate their use of the
+-- set operation.
+
+snmpSet        OBJECT IDENTIFIER ::= { snmpMIBObjects 6 }
+
+snmpSetSerialNo OBJECT-TYPE
+    SYNTAX     TestAndIncr
+    MAX-ACCESS read-write
+    STATUS     current
+    DESCRIPTION
+            "An advisory lock used to allow several cooperating
+            command generator applications to coordinate their
+            use of the SNMP set operation.
+
+            This object is used for coarse-grain coordination.
+            To achieve fine-grain coordination, one or more similar
+            objects might be defined within each MIB group, as
+            appropriate."
+    ::= { snmpSet 1 }
+
+-- conformance information
+
+snmpMIBConformance
+               OBJECT IDENTIFIER ::= { snmpMIB 2 }
+
+snmpMIBCompliances
+               OBJECT IDENTIFIER ::= { snmpMIBConformance 1 }
+snmpMIBGroups  OBJECT IDENTIFIER ::= { snmpMIBConformance 2 }
+
+-- compliance statements
+
+
+
+
+--    ::= { snmpMIBCompliances 1 }      this OID is obsolete
+snmpBasicCompliance MODULE-COMPLIANCE
+    STATUS  deprecated
+    DESCRIPTION
+            "The compliance statement for SNMPv2 entities which
+            implement the SNMPv2 MIB.
+
+            This compliance statement is replaced by
+            snmpBasicComplianceRev2."
+    MODULE  -- this module
+        MANDATORY-GROUPS { snmpGroup, snmpSetGroup, systemGroup,
+                           snmpBasicNotificationsGroup }
+
+        GROUP   snmpCommunityGroup
+        DESCRIPTION
+            "This group is mandatory for SNMPv2 entities which
+            support community-based authentication."
+
+    ::= { snmpMIBCompliances 2 }
+
+snmpBasicComplianceRev2 MODULE-COMPLIANCE
+    STATUS  current
+    DESCRIPTION
+            "The compliance statement for SNMP entities which
+            implement this MIB module."
+    MODULE  -- this module
+        MANDATORY-GROUPS { snmpGroup, snmpSetGroup, systemGroup,
+                           snmpBasicNotificationsGroup }
+
+        GROUP   snmpCommunityGroup
+        DESCRIPTION
+            "This group is mandatory for SNMP entities which
+            support community-based authentication."
+
+        GROUP   snmpWarmStartNotificationGroup
+        DESCRIPTION
+            "This group is mandatory for an SNMP entity which
+            supports command responder applications, and is
+            able to reinitialize itself such that its
+            configuration is unaltered."
+
+    ::= { snmpMIBCompliances 3 }
+
+-- units of conformance
+
+--  ::= { snmpMIBGroups 1 }           this OID is obsolete
+--  ::= { snmpMIBGroups 2 }           this OID is obsolete
+--  ::= { snmpMIBGroups 3 }           this OID is obsolete
+
+
+
+--  ::= { snmpMIBGroups 4 }           this OID is obsolete
+
+snmpGroup OBJECT-GROUP
+    OBJECTS { snmpInPkts,
+              snmpInBadVersions,
+              snmpInASNParseErrs,
+              snmpSilentDrops,
+              snmpProxyDrops,
+              snmpEnableAuthenTraps }
+    STATUS  current
+    DESCRIPTION
+            "A collection of objects providing basic instrumentation
+            and control of an SNMP entity."
+    ::= { snmpMIBGroups 8 }
+
+snmpCommunityGroup OBJECT-GROUP
+    OBJECTS { snmpInBadCommunityNames,
+              snmpInBadCommunityUses }
+    STATUS  current
+    DESCRIPTION
+            "A collection of objects providing basic instrumentation
+            of a SNMP entity which supports community-based
+            authentication."
+    ::= { snmpMIBGroups 9 }
+
+snmpSetGroup OBJECT-GROUP
+    OBJECTS { snmpSetSerialNo }
+    STATUS  current
+    DESCRIPTION
+            "A collection of objects which allow several cooperating
+            command generator applications to coordinate their
+            use of the set operation."
+    ::= { snmpMIBGroups 5 }
+
+systemGroup OBJECT-GROUP
+    OBJECTS { sysDescr, sysObjectID, sysUpTime,
+              sysContact, sysName, sysLocation,
+              sysServices,
+              sysORLastChange, sysORID,
+              sysORUpTime, sysORDescr }
+    STATUS  current
+    DESCRIPTION
+            "The system group defines objects which are common to all
+            managed systems."
+    ::= { snmpMIBGroups 6 }
+
+snmpBasicNotificationsGroup NOTIFICATION-GROUP
+    NOTIFICATIONS { coldStart, authenticationFailure }
+
+
+
+    STATUS        current
+    DESCRIPTION
+       "The basic notifications implemented by an SNMP entity
+        supporting command responder applications."
+    ::= { snmpMIBGroups 7 }
+
+snmpWarmStartNotificationGroup NOTIFICATION-GROUP
+   NOTIFICATIONS { warmStart }
+   STATUS        current
+   DESCRIPTION
+     "An additional notification for an SNMP entity supporting
+     command responder applications, if it is able to reinitialize
+     itself such that its configuration is unaltered."
+  ::= { snmpMIBGroups 11 }
+
+snmpNotificationGroup OBJECT-GROUP
+    OBJECTS { snmpTrapOID, snmpTrapEnterprise }
+    STATUS  current
+    DESCRIPTION
+            "These objects are required for entities
+            which support notification originator applications."
+    ::= { snmpMIBGroups 12 }
+
+-- definitions in RFC 1213 made obsolete by the inclusion of a
+-- subset of the snmp group in this MIB
+
+snmpOutPkts OBJECT-TYPE
+    SYNTAX      Counter32
+    MAX-ACCESS  read-only
+    STATUS      obsolete
+    DESCRIPTION
+            "The total number of SNMP Messages which were
+            passed from the SNMP protocol entity to the
+            transport service."
+    ::= { snmp 2 }
+
+-- { snmp 7 } is not used
+
+snmpInTooBigs OBJECT-TYPE
+    SYNTAX      Counter32
+    MAX-ACCESS  read-only
+    STATUS      obsolete
+    DESCRIPTION
+            "The total number of SNMP PDUs which were
+            delivered to the SNMP protocol entity and for
+            which the value of the error-status field was
+            `tooBig'."
+    ::= { snmp 8 }
+
+
+
+snmpInNoSuchNames OBJECT-TYPE
+    SYNTAX      Counter32
+    MAX-ACCESS  read-only
+    STATUS      obsolete
+    DESCRIPTION
+            "The total number of SNMP PDUs which were
+            delivered to the SNMP protocol entity and for
+            which the value of the error-status field was
+            `noSuchName'."
+    ::= { snmp 9 }
+
+snmpInBadValues OBJECT-TYPE
+    SYNTAX      Counter32
+    MAX-ACCESS  read-only
+    STATUS      obsolete
+    DESCRIPTION
+            "The total number of SNMP PDUs which were
+            delivered to the SNMP protocol entity and for
+            which the value of the error-status field was
+            `badValue'."
+    ::= { snmp 10 }
+
+snmpInReadOnlys OBJECT-TYPE
+    SYNTAX      Counter32
+    MAX-ACCESS  read-only
+    STATUS      obsolete
+    DESCRIPTION
+            "The total number valid SNMP PDUs which were delivered
+            to the SNMP protocol entity and for which the value
+            of the error-status field was `readOnly'.  It should
+            be noted that it is a protocol error to generate an
+            SNMP PDU which contains the value `readOnly' in the
+            error-status field, as such this object is provided
+            as a means of detecting incorrect implementations of
+            the SNMP."
+    ::= { snmp 11 }
+
+snmpInGenErrs OBJECT-TYPE
+    SYNTAX      Counter32
+    MAX-ACCESS  read-only
+    STATUS      obsolete
+    DESCRIPTION
+            "The total number of SNMP PDUs which were delivered
+            to the SNMP protocol entity and for which the value
+            of the error-status field was `genErr'."
+    ::= { snmp 12 }
+
+snmpInTotalReqVars OBJECT-TYPE
+
+
+
+    SYNTAX      Counter32
+    MAX-ACCESS  read-only
+    STATUS      obsolete
+    DESCRIPTION
+            "The total number of MIB objects which have been
+            retrieved successfully by the SNMP protocol entity
+            as the result of receiving valid SNMP Get-Request
+            and Get-Next PDUs."
+    ::= { snmp 13 }
+
+snmpInTotalSetVars OBJECT-TYPE
+    SYNTAX      Counter32
+    MAX-ACCESS  read-only
+    STATUS      obsolete
+    DESCRIPTION
+            "The total number of MIB objects which have been
+            altered successfully by the SNMP protocol entity as
+            the result of receiving valid SNMP Set-Request PDUs."
+    ::= { snmp 14 }
+
+snmpInGetRequests OBJECT-TYPE
+    SYNTAX      Counter32
+    MAX-ACCESS  read-only
+    STATUS      obsolete
+    DESCRIPTION
+            "The total number of SNMP Get-Request PDUs which
+            have been accepted and processed by the SNMP
+            protocol entity."
+    ::= { snmp 15 }
+
+snmpInGetNexts OBJECT-TYPE
+    SYNTAX      Counter32
+    MAX-ACCESS  read-only
+    STATUS      obsolete
+    DESCRIPTION
+            "The total number of SNMP Get-Next PDUs which have been
+            accepted and processed by the SNMP protocol entity."
+    ::= { snmp 16 }
+
+snmpInSetRequests OBJECT-TYPE
+    SYNTAX      Counter32
+    MAX-ACCESS  read-only
+    STATUS      obsolete
+    DESCRIPTION
+            "The total number of SNMP Set-Request PDUs which
+            have been accepted and processed by the SNMP protocol
+            entity."
+    ::= { snmp 17 }
+
+
+
+snmpInGetResponses OBJECT-TYPE
+    SYNTAX      Counter32
+    MAX-ACCESS  read-only
+    STATUS      obsolete
+    DESCRIPTION
+            "The total number of SNMP Get-Response PDUs which
+            have been accepted and processed by the SNMP protocol
+            entity."
+    ::= { snmp 18 }
+
+snmpInTraps OBJECT-TYPE
+    SYNTAX      Counter32
+    MAX-ACCESS  read-only
+    STATUS      obsolete
+    DESCRIPTION
+            "The total number of SNMP Trap PDUs which have been
+            accepted and processed by the SNMP protocol entity."
+    ::= { snmp 19 }
+
+snmpOutTooBigs OBJECT-TYPE
+    SYNTAX      Counter32
+    MAX-ACCESS  read-only
+    STATUS      obsolete
+    DESCRIPTION
+            "The total number of SNMP PDUs which were generated
+            by the SNMP protocol entity and for which the value
+            of the error-status field was `tooBig.'"
+    ::= { snmp 20 }
+
+snmpOutNoSuchNames OBJECT-TYPE
+    SYNTAX      Counter32
+    MAX-ACCESS  read-only
+    STATUS      obsolete
+    DESCRIPTION
+            "The total number of SNMP PDUs which were generated
+            by the SNMP protocol entity and for which the value
+            of the error-status was `noSuchName'."
+    ::= { snmp 21 }
+
+snmpOutBadValues OBJECT-TYPE
+    SYNTAX      Counter32
+    MAX-ACCESS  read-only
+    STATUS      obsolete
+    DESCRIPTION
+            "The total number of SNMP PDUs which were generated
+            by the SNMP protocol entity and for which the value
+            of the error-status field was `badValue'."
+    ::= { snmp 22 }
+
+
+
+-- { snmp 23 } is not used
+
+snmpOutGenErrs OBJECT-TYPE
+    SYNTAX      Counter32
+    MAX-ACCESS  read-only
+    STATUS      obsolete
+    DESCRIPTION
+            "The total number of SNMP PDUs which were generated
+            by the SNMP protocol entity and for which the value
+            of the error-status field was `genErr'."
+    ::= { snmp 24 }
+
+snmpOutGetRequests OBJECT-TYPE
+    SYNTAX      Counter32
+    MAX-ACCESS  read-only
+    STATUS      obsolete
+    DESCRIPTION
+            "The total number of SNMP Get-Request PDUs which
+            have been generated by the SNMP protocol entity."
+    ::= { snmp 25 }
+
+snmpOutGetNexts OBJECT-TYPE
+    SYNTAX      Counter32
+    MAX-ACCESS  read-only
+    STATUS      obsolete
+    DESCRIPTION
+            "The total number of SNMP Get-Next PDUs which have
+            been generated by the SNMP protocol entity."
+    ::= { snmp 26 }
+
+snmpOutSetRequests OBJECT-TYPE
+    SYNTAX      Counter32
+    MAX-ACCESS  read-only
+    STATUS      obsolete
+    DESCRIPTION
+            "The total number of SNMP Set-Request PDUs which
+            have been generated by the SNMP protocol entity."
+    ::= { snmp 27 }
+
+snmpOutGetResponses OBJECT-TYPE
+    SYNTAX      Counter32
+    MAX-ACCESS  read-only
+    STATUS      obsolete
+    DESCRIPTION
+            "The total number of SNMP Get-Response PDUs which
+            have been generated by the SNMP protocol entity."
+    ::= { snmp 28 }
+
+
+
+
+snmpOutTraps OBJECT-TYPE
+    SYNTAX      Counter32
+    MAX-ACCESS  read-only
+    STATUS      obsolete
+    DESCRIPTION
+            "The total number of SNMP Trap PDUs which have
+            been generated by the SNMP protocol entity."
+    ::= { snmp 29 }
+
+snmpObsoleteGroup OBJECT-GROUP
+    OBJECTS { snmpOutPkts, snmpInTooBigs, snmpInNoSuchNames,
+              snmpInBadValues, snmpInReadOnlys, snmpInGenErrs,
+              snmpInTotalReqVars, snmpInTotalSetVars,
+              snmpInGetRequests, snmpInGetNexts, snmpInSetRequests,
+              snmpInGetResponses, snmpInTraps, snmpOutTooBigs,
+              snmpOutNoSuchNames, snmpOutBadValues,
+              snmpOutGenErrs, snmpOutGetRequests, snmpOutGetNexts,
+              snmpOutSetRequests, snmpOutGetResponses, snmpOutTraps
+              }
+    STATUS  obsolete
+    DESCRIPTION
+            "A collection of objects from RFC 1213 made obsolete
+            by this MIB module."
+    ::= { snmpMIBGroups 10 }
+
+END
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/Mibs/SNMPv2-SMI
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/Mibs/SNMPv2-SMI	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/Mibs/SNMPv2-SMI	(revision 457)
@@ -0,0 +1,352 @@
+SNMPv2-SMI DEFINITIONS ::= BEGIN
+
+
+-- the path to the root
+
+org            OBJECT IDENTIFIER ::= { iso 3 }  --  "iso" = 1
+dod            OBJECT IDENTIFIER ::= { org 6 }
+internet       OBJECT IDENTIFIER ::= { dod 1 }
+
+directory      OBJECT IDENTIFIER ::= { internet 1 }
+
+mgmt           OBJECT IDENTIFIER ::= { internet 2 }
+mib-2          OBJECT IDENTIFIER ::= { mgmt 1 }
+transmission   OBJECT IDENTIFIER ::= { mib-2 10 }
+
+experimental   OBJECT IDENTIFIER ::= { internet 3 }
+
+private        OBJECT IDENTIFIER ::= { internet 4 }
+enterprises    OBJECT IDENTIFIER ::= { private 1 }
+
+security       OBJECT IDENTIFIER ::= { internet 5 }
+
+snmpV2         OBJECT IDENTIFIER ::= { internet 6 }
+
+-- transport domains
+snmpDomains    OBJECT IDENTIFIER ::= { snmpV2 1 }
+
+-- transport proxies
+snmpProxys     OBJECT IDENTIFIER ::= { snmpV2 2 }
+
+-- module identities
+snmpModules    OBJECT IDENTIFIER ::= { snmpV2 3 }
+
+-- Extended UTCTime, to allow dates with four-digit years
+-- (Note that this definition of ExtUTCTime is not to be IMPORTed
+--  by MIB modules.)
+ExtUTCTime ::= OCTET STRING(SIZE(11 | 13))
+    -- format is YYMMDDHHMMZ or YYYYMMDDHHMMZ
+    --   where: YY   - last two digits of year (only years
+    --                 between 1900-1999)
+    --          YYYY - last four digits of the year (any year)
+    --          MM   - month (01 through 12)
+    --          DD   - day of month (01 through 31)
+    --          HH   - hours (00 through 23)
+    --          MM   - minutes (00 through 59)
+    --          Z    - denotes GMT (the ASCII character Z)
+    --
+    -- For example, "9502192015Z" and "199502192015Z" represent
+    -- 8:15pm GMT on 19 February 1995. Years after 1999 must use
+    -- the four digit year format. Years 1900-1999 may use the
+    -- two or four digit format.
+
+-- definitions for information modules
+
+MODULE-IDENTITY MACRO ::=
+BEGIN
+    TYPE NOTATION ::=
+                  "LAST-UPDATED" value(Update ExtUTCTime)
+                  "ORGANIZATION" Text
+                  "CONTACT-INFO" Text
+                  "DESCRIPTION" Text
+                  RevisionPart
+
+    VALUE NOTATION ::=
+                  value(VALUE OBJECT IDENTIFIER)
+
+    RevisionPart ::=
+                  Revisions
+                | empty
+    Revisions ::=
+                  Revision
+                | Revisions Revision
+    Revision ::=
+                  "REVISION" value(Update ExtUTCTime)
+                  "DESCRIPTION" Text
+
+    -- a character string as defined in section 3.1.1
+    Text ::= value(IA5String)
+END
+
+
+OBJECT-IDENTITY MACRO ::=
+BEGIN
+    TYPE NOTATION ::=
+                  "STATUS" Status
+                  "DESCRIPTION" Text
+                  ReferPart
+
+    VALUE NOTATION ::=
+                  value(VALUE OBJECT IDENTIFIER)
+
+    Status ::=
+                  "current"
+                | "deprecated"
+                | "obsolete"
+
+    ReferPart ::=
+                  "REFERENCE" Text
+                | empty
+
+    -- a character string as defined in section 3.1.1
+    Text ::= value(IA5String)
+END
+
+
+-- names of objects
+-- (Note that these definitions of ObjectName and NotificationName
+--  are not to be IMPORTed by MIB modules.)
+
+ObjectName ::=
+    OBJECT IDENTIFIER
+
+NotificationName ::=
+    OBJECT IDENTIFIER
+
+-- syntax of objects
+
+-- the "base types" defined here are:
+--   3 built-in ASN.1 types: INTEGER, OCTET STRING, OBJECT IDENTIFIER
+--   8 application-defined types: Integer32, IpAddress, Counter32,
+--              Gauge32, Unsigned32, TimeTicks, Opaque, and Counter64
+
+ObjectSyntax ::=
+    CHOICE {
+        simple
+            SimpleSyntax,
+
+          -- note that SEQUENCEs for conceptual tables and
+          -- rows are not mentioned here...
+
+        application-wide
+            ApplicationSyntax
+    }
+
+-- built-in ASN.1 types
+
+SimpleSyntax ::=
+    CHOICE {
+        -- INTEGERs with a more restrictive range
+        -- may also be used
+        integer-value               -- includes Integer32
+            INTEGER (-2147483648..2147483647),
+
+        -- OCTET STRINGs with a more restrictive size
+        -- may also be used
+        string-value
+            OCTET STRING (SIZE (0..65535)),
+
+        objectID-value
+            OBJECT IDENTIFIER
+    }
+
+-- indistinguishable from INTEGER, but never needs more than
+-- 32-bits for a two's complement representation
+Integer32 ::=
+        INTEGER (-2147483648..2147483647)
+
+
+-- application-wide types
+
+ApplicationSyntax ::=
+    CHOICE {
+        ipAddress-value
+            IpAddress,
+
+        counter-value
+            Counter32,
+
+        timeticks-value
+            TimeTicks,
+
+        arbitrary-value
+            Opaque,
+
+        big-counter-value
+            Counter64,
+
+        unsigned-integer-value  -- includes Gauge32
+            Unsigned32
+    }
+
+-- in network-byte order
+-- (this is a tagged type for historical reasons)
+IpAddress ::=
+    [APPLICATION 0]
+        IMPLICIT OCTET STRING (SIZE (4))
+
+-- this wraps
+Counter32 ::=
+    [APPLICATION 1]
+        IMPLICIT INTEGER (0..4294967295)
+
+-- this doesn't wrap
+Gauge32 ::=
+    [APPLICATION 2]
+        IMPLICIT INTEGER (0..4294967295)
+
+-- an unsigned 32-bit quantity
+-- indistinguishable from Gauge32
+Unsigned32 ::=
+    [APPLICATION 2]
+        IMPLICIT INTEGER (0..4294967295)
+
+-- hundredths of seconds since an epoch
+TimeTicks ::=
+    [APPLICATION 3]
+        IMPLICIT INTEGER (0..4294967295)
+
+-- for backward-compatibility only
+Opaque ::=
+    [APPLICATION 4]
+        IMPLICIT OCTET STRING
+
+-- for counters that wrap in less than one hour with only 32 bits
+Counter64 ::=
+    [APPLICATION 6]
+        IMPLICIT INTEGER (0..18446744073709551615)
+
+
+-- definition for objects
+
+OBJECT-TYPE MACRO ::=
+BEGIN
+    TYPE NOTATION ::=
+                  "SYNTAX" Syntax
+                  UnitsPart
+                  "MAX-ACCESS" Access
+                  "STATUS" Status
+                  "DESCRIPTION" Text
+                  ReferPart
+                  IndexPart
+                  DefValPart
+
+    VALUE NOTATION ::=
+                  value(VALUE ObjectName)
+
+    Syntax ::=   -- Must be one of the following:
+                       -- a base type (or its refinement),
+                       -- a textual convention (or its refinement), or
+                       -- a BITS pseudo-type
+                   type
+                | "BITS" "{" NamedBits "}"
+
+    NamedBits ::= NamedBit
+                | NamedBits "," NamedBit
+
+    NamedBit ::=  identifier "(" number ")" -- number is nonnegative
+
+    UnitsPart ::=
+                  "UNITS" Text
+                | empty
+
+    Access ::=
+                  "not-accessible"
+                | "accessible-for-notify"
+                | "read-only"
+                | "read-write"
+                | "read-create"
+
+    Status ::=
+                  "current"
+                | "deprecated"
+                | "obsolete"
+
+    ReferPart ::=
+                  "REFERENCE" Text
+                | empty
+
+    IndexPart ::=
+                  "INDEX"    "{" IndexTypes "}"
+                | "AUGMENTS" "{" Entry      "}"
+                | empty
+    IndexTypes ::=
+                  IndexType
+                | IndexTypes "," IndexType
+    IndexType ::=
+                  "IMPLIED" Index
+                | Index
+    Index ::=
+                    -- use the SYNTAX value of the
+                    -- correspondent OBJECT-TYPE invocation
+                  value(ObjectName)
+    Entry ::=
+                    -- use the INDEX value of the
+                    -- correspondent OBJECT-TYPE invocation
+                  value(ObjectName)
+
+    DefValPart ::= "DEFVAL" "{" Defvalue "}"
+                | empty
+
+    Defvalue ::=  -- must be valid for the type specified in
+                  -- SYNTAX clause of same OBJECT-TYPE macro
+                  value(ObjectSyntax)
+                | "{" BitsValue "}"
+
+    BitsValue ::= BitNames
+                | empty
+
+    BitNames ::=  BitName
+                | BitNames "," BitName
+
+    BitName ::= identifier
+
+    -- a character string as defined in section 3.1.1
+    Text ::= value(IA5String)
+END
+
+
+-- definitions for notifications
+
+NOTIFICATION-TYPE MACRO ::=
+BEGIN
+    TYPE NOTATION ::=
+                  ObjectsPart
+                  "STATUS" Status
+                  "DESCRIPTION" Text
+                  ReferPart
+
+    VALUE NOTATION ::=
+                  value(VALUE NotificationName)
+
+    ObjectsPart ::=
+                  "OBJECTS" "{" Objects "}"
+                | empty
+    Objects ::=
+                  Object
+                | Objects "," Object
+    Object ::=
+                  value(ObjectName)
+
+    Status ::=
+                  "current"
+                | "deprecated"
+                | "obsolete"
+
+    ReferPart ::=
+                  "REFERENCE" Text
+                | empty
+
+    -- a character string as defined in section 3.1.1
+    Text ::= value(IA5String)
+END
+
+-- definitions of administrative identifiers
+
+zeroDotZero    OBJECT-IDENTITY
+    STATUS     current
+    DESCRIPTION
+            "A value used for null identifiers."
+    ::= { 0 0 }
+
+END
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/Mibs/SNMPv2-TC
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/Mibs/SNMPv2-TC	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/Mibs/SNMPv2-TC	(revision 457)
@@ -0,0 +1,786 @@
+SNMPv2-TC DEFINITIONS ::= BEGIN
+
+IMPORTS
+    TimeTicks         FROM SNMPv2-SMI;
+
+
+-- definition of textual conventions
+
+TEXTUAL-CONVENTION MACRO ::=
+BEGIN
+    TYPE NOTATION ::=
+                  DisplayPart
+                  "STATUS" Status
+                  "DESCRIPTION" Text
+                  ReferPart
+                  "SYNTAX" Syntax
+
+    VALUE NOTATION ::=
+                   value(VALUE Syntax)      -- adapted ASN.1
+
+    DisplayPart ::=
+                  "DISPLAY-HINT" Text
+                | empty
+
+    Status ::=
+                  "current"
+                | "deprecated"
+                | "obsolete"
+
+    ReferPart ::=
+                  "REFERENCE" Text
+                | empty
+
+    -- a character string as defined in [2]
+    Text ::= value(IA5String)
+
+    Syntax ::=   -- Must be one of the following:
+                       -- a base type (or its refinement), or
+                       -- a BITS pseudo-type
+                  type
+                | "BITS" "{" NamedBits "}"
+
+    NamedBits ::= NamedBit
+                | NamedBits "," NamedBit
+
+    NamedBit ::=  identifier "(" number ")" -- number is nonnegative
+
+END
+
+
+
+
+DisplayString ::= TEXTUAL-CONVENTION
+    DISPLAY-HINT "255a"
+    STATUS       current
+    DESCRIPTION
+            "Represents textual information taken from the NVT ASCII
+            character set, as defined in pages 4, 10-11 of RFC 854.
+
+            To summarize RFC 854, the NVT ASCII repertoire specifies:
+
+              - the use of character codes 0-127 (decimal)
+
+              - the graphics characters (32-126) are interpreted as
+                US ASCII
+
+              - NUL, LF, CR, BEL, BS, HT, VT and FF have the special
+                meanings specified in RFC 854
+
+              - the other 25 codes have no standard interpretation
+
+              - the sequence 'CR LF' means newline
+
+              - the sequence 'CR NUL' means carriage-return
+
+              - an 'LF' not preceded by a 'CR' means moving to the
+                same column on the next line.
+
+              - the sequence 'CR x' for any x other than LF or NUL is
+                illegal.  (Note that this also means that a string may
+                end with either 'CR LF' or 'CR NUL', but not with CR.)
+
+            Any object defined using this syntax may not exceed 255
+            characters in length."
+    SYNTAX       OCTET STRING (SIZE (0..255))
+
+PhysAddress ::= TEXTUAL-CONVENTION
+    DISPLAY-HINT "1x:"
+    STATUS       current
+    DESCRIPTION
+            "Represents media- or physical-level addresses."
+    SYNTAX       OCTET STRING
+
+
+MacAddress ::= TEXTUAL-CONVENTION
+    DISPLAY-HINT "1x:"
+    STATUS       current
+    DESCRIPTION
+            "Represents an 802 MAC address represented in the
+            `canonical' order defined by IEEE 802.1a, i.e., as if it
+            were transmitted least significant bit first, even though
+            802.5 (in contrast to other 802.x protocols) requires MAC
+            addresses to be transmitted most significant bit first."
+    SYNTAX       OCTET STRING (SIZE (6))
+
+TruthValue ::= TEXTUAL-CONVENTION
+    STATUS       current
+    DESCRIPTION
+            "Represents a boolean value."
+    SYNTAX       INTEGER { true(1), false(2) }
+
+TestAndIncr ::= TEXTUAL-CONVENTION
+    STATUS       current
+    DESCRIPTION
+            "Represents integer-valued information used for atomic
+            operations.  When the management protocol is used to specify
+            that an object instance having this syntax is to be
+            modified, the new value supplied via the management protocol
+            must precisely match the value presently held by the
+            instance.  If not, the management protocol set operation
+            fails with an error of `inconsistentValue'.  Otherwise, if
+            the current value is the maximum value of 2^31-1 (2147483647
+            decimal), then the value held by the instance is wrapped to
+            zero; otherwise, the value held by the instance is
+            incremented by one.  (Note that regardless of whether the
+            management protocol set operation succeeds, the variable-
+            binding in the request and response PDUs are identical.)
+
+            The value of the ACCESS clause for objects having this
+            syntax is either `read-write' or `read-create'.  When an
+            instance of a columnar object having this syntax is created,
+            any value may be supplied via the management protocol.
+
+            When the network management portion of the system is re-
+            initialized, the value of every object instance having this
+            syntax must either be incremented from its value prior to
+            the re-initialization, or (if the value prior to the re-
+            initialization is unknown) be set to a pseudo-randomly
+            generated value."
+    SYNTAX       INTEGER (0..2147483647)
+
+AutonomousType ::= TEXTUAL-CONVENTION
+    STATUS       current
+    DESCRIPTION
+            "Represents an independently extensible type identification
+            value.  It may, for example, indicate a particular sub-tree
+            with further MIB definitions, or define a particular type of
+            protocol or hardware."
+    SYNTAX       OBJECT IDENTIFIER
+
+
+InstancePointer ::= TEXTUAL-CONVENTION
+    STATUS       obsolete
+    DESCRIPTION
+            "A pointer to either a specific instance of a MIB object or
+            a conceptual row of a MIB table in the managed device.  In
+            the latter case, by convention, it is the name of the
+            particular instance of the first accessible columnar object
+            in the conceptual row.
+
+            The two uses of this textual convention are replaced by
+            VariablePointer and RowPointer, respectively."
+    SYNTAX       OBJECT IDENTIFIER
+
+
+VariablePointer ::= TEXTUAL-CONVENTION
+    STATUS       current
+    DESCRIPTION
+            "A pointer to a specific object instance.  For example,
+            sysContact.0 or ifInOctets.3."
+    SYNTAX       OBJECT IDENTIFIER
+
+
+RowPointer ::= TEXTUAL-CONVENTION
+    STATUS       current
+    DESCRIPTION
+            "Represents a pointer to a conceptual row.  The value is the
+            name of the instance of the first accessible columnar object
+            in the conceptual row.
+
+            For example, ifIndex.3 would point to the 3rd row in the
+            ifTable (note that if ifIndex were not-accessible, then
+            ifDescr.3 would be used instead)."
+    SYNTAX       OBJECT IDENTIFIER
+
+RowStatus ::= TEXTUAL-CONVENTION
+    STATUS       current
+    DESCRIPTION
+            "The RowStatus textual convention is used to manage the
+            creation and deletion of conceptual rows, and is used as the
+            value of the SYNTAX clause for the status column of a
+            conceptual row (as described in Section 7.7.1 of [2].)
+            The status column has six defined values:
+
+                 - `active', which indicates that the conceptual row is
+                 available for use by the managed device;
+
+                 - `notInService', which indicates that the conceptual
+                 row exists in the agent, but is unavailable for use by
+                 the managed device (see NOTE below); 'notInService' has
+                 no implication regarding the internal consistency of
+                 the row, availability of resources, or consistency with
+                 the current state of the managed device;
+
+                 - `notReady', which indicates that the conceptual row
+                 exists in the agent, but is missing information
+                 necessary in order to be available for use by the
+                 managed device (i.e., one or more required columns in
+                 the conceptual row have not been instanciated);
+
+                 - `createAndGo', which is supplied by a management
+                 station wishing to create a new instance of a
+                 conceptual row and to have its status automatically set
+                 to active, making it available for use by the managed
+                 device;
+
+                 - `createAndWait', which is supplied by a management
+                 station wishing to create a new instance of a
+                 conceptual row (but not make it available for use by
+                 the managed device); and,
+
+                 - `destroy', which is supplied by a management station
+                 wishing to delete all of the instances associated with
+                 an existing conceptual row.
+
+            Whereas five of the six values (all except `notReady') may
+            be specified in a management protocol set operation, only
+            three values will be returned in response to a management
+            protocol retrieval operation:  `notReady', `notInService' or
+            `active'.  That is, when queried, an existing conceptual row
+            has only three states:  it is either available for use by
+            the managed device (the status column has value `active');
+            it is not available for use by the managed device, though
+            the agent has sufficient information to attempt to make it
+            so (the status column has value `notInService'); or, it is
+            not available for use by the managed device, and an attempt
+            to make it so would fail because the agent has insufficient
+            information (the state column has value `notReady').
+
+                                     NOTE WELL
+
+                 This textual convention may be used for a MIB table,
+                 irrespective of whether the values of that table's
+                 conceptual rows are able to be modified while it is
+                 active, or whether its conceptual rows must be taken
+                 out of service in order to be modified.  That is, it is
+                 the responsibility of the DESCRIPTION clause of the
+                 status column to specify whether the status column must
+                 not be `active' in order for the value of some other
+                 column of the same conceptual row to be modified.  If
+                 such a specification is made, affected columns may be
+                 changed by an SNMP set PDU if the RowStatus would not
+                 be equal to `active' either immediately before or after
+                 processing the PDU.  In other words, if the PDU also
+                 contained a varbind that would change the RowStatus
+                 value, the column in question may be changed if the
+                 RowStatus was not equal to `active' as the PDU was
+                 received, or if the varbind sets the status to a value
+                 other than 'active'.
+
+
+            Also note that whenever any elements of a row exist, the
+            RowStatus column must also exist.
+
+            To summarize the effect of having a conceptual row with a
+            status column having a SYNTAX clause value of RowStatus,
+            consider the following state diagram:
+
+
+                                         STATE
+              +--------------+-----------+-------------+-------------
+              |      A       |     B     |      C      |      D
+              |              |status col.|status column|
+              |status column |    is     |      is     |status column
+    ACTION    |does not exist|  notReady | notInService|  is active
+--------------+--------------+-----------+-------------+-------------
+set status    |noError    ->D|inconsist- |inconsistent-|inconsistent-
+column to     |       or     |   entValue|        Value|        Value
+createAndGo   |inconsistent- |           |             |
+              |         Value|           |             |
+--------------+--------------+-----------+-------------+-------------
+set status    |noError  see 1|inconsist- |inconsistent-|inconsistent-
+column to     |       or     |   entValue|        Value|        Value
+createAndWait |wrongValue    |           |             |
+--------------+--------------+-----------+-------------+-------------
+set status    |inconsistent- |inconsist- |noError      |noError
+column to     |         Value|   entValue|             |
+active        |              |           |             |
+              |              |     or    |             |
+              |              |           |             |
+              |              |see 2   ->D|see 8     ->D|          ->D
+--------------+--------------+-----------+-------------+-------------
+set status    |inconsistent- |inconsist- |noError      |noError   ->C
+column to     |         Value|   entValue|             |
+notInService  |              |           |             |
+              |              |     or    |             |      or
+              |              |           |             |
+              |              |see 3   ->C|          ->C|see 6
+--------------+--------------+-----------+-------------+-------------
+set status    |noError       |noError    |noError      |noError   ->A
+column to     |              |           |             |      or
+destroy       |           ->A|        ->A|          ->A|see 7
+--------------+--------------+-----------+-------------+-------------
+set any other |see 4         |noError    |noError      |see 5
+column to some|              |           |             |
+value         |              |      see 1|          ->C|          ->D
+--------------+--------------+-----------+-------------+-------------
+
+            (1) goto B or C, depending on information available to the
+            agent.
+
+            (2) if other variable bindings included in the same PDU,
+            provide values for all columns which are missing but
+            required, and all columns have acceptable values, then
+            return noError and goto D.
+
+            (3) if other variable bindings included in the same PDU,
+            provide legal values for all columns which are missing but
+            required, then return noError and goto C.
+
+            (4) at the discretion of the agent, the return value may be
+            either:
+
+                 inconsistentName:  because the agent does not choose to
+                 create such an instance when the corresponding
+                 RowStatus instance does not exist, or
+
+                 inconsistentValue:  if the supplied value is
+                 inconsistent with the state of some other MIB object's
+                 value, or
+
+                 noError: because the agent chooses to create the
+                 instance.
+
+            If noError is returned, then the instance of the status
+            column must also be created, and the new state is B or C,
+            depending on the information available to the agent.  If
+            inconsistentName or inconsistentValue is returned, the row
+            remains in state A.
+
+            (5) depending on the MIB definition for the column/table,
+            either noError or inconsistentValue may be returned.
+
+            (6) the return value can indicate one of the following
+            errors:
+
+                 wrongValue: because the agent does not support
+                 notInService (e.g., an agent which does not support
+                 createAndWait), or
+
+                 inconsistentValue: because the agent is unable to take
+                 the row out of service at this time, perhaps because it
+                 is in use and cannot be de-activated.
+
+            (7) the return value can indicate the following error:
+
+                 inconsistentValue: because the agent is unable to
+                 remove the row at this time, perhaps because it is in
+                 use and cannot be de-activated.
+
+            (8) the transition to D can fail, e.g., if the values of the
+            conceptual row are inconsistent, then the error code would
+            be inconsistentValue.
+
+            NOTE: Other processing of (this and other varbinds of) the
+            set request may result in a response other than noError
+            being returned, e.g., wrongValue, noCreation, etc.
+
+
+                              Conceptual Row Creation
+
+            There are four potential interactions when creating a
+            conceptual row:  selecting an instance-identifier which is
+            not in use; creating the conceptual row; initializing any
+            objects for which the agent does not supply a default; and,
+            making the conceptual row available for use by the managed
+            device.
+
+            Interaction 1: Selecting an Instance-Identifier
+
+            The algorithm used to select an instance-identifier varies
+            for each conceptual row.  In some cases, the instance-
+            identifier is semantically significant, e.g., the
+            destination address of a route, and a management station
+            selects the instance-identifier according to the semantics.
+
+            In other cases, the instance-identifier is used solely to
+            distinguish conceptual rows, and a management station
+            without specific knowledge of the conceptual row might
+            examine the instances present in order to determine an
+            unused instance-identifier.  (This approach may be used, but
+            it is often highly sub-optimal; however, it is also a
+            questionable practice for a naive management station to
+            attempt conceptual row creation.)
+
+            Alternately, the MIB module which defines the conceptual row
+            might provide one or more objects which provide assistance
+            in determining an unused instance-identifier.  For example,
+            if the conceptual row is indexed by an integer-value, then
+            an object having an integer-valued SYNTAX clause might be
+            defined for such a purpose, allowing a management station to
+            issue a management protocol retrieval operation.  In order
+            to avoid unnecessary collisions between competing management
+            stations, `adjacent' retrievals of this object should be
+            different.
+
+            Finally, the management station could select a pseudo-random
+            number to use as the index.  In the event that this index
+            was already in use and an inconsistentValue was returned in
+            response to the management protocol set operation, the
+            management station should simply select a new pseudo-random
+            number and retry the operation.
+
+            A MIB designer should choose between the two latter
+            algorithms based on the size of the table (and therefore the
+            efficiency of each algorithm).  For tables in which a large
+            number of entries are expected, it is recommended that a MIB
+            object be defined that returns an acceptable index for
+            creation.  For tables with small numbers of entries, it is
+            recommended that the latter pseudo-random index mechanism be
+            used.
+
+            Interaction 2: Creating the Conceptual Row
+
+            Once an unused instance-identifier has been selected, the
+            management station determines if it wishes to create and
+            activate the conceptual row in one transaction or in a
+            negotiated set of interactions.
+
+            Interaction 2a: Creating and Activating the Conceptual Row
+
+            The management station must first determine the column
+            requirements, i.e., it must determine those columns for
+            which it must or must not provide values.  Depending on the
+            complexity of the table and the management station's
+            knowledge of the agent's capabilities, this determination
+            can be made locally by the management station.  Alternately,
+            the management station issues a management protocol get
+            operation to examine all columns in the conceptual row that
+            it wishes to create.  In response, for each column, there
+            are three possible outcomes:
+
+                 - a value is returned, indicating that some other
+                 management station has already created this conceptual
+                 row.  We return to interaction 1.
+
+                 - the exception `noSuchInstance' is returned,
+                 indicating that the agent implements the object-type
+                 associated with this column, and that this column in at
+                 least one conceptual row would be accessible in the MIB
+                 view used by the retrieval were it to exist. For those
+                 columns to which the agent provides read-create access,
+                 the `noSuchInstance' exception tells the management
+                 station that it should supply a value for this column
+                 when the conceptual row is to be created.
+
+                 - the exception `noSuchObject' is returned, indicating
+                 that the agent does not implement the object-type
+                 associated with this column or that there is no
+                 conceptual row for which this column would be
+                 accessible in the MIB view used by the retrieval.  As
+                 such, the management station can not issue any
+                 management protocol set operations to create an
+                 instance of this column.
+
+            Once the column requirements have been determined, a
+            management protocol set operation is accordingly issued.
+            This operation also sets the new instance of the status
+            column to `createAndGo'.
+
+            When the agent processes the set operation, it verifies that
+            it has sufficient information to make the conceptual row
+            available for use by the managed device.  The information
+            available to the agent is provided by two sources:  the
+            management protocol set operation which creates the
+            conceptual row, and, implementation-specific defaults
+            supplied by the agent (note that an agent must provide
+            implementation-specific defaults for at least those objects
+            which it implements as read-only).  If there is sufficient
+            information available, then the conceptual row is created, a
+            `noError' response is returned, the status column is set to
+            `active', and no further interactions are necessary (i.e.,
+            interactions 3 and 4 are skipped).  If there is insufficient
+            information, then the conceptual row is not created, and the
+            set operation fails with an error of `inconsistentValue'.
+            On this error, the management station can issue a management
+            protocol retrieval operation to determine if this was
+            because it failed to specify a value for a required column,
+            or, because the selected instance of the status column
+            already existed.  In the latter case, we return to
+            interaction 1.  In the former case, the management station
+            can re-issue the set operation with the additional
+            information, or begin interaction 2 again using
+            `createAndWait' in order to negotiate creation of the
+            conceptual row.
+
+                                     NOTE WELL
+
+                 Regardless of the method used to determine the column
+                 requirements, it is possible that the management
+                 station might deem a column necessary when, in fact,
+                 the agent will not allow that particular columnar
+                 instance to be created or written.  In this case, the
+                 management protocol set operation will fail with an
+                 error such as `noCreation' or `notWritable'.  In this
+                 case, the management station decides whether it needs
+                 to be able to set a value for that particular columnar
+                 instance.  If not, the management station re-issues the
+                 management protocol set operation, but without setting
+                 a value for that particular columnar instance;
+                 otherwise, the management station aborts the row
+                 creation algorithm.
+
+            Interaction 2b: Negotiating the Creation of the Conceptual
+            Row
+
+            The management station issues a management protocol set
+            operation which sets the desired instance of the status
+            column to `createAndWait'.  If the agent is unwilling to
+            process a request of this sort, the set operation fails with
+            an error of `wrongValue'.  (As a consequence, such an agent
+            must be prepared to accept a single management protocol set
+            operation, i.e., interaction 2a above, containing all of the
+            columns indicated by its column requirements.)  Otherwise,
+            the conceptual row is created, a `noError' response is
+            returned, and the status column is immediately set to either
+            `notInService' or `notReady', depending on whether it has
+            sufficient information to (attempt to) make the conceptual
+            row available for use by the managed device.  If there is
+            sufficient information available, then the status column is
+            set to `notInService'; otherwise, if there is insufficient
+            information, then the status column is set to `notReady'.
+            Regardless, we proceed to interaction 3.
+
+            Interaction 3: Initializing non-defaulted Objects
+
+            The management station must now determine the column
+            requirements.  It issues a management protocol get operation
+            to examine all columns in the created conceptual row.  In
+            the response, for each column, there are three possible
+            outcomes:
+
+                 - a value is returned, indicating that the agent
+                 implements the object-type associated with this column
+                 and had sufficient information to provide a value.  For
+                 those columns to which the agent provides read-create
+                 access (and for which the agent allows their values to
+                 be changed after their creation), a value return tells
+                 the management station that it may issue additional
+                 management protocol set operations, if it desires, in
+                 order to change the value associated with this column.
+
+                 - the exception `noSuchInstance' is returned,
+                 indicating that the agent implements the object-type
+                 associated with this column, and that this column in at
+                 least one conceptual row would be accessible in the MIB
+                 view used by the retrieval were it to exist. However,
+                 the agent does not have sufficient information to
+                 provide a value, and until a value is provided, the
+                 conceptual row may not be made available for use by the
+                 managed device.  For those columns to which the agent
+                 provides read-create access, the `noSuchInstance'
+                 exception tells the management station that it must
+                 issue additional management protocol set operations, in
+                 order to provide a value associated with this column.
+
+                 - the exception `noSuchObject' is returned, indicating
+                 that the agent does not implement the object-type
+                 associated with this column or that there is no
+                 conceptual row for which this column would be
+                 accessible in the MIB view used by the retrieval.  As
+                 such, the management station can not issue any
+                 management protocol set operations to create an
+                 instance of this column.
+
+            If the value associated with the status column is
+            `notReady', then the management station must first deal with
+            all `noSuchInstance' columns, if any.  Having done so, the
+            value of the status column becomes `notInService', and we
+            proceed to interaction 4.
+
+            Interaction 4: Making the Conceptual Row Available
+
+            Once the management station is satisfied with the values
+            associated with the columns of the conceptual row, it issues
+            a management protocol set operation to set the status column
+            to `active'.  If the agent has sufficient information to
+            make the conceptual row available for use by the managed
+            device, the management protocol set operation succeeds (a
+            `noError' response is returned).  Otherwise, the management
+            protocol set operation fails with an error of
+            `inconsistentValue'.
+
+                                     NOTE WELL
+
+                 A conceptual row having a status column with value
+                 `notInService' or `notReady' is unavailable to the
+                 managed device.  As such, it is possible for the
+                 managed device to create its own instances during the
+                 time between the management protocol set operation
+                 which sets the status column to `createAndWait' and the
+                 management protocol set operation which sets the status
+                 column to `active'.  In this case, when the management
+                 protocol set operation is issued to set the status
+                 column to `active', the values held in the agent
+                 supersede those used by the managed device.
+
+            If the management station is prevented from setting the
+            status column to `active' (e.g., due to management station
+            or network failure) the conceptual row will be left in the
+            `notInService' or `notReady' state, consuming resources
+            indefinitely.  The agent must detect conceptual rows that
+            have been in either state for an abnormally long period of
+            time and remove them.  It is the responsibility of the
+            DESCRIPTION clause of the status column to indicate what an
+            abnormally long period of time would be.  This period of
+            time should be long enough to allow for human response time
+            (including `think time') between the creation of the
+            conceptual row and the setting of the status to `active'.
+            In the absence of such information in the DESCRIPTION
+            clause, it is suggested that this period be approximately 5
+            minutes in length.  This removal action applies not only to
+            newly-created rows, but also to previously active rows which
+            are set to, and left in, the notInService state for a
+            prolonged period exceeding that which is considered normal
+            for such a conceptual row.
+
+                             Conceptual Row Suspension
+
+            When a conceptual row is `active', the management station
+            may issue a management protocol set operation which sets the
+            instance of the status column to `notInService'.  If the
+            agent is unwilling to do so, the set operation fails with an
+            error of `wrongValue' or `inconsistentValue'.  Otherwise,
+            the conceptual row is taken out of service, and a `noError'
+            response is returned.  It is the responsibility of the
+            DESCRIPTION clause of the status column to indicate under
+            what circumstances the status column should be taken out of
+            service (e.g., in order for the value of some other column
+            of the same conceptual row to be modified).
+
+
+                              Conceptual Row Deletion
+
+            For deletion of conceptual rows, a management protocol set
+            operation is issued which sets the instance of the status
+            column to `destroy'.  This request may be made regardless of
+            the current value of the status column (e.g., it is possible
+            to delete conceptual rows which are either `notReady',
+            `notInService' or `active'.)  If the operation succeeds,
+            then all instances associated with the conceptual row are
+            immediately removed."
+    SYNTAX       INTEGER {
+                     -- the following two values are states:
+                     -- these values may be read or written
+                     active(1),
+                     notInService(2),
+
+                     -- the following value is a state:
+                     -- this value may be read, but not written
+                     notReady(3),
+
+                     -- the following three values are
+                     -- actions: these values may be written,
+                     --   but are never read
+                     createAndGo(4),
+                     createAndWait(5),
+                     destroy(6)
+                 }
+
+TimeStamp ::= TEXTUAL-CONVENTION
+    STATUS       current
+    DESCRIPTION
+            "The value of the sysUpTime object at which a specific
+            occurrence happened.  The specific occurrence must be
+            defined in the description of any object defined using this
+            type.
+
+            If sysUpTime is reset to zero as a result of a re-
+            initialization of the network management (sub)system, then
+            the values of all TimeStamp objects are also reset.
+            However, after approximately 497 days without a re-
+            initialization, the sysUpTime object will reach 2^^32-1 and
+            then increment around to zero; in this case, existing values
+            of TimeStamp objects do not change.  This can lead to
+            ambiguities in the value of TimeStamp objects."
+    SYNTAX       TimeTicks
+
+
+TimeInterval ::= TEXTUAL-CONVENTION
+    STATUS       current
+    DESCRIPTION
+            "A period of time, measured in units of 0.01 seconds."
+    SYNTAX       INTEGER (0..2147483647)
+
+DateAndTime ::= TEXTUAL-CONVENTION
+    DISPLAY-HINT "2d-1d-1d,1d:1d:1d.1d,1a1d:1d"
+    STATUS       current
+    DESCRIPTION
+            "A date-time specification.
+
+            field  octets  contents                  range
+            -----  ------  --------                  -----
+              1      1-2   year*                     0..65536
+              2       3    month                     1..12
+              3       4    day                       1..31
+              4       5    hour                      0..23
+              5       6    minutes                   0..59
+              6       7    seconds                   0..60
+                           (use 60 for leap-second)
+              7       8    deci-seconds              0..9
+              8       9    direction from UTC        '+' / '-'
+              9      10    hours from UTC*           0..13
+             10      11    minutes from UTC          0..59
+
+            * Notes:
+            - the value of year is in network-byte order
+            - daylight saving time in New Zealand is +13
+
+            For example, Tuesday May 26, 1992 at 1:30:15 PM EDT would be
+            displayed as:
+
+                             1992-5-26,13:30:15.0,-4:0
+
+            Note that if only local time is known, then timezone
+            information (fields 8-10) is not present."
+    SYNTAX       OCTET STRING (SIZE (8 | 11))
+
+
+StorageType ::= TEXTUAL-CONVENTION
+    STATUS       current
+    DESCRIPTION
+            "Describes the memory realization of a conceptual row.  A
+            row which is volatile(2) is lost upon reboot.  A row which
+            is either nonVolatile(3), permanent(4) or readOnly(5), is
+            backed up by stable storage.  A row which is permanent(4)
+            can be changed but not deleted.  A row which is readOnly(5)
+            cannot be changed nor deleted.
+
+            If the value of an object with this syntax is either
+            permanent(4) or readOnly(5), it cannot be written.
+            Conversely, if the value is either other(1), volatile(2) or
+            nonVolatile(3), it cannot be modified to be permanent(4) or
+            readOnly(5).  (All illegal modifications result in a
+            'wrongValue' error.)
+
+            Every usage of this textual convention is required to
+            specify the columnar objects which a permanent(4) row must
+            at a minimum allow to be writable."
+    SYNTAX       INTEGER {
+                     other(1),       -- eh?
+                     volatile(2),    -- e.g., in RAM
+                     nonVolatile(3), -- e.g., in NVRAM
+                     permanent(4),   -- e.g., partially in ROM
+                     readOnly(5)     -- e.g., completely in ROM
+                 }
+
+TDomain ::= TEXTUAL-CONVENTION
+    STATUS       current
+    DESCRIPTION
+          "Denotes a kind of transport service.
+
+          Some possible values, such as snmpUDPDomain, are defined in
+          the SNMPv2-TM MIB module.  Other possible values are defined
+          in other MIB modules."
+    REFERENCE    "The SNMPv2-TM MIB module is defined in RFC 1906."
+    SYNTAX       OBJECT IDENTIFIER
+
+
+TAddress ::= TEXTUAL-CONVENTION
+    STATUS       current
+    DESCRIPTION
+          "Denotes a transport service address.
+
+          A TAddress value is always interpreted within the context of a
+          TDomain value.  Thus, each definition of a TDomain value must
+          be accompanied by a definition of a textual convention for use
+          with that TDomain.  Some possible textual conventions, such as
+          SnmpUDPAddress for snmpUDPDomain, are defined in the SNMPv2-TM
+          MIB module.  Other possible textual conventions are defined in
+          other MIB modules."
+    REFERENCE    "The SNMPv2-TM MIB module is defined in RFC 1906."
+    SYNTAX       OCTET STRING (SIZE (1..255))
+
+
+END
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/Mibs/SNMPv2-TM
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/Mibs/SNMPv2-TM	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/Mibs/SNMPv2-TM	(revision 457)
@@ -0,0 +1,194 @@
+SNMPv2-TM DEFINITIONS ::= BEGIN
+
+IMPORTS
+    MODULE-IDENTITY, OBJECT-IDENTITY,
+    snmpModules, snmpDomains, snmpProxys
+        FROM SNMPv2-SMI
+    TEXTUAL-CONVENTION
+        FROM SNMPv2-TC;
+
+snmpv2tm MODULE-IDENTITY
+    LAST-UPDATED "200210160000Z"
+    ORGANIZATION "IETF SNMPv3 Working Group"
+    CONTACT-INFO
+            "WG-EMail:   snmpv3@lists.tislabs.com
+             Subscribe:  snmpv3-request@lists.tislabs.com
+
+             Co-Chair:   Russ Mundy
+                         Network Associates Laboratories
+             postal:     15204 Omega Drive, Suite 300
+                         Rockville, MD 20850-4601
+                         USA
+             EMail:      mundy@tislabs.com
+             phone:      +1 301 947-7107
+
+
+
+             Co-Chair:   David Harrington
+                         Enterasys Networks
+             postal:     35 Industrial Way
+                         P. O. Box 5005
+                         Rochester, NH 03866-5005
+                         USA
+             EMail:      dbh@enterasys.com
+             phone:      +1 603 337-2614
+
+             Editor:     Randy Presuhn
+                         BMC Software, Inc.
+             postal:     2141 North First Street
+                         San Jose, CA 95131
+                         USA
+             EMail:      randy_presuhn@bmc.com
+             phone:      +1 408 546-1006"
+    DESCRIPTION
+            "The MIB module for SNMP transport mappings.
+
+             Copyright (C) The Internet Society (2002). This
+             version of this MIB module is part of RFC 3417;
+             see the RFC itself for full legal notices.
+            "
+    REVISION     "200210160000Z"
+    DESCRIPTION
+            "Clarifications, published as RFC 3417."
+    REVISION    "199601010000Z"
+    DESCRIPTION
+            "Clarifications, published as RFC 1906."
+    REVISION    "199304010000Z"
+    DESCRIPTION
+            "The initial version, published as RFC 1449."
+    ::= { snmpModules 19 }
+
+-- SNMP over UDP over IPv4
+
+snmpUDPDomain  OBJECT-IDENTITY
+    STATUS     current
+    DESCRIPTION
+            "The SNMP over UDP over IPv4 transport domain.
+            The corresponding transport address is of type
+            SnmpUDPAddress."
+    ::= { snmpDomains 1 }
+
+
+
+
+
+
+
+
+SnmpUDPAddress ::= TEXTUAL-CONVENTION
+    DISPLAY-HINT "1d.1d.1d.1d/2d"
+    STATUS       current
+    DESCRIPTION
+            "Represents a UDP over IPv4 address:
+
+               octets   contents        encoding
+                1-4     IP-address      network-byte order
+                5-6     UDP-port        network-byte order
+            "
+    SYNTAX       OCTET STRING (SIZE (6))
+
+-- SNMP over OSI
+
+snmpCLNSDomain OBJECT-IDENTITY
+    STATUS     current
+    DESCRIPTION
+            "The SNMP over CLNS transport domain.
+            The corresponding transport address is of type
+            SnmpOSIAddress."
+    ::= { snmpDomains 2 }
+
+snmpCONSDomain OBJECT-IDENTITY
+    STATUS     current
+    DESCRIPTION
+            "The SNMP over CONS transport domain.
+            The corresponding transport address is of type
+            SnmpOSIAddress."
+    ::= { snmpDomains 3 }
+
+SnmpOSIAddress ::= TEXTUAL-CONVENTION
+    DISPLAY-HINT "*1x:/1x:"
+    STATUS       current
+    DESCRIPTION
+            "Represents an OSI transport-address:
+
+          octets   contents           encoding
+             1     length of NSAP     'n' as an unsigned-integer
+                                         (either 0 or from 3 to 20)
+          2..(n+1) NSAP                concrete binary representation
+          (n+2)..m TSEL                string of (up to 64) octets
+            "
+    SYNTAX       OCTET STRING (SIZE (1 | 4..85))
+
+
+
+
+
+
+
+
+-- SNMP over DDP
+
+snmpDDPDomain  OBJECT-IDENTITY
+    STATUS     current
+    DESCRIPTION
+            "The SNMP over DDP transport domain.  The corresponding
+            transport address is of type SnmpNBPAddress."
+    ::= { snmpDomains 4 }
+
+SnmpNBPAddress ::= TEXTUAL-CONVENTION
+    STATUS       current
+    DESCRIPTION
+            "Represents an NBP name:
+
+         octets        contents          encoding
+            1          length of object  'n' as an unsigned integer
+          2..(n+1)     object            string of (up to 32) octets
+           n+2         length of type    'p' as an unsigned integer
+      (n+3)..(n+2+p)   type              string of (up to 32) octets
+          n+3+p        length of zone    'q' as an unsigned integer
+    (n+4+p)..(n+3+p+q) zone              string of (up to 32) octets
+
+            For comparison purposes, strings are
+            case-insensitive. All strings may contain any octet
+            other than 255 (hex ff)."
+    SYNTAX       OCTET STRING (SIZE (3..99))
+
+-- SNMP over IPX
+
+snmpIPXDomain  OBJECT-IDENTITY
+    STATUS     current
+    DESCRIPTION
+            "The SNMP over IPX transport domain.  The corresponding
+            transport address is of type SnmpIPXAddress."
+    ::= { snmpDomains 5 }
+
+SnmpIPXAddress ::= TEXTUAL-CONVENTION
+    DISPLAY-HINT "4x.1x:1x:1x:1x:1x:1x.2d"
+    STATUS       current
+    DESCRIPTION
+            "Represents an IPX address:
+
+               octets   contents            encoding
+                1-4     network-number      network-byte order
+                5-10    physical-address    network-byte order
+               11-12    socket-number       network-byte order
+            "
+    SYNTAX       OCTET STRING (SIZE (12))
+
+
+
+-- for proxy to SNMPv1 (RFC 1157)
+
+rfc1157Proxy   OBJECT IDENTIFIER ::= { snmpProxys 1 }
+
+rfc1157Domain  OBJECT-IDENTITY
+    STATUS     deprecated
+    DESCRIPTION
+            "The transport domain for SNMPv1 over UDP over IPv4.
+            The corresponding transport address is of type
+            SnmpUDPAddress."
+    ::= { rfc1157Proxy 1 }
+
+--  ::= { rfc1157Proxy 2 }            this OID is obsolete
+
+END
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/Mibs/TCP-MIB
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/Mibs/TCP-MIB	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/Mibs/TCP-MIB	(revision 457)
@@ -0,0 +1,829 @@
+TCP-MIB DEFINITIONS ::= BEGIN
+
+IMPORTS
+    MODULE-IDENTITY, OBJECT-TYPE, Integer32, Unsigned32,
+    Gauge32, Counter32, Counter64, IpAddress, mib-2
+                                       FROM SNMPv2-SMI
+    MODULE-COMPLIANCE, OBJECT-GROUP    FROM SNMPv2-CONF
+    InetAddress, InetAddressType,
+    InetPortNumber                     FROM INET-ADDRESS-MIB;
+
+tcpMIB MODULE-IDENTITY
+    LAST-UPDATED "200502180000Z"  -- 18 February 2005
+    ORGANIZATION
+           "IETF IPv6 MIB Revision Team
+            http://www.ietf.org/html.charters/ipv6-charter.html"
+    CONTACT-INFO
+           "Rajiv Raghunarayan (editor)
+
+            Cisco Systems Inc.
+            170 West Tasman Drive
+            San Jose, CA 95134
+
+            Phone: +1 408 853 9612
+            Email: <raraghun@cisco.com>
+
+            Send comments to <ipv6@ietf.org>"
+    DESCRIPTION
+           "The MIB module for managing TCP implementations.
+
+            Copyright (C) The Internet Society (2005). This version
+            of this MIB module is a part of RFC 4022; see the RFC
+            itself for full legal notices."
+    REVISION      "200502180000Z"  -- 18 February 2005
+    DESCRIPTION
+           "IP version neutral revision, published as RFC 4022."
+    REVISION      "9411010000Z"
+    DESCRIPTION
+           "Initial SMIv2 version, published as RFC 2012."
+    REVISION      "9103310000Z"
+    DESCRIPTION
+           "The initial revision of this MIB module was part of
+            MIB-II."
+    ::= { mib-2 49 }
+
+-- the TCP base variables group
+
+
+
+
+tcp      OBJECT IDENTIFIER ::= { mib-2 6 }
+
+-- Scalars
+
+tcpRtoAlgorithm OBJECT-TYPE
+    SYNTAX      INTEGER {
+                    other(1),    -- none of the following
+                    constant(2), -- a constant rto
+                    rsre(3),     -- MIL-STD-1778, Appendix B
+                    vanj(4),     -- Van Jacobson's algorithm
+                    rfc2988(5)   -- RFC 2988
+                }
+    MAX-ACCESS read-only
+    STATUS     current
+    DESCRIPTION
+           "The algorithm used to determine the timeout value used for
+            retransmitting unacknowledged octets."
+    ::= { tcp 1 }
+
+tcpRtoMin OBJECT-TYPE
+    SYNTAX     Integer32 (0..2147483647)
+    UNITS      "milliseconds"
+    MAX-ACCESS read-only
+    STATUS     current
+    DESCRIPTION
+           "The minimum value permitted by a TCP implementation for
+            the retransmission timeout, measured in milliseconds.
+            More refined semantics for objects of this type depend
+            on the algorithm used to determine the retransmission
+            timeout; in particular, the IETF standard algorithm
+            rfc2988(5) provides a minimum value."
+    ::= { tcp 2 }
+
+tcpRtoMax OBJECT-TYPE
+    SYNTAX     Integer32 (0..2147483647)
+    UNITS      "milliseconds"
+    MAX-ACCESS read-only
+    STATUS     current
+    DESCRIPTION
+           "The maximum value permitted by a TCP implementation for
+            the retransmission timeout, measured in milliseconds.
+            More refined semantics for objects of this type depend
+            on the algorithm used to determine the retransmission
+            timeout; in particular, the IETF standard algorithm
+            rfc2988(5) provides an upper bound (as part of an
+            adaptive backoff algorithm)."
+    ::= { tcp 3 }
+
+
+
+
+tcpMaxConn OBJECT-TYPE
+    SYNTAX     Integer32 (-1 | 0..2147483647)
+    MAX-ACCESS read-only
+    STATUS     current
+    DESCRIPTION
+           "The limit on the total number of TCP connections the entity
+            can support.  In entities where the maximum number of
+            connections is dynamic, this object should contain the
+            value -1."
+    ::= { tcp 4 }
+
+tcpActiveOpens OBJECT-TYPE
+    SYNTAX     Counter32
+    MAX-ACCESS read-only
+    STATUS     current
+    DESCRIPTION
+           "The number of times that TCP connections have made a direct
+            transition to the SYN-SENT state from the CLOSED state.
+
+            Discontinuities in the value of this counter are
+            indicated via discontinuities in the value of sysUpTime."
+    ::= { tcp 5 }
+
+tcpPassiveOpens OBJECT-TYPE
+    SYNTAX     Counter32
+    MAX-ACCESS read-only
+    STATUS     current
+    DESCRIPTION
+           "The number of times TCP connections have made a direct
+            transition to the SYN-RCVD state from the LISTEN state.
+
+            Discontinuities in the value of this counter are
+            indicated via discontinuities in the value of sysUpTime."
+    ::= { tcp 6 }
+
+tcpAttemptFails OBJECT-TYPE
+    SYNTAX     Counter32
+    MAX-ACCESS read-only
+    STATUS     current
+    DESCRIPTION
+           "The number of times that TCP connections have made a direct
+            transition to the CLOSED state from either the SYN-SENT
+            state or the SYN-RCVD state, plus the number of times that
+            TCP connections have made a direct transition to the
+            LISTEN state from the SYN-RCVD state.
+
+            Discontinuities in the value of this counter are
+            indicated via discontinuities in the value of sysUpTime."
+
+
+
+    ::= { tcp 7 }
+
+tcpEstabResets OBJECT-TYPE
+    SYNTAX     Counter32
+    MAX-ACCESS read-only
+    STATUS     current
+    DESCRIPTION
+           "The number of times that TCP connections have made a direct
+            transition to the CLOSED state from either the ESTABLISHED
+            state or the CLOSE-WAIT state.
+
+            Discontinuities in the value of this counter are
+            indicated via discontinuities in the value of sysUpTime."
+    ::= { tcp 8 }
+
+tcpCurrEstab OBJECT-TYPE
+    SYNTAX     Gauge32
+    MAX-ACCESS read-only
+    STATUS     current
+    DESCRIPTION
+           "The number of TCP connections for which the current state
+            is either ESTABLISHED or CLOSE-WAIT."
+    ::= { tcp 9 }
+
+tcpInSegs OBJECT-TYPE
+    SYNTAX     Counter32
+    MAX-ACCESS read-only
+    STATUS     current
+    DESCRIPTION
+           "The total number of segments received, including those
+            received in error.  This count includes segments received
+            on currently established connections.
+
+            Discontinuities in the value of this counter are
+            indicated via discontinuities in the value of sysUpTime."
+    ::= { tcp 10 }
+
+tcpOutSegs OBJECT-TYPE
+    SYNTAX     Counter32
+    MAX-ACCESS read-only
+    STATUS     current
+    DESCRIPTION
+           "The total number of segments sent, including those on
+            current connections but excluding those containing only
+            retransmitted octets.
+
+            Discontinuities in the value of this counter are
+            indicated via discontinuities in the value of sysUpTime."
+
+
+
+    ::= { tcp 11 }
+
+tcpRetransSegs OBJECT-TYPE
+    SYNTAX     Counter32
+    MAX-ACCESS read-only
+    STATUS     current
+    DESCRIPTION
+           "The total number of segments retransmitted; that is, the
+            number of TCP segments transmitted containing one or more
+            previously transmitted octets.
+
+            Discontinuities in the value of this counter are
+            indicated via discontinuities in the value of sysUpTime."
+    ::= { tcp 12 }
+
+tcpInErrs OBJECT-TYPE
+    SYNTAX     Counter32
+    MAX-ACCESS read-only
+    STATUS     current
+    DESCRIPTION
+           "The total number of segments received in error (e.g., bad
+            TCP checksums).
+
+            Discontinuities in the value of this counter are
+            indicated via discontinuities in the value of sysUpTime."
+    ::= { tcp 14 }
+
+tcpOutRsts OBJECT-TYPE
+    SYNTAX     Counter32
+    MAX-ACCESS read-only
+    STATUS     current
+    DESCRIPTION
+           "The number of TCP segments sent containing the RST flag.
+
+            Discontinuities in the value of this counter are
+            indicated via discontinuities in the value of sysUpTime."
+    ::= { tcp 15 }
+
+-- { tcp 16 } was used to represent the ipv6TcpConnTable in RFC 2452,
+-- which has since been obsoleted.  It MUST not be used.
+
+tcpHCInSegs OBJECT-TYPE
+    SYNTAX     Counter64
+    MAX-ACCESS read-only
+    STATUS     current
+    DESCRIPTION
+           "The total number of segments received, including those
+            received in error.  This count includes segments received
+
+
+
+            on currently established connections.  This object is
+            the 64-bit equivalent of tcpInSegs.
+
+            Discontinuities in the value of this counter are
+            indicated via discontinuities in the value of sysUpTime."
+    ::= { tcp 17 }
+
+tcpHCOutSegs OBJECT-TYPE
+    SYNTAX     Counter64
+    MAX-ACCESS read-only
+    STATUS     current
+    DESCRIPTION
+           "The total number of segments sent, including those on
+            current connections but excluding those containing only
+            retransmitted octets.  This object is the 64-bit
+            equivalent of tcpOutSegs.
+
+            Discontinuities in the value of this counter are
+            indicated via discontinuities in the value of sysUpTime."
+    ::= { tcp 18 }
+
+
+-- The TCP Connection table
+
+tcpConnectionTable OBJECT-TYPE
+    SYNTAX     SEQUENCE OF TcpConnectionEntry
+    MAX-ACCESS not-accessible
+    STATUS     current
+    DESCRIPTION
+           "A table containing information about existing TCP
+            connections.  Note that unlike earlier TCP MIBs, there
+            is a separate table for connections in the LISTEN state."
+    ::= { tcp 19 }
+
+tcpConnectionEntry OBJECT-TYPE
+    SYNTAX     TcpConnectionEntry
+    MAX-ACCESS not-accessible
+    STATUS     current
+    DESCRIPTION
+           "A conceptual row of the tcpConnectionTable containing
+            information about a particular current TCP connection.
+            Each row of this table is transient in that it ceases to
+            exist when (or soon after) the connection makes the
+            transition to the CLOSED state."
+    INDEX   { tcpConnectionLocalAddressType,
+              tcpConnectionLocalAddress,
+              tcpConnectionLocalPort,
+              tcpConnectionRemAddressType,
+
+
+
+              tcpConnectionRemAddress,
+              tcpConnectionRemPort }
+    ::= { tcpConnectionTable 1 }
+
+TcpConnectionEntry ::= SEQUENCE {
+        tcpConnectionLocalAddressType   InetAddressType,
+        tcpConnectionLocalAddress       InetAddress,
+        tcpConnectionLocalPort          InetPortNumber,
+        tcpConnectionRemAddressType     InetAddressType,
+        tcpConnectionRemAddress         InetAddress,
+        tcpConnectionRemPort            InetPortNumber,
+        tcpConnectionState              INTEGER,
+        tcpConnectionProcess            Unsigned32
+    }
+
+tcpConnectionLocalAddressType OBJECT-TYPE
+    SYNTAX     InetAddressType
+    MAX-ACCESS not-accessible
+    STATUS     current
+    DESCRIPTION
+           "The address type of tcpConnectionLocalAddress."
+    ::= { tcpConnectionEntry 1 }
+
+tcpConnectionLocalAddress OBJECT-TYPE
+    SYNTAX     InetAddress
+    MAX-ACCESS not-accessible
+    STATUS     current
+    DESCRIPTION
+           "The local IP address for this TCP connection.  The type
+            of this address is determined by the value of
+            tcpConnectionLocalAddressType.
+
+            As this object is used in the index for the
+            tcpConnectionTable, implementors should be
+            careful not to create entries that would result in OIDs
+            with more than 128 subidentifiers; otherwise the information
+            cannot be accessed by using SNMPv1, SNMPv2c, or SNMPv3."
+    ::= { tcpConnectionEntry 2 }
+
+tcpConnectionLocalPort OBJECT-TYPE
+    SYNTAX     InetPortNumber
+    MAX-ACCESS not-accessible
+    STATUS     current
+    DESCRIPTION
+           "The local port number for this TCP connection."
+    ::= { tcpConnectionEntry 3 }
+
+tcpConnectionRemAddressType OBJECT-TYPE
+
+
+
+    SYNTAX     InetAddressType
+    MAX-ACCESS not-accessible
+    STATUS     current
+    DESCRIPTION
+           "The address type of tcpConnectionRemAddress."
+    ::= { tcpConnectionEntry 4 }
+
+tcpConnectionRemAddress OBJECT-TYPE
+    SYNTAX     InetAddress
+    MAX-ACCESS not-accessible
+    STATUS     current
+    DESCRIPTION
+           "The remote IP address for this TCP connection.  The type
+            of this address is determined by the value of
+            tcpConnectionRemAddressType.
+
+            As this object is used in the index for the
+            tcpConnectionTable, implementors should be
+            careful not to create entries that would result in OIDs
+            with more than 128 subidentifiers; otherwise the information
+            cannot be accessed by using SNMPv1, SNMPv2c, or SNMPv3."
+    ::= { tcpConnectionEntry 5 }
+
+tcpConnectionRemPort OBJECT-TYPE
+    SYNTAX     InetPortNumber
+    MAX-ACCESS not-accessible
+    STATUS     current
+    DESCRIPTION
+           "The remote port number for this TCP connection."
+    ::= { tcpConnectionEntry 6 }
+
+tcpConnectionState OBJECT-TYPE
+    SYNTAX     INTEGER {
+                    closed(1),
+                    listen(2),
+                    synSent(3),
+                    synReceived(4),
+                    established(5),
+                    finWait1(6),
+                    finWait2(7),
+                    closeWait(8),
+                    lastAck(9),
+                    closing(10),
+                    timeWait(11),
+                    deleteTCB(12)
+                }
+    MAX-ACCESS read-write
+    STATUS     current
+
+
+
+    DESCRIPTION
+           "The state of this TCP connection.
+
+            The value listen(2) is included only for parallelism to the
+            old tcpConnTable and should not be used.  A connection in
+            LISTEN state should be present in the tcpListenerTable.
+
+            The only value that may be set by a management station is
+            deleteTCB(12).  Accordingly, it is appropriate for an agent
+            to return a `badValue' response if a management station
+            attempts to set this object to any other value.
+
+            If a management station sets this object to the value
+            deleteTCB(12), then the TCB (as defined in [RFC793]) of
+            the corresponding connection on the managed node is
+            deleted, resulting in immediate termination of the
+            connection.
+
+            As an implementation-specific option, a RST segment may be
+            sent from the managed node to the other TCP endpoint (note,
+            however, that RST segments are not sent reliably)."
+    ::= { tcpConnectionEntry 7 }
+
+tcpConnectionProcess OBJECT-TYPE
+    SYNTAX     Unsigned32
+    MAX-ACCESS read-only
+    STATUS     current
+    DESCRIPTION
+           "The system's process ID for the process associated with
+            this connection, or zero if there is no such process.  This
+            value is expected to be the same as HOST-RESOURCES-MIB::
+            hrSWRunIndex or SYSAPPL-MIB::sysApplElmtRunIndex for some
+            row in the appropriate tables."
+    ::= { tcpConnectionEntry 8 }
+
+-- The TCP Listener table
+
+tcpListenerTable OBJECT-TYPE
+    SYNTAX     SEQUENCE OF TcpListenerEntry
+    MAX-ACCESS not-accessible
+    STATUS     current
+    DESCRIPTION
+           "A table containing information about TCP listeners.  A
+            listening application can be represented in three
+            possible ways:
+
+            1. An application that is willing to accept both IPv4 and
+               IPv6 datagrams is represented by
+
+
+
+               a tcpListenerLocalAddressType of unknown (0) and
+               a tcpListenerLocalAddress of ''h (a zero-length
+               octet-string).
+
+            2. An application that is willing to accept only IPv4 or
+               IPv6 datagrams is represented by a
+               tcpListenerLocalAddressType of the appropriate address
+               type and a tcpListenerLocalAddress of '0.0.0.0' or '::'
+               respectively.
+
+            3. An application that is listening for data destined
+               only to a specific IP address, but from any remote
+               system, is represented by a tcpListenerLocalAddressType
+               of an appropriate address type, with
+               tcpListenerLocalAddress as the specific local address.
+
+            NOTE: The address type in this table represents the
+            address type used for the communication, irrespective
+            of the higher-layer abstraction.  For example, an
+            application using IPv6 'sockets' to communicate via
+            IPv4 between ::ffff:10.0.0.1 and ::ffff:10.0.0.2 would
+            use InetAddressType ipv4(1))."
+    ::= { tcp 20 }
+
+tcpListenerEntry OBJECT-TYPE
+    SYNTAX     TcpListenerEntry
+    MAX-ACCESS not-accessible
+    STATUS     current
+    DESCRIPTION
+           "A conceptual row of the tcpListenerTable containing
+            information about a particular TCP listener."
+    INDEX   { tcpListenerLocalAddressType,
+              tcpListenerLocalAddress,
+              tcpListenerLocalPort }
+    ::= { tcpListenerTable 1 }
+
+TcpListenerEntry ::= SEQUENCE {
+        tcpListenerLocalAddressType       InetAddressType,
+        tcpListenerLocalAddress           InetAddress,
+        tcpListenerLocalPort              InetPortNumber,
+        tcpListenerProcess                Unsigned32
+    }
+
+tcpListenerLocalAddressType OBJECT-TYPE
+    SYNTAX     InetAddressType
+    MAX-ACCESS not-accessible
+    STATUS     current
+    DESCRIPTION
+
+
+
+           "The address type of tcpListenerLocalAddress.  The value
+            should be unknown (0) if connection initiations to all
+            local IP addresses are accepted."
+    ::= { tcpListenerEntry 1 }
+
+tcpListenerLocalAddress OBJECT-TYPE
+    SYNTAX     InetAddress
+    MAX-ACCESS not-accessible
+    STATUS     current
+    DESCRIPTION
+           "The local IP address for this TCP connection.
+
+            The value of this object can be represented in three
+            possible ways, depending on the characteristics of the
+            listening application:
+
+            1. For an application willing to accept both IPv4 and
+               IPv6 datagrams, the value of this object must be
+               ''h (a zero-length octet-string), with the value
+               of the corresponding tcpListenerLocalAddressType
+               object being unknown (0).
+
+            2. For an application willing to accept only IPv4 or
+               IPv6 datagrams, the value of this object must be
+               '0.0.0.0' or '::' respectively, with
+               tcpListenerLocalAddressType representing the
+               appropriate address type.
+
+            3. For an application which is listening for data
+               destined only to a specific IP address, the value
+               of this object is the specific local address, with
+               tcpListenerLocalAddressType representing the
+               appropriate address type.
+
+            As this object is used in the index for the
+            tcpListenerTable, implementors should be
+            careful not to create entries that would result in OIDs
+            with more than 128 subidentifiers; otherwise the information
+            cannot be accessed, using SNMPv1, SNMPv2c, or SNMPv3."
+    ::= { tcpListenerEntry 2 }
+
+tcpListenerLocalPort OBJECT-TYPE
+    SYNTAX     InetPortNumber
+    MAX-ACCESS not-accessible
+    STATUS     current
+    DESCRIPTION
+           "The local port number for this TCP connection."
+    ::= { tcpListenerEntry 3 }
+
+
+
+tcpListenerProcess OBJECT-TYPE
+    SYNTAX     Unsigned32
+    MAX-ACCESS read-only
+    STATUS     current
+    DESCRIPTION
+           "The system's process ID for the process associated with
+            this listener, or zero if there is no such process.  This
+            value is expected to be the same as HOST-RESOURCES-MIB::
+            hrSWRunIndex or SYSAPPL-MIB::sysApplElmtRunIndex for some
+            row in the appropriate tables."
+    ::= { tcpListenerEntry 4 }
+
+
+-- The deprecated TCP Connection table
+
+tcpConnTable OBJECT-TYPE
+    SYNTAX     SEQUENCE OF TcpConnEntry
+    MAX-ACCESS not-accessible
+    STATUS     deprecated
+    DESCRIPTION
+           "A table containing information about existing IPv4-specific
+            TCP connections or listeners.  This table has been
+            deprecated in favor of the version neutral
+            tcpConnectionTable."
+    ::= { tcp 13 }
+
+tcpConnEntry OBJECT-TYPE
+    SYNTAX     TcpConnEntry
+    MAX-ACCESS not-accessible
+    STATUS     deprecated
+    DESCRIPTION
+           "A conceptual row of the tcpConnTable containing information
+            about a particular current IPv4 TCP connection.  Each row
+            of this table is transient in that it ceases to exist when
+            (or soon after) the connection makes the transition to the
+            CLOSED state."
+    INDEX   { tcpConnLocalAddress,
+              tcpConnLocalPort,
+              tcpConnRemAddress,
+              tcpConnRemPort }
+    ::= { tcpConnTable 1 }
+
+TcpConnEntry ::= SEQUENCE {
+        tcpConnState         INTEGER,
+        tcpConnLocalAddress  IpAddress,
+        tcpConnLocalPort     Integer32,
+        tcpConnRemAddress    IpAddress,
+        tcpConnRemPort       Integer32
+
+
+
+    }
+
+tcpConnState OBJECT-TYPE
+    SYNTAX     INTEGER {
+                    closed(1),
+                    listen(2),
+                    synSent(3),
+                    synReceived(4),
+                    established(5),
+                    finWait1(6),
+                    finWait2(7),
+                    closeWait(8),
+                    lastAck(9),
+                    closing(10),
+                    timeWait(11),
+                    deleteTCB(12)
+                }
+    MAX-ACCESS read-write
+    STATUS     deprecated
+    DESCRIPTION
+           "The state of this TCP connection.
+
+            The only value that may be set by a management station is
+            deleteTCB(12).  Accordingly, it is appropriate for an agent
+            to return a `badValue' response if a management station
+            attempts to set this object to any other value.
+
+            If a management station sets this object to the value
+            deleteTCB(12), then the TCB (as defined in [RFC793]) of
+            the corresponding connection on the managed node is
+            deleted, resulting in immediate termination of the
+            connection.
+
+            As an implementation-specific option, a RST segment may be
+            sent from the managed node to the other TCP endpoint (note,
+            however, that RST segments are not sent reliably)."
+    ::= { tcpConnEntry 1 }
+
+tcpConnLocalAddress OBJECT-TYPE
+    SYNTAX     IpAddress
+    MAX-ACCESS read-only
+    STATUS     deprecated
+    DESCRIPTION
+           "The local IP address for this TCP connection.  In the case
+            of a connection in the listen state willing to
+            accept connections for any IP interface associated with the
+            node, the value 0.0.0.0 is used."
+    ::= { tcpConnEntry 2 }
+
+
+
+tcpConnLocalPort OBJECT-TYPE
+    SYNTAX     Integer32 (0..65535)
+    MAX-ACCESS read-only
+    STATUS     deprecated
+    DESCRIPTION
+           "The local port number for this TCP connection."
+    ::= { tcpConnEntry 3 }
+
+tcpConnRemAddress OBJECT-TYPE
+    SYNTAX     IpAddress
+    MAX-ACCESS read-only
+    STATUS     deprecated
+    DESCRIPTION
+           "The remote IP address for this TCP connection."
+    ::= { tcpConnEntry 4 }
+
+tcpConnRemPort OBJECT-TYPE
+    SYNTAX     Integer32 (0..65535)
+    MAX-ACCESS read-only
+    STATUS     deprecated
+    DESCRIPTION
+           "The remote port number for this TCP connection."
+    ::= { tcpConnEntry 5 }
+
+-- conformance information
+
+tcpMIBConformance OBJECT IDENTIFIER ::= { tcpMIB 2 }
+
+tcpMIBCompliances OBJECT IDENTIFIER ::= { tcpMIBConformance 1 }
+tcpMIBGroups      OBJECT IDENTIFIER ::= { tcpMIBConformance 2 }
+
+-- compliance statements
+
+tcpMIBCompliance2 MODULE-COMPLIANCE
+    STATUS     current
+    DESCRIPTION
+           "The compliance statement for systems that implement TCP.
+
+            A number of INDEX objects cannot be
+            represented in the form of OBJECT clauses in SMIv2 but
+            have the following compliance requirements,
+            expressed in OBJECT clause form in this description
+            clause:
+
+            -- OBJECT      tcpConnectionLocalAddressType
+            -- SYNTAX      InetAddressType { ipv4(1), ipv6(2) }
+            -- DESCRIPTION
+            --     This MIB requires support for only global IPv4
+
+
+
+            --     and IPv6 address types.
+            --
+            -- OBJECT      tcpConnectionRemAddressType
+            -- SYNTAX      InetAddressType { ipv4(1), ipv6(2) }
+            -- DESCRIPTION
+            --     This MIB requires support for only global IPv4
+            --     and IPv6 address types.
+            --
+            -- OBJECT      tcpListenerLocalAddressType
+            -- SYNTAX      InetAddressType { unknown(0), ipv4(1),
+            --                               ipv6(2) }
+            -- DESCRIPTION
+            --     This MIB requires support for only global IPv4
+            --     and IPv6 address types.  The type unknown also
+            --     needs to be supported to identify a special
+            --     case in the listener table: a listen using
+            --     both IPv4 and IPv6 addresses on the device.
+            --
+           "
+    MODULE  -- this module
+        MANDATORY-GROUPS { tcpBaseGroup, tcpConnectionGroup,
+                           tcpListenerGroup }
+        GROUP       tcpHCGroup
+        DESCRIPTION
+           "This group is mandatory for systems that are capable
+            of receiving or transmitting more than 1 million TCP
+            segments per second.  1 million segments per second will
+            cause a Counter32 to wrap in just over an hour."
+        OBJECT      tcpConnectionState
+        SYNTAX      INTEGER { closed(1), listen(2), synSent(3),
+                              synReceived(4), established(5),
+                              finWait1(6), finWait2(7), closeWait(8),
+                              lastAck(9), closing(10), timeWait(11) }
+        MIN-ACCESS  read-only
+        DESCRIPTION
+           "Write access is not required, nor is support for the value
+            deleteTCB (12)."
+    ::= { tcpMIBCompliances 2 }
+
+tcpMIBCompliance MODULE-COMPLIANCE
+    STATUS     deprecated
+    DESCRIPTION
+           "The compliance statement for IPv4-only systems that
+            implement TCP.  In order to be IP version independent, this
+            compliance statement is deprecated in favor of
+            tcpMIBCompliance2.  However, agents are still encouraged
+            to implement these objects in order to interoperate with
+            the deployed base of managers."
+
+
+
+    MODULE  -- this module
+        MANDATORY-GROUPS { tcpGroup }
+        OBJECT      tcpConnState
+        MIN-ACCESS  read-only
+        DESCRIPTION
+           "Write access is not required."
+    ::= { tcpMIBCompliances 1 }
+
+
+-- units of conformance
+
+tcpGroup OBJECT-GROUP
+    OBJECTS   { tcpRtoAlgorithm, tcpRtoMin, tcpRtoMax,
+                tcpMaxConn, tcpActiveOpens,
+                tcpPassiveOpens, tcpAttemptFails,
+                tcpEstabResets, tcpCurrEstab, tcpInSegs,
+                tcpOutSegs, tcpRetransSegs, tcpConnState,
+                tcpConnLocalAddress, tcpConnLocalPort,
+                tcpConnRemAddress, tcpConnRemPort,
+                tcpInErrs, tcpOutRsts }
+    STATUS     deprecated
+    DESCRIPTION
+           "The tcp group of objects providing for management of TCP
+            entities."
+    ::= { tcpMIBGroups 1 }
+
+tcpBaseGroup OBJECT-GROUP
+    OBJECTS   { tcpRtoAlgorithm, tcpRtoMin, tcpRtoMax,
+                tcpMaxConn, tcpActiveOpens,
+                tcpPassiveOpens, tcpAttemptFails,
+                tcpEstabResets, tcpCurrEstab, tcpInSegs,
+                tcpOutSegs, tcpRetransSegs,
+                tcpInErrs, tcpOutRsts }
+    STATUS     current
+    DESCRIPTION
+           "The group of counters common to TCP entities."
+    ::= { tcpMIBGroups 2 }
+
+tcpConnectionGroup OBJECT-GROUP
+    OBJECTS    { tcpConnectionState, tcpConnectionProcess }
+    STATUS     current
+    DESCRIPTION
+           "The group provides general information about TCP
+            connections."
+    ::= { tcpMIBGroups 3 }
+
+tcpListenerGroup OBJECT-GROUP
+    OBJECTS    { tcpListenerProcess }
+
+
+
+    STATUS     current
+    DESCRIPTION
+           "This group has objects providing general information about
+            TCP listeners."
+    ::= { tcpMIBGroups 4 }
+
+tcpHCGroup OBJECT-GROUP
+    OBJECTS    { tcpHCInSegs, tcpHCOutSegs }
+    STATUS     current
+    DESCRIPTION
+           "The group of objects providing for counters of high speed
+            TCP implementations."
+    ::= { tcpMIBGroups 5 }
+
+END
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/Mibs/UDP-MIB
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/Mibs/UDP-MIB	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/Mibs/UDP-MIB	(revision 457)
@@ -0,0 +1,579 @@
+UDP-MIB DEFINITIONS ::= BEGIN
+
+IMPORTS
+    MODULE-IDENTITY, OBJECT-TYPE, Integer32, Counter32, Counter64,
+    Unsigned32, IpAddress, mib-2       FROM SNMPv2-SMI
+    MODULE-COMPLIANCE, OBJECT-GROUP    FROM SNMPv2-CONF
+    InetAddress, InetAddressType,
+    InetPortNumber                     FROM INET-ADDRESS-MIB;
+
+udpMIB MODULE-IDENTITY
+    LAST-UPDATED "200505200000Z"  -- May 20, 2005
+    ORGANIZATION
+           "IETF IPv6 Working Group
+            http://www.ietf.org/html.charters/ipv6-charter.html"
+    CONTACT-INFO
+           "Bill Fenner (editor)
+
+            AT&T Labs -- Research
+            75 Willow Rd.
+            Menlo Park, CA 94025
+
+            Phone: +1 650 330-7893
+            Email: <fenner@research.att.com>
+
+            John Flick (editor)
+
+            Hewlett-Packard Company
+            8000 Foothills Blvd. M/S 5557
+            Roseville, CA 95747
+
+            Phone: +1 916 785 4018
+            Email: <john.flick@hp.com>
+
+            Send comments to <ipv6@ietf.org>"
+
+
+
+    DESCRIPTION
+           "The MIB module for managing UDP implementations.
+            Copyright (C) The Internet Society (2005).  This
+            version of this MIB module is part of RFC 4113;
+            see the RFC itself for full legal notices."
+    REVISION      "200505200000Z"  -- May 20, 2005
+    DESCRIPTION
+           "IP version neutral revision, incorporating the
+            following revisions:
+
+            - Added udpHCInDatagrams and udpHCOutDatagrams in order
+              to provide high-capacity counters for fast networks.
+            - Added text to the descriptions of all counter objects
+              to indicate how discontinuities are detected.
+            - Deprecated the IPv4-specific udpTable and replaced it
+              with the version neutral udpEndpointTable.  This
+              table includes support for connected UDP endpoints
+              and support for identification of the operating
+              system process associated with a UDP endpoint.
+            - Deprecated the udpGroup and replaced it with object
+              groups representing the current set of objects.
+            - Deprecated udpMIBCompliance and replaced it with
+              udpMIBCompliance2, which includes the compliance
+              information for the new object groups.
+
+            This version published as RFC 4113."
+    REVISION      "199411010000Z"    -- November 1, 1994
+    DESCRIPTION
+           "Initial SMIv2 version, published as RFC 2013."
+    REVISION      "199103310000Z"    -- March 31, 1991
+    DESCRIPTION
+           "The initial revision of this MIB module was part of
+            MIB-II, published as RFC 1213."
+    ::= { mib-2 50 }
+
+-- the UDP group
+
+udp      OBJECT IDENTIFIER ::= { mib-2 7 }
+
+udpInDatagrams OBJECT-TYPE
+    SYNTAX     Counter32
+    MAX-ACCESS read-only
+    STATUS     current
+    DESCRIPTION
+           "The total number of UDP datagrams delivered to UDP
+            users.
+
+
+
+
+
+            Discontinuities in the value of this counter can occur
+            at re-initialization of the management system, and at
+            other times as indicated by discontinuities in the
+            value of sysUpTime."
+    ::= { udp 1 }
+
+udpNoPorts OBJECT-TYPE
+    SYNTAX     Counter32
+    MAX-ACCESS read-only
+    STATUS     current
+    DESCRIPTION
+           "The total number of received UDP datagrams for which
+            there was no application at the destination port.
+
+            Discontinuities in the value of this counter can occur
+            at re-initialization of the management system, and at
+            other times as indicated by discontinuities in the
+            value of sysUpTime."
+    ::= { udp 2 }
+
+udpInErrors OBJECT-TYPE
+    SYNTAX     Counter32
+    MAX-ACCESS read-only
+    STATUS     current
+    DESCRIPTION
+           "The number of received UDP datagrams that could not be
+            delivered for reasons other than the lack of an
+            application at the destination port.
+
+            Discontinuities in the value of this counter can occur
+            at re-initialization of the management system, and at
+            other times as indicated by discontinuities in the
+            value of sysUpTime."
+    ::= { udp 3 }
+
+udpOutDatagrams OBJECT-TYPE
+    SYNTAX     Counter32
+    MAX-ACCESS read-only
+    STATUS     current
+    DESCRIPTION
+           "The total number of UDP datagrams sent from this
+            entity.
+
+            Discontinuities in the value of this counter can occur
+            at re-initialization of the management system, and at
+            other times as indicated by discontinuities in the
+            value of sysUpTime."
+    ::= { udp 4 }
+
+
+
+udpHCInDatagrams OBJECT-TYPE
+    SYNTAX     Counter64
+    MAX-ACCESS read-only
+    STATUS     current
+    DESCRIPTION
+           "The total number of UDP datagrams delivered to UDP
+            users, for devices that can receive more than 1
+            million UDP datagrams per second.
+
+            Discontinuities in the value of this counter can occur
+            at re-initialization of the management system, and at
+            other times as indicated by discontinuities in the
+            value of sysUpTime."
+    ::= { udp 8 }
+
+udpHCOutDatagrams OBJECT-TYPE
+    SYNTAX     Counter64
+    MAX-ACCESS read-only
+    STATUS     current
+    DESCRIPTION
+           "The total number of UDP datagrams sent from this
+            entity, for devices that can transmit more than 1
+            million UDP datagrams per second.
+
+            Discontinuities in the value of this counter can occur
+            at re-initialization of the management system, and at
+            other times as indicated by discontinuities in the
+            value of sysUpTime."
+    ::= { udp 9 }
+
+--
+-- { udp 6 } was defined as the ipv6UdpTable in RFC2454's
+-- IPV6-UDP-MIB.  This RFC obsoletes RFC 2454, so { udp 6 } is
+-- obsoleted.
+--
+
+-- The UDP "Endpoint" table.
+
+udpEndpointTable OBJECT-TYPE
+    SYNTAX     SEQUENCE OF UdpEndpointEntry
+    MAX-ACCESS not-accessible
+    STATUS     current
+    DESCRIPTION
+           "A table containing information about this entity's UDP
+            endpoints on which a local application is currently
+            accepting or sending datagrams.
+
+
+
+
+
+            The address type in this table represents the address
+            type used for the communication, irrespective of the
+            higher-layer abstraction.  For example, an application
+            using IPv6 'sockets' to communicate via IPv4 between
+            ::ffff:10.0.0.1 and ::ffff:10.0.0.2 would use
+            InetAddressType ipv4(1).
+
+            Unlike the udpTable in RFC 2013, this table also allows
+            the representation of an application that completely
+            specifies both local and remote addresses and ports.  A
+            listening application is represented in three possible
+            ways:
+
+            1) An application that is willing to accept both IPv4
+               and IPv6 datagrams is represented by a
+               udpEndpointLocalAddressType of unknown(0) and a
+               udpEndpointLocalAddress of ''h (a zero-length
+               octet-string).
+
+            2) An application that is willing to accept only IPv4
+               or only IPv6 datagrams is represented by a
+               udpEndpointLocalAddressType of the appropriate
+               address type and a udpEndpointLocalAddress of
+               '0.0.0.0' or '::' respectively.
+
+            3) An application that is listening for datagrams only
+               for a specific IP address but from any remote
+               system is represented by a
+               udpEndpointLocalAddressType of the appropriate
+               address type, with udpEndpointLocalAddress
+               specifying the local address.
+
+            In all cases where the remote is a wildcard, the
+            udpEndpointRemoteAddressType is unknown(0), the
+            udpEndpointRemoteAddress is ''h (a zero-length
+            octet-string), and the udpEndpointRemotePort is 0.
+
+            If the operating system is demultiplexing UDP packets
+            by remote address and port, or if the application has
+            'connected' the socket specifying a default remote
+            address and port, the udpEndpointRemote* values should
+            be used to reflect this."
+    ::= { udp 7 }
+
+udpEndpointEntry OBJECT-TYPE
+    SYNTAX     UdpEndpointEntry
+    MAX-ACCESS not-accessible
+    STATUS     current
+
+
+
+    DESCRIPTION
+           "Information about a particular current UDP endpoint.
+
+            Implementers need to be aware that if the total number
+            of elements (octets or sub-identifiers) in
+            udpEndpointLocalAddress and udpEndpointRemoteAddress
+            exceeds 111, then OIDs of column instances in this table
+            will have more than 128 sub-identifiers and cannot be
+            accessed using SNMPv1, SNMPv2c, or SNMPv3."
+    INDEX   { udpEndpointLocalAddressType,
+              udpEndpointLocalAddress,
+              udpEndpointLocalPort,
+              udpEndpointRemoteAddressType,
+              udpEndpointRemoteAddress,
+              udpEndpointRemotePort,
+              udpEndpointInstance }
+    ::= { udpEndpointTable 1 }
+
+UdpEndpointEntry ::= SEQUENCE {
+        udpEndpointLocalAddressType   InetAddressType,
+        udpEndpointLocalAddress       InetAddress,
+        udpEndpointLocalPort          InetPortNumber,
+        udpEndpointRemoteAddressType  InetAddressType,
+        udpEndpointRemoteAddress      InetAddress,
+        udpEndpointRemotePort         InetPortNumber,
+        udpEndpointInstance           Unsigned32,
+        udpEndpointProcess            Unsigned32
+    }
+
+udpEndpointLocalAddressType OBJECT-TYPE
+    SYNTAX     InetAddressType
+    MAX-ACCESS not-accessible
+    STATUS     current
+    DESCRIPTION
+           "The address type of udpEndpointLocalAddress.  Only
+            IPv4, IPv4z, IPv6, and IPv6z addresses are expected, or
+            unknown(0) if datagrams for all local IP addresses are
+            accepted."
+    ::= { udpEndpointEntry 1 }
+
+udpEndpointLocalAddress OBJECT-TYPE
+    SYNTAX     InetAddress
+    MAX-ACCESS not-accessible
+    STATUS     current
+    DESCRIPTION
+           "The local IP address for this UDP endpoint.
+
+            The value of this object can be represented in three
+
+
+
+            possible ways, depending on the characteristics of the
+            listening application:
+
+            1. For an application that is willing to accept both
+               IPv4 and IPv6 datagrams, the value of this object
+               must be ''h (a zero-length octet-string), with
+               the value of the corresponding instance of the
+               udpEndpointLocalAddressType object being unknown(0).
+
+            2. For an application that is willing to accept only IPv4
+               or only IPv6 datagrams, the value of this object
+               must be '0.0.0.0' or '::', respectively, while the
+               corresponding instance of the
+               udpEndpointLocalAddressType object represents the
+               appropriate address type.
+
+            3. For an application that is listening for data
+               destined only to a specific IP address, the value
+               of this object is the specific IP address for which
+               this node is receiving packets, with the
+               corresponding instance of the
+               udpEndpointLocalAddressType object representing the
+               appropriate address type.
+
+            As this object is used in the index for the
+            udpEndpointTable, implementors of this table should be
+            careful not to create entries that would result in OIDs
+            with more than 128 subidentifiers; else the information
+            cannot be accessed using SNMPv1, SNMPv2c, or SNMPv3."
+    ::= { udpEndpointEntry 2 }
+
+udpEndpointLocalPort OBJECT-TYPE
+    SYNTAX     InetPortNumber
+    MAX-ACCESS not-accessible
+    STATUS     current
+    DESCRIPTION
+           "The local port number for this UDP endpoint."
+    ::= { udpEndpointEntry 3 }
+
+udpEndpointRemoteAddressType OBJECT-TYPE
+    SYNTAX     InetAddressType
+    MAX-ACCESS not-accessible
+    STATUS     current
+    DESCRIPTION
+           "The address type of udpEndpointRemoteAddress.  Only
+            IPv4, IPv4z, IPv6, and IPv6z addresses are expected, or
+            unknown(0) if datagrams for all remote IP addresses are
+            accepted.  Also, note that some combinations of
+
+
+
+            udpEndpointLocalAdressType and
+            udpEndpointRemoteAddressType are not supported.  In
+            particular, if the value of this object is not
+            unknown(0), it is expected to always refer to the
+            same IP version as udpEndpointLocalAddressType."
+    ::= { udpEndpointEntry 4 }
+
+udpEndpointRemoteAddress OBJECT-TYPE
+    SYNTAX     InetAddress
+    MAX-ACCESS not-accessible
+    STATUS     current
+    DESCRIPTION
+           "The remote IP address for this UDP endpoint.  If
+            datagrams from any remote system are to be accepted,
+            this value is ''h (a zero-length octet-string).
+            Otherwise, it has the type described by
+            udpEndpointRemoteAddressType and is the address of the
+            remote system from which datagrams are to be accepted
+            (or to which all datagrams will be sent).
+
+            As this object is used in the index for the
+            udpEndpointTable, implementors of this table should be
+            careful not to create entries that would result in OIDs
+            with more than 128 subidentifiers; else the information
+            cannot be accessed using SNMPv1, SNMPv2c, or SNMPv3."
+    ::= { udpEndpointEntry 5 }
+
+udpEndpointRemotePort OBJECT-TYPE
+    SYNTAX     InetPortNumber
+    MAX-ACCESS not-accessible
+    STATUS     current
+    DESCRIPTION
+           "The remote port number for this UDP endpoint.  If
+            datagrams from any remote system are to be accepted,
+            this value is zero."
+    ::= { udpEndpointEntry 6 }
+
+udpEndpointInstance OBJECT-TYPE
+    SYNTAX     Unsigned32 (1..'ffffffff'h)
+    MAX-ACCESS not-accessible
+    STATUS     current
+    DESCRIPTION
+           "The instance of this tuple.  This object is used to
+            distinguish among multiple processes 'connected' to
+            the same UDP endpoint.  For example, on a system
+            implementing the BSD sockets interface, this would be
+            used to support the SO_REUSEADDR and SO_REUSEPORT
+            socket options."
+
+
+
+    ::= { udpEndpointEntry 7 }
+
+udpEndpointProcess OBJECT-TYPE
+    SYNTAX     Unsigned32
+    MAX-ACCESS read-only
+    STATUS     current
+    DESCRIPTION
+           "The system's process ID for the process associated with
+            this endpoint, or zero if there is no such process.
+            This value is expected to be the same as
+            HOST-RESOURCES-MIB::hrSWRunIndex or SYSAPPL-MIB::
+            sysApplElmtRunIndex for some row in the appropriate
+            tables."
+    ::= { udpEndpointEntry 8 }
+
+-- The deprecated UDP Listener table
+
+-- The deprecated UDP listener table only contains information
+-- about this entity's IPv4 UDP end-points on which a local
+-- application is currently accepting datagrams.  It does not
+-- provide more detailed connection information, or information
+-- about IPv6 endpoints.
+
+udpTable OBJECT-TYPE
+    SYNTAX     SEQUENCE OF UdpEntry
+    MAX-ACCESS not-accessible
+    STATUS     deprecated
+    DESCRIPTION
+           "A table containing IPv4-specific UDP listener
+            information.  It contains information about all local
+            IPv4 UDP end-points on which an application is
+            currently accepting datagrams.  This table has been
+            deprecated in favor of the version neutral
+            udpEndpointTable."
+    ::= { udp 5 }
+
+udpEntry OBJECT-TYPE
+    SYNTAX     UdpEntry
+    MAX-ACCESS not-accessible
+    STATUS     deprecated
+    DESCRIPTION
+           "Information about a particular current UDP listener."
+    INDEX   { udpLocalAddress, udpLocalPort }
+    ::= { udpTable 1 }
+
+UdpEntry ::= SEQUENCE {
+    udpLocalAddress   IpAddress,
+    udpLocalPort      Integer32
+
+
+
+}
+
+udpLocalAddress OBJECT-TYPE
+    SYNTAX     IpAddress
+    MAX-ACCESS read-only
+    STATUS     deprecated
+    DESCRIPTION
+           "The local IP address for this UDP listener.  In the
+            case of a UDP listener that is willing to accept
+            datagrams for any IP interface associated with the
+            node, the value 0.0.0.0 is used."
+    ::= { udpEntry 1 }
+
+udpLocalPort OBJECT-TYPE
+    SYNTAX     Integer32 (0..65535)
+    MAX-ACCESS read-only
+    STATUS     deprecated
+    DESCRIPTION
+           "The local port number for this UDP listener."
+    ::= { udpEntry 2 }
+
+-- conformance information
+
+udpMIBConformance OBJECT IDENTIFIER ::= { udpMIB 2 }
+udpMIBCompliances OBJECT IDENTIFIER ::= { udpMIBConformance 1 }
+udpMIBGroups      OBJECT IDENTIFIER ::= { udpMIBConformance 2 }
+
+-- compliance statements
+
+udpMIBCompliance2 MODULE-COMPLIANCE
+    STATUS     current
+    DESCRIPTION
+           "The compliance statement for systems that implement
+            UDP.
+
+            There are a number of INDEX objects that cannot be
+            represented in the form of OBJECT clauses in SMIv2, but
+            for which we have the following compliance
+            requirements, expressed in OBJECT clause form in this
+            description clause:
+
+            -- OBJECT      udpEndpointLocalAddressType
+            -- SYNTAX      InetAddressType { unknown(0), ipv4(1),
+            --                               ipv6(2), ipv4z(3),
+            --                               ipv6z(4) }
+            -- DESCRIPTION
+            --     Support for dns(5) is not required.
+            -- OBJECT      udpEndpointLocalAddress
+
+
+
+            -- SYNTAX      InetAddress (SIZE(0|4|8|16|20))
+            -- DESCRIPTION
+            --     Support is only required for zero-length
+            --     octet-strings, and for scoped and unscoped
+            --     IPv4 and IPv6 addresses.
+            -- OBJECT      udpEndpointRemoteAddressType
+            -- SYNTAX      InetAddressType { unknown(0), ipv4(1),
+            --                               ipv6(2), ipv4z(3),
+            --                               ipv6z(4) }
+            -- DESCRIPTION
+            --     Support for dns(5) is not required.
+            -- OBJECT      udpEndpointRemoteAddress
+            -- SYNTAX      InetAddress (SIZE(0|4|8|16|20))
+            -- DESCRIPTION
+            --     Support is only required for zero-length
+            --     octet-strings, and for scoped and unscoped
+            --     IPv4 and IPv6 addresses.
+           "
+    MODULE  -- this module
+         MANDATORY-GROUPS { udpBaseGroup, udpEndpointGroup }
+         GROUP       udpHCGroup
+         DESCRIPTION
+                "This group is mandatory for systems that
+                 are capable of receiving or transmitting more than
+                 1 million UDP datagrams per second.  1 million
+                 datagrams per second will cause a Counter32 to
+                 wrap in just over an hour."
+    ::= { udpMIBCompliances 2 }
+
+udpMIBCompliance MODULE-COMPLIANCE
+    STATUS     deprecated
+    DESCRIPTION
+           "The compliance statement for IPv4-only systems that
+            implement UDP.  For IP version independence, this
+            compliance statement is deprecated in favor of
+            udpMIBCompliance2.  However, agents are still
+            encouraged to implement these objects in order to
+            interoperate with the deployed base of managers."
+    MODULE  -- this module
+        MANDATORY-GROUPS { udpGroup }
+    ::= { udpMIBCompliances 1 }
+
+-- units of conformance
+
+udpGroup OBJECT-GROUP
+    OBJECTS   { udpInDatagrams, udpNoPorts,
+                udpInErrors, udpOutDatagrams,
+                udpLocalAddress, udpLocalPort }
+
+
+
+    STATUS     deprecated
+    DESCRIPTION
+           "The deprecated group of objects providing for
+            management of UDP over IPv4."
+    ::= { udpMIBGroups 1 }
+
+udpBaseGroup OBJECT-GROUP
+    OBJECTS   { udpInDatagrams, udpNoPorts, udpInErrors,
+                udpOutDatagrams }
+    STATUS     current
+    DESCRIPTION
+           "The group of objects providing for counters of UDP
+            statistics."
+    ::= { udpMIBGroups 2 }
+
+udpHCGroup OBJECT-GROUP
+    OBJECTS   { udpHCInDatagrams, udpHCOutDatagrams }
+    STATUS     current
+    DESCRIPTION
+           "The group of objects providing for counters of high
+            speed UDP implementations."
+    ::= { udpMIBGroups 3 }
+
+udpEndpointGroup OBJECT-GROUP
+    OBJECTS    { udpEndpointProcess }
+    STATUS     current
+    DESCRIPTION
+           "The group of objects providing for the IP version
+            independent management of UDP 'endpoints'."
+    ::= { udpMIBGroups 4 }
+
+END
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/SharpSnmpLib/Mib/DisplayHint.cs
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/SharpSnmpLib/Mib/DisplayHint.cs	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/SharpSnmpLib/Mib/DisplayHint.cs	(revision 457)
@@ -0,0 +1,84 @@
+using System;
+using System.Collections.Generic;
+using System.Collections;
+
+namespace Lextm.SharpSnmpLib.Mib
+{
+    public class DisplayHint
+    {
+        private enum NumType {
+            dec,
+            hex,
+            oct,
+            bin,
+            str
+        }
+
+        private string _str;
+        private NumType _type;
+        private int _decimalPoints = 0;
+
+        public DisplayHint(string str)
+        {
+            _str = str;
+            if (str.StartsWith("d"))
+            {
+                _type = NumType.dec;
+                if (str.StartsWith("d-"))
+                {
+                    _decimalPoints = Convert.ToInt32(str.Substring(2));
+                }
+            }
+            else if (str.StartsWith("o"))
+            {
+                _type = NumType.oct;
+            }
+            else if (str.StartsWith("h"))
+            {
+                _type = NumType.hex;
+            }
+            else if (str.StartsWith("b"))
+            {
+                _type = NumType.bin;
+            }
+            else
+            {
+                _type = NumType.str;
+                foreach (char c in str)
+                {
+
+                }
+            }
+
+        }
+
+        public override string ToString()
+        {
+            return _str;
+        }
+
+        internal object Decode(int i)
+        {
+            switch (_type)
+            {
+                case NumType.dec:
+                    if (_decimalPoints == 0)
+                    {
+                        return i;
+                    }
+                    else
+                    {
+                        return i / Math.Pow(10.0, _decimalPoints);
+                    }
+                case NumType.hex:
+                    return System.Convert.ToString(i, 16);
+                case NumType.oct:
+                    return System.Convert.ToString(i, 8);
+                case NumType.bin:
+                    return System.Convert.ToString(i, 2);
+                default:
+                    return null;
+            }
+        }
+    }
+}
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/SharpSnmpLib/Mib/Elements/Entities/AgentCapabilities.cs
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/SharpSnmpLib/Mib/Elements/Entities/AgentCapabilities.cs	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/SharpSnmpLib/Mib/Elements/Entities/AgentCapabilities.cs	(revision 457)
@@ -0,0 +1,29 @@
+/*
+ * Created by SharpDevelop.
+ * User: lextm
+ * Date: 2008/5/31
+ * Time: 13:18
+ * 
+ * To change this template use Tools | Options | Coding | Edit Standard Headers.
+ */
+
+namespace Lextm.SharpSnmpLib.Mib.Elements.Entities
+{
+    /// <summary>
+    /// The AGENT-CAPABILITIES construct is used to specify implementation characteristics of an SNMP agent sub-system with respect to object types and events.
+    /// </summary>
+    public sealed class AgentCapabilities : EntityBase
+    {       
+        /// <summary>
+        /// Creates an <see cref="AgentCapabilities"/> instance.
+        /// </summary>
+        /// <param name="module"></param>
+        /// <param name="header"></param>
+        /// <param name="lexer"></param>
+        public AgentCapabilities(IModule module, SymbolList preAssignSymbols, ISymbolEnumerator symbols)
+            : base(module, preAssignSymbols, symbols)
+        {
+        }
+       
+    }
+}
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/SharpSnmpLib/Mib/Elements/Entities/EntityBase.cs
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/SharpSnmpLib/Mib/Elements/Entities/EntityBase.cs	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/SharpSnmpLib/Mib/Elements/Entities/EntityBase.cs	(revision 457)
@@ -0,0 +1,46 @@
+using System;
+
+namespace Lextm.SharpSnmpLib.Mib.Elements.Entities
+{
+    public abstract class EntityBase: IEntity
+    {
+        private readonly IModule _module;
+        private string _parent;
+        private readonly uint   _value;
+        private readonly string _name;
+
+        public EntityBase(IModule module, SymbolList preAssignSymbols, ISymbolEnumerator symbols)
+        {
+            _module = module;
+            _name   = preAssignSymbols[0].ToString();
+
+            Lexer.ParseOidValue(symbols, out _parent, out _value);
+        }
+
+        public IModule Module
+        {
+            get { return _module; }
+        }
+
+        public string Parent
+        {
+            get { return _parent; }
+            set { _parent = value; }
+        }
+
+        public uint Value
+        {
+            get { return _value; }
+        }
+
+        public string Name
+        {
+            get { return _name; }
+        }
+        
+        public virtual string Description
+        {
+            get { return string.Empty; }
+        }
+    }
+}
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/SharpSnmpLib/Mib/Elements/Entities/IEntity.cs
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/SharpSnmpLib/Mib/Elements/Entities/IEntity.cs	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/SharpSnmpLib/Mib/Elements/Entities/IEntity.cs	(revision 457)
@@ -0,0 +1,62 @@
+// Entity interface.
+// Copyright (C) 2008-2010 Malcolm Crowe, Lex Li, and other contributors.
+// 
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+// 
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+// 
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+
+/*
+ * Created by SharpDevelop.
+ * User: lextm
+ * Date: 2008/5/19
+ * Time: 20:10
+ * 
+ * To change this template use Tools | Options | Coding | Edit Standard Headers.
+ */
+
+using System;
+
+namespace Lextm.SharpSnmpLib.Mib.Elements.Entities
+{
+    /// <summary>
+    /// Basic interface for all elements building up the MIB tree, thus having an OID as value.
+    /// </summary>
+    public interface IEntity : IDeclaration
+    {
+        /// <summary>
+        /// Parent name.
+        /// </summary>
+        string Parent
+        {
+            get;
+            set;
+        }
+        
+        /// <summary>
+        /// Value.
+        /// </summary>
+        uint Value
+        {
+            get;            
+        }
+
+        /// <summary>
+        /// Gets the description.
+        /// </summary>
+        /// <value>The description.</value>
+        string Description
+        {
+            get;
+        }
+    }
+}
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/SharpSnmpLib/Mib/Elements/Entities/ModuleCompliance.cs
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/SharpSnmpLib/Mib/Elements/Entities/ModuleCompliance.cs	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/SharpSnmpLib/Mib/Elements/Entities/ModuleCompliance.cs	(revision 457)
@@ -0,0 +1,23 @@
+/*
+ * Created by SharpDevelop.
+ * User: lextm
+ * Date: 2008/5/21
+ * Time: 19:35
+ * 
+ * To change this template use Tools | Options | Coding | Edit Standard Headers.
+ */
+
+namespace Lextm.SharpSnmpLib.Mib.Elements.Entities
+{
+    /// <summary>
+    /// Description of ModuleComplianceNode.
+    /// </summary>
+    public sealed class ModuleCompliance : EntityBase
+    {
+        public ModuleCompliance(IModule module, SymbolList preAssignSymbols, ISymbolEnumerator symbols)
+            : base(module, preAssignSymbols, symbols)
+        {
+        }
+       
+    }
+}
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/SharpSnmpLib/Mib/Elements/Entities/ModuleIdentity.cs
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/SharpSnmpLib/Mib/Elements/Entities/ModuleIdentity.cs	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/SharpSnmpLib/Mib/Elements/Entities/ModuleIdentity.cs	(revision 457)
@@ -0,0 +1,10 @@
+namespace Lextm.SharpSnmpLib.Mib.Elements.Entities
+{
+    public sealed class ModuleIdentity : EntityBase
+    {
+        public ModuleIdentity(IModule module, SymbolList preAssignSymbols, ISymbolEnumerator symbols)
+            : base(module, preAssignSymbols, symbols)
+        {
+        }
+    }
+}
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/SharpSnmpLib/Mib/Elements/Entities/NotificationGroup.cs
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/SharpSnmpLib/Mib/Elements/Entities/NotificationGroup.cs	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/SharpSnmpLib/Mib/Elements/Entities/NotificationGroup.cs	(revision 457)
@@ -0,0 +1,22 @@
+/*
+ * Created by SharpDevelop.
+ * User: lextm
+ * Date: 2008/5/21
+ * Time: 19:34
+ * 
+ * To change this template use Tools | Options | Coding | Edit Standard Headers.
+ */
+
+namespace Lextm.SharpSnmpLib.Mib.Elements.Entities
+{
+    /// <summary>
+    /// Description of NotificationGroupNode.
+    /// </summary>
+    public sealed class NotificationGroup : EntityBase
+    {
+        public NotificationGroup(IModule module, SymbolList preAssignSymbols, ISymbolEnumerator symbols)
+            : base(module, preAssignSymbols, symbols)
+        {
+        }
+   }
+}
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/SharpSnmpLib/Mib/Elements/Entities/NotificationType.cs
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/SharpSnmpLib/Mib/Elements/Entities/NotificationType.cs	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/SharpSnmpLib/Mib/Elements/Entities/NotificationType.cs	(revision 457)
@@ -0,0 +1,11 @@
+
+namespace Lextm.SharpSnmpLib.Mib.Elements.Entities
+{
+    public sealed class NotificationType : EntityBase
+    {
+        public NotificationType(IModule module, SymbolList preAssignSymbols, ISymbolEnumerator symbols)
+            : base(module, preAssignSymbols, symbols)
+        {
+        }
+   }
+}
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/SharpSnmpLib/Mib/Elements/Entities/ObjectGroup.cs
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/SharpSnmpLib/Mib/Elements/Entities/ObjectGroup.cs	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/SharpSnmpLib/Mib/Elements/Entities/ObjectGroup.cs	(revision 457)
@@ -0,0 +1,22 @@
+/*
+ * Created by SharpDevelop.
+ * User: lextm
+ * Date: 2008/5/21
+ * Time: 19:27
+ * 
+ * To change this template use Tools | Options | Coding | Edit Standard Headers.
+ */
+
+namespace Lextm.SharpSnmpLib.Mib.Elements.Entities
+{
+    /// <summary>
+    /// Description of ObjectGroupNode.
+    /// </summary>
+    public sealed class ObjectGroup : EntityBase
+    {
+        public ObjectGroup(IModule module, SymbolList preAssignSymbols, ISymbolEnumerator symbols)
+            : base(module, preAssignSymbols, symbols)
+        {
+        }
+   }
+}
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/SharpSnmpLib/Mib/Elements/Entities/ObjectIdentity.cs
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/SharpSnmpLib/Mib/Elements/Entities/ObjectIdentity.cs	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/SharpSnmpLib/Mib/Elements/Entities/ObjectIdentity.cs	(revision 457)
@@ -0,0 +1,21 @@
+
+namespace Lextm.SharpSnmpLib.Mib.Elements.Entities
+{
+    /// <summary>
+    /// Object identifier node.
+    /// </summary>
+    public sealed class ObjectIdentity : EntityBase
+    {
+       
+        /// <summary>
+        /// Creates a <see cref="ObjectIdentity"/>.
+        /// </summary>
+        /// <param name="module">Module name</param>
+        /// <param name="header">Header</param>
+        /// <param name="lexer">Lexer</param>
+        public ObjectIdentity(IModule module, SymbolList preAssignSymbols, ISymbolEnumerator symbols)
+            : base(module, preAssignSymbols, symbols)
+        {
+        }
+    }
+}
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/SharpSnmpLib/Mib/Elements/Entities/ObjectType.cs
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/SharpSnmpLib/Mib/Elements/Entities/ObjectType.cs	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/SharpSnmpLib/Mib/Elements/Entities/ObjectType.cs	(revision 457)
@@ -0,0 +1,336 @@
+using System;
+using System.Collections.Generic;
+using Lextm.SharpSnmpLib.Mib.Elements.Types;
+
+namespace Lextm.SharpSnmpLib.Mib.Elements.Entities
+{
+    public sealed class ObjectType : EntityBase, ITypeReferrer
+    {
+        private ITypeAssignment _syntax;
+        private string _units;
+        private MaxAccess _access;
+        private Status _status;
+        private string _description;
+        private string _reference;
+        private IList<string> _indices;
+        private string _augments;
+        private string _defVal;
+
+        public ObjectType(IModule module, SymbolList preAssignSymbols, ISymbolEnumerator symbols)
+            : base(module, preAssignSymbols, symbols)
+        {
+            ParseProperties(preAssignSymbols);
+        }
+
+        private void ParseProperties(SymbolList header)
+        {
+            ISymbolEnumerator headerSymbols = header.GetSymbolEnumerator();
+            Symbol temp = headerSymbols.NextNonEOLSymbol();
+
+            // Skip name
+            temp = headerSymbols.NextNonEOLSymbol();
+            temp.Expect(Symbol.ObjectType);
+
+            _syntax         = ParseSyntax       (Module, headerSymbols);
+            _units          = ParseUnits        (headerSymbols);
+            _access         = ParseAccess       (headerSymbols);
+            _status         = ParseStatus       (headerSymbols);
+            _description    = ParseDescription  (headerSymbols);
+            _reference      = ParseReference    (headerSymbols);
+            _indices        = ParseIndices      (headerSymbols);
+            _augments        = ParseAugments     (headerSymbols);
+            _defVal         = ParseDefVal       (headerSymbols);
+        }
+
+        private static string ParseAugments(ISymbolEnumerator symbols)
+        {
+            Symbol current = symbols.NextNonEOLSymbol();
+
+            if (current == Symbol.Augments)
+            {
+                string augment = null;
+
+                current = symbols.NextNonEOLSymbol();
+                current.Expect(Symbol.OpenBracket);
+
+                current = symbols.NextNonEOLSymbol();
+                augment = current.ToString();
+
+                current = symbols.NextNonEOLSymbol();
+                current.Expect(Symbol.CloseBracket);
+
+                return augment;
+            }
+            else if (current != null)
+            {
+                symbols.PutBack(current);
+            }
+            
+            return null;
+        }
+
+        private static string ParseDefVal(ISymbolEnumerator symbols)
+        {
+            Symbol current = symbols.NextNonEOLSymbol();
+
+            if (current == Symbol.DefVal)
+            {
+                current = symbols.NextNonEOLSymbol();
+                current.Expect(Symbol.OpenBracket);
+
+                string defVal = null;
+                current = symbols.NextNonEOLSymbol();
+
+                if (current == Symbol.OpenBracket)
+                {
+                    int depth = 1;
+                    // TODO: decode this.
+                    while (depth > 0)
+                    {
+                        current = symbols.NextNonEOLSymbol();
+                        if (current == Symbol.OpenBracket)
+                        {
+                            depth++;
+                        }
+                        else if (current == Symbol.CloseBracket)
+                        {
+                            depth--;
+                        }
+                    }
+                }
+                else
+                {
+                    defVal = current.ToString();
+                    current = symbols.NextNonEOLSymbol();
+                    current.Expect(Symbol.CloseBracket);
+                }
+
+                return defVal;
+            }
+            else if (current != null)
+            {
+                symbols.PutBack(current);
+            }
+
+            return null;
+        }
+
+        private static IList<string> ParseIndices(ISymbolEnumerator symbols)
+        {
+            Symbol current = symbols.NextNonEOLSymbol();
+
+            if (current == Symbol.Index)
+            {
+                current = symbols.NextNonEOLSymbol();
+                current.Expect(Symbol.OpenBracket);
+
+                List<string> indices = new List<string>();
+
+                while (current != Symbol.CloseBracket)
+                {
+                   current = symbols.NextNonEOLSymbol();
+                   
+                   bool lastIndex = false;
+                    if (current == Symbol.Implied)
+                    {
+                        current = symbols.NextNonEOLSymbol();
+                        lastIndex = true; // 'IMPLIED' may only be used for last index 
+                    }
+
+                    current.Assert((current != Symbol.Comma) && (current != Symbol.CloseBracket), "Expected index name but found symbol!");
+                    indices.Add(current.ToString());
+
+                    current = symbols.NextNonEOLSymbol();
+                    if (lastIndex)
+                    {
+                       current.Expect(Symbol.CloseBracket);
+                    }
+                    else
+                    {
+                       current.Expect(Symbol.Comma, Symbol.CloseBracket);
+                    }
+                }
+
+                return indices;
+            }
+            else if (current != null)
+            {
+                symbols.PutBack(current);
+            }
+
+            return null;
+        }
+
+        private static string ParseReference(ISymbolEnumerator symbols)
+        {
+            Symbol current = symbols.NextNonEOLSymbol();
+
+            if (current == Symbol.Reference)
+            {
+                return symbols.NextNonEOLSymbol().ToString();
+            }
+            else if (current != null)
+            {
+                symbols.PutBack(current);
+            }
+
+            return null;
+        }
+
+        private static string ParseDescription(ISymbolEnumerator symbols)
+        {
+            Symbol current = symbols.NextNonEOLSymbol();
+
+            if (current == Symbol.Description)
+            {
+                return symbols.NextNonEOLSymbol().ToString().Trim(new char[] { '"' });
+            }
+            else if (current != null)
+            {
+                symbols.PutBack(current);
+            }
+
+            return null;
+        }
+
+        private static Status ParseStatus(ISymbolEnumerator symbols)
+        {
+            Status status = Status.obsolete;
+
+            Symbol current = symbols.NextNonEOLSymbol();
+            current.Expect(Symbol.Status);
+            
+            current = symbols.NextNonEOLSymbol();
+            try
+            {
+                status = (Status)Enum.Parse(typeof(Status), current.ToString());
+            }
+            catch (ArgumentException)
+            {
+                current.Assert(false, "Invalid/Unknown status");
+            }
+            
+            return status;
+        }
+
+        private static MaxAccess ParseAccess(ISymbolEnumerator symbols)
+        {
+            MaxAccess access = MaxAccess.notAccessible;
+
+            Symbol current = symbols.NextNonEOLSymbol();
+            current.Expect(Symbol.MaxAccess, Symbol.Access);
+
+            current = symbols.NextNonEOLSymbol();
+            switch (current.ToString())
+            {
+                case "not-accessible":
+                    access = MaxAccess.notAccessible;
+                    break;
+                case "accessible-for-notify":
+                    access = MaxAccess.accessibleForNotify;
+                    break;
+                case "read-only":
+                    access = MaxAccess.readOnly;
+                    break;
+                case "read-write":
+                    access = MaxAccess.readWrite;
+                    break;
+                case "read-create":
+                    access = MaxAccess.readCreate;
+                    break;
+                case "write-only":
+                    access = MaxAccess.readWrite;
+                    break;
+                default:
+                    current.Assert(false, "Invalid/Unknown access");
+                    break;
+            }
+
+            return access;
+        }
+
+        private static string ParseUnits(ISymbolEnumerator symbols)
+        {
+            Symbol current = symbols.NextNonEOLSymbol();
+
+            if (current == Symbol.Units)
+            {
+                return symbols.NextNonEOLSymbol().ToString();
+            }
+            else if (current != null)
+            {
+                symbols.PutBack(current);
+            }
+
+            return null;
+        }
+
+        private static ITypeAssignment ParseSyntax(IModule module, ISymbolEnumerator symbols)
+        {
+            Symbol current = symbols.NextNonEOLSymbol();
+            current.Expect(Symbol.Syntax);
+
+            return Lexer.ParseBasicTypeDef(module, String.Empty, symbols, isMacroSyntax: true);
+        }
+
+        private static bool IsProperty(Symbol sym)
+        {
+            string s = sym.ToString();
+            return s == "SYNTAX" || s == "MAX-ACCESS" || s == "STATUS" || s == "DESCRIPTION";
+        }
+
+        public ITypeAssignment Syntax
+        {
+            get { return _syntax; }
+            internal set { _syntax = value; }
+        }
+
+        public override string Description
+        {
+            get { return _description; }
+        }
+
+        public MaxAccess Access
+        {
+            get { return _access; }
+        }
+
+        public IList<string> Indices
+        {
+            get { return _indices; }
+        }
+
+        public string Augments
+        {
+            get { return _augments; }
+        }
+
+        #region ITypeReferrer Member
+
+        public ITypeAssignment ReferredType
+        {
+            get { return _syntax; }
+            set { _syntax = value; }
+        }
+
+        public ITypeAssignment BaseType
+        {
+            get
+            {
+                ITypeReferrer   tr     = this;
+                ITypeAssignment result = null;
+
+                while ((tr != null) && (tr.ReferredType != null))
+                {
+                    result = tr.ReferredType;
+                    tr = tr.ReferredType as ITypeReferrer;
+                }
+
+                return result;
+            }
+        }
+
+        #endregion
+
+    }
+}
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/SharpSnmpLib/Mib/Elements/Entities/OidValueAssignment.cs
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/SharpSnmpLib/Mib/Elements/Entities/OidValueAssignment.cs	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/SharpSnmpLib/Mib/Elements/Entities/OidValueAssignment.cs	(revision 457)
@@ -0,0 +1,30 @@
+/*
+ * Created by SharpDevelop.
+ * User: lextm
+ * Date: 2008/5/17
+ * Time: 20:49
+ * 
+ * To change this template use Tools | Options | Coding | Edit Standard Headers.
+ */
+
+using System;
+
+namespace Lextm.SharpSnmpLib.Mib.Elements.Entities
+{
+    /// <summary>
+    /// Object identifier node.
+    /// </summary>
+    public sealed class OidValueAssignment : EntityBase
+    {
+        /// <summary>
+        /// Creates a <see cref="OidValueAssignment"/>.
+        /// </summary>
+        /// <param name="module">Module</param>
+        /// <param name="name">Name</param>
+        /// <param name="lexer">Lexer</param>
+        public OidValueAssignment(IModule module, SymbolList preAssignSymbols, ISymbolEnumerator symbols)
+            : base(module, preAssignSymbols, symbols)
+        {
+        }
+    }
+}
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/SharpSnmpLib/Mib/Elements/Exports.cs
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/SharpSnmpLib/Mib/Elements/Exports.cs	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/SharpSnmpLib/Mib/Elements/Exports.cs	(revision 457)
@@ -0,0 +1,56 @@
+/*
+ * Created by SharpDevelop.
+ * User: lextm
+ * Date: 2008/6/7
+ * Time: 17:34
+ * 
+ * To change this template use Tools | Options | Coding | Edit Standard Headers.
+ */
+
+using System.Collections.Generic;
+
+namespace Lextm.SharpSnmpLib.Mib.Elements
+{
+    /// <summary>
+    /// Description of Exports.
+    /// </summary>
+    public sealed class Exports: IElement
+    {
+        private IModule _module;
+        private readonly IList<string> _types = new List<string>();
+
+        public Exports(IModule module, ISymbolEnumerator s)
+        {
+            _module = module;
+
+            Symbol previous = null;
+            Symbol current;
+            do
+            {
+                current = s.NextSymbol();
+
+                if (current == Symbol.EOL)
+                {
+                    continue;
+                }
+                else if (((current == Symbol.Comma) || (current == Symbol.Semicolon)) && (previous != null))
+                {
+                    previous.AssertIsValidIdentifier();
+                    _types.Add(previous.ToString());
+                }
+
+                previous = current;
+            }
+            while (current != Symbol.Semicolon);
+        }
+
+        #region IElement Member
+
+        public IModule Module
+        {
+            get { return _module; }
+        }
+
+        #endregion
+    }
+}
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/SharpSnmpLib/Mib/Elements/IDeclaration.cs
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/SharpSnmpLib/Mib/Elements/IDeclaration.cs	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/SharpSnmpLib/Mib/Elements/IDeclaration.cs	(revision 457)
@@ -0,0 +1,18 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace Lextm.SharpSnmpLib.Mib.Elements
+{
+    public interface IDeclaration: IElement
+    {
+        /// <summary>
+        /// Name.
+        /// </summary>
+        string Name
+        {
+            get;
+        }
+    }
+}
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/SharpSnmpLib/Mib/Elements/IElement.cs
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/SharpSnmpLib/Mib/Elements/IElement.cs	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/SharpSnmpLib/Mib/Elements/IElement.cs	(revision 457)
@@ -0,0 +1,35 @@
+// Construct interface.
+// Copyright (C) 2008-2010 Malcolm Crowe, Lex Li, and other contributors.
+// 
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+// 
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+// 
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+
+namespace Lextm.SharpSnmpLib.Mib.Elements
+{
+    /// <summary>
+    /// Construct interface.
+    /// </summary>
+    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1040:AvoidEmptyInterfaces")]
+    public interface IElement
+    {
+        /// <summary>
+        /// Containing module.
+        /// </summary>
+        IModule Module
+        {
+            get;
+        }
+
+    }
+}
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/SharpSnmpLib/Mib/Elements/ITypeReferrer.cs
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/SharpSnmpLib/Mib/Elements/ITypeReferrer.cs	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/SharpSnmpLib/Mib/Elements/ITypeReferrer.cs	(revision 457)
@@ -0,0 +1,10 @@
+using Lextm.SharpSnmpLib.Mib.Elements.Types;
+
+namespace Lextm.SharpSnmpLib.Mib.Elements
+{
+    public interface ITypeReferrer
+    {
+        ITypeAssignment ReferredType { get; set; }
+        ITypeAssignment BaseType { get; }
+    }
+}
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/SharpSnmpLib/Mib/Elements/Imports.cs
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/SharpSnmpLib/Mib/Elements/Imports.cs	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/SharpSnmpLib/Mib/Elements/Imports.cs	(revision 457)
@@ -0,0 +1,81 @@
+/*
+ * Created by SharpDevelop.
+ * User: lextm
+ * Date: 2008/5/31
+ * Time: 12:07
+ * 
+ * To change this template use Tools | Options | Coding | Edit Standard Headers.
+ */
+
+using System.Collections.Generic;
+
+namespace Lextm.SharpSnmpLib.Mib.Elements
+{
+    /// <summary>
+    /// The IMPORTS construct is used to specify items used in the current MIB module which are defined in another MIB module or ASN.1 module.
+    /// </summary>
+    public sealed class Imports : List<ImportsFrom>, IElement
+    {
+        private IModule _module;
+
+        /// <summary>
+        /// Creates an <see cref="Imports"/> instance.
+        /// </summary>
+        /// <param name="lexer"></param>
+        public Imports(IModule module, ISymbolEnumerator symbols)
+        {
+            _module = module;
+
+            Symbol current;
+            while ((current = symbols.NextSymbol()) != Symbol.Semicolon)
+            {
+                if (current == Symbol.EOL)
+                {
+                    continue;
+                }
+
+                ImportsFrom imports = new ImportsFrom(current, symbols);
+
+                this.Add(imports);
+            }
+        }
+
+        public IList<string> Dependents
+        {
+            get
+            {
+                List<string> result = new List<string>();
+
+                foreach (ImportsFrom import in this)
+                {
+                    result.Add(import.Module);
+                }
+
+                return result;
+            }
+        }
+
+        public ImportsFrom GetImportFromType(string type)
+        {
+            foreach (ImportsFrom import in this)
+            {
+                if (import.Types.Contains(type))
+                {
+                    return import;
+                }
+            }
+
+            return null;
+        }
+       
+        #region IElement Member
+
+        public IModule Module
+        {
+            get { return _module; }
+        }
+
+        #endregion
+
+    }
+}
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/SharpSnmpLib/Mib/Elements/ImportsFrom.cs
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/SharpSnmpLib/Mib/Elements/ImportsFrom.cs	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/SharpSnmpLib/Mib/Elements/ImportsFrom.cs	(revision 457)
@@ -0,0 +1,60 @@
+/*
+ * Created by SharpDevelop.
+ * User: lextm
+ * Date: 2008/5/31
+ * Time: 12:07
+ * 
+ * To change this template use Tools | Options | Coding | Edit Standard Headers.
+ */
+
+using System.Collections.Generic;
+
+namespace Lextm.SharpSnmpLib.Mib.Elements
+{
+    public sealed class ImportsFrom
+    {
+        private readonly string _module;
+        private readonly List<string> _types = new List<string>();
+
+        public ImportsFrom(Symbol last, ISymbolEnumerator symbols)
+        {
+            Symbol previous = last;
+            Symbol current;
+            while ((current = symbols.NextSymbol()) != Symbol.From)
+            {
+                if (current == Symbol.EOL) 
+                {
+                    continue;
+                }
+                
+                if (current == Symbol.Comma)
+                {
+                    previous.AssertIsValidIdentifier();
+                    _types.Add(previous.ToString());
+                }
+                
+                previous = current;
+            }
+
+            previous.AssertIsValidIdentifier();
+            _types.Add(previous.ToString());
+
+            _module = symbols.NextSymbol().ToString().ToUpperInvariant(); // module names are uppercase
+        }
+        
+        public string Module
+        {
+            get { return _module; }
+        }
+
+        public IList<string> Types
+        {
+            get { return _types; }
+        }
+
+        public override string ToString()
+        {
+            return string.Join(", ", _types.ToArray()) + " FROM " + _module;
+        }
+    }
+}
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/SharpSnmpLib/Mib/Elements/TrapType.cs
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/SharpSnmpLib/Mib/Elements/TrapType.cs	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/SharpSnmpLib/Mib/Elements/TrapType.cs	(revision 457)
@@ -0,0 +1,48 @@
+/*
+ * Created by SharpDevelop.
+ * User: lextm
+ * Date: 2008/5/31
+ * Time: 12:20
+ * 
+ * To change this template use Tools | Options | Coding | Edit Standard Headers.
+ */
+
+namespace Lextm.SharpSnmpLib.Mib.Elements
+{
+    public sealed class TrapType : IDeclaration
+    {
+        private readonly IModule _module;
+        private readonly string _name;
+        private readonly int _value;
+
+        public TrapType(IModule module, SymbolList preAssignSymbols, ISymbolEnumerator symbols)
+        {
+            _module = module;
+            _name = preAssignSymbols[0].ToString();
+
+            Symbol valueSymbol = symbols.NextNonEOLSymbol();
+
+            bool succeeded = int.TryParse(valueSymbol.ToString(), out _value);
+            valueSymbol.Assert(succeeded, "not a decimal");
+        }
+
+        public int Value
+        {
+            get { return _value; }
+        }
+
+        #region IDeclaration Member
+
+        public IModule Module
+        {
+            get { return _module; }
+        }
+
+        public string Name
+        {
+            get { return _name; }
+        }
+
+        #endregion
+    }
+}
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/SharpSnmpLib/Mib/Elements/Types/BaseType.cs
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/SharpSnmpLib/Mib/Elements/Types/BaseType.cs	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/SharpSnmpLib/Mib/Elements/Types/BaseType.cs	(revision 457)
@@ -0,0 +1,54 @@
+
+namespace Lextm.SharpSnmpLib.Mib.Elements.Types
+{
+    public abstract class BaseType : ITypeAssignment
+    {
+        private IModule _module;
+        private string _name;
+
+        protected BaseType(IModule module, string name)
+        {
+            _module = module;
+            _name   = name;
+        }
+
+        public virtual IModule Module
+        {
+            // differentiate between:
+            //    FddiTimeNano ::= INTEGER (0..2147483647) 
+            //    which is an IntegerType which appears under Types in a MibModule and therefore has a name and module
+            // and
+            //    SYNTAX INTEGER (0..2147483647) 
+            //    which is also an IntegerType but not defined as a separate type and therefore has NO name and NO module
+            get
+            {
+                if (!string.IsNullOrEmpty(_name))
+                {
+                    return _module;
+                }
+                else
+                {
+                    return null;
+                }                
+            }
+            protected set { _module = value; }
+        }
+
+        public virtual string Name
+        {
+            get
+            {
+                if (!string.IsNullOrEmpty(_name))
+                {
+                    return _name;
+                }
+                else
+                {
+                    return "{ Implicit Base Type }";
+                }
+            }
+            protected set { _name = value; }
+        }
+
+    }
+}
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/SharpSnmpLib/Mib/Elements/Types/BitsType.cs
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/SharpSnmpLib/Mib/Elements/Types/BitsType.cs	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/SharpSnmpLib/Mib/Elements/Types/BitsType.cs	(revision 457)
@@ -0,0 +1,26 @@
+using System;
+using System.Collections.Generic;
+
+namespace Lextm.SharpSnmpLib.Mib.Elements.Types
+{
+    public class BitsType : BaseType
+    {
+        private ValueMap _map;
+
+        public BitsType(IModule module, string name, ISymbolEnumerator symbols)
+            : base(module, name)
+        {
+            _map = Lexer.DecodeEnumerations(symbols);
+        }
+
+        public ValueMap Map
+        {
+            get { return _map; }
+        }
+
+        public string this[int value]
+        {
+            get { return _map[value]; }
+        }
+    }
+}
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/SharpSnmpLib/Mib/Elements/Types/Choice.cs
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/SharpSnmpLib/Mib/Elements/Types/Choice.cs	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/SharpSnmpLib/Mib/Elements/Types/Choice.cs	(revision 457)
@@ -0,0 +1,35 @@
+/*
+ * Created by SharpDevelop.
+ * User: lextm
+ * Date: 2008/5/31
+ * Time: 11:39
+ * 
+ * To change this template use Tools | Options | Coding | Edit Standard Headers.
+ */
+
+namespace Lextm.SharpSnmpLib.Mib.Elements.Types
+{
+    /// <summary>
+    /// The CHOICE type represents a list of alternatives..
+    /// </summary>
+    public sealed class Choice : BaseType
+    {
+        /// <summary>
+        /// Creates a <see cref="Choice"/> instance.
+        /// </summary>
+        /// <param name="module"></param>
+        /// <param name="name"></param>
+        /// <param name="lexer"></param>
+        public Choice(IModule module, string name, ISymbolEnumerator symbols)
+            : base(module, name)
+        {
+            while (symbols.NextNonEOLSymbol() != Symbol.OpenBracket)
+            {
+            }
+
+            while (symbols.NextNonEOLSymbol() != Symbol.CloseBracket)
+            {
+            }
+        }
+    }
+}
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/SharpSnmpLib/Mib/Elements/Types/ITypeAssignment.cs
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/SharpSnmpLib/Mib/Elements/Types/ITypeAssignment.cs	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/SharpSnmpLib/Mib/Elements/Types/ITypeAssignment.cs	(revision 457)
@@ -0,0 +1,6 @@
+namespace Lextm.SharpSnmpLib.Mib.Elements.Types
+{
+    public interface ITypeAssignment : IDeclaration
+    {
+    }
+}
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/SharpSnmpLib/Mib/Elements/Types/IntegerType.cs
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/SharpSnmpLib/Mib/Elements/Types/IntegerType.cs	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/SharpSnmpLib/Mib/Elements/Types/IntegerType.cs	(revision 457)
@@ -0,0 +1,117 @@
+/*
+ * Created by SharpDevelop.
+ * User: lextm
+ * Date: 2008/7/25
+ * Time: 20:41
+ * 
+ * To change this template use Tools | Options | Coding | Edit Standard Headers.
+ */
+
+using System;
+using System.Collections.Generic;
+
+namespace Lextm.SharpSnmpLib.Mib.Elements.Types
+{
+    /// <summary>
+    /// The INTEGER type represents a list of alternatives, or a range of numbers..
+    /// Includes Integer32 as it's indistinguishable from INTEGER.
+    /// </summary>
+    /**
+     * As this type is used for Integer32 as well as INTEGER it incorrectly
+     * allows enumeration sub-typing of Integer32.  This is ok as currently we
+     * do not care about detecting incorrect MIBs and this doesn't block the
+     * decoding of correct MIBs.
+     */
+    public sealed class IntegerType : BaseType
+    {
+        public enum Types
+        {
+            Integer,
+            Integer32
+        }
+
+        private Types _type;
+        private bool _isEnumeration;
+        private ValueMap _map;
+        private ValueRanges _ranges;
+
+        /// <summary>
+        /// Creates an <see cref="IntegerType"/> instance.
+        /// </summary>
+        /// <param name="module"></param>
+        /// <param name="name"></param>
+        /// <param name="enumerator"></param>
+        public IntegerType(IModule module, string name, Symbol type, ISymbolEnumerator symbols)
+            : base (module, name)
+        {
+            Types? t = GetExactType(type);
+            type.Assert(t.HasValue, "Unknown symbol for unsigned type!");
+            _type = t.Value;
+
+            _isEnumeration = false;
+
+            Symbol current = symbols.NextNonEOLSymbol();
+            if (current == Symbol.OpenBracket)
+            {
+                _isEnumeration = true;
+                symbols.PutBack(current);
+                _map = Lexer.DecodeEnumerations(symbols);
+            }
+            else if (current == Symbol.OpenParentheses)
+            {
+                symbols.PutBack(current);
+                _ranges = Lexer.DecodeRanges(symbols);
+                current.Assert(!_ranges.IsSizeDeclaration, "SIZE keyword is not allowed for ranges of integer types!");
+            }
+            else
+            {
+                symbols.PutBack(current);
+            }
+        }
+
+        public Types Type
+        {
+            get { return _type; }
+        }
+
+        public ValueRanges Ranges
+        {
+            get { return _ranges; }
+        }
+
+        public bool IsEnumeration
+        {
+            get
+            {
+                return _isEnumeration;
+            }
+        }
+
+        public ValueMap Enumeration
+        {
+            get { return _isEnumeration ? _map : null; }
+        }
+
+        internal static Types? GetExactType(Symbol symbol)
+        {
+            if (symbol == Symbol.Integer)
+            {
+                // represents the ASN.1 builtin INTEGER type:
+                //  may be represent any arbitrary (signed/unsigned) integer (in theory may have any size)
+                return Types.Integer;
+            }
+            else if (symbol == Symbol.Integer32)
+            {
+                // Integer32 ::= INTEGER (-2147483648..2147483647) // from SNMPv2-SMI
+                return Types.Integer32;
+            }
+
+            return null;
+        }
+
+        internal static bool IsIntegerType(Symbol symbol)
+        {
+            return GetExactType(symbol).HasValue;
+        }
+    }
+}
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/SharpSnmpLib/Mib/Elements/Types/IpAddressType.cs
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/SharpSnmpLib/Mib/Elements/Types/IpAddressType.cs	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/SharpSnmpLib/Mib/Elements/Types/IpAddressType.cs	(revision 457)
@@ -0,0 +1,21 @@
+
+namespace Lextm.SharpSnmpLib.Mib.Elements.Types
+{
+    public class IpAddressType : OctetStringType
+    {
+        public IpAddressType(IModule module, string name, ISymbolEnumerator symbols)
+            : base(module, name, symbols)
+        {
+            if (this.Size.Count != 0)
+            {
+                throw new MibException("Size definition not allowed for IpAddress type!");
+            }
+
+            // IpAddress type is defined as:
+            // IpAddress ::=
+            //    [APPLICATION 0]
+            //        IMPLICIT OCTET STRING (SIZE (4))
+            this.Size.Add(new ValueRange(4, null));
+        }
+    }
+}
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/SharpSnmpLib/Mib/Elements/Types/Macro.cs
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/SharpSnmpLib/Mib/Elements/Types/Macro.cs	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/SharpSnmpLib/Mib/Elements/Types/Macro.cs	(revision 457)
@@ -0,0 +1,34 @@
+
+namespace Lextm.SharpSnmpLib.Mib.Elements.Types
+{
+    public sealed class Macro : ITypeAssignment
+    {
+        private IModule _module;
+        private string _name;
+
+        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1804:RemoveUnusedLocals", MessageId = "temp")]
+        public Macro(IModule module, SymbolList preAssignSymbols, ISymbolEnumerator symbols)
+        {
+            _module = module;
+            _name = preAssignSymbols[0].ToString();
+            
+            while (symbols.NextNonEOLSymbol() != Symbol.Begin)
+            {                
+            }
+
+            while (symbols.NextNonEOLSymbol() != Symbol.End)
+            {
+            }
+        }
+
+        public IModule Module
+        {
+            get { return _module; }
+        }
+
+        public string Name
+        {
+            get { return _name; }
+        }
+    }
+}
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/SharpSnmpLib/Mib/Elements/Types/ObjectIdentifierType.cs
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/SharpSnmpLib/Mib/Elements/Types/ObjectIdentifierType.cs	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/SharpSnmpLib/Mib/Elements/Types/ObjectIdentifierType.cs	(revision 457)
@@ -0,0 +1,11 @@
+
+namespace Lextm.SharpSnmpLib.Mib.Elements.Types
+{
+    public class ObjectIdentifierType : BaseType
+    {
+        public ObjectIdentifierType(IModule module, string name, ISymbolEnumerator symbols)
+            : base(module, name)
+        {
+        }
+    }
+}
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/SharpSnmpLib/Mib/Elements/Types/OctetStringType.cs
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/SharpSnmpLib/Mib/Elements/Types/OctetStringType.cs	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/SharpSnmpLib/Mib/Elements/Types/OctetStringType.cs	(revision 457)
@@ -0,0 +1,31 @@
+using System.Collections.Generic;
+
+namespace Lextm.SharpSnmpLib.Mib.Elements.Types
+{
+    public class OctetStringType : BaseType
+    {
+        private ValueRanges _size;
+
+        public OctetStringType(IModule module, string name, ISymbolEnumerator symbols)
+            : base(module, name)
+        {
+            Symbol current = symbols.NextNonEOLSymbol();
+            if (current == Symbol.OpenParentheses)
+            {
+                symbols.PutBack(current);
+                _size = Lexer.DecodeRanges(symbols);
+                current.Assert(_size.IsSizeDeclaration, "SIZE keyword is required for ranges of octet string!");
+            }
+            else
+            {
+                symbols.PutBack(current);
+                _size   = new ValueRanges(isSizeDecl: true);
+            }
+        }
+
+        public ValueRanges Size
+        {
+            get { return _size; }
+        }
+    }
+}
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/SharpSnmpLib/Mib/Elements/Types/OpaqueType.cs
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/SharpSnmpLib/Mib/Elements/Types/OpaqueType.cs	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/SharpSnmpLib/Mib/Elements/Types/OpaqueType.cs	(revision 457)
@@ -0,0 +1,11 @@
+
+namespace Lextm.SharpSnmpLib.Mib.Elements.Types
+{
+    public class OpaqueType : OctetStringType
+    {
+        public OpaqueType(IModule module, string name, ISymbolEnumerator symbols)
+            : base(module, name, symbols)
+        {
+        }
+    }
+}
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/SharpSnmpLib/Mib/Elements/Types/Sequence.cs
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/SharpSnmpLib/Mib/Elements/Types/Sequence.cs	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/SharpSnmpLib/Mib/Elements/Types/Sequence.cs	(revision 457)
@@ -0,0 +1,46 @@
+/*
+ * Created by SharpDevelop.
+ * User: lextm
+ * Date: 2008/5/21
+ * Time: 19:43
+ * 
+ * To change this template use Tools | Options | Coding | Edit Standard Headers.
+ */
+
+
+namespace Lextm.SharpSnmpLib.Mib.Elements.Types
+{
+    /// <summary>
+    /// The SEQUENCE type represents a set of specified types. This is roughtly analogous to a <code>struct</code> in C.
+    /// </summary>
+    public sealed class Sequence : BaseType
+    {
+        /// <summary>
+        /// Creates a <see cref="Sequence" /> instance.
+        /// </summary>
+        /// <param name="module">The module.</param>
+        /// <param name="name">The name.</param>
+        /// <param name="symbols">The enumerator.</param>
+        public Sequence(IModule module, string name, ISymbolEnumerator symbols)
+            : base(module, name)
+        {
+            // parse between ( )
+            Symbol temp = symbols.NextNonEOLSymbol();
+            int bracketSection = 0;
+            temp.Expect(Symbol.OpenBracket);
+            bracketSection++;
+            while (bracketSection > 0)
+            {
+                temp = symbols.NextNonEOLSymbol();
+                if (temp == Symbol.OpenBracket)
+                {
+                    bracketSection++;
+                }
+                else if (temp == Symbol.CloseBracket)
+                {
+                    bracketSection--;
+                }
+            }
+        }
+    }
+}
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/SharpSnmpLib/Mib/Elements/Types/SequenceOf.cs
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/SharpSnmpLib/Mib/Elements/Types/SequenceOf.cs	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/SharpSnmpLib/Mib/Elements/Types/SequenceOf.cs	(revision 457)
@@ -0,0 +1,23 @@
+using System.Collections.Generic;
+
+namespace Lextm.SharpSnmpLib.Mib.Elements.Types
+{
+    /// <summary>
+    /// The SEQUENCE OF type represents a list of data sets..
+    /// </summary>
+    public sealed class SequenceOf : BaseType
+    {
+        private string _type;
+
+        public SequenceOf(IModule module, string name, ISymbolEnumerator sym)
+            : base(module, name)
+        {
+            _type = sym.NextNonEOLSymbol().ToString();
+        }
+
+        public string Type
+        {
+            get { return _type; }
+        }
+    }
+}
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/SharpSnmpLib/Mib/Elements/Types/TextualConvention.cs
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/SharpSnmpLib/Mib/Elements/Types/TextualConvention.cs	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/SharpSnmpLib/Mib/Elements/Types/TextualConvention.cs	(revision 457)
@@ -0,0 +1,238 @@
+using System;
+
+namespace Lextm.SharpSnmpLib.Mib.Elements.Types
+{
+    public sealed class TextualConvention : ITypeAssignment, ITypeReferrer
+    {
+        private IModule _module;
+        private string _name;
+        private DisplayHint _displayHint;
+        private Status _status;
+        private string _description;
+        private string _reference;
+        private ITypeAssignment _syntax;
+
+        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA1801:ReviewUnusedParameters", MessageId = "module")]
+        public TextualConvention(IModule module, string name, ISymbolEnumerator symbols)
+        {
+            _module = module;
+            _name = name;
+
+            _displayHint = ParseDisplayHint(symbols);
+            _status      = ParseStatus(symbols);
+            _description = ParseDescription(symbols);
+            _reference   = ParseReference(symbols);
+            _syntax      = ParseSyntax(module, symbols);
+        }
+
+        private static DisplayHint ParseDisplayHint(ISymbolEnumerator symbols)
+        {
+            Symbol current = symbols.NextNonEOLSymbol();
+
+            if (current == Symbol.DisplayHint)
+            {
+                return new DisplayHint(symbols.NextNonEOLSymbol().ToString().Trim(new char[] { '"' }));
+            }
+
+            symbols.PutBack(current);
+            return null;
+        }
+
+        private static Status ParseStatus(ISymbolEnumerator symbols)
+        {
+            Symbol current = symbols.NextNonEOLSymbol();
+            current.Expect(Symbol.Status);
+
+            try
+            {
+                return (Status)Enum.Parse(typeof(Status), symbols.NextNonEOLSymbol().ToString());
+            }
+            catch (ArgumentException)
+            {
+                current.Assert(false, "Invalid/Unknown status");
+            }
+
+            return Status.current;
+        }
+
+        private static string ParseDescription(ISymbolEnumerator symbols)
+        {
+            Symbol current = symbols.NextNonEOLSymbol();
+            current.Expect(Symbol.Description);
+
+            return symbols.NextNonEOLSymbol().ToString().Trim(new char[] { '"' });
+        }
+
+        private static string ParseReference(ISymbolEnumerator symbols)
+        {
+            Symbol current = symbols.NextNonEOLSymbol();
+
+            if (current == Symbol.Reference)
+            {
+                string reference = symbols.NextNonEOLSymbol().ToString();
+                if ((reference.Length >= 2) && reference.StartsWith("\"") && reference.EndsWith("\""))
+                {
+                    return reference.Substring(1, reference.Length-2);
+                }
+
+                return reference;
+            }
+
+            symbols.PutBack(current);
+            return null;
+        }
+
+        private static ITypeAssignment ParseSyntax(IModule module, ISymbolEnumerator symbols)
+        {
+            Symbol current = symbols.NextNonEOLSymbol();
+            current.Expect(Symbol.Syntax);
+
+            /* 
+             * RFC2579 definition:
+             *       Syntax ::=   -- Must be one of the following:
+             *                    -- a base type (or its refinement), or
+             *                    -- a BITS pseudo-type
+             *               type
+             *             | "BITS" "{" NamedBits "}"
+             *
+             * From section 3.5:
+             *      The data structure must be one of the alternatives defined
+             *      in the ObjectSyntax CHOICE or the BITS construct.  Note
+             *      that this means that the SYNTAX clause of a Textual
+             *      Convention can not refer to a previously defined Textual
+             *      Convention.
+             *      
+             *      The SYNTAX clause of a TEXTUAL CONVENTION macro may be
+             *      sub-typed in the same way as the SYNTAX clause of an
+             *      OBJECT-TYPE macro.
+             * 
+             * Therefore the possible values are (grouped by underlying type):
+             *      INTEGER, Integer32
+             *      OCTET STRING, Opaque
+             *      OBJECT IDENTIFIER
+             *      IpAddress
+             *      Counter64
+             *      Unsigned32, Counter32, Gauge32, TimeTicks
+             *      BITS
+             * With appropriate sub-typing.
+             */
+
+            return Lexer.ParseBasicTypeDef(module, String.Empty, symbols, isMacroSyntax: true);
+        }
+
+        public IModule Module
+        {
+            get { return _module; }
+        }
+
+        public string Name
+        {
+            get { return _name; }
+        }
+
+        public string DisplayHint
+        {
+            get { return _displayHint == null ? null : _displayHint.ToString(); }
+        }
+
+        public Status Status
+        {
+            get { return _status; }
+        }
+
+        public string Description
+        {
+            get { return _description; }
+        }
+
+        public string Reference
+        {
+            get { return _reference; }
+        }
+
+        public ITypeAssignment Syntax
+        {
+            get { return _syntax; }
+        }
+
+        //internal object Decode(Variable v)
+        //{
+        //    if (_syntax is IntegerType)
+        //    {
+        //        Integer32 i = v.Data as Integer32;
+        //        if (i == null || (_syntax as IntegerType).IsEnumeration)
+        //        {
+        //            return null;
+        //        }
+        //        else if (_displayHint != null)
+        //        {
+        //            return _displayHint.Decode(i.ToInt32());
+        //        }
+        //        else
+        //        {
+        //            return i.ToInt32();
+        //        }
+        //    }
+        //    else if (_syntax is UnsignedType)
+        //    {
+        //        Integer32 i = v.Data as Integer32;
+        //        if (i == null)
+        //        {
+        //            return null;
+        //        }
+        //        else if (_displayHint != null)
+        //        {
+        //            return _displayHint.Decode(i.ToInt32());
+        //        }
+        //        else
+        //        {
+        //            return i.ToInt32();
+        //        }
+        //    }
+        //    else if (_syntax is OctetStringType)
+        //    {
+        //        OctetString o = v.Data as OctetString;
+        //        if (o == null)
+        //        {
+        //            return null;
+        //        }
+        //        else
+        //        {
+        //            // TODO: Follow the format specifier for octet strings.
+        //            return null;
+        //        }
+        //    }
+        //    else
+        //    {
+        //        return null;
+        //    }
+        //}
+
+        #region ITypeReferrer Member
+
+        public ITypeAssignment ReferredType
+        {
+            get { return _syntax; }
+            set { _syntax = value; }
+        }
+
+        public ITypeAssignment BaseType
+        {
+            get
+            {
+                ITypeReferrer   tr     = this;
+                ITypeAssignment result = this;
+
+                while ((tr != null) && (tr.ReferredType != null))
+                {
+                    result = tr.ReferredType;
+                    tr = tr.ReferredType as ITypeReferrer;
+                }
+
+                return result;
+            }
+        }
+
+        #endregion
+    }
+}
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/SharpSnmpLib/Mib/Elements/Types/TypeAssignment.cs
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/SharpSnmpLib/Mib/Elements/Types/TypeAssignment.cs	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/SharpSnmpLib/Mib/Elements/Types/TypeAssignment.cs	(revision 457)
@@ -0,0 +1,147 @@
+/*
+ * Created by SharpDevelop.
+ * User: lextm
+ * Date: 2008/5/18
+ * Time: 13:24
+ * 
+ * To change this template use Tools | Options | Coding | Edit Standard Headers.
+ */
+using System;
+using System.Collections.Generic;
+
+namespace Lextm.SharpSnmpLib.Mib.Elements.Types
+{
+    /* Please be aware of the following possible constructs:
+     * 
+     *    isnsRegEntityIndex          OBJECT-TYPE
+     *    SYNTAX                      IsnsEntityIndexIdOrZero
+     *                                ( 1 .. 4294967295 )
+     *    MAX-ACCESS              not-accessible
+     * 
+     * 
+     */
+
+    /// <summary/>
+    /// </summary>
+    public sealed class TypeAssignment : ITypeAssignment
+    {
+        private IModule _module;
+        private string _name;
+        private string _type;
+        private ValueRanges _ranges;
+        private ValueMap _map;
+
+        /// <summary>
+        /// Creates an <see cref="TypeAssignment" />.
+        /// </summary>
+        /// <param name="module">The module.</param>
+        /// <param name="name">The name.</param>
+        /// <param name="type">The type.</param>
+        /// <param name="symbols">The symbols.</param>
+        /// <param name="isMacroSyntax">if set to <c>true</c> indicates that the syntax clause of a macro is parsed (e.g. OBJECT-TYPE, TEXTUAL-CONVENTION).</param>
+        public TypeAssignment(IModule module, string name, Symbol type, ISymbolEnumerator symbols, bool isMacroSyntax)
+        {
+            _module = module;
+            _name   = name;
+
+            SymbolList typeSymbols = new SymbolList();
+            typeSymbols.Add(type);
+
+            Symbol current = symbols.NextSymbol();
+            while (current != Symbol.EOL)
+            {
+                if (current == Symbol.OpenParentheses)
+                {
+                    // parse range of unknown type
+                    symbols.PutBack(current);
+                    _ranges = Lexer.DecodeRanges(symbols);
+                    break;
+                }
+                else if (current == Symbol.OpenBracket)
+                {
+                    symbols.PutBack(current);
+                    _map = Lexer.DecodeEnumerations(symbols);
+                    break;
+                }
+
+                typeSymbols.Add(current);
+                current = symbols.NextSymbol();
+            }
+
+            _type = typeSymbols.Join(" ");
+
+            if ((_ranges == null) && (_map == null))
+            {
+                current = symbols.NextNonEOLSymbol();
+                if (current == Symbol.OpenParentheses)
+                {
+                    // parse range of unknown type
+                    symbols.PutBack(current);
+                    _ranges = Lexer.DecodeRanges(symbols);
+                }
+                else if (current == Symbol.OpenBracket)
+                {
+                    symbols.PutBack(current);
+                    _map = Lexer.DecodeEnumerations(symbols);
+                }
+                else if (current != null)
+                {
+                    symbols.PutBack(current);
+                }
+            }
+
+            if (isMacroSyntax)
+            {
+                // inside a macro the syntax is limited to one line, except there are brackets used for ranges/enums
+                return;
+            }
+
+            // outside macro Syntax clause we  wait for two consecutive linebreaks with a following valid identifier as end condition         
+            Symbol previous = current;
+            Symbol veryPrevious = null;
+
+            while ((current = symbols.NextSymbol()) != null)
+            {
+                if ((veryPrevious == Symbol.EOL) && (previous == Symbol.EOL) && current.IsValidIdentifier())
+                {
+                    symbols.PutBack(current);
+                    return;
+                }
+
+                veryPrevious = previous;
+                previous = current;
+            }
+            
+            previous.Assert(false, "end of file reached");
+        }
+
+        public string Type
+        {
+            get { return _type; }
+        }
+
+        public ValueRanges Ranges
+        {
+            get { return _ranges; }
+        }
+
+        public IDictionary<long, string> Map
+        {
+            get { return _map; }
+        }
+
+        #region ITypeAssignment Member
+
+        public IModule Module
+        {
+            get { return _module; }
+        }
+
+        public string Name
+        {
+            get { return _name; }
+        }
+
+        #endregion
+    }
+}
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/SharpSnmpLib/Mib/Elements/Types/UnsignedType.cs
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/SharpSnmpLib/Mib/Elements/Types/UnsignedType.cs	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/SharpSnmpLib/Mib/Elements/Types/UnsignedType.cs	(revision 457)
@@ -0,0 +1,103 @@
+using System.Collections.Generic;
+
+namespace Lextm.SharpSnmpLib.Mib.Elements.Types
+{
+    /**
+     * As this type is used for Counter32 and TimeTicks as well as Unsigned32
+     * and Gauge32 it incorrectly allows range restrictions of Counter32 and
+     * TimeTicks.  This is ok as currently we do not care about detecting
+     * incorrect MIBs and this doesn't block the decoding of correct MIBs.
+     */
+    public class UnsignedType : BaseType
+    {
+        public enum Types
+        {
+            Unsigned32,
+            Gauge32,
+            Counter32,
+            TimeTicks,
+            Counter64,
+        }
+
+        private Types _type;
+        private ValueRanges _ranges;
+
+        public UnsignedType(IModule module, string name, Symbol type, ISymbolEnumerator symbols)
+            : base(module, name)
+        {
+            Types? t = GetExactType(type);
+            type.Assert(t.HasValue, "Unknown symbol for unsigned type!");
+            _type = t.Value;
+
+            Symbol current = symbols.NextNonEOLSymbol();
+            if (current == Symbol.OpenParentheses)
+            {
+                current.Assert((_type != Types.Counter64), "Ranges are not supported for Counter64 type!"); // our internal struct can only hold int64 values
+
+                symbols.PutBack(current);
+                _ranges = Lexer.DecodeRanges(symbols);
+                current.Assert(!_ranges.IsSizeDeclaration, "SIZE keyword is not allowed for ranges of unsigned types!");
+            }
+            else
+            {
+                symbols.PutBack(current);
+            }
+        }
+
+        public Types Type
+        {
+            get { return _type; }
+        }
+
+        public ValueRanges Ranges
+        {
+            get { return _ranges; }
+        }
+
+        internal static Types? GetExactType(Symbol symbol)
+        {
+            if (symbol == Symbol.Unsigned32)
+            {
+                // [APPLICATION 2] IMPLICIT INTEGER (0..4294967295) // from SNMPv2-SMI
+                return Types.Unsigned32;
+            }
+            else if (symbol == Symbol.Gauge32)
+            {
+                // [APPLICATION 2] IMPLICIT INTEGER (0..4294967295) // from SNMPv2-SMI
+                return Types.Gauge32;
+            }
+            else if (symbol == Symbol.Counter32)
+            {
+                // [APPLICATION 1] IMPLICIT INTEGER (0..4294967295) // from SNMPv2-SMI
+                return Types.Counter32;
+            }
+            else if (symbol == Symbol.TimeTicks)
+            {
+                // [APPLICATION 3] IMPLICIT INTEGER (0..4294967295) // from SNMPv2-SMI + RFC1155-SMI
+                return Types.TimeTicks;
+            }
+            else if (symbol == Symbol.Gauge)
+            {
+                // [APPLICATION 2] IMPLICIT INTEGER (0..4294967295) // from RFC1155-SMI
+                return Types.Gauge32;
+            }
+            else if (symbol == Symbol.Counter)
+            {
+                // [APPLICATION 1] IMPLICIT INTEGER (0..4294967295) // from RFC1155-SMI
+                return Types.Counter32;
+            }
+            else if (symbol == Symbol.Counter64)
+            {
+               // [APPLICATION 6] IMPLICIT INTEGER (0..18446744073709551615) // from SNMPv2-SMI
+               return Types.Counter64;
+            }
+
+            return null;
+        }
+
+        internal static bool IsUnsignedType(Symbol symbol)
+        {
+            return GetExactType(symbol).HasValue;
+        }
+    }
+}
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/SharpSnmpLib/Mib/IModule.cs
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/SharpSnmpLib/Mib/IModule.cs	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/SharpSnmpLib/Mib/IModule.cs	(revision 457)
@@ -0,0 +1,81 @@
+// Module interface.
+// Copyright (C) 2008-2010 Malcolm Crowe, Lex Li, and other contributors.
+// 
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+// 
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+// 
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+
+/*
+ * Created by SharpDevelop.
+ * User: lextm
+ * Date: 5/1/2009
+ * Time: 10:40 AM
+ * 
+ * To change this template use Tools | Options | Coding | Edit Standard Headers.
+ */
+using System.Collections.Generic;
+using Lextm.SharpSnmpLib.Mib.Elements.Entities;
+using Lextm.SharpSnmpLib.Mib.Elements.Types;
+using Lextm.SharpSnmpLib.Mib.Elements;
+
+namespace Lextm.SharpSnmpLib.Mib
+{
+    /// <summary>
+    /// MIB Module interface.
+    /// </summary>
+    public interface IModule
+    {
+        /// <summary>
+        /// Module name.
+        /// </summary>
+        string Name
+        {
+            get;
+        }
+
+        Exports Exports
+        {
+            get;
+        }
+
+        Imports Imports
+        {
+            get;
+        }
+
+        /// <summary>
+        /// Entities + Types + all other elements implementing IDeclaration
+        /// </summary>
+        IList<IDeclaration> Declarations
+        {
+            get;
+        }
+
+        /// <summary>
+        /// Entities.
+        /// </summary>
+        IList<IEntity> Entities
+        {
+            get;
+        }
+
+        /// <summary>
+        /// Known types.
+        /// </summary>
+        IList<ITypeAssignment> Types
+        {
+            get;
+        }
+       
+    }
+}
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/SharpSnmpLib/Mib/ISymbolEnumerator.cs
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/SharpSnmpLib/Mib/ISymbolEnumerator.cs	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/SharpSnmpLib/Mib/ISymbolEnumerator.cs	(revision 457)
@@ -0,0 +1,9 @@
+using System.Collections.Generic;
+
+namespace Lextm.SharpSnmpLib.Mib
+{
+    public interface ISymbolEnumerator: IEnumerator<Symbol>
+    {
+        bool PutBack(Symbol item);
+    }
+}
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/SharpSnmpLib/Mib/Lexer.cs
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/SharpSnmpLib/Mib/Lexer.cs	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/SharpSnmpLib/Mib/Lexer.cs	(revision 457)
@@ -0,0 +1,581 @@
+/*
+ * Created by SharpDevelop.
+ * User: lextm
+ * Date: 2008/5/17
+ * Time: 16:50
+ *
+ * To change this template use Tools | Options | Coding | Edit Standard Headers.
+ */
+
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Text;
+using Lextm.SharpSnmpLib.Mib.Elements.Types;
+
+namespace Lextm.SharpSnmpLib.Mib
+{
+    /// <summary>
+    /// Lexer class that parses MIB files into symbol list.
+    /// </summary>
+    public sealed class Lexer
+    {
+        private readonly SymbolList _symbols = new SymbolList();
+
+        public Lexer(string file)
+            : this(file, new StreamReader(file))
+        {
+        }
+
+        public Lexer(string file, TextReader stream)
+        {
+            this.Parse(file, stream);
+        }
+
+
+        public ISymbolEnumerator GetEnumerator()
+        {
+            return _symbols.GetSymbolEnumerator();
+        }
+
+
+        #region Parsing of MIB File
+
+        private class ParseParams
+        {
+            public string File;
+            public StringBuilder Temp = new StringBuilder();
+            public bool StringSection = false;
+            public bool AssignSection = false;
+            public bool AssignAhead = false;
+            public bool DotSection = false;
+
+        }
+
+        /// <summary>
+        /// Parses MIB file to symbol list.
+        /// </summary>
+        /// <param name="file">File</param>
+        /// <param name="stream">File stream</param>
+        private void Parse(string file, TextReader stream)
+        {
+            if (stream == null)
+            {
+                throw new ArgumentNullException("stream");
+            }
+
+            ParseParams pp = new ParseParams();
+            pp.File = file;
+            
+            string line;
+            int row = 0;
+            while ((line = stream.ReadLine()) != null)
+            {
+                if (!pp.StringSection && line.TrimStart().StartsWith("--", StringComparison.Ordinal))
+                {
+                    row++;
+                    continue; // commented line
+                }
+
+                ParseLine(pp, line, row);
+                row++;
+            }
+        }
+
+        private void ParseLine(ParseParams pp, string line, int row)
+        {
+            line = line + "\n";
+            int count = line.Length;
+            for (int i = 0; i < count; i++)
+            {
+                char current = line[i];
+                bool moveNext = Parse(pp, current, row, i);
+                if (moveNext)
+                {
+                    break;
+                }
+            }
+        }
+
+        private bool Parse(ParseParams pp, char current, int row, int column)
+        {
+            switch (current)
+            {
+                case '\n':
+                case '{':
+                case '}':
+                case '(':
+                case ')':
+                case '[':
+                case ']':
+                case ';':
+                case ',':
+                case '|':
+                    if (!pp.StringSection)
+                    {
+                        bool moveNext = ParseLastSymbol(pp, row, column);
+                        if (moveNext)
+                        {
+                            _symbols.Add(CreateSpecialSymbol(pp.File, '\n', row, column));
+                            return true;
+                        }
+
+                        _symbols.Add(CreateSpecialSymbol(pp.File, current, row, column));
+                        return false;
+                    }
+
+                    break;
+                case '"':
+                    pp.StringSection = !pp.StringSection;
+                    break;
+                case '\r':
+                    return false;
+                default:
+                    if ((int)current == 0x1A)
+                    {
+                        // IMPORTANT: ignore invisible characters such as SUB.
+                        return false;
+                    }
+                    
+                    if (Char.IsWhiteSpace(current) && !pp.AssignSection && !pp.StringSection)
+                    {                     
+                        bool moveNext = ParseLastSymbol(pp, row, column);
+                        if (moveNext)
+                        {
+                            _symbols.Add(CreateSpecialSymbol(pp.File, '\n', row, column));
+                            return true;
+                        }
+
+                        return false;
+                    }
+                    
+                    if (pp.AssignAhead)
+                    {
+                        pp.AssignAhead = false;
+                        ParseLastSymbol(pp, row, column);
+                        break;
+                    }
+
+                    if (pp.DotSection && current != '.')
+                    {
+                        ParseLastSymbol(pp, row, column);
+                        pp.DotSection = false;
+                    }
+
+                    if (current == '.' && !pp.StringSection)
+                    {
+                        if (!pp.DotSection)
+                        {
+                            ParseLastSymbol(pp, row, column);
+                            pp.DotSection = true;
+                        }
+                    }
+                    
+                    if (current == ':' && !pp.StringSection)
+                    {    
+                        if (!pp.AssignSection)
+                        {
+                            ParseLastSymbol(pp, row, column);
+                        }
+                        
+                        pp.AssignSection = true;
+                    }
+                    
+                    if (current == '=' && !pp.StringSection)
+                    {
+                        pp.AssignSection = false; 
+                        pp.AssignAhead = true;
+                    }
+
+                    break;
+            }
+
+            pp.Temp.Append(current);
+            return false;
+        }
+
+        private bool ParseLastSymbol(ParseParams pp, int row, int column)
+        {
+            if (pp.Temp.Length > 0)
+            {
+                Symbol s = new Symbol(pp.File, pp.Temp.ToString(), row, column);
+
+                pp.Temp.Length = 0;
+
+                if (s.ToString().StartsWith(Symbol.Comment.ToString()))
+                {
+                    // ignore the rest symbols on this line because they are in comment.
+                    return true;
+                }
+
+                _symbols.Add(s);
+            }
+
+            return false;
+        }
+
+        private static Symbol CreateSpecialSymbol(string file, char value, int row, int column)
+        {
+            string str;
+            switch (value)
+            {
+                case '\n':
+                    str = Environment.NewLine;
+                    break;
+                case '{':
+                    str = "{";
+                    break;
+                case '}':
+                    str = "}";
+                    break;
+                case '(':
+                    str = "(";
+                    break;
+                case ')':
+                    str = ")";
+                    break;
+                case '[':
+                    str = "[";
+                    break;
+                case ']':
+                    str = "]";
+                    break;
+                case ';':
+                    str = ";";
+                    break;
+                case ',':
+                    str = ",";
+                    break;
+                case '|':
+                    str = "|";
+                    break;
+                default:
+                    throw new ArgumentException("value is not a special character");
+            }
+
+            return new Symbol(file, str, row, column);
+        }
+
+        #endregion
+
+        #region Static Parse Helper
+
+        public static ITypeAssignment ParseBasicTypeDef(IModule module, string name, ISymbolEnumerator symbols, bool isMacroSyntax = false)
+        {
+            Symbol current = symbols.NextNonEOLSymbol();
+
+            if (current == Symbol.Bits)
+            {
+                return new BitsType(module, name, symbols);
+            }
+            if (IntegerType.IsIntegerType(current))
+            {
+                return new IntegerType(module, name, current, symbols);
+            }
+            if (UnsignedType.IsUnsignedType(current))
+            {
+                return new UnsignedType(module, name, current, symbols);
+            }
+            if (current == Symbol.Opaque)
+            {
+                return new OpaqueType(module, name, symbols);
+            }
+            if (current == Symbol.IpAddress)
+            {
+                return new IpAddressType(module, name, symbols);
+            }
+            if (current == Symbol.TextualConvention)
+            {
+                return new TextualConvention(module, name, symbols);
+            }
+            if (current == Symbol.Octet)
+            {
+                Symbol next = symbols.NextNonEOLSymbol();
+
+                if (next == Symbol.String)
+                {
+                    return new OctetStringType(module, name, symbols);
+                }
+
+                symbols.PutBack(next);
+            }
+            if (current == Symbol.Object)
+            {
+                Symbol next = symbols.NextNonEOLSymbol();
+
+                if (next == Symbol.Identifier)
+                {
+                    return new ObjectIdentifierType(module, name, symbols);
+                }
+
+                symbols.PutBack(next);
+            }
+            if (current == Symbol.Sequence)
+            {
+                Symbol next = symbols.NextNonEOLSymbol();
+
+                if (next == Symbol.Of)
+                {
+                    return new SequenceOf(module, name, symbols);
+                }
+                else
+                {
+                    symbols.PutBack(next);
+                    return new Sequence(module, name, symbols);
+                }
+            }
+            if (current == Symbol.Choice)
+            {
+                return new Choice(module, name, symbols);
+            }
+
+
+            return new TypeAssignment(module, name, current, symbols, isMacroSyntax);
+        }
+
+        public static void ParseOidValue(ISymbolEnumerator symbols, out string parent, out uint value)
+        {
+            parent = null;
+            value = 0;
+            
+            Symbol current  = symbols.NextNonEOLSymbol();
+            current.Expect(Symbol.OpenBracket);
+
+            Symbol previous = null;
+            StringBuilder longParent = new StringBuilder();
+
+            current = symbols.NextNonEOLSymbol();
+            longParent.Append(current);
+
+            while ((current = symbols.NextNonEOLSymbol()) != null)
+            {
+                bool succeeded;
+
+                if (current == Symbol.OpenParentheses)
+                {
+                    longParent.Append(current);
+                    
+                    current = symbols.NextNonEOLSymbol();
+                    succeeded = UInt32.TryParse(current.ToString(), out value);
+                    current.Assert(succeeded, "not a decimal");
+                    longParent.Append(current);
+                    current = symbols.NextNonEOLSymbol();
+                    current.Expect(Symbol.CloseParentheses);
+                    longParent.Append(current);
+                    continue;
+                }
+
+                if (current == Symbol.CloseBracket)
+                {
+                    parent = longParent.ToString();
+                    return;
+                }
+
+                succeeded = UInt32.TryParse(current.ToString(), out value);
+                if (succeeded)
+                {
+                    // numerical way
+                    while ((current = symbols.NextNonEOLSymbol()) != Symbol.CloseBracket)
+                    {
+                        longParent.Append(".").Append(value);
+                        succeeded = UInt32.TryParse(current.ToString(), out value);
+                        current.Assert(succeeded, "not a decimal");
+                    }
+
+                    current.Expect(Symbol.CloseBracket);
+                    parent = longParent.ToString();
+                    return;
+                }
+
+                longParent.Append(".");
+                longParent.Append(current);
+                current = symbols.NextNonEOLSymbol();
+                current.Expect(Symbol.OpenParentheses);
+                longParent.Append(current);
+                current = symbols.NextNonEOLSymbol();
+                succeeded = UInt32.TryParse(current.ToString(), out value);
+                current.Assert(succeeded, "not a decimal");
+                longParent.Append(current);
+                current = symbols.NextNonEOLSymbol();
+                current.Expect(Symbol.CloseParentheses);
+                longParent.Append(current);
+                previous = current;
+            }
+
+            throw MibException.Create("end of file reached", previous);
+        }
+
+
+        public static ValueRanges DecodeRanges(ISymbolEnumerator symbols)
+        {
+            ValueRanges result = new ValueRanges();
+
+            Symbol startSymbol = symbols.NextNonEOLSymbol();
+            Symbol current = startSymbol;
+            current.Expect(Symbol.OpenParentheses);
+
+            while (current != Symbol.CloseParentheses)
+            {
+                Symbol value1Symbol = symbols.NextNonEOLSymbol();
+
+                if ((value1Symbol == Symbol.Size) && !result.IsSizeDeclaration)
+                {
+                    result.IsSizeDeclaration = true;
+                    symbols.NextNonEOLSymbol().Expect(Symbol.OpenParentheses);
+                    continue;
+                }
+
+                // check for valid number
+                Int64? value1 = DecodeNumber(value1Symbol);
+                if (!value1.HasValue)
+                {
+                    value1Symbol.Assert(false, "Invalid range declaration!");                    
+                }
+
+                // process next symbol
+                ValueRange range;
+                current = symbols.NextNonEOLSymbol();
+
+                if (current == Symbol.DoubleDot)
+                {
+                    // its a continous range
+                    Symbol value2Symbol = symbols.NextNonEOLSymbol();
+                    Int64? value2 = DecodeNumber(value2Symbol);
+                    value2Symbol.Assert(value2.HasValue && (value2.Value >= value1.Value), "Invalid range declaration!");
+
+                    if (value2.Value == value1.Value)
+                    {
+                        range = new ValueRange(value1.Value, null);
+                    }
+                    else
+                    {
+                        range = new ValueRange(value1.Value, value2.Value);
+                    }
+
+                    current = symbols.NextNonEOLSymbol();
+                }
+                else
+                {
+                    // its a single number
+                    range = new ValueRange(value1.Value, null);
+                }
+
+                // validate range
+                if (result.IsSizeDeclaration)
+                {
+                    value1Symbol.Assert(range.Start >= 0, "Invalid range declaration! Size must be greater than 0");
+                }
+
+                result.Add(range);
+                
+                // check next symbol
+                current.Expect(Symbol.Pipe, Symbol.CloseParentheses);
+            }
+
+            if (result.IsSizeDeclaration)
+            {
+                current = symbols.NextNonEOLSymbol();
+                current.Expect(Symbol.CloseParentheses);
+            }
+
+            // validate ranges in between
+            for (int i=0; i<result.Count; i++)
+            {
+                for (int k=i+1; k<result.Count; k++)
+                {
+                    startSymbol.Assert(!result[i].IntersectsWith(result[k]), "Invalid range declaration! Overlapping of ranges!");
+                }
+            }
+
+            return result;
+        }
+
+        public static Int64? DecodeNumber(Symbol number)
+        {
+            Int64  result;
+            string numString = (number != null) ? number.ToString() : null;
+
+            if (!String.IsNullOrEmpty(numString))
+            {
+                if (numString.StartsWith("'") && (numString.Length > 3))
+                {
+                    // search second apostrophe
+                    int end = numString.IndexOf('\'', 1);
+                    if (end == (numString.Length - 2))
+                    {
+                        try
+                        {
+                            switch (numString[numString.Length - 1])
+                            {
+                                case 'b':
+                                case 'B':
+                                    result = Convert.ToInt64(numString.Substring(1, numString.Length - 3), 2);
+                                    return result;
+                                case 'h':
+                                case 'H':
+                                    result = Convert.ToInt64(numString.Substring(1, numString.Length - 3), 16);
+                                    return result;
+                            }
+                        }
+                        catch
+                        {
+                        }
+                    }
+                }
+                else if (Int64.TryParse(numString, out result))
+                {
+                    return result;
+                }
+            }
+
+            return null;
+        }
+
+        public static ValueMap DecodeEnumerations(ISymbolEnumerator symbols)
+        {
+            Symbol current = symbols.NextNonEOLSymbol();
+            current.Expect(Symbol.OpenBracket);
+
+            ValueMap map = new ValueMap();
+            do
+            {
+                current = symbols.NextNonEOLSymbol();
+                string identifier = current.ToString();
+
+                current = symbols.NextNonEOLSymbol();
+                current.Expect(Symbol.OpenParentheses);
+
+                current = symbols.NextNonEOLSymbol();
+                Int64 enumValue;
+                if (Int64.TryParse(current.ToString(), out enumValue))
+                {
+                    try
+                    {
+                        // Have to include the number as it seems repeated identifiers are allowed ??
+                        map.Add(enumValue, String.Format("{0}({1})", identifier, enumValue));
+                    }
+                    catch (ArgumentException ex)
+                    {
+                        current.Assert(false, ex.Message);
+                    }
+                }
+                else
+                {
+                    // Need to get "DefinedValue".
+                }
+
+                current = symbols.NextNonEOLSymbol();
+                current.Expect(Symbol.CloseParentheses);
+
+                current = symbols.NextNonEOLSymbol();
+            } while (current == Symbol.Comma);
+
+            current.Expect(Symbol.CloseBracket);
+
+            return map;
+        }
+
+        #endregion
+
+    }
+}
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/SharpSnmpLib/Mib/MaxAccess.cs
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/SharpSnmpLib/Mib/MaxAccess.cs	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/SharpSnmpLib/Mib/MaxAccess.cs	(revision 457)
@@ -0,0 +1,17 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace Lextm.SharpSnmpLib.Mib
+{
+    public enum MaxAccess
+    {
+        notAccessible,
+        accessibleForNotify,
+        readOnly,
+        readWrite,
+        readCreate
+    }
+
+}
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/SharpSnmpLib/Mib/MibDocument.cs
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/SharpSnmpLib/Mib/MibDocument.cs	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/SharpSnmpLib/Mib/MibDocument.cs	(revision 457)
@@ -0,0 +1,57 @@
+/*
+ * Created by SharpDevelop.
+ * User: lextm
+ * Date: 2008/5/17
+ * Time: 17:38
+ * 
+ * To change this template use Tools | Options | Coding | Edit Standard Headers.
+ */
+
+using System.Collections.Generic;
+
+namespace Lextm.SharpSnmpLib.Mib
+{
+    /// <summary>
+    /// MIB document.
+    /// </summary>
+    public sealed class MibDocument
+    {
+        private readonly List<IModule> _modules = new List<IModule>();
+
+        /// <summary>
+        /// Initializes a new instance of the <see cref="MibDocument" /> class.
+        /// </summary>
+        /// <param name="file">The file.</param>
+        public MibDocument(string file)
+            : this(new Lexer(file))
+        {
+        }
+
+        /// <summary>
+        /// Initializes a new instance of the <see cref="MibDocument"/> class.
+        /// </summary>
+        /// <param name="lexer">The lexer.</param>
+        public MibDocument(Lexer lexer)
+        {
+            ISymbolEnumerator symbols = lexer.GetEnumerator();
+
+            Symbol current;
+            while ((current = symbols.NextNonEOLSymbol()) != null)
+            {
+                symbols.PutBack(current);
+                _modules.Add(new MibModule(symbols));                
+            }
+        }
+        
+        /// <summary>
+        /// <see cref="MibModule"/> containing in this document.
+        /// </summary>
+        public IList<IModule> Modules
+        {
+            get
+            {
+                return _modules;
+            }
+        }
+    }
+}
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/SharpSnmpLib/Mib/MibException.cs
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/SharpSnmpLib/Mib/MibException.cs	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/SharpSnmpLib/Mib/MibException.cs	(revision 457)
@@ -0,0 +1,113 @@
+/*
+ * Created by SharpDevelop.
+ * User: lextm
+ * Date: 2008/5/17
+ * Time: 16:33
+ * 
+ * To change this template use Tools | Options | Coding | Edit Standard Headers.
+ */
+
+using System;
+using System.Globalization;
+#if (!SILVERLIGHT)
+using System.Runtime.Serialization;
+using System.Security.Permissions; 
+#endif
+
+namespace Lextm.SharpSnmpLib.Mib
+{
+    /// <summary>
+    /// Description of MibException.
+    /// </summary>
+    [Serializable]
+    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Mib")]
+    public sealed class MibException : Exception
+    {
+        /// <summary>
+        /// Symbol.
+        /// </summary>
+        public Symbol Symbol { get; private set; }
+
+        /// <summary>
+        /// Creates a <see cref="MibException"/>.
+        /// </summary>
+        public MibException()
+        {
+        }
+        
+        /// <summary>
+        /// Creates a <see cref="SnmpException"/> instance with a specific <see cref="string"/>.
+        /// </summary>
+        /// <param name="message">Message</param>
+        public MibException(string message) : base(message)
+        {
+        }
+
+        /// <summary>
+        /// Creates a <see cref="MibException"/> instance with a specific <see cref="string"/> and an <see cref="Exception"/>.
+        /// </summary>
+        /// <param name="message">Message</param>
+        /// <param name="inner">Inner exception</param>
+        public MibException(string message, Exception inner)
+            : base(message, inner)
+        {
+        }
+#if (!SILVERLIGHT)        
+        /// <summary>
+        /// Creates a <see cref="MibException"/> instance.
+        /// </summary>
+        /// <param name="info">Info</param>
+        /// <param name="context">Context</param>
+        private MibException(SerializationInfo info, StreamingContext context) : base(info, context)
+        {
+            if (info == null)
+            {
+                throw new ArgumentNullException("info");
+            }
+            
+            Symbol = (Symbol)info.GetValue("Symbol", typeof(Symbol));
+        }
+        
+        /// <summary>
+        /// Gets object data.
+        /// </summary>
+        /// <param name="info">Info</param>
+        /// <param name="context">Context</param>
+        [SecurityPermission(SecurityAction.Demand, SerializationFormatter = true)]
+        public override void GetObjectData(SerializationInfo info, StreamingContext context)
+        {
+            base.GetObjectData(info, context);
+            info.AddValue("Symbol", Symbol);
+        }
+#endif
+
+        /// <summary>
+        /// Creates a <see cref="MibException"/> with a specific <see cref="Symbol"/>.
+        /// </summary>
+        /// <param name="message">Message</param>
+        /// <param name="symbol">Symbol</param>
+        /// <returns></returns>
+        public static MibException Create(string message, Symbol symbol)
+        {
+            if (symbol == null)
+            {
+                throw new ArgumentNullException("symbol");
+            }
+
+            if (String.IsNullOrEmpty(message))
+            {
+                message = "Unknown MIB Exception";
+            }
+
+            message = String.Format(
+                "{0} (file: \"{1}\"; row: {2}; column: {3})",
+                message,
+                symbol.File,
+                symbol.Row + 1,
+                symbol.Column + 1);
+
+            MibException ex = new MibException(message) { Symbol = symbol };
+            return ex;
+        }
+    }
+}
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/SharpSnmpLib/Mib/MibModule.cs
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/SharpSnmpLib/Mib/MibModule.cs	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/SharpSnmpLib/Mib/MibModule.cs	(revision 457)
@@ -0,0 +1,294 @@
+/*
+ * Created by SharpDevelop.
+ * User: lextm
+ * Date: 2008/5/17
+ * Time: 17:38
+ * 
+ * To change this template use Tools | Options | Coding | Edit Standard Headers.
+ */
+
+using System;
+using System.Collections.Generic;
+using Lextm.SharpSnmpLib.Mib.Elements;
+using Lextm.SharpSnmpLib.Mib.Elements.Entities;
+using Lextm.SharpSnmpLib.Mib.Elements.Types;
+
+namespace Lextm.SharpSnmpLib.Mib
+{
+    /// <summary>
+    /// MIB module class.
+    /// </summary>
+    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Mib")]
+    public sealed class MibModule : IModule
+    {
+        private readonly string _name;
+        private readonly Imports _imports;
+        private readonly Exports _exports;
+        private readonly List<IElement> _tokens = new List<IElement>();
+    
+        /// <summary>
+        /// Creates a <see cref="MibModule"/> with a specific <see cref="Lexer"/>.
+        /// </summary>
+        /// <param name="name">Module name</param>
+        /// <param name="symbols">Lexer</param>
+        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "lexer")]
+        public MibModule(ISymbolEnumerator symbols)
+        {
+            if (symbols == null)
+            {
+                throw new ArgumentNullException("lexer");
+            }
+
+            Symbol temp = symbols.NextNonEOLSymbol();
+            temp.AssertIsValidIdentifier();
+            _name = temp.ToString().ToUpperInvariant(); // all module names are uppercase
+            
+            temp = symbols.NextNonEOLSymbol();
+            temp.Expect(Symbol.Definitions);
+            
+            temp = symbols.NextNonEOLSymbol();
+            temp.Expect(Symbol.Assign);
+            
+            temp = symbols.NextSymbol();
+            temp.Expect(Symbol.Begin);
+            
+            temp = symbols.NextNonEOLSymbol();
+            if (temp == Symbol.Imports)
+            {
+                _imports = ParseDependents(symbols);
+            }
+            else if (temp == Symbol.Exports)
+            {
+                _exports = ParseExports(symbols);
+            }
+            else
+            {
+                symbols.PutBack(temp);
+            }
+
+            ParseEntities(symbols);
+        }
+
+        #region Accessors
+
+        /// <summary>
+        /// Module name.
+        /// </summary>
+        public string Name
+        {
+            get { return _name; }
+        }
+        
+        public Exports Exports
+        {
+            get { return _exports; }
+        }
+
+        public Imports Imports
+        {
+            get { return _imports; }
+        }
+
+        public List<IElement> Tokens
+        {
+            get { return this._tokens; }
+        }
+
+        /// <summary>
+        /// Entities + Types + all other elements implementing IDeclaration
+        /// </summary>
+        public IList<IDeclaration> Declarations
+        {
+            get
+            {
+                IList<IDeclaration> result = new List<IDeclaration>();
+                foreach (IElement e in _tokens)
+                {
+                    IDeclaration decl = e as IDeclaration;
+                    if (decl != null)
+                    {
+                        result.Add(decl);
+                    }
+                }
+
+                return result;
+            }
+        }
+
+        /// <summary>
+        /// OID nodes.
+        /// </summary>
+        public IList<IEntity> Entities
+        {
+            get
+            {
+                IList<IEntity> result = new List<IEntity>();
+                foreach (IElement e in _tokens)
+                {
+                    IEntity entity = e as IEntity;
+                    if (entity != null)
+                    {
+                        result.Add(entity);
+                    }
+                }
+
+                return result;
+            }
+        }
+
+        public IList<ITypeAssignment> Types
+        {
+            get
+            {
+                IList<ITypeAssignment> result = new List<ITypeAssignment>();
+                foreach (IElement e in _tokens)
+                {
+                    ITypeAssignment type = e as ITypeAssignment;
+                    if (type != null)
+                    {
+                        result.Add(type);
+                    }
+                }
+
+                return result;
+            }
+        }
+
+        #endregion
+
+        #region Parsing of Symbols
+
+        private Exports ParseExports(ISymbolEnumerator symbols)
+        {
+            return new Exports(this, symbols);
+        }
+
+        private Imports ParseDependents(ISymbolEnumerator symbols)
+        {
+            return new Imports(this, symbols);
+        }
+        
+        private void ParseEntities(ISymbolEnumerator symbols)
+        {
+            Symbol     temp   = symbols.NextNonEOLSymbol();
+            SymbolList buffer = new SymbolList();
+
+            while (temp != Symbol.End)
+            {
+                if (temp == Symbol.Assign)
+                {
+                    ParseEntity(buffer, symbols);
+                    buffer.Clear();
+                    // skip linebreaks behind an entity
+                    temp = symbols.NextNonEOLSymbol();
+                }
+                else
+                {
+                    buffer.Add(temp);
+                    temp = symbols.NextSymbol();
+                }
+            }
+        }
+
+        private void ParseEntity(SymbolList preAssignSymbols, ISymbolEnumerator symbols)
+        {
+            if ((preAssignSymbols == null) || (preAssignSymbols.Count == 0))
+            {
+                Symbol s = symbols.NextSymbol();
+                if (s != null)
+                {
+                    s.Assert(false, "Invalid Entitiy declaration");
+                }
+                else
+                {
+                    throw new MibException("Invalid Entitiy declaration");
+                }
+            }
+
+            // check for a valid identifier
+            preAssignSymbols[0].AssertIsValidIdentifier();
+            
+            if (preAssignSymbols.Count == 1)
+            {
+                // its a typedef
+                _tokens.Add(Lexer.ParseBasicTypeDef(this, preAssignSymbols[0].ToString(), symbols, isMacroSyntax: false));
+                return;
+            }
+
+            ISymbolEnumerator preAssignSymbolsEnumerator = preAssignSymbols.GetSymbolEnumerator();
+            preAssignSymbolsEnumerator.NextNonEOLSymbol(); // returns identifier
+            Symbol type = preAssignSymbolsEnumerator.NextNonEOLSymbol();
+
+            // parse declarations
+            if (type == Symbol.Object)
+            {
+                Symbol next = preAssignSymbolsEnumerator.NextNonEOLSymbol();
+
+                if (next == Symbol.Identifier)
+                {
+                    _tokens.Add(new OidValueAssignment(this, preAssignSymbols, symbols));
+                    return;
+                }
+                else if (next != null)
+                {
+                    preAssignSymbolsEnumerator.PutBack(next);
+                }
+            }
+            if (type == Symbol.ModuleIdentity)
+            {
+                _tokens.Add(new ModuleIdentity(this, preAssignSymbols, symbols));
+                return;
+            }
+            if (type == Symbol.ObjectType)
+            {
+                _tokens.Add(new ObjectType(this, preAssignSymbols, symbols));
+                return;
+            }
+            if (type == Symbol.ObjectGroup)
+            {
+                _tokens.Add(new ObjectGroup(this, preAssignSymbols, symbols));
+                return;
+            }
+            if (type == Symbol.NotificationGroup)
+            {
+                _tokens.Add(new NotificationGroup(this, preAssignSymbols, symbols));
+                return;
+            }
+            if (type == Symbol.ModuleCompliance)
+            {
+                _tokens.Add(new ModuleCompliance(this, preAssignSymbols, symbols));
+                return;
+            }
+            if (type == Symbol.NotificationType)
+            {
+                _tokens.Add(new NotificationType(this, preAssignSymbols, symbols));
+                return;
+            }
+            if (type == Symbol.ObjectIdentity)
+            {
+                _tokens.Add(new ObjectIdentity(this, preAssignSymbols, symbols));
+                return;
+            }
+            if (type == Symbol.Macro)
+            {
+                _tokens.Add(new Macro(this, preAssignSymbols, symbols));
+                return;
+            }
+            if (type == Symbol.TrapType)
+            {
+                _tokens.Add(new TrapType(this, preAssignSymbols, symbols));
+                return;
+            }
+            if (type == Symbol.AgentCapabilities)
+            {
+                _tokens.Add(new AgentCapabilities(this, preAssignSymbols, symbols));
+                return;
+            }
+
+            preAssignSymbols[1].Assert(false, "Unknown/Invalid declaration");
+        }
+
+        #endregion
+
+    }
+}
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/SharpSnmpLib/Mib/MibResolver.cs
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/SharpSnmpLib/Mib/MibResolver.cs	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/SharpSnmpLib/Mib/MibResolver.cs	(revision 457)
@@ -0,0 +1,97 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.IO;
+using System.Reflection;
+
+namespace Lextm.SharpSnmpLib.Mib
+{
+    public interface IMibResolver
+    {
+        IModule Resolve(string moduleName);
+    }
+
+    public class FileSystemMibResolver : IMibResolver
+    {
+        private string _path;
+        private bool _recursive;
+
+        public FileSystemMibResolver(string path, bool recursive)
+        {
+            _path = path;
+            _recursive = recursive;
+        }
+
+        #region IMibResolver Member
+
+        public IModule Resolve(string moduleName)
+        {
+            if (Directory.Exists(_path))
+            {
+                string[] matchedFiles = Directory.GetFiles(
+                    _path,
+                    "*",
+                    (_recursive) ? SearchOption.AllDirectories : SearchOption.TopDirectoryOnly);
+
+                if ((matchedFiles != null) && (matchedFiles.Length >= 1))
+                {
+                    foreach (string matchedFile in matchedFiles)
+                    {
+						if (Path.GetFileNameWithoutExtension(matchedFile.ToLowerInvariant()) == moduleName.ToLowerInvariant())
+						{
+							try
+							{
+								MibDocument md = new MibDocument (matchedFile);
+								if (md.Modules.Count > 0)
+								{
+									return md.Modules [0];
+								}
+							} catch
+							{
+							}
+						}
+                    }                  
+                }
+            }
+
+            return null;
+        }
+
+        #endregion
+
+    }
+
+    // earlier code for search of versioned MIBs:
+    //
+    //private const string Pattern = "-V[0-9]+$";
+    //public static bool AllDependentsAvailable(MibModule module, IDictionary<string, MibModule> modules)
+    //{
+    //    foreach (string dependent in module.Dependents)
+    //    {
+    //        if (!DependentFound(dependent, modules))
+    //        {
+    //            return false;
+    //        }
+    //    }
+
+    //    return true;
+    //}
+
+    //private static bool DependentFound(string dependent, IDictionary<string, MibModule> modules)
+    //{
+    //    if (!Regex.IsMatch(dependent, Pattern))
+    //    {
+    //        return modules.ContainsKey(dependent);
+    //    }
+
+    //    if (modules.ContainsKey(dependent))
+    //    {
+    //        return true;
+    //    }
+
+    //    string dependentNonVersion = Regex.Replace(dependent, Pattern, string.Empty);
+    //    return modules.ContainsKey(dependentNonVersion);
+    //}
+
+}
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/SharpSnmpLib/Mib/MibTree.cs
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/SharpSnmpLib/Mib/MibTree.cs	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/SharpSnmpLib/Mib/MibTree.cs	(revision 457)
@@ -0,0 +1,130 @@
+using System.Collections.Generic;
+using Lextm.SharpSnmpLib.Mib.Elements.Entities;
+
+namespace Lextm.SharpSnmpLib.Mib
+{
+    /// <summary>
+    /// Builds up a tree from a single MIB
+    /// </summary>
+    public class MibTree
+    {
+        private readonly List<MibTreeNode> _root = new List<MibTreeNode>();
+
+        public MibTree(MibModule module)
+        {
+            IList<IEntity> entities = module.Entities;
+
+            if (entities.Count > 0)
+            {
+                // try to find module identity as root
+                foreach (IEntity element in entities)
+                {
+                    ModuleIdentity mi = element as ModuleIdentity;
+
+                    if (mi != null)
+                    {
+                        _root.Add(new MibTreeNode(null, mi));
+                    }
+                }
+
+                // find OID assignments as root, if there are any that are not below ModuleIdentity
+                foreach (IEntity element in entities)
+                {
+                    OidValueAssignment oa = element as OidValueAssignment;
+
+                    if (oa != null)
+                    {
+                        _root.Add(new MibTreeNode(null, oa));
+                    }
+                }
+
+                FilterRealRoots (entities);
+
+                foreach (MibTreeNode mibTreeNode in _root)
+                {
+                    entities.Remove (mibTreeNode.Entity);
+                }
+
+                if (_root.Count == 0)
+                {
+                    //no module identity, assume first entity is root
+                    _root.Add(new MibTreeNode(null, entities[0]));
+                }
+
+                foreach (MibTreeNode mibTreeNode in _root)
+                {
+					if (entities.Contains (mibTreeNode.Entity))
+					{
+						entities.Remove (mibTreeNode.Entity);
+					}
+                    BuildTree(mibTreeNode, entities);
+                    UpdateTreeNodeTypes(mibTreeNode);
+                }
+            }
+        }
+
+        public IList<MibTreeNode> Root
+        {
+            get { return _root; }
+        }
+
+        private bool EntityExists(IList<IEntity> entities, string name)
+		{
+            foreach(IEntity entity in entities)
+			{
+                if (entity.Name == name)
+				{
+                    return true;
+                }
+            }
+            return false;
+        }
+
+        private void FilterRealRoots(IList<IEntity> entities)
+        {
+            int i = 0;
+            while (i < _root.Count)
+			{
+                if (EntityExists(entities, _root[i].Entity.Parent))
+                {
+                    _root.RemoveAt(i);
+                }
+                else
+                {
+                    i++;
+                }
+            }
+		}
+		
+		private void BuildTree(MibTreeNode node, IList<IEntity> entities)
+        {
+            int i = 0;
+            while (i < entities.Count)
+            {
+                if (entities[i].Parent == node.Entity.Name)
+                {
+                    node.AddChild(entities[i]);
+                    entities.RemoveAt(i);
+                }
+                else
+                {
+                    i++;
+                }
+            }
+
+            foreach (MibTreeNode childNode in node.ChildNodes)
+            {
+                BuildTree(childNode, entities);
+            }
+        }
+        
+        private void UpdateTreeNodeTypes(MibTreeNode node)
+        {
+            node.UpdateNodeType();
+            foreach (MibTreeNode childNode in node.ChildNodes)
+            {
+                UpdateTreeNodeTypes(childNode);
+            }
+        }
+    }
+}
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/SharpSnmpLib/Mib/MibTreeNode.cs
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/SharpSnmpLib/Mib/MibTreeNode.cs	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/SharpSnmpLib/Mib/MibTreeNode.cs	(revision 457)
@@ -0,0 +1,112 @@
+using System;
+using System.Collections.Generic;
+using Lextm.SharpSnmpLib.Mib.Elements.Entities;
+using Lextm.SharpSnmpLib.Mib.Elements.Types;
+
+namespace Lextm.SharpSnmpLib.Mib
+{
+    [Flags]
+    public enum MibTreeNodeType
+    {
+        Unknown             = 0,
+        Container           = (1 << 0),
+        Scalar              = (1 << 1),
+        Table               = (1 << 2),
+        TableRow            = (1 << 3),
+        TableCell           = (1 << 4),
+        NotificationRelated = (1 << 5),
+        ConformanceRelated  = (1 << 6)
+    }
+
+
+    public class MibTreeNode
+    {
+        private MibTreeNode       _parent     = null;
+        private List<MibTreeNode> _childNodes = new List<MibTreeNode>();
+        private IEntity           _entity     = null;
+        private MibTreeNodeType   _nodeType   = MibTreeNodeType.Unknown;
+
+        public MibTreeNode(MibTreeNode parent, IEntity entity)
+        {
+            _parent = parent;
+            _entity = entity;
+        }
+
+        public MibTreeNode Parent
+        {
+            get { return _parent; }
+        }
+
+        public IEntity Entity
+        {
+            get { return _entity; }
+        }
+
+        public MibTreeNodeType NodeType
+        {
+            get { return _nodeType; }
+        }
+
+        public List<MibTreeNode> ChildNodes
+        {
+            get { return _childNodes; }
+        }
+
+        public MibTreeNode AddChild(IEntity element)
+        {
+            MibTreeNode result = new MibTreeNode(this, element);
+            this.ChildNodes.Add(result);
+
+            return result;
+        }
+
+        public void UpdateNodeType()
+        {
+            _nodeType = MibTreeNodeType.Unknown;
+
+            if (_entity != null)
+            {
+                if ((_entity is OidValueAssignment) || (_entity is ObjectIdentity))
+                {
+                    _nodeType |= MibTreeNodeType.Container;
+                    return;
+                }
+                else if (_childNodes.Count > 0)
+                {
+                    _nodeType |= MibTreeNodeType.Container;
+                }
+
+                if (_entity is ObjectType)
+                {
+                    ObjectType ot = _entity as ObjectType;
+
+                    if (ot.Syntax is SequenceOf)
+                    {
+                        _nodeType |= MibTreeNodeType.Table;
+                    }
+                    else if (ot.Syntax is Sequence)
+                    {
+                        _nodeType |= MibTreeNodeType.TableRow;
+                    }
+                    else if ((_parent != null) && ((_parent.NodeType & MibTreeNodeType.TableRow) != 0))
+                    {
+                        _nodeType |= MibTreeNodeType.TableCell;
+                        _nodeType |= MibTreeNodeType.Scalar;
+                    }
+                    else
+                    {
+                        _nodeType |= MibTreeNodeType.Scalar;
+                    }
+                }
+                else if ((_entity is ModuleCompliance) || (_entity is ObjectGroup) || (_entity is NotificationGroup))
+                {
+                    _nodeType |= MibTreeNodeType.ConformanceRelated;
+                }
+                else if ((_entity is NotificationGroup) || (_entity is NotificationType))
+                {
+                    _nodeType |= MibTreeNodeType.NotificationRelated;
+                }
+            }
+        }
+    }
+}
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/SharpSnmpLib/Mib/MibTypesResolver.cs
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/SharpSnmpLib/Mib/MibTypesResolver.cs	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/SharpSnmpLib/Mib/MibTypesResolver.cs	(revision 457)
@@ -0,0 +1,216 @@
+using System;
+using System.Collections.Generic;
+using System.Text.RegularExpressions;
+using Lextm.SharpSnmpLib.Mib.Elements;
+using Lextm.SharpSnmpLib.Mib.Elements.Entities;
+using Lextm.SharpSnmpLib.Mib.Elements.Types;
+
+namespace Lextm.SharpSnmpLib.Mib
+{
+	 public static class MibTypesResolver
+	 {
+		  private static readonly Regex              _namedOidPathRegex = new Regex(@"^(?<Name>[^\(]+)\((?<Value>\d+)\)$");
+		  private static readonly List<IMibResolver> _resolver      = new List<IMibResolver>();
+		  private static readonly List<IModule>      _cachedModules = new List<IModule>();
+
+		  public static void RegisterResolver(IMibResolver resolver)
+		  {
+				if (resolver != null)
+				{
+					 _resolver.Add(resolver);
+				}
+		  }
+
+		  public static IModule ResolveModule(string moduleName)
+		  {
+				// check if module is already cached
+				foreach (MibModule cachedModule in _cachedModules)
+				{
+					 if (cachedModule.Name == moduleName)
+					 {
+						  return cachedModule;
+					 }
+				}
+
+				foreach (IMibResolver resolver in _resolver)
+				{
+					 IModule resolvedModule = resolver.Resolve(moduleName);
+					 if (resolvedModule != null)
+					 {
+						  ResolveTypes(resolvedModule);
+						  _cachedModules.Add(resolvedModule);
+						  return resolvedModule;
+					 }
+				}
+
+				return null;
+		  }
+
+		  public static void ResolveTypes(IModule module)
+		  {
+				foreach (IEntity entity in module.Entities)
+				{
+					 ITypeReferrer typeReferringEntity = entity as ITypeReferrer;
+
+					 if (typeReferringEntity != null)
+					 {
+						  CheckTypeReferrer(module, typeReferringEntity);
+					 }
+				}
+
+				if (!_cachedModules.Contains(module))
+				{
+					 _cachedModules.Add(module);
+				}
+		  }
+
+		  private static void CheckTypeReferrer(IModule module, ITypeReferrer typeReferringEntity)
+		  {
+				TypeAssignment unknownType = typeReferringEntity.ReferredType as TypeAssignment;
+				if (unknownType != null)
+				{
+					 typeReferringEntity.ReferredType = ResolveType(module, unknownType);
+
+					 if (typeReferringEntity.ReferredType is TypeAssignment)
+					 {
+						  Console.WriteLine(String.Format("Could not resolve type '{0}' declared in module '{1}'", (typeReferringEntity.ReferredType as TypeAssignment).Type, typeReferringEntity.ReferredType.Module.Name));
+					 }
+				}
+
+				ITypeReferrer nextTypeReferringEntity = typeReferringEntity.ReferredType as ITypeReferrer;
+				if (nextTypeReferringEntity != null)
+				{
+					 CheckTypeReferrer(module, nextTypeReferringEntity);
+				}
+		  }
+
+		  public static ITypeAssignment ResolveType(IModule module, TypeAssignment type)
+		  {
+				ITypeAssignment result = ResolveDeclaration(module, type.Type) as ITypeAssignment;
+
+				return (result != null) ? result : type;
+		  }
+
+		  public static IDeclaration ResolveDeclaration(IModule module, string name)
+		  {
+				if ((module == null) || String.IsNullOrEmpty(name))
+				{
+					 return null;
+				}
+
+				// check module internal types
+				foreach (IDeclaration decl in module.Declarations)
+				{
+				if (decl.Name == name)
+					 {
+					return decl;
+					 }
+				}
+
+				// check if type is imported
+				if (module.Imports != null)
+				{
+					 ImportsFrom imports = module.Imports.GetImportFromType(name);
+					 if (imports != null)
+					 {
+						  IModule importedModule = ResolveModule(imports.Module);
+						  if (importedModule != null)
+						  {
+								return ResolveDeclaration(importedModule, name);
+						  }
+					 }
+				}
+
+				return null;
+		  }
+
+		  public static ObjectIdentifier ResolveOid(IEntity entity)
+		  {
+				ObjectIdentifier result = new ObjectIdentifier();
+
+				if (entity != null)
+				{
+					 ResolveOid(entity, result);
+				}
+
+				return result;
+		  }
+
+		  private static void ResolveOid(IEntity entity, ObjectIdentifier result)
+		  {
+				result.Prepend(entity.Name, entity.Value);
+				
+				// check parent
+				if (!String.IsNullOrEmpty(entity.Parent))
+				{
+					 string[] pathParts = entity.Parent.Split('.');
+					 uint value;
+
+					 // all parts except the first should have their value directly or indirectly with them
+					 if (pathParts.Length > 1)
+					 {
+						  for (int i=pathParts.Length-1; i>=1; i--)
+						  {
+								if (uint.TryParse(pathParts[i], out value))
+								{
+									 result.Prepend("", value);
+								}
+								else
+								{
+									 Match m = _namedOidPathRegex.Match(pathParts[i]);
+									 if (m.Success)
+									 {
+										  result.Prepend(m.Groups["Name"].Value, uint.Parse(m.Groups["Value"].Value));
+									 }
+									 else
+									 {
+										  throw new MibException("Invalid OID path detected for entity '" + entity.Name + "' in module '" + entity.Module + "'!");
+									 }
+								}
+						  }
+					 }
+
+					 // parse root part: either another entity or a standard root object
+					 if (IsOidRoot(pathParts[0], out value))
+					 {
+						  result.Prepend(pathParts[0], value);
+					 }
+					 else
+					 {
+						  // try to find entity inside this module
+						  if (entity.Module != null)
+						  {
+								entity = ResolveDeclaration(entity.Module, pathParts[0]) as IEntity;
+
+								if (entity != null)
+								{
+									 ResolveOid(entity, result);
+								}
+								else
+								{
+									 result.Prepend("", uint.MaxValue);
+								}
+						  }
+						  else
+						  {
+								result.Prepend("", uint.MaxValue);
+						  }
+					 }
+				}
+		  }
+
+		  public static bool IsOidRoot(string name, out uint value)
+		  {
+				value = uint.MaxValue;
+
+				switch (name)
+				{
+					 case "ccitt": value = 0; return true;
+					 case "iso": value = 1; return true;
+					 case "joint-iso-ccitt": value = 2; return true;
+				}
+
+				return false;
+		  }
+	 }
+}
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/SharpSnmpLib/Mib/ObjectIdentifier.cs
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/SharpSnmpLib/Mib/ObjectIdentifier.cs	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/SharpSnmpLib/Mib/ObjectIdentifier.cs	(revision 457)
@@ -0,0 +1,54 @@
+using System.Collections.Generic;
+using System.Text;
+
+namespace Lextm.SharpSnmpLib.Mib
+{
+    public class ObjectIdentifier: List<KeyValuePair<string, uint>>
+    {
+        public void Add(string name, uint oid)
+        {
+            this.Add(new KeyValuePair<string, uint>(name, oid));
+        }
+
+        public void Prepend(string name, uint oid)
+        {
+            this.Insert(0, new KeyValuePair<string, uint>(name, oid));
+        }
+
+        public void Insert(int index, string name, uint oid)
+        {
+            this.Insert(index, new KeyValuePair<string, uint>(name, oid));
+        }
+
+        public string GetOidString()
+        {
+            StringBuilder result = new StringBuilder();
+
+            foreach (KeyValuePair<string, uint> level in this)
+            {
+                result.Append(level.Value);
+                result.Append('.');
+            }
+
+            if (result.Length > 0)
+            {
+                result.Length--;
+            }
+
+            return result.ToString();
+        }
+
+        public uint[] GetOidValues()
+        {
+            List<uint> result = new List<uint>();
+            
+            foreach (KeyValuePair<string, uint> level in this)
+            {
+                result.Add(level.Value);
+            }
+
+            return result.ToArray();
+        }
+
+    }
+}
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/SharpSnmpLib/Mib/Status.cs
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/SharpSnmpLib/Mib/Status.cs	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/SharpSnmpLib/Mib/Status.cs	(revision 457)
@@ -0,0 +1,17 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace Lextm.SharpSnmpLib.Mib
+{
+    public enum Status
+    {
+        current,
+        deprecated,
+        obsolete,
+        mandatory,
+        optional
+    }
+
+}
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/SharpSnmpLib/Mib/Symbol.cs
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/SharpSnmpLib/Mib/Symbol.cs	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/SharpSnmpLib/Mib/Symbol.cs	(revision 457)
@@ -0,0 +1,357 @@
+/*
+ * Created by SharpDevelop.
+ * User: lextm
+ * Date: 2008/5/17
+ * Time: 17:14
+ * 
+ * To change this template use Tools | Options | Coding | Edit Standard Headers.
+ */
+
+using System;
+using System.Configuration;
+using System.Globalization;
+using System.Text;
+
+namespace Lextm.SharpSnmpLib.Mib
+{
+    /// <summary>
+    /// Description of Symbol.
+    /// </summary>
+    public sealed class Symbol : IEquatable<Symbol>
+    {
+        private readonly string _text;
+        private readonly int _row;
+        private readonly int _column;
+        private readonly string _file;
+        
+        private Symbol(string text) : this(null, text, -1, -1)
+        {
+        }
+        
+        /// <summary>
+        /// Creates a <see cref="Symbol"/>.
+        /// </summary>
+        /// <param name="file">File</param>
+        /// <param name="text">Text</param>
+        /// <param name="row">Row number</param>
+        /// <param name="column">column number</param>
+        public Symbol(string file, string text, int row, int column)
+        {
+            _file = file;
+            _text = text;
+            _row = row;
+            _column = column;
+        }
+        
+        /// <summary>
+        /// File.
+        /// </summary>
+        public string File
+        {
+            get
+            {
+                return _file;
+            }
+        }
+        
+        /// <summary>
+        /// Row number.
+        /// </summary>
+        public int Row
+        {
+            get
+            {
+                return _row;
+            }
+        }
+        
+        /// <summary>
+        /// Column number.
+        /// </summary>
+        public int Column
+        {
+            get
+            {
+                return _column;
+            }
+        }        
+        
+        /// <summary>
+        /// Returns a <see cref="String"/> that represents this <see cref="Symbol"/>.
+        /// </summary>
+        /// <returns></returns>
+        public override string ToString()
+        {
+            return _text;
+        }
+        
+        /// <summary>
+        /// Determines whether the specified <see cref="Object"/> is equal to the current <see cref="Symbol"/>.
+        /// </summary>
+        /// <param name="obj">The <see cref="Object"/> to compare with the current <see cref="Symbol"/>. </param>
+        /// <returns><value>true</value> if the specified <see cref="Object"/> is equal to the current <see cref="Symbol"/>; otherwise, <value>false</value>.
+        /// </returns>
+        public override bool Equals(object obj)
+        {
+            if (obj == null)
+            {
+                return false;
+            }
+            
+            if (ReferenceEquals(this, obj))
+            {
+                return true;
+            }
+            
+            return GetType() == obj.GetType() && Equals((Symbol)obj);
+        }
+        
+        /// <summary>
+        /// Serves as a hash function for a particular type.
+        /// </summary>
+        /// <returns>A hash code for the current <see cref="Symbol"/>.</returns>
+        public override int GetHashCode()
+        {
+            return _text.GetHashCode();
+        }
+
+        /// <summary>
+        /// The equality operator.
+        /// </summary>
+        /// <param name="left">Left <see cref="Symbol"/> object</param>
+        /// <param name="right">Right <see cref="Symbol"/> object</param>
+        /// <returns>
+        /// Returns <c>true</c> if the values of its operands are equal, <c>false</c> otherwise.</returns>
+        public static bool operator ==(Symbol left, Symbol right)
+        {
+            return Equals(left, right);
+        }
+        
+        /// <summary>
+        /// Determines whether the specified <see cref="Symbol"/> is equal to the current <see cref="Symbol"/>.
+        /// </summary>
+        /// <param name="left">Left <see cref="Symbol"/> object</param>
+        /// <param name="right">Right <see cref="Symbol"/> object</param>
+        /// <returns>
+        /// Returns <c>true</c> if the values of its operands are equal, <c>false</c> otherwise.</returns>
+        public static bool Equals(Symbol left, Symbol right)
+        {
+            object l = left;
+            object r = right;
+            if (l == r)
+            {
+                return true;
+            }
+
+            if (l == null || r == null)
+            {
+                return false;
+            }
+
+            return left._text.Equals(right._text);
+        }
+        
+        /// <summary>
+        /// The inequality operator.
+        /// </summary>
+        /// <param name="left">Left <see cref="Symbol"/> object</param>
+        /// <param name="right">Right <see cref="Symbol"/> object</param>
+        /// <returns>
+        /// Returns <c>true</c> if the values of its operands are not equal, <c>false</c> otherwise.</returns>
+        public static bool operator !=(Symbol left, Symbol right)
+        {
+            return !(left == right);
+        }
+
+        #region IEquatable<Symbol> Members
+        /// <summary>
+        /// Indicates whether the current object is equal to another object of the same type.
+        /// </summary>
+        /// <param name="other">An object to compare with this object.</param>
+        /// <returns><value>true</value> if the current object is equal to the <paramref name="other"/> parameter; otherwise, <value>false</value>.
+        /// </returns>
+        public bool Equals(Symbol other)
+        {
+            return Equals(this, other);
+        }
+
+        #endregion
+        
+        public static readonly Symbol Definitions = new Symbol("DEFINITIONS");        
+        public static readonly Symbol Begin = new Symbol("BEGIN");        
+        public static readonly Symbol Object = new Symbol("OBJECT");        
+        public static readonly Symbol Identifier = new Symbol("IDENTIFIER");
+        public static readonly Symbol Assign = new Symbol("::=");
+        public static readonly Symbol OpenBracket = new Symbol("{");
+        public static readonly Symbol CloseBracket = new Symbol("}");
+        public static readonly Symbol Comment = new Symbol("--");
+        public static readonly Symbol Imports = new Symbol("IMPORTS");
+        public static readonly Symbol Semicolon = new Symbol(";");
+        public static readonly Symbol From = new Symbol("FROM");
+        public static readonly Symbol ModuleIdentity = new Symbol("MODULE-IDENTITY");
+        public static readonly Symbol ObjectType = new Symbol("OBJECT-TYPE");
+        public static readonly Symbol ObjectGroup = new Symbol("OBJECT-GROUP");
+        public static readonly Symbol NotificationGroup = new Symbol("NOTIFICATION-GROUP");
+        public static readonly Symbol ModuleCompliance = new Symbol("MODULE-COMPLIANCE");
+        public static readonly Symbol Sequence = new Symbol("SEQUENCE");
+        public static readonly Symbol NotificationType = new Symbol("NOTIFICATION-TYPE");
+        public static readonly Symbol EOL = new Symbol(Environment.NewLine);
+        public static readonly Symbol ObjectIdentity = new Symbol("OBJECT-IDENTITY");
+        public static readonly Symbol End = new Symbol("END");
+        public static readonly Symbol Macro = new Symbol("MACRO");
+        public static readonly Symbol Choice = new Symbol("CHOICE");
+        public static readonly Symbol TrapType = new Symbol("TRAP-TYPE");
+        public static readonly Symbol AgentCapabilities = new Symbol("AGENT-CAPABILITIES");
+        public static readonly Symbol Comma = new Symbol(",");
+        public static readonly Symbol TextualConvention = new Symbol("TEXTUAL-CONVENTION");
+        public static readonly Symbol Syntax = new Symbol("SYNTAX");
+        public static readonly Symbol Bits = new Symbol("BITS");
+        public static readonly Symbol Octet = new Symbol("OCTET");
+        public static readonly Symbol String = new Symbol("STRING");
+        public static readonly Symbol OpenParentheses = new Symbol("(");
+        public static readonly Symbol CloseParentheses = new Symbol(")");
+        public static readonly Symbol Exports = new Symbol("EXPORTS");
+        public static readonly Symbol DisplayHint = new Symbol("DISPLAY-HINT");
+        public static readonly Symbol Status = new Symbol("STATUS");
+        public static readonly Symbol Description = new Symbol("DESCRIPTION");
+        public static readonly Symbol Reference = new Symbol("REFERENCE");
+        public static readonly Symbol DoubleDot = new Symbol("..");
+        public static readonly Symbol Pipe = new Symbol("|");
+        public static readonly Symbol Size = new Symbol("SIZE");
+        public static readonly Symbol Units = new Symbol("UNITS");
+        public static readonly Symbol MaxAccess = new Symbol("MAX-ACCESS");
+        public static readonly Symbol Access = new Symbol("ACCESS");
+        public static readonly Symbol Index = new Symbol("INDEX");
+        public static readonly Symbol Augments = new Symbol("AUGMENTS");
+        public static readonly Symbol DefVal = new Symbol("DEFVAL");
+        public static readonly Symbol Of = new Symbol("OF");
+        public static readonly Symbol Integer = new Symbol("INTEGER");
+        public static readonly Symbol Integer32 = new Symbol("Integer32");
+        public static readonly Symbol IpAddress = new Symbol("IpAddress");
+        public static readonly Symbol Counter32 = new Symbol("Counter32");
+        public static readonly Symbol Counter = new Symbol("Counter");
+        public static readonly Symbol TimeTicks = new Symbol("TimeTicks");
+        public static readonly Symbol Opaque = new Symbol("Opaque");
+        public static readonly Symbol Counter64 = new Symbol("Counter64");
+        public static readonly Symbol Unsigned32 = new Symbol("Unsigned32");
+        public static readonly Symbol Gauge32 = new Symbol("Gauge32");
+        public static readonly Symbol Gauge = new Symbol("Gauge");
+        public static readonly Symbol TruthValue = new Symbol("TruthValue");
+        public static readonly Symbol Implied = new Symbol("IMPLIED");
+
+        internal void Expect(Symbol expected, params Symbol[] orExpected)
+        {
+            bool isExpected = (this == expected);
+
+            if (!isExpected && (orExpected != null) && (orExpected.Length > 0))
+            {
+                // check the alternatives
+                for (int i=0; i<orExpected.Length; i++)
+                {
+                    if (this == orExpected[i])
+                    {
+                        isExpected = true;
+                        break;
+                    }
+                }              
+            }
+
+            if (!isExpected)
+            {
+                if ((orExpected == null) || (orExpected.Length == 0))
+                {
+                    Assert(false, "Unexpected symbol found! Expected '" + expected.ToString() + "'");
+                }
+                else
+                {
+                    StringBuilder msg = new StringBuilder("Unexpected symbol found! Expected one of the following: '");
+                    msg.Append(expected);
+
+                    // check the alternatives
+                    for (int i=0; i<orExpected.Length; i++)
+                    {
+                        msg.Append("', '");
+                        msg.Append(expected);
+                    }
+                    msg.Append("'");
+
+                    Assert(false, msg.ToString());
+                }
+            }
+        }
+
+        internal void Assert(bool condition, string message)
+        {
+            if (!condition)
+            {
+                throw MibException.Create(message, this);
+            }
+        }
+
+        internal void AssertIsValidIdentifier()
+        {
+            string message;
+            bool isValid = IsValidIdentifier(ToString(), out message);
+            Assert(isValid, message);
+        }
+
+        internal bool IsValidIdentifier()
+        {      
+            string message;
+            return IsValidIdentifier(ToString(), out message);
+        }
+
+        private static bool IsValidIdentifier(string name, out string message)
+        {
+            if (UseStricterValidation && (name.Length < 1 || name.Length > 64))
+            {
+                message = "an identifier must consist of 1 to 64 letters, digits, and hyphens";
+                return false;
+            }
+
+            if (!Char.IsLetter(name[0]))
+            {
+                message = "the initial character must be a letter";
+                return false;
+            }
+
+            if (name.EndsWith("-", StringComparison.Ordinal))
+            {
+                message = "a hyphen cannot be the last character of an identifier";
+                return false;
+            }
+
+            if (name.Contains("--"))
+            {
+                message = "a hyphen cannot be immediately followed by another hyphen in an identifier";
+                return false;
+            }
+
+            if (UseStricterValidation && name.Contains("_"))
+            {
+                message = "underscores are not allowed in identifiers";
+                return false;
+            }
+
+            // TODO: SMIv2 forbids "-" except in module names and keywords
+            message = null;
+            return true;
+        }
+
+        private static bool? _useStricterValidation;
+
+        private static bool UseStricterValidation
+        {
+            get
+            {
+                if (_useStricterValidation == null)
+                {
+                    object setting = ConfigurationManager.AppSettings["StricterValidationEnabled"];
+                    _useStricterValidation = setting != null && Convert.ToBoolean(setting.ToString(), CultureInfo.InvariantCulture);
+                }
+
+                return _useStricterValidation.Value;
+            }
+        }
+    }
+}
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/SharpSnmpLib/Mib/SymbolList.cs
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/SharpSnmpLib/Mib/SymbolList.cs	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/SharpSnmpLib/Mib/SymbolList.cs	(revision 457)
@@ -0,0 +1,146 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace Lextm.SharpSnmpLib.Mib
+{
+    public class SymbolList : List<Symbol>
+    {
+        public class SymbolEnumerator : ISymbolEnumerator
+        {
+            private SymbolList _list  = null;
+            private int        _index = -1;
+
+            internal SymbolEnumerator(SymbolList list)
+            {
+                if (list == null)
+                {
+                    throw new ArgumentNullException("lexer");
+                }
+
+                _list = list;
+            }
+
+            #region ISymbolEnumerator Member
+
+            public bool PutBack(Symbol item)
+            {
+                if ((_index < 0) || (_index >= _list.Count) || (item != _list[_index]))
+                {
+                    throw new ArgumentException(@"wrong last symbol", "last");
+                    //return false;
+                }
+
+                _index--;
+                return true;
+            }
+
+            #endregion
+
+            #region IEnumerator<Symbol> Member
+
+            public Symbol Current
+            {
+                get
+                {
+                    if ((_index >= 0) && (_index <= _list.Count))
+                    {
+                        return _list[_index];
+                    }
+
+                    return null;
+                }
+            }
+
+            #endregion
+
+            #region IDisposable Member
+
+            public void Dispose()
+            {
+            }
+
+            #endregion
+
+            #region IEnumerator Member
+
+            object System.Collections.IEnumerator.Current
+            {
+                get { return this.Current; }
+            }
+
+            public bool MoveNext()
+            {
+                _index++;
+                return (_index >= 0) && (_index < _list.Count);
+            }
+
+            public void Reset()
+            {
+                _index = -1;
+            }
+
+            #endregion
+        }
+
+        /// <summary>
+        /// Initializes a new instance of the <see cref="SymbolList"/> class.
+        /// </summary>
+        public SymbolList()
+        {
+        }
+
+        public ISymbolEnumerator GetSymbolEnumerator()
+        {
+            return new SymbolEnumerator(this);
+        }
+
+        public string Join(string separator)
+        {
+            if (separator == null)
+                separator = "";
+
+            StringBuilder result = new StringBuilder();
+
+            foreach (Symbol s in this)
+            {
+                result.Append(s);
+                result.Append(separator);
+            }
+
+            if (result.Length > 0)
+            {
+                result.Length -= separator.Length;
+            }
+
+            return result.ToString();
+        }
+    }
+
+    public static class SymbolEnumeratorExtension
+    {
+        public static Symbol NextSymbol(this IEnumerator<Symbol> enumerator)
+        {
+            if (enumerator.MoveNext())
+            {
+                return enumerator.Current;
+            }
+
+            return null;
+        }
+
+        public static Symbol NextNonEOLSymbol(this IEnumerator<Symbol> enumerator)
+        {
+            while (enumerator.MoveNext())
+            {
+                if (enumerator.Current != Symbol.EOL)
+                {
+                    return enumerator.Current;
+                }
+            }
+
+            return null;
+        }
+    }
+}
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/SharpSnmpLib/Mib/ValueMap.cs
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/SharpSnmpLib/Mib/ValueMap.cs	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/SharpSnmpLib/Mib/ValueMap.cs	(revision 457)
@@ -0,0 +1,103 @@
+using System;
+using System.Collections.Generic;
+
+namespace Lextm.SharpSnmpLib.Mib
+{
+	public class ValueMap : Dictionary<Int64, string>
+	{
+		public ValueMap()
+		{
+		}
+
+		/// <summary>
+		/// Returns the values of the map as continous range. At best as one range.
+		/// </summary>
+		/// <returns></returns>
+		public ValueRanges GetContinousRanges()
+		{
+			ValueRanges result = new ValueRanges();
+
+			if (this.Count > 0)
+			{
+				List<Int64> values = new List<long>(this.Keys);
+				values.Sort();
+
+				Int64 last   = values[0];
+				Int64 offset = values[0];
+				for (int i=1; i<values.Count; i++)
+				{
+					if (values[i] != last + 1)
+					{
+						if (last == offset)
+						{
+							result.Add(new ValueRange(offset, null));
+						}
+						else
+						{
+							result.Add(new ValueRange(offset, last));
+						}
+
+						offset = values[i];
+					}
+
+					last = values[i];
+				}
+
+				if (last == offset)
+				{
+					result.Add(new ValueRange(offset, null));
+				}
+				else
+				{
+					result.Add(new ValueRange(offset, last));
+				}
+			}
+
+			return result;
+		}
+
+		/// <summary>
+		/// Gets the highest value contained in this value map.
+		/// </summary>
+		/// <returns></returns>
+		public Int64 GetHighestValue()
+		{
+			Int64 result = 0;
+
+			foreach (Int64 value in this.Keys)
+			{
+				if (value > result)
+				{
+					result = value;
+				}
+			}
+
+			return result;
+		}
+
+		/// <summary>
+		/// Interprets the single values as bit positions and creates a mask of it.
+		/// </summary>
+		/// <returns></returns>
+		public UInt32 GetBitMask()
+		{
+			UInt32 result = 0;
+
+			foreach (Int64 key in this.Keys)
+			{
+				if (key < 0)
+				{
+					throw new NotSupportedException("Negative numbers are not allowed for Bits!");
+				}
+				if (key > 31)
+				{
+					throw new NotSupportedException("Bits with more than 32 bits are not supported!");
+				}
+
+				result |= (UInt32)(1 << (int)key);
+			}
+
+			return result;
+		}
+	}
+}
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/SharpSnmpLib/Mib/ValueRange.cs
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/SharpSnmpLib/Mib/ValueRange.cs	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/SharpSnmpLib/Mib/ValueRange.cs	(revision 457)
@@ -0,0 +1,76 @@
+using System;
+using System.Collections.Generic;
+
+namespace Lextm.SharpSnmpLib.Mib
+{
+    public class ValueRanges: List<ValueRange>
+    {
+        public bool IsSizeDeclaration { get; internal set; }
+
+        public ValueRanges(bool isSizeDecl = false)
+        {
+            IsSizeDeclaration = isSizeDecl;
+        }
+
+        public bool Contains(Int64 value)
+        {
+            foreach (ValueRange range in this)
+            {
+                if (range.Contains(value))
+                {
+                    return true;
+                }
+            }
+
+            return false;
+        }
+    }
+
+    public class ValueRange
+    {
+        private readonly Int64 _start;
+        private readonly Int64? _end;
+
+        public ValueRange(Int64 first, Int64? second)
+        {
+            _start = first;
+            _end   = second;
+        }
+
+        public Int64 Start
+        {
+            get { return _start; }
+        }
+
+        public Int64? End
+        {
+            get { return _end; }
+        }
+
+        public bool IntersectsWith(ValueRange other)
+        {
+            if (this._end == null)
+            {
+                return other.Contains(this._start);
+            }
+            else if (other._end == null)
+            {
+                return this.Contains(other._start);
+            }
+
+            return (this._start <= other.End) && (this._end >= other._start);
+        }
+
+        public bool Contains(Int64 value)
+        {
+            if (_end == null)
+            {
+                return value == _start;
+            }
+            else
+            {
+                return (_start <= value) && (value <= _end);
+            }
+        }
+    }
+}
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/SharpSnmpLib/Properties/AssemblyInfo.cs
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/SharpSnmpLib/Properties/AssemblyInfo.cs	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/SharpSnmpLib/Properties/AssemblyInfo.cs	(revision 457)
@@ -0,0 +1,61 @@
+// <summary>#SNMP Library. An open source SNMP implementation for .NET.</summary>
+// <copyright company="Lex Y. Li" file="AssemblyInfo.cs">Copyright (C) 2008  Lex Y. Li</copyright>
+// 
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+// 
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+// 
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+
+#region Using directives
+
+using System;
+using System.Reflection;
+using System.Resources;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+#endregion
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("SharpSnmpLib")]
+[assembly: AssemblyDescription("#SNMP Library for .NET")]
+[assembly: AssemblyConfiguration("Lesser GPL 2.1+")]
+[assembly: AssemblyCompany("LeXtudio")]
+[assembly: AssemblyProduct("#SNMPLib")]
+[assembly: AssemblyCopyright("(C) 2008-2010 Malcolm Crowe, Lex Li, Steve Santacroce, and other contributors.")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// This sets the default COM visibility of types in the assembly to invisible.
+// If you need to expose index type to COM, use [ComVisible(true)] on that type.
+[assembly: ComVisible(false)]
+
+// The assembly version has following format :
+//
+// Major.Minor.Build.Revision
+//
+// You can specify all the values or you can use the default the Revision and
+// Build Numbers by using the '*' as shown below:
+[assembly: AssemblyVersion("7.0.011207.31")]
+#if (!CF)
+[assembly: AssemblyFileVersion("7.0.011207.31")]
+#endif
+[assembly: NeutralResourcesLanguage("en-US")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Lextm")]
+
+[assembly: InternalsVisibleTo("SharpSnmpLib.Tests, PublicKey=0024000004800000940000000602000000240000525341310004000001000100f7030532c52524"
++ "993841a0d09420340f3814e1b65473851bdcd18815510b035a2ae9ecee69c4cd2d9e4d6e6d5fbf"
++ "a564e86c4a4cddc9597619a31c060846ebb2e99511a0323ff82b1ebd95d6a4912502945f0e769f"
++ "190a69a439dbfb969ebad72a6f7e2e047907da4a7b9c08c6e98d5f1be8b8cafaf3eb978914059a"
++ "245d4bc1")]
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/SharpSnmpLib/Properties/Resources.Designer.cs
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/SharpSnmpLib/Properties/Resources.Designer.cs	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/SharpSnmpLib/Properties/Resources.Designer.cs	(revision 457)
@@ -0,0 +1,63 @@
+//------------------------------------------------------------------------------
+// <auto-generated>
+//     Dieser Code wurde von einem Tool generiert.
+//     Laufzeitversion:4.0.30319.225
+//
+//     Anderungen an dieser Datei konnen falsches Verhalten verursachen und gehen verloren, wenn
+//     der Code erneut generiert wird.
+// </auto-generated>
+//------------------------------------------------------------------------------
+
+namespace Lextm.SharpSnmpLib.Mib {
+    using System;
+    
+    
+    /// <summary>
+    ///   Eine stark typisierte Ressourcenklasse zum Suchen von lokalisierten Zeichenfolgen usw.
+    /// </summary>
+    // Diese Klasse wurde von der StronglyTypedResourceBuilder automatisch generiert
+    // -Klasse uber ein Tool wie ResGen oder Visual Studio automatisch generiert.
+    // Um einen Member hinzuzufugen oder zu entfernen, bearbeiten Sie die .ResX-Datei und fuhren dann ResGen
+    // mit der /str-Option erneut aus, oder Sie erstellen Ihr VS-Projekt neu.
+    [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+    [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
+    internal class Resources {
+        
+        private static global::System.Resources.ResourceManager resourceMan;
+        
+        private static global::System.Globalization.CultureInfo resourceCulture;
+        
+        [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
+        internal Resources() {
+        }
+        
+        /// <summary>
+        ///   Gibt die zwischengespeicherte ResourceManager-Instanz zuruck, die von dieser Klasse verwendet wird.
+        /// </summary>
+        [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
+        internal static global::System.Resources.ResourceManager ResourceManager {
+            get {
+                if (object.ReferenceEquals(resourceMan, null)) {
+                    global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Lextm.SharpSnmpLib.Properties.Resources", typeof(Resources).Assembly);
+                    resourceMan = temp;
+                }
+                return resourceMan;
+            }
+        }
+        
+        /// <summary>
+        ///   Uberschreibt die CurrentUICulture-Eigenschaft des aktuellen Threads fur alle
+        ///   Ressourcenzuordnungen, die diese stark typisierte Ressourcenklasse verwenden.
+        /// </summary>
+        [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
+        internal static global::System.Globalization.CultureInfo Culture {
+            get {
+                return resourceCulture;
+            }
+            set {
+                resourceCulture = value;
+            }
+        }
+    }
+}
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/SharpSnmpLib/Properties/Resources.resx
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/SharpSnmpLib/Properties/Resources.resx	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/SharpSnmpLib/Properties/Resources.resx	(revision 457)
@@ -0,0 +1,120 @@
+<?xml version="1.0" encoding="utf-8"?>
+<root>
+  <!-- 
+    Microsoft ResX Schema 
+    
+    Version 2.0
+    
+    The primary goals of this format is to allow a simple XML format 
+    that is mostly human readable. The generation and parsing of the 
+    various data types are done through the TypeConverter classes 
+    associated with the data types.
+    
+    Example:
+    
+    ... ado.net/XML headers & schema ...
+    <resheader name="resmimetype">text/microsoft-resx</resheader>
+    <resheader name="version">2.0</resheader>
+    <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
+    <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
+    <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
+    <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
+    <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
+        <value>[base64 mime encoded serialized .NET Framework object]</value>
+    </data>
+    <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
+        <comment>This is a comment</comment>
+    </data>
+                
+    There are any number of "resheader" rows that contain simple 
+    name/value pairs.
+    
+    Each data row contains a name, and value. The row also contains a 
+    type or mimetype. Type corresponds to a .NET class that support 
+    text/value conversion through the TypeConverter architecture. 
+    Classes that don't support this are serialized and stored with the 
+    mimetype set.
+    
+    The mimetype is used for serialized objects, and tells the 
+    ResXResourceReader how to depersist the object. This is currently not 
+    extensible. For a given mimetype the value must be set accordingly:
+    
+    Note - application/x-microsoft.net.object.binary.base64 is the format 
+    that the ResXResourceWriter will generate, however the reader can 
+    read any of the formats listed below.
+    
+    mimetype: application/x-microsoft.net.object.binary.base64
+    value   : The object must be serialized with 
+            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
+            : and then encoded with base64 encoding.
+    
+    mimetype: application/x-microsoft.net.object.soap.base64
+    value   : The object must be serialized with 
+            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
+            : and then encoded with base64 encoding.
+
+    mimetype: application/x-microsoft.net.object.bytearray.base64
+    value   : The object must be serialized into a byte array 
+            : using a System.ComponentModel.TypeConverter
+            : and then encoded with base64 encoding.
+    -->
+  <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
+    <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
+    <xsd:element name="root" msdata:IsDataSet="true">
+      <xsd:complexType>
+        <xsd:choice maxOccurs="unbounded">
+          <xsd:element name="metadata">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" />
+              </xsd:sequence>
+              <xsd:attribute name="name" use="required" type="xsd:string" />
+              <xsd:attribute name="type" type="xsd:string" />
+              <xsd:attribute name="mimetype" type="xsd:string" />
+              <xsd:attribute ref="xml:space" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="assembly">
+            <xsd:complexType>
+              <xsd:attribute name="alias" type="xsd:string" />
+              <xsd:attribute name="name" type="xsd:string" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="data">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+                <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
+              <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
+              <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
+              <xsd:attribute ref="xml:space" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="resheader">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" use="required" />
+            </xsd:complexType>
+          </xsd:element>
+        </xsd:choice>
+      </xsd:complexType>
+    </xsd:element>
+  </xsd:schema>
+  <resheader name="resmimetype">
+    <value>text/microsoft-resx</value>
+  </resheader>
+  <resheader name="version">
+    <value>2.0</value>
+  </resheader>
+  <resheader name="reader">
+    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+  <resheader name="writer">
+    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+</root>
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/SharpSnmpLib/SharpSnmpLib.Mib.csproj
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/SharpSnmpLib/SharpSnmpLib.Mib.csproj	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/SharpSnmpLib/SharpSnmpLib.Mib.csproj	(revision 457)
@@ -0,0 +1,140 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+    <ProductVersion>8.0.30703</ProductVersion>
+    <SchemaVersion>2.0</SchemaVersion>
+    <ProjectGuid>{CBE20411-5DB7-487D-825D-7694267BB6F5}</ProjectGuid>
+    <OutputType>Library</OutputType>
+    <AppDesignerFolder>Properties</AppDesignerFolder>
+    <RootNamespace>Lextm.SharpSnmpLib</RootNamespace>
+    <AssemblyName>SharpSnmpLib.Mib</AssemblyName>
+    <DocumentationFile>..\bin\SharpSnmpLib.Mib.xml</DocumentationFile>
+    <FileAlignment>512</FileAlignment>
+    <TargetFrameworkProfile />
+    <SignAssembly>True</SignAssembly>
+    <AssemblyOriginatorKeyFile>sharpsnmplib.snk</AssemblyOriginatorKeyFile>
+    <DelaySign>False</DelaySign>
+    <AssemblyOriginatorKeyMode>File</AssemblyOriginatorKeyMode>
+    <SccProjectName>
+    </SccProjectName>
+    <SccLocalPath>
+    </SccLocalPath>
+    <SccAuxPath>
+    </SccAuxPath>
+    <SccProvider>
+    </SccProvider>
+    <RunSourceAnalysis>False</RunSourceAnalysis>
+    <TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+    <DebugSymbols>true</DebugSymbols>
+    <DebugType>full</DebugType>
+    <Optimize>false</Optimize>
+    <OutputPath>bin\Debug\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+    <DocumentationFile>
+    </DocumentationFile>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+    <DebugType>pdbonly</DebugType>
+    <Optimize>true</Optimize>
+    <OutputPath>bin\Release\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+    <DocumentationFile>
+    </DocumentationFile>
+  </PropertyGroup>
+  <ItemGroup>
+    <Reference Include="System" />
+    <Reference Include="System.Configuration" />
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="Mib\DisplayHint.cs" />
+    <Compile Include="Mib\Elements\Entities\AgentCapabilities.cs" />
+    <Compile Include="Mib\Elements\Entities\EntityBase.cs" />
+    <Compile Include="Mib\Elements\Entities\IEntity.cs" />
+    <Compile Include="Mib\Elements\Entities\ModuleCompliance.cs" />
+    <Compile Include="Mib\Elements\Entities\ModuleIdentity.cs" />
+    <Compile Include="Mib\Elements\Entities\NotificationGroup.cs" />
+    <Compile Include="Mib\Elements\Entities\NotificationType.cs" />
+    <Compile Include="Mib\Elements\Entities\ObjectGroup.cs" />
+    <Compile Include="Mib\Elements\Entities\ObjectIdentity.cs" />
+    <Compile Include="Mib\Elements\Entities\ObjectType.cs" />
+    <Compile Include="Mib\Elements\Entities\OidValueAssignment.cs" />
+    <Compile Include="Mib\Elements\Exports.cs" />
+    <Compile Include="Mib\Elements\IElement.cs" />
+    <Compile Include="Mib\Elements\Imports.cs" />
+    <Compile Include="Mib\Elements\ImportsFrom.cs" />
+    <Compile Include="Mib\Elements\IDeclaration.cs" />
+    <Compile Include="Mib\Elements\TrapType.cs" />
+    <Compile Include="Mib\Elements\Types\BaseType.cs" />
+    <Compile Include="Mib\Elements\Types\BitsType.cs" />
+    <Compile Include="Mib\Elements\Types\Choice.cs" />
+    <Compile Include="Mib\Elements\Types\IntegerType.cs" />
+    <Compile Include="Mib\Elements\Types\IpAddressType.cs" />
+    <Compile Include="Mib\Elements\Types\ITypeAssignment.cs" />
+    <Compile Include="Mib\Elements\ITypeReferrer.cs" />
+    <Compile Include="Mib\Elements\Types\Macro.cs" />
+    <Compile Include="Mib\Elements\Types\ObjectIdentifierType.cs" />
+    <Compile Include="Mib\Elements\Types\OctetStringType.cs" />
+    <Compile Include="Mib\Elements\Types\OpaqueType.cs" />
+    <Compile Include="Mib\Elements\Types\Sequence.cs" />
+    <Compile Include="Mib\Elements\Types\SequenceOf.cs" />
+    <Compile Include="Mib\Elements\Types\TextualConvention.cs" />
+    <Compile Include="Mib\Elements\Types\TypeAssignment.cs" />
+    <Compile Include="Mib\Elements\Types\UnsignedType.cs" />
+    <Compile Include="Mib\IModule.cs" />
+    <Compile Include="Mib\ISymbolEnumerator.cs" />
+    <Compile Include="Mib\MaxAccess.cs" />
+    <Compile Include="Mib\MibResolver.cs" />
+    <Compile Include="Mib\MibTree.cs" />
+    <Compile Include="Mib\MibTreeNode.cs" />
+    <Compile Include="Mib\MibTypesResolver.cs" />
+    <Compile Include="Mib\ObjectIdentifier.cs" />
+    <Compile Include="Mib\Status.cs" />
+    <Compile Include="Mib\SymbolList.cs" />
+    <Compile Include="Mib\Lexer.cs" />
+    <Compile Include="Mib\MibDocument.cs" />
+    <Compile Include="Mib\MibModule.cs" />
+    <Compile Include="Mib\MibException.cs" />
+    <Compile Include="Mib\Symbol.cs" />
+    <Compile Include="Mib\ValueMap.cs" />
+    <Compile Include="Mib\ValueRange.cs" />
+    <Compile Include="Properties\AssemblyInfo.cs" />
+    <Compile Include="Properties\Resources.Designer.cs">
+      <AutoGen>True</AutoGen>
+      <DesignTime>True</DesignTime>
+      <DependentUpon>Resources.resx</DependentUpon>
+    </Compile>
+  </ItemGroup>
+  <ItemGroup>
+    <None Include="sharpsnmplib.snk" />
+  </ItemGroup>
+  <ItemGroup>
+    <None Include="license.txt" />
+  </ItemGroup>
+  <ItemGroup>
+    <EmbeddedResource Include="Properties\Resources.resx">
+      <Generator>ResXFileCodeGenerator</Generator>
+      <LastGenOutput>Resources.Designer.cs</LastGenOutput>
+      <CustomToolNamespace>Lextm.SharpSnmpLib.Mib</CustomToolNamespace>
+      <SubType>Designer</SubType>
+    </EmbeddedResource>
+  </ItemGroup>
+  <ItemGroup>
+    <Folder Include="Resources\" />
+  </ItemGroup>
+  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
+       Other similar extension points exist, see Microsoft.Common.targets.
+  <Target Name="BeforeBuild">
+  </Target>
+  <Target Name="AfterBuild">
+  </Target>
+  -->
+</Project>
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/SharpSnmpLib/license.txt
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/SharpSnmpLib/license.txt	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/SharpSnmpLib/license.txt	(revision 457)
@@ -0,0 +1,458 @@
+		  GNU LESSER GENERAL PUBLIC LICENSE
+		       Version 2.1, February 1999
+
+ Copyright (C) 1991, 1999 Free Software Foundation, Inc.
+     59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+[This is the first released version of the Lesser GPL.  It also counts
+ as the successor of the GNU Library Public License, version 2, hence
+ the version number 2.1.]
+
+			    Preamble
+
+  The licenses for most software are designed to take away your
+freedom to share and change it.  By contrast, the GNU General Public
+Licenses are intended to guarantee your freedom to share and change
+free software--to make sure the software is free for all its users.
+
+  This license, the Lesser General Public License, applies to some
+specially designated software packages--typically libraries--of the
+Free Software Foundation and other authors who decide to use it.  You
+can use it too, but we suggest you first think carefully about whether
+this license or the ordinary General Public License is the better
+strategy to use in any particular case, based on the explanations below.
+
+  When we speak of free software, we are referring to freedom of use,
+not price.  Our General Public Licenses are designed to make sure that
+you have the freedom to distribute copies of free software (and charge
+for this service if you wish); that you receive source code or can get
+it if you want it; that you can change the software and use pieces of
+it in new free programs; and that you are informed that you can do
+these things.
+
+  To protect your rights, we need to make restrictions that forbid
+distributors to deny you these rights or to ask you to surrender these
+rights.  These restrictions translate to certain responsibilities for
+you if you distribute copies of the library or if you modify it.
+
+  For example, if you distribute copies of the library, whether gratis
+or for a fee, you must give the recipients all the rights that we gave
+you.  You must make sure that they, too, receive or can get the source
+code.  If you link other code with the library, you must provide
+complete object files to the recipients, so that they can relink them
+with the library after making changes to the library and recompiling
+it.  And you must show them these terms so they know their rights.
+
+  We protect your rights with a two-step method: (1) we copyright the
+library, and (2) we offer you this license, which gives you legal
+permission to copy, distribute and/or modify the library.
+
+  To protect each distributor, we want to make it very clear that
+there is no warranty for the free library.  Also, if the library is
+modified by someone else and passed on, the recipients should know
+that what they have is not the original version, so that the original
+author's reputation will not be affected by problems that might be
+introduced by others.
+
+  Finally, software patents pose a constant threat to the existence of
+any free program.  We wish to make sure that a company cannot
+effectively restrict the users of a free program by obtaining a
+restrictive license from a patent holder.  Therefore, we insist that
+any patent license obtained for a version of the library must be
+consistent with the full freedom of use specified in this license.
+
+  Most GNU software, including some libraries, is covered by the
+ordinary GNU General Public License.  This license, the GNU Lesser
+General Public License, applies to certain designated libraries, and
+is quite different from the ordinary General Public License.  We use
+this license for certain libraries in order to permit linking those
+libraries into non-free programs.
+
+  When a program is linked with a library, whether statically or using
+a shared library, the combination of the two is legally speaking a
+combined work, a derivative of the original library.  The ordinary
+General Public License therefore permits such linking only if the
+entire combination fits its criteria of freedom.  The Lesser General
+Public License permits more lax criteria for linking other code with
+the library.
+
+  We call this license the "Lesser" General Public License because it
+does Less to protect the user's freedom than the ordinary General
+Public License.  It also provides other free software developers Less
+of an advantage over competing non-free programs.  These disadvantages
+are the reason we use the ordinary General Public License for many
+libraries.  However, the Lesser license provides advantages in certain
+special circumstances.
+
+  For example, on rare occasions, there may be a special need to
+encourage the widest possible use of a certain library, so that it becomes
+a de-facto standard.  To achieve this, non-free programs must be
+allowed to use the library.  A more frequent case is that a free
+library does the same job as widely used non-free libraries.  In this
+case, there is little to gain by limiting the free library to free
+software only, so we use the Lesser General Public License.
+
+  In other cases, permission to use a particular library in non-free
+programs enables a greater number of people to use a large body of
+free software.  For example, permission to use the GNU C Library in
+non-free programs enables many more people to use the whole GNU
+operating system, as well as its variant, the GNU/Linux operating
+system.
+
+  Although the Lesser General Public License is Less protective of the
+users' freedom, it does ensure that the user of a program that is
+linked with the Library has the freedom and the wherewithal to run
+that program using a modified version of the Library.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.  Pay close attention to the difference between a
+"work based on the library" and a "work that uses the library".  The
+former contains code derived from the library, whereas the latter must
+be combined with the library in order to run.
+
+		  GNU LESSER GENERAL PUBLIC LICENSE
+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+  0. This License Agreement applies to any software library or other
+program which contains a notice placed by the copyright holder or
+other authorized party saying it may be distributed under the terms of
+this Lesser General Public License (also called "this License").
+Each licensee is addressed as "you".
+
+  A "library" means a collection of software functions and/or data
+prepared so as to be conveniently linked with application programs
+(which use some of those functions and data) to form executables.
+
+  The "Library", below, refers to any such software library or work
+which has been distributed under these terms.  A "work based on the
+Library" means either the Library or any derivative work under
+copyright law: that is to say, a work containing the Library or a
+portion of it, either verbatim or with modifications and/or translated
+straightforwardly into another language.  (Hereinafter, translation is
+included without limitation in the term "modification".)
+
+  "Source code" for a work means the preferred form of the work for
+making modifications to it.  For a library, complete source code means
+all the source code for all modules it contains, plus any associated
+interface definition files, plus the scripts used to control compilation
+and installation of the library.
+
+  Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope.  The act of
+running a program using the Library is not restricted, and output from
+such a program is covered only if its contents constitute a work based
+on the Library (independent of the use of the Library in a tool for
+writing it).  Whether that is true depends on what the Library does
+and what the program that uses the Library does.
+  
+  1. You may copy and distribute verbatim copies of the Library's
+complete source code as you receive it, in any medium, provided that
+you conspicuously and appropriately publish on each copy an
+appropriate copyright notice and disclaimer of warranty; keep intact
+all the notices that refer to this License and to the absence of any
+warranty; and distribute a copy of this License along with the
+Library.
+
+  You may charge a fee for the physical act of transferring a copy,
+and you may at your option offer warranty protection in exchange for a
+fee.
+
+  2. You may modify your copy or copies of the Library or any portion
+of it, thus forming a work based on the Library, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+    a) The modified work must itself be a software library.
+
+    b) You must cause the files modified to carry prominent notices
+    stating that you changed the files and the date of any change.
+
+    c) You must cause the whole of the work to be licensed at no
+    charge to all third parties under the terms of this License.
+
+    d) If a facility in the modified Library refers to a function or a
+    table of data to be supplied by an application program that uses
+    the facility, other than as an argument passed when the facility
+    is invoked, then you must make a good faith effort to ensure that,
+    in the event an application does not supply such function or
+    table, the facility still operates, and performs whatever part of
+    its purpose remains meaningful.
+
+    (For example, a function in a library to compute square roots has
+    a purpose that is entirely well-defined independent of the
+    application.  Therefore, Subsection 2d requires that any
+    application-supplied function or table used by this function must
+    be optional: if the application does not supply it, the square
+    root function must still compute square roots.)
+
+These requirements apply to the modified work as a whole.  If
+identifiable sections of that work are not derived from the Library,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works.  But when you
+distribute the same sections as part of a whole which is a work based
+on the Library, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote
+it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Library.
+
+In addition, mere aggregation of another work not based on the Library
+with the Library (or with a work based on the Library) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+  3. You may opt to apply the terms of the ordinary GNU General Public
+License instead of this License to a given copy of the Library.  To do
+this, you must alter all the notices that refer to this License, so
+that they refer to the ordinary GNU General Public License, version 2,
+instead of to this License.  (If a newer version than version 2 of the
+ordinary GNU General Public License has appeared, then you can specify
+that version instead if you wish.)  Do not make any other change in
+these notices.
+
+  Once this change is made in a given copy, it is irreversible for
+that copy, so the ordinary GNU General Public License applies to all
+subsequent copies and derivative works made from that copy.
+
+  This option is useful when you wish to copy part of the code of
+the Library into a program that is not a library.
+
+  4. You may copy and distribute the Library (or a portion or
+derivative of it, under Section 2) in object code or executable form
+under the terms of Sections 1 and 2 above provided that you accompany
+it with the complete corresponding machine-readable source code, which
+must be distributed under the terms of Sections 1 and 2 above on a
+medium customarily used for software interchange.
+
+  If distribution of object code is made by offering access to copy
+from a designated place, then offering equivalent access to copy the
+source code from the same place satisfies the requirement to
+distribute the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+  5. A program that contains no derivative of any portion of the
+Library, but is designed to work with the Library by being compiled or
+linked with it, is called a "work that uses the Library".  Such a
+work, in isolation, is not a derivative work of the Library, and
+therefore falls outside the scope of this License.
+
+  However, linking a "work that uses the Library" with the Library
+creates an executable that is a derivative of the Library (because it
+contains portions of the Library), rather than a "work that uses the
+library".  The executable is therefore covered by this License.
+Section 6 states terms for distribution of such executables.
+
+  When a "work that uses the Library" uses material from a header file
+that is part of the Library, the object code for the work may be a
+derivative work of the Library even though the source code is not.
+Whether this is true is especially significant if the work can be
+linked without the Library, or if the work is itself a library.  The
+threshold for this to be true is not precisely defined by law.
+
+  If such an object file uses only numerical parameters, data
+structure layouts and accessors, and small macros and small inline
+functions (ten lines or less in length), then the use of the object
+file is unrestricted, regardless of whether it is legally a derivative
+work.  (Executables containing this object code plus portions of the
+Library will still fall under Section 6.)
+
+  Otherwise, if the work is a derivative of the Library, you may
+distribute the object code for the work under the terms of Section 6.
+Any executables containing that work also fall under Section 6,
+whether or not they are linked directly with the Library itself.
+
+  6. As an exception to the Sections above, you may also combine or
+link a "work that uses the Library" with the Library to produce a
+work containing portions of the Library, and distribute that work
+under terms of your choice, provided that the terms permit
+modification of the work for the customer's own use and reverse
+engineering for debugging such modifications.
+
+  You must give prominent notice with each copy of the work that the
+Library is used in it and that the Library and its use are covered by
+this License.  You must supply a copy of this License.  If the work
+during execution displays copyright notices, you must include the
+copyright notice for the Library among them, as well as a reference
+directing the user to the copy of this License.  Also, you must do one
+of these things:
+
+    a) Accompany the work with the complete corresponding
+    machine-readable source code for the Library including whatever
+    changes were used in the work (which must be distributed under
+    Sections 1 and 2 above); and, if the work is an executable linked
+    with the Library, with the complete machine-readable "work that
+    uses the Library", as object code and/or source code, so that the
+    user can modify the Library and then relink to produce a modified
+    executable containing the modified Library.  (It is understood
+    that the user who changes the contents of definitions files in the
+    Library will not necessarily be able to recompile the application
+    to use the modified definitions.)
+
+    b) Use a suitable shared library mechanism for linking with the
+    Library.  A suitable mechanism is one that (1) uses at run time a
+    copy of the library already present on the user's computer system,
+    rather than copying library functions into the executable, and (2)
+    will operate properly with a modified version of the library, if
+    the user installs one, as long as the modified version is
+    interface-compatible with the version that the work was made with.
+
+    c) Accompany the work with a written offer, valid for at
+    least three years, to give the same user the materials
+    specified in Subsection 6a, above, for a charge no more
+    than the cost of performing this distribution.
+
+    d) If distribution of the work is made by offering access to copy
+    from a designated place, offer equivalent access to copy the above
+    specified materials from the same place.
+
+    e) Verify that the user has already received a copy of these
+    materials or that you have already sent this user a copy.
+
+  For an executable, the required form of the "work that uses the
+Library" must include any data and utility programs needed for
+reproducing the executable from it.  However, as a special exception,
+the materials to be distributed need not include anything that is
+normally distributed (in either source or binary form) with the major
+components (compiler, kernel, and so on) of the operating system on
+which the executable runs, unless that component itself accompanies
+the executable.
+
+  It may happen that this requirement contradicts the license
+restrictions of other proprietary libraries that do not normally
+accompany the operating system.  Such a contradiction means you cannot
+use both them and the Library together in an executable that you
+distribute.
+
+  7. You may place library facilities that are a work based on the
+Library side-by-side in a single library together with other library
+facilities not covered by this License, and distribute such a combined
+library, provided that the separate distribution of the work based on
+the Library and of the other library facilities is otherwise
+permitted, and provided that you do these two things:
+
+    a) Accompany the combined library with a copy of the same work
+    based on the Library, uncombined with any other library
+    facilities.  This must be distributed under the terms of the
+    Sections above.
+
+    b) Give prominent notice with the combined library of the fact
+    that part of it is a work based on the Library, and explaining
+    where to find the accompanying uncombined form of the same work.
+
+  8. You may not copy, modify, sublicense, link with, or distribute
+the Library except as expressly provided under this License.  Any
+attempt otherwise to copy, modify, sublicense, link with, or
+distribute the Library is void, and will automatically terminate your
+rights under this License.  However, parties who have received copies,
+or rights, from you under this License will not have their licenses
+terminated so long as such parties remain in full compliance.
+
+  9. You are not required to accept this License, since you have not
+signed it.  However, nothing else grants you permission to modify or
+distribute the Library or its derivative works.  These actions are
+prohibited by law if you do not accept this License.  Therefore, by
+modifying or distributing the Library (or any work based on the
+Library), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Library or works based on it.
+
+  10. Each time you redistribute the Library (or any work based on the
+Library), the recipient automatically receives a license from the
+original licensor to copy, distribute, link with or modify the Library
+subject to these terms and conditions.  You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties with
+this License.
+
+  11. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Library at all.  For example, if a patent
+license would not permit royalty-free redistribution of the Library by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Library.
+
+If any portion of this section is held invalid or unenforceable under any
+particular circumstance, the balance of the section is intended to apply,
+and the section as a whole is intended to apply in other circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system which is
+implemented by public license practices.  Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+  12. If the distribution and/or use of the Library is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Library under this License may add
+an explicit geographical distribution limitation excluding those countries,
+so that distribution is permitted only in or among countries not thus
+excluded.  In such case, this License incorporates the limitation as if
+written in the body of this License.
+
+  13. The Free Software Foundation may publish revised and/or new
+versions of the Lesser General Public License from time to time.
+Such new versions will be similar in spirit to the present version,
+but may differ in detail to address new problems or concerns.
+
+Each version is given a distinguishing version number.  If the Library
+specifies a version number of this License which applies to it and
+"any later version", you have the option of following the terms and
+conditions either of that version or of any later version published by
+the Free Software Foundation.  If the Library does not specify a
+license version number, you may choose any version ever published by
+the Free Software Foundation.
+
+  14. If you wish to incorporate parts of the Library into other free
+programs whose distribution conditions are incompatible with these,
+write to the author to ask for permission.  For software which is
+copyrighted by the Free Software Foundation, write to the Free
+Software Foundation; we sometimes make exceptions for this.  Our
+decision will be guided by the two goals of preserving the free status
+of all derivatives of our free software and of promoting the sharing
+and reuse of software generally.
+
+			    NO WARRANTY
+
+  15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
+WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
+EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
+OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
+KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
+LIBRARY IS WITH YOU.  SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
+THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+  16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
+WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
+AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
+FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
+CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
+LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
+RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
+FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
+SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGES.
+
+		     END OF TERMS AND CONDITIONS
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/example/compile_udp_mib.cmd
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/example/compile_udp_mib.cmd	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/example/compile_udp_mib.cmd	(revision 457)
@@ -0,0 +1,1 @@
+..\LwipMibCompiler\bin\Debug\LwipMibCompiler.exe ..\Mibs\UDP-MIB .\ ..\Mibs\
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/example/compile_udp_mib.sh
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/example/compile_udp_mib.sh	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/example/compile_udp_mib.sh	(revision 457)
@@ -0,0 +1,1 @@
+../LwipMibCompiler/bin/Debug/LwipMibCompiler.exe ../Mibs/UDP-MIB ./ ../Mibs/
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/chargen/README
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/chargen/README	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/chargen/README	(revision 457)
@@ -0,0 +1,52 @@
+
+        CHARGEN
+        
+This file implements a nice example of handling multiple tcp sockets in a
+server environment. Just call chargen_init() from your application after
+you have initialized lwip and added your network interfaces. Change the
+MAX_SERV option to increase or decrease the number of sessions supported.
+
+chargen will jam as much data as possible into the output socket, so it
+will take up a lot of CPU time. Therefore it will be a good idea to run it
+as the lowest possible priority (just ahead of any idle task).
+ 
+This is also a good example of how to support multiple sessions in an
+embedded system where you might not have fork(). The multiple sessions are
+all handled by the same thread and select() is used for demultiplexing.
+ 
+No makefile is provided, just add chargen to the makefile for your
+application. It is OS and HW independent.
+
+Once the chargen server is running in your application, go to another system
+and open a telnet session to your lwip platform at port 19. You should see an
+ASCII pattern start to stream on you screen.
+
+As an example, lets say that your system running lwip is at IP address
+192.168.10.244 and you have a linux system connected to it at IP address
+192.168.10.59. Issue the following command at a terminal prompt on the linux system:
+
+telnet 192.168.10.244 19
+
+You will see a pattern similar to the following on streaming by on your
+screen:
+
+ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{
+BCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|
+CDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}
+DEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~
+EFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~!
+FGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~!"
+GHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~!"#
+HIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~!"#$
+IJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~!"#$%
+JKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~!"#$%&
+KLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~!"#$%&'
+LMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~!"#$%&'(
+
+It even works from windows: At a dos prompt you can also issue the same
+telnet command and you will get a similar (but much slower, at least on W98)
+data stream.
+
+David Haas
+
+
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/chargen/chargen.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/chargen/chargen.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/chargen/chargen.c	(revision 457)
@@ -0,0 +1,275 @@
+/** @file
+ *
+ *  chargen server for lwip
+ */
+/*
+ * Copyright (c) 2003 NBS Card Technology, Paramus, NJ.
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission. 
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ * 
+ * Author: David Haas <dhaas@alum.rpi.edu>
+ *
+ * Purpose:   chargen server for testing and demonstration purposes
+ *
+ * This file implements a nice example of handling multiple tcp sockets in a
+ * server environment. Just call chargen_init() from your application after
+ * you have initialized lwip and added your network interfaces. Change the
+ * MAX_SERV option to increase or decrease the number of sessions supported.
+ *
+ * chargen will jam as much data as possible into the output socket, so it
+ * will take up a lot of CPU time. Therefore it will be a good idea to run it
+ * as the lowest possible priority (just ahead of any idle task).
+ *
+ * This is also a good example of how to support multiple sessions in an
+ * embedded system where you might not have fork().
+ */
+
+#include "lwip/opt.h"
+#include "lwip/sys.h"
+#include "lwip/sockets.h"
+#include "lwip/mem.h"
+
+#include <string.h>
+
+#include "chargen.h"
+
+#if LWIP_SOCKET && LWIP_SOCKET_SELECT
+
+#define MAX_SERV                 5         /* Maximum number of chargen services. Don't need too many */
+#define CHARGEN_THREAD_NAME      "chargen"
+#define CHARGEN_PRIORITY         254       /* Really low priority */
+#define CHARGEN_THREAD_STACKSIZE 0
+#define SEND_SIZE TCP_SNDLOWAT             /* If we only send this much, then when select
+                                              says we can send, we know we won't block */
+
+struct charcb {
+  struct charcb *next;
+  int socket;
+  struct sockaddr_storage cliaddr;
+  socklen_t clilen;
+  char nextchar;
+};
+
+static struct charcb *charcb_list = 0;
+
+/**************************************************************
+ * void close_chargen(struct charcb *p_charcb)
+ *
+ * Close the socket and remove this charcb from the list.
+ **************************************************************/
+static void
+close_chargen(struct charcb *p_charcb)
+{
+  struct charcb *p_search_charcb;
+
+  /* Either an error or tcp connection closed on other
+   * end. Close here */
+  lwip_close(p_charcb->socket);
+  /* Free charcb */
+  if (charcb_list == p_charcb) {
+    charcb_list = p_charcb->next;
+  } else {
+    for (p_search_charcb = charcb_list; p_search_charcb; p_search_charcb = p_search_charcb->next) {
+      if (p_search_charcb->next == p_charcb) {
+        p_search_charcb->next = p_charcb->next;
+        break;
+      }
+    }
+  }
+  mem_free(p_charcb);
+}
+
+/**************************************************************
+ * void do_read(struct charcb *p_charcb)
+ *
+ * Socket definitely is ready for reading. Read a buffer from the socket and
+ * discard the data.  If no data is read, then the socket is closed and the
+ * charcb is removed from the list and freed.
+ **************************************************************/
+static int
+do_read(struct charcb *p_charcb)
+{
+  char buffer[80];
+  int readcount;
+
+  /* Read some data */
+  readcount = lwip_read(p_charcb->socket, &buffer, 80);
+  if (readcount <= 0) {
+    close_chargen(p_charcb);
+    return -1;
+  }
+  return 0;
+}
+
+/**************************************************************
+ * void chargen_thread(void *arg)
+ *
+ * chargen task. This server will wait for connections on well
+ * known TCP port number: 19. For every connection, the server will
+ * write as much data as possible to the tcp port.
+ **************************************************************/
+static void
+chargen_thread(void *arg)
+{
+  int listenfd;
+#if LWIP_IPV6
+  struct sockaddr_in6 chargen_saddr;
+#else /* LWIP_IPV6 */
+  struct sockaddr_in chargen_saddr;
+#endif /* LWIP_IPV6 */
+  fd_set readset;
+  fd_set writeset;
+  int i, maxfdp1;
+  struct charcb *p_charcb;
+  LWIP_UNUSED_ARG(arg);
+
+  memset(&chargen_saddr, 0, sizeof (chargen_saddr));
+#if LWIP_IPV6
+  /* First acquire our socket for listening for connections */
+  listenfd = lwip_socket(AF_INET6, SOCK_STREAM, 0);
+  chargen_saddr.sin6_family = AF_INET6;
+  chargen_saddr.sin6_addr = in6addr_any;
+  chargen_saddr.sin6_port = lwip_htons(19); /* Chargen server port */
+#else /* LWIP_IPV6 */
+  /* First acquire our socket for listening for connections */
+  listenfd = lwip_socket(AF_INET, SOCK_STREAM, 0);
+  chargen_saddr.sin_family = AF_INET;
+  chargen_saddr.sin_addr.s_addr = PP_HTONL(INADDR_ANY);
+  chargen_saddr.sin_port = lwip_htons(19); /* Chargen server port */
+#endif /* LWIP_IPV6 */
+
+  LWIP_ASSERT("chargen_thread(): Socket create failed.", listenfd >= 0);
+
+  if (lwip_bind(listenfd, (struct sockaddr *) &chargen_saddr, sizeof (chargen_saddr)) == -1) {
+    LWIP_ASSERT("chargen_thread(): Socket bind failed.", 0);
+  }
+
+  /* Put socket into listening mode */
+  if (lwip_listen(listenfd, MAX_SERV) == -1) {
+    LWIP_ASSERT("chargen_thread(): Listen failed.", 0);
+  }
+
+
+  /* Wait forever for network input: This could be connections or data */
+  for (;;) {
+    maxfdp1 = listenfd + 1;
+
+    /* Determine what sockets need to be in readset */
+    FD_ZERO(&readset);
+    FD_ZERO(&writeset);
+    FD_SET(listenfd, &readset);
+    for (p_charcb = charcb_list; p_charcb; p_charcb = p_charcb->next) {
+      if (maxfdp1 < p_charcb->socket + 1) {
+        maxfdp1 = p_charcb->socket + 1;
+      }
+      FD_SET(p_charcb->socket, &readset);
+      FD_SET(p_charcb->socket, &writeset);
+    }
+
+    /* Wait for data or a new connection */
+    i = lwip_select(maxfdp1, &readset, &writeset, 0, 0);
+
+    if (i == 0) {
+      continue;
+    }
+    /* At least one descriptor is ready */
+    if (FD_ISSET(listenfd, &readset)) {
+      /* We have a new connection request!!! */
+      /* Lets create a new control block */
+      p_charcb = (struct charcb *) mem_malloc(sizeof (struct charcb));
+      if (p_charcb) {
+        p_charcb->socket = lwip_accept(listenfd,
+                (struct sockaddr *) &p_charcb->cliaddr,
+                &p_charcb->clilen);
+        if (p_charcb->socket < 0) {
+          mem_free(p_charcb);
+        } else {
+          /* Keep this tecb in our list */
+          p_charcb->next = charcb_list;
+          charcb_list = p_charcb;
+          p_charcb->nextchar = 0x21;
+        }
+      } else {
+        /* No memory to accept connection. Just accept and then close */
+        int sock;
+        struct sockaddr cliaddr;
+        socklen_t clilen;
+
+        sock = lwip_accept(listenfd, &cliaddr, &clilen);
+        if (sock >= 0) {
+          lwip_close(sock);
+        }
+      }
+    }
+    /* Go through list of connected clients and process data */
+    for (p_charcb = charcb_list; p_charcb; p_charcb = p_charcb->next) {
+      if (FD_ISSET(p_charcb->socket, &readset)) {
+        /* This socket is ready for reading. This could be because someone typed
+         * some characters or it could be because the socket is now closed. Try reading
+         * some data to see. */
+        if (do_read(p_charcb) < 0) {
+          break;
+        }
+      }
+      if (FD_ISSET(p_charcb->socket, &writeset)) {
+        char line[80];
+        char setchar = p_charcb->nextchar;
+
+        for (i = 0; i < 59; i++) {
+          line[i] = setchar;
+          if (++setchar == 0x7f) {
+            setchar = 0x21;
+          }
+        }
+        line[i++] = '\n';
+        line[i++] = '\r';
+        line[i] = 0;
+        if (lwip_write(p_charcb->socket, line, strlen(line)) < 0) {
+          close_chargen(p_charcb);
+          break;
+        }
+        if (++p_charcb->nextchar == 0x7f) {
+          p_charcb->nextchar = 0x21;
+        }
+      }
+    }
+  }
+}
+
+
+/**************************************************************
+ * void chargen_init(void)
+ *
+ * This function initializes the chargen service. This function
+ * may only be called either before or after tasking has started.
+ **************************************************************/
+void
+chargen_init(void)
+{
+  sys_thread_new(CHARGEN_THREAD_NAME, chargen_thread, 0, CHARGEN_THREAD_STACKSIZE, CHARGEN_PRIORITY);
+}
+
+#endif /* LWIP_SOCKET && LWIP_SOCKET_SELECT */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/chargen/chargen.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/chargen/chargen.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/chargen/chargen.h	(revision 457)
@@ -0,0 +1,12 @@
+#ifndef LWIP_CHARGEN_H
+#define LWIP_CHARGEN_H
+
+#include "lwip/opt.h"
+
+#if LWIP_SOCKET
+
+void chargen_init(void);
+
+#endif /* LWIP_SOCKET */
+
+#endif /* LWIP_CHARGEN_H */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/httpserver/README
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/httpserver/README	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/httpserver/README	(revision 457)
@@ -0,0 +1,12 @@
+HTTPSERVER
+
+This is a demonstration of how to make the most basic kind 
+of server using lWIP.
+
+* httpserver-raw.c - uses raw TCP calls (coming soon!)
+
+* httpserver-netconn.c - uses netconn and netbuf API
+
+This code updates the examples in Adam Dunkel's original
+lwIP documentation to match changes in the code since that
+PDF release. 
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/httpserver/httpserver-netconn.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/httpserver/httpserver-netconn.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/httpserver/httpserver-netconn.c	(revision 457)
@@ -0,0 +1,103 @@
+
+#include "lwip/opt.h"
+#include "lwip/arch.h"
+#include "lwip/api.h"
+
+#include "httpserver-netconn.h"
+
+#if LWIP_NETCONN
+
+#ifndef HTTPD_DEBUG
+#define HTTPD_DEBUG         LWIP_DBG_OFF
+#endif
+
+static const char http_html_hdr[] = "HTTP/1.1 200 OK\r\nContent-type: text/html\r\n\r\n";
+static const char http_index_html[] = "<html><head><title>Congrats!</title></head><body><h1>Welcome to our lwIP HTTP server!</h1><p>This is a small test page, served by httpserver-netconn.</body></html>";
+
+/** Serve one HTTP connection accepted in the http thread */
+static void
+http_server_netconn_serve(struct netconn *conn)
+{
+  struct netbuf *inbuf;
+  char *buf;
+  u16_t buflen;
+  err_t err;
+  
+  /* Read the data from the port, blocking if nothing yet there. 
+   We assume the request (the part we care about) is in one netbuf */
+  err = netconn_recv(conn, &inbuf);
+  
+  if (err == ERR_OK) {
+    netbuf_data(inbuf, (void**)&buf, &buflen);
+    
+    /* Is this an HTTP GET command? (only check the first 5 chars, since
+    there are other formats for GET, and we're keeping it very simple )*/
+    if (buflen>=5 &&
+        buf[0]=='G' &&
+        buf[1]=='E' &&
+        buf[2]=='T' &&
+        buf[3]==' ' &&
+        buf[4]=='/' ) {
+      
+      /* Send the HTML header 
+             * subtract 1 from the size, since we dont send the \0 in the string
+             * NETCONN_NOCOPY: our data is const static, so no need to copy it
+       */
+      netconn_write(conn, http_html_hdr, sizeof(http_html_hdr)-1, NETCONN_NOCOPY);
+      
+      /* Send our HTML page */
+      netconn_write(conn, http_index_html, sizeof(http_index_html)-1, NETCONN_NOCOPY);
+    }
+  }
+  /* Close the connection (server closes in HTTP) */
+  netconn_close(conn);
+  
+  /* Delete the buffer (netconn_recv gives us ownership,
+   so we have to make sure to deallocate the buffer) */
+  netbuf_delete(inbuf);
+}
+
+/** The main function, never returns! */
+static void
+http_server_netconn_thread(void *arg)
+{
+  struct netconn *conn, *newconn;
+  err_t err;
+  LWIP_UNUSED_ARG(arg);
+  
+  /* Create a new TCP connection handle */
+  /* Bind to port 80 (HTTP) with default IP address */
+#if LWIP_IPV6
+  conn = netconn_new(NETCONN_TCP_IPV6);
+  netconn_bind(conn, IP6_ADDR_ANY, 80);
+#else /* LWIP_IPV6 */
+  conn = netconn_new(NETCONN_TCP);
+  netconn_bind(conn, IP_ADDR_ANY, 80);
+#endif /* LWIP_IPV6 */
+  LWIP_ERROR("http_server: invalid conn", (conn != NULL), return;);
+  
+  /* Put the connection into LISTEN state */
+  netconn_listen(conn);
+  
+  do {
+    err = netconn_accept(conn, &newconn);
+    if (err == ERR_OK) {
+      http_server_netconn_serve(newconn);
+      netconn_delete(newconn);
+    }
+  } while(err == ERR_OK);
+  LWIP_DEBUGF(HTTPD_DEBUG,
+    ("http_server_netconn_thread: netconn_accept received error %d, shutting down",
+    err));
+  netconn_close(conn);
+  netconn_delete(conn);
+}
+
+/** Initialize the HTTP server (start its thread) */
+void
+http_server_netconn_init(void)
+{
+  sys_thread_new("http_server_netconn", http_server_netconn_thread, NULL, DEFAULT_THREAD_STACKSIZE, DEFAULT_THREAD_PRIO);
+}
+
+#endif /* LWIP_NETCONN*/
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/httpserver/httpserver-netconn.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/httpserver/httpserver-netconn.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/httpserver/httpserver-netconn.h	(revision 457)
@@ -0,0 +1,6 @@
+#ifndef LWIP_HTTPSERVER_NETCONN_H
+#define LWIP_HTTPSERVER_NETCONN_H
+
+void http_server_netconn_init(void);
+
+#endif /* LWIP_HTTPSERVER_NETCONN_H */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/netio/netio.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/netio/netio.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/netio/netio.c	(revision 457)
@@ -0,0 +1,55 @@
+#include "netio.h"
+
+#include "lwip/opt.h"
+#include "lwip/tcp.h"
+
+/* See http://www.nwlab.net/art/netio/netio.html to get the netio tool */
+
+#if LWIP_TCP && LWIP_CALLBACK_API
+static err_t
+netio_recv(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err)
+{
+  LWIP_UNUSED_ARG(arg);
+
+  if (err == ERR_OK && p != NULL) {
+    tcp_recved(pcb, p->tot_len);
+    pbuf_free(p);
+  } else {
+    pbuf_free(p);
+  }
+
+  if (err == ERR_OK && p == NULL) {
+    tcp_arg(pcb, NULL);
+    tcp_sent(pcb, NULL);
+    tcp_recv(pcb, NULL);
+    tcp_close(pcb);
+  }
+
+  return ERR_OK;
+}
+
+static err_t
+netio_accept(void *arg, struct tcp_pcb *pcb, err_t err)
+{
+  LWIP_UNUSED_ARG(arg);
+  LWIP_UNUSED_ARG(err);
+
+  if (pcb != NULL) {
+    tcp_arg(pcb, NULL);
+    tcp_sent(pcb, NULL);
+    tcp_recv(pcb, netio_recv);
+  }
+  return ERR_OK;
+}
+
+void
+netio_init(void)
+{
+  struct tcp_pcb *pcb;
+
+  pcb = tcp_new_ip_type(IPADDR_TYPE_ANY);
+  tcp_bind(pcb, IP_ANY_TYPE, 18767);
+  pcb = tcp_listen(pcb);
+  tcp_accept(pcb, netio_accept);
+}
+#endif /* LWIP_TCP && LWIP_CALLBACK_API */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/netio/netio.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/netio/netio.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/netio/netio.h	(revision 457)
@@ -0,0 +1,6 @@
+#ifndef LWIP_NETIO_H
+#define LWIP_NETIO_H
+
+void netio_init(void);
+
+#endif /* LWIP_NETIO_H */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/ping/ping.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/ping/ping.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/ping/ping.c	(revision 457)
@@ -0,0 +1,426 @@
+/**
+ * @file
+ * Ping sender module
+ *
+ */
+
+/*
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission. 
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ * 
+ */
+
+/** 
+ * This is an example of a "ping" sender (with raw API and socket API).
+ * It can be used as a start point to maintain opened a network connection, or
+ * like a network "watchdog" for your device.
+ *
+ */
+
+#include "lwip/opt.h"
+
+#if LWIP_RAW /* don't build if not configured for use in lwipopts.h */
+
+#include "ping.h"
+
+#include "lwip/mem.h"
+#include "lwip/raw.h"
+#include "lwip/icmp.h"
+#include "lwip/netif.h"
+#include "lwip/sys.h"
+#include "lwip/timeouts.h"
+#include "lwip/inet_chksum.h"
+#include "lwip/prot/ip4.h"
+
+#if PING_USE_SOCKETS
+#include "lwip/sockets.h"
+#include "lwip/inet.h"
+#include <string.h>
+#endif /* PING_USE_SOCKETS */
+
+
+/**
+ * PING_DEBUG: Enable debugging for PING.
+ */
+#ifndef PING_DEBUG
+#define PING_DEBUG     LWIP_DBG_ON
+#endif
+
+/** ping receive timeout - in milliseconds */
+#ifndef PING_RCV_TIMEO
+#define PING_RCV_TIMEO 1000
+#endif
+
+/** ping delay - in milliseconds */
+#ifndef PING_DELAY
+#define PING_DELAY     1000
+#endif
+
+/** ping identifier - must fit on a u16_t */
+#ifndef PING_ID
+#define PING_ID        0xAFAF
+#endif
+
+/** ping additional data size to include in the packet */
+#ifndef PING_DATA_SIZE
+#define PING_DATA_SIZE 32
+#endif
+
+/** ping result action - no default action */
+#ifndef PING_RESULT
+#define PING_RESULT(ping_ok)
+#endif
+
+/* ping variables */
+static const ip_addr_t* ping_target;
+static u16_t ping_seq_num;
+#if defined(LWIP_DEBUG) || defined(USE_PINGSEND)
+static u32_t ping_time;
+#endif /* LWIP_DEBUG */
+#if !PING_USE_SOCKETS
+static struct raw_pcb *ping_pcb;
+#endif /* PING_USE_SOCKETS */
+
+/** Prepare a echo ICMP request */
+static void
+ping_prepare_echo( struct icmp_echo_hdr *iecho, u16_t len)
+{
+  size_t i;
+  size_t data_len = len - sizeof(struct icmp_echo_hdr);
+
+  ICMPH_TYPE_SET(iecho, ICMP_ECHO);
+  ICMPH_CODE_SET(iecho, 0);
+  iecho->chksum = 0;
+  iecho->id     = PING_ID;
+  iecho->seqno  = lwip_htons(++ping_seq_num);
+
+  /* fill the additional data buffer with some data */
+  for(i = 0; i < data_len; i++) {
+    ((char*)iecho)[sizeof(struct icmp_echo_hdr) + i] = (char)i;
+  }
+
+  iecho->chksum = inet_chksum(iecho, len);
+}
+
+#if PING_USE_SOCKETS
+
+/* Ping using the socket ip */
+static err_t
+ping_send(int s, const ip_addr_t *addr)
+{
+  int err;
+  struct icmp_echo_hdr *iecho;
+  struct sockaddr_storage to;
+  size_t ping_size = sizeof(struct icmp_echo_hdr) + PING_DATA_SIZE;
+  LWIP_ASSERT("ping_size is too big", ping_size <= 0xffff);
+
+#if LWIP_IPV6
+  if(IP_IS_V6(addr) && !ip6_addr_isipv4mappedipv6(ip_2_ip6(addr))) {
+    /* todo: support ICMP6 echo */
+    return ERR_VAL;
+  }
+#endif /* LWIP_IPV6 */
+
+  iecho = (struct icmp_echo_hdr *)mem_malloc((mem_size_t)ping_size);
+  if (!iecho) {
+    return ERR_MEM;
+  }
+
+  ping_prepare_echo(iecho, (u16_t)ping_size);
+  
+#if LWIP_IPV4
+  if(IP_IS_V4(addr)) {
+    struct sockaddr_in *to4 = (struct sockaddr_in*)&to;
+    to4->sin_len    = sizeof(to4);
+    to4->sin_family = AF_INET;
+    inet_addr_from_ip4addr(&to4->sin_addr, ip_2_ip4(addr));
+  }
+#endif /* LWIP_IPV4 */
+
+#if LWIP_IPV6
+  if(IP_IS_V6(addr)) {
+    struct sockaddr_in6 *to6 = (struct sockaddr_in6*)&to;
+    to6->sin6_len    = sizeof(to6);
+    to6->sin6_family = AF_INET6;
+    inet6_addr_from_ip6addr(&to6->sin6_addr, ip_2_ip6(addr));
+  }
+#endif /* LWIP_IPV6 */
+
+  err = lwip_sendto(s, iecho, ping_size, 0, (struct sockaddr*)&to, sizeof(to));
+
+  mem_free(iecho);
+
+  return (err ? ERR_OK : ERR_VAL);
+}
+
+static void
+ping_recv(int s)
+{
+  char buf[64];
+  int len;
+  struct sockaddr_storage from;
+  int fromlen = sizeof(from);
+
+  while((len = lwip_recvfrom(s, buf, sizeof(buf), 0, (struct sockaddr*)&from, (socklen_t*)&fromlen)) > 0) {
+    if (len >= (int)(sizeof(struct ip_hdr)+sizeof(struct icmp_echo_hdr))) {
+      ip_addr_t fromaddr;
+      memset(&fromaddr, 0, sizeof(fromaddr));
+
+#if LWIP_IPV4
+      if(from.ss_family == AF_INET) {
+        struct sockaddr_in *from4 = (struct sockaddr_in*)&from;
+        inet_addr_to_ip4addr(ip_2_ip4(&fromaddr), &from4->sin_addr);
+        IP_SET_TYPE_VAL(fromaddr, IPADDR_TYPE_V4);
+      }
+#endif /* LWIP_IPV4 */
+
+#if LWIP_IPV6
+      if(from.ss_family == AF_INET6) {
+        struct sockaddr_in6 *from6 = (struct sockaddr_in6*)&from;
+        inet6_addr_to_ip6addr(ip_2_ip6(&fromaddr), &from6->sin6_addr);
+        IP_SET_TYPE_VAL(fromaddr, IPADDR_TYPE_V6);
+      }
+#endif /* LWIP_IPV6 */
+      
+      LWIP_DEBUGF( PING_DEBUG, ("ping: recv "));
+      ip_addr_debug_print_val(PING_DEBUG, fromaddr);
+      LWIP_DEBUGF( PING_DEBUG, (" %"U32_F" ms\n", (sys_now() - ping_time)));
+
+      /* todo: support ICMP6 echo */
+#if LWIP_IPV4
+      if (IP_IS_V4_VAL(fromaddr)) {
+        struct ip_hdr *iphdr;
+        struct icmp_echo_hdr *iecho;
+
+        iphdr = (struct ip_hdr *)buf;
+        iecho = (struct icmp_echo_hdr *)(buf + (IPH_HL(iphdr) * 4));
+        if ((iecho->id == PING_ID) && (iecho->seqno == lwip_htons(ping_seq_num))) {
+          /* do some ping result processing */
+          PING_RESULT((ICMPH_TYPE(iecho) == ICMP_ER));
+#ifdef USE_PINGSEND
+          syslog_2(LOG_NOTICE, "ping: ok [%08x] %dus", fromaddr.u_addr.ip4.addr, (sys_now() - ping_time));
+#endif
+          return;
+        } else {
+#ifdef USE_PINGSEND
+          syslog_0(LOG_NOTICE, "ping: drop");
+#else
+          LWIP_DEBUGF( PING_DEBUG, ("ping: drop\n"));
+#endif
+        }
+      }
+#endif /* LWIP_IPV4 */
+    }
+    fromlen = sizeof(from);
+  }
+#ifdef USE_PINGSEND
+  syslog_1(LOG_NOTICE, "ping: drop (%d)", len);
+#endif
+
+  if (len == 0) {
+    LWIP_DEBUGF( PING_DEBUG, ("ping: recv - %"U32_F" ms - timeout\n", (sys_now()-ping_time)));
+  }
+
+  /* do some ping result processing */
+  PING_RESULT(0);
+}
+
+static void
+ping_thread(void *arg)
+{
+  int s;
+  int ret;
+#ifdef USE_PINGSEND
+  int count = 0;
+#endif
+
+#if LWIP_SO_SNDRCVTIMEO_NONSTANDARD
+  int timeout = PING_RCV_TIMEO;
+#else
+  struct timeval timeout;
+  timeout.tv_sec = PING_RCV_TIMEO/1000;
+  timeout.tv_usec = (PING_RCV_TIMEO%1000)*1000;
+#endif
+  LWIP_UNUSED_ARG(arg);
+
+#if LWIP_IPV6
+  if(IP_IS_V4(ping_target) || ip6_addr_isipv4mappedipv6(ip_2_ip6(ping_target))) {
+    s = lwip_socket(AF_INET, SOCK_RAW, IP_PROTO_ICMP);
+  } else {
+    s = lwip_socket(AF_INET6, SOCK_RAW, IP6_NEXTH_ICMP6);
+  }
+#else
+  s = lwip_socket(AF_INET,  SOCK_RAW, IP_PROTO_ICMP);
+#endif
+  if (s < 0) {
+    return;
+  }
+
+  ret = lwip_setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(timeout));
+  LWIP_ASSERT("setting receive timeout failed", ret == 0);
+  LWIP_UNUSED_ARG(ret);
+
+  while (1) {
+#ifdef USE_PINGSEND
+    while(ping_target->u_addr.ip4.addr == 0){
+      dly_tsk(500);
+    }
+#endif
+    if (ping_send(s, ping_target) == ERR_OK) {
+      LWIP_DEBUGF( PING_DEBUG, ("ping: send "));
+      ip_addr_debug_print(PING_DEBUG, ping_target);
+      LWIP_DEBUGF( PING_DEBUG, ("\n"));
+
+      ping_time = sys_now();
+      ping_recv(s);
+    } else {
+      LWIP_DEBUGF( PING_DEBUG, ("ping: send "));
+      ip_addr_debug_print(PING_DEBUG, ping_target);
+      LWIP_DEBUGF( PING_DEBUG, (" - error\n"));
+    }
+    sys_msleep(PING_DELAY);
+#ifdef USE_PINGSEND
+    if(++count > 3){
+      ((ip_addr_t*)ping_target)->u_addr.ip4.addr = 0;
+      count = 0;
+    }
+#endif
+  }
+}
+
+#ifdef USE_PINGSEND
+void
+set_pingaddr(uint32_t paddr)
+{
+  ((ip_addr_t*)ping_target)->u_addr.ip4.addr = paddr;
+}
+#endif
+
+#else /* PING_USE_SOCKETS */
+
+/* Ping using the raw ip */
+static u8_t
+ping_recv(void *arg, struct raw_pcb *pcb, struct pbuf *p, const ip_addr_t *addr)
+{
+  struct icmp_echo_hdr *iecho;
+  LWIP_UNUSED_ARG(arg);
+  LWIP_UNUSED_ARG(pcb);
+  LWIP_UNUSED_ARG(addr);
+  LWIP_ASSERT("p != NULL", p != NULL);
+
+  if ((p->tot_len >= (PBUF_IP_HLEN + sizeof(struct icmp_echo_hdr))) &&
+      pbuf_remove_header(p, PBUF_IP_HLEN) == 0) {
+    iecho = (struct icmp_echo_hdr *)p->payload;
+
+    if ((iecho->id == PING_ID) && (iecho->seqno == lwip_htons(ping_seq_num))) {
+      LWIP_DEBUGF( PING_DEBUG, ("ping: recv "));
+      ip_addr_debug_print(PING_DEBUG, addr);
+      LWIP_DEBUGF( PING_DEBUG, (" %"U32_F" ms\n", (sys_now()-ping_time)));
+
+      /* do some ping result processing */
+      PING_RESULT(1);
+      pbuf_free(p);
+      return 1; /* eat the packet */
+    }
+    /* not eaten, restore original packet */
+    pbuf_add_header(p, PBUF_IP_HLEN);
+  }
+
+  return 0; /* don't eat the packet */
+}
+
+static void
+ping_send(struct raw_pcb *raw, const ip_addr_t *addr)
+{
+  struct pbuf *p;
+  struct icmp_echo_hdr *iecho;
+  size_t ping_size = sizeof(struct icmp_echo_hdr) + PING_DATA_SIZE;
+
+  LWIP_DEBUGF( PING_DEBUG, ("ping: send "));
+  ip_addr_debug_print(PING_DEBUG, addr);
+  LWIP_DEBUGF( PING_DEBUG, ("\n"));
+  LWIP_ASSERT("ping_size <= 0xffff", ping_size <= 0xffff);
+
+  p = pbuf_alloc(PBUF_IP, (u16_t)ping_size, PBUF_RAM);
+  if (!p) {
+    return;
+  }
+  if ((p->len == p->tot_len) && (p->next == NULL)) {
+    iecho = (struct icmp_echo_hdr *)p->payload;
+
+    ping_prepare_echo(iecho, (u16_t)ping_size);
+
+    raw_sendto(raw, p, addr);
+#if defined(LWIP_DEBUG) || defined(USE_PINGSEND)
+    ping_time = sys_now();
+#endif /* LWIP_DEBUG */
+  }
+  pbuf_free(p);
+}
+
+static void
+ping_timeout(void *arg)
+{
+  struct raw_pcb *pcb = (struct raw_pcb*)arg;
+
+  LWIP_ASSERT("ping_timeout: no pcb given!", pcb != NULL);
+
+  ping_send(ping_pcb, ping_target);
+
+  sys_timeout(PING_DELAY, ping_timeout, pcb);
+}
+
+static void
+ping_raw_init(void)
+{
+  ping_pcb = raw_new(IP_PROTO_ICMP);
+  LWIP_ASSERT("ping_pcb != NULL", ping_pcb != NULL);
+
+  raw_recv(ping_pcb, ping_recv, NULL);
+  raw_bind(ping_pcb, IP_ADDR_ANY);
+  sys_timeout(PING_DELAY, ping_timeout, ping_pcb);
+}
+
+void
+ping_send_now(void)
+{
+  LWIP_ASSERT("ping_pcb != NULL", ping_pcb != NULL);
+  ping_send(ping_pcb, ping_target);
+}
+
+#endif /* PING_USE_SOCKETS */
+
+void
+ping_init(const ip_addr_t* ping_addr)
+{
+  ping_target = ping_addr;
+
+#if PING_USE_SOCKETS
+  sys_thread_new("ping_thread", ping_thread, NULL, DEFAULT_THREAD_STACKSIZE, DEFAULT_THREAD_PRIO);
+#else /* PING_USE_SOCKETS */
+  ping_raw_init();
+#endif /* PING_USE_SOCKETS */
+}
+
+#endif /* LWIP_RAW */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/ping/ping.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/ping/ping.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/ping/ping.h	(revision 457)
@@ -0,0 +1,19 @@
+#ifndef LWIP_PING_H
+#define LWIP_PING_H
+
+#include "lwip/ip_addr.h"
+
+/**
+ * PING_USE_SOCKETS: Set to 1 to use sockets, otherwise the raw api is used
+ */
+#ifndef PING_USE_SOCKETS
+#define PING_USE_SOCKETS    LWIP_SOCKET
+#endif
+
+void ping_init(const ip_addr_t* ping_addr);
+
+#if !PING_USE_SOCKETS
+void ping_send_now(void);
+#endif /* !PING_USE_SOCKETS */
+
+#endif /* LWIP_PING_H */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/rtp/rtp.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/rtp/rtp.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/rtp/rtp.c	(revision 457)
@@ -0,0 +1,308 @@
+/**
+ * @file
+ * RTP client/server module
+ *
+ */
+
+/*
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission. 
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ * 
+ */
+
+#include "lwip/opt.h"
+
+#if LWIP_SOCKET && LWIP_IGMP /* don't build if not configured for use in lwipopts.h */
+
+#include "lwip/sys.h"
+#include "lwip/sockets.h"
+
+#include "rtp.h"
+
+#include "rtpdata.h"
+
+#include <string.h>
+
+/** This is an example of a "RTP" client/server based on a MPEG4 bitstream (with socket API).
+ */
+
+/**
+ * RTP_DEBUG: Enable debugging for RTP.
+ */
+#ifndef RTP_DEBUG
+#define RTP_DEBUG                   LWIP_DBG_ON
+#endif
+
+/** RTP stream port */
+#ifndef RTP_STREAM_PORT
+#define RTP_STREAM_PORT             4000
+#endif
+
+/** RTP stream multicast address as IPv4 address in "u32_t" format */
+#ifndef RTP_STREAM_ADDRESS
+#define RTP_STREAM_ADDRESS          inet_addr("232.0.0.0")
+#endif
+
+/** RTP send delay - in milliseconds */
+#ifndef RTP_SEND_DELAY
+#define RTP_SEND_DELAY              40
+#endif
+
+/** RTP receive timeout - in milliseconds */
+#ifndef RTP_RECV_TIMEOUT
+#define RTP_RECV_TIMEOUT            2000
+#endif
+
+/** RTP stats display period - in received packets */
+#ifndef RTP_RECV_STATS
+#define RTP_RECV_STATS              50
+#endif
+
+/** RTP macro to let the application process the data */
+#ifndef RTP_RECV_PROCESSING
+#define RTP_RECV_PROCESSING(p,s)
+#endif
+
+/** RTP packet/payload size */
+#define RTP_PACKET_SIZE             1500
+#define RTP_PAYLOAD_SIZE            1024
+
+/** RTP header constants */
+#define RTP_VERSION                 0x80
+#define RTP_TIMESTAMP_INCREMENT     3600
+#define RTP_SSRC                    0
+#define RTP_PAYLOADTYPE             96
+#define RTP_MARKER_MASK             0x80
+
+/** RTP message header */
+#ifdef PACK_STRUCT_USE_INCLUDES
+#  include "arch/bpstruct.h"
+#endif
+PACK_STRUCT_BEGIN
+struct rtp_hdr {
+  PACK_STRUCT_FLD_8(u8_t  version);
+  PACK_STRUCT_FLD_8(u8_t  payloadtype);
+  PACK_STRUCT_FIELD(u16_t seqNum);
+  PACK_STRUCT_FIELD(u32_t timestamp);
+  PACK_STRUCT_FIELD(u32_t ssrc);
+} PACK_STRUCT_STRUCT;
+PACK_STRUCT_END
+#ifdef PACK_STRUCT_USE_INCLUDES
+#  include "arch/epstruct.h"
+#endif
+
+/** RTP packets */
+static u8_t rtp_send_packet[RTP_PACKET_SIZE];
+static u8_t rtp_recv_packet[RTP_PACKET_SIZE];
+
+/**
+ * RTP send packets
+ */
+static void
+rtp_send_packets( int sock, struct sockaddr_in* to)
+{
+  struct rtp_hdr* rtphdr;
+  u8_t*           rtp_payload;
+  size_t          rtp_payload_size;
+  size_t          rtp_data_index;
+
+  /* prepare RTP packet */
+  rtphdr = (struct rtp_hdr*)rtp_send_packet;
+  rtphdr->version     = RTP_VERSION;
+  rtphdr->payloadtype = 0;
+  rtphdr->ssrc        = PP_HTONL(RTP_SSRC);
+  rtphdr->timestamp   = lwip_htonl(lwip_ntohl(rtphdr->timestamp) + RTP_TIMESTAMP_INCREMENT);
+
+  /* send RTP stream packets */
+  rtp_data_index = 0;
+  do {
+    rtp_payload      = rtp_send_packet+sizeof(struct rtp_hdr);
+    rtp_payload_size = LWIP_MIN(RTP_PAYLOAD_SIZE, sizeof(rtp_data) - rtp_data_index);
+
+    MEMCPY(rtp_payload, rtp_data + rtp_data_index, rtp_payload_size);
+
+    /* set MARKER bit in RTP header on the last packet of an image */
+    if ((rtp_data_index + rtp_payload_size) >= sizeof(rtp_data)) {
+      rtphdr->payloadtype = RTP_PAYLOADTYPE | RTP_MARKER_MASK;
+    } else {
+      rtphdr->payloadtype = RTP_PAYLOADTYPE;
+    }
+
+    /* send RTP stream packet */
+    if (lwip_sendto(sock, rtp_send_packet, sizeof(struct rtp_hdr) + rtp_payload_size,
+        0, (struct sockaddr *)to, sizeof(struct sockaddr)) >= 0) {
+      rtphdr->seqNum  = lwip_htons((u16_t)(lwip_ntohs(rtphdr->seqNum) + 1));
+      rtp_data_index += rtp_payload_size;
+    } else {
+      LWIP_DEBUGF(RTP_DEBUG, ("rtp_sender: not sendto==%i\n", errno));
+    }
+  }while (rtp_data_index < sizeof(rtp_data));
+}
+
+/**
+ * RTP send thread
+ */
+static void
+rtp_send_thread(void *arg)
+{
+  int                sock;
+  struct sockaddr_in local;
+  struct sockaddr_in to;
+  u32_t              rtp_stream_address;
+
+  LWIP_UNUSED_ARG(arg);
+
+  /* initialize RTP stream address */
+  rtp_stream_address = RTP_STREAM_ADDRESS;
+
+  /* if we got a valid RTP stream address... */
+  if (rtp_stream_address != 0) {
+    /* create new socket */
+    sock = lwip_socket(AF_INET, SOCK_DGRAM, 0);
+    if (sock >= 0) {
+      /* prepare local address */
+      memset(&local, 0, sizeof(local));
+      local.sin_family      = AF_INET;
+      local.sin_port        = PP_HTONS(INADDR_ANY);
+      local.sin_addr.s_addr = PP_HTONL(INADDR_ANY);
+
+      /* bind to local address */
+      if (lwip_bind(sock, (struct sockaddr *)&local, sizeof(local)) == 0) {
+        /* prepare RTP stream address */
+        memset(&to, 0, sizeof(to));
+        to.sin_family      = AF_INET;
+        to.sin_port        = PP_HTONS(RTP_STREAM_PORT);
+        to.sin_addr.s_addr = rtp_stream_address;
+
+        /* send RTP packets */
+        memset(rtp_send_packet, 0, sizeof(rtp_send_packet));
+        while (1) {
+          rtp_send_packets( sock, &to);
+          sys_msleep(RTP_SEND_DELAY);
+        }
+      }
+
+      /* close the socket */
+      lwip_close(sock);
+    }
+  }
+}
+
+/**
+ * RTP recv thread
+ */
+static void
+rtp_recv_thread(void *arg)
+{
+  int                sock;
+  struct sockaddr_in local;
+  struct sockaddr_in from;
+  int                fromlen;
+  struct ip_mreq     ipmreq;
+  struct rtp_hdr*    rtphdr;
+  u32_t              rtp_stream_address;
+  int                timeout;
+  int                result;
+  int                recvrtppackets  = 0;
+  int                lostrtppackets  = 0;
+  u16_t              lastrtpseq = 0;
+
+  LWIP_UNUSED_ARG(arg);
+
+  /* initialize RTP stream address */
+  rtp_stream_address = RTP_STREAM_ADDRESS;
+
+  /* if we got a valid RTP stream address... */
+  if (rtp_stream_address != 0) {
+    /* create new socket */
+    sock = lwip_socket(AF_INET, SOCK_DGRAM, 0);
+    if (sock >= 0) {
+      /* prepare local address */
+      memset(&local, 0, sizeof(local));
+      local.sin_family      = AF_INET;
+      local.sin_port        = PP_HTONS(RTP_STREAM_PORT);
+      local.sin_addr.s_addr = PP_HTONL(INADDR_ANY);
+
+      /* bind to local address */
+      if (lwip_bind(sock, (struct sockaddr *)&local, sizeof(local)) == 0) {
+        /* set recv timeout */
+        timeout = RTP_RECV_TIMEOUT;
+        result = lwip_setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, (char *)&timeout, sizeof(timeout));
+        if (result) {
+          LWIP_DEBUGF(RTP_DEBUG, ("rtp_recv_thread: setsockopt(SO_RCVTIMEO) failed: errno=%d\n", errno));
+        }
+
+        /* prepare multicast "ip_mreq" struct */
+        ipmreq.imr_multiaddr.s_addr = rtp_stream_address;
+        ipmreq.imr_interface.s_addr = PP_HTONL(INADDR_ANY);
+
+        /* join multicast group */
+        if (lwip_setsockopt(sock, IPPROTO_IP, IP_ADD_MEMBERSHIP, &ipmreq, sizeof(ipmreq)) == 0) {
+          /* receive RTP packets */
+          while(1) {
+            fromlen = sizeof(from);
+            result  = lwip_recvfrom(sock, rtp_recv_packet, sizeof(rtp_recv_packet), 0,
+              (struct sockaddr *)&from, (socklen_t *)&fromlen);
+            if ((result > 0) && ((size_t)result >= sizeof(struct rtp_hdr))) {
+              size_t recved = (size_t)result;
+              rtphdr = (struct rtp_hdr *)rtp_recv_packet;
+              recvrtppackets++;
+              if ((lastrtpseq == 0) || ((lastrtpseq + 1) == lwip_ntohs(rtphdr->seqNum))) {
+                RTP_RECV_PROCESSING((rtp_recv_packet + sizeof(rtp_hdr)), (recved-sizeof(rtp_hdr)));
+                LWIP_UNUSED_ARG(recved); /* just in case... */
+              } else {
+                lostrtppackets++;
+              }
+              lastrtpseq = lwip_ntohs(rtphdr->seqNum);
+              if ((recvrtppackets % RTP_RECV_STATS) == 0) {
+                LWIP_DEBUGF(RTP_DEBUG, ("rtp_recv_thread: recv %6i packet(s) / lost %4i packet(s) (%.4f%%)...\n", recvrtppackets, lostrtppackets, (lostrtppackets*100.0)/recvrtppackets));
+              }
+            } else {
+              LWIP_DEBUGF(RTP_DEBUG, ("rtp_recv_thread: recv timeout...\n"));
+            }
+          }
+
+          /* leave multicast group */
+          /* TODO: this code is never reached
+          result = lwip_setsockopt(sock, IPPROTO_IP, IP_DROP_MEMBERSHIP, &ipmreq, sizeof(ipmreq));
+          if (result) {
+            LWIP_DEBUGF(RTP_DEBUG, ("rtp_recv_thread: setsockopt(IP_DROP_MEMBERSHIP) failed: errno=%d\n", errno));
+          }*/
+        }
+      }
+
+      /* close the socket */
+      lwip_close(sock);
+    }
+  }
+}
+
+void
+rtp_init(void)
+{
+  sys_thread_new("rtp_send_thread", rtp_send_thread, NULL, DEFAULT_THREAD_STACKSIZE, DEFAULT_THREAD_PRIO);
+  sys_thread_new("rtp_recv_thread", rtp_recv_thread, NULL, DEFAULT_THREAD_STACKSIZE, DEFAULT_THREAD_PRIO);
+}
+
+#endif /* LWIP_SOCKET && LWIP_IGMP */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/rtp/rtp.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/rtp/rtp.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/rtp/rtp.h	(revision 457)
@@ -0,0 +1,8 @@
+#ifndef LWIP_RTP_H
+#define LWIP_RTP_H
+
+#if LWIP_SOCKET && LWIP_IGMP
+void rtp_init(void);
+#endif /* LWIP_SOCKET && LWIP_IGMP */
+
+#endif /* LWIP_RTP_H */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/rtp/rtpdata.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/rtp/rtpdata.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/rtp/rtpdata.h	(revision 457)
@@ -0,0 +1,2040 @@
+const unsigned char rtp_data[] = {
+  0x00, 0x00, 0x01, 0xb0, 0xf5, 0x00, 0x00, 0x01, 
+  0xb5, 0x09, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 
+  0x01, 0x20, 0x00, 0x86, 0x84, 0x00, 0x67, 0x0c, 
+  0x2c, 0x10, 0x90, 0x51, 0x8f, 0x00, 0x00, 0x01, 
+  0xb2, 0x44, 0x69, 0x76, 0x58, 0x35, 0x30, 0x33, 
+  0x62, 0x31, 0x33, 0x39, 0x33, 0x70, 0x00, 0x00, 
+  0x01, 0xb2, 0x58, 0x76, 0x69, 0x44, 0x30, 0x30, 
+  0x33, 0x39, 0x00, 0x00, 0x01, 0xb6, 0x18, 0x60, 
+  0xab, 0x94, 0x03, 0xc0, 0xca, 0xc0, 0x3e, 0xd0, 
+  0x78, 0x4f, 0xf9, 0x44, 0x91, 0xe9, 0xfa, 0xc9, 
+  0xfe, 0xa1, 0xa4, 0xc1, 0x66, 0x03, 0x2e, 0x39, 
+  0x0c, 0x7e, 0x0e, 0xaa, 0x02, 0x92, 0xf8, 0xd5, 
+  0xec, 0xe2, 0x35, 0xb9, 0x35, 0x0c, 0xb3, 0x82, 
+  0xa6, 0xad, 0xd0, 0xd1, 0xca, 0xb8, 0xe8, 0x10, 
+  0x55, 0x78, 0x03, 0xc0, 0x38, 0x15, 0xba, 0xce, 
+  0xe2, 0xea, 0x00, 0xc3, 0x60, 0xb1, 0x70, 0xf4, 
+  0x14, 0x6c, 0x35, 0x4d, 0xe8, 0x5a, 0x1e, 0x58, 
+  0xdf, 0x03, 0x01, 0xfd, 0x2a, 0x45, 0x54, 0xca, 
+  0x0f, 0x05, 0x00, 0xbd, 0xd0, 0xcc, 0xb4, 0x90, 
+  0x4c, 0x24, 0x6b, 0x20, 0x30, 0x95, 0xf1, 0x2f, 
+  0xb4, 0xa7, 0x83, 0xdc, 0xce, 0x03, 0x05, 0x02, 
+  0x1a, 0x5d, 0x1a, 0x2c, 0xbf, 0x51, 0x28, 0x8b, 
+  0xd7, 0x6b, 0xdd, 0xf9, 0x44, 0xbb, 0x0e, 0x91, 
+  0x64, 0xb9, 0xa6, 0x33, 0xd3, 0x6e, 0x34, 0xa4, 
+  0xac, 0xac, 0x53, 0x0d, 0x79, 0xbe, 0xae, 0x5b, 
+  0x47, 0x2e, 0xde, 0x62, 0xa1, 0x53, 0xcd, 0x7d, 
+  0xfe, 0x66, 0xa1, 0x2b, 0x9c, 0xe1, 0xca, 0xbc, 
+  0xea, 0x84, 0x1c, 0x68, 0xff, 0xbb, 0x28, 0xa1, 
+  0x26, 0x18, 0x99, 0xb1, 0x4f, 0x68, 0x80, 0x28, 
+  0x0e, 0x20, 0xc3, 0xbf, 0x0f, 0x80, 0xf8, 0x90, 
+  0x3b, 0x1f, 0x16, 0xe4, 0xb0, 0x6f, 0x44, 0x16, 
+  0x38, 0xb8, 0xc3, 0x81, 0x22, 0xfa, 0xe3, 0x09, 
+  0xf6, 0x61, 0x6d, 0xef, 0x67, 0x56, 0x3b, 0x57, 
+  0xb5, 0x23, 0x03, 0x1f, 0x6d, 0x0d, 0xb9, 0x08, 
+  0xc6, 0x43, 0xba, 0xd1, 0x40, 0x5a, 0xe8, 0xca, 
+  0x9e, 0x17, 0x1f, 0x6d, 0x5d, 0x16, 0x98, 0xab, 
+  0xe6, 0x99, 0xf6, 0x37, 0xc6, 0x1b, 0xdc, 0xb9, 
+  0xb3, 0xfe, 0x9a, 0x4b, 0x1e, 0xec, 0xf9, 0x5f, 
+  0xb8, 0xc7, 0xfc, 0xbe, 0x6c, 0xd5, 0xf3, 0x9b, 
+  0x17, 0x8b, 0x89, 0x82, 0xff, 0x30, 0x19, 0x20, 
+  0x30, 0xe6, 0x29, 0x96, 0x75, 0x75, 0xeb, 0x00, 
+  0x3f, 0xa1, 0x20, 0x5b, 0x06, 0x11, 0x98, 0x1f, 
+  0xb2, 0xad, 0x3a, 0x59, 0xe6, 0x7d, 0x38, 0xa4, 
+  0xb1, 0x4f, 0xfe, 0xdf, 0x3a, 0x4b, 0xdb, 0x69, 
+  0xc3, 0x93, 0xcc, 0xdf, 0x5e, 0xf7, 0x2a, 0x38, 
+  0x2a, 0x89, 0x84, 0x80, 0x6c, 0x12, 0x44, 0x95, 
+  0x78, 0xd8, 0x7e, 0x3f, 0x4e, 0xcf, 0x3f, 0x39, 
+  0xba, 0x9f, 0xfa, 0x8f, 0x2f, 0x62, 0xfa, 0xf0, 
+  0xb6, 0x20, 0xa7, 0x06, 0x02, 0x3f, 0x28, 0x96, 
+  0x80, 0xf0, 0x99, 0x8e, 0x82, 0x15, 0x11, 0x87, 
+  0x35, 0xa4, 0xfd, 0x53, 0xcb, 0xcd, 0x68, 0x38, 
+  0xe8, 0xdb, 0x8d, 0xc2, 0x71, 0xbc, 0x65, 0x3e, 
+  0xac, 0x5b, 0x0d, 0xae, 0xc0, 0x3c, 0x77, 0xfe, 
+  0xe8, 0xde, 0x3c, 0xbd, 0xdb, 0xb3, 0x39, 0x09, 
+  0x56, 0x0a, 0xa2, 0xfe, 0x40, 0xd7, 0x6f, 0x56, 
+  0x07, 0x02, 0xec, 0xd6, 0xed, 0x06, 0x5e, 0x2f, 
+  0xb6, 0xce, 0xf1, 0x4f, 0x16, 0x88, 0x04, 0x41, 
+  0x79, 0x0e, 0x98, 0xbe, 0x54, 0x75, 0x1a, 0xd6, 
+  0x50, 0xcf, 0x82, 0x6a, 0xf7, 0xaf, 0x7f, 0xfb, 
+  0x6d, 0x88, 0x97, 0x24, 0x40, 0x68, 0xa0, 0x57, 
+  0x79, 0x57, 0xe9, 0x6b, 0xaa, 0xe5, 0xe4, 0x2b, 
+  0xaa, 0x14, 0x64, 0x90, 0x6c, 0x50, 0x4a, 0xe3, 
+  0x97, 0x43, 0xf6, 0x81, 0x90, 0xa9, 0xa6, 0xba, 
+  0xb1, 0x21, 0x12, 0x5f, 0xe0, 0xdf, 0x88, 0x86, 
+  0x03, 0x30, 0x94, 0xb2, 0x6d, 0xd2, 0xdc, 0x45, 
+  0x14, 0x54, 0x1d, 0xe8, 0x38, 0x8d, 0xbe, 0x8a, 
+  0xaf, 0x20, 0xa2, 0x3e, 0xa2, 0x5c, 0xc6, 0xae, 
+  0xe6, 0xc4, 0x48, 0xec, 0xea, 0xc7, 0x4e, 0x17, 
+  0xb2, 0x91, 0x52, 0xb4, 0xe9, 0x8b, 0x15, 0xfb, 
+  0x99, 0x7c, 0xda, 0xb8, 0xad, 0x57, 0x31, 0x5b, 
+  0x5b, 0x67, 0xaa, 0x1e, 0x93, 0x76, 0xa5, 0x25, 
+  0xd9, 0x0d, 0x70, 0xd8, 0xb9, 0x11, 0x34, 0xfd, 
+  0xaf, 0x0e, 0x0d, 0x42, 0x57, 0x97, 0x26, 0x06, 
+  0xdf, 0x29, 0x7e, 0x79, 0x72, 0x22, 0x36, 0xa5, 
+  0x9f, 0x6a, 0x16, 0x24, 0x6f, 0x10, 0x56, 0xec, 
+  0x5b, 0x46, 0x50, 0x94, 0x88, 0xc4, 0xfa, 0x9e, 
+  0xd8, 0x5b, 0xb7, 0x50, 0x72, 0x62, 0x25, 0xaa, 
+  0x39, 0x84, 0x69, 0xaa, 0xfc, 0xbf, 0x9b, 0x45, 
+  0xf7, 0xc5, 0x41, 0x97, 0x41, 0xc7, 0xac, 0x7f, 
+  0x68, 0x92, 0xab, 0x64, 0xaa, 0x46, 0x32, 0x84, 
+  0x77, 0x1b, 0xfc, 0xbc, 0x5a, 0x42, 0x28, 0xfa, 
+  0x3e, 0x55, 0xf4, 0xe9, 0x44, 0xac, 0xc5, 0x4a, 
+  0x6c, 0x93, 0xde, 0x03, 0x6d, 0xdc, 0xb8, 0x5b, 
+  0xb7, 0x83, 0x7e, 0xc2, 0xaa, 0x33, 0x70, 0x34, 
+  0x41, 0x46, 0x25, 0xa5, 0x6f, 0xdb, 0x96, 0x0f, 
+  0xd3, 0xab, 0xd4, 0x17, 0x65, 0x96, 0x0c, 0x1e, 
+  0x39, 0x4c, 0x9d, 0x90, 0x3f, 0x5b, 0x8d, 0xaa, 
+  0xce, 0xac, 0xa6, 0x50, 0xf0, 0x66, 0xb2, 0x30, 
+  0xce, 0x42, 0x61, 0xaa, 0xb6, 0x7e, 0xca, 0xbf, 
+  0xfd, 0xbf, 0xef, 0x51, 0xed, 0xdf, 0x95, 0x0b, 
+  0xa7, 0x34, 0x24, 0x13, 0x62, 0x44, 0x81, 0xdf, 
+  0x3a, 0x8e, 0x95, 0x91, 0x67, 0xd7, 0x57, 0x54, 
+  0x92, 0x1d, 0x79, 0xa3, 0x2a, 0xf3, 0x0c, 0x7a, 
+  0x12, 0xa8, 0x33, 0xf9, 0x05, 0x02, 0x7b, 0xef, 
+  0x12, 0x18, 0xab, 0x8b, 0x40, 0x38, 0x7e, 0x0c, 
+  0x1f, 0x04, 0x30, 0x62, 0xa8, 0xd5, 0xd9, 0x78, 
+  0xdd, 0x1c, 0xb4, 0x57, 0xc1, 0x83, 0xc4, 0x41, 
+  0x08, 0x72, 0x5c, 0xc2, 0xb6, 0xd3, 0xd4, 0x85, 
+  0x4a, 0x7e, 0x58, 0xc3, 0x19, 0xfa, 0xdd, 0x51, 
+  0x03, 0x85, 0x1d, 0xe9, 0x10, 0x5e, 0x8c, 0x8f, 
+  0x41, 0x03, 0xe9, 0xbc, 0xa8, 0xba, 0xeb, 0x73, 
+  0x7d, 0x85, 0x69, 0xc7, 0x3b, 0xd9, 0x49, 0x0b, 
+  0x39, 0x03, 0x12, 0x11, 0x8b, 0x72, 0x97, 0x62, 
+  0x5f, 0xfe, 0x59, 0x4d, 0xc0, 0x3a, 0xdf, 0xcb, 
+  0x3e, 0x80, 0x39, 0xd5, 0x7a, 0xb1, 0x45, 0x86, 
+  0x06, 0xf6, 0xb6, 0xda, 0x98, 0xa1, 0x41, 0xae, 
+  0x12, 0xd3, 0xd1, 0x71, 0x5a, 0xa5, 0x40, 0xc0, 
+  0x8a, 0x3f, 0x4e, 0xac, 0x78, 0x93, 0x55, 0x31, 
+  0xfc, 0xcf, 0x67, 0x93, 0x52, 0xc4, 0x53, 0x0d, 
+  0xdf, 0x49, 0xd7, 0x83, 0x00, 0x18, 0x4b, 0xcd, 
+  0x65, 0xaf, 0xb5, 0xd5, 0x6c, 0xc4, 0x14, 0xb7, 
+  0xdb, 0x9d, 0x06, 0x17, 0xca, 0xe1, 0x60, 0x07, 
+  0x6d, 0x57, 0xd0, 0xfb, 0x1a, 0xf5, 0xb2, 0x56, 
+  0xca, 0xea, 0x21, 0x77, 0x41, 0xc0, 0x46, 0xc8, 
+  0x85, 0xe3, 0x15, 0x6a, 0xdb, 0x80, 0x47, 0x6d, 
+  0x05, 0x44, 0x06, 0x04, 0xf6, 0x92, 0x24, 0xdb, 
+  0x9b, 0x6f, 0xfa, 0x8d, 0x72, 0x2d, 0x75, 0x7e, 
+  0x33, 0x9c, 0xe7, 0x06, 0xbb, 0x3d, 0xa4, 0xb7, 
+  0xee, 0x31, 0x46, 0x4b, 0x91, 0xe2, 0xb0, 0x54, 
+  0x5c, 0x78, 0x9e, 0x45, 0x90, 0xe4, 0x76, 0xbe, 
+  0xe1, 0x4c, 0xae, 0x89, 0x20, 0x6e, 0x77, 0x76, 
+  0x94, 0x63, 0x93, 0xaa, 0x62, 0x0e, 0x28, 0x7b, 
+  0xec, 0xc9, 0xc5, 0x25, 0x64, 0x5a, 0xe9, 0xcc, 
+  0x91, 0x1a, 0x9c, 0xcf, 0x91, 0x47, 0x32, 0x12, 
+  0x9f, 0x8b, 0x36, 0x07, 0x33, 0x4c, 0x45, 0x06, 
+  0x19, 0xdb, 0x61, 0xc5, 0x68, 0xb7, 0xab, 0x2e, 
+  0x7b, 0x5c, 0xa6, 0x4c, 0x6e, 0x08, 0x5f, 0xc1, 
+  0xc4, 0x99, 0x64, 0xef, 0xd8, 0x05, 0x5c, 0x0f, 
+  0x76, 0xdd, 0xab, 0x4f, 0x8e, 0x29, 0x54, 0x59, 
+  0x1d, 0x30, 0x33, 0xfb, 0x3b, 0x43, 0x96, 0xf4, 
+  0x52, 0x47, 0x2c, 0x66, 0x81, 0xca, 0xa6, 0x73, 
+  0x51, 0xc1, 0xc0, 0x32, 0x98, 0xa3, 0x41, 0x1c, 
+  0x40, 0x5e, 0x22, 0x05, 0xa0, 0xdb, 0xb0, 0x88, 
+  0xdf, 0xee, 0x2f, 0x3a, 0xbb, 0xe2, 0xef, 0x79, 
+  0x09, 0xa6, 0x0c, 0x0f, 0x4c, 0xdc, 0x81, 0xcc, 
+  0x3d, 0x36, 0x52, 0x4e, 0xbd, 0x44, 0x0d, 0x0d, 
+  0x84, 0xf5, 0x74, 0x33, 0x14, 0x1a, 0x87, 0xcb, 
+  0xcc, 0x93, 0xa3, 0x69, 0x21, 0x20, 0x26, 0x23, 
+  0xd9, 0x95, 0x0c, 0x22, 0x2b, 0x2f, 0x0d, 0xf4, 
+  0x34, 0x74, 0x53, 0x16, 0x5d, 0x60, 0x96, 0x3e, 
+  0x53, 0xd3, 0xcc, 0xc5, 0x72, 0x49, 0xc2, 0x4d, 
+  0xea, 0x02, 0x21, 0x7f, 0xbd, 0x80, 0x1d, 0xf0, 
+  0x87, 0xe6, 0xdb, 0xcc, 0x92, 0xdd, 0xfe, 0x78, 
+  0x4a, 0xd2, 0xf9, 0x77, 0x24, 0xed, 0x5a, 0x31, 
+  0x6c, 0xec, 0x71, 0x5d, 0x85, 0xad, 0xb3, 0xb9, 
+  0x6f, 0x11, 0x2d, 0xfa, 0x42, 0x2b, 0xcb, 0x01, 
+  0x08, 0x18, 0x11, 0x56, 0xcb, 0x01, 0xe1, 0xe0, 
+  0x1f, 0x06, 0xe8, 0x3c, 0x6c, 0x01, 0xaa, 0x49, 
+  0x86, 0xbf, 0x63, 0x79, 0x03, 0xbe, 0xd8, 0x47, 
+  0x4f, 0x26, 0x0d, 0x11, 0xe3, 0x76, 0x27, 0x0e, 
+  0xf1, 0x79, 0x44, 0x46, 0xc3, 0x3b, 0x4f, 0x05, 
+  0x20, 0x40, 0xff, 0x59, 0x6f, 0xaa, 0x17, 0xf4, 
+  0x40, 0xa1, 0x15, 0x0a, 0x4c, 0x0f, 0x94, 0x81, 
+  0xb8, 0x0c, 0x8e, 0x8d, 0xc3, 0x80, 0xc1, 0xeb, 
+  0x02, 0x16, 0xf4, 0xbe, 0xca, 0xa4, 0x3a, 0xa8, 
+  0xec, 0x0c, 0x89, 0xc4, 0x59, 0xe4, 0x8b, 0x9a, 
+  0x40, 0x7e, 0xae, 0xea, 0xa0, 0xeb, 0x6a, 0x99, 
+  0x95, 0x73, 0x79, 0x62, 0x18, 0xb8, 0x38, 0x64, 
+  0x73, 0x97, 0xb7, 0x58, 0xd1, 0x2d, 0x8d, 0xbe, 
+  0xf3, 0x13, 0x2f, 0x7c, 0xc0, 0x1d, 0x61, 0x4e, 
+  0x4c, 0xe6, 0x95, 0xce, 0x97, 0xf9, 0xbc, 0xf4, 
+  0x5a, 0xce, 0xa1, 0x3b, 0x39, 0xef, 0xc5, 0x39, 
+  0x4b, 0x72, 0x1b, 0xa5, 0x41, 0x92, 0x27, 0xda, 
+  0x72, 0xc2, 0xbb, 0xd4, 0x8d, 0x34, 0x97, 0x9d, 
+  0xb7, 0xde, 0xe7, 0xb0, 0x64, 0x8a, 0x0a, 0x0c, 
+  0x0e, 0x60, 0x30, 0x62, 0xb8, 0xbb, 0x9f, 0x96, 
+  0x05, 0x31, 0x33, 0xfa, 0x3c, 0x1f, 0xf4, 0x3d, 
+  0x04, 0x3c, 0x5c, 0x1e, 0x1b, 0xfe, 0xf1, 0xfe, 
+  0xa1, 0xb1, 0x03, 0x54, 0x99, 0x50, 0x61, 0xc5, 
+  0xbc, 0x2d, 0x00, 0xfe, 0xaf, 0x01, 0xe1, 0x7f, 
+  0xeb, 0xd4, 0x77, 0x0d, 0xb4, 0x0a, 0x9c, 0x18, 
+  0x92, 0x3d, 0x5a, 0xbf, 0xc0, 0x98, 0x66, 0xcc, 
+  0x06, 0x09, 0x6a, 0x50, 0xe9, 0x18, 0x32, 0x00, 
+  0x78, 0xc8, 0x06, 0x68, 0xac, 0x8b, 0x3f, 0x38, 
+  0xbf, 0x4a, 0x33, 0x30, 0x1c, 0x4f, 0xae, 0x16, 
+  0x44, 0x98, 0x24, 0x08, 0xc9, 0x07, 0xed, 0x62, 
+  0xbb, 0x89, 0x15, 0xca, 0x0f, 0x09, 0x00, 0x7a, 
+  0x51, 0xc5, 0x93, 0x54, 0x45, 0xfb, 0x73, 0xdf, 
+  0xe9, 0x42, 0x07, 0x90, 0x10, 0xcb, 0xdb, 0x2b, 
+  0x47, 0x20, 0x2b, 0xaa, 0xf4, 0x5c, 0xa4, 0x28, 
+  0x38, 0x9d, 0x5a, 0x44, 0x22, 0x0d, 0x54, 0x81, 
+  0x1d, 0x07, 0x0a, 0x37, 0xee, 0x49, 0x8b, 0xfb, 
+  0x3a, 0x8d, 0x7e, 0x83, 0x84, 0xfd, 0xf7, 0x98, 
+  0xad, 0xac, 0xa7, 0x46, 0x07, 0x62, 0x72, 0x56, 
+  0x1c, 0x03, 0x05, 0x4d, 0x70, 0xd8, 0x60, 0x62, 
+  0x8a, 0x8d, 0xe8, 0x23, 0x03, 0x04, 0x6d, 0x60, 
+  0xdc, 0x2a, 0x27, 0x92, 0x08, 0x8f, 0x65, 0xed, 
+  0xbd, 0xca, 0xa5, 0x1d, 0x80, 0x8d, 0x11, 0x03, 
+  0x83, 0xc7, 0x05, 0x04, 0x85, 0xcd, 0x2f, 0x3a, 
+  0xd4, 0x83, 0x02, 0x91, 0x91, 0xc5, 0x76, 0xb5, 
+  0x79, 0xcb, 0xfb, 0x29, 0x22, 0x90, 0x1e, 0x09, 
+  0x9f, 0x2c, 0x07, 0x77, 0xa0, 0x38, 0xf8, 0x63, 
+  0xf5, 0x2a, 0xd4, 0xc5, 0x0f, 0xd7, 0x43, 0x38, 
+  0xb5, 0xe8, 0x38, 0x94, 0x29, 0x71, 0x68, 0xb4, 
+  0x99, 0x0a, 0x4d, 0xf6, 0x94, 0x9d, 0x8e, 0x96, 
+  0x58, 0x88, 0x63, 0x46, 0x02, 0x9d, 0x64, 0x83, 
+  0x70, 0x72, 0x32, 0x6f, 0x90, 0x1d, 0x0e, 0xd5, 
+  0xf5, 0xd9, 0x0d, 0xe8, 0x0f, 0xa3, 0x20, 0x5f, 
+  0x26, 0x59, 0xc3, 0x50, 0x33, 0x04, 0xc9, 0x0c, 
+  0xc8, 0xa2, 0xce, 0x12, 0x43, 0x44, 0xa3, 0x55, 
+  0xe5, 0x07, 0x05, 0x1a, 0x69, 0xa8, 0xc4, 0x39, 
+  0x92, 0xa2, 0x44, 0x0e, 0x08, 0xe0, 0xa2, 0x4a, 
+  0x28, 0xd7, 0x80, 0xe1, 0x37, 0x96, 0x0c, 0x49, 
+  0x28, 0x0f, 0x3c, 0xc8, 0xe2, 0xc1, 0x5d, 0x4f, 
+  0xd4, 0x48, 0xa2, 0x21, 0x59, 0xf1, 0x0d, 0x9f, 
+  0xaa, 0xc6, 0x77, 0xc8, 0xe5, 0xce, 0x0d, 0xca, 
+  0x02, 0x87, 0x4a, 0x49, 0x01, 0xc8, 0x48, 0xc8, 
+  0xf3, 0x1b, 0x2f, 0xdf, 0x6c, 0xcb, 0x88, 0x66, 
+  0xf1, 0x40, 0xbd, 0x6a, 0x34, 0xfc, 0xb0, 0x89, 
+  0xde, 0x11, 0xc5, 0xc6, 0xa2, 0x44, 0xc6, 0xdb, 
+  0x67, 0xff, 0xd1, 0x79, 0x01, 0xa4, 0x9e, 0xf0, 
+  0x1f, 0x10, 0x57, 0x2b, 0x24, 0xc5, 0x1c, 0x09, 
+  0x45, 0x7e, 0xcc, 0x55, 0xe5, 0x0d, 0x64, 0xe2, 
+  0x2c, 0xe4, 0xea, 0xe4, 0x81, 0x31, 0xfd, 0x61, 
+  0x38, 0x8f, 0xba, 0x1f, 0xb4, 0xd9, 0x6c, 0xa8, 
+  0xac, 0xe4, 0xe8, 0xca, 0x9e, 0xee, 0xa9, 0x51, 
+  0xd7, 0xe9, 0x9d, 0xcc, 0xb0, 0x7c, 0x24, 0xc5, 
+  0x13, 0xa0, 0x89, 0x78, 0x0b, 0x15, 0xd1, 0x09, 
+  0xe4, 0xbf, 0x34, 0x6f, 0xcf, 0x0b, 0x82, 0x51, 
+  0xb3, 0x70, 0x7d, 0x83, 0xe1, 0x24, 0x0d, 0x33, 
+  0xad, 0xda, 0x5d, 0xfe, 0xe7, 0x38, 0x54, 0x52, 
+  0x0e, 0x3d, 0xd5, 0xec, 0xef, 0x0b, 0x05, 0xe1, 
+  0x16, 0xa9, 0x45, 0xec, 0x5f, 0x81, 0xb9, 0xc8, 
+  0xff, 0x36, 0x0e, 0x0e, 0x01, 0x81, 0x31, 0xae, 
+  0x4b, 0x35, 0xd8, 0x18, 0x17, 0x8c, 0x33, 0x7a, 
+  0xa2, 0xee, 0x06, 0x5b, 0xd8, 0x0b, 0x07, 0xb0, 
+  0x52, 0xbe, 0xf6, 0xf4, 0x38, 0xec, 0x35, 0x6e, 
+  0x45, 0xc1, 0x5e, 0x51, 0xd3, 0x67, 0x93, 0x6d, 
+  0xaf, 0xd0, 0xe0, 0x2a, 0xea, 0x6a, 0x1e, 0x03, 
+  0x0c, 0x38, 0xa4, 0x38, 0xea, 0x34, 0x41, 0x99, 
+  0xcb, 0xe0, 0xcd, 0xda, 0xf2, 0xee, 0x86, 0x28, 
+  0x83, 0x38, 0x0b, 0x13, 0xd1, 0x73, 0x1e, 0x4f, 
+  0xb5, 0x18, 0x7d, 0xef, 0xed, 0x09, 0xdf, 0xf7, 
+  0x4a, 0x91, 0xdb, 0x41, 0x84, 0xf7, 0x07, 0x14, 
+  0x15, 0x3b, 0x01, 0xc5, 0x28, 0x41, 0x78, 0x9f, 
+  0xf6, 0x92, 0xce, 0x06, 0xe0, 0xb9, 0x9d, 0xa0, 
+  0xee, 0xf0, 0x25, 0xa9, 0xd4, 0xe0, 0x71, 0xb4, 
+  0x66, 0x0c, 0x11, 0x47, 0x01, 0x89, 0x34, 0x62, 
+  0x11, 0x60, 0x27, 0xa0, 0xfb, 0x1f, 0xfe, 0xd1, 
+  0x50, 0x6e, 0x0e, 0x23, 0xc3, 0xd8, 0x0e, 0xe8, 
+  0x53, 0xa7, 0x94, 0x03, 0x12, 0x41, 0x9a, 0x90, 
+  0x97, 0xce, 0x87, 0x0d, 0x42, 0x9d, 0x07, 0xce, 
+  0xff, 0xef, 0x4e, 0x07, 0x1a, 0x31, 0x08, 0x92, 
+  0x98, 0x0c, 0x49, 0x46, 0x74, 0x22, 0x2a, 0xf1, 
+  0x01, 0x51, 0x48, 0x26, 0xe9, 0xf5, 0xcd, 0xb0, 
+  0x0c, 0x2e, 0xa1, 0x3d, 0x29, 0x05, 0x4f, 0xa0, 
+  0x12, 0x06, 0x08, 0x9c, 0x94, 0x08, 0x60, 0xce, 
+  0xd0, 0x96, 0x81, 0x81, 0x18, 0x62, 0x03, 0xcc, 
+  0xba, 0x15, 0xd6, 0x91, 0x11, 0x14, 0x7e, 0xb2, 
+  0x7e, 0xd4, 0x56, 0x74, 0x37, 0xdc, 0x82, 0xfb, 
+  0x21, 0xa1, 0x93, 0x91, 0x60, 0x3d, 0xcb, 0x28, 
+  0x4b, 0x52, 0xe9, 0x26, 0x4a, 0x0c, 0x32, 0xca, 
+  0x31, 0xab, 0x10, 0x19, 0x6e, 0x76, 0x50, 0x1e, 
+  0x7c, 0x89, 0x2f, 0x42, 0x4a, 0x46, 0xf8, 0xb1, 
+  0x5e, 0xdc, 0xbe, 0x81, 0x4a, 0x0c, 0x4e, 0x6a, 
+  0x31, 0x70, 0xd4, 0x17, 0x62, 0x30, 0xf8, 0xbb, 
+  0xaa, 0xba, 0x06, 0x98, 0xf4, 0x05, 0x40, 0x7c, 
+  0x8e, 0x81, 0x22, 0xc7, 0x8b, 0xf2, 0x67, 0x49, 
+  0x64, 0x58, 0x1c, 0xb8, 0xa0, 0x6d, 0xb9, 0xea, 
+  0x5b, 0x11, 0x47, 0x18, 0xe7, 0xd0, 0xbc, 0xce, 
+  0xf3, 0x9d, 0x19, 0x10, 0x92, 0x95, 0x45, 0x47, 
+  0x78, 0x87, 0x81, 0x32, 0x6b, 0xc0, 0xe5, 0x7a, 
+  0x79, 0x25, 0x37, 0x0d, 0x05, 0x06, 0x73, 0x39, 
+  0x50, 0x9f, 0x8f, 0x5d, 0x09, 0x24, 0x34, 0x32, 
+  0x18, 0x04, 0x62, 0x9c, 0xe8, 0x1e, 0x06, 0x52, 
+  0x88, 0x1e, 0x26, 0x01, 0x30, 0x36, 0x81, 0x60, 
+  0x63, 0x41, 0x6a, 0x77, 0xa8, 0x42, 0xd4, 0xba, 
+  0x1f, 0x0e, 0x79, 0x06, 0x2d, 0x16, 0x83, 0x00, 
+  0xe3, 0xe6, 0xcb, 0xba, 0x82, 0x4a, 0x27, 0xd7, 
+  0x5e, 0xdc, 0x58, 0x44, 0x19, 0x28, 0x0c, 0xc7, 
+  0x2f, 0x57, 0xb2, 0x83, 0x83, 0x40, 0xcc, 0x1c, 
+  0xb8, 0x99, 0x41, 0xb9, 0xb0, 0xc8, 0x1f, 0x36, 
+  0x00, 0x75, 0x14, 0xa9, 0x25, 0x34, 0x87, 0x83, 
+  0x05, 0x13, 0x16, 0x7d, 0x91, 0x40, 0x3b, 0x9c, 
+  0xe8, 0x38, 0x57, 0x17, 0xd2, 0x03, 0xc0, 0xff, 
+  0x4e, 0x0c, 0x1f, 0x16, 0x96, 0xc0, 0xe3, 0x8d, 
+  0x62, 0x75, 0xb8, 0x04, 0xae, 0x03, 0x80, 0x88, 
+  0xa1, 0x56, 0x31, 0x57, 0x66, 0x2d, 0x8a, 0xef, 
+  0x11, 0x6f, 0xca, 0xe9, 0x47, 0x79, 0xd0, 0x9d, 
+  0x0c, 0xb0, 0x18, 0x47, 0x06, 0x03, 0x57, 0x2c, 
+  0xda, 0x8f, 0x4a, 0x80, 0xd9, 0xa0, 0x62, 0x80, 
+  0x60, 0x4d, 0x95, 0x18, 0x8c, 0x18, 0x45, 0xcb, 
+  0x17, 0xad, 0x34, 0xa3, 0xd2, 0xa1, 0xb5, 0xd3, 
+  0x32, 0xd9, 0xdb, 0xd1, 0x82, 0x98, 0x18, 0x83, 
+  0xa9, 0xcd, 0xb5, 0x20, 0x77, 0x03, 0x5c, 0x5f, 
+  0xa6, 0xdb, 0x48, 0x12, 0xd7, 0x46, 0xc8, 0xd1, 
+  0x78, 0x1c, 0x1d, 0x17, 0x04, 0x91, 0xe8, 0xbc, 
+  0x2a, 0xa0, 0x53, 0x83, 0x11, 0x29, 0xff, 0x18, 
+  0xfe, 0x8d, 0x98, 0x6e, 0xad, 0x11, 0x65, 0xa0, 
+  0xc8, 0x3c, 0x48, 0x48, 0x13, 0x55, 0x28, 0xf5, 
+  0x61, 0x9d, 0xe0, 0x38, 0x5e, 0x12, 0xc0, 0x70, 
+  0x44, 0xbf, 0x6f, 0x25, 0x9d, 0x2b, 0xcf, 0xb6, 
+  0x79, 0x3d, 0xcf, 0x45, 0x32, 0xa8, 0x19, 0x67, 
+  0x3a, 0x14, 0x43, 0x6d, 0x7d, 0xa1, 0x04, 0xb7, 
+  0x3e, 0xd3, 0x75, 0x45, 0x2a, 0x6a, 0x6d, 0xb2, 
+  0x12, 0x87, 0x90, 0xa0, 0x6b, 0xbf, 0x1a, 0x5b, 
+  0xb7, 0x14, 0xd0, 0x26, 0x88, 0x5e, 0xb8, 0x4d, 
+  0x70, 0x19, 0x65, 0x36, 0xdd, 0x9c, 0x40, 0x7a, 
+  0xbf, 0x21, 0xc8, 0x38, 0x38, 0x01, 0xca, 0x1e, 
+  0xc5, 0xee, 0xb3, 0x40, 0xc0, 0x9a, 0xd6, 0x24, 
+  0xa7, 0xb4, 0x6b, 0x06, 0x18, 0xfc, 0x1c, 0x11, 
+  0xaf, 0x6d, 0xcc, 0xbd, 0x5e, 0xc8, 0x8e, 0x07, 
+  0xbc, 0xe0, 0x52, 0x8f, 0x9a, 0xb1, 0x74, 0x40, 
+  0xe4, 0x63, 0x20, 0x99, 0x4f, 0xa8, 0xbc, 0x0e, 
+  0xf2, 0x86, 0x80, 0xea, 0x09, 0x8a, 0xec, 0xdd, 
+  0xe7, 0x39, 0x49, 0x6e, 0xc4, 0x5c, 0x5d, 0x0d, 
+  0x45, 0xd1, 0x7b, 0x8b, 0xd5, 0xaf, 0x43, 0x17, 
+  0xe9, 0x49, 0xac, 0x6d, 0x10, 0xa6, 0x4e, 0x5e, 
+  0xa8, 0xc8, 0x20, 0xca, 0x54, 0x8e, 0xa1, 0x15, 
+  0xb5, 0x0d, 0xa0, 0x66, 0x70, 0x93, 0x6f, 0x01, 
+  0xc4, 0x2b, 0xc1, 0x46, 0xbd, 0x74, 0x96, 0x05, 
+  0x75, 0x50, 0xc0, 0xc3, 0x8b, 0x22, 0x25, 0x07, 
+  0x1d, 0xf6, 0x70, 0x92, 0x2d, 0x17, 0x09, 0xcb, 
+  0xef, 0xbd, 0x88, 0xd6, 0x46, 0x7b, 0xbd, 0xa0, 
+  0xe7, 0xe9, 0xc7, 0x09, 0x01, 0xc0, 0xb1, 0x29, 
+  0x3a, 0xc1, 0xdd, 0x05, 0xd2, 0x6a, 0x60, 0x73, 
+  0x06, 0x54, 0x26, 0x84, 0x0b, 0x22, 0x42, 0x7e, 
+  0x0d, 0x62, 0xfe, 0xc5, 0xb8, 0x30, 0x3a, 0xa2, 
+  0x5f, 0x5b, 0xee, 0x6c, 0xc2, 0x50, 0x7a, 0x18, 
+  0x00, 0xdf, 0x86, 0x41, 0x97, 0x16, 0x3d, 0xd9, 
+  0xcb, 0x09, 0x46, 0x40, 0xb0, 0x04, 0xe5, 0xa0, 
+  0xbb, 0xa9, 0x8d, 0x84, 0xa6, 0xd4, 0xb7, 0x53, 
+  0xb2, 0xdf, 0x33, 0x16, 0x41, 0x38, 0x2f, 0x3c, 
+  0xa8, 0x21, 0xef, 0x3e, 0xd6, 0xcd, 0x8b, 0xf9, 
+  0x1f, 0x03, 0x7a, 0x29, 0x18, 0x84, 0x26, 0x7f, 
+  0xe1, 0xdf, 0x98, 0x1c, 0x36, 0x58, 0xdc, 0x51, 
+  0xde, 0x2d, 0x35, 0x1f, 0x69, 0xa7, 0x0a, 0x82, 
+  0x08, 0xe9, 0x59, 0x7f, 0x2b, 0x4a, 0x39, 0x25, 
+  0x96, 0x5f, 0xf1, 0x08, 0xa6, 0x5b, 0x4b, 0x67, 
+  0x51, 0x12, 0xf0, 0xf2, 0xae, 0x68, 0xbb, 0x72, 
+  0xef, 0x0a, 0xb6, 0x02, 0xbd, 0x14, 0x42, 0x37, 
+  0x1b, 0x80, 0xe2, 0x3a, 0xb7, 0xb4, 0x1c, 0x0a, 
+  0x9b, 0xa0, 0xea, 0x11, 0x21, 0x4b, 0x07, 0xc9, 
+  0x93, 0xb7, 0x7b, 0xd1, 0x13, 0x8d, 0x62, 0xfd, 
+  0x28, 0xbd, 0x44, 0x0e, 0x0f, 0x4e, 0x49, 0xb4, 
+  0x43, 0x11, 0xc0, 0x38, 0x38, 0x08, 0xd2, 0xd9, 
+  0x2e, 0x2c, 0x03, 0x9f, 0xa7, 0xd6, 0x37, 0x46, 
+  0x01, 0x1f, 0x58, 0x56, 0xc0, 0x9c, 0x07, 0x0c, 
+  0x9d, 0xba, 0x0a, 0x9a, 0x15, 0xd4, 0x63, 0x6a, 
+  0x13, 0x69, 0xe0, 0x6f, 0x4c, 0xd0, 0x53, 0xc0, 
+  0xf6, 0x6f, 0x3c, 0xb7, 0x7d, 0xcb, 0x3b, 0x40, 
+  0x8e, 0xfa, 0x04, 0x48, 0x16, 0x35, 0x8b, 0x7d, 
+  0xbc, 0x81, 0xaa, 0xb2, 0xe8, 0xbf, 0x7a, 0x0c, 
+  0x1c, 0xfe, 0x86, 0x26, 0x8e, 0x86, 0x25, 0x83, 
+  0x9d, 0x07, 0x11, 0xcf, 0xb8, 0x5b, 0x88, 0xe9, 
+  0x5e, 0x12, 0x21, 0x13, 0xed, 0xb1, 0xfa, 0x0c, 
+  0x87, 0xf0, 0xa3, 0x96, 0x05, 0x75, 0x33, 0x7a, 
+  0x3d, 0x1f, 0x09, 0x49, 0x58, 0x56, 0x9d, 0x95, 
+  0x5e, 0x52, 0x9b, 0x30, 0x3d, 0x64, 0x3d, 0xe4, 
+  0xde, 0xcb, 0x3c, 0x59, 0x56, 0x0d, 0xd4, 0x94, 
+  0x43, 0xf6, 0x24, 0xb7, 0x19, 0x1f, 0xa5, 0x6f, 
+  0xd7, 0xc5, 0x9f, 0x56, 0xde, 0xe7, 0x38, 0x8a, 
+  0xed, 0x3c, 0x15, 0xc1, 0x9b, 0x6b, 0x55, 0xab, 
+  0x11, 0xa4, 0xce, 0xef, 0xd2, 0x4c, 0x88, 0x00, 
+  0xad, 0x15, 0x18, 0xff, 0xb5, 0xad, 0xdf, 0x6f, 
+  0xa4, 0xdc, 0xbc, 0xab, 0x84, 0x65, 0x30, 0xab, 
+  0x09, 0x6b, 0xf4, 0xff, 0x43, 0x78, 0x30, 0x08, 
+  0xa7, 0xa0, 0xa9, 0xa2, 0xf0, 0x8b, 0x72, 0x82, 
+  0xa0, 0x5c, 0x12, 0xb0, 0x27, 0xe1, 0x84, 0x09, 
+  0x27, 0x6e, 0x2d, 0x62, 0xc6, 0xd1, 0x85, 0x1a, 
+  0x72, 0xb1, 0xbf, 0x83, 0xcc, 0x7f, 0xfa, 0x13, 
+  0x54, 0xe0, 0x71, 0xfa, 0x0e, 0x23, 0x7d, 0x06, 
+  0x25, 0x18, 0x4a, 0x11, 0x69, 0x43, 0x76, 0xe8, 
+  0xc8, 0x18, 0x23, 0x96, 0x15, 0x2c, 0x7f, 0x4e, 
+  0x8b, 0x01, 0x83, 0x6d, 0x18, 0x83, 0x04, 0x5b, 
+  0x80, 0xa8, 0xc1, 0x9d, 0x01, 0xfa, 0xe2, 0xa3, 
+  0x8d, 0x4f, 0xe9, 0x63, 0x0d, 0xfe, 0xe7, 0x7b, 
+  0xcc, 0x5e, 0x86, 0xf5, 0x1b, 0xae, 0x0e, 0x93, 
+  0xa0, 0x1f, 0x36, 0x33, 0xe8, 0x0e, 0x74, 0xcf, 
+  0xa0, 0x43, 0x11, 0x82, 0x6d, 0x5a, 0xa8, 0xa6, 
+  0x1a, 0xcb, 0xa1, 0xb4, 0x99, 0x6a, 0x08, 0x8f, 
+  0x68, 0x30, 0x2c, 0x5f, 0x51, 0xfd, 0x10, 0x1a, 
+  0xff, 0xd6, 0xec, 0xe7, 0x7a, 0xc7, 0xaf, 0x49, 
+  0x16, 0xbb, 0x51, 0x50, 0xad, 0xbf, 0x8b, 0x76, 
+  0x86, 0x20, 0x9b, 0x11, 0x81, 0xc5, 0x1b, 0x6f, 
+  0x06, 0xdf, 0xfc, 0x28, 0xda, 0xe9, 0x03, 0x6a, 
+  0xc1, 0x83, 0x96, 0xc1, 0x86, 0x3a, 0x12, 0xd2, 
+  0x8a, 0x8c, 0x83, 0x85, 0xd0, 0xa0, 0xf3, 0x2e, 
+  0x86, 0xee, 0xe1, 0xb7, 0xa1, 0x6d, 0x16, 0x2e, 
+  0xf4, 0x46, 0xc1, 0x45, 0x99, 0xd2, 0x6d, 0x72, 
+  0xd2, 0xe6, 0x52, 0x84, 0x07, 0x84, 0xf3, 0xc0, 
+  0xe0, 0x0e, 0xa2, 0x1f, 0x6c, 0xce, 0xf6, 0x83, 
+  0xc1, 0xc0, 0x3f, 0x47, 0xb9, 0x68, 0xc8, 0x11, 
+  0x04, 0x14, 0x40, 0xc3, 0x43, 0x13, 0xa0, 0xf3, 
+  0xff, 0xff, 0xbe, 0xfe, 0x58, 0xd4, 0x51, 0x7b, 
+  0x0a, 0x01, 0x62, 0x48, 0xe1, 0x9b, 0x6b, 0x65, 
+  0x8b, 0x54, 0x41, 0xc8, 0x9d, 0x57, 0x57, 0x64, 
+  0xf7, 0x51, 0x83, 0x0c, 0x47, 0x25, 0x01, 0xc8, 
+  0xad, 0x4a, 0x58, 0x4b, 0x05, 0xe0, 0xc0, 0x3d, 
+  0x10, 0x4e, 0xb5, 0x85, 0xb8, 0xbc, 0xb0, 0x1e, 
+  0x2a, 0x00, 0xb0, 0x58, 0xbd, 0x5e, 0xca, 0x4a, 
+  0x0c, 0x2e, 0x19, 0x82, 0xe5, 0x3e, 0x8b, 0xa0, 
+  0xe0, 0xc8, 0x8a, 0xae, 0xe7, 0xbe, 0x55, 0xbc, 
+  0x45, 0x4a, 0x60, 0x60, 0x09, 0xcb, 0x89, 0x4c, 
+  0x32, 0x08, 0x6d, 0x09, 0x0d, 0xb4, 0xd2, 0x54, 
+  0xf8, 0xa8, 0xab, 0xca, 0x6f, 0xc4, 0xbf, 0x00, 
+  0xe6, 0xb6, 0x8c, 0x4f, 0xc6, 0x16, 0xf7, 0x67, 
+  0x1a, 0x9b, 0x2a, 0x1c, 0xe0, 0x0e, 0x44, 0x80, 
+  0x80, 0x34, 0xb2, 0x9d, 0x59, 0x58, 0x17, 0xd1, 
+  0x87, 0x81, 0x60, 0x2c, 0xf8, 0x0a, 0xad, 0x69, 
+  0x49, 0x5d, 0x40, 0x43, 0x1b, 0x4e, 0x83, 0x7c, 
+  0x48, 0x88, 0x92, 0x09, 0x3f, 0x05, 0x78, 0xf6, 
+  0xc0, 0x60, 0xc9, 0xea, 0xd0, 0x66, 0xd3, 0x20, 
+  0x08, 0x5b, 0xa0, 0xaf, 0x1d, 0xb3, 0xa1, 0x35, 
+  0x2e, 0x1c, 0xc8, 0x33, 0x09, 0x1a, 0x34, 0x6d, 
+  0x83, 0x06, 0x61, 0x21, 0x5a, 0x99, 0x57, 0xd1, 
+  0xcc, 0xa2, 0x96, 0xed, 0x05, 0xc3, 0x61, 0x84, 
+  0x1e, 0x07, 0xfc, 0x3e, 0x55, 0x2d, 0x01, 0xe4, 
+  0x92, 0xc4, 0x56, 0xd6, 0xff, 0xc0, 0xa0, 0x6a, 
+  0x23, 0x89, 0x29, 0xc4, 0x76, 0x43, 0xf6, 0x7c, 
+  0xd6, 0x55, 0x0a, 0x0a, 0xb1, 0x00, 0x13, 0xaf, 
+  0xa2, 0xa0, 0xe4, 0x5c, 0x11, 0xb2, 0xa2, 0x51, 
+  0x80, 0x46, 0x98, 0xc3, 0x1e, 0x1b, 0x35, 0xc2, 
+  0x5c, 0xb5, 0xf4, 0xfb, 0xf2, 0x1c, 0x83, 0x83, 
+  0x80, 0x7c, 0xf8, 0x01, 0xfd, 0x9a, 0x85, 0x49, 
+  0x69, 0xc7, 0xd8, 0x1a, 0xc3, 0x0f, 0xa3, 0x27, 
+  0xb5, 0xa6, 0xc5, 0xdb, 0x3a, 0x15, 0x6e, 0x5e, 
+  0xdb, 0x93, 0x60, 0x8b, 0x28, 0x31, 0x48, 0xc0, 
+  0x35, 0x09, 0x3b, 0x5f, 0x28, 0x18, 0x54, 0x01, 
+  0x80, 0x66, 0x8c, 0x8e, 0x7e, 0xd6, 0xaa, 0x8d, 
+  0xa9, 0x9c, 0xa6, 0xe3, 0x10, 0xb6, 0x8c, 0x16, 
+  0xd0, 0x97, 0x4f, 0x78, 0x15, 0x21, 0x88, 0xb8, 
+  0x85, 0xb9, 0x01, 0xd1, 0x67, 0x69, 0xfd, 0xbe, 
+  0xe4, 0x52, 0xd6, 0xc4, 0x6a, 0x24, 0x07, 0x54, 
+  0x28, 0x08, 0xa6, 0x6f, 0x94, 0x03, 0x22, 0xf8, 
+  0x67, 0x46, 0x20, 0x9a, 0x4c, 0x93, 0x90, 0x1c, 
+  0x09, 0x90, 0x32, 0x46, 0x32, 0x0a, 0x2d, 0xe8, 
+  0x27, 0xc5, 0xdc, 0xf6, 0xc9, 0xde, 0x4e, 0x1a, 
+  0x45, 0x02, 0x5b, 0xab, 0xeb, 0x4a, 0x2f, 0x4d, 
+  0x95, 0x29, 0xe8, 0x0f, 0x04, 0xcc, 0xb8, 0xbc, 
+  0x6b, 0x32, 0x06, 0x08, 0x0d, 0xc0, 0x5f, 0xdb, 
+  0x24, 0x46, 0xb1, 0xbe, 0x85, 0x5a, 0xeb, 0x4a, 
+  0xa0, 0x40, 0x42, 0x48, 0x59, 0x37, 0xbd, 0x18, 
+  0x82, 0x72, 0x63, 0xfd, 0xa5, 0x12, 0x83, 0x90, 
+  0x85, 0x1e, 0xd5, 0x83, 0x35, 0xe0, 0xb9, 0x02, 
+  0xc7, 0xcd, 0x88, 0x23, 0x86, 0xe7, 0xc7, 0x12, 
+  0x4b, 0xcd, 0x1c, 0x59, 0x51, 0x29, 0x0c, 0x3b, 
+  0xc9, 0xd0, 0x4d, 0xf9, 0x6a, 0x33, 0xba, 0xef, 
+  0x2e, 0xe5, 0xd8, 0x69, 0x1a, 0x14, 0x44, 0x29, 
+  0xe6, 0xcb, 0xee, 0x7f, 0xd6, 0x9b, 0x25, 0x0c, 
+  0x51, 0x05, 0x48, 0xe4, 0xf9, 0x6a, 0xfd, 0xc9, 
+  0x9d, 0x8b, 0xd9, 0xd1, 0x3a, 0x14, 0x7d, 0xa9, 
+  0x38, 0x5a, 0x55, 0xd4, 0x57, 0x7f, 0xfb, 0x62, 
+  0x11, 0x80, 0x30, 0x61, 0x1d, 0x6a, 0x00, 0x92, 
+  0x2e, 0x9a, 0x7b, 0x82, 0x4a, 0x75, 0x77, 0x3b, 
+  0x61, 0xb6, 0xbe, 0x36, 0xa1, 0x87, 0x67, 0x46, 
+  0x0f, 0x30, 0xaf, 0x70, 0xbd, 0x8d, 0xc8, 0x31, 
+  0x53, 0x37, 0xc0, 0xc1, 0x8c, 0x15, 0x1d, 0x4d, 
+  0x38, 0xb5, 0x5c, 0x1c, 0x0b, 0xc1, 0x53, 0x17, 
+  0xe0, 0x75, 0xb6, 0x68, 0x19, 0x9d, 0x2b, 0xf4, 
+  0xe2, 0x09, 0x41, 0x30, 0xbe, 0xd0, 0xf7, 0xb2, 
+  0x2c, 0x69, 0xd1, 0x33, 0x83, 0xa6, 0x59, 0x66, 
+  0x17, 0xcb, 0x59, 0x6c, 0x18, 0x0c, 0x27, 0x1b, 
+  0xfe, 0xd4, 0x72, 0xac, 0x75, 0x25, 0x65, 0xca, 
+  0xfa, 0x0c, 0x05, 0xac, 0x29, 0x06, 0x04, 0xe1, 
+  0x78, 0xe8, 0x79, 0x4a, 0xf2, 0xa9, 0xe6, 0xfb, 
+  0xf1, 0x0e, 0x7e, 0xcd, 0x95, 0x6c, 0xed, 0x5a, 
+  0x9a, 0xa6, 0xc5, 0x01, 0x4d, 0x38, 0x36, 0x24, 
+  0x6b, 0xac, 0xe8, 0xf0, 0x77, 0xb9, 0xe9, 0x6f, 
+  0x55, 0x8f, 0x52, 0x48, 0xb2, 0xeb, 0xe6, 0x29, 
+  0xb7, 0xa6, 0xa5, 0x71, 0xbe, 0x57, 0x9e, 0xd0, 
+  0xda, 0xa1, 0xe5, 0x08, 0xaa, 0x65, 0xc1, 0x13, 
+  0xe8, 0x43, 0xef, 0x06, 0xac, 0xf8, 0x1f, 0x37, 
+  0xff, 0xb7, 0x53, 0x7e, 0x65, 0xd9, 0xf4, 0xdf, 
+  0x99, 0xc5, 0x25, 0x9b, 0x9b, 0x5c, 0x71, 0x90, 
+  0x6c, 0x49, 0xbe, 0x55, 0xff, 0x69, 0x70, 0xfa, 
+  0xff, 0xca, 0x7f, 0xe4, 0xe2, 0x4c, 0x42, 0x84, 
+  0x3a, 0x7d, 0xb0, 0x07, 0x07, 0x8c, 0x29, 0x80, 
+  0xc5, 0xa3, 0xc6, 0xee, 0xe1, 0x66, 0xe3, 0x1f, 
+  0xdf, 0xd5, 0x15, 0x08, 0x89, 0x16, 0x3c, 0x30, 
+  0x39, 0xcf, 0xaf, 0x35, 0x10, 0x2a, 0x38, 0x19, 
+  0xbe, 0x26, 0xb8, 0x13, 0x83, 0x00, 0x1c, 0xe4, 
+  0xda, 0xc5, 0x2b, 0xcf, 0xd2, 0xad, 0xc2, 0xa9, 
+  0x37, 0xb7, 0xb5, 0x01, 0x41, 0x0d, 0x40, 0x38, 
+  0x01, 0x9d, 0xe5, 0x12, 0x7f, 0xb4, 0x38, 0x54, 
+  0x5c, 0xdb, 0x7c, 0x02, 0x73, 0x7e, 0x2c, 0x17, 
+  0x2a, 0x1e, 0x09, 0x0a, 0xb3, 0x7c, 0x5d, 0x07, 
+  0xbb, 0xf5, 0xfb, 0xff, 0xa6, 0x9e, 0xef, 0x29, 
+  0xb5, 0x0b, 0x70, 0x6a, 0xa0, 0x6d, 0x01, 0x67, 
+  0xe9, 0x2d, 0x98, 0x72, 0xa6, 0x44, 0x47, 0x12, 
+  0xa2, 0x58, 0x25, 0x2b, 0xdc, 0x67, 0x71, 0xa5, 
+  0x57, 0x0b, 0x15, 0x65, 0xba, 0xa6, 0x07, 0xb3, 
+  0xb6, 0x22, 0x35, 0xde, 0x13, 0x09, 0xda, 0x08, 
+  0x0d, 0xb3, 0xad, 0x83, 0xc1, 0x40, 0x42, 0x3b, 
+  0xb7, 0x22, 0x90, 0xf5, 0xbe, 0x5d, 0xea, 0xcb, 
+  0x01, 0x88, 0xa5, 0x72, 0x60, 0xbe, 0x23, 0x64, 
+  0x6d, 0x57, 0xbb, 0x10, 0x7f, 0x94, 0x41, 0xac, 
+  0x73, 0x84, 0xb1, 0x75, 0xc1, 0x38, 0xeb, 0x25, 
+  0xbe, 0x6e, 0xf4, 0xb9, 0x8f, 0xa9, 0xd5, 0x84, 
+  0x14, 0xad, 0xfe, 0xc3, 0x48, 0x11, 0x52, 0x99, 
+  0x3a, 0x4e, 0x70, 0xe7, 0x65, 0x5a, 0x29, 0x85, 
+  0x2a, 0x02, 0x68, 0x99, 0xaf, 0xaa, 0xfa, 0xad, 
+  0x2c, 0xd1, 0x09, 0x46, 0xc4, 0x0d, 0xfd, 0xba, 
+  0x0c, 0x18, 0x98, 0x6d, 0x97, 0x5a, 0xd3, 0x0d, 
+  0xf9, 0x57, 0xbd, 0x75, 0x4e, 0x7f, 0x3b, 0xd5, 
+  0xf2, 0xa3, 0x9d, 0xde, 0xaf, 0x10, 0x13, 0x97, 
+  0xd5, 0x1c, 0xdb, 0xa3, 0xa2, 0xe9, 0x50, 0x7d, 
+  0x44, 0xdd, 0xe4, 0x0d, 0xea, 0x08, 0x27, 0x33, 
+  0x41, 0xba, 0xd5, 0xda, 0xc4, 0x2c, 0xec, 0xe7, 
+  0x66, 0x35, 0xc9, 0x3b, 0xd9, 0x27, 0x73, 0x83, 
+  0x17, 0x0d, 0x08, 0x3d, 0x35, 0x34, 0xa6, 0x9e, 
+  0xd7, 0xea, 0x84, 0xb2, 0xcf, 0x87, 0x95, 0x94, 
+  0xd5, 0x8b, 0x2e, 0x11, 0x89, 0x02, 0x06, 0x25, 
+  0x6a, 0x46, 0xd5, 0xe5, 0xa5, 0xb9, 0x54, 0x67, 
+  0x22, 0x9d, 0x2b, 0x92, 0xa0, 0x3c, 0x5e, 0xc5, 
+  0x78, 0x38, 0xac, 0xc2, 0xff, 0xe1, 0x57, 0xbc, 
+  0xb2, 0xd5, 0x48, 0xc7, 0x85, 0x10, 0x81, 0x54, 
+  0x89, 0x3d, 0xbb, 0xdc, 0xb8, 0xd8, 0xf5, 0x9c, 
+  0x8c, 0xa7, 0xe9, 0x46, 0x45, 0xd7, 0x40, 0x88, 
+  0x8c, 0xdc, 0x56, 0xdc, 0x46, 0xa3, 0x06, 0xfc, 
+  0xce, 0x91, 0x69, 0x8a, 0x55, 0x02, 0x8b, 0x72, 
+  0xe7, 0xdb, 0x1f, 0xa5, 0x2b, 0x06, 0x40, 0x55, 
+  0x31, 0x45, 0x9d, 0x40, 0xdd, 0x90, 0x54, 0x9a, 
+  0x70, 0x64, 0x89, 0x15, 0xc9, 0xbe, 0x4f, 0xb3, 
+  0x6d, 0xe5, 0x1c, 0xab, 0xc2, 0xc8, 0x30, 0x94, 
+  0xea, 0x5e, 0x54, 0xab, 0x14, 0x7b, 0xfe, 0xce, 
+  0x9b, 0xe6, 0xae, 0x50, 0xa6, 0xe9, 0x18, 0xb6, 
+  0xb1, 0x95, 0x44, 0x53, 0xcf, 0x7b, 0x96, 0x7b, 
+  0x98, 0x59, 0x43, 0x8e, 0x95, 0x0c, 0x21, 0x3b, 
+  0x95, 0xc2, 0xb5, 0xe1, 0x42, 0x80, 0xc0, 0xf6, 
+  0x99, 0xa4, 0xe0, 0x19, 0x83, 0xe1, 0x29, 0x28, 
+  0xf3, 0xd4, 0x72, 0xdb, 0x77, 0xd4, 0x3c, 0xaa, 
+  0x70, 0x3c, 0x45, 0xbd, 0x1b, 0x76, 0xf4, 0x80, 
+  0x30, 0x60, 0x34, 0x12, 0x6f, 0xe2, 0x84, 0x96, 
+  0xaf, 0x36, 0x29, 0xfb, 0x52, 0x73, 0xa8, 0xff, 
+  0x2d, 0xe9, 0xe3, 0x3f, 0xf4, 0xa8, 0xb2, 0xf7, 
+  0x4d, 0x15, 0x45, 0x83, 0x9b, 0x38, 0x33, 0x8b, 
+  0x8a, 0xf0, 0x80, 0xd4, 0x5e, 0x79, 0x7e, 0xf2, 
+  0xd1, 0xb8, 0xbe, 0x2f, 0xb2, 0x94, 0x9e, 0x24, 
+  0x73, 0xfe, 0x02, 0x63, 0x26, 0x79, 0xa4, 0xdd, 
+  0x4a, 0xda, 0x4a, 0xb5, 0xbb, 0x7c, 0x55, 0xdb, 
+  0xee, 0xca, 0x1b, 0x4b, 0xd9, 0xd8, 0x02, 0x0e, 
+  0xfd, 0xaa, 0xd7, 0xee, 0x6c, 0xb3, 0x86, 0xfb, 
+  0x28, 0x56, 0x0c, 0x1a, 0xab, 0xf8, 0x24, 0xb3, 
+  0xf5, 0x51, 0x46, 0xc6, 0x5b, 0xbd, 0x5a, 0xc9, 
+  0x26, 0xd9, 0xb5, 0x75, 0xb9, 0xc3, 0x7c, 0x3c, 
+  0x48, 0x43, 0x08, 0x5a, 0x3f, 0x6f, 0x4b, 0xfb, 
+  0x41, 0x86, 0xc5, 0xad, 0xf1, 0x78, 0xa7, 0x24, 
+  0xce, 0x45, 0xe8, 0xa4, 0x5e, 0x33, 0xcb, 0x3b, 
+  0x39, 0xd4, 0x67, 0x55, 0x72, 0x63, 0xc2, 0xd6, 
+  0x1b, 0x45, 0x29, 0xbb, 0xd8, 0x81, 0x00, 0xcc, 
+  0x63, 0xd3, 0xc5, 0x12, 0x73, 0xfe, 0xf6, 0xde, 
+  0x6e, 0x41, 0x89, 0x5f, 0xaf, 0x65, 0x5a, 0x9b, 
+  0x21, 0x59, 0x5c, 0xc1, 0x0b, 0xc5, 0x7a, 0xbe, 
+  0x28, 0xdf, 0x40, 0xf6, 0x2c, 0x8a, 0xc2, 0xa5, 
+  0x2b, 0x74, 0xf9, 0x3d, 0x63, 0x13, 0xd8, 0x98, 
+  0x71, 0x6f, 0x73, 0xb6, 0x88, 0x0d, 0xb3, 0x66, 
+  0x5a, 0x56, 0x22, 0x77, 0x9b, 0x88, 0x08, 0x64, 
+  0x2d, 0xff, 0x50, 0x42, 0x0d, 0x35, 0x47, 0x1b, 
+  0x93, 0x2d, 0x42, 0x88, 0x50, 0x2f, 0x06, 0xcf, 
+  0x29, 0x4a, 0x3e, 0xa5, 0x5d, 0xc4, 0xea, 0xbb, 
+  0x03, 0xde, 0xf0, 0x73, 0x2f, 0x51, 0xa8, 0x13, 
+  0x11, 0x64, 0x03, 0x14, 0xfb, 0xb3, 0xe1, 0xe2, 
+  0x65, 0x18, 0xcd, 0xd9, 0x51, 0x72, 0xf3, 0x72, 
+  0xd1, 0x12, 0xa3, 0x42, 0x8c, 0x4d, 0x00, 0x79, 
+  0x9f, 0x36, 0x24, 0x8e, 0x95, 0x2a, 0xcc, 0x06, 
+  0x02, 0xea, 0xad, 0x2b, 0xaa, 0x43, 0xcf, 0xe5, 
+  0xd3, 0x4b, 0x2c, 0x4a, 0x34, 0x76, 0xdb, 0x9b, 
+  0x97, 0x80, 0xe1, 0x56, 0xba, 0x6d, 0xe5, 0xf7, 
+  0x40, 0x70, 0x3a, 0x05, 0x91, 0xca, 0x8f, 0x9b, 
+  0xc1, 0x88, 0x2c, 0x0f, 0x0b, 0xb2, 0x50, 0x42, 
+  0x06, 0x2d, 0xbb, 0x98, 0x4b, 0xc6, 0x22, 0x90, 
+  0x78, 0xcf, 0xfd, 0xe6, 0x50, 0x60, 0x9d, 0x16, 
+  0xda, 0xd1, 0xd2, 0x6f, 0xb3, 0xf9, 0x21, 0xab, 
+  0x38, 0xc2, 0x30, 0xd4, 0xb7, 0xea, 0x1d, 0xfa, 
+  0xf6, 0xe7, 0x01, 0xc1, 0xde, 0xc0, 0xb3, 0x4f, 
+  0x03, 0x0f, 0xe7, 0x40, 0x39, 0x3a, 0x3a, 0xbb, 
+  0x08, 0x81, 0x5f, 0x10, 0x10, 0x94, 0x4c, 0x5d, 
+  0x3f, 0x9f, 0xd0, 0x34, 0x9d, 0x3e, 0xad, 0x31, 
+  0x8f, 0x66, 0xf6, 0xf4, 0x45, 0x2a, 0x9b, 0x78, 
+  0xe2, 0x02, 0x3f, 0xbc, 0x3f, 0x2e, 0xfb, 0x01, 
+  0xf8, 0x1a, 0x9b, 0xc0, 0xf6, 0xe5, 0xb5, 0x65, 
+  0xf8, 0xa2, 0xce, 0x3c, 0x23, 0xb4, 0x25, 0x17, 
+  0x2a, 0xb5, 0xa0, 0x60, 0xfd, 0x5f, 0x2f, 0xa5, 
+  0x0f, 0xd5, 0x28, 0x6b, 0xf6, 0xf4, 0x3a, 0xe4, 
+  0xf2, 0x28, 0x8c, 0xd8, 0xac, 0xe4, 0xdf, 0x51, 
+  0x0b, 0x14, 0x6a, 0x32, 0x5e, 0x0b, 0x9d, 0x5f, 
+  0xf8, 0x9d, 0x27, 0xfd, 0x36, 0xfb, 0xfa, 0x59, 
+  0xe0, 0x33, 0xce, 0xf1, 0x63, 0xb6, 0xd9, 0x6f, 
+  0x41, 0xe1, 0x20, 0x15, 0xba, 0x5e, 0x42, 0x57, 
+  0xed, 0x09, 0x1a, 0x59, 0xed, 0x1e, 0x8f, 0x4b, 
+  0xea, 0x56, 0x94, 0x6f, 0x33, 0xba, 0x2f, 0x14, 
+  0x74, 0x9e, 0x08, 0x51, 0x08, 0x8d, 0xbf, 0xf3, 
+  0x7d, 0x57, 0x2a, 0xf1, 0x01, 0xf2, 0x59, 0xd2, 
+  0xd9, 0xce, 0xe4, 0x97, 0xa4, 0xf8, 0x3f, 0x9c, 
+  0x00, 0x6b, 0xa3, 0x1a, 0xfe, 0x82, 0x26, 0xd6, 
+  0x26, 0x67, 0xb6, 0xf2, 0xab, 0xad, 0x7c, 0x3d, 
+  0x9c, 0x06, 0x34, 0xa3, 0x61, 0x55, 0x29, 0x42, 
+  0xe3, 0xac, 0xea, 0x52, 0x4a, 0xc6, 0x1c, 0x32, 
+  0x21, 0xa5, 0x69, 0xbf, 0x7f, 0x1a, 0xc6, 0x04, 
+  0xaa, 0x92, 0x0e, 0x54, 0x79, 0xac, 0xa5, 0xbb, 
+  0xe4, 0x32, 0xc5, 0x2a, 0x38, 0x69, 0x67, 0x91, 
+  0x57, 0xf1, 0xfa, 0xa0, 0xe9, 0xa5, 0x43, 0xea, 
+  0x9e, 0x6c, 0xe4, 0x1b, 0x72, 0xef, 0x1c, 0x5a, 
+  0xac, 0xcc, 0xf7, 0xae, 0x41, 0xcc, 0xa6, 0xcf, 
+  0xaa, 0xe5, 0xd5, 0x77, 0xc1, 0xdc, 0x6e, 0x7f, 
+  0xb9, 0xad, 0x62, 0xe5, 0x56, 0xf0, 0xd3, 0xca, 
+  0x35, 0x1a, 0x55, 0x3f, 0xa0, 0xc1, 0xef, 0x9b, 
+  0x6a, 0x59, 0xba, 0x59, 0x35, 0x6f, 0x72, 0xd3, 
+  0x48, 0x86, 0xa5, 0x41, 0x4e, 0x25, 0xa3, 0x06, 
+  0x0f, 0x55, 0xa6, 0x9b, 0xb3, 0x26, 0x03, 0x8e, 
+  0x2d, 0xe6, 0x75, 0x3b, 0x38, 0xd4, 0xe7, 0xfe, 
+  0xa3, 0xdd, 0xe5, 0xd9, 0x2a, 0x20, 0x71, 0x29, 
+  0x39, 0xec, 0xab, 0xdc, 0xda, 0xa5, 0x47, 0xae, 
+  0x59, 0x05, 0xb5, 0x71, 0x2b, 0x0a, 0x84, 0x25, 
+  0x51, 0x9f, 0xa9, 0x6d, 0x2f, 0x9b, 0x8a, 0x1b, 
+  0x4f, 0xc9, 0xfd, 0xe6, 0x4e, 0x74, 0x3b, 0x5c, 
+  0x8b, 0xf3, 0x6e, 0x4a, 0x18, 0xc0, 0x74, 0x3f, 
+  0x72, 0xee, 0x48, 0xa7, 0x75, 0xb6, 0x7f, 0x6a, 
+  0x2e, 0x49, 0x6a, 0xd3, 0xa1, 0x40, 0xd4, 0x47, 
+  0xd8, 0xce, 0x59, 0x2c, 0x43, 0xc5, 0xe5, 0x5d, 
+  0xfa, 0x66, 0x3f, 0xfa, 0x86, 0xf5, 0x7c, 0x3d, 
+  0x17, 0x32, 0xa2, 0x0f, 0xf1, 0xa5, 0x3d, 0xb4, 
+  0x11, 0xf8, 0x6c, 0x96, 0x22, 0x18, 0xb9, 0xe9, 
+  0x56, 0xee, 0x15, 0x28, 0x44, 0x84, 0x91, 0x11, 
+  0x09, 0xab, 0x75, 0xb6, 0x3d, 0xd9, 0x38, 0xb9, 
+  0x6a, 0x10, 0x1c, 0x35, 0x19, 0xb3, 0x89, 0xd9, 
+  0x95, 0x16, 0xfa, 0x92, 0x2f, 0x45, 0xdc, 0x3f, 
+  0x25, 0x2c, 0xd0, 0x74, 0xd0, 0xc8, 0xf6, 0x9a, 
+  0x31, 0x3f, 0xb8, 0x5a, 0x80, 0xd2, 0xc8, 0x39, 
+  0x10, 0x04, 0xb1, 0x12, 0xf9, 0x19, 0x5a, 0xe6, 
+  0xa0, 0xd1, 0x7d, 0x00, 0xdd, 0xed, 0x2b, 0x49, 
+  0xa0, 0x48, 0x07, 0x3c, 0x69, 0x00, 0x34, 0x43, 
+  0x5e, 0xc6, 0xf1, 0xa4, 0x12, 0x73, 0x06, 0xc8, 
+  0x0e, 0x97, 0x18, 0xdb, 0xd5, 0x82, 0xbd, 0x78, 
+  0xf2, 0x3f, 0x5e, 0xa1, 0x5f, 0x88, 0x88, 0x92, 
+  0xfe, 0x5f, 0x5b, 0xe9, 0xda, 0x04, 0xe5, 0x04, 
+  0xc2, 0x23, 0xf6, 0x95, 0x49, 0x92, 0x40, 0xfd, 
+  0x58, 0x31, 0xbd, 0xc8, 0x83, 0xd2, 0xd4, 0x76, 
+  0x21, 0x0a, 0x82, 0x40, 0xf0, 0x21, 0x26, 0x69, 
+  0x40, 0x19, 0x12, 0xcb, 0x95, 0x37, 0xd1, 0xc6, 
+  0x82, 0xbb, 0x56, 0xab, 0x8d, 0x86, 0xcf, 0xb2, 
+  0x83, 0xba, 0x43, 0x53, 0xa6, 0x95, 0x7e, 0x52, 
+  0xb6, 0x6e, 0xac, 0x8a, 0xa1, 0x29, 0x38, 0x58, 
+  0x77, 0xbe, 0xf2, 0x46, 0x77, 0x65, 0x2c, 0xc8, 
+  0xa6, 0xac, 0xba, 0x88, 0x8e, 0xc3, 0x74, 0x5c, 
+  0x41, 0x70, 0x20, 0x8f, 0xf6, 0x16, 0x87, 0xc3, 
+  0xa4, 0xc6, 0xe1, 0x78, 0x97, 0xef, 0x51, 0x87, 
+  0x17, 0xea, 0xc8, 0xe9, 0xc5, 0x04, 0x31, 0xe9, 
+  0x68, 0x84, 0xde, 0x26, 0x56, 0x3a, 0xf8, 0xfc, 
+  0xb3, 0x8a, 0x12, 0x33, 0xe6, 0x57, 0x43, 0x32, 
+  0x6f, 0xd1, 0x0d, 0x6a, 0x8d, 0x83, 0x7e, 0x70, 
+  0x1c, 0x7a, 0x26, 0xbe, 0x02, 0x94, 0x03, 0x98, 
+  0x6e, 0x6b, 0x0c, 0x0e, 0xdb, 0xdc, 0x44, 0x55, 
+  0x80, 0xc0, 0x3c, 0x26, 0x33, 0xf0, 0x41, 0xd6, 
+  0xdb, 0x97, 0xc3, 0xa5, 0x77, 0xd7, 0x26, 0xf7, 
+  0x6e, 0x79, 0x47, 0x67, 0x78, 0xbe, 0x55, 0xc5, 
+  0x41, 0x9d, 0x5a, 0xb0, 0x65, 0x6a, 0x0a, 0xd2, 
+  0x0f, 0xfd, 0xe0, 0xe7, 0xc3, 0xa5, 0x00, 0xf1, 
+  0x5f, 0xfb, 0xb4, 0xc0, 0x30, 0x4e, 0x3d, 0x6d, 
+  0x94, 0xb6, 0x83, 0x2f, 0xf6, 0xed, 0x06, 0x25, 
+  0xbb, 0xd0, 0x60, 0xaf, 0xea, 0x64, 0x2b, 0x86, 
+  0x9b, 0x68, 0x66, 0x79, 0x91, 0x8f, 0x7c, 0x10, 
+  0xd5, 0x8e, 0x73, 0xaa, 0x8b, 0x95, 0x67, 0x54, 
+  0x52, 0xd1, 0xeb, 0x5d, 0x9e, 0x42, 0x22, 0xf9, 
+  0x73, 0xd0, 0x3d, 0x11, 0xc1, 0x09, 0xa1, 0x15, 
+  0x33, 0x7f, 0x99, 0x54, 0x28, 0xdf, 0xb7, 0xcb, 
+  0x50, 0x8d, 0xff, 0x0f, 0xad, 0xd7, 0xf3, 0x37, 
+  0xed, 0x20, 0xf6, 0x82, 0x3a, 0x80, 0xc8, 0xfe, 
+  0x91, 0x1a, 0x0d, 0xa0, 0xa0, 0xc9, 0x20, 0x2a, 
+  0xa3, 0x76, 0x64, 0x9d, 0x04, 0x4f, 0x5e, 0x83, 
+  0x0c, 0x78, 0xf1, 0x82, 0x70, 0x66, 0x47, 0xd6, 
+  0x71, 0x50, 0x8d, 0x06, 0x31, 0x89, 0xd4, 0x05, 
+  0x4d, 0x4b, 0xde, 0x03, 0x0a, 0x59, 0x46, 0x04, 
+  0x81, 0x2d, 0x38, 0x30, 0xd8, 0x74, 0x3f, 0x64, 
+  0x18, 0xa1, 0x33, 0x3f, 0x83, 0x1c, 0xc7, 0x8f, 
+  0xd6, 0xf8, 0x49, 0x09, 0x7f, 0xfa, 0x19, 0x99, 
+  0xd7, 0x30, 0xd8, 0x41, 0x4a, 0xc2, 0x6e, 0x35, 
+  0x3d, 0xac, 0xfe, 0xd2, 0xa6, 0xa1, 0xbb, 0x33, 
+  0x3c, 0xe3, 0x7c, 0xc0, 0x60, 0x3f, 0x3c, 0xdc, 
+  0x5a, 0x02, 0xa5, 0x26, 0x37, 0x94, 0x11, 0xbb, 
+  0xf6, 0xb4, 0x91, 0x1c, 0xc8, 0xe1, 0x60, 0x28, 
+  0x04, 0x36, 0x15, 0x2b, 0x0f, 0x23, 0x05, 0xe5, 
+  0xcc, 0xe3, 0x6c, 0x36, 0x15, 0x98, 0xbf, 0x07, 
+  0x81, 0x81, 0xcd, 0xb0, 0x51, 0xe8, 0x3c, 0x6c, 
+  0x01, 0x63, 0xcf, 0xc1, 0x88, 0x7f, 0x75, 0xa1, 
+  0x70, 0xe3, 0xe6, 0x4c, 0xb1, 0x4d, 0xaa, 0x4b, 
+  0x1a, 0x6b, 0x39, 0x02, 0x9d, 0x31, 0xe8, 0x8c, 
+  0x08, 0x21, 0x09, 0x9c, 0xf7, 0x9b, 0x1e, 0xb4, 
+  0xab, 0x85, 0xb7, 0xf1, 0x9c, 0xe7, 0x50, 0xe4, 
+  0xee, 0xf2, 0x0c, 0x00, 0x58, 0xb9, 0xa4, 0xf1, 
+  0xbf, 0xcd, 0x62, 0x2a, 0xf8, 0xe6, 0x8e, 0x65, 
+  0x94, 0xb5, 0x4e, 0xcb, 0xcc, 0x2c, 0x34, 0x6c, 
+  0x44, 0x88, 0x09, 0xd4, 0x68, 0x1e, 0x02, 0x08, 
+  0x32, 0xfe, 0x75, 0x58, 0x43, 0x63, 0xc4, 0x9e, 
+  0x4d, 0xbf, 0x17, 0xeb, 0x6c, 0x0c, 0x78, 0x78, 
+  0xd2, 0x40, 0x60, 0x0e, 0x2e, 0x4d, 0xfb, 0xa0, 
+  0xc1, 0xf8, 0xee, 0x56, 0x8a, 0xee, 0xaa, 0x6f, 
+  0xc9, 0x29, 0x4e, 0x07, 0x8d, 0xac, 0x1b, 0x96, 
+  0x9c, 0x2b, 0x13, 0xe7, 0x78, 0xba, 0xe8, 0x79, 
+  0xb6, 0x40, 0x71, 0xdd, 0x34, 0x1b, 0x4c, 0x9e, 
+  0x5e, 0xa9, 0x53, 0xba, 0xba, 0xc1, 0xd4, 0x81, 
+  0xc0, 0x15, 0x51, 0x50, 0xed, 0xbc, 0xef, 0x24, 
+  0x3c, 0x2b, 0xba, 0x39, 0x2a, 0xef, 0x27, 0xa7, 
+  0x2f, 0x27, 0x7b, 0x62, 0x3a, 0x6d, 0x70, 0xdf, 
+  0x86, 0xcf, 0x16, 0xf0, 0x18, 0x63, 0xf8, 0xd6, 
+  0x37, 0xb6, 0x4b, 0x23, 0x6a, 0xdb, 0x6d, 0xbb, 
+  0x7f, 0x9c, 0x5b, 0x79, 0x24, 0xe5, 0xe9, 0xae, 
+  0x22, 0xa7, 0x6c, 0x3e, 0x4b, 0x36, 0x58, 0xa3, 
+  0xd8, 0xcb, 0x15, 0x49, 0x6e, 0xef, 0x3b, 0x11, 
+  0xac, 0xb4, 0xd5, 0x8d, 0xd0, 0xa5, 0x56, 0x0e, 
+  0x65, 0x07, 0x13, 0x54, 0xff, 0xb3, 0x7f, 0x3e, 
+  0xa2, 0xee, 0xf0, 0xac, 0xd0, 0xc9, 0x79, 0x87, 
+  0xd5, 0x52, 0xa5, 0x49, 0x65, 0x44, 0x55, 0xaa, 
+  0x2c, 0x96, 0x1b, 0xe9, 0x36, 0x1f, 0x5c, 0x54, 
+  0xdb, 0x7e, 0x6e, 0x8e, 0x7f, 0x99, 0xd9, 0x24, 
+  0x51, 0x67, 0xaf, 0x64, 0x2a, 0xbc, 0xbc, 0xff, 
+  0x16, 0xe4, 0x40, 0x42, 0x4f, 0x5a, 0x92, 0x29, 
+  0x69, 0x15, 0x6f, 0xbb, 0x16, 0xe1, 0xbb, 0xd5, 
+  0x39, 0x38, 0xa0, 0x97, 0xa2, 0x65, 0x15, 0xe9, 
+  0xa6, 0x59, 0xec, 0x92, 0xed, 0xd5, 0x1b, 0x79, 
+  0x2d, 0x51, 0x2f, 0x56, 0x37, 0xbd, 0x24, 0x36, 
+  0x52, 0x43, 0x76, 0x28, 0xeb, 0x6a, 0x24, 0x6f, 
+  0x79, 0xd0, 0xe4, 0xaa, 0xf3, 0x27, 0x6a, 0xc8, 
+  0x91, 0xa2, 0xa6, 0x8e, 0xab, 0x92, 0xb3, 0xed, 
+  0xd0, 0xef, 0x11, 0xb4, 0xa0, 0xab, 0x60, 0xcb, 
+  0x3a, 0x52, 0xbd, 0x1a, 0xae, 0xc8, 0xe7, 0x56, 
+  0x9c, 0x53, 0x85, 0x8a, 0x77, 0x57, 0xcd, 0xa2, 
+  0xe5, 0xe1, 0xb3, 0x67, 0xa0, 0x9f, 0x4c, 0xbc, 
+  0xda, 0x39, 0xc2, 0xb9, 0x27, 0x11, 0xc3, 0x7a, 
+  0xb7, 0x17, 0xec, 0x1a, 0xc7, 0xf7, 0x3c, 0xd4, 
+  0xdf, 0xe6, 0x95, 0xf3, 0x25, 0x37, 0xb5, 0x04, 
+  0x50, 0xb7, 0x45, 0xc2, 0x72, 0x49, 0xb9, 0xbe, 
+  0xb3, 0xeb, 0x6e, 0x64, 0x8a, 0x6d, 0x80, 0xc1, 
+  0x9d, 0xe0, 0xc5, 0xf4, 0xad, 0x86, 0xdb, 0x51, 
+  0x2d, 0xbf, 0x68, 0xa9, 0x78, 0x83, 0x22, 0x1b, 
+  0xab, 0x9b, 0x28, 0x26, 0x36, 0xac, 0x84, 0xe6, 
+  0x98, 0x56, 0xf8, 0x84, 0x05, 0xdb, 0x94, 0x71, 
+  0x9d, 0xba, 0xdc, 0x5f, 0xcb, 0x2f, 0xbc, 0xd8, 
+  0x8e, 0xed, 0x24, 0x51, 0xd5, 0xfa, 0x4e, 0x2f, 
+  0x08, 0x5a, 0xc8, 0x96, 0x5c, 0xad, 0x86, 0x36, 
+  0xcd, 0x80, 0x60, 0xb7, 0x67, 0x3f, 0xc5, 0x25, 
+  0x45, 0x9d, 0x11, 0x26, 0x20, 0xed, 0xe7, 0x7a, 
+  0x7c, 0x4e, 0x3d, 0x51, 0x07, 0x29, 0x33, 0xfd, 
+  0xad, 0xa3, 0xc5, 0x02, 0x09, 0x62, 0xd9, 0x3a, 
+  0x55, 0x66, 0xd9, 0x16, 0x5e, 0x45, 0xad, 0x5d, 
+  0xe6, 0xc7, 0x43, 0xcd, 0x1e, 0x36, 0xdf, 0xcb, 
+  0x51, 0x4c, 0xf6, 0x60, 0x7b, 0x3b, 0x14, 0xa3, 
+  0x8b, 0xf1, 0x4a, 0x0b, 0x3a, 0x54, 0x46, 0x38, 
+  0xa7, 0x14, 0x1a, 0xe1, 0x3a, 0xa6, 0xa4, 0x08, 
+  0x5f, 0xf3, 0x3d, 0x6b, 0xf6, 0x5c, 0xc2, 0xc5, 
+  0x16, 0xdb, 0x69, 0xb5, 0x30, 0xac, 0x0b, 0xaf, 
+  0x56, 0xe1, 0x24, 0x3c, 0x2f, 0x69, 0x33, 0x3b, 
+  0xbd, 0xd6, 0x14, 0x28, 0x5b, 0x24, 0x9d, 0x46, 
+  0xb5, 0x5e, 0xa0, 0xb2, 0x73, 0x51, 0x0d, 0x04, 
+  0x6c, 0x0f, 0x38, 0x97, 0xed, 0xcd, 0xaa, 0x55, 
+  0xa3, 0xb5, 0x7e, 0x96, 0x22, 0xc1, 0x16, 0x2d, 
+  0xd4, 0x7c, 0xe9, 0xd4, 0xd9, 0xf3, 0x63, 0x86, 
+  0xfc, 0xd2, 0x82, 0xdd, 0x44, 0x86, 0xf5, 0x05, 
+  0xe5, 0x5f, 0x82, 0xe2, 0x47, 0xb9, 0x69, 0xb5, 
+  0x03, 0x4d, 0x31, 0xc0, 0x43, 0xa3, 0xb0, 0xfa, 
+  0xcb, 0x6b, 0x09, 0x23, 0x3f, 0x6b, 0x72, 0x28, 
+  0x97, 0xf2, 0xaf, 0x9c, 0x9c, 0x1b, 0x48, 0xb4, 
+  0x8b, 0x1f, 0x3a, 0x0d, 0x15, 0x2b, 0x82, 0x18, 
+  0xf9, 0x96, 0x0a, 0xfc, 0x06, 0xf3, 0x3e, 0x89, 
+  0x4c, 0x8a, 0x64, 0xaa, 0x43, 0x84, 0x7d, 0x82, 
+  0xe3, 0xa2, 0xc5, 0x62, 0x32, 0x51, 0xda, 0xa1, 
+  0xc0, 0xe0, 0xac, 0x73, 0x91, 0x9b, 0xfe, 0x49, 
+  0x9a, 0xc7, 0x43, 0xd9, 0x32, 0xd0, 0x2f, 0x2a, 
+  0x25, 0xa8, 0x99, 0x22, 0xe5, 0x4d, 0x08, 0xcc, 
+  0xa4, 0xf4, 0x6a, 0x34, 0x1f, 0x8f, 0xd8, 0x5f, 
+  0x8a, 0x57, 0xad, 0xc8, 0x8d, 0x4f, 0x27, 0x50, 
+  0x05, 0x12, 0xb6, 0x83, 0x83, 0x35, 0x82, 0x2d, 
+  0x30, 0x89, 0x78, 0x68, 0x5c, 0x09, 0x95, 0xd1, 
+  0x90, 0x38, 0x17, 0xb6, 0x88, 0xa0, 0x1c, 0x30, 
+  0x0a, 0x6c, 0x94, 0x16, 0x20, 0xb0, 0x0a, 0x8f, 
+  0x0c, 0xc9, 0xaa, 0xe6, 0x84, 0x82, 0xff, 0x6a, 
+  0x25, 0xc1, 0x1c, 0x1c, 0xbc, 0x05, 0xc1, 0x61, 
+  0xeb, 0x63, 0xce, 0x2b, 0x1e, 0x2a, 0x4b, 0x04, 
+  0x7c, 0x61, 0x9f, 0x8e, 0x99, 0xfd, 0x49, 0xa0, 
+  0x78, 0x43, 0xff, 0xb2, 0xe1, 0x5f, 0x3d, 0xec, 
+  0x06, 0xe8, 0x94, 0xbf, 0x67, 0x43, 0xdb, 0xfc, 
+  0xf3, 0x7c, 0xed, 0xc3, 0xf8, 0xa5, 0x11, 0xa0, 
+  0x58, 0x04, 0x5e, 0xab, 0x54, 0x99, 0x29, 0x53, 
+  0x0a, 0x87, 0xf1, 0x20, 0x78, 0xac, 0x18, 0x3d, 
+  0x2e, 0x12, 0xc4, 0x86, 0xd1, 0x28, 0xfc, 0x03, 
+  0x71, 0x38, 0xf8, 0x15, 0xb1, 0xad, 0x47, 0x03, 
+  0xa6, 0xcc, 0x7d, 0x53, 0x16, 0x94, 0x1d, 0x17, 
+  0x22, 0xdf, 0xe3, 0xef, 0x89, 0x77, 0xa3, 0xd6, 
+  0x87, 0x98, 0x9b, 0xf7, 0x1a, 0x1f, 0xb3, 0xad, 
+  0xb0, 0x5c, 0x23, 0x24, 0x4e, 0xca, 0x46, 0x13, 
+  0xeb, 0x71, 0xaa, 0x23, 0x46, 0x5a, 0xf8, 0x93, 
+  0xf6, 0x37, 0xf7, 0x26, 0x82, 0xb5, 0x3b, 0x7d, 
+  0xf4, 0xf5, 0xc9, 0x98, 0x01, 0x65, 0xb5, 0x50, 
+  0xf5, 0x4d, 0xcf, 0x36, 0xad, 0xb1, 0xd4, 0xff, 
+  0x9b, 0x4c, 0xc7, 0xef, 0x80, 0xcb, 0x0a, 0xd3, 
+  0x2b, 0xf3, 0x6c, 0x7f, 0x22, 0xd7, 0x2e, 0x01, 
+  0x5f, 0x59, 0xb9, 0x2c, 0xbf, 0xf6, 0xc8, 0xf3, 
+  0xd1, 0x85, 0x40, 0x7d, 0x30, 0x06, 0x08, 0x0c, 
+  0xb5, 0x78, 0xc0, 0x2a, 0xc4, 0xb4, 0xad, 0x80, 
+  0x69, 0x7a, 0x95, 0x69, 0xc7, 0xa9, 0xd4, 0x33, 
+  0x57, 0xf1, 0x74, 0x12, 0xfc, 0xd3, 0x4d, 0x62, 
+  0x96, 0x94, 0xef, 0x44, 0x81, 0xbd, 0x1b, 0x78, 
+  0xc0, 0xb9, 0x20, 0xf8, 0x79, 0x07, 0x89, 0xc4, 
+  0x06, 0x87, 0xc9, 0x32, 0xf1, 0xa6, 0x1b, 0xd4, 
+  0x81, 0x01, 0x5c, 0x54, 0xad, 0x9f, 0xd0, 0x61, 
+  0x04, 0x77, 0xf9, 0x32, 0xcd, 0x69, 0xb4, 0xac, 
+  0x78, 0x72, 0x94, 0x40, 0x4d, 0xee, 0xa9, 0xb3, 
+  0xc9, 0x98, 0xda, 0xd9, 0x91, 0x8f, 0x2e, 0xa4, 
+  0x18, 0x07, 0xd9, 0xc8, 0x03, 0xc9, 0x45, 0x38, 
+  0x38, 0x89, 0xff, 0xb3, 0x57, 0x69, 0x46, 0x37, 
+  0x37, 0xcd, 0xb5, 0xf5, 0x4c, 0xf7, 0x92, 0xa7, 
+  0x48, 0xad, 0xa9, 0x57, 0x93, 0x7b, 0xef, 0xae, 
+  0x59, 0xf6, 0xb6, 0x15, 0xca, 0x22, 0x3e, 0x58, 
+  0x65, 0x26, 0x4a, 0x39, 0xf0, 0xf4, 0x4a, 0x4a, 
+  0xd4, 0xff, 0x8a, 0x94, 0x75, 0x9f, 0x29, 0xf5, 
+  0xdf, 0x36, 0xa3, 0x6e, 0x07, 0xbe, 0xec, 0x2d, 
+  0xcf, 0xc9, 0xb7, 0xb1, 0x6e, 0xf5, 0xc1, 0x88, 
+  0x43, 0xf1, 0x7f, 0x81, 0xc0, 0xa4, 0x04, 0x50, 
+  0x6e, 0x16, 0x7c, 0x3f, 0x05, 0x58, 0x30, 0xe4, 
+  0x7a, 0x0e, 0x05, 0x58, 0x30, 0x29, 0xc1, 0x8b, 
+  0x4b, 0x01, 0x4c, 0x0c, 0xa4, 0x18, 0x41, 0x10, 
+  0x41, 0x10, 0x18, 0x6c, 0xa4, 0x3f, 0x02, 0xe0, 
+  0xaa, 0x06, 0x0e, 0x41, 0xf0, 0x7f, 0xed, 0x0b, 
+  0x69, 0x44, 0xb4, 0xe5, 0xcd, 0x5c, 0x1f, 0xb4, 
+  0x3f, 0xd5, 0x7c, 0x6d, 0xa2, 0xf6, 0x8b, 0xc4, 
+  0x88, 0x24, 0x2b, 0x4f, 0xac, 0xec, 0xff, 0xc7, 
+  0x20, 0x64, 0x78, 0xa9, 0x20, 0x32, 0x96, 0x1b, 
+  0x8a, 0xfc, 0xac, 0xaf, 0xf5, 0xac, 0x6f, 0x14, 
+  0xe5, 0x6d, 0xa6, 0xcc, 0x45, 0x19, 0x2a, 0xe8, 
+  0xd0, 0x12, 0x9f, 0xc1, 0xe9, 0xa0, 0x03, 0xe0, 
+  0x52, 0x9a, 0x82, 0x27, 0xb7, 0x7e, 0x3e, 0xbd, 
+  0x60, 0xb5, 0xb5, 0x65, 0xcc, 0xf4, 0x42, 0xec, 
+  0xbb, 0x3f, 0xf4, 0x89, 0x55, 0xef, 0x41, 0x55, 
+  0x14, 0x03, 0x23, 0x65, 0xb5, 0xae, 0x33, 0xdd, 
+  0xe1, 0x87, 0x9b, 0xe6, 0xfa, 0x20, 0x27, 0x1f, 
+  0x27, 0x98, 0xa2, 0x6d, 0x2e, 0x2f, 0x48, 0x3f, 
+  0x51, 0xde, 0xdc, 0x8d, 0xd4, 0xcd, 0xb6, 0x58, 
+  0xa5, 0x46, 0xdc, 0x2d, 0xe1, 0x69, 0x67, 0xf8, 
+  0x36, 0xa7, 0x87, 0x23, 0xf9, 0x41, 0xe0, 0x60, 
+  0x43, 0x05, 0x14, 0x03, 0x05, 0x9d, 0x08, 0x00, 
+  0x8a, 0x08, 0xb5, 0x38, 0x2a, 0x80, 0xd6, 0xab, 
+  0x10, 0xe8, 0x3c, 0x17, 0xfd, 0x34, 0xb8, 0x15, 
+  0xa0, 0xaa, 0x8a, 0xc0, 0xd4, 0x6d, 0x42, 0xea, 
+  0x47, 0x0a, 0x03, 0xd0, 0xb1, 0x29, 0xed, 0x06, 
+  0xe9, 0x7b, 0x6a, 0x9b, 0x06, 0x62, 0x27, 0xf0, 
+  0x28, 0x84, 0x3c, 0x10, 0x01, 0x84, 0xa0, 0x62, 
+  0xd5, 0x0d, 0xeb, 0x2c, 0x37, 0x07, 0x9f, 0x57, 
+  0x73, 0xc0, 0xc2, 0x00, 0x7e, 0xc0, 0xec, 0x71, 
+  0x55, 0x4c, 0x67, 0xc3, 0xfa, 0xcd, 0x4c, 0x38, 
+  0xf3, 0x3f, 0x85, 0xd0, 0xc5, 0xba, 0x80, 0xf4, 
+  0x4d, 0x3f, 0x56, 0x9b, 0x64, 0x40, 0xc2, 0xf1, 
+  0xd6, 0xab, 0xed, 0xca, 0x93, 0x04, 0xb1, 0xf6, 
+  0x97, 0xf7, 0x03, 0xbf, 0x52, 0xec, 0x57, 0x53, 
+  0xcd, 0xf2, 0x8a, 0x5b, 0xea, 0xd2, 0x9c, 0x51, 
+  0xaa, 0x64, 0xe3, 0xd4, 0x08, 0x25, 0xe5, 0xc2, 
+  0x56, 0x84, 0x2c, 0x6f, 0xe5, 0xdd, 0x56, 0x24, 
+  0x97, 0x24, 0x6f, 0x13, 0xa7, 0x9e, 0xd6, 0x07, 
+  0xca, 0xc3, 0xf1, 0xc8, 0xef, 0x32, 0x2b, 0xf5, 
+  0x98, 0xab, 0x5a, 0xcc, 0x0f, 0xd9, 0x9f, 0x1f, 
+  0x78, 0xae, 0x7f, 0x2e, 0xf0, 0x2c, 0x61, 0x08, 
+  0x1e, 0x06, 0x04, 0x10, 0x53, 0x01, 0xe0, 0xfc, 
+  0x18, 0xb0, 0x6c, 0x5c, 0xa0, 0x3e, 0x1c, 0xd0, 
+  0x3b, 0x40, 0xf9, 0x65, 0x53, 0xd0, 0x61, 0x00, 
+  0x1e, 0x0b, 0xfc, 0xf9, 0x41, 0x56, 0x20, 0x88, 
+  0x0a, 0x41, 0x80, 0xc7, 0x40, 0xd0, 0xe0, 0x3c, 
+  0x07, 0xc1, 0x80, 0x54, 0x46, 0x0c, 0xad, 0x30, 
+  0xf0, 0x1e, 0x0a, 0x02, 0xf4, 0xe3, 0xf6, 0x87, 
+  0xdc, 0x07, 0x81, 0xff, 0x1c, 0x48, 0x61, 0x5a, 
+  0xb4, 0xbe, 0x63, 0x80, 0xaa, 0x50, 0x3f, 0xfb, 
+  0x2d, 0x7d, 0x96, 0x67, 0x01, 0x55, 0xd0, 0xf7, 
+  0xed, 0x6e, 0x87, 0xd6, 0x95, 0xeb, 0x9e, 0xda, 
+  0xb2, 0x0e, 0x1a, 0x0c, 0x6c, 0xa7, 0xaa, 0xe1, 
+  0x79, 0x84, 0xd9, 0x98, 0x23, 0x09, 0x6d, 0xf2, 
+  0x08, 0xbd, 0x68, 0x70, 0x3c, 0x1f, 0xb2, 0x1e, 
+  0x71, 0x48, 0x18, 0xef, 0x95, 0x32, 0xc8, 0x79, 
+  0xc5, 0x25, 0x43, 0x72, 0xa4, 0x6f, 0x7a, 0x3a, 
+  0xb9, 0x55, 0x27, 0xca, 0x5d, 0x55, 0x5b, 0x2c, 
+  0x2f, 0x2e, 0xdf, 0x5c, 0xff, 0x92, 0x25, 0x63, 
+  0x7f, 0x35, 0x4e, 0x76, 0x8d, 0xf2, 0x9b, 0x99, 
+  0xff, 0x7e, 0xf4, 0xb3, 0xe6, 0x03, 0x10, 0x32, 
+  0x70, 0x86, 0x0d, 0x85, 0x6a, 0x3a, 0x24, 0xb0, 
+  0x99, 0x6a, 0x06, 0xb8, 0x21, 0x02, 0x18, 0x32, 
+  0xe9, 0x18, 0xd0, 0x78, 0x48, 0x0a, 0xd2, 0x83, 
+  0x15, 0xb0, 0xba, 0x49, 0x67, 0x0b, 0x19, 0x06, 
+  0x41, 0xa1, 0x70, 0xe9, 0x57, 0x52, 0xe8, 0x85, 
+  0xf6, 0x1b, 0x55, 0x8a, 0xda, 0x10, 0x68, 0x33, 
+  0x09, 0x81, 0xe0, 0x7f, 0xb5, 0x04, 0x49, 0xff, 
+  0x08, 0x40, 0xaa, 0x6f, 0xa3, 0xcf, 0xb6, 0xac, 
+  0x21, 0x2a, 0x1d, 0xab, 0xf9, 0x6d, 0x2c, 0x6f, 
+  0xcd, 0xb4, 0x3e, 0xd4, 0x93, 0xfe, 0xf7, 0xd4, 
+  0xb2, 0x20, 0x99, 0xbb, 0xd3, 0x4a, 0x78, 0x88, 
+  0x1c, 0x41, 0xa6, 0x83, 0x65, 0xc0, 0x7b, 0xc3, 
+  0x81, 0xca, 0x41, 0x21, 0x50, 0x82, 0xde, 0x2a, 
+  0x68, 0xb7, 0xc9, 0xbc, 0x1f, 0xab, 0xfa, 0xde, 
+  0x55, 0xe2, 0xde, 0x0e, 0x59, 0xff, 0x2a, 0x86, 
+  0xb3, 0xbf, 0xd5, 0x15, 0x44, 0x59, 0xe6, 0x6d, 
+  0x06, 0x60, 0xab, 0x07, 0x20, 0xa0, 0x95, 0xb0, 
+  0x2d, 0x04, 0x11, 0x28, 0xb5, 0x92, 0xbd, 0x68, 
+  0x0c, 0x42, 0xde, 0xb6, 0x06, 0x73, 0x5a, 0x2a, 
+  0x5c, 0x73, 0x9b, 0xe0, 0xee, 0x58, 0xe0, 0xb8, 
+  0x07, 0x40, 0xf8, 0x42, 0x1d, 0xb2, 0x0c, 0x5c, 
+  0xc0, 0xf8, 0x7a, 0x98, 0xbd, 0xbf, 0x83, 0x2b, 
+  0x03, 0xc5, 0xf1, 0xa5, 0x5f, 0x9f, 0xdc, 0x63, 
+  0x2f, 0xfb, 0xac, 0xe6, 0x2e, 0x9b, 0x65, 0x4e, 
+  0xd0, 0x18, 0x4e, 0x58, 0xdd, 0xa5, 0xb2, 0x67, 
+  0x5a, 0x6c, 0x05, 0x1e, 0x06, 0x60, 0x1b, 0x00, 
+  0xf0, 0xec, 0x14, 0x1f, 0x4e, 0x9d, 0x24, 0x56, 
+  0xc8, 0x43, 0x64, 0x7e, 0x5a, 0xaf, 0x66, 0x6b, 
+  0x6a, 0xb1, 0x84, 0xec, 0xb1, 0xe0, 0x55, 0x6d, 
+  0xf5, 0x03, 0x56, 0x70, 0x73, 0x77, 0x3b, 0x7f, 
+  0xf5, 0x9b, 0x2d, 0x62, 0x40, 0x18, 0x6a, 0xf5, 
+  0x1f, 0xc5, 0xf7, 0xa3, 0x2e, 0x3f, 0x5c, 0x98, 
+  0x42, 0x08, 0x21, 0x09, 0x60, 0x78, 0x3f, 0xf8, 
+  0x47, 0x43, 0xf6, 0xa9, 0x27, 0x0a, 0x1e, 0x33, 
+  0x03, 0xea, 0xfc, 0x08, 0x61, 0x08, 0x7d, 0xa5, 
+  0xc9, 0xe6, 0xcd, 0xce, 0x7d, 0x81, 0xfb, 0x43, 
+  0xd1, 0xf8, 0x90, 0x3c, 0xaa, 0xaf, 0x53, 0x96, 
+  0x42, 0xfa, 0x98, 0xbc, 0x3c, 0x8c, 0x2f, 0xd2, 
+  0xc8, 0xa5, 0xaf, 0xa9, 0x93, 0xf9, 0x6b, 0x82, 
+  0x58, 0x28, 0xc0, 0xf8, 0xfd, 0x85, 0x4a, 0x95, 
+  0x0e, 0x59, 0xfe, 0xee, 0x16, 0xab, 0x6e, 0x30, 
+  0xc3, 0x4c, 0x4f, 0xb3, 0xfe, 0x37, 0xfe, 0x4d, 
+  0xcf, 0x66, 0x4d, 0x6f, 0x79, 0xfb, 0xc9, 0xc8, 
+  0xbf, 0x21, 0xc3, 0x03, 0xdf, 0x84, 0x0a, 0xc0, 
+  0xe5, 0x28, 0xf8, 0x0e, 0x8e, 0x83, 0xff, 0xcf, 
+  0x27, 0x2f, 0x54, 0xb8, 0xe5, 0x52, 0xae, 0xf9, 
+  0xb9, 0x37, 0x1b, 0x97, 0x62, 0x8f, 0x29, 0x96, 
+  0xe6, 0xac, 0x6e, 0x1c, 0xb6, 0xde, 0x21, 0xe4, 
+  0x34, 0xed, 0x71, 0x9b, 0x69, 0xfe, 0xac, 0x4a, 
+  0x4a, 0x07, 0x55, 0x2b, 0x08, 0x42, 0x1a, 0x46, 
+  0xe2, 0x51, 0x08, 0x7a, 0x21, 0x7c, 0x0e, 0x68, 
+  0x34, 0x11, 0x92, 0xd5, 0x6c, 0xf9, 0xa5, 0x4a, 
+  0x75, 0x52, 0x56, 0x04, 0x11, 0xfb, 0x55, 0x16, 
+  0xa8, 0xd5, 0x7e, 0xb8, 0x38, 0x93, 0x7f, 0xbb, 
+  0xa0, 0xb2, 0x28, 0xd0, 0x33, 0x62, 0x58, 0x94, 
+  0x9c, 0x78, 0x3f, 0x48, 0xa8, 0x4a, 0xa2, 0x1a, 
+  0x96, 0xb0, 0xb1, 0x52, 0x42, 0xf5, 0x49, 0xfd, 
+  0x36, 0x66, 0xea, 0xfe, 0x9e, 0x6f, 0xdb, 0x93, 
+  0x79, 0x6a, 0x25, 0xd7, 0xe3, 0xec, 0x03, 0x5b, 
+  0x1f, 0x0f, 0x47, 0x63, 0xe1, 0xf4, 0x1d, 0x0f, 
+  0x00, 0xe8, 0xf9, 0xaf, 0x26, 0x4e, 0xca, 0x7a, 
+  0x94, 0x7a, 0xc1, 0x77, 0xd5, 0x07, 0xdf, 0xd2, 
+  0xdf, 0x56, 0x9b, 0xfa, 0x5c, 0x61, 0x99, 0x65, 
+  0x6b, 0xc0, 0x65, 0x82, 0xbf, 0xa9, 0xa3, 0x89, 
+  0x02, 0xd4, 0xc2, 0x06, 0x0e, 0x80, 0x31, 0xa0, 
+  0x78, 0x2f, 0xf9, 0x44, 0x06, 0x18, 0x9b, 0x7e, 
+  0xac, 0x1e, 0x0b, 0xfd, 0x9f, 0x82, 0x85, 0x91, 
+  0x28, 0x18, 0x38, 0xf7, 0x04, 0x28, 0x23, 0xe8, 
+  0x30, 0x18, 0x10, 0x18, 0x51, 0xec, 0xe0, 0x2b, 
+  0x27, 0xc5, 0x7d, 0x51, 0xde, 0x75, 0x74, 0x27, 
+  0xb5, 0xc1, 0x66, 0xc0, 0x8e, 0x10, 0xcb, 0xd2, 
+  0x83, 0x32, 0x21, 0x26, 0x12, 0x07, 0xf1, 0x37, 
+  0xbe, 0xaf, 0x52, 0x44, 0xcd, 0x40, 0x6c, 0x12, 
+  0xfb, 0xcc, 0xef, 0x03, 0xfb, 0x90, 0x21, 0xa4, 
+  0xef, 0x74, 0x18, 0xd2, 0x9b, 0x3c, 0x22, 0x1f, 
+  0x14, 0x01, 0xe0, 0x51, 0x62, 0x66, 0x52, 0x40, 
+  0x3b, 0xa2, 0x4e, 0x09, 0x5e, 0x05, 0x3f, 0xc7, 
+  0xc0, 0xa7, 0xcb, 0x47, 0x20, 0xaa, 0x8c, 0x8e, 
+  0x14, 0xf0, 0xb7, 0xa3, 0x80, 0x23, 0xc2, 0xc0, 
+  0xe7, 0x87, 0xcd, 0x24, 0x6c, 0x49, 0x03, 0x82, 
+  0x18, 0x31, 0x5e, 0x17, 0xc6, 0x9a, 0xbc, 0x60, 
+  0x1e, 0x0b, 0xfd, 0xb1, 0x28, 0x10, 0xc2, 0x13, 
+  0x5f, 0xa3, 0x75, 0x05, 0x8d, 0x89, 0x25, 0xc5, 
+  0x5b, 0xf5, 0x0a, 0x78, 0x05, 0xbe, 0xf2, 0x1a, 
+  0xca, 0x86, 0x80, 0xc7, 0x9a, 0x55, 0xe9, 0x33, 
+  0xde, 0x2b, 0xfe, 0xff, 0x74, 0x45, 0xdb, 0x77, 
+  0x76, 0x95, 0xdf, 0xff, 0x6d, 0xaf, 0x35, 0x8f, 
+  0x79, 0x01, 0x64, 0x91, 0x10, 0xcc, 0x55, 0xae, 
+  0x68, 0x14, 0x00, 0xcd, 0x0f, 0x19, 0x56, 0x56, 
+  0x39, 0xc6, 0x2e, 0x79, 0xa6, 0xb5, 0x70, 0xe6, 
+  0x90, 0x6a, 0x0c, 0xb2, 0xa9, 0x3d, 0xde, 0x16, 
+  0xb6, 0xdf, 0xf5, 0x44, 0x59, 0x4d, 0xdb, 0xd7, 
+  0xc7, 0xd4, 0x06, 0xd0, 0x07, 0x03, 0x97, 0x3f, 
+  0xa1, 0xa4, 0x48, 0x81, 0xc7, 0x5a, 0x1b, 0x0f, 
+  0x6d, 0x33, 0xa6, 0x2d, 0xf0, 0xe8, 0xb9, 0x8e, 
+  0x0e, 0x13, 0x30, 0xd4, 0x35, 0xe6, 0xbd, 0x81, 
+  0x91, 0x84, 0x0b, 0x32, 0x2c, 0x2f, 0x09, 0x9d, 
+  0x9d, 0x3f, 0xe5, 0x34, 0x11, 0xce, 0x62, 0x19, 
+  0xd2, 0x9e, 0x3f, 0x4e, 0x78, 0x0e, 0x25, 0x19, 
+  0x11, 0xf5, 0x00, 0x3c, 0x94, 0x23, 0xdc, 0x07, 
+  0x23, 0x39, 0x91, 0xa3, 0xe1, 0xe5, 0x02, 0x43, 
+  0x4d, 0x3f, 0x51, 0x82, 0xc4, 0x1c, 0x2e, 0xeb, 
+  0xcf, 0xc1, 0xf3, 0x0d, 0x27, 0xb9, 0x93, 0x74, 
+  0x73, 0x37, 0x6d, 0xd0, 0x33, 0x9e, 0xea, 0x39, 
+  0x14, 0xa2, 0xea, 0x22, 0xce, 0x73, 0x88, 0x88, 
+  0x54, 0xa8, 0xc4, 0xc2, 0xd5, 0x0b, 0x2c, 0x37, 
+  0xe2, 0xdd, 0x88, 0x44, 0xc6, 0xc1, 0x5d, 0x5c, 
+  0xae, 0xec, 0xa8, 0xd4, 0x44, 0x1c, 0xaa, 0x3b, 
+  0xd5, 0x90, 0x20, 0x9d, 0x43, 0xc3, 0x83, 0x71, 
+  0xea, 0x82, 0xf6, 0xc4, 0x0b, 0x1a, 0xff, 0x40, 
+  0x87, 0xd8, 0x0f, 0x66, 0xf3, 0xf2, 0x72, 0x6a, 
+  0xd6, 0x11, 0xad, 0xef, 0xd9, 0xa0, 0xc1, 0xef, 
+  0xe1, 0x59, 0x56, 0x77, 0x95, 0x44, 0x88, 0x44, 
+  0x5e, 0xf2, 0x22, 0xea, 0xce, 0x15, 0x26, 0xf6, 
+  0x24, 0x9b, 0xb9, 0xb7, 0xa8, 0x54, 0xd6, 0x65, 
+  0xbc, 0xe2, 0xd1, 0x6f, 0x4e, 0x45, 0x90, 0x8c, 
+  0xce, 0xf6, 0x23, 0x8b, 0xc3, 0x43, 0x5a, 0x9a, 
+  0xde, 0xe2, 0x82, 0xd0, 0xfb, 0xed, 0xb2, 0x1e, 
+  0x41, 0xc2, 0x05, 0x08, 0x06, 0xd7, 0x54, 0xf1, 
+  0x1c, 0x95, 0x71, 0x41, 0x4a, 0xd3, 0x72, 0xc5, 
+  0xb9, 0x93, 0x6d, 0xd6, 0xb3, 0xa8, 0xaa, 0xc8, 
+  0xed, 0x8b, 0xc5, 0xd6, 0x97, 0x49, 0xd7, 0x9d, 
+  0x89, 0xe4, 0x91, 0x69, 0x2c, 0xda, 0xba, 0xd6, 
+  0x0d, 0x83, 0xde, 0xc5, 0xc6, 0x26, 0xfa, 0x81, 
+  0xe9, 0x56, 0xea, 0x9b, 0x27, 0x36, 0xa3, 0xe7, 
+  0x2a, 0xcb, 0x2c, 0x8b, 0xa3, 0x71, 0x99, 0xe5, 
+  0x9b, 0xc4, 0x10, 0x33, 0xa1, 0x5c, 0x4d, 0x45, 
+  0x62, 0x02, 0xab, 0x93, 0x9f, 0x51, 0x20, 0x77, 
+  0xe5, 0x37, 0x72, 0xa0, 0x95, 0x74, 0x5c, 0x5e, 
+  0xa9, 0x58, 0x6a, 0x33, 0xfa, 0xbf, 0x0f, 0xf9, 
+  0xa9, 0x8b, 0x75, 0xaf, 0x58, 0x5b, 0xcc, 0xfb, 
+  0x17, 0x43, 0xd2, 0xae, 0xf9, 0x47, 0xb6, 0x1b, 
+  0xde, 0xc5, 0xd1, 0xae, 0x8d, 0xeb, 0x37, 0xe5, 
+  0xf3, 0x3e, 0xc2, 0x9f, 0x69, 0x6e, 0xb7, 0xf0, 
+  0x21, 0x22, 0x2e, 0x76, 0x49, 0x57, 0x45, 0x56, 
+  0x40, 0x8d, 0xe2, 0x54, 0x8a, 0x8b, 0x4b, 0x6c, 
+  0x68, 0x70, 0xc2, 0x2f, 0x7b, 0x99, 0x16, 0xef, 
+  0x54, 0xc8, 0xa3, 0xa1, 0xea, 0x3e, 0xda, 0xb8, 
+  0x56, 0xa5, 0xbc, 0x20, 0xab, 0xa2, 0xaf, 0x27, 
+  0xa2, 0xeb, 0xa1, 0x9b, 0x32, 0x4d, 0xa6, 0xf8, 
+  0x1c, 0x68, 0x61, 0x45, 0x7a, 0xb3, 0x6b, 0x4d, 
+  0x0e, 0x3f, 0xfb, 0xb8, 0x8e, 0x7e, 0xf7, 0x85, 
+  0x8b, 0x55, 0x1c, 0xe6, 0x4e, 0x73, 0xbc, 0x8b, 
+  0x09, 0x88, 0xfe, 0x37, 0xa5, 0x9d, 0xb6, 0x5b, 
+  0x67, 0x38, 0x80, 0xd7, 0x7b, 0xc2, 0x53, 0xae, 
+  0x58, 0xb2, 0xd9, 0xb6, 0xae, 0x4b, 0x0d, 0xaf, 
+  0x4d, 0x94, 0x3b, 0x5c, 0xfe, 0x9a, 0xb8, 0x90, 
+  0x15, 0xbf, 0x56, 0xb6, 0xb7, 0x72, 0x2d, 0x7d, 
+  0x65, 0x96, 0x08, 0x90, 0xab, 0xba, 0xa4, 0xd1, 
+  0x11, 0x5a, 0x3c, 0xcd, 0x62, 0x59, 0x3e, 0xc4, 
+  0xe6, 0xf6, 0xac, 0xa4, 0xae, 0x59, 0xb3, 0xba, 
+  0xa7, 0x88, 0xfb, 0x28, 0xde, 0x72, 0x11, 0xd8, 
+  0xe3, 0xb2, 0x23, 0x95, 0x05, 0x5a, 0x8c, 0x16, 
+  0xea, 0xf0, 0xdc, 0x59, 0x01, 0x3c, 0xff, 0x54, 
+  0xe1, 0x65, 0xf5, 0xe5, 0x0f, 0x2d, 0x58, 0x63, 
+  0x7b, 0x9c, 0xe3, 0xd9, 0x7a, 0xb1, 0x2f, 0x7b, 
+  0x28, 0x4b, 0x13, 0x4d, 0x33, 0x03, 0x86, 0x2f, 
+  0xbc, 0x1e, 0xdc, 0x91, 0x1f, 0x7b, 0x79, 0x00, 
+  0xae, 0xad, 0xde, 0xf1, 0x18, 0x50, 0x4d, 0x80, 
+  0x33, 0x9d, 0xb9, 0xca, 0x50, 0x8f, 0x84, 0xab, 
+  0xf0, 0x99, 0x55, 0x73, 0x73, 0xdc, 0x6b, 0x2e, 
+  0x7f, 0x9c, 0x9f, 0x11, 0x20, 0x2b, 0xe2, 0x95, 
+  0xc9, 0xa1, 0xab, 0x24, 0x93, 0xb0, 0xd1, 0x51, 
+  0x52, 0x05, 0xd6, 0x0c, 0x5f, 0x78, 0x4b, 0x4f, 
+  0xd4, 0xc4, 0x6a, 0x92, 0xfa, 0x6b, 0x6a, 0x76, 
+  0xf4, 0x73, 0x62, 0x8e, 0x6a, 0xca, 0x16, 0x43, 
+  0x06, 0xd3, 0xa8, 0xc2, 0x9b, 0xb0, 0x72, 0xca, 
+  0xa9, 0xf8, 0xb4, 0x1f, 0xb0, 0xdf, 0xba, 0x49, 
+  0xb3, 0x96, 0x0d, 0xd1, 0x2e, 0x68, 0x4e, 0x83, 
+  0x10, 0x41, 0xad, 0xb7, 0x36, 0xde, 0xb7, 0xce, 
+  0xf0, 0xb7, 0x16, 0x5a, 0xe2, 0xd7, 0x96, 0x0a, 
+  0xcb, 0xe2, 0xac, 0xeb, 0x05, 0x57, 0x91, 0x99, 
+  0x78, 0x8f, 0x8b, 0xf7, 0x16, 0x5f, 0x90, 0x28, 
+  0x5b, 0x6b, 0xa2, 0xee, 0xf7, 0xa0, 0xf5, 0x30, 
+  0x01, 0x84, 0xbd, 0x05, 0xe0, 0x3a, 0x1b, 0x04, 
+  0xd5, 0x56, 0xd3, 0x61, 0x8c, 0xa0, 0xe0, 0x1e, 
+  0x72, 0xa9, 0xf9, 0x10, 0x1f, 0xd3, 0xa3, 0x68, 
+  0xca, 0x11, 0x1d, 0x2c, 0xa6, 0x9a, 0x88, 0xae, 
+  0x29, 0xe7, 0xaf, 0xfd, 0x3f, 0xc1, 0xce, 0x7b, 
+  0xfc, 0x53, 0xec, 0x6f, 0x90, 0x41, 0xcc, 0xb3, 
+  0x19, 0xe6, 0x0e, 0x66, 0xa8, 0x73, 0x52, 0xb1, 
+  0xa4, 0x20, 0xe4, 0x47, 0x0c, 0xb4, 0xad, 0x9b, 
+  0xf6, 0x73, 0xe9, 0xae, 0x7b, 0x2c, 0x2c, 0xf9, 
+  0x6c, 0x05, 0x6c, 0x0e, 0x54, 0x41, 0xb5, 0xe8, 
+  0xc5, 0x18, 0xa9, 0x4a, 0x81, 0xc2, 0x8a, 0x98, 
+  0xaa, 0xf2, 0xce, 0x7f, 0xde, 0xff, 0xaa, 0x36, 
+  0x99, 0xf7, 0x99, 0x6b, 0x79, 0x7a, 0x56, 0xc3, 
+  0x33, 0x5a, 0xde, 0x6c, 0x9b, 0x14, 0xe5, 0xe6, 
+  0xe6, 0x68, 0xdf, 0x23, 0xde, 0xef, 0x57, 0xed, 
+  0xb6, 0xdb, 0xd4, 0x3d, 0xb4, 0x96, 0xa1, 0xb4, 
+  0x8d, 0x05, 0x24, 0x80, 0xe2, 0x51, 0xaf, 0xe8, 
+  0x3f, 0x7c, 0x00, 0x72, 0x13, 0xc6, 0xc2, 0xd0, 
+  0x2b, 0x26, 0x8e, 0x74, 0x7c, 0x3c, 0xd6, 0x62, 
+  0x8b, 0x15, 0xfc, 0x74, 0x3c, 0xfa, 0x59, 0x73, 
+  0x85, 0x97, 0x13, 0xfd, 0x35, 0x57, 0x2b, 0x53, 
+  0x24, 0x6a, 0x96, 0xf5, 0xa5, 0x12, 0x7a, 0xe2, 
+  0x88, 0x79, 0x54, 0xe9, 0x07, 0x83, 0xf5, 0x10, 
+  0x7e, 0x93, 0xc9, 0x7d, 0x2a, 0x9e, 0x37, 0xaa, 
+  0xfd, 0x4b, 0x78, 0x37, 0x2d, 0x61, 0xb6, 0x1b, 
+  0x29, 0x0f, 0x54, 0x7d, 0x6b, 0xf9, 0xa5, 0x98, 
+  0x7a, 0xaf, 0x41, 0x63, 0xd0, 0xc0, 0xeb, 0x19, 
+  0x83, 0x81, 0x3a, 0xd9, 0x06, 0x24, 0xaf, 0xa3, 
+  0x44, 0xc4, 0x9b, 0xca, 0x37, 0xcc, 0x2c, 0x51, 
+  0x22, 0x8a, 0xd6, 0x56, 0x0b, 0x24, 0x92, 0x35, 
+  0x58, 0xb0, 0x70, 0x20, 0x4c, 0xc9, 0xe8, 0xc1, 
+  0x60, 0xe0, 0xb2, 0x4f, 0x28, 0x51, 0x0f, 0x29, 
+  0x31, 0xa9, 0xd8, 0xa9, 0xa4, 0xc9, 0xa6, 0xf3, 
+  0xb8, 0x3e, 0x1e, 0x24, 0x2e, 0x9b, 0x73, 0xaa, 
+  0x2b, 0x70, 0xb9, 0x86, 0x87, 0x3b, 0x93, 0x7f, 
+  0x30, 0xb5, 0x4a, 0x82, 0xdf, 0xa8, 0xe2, 0x9a, 
+  0x7c, 0xcf, 0x4f, 0x7e, 0x9b, 0x2b, 0x19, 0x05, 
+  0x5a, 0x8c, 0x24, 0x07, 0x12, 0x91, 0xe9, 0x8b, 
+  0x44, 0x84, 0x93, 0x47, 0x29, 0xd8, 0x1f, 0x09, 
+  0x54, 0x77, 0x36, 0x96, 0x27, 0x06, 0x50, 0x3e, 
+  0xf2, 0x59, 0xff, 0x87, 0x6c, 0xfd, 0x2e, 0x35, 
+  0x89, 0xef, 0xea, 0x9d, 0x2d, 0xbb, 0xf5, 0x2d, 
+  0xaf, 0x2d, 0xbd, 0x78, 0x95, 0x38, 0xe1, 0xb4, 
+  0xda, 0xc7, 0xd3, 0x34, 0x3f, 0x53, 0x24, 0xaa, 
+  0x93, 0xe3, 0x4c, 0xb1, 0xbf, 0xc1, 0xb5, 0xfb, 
+  0x5a, 0xa7, 0x0a, 0xbf, 0x26, 0xaf, 0x2f, 0x2a, 
+  0x24, 0x4e, 0x44, 0x4a, 0x49, 0x93, 0x1a, 0xf9, 
+  0x6b, 0x79, 0xac, 0xaf, 0xc5, 0x3c, 0xcb, 0xca, 
+  0x6e, 0x50, 0x60, 0xa5, 0x3d, 0xf3, 0x78, 0xb3, 
+  0x5c, 0x44, 0xa6, 0xfc, 0xd6, 0x8c, 0xba, 0x8c, 
+  0x1d, 0x48, 0x06, 0x10, 0x9a, 0x88, 0x10, 0x1e, 
+  0xd7, 0xb2, 0xe6, 0xf5, 0xa4, 0xe9, 0x15, 0x09, 
+  0x25, 0xed, 0x35, 0x93, 0x75, 0xb6, 0x5a, 0x92, 
+  0x22, 0x54, 0xd6, 0x78, 0x93, 0x39, 0xef, 0x01, 
+  0x49, 0x92, 0x39, 0x3d, 0x4d, 0xe6, 0x8b, 0xa7, 
+  0x8b, 0x92, 0x5b, 0xb3, 0x1a, 0x48, 0x93, 0xcd, 
+  0x5e, 0xed, 0xad, 0x7b, 0x22, 0x3d, 0xde, 0xcc, 
+  0xdb, 0xb7, 0x7b, 0x6f, 0x24, 0x99, 0x88, 0x0f, 
+  0x6f, 0xe1, 0x66, 0x45, 0x3d, 0x02, 0x74, 0xd2, 
+  0xc4, 0xa1, 0x57, 0x50, 0x8c, 0x95, 0x11, 0x40, 
+  0x2c, 0x45, 0x3c, 0x52, 0x85, 0xfa, 0x6a, 0xb4, 
+  0x21, 0x09, 0x0d, 0x72, 0xaa, 0x10, 0x84, 0x85, 
+  0x56, 0x7f, 0xcc, 0xe0, 0x80, 0x3a, 0x2e, 0x6a, 
+  0xc6, 0x58, 0xe8, 0xe1, 0x9c, 0xbe, 0x6b, 0x38, 
+  0xdb, 0x4a, 0x74, 0x70, 0xdc, 0x0f, 0x5a, 0x2d, 
+  0xd5, 0x16, 0x29, 0xd3, 0xe5, 0xfc, 0xc3, 0x49, 
+  0xb2, 0x34, 0xc3, 0x4d, 0x30, 0xd6, 0x5b, 0x71, 
+  0x86, 0x3d, 0x15, 0x7a, 0x5d, 0xbd, 0xfd, 0x9e, 
+  0xc9, 0x99, 0x3b, 0x7b, 0xbb, 0x79, 0xdb, 0xb6, 
+  0xed, 0x5e, 0x9f, 0x2a, 0x63, 0x5a, 0x2f, 0x25, 
+  0x42, 0x14, 0x42, 0x4a, 0x45, 0x13, 0x74, 0xa3, 
+  0x87, 0xc4, 0x7b, 0x99, 0xfc, 0xdf, 0x6f, 0xa3, 
+  0x7e, 0xfc, 0xb1, 0xbf, 0x7f, 0x33, 0xfe, 0xdf, 
+  0x55, 0xae, 0x7f, 0xdf, 0x53, 0x9b, 0x95, 0x0e, 
+  0x6f, 0x65, 0x21, 0xba, 0x88, 0x1d, 0xc0, 0x58, 
+  0x03, 0x9f, 0x81, 0xcb, 0xd4, 0x60, 0xe2, 0x17, 
+  0x18, 0xbe, 0xa6, 0xa2, 0x41, 0x28, 0x74, 0xd1, 
+  0x6b, 0x4d, 0x09, 0x43, 0xc5, 0x5e, 0x67, 0x2e, 
+  0x2b, 0xf2, 0xa1, 0xe2, 0x65, 0x58, 0xaf, 0x39, 
+  0xb1, 0x43, 0x38, 0xc3, 0x59, 0x8c, 0xe7, 0x3f, 
+  0xfc, 0xe7, 0xe6, 0xad, 0xfd, 0x82, 0x2b, 0xc5, 
+  0xad, 0x7b, 0xde, 0x6a, 0x34, 0xd7, 0xa3, 0x5e, 
+  0xcc, 0x99, 0xef, 0x35, 0x26, 0x67, 0xbd, 0x88, 
+  0xb3, 0x3d, 0xee, 0x66, 0x64, 0x85, 0x53, 0x24, 
+  0xe6, 0x49, 0xc8, 0x79, 0x0f, 0x55, 0xc6, 0x43, 
+  0x20, 0x1f, 0x0a, 0x02, 0xad, 0x88, 0x90, 0x84, 
+  0x56, 0x94, 0x85, 0x55, 0x1b, 0xe3, 0x0c, 0x7a, 
+  0xb7, 0xbe, 0x6b, 0x33, 0x59, 0xd2, 0xd6, 0x77, 
+  0xd9, 0x26, 0xb3, 0xfe, 0x70, 0xb5, 0xbb, 0xc9, 
+  0x5b, 0xff, 0x39, 0x85, 0xbb, 0xdd, 0x51, 0xc9, 
+  0xde, 0x3a, 0x38, 0xb0, 0xcc, 0x1d, 0xc0, 0x4e, 
+  0x4c, 0xe3, 0x5b, 0x62, 0x11, 0xae, 0xbe, 0xa8, 
+  0x86, 0x2f, 0xce, 0xdd, 0x19, 0x02, 0xc5, 0xee, 
+  0xc2, 0x9a, 0x0b, 0x96, 0x95, 0x63, 0x9a, 0xfa, 
+  0x83, 0x88, 0x74, 0x07, 0x1f, 0xd1, 0x02, 0x22, 
+  0x2a, 0x0c, 0x45, 0xcb, 0x42, 0x64, 0x42, 0x41, 
+  0xa7, 0x45, 0x21, 0x44, 0x83, 0x86, 0x03, 0x56, 
+  0x80, 0x31, 0x21, 0x7d, 0x59, 0x10, 0x64, 0x19, 
+  0x39, 0xd6, 0xe9, 0x1e, 0x9c, 0x5c, 0x44, 0xb1, 
+  0x28, 0x39, 0x71, 0x5a, 0x62, 0x78, 0x91, 0x60, 
+  0x7f, 0x2f, 0xff, 0xf0, 0x3d, 0x1c, 0x00, 0x60, 
+  0xe7, 0x67, 0x74, 0xcb, 0x8c, 0x21, 0x40, 0x2c, 
+  0x51, 0x0d, 0x75, 0x88, 0x40, 0x70, 0x38, 0x82, 
+  0x01, 0xc6, 0xba, 0x0e, 0x26, 0x68, 0x56, 0x44, 
+  0x0e, 0x34, 0xe6, 0x2b, 0x13, 0x69, 0x9a, 0x65, 
+  0x85, 0x28, 0x79, 0x10, 0xf0, 0x31, 0x91, 0x61, 
+  0x88, 0x54, 0xa2, 0xaf, 0x41, 0xcf, 0xef, 0x7b, 
+  0xcb, 0xcb, 0xd9, 0x54, 0xca, 0x22, 0x21, 0x40, 
+  0xe2, 0xfa, 0x8a, 0xf2, 0x03, 0x81, 0x72, 0x70, 
+  0x41, 0x9a, 0xd5, 0xdc, 0x8d, 0xf2, 0x76, 0x2e, 
+  0x55, 0xfb, 0xa8, 0x38, 0x6d, 0x70, 0x74, 0x7a, 
+  0x10, 0x54, 0xc5, 0xaa, 0x26, 0xa3, 0x44, 0x0b, 
+  0x00, 0x5f, 0x2c, 0xdc, 0xe0, 0x75, 0x11, 0xde, 
+  0x44, 0x7c, 0xec, 0x44, 0x75, 0x75, 0x43, 0x9a, 
+  0xc5, 0x0f, 0xed, 0xde, 0xed, 0x24, 0xd9, 0x10, 
+  0x62, 0xc8, 0xf8, 0x04, 0x56, 0xec, 0x46, 0x42, 
+  0x96, 0x15, 0xcb, 0x17, 0x5a, 0xc4, 0x38, 0xb1, 
+  0x22, 0xe8, 0xa1, 0x48, 0xc8, 0xe1, 0x92, 0xae, 
+  0x09, 0xd1, 0x34, 0xf3, 0x03, 0x9b, 0xd1, 0xb7, 
+  0x22, 0x05, 0x89, 0x29, 0x0e, 0xb9, 0x11, 0xf1, 
+  0x12, 0x14, 0x01, 0x8c, 0x0c, 0xa9, 0x3c, 0xcc, 
+  0x5e, 0x23, 0xec, 0x28, 0x0a, 0x67, 0x57, 0x36, 
+  0x0e, 0x28, 0x39, 0x22, 0x11, 0x71, 0xda, 0xbf, 
+  0x91, 0x7d, 0xd2, 0x85, 0xd7, 0x0c, 0xc6, 0x01, 
+  0x3d, 0x2b, 0xda, 0xcb, 0x52, 0x23, 0x88, 0x56, 
+  0xec, 0xe8, 0xc6, 0x20, 0x44, 0x4f, 0x8a, 0x14, 
+  0x12, 0x50, 0xc5, 0x12, 0xe4, 0x4c, 0xa4, 0xe7, 
+  0x46, 0x9a, 0x66, 0x72, 0x36, 0xde, 0x8e, 0x7e, 
+  0xc9, 0x50, 0x14, 0xf4, 0x5a, 0x12, 0x55, 0xa1, 
+  0x5d, 0x24, 0x22, 0x82, 0xc9, 0x51, 0xcb, 0xde, 
+  0x02, 0xc0, 0xa7, 0xa2, 0x92, 0x35, 0x44, 0x46, 
+  0x85, 0x11, 0x28, 0x30, 0x51, 0xa4, 0x43, 0x41, 
+  0x85, 0xe0, 0xe0, 0xae, 0xf5, 0x09, 0x06, 0x99, 
+  0x2f, 0x31, 0x99, 0x16, 0xc2, 0xc9, 0xc0, 0xd3, 
+  0xa3, 0x28, 0x43, 0xda, 0xbf, 0x9b, 0xe8, 0x1d, 
+  0xdb, 0xf5, 0xd0, 0x16, 0x60, 0x67, 0x49, 0x10, 
+  0xde, 0x9d, 0x9e, 0x14, 0x8c, 0x51, 0x82, 0xc0, 
+  0xd0, 0xa9, 0x55, 0x18, 0x5a, 0xd5, 0xb2, 0xd2, 
+  0xb9, 0xcd, 0x59, 0x65, 0xcd, 0xd4, 0x08, 0x14, 
+  0x41, 0x83, 0x9c, 0xdd, 0x5d, 0xfa, 0x6b, 0x29, 
+  0x05, 0xcb, 0x52, 0x32, 0x07, 0x06, 0x24, 0xe6, 
+  0xaf, 0xe9, 0x48, 0xa5, 0x45, 0x3a, 0x48, 0x0e, 
+  0x20, 0x5e, 0x70, 0x17, 0xba, 0x75, 0x69, 0x48, 
+  0x47, 0x1d, 0x36, 0x0e, 0x17, 0x11, 0x6e, 0xea, 
+  0x34, 0x63, 0x35, 0x86, 0x92, 0x5b, 0xa6, 0xa9, 
+  0x2c, 0xe8, 0x38, 0x16, 0x02, 0xa5, 0x59, 0xd1, 
+  0x75, 0x7b, 0xde, 0x70, 0x1f, 0xbe, 0x00, 0x3f, 
+  0xfa, 0xfa, 0xce, 0x9a, 0x90, 0x51, 0xe4, 0xea, 
+  0x0c, 0x22, 0x99, 0x57, 0x34, 0x4d, 0x57, 0xa3, 
+  0x8f, 0x86, 0xca, 0x0f, 0xdb, 0x6d, 0x37, 0x50, 
+  0x4a, 0xe5, 0x5b, 0x6a, 0xd8, 0xbf, 0x65, 0xec, 
+  0xd7, 0x2b, 0xb5, 0xff, 0x61, 0xc7, 0xe9, 0x7b, 
+  0xd3, 0x96, 0xcc, 0x9c, 0x5a, 0xb7, 0xed, 0x41, 
+  0x38, 0x73, 0x46, 0x53, 0x75, 0x6b, 0xfd, 0x30, 
+  0xd7, 0x84, 0xaf, 0xd3, 0x32, 0x07, 0x95, 0xfc, 
+  0x73, 0x5a, 0x1b, 0xf9, 0x42, 0x99, 0x03, 0x8e, 
+  0x10, 0xcc, 0xa0, 0xe1, 0xa0, 0xc4, 0x10, 0x8b, 
+  0xf7, 0xe3, 0xdc, 0xf0, 0x7d, 0x71, 0x4e, 0x7e, 
+  0x5d, 0xb4, 0x36, 0x14, 0x28, 0x83, 0x03, 0x00, 
+  0x58, 0x82, 0xc0, 0xfa, 0x7f, 0x39, 0x51, 0x9e, 
+  0x89, 0xbb, 0x20, 0xcd, 0x12, 0x01, 0x3d, 0xaf, 
+  0x50, 0x83, 0x85, 0xe8, 0x8a, 0x05, 0x29, 0xaf, 
+  0x4e, 0xe8, 0x84, 0x31, 0x08, 0x8c, 0x3f, 0xa7, 
+  0x22, 0xf5, 0x88, 0xea, 0x83, 0xba, 0x18, 0x0a, 
+  0xf4, 0x92, 0xa1, 0x44, 0x0e, 0x44, 0x12, 0x6a, 
+  0x0e, 0x90, 0x1c, 0x7a, 0xa0, 0x21, 0xa9, 0xb5, 
+  0xd1, 0x83, 0xba, 0x6d, 0x08, 0x4d, 0xdf, 0x97, 
+  0x35, 0x22, 0x30, 0x72, 0x03, 0xbf, 0x88, 0xc0, 
+  0x72, 0xe0, 0x38, 0x29, 0x9d, 0x34, 0xbd, 0x0a, 
+  0x34, 0xdf, 0x91, 0xf0, 0xa4, 0x53, 0x39, 0x09, 
+  0x2a, 0x30, 0x73, 0xdf, 0x91, 0xc4, 0x00, 0xe5, 
+  0xa7, 0x01, 0x39, 0xf9, 0x11, 0xa0, 0x8a, 0xbe, 
+  0x2f, 0xaa, 0x31, 0x90, 0xcc, 0x31, 0x27, 0xfd, 
+  0x34, 0xb1, 0xcf, 0x01, 0xfd, 0x7f, 0xff, 0xd2, 
+  0x74, 0xa0, 0x1d, 0x4a, 0x4e, 0x59, 0x0e, 0xe9, 
+  0xb4, 0x05, 0x00, 0xe3, 0x44, 0xf8, 0x31, 0x05, 
+  0xd3, 0x8b, 0x21, 0x7e, 0x5c, 0x1c, 0x03, 0xc1, 
+  0x3d, 0x51, 0x14, 0x0a, 0xea, 0x78, 0xa0, 0x31, 
+  0x09, 0x64, 0x1c, 0x12, 0xbe, 0x1b, 0x80, 0xe2, 
+  0x0c, 0x8b, 0x84, 0x85, 0x20, 0xb0, 0x09, 0x18, 
+  0x28, 0xd3, 0xe0, 0xe4, 0x20, 0xe0, 0x4d, 0xf6, 
+  0x9a, 0x07, 0x06, 0x4f, 0x60, 0xe4, 0x46, 0xdf, 
+  0xc6, 0x22, 0xe0, 0xc0, 0x28, 0xe2, 0x32, 0x0d, 
+  0x3f, 0xde, 0x00, 0xe0, 0x92, 0x01, 0x79, 0x54, 
+  0x6e, 0xec, 0xba, 0x02, 0x1a, 0x6c, 0xfc, 0x5f, 
+  0x8b, 0xc0, 0x77, 0x4f, 0x4a, 0x03, 0x61, 0x1b, 
+  0x50, 0x83, 0x84, 0x5f, 0xa3, 0x31, 0x45, 0xc5, 
+  0x81, 0xd4, 0xee, 0x9c, 0xda, 0x48, 0x31, 0xe2, 
+  0x32, 0x8a, 0xe2, 0xd2, 0x5b, 0xb7, 0x68, 0xcb, 
+  0x0d, 0x12, 0xa2, 0x42, 0x14, 0x65, 0xcd, 0x03, 
+  0x83, 0x20, 0x9d, 0x0e, 0x0b, 0x82, 0x96, 0xb4, 
+  0x64, 0xed, 0x34, 0xf9, 0xb5, 0x0d, 0x80, 0xfd, 
+  0xb0, 0x01, 0xd6, 0x62, 0x8d, 0x5d, 0x1d, 0x29, 
+  0xa1, 0x80, 0x66, 0x32, 0x7f, 0xe9, 0xb1, 0x33, 
+  0x17, 0x1a, 0x87, 0x59, 0x72, 0x0a, 0xba, 0x7a, 
+  0x88, 0x92, 0xf1, 0xf8, 0x31, 0x07, 0x40, 0x8f, 
+  0x12, 0xa0, 0x45, 0x3a, 0x88, 0x1c, 0x11, 0x30, 
+  0x72, 0xe4, 0x5a, 0x83, 0x61, 0x3c, 0x4e, 0xaa, 
+  0x00, 0xc9, 0x19, 0xf6, 0xb0, 0x38, 0x07, 0x04, 
+  0x93, 0x46, 0x62, 0x66, 0xb0, 0x2c, 0x08, 0xea, 
+  0x95, 0xc1, 0x3f, 0x48, 0x99, 0x3a, 0x8e, 0xf4, 
+  0xd2, 0xc0, 0xe0, 0xc4, 0x69, 0x34, 0x1e, 0x82, 
+  0x00, 0x30, 0x71, 0x4b, 0xdb, 0x0c, 0x45, 0x29, 
+  0xda, 0x4d, 0xa7, 0xf9, 0xde, 0x74, 0x5c, 0x0b, 
+  0xa4, 0xfc, 0xa6, 0xfc, 0x3d, 0x51, 0xc9, 0xf0, 
+  0xf3, 0x88, 0xcd, 0x4e, 0xd3, 0x60, 0xbb, 0xf3, 
+  0xaa, 0x17, 0xe4, 0xa2, 0xe0, 0x71, 0xf8, 0x8b, 
+  0x5c, 0x86, 0xa8, 0x3b, 0xa7, 0x64, 0x1a, 0x69, 
+  0x8e, 0x01, 0x14, 0x49, 0x41, 0x3c, 0x08, 0xd0, 
+  0x18, 0x07, 0xb9, 0x1c, 0x4e, 0x25, 0xd4, 0x71, 
+  0x80, 0x7d, 0x8f, 0xff, 0x52, 0xdd, 0x36, 0x14, 
+  0xd7, 0x4d, 0x38, 0xba, 0x36, 0x5a, 0x18, 0xa9, 
+  0xd2, 0x91, 0xda, 0x1f, 0xb5, 0x90, 0xa1, 0x71, 
+  0x7f, 0x48, 0x28, 0x19, 0x7a, 0x8c, 0xbc, 0x61, 
+  0xc8, 0x12, 0x7e, 0xae, 0x15, 0x60, 0xc8, 0x4d, 
+  0xe6, 0xea, 0x20, 0xc0, 0x13, 0x75, 0xe9, 0x52, 
+  0xaf, 0x74, 0x3d, 0xd6, 0x6d, 0xa2, 0xba, 0x69, 
+  0x32, 0xa4, 0x77, 0x65, 0x3d, 0x2b, 0x50, 0x75, 
+  0x05, 0xd5, 0xee, 0x1f, 0x55, 0xca, 0xd1, 0xbf, 
+  0x5e, 0x59, 0xbe, 0x06, 0x24, 0xc3, 0xe9, 0xff, 
+  0xeb, 0x20, 0x39, 0x41, 0xda, 0x80, 0x75, 0x07, 
+  0x0d, 0x56, 0x02, 0xe7, 0xaf, 0xa0, 0xcc, 0x8b, 
+  0x4e, 0x65, 0x91, 0x12, 0xc3, 0x49, 0x52, 0xe7, 
+  0x59, 0xa5, 0x01, 0x47, 0x2d, 0x06, 0x14, 0x4e, 
+  0x6a, 0x3a, 0x76, 0x2e, 0xbf, 0xfe, 0xd7, 0xc1, 
+  0x8d, 0xfa, 0xd4, 0x44, 0x27, 0x3e, 0x5a, 0x25, 
+  0xb0, 0xc5, 0x51, 0xd3, 0x54, 0xb2, 0xab, 0xf0, 
+  0x3c, 0x64, 0x01, 0xad, 0xb7, 0x8b, 0x85, 0x63, 
+  0x16, 0x67, 0x95, 0xc0, 0x64, 0x3e, 0xd9, 0x62, 
+  0x14, 0x41, 0x29, 0x6f, 0x5b, 0xc5, 0xba, 0x84, 
+  0xd0, 0xc4, 0x2b, 0x4d, 0x8a, 0x01, 0xd2, 0xe0, 
+  0x0f, 0x76, 0x9a, 0x02, 0x40, 0xed, 0xa1, 0x2e, 
+  0x37, 0x7d, 0x8c, 0xe4, 0xf5, 0x90, 0x15, 0xad, 
+  0x6b, 0x48, 0x10, 0x29, 0x40, 0xb1, 0x01, 0x1d, 
+  0xc3, 0x5c, 0x07, 0x1f, 0x24, 0xab, 0x4a, 0x90, 
+  0x14, 0x82, 0xc0, 0x27, 0x8d, 0x44, 0x18, 0x12, 
+  0x05, 0x1a, 0x24, 0x1c, 0x34, 0xbf, 0x42, 0xbd, 
+  0x3b, 0x15, 0x6d, 0x07, 0x12, 0x0b, 0x9e, 0xac, 
+  0x0c, 0x81, 0xcf, 0xf6, 0x03, 0xd0, 0x40, 0x06, 
+  0x30, 0x20, 0x61, 0x4e, 0x9d, 0x8c, 0xf8, 0x26, 
+  0x84, 0x43, 0x33, 0x74, 0x1c, 0x0b, 0xec, 0xb9, 
+  0x36, 0x41, 0x45, 0x5a, 0x28, 0xb9, 0xcd, 0x3f, 
+  0x9d, 0x2d, 0x80, 0xe9, 0x01, 0xc2, 0xfa, 0x34, 
+  0xde, 0x07, 0x1b, 0x73, 0xc1, 0xb8, 0xcf, 0xa5, 
+  0x23, 0x56, 0xd7, 0x41, 0xc8, 0xf8, 0x14, 0xe7, 
+  0x2a, 0xf0, 0x52, 0x0e, 0x0a, 0x3c, 0x43, 0x7a, 
+  0x8c, 0x4f, 0x89, 0x41, 0xd4, 0x13, 0x7d, 0xa0, 
+  0xe0, 0xc8, 0x89, 0xaa, 0x03, 0xd1, 0x3f, 0x3b, 
+  0xd2, 0x40, 0x71, 0xd6, 0x37, 0x01, 0xfc, 0x05, 
+  0xd3, 0x84, 0x39, 0x09, 0x03, 0x23, 0xa1, 0x1e, 
+  0x9e, 0x19, 0x83, 0x06, 0x41, 0x57, 0x07, 0x0c, 
+  0x09, 0x4f, 0x63, 0xfc, 0x66, 0xb8, 0x38, 0xf2, 
+  0xf0, 0x17, 0x71, 0x3c, 0x32, 0x0a, 0xba, 0x28, 
+  0x81, 0x72, 0x40, 0x5c, 0x35, 0xa9, 0x0b, 0x07, 
+  0x02, 0x6a, 0x12, 0x11, 0xe9, 0xea, 0x0e, 0x01, 
+  0xe0, 0xb8, 0xe8, 0x81, 0xc2, 0x8d, 0x46, 0x42, 
+  0x9c, 0x0f, 0x43, 0xff, 0xff, 0x02, 0x76, 0x22, 
+  0xa9, 0xcd, 0x07, 0x52, 0x3e, 0x0e, 0x04, 0xea, 
+  0xa0, 0xf3, 0xd0, 0x01, 0x83, 0x88, 0x9a, 0xe8, 
+  0xd1, 0x92, 0x03, 0x81, 0x3e, 0xf6, 0x54, 0x5d, 
+  0x58, 0x4d, 0x17, 0x66, 0xc3, 0x10, 0x5c, 0xf0, 
+  0xcc, 0x1c, 0x12, 0x3a, 0xe9, 0x05, 0x80, 0x54, 
+  0xc8, 0xc1, 0xd7, 0xa7, 0xaa, 0xf5, 0xd8, 0x6d, 
+  0x68, 0x8a, 0xba, 0x39, 0xc4, 0x08, 0xc8, 0x2c, 
+  0x07, 0x83, 0x84, 0xf5, 0x79, 0xa8, 0x45, 0xcb, 
+  0x82, 0xc3, 0x83, 0x17, 0xa6, 0x48, 0x48, 0x27, 
+  0xd3, 0xc2, 0xe1, 0x3f, 0x07, 0x04, 0xcc, 0x65, 
+  0xd0, 0xc8, 0x28, 0xc0, 0xe2, 0x40, 0x5c, 0x5b, 
+  0x38, 0x0b, 0xba, 0xbf, 0xa5, 0x72, 0x72, 0xca, 
+  0x8d, 0x1a, 0x21, 0x75, 0x8b, 0x13, 0xf2, 0x99, 
+  0x67, 0x10, 0x51, 0x81, 0x07, 0x15, 0x60, 0x75, 
+  0x58, 0x2a, 0xb6, 0x9e, 0xd3, 0xca, 0x54, 0xc5, 
+  0x8a, 0x41, 0xce, 0x65, 0x24, 0x4d, 0x15, 0x45, 
+  0xd0, 0xc0, 0x5c, 0x0b, 0xcc, 0xb1, 0xb1, 0x8f, 
+  0x20, 0x60, 0x13, 0x34, 0xee, 0x14, 0xbf, 0x5e, 
+  0x77, 0x4d, 0x03, 0xa0, 0x2c, 0x42, 0x6d, 0x2d, 
+  0xa7, 0x97, 0x2f, 0x98, 0xdb, 0x5c, 0x2d, 0xd5, 
+  0xd1, 0x77, 0xa8, 0x2e, 0x5e, 0x73, 0x81, 0x2d, 
+  0xef, 0xb1, 0xa5, 0x38, 0x38, 0xb9, 0x56, 0xec, 
+  0xd6, 0xb7, 0x64, 0x24, 0x41, 0x6a, 0x2a, 0x71, 
+  0x3d, 0x04, 0x5a, 0x28, 0xa9, 0x99, 0xd6, 0x49, 
+  0x01, 0xc4, 0x16, 0x20, 0xe8, 0xa0, 0xe5, 0x63, 
+  0xe8, 0x53, 0xe9, 0x2f, 0x14, 0x03, 0xb8, 0x35, 
+  0xa0, 0x44, 0x82, 0x2f, 0xdb, 0xd8, 0x1b, 0xeb, 
+  0xd0, 0x3c, 0x58, 0x3d, 0x19, 0x16, 0x1d, 0xd7, 
+  0xb5, 0x1b, 0x60, 0x54, 0xaf, 0xfd, 0xb4, 0x38, 
+  0xd7, 0x7a, 0xc2, 0xa0, 0x62, 0x49, 0x2a, 0xf5, 
+  0x61, 0x33, 0xfa, 0x25, 0xa7, 0xbc, 0x16, 0x27, 
+  0x7d, 0xd4, 0x3f, 0x76, 0xba, 0xbf, 0xcc, 0xb3, 
+  0x9d, 0xdc, 0xd9, 0xc3, 0xd5, 0x3e, 0xd2, 0x0b, 
+  0xfc, 0xb6, 0x58, 0xe8, 0x80, 0x52, 0x06, 0x07, 
+  0xb5, 0xfd, 0x15, 0xb1, 0x6e, 0x5e, 0xf4, 0xb3, 
+  0x76, 0x0a, 0xb5, 0xea, 0xfe, 0x4f, 0xd9, 0xe1, 
+  0xc2, 0x76, 0xbb, 0x02, 0xd9, 0x1e, 0x0f, 0x77, 
+  0xab, 0x4f, 0x79, 0xb5, 0x8c, 0xd2, 0xdc, 0x42, 
+  0x27, 0xef, 0xf5, 0x4e, 0x60, 0x31, 0xa9, 0x4d, 
+  0x54, 0x47, 0xf5, 0xdb, 0x4d, 0x25, 0xec, 0xee, 
+  0x7d, 0x56, 0x5b, 0x78, 0x2b, 0xd1, 0x25, 0xc4, 
+  0x75, 0x96, 0xf9, 0xc8, 0x08, 0xce, 0xfb, 0x9f, 
+  0xe2, 0xf3, 0x1f, 0x6d, 0xb5, 0xb6, 0x21, 0x95, 
+  0x01, 0xf4, 0xca, 0x8a, 0x87, 0xbb, 0x20, 0x49, 
+  0x53, 0x2e, 0x5c, 0xa9, 0xa8, 0x5e, 0xc3, 0x74, 
+  0xb4, 0xa9, 0x96, 0xb4, 0x3b, 0xf8, 0x73, 0x05, 
+  0x6b, 0x37, 0x79, 0x4a, 0x78, 0x2f, 0x82, 0x75, 
+  0xd3, 0x2b, 0x03, 0x6a, 0xda, 0x54, 0xc4, 0xfd, 
+  0xd6, 0xff, 0xef, 0x65, 0xe7, 0x17, 0xba, 0xb5, 
+  0x5c, 0xc9, 0xa8, 0x9a, 0x8f, 0x9a, 0x61, 0x8a, 
+  0xce, 0xa7, 0xdc, 0xc0, 0x2f, 0xf4, 0x21, 0x9a, 
+  0xc6, 0x85, 0x43, 0x2c, 0xe0, 0xca, 0x93, 0x69, 
+  0xae, 0x5d, 0x7b, 0xe3, 0x6b, 0x82, 0x71, 0x4a, 
+  0x8a, 0x91, 0xf1, 0x28, 0x3a, 0xbd, 0x05, 0xac, 
+  0x15, 0x22, 0xea, 0x04, 0x0e, 0xc8, 0xa2, 0xee, 
+  0xf4, 0x1c, 0x52, 0x0e, 0x40, 0x15, 0x4d, 0x8b, 
+  0x03, 0xa0, 0x0f, 0xe9, 0x1a, 0x0b, 0x43, 0x61, 
+  0x85, 0x39, 0xa6, 0x41, 0x78, 0x4b, 0x78, 0x88, 
+  0xf6, 0x9c, 0xf5, 0x70, 0x77, 0x02, 0x2c, 0x0f, 
+  0x4f, 0x00, 0x18, 0xd2, 0xc7, 0x08, 0x41, 0xc1, 
+  0x88, 0x4d, 0x40, 0xc7, 0x99, 0x19, 0x1e, 0x9e, 
+  0xf2, 0xd6, 0x02, 0xc7, 0x80, 0xe1, 0x93, 0xf7, 
+  0x91, 0x8c, 0x85, 0x73, 0x1a, 0x5c, 0xfc, 0x22, 
+  0x74, 0xa7, 0xb4, 0xd8, 0x39, 0x18, 0x4b, 0x97, 
+  0x01, 0xe8, 0xc1, 0x3f, 0xa2, 0x07, 0xf5, 0x80, 
+  0x0f, 0xf4, 0x13, 0x35, 0x02, 0xad, 0x7d, 0x20, 
+  0xc0, 0x1c, 0x14, 0xfa, 0x32, 0xef, 0x41, 0xc3, 
+  0x56, 0x19, 0x23, 0x21, 0x62, 0xe7, 0xf2, 0x02, 
+  0xeb, 0x4d, 0x83, 0x8a, 0x41, 0xc3, 0x07, 0x30, 
+  0x73, 0xf4, 0xea, 0x23, 0x40, 0xe0, 0x9d, 0xae, 
+  0x4a, 0x32, 0x05, 0xc4, 0xe9, 0x2f, 0x5d, 0xae, 
+  0xc1, 0xc5, 0x34, 0x51, 0x22, 0xad, 0xc0, 0x75, 
+  0xbc, 0x07, 0x1e, 0xb3, 0x47, 0xb7, 0x54, 0xf8, 
+  0x39, 0xcd, 0x08, 0x3a, 0x80, 0xea, 0x13, 0xb5, 
+  0xc1, 0xcb, 0x84, 0xac, 0x9b, 0x29, 0x0a, 0x34, 
+  0xfa, 0xe4, 0x83, 0x1a, 0x0e, 0x26, 0x90, 0x72, 
+  0xeb, 0x03, 0xa0, 0xd7, 0x23, 0xa1, 0x92, 0xc0, 
+  0xb1, 0x39, 0xd1, 0x03, 0x83, 0x32, 0x78, 0x09, 
+  0xf5, 0x7f, 0x17, 0x37, 0xd5, 0xa2, 0x31, 0xad, 
+  0xa2, 0xe8, 0x48, 0xa3, 0x3e, 0x6f, 0xec, 0x75, 
+  0xb6, 0xb3, 0xf2, 0xcb, 0x9a, 0x0e, 0xe0, 0x48, 
+  0x36, 0x08, 0x23, 0xe4, 0xa9, 0xd8, 0x5b, 0x6b, 
+  0x1b, 0x38, 0xdf, 0xbb, 0xc4, 0x7d, 0x86, 0x53, 
+  0x14, 0x44, 0x47, 0xf5, 0xf5, 0xca, 0x32, 0x17, 
+  0x86, 0x63, 0x43, 0x09, 0xeb, 0x06, 0x93, 0xfa, 
+  0xde, 0x08, 0xb1, 0x0c, 0x5a, 0xf4, 0x26, 0x1b, 
+  0xab, 0x12, 0xd5, 0x6e, 0xd2, 0xcc, 0x56, 0xc3, 
+  0x1f, 0xa6, 0xcd, 0x10, 0x18, 0x1e, 0x25, 0x65, 
+  0xb6, 0xf7, 0x7d, 0x1a, 0x56, 0x95, 0x8b, 0x22, 
+  0xdd, 0x18, 0x74, 0xe1, 0x53, 0xb0, 0x6f, 0xc1, 
+  0x5e, 0xb9, 0xe1, 0x1e, 0x17, 0x37, 0xe5, 0xbe, 
+  0x9f, 0x06, 0xf8, 0xb9, 0x49, 0x09, 0x94, 0xf7, 
+  0xfa, 0x88, 0x40, 0xde, 0x0d, 0xe5, 0xa4, 0xab, 
+  0x82, 0x4f, 0x48, 0x97, 0x8b, 0x45, 0x17, 0x31, 
+  0x4c, 0xd2, 0x81, 0x5a, 0x7b, 0x7d, 0x3a, 0xbb, 
+  0x02, 0x07, 0xfa, 0xf3, 0x1b, 0xcb, 0x56, 0xc5, 
+  0x0a, 0x62, 0x37, 0x6b, 0xab, 0xff, 0xde, 0x61, 
+  0x68, 0x1a, 0x6e, 0xf6, 0xc2, 0xb5, 0x91, 0x20, 
+  0x07, 0x05, 0x6a, 0x6e, 0x6e, 0xd8, 0xa3, 0x9c, 
+  0x80, 0x3c, 0x4e, 0x8c, 0xc6, 0x96, 0xef, 0x73, 
+  0x35, 0x08, 0x26, 0x2a, 0xdb, 0x0c, 0x2f, 0xdb, 
+  0x3d, 0xb3, 0x94, 0xf9, 0x72, 0xe4, 0x25, 0xca, 
+  0x41, 0xa6, 0x66, 0x83, 0x51, 0xfe, 0xf0, 0xb3, 
+  0xd7, 0x0a, 0x40, 0x77, 0x02, 0x7a, 0xa2, 0x18, 
+  0x43, 0x66, 0x22, 0xcb, 0x3a, 0x1c, 0x40, 0x70, 
+  0x26, 0xa7, 0x02, 0x09, 0x7d, 0x46, 0xd2, 0xab, 
+  0x41, 0x83, 0x41, 0x79, 0x1a, 0x30, 0x0f, 0xab, 
+  0x06, 0x0e, 0x18, 0xa0, 0xc0, 0x48, 0x23, 0xf2, 
+  0x06, 0xd0, 0x64, 0xfd, 0xfe, 0x5c, 0xd7, 0xed, 
+  0x2b, 0x53, 0xbb, 0x79, 0x0c, 0x49, 0x71, 0x70, 
+  0x37, 0x34, 0x7b, 0x77, 0xab, 0xa3, 0x80, 0xa6, 
+  0x89, 0xd7, 0x07, 0x8a, 0x80, 0x24, 0x2d, 0x4f, 
+  0x3c, 0xba, 0xe7, 0x4a, 0x35, 0x22, 0x4d, 0x4f, 
+  0x8b, 0xef, 0x10, 0x87, 0xda, 0xdc, 0xe2, 0x00, 
+  0x21, 0x5f, 0xdb, 0xb4, 0xdc, 0x19, 0xba, 0x11, 
+  0x26, 0x9d, 0x53, 0x50, 0x41, 0xad, 0x73, 0x50, 
+  0x85, 0x2f, 0x77, 0x50, 0x65, 0xa3, 0x20, 0x71, 
+  0x35, 0x71, 0x2e, 0xad, 0x8d, 0x6c, 0x17, 0x06, 
+  0x67, 0xaa, 0xdc, 0x5d, 0x6a, 0x6d, 0x49, 0xdd, 
+  0x7f, 0x32, 0xae, 0x8e, 0x04, 0x95, 0xb2, 0x71, 
+  0x7e, 0x2d, 0x0e, 0xc1, 0x70, 0x7f, 0x35, 0x7f, 
+  0x60, 0x73, 0x06, 0x11, 0xf0, 0xa8, 0x7d, 0xb2, 
+  0x87, 0xbf, 0x6d, 0x07, 0xa4, 0x0d, 0x0f, 0x99, 
+  0xc5, 0x3c, 0xe0, 0x66, 0x0e, 0x9d, 0x3f, 0xa6, 
+  0xae, 0xa7, 0x6b, 0x16, 0x47, 0x43, 0x87, 0x3e, 
+  0x17, 0xb6, 0x36, 0x68, 0x71, 0x00, 0x8b, 0x37, 
+  0x83, 0x08, 0x8c, 0x29, 0x2c, 0xd2, 0x46, 0x98, 
+  0x1b, 0x2a, 0xe1, 0x2c, 0x46, 0x31, 0xe0, 0x5b, 
+  0x1c, 0x86, 0xb0, 0x67, 0xd1, 0x7b, 0xe5, 0xe1, 
+  0xa0, 0xa3, 0x5d, 0x04, 0xc3, 0xe1, 0xeb, 0x50, 
+  0x15, 0xbf, 0xfc, 0x8b, 0x66, 0x4a, 0x85, 0x47, 
+  0x69, 0x16, 0x62, 0x2a, 0xff, 0xff, 0x7c, 0xa1, 
+  0x49, 0x5d, 0xde, 0x44, 0x60, 0xe2, 0x0b, 0xba, 
+  0x1a, 0xf2, 0x11, 0x56, 0x36, 0x85, 0x03, 0xe2, 
+  0x9f, 0xe4, 0x24, 0x14, 0xeb, 0xdd, 0xd6, 0x2b, 
+  0x5c, 0x9b, 0x9c, 0x85, 0x72, 0xae, 0x86, 0x74, 
+  0x89, 0x74, 0xfb, 0x6a, 0x0b, 0xee, 0xa3, 0x18, 
+  0xae, 0x47, 0x1c, 0xb0, 0xa6, 0x93, 0x44, 0xcb, 
+  0xd2, 0x51, 0x33, 0xf5, 0x4a, 0x90, 0x58, 0xba, 
+  0xa6, 0x50, 0x48, 0x60, 0xb1, 0x95, 0x4a, 0xc7, 
+  0x3c, 0xd6, 0x99, 0x9f, 0x51, 0xec, 0x61, 0x42, 
+  0xc8, 0x3b, 0xf6, 0xda, 0xc4, 0x4b, 0x53, 0x4b, 
+  0x1c, 0x44, 0x3f, 0x69, 0x2e, 0x79, 0xb6, 0xb6, 
+  0x55, 0xa7, 0x62, 0x9c, 0xd5, 0x14, 0xd5, 0xad, 
+  0x7f, 0x72, 0x89, 0xa0, 0x0c, 0xa2, 0xea, 0xc2, 
+  0x80, 0xd8, 0x3e, 0x11, 0xc4, 0x94, 0x9e, 0x1c, 
+  0x31, 0x18, 0x51, 0xde, 0xf0, 0x70, 0x7e, 0xee, 
+  0x16, 0x95, 0xa9, 0x2b, 0x0a, 0xa2, 0xeb, 0x25, 
+  0xa5, 0x55, 0x11, 0xb1, 0x49, 0xa6, 0xba, 0x4a, 
+  0x48, 0x1c, 0x00, 0xf0, 0xa0, 0x88, 0xf5, 0xbc, 
+  0xc9, 0x6f, 0x70, 0x3d, 0x93, 0xa7, 0x91, 0xd6, 
+  0x3d, 0x03, 0x8f, 0xfe, 0x8b, 0xd6, 0x05, 0xc1, 
+  0x76, 0x96, 0x6e, 0x83, 0xce, 0xff, 0xfb, 0xc3, 
+  0xda, 0xf0, 0xa1, 0x65, 0x97, 0xa2, 0x8b, 0xbf, 
+  0xa5, 0x10, 0x89, 0x02, 0xce, 0x23, 0x2d, 0xb2, 
+  0x55, 0x0e, 0x4f, 0x53, 0x78, 0xdf, 0xf7, 0x3d, 
+  0xab, 0x14, 0xbf, 0xc8, 0x0a, 0xe8, 0xfd, 0x79, 
+  0xb0, 0xa4, 0xa4, 0x1c, 0x41, 0x13, 0x64, 0x46, 
+  0x28, 0x4c, 0xb3, 0x24, 0x02, 0xba, 0x58, 0x50, 
+  0x14, 0xa7, 0x67, 0x35, 0x7e, 0xf2, 0xa2, 0x7b, 
+  0xb6, 0x0c, 0x33, 0xa8, 0x4e, 0xeb, 0xee, 0x74, 
+  0xb6, 0x03, 0xb8, 0x0b, 0x01, 0x71, 0x0d, 0x65, 
+  0x91, 0x7a, 0x0e, 0x05, 0x8f, 0x68, 0x48, 0x96, 
+  0x31, 0xb0, 0x39, 0xcc, 0xd4, 0x41, 0x4c, 0xec, 
+  0xfa, 0x22, 0xbc, 0xb5, 0x09, 0x07, 0x36, 0x77, 
+  0x8b, 0xe0, 0xaf, 0x5f, 0x58, 0xb1, 0xb9, 0x49, 
+  0x4d, 0x3b, 0xca, 0x87, 0xb6, 0x70, 0x92, 0x82, 
+  0xf1, 0xe5, 0xe8, 0xdb, 0x7b, 0x65, 0x2c, 0xd8, 
+  0xf1, 0x84, 0x08, 0x7f, 0x67, 0xf0, 0x40, 0x69, 
+  0x24, 0xd4, 0x6b, 0x53, 0x7c, 0x74, 0x9d, 0xe8, 
+  0x88, 0x2b, 0xab, 0xba, 0x49, 0xc4, 0x34, 0x55, 
+  0x81, 0x60, 0x0b, 0xb3, 0xc2, 0x30, 0x22, 0xa9, 
+  0xee, 0x82, 0x2b, 0x3a, 0x0b, 0x00, 0x5c, 0x6c, 
+  0x95, 0x04, 0xe5, 0xef, 0x46, 0x22, 0x74, 0x98, 
+  0x52, 0x2a, 0xd7, 0x6f, 0x68, 0x11, 0x85, 0x29, 
+  0xfd, 0xbd, 0x28, 0xc8, 0x4f, 0xb6, 0xde, 0x41, 
+  0x13, 0x17, 0x46, 0x46, 0xca, 0x3e, 0x69, 0xd5, 
+  0x3f, 0xde, 0x02, 0x69, 0x86, 0x47, 0xe3, 0xe6, 
+  0x03, 0xb6, 0x7d, 0x00, 0x9f, 0x68, 0xc1, 0x1b, 
+  0xd4, 0xd2, 0xf5, 0x7b, 0x2d, 0x6d, 0xb6, 0x74, 
+  0x09, 0xff, 0x46, 0x5c, 0x87, 0x15, 0x53, 0xd4, 
+  0x1a, 0x30, 0xe0, 0x60, 0x31, 0x0a, 0xf5, 0x03, 
+  0x38, 0x49, 0x0e, 0x6b, 0x9d, 0x12, 0x62, 0xaf, 
+  0xe1, 0x57, 0xd2, 0xb0, 0xb5, 0x86, 0x0f, 0x36, 
+  0x3b, 0x4c, 0xda, 0xcd, 0x46, 0x1b, 0xef, 0x0b, 
+  0x46, 0x07, 0xf6, 0x23, 0x41, 0x42, 0x69, 0xcb, 
+  0x91, 0x07, 0xaf, 0x78, 0xb9, 0x21, 0x20, 0x9c, 
+  0xb5, 0x00, 0x4c, 0x13, 0x35, 0xcf, 0x17, 0x08, 
+  0x62, 0x5e, 0xb6, 0x05, 0xb3, 0xd9, 0x28, 0x78, 
+  0x0c, 0x2f, 0x21, 0x32, 0x21, 0x30, 0xad, 0x4c, 
+  0xb6, 0xa5, 0x56, 0xda, 0xdc, 0x46, 0x4d, 0x3a, 
+  0xa6, 0x2d, 0xcb, 0x94, 0x16, 0x26, 0xc1, 0x75, 
+  0x0b, 0x8a, 0x6f, 0xf4, 0xaa, 0x0d, 0x9d, 0xae, 
+  0xb8, 0xf8, 0x78, 0x3c, 0x5d, 0x4f, 0xd5, 0x35, 
+  0x3a, 0x57, 0xd2, 0x97, 0xce, 0x79, 0x80, 0x24, 
+  0x0e, 0xed, 0x3e, 0x58, 0x39, 0x90, 0x16, 0x00, 
+  0x9d, 0x45, 0x74, 0x65, 0xc0, 0x1c, 0x48, 0x43, 
+  0xc4, 0x7d, 0xe6, 0xf4, 0x9b, 0x5e, 0x61, 0x6a, 
+  0xeb, 0x74, 0xd2, 0xc0, 0x9a, 0x9b, 0x3b, 0xb3, 
+  0x0d, 0x5b, 0xc0, 0x5d, 0x65, 0xba, 0x4a, 0x32, 
+  0x19, 0x02, 0xea, 0x7b, 0x21, 0xbb, 0x1f, 0x8c, 
+  0xce, 0x77, 0x0a, 0x25, 0x8b, 0x83, 0x81, 0x73, 
+  0x41, 0xf7, 0xa1, 0xb1, 0x9b, 0xfe, 0x4f, 0xc1, 
+  0x17, 0x51, 0x9b, 0xe1, 0x28, 0x2d, 0xa2, 0x4a, 
+  0x4b, 0x4d, 0xbc, 0xad, 0x33, 0x4a, 0x27, 0x10, 
+  0xd2, 0x50, 0x1c, 0xb1, 0x36, 0x50, 0x48, 0x65, 
+  0x35, 0xf8, 0x88, 0x28, 0x6b, 0x82, 0xc0, 0x1c, 
+  0x80, 0xa0, 0xfd, 0x5d, 0x17, 0x78, 0x13, 0xeb, 
+  0xcb, 0x5d, 0x85, 0x08, 0x51, 0x92, 0xf4, 0x1c, 
+  0xf4, 0xa4, 0xe2, 0x35, 0x9f, 0x08, 0xa9, 0xa4, 
+  0x08, 0x05, 0x32, 0x6d, 0x16, 0xf1, 0x7b, 0xc1, 
+  0x92, 0xc7, 0xd7, 0x8b, 0x2c, 0x27, 0xdf, 0x4e, 
+  0x9a, 0xe6, 0x54, 0x40, 0xe4, 0x21, 0x5a, 0xf9, 
+  0xc6, 0x24, 0xef, 0x65, 0x07, 0x2e, 0x2b, 0x4d, 
+  0x4f, 0x2a, 0x09, 0x6c, 0xe8, 0xc7, 0x88, 0x05, 
+  0xc7, 0x50, 0xb2, 0xde, 0xa2, 0xa1, 0x80, 0x64, 
+  0x0b, 0xb3, 0x36, 0xcd, 0x26, 0xde, 0x98, 0x8a, 
+  0xe4, 0x84, 0x17, 0x54, 0x2c, 0x54, 0x0e, 0x18, 
+  0x38, 0xa6, 0xb5, 0x0a, 0x46, 0x41, 0x2f, 0x1c, 
+  0x74, 0x80, 0xee, 0xf1, 0x7e, 0x74, 0x29, 0x8b, 
+  0xd4, 0xdd, 0xb5, 0x64, 0x74, 0x17, 0xcf, 0xcf, 
+  0xd8, 0x32, 0x34, 0xf9, 0xfc, 0x58, 0x64, 0xb5, 
+  0x44, 0x0e, 0x34, 0x41, 0x17, 0x15, 0xeb, 0xe0, 
+  0xa3, 0x49, 0x08, 0x3f, 0xe8, 0xc8, 0x8d, 0x5e, 
+  0xde, 0xa2, 0xb5, 0x00, 0x3a, 0x05, 0x78, 0xca, 
+  0x0a, 0xf5, 0xe5, 0x09, 0xb0, 0x5f, 0xea, 0x33, 
+  0x73, 0xce, 0x12, 0xde, 0x89, 0xa2, 0x49, 0x17, 
+  0x5a, 0x70, 0x07, 0xc1, 0x3b, 0xf5, 0x4c, 0x58, 
+  0xf6, 0xbe, 0x51, 0x49, 0x0f, 0xee, 0x8c, 0x11, 
+  0x03, 0x85, 0x5a, 0x29, 0x35, 0xd3, 0x44, 0x4c, 
+  0x63, 0x24, 0x0c, 0xc5, 0x2b, 0x2d, 0x9c, 0x46, 
+  0x50, 0x28, 0xd3, 0x88, 0xc4, 0x34, 0xbb, 0xb0, 
+  0x81, 0x41, 0x3d, 0xcf, 0x22, 0x58, 0x63, 0x43, 
+  0x13, 0xd3, 0x70, 0x64, 0x28, 0xc6, 0xcb, 0x90, 
+  0x6b, 0x9d, 0xd8, 0x38, 0x74, 0xfe, 0xf8, 0xa5, 
+  0x18, 0x0f, 0x08, 0xa3, 0x76, 0x8c, 0xa0, 0xbc, 
+  0x85, 0xc8, 0x2f, 0x0a, 0x16, 0x41, 0xc8, 0x3a, 
+  0x02, 0xe7, 0x5e, 0x03, 0xd2, 0x49, 0xde, 0x53, 
+  0x5c, 0x5c, 0x85, 0xf0, 0xa5, 0x69, 0x10, 0xf4, 
+  0x28, 0x65, 0x48, 0x38, 0x52, 0x11, 0x7b, 0x78, 
+  0x8b, 0x9d, 0x07, 0x04, 0x53, 0x3b, 0xd4, 0x75, 
+  0x41, 0xdd, 0x7c, 0xb1, 0xb4, 0x43, 0x21, 0x33, 
+  0xa0, 0xfd, 0xf0, 0x01, 0xee, 0x5e, 0x23, 0xd0, 
+  0x1e, 0x4c, 0xef, 0x05, 0xe2, 0xe1, 0x47, 0x8b, 
+  0x21, 0x84, 0x1a, 0x7b, 0xa8, 0x14, 0x03, 0x8e, 
+  0xb1, 0x5c, 0xf4, 0x92, 0x42, 0x55, 0x86, 0x92, 
+  0x69, 0x69, 0x42, 0x5b, 0x6a, 0xf1, 0x01, 0x20, 
+  0x4b, 0xa7, 0x0b, 0x03, 0x82, 0x36, 0x8b, 0xa8, 
+  0x0d, 0x10, 0xe1, 0x88, 0x38, 0x62, 0x2e, 0x13, 
+  0xe0, 0x7a, 0x48, 0x00, 0xc6, 0xb3, 0xbd, 0xe8, 
+  0x49, 0xaf, 0xb8, 0xed, 0x3b, 0x10, 0xa2, 0x15, 
+  0x4a, 0xd4, 0x30, 0x7e, 0x9c, 0xe9, 0xb0, 0x58, 
+  0x92, 0x04, 0x8d, 0x2a, 0xc8, 0xcf, 0xe9, 0xcc, 
+  0x8b, 0xa3, 0x0c, 0x89, 0xf5, 0x9c, 0xe5, 0xc5, 
+  0x08, 0xca, 0xd4, 0x95, 0x15, 0x21, 0xe2, 0xc8, 
+  0xc6, 0x93, 0xc2, 0x40, 0x70, 0x62, 0xf7, 0x20, 
+  0x39, 0x60, 0xaa, 0x5a, 0x48, 0x2e, 0x22, 0xd3, 
+  0x47, 0x26, 0x2c, 0xb8, 0xc8, 0x88, 0xaf, 0x11, 
+  0xf0, 0x32, 0x07, 0x02, 0x6c, 0xf1, 0x0f, 0x38, 
+  0x84, 0x1d, 0x5d, 0x96, 0x07, 0x70, 0x1c, 0x2b, 
+  0xb9, 0xc2, 0x50, 0x9b, 0x4e, 0x45, 0xe3, 0x25, 
+  0x8f, 0xee, 0x14, 0x72, 0x2c, 0x68, 0x29, 0x80, 
+  0x46, 0x58, 0xa1, 0x11, 0x20, 0x38, 0x9b, 0x70, 
+  0x90, 0x1c, 0x2e, 0x0c, 0x84, 0xcc, 0x7e, 0x27, 
+  0x2a, 0x16, 0x07, 0x0a, 0x1a, 0x88, 0x0f, 0x41, 
+  0xff, 0xf8, 0x61, 0x44, 0xd8, 0x60, 0x18, 0x85, 
+  0x53, 0x03, 0x20, 0x73, 0xa2, 0x07, 0x6b, 0xee, 
+  0x92, 0xc7, 0x4f, 0x0d, 0xf6, 0xf0, 0x17, 0x1a, 
+  0x59, 0xde, 0x9b, 0x28, 0x07, 0x04, 0xda, 0xca, 
+  0x2b, 0x6a, 0x37, 0x58, 0x6b, 0xaf, 0x83, 0x13, 
+  0x60, 0xe7, 0x6e, 0xc4, 0x48, 0x21, 0x0e, 0x58, 
+  0x92, 0x83, 0x82, 0x78, 0x8b, 0x23, 0x58, 0xd9, 
+  0x0d, 0x24, 0x7d, 0xb9, 0x2c, 0x07, 0x2c, 0x0e, 
+  0x42, 0x09, 0x98, 0xb0, 0xd8, 0x4d, 0x23, 0x10, 
+  0x70, 0xa7, 0x73, 0x86, 0xc6, 0x0b, 0x04, 0x9f, 
+  0xfb, 0x56, 0x29, 0x07, 0x23, 0x8f, 0x98, 0x0e, 
+  0x8f, 0x63, 0x0a, 0x50, 0x76, 0x29, 0x28, 0x26, 
+  0x3c, 0x5f, 0x02, 0xfb, 0x51, 0x9b, 0xb0, 0x61, 
+  0xc0, 0x70, 0xbc, 0x17, 0x29, 0xc0, 0xcc, 0x1d, 
+  0x08, 0x62, 0xca, 0x72, 0xf0, 0xa4, 0xfd, 0x5d, 
+  0x2c, 0x58, 0xd5, 0x5c, 0x1c, 0x2a, 0x4e, 0xf7, 
+  0x0a, 0x01, 0xfa, 0xff, 0xff, 0xd5, 0x09, 0xa8, 
+  0x8c, 0x1c, 0x30, 0x25, 0x09, 0xd3, 0xd9, 0x30, 
+  0xd3, 0xdb, 0x94, 0x13, 0x74, 0xc8, 0x71, 0x1a, 
+  0x21, 0x87, 0x43, 0x10, 0x89, 0x5a, 0x6b, 0x91, 
+  0xd5, 0x66, 0xa0, 0xb0, 0x1c, 0x30, 0x58, 0x64, 
+  0x15, 0xfe, 0x36, 0x04, 0x7b, 0x4d, 0x23, 0x07, 
+  0x3a, 0xf1, 0x0a, 0xc2, 0x7d, 0x3b, 0xa1, 0x91, 
+  0xa4, 0x62, 0x96, 0xb1, 0xae, 0x83, 0xf6, 0xc0, 
+  0x07, 0xae, 0x6c, 0x11, 0x45, 0xf4, 0x1c, 0x35, 
+  0x6a, 0x28, 0x39, 0x60, 0x71, 0x1b, 0xf4, 0x39, 
+  0x44, 0x41, 0xae, 0xf1, 0x07, 0x01, 0xd4, 0x89, 
+  0xf6, 0x94, 0x1f, 0x7d, 0xab, 0x1b, 0x20, 0xdb, 
+  0x22, 0x1e, 0xa2, 0x07, 0x09, 0x8b, 0xe3, 0xf4, 
+  0xda, 0x82, 0x8c, 0x25, 0x01, 0xc0, 0xe2, 0x36, 
+  0x59, 0xa0, 0xe2, 0x42, 0x82, 0x64, 0x78, 0xb0, 
+  0x66, 0x0e, 0x59, 0xdd, 0x63, 0x65, 0x0b, 0x02, 
+  0x6a, 0x8c, 0xc2, 0xad, 0x7a, 0x90, 0xa3, 0xa0, 
+  0xbd, 0xda, 0x53, 0xd9, 0xd5, 0x82, 0x4f, 0x2c, 
+  0x37, 0xd8, 0x50, 0x8c, 0xa0, 0x2a, 0x70, 0x5e, 
+  0x47, 0x4a, 0xa9, 0x28, 0xaf, 0x4f, 0x58, 0x88, 
+  0x31, 0x29, 0x19, 0x76, 0x8c, 0xc8, 0xbf, 0x0d, 
+  0xc1, 0x56, 0xe7, 0x0a, 0x05, 0xe5, 0x20, 0xe8, 
+  0xe6, 0xb0, 0x3b, 0xb7, 0xa0, 0xe1, 0x80, 0xaa, 
+  0xa0, 0x23, 0xd7, 0x74, 0xd5, 0x01, 0xfc, 0x19, 
+  0x85, 0x13, 0x01, 0xc1, 0x91, 0x1b, 0xec, 0x28, 
+  0x80, 0xb1, 0xe2, 0xc7, 0x6a, 0x74, 0x07, 0x2c, 
+  0x31, 0x15, 0xd8, 0xbd, 0xb7, 0x82, 0xe2, 0x1d, 
+  0x3c, 0xa2, 0x83, 0x97, 0x09, 0x3a, 0xc0, 0xb1, 
+  0x34, 0x50, 0x0b, 0x87, 0x6c, 0xc8, 0xa7, 0x6e, 
+  0x64, 0x37, 0xb7, 0x91, 0x1f, 0x09, 0x0a, 0x38, 
+  0x34, 0x8c, 0x97, 0x80, 0xe5, 0x8d, 0x94, 0x0a, 
+  0xd6, 0xe9, 0x24, 0x18, 0xae, 0x34, 0xd7, 0xd2, 
+  0x94, 0x20, 0x36, 0x34, 0x7c, 0x29, 0xe9, 0xb0, 
+  0x71, 0x3e, 0xe2, 0x08, 0x69, 0xde, 0x14, 0x8b, 
+  0xca, 0x01, 0x32, 0x67, 0x64, 0x43, 0x85, 0x07, 
+  0xf4, 0xdf, 0x04, 0xdb, 0x88, 0x38, 0xb0, 0xbc, 
+  0x32, 0x44, 0x14, 0x4f, 0x10, 0xa8, 0x34, 0x89, 
+  0x10, 0x38, 0x28, 0x7c, 0xe2, 0x0a, 0x0e, 0x17, 
+  0x04, 0xae, 0xfd, 0x78, 0x5d, 0x12, 0xdc, 0xde, 
+  0x73, 0x9c, 0x17, 0x85, 0x2f, 0x79, 0xc5, 0xbb, 
+  0x2c, 0x21, 0x6b, 0x92, 0x14, 0x92, 0x9f, 0x9e, 
+  0x0c, 0xd6, 0x20, 0x99, 0x28, 0xae, 0x27, 0x22, 
+  0x6d, 0xd9, 0xc4, 0x41, 0x99, 0xfd, 0x71, 0x42, 
+  0x25, 0x8a, 0x41, 0xd2, 0x1c, 0x60, 0xe3, 0xfa, 
+  0x14, 0x70, 0xa4, 0x8a, 0xaf, 0xa5, 0xd1, 0x90, 
+  0x26, 0x42, 0x2e, 0x53, 0x42, 0xe8, 0x0e, 0x0a, 
+  0x37, 0x27, 0x69, 0x29, 0x21, 0x41, 0x3c, 0xf6, 
+  0xf2, 0x21, 0xe5, 0x07, 0x48, 0x7a, 0x49, 0xd0, 
+  0x5c, 0xe9, 0xc9, 0x25, 0x0c, 0xa7, 0x02, 0xa9, 
+  0x9d, 0x17, 0x8c, 0x85, 0xdd, 0x05, 0xf6, 0x83, 
+  0x31, 0x8f, 0x41, 0xc2, 0xa8, 0x46, 0x0e, 0xa0, 
+  0xe0, 0x5f, 0x3c, 0x19, 0xd1, 0x4e, 0x9e, 0x40, 
+  0x89, 0x60, 0x5e, 0xcf, 0x60, 0x38, 0x07, 0xd4, 
+  0x20, 0xba, 0x7c, 0x28, 0xe8, 0x38, 0x62, 0xe9, 
+  0x25, 0xe1, 0xa1, 0x90, 0x38, 0x9a, 0xac, 0x45, 
+  0xaf, 0xa5, 0x8b, 0x21, 0xea, 0x23, 0x60, 0xe7, 
+  0x68, 0x8c, 0xa3, 0x81, 0x4c, 0xc3, 0x74, 0xd7, 
+  0x03, 0x22, 0x3e, 0xb8, 0xb8, 0x26, 0x64, 0x24, 
+  0xa4, 0xa7, 0xb4, 0xe6, 0x14, 0x12, 0x05, 0x52, 
+  0x0f, 0x45, 0x00, 0x19, 0xfc, 0x0e, 0x0a, 0x34, 
+  0x19, 0x03, 0x81, 0x7f, 0x8d, 0x34, 0xf7, 0x02, 
+  0x39, 0x8b, 0x8b, 0x90, 0x04, 0x52, 0x14, 0xb8, 
+  0xb8, 0x2c, 0x42, 0x58, 0x0b, 0x98, 0x9e, 0x51, 
+  0xc0, 0xc5, 0x68, 0x11, 0xe8, 0x03, 0x81, 0xc0, 
+  0xbf, 0x66, 0x81, 0xd5, 0xd2, 0xb9, 0x41, 0x27, 
+  0x02, 0x63, 0x11, 0xa3, 0x3f, 0x57, 0x9e, 0x73, 
+  0xbc, 0xb1, 0x09, 0x4f, 0x08, 0x37, 0x30, 0x94, 
+  0xe6, 0x93, 0x8b, 0xa3, 0x36, 0x6e, 0x00, 0xe1, 
+  0xae, 0xa8, 0x91, 0x83, 0x8d, 0x12, 0x85, 0x4a, 
+  0x8a, 0x1b, 0x27, 0xd3, 0xd3, 0x88, 0xc3, 0x07, 
+  0xcc, 0x80, 0xe0, 0x5c, 0xcc, 0xea, 0xc1, 0x90, 
+  0x2c, 0x5d, 0x3c, 0xa0, 0xe0, 0x9e, 0xad, 0x62, 
+  0x37, 0xc5, 0xe2, 0xa1, 0x40, 0x84, 0x2b, 0x82, 
+  0xb0, 0x5d, 0x3e, 0x73, 0xbd, 0x07, 0x0b, 0xc2, 
+  0x77, 0x16, 0x25, 0x17, 0x70, 0xd8, 0x38, 0x69, 
+  0x08, 0xb4, 0xcb, 0x0e, 0x05, 0x14, 0x38, 0x27, 
+  0x48, 0xaa, 0xa1, 0x85, 0x10, 0x07, 0xa3, 0x3d, 
+  0x54, 0x66, 0x18, 0x03, 0x8f, 0x1b, 0x3a, 0x4a, 
+  0x27, 0xd7, 0xbb, 0x01, 0xd0, 0xfe, 0xea, 0xf3, 
+  0xa6, 0xf8, 0x43, 0x86, 0x10, 0x1c, 0x76, 0x86, 
+  0x34, 0x62, 0x4a, 0x0b, 0xc4, 0xb9, 0xd3, 0x4e, 
+  0xd7, 0xf9, 0xa0, 0xb1, 0x24, 0x14, 0x50, 0xcf, 
+  0x86, 0x81, 0x3d, 0xe5, 0x42, 0xb7, 0x68, 0x2e, 
+  0xf4, 0x92, 0x14, 0x44, 0x63, 0x2e, 0x1d, 0x7e, 
+  0xaf, 0x42, 0x6d, 0x7f, 0x64, 0x29, 0x0a, 0xb5, 
+  0xec, 0x40, 0x0e, 0x04, 0xef, 0xbd, 0xe7, 0x56, 
+  0x40, 0x0b, 0x0a, 0x79, 0x8c, 0x7b, 0xc0, 0xa7, 
+  0x3d, 0xaf, 0x94, 0xde, 0x21, 0x45, 0xc0, 0xc0, 
+  0x17, 0x33, 0x31, 0x0a, 0xcb, 0x92, 0x03, 0x8f, 
+  0xb5, 0xd0, 0xf7, 0x9d, 0x3b, 0x56, 0x61, 0x21, 
+  0x25, 0x19, 0x82, 0xee, 0xf3, 0x92, 0xa3, 0x76, 
+  0xbd, 0xe7, 0xf6, 0x76, 0xf6, 0xe4, 0xc0, 0x29, 
+  0x81, 0xb5, 0xd0, 0x70, 0xad, 0xff, 0x3c, 0xba, 
+  0xd3, 0x6d, 0x96, 0xf5, 0x10, 0x2f, 0xe3, 0xb3, 
+  0x05, 0xc4, 0x53, 0xdb, 0x61, 0x20, 0x3a, 0x9f, 
+  0x9d, 0x35, 0xca, 0x4f, 0xa6, 0xe2, 0x90, 0x72, 
+  0xdd, 0x09, 0x21, 0x70, 0x7e, 0xe8, 0x00, 0xf2, 
+  0xe0, 0x3d, 0x60, 0x1d, 0x42, 0x5d, 0x20, 0x6d, 
+  0x82, 0xb6, 0xea, 0xe8, 0x04, 0xda, 0xfa, 0x48, 
+  0x8b, 0xb0, 0x96, 0xa0, 0x07, 0x2c, 0x4f, 0xed, 
+  0xbc, 0x5b, 0xa0, 0xe9, 0x05, 0x0f, 0x3a, 0x4a, 
+  0x82, 0x0a, 0xfe, 0x62, 0x13, 0xb1, 0x79, 0xde, 
+  0x8b, 0x88, 0x34, 0xe5, 0x1a, 0x01, 0x70, 0x57, 
+  0x2b, 0x82, 0xc3, 0x91, 0x72, 0x1a, 0xad, 0x62, 
+  0x0e, 0x83, 0x89, 0x57, 0x81, 0x27, 0x50, 0x2f, 
+  0x07, 0x3f, 0x07, 0x23, 0x3f, 0x17, 0xfc, 0xc4, 
+  0x1d, 0xda, 0x18, 0x11, 0x3b, 0x6f, 0x50, 0x62, 
+  0xc2, 0xf4, 0x40, 0x9d, 0xbc, 0x52, 0x88, 0x5c, 
+  0x2b, 0x77, 0x28, 0x6e, 0xb9, 0x20, 0x2e, 0xad, 
+  0x42, 0x68, 0x9f, 0x5e, 0x64, 0xbd, 0x36, 0x53, 
+  0x0a, 0x4a, 0x46, 0x8d, 0x64, 0x2b, 0x22, 0x3b, 
+  0xa6, 0xf5, 0x06, 0x76, 0x12, 0x89, 0xba, 0xc3, 
+  0x24, 0x23, 0x10, 0xc0, 0x87, 0x92, 0xf0, 0xe6, 
+  0xbe, 0x2b, 0x88, 0x6d, 0x34, 0x18, 0x1f, 0x95, 
+  0x89, 0x01, 0x7b, 0xed, 0x07, 0x20, 0x0c, 0x44, 
+  0xdb, 0x69, 0xae, 0x12, 0x20, 0x20, 0x8b, 0x40, 
+  0x9e, 0x2c, 0x4f, 0x10, 0x9b, 0x5c, 0x24, 0x79, 
+  0x78, 0x85, 0x12, 0x31, 0x98, 0x56, 0xf6, 0xde, 
+  0xa2, 0xb4, 0x66, 0x43, 0x54, 0xa9, 0x76, 0xbc, 
+  0xf0, 0x1c, 0x45, 0xba, 0x1a, 0x21, 0x28, 0x07, 
+  0x3f, 0x81, 0x1e, 0x83, 0x06, 0x5d, 0x0c, 0x89, 
+  0xa7, 0x94, 0x93, 0x80, 0xbd, 0xe9, 0xa0, 0xc3, 
+  0xa0, 0x3c, 0xee, 0x9c, 0xf2, 0x12, 0x03, 0x85, 
+  0x4f, 0x80, 0xea, 0x7a, 0xa2, 0xc8, 0x10, 0xae, 
+  0x8c, 0x82, 0x46, 0x28, 0xc1, 0xc2, 0xf0, 0x77, 
+  0x48, 0x69, 0xae, 0x48, 0x2b, 0xab, 0xe4, 0x0b, 
+  0x5e, 0xa3, 0x91, 0x61, 0x5e, 0x5c, 0xda, 0x34, 
+  0x44, 0xbd, 0xa4, 0x0d, 0x7e, 0x50, 0x73, 0xba, 
+  0xf4, 0x1f, 0xbf, 0xff, 0xff, 0x6a, 0x20, 0xa6, 
+  0x27, 0xf9, 0xc0, 0x7a, 0x0f, 0xff, 0xcf, 0xf5, 
+  0xd1, 0xae, 0x15, 0x65, 0x28, 0x90, 0x84, 0xd3, 
+  0x0a, 0x2f, 0x06, 0x00, 0xe2, 0x3f, 0x83, 0x4d, 
+  0x3f, 0x10, 0xac, 0x52, 0x0e, 0x3b, 0x81, 0xd1, 
+  0x7e, 0x06, 0x01, 0x14, 0x82, 0x3a, 0x04, 0x02, 
+  0xe4, 0x76, 0x1e, 0xe0, 0xe0, 0x5d, 0x52, 0x95, 
+  0xdd, 0xa7, 0xb8, 0x0b, 0x14, 0x00, 0xe0, 0xc8, 
+  0xeb, 0x58, 0xd8, 0xc4, 0x30, 0x21, 0xe0, 0xf4, 
+  0x30, 0x01, 0x84, 0xf4, 0x31, 0x18, 0x02, 0x7a, 
+  0x94, 0x2c, 0x15, 0xc4, 0xda, 0xc4, 0x78, 0x62, 
+  0x32, 0x8b, 0x42, 0x45, 0x81, 0xc5, 0x24, 0x71, 
+  0x01, 0x74, 0xe0, 0xc8, 0x90, 0x1c, 0x6c, 0x94, 
+  0x4d, 0x48, 0xb4, 0xf4, 0x37, 0x0d, 0x03, 0x89, 
+  0x0f, 0x38, 0x67, 0x60, 0x3f, 0xbc, 0x00, 0x6c, 
+  0x5e, 0x0e, 0x41, 0x4d, 0x85, 0x76, 0x02, 0xef, 
+  0x5e, 0x41, 0xcb, 0xd0, 0x70, 0x64, 0x85, 0x62, 
+  0x79, 0xd1, 0x80, 0xb8, 0x1c, 0x27, 0x70, 0x1f, 
+  0xdf, 0xff, 0xf7, 0x20, 0xa3, 0x25, 0x22, 0xd3, 
+  0x8b, 0x9e, 0x02, 0x1e, 0x5c, 0x1c, 0x11, 0xae, 
+  0xa3, 0x3a, 0xb7, 0xb2, 0x8b, 0xab, 0xe0, 0xb1, 
+  0x12, 0xf0, 0x1c, 0x2e, 0x0a, 0x12, 0xbc, 0x95, 
+  0x0f, 0x6a, 0x09, 0x2f, 0x45, 0xeb, 0x40, 0x1c, 
+  0x43, 0xcd, 0x59, 0x0b, 0xe2, 0x6a, 0x5f, 0x43, 
+  0x4a, 0x09, 0x54, 0xd3, 0x62, 0x9f, 0x65, 0x88, 
+  0x94, 0x8c, 0xaa, 0xc2, 0xfa, 0xfe, 0x55, 0x2c, 
+  0xe7, 0x82, 0xad, 0x6d, 0x41, 0xcc, 0x19, 0x22, 
+  0xe0, 0xa7, 0x31, 0x53, 0x91, 0x03, 0xf5, 0x17, 
+  0xfe, 0x2e, 0x29, 0x26, 0x4c, 0xb1, 0xb9, 0x2f, 
+  0x5b, 0x80, 0x8c, 0xb8, 0x61, 0x41, 0x77, 0x41, 
+  0xef, 0x11, 0xd4, 0x06, 0x86, 0x24, 0x5e, 0x44, 
+  0x2b, 0x8c, 0xd1, 0x14, 0x93, 0x32, 0xfc, 0x5b, 
+  0x51, 0x0a, 0xb4, 0xe5, 0x64, 0x3c, 0xb4, 0xd8, 
+  0x39, 0x18, 0x51, 0x48, 0x41, 0xcb, 0x70, 0x9f, 
+  0x70, 0x32, 0x40, 0x15, 0x4a, 0x88, 0x0e, 0x46, 
+  0x19, 0x84, 0x70, 0xd2, 0xe7, 0xf5, 0xe7, 0x81, 
+  0xaa, 0xe7, 0xdf, 0xe8, 0x69, 0x25, 0x36, 0x48, 
+  0x0e, 0x42, 0x14, 0x4d, 0xa6, 0xf2, 0x92, 0xac, 
+  0x49, 0xd2, 0x66, 0x85, 0x01, 0x28, 0xb8, 0x13, 
+  0x19, 0x6b, 0x78, 0x2e, 0x7e, 0xbf, 0xf8, 0x13, 
+  0xee, 0x50, 0x71, 0xcf, 0x20, 0x7f, 0x20, 0x30, 
+  0x2c, 0x34, 0x13, 0x5b, 0xb2, 0x31, 0x8a, 0xe2, 
+  0xf7, 0x34, 0x83, 0x31, 0xa6, 0xbe, 0x99, 0x56, 
+  0x1b, 0x6b, 0xb4, 0xa8, 0xf9, 0xca, 0x31, 0x1a, 
+  0x39, 0x50, 0x2c, 0x0e, 0x90, 0x1c, 0x73, 0xdc, 
+  0x9d, 0x5d, 0x6e, 0x22, 0xa6, 0x90, 0x9e, 0x5a, 
+  0xb2, 0x0e, 0x13, 0x45, 0xe7, 0xb3, 0xa0, 0xc4, 
+  0xcf, 0xbd, 0x43, 0x4d, 0x83, 0x06, 0x50, 0xe5, 
+  0x81, 0x6e, 0x00, 0xee, 0x00, 0xe8, 0xe9, 0xb8, 
+  0x52, 0x41, 0xec, 0x1b, 0x51, 0x75, 0x80, 0x99, 
+  0x57, 0xd1, 0x75, 0xd0, 0x94, 0x12, 0x0b, 0x89, 
+  0xfc, 0x17, 0x44, 0x25, 0x20, 0xb9, 0x53, 0x79, 
+  0x67, 0x3b, 0xf5, 0x22, 0x26, 0x69, 0x25, 0x42, 
+  0xe5, 0x71, 0x9c, 0xa1, 0xd0, 0x31, 0x5f, 0x6c, 
+  0x9b, 0x56, 0x35, 0x41, 0x71, 0x0b, 0x64, 0xe0, 
+  0x8a, 0x2b, 0xd3, 0xd7, 0x41, 0x63, 0x00, 0x79, 
+  0xdd, 0xd9, 0x2a, 0xe8, 0x51, 0x10, 0x40, 0x22, 
+  0x7d, 0x0b, 0x3b, 0xe2, 0x45, 0xe8, 0xbf, 0x54, 
+  0xf4, 0x60, 0xb0, 0xa5, 0x29, 0xe5, 0x11, 0x0d, 
+  0x29, 0xab, 0xde, 0xa2, 0x45, 0x20, 0x2f, 0xea, 
+  0xc8, 0xfa, 0x2e, 0x7e, 0x9c, 0x95, 0x12, 0x84, 
+  0xae, 0x23, 0x07, 0x09, 0x93, 0x24, 0x09, 0x38, 
+  0x3b, 0x86, 0x81, 0x35, 0x84, 0xda, 0xfb, 0x92, 
+  0x2f, 0x10, 0x83, 0x82, 0x2e, 0xba, 0x10, 0xc8, 
+  0xa4, 0x22, 0xdd, 0x07, 0x0d, 0x1f, 0x0d, 0xd9, 
+  0xd0, 0x4d, 0xd7, 0x21, 0xd7, 0x98, 0x03, 0x81, 
+  0x60, 0x7d, 0xd5, 0xe7, 0x21, 0x42, 0xe7, 0xe6, 
+  0xa0, 0xab, 0x83, 0x82, 0x7d, 0xc8, 0x32, 0xe5, 
+  0x07, 0x3e, 0x14, 0x9d, 0xd3, 0xf3, 0xa4, 0xa3, 
+  0x10, 0xca, 0x83, 0x8e, 0xa6, 0xb1, 0x4a, 0xc4, 
+  0xed, 0x74, 0x7d, 0x07, 0x02, 0xeb, 0xc3, 0x17, 
+  0x9c, 0xa8, 0xc2, 0x4a, 0x9f, 0x5c, 0x5c, 0x69, 
+  0x01, 0x36, 0x9d, 0xa4, 0xa0, 0xf3, 0xff, 0xff, 
+  0xa0, 0x39, 0x32, 0x52, 0x45, 0x91, 0x2f, 0xc0, 
+  0x9f, 0x06, 0x60, 0xe2, 0x5a, 0x77, 0x0a, 0x3f, 
+  0x89, 0x24, 0x28, 0x5c, 0x22, 0xac, 0xc5, 0xf8, 
+  0xb7, 0x6c, 0x40, 0x33, 0x7d, 0x58, 0x89, 0x72, 
+  0x69, 0xea, 0xc0, 0xe1, 0x91, 0x1f, 0x57, 0xd9, 
+  0x99, 0x27, 0x17, 0x47, 0x7a, 0x88, 0x26, 0xdb, 
+  0xa6, 0xe5, 0xe4, 0x01, 0xe2, 0xa9, 0x0c, 0x05, 
+  0x3b, 0x90, 0xda, 0x3e, 0x2c, 0x2b, 0x7e, 0x77, 
+  0xa4, 0x7a, 0x73, 0xc8, 0x1c, 0x59, 0x0a, 0x41, 
+  0x3f, 0x16, 0x61, 0x47, 0x01, 0xc4, 0xb3, 0x80, 
+  0xba, 0xd3, 0x4d, 0x86, 0x21, 0x80, 0x52, 0xfa, 
+  0x48, 0x8d, 0x10, 0xc4, 0x17, 0xd2, 0xf5, 0x14, 
+  0x0a, 0xe2, 0x7d, 0x46, 0x54, 0x4b, 0x0c, 0x0d, 
+  0x05, 0x58, 0xb0, 0x95, 0x4f, 0x50, 0x83, 0x91, 
+  0x05, 0x39, 0x10, 0x39, 0x10, 0x38, 0x8f, 0x1b, 
+  0xbc, 0x85, 0x01, 0x88, 0xd3, 0xb4, 0x13, 0xb5, 
+  0xe5, 0x74, 0x4b, 0x03, 0x91, 0x10, 0x31, 0x8c, 
+  0x0a, 0x25, 0x72, 0x5b, 0x06, 0x70, 0x9e, 0x51, 
+  0x53, 0x55, 0x19, 0x28, 0x38, 0xa0, 0x8f, 0x83, 
+  0x64, 0x21, 0x5e, 0xbb, 0x19, 0xcd, 0x18, 0x06, 
+  0x20, 0xe3, 0xf3, 0x16, 0xe8, 0x38, 0x22, 0xd0, 
+  0x12, 0x62, 0xac, 0x6c, 0x1d, 0x11, 0x9d, 0xbd, 
+  0x28, 0x84, 0xfa, 0xfa, 0x95, 0x77, 0xa0, 0x3a, 
+  0x86, 0x48, 0xa9, 0xa0, 0x8e, 0x2c, 0x50, 0x8f, 
+  0xbc, 0x01, 0xc0, 0xb0, 0x05, 0xcc, 0xd5, 0x90, 
+  0x41, 0x70, 0x4e, 0x9a, 0xeb, 0x22, 0x07, 0x14, 
+  0x82, 0xeb, 0xe0, 0x9f, 0x4e, 0x2c, 0x07, 0xea, 
+  0x80, 0x0d, 0x12, 0xc2, 0x81, 0x98, 0x38, 0x56, 
+  0x99, 0x60, 0x38, 0x27, 0xa5, 0x00, 0xf3, 0xff, 
+  0xff, 0x91, 0x99, 0x54, 0x8c, 0x4d, 0x9f, 0xab, 
+  0xdd, 0x51, 0x57, 0x5c, 0x90, 0x60, 0xb1, 0xef, 
+  0xca, 0x2b, 0xc0, 0xe2, 0x2a, 0x58, 0x94, 0xf1, 
+  0x4a, 0x22, 0xc8, 0x5d, 0xdf, 0x50, 0x49, 0x46, 
+  0x68, 0xc6, 0x51, 0xd1, 0x7b, 0x03, 0x00, 0x4d, 
+  0xa5, 0x14, 0x1d, 0x51, 0x05, 0x4f, 0x8b, 0x76, 
+  0x86, 0x6b, 0x03, 0x81, 0x3b, 0xd3, 0xb5, 0x1a, 
+  0xa7, 0xb6, 0xce, 0x20, 0x9c, 0x5e, 0x2c, 0x6c, 
+  0x86, 0x79, 0xc3, 0x64, 0x9d, 0x3f, 0xb8, 0x6c, 
+  0x1c, 0x42, 0xd6, 0x5a, 0x76, 0x0a, 0x2a, 0x32, 
+  0x3d, 0x77, 0x79, 0xc4, 0x16, 0x12, 0xd0, 0xa7, 
+  0x41, 0x80, 0xaf, 0x76, 0x20, 0xec, 0x07, 0x05, 
+  0x1f, 0x11, 0x85, 0x1c, 0xa8, 0x02, 0x8d, 0x7c, 
+  0x0e, 0x21, 0x75, 0x4f, 0x60, 0x3a, 0xa2, 0x27, 
+  0x9d, 0x06, 0x0c, 0x8d, 0x0a, 0xd9, 0x22, 0xf5, 
+  0x4d, 0x07, 0x50, 0x4c, 0xed, 0xe2, 0x30, 0xcc, 
+  0x07, 0xbb, 0x4f, 0x0c, 0xd1, 0x14, 0x83, 0x83, 
+  0x3e, 0x0d, 0x67, 0x94, 0x62, 0x0e, 0x17, 0xf5, 
+  0x00, 0xd1, 0xf0, 0x1c, 0xfd, 0x62, 0x04, 0x24, 
+  0x18, 0x51, 0x53, 0xfc, 0x28, 0x07, 0x0d, 0x77, 
+  0x03, 0x31, 0x5e, 0x51, 0xc8, 0x0e, 0x0a, 0xda, 
+  0xd5, 0x0f, 0x16, 0x58, 0x1d, 0xc0, 0x71, 0xc6, 
+  0x8b, 0x22, 0xc4, 0x66, 0xc2, 0x3d, 0x77, 0x6c, 
+  0xd2, 0x47, 0x65, 0x15, 0x0f, 0x41, 0xc3, 0x31, 
+  0x3f, 0xec, 0x36, 0x0b, 0xc7, 0x3b, 0x57, 0x44, 
+  0x52, 0x6e, 0x8a, 0xa7, 0x37, 0x95, 0x6a, 0x09, 
+  0x95, 0x37, 0xc4, 0x3c, 0x81, 0x98, 0x3a, 0x04, 
+  0x9f, 0x8b, 0x1a, 0x19, 0x83, 0x83, 0x11, 0x35, 
+  0x03, 0x90, 0x50, 0x72, 0x12, 0x39, 0xb0, 0xdf, 
+  0x41, 0xc4, 0x71, 0x4a, 0x12, 0x6d, 0x3e, 0x58, 
+  0xb8, 0xc9, 0x08, 0x2c, 0x20, 0x38, 0xf7, 0x58, 
+  0xd7, 0x41, 0xc1, 0x3d, 0x70, 0x33, 0x05, 0xd4, 
+  0xa8, 0x58, 0x1c, 0x18, 0xc8, 0x14, 0x77, 0xa2, 
+  0xa8, 0xbf, 0xcb, 0x51, 0x83, 0x8e, 0xc5, 0x29, 
+  0x5c, 0x17, 0x9e, 0xa0, 0x25, 0x44, 0x28, 0x9a, 
+  0x2f, 0xa8, 0x43, 0x0a, 0x7a, 0xd8, 0x8f, 0xb6, 
+  0x82, 0x66, 0x9f, 0x5e, 0x0c, 0x0d, 0x03, 0x97, 
+  0x42, 0x8c, 0xf4, 0xf0, 0xda, 0x21, 0x3e, 0x47, 
+  0xc3, 0x64, 0xcc, 0x66, 0x0e, 0x1a, 0x51, 0x5d, 
+  0x5d, 0x3b, 0x8a, 0x0a, 0x0a, 0x62, 0x3e, 0x72, 
+  0x3d, 0xdf, 0x83, 0x90, 0xa0, 0x05, 0xf7, 0xde, 
+  0x45, 0xb8, 0x33, 0xe2, 0xc0, 0xb0, 0x19, 0x91, 
+  0x3c, 0xef, 0x43, 0x75, 0xa2, 0x33, 0x6b, 0xf0, 
+  0x33, 0x7e, 0x56, 0x28, 0xd3, 0xab, 0xd4, 0x52, 
+  0x90, 0xfe, 0x21, 0x40, 0x52, 0xe8, 0x9e, 0xe7, 
+  0x22, 0x00, 0xd5, 0x4d, 0x06, 0x09, 0xe7, 0x90, 
+  0x16, 0x3c, 0xe1, 0x42, 0x10, 0xc0, 0x69, 0x10, 
+  0x71, 0xd1, 0x3d, 0x27, 0x79, 0x08, 0xda, 0x81, 
+  0x9a, 0x30, 0x72, 0x30, 0x4d, 0x72, 0x2e, 0x83, 
+  0x9c, 0x07, 0x06, 0x42, 0xbd, 0xcb, 0xd2, 0x2e, 
+  0x74, 0x51, 0xa7, 0xd4, 0x53, 0x70, 0x63, 0xc0, 
+  0x70, 0x49, 0xb9, 0x06, 0x66, 0xd0, 0x02, 0xc4, 
+  0x17, 0x9b, 0x84, 0x88, 0xc3, 0x30, 0x70, 0x55, 
+  0xb8, 0x0e, 0x5c, 0x1c, 0x32, 0x09, 0x90, 0xe5, 
+  0x5e, 0x6d, 0x01, 0xc4, 0x7d, 0x0a, 0xfd, 0x46, 
+  0x48, 0x48, 0xb3, 0xb7, 0x06, 0x4b, 0x8c, 0x10, 
+  0x03, 0x9f, 0xba, 0x2e, 0x46, 0x19, 0xbe, 0xf5, 
+  0x1a, 0xc7, 0xb4, 0xe0, 0x65, 0x02, 0x7c, 0x30, 
+  0x0c, 0x4d, 0x8a, 0x5f, 0x0d, 0x45, 0xca, 0x28, 
+  0x4b, 0x2b, 0x03, 0xa0, 0x30, 0x2c, 0x42, 0x5c, 
+  0xe6, 0x9e, 0x28, 0x82, 0xe0, 0x5c, 0xbe, 0xa3, 
+  0x96, 0x06, 0x61, 0x2c, 0x40, 0x1d, 0xd2, 0x17, 
+  0xc5, 0xc1, 0xc3, 0x5e, 0xce, 0x1a, 0xe0, 0xaf, 
+  0x4f, 0x0c, 0xba, 0x19, 0x06, 0x40, 0x3c, 0x6b, 
+  0xe7, 0x57, 0x58, 0xd4, 0x07, 0x1b, 0x14, 0x27, 
+  0xce, 0x92, 0xc2, 0x94, 0x60, 0xbe, 0x60, 0xe0, 
+  0x9f, 0x44, 0x85, 0xfa, 0xf8, 0xd8, 0x64, 0xa3, 
+  0x80, 0x39, 0x10, 0x55, 0xed, 0x18, 0x9b, 0x0b, 
+  0x32, 0x20, 0x58, 0x02, 0xe7, 0x1b, 0x21, 0xbd, 
+  0x9d, 0xe9, 0x50, 0x26, 0xe9, 0xba, 0x1f, 0xa2, 
+  0xee, 0x14, 0x2e, 0x03, 0xc8, 0xdd, 0x10, 0x4d, 
+  0x66, 0x8c, 0xe9, 0x48, 0x2e, 0x51, 0xe0, 0x26, 
+  0xa9, 0xc6, 0x43, 0x9c, 0x92, 0x20, 0x04, 0xd2, 
+  0xd7, 0x43, 0x27, 0x01, 0x7d, 0xa7, 0x65, 0x7c, 
+  0x0e, 0xb0, 0x11, 0xc2, 0x5b, 0xbf, 0x51, 0x57, 
+  0xc0, 0x46, 0xb1, 0x71, 0x97, 0x5d, 0x62, 0x06, 
+  0x68, 0xdf, 0xba, 0x6c, 0xad, 0x18, 0xc8, 0xe4, 
+  0x28, 0xcc, 0x1b, 0x7b, 0x85, 0x10, 0x31, 0x3f, 
+  0x41, 0xc8, 0x88, 0xb4, 0xde, 0x7f, 0x7e, 0x0c, 
+  0x05, 0x3e, 0xb9, 0xb5, 0x10, 0x6b, 0x2a, 0x1b, 
+  0xe7, 0x54, 0xe6, 0x12, 0x8d, 0xe8, 0x38, 0x62, 
+  0x7b, 0xd2, 0x45, 0xe8, 0x51, 0xf8, 0x8d, 0x71, 
+  0x78, 0x38, 0x62, 0x13, 0xb2, 0xfd, 0x09, 0x62, 
+  0x6c, 0x0d, 0x60, 0x32, 0x1f, 0xb7, 0xfa, 0x53, 
+  0xc8, 0x50, 0xb7, 0x06, 0x92, 0xa3, 0x32, 0xad, 
+  0x38, 0x0e, 0x28, 0x3d, 0x27, 0x9f, 0x20, 0x63, 
+  0xd7, 0xcb, 0xd4, 0x72, 0xf0, 0x90, 0x83, 0x5f, 
+  0x5d, 0x18, 0x92, 0xa3, 0x0d, 0xd7, 0x3d, 0xaa, 
+  0x91, 0x95, 0xe9, 0x48, 0xd1, 0xf4, 0x1f, 0xc2, 
+  0x00, 0x3f, 0x6c, 0x44, 0xba, 0x00, 0x70, 0x72, 
+  0x7e, 0x70, 0x57, 0x53, 0x64, 0x92, 0x0c, 0xcd, 
+  0x92, 0x02, 0xeb, 0xae, 0x50, 0x2a, 0xca, 0x0a, 
+  0x45, 0xc0, 0x3c, 0x1c, 0xee, 0x18, 0x03, 0x90, 
+  0x84, 0x54, 0x35, 0xe8, 0x49, 0xa7, 0x35, 0x12, 
+  0x00, 0x1c, 0x2e, 0x07, 0x3b, 0x49, 0x01, 0xdd, 
+  0x19, 0x83, 0x90, 0x89, 0xa7, 0x85, 0x05, 0x01, 
+  0x1b, 0x17, 0x14, 0x03, 0xb8, 0x0b, 0xe6, 0xc2, 
+  0x9e, 0x94, 0x9c, 0xd3, 0xa0, 0x70, 0x66, 0x43, 
+  0x3c, 0x07, 0x05, 0x49, 0x74, 0xd5, 0xe0, 0xc0, 
+  0x07, 0xae, 0xea, 0x5f, 0xa6, 0xc1, 0xc3, 0x05, 
+  0x85, 0xc2, 0xb8, 0xa4, 0x90, 0x2b, 0x89, 0xb8, 
+  0x0e, 0x42, 0x12, 0x34, 0x46, 0x81, 0xc4, 0xa2, 
+  0x96, 0xb8, 0x64, 0x6e, 0x02, 0xe7, 0xa3, 0x40, 
+  0x32, 0x07, 0x40, 0x5c, 0x3d, 0xed, 0x5f, 0xa1, 
+  0x55, 0x4b, 0xf9, 0x60, 0x70, 0xa2, 0x11, 0xf4, 
+  0x32, 0x73, 0xe5, 0x29, 0x0c, 0x01, 0xc5, 0x03, 
+  0x5b, 0x57, 0x20, 0x89, 0xd8, 0x39, 0x00, 0x39, 
+  0x71, 0x80, 0xd1, 0x8c, 0x49, 0x3a, 0x09, 0xf0, 
+  0xa2, 0x23, 0x07, 0x02, 0xfa, 0x54, 0x78, 0x94, 
+  0x31, 0x13, 0xac, 0x2a, 0x15, 0xd5, 0xe1, 0x17, 
+  0x51, 0x03, 0xa5, 0x3b, 0xa1, 0x2a, 0x37, 0xed, 
+  0xd2, 0xa2, 0x52, 0x42, 0x8a, 0xb1, 0xa2, 0x83, 
+  0xb2, 0xa4, 0xa2, 0x4a, 0x50, 0x8f, 0xa1, 0x80, 
+  0x55, 0x29, 0xd8, 0x9e, 0x50, 0x87, 0xa7, 0x31, 
+  0x50, 0x3b, 0x92, 0x0c, 0x0f, 0xf1, 0x99, 0x48, 
+  0x38, 0x07, 0x22, 0x24, 0x3f, 0xc1, 0xcb, 0x83, 
+  0x81, 0x60, 0x35, 0xc1, 0x75, 0x13, 0xf1, 0x74, 
+  0x43, 0x12, 0x51, 0x98, 0x47, 0x84, 0x52, 0x81, 
+  0x82, 0xc0, 0xe1, 0xac, 0x74, 0x16, 0x04, 0xa1, 
+  0x81, 0xe6, 0x04, 0x83, 0x20, 0x89, 0xd6, 0x42, 
+  0x7f, 0x4d, 0xd1, 0x81, 0x48, 0xa1, 0x46, 0x3f, 
+  0x8c, 0xc5, 0x33, 0x9b, 0xe4, 0x1b, 0x9d, 0x5c, 
+  0x63, 0x90, 0x1c, 0x83, 0xae, 0xc8, 0x51, 0x06, 
+  0x50, 0x32, 0xa0, 0xbf, 0x2d, 0xc0, 0x71, 0x20, 
+  0x38, 0x5c, 0x4a, 0xef, 0xa7, 0xb4, 0xd0, 0xb8, 
+  0x4b, 0x45, 0xc2, 0xf0, 0x4e, 0x65, 0x21, 0x3f, 
+  0x34, 0x8c, 0x1c, 0x4a, 0x0e, 0xeb, 0xe4, 0xa0, 
+  0x1d, 0x46, 0x01, 0x5c, 0xe8, 0x9f, 0x5f, 0x14, 
+  0xa2, 0x37, 0x49, 0x44, 0xcf, 0x9c, 0x18, 0x92, 
+  0xa3, 0x07, 0x09, 0xe6, 0x1b, 0x09, 0x2b, 0x83, 
+  0x10, 0x4c, 0xe2, 0x35, 0x9d, 0x13, 0x92, 0x80, 
+  0x70, 0x66, 0x35, 0x6b, 0x77, 0x84, 0x6c, 0x64, 
+  0xb9, 0xa5, 0x96, 0x13, 0xee, 0x0c, 0x41, 0xc8, 
+  0xfa, 0x13, 0xb5, 0x9d, 0x25, 0x0a, 0x75, 0xde, 
+  0x50, 0x70, 0x2f, 0xa7, 0x56, 0x37, 0x61, 0xb2, 
+  0x42, 0x40, 0xae, 0x68, 0xcc, 0xa5, 0x07, 0x42, 
+  0x4d, 0x0d, 0xad, 0xca, 0x0b, 0xd5, 0xa3, 0x21, 
+  0x36, 0x9e, 0x8a, 0x22, 0xfd, 0x05, 0x88, 0x38, 
+  0x82, 0x4a, 0x28, 0xc1, 0x6e, 0x92, 0xad, 0x43, 
+  0x17, 0x4a, 0x34, 0x60, 0xfe, 0x10, 0x01, 0xe3, 
+  0x75, 0x6e, 0x03, 0x82, 0x4b, 0xdc, 0xa2, 0xbd, 
+  0x77, 0x28, 0x3b, 0xab, 0x77, 0x85, 0x21, 0x3c, 
+  0xc1, 0x9b, 0x9c, 0xb6, 0x76, 0xdb, 0x67, 0x78, 
+  0xb6, 0x5e, 0x21, 0x92, 0xde, 0x11, 0x4a, 0x20, 
+  0x74, 0x08, 0xa4, 0xa1, 0xb8, 0xd3, 0x5e, 0x68, 
+  0xd6, 0x57, 0x85, 0x01, 0x89, 0x0c, 0x5e, 0xa0, 
+  0x07, 0x1a, 0x07, 0x09, 0xf7, 0x11, 0x02, 0xeb, 
+  0x07, 0x1e, 0xd3, 0x46, 0xad, 0x11, 0x94, 0x74, 
+  0x1d, 0xd7, 0x29, 0xc3, 0x62, 0xf7, 0x24, 0x1f, 
+  0x7c, 0x18, 0x38, 0xf8, 0x30, 0xc2, 0x86, 0x12, 
+  0x03, 0x9f, 0xea, 0x66, 0xc1, 0x83, 0x86, 0xc6, 
+  0x5e, 0xa0, 0x39, 0xce, 0x51, 0x44, 0xda, 0xf8, 
+  0x5f, 0x01, 0xc3, 0x4f, 0x61, 0xb5, 0xe8, 0x62, 
+  0x8c, 0xa0, 0x17, 0x57, 0x75, 0x0f, 0x36, 0xf1, 
+  0x65, 0xc8, 0x1c, 0x02, 0x53, 0xab, 0xd0, 0x58, 
+  0xba, 0xf6, 0x44, 0x00, 0x9d, 0xaf, 0x48, 0x22, 
+  0x38, 0x85, 0x09, 0x48, 0x45, 0xe5, 0x28, 0x1a, 
+  0xfb, 0x20, 0x6f, 0x38, 0x32, 0x14, 0x54, 0xb4, 
+  0x63, 0xd0, 0x70, 0xd6, 0x82, 0xef, 0x5d, 0xd1, 
+  0x9f, 0x56, 0x3d, 0xc6, 0x1c, 0xe2, 0x11, 0x5b, 
+  0x46, 0x6a, 0xfd, 0x6e, 0x04, 0xad, 0x62, 0x8c, 
+  0x07, 0x00, 0xe2, 0x32, 0xf8, 0x1c, 0xf0, 0x51, 
+  0x57, 0xc0, 0xe0, 0x1c, 0x2a, 0xf1, 0x07, 0x09, 
+  0xb0, 0xbe, 0x03, 0xb8, 0x09, 0xfd, 0x62, 0x8b, 
+  0x45, 0xe1, 0x5d, 0x07, 0x2c, 0xb0, 0x4f, 0x17, 
+  0xf4, 0x95, 0x00, 0x26, 0xc9, 0x4a, 0x18, 0x13, 
+  0xe2, 0xb4, 0x6b, 0xd0, 0xb1, 0xd4, 0x11, 0x69, 
+  0x69, 0xc2, 0xc8, 0x75, 0xf2, 0xc0, 0xe4, 0x64, 
+  0x1d, 0x71, 0x80, 0xb8, 0x4c, 0xc6, 0x36, 0x3b, 
+  0x64, 0x90, 0x38, 0xb3, 0x56, 0x18, 0x65, 0x08, 
+  0x8c, 0x46, 0xb9, 0xfa, 0xbf, 0x0c, 0xaa, 0xc1, 
+  0x26, 0x90, 0x1e, 0x8f, 0xff, 0xf2, 0x36, 0xba, 
+  0x34, 0x56, 0x54, 0x2b, 0x03, 0x90, 0x9e, 0x9a, 
+  0x31, 0x44, 0x18, 0x11, 0xfb, 0xc8, 0x13, 0x6b, 
+  0xe9, 0x61, 0x24, 0xc4, 0x68, 0x85, 0x33, 0x25, 
+  0x29, 0xa1, 0x15, 0x5d, 0xa4, 0xb2, 0xda, 0x15, 
+  0x7e, 0x62, 0x35, 0x96, 0x20, 0xf3, 0xa4, 0x51, 
+  0x79, 0xb0, 0xa5, 0x1f, 0x20, 0xc7, 0x80, 0x9b, 
+  0xed, 0x24, 0xe2, 0x11, 0xab, 0xe8, 0xcb, 0xa1, 
+  0x54, 0xcc, 0x44, 0x8b, 0x66, 0x76, 0x3a, 0x62, 
+  0x20, 0x4f, 0xd7, 0xe2, 0x29, 0xbe, 0x92, 0x93, 
+  0xb5, 0x90, 0x03, 0xba, 0x27, 0x7d, 0xb0, 0x39, 
+  0x2b, 0xea, 0x31, 0x9f, 0x02, 0x7f, 0x78, 0x50, 
+  0x80, 0x30, 0x3f, 0x68, 0x38, 0x90, 0x5e, 0x73, 
+  0x5f, 0x4e, 0xc5, 0x83, 0x80, 0x58, 0x53, 0x64, 
+  0x0e, 0xf5, 0x75, 0xea, 0xfd, 0x28, 0x01, 0xc2, 
+  0x7d, 0x25, 0x24, 0x18, 0x21, 0x26, 0x63, 0x2e, 
+  0x14, 0x03, 0x89, 0xb0, 0x4b, 0xd7, 0xcb, 0x40, 
+  0x1c, 0x0e, 0x27, 0xf1, 0x0a, 0x25, 0x08, 0xf8, 
+  0x0b, 0x00, 0x96, 0x57, 0x24, 0xb4, 0x1c, 0xbb, 
+  0xf2, 0xc8, 0x90, 0x13, 0xdb, 0xc5, 0xf8, 0x0b, 
+  0x8d, 0x77, 0x68, 0xc5, 0x12, 0x15, 0xd6, 0x58, 
+  0x1c, 0x41, 0x0a, 0x24, 0x17, 0x74, 0x99, 0x86, 
+  0x6e, 0x7b, 0x56, 0x5b, 0x8a, 0x1e, 0xb3, 0xa8, 
+  0xcf, 0x6b, 0xb5, 0x34, 0x66, 0x18, 0x0c, 0x90, 
+  0x0c, 0x0f, 0x6e, 0x12, 0x2e, 0x50, 0x30, 0x15, 
+  0xb8, 0xa5, 0x61, 0xbd, 0xe7, 0x21, 0x0b, 0x51, 
+  0x94, 0xd4, 0xe7, 0x03, 0x00, 0x75, 0x0a, 0xfb, 
+  0xce, 0x9c, 0xab, 0xb2, 0x94, 0x48, 0x17, 0x0c, 
+  0x02, 0x67, 0xc1, 0x91, 0x45, 0xa6, 0xc1, 0x3e, 
+  0x49, 0x62, 0x34, 0x41, 0x33, 0xb4, 0x67, 0xd1, 
+  0x5c, 0x9d, 0xe2, 0xe7, 0x62, 0xee, 0x55, 0x08, 
+  0x81, 0xdc, 0x42, 0x0e, 0x21, 0x85, 0xe4, 0xef, 
+  0x00, 0x78, 0x39, 0x18, 0x55, 0x2b, 0x92, 0xde, 
+  0xf4, 0xd1, 0x48, 0x2e, 0x7c, 0x90, 0x91, 0x6e, 
+  0x83, 0x84, 0xee, 0x4b, 0x16, 0x14, 0x55, 0xf5, 
+  0x45, 0x10, 0x03, 0x9c, 0xe7, 0x0d, 0xf4, 0x90, 
+  0x64, 0x0b, 0x17, 0xcd, 0x84, 0x96, 0x4a, 0xbc, 
+  0x09, 0x37, 0x4a, 0x3a, 0x0f, 0x3d, 0x00, 0x19, 
+  0x34, 0x74, 0x5f, 0x59, 0x41, 0x18, 0x17, 0x33, 
+  0x95, 0x75, 0xe7, 0x14, 0x80, 0xee, 0x84, 0xcc, 
+  0xae, 0x12, 0x80, 0xf2, 0x0d, 0xa4, 0x9d, 0xc9, 
+  0x00, 0x79, 0x03, 0x3b, 0x5f, 0x5b, 0xc4, 0x3d, 
+  0x82, 0xf0, 0x71, 0xf9, 0xb3, 0x88, 0xfb, 0xd0, 
+  0x72, 0x09, 0xd1, 0xa4, 0xe2, 0xc8, 0x33, 0x7a, 
+  0x8d, 0x00, 0x39, 0x08, 0x2e, 0xb5, 0xc0, 0xd4, 
+  0xd7, 0x68, 0x38, 0x17, 0x5a, 0x33, 0xfa, 0xf3, 
+  0x38, 0x83, 0x8b, 0x12, 0x21, 0x39, 0x2b, 0x94, 
+  0xf5, 0x18, 0x38, 0x33, 0x21, 0x9b, 0x41, 0xf1, 
+  0xe0, 0x07, 0xd2, 0x52, 0x59, 0x11, 0x92, 0x92, 
+  0x2f, 0x41, 0xc4, 0x3d, 0x5e, 0x1e, 0xd3, 0x95, 
+  0xc0, 0x71, 0x0c, 0x7a, 0xc5, 0x38, 0x8c, 0x6e, 
+  0xed, 0x31, 0xb0, 0xe2, 0x82, 0x35, 0x09, 0x27, 
+  0x3d, 0xaa, 0x72, 0xdc, 0x43, 0x04, 0x47, 0xc5, 
+  0xa9, 0xb0, 0x9b, 0x7f
+};
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/shell/shell.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/shell/shell.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/shell/shell.c	(revision 457)
@@ -0,0 +1,1394 @@
+/*
+ * Copyright (c) 2001-2003 Swedish Institute of Computer Science.
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission. 
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ * 
+ * Author: Adam Dunkels <adam@sics.se>
+ *
+ */
+
+#include "shell.h"
+
+#include "lwip/opt.h"
+
+#if LWIP_NETCONN && LWIP_TCP
+
+#include <string.h>
+#include <stdio.h>
+
+#include "lwip/mem.h"
+#include "lwip/debug.h"
+#include "lwip/def.h"
+#include "lwip/api.h"
+#include "lwip/stats.h"
+
+#if LWIP_SOCKET
+#include "lwip/errno.h"
+#include "lwip/if_api.h"
+#endif
+
+#if 1 /* WIN32 TOPPERS */
+#define NEWLINE "\r\n"
+#else /* WIN32 */
+#define NEWLINE "\n"
+#endif /* WIN32 */
+
+/** Define this to 1 if you want to echo back all received characters
+ * (e.g. so they are displayed on a remote telnet)
+ */
+#ifndef SHELL_ECHO
+#define SHELL_ECHO 0
+#endif
+
+#define BUFSIZE             1024
+static unsigned char buffer[BUFSIZE];
+
+struct command {
+  struct netconn *conn;
+  s8_t (* exec)(struct command *);
+  u8_t nargs;
+  char *args[10];
+};
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <limits.h>
+
+/*
+ *  TELNET state
+ */
+#define	TELNET_STATE_DATA   0
+#define	TELNET_STATE_CR     1
+#define	TELNET_STATE_IAC    2
+#define	TELNET_STATE_WILL   3
+#define	TELNET_STATE_WONT   4
+#define	TELNET_STATE_DO     5
+#define	TELNET_STATE_DONT   6
+#define	TELNET_STATE_SB     7
+#define	TELNET_STATE_SE     8
+
+/*
+ *  TELNET control command
+ */
+#define	TELNET_SE       240
+#define TELNET_NOP      241
+#define TELNET_DM       242
+#define TELNET_BRK      243
+#define TELNET_IP       244
+#define TELNET_AO       245
+#define TELNET_AYT      246
+#define TELNET_EC       247
+#define TELNET_EL       248
+#define TELNET_GA       249
+#define TELNET_SB       250
+#define TELNET_WILL     251
+#define TELNET_WONT     252
+#define TELNET_DO       253
+#define TELNET_DONT     254
+#define TELNET_IAC      255
+
+#define ESUCCESS 0
+#define ESYNTAX -1
+#define ETOOFEW -2
+#define ETOOMANY -3
+#define ECLOSED -4
+
+#define NCONNS 10
+static struct netconn *conns[NCONNS];
+
+/* help_msg is split into 3 strings to prevent exceeding the C89 maximum length of 509 per string */
+static char help_msg1[] = "Available commands:"NEWLINE"\
+open [IP address] [TCP port]: opens a TCP connection to the specified address."NEWLINE"\
+lstn [TCP port]: sets up a server on the specified port."NEWLINE"\
+acpt [connection #]: waits for an incoming connection request."NEWLINE"\
+send [connection #] [message]: sends a message on a TCP connection."NEWLINE"\
+udpc [local UDP port] [IP address] [remote port]: opens a UDP \"connection\"."NEWLINE"\
+udpl [local UDP port] [IP address] [remote port]: opens a UDP-Lite \"connection\"."NEWLINE"";
+static char help_msg2[] = "udpn [local UDP port] [IP address] [remote port]: opens a UDP \"connection\" without checksums."NEWLINE"\
+udpb [local port] [remote port]: opens a UDP broadcast \"connection\"."NEWLINE"\
+usnd [connection #] [message]: sends a message on a UDP connection."NEWLINE"\
+recv [connection #]: recieves data on a TCP or UDP connection."NEWLINE"\
+clos [connection #]: closes a TCP or UDP connection."NEWLINE"\
+stat: prints out lwIP statistics."NEWLINE"\
+idxtoname [index]: outputs interface name from index."NEWLINE"\
+nametoidx [name]: outputs interface index from name."NEWLINE;
+static char help_msg3[] = 
+"gethostnm [name]: outputs IP address of host."NEWLINE"\
+quit: quits"NEWLINE"";
+
+#if LWIP_STATS
+static char padding_10spaces[] = "          ";
+
+#define PROTOCOL_STATS (LINK_STATS && ETHARP_STATS && IPFRAG_STATS && IP_STATS && ICMP_STATS && UDP_STATS && TCP_STATS)
+
+#if PROTOCOL_STATS
+static const char* shell_stat_proto_names[] = {
+#if LINK_STATS
+  "LINK      ",
+#endif
+#if ETHARP_STATS
+  "ETHARP    ",
+#endif
+#if IPFRAG_STATS
+  "IP_FRAG   ",
+#endif
+#if IP_STATS
+  "IP        ",
+#endif
+#if ICMP_STATS
+  "ICMP      ",
+#endif
+#if UDP_STATS
+  "UDP       ",
+#endif
+#if TCP_STATS
+  "TCP       ",
+#endif
+  "last"
+};
+
+static struct stats_proto* shell_stat_proto_stats[] = {
+#if LINK_STATS
+  &lwip_stats.link,
+#endif
+#if ETHARP_STATS
+  &lwip_stats.etharp,
+#endif
+#if IPFRAG_STATS
+  &lwip_stats.ip_frag,
+#endif
+#if IP_STATS
+  &lwip_stats.ip,
+#endif
+#if ICMP_STATS
+  &lwip_stats.icmp,
+#endif
+#if UDP_STATS
+  &lwip_stats.udp,
+#endif
+#if TCP_STATS
+  &lwip_stats.tcp,
+#endif
+};
+const size_t num_protostats = sizeof(shell_stat_proto_stats)/sizeof(struct stats_proto*);
+
+static const char *stat_msgs_proto[] = {
+  " * transmitted ",
+  "           * received ",
+  "             forwarded ",
+  "           * dropped ",
+  "           * checksum errors ",
+  "           * length errors ",
+  "           * memory errors ",
+  "             routing errors ",
+  "             protocol errors ",
+  "             option errors ",
+  "           * misc errors ",
+  "             cache hits "
+};
+#endif /* PROTOCOL_STATS */
+#endif /* LWIP_STATS */
+
+/*-----------------------------------------------------------------------------------*/
+static void
+sendstr(const char *str, struct netconn *conn)
+{
+  netconn_write(conn, (const void *)str, strlen(str), NETCONN_NOCOPY);
+}
+/*-----------------------------------------------------------------------------------*/
+static s8_t
+com_open(struct command *com)
+{
+  ip_addr_t ipaddr;
+  u16_t port;
+  int i;
+  err_t err;
+  long tmp;
+
+  if (ipaddr_aton(com->args[0], &ipaddr) == -1) {
+    sendstr(strerror(errno), com->conn);
+    return ESYNTAX;
+  }
+  tmp = strtol(com->args[1], NULL, 10);
+  if((tmp < 0) || (tmp > 0xffff)) {
+    sendstr("Invalid port number."NEWLINE, com->conn);
+    return ESUCCESS;
+  }
+  port = (u16_t)tmp;
+
+  /* Find the first unused connection in conns. */
+  for(i = 0; i < NCONNS && conns[i] != NULL; i++);
+
+  if (i == NCONNS) {
+    sendstr("No more connections available, sorry."NEWLINE, com->conn);
+    return ESUCCESS;
+  }
+
+  sendstr("Opening connection to ", com->conn);
+  netconn_write(com->conn, com->args[0], strlen(com->args[0]), NETCONN_COPY);
+  sendstr(":", com->conn);
+  netconn_write(com->conn, com->args[1], strlen(com->args[1]), NETCONN_COPY);
+  sendstr(NEWLINE, com->conn);
+
+  conns[i] = netconn_new(NETCONN_TCP);
+  if (conns[i] == NULL) {    
+    sendstr("Could not create connection identifier (out of memory)."NEWLINE, com->conn); 
+    return ESUCCESS;
+  }
+  err = netconn_connect(conns[i], &ipaddr, port);
+  if (err != ERR_OK) {
+    fprintf(stderr, "error %s"NEWLINE, lwip_strerr(err));
+    sendstr("Could not connect to remote host: ", com->conn);
+#ifdef LWIP_DEBUG
+    sendstr(lwip_strerr(err), com->conn);
+#else
+    sendstr("(debugging must be turned on for error message to appear)", com->conn);
+#endif /* LWIP_DEBUG */
+    sendstr(NEWLINE, com->conn);
+    netconn_delete(conns[i]);
+    conns[i] = NULL;
+    return ESUCCESS;
+  }
+
+  sendstr("Opened connection, connection identifier is ", com->conn);
+  snprintf((char *)buffer, sizeof(buffer), "%d"NEWLINE, i);
+  netconn_write(com->conn, buffer, strlen((const char *)buffer), NETCONN_COPY);
+  
+  return ESUCCESS;
+}
+/*-----------------------------------------------------------------------------------*/
+static s8_t
+com_lstn(struct command *com)
+{
+  u16_t port;
+  int i;
+  err_t err;
+  long tmp;
+
+  tmp = strtol(com->args[0], NULL, 10);
+  if((tmp < 0) || (tmp > 0xffff)) {
+    sendstr("Invalid port number."NEWLINE, com->conn);
+    return ESUCCESS;
+  }
+  port = (u16_t)tmp;
+
+  /* Find the first unused connection in conns. */
+  for(i = 0; i < NCONNS && conns[i] != NULL; i++);
+
+  if (i == NCONNS) {
+    sendstr("No more connections available, sorry."NEWLINE, com->conn);
+    return ESUCCESS;
+  }
+
+  sendstr("Opening a listening connection on port ", com->conn);
+  netconn_write(com->conn, com->args[0], strlen(com->args[0]), NETCONN_COPY);
+  sendstr(NEWLINE, com->conn);
+
+  conns[i] = netconn_new(NETCONN_TCP);
+  if (conns[i] == NULL) {    
+    sendstr("Could not create connection identifier (out of memory)."NEWLINE, com->conn); 
+    return ESUCCESS;
+  }
+  
+  err = netconn_bind(conns[i], IP_ADDR_ANY, port);
+  if (err != ERR_OK) {
+    netconn_delete(conns[i]);
+    conns[i] = NULL;
+    sendstr("Could not bind: ", com->conn);
+#ifdef LWIP_DEBUG
+    sendstr(lwip_strerr(err), com->conn);
+#else
+    sendstr("(debugging must be turned on for error message to appear)", com->conn);
+#endif /* LWIP_DEBUG */
+    sendstr(NEWLINE, com->conn);
+    return ESUCCESS;
+  }
+  
+  err = netconn_listen(conns[i]);
+  if (err != ERR_OK) {
+    netconn_delete(conns[i]);
+    conns[i] = NULL;
+    sendstr("Could not listen: ", com->conn);
+#ifdef LWIP_DEBUG
+    sendstr(lwip_strerr(err), com->conn);
+#else
+    sendstr("(debugging must be turned on for error message to appear)", com->conn);
+#endif /* LWIP_DEBUG */
+    sendstr(NEWLINE, com->conn);
+    return ESUCCESS;
+  }
+
+  sendstr("Opened connection, connection identifier is ", com->conn);
+  snprintf((char *)buffer, sizeof(buffer), "%d"NEWLINE, i);
+  netconn_write(com->conn, buffer, strlen((const char *)buffer), NETCONN_COPY);
+  
+  return ESUCCESS;
+}
+/*-----------------------------------------------------------------------------------*/
+/*-----------------------------------------------------------------------------------*/
+static s8_t
+com_clos(struct command *com)
+{
+  int i;
+  err_t err;
+  
+  i = strtol(com->args[0], NULL, 10);
+
+  if (i > NCONNS) {
+    sendstr("Connection identifier too high."NEWLINE, com->conn);
+    return ESUCCESS;
+  }
+  if (conns[i] == NULL) {
+    sendstr("Connection identifier not in use."NEWLINE, com->conn);
+    return ESUCCESS;
+  }
+
+  err = netconn_close(conns[i]);
+  if (err != ERR_OK) {
+    sendstr("Could not close connection: ", com->conn);
+#ifdef LWIP_DEBUG
+    sendstr(lwip_strerr(err), com->conn);
+#else
+    sendstr("(debugging must be turned on for error message to appear)", com->conn);
+#endif /* LWIP_DEBUG */
+    sendstr(NEWLINE, com->conn);
+    return ESUCCESS;
+  }
+
+  sendstr("Connection closed."NEWLINE, com->conn);
+  netconn_delete(conns[i]);
+  conns[i] = NULL;
+  return ESUCCESS;
+}
+/*-----------------------------------------------------------------------------------*/
+static s8_t
+com_acpt(struct command *com)
+{
+  int i, j;
+  err_t err;
+
+  /* Find the first unused connection in conns. */
+  for(j = 0; j < NCONNS && conns[j] != NULL; j++);
+
+  if (j == NCONNS) {
+    sendstr("No more connections available, sorry."NEWLINE, com->conn);
+    return ESUCCESS;
+  }
+
+  i = strtol(com->args[0], NULL, 10);
+
+  if (i > NCONNS) {
+    sendstr("Connection identifier too high."NEWLINE, com->conn);
+    return ESUCCESS;
+  }
+  if (conns[i] == NULL) {
+    sendstr("Connection identifier not in use."NEWLINE, com->conn);
+    return ESUCCESS;
+  }
+
+  err = netconn_accept(conns[i], &conns[j]);
+  
+  if (err != ERR_OK) {
+    sendstr("Could not accept connection: ", com->conn);
+#ifdef LWIP_DEBUG
+    sendstr(lwip_strerr(err), com->conn);
+#else
+    sendstr("(debugging must be turned on for error message to appear)", com->conn);
+#endif /* LWIP_DEBUG */
+    sendstr(NEWLINE, com->conn);
+    return ESUCCESS;
+  }
+
+  sendstr("Accepted connection, connection identifier for new connection is ", com->conn);
+  snprintf((char *)buffer, sizeof(buffer), "%d"NEWLINE, j);
+  netconn_write(com->conn, buffer, strlen((const char *)buffer), NETCONN_COPY);
+
+  return ESUCCESS;
+}
+/*-----------------------------------------------------------------------------------*/
+#if LWIP_STATS
+static void
+com_stat_write_mem(struct netconn *conn, struct stats_mem *elem, int i)
+{
+  u16_t len;
+  char buf[100];
+  size_t slen;
+
+#ifdef LWIP_DEBUG
+  LWIP_UNUSED_ARG(i);
+  slen = strlen(elem->name);
+  netconn_write(conn, elem->name, slen, NETCONN_COPY);
+#else /*  LWIP_DEBUG */
+  len = (u16_t)sprintf(buf, "%d", i);
+  slen = strlen(buf);
+  netconn_write(conn, buf, slen, NETCONN_COPY);
+#endif /*  LWIP_DEBUG */
+  if(slen < 10) {
+    netconn_write(conn, padding_10spaces, 10-slen, NETCONN_COPY);
+  }
+
+  len = (u16_t)sprintf(buf, " * available %"MEM_SIZE_F NEWLINE, elem->avail);
+  netconn_write(conn, buf, len, NETCONN_COPY);
+  len = (u16_t)sprintf(buf, "           * used %"MEM_SIZE_F NEWLINE, elem->used);
+  netconn_write(conn, buf, len, NETCONN_COPY);
+  len = (u16_t)sprintf(buf, "           * high water mark %"MEM_SIZE_F NEWLINE, elem->max);
+  netconn_write(conn, buf, len, NETCONN_COPY);
+  len = (u16_t)sprintf(buf, "           * errors %"STAT_COUNTER_F NEWLINE, elem->err);
+  netconn_write(conn, buf, len, NETCONN_COPY);
+  len = (u16_t)sprintf(buf, "           * illegal %"STAT_COUNTER_F NEWLINE, elem->illegal);
+  netconn_write(conn, buf, len, NETCONN_COPY);
+}
+static void
+com_stat_write_sys(struct netconn *conn, struct stats_syselem *elem, const char *name)
+{
+  u16_t len;
+  char buf[100];
+  size_t slen = strlen(name);
+
+  netconn_write(conn, name, slen, NETCONN_COPY);
+  if(slen < 10) {
+    netconn_write(conn, padding_10spaces, 10-slen, NETCONN_COPY);
+  }
+
+  len = (u16_t)sprintf(buf, " * used %"STAT_COUNTER_F NEWLINE, elem->used);
+  netconn_write(conn, buf, len, NETCONN_COPY);
+  len = (u16_t)sprintf(buf, "           * high water mark %"STAT_COUNTER_F NEWLINE, elem->max);
+  netconn_write(conn, buf, len, NETCONN_COPY);
+  len = (u16_t)sprintf(buf, "           * errors %"STAT_COUNTER_F NEWLINE, elem->err);
+  netconn_write(conn, buf, len, NETCONN_COPY);
+}
+static s8_t
+com_stat(struct command *com)
+{
+#if PROTOCOL_STATS || MEMP_STATS
+  size_t i;
+#endif /* PROTOCOL_STATS || MEMP_STATS */
+#if PROTOCOL_STATS
+  size_t k;
+  char buf[100];
+  u16_t len;
+
+  /* protocol stats, @todo: add IGMP */
+  for(i = 0; i < num_protostats; i++) {
+    size_t s = sizeof(struct stats_proto)/sizeof(STAT_COUNTER);
+    STAT_COUNTER *c = &shell_stat_proto_stats[i]->xmit;
+    LWIP_ASSERT("stats not in sync", s == sizeof(stat_msgs_proto)/sizeof(char*));
+    netconn_write(com->conn, shell_stat_proto_names[i], strlen(shell_stat_proto_names[i]), NETCONN_COPY);
+    for(k = 0; k < s; k++) {
+      len = (u16_t)sprintf(buf, "%s%"STAT_COUNTER_F NEWLINE, stat_msgs_proto[k], c[k]);
+      netconn_write(com->conn, buf, len, NETCONN_COPY);
+    }
+  }
+#endif /* PROTOCOL_STATS */
+#if MEM_STATS
+  com_stat_write_mem(com->conn, &lwip_stats.mem, -1);
+#endif /* MEM_STATS */
+#if MEMP_STATS
+  for(i = 0; i < MEMP_MAX; i++) {
+    com_stat_write_mem(com->conn, lwip_stats.memp[i], -1);
+  }
+#endif /* MEMP_STATS */
+#if SYS_STATS
+  com_stat_write_sys(com->conn, &lwip_stats.sys.sem,   "SEM       ");
+  com_stat_write_sys(com->conn, &lwip_stats.sys.mutex, "MUTEX     ");
+  com_stat_write_sys(com->conn, &lwip_stats.sys.mbox,  "MBOX      ");
+#endif /* SYS_STATS */
+
+  return ESUCCESS;
+}
+#endif
+/*-----------------------------------------------------------------------------------*/
+static s8_t
+com_send(struct command *com)
+{
+  int i;
+  err_t err;
+  size_t len;
+  
+  i = strtol(com->args[0], NULL, 10);
+
+  if (i > NCONNS) {
+    sendstr("Connection identifier too high."NEWLINE, com->conn);
+    return ESUCCESS;
+  }
+
+  if (conns[i] == NULL) {
+    sendstr("Connection identifier not in use."NEWLINE, com->conn);
+    return ESUCCESS;
+  }
+
+  len = strlen(com->args[1]);
+  com->args[1][len] = '\r';
+  com->args[1][len + 1] = '\n';
+  com->args[1][len + 2] = 0;
+  
+  err = netconn_write(conns[i], com->args[1], len + 3, NETCONN_COPY);
+  if (err != ERR_OK) {
+    sendstr("Could not send data: ", com->conn);
+#ifdef LWIP_DEBUG
+    sendstr(lwip_strerr(err), com->conn);
+#else
+    sendstr("(debugging must be turned on for error message to appear)", com->conn);
+#endif /* LWIP_DEBUG */
+    sendstr(NEWLINE, com->conn);
+    return ESUCCESS;
+  }
+  
+  sendstr("Data enqueued for sending."NEWLINE, com->conn);
+  return ESUCCESS;
+}
+/*-----------------------------------------------------------------------------------*/
+static s8_t
+com_recv(struct command *com)
+{
+  int i;
+  err_t err;
+  struct netbuf *buf;
+  u16_t len;
+  
+  i = strtol(com->args[0], NULL, 10);
+
+  if (i > NCONNS) {
+    sendstr("Connection identifier too high."NEWLINE, com->conn);
+    return ESUCCESS;
+  }
+
+  if (conns[i] == NULL) {
+    sendstr("Connection identifier not in use."NEWLINE, com->conn);
+    return ESUCCESS;
+  }
+
+  err = netconn_recv(conns[i], &buf);
+  if (err == ERR_OK) {
+      
+    netbuf_copy(buf, buffer, BUFSIZE);
+    len = netbuf_len(buf);
+    sendstr("Reading from connection:"NEWLINE, com->conn);
+    netconn_write(com->conn, buffer, len, NETCONN_COPY);
+    netbuf_delete(buf);
+  } else {
+    sendstr("EOF."NEWLINE, com->conn); 
+  }
+  err = netconn_err(conns[i]);
+  if (err != ERR_OK) {
+    sendstr("Could not receive data: ", com->conn);
+#ifdef LWIP_DEBUG
+    sendstr(lwip_strerr(err), com->conn);
+#else
+    sendstr("(debugging must be turned on for error message to appear)", com->conn);
+#endif /* LWIP_DEBUG */
+    sendstr(NEWLINE, com->conn);
+    return ESUCCESS;
+  }
+  return ESUCCESS;
+}
+/*-----------------------------------------------------------------------------------*/
+static s8_t
+com_udpc(struct command *com)
+{
+  ip_addr_t ipaddr;
+  u16_t lport, rport;
+  int i;
+  err_t err;
+  long tmp;
+
+  tmp = strtol(com->args[0], NULL, 10);
+  if((tmp < 0) || (tmp > 0xffff)) {
+    sendstr("Invalid port number."NEWLINE, com->conn);
+    return ESUCCESS;
+  }
+  lport = (u16_t)tmp;
+  if (ipaddr_aton(com->args[1], &ipaddr) == -1) {
+    sendstr(strerror(errno), com->conn);
+    return ESYNTAX;
+  }
+  tmp = strtol(com->args[2], NULL, 10);
+  if((tmp < 0) || (tmp > 0xffff)) {
+    sendstr("Invalid port number."NEWLINE, com->conn);
+    return ESUCCESS;
+  }
+  rport = (u16_t)tmp;
+
+  /* Find the first unused connection in conns. */
+  for(i = 0; i < NCONNS && conns[i] != NULL; i++);
+
+  if (i == NCONNS) {
+    sendstr("No more connections available, sorry."NEWLINE, com->conn);
+    return ESUCCESS;
+  }
+
+  sendstr("Setting up UDP connection from port ", com->conn);
+  netconn_write(com->conn, com->args[0], strlen(com->args[0]), NETCONN_COPY);
+  sendstr(" to ", com->conn);
+  netconn_write(com->conn, com->args[1], strlen(com->args[1]), NETCONN_COPY);
+  sendstr(":", com->conn);
+  netconn_write(com->conn, com->args[2], strlen(com->args[2]), NETCONN_COPY);
+  sendstr(NEWLINE, com->conn);
+
+  conns[i] = netconn_new(NETCONN_UDP);
+  if (conns[i] == NULL) {    
+    sendstr("Could not create connection identifier (out of memory)."NEWLINE, com->conn); 
+    return ESUCCESS;
+  }
+
+  err = netconn_connect(conns[i], &ipaddr, rport);
+  if (err != ERR_OK) {
+    netconn_delete(conns[i]);
+    conns[i] = NULL;
+    sendstr("Could not connect to remote host: ", com->conn);
+#ifdef LWIP_DEBUG
+    sendstr(lwip_strerr(err), com->conn);
+#else
+    sendstr("(debugging must be turned on for error message to appear)", com->conn);
+#endif /* LWIP_DEBUG */
+    sendstr(NEWLINE, com->conn);
+    return ESUCCESS;
+  }
+
+  err = netconn_bind(conns[i], IP_ADDR_ANY, lport);
+  if (err != ERR_OK) {
+    netconn_delete(conns[i]);
+    conns[i] = NULL;
+    sendstr("Could not bind: ", com->conn);
+#ifdef LWIP_DEBUG
+    sendstr(lwip_strerr(err), com->conn);
+#else
+    sendstr("(debugging must be turned on for error message to appear)", com->conn);
+#endif /* LWIP_DEBUG */
+    sendstr(NEWLINE, com->conn);
+    return ESUCCESS;
+  }
+
+  sendstr("Connection set up, connection identifier is ", com->conn);
+  snprintf((char *)buffer, sizeof(buffer), "%d"NEWLINE, i);
+  netconn_write(com->conn, buffer, strlen((const char *)buffer), NETCONN_COPY);
+  
+  return ESUCCESS;
+}
+/*-----------------------------------------------------------------------------------*/
+static s8_t
+com_udpl(struct command *com)
+{
+  ip_addr_t ipaddr;
+  u16_t lport, rport;
+  int i;
+  err_t err;
+  long tmp;
+
+  tmp = strtol(com->args[0], NULL, 10);
+  if((tmp < 0) || (tmp > 0xffff)) {
+    sendstr("Invalid port number."NEWLINE, com->conn);
+    return ESUCCESS;
+  }
+  lport = (u16_t)tmp;
+  if (ipaddr_aton(com->args[1], &ipaddr) == -1) {
+    sendstr(strerror(errno), com->conn);
+    return ESYNTAX;
+  }
+  tmp = strtol(com->args[2], NULL, 10);
+  if((tmp < 0) || (tmp > 0xffff)) {
+    sendstr("Invalid port number."NEWLINE, com->conn);
+    return ESUCCESS;
+  }
+  rport = (u16_t)tmp;
+
+  /* Find the first unused connection in conns. */
+  for(i = 0; i < NCONNS && conns[i] != NULL; i++);
+
+  if (i == NCONNS) {
+    sendstr("No more connections available, sorry."NEWLINE, com->conn);
+    return ESUCCESS;
+  }
+
+  sendstr("Setting up UDP-Lite connection from port ", com->conn);
+  netconn_write(com->conn, com->args[0], strlen(com->args[0]), NETCONN_COPY);
+  sendstr(" to ", com->conn);
+  netconn_write(com->conn, com->args[1], strlen(com->args[1]), NETCONN_COPY);
+  sendstr(":", com->conn);
+  netconn_write(com->conn, com->args[2], strlen(com->args[2]), NETCONN_COPY);
+  sendstr(NEWLINE, com->conn);
+
+  conns[i] = netconn_new(NETCONN_UDPLITE);
+  if (conns[i] == NULL) {    
+    sendstr("Could not create connection identifier (out of memory)."NEWLINE, com->conn); 
+    return ESUCCESS;
+  }
+
+  err = netconn_connect(conns[i], &ipaddr, rport);
+  if (err != ERR_OK) {
+    netconn_delete(conns[i]);
+    conns[i] = NULL;
+    sendstr("Could not connect to remote host: ", com->conn);
+#ifdef LWIP_DEBUG
+    sendstr(lwip_strerr(err), com->conn);
+#else
+    sendstr("(debugging must be turned on for error message to appear)", com->conn);
+#endif /* LWIP_DEBUG */
+    sendstr(NEWLINE, com->conn);
+    return ESUCCESS;
+  }
+
+  err = netconn_bind(conns[i], IP_ADDR_ANY, lport);
+  if (err != ERR_OK) {
+    netconn_delete(conns[i]);
+    conns[i] = NULL;
+    sendstr("Could not bind: ", com->conn);
+#ifdef LWIP_DEBUG
+    sendstr(lwip_strerr(err), com->conn);
+#else
+    sendstr("(debugging must be turned on for error message to appear)", com->conn);
+#endif /* LWIP_DEBUG */
+    sendstr(NEWLINE, com->conn);
+    return ESUCCESS;
+  }
+
+  sendstr("Connection set up, connection identifier is ", com->conn);
+  snprintf((char *)buffer, sizeof(buffer), "%d"NEWLINE, i);
+  netconn_write(com->conn, buffer, strlen((const char *)buffer), NETCONN_COPY);
+  
+  return ESUCCESS;
+}
+/*-----------------------------------------------------------------------------------*/
+static s8_t
+com_udpn(struct command *com)
+{
+  ip_addr_t ipaddr;
+  u16_t lport, rport;
+  int i;
+  err_t err;
+  long tmp;
+
+  tmp = strtol(com->args[0], NULL, 10);
+  if((tmp < 0) || (tmp > 0xffff)) {
+    sendstr("Invalid port number."NEWLINE, com->conn);
+    return ESUCCESS;
+  }
+  lport = (u16_t)tmp;
+  if (ipaddr_aton(com->args[1], &ipaddr) == -1) {
+    sendstr(strerror(errno), com->conn);
+    return ESYNTAX;
+  }
+  tmp = strtol(com->args[2], NULL, 10);
+  if((tmp < 0) || (tmp > 0xffff)) {
+    sendstr("Invalid port number."NEWLINE, com->conn);
+    return ESUCCESS;
+  }
+  rport = (u16_t)tmp;
+
+  /* Find the first unused connection in conns. */
+  for(i = 0; i < NCONNS && conns[i] != NULL; i++);
+
+  if (i == NCONNS) {
+    sendstr("No more connections available, sorry."NEWLINE, com->conn);
+    return ESUCCESS;
+  }
+
+  sendstr("Setting up UDP connection without checksums from port ", com->conn);
+  netconn_write(com->conn, com->args[0], strlen(com->args[0]), NETCONN_COPY);
+  sendstr(" to ", com->conn);
+  netconn_write(com->conn, com->args[1], strlen(com->args[1]), NETCONN_COPY);
+  sendstr(":", com->conn);
+  netconn_write(com->conn, com->args[2], strlen(com->args[2]), NETCONN_COPY);
+  sendstr(NEWLINE, com->conn);
+
+  conns[i] = netconn_new(NETCONN_UDPNOCHKSUM);
+  if (conns[i] == NULL) {    
+    sendstr("Could not create connection identifier (out of memory)."NEWLINE, com->conn); 
+    return ESUCCESS;
+  }
+
+  err = netconn_connect(conns[i], &ipaddr, rport);
+  if (err != ERR_OK) {
+    netconn_delete(conns[i]);
+    conns[i] = NULL;
+    sendstr("Could not connect to remote host: ", com->conn);
+#ifdef LWIP_DEBUG
+    sendstr(lwip_strerr(err), com->conn);
+#else
+    sendstr("(debugging must be turned on for error message to appear)", com->conn);
+#endif /* LWIP_DEBUG */
+    sendstr(NEWLINE, com->conn);
+    return ESUCCESS;
+  }
+
+  err = netconn_bind(conns[i], IP_ADDR_ANY, lport);
+  if (err != ERR_OK) {
+    netconn_delete(conns[i]);
+    conns[i] = NULL;
+    sendstr("Could not bind: ", com->conn);
+#ifdef LWIP_DEBUG
+    sendstr(lwip_strerr(err), com->conn);
+#else
+    sendstr("(debugging must be turned on for error message to appear)", com->conn);
+#endif /* LWIP_DEBUG */
+    sendstr(NEWLINE, com->conn);
+    return ESUCCESS;
+  }
+
+  sendstr("Connection set up, connection identifier is ", com->conn);
+  snprintf((char *)buffer, sizeof(buffer), "%d"NEWLINE, i);
+  netconn_write(com->conn, buffer, strlen((const char *)buffer), NETCONN_COPY);
+  
+  return ESUCCESS;
+}
+/*-----------------------------------------------------------------------------------*/
+static s8_t
+com_udpb(struct command *com)
+{
+  ip_addr_t ipaddr;
+#if LWIP_IPV4
+  u16_t lport;
+#endif /* LWIP_IPV4 */
+  u16_t rport;
+  int i;
+  err_t err;
+  long tmp;
+
+  tmp = strtol(com->args[0], NULL, 10);
+  if((tmp < 0) || (tmp > 0xffff)) {
+    sendstr("Invalid port number."NEWLINE, com->conn);
+    return ESUCCESS;
+  }
+#if LWIP_IPV4
+  lport = (u16_t)tmp;
+#endif /* LWIP_IPV4 */
+  if (ipaddr_aton(com->args[1], &ipaddr) == -1) {
+    sendstr(strerror(errno), com->conn);
+    return ESYNTAX;
+  }
+  tmp = strtol(com->args[2], NULL, 10);
+  if((tmp < 0) || (tmp > 0xffff)) {
+    sendstr("Invalid port number."NEWLINE, com->conn);
+    return ESUCCESS;
+  }
+  rport = (u16_t)tmp;
+
+  /* Find the first unused connection in conns. */
+  for(i = 0; i < NCONNS && conns[i] != NULL; i++);
+
+  if (i == NCONNS) {
+    sendstr("No more connections available, sorry."NEWLINE, com->conn);
+    return ESUCCESS;
+  }
+
+  sendstr("Setting up UDP broadcast connection from port ", com->conn);
+  netconn_write(com->conn, com->args[0], strlen(com->args[0]), NETCONN_COPY);
+  sendstr(" to ", com->conn);
+  netconn_write(com->conn, com->args[1], strlen(com->args[1]), NETCONN_COPY);
+  sendstr(NEWLINE, com->conn);
+
+  conns[i] = netconn_new(NETCONN_UDP);
+  if (conns[i] == NULL) {    
+    sendstr("Could not create connection identifier (out of memory)."NEWLINE, com->conn); 
+    return ESUCCESS;
+  }
+
+  err = netconn_connect(conns[i], &ipaddr, rport);
+  if (err != ERR_OK) {
+    netconn_delete(conns[i]);
+    conns[i] = NULL;
+    sendstr("Could not connect to remote host: ", com->conn);
+#ifdef LWIP_DEBUG
+    sendstr(lwip_strerr(err), com->conn);
+#else
+    sendstr("(debugging must be turned on for error message to appear)", com->conn);
+#endif /* LWIP_DEBUG */
+    sendstr(NEWLINE, com->conn);
+    return ESUCCESS;
+  }
+
+#if LWIP_IPV4
+  if (IP_IS_V6_VAL(ipaddr)) {
+    err = netconn_bind(conns[i], &ip_addr_broadcast, lport);
+    if (err != ERR_OK) {
+      netconn_delete(conns[i]);
+      conns[i] = NULL;
+      sendstr("Could not bind: ", com->conn);
+#ifdef LWIP_DEBUG
+      sendstr(lwip_strerr(err), com->conn);
+#else
+      sendstr("(debugging must be turned on for error message to appear)", com->conn);
+#endif /* LWIP_DEBUG */
+      sendstr(NEWLINE, com->conn);
+      return ESUCCESS;
+    }
+  }
+#endif /* LWIP_IPV4 */
+
+  sendstr("Connection set up, connection identifier is ", com->conn);
+  snprintf((char *)buffer, sizeof(buffer), "%d"NEWLINE, i);
+  netconn_write(com->conn, buffer, strlen((const char *)buffer), NETCONN_COPY);
+  
+  return ESUCCESS;
+}
+/*-----------------------------------------------------------------------------------*/
+static s8_t
+com_usnd(struct command *com)
+{
+  long i;
+  err_t err;
+  struct netbuf *buf;
+  char *mem;
+  u16_t len;
+  size_t tmp;
+  
+  i = strtol(com->args[0], NULL, 10);
+
+  if (i > NCONNS) {
+    sendstr("Connection identifier too high."NEWLINE, com->conn);
+    return ESUCCESS;
+  }
+
+  if (conns[i] == NULL) {
+    sendstr("Connection identifier not in use."NEWLINE, com->conn);
+    return ESUCCESS;
+  }
+  tmp = strlen(com->args[1]) + 1;
+  if (tmp > 0xffff) {
+    sendstr("Invalid length."NEWLINE, com->conn);
+    return ESUCCESS;
+  }
+  len = (u16_t)tmp;
+
+  buf = netbuf_new();
+  mem = (char *)netbuf_alloc(buf, len);
+  if (mem == NULL) {
+    sendstr("Could not allocate memory for sending."NEWLINE, com->conn);
+    return ESUCCESS;
+  }
+  strncpy(mem, com->args[1], len);
+  err = netconn_send(conns[i], buf);
+  netbuf_delete(buf);
+  if (err != ERR_OK) {
+    sendstr("Could not send data: ", com->conn);
+#ifdef LWIP_DEBUG
+    sendstr(lwip_strerr(err), com->conn);
+#else
+    sendstr("(debugging must be turned on for error message to appear)", com->conn);
+#endif /* LWIP_DEBUG */
+    sendstr(NEWLINE, com->conn);
+    return ESUCCESS;
+  }
+  
+  sendstr("Data sent."NEWLINE, com->conn);
+  return ESUCCESS;
+}
+/*-----------------------------------------------------------------------------------*/
+#if LWIP_SOCKET
+/*-----------------------------------------------------------------------------------*/
+static s8_t
+com_idxtoname(struct command *com)
+{
+  long i = strtol(com->args[0], NULL, 10);
+
+  if (lwip_if_indextoname((unsigned int)i, (char *)buffer)) {
+    netconn_write(com->conn, buffer, strlen((const char *)buffer), NETCONN_COPY);
+    sendstr(NEWLINE, com->conn);
+  } else {
+    snprintf((char *)buffer, sizeof(buffer), "if_indextoname() failed: %d"NEWLINE, errno);
+    netconn_write(com->conn, buffer, strlen((const char *)buffer), NETCONN_COPY);
+  }
+  return ESUCCESS;
+}
+/*-----------------------------------------------------------------------------------*/
+static s8_t
+com_nametoidx(struct command *com)
+{
+  unsigned int idx = lwip_if_nametoindex(com->args[0]);
+
+  if (idx) {
+    snprintf((char *)buffer, sizeof(buffer), "%u"NEWLINE, idx);
+    netconn_write(com->conn, buffer, strlen((const char *)buffer), NETCONN_COPY);
+  } else {
+    sendstr("No interface found"NEWLINE, com->conn);
+  }
+  return ESUCCESS;
+}
+#endif /* LWIP_SOCKET */
+/*-----------------------------------------------------------------------------------*/
+#if LWIP_DNS
+static s8_t
+com_gethostbyname(struct command *com)
+{
+  ip_addr_t addr;
+  err_t err = netconn_gethostbyname(com->args[0], &addr);
+
+  if (err == ERR_OK) {
+    if (ipaddr_ntoa_r(&addr, (char *)buffer, sizeof(buffer))) {
+      sendstr("Host found: ", com->conn);
+      sendstr((char *)buffer, com->conn);
+      sendstr(NEWLINE, com->conn);
+    } else {
+        sendstr("ipaddr_ntoa_r failed", com->conn);
+    }
+  } else {
+    sendstr("No host found"NEWLINE, com->conn);
+  }
+  return ESUCCESS;
+}
+#endif /* LWIP_DNS */
+/*-----------------------------------------------------------------------------------*/
+static s8_t
+com_help(struct command *com)
+{
+  sendstr(help_msg1, com->conn);
+  sendstr(help_msg2, com->conn);
+  sendstr(help_msg3, com->conn);
+  return ESUCCESS;
+}
+/*-----------------------------------------------------------------------------------*/
+static s8_t
+parse_command(struct command *com, u32_t len)
+{
+  u16_t i;
+  u16_t bufp;
+  
+  if (strncmp((const char *)buffer, "open", 4) == 0) {
+    com->exec = com_open;
+    com->nargs = 2;
+  } else if (strncmp((const char *)buffer, "lstn", 4) == 0) {
+    com->exec = com_lstn;
+    com->nargs = 1;
+  } else if (strncmp((const char *)buffer, "acpt", 4) == 0) {
+    com->exec = com_acpt;
+    com->nargs = 1;
+  } else if (strncmp((const char *)buffer, "clos", 4) == 0) {
+    com->exec = com_clos;
+    com->nargs = 1;
+#if LWIP_STATS    
+  } else if (strncmp((const char *)buffer, "stat", 4) == 0) {
+    com->exec = com_stat;
+    com->nargs = 0;
+#endif    
+  } else if (strncmp((const char *)buffer, "send", 4) == 0) {
+    com->exec = com_send;
+    com->nargs = 2;
+  } else if (strncmp((const char *)buffer, "recv", 4) == 0) {
+    com->exec = com_recv;
+    com->nargs = 1;
+  } else if (strncmp((const char *)buffer, "udpc", 4) == 0) {
+    com->exec = com_udpc;
+    com->nargs = 3;
+  } else if (strncmp((const char *)buffer, "udpb", 4) == 0) {
+    com->exec = com_udpb;
+    com->nargs = 2;
+  } else if (strncmp((const char *)buffer, "udpl", 4) == 0) {
+    com->exec = com_udpl;
+    com->nargs = 3;
+  } else if (strncmp((const char *)buffer, "udpn", 4) == 0) {
+    com->exec = com_udpn;
+    com->nargs = 3;
+  } else if (strncmp((const char *)buffer, "usnd", 4) == 0) {
+    com->exec = com_usnd;
+    com->nargs = 2;
+#if LWIP_SOCKET
+  } else if (strncmp((const char *)buffer, "idxtoname", 9) == 0) {
+    com->exec = com_idxtoname;
+    com->nargs = 1;
+  } else if (strncmp((const char *)buffer, "nametoidx", 9) == 0) {
+    com->exec = com_nametoidx;
+    com->nargs = 1;
+#endif /* LWIP_SOCKET */
+#if LWIP_DNS
+  } else if (strncmp((const char *)buffer, "gethostnm", 9) == 0) {
+    com->exec = com_gethostbyname;
+    com->nargs = 1;
+#endif /* LWIP_DNS */
+  } else if (strncmp((const char *)buffer, "help", 4) == 0) {
+    com->exec = com_help;
+    com->nargs = 0;
+  } else if (strncmp((const char *)buffer, "quit", 4) == 0) {
+    printf("quit"NEWLINE);
+    return ECLOSED;
+  } else {
+    return ESYNTAX;
+  }
+
+  if (com->nargs == 0) {
+    return ESUCCESS;
+  }
+  bufp = 0;
+  for(; bufp < len && buffer[bufp] != ' '; bufp++);
+  for(i = 0; i < 10; i++) {
+    for(; bufp < len && buffer[bufp] == ' '; bufp++);
+    if (buffer[bufp] == '\r' ||
+       buffer[bufp] == '\n') {
+      buffer[bufp] = 0;
+      if (i < com->nargs - 1) {
+        return ETOOFEW;
+      }
+      if (i > com->nargs - 1) {
+        return ETOOMANY;
+      }
+      break;
+    }    
+    if (bufp > len) {
+      return ETOOFEW;
+    }    
+    com->args[i] = (char *)&buffer[bufp];
+    for(; bufp < len && buffer[bufp] != ' ' && buffer[bufp] != '\r' &&
+      buffer[bufp] != '\n'; bufp++) {
+      if (buffer[bufp] == '\\') {
+        buffer[bufp] = ' ';
+      }
+    }
+    if (bufp > len) {
+      return ESYNTAX;
+    }
+    buffer[bufp] = 0;
+    bufp++;
+    if (i == com->nargs - 1) {
+      break;
+    }
+
+  }
+
+  return ESUCCESS;
+}
+/*-----------------------------------------------------------------------------------*/
+static void
+shell_error(s8_t err, struct netconn *conn)
+{
+  switch (err) {
+  case ESYNTAX:
+    sendstr("## Syntax error"NEWLINE, conn);
+    break;
+  case ETOOFEW:
+    sendstr("## Too few arguments to command given"NEWLINE, conn);
+    break;
+  case ETOOMANY:
+    sendstr("## Too many arguments to command given"NEWLINE, conn);
+    break;
+  case ECLOSED:
+    sendstr("## Connection closed"NEWLINE, conn);
+    break;
+  default:
+    /* unknown error, don't assert here */
+    break;
+  }
+}
+/*-----------------------------------------------------------------------------------*/
+static void
+prompt(struct netconn *conn)
+{
+  sendstr("> ", conn);
+}  
+/*-----------------------------------------------------------------------------------*/
+static void
+shell_main(struct netconn *conn)
+{
+  struct pbuf *p;
+  u16_t len = 0, cur_len;
+  struct command com;
+  s8_t err;
+  int i;
+  err_t ret;
+#if SHELL_ECHO
+  void *echomem;
+#endif /* SHELL_ECHO */
+  uint8_t c, *pc, state = TELNET_STATE_DATA;
+  int16_t clen;
+
+  do {
+    ret = netconn_recv_tcp_pbuf(conn, &p);
+    if (ret == ERR_OK) {
+      pc   = p->payload;
+      clen = p->tot_len;
+      cur_len = len;
+      while(clen-- > 0) {
+        c = *pc++;
+
+		switch(state){
+		case TELNET_STATE_DATA:
+          if(c == TELNET_IAC) {
+            state = TELNET_STATE_IAC;
+            break;
+          }
+          buffer[len++] = c;
+
+          if(c == '\r')
+            state = TELNET_STATE_CR;
+          break;
+
+        case TELNET_STATE_CR:
+			/*
+			 * Convert CR+something as:
+			 * CR+NUL  = CR only
+			 * CR+LF   = CR+LF or CR only
+			 * CR+else = CR+LF+else or CR+else
+			 */
+          if(c != 0x00){
+            if(c != '\n')
+              buffer[len++] = c;
+          }
+          state = TELNET_STATE_DATA;
+          break;
+
+        case TELNET_STATE_IAC:
+          switch(c){
+          case TELNET_AYT:
+            sendstr(NEWLINE"[yes]"NEWLINE, conn);
+            state = TELNET_STATE_DATA;
+            break;
+          case TELNET_SB:
+            state = TELNET_STATE_SB;
+            break;
+          case TELNET_WILL:
+            state = TELNET_STATE_WILL;
+            break;
+          case TELNET_WONT:
+            state = TELNET_STATE_WONT;
+            break;
+          case TELNET_DO:
+            state = TELNET_STATE_DO;
+            break;
+          case TELNET_DONT:
+            state = TELNET_STATE_DONT;
+            break;
+          case TELNET_IAC:
+            buffer[len++] = c;
+            state = TELNET_STATE_DATA;
+            break;
+          default:
+            state = TELNET_STATE_DATA;
+            break;
+          }
+          break;
+
+		case TELNET_STATE_SB:
+			if(c == TELNET_IAC)
+              state = TELNET_STATE_SE;
+			break;
+
+		case TELNET_STATE_SE:
+			if (c == TELNET_SE)
+				state = TELNET_STATE_DATA;
+			else
+				state = TELNET_STATE_SB;
+			break;
+        default:
+			state = TELNET_STATE_DATA;
+			break;
+		}
+      }
+#if SHELL_ECHO
+      if(len > cur_len){
+        echomem = mem_malloc(len-cur_len+1);
+        if (echomem != NULL) {
+          buffer[len] = '\n';
+          MEMCPY(echomem, &buffer[cur_len], len-cur_len+1);
+          if(buffer[len-1] == '\r')
+            netconn_write(conn, echomem, len-cur_len+1, NETCONN_COPY);
+          else
+            netconn_write(conn, echomem, len-cur_len, NETCONN_COPY);
+          mem_free(echomem);
+        }
+      }
+#endif /* SHELL_ECHO */
+      pbuf_free(p);
+      if (((len > 0) && ((buffer[len-1] == '\r') || (buffer[len-1] == '\n'))) ||
+          (len >= BUFSIZE)) {
+        if (buffer[0] != 0xff && 
+           buffer[1] != 0xfe && len > 1) {
+          err = parse_command(&com, len);
+          if (err == ESUCCESS) {
+            com.conn = conn;
+            err = com.exec(&com);
+          }
+          if (err == ECLOSED) {
+            printf("Closed"NEWLINE);
+            shell_error(err, conn);
+            goto close;
+          }
+          if (err != ESUCCESS) {
+            shell_error(err, conn);
+          }
+        } else {
+          sendstr(NEWLINE NEWLINE
+                  "lwIP simple interactive shell."NEWLINE
+                  "(c) Copyright 2001, Swedish Institute of Computer Science."NEWLINE
+                  "Written by Adam Dunkels."NEWLINE
+                  "For help, try the \"help\" command."NEWLINE, conn);
+        }
+        if (ret == ERR_OK) {
+          prompt(conn);
+        }
+        len = 0;
+      }
+    }
+  } while (ret == ERR_OK);
+  if(err == ERR_CLSD)
+    printf("disconnect !"NEWLINE);
+  else
+    printf("err %s"NEWLINE, lwip_strerr(ret));
+
+close:
+  netconn_close(conn);
+
+  for(i = 0; i < NCONNS; i++) {
+    if (conns[i] != NULL) {
+      netconn_delete(conns[i]);
+    }
+    conns[i] = NULL;
+  }
+}
+/*-----------------------------------------------------------------------------------*/
+static void 
+shell_thread(void *arg)
+{
+  struct netconn *conn, *newconn;
+  err_t err;
+  LWIP_UNUSED_ARG(arg);
+
+#if LWIP_IPV4	/* LWIP_IPV4 */
+  conn = netconn_new(NETCONN_TCP);
+  LWIP_ERROR("shell: invalid conn", (conn != NULL), return;);
+  err = netconn_bind(conn, IP_ADDR_ANY, 23);
+#elif LWIP_IPV6	/* LWIP_IPV6 */
+  conn = netconn_new(NETCONN_TCP_IPV6);
+  LWIP_ERROR("shell: invalid conn", (conn != NULL), return;);
+  err = netconn_bind(conn, IP6_ADDR_ANY, 23);
+#endif /* LWIP_IPV6 */
+  LWIP_ERROR("shell: netconn_bind failed", (err == ERR_OK), netconn_delete(conn); return;);
+  err = netconn_listen(conn);
+  LWIP_ERROR("shell: netconn_listen failed", (err == ERR_OK), netconn_delete(conn); return;);
+
+  while (1) {
+    err = netconn_accept(conn, &newconn);
+    if (err == ERR_OK) {
+      shell_main(newconn);
+      netconn_delete(newconn);
+    }
+  }
+}
+/*-----------------------------------------------------------------------------------*/
+void
+shell_init(void)
+{
+  sys_thread_new("shell_thread", shell_thread, NULL, DEFAULT_THREAD_STACKSIZE, DEFAULT_THREAD_PRIO);
+}
+
+#endif /* LWIP_NETCONN && LWIP_TCP */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/shell/shell.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/shell/shell.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/shell/shell.h	(revision 457)
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2001-2003 Swedish Institute of Computer Science.
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission. 
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ * 
+ * Author: Adam Dunkels <adam@sics.se>
+ *
+ */
+#ifndef LWIP_SHELL_H
+#define LWIP_SHELL_H
+
+void shell_init(void);
+
+#endif /* LWIP_SHELL_H */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/socket_examples/socket_examples.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/socket_examples/socket_examples.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/socket_examples/socket_examples.c	(revision 457)
@@ -0,0 +1,680 @@
+
+#include "socket_examples.h"
+
+#include "lwip/opt.h"
+
+#if LWIP_SOCKET && (LWIP_IPV4 || LWIP_IPV6)
+
+#include "lwip/sockets.h"
+#include "lwip/sys.h"
+
+#include <string.h>
+#include <stdio.h>
+
+#ifndef SOCK_TARGET_HOST4
+#define SOCK_TARGET_HOST4  "192.168.0.1"
+#endif
+
+#ifndef SOCK_TARGET_HOST6
+#define SOCK_TARGET_HOST6  "FE80::12:34FF:FE56:78AB"
+#endif
+
+#ifndef SOCK_TARGET_PORT
+#define SOCK_TARGET_PORT  80
+#endif
+
+#ifndef SOCK_TARGET_MAXHTTPPAGESIZE
+#define SOCK_TARGET_MAXHTTPPAGESIZE 1024
+#endif
+
+#ifndef SOCKET_EXAMPLES_RUN_PARALLEL
+#define SOCKET_EXAMPLES_RUN_PARALLEL 0
+#endif
+
+const u8_t cmpbuf[8] = {0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab};
+
+/* a helper struct to ensure memory before/after fd_set is not touched */
+typedef struct _xx
+{
+  u8_t buf1[8];
+  fd_set readset;
+  u8_t buf2[8];
+  fd_set writeset;
+  u8_t buf3[8];
+  fd_set errset;
+  u8_t buf4[8];
+} fdsets;
+
+#define INIT_FDSETS(sets) do { \
+  memset((sets)->buf1, 0xab, 8); \
+  memset((sets)->buf2, 0xab, 8); \
+  memset((sets)->buf3, 0xab, 8); \
+  memset((sets)->buf4, 0xab, 8); \
+}while(0)
+
+#define CHECK_FDSETS(sets) do { \
+  LWIP_ASSERT("buf1 fail", !memcmp((sets)->buf1, cmpbuf, 8)); \
+  LWIP_ASSERT("buf2 fail", !memcmp((sets)->buf2, cmpbuf, 8)); \
+  LWIP_ASSERT("buf3 fail", !memcmp((sets)->buf3, cmpbuf, 8)); \
+  LWIP_ASSERT("buf4 fail", !memcmp((sets)->buf4, cmpbuf, 8)); \
+}while(0)
+
+static ip_addr_t dstaddr;
+
+/** This is an example function that tests
+    blocking- and nonblocking connect. */
+static void
+sockex_nonblocking_connect(void *arg)
+{
+#if LWIP_SOCKET_SELECT
+  int s;
+  int ret;
+  int opt;
+#if LWIP_IPV6
+  struct sockaddr_in6 addr;
+#else /* LWIP_IPV6 */
+  struct sockaddr_in addr;
+#endif /* LWIP_IPV6 */
+  fdsets sets;
+  struct timeval tv;
+  u32_t ticks_a, ticks_b;
+  int err;
+  const ip_addr_t *ipaddr = (const ip_addr_t*)arg;
+  struct pollfd fds;
+  INIT_FDSETS(&sets);
+
+  /* set up address to connect to */
+  memset(&addr, 0, sizeof(addr));
+#if LWIP_IPV6
+  addr.sin6_len = sizeof(addr);
+  addr.sin6_family = AF_INET6;
+  addr.sin6_port = PP_HTONS(SOCK_TARGET_PORT);
+  inet6_addr_from_ip6addr(&addr.sin6_addr, ip_2_ip6(ipaddr));
+#else /* LWIP_IPV6 */
+  addr.sin_len = sizeof(addr);
+  addr.sin_family = AF_INET;
+  addr.sin_port = PP_HTONS(SOCK_TARGET_PORT);
+  inet_addr_from_ip4addr(&addr.sin_addr, ip_2_ip4(ipaddr));
+#endif /* LWIP_IPV6 */
+
+  /* first try blocking: */
+
+  /* create the socket */
+#if LWIP_IPV6
+  s = lwip_socket(AF_INET6, SOCK_STREAM, 0);
+#else /* LWIP_IPV6 */
+  s = lwip_socket(AF_INET, SOCK_STREAM, 0);
+#endif /* LWIP_IPV6 */
+  LWIP_ASSERT("s >= 0", s >= 0);
+
+  /* connect */
+  ret = lwip_connect(s, (struct sockaddr*)&addr, sizeof(addr));
+  /* should succeed */
+  LWIP_ASSERT("ret == 0", ret == 0);
+
+  /* write something */
+  ret = lwip_write(s, "test", 4);
+  LWIP_ASSERT("ret == 4", ret == 4);
+
+  /* close */
+  ret = lwip_close(s);
+  LWIP_ASSERT("ret == 0", ret == 0);
+
+  /* now try nonblocking and close before being connected */
+
+  /* create the socket */
+#if LWIP_IPV6
+  s = lwip_socket(AF_INET6, SOCK_STREAM, 0);
+#else /* LWIP_IPV6 */
+  s = lwip_socket(AF_INET, SOCK_STREAM, 0);
+#endif /* LWIP_IPV6 */
+  LWIP_ASSERT("s >= 0", s >= 0);
+  /* nonblocking */
+  opt = lwip_fcntl(s, F_GETFL, 0);
+  LWIP_ASSERT("ret != -1", ret != -1);
+  opt |= O_NONBLOCK;
+  ret = lwip_fcntl(s, F_SETFL, opt);
+  LWIP_ASSERT("ret != -1", ret != -1);
+  /* connect */
+  ret = lwip_connect(s, (struct sockaddr*)&addr, sizeof(addr));
+  /* should have an error: "inprogress" */
+  LWIP_ASSERT("ret == -1", ret == -1);
+  err = errno;
+  LWIP_ASSERT("errno == EINPROGRESS", err == EINPROGRESS);
+  /* close */
+  ret = lwip_close(s);
+  LWIP_ASSERT("ret == 0", ret == 0);
+  /* try to close again, should fail with EBADF */
+  ret = lwip_close(s);
+  LWIP_ASSERT("ret == -1", ret == -1);
+  err = errno;
+  LWIP_ASSERT("errno == EBADF", err == EBADF);
+  printf("closing socket in nonblocking connect succeeded\n");
+
+  /* now try nonblocking, connect should succeed:
+     this test only works if it is fast enough, i.e. no breakpoints, please! */
+
+  /* create the socket */
+#if LWIP_IPV6
+  s = lwip_socket(AF_INET6, SOCK_STREAM, 0);
+#else /* LWIP_IPV6 */
+  s = lwip_socket(AF_INET, SOCK_STREAM, 0);
+#endif /* LWIP_IPV6 */
+  LWIP_ASSERT("s >= 0", s >= 0);
+
+  /* nonblocking */
+  opt = 1;
+  ret = lwip_ioctl(s, FIONBIO, &opt);
+  LWIP_ASSERT("ret == 0", ret == 0);
+
+  /* connect */
+  ret = lwip_connect(s, (struct sockaddr*)&addr, sizeof(addr));
+  /* should have an error: "inprogress" */
+  LWIP_ASSERT("ret == -1", ret == -1);
+  err = errno;
+  LWIP_ASSERT("errno == EINPROGRESS", err == EINPROGRESS);
+
+  /* write should fail, too */
+  ret = lwip_write(s, "test", 4);
+  LWIP_ASSERT("ret == -1", ret == -1);
+  err = errno;
+  LWIP_ASSERT("errno == EINPROGRESS", err == EINPROGRESS);
+
+  CHECK_FDSETS(&sets);
+  FD_ZERO(&sets.readset);
+  CHECK_FDSETS(&sets);
+  FD_SET(s, &sets.readset);
+  CHECK_FDSETS(&sets);
+  FD_ZERO(&sets.writeset);
+  CHECK_FDSETS(&sets);
+  FD_SET(s, &sets.writeset);
+  CHECK_FDSETS(&sets);
+  FD_ZERO(&sets.errset);
+  CHECK_FDSETS(&sets);
+  FD_SET(s, &sets.errset);
+  CHECK_FDSETS(&sets);
+  tv.tv_sec = 0;
+  tv.tv_usec = 0;
+  /* select without waiting should fail */
+  ret = lwip_select(s + 1, &sets.readset, &sets.writeset, &sets.errset, &tv);
+  CHECK_FDSETS(&sets);
+  LWIP_ASSERT("ret == 0", ret == 0);
+  LWIP_ASSERT("!FD_ISSET(s, &writeset)", !FD_ISSET(s, &sets.writeset));
+  LWIP_ASSERT("!FD_ISSET(s, &readset)", !FD_ISSET(s, &sets.readset));
+  LWIP_ASSERT("!FD_ISSET(s, &errset)", !FD_ISSET(s, &sets.errset));
+
+  fds.fd = s;
+  fds.events = POLLIN|POLLOUT;
+  fds.revents = 0;
+  ret = lwip_poll(&fds, 1, 0);
+  LWIP_ASSERT("ret == 0", ret == 0);
+  LWIP_ASSERT("fds.revents == 0", fds.revents == 0);
+
+  FD_ZERO(&sets.readset);
+  FD_SET(s, &sets.readset);
+  FD_ZERO(&sets.writeset);
+  FD_SET(s, &sets.writeset);
+  FD_ZERO(&sets.errset);
+  FD_SET(s, &sets.errset);
+  ticks_a = sys_now();
+  /* select with waiting should succeed */
+  ret = lwip_select(s + 1, &sets.readset, &sets.writeset, &sets.errset, NULL);
+  ticks_b = sys_now();
+  LWIP_ASSERT("ret == 1", ret == 1);
+  LWIP_ASSERT("FD_ISSET(s, &writeset)", FD_ISSET(s, &sets.writeset));
+  LWIP_ASSERT("!FD_ISSET(s, &readset)", !FD_ISSET(s, &sets.readset));
+  LWIP_ASSERT("!FD_ISSET(s, &errset)", !FD_ISSET(s, &sets.errset));
+
+  fds.fd = s;
+  fds.events = POLLIN|POLLOUT;
+  fds.revents = 0;
+  ret = lwip_poll(&fds, 1, 0);
+  LWIP_ASSERT("ret == 1", ret == 1);
+  LWIP_ASSERT("fds.revents & POLLOUT", fds.revents & POLLOUT);
+
+  /* now write should succeed */
+  ret = lwip_write(s, "test", 4);
+  LWIP_ASSERT("ret == 4", ret == 4);
+
+  /* close */
+  ret = lwip_close(s);
+  LWIP_ASSERT("ret == 0", ret == 0);
+
+  printf("select() needed %d ticks to return writable\n", (int)(ticks_b - ticks_a));
+
+
+  /* now try nonblocking to invalid address:
+     this test only works if it is fast enough, i.e. no breakpoints, please! */
+
+  /* create the socket */
+#if LWIP_IPV6
+  s = lwip_socket(AF_INET6, SOCK_STREAM, 0);
+#else /* LWIP_IPV6 */
+  s = lwip_socket(AF_INET, SOCK_STREAM, 0);
+#endif /* LWIP_IPV6 */
+  LWIP_ASSERT("s >= 0", s >= 0);
+
+  /* nonblocking */
+  opt = 1;
+  ret = lwip_ioctl(s, FIONBIO, &opt);
+  LWIP_ASSERT("ret == 0", ret == 0);
+
+#if LWIP_IPV6
+  addr.sin6_addr.un.u8_addr[0]++; /* this should result in an invalid address */
+#else /* LWIP_IPV6 */
+  addr.sin_addr.s_addr++; /* this should result in an invalid address */
+#endif /* LWIP_IPV6 */
+
+  /* connect */
+  ret = lwip_connect(s, (struct sockaddr*)&addr, sizeof(addr));
+  /* should have an error: "inprogress" */
+  LWIP_ASSERT("ret == -1", ret == -1);
+  err = errno;
+  LWIP_ASSERT("errno == EINPROGRESS", err == EINPROGRESS);
+
+  /* write should fail, too */
+  ret = lwip_write(s, "test", 4);
+  LWIP_ASSERT("ret == -1", ret == -1);
+  err = errno;
+  LWIP_ASSERT("errno == EINPROGRESS", err == EINPROGRESS);
+  LWIP_UNUSED_ARG(err);
+
+  FD_ZERO(&sets.readset);
+  FD_SET(s, &sets.readset);
+  FD_ZERO(&sets.writeset);
+  FD_SET(s, &sets.writeset);
+  FD_ZERO(&sets.errset);
+  FD_SET(s, &sets.errset);
+  tv.tv_sec = 0;
+  tv.tv_usec = 0;
+  /* select without waiting should fail */
+  ret = lwip_select(s + 1, &sets.readset, &sets.writeset, &sets.errset, &tv);
+  LWIP_ASSERT("ret == 0", ret == 0);
+
+  FD_ZERO(&sets.readset);
+  FD_SET(s, &sets.readset);
+  FD_ZERO(&sets.writeset);
+  FD_SET(s, &sets.writeset);
+  FD_ZERO(&sets.errset);
+  FD_SET(s, &sets.errset);
+  ticks_a = sys_now();
+  /* select with waiting should eventually succeed and return errset! */
+  ret = lwip_select(s + 1, &sets.readset, &sets.writeset, &sets.errset, NULL);
+  ticks_b = sys_now();
+  LWIP_ASSERT("ret > 0", ret > 0);
+  LWIP_ASSERT("FD_ISSET(s, &errset)", FD_ISSET(s, &sets.errset));
+  /*LWIP_ASSERT("!FD_ISSET(s, &readset)", !FD_ISSET(s, &sets.readset));
+  LWIP_ASSERT("!FD_ISSET(s, &writeset)", !FD_ISSET(s, &sets.writeset));*/
+
+  /* close */
+  ret = lwip_close(s);
+  LWIP_ASSERT("ret == 0", ret == 0);
+  LWIP_UNUSED_ARG(ret);
+
+  printf("select() needed %d ticks to return error\n", (int)(ticks_b - ticks_a));
+  printf("sockex_nonblocking_connect finished successfully\n");
+#else
+  LWIP_UNUSED_ARG(arg);
+#endif
+}
+
+/** This is an example function that tests
+    the recv function (timeout etc.). */
+static void
+sockex_testrecv(void *arg)
+{
+  int s;
+  int ret;
+  int err;
+#if LWIP_SO_SNDRCVTIMEO_NONSTANDARD
+  int opt, opt2;
+#else
+  struct timeval opt, opt2;
+#endif
+  socklen_t opt2size;
+#if LWIP_IPV6
+  struct sockaddr_in6 addr;
+#else /* LWIP_IPV6 */
+  struct sockaddr_in addr;
+#endif /* LWIP_IPV6 */
+  size_t len;
+  char rxbuf[SOCK_TARGET_MAXHTTPPAGESIZE];
+#if LWIP_SOCKET_SELECT
+  fd_set readset;
+  fd_set errset;
+  struct timeval tv;
+#endif
+  const ip_addr_t *ipaddr = (const ip_addr_t*)arg;
+
+  /* set up address to connect to */
+  memset(&addr, 0, sizeof(addr));
+#if LWIP_IPV6
+  addr.sin6_len = sizeof(addr);
+  addr.sin6_family = AF_INET6;
+  addr.sin6_port = PP_HTONS(SOCK_TARGET_PORT);
+  inet6_addr_from_ip6addr(&addr.sin6_addr, ip_2_ip6(ipaddr));
+#else /* LWIP_IPV6 */
+  addr.sin_len = sizeof(addr);
+  addr.sin_family = AF_INET;
+  addr.sin_port = PP_HTONS(SOCK_TARGET_PORT);
+  inet_addr_from_ip4addr(&addr.sin_addr, ip_2_ip4(ipaddr));
+#endif /* LWIP_IPV6 */
+
+  /* first try blocking: */
+
+  /* create the socket */
+#if LWIP_IPV6
+  s = lwip_socket(AF_INET6, SOCK_STREAM, 0);
+#else /* LWIP_IPV6 */
+  s = lwip_socket(AF_INET, SOCK_STREAM, 0);
+#endif /* LWIP_IPV6 */
+  LWIP_ASSERT("s >= 0", s >= 0);
+
+  /* connect */
+  ret = lwip_connect(s, (struct sockaddr*)&addr, sizeof(addr));
+  /* should succeed */
+  LWIP_ASSERT("ret == 0", ret == 0);
+
+  /* set recv timeout (100 ms) */
+#if LWIP_SO_SNDRCVTIMEO_NONSTANDARD
+  opt = 100;
+#else
+  opt.tv_sec = 0;
+  opt.tv_usec = 100 * 1000;
+#endif
+  ret = lwip_setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, &opt, sizeof(opt));
+  LWIP_ASSERT("ret == 0", ret == 0);
+#if LWIP_SO_SNDRCVTIMEO_NONSTANDARD
+  opt2 = 0;
+#else
+  opt2.tv_sec = 0;
+  opt2.tv_usec = 0;
+#endif
+  opt2size = sizeof(opt2);
+  ret = lwip_getsockopt(s, SOL_SOCKET, SO_RCVTIMEO, &opt2, &opt2size);
+  LWIP_ASSERT("ret == 0", ret == 0);
+  LWIP_ASSERT("opt2size == sizeof(opt2)", opt2size == sizeof(opt2));
+#if LWIP_SO_SNDRCVTIMEO_NONSTANDARD
+  LWIP_ASSERT("opt == opt2", opt == opt2);
+#else
+  LWIP_ASSERT("opt == opt2", opt.tv_sec == opt2.tv_sec);
+  LWIP_ASSERT("opt == opt2", opt.tv_usec == opt2.tv_usec);
+#endif
+
+  /* write the start of a GET request */
+#define SNDSTR1 "G"
+  len = strlen(SNDSTR1);
+  ret = lwip_write(s, SNDSTR1, len);
+  LWIP_ASSERT("ret == len", ret == (int)len);
+
+  /* should time out if the other side is a good HTTP server */
+  ret = lwip_read(s, rxbuf, 1);
+  LWIP_ASSERT("ret == -1", ret == -1);
+  err = errno;
+  LWIP_ASSERT("errno == EAGAIN", err == EAGAIN);
+  LWIP_UNUSED_ARG(err);
+
+  /* write the rest of a GET request */
+#define SNDSTR2 "ET / HTTP_1.1\r\n\r\n"
+  len = strlen(SNDSTR2);
+  ret = lwip_write(s, SNDSTR2, len);
+  LWIP_ASSERT("ret == len", ret == (int)len);
+
+  /* wait a while: should be enough for the server to send a response */
+  sys_msleep(1000);
+
+  /* should not time out but receive a response */
+  ret = lwip_read(s, rxbuf, SOCK_TARGET_MAXHTTPPAGESIZE);
+  LWIP_ASSERT("ret > 0", ret > 0);
+
+#if LWIP_SOCKET_SELECT
+  /* now select should directly return because the socket is readable */
+  FD_ZERO(&readset);
+  FD_ZERO(&errset);
+  FD_SET(s, &readset);
+  FD_SET(s, &errset);
+  tv.tv_sec = 10;
+  tv.tv_usec = 0;
+  ret = lwip_select(s + 1, &readset, NULL, &errset, &tv);
+  LWIP_ASSERT("ret == 1", ret == 1);
+  LWIP_ASSERT("!FD_ISSET(s, &errset)", !FD_ISSET(s, &errset));
+  LWIP_ASSERT("FD_ISSET(s, &readset)", FD_ISSET(s, &readset));
+#endif
+
+  /* should not time out but receive a response */
+  ret = lwip_read(s, rxbuf, SOCK_TARGET_MAXHTTPPAGESIZE);
+  /* might receive a second packet for HTTP/1.1 servers */
+  if (ret > 0) {
+    /* should return 0: closed */
+    ret = lwip_read(s, rxbuf, SOCK_TARGET_MAXHTTPPAGESIZE);
+    LWIP_ASSERT("ret == 0", ret == 0);
+  }
+
+  /* close */
+  ret = lwip_close(s);
+  LWIP_ASSERT("ret == 0", ret == 0);
+  LWIP_UNUSED_ARG(ret);
+
+  printf("sockex_testrecv finished successfully\n");
+}
+
+#if LWIP_SOCKET_SELECT
+/** helper struct for the 2 functions below (multithreaded: thread-argument) */
+struct sockex_select_helper {
+  int socket;
+  int wait_read;
+  int expect_read;
+  int wait_write;
+  int expect_write;
+  int wait_err;
+  int expect_err;
+  int wait_ms;
+  sys_sem_t sem;
+};
+
+/** helper thread to wait for socket events using select */
+static void
+sockex_select_waiter(void *arg)
+{
+  struct sockex_select_helper *helper = (struct sockex_select_helper *)arg;
+  int ret;
+  fd_set readset;
+  fd_set writeset;
+  fd_set errset;
+  struct timeval tv;
+
+  LWIP_ASSERT("helper != NULL", helper != NULL);
+
+  FD_ZERO(&readset);
+  FD_ZERO(&writeset);
+  FD_ZERO(&errset);
+  if (helper->wait_read) {
+    FD_SET(helper->socket, &readset);
+  }
+  if (helper->wait_write) {
+    FD_SET(helper->socket, &writeset);
+  }
+  if (helper->wait_err) {
+    FD_SET(helper->socket, &errset);
+  }
+
+  tv.tv_sec = helper->wait_ms / 1000;
+  tv.tv_usec = (helper->wait_ms % 1000) * 1000;
+
+  ret = lwip_select(helper->socket, &readset, &writeset, &errset, &tv);
+  if (helper->expect_read || helper->expect_write || helper->expect_err) {
+    LWIP_ASSERT("ret > 0", ret > 0);
+  } else {
+    LWIP_ASSERT("ret == 0", ret == 0);
+  }
+  LWIP_UNUSED_ARG(ret);
+  if (helper->expect_read) {
+    LWIP_ASSERT("FD_ISSET(helper->socket, &readset)", FD_ISSET(helper->socket, &readset));
+  } else {
+    LWIP_ASSERT("!FD_ISSET(helper->socket, &readset)", !FD_ISSET(helper->socket, &readset));
+  }
+  if (helper->expect_write) {
+    LWIP_ASSERT("FD_ISSET(helper->socket, &writeset)", FD_ISSET(helper->socket, &writeset));
+  } else {
+    LWIP_ASSERT("!FD_ISSET(helper->socket, &writeset)", !FD_ISSET(helper->socket, &writeset));
+  }
+  if (helper->expect_err) {
+    LWIP_ASSERT("FD_ISSET(helper->socket, &errset)", FD_ISSET(helper->socket, &errset));
+  } else {
+    LWIP_ASSERT("!FD_ISSET(helper->socket, &errset)", !FD_ISSET(helper->socket, &errset));
+  }
+  sys_sem_signal(&helper->sem);
+}
+
+/** This is an example function that tests
+    more than one thread being active in select. */
+static void
+sockex_testtwoselects(void *arg)
+{
+  int s1;
+  int s2;
+  int ret;
+#if LWIP_IPV6
+  struct sockaddr_in6 addr;
+#else /* LWIP_IPV6 */
+  struct sockaddr_in addr;
+#endif /* LWIP_IPV6 */
+  size_t len;
+  err_t lwiperr;
+  struct sockex_select_helper h1, h2, h3, h4;
+  const ip_addr_t *ipaddr = (const ip_addr_t*)arg;
+
+  /* set up address to connect to */
+  memset(&addr, 0, sizeof(addr));
+#if LWIP_IPV6
+  addr.sin6_len = sizeof(addr);
+  addr.sin6_family = AF_INET6;
+  addr.sin6_port = PP_HTONS(SOCK_TARGET_PORT);
+  inet6_addr_from_ip6addr(&addr.sin6_addr, ip_2_ip6(ipaddr));
+#else /* LWIP_IPV6 */
+  addr.sin_len = sizeof(addr);
+  addr.sin_family = AF_INET;
+  addr.sin_port = PP_HTONS(SOCK_TARGET_PORT);
+  inet_addr_from_ip4addr(&addr.sin_addr, ip_2_ip4(ipaddr));
+#endif /* LWIP_IPV6 */
+
+  /* create the sockets */
+#if LWIP_IPV6
+  s1 = lwip_socket(AF_INET6, SOCK_STREAM, 0);
+  s2 = lwip_socket(AF_INET6, SOCK_STREAM, 0);
+#else /* LWIP_IPV6 */
+  s1 = lwip_socket(AF_INET, SOCK_STREAM, 0);
+  s2 = lwip_socket(AF_INET, SOCK_STREAM, 0);
+#endif /* LWIP_IPV6 */
+  LWIP_ASSERT("s1 >= 0", s1 >= 0);
+  LWIP_ASSERT("s2 >= 0", s2 >= 0);
+
+  /* connect, should succeed */
+  ret = lwip_connect(s1, (struct sockaddr*)&addr, sizeof(addr));
+  LWIP_ASSERT("ret == 0", ret == 0);
+  ret = lwip_connect(s2, (struct sockaddr*)&addr, sizeof(addr));
+  LWIP_ASSERT("ret == 0", ret == 0);
+
+  /* write the start of a GET request */
+#define SNDSTR1 "G"
+  len = strlen(SNDSTR1);
+  ret = lwip_write(s1, SNDSTR1, len);
+  LWIP_ASSERT("ret == len", ret == (int)len);
+  ret = lwip_write(s2, SNDSTR1, len);
+  LWIP_ASSERT("ret == len", ret == (int)len);
+  LWIP_UNUSED_ARG(ret);
+
+  h1.wait_read  = 1;
+  h1.wait_write = 1;
+  h1.wait_err   = 1;
+  h1.expect_read  = 0;
+  h1.expect_write = 0;
+  h1.expect_err   = 0;
+  lwiperr = sys_sem_new(&h1.sem, 0);
+  LWIP_ASSERT("lwiperr == ERR_OK", lwiperr == ERR_OK);
+  h1.socket = s1;
+  h1.wait_ms = 500;
+
+  h2 = h1;
+  lwiperr = sys_sem_new(&h2.sem, 0);
+  LWIP_ASSERT("lwiperr == ERR_OK", lwiperr == ERR_OK);
+  h2.socket = s2;
+  h2.wait_ms = 1000;
+
+  h3 = h1;
+  lwiperr = sys_sem_new(&h3.sem, 0);
+  LWIP_ASSERT("lwiperr == ERR_OK", lwiperr == ERR_OK);
+  h3.socket = s2;
+  h3.wait_ms = 1500;
+
+  h4 = h1;
+  lwiperr = sys_sem_new(&h4.sem, 0);
+  LWIP_ASSERT("lwiperr == ERR_OK", lwiperr == ERR_OK);
+  LWIP_UNUSED_ARG(lwiperr);
+  h4.socket = s2;
+  h4.wait_ms = 2000;
+
+  /* select: all sockets should time out if the other side is a good HTTP server */
+
+  sys_thread_new("sockex_select_waiter1", sockex_select_waiter, &h2, 0, 0);
+  sys_msleep(100);
+  sys_thread_new("sockex_select_waiter2", sockex_select_waiter, &h1, 0, 0);
+  sys_msleep(100);
+  sys_thread_new("sockex_select_waiter2", sockex_select_waiter, &h4, 0, 0);
+  sys_msleep(100);
+  sys_thread_new("sockex_select_waiter2", sockex_select_waiter, &h3, 0, 0);
+
+  sys_sem_wait(&h1.sem);
+  sys_sem_wait(&h2.sem);
+  sys_sem_wait(&h3.sem);
+  sys_sem_wait(&h4.sem);
+
+  /* close */
+  ret = lwip_close(s1);
+  LWIP_ASSERT("ret == 0", ret == 0);
+  ret = lwip_close(s2);
+  LWIP_ASSERT("ret == 0", ret == 0);
+
+  printf("sockex_testtwoselects finished successfully\n");
+}
+#else
+static void
+sockex_testtwoselects(void *arg)
+{
+  LWIP_UNUSED_ARG(arg);
+}
+#endif
+
+#if !SOCKET_EXAMPLES_RUN_PARALLEL
+static void
+socket_example_test(void* arg)
+{
+  sys_msleep(1000);
+  sockex_nonblocking_connect(arg);
+  sockex_testrecv(arg);
+  sockex_testtwoselects(arg);
+  printf("all tests done, thread ending\n");
+}
+#endif
+
+void socket_examples_init(void)
+{
+  int addr_ok;
+#if LWIP_IPV6
+  IP_SET_TYPE_VAL(dstaddr, IPADDR_TYPE_V6);
+  addr_ok = ip6addr_aton(SOCK_TARGET_HOST6, ip_2_ip6(&dstaddr));
+#else /* LWIP_IPV6 */
+  IP_SET_TYPE_VAL(dstaddr, IPADDR_TYPE_V4);
+  addr_ok = ip4addr_aton(SOCK_TARGET_HOST4, ip_2_ip4(&dstaddr));
+#endif /* LWIP_IPV6 */
+  LWIP_ASSERT("invalid address", addr_ok);
+#if SOCKET_EXAMPLES_RUN_PARALLEL
+  sys_thread_new("sockex_nonblocking_connect", sockex_nonblocking_connect, &dstaddr, 0, 0);
+  sys_thread_new("sockex_testrecv", sockex_testrecv, &dstaddr, 0, 0);
+  sys_thread_new("sockex_testtwoselects", sockex_testtwoselects, &dstaddr, 0, 0);
+#else
+  sys_thread_new("socket_example_test", socket_example_test, &dstaddr, 0, 0);
+#endif
+}
+
+#endif /* LWIP_SOCKET */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/socket_examples/socket_examples.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/socket_examples/socket_examples.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/socket_examples/socket_examples.h	(revision 457)
@@ -0,0 +1,6 @@
+#ifndef LWIP_SOCKET_EXAMPLES_H
+#define LWIP_SOCKET_EXAMPLES_H
+
+void socket_examples_init(void);
+
+#endif /* LWIP_SOCKET_EXAMPLES_H */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/tcpecho/tcpecho.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/tcpecho/tcpecho.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/tcpecho/tcpecho.c	(revision 457)
@@ -0,0 +1,101 @@
+/*
+ * Copyright (c) 2001-2003 Swedish Institute of Computer Science.
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission. 
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ * 
+ * Author: Adam Dunkels <adam@sics.se>
+ *
+ */
+#include "tcpecho.h"
+
+#include "lwip/opt.h"
+
+#if LWIP_NETCONN
+
+#include "lwip/sys.h"
+#include "lwip/api.h"
+/*-----------------------------------------------------------------------------------*/
+static void 
+tcpecho_thread(void *arg)
+{
+  struct netconn *conn, *newconn;
+  err_t err;
+  LWIP_UNUSED_ARG(arg);
+
+  /* Create a new connection identifier. */
+  /* Bind connection to well known port number 7. */
+#if LWIP_IPV6
+  conn = netconn_new(NETCONN_TCP_IPV6);
+  netconn_bind(conn, IP6_ADDR_ANY, 7);
+#else /* LWIP_IPV6 */
+  conn = netconn_new(NETCONN_TCP);
+  netconn_bind(conn, IP_ADDR_ANY, 7);
+#endif /* LWIP_IPV6 */
+  LWIP_ERROR("tcpecho: invalid conn", (conn != NULL), return;);
+
+  /* Tell connection to go into listening mode. */
+  netconn_listen(conn);
+
+  while (1) {
+
+    /* Grab new connection. */
+    err = netconn_accept(conn, &newconn);
+    /*printf("accepted new connection %p\n", newconn);*/
+    /* Process the new connection. */
+    if (err == ERR_OK) {
+      struct netbuf *buf;
+      void *data;
+      u16_t len;
+      
+      while ((err = netconn_recv(newconn, &buf)) == ERR_OK) {
+        /*printf("Recved\n");*/
+        do {
+             netbuf_data(buf, &data, &len);
+             err = netconn_write(newconn, data, len, NETCONN_COPY);
+#if 0
+            if (err != ERR_OK) {
+              printf("tcpecho: netconn_write: error \"%s\"\n", lwip_strerr(err));
+            }
+#endif
+        } while (netbuf_next(buf) >= 0);
+        netbuf_delete(buf);
+      }
+      /*printf("Got EOF, looping\n");*/ 
+      /* Close connection and discard connection identifier. */
+      netconn_close(newconn);
+      netconn_delete(newconn);
+    }
+  }
+}
+/*-----------------------------------------------------------------------------------*/
+void
+tcpecho_init(void)
+{
+  sys_thread_new("tcpecho_thread", tcpecho_thread, NULL, DEFAULT_THREAD_STACKSIZE, DEFAULT_THREAD_PRIO);
+}
+/*-----------------------------------------------------------------------------------*/
+
+#endif /* LWIP_NETCONN */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/tcpecho/tcpecho.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/tcpecho/tcpecho.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/tcpecho/tcpecho.h	(revision 457)
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2001-2003 Swedish Institute of Computer Science.
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission. 
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ * 
+ * Author: Adam Dunkels <adam@sics.se>
+ *
+ */
+
+#ifndef LWIP_TCPECHO_H
+#define LWIP_TCPECHO_H
+
+void tcpecho_init(void);
+
+#endif /* LWIP_TCPECHO_H */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/tcpecho_raw/tcpecho_raw.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/tcpecho_raw/tcpecho_raw.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/tcpecho_raw/tcpecho_raw.c	(revision 457)
@@ -0,0 +1,303 @@
+/*
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission. 
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of and a contribution to the lwIP TCP/IP stack.
+ *
+ * Credits go to Adam Dunkels (and the current maintainers) of this software.
+ *
+ * Christiaan Simons rewrote this file to get a more stable echo example.
+ */
+
+/**
+ * @file
+ * TCP echo server example using raw API.
+ *
+ * Echos all bytes sent by connecting client,
+ * and passively closes when client is done.
+ *
+ */
+
+#include "lwip/opt.h"
+#include "lwip/debug.h"
+#include "lwip/stats.h"
+#include "lwip/tcp.h"
+#include "tcpecho_raw.h"
+
+#if LWIP_TCP && LWIP_CALLBACK_API
+
+static struct tcp_pcb *tcpecho_raw_pcb;
+
+enum tcpecho_raw_states
+{
+  ES_NONE = 0,
+  ES_ACCEPTED,
+  ES_RECEIVED,
+  ES_CLOSING
+};
+
+struct tcpecho_raw_state
+{
+  u8_t state;
+  u8_t retries;
+  struct tcp_pcb *pcb;
+  /* pbuf (chain) to recycle */
+  struct pbuf *p;
+};
+
+static void
+tcpecho_raw_free(struct tcpecho_raw_state *es)
+{
+  if (es != NULL) {
+    if (es->p) {
+      /* free the buffer chain if present */
+      pbuf_free(es->p);
+    }
+
+    mem_free(es);
+  }  
+}
+
+static void
+tcpecho_raw_close(struct tcp_pcb *tpcb, struct tcpecho_raw_state *es)
+{
+  tcp_arg(tpcb, NULL);
+  tcp_sent(tpcb, NULL);
+  tcp_recv(tpcb, NULL);
+  tcp_err(tpcb, NULL);
+  tcp_poll(tpcb, NULL, 0);
+
+  tcpecho_raw_free(es);
+
+  tcp_close(tpcb);
+}
+
+static void
+tcpecho_raw_send(struct tcp_pcb *tpcb, struct tcpecho_raw_state *es)
+{
+  struct pbuf *ptr;
+  err_t wr_err = ERR_OK;
+ 
+  while ((wr_err == ERR_OK) &&
+         (es->p != NULL) && 
+         (es->p->len <= tcp_sndbuf(tpcb))) {
+    ptr = es->p;
+
+    /* enqueue data for transmission */
+    wr_err = tcp_write(tpcb, ptr->payload, ptr->len, 1);
+    if (wr_err == ERR_OK) {
+      u16_t plen;
+
+      plen = ptr->len;
+      /* continue with next pbuf in chain (if any) */
+      es->p = ptr->next;
+      if(es->p != NULL) {
+        /* new reference! */
+        pbuf_ref(es->p);
+      }
+      /* chop first pbuf from chain */
+      pbuf_free(ptr);
+      /* we can read more data now */
+      tcp_recved(tpcb, plen);
+    } else if(wr_err == ERR_MEM) {
+      /* we are low on memory, try later / harder, defer to poll */
+      es->p = ptr;
+    } else {
+      /* other problem ?? */
+    }
+  }
+}
+
+static void
+tcpecho_raw_error(void *arg, err_t err)
+{
+  struct tcpecho_raw_state *es;
+
+  LWIP_UNUSED_ARG(err);
+
+  es = (struct tcpecho_raw_state *)arg;
+
+  tcpecho_raw_free(es);
+}
+
+static err_t
+tcpecho_raw_poll(void *arg, struct tcp_pcb *tpcb)
+{
+  err_t ret_err;
+  struct tcpecho_raw_state *es;
+
+  es = (struct tcpecho_raw_state *)arg;
+  if (es != NULL) {
+    if (es->p != NULL) {
+      /* there is a remaining pbuf (chain)  */
+      tcpecho_raw_send(tpcb, es);
+    } else {
+      /* no remaining pbuf (chain)  */
+      if(es->state == ES_CLOSING) {
+        tcpecho_raw_close(tpcb, es);
+      }
+    }
+    ret_err = ERR_OK;
+  } else {
+    /* nothing to be done */
+    tcp_abort(tpcb);
+    ret_err = ERR_ABRT;
+  }
+  return ret_err;
+}
+
+static err_t
+tcpecho_raw_sent(void *arg, struct tcp_pcb *tpcb, u16_t len)
+{
+  struct tcpecho_raw_state *es;
+
+  LWIP_UNUSED_ARG(len);
+
+  es = (struct tcpecho_raw_state *)arg;
+  es->retries = 0;
+  
+  if(es->p != NULL) {
+    /* still got pbufs to send */
+    tcp_sent(tpcb, tcpecho_raw_sent);
+    tcpecho_raw_send(tpcb, es);
+  } else {
+    /* no more pbufs to send */
+    if(es->state == ES_CLOSING) {
+      tcpecho_raw_close(tpcb, es);
+    }
+  }
+  return ERR_OK;
+}
+
+static err_t
+tcpecho_raw_recv(void *arg, struct tcp_pcb *tpcb, struct pbuf *p, err_t err)
+{
+  struct tcpecho_raw_state *es;
+  err_t ret_err;
+
+  LWIP_ASSERT("arg != NULL",arg != NULL);
+  es = (struct tcpecho_raw_state *)arg;
+  if (p == NULL) {
+    /* remote host closed connection */
+    es->state = ES_CLOSING;
+    if(es->p == NULL) {
+      /* we're done sending, close it */
+      tcpecho_raw_close(tpcb, es);
+    } else {
+      /* we're not done yet */
+      tcpecho_raw_send(tpcb, es);
+    }
+    ret_err = ERR_OK;
+  } else if(err != ERR_OK) {
+    /* cleanup, for unknown reason */
+    if (p != NULL) {
+      pbuf_free(p);
+    }
+    ret_err = err;
+  }
+  else if(es->state == ES_ACCEPTED) {
+    /* first data chunk in p->payload */
+    es->state = ES_RECEIVED;
+    /* store reference to incoming pbuf (chain) */
+    es->p = p;
+    tcpecho_raw_send(tpcb, es);
+    ret_err = ERR_OK;
+  } else if (es->state == ES_RECEIVED) {
+    /* read some more data */
+    if(es->p == NULL) {
+      es->p = p;
+      tcpecho_raw_send(tpcb, es);
+    } else {
+      struct pbuf *ptr;
+
+      /* chain pbufs to the end of what we recv'ed previously  */
+      ptr = es->p;
+      pbuf_cat(ptr,p);
+    }
+    ret_err = ERR_OK;
+  } else {
+    /* unkown es->state, trash data  */
+    tcp_recved(tpcb, p->tot_len);
+    pbuf_free(p);
+    ret_err = ERR_OK;
+  }
+  return ret_err;
+}
+
+static err_t
+tcpecho_raw_accept(void *arg, struct tcp_pcb *newpcb, err_t err)
+{
+  err_t ret_err;
+  struct tcpecho_raw_state *es;
+
+  LWIP_UNUSED_ARG(arg);
+  if ((err != ERR_OK) || (newpcb == NULL)) {
+    return ERR_VAL;
+  }
+
+  /* Unless this pcb should have NORMAL priority, set its priority now.
+     When running out of pcbs, low priority pcbs can be aborted to create
+     new pcbs of higher priority. */
+  tcp_setprio(newpcb, TCP_PRIO_MIN);
+
+  es = (struct tcpecho_raw_state *)mem_malloc(sizeof(struct tcpecho_raw_state));
+  if (es != NULL) {
+    es->state = ES_ACCEPTED;
+    es->pcb = newpcb;
+    es->retries = 0;
+    es->p = NULL;
+    /* pass newly allocated es to our callbacks */
+    tcp_arg(newpcb, es);
+    tcp_recv(newpcb, tcpecho_raw_recv);
+    tcp_err(newpcb, tcpecho_raw_error);
+    tcp_poll(newpcb, tcpecho_raw_poll, 0);
+    tcp_sent(newpcb, tcpecho_raw_sent);
+    ret_err = ERR_OK;
+  } else {
+    ret_err = ERR_MEM;
+  }
+  return ret_err;
+}
+
+void
+tcpecho_raw_init(void)
+{
+  tcpecho_raw_pcb = tcp_new_ip_type(IPADDR_TYPE_ANY);
+  if (tcpecho_raw_pcb != NULL) {
+    err_t err;
+
+    err = tcp_bind(tcpecho_raw_pcb, IP_ANY_TYPE, 7);
+    if (err == ERR_OK) {
+      tcpecho_raw_pcb = tcp_listen(tcpecho_raw_pcb);
+      tcp_accept(tcpecho_raw_pcb, tcpecho_raw_accept);
+    } else {
+      /* abort? output diagnostic? */
+    }
+  } else {
+    /* abort? output diagnostic? */
+  }
+}
+
+#endif /* LWIP_TCP && LWIP_CALLBACK_API */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/tcpecho_raw/tcpecho_raw.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/tcpecho_raw/tcpecho_raw.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/tcpecho_raw/tcpecho_raw.h	(revision 457)
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission. 
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ * 
+ */
+#ifndef LWIP_TCPECHO_RAW_H
+#define LWIP_TCPECHO_RAW_H
+
+void tcpecho_raw_init(void);
+
+#endif /* LWIP_TCPECHO_RAW_H */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/udpecho/udpecho.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/udpecho/udpecho.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/udpecho/udpecho.c	(revision 457)
@@ -0,0 +1,87 @@
+/*
+ * Copyright (c) 2001-2003 Swedish Institute of Computer Science.
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission. 
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ * 
+ * Author: Adam Dunkels <adam@sics.se>
+ *
+ */
+
+#include "udpecho.h"
+
+#include "lwip/opt.h"
+
+#if LWIP_NETCONN
+
+#include "lwip/api.h"
+#include "lwip/sys.h"
+
+/*-----------------------------------------------------------------------------------*/
+static void
+udpecho_thread(void *arg)
+{
+  struct netconn *conn;
+  struct netbuf *buf;
+  static char buffer[4096];
+  err_t err;
+  LWIP_UNUSED_ARG(arg);
+
+#if LWIP_IPV6
+  conn = netconn_new(NETCONN_UDP_IPV6);
+  netconn_bind(conn, IP6_ADDR_ANY, 7);
+#else /* LWIP_IPV6 */
+  conn = netconn_new(NETCONN_UDP);
+  netconn_bind(conn, IP_ADDR_ANY, 7);
+#endif /* LWIP_IPV6 */
+  LWIP_ERROR("udpecho: invalid conn", (conn != NULL), return;);
+
+  while (1) {
+    err = netconn_recv(conn, &buf);
+    if (err == ERR_OK) {
+      /*  no need netconn_connect here, since the netbuf contains the address */
+      if(netbuf_copy(buf, buffer, sizeof(buffer)) != buf->p->tot_len) {
+        LWIP_DEBUGF(LWIP_DBG_ON, ("netbuf_copy failed\n"));
+      } else {
+        buffer[buf->p->tot_len] = '\0';
+        err = netconn_send(conn, buf);
+        if(err != ERR_OK) {
+          LWIP_DEBUGF(LWIP_DBG_ON, ("netconn_send failed: %d\n", (int)err));
+        } else {
+          LWIP_DEBUGF(LWIP_DBG_ON, ("got %s\n", buffer));
+        }
+      }
+      netbuf_delete(buf);
+    }
+  }
+}
+/*-----------------------------------------------------------------------------------*/
+void
+udpecho_init(void)
+{
+  sys_thread_new("udpecho_thread", udpecho_thread, NULL, DEFAULT_THREAD_STACKSIZE, DEFAULT_THREAD_PRIO);
+}
+
+#endif /* LWIP_NETCONN */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/udpecho/udpecho.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/udpecho/udpecho.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/udpecho/udpecho.h	(revision 457)
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2001-2003 Swedish Institute of Computer Science.
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission. 
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ * 
+ * Author: Adam Dunkels <adam@sics.se>
+ *
+ */
+#ifndef LWIP_UDPECHO_H
+#define LWIP_UDPECHO_H
+
+void udpecho_init(void);
+
+#endif /* LWIP_UDPECHO_H */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/udpecho_raw/udpecho_raw.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/udpecho_raw/udpecho_raw.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/udpecho_raw/udpecho_raw.c	(revision 457)
@@ -0,0 +1,88 @@
+/*
+ * Copyright (c) 2016 Stephan Linz <linz@li-pro.net>, Li-Pro.Net
+ * All rights reserved.
+ *
+ * Based on examples provided by
+ * Iwan Budi Kusnanto <ibk@labhijau.net> (https://gist.github.com/iwanbk/1399729)
+ * Juri Haberland <juri@sapienti-sat.org> (https://lists.gnu.org/archive/html/lwip-users/2007-06/msg00078.html)
+ *
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of and a contribution to the lwIP TCP/IP stack.
+ *
+ * Credits go to Adam Dunkels (and the current maintainers) of this software.
+ *
+ * Stephan Linz rewrote this file to get a basic echo example.
+ */
+
+/**
+ * @file
+ * UDP echo server example using raw API.
+ *
+ * Echos all bytes sent by connecting client,
+ * and passively closes when client is done.
+ *
+ */
+
+#include "lwip/opt.h"
+#include "lwip/debug.h"
+#include "lwip/stats.h"
+#include "lwip/udp.h"
+#include "udpecho_raw.h"
+
+#if LWIP_UDP
+
+static struct udp_pcb *udpecho_raw_pcb;
+
+static void
+udpecho_raw_recv(void *arg, struct udp_pcb *upcb, struct pbuf *p,
+                 const ip_addr_t *addr, u16_t port)
+{
+  LWIP_UNUSED_ARG(arg);
+  if (p != NULL) {
+    /* send received packet back to sender */
+    udp_sendto(upcb, p, addr, port);
+    /* free the pbuf */
+    pbuf_free(p);
+  }
+}
+
+void
+udpecho_raw_init(void)
+{
+  udpecho_raw_pcb = udp_new_ip_type(IPADDR_TYPE_ANY);
+  if (udpecho_raw_pcb != NULL) {
+    err_t err;
+
+    err = udp_bind(udpecho_raw_pcb, IP_ANY_TYPE, 7);
+    if (err == ERR_OK) {
+      udp_recv(udpecho_raw_pcb, udpecho_raw_recv, NULL);
+    } else {
+      /* abort? output diagnostic? */
+    }
+  } else {
+    /* abort? output diagnostic? */
+  }
+}
+
+#endif /* LWIP_UDP */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/udpecho_raw/udpecho_raw.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/udpecho_raw/udpecho_raw.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/udpecho_raw/udpecho_raw.h	(revision 457)
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2016 Stephan Linz <linz@li-pro.net>, Li-Pro.Net
+ * All rights reserved.
+ *
+ * Based on examples provided by
+ * Iwan Budi Kusnanto <ibk@labhijau.net> (https://gist.github.com/iwanbk/1399729)
+ * Juri Haberland <juri@sapienti-sat.org> (https://lists.gnu.org/archive/html/lwip-users/2007-06/msg00078.html)
+ *
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ */
+#ifndef LWIP_UDPECHO_RAW_H
+#define LWIP_UDPECHO_RAW_H
+
+void udpecho_raw_init(void);
+
+#endif /* LWIP_UDPECHO_RAW_H */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/examples/ethernetif/ethernetif.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/examples/ethernetif/ethernetif.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/examples/ethernetif/ethernetif.c	(revision 457)
@@ -0,0 +1,337 @@
+/**
+ * @file
+ * Ethernet Interface Skeleton
+ *
+ */
+
+/*
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Adam Dunkels <adam@sics.se>
+ *
+ */
+
+/*
+ * This file is a skeleton for developing Ethernet network interface
+ * drivers for lwIP. Add code to the low_level functions and do a
+ * search-and-replace for the word "ethernetif" to replace it with
+ * something that better describes your network interface.
+ */
+
+#include "lwip/opt.h"
+
+#if 0 /* don't build, this is only a skeleton, see previous comment */
+
+#include "lwip/def.h"
+#include "lwip/mem.h"
+#include "lwip/pbuf.h"
+#include "lwip/stats.h"
+#include "lwip/snmp.h"
+#include "lwip/ethip6.h"
+#include "lwip/etharp.h"
+#include "netif/ppp/pppoe.h"
+
+/* Define those to better describe your network interface. */
+#define IFNAME0 'e'
+#define IFNAME1 'n'
+
+/**
+ * Helper struct to hold private data used to operate your ethernet interface.
+ * Keeping the ethernet address of the MAC in this struct is not necessary
+ * as it is already kept in the struct netif.
+ * But this is only an example, anyway...
+ */
+struct ethernetif {
+  struct eth_addr *ethaddr;
+  /* Add whatever per-interface state that is needed here. */
+};
+
+/* Forward declarations. */
+static void  ethernetif_input(struct netif *netif);
+
+/**
+ * In this function, the hardware should be initialized.
+ * Called from ethernetif_init().
+ *
+ * @param netif the already initialized lwip network interface structure
+ *        for this ethernetif
+ */
+static void
+low_level_init(struct netif *netif)
+{
+  struct ethernetif *ethernetif = netif->state;
+
+  /* set MAC hardware address length */
+  netif->hwaddr_len = ETHARP_HWADDR_LEN;
+
+  /* set MAC hardware address */
+  netif->hwaddr[0] = ;
+  ...
+  netif->hwaddr[5] = ;
+
+  /* maximum transfer unit */
+  netif->mtu = 1500;
+
+  /* device capabilities */
+  /* don't set NETIF_FLAG_ETHARP if this device is not an ethernet one */
+  netif->flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP | NETIF_FLAG_LINK_UP;
+
+#if LWIP_IPV6 && LWIP_IPV6_MLD
+  /*
+   * For hardware/netifs that implement MAC filtering.
+   * All-nodes link-local is handled by default, so we must let the hardware know
+   * to allow multicast packets in.
+   * Should set mld_mac_filter previously. */
+  if (netif->mld_mac_filter != NULL) {
+    ip6_addr_t ip6_allnodes_ll;
+    ip6_addr_set_allnodes_linklocal(&ip6_allnodes_ll);
+    netif->mld_mac_filter(netif, &ip6_allnodes_ll, NETIF_ADD_MAC_FILTER);
+  }
+#endif /* LWIP_IPV6 && LWIP_IPV6_MLD */
+
+  /* Do whatever else is needed to initialize interface. */
+}
+
+/**
+ * This function should do the actual transmission of the packet. The packet is
+ * contained in the pbuf that is passed to the function. This pbuf
+ * might be chained.
+ *
+ * @param netif the lwip network interface structure for this ethernetif
+ * @param p the MAC packet to send (e.g. IP packet including MAC addresses and type)
+ * @return ERR_OK if the packet could be sent
+ *         an err_t value if the packet couldn't be sent
+ *
+ * @note Returning ERR_MEM here if a DMA queue of your MAC is full can lead to
+ *       strange results. You might consider waiting for space in the DMA queue
+ *       to become available since the stack doesn't retry to send a packet
+ *       dropped because of memory failure (except for the TCP timers).
+ */
+
+static err_t
+low_level_output(struct netif *netif, struct pbuf *p)
+{
+  struct ethernetif *ethernetif = netif->state;
+  struct pbuf *q;
+
+  initiate transfer();
+
+#if ETH_PAD_SIZE
+  pbuf_remove_header(p, ETH_PAD_SIZE); /* drop the padding word */
+#endif
+
+  for (q = p; q != NULL; q = q->next) {
+    /* Send the data from the pbuf to the interface, one pbuf at a
+       time. The size of the data in each pbuf is kept in the ->len
+       variable. */
+    send data from(q->payload, q->len);
+  }
+
+  signal that packet should be sent();
+
+  MIB2_STATS_NETIF_ADD(netif, ifoutoctets, p->tot_len);
+  if (((u8_t *)p->payload)[0] & 1) {
+    /* broadcast or multicast packet*/
+    MIB2_STATS_NETIF_INC(netif, ifoutnucastpkts);
+  } else {
+    /* unicast packet */
+    MIB2_STATS_NETIF_INC(netif, ifoutucastpkts);
+  }
+  /* increase ifoutdiscards or ifouterrors on error */
+
+#if ETH_PAD_SIZE
+  pbuf_add_header(p, ETH_PAD_SIZE); /* reclaim the padding word */
+#endif
+
+  LINK_STATS_INC(link.xmit);
+
+  return ERR_OK;
+}
+
+/**
+ * Should allocate a pbuf and transfer the bytes of the incoming
+ * packet from the interface into the pbuf.
+ *
+ * @param netif the lwip network interface structure for this ethernetif
+ * @return a pbuf filled with the received packet (including MAC header)
+ *         NULL on memory error
+ */
+static struct pbuf *
+low_level_input(struct netif *netif)
+{
+  struct ethernetif *ethernetif = netif->state;
+  struct pbuf *p, *q;
+  u16_t len;
+
+  /* Obtain the size of the packet and put it into the "len"
+     variable. */
+  len = ;
+
+#if ETH_PAD_SIZE
+  len += ETH_PAD_SIZE; /* allow room for Ethernet padding */
+#endif
+
+  /* We allocate a pbuf chain of pbufs from the pool. */
+  p = pbuf_alloc(PBUF_RAW, len, PBUF_POOL);
+
+  if (p != NULL) {
+
+#if ETH_PAD_SIZE
+    pbuf_remove_header(p, ETH_PAD_SIZE); /* drop the padding word */
+#endif
+
+    /* We iterate over the pbuf chain until we have read the entire
+     * packet into the pbuf. */
+    for (q = p; q != NULL; q = q->next) {
+      /* Read enough bytes to fill this pbuf in the chain. The
+       * available data in the pbuf is given by the q->len
+       * variable.
+       * This does not necessarily have to be a memcpy, you can also preallocate
+       * pbufs for a DMA-enabled MAC and after receiving truncate it to the
+       * actually received size. In this case, ensure the tot_len member of the
+       * pbuf is the sum of the chained pbuf len members.
+       */
+      read data into(q->payload, q->len);
+    }
+    acknowledge that packet has been read();
+
+    MIB2_STATS_NETIF_ADD(netif, ifinoctets, p->tot_len);
+    if (((u8_t *)p->payload)[0] & 1) {
+      /* broadcast or multicast packet*/
+      MIB2_STATS_NETIF_INC(netif, ifinnucastpkts);
+    } else {
+      /* unicast packet*/
+      MIB2_STATS_NETIF_INC(netif, ifinucastpkts);
+    }
+#if ETH_PAD_SIZE
+    pbuf_add_header(p, ETH_PAD_SIZE); /* reclaim the padding word */
+#endif
+
+    LINK_STATS_INC(link.recv);
+  } else {
+    drop packet();
+    LINK_STATS_INC(link.memerr);
+    LINK_STATS_INC(link.drop);
+    MIB2_STATS_NETIF_INC(netif, ifindiscards);
+  }
+
+  return p;
+}
+
+/**
+ * This function should be called when a packet is ready to be read
+ * from the interface. It uses the function low_level_input() that
+ * should handle the actual reception of bytes from the network
+ * interface. Then the type of the received packet is determined and
+ * the appropriate input function is called.
+ *
+ * @param netif the lwip network interface structure for this ethernetif
+ */
+static void
+ethernetif_input(struct netif *netif)
+{
+  struct ethernetif *ethernetif;
+  struct eth_hdr *ethhdr;
+  struct pbuf *p;
+
+  ethernetif = netif->state;
+
+  /* move received packet into a new pbuf */
+  p = low_level_input(netif);
+  /* if no packet could be read, silently ignore this */
+  if (p != NULL) {
+    /* pass all packets to ethernet_input, which decides what packets it supports */
+    if (netif->input(p, netif) != ERR_OK) {
+      LWIP_DEBUGF(NETIF_DEBUG, ("ethernetif_input: IP input error\n"));
+      pbuf_free(p);
+      p = NULL;
+    }
+  }
+}
+
+/**
+ * Should be called at the beginning of the program to set up the
+ * network interface. It calls the function low_level_init() to do the
+ * actual setup of the hardware.
+ *
+ * This function should be passed as a parameter to netif_add().
+ *
+ * @param netif the lwip network interface structure for this ethernetif
+ * @return ERR_OK if the loopif is initialized
+ *         ERR_MEM if private data couldn't be allocated
+ *         any other err_t on error
+ */
+err_t
+ethernetif_init(struct netif *netif)
+{
+  struct ethernetif *ethernetif;
+
+  LWIP_ASSERT("netif != NULL", (netif != NULL));
+
+  ethernetif = mem_malloc(sizeof(struct ethernetif));
+  if (ethernetif == NULL) {
+    LWIP_DEBUGF(NETIF_DEBUG, ("ethernetif_init: out of memory\n"));
+    return ERR_MEM;
+  }
+
+#if LWIP_NETIF_HOSTNAME
+  /* Initialize interface hostname */
+  netif->hostname = "lwip";
+#endif /* LWIP_NETIF_HOSTNAME */
+
+  /*
+   * Initialize the snmp variables and counters inside the struct netif.
+   * The last argument should be replaced with your link speed, in units
+   * of bits per second.
+   */
+  MIB2_INIT_NETIF(netif, snmp_ifType_ethernet_csmacd, LINK_SPEED_OF_YOUR_NETIF_IN_BPS);
+
+  netif->state = ethernetif;
+  netif->name[0] = IFNAME0;
+  netif->name[1] = IFNAME1;
+  /* We directly use etharp_output() here to save a function call.
+   * You can instead declare your own function an call etharp_output()
+   * from it if you have to do some checks before sending (e.g. if link
+   * is available...) */
+#if LWIP_IPV4
+  netif->output = etharp_output;
+#endif /* LWIP_IPV4 */
+#if LWIP_IPV6
+  netif->output_ip6 = ethip6_output;
+#endif /* LWIP_IPV6 */
+  netif->linkoutput = low_level_output;
+
+  ethernetif->ethaddr = (struct eth_addr *) & (netif->hwaddr[0]);
+
+  /* initialize the hardware */
+  low_level_init(netif);
+
+  return ERR_OK;
+}
+
+#endif /* 0 */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/examples/example_app/default_netif.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/examples/example_app/default_netif.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/examples/example_app/default_netif.h	(revision 457)
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2001-2003 Swedish Institute of Computer Science.
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission. 
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ * 
+ * Author: Adam Dunkels <adam@sics.se>
+ *
+ */
+
+#ifndef LWIP_DEFAULT_NETIF_H
+#define LWIP_DEFAULT_NETIF_H
+
+#include "lwip/ip_addr.h"
+
+#if LWIP_IPV4
+void init_default_netif(const ip4_addr_t *ipaddr, const ip4_addr_t *netmask, const ip4_addr_t *gw);
+#else
+void init_default_netif(void);
+#endif
+
+void default_netif_poll(void);
+void default_netif_shutdown(void);
+
+#endif
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/examples/example_app/lwipcfg.h.example
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/examples/example_app/lwipcfg.h.example	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/examples/example_app/lwipcfg.h.example	(revision 457)
@@ -0,0 +1,76 @@
+/**
+ * Additional settings for the win32 port.
+ * Copy this to lwipcfg_msvc.h and make the config changes you need.
+ */
+
+/* configuration for this port */
+#define PPP_USERNAME  "Admin"
+#define PPP_PASSWORD  "pass"
+
+/** Define this to the index of the windows network adapter to use */
+#define PACKET_LIB_ADAPTER_NR         1
+/** Define this to the GUID of the windows network adapter to use
+ * or NOT define this if you want PACKET_LIB_ADAPTER_NR to be used */ 
+/*#define PACKET_LIB_ADAPTER_GUID       "00000000-0000-0000-0000-000000000000"*/
+/*#define PACKET_LIB_GET_ADAPTER_NETADDRESS(addr) IP4_ADDR((addr), 192,168,1,0)*/
+/*#define PACKET_LIB_QUIET*/
+
+/* If these 2 are not defined, the corresponding config setting is used */
+/* #define USE_DHCP    0 */
+/* #define USE_AUTOIP  0 */
+
+/* #define USE_PCAPIF 1 */
+#define LWIP_PORT_INIT_IPADDR(addr)   IP4_ADDR((addr), 192,168,1,200)
+#define LWIP_PORT_INIT_GW(addr)       IP4_ADDR((addr), 192,168,1,1)
+#define LWIP_PORT_INIT_NETMASK(addr)  IP4_ADDR((addr), 255,255,255,0)
+
+/* remember to change this MAC address to suit your needs!
+   the last octet will be increased by netif->num for each netif */
+#define LWIP_MAC_ADDR_BASE            {0x00,0x01,0x02,0x03,0x04,0x05}
+
+/* #define USE_SLIPIF 0 */
+/* #define SIO_USE_COMPORT 0 */
+#ifdef USE_SLIPIF
+#if USE_SLIPIF
+#define LWIP_PORT_INIT_SLIP1_IPADDR(addr)   IP4_ADDR((addr), 192, 168,   2, 2)
+#define LWIP_PORT_INIT_SLIP1_GW(addr)       IP4_ADDR((addr), 192, 168,   2, 1)
+#define LWIP_PORT_INIT_SLIP1_NETMASK(addr)  IP4_ADDR((addr), 255, 255, 255, 0)
+#if USE_SLIPIF > 1
+#define LWIP_PORT_INIT_SLIP2_IPADDR(addr)   IP4_ADDR((addr), 192, 168,   2, 1)
+#define LWIP_PORT_INIT_SLIP2_GW(addr)       IP4_ADDR((addr), 0,     0,   0, 0)
+#define LWIP_PORT_INIT_SLIP2_NETMASK(addr)  IP4_ADDR((addr), 255, 255, 255, 0)*/
+#endif /* USE_SLIPIF > 1 */
+#endif /* USE_SLIPIF */
+#endif /* USE_SLIPIF */
+
+/* configuration for applications */
+
+#define LWIP_CHARGEN_APP              0
+#define LWIP_DNS_APP                  0
+#define LWIP_HTTPD_APP                0
+/* Set this to 1 to use the netconn http server,
+ * otherwise the raw api server will be used. */
+/*#define LWIP_HTTPD_APP_NETCONN     */
+#define LWIP_NETBIOS_APP              0
+#define LWIP_NETIO_APP                0
+#define LWIP_MDNS_APP                 0
+#define LWIP_MQTT_APP                 0
+#define LWIP_PING_APP                 0
+#define LWIP_RTP_APP                  0
+#define LWIP_SHELL_APP                0
+#define LWIP_SNMP_APP                 0
+#define LWIP_SNTP_APP                 0
+#define LWIP_SOCKET_EXAMPLES_APP      0
+#define LWIP_TCPECHO_APP              0
+/* Set this to 1 to use the netconn tcpecho server,
+ * otherwise the raw api server will be used. */
+/*#define LWIP_TCPECHO_APP_NETCONN   */
+#define LWIP_TFTP_APP                 0
+#define LWIP_UDPECHO_APP              0
+#define LWIP_LWIPERF_APP              0
+
+/*#define USE_DHCP    1*/
+/*#define USE_AUTOIP  1*/
+
+/* define this to your custom application-init function */
+/* #define LWIP_APP_INIT my_app_init() */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/examples/example_app/lwipopts.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/examples/example_app/lwipopts.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/examples/example_app/lwipopts.h	(revision 457)
@@ -0,0 +1,329 @@
+/*
+ * Copyright (c) 2001-2003 Swedish Institute of Computer Science.
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission. 
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ * 
+ * Author: Adam Dunkels <adam@sics.se>
+ *
+ */
+#ifndef LWIP_LWIPOPTS_H
+#define LWIP_LWIPOPTS_H
+
+#ifdef LWIP_OPTTEST_FILE
+#include "lwipopts_test.h"
+#else /* LWIP_OPTTEST_FILE */
+
+#define LWIP_IPV4                  1
+#define LWIP_IPV6                  1
+
+#define NO_SYS                     0
+#define LWIP_SOCKET                (NO_SYS==0)
+#define LWIP_NETCONN               (NO_SYS==0)
+#define LWIP_NETIF_API             (NO_SYS==0)
+
+#define LWIP_IGMP                  LWIP_IPV4
+#define LWIP_ICMP                  LWIP_IPV4
+
+#define LWIP_SNMP                  LWIP_UDP
+#define MIB2_STATS                 LWIP_SNMP
+#ifdef LWIP_HAVE_MBEDTLS
+#define LWIP_SNMP_V3               (LWIP_SNMP)
+#endif
+
+#define LWIP_DNS                   LWIP_UDP
+#define LWIP_MDNS_RESPONDER        LWIP_UDP
+
+#define LWIP_NUM_NETIF_CLIENT_DATA (LWIP_MDNS_RESPONDER)
+
+#define LWIP_HAVE_LOOPIF           1
+#define LWIP_NETIF_LOOPBACK        1
+#define LWIP_LOOPBACK_MAX_PBUFS    10
+
+#define TCP_LISTEN_BACKLOG         1
+
+#define LWIP_COMPAT_SOCKETS        1
+#define LWIP_SO_RCVTIMEO           1
+#define LWIP_SO_RCVBUF             1
+
+#define LWIP_TCPIP_CORE_LOCKING    1
+
+#define LWIP_NETIF_LINK_CALLBACK        1
+#define LWIP_NETIF_STATUS_CALLBACK      1
+#define LWIP_NETIF_EXT_STATUS_CALLBACK  1
+
+#ifdef LWIP_DEBUG
+
+#define LWIP_DBG_MIN_LEVEL         0
+#define PPP_DEBUG                  LWIP_DBG_OFF
+#define MEM_DEBUG                  LWIP_DBG_OFF
+#define MEMP_DEBUG                 LWIP_DBG_OFF
+#define PBUF_DEBUG                 LWIP_DBG_OFF
+#define API_LIB_DEBUG              LWIP_DBG_OFF
+#define API_MSG_DEBUG              LWIP_DBG_OFF
+#define TCPIP_DEBUG                LWIP_DBG_OFF
+#define NETIF_DEBUG                LWIP_DBG_OFF
+#define SOCKETS_DEBUG              LWIP_DBG_OFF
+#define DNS_DEBUG                  LWIP_DBG_OFF
+#define AUTOIP_DEBUG               LWIP_DBG_OFF
+#define DHCP_DEBUG                 LWIP_DBG_OFF
+#define IP_DEBUG                   LWIP_DBG_OFF
+#define IP_REASS_DEBUG             LWIP_DBG_OFF
+#define ICMP_DEBUG                 LWIP_DBG_OFF
+#define IGMP_DEBUG                 LWIP_DBG_OFF
+#define UDP_DEBUG                  LWIP_DBG_OFF
+#define TCP_DEBUG                  LWIP_DBG_OFF
+#define TCP_INPUT_DEBUG            LWIP_DBG_OFF
+#define TCP_OUTPUT_DEBUG           LWIP_DBG_OFF
+#define TCP_RTO_DEBUG              LWIP_DBG_OFF
+#define TCP_CWND_DEBUG             LWIP_DBG_OFF
+#define TCP_WND_DEBUG              LWIP_DBG_OFF
+#define TCP_FR_DEBUG               LWIP_DBG_OFF
+#define TCP_QLEN_DEBUG             LWIP_DBG_OFF
+#define TCP_RST_DEBUG              LWIP_DBG_OFF
+#endif
+
+#define LWIP_DBG_TYPES_ON         (LWIP_DBG_ON|LWIP_DBG_TRACE|LWIP_DBG_STATE|LWIP_DBG_FRESH|LWIP_DBG_HALT)
+
+
+/* ---------- Memory options ---------- */
+/* MEM_ALIGNMENT: should be set to the alignment of the CPU for which
+   lwIP is compiled. 4 byte alignment -> define MEM_ALIGNMENT to 4, 2
+   byte alignment -> define MEM_ALIGNMENT to 2. */
+/* MSVC port: intel processors don't need 4-byte alignment,
+   but are faster that way! */
+#define MEM_ALIGNMENT           4U
+
+/* MEM_SIZE: the size of the heap memory. If the application will send
+a lot of data that needs to be copied, this should be set high. */
+#define MEM_SIZE               10240
+
+/* MEMP_NUM_PBUF: the number of memp struct pbufs. If the application
+   sends a lot of data out of ROM (or other static memory), this
+   should be set high. */
+#define MEMP_NUM_PBUF           16
+/* MEMP_NUM_RAW_PCB: the number of UDP protocol control blocks. One
+   per active RAW "connection". */
+#define MEMP_NUM_RAW_PCB        3
+/* MEMP_NUM_UDP_PCB: the number of UDP protocol control blocks. One
+   per active UDP "connection". */
+#define MEMP_NUM_UDP_PCB        4
+/* MEMP_NUM_TCP_PCB: the number of simulatenously active TCP
+   connections. */
+#define MEMP_NUM_TCP_PCB        5
+/* MEMP_NUM_TCP_PCB_LISTEN: the number of listening TCP
+   connections. */
+#define MEMP_NUM_TCP_PCB_LISTEN 8
+/* MEMP_NUM_TCP_SEG: the number of simultaneously queued TCP
+   segments. */
+#define MEMP_NUM_TCP_SEG        16
+/* MEMP_NUM_SYS_TIMEOUT: the number of simulateously active
+   timeouts. */
+#define MEMP_NUM_SYS_TIMEOUT    17
+
+/* The following four are used only with the sequential API and can be
+   set to 0 if the application only will use the raw API. */
+/* MEMP_NUM_NETBUF: the number of struct netbufs. */
+#define MEMP_NUM_NETBUF         2
+/* MEMP_NUM_NETCONN: the number of struct netconns. */
+#define MEMP_NUM_NETCONN        10
+/* MEMP_NUM_TCPIP_MSG_*: the number of struct tcpip_msg, which is used
+   for sequential API communication and incoming packets. Used in
+   src/api/tcpip.c. */
+#define MEMP_NUM_TCPIP_MSG_API   16
+#define MEMP_NUM_TCPIP_MSG_INPKT 16
+
+
+/* ---------- Pbuf options ---------- */
+/* PBUF_POOL_SIZE: the number of buffers in the pbuf pool. */
+#define PBUF_POOL_SIZE          120
+
+/* PBUF_POOL_BUFSIZE: the size of each pbuf in the pbuf pool. */
+#define PBUF_POOL_BUFSIZE       256
+
+/** SYS_LIGHTWEIGHT_PROT
+ * define SYS_LIGHTWEIGHT_PROT in lwipopts.h if you want inter-task protection
+ * for certain critical regions during buffer allocation, deallocation and memory
+ * allocation and deallocation.
+ */
+#define SYS_LIGHTWEIGHT_PROT    (NO_SYS==0)
+
+
+/* ---------- TCP options ---------- */
+#define LWIP_TCP                1
+#define TCP_TTL                 255
+
+#define LWIP_ALTCP              (LWIP_TCP)
+#ifdef LWIP_HAVE_MBEDTLS
+#define LWIP_ALTCP_TLS          (LWIP_TCP)
+#define LWIP_ALTCP_TLS_MBEDTLS  (LWIP_TCP)
+#endif
+
+
+/* Controls if TCP should queue segments that arrive out of
+   order. Define to 0 if your device is low on memory. */
+#define TCP_QUEUE_OOSEQ         1
+
+/* TCP Maximum segment size. */
+#define TCP_MSS                 1024
+
+/* TCP sender buffer space (bytes). */
+#define TCP_SND_BUF             2048
+
+/* TCP sender buffer space (pbufs). This must be at least = 2 *
+   TCP_SND_BUF/TCP_MSS for things to work. */
+#define TCP_SND_QUEUELEN       (4 * TCP_SND_BUF/TCP_MSS)
+
+/* TCP writable space (bytes). This must be less than or equal
+   to TCP_SND_BUF. It is the amount of space which must be
+   available in the tcp snd_buf for select to return writable */
+#define TCP_SNDLOWAT           (TCP_SND_BUF/2)
+
+/* TCP receive window. */
+#define TCP_WND                 (20 * 1024)
+
+/* Maximum number of retransmissions of data segments. */
+#define TCP_MAXRTX              12
+
+/* Maximum number of retransmissions of SYN segments. */
+#define TCP_SYNMAXRTX           4
+
+
+/* ---------- ARP options ---------- */
+#define LWIP_ARP                1
+#define ARP_TABLE_SIZE          10
+#define ARP_QUEUEING            1
+
+
+/* ---------- IP options ---------- */
+/* Define IP_FORWARD to 1 if you wish to have the ability to forward
+   IP packets across network interfaces. If you are going to run lwIP
+   on a device with only one network interface, define this to 0. */
+#define IP_FORWARD              1
+
+/* IP reassembly and segmentation.These are orthogonal even
+ * if they both deal with IP fragments */
+#define IP_REASSEMBLY           1
+#define IP_REASS_MAX_PBUFS      (10 * ((1500 + PBUF_POOL_BUFSIZE - 1) / PBUF_POOL_BUFSIZE))
+#define MEMP_NUM_REASSDATA      IP_REASS_MAX_PBUFS
+#define IP_FRAG                 1
+#define IPV6_FRAG_COPYHEADER    1
+
+/* ---------- ICMP options ---------- */
+#define ICMP_TTL                255
+
+
+/* ---------- DHCP options ---------- */
+/* Define LWIP_DHCP to 1 if you want DHCP configuration of
+   interfaces. */
+#define LWIP_DHCP               LWIP_UDP
+
+/* 1 if you want to do an ARP check on the offered address
+   (recommended). */
+#define DHCP_DOES_ARP_CHECK    (LWIP_DHCP)
+
+
+/* ---------- AUTOIP options ------- */
+#define LWIP_AUTOIP            (LWIP_DHCP)
+#define LWIP_DHCP_AUTOIP_COOP  (LWIP_DHCP && LWIP_AUTOIP)
+
+
+/* ---------- UDP options ---------- */
+#define LWIP_UDP                1
+#define LWIP_UDPLITE            LWIP_UDP
+#define UDP_TTL                 255
+
+
+/* ---------- RAW options ---------- */
+#define LWIP_RAW                1
+
+
+/* ---------- Statistics options ---------- */
+
+#define LWIP_STATS              1
+#define LWIP_STATS_DISPLAY      1
+
+#if LWIP_STATS
+#define LINK_STATS              1
+#define IP_STATS                1
+#define ICMP_STATS              1
+#define IGMP_STATS              1
+#define IPFRAG_STATS            1
+#define UDP_STATS               1
+#define TCP_STATS               1
+#define MEM_STATS               1
+#define MEMP_STATS              1
+#define PBUF_STATS              1
+#define SYS_STATS               1
+#endif /* LWIP_STATS */
+
+/* ---------- NETBIOS options ---------- */
+#define LWIP_NETBIOS_RESPOND_NAME_QUERY 1
+
+/* ---------- PPP options ---------- */
+
+#define PPP_SUPPORT             1      /* Set > 0 for PPP */
+
+#if PPP_SUPPORT
+
+#define NUM_PPP                 1      /* Max PPP sessions. */
+
+
+/* Select modules to enable.  Ideally these would be set in the makefile but
+ * we're limited by the command line length so you need to modify the settings
+ * in this file.
+ */
+#define PPPOE_SUPPORT           1
+#define PPPOS_SUPPORT           1
+
+#define PAP_SUPPORT             1      /* Set > 0 for PAP. */
+#define CHAP_SUPPORT            1      /* Set > 0 for CHAP. */
+#define MSCHAP_SUPPORT          0      /* Set > 0 for MSCHAP */
+#define CBCP_SUPPORT            0      /* Set > 0 for CBCP (NOT FUNCTIONAL!) */
+#define CCP_SUPPORT             0      /* Set > 0 for CCP */
+#define VJ_SUPPORT              1      /* Set > 0 for VJ header compression. */
+#define MD5_SUPPORT             1      /* Set > 0 for MD5 (see also CHAP) */
+
+#endif /* PPP_SUPPORT */
+
+#endif /* LWIP_OPTTEST_FILE */
+
+/* The following defines must be done even in OPTTEST mode: */
+
+#if !defined(NO_SYS) || !NO_SYS /* default is 0 */
+void sys_check_core_locking(void);
+#define LWIP_ASSERT_CORE_LOCKED()  sys_check_core_locking()
+void sys_mark_tcpip_thread(void);
+#define LWIP_MARK_TCPIP_THREAD()   sys_mark_tcpip_thread()
+
+#if !defined(LWIP_TCPIP_CORE_LOCKING) || LWIP_TCPIP_CORE_LOCKING /* default is 1 */
+void sys_lock_tcpip_core(void);
+#define LOCK_TCPIP_CORE()          sys_lock_tcpip_core()
+void sys_unlock_tcpip_core(void);
+#define UNLOCK_TCPIP_CORE()        sys_unlock_tcpip_core()
+#endif
+#endif
+
+#endif /* LWIP_LWIPOPTS_H */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/examples/example_app/lwippools.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/examples/example_app/lwippools.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/examples/example_app/lwippools.h	(revision 457)
@@ -0,0 +1,20 @@
+/* OPTIONAL: Pools to replace heap allocation
+ * Optional: Pools can be used instead of the heap for mem_malloc. If
+ * so, these should be defined here, in increasing order according to 
+ * the pool element size.
+ *
+ * LWIP_MALLOC_MEMPOOL(number_elements, element_size)
+ */
+#if MEM_USE_POOLS
+LWIP_MALLOC_MEMPOOL_START
+LWIP_MALLOC_MEMPOOL(100, 256)
+LWIP_MALLOC_MEMPOOL(50, 512)
+LWIP_MALLOC_MEMPOOL(20, 1024)
+LWIP_MALLOC_MEMPOOL(20, 1536)
+LWIP_MALLOC_MEMPOOL_END
+#endif /* MEM_USE_POOLS */
+
+/* Optional: Your custom pools can go here if you would like to use
+ * lwIP's memory pools for anything else.
+ */
+LWIP_MEMPOOL(SYS_MBOX, 22, 100, "SYS_MBOX")
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/examples/example_app/ppp_settings.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/examples/example_app/ppp_settings.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/examples/example_app/ppp_settings.h	(revision 457)
@@ -0,0 +1,6 @@
+#ifdef _MSC_VER
+#pragma warning (disable: 4242) /* PPP only: conversion from 'x' to 'y', possible loss of data */
+#pragma warning (disable: 4244) /* PPP only: conversion from 'x' to 'y', possible loss of data (again?) */
+#pragma warning (disable: 4310) /* PPP only: cast truncates constant value */
+#pragma warning (disable: 4706) /* PPP only: assignment within conditional expression */
+#endif /* MSC_VER  */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/examples/example_app/test.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/examples/example_app/test.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/examples/example_app/test.c	(revision 457)
@@ -0,0 +1,758 @@
+/*
+ * Copyright (c) 2001,2002 Florian Schulze.
+ * 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 authors nor the names of the contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHORS 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 AUTHORS 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.
+ *
+ * test.c - This file is part of lwIP test
+ *
+ */
+
+/* C runtime includes */
+#include <stdio.h>
+#include <stdarg.h>
+#include <time.h>
+#include <string.h>
+
+/* lwIP core includes */
+#include "lwip/opt.h"
+
+#include "lwip/sys.h"
+#include "lwip/timeouts.h"
+#include "lwip/debug.h"
+#include "lwip/stats.h"
+#include "lwip/init.h"
+#include "lwip/tcpip.h"
+#include "lwip/netif.h"
+#include "lwip/api.h"
+
+#include "lwip/tcp.h"
+#include "lwip/udp.h"
+#include "lwip/dns.h"
+#include "lwip/dhcp.h"
+#include "lwip/autoip.h"
+
+/* lwIP netif includes */
+#include "lwip/etharp.h"
+#include "netif/ethernet.h"
+
+/* applications includes */
+#include "lwip/apps/netbiosns.h"
+#include "lwip/apps/httpd.h"
+#include "apps/httpserver/httpserver-netconn.h"
+#include "apps/netio/netio.h"
+#include "apps/ping/ping.h"
+#include "apps/rtp/rtp.h"
+#include "apps/chargen/chargen.h"
+#include "apps/shell/shell.h"
+#include "apps/tcpecho/tcpecho.h"
+#include "apps/udpecho/udpecho.h"
+#include "apps/tcpecho_raw/tcpecho_raw.h"
+#include "apps/socket_examples/socket_examples.h"
+
+#include "examples/lwiperf/lwiperf_example.h"
+#include "examples/mdns/mdns_example.h"
+#include "examples/snmp/snmp_example.h"
+#include "examples/tftp/tftp_example.h"
+#include "examples/sntp/sntp_example.h"
+#include "examples/mqtt/mqtt_example.h"
+
+#include "examples/httpd/cgi_example/cgi_example.h"
+#include "examples/httpd/fs_example/fs_example.h"
+#include "examples/httpd/ssi_example/ssi_example.h"
+
+#include "default_netif.h"
+
+#if NO_SYS
+/* ... then we need information about the timer intervals: */
+#include "lwip/ip4_frag.h"
+#include "lwip/igmp.h"
+#endif /* NO_SYS */
+
+#include "netif/ppp/ppp_opts.h"
+#if PPP_SUPPORT
+/* PPP includes */
+#include "lwip/sio.h"
+#include "netif/ppp/pppapi.h"
+#include "netif/ppp/pppos.h"
+#include "netif/ppp/pppoe.h"
+#if !NO_SYS && !LWIP_PPP_API
+#error With NO_SYS==0, LWIP_PPP_API==1 is required.
+#endif
+#endif /* PPP_SUPPORT */
+
+/* include the port-dependent configuration */
+#include "lwipcfg.h"
+
+#ifndef LWIP_EXAMPLE_APP_ABORT
+#define LWIP_EXAMPLE_APP_ABORT() 0
+#endif
+
+/** Define this to 1 to enable a port-specific ethernet interface as default interface. */
+#ifndef USE_DEFAULT_ETH_NETIF
+#define USE_DEFAULT_ETH_NETIF 1
+#endif
+
+/** Define this to 1 to enable a PPP interface. */
+#ifndef USE_PPP
+#define USE_PPP 0
+#endif
+
+/** Define this to 1 or 2 to support 1 or 2 SLIP interfaces. */
+#ifndef USE_SLIPIF
+#define USE_SLIPIF 0
+#endif
+
+/** Use an ethernet adapter? Default to enabled if port-specific ethernet netif or PPPoE are used. */
+#ifndef USE_ETHERNET
+#define USE_ETHERNET  (USE_DEFAULT_ETH_NETIF || PPPOE_SUPPORT)
+#endif
+
+/** Use an ethernet adapter for TCP/IP? By default only if port-specific ethernet netif is used. */
+#ifndef USE_ETHERNET_TCPIP
+#define USE_ETHERNET_TCPIP  (USE_DEFAULT_ETH_NETIF)
+#endif
+
+#if USE_SLIPIF
+#include <netif/slipif.h>
+#endif /* USE_SLIPIF */
+
+#ifndef USE_DHCP
+#define USE_DHCP    LWIP_DHCP
+#endif
+#ifndef USE_AUTOIP
+#define USE_AUTOIP  LWIP_AUTOIP
+#endif
+
+/* globales variables for netifs */
+#if USE_ETHERNET
+#if LWIP_DHCP
+/* dhcp struct for the ethernet netif */
+struct dhcp netif_dhcp;
+#endif /* LWIP_DHCP */
+#if LWIP_AUTOIP
+/* autoip struct for the ethernet netif */
+struct autoip netif_autoip;
+#endif /* LWIP_AUTOIP */
+#endif /* USE_ETHERNET */
+#if USE_PPP
+/* THE PPP PCB */
+ppp_pcb *ppp;
+/* THE PPP interface */
+struct netif ppp_netif;
+/* THE PPP descriptor */
+u8_t sio_idx = 0;
+sio_fd_t ppp_sio;
+#endif /* USE_PPP */
+#if USE_SLIPIF
+struct netif slipif1;
+#if USE_SLIPIF > 1
+struct netif slipif2;
+#endif /* USE_SLIPIF > 1 */
+#endif /* USE_SLIPIF */
+
+
+#if USE_PPP
+static void
+pppLinkStatusCallback(ppp_pcb *pcb, int errCode, void *ctx)
+{
+  struct netif *pppif = ppp_netif(pcb);
+  LWIP_UNUSED_ARG(ctx);
+
+  switch(errCode) {
+    case PPPERR_NONE: {             /* No error. */
+      printf("pppLinkStatusCallback: PPPERR_NONE\n");
+#if LWIP_IPV4
+      printf("   our_ipaddr  = %s\n", ip4addr_ntoa(netif_ip4_addr(pppif)));
+      printf("   his_ipaddr  = %s\n", ip4addr_ntoa(netif_ip4_gw(pppif)));
+      printf("   netmask     = %s\n", ip4addr_ntoa(netif_ip4_netmask(pppif)));
+#endif /* LWIP_IPV4 */
+#if LWIP_DNS
+      printf("   dns1        = %s\n", ipaddr_ntoa(dns_getserver(0)));
+      printf("   dns2        = %s\n", ipaddr_ntoa(dns_getserver(1)));
+#endif /* LWIP_DNS */
+#if PPP_IPV6_SUPPORT
+      printf("   our6_ipaddr = %s\n", ip6addr_ntoa(netif_ip6_addr(pppif, 0)));
+#endif /* PPP_IPV6_SUPPORT */
+      break;
+    }
+    case PPPERR_PARAM: {           /* Invalid parameter. */
+      printf("pppLinkStatusCallback: PPPERR_PARAM\n");
+      break;
+    }
+    case PPPERR_OPEN: {            /* Unable to open PPP session. */
+      printf("pppLinkStatusCallback: PPPERR_OPEN\n");
+      break;
+    }
+    case PPPERR_DEVICE: {          /* Invalid I/O device for PPP. */
+      printf("pppLinkStatusCallback: PPPERR_DEVICE\n");
+      break;
+    }
+    case PPPERR_ALLOC: {           /* Unable to allocate resources. */
+      printf("pppLinkStatusCallback: PPPERR_ALLOC\n");
+      break;
+    }
+    case PPPERR_USER: {            /* User interrupt. */
+      printf("pppLinkStatusCallback: PPPERR_USER\n");
+      break;
+    }
+    case PPPERR_CONNECT: {         /* Connection lost. */
+      printf("pppLinkStatusCallback: PPPERR_CONNECT\n");
+      break;
+    }
+    case PPPERR_AUTHFAIL: {        /* Failed authentication challenge. */
+      printf("pppLinkStatusCallback: PPPERR_AUTHFAIL\n");
+      break;
+    }
+    case PPPERR_PROTOCOL: {        /* Failed to meet protocol. */
+      printf("pppLinkStatusCallback: PPPERR_PROTOCOL\n");
+      break;
+    }
+    case PPPERR_PEERDEAD: {        /* Connection timeout */
+      printf("pppLinkStatusCallback: PPPERR_PEERDEAD\n");
+      break;
+    }
+    case PPPERR_IDLETIMEOUT: {     /* Idle Timeout */
+      printf("pppLinkStatusCallback: PPPERR_IDLETIMEOUT\n");
+      break;
+    }
+    case PPPERR_CONNECTTIME: {     /* Max connect time reached */
+      printf("pppLinkStatusCallback: PPPERR_CONNECTTIME\n");
+      break;
+    }
+    case PPPERR_LOOPBACK: {        /* Loopback detected */
+      printf("pppLinkStatusCallback: PPPERR_LOOPBACK\n");
+      break;
+    }
+    default: {
+      printf("pppLinkStatusCallback: unknown errCode %d\n", errCode);
+      break;
+    }
+  }
+}
+
+#if PPPOS_SUPPORT
+static u32_t
+ppp_output_cb(ppp_pcb *pcb, u8_t *data, u32_t len, void *ctx)
+{
+  LWIP_UNUSED_ARG(pcb);
+  LWIP_UNUSED_ARG(ctx);
+  return sio_write(ppp_sio, data, len);
+}
+#endif /* PPPOS_SUPPORT */
+#endif /* USE_PPP */
+
+#if LWIP_NETIF_STATUS_CALLBACK
+static void
+status_callback(struct netif *state_netif)
+{
+  if (netif_is_up(state_netif)) {
+#if LWIP_IPV4
+    printf("status_callback==UP, local interface IP is %s\n", ip4addr_ntoa(netif_ip4_addr(state_netif)));
+#else
+    printf("status_callback==UP\n");
+#endif
+  } else {
+    printf("status_callback==DOWN\n");
+  }
+}
+#endif /* LWIP_NETIF_STATUS_CALLBACK */
+
+#if LWIP_NETIF_LINK_CALLBACK
+static void
+link_callback(struct netif *state_netif)
+{
+  if (netif_is_link_up(state_netif)) {
+    printf("link_callback==UP\n");
+  } else {
+    printf("link_callback==DOWN\n");
+  }
+}
+#endif /* LWIP_NETIF_LINK_CALLBACK */
+
+/* This function initializes all network interfaces */
+static void
+test_netif_init(void)
+{
+#if LWIP_IPV4 && USE_ETHERNET
+  ip4_addr_t ipaddr, netmask, gw;
+#endif /* LWIP_IPV4 && USE_ETHERNET */
+#if USE_SLIPIF
+  u8_t num_slip1 = 0;
+#if LWIP_IPV4
+  ip4_addr_t ipaddr_slip1, netmask_slip1, gw_slip1;
+#endif
+#if USE_SLIPIF > 1
+  u8_t num_slip2 = 1;
+#if LWIP_IPV4
+  ip4_addr_t ipaddr_slip2, netmask_slip2, gw_slip2;
+#endif
+#endif /* USE_SLIPIF > 1 */
+#endif /* USE_SLIPIF */
+#if USE_DHCP || USE_AUTOIP
+  err_t err;
+#endif
+
+#if USE_PPP
+  const char *username = NULL, *password = NULL;
+#ifdef PPP_USERNAME
+  username = PPP_USERNAME;
+#endif
+#ifdef PPP_PASSWORD
+  password = PPP_PASSWORD;
+#endif
+  printf("ppp_connect: COM%d\n", (int)sio_idx);
+#if PPPOS_SUPPORT
+  ppp_sio = sio_open(sio_idx);
+  if (ppp_sio == NULL) {
+    printf("sio_open error\n");
+  } else {
+    ppp = pppos_create(&ppp_netif, ppp_output_cb, pppLinkStatusCallback, NULL);
+    if (ppp == NULL) {
+      printf("pppos_create error\n");
+    } else {
+      ppp_set_auth(ppp, PPPAUTHTYPE_ANY, username, password);
+      ppp_connect(ppp, 0);
+    }
+  }
+#endif /* PPPOS_SUPPORT */
+#endif  /* USE_PPP */
+
+#if USE_ETHERNET
+#if LWIP_IPV4
+  ip4_addr_set_zero(&gw);
+  ip4_addr_set_zero(&ipaddr);
+  ip4_addr_set_zero(&netmask);
+#if USE_ETHERNET_TCPIP
+#if USE_DHCP
+  printf("Starting lwIP, local interface IP is dhcp-enabled\n");
+#elif USE_AUTOIP
+  printf("Starting lwIP, local interface IP is autoip-enabled\n");
+#else /* USE_DHCP */
+  LWIP_PORT_INIT_GW(&gw);
+  LWIP_PORT_INIT_IPADDR(&ipaddr);
+  LWIP_PORT_INIT_NETMASK(&netmask);
+  printf("Starting lwIP, local interface IP is %s\n", ip4addr_ntoa(&ipaddr));
+#endif /* USE_DHCP */
+#endif /* USE_ETHERNET_TCPIP */
+#else /* LWIP_IPV4 */
+  printf("Starting lwIP, IPv4 disable\n");
+#endif /* LWIP_IPV4 */
+
+#if LWIP_IPV4
+  init_default_netif(&ipaddr, &netmask, &gw);
+#else
+  init_default_netif();
+#endif
+#if LWIP_IPV6
+  netif_create_ip6_linklocal_address(netif_default, 1);
+#if LWIP_IPV6_AUTOCONFIG 
+  netif_default->ip6_autoconfig_enabled = 1;
+#endif
+  printf("ip6 linklocal address: %s\n", ip6addr_ntoa(netif_ip6_addr(netif_default, 0)));
+#endif /* LWIP_IPV6 */
+#if LWIP_NETIF_STATUS_CALLBACK
+  netif_set_status_callback(netif_default, status_callback);
+#endif /* LWIP_NETIF_STATUS_CALLBACK */
+#if LWIP_NETIF_LINK_CALLBACK
+  netif_set_link_callback(netif_default, link_callback);
+#endif /* LWIP_NETIF_LINK_CALLBACK */
+
+#if USE_ETHERNET_TCPIP
+#if LWIP_AUTOIP
+  autoip_set_struct(netif_default, &netif_autoip);
+#endif /* LWIP_AUTOIP */
+#if LWIP_DHCP
+  dhcp_set_struct(netif_default, &netif_dhcp);
+#endif /* LWIP_DHCP */
+  netif_set_up(netif_default);
+#if USE_DHCP
+  err = dhcp_start(netif_default);
+  LWIP_ASSERT("dhcp_start failed", err == ERR_OK);
+#elif USE_AUTOIP
+  err = autoip_start(netif_default);
+  LWIP_ASSERT("autoip_start failed", err == ERR_OK);
+#endif /* USE_DHCP */
+#else /* USE_ETHERNET_TCPIP */
+  /* Use ethernet for PPPoE only */
+  netif.flags &= ~(NETIF_FLAG_ETHARP | NETIF_FLAG_IGMP); /* no ARP */
+  netif.flags |= NETIF_FLAG_ETHERNET; /* but pure ethernet */
+#endif /* USE_ETHERNET_TCPIP */
+
+#if USE_PPP && PPPOE_SUPPORT
+  /* start PPPoE after ethernet netif is added! */
+  ppp = pppoe_create(&ppp_netif, netif_default, NULL, NULL, pppLinkStatusCallback, NULL);
+  if (ppp == NULL) {
+    printf("pppoe_create error\n");
+  } else {
+    ppp_set_auth(ppp, PPPAUTHTYPE_ANY, username, password);
+    ppp_connect(ppp, 0);
+  }
+#endif /* USE_PPP && PPPOE_SUPPORT */
+
+#endif /* USE_ETHERNET */
+#if USE_SLIPIF
+#if LWIP_IPV4
+#define SLIP1_ADDRS &ipaddr_slip1, &netmask_slip1, &gw_slip1,
+  LWIP_PORT_INIT_SLIP1_IPADDR(&ipaddr_slip1);
+  LWIP_PORT_INIT_SLIP1_GW(&gw_slip1);
+  LWIP_PORT_INIT_SLIP1_NETMASK(&netmask_slip1);
+  printf("Starting lwIP slipif, local interface IP is %s\n", ip4addr_ntoa(&ipaddr_slip1));
+#else
+#define SLIP1_ADDRS
+  printf("Starting lwIP slipif\n");
+#endif
+#if defined(SIO_USE_COMPORT) && SIO_USE_COMPORT
+  num_slip1++; /* COM ports cannot be 0-based */
+#endif
+  netif_add(&slipif1, SLIP1_ADDRS &num_slip1, slipif_init, ip_input);
+#if !USE_ETHERNET
+  netif_set_default(&slipif1);
+#endif /* !USE_ETHERNET */
+#if LWIP_IPV6
+  netif_create_ip6_linklocal_address(&slipif1, 1);
+  printf("SLIP ip6 linklocal address: %s\n", ip6addr_ntoa(netif_ip6_addr(&slipif1, 0)));
+#endif /* LWIP_IPV6 */
+#if LWIP_NETIF_STATUS_CALLBACK
+  netif_set_status_callback(&slipif1, status_callback);
+#endif /* LWIP_NETIF_STATUS_CALLBACK */
+#if LWIP_NETIF_LINK_CALLBACK
+  netif_set_link_callback(&slipif1, link_callback);
+#endif /* LWIP_NETIF_LINK_CALLBACK */
+  netif_set_up(&slipif1);
+
+#if USE_SLIPIF > 1
+#if LWIP_IPV4
+#define SLIP2_ADDRS &ipaddr_slip2, &netmask_slip2, &gw_slip2,
+  LWIP_PORT_INIT_SLIP2_IPADDR(&ipaddr_slip2);
+  LWIP_PORT_INIT_SLIP2_GW(&gw_slip2);
+  LWIP_PORT_INIT_SLIP2_NETMASK(&netmask_slip2);
+  printf("Starting lwIP SLIP if #2, local interface IP is %s\n", ip4addr_ntoa(&ipaddr_slip2));
+#else
+#define SLIP2_ADDRS
+  printf("Starting lwIP SLIP if #2\n");
+#endif
+#if defined(SIO_USE_COMPORT) && SIO_USE_COMPORT
+  num_slip2++; /* COM ports cannot be 0-based */
+#endif
+  netif_add(&slipif2, SLIP2_ADDRS &num_slip2, slipif_init, ip_input);
+#if LWIP_IPV6
+  netif_create_ip6_linklocal_address(&slipif1, 1);
+  printf("SLIP2 ip6 linklocal address: ");
+  ip6_addr_debug_print(0xFFFFFFFF & ~LWIP_DBG_HALT, netif_ip6_addr(&slipif2, 0));
+  printf("\n");
+#endif /* LWIP_IPV6 */
+#if LWIP_NETIF_STATUS_CALLBACK
+  netif_set_status_callback(&slipif2, status_callback);
+#endif /* LWIP_NETIF_STATUS_CALLBACK */
+#if LWIP_NETIF_LINK_CALLBACK
+  netif_set_link_callback(&slipif2, link_callback);
+#endif /* LWIP_NETIF_LINK_CALLBACK */
+  netif_set_up(&slipif2);
+#endif /* USE_SLIPIF > 1*/
+#endif /* USE_SLIPIF */
+}
+
+#if LWIP_DNS_APP && LWIP_DNS
+static void
+dns_found(const char *name, const ip_addr_t *addr, void *arg)
+{
+  LWIP_UNUSED_ARG(arg);
+  printf("%s: %s\n", name, addr ? ipaddr_ntoa(addr) : "<not found>");
+}
+
+static void
+dns_dorequest(void *arg)
+{
+  const char* dnsname = "3com.com";
+  ip_addr_t dnsresp;
+  LWIP_UNUSED_ARG(arg);
+ 
+  if (dns_gethostbyname(dnsname, &dnsresp, dns_found, 0) == ERR_OK) {
+    dns_found(dnsname, &dnsresp, 0);
+  }
+}
+#endif /* LWIP_DNS_APP && LWIP_DNS */
+
+/* This function initializes applications */
+static void
+apps_init(void)
+{
+#if LWIP_DNS_APP && LWIP_DNS
+  /* wait until the netif is up (for dhcp, autoip or ppp) */
+  sys_timeout(5000, dns_dorequest, NULL);
+#endif /* LWIP_DNS_APP && LWIP_DNS */
+
+#if LWIP_CHARGEN_APP && LWIP_SOCKET
+  chargen_init();
+#endif /* LWIP_CHARGEN_APP && LWIP_SOCKET */
+
+#if LWIP_PING_APP && LWIP_RAW && LWIP_ICMP
+  ping_init(&netif_default->gw);
+#endif /* LWIP_PING_APP && LWIP_RAW && LWIP_ICMP */
+
+#if LWIP_NETBIOS_APP && LWIP_UDP
+  netbiosns_init();
+#ifndef NETBIOS_LWIP_NAME
+#if LWIP_NETIF_HOSTNAME
+  netbiosns_set_name(netif_default->hostname);
+#else
+  netbiosns_set_name("NETBIOSLWIPDEV");
+#endif
+#endif
+#endif /* LWIP_NETBIOS_APP && LWIP_UDP */
+
+#if LWIP_HTTPD_APP && LWIP_TCP
+#ifdef LWIP_HTTPD_APP_NETCONN
+  http_server_netconn_init();
+#else /* LWIP_HTTPD_APP_NETCONN */
+#if defined(LWIP_HTTPD_EXAMPLE_CUSTOMFILES) && LWIP_HTTPD_EXAMPLE_CUSTOMFILES && defined(LWIP_HTTPD_EXAMPLE_CUSTOMFILES_ROOTDIR)
+  fs_ex_init(LWIP_HTTPD_EXAMPLE_CUSTOMFILES_ROOTDIR);
+#endif
+  httpd_init();
+#if defined(LWIP_HTTPD_EXAMPLE_SSI_SIMPLE) && LWIP_HTTPD_EXAMPLE_SSI_SIMPLE
+  ssi_ex_init();
+#endif
+#if defined(LWIP_HTTPD_EXAMPLE_CGI_SIMPLE) && LWIP_HTTPD_EXAMPLE_CGI_SIMPLE
+  cgi_ex_init();
+#endif
+#endif /* LWIP_HTTPD_APP_NETCONN */
+#endif /* LWIP_HTTPD_APP && LWIP_TCP */
+
+#if LWIP_NETIO_APP && LWIP_TCP
+  netio_init();
+#endif /* LWIP_NETIO_APP && LWIP_TCP */
+
+#if LWIP_RTP_APP && LWIP_SOCKET && LWIP_IGMP
+  rtp_init();
+#endif /* LWIP_RTP_APP && LWIP_SOCKET && LWIP_IGMP */
+
+#if LWIP_SHELL_APP && LWIP_NETCONN
+  shell_init();
+#endif /* LWIP_SHELL_APP && LWIP_NETCONN */
+#if LWIP_TCPECHO_APP
+#if LWIP_NETCONN && defined(LWIP_TCPECHO_APP_NETCONN)
+  tcpecho_init();
+#else /* LWIP_NETCONN && defined(LWIP_TCPECHO_APP_NETCONN) */
+  tcpecho_raw_init();
+#endif
+#endif /* LWIP_TCPECHO_APP && LWIP_NETCONN */
+#if LWIP_UDPECHO_APP && LWIP_NETCONN
+  udpecho_init();
+#endif /* LWIP_UDPECHO_APP && LWIP_NETCONN */
+#if LWIP_SOCKET_EXAMPLES_APP && LWIP_SOCKET
+  socket_examples_init();
+#endif /* LWIP_SOCKET_EXAMPLES_APP && LWIP_SOCKET */
+#if LWIP_MDNS_APP
+  mdns_example_init();
+#endif
+#if LWIP_SNMP_APP
+  snmp_example_init();
+#endif
+#if LWIP_SNTP_APP
+  sntp_example_init();
+#endif
+#if LWIP_TFTP_APP
+  tftp_example_init();
+#endif
+#if LWIP_LWIPERF_APP
+  lwiperf_example_init();
+#endif
+#if LWIP_MQTT_APP
+  mqtt_example_init();
+#endif
+
+#ifdef LWIP_APP_INIT
+  LWIP_APP_INIT();
+#endif
+}
+
+/* This function initializes this lwIP test. When NO_SYS=1, this is done in
+ * the main_loop context (there is no other one), when NO_SYS=0, this is done
+ * in the tcpip_thread context */
+static void
+test_init(void * arg)
+{ /* remove compiler warning */
+#if NO_SYS
+  LWIP_UNUSED_ARG(arg);
+#else /* NO_SYS */
+  sys_sem_t *init_sem;
+  LWIP_ASSERT("arg != NULL", arg != NULL);
+  init_sem = (sys_sem_t*)arg;
+#endif /* NO_SYS */
+
+  /* init randomizer again (seed per thread) */
+  srand((unsigned int)time(0));
+
+  /* init network interfaces */
+  test_netif_init();
+
+  /* init apps */
+  apps_init();
+
+#if !NO_SYS
+  sys_sem_signal(init_sem);
+#endif /* !NO_SYS */
+}
+
+/* This is somewhat different to other ports: we have a main loop here:
+ * a dedicated task that waits for packets to arrive. This would normally be
+ * done from interrupt context with embedded hardware, but we don't get an
+ * interrupt in windows for that :-) */
+static void
+main_loop(void)
+{
+#if !NO_SYS
+  err_t err;
+  sys_sem_t init_sem;
+#endif /* NO_SYS */
+#if USE_PPP
+#if !USE_ETHERNET
+  int count;
+  u8_t rxbuf[1024];
+#endif
+  volatile int callClosePpp = 0;
+#endif /* USE_PPP */
+
+  /* initialize lwIP stack, network interfaces and applications */
+#if NO_SYS
+  lwip_init();
+  test_init(NULL);
+#else /* NO_SYS */
+  err = sys_sem_new(&init_sem, 0);
+  LWIP_ASSERT("failed to create init_sem", err == ERR_OK);
+  LWIP_UNUSED_ARG(err);
+  tcpip_init(test_init, &init_sem);
+  /* we have to wait for initialization to finish before
+   * calling update_adapter()! */
+  sys_sem_wait(&init_sem);
+  sys_sem_free(&init_sem);
+#endif /* NO_SYS */
+
+#if (LWIP_SOCKET || LWIP_NETCONN) && LWIP_NETCONN_SEM_PER_THREAD
+  netconn_thread_init();
+#endif
+
+  /* MAIN LOOP for driver update (and timers if NO_SYS) */
+  while (!LWIP_EXAMPLE_APP_ABORT()) {
+#if NO_SYS
+    /* handle timers (already done in tcpip.c when NO_SYS=0) */
+    sys_check_timeouts();
+#endif /* NO_SYS */
+
+#if USE_ETHERNET
+    default_netif_poll();
+#else /* USE_ETHERNET */
+    /* try to read characters from serial line and pass them to PPPoS */
+    count = sio_read(ppp_sio, (u8_t*)rxbuf, 1024);
+    if(count > 0) {
+      pppos_input(ppp, rxbuf, count);
+    } else {
+      /* nothing received, give other tasks a chance to run */
+      sys_msleep(1);
+    }
+
+#endif /* USE_ETHERNET */
+#if USE_SLIPIF
+    slipif_poll(&slipif1);
+#if USE_SLIPIF > 1
+    slipif_poll(&slipif2);
+#endif /* USE_SLIPIF > 1 */
+#endif /* USE_SLIPIF */
+#if ENABLE_LOOPBACK && !LWIP_NETIF_LOOPBACK_MULTITHREADING
+    /* check for loopback packets on all netifs */
+    netif_poll_all();
+#endif /* ENABLE_LOOPBACK && !LWIP_NETIF_LOOPBACK_MULTITHREADING */
+#if USE_PPP
+    {
+    int do_hup = 0;
+    if(do_hup) {
+      ppp_close(ppp, 1);
+      do_hup = 0;
+    }
+    }
+    if(callClosePpp && ppp) {
+      /* make sure to disconnect PPP before stopping the program... */
+      callClosePpp = 0;
+#if NO_SYS
+      ppp_close(ppp, 0);
+#else
+      pppapi_close(ppp, 0);
+#endif
+      ppp = NULL;
+    }
+#endif /* USE_PPP */
+  }
+
+#if USE_PPP
+    if(ppp) {
+      u32_t started;
+      printf("Closing PPP connection...\n");
+      /* make sure to disconnect PPP before stopping the program... */
+#if NO_SYS
+      ppp_close(ppp, 0);
+#else
+      pppapi_close(ppp, 0);
+#endif
+      ppp = NULL;
+      /* Wait for some time to let PPP finish... */
+      started = sys_now();
+      do
+      {
+#if USE_ETHERNET
+        default_netif_poll();
+#endif
+        /* @todo: need a better check here: only wait until PPP is down */
+      } while(sys_now() - started < 5000);
+    }
+#endif /* USE_PPP */
+#if (LWIP_SOCKET || LWIP_NETCONN) && LWIP_NETCONN_SEM_PER_THREAD
+  netconn_thread_cleanup();
+#endif
+#if USE_ETHERNET
+  default_netif_shutdown();
+#endif /* USE_ETHERNET */
+}
+
+#if USE_PPP && PPPOS_SUPPORT
+int main(int argc, char **argv)
+#else /* USE_PPP && PPPOS_SUPPORT */
+int main(void)
+#endif /* USE_PPP && PPPOS_SUPPORT */
+{
+#if USE_PPP && PPPOS_SUPPORT
+  if(argc > 1) {
+    sio_idx = (u8_t)atoi(argv[1]);
+  }
+  printf("Using serial port %d for PPP\n", sio_idx);
+#endif /* USE_PPP && PPPOS_SUPPORT */
+  /* no stdio-buffering, please! */
+  setvbuf(stdout, NULL,_IONBF, 0);
+
+  main_loop();
+
+  return 0;
+}
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/examples/example_app/test_configs/opt_default.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/examples/example_app/test_configs/opt_default.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/examples/example_app/test_configs/opt_default.h	(revision 457)
@@ -0,0 +1,296 @@
+/* test an lwipopts.h file with default contents */
+#define NO_SYS                          0
+#define NO_SYS_NO_TIMERS                0
+#define LWIP_TIMERS                     1
+#define LWIP_TIMERS_CUSTOM              0
+#define LWIP_MPU_COMPATIBLE             0
+#define LWIP_TCPIP_CORE_LOCKING         1
+#define LWIP_TCPIP_CORE_LOCKING_INPUT   0
+#define SYS_LIGHTWEIGHT_PROT            1
+#define MEM_LIBC_MALLOC                 0
+#define MEMP_MEM_MALLOC                 0
+#define MEMP_MEM_INIT                   0
+#define MEM_ALIGNMENT                   1
+#define MEM_SIZE                        1600
+#define MEMP_OVERFLOW_CHECK             0
+#define MEMP_SANITY_CHECK               0
+#define MEM_OVERFLOW_CHECK              0
+#define MEM_SANITY_CHECK                0
+#define MEM_USE_POOLS                   0
+#define MEM_USE_POOLS_TRY_BIGGER_POOL   0
+#define MEMP_USE_CUSTOM_POOLS           0
+#define LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT 0
+/*#define MEMP_NUM_PBUF                   16
+#define MEMP_NUM_RAW_PCB                4
+#define MEMP_NUM_UDP_PCB                4
+#define MEMP_NUM_TCP_PCB                5
+#define MEMP_NUM_TCP_PCB_LISTEN         8
+#define MEMP_NUM_TCP_SEG                16
+#define MEMP_NUM_ALTCP_PCB              MEMP_NUM_TCP_PCB
+#define MEMP_NUM_REASSDATA              5
+#define MEMP_NUM_FRAG_PBUF              15
+#define MEMP_NUM_ARP_QUEUE              30
+#define MEMP_NUM_IGMP_GROUP             8
+#define MEMP_NUM_SYS_TIMEOUT            (LWIP_NUM_SYS_TIMEOUT_INTERNAL + 2)
+#define MEMP_NUM_NETBUF                 2
+#define MEMP_NUM_NETCONN                4
+#define MEMP_NUM_SELECT_CB              4
+#define MEMP_NUM_TCPIP_MSG_API          8
+#define MEMP_NUM_TCPIP_MSG_INPKT        8
+#define MEMP_NUM_NETDB                  1
+#define MEMP_NUM_LOCALHOSTLIST          1
+#define PBUF_POOL_SIZE                  16
+#define MEMP_NUM_API_MSG                MEMP_NUM_TCPIP_MSG_API
+#define MEMP_NUM_DNS_API_MSG            MEMP_NUM_TCPIP_MSG_API
+#define MEMP_NUM_SOCKET_SETGETSOCKOPT_DATA MEMP_NUM_TCPIP_MSG_API
+#define MEMP_NUM_NETIFAPI_MSG           MEMP_NUM_TCPIP_MSG_API*/
+#define LWIP_ARP                        1
+#define ARP_TABLE_SIZE                  10
+#define ARP_MAXAGE                      300
+#define ARP_QUEUEING                    0
+#define ARP_QUEUE_LEN                   3
+#define ETHARP_SUPPORT_VLAN             0
+#define LWIP_ETHERNET                   LWIP_ARP
+#define ETH_PAD_SIZE                    0
+#define ETHARP_SUPPORT_STATIC_ENTRIES   0
+#define ETHARP_TABLE_MATCH_NETIF        !LWIP_SINGLE_NETIF
+#define LWIP_IPV4                       1
+#define IP_FORWARD                      0
+#define IP_REASSEMBLY                   1
+#define IP_FRAG                         1
+#define IP_OPTIONS_ALLOWED              1
+#define IP_REASS_MAXAGE                 15
+#define IP_REASS_MAX_PBUFS              10
+#define IP_DEFAULT_TTL                  255
+#define IP_SOF_BROADCAST                0
+#define IP_SOF_BROADCAST_RECV           0
+#define IP_FORWARD_ALLOW_TX_ON_RX_NETIF 0
+#define LWIP_ICMP                       1
+#define ICMP_TTL                        (IP_DEFAULT_TTL)
+#define LWIP_BROADCAST_PING             0
+#define LWIP_MULTICAST_PING             0
+#define LWIP_RAW                        0
+#define RAW_TTL                         (IP_DEFAULT_TTL)
+#define LWIP_DHCP                       0
+#define DHCP_DOES_ARP_CHECK             ((LWIP_DHCP) && (LWIP_ARP))
+#define LWIP_DHCP_CHECK_LINK_UP         0
+#define LWIP_DHCP_BOOTP_FILE            0
+#define LWIP_DHCP_GET_NTP_SRV           0
+#define LWIP_DHCP_MAX_NTP_SERVERS       1
+#define LWIP_DHCP_MAX_DNS_SERVERS       DNS_MAX_SERVERS
+#define LWIP_AUTOIP                     0
+#define LWIP_DHCP_AUTOIP_COOP           0
+#define LWIP_DHCP_AUTOIP_COOP_TRIES     9
+#define LWIP_MIB2_CALLBACKS             0
+#define LWIP_MULTICAST_TX_OPTIONS       ((LWIP_IGMP || LWIP_IPV6_MLD) && (LWIP_UDP || LWIP_RAW))
+#define LWIP_IGMP                       0
+#define LWIP_DNS                        0
+#define DNS_TABLE_SIZE                  4
+#define DNS_MAX_NAME_LENGTH             256
+#define DNS_MAX_SERVERS                 2
+#define DNS_MAX_RETRIES                 4
+#define DNS_DOES_NAME_CHECK             1
+#define LWIP_DNS_SECURE (LWIP_DNS_SECURE_RAND_XID | LWIP_DNS_SECURE_NO_MULTIPLE_OUTSTANDING | LWIP_DNS_SECURE_RAND_SRC_PORT)
+#define DNS_LOCAL_HOSTLIST              0
+#define DNS_LOCAL_HOSTLIST_IS_DYNAMIC   0
+#define LWIP_DNS_SUPPORT_MDNS_QUERIES   0
+#define LWIP_UDP                        1
+#define LWIP_UDPLITE                    0
+#define UDP_TTL                         (IP_DEFAULT_TTL)
+#define LWIP_NETBUF_RECVINFO            0
+#define LWIP_TCP                        1
+#define TCP_TTL                         (IP_DEFAULT_TTL)
+#define TCP_WND                         (4 * TCP_MSS)
+#define TCP_MAXRTX                      12
+#define TCP_SYNMAXRTX                   6
+#define TCP_QUEUE_OOSEQ                 (LWIP_TCP)
+#define LWIP_TCP_SACK_OUT               0
+#define LWIP_TCP_MAX_SACK_NUM           4
+#define TCP_MSS                         536
+#define TCP_CALCULATE_EFF_SEND_MSS      1
+#define TCP_SND_BUF                     (2 * TCP_MSS)
+#define TCP_SND_QUEUELEN                ((4 * (TCP_SND_BUF) + (TCP_MSS - 1))/(TCP_MSS))
+#define TCP_SNDLOWAT                    LWIP_MIN(LWIP_MAX(((TCP_SND_BUF)/2), (2 * TCP_MSS) + 1), (TCP_SND_BUF) - 1)
+#define TCP_SNDQUEUELOWAT               LWIP_MAX(((TCP_SND_QUEUELEN)/2), 5)
+#define TCP_OOSEQ_MAX_BYTES             0
+#define TCP_OOSEQ_BYTES_LIMIT(pcb)      TCP_OOSEQ_MAX_BYTES
+#define TCP_OOSEQ_MAX_PBUFS             0
+#define TCP_OOSEQ_PBUFS_LIMIT(pcb)      TCP_OOSEQ_MAX_PBUFS
+#define TCP_LISTEN_BACKLOG              0
+#define TCP_DEFAULT_LISTEN_BACKLOG      0xff
+#define TCP_OVERSIZE                    TCP_MSS
+#define LWIP_TCP_TIMESTAMPS             0
+#define TCP_WND_UPDATE_THRESHOLD        LWIP_MIN((TCP_WND / 4), (TCP_MSS * 4))
+#define LWIP_EVENT_API                  0
+#define LWIP_CALLBACK_API               1
+#define LWIP_WND_SCALE                  0
+#define TCP_RCV_SCALE                   0
+#define LWIP_TCP_PCB_NUM_EXT_ARGS       0
+#define LWIP_ALTCP                      0
+#define LWIP_ALTCP_TLS                  0
+#define PBUF_LINK_HLEN                  (14 + ETH_PAD_SIZE)
+#define PBUF_LINK_ENCAPSULATION_HLEN    0
+#define PBUF_POOL_BUFSIZE               LWIP_MEM_ALIGN_SIZE(TCP_MSS+40+PBUF_LINK_ENCAPSULATION_HLEN+PBUF_LINK_HLEN)
+#define LWIP_PBUF_REF_T                 u8_t
+#define LWIP_SINGLE_NETIF               0
+#define LWIP_NETIF_HOSTNAME             0
+#define LWIP_NETIF_API                  0
+#define LWIP_NETIF_STATUS_CALLBACK      0
+#define LWIP_NETIF_EXT_STATUS_CALLBACK  0
+#define LWIP_NETIF_LINK_CALLBACK        0
+#define LWIP_NETIF_REMOVE_CALLBACK      0
+#define LWIP_NETIF_HWADDRHINT           0
+#define LWIP_NETIF_TX_SINGLE_PBUF       0
+#define LWIP_NUM_NETIF_CLIENT_DATA      0
+#define LWIP_HAVE_LOOPIF                (LWIP_NETIF_LOOPBACK && !LWIP_SINGLE_NETIF)
+#define LWIP_LOOPIF_MULTICAST           0
+#define LWIP_NETIF_LOOPBACK             0
+#define LWIP_LOOPBACK_MAX_PBUFS         0
+#define LWIP_NETIF_LOOPBACK_MULTITHREADING    (!NO_SYS)
+/*#define TCPIP_THREAD_NAME               "tcpip_thread"
+#define TCPIP_THREAD_STACKSIZE          0
+#define TCPIP_THREAD_PRIO               1
+#define TCPIP_MBOX_SIZE                 0
+#define LWIP_TCPIP_THREAD_ALIVE()
+#define SLIPIF_THREAD_NAME              "slipif_loop"
+#define SLIPIF_THREAD_STACKSIZE         0
+#define SLIPIF_THREAD_PRIO              1
+#define DEFAULT_THREAD_NAME             "lwIP"
+#define DEFAULT_THREAD_STACKSIZE        0
+#define DEFAULT_THREAD_PRIO             1
+#define DEFAULT_RAW_RECVMBOX_SIZE       0
+#define DEFAULT_UDP_RECVMBOX_SIZE       0
+#define DEFAULT_TCP_RECVMBOX_SIZE       0
+#define DEFAULT_ACCEPTMBOX_SIZE         0*/
+#define LWIP_NETCONN                    1
+#define LWIP_TCPIP_TIMEOUT              0
+#define LWIP_NETCONN_SEM_PER_THREAD     0
+#define LWIP_NETCONN_FULLDUPLEX         0
+#define LWIP_SOCKET                     1
+#define LWIP_COMPAT_SOCKETS             1 /* 0..2 */
+#define LWIP_POSIX_SOCKETS_IO_NAMES     1
+#define LWIP_SOCKET_OFFSET              0
+#define LWIP_TCP_KEEPALIVE              0
+#define LWIP_SO_SNDTIMEO                0
+#define LWIP_SO_RCVTIMEO                0
+#define LWIP_SO_SNDRCVTIMEO_NONSTANDARD 0
+#define LWIP_SO_RCVBUF                  0
+#define LWIP_SO_LINGER                  0
+#define RECV_BUFSIZE_DEFAULT            INT_MAX
+#define LWIP_TCP_CLOSE_TIMEOUT_MS_DEFAULT 20000
+#define SO_REUSE                        0
+#define SO_REUSE_RXTOALL                0
+#define LWIP_FIONREAD_LINUXMODE         0
+#define LWIP_SOCKET_SELECT              1
+#define LWIP_SOCKET_POLL                1
+#define LWIP_STATS                      1
+#define LWIP_STATS_DISPLAY              0
+#define LINK_STATS                      1
+#define ETHARP_STATS                    (LWIP_ARP)
+#define IP_STATS                        1
+#define IPFRAG_STATS                    (IP_REASSEMBLY || IP_FRAG)
+#define ICMP_STATS                      1
+#define IGMP_STATS                      (LWIP_IGMP)
+#define UDP_STATS                       (LWIP_UDP)
+#define TCP_STATS                       (LWIP_TCP)
+#define MEM_STATS                       ((MEM_LIBC_MALLOC == 0) && (MEM_USE_POOLS == 0))
+#define MEMP_STATS                      (MEMP_MEM_MALLOC == 0)
+#define SYS_STATS                       (NO_SYS == 0)
+#define IP6_STATS                       (LWIP_IPV6)
+#define ICMP6_STATS                     (LWIP_IPV6 && LWIP_ICMP6)
+#define IP6_FRAG_STATS                  (LWIP_IPV6 && (LWIP_IPV6_FRAG || LWIP_IPV6_REASS))
+#define MLD6_STATS                      (LWIP_IPV6 && LWIP_IPV6_MLD)
+#define ND6_STATS                       (LWIP_IPV6)
+#define MIB2_STATS                      0
+#define LWIP_CHECKSUM_CTRL_PER_NETIF    0
+#define CHECKSUM_GEN_IP                 1
+#define CHECKSUM_GEN_UDP                1
+#define CHECKSUM_GEN_TCP                1
+#define CHECKSUM_GEN_ICMP               1
+#define CHECKSUM_GEN_ICMP6              1
+#define CHECKSUM_CHECK_IP               1
+#define CHECKSUM_CHECK_UDP              1
+#define CHECKSUM_CHECK_TCP              1
+#define CHECKSUM_CHECK_ICMP             1
+#define CHECKSUM_CHECK_ICMP6            1
+#define LWIP_CHECKSUM_ON_COPY           0
+#define LWIP_IPV6                       0
+#define IPV6_REASS_MAXAGE               60
+#define LWIP_IPV6_SCOPES                (LWIP_IPV6 && !LWIP_SINGLE_NETIF)
+#define LWIP_IPV6_SCOPES_DEBUG          0
+#define LWIP_IPV6_NUM_ADDRESSES         3
+#define LWIP_IPV6_FORWARD               0
+#define LWIP_IPV6_FRAG                  1
+#define LWIP_IPV6_REASS                 (LWIP_IPV6)
+#define LWIP_IPV6_SEND_ROUTER_SOLICIT   1
+#define LWIP_IPV6_AUTOCONFIG            (LWIP_IPV6)
+#define LWIP_IPV6_ADDRESS_LIFETIMES     (LWIP_IPV6_AUTOCONFIG)
+#define LWIP_IPV6_DUP_DETECT_ATTEMPTS   1
+#define LWIP_ICMP6                      (LWIP_IPV6)
+#define LWIP_ICMP6_DATASIZE             8
+#define LWIP_ICMP6_HL                   255
+#define LWIP_IPV6_MLD                   (LWIP_IPV6)
+#define MEMP_NUM_MLD6_GROUP             4
+#define LWIP_ND6_QUEUEING               (LWIP_IPV6)
+#define MEMP_NUM_ND6_QUEUE              20
+#define LWIP_ND6_NUM_NEIGHBORS          10
+#define LWIP_ND6_NUM_DESTINATIONS       10
+#define LWIP_ND6_NUM_PREFIXES           5
+#define LWIP_ND6_NUM_ROUTERS            3
+#define LWIP_ND6_MAX_MULTICAST_SOLICIT  3
+#define LWIP_ND6_MAX_UNICAST_SOLICIT    3
+#define LWIP_ND6_MAX_ANYCAST_DELAY_TIME 1000
+#define LWIP_ND6_MAX_NEIGHBOR_ADVERTISEMENT  3
+#define LWIP_ND6_REACHABLE_TIME         30000
+#define LWIP_ND6_RETRANS_TIMER          1000
+#define LWIP_ND6_DELAY_FIRST_PROBE_TIME 5000
+#define LWIP_ND6_ALLOW_RA_UPDATES       1
+#define LWIP_ND6_TCP_REACHABILITY_HINTS 1
+#define LWIP_ND6_RDNSS_MAX_DNS_SERVERS  0
+#define LWIP_IPV6_DHCP6                 0
+#define LWIP_IPV6_DHCP6_STATEFUL        0
+#define LWIP_IPV6_DHCP6_STATELESS       LWIP_IPV6_DHCP6
+#define LWIP_DHCP6_GET_NTP_SRV          0
+#define LWIP_DHCP6_MAX_NTP_SERVERS      1
+#define LWIP_DHCP6_MAX_DNS_SERVERS      DNS_MAX_SERVERS
+
+/* TODO: check hooks */
+
+#define LWIP_DBG_MIN_LEVEL              LWIP_DBG_LEVEL_ALL
+#define LWIP_DBG_TYPES_ON               LWIP_DBG_ON
+#define ETHARP_DEBUG                    LWIP_DBG_OFF
+#define NETIF_DEBUG                     LWIP_DBG_OFF
+#define PBUF_DEBUG                      LWIP_DBG_OFF
+#define API_LIB_DEBUG                   LWIP_DBG_OFF
+#define API_MSG_DEBUG                   LWIP_DBG_OFF
+#define SOCKETS_DEBUG                   LWIP_DBG_OFF
+#define ICMP_DEBUG                      LWIP_DBG_OFF
+#define IGMP_DEBUG                      LWIP_DBG_OFF
+#define INET_DEBUG                      LWIP_DBG_OFF
+#define IP_DEBUG                        LWIP_DBG_OFF
+#define IP_REASS_DEBUG                  LWIP_DBG_OFF
+#define RAW_DEBUG                       LWIP_DBG_OFF
+#define MEM_DEBUG                       LWIP_DBG_OFF
+#define MEMP_DEBUG                      LWIP_DBG_OFF
+#define SYS_DEBUG                       LWIP_DBG_OFF
+#define TIMERS_DEBUG                    LWIP_DBG_OFF
+#define TCP_DEBUG                       LWIP_DBG_OFF
+#define TCP_INPUT_DEBUG                 LWIP_DBG_OFF
+#define TCP_FR_DEBUG                    LWIP_DBG_OFF
+#define TCP_RTO_DEBUG                   LWIP_DBG_OFF
+#define TCP_CWND_DEBUG                  LWIP_DBG_OFF
+#define TCP_WND_DEBUG                   LWIP_DBG_OFF
+#define TCP_OUTPUT_DEBUG                LWIP_DBG_OFF
+#define TCP_RST_DEBUG                   LWIP_DBG_OFF
+#define TCP_QLEN_DEBUG                  LWIP_DBG_OFF
+#define UDP_DEBUG                       LWIP_DBG_OFF
+#define TCPIP_DEBUG                     LWIP_DBG_OFF
+#define SLIP_DEBUG                      LWIP_DBG_OFF
+#define DHCP_DEBUG                      LWIP_DBG_OFF
+#define AUTOIP_DEBUG                    LWIP_DBG_OFF
+#define DNS_DEBUG                       LWIP_DBG_OFF
+#define IP6_DEBUG                       LWIP_DBG_OFF
+#define DHCP6_DEBUG                     LWIP_DBG_OFF
+#define LWIP_TESTMODE                   0
+
+#define LWIP_PERF                       0
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/examples/example_app/test_configs/opt_dualstack.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/examples/example_app/test_configs/opt_dualstack.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/examples/example_app/test_configs/opt_dualstack.h	(revision 457)
@@ -0,0 +1,296 @@
+/* test an lwipopts.h file with default contents */
+#define NO_SYS                          0
+#define NO_SYS_NO_TIMERS                0
+#define LWIP_TIMERS                     1
+#define LWIP_TIMERS_CUSTOM              0
+#define LWIP_MPU_COMPATIBLE             0
+#define LWIP_TCPIP_CORE_LOCKING         1
+#define LWIP_TCPIP_CORE_LOCKING_INPUT   0
+#define SYS_LIGHTWEIGHT_PROT            1
+#define MEM_LIBC_MALLOC                 0
+#define MEMP_MEM_MALLOC                 0
+#define MEMP_MEM_INIT                   0
+#define MEM_ALIGNMENT                   1
+#define MEM_SIZE                        1600
+#define MEMP_OVERFLOW_CHECK             0
+#define MEMP_SANITY_CHECK               0
+#define MEM_OVERFLOW_CHECK              0
+#define MEM_SANITY_CHECK                0
+#define MEM_USE_POOLS                   0
+#define MEM_USE_POOLS_TRY_BIGGER_POOL   0
+#define MEMP_USE_CUSTOM_POOLS           0
+#define LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT 0
+/*#define MEMP_NUM_PBUF                   16
+#define MEMP_NUM_RAW_PCB                4
+#define MEMP_NUM_UDP_PCB                4
+#define MEMP_NUM_TCP_PCB                5
+#define MEMP_NUM_TCP_PCB_LISTEN         8
+#define MEMP_NUM_TCP_SEG                16
+#define MEMP_NUM_ALTCP_PCB              MEMP_NUM_TCP_PCB
+#define MEMP_NUM_REASSDATA              5
+#define MEMP_NUM_FRAG_PBUF              15
+#define MEMP_NUM_ARP_QUEUE              30
+#define MEMP_NUM_IGMP_GROUP             8
+#define MEMP_NUM_SYS_TIMEOUT            (LWIP_NUM_SYS_TIMEOUT_INTERNAL + 2)
+#define MEMP_NUM_NETBUF                 2
+#define MEMP_NUM_NETCONN                4
+#define MEMP_NUM_SELECT_CB              4
+#define MEMP_NUM_TCPIP_MSG_API          8
+#define MEMP_NUM_TCPIP_MSG_INPKT        8
+#define MEMP_NUM_NETDB                  1
+#define MEMP_NUM_LOCALHOSTLIST          1
+#define PBUF_POOL_SIZE                  16
+#define MEMP_NUM_API_MSG                MEMP_NUM_TCPIP_MSG_API
+#define MEMP_NUM_DNS_API_MSG            MEMP_NUM_TCPIP_MSG_API
+#define MEMP_NUM_SOCKET_SETGETSOCKOPT_DATA MEMP_NUM_TCPIP_MSG_API
+#define MEMP_NUM_NETIFAPI_MSG           MEMP_NUM_TCPIP_MSG_API*/
+#define LWIP_ARP                        1
+#define ARP_TABLE_SIZE                  10
+#define ARP_MAXAGE                      300
+#define ARP_QUEUEING                    0
+#define ARP_QUEUE_LEN                   3
+#define ETHARP_SUPPORT_VLAN             0
+#define LWIP_ETHERNET                   LWIP_ARP
+#define ETH_PAD_SIZE                    0
+#define ETHARP_SUPPORT_STATIC_ENTRIES   0
+#define ETHARP_TABLE_MATCH_NETIF        !LWIP_SINGLE_NETIF
+#define LWIP_IPV4                       1
+#define IP_FORWARD                      0
+#define IP_REASSEMBLY                   1
+#define IP_FRAG                         1
+#define IP_OPTIONS_ALLOWED              1
+#define IP_REASS_MAXAGE                 15
+#define IP_REASS_MAX_PBUFS              10
+#define IP_DEFAULT_TTL                  255
+#define IP_SOF_BROADCAST                0
+#define IP_SOF_BROADCAST_RECV           0
+#define IP_FORWARD_ALLOW_TX_ON_RX_NETIF 0
+#define LWIP_ICMP                       1
+#define ICMP_TTL                        (IP_DEFAULT_TTL)
+#define LWIP_BROADCAST_PING             0
+#define LWIP_MULTICAST_PING             0
+#define LWIP_RAW                        0
+#define RAW_TTL                         (IP_DEFAULT_TTL)
+#define LWIP_DHCP                       0
+#define DHCP_DOES_ARP_CHECK             ((LWIP_DHCP) && (LWIP_ARP))
+#define LWIP_DHCP_CHECK_LINK_UP         0
+#define LWIP_DHCP_BOOTP_FILE            0
+#define LWIP_DHCP_GET_NTP_SRV           0
+#define LWIP_DHCP_MAX_NTP_SERVERS       1
+#define LWIP_DHCP_MAX_DNS_SERVERS       DNS_MAX_SERVERS
+#define LWIP_AUTOIP                     0
+#define LWIP_DHCP_AUTOIP_COOP           0
+#define LWIP_DHCP_AUTOIP_COOP_TRIES     9
+#define LWIP_MIB2_CALLBACKS             0
+#define LWIP_MULTICAST_TX_OPTIONS       ((LWIP_IGMP || LWIP_IPV6_MLD) && (LWIP_UDP || LWIP_RAW))
+#define LWIP_IGMP                       0
+#define LWIP_DNS                        0
+#define DNS_TABLE_SIZE                  4
+#define DNS_MAX_NAME_LENGTH             256
+#define DNS_MAX_SERVERS                 2
+#define DNS_MAX_RETRIES                 4
+#define DNS_DOES_NAME_CHECK             1
+#define LWIP_DNS_SECURE (LWIP_DNS_SECURE_RAND_XID | LWIP_DNS_SECURE_NO_MULTIPLE_OUTSTANDING | LWIP_DNS_SECURE_RAND_SRC_PORT)
+#define DNS_LOCAL_HOSTLIST              0
+#define DNS_LOCAL_HOSTLIST_IS_DYNAMIC   0
+#define LWIP_DNS_SUPPORT_MDNS_QUERIES   0
+#define LWIP_UDP                        1
+#define LWIP_UDPLITE                    0
+#define UDP_TTL                         (IP_DEFAULT_TTL)
+#define LWIP_NETBUF_RECVINFO            0
+#define LWIP_TCP                        1
+#define TCP_TTL                         (IP_DEFAULT_TTL)
+#define TCP_WND                         (4 * TCP_MSS)
+#define TCP_MAXRTX                      12
+#define TCP_SYNMAXRTX                   6
+#define TCP_QUEUE_OOSEQ                 (LWIP_TCP)
+#define LWIP_TCP_SACK_OUT               0
+#define LWIP_TCP_MAX_SACK_NUM           4
+#define TCP_MSS                         536
+#define TCP_CALCULATE_EFF_SEND_MSS      1
+#define TCP_SND_BUF                     (2 * TCP_MSS)
+#define TCP_SND_QUEUELEN                ((4 * (TCP_SND_BUF) + (TCP_MSS - 1))/(TCP_MSS))
+#define TCP_SNDLOWAT                    LWIP_MIN(LWIP_MAX(((TCP_SND_BUF)/2), (2 * TCP_MSS) + 1), (TCP_SND_BUF) - 1)
+#define TCP_SNDQUEUELOWAT               LWIP_MAX(((TCP_SND_QUEUELEN)/2), 5)
+#define TCP_OOSEQ_MAX_BYTES             0
+#define TCP_OOSEQ_BYTES_LIMIT(pcb)      TCP_OOSEQ_MAX_BYTES
+#define TCP_OOSEQ_MAX_PBUFS             0
+#define TCP_OOSEQ_PBUFS_LIMIT(pcb)      TCP_OOSEQ_MAX_PBUFS
+#define TCP_LISTEN_BACKLOG              0
+#define TCP_DEFAULT_LISTEN_BACKLOG      0xff
+#define TCP_OVERSIZE                    TCP_MSS
+#define LWIP_TCP_TIMESTAMPS             0
+#define TCP_WND_UPDATE_THRESHOLD        LWIP_MIN((TCP_WND / 4), (TCP_MSS * 4))
+#define LWIP_EVENT_API                  0
+#define LWIP_CALLBACK_API               1
+#define LWIP_WND_SCALE                  0
+#define TCP_RCV_SCALE                   0
+#define LWIP_TCP_PCB_NUM_EXT_ARGS       0
+#define LWIP_ALTCP                      0
+#define LWIP_ALTCP_TLS                  0
+#define PBUF_LINK_HLEN                  (14 + ETH_PAD_SIZE)
+#define PBUF_LINK_ENCAPSULATION_HLEN    0
+#define PBUF_POOL_BUFSIZE               LWIP_MEM_ALIGN_SIZE(TCP_MSS+40+PBUF_LINK_ENCAPSULATION_HLEN+PBUF_LINK_HLEN)
+#define LWIP_PBUF_REF_T                 u8_t
+#define LWIP_SINGLE_NETIF               0
+#define LWIP_NETIF_HOSTNAME             0
+#define LWIP_NETIF_API                  0
+#define LWIP_NETIF_STATUS_CALLBACK      0
+#define LWIP_NETIF_EXT_STATUS_CALLBACK  0
+#define LWIP_NETIF_LINK_CALLBACK        0
+#define LWIP_NETIF_REMOVE_CALLBACK      0
+#define LWIP_NETIF_HWADDRHINT           0
+#define LWIP_NETIF_TX_SINGLE_PBUF       0
+#define LWIP_NUM_NETIF_CLIENT_DATA      0
+#define LWIP_HAVE_LOOPIF                (LWIP_NETIF_LOOPBACK && !LWIP_SINGLE_NETIF)
+#define LWIP_LOOPIF_MULTICAST           0
+#define LWIP_NETIF_LOOPBACK             0
+#define LWIP_LOOPBACK_MAX_PBUFS         0
+#define LWIP_NETIF_LOOPBACK_MULTITHREADING    (!NO_SYS)
+/*#define TCPIP_THREAD_NAME               "tcpip_thread"
+#define TCPIP_THREAD_STACKSIZE          0
+#define TCPIP_THREAD_PRIO               1
+#define TCPIP_MBOX_SIZE                 0
+#define LWIP_TCPIP_THREAD_ALIVE()
+#define SLIPIF_THREAD_NAME              "slipif_loop"
+#define SLIPIF_THREAD_STACKSIZE         0
+#define SLIPIF_THREAD_PRIO              1
+#define DEFAULT_THREAD_NAME             "lwIP"
+#define DEFAULT_THREAD_STACKSIZE        0
+#define DEFAULT_THREAD_PRIO             1
+#define DEFAULT_RAW_RECVMBOX_SIZE       0
+#define DEFAULT_UDP_RECVMBOX_SIZE       0
+#define DEFAULT_TCP_RECVMBOX_SIZE       0
+#define DEFAULT_ACCEPTMBOX_SIZE         0*/
+#define LWIP_NETCONN                    1
+#define LWIP_TCPIP_TIMEOUT              0
+#define LWIP_NETCONN_SEM_PER_THREAD     0
+#define LWIP_NETCONN_FULLDUPLEX         0
+#define LWIP_SOCKET                     1
+#define LWIP_COMPAT_SOCKETS             1 /* 0..2 */
+#define LWIP_POSIX_SOCKETS_IO_NAMES     1
+#define LWIP_SOCKET_OFFSET              0
+#define LWIP_TCP_KEEPALIVE              0
+#define LWIP_SO_SNDTIMEO                0
+#define LWIP_SO_RCVTIMEO                0
+#define LWIP_SO_SNDRCVTIMEO_NONSTANDARD 0
+#define LWIP_SO_RCVBUF                  0
+#define LWIP_SO_LINGER                  0
+#define RECV_BUFSIZE_DEFAULT            INT_MAX
+#define LWIP_TCP_CLOSE_TIMEOUT_MS_DEFAULT 20000
+#define SO_REUSE                        0
+#define SO_REUSE_RXTOALL                0
+#define LWIP_FIONREAD_LINUXMODE         0
+#define LWIP_SOCKET_SELECT              1
+#define LWIP_SOCKET_POLL                1
+#define LWIP_STATS                      1
+#define LWIP_STATS_DISPLAY              0
+#define LINK_STATS                      1
+#define ETHARP_STATS                    (LWIP_ARP)
+#define IP_STATS                        1
+#define IPFRAG_STATS                    (IP_REASSEMBLY || IP_FRAG)
+#define ICMP_STATS                      1
+#define IGMP_STATS                      (LWIP_IGMP)
+#define UDP_STATS                       (LWIP_UDP)
+#define TCP_STATS                       (LWIP_TCP)
+#define MEM_STATS                       ((MEM_LIBC_MALLOC == 0) && (MEM_USE_POOLS == 0))
+#define MEMP_STATS                      (MEMP_MEM_MALLOC == 0)
+#define SYS_STATS                       (NO_SYS == 0)
+#define IP6_STATS                       (LWIP_IPV6)
+#define ICMP6_STATS                     (LWIP_IPV6 && LWIP_ICMP6)
+#define IP6_FRAG_STATS                  (LWIP_IPV6 && (LWIP_IPV6_FRAG || LWIP_IPV6_REASS))
+#define MLD6_STATS                      (LWIP_IPV6 && LWIP_IPV6_MLD)
+#define ND6_STATS                       (LWIP_IPV6)
+#define MIB2_STATS                      0
+#define LWIP_CHECKSUM_CTRL_PER_NETIF    0
+#define CHECKSUM_GEN_IP                 1
+#define CHECKSUM_GEN_UDP                1
+#define CHECKSUM_GEN_TCP                1
+#define CHECKSUM_GEN_ICMP               1
+#define CHECKSUM_GEN_ICMP6              1
+#define CHECKSUM_CHECK_IP               1
+#define CHECKSUM_CHECK_UDP              1
+#define CHECKSUM_CHECK_TCP              1
+#define CHECKSUM_CHECK_ICMP             1
+#define CHECKSUM_CHECK_ICMP6            1
+#define LWIP_CHECKSUM_ON_COPY           0
+#define LWIP_IPV6                       1
+#define IPV6_REASS_MAXAGE               60
+#define LWIP_IPV6_SCOPES                (LWIP_IPV6 && !LWIP_SINGLE_NETIF)
+#define LWIP_IPV6_SCOPES_DEBUG          0
+#define LWIP_IPV6_NUM_ADDRESSES         3
+#define LWIP_IPV6_FORWARD               0
+#define LWIP_IPV6_FRAG                  1
+#define LWIP_IPV6_REASS                 (LWIP_IPV6)
+#define LWIP_IPV6_SEND_ROUTER_SOLICIT   1
+#define LWIP_IPV6_AUTOCONFIG            (LWIP_IPV6)
+#define LWIP_IPV6_ADDRESS_LIFETIMES     (LWIP_IPV6_AUTOCONFIG)
+#define LWIP_IPV6_DUP_DETECT_ATTEMPTS   1
+#define LWIP_ICMP6                      (LWIP_IPV6)
+#define LWIP_ICMP6_DATASIZE             8
+#define LWIP_ICMP6_HL                   255
+#define LWIP_IPV6_MLD                   (LWIP_IPV6)
+#define MEMP_NUM_MLD6_GROUP             4
+#define LWIP_ND6_QUEUEING               (LWIP_IPV6)
+#define MEMP_NUM_ND6_QUEUE              20
+#define LWIP_ND6_NUM_NEIGHBORS          10
+#define LWIP_ND6_NUM_DESTINATIONS       10
+#define LWIP_ND6_NUM_PREFIXES           5
+#define LWIP_ND6_NUM_ROUTERS            3
+#define LWIP_ND6_MAX_MULTICAST_SOLICIT  3
+#define LWIP_ND6_MAX_UNICAST_SOLICIT    3
+#define LWIP_ND6_MAX_ANYCAST_DELAY_TIME 1000
+#define LWIP_ND6_MAX_NEIGHBOR_ADVERTISEMENT  3
+#define LWIP_ND6_REACHABLE_TIME         30000
+#define LWIP_ND6_RETRANS_TIMER          1000
+#define LWIP_ND6_DELAY_FIRST_PROBE_TIME 5000
+#define LWIP_ND6_ALLOW_RA_UPDATES       1
+#define LWIP_ND6_TCP_REACHABILITY_HINTS 1
+#define LWIP_ND6_RDNSS_MAX_DNS_SERVERS  0
+#define LWIP_IPV6_DHCP6                 0
+#define LWIP_IPV6_DHCP6_STATEFUL        0
+#define LWIP_IPV6_DHCP6_STATELESS       LWIP_IPV6_DHCP6
+#define LWIP_DHCP6_GET_NTP_SRV          0
+#define LWIP_DHCP6_MAX_NTP_SERVERS      1
+#define LWIP_DHCP6_MAX_DNS_SERVERS      DNS_MAX_SERVERS
+
+/* TODO: check hooks */
+
+#define LWIP_DBG_MIN_LEVEL              LWIP_DBG_LEVEL_ALL
+#define LWIP_DBG_TYPES_ON               LWIP_DBG_ON
+#define ETHARP_DEBUG                    LWIP_DBG_OFF
+#define NETIF_DEBUG                     LWIP_DBG_OFF
+#define PBUF_DEBUG                      LWIP_DBG_OFF
+#define API_LIB_DEBUG                   LWIP_DBG_OFF
+#define API_MSG_DEBUG                   LWIP_DBG_OFF
+#define SOCKETS_DEBUG                   LWIP_DBG_OFF
+#define ICMP_DEBUG                      LWIP_DBG_OFF
+#define IGMP_DEBUG                      LWIP_DBG_OFF
+#define INET_DEBUG                      LWIP_DBG_OFF
+#define IP_DEBUG                        LWIP_DBG_OFF
+#define IP_REASS_DEBUG                  LWIP_DBG_OFF
+#define RAW_DEBUG                       LWIP_DBG_OFF
+#define MEM_DEBUG                       LWIP_DBG_OFF
+#define MEMP_DEBUG                      LWIP_DBG_OFF
+#define SYS_DEBUG                       LWIP_DBG_OFF
+#define TIMERS_DEBUG                    LWIP_DBG_OFF
+#define TCP_DEBUG                       LWIP_DBG_OFF
+#define TCP_INPUT_DEBUG                 LWIP_DBG_OFF
+#define TCP_FR_DEBUG                    LWIP_DBG_OFF
+#define TCP_RTO_DEBUG                   LWIP_DBG_OFF
+#define TCP_CWND_DEBUG                  LWIP_DBG_OFF
+#define TCP_WND_DEBUG                   LWIP_DBG_OFF
+#define TCP_OUTPUT_DEBUG                LWIP_DBG_OFF
+#define TCP_RST_DEBUG                   LWIP_DBG_OFF
+#define TCP_QLEN_DEBUG                  LWIP_DBG_OFF
+#define UDP_DEBUG                       LWIP_DBG_OFF
+#define TCPIP_DEBUG                     LWIP_DBG_OFF
+#define SLIP_DEBUG                      LWIP_DBG_OFF
+#define DHCP_DEBUG                      LWIP_DBG_OFF
+#define AUTOIP_DEBUG                    LWIP_DBG_OFF
+#define DNS_DEBUG                       LWIP_DBG_OFF
+#define IP6_DEBUG                       LWIP_DBG_OFF
+#define DHCP6_DEBUG                     LWIP_DBG_OFF
+#define LWIP_TESTMODE                   0
+
+#define LWIP_PERF                       0
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/examples/example_app/test_configs/opt_ipv4only.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/examples/example_app/test_configs/opt_ipv4only.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/examples/example_app/test_configs/opt_ipv4only.h	(revision 457)
@@ -0,0 +1,296 @@
+/* test an lwipopts.h file with default contents */
+#define NO_SYS                          0
+#define NO_SYS_NO_TIMERS                0
+#define LWIP_TIMERS                     1
+#define LWIP_TIMERS_CUSTOM              0
+#define LWIP_MPU_COMPATIBLE             0
+#define LWIP_TCPIP_CORE_LOCKING         1
+#define LWIP_TCPIP_CORE_LOCKING_INPUT   0
+#define SYS_LIGHTWEIGHT_PROT            1
+#define MEM_LIBC_MALLOC                 0
+#define MEMP_MEM_MALLOC                 0
+#define MEMP_MEM_INIT                   0
+#define MEM_ALIGNMENT                   1
+#define MEM_SIZE                        1600
+#define MEMP_OVERFLOW_CHECK             0
+#define MEMP_SANITY_CHECK               0
+#define MEM_OVERFLOW_CHECK              0
+#define MEM_SANITY_CHECK                0
+#define MEM_USE_POOLS                   0
+#define MEM_USE_POOLS_TRY_BIGGER_POOL   0
+#define MEMP_USE_CUSTOM_POOLS           0
+#define LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT 0
+/*#define MEMP_NUM_PBUF                   16
+#define MEMP_NUM_RAW_PCB                4
+#define MEMP_NUM_UDP_PCB                4
+#define MEMP_NUM_TCP_PCB                5
+#define MEMP_NUM_TCP_PCB_LISTEN         8
+#define MEMP_NUM_TCP_SEG                16
+#define MEMP_NUM_ALTCP_PCB              MEMP_NUM_TCP_PCB
+#define MEMP_NUM_REASSDATA              5
+#define MEMP_NUM_FRAG_PBUF              15
+#define MEMP_NUM_ARP_QUEUE              30
+#define MEMP_NUM_IGMP_GROUP             8
+#define MEMP_NUM_SYS_TIMEOUT            (LWIP_NUM_SYS_TIMEOUT_INTERNAL + 2)
+#define MEMP_NUM_NETBUF                 2
+#define MEMP_NUM_NETCONN                4
+#define MEMP_NUM_SELECT_CB              4
+#define MEMP_NUM_TCPIP_MSG_API          8
+#define MEMP_NUM_TCPIP_MSG_INPKT        8
+#define MEMP_NUM_NETDB                  1
+#define MEMP_NUM_LOCALHOSTLIST          1
+#define PBUF_POOL_SIZE                  16
+#define MEMP_NUM_API_MSG                MEMP_NUM_TCPIP_MSG_API
+#define MEMP_NUM_DNS_API_MSG            MEMP_NUM_TCPIP_MSG_API
+#define MEMP_NUM_SOCKET_SETGETSOCKOPT_DATA MEMP_NUM_TCPIP_MSG_API
+#define MEMP_NUM_NETIFAPI_MSG           MEMP_NUM_TCPIP_MSG_API*/
+#define LWIP_ARP                        1
+#define ARP_TABLE_SIZE                  10
+#define ARP_MAXAGE                      300
+#define ARP_QUEUEING                    0
+#define ARP_QUEUE_LEN                   3
+#define ETHARP_SUPPORT_VLAN             0
+#define LWIP_ETHERNET                   LWIP_ARP
+#define ETH_PAD_SIZE                    0
+#define ETHARP_SUPPORT_STATIC_ENTRIES   0
+#define ETHARP_TABLE_MATCH_NETIF        !LWIP_SINGLE_NETIF
+#define LWIP_IPV4                       1
+#define IP_FORWARD                      0
+#define IP_REASSEMBLY                   1
+#define IP_FRAG                         1
+#define IP_OPTIONS_ALLOWED              1
+#define IP_REASS_MAXAGE                 15
+#define IP_REASS_MAX_PBUFS              10
+#define IP_DEFAULT_TTL                  255
+#define IP_SOF_BROADCAST                0
+#define IP_SOF_BROADCAST_RECV           0
+#define IP_FORWARD_ALLOW_TX_ON_RX_NETIF 0
+#define LWIP_ICMP                       1
+#define ICMP_TTL                        (IP_DEFAULT_TTL)
+#define LWIP_BROADCAST_PING             0
+#define LWIP_MULTICAST_PING             0
+#define LWIP_RAW                        0
+#define RAW_TTL                         (IP_DEFAULT_TTL)
+#define LWIP_DHCP                       0
+#define DHCP_DOES_ARP_CHECK             ((LWIP_DHCP) && (LWIP_ARP))
+#define LWIP_DHCP_CHECK_LINK_UP         0
+#define LWIP_DHCP_BOOTP_FILE            0
+#define LWIP_DHCP_GET_NTP_SRV           0
+#define LWIP_DHCP_MAX_NTP_SERVERS       1
+#define LWIP_DHCP_MAX_DNS_SERVERS       DNS_MAX_SERVERS
+#define LWIP_AUTOIP                     0
+#define LWIP_DHCP_AUTOIP_COOP           0
+#define LWIP_DHCP_AUTOIP_COOP_TRIES     9
+#define LWIP_MIB2_CALLBACKS             0
+#define LWIP_MULTICAST_TX_OPTIONS       ((LWIP_IGMP || LWIP_IPV6_MLD) && (LWIP_UDP || LWIP_RAW))
+#define LWIP_IGMP                       0
+#define LWIP_DNS                        0
+#define DNS_TABLE_SIZE                  4
+#define DNS_MAX_NAME_LENGTH             256
+#define DNS_MAX_SERVERS                 2
+#define DNS_MAX_RETRIES                 4
+#define DNS_DOES_NAME_CHECK             1
+#define LWIP_DNS_SECURE (LWIP_DNS_SECURE_RAND_XID | LWIP_DNS_SECURE_NO_MULTIPLE_OUTSTANDING | LWIP_DNS_SECURE_RAND_SRC_PORT)
+#define DNS_LOCAL_HOSTLIST              0
+#define DNS_LOCAL_HOSTLIST_IS_DYNAMIC   0
+#define LWIP_DNS_SUPPORT_MDNS_QUERIES   0
+#define LWIP_UDP                        1
+#define LWIP_UDPLITE                    0
+#define UDP_TTL                         (IP_DEFAULT_TTL)
+#define LWIP_NETBUF_RECVINFO            0
+#define LWIP_TCP                        1
+#define TCP_TTL                         (IP_DEFAULT_TTL)
+#define TCP_WND                         (4 * TCP_MSS)
+#define TCP_MAXRTX                      12
+#define TCP_SYNMAXRTX                   6
+#define TCP_QUEUE_OOSEQ                 (LWIP_TCP)
+#define LWIP_TCP_SACK_OUT               0
+#define LWIP_TCP_MAX_SACK_NUM           4
+#define TCP_MSS                         536
+#define TCP_CALCULATE_EFF_SEND_MSS      1
+#define TCP_SND_BUF                     (2 * TCP_MSS)
+#define TCP_SND_QUEUELEN                ((4 * (TCP_SND_BUF) + (TCP_MSS - 1))/(TCP_MSS))
+#define TCP_SNDLOWAT                    LWIP_MIN(LWIP_MAX(((TCP_SND_BUF)/2), (2 * TCP_MSS) + 1), (TCP_SND_BUF) - 1)
+#define TCP_SNDQUEUELOWAT               LWIP_MAX(((TCP_SND_QUEUELEN)/2), 5)
+#define TCP_OOSEQ_MAX_BYTES             0
+#define TCP_OOSEQ_BYTES_LIMIT(pcb)      TCP_OOSEQ_MAX_BYTES
+#define TCP_OOSEQ_MAX_PBUFS             0
+#define TCP_OOSEQ_PBUFS_LIMIT(pcb)      TCP_OOSEQ_MAX_PBUFS
+#define TCP_LISTEN_BACKLOG              0
+#define TCP_DEFAULT_LISTEN_BACKLOG      0xff
+#define TCP_OVERSIZE                    TCP_MSS
+#define LWIP_TCP_TIMESTAMPS             0
+#define TCP_WND_UPDATE_THRESHOLD        LWIP_MIN((TCP_WND / 4), (TCP_MSS * 4))
+#define LWIP_EVENT_API                  0
+#define LWIP_CALLBACK_API               1
+#define LWIP_WND_SCALE                  0
+#define TCP_RCV_SCALE                   0
+#define LWIP_TCP_PCB_NUM_EXT_ARGS       0
+#define LWIP_ALTCP                      0
+#define LWIP_ALTCP_TLS                  0
+#define PBUF_LINK_HLEN                  (14 + ETH_PAD_SIZE)
+#define PBUF_LINK_ENCAPSULATION_HLEN    0
+#define PBUF_POOL_BUFSIZE               LWIP_MEM_ALIGN_SIZE(TCP_MSS+40+PBUF_LINK_ENCAPSULATION_HLEN+PBUF_LINK_HLEN)
+#define LWIP_PBUF_REF_T                 u8_t
+#define LWIP_SINGLE_NETIF               0
+#define LWIP_NETIF_HOSTNAME             0
+#define LWIP_NETIF_API                  0
+#define LWIP_NETIF_STATUS_CALLBACK      0
+#define LWIP_NETIF_EXT_STATUS_CALLBACK  0
+#define LWIP_NETIF_LINK_CALLBACK        0
+#define LWIP_NETIF_REMOVE_CALLBACK      0
+#define LWIP_NETIF_HWADDRHINT           0
+#define LWIP_NETIF_TX_SINGLE_PBUF       0
+#define LWIP_NUM_NETIF_CLIENT_DATA      0
+#define LWIP_HAVE_LOOPIF                (LWIP_NETIF_LOOPBACK && !LWIP_SINGLE_NETIF)
+#define LWIP_LOOPIF_MULTICAST           0
+#define LWIP_NETIF_LOOPBACK             0
+#define LWIP_LOOPBACK_MAX_PBUFS         0
+#define LWIP_NETIF_LOOPBACK_MULTITHREADING    (!NO_SYS)
+/*#define TCPIP_THREAD_NAME               "tcpip_thread"
+#define TCPIP_THREAD_STACKSIZE          0
+#define TCPIP_THREAD_PRIO               1
+#define TCPIP_MBOX_SIZE                 0
+#define LWIP_TCPIP_THREAD_ALIVE()
+#define SLIPIF_THREAD_NAME              "slipif_loop"
+#define SLIPIF_THREAD_STACKSIZE         0
+#define SLIPIF_THREAD_PRIO              1
+#define DEFAULT_THREAD_NAME             "lwIP"
+#define DEFAULT_THREAD_STACKSIZE        0
+#define DEFAULT_THREAD_PRIO             1
+#define DEFAULT_RAW_RECVMBOX_SIZE       0
+#define DEFAULT_UDP_RECVMBOX_SIZE       0
+#define DEFAULT_TCP_RECVMBOX_SIZE       0
+#define DEFAULT_ACCEPTMBOX_SIZE         0*/
+#define LWIP_NETCONN                    1
+#define LWIP_TCPIP_TIMEOUT              0
+#define LWIP_NETCONN_SEM_PER_THREAD     0
+#define LWIP_NETCONN_FULLDUPLEX         0
+#define LWIP_SOCKET                     1
+#define LWIP_COMPAT_SOCKETS             1 /* 0..2 */
+#define LWIP_POSIX_SOCKETS_IO_NAMES     1
+#define LWIP_SOCKET_OFFSET              0
+#define LWIP_TCP_KEEPALIVE              0
+#define LWIP_SO_SNDTIMEO                0
+#define LWIP_SO_RCVTIMEO                0
+#define LWIP_SO_SNDRCVTIMEO_NONSTANDARD 0
+#define LWIP_SO_RCVBUF                  0
+#define LWIP_SO_LINGER                  0
+#define RECV_BUFSIZE_DEFAULT            INT_MAX
+#define LWIP_TCP_CLOSE_TIMEOUT_MS_DEFAULT 20000
+#define SO_REUSE                        0
+#define SO_REUSE_RXTOALL                0
+#define LWIP_FIONREAD_LINUXMODE         0
+#define LWIP_SOCKET_SELECT              1
+#define LWIP_SOCKET_POLL                1
+#define LWIP_STATS                      1
+#define LWIP_STATS_DISPLAY              0
+#define LINK_STATS                      1
+#define ETHARP_STATS                    (LWIP_ARP)
+#define IP_STATS                        1
+#define IPFRAG_STATS                    (IP_REASSEMBLY || IP_FRAG)
+#define ICMP_STATS                      1
+#define IGMP_STATS                      (LWIP_IGMP)
+#define UDP_STATS                       (LWIP_UDP)
+#define TCP_STATS                       (LWIP_TCP)
+#define MEM_STATS                       ((MEM_LIBC_MALLOC == 0) && (MEM_USE_POOLS == 0))
+#define MEMP_STATS                      (MEMP_MEM_MALLOC == 0)
+#define SYS_STATS                       (NO_SYS == 0)
+#define IP6_STATS                       (LWIP_IPV6)
+#define ICMP6_STATS                     (LWIP_IPV6 && LWIP_ICMP6)
+#define IP6_FRAG_STATS                  (LWIP_IPV6 && (LWIP_IPV6_FRAG || LWIP_IPV6_REASS))
+#define MLD6_STATS                      (LWIP_IPV6 && LWIP_IPV6_MLD)
+#define ND6_STATS                       (LWIP_IPV6)
+#define MIB2_STATS                      0
+#define LWIP_CHECKSUM_CTRL_PER_NETIF    0
+#define CHECKSUM_GEN_IP                 1
+#define CHECKSUM_GEN_UDP                1
+#define CHECKSUM_GEN_TCP                1
+#define CHECKSUM_GEN_ICMP               1
+#define CHECKSUM_GEN_ICMP6              1
+#define CHECKSUM_CHECK_IP               1
+#define CHECKSUM_CHECK_UDP              1
+#define CHECKSUM_CHECK_TCP              1
+#define CHECKSUM_CHECK_ICMP             1
+#define CHECKSUM_CHECK_ICMP6            1
+#define LWIP_CHECKSUM_ON_COPY           0
+#define LWIP_IPV6                       0
+#define IPV6_REASS_MAXAGE               60
+#define LWIP_IPV6_SCOPES                (LWIP_IPV6 && !LWIP_SINGLE_NETIF)
+#define LWIP_IPV6_SCOPES_DEBUG          0
+#define LWIP_IPV6_NUM_ADDRESSES         3
+#define LWIP_IPV6_FORWARD               0
+#define LWIP_IPV6_FRAG                  1
+#define LWIP_IPV6_REASS                 (LWIP_IPV6)
+#define LWIP_IPV6_SEND_ROUTER_SOLICIT   1
+#define LWIP_IPV6_AUTOCONFIG            (LWIP_IPV6)
+#define LWIP_IPV6_ADDRESS_LIFETIMES     (LWIP_IPV6_AUTOCONFIG)
+#define LWIP_IPV6_DUP_DETECT_ATTEMPTS   1
+#define LWIP_ICMP6                      (LWIP_IPV6)
+#define LWIP_ICMP6_DATASIZE             8
+#define LWIP_ICMP6_HL                   255
+#define LWIP_IPV6_MLD                   (LWIP_IPV6)
+#define MEMP_NUM_MLD6_GROUP             4
+#define LWIP_ND6_QUEUEING               (LWIP_IPV6)
+#define MEMP_NUM_ND6_QUEUE              20
+#define LWIP_ND6_NUM_NEIGHBORS          10
+#define LWIP_ND6_NUM_DESTINATIONS       10
+#define LWIP_ND6_NUM_PREFIXES           5
+#define LWIP_ND6_NUM_ROUTERS            3
+#define LWIP_ND6_MAX_MULTICAST_SOLICIT  3
+#define LWIP_ND6_MAX_UNICAST_SOLICIT    3
+#define LWIP_ND6_MAX_ANYCAST_DELAY_TIME 1000
+#define LWIP_ND6_MAX_NEIGHBOR_ADVERTISEMENT  3
+#define LWIP_ND6_REACHABLE_TIME         30000
+#define LWIP_ND6_RETRANS_TIMER          1000
+#define LWIP_ND6_DELAY_FIRST_PROBE_TIME 5000
+#define LWIP_ND6_ALLOW_RA_UPDATES       1
+#define LWIP_ND6_TCP_REACHABILITY_HINTS 1
+#define LWIP_ND6_RDNSS_MAX_DNS_SERVERS  0
+#define LWIP_IPV6_DHCP6                 0
+#define LWIP_IPV6_DHCP6_STATEFUL        0
+#define LWIP_IPV6_DHCP6_STATELESS       LWIP_IPV6_DHCP6
+#define LWIP_DHCP6_GET_NTP_SRV          0
+#define LWIP_DHCP6_MAX_NTP_SERVERS      1
+#define LWIP_DHCP6_MAX_DNS_SERVERS      DNS_MAX_SERVERS
+
+/* TODO: check hooks */
+
+#define LWIP_DBG_MIN_LEVEL              LWIP_DBG_LEVEL_ALL
+#define LWIP_DBG_TYPES_ON               LWIP_DBG_ON
+#define ETHARP_DEBUG                    LWIP_DBG_OFF
+#define NETIF_DEBUG                     LWIP_DBG_OFF
+#define PBUF_DEBUG                      LWIP_DBG_OFF
+#define API_LIB_DEBUG                   LWIP_DBG_OFF
+#define API_MSG_DEBUG                   LWIP_DBG_OFF
+#define SOCKETS_DEBUG                   LWIP_DBG_OFF
+#define ICMP_DEBUG                      LWIP_DBG_OFF
+#define IGMP_DEBUG                      LWIP_DBG_OFF
+#define INET_DEBUG                      LWIP_DBG_OFF
+#define IP_DEBUG                        LWIP_DBG_OFF
+#define IP_REASS_DEBUG                  LWIP_DBG_OFF
+#define RAW_DEBUG                       LWIP_DBG_OFF
+#define MEM_DEBUG                       LWIP_DBG_OFF
+#define MEMP_DEBUG                      LWIP_DBG_OFF
+#define SYS_DEBUG                       LWIP_DBG_OFF
+#define TIMERS_DEBUG                    LWIP_DBG_OFF
+#define TCP_DEBUG                       LWIP_DBG_OFF
+#define TCP_INPUT_DEBUG                 LWIP_DBG_OFF
+#define TCP_FR_DEBUG                    LWIP_DBG_OFF
+#define TCP_RTO_DEBUG                   LWIP_DBG_OFF
+#define TCP_CWND_DEBUG                  LWIP_DBG_OFF
+#define TCP_WND_DEBUG                   LWIP_DBG_OFF
+#define TCP_OUTPUT_DEBUG                LWIP_DBG_OFF
+#define TCP_RST_DEBUG                   LWIP_DBG_OFF
+#define TCP_QLEN_DEBUG                  LWIP_DBG_OFF
+#define UDP_DEBUG                       LWIP_DBG_OFF
+#define TCPIP_DEBUG                     LWIP_DBG_OFF
+#define SLIP_DEBUG                      LWIP_DBG_OFF
+#define DHCP_DEBUG                      LWIP_DBG_OFF
+#define AUTOIP_DEBUG                    LWIP_DBG_OFF
+#define DNS_DEBUG                       LWIP_DBG_OFF
+#define IP6_DEBUG                       LWIP_DBG_OFF
+#define DHCP6_DEBUG                     LWIP_DBG_OFF
+#define LWIP_TESTMODE                   0
+
+#define LWIP_PERF                       0
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/examples/example_app/test_configs/opt_ipv6only.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/examples/example_app/test_configs/opt_ipv6only.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/examples/example_app/test_configs/opt_ipv6only.h	(revision 457)
@@ -0,0 +1,296 @@
+/* test an lwipopts.h file with default contents */
+#define NO_SYS                          0
+#define NO_SYS_NO_TIMERS                0
+#define LWIP_TIMERS                     1
+#define LWIP_TIMERS_CUSTOM              0
+#define LWIP_MPU_COMPATIBLE             0
+#define LWIP_TCPIP_CORE_LOCKING         1
+#define LWIP_TCPIP_CORE_LOCKING_INPUT   0
+#define SYS_LIGHTWEIGHT_PROT            1
+#define MEM_LIBC_MALLOC                 0
+#define MEMP_MEM_MALLOC                 0
+#define MEMP_MEM_INIT                   0
+#define MEM_ALIGNMENT                   1
+#define MEM_SIZE                        1600
+#define MEMP_OVERFLOW_CHECK             0
+#define MEMP_SANITY_CHECK               0
+#define MEM_OVERFLOW_CHECK              0
+#define MEM_SANITY_CHECK                0
+#define MEM_USE_POOLS                   0
+#define MEM_USE_POOLS_TRY_BIGGER_POOL   0
+#define MEMP_USE_CUSTOM_POOLS           0
+#define LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT 0
+/*#define MEMP_NUM_PBUF                   16
+#define MEMP_NUM_RAW_PCB                4
+#define MEMP_NUM_UDP_PCB                4
+#define MEMP_NUM_TCP_PCB                5
+#define MEMP_NUM_TCP_PCB_LISTEN         8
+#define MEMP_NUM_TCP_SEG                16
+#define MEMP_NUM_ALTCP_PCB              MEMP_NUM_TCP_PCB
+#define MEMP_NUM_REASSDATA              5
+#define MEMP_NUM_FRAG_PBUF              15
+#define MEMP_NUM_ARP_QUEUE              30
+#define MEMP_NUM_IGMP_GROUP             8
+#define MEMP_NUM_SYS_TIMEOUT            (LWIP_NUM_SYS_TIMEOUT_INTERNAL + 2)
+#define MEMP_NUM_NETBUF                 2
+#define MEMP_NUM_NETCONN                4
+#define MEMP_NUM_SELECT_CB              4
+#define MEMP_NUM_TCPIP_MSG_API          8
+#define MEMP_NUM_TCPIP_MSG_INPKT        8
+#define MEMP_NUM_NETDB                  1
+#define MEMP_NUM_LOCALHOSTLIST          1
+#define PBUF_POOL_SIZE                  16
+#define MEMP_NUM_API_MSG                MEMP_NUM_TCPIP_MSG_API
+#define MEMP_NUM_DNS_API_MSG            MEMP_NUM_TCPIP_MSG_API
+#define MEMP_NUM_SOCKET_SETGETSOCKOPT_DATA MEMP_NUM_TCPIP_MSG_API
+#define MEMP_NUM_NETIFAPI_MSG           MEMP_NUM_TCPIP_MSG_API*/
+#define LWIP_ARP                        1
+#define ARP_TABLE_SIZE                  10
+#define ARP_MAXAGE                      300
+#define ARP_QUEUEING                    0
+#define ARP_QUEUE_LEN                   3
+#define ETHARP_SUPPORT_VLAN             0
+#define LWIP_ETHERNET                   LWIP_ARP
+#define ETH_PAD_SIZE                    0
+#define ETHARP_SUPPORT_STATIC_ENTRIES   0
+#define ETHARP_TABLE_MATCH_NETIF        !LWIP_SINGLE_NETIF
+#define LWIP_IPV4                       0
+#define IP_FORWARD                      0
+#define IP_REASSEMBLY                   1
+#define IP_FRAG                         1
+#define IP_OPTIONS_ALLOWED              1
+#define IP_REASS_MAXAGE                 15
+#define IP_REASS_MAX_PBUFS              10
+#define IP_DEFAULT_TTL                  255
+#define IP_SOF_BROADCAST                0
+#define IP_SOF_BROADCAST_RECV           0
+#define IP_FORWARD_ALLOW_TX_ON_RX_NETIF 0
+#define LWIP_ICMP                       1
+#define ICMP_TTL                        (IP_DEFAULT_TTL)
+#define LWIP_BROADCAST_PING             0
+#define LWIP_MULTICAST_PING             0
+#define LWIP_RAW                        0
+#define RAW_TTL                         (IP_DEFAULT_TTL)
+#define LWIP_DHCP                       0
+#define DHCP_DOES_ARP_CHECK             ((LWIP_DHCP) && (LWIP_ARP))
+#define LWIP_DHCP_CHECK_LINK_UP         0
+#define LWIP_DHCP_BOOTP_FILE            0
+#define LWIP_DHCP_GET_NTP_SRV           0
+#define LWIP_DHCP_MAX_NTP_SERVERS       1
+#define LWIP_DHCP_MAX_DNS_SERVERS       DNS_MAX_SERVERS
+#define LWIP_AUTOIP                     0
+#define LWIP_DHCP_AUTOIP_COOP           0
+#define LWIP_DHCP_AUTOIP_COOP_TRIES     9
+#define LWIP_MIB2_CALLBACKS             0
+#define LWIP_MULTICAST_TX_OPTIONS       ((LWIP_IGMP || LWIP_IPV6_MLD) && (LWIP_UDP || LWIP_RAW))
+#define LWIP_IGMP                       0
+#define LWIP_DNS                        0
+#define DNS_TABLE_SIZE                  4
+#define DNS_MAX_NAME_LENGTH             256
+#define DNS_MAX_SERVERS                 2
+#define DNS_MAX_RETRIES                 4
+#define DNS_DOES_NAME_CHECK             1
+#define LWIP_DNS_SECURE (LWIP_DNS_SECURE_RAND_XID | LWIP_DNS_SECURE_NO_MULTIPLE_OUTSTANDING | LWIP_DNS_SECURE_RAND_SRC_PORT)
+#define DNS_LOCAL_HOSTLIST              0
+#define DNS_LOCAL_HOSTLIST_IS_DYNAMIC   0
+#define LWIP_DNS_SUPPORT_MDNS_QUERIES   0
+#define LWIP_UDP                        1
+#define LWIP_UDPLITE                    0
+#define UDP_TTL                         (IP_DEFAULT_TTL)
+#define LWIP_NETBUF_RECVINFO            0
+#define LWIP_TCP                        1
+#define TCP_TTL                         (IP_DEFAULT_TTL)
+#define TCP_WND                         (4 * TCP_MSS)
+#define TCP_MAXRTX                      12
+#define TCP_SYNMAXRTX                   6
+#define TCP_QUEUE_OOSEQ                 (LWIP_TCP)
+#define LWIP_TCP_SACK_OUT               0
+#define LWIP_TCP_MAX_SACK_NUM           4
+#define TCP_MSS                         536
+#define TCP_CALCULATE_EFF_SEND_MSS      1
+#define TCP_SND_BUF                     (2 * TCP_MSS)
+#define TCP_SND_QUEUELEN                ((4 * (TCP_SND_BUF) + (TCP_MSS - 1))/(TCP_MSS))
+#define TCP_SNDLOWAT                    LWIP_MIN(LWIP_MAX(((TCP_SND_BUF)/2), (2 * TCP_MSS) + 1), (TCP_SND_BUF) - 1)
+#define TCP_SNDQUEUELOWAT               LWIP_MAX(((TCP_SND_QUEUELEN)/2), 5)
+#define TCP_OOSEQ_MAX_BYTES             0
+#define TCP_OOSEQ_BYTES_LIMIT(pcb)      TCP_OOSEQ_MAX_BYTES
+#define TCP_OOSEQ_MAX_PBUFS             0
+#define TCP_OOSEQ_PBUFS_LIMIT(pcb)      TCP_OOSEQ_MAX_PBUFS
+#define TCP_LISTEN_BACKLOG              0
+#define TCP_DEFAULT_LISTEN_BACKLOG      0xff
+#define TCP_OVERSIZE                    TCP_MSS
+#define LWIP_TCP_TIMESTAMPS             0
+#define TCP_WND_UPDATE_THRESHOLD        LWIP_MIN((TCP_WND / 4), (TCP_MSS * 4))
+#define LWIP_EVENT_API                  0
+#define LWIP_CALLBACK_API               1
+#define LWIP_WND_SCALE                  0
+#define TCP_RCV_SCALE                   0
+#define LWIP_TCP_PCB_NUM_EXT_ARGS       0
+#define LWIP_ALTCP                      0
+#define LWIP_ALTCP_TLS                  0
+#define PBUF_LINK_HLEN                  (14 + ETH_PAD_SIZE)
+#define PBUF_LINK_ENCAPSULATION_HLEN    0
+#define PBUF_POOL_BUFSIZE               LWIP_MEM_ALIGN_SIZE(TCP_MSS+40+PBUF_LINK_ENCAPSULATION_HLEN+PBUF_LINK_HLEN)
+#define LWIP_PBUF_REF_T                 u8_t
+#define LWIP_SINGLE_NETIF               0
+#define LWIP_NETIF_HOSTNAME             0
+#define LWIP_NETIF_API                  0
+#define LWIP_NETIF_STATUS_CALLBACK      0
+#define LWIP_NETIF_EXT_STATUS_CALLBACK  0
+#define LWIP_NETIF_LINK_CALLBACK        0
+#define LWIP_NETIF_REMOVE_CALLBACK      0
+#define LWIP_NETIF_HWADDRHINT           0
+#define LWIP_NETIF_TX_SINGLE_PBUF       0
+#define LWIP_NUM_NETIF_CLIENT_DATA      0
+#define LWIP_HAVE_LOOPIF                (LWIP_NETIF_LOOPBACK && !LWIP_SINGLE_NETIF)
+#define LWIP_LOOPIF_MULTICAST           0
+#define LWIP_NETIF_LOOPBACK             0
+#define LWIP_LOOPBACK_MAX_PBUFS         0
+#define LWIP_NETIF_LOOPBACK_MULTITHREADING    (!NO_SYS)
+/*#define TCPIP_THREAD_NAME               "tcpip_thread"
+#define TCPIP_THREAD_STACKSIZE          0
+#define TCPIP_THREAD_PRIO               1
+#define TCPIP_MBOX_SIZE                 0
+#define LWIP_TCPIP_THREAD_ALIVE()
+#define SLIPIF_THREAD_NAME              "slipif_loop"
+#define SLIPIF_THREAD_STACKSIZE         0
+#define SLIPIF_THREAD_PRIO              1
+#define DEFAULT_THREAD_NAME             "lwIP"
+#define DEFAULT_THREAD_STACKSIZE        0
+#define DEFAULT_THREAD_PRIO             1
+#define DEFAULT_RAW_RECVMBOX_SIZE       0
+#define DEFAULT_UDP_RECVMBOX_SIZE       0
+#define DEFAULT_TCP_RECVMBOX_SIZE       0
+#define DEFAULT_ACCEPTMBOX_SIZE         0*/
+#define LWIP_NETCONN                    1
+#define LWIP_TCPIP_TIMEOUT              0
+#define LWIP_NETCONN_SEM_PER_THREAD     0
+#define LWIP_NETCONN_FULLDUPLEX         0
+#define LWIP_SOCKET                     1
+#define LWIP_COMPAT_SOCKETS             1 /* 0..2 */
+#define LWIP_POSIX_SOCKETS_IO_NAMES     1
+#define LWIP_SOCKET_OFFSET              0
+#define LWIP_TCP_KEEPALIVE              0
+#define LWIP_SO_SNDTIMEO                0
+#define LWIP_SO_RCVTIMEO                0
+#define LWIP_SO_SNDRCVTIMEO_NONSTANDARD 0
+#define LWIP_SO_RCVBUF                  0
+#define LWIP_SO_LINGER                  0
+#define RECV_BUFSIZE_DEFAULT            INT_MAX
+#define LWIP_TCP_CLOSE_TIMEOUT_MS_DEFAULT 20000
+#define SO_REUSE                        0
+#define SO_REUSE_RXTOALL                0
+#define LWIP_FIONREAD_LINUXMODE         0
+#define LWIP_SOCKET_SELECT              1
+#define LWIP_SOCKET_POLL                1
+#define LWIP_STATS                      1
+#define LWIP_STATS_DISPLAY              0
+#define LINK_STATS                      1
+#define ETHARP_STATS                    (LWIP_ARP)
+#define IP_STATS                        1
+#define IPFRAG_STATS                    (IP_REASSEMBLY || IP_FRAG)
+#define ICMP_STATS                      1
+#define IGMP_STATS                      (LWIP_IGMP)
+#define UDP_STATS                       (LWIP_UDP)
+#define TCP_STATS                       (LWIP_TCP)
+#define MEM_STATS                       ((MEM_LIBC_MALLOC == 0) && (MEM_USE_POOLS == 0))
+#define MEMP_STATS                      (MEMP_MEM_MALLOC == 0)
+#define SYS_STATS                       (NO_SYS == 0)
+#define IP6_STATS                       (LWIP_IPV6)
+#define ICMP6_STATS                     (LWIP_IPV6 && LWIP_ICMP6)
+#define IP6_FRAG_STATS                  (LWIP_IPV6 && (LWIP_IPV6_FRAG || LWIP_IPV6_REASS))
+#define MLD6_STATS                      (LWIP_IPV6 && LWIP_IPV6_MLD)
+#define ND6_STATS                       (LWIP_IPV6)
+#define MIB2_STATS                      0
+#define LWIP_CHECKSUM_CTRL_PER_NETIF    0
+#define CHECKSUM_GEN_IP                 1
+#define CHECKSUM_GEN_UDP                1
+#define CHECKSUM_GEN_TCP                1
+#define CHECKSUM_GEN_ICMP               1
+#define CHECKSUM_GEN_ICMP6              1
+#define CHECKSUM_CHECK_IP               1
+#define CHECKSUM_CHECK_UDP              1
+#define CHECKSUM_CHECK_TCP              1
+#define CHECKSUM_CHECK_ICMP             1
+#define CHECKSUM_CHECK_ICMP6            1
+#define LWIP_CHECKSUM_ON_COPY           0
+#define LWIP_IPV6                       1
+#define IPV6_REASS_MAXAGE               60
+#define LWIP_IPV6_SCOPES                (LWIP_IPV6 && !LWIP_SINGLE_NETIF)
+#define LWIP_IPV6_SCOPES_DEBUG          0
+#define LWIP_IPV6_NUM_ADDRESSES         3
+#define LWIP_IPV6_FORWARD               0
+#define LWIP_IPV6_FRAG                  1
+#define LWIP_IPV6_REASS                 (LWIP_IPV6)
+#define LWIP_IPV6_SEND_ROUTER_SOLICIT   1
+#define LWIP_IPV6_AUTOCONFIG            (LWIP_IPV6)
+#define LWIP_IPV6_ADDRESS_LIFETIMES     (LWIP_IPV6_AUTOCONFIG)
+#define LWIP_IPV6_DUP_DETECT_ATTEMPTS   1
+#define LWIP_ICMP6                      (LWIP_IPV6)
+#define LWIP_ICMP6_DATASIZE             8
+#define LWIP_ICMP6_HL                   255
+#define LWIP_IPV6_MLD                   (LWIP_IPV6)
+#define MEMP_NUM_MLD6_GROUP             4
+#define LWIP_ND6_QUEUEING               (LWIP_IPV6)
+#define MEMP_NUM_ND6_QUEUE              20
+#define LWIP_ND6_NUM_NEIGHBORS          10
+#define LWIP_ND6_NUM_DESTINATIONS       10
+#define LWIP_ND6_NUM_PREFIXES           5
+#define LWIP_ND6_NUM_ROUTERS            3
+#define LWIP_ND6_MAX_MULTICAST_SOLICIT  3
+#define LWIP_ND6_MAX_UNICAST_SOLICIT    3
+#define LWIP_ND6_MAX_ANYCAST_DELAY_TIME 1000
+#define LWIP_ND6_MAX_NEIGHBOR_ADVERTISEMENT  3
+#define LWIP_ND6_REACHABLE_TIME         30000
+#define LWIP_ND6_RETRANS_TIMER          1000
+#define LWIP_ND6_DELAY_FIRST_PROBE_TIME 5000
+#define LWIP_ND6_ALLOW_RA_UPDATES       1
+#define LWIP_ND6_TCP_REACHABILITY_HINTS 1
+#define LWIP_ND6_RDNSS_MAX_DNS_SERVERS  0
+#define LWIP_IPV6_DHCP6                 0
+#define LWIP_IPV6_DHCP6_STATEFUL        0
+#define LWIP_IPV6_DHCP6_STATELESS       LWIP_IPV6_DHCP6
+#define LWIP_DHCP6_GET_NTP_SRV          0
+#define LWIP_DHCP6_MAX_NTP_SERVERS      1
+#define LWIP_DHCP6_MAX_DNS_SERVERS      DNS_MAX_SERVERS
+
+/* TODO: check hooks */
+
+#define LWIP_DBG_MIN_LEVEL              LWIP_DBG_LEVEL_ALL
+#define LWIP_DBG_TYPES_ON               LWIP_DBG_ON
+#define ETHARP_DEBUG                    LWIP_DBG_OFF
+#define NETIF_DEBUG                     LWIP_DBG_OFF
+#define PBUF_DEBUG                      LWIP_DBG_OFF
+#define API_LIB_DEBUG                   LWIP_DBG_OFF
+#define API_MSG_DEBUG                   LWIP_DBG_OFF
+#define SOCKETS_DEBUG                   LWIP_DBG_OFF
+#define ICMP_DEBUG                      LWIP_DBG_OFF
+#define IGMP_DEBUG                      LWIP_DBG_OFF
+#define INET_DEBUG                      LWIP_DBG_OFF
+#define IP_DEBUG                        LWIP_DBG_OFF
+#define IP_REASS_DEBUG                  LWIP_DBG_OFF
+#define RAW_DEBUG                       LWIP_DBG_OFF
+#define MEM_DEBUG                       LWIP_DBG_OFF
+#define MEMP_DEBUG                      LWIP_DBG_OFF
+#define SYS_DEBUG                       LWIP_DBG_OFF
+#define TIMERS_DEBUG                    LWIP_DBG_OFF
+#define TCP_DEBUG                       LWIP_DBG_OFF
+#define TCP_INPUT_DEBUG                 LWIP_DBG_OFF
+#define TCP_FR_DEBUG                    LWIP_DBG_OFF
+#define TCP_RTO_DEBUG                   LWIP_DBG_OFF
+#define TCP_CWND_DEBUG                  LWIP_DBG_OFF
+#define TCP_WND_DEBUG                   LWIP_DBG_OFF
+#define TCP_OUTPUT_DEBUG                LWIP_DBG_OFF
+#define TCP_RST_DEBUG                   LWIP_DBG_OFF
+#define TCP_QLEN_DEBUG                  LWIP_DBG_OFF
+#define UDP_DEBUG                       LWIP_DBG_OFF
+#define TCPIP_DEBUG                     LWIP_DBG_OFF
+#define SLIP_DEBUG                      LWIP_DBG_OFF
+#define DHCP_DEBUG                      LWIP_DBG_OFF
+#define AUTOIP_DEBUG                    LWIP_DBG_OFF
+#define DNS_DEBUG                       LWIP_DBG_OFF
+#define IP6_DEBUG                       LWIP_DBG_OFF
+#define DHCP6_DEBUG                     LWIP_DBG_OFF
+#define LWIP_TESTMODE                   0
+
+#define LWIP_PERF                       0
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/examples/example_app/test_configs/opt_no_tcp_dualstack.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/examples/example_app/test_configs/opt_no_tcp_dualstack.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/examples/example_app/test_configs/opt_no_tcp_dualstack.h	(revision 457)
@@ -0,0 +1,4 @@
+#include "test_configs/opt_dualstack.h"
+
+#undef LWIP_TCP
+#define LWIP_TCP 0
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/examples/example_app/test_configs/opt_no_tcp_ipv4only.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/examples/example_app/test_configs/opt_no_tcp_ipv4only.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/examples/example_app/test_configs/opt_no_tcp_ipv4only.h	(revision 457)
@@ -0,0 +1,4 @@
+#include "test_configs/opt_ipv4only.h"
+
+#undef LWIP_TCP
+#define LWIP_TCP 0
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/examples/example_app/test_configs/opt_no_tcp_ipv6only.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/examples/example_app/test_configs/opt_no_tcp_ipv6only.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/examples/example_app/test_configs/opt_no_tcp_ipv6only.h	(revision 457)
@@ -0,0 +1,4 @@
+#include "test_configs/opt_ipv6only.h"
+
+#undef LWIP_TCP
+#define LWIP_TCP 0
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/examples/example_app/test_configs/opt_no_udp_dualstack.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/examples/example_app/test_configs/opt_no_udp_dualstack.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/examples/example_app/test_configs/opt_no_udp_dualstack.h	(revision 457)
@@ -0,0 +1,4 @@
+#include "test_configs/opt_dualstack.h"
+
+#undef LWIP_UDP
+#define LWIP_UDP 0
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/examples/example_app/test_configs/opt_no_udp_ipv4only.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/examples/example_app/test_configs/opt_no_udp_ipv4only.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/examples/example_app/test_configs/opt_no_udp_ipv4only.h	(revision 457)
@@ -0,0 +1,4 @@
+#include "test_configs/opt_ipv4only.h"
+
+#undef LWIP_UDP
+#define LWIP_UDP 0
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/examples/example_app/test_configs/opt_no_udp_ipv6only.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/examples/example_app/test_configs/opt_no_udp_ipv6only.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/examples/example_app/test_configs/opt_no_udp_ipv6only.h	(revision 457)
@@ -0,0 +1,4 @@
+#include "test_configs/opt_ipv6only.h"
+
+#undef LWIP_UDP
+#define LWIP_UDP 0
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/examples/example_app/test_configs/opt_none.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/examples/example_app/test_configs/opt_none.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/examples/example_app/test_configs/opt_none.h	(revision 457)
@@ -0,0 +1,2 @@
+/* test and empty lwipopts.h file */
+
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/examples/example_app/test_configs/opt_nosys_dual.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/examples/example_app/test_configs/opt_nosys_dual.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/examples/example_app/test_configs/opt_nosys_dual.h	(revision 457)
@@ -0,0 +1,296 @@
+/* test an lwipopts.h file with default contents */
+#define NO_SYS                          0
+#define NO_SYS_NO_TIMERS                0
+#define LWIP_TIMERS                     1
+#define LWIP_TIMERS_CUSTOM              0
+#define LWIP_MPU_COMPATIBLE             0
+#define LWIP_TCPIP_CORE_LOCKING         1
+#define LWIP_TCPIP_CORE_LOCKING_INPUT   0
+#define SYS_LIGHTWEIGHT_PROT            1
+#define MEM_LIBC_MALLOC                 0
+#define MEMP_MEM_MALLOC                 0
+#define MEMP_MEM_INIT                   0
+#define MEM_ALIGNMENT                   1
+#define MEM_SIZE                        1600
+#define MEMP_OVERFLOW_CHECK             0
+#define MEMP_SANITY_CHECK               0
+#define MEM_OVERFLOW_CHECK              0
+#define MEM_SANITY_CHECK                0
+#define MEM_USE_POOLS                   0
+#define MEM_USE_POOLS_TRY_BIGGER_POOL   0
+#define MEMP_USE_CUSTOM_POOLS           0
+#define LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT 0
+/*#define MEMP_NUM_PBUF                   16
+#define MEMP_NUM_RAW_PCB                4
+#define MEMP_NUM_UDP_PCB                4
+#define MEMP_NUM_TCP_PCB                5
+#define MEMP_NUM_TCP_PCB_LISTEN         8
+#define MEMP_NUM_TCP_SEG                16
+#define MEMP_NUM_ALTCP_PCB              MEMP_NUM_TCP_PCB
+#define MEMP_NUM_REASSDATA              5
+#define MEMP_NUM_FRAG_PBUF              15
+#define MEMP_NUM_ARP_QUEUE              30
+#define MEMP_NUM_IGMP_GROUP             8
+#define MEMP_NUM_SYS_TIMEOUT            (LWIP_NUM_SYS_TIMEOUT_INTERNAL + 2)
+#define MEMP_NUM_NETBUF                 2
+#define MEMP_NUM_NETCONN                4
+#define MEMP_NUM_SELECT_CB              4
+#define MEMP_NUM_TCPIP_MSG_API          8
+#define MEMP_NUM_TCPIP_MSG_INPKT        8
+#define MEMP_NUM_NETDB                  1
+#define MEMP_NUM_LOCALHOSTLIST          1
+#define PBUF_POOL_SIZE                  16
+#define MEMP_NUM_API_MSG                MEMP_NUM_TCPIP_MSG_API
+#define MEMP_NUM_DNS_API_MSG            MEMP_NUM_TCPIP_MSG_API
+#define MEMP_NUM_SOCKET_SETGETSOCKOPT_DATA MEMP_NUM_TCPIP_MSG_API
+#define MEMP_NUM_NETIFAPI_MSG           MEMP_NUM_TCPIP_MSG_API*/
+#define LWIP_ARP                        1
+#define ARP_TABLE_SIZE                  10
+#define ARP_MAXAGE                      300
+#define ARP_QUEUEING                    0
+#define ARP_QUEUE_LEN                   3
+#define ETHARP_SUPPORT_VLAN             0
+#define LWIP_ETHERNET                   LWIP_ARP
+#define ETH_PAD_SIZE                    0
+#define ETHARP_SUPPORT_STATIC_ENTRIES   0
+#define ETHARP_TABLE_MATCH_NETIF        !LWIP_SINGLE_NETIF
+#define LWIP_IPV4                       1
+#define IP_FORWARD                      0
+#define IP_REASSEMBLY                   1
+#define IP_FRAG                         1
+#define IP_OPTIONS_ALLOWED              1
+#define IP_REASS_MAXAGE                 15
+#define IP_REASS_MAX_PBUFS              10
+#define IP_DEFAULT_TTL                  255
+#define IP_SOF_BROADCAST                0
+#define IP_SOF_BROADCAST_RECV           0
+#define IP_FORWARD_ALLOW_TX_ON_RX_NETIF 0
+#define LWIP_ICMP                       1
+#define ICMP_TTL                        (IP_DEFAULT_TTL)
+#define LWIP_BROADCAST_PING             0
+#define LWIP_MULTICAST_PING             0
+#define LWIP_RAW                        0
+#define RAW_TTL                         (IP_DEFAULT_TTL)
+#define LWIP_DHCP                       0
+#define DHCP_DOES_ARP_CHECK             ((LWIP_DHCP) && (LWIP_ARP))
+#define LWIP_DHCP_CHECK_LINK_UP         0
+#define LWIP_DHCP_BOOTP_FILE            0
+#define LWIP_DHCP_GET_NTP_SRV           0
+#define LWIP_DHCP_MAX_NTP_SERVERS       1
+#define LWIP_DHCP_MAX_DNS_SERVERS       DNS_MAX_SERVERS
+#define LWIP_AUTOIP                     0
+#define LWIP_DHCP_AUTOIP_COOP           0
+#define LWIP_DHCP_AUTOIP_COOP_TRIES     9
+#define LWIP_MIB2_CALLBACKS             0
+#define LWIP_MULTICAST_TX_OPTIONS       ((LWIP_IGMP || LWIP_IPV6_MLD) && (LWIP_UDP || LWIP_RAW))
+#define LWIP_IGMP                       0
+#define LWIP_DNS                        0
+#define DNS_TABLE_SIZE                  4
+#define DNS_MAX_NAME_LENGTH             256
+#define DNS_MAX_SERVERS                 2
+#define DNS_MAX_RETRIES                 4
+#define DNS_DOES_NAME_CHECK             1
+#define LWIP_DNS_SECURE (LWIP_DNS_SECURE_RAND_XID | LWIP_DNS_SECURE_NO_MULTIPLE_OUTSTANDING | LWIP_DNS_SECURE_RAND_SRC_PORT)
+#define DNS_LOCAL_HOSTLIST              0
+#define DNS_LOCAL_HOSTLIST_IS_DYNAMIC   0
+#define LWIP_DNS_SUPPORT_MDNS_QUERIES   0
+#define LWIP_UDP                        1
+#define LWIP_UDPLITE                    0
+#define UDP_TTL                         (IP_DEFAULT_TTL)
+#define LWIP_NETBUF_RECVINFO            0
+#define LWIP_TCP                        1
+#define TCP_TTL                         (IP_DEFAULT_TTL)
+#define TCP_WND                         (4 * TCP_MSS)
+#define TCP_MAXRTX                      12
+#define TCP_SYNMAXRTX                   6
+#define TCP_QUEUE_OOSEQ                 (LWIP_TCP)
+#define LWIP_TCP_SACK_OUT               0
+#define LWIP_TCP_MAX_SACK_NUM           4
+#define TCP_MSS                         536
+#define TCP_CALCULATE_EFF_SEND_MSS      1
+#define TCP_SND_BUF                     (2 * TCP_MSS)
+#define TCP_SND_QUEUELEN                ((4 * (TCP_SND_BUF) + (TCP_MSS - 1))/(TCP_MSS))
+#define TCP_SNDLOWAT                    LWIP_MIN(LWIP_MAX(((TCP_SND_BUF)/2), (2 * TCP_MSS) + 1), (TCP_SND_BUF) - 1)
+#define TCP_SNDQUEUELOWAT               LWIP_MAX(((TCP_SND_QUEUELEN)/2), 5)
+#define TCP_OOSEQ_MAX_BYTES             0
+#define TCP_OOSEQ_BYTES_LIMIT(pcb)      TCP_OOSEQ_MAX_BYTES
+#define TCP_OOSEQ_MAX_PBUFS             0
+#define TCP_OOSEQ_PBUFS_LIMIT(pcb)      TCP_OOSEQ_MAX_PBUFS
+#define TCP_LISTEN_BACKLOG              0
+#define TCP_DEFAULT_LISTEN_BACKLOG      0xff
+#define TCP_OVERSIZE                    TCP_MSS
+#define LWIP_TCP_TIMESTAMPS             0
+#define TCP_WND_UPDATE_THRESHOLD        LWIP_MIN((TCP_WND / 4), (TCP_MSS * 4))
+#define LWIP_EVENT_API                  0
+#define LWIP_CALLBACK_API               1
+#define LWIP_WND_SCALE                  0
+#define TCP_RCV_SCALE                   0
+#define LWIP_TCP_PCB_NUM_EXT_ARGS       0
+#define LWIP_ALTCP                      0
+#define LWIP_ALTCP_TLS                  0
+#define PBUF_LINK_HLEN                  (14 + ETH_PAD_SIZE)
+#define PBUF_LINK_ENCAPSULATION_HLEN    0
+#define PBUF_POOL_BUFSIZE               LWIP_MEM_ALIGN_SIZE(TCP_MSS+40+PBUF_LINK_ENCAPSULATION_HLEN+PBUF_LINK_HLEN)
+#define LWIP_PBUF_REF_T                 u8_t
+#define LWIP_SINGLE_NETIF               0
+#define LWIP_NETIF_HOSTNAME             0
+#define LWIP_NETIF_API                  0
+#define LWIP_NETIF_STATUS_CALLBACK      0
+#define LWIP_NETIF_EXT_STATUS_CALLBACK  0
+#define LWIP_NETIF_LINK_CALLBACK        0
+#define LWIP_NETIF_REMOVE_CALLBACK      0
+#define LWIP_NETIF_HWADDRHINT           0
+#define LWIP_NETIF_TX_SINGLE_PBUF       0
+#define LWIP_NUM_NETIF_CLIENT_DATA      0
+#define LWIP_HAVE_LOOPIF                (LWIP_NETIF_LOOPBACK && !LWIP_SINGLE_NETIF)
+#define LWIP_LOOPIF_MULTICAST           0
+#define LWIP_NETIF_LOOPBACK             0
+#define LWIP_LOOPBACK_MAX_PBUFS         0
+#define LWIP_NETIF_LOOPBACK_MULTITHREADING    (!NO_SYS)
+/*#define TCPIP_THREAD_NAME               "tcpip_thread"
+#define TCPIP_THREAD_STACKSIZE          0
+#define TCPIP_THREAD_PRIO               1
+#define TCPIP_MBOX_SIZE                 0
+#define LWIP_TCPIP_THREAD_ALIVE()
+#define SLIPIF_THREAD_NAME              "slipif_loop"
+#define SLIPIF_THREAD_STACKSIZE         0
+#define SLIPIF_THREAD_PRIO              1
+#define DEFAULT_THREAD_NAME             "lwIP"
+#define DEFAULT_THREAD_STACKSIZE        0
+#define DEFAULT_THREAD_PRIO             1
+#define DEFAULT_RAW_RECVMBOX_SIZE       0
+#define DEFAULT_UDP_RECVMBOX_SIZE       0
+#define DEFAULT_TCP_RECVMBOX_SIZE       0
+#define DEFAULT_ACCEPTMBOX_SIZE         0*/
+#define LWIP_NETCONN                    0
+#define LWIP_TCPIP_TIMEOUT              0
+#define LWIP_NETCONN_SEM_PER_THREAD     0
+#define LWIP_NETCONN_FULLDUPLEX         0
+#define LWIP_SOCKET                     0
+#define LWIP_COMPAT_SOCKETS             1 /* 0..2 */
+#define LWIP_POSIX_SOCKETS_IO_NAMES     1
+#define LWIP_SOCKET_OFFSET              0
+#define LWIP_TCP_KEEPALIVE              0
+#define LWIP_SO_SNDTIMEO                0
+#define LWIP_SO_RCVTIMEO                0
+#define LWIP_SO_SNDRCVTIMEO_NONSTANDARD 0
+#define LWIP_SO_RCVBUF                  0
+#define LWIP_SO_LINGER                  0
+#define RECV_BUFSIZE_DEFAULT            INT_MAX
+#define LWIP_TCP_CLOSE_TIMEOUT_MS_DEFAULT 20000
+#define SO_REUSE                        0
+#define SO_REUSE_RXTOALL                0
+#define LWIP_FIONREAD_LINUXMODE         0
+#define LWIP_SOCKET_SELECT              1
+#define LWIP_SOCKET_POLL                1
+#define LWIP_STATS                      1
+#define LWIP_STATS_DISPLAY              0
+#define LINK_STATS                      1
+#define ETHARP_STATS                    (LWIP_ARP)
+#define IP_STATS                        1
+#define IPFRAG_STATS                    (IP_REASSEMBLY || IP_FRAG)
+#define ICMP_STATS                      1
+#define IGMP_STATS                      (LWIP_IGMP)
+#define UDP_STATS                       (LWIP_UDP)
+#define TCP_STATS                       (LWIP_TCP)
+#define MEM_STATS                       ((MEM_LIBC_MALLOC == 0) && (MEM_USE_POOLS == 0))
+#define MEMP_STATS                      (MEMP_MEM_MALLOC == 0)
+#define SYS_STATS                       (NO_SYS == 0)
+#define IP6_STATS                       (LWIP_IPV6)
+#define ICMP6_STATS                     (LWIP_IPV6 && LWIP_ICMP6)
+#define IP6_FRAG_STATS                  (LWIP_IPV6 && (LWIP_IPV6_FRAG || LWIP_IPV6_REASS))
+#define MLD6_STATS                      (LWIP_IPV6 && LWIP_IPV6_MLD)
+#define ND6_STATS                       (LWIP_IPV6)
+#define MIB2_STATS                      0
+#define LWIP_CHECKSUM_CTRL_PER_NETIF    0
+#define CHECKSUM_GEN_IP                 1
+#define CHECKSUM_GEN_UDP                1
+#define CHECKSUM_GEN_TCP                1
+#define CHECKSUM_GEN_ICMP               1
+#define CHECKSUM_GEN_ICMP6              1
+#define CHECKSUM_CHECK_IP               1
+#define CHECKSUM_CHECK_UDP              1
+#define CHECKSUM_CHECK_TCP              1
+#define CHECKSUM_CHECK_ICMP             1
+#define CHECKSUM_CHECK_ICMP6            1
+#define LWIP_CHECKSUM_ON_COPY           0
+#define LWIP_IPV6                       1
+#define IPV6_REASS_MAXAGE               60
+#define LWIP_IPV6_SCOPES                (LWIP_IPV6 && !LWIP_SINGLE_NETIF)
+#define LWIP_IPV6_SCOPES_DEBUG          0
+#define LWIP_IPV6_NUM_ADDRESSES         3
+#define LWIP_IPV6_FORWARD               0
+#define LWIP_IPV6_FRAG                  1
+#define LWIP_IPV6_REASS                 (LWIP_IPV6)
+#define LWIP_IPV6_SEND_ROUTER_SOLICIT   1
+#define LWIP_IPV6_AUTOCONFIG            (LWIP_IPV6)
+#define LWIP_IPV6_ADDRESS_LIFETIMES     (LWIP_IPV6_AUTOCONFIG)
+#define LWIP_IPV6_DUP_DETECT_ATTEMPTS   1
+#define LWIP_ICMP6                      (LWIP_IPV6)
+#define LWIP_ICMP6_DATASIZE             8
+#define LWIP_ICMP6_HL                   255
+#define LWIP_IPV6_MLD                   (LWIP_IPV6)
+#define MEMP_NUM_MLD6_GROUP             4
+#define LWIP_ND6_QUEUEING               (LWIP_IPV6)
+#define MEMP_NUM_ND6_QUEUE              20
+#define LWIP_ND6_NUM_NEIGHBORS          10
+#define LWIP_ND6_NUM_DESTINATIONS       10
+#define LWIP_ND6_NUM_PREFIXES           5
+#define LWIP_ND6_NUM_ROUTERS            3
+#define LWIP_ND6_MAX_MULTICAST_SOLICIT  3
+#define LWIP_ND6_MAX_UNICAST_SOLICIT    3
+#define LWIP_ND6_MAX_ANYCAST_DELAY_TIME 1000
+#define LWIP_ND6_MAX_NEIGHBOR_ADVERTISEMENT  3
+#define LWIP_ND6_REACHABLE_TIME         30000
+#define LWIP_ND6_RETRANS_TIMER          1000
+#define LWIP_ND6_DELAY_FIRST_PROBE_TIME 5000
+#define LWIP_ND6_ALLOW_RA_UPDATES       1
+#define LWIP_ND6_TCP_REACHABILITY_HINTS 1
+#define LWIP_ND6_RDNSS_MAX_DNS_SERVERS  0
+#define LWIP_IPV6_DHCP6                 0
+#define LWIP_IPV6_DHCP6_STATEFUL        0
+#define LWIP_IPV6_DHCP6_STATELESS       LWIP_IPV6_DHCP6
+#define LWIP_DHCP6_GET_NTP_SRV          0
+#define LWIP_DHCP6_MAX_NTP_SERVERS      1
+#define LWIP_DHCP6_MAX_DNS_SERVERS      DNS_MAX_SERVERS
+
+/* TODO: check hooks */
+
+#define LWIP_DBG_MIN_LEVEL              LWIP_DBG_LEVEL_ALL
+#define LWIP_DBG_TYPES_ON               LWIP_DBG_ON
+#define ETHARP_DEBUG                    LWIP_DBG_OFF
+#define NETIF_DEBUG                     LWIP_DBG_OFF
+#define PBUF_DEBUG                      LWIP_DBG_OFF
+#define API_LIB_DEBUG                   LWIP_DBG_OFF
+#define API_MSG_DEBUG                   LWIP_DBG_OFF
+#define SOCKETS_DEBUG                   LWIP_DBG_OFF
+#define ICMP_DEBUG                      LWIP_DBG_OFF
+#define IGMP_DEBUG                      LWIP_DBG_OFF
+#define INET_DEBUG                      LWIP_DBG_OFF
+#define IP_DEBUG                        LWIP_DBG_OFF
+#define IP_REASS_DEBUG                  LWIP_DBG_OFF
+#define RAW_DEBUG                       LWIP_DBG_OFF
+#define MEM_DEBUG                       LWIP_DBG_OFF
+#define MEMP_DEBUG                      LWIP_DBG_OFF
+#define SYS_DEBUG                       LWIP_DBG_OFF
+#define TIMERS_DEBUG                    LWIP_DBG_OFF
+#define TCP_DEBUG                       LWIP_DBG_OFF
+#define TCP_INPUT_DEBUG                 LWIP_DBG_OFF
+#define TCP_FR_DEBUG                    LWIP_DBG_OFF
+#define TCP_RTO_DEBUG                   LWIP_DBG_OFF
+#define TCP_CWND_DEBUG                  LWIP_DBG_OFF
+#define TCP_WND_DEBUG                   LWIP_DBG_OFF
+#define TCP_OUTPUT_DEBUG                LWIP_DBG_OFF
+#define TCP_RST_DEBUG                   LWIP_DBG_OFF
+#define TCP_QLEN_DEBUG                  LWIP_DBG_OFF
+#define UDP_DEBUG                       LWIP_DBG_OFF
+#define TCPIP_DEBUG                     LWIP_DBG_OFF
+#define SLIP_DEBUG                      LWIP_DBG_OFF
+#define DHCP_DEBUG                      LWIP_DBG_OFF
+#define AUTOIP_DEBUG                    LWIP_DBG_OFF
+#define DNS_DEBUG                       LWIP_DBG_OFF
+#define IP6_DEBUG                       LWIP_DBG_OFF
+#define DHCP6_DEBUG                     LWIP_DBG_OFF
+#define LWIP_TESTMODE                   0
+
+#define LWIP_PERF                       0
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/examples/example_app/test_configs/opt_nosys_ipv4.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/examples/example_app/test_configs/opt_nosys_ipv4.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/examples/example_app/test_configs/opt_nosys_ipv4.h	(revision 457)
@@ -0,0 +1,296 @@
+/* test an lwipopts.h file with default contents */
+#define NO_SYS                          0
+#define NO_SYS_NO_TIMERS                0
+#define LWIP_TIMERS                     1
+#define LWIP_TIMERS_CUSTOM              0
+#define LWIP_MPU_COMPATIBLE             0
+#define LWIP_TCPIP_CORE_LOCKING         1
+#define LWIP_TCPIP_CORE_LOCKING_INPUT   0
+#define SYS_LIGHTWEIGHT_PROT            1
+#define MEM_LIBC_MALLOC                 0
+#define MEMP_MEM_MALLOC                 0
+#define MEMP_MEM_INIT                   0
+#define MEM_ALIGNMENT                   1
+#define MEM_SIZE                        1600
+#define MEMP_OVERFLOW_CHECK             0
+#define MEMP_SANITY_CHECK               0
+#define MEM_OVERFLOW_CHECK              0
+#define MEM_SANITY_CHECK                0
+#define MEM_USE_POOLS                   0
+#define MEM_USE_POOLS_TRY_BIGGER_POOL   0
+#define MEMP_USE_CUSTOM_POOLS           0
+#define LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT 0
+/*#define MEMP_NUM_PBUF                   16
+#define MEMP_NUM_RAW_PCB                4
+#define MEMP_NUM_UDP_PCB                4
+#define MEMP_NUM_TCP_PCB                5
+#define MEMP_NUM_TCP_PCB_LISTEN         8
+#define MEMP_NUM_TCP_SEG                16
+#define MEMP_NUM_ALTCP_PCB              MEMP_NUM_TCP_PCB
+#define MEMP_NUM_REASSDATA              5
+#define MEMP_NUM_FRAG_PBUF              15
+#define MEMP_NUM_ARP_QUEUE              30
+#define MEMP_NUM_IGMP_GROUP             8
+#define MEMP_NUM_SYS_TIMEOUT            (LWIP_NUM_SYS_TIMEOUT_INTERNAL + 2)
+#define MEMP_NUM_NETBUF                 2
+#define MEMP_NUM_NETCONN                4
+#define MEMP_NUM_SELECT_CB              4
+#define MEMP_NUM_TCPIP_MSG_API          8
+#define MEMP_NUM_TCPIP_MSG_INPKT        8
+#define MEMP_NUM_NETDB                  1
+#define MEMP_NUM_LOCALHOSTLIST          1
+#define PBUF_POOL_SIZE                  16
+#define MEMP_NUM_API_MSG                MEMP_NUM_TCPIP_MSG_API
+#define MEMP_NUM_DNS_API_MSG            MEMP_NUM_TCPIP_MSG_API
+#define MEMP_NUM_SOCKET_SETGETSOCKOPT_DATA MEMP_NUM_TCPIP_MSG_API
+#define MEMP_NUM_NETIFAPI_MSG           MEMP_NUM_TCPIP_MSG_API*/
+#define LWIP_ARP                        1
+#define ARP_TABLE_SIZE                  10
+#define ARP_MAXAGE                      300
+#define ARP_QUEUEING                    0
+#define ARP_QUEUE_LEN                   3
+#define ETHARP_SUPPORT_VLAN             0
+#define LWIP_ETHERNET                   LWIP_ARP
+#define ETH_PAD_SIZE                    0
+#define ETHARP_SUPPORT_STATIC_ENTRIES   0
+#define ETHARP_TABLE_MATCH_NETIF        !LWIP_SINGLE_NETIF
+#define LWIP_IPV4                       1
+#define IP_FORWARD                      0
+#define IP_REASSEMBLY                   1
+#define IP_FRAG                         1
+#define IP_OPTIONS_ALLOWED              1
+#define IP_REASS_MAXAGE                 15
+#define IP_REASS_MAX_PBUFS              10
+#define IP_DEFAULT_TTL                  255
+#define IP_SOF_BROADCAST                0
+#define IP_SOF_BROADCAST_RECV           0
+#define IP_FORWARD_ALLOW_TX_ON_RX_NETIF 0
+#define LWIP_ICMP                       1
+#define ICMP_TTL                        (IP_DEFAULT_TTL)
+#define LWIP_BROADCAST_PING             0
+#define LWIP_MULTICAST_PING             0
+#define LWIP_RAW                        0
+#define RAW_TTL                         (IP_DEFAULT_TTL)
+#define LWIP_DHCP                       0
+#define DHCP_DOES_ARP_CHECK             ((LWIP_DHCP) && (LWIP_ARP))
+#define LWIP_DHCP_CHECK_LINK_UP         0
+#define LWIP_DHCP_BOOTP_FILE            0
+#define LWIP_DHCP_GET_NTP_SRV           0
+#define LWIP_DHCP_MAX_NTP_SERVERS       1
+#define LWIP_DHCP_MAX_DNS_SERVERS       DNS_MAX_SERVERS
+#define LWIP_AUTOIP                     0
+#define LWIP_DHCP_AUTOIP_COOP           0
+#define LWIP_DHCP_AUTOIP_COOP_TRIES     9
+#define LWIP_MIB2_CALLBACKS             0
+#define LWIP_MULTICAST_TX_OPTIONS       ((LWIP_IGMP || LWIP_IPV6_MLD) && (LWIP_UDP || LWIP_RAW))
+#define LWIP_IGMP                       0
+#define LWIP_DNS                        0
+#define DNS_TABLE_SIZE                  4
+#define DNS_MAX_NAME_LENGTH             256
+#define DNS_MAX_SERVERS                 2
+#define DNS_MAX_RETRIES                 4
+#define DNS_DOES_NAME_CHECK             1
+#define LWIP_DNS_SECURE (LWIP_DNS_SECURE_RAND_XID | LWIP_DNS_SECURE_NO_MULTIPLE_OUTSTANDING | LWIP_DNS_SECURE_RAND_SRC_PORT)
+#define DNS_LOCAL_HOSTLIST              0
+#define DNS_LOCAL_HOSTLIST_IS_DYNAMIC   0
+#define LWIP_DNS_SUPPORT_MDNS_QUERIES   0
+#define LWIP_UDP                        1
+#define LWIP_UDPLITE                    0
+#define UDP_TTL                         (IP_DEFAULT_TTL)
+#define LWIP_NETBUF_RECVINFO            0
+#define LWIP_TCP                        1
+#define TCP_TTL                         (IP_DEFAULT_TTL)
+#define TCP_WND                         (4 * TCP_MSS)
+#define TCP_MAXRTX                      12
+#define TCP_SYNMAXRTX                   6
+#define TCP_QUEUE_OOSEQ                 (LWIP_TCP)
+#define LWIP_TCP_SACK_OUT               0
+#define LWIP_TCP_MAX_SACK_NUM           4
+#define TCP_MSS                         536
+#define TCP_CALCULATE_EFF_SEND_MSS      1
+#define TCP_SND_BUF                     (2 * TCP_MSS)
+#define TCP_SND_QUEUELEN                ((4 * (TCP_SND_BUF) + (TCP_MSS - 1))/(TCP_MSS))
+#define TCP_SNDLOWAT                    LWIP_MIN(LWIP_MAX(((TCP_SND_BUF)/2), (2 * TCP_MSS) + 1), (TCP_SND_BUF) - 1)
+#define TCP_SNDQUEUELOWAT               LWIP_MAX(((TCP_SND_QUEUELEN)/2), 5)
+#define TCP_OOSEQ_MAX_BYTES             0
+#define TCP_OOSEQ_BYTES_LIMIT(pcb)      TCP_OOSEQ_MAX_BYTES
+#define TCP_OOSEQ_MAX_PBUFS             0
+#define TCP_OOSEQ_PBUFS_LIMIT(pcb)      TCP_OOSEQ_MAX_PBUFS
+#define TCP_LISTEN_BACKLOG              0
+#define TCP_DEFAULT_LISTEN_BACKLOG      0xff
+#define TCP_OVERSIZE                    TCP_MSS
+#define LWIP_TCP_TIMESTAMPS             0
+#define TCP_WND_UPDATE_THRESHOLD        LWIP_MIN((TCP_WND / 4), (TCP_MSS * 4))
+#define LWIP_EVENT_API                  0
+#define LWIP_CALLBACK_API               1
+#define LWIP_WND_SCALE                  0
+#define TCP_RCV_SCALE                   0
+#define LWIP_TCP_PCB_NUM_EXT_ARGS       0
+#define LWIP_ALTCP                      0
+#define LWIP_ALTCP_TLS                  0
+#define PBUF_LINK_HLEN                  (14 + ETH_PAD_SIZE)
+#define PBUF_LINK_ENCAPSULATION_HLEN    0
+#define PBUF_POOL_BUFSIZE               LWIP_MEM_ALIGN_SIZE(TCP_MSS+40+PBUF_LINK_ENCAPSULATION_HLEN+PBUF_LINK_HLEN)
+#define LWIP_PBUF_REF_T                 u8_t
+#define LWIP_SINGLE_NETIF               0
+#define LWIP_NETIF_HOSTNAME             0
+#define LWIP_NETIF_API                  0
+#define LWIP_NETIF_STATUS_CALLBACK      0
+#define LWIP_NETIF_EXT_STATUS_CALLBACK  0
+#define LWIP_NETIF_LINK_CALLBACK        0
+#define LWIP_NETIF_REMOVE_CALLBACK      0
+#define LWIP_NETIF_HWADDRHINT           0
+#define LWIP_NETIF_TX_SINGLE_PBUF       0
+#define LWIP_NUM_NETIF_CLIENT_DATA      0
+#define LWIP_HAVE_LOOPIF                (LWIP_NETIF_LOOPBACK && !LWIP_SINGLE_NETIF)
+#define LWIP_LOOPIF_MULTICAST           0
+#define LWIP_NETIF_LOOPBACK             0
+#define LWIP_LOOPBACK_MAX_PBUFS         0
+#define LWIP_NETIF_LOOPBACK_MULTITHREADING    (!NO_SYS)
+/*#define TCPIP_THREAD_NAME               "tcpip_thread"
+#define TCPIP_THREAD_STACKSIZE          0
+#define TCPIP_THREAD_PRIO               1
+#define TCPIP_MBOX_SIZE                 0
+#define LWIP_TCPIP_THREAD_ALIVE()
+#define SLIPIF_THREAD_NAME              "slipif_loop"
+#define SLIPIF_THREAD_STACKSIZE         0
+#define SLIPIF_THREAD_PRIO              1
+#define DEFAULT_THREAD_NAME             "lwIP"
+#define DEFAULT_THREAD_STACKSIZE        0
+#define DEFAULT_THREAD_PRIO             1
+#define DEFAULT_RAW_RECVMBOX_SIZE       0
+#define DEFAULT_UDP_RECVMBOX_SIZE       0
+#define DEFAULT_TCP_RECVMBOX_SIZE       0
+#define DEFAULT_ACCEPTMBOX_SIZE         0*/
+#define LWIP_NETCONN                    0
+#define LWIP_TCPIP_TIMEOUT              0
+#define LWIP_NETCONN_SEM_PER_THREAD     0
+#define LWIP_NETCONN_FULLDUPLEX         0
+#define LWIP_SOCKET                     0
+#define LWIP_COMPAT_SOCKETS             1 /* 0..2 */
+#define LWIP_POSIX_SOCKETS_IO_NAMES     1
+#define LWIP_SOCKET_OFFSET              0
+#define LWIP_TCP_KEEPALIVE              0
+#define LWIP_SO_SNDTIMEO                0
+#define LWIP_SO_RCVTIMEO                0
+#define LWIP_SO_SNDRCVTIMEO_NONSTANDARD 0
+#define LWIP_SO_RCVBUF                  0
+#define LWIP_SO_LINGER                  0
+#define RECV_BUFSIZE_DEFAULT            INT_MAX
+#define LWIP_TCP_CLOSE_TIMEOUT_MS_DEFAULT 20000
+#define SO_REUSE                        0
+#define SO_REUSE_RXTOALL                0
+#define LWIP_FIONREAD_LINUXMODE         0
+#define LWIP_SOCKET_SELECT              1
+#define LWIP_SOCKET_POLL                1
+#define LWIP_STATS                      1
+#define LWIP_STATS_DISPLAY              0
+#define LINK_STATS                      1
+#define ETHARP_STATS                    (LWIP_ARP)
+#define IP_STATS                        1
+#define IPFRAG_STATS                    (IP_REASSEMBLY || IP_FRAG)
+#define ICMP_STATS                      1
+#define IGMP_STATS                      (LWIP_IGMP)
+#define UDP_STATS                       (LWIP_UDP)
+#define TCP_STATS                       (LWIP_TCP)
+#define MEM_STATS                       ((MEM_LIBC_MALLOC == 0) && (MEM_USE_POOLS == 0))
+#define MEMP_STATS                      (MEMP_MEM_MALLOC == 0)
+#define SYS_STATS                       (NO_SYS == 0)
+#define IP6_STATS                       (LWIP_IPV6)
+#define ICMP6_STATS                     (LWIP_IPV6 && LWIP_ICMP6)
+#define IP6_FRAG_STATS                  (LWIP_IPV6 && (LWIP_IPV6_FRAG || LWIP_IPV6_REASS))
+#define MLD6_STATS                      (LWIP_IPV6 && LWIP_IPV6_MLD)
+#define ND6_STATS                       (LWIP_IPV6)
+#define MIB2_STATS                      0
+#define LWIP_CHECKSUM_CTRL_PER_NETIF    0
+#define CHECKSUM_GEN_IP                 1
+#define CHECKSUM_GEN_UDP                1
+#define CHECKSUM_GEN_TCP                1
+#define CHECKSUM_GEN_ICMP               1
+#define CHECKSUM_GEN_ICMP6              1
+#define CHECKSUM_CHECK_IP               1
+#define CHECKSUM_CHECK_UDP              1
+#define CHECKSUM_CHECK_TCP              1
+#define CHECKSUM_CHECK_ICMP             1
+#define CHECKSUM_CHECK_ICMP6            1
+#define LWIP_CHECKSUM_ON_COPY           0
+#define LWIP_IPV6                       0
+#define IPV6_REASS_MAXAGE               60
+#define LWIP_IPV6_SCOPES                (LWIP_IPV6 && !LWIP_SINGLE_NETIF)
+#define LWIP_IPV6_SCOPES_DEBUG          0
+#define LWIP_IPV6_NUM_ADDRESSES         3
+#define LWIP_IPV6_FORWARD               0
+#define LWIP_IPV6_FRAG                  1
+#define LWIP_IPV6_REASS                 (LWIP_IPV6)
+#define LWIP_IPV6_SEND_ROUTER_SOLICIT   1
+#define LWIP_IPV6_AUTOCONFIG            (LWIP_IPV6)
+#define LWIP_IPV6_ADDRESS_LIFETIMES     (LWIP_IPV6_AUTOCONFIG)
+#define LWIP_IPV6_DUP_DETECT_ATTEMPTS   1
+#define LWIP_ICMP6                      (LWIP_IPV6)
+#define LWIP_ICMP6_DATASIZE             8
+#define LWIP_ICMP6_HL                   255
+#define LWIP_IPV6_MLD                   (LWIP_IPV6)
+#define MEMP_NUM_MLD6_GROUP             4
+#define LWIP_ND6_QUEUEING               (LWIP_IPV6)
+#define MEMP_NUM_ND6_QUEUE              20
+#define LWIP_ND6_NUM_NEIGHBORS          10
+#define LWIP_ND6_NUM_DESTINATIONS       10
+#define LWIP_ND6_NUM_PREFIXES           5
+#define LWIP_ND6_NUM_ROUTERS            3
+#define LWIP_ND6_MAX_MULTICAST_SOLICIT  3
+#define LWIP_ND6_MAX_UNICAST_SOLICIT    3
+#define LWIP_ND6_MAX_ANYCAST_DELAY_TIME 1000
+#define LWIP_ND6_MAX_NEIGHBOR_ADVERTISEMENT  3
+#define LWIP_ND6_REACHABLE_TIME         30000
+#define LWIP_ND6_RETRANS_TIMER          1000
+#define LWIP_ND6_DELAY_FIRST_PROBE_TIME 5000
+#define LWIP_ND6_ALLOW_RA_UPDATES       1
+#define LWIP_ND6_TCP_REACHABILITY_HINTS 1
+#define LWIP_ND6_RDNSS_MAX_DNS_SERVERS  0
+#define LWIP_IPV6_DHCP6                 0
+#define LWIP_IPV6_DHCP6_STATEFUL        0
+#define LWIP_IPV6_DHCP6_STATELESS       LWIP_IPV6_DHCP6
+#define LWIP_DHCP6_GET_NTP_SRV          0
+#define LWIP_DHCP6_MAX_NTP_SERVERS      1
+#define LWIP_DHCP6_MAX_DNS_SERVERS      DNS_MAX_SERVERS
+
+/* TODO: check hooks */
+
+#define LWIP_DBG_MIN_LEVEL              LWIP_DBG_LEVEL_ALL
+#define LWIP_DBG_TYPES_ON               LWIP_DBG_ON
+#define ETHARP_DEBUG                    LWIP_DBG_OFF
+#define NETIF_DEBUG                     LWIP_DBG_OFF
+#define PBUF_DEBUG                      LWIP_DBG_OFF
+#define API_LIB_DEBUG                   LWIP_DBG_OFF
+#define API_MSG_DEBUG                   LWIP_DBG_OFF
+#define SOCKETS_DEBUG                   LWIP_DBG_OFF
+#define ICMP_DEBUG                      LWIP_DBG_OFF
+#define IGMP_DEBUG                      LWIP_DBG_OFF
+#define INET_DEBUG                      LWIP_DBG_OFF
+#define IP_DEBUG                        LWIP_DBG_OFF
+#define IP_REASS_DEBUG                  LWIP_DBG_OFF
+#define RAW_DEBUG                       LWIP_DBG_OFF
+#define MEM_DEBUG                       LWIP_DBG_OFF
+#define MEMP_DEBUG                      LWIP_DBG_OFF
+#define SYS_DEBUG                       LWIP_DBG_OFF
+#define TIMERS_DEBUG                    LWIP_DBG_OFF
+#define TCP_DEBUG                       LWIP_DBG_OFF
+#define TCP_INPUT_DEBUG                 LWIP_DBG_OFF
+#define TCP_FR_DEBUG                    LWIP_DBG_OFF
+#define TCP_RTO_DEBUG                   LWIP_DBG_OFF
+#define TCP_CWND_DEBUG                  LWIP_DBG_OFF
+#define TCP_WND_DEBUG                   LWIP_DBG_OFF
+#define TCP_OUTPUT_DEBUG                LWIP_DBG_OFF
+#define TCP_RST_DEBUG                   LWIP_DBG_OFF
+#define TCP_QLEN_DEBUG                  LWIP_DBG_OFF
+#define UDP_DEBUG                       LWIP_DBG_OFF
+#define TCPIP_DEBUG                     LWIP_DBG_OFF
+#define SLIP_DEBUG                      LWIP_DBG_OFF
+#define DHCP_DEBUG                      LWIP_DBG_OFF
+#define AUTOIP_DEBUG                    LWIP_DBG_OFF
+#define DNS_DEBUG                       LWIP_DBG_OFF
+#define IP6_DEBUG                       LWIP_DBG_OFF
+#define DHCP6_DEBUG                     LWIP_DBG_OFF
+#define LWIP_TESTMODE                   0
+
+#define LWIP_PERF                       0
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/examples/example_app/test_configs/opt_nosys_ipv6.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/examples/example_app/test_configs/opt_nosys_ipv6.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/examples/example_app/test_configs/opt_nosys_ipv6.h	(revision 457)
@@ -0,0 +1,296 @@
+/* test an lwipopts.h file with default contents */
+#define NO_SYS                          0
+#define NO_SYS_NO_TIMERS                0
+#define LWIP_TIMERS                     1
+#define LWIP_TIMERS_CUSTOM              0
+#define LWIP_MPU_COMPATIBLE             0
+#define LWIP_TCPIP_CORE_LOCKING         1
+#define LWIP_TCPIP_CORE_LOCKING_INPUT   0
+#define SYS_LIGHTWEIGHT_PROT            1
+#define MEM_LIBC_MALLOC                 0
+#define MEMP_MEM_MALLOC                 0
+#define MEMP_MEM_INIT                   0
+#define MEM_ALIGNMENT                   1
+#define MEM_SIZE                        1600
+#define MEMP_OVERFLOW_CHECK             0
+#define MEMP_SANITY_CHECK               0
+#define MEM_OVERFLOW_CHECK              0
+#define MEM_SANITY_CHECK                0
+#define MEM_USE_POOLS                   0
+#define MEM_USE_POOLS_TRY_BIGGER_POOL   0
+#define MEMP_USE_CUSTOM_POOLS           0
+#define LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT 0
+/*#define MEMP_NUM_PBUF                   16
+#define MEMP_NUM_RAW_PCB                4
+#define MEMP_NUM_UDP_PCB                4
+#define MEMP_NUM_TCP_PCB                5
+#define MEMP_NUM_TCP_PCB_LISTEN         8
+#define MEMP_NUM_TCP_SEG                16
+#define MEMP_NUM_ALTCP_PCB              MEMP_NUM_TCP_PCB
+#define MEMP_NUM_REASSDATA              5
+#define MEMP_NUM_FRAG_PBUF              15
+#define MEMP_NUM_ARP_QUEUE              30
+#define MEMP_NUM_IGMP_GROUP             8
+#define MEMP_NUM_SYS_TIMEOUT            (LWIP_NUM_SYS_TIMEOUT_INTERNAL + 2)
+#define MEMP_NUM_NETBUF                 2
+#define MEMP_NUM_NETCONN                4
+#define MEMP_NUM_SELECT_CB              4
+#define MEMP_NUM_TCPIP_MSG_API          8
+#define MEMP_NUM_TCPIP_MSG_INPKT        8
+#define MEMP_NUM_NETDB                  1
+#define MEMP_NUM_LOCALHOSTLIST          1
+#define PBUF_POOL_SIZE                  16
+#define MEMP_NUM_API_MSG                MEMP_NUM_TCPIP_MSG_API
+#define MEMP_NUM_DNS_API_MSG            MEMP_NUM_TCPIP_MSG_API
+#define MEMP_NUM_SOCKET_SETGETSOCKOPT_DATA MEMP_NUM_TCPIP_MSG_API
+#define MEMP_NUM_NETIFAPI_MSG           MEMP_NUM_TCPIP_MSG_API*/
+#define LWIP_ARP                        1
+#define ARP_TABLE_SIZE                  10
+#define ARP_MAXAGE                      300
+#define ARP_QUEUEING                    0
+#define ARP_QUEUE_LEN                   3
+#define ETHARP_SUPPORT_VLAN             0
+#define LWIP_ETHERNET                   LWIP_ARP
+#define ETH_PAD_SIZE                    0
+#define ETHARP_SUPPORT_STATIC_ENTRIES   0
+#define ETHARP_TABLE_MATCH_NETIF        !LWIP_SINGLE_NETIF
+#define LWIP_IPV4                       0
+#define IP_FORWARD                      0
+#define IP_REASSEMBLY                   1
+#define IP_FRAG                         1
+#define IP_OPTIONS_ALLOWED              1
+#define IP_REASS_MAXAGE                 15
+#define IP_REASS_MAX_PBUFS              10
+#define IP_DEFAULT_TTL                  255
+#define IP_SOF_BROADCAST                0
+#define IP_SOF_BROADCAST_RECV           0
+#define IP_FORWARD_ALLOW_TX_ON_RX_NETIF 0
+#define LWIP_ICMP                       1
+#define ICMP_TTL                        (IP_DEFAULT_TTL)
+#define LWIP_BROADCAST_PING             0
+#define LWIP_MULTICAST_PING             0
+#define LWIP_RAW                        0
+#define RAW_TTL                         (IP_DEFAULT_TTL)
+#define LWIP_DHCP                       0
+#define DHCP_DOES_ARP_CHECK             ((LWIP_DHCP) && (LWIP_ARP))
+#define LWIP_DHCP_CHECK_LINK_UP         0
+#define LWIP_DHCP_BOOTP_FILE            0
+#define LWIP_DHCP_GET_NTP_SRV           0
+#define LWIP_DHCP_MAX_NTP_SERVERS       1
+#define LWIP_DHCP_MAX_DNS_SERVERS       DNS_MAX_SERVERS
+#define LWIP_AUTOIP                     0
+#define LWIP_DHCP_AUTOIP_COOP           0
+#define LWIP_DHCP_AUTOIP_COOP_TRIES     9
+#define LWIP_MIB2_CALLBACKS             0
+#define LWIP_MULTICAST_TX_OPTIONS       ((LWIP_IGMP || LWIP_IPV6_MLD) && (LWIP_UDP || LWIP_RAW))
+#define LWIP_IGMP                       0
+#define LWIP_DNS                        0
+#define DNS_TABLE_SIZE                  4
+#define DNS_MAX_NAME_LENGTH             256
+#define DNS_MAX_SERVERS                 2
+#define DNS_MAX_RETRIES                 4
+#define DNS_DOES_NAME_CHECK             1
+#define LWIP_DNS_SECURE (LWIP_DNS_SECURE_RAND_XID | LWIP_DNS_SECURE_NO_MULTIPLE_OUTSTANDING | LWIP_DNS_SECURE_RAND_SRC_PORT)
+#define DNS_LOCAL_HOSTLIST              0
+#define DNS_LOCAL_HOSTLIST_IS_DYNAMIC   0
+#define LWIP_DNS_SUPPORT_MDNS_QUERIES   0
+#define LWIP_UDP                        1
+#define LWIP_UDPLITE                    0
+#define UDP_TTL                         (IP_DEFAULT_TTL)
+#define LWIP_NETBUF_RECVINFO            0
+#define LWIP_TCP                        1
+#define TCP_TTL                         (IP_DEFAULT_TTL)
+#define TCP_WND                         (4 * TCP_MSS)
+#define TCP_MAXRTX                      12
+#define TCP_SYNMAXRTX                   6
+#define TCP_QUEUE_OOSEQ                 (LWIP_TCP)
+#define LWIP_TCP_SACK_OUT               0
+#define LWIP_TCP_MAX_SACK_NUM           4
+#define TCP_MSS                         536
+#define TCP_CALCULATE_EFF_SEND_MSS      1
+#define TCP_SND_BUF                     (2 * TCP_MSS)
+#define TCP_SND_QUEUELEN                ((4 * (TCP_SND_BUF) + (TCP_MSS - 1))/(TCP_MSS))
+#define TCP_SNDLOWAT                    LWIP_MIN(LWIP_MAX(((TCP_SND_BUF)/2), (2 * TCP_MSS) + 1), (TCP_SND_BUF) - 1)
+#define TCP_SNDQUEUELOWAT               LWIP_MAX(((TCP_SND_QUEUELEN)/2), 5)
+#define TCP_OOSEQ_MAX_BYTES             0
+#define TCP_OOSEQ_BYTES_LIMIT(pcb)      TCP_OOSEQ_MAX_BYTES
+#define TCP_OOSEQ_MAX_PBUFS             0
+#define TCP_OOSEQ_PBUFS_LIMIT(pcb)      TCP_OOSEQ_MAX_PBUFS
+#define TCP_LISTEN_BACKLOG              0
+#define TCP_DEFAULT_LISTEN_BACKLOG      0xff
+#define TCP_OVERSIZE                    TCP_MSS
+#define LWIP_TCP_TIMESTAMPS             0
+#define TCP_WND_UPDATE_THRESHOLD        LWIP_MIN((TCP_WND / 4), (TCP_MSS * 4))
+#define LWIP_EVENT_API                  0
+#define LWIP_CALLBACK_API               1
+#define LWIP_WND_SCALE                  0
+#define TCP_RCV_SCALE                   0
+#define LWIP_TCP_PCB_NUM_EXT_ARGS       0
+#define LWIP_ALTCP                      0
+#define LWIP_ALTCP_TLS                  0
+#define PBUF_LINK_HLEN                  (14 + ETH_PAD_SIZE)
+#define PBUF_LINK_ENCAPSULATION_HLEN    0
+#define PBUF_POOL_BUFSIZE               LWIP_MEM_ALIGN_SIZE(TCP_MSS+40+PBUF_LINK_ENCAPSULATION_HLEN+PBUF_LINK_HLEN)
+#define LWIP_PBUF_REF_T                 u8_t
+#define LWIP_SINGLE_NETIF               0
+#define LWIP_NETIF_HOSTNAME             0
+#define LWIP_NETIF_API                  0
+#define LWIP_NETIF_STATUS_CALLBACK      0
+#define LWIP_NETIF_EXT_STATUS_CALLBACK  0
+#define LWIP_NETIF_LINK_CALLBACK        0
+#define LWIP_NETIF_REMOVE_CALLBACK      0
+#define LWIP_NETIF_HWADDRHINT           0
+#define LWIP_NETIF_TX_SINGLE_PBUF       0
+#define LWIP_NUM_NETIF_CLIENT_DATA      0
+#define LWIP_HAVE_LOOPIF                (LWIP_NETIF_LOOPBACK && !LWIP_SINGLE_NETIF)
+#define LWIP_LOOPIF_MULTICAST           0
+#define LWIP_NETIF_LOOPBACK             0
+#define LWIP_LOOPBACK_MAX_PBUFS         0
+#define LWIP_NETIF_LOOPBACK_MULTITHREADING    (!NO_SYS)
+/*#define TCPIP_THREAD_NAME               "tcpip_thread"
+#define TCPIP_THREAD_STACKSIZE          0
+#define TCPIP_THREAD_PRIO               1
+#define TCPIP_MBOX_SIZE                 0
+#define LWIP_TCPIP_THREAD_ALIVE()
+#define SLIPIF_THREAD_NAME              "slipif_loop"
+#define SLIPIF_THREAD_STACKSIZE         0
+#define SLIPIF_THREAD_PRIO              1
+#define DEFAULT_THREAD_NAME             "lwIP"
+#define DEFAULT_THREAD_STACKSIZE        0
+#define DEFAULT_THREAD_PRIO             1
+#define DEFAULT_RAW_RECVMBOX_SIZE       0
+#define DEFAULT_UDP_RECVMBOX_SIZE       0
+#define DEFAULT_TCP_RECVMBOX_SIZE       0
+#define DEFAULT_ACCEPTMBOX_SIZE         0*/
+#define LWIP_NETCONN                    0
+#define LWIP_TCPIP_TIMEOUT              0
+#define LWIP_NETCONN_SEM_PER_THREAD     0
+#define LWIP_NETCONN_FULLDUPLEX         0
+#define LWIP_SOCKET                     0
+#define LWIP_COMPAT_SOCKETS             1 /* 0..2 */
+#define LWIP_POSIX_SOCKETS_IO_NAMES     1
+#define LWIP_SOCKET_OFFSET              0
+#define LWIP_TCP_KEEPALIVE              0
+#define LWIP_SO_SNDTIMEO                0
+#define LWIP_SO_RCVTIMEO                0
+#define LWIP_SO_SNDRCVTIMEO_NONSTANDARD 0
+#define LWIP_SO_RCVBUF                  0
+#define LWIP_SO_LINGER                  0
+#define RECV_BUFSIZE_DEFAULT            INT_MAX
+#define LWIP_TCP_CLOSE_TIMEOUT_MS_DEFAULT 20000
+#define SO_REUSE                        0
+#define SO_REUSE_RXTOALL                0
+#define LWIP_FIONREAD_LINUXMODE         0
+#define LWIP_SOCKET_SELECT              1
+#define LWIP_SOCKET_POLL                1
+#define LWIP_STATS                      1
+#define LWIP_STATS_DISPLAY              0
+#define LINK_STATS                      1
+#define ETHARP_STATS                    (LWIP_ARP)
+#define IP_STATS                        1
+#define IPFRAG_STATS                    (IP_REASSEMBLY || IP_FRAG)
+#define ICMP_STATS                      1
+#define IGMP_STATS                      (LWIP_IGMP)
+#define UDP_STATS                       (LWIP_UDP)
+#define TCP_STATS                       (LWIP_TCP)
+#define MEM_STATS                       ((MEM_LIBC_MALLOC == 0) && (MEM_USE_POOLS == 0))
+#define MEMP_STATS                      (MEMP_MEM_MALLOC == 0)
+#define SYS_STATS                       (NO_SYS == 0)
+#define IP6_STATS                       (LWIP_IPV6)
+#define ICMP6_STATS                     (LWIP_IPV6 && LWIP_ICMP6)
+#define IP6_FRAG_STATS                  (LWIP_IPV6 && (LWIP_IPV6_FRAG || LWIP_IPV6_REASS))
+#define MLD6_STATS                      (LWIP_IPV6 && LWIP_IPV6_MLD)
+#define ND6_STATS                       (LWIP_IPV6)
+#define MIB2_STATS                      0
+#define LWIP_CHECKSUM_CTRL_PER_NETIF    0
+#define CHECKSUM_GEN_IP                 1
+#define CHECKSUM_GEN_UDP                1
+#define CHECKSUM_GEN_TCP                1
+#define CHECKSUM_GEN_ICMP               1
+#define CHECKSUM_GEN_ICMP6              1
+#define CHECKSUM_CHECK_IP               1
+#define CHECKSUM_CHECK_UDP              1
+#define CHECKSUM_CHECK_TCP              1
+#define CHECKSUM_CHECK_ICMP             1
+#define CHECKSUM_CHECK_ICMP6            1
+#define LWIP_CHECKSUM_ON_COPY           0
+#define LWIP_IPV6                       1
+#define IPV6_REASS_MAXAGE               60
+#define LWIP_IPV6_SCOPES                (LWIP_IPV6 && !LWIP_SINGLE_NETIF)
+#define LWIP_IPV6_SCOPES_DEBUG          0
+#define LWIP_IPV6_NUM_ADDRESSES         3
+#define LWIP_IPV6_FORWARD               0
+#define LWIP_IPV6_FRAG                  1
+#define LWIP_IPV6_REASS                 (LWIP_IPV6)
+#define LWIP_IPV6_SEND_ROUTER_SOLICIT   1
+#define LWIP_IPV6_AUTOCONFIG            (LWIP_IPV6)
+#define LWIP_IPV6_ADDRESS_LIFETIMES     (LWIP_IPV6_AUTOCONFIG)
+#define LWIP_IPV6_DUP_DETECT_ATTEMPTS   1
+#define LWIP_ICMP6                      (LWIP_IPV6)
+#define LWIP_ICMP6_DATASIZE             8
+#define LWIP_ICMP6_HL                   255
+#define LWIP_IPV6_MLD                   (LWIP_IPV6)
+#define MEMP_NUM_MLD6_GROUP             4
+#define LWIP_ND6_QUEUEING               (LWIP_IPV6)
+#define MEMP_NUM_ND6_QUEUE              20
+#define LWIP_ND6_NUM_NEIGHBORS          10
+#define LWIP_ND6_NUM_DESTINATIONS       10
+#define LWIP_ND6_NUM_PREFIXES           5
+#define LWIP_ND6_NUM_ROUTERS            3
+#define LWIP_ND6_MAX_MULTICAST_SOLICIT  3
+#define LWIP_ND6_MAX_UNICAST_SOLICIT    3
+#define LWIP_ND6_MAX_ANYCAST_DELAY_TIME 1000
+#define LWIP_ND6_MAX_NEIGHBOR_ADVERTISEMENT  3
+#define LWIP_ND6_REACHABLE_TIME         30000
+#define LWIP_ND6_RETRANS_TIMER          1000
+#define LWIP_ND6_DELAY_FIRST_PROBE_TIME 5000
+#define LWIP_ND6_ALLOW_RA_UPDATES       1
+#define LWIP_ND6_TCP_REACHABILITY_HINTS 1
+#define LWIP_ND6_RDNSS_MAX_DNS_SERVERS  0
+#define LWIP_IPV6_DHCP6                 0
+#define LWIP_IPV6_DHCP6_STATEFUL        0
+#define LWIP_IPV6_DHCP6_STATELESS       LWIP_IPV6_DHCP6
+#define LWIP_DHCP6_GET_NTP_SRV          0
+#define LWIP_DHCP6_MAX_NTP_SERVERS      1
+#define LWIP_DHCP6_MAX_DNS_SERVERS      DNS_MAX_SERVERS
+
+/* TODO: check hooks */
+
+#define LWIP_DBG_MIN_LEVEL              LWIP_DBG_LEVEL_ALL
+#define LWIP_DBG_TYPES_ON               LWIP_DBG_ON
+#define ETHARP_DEBUG                    LWIP_DBG_OFF
+#define NETIF_DEBUG                     LWIP_DBG_OFF
+#define PBUF_DEBUG                      LWIP_DBG_OFF
+#define API_LIB_DEBUG                   LWIP_DBG_OFF
+#define API_MSG_DEBUG                   LWIP_DBG_OFF
+#define SOCKETS_DEBUG                   LWIP_DBG_OFF
+#define ICMP_DEBUG                      LWIP_DBG_OFF
+#define IGMP_DEBUG                      LWIP_DBG_OFF
+#define INET_DEBUG                      LWIP_DBG_OFF
+#define IP_DEBUG                        LWIP_DBG_OFF
+#define IP_REASS_DEBUG                  LWIP_DBG_OFF
+#define RAW_DEBUG                       LWIP_DBG_OFF
+#define MEM_DEBUG                       LWIP_DBG_OFF
+#define MEMP_DEBUG                      LWIP_DBG_OFF
+#define SYS_DEBUG                       LWIP_DBG_OFF
+#define TIMERS_DEBUG                    LWIP_DBG_OFF
+#define TCP_DEBUG                       LWIP_DBG_OFF
+#define TCP_INPUT_DEBUG                 LWIP_DBG_OFF
+#define TCP_FR_DEBUG                    LWIP_DBG_OFF
+#define TCP_RTO_DEBUG                   LWIP_DBG_OFF
+#define TCP_CWND_DEBUG                  LWIP_DBG_OFF
+#define TCP_WND_DEBUG                   LWIP_DBG_OFF
+#define TCP_OUTPUT_DEBUG                LWIP_DBG_OFF
+#define TCP_RST_DEBUG                   LWIP_DBG_OFF
+#define TCP_QLEN_DEBUG                  LWIP_DBG_OFF
+#define UDP_DEBUG                       LWIP_DBG_OFF
+#define TCPIP_DEBUG                     LWIP_DBG_OFF
+#define SLIP_DEBUG                      LWIP_DBG_OFF
+#define DHCP_DEBUG                      LWIP_DBG_OFF
+#define AUTOIP_DEBUG                    LWIP_DBG_OFF
+#define DNS_DEBUG                       LWIP_DBG_OFF
+#define IP6_DEBUG                       LWIP_DBG_OFF
+#define DHCP6_DEBUG                     LWIP_DBG_OFF
+#define LWIP_TESTMODE                   0
+
+#define LWIP_PERF                       0
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/examples/httpd/cgi_example/cgi_example.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/examples/httpd/cgi_example/cgi_example.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/examples/httpd/cgi_example/cgi_example.c	(revision 457)
@@ -0,0 +1,107 @@
+/**
+ * @file
+ * HTTPD simple CGI example
+ *
+ * This file demonstrates how to add support for basic CGI.
+ */
+ 
+ /*
+ * Copyright (c) 2017 Simon Goldschmidt
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission. 
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ * 
+ * Author: Simon Goldschmidt <goldsimon@gmx.de>
+ *
+ */
+
+#include "lwip/opt.h"
+#include "cgi_example.h"
+
+#include "lwip/apps/httpd.h"
+
+#include "lwip/def.h"
+#include "lwip/mem.h"
+
+#include <stdio.h>
+#include <string.h>
+
+/** define LWIP_HTTPD_EXAMPLE_CGI_SIMPLE to 1 to enable this cgi example */
+#ifndef LWIP_HTTPD_EXAMPLE_CGI_SIMPLE
+#define LWIP_HTTPD_EXAMPLE_CGI_SIMPLE 0
+#endif
+
+#if LWIP_HTTPD_EXAMPLE_CGI_SIMPLE
+
+#if !LWIP_HTTPD_CGI
+#error LWIP_HTTPD_EXAMPLE_CGI_SIMPLE needs LWIP_HTTPD_CGI
+#endif
+
+static const char *cgi_handler_basic(int iIndex, int iNumParams, char *pcParam[], char *pcValue[]);
+
+static const tCGI cgi_handlers[] = {
+  {
+    "/basic_cgi",
+    cgi_handler_basic
+  },
+  {
+    "/basic_cgi_2",
+    cgi_handler_basic
+  }
+};
+
+void
+cgi_ex_init(void)
+{
+  http_set_cgi_handlers(cgi_handlers, LWIP_ARRAYSIZE(cgi_handlers));
+}
+
+/** This basic CGI function can parse param/value pairs and return an url that
+ * is sent as a response by httpd.
+ *
+ * This example function just checks that the input url has two key value
+ * parameter pairs: "foo=bar" and "test=123"
+ * If not, it returns 404
+ */
+static const char *
+cgi_handler_basic(int iIndex, int iNumParams, char *pcParam[], char *pcValue[])
+{
+  LWIP_ASSERT("check index", iIndex < LWIP_ARRAYSIZE(cgi_handlers));
+
+  if (iNumParams == 2) {
+    if (!strcmp(pcParam[0], "foo")) {
+      if (!strcmp(pcValue[0], "bar")) {
+        if (!strcmp(pcParam[1], "test")) {
+          if (!strcmp(pcValue[1], "123")) {
+            return "/index.html";
+          }
+        }
+      }
+    }
+  }
+  return "/404.html";
+}
+
+#endif /* LWIP_HTTPD_EXAMPLE_CGI_SIMPLE */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/examples/httpd/cgi_example/cgi_example.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/examples/httpd/cgi_example/cgi_example.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/examples/httpd/cgi_example/cgi_example.h	(revision 457)
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2017 Simon Goldschmidt
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission. 
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ * 
+ * Author: Simon Goldschmidt <goldsimon@gmx.de>
+ *
+ */
+
+#ifndef LWIP_HDR_HTTP_EXAMPLES_CGI_EXAMPLE
+#define LWIP_HDR_HTTP_EXAMPLES_CGI_EXAMPLE
+
+void cgi_ex_init(void);
+
+#endif /* LWIP_HDR_HTTP_EXAMPLES_CGI_EXAMPLE */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/examples/httpd/examples_fs/404.html
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/examples/httpd/examples_fs/404.html	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/examples/httpd/examples_fs/404.html	(revision 457)
@@ -0,0 +1,21 @@
+<html>
+<head><title>lwIP - A Lightweight TCP/IP Stack</title></head>
+<body bgcolor="white" text="black">
+
+    <table width="100%">
+      <tr valign="top"><td width="80">	  
+	  <a href="http://www.sics.se/"><img src="/img/sics.gif"
+	  border="0" alt="SICS logo" title="SICS logo"></a>
+	</td><td width="500">	  
+	  <h1>lwIP - A Lightweight TCP/IP Stack</h1>
+	  <h2>404 - Page not found</h2>
+	  <p>
+	    Sorry, the page you are requesting was not found on this
+	    server. 
+	  </p>
+	</td><td>
+	  &nbsp;
+	</td></tr>
+      </table>
+</body>
+</html>
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/examples/httpd/examples_fs/index.html
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/examples/httpd/examples_fs/index.html	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/examples/httpd/examples_fs/index.html	(revision 457)
@@ -0,0 +1,47 @@
+<html>
+<head><title>lwIP - A Lightweight TCP/IP Stack</title></head>
+<body bgcolor="white" text="black">
+
+    <table width="100%">
+      <tr valign="top"><td width="80">	  
+	  <a href="http://www.sics.se/"><img src="/img/sics.gif"
+	  border="0" alt="SICS logo" title="SICS logo"></a>
+	</td><td width="500">	  
+	  <h1>lwIP - A Lightweight TCP/IP Stack</h1>
+	  <p>
+	    The web page you are watching was served by a simple web
+	    server running on top of the lightweight TCP/IP stack <a
+	    href="http://www.sics.se/~adam/lwip/">lwIP</a>.
+	  </p>
+	  <p>
+	    lwIP is an open source implementation of the TCP/IP
+	    protocol suite that was originally written by <a
+	    href="http://www.sics.se/~adam/lwip/">Adam Dunkels
+	    of the Swedish Institute of Computer Science</a> but now is
+	    being actively developed by a team of developers
+	    distributed world-wide. Since it's release, lwIP has
+	    spurred a lot of interest and has been ported to several
+	    platforms and operating systems. lwIP can be used either
+	    with or without an underlying OS.
+	  </p>
+	  <p>
+	    The focus of the lwIP TCP/IP implementation is to reduce
+	    the RAM usage while still having a full scale TCP. This
+	    makes lwIP suitable for use in embedded systems with tens
+	    of kilobytes of free RAM and room for around 40 kilobytes
+	    of code ROM.
+	  </p>
+	  <p>
+	    More information about lwIP can be found at the lwIP
+	    homepage at <a
+	    href="http://savannah.nongnu.org/projects/lwip/">http://savannah.nongnu.org/projects/lwip/</a>
+	    or at the lwIP wiki at <a
+	    href="http://lwip.wikia.com/">http://lwip.wikia.com/</a>.
+	  </p>
+	</td><td>
+	  &nbsp;
+	</td></tr>
+      </table>
+</body>
+</html>
+
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/examples/httpd/examples_fs/login.html
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/examples/httpd/examples_fs/login.html	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/examples/httpd/examples_fs/login.html	(revision 457)
@@ -0,0 +1,28 @@
+<html>
+<head><title>lwIP - A Lightweight TCP/IP Stack</title></head>
+<body bgcolor="white" text="black">
+
+<table width="100%">
+ <tr valign="top">
+  <td width="80">
+   <a href="http://www.sics.se/"><img src="/img/sics.gif" border="0" alt="SICS logo" title="SICS logo"/></a>
+  </td>
+  <td width="500">
+   <h1>Login</h1>
+   <form name="login" action="login.cgi" method="post">
+    <div>
+     <label><b>Username</b></label>
+     <input type="text" placeholder="Enter Username" name="user" required>
+     <label><b>Password</b></label>
+     <input type="password" placeholder="Enter Password" name="pass" required>
+     <button type="submit">Login</button>
+    </div>
+   </form> 
+  </td>
+  <td>
+   &nbsp;
+  </td>
+ </tr>
+</table>
+</body>
+</html>
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/examples/httpd/examples_fs/loginfail.html
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/examples/httpd/examples_fs/loginfail.html	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/examples/httpd/examples_fs/loginfail.html	(revision 457)
@@ -0,0 +1,25 @@
+<html>
+<head><title>lwIP - A Lightweight TCP/IP Stack</title></head>
+<body bgcolor="white" text="black">
+
+ <table width="100%">
+  <tr valign="top">
+   <td width="80">
+    <a href="http://www.sics.se/"><img src="/img/sics.gif" border="0" alt="SICS logo" title="SICS logo"/></a>
+   </td>
+   <td width="500">
+    <h1>lwIP - A Lightweight TCP/IP Stack</h1>
+    <p>
+     Login failed.
+    </p>
+    <p>
+     Click <a href="login.html">here</a> to retry login.
+    </p>
+   </td>
+   <td>
+    &nbsp;
+   </td>
+  </tr>
+ </table>
+</body>
+</html>
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/examples/httpd/examples_fs/session.html
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/examples/httpd/examples_fs/session.html	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/examples/httpd/examples_fs/session.html	(revision 457)
@@ -0,0 +1,25 @@
+<html>
+<head><title>lwIP - A Lightweight TCP/IP Stack</title></head>
+<body bgcolor="white" text="black">
+
+ <table width="100%">
+  <tr valign="top">
+   <td width="80">
+    <a href="http://www.sics.se/"><img src="/img/sics.gif" border="0" alt="SICS logo" title="SICS logo"/></a>
+   </td>
+   <td width="500">
+    <h1>lwIP - A Lightweight TCP/IP Stack</h1>
+    <p>
+     Login succeeded, session active.
+    </p>
+    <p>
+     Click <a href="login.html">here</a> to retry login.
+    </p>
+   </td>
+   <td>
+    &nbsp;
+   </td>
+  </tr>
+ </table>
+</body>
+</html>
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/examples/httpd/examples_fs/ssi.shtml
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/examples/httpd/examples_fs/ssi.shtml	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/examples/httpd/examples_fs/ssi.shtml	(revision 457)
@@ -0,0 +1,315 @@
+<html>
+<head><title>lwIP - A Lightweight TCP/IP Stack</title></head>
+<body bgcolor="white" text="black">
+
+    <table width="100%">
+      <tr valign="top"><td width="80">	  
+	  <a href="http://www.sics.se/"><img src="/img/sics.gif"
+	  border="0" alt="SICS logo" title="SICS logo"></a>
+	</td><td width="500">	  
+	  <h1>lwIP - A Lightweight TCP/IP Stack</h1>
+	  <h1><!--#HellWorl--></h1>
+	  <p>
+	    The web page you are watching was served by a simple web
+	    server running on top of the lightweight TCP/IP stack <a
+	    href="http://www.sics.se/~adam/lwip/">lwIP</a>.
+	  </p>
+	  <p>
+	    This page is here to test SSI, so here is a counter as
+	    an example of content changing for every request:
+	    "<!--#counter-->"
+	  </p>
+	  <p>
+	    And here is an example of a tag result buffer return in
+	    multiple parts: "<!--#MultPart-->"
+	  </p>
+	  <p>
+	    To test LWIP_HTTPD_CGI_SSI, here are the CGI parameters:
+	    <!--#CgiParam-->
+	  </p>
+	  <p>
+	    lwIP is an open source implementation of the TCP/IP
+	    protocol suite that was originally written by <a
+	    href="http://www.sics.se/~adam/lwip/">Adam Dunkels
+	    of the Swedish Institute of Computer Science</a> but now is
+	    being actively developed by a team of developers
+	    distributed world-wide. Since it's release, lwIP has
+	    spurred a lot of interest and has been ported to several
+	    platforms and operating systems. lwIP can be used either
+	    with or without an underlying OS.
+	  </p>
+	  <p>
+	  <p>
+	    lwIP is an open source implementation of the TCP/IP
+	    protocol suite that was originally written by <a
+	    href="http://www.sics.se/~adam/lwip/">Adam Dunkels
+	    of the Swedish Institute of Computer Science</a> but now is
+	    being actively developed by a team of developers
+	    distributed world-wide. Since it's release, lwIP has
+	    spurred a lot of interest and has been ported to several
+	    platforms and operating systems. lwIP can be used either
+	    with or without an underlying OS.
+	  </p>
+	  <p>
+	    lwIP is an open source implementation of the TCP/IP
+	    protocol suite that was originally written by <a
+	    href="http://www.sics.se/~adam/lwip/">Adam Dunkels
+	    of the Swedish Institute of Computer Science</a> but now is
+	    being actively developed by a team of developers
+	    distributed world-wide. Since it's release, lwIP has
+	    spurred a lot of interest and has been ported to several
+	    platforms and operating systems. lwIP can be used either
+	    with or without an underlying OS.
+	  </p>
+	  <p>
+	    lwIP is an open source implementation of the TCP/IP
+	    protocol suite that was originally written by <a
+	    href="http://www.sics.se/~adam/lwip/">Adam Dunkels
+	    of the Swedish Institute of Computer Science</a> but now is
+	    being actively developed by a team of developers
+	    distributed world-wide. Since it's release, lwIP has
+	    spurred a lot of interest and has been ported to several
+	    platforms and operating systems. lwIP can be used either
+	    with or without an underlying OS.
+	  </p>
+	  <p>
+	    lwIP is an open source implementation of the TCP/IP
+	    protocol suite that was originally written by <a
+	    href="http://www.sics.se/~adam/lwip/">Adam Dunkels
+	    of the Swedish Institute of Computer Science</a> but now is
+	    being actively developed by a team of developers
+	    distributed world-wide. Since it's release, lwIP has
+	    spurred a lot of interest and has been ported to several
+	    platforms and operating systems. lwIP can be used either
+	    with or without an underlying OS.
+	  </p>
+	  <p>
+	    lwIP is an open source implementation of the TCP/IP
+	    protocol suite that was originally written by <a
+	    href="http://www.sics.se/~adam/lwip/">Adam Dunkels
+	    of the Swedish Institute of Computer Science</a> but now is
+	    being actively developed by a team of developers
+	    distributed world-wide. Since it's release, lwIP has
+	    spurred a lot of interest and has been ported to several
+	    platforms and operating systems. lwIP can be used either
+	    with or without an underlying OS.
+	  </p>
+	  <p>
+	    lwIP is an open source implementation of the TCP/IP
+	    protocol suite that was originally written by <a
+	    href="http://www.sics.se/~adam/lwip/">Adam Dunkels
+	    of the Swedish Institute of Computer Science</a> but now is
+	    being actively developed by a team of developers
+	    distributed world-wide. Since it's release, lwIP has
+	    spurred a lot of interest and has been ported to several
+	    platforms and operating systems. lwIP can be used either
+	    with or without an underlying OS.
+	  </p>
+	  <p>
+	    lwIP is an open source implementation of the TCP/IP
+	    protocol suite that was originally written by <a
+	    href="http://www.sics.se/~adam/lwip/">Adam Dunkels
+	    of the Swedish Institute of Computer Science</a> but now is
+	    being actively developed by a team of developers
+	    distributed world-wide. Since it's release, lwIP has
+	    spurred a lot of interest and has been ported to several
+	    platforms and operating systems. lwIP can be used either
+	    with or without an underlying OS.
+	  </p>
+	  <p>
+	    lwIP is an open source implementation of the TCP/IP
+	    protocol suite that was originally written by <a
+	    href="http://www.sics.se/~adam/lwip/">Adam Dunkels
+	    of the Swedish Institute of Computer Science</a> but now is
+	    being actively developed by a team of developers
+	    distributed world-wide. Since it's release, lwIP has
+	    spurred a lot of interest and has been ported to several
+	    platforms and operating systems. lwIP can be used either
+	    with or without an underlying OS.
+	  </p>
+	  <p>
+	    lwIP is an open source implementation of the TCP/IP
+	    protocol suite that was originally written by <a
+	    href="http://www.sics.se/~adam/lwip/">Adam Dunkels
+	    of the Swedish Institute of Computer Science</a> but now is
+	    being actively developed by a team of developers
+	    distributed world-wide. Since it's release, lwIP has
+	    spurred a lot of interest and has been ported to several
+	    platforms and operating systems. lwIP can be used either
+	    with or without an underlying OS.
+	  </p>
+	  <p>
+	    lwIP is an open source implementation of the TCP/IP
+	    protocol suite that was originally written by <a
+	    href="http://www.sics.se/~adam/lwip/">Adam Dunkels
+	    of the Swedish Institute of Computer Science</a> but now is
+	    being actively developed by a team of developers
+	    distributed world-wide. Since it's release, lwIP has
+	    spurred a lot of interest and has been ported to several
+	    platforms and operating systems. lwIP can be used either
+	    with or without an underlying OS.
+	  </p>
+	  <p>
+	    lwIP is an open source implementation of the TCP/IP
+	    protocol suite that was originally written by <a
+	    href="http://www.sics.se/~adam/lwip/">Adam Dunkels
+	    of the Swedish Institute of Computer Science</a> but now is
+	    being actively developed by a team of developers
+	    distributed world-wide. Since it's release, lwIP has
+	    spurred a lot of interest and has been ported to several
+	    platforms and operating systems. lwIP can be used either
+	    with or without an underlying OS.
+	  </p>
+	  <p>
+	    lwIP is an open source implementation of the TCP/IP
+	    protocol suite that was originally written by <a
+	    href="http://www.sics.se/~adam/lwip/">Adam Dunkels
+	    of the Swedish Institute of Computer Science</a> but now is
+	    being actively developed by a team of developers
+	    distributed world-wide. Since it's release, lwIP has
+	    spurred a lot of interest and has been ported to several
+	    platforms and operating systems. lwIP can be used either
+	    with or without an underlying OS.
+	  </p>
+	  <p>
+	    lwIP is an open source implementation of the TCP/IP
+	    protocol suite that was originally written by <a
+	    href="http://www.sics.se/~adam/lwip/">Adam Dunkels
+	    of the Swedish Institute of Computer Science</a> but now is
+	    being actively developed by a team of developers
+	    distributed world-wide. Since it's release, lwIP has
+	    spurred a lot of interest and has been ported to several
+	    platforms and operating systems. lwIP can be used either
+	    with or without an underlying OS.
+	  </p>
+	  <p>
+	    lwIP is an open source implementation of the TCP/IP
+	    protocol suite that was originally written by <a
+	    href="http://www.sics.se/~adam/lwip/">Adam Dunkels
+	    of the Swedish Institute of Computer Science</a> but now is
+	    being actively developed by a team of developers
+	    distributed world-wide. Since it's release, lwIP has
+	    spurred a lot of interest and has been ported to several
+	    platforms and operating systems. lwIP can be used either
+	    with or without an underlying OS.
+	  </p>
+	  <p>
+	    lwIP is an open source implementation of the TCP/IP
+	    protocol suite that was originally written by <a
+	    href="http://www.sics.se/~adam/lwip/">Adam Dunkels
+	    of the Swedish Institute of Computer Science</a> but now is
+	    being actively developed by a team of developers
+	    distributed world-wide. Since it's release, lwIP has
+	    spurred a lot of interest and has been ported to several
+	    platforms and operating systems. lwIP can be used either
+	    with or without an underlying OS.
+	  </p>
+	  <p>
+	    lwIP is an open source implementation of the TCP/IP
+	    protocol suite that was originally written by <a
+	    href="http://www.sics.se/~adam/lwip/">Adam Dunkels
+	    of the Swedish Institute of Computer Science</a> but now is
+	    being actively developed by a team of developers
+	    distributed world-wide. Since it's release, lwIP has
+	    spurred a lot of interest and has been ported to several
+	    platforms and operating systems. lwIP can be used either
+	    with or without an underlying OS.
+	  </p>
+	  <p>
+	    lwIP is an open source implementation of the TCP/IP
+	    protocol suite that was originally written by <a
+	    href="http://www.sics.se/~adam/lwip/">Adam Dunkels
+	    of the Swedish Institute of Computer Science</a> but now is
+	    being actively developed by a team of developers
+	    distributed world-wide. Since it's release, lwIP has
+	    spurred a lot of interest and has been ported to several
+	    platforms and operating systems. lwIP can be used either
+	    with or without an underlying OS.
+	  </p>
+	  <p>
+	    lwIP is an open source implementation of the TCP/IP
+	    protocol suite that was originally written by <a
+	    href="http://www.sics.se/~adam/lwip/">Adam Dunkels
+	    of the Swedish Institute of Computer Science</a> but now is
+	    being actively developed by a team of developers
+	    distributed world-wide. Since it's release, lwIP has
+	    spurred a lot of interest and has been ported to several
+	    platforms and operating systems. lwIP can be used either
+	    with or without an underlying OS.
+	  </p>
+	  <p>
+	    lwIP is an open source implementation of the TCP/IP
+	    protocol suite that was originally written by <a
+	    href="http://www.sics.se/~adam/lwip/">Adam Dunkels
+	    of the Swedish Institute of Computer Science</a> but now is
+	    being actively developed by a team of developers
+	    distributed world-wide. Since it's release, lwIP has
+	    spurred a lot of interest and has been ported to several
+	    platforms and operating systems. lwIP can be used either
+	    with or without an underlying OS.
+	  </p>
+	  <p>
+	    lwIP is an open source implementation of the TCP/IP
+	    protocol suite that was originally written by <a
+	    href="http://www.sics.se/~adam/lwip/">Adam Dunkels
+	    of the Swedish Institute of Computer Science</a> but now is
+	    being actively developed by a team of developers
+	    distributed world-wide. Since it's release, lwIP has
+	    spurred a lot of interest and has been ported to several
+	    platforms and operating systems. lwIP can be used either
+	    with or without an underlying OS.
+	  </p>
+	  <p>
+	    lwIP is an open source implementation of the TCP/IP
+	    protocol suite that was originally written by <a
+	    href="http://www.sics.se/~adam/lwip/">Adam Dunkels
+	    of the Swedish Institute of Computer Science</a> but now is
+	    being actively developed by a team of developers
+	    distributed world-wide. Since it's release, lwIP has
+	    spurred a lot of interest and has been ported to several
+	    platforms and operating systems. lwIP can be used either
+	    with or without an underlying OS.
+	  </p>
+	  <p>
+	    lwIP is an open source implementation of the TCP/IP
+	    protocol suite that was originally written by <a
+	    href="http://www.sics.se/~adam/lwip/">Adam Dunkels
+	    of the Swedish Institute of Computer Science</a> but now is
+	    being actively developed by a team of developers
+	    distributed world-wide. Since it's release, lwIP has
+	    spurred a lot of interest and has been ported to several
+	    platforms and operating systems. lwIP can be used either
+	    with or without an underlying OS.
+	  </p>
+	  <p>
+	    lwIP is an open source implementation of the TCP/IP
+	    protocol suite that was originally written by <a
+	    href="http://www.sics.se/~adam/lwip/">Adam Dunkels
+	    of the Swedish Institute of Computer Science</a> but now is
+	    being actively developed by a team of developers
+	    distributed world-wide. Since it's release, lwIP has
+	    spurred a lot of interest and has been ported to several
+	    platforms and operating systems. lwIP can be used either
+	    with or without an underlying OS.
+	  </p>
+	  <p>
+	    The focus of the lwIP TCP/IP implementation is to reduce
+	    the RAM usage while still having a full scale TCP. This
+	    makes lwIP suitable for use in embedded systems with tens
+	    of kilobytes of free RAM and room for around 40 kilobytes
+	    of code ROM.
+	  </p>
+	  <p>
+	    More information about lwIP can be found at the lwIP
+	    homepage at <a
+	    href="http://savannah.nongnu.org/projects/lwip/">http://savannah.nongnu.org/projects/lwip/</a>
+	    or at the lwIP wiki at <a
+	    href="http://lwip.wikia.com/">http://lwip.wikia.com/</a>.
+	  </p>
+	</td><td>
+	  &nbsp;
+	</td></tr>
+      </table>
+</body>
+</html>
+
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/examples/httpd/examples_fsdata.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/examples/httpd/examples_fsdata.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/examples/httpd/examples_fsdata.c	(revision 457)
@@ -0,0 +1,1543 @@
+#include "lwip/apps/fs.h"
+#include "lwip/def.h"
+
+
+#define file_NULL (struct fsdata_file *) NULL
+
+
+#ifndef FS_FILE_FLAGS_HEADER_INCLUDED
+#define FS_FILE_FLAGS_HEADER_INCLUDED 1
+#endif
+#ifndef FS_FILE_FLAGS_HEADER_PERSISTENT
+#define FS_FILE_FLAGS_HEADER_PERSISTENT 0
+#endif
+/* FSDATA_FILE_ALIGNMENT: 0=off, 1=by variable, 2=by include */
+#ifndef FSDATA_FILE_ALIGNMENT
+#define FSDATA_FILE_ALIGNMENT 0
+#endif
+#ifndef FSDATA_ALIGN_PRE
+#define FSDATA_ALIGN_PRE
+#endif
+#ifndef FSDATA_ALIGN_POST
+#define FSDATA_ALIGN_POST
+#endif
+#if FSDATA_FILE_ALIGNMENT==2
+#include "fsdata_alignment.h"
+#endif
+#if FSDATA_FILE_ALIGNMENT==1
+static const unsigned int dummy_align__img_sics_gif = 0;
+#endif
+static const unsigned char FSDATA_ALIGN_PRE data__img_sics_gif[] FSDATA_ALIGN_POST = {
+/* /img/sics.gif (14 chars) */
+0x2f,0x69,0x6d,0x67,0x2f,0x73,0x69,0x63,0x73,0x2e,0x67,0x69,0x66,0x00,0x00,0x00,
+
+/* HTTP header */
+/* "HTTP/1.1 200 OK
+" (17 bytes) */
+0x48,0x54,0x54,0x50,0x2f,0x31,0x2e,0x31,0x20,0x32,0x30,0x30,0x20,0x4f,0x4b,0x0d,
+0x0a,
+/* "Server: lwIP/2.0.3d (http://savannah.nongnu.org/projects/lwip)
+" (64 bytes) */
+0x53,0x65,0x72,0x76,0x65,0x72,0x3a,0x20,0x6c,0x77,0x49,0x50,0x2f,0x32,0x2e,0x30,
+0x2e,0x33,0x64,0x20,0x28,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x73,0x61,0x76,0x61,
+0x6e,0x6e,0x61,0x68,0x2e,0x6e,0x6f,0x6e,0x67,0x6e,0x75,0x2e,0x6f,0x72,0x67,0x2f,
+0x70,0x72,0x6f,0x6a,0x65,0x63,0x74,0x73,0x2f,0x6c,0x77,0x69,0x70,0x29,0x0d,0x0a,
+
+/* "Content-Length: 724
+" (18+ bytes) */
+0x43,0x6f,0x6e,0x74,0x65,0x6e,0x74,0x2d,0x4c,0x65,0x6e,0x67,0x74,0x68,0x3a,0x20,
+0x37,0x32,0x34,0x0d,0x0a,
+/* "Connection: keep-alive
+" (24 bytes) */
+0x43,0x6f,0x6e,0x6e,0x65,0x63,0x74,0x69,0x6f,0x6e,0x3a,0x20,0x6b,0x65,0x65,0x70,
+0x2d,0x61,0x6c,0x69,0x76,0x65,0x0d,0x0a,
+/* "Content-Type: image/gif
+
+" (27 bytes) */
+0x43,0x6f,0x6e,0x74,0x65,0x6e,0x74,0x2d,0x54,0x79,0x70,0x65,0x3a,0x20,0x69,0x6d,
+0x61,0x67,0x65,0x2f,0x67,0x69,0x66,0x0d,0x0a,0x0d,0x0a,
+/* raw file data (724 bytes) */
+0x47,0x49,0x46,0x38,0x39,0x61,0x46,0x00,0x22,0x00,0xa5,0x00,0x00,0xd9,0x2b,0x39,
+0x6a,0x6a,0x6a,0xbf,0xbf,0xbf,0x93,0x93,0x93,0x0f,0x0f,0x0f,0xb0,0xb0,0xb0,0xa6,
+0xa6,0xa6,0x80,0x80,0x80,0x76,0x76,0x76,0x1e,0x1e,0x1e,0x9d,0x9d,0x9d,0x2e,0x2e,
+0x2e,0x49,0x49,0x49,0x54,0x54,0x54,0x8a,0x8a,0x8a,0x60,0x60,0x60,0xc6,0xa6,0x99,
+0xbd,0xb5,0xb2,0xc2,0xab,0xa1,0xd9,0x41,0x40,0xd5,0x67,0x55,0xc0,0xb0,0xaa,0xd5,
+0x5e,0x4e,0xd6,0x50,0x45,0xcc,0x93,0x7d,0xc8,0xa1,0x90,0xce,0x8b,0x76,0xd2,0x7b,
+0x65,0xd1,0x84,0x6d,0xc9,0x99,0x86,0x3a,0x3a,0x3a,0x00,0x00,0x00,0xb8,0xb8,0xb8,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x2c,0x00,0x00,
+0x00,0x00,0x46,0x00,0x22,0x00,0x00,0x06,0xfe,0x40,0x90,0x70,0x48,0x2c,0x1a,0x8f,
+0xc8,0xa4,0x72,0xc9,0x6c,0x3a,0x9f,0xd0,0xa8,0x74,0x4a,0xad,0x5a,0xaf,0xd8,0xac,
+0x76,0xa9,0x40,0x04,0xbe,0x83,0xe2,0x60,0x3c,0x50,0x20,0x0d,0x8e,0x6f,0x00,0x31,
+0x28,0x1c,0x0d,0x07,0xb5,0xc3,0x60,0x75,0x24,0x3e,0xf8,0xfc,0x87,0x11,0x06,0xe9,
+0x3d,0x46,0x07,0x0b,0x7a,0x7a,0x7c,0x43,0x06,0x1e,0x84,0x78,0x0b,0x07,0x6e,0x51,
+0x01,0x8a,0x84,0x08,0x7e,0x79,0x80,0x87,0x89,0x91,0x7a,0x93,0x0a,0x04,0x99,0x78,
+0x96,0x4f,0x03,0x9e,0x79,0x01,0x94,0x9f,0x43,0x9c,0xa3,0xa4,0x05,0x77,0xa3,0xa0,
+0x4e,0x98,0x79,0x0b,0x1e,0x83,0xa4,0xa6,0x1f,0x96,0x05,0x9d,0xaa,0x78,0x01,0x07,
+0x84,0x04,0x1e,0x1e,0xbb,0xb8,0x51,0x84,0x0e,0x43,0x05,0x07,0x77,0xa5,0x7f,0x42,
+0xb1,0xb2,0x01,0x63,0x08,0x0d,0xbb,0x01,0x0c,0x7a,0x0d,0x44,0x0e,0xd8,0xaf,0x4c,
+0x05,0x7a,0x04,0x47,0x07,0x07,0xb7,0x80,0xa2,0xe1,0x7d,0x44,0x05,0x01,0x04,0x01,
+0xd0,0xea,0x87,0x93,0x4f,0xe0,0x9a,0x49,0xce,0xd8,0x79,0x04,0x66,0x20,0x15,0x10,
+0x10,0x11,0x92,0x29,0x80,0xb6,0xc0,0x91,0x15,0x45,0x1e,0x90,0x19,0x71,0x46,0xa8,
+0x5c,0x04,0x0e,0x00,0x22,0x4e,0xe8,0x40,0x24,0x9f,0x3e,0x04,0x06,0xa7,0x58,0xd4,
+0x93,0xa0,0x1c,0x91,0x3f,0xe8,0xf0,0x88,0x03,0xb1,0x21,0xa2,0x49,0x00,0x19,0x86,
+0xfc,0x52,0x44,0xe0,0x01,0x9d,0x29,0x21,0x15,0x25,0x50,0xf7,0x67,0x25,0x1e,0x06,
+0xfd,0x4e,0x9a,0xb4,0x90,0xac,0x15,0xfa,0xcb,0x52,0x53,0x1e,0x8c,0xf2,0xf8,0x07,
+0x92,0x2d,0x08,0x3a,0x4d,0x12,0x49,0x95,0x49,0xdb,0x14,0x04,0xc4,0x14,0x85,0x29,
+0xaa,0xe7,0x01,0x08,0xa4,0x49,0x01,0x14,0x51,0xe0,0x53,0x91,0xd5,0x29,0x06,0x1a,
+0x64,0x02,0xf4,0xc7,0x81,0x9e,0x05,0x20,0x22,0x64,0xa5,0x30,0xae,0xab,0x9e,0x97,
+0x53,0xd8,0xb9,0xfd,0x50,0xef,0x93,0x02,0x42,0x74,0x34,0xe8,0x9c,0x20,0x21,0xc9,
+0x01,0x68,0x78,0xe6,0x55,0x29,0x20,0x56,0x4f,0x4c,0x40,0x51,0x71,0x82,0xc0,0x70,
+0x21,0x22,0x85,0xbe,0x4b,0x1c,0x44,0x05,0xea,0xa4,0x01,0xbf,0x22,0xb5,0xf0,0x1c,
+0x06,0x51,0x38,0x8f,0xe0,0x22,0xec,0x18,0xac,0x39,0x22,0xd4,0xd6,0x93,0x44,0x01,
+0x32,0x82,0xc8,0xfc,0x61,0xb3,0x01,0x45,0x0c,0x2e,0x83,0x30,0xd0,0x0e,0x17,0x24,
+0x0f,0x70,0x85,0x94,0xee,0x05,0x05,0x53,0x4b,0x32,0x1b,0x3f,0x98,0xd3,0x1d,0x29,
+0x81,0xb0,0xae,0x1e,0x8c,0x7e,0x68,0xe0,0x60,0x5a,0x54,0x8f,0xb0,0x78,0x69,0x73,
+0x06,0xa2,0x00,0x6b,0x57,0xca,0x3d,0x11,0x50,0xbd,0x04,0x30,0x4b,0x3a,0xd4,0xab,
+0x5f,0x1f,0x9b,0x3d,0x13,0x74,0x27,0x88,0x3c,0x25,0xe0,0x17,0xbe,0x7a,0x79,0x45,
+0x0d,0x0c,0xb0,0x8b,0xda,0x90,0xca,0x80,0x06,0x5d,0x17,0x60,0x1c,0x22,0x4c,0xd8,
+0x57,0x22,0x06,0x20,0x00,0x98,0x07,0x08,0xe4,0x56,0x80,0x80,0x1c,0xc5,0xb7,0xc5,
+0x82,0x0c,0x36,0xe8,0xe0,0x83,0x10,0x46,0x28,0xe1,0x84,0x14,0x56,0x68,0xa1,0x10,
+0x41,0x00,0x00,0x3b,};
+
+#if FSDATA_FILE_ALIGNMENT==1
+static const unsigned int dummy_align__404_html = 1;
+#endif
+static const unsigned char FSDATA_ALIGN_PRE data__404_html[] FSDATA_ALIGN_POST = {
+/* /404.html (10 chars) */
+0x2f,0x34,0x30,0x34,0x2e,0x68,0x74,0x6d,0x6c,0x00,0x00,0x00,
+
+/* HTTP header */
+/* "HTTP/1.1 404 File not found
+" (29 bytes) */
+0x48,0x54,0x54,0x50,0x2f,0x31,0x2e,0x31,0x20,0x34,0x30,0x34,0x20,0x46,0x69,0x6c,
+0x65,0x20,0x6e,0x6f,0x74,0x20,0x66,0x6f,0x75,0x6e,0x64,0x0d,0x0a,
+/* "Server: lwIP/2.0.3d (http://savannah.nongnu.org/projects/lwip)
+" (64 bytes) */
+0x53,0x65,0x72,0x76,0x65,0x72,0x3a,0x20,0x6c,0x77,0x49,0x50,0x2f,0x32,0x2e,0x30,
+0x2e,0x33,0x64,0x20,0x28,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x73,0x61,0x76,0x61,
+0x6e,0x6e,0x61,0x68,0x2e,0x6e,0x6f,0x6e,0x67,0x6e,0x75,0x2e,0x6f,0x72,0x67,0x2f,
+0x70,0x72,0x6f,0x6a,0x65,0x63,0x74,0x73,0x2f,0x6c,0x77,0x69,0x70,0x29,0x0d,0x0a,
+
+/* "Content-Length: 565
+" (18+ bytes) */
+0x43,0x6f,0x6e,0x74,0x65,0x6e,0x74,0x2d,0x4c,0x65,0x6e,0x67,0x74,0x68,0x3a,0x20,
+0x35,0x36,0x35,0x0d,0x0a,
+/* "Connection: keep-alive
+" (24 bytes) */
+0x43,0x6f,0x6e,0x6e,0x65,0x63,0x74,0x69,0x6f,0x6e,0x3a,0x20,0x6b,0x65,0x65,0x70,
+0x2d,0x61,0x6c,0x69,0x76,0x65,0x0d,0x0a,
+/* "Content-Type: text/html
+
+" (27 bytes) */
+0x43,0x6f,0x6e,0x74,0x65,0x6e,0x74,0x2d,0x54,0x79,0x70,0x65,0x3a,0x20,0x74,0x65,
+0x78,0x74,0x2f,0x68,0x74,0x6d,0x6c,0x0d,0x0a,0x0d,0x0a,
+/* raw file data (565 bytes) */
+0x3c,0x68,0x74,0x6d,0x6c,0x3e,0x0d,0x0a,0x3c,0x68,0x65,0x61,0x64,0x3e,0x3c,0x74,
+0x69,0x74,0x6c,0x65,0x3e,0x6c,0x77,0x49,0x50,0x20,0x2d,0x20,0x41,0x20,0x4c,0x69,
+0x67,0x68,0x74,0x77,0x65,0x69,0x67,0x68,0x74,0x20,0x54,0x43,0x50,0x2f,0x49,0x50,
+0x20,0x53,0x74,0x61,0x63,0x6b,0x3c,0x2f,0x74,0x69,0x74,0x6c,0x65,0x3e,0x3c,0x2f,
+0x68,0x65,0x61,0x64,0x3e,0x0d,0x0a,0x3c,0x62,0x6f,0x64,0x79,0x20,0x62,0x67,0x63,
+0x6f,0x6c,0x6f,0x72,0x3d,0x22,0x77,0x68,0x69,0x74,0x65,0x22,0x20,0x74,0x65,0x78,
+0x74,0x3d,0x22,0x62,0x6c,0x61,0x63,0x6b,0x22,0x3e,0x0d,0x0a,0x0d,0x0a,0x20,0x20,
+0x20,0x20,0x3c,0x74,0x61,0x62,0x6c,0x65,0x20,0x77,0x69,0x64,0x74,0x68,0x3d,0x22,
+0x31,0x30,0x30,0x25,0x22,0x3e,0x0d,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x3c,0x74,
+0x72,0x20,0x76,0x61,0x6c,0x69,0x67,0x6e,0x3d,0x22,0x74,0x6f,0x70,0x22,0x3e,0x3c,
+0x74,0x64,0x20,0x77,0x69,0x64,0x74,0x68,0x3d,0x22,0x38,0x30,0x22,0x3e,0x09,0x20,
+0x20,0x0d,0x0a,0x09,0x20,0x20,0x3c,0x61,0x20,0x68,0x72,0x65,0x66,0x3d,0x22,0x68,
+0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77,0x77,0x77,0x2e,0x73,0x69,0x63,0x73,0x2e,0x73,
+0x65,0x2f,0x22,0x3e,0x3c,0x69,0x6d,0x67,0x20,0x73,0x72,0x63,0x3d,0x22,0x2f,0x69,
+0x6d,0x67,0x2f,0x73,0x69,0x63,0x73,0x2e,0x67,0x69,0x66,0x22,0x0d,0x0a,0x09,0x20,
+0x20,0x62,0x6f,0x72,0x64,0x65,0x72,0x3d,0x22,0x30,0x22,0x20,0x61,0x6c,0x74,0x3d,
+0x22,0x53,0x49,0x43,0x53,0x20,0x6c,0x6f,0x67,0x6f,0x22,0x20,0x74,0x69,0x74,0x6c,
+0x65,0x3d,0x22,0x53,0x49,0x43,0x53,0x20,0x6c,0x6f,0x67,0x6f,0x22,0x3e,0x3c,0x2f,
+0x61,0x3e,0x0d,0x0a,0x09,0x3c,0x2f,0x74,0x64,0x3e,0x3c,0x74,0x64,0x20,0x77,0x69,
+0x64,0x74,0x68,0x3d,0x22,0x35,0x30,0x30,0x22,0x3e,0x09,0x20,0x20,0x0d,0x0a,0x09,
+0x20,0x20,0x3c,0x68,0x31,0x3e,0x6c,0x77,0x49,0x50,0x20,0x2d,0x20,0x41,0x20,0x4c,
+0x69,0x67,0x68,0x74,0x77,0x65,0x69,0x67,0x68,0x74,0x20,0x54,0x43,0x50,0x2f,0x49,
+0x50,0x20,0x53,0x74,0x61,0x63,0x6b,0x3c,0x2f,0x68,0x31,0x3e,0x0d,0x0a,0x09,0x20,
+0x20,0x3c,0x68,0x32,0x3e,0x34,0x30,0x34,0x20,0x2d,0x20,0x50,0x61,0x67,0x65,0x20,
+0x6e,0x6f,0x74,0x20,0x66,0x6f,0x75,0x6e,0x64,0x3c,0x2f,0x68,0x32,0x3e,0x0d,0x0a,
+0x09,0x20,0x20,0x3c,0x70,0x3e,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x53,0x6f,0x72,
+0x72,0x79,0x2c,0x20,0x74,0x68,0x65,0x20,0x70,0x61,0x67,0x65,0x20,0x79,0x6f,0x75,
+0x20,0x61,0x72,0x65,0x20,0x72,0x65,0x71,0x75,0x65,0x73,0x74,0x69,0x6e,0x67,0x20,
+0x77,0x61,0x73,0x20,0x6e,0x6f,0x74,0x20,0x66,0x6f,0x75,0x6e,0x64,0x20,0x6f,0x6e,
+0x20,0x74,0x68,0x69,0x73,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x73,0x65,0x72,0x76,
+0x65,0x72,0x2e,0x20,0x0d,0x0a,0x09,0x20,0x20,0x3c,0x2f,0x70,0x3e,0x0d,0x0a,0x09,
+0x3c,0x2f,0x74,0x64,0x3e,0x3c,0x74,0x64,0x3e,0x0d,0x0a,0x09,0x20,0x20,0x26,0x6e,
+0x62,0x73,0x70,0x3b,0x0d,0x0a,0x09,0x3c,0x2f,0x74,0x64,0x3e,0x3c,0x2f,0x74,0x72,
+0x3e,0x0d,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x3c,0x2f,0x74,0x61,0x62,0x6c,0x65,
+0x3e,0x0d,0x0a,0x3c,0x2f,0x62,0x6f,0x64,0x79,0x3e,0x0d,0x0a,0x3c,0x2f,0x68,0x74,
+0x6d,0x6c,0x3e,0x0d,0x0a,};
+
+#if FSDATA_FILE_ALIGNMENT==1
+static const unsigned int dummy_align__index_html = 2;
+#endif
+static const unsigned char FSDATA_ALIGN_PRE data__index_html[] FSDATA_ALIGN_POST = {
+/* /index.html (12 chars) */
+0x2f,0x69,0x6e,0x64,0x65,0x78,0x2e,0x68,0x74,0x6d,0x6c,0x00,
+
+/* HTTP header */
+/* "HTTP/1.1 200 OK
+" (17 bytes) */
+0x48,0x54,0x54,0x50,0x2f,0x31,0x2e,0x31,0x20,0x32,0x30,0x30,0x20,0x4f,0x4b,0x0d,
+0x0a,
+/* "Server: lwIP/2.0.3d (http://savannah.nongnu.org/projects/lwip)
+" (64 bytes) */
+0x53,0x65,0x72,0x76,0x65,0x72,0x3a,0x20,0x6c,0x77,0x49,0x50,0x2f,0x32,0x2e,0x30,
+0x2e,0x33,0x64,0x20,0x28,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x73,0x61,0x76,0x61,
+0x6e,0x6e,0x61,0x68,0x2e,0x6e,0x6f,0x6e,0x67,0x6e,0x75,0x2e,0x6f,0x72,0x67,0x2f,
+0x70,0x72,0x6f,0x6a,0x65,0x63,0x74,0x73,0x2f,0x6c,0x77,0x69,0x70,0x29,0x0d,0x0a,
+
+/* "Content-Length: 1751
+" (18+ bytes) */
+0x43,0x6f,0x6e,0x74,0x65,0x6e,0x74,0x2d,0x4c,0x65,0x6e,0x67,0x74,0x68,0x3a,0x20,
+0x31,0x37,0x35,0x31,0x0d,0x0a,
+/* "Connection: keep-alive
+" (24 bytes) */
+0x43,0x6f,0x6e,0x6e,0x65,0x63,0x74,0x69,0x6f,0x6e,0x3a,0x20,0x6b,0x65,0x65,0x70,
+0x2d,0x61,0x6c,0x69,0x76,0x65,0x0d,0x0a,
+/* "Content-Type: text/html
+
+" (27 bytes) */
+0x43,0x6f,0x6e,0x74,0x65,0x6e,0x74,0x2d,0x54,0x79,0x70,0x65,0x3a,0x20,0x74,0x65,
+0x78,0x74,0x2f,0x68,0x74,0x6d,0x6c,0x0d,0x0a,0x0d,0x0a,
+/* raw file data (1751 bytes) */
+0x3c,0x68,0x74,0x6d,0x6c,0x3e,0x0d,0x0a,0x3c,0x68,0x65,0x61,0x64,0x3e,0x3c,0x74,
+0x69,0x74,0x6c,0x65,0x3e,0x6c,0x77,0x49,0x50,0x20,0x2d,0x20,0x41,0x20,0x4c,0x69,
+0x67,0x68,0x74,0x77,0x65,0x69,0x67,0x68,0x74,0x20,0x54,0x43,0x50,0x2f,0x49,0x50,
+0x20,0x53,0x74,0x61,0x63,0x6b,0x3c,0x2f,0x74,0x69,0x74,0x6c,0x65,0x3e,0x3c,0x2f,
+0x68,0x65,0x61,0x64,0x3e,0x0d,0x0a,0x3c,0x62,0x6f,0x64,0x79,0x20,0x62,0x67,0x63,
+0x6f,0x6c,0x6f,0x72,0x3d,0x22,0x77,0x68,0x69,0x74,0x65,0x22,0x20,0x74,0x65,0x78,
+0x74,0x3d,0x22,0x62,0x6c,0x61,0x63,0x6b,0x22,0x3e,0x0d,0x0a,0x0d,0x0a,0x20,0x20,
+0x20,0x20,0x3c,0x74,0x61,0x62,0x6c,0x65,0x20,0x77,0x69,0x64,0x74,0x68,0x3d,0x22,
+0x31,0x30,0x30,0x25,0x22,0x3e,0x0d,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x3c,0x74,
+0x72,0x20,0x76,0x61,0x6c,0x69,0x67,0x6e,0x3d,0x22,0x74,0x6f,0x70,0x22,0x3e,0x3c,
+0x74,0x64,0x20,0x77,0x69,0x64,0x74,0x68,0x3d,0x22,0x38,0x30,0x22,0x3e,0x09,0x20,
+0x20,0x0d,0x0a,0x09,0x20,0x20,0x3c,0x61,0x20,0x68,0x72,0x65,0x66,0x3d,0x22,0x68,
+0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77,0x77,0x77,0x2e,0x73,0x69,0x63,0x73,0x2e,0x73,
+0x65,0x2f,0x22,0x3e,0x3c,0x69,0x6d,0x67,0x20,0x73,0x72,0x63,0x3d,0x22,0x2f,0x69,
+0x6d,0x67,0x2f,0x73,0x69,0x63,0x73,0x2e,0x67,0x69,0x66,0x22,0x0d,0x0a,0x09,0x20,
+0x20,0x62,0x6f,0x72,0x64,0x65,0x72,0x3d,0x22,0x30,0x22,0x20,0x61,0x6c,0x74,0x3d,
+0x22,0x53,0x49,0x43,0x53,0x20,0x6c,0x6f,0x67,0x6f,0x22,0x20,0x74,0x69,0x74,0x6c,
+0x65,0x3d,0x22,0x53,0x49,0x43,0x53,0x20,0x6c,0x6f,0x67,0x6f,0x22,0x3e,0x3c,0x2f,
+0x61,0x3e,0x0d,0x0a,0x09,0x3c,0x2f,0x74,0x64,0x3e,0x3c,0x74,0x64,0x20,0x77,0x69,
+0x64,0x74,0x68,0x3d,0x22,0x35,0x30,0x30,0x22,0x3e,0x09,0x20,0x20,0x0d,0x0a,0x09,
+0x20,0x20,0x3c,0x68,0x31,0x3e,0x6c,0x77,0x49,0x50,0x20,0x2d,0x20,0x41,0x20,0x4c,
+0x69,0x67,0x68,0x74,0x77,0x65,0x69,0x67,0x68,0x74,0x20,0x54,0x43,0x50,0x2f,0x49,
+0x50,0x20,0x53,0x74,0x61,0x63,0x6b,0x3c,0x2f,0x68,0x31,0x3e,0x0d,0x0a,0x09,0x20,
+0x20,0x3c,0x70,0x3e,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x54,0x68,0x65,0x20,0x77,
+0x65,0x62,0x20,0x70,0x61,0x67,0x65,0x20,0x79,0x6f,0x75,0x20,0x61,0x72,0x65,0x20,
+0x77,0x61,0x74,0x63,0x68,0x69,0x6e,0x67,0x20,0x77,0x61,0x73,0x20,0x73,0x65,0x72,
+0x76,0x65,0x64,0x20,0x62,0x79,0x20,0x61,0x20,0x73,0x69,0x6d,0x70,0x6c,0x65,0x20,
+0x77,0x65,0x62,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x73,0x65,0x72,0x76,0x65,0x72,
+0x20,0x72,0x75,0x6e,0x6e,0x69,0x6e,0x67,0x20,0x6f,0x6e,0x20,0x74,0x6f,0x70,0x20,
+0x6f,0x66,0x20,0x74,0x68,0x65,0x20,0x6c,0x69,0x67,0x68,0x74,0x77,0x65,0x69,0x67,
+0x68,0x74,0x20,0x54,0x43,0x50,0x2f,0x49,0x50,0x20,0x73,0x74,0x61,0x63,0x6b,0x20,
+0x3c,0x61,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x68,0x72,0x65,0x66,0x3d,0x22,0x68,
+0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77,0x77,0x77,0x2e,0x73,0x69,0x63,0x73,0x2e,0x73,
+0x65,0x2f,0x7e,0x61,0x64,0x61,0x6d,0x2f,0x6c,0x77,0x69,0x70,0x2f,0x22,0x3e,0x6c,
+0x77,0x49,0x50,0x3c,0x2f,0x61,0x3e,0x2e,0x0d,0x0a,0x09,0x20,0x20,0x3c,0x2f,0x70,
+0x3e,0x0d,0x0a,0x09,0x20,0x20,0x3c,0x70,0x3e,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,
+0x6c,0x77,0x49,0x50,0x20,0x69,0x73,0x20,0x61,0x6e,0x20,0x6f,0x70,0x65,0x6e,0x20,
+0x73,0x6f,0x75,0x72,0x63,0x65,0x20,0x69,0x6d,0x70,0x6c,0x65,0x6d,0x65,0x6e,0x74,
+0x61,0x74,0x69,0x6f,0x6e,0x20,0x6f,0x66,0x20,0x74,0x68,0x65,0x20,0x54,0x43,0x50,
+0x2f,0x49,0x50,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x70,0x72,0x6f,0x74,0x6f,0x63,
+0x6f,0x6c,0x20,0x73,0x75,0x69,0x74,0x65,0x20,0x74,0x68,0x61,0x74,0x20,0x77,0x61,
+0x73,0x20,0x6f,0x72,0x69,0x67,0x69,0x6e,0x61,0x6c,0x6c,0x79,0x20,0x77,0x72,0x69,
+0x74,0x74,0x65,0x6e,0x20,0x62,0x79,0x20,0x3c,0x61,0x0d,0x0a,0x09,0x20,0x20,0x20,
+0x20,0x68,0x72,0x65,0x66,0x3d,0x22,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77,0x77,
+0x77,0x2e,0x73,0x69,0x63,0x73,0x2e,0x73,0x65,0x2f,0x7e,0x61,0x64,0x61,0x6d,0x2f,
+0x6c,0x77,0x69,0x70,0x2f,0x22,0x3e,0x41,0x64,0x61,0x6d,0x20,0x44,0x75,0x6e,0x6b,
+0x65,0x6c,0x73,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x6f,0x66,0x20,0x74,0x68,0x65,
+0x20,0x53,0x77,0x65,0x64,0x69,0x73,0x68,0x20,0x49,0x6e,0x73,0x74,0x69,0x74,0x75,
+0x74,0x65,0x20,0x6f,0x66,0x20,0x43,0x6f,0x6d,0x70,0x75,0x74,0x65,0x72,0x20,0x53,
+0x63,0x69,0x65,0x6e,0x63,0x65,0x3c,0x2f,0x61,0x3e,0x20,0x62,0x75,0x74,0x20,0x6e,
+0x6f,0x77,0x20,0x69,0x73,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x62,0x65,0x69,0x6e,
+0x67,0x20,0x61,0x63,0x74,0x69,0x76,0x65,0x6c,0x79,0x20,0x64,0x65,0x76,0x65,0x6c,
+0x6f,0x70,0x65,0x64,0x20,0x62,0x79,0x20,0x61,0x20,0x74,0x65,0x61,0x6d,0x20,0x6f,
+0x66,0x20,0x64,0x65,0x76,0x65,0x6c,0x6f,0x70,0x65,0x72,0x73,0x0d,0x0a,0x09,0x20,
+0x20,0x20,0x20,0x64,0x69,0x73,0x74,0x72,0x69,0x62,0x75,0x74,0x65,0x64,0x20,0x77,
+0x6f,0x72,0x6c,0x64,0x2d,0x77,0x69,0x64,0x65,0x2e,0x20,0x53,0x69,0x6e,0x63,0x65,
+0x20,0x69,0x74,0x27,0x73,0x20,0x72,0x65,0x6c,0x65,0x61,0x73,0x65,0x2c,0x20,0x6c,
+0x77,0x49,0x50,0x20,0x68,0x61,0x73,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x73,0x70,
+0x75,0x72,0x72,0x65,0x64,0x20,0x61,0x20,0x6c,0x6f,0x74,0x20,0x6f,0x66,0x20,0x69,
+0x6e,0x74,0x65,0x72,0x65,0x73,0x74,0x20,0x61,0x6e,0x64,0x20,0x68,0x61,0x73,0x20,
+0x62,0x65,0x65,0x6e,0x20,0x70,0x6f,0x72,0x74,0x65,0x64,0x20,0x74,0x6f,0x20,0x73,
+0x65,0x76,0x65,0x72,0x61,0x6c,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x70,0x6c,0x61,
+0x74,0x66,0x6f,0x72,0x6d,0x73,0x20,0x61,0x6e,0x64,0x20,0x6f,0x70,0x65,0x72,0x61,
+0x74,0x69,0x6e,0x67,0x20,0x73,0x79,0x73,0x74,0x65,0x6d,0x73,0x2e,0x20,0x6c,0x77,
+0x49,0x50,0x20,0x63,0x61,0x6e,0x20,0x62,0x65,0x20,0x75,0x73,0x65,0x64,0x20,0x65,
+0x69,0x74,0x68,0x65,0x72,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x77,0x69,0x74,0x68,
+0x20,0x6f,0x72,0x20,0x77,0x69,0x74,0x68,0x6f,0x75,0x74,0x20,0x61,0x6e,0x20,0x75,
+0x6e,0x64,0x65,0x72,0x6c,0x79,0x69,0x6e,0x67,0x20,0x4f,0x53,0x2e,0x0d,0x0a,0x09,
+0x20,0x20,0x3c,0x2f,0x70,0x3e,0x0d,0x0a,0x09,0x20,0x20,0x3c,0x70,0x3e,0x0d,0x0a,
+0x09,0x20,0x20,0x20,0x20,0x54,0x68,0x65,0x20,0x66,0x6f,0x63,0x75,0x73,0x20,0x6f,
+0x66,0x20,0x74,0x68,0x65,0x20,0x6c,0x77,0x49,0x50,0x20,0x54,0x43,0x50,0x2f,0x49,
+0x50,0x20,0x69,0x6d,0x70,0x6c,0x65,0x6d,0x65,0x6e,0x74,0x61,0x74,0x69,0x6f,0x6e,
+0x20,0x69,0x73,0x20,0x74,0x6f,0x20,0x72,0x65,0x64,0x75,0x63,0x65,0x0d,0x0a,0x09,
+0x20,0x20,0x20,0x20,0x74,0x68,0x65,0x20,0x52,0x41,0x4d,0x20,0x75,0x73,0x61,0x67,
+0x65,0x20,0x77,0x68,0x69,0x6c,0x65,0x20,0x73,0x74,0x69,0x6c,0x6c,0x20,0x68,0x61,
+0x76,0x69,0x6e,0x67,0x20,0x61,0x20,0x66,0x75,0x6c,0x6c,0x20,0x73,0x63,0x61,0x6c,
+0x65,0x20,0x54,0x43,0x50,0x2e,0x20,0x54,0x68,0x69,0x73,0x0d,0x0a,0x09,0x20,0x20,
+0x20,0x20,0x6d,0x61,0x6b,0x65,0x73,0x20,0x6c,0x77,0x49,0x50,0x20,0x73,0x75,0x69,
+0x74,0x61,0x62,0x6c,0x65,0x20,0x66,0x6f,0x72,0x20,0x75,0x73,0x65,0x20,0x69,0x6e,
+0x20,0x65,0x6d,0x62,0x65,0x64,0x64,0x65,0x64,0x20,0x73,0x79,0x73,0x74,0x65,0x6d,
+0x73,0x20,0x77,0x69,0x74,0x68,0x20,0x74,0x65,0x6e,0x73,0x0d,0x0a,0x09,0x20,0x20,
+0x20,0x20,0x6f,0x66,0x20,0x6b,0x69,0x6c,0x6f,0x62,0x79,0x74,0x65,0x73,0x20,0x6f,
+0x66,0x20,0x66,0x72,0x65,0x65,0x20,0x52,0x41,0x4d,0x20,0x61,0x6e,0x64,0x20,0x72,
+0x6f,0x6f,0x6d,0x20,0x66,0x6f,0x72,0x20,0x61,0x72,0x6f,0x75,0x6e,0x64,0x20,0x34,
+0x30,0x20,0x6b,0x69,0x6c,0x6f,0x62,0x79,0x74,0x65,0x73,0x0d,0x0a,0x09,0x20,0x20,
+0x20,0x20,0x6f,0x66,0x20,0x63,0x6f,0x64,0x65,0x20,0x52,0x4f,0x4d,0x2e,0x0d,0x0a,
+0x09,0x20,0x20,0x3c,0x2f,0x70,0x3e,0x0d,0x0a,0x09,0x20,0x20,0x3c,0x70,0x3e,0x0d,
+0x0a,0x09,0x20,0x20,0x20,0x20,0x4d,0x6f,0x72,0x65,0x20,0x69,0x6e,0x66,0x6f,0x72,
+0x6d,0x61,0x74,0x69,0x6f,0x6e,0x20,0x61,0x62,0x6f,0x75,0x74,0x20,0x6c,0x77,0x49,
+0x50,0x20,0x63,0x61,0x6e,0x20,0x62,0x65,0x20,0x66,0x6f,0x75,0x6e,0x64,0x20,0x61,
+0x74,0x20,0x74,0x68,0x65,0x20,0x6c,0x77,0x49,0x50,0x0d,0x0a,0x09,0x20,0x20,0x20,
+0x20,0x68,0x6f,0x6d,0x65,0x70,0x61,0x67,0x65,0x20,0x61,0x74,0x20,0x3c,0x61,0x0d,
+0x0a,0x09,0x20,0x20,0x20,0x20,0x68,0x72,0x65,0x66,0x3d,0x22,0x68,0x74,0x74,0x70,
+0x3a,0x2f,0x2f,0x73,0x61,0x76,0x61,0x6e,0x6e,0x61,0x68,0x2e,0x6e,0x6f,0x6e,0x67,
+0x6e,0x75,0x2e,0x6f,0x72,0x67,0x2f,0x70,0x72,0x6f,0x6a,0x65,0x63,0x74,0x73,0x2f,
+0x6c,0x77,0x69,0x70,0x2f,0x22,0x3e,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x73,0x61,
+0x76,0x61,0x6e,0x6e,0x61,0x68,0x2e,0x6e,0x6f,0x6e,0x67,0x6e,0x75,0x2e,0x6f,0x72,
+0x67,0x2f,0x70,0x72,0x6f,0x6a,0x65,0x63,0x74,0x73,0x2f,0x6c,0x77,0x69,0x70,0x2f,
+0x3c,0x2f,0x61,0x3e,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x6f,0x72,0x20,0x61,0x74,
+0x20,0x74,0x68,0x65,0x20,0x6c,0x77,0x49,0x50,0x20,0x77,0x69,0x6b,0x69,0x20,0x61,
+0x74,0x20,0x3c,0x61,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x68,0x72,0x65,0x66,0x3d,
+0x22,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x6c,0x77,0x69,0x70,0x2e,0x77,0x69,0x6b,
+0x69,0x61,0x2e,0x63,0x6f,0x6d,0x2f,0x22,0x3e,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,
+0x6c,0x77,0x69,0x70,0x2e,0x77,0x69,0x6b,0x69,0x61,0x2e,0x63,0x6f,0x6d,0x2f,0x3c,
+0x2f,0x61,0x3e,0x2e,0x0d,0x0a,0x09,0x20,0x20,0x3c,0x2f,0x70,0x3e,0x0d,0x0a,0x09,
+0x3c,0x2f,0x74,0x64,0x3e,0x3c,0x74,0x64,0x3e,0x0d,0x0a,0x09,0x20,0x20,0x26,0x6e,
+0x62,0x73,0x70,0x3b,0x0d,0x0a,0x09,0x3c,0x2f,0x74,0x64,0x3e,0x3c,0x2f,0x74,0x72,
+0x3e,0x0d,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x3c,0x2f,0x74,0x61,0x62,0x6c,0x65,
+0x3e,0x0d,0x0a,0x3c,0x2f,0x62,0x6f,0x64,0x79,0x3e,0x0d,0x0a,0x3c,0x2f,0x68,0x74,
+0x6d,0x6c,0x3e,0x0d,0x0a,0x0d,0x0a,};
+
+#if FSDATA_FILE_ALIGNMENT==1
+static const unsigned int dummy_align__login_html = 3;
+#endif
+static const unsigned char FSDATA_ALIGN_PRE data__login_html[] FSDATA_ALIGN_POST = {
+/* /login.html (12 chars) */
+0x2f,0x6c,0x6f,0x67,0x69,0x6e,0x2e,0x68,0x74,0x6d,0x6c,0x00,
+
+/* HTTP header */
+/* "HTTP/1.1 200 OK
+" (17 bytes) */
+0x48,0x54,0x54,0x50,0x2f,0x31,0x2e,0x31,0x20,0x32,0x30,0x30,0x20,0x4f,0x4b,0x0d,
+0x0a,
+/* "Server: lwIP/2.0.3d (http://savannah.nongnu.org/projects/lwip)
+" (64 bytes) */
+0x53,0x65,0x72,0x76,0x65,0x72,0x3a,0x20,0x6c,0x77,0x49,0x50,0x2f,0x32,0x2e,0x30,
+0x2e,0x33,0x64,0x20,0x28,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x73,0x61,0x76,0x61,
+0x6e,0x6e,0x61,0x68,0x2e,0x6e,0x6f,0x6e,0x67,0x6e,0x75,0x2e,0x6f,0x72,0x67,0x2f,
+0x70,0x72,0x6f,0x6a,0x65,0x63,0x74,0x73,0x2f,0x6c,0x77,0x69,0x70,0x29,0x0d,0x0a,
+
+/* "Content-Length: 768
+" (18+ bytes) */
+0x43,0x6f,0x6e,0x74,0x65,0x6e,0x74,0x2d,0x4c,0x65,0x6e,0x67,0x74,0x68,0x3a,0x20,
+0x37,0x36,0x38,0x0d,0x0a,
+/* "Connection: keep-alive
+" (24 bytes) */
+0x43,0x6f,0x6e,0x6e,0x65,0x63,0x74,0x69,0x6f,0x6e,0x3a,0x20,0x6b,0x65,0x65,0x70,
+0x2d,0x61,0x6c,0x69,0x76,0x65,0x0d,0x0a,
+/* "Content-Type: text/html
+
+" (27 bytes) */
+0x43,0x6f,0x6e,0x74,0x65,0x6e,0x74,0x2d,0x54,0x79,0x70,0x65,0x3a,0x20,0x74,0x65,
+0x78,0x74,0x2f,0x68,0x74,0x6d,0x6c,0x0d,0x0a,0x0d,0x0a,
+/* raw file data (768 bytes) */
+0x3c,0x68,0x74,0x6d,0x6c,0x3e,0x0d,0x0a,0x3c,0x68,0x65,0x61,0x64,0x3e,0x3c,0x74,
+0x69,0x74,0x6c,0x65,0x3e,0x6c,0x77,0x49,0x50,0x20,0x2d,0x20,0x41,0x20,0x4c,0x69,
+0x67,0x68,0x74,0x77,0x65,0x69,0x67,0x68,0x74,0x20,0x54,0x43,0x50,0x2f,0x49,0x50,
+0x20,0x53,0x74,0x61,0x63,0x6b,0x3c,0x2f,0x74,0x69,0x74,0x6c,0x65,0x3e,0x3c,0x2f,
+0x68,0x65,0x61,0x64,0x3e,0x0d,0x0a,0x3c,0x62,0x6f,0x64,0x79,0x20,0x62,0x67,0x63,
+0x6f,0x6c,0x6f,0x72,0x3d,0x22,0x77,0x68,0x69,0x74,0x65,0x22,0x20,0x74,0x65,0x78,
+0x74,0x3d,0x22,0x62,0x6c,0x61,0x63,0x6b,0x22,0x3e,0x0d,0x0a,0x0d,0x0a,0x3c,0x74,
+0x61,0x62,0x6c,0x65,0x20,0x77,0x69,0x64,0x74,0x68,0x3d,0x22,0x31,0x30,0x30,0x25,
+0x22,0x3e,0x0d,0x0a,0x20,0x3c,0x74,0x72,0x20,0x76,0x61,0x6c,0x69,0x67,0x6e,0x3d,
+0x22,0x74,0x6f,0x70,0x22,0x3e,0x0d,0x0a,0x20,0x20,0x3c,0x74,0x64,0x20,0x77,0x69,
+0x64,0x74,0x68,0x3d,0x22,0x38,0x30,0x22,0x3e,0x0d,0x0a,0x20,0x20,0x20,0x3c,0x61,
+0x20,0x68,0x72,0x65,0x66,0x3d,0x22,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77,0x77,
+0x77,0x2e,0x73,0x69,0x63,0x73,0x2e,0x73,0x65,0x2f,0x22,0x3e,0x3c,0x69,0x6d,0x67,
+0x20,0x73,0x72,0x63,0x3d,0x22,0x2f,0x69,0x6d,0x67,0x2f,0x73,0x69,0x63,0x73,0x2e,
+0x67,0x69,0x66,0x22,0x20,0x62,0x6f,0x72,0x64,0x65,0x72,0x3d,0x22,0x30,0x22,0x20,
+0x61,0x6c,0x74,0x3d,0x22,0x53,0x49,0x43,0x53,0x20,0x6c,0x6f,0x67,0x6f,0x22,0x20,
+0x74,0x69,0x74,0x6c,0x65,0x3d,0x22,0x53,0x49,0x43,0x53,0x20,0x6c,0x6f,0x67,0x6f,
+0x22,0x2f,0x3e,0x3c,0x2f,0x61,0x3e,0x0d,0x0a,0x20,0x20,0x3c,0x2f,0x74,0x64,0x3e,
+0x0d,0x0a,0x20,0x20,0x3c,0x74,0x64,0x20,0x77,0x69,0x64,0x74,0x68,0x3d,0x22,0x35,
+0x30,0x30,0x22,0x3e,0x0d,0x0a,0x20,0x20,0x20,0x3c,0x68,0x31,0x3e,0x4c,0x6f,0x67,
+0x69,0x6e,0x3c,0x2f,0x68,0x31,0x3e,0x0d,0x0a,0x20,0x20,0x20,0x3c,0x66,0x6f,0x72,
+0x6d,0x20,0x6e,0x61,0x6d,0x65,0x3d,0x22,0x6c,0x6f,0x67,0x69,0x6e,0x22,0x20,0x61,
+0x63,0x74,0x69,0x6f,0x6e,0x3d,0x22,0x6c,0x6f,0x67,0x69,0x6e,0x2e,0x63,0x67,0x69,
+0x22,0x20,0x6d,0x65,0x74,0x68,0x6f,0x64,0x3d,0x22,0x70,0x6f,0x73,0x74,0x22,0x3e,
+0x0d,0x0a,0x20,0x20,0x20,0x20,0x3c,0x64,0x69,0x76,0x3e,0x0d,0x0a,0x20,0x20,0x20,
+0x20,0x20,0x3c,0x6c,0x61,0x62,0x65,0x6c,0x3e,0x3c,0x62,0x3e,0x55,0x73,0x65,0x72,
+0x6e,0x61,0x6d,0x65,0x3c,0x2f,0x62,0x3e,0x3c,0x2f,0x6c,0x61,0x62,0x65,0x6c,0x3e,
+0x0d,0x0a,0x20,0x20,0x20,0x20,0x20,0x3c,0x69,0x6e,0x70,0x75,0x74,0x20,0x74,0x79,
+0x70,0x65,0x3d,0x22,0x74,0x65,0x78,0x74,0x22,0x20,0x70,0x6c,0x61,0x63,0x65,0x68,
+0x6f,0x6c,0x64,0x65,0x72,0x3d,0x22,0x45,0x6e,0x74,0x65,0x72,0x20,0x55,0x73,0x65,
+0x72,0x6e,0x61,0x6d,0x65,0x22,0x20,0x6e,0x61,0x6d,0x65,0x3d,0x22,0x75,0x73,0x65,
+0x72,0x22,0x20,0x72,0x65,0x71,0x75,0x69,0x72,0x65,0x64,0x3e,0x0d,0x0a,0x20,0x20,
+0x20,0x20,0x20,0x3c,0x6c,0x61,0x62,0x65,0x6c,0x3e,0x3c,0x62,0x3e,0x50,0x61,0x73,
+0x73,0x77,0x6f,0x72,0x64,0x3c,0x2f,0x62,0x3e,0x3c,0x2f,0x6c,0x61,0x62,0x65,0x6c,
+0x3e,0x0d,0x0a,0x20,0x20,0x20,0x20,0x20,0x3c,0x69,0x6e,0x70,0x75,0x74,0x20,0x74,
+0x79,0x70,0x65,0x3d,0x22,0x70,0x61,0x73,0x73,0x77,0x6f,0x72,0x64,0x22,0x20,0x70,
+0x6c,0x61,0x63,0x65,0x68,0x6f,0x6c,0x64,0x65,0x72,0x3d,0x22,0x45,0x6e,0x74,0x65,
+0x72,0x20,0x50,0x61,0x73,0x73,0x77,0x6f,0x72,0x64,0x22,0x20,0x6e,0x61,0x6d,0x65,
+0x3d,0x22,0x70,0x61,0x73,0x73,0x22,0x20,0x72,0x65,0x71,0x75,0x69,0x72,0x65,0x64,
+0x3e,0x0d,0x0a,0x20,0x20,0x20,0x20,0x20,0x3c,0x62,0x75,0x74,0x74,0x6f,0x6e,0x20,
+0x74,0x79,0x70,0x65,0x3d,0x22,0x73,0x75,0x62,0x6d,0x69,0x74,0x22,0x3e,0x4c,0x6f,
+0x67,0x69,0x6e,0x3c,0x2f,0x62,0x75,0x74,0x74,0x6f,0x6e,0x3e,0x0d,0x0a,0x20,0x20,
+0x20,0x20,0x3c,0x2f,0x64,0x69,0x76,0x3e,0x0d,0x0a,0x20,0x20,0x20,0x3c,0x2f,0x66,
+0x6f,0x72,0x6d,0x3e,0x20,0x0d,0x0a,0x20,0x20,0x3c,0x2f,0x74,0x64,0x3e,0x0d,0x0a,
+0x20,0x20,0x3c,0x74,0x64,0x3e,0x0d,0x0a,0x20,0x20,0x20,0x26,0x6e,0x62,0x73,0x70,
+0x3b,0x0d,0x0a,0x20,0x20,0x3c,0x2f,0x74,0x64,0x3e,0x0d,0x0a,0x20,0x3c,0x2f,0x74,
+0x72,0x3e,0x0d,0x0a,0x3c,0x2f,0x74,0x61,0x62,0x6c,0x65,0x3e,0x0d,0x0a,0x3c,0x2f,
+0x62,0x6f,0x64,0x79,0x3e,0x0d,0x0a,0x3c,0x2f,0x68,0x74,0x6d,0x6c,0x3e,0x0d,0x0a,
+};
+
+#if FSDATA_FILE_ALIGNMENT==1
+static const unsigned int dummy_align__loginfail_html = 4;
+#endif
+static const unsigned char FSDATA_ALIGN_PRE data__loginfail_html[] FSDATA_ALIGN_POST = {
+/* /loginfail.html (16 chars) */
+0x2f,0x6c,0x6f,0x67,0x69,0x6e,0x66,0x61,0x69,0x6c,0x2e,0x68,0x74,0x6d,0x6c,0x00,
+
+
+/* HTTP header */
+/* "HTTP/1.1 200 OK
+" (17 bytes) */
+0x48,0x54,0x54,0x50,0x2f,0x31,0x2e,0x31,0x20,0x32,0x30,0x30,0x20,0x4f,0x4b,0x0d,
+0x0a,
+/* "Server: lwIP/2.0.3d (http://savannah.nongnu.org/projects/lwip)
+" (64 bytes) */
+0x53,0x65,0x72,0x76,0x65,0x72,0x3a,0x20,0x6c,0x77,0x49,0x50,0x2f,0x32,0x2e,0x30,
+0x2e,0x33,0x64,0x20,0x28,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x73,0x61,0x76,0x61,
+0x6e,0x6e,0x61,0x68,0x2e,0x6e,0x6f,0x6e,0x67,0x6e,0x75,0x2e,0x6f,0x72,0x67,0x2f,
+0x70,0x72,0x6f,0x6a,0x65,0x63,0x74,0x73,0x2f,0x6c,0x77,0x69,0x70,0x29,0x0d,0x0a,
+
+/* "Content-Length: 559
+" (18+ bytes) */
+0x43,0x6f,0x6e,0x74,0x65,0x6e,0x74,0x2d,0x4c,0x65,0x6e,0x67,0x74,0x68,0x3a,0x20,
+0x35,0x35,0x39,0x0d,0x0a,
+/* "Connection: keep-alive
+" (24 bytes) */
+0x43,0x6f,0x6e,0x6e,0x65,0x63,0x74,0x69,0x6f,0x6e,0x3a,0x20,0x6b,0x65,0x65,0x70,
+0x2d,0x61,0x6c,0x69,0x76,0x65,0x0d,0x0a,
+/* "Content-Type: text/html
+
+" (27 bytes) */
+0x43,0x6f,0x6e,0x74,0x65,0x6e,0x74,0x2d,0x54,0x79,0x70,0x65,0x3a,0x20,0x74,0x65,
+0x78,0x74,0x2f,0x68,0x74,0x6d,0x6c,0x0d,0x0a,0x0d,0x0a,
+/* raw file data (559 bytes) */
+0x3c,0x68,0x74,0x6d,0x6c,0x3e,0x0d,0x0a,0x3c,0x68,0x65,0x61,0x64,0x3e,0x3c,0x74,
+0x69,0x74,0x6c,0x65,0x3e,0x6c,0x77,0x49,0x50,0x20,0x2d,0x20,0x41,0x20,0x4c,0x69,
+0x67,0x68,0x74,0x77,0x65,0x69,0x67,0x68,0x74,0x20,0x54,0x43,0x50,0x2f,0x49,0x50,
+0x20,0x53,0x74,0x61,0x63,0x6b,0x3c,0x2f,0x74,0x69,0x74,0x6c,0x65,0x3e,0x3c,0x2f,
+0x68,0x65,0x61,0x64,0x3e,0x0d,0x0a,0x3c,0x62,0x6f,0x64,0x79,0x20,0x62,0x67,0x63,
+0x6f,0x6c,0x6f,0x72,0x3d,0x22,0x77,0x68,0x69,0x74,0x65,0x22,0x20,0x74,0x65,0x78,
+0x74,0x3d,0x22,0x62,0x6c,0x61,0x63,0x6b,0x22,0x3e,0x0d,0x0a,0x0d,0x0a,0x20,0x3c,
+0x74,0x61,0x62,0x6c,0x65,0x20,0x77,0x69,0x64,0x74,0x68,0x3d,0x22,0x31,0x30,0x30,
+0x25,0x22,0x3e,0x0d,0x0a,0x20,0x20,0x3c,0x74,0x72,0x20,0x76,0x61,0x6c,0x69,0x67,
+0x6e,0x3d,0x22,0x74,0x6f,0x70,0x22,0x3e,0x0d,0x0a,0x20,0x20,0x20,0x3c,0x74,0x64,
+0x20,0x77,0x69,0x64,0x74,0x68,0x3d,0x22,0x38,0x30,0x22,0x3e,0x0d,0x0a,0x20,0x20,
+0x20,0x20,0x3c,0x61,0x20,0x68,0x72,0x65,0x66,0x3d,0x22,0x68,0x74,0x74,0x70,0x3a,
+0x2f,0x2f,0x77,0x77,0x77,0x2e,0x73,0x69,0x63,0x73,0x2e,0x73,0x65,0x2f,0x22,0x3e,
+0x3c,0x69,0x6d,0x67,0x20,0x73,0x72,0x63,0x3d,0x22,0x2f,0x69,0x6d,0x67,0x2f,0x73,
+0x69,0x63,0x73,0x2e,0x67,0x69,0x66,0x22,0x20,0x62,0x6f,0x72,0x64,0x65,0x72,0x3d,
+0x22,0x30,0x22,0x20,0x61,0x6c,0x74,0x3d,0x22,0x53,0x49,0x43,0x53,0x20,0x6c,0x6f,
+0x67,0x6f,0x22,0x20,0x74,0x69,0x74,0x6c,0x65,0x3d,0x22,0x53,0x49,0x43,0x53,0x20,
+0x6c,0x6f,0x67,0x6f,0x22,0x2f,0x3e,0x3c,0x2f,0x61,0x3e,0x0d,0x0a,0x20,0x20,0x20,
+0x3c,0x2f,0x74,0x64,0x3e,0x0d,0x0a,0x20,0x20,0x20,0x3c,0x74,0x64,0x20,0x77,0x69,
+0x64,0x74,0x68,0x3d,0x22,0x35,0x30,0x30,0x22,0x3e,0x0d,0x0a,0x20,0x20,0x20,0x20,
+0x3c,0x68,0x31,0x3e,0x6c,0x77,0x49,0x50,0x20,0x2d,0x20,0x41,0x20,0x4c,0x69,0x67,
+0x68,0x74,0x77,0x65,0x69,0x67,0x68,0x74,0x20,0x54,0x43,0x50,0x2f,0x49,0x50,0x20,
+0x53,0x74,0x61,0x63,0x6b,0x3c,0x2f,0x68,0x31,0x3e,0x0d,0x0a,0x20,0x20,0x20,0x20,
+0x3c,0x70,0x3e,0x0d,0x0a,0x20,0x20,0x20,0x20,0x20,0x4c,0x6f,0x67,0x69,0x6e,0x20,
+0x66,0x61,0x69,0x6c,0x65,0x64,0x2e,0x0d,0x0a,0x20,0x20,0x20,0x20,0x3c,0x2f,0x70,
+0x3e,0x0d,0x0a,0x20,0x20,0x20,0x20,0x3c,0x70,0x3e,0x0d,0x0a,0x20,0x20,0x20,0x20,
+0x20,0x43,0x6c,0x69,0x63,0x6b,0x20,0x3c,0x61,0x20,0x68,0x72,0x65,0x66,0x3d,0x22,
+0x6c,0x6f,0x67,0x69,0x6e,0x2e,0x68,0x74,0x6d,0x6c,0x22,0x3e,0x68,0x65,0x72,0x65,
+0x3c,0x2f,0x61,0x3e,0x20,0x74,0x6f,0x20,0x72,0x65,0x74,0x72,0x79,0x20,0x6c,0x6f,
+0x67,0x69,0x6e,0x2e,0x0d,0x0a,0x20,0x20,0x20,0x20,0x3c,0x2f,0x70,0x3e,0x0d,0x0a,
+0x20,0x20,0x20,0x3c,0x2f,0x74,0x64,0x3e,0x0d,0x0a,0x20,0x20,0x20,0x3c,0x74,0x64,
+0x3e,0x0d,0x0a,0x20,0x20,0x20,0x20,0x26,0x6e,0x62,0x73,0x70,0x3b,0x0d,0x0a,0x20,
+0x20,0x20,0x3c,0x2f,0x74,0x64,0x3e,0x0d,0x0a,0x20,0x20,0x3c,0x2f,0x74,0x72,0x3e,
+0x0d,0x0a,0x20,0x3c,0x2f,0x74,0x61,0x62,0x6c,0x65,0x3e,0x0d,0x0a,0x3c,0x2f,0x62,
+0x6f,0x64,0x79,0x3e,0x0d,0x0a,0x3c,0x2f,0x68,0x74,0x6d,0x6c,0x3e,0x0d,0x0a,};
+
+#if FSDATA_FILE_ALIGNMENT==1
+static const unsigned int dummy_align__session_html = 5;
+#endif
+static const unsigned char FSDATA_ALIGN_PRE data__session_html[] FSDATA_ALIGN_POST = {
+/* /session.html (14 chars) */
+0x2f,0x73,0x65,0x73,0x73,0x69,0x6f,0x6e,0x2e,0x68,0x74,0x6d,0x6c,0x00,0x00,0x00,
+
+/* HTTP header */
+/* "HTTP/1.1 200 OK
+" (17 bytes) */
+0x48,0x54,0x54,0x50,0x2f,0x31,0x2e,0x31,0x20,0x32,0x30,0x30,0x20,0x4f,0x4b,0x0d,
+0x0a,
+/* "Server: lwIP/2.0.3d (http://savannah.nongnu.org/projects/lwip)
+" (64 bytes) */
+0x53,0x65,0x72,0x76,0x65,0x72,0x3a,0x20,0x6c,0x77,0x49,0x50,0x2f,0x32,0x2e,0x30,
+0x2e,0x33,0x64,0x20,0x28,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x73,0x61,0x76,0x61,
+0x6e,0x6e,0x61,0x68,0x2e,0x6e,0x6f,0x6e,0x67,0x6e,0x75,0x2e,0x6f,0x72,0x67,0x2f,
+0x70,0x72,0x6f,0x6a,0x65,0x63,0x74,0x73,0x2f,0x6c,0x77,0x69,0x70,0x29,0x0d,0x0a,
+
+/* "Content-Length: 578
+" (18+ bytes) */
+0x43,0x6f,0x6e,0x74,0x65,0x6e,0x74,0x2d,0x4c,0x65,0x6e,0x67,0x74,0x68,0x3a,0x20,
+0x35,0x37,0x38,0x0d,0x0a,
+/* "Connection: keep-alive
+" (24 bytes) */
+0x43,0x6f,0x6e,0x6e,0x65,0x63,0x74,0x69,0x6f,0x6e,0x3a,0x20,0x6b,0x65,0x65,0x70,
+0x2d,0x61,0x6c,0x69,0x76,0x65,0x0d,0x0a,
+/* "Content-Type: text/html
+
+" (27 bytes) */
+0x43,0x6f,0x6e,0x74,0x65,0x6e,0x74,0x2d,0x54,0x79,0x70,0x65,0x3a,0x20,0x74,0x65,
+0x78,0x74,0x2f,0x68,0x74,0x6d,0x6c,0x0d,0x0a,0x0d,0x0a,
+/* raw file data (578 bytes) */
+0x3c,0x68,0x74,0x6d,0x6c,0x3e,0x0d,0x0a,0x3c,0x68,0x65,0x61,0x64,0x3e,0x3c,0x74,
+0x69,0x74,0x6c,0x65,0x3e,0x6c,0x77,0x49,0x50,0x20,0x2d,0x20,0x41,0x20,0x4c,0x69,
+0x67,0x68,0x74,0x77,0x65,0x69,0x67,0x68,0x74,0x20,0x54,0x43,0x50,0x2f,0x49,0x50,
+0x20,0x53,0x74,0x61,0x63,0x6b,0x3c,0x2f,0x74,0x69,0x74,0x6c,0x65,0x3e,0x3c,0x2f,
+0x68,0x65,0x61,0x64,0x3e,0x0d,0x0a,0x3c,0x62,0x6f,0x64,0x79,0x20,0x62,0x67,0x63,
+0x6f,0x6c,0x6f,0x72,0x3d,0x22,0x77,0x68,0x69,0x74,0x65,0x22,0x20,0x74,0x65,0x78,
+0x74,0x3d,0x22,0x62,0x6c,0x61,0x63,0x6b,0x22,0x3e,0x0d,0x0a,0x0d,0x0a,0x20,0x3c,
+0x74,0x61,0x62,0x6c,0x65,0x20,0x77,0x69,0x64,0x74,0x68,0x3d,0x22,0x31,0x30,0x30,
+0x25,0x22,0x3e,0x0d,0x0a,0x20,0x20,0x3c,0x74,0x72,0x20,0x76,0x61,0x6c,0x69,0x67,
+0x6e,0x3d,0x22,0x74,0x6f,0x70,0x22,0x3e,0x0d,0x0a,0x20,0x20,0x20,0x3c,0x74,0x64,
+0x20,0x77,0x69,0x64,0x74,0x68,0x3d,0x22,0x38,0x30,0x22,0x3e,0x0d,0x0a,0x20,0x20,
+0x20,0x20,0x3c,0x61,0x20,0x68,0x72,0x65,0x66,0x3d,0x22,0x68,0x74,0x74,0x70,0x3a,
+0x2f,0x2f,0x77,0x77,0x77,0x2e,0x73,0x69,0x63,0x73,0x2e,0x73,0x65,0x2f,0x22,0x3e,
+0x3c,0x69,0x6d,0x67,0x20,0x73,0x72,0x63,0x3d,0x22,0x2f,0x69,0x6d,0x67,0x2f,0x73,
+0x69,0x63,0x73,0x2e,0x67,0x69,0x66,0x22,0x20,0x62,0x6f,0x72,0x64,0x65,0x72,0x3d,
+0x22,0x30,0x22,0x20,0x61,0x6c,0x74,0x3d,0x22,0x53,0x49,0x43,0x53,0x20,0x6c,0x6f,
+0x67,0x6f,0x22,0x20,0x74,0x69,0x74,0x6c,0x65,0x3d,0x22,0x53,0x49,0x43,0x53,0x20,
+0x6c,0x6f,0x67,0x6f,0x22,0x2f,0x3e,0x3c,0x2f,0x61,0x3e,0x0d,0x0a,0x20,0x20,0x20,
+0x3c,0x2f,0x74,0x64,0x3e,0x0d,0x0a,0x20,0x20,0x20,0x3c,0x74,0x64,0x20,0x77,0x69,
+0x64,0x74,0x68,0x3d,0x22,0x35,0x30,0x30,0x22,0x3e,0x0d,0x0a,0x20,0x20,0x20,0x20,
+0x3c,0x68,0x31,0x3e,0x6c,0x77,0x49,0x50,0x20,0x2d,0x20,0x41,0x20,0x4c,0x69,0x67,
+0x68,0x74,0x77,0x65,0x69,0x67,0x68,0x74,0x20,0x54,0x43,0x50,0x2f,0x49,0x50,0x20,
+0x53,0x74,0x61,0x63,0x6b,0x3c,0x2f,0x68,0x31,0x3e,0x0d,0x0a,0x20,0x20,0x20,0x20,
+0x3c,0x70,0x3e,0x0d,0x0a,0x20,0x20,0x20,0x20,0x20,0x4c,0x6f,0x67,0x69,0x6e,0x20,
+0x73,0x75,0x63,0x63,0x65,0x65,0x64,0x65,0x64,0x2c,0x20,0x73,0x65,0x73,0x73,0x69,
+0x6f,0x6e,0x20,0x61,0x63,0x74,0x69,0x76,0x65,0x2e,0x0d,0x0a,0x20,0x20,0x20,0x20,
+0x3c,0x2f,0x70,0x3e,0x0d,0x0a,0x20,0x20,0x20,0x20,0x3c,0x70,0x3e,0x0d,0x0a,0x20,
+0x20,0x20,0x20,0x20,0x43,0x6c,0x69,0x63,0x6b,0x20,0x3c,0x61,0x20,0x68,0x72,0x65,
+0x66,0x3d,0x22,0x6c,0x6f,0x67,0x69,0x6e,0x2e,0x68,0x74,0x6d,0x6c,0x22,0x3e,0x68,
+0x65,0x72,0x65,0x3c,0x2f,0x61,0x3e,0x20,0x74,0x6f,0x20,0x72,0x65,0x74,0x72,0x79,
+0x20,0x6c,0x6f,0x67,0x69,0x6e,0x2e,0x0d,0x0a,0x20,0x20,0x20,0x20,0x3c,0x2f,0x70,
+0x3e,0x0d,0x0a,0x20,0x20,0x20,0x3c,0x2f,0x74,0x64,0x3e,0x0d,0x0a,0x20,0x20,0x20,
+0x3c,0x74,0x64,0x3e,0x0d,0x0a,0x20,0x20,0x20,0x20,0x26,0x6e,0x62,0x73,0x70,0x3b,
+0x0d,0x0a,0x20,0x20,0x20,0x3c,0x2f,0x74,0x64,0x3e,0x0d,0x0a,0x20,0x20,0x3c,0x2f,
+0x74,0x72,0x3e,0x0d,0x0a,0x20,0x3c,0x2f,0x74,0x61,0x62,0x6c,0x65,0x3e,0x0d,0x0a,
+0x3c,0x2f,0x62,0x6f,0x64,0x79,0x3e,0x0d,0x0a,0x3c,0x2f,0x68,0x74,0x6d,0x6c,0x3e,
+0x0d,0x0a,};
+
+#if FSDATA_FILE_ALIGNMENT==1
+static const unsigned int dummy_align__ssi_shtml = 6;
+#endif
+static const unsigned char FSDATA_ALIGN_PRE data__ssi_shtml[] FSDATA_ALIGN_POST = {
+/* /ssi.shtml (11 chars) */
+0x2f,0x73,0x73,0x69,0x2e,0x73,0x68,0x74,0x6d,0x6c,0x00,0x00,
+
+/* HTTP header */
+/* "HTTP/1.1 200 OK
+" (17 bytes) */
+0x48,0x54,0x54,0x50,0x2f,0x31,0x2e,0x31,0x20,0x32,0x30,0x30,0x20,0x4f,0x4b,0x0d,
+0x0a,
+/* "Server: lwIP/2.0.3d (http://savannah.nongnu.org/projects/lwip)
+" (64 bytes) */
+0x53,0x65,0x72,0x76,0x65,0x72,0x3a,0x20,0x6c,0x77,0x49,0x50,0x2f,0x32,0x2e,0x30,
+0x2e,0x33,0x64,0x20,0x28,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x73,0x61,0x76,0x61,
+0x6e,0x6e,0x61,0x68,0x2e,0x6e,0x6f,0x6e,0x67,0x6e,0x75,0x2e,0x6f,0x72,0x67,0x2f,
+0x70,0x72,0x6f,0x6a,0x65,0x63,0x74,0x73,0x2f,0x6c,0x77,0x69,0x70,0x29,0x0d,0x0a,
+
+/* "Connection: Close
+" (19 bytes) */
+0x43,0x6f,0x6e,0x6e,0x65,0x63,0x74,0x69,0x6f,0x6e,0x3a,0x20,0x43,0x6c,0x6f,0x73,
+0x65,0x0d,0x0a,
+/* "Content-Type: text/html
+Expires: Fri, 10 Apr 2008 14:00:00 GMT
+Pragma: no-cache
+
+" (85 bytes) */
+0x43,0x6f,0x6e,0x74,0x65,0x6e,0x74,0x2d,0x54,0x79,0x70,0x65,0x3a,0x20,0x74,0x65,
+0x78,0x74,0x2f,0x68,0x74,0x6d,0x6c,0x0d,0x0a,0x45,0x78,0x70,0x69,0x72,0x65,0x73,
+0x3a,0x20,0x46,0x72,0x69,0x2c,0x20,0x31,0x30,0x20,0x41,0x70,0x72,0x20,0x32,0x30,
+0x30,0x38,0x20,0x31,0x34,0x3a,0x30,0x30,0x3a,0x30,0x30,0x20,0x47,0x4d,0x54,0x0d,
+0x0a,0x50,0x72,0x61,0x67,0x6d,0x61,0x3a,0x20,0x6e,0x6f,0x2d,0x63,0x61,0x63,0x68,
+0x65,0x0d,0x0a,0x0d,0x0a,
+/* raw file data (14429 bytes) */
+0x3c,0x68,0x74,0x6d,0x6c,0x3e,0x0d,0x0a,0x3c,0x68,0x65,0x61,0x64,0x3e,0x3c,0x74,
+0x69,0x74,0x6c,0x65,0x3e,0x6c,0x77,0x49,0x50,0x20,0x2d,0x20,0x41,0x20,0x4c,0x69,
+0x67,0x68,0x74,0x77,0x65,0x69,0x67,0x68,0x74,0x20,0x54,0x43,0x50,0x2f,0x49,0x50,
+0x20,0x53,0x74,0x61,0x63,0x6b,0x3c,0x2f,0x74,0x69,0x74,0x6c,0x65,0x3e,0x3c,0x2f,
+0x68,0x65,0x61,0x64,0x3e,0x0d,0x0a,0x3c,0x62,0x6f,0x64,0x79,0x20,0x62,0x67,0x63,
+0x6f,0x6c,0x6f,0x72,0x3d,0x22,0x77,0x68,0x69,0x74,0x65,0x22,0x20,0x74,0x65,0x78,
+0x74,0x3d,0x22,0x62,0x6c,0x61,0x63,0x6b,0x22,0x3e,0x0d,0x0a,0x0d,0x0a,0x20,0x20,
+0x20,0x20,0x3c,0x74,0x61,0x62,0x6c,0x65,0x20,0x77,0x69,0x64,0x74,0x68,0x3d,0x22,
+0x31,0x30,0x30,0x25,0x22,0x3e,0x0d,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x3c,0x74,
+0x72,0x20,0x76,0x61,0x6c,0x69,0x67,0x6e,0x3d,0x22,0x74,0x6f,0x70,0x22,0x3e,0x3c,
+0x74,0x64,0x20,0x77,0x69,0x64,0x74,0x68,0x3d,0x22,0x38,0x30,0x22,0x3e,0x09,0x20,
+0x20,0x0d,0x0a,0x09,0x20,0x20,0x3c,0x61,0x20,0x68,0x72,0x65,0x66,0x3d,0x22,0x68,
+0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77,0x77,0x77,0x2e,0x73,0x69,0x63,0x73,0x2e,0x73,
+0x65,0x2f,0x22,0x3e,0x3c,0x69,0x6d,0x67,0x20,0x73,0x72,0x63,0x3d,0x22,0x2f,0x69,
+0x6d,0x67,0x2f,0x73,0x69,0x63,0x73,0x2e,0x67,0x69,0x66,0x22,0x0d,0x0a,0x09,0x20,
+0x20,0x62,0x6f,0x72,0x64,0x65,0x72,0x3d,0x22,0x30,0x22,0x20,0x61,0x6c,0x74,0x3d,
+0x22,0x53,0x49,0x43,0x53,0x20,0x6c,0x6f,0x67,0x6f,0x22,0x20,0x74,0x69,0x74,0x6c,
+0x65,0x3d,0x22,0x53,0x49,0x43,0x53,0x20,0x6c,0x6f,0x67,0x6f,0x22,0x3e,0x3c,0x2f,
+0x61,0x3e,0x0d,0x0a,0x09,0x3c,0x2f,0x74,0x64,0x3e,0x3c,0x74,0x64,0x20,0x77,0x69,
+0x64,0x74,0x68,0x3d,0x22,0x35,0x30,0x30,0x22,0x3e,0x09,0x20,0x20,0x0d,0x0a,0x09,
+0x20,0x20,0x3c,0x68,0x31,0x3e,0x6c,0x77,0x49,0x50,0x20,0x2d,0x20,0x41,0x20,0x4c,
+0x69,0x67,0x68,0x74,0x77,0x65,0x69,0x67,0x68,0x74,0x20,0x54,0x43,0x50,0x2f,0x49,
+0x50,0x20,0x53,0x74,0x61,0x63,0x6b,0x3c,0x2f,0x68,0x31,0x3e,0x0d,0x0a,0x09,0x20,
+0x20,0x3c,0x68,0x31,0x3e,0x3c,0x21,0x2d,0x2d,0x23,0x48,0x65,0x6c,0x6c,0x57,0x6f,
+0x72,0x6c,0x2d,0x2d,0x3e,0x3c,0x2f,0x68,0x31,0x3e,0x0d,0x0a,0x09,0x20,0x20,0x3c,
+0x70,0x3e,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x54,0x68,0x65,0x20,0x77,0x65,0x62,
+0x20,0x70,0x61,0x67,0x65,0x20,0x79,0x6f,0x75,0x20,0x61,0x72,0x65,0x20,0x77,0x61,
+0x74,0x63,0x68,0x69,0x6e,0x67,0x20,0x77,0x61,0x73,0x20,0x73,0x65,0x72,0x76,0x65,
+0x64,0x20,0x62,0x79,0x20,0x61,0x20,0x73,0x69,0x6d,0x70,0x6c,0x65,0x20,0x77,0x65,
+0x62,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x73,0x65,0x72,0x76,0x65,0x72,0x20,0x72,
+0x75,0x6e,0x6e,0x69,0x6e,0x67,0x20,0x6f,0x6e,0x20,0x74,0x6f,0x70,0x20,0x6f,0x66,
+0x20,0x74,0x68,0x65,0x20,0x6c,0x69,0x67,0x68,0x74,0x77,0x65,0x69,0x67,0x68,0x74,
+0x20,0x54,0x43,0x50,0x2f,0x49,0x50,0x20,0x73,0x74,0x61,0x63,0x6b,0x20,0x3c,0x61,
+0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x68,0x72,0x65,0x66,0x3d,0x22,0x68,0x74,0x74,
+0x70,0x3a,0x2f,0x2f,0x77,0x77,0x77,0x2e,0x73,0x69,0x63,0x73,0x2e,0x73,0x65,0x2f,
+0x7e,0x61,0x64,0x61,0x6d,0x2f,0x6c,0x77,0x69,0x70,0x2f,0x22,0x3e,0x6c,0x77,0x49,
+0x50,0x3c,0x2f,0x61,0x3e,0x2e,0x0d,0x0a,0x09,0x20,0x20,0x3c,0x2f,0x70,0x3e,0x0d,
+0x0a,0x09,0x20,0x20,0x3c,0x70,0x3e,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x54,0x68,
+0x69,0x73,0x20,0x70,0x61,0x67,0x65,0x20,0x69,0x73,0x20,0x68,0x65,0x72,0x65,0x20,
+0x74,0x6f,0x20,0x74,0x65,0x73,0x74,0x20,0x53,0x53,0x49,0x2c,0x20,0x73,0x6f,0x20,
+0x68,0x65,0x72,0x65,0x20,0x69,0x73,0x20,0x61,0x20,0x63,0x6f,0x75,0x6e,0x74,0x65,
+0x72,0x20,0x61,0x73,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x61,0x6e,0x20,0x65,0x78,
+0x61,0x6d,0x70,0x6c,0x65,0x20,0x6f,0x66,0x20,0x63,0x6f,0x6e,0x74,0x65,0x6e,0x74,
+0x20,0x63,0x68,0x61,0x6e,0x67,0x69,0x6e,0x67,0x20,0x66,0x6f,0x72,0x20,0x65,0x76,
+0x65,0x72,0x79,0x20,0x72,0x65,0x71,0x75,0x65,0x73,0x74,0x3a,0x0d,0x0a,0x09,0x20,
+0x20,0x20,0x20,0x22,0x3c,0x21,0x2d,0x2d,0x23,0x63,0x6f,0x75,0x6e,0x74,0x65,0x72,
+0x2d,0x2d,0x3e,0x22,0x0d,0x0a,0x09,0x20,0x20,0x3c,0x2f,0x70,0x3e,0x0d,0x0a,0x09,
+0x20,0x20,0x3c,0x70,0x3e,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x41,0x6e,0x64,0x20,
+0x68,0x65,0x72,0x65,0x20,0x69,0x73,0x20,0x61,0x6e,0x20,0x65,0x78,0x61,0x6d,0x70,
+0x6c,0x65,0x20,0x6f,0x66,0x20,0x61,0x20,0x74,0x61,0x67,0x20,0x72,0x65,0x73,0x75,
+0x6c,0x74,0x20,0x62,0x75,0x66,0x66,0x65,0x72,0x20,0x72,0x65,0x74,0x75,0x72,0x6e,
+0x20,0x69,0x6e,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x6d,0x75,0x6c,0x74,0x69,0x70,
+0x6c,0x65,0x20,0x70,0x61,0x72,0x74,0x73,0x3a,0x20,0x22,0x3c,0x21,0x2d,0x2d,0x23,
+0x4d,0x75,0x6c,0x74,0x50,0x61,0x72,0x74,0x2d,0x2d,0x3e,0x22,0x0d,0x0a,0x09,0x20,
+0x20,0x3c,0x2f,0x70,0x3e,0x0d,0x0a,0x09,0x20,0x20,0x3c,0x70,0x3e,0x0d,0x0a,0x09,
+0x20,0x20,0x20,0x20,0x54,0x6f,0x20,0x74,0x65,0x73,0x74,0x20,0x4c,0x57,0x49,0x50,
+0x5f,0x48,0x54,0x54,0x50,0x44,0x5f,0x43,0x47,0x49,0x5f,0x53,0x53,0x49,0x2c,0x20,
+0x68,0x65,0x72,0x65,0x20,0x61,0x72,0x65,0x20,0x74,0x68,0x65,0x20,0x43,0x47,0x49,
+0x20,0x70,0x61,0x72,0x61,0x6d,0x65,0x74,0x65,0x72,0x73,0x3a,0x0d,0x0a,0x09,0x20,
+0x20,0x20,0x20,0x3c,0x21,0x2d,0x2d,0x23,0x43,0x67,0x69,0x50,0x61,0x72,0x61,0x6d,
+0x2d,0x2d,0x3e,0x0d,0x0a,0x09,0x20,0x20,0x3c,0x2f,0x70,0x3e,0x0d,0x0a,0x09,0x20,
+0x20,0x3c,0x70,0x3e,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x6c,0x77,0x49,0x50,0x20,
+0x69,0x73,0x20,0x61,0x6e,0x20,0x6f,0x70,0x65,0x6e,0x20,0x73,0x6f,0x75,0x72,0x63,
+0x65,0x20,0x69,0x6d,0x70,0x6c,0x65,0x6d,0x65,0x6e,0x74,0x61,0x74,0x69,0x6f,0x6e,
+0x20,0x6f,0x66,0x20,0x74,0x68,0x65,0x20,0x54,0x43,0x50,0x2f,0x49,0x50,0x0d,0x0a,
+0x09,0x20,0x20,0x20,0x20,0x70,0x72,0x6f,0x74,0x6f,0x63,0x6f,0x6c,0x20,0x73,0x75,
+0x69,0x74,0x65,0x20,0x74,0x68,0x61,0x74,0x20,0x77,0x61,0x73,0x20,0x6f,0x72,0x69,
+0x67,0x69,0x6e,0x61,0x6c,0x6c,0x79,0x20,0x77,0x72,0x69,0x74,0x74,0x65,0x6e,0x20,
+0x62,0x79,0x20,0x3c,0x61,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x68,0x72,0x65,0x66,
+0x3d,0x22,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77,0x77,0x77,0x2e,0x73,0x69,0x63,
+0x73,0x2e,0x73,0x65,0x2f,0x7e,0x61,0x64,0x61,0x6d,0x2f,0x6c,0x77,0x69,0x70,0x2f,
+0x22,0x3e,0x41,0x64,0x61,0x6d,0x20,0x44,0x75,0x6e,0x6b,0x65,0x6c,0x73,0x0d,0x0a,
+0x09,0x20,0x20,0x20,0x20,0x6f,0x66,0x20,0x74,0x68,0x65,0x20,0x53,0x77,0x65,0x64,
+0x69,0x73,0x68,0x20,0x49,0x6e,0x73,0x74,0x69,0x74,0x75,0x74,0x65,0x20,0x6f,0x66,
+0x20,0x43,0x6f,0x6d,0x70,0x75,0x74,0x65,0x72,0x20,0x53,0x63,0x69,0x65,0x6e,0x63,
+0x65,0x3c,0x2f,0x61,0x3e,0x20,0x62,0x75,0x74,0x20,0x6e,0x6f,0x77,0x20,0x69,0x73,
+0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x62,0x65,0x69,0x6e,0x67,0x20,0x61,0x63,0x74,
+0x69,0x76,0x65,0x6c,0x79,0x20,0x64,0x65,0x76,0x65,0x6c,0x6f,0x70,0x65,0x64,0x20,
+0x62,0x79,0x20,0x61,0x20,0x74,0x65,0x61,0x6d,0x20,0x6f,0x66,0x20,0x64,0x65,0x76,
+0x65,0x6c,0x6f,0x70,0x65,0x72,0x73,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x64,0x69,
+0x73,0x74,0x72,0x69,0x62,0x75,0x74,0x65,0x64,0x20,0x77,0x6f,0x72,0x6c,0x64,0x2d,
+0x77,0x69,0x64,0x65,0x2e,0x20,0x53,0x69,0x6e,0x63,0x65,0x20,0x69,0x74,0x27,0x73,
+0x20,0x72,0x65,0x6c,0x65,0x61,0x73,0x65,0x2c,0x20,0x6c,0x77,0x49,0x50,0x20,0x68,
+0x61,0x73,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x73,0x70,0x75,0x72,0x72,0x65,0x64,
+0x20,0x61,0x20,0x6c,0x6f,0x74,0x20,0x6f,0x66,0x20,0x69,0x6e,0x74,0x65,0x72,0x65,
+0x73,0x74,0x20,0x61,0x6e,0x64,0x20,0x68,0x61,0x73,0x20,0x62,0x65,0x65,0x6e,0x20,
+0x70,0x6f,0x72,0x74,0x65,0x64,0x20,0x74,0x6f,0x20,0x73,0x65,0x76,0x65,0x72,0x61,
+0x6c,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x70,0x6c,0x61,0x74,0x66,0x6f,0x72,0x6d,
+0x73,0x20,0x61,0x6e,0x64,0x20,0x6f,0x70,0x65,0x72,0x61,0x74,0x69,0x6e,0x67,0x20,
+0x73,0x79,0x73,0x74,0x65,0x6d,0x73,0x2e,0x20,0x6c,0x77,0x49,0x50,0x20,0x63,0x61,
+0x6e,0x20,0x62,0x65,0x20,0x75,0x73,0x65,0x64,0x20,0x65,0x69,0x74,0x68,0x65,0x72,
+0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x77,0x69,0x74,0x68,0x20,0x6f,0x72,0x20,0x77,
+0x69,0x74,0x68,0x6f,0x75,0x74,0x20,0x61,0x6e,0x20,0x75,0x6e,0x64,0x65,0x72,0x6c,
+0x79,0x69,0x6e,0x67,0x20,0x4f,0x53,0x2e,0x0d,0x0a,0x09,0x20,0x20,0x3c,0x2f,0x70,
+0x3e,0x0d,0x0a,0x09,0x20,0x20,0x3c,0x70,0x3e,0x0d,0x0a,0x09,0x20,0x20,0x3c,0x70,
+0x3e,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x6c,0x77,0x49,0x50,0x20,0x69,0x73,0x20,
+0x61,0x6e,0x20,0x6f,0x70,0x65,0x6e,0x20,0x73,0x6f,0x75,0x72,0x63,0x65,0x20,0x69,
+0x6d,0x70,0x6c,0x65,0x6d,0x65,0x6e,0x74,0x61,0x74,0x69,0x6f,0x6e,0x20,0x6f,0x66,
+0x20,0x74,0x68,0x65,0x20,0x54,0x43,0x50,0x2f,0x49,0x50,0x0d,0x0a,0x09,0x20,0x20,
+0x20,0x20,0x70,0x72,0x6f,0x74,0x6f,0x63,0x6f,0x6c,0x20,0x73,0x75,0x69,0x74,0x65,
+0x20,0x74,0x68,0x61,0x74,0x20,0x77,0x61,0x73,0x20,0x6f,0x72,0x69,0x67,0x69,0x6e,
+0x61,0x6c,0x6c,0x79,0x20,0x77,0x72,0x69,0x74,0x74,0x65,0x6e,0x20,0x62,0x79,0x20,
+0x3c,0x61,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x68,0x72,0x65,0x66,0x3d,0x22,0x68,
+0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77,0x77,0x77,0x2e,0x73,0x69,0x63,0x73,0x2e,0x73,
+0x65,0x2f,0x7e,0x61,0x64,0x61,0x6d,0x2f,0x6c,0x77,0x69,0x70,0x2f,0x22,0x3e,0x41,
+0x64,0x61,0x6d,0x20,0x44,0x75,0x6e,0x6b,0x65,0x6c,0x73,0x0d,0x0a,0x09,0x20,0x20,
+0x20,0x20,0x6f,0x66,0x20,0x74,0x68,0x65,0x20,0x53,0x77,0x65,0x64,0x69,0x73,0x68,
+0x20,0x49,0x6e,0x73,0x74,0x69,0x74,0x75,0x74,0x65,0x20,0x6f,0x66,0x20,0x43,0x6f,
+0x6d,0x70,0x75,0x74,0x65,0x72,0x20,0x53,0x63,0x69,0x65,0x6e,0x63,0x65,0x3c,0x2f,
+0x61,0x3e,0x20,0x62,0x75,0x74,0x20,0x6e,0x6f,0x77,0x20,0x69,0x73,0x0d,0x0a,0x09,
+0x20,0x20,0x20,0x20,0x62,0x65,0x69,0x6e,0x67,0x20,0x61,0x63,0x74,0x69,0x76,0x65,
+0x6c,0x79,0x20,0x64,0x65,0x76,0x65,0x6c,0x6f,0x70,0x65,0x64,0x20,0x62,0x79,0x20,
+0x61,0x20,0x74,0x65,0x61,0x6d,0x20,0x6f,0x66,0x20,0x64,0x65,0x76,0x65,0x6c,0x6f,
+0x70,0x65,0x72,0x73,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x64,0x69,0x73,0x74,0x72,
+0x69,0x62,0x75,0x74,0x65,0x64,0x20,0x77,0x6f,0x72,0x6c,0x64,0x2d,0x77,0x69,0x64,
+0x65,0x2e,0x20,0x53,0x69,0x6e,0x63,0x65,0x20,0x69,0x74,0x27,0x73,0x20,0x72,0x65,
+0x6c,0x65,0x61,0x73,0x65,0x2c,0x20,0x6c,0x77,0x49,0x50,0x20,0x68,0x61,0x73,0x0d,
+0x0a,0x09,0x20,0x20,0x20,0x20,0x73,0x70,0x75,0x72,0x72,0x65,0x64,0x20,0x61,0x20,
+0x6c,0x6f,0x74,0x20,0x6f,0x66,0x20,0x69,0x6e,0x74,0x65,0x72,0x65,0x73,0x74,0x20,
+0x61,0x6e,0x64,0x20,0x68,0x61,0x73,0x20,0x62,0x65,0x65,0x6e,0x20,0x70,0x6f,0x72,
+0x74,0x65,0x64,0x20,0x74,0x6f,0x20,0x73,0x65,0x76,0x65,0x72,0x61,0x6c,0x0d,0x0a,
+0x09,0x20,0x20,0x20,0x20,0x70,0x6c,0x61,0x74,0x66,0x6f,0x72,0x6d,0x73,0x20,0x61,
+0x6e,0x64,0x20,0x6f,0x70,0x65,0x72,0x61,0x74,0x69,0x6e,0x67,0x20,0x73,0x79,0x73,
+0x74,0x65,0x6d,0x73,0x2e,0x20,0x6c,0x77,0x49,0x50,0x20,0x63,0x61,0x6e,0x20,0x62,
+0x65,0x20,0x75,0x73,0x65,0x64,0x20,0x65,0x69,0x74,0x68,0x65,0x72,0x0d,0x0a,0x09,
+0x20,0x20,0x20,0x20,0x77,0x69,0x74,0x68,0x20,0x6f,0x72,0x20,0x77,0x69,0x74,0x68,
+0x6f,0x75,0x74,0x20,0x61,0x6e,0x20,0x75,0x6e,0x64,0x65,0x72,0x6c,0x79,0x69,0x6e,
+0x67,0x20,0x4f,0x53,0x2e,0x0d,0x0a,0x09,0x20,0x20,0x3c,0x2f,0x70,0x3e,0x0d,0x0a,
+0x09,0x20,0x20,0x3c,0x70,0x3e,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x6c,0x77,0x49,
+0x50,0x20,0x69,0x73,0x20,0x61,0x6e,0x20,0x6f,0x70,0x65,0x6e,0x20,0x73,0x6f,0x75,
+0x72,0x63,0x65,0x20,0x69,0x6d,0x70,0x6c,0x65,0x6d,0x65,0x6e,0x74,0x61,0x74,0x69,
+0x6f,0x6e,0x20,0x6f,0x66,0x20,0x74,0x68,0x65,0x20,0x54,0x43,0x50,0x2f,0x49,0x50,
+0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x70,0x72,0x6f,0x74,0x6f,0x63,0x6f,0x6c,0x20,
+0x73,0x75,0x69,0x74,0x65,0x20,0x74,0x68,0x61,0x74,0x20,0x77,0x61,0x73,0x20,0x6f,
+0x72,0x69,0x67,0x69,0x6e,0x61,0x6c,0x6c,0x79,0x20,0x77,0x72,0x69,0x74,0x74,0x65,
+0x6e,0x20,0x62,0x79,0x20,0x3c,0x61,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x68,0x72,
+0x65,0x66,0x3d,0x22,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77,0x77,0x77,0x2e,0x73,
+0x69,0x63,0x73,0x2e,0x73,0x65,0x2f,0x7e,0x61,0x64,0x61,0x6d,0x2f,0x6c,0x77,0x69,
+0x70,0x2f,0x22,0x3e,0x41,0x64,0x61,0x6d,0x20,0x44,0x75,0x6e,0x6b,0x65,0x6c,0x73,
+0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x6f,0x66,0x20,0x74,0x68,0x65,0x20,0x53,0x77,
+0x65,0x64,0x69,0x73,0x68,0x20,0x49,0x6e,0x73,0x74,0x69,0x74,0x75,0x74,0x65,0x20,
+0x6f,0x66,0x20,0x43,0x6f,0x6d,0x70,0x75,0x74,0x65,0x72,0x20,0x53,0x63,0x69,0x65,
+0x6e,0x63,0x65,0x3c,0x2f,0x61,0x3e,0x20,0x62,0x75,0x74,0x20,0x6e,0x6f,0x77,0x20,
+0x69,0x73,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x62,0x65,0x69,0x6e,0x67,0x20,0x61,
+0x63,0x74,0x69,0x76,0x65,0x6c,0x79,0x20,0x64,0x65,0x76,0x65,0x6c,0x6f,0x70,0x65,
+0x64,0x20,0x62,0x79,0x20,0x61,0x20,0x74,0x65,0x61,0x6d,0x20,0x6f,0x66,0x20,0x64,
+0x65,0x76,0x65,0x6c,0x6f,0x70,0x65,0x72,0x73,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,
+0x64,0x69,0x73,0x74,0x72,0x69,0x62,0x75,0x74,0x65,0x64,0x20,0x77,0x6f,0x72,0x6c,
+0x64,0x2d,0x77,0x69,0x64,0x65,0x2e,0x20,0x53,0x69,0x6e,0x63,0x65,0x20,0x69,0x74,
+0x27,0x73,0x20,0x72,0x65,0x6c,0x65,0x61,0x73,0x65,0x2c,0x20,0x6c,0x77,0x49,0x50,
+0x20,0x68,0x61,0x73,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x73,0x70,0x75,0x72,0x72,
+0x65,0x64,0x20,0x61,0x20,0x6c,0x6f,0x74,0x20,0x6f,0x66,0x20,0x69,0x6e,0x74,0x65,
+0x72,0x65,0x73,0x74,0x20,0x61,0x6e,0x64,0x20,0x68,0x61,0x73,0x20,0x62,0x65,0x65,
+0x6e,0x20,0x70,0x6f,0x72,0x74,0x65,0x64,0x20,0x74,0x6f,0x20,0x73,0x65,0x76,0x65,
+0x72,0x61,0x6c,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x70,0x6c,0x61,0x74,0x66,0x6f,
+0x72,0x6d,0x73,0x20,0x61,0x6e,0x64,0x20,0x6f,0x70,0x65,0x72,0x61,0x74,0x69,0x6e,
+0x67,0x20,0x73,0x79,0x73,0x74,0x65,0x6d,0x73,0x2e,0x20,0x6c,0x77,0x49,0x50,0x20,
+0x63,0x61,0x6e,0x20,0x62,0x65,0x20,0x75,0x73,0x65,0x64,0x20,0x65,0x69,0x74,0x68,
+0x65,0x72,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x77,0x69,0x74,0x68,0x20,0x6f,0x72,
+0x20,0x77,0x69,0x74,0x68,0x6f,0x75,0x74,0x20,0x61,0x6e,0x20,0x75,0x6e,0x64,0x65,
+0x72,0x6c,0x79,0x69,0x6e,0x67,0x20,0x4f,0x53,0x2e,0x0d,0x0a,0x09,0x20,0x20,0x3c,
+0x2f,0x70,0x3e,0x0d,0x0a,0x09,0x20,0x20,0x3c,0x70,0x3e,0x0d,0x0a,0x09,0x20,0x20,
+0x20,0x20,0x6c,0x77,0x49,0x50,0x20,0x69,0x73,0x20,0x61,0x6e,0x20,0x6f,0x70,0x65,
+0x6e,0x20,0x73,0x6f,0x75,0x72,0x63,0x65,0x20,0x69,0x6d,0x70,0x6c,0x65,0x6d,0x65,
+0x6e,0x74,0x61,0x74,0x69,0x6f,0x6e,0x20,0x6f,0x66,0x20,0x74,0x68,0x65,0x20,0x54,
+0x43,0x50,0x2f,0x49,0x50,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x70,0x72,0x6f,0x74,
+0x6f,0x63,0x6f,0x6c,0x20,0x73,0x75,0x69,0x74,0x65,0x20,0x74,0x68,0x61,0x74,0x20,
+0x77,0x61,0x73,0x20,0x6f,0x72,0x69,0x67,0x69,0x6e,0x61,0x6c,0x6c,0x79,0x20,0x77,
+0x72,0x69,0x74,0x74,0x65,0x6e,0x20,0x62,0x79,0x20,0x3c,0x61,0x0d,0x0a,0x09,0x20,
+0x20,0x20,0x20,0x68,0x72,0x65,0x66,0x3d,0x22,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,
+0x77,0x77,0x77,0x2e,0x73,0x69,0x63,0x73,0x2e,0x73,0x65,0x2f,0x7e,0x61,0x64,0x61,
+0x6d,0x2f,0x6c,0x77,0x69,0x70,0x2f,0x22,0x3e,0x41,0x64,0x61,0x6d,0x20,0x44,0x75,
+0x6e,0x6b,0x65,0x6c,0x73,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x6f,0x66,0x20,0x74,
+0x68,0x65,0x20,0x53,0x77,0x65,0x64,0x69,0x73,0x68,0x20,0x49,0x6e,0x73,0x74,0x69,
+0x74,0x75,0x74,0x65,0x20,0x6f,0x66,0x20,0x43,0x6f,0x6d,0x70,0x75,0x74,0x65,0x72,
+0x20,0x53,0x63,0x69,0x65,0x6e,0x63,0x65,0x3c,0x2f,0x61,0x3e,0x20,0x62,0x75,0x74,
+0x20,0x6e,0x6f,0x77,0x20,0x69,0x73,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x62,0x65,
+0x69,0x6e,0x67,0x20,0x61,0x63,0x74,0x69,0x76,0x65,0x6c,0x79,0x20,0x64,0x65,0x76,
+0x65,0x6c,0x6f,0x70,0x65,0x64,0x20,0x62,0x79,0x20,0x61,0x20,0x74,0x65,0x61,0x6d,
+0x20,0x6f,0x66,0x20,0x64,0x65,0x76,0x65,0x6c,0x6f,0x70,0x65,0x72,0x73,0x0d,0x0a,
+0x09,0x20,0x20,0x20,0x20,0x64,0x69,0x73,0x74,0x72,0x69,0x62,0x75,0x74,0x65,0x64,
+0x20,0x77,0x6f,0x72,0x6c,0x64,0x2d,0x77,0x69,0x64,0x65,0x2e,0x20,0x53,0x69,0x6e,
+0x63,0x65,0x20,0x69,0x74,0x27,0x73,0x20,0x72,0x65,0x6c,0x65,0x61,0x73,0x65,0x2c,
+0x20,0x6c,0x77,0x49,0x50,0x20,0x68,0x61,0x73,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,
+0x73,0x70,0x75,0x72,0x72,0x65,0x64,0x20,0x61,0x20,0x6c,0x6f,0x74,0x20,0x6f,0x66,
+0x20,0x69,0x6e,0x74,0x65,0x72,0x65,0x73,0x74,0x20,0x61,0x6e,0x64,0x20,0x68,0x61,
+0x73,0x20,0x62,0x65,0x65,0x6e,0x20,0x70,0x6f,0x72,0x74,0x65,0x64,0x20,0x74,0x6f,
+0x20,0x73,0x65,0x76,0x65,0x72,0x61,0x6c,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x70,
+0x6c,0x61,0x74,0x66,0x6f,0x72,0x6d,0x73,0x20,0x61,0x6e,0x64,0x20,0x6f,0x70,0x65,
+0x72,0x61,0x74,0x69,0x6e,0x67,0x20,0x73,0x79,0x73,0x74,0x65,0x6d,0x73,0x2e,0x20,
+0x6c,0x77,0x49,0x50,0x20,0x63,0x61,0x6e,0x20,0x62,0x65,0x20,0x75,0x73,0x65,0x64,
+0x20,0x65,0x69,0x74,0x68,0x65,0x72,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x77,0x69,
+0x74,0x68,0x20,0x6f,0x72,0x20,0x77,0x69,0x74,0x68,0x6f,0x75,0x74,0x20,0x61,0x6e,
+0x20,0x75,0x6e,0x64,0x65,0x72,0x6c,0x79,0x69,0x6e,0x67,0x20,0x4f,0x53,0x2e,0x0d,
+0x0a,0x09,0x20,0x20,0x3c,0x2f,0x70,0x3e,0x0d,0x0a,0x09,0x20,0x20,0x3c,0x70,0x3e,
+0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x6c,0x77,0x49,0x50,0x20,0x69,0x73,0x20,0x61,
+0x6e,0x20,0x6f,0x70,0x65,0x6e,0x20,0x73,0x6f,0x75,0x72,0x63,0x65,0x20,0x69,0x6d,
+0x70,0x6c,0x65,0x6d,0x65,0x6e,0x74,0x61,0x74,0x69,0x6f,0x6e,0x20,0x6f,0x66,0x20,
+0x74,0x68,0x65,0x20,0x54,0x43,0x50,0x2f,0x49,0x50,0x0d,0x0a,0x09,0x20,0x20,0x20,
+0x20,0x70,0x72,0x6f,0x74,0x6f,0x63,0x6f,0x6c,0x20,0x73,0x75,0x69,0x74,0x65,0x20,
+0x74,0x68,0x61,0x74,0x20,0x77,0x61,0x73,0x20,0x6f,0x72,0x69,0x67,0x69,0x6e,0x61,
+0x6c,0x6c,0x79,0x20,0x77,0x72,0x69,0x74,0x74,0x65,0x6e,0x20,0x62,0x79,0x20,0x3c,
+0x61,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x68,0x72,0x65,0x66,0x3d,0x22,0x68,0x74,
+0x74,0x70,0x3a,0x2f,0x2f,0x77,0x77,0x77,0x2e,0x73,0x69,0x63,0x73,0x2e,0x73,0x65,
+0x2f,0x7e,0x61,0x64,0x61,0x6d,0x2f,0x6c,0x77,0x69,0x70,0x2f,0x22,0x3e,0x41,0x64,
+0x61,0x6d,0x20,0x44,0x75,0x6e,0x6b,0x65,0x6c,0x73,0x0d,0x0a,0x09,0x20,0x20,0x20,
+0x20,0x6f,0x66,0x20,0x74,0x68,0x65,0x20,0x53,0x77,0x65,0x64,0x69,0x73,0x68,0x20,
+0x49,0x6e,0x73,0x74,0x69,0x74,0x75,0x74,0x65,0x20,0x6f,0x66,0x20,0x43,0x6f,0x6d,
+0x70,0x75,0x74,0x65,0x72,0x20,0x53,0x63,0x69,0x65,0x6e,0x63,0x65,0x3c,0x2f,0x61,
+0x3e,0x20,0x62,0x75,0x74,0x20,0x6e,0x6f,0x77,0x20,0x69,0x73,0x0d,0x0a,0x09,0x20,
+0x20,0x20,0x20,0x62,0x65,0x69,0x6e,0x67,0x20,0x61,0x63,0x74,0x69,0x76,0x65,0x6c,
+0x79,0x20,0x64,0x65,0x76,0x65,0x6c,0x6f,0x70,0x65,0x64,0x20,0x62,0x79,0x20,0x61,
+0x20,0x74,0x65,0x61,0x6d,0x20,0x6f,0x66,0x20,0x64,0x65,0x76,0x65,0x6c,0x6f,0x70,
+0x65,0x72,0x73,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x64,0x69,0x73,0x74,0x72,0x69,
+0x62,0x75,0x74,0x65,0x64,0x20,0x77,0x6f,0x72,0x6c,0x64,0x2d,0x77,0x69,0x64,0x65,
+0x2e,0x20,0x53,0x69,0x6e,0x63,0x65,0x20,0x69,0x74,0x27,0x73,0x20,0x72,0x65,0x6c,
+0x65,0x61,0x73,0x65,0x2c,0x20,0x6c,0x77,0x49,0x50,0x20,0x68,0x61,0x73,0x0d,0x0a,
+0x09,0x20,0x20,0x20,0x20,0x73,0x70,0x75,0x72,0x72,0x65,0x64,0x20,0x61,0x20,0x6c,
+0x6f,0x74,0x20,0x6f,0x66,0x20,0x69,0x6e,0x74,0x65,0x72,0x65,0x73,0x74,0x20,0x61,
+0x6e,0x64,0x20,0x68,0x61,0x73,0x20,0x62,0x65,0x65,0x6e,0x20,0x70,0x6f,0x72,0x74,
+0x65,0x64,0x20,0x74,0x6f,0x20,0x73,0x65,0x76,0x65,0x72,0x61,0x6c,0x0d,0x0a,0x09,
+0x20,0x20,0x20,0x20,0x70,0x6c,0x61,0x74,0x66,0x6f,0x72,0x6d,0x73,0x20,0x61,0x6e,
+0x64,0x20,0x6f,0x70,0x65,0x72,0x61,0x74,0x69,0x6e,0x67,0x20,0x73,0x79,0x73,0x74,
+0x65,0x6d,0x73,0x2e,0x20,0x6c,0x77,0x49,0x50,0x20,0x63,0x61,0x6e,0x20,0x62,0x65,
+0x20,0x75,0x73,0x65,0x64,0x20,0x65,0x69,0x74,0x68,0x65,0x72,0x0d,0x0a,0x09,0x20,
+0x20,0x20,0x20,0x77,0x69,0x74,0x68,0x20,0x6f,0x72,0x20,0x77,0x69,0x74,0x68,0x6f,
+0x75,0x74,0x20,0x61,0x6e,0x20,0x75,0x6e,0x64,0x65,0x72,0x6c,0x79,0x69,0x6e,0x67,
+0x20,0x4f,0x53,0x2e,0x0d,0x0a,0x09,0x20,0x20,0x3c,0x2f,0x70,0x3e,0x0d,0x0a,0x09,
+0x20,0x20,0x3c,0x70,0x3e,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x6c,0x77,0x49,0x50,
+0x20,0x69,0x73,0x20,0x61,0x6e,0x20,0x6f,0x70,0x65,0x6e,0x20,0x73,0x6f,0x75,0x72,
+0x63,0x65,0x20,0x69,0x6d,0x70,0x6c,0x65,0x6d,0x65,0x6e,0x74,0x61,0x74,0x69,0x6f,
+0x6e,0x20,0x6f,0x66,0x20,0x74,0x68,0x65,0x20,0x54,0x43,0x50,0x2f,0x49,0x50,0x0d,
+0x0a,0x09,0x20,0x20,0x20,0x20,0x70,0x72,0x6f,0x74,0x6f,0x63,0x6f,0x6c,0x20,0x73,
+0x75,0x69,0x74,0x65,0x20,0x74,0x68,0x61,0x74,0x20,0x77,0x61,0x73,0x20,0x6f,0x72,
+0x69,0x67,0x69,0x6e,0x61,0x6c,0x6c,0x79,0x20,0x77,0x72,0x69,0x74,0x74,0x65,0x6e,
+0x20,0x62,0x79,0x20,0x3c,0x61,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x68,0x72,0x65,
+0x66,0x3d,0x22,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77,0x77,0x77,0x2e,0x73,0x69,
+0x63,0x73,0x2e,0x73,0x65,0x2f,0x7e,0x61,0x64,0x61,0x6d,0x2f,0x6c,0x77,0x69,0x70,
+0x2f,0x22,0x3e,0x41,0x64,0x61,0x6d,0x20,0x44,0x75,0x6e,0x6b,0x65,0x6c,0x73,0x0d,
+0x0a,0x09,0x20,0x20,0x20,0x20,0x6f,0x66,0x20,0x74,0x68,0x65,0x20,0x53,0x77,0x65,
+0x64,0x69,0x73,0x68,0x20,0x49,0x6e,0x73,0x74,0x69,0x74,0x75,0x74,0x65,0x20,0x6f,
+0x66,0x20,0x43,0x6f,0x6d,0x70,0x75,0x74,0x65,0x72,0x20,0x53,0x63,0x69,0x65,0x6e,
+0x63,0x65,0x3c,0x2f,0x61,0x3e,0x20,0x62,0x75,0x74,0x20,0x6e,0x6f,0x77,0x20,0x69,
+0x73,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x62,0x65,0x69,0x6e,0x67,0x20,0x61,0x63,
+0x74,0x69,0x76,0x65,0x6c,0x79,0x20,0x64,0x65,0x76,0x65,0x6c,0x6f,0x70,0x65,0x64,
+0x20,0x62,0x79,0x20,0x61,0x20,0x74,0x65,0x61,0x6d,0x20,0x6f,0x66,0x20,0x64,0x65,
+0x76,0x65,0x6c,0x6f,0x70,0x65,0x72,0x73,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x64,
+0x69,0x73,0x74,0x72,0x69,0x62,0x75,0x74,0x65,0x64,0x20,0x77,0x6f,0x72,0x6c,0x64,
+0x2d,0x77,0x69,0x64,0x65,0x2e,0x20,0x53,0x69,0x6e,0x63,0x65,0x20,0x69,0x74,0x27,
+0x73,0x20,0x72,0x65,0x6c,0x65,0x61,0x73,0x65,0x2c,0x20,0x6c,0x77,0x49,0x50,0x20,
+0x68,0x61,0x73,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x73,0x70,0x75,0x72,0x72,0x65,
+0x64,0x20,0x61,0x20,0x6c,0x6f,0x74,0x20,0x6f,0x66,0x20,0x69,0x6e,0x74,0x65,0x72,
+0x65,0x73,0x74,0x20,0x61,0x6e,0x64,0x20,0x68,0x61,0x73,0x20,0x62,0x65,0x65,0x6e,
+0x20,0x70,0x6f,0x72,0x74,0x65,0x64,0x20,0x74,0x6f,0x20,0x73,0x65,0x76,0x65,0x72,
+0x61,0x6c,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x70,0x6c,0x61,0x74,0x66,0x6f,0x72,
+0x6d,0x73,0x20,0x61,0x6e,0x64,0x20,0x6f,0x70,0x65,0x72,0x61,0x74,0x69,0x6e,0x67,
+0x20,0x73,0x79,0x73,0x74,0x65,0x6d,0x73,0x2e,0x20,0x6c,0x77,0x49,0x50,0x20,0x63,
+0x61,0x6e,0x20,0x62,0x65,0x20,0x75,0x73,0x65,0x64,0x20,0x65,0x69,0x74,0x68,0x65,
+0x72,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x77,0x69,0x74,0x68,0x20,0x6f,0x72,0x20,
+0x77,0x69,0x74,0x68,0x6f,0x75,0x74,0x20,0x61,0x6e,0x20,0x75,0x6e,0x64,0x65,0x72,
+0x6c,0x79,0x69,0x6e,0x67,0x20,0x4f,0x53,0x2e,0x0d,0x0a,0x09,0x20,0x20,0x3c,0x2f,
+0x70,0x3e,0x0d,0x0a,0x09,0x20,0x20,0x3c,0x70,0x3e,0x0d,0x0a,0x09,0x20,0x20,0x20,
+0x20,0x6c,0x77,0x49,0x50,0x20,0x69,0x73,0x20,0x61,0x6e,0x20,0x6f,0x70,0x65,0x6e,
+0x20,0x73,0x6f,0x75,0x72,0x63,0x65,0x20,0x69,0x6d,0x70,0x6c,0x65,0x6d,0x65,0x6e,
+0x74,0x61,0x74,0x69,0x6f,0x6e,0x20,0x6f,0x66,0x20,0x74,0x68,0x65,0x20,0x54,0x43,
+0x50,0x2f,0x49,0x50,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x70,0x72,0x6f,0x74,0x6f,
+0x63,0x6f,0x6c,0x20,0x73,0x75,0x69,0x74,0x65,0x20,0x74,0x68,0x61,0x74,0x20,0x77,
+0x61,0x73,0x20,0x6f,0x72,0x69,0x67,0x69,0x6e,0x61,0x6c,0x6c,0x79,0x20,0x77,0x72,
+0x69,0x74,0x74,0x65,0x6e,0x20,0x62,0x79,0x20,0x3c,0x61,0x0d,0x0a,0x09,0x20,0x20,
+0x20,0x20,0x68,0x72,0x65,0x66,0x3d,0x22,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77,
+0x77,0x77,0x2e,0x73,0x69,0x63,0x73,0x2e,0x73,0x65,0x2f,0x7e,0x61,0x64,0x61,0x6d,
+0x2f,0x6c,0x77,0x69,0x70,0x2f,0x22,0x3e,0x41,0x64,0x61,0x6d,0x20,0x44,0x75,0x6e,
+0x6b,0x65,0x6c,0x73,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x6f,0x66,0x20,0x74,0x68,
+0x65,0x20,0x53,0x77,0x65,0x64,0x69,0x73,0x68,0x20,0x49,0x6e,0x73,0x74,0x69,0x74,
+0x75,0x74,0x65,0x20,0x6f,0x66,0x20,0x43,0x6f,0x6d,0x70,0x75,0x74,0x65,0x72,0x20,
+0x53,0x63,0x69,0x65,0x6e,0x63,0x65,0x3c,0x2f,0x61,0x3e,0x20,0x62,0x75,0x74,0x20,
+0x6e,0x6f,0x77,0x20,0x69,0x73,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x62,0x65,0x69,
+0x6e,0x67,0x20,0x61,0x63,0x74,0x69,0x76,0x65,0x6c,0x79,0x20,0x64,0x65,0x76,0x65,
+0x6c,0x6f,0x70,0x65,0x64,0x20,0x62,0x79,0x20,0x61,0x20,0x74,0x65,0x61,0x6d,0x20,
+0x6f,0x66,0x20,0x64,0x65,0x76,0x65,0x6c,0x6f,0x70,0x65,0x72,0x73,0x0d,0x0a,0x09,
+0x20,0x20,0x20,0x20,0x64,0x69,0x73,0x74,0x72,0x69,0x62,0x75,0x74,0x65,0x64,0x20,
+0x77,0x6f,0x72,0x6c,0x64,0x2d,0x77,0x69,0x64,0x65,0x2e,0x20,0x53,0x69,0x6e,0x63,
+0x65,0x20,0x69,0x74,0x27,0x73,0x20,0x72,0x65,0x6c,0x65,0x61,0x73,0x65,0x2c,0x20,
+0x6c,0x77,0x49,0x50,0x20,0x68,0x61,0x73,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x73,
+0x70,0x75,0x72,0x72,0x65,0x64,0x20,0x61,0x20,0x6c,0x6f,0x74,0x20,0x6f,0x66,0x20,
+0x69,0x6e,0x74,0x65,0x72,0x65,0x73,0x74,0x20,0x61,0x6e,0x64,0x20,0x68,0x61,0x73,
+0x20,0x62,0x65,0x65,0x6e,0x20,0x70,0x6f,0x72,0x74,0x65,0x64,0x20,0x74,0x6f,0x20,
+0x73,0x65,0x76,0x65,0x72,0x61,0x6c,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x70,0x6c,
+0x61,0x74,0x66,0x6f,0x72,0x6d,0x73,0x20,0x61,0x6e,0x64,0x20,0x6f,0x70,0x65,0x72,
+0x61,0x74,0x69,0x6e,0x67,0x20,0x73,0x79,0x73,0x74,0x65,0x6d,0x73,0x2e,0x20,0x6c,
+0x77,0x49,0x50,0x20,0x63,0x61,0x6e,0x20,0x62,0x65,0x20,0x75,0x73,0x65,0x64,0x20,
+0x65,0x69,0x74,0x68,0x65,0x72,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x77,0x69,0x74,
+0x68,0x20,0x6f,0x72,0x20,0x77,0x69,0x74,0x68,0x6f,0x75,0x74,0x20,0x61,0x6e,0x20,
+0x75,0x6e,0x64,0x65,0x72,0x6c,0x79,0x69,0x6e,0x67,0x20,0x4f,0x53,0x2e,0x0d,0x0a,
+0x09,0x20,0x20,0x3c,0x2f,0x70,0x3e,0x0d,0x0a,0x09,0x20,0x20,0x3c,0x70,0x3e,0x0d,
+0x0a,0x09,0x20,0x20,0x20,0x20,0x6c,0x77,0x49,0x50,0x20,0x69,0x73,0x20,0x61,0x6e,
+0x20,0x6f,0x70,0x65,0x6e,0x20,0x73,0x6f,0x75,0x72,0x63,0x65,0x20,0x69,0x6d,0x70,
+0x6c,0x65,0x6d,0x65,0x6e,0x74,0x61,0x74,0x69,0x6f,0x6e,0x20,0x6f,0x66,0x20,0x74,
+0x68,0x65,0x20,0x54,0x43,0x50,0x2f,0x49,0x50,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,
+0x70,0x72,0x6f,0x74,0x6f,0x63,0x6f,0x6c,0x20,0x73,0x75,0x69,0x74,0x65,0x20,0x74,
+0x68,0x61,0x74,0x20,0x77,0x61,0x73,0x20,0x6f,0x72,0x69,0x67,0x69,0x6e,0x61,0x6c,
+0x6c,0x79,0x20,0x77,0x72,0x69,0x74,0x74,0x65,0x6e,0x20,0x62,0x79,0x20,0x3c,0x61,
+0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x68,0x72,0x65,0x66,0x3d,0x22,0x68,0x74,0x74,
+0x70,0x3a,0x2f,0x2f,0x77,0x77,0x77,0x2e,0x73,0x69,0x63,0x73,0x2e,0x73,0x65,0x2f,
+0x7e,0x61,0x64,0x61,0x6d,0x2f,0x6c,0x77,0x69,0x70,0x2f,0x22,0x3e,0x41,0x64,0x61,
+0x6d,0x20,0x44,0x75,0x6e,0x6b,0x65,0x6c,0x73,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,
+0x6f,0x66,0x20,0x74,0x68,0x65,0x20,0x53,0x77,0x65,0x64,0x69,0x73,0x68,0x20,0x49,
+0x6e,0x73,0x74,0x69,0x74,0x75,0x74,0x65,0x20,0x6f,0x66,0x20,0x43,0x6f,0x6d,0x70,
+0x75,0x74,0x65,0x72,0x20,0x53,0x63,0x69,0x65,0x6e,0x63,0x65,0x3c,0x2f,0x61,0x3e,
+0x20,0x62,0x75,0x74,0x20,0x6e,0x6f,0x77,0x20,0x69,0x73,0x0d,0x0a,0x09,0x20,0x20,
+0x20,0x20,0x62,0x65,0x69,0x6e,0x67,0x20,0x61,0x63,0x74,0x69,0x76,0x65,0x6c,0x79,
+0x20,0x64,0x65,0x76,0x65,0x6c,0x6f,0x70,0x65,0x64,0x20,0x62,0x79,0x20,0x61,0x20,
+0x74,0x65,0x61,0x6d,0x20,0x6f,0x66,0x20,0x64,0x65,0x76,0x65,0x6c,0x6f,0x70,0x65,
+0x72,0x73,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x64,0x69,0x73,0x74,0x72,0x69,0x62,
+0x75,0x74,0x65,0x64,0x20,0x77,0x6f,0x72,0x6c,0x64,0x2d,0x77,0x69,0x64,0x65,0x2e,
+0x20,0x53,0x69,0x6e,0x63,0x65,0x20,0x69,0x74,0x27,0x73,0x20,0x72,0x65,0x6c,0x65,
+0x61,0x73,0x65,0x2c,0x20,0x6c,0x77,0x49,0x50,0x20,0x68,0x61,0x73,0x0d,0x0a,0x09,
+0x20,0x20,0x20,0x20,0x73,0x70,0x75,0x72,0x72,0x65,0x64,0x20,0x61,0x20,0x6c,0x6f,
+0x74,0x20,0x6f,0x66,0x20,0x69,0x6e,0x74,0x65,0x72,0x65,0x73,0x74,0x20,0x61,0x6e,
+0x64,0x20,0x68,0x61,0x73,0x20,0x62,0x65,0x65,0x6e,0x20,0x70,0x6f,0x72,0x74,0x65,
+0x64,0x20,0x74,0x6f,0x20,0x73,0x65,0x76,0x65,0x72,0x61,0x6c,0x0d,0x0a,0x09,0x20,
+0x20,0x20,0x20,0x70,0x6c,0x61,0x74,0x66,0x6f,0x72,0x6d,0x73,0x20,0x61,0x6e,0x64,
+0x20,0x6f,0x70,0x65,0x72,0x61,0x74,0x69,0x6e,0x67,0x20,0x73,0x79,0x73,0x74,0x65,
+0x6d,0x73,0x2e,0x20,0x6c,0x77,0x49,0x50,0x20,0x63,0x61,0x6e,0x20,0x62,0x65,0x20,
+0x75,0x73,0x65,0x64,0x20,0x65,0x69,0x74,0x68,0x65,0x72,0x0d,0x0a,0x09,0x20,0x20,
+0x20,0x20,0x77,0x69,0x74,0x68,0x20,0x6f,0x72,0x20,0x77,0x69,0x74,0x68,0x6f,0x75,
+0x74,0x20,0x61,0x6e,0x20,0x75,0x6e,0x64,0x65,0x72,0x6c,0x79,0x69,0x6e,0x67,0x20,
+0x4f,0x53,0x2e,0x0d,0x0a,0x09,0x20,0x20,0x3c,0x2f,0x70,0x3e,0x0d,0x0a,0x09,0x20,
+0x20,0x3c,0x70,0x3e,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x6c,0x77,0x49,0x50,0x20,
+0x69,0x73,0x20,0x61,0x6e,0x20,0x6f,0x70,0x65,0x6e,0x20,0x73,0x6f,0x75,0x72,0x63,
+0x65,0x20,0x69,0x6d,0x70,0x6c,0x65,0x6d,0x65,0x6e,0x74,0x61,0x74,0x69,0x6f,0x6e,
+0x20,0x6f,0x66,0x20,0x74,0x68,0x65,0x20,0x54,0x43,0x50,0x2f,0x49,0x50,0x0d,0x0a,
+0x09,0x20,0x20,0x20,0x20,0x70,0x72,0x6f,0x74,0x6f,0x63,0x6f,0x6c,0x20,0x73,0x75,
+0x69,0x74,0x65,0x20,0x74,0x68,0x61,0x74,0x20,0x77,0x61,0x73,0x20,0x6f,0x72,0x69,
+0x67,0x69,0x6e,0x61,0x6c,0x6c,0x79,0x20,0x77,0x72,0x69,0x74,0x74,0x65,0x6e,0x20,
+0x62,0x79,0x20,0x3c,0x61,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x68,0x72,0x65,0x66,
+0x3d,0x22,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77,0x77,0x77,0x2e,0x73,0x69,0x63,
+0x73,0x2e,0x73,0x65,0x2f,0x7e,0x61,0x64,0x61,0x6d,0x2f,0x6c,0x77,0x69,0x70,0x2f,
+0x22,0x3e,0x41,0x64,0x61,0x6d,0x20,0x44,0x75,0x6e,0x6b,0x65,0x6c,0x73,0x0d,0x0a,
+0x09,0x20,0x20,0x20,0x20,0x6f,0x66,0x20,0x74,0x68,0x65,0x20,0x53,0x77,0x65,0x64,
+0x69,0x73,0x68,0x20,0x49,0x6e,0x73,0x74,0x69,0x74,0x75,0x74,0x65,0x20,0x6f,0x66,
+0x20,0x43,0x6f,0x6d,0x70,0x75,0x74,0x65,0x72,0x20,0x53,0x63,0x69,0x65,0x6e,0x63,
+0x65,0x3c,0x2f,0x61,0x3e,0x20,0x62,0x75,0x74,0x20,0x6e,0x6f,0x77,0x20,0x69,0x73,
+0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x62,0x65,0x69,0x6e,0x67,0x20,0x61,0x63,0x74,
+0x69,0x76,0x65,0x6c,0x79,0x20,0x64,0x65,0x76,0x65,0x6c,0x6f,0x70,0x65,0x64,0x20,
+0x62,0x79,0x20,0x61,0x20,0x74,0x65,0x61,0x6d,0x20,0x6f,0x66,0x20,0x64,0x65,0x76,
+0x65,0x6c,0x6f,0x70,0x65,0x72,0x73,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x64,0x69,
+0x73,0x74,0x72,0x69,0x62,0x75,0x74,0x65,0x64,0x20,0x77,0x6f,0x72,0x6c,0x64,0x2d,
+0x77,0x69,0x64,0x65,0x2e,0x20,0x53,0x69,0x6e,0x63,0x65,0x20,0x69,0x74,0x27,0x73,
+0x20,0x72,0x65,0x6c,0x65,0x61,0x73,0x65,0x2c,0x20,0x6c,0x77,0x49,0x50,0x20,0x68,
+0x61,0x73,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x73,0x70,0x75,0x72,0x72,0x65,0x64,
+0x20,0x61,0x20,0x6c,0x6f,0x74,0x20,0x6f,0x66,0x20,0x69,0x6e,0x74,0x65,0x72,0x65,
+0x73,0x74,0x20,0x61,0x6e,0x64,0x20,0x68,0x61,0x73,0x20,0x62,0x65,0x65,0x6e,0x20,
+0x70,0x6f,0x72,0x74,0x65,0x64,0x20,0x74,0x6f,0x20,0x73,0x65,0x76,0x65,0x72,0x61,
+0x6c,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x70,0x6c,0x61,0x74,0x66,0x6f,0x72,0x6d,
+0x73,0x20,0x61,0x6e,0x64,0x20,0x6f,0x70,0x65,0x72,0x61,0x74,0x69,0x6e,0x67,0x20,
+0x73,0x79,0x73,0x74,0x65,0x6d,0x73,0x2e,0x20,0x6c,0x77,0x49,0x50,0x20,0x63,0x61,
+0x6e,0x20,0x62,0x65,0x20,0x75,0x73,0x65,0x64,0x20,0x65,0x69,0x74,0x68,0x65,0x72,
+0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x77,0x69,0x74,0x68,0x20,0x6f,0x72,0x20,0x77,
+0x69,0x74,0x68,0x6f,0x75,0x74,0x20,0x61,0x6e,0x20,0x75,0x6e,0x64,0x65,0x72,0x6c,
+0x79,0x69,0x6e,0x67,0x20,0x4f,0x53,0x2e,0x0d,0x0a,0x09,0x20,0x20,0x3c,0x2f,0x70,
+0x3e,0x0d,0x0a,0x09,0x20,0x20,0x3c,0x70,0x3e,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,
+0x6c,0x77,0x49,0x50,0x20,0x69,0x73,0x20,0x61,0x6e,0x20,0x6f,0x70,0x65,0x6e,0x20,
+0x73,0x6f,0x75,0x72,0x63,0x65,0x20,0x69,0x6d,0x70,0x6c,0x65,0x6d,0x65,0x6e,0x74,
+0x61,0x74,0x69,0x6f,0x6e,0x20,0x6f,0x66,0x20,0x74,0x68,0x65,0x20,0x54,0x43,0x50,
+0x2f,0x49,0x50,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x70,0x72,0x6f,0x74,0x6f,0x63,
+0x6f,0x6c,0x20,0x73,0x75,0x69,0x74,0x65,0x20,0x74,0x68,0x61,0x74,0x20,0x77,0x61,
+0x73,0x20,0x6f,0x72,0x69,0x67,0x69,0x6e,0x61,0x6c,0x6c,0x79,0x20,0x77,0x72,0x69,
+0x74,0x74,0x65,0x6e,0x20,0x62,0x79,0x20,0x3c,0x61,0x0d,0x0a,0x09,0x20,0x20,0x20,
+0x20,0x68,0x72,0x65,0x66,0x3d,0x22,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77,0x77,
+0x77,0x2e,0x73,0x69,0x63,0x73,0x2e,0x73,0x65,0x2f,0x7e,0x61,0x64,0x61,0x6d,0x2f,
+0x6c,0x77,0x69,0x70,0x2f,0x22,0x3e,0x41,0x64,0x61,0x6d,0x20,0x44,0x75,0x6e,0x6b,
+0x65,0x6c,0x73,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x6f,0x66,0x20,0x74,0x68,0x65,
+0x20,0x53,0x77,0x65,0x64,0x69,0x73,0x68,0x20,0x49,0x6e,0x73,0x74,0x69,0x74,0x75,
+0x74,0x65,0x20,0x6f,0x66,0x20,0x43,0x6f,0x6d,0x70,0x75,0x74,0x65,0x72,0x20,0x53,
+0x63,0x69,0x65,0x6e,0x63,0x65,0x3c,0x2f,0x61,0x3e,0x20,0x62,0x75,0x74,0x20,0x6e,
+0x6f,0x77,0x20,0x69,0x73,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x62,0x65,0x69,0x6e,
+0x67,0x20,0x61,0x63,0x74,0x69,0x76,0x65,0x6c,0x79,0x20,0x64,0x65,0x76,0x65,0x6c,
+0x6f,0x70,0x65,0x64,0x20,0x62,0x79,0x20,0x61,0x20,0x74,0x65,0x61,0x6d,0x20,0x6f,
+0x66,0x20,0x64,0x65,0x76,0x65,0x6c,0x6f,0x70,0x65,0x72,0x73,0x0d,0x0a,0x09,0x20,
+0x20,0x20,0x20,0x64,0x69,0x73,0x74,0x72,0x69,0x62,0x75,0x74,0x65,0x64,0x20,0x77,
+0x6f,0x72,0x6c,0x64,0x2d,0x77,0x69,0x64,0x65,0x2e,0x20,0x53,0x69,0x6e,0x63,0x65,
+0x20,0x69,0x74,0x27,0x73,0x20,0x72,0x65,0x6c,0x65,0x61,0x73,0x65,0x2c,0x20,0x6c,
+0x77,0x49,0x50,0x20,0x68,0x61,0x73,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x73,0x70,
+0x75,0x72,0x72,0x65,0x64,0x20,0x61,0x20,0x6c,0x6f,0x74,0x20,0x6f,0x66,0x20,0x69,
+0x6e,0x74,0x65,0x72,0x65,0x73,0x74,0x20,0x61,0x6e,0x64,0x20,0x68,0x61,0x73,0x20,
+0x62,0x65,0x65,0x6e,0x20,0x70,0x6f,0x72,0x74,0x65,0x64,0x20,0x74,0x6f,0x20,0x73,
+0x65,0x76,0x65,0x72,0x61,0x6c,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x70,0x6c,0x61,
+0x74,0x66,0x6f,0x72,0x6d,0x73,0x20,0x61,0x6e,0x64,0x20,0x6f,0x70,0x65,0x72,0x61,
+0x74,0x69,0x6e,0x67,0x20,0x73,0x79,0x73,0x74,0x65,0x6d,0x73,0x2e,0x20,0x6c,0x77,
+0x49,0x50,0x20,0x63,0x61,0x6e,0x20,0x62,0x65,0x20,0x75,0x73,0x65,0x64,0x20,0x65,
+0x69,0x74,0x68,0x65,0x72,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x77,0x69,0x74,0x68,
+0x20,0x6f,0x72,0x20,0x77,0x69,0x74,0x68,0x6f,0x75,0x74,0x20,0x61,0x6e,0x20,0x75,
+0x6e,0x64,0x65,0x72,0x6c,0x79,0x69,0x6e,0x67,0x20,0x4f,0x53,0x2e,0x0d,0x0a,0x09,
+0x20,0x20,0x3c,0x2f,0x70,0x3e,0x0d,0x0a,0x09,0x20,0x20,0x3c,0x70,0x3e,0x0d,0x0a,
+0x09,0x20,0x20,0x20,0x20,0x6c,0x77,0x49,0x50,0x20,0x69,0x73,0x20,0x61,0x6e,0x20,
+0x6f,0x70,0x65,0x6e,0x20,0x73,0x6f,0x75,0x72,0x63,0x65,0x20,0x69,0x6d,0x70,0x6c,
+0x65,0x6d,0x65,0x6e,0x74,0x61,0x74,0x69,0x6f,0x6e,0x20,0x6f,0x66,0x20,0x74,0x68,
+0x65,0x20,0x54,0x43,0x50,0x2f,0x49,0x50,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x70,
+0x72,0x6f,0x74,0x6f,0x63,0x6f,0x6c,0x20,0x73,0x75,0x69,0x74,0x65,0x20,0x74,0x68,
+0x61,0x74,0x20,0x77,0x61,0x73,0x20,0x6f,0x72,0x69,0x67,0x69,0x6e,0x61,0x6c,0x6c,
+0x79,0x20,0x77,0x72,0x69,0x74,0x74,0x65,0x6e,0x20,0x62,0x79,0x20,0x3c,0x61,0x0d,
+0x0a,0x09,0x20,0x20,0x20,0x20,0x68,0x72,0x65,0x66,0x3d,0x22,0x68,0x74,0x74,0x70,
+0x3a,0x2f,0x2f,0x77,0x77,0x77,0x2e,0x73,0x69,0x63,0x73,0x2e,0x73,0x65,0x2f,0x7e,
+0x61,0x64,0x61,0x6d,0x2f,0x6c,0x77,0x69,0x70,0x2f,0x22,0x3e,0x41,0x64,0x61,0x6d,
+0x20,0x44,0x75,0x6e,0x6b,0x65,0x6c,0x73,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x6f,
+0x66,0x20,0x74,0x68,0x65,0x20,0x53,0x77,0x65,0x64,0x69,0x73,0x68,0x20,0x49,0x6e,
+0x73,0x74,0x69,0x74,0x75,0x74,0x65,0x20,0x6f,0x66,0x20,0x43,0x6f,0x6d,0x70,0x75,
+0x74,0x65,0x72,0x20,0x53,0x63,0x69,0x65,0x6e,0x63,0x65,0x3c,0x2f,0x61,0x3e,0x20,
+0x62,0x75,0x74,0x20,0x6e,0x6f,0x77,0x20,0x69,0x73,0x0d,0x0a,0x09,0x20,0x20,0x20,
+0x20,0x62,0x65,0x69,0x6e,0x67,0x20,0x61,0x63,0x74,0x69,0x76,0x65,0x6c,0x79,0x20,
+0x64,0x65,0x76,0x65,0x6c,0x6f,0x70,0x65,0x64,0x20,0x62,0x79,0x20,0x61,0x20,0x74,
+0x65,0x61,0x6d,0x20,0x6f,0x66,0x20,0x64,0x65,0x76,0x65,0x6c,0x6f,0x70,0x65,0x72,
+0x73,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x64,0x69,0x73,0x74,0x72,0x69,0x62,0x75,
+0x74,0x65,0x64,0x20,0x77,0x6f,0x72,0x6c,0x64,0x2d,0x77,0x69,0x64,0x65,0x2e,0x20,
+0x53,0x69,0x6e,0x63,0x65,0x20,0x69,0x74,0x27,0x73,0x20,0x72,0x65,0x6c,0x65,0x61,
+0x73,0x65,0x2c,0x20,0x6c,0x77,0x49,0x50,0x20,0x68,0x61,0x73,0x0d,0x0a,0x09,0x20,
+0x20,0x20,0x20,0x73,0x70,0x75,0x72,0x72,0x65,0x64,0x20,0x61,0x20,0x6c,0x6f,0x74,
+0x20,0x6f,0x66,0x20,0x69,0x6e,0x74,0x65,0x72,0x65,0x73,0x74,0x20,0x61,0x6e,0x64,
+0x20,0x68,0x61,0x73,0x20,0x62,0x65,0x65,0x6e,0x20,0x70,0x6f,0x72,0x74,0x65,0x64,
+0x20,0x74,0x6f,0x20,0x73,0x65,0x76,0x65,0x72,0x61,0x6c,0x0d,0x0a,0x09,0x20,0x20,
+0x20,0x20,0x70,0x6c,0x61,0x74,0x66,0x6f,0x72,0x6d,0x73,0x20,0x61,0x6e,0x64,0x20,
+0x6f,0x70,0x65,0x72,0x61,0x74,0x69,0x6e,0x67,0x20,0x73,0x79,0x73,0x74,0x65,0x6d,
+0x73,0x2e,0x20,0x6c,0x77,0x49,0x50,0x20,0x63,0x61,0x6e,0x20,0x62,0x65,0x20,0x75,
+0x73,0x65,0x64,0x20,0x65,0x69,0x74,0x68,0x65,0x72,0x0d,0x0a,0x09,0x20,0x20,0x20,
+0x20,0x77,0x69,0x74,0x68,0x20,0x6f,0x72,0x20,0x77,0x69,0x74,0x68,0x6f,0x75,0x74,
+0x20,0x61,0x6e,0x20,0x75,0x6e,0x64,0x65,0x72,0x6c,0x79,0x69,0x6e,0x67,0x20,0x4f,
+0x53,0x2e,0x0d,0x0a,0x09,0x20,0x20,0x3c,0x2f,0x70,0x3e,0x0d,0x0a,0x09,0x20,0x20,
+0x3c,0x70,0x3e,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x6c,0x77,0x49,0x50,0x20,0x69,
+0x73,0x20,0x61,0x6e,0x20,0x6f,0x70,0x65,0x6e,0x20,0x73,0x6f,0x75,0x72,0x63,0x65,
+0x20,0x69,0x6d,0x70,0x6c,0x65,0x6d,0x65,0x6e,0x74,0x61,0x74,0x69,0x6f,0x6e,0x20,
+0x6f,0x66,0x20,0x74,0x68,0x65,0x20,0x54,0x43,0x50,0x2f,0x49,0x50,0x0d,0x0a,0x09,
+0x20,0x20,0x20,0x20,0x70,0x72,0x6f,0x74,0x6f,0x63,0x6f,0x6c,0x20,0x73,0x75,0x69,
+0x74,0x65,0x20,0x74,0x68,0x61,0x74,0x20,0x77,0x61,0x73,0x20,0x6f,0x72,0x69,0x67,
+0x69,0x6e,0x61,0x6c,0x6c,0x79,0x20,0x77,0x72,0x69,0x74,0x74,0x65,0x6e,0x20,0x62,
+0x79,0x20,0x3c,0x61,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x68,0x72,0x65,0x66,0x3d,
+0x22,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77,0x77,0x77,0x2e,0x73,0x69,0x63,0x73,
+0x2e,0x73,0x65,0x2f,0x7e,0x61,0x64,0x61,0x6d,0x2f,0x6c,0x77,0x69,0x70,0x2f,0x22,
+0x3e,0x41,0x64,0x61,0x6d,0x20,0x44,0x75,0x6e,0x6b,0x65,0x6c,0x73,0x0d,0x0a,0x09,
+0x20,0x20,0x20,0x20,0x6f,0x66,0x20,0x74,0x68,0x65,0x20,0x53,0x77,0x65,0x64,0x69,
+0x73,0x68,0x20,0x49,0x6e,0x73,0x74,0x69,0x74,0x75,0x74,0x65,0x20,0x6f,0x66,0x20,
+0x43,0x6f,0x6d,0x70,0x75,0x74,0x65,0x72,0x20,0x53,0x63,0x69,0x65,0x6e,0x63,0x65,
+0x3c,0x2f,0x61,0x3e,0x20,0x62,0x75,0x74,0x20,0x6e,0x6f,0x77,0x20,0x69,0x73,0x0d,
+0x0a,0x09,0x20,0x20,0x20,0x20,0x62,0x65,0x69,0x6e,0x67,0x20,0x61,0x63,0x74,0x69,
+0x76,0x65,0x6c,0x79,0x20,0x64,0x65,0x76,0x65,0x6c,0x6f,0x70,0x65,0x64,0x20,0x62,
+0x79,0x20,0x61,0x20,0x74,0x65,0x61,0x6d,0x20,0x6f,0x66,0x20,0x64,0x65,0x76,0x65,
+0x6c,0x6f,0x70,0x65,0x72,0x73,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x64,0x69,0x73,
+0x74,0x72,0x69,0x62,0x75,0x74,0x65,0x64,0x20,0x77,0x6f,0x72,0x6c,0x64,0x2d,0x77,
+0x69,0x64,0x65,0x2e,0x20,0x53,0x69,0x6e,0x63,0x65,0x20,0x69,0x74,0x27,0x73,0x20,
+0x72,0x65,0x6c,0x65,0x61,0x73,0x65,0x2c,0x20,0x6c,0x77,0x49,0x50,0x20,0x68,0x61,
+0x73,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x73,0x70,0x75,0x72,0x72,0x65,0x64,0x20,
+0x61,0x20,0x6c,0x6f,0x74,0x20,0x6f,0x66,0x20,0x69,0x6e,0x74,0x65,0x72,0x65,0x73,
+0x74,0x20,0x61,0x6e,0x64,0x20,0x68,0x61,0x73,0x20,0x62,0x65,0x65,0x6e,0x20,0x70,
+0x6f,0x72,0x74,0x65,0x64,0x20,0x74,0x6f,0x20,0x73,0x65,0x76,0x65,0x72,0x61,0x6c,
+0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x70,0x6c,0x61,0x74,0x66,0x6f,0x72,0x6d,0x73,
+0x20,0x61,0x6e,0x64,0x20,0x6f,0x70,0x65,0x72,0x61,0x74,0x69,0x6e,0x67,0x20,0x73,
+0x79,0x73,0x74,0x65,0x6d,0x73,0x2e,0x20,0x6c,0x77,0x49,0x50,0x20,0x63,0x61,0x6e,
+0x20,0x62,0x65,0x20,0x75,0x73,0x65,0x64,0x20,0x65,0x69,0x74,0x68,0x65,0x72,0x0d,
+0x0a,0x09,0x20,0x20,0x20,0x20,0x77,0x69,0x74,0x68,0x20,0x6f,0x72,0x20,0x77,0x69,
+0x74,0x68,0x6f,0x75,0x74,0x20,0x61,0x6e,0x20,0x75,0x6e,0x64,0x65,0x72,0x6c,0x79,
+0x69,0x6e,0x67,0x20,0x4f,0x53,0x2e,0x0d,0x0a,0x09,0x20,0x20,0x3c,0x2f,0x70,0x3e,
+0x0d,0x0a,0x09,0x20,0x20,0x3c,0x70,0x3e,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x6c,
+0x77,0x49,0x50,0x20,0x69,0x73,0x20,0x61,0x6e,0x20,0x6f,0x70,0x65,0x6e,0x20,0x73,
+0x6f,0x75,0x72,0x63,0x65,0x20,0x69,0x6d,0x70,0x6c,0x65,0x6d,0x65,0x6e,0x74,0x61,
+0x74,0x69,0x6f,0x6e,0x20,0x6f,0x66,0x20,0x74,0x68,0x65,0x20,0x54,0x43,0x50,0x2f,
+0x49,0x50,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x70,0x72,0x6f,0x74,0x6f,0x63,0x6f,
+0x6c,0x20,0x73,0x75,0x69,0x74,0x65,0x20,0x74,0x68,0x61,0x74,0x20,0x77,0x61,0x73,
+0x20,0x6f,0x72,0x69,0x67,0x69,0x6e,0x61,0x6c,0x6c,0x79,0x20,0x77,0x72,0x69,0x74,
+0x74,0x65,0x6e,0x20,0x62,0x79,0x20,0x3c,0x61,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,
+0x68,0x72,0x65,0x66,0x3d,0x22,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77,0x77,0x77,
+0x2e,0x73,0x69,0x63,0x73,0x2e,0x73,0x65,0x2f,0x7e,0x61,0x64,0x61,0x6d,0x2f,0x6c,
+0x77,0x69,0x70,0x2f,0x22,0x3e,0x41,0x64,0x61,0x6d,0x20,0x44,0x75,0x6e,0x6b,0x65,
+0x6c,0x73,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x6f,0x66,0x20,0x74,0x68,0x65,0x20,
+0x53,0x77,0x65,0x64,0x69,0x73,0x68,0x20,0x49,0x6e,0x73,0x74,0x69,0x74,0x75,0x74,
+0x65,0x20,0x6f,0x66,0x20,0x43,0x6f,0x6d,0x70,0x75,0x74,0x65,0x72,0x20,0x53,0x63,
+0x69,0x65,0x6e,0x63,0x65,0x3c,0x2f,0x61,0x3e,0x20,0x62,0x75,0x74,0x20,0x6e,0x6f,
+0x77,0x20,0x69,0x73,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x62,0x65,0x69,0x6e,0x67,
+0x20,0x61,0x63,0x74,0x69,0x76,0x65,0x6c,0x79,0x20,0x64,0x65,0x76,0x65,0x6c,0x6f,
+0x70,0x65,0x64,0x20,0x62,0x79,0x20,0x61,0x20,0x74,0x65,0x61,0x6d,0x20,0x6f,0x66,
+0x20,0x64,0x65,0x76,0x65,0x6c,0x6f,0x70,0x65,0x72,0x73,0x0d,0x0a,0x09,0x20,0x20,
+0x20,0x20,0x64,0x69,0x73,0x74,0x72,0x69,0x62,0x75,0x74,0x65,0x64,0x20,0x77,0x6f,
+0x72,0x6c,0x64,0x2d,0x77,0x69,0x64,0x65,0x2e,0x20,0x53,0x69,0x6e,0x63,0x65,0x20,
+0x69,0x74,0x27,0x73,0x20,0x72,0x65,0x6c,0x65,0x61,0x73,0x65,0x2c,0x20,0x6c,0x77,
+0x49,0x50,0x20,0x68,0x61,0x73,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x73,0x70,0x75,
+0x72,0x72,0x65,0x64,0x20,0x61,0x20,0x6c,0x6f,0x74,0x20,0x6f,0x66,0x20,0x69,0x6e,
+0x74,0x65,0x72,0x65,0x73,0x74,0x20,0x61,0x6e,0x64,0x20,0x68,0x61,0x73,0x20,0x62,
+0x65,0x65,0x6e,0x20,0x70,0x6f,0x72,0x74,0x65,0x64,0x20,0x74,0x6f,0x20,0x73,0x65,
+0x76,0x65,0x72,0x61,0x6c,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x70,0x6c,0x61,0x74,
+0x66,0x6f,0x72,0x6d,0x73,0x20,0x61,0x6e,0x64,0x20,0x6f,0x70,0x65,0x72,0x61,0x74,
+0x69,0x6e,0x67,0x20,0x73,0x79,0x73,0x74,0x65,0x6d,0x73,0x2e,0x20,0x6c,0x77,0x49,
+0x50,0x20,0x63,0x61,0x6e,0x20,0x62,0x65,0x20,0x75,0x73,0x65,0x64,0x20,0x65,0x69,
+0x74,0x68,0x65,0x72,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x77,0x69,0x74,0x68,0x20,
+0x6f,0x72,0x20,0x77,0x69,0x74,0x68,0x6f,0x75,0x74,0x20,0x61,0x6e,0x20,0x75,0x6e,
+0x64,0x65,0x72,0x6c,0x79,0x69,0x6e,0x67,0x20,0x4f,0x53,0x2e,0x0d,0x0a,0x09,0x20,
+0x20,0x3c,0x2f,0x70,0x3e,0x0d,0x0a,0x09,0x20,0x20,0x3c,0x70,0x3e,0x0d,0x0a,0x09,
+0x20,0x20,0x20,0x20,0x6c,0x77,0x49,0x50,0x20,0x69,0x73,0x20,0x61,0x6e,0x20,0x6f,
+0x70,0x65,0x6e,0x20,0x73,0x6f,0x75,0x72,0x63,0x65,0x20,0x69,0x6d,0x70,0x6c,0x65,
+0x6d,0x65,0x6e,0x74,0x61,0x74,0x69,0x6f,0x6e,0x20,0x6f,0x66,0x20,0x74,0x68,0x65,
+0x20,0x54,0x43,0x50,0x2f,0x49,0x50,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x70,0x72,
+0x6f,0x74,0x6f,0x63,0x6f,0x6c,0x20,0x73,0x75,0x69,0x74,0x65,0x20,0x74,0x68,0x61,
+0x74,0x20,0x77,0x61,0x73,0x20,0x6f,0x72,0x69,0x67,0x69,0x6e,0x61,0x6c,0x6c,0x79,
+0x20,0x77,0x72,0x69,0x74,0x74,0x65,0x6e,0x20,0x62,0x79,0x20,0x3c,0x61,0x0d,0x0a,
+0x09,0x20,0x20,0x20,0x20,0x68,0x72,0x65,0x66,0x3d,0x22,0x68,0x74,0x74,0x70,0x3a,
+0x2f,0x2f,0x77,0x77,0x77,0x2e,0x73,0x69,0x63,0x73,0x2e,0x73,0x65,0x2f,0x7e,0x61,
+0x64,0x61,0x6d,0x2f,0x6c,0x77,0x69,0x70,0x2f,0x22,0x3e,0x41,0x64,0x61,0x6d,0x20,
+0x44,0x75,0x6e,0x6b,0x65,0x6c,0x73,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x6f,0x66,
+0x20,0x74,0x68,0x65,0x20,0x53,0x77,0x65,0x64,0x69,0x73,0x68,0x20,0x49,0x6e,0x73,
+0x74,0x69,0x74,0x75,0x74,0x65,0x20,0x6f,0x66,0x20,0x43,0x6f,0x6d,0x70,0x75,0x74,
+0x65,0x72,0x20,0x53,0x63,0x69,0x65,0x6e,0x63,0x65,0x3c,0x2f,0x61,0x3e,0x20,0x62,
+0x75,0x74,0x20,0x6e,0x6f,0x77,0x20,0x69,0x73,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,
+0x62,0x65,0x69,0x6e,0x67,0x20,0x61,0x63,0x74,0x69,0x76,0x65,0x6c,0x79,0x20,0x64,
+0x65,0x76,0x65,0x6c,0x6f,0x70,0x65,0x64,0x20,0x62,0x79,0x20,0x61,0x20,0x74,0x65,
+0x61,0x6d,0x20,0x6f,0x66,0x20,0x64,0x65,0x76,0x65,0x6c,0x6f,0x70,0x65,0x72,0x73,
+0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x64,0x69,0x73,0x74,0x72,0x69,0x62,0x75,0x74,
+0x65,0x64,0x20,0x77,0x6f,0x72,0x6c,0x64,0x2d,0x77,0x69,0x64,0x65,0x2e,0x20,0x53,
+0x69,0x6e,0x63,0x65,0x20,0x69,0x74,0x27,0x73,0x20,0x72,0x65,0x6c,0x65,0x61,0x73,
+0x65,0x2c,0x20,0x6c,0x77,0x49,0x50,0x20,0x68,0x61,0x73,0x0d,0x0a,0x09,0x20,0x20,
+0x20,0x20,0x73,0x70,0x75,0x72,0x72,0x65,0x64,0x20,0x61,0x20,0x6c,0x6f,0x74,0x20,
+0x6f,0x66,0x20,0x69,0x6e,0x74,0x65,0x72,0x65,0x73,0x74,0x20,0x61,0x6e,0x64,0x20,
+0x68,0x61,0x73,0x20,0x62,0x65,0x65,0x6e,0x20,0x70,0x6f,0x72,0x74,0x65,0x64,0x20,
+0x74,0x6f,0x20,0x73,0x65,0x76,0x65,0x72,0x61,0x6c,0x0d,0x0a,0x09,0x20,0x20,0x20,
+0x20,0x70,0x6c,0x61,0x74,0x66,0x6f,0x72,0x6d,0x73,0x20,0x61,0x6e,0x64,0x20,0x6f,
+0x70,0x65,0x72,0x61,0x74,0x69,0x6e,0x67,0x20,0x73,0x79,0x73,0x74,0x65,0x6d,0x73,
+0x2e,0x20,0x6c,0x77,0x49,0x50,0x20,0x63,0x61,0x6e,0x20,0x62,0x65,0x20,0x75,0x73,
+0x65,0x64,0x20,0x65,0x69,0x74,0x68,0x65,0x72,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,
+0x77,0x69,0x74,0x68,0x20,0x6f,0x72,0x20,0x77,0x69,0x74,0x68,0x6f,0x75,0x74,0x20,
+0x61,0x6e,0x20,0x75,0x6e,0x64,0x65,0x72,0x6c,0x79,0x69,0x6e,0x67,0x20,0x4f,0x53,
+0x2e,0x0d,0x0a,0x09,0x20,0x20,0x3c,0x2f,0x70,0x3e,0x0d,0x0a,0x09,0x20,0x20,0x3c,
+0x70,0x3e,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x6c,0x77,0x49,0x50,0x20,0x69,0x73,
+0x20,0x61,0x6e,0x20,0x6f,0x70,0x65,0x6e,0x20,0x73,0x6f,0x75,0x72,0x63,0x65,0x20,
+0x69,0x6d,0x70,0x6c,0x65,0x6d,0x65,0x6e,0x74,0x61,0x74,0x69,0x6f,0x6e,0x20,0x6f,
+0x66,0x20,0x74,0x68,0x65,0x20,0x54,0x43,0x50,0x2f,0x49,0x50,0x0d,0x0a,0x09,0x20,
+0x20,0x20,0x20,0x70,0x72,0x6f,0x74,0x6f,0x63,0x6f,0x6c,0x20,0x73,0x75,0x69,0x74,
+0x65,0x20,0x74,0x68,0x61,0x74,0x20,0x77,0x61,0x73,0x20,0x6f,0x72,0x69,0x67,0x69,
+0x6e,0x61,0x6c,0x6c,0x79,0x20,0x77,0x72,0x69,0x74,0x74,0x65,0x6e,0x20,0x62,0x79,
+0x20,0x3c,0x61,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x68,0x72,0x65,0x66,0x3d,0x22,
+0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77,0x77,0x77,0x2e,0x73,0x69,0x63,0x73,0x2e,
+0x73,0x65,0x2f,0x7e,0x61,0x64,0x61,0x6d,0x2f,0x6c,0x77,0x69,0x70,0x2f,0x22,0x3e,
+0x41,0x64,0x61,0x6d,0x20,0x44,0x75,0x6e,0x6b,0x65,0x6c,0x73,0x0d,0x0a,0x09,0x20,
+0x20,0x20,0x20,0x6f,0x66,0x20,0x74,0x68,0x65,0x20,0x53,0x77,0x65,0x64,0x69,0x73,
+0x68,0x20,0x49,0x6e,0x73,0x74,0x69,0x74,0x75,0x74,0x65,0x20,0x6f,0x66,0x20,0x43,
+0x6f,0x6d,0x70,0x75,0x74,0x65,0x72,0x20,0x53,0x63,0x69,0x65,0x6e,0x63,0x65,0x3c,
+0x2f,0x61,0x3e,0x20,0x62,0x75,0x74,0x20,0x6e,0x6f,0x77,0x20,0x69,0x73,0x0d,0x0a,
+0x09,0x20,0x20,0x20,0x20,0x62,0x65,0x69,0x6e,0x67,0x20,0x61,0x63,0x74,0x69,0x76,
+0x65,0x6c,0x79,0x20,0x64,0x65,0x76,0x65,0x6c,0x6f,0x70,0x65,0x64,0x20,0x62,0x79,
+0x20,0x61,0x20,0x74,0x65,0x61,0x6d,0x20,0x6f,0x66,0x20,0x64,0x65,0x76,0x65,0x6c,
+0x6f,0x70,0x65,0x72,0x73,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x64,0x69,0x73,0x74,
+0x72,0x69,0x62,0x75,0x74,0x65,0x64,0x20,0x77,0x6f,0x72,0x6c,0x64,0x2d,0x77,0x69,
+0x64,0x65,0x2e,0x20,0x53,0x69,0x6e,0x63,0x65,0x20,0x69,0x74,0x27,0x73,0x20,0x72,
+0x65,0x6c,0x65,0x61,0x73,0x65,0x2c,0x20,0x6c,0x77,0x49,0x50,0x20,0x68,0x61,0x73,
+0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x73,0x70,0x75,0x72,0x72,0x65,0x64,0x20,0x61,
+0x20,0x6c,0x6f,0x74,0x20,0x6f,0x66,0x20,0x69,0x6e,0x74,0x65,0x72,0x65,0x73,0x74,
+0x20,0x61,0x6e,0x64,0x20,0x68,0x61,0x73,0x20,0x62,0x65,0x65,0x6e,0x20,0x70,0x6f,
+0x72,0x74,0x65,0x64,0x20,0x74,0x6f,0x20,0x73,0x65,0x76,0x65,0x72,0x61,0x6c,0x0d,
+0x0a,0x09,0x20,0x20,0x20,0x20,0x70,0x6c,0x61,0x74,0x66,0x6f,0x72,0x6d,0x73,0x20,
+0x61,0x6e,0x64,0x20,0x6f,0x70,0x65,0x72,0x61,0x74,0x69,0x6e,0x67,0x20,0x73,0x79,
+0x73,0x74,0x65,0x6d,0x73,0x2e,0x20,0x6c,0x77,0x49,0x50,0x20,0x63,0x61,0x6e,0x20,
+0x62,0x65,0x20,0x75,0x73,0x65,0x64,0x20,0x65,0x69,0x74,0x68,0x65,0x72,0x0d,0x0a,
+0x09,0x20,0x20,0x20,0x20,0x77,0x69,0x74,0x68,0x20,0x6f,0x72,0x20,0x77,0x69,0x74,
+0x68,0x6f,0x75,0x74,0x20,0x61,0x6e,0x20,0x75,0x6e,0x64,0x65,0x72,0x6c,0x79,0x69,
+0x6e,0x67,0x20,0x4f,0x53,0x2e,0x0d,0x0a,0x09,0x20,0x20,0x3c,0x2f,0x70,0x3e,0x0d,
+0x0a,0x09,0x20,0x20,0x3c,0x70,0x3e,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x6c,0x77,
+0x49,0x50,0x20,0x69,0x73,0x20,0x61,0x6e,0x20,0x6f,0x70,0x65,0x6e,0x20,0x73,0x6f,
+0x75,0x72,0x63,0x65,0x20,0x69,0x6d,0x70,0x6c,0x65,0x6d,0x65,0x6e,0x74,0x61,0x74,
+0x69,0x6f,0x6e,0x20,0x6f,0x66,0x20,0x74,0x68,0x65,0x20,0x54,0x43,0x50,0x2f,0x49,
+0x50,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x70,0x72,0x6f,0x74,0x6f,0x63,0x6f,0x6c,
+0x20,0x73,0x75,0x69,0x74,0x65,0x20,0x74,0x68,0x61,0x74,0x20,0x77,0x61,0x73,0x20,
+0x6f,0x72,0x69,0x67,0x69,0x6e,0x61,0x6c,0x6c,0x79,0x20,0x77,0x72,0x69,0x74,0x74,
+0x65,0x6e,0x20,0x62,0x79,0x20,0x3c,0x61,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x68,
+0x72,0x65,0x66,0x3d,0x22,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77,0x77,0x77,0x2e,
+0x73,0x69,0x63,0x73,0x2e,0x73,0x65,0x2f,0x7e,0x61,0x64,0x61,0x6d,0x2f,0x6c,0x77,
+0x69,0x70,0x2f,0x22,0x3e,0x41,0x64,0x61,0x6d,0x20,0x44,0x75,0x6e,0x6b,0x65,0x6c,
+0x73,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x6f,0x66,0x20,0x74,0x68,0x65,0x20,0x53,
+0x77,0x65,0x64,0x69,0x73,0x68,0x20,0x49,0x6e,0x73,0x74,0x69,0x74,0x75,0x74,0x65,
+0x20,0x6f,0x66,0x20,0x43,0x6f,0x6d,0x70,0x75,0x74,0x65,0x72,0x20,0x53,0x63,0x69,
+0x65,0x6e,0x63,0x65,0x3c,0x2f,0x61,0x3e,0x20,0x62,0x75,0x74,0x20,0x6e,0x6f,0x77,
+0x20,0x69,0x73,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x62,0x65,0x69,0x6e,0x67,0x20,
+0x61,0x63,0x74,0x69,0x76,0x65,0x6c,0x79,0x20,0x64,0x65,0x76,0x65,0x6c,0x6f,0x70,
+0x65,0x64,0x20,0x62,0x79,0x20,0x61,0x20,0x74,0x65,0x61,0x6d,0x20,0x6f,0x66,0x20,
+0x64,0x65,0x76,0x65,0x6c,0x6f,0x70,0x65,0x72,0x73,0x0d,0x0a,0x09,0x20,0x20,0x20,
+0x20,0x64,0x69,0x73,0x74,0x72,0x69,0x62,0x75,0x74,0x65,0x64,0x20,0x77,0x6f,0x72,
+0x6c,0x64,0x2d,0x77,0x69,0x64,0x65,0x2e,0x20,0x53,0x69,0x6e,0x63,0x65,0x20,0x69,
+0x74,0x27,0x73,0x20,0x72,0x65,0x6c,0x65,0x61,0x73,0x65,0x2c,0x20,0x6c,0x77,0x49,
+0x50,0x20,0x68,0x61,0x73,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x73,0x70,0x75,0x72,
+0x72,0x65,0x64,0x20,0x61,0x20,0x6c,0x6f,0x74,0x20,0x6f,0x66,0x20,0x69,0x6e,0x74,
+0x65,0x72,0x65,0x73,0x74,0x20,0x61,0x6e,0x64,0x20,0x68,0x61,0x73,0x20,0x62,0x65,
+0x65,0x6e,0x20,0x70,0x6f,0x72,0x74,0x65,0x64,0x20,0x74,0x6f,0x20,0x73,0x65,0x76,
+0x65,0x72,0x61,0x6c,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x70,0x6c,0x61,0x74,0x66,
+0x6f,0x72,0x6d,0x73,0x20,0x61,0x6e,0x64,0x20,0x6f,0x70,0x65,0x72,0x61,0x74,0x69,
+0x6e,0x67,0x20,0x73,0x79,0x73,0x74,0x65,0x6d,0x73,0x2e,0x20,0x6c,0x77,0x49,0x50,
+0x20,0x63,0x61,0x6e,0x20,0x62,0x65,0x20,0x75,0x73,0x65,0x64,0x20,0x65,0x69,0x74,
+0x68,0x65,0x72,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x77,0x69,0x74,0x68,0x20,0x6f,
+0x72,0x20,0x77,0x69,0x74,0x68,0x6f,0x75,0x74,0x20,0x61,0x6e,0x20,0x75,0x6e,0x64,
+0x65,0x72,0x6c,0x79,0x69,0x6e,0x67,0x20,0x4f,0x53,0x2e,0x0d,0x0a,0x09,0x20,0x20,
+0x3c,0x2f,0x70,0x3e,0x0d,0x0a,0x09,0x20,0x20,0x3c,0x70,0x3e,0x0d,0x0a,0x09,0x20,
+0x20,0x20,0x20,0x6c,0x77,0x49,0x50,0x20,0x69,0x73,0x20,0x61,0x6e,0x20,0x6f,0x70,
+0x65,0x6e,0x20,0x73,0x6f,0x75,0x72,0x63,0x65,0x20,0x69,0x6d,0x70,0x6c,0x65,0x6d,
+0x65,0x6e,0x74,0x61,0x74,0x69,0x6f,0x6e,0x20,0x6f,0x66,0x20,0x74,0x68,0x65,0x20,
+0x54,0x43,0x50,0x2f,0x49,0x50,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x70,0x72,0x6f,
+0x74,0x6f,0x63,0x6f,0x6c,0x20,0x73,0x75,0x69,0x74,0x65,0x20,0x74,0x68,0x61,0x74,
+0x20,0x77,0x61,0x73,0x20,0x6f,0x72,0x69,0x67,0x69,0x6e,0x61,0x6c,0x6c,0x79,0x20,
+0x77,0x72,0x69,0x74,0x74,0x65,0x6e,0x20,0x62,0x79,0x20,0x3c,0x61,0x0d,0x0a,0x09,
+0x20,0x20,0x20,0x20,0x68,0x72,0x65,0x66,0x3d,0x22,0x68,0x74,0x74,0x70,0x3a,0x2f,
+0x2f,0x77,0x77,0x77,0x2e,0x73,0x69,0x63,0x73,0x2e,0x73,0x65,0x2f,0x7e,0x61,0x64,
+0x61,0x6d,0x2f,0x6c,0x77,0x69,0x70,0x2f,0x22,0x3e,0x41,0x64,0x61,0x6d,0x20,0x44,
+0x75,0x6e,0x6b,0x65,0x6c,0x73,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x6f,0x66,0x20,
+0x74,0x68,0x65,0x20,0x53,0x77,0x65,0x64,0x69,0x73,0x68,0x20,0x49,0x6e,0x73,0x74,
+0x69,0x74,0x75,0x74,0x65,0x20,0x6f,0x66,0x20,0x43,0x6f,0x6d,0x70,0x75,0x74,0x65,
+0x72,0x20,0x53,0x63,0x69,0x65,0x6e,0x63,0x65,0x3c,0x2f,0x61,0x3e,0x20,0x62,0x75,
+0x74,0x20,0x6e,0x6f,0x77,0x20,0x69,0x73,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x62,
+0x65,0x69,0x6e,0x67,0x20,0x61,0x63,0x74,0x69,0x76,0x65,0x6c,0x79,0x20,0x64,0x65,
+0x76,0x65,0x6c,0x6f,0x70,0x65,0x64,0x20,0x62,0x79,0x20,0x61,0x20,0x74,0x65,0x61,
+0x6d,0x20,0x6f,0x66,0x20,0x64,0x65,0x76,0x65,0x6c,0x6f,0x70,0x65,0x72,0x73,0x0d,
+0x0a,0x09,0x20,0x20,0x20,0x20,0x64,0x69,0x73,0x74,0x72,0x69,0x62,0x75,0x74,0x65,
+0x64,0x20,0x77,0x6f,0x72,0x6c,0x64,0x2d,0x77,0x69,0x64,0x65,0x2e,0x20,0x53,0x69,
+0x6e,0x63,0x65,0x20,0x69,0x74,0x27,0x73,0x20,0x72,0x65,0x6c,0x65,0x61,0x73,0x65,
+0x2c,0x20,0x6c,0x77,0x49,0x50,0x20,0x68,0x61,0x73,0x0d,0x0a,0x09,0x20,0x20,0x20,
+0x20,0x73,0x70,0x75,0x72,0x72,0x65,0x64,0x20,0x61,0x20,0x6c,0x6f,0x74,0x20,0x6f,
+0x66,0x20,0x69,0x6e,0x74,0x65,0x72,0x65,0x73,0x74,0x20,0x61,0x6e,0x64,0x20,0x68,
+0x61,0x73,0x20,0x62,0x65,0x65,0x6e,0x20,0x70,0x6f,0x72,0x74,0x65,0x64,0x20,0x74,
+0x6f,0x20,0x73,0x65,0x76,0x65,0x72,0x61,0x6c,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,
+0x70,0x6c,0x61,0x74,0x66,0x6f,0x72,0x6d,0x73,0x20,0x61,0x6e,0x64,0x20,0x6f,0x70,
+0x65,0x72,0x61,0x74,0x69,0x6e,0x67,0x20,0x73,0x79,0x73,0x74,0x65,0x6d,0x73,0x2e,
+0x20,0x6c,0x77,0x49,0x50,0x20,0x63,0x61,0x6e,0x20,0x62,0x65,0x20,0x75,0x73,0x65,
+0x64,0x20,0x65,0x69,0x74,0x68,0x65,0x72,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x77,
+0x69,0x74,0x68,0x20,0x6f,0x72,0x20,0x77,0x69,0x74,0x68,0x6f,0x75,0x74,0x20,0x61,
+0x6e,0x20,0x75,0x6e,0x64,0x65,0x72,0x6c,0x79,0x69,0x6e,0x67,0x20,0x4f,0x53,0x2e,
+0x0d,0x0a,0x09,0x20,0x20,0x3c,0x2f,0x70,0x3e,0x0d,0x0a,0x09,0x20,0x20,0x3c,0x70,
+0x3e,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x6c,0x77,0x49,0x50,0x20,0x69,0x73,0x20,
+0x61,0x6e,0x20,0x6f,0x70,0x65,0x6e,0x20,0x73,0x6f,0x75,0x72,0x63,0x65,0x20,0x69,
+0x6d,0x70,0x6c,0x65,0x6d,0x65,0x6e,0x74,0x61,0x74,0x69,0x6f,0x6e,0x20,0x6f,0x66,
+0x20,0x74,0x68,0x65,0x20,0x54,0x43,0x50,0x2f,0x49,0x50,0x0d,0x0a,0x09,0x20,0x20,
+0x20,0x20,0x70,0x72,0x6f,0x74,0x6f,0x63,0x6f,0x6c,0x20,0x73,0x75,0x69,0x74,0x65,
+0x20,0x74,0x68,0x61,0x74,0x20,0x77,0x61,0x73,0x20,0x6f,0x72,0x69,0x67,0x69,0x6e,
+0x61,0x6c,0x6c,0x79,0x20,0x77,0x72,0x69,0x74,0x74,0x65,0x6e,0x20,0x62,0x79,0x20,
+0x3c,0x61,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x68,0x72,0x65,0x66,0x3d,0x22,0x68,
+0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77,0x77,0x77,0x2e,0x73,0x69,0x63,0x73,0x2e,0x73,
+0x65,0x2f,0x7e,0x61,0x64,0x61,0x6d,0x2f,0x6c,0x77,0x69,0x70,0x2f,0x22,0x3e,0x41,
+0x64,0x61,0x6d,0x20,0x44,0x75,0x6e,0x6b,0x65,0x6c,0x73,0x0d,0x0a,0x09,0x20,0x20,
+0x20,0x20,0x6f,0x66,0x20,0x74,0x68,0x65,0x20,0x53,0x77,0x65,0x64,0x69,0x73,0x68,
+0x20,0x49,0x6e,0x73,0x74,0x69,0x74,0x75,0x74,0x65,0x20,0x6f,0x66,0x20,0x43,0x6f,
+0x6d,0x70,0x75,0x74,0x65,0x72,0x20,0x53,0x63,0x69,0x65,0x6e,0x63,0x65,0x3c,0x2f,
+0x61,0x3e,0x20,0x62,0x75,0x74,0x20,0x6e,0x6f,0x77,0x20,0x69,0x73,0x0d,0x0a,0x09,
+0x20,0x20,0x20,0x20,0x62,0x65,0x69,0x6e,0x67,0x20,0x61,0x63,0x74,0x69,0x76,0x65,
+0x6c,0x79,0x20,0x64,0x65,0x76,0x65,0x6c,0x6f,0x70,0x65,0x64,0x20,0x62,0x79,0x20,
+0x61,0x20,0x74,0x65,0x61,0x6d,0x20,0x6f,0x66,0x20,0x64,0x65,0x76,0x65,0x6c,0x6f,
+0x70,0x65,0x72,0x73,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x64,0x69,0x73,0x74,0x72,
+0x69,0x62,0x75,0x74,0x65,0x64,0x20,0x77,0x6f,0x72,0x6c,0x64,0x2d,0x77,0x69,0x64,
+0x65,0x2e,0x20,0x53,0x69,0x6e,0x63,0x65,0x20,0x69,0x74,0x27,0x73,0x20,0x72,0x65,
+0x6c,0x65,0x61,0x73,0x65,0x2c,0x20,0x6c,0x77,0x49,0x50,0x20,0x68,0x61,0x73,0x0d,
+0x0a,0x09,0x20,0x20,0x20,0x20,0x73,0x70,0x75,0x72,0x72,0x65,0x64,0x20,0x61,0x20,
+0x6c,0x6f,0x74,0x20,0x6f,0x66,0x20,0x69,0x6e,0x74,0x65,0x72,0x65,0x73,0x74,0x20,
+0x61,0x6e,0x64,0x20,0x68,0x61,0x73,0x20,0x62,0x65,0x65,0x6e,0x20,0x70,0x6f,0x72,
+0x74,0x65,0x64,0x20,0x74,0x6f,0x20,0x73,0x65,0x76,0x65,0x72,0x61,0x6c,0x0d,0x0a,
+0x09,0x20,0x20,0x20,0x20,0x70,0x6c,0x61,0x74,0x66,0x6f,0x72,0x6d,0x73,0x20,0x61,
+0x6e,0x64,0x20,0x6f,0x70,0x65,0x72,0x61,0x74,0x69,0x6e,0x67,0x20,0x73,0x79,0x73,
+0x74,0x65,0x6d,0x73,0x2e,0x20,0x6c,0x77,0x49,0x50,0x20,0x63,0x61,0x6e,0x20,0x62,
+0x65,0x20,0x75,0x73,0x65,0x64,0x20,0x65,0x69,0x74,0x68,0x65,0x72,0x0d,0x0a,0x09,
+0x20,0x20,0x20,0x20,0x77,0x69,0x74,0x68,0x20,0x6f,0x72,0x20,0x77,0x69,0x74,0x68,
+0x6f,0x75,0x74,0x20,0x61,0x6e,0x20,0x75,0x6e,0x64,0x65,0x72,0x6c,0x79,0x69,0x6e,
+0x67,0x20,0x4f,0x53,0x2e,0x0d,0x0a,0x09,0x20,0x20,0x3c,0x2f,0x70,0x3e,0x0d,0x0a,
+0x09,0x20,0x20,0x3c,0x70,0x3e,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x6c,0x77,0x49,
+0x50,0x20,0x69,0x73,0x20,0x61,0x6e,0x20,0x6f,0x70,0x65,0x6e,0x20,0x73,0x6f,0x75,
+0x72,0x63,0x65,0x20,0x69,0x6d,0x70,0x6c,0x65,0x6d,0x65,0x6e,0x74,0x61,0x74,0x69,
+0x6f,0x6e,0x20,0x6f,0x66,0x20,0x74,0x68,0x65,0x20,0x54,0x43,0x50,0x2f,0x49,0x50,
+0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x70,0x72,0x6f,0x74,0x6f,0x63,0x6f,0x6c,0x20,
+0x73,0x75,0x69,0x74,0x65,0x20,0x74,0x68,0x61,0x74,0x20,0x77,0x61,0x73,0x20,0x6f,
+0x72,0x69,0x67,0x69,0x6e,0x61,0x6c,0x6c,0x79,0x20,0x77,0x72,0x69,0x74,0x74,0x65,
+0x6e,0x20,0x62,0x79,0x20,0x3c,0x61,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x68,0x72,
+0x65,0x66,0x3d,0x22,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77,0x77,0x77,0x2e,0x73,
+0x69,0x63,0x73,0x2e,0x73,0x65,0x2f,0x7e,0x61,0x64,0x61,0x6d,0x2f,0x6c,0x77,0x69,
+0x70,0x2f,0x22,0x3e,0x41,0x64,0x61,0x6d,0x20,0x44,0x75,0x6e,0x6b,0x65,0x6c,0x73,
+0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x6f,0x66,0x20,0x74,0x68,0x65,0x20,0x53,0x77,
+0x65,0x64,0x69,0x73,0x68,0x20,0x49,0x6e,0x73,0x74,0x69,0x74,0x75,0x74,0x65,0x20,
+0x6f,0x66,0x20,0x43,0x6f,0x6d,0x70,0x75,0x74,0x65,0x72,0x20,0x53,0x63,0x69,0x65,
+0x6e,0x63,0x65,0x3c,0x2f,0x61,0x3e,0x20,0x62,0x75,0x74,0x20,0x6e,0x6f,0x77,0x20,
+0x69,0x73,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x62,0x65,0x69,0x6e,0x67,0x20,0x61,
+0x63,0x74,0x69,0x76,0x65,0x6c,0x79,0x20,0x64,0x65,0x76,0x65,0x6c,0x6f,0x70,0x65,
+0x64,0x20,0x62,0x79,0x20,0x61,0x20,0x74,0x65,0x61,0x6d,0x20,0x6f,0x66,0x20,0x64,
+0x65,0x76,0x65,0x6c,0x6f,0x70,0x65,0x72,0x73,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,
+0x64,0x69,0x73,0x74,0x72,0x69,0x62,0x75,0x74,0x65,0x64,0x20,0x77,0x6f,0x72,0x6c,
+0x64,0x2d,0x77,0x69,0x64,0x65,0x2e,0x20,0x53,0x69,0x6e,0x63,0x65,0x20,0x69,0x74,
+0x27,0x73,0x20,0x72,0x65,0x6c,0x65,0x61,0x73,0x65,0x2c,0x20,0x6c,0x77,0x49,0x50,
+0x20,0x68,0x61,0x73,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x73,0x70,0x75,0x72,0x72,
+0x65,0x64,0x20,0x61,0x20,0x6c,0x6f,0x74,0x20,0x6f,0x66,0x20,0x69,0x6e,0x74,0x65,
+0x72,0x65,0x73,0x74,0x20,0x61,0x6e,0x64,0x20,0x68,0x61,0x73,0x20,0x62,0x65,0x65,
+0x6e,0x20,0x70,0x6f,0x72,0x74,0x65,0x64,0x20,0x74,0x6f,0x20,0x73,0x65,0x76,0x65,
+0x72,0x61,0x6c,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x70,0x6c,0x61,0x74,0x66,0x6f,
+0x72,0x6d,0x73,0x20,0x61,0x6e,0x64,0x20,0x6f,0x70,0x65,0x72,0x61,0x74,0x69,0x6e,
+0x67,0x20,0x73,0x79,0x73,0x74,0x65,0x6d,0x73,0x2e,0x20,0x6c,0x77,0x49,0x50,0x20,
+0x63,0x61,0x6e,0x20,0x62,0x65,0x20,0x75,0x73,0x65,0x64,0x20,0x65,0x69,0x74,0x68,
+0x65,0x72,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x77,0x69,0x74,0x68,0x20,0x6f,0x72,
+0x20,0x77,0x69,0x74,0x68,0x6f,0x75,0x74,0x20,0x61,0x6e,0x20,0x75,0x6e,0x64,0x65,
+0x72,0x6c,0x79,0x69,0x6e,0x67,0x20,0x4f,0x53,0x2e,0x0d,0x0a,0x09,0x20,0x20,0x3c,
+0x2f,0x70,0x3e,0x0d,0x0a,0x09,0x20,0x20,0x3c,0x70,0x3e,0x0d,0x0a,0x09,0x20,0x20,
+0x20,0x20,0x6c,0x77,0x49,0x50,0x20,0x69,0x73,0x20,0x61,0x6e,0x20,0x6f,0x70,0x65,
+0x6e,0x20,0x73,0x6f,0x75,0x72,0x63,0x65,0x20,0x69,0x6d,0x70,0x6c,0x65,0x6d,0x65,
+0x6e,0x74,0x61,0x74,0x69,0x6f,0x6e,0x20,0x6f,0x66,0x20,0x74,0x68,0x65,0x20,0x54,
+0x43,0x50,0x2f,0x49,0x50,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x70,0x72,0x6f,0x74,
+0x6f,0x63,0x6f,0x6c,0x20,0x73,0x75,0x69,0x74,0x65,0x20,0x74,0x68,0x61,0x74,0x20,
+0x77,0x61,0x73,0x20,0x6f,0x72,0x69,0x67,0x69,0x6e,0x61,0x6c,0x6c,0x79,0x20,0x77,
+0x72,0x69,0x74,0x74,0x65,0x6e,0x20,0x62,0x79,0x20,0x3c,0x61,0x0d,0x0a,0x09,0x20,
+0x20,0x20,0x20,0x68,0x72,0x65,0x66,0x3d,0x22,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,
+0x77,0x77,0x77,0x2e,0x73,0x69,0x63,0x73,0x2e,0x73,0x65,0x2f,0x7e,0x61,0x64,0x61,
+0x6d,0x2f,0x6c,0x77,0x69,0x70,0x2f,0x22,0x3e,0x41,0x64,0x61,0x6d,0x20,0x44,0x75,
+0x6e,0x6b,0x65,0x6c,0x73,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x6f,0x66,0x20,0x74,
+0x68,0x65,0x20,0x53,0x77,0x65,0x64,0x69,0x73,0x68,0x20,0x49,0x6e,0x73,0x74,0x69,
+0x74,0x75,0x74,0x65,0x20,0x6f,0x66,0x20,0x43,0x6f,0x6d,0x70,0x75,0x74,0x65,0x72,
+0x20,0x53,0x63,0x69,0x65,0x6e,0x63,0x65,0x3c,0x2f,0x61,0x3e,0x20,0x62,0x75,0x74,
+0x20,0x6e,0x6f,0x77,0x20,0x69,0x73,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x62,0x65,
+0x69,0x6e,0x67,0x20,0x61,0x63,0x74,0x69,0x76,0x65,0x6c,0x79,0x20,0x64,0x65,0x76,
+0x65,0x6c,0x6f,0x70,0x65,0x64,0x20,0x62,0x79,0x20,0x61,0x20,0x74,0x65,0x61,0x6d,
+0x20,0x6f,0x66,0x20,0x64,0x65,0x76,0x65,0x6c,0x6f,0x70,0x65,0x72,0x73,0x0d,0x0a,
+0x09,0x20,0x20,0x20,0x20,0x64,0x69,0x73,0x74,0x72,0x69,0x62,0x75,0x74,0x65,0x64,
+0x20,0x77,0x6f,0x72,0x6c,0x64,0x2d,0x77,0x69,0x64,0x65,0x2e,0x20,0x53,0x69,0x6e,
+0x63,0x65,0x20,0x69,0x74,0x27,0x73,0x20,0x72,0x65,0x6c,0x65,0x61,0x73,0x65,0x2c,
+0x20,0x6c,0x77,0x49,0x50,0x20,0x68,0x61,0x73,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,
+0x73,0x70,0x75,0x72,0x72,0x65,0x64,0x20,0x61,0x20,0x6c,0x6f,0x74,0x20,0x6f,0x66,
+0x20,0x69,0x6e,0x74,0x65,0x72,0x65,0x73,0x74,0x20,0x61,0x6e,0x64,0x20,0x68,0x61,
+0x73,0x20,0x62,0x65,0x65,0x6e,0x20,0x70,0x6f,0x72,0x74,0x65,0x64,0x20,0x74,0x6f,
+0x20,0x73,0x65,0x76,0x65,0x72,0x61,0x6c,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x70,
+0x6c,0x61,0x74,0x66,0x6f,0x72,0x6d,0x73,0x20,0x61,0x6e,0x64,0x20,0x6f,0x70,0x65,
+0x72,0x61,0x74,0x69,0x6e,0x67,0x20,0x73,0x79,0x73,0x74,0x65,0x6d,0x73,0x2e,0x20,
+0x6c,0x77,0x49,0x50,0x20,0x63,0x61,0x6e,0x20,0x62,0x65,0x20,0x75,0x73,0x65,0x64,
+0x20,0x65,0x69,0x74,0x68,0x65,0x72,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x77,0x69,
+0x74,0x68,0x20,0x6f,0x72,0x20,0x77,0x69,0x74,0x68,0x6f,0x75,0x74,0x20,0x61,0x6e,
+0x20,0x75,0x6e,0x64,0x65,0x72,0x6c,0x79,0x69,0x6e,0x67,0x20,0x4f,0x53,0x2e,0x0d,
+0x0a,0x09,0x20,0x20,0x3c,0x2f,0x70,0x3e,0x0d,0x0a,0x09,0x20,0x20,0x3c,0x70,0x3e,
+0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x6c,0x77,0x49,0x50,0x20,0x69,0x73,0x20,0x61,
+0x6e,0x20,0x6f,0x70,0x65,0x6e,0x20,0x73,0x6f,0x75,0x72,0x63,0x65,0x20,0x69,0x6d,
+0x70,0x6c,0x65,0x6d,0x65,0x6e,0x74,0x61,0x74,0x69,0x6f,0x6e,0x20,0x6f,0x66,0x20,
+0x74,0x68,0x65,0x20,0x54,0x43,0x50,0x2f,0x49,0x50,0x0d,0x0a,0x09,0x20,0x20,0x20,
+0x20,0x70,0x72,0x6f,0x74,0x6f,0x63,0x6f,0x6c,0x20,0x73,0x75,0x69,0x74,0x65,0x20,
+0x74,0x68,0x61,0x74,0x20,0x77,0x61,0x73,0x20,0x6f,0x72,0x69,0x67,0x69,0x6e,0x61,
+0x6c,0x6c,0x79,0x20,0x77,0x72,0x69,0x74,0x74,0x65,0x6e,0x20,0x62,0x79,0x20,0x3c,
+0x61,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x68,0x72,0x65,0x66,0x3d,0x22,0x68,0x74,
+0x74,0x70,0x3a,0x2f,0x2f,0x77,0x77,0x77,0x2e,0x73,0x69,0x63,0x73,0x2e,0x73,0x65,
+0x2f,0x7e,0x61,0x64,0x61,0x6d,0x2f,0x6c,0x77,0x69,0x70,0x2f,0x22,0x3e,0x41,0x64,
+0x61,0x6d,0x20,0x44,0x75,0x6e,0x6b,0x65,0x6c,0x73,0x0d,0x0a,0x09,0x20,0x20,0x20,
+0x20,0x6f,0x66,0x20,0x74,0x68,0x65,0x20,0x53,0x77,0x65,0x64,0x69,0x73,0x68,0x20,
+0x49,0x6e,0x73,0x74,0x69,0x74,0x75,0x74,0x65,0x20,0x6f,0x66,0x20,0x43,0x6f,0x6d,
+0x70,0x75,0x74,0x65,0x72,0x20,0x53,0x63,0x69,0x65,0x6e,0x63,0x65,0x3c,0x2f,0x61,
+0x3e,0x20,0x62,0x75,0x74,0x20,0x6e,0x6f,0x77,0x20,0x69,0x73,0x0d,0x0a,0x09,0x20,
+0x20,0x20,0x20,0x62,0x65,0x69,0x6e,0x67,0x20,0x61,0x63,0x74,0x69,0x76,0x65,0x6c,
+0x79,0x20,0x64,0x65,0x76,0x65,0x6c,0x6f,0x70,0x65,0x64,0x20,0x62,0x79,0x20,0x61,
+0x20,0x74,0x65,0x61,0x6d,0x20,0x6f,0x66,0x20,0x64,0x65,0x76,0x65,0x6c,0x6f,0x70,
+0x65,0x72,0x73,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x64,0x69,0x73,0x74,0x72,0x69,
+0x62,0x75,0x74,0x65,0x64,0x20,0x77,0x6f,0x72,0x6c,0x64,0x2d,0x77,0x69,0x64,0x65,
+0x2e,0x20,0x53,0x69,0x6e,0x63,0x65,0x20,0x69,0x74,0x27,0x73,0x20,0x72,0x65,0x6c,
+0x65,0x61,0x73,0x65,0x2c,0x20,0x6c,0x77,0x49,0x50,0x20,0x68,0x61,0x73,0x0d,0x0a,
+0x09,0x20,0x20,0x20,0x20,0x73,0x70,0x75,0x72,0x72,0x65,0x64,0x20,0x61,0x20,0x6c,
+0x6f,0x74,0x20,0x6f,0x66,0x20,0x69,0x6e,0x74,0x65,0x72,0x65,0x73,0x74,0x20,0x61,
+0x6e,0x64,0x20,0x68,0x61,0x73,0x20,0x62,0x65,0x65,0x6e,0x20,0x70,0x6f,0x72,0x74,
+0x65,0x64,0x20,0x74,0x6f,0x20,0x73,0x65,0x76,0x65,0x72,0x61,0x6c,0x0d,0x0a,0x09,
+0x20,0x20,0x20,0x20,0x70,0x6c,0x61,0x74,0x66,0x6f,0x72,0x6d,0x73,0x20,0x61,0x6e,
+0x64,0x20,0x6f,0x70,0x65,0x72,0x61,0x74,0x69,0x6e,0x67,0x20,0x73,0x79,0x73,0x74,
+0x65,0x6d,0x73,0x2e,0x20,0x6c,0x77,0x49,0x50,0x20,0x63,0x61,0x6e,0x20,0x62,0x65,
+0x20,0x75,0x73,0x65,0x64,0x20,0x65,0x69,0x74,0x68,0x65,0x72,0x0d,0x0a,0x09,0x20,
+0x20,0x20,0x20,0x77,0x69,0x74,0x68,0x20,0x6f,0x72,0x20,0x77,0x69,0x74,0x68,0x6f,
+0x75,0x74,0x20,0x61,0x6e,0x20,0x75,0x6e,0x64,0x65,0x72,0x6c,0x79,0x69,0x6e,0x67,
+0x20,0x4f,0x53,0x2e,0x0d,0x0a,0x09,0x20,0x20,0x3c,0x2f,0x70,0x3e,0x0d,0x0a,0x09,
+0x20,0x20,0x3c,0x70,0x3e,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x6c,0x77,0x49,0x50,
+0x20,0x69,0x73,0x20,0x61,0x6e,0x20,0x6f,0x70,0x65,0x6e,0x20,0x73,0x6f,0x75,0x72,
+0x63,0x65,0x20,0x69,0x6d,0x70,0x6c,0x65,0x6d,0x65,0x6e,0x74,0x61,0x74,0x69,0x6f,
+0x6e,0x20,0x6f,0x66,0x20,0x74,0x68,0x65,0x20,0x54,0x43,0x50,0x2f,0x49,0x50,0x0d,
+0x0a,0x09,0x20,0x20,0x20,0x20,0x70,0x72,0x6f,0x74,0x6f,0x63,0x6f,0x6c,0x20,0x73,
+0x75,0x69,0x74,0x65,0x20,0x74,0x68,0x61,0x74,0x20,0x77,0x61,0x73,0x20,0x6f,0x72,
+0x69,0x67,0x69,0x6e,0x61,0x6c,0x6c,0x79,0x20,0x77,0x72,0x69,0x74,0x74,0x65,0x6e,
+0x20,0x62,0x79,0x20,0x3c,0x61,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x68,0x72,0x65,
+0x66,0x3d,0x22,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77,0x77,0x77,0x2e,0x73,0x69,
+0x63,0x73,0x2e,0x73,0x65,0x2f,0x7e,0x61,0x64,0x61,0x6d,0x2f,0x6c,0x77,0x69,0x70,
+0x2f,0x22,0x3e,0x41,0x64,0x61,0x6d,0x20,0x44,0x75,0x6e,0x6b,0x65,0x6c,0x73,0x0d,
+0x0a,0x09,0x20,0x20,0x20,0x20,0x6f,0x66,0x20,0x74,0x68,0x65,0x20,0x53,0x77,0x65,
+0x64,0x69,0x73,0x68,0x20,0x49,0x6e,0x73,0x74,0x69,0x74,0x75,0x74,0x65,0x20,0x6f,
+0x66,0x20,0x43,0x6f,0x6d,0x70,0x75,0x74,0x65,0x72,0x20,0x53,0x63,0x69,0x65,0x6e,
+0x63,0x65,0x3c,0x2f,0x61,0x3e,0x20,0x62,0x75,0x74,0x20,0x6e,0x6f,0x77,0x20,0x69,
+0x73,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x62,0x65,0x69,0x6e,0x67,0x20,0x61,0x63,
+0x74,0x69,0x76,0x65,0x6c,0x79,0x20,0x64,0x65,0x76,0x65,0x6c,0x6f,0x70,0x65,0x64,
+0x20,0x62,0x79,0x20,0x61,0x20,0x74,0x65,0x61,0x6d,0x20,0x6f,0x66,0x20,0x64,0x65,
+0x76,0x65,0x6c,0x6f,0x70,0x65,0x72,0x73,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x64,
+0x69,0x73,0x74,0x72,0x69,0x62,0x75,0x74,0x65,0x64,0x20,0x77,0x6f,0x72,0x6c,0x64,
+0x2d,0x77,0x69,0x64,0x65,0x2e,0x20,0x53,0x69,0x6e,0x63,0x65,0x20,0x69,0x74,0x27,
+0x73,0x20,0x72,0x65,0x6c,0x65,0x61,0x73,0x65,0x2c,0x20,0x6c,0x77,0x49,0x50,0x20,
+0x68,0x61,0x73,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x73,0x70,0x75,0x72,0x72,0x65,
+0x64,0x20,0x61,0x20,0x6c,0x6f,0x74,0x20,0x6f,0x66,0x20,0x69,0x6e,0x74,0x65,0x72,
+0x65,0x73,0x74,0x20,0x61,0x6e,0x64,0x20,0x68,0x61,0x73,0x20,0x62,0x65,0x65,0x6e,
+0x20,0x70,0x6f,0x72,0x74,0x65,0x64,0x20,0x74,0x6f,0x20,0x73,0x65,0x76,0x65,0x72,
+0x61,0x6c,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x70,0x6c,0x61,0x74,0x66,0x6f,0x72,
+0x6d,0x73,0x20,0x61,0x6e,0x64,0x20,0x6f,0x70,0x65,0x72,0x61,0x74,0x69,0x6e,0x67,
+0x20,0x73,0x79,0x73,0x74,0x65,0x6d,0x73,0x2e,0x20,0x6c,0x77,0x49,0x50,0x20,0x63,
+0x61,0x6e,0x20,0x62,0x65,0x20,0x75,0x73,0x65,0x64,0x20,0x65,0x69,0x74,0x68,0x65,
+0x72,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x77,0x69,0x74,0x68,0x20,0x6f,0x72,0x20,
+0x77,0x69,0x74,0x68,0x6f,0x75,0x74,0x20,0x61,0x6e,0x20,0x75,0x6e,0x64,0x65,0x72,
+0x6c,0x79,0x69,0x6e,0x67,0x20,0x4f,0x53,0x2e,0x0d,0x0a,0x09,0x20,0x20,0x3c,0x2f,
+0x70,0x3e,0x0d,0x0a,0x09,0x20,0x20,0x3c,0x70,0x3e,0x0d,0x0a,0x09,0x20,0x20,0x20,
+0x20,0x6c,0x77,0x49,0x50,0x20,0x69,0x73,0x20,0x61,0x6e,0x20,0x6f,0x70,0x65,0x6e,
+0x20,0x73,0x6f,0x75,0x72,0x63,0x65,0x20,0x69,0x6d,0x70,0x6c,0x65,0x6d,0x65,0x6e,
+0x74,0x61,0x74,0x69,0x6f,0x6e,0x20,0x6f,0x66,0x20,0x74,0x68,0x65,0x20,0x54,0x43,
+0x50,0x2f,0x49,0x50,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x70,0x72,0x6f,0x74,0x6f,
+0x63,0x6f,0x6c,0x20,0x73,0x75,0x69,0x74,0x65,0x20,0x74,0x68,0x61,0x74,0x20,0x77,
+0x61,0x73,0x20,0x6f,0x72,0x69,0x67,0x69,0x6e,0x61,0x6c,0x6c,0x79,0x20,0x77,0x72,
+0x69,0x74,0x74,0x65,0x6e,0x20,0x62,0x79,0x20,0x3c,0x61,0x0d,0x0a,0x09,0x20,0x20,
+0x20,0x20,0x68,0x72,0x65,0x66,0x3d,0x22,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77,
+0x77,0x77,0x2e,0x73,0x69,0x63,0x73,0x2e,0x73,0x65,0x2f,0x7e,0x61,0x64,0x61,0x6d,
+0x2f,0x6c,0x77,0x69,0x70,0x2f,0x22,0x3e,0x41,0x64,0x61,0x6d,0x20,0x44,0x75,0x6e,
+0x6b,0x65,0x6c,0x73,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x6f,0x66,0x20,0x74,0x68,
+0x65,0x20,0x53,0x77,0x65,0x64,0x69,0x73,0x68,0x20,0x49,0x6e,0x73,0x74,0x69,0x74,
+0x75,0x74,0x65,0x20,0x6f,0x66,0x20,0x43,0x6f,0x6d,0x70,0x75,0x74,0x65,0x72,0x20,
+0x53,0x63,0x69,0x65,0x6e,0x63,0x65,0x3c,0x2f,0x61,0x3e,0x20,0x62,0x75,0x74,0x20,
+0x6e,0x6f,0x77,0x20,0x69,0x73,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x62,0x65,0x69,
+0x6e,0x67,0x20,0x61,0x63,0x74,0x69,0x76,0x65,0x6c,0x79,0x20,0x64,0x65,0x76,0x65,
+0x6c,0x6f,0x70,0x65,0x64,0x20,0x62,0x79,0x20,0x61,0x20,0x74,0x65,0x61,0x6d,0x20,
+0x6f,0x66,0x20,0x64,0x65,0x76,0x65,0x6c,0x6f,0x70,0x65,0x72,0x73,0x0d,0x0a,0x09,
+0x20,0x20,0x20,0x20,0x64,0x69,0x73,0x74,0x72,0x69,0x62,0x75,0x74,0x65,0x64,0x20,
+0x77,0x6f,0x72,0x6c,0x64,0x2d,0x77,0x69,0x64,0x65,0x2e,0x20,0x53,0x69,0x6e,0x63,
+0x65,0x20,0x69,0x74,0x27,0x73,0x20,0x72,0x65,0x6c,0x65,0x61,0x73,0x65,0x2c,0x20,
+0x6c,0x77,0x49,0x50,0x20,0x68,0x61,0x73,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x73,
+0x70,0x75,0x72,0x72,0x65,0x64,0x20,0x61,0x20,0x6c,0x6f,0x74,0x20,0x6f,0x66,0x20,
+0x69,0x6e,0x74,0x65,0x72,0x65,0x73,0x74,0x20,0x61,0x6e,0x64,0x20,0x68,0x61,0x73,
+0x20,0x62,0x65,0x65,0x6e,0x20,0x70,0x6f,0x72,0x74,0x65,0x64,0x20,0x74,0x6f,0x20,
+0x73,0x65,0x76,0x65,0x72,0x61,0x6c,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x70,0x6c,
+0x61,0x74,0x66,0x6f,0x72,0x6d,0x73,0x20,0x61,0x6e,0x64,0x20,0x6f,0x70,0x65,0x72,
+0x61,0x74,0x69,0x6e,0x67,0x20,0x73,0x79,0x73,0x74,0x65,0x6d,0x73,0x2e,0x20,0x6c,
+0x77,0x49,0x50,0x20,0x63,0x61,0x6e,0x20,0x62,0x65,0x20,0x75,0x73,0x65,0x64,0x20,
+0x65,0x69,0x74,0x68,0x65,0x72,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x77,0x69,0x74,
+0x68,0x20,0x6f,0x72,0x20,0x77,0x69,0x74,0x68,0x6f,0x75,0x74,0x20,0x61,0x6e,0x20,
+0x75,0x6e,0x64,0x65,0x72,0x6c,0x79,0x69,0x6e,0x67,0x20,0x4f,0x53,0x2e,0x0d,0x0a,
+0x09,0x20,0x20,0x3c,0x2f,0x70,0x3e,0x0d,0x0a,0x09,0x20,0x20,0x3c,0x70,0x3e,0x0d,
+0x0a,0x09,0x20,0x20,0x20,0x20,0x6c,0x77,0x49,0x50,0x20,0x69,0x73,0x20,0x61,0x6e,
+0x20,0x6f,0x70,0x65,0x6e,0x20,0x73,0x6f,0x75,0x72,0x63,0x65,0x20,0x69,0x6d,0x70,
+0x6c,0x65,0x6d,0x65,0x6e,0x74,0x61,0x74,0x69,0x6f,0x6e,0x20,0x6f,0x66,0x20,0x74,
+0x68,0x65,0x20,0x54,0x43,0x50,0x2f,0x49,0x50,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,
+0x70,0x72,0x6f,0x74,0x6f,0x63,0x6f,0x6c,0x20,0x73,0x75,0x69,0x74,0x65,0x20,0x74,
+0x68,0x61,0x74,0x20,0x77,0x61,0x73,0x20,0x6f,0x72,0x69,0x67,0x69,0x6e,0x61,0x6c,
+0x6c,0x79,0x20,0x77,0x72,0x69,0x74,0x74,0x65,0x6e,0x20,0x62,0x79,0x20,0x3c,0x61,
+0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x68,0x72,0x65,0x66,0x3d,0x22,0x68,0x74,0x74,
+0x70,0x3a,0x2f,0x2f,0x77,0x77,0x77,0x2e,0x73,0x69,0x63,0x73,0x2e,0x73,0x65,0x2f,
+0x7e,0x61,0x64,0x61,0x6d,0x2f,0x6c,0x77,0x69,0x70,0x2f,0x22,0x3e,0x41,0x64,0x61,
+0x6d,0x20,0x44,0x75,0x6e,0x6b,0x65,0x6c,0x73,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,
+0x6f,0x66,0x20,0x74,0x68,0x65,0x20,0x53,0x77,0x65,0x64,0x69,0x73,0x68,0x20,0x49,
+0x6e,0x73,0x74,0x69,0x74,0x75,0x74,0x65,0x20,0x6f,0x66,0x20,0x43,0x6f,0x6d,0x70,
+0x75,0x74,0x65,0x72,0x20,0x53,0x63,0x69,0x65,0x6e,0x63,0x65,0x3c,0x2f,0x61,0x3e,
+0x20,0x62,0x75,0x74,0x20,0x6e,0x6f,0x77,0x20,0x69,0x73,0x0d,0x0a,0x09,0x20,0x20,
+0x20,0x20,0x62,0x65,0x69,0x6e,0x67,0x20,0x61,0x63,0x74,0x69,0x76,0x65,0x6c,0x79,
+0x20,0x64,0x65,0x76,0x65,0x6c,0x6f,0x70,0x65,0x64,0x20,0x62,0x79,0x20,0x61,0x20,
+0x74,0x65,0x61,0x6d,0x20,0x6f,0x66,0x20,0x64,0x65,0x76,0x65,0x6c,0x6f,0x70,0x65,
+0x72,0x73,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x64,0x69,0x73,0x74,0x72,0x69,0x62,
+0x75,0x74,0x65,0x64,0x20,0x77,0x6f,0x72,0x6c,0x64,0x2d,0x77,0x69,0x64,0x65,0x2e,
+0x20,0x53,0x69,0x6e,0x63,0x65,0x20,0x69,0x74,0x27,0x73,0x20,0x72,0x65,0x6c,0x65,
+0x61,0x73,0x65,0x2c,0x20,0x6c,0x77,0x49,0x50,0x20,0x68,0x61,0x73,0x0d,0x0a,0x09,
+0x20,0x20,0x20,0x20,0x73,0x70,0x75,0x72,0x72,0x65,0x64,0x20,0x61,0x20,0x6c,0x6f,
+0x74,0x20,0x6f,0x66,0x20,0x69,0x6e,0x74,0x65,0x72,0x65,0x73,0x74,0x20,0x61,0x6e,
+0x64,0x20,0x68,0x61,0x73,0x20,0x62,0x65,0x65,0x6e,0x20,0x70,0x6f,0x72,0x74,0x65,
+0x64,0x20,0x74,0x6f,0x20,0x73,0x65,0x76,0x65,0x72,0x61,0x6c,0x0d,0x0a,0x09,0x20,
+0x20,0x20,0x20,0x70,0x6c,0x61,0x74,0x66,0x6f,0x72,0x6d,0x73,0x20,0x61,0x6e,0x64,
+0x20,0x6f,0x70,0x65,0x72,0x61,0x74,0x69,0x6e,0x67,0x20,0x73,0x79,0x73,0x74,0x65,
+0x6d,0x73,0x2e,0x20,0x6c,0x77,0x49,0x50,0x20,0x63,0x61,0x6e,0x20,0x62,0x65,0x20,
+0x75,0x73,0x65,0x64,0x20,0x65,0x69,0x74,0x68,0x65,0x72,0x0d,0x0a,0x09,0x20,0x20,
+0x20,0x20,0x77,0x69,0x74,0x68,0x20,0x6f,0x72,0x20,0x77,0x69,0x74,0x68,0x6f,0x75,
+0x74,0x20,0x61,0x6e,0x20,0x75,0x6e,0x64,0x65,0x72,0x6c,0x79,0x69,0x6e,0x67,0x20,
+0x4f,0x53,0x2e,0x0d,0x0a,0x09,0x20,0x20,0x3c,0x2f,0x70,0x3e,0x0d,0x0a,0x09,0x20,
+0x20,0x3c,0x70,0x3e,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x54,0x68,0x65,0x20,0x66,
+0x6f,0x63,0x75,0x73,0x20,0x6f,0x66,0x20,0x74,0x68,0x65,0x20,0x6c,0x77,0x49,0x50,
+0x20,0x54,0x43,0x50,0x2f,0x49,0x50,0x20,0x69,0x6d,0x70,0x6c,0x65,0x6d,0x65,0x6e,
+0x74,0x61,0x74,0x69,0x6f,0x6e,0x20,0x69,0x73,0x20,0x74,0x6f,0x20,0x72,0x65,0x64,
+0x75,0x63,0x65,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x74,0x68,0x65,0x20,0x52,0x41,
+0x4d,0x20,0x75,0x73,0x61,0x67,0x65,0x20,0x77,0x68,0x69,0x6c,0x65,0x20,0x73,0x74,
+0x69,0x6c,0x6c,0x20,0x68,0x61,0x76,0x69,0x6e,0x67,0x20,0x61,0x20,0x66,0x75,0x6c,
+0x6c,0x20,0x73,0x63,0x61,0x6c,0x65,0x20,0x54,0x43,0x50,0x2e,0x20,0x54,0x68,0x69,
+0x73,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x6d,0x61,0x6b,0x65,0x73,0x20,0x6c,0x77,
+0x49,0x50,0x20,0x73,0x75,0x69,0x74,0x61,0x62,0x6c,0x65,0x20,0x66,0x6f,0x72,0x20,
+0x75,0x73,0x65,0x20,0x69,0x6e,0x20,0x65,0x6d,0x62,0x65,0x64,0x64,0x65,0x64,0x20,
+0x73,0x79,0x73,0x74,0x65,0x6d,0x73,0x20,0x77,0x69,0x74,0x68,0x20,0x74,0x65,0x6e,
+0x73,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x6f,0x66,0x20,0x6b,0x69,0x6c,0x6f,0x62,
+0x79,0x74,0x65,0x73,0x20,0x6f,0x66,0x20,0x66,0x72,0x65,0x65,0x20,0x52,0x41,0x4d,
+0x20,0x61,0x6e,0x64,0x20,0x72,0x6f,0x6f,0x6d,0x20,0x66,0x6f,0x72,0x20,0x61,0x72,
+0x6f,0x75,0x6e,0x64,0x20,0x34,0x30,0x20,0x6b,0x69,0x6c,0x6f,0x62,0x79,0x74,0x65,
+0x73,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x6f,0x66,0x20,0x63,0x6f,0x64,0x65,0x20,
+0x52,0x4f,0x4d,0x2e,0x0d,0x0a,0x09,0x20,0x20,0x3c,0x2f,0x70,0x3e,0x0d,0x0a,0x09,
+0x20,0x20,0x3c,0x70,0x3e,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x4d,0x6f,0x72,0x65,
+0x20,0x69,0x6e,0x66,0x6f,0x72,0x6d,0x61,0x74,0x69,0x6f,0x6e,0x20,0x61,0x62,0x6f,
+0x75,0x74,0x20,0x6c,0x77,0x49,0x50,0x20,0x63,0x61,0x6e,0x20,0x62,0x65,0x20,0x66,
+0x6f,0x75,0x6e,0x64,0x20,0x61,0x74,0x20,0x74,0x68,0x65,0x20,0x6c,0x77,0x49,0x50,
+0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x68,0x6f,0x6d,0x65,0x70,0x61,0x67,0x65,0x20,
+0x61,0x74,0x20,0x3c,0x61,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x68,0x72,0x65,0x66,
+0x3d,0x22,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x73,0x61,0x76,0x61,0x6e,0x6e,0x61,
+0x68,0x2e,0x6e,0x6f,0x6e,0x67,0x6e,0x75,0x2e,0x6f,0x72,0x67,0x2f,0x70,0x72,0x6f,
+0x6a,0x65,0x63,0x74,0x73,0x2f,0x6c,0x77,0x69,0x70,0x2f,0x22,0x3e,0x68,0x74,0x74,
+0x70,0x3a,0x2f,0x2f,0x73,0x61,0x76,0x61,0x6e,0x6e,0x61,0x68,0x2e,0x6e,0x6f,0x6e,
+0x67,0x6e,0x75,0x2e,0x6f,0x72,0x67,0x2f,0x70,0x72,0x6f,0x6a,0x65,0x63,0x74,0x73,
+0x2f,0x6c,0x77,0x69,0x70,0x2f,0x3c,0x2f,0x61,0x3e,0x0d,0x0a,0x09,0x20,0x20,0x20,
+0x20,0x6f,0x72,0x20,0x61,0x74,0x20,0x74,0x68,0x65,0x20,0x6c,0x77,0x49,0x50,0x20,
+0x77,0x69,0x6b,0x69,0x20,0x61,0x74,0x20,0x3c,0x61,0x0d,0x0a,0x09,0x20,0x20,0x20,
+0x20,0x68,0x72,0x65,0x66,0x3d,0x22,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x6c,0x77,
+0x69,0x70,0x2e,0x77,0x69,0x6b,0x69,0x61,0x2e,0x63,0x6f,0x6d,0x2f,0x22,0x3e,0x68,
+0x74,0x74,0x70,0x3a,0x2f,0x2f,0x6c,0x77,0x69,0x70,0x2e,0x77,0x69,0x6b,0x69,0x61,
+0x2e,0x63,0x6f,0x6d,0x2f,0x3c,0x2f,0x61,0x3e,0x2e,0x0d,0x0a,0x09,0x20,0x20,0x3c,
+0x2f,0x70,0x3e,0x0d,0x0a,0x09,0x3c,0x2f,0x74,0x64,0x3e,0x3c,0x74,0x64,0x3e,0x0d,
+0x0a,0x09,0x20,0x20,0x26,0x6e,0x62,0x73,0x70,0x3b,0x0d,0x0a,0x09,0x3c,0x2f,0x74,
+0x64,0x3e,0x3c,0x2f,0x74,0x72,0x3e,0x0d,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x3c,
+0x2f,0x74,0x61,0x62,0x6c,0x65,0x3e,0x0d,0x0a,0x3c,0x2f,0x62,0x6f,0x64,0x79,0x3e,
+0x0d,0x0a,0x3c,0x2f,0x68,0x74,0x6d,0x6c,0x3e,0x0d,0x0a,0x0d,0x0a,};
+
+
+
+const struct fsdata_file file__img_sics_gif[] = { {
+file_NULL,
+data__img_sics_gif,
+data__img_sics_gif + 16,
+sizeof(data__img_sics_gif) - 16,
+FS_FILE_FLAGS_HEADER_INCLUDED | FS_FILE_FLAGS_HEADER_PERSISTENT | FS_FILE_FLAGS_HEADER_HTTPVER_1_1,
+}};
+
+const struct fsdata_file file__404_html[] = { {
+file__img_sics_gif,
+data__404_html,
+data__404_html + 12,
+sizeof(data__404_html) - 12,
+FS_FILE_FLAGS_HEADER_INCLUDED | FS_FILE_FLAGS_HEADER_PERSISTENT | FS_FILE_FLAGS_HEADER_HTTPVER_1_1,
+}};
+
+const struct fsdata_file file__index_html[] = { {
+file__404_html,
+data__index_html,
+data__index_html + 12,
+sizeof(data__index_html) - 12,
+FS_FILE_FLAGS_HEADER_INCLUDED | FS_FILE_FLAGS_HEADER_PERSISTENT | FS_FILE_FLAGS_HEADER_HTTPVER_1_1,
+}};
+
+const struct fsdata_file file__login_html[] = { {
+file__index_html,
+data__login_html,
+data__login_html + 12,
+sizeof(data__login_html) - 12,
+FS_FILE_FLAGS_HEADER_INCLUDED | FS_FILE_FLAGS_HEADER_PERSISTENT | FS_FILE_FLAGS_HEADER_HTTPVER_1_1,
+}};
+
+const struct fsdata_file file__loginfail_html[] = { {
+file__login_html,
+data__loginfail_html,
+data__loginfail_html + 16,
+sizeof(data__loginfail_html) - 16,
+FS_FILE_FLAGS_HEADER_INCLUDED | FS_FILE_FLAGS_HEADER_PERSISTENT | FS_FILE_FLAGS_HEADER_HTTPVER_1_1,
+}};
+
+const struct fsdata_file file__session_html[] = { {
+file__loginfail_html,
+data__session_html,
+data__session_html + 16,
+sizeof(data__session_html) - 16,
+FS_FILE_FLAGS_HEADER_INCLUDED | FS_FILE_FLAGS_HEADER_PERSISTENT | FS_FILE_FLAGS_HEADER_HTTPVER_1_1,
+}};
+
+const struct fsdata_file file__ssi_shtml[] = { {
+file__session_html,
+data__ssi_shtml,
+data__ssi_shtml + 12,
+sizeof(data__ssi_shtml) - 12,
+FS_FILE_FLAGS_HEADER_INCLUDED | FS_FILE_FLAGS_SSI,
+}};
+
+#define FS_ROOT file__ssi_shtml
+#define FS_NUMFILES 7
+
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/examples/httpd/fs_example/fs_example.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/examples/httpd/fs_example/fs_example.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/examples/httpd/fs_example/fs_example.c	(revision 457)
@@ -0,0 +1,321 @@
+/**
+ * @file
+ * HTTPD custom file system example
+ *
+ * This file demonstrates how to add support for an external file system to httpd.
+ * It provides access to the specified root directory and uses stdio.h file functions
+ * to read files.
+ *
+ * ATTENTION: This implementation is *not* secure: no checks are added to ensure
+ * files are only read below the specified root directory!
+ */
+ 
+ /*
+ * Copyright (c) 2017 Simon Goldschmidt
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission. 
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ * 
+ * Author: Simon Goldschmidt <goldsimon@gmx.de>
+ *
+ */
+
+#include "lwip/opt.h"
+#include "fs_example.h"
+
+#include "lwip/apps/fs.h"
+#include "lwip/def.h"
+#include "lwip/mem.h"
+
+#include <stdio.h>
+#include <string.h>
+
+/** define LWIP_HTTPD_EXAMPLE_CUSTOMFILES to 1 to enable this file system */
+#ifndef LWIP_HTTPD_EXAMPLE_CUSTOMFILES
+#define LWIP_HTTPD_EXAMPLE_CUSTOMFILES 0
+#endif
+
+/** define LWIP_HTTPD_EXAMPLE_CUSTOMFILES_DELAYED to 1 to delay open and read
+ * as if e.g. reading from external SPI flash */
+#ifndef LWIP_HTTPD_EXAMPLE_CUSTOMFILES_DELAYED
+#define LWIP_HTTPD_EXAMPLE_CUSTOMFILES_DELAYED 1
+#endif
+
+/** define LWIP_HTTPD_EXAMPLE_CUSTOMFILES_LIMIT_READ to the number of bytes
+ * to read to emulate limited transfer buffers and don't read whole files in
+ * one chunk.
+ * WARNING: lowering this slows down the connection!
+ */
+#ifndef LWIP_HTTPD_EXAMPLE_CUSTOMFILES_LIMIT_READ
+#define LWIP_HTTPD_EXAMPLE_CUSTOMFILES_LIMIT_READ 0
+#endif
+
+#if LWIP_HTTPD_EXAMPLE_CUSTOMFILES
+
+#if !LWIP_HTTPD_CUSTOM_FILES
+#error This needs LWIP_HTTPD_CUSTOM_FILES
+#endif
+#if !LWIP_HTTPD_DYNAMIC_HEADERS
+#error This needs LWIP_HTTPD_DYNAMIC_HEADERS
+#endif
+#if !LWIP_HTTPD_DYNAMIC_FILE_READ
+#error This wants to demonstrate read-after-open, so LWIP_HTTPD_DYNAMIC_FILE_READ is required!
+#endif
+#if !LWIP_HTTPD_FS_ASYNC_READ
+#error This needs LWIP_HTTPD_FS_ASYNC_READ
+#endif
+
+#if LWIP_HTTPD_EXAMPLE_CUSTOMFILES_DELAYED
+#include "lwip/tcpip.h"
+#endif
+
+struct fs_custom_data {
+  FILE *f;
+#if LWIP_HTTPD_EXAMPLE_CUSTOMFILES_DELAYED
+  int delay_read;
+  fs_wait_cb callback_fn;
+  void *callback_arg;
+#endif
+};
+
+const char* fs_ex_root_dir;
+
+void
+fs_ex_init(const char *httpd_root_dir)
+{
+  fs_ex_root_dir = strdup(httpd_root_dir);
+}
+
+#if LWIP_HTTPD_CUSTOM_FILES
+int
+fs_open_custom(struct fs_file *file, const char *name)
+{
+  char full_filename[256];
+  FILE *f;
+
+  snprintf(full_filename, 255, "%s%s", fs_ex_root_dir, name);
+  full_filename[255] = 0;
+
+  f = fopen(full_filename, "rb");
+  if (f != NULL) {
+    if (!fseek(f, 0, SEEK_END)) {
+      int len = (int)ftell(f);
+      if(!fseek(f, 0, SEEK_SET)) {
+        struct fs_custom_data *data = (struct fs_custom_data *)mem_malloc(sizeof(struct fs_custom_data));
+        LWIP_ASSERT("out of memory?", data != NULL);
+        memset(file, 0, sizeof(struct fs_file));
+#if LWIP_HTTPD_EXAMPLE_CUSTOMFILES_DELAYED
+        file->len = 0; /* read size delayed */
+        data->delay_read = 3;
+        LWIP_UNUSED_ARG(len);
+#else
+        file->len = len;
+#endif
+        file->flags = FS_FILE_FLAGS_HEADER_PERSISTENT;
+        data->f = f;
+        file->pextension = data;
+        return 1;
+      }
+    }
+    fclose(f);
+  }
+  return 0;
+}
+
+void
+fs_close_custom(struct fs_file *file)
+{
+  if (file && file->pextension) {
+    struct fs_custom_data *data = (struct fs_custom_data *)file->pextension;
+    if (data->f != NULL) {
+      fclose(data->f);
+      data->f = NULL;
+    }
+    mem_free(data);
+  }
+}
+
+#if LWIP_HTTPD_FS_ASYNC_READ
+u8_t
+fs_canread_custom(struct fs_file *file)
+{
+  /* This function is only necessary for asynchronous I/O:
+     If reading would block, return 0 and implement fs_wait_read_custom() to call the
+     supplied callback if reading works. */
+#if LWIP_HTTPD_EXAMPLE_CUSTOMFILES_DELAYED
+  struct fs_custom_data *data;
+  LWIP_ASSERT("file != NULL", file != NULL);
+  data = (struct fs_custom_data *)file->pextension;
+  if (data == NULL) {
+    /* file transfer has been completed already */
+    LWIP_ASSERT("transfer complete", file->index == file->len);
+    return 1;
+  }
+  LWIP_ASSERT("data != NULL", data != NULL);
+  /* This just simulates a simple delay. This delay would normally come e.g. from SPI transfer */
+  if (data->delay_read == 3) {
+    /* delayed file size mode */
+    data->delay_read = 1;
+    LWIP_ASSERT("", file->len == 0);
+    if (!fseek(data->f, 0, SEEK_END)) {
+      int len = (int)ftell(data->f);
+      if(!fseek(data->f, 0, SEEK_SET)) {
+        file->len = len; /* read size delayed */
+        data->delay_read = 1;
+        return 0;
+      }
+    }
+    /* if we come here, something is wrong with the file */
+    LWIP_ASSERT("file error", 0);
+  }
+  if (data->delay_read == 1) {
+    /* tell read function to delay further */
+  }
+#endif
+  LWIP_UNUSED_ARG(file);
+  return 1;
+}
+
+#if LWIP_HTTPD_EXAMPLE_CUSTOMFILES_DELAYED
+static void
+fs_example_read_cb(void *arg)
+{
+  struct fs_custom_data *data = (struct fs_custom_data *)arg;
+  fs_wait_cb callback_fn = data->callback_fn;
+  void *callback_arg = data->callback_arg;
+  data->callback_fn = NULL;
+  data->callback_arg = NULL;
+
+  LWIP_ASSERT("no callback_fn", callback_fn != NULL);
+
+  callback_fn(callback_arg);
+}
+#endif
+
+u8_t
+fs_wait_read_custom(struct fs_file *file, fs_wait_cb callback_fn, void *callback_arg)
+{
+#if LWIP_HTTPD_EXAMPLE_CUSTOMFILES_DELAYED
+  err_t err;
+  struct fs_custom_data *data = (struct fs_custom_data *)file->pextension;
+  LWIP_ASSERT("data not set", data != NULL);
+  data->callback_fn = callback_fn;
+  data->callback_arg = callback_arg;
+  err = tcpip_try_callback(fs_example_read_cb, data);
+  LWIP_ASSERT("out of queue elements?", err == ERR_OK);
+  LWIP_UNUSED_ARG(err);
+#else
+  LWIP_ASSERT("not implemented in this example configuration", 0);
+#endif
+  LWIP_UNUSED_ARG(file);
+  LWIP_UNUSED_ARG(callback_fn);
+  LWIP_UNUSED_ARG(callback_arg);
+  /* Return
+     - 1 if ready to read (at least one byte)
+     - 0 if reading should be delayed (call 'tcpip_callback(callback_fn, callback_arg)' when ready) */
+  return 1;
+}
+
+int
+fs_read_async_custom(struct fs_file *file, char *buffer, int count, fs_wait_cb callback_fn, void *callback_arg)
+{
+  struct fs_custom_data *data = (struct fs_custom_data *)file->pextension;
+  FILE *f;
+  int len;
+  int read_count = count;
+  LWIP_ASSERT("data not set", data != NULL);
+
+#if LWIP_HTTPD_EXAMPLE_CUSTOMFILES_DELAYED
+  /* This just simulates a delay. This delay would normally come e.g. from SPI transfer */
+  LWIP_ASSERT("invalid state", data->delay_read >= 0 && data->delay_read <= 2);
+  if (data->delay_read == 2) {
+    /* no delay next time */
+    data->delay_read = 0;
+    return FS_READ_DELAYED;
+  } else if (data->delay_read == 1) {
+    err_t err;
+    /* execute requested delay */
+    data->delay_read = 2;
+    LWIP_ASSERT("duplicate callback request", data->callback_fn == NULL);
+    data->callback_fn = callback_fn;
+    data->callback_arg = callback_arg;
+    err = tcpip_try_callback(fs_example_read_cb, data);
+    LWIP_ASSERT("out of queue elements?", err == ERR_OK);
+    LWIP_UNUSED_ARG(err);
+    return FS_READ_DELAYED;
+  }
+  /* execute this read but delay the next one */
+  data->delay_read = 1;
+#endif
+
+#if LWIP_HTTPD_EXAMPLE_CUSTOMFILES_LIMIT_READ
+  read_count = LWIP_MIN(read_count, LWIP_HTTPD_EXAMPLE_CUSTOMFILES_LIMIT_READ);
+#endif
+
+  f = data->f;
+  len = (int)fread(buffer, 1, read_count, f);
+
+  LWIP_UNUSED_ARG(callback_fn);
+  LWIP_UNUSED_ARG(callback_arg);
+
+  file->index += len;
+
+  /* Return
+     - FS_READ_EOF if all bytes have been read
+     - FS_READ_DELAYED if reading is delayed (call 'tcpip_callback(callback_fn, callback_arg)' when done) */
+  if (len == 0) {
+    /* all bytes read already */
+    return FS_READ_EOF;
+  }
+  return len;
+}
+
+#else /* LWIP_HTTPD_FS_ASYNC_READ */
+int
+fs_read_custom(struct fs_file *file, char *buffer, int count)
+{
+  struct fs_custom_data *data = (struct fs_custom_data *)file->pextension;
+  FILE *f;
+  int len;
+  int read_count = count;
+  LWIP_ASSERT("data not set", data != NULL);
+
+#if LWIP_HTTPD_EXAMPLE_CUSTOMFILES_LIMIT_READ
+  read_count = LWIP_MIN(read_count, LWIP_HTTPD_EXAMPLE_CUSTOMFILES_LIMIT_READ);
+#endif
+
+  f = data->f;
+  len = (int)fread(buffer, 1, read_count, f);
+
+  file->index += len;
+
+  /* Return FS_READ_EOF if all bytes have been read */
+  return len;
+}
+
+#endif /* LWIP_HTTPD_FS_ASYNC_READ */
+#endif /* LWIP_HTTPD_CUSTOM_FILES */
+
+#endif /* LWIP_HTTPD_EXAMPLE_CUSTOMFILES */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/examples/httpd/fs_example/fs_example.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/examples/httpd/fs_example/fs_example.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/examples/httpd/fs_example/fs_example.h	(revision 457)
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2017 Simon Goldschmidt
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission. 
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ * 
+ * Author: Simon Goldschmidt <goldsimon@gmx.de>
+ *
+ */
+
+#ifndef LWIP_HDR_HTTP_EXAMPLES_FS_EXAMPLE
+#define LWIP_HDR_HTTP_EXAMPLES_FS_EXAMPLE
+
+void fs_ex_init(const char *httpd_root_dir);
+
+#endif /* LWIP_HDR_HTTP_EXAMPLES_FS_EXAMPLE */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/examples/httpd/genfiles_example/genfiles_example.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/examples/httpd/genfiles_example/genfiles_example.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/examples/httpd/genfiles_example/genfiles_example.c	(revision 457)
@@ -0,0 +1,183 @@
+/**
+ * @file
+ * HTTPD custom file system example for runtime generated files
+ *
+ * This file demonstrates how to add support for generated files to httpd.
+ */
+ 
+ /*
+ * Copyright (c) 2017 Simon Goldschmidt
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission. 
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ * 
+ * Author: Simon Goldschmidt <goldsimon@gmx.de>
+ *
+ */
+
+#include "lwip/opt.h"
+#include "genfiles_example.h"
+
+#include "lwip/apps/fs.h"
+#include "lwip/def.h"
+#include "lwip/mem.h"
+
+#include <stdio.h>
+#include <string.h>
+
+/** define LWIP_HTTPD_EXAMPLE_GENERATEDFILES to 1 to enable this file system */
+#ifndef LWIP_HTTPD_EXAMPLE_GENERATEDFILES
+#define LWIP_HTTPD_EXAMPLE_GENERATEDFILES 0
+#endif
+
+#if LWIP_HTTPD_EXAMPLE_GENERATEDFILES
+
+#if !LWIP_HTTPD_CUSTOM_FILES
+#error This needs LWIP_HTTPD_CUSTOM_FILES
+#endif
+#if !LWIP_HTTPD_DYNAMIC_HEADERS
+#error This needs LWIP_HTTPD_DYNAMIC_HEADERS
+#endif
+
+/* This is the page we send. It's not generated, as you see.
+ * Generating custom things instead of memcpy is left to your imagination :-)
+ */
+const char generated_html[] =
+"<html>\n"
+"<head><title>lwIP - A Lightweight TCP/IP Stack</title></head>\n"
+" <body bgcolor=\"white\" text=\"black\">\n"
+"  <table width=\"100%\">\n"
+"   <tr valign=\"top\">\n"
+"    <td width=\"80\">\n"
+"     <a href=\"http://www.sics.se/\"><img src=\"/img/sics.gif\"\n"
+"      border=\"0\" alt=\"SICS logo\" title=\"SICS logo\"></a>\n"
+"    </td>\n"
+"    <td width=\"500\">\n"
+"     <h1>lwIP - A Lightweight TCP/IP Stack</h1>\n"
+"     <h2>Generated page</h2>\n"
+"     <p>This page might be generated in-memory at runtime</p>\n"
+"    </td>\n"
+"    <td>\n"
+"    &nbsp;\n"
+"    </td>\n"
+"   </tr>\n"
+"  </table>\n"
+" </body>\n"
+"</html>";
+
+
+void
+genfiles_ex_init(void)
+{
+  /* nothing to do here yet */
+}
+
+int
+fs_open_custom(struct fs_file *file, const char *name)
+{
+  /* this example only provides one file */
+  if (!strcmp(name, "/generated.html")) {
+    /* initialize fs_file correctly */
+    memset(file, 0, sizeof(struct fs_file));
+    file->pextension = mem_malloc(sizeof(generated_html));
+    if (file->pextension != NULL) {
+      /* instead of doing memcpy, you would generate e.g. a JSON here */
+      memcpy(file->pextension, generated_html, sizeof(generated_html));
+      file->data = (const char *)file->pextension;
+      file->len = sizeof(generated_html) - 1; /* don't send the trailing 0 */
+      file->index = file->len;
+      /* allow persisteng connections */
+      file->flags = FS_FILE_FLAGS_HEADER_PERSISTENT;
+      return 1;
+    }
+  }
+  return 0;
+}
+
+void
+fs_close_custom(struct fs_file *file)
+{
+  if (file && file->pextension) {
+    mem_free(file->pextension);
+    file->pextension = NULL;
+  }
+}
+
+#if LWIP_HTTPD_FS_ASYNC_READ
+u8_t
+fs_canread_custom(struct fs_file *file)
+{
+  LWIP_UNUSED_ARG(file);
+  /* This example does not use delayed/async reading */
+  return 1;
+}
+
+u8_t
+fs_wait_read_custom(struct fs_file *file, fs_wait_cb callback_fn, void *callback_arg)
+{
+  LWIP_ASSERT("not implemented in this example configuration", 0);
+  LWIP_UNUSED_ARG(file);
+  LWIP_UNUSED_ARG(callback_fn);
+  LWIP_UNUSED_ARG(callback_arg);
+  /* Return
+     - 1 if ready to read (at least one byte)
+     - 0 if reading should be delayed (call 'tcpip_callback(callback_fn, callback_arg)' when ready) */
+  return 1;
+}
+
+int
+fs_read_async_custom(struct fs_file *file, char *buffer, int count, fs_wait_cb callback_fn, void *callback_arg)
+{
+  LWIP_ASSERT("not implemented in this example configuration", 0);
+  LWIP_UNUSED_ARG(file);
+  LWIP_UNUSED_ARG(buffer);
+  LWIP_UNUSED_ARG(count);
+  LWIP_UNUSED_ARG(callback_fn);
+  LWIP_UNUSED_ARG(callback_arg);
+  /* Return
+     - FS_READ_EOF if all bytes have been read
+     - FS_READ_DELAYED if reading is delayed (call 'tcpip_callback(callback_fn, callback_arg)' when done) */
+  /* all bytes read already */
+  return FS_READ_EOF;
+}
+
+#else /* LWIP_HTTPD_FS_ASYNC_READ */
+int
+fs_read_custom(struct fs_file *file, char *buffer, int count)
+{
+  LWIP_ASSERT("not implemented in this example configuration", 0);
+  LWIP_UNUSED_ARG(file);
+  LWIP_UNUSED_ARG(buffer);
+  LWIP_UNUSED_ARG(count);
+  /* Return
+     - FS_READ_EOF if all bytes have been read
+     - FS_READ_DELAYED if reading is delayed (call 'tcpip_callback(callback_fn, callback_arg)' when done) */
+  /* all bytes read already */
+  return FS_READ_EOF;
+}
+
+#endif /* LWIP_HTTPD_FS_ASYNC_READ */
+
+#endif /* LWIP_HTTPD_EXAMPLE_GENERATEDFILES */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/examples/httpd/genfiles_example/genfiles_example.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/examples/httpd/genfiles_example/genfiles_example.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/examples/httpd/genfiles_example/genfiles_example.h	(revision 457)
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2017 Simon Goldschmidt
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission. 
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ * 
+ * Author: Simon Goldschmidt <goldsimon@gmx.de>
+ *
+ */
+
+#ifndef LWIP_HDR_HTTP_EXAMPLES_GENFILES_EXAMPLE
+#define LWIP_HDR_HTTP_EXAMPLES_GENFILES_EXAMPLE
+
+void genfiles_ex_init(void);
+
+#endif /* LWIP_HDR_HTTP_EXAMPLES_GENFILES_EXAMPLE */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/examples/httpd/post_example/post_example.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/examples/httpd/post_example/post_example.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/examples/httpd/post_example/post_example.c	(revision 457)
@@ -0,0 +1,157 @@
+/**
+ * @file
+ * HTTPD example for simple POST
+ */
+ 
+ /*
+ * Copyright (c) 2017 Simon Goldschmidt
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission. 
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ * 
+ * Author: Simon Goldschmidt <goldsimon@gmx.de>
+ *
+ */
+
+#include "lwip/opt.h"
+
+#include "lwip/apps/httpd.h"
+#include "lwip/def.h"
+#include "lwip/mem.h"
+
+#include <stdio.h>
+#include <string.h>
+
+/** define LWIP_HTTPD_EXAMPLE_GENERATEDFILES to 1 to enable this file system */
+#ifndef LWIP_HTTPD_EXAMPLE_SIMPLEPOST
+#define LWIP_HTTPD_EXAMPLE_SIMPLEPOST 0
+#endif
+
+#if LWIP_HTTPD_EXAMPLE_SIMPLEPOST
+
+#if !LWIP_HTTPD_SUPPORT_POST
+#error This needs LWIP_HTTPD_SUPPORT_POST
+#endif
+
+#define USER_PASS_BUFSIZE 16
+
+static void *current_connection;
+static void *valid_connection;
+static char last_user[USER_PASS_BUFSIZE];
+
+err_t
+httpd_post_begin(void *connection, const char *uri, const char *http_request,
+                 u16_t http_request_len, int content_len, char *response_uri,
+                 u16_t response_uri_len, u8_t *post_auto_wnd)
+{
+  LWIP_UNUSED_ARG(connection);
+  LWIP_UNUSED_ARG(http_request);
+  LWIP_UNUSED_ARG(http_request_len);
+  LWIP_UNUSED_ARG(content_len);
+  LWIP_UNUSED_ARG(post_auto_wnd);
+  if (!memcmp(uri, "/login.cgi", 11)) {
+    if (current_connection != connection) {
+      current_connection = connection;
+      valid_connection = NULL;
+      /* default page is "login failed" */
+      snprintf(response_uri, response_uri_len, "/loginfail.html");
+      /* e.g. for large uploads to slow flash over a fast connection, you should
+         manually update the rx window. That way, a sender can only send a full
+         tcp window at a time. If this is required, set 'post_aut_wnd' to 0.
+         We do not need to throttle upload speed here, so: */
+      *post_auto_wnd = 1;
+      return ERR_OK;
+    }
+  }
+  return ERR_VAL;
+}
+
+err_t
+httpd_post_receive_data(void *connection, struct pbuf *p)
+{
+  if (current_connection == connection) {
+    u16_t token_user = pbuf_memfind(p, "user=", 5, 0);
+    u16_t token_pass = pbuf_memfind(p, "pass=", 5, 0);
+    if ((token_user != 0xFFFF) && (token_pass != 0xFFFF)) {
+      u16_t value_user = token_user + 5;
+      u16_t value_pass = token_pass + 5;
+      u16_t len_user = 0;
+      u16_t len_pass = 0;
+      u16_t tmp;
+      /* find user len */
+      tmp = pbuf_memfind(p, "&", 1, value_user);
+      if (tmp != 0xFFFF) {
+        len_user = tmp - value_user;
+      } else {
+        len_user = p->tot_len - value_user;
+      }
+      /* find pass len */
+      tmp = pbuf_memfind(p, "&", 1, value_pass);
+      if (tmp != 0xFFFF) {
+        len_pass = tmp - value_pass;
+      } else {
+        len_pass = p->tot_len - value_pass;
+      }
+      if ((len_user > 0) && (len_user < USER_PASS_BUFSIZE) &&
+          (len_pass > 0) && (len_pass < USER_PASS_BUFSIZE)) {
+        /* provide contiguous storage if p is a chained pbuf */
+        char buf_user[USER_PASS_BUFSIZE];
+        char buf_pass[USER_PASS_BUFSIZE];
+        char *user = (char *)pbuf_get_contiguous(p, buf_user, sizeof(buf_user), len_user, value_user);
+        char *pass = (char *)pbuf_get_contiguous(p, buf_pass, sizeof(buf_pass), len_pass, value_pass);
+        if (user && pass) {
+          user[len_user] = 0;
+          pass[len_pass] = 0;
+          if (!strcmp(user, "lwip") && !strcmp(pass, "post")) {
+            /* user and password are correct, create a "session" */
+            valid_connection = connection;
+            memcpy(last_user, user, sizeof(last_user));
+          }
+        }
+      }
+    }
+    /* not returning ERR_OK aborts the connection, so return ERR_OK unless the
+       conenction is unknown */
+    return ERR_OK;
+  }
+  return ERR_VAL;
+}
+
+void
+httpd_post_finished(void *connection, char *response_uri, u16_t response_uri_len)
+{
+  /* default page is "login failed" */
+  snprintf(response_uri, response_uri_len, "/loginfail.html");
+  if (current_connection == connection) {
+    if (valid_connection == connection) {
+      /* login succeeded */
+      snprintf(response_uri, response_uri_len, "/session.html");
+    }
+    current_connection = NULL;
+    valid_connection = NULL;
+  }
+}
+
+#endif /* LWIP_HTTPD_EXAMPLE_SIMPLEPOST*/
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/examples/httpd/ssi_example/ssi_example.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/examples/httpd/ssi_example/ssi_example.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/examples/httpd/ssi_example/ssi_example.c	(revision 457)
@@ -0,0 +1,264 @@
+/**
+ * @file
+ * HTTPD simple SSI example
+ *
+ * This file demonstrates how to add support for SSI.
+ * It does this in a very simple way by providing the three tags 'HelloWorld'
+ * 'counter', and 'MultiPart'.
+ *
+ * This file also demonstrates how to integrate CGI with SSI.
+ */
+ 
+ /*
+ * Copyright (c) 2017 Simon Goldschmidt
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission. 
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ * 
+ * Author: Simon Goldschmidt <goldsimon@gmx.de>
+ *
+ */
+
+#include "lwip/opt.h"
+#include "ssi_example.h"
+
+#include "lwip/apps/httpd.h"
+
+#include "lwip/def.h"
+#include "lwip/mem.h"
+
+#include <stdio.h>
+#include <string.h>
+
+/** define LWIP_HTTPD_EXAMPLE_SSI_SIMPLE to 1 to enable this ssi example*/
+#ifndef LWIP_HTTPD_EXAMPLE_SSI_SIMPLE
+#define LWIP_HTTPD_EXAMPLE_SSI_SIMPLE 0
+#endif
+
+/** define LWIP_HTTPD_EXAMPLE_SSI_SIMPLE_CGI_INTEGRATION to 1 to show how to
+ * integrate CGI into SSI (LWIP_HTTPD_CGI_SSI) */
+#ifndef LWIP_HTTPD_EXAMPLE_SSI_SIMPLE_CGI_INTEGRATION
+#define LWIP_HTTPD_EXAMPLE_SSI_SIMPLE_CGI_INTEGRATION 0
+#endif
+
+#if LWIP_HTTPD_EXAMPLE_SSI_SIMPLE
+
+#if LWIP_HTTPD_EXAMPLE_SSI_SIMPLE_CGI_INTEGRATION
+#if !LWIP_HTTPD_FILE_STATE
+#error LWIP_HTTPD_EXAMPLE_SSI_SIMPLE_CGI_INTEGRATION needs LWIP_HTTPD_FILE_STATE
+#endif
+#if !LWIP_HTTPD_CGI_SSI
+#error LWIP_HTTPD_EXAMPLE_SSI_SIMPLE_CGI_INTEGRATION needs LWIP_HTTPD_CGI_SSI
+#endif
+
+#define MAX_CGI_LEN   16
+#endif
+
+const char * ssi_example_tags[] = {
+  "HellWorl",
+  "counter",
+  "MultPart"
+#if LWIP_HTTPD_EXAMPLE_SSI_SIMPLE_CGI_INTEGRATION
+  ,"CgiParam"
+#endif
+};
+
+u16_t ssi_example_ssi_handler(
+#if LWIP_HTTPD_SSI_RAW
+                             const char* ssi_tag_name,
+#else /* LWIP_HTTPD_SSI_RAW */
+                             int iIndex,
+#endif /* LWIP_HTTPD_SSI_RAW */
+                             char *pcInsert, int iInsertLen
+#if LWIP_HTTPD_SSI_MULTIPART
+                             , u16_t current_tag_part, u16_t *next_tag_part
+#endif /* LWIP_HTTPD_SSI_MULTIPART */
+#if defined(LWIP_HTTPD_FILE_STATE) && LWIP_HTTPD_FILE_STATE
+                             , void *connection_state
+#endif /* LWIP_HTTPD_FILE_STATE */
+                             )
+{
+  size_t printed;
+#if LWIP_HTTPD_SSI_RAW
+  /* a real application could use if(!strcmp) blocks here, but we want to keep
+     the differences between configurations small, so translate string to index here */
+  int iIndex;
+  for (iIndex = 0; iIndex < LWIP_ARRAYSIZE(ssi_example_tags); iIndex++) {
+    if(!strcmp(ssi_tag_name, ssi_example_tags[iIndex])) {
+      break;
+    }
+  }
+#endif
+#if defined(LWIP_HTTPD_FILE_STATE) && LWIP_HTTPD_FILE_STATE
+  LWIP_UNUSED_ARG(connection_state);
+#endif
+
+  switch (iIndex) {
+  case 0: /* "HelloWorld" */
+    printed = snprintf(pcInsert, iInsertLen, "Hello World!");
+    break;
+  case 1: /* "counter" */
+    {
+      static int counter;
+      counter++;
+      printed = snprintf(pcInsert, iInsertLen, "%d", counter);
+    }
+    break;
+  case 2: /* "MultPart" */
+#if LWIP_HTTPD_SSI_MULTIPART
+    switch (current_tag_part) {
+    case 0:
+      printed = snprintf(pcInsert, iInsertLen, "part0");
+      *next_tag_part = 1;
+      break;
+    case 1:
+      printed = snprintf(pcInsert, iInsertLen, "part1");
+      *next_tag_part = 2;
+      break;
+    case 2:
+      printed = snprintf(pcInsert, iInsertLen, "part2");
+      break;
+    default:
+      printed = snprintf(pcInsert, iInsertLen, "unhandled part: %d", (int)current_tag_part);
+      break;
+    }
+#else
+    printed = snprintf(pcInsert, iInsertLen, "LWIP_HTTPD_SSI_MULTIPART disabled");
+#endif
+    break;
+#if LWIP_HTTPD_EXAMPLE_SSI_SIMPLE_CGI_INTEGRATION
+  case 3:
+    if (connection_state) {
+      char *params = (char *)connection_state;
+      if (*params) {
+        printed = snprintf(pcInsert, iInsertLen, "%s", (char *)params);
+      } else {
+        printed = snprintf(pcInsert, iInsertLen, "none");
+      }
+    } else {
+       printed = snprintf(pcInsert, iInsertLen, "NULL");
+    }
+    break;
+#endif
+  default: /* unknown tag */
+    printed = 0;
+    break;
+  }
+  LWIP_ASSERT("sane length", printed <= 0xFFFF);
+  return (u16_t)printed;
+}
+
+void
+ssi_ex_init(void)
+{
+  int i;
+  for (i = 0; i < LWIP_ARRAYSIZE(ssi_example_tags); i++) {
+    LWIP_ASSERT("tag too long for LWIP_HTTPD_MAX_TAG_NAME_LEN",
+      strlen(ssi_example_tags[i]) <= LWIP_HTTPD_MAX_TAG_NAME_LEN);
+  }
+
+  http_set_ssi_handler(ssi_example_ssi_handler,
+#if LWIP_HTTPD_SSI_RAW
+    NULL, 0
+#else
+    ssi_example_tags, LWIP_ARRAYSIZE(ssi_example_tags)
+#endif
+    );
+}
+
+#if LWIP_HTTPD_EXAMPLE_SSI_SIMPLE_CGI_INTEGRATION
+void *
+fs_state_init(struct fs_file *file, const char *name)
+{
+  char *ret;
+  LWIP_UNUSED_ARG(file);
+  LWIP_UNUSED_ARG(name);
+  ret = (char *)mem_malloc(MAX_CGI_LEN);
+  if (ret) {
+    *ret = 0;
+  }
+  return ret;
+}
+
+void
+fs_state_free(struct fs_file *file, void *state)
+{
+  LWIP_UNUSED_ARG(file);
+  if (state != NULL) {
+    mem_free(state);
+  }
+}
+
+void
+httpd_cgi_handler(struct fs_file *file, const char* uri, int iNumParams,
+                              char **pcParam, char **pcValue
+#if defined(LWIP_HTTPD_FILE_STATE) && LWIP_HTTPD_FILE_STATE
+                                     , void *connection_state
+#endif /* LWIP_HTTPD_FILE_STATE */
+                                     )
+{
+  LWIP_UNUSED_ARG(file);
+  LWIP_UNUSED_ARG(uri);
+  if (connection_state != NULL) {
+    char *start = (char *)connection_state;
+    char *end = start + MAX_CGI_LEN;
+    int i;
+    memset(start, 0, MAX_CGI_LEN);
+    /* print a string of the arguments: */
+    for (i = 0; i < iNumParams; i++) {
+      size_t len;
+      len = end - start;
+      if (len) {
+        size_t inlen = strlen(pcParam[i]);
+        size_t copylen = LWIP_MIN(inlen, len);
+        memcpy(start, pcParam[i], copylen);
+        start += copylen;
+        len -= copylen;
+      }
+      if (len) {
+        *start = '=';
+        start++;
+        len--;
+      }
+      if (len) {
+        size_t inlen = strlen(pcValue[i]);
+        size_t copylen = LWIP_MIN(inlen, len);
+        memcpy(start, pcValue[i], copylen);
+        start += copylen;
+        len -= copylen;
+      }
+      if (len) {
+        *start = ';';
+        len--;
+      }
+      /* ensure NULL termination */
+      end--;
+      *end = 0;
+    }
+  }
+}
+#endif /* LWIP_HTTPD_EXAMPLE_SSI_SIMPLE_CGI_INTEGRATION */
+
+#endif /* LWIP_HTTPD_EXAMPLE_SSI_SIMPLE */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/examples/httpd/ssi_example/ssi_example.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/examples/httpd/ssi_example/ssi_example.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/examples/httpd/ssi_example/ssi_example.h	(revision 457)
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2017 Simon Goldschmidt
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission. 
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ * 
+ * Author: Simon Goldschmidt <goldsimon@gmx.de>
+ *
+ */
+
+#ifndef LWIP_HDR_HTTP_EXAMPLES_SSI_EXAMPLE
+#define LWIP_HDR_HTTP_EXAMPLES_SSI_EXAMPLE
+
+void ssi_ex_init(void);
+
+#endif /* LWIP_HDR_HTTP_EXAMPLES_SSI_EXAMPLE */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/examples/lwiperf/lwiperf_example.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/examples/lwiperf/lwiperf_example.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/examples/lwiperf/lwiperf_example.c	(revision 457)
@@ -0,0 +1,54 @@
+/*
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission. 
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ * 
+ * Author: Dirk Ziegelmeier <dziegel@gmx.de>
+ *
+ */
+
+#include "lwip/apps/lwiperf.h"
+#include "lwiperf_example.h"
+
+#if LWIP_TCP
+static void
+lwiperf_report(void *arg, enum lwiperf_report_type report_type,
+  const ip_addr_t* local_addr, u16_t local_port, const ip_addr_t* remote_addr, u16_t remote_port,
+  u32_t bytes_transferred, u32_t ms_duration, u32_t bandwidth_kbitpsec)
+{
+  LWIP_UNUSED_ARG(arg);
+  LWIP_UNUSED_ARG(local_addr);
+  LWIP_UNUSED_ARG(local_port);
+
+  printf("IPERF report: type=%d, remote: %s:%d, total bytes: %"U32_F", duration in ms: %"U32_F", kbits/s: %"U32_F"\n",
+    (int)report_type, ipaddr_ntoa(remote_addr), (int)remote_port, bytes_transferred, ms_duration, bandwidth_kbitpsec);
+}
+#endif /* LWIP_TCP */
+
+void
+lwiperf_example_init(void)
+{
+#if LWIP_TCP
+  lwiperf_start_tcp_server_default(lwiperf_report, NULL);
+#endif
+}
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/examples/lwiperf/lwiperf_example.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/examples/lwiperf/lwiperf_example.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/examples/lwiperf/lwiperf_example.h	(revision 457)
@@ -0,0 +1,43 @@
+/*
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission. 
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ * 
+ * Author: Dirk Ziegelmeier <dziegel@gmx.de>
+ *
+ */
+
+#ifndef LWIPERF_EXAMPLE_H
+#define LWIPERF_EXAMPLE_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void lwiperf_example_init(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LWIPERF_EXAMPLE_H */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/examples/mdns/mdns_example.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/examples/mdns/mdns_example.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/examples/mdns/mdns_example.c	(revision 457)
@@ -0,0 +1,63 @@
+/*
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission. 
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ * 
+ * Author: Dirk Ziegelmeier <dziegel@gmx.de>
+ *
+ */
+
+#include "lwip/apps/mdns.h"
+#include "mdns_example.h"
+
+#if LWIP_MDNS_RESPONDER
+static void
+srv_txt(struct mdns_service *service, void *txt_userdata)
+{
+  err_t res;
+  LWIP_UNUSED_ARG(txt_userdata);
+  
+  res = mdns_resp_add_service_txtitem(service, "path=/", 6);
+  LWIP_ERROR("mdns add service txt failed\n", (res == ERR_OK), return);
+}
+#endif
+
+#if LWIP_MDNS_RESPONDER
+static void
+mdns_example_report(struct netif* netif, u8_t result)
+{
+  LWIP_PLATFORM_DIAG(("mdns status[netif %d]: %d\n", netif->num, result));
+}
+#endif
+
+void
+mdns_example_init(void)
+{
+#if LWIP_MDNS_RESPONDER
+  mdns_resp_register_name_result_cb(mdns_example_report);
+  mdns_resp_init();
+  mdns_resp_add_netif(netif_default, "lwip", 3600);
+  mdns_resp_add_service(netif_default, "myweb", "_http", DNSSD_PROTO_TCP, 80, 3600, srv_txt, NULL);
+  mdns_resp_announce(netif_default);
+#endif
+}
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/examples/mdns/mdns_example.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/examples/mdns/mdns_example.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/examples/mdns/mdns_example.h	(revision 457)
@@ -0,0 +1,43 @@
+/*
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission. 
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ * 
+ * Author: Dirk Ziegelmeier <dziegel@gmx.de>
+ *
+ */
+
+#ifndef MDNS_EXAMPLE_H
+#define MDNS_EXAMPLE_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void mdns_example_init(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* MDNS_EXAMPLE_H */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/examples/mqtt/mqtt_example.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/examples/mqtt/mqtt_example.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/examples/mqtt/mqtt_example.c	(revision 457)
@@ -0,0 +1,128 @@
+/*
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission. 
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ * 
+ * Author: Dirk Ziegelmeier <dziegel@gmx.de>
+ *
+ */
+
+#include "lwip/apps/mqtt.h"
+#include "mqtt_example.h"
+
+#if LWIP_TCP
+
+/** Define this to a compile-time IP address initialization
+ * to connect anything else than IPv4 loopback
+ */
+#ifndef LWIP_MQTT_EXAMPLE_IPADDR_INIT
+#if LWIP_IPV4
+#define LWIP_MQTT_EXAMPLE_IPADDR_INIT = IPADDR4_INIT(IPADDR_LOOPBACK)
+#else
+#define LWIP_MQTT_EXAMPLE_IPADDR_INIT
+#endif
+#endif
+
+static ip_addr_t mqtt_ip LWIP_MQTT_EXAMPLE_IPADDR_INIT;
+static mqtt_client_t* mqtt_client;
+
+static const struct mqtt_connect_client_info_t mqtt_client_info =
+{
+  "test",
+  NULL, /* user */
+  NULL, /* pass */
+  100,  /* keep alive */
+  NULL, /* will_topic */
+  NULL, /* will_msg */
+  0,    /* will_qos */
+  0     /* will_retain */
+#if LWIP_ALTCP && LWIP_ALTCP_TLS
+  , NULL
+#endif
+};
+
+static void 
+mqtt_incoming_data_cb(void *arg, const u8_t *data, u16_t len, u8_t flags)
+{
+  const struct mqtt_connect_client_info_t* client_info = (const struct mqtt_connect_client_info_t*)arg;
+  LWIP_UNUSED_ARG(data);
+
+  printf("MQTT client \"%s\" data cb: len %d, flags %d\n", client_info->client_id,
+          (int)len, (int)flags);
+}
+
+static void
+mqtt_incoming_publish_cb(void *arg, const char *topic, u32_t tot_len)
+{
+  const struct mqtt_connect_client_info_t* client_info = (const struct mqtt_connect_client_info_t*)arg;
+
+  printf("MQTT client \"%s\" publish cb: topic %s, len %d\n", client_info->client_id,
+          topic, (int)tot_len);
+}
+
+static void
+mqtt_request_cb(void *arg, err_t err)
+{
+  const struct mqtt_connect_client_info_t* client_info = (const struct mqtt_connect_client_info_t*)arg;
+
+  printf("MQTT client \"%s\" request cb: err %d\n", client_info->client_id, (int)err);
+}
+
+static void
+mqtt_connection_cb(mqtt_client_t *client, void *arg, mqtt_connection_status_t status)
+{
+  const struct mqtt_connect_client_info_t* client_info = (const struct mqtt_connect_client_info_t*)arg;
+  LWIP_UNUSED_ARG(client);
+
+  printf("MQTT client \"%s\" connection cb: status %d\n", client_info->client_id, (int)status);
+
+  if (status == MQTT_CONNECT_ACCEPTED) {
+    mqtt_sub_unsub(client,
+            "topic_qos1", 1,
+            mqtt_request_cb, LWIP_CONST_CAST(void*, client_info),
+            1);
+    mqtt_sub_unsub(client,
+            "topic_qos0", 0,
+            mqtt_request_cb, LWIP_CONST_CAST(void*, client_info),
+            1);
+  }
+}
+#endif /* LWIP_TCP */
+
+void
+mqtt_example_init(void)
+{
+#if LWIP_TCP
+  mqtt_client = mqtt_client_new();
+
+  mqtt_set_inpub_callback(mqtt_client,
+          mqtt_incoming_publish_cb,
+          mqtt_incoming_data_cb,
+          LWIP_CONST_CAST(void*, &mqtt_client_info));
+
+  mqtt_client_connect(mqtt_client,
+          &mqtt_ip, MQTT_PORT,
+          mqtt_connection_cb, LWIP_CONST_CAST(void*, &mqtt_client_info),
+          &mqtt_client_info);
+#endif /* LWIP_TCP */
+}
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/examples/mqtt/mqtt_example.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/examples/mqtt/mqtt_example.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/examples/mqtt/mqtt_example.h	(revision 457)
@@ -0,0 +1,43 @@
+/*
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission. 
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ * 
+ * Author: Dirk Ziegelmeier <dziegel@gmx.de>
+ *
+ */
+
+#ifndef MQTT_EXAMPLE_H
+#define MQTT_EXAMPLE_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void mqtt_example_init(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* MQTT_EXAMPLE_H */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/examples/ppp/pppos_example.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/examples/ppp/pppos_example.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/examples/ppp/pppos_example.c	(revision 457)
@@ -0,0 +1,219 @@
+/*
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission. 
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ * 
+ * Author: Dirk Ziegelmeier <dziegel@gmx.de>
+ *
+ */
+
+#include "lwip/dns.h"
+
+#ifndef PPPOS_SUPPORT
+#define PPPOS_SUPPORT 0
+#endif /* PPPOS_SUPPORT */
+
+#if PPPOS_SUPPORT
+#include "netif/ppp/pppos.h"
+#include "lwip/sio.h"
+#define PPP_PTY_TEST 1
+#endif /* PPPOS_SUPPORT */
+
+#include "pppos_example.h"
+
+#if PPPOS_SUPPORT
+static sio_fd_t ppp_sio;
+static ppp_pcb *ppp;
+static struct netif pppos_netif;
+
+static void
+pppos_rx_thread(void *arg)
+{
+  u32_t len;
+  u8_t buffer[128];
+  LWIP_UNUSED_ARG(arg);
+
+  /* Please read the "PPPoS input path" chapter in the PPP documentation. */
+  while (1) {
+    len = sio_read(ppp_sio, buffer, sizeof(buffer));
+    if (len > 0) {
+      /* Pass received raw characters from PPPoS to be decoded through lwIP
+       * TCPIP thread using the TCPIP API. This is thread safe in all cases
+       * but you should avoid passing data byte after byte. */
+      pppos_input_tcpip(ppp, buffer, len);
+    }
+  }
+}
+
+static void
+ppp_link_status_cb(ppp_pcb *pcb, int err_code, void *ctx)
+{
+    struct netif *pppif = ppp_netif(pcb);
+    LWIP_UNUSED_ARG(ctx);
+
+    switch(err_code) {
+    case PPPERR_NONE:               /* No error. */
+        {
+#if LWIP_DNS
+        const ip_addr_t *ns;
+#endif /* LWIP_DNS */
+        fprintf(stderr, "ppp_link_status_cb: PPPERR_NONE\n\r");
+#if LWIP_IPV4
+        fprintf(stderr, "   our_ip4addr = %s\n\r", ip4addr_ntoa(netif_ip4_addr(pppif)));
+        fprintf(stderr, "   his_ipaddr  = %s\n\r", ip4addr_ntoa(netif_ip4_gw(pppif)));
+        fprintf(stderr, "   netmask     = %s\n\r", ip4addr_ntoa(netif_ip4_netmask(pppif)));
+#endif /* LWIP_IPV4 */
+#if LWIP_IPV6
+        fprintf(stderr, "   our_ip6addr = %s\n\r", ip6addr_ntoa(netif_ip6_addr(pppif, 0)));
+#endif /* LWIP_IPV6 */
+
+#if LWIP_DNS
+        ns = dns_getserver(0);
+        fprintf(stderr, "   dns1        = %s\n\r", ipaddr_ntoa(ns));
+        ns = dns_getserver(1);
+        fprintf(stderr, "   dns2        = %s\n\r", ipaddr_ntoa(ns));
+#endif /* LWIP_DNS */
+#if PPP_IPV6_SUPPORT
+        fprintf(stderr, "   our6_ipaddr = %s\n\r", ip6addr_ntoa(netif_ip6_addr(pppif, 0)));
+#endif /* PPP_IPV6_SUPPORT */
+        }
+        break;
+
+    case PPPERR_PARAM:             /* Invalid parameter. */
+        printf("ppp_link_status_cb: PPPERR_PARAM\n");
+        break;
+
+    case PPPERR_OPEN:              /* Unable to open PPP session. */
+        printf("ppp_link_status_cb: PPPERR_OPEN\n");
+        break;
+
+    case PPPERR_DEVICE:            /* Invalid I/O device for PPP. */
+        printf("ppp_link_status_cb: PPPERR_DEVICE\n");
+        break;
+
+    case PPPERR_ALLOC:             /* Unable to allocate resources. */
+        printf("ppp_link_status_cb: PPPERR_ALLOC\n");
+        break;
+
+    case PPPERR_USER:              /* User interrupt. */
+        printf("ppp_link_status_cb: PPPERR_USER\n");
+        break;
+
+    case PPPERR_CONNECT:           /* Connection lost. */
+        printf("ppp_link_status_cb: PPPERR_CONNECT\n");
+        break;
+
+    case PPPERR_AUTHFAIL:          /* Failed authentication challenge. */
+        printf("ppp_link_status_cb: PPPERR_AUTHFAIL\n");
+        break;
+
+    case PPPERR_PROTOCOL:          /* Failed to meet protocol. */
+        printf("ppp_link_status_cb: PPPERR_PROTOCOL\n");
+        break;
+
+    case PPPERR_PEERDEAD:          /* Connection timeout. */
+        printf("ppp_link_status_cb: PPPERR_PEERDEAD\n");
+        break;
+
+    case PPPERR_IDLETIMEOUT:       /* Idle Timeout. */
+        printf("ppp_link_status_cb: PPPERR_IDLETIMEOUT\n");
+        break;
+
+    case PPPERR_CONNECTTIME:       /* PPPERR_CONNECTTIME. */
+        printf("ppp_link_status_cb: PPPERR_CONNECTTIME\n");
+        break;
+
+    case PPPERR_LOOPBACK:          /* Connection timeout. */
+        printf("ppp_link_status_cb: PPPERR_LOOPBACK\n");
+        break;
+
+    default:
+        printf("ppp_link_status_cb: unknown errCode %d\n", err_code);
+        break;
+    }
+}
+
+static u32_t
+ppp_output_cb(ppp_pcb *pcb, u8_t *data, u32_t len, void *ctx)
+{
+  LWIP_UNUSED_ARG(pcb);
+  LWIP_UNUSED_ARG(ctx);
+  return sio_write(ppp_sio, data, len);
+}
+
+#if LWIP_NETIF_STATUS_CALLBACK
+static void
+netif_status_callback(struct netif *nif)
+{
+  printf("PPPNETIF: %c%c%d is %s\n", nif->name[0], nif->name[1], nif->num,
+         netif_is_up(nif) ? "UP" : "DOWN");
+#if LWIP_IPV4
+  printf("IPV4: Host at %s ", ip4addr_ntoa(netif_ip4_addr(nif)));
+  printf("mask %s ", ip4addr_ntoa(netif_ip4_netmask(nif)));
+  printf("gateway %s\n", ip4addr_ntoa(netif_ip4_gw(nif)));
+#endif /* LWIP_IPV4 */
+#if LWIP_IPV6
+  printf("IPV6: Host at %s\n", ip6addr_ntoa(netif_ip6_addr(nif, 0)));
+#endif /* LWIP_IPV6 */
+#if LWIP_NETIF_HOSTNAME
+  printf("FQDN: %s\n", netif_get_hostname(nif));
+#endif /* LWIP_NETIF_HOSTNAME */
+}
+#endif /* LWIP_NETIF_STATUS_CALLBACK */
+#endif
+
+void
+pppos_example_init(void)
+{
+#if PPPOS_SUPPORT
+#if PPP_PTY_TEST
+  ppp_sio = sio_open(2);
+#else
+  ppp_sio = sio_open(0);
+#endif
+  if(!ppp_sio)
+  {
+      perror("PPPOS example: Error opening device");
+      return;
+  }
+
+  ppp = pppos_create(&pppos_netif, ppp_output_cb, ppp_link_status_cb, NULL);
+  if (!ppp)
+  {
+      printf("PPPOS example: Could not create PPP control interface");
+      return;
+  }
+
+#ifdef LWIP_PPP_CHAP_TEST
+  ppp_set_auth(ppp, PPPAUTHTYPE_CHAP, "lwip", "mysecret");
+#endif
+
+  ppp_connect(ppp, 0);
+
+#if LWIP_NETIF_STATUS_CALLBACK
+  netif_set_status_callback(&pppos_netif, netif_status_callback);
+#endif /* LWIP_NETIF_STATUS_CALLBACK */
+
+  sys_thread_new("pppos_rx_thread", pppos_rx_thread, NULL, DEFAULT_THREAD_STACKSIZE, DEFAULT_THREAD_PRIO);
+#endif /* PPPOS_SUPPORT */
+}
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/examples/ppp/pppos_example.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/examples/ppp/pppos_example.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/examples/ppp/pppos_example.h	(revision 457)
@@ -0,0 +1,43 @@
+/*
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission. 
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ * 
+ * Author: Dirk Ziegelmeier <dziegel@gmx.de>
+ *
+ */
+
+#ifndef PPPOS_EXAMPLE_H
+#define PPPOS_EXAMPLE_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void pppos_example_init(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* PPPOS_EXAMPLE_H */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/examples/snmp/snmp_example.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/examples/snmp/snmp_example.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/examples/snmp/snmp_example.c	(revision 457)
@@ -0,0 +1,72 @@
+/*
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission. 
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ * 
+ * Author: Dirk Ziegelmeier <dziegel@gmx.de>
+ *
+ */
+
+#include "lwip/apps/snmp.h"
+#include "lwip/apps/snmp_mib2.h"
+#include "lwip/apps/snmpv3.h"
+#include "lwip/apps/snmp_snmpv2_framework.h"
+#include "lwip/apps/snmp_snmpv2_usm.h"
+#include "examples/snmp/snmp_v3/snmpv3_dummy.h"
+#include "examples/snmp/snmp_private_mib/private_mib.h"
+#include "snmp_example.h"
+
+
+#if LWIP_SNMP
+static const struct snmp_mib *mibs[] = {
+  &mib2,
+  &mib_private
+#if LWIP_SNMP_V3
+  , &snmpframeworkmib
+  , &snmpusmmib
+#endif
+};
+#endif /* LWIP_SNMP */
+
+void
+snmp_example_init(void)
+{
+#if LWIP_SNMP
+  lwip_privmib_init();
+#if SNMP_LWIP_MIB2
+#if SNMP_USE_NETCONN
+  snmp_threadsync_init(&snmp_mib2_lwip_locks, snmp_mib2_lwip_synchronizer);
+#endif /* SNMP_USE_NETCONN */
+  snmp_mib2_set_syscontact_readonly((const u8_t*)"root", NULL);
+  snmp_mib2_set_syslocation_readonly((const u8_t*)"lwIP development PC", NULL);
+  snmp_mib2_set_sysdescr((const u8_t*)"simhost", NULL);
+#endif /* SNMP_LWIP_MIB2 */
+
+#if LWIP_SNMP_V3
+  snmpv3_dummy_init();
+#endif
+
+  snmp_set_mibs(mibs, LWIP_ARRAYSIZE(mibs));
+  snmp_init();
+#endif /* LWIP_SNMP */
+}
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/examples/snmp/snmp_example.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/examples/snmp/snmp_example.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/examples/snmp/snmp_example.h	(revision 457)
@@ -0,0 +1,43 @@
+/*
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission. 
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ * 
+ * Author: Dirk Ziegelmeier <dziegel@gmx.de>
+ *
+ */
+
+#ifndef SNMP_EXAMPLE_H
+#define SNMP_EXAMPLE_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void snmp_example_init(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* SNMP_EXAMPLE_H */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/examples/snmp/snmp_private_mib/lwip_prvmib.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/examples/snmp/snmp_private_mib/lwip_prvmib.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/examples/snmp/snmp_private_mib/lwip_prvmib.c	(revision 457)
@@ -0,0 +1,401 @@
+/**
+ * @file
+ * lwip Private MIB 
+ *
+ * @todo create MIB file for this example
+ * @note the lwip enterprise tree root (26381) is owned by the lwIP project.
+ * It is NOT allowed to allocate new objects under this ID (26381) without our,
+ * the lwip developers, permission!
+ *
+ * Please apply for your own ID with IANA: http://www.iana.org/numbers.html
+ *  
+ * lwip        OBJECT IDENTIFIER ::= { enterprises 26381 }
+ * example     OBJECT IDENTIFIER ::= { lwip 1 }
+ */
+ 
+/*
+ * Copyright (c) 2006 Axon Digital Design B.V., The Netherlands.
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * Author: Christiaan Simons <christiaan.simons@axon.tv>
+ */
+
+#include "private_mib.h"
+
+#if LWIP_SNMP
+
+/** Directory where the sensor files are */
+#define SENSORS_DIR           "w:\\sensors"
+/** Set to 1 to read sensor values from files (in directory defined by SENSORS_DIR) */
+#define SENSORS_USE_FILES     0
+/** Set to 1 to search sensor files at startup (in directory defined by SENSORS_DIR) */
+#define SENSORS_SEARCH_FILES  0
+
+#if SENSORS_SEARCH_FILES
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <dirent.h>
+#endif /* SENSORS_SEARCH_FILES */
+
+#include <string.h>
+#include <stdio.h>
+
+#include "lwip/apps/snmp_table.h"
+#include "lwip/apps/snmp_scalar.h"
+
+#if !SENSORS_USE_FILES || !SENSORS_SEARCH_FILES
+/** When not using & searching files, defines the number of sensors */
+#define SENSOR_COUNT 4
+#endif /* !SENSORS_USE_FILES || !SENSORS_SEARCH_FILES */
+
+/*
+  This example presents a table for a few (at most 10) sensors.
+  Sensor detection takes place at initialization (once only).
+  Sensors may and can not be added or removed after agent
+  has started. Note this is only a limitation of this crude example,
+  the agent does support dynamic object insertions and removals.
+   
+  You'll need to manually create a directory called "sensors" and
+  a few single line text files with an integer temperature value.
+  The files must be called [0..9].txt. 
+   
+  ./sensors/0.txt [content: 20]
+  ./sensors/3.txt [content: 75]
+    
+  The sensor values may be changed in runtime by editing the 
+  text files in the "sensors" directory.
+*/
+
+#define SENSOR_MAX      10
+#define SENSOR_NAME_LEN 20
+
+struct sensor_inf
+{
+  u8_t num;
+
+  char file[SENSOR_NAME_LEN + 1];
+
+#if !SENSORS_USE_FILES
+  /** When not using files, contains the value of the sensor */
+  s32_t value;
+#endif /* !SENSORS_USE_FILES */
+};
+
+static struct sensor_inf sensors[SENSOR_MAX];
+
+static s16_t      sensor_count_get_value(struct snmp_node_instance* instance, void* value);
+static snmp_err_t sensor_table_get_cell_instance(const u32_t* column, const u32_t* row_oid, u8_t row_oid_len, struct snmp_node_instance* cell_instance);
+static snmp_err_t sensor_table_get_next_cell_instance(const u32_t* column, struct snmp_obj_id* row_oid, struct snmp_node_instance* cell_instance);
+static s16_t      sensor_table_get_value(struct snmp_node_instance* instance, void* value);
+static snmp_err_t sensor_table_set_value(struct snmp_node_instance* instance, u16_t len, void *value);
+
+/* sensorentry .1.3.6.1.4.1.26381.1.1.1 (.level0.level1)
+   where level 0 is the table column (temperature/file name)
+   and level 1 the table row (sensor index) */
+static const struct snmp_table_col_def sensor_table_columns[] = {
+  { 1, SNMP_ASN1_TYPE_INTEGER,      SNMP_NODE_INSTANCE_READ_WRITE },
+  { 2, SNMP_ASN1_TYPE_OCTET_STRING, SNMP_NODE_INSTANCE_READ_ONLY  }
+};
+
+/* sensortable .1.3.6.1.4.1.26381.1.1 */
+static const struct snmp_table_node sensor_table = SNMP_TABLE_CREATE(
+  1, sensor_table_columns, 
+  sensor_table_get_cell_instance, sensor_table_get_next_cell_instance, 
+  sensor_table_get_value, snmp_set_test_ok, sensor_table_set_value);
+
+/* sensorcount .1.3.6.1.4.1.26381.1.2 */
+static const struct snmp_scalar_node sensor_count = SNMP_SCALAR_CREATE_NODE_READONLY(
+  2, SNMP_ASN1_TYPE_INTEGER, sensor_count_get_value); 
+
+/* example .1.3.6.1.4.1.26381.1 */
+static const struct snmp_node* const example_nodes[] = {
+  &sensor_table.node.node,
+  &sensor_count.node.node
+};
+static const struct snmp_tree_node example_node = SNMP_CREATE_TREE_NODE(1, example_nodes);
+
+static const u32_t prvmib_base_oid[] = { 1,3,6,1,4,1,26381,1 };
+const struct snmp_mib mib_private = SNMP_MIB_CREATE(prvmib_base_oid, &example_node.node);
+
+#if 0
+/* for reference: we could also have expressed it like this: */
+
+/* lwip .1.3.6.1.4.1.26381 */
+static const struct snmp_node* const lwip_nodes[] = {
+  &example_node.node
+};
+static const struct snmp_tree_node lwip_node = SNMP_CREATE_TREE_NODE(26381, lwip_nodes);
+
+/* enterprises .1.3.6.1.4.1 */
+static const struct snmp_node* const enterprises_nodes[] = {
+  &lwip_node.node
+};
+static const struct snmp_tree_node enterprises_node = SNMP_CREATE_TREE_NODE(1, enterprises_nodes);
+
+/* private .1.3.6.1.4 */
+static const struct snmp_node* const private_nodes[] = {
+  &enterprises_node.node
+};
+static const struct snmp_tree_node private_root = SNMP_CREATE_TREE_NODE(4, private_nodes);
+
+static const u32_t prvmib_base_oid[] = { 1,3,6,1,4 };
+const struct snmp_mib mib_private = SNMP_MIB_CREATE(prvmib_base_oid, &private_root.node);
+#endif
+
+/**
+ * Initialises this private MIB before use.
+ * @see main.c
+ */
+void
+lwip_privmib_init(void)
+{
+#if SENSORS_USE_FILES && SENSORS_SEARCH_FILES
+  char *buf, *ebuf, *cp;
+  size_t bufsize;
+  int nbytes;
+  struct stat sb;
+  struct dirent *dp;
+  int fd;
+#else /* SENSORS_USE_FILES && SENSORS_SEARCH_FILES */
+  u8_t i;
+#endif /* SENSORS_USE_FILES && SENSORS_SEARCH_FILES */
+
+  memset(sensors, 0, sizeof(sensors));
+  
+  printf("SNMP private MIB start, detecting sensors.\n");
+
+#if SENSORS_USE_FILES && SENSORS_SEARCH_FILES
+  /* look for sensors in sensors directory */
+  fd = open(SENSORS_DIR, O_RDONLY);
+  if (fd > -1)
+  {
+    fstat(fd, &sb);
+    bufsize = sb.st_size;
+    if (bufsize < (size_t)sb.st_blksize)
+    {
+      bufsize = sb.st_blksize;
+    }
+    buf = (char*)malloc(bufsize);
+    if (buf != NULL)
+    {
+      do
+      {
+        long base;
+        
+        nbytes = getdirentries(fd, buf, bufsize, &base);
+        if (nbytes > 0)
+        {
+          ebuf = buf + nbytes;
+          cp = buf;
+          while (cp < ebuf)
+          {
+            dp = (struct dirent *)cp;
+            if (lwip_isdigit(dp->d_name[0]))
+            {
+              unsigned char idx = dp->d_name[0] - '0';
+
+              sensors[idx].num = idx+1;
+              strncpy(&sensors[idx].file[0], dp->d_name, SENSOR_NAME_LEN);
+              printf("%s\n", sensors[idx].file);
+            }
+            cp += dp->d_reclen;
+          }
+        } 
+      }
+      while (nbytes > 0);
+    
+      free(buf);
+    }
+    close(fd);
+  }
+#else /* SENSORS_USE_FILES && SENSORS_SEARCH_FILES */
+  for (i = 0; i < SENSOR_COUNT; i++) {
+    sensors[i].num = (u8_t)(i + 1);
+    snprintf(sensors[i].file, sizeof(sensors[i].file), "%d.txt", i);
+
+#if !SENSORS_USE_FILES
+    /* initialize sensor value to != zero */
+    sensors[i].value = 11 * (i+1);
+#endif /* !SENSORS_USE_FILES */
+  }
+#endif /* SENSORS_USE_FILE && SENSORS_SEARCH_FILES */
+}
+
+/* sensorcount .1.3.6.1.4.1.26381.1.2 */
+static s16_t
+sensor_count_get_value(struct snmp_node_instance* instance, void* value)
+{
+  size_t count = 0;
+  u32_t *uint_ptr = (u32_t*)value;
+
+  LWIP_UNUSED_ARG(instance);
+  
+  for(count=0; count<LWIP_ARRAYSIZE(sensors); count++) {
+    if(sensors[count].num == 0) {
+      *uint_ptr = (u32_t)count;
+      return sizeof(*uint_ptr);
+    }
+  }
+
+  return 0;  
+}
+
+/* sensortable .1.3.6.1.4.1.26381.1.1 */
+/* list of allowed value ranges for incoming OID */
+static const struct snmp_oid_range sensor_table_oid_ranges[] = {
+  { 1, SENSOR_MAX+1 }
+};
+
+static snmp_err_t
+sensor_table_get_cell_instance(const u32_t* column, const u32_t* row_oid, u8_t row_oid_len, struct snmp_node_instance* cell_instance)
+{
+  u32_t sensor_num;
+  size_t i;
+
+  LWIP_UNUSED_ARG(column);
+
+  /* check if incoming OID length and if values are in plausible range */
+  if(!snmp_oid_in_range(row_oid, row_oid_len, sensor_table_oid_ranges, LWIP_ARRAYSIZE(sensor_table_oid_ranges))) {
+    return SNMP_ERR_NOSUCHINSTANCE;
+  }
+
+  /* get sensor index from incoming OID */
+  sensor_num = row_oid[0];
+
+  /* find sensor with index */
+  for(i=0; i<LWIP_ARRAYSIZE(sensors); i++) {
+    if(sensors[i].num != 0) {
+      if(sensors[i].num == sensor_num) {
+        /* store sensor index for subsequent operations (get/test/set) */
+        cell_instance->reference.u32 = (u32_t)i;
+        return SNMP_ERR_NOERROR;
+      }
+    }
+  }
+
+  /* not found */
+  return SNMP_ERR_NOSUCHINSTANCE;
+}
+
+static snmp_err_t
+sensor_table_get_next_cell_instance(const u32_t* column, struct snmp_obj_id* row_oid, struct snmp_node_instance* cell_instance)
+{
+  size_t i;
+  struct snmp_next_oid_state state;
+  u32_t result_temp[LWIP_ARRAYSIZE(sensor_table_oid_ranges)];
+
+  LWIP_UNUSED_ARG(column);
+  
+  /* init struct to search next oid */
+  snmp_next_oid_init(&state, row_oid->id, row_oid->len, result_temp, LWIP_ARRAYSIZE(sensor_table_oid_ranges));
+
+  /* iterate over all possible OIDs to find the next one */
+  for(i=0; i<LWIP_ARRAYSIZE(sensors); i++) {
+    if(sensors[i].num != 0) {
+      u32_t test_oid[LWIP_ARRAYSIZE(sensor_table_oid_ranges)];
+
+      test_oid[0] = sensors[i].num;
+
+      /* check generated OID: is it a candidate for the next one? */
+      snmp_next_oid_check(&state, test_oid, LWIP_ARRAYSIZE(sensor_table_oid_ranges), (void*)i);
+    }
+  }
+
+  /* did we find a next one? */
+  if(state.status == SNMP_NEXT_OID_STATUS_SUCCESS) {
+    snmp_oid_assign(row_oid, state.next_oid, state.next_oid_len);
+    /* store sensor index for subsequent operations (get/test/set) */
+    cell_instance->reference.u32 = LWIP_CONST_CAST(u32_t, state.reference);
+    return SNMP_ERR_NOERROR;
+  }
+
+  /* not found */
+  return SNMP_ERR_NOSUCHINSTANCE;
+}
+
+static s16_t
+sensor_table_get_value(struct snmp_node_instance* instance, void* value)
+{
+  u32_t i = instance->reference.u32;
+  s32_t *temperature = (s32_t *)value;
+
+  switch (SNMP_TABLE_GET_COLUMN_FROM_OID(instance->instance_oid.id))
+  {
+  case 1: /* sensor value */
+#if SENSORS_USE_FILES
+    FILE* sensf;
+    char senspath[sizeof(SENSORS_DIR)+1+SENSOR_NAME_LEN+1] = SENSORS_DIR"/";
+
+    strncpy(&senspath[sizeof(SENSORS_DIR)],
+            sensors[i].file,
+            SENSOR_NAME_LEN);
+    sensf = fopen(senspath,"r");
+    if (sensf != NULL)
+    {
+      fscanf(sensf,"%"S32_F,temperature);
+      fclose(sensf);
+    }
+#else /* SENSORS_USE_FILES */
+    *temperature = sensors[i].value;
+#endif /* SENSORS_USE_FILES */
+    return sizeof(s32_t);
+  case 2: /* file name */
+    MEMCPY(value, sensors[i].file, strlen(sensors[i].file));
+    return (s16_t)strlen(sensors[i].file);
+  default:
+    return 0;
+  }
+}
+
+static snmp_err_t
+sensor_table_set_value(struct snmp_node_instance* instance, u16_t len, void *value)
+{
+  u32_t i = instance->reference.u32;
+  s32_t *temperature = (s32_t *)value;
+#if SENSORS_USE_FILES
+  FILE* sensf;
+  char senspath[sizeof(SENSORS_DIR)+1+SENSOR_NAME_LEN+1] = SENSORS_DIR"/";
+
+  strncpy(&senspath[sizeof(SENSORS_DIR)],
+          sensors[i].file,
+          SENSOR_NAME_LEN);
+  sensf = fopen(senspath, "w");
+  if (sensf != NULL)
+  {
+    fprintf(sensf, "%"S32_F, *temperature);
+    fclose(sensf);
+  }
+#else /* SENSORS_USE_FILES */
+  sensors[i].value = *temperature;
+#endif /* SENSORS_USE_FILES */  
+
+  LWIP_UNUSED_ARG(len);
+
+  return SNMP_ERR_NOERROR;
+}
+
+#endif /* LWIP_SNMP */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/examples/snmp/snmp_private_mib/private_mib.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/examples/snmp/snmp_private_mib/private_mib.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/examples/snmp/snmp_private_mib/private_mib.h	(revision 457)
@@ -0,0 +1,26 @@
+/**
+ * @file
+ * Exports Private lwIP MIB 
+ */
+
+#ifndef LWIP_HDR_PRIVATE_MIB_H
+#define LWIP_HDR_PRIVATE_MIB_H
+
+#include "lwip/apps/snmp_opts.h"
+
+#include "lwip/apps/snmp_core.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* export MIB */
+extern const struct snmp_mib mib_private;
+
+void lwip_privmib_init(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/examples/snmp/snmp_v3/snmpv3_dummy.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/examples/snmp/snmp_v3/snmpv3_dummy.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/examples/snmp/snmp_v3/snmpv3_dummy.c	(revision 457)
@@ -0,0 +1,395 @@
+/**
+ * @file
+ * Dummy SNMPv3 functions.
+ */
+
+/*
+ * Copyright (c) 2016 Elias Oenal.
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * Author: Elias Oenal <lwip@eliasoenal.com>
+ *         Dirk Ziegelmeier <dirk@ziegelmeier.net>
+ */
+
+#include "lwip/apps/snmpv3.h"
+#include "snmpv3_dummy.h"
+#include <string.h>
+#include "lwip/err.h"
+#include "lwip/def.h"
+#include "lwip/timeouts.h"
+
+#if LWIP_SNMP && LWIP_SNMP_V3
+
+struct user_table_entry {
+  char               username[32];
+  snmpv3_auth_algo_t auth_algo;
+  u8_t               auth_key[20];
+  snmpv3_priv_algo_t priv_algo;
+  u8_t               priv_key[20];
+};
+
+static struct user_table_entry user_table[] = {
+  { "lwip", SNMP_V3_AUTH_ALGO_INVAL, "" , SNMP_V3_PRIV_ALGO_INVAL, "" },
+  { "piwl", SNMP_V3_AUTH_ALGO_INVAL, "" , SNMP_V3_PRIV_ALGO_INVAL, "" },
+  { "test", SNMP_V3_AUTH_ALGO_INVAL, "" , SNMP_V3_PRIV_ALGO_INVAL, "" }
+};
+
+static char snmpv3_engineid[32];
+static u8_t snmpv3_engineid_len;
+
+static u32_t enginetime = 0;
+
+/* In this implementation engineboots is volatile. In a real world application this value should be stored in non-volatile memory.*/
+static u32_t engineboots = 0;
+
+/**
+ * @brief   Get the user table entry for the given username.
+ *
+ * @param[in] username  pointer to the username
+ *
+ * @return              pointer to the user table entry or NULL if not found.
+ */
+static struct user_table_entry*
+get_user(const char *username)
+{
+  size_t i;
+
+  for (i = 0; i < LWIP_ARRAYSIZE(user_table); i++) {
+    if (strnlen(username, 32) != strnlen(user_table[i].username, 32)) {
+      continue;
+    }
+
+    if (memcmp(username, user_table[i].username, strnlen(username, 32)) == 0) {
+      return &user_table[i];
+    }
+  }
+
+  return NULL;
+}
+
+u8_t
+snmpv3_get_amount_of_users(void)
+{
+  return LWIP_ARRAYSIZE(user_table);
+}
+
+/**
+ * @brief Get the username of a user number (index)
+ * @param username is a pointer to a string.
+ * @param index is the user index.
+ * @return ERR_OK if user is found, ERR_VAL is user is not found.
+ */
+err_t
+snmpv3_get_username(char *username, u8_t index)
+{
+  if (index < LWIP_ARRAYSIZE(user_table)) {
+    MEMCPY(username, user_table[index].username, sizeof(user_table[0].username));
+    return ERR_OK;
+  }
+
+  return ERR_VAL;
+}
+
+/**
+ * Timer callback function that increments enginetime and reschedules itself.
+ *
+ * @param arg unused argument
+ */
+static void
+snmpv3_enginetime_timer(void *arg)
+{
+  LWIP_UNUSED_ARG(arg);
+  
+  enginetime++;
+
+  /* This handles the engine time reset */
+  snmpv3_get_engine_time_internal();
+
+  /* restart timer */
+  sys_timeout(1000, snmpv3_enginetime_timer, NULL);
+}
+
+err_t
+snmpv3_set_user_auth_algo(const char *username, snmpv3_auth_algo_t algo)
+{
+  struct user_table_entry *p = get_user(username);
+
+  if (p) {
+    switch (algo) {
+    case SNMP_V3_AUTH_ALGO_INVAL:
+      if (p->priv_algo != SNMP_V3_PRIV_ALGO_INVAL) {
+        /* Privacy MUST be disabled before configuring authentication */
+        break;
+      } else {
+        p->auth_algo = algo;
+        return ERR_OK;
+      }
+#if LWIP_SNMP_V3_CRYPTO
+    case SNMP_V3_AUTH_ALGO_MD5:
+    case SNMP_V3_AUTH_ALGO_SHA:
+#endif
+      p->auth_algo = algo;
+      return ERR_OK;
+    default:
+      break;
+    }
+  }
+
+  return ERR_VAL;
+}
+
+err_t
+snmpv3_set_user_priv_algo(const char *username, snmpv3_priv_algo_t algo)
+{
+  struct user_table_entry *p = get_user(username);
+
+  if (p) {
+    switch (algo) {
+#if LWIP_SNMP_V3_CRYPTO
+    case SNMP_V3_PRIV_ALGO_AES:
+    case SNMP_V3_PRIV_ALGO_DES:
+      if (p->auth_algo == SNMP_V3_AUTH_ALGO_INVAL) {
+        /* Authentication MUST be enabled before configuring privacy */
+        break;
+      } else {
+        p->priv_algo = algo;
+        return ERR_OK;
+      }
+#endif
+    case SNMP_V3_PRIV_ALGO_INVAL:
+      p->priv_algo = algo;
+      return ERR_OK;
+    default:
+      break;
+    }
+  }
+
+  return ERR_VAL;
+}
+
+err_t
+snmpv3_set_user_auth_key(const char *username, const char *password)
+{
+  struct user_table_entry *p = get_user(username);
+  const char *engineid;
+  u8_t engineid_len;
+
+  if (p) {
+    /* password should be at least 8 characters long */
+    if (strlen(password) >= 8) {
+      memset(p->auth_key, 0, sizeof(p->auth_key));
+      snmpv3_get_engine_id(&engineid, &engineid_len);
+      switch (p->auth_algo) {
+      case SNMP_V3_AUTH_ALGO_INVAL:
+        return ERR_OK;
+#if LWIP_SNMP_V3_CRYPTO
+      case SNMP_V3_AUTH_ALGO_MD5:
+        snmpv3_password_to_key_md5((const u8_t*)password, strlen(password), (const u8_t*)engineid, engineid_len, p->auth_key);
+        return ERR_OK;
+      case SNMP_V3_AUTH_ALGO_SHA:
+        snmpv3_password_to_key_sha((const u8_t*)password, strlen(password), (const u8_t*)engineid, engineid_len, p->auth_key);
+        return ERR_OK;
+#endif
+      default:
+        return ERR_VAL;
+      }
+    }
+  }
+
+  return ERR_VAL;
+}
+
+err_t
+snmpv3_set_user_priv_key(const char *username, const char *password)
+{
+  struct user_table_entry *p = get_user(username);
+  const char *engineid;
+  u8_t engineid_len;
+
+  if (p) {
+    /* password should be at least 8 characters long */
+    if (strlen(password) >= 8) {
+      memset(p->priv_key, 0, sizeof(p->priv_key));
+      snmpv3_get_engine_id(&engineid, &engineid_len);
+      switch (p->auth_algo) {
+      case SNMP_V3_AUTH_ALGO_INVAL:
+        return ERR_OK;
+#if LWIP_SNMP_V3_CRYPTO
+      case SNMP_V3_AUTH_ALGO_MD5:
+        snmpv3_password_to_key_md5((const u8_t*)password, strlen(password), (const u8_t*)engineid, engineid_len, p->priv_key);
+        return ERR_OK;
+      case SNMP_V3_AUTH_ALGO_SHA:
+        snmpv3_password_to_key_sha((const u8_t*)password, strlen(password), (const u8_t*)engineid, engineid_len, p->priv_key);
+        return ERR_OK;
+#endif
+      default:
+        return ERR_VAL;
+      }
+    }
+  }
+
+  return ERR_VAL;
+}
+
+/**
+ * @brief   Get the storage type of the given username.
+ *
+ * @param[in] username  pointer to the username
+ * @param[out] type     the storage type
+ *
+ * @return              ERR_OK if the user was found, ERR_VAL if not.
+ */
+err_t
+snmpv3_get_user_storagetype(const char *username, snmpv3_user_storagetype_t *type)
+{
+  if (get_user(username) != NULL) {
+    /* Found user in user table
+     * In this dummy implementation, storage is permanent because no user can be deleted.
+     * All changes to users are lost after a reboot.*/
+    *type = SNMP_V3_USER_STORAGETYPE_PERMANENT;
+    return ERR_OK;
+  }
+
+  return ERR_VAL;
+}
+
+/**
+ *  @param username is a pointer to a string.
+ * @param auth_algo is a pointer to u8_t. The implementation has to set this if user was found.
+ * @param auth_key is a pointer to a pointer to a string. Implementation has to set this if user was found.
+ * @param priv_algo is a pointer to u8_t. The implementation has to set this if user was found.
+ * @param priv_key is a pointer to a pointer to a string. Implementation has to set this if user was found.
+ */
+err_t
+snmpv3_get_user(const char* username, snmpv3_auth_algo_t *auth_algo, u8_t *auth_key, snmpv3_priv_algo_t *priv_algo, u8_t *priv_key)
+{
+  const struct user_table_entry *p;
+  
+  /* The msgUserName specifies the user (principal) on whose behalf the
+     message is being exchanged. Note that a zero-length userName will
+     not match any user, but it can be used for snmpEngineID discovery. */
+  if(strlen(username) == 0) {
+    return ERR_OK;
+  }
+  
+  p = get_user(username);
+
+  if (!p) {
+    return ERR_VAL;
+  }
+  
+  if (auth_algo != NULL) {
+    *auth_algo = p->auth_algo;
+  }
+  if(auth_key != NULL) {
+    MEMCPY(auth_key, p->auth_key, sizeof(p->auth_key));
+  }
+  if (priv_algo != NULL) {
+    *priv_algo = p->priv_algo;
+  }
+  if(priv_key != NULL) {
+    MEMCPY(priv_key, p->priv_key, sizeof(p->priv_key));
+  }
+  return ERR_OK;
+}
+
+/**
+ * Get engine ID from persistence
+ */
+void
+snmpv3_get_engine_id(const char **id, u8_t *len)
+{
+  *id = snmpv3_engineid;
+  *len = snmpv3_engineid_len;
+}
+
+/**
+ * Store engine ID in persistence
+ */
+err_t
+snmpv3_set_engine_id(const char *id, u8_t len)
+{
+  MEMCPY(snmpv3_engineid, id, len);
+  snmpv3_engineid_len = len;
+  return ERR_OK;
+}
+
+/**
+ * Get engine boots from persistence. Must be increased on each boot.
+ */
+u32_t
+snmpv3_get_engine_boots(void)
+{
+  return engineboots;
+}
+
+/**
+ * Store engine boots in persistence
+ */
+void 
+snmpv3_set_engine_boots(u32_t boots)
+{
+  engineboots = boots;
+}
+
+/**
+ * RFC3414 2.2.2.
+ * Once the timer reaches 2147483647 it gets reset to zero and the
+ * engine boot ups get incremented.
+ */
+u32_t
+snmpv3_get_engine_time(void)
+{
+  return enginetime;
+}
+
+/**
+ * Reset current engine time to 0
+ */
+void
+snmpv3_reset_engine_time(void)
+{
+  enginetime = 0;
+}
+
+/**
+ * Initialize dummy SNMPv3 implementation
+ */
+void
+snmpv3_dummy_init(void)
+{
+  snmpv3_set_engine_id("FOO", 3);
+
+  snmpv3_set_user_auth_algo("lwip", SNMP_V3_AUTH_ALGO_SHA);
+  snmpv3_set_user_auth_key("lwip", "maplesyrup");
+
+  snmpv3_set_user_priv_algo("lwip", SNMP_V3_PRIV_ALGO_DES);
+  snmpv3_set_user_priv_key("lwip", "maplesyrup");
+
+  /* Start the engine time timer */
+  snmpv3_enginetime_timer(NULL);
+}
+
+#endif /* LWIP_SNMP && LWIP_SNMP_V3 */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/examples/snmp/snmp_v3/snmpv3_dummy.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/examples/snmp/snmp_v3/snmpv3_dummy.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/examples/snmp/snmp_v3/snmpv3_dummy.h	(revision 457)
@@ -0,0 +1,53 @@
+/**
+ * @file
+ * Dummy SNMPv3 functions.
+ */
+
+/*
+ * Copyright (c) 2017 Dirk Ziegelmeier.
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * Author: Dirk Ziegelmeier <dziegel@gmx.de>
+ */
+
+#ifndef LWIP_HDR_APPS_SNMP_V3_DUMMY_H
+#define LWIP_HDR_APPS_SNMP_V3_DUMMY_H
+
+#include "lwip/apps/snmp_opts.h"
+#include "lwip/err.h"
+#include "lwip/apps/snmpv3.h"
+
+#if LWIP_SNMP && LWIP_SNMP_V3
+
+err_t snmpv3_set_user_auth_algo(const char *username, snmpv3_auth_algo_t algo);
+err_t snmpv3_set_user_priv_algo(const char *username, snmpv3_priv_algo_t algo);
+err_t snmpv3_set_user_auth_key(const char *username, const char *password);
+err_t snmpv3_set_user_priv_key(const char *username, const char *password);
+
+void snmpv3_dummy_init(void);
+
+#endif /* LWIP_SNMP && LWIP_SNMP_V3 */
+
+#endif /* LWIP_HDR_APPS_SNMP_V3_DUMMY_H */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/examples/sntp/sntp_example.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/examples/sntp/sntp_example.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/examples/sntp/sntp_example.c	(revision 457)
@@ -0,0 +1,66 @@
+/*
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission. 
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ * 
+ * Author: Dirk Ziegelmeier <dziegel@gmx.de>
+ *
+ */
+
+#include <time.h>
+
+#include "lwip/opt.h"
+#include "lwip/apps/sntp.h"
+#include "sntp_example.h"
+#include "lwip/netif.h"
+
+void
+sntp_set_system_time(u32_t sec)
+{
+  char buf[32];
+  struct tm current_time_val;
+  time_t current_time = (time_t)sec;
+
+#ifdef _MSC_VER
+  localtime_s(&current_time_val, &current_time);
+#else
+  localtime_r(&current_time, &current_time_val);
+#endif
+  
+  strftime(buf, sizeof(buf), "%d.%m.%Y %H:%M:%S", &current_time_val);
+  printf("SNTP time: %s\n", buf);
+}
+
+void
+sntp_example_init(void)
+{
+  sntp_setoperatingmode(SNTP_OPMODE_POLL);
+#if LWIP_DHCP
+  sntp_servermode_dhcp(1); /* get SNTP server via DHCP */
+#else /* LWIP_DHCP */
+#if LWIP_IPV4
+  sntp_setserver(0, netif_ip_gw4(netif_default));
+#endif /* LWIP_IPV4 */
+#endif /* LWIP_DHCP */
+  sntp_init();
+}
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/examples/sntp/sntp_example.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/examples/sntp/sntp_example.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/examples/sntp/sntp_example.h	(revision 457)
@@ -0,0 +1,45 @@
+/*
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission. 
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ * 
+ * Author: Dirk Ziegelmeier <dziegel@gmx.de>
+ *
+ */
+
+#ifndef SNTP_EXAMPLE_H
+#define SNTP_EXAMPLE_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void sntp_example_init(void);
+
+void sntp_set_system_time(u32_t sec);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* SNTP_EXAMPLE_H */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/examples/tftp/tftp_example.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/examples/tftp/tftp_example.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/examples/tftp/tftp_example.c	(revision 457)
@@ -0,0 +1,91 @@
+/*
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission. 
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ * 
+ * Author: Dirk Ziegelmeier <dziegel@gmx.de>
+ *
+ */
+
+#include <stdio.h>
+
+#include "lwip/apps/tftp_server.h"
+#include "tftp_example.h"
+
+#if LWIP_UDP
+
+static void*
+tftp_open(const char* fname, const char* mode, u8_t is_write)
+{
+  LWIP_UNUSED_ARG(mode);
+  
+  if (is_write) {
+    return (void*)fopen(fname, "wb");
+  } else {
+    return (void*)fopen(fname, "rb");
+  }
+}
+
+static void 
+tftp_close(void* handle)
+{
+  fclose((FILE*)handle);
+}
+
+static int
+tftp_read(void* handle, void* buf, int bytes)
+{
+  int ret = fread(buf, 1, bytes, (FILE*)handle);
+  if (ret <= 0) {
+    return -1;
+  }
+  return ret;
+}
+
+static int
+tftp_write(void* handle, struct pbuf* p)
+{
+  while (p != NULL) {
+    if (fwrite(p->payload, 1, p->len, (FILE*)handle) != (size_t)p->len) {
+      return -1;
+    }
+    p = p->next;
+  }
+  
+  return 0;
+}
+
+static const struct tftp_context tftp = {
+  tftp_open,
+  tftp_close,
+  tftp_read,
+  tftp_write
+};
+
+void
+tftp_example_init(void)
+{
+  tftp_init(&tftp);
+}
+
+#endif /* LWIP_UDP */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/examples/tftp/tftp_example.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/examples/tftp/tftp_example.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/examples/tftp/tftp_example.h	(revision 457)
@@ -0,0 +1,28 @@
+/*
+ * To change this license header, choose License Headers in Project Properties.
+ * To change this template file, choose Tools | Templates
+ * and open the template in the editor.
+ */
+
+/* 
+ * File:   tftp_example.h
+ * Author: dziegel
+ *
+ * Created on February 17, 2018, 3:43 PM
+ */
+
+#ifndef TFTP_EXAMPLE_H
+#define TFTP_EXAMPLE_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void tftp_example_init(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* TFTP_EXAMPLE_H */
+
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/ports/CMakeCommon.cmake
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/ports/CMakeCommon.cmake	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/ports/CMakeCommon.cmake	(revision 457)
@@ -0,0 +1,105 @@
+# ARM mbedtls support https://tls.mbed.org/
+set(MBEDTLSDIR ${LWIP_CONTRIB_DIR}/../mbedtls)
+if(EXISTS ${MBEDTLSDIR}/CMakeLists.txt)
+    set(LWIP_HAVE_MBEDTLS ON BOOL)
+
+    # Prevent building MBEDTLS programs and tests
+    set(ENABLE_PROGRAMS OFF CACHE BOOL "")
+    set(ENABLE_TESTING  OFF CACHE BOOL "")
+    
+    # mbedtls uses cmake. Sweet!
+    add_subdirectory(${MBEDTLSDIR} mbedtls)
+
+    set (LWIP_MBEDTLS_DEFINITIONS
+        -DLWIP_HAVE_MBEDTLS=1
+    )
+    set (LWIP_MBEDTLS_INCLUDE_DIRS
+        ${MBEDTLSDIR}/include
+    )
+    set (LWIP_MBEDTLS_LINK_LIBRARIES
+        mbedtls
+        mbedcrypto
+        mbedx509
+    )
+endif()
+
+set(LWIP_COMPILER_FLAGS_GNU_CLANG
+    -g
+    -Wall
+    -pedantic
+    -Werror
+    -Wparentheses
+    -Wsequence-point
+    -Wswitch-default
+    -Wextra -Wundef
+    -Wshadow
+    -Wpointer-arith
+    -Wcast-qual
+    -Wc++-compat
+    -Wwrite-strings
+    -Wold-style-definition
+    -Wcast-align
+    -Wmissing-prototypes
+    -Wnested-externs
+    -Wunreachable-code
+    -Wuninitialized
+    -Wmissing-prototypes
+    -Waggregate-return
+    -Wlogical-not-parentheses
+)
+
+if (NOT LWIP_HAVE_MBEDTLS)
+    list(APPEND LWIP_COMPILER_FLAGS_GNU_CLANG
+        -Wredundant-decls
+    )
+endif()
+
+if(CMAKE_C_COMPILER_ID STREQUAL GNU)
+    list(APPEND LWIP_COMPILER_FLAGS_GNU_CLANG
+        -Wlogical-op
+        -Wtrampolines
+    )
+
+    if (NOT LWIP_HAVE_MBEDTLS)
+        list(APPEND LWIP_COMPILER_FLAGS_GNU_CLANG
+            -Wc90-c99-compat
+        )
+    endif()
+
+    if(NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 4.9)
+        if(LWIP_USE_SANITIZERS)
+            list(APPEND LWIP_COMPILER_FLAGS_GNU_CLANG
+                -fsanitize=address
+                -fsanitize=undefined
+                -fno-sanitize=alignment
+                -fstack-protector
+                -fstack-check
+            )
+            set(LWIP_SANITIZER_LIBS asan ubsan)
+        endif()
+    endif()
+
+    set(LWIP_COMPILER_FLAGS ${LWIP_COMPILER_FLAGS_GNU_CLANG})
+endif()
+
+if(CMAKE_C_COMPILER_ID STREQUAL Clang)
+    list(APPEND LWIP_COMPILER_FLAGS_GNU_CLANG
+        -Wdocumentation
+        -Wno-documentation-deprecated-sync
+    )
+
+    if(LWIP_USE_SANITIZERS)
+        list(APPEND LWIP_COMPILER_FLAGS_GNU_CLANG
+            -fsanitize=address
+            -fsanitize=undefined
+            -fno-sanitize=alignment
+        )
+        set(LWIP_SANITIZER_LIBS asan ubsan)
+    endif()
+
+    set(LWIP_COMPILER_FLAGS ${LWIP_COMPILER_FLAGS_GNU_CLANG})
+endif()
+
+if(CMAKE_C_COMPILER_ID STREQUAL MSVC)
+    # TODO
+endif()
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/ports/Common.allports.mk
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/ports/Common.allports.mk	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/ports/Common.allports.mk	(revision 457)
@@ -0,0 +1,91 @@
+#
+# Copyright (c) 2001, 2002 Swedish Institute of Computer Science.
+# 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. The name of the author may not be used to endorse or promote products
+#    derived from this software without specific prior written permission. 
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+#
+# This file is part of the lwIP TCP/IP stack.
+# 
+# Author: Adam Dunkels <adam@sics.se>
+#
+
+#CC=gcc
+#CC=clang
+CCDEP?=$(CC)
+
+CFLAGS+=-g -DLWIP_DEBUG -Wall -pedantic -Werror \
+	-Wparentheses -Wsequence-point -Wswitch-default \
+	-Wextra -Wundef -Wshadow -Wpointer-arith -Wcast-qual \
+	-Wc++-compat -Wwrite-strings -Wold-style-definition -Wcast-align \
+	-Wmissing-prototypes -Wredundant-decls -Wnested-externs \
+	-Wunreachable-code -Wuninitialized -Wmissing-prototypes \
+	-Wredundant-decls -Waggregate-return -Wlogical-not-parentheses
+#	-Wconversion -Wsign-compare -Wmissing-include-dirs
+
+ifeq (,$(findstring clang,$(CC)))
+CFLAGS+= -Wlogical-op -Wc90-c99-compat -Wtrampolines
+# if GCC is newer than 4.8/4.9 you may use:
+#CFLAGS:=$(CFLAGS) -fsanitize=address -fstack-protector -fstack-check -fsanitize=undefined -fno-sanitize=alignment
+else
+# we cannot sanitize alignment on x86-64 targets because clang wants 64 bit alignment
+CFLAGS+= -fsanitize=address -fsanitize=undefined -fno-sanitize=alignment -Wdocumentation -Wno-documentation-deprecated-sync
+endif
+
+CONTRIBDIR?=../../..
+ARFLAGS?=rs
+
+#Set this to where you have the lwip core module checked out from git
+#default assumes it's a dir named lwip at the same level as the contrib module
+LWIPDIR?=$(CONTRIBDIR)/../lwip/src
+
+CFLAGS+=-I. \
+	-I$(CONTRIBDIR) \
+	-I$(LWIPDIR)/include \
+	-I$(LWIPARCH)/include
+
+# Add include path and link to mbedTLS lib if available
+MBEDTLSDIR?=$(CONTRIBDIR)/../mbedtls
+ifneq (,$(wildcard $(MBEDTLSDIR)/include/mbedtls/*.h))
+LDFLAGS+=-L$(MBEDTLSDIR)/library -lmbedtls -lmbedcrypto -lmbedx509
+CFLAGS+=-I$(MBEDTLSDIR)/include -Wno-redundant-decls -DLWIP_HAVE_MBEDTLS=1 -Wno-c90-c99-compat
+endif
+
+include $(CONTRIBDIR)/Filelists.mk
+include $(LWIPDIR)/Filelists.mk
+
+# LWIPFILES: All the above.
+LWIPFILES=$(LWIPNOAPPSFILES) $(ARCHFILES)
+LWIPOBJS=$(notdir $(LWIPFILES:.c=.o))
+
+LWIPLIBCOMMON=liblwipcommon.a
+$(LWIPLIBCOMMON): $(LWIPOBJS)
+	$(AR) $(ARFLAGS) $(LWIPLIBCOMMON) $?
+
+APPFILES=$(CONTRIBAPPFILES) $(LWIPAPPFILES)
+APPLIB=liblwipapps.a
+APPOBJS=$(notdir $(APPFILES:.c=.o))
+$(APPLIB): $(APPOBJS)
+	$(AR) $(ARFLAGS) $(APPLIB) $?
+
+%.o:
+	$(CC) $(CFLAGS) -c $<
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/ports/FILES
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/ports/FILES	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/ports/FILES	(revision 457)
@@ -0,0 +1,8 @@
+unix/      - Architectural files for testing on unix-like systems
+             (assuming gcc and pthreads).
+           - Maintained by Kieran Mansley <kieran@recoil.org>
+
+msvc6/     - Architectural files for Microsoft Visual C++ 6.0.
+           - Maintained by Simon Goldschmidt <sgoldschmidt@de.pepperl-fuchs.com>
+
+old/       - Ports that are no longer actively maintained
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/ports/freertos/include/arch/sys_arch.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/ports/freertos/include/arch/sys_arch.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/ports/freertos/include/arch/sys_arch.h	(revision 457)
@@ -0,0 +1,95 @@
+/*
+ * Copyright (c) 2017 Simon Goldschmidt
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Simon Goldschmdit <goldsimon@gmx.de>
+ *
+ */
+#ifndef LWIP_ARCH_SYS_ARCH_H
+#define LWIP_ARCH_SYS_ARCH_H
+
+#include "lwip/opt.h"
+#include "lwip/arch.h"
+
+/** This is returned by _fromisr() sys functions to tell the outermost function
+ * that a higher priority task was woken and the scheduler needs to be invoked.
+ */
+#define ERR_NEED_SCHED 123
+
+/* This port includes FreeRTOS headers in sys_arch.c only.
+ *  FreeRTOS uses pointers as object types. We use wrapper structs instead of
+ * void pointers directly to get a tiny bit of type safety.
+ */
+
+void sys_arch_msleep(u32_t delay_ms);
+#define sys_msleep(ms) sys_arch_msleep(ms)
+
+#if SYS_LIGHTWEIGHT_PROT
+typedef u32_t sys_prot_t;
+#endif /* SYS_LIGHTWEIGHT_PROT */
+
+#if !LWIP_COMPAT_MUTEX
+struct _sys_mut {
+  void *mut;
+};
+typedef struct _sys_mut sys_mutex_t;
+#define sys_mutex_valid_val(mutex)   ((mutex).mut != NULL)
+#define sys_mutex_valid(mutex)       (((mutex) != NULL) && sys_mutex_valid_val(*(mutex)))
+#define sys_mutex_set_invalid(mutex) ((mutex)->mut = NULL)
+#endif /* !LWIP_COMPAT_MUTEX */
+
+struct _sys_sem {
+  void *sem;
+};
+typedef struct _sys_sem sys_sem_t;
+#define sys_sem_valid_val(sema)   ((sema).sem != NULL)
+#define sys_sem_valid(sema)       (((sema) != NULL) && sys_sem_valid_val(*(sema)))
+#define sys_sem_set_invalid(sema) ((sema)->sem = NULL)
+
+struct _sys_mbox {
+  void *mbx;
+};
+typedef struct _sys_mbox sys_mbox_t;
+#define sys_mbox_valid_val(mbox)   ((mbox).mbx != NULL)
+#define sys_mbox_valid(mbox)       (((mbox) != NULL) && sys_mbox_valid_val(*(mbox)))
+#define sys_mbox_set_invalid(mbox) ((mbox)->mbx = NULL)
+
+struct _sys_thread {
+  void *thread_handle;
+};
+typedef struct _sys_thread sys_thread_t;
+
+#if LWIP_NETCONN_SEM_PER_THREAD
+sys_sem_t* sys_arch_netconn_sem_get(void);
+void sys_arch_netconn_sem_alloc(void);
+void sys_arch_netconn_sem_free(void);
+#define LWIP_NETCONN_THREAD_SEM_GET()   sys_arch_netconn_sem_get()
+#define LWIP_NETCONN_THREAD_SEM_ALLOC() sys_arch_netconn_sem_alloc()
+#define LWIP_NETCONN_THREAD_SEM_FREE()  sys_arch_netconn_sem_free()
+#endif /* LWIP_NETCONN_SEM_PER_THREAD */
+
+#endif /* LWIP_ARCH_SYS_ARCH_H */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/ports/freertos/sys_arch.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/ports/freertos/sys_arch.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/ports/freertos/sys_arch.c	(revision 457)
@@ -0,0 +1,609 @@
+/*
+ * Copyright (c) 2017 Simon Goldschmidt
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Simon Goldschmidt <goldsimon@gmx.de>
+ *
+ */
+
+/* lwIP includes. */
+#include "lwip/debug.h"
+#include "lwip/def.h"
+#include "lwip/sys.h"
+#include "lwip/mem.h"
+#include "lwip/stats.h"
+#include "FreeRTOS.h"
+#include "semphr.h"
+#include "task.h"
+
+/** Set this to 1 if you want the stack size passed to sys_thread_new() to be
+ * interpreted as number of stack words (FreeRTOS-like).
+ * Default is that they are interpreted as byte count (lwIP-like).
+ */
+#ifndef LWIP_FREERTOS_THREAD_STACKSIZE_IS_STACKWORDS
+#define LWIP_FREERTOS_THREAD_STACKSIZE_IS_STACKWORDS  0
+#endif
+
+/** Set this to 1 to use a mutex for SYS_ARCH_PROTECT() critical regions.
+ * Default is 0 and locks interrupts/scheduler for SYS_ARCH_PROTECT().
+ */
+#ifndef LWIP_FREERTOS_SYS_ARCH_PROTECT_USES_MUTEX
+#define LWIP_FREERTOS_SYS_ARCH_PROTECT_USES_MUTEX     0
+#endif
+
+/** Set this to 1 to include a sanity check that SYS_ARCH_PROTECT() and
+ * SYS_ARCH_UNPROTECT() are called matching.
+ */
+#ifndef LWIP_FREERTOS_SYS_ARCH_PROTECT_SANITY_CHECK
+#define LWIP_FREERTOS_SYS_ARCH_PROTECT_SANITY_CHECK   0
+#endif
+
+/** Set this to 1 to let sys_mbox_free check that queues are empty when freed */
+#ifndef LWIP_FREERTOS_CHECK_QUEUE_EMPTY_ON_FREE
+#define LWIP_FREERTOS_CHECK_QUEUE_EMPTY_ON_FREE       0
+#endif
+
+/** Set this to 1 to enable core locking check functions in this port.
+ * For this to work, you'll have to define LWIP_ASSERT_CORE_LOCKED()
+ * and LWIP_MARK_TCPIP_THREAD() correctly in your lwipopts.h! */
+#ifndef LWIP_FREERTOS_CHECK_CORE_LOCKING
+#define LWIP_FREERTOS_CHECK_CORE_LOCKING              0
+#endif
+
+/** Set this to 0 to implement sys_now() yourself, e.g. using a hw timer.
+ * Default is 1, where FreeRTOS ticks are used to calculate back to ms.
+ */
+#ifndef LWIP_FREERTOS_SYS_NOW_FROM_FREERTOS
+#define LWIP_FREERTOS_SYS_NOW_FROM_FREERTOS           1
+#endif
+
+#if !configSUPPORT_DYNAMIC_ALLOCATION
+# error "lwIP FreeRTOS port requires configSUPPORT_DYNAMIC_ALLOCATION"
+#endif
+#if !INCLUDE_vTaskDelay
+# error "lwIP FreeRTOS port requires INCLUDE_vTaskDelay"
+#endif
+#if !INCLUDE_vTaskSuspend
+# error "lwIP FreeRTOS port requires INCLUDE_vTaskSuspend"
+#endif
+#if LWIP_FREERTOS_SYS_ARCH_PROTECT_USES_MUTEX || !LWIP_COMPAT_MUTEX
+#if !configUSE_MUTEXES
+# error "lwIP FreeRTOS port requires configUSE_MUTEXES"
+#endif
+#endif
+
+#if SYS_LIGHTWEIGHT_PROT && LWIP_FREERTOS_SYS_ARCH_PROTECT_USES_MUTEX
+static SemaphoreHandle_t sys_arch_protect_mutex;
+#endif
+#if SYS_LIGHTWEIGHT_PROT && LWIP_FREERTOS_SYS_ARCH_PROTECT_SANITY_CHECK
+static sys_prot_t sys_arch_protect_nesting;
+#endif
+
+/* Initialize this module (see description in sys.h) */
+void
+sys_init(void)
+{
+#if SYS_LIGHTWEIGHT_PROT && LWIP_FREERTOS_SYS_ARCH_PROTECT_USES_MUTEX
+  /* initialize sys_arch_protect global mutex */
+  sys_arch_protect_mutex = xSemaphoreCreateRecursiveMutex();
+  LWIP_ASSERT("failed to create sys_arch_protect mutex",
+    sys_arch_protect_mutex != NULL);
+#endif /* SYS_LIGHTWEIGHT_PROT && LWIP_FREERTOS_SYS_ARCH_PROTECT_USES_MUTEX */
+}
+
+#if configUSE_16_BIT_TICKS == 1
+#error This port requires 32 bit ticks or timer overflow will fail
+#endif
+
+#if LWIP_FREERTOS_SYS_NOW_FROM_FREERTOS
+u32_t
+sys_now(void)
+{
+  return xTaskGetTickCount() * portTICK_PERIOD_MS;
+}
+#endif
+
+u32_t
+sys_jiffies(void)
+{
+  return xTaskGetTickCount();
+}
+
+#if SYS_LIGHTWEIGHT_PROT
+
+sys_prot_t
+sys_arch_protect(void)
+{
+#if LWIP_FREERTOS_SYS_ARCH_PROTECT_USES_MUTEX
+  BaseType_t ret;
+  LWIP_ASSERT("sys_arch_protect_mutex != NULL", sys_arch_protect_mutex != NULL);
+
+  ret = xSemaphoreTakeRecursive(sys_arch_protect_mutex, portMAX_DELAY);
+  LWIP_ASSERT("sys_arch_protect failed to take the mutex", ret == pdTRUE);
+#else /* LWIP_FREERTOS_SYS_ARCH_PROTECT_USES_MUTEX */
+  taskENTER_CRITICAL();
+#endif /* LWIP_FREERTOS_SYS_ARCH_PROTECT_USES_MUTEX */
+#if LWIP_FREERTOS_SYS_ARCH_PROTECT_SANITY_CHECK
+  {
+    /* every nested call to sys_arch_protect() returns an increased number */
+    sys_prot_t ret = sys_arch_protect_nesting;
+    sys_arch_protect_nesting++;
+    LWIP_ASSERT("sys_arch_protect overflow", sys_arch_protect_nesting > ret);
+    return ret;
+  }
+#else
+  return 1;
+#endif
+}
+
+void
+sys_arch_unprotect(sys_prot_t pval)
+{
+#if LWIP_FREERTOS_SYS_ARCH_PROTECT_USES_MUTEX
+  BaseType_t ret;
+#endif
+#if LWIP_FREERTOS_SYS_ARCH_PROTECT_SANITY_CHECK
+  LWIP_ASSERT("unexpected sys_arch_protect_nesting", sys_arch_protect_nesting > 0);
+  sys_arch_protect_nesting--;
+  LWIP_ASSERT("unexpected sys_arch_protect_nesting", sys_arch_protect_nesting == pval);
+#endif
+
+#if LWIP_FREERTOS_SYS_ARCH_PROTECT_USES_MUTEX
+  LWIP_ASSERT("sys_arch_protect_mutex != NULL", sys_arch_protect_mutex != NULL);
+
+  ret = xSemaphoreGiveRecursive(sys_arch_protect_mutex);
+  LWIP_ASSERT("sys_arch_unprotect failed to give the mutex", ret == pdTRUE);
+#else /* LWIP_FREERTOS_SYS_ARCH_PROTECT_USES_MUTEX */
+  taskEXIT_CRITICAL();
+#endif /* LWIP_FREERTOS_SYS_ARCH_PROTECT_USES_MUTEX */
+  LWIP_UNUSED_ARG(pval);
+}
+
+#endif /* SYS_LIGHTWEIGHT_PROT */
+
+void
+sys_arch_msleep(u32_t delay_ms)
+{
+  TickType_t delay_ticks = delay_ms / portTICK_RATE_MS;
+  vTaskDelay(delay_ticks);
+}
+
+#if !LWIP_COMPAT_MUTEX
+
+/* Create a new mutex*/
+err_t
+sys_mutex_new(sys_mutex_t *mutex)
+{
+  LWIP_ASSERT("mutex != NULL", mutex != NULL);
+
+  mutex->mut = xSemaphoreCreateRecursiveMutex();
+  if(mutex->mut == NULL) {
+    SYS_STATS_INC(mutex.err);
+    return ERR_MEM;
+  }
+  SYS_STATS_INC_USED(mutex);
+  return ERR_OK;
+}
+
+void
+sys_mutex_lock(sys_mutex_t *mutex)
+{
+  BaseType_t ret;
+  LWIP_ASSERT("mutex != NULL", mutex != NULL);
+  LWIP_ASSERT("mutex->mut != NULL", mutex->mut != NULL);
+
+  ret = xSemaphoreTakeRecursive(mutex->mut, portMAX_DELAY);
+  LWIP_ASSERT("failed to take the mutex", ret == pdTRUE);
+}
+
+void
+sys_mutex_unlock(sys_mutex_t *mutex)
+{
+  BaseType_t ret;
+  LWIP_ASSERT("mutex != NULL", mutex != NULL);
+  LWIP_ASSERT("mutex->mut != NULL", mutex->mut != NULL);
+
+  ret = xSemaphoreGiveRecursive(mutex->mut);
+  LWIP_ASSERT("failed to give the mutex", ret == pdTRUE);
+}
+
+void
+sys_mutex_free(sys_mutex_t *mutex)
+{
+  LWIP_ASSERT("mutex != NULL", mutex != NULL);
+  LWIP_ASSERT("mutex->mut != NULL", mutex->mut != NULL);
+
+  SYS_STATS_DEC(mutex.used);
+  vSemaphoreDelete(mutex->mut);
+  mutex->mut = NULL;
+}
+
+#endif /* !LWIP_COMPAT_MUTEX */
+
+err_t
+sys_sem_new(sys_sem_t *sem, u8_t initial_count)
+{
+  LWIP_ASSERT("sem != NULL", sem != NULL);
+  LWIP_ASSERT("initial_count invalid (not 0 or 1)",
+    (initial_count == 0) || (initial_count == 1));
+
+  sem->sem = xSemaphoreCreateBinary();
+  if(sem->sem == NULL) {
+    SYS_STATS_INC(sem.err);
+    return ERR_MEM;
+  }
+  SYS_STATS_INC_USED(sem);
+
+  if(initial_count == 1) {
+    BaseType_t ret = xSemaphoreGive(sem->sem);
+    LWIP_ASSERT("sys_sem_new: initial give failed", ret == pdTRUE);
+  }
+  return ERR_OK;
+}
+
+void
+sys_sem_signal(sys_sem_t *sem)
+{
+  BaseType_t ret;
+  LWIP_ASSERT("sem != NULL", sem != NULL);
+  LWIP_ASSERT("sem->sem != NULL", sem->sem != NULL);
+
+  ret = xSemaphoreGive(sem->sem);
+  /* queue full is OK, this is a signal only... */
+  LWIP_ASSERT("sys_sem_signal: sane return value",
+    (ret == pdTRUE) || (ret == errQUEUE_FULL));
+}
+
+u32_t
+sys_arch_sem_wait(sys_sem_t *sem, u32_t timeout_ms)
+{
+  BaseType_t ret;
+  LWIP_ASSERT("sem != NULL", sem != NULL);
+  LWIP_ASSERT("sem->sem != NULL", sem->sem != NULL);
+
+  if(!timeout_ms) {
+    /* wait infinite */
+    ret = xSemaphoreTake(sem->sem, portMAX_DELAY);
+    LWIP_ASSERT("taking semaphore failed", ret == pdTRUE);
+  } else {
+    TickType_t timeout_ticks = timeout_ms / portTICK_RATE_MS;
+    ret = xSemaphoreTake(sem->sem, timeout_ticks);
+    if (ret == errQUEUE_EMPTY) {
+      /* timed out */
+      return SYS_ARCH_TIMEOUT;
+    }
+    LWIP_ASSERT("taking semaphore failed", ret == pdTRUE);
+  }
+
+  /* Old versions of lwIP required us to return the time waited.
+     This is not the case any more. Just returning != SYS_ARCH_TIMEOUT
+     here is enough. */
+  return 1;
+}
+
+void
+sys_sem_free(sys_sem_t *sem)
+{
+  LWIP_ASSERT("sem != NULL", sem != NULL);
+  LWIP_ASSERT("sem->sem != NULL", sem->sem != NULL);
+
+  SYS_STATS_DEC(sem.used);
+  vSemaphoreDelete(sem->sem);
+  sem->sem = NULL;
+}
+
+err_t
+sys_mbox_new(sys_mbox_t *mbox, int size)
+{
+  LWIP_ASSERT("mbox != NULL", mbox != NULL);
+  LWIP_ASSERT("size > 0", size > 0);
+
+  mbox->mbx = xQueueCreate((UBaseType_t)size, sizeof(void *));
+  if(mbox->mbx == NULL) {
+    SYS_STATS_INC(mbox.err);
+    return ERR_MEM;
+  }
+  SYS_STATS_INC_USED(mbox);
+  return ERR_OK;
+}
+
+void
+sys_mbox_post(sys_mbox_t *mbox, void *msg)
+{
+  BaseType_t ret;
+  LWIP_ASSERT("mbox != NULL", mbox != NULL);
+  LWIP_ASSERT("mbox->mbx != NULL", mbox->mbx != NULL);
+
+  ret = xQueueSendToBack(mbox->mbx, &msg, portMAX_DELAY);
+  LWIP_ASSERT("mbox post failed", ret == pdTRUE);
+}
+
+err_t
+sys_mbox_trypost(sys_mbox_t *mbox, void *msg)
+{
+  BaseType_t ret;
+  LWIP_ASSERT("mbox != NULL", mbox != NULL);
+  LWIP_ASSERT("mbox->mbx != NULL", mbox->mbx != NULL);
+
+  ret = xQueueSendToBack(mbox->mbx, &msg, 0);
+  if (ret == pdTRUE) {
+    return ERR_OK;
+  } else {
+    LWIP_ASSERT("mbox trypost failed", ret == errQUEUE_FULL);
+    SYS_STATS_INC(mbox.err);
+    return ERR_MEM;
+  }
+}
+
+err_t
+sys_mbox_trypost_fromisr(sys_mbox_t *mbox, void *msg)
+{
+  BaseType_t ret;
+  BaseType_t xHigherPriorityTaskWoken = pdFALSE;
+  LWIP_ASSERT("mbox != NULL", mbox != NULL);
+  LWIP_ASSERT("mbox->mbx != NULL", mbox->mbx != NULL);
+
+  ret = xQueueSendToBackFromISR(mbox->mbx, &msg, &xHigherPriorityTaskWoken);
+  if (ret == pdTRUE) {
+    if (xHigherPriorityTaskWoken == pdTRUE) {
+      return ERR_NEED_SCHED;
+    }
+    return ERR_OK;
+  } else {
+    LWIP_ASSERT("mbox trypost failed", ret == errQUEUE_FULL);
+    SYS_STATS_INC(mbox.err);
+    return ERR_MEM;
+  }
+}
+
+u32_t
+sys_arch_mbox_fetch(sys_mbox_t *mbox, void **msg, u32_t timeout_ms)
+{
+  BaseType_t ret;
+  void *msg_dummy;
+  LWIP_ASSERT("mbox != NULL", mbox != NULL);
+  LWIP_ASSERT("mbox->mbx != NULL", mbox->mbx != NULL);
+
+  if (!msg) {
+    msg = &msg_dummy;
+  }
+
+  if (!timeout_ms) {
+    /* wait infinite */
+    ret = xQueueReceive(mbox->mbx, &(*msg), portMAX_DELAY);
+    LWIP_ASSERT("mbox fetch failed", ret == pdTRUE);
+  } else {
+    TickType_t timeout_ticks = timeout_ms / portTICK_RATE_MS;
+    ret = xQueueReceive(mbox->mbx, &(*msg), timeout_ticks);
+    if (ret == errQUEUE_EMPTY) {
+      /* timed out */
+      *msg = NULL;
+      return SYS_ARCH_TIMEOUT;
+    }
+    LWIP_ASSERT("mbox fetch failed", ret == pdTRUE);
+  }
+
+  /* Old versions of lwIP required us to return the time waited.
+     This is not the case any more. Just returning != SYS_ARCH_TIMEOUT
+     here is enough. */
+  return 1;
+}
+
+u32_t
+sys_arch_mbox_tryfetch(sys_mbox_t *mbox, void **msg)
+{
+  BaseType_t ret;
+  void *msg_dummy;
+  LWIP_ASSERT("mbox != NULL", mbox != NULL);
+  LWIP_ASSERT("mbox->mbx != NULL", mbox->mbx != NULL);
+
+  if (!msg) {
+    msg = &msg_dummy;
+  }
+
+  ret = xQueueReceive(mbox->mbx, &(*msg), 0);
+  if (ret == errQUEUE_EMPTY) {
+    *msg = NULL;
+    return SYS_MBOX_EMPTY;
+  }
+  LWIP_ASSERT("mbox fetch failed", ret == pdTRUE);
+
+  /* Old versions of lwIP required us to return the time waited.
+     This is not the case any more. Just returning != SYS_ARCH_TIMEOUT
+     here is enough. */
+  return 1;
+}
+
+void
+sys_mbox_free(sys_mbox_t *mbox)
+{
+  LWIP_ASSERT("mbox != NULL", mbox != NULL);
+  LWIP_ASSERT("mbox->mbx != NULL", mbox->mbx != NULL);
+
+#if LWIP_FREERTOS_CHECK_QUEUE_EMPTY_ON_FREE
+  {
+    UBaseType_t msgs_waiting = uxQueueMessagesWaiting(mbox->mbx);
+    LWIP_ASSERT("mbox quence not empty", msgs_waiting == 0);
+
+    if (msgs_waiting != 0) {
+      SYS_STATS_INC(mbox.err);
+    }
+  }
+#endif
+
+  vQueueDelete(mbox->mbx);
+
+  SYS_STATS_DEC(mbox.used);
+}
+
+sys_thread_t
+sys_thread_new(const char *name, lwip_thread_fn thread, void *arg, int stacksize, int prio)
+{
+  TaskHandle_t rtos_task;
+  BaseType_t ret;
+  sys_thread_t lwip_thread;
+  size_t rtos_stacksize;
+
+  LWIP_ASSERT("invalid stacksize", stacksize > 0);
+#if LWIP_FREERTOS_THREAD_STACKSIZE_IS_STACKWORDS
+  rtos_stacksize = (size_t)stacksize;
+#else
+  rtos_stacksize = (size_t)stacksize / sizeof(StackType_t);
+#endif
+
+  /* lwIP's lwip_thread_fn matches FreeRTOS' TaskFunction_t, so we can pass the
+     thread function without adaption here. */
+  ret = xTaskCreate(thread, name, (configSTACK_DEPTH_TYPE)rtos_stacksize, arg, prio, &rtos_task);
+  LWIP_ASSERT("task creation failed", ret == pdTRUE);
+
+  lwip_thread.thread_handle = rtos_task;
+  return lwip_thread;
+}
+
+#if LWIP_NETCONN_SEM_PER_THREAD
+#if configNUM_THREAD_LOCAL_STORAGE_POINTERS > 0
+
+sys_sem_t *
+sys_arch_netconn_sem_get(void)
+{
+  void* ret;
+  TaskHandle_t task = xTaskGetCurrentTaskHandle();
+  LWIP_ASSERT("task != NULL", task != NULL);
+
+  ret = pvTaskGetThreadLocalStoragePointer(task, 0);
+  return ret;
+}
+
+void
+sys_arch_netconn_sem_alloc(void)
+{
+  void *ret;
+  TaskHandle_t task = xTaskGetCurrentTaskHandle();
+  LWIP_ASSERT("task != NULL", task != NULL);
+
+  ret = pvTaskGetThreadLocalStoragePointer(task, 0);
+  if(ret == NULL) {
+    sys_sem_t *sem;
+    err_t err;
+    /* need to allocate the memory for this semaphore */
+    sem = mem_malloc(sizeof(sys_sem_t));
+    LWIP_ASSERT("sem != NULL", sem != NULL);
+    err = sys_sem_new(sem, 0);
+    LWIP_ASSERT("err == ERR_OK", err == ERR_OK);
+    LWIP_ASSERT("sem invalid", sys_sem_valid(sem));
+    vTaskSetThreadLocalStoragePointer(task, 0, sem);
+  }
+}
+
+void sys_arch_netconn_sem_free(void)
+{
+  void* ret;
+  TaskHandle_t task = xTaskGetCurrentTaskHandle();
+  LWIP_ASSERT("task != NULL", task != NULL);
+
+  ret = pvTaskGetThreadLocalStoragePointer(task, 0);
+  if(ret != NULL) {
+    sys_sem_t *sem = ret;
+    sys_sem_free(sem);
+    mem_free(sem);
+    vTaskSetThreadLocalStoragePointer(task, 0, NULL);
+  }
+}
+
+#else /* configNUM_THREAD_LOCAL_STORAGE_POINTERS > 0 */
+#error LWIP_NETCONN_SEM_PER_THREAD needs configNUM_THREAD_LOCAL_STORAGE_POINTERS
+#endif /* configNUM_THREAD_LOCAL_STORAGE_POINTERS > 0 */
+
+#endif /* LWIP_NETCONN_SEM_PER_THREAD */
+
+#if LWIP_FREERTOS_CHECK_CORE_LOCKING
+#if LWIP_TCPIP_CORE_LOCKING
+
+/** Flag the core lock held. A counter for recursive locks. */
+static u8_t lwip_core_lock_count;
+static TaskHandle_t lwip_core_lock_holder_thread;
+
+void
+sys_lock_tcpip_core(void)
+{
+   sys_mutex_lock(&lock_tcpip_core);
+   if (lwip_core_lock_count == 0) {
+     lwip_core_lock_holder_thread = xTaskGetCurrentTaskHandle();
+   }
+   lwip_core_lock_count++;
+}
+
+void
+sys_unlock_tcpip_core(void)
+{
+   lwip_core_lock_count--;
+   if (lwip_core_lock_count == 0) {
+       lwip_core_lock_holder_thread = 0;
+   }
+   sys_mutex_unlock(&lock_tcpip_core);
+}
+
+#endif /* LWIP_TCPIP_CORE_LOCKING */
+
+#if !NO_SYS
+static TaskHandle_t lwip_tcpip_thread;
+#endif
+
+void
+sys_mark_tcpip_thread(void)
+{
+#if !NO_SYS
+  lwip_tcpip_thread = xTaskGetCurrentTaskHandle();
+#endif
+}
+
+void
+sys_check_core_locking(void)
+{
+  /* Embedded systems should check we are NOT in an interrupt context here */
+  /* E.g. core Cortex-M3/M4 ports:
+         configASSERT( ( portNVIC_INT_CTRL_REG & portVECTACTIVE_MASK ) == 0 );
+
+     Instead, we use more generic FreeRTOS functions here, which should fail from ISR: */
+  taskENTER_CRITICAL();
+  taskEXIT_CRITICAL();
+
+#if !NO_SYS
+  if (lwip_tcpip_thread != 0) {
+    TaskHandle_t current_thread = xTaskGetCurrentTaskHandle();
+
+#if LWIP_TCPIP_CORE_LOCKING
+    LWIP_ASSERT("Function called without core lock",
+                current_thread == lwip_core_lock_holder_thread && lwip_core_lock_count > 0);
+#else /* LWIP_TCPIP_CORE_LOCKING */
+    LWIP_ASSERT("Function called from wrong thread", current_thread == lwip_tcpip_thread);
+#endif /* LWIP_TCPIP_CORE_LOCKING */
+  }
+#endif /* !NO_SYS */
+}
+
+#endif /* LWIP_FREERTOS_CHECK_CORE_LOCKING*/
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/ports/toppers/ethernetif.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/ports/toppers/ethernetif.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/ports/toppers/ethernetif.c	(revision 457)
@@ -0,0 +1,480 @@
+/*
+ *  TOPPERS/ASP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Advanced Standard Profile Kernel
+ * 
+ *  Copyright (C) 2003-2015 by Ryosuke Takeuchi
+ *                     GJ Business Division RICOH COMPANY,LTD. JAPAN
+ *  Copyright (C) 2017-2019 by TOPPERS PROJECT Educational Working Group.
+ * 
+ *  上記著作権者は，Free Software Foundation によって公表されている 
+ *  GNU General Public License の Version 2 に記述されている条件か，以
+ *  下の(1)～(4)の条件を満たす場合に限り，本ソフトウェア（本ソフトウェ
+ *  アを改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを再利用可能なバイナリコード（リロケータブルオブ
+ *      ジェクトファイルやライブラリなど）の形で利用する場合には，利用
+ *      に伴うドキュメント（利用者マニュアルなど）に，上記の著作権表示，
+ *      この利用条件および下記の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを再利用不可能なバイナリコードの形または機器に組
+ *      み込んだ形で利用する場合には，次のいずれかの条件を満たすこと．
+ *    (a) 利用に伴うドキュメント（利用者マニュアルなど）に，上記の著作
+ *        権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 利用の形態を，別に定める方法によって，上記著作権者に報告する
+ *        こと．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者を免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者は，
+ *  本ソフトウェアに関して，その適用可能性も含めて，いかなる保証も行わ
+ *  ない．また，本ソフトウェアの利用により直接的または間接的に生じたい
+ *  かなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Adam Dunkels <adam@sics.se>
+ *
+ */
+
+/*
+ * This file is a skeleton for developing Ethernet network interface
+ * drivers for lwIP. Add code to the low_level functions and do a
+ * search-and-replace for the word "ethernetif" to replace it with
+ * something that better describes your network interface.
+ */
+
+#include "kernel_impl.h"
+#include <t_syslog.h>
+#include <t_stdlib.h>
+#include <sil.h>
+#include <string.h>
+#include <target_syssvc.h>
+#include "kernel_cfg.h"
+
+#include "lwip/opt.h"
+
+#include "lwip/def.h"
+#include "lwip/ip.h"
+#include "lwip/mem.h"
+#include "lwip/stats.h"
+#include "lwip/snmp.h"
+#include "lwip/pbuf.h"
+#include "lwip/sys.h"
+#include "lwip/timeouts.h"
+#include "netif/etharp.h"
+#include "lwip/ethip6.h"
+
+#include "emac.h"
+
+/*
+ *  DESCRIPTOR定義
+ */
+#ifndef EMAC_PKTBUFSIZE
+#define EMAC_PKTBUFSIZE 1536
+#endif
+#ifndef NUM_RX_DESC
+#define NUM_RX_DESC     32		/* 受信キューの個数 */
+#endif
+#ifndef NUM_TX_DESC
+#define NUM_TX_DESC     24		/* 送信キューの個数 */
+#endif
+#define NUM_ALL_DESC    (NUM_RX_DESC + NUM_TX_DESC)
+
+static uint32_t event_count, event_value;
+#ifndef EMAC_DATA_ATTRIBUTE
+static uint8_t netqueue[(NUM_ALL_DESC * EMAC_QUE_SIZE)] __attribute__ ((aligned (32)));
+static uint8_t netbuffer[(NUM_ALL_DESC * EMAC_PKTBUFSIZE)] __attribute__ ((aligned (32));
+#else
+static uint8_t netqueue[(NUM_ALL_DESC * EMAC_QUE_SIZE)] __attribute__ (EMAC_DATA_ATTRIBUTE) __attribute__ ((aligned (32)));
+static uint8_t netbuffer[(NUM_ALL_DESC * EMAC_PKTBUFSIZE)] __attribute__ (EMAC_DATA_ATTRIBUTE) __attribute__ ((aligned (32)));
+#endif
+
+/* Define those to better describe your network interface. */
+#define IFNAME0 'e'
+#define IFNAME1 'n'
+
+
+/**
+ * Helper struct to hold private data used to operate your ethernet interface.
+ * Keeping the ethernet address of the MAC in this struct is not necessary
+ * as it is already kept in the struct netif.
+ * But this is only an example, anyway...
+ */
+struct ethernetif {
+  struct netif    *netif;
+  EMAC_Handle_t   *emacdev;
+  struct eth_addr *ethaddr;
+  uint8_t         enable;
+  /* Add whatever per-interface state that is needed here. */
+};
+
+/* Forward declarations. */
+static void ethernetif_input(struct netif *netif);
+static void ethernet_thread(void *arg);
+
+/**
+ *  callback from emac
+ */
+static void
+emac_event(EMAC_Handle_t *hemac, int mode, uint32_t event)
+{
+  event_value |= event;
+  if((++event_count % 200) == 0){
+	syslog_3(LOG_NOTICE, "emac_event(%08x, %08x) count(%d)", hemac, event_value, event_count);
+    event_value = 0;
+  }
+  if(mode == 0)
+    iset_flg(FLG_GMAC, event);
+  else
+    set_flg(FLG_GMAC, event);
+}
+
+/**
+ * In this function, the hardware should be initialized.
+ * Called from ethernetif_init().
+ *
+ * @param netif the already initialized lwip network interface structure
+ *        for this ethernetif
+ */
+static void
+low_level_init(struct netif *netif)
+{
+  EMAC_Init_t Init;
+  struct ethernetif *ethernetif = netif->state;
+  EMAC_Handle_t *emacdev;
+
+  /* set MAC hardware address length */
+  netif->hwaddr_len = ETHARP_HWADDR_LEN;
+
+  /* set MAC hardware address */
+  netif->hwaddr[0] = 0x02;
+  netif->hwaddr[1] = 0x12;
+  netif->hwaddr[2] = 0x34;
+  netif->hwaddr[3] = 0x56;
+  netif->hwaddr[4] = 0x78;
+  netif->hwaddr[5] = 0xab;
+
+  /* maximum transfer unit */
+  netif->mtu = 1500;
+
+  /* device capabilities */
+  /* don't set NETIF_FLAG_ETHARP if this device is not an ethernet one */
+  netif->flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP | NETIF_FLAG_IGMP;
+
+#if LWIP_IPV6 && LWIP_IPV6_MLD
+  /*
+   * For hardware/netifs that implement MAC filtering.
+   * All-nodes link-local is handled by default, so we must let the hardware know
+   * to allow multicast packets in.
+   * Should set mld_mac_filter previously. */
+  if (netif->mld_mac_filter != NULL) {
+    ip6_addr_t ip6_allnodes_ll;
+    ip6_addr_set_allnodes_linklocal(&ip6_allnodes_ll);
+    netif->mld_mac_filter(netif, &ip6_allnodes_ll, NETIF_ADD_MAC_FILTER);
+  }
+#endif /* LWIP_IPV6 && LWIP_IPV6_MLD */
+
+  /* Do whatever else is needed to initialize interface. */
+
+//  netif_set_link_up(netif);
+
+  ethernetif->netif = netif;
+  Init.paketbufsize = EMAC_PKTBUFSIZE;
+  Init.rxquecount   = NUM_RX_DESC;
+  Init.txquecount   = NUM_TX_DESC;
+  Init.quebuffer    = netqueue;
+  Init.databuffer   = netbuffer;
+  Init.semid        = SEM_GMAC_MDIO;
+  emacdev = emac_init(MACDEF_PORTID, &Init);
+  ethernetif->emacdev = emacdev;
+  emacdev->emacevent = emac_event;
+
+  /* EMAC のリセット */
+  emac_reset(emacdev, (uint8_t *)ethernetif->ethaddr);
+
+  /* 送受信を開始する */
+#ifdef LWIP_AUTONEGO
+  emac_start(emacdev, EMAC_LINK_AUTONEGO);
+#else	/* LWIP_AUTONEGO */
+  emac_start(emacdev, EMAC_LINK_100BASE_FULL);
+#endif	/* LWIP_AUTONEGO */
+  ethernetif->enable = 1;
+  sys_thread_new("ethernet_thread", ethernet_thread, netif, DEFAULT_THREAD_STACKSIZE, DEFAULT_THREAD_PRIO);
+}
+
+/**
+ * This function should do the actual transmission of the packet. The packet is
+ * contained in the pbuf that is passed to the function. This pbuf
+ * might be chained.
+ *
+ * @param netif the lwip network interface structure for this ethernetif
+ * @param p the MAC packet to send (e.g. IP packet including MAC addresses and type)
+ * @return ERR_OK if the packet could be sent
+ *         an err_t value if the packet couldn't be sent
+ *
+ * @note Returning ERR_MEM here if a DMA queue of your MAC is full can lead to
+ *       strange results. You might consider waiting for space in the DMA queue
+ *       to become available since the stack doesn't retry to send a packet
+ *       dropped because of memory failure (except for the TCP timers).
+ */
+static err_t
+low_level_output(struct netif *netif, struct pbuf *p)
+{
+  struct ethernetif *ethernetif = netif->state;
+  err_t  err = ERR_OK;
+
+#if ETH_PAD_SIZE
+  pbuf_header(p, -ETH_PAD_SIZE); /* drop the padding word */
+#endif
+
+  if(emac_send(ethernetif->emacdev, (struct emac_pkt *)p) != 0)
+    err = ERR_MEM;
+
+  MIB2_STATS_NETIF_ADD(netif, ifoutoctets, p->tot_len);
+  if (((u8_t*)p->payload)[0] & 1) {
+    /* broadcast or multicast packet*/
+    MIB2_STATS_NETIF_INC(netif, ifoutnucastpkts);
+  } else {
+    /* unicast packet */
+    MIB2_STATS_NETIF_INC(netif, ifoutucastpkts);
+  }
+  /* increase ifoutdiscards or ifouterrors on error */
+
+#if ETH_PAD_SIZE
+  pbuf_header(p, ETH_PAD_SIZE); /* reclaim the padding word */
+#endif
+
+  LINK_STATS_INC(link.xmit);
+
+  return err;
+}
+
+/**
+ * Should allocate a pbuf and transfer the bytes of the incoming
+ * packet from the interface into the pbuf.
+ *
+ * @param netif the lwip network interface structure for this ethernetif
+ * @return a pbuf filled with the received packet (including MAC header)
+ *         NULL on memory error
+ */
+static struct pbuf *
+low_level_input(struct netif *netif)
+{
+  struct ethernetif *ethernetif = (struct ethernetif *)netif->state;
+  struct pbuf *p;
+  int    len;
+  ER     ercd;
+
+  /* Obtain the size of the packet and put it into the "len"
+     variable. */
+  len = emac_recv_length(ethernetif->emacdev);
+  if(len <= 0)
+    return NULL;
+
+#if ETH_PAD_SIZE
+  len += ETH_PAD_SIZE; /* allow room for Ethernet padding */
+#endif
+
+  /* We allocate a pbuf chain of pbufs from the pool. */
+  p = pbuf_alloc(PBUF_RAW, len, PBUF_POOL);
+
+  if (p != NULL) {
+
+#if ETH_PAD_SIZE
+    pbuf_header(p, -ETH_PAD_SIZE); /* drop the padding word */
+#endif
+
+    ercd = emac_recv(ethernetif->emacdev, (struct emac_pkt *)p);
+    if(ercd != E_OK)
+      syslog_1(LOG_ERROR, "low_level_input emac_recv error(%d) !", ercd);
+
+    MIB2_STATS_NETIF_ADD(netif, ifinoctets, p->tot_len);
+    if (((u8_t*)p->payload)[0] & 1) {
+      /* broadcast or multicast packet*/
+      MIB2_STATS_NETIF_INC(netif, ifinnucastpkts);
+    } else {
+      /* unicast packet*/
+      MIB2_STATS_NETIF_INC(netif, ifinucastpkts);
+    }
+#if ETH_PAD_SIZE
+    pbuf_header(p, ETH_PAD_SIZE); /* reclaim the padding word */
+#endif
+
+    LINK_STATS_INC(link.recv);
+  } else {
+    emac_recv(ethernetif->emacdev, NULL);
+    LINK_STATS_INC(link.memerr);
+    LINK_STATS_INC(link.drop);
+    MIB2_STATS_NETIF_INC(netif, ifindiscards);
+  }
+
+  return p;
+}
+
+/**
+ * This function should be called when a packet is ready to be read
+ * from the interface. It uses the function low_level_input() that
+ * should handle the actual reception of bytes from the network
+ * interface. Then the type of the received packet is determined and
+ * the appropriate input function is called.
+ *
+ * @param netif the lwip network interface structure for this ethernetif
+ */
+static void
+ethernetif_input(struct netif *netif)
+{
+  struct pbuf *p;
+
+  /* move received packet into a new pbuf */
+  p = low_level_input(netif);
+  /* if no packet could be read, silently ignore this */
+  if (p != NULL) {
+    /* pass all packets to ethernet_input, which decides what packets it supports */
+    if (netif->input(p, netif) != ERR_OK) {
+      LWIP_DEBUGF(NETIF_DEBUG, ("ethernetif_input: IP input error\n"));
+      pbuf_free(p);
+      p = NULL;
+    }
+  }
+}
+
+/**
+ * Should be called at the beginning of the program to set up the
+ * network interface. It calls the function low_level_init() to do the
+ * actual setup of the hardware.
+ *
+ * This function should be passed as a parameter to netif_add().
+ *
+ * @param netif the lwip network interface structure for this ethernetif
+ * @return ERR_OK if the loopif is initialized
+ *         ERR_MEM if private data couldn't be allocated
+ *         any other err_t on error
+ */
+err_t
+ethernetif_init(struct netif *netif)
+{
+  struct ethernetif *ethernetif;
+
+  LWIP_ASSERT("netif != NULL", (netif != NULL));
+
+  ethernetif = mem_malloc(sizeof(struct ethernetif));
+  if (ethernetif == NULL) {
+    LWIP_DEBUGF(NETIF_DEBUG, ("ethernetif_init: out of memory\n"));
+    return ERR_MEM;
+  }
+
+#if LWIP_NETIF_HOSTNAME
+  /* Initialize interface hostname */
+  netif->hostname = "lwip";
+#endif /* LWIP_NETIF_HOSTNAME */
+
+  /*
+   * Initialize the snmp variables and counters inside the struct netif.
+   * The last argument should be replaced with your link speed, in units
+   * of bits per second.
+   */
+  MIB2_INIT_NETIF(netif, snmp_ifType_ethernet_csmacd, LINK_SPEED_OF_YOUR_NETIF_IN_BPS);
+
+  netif->state = ethernetif;
+
+  netif->name[0] = IFNAME0;
+  netif->name[1] = IFNAME1;
+  /* We directly use etharp_output() here to save a function call.
+   * You can instead declare your own function an call etharp_output()
+   * from it if you have to do some checks before sending (e.g. if link
+   * is available...) */
+  netif->output = etharp_output;
+#if LWIP_IPV6
+  netif->output_ip6 = ethip6_output;
+#endif /* LWIP_IPV6 */
+  netif->linkoutput = low_level_output;
+  netif->mtu = 1500;
+
+  ethernetif->ethaddr = (struct eth_addr *)&(netif->hwaddr[0]);
+
+  low_level_init(netif);
+
+  return ERR_OK;
+}
+
+/**
+ * ethernet polling thread
+ */
+static void
+ethernet_thread(void *arg)
+{
+  struct netif *netif;
+  struct ethernetif *ethernetif;
+  FLGPTN flgptn;
+  ER     ercd;
+  uint32_t rlink;
+  int    len;
+
+  netif = (struct netif *)arg;
+  ethernetif = (struct ethernetif *)netif->state;
+  dly_tsk(1000);
+
+  while(1) {
+    ercd = twai_flg(FLG_GMAC, 0x00ff, TWF_ORW, &flgptn, 100);
+    if(ercd == E_OK){
+      clr_flg(FLG_GMAC, ~flgptn);
+      if((flgptn & RESET_EVNT_DETECT) != 0){
+        emac_reset(ethernetif->emacdev, (uint8_t *)ethernetif->ethaddr);
+        continue;
+      }
+    }
+
+    rlink = emac_link_detect(ethernetif->emacdev);
+    if(rlink == 0 && (netif->flags & NETIF_FLAG_LINK_UP)){
+      syslog_2(LOG_NOTICE, "ethernetif:unlink[%08x][%08x] !", rlink, netif->flags);
+      netif_set_link_down(netif);
+    }
+    else if(rlink != 0 && !(netif->flags & NETIF_FLAG_LINK_UP)){
+      /* Interface mode の設定 */
+      emac_link_mode_set(ethernetif->emacdev, rlink);
+      syslog_2(LOG_NOTICE, "ethernetif:link[%08x][%08x] !", rlink, netif->flags);
+      netif_set_link_up(netif);
+    }
+
+    len = emac_recv_length(ethernetif->emacdev);
+
+    /* Wait for a packet to arrive. */
+    if(len > 0) {
+      /* Handle incoming packet. */
+      ethernetif_input(netif);
+    }
+  }
+}
+
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/ports/toppers/include/arch/cc.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/ports/toppers/include/arch/cc.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/ports/toppers/include/arch/cc.h	(revision 457)
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2001-2003 Swedish Institute of Computer Science.
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission. 
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ * 
+ * Author: Adam Dunkels <adam@sics.se>
+ *
+ */
+#ifndef LWIP_ARCH_CC_H
+#define LWIP_ARCH_CC_H
+
+/* see https://sourceforge.net/p/predef/wiki/OperatingSystems/ */
+#include <kernel.h>
+#include <t_syslog.h>
+#include <t_stdlib.h>
+#include <sil.h>
+#include "syssvc/serial.h"
+#include "syssvc/syslog.h"
+
+#define LWIP_TIMEVAL_PRIVATE 0
+#include <sys/time.h>
+
+#define LWIP_NO_INTTYPES_H 1
+
+/* different handling for unit test, normally not needed */
+#ifdef LWIP_NOASSERT_ON_ERROR
+#define LWIP_ERROR(message, expression, handler) do { if (!(expression)) { \
+  handler;}} while(0)
+#endif
+
+#if defined(LWIP_UNIX_ANDROID) && defined(FD_SET)
+typedef __kernel_fd_set fd_set;
+#endif
+
+struct sio_status_s;
+typedef struct sio_status_s sio_status_t;
+#define sio_fd_t sio_status_t*
+#define __sio_fd_t_defined
+
+/* Define (sn)printf formatters for these lwIP types */
+#define X8_F  "02x"
+#define U16_F "hu"
+#define U32_F "lu"
+#define S32_F "ld"
+#define X32_F "lx"
+
+#define S16_F "hd"
+#define X16_F "hx"
+#define SZT_F "lu"
+
+#endif /* LWIP_ARCH_CC_H */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/ports/toppers/include/arch/sys_arch.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/ports/toppers/include/arch/sys_arch.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/ports/toppers/include/arch/sys_arch.h	(revision 457)
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2001-2003 Swedish Institute of Computer Science.
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission. 
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ * 
+ * Author: Adam Dunkels <adam@sics.se>
+ *
+ */
+#ifndef LWIP_ARCH_SYS_ARCH_H
+#define LWIP_ARCH_SYS_ARCH_H
+
+#include <errno.h>
+
+#define SYS_MBOX_NULL NULL
+#define SYS_SEM_NULL  NULL
+
+typedef u32_t sys_prot_t;
+
+struct sys_sem;
+typedef struct sys_sem * sys_sem_t;
+#define sys_sem_valid(sem)       (((sem) != NULL) && (*(sem) != NULL))
+#define sys_sem_set_invalid(sem) do { if((sem) != NULL) { *(sem) = NULL; }}while(0)
+
+struct sys_mutex;
+typedef struct sys_mutex * sys_mutex_t;
+#define sys_mutex_valid(mutex)       sys_sem_valid(mutex)
+#define sys_mutex_set_invalid(mutex) sys_sem_set_invalid(mutex)
+
+struct sys_mbox;
+typedef struct sys_mbox * sys_mbox_t;
+#define sys_mbox_valid(mbox)       sys_sem_valid(mbox)
+#define sys_mbox_set_invalid(mbox) sys_sem_set_invalid(mbox)
+
+struct sys_thread;
+typedef struct sys_thread * sys_thread_t;
+
+#endif /* LWIP_ARCH_SYS_ARCH_H */
+
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/ports/toppers/snprintf.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/ports/toppers/snprintf.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/ports/toppers/snprintf.c	(revision 457)
@@ -0,0 +1,82 @@
+/*
+ *  TOPPERS/JSP/ASP/FMP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Just Standard Profile Kernel
+ * 
+ *  Copyright (C) 2008-2011 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ *  Copyright (C) 2015-2017 by TOPPERS PROJECT Educational Working Group.
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *	snprintf代用プログラム
+ */
+
+#include "kernel_impl.h"
+#include <t_syslog.h>
+#include <t_stdlib.h>
+#include "kernel_cfg.h"
+#include <stdarg.h>
+#include <target_stddef.h>
+
+extern int _setformat(void (*)(char c, char **p), char **, const char *, va_list);
+
+static int putlen;
+
+static void putz (char c, char ** p)
+{
+	if(putlen-- > 0)
+	    *(*p)++ = c;
+}
+
+/*  sprintf() takes an unlimited number of arguments,
+ *  which the caller has thoughtfully pushed onto the stack.
+ *  It returns a count of bytes moved to the output buffer.
+ */
+int
+snprintf(char * buffer, size_t len, const char * format, ...)
+{
+    int count;
+    char * pbuffer = buffer;
+    va_list args;
+    va_start(args, format);
+
+	wai_sem(LWIP_SNPRINTF);
+	putlen = len;
+    count = _setformat(putz, &pbuffer, format, args);
+	sig_sem(LWIP_SNPRINTF);
+    *pbuffer = 0;
+    return count;
+}
+
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/ports/toppers/sys_arch.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/ports/toppers/sys_arch.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/ports/toppers/sys_arch.c	(revision 457)
@@ -0,0 +1,566 @@
+/*
+ *  TOPPERS/ASP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Advanced Standard Profile Kernel
+ * 
+ *  Copyright (C) 2003-2015 by Ryosuke Takeuchi
+ *                     GJ Business Division RICOH COMPANY,LTD. JAPAN
+ *  Copyright (C) 2017-2019 by TOPPERS PROJECT Educational Working Group.
+ * 
+ *  上記著作権者は，Free Software Foundation によって公表されている 
+ *  GNU General Public License の Version 2 に記述されている条件か，以
+ *  下の(1)～(4)の条件を満たす場合に限り，本ソフトウェア（本ソフトウェ
+ *  アを改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを再利用可能なバイナリコード（リロケータブルオブ
+ *      ジェクトファイルやライブラリなど）の形で利用する場合には，利用
+ *      に伴うドキュメント（利用者マニュアルなど）に，上記の著作権表示，
+ *      この利用条件および下記の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを再利用不可能なバイナリコードの形または機器に組
+ *      み込んだ形で利用する場合には，次のいずれかの条件を満たすこと．
+ *    (a) 利用に伴うドキュメント（利用者マニュアルなど）に，上記の著作
+ *        権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 利用の形態を，別に定める方法によって，上記著作権者に報告する
+ *        こと．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者を免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者は，
+ *  本ソフトウェアに関して，その適用可能性も含めて，いかなる保証も行わ
+ *  ない．また，本ソフトウェアの利用により直接的または間接的に生じたい
+ *  かなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+/*
+ *  lwipシステム関数
+ */
+#include "kernel_impl.h"
+#include <t_syslog.h>
+#include <t_stdlib.h>
+#include <sil.h>
+#include <string.h>
+#include <target_syssvc.h>
+#include "kernel_cfg.h"
+#include "device.h"
+#include "lwip.h"
+
+#include "lwip/opt.h"
+#include "lwip/err.h"
+#include "lwip/sys.h"
+#include "arch/sys_arch.h"
+
+/*
+ *  サービスコールのエラーのログ出力
+ */
+Inline void
+svc_perror(const char *file, int_t line, const char *expr, ER ercd)
+{
+	if (ercd < 0) {
+		t_perror(LOG_ERROR, file, line, expr, ercd);
+	}
+}
+
+#define	SVC_PERROR(expr)	svc_perror(__FILE__, __LINE__, #expr, (expr))
+
+#define NUM_LWIP_TASK  (LWIP_TASK_N - LWIP_TASK_1 + 1)
+#define NUM_LOCK       (LWIP_LOCK_N - LWIP_LOCK_1 + 1)
+#define NUM_SEM0       (LWIP0_SEM_N - LWIP0_SEM_1 + 1)
+
+Inline void
+svc_perror2(const char *file, int_t line, const char *expr, ER ercd)
+{
+	if (ercd != E_OK && ercd != E_QOVR) {
+		t_perror(LOG_ERROR, file, line, expr, ercd);
+	}
+}
+
+#define	SVC_PERROR2(expr)	svc_perror2(__FILE__, __LINE__, #expr, (expr))
+
+struct sys_thread {
+	const char *name;
+	void       (*func)(struct sys_thread *);	/* エラーコールバック関数 */
+	ID         threadno;
+	void       *arg;
+	ID         pri;
+};
+
+struct sys_sem {
+	bool_t     act;
+	int        count;
+	ID         semid;
+};
+
+#define SYS_MBOX_SIZE 128
+
+struct sys_mbox {
+	int        first, last;
+	void       *msgs[SYS_MBOX_SIZE];
+	struct sys_sem *not_empty;
+	struct sys_sem *not_full;
+	struct sys_sem *mutex;
+	int        wait_send;
+};
+
+static int use_task_num, lwip_count;
+static struct sys_thread *lwip_thread;
+static struct sys_thread Sys_Thread[NUM_LWIP_TASK];
+static struct sys_sem    Sys_Lock[NUM_LOCK];
+static struct sys_sem    Sys_Sem0[NUM_SEM0];
+
+static struct sys_thread *
+search_thread(void)
+{
+	struct sys_thread *pthread = &Sys_Thread[0];
+	ID tid = 0;
+	int i;
+
+	get_tid(&tid);
+	for(i = 0 ; i < NUM_LWIP_TASK ; i++, pthread++){
+		if(pthread->threadno == tid)
+			return pthread;
+	}
+	return NULL;
+}
+
+void abort(void)
+{
+	struct sys_thread *pthread = search_thread();
+	syslog_2(LOG_ERROR, "abort [%s] thread(%d) !", pthread->name, pthread->threadno);
+	slp_tsk();
+}
+
+void
+sys_msleep(u32_t ms)
+{
+	dly_tsk(ms);
+}
+
+void
+sys_memcpy(volatile void *d, const volatile void *s, int len)
+{
+  volatile char *src = (volatile char *)s;
+  volatile char *dst = d;
+
+  while(len > 0){
+    *dst++ = *src++;
+    len--;
+  }
+}
+
+void
+sys_memset(volatile void *d, unsigned char val, int len)
+{
+  volatile char *dst = d;
+
+  while(len > 0){
+    *dst++ = val;
+    len--;
+  }
+}
+
+u32_t
+sys_now(void)
+{
+#ifdef TOPPERS_SUPPORT_GET_UTM
+	SYSUTM	utime;
+	SVC_PERROR(get_utm(&utime));
+	return utime / 1000;
+#else	/* TOPPERS_SUPPORT_GET_UTM */
+	SYSTIM	stime;
+	SVC_PERROR(get_tim(&stime));
+	return stime;
+#endif	/* TOPPERS_SUPPORT_GET_UTM */
+}
+
+u32_t
+sys_jiffies(void)
+{
+#ifdef TOPPERS_SUPPORT_GET_UTM
+	SYSUTM	utime;
+	SVC_PERROR(get_utm(&utime));
+	return utime * 1000;
+#else	/* TOPPERS_SUPPORT_GET_UTM */
+	SYSTIM	stime;
+	SVC_PERROR(get_tim(&stime));
+	return stime * 1000000;
+#endif	/* TOPPERS_SUPPORT_GET_UTM */
+}
+
+void
+sys_init(void)
+{
+	static bool_t init = false;
+	int i;
+
+	if(!init){
+		use_task_num = 0;
+		lwip_count   = 0;
+		lwip_thread  = NULL;
+		for(i = 0 ; i < NUM_LWIP_TASK ; i++){
+			Sys_Thread[i].threadno = LWIP_TASK_1+i;
+		}
+		for(i = 0 ; i < NUM_LOCK ; i++){
+			Sys_Lock[i].semid = LWIP_LOCK_1+i;
+			Sys_Lock[i].act   = false;
+		}
+		for(i = 0 ; i < NUM_SEM0 ; i++){
+			Sys_Sem0[i].semid = LWIP0_SEM_1+i;
+			Sys_Sem0[i].act   = false;
+		}
+		init = true;
+	}
+}
+
+
+void
+lwip_task(intptr_t exinf)
+{
+	struct sys_thread *pthread = &Sys_Thread[(int)exinf];
+	ID tid;
+	get_tid(&tid);
+	syslog_4(LOG_NOTICE, "lwip_task:start lwip task(%d:%d)[%s] pri(%d) !", (int)exinf, tid, pthread->name, pthread->pri);
+	if(pthread->pri >= 128){
+		SVC_PERROR(chg_pri(pthread->threadno, LWIP_DEFAULT_PRIORITY+5));
+		dly_tsk(100);
+	}
+	pthread->func(pthread->arg);
+}
+
+sys_thread_t
+sys_thread_new(const char *name, lwip_thread_fn function, void *arg, int stacksize, int prio)
+{
+	struct sys_thread *pthread;
+	if(use_task_num >= NUM_LWIP_TASK){
+		syslog_1(LOG_ERROR, "sys_thread_new over task count(%d) !", use_task_num);
+		slp_tsk();
+	}
+	wai_sem(LWIP_THREAD);
+	pthread = &Sys_Thread[use_task_num++];
+	pthread->name = name;
+	pthread->pri  = prio;
+	pthread->arg  = arg;
+	pthread->func = (void (*)(struct sys_thread *))function;
+	SVC_PERROR(act_tsk(pthread->threadno));
+	sig_sem(LWIP_THREAD);
+	return pthread;
+}
+
+err_t
+sys_mbox_new(struct sys_mbox **mb, int size)
+{
+	struct sys_mbox *mbox;
+	err_t  err;
+
+	mbox = (struct sys_mbox *)malloc(sizeof(struct sys_mbox));
+	if(mbox == NULL){
+		syslog_0(LOG_ERROR, "## sys_mbox_new mem error 1 ##");
+		return ERR_MEM;
+	}
+
+	mbox->first = mbox->last = 0;
+	mbox->wait_send = 0;
+	err = sys_sem_new(&mbox->not_empty, 0);
+	if(err != E_OK){
+		syslog_0(LOG_ERROR, "## sys_mbox_new sem error 1 ##");
+		free(mbox);
+		return err;
+	}
+	err = sys_sem_new(&mbox->not_full, 0);
+	if(err != E_OK){
+		syslog_0(LOG_ERROR, "## sys_mbox_new sem error 2 ##");
+		free(mbox);
+		return err;
+	}
+	err = sys_sem_new(&mbox->mutex, 1);
+	if(err != E_OK){
+		syslog_0(LOG_ERROR, "## sys_mbox_new sem error 3 ##");
+		free(mbox);
+		return err;
+	}
+
+	*mb = mbox;
+	return ERR_OK;
+}
+
+void
+sys_mbox_free(struct sys_mbox **mb)
+{
+	if ((mb != NULL) && (*mb != SYS_MBOX_NULL)) {
+		struct sys_mbox *mbox = *mb;
+//		SYS_STATS_DEC(mbox.used);
+		sys_mutex_lock(&mbox->mutex);
+		sys_sem_free(&mbox->not_empty);
+		sys_sem_free(&mbox->not_full);
+		sys_mutex_unlock(&mbox->mutex);
+		sys_sem_free(&mbox->mutex);
+		mbox->not_empty = mbox->not_full = mbox->mutex = NULL;
+		free(mbox);
+  }
+}
+
+err_t
+sys_mbox_trypost(struct sys_mbox **mb, void *msg)
+{
+	u8_t first;
+	struct sys_mbox *mbox;
+
+	LWIP_ASSERT("invalid mbox", (mb != NULL) && (*mb != NULL));
+	mbox = *mb;
+
+	sys_arch_sem_wait(&mbox->mutex, 0);
+
+	if((mbox->last + 1) >= (mbox->first + SYS_MBOX_SIZE)) {
+ 		sys_sem_signal(&mbox->mutex);
+		return ERR_MEM;
+	}
+
+	mbox->msgs[mbox->last % SYS_MBOX_SIZE] = msg;
+
+	if(mbox->last == mbox->first)
+		first = 1;
+	else
+		first = 0;
+
+	mbox->last++;
+
+	if(first)
+		sys_sem_signal(&mbox->not_empty);
+	sys_sem_signal(&mbox->mutex);
+
+	return ERR_OK;
+}
+
+err_t
+sys_mbox_trypost_fromisr(sys_mbox_t *q, void *msg)
+{
+	return sys_mbox_trypost(q, msg);
+}
+
+void
+sys_mbox_post(struct sys_mbox **mb, void *msg)
+{
+	u8_t first;
+	struct sys_mbox *mbox;
+	LWIP_ASSERT("invalid mbox", (mb != NULL) && (*mb != NULL));
+ 	mbox = *mb;
+
+	sys_arch_sem_wait(&mbox->mutex, 0);
+
+	syslog_2(LOG_NOTICE, "## sys_mbox_post mbox[%08x] msg[%08x] ##", mbox, msg);
+
+	while ((mbox->last + 1) >= (mbox->first + SYS_MBOX_SIZE)) {
+		mbox->wait_send++;
+		sys_sem_signal(&mbox->mutex);
+		sys_arch_sem_wait(&mbox->not_full, 0);
+		sys_arch_sem_wait(&mbox->mutex, 0);
+		mbox->wait_send--;
+	}
+
+	mbox->msgs[mbox->last % SYS_MBOX_SIZE] = msg;
+
+	if(mbox->last == mbox->first)
+		first = 1;
+	else
+		first = 0;
+
+	mbox->last++;
+
+	if(first)
+		sys_sem_signal(&mbox->not_empty);
+
+	sys_sem_signal(&mbox->mutex);
+}
+
+u32_t
+sys_arch_mbox_fetch(struct sys_mbox **mb, void **msg, u32_t timeout)
+{
+	u32_t time_needed = 0;
+	struct sys_mbox *mbox;
+
+	if(mb == NULL && *mb == NULL){
+		ID tid;
+		get_tid(&tid);
+		syslog_1(LOG_ERROR, "sys_arch_mbox_fetch mail box error task(%d) !", tid);
+		slp_tsk();
+	}
+	mbox = *mb;
+
+	/* The mutex lock is quick so we don't bother with the timeout
+		stuff here. */
+	sys_arch_sem_wait(&mbox->mutex, 0);
+
+	while (mbox->first == mbox->last) {
+		sys_sem_signal(&mbox->mutex);
+
+		/* We block while waiting for a mail to arrive in the mailbox. We
+		   must be prepared to timeout. */
+		if(timeout != 0) {
+			time_needed = sys_arch_sem_wait(&mbox->not_empty, timeout);
+			if (time_needed == SYS_ARCH_TIMEOUT) {
+				return SYS_ARCH_TIMEOUT;
+			}
+		}
+		else{
+			sys_arch_sem_wait(&mbox->not_empty, 0);
+		}
+		sys_arch_sem_wait(&mbox->mutex, 0);
+	}
+
+	if (msg != NULL)
+		*msg = mbox->msgs[mbox->first % SYS_MBOX_SIZE];
+	else
+		syslog_1(LOG_NOTICE, "sys_mbox_fetch: mbox %8x, null msg", (void *)mbox);
+
+	mbox->first++;
+
+	if (mbox->wait_send) {
+		sys_sem_signal(&mbox->not_full);
+	}
+
+	sys_sem_signal(&mbox->mutex);
+
+	return time_needed;
+}
+
+u32_t
+sys_arch_mbox_tryfetch(struct sys_mbox **mb, void **msg)
+{
+	struct sys_mbox *mbox;
+	LWIP_ASSERT("invalid mbox", (mb != NULL) && (*mb != NULL));
+	mbox = *mb;
+
+	sys_arch_sem_wait(&mbox->mutex, 0);
+
+	if(mbox->first == mbox->last){
+		sys_sem_signal(&mbox->mutex);
+		return SYS_MBOX_EMPTY;
+	}
+
+	if(msg != NULL)
+		*msg = mbox->msgs[mbox->first % SYS_MBOX_SIZE];
+	else
+		syslog_1(LOG_NOTICE, "sys_mbox_tryfetch: mbox %08x, null msg", (void *)mbox);
+
+	mbox->first++;
+
+	if (mbox->wait_send) {
+		sys_sem_signal(&mbox->not_full);
+	}
+
+	sys_sem_signal(&mbox->mutex);
+	return 0;
+}
+
+err_t
+sys_sem_new(struct sys_sem **sem, u8_t count)
+{
+	struct sys_sem *psem = NULL;
+	int num = 0, i;
+
+	if(count == 0){
+		psem = &Sys_Sem0[0];
+		num  = NUM_SEM0;
+	}
+	else if(count == 1){
+		psem = &Sys_Lock[0];
+		num  = NUM_LOCK;
+	}
+	else{
+		syslog_1(LOG_ERROR, "sys_sem_new no request count(%d) !", count);
+		slp_tsk();
+	}
+	for(i = 0 ; i < num ; i++, psem++){
+		if(!psem->act){
+			psem->count = count;
+			psem->act = true;
+			*sem = psem;
+			return ERR_OK;
+		}
+	}
+	return ERR_MEM;
+}
+
+u32_t
+sys_arch_sem_wait(struct sys_sem **s, u32_t timeout)
+{
+	struct sys_sem *psem = *s;
+	ER ercd;
+
+	if(timeout == 0)
+		ercd = wai_sem(psem->semid);
+	else
+		ercd = twai_sem(psem->semid, timeout);
+	if(ercd == E_TMOUT)
+		return SYS_ARCH_TIMEOUT;
+	else if(ercd == E_OK)
+		return 0;
+	else{
+		syslog_1(LOG_ERROR, "sys_arch_sem_wait error (%d) !", ercd);
+		slp_tsk();
+	}
+	return 0;
+}
+
+void
+sys_sem_signal(struct sys_sem **s)
+{
+	struct sys_sem *psem = *s;
+	SVC_PERROR2(sig_sem(psem->semid));
+}
+
+void
+sys_sem_free(struct sys_sem **sem)
+{
+	struct sys_sem *psem = *sem;
+	psem->act = false;
+}
+
+sys_prot_t
+sys_arch_protect(void)
+{
+	struct sys_thread *pthread = search_thread();
+
+	if(lwip_thread != pthread){
+		wai_sem(LWIP_PROTECT);
+		lwip_thread = pthread;
+		lwip_count = 1;
+	}
+	else
+		lwip_count++;
+	return (sys_prot_t)pthread;
+}
+
+void
+sys_arch_unprotect(sys_prot_t pval)
+{
+	struct sys_thread *pthread = (struct sys_thread *)pval;
+
+	if(lwip_thread == pthread){
+		if(--lwip_count == 0){
+			lwip_thread = NULL;
+			sig_sem(LWIP_PROTECT);
+		}
+	}
+}
+
+#if PPP_SUPPORT == 0
+sio_fd_t sio_open(u8_t devnum)
+{
+	return 0;
+}
+
+void sio_send( u8_t c, sio_status_t * siostat )
+{
+}
+
+u32_t sio_read(sio_status_t * siostat, u8_t *buf, u32_t size)
+{
+   return 0;
+}
+
+#endif
+
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/ports/unix/Common.mk
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/ports/unix/Common.mk	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/ports/unix/Common.mk	(revision 457)
@@ -0,0 +1,51 @@
+#
+# Copyright (c) 2001, 2002 Swedish Institute of Computer Science.
+# 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. The name of the author may not be used to endorse or promote products
+#    derived from this software without specific prior written permission. 
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+#
+# This file is part of the lwIP TCP/IP stack.
+# 
+# Author: Adam Dunkels <adam@sics.se>
+#
+
+# Architecture specific files.
+LWIPARCH?=$(CONTRIBDIR)/ports/unix/port
+SYSARCH?=$(LWIPARCH)/sys_arch.c
+ARCHFILES=$(LWIPARCH)/perf.c \
+  $(SYSARCH) \
+	$(LWIPARCH)/netif/tapif.c \
+	$(LWIPARCH)/netif/list.c \
+	$(LWIPARCH)/netif/sio.c \
+	$(LWIPARCH)/netif/fifo.c
+
+UNIX_COMMON_MK_DIR := $(dir $(abspath $(lastword $(MAKEFILE_LIST))))
+include $(UNIX_COMMON_MK_DIR)../Common.allports.mk
+
+LDFLAGS+=-lutil
+
+UNAME_S:= $(shell uname -s)
+ifneq ($(UNAME_S),Darwin)
+# Darwin doesn't have pthreads or POSIX real-time extensions libs
+LDFLAGS+=-pthread -lrt
+endif
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/ports/unix/Filelists.cmake
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/ports/unix/Filelists.cmake	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/ports/unix/Filelists.cmake	(revision 457)
@@ -0,0 +1,40 @@
+# This file is indended to be included in end-user CMakeLists.txt
+# include(/path/to/Filelists.cmake)
+# It assumes the variable LWIP_CONTRIB_DIR is defined pointing to the
+# root path of lwIP contrib sources.
+#
+# This file is NOT designed (on purpose) to be used as cmake
+# subdir via add_subdirectory()
+# The intention is to provide greater flexibility to users to 
+# create their own targets using the *_SRCS variables.
+
+set(lwipcontribportunix_SRCS
+    ${LWIP_CONTRIB_DIR}/ports/unix/port/sys_arch.c
+    ${LWIP_CONTRIB_DIR}/ports/unix/port/perf.c
+)
+
+set(lwipcontribportunixnetifs_SRCS
+    ${LWIP_CONTRIB_DIR}/ports/unix/port/netif/tapif.c
+    ${LWIP_CONTRIB_DIR}/ports/unix/port/netif/list.c
+    ${LWIP_CONTRIB_DIR}/ports/unix/port/netif/sio.c
+    ${LWIP_CONTRIB_DIR}/ports/unix/port/netif/fifo.c
+)
+
+add_library(lwipcontribportunix EXCLUDE_FROM_ALL ${lwipcontribportunix_SRCS} ${lwipcontribportunixnetifs_SRCS})
+target_include_directories(lwipcontribportunix PRIVATE ${LWIP_INCLUDE_DIRS} ${LWIP_MBEDTLS_INCLUDE_DIRS})
+target_compile_options(lwipcontribportunix PRIVATE ${LWIP_COMPILER_FLAGS})
+target_compile_definitions(lwipcontribportunix PRIVATE ${LWIP_DEFINITIONS} ${LWIP_MBEDTLS_DEFINITIONS})
+target_link_libraries(lwipcontribportunix PUBLIC ${LWIP_MBEDTLS_LINK_LIBRARIES})
+
+if (CMAKE_SYSTEM_NAME STREQUAL Linux)
+    find_library(LIBUTIL util)
+    find_library(LIBPTHREAD pthread)
+    find_library(LIBRT rt)
+    target_link_libraries(lwipcontribportunix PUBLIC ${LIBUTIL} ${LIBPTHREAD} ${LIBRT})
+endif()
+
+if (CMAKE_SYSTEM_NAME STREQUAL Darwin)
+    # Darwin doesn't have pthreads or POSIX real-time extensions libs
+    find_library(LIBUTIL util)
+    target_link_libraries(lwipcontribportunix PUBLIC ${LIBUTIL})
+endif()
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/ports/unix/README
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/ports/unix/README	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/ports/unix/README	(revision 457)
@@ -0,0 +1,25 @@
+This port contains infrastructure and examples for running lwIP on Unix-like
+operating systems (Linux, OpenBSD, cygwin). Much of this is targetted towards
+testing lwIP applications.
+
+* port/sys_arch.c, port/perf.c, port/include/arch/: Generic platform porting,
+  for both states of NO_SYS. (Mapping debugging to printf, providing 
+  sys_now & co from the system time etc.)
+
+* check: Runs the unit tests shipped with main lwIP on the Unix port.
+
+* port/netif, port/include/netif: Various network interface implementations and
+  their helpers, some explicitly for Unix infrastructure, some generic (but most
+  useful on an easy to debug system):
+
+  * fifo: Helper for sio
+
+  * list: Helper for unixif
+
+  * pcapif: Network interface that replays packages from a PCAP dump file, and
+    discards packages sent out from it
+
+  * sio: Mapping Unix character devices to lwIP's sio mechanisms
+
+  * tapif: Network interface that is mapped to a tap interface (Unix user
+    space layer 2 network device). Uses lwIP threads.
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/ports/unix/check/CMakeLists.txt
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/ports/unix/check/CMakeLists.txt	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/ports/unix/check/CMakeLists.txt	(revision 457)
@@ -0,0 +1,59 @@
+cmake_minimum_required(VERSION 3.8)
+
+project(lwipunittests C)
+
+if (NOT CMAKE_SYSTEM_NAME STREQUAL Linux AND NOT CMAKE_SYSTEM_NAME STREQUAL Darwin)
+    message(FATAL_ERROR "Unit test are currently only working on Linux or Darwin")
+endif()
+
+set(LWIP_CONTRIB_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../../..)
+set(LWIP_DIR         ${CMAKE_CURRENT_SOURCE_DIR}/../../../../lwip)
+
+set(LWIP_USE_SANITIZERS true)
+include(${LWIP_CONTRIB_DIR}/ports/CMakeCommon.cmake)
+
+if(CMAKE_C_COMPILER_ID STREQUAL Clang)
+    # check.h causes 'error: token pasting of ',' and __VA_ARGS__ is a GNU extension' with clang 9.0.0
+    list(LWIP_COMPILER_FLAGS APPEND -Wno-gnu-zero-variadic-macro-arguments)
+endif()
+
+set (LWIP_DEFINITIONS -DLWIP_DEBUG -DLWIP_NOASSERT_ON_ERROR)
+set (LWIP_INCLUDE_DIRS
+    "${LWIP_DIR}/test/unit"
+    "${LWIP_DIR}/src/include"
+    "${LWIP_CONTRIB_DIR}/"
+    "${LWIP_CONTRIB_DIR}/ports/unix/port/include"
+    "${CMAKE_CURRENT_SOURCE_DIR}/"
+)
+
+include(${LWIP_CONTRIB_DIR}/ports/unix/Filelists.cmake)
+include(${LWIP_DIR}/src/Filelists.cmake)
+include(${LWIP_DIR}/test/unit/Filelists.cmake)
+
+add_executable(lwip_unittests ${LWIP_TESTFILES})
+target_include_directories(lwip_unittests PRIVATE ${LWIP_INCLUDE_DIRS})
+target_compile_options(lwip_unittests PRIVATE ${LWIP_COMPILER_FLAGS})
+target_compile_definitions(lwip_unittests PRIVATE ${LWIP_DEFINITIONS} ${LWIP_MBEDTLS_DEFINITIONS})
+
+find_library(LIBCHECK check)
+find_library(LIBM m)
+target_link_libraries(lwip_unittests ${LWIP_SANITIZER_LIBS} lwipallapps lwipcore ${LIBCHECK} ${LIBM})
+
+if (NOT CMAKE_SYSTEM_NAME STREQUAL Darwin)
+    # check installed via brew on Darwin doesn't have a separate subunit library (must be statically linked)
+    find_library(LIBSUBUNIT subunit)
+    target_link_libraries(lwip_unittests ${LIBSUBUNIT})
+endif()
+
+if (CMAKE_SYSTEM_NAME STREQUAL Linux)
+    find_library(LIBUTIL util)
+    find_library(LIBPTHREAD pthread)
+    find_library(LIBRT rt)
+    target_link_libraries(lwip_unittests ${LIBUTIL} ${LIBPTHREAD} ${LIBRT})
+endif()
+
+if (CMAKE_SYSTEM_NAME STREQUAL Darwin)
+    # Darwin doesn't have pthreads or POSIX real-time extensions libs
+    find_library(LIBUTIL util)
+    target_link_libraries(lwip_unittests ${LIBUTIL})
+endif()
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/ports/unix/check/Makefile
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/ports/unix/check/Makefile	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/ports/unix/check/Makefile	(revision 457)
@@ -0,0 +1,78 @@
+#
+# Copyright (c) 2001, 2002 Swedish Institute of Computer Science.
+# 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. The name of the author may not be used to endorse or promote products
+#    derived from this software without specific prior written permission. 
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+#
+# This file is part of the lwIP TCP/IP stack.
+# 
+# Author: Adam Dunkels <adam@sics.se>
+#
+ 
+all compile: lwip_unittests
+.PHONY: all clean check
+
+# The include path to sys_arch.h and lwipopts.h must be first, so this must be before Common.mk
+CFLAGS=-DLWIP_NOASSERT_ON_ERROR -I/usr/include/check -I$(LWIPDIR)/../test/unit
+
+ifeq (clang,$(findstring clang,$(CC)))
+# check.h causes 'error: token pasting of ',' and __VA_ARGS__ is a GNU extension' with clang 9.0.0
+CFLAGS+=-Wno-gnu-zero-variadic-macro-arguments
+endif
+
+# Prevent compiling sys_arch.c of unix port because unit test provide their own port
+SYSARCH?=
+include ../Common.mk
+
+LDFLAGS:=-lcheck -lm $(LDFLAGS)
+
+ifneq ($(UNAME_S),Darwin)
+# check installed via brew on Darwin doesn't have a separate subunit library (must be statically linked)
+LDFLAGS+=-lsubunit
+endif
+
+TESTDIR=$(LWIPDIR)/../test/unit
+include $(TESTDIR)/Filelists.mk
+TESTOBJS=$(notdir $(TESTFILES:.c=.o))
+
+clean:
+	@rm -f *.o $(LWIPLIBCOMMON) $(APPLIB) lwip_unittests *.s .depend* *.core core lwip_unittests.xml
+
+depend dep: .depend
+
+include .depend
+
+.depend: $(LWIPFILES) $(APPFILES) $(TESTFILES)
+	$(CCDEP) $(CFLAGS) -MM $^ > .depend || rm -f .depend
+
+ifneq ($(UNAME_S),Darwin)
+# clang on Darwin doesn't support --start-group
+lwip_unittests: .depend $(TESTOBJS) $(LWIPLIBCOMMON) $(APPLIB)
+	$(CC) $(CFLAGS) -o lwip_unittests $(TESTOBJS)  -Wl,--start-group $(LWIPLIBCOMMON) $(APPLIB) $(LDFLAGS) -Wl,--end-group
+else
+lwip_unittests: .depend $(TESTOBJS) $(LWIPLIBCOMMON) $(APPLIB)
+	$(CC) $(CFLAGS) -o lwip_unittests $(TESTOBJS) $(LWIPLIBCOMMON) $(APPLIB) $(LDFLAGS)
+endif
+
+check: lwip_unittests
+	@./lwip_unittests
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/ports/unix/check/README
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/ports/unix/check/README	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/ports/unix/check/README	(revision 457)
@@ -0,0 +1,8 @@
+
+Helper files to run lwIP unit tests on unix-like systems.
+
+1. Install the check library, through a package manager or from http://check.sourceforge.net/
+2. Put the lwip code in a directory called 'lwip' in the same directory as lwip-contrib is
+3. Run `make check`
+4. Make sure all tests pass
+
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/ports/unix/check/config.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/ports/unix/check/config.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/ports/unix/check/config.h	(revision 457)
@@ -0,0 +1,2 @@
+/* Enable this to simplify debugging */
+/* #define LWIP_UNITTESTS_NOFORK */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/ports/unix/example_app/CMakeLists.txt
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/ports/unix/example_app/CMakeLists.txt	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/ports/unix/example_app/CMakeLists.txt	(revision 457)
@@ -0,0 +1,33 @@
+cmake_minimum_required(VERSION 3.8)
+
+project(example_app C)
+
+set (CMAKE_EXPORT_COMPILE_COMMANDS ON)
+
+set(LWIP_CONTRIB_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../../..)
+set(LWIP_DIR         ${CMAKE_CURRENT_SOURCE_DIR}/../../../../lwip)
+
+include(${LWIP_CONTRIB_DIR}/ports/CMakeCommon.cmake)
+
+set (LWIP_DEFINITIONS -DLWIP_DEBUG)
+set (LWIP_INCLUDE_DIRS
+    "${LWIP_DIR}/src/include"
+    "${LWIP_CONTRIB_DIR}/"
+    "${LWIP_CONTRIB_DIR}/ports/unix/port/include"
+    "${LWIP_CONTRIB_DIR}/examples/example_app"
+)
+
+include(${LWIP_DIR}/src/Filelists.cmake)
+include(${LWIP_CONTRIB_DIR}/Filelists.cmake)
+include(${LWIP_CONTRIB_DIR}/ports/unix/Filelists.cmake)
+
+add_executable(example_app ${LWIP_CONTRIB_DIR}/examples/example_app/test.c default_netif.c)
+target_include_directories(example_app PRIVATE ${LWIP_INCLUDE_DIRS})
+target_compile_options(example_app PRIVATE ${LWIP_COMPILER_FLAGS})
+target_compile_definitions(example_app PRIVATE ${LWIP_DEFINITIONS} ${LWIP_MBEDTLS_DEFINITIONS})
+target_link_libraries(example_app ${LWIP_SANITIZER_LIBS} lwipcontribexamples lwipcontribapps lwipcontribaddons lwipallapps lwipcontribportunix lwipcore)
+
+add_executable(makefsdata ${lwipmakefsdata_SRCS})
+target_compile_options(makefsdata PRIVATE ${LWIP_COMPILER_FLAGS})
+target_include_directories(makefsdata PRIVATE ${LWIP_INCLUDE_DIRS})
+target_link_libraries(makefsdata ${LWIP_SANITIZER_LIBS})
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/ports/unix/example_app/Makefile
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/ports/unix/example_app/Makefile	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/ports/unix/example_app/Makefile	(revision 457)
@@ -0,0 +1,58 @@
+#
+# Copyright (c) 2001, 2002 Swedish Institute of Computer Science.
+# 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. The name of the author may not be used to endorse or promote products
+#    derived from this software without specific prior written permission. 
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+#
+# This file is part of the lwIP TCP/IP stack.
+# 
+# Author: Adam Dunkels <adam@sics.se>
+#
+
+all compile: example_app makefsdata
+.PHONY: all
+
+include ../Common.mk
+
+CFLAGS+=-I$(CONTRIBDIR)/examples/example_app
+
+TESTFLAGS?=
+CFLAGS+=$(TESTFLAGS)
+
+MAKEFSDATAOBJS=$(notdir $(MAKEFSDATAFILES:.c=.o))
+
+clean:
+	rm -f *.o $(LWIPLIBCOMMON) $(APPLIB) example_app makefsdata *.s .depend* *.core core
+
+depend dep: .depend
+
+include .depend
+
+.depend: $(CONTRIBDIR)/examples/example_app/test.c default_netif.c $(LWIPFILES) $(APPFILES) $(MAKEFSDATAFILES)
+	$(CCDEP) $(CFLAGS) -MM $^ > .depend || rm -f .depend
+
+example_app: .depend $(LWIPLIBCOMMON) $(APPLIB) default_netif.o test.o
+	$(CC) $(CFLAGS) -o example_app test.o default_netif.o -Wl,--start-group $(APPLIB) $(LWIPLIBCOMMON) -Wl,--end-group $(LDFLAGS)
+
+makefsdata: .depend $(MAKEFSDATAOBJS)
+	$(CC) $(CFLAGS) -o makefsdata $(MAKEFSDATAOBJS)
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/ports/unix/example_app/default_netif.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/ports/unix/example_app/default_netif.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/ports/unix/example_app/default_netif.c	(revision 457)
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 2001-2003 Swedish Institute of Computer Science.
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission. 
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ * 
+ * Author: Adam Dunkels <adam@sics.se>
+ *
+ */
+
+#include "lwip/opt.h"
+
+#include "lwip/netif.h"
+#include "lwip/ip_addr.h"
+#include "lwip/tcpip.h"
+#include "netif/tapif.h"
+#include "examples/example_app/default_netif.h"
+
+static struct netif netif;
+
+#if LWIP_IPV4
+#define NETIF_ADDRS ipaddr, netmask, gw,
+void init_default_netif(const ip4_addr_t *ipaddr, const ip4_addr_t *netmask, const ip4_addr_t *gw)
+#else
+#define NETIF_ADDRS
+void init_default_netif(void)
+#endif
+{
+#if NO_SYS
+netif_add(&netif, NETIF_ADDRS NULL, tapif_init, netif_input);
+#else
+  netif_add(&netif, NETIF_ADDRS NULL, tapif_init, tcpip_input);
+#endif
+  netif_set_default(&netif);
+}
+
+void
+default_netif_poll(void)
+{
+  tapif_poll(&netif);
+}
+
+void
+default_netif_shutdown(void)
+{
+}
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/ports/unix/example_app/iteropts.sh
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/ports/unix/example_app/iteropts.sh	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/ports/unix/example_app/iteropts.sh	(revision 457)
@@ -0,0 +1,24 @@
+#!/bin/bash
+
+LOGFILE=iteropts.log
+EXAPPDIR=../../../examples/example_app
+
+pushd `dirname "$0"`
+pwd
+echo Starting Iteropts run >> $LOGFILE
+for f in $EXAPPDIR/test_configs/*.h
+do
+    echo Cleaning...
+    make clean
+    BUILDLOG=$(basename "$f" ".h").log
+    echo testing $f
+    echo testing $f >> $LOGFILE
+    rm $EXAPPDIR/lwipopts_test.h
+    # cat the file to update its timestamp
+    cat $f > $EXAPPDIR/lwipopts_test.h
+    make TESTFLAGS=-DLWIP_OPTTEST_FILE -j 8 &> $BUILDLOG 2>&1 || echo file $f failed >> $LOGFILE
+    echo test $f done >> $LOGFILE
+done
+echo done, cleaning
+make clean
+popd
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/ports/unix/lib/CMakeLists.txt
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/ports/unix/lib/CMakeLists.txt	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/ports/unix/lib/CMakeLists.txt	(revision 457)
@@ -0,0 +1,34 @@
+cmake_minimum_required(VERSION 3.8)
+
+project(lwip C)
+
+set (BUILD_SHARED_LIBS ON)
+
+if (NOT CMAKE_SYSTEM_NAME STREQUAL Linux AND NOT CMAKE_SYSTEM_NAME STREQUAL GNU)
+    message(FATAL_ERROR "Lwip shared library is only working on Linux or the Hurd")
+endif()
+
+set(LWIP_CONTRIB_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../../..)
+set(LWIP_DIR         ${CMAKE_CURRENT_SOURCE_DIR}/../../../../lwip)
+
+include(${LWIP_CONTRIB_DIR}/ports/CMakeCommon.cmake)
+
+set (LWIP_DEFINITIONS -DLWIP_DEBUG)
+set (LWIP_INCLUDE_DIRS
+    "${LWIP_DIR}/src/include"
+    "${LWIP_CONTRIB_DIR}/"
+    "${LWIP_CONTRIB_DIR}/ports/unix/port/include"
+    "${CMAKE_CURRENT_SOURCE_DIR}/"
+)
+
+include(${LWIP_CONTRIB_DIR}/ports/unix/Filelists.cmake)
+include(${LWIP_DIR}/src/Filelists.cmake)
+
+add_library(lwip ${lwipnoapps_SRCS} ${lwipcontribportunix_SRCS} ${lwipcontribportunixnetifs_SRCS})
+target_compile_options(lwip PRIVATE ${LWIP_COMPILER_FLAGS})
+target_compile_definitions(lwip PRIVATE ${LWIP_DEFINITIONS} ${LWIP_MBEDTLS_DEFINITIONS})
+target_include_directories(lwip PRIVATE ${LWIP_INCLUDE_DIRS} ${LWIP_MBEDTLS_INCLUDE_DIRS})
+target_link_libraries(lwip ${LWIP_SANITIZER_LIBS})
+
+find_library(LIBPTHREAD pthread)
+target_link_libraries(lwip ${LIBPTHREAD})
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/ports/unix/lib/README
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/ports/unix/lib/README	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/ports/unix/lib/README	(revision 457)
@@ -0,0 +1,28 @@
+This directory contains an example of how to compile lwIP as a shared library
+on Linux.
+
+Some brief instructions:
+
+* Compile the code:
+
+ > mkdir build
+ > cd build
+ > cmake ..
+ > make clean all
+
+ This should produce liblwip.so. This is the shared library.
+
+* Link an application against the shared library
+
+ If you're using gcc you can do this by including -llwip in your link command.
+
+* Run your application
+
+ Ensure that LD_LIBRARY_PATH includes the directory that contains liblwip.so
+ (ie. this directory)
+
+
+If you are unsure about shared libraries and libraries on linux in
+general, you might find this HOWTO useful:
+
+<http://www.tldp.org/HOWTO/Program-Library-HOWTO/>
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/ports/unix/lib/lwipopts.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/ports/unix/lib/lwipopts.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/ports/unix/lib/lwipopts.h	(revision 457)
@@ -0,0 +1,445 @@
+/**
+ * @file
+ *
+ * lwIP Options Configuration
+ */
+
+/*
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Adam Dunkels <adam@sics.se>
+ *
+ */
+#ifndef LWIP_LWIPOPTS_H
+#define LWIP_LWIPOPTS_H
+
+/*
+ * Include user defined options first. Anything not defined in these files
+ * will be set to standard values. Override anything you dont like!
+ */
+#include "lwipopts.h"
+#include "lwip/debug.h"
+
+/*
+   -----------------------------------------------
+   ---------- Platform specific locking ----------
+   -----------------------------------------------
+*/
+
+/**
+ * SYS_LIGHTWEIGHT_PROT==1: if you want inter-task protection for certain
+ * critical regions during buffer allocation, deallocation and memory
+ * allocation and deallocation.
+ */
+#define SYS_LIGHTWEIGHT_PROT            0
+
+/**
+ * NO_SYS==1: Provides VERY minimal functionality. Otherwise,
+ * use lwIP facilities.
+ */
+#define NO_SYS                          0
+
+/*
+   ------------------------------------
+   ---------- Memory options ----------
+   ------------------------------------
+*/
+
+/**
+ * MEM_ALIGNMENT: should be set to the alignment of the CPU
+ *    4 byte alignment -> #define MEM_ALIGNMENT 4
+ *    2 byte alignment -> #define MEM_ALIGNMENT 2
+ */
+#define MEM_ALIGNMENT                   1U
+
+/**
+ * MEM_SIZE: the size of the heap memory. If the application will send
+ * a lot of data that needs to be copied, this should be set high.
+ */
+#define MEM_SIZE                        1600
+
+/*
+   ------------------------------------------------
+   ---------- Internal Memory Pool Sizes ----------
+   ------------------------------------------------
+*/
+/**
+ * MEMP_NUM_PBUF: the number of memp struct pbufs (used for PBUF_ROM and PBUF_REF).
+ * If the application sends a lot of data out of ROM (or other static memory),
+ * this should be set high.
+ */
+#define MEMP_NUM_PBUF                   16
+
+/**
+ * MEMP_NUM_RAW_PCB: Number of raw connection PCBs
+ * (requires the LWIP_RAW option)
+ */
+#define MEMP_NUM_RAW_PCB                4
+
+/**
+ * MEMP_NUM_UDP_PCB: the number of UDP protocol control blocks. One
+ * per active UDP "connection".
+ * (requires the LWIP_UDP option)
+ */
+#define MEMP_NUM_UDP_PCB                4
+
+/**
+ * MEMP_NUM_TCP_PCB: the number of simulatenously active TCP connections.
+ * (requires the LWIP_TCP option)
+ */
+#define MEMP_NUM_TCP_PCB                4
+
+/**
+ * MEMP_NUM_TCP_PCB_LISTEN: the number of listening TCP connections.
+ * (requires the LWIP_TCP option)
+ */
+#define MEMP_NUM_TCP_PCB_LISTEN         4
+
+/**
+ * MEMP_NUM_TCP_SEG: the number of simultaneously queued TCP segments.
+ * (requires the LWIP_TCP option)
+ */
+#define MEMP_NUM_TCP_SEG                16
+
+/**
+ * MEMP_NUM_REASSDATA: the number of simultaneously IP packets queued for
+ * reassembly (whole packets, not fragments!)
+ */
+#define MEMP_NUM_REASSDATA              1
+
+/**
+ * MEMP_NUM_ARP_QUEUE: the number of simulateously queued outgoing
+ * packets (pbufs) that are waiting for an ARP request (to resolve
+ * their destination address) to finish.
+ * (requires the ARP_QUEUEING option)
+ */
+#define MEMP_NUM_ARP_QUEUE              2
+
+/**
+ * MEMP_NUM_SYS_TIMEOUT: the number of simulateously active timeouts.
+ * (requires NO_SYS==0)
+ */
+#define MEMP_NUM_SYS_TIMEOUT            8
+
+/**
+ * MEMP_NUM_NETBUF: the number of struct netbufs.
+ * (only needed if you use the sequential API, like api_lib.c)
+ */
+#define MEMP_NUM_NETBUF                 2
+
+/**
+ * MEMP_NUM_NETCONN: the number of struct netconns.
+ * (only needed if you use the sequential API, like api_lib.c)
+ */
+#define MEMP_NUM_NETCONN               32
+
+/**
+ * MEMP_NUM_TCPIP_MSG_API: the number of struct tcpip_msg, which are used
+ * for callback/timeout API communication.
+ * (only needed if you use tcpip.c)
+ */
+#define MEMP_NUM_TCPIP_MSG_API          8
+
+/**
+ * MEMP_NUM_TCPIP_MSG_INPKT: the number of struct tcpip_msg, which are used
+ * for incoming packets.
+ * (only needed if you use tcpip.c)
+ */
+#define MEMP_NUM_TCPIP_MSG_INPKT        8
+
+/**
+ * PBUF_POOL_SIZE: the number of buffers in the pbuf pool.
+ */
+#define PBUF_POOL_SIZE                  8
+
+/*
+   ---------------------------------
+   ---------- ARP options ----------
+   ---------------------------------
+*/
+/**
+ * LWIP_ARP==1: Enable ARP functionality.
+ */
+#define LWIP_ARP                        1
+
+/*
+   --------------------------------
+   ---------- IP options ----------
+   --------------------------------
+*/
+/**
+ * IP_FORWARD==1: Enables the ability to forward IP packets across network
+ * interfaces. If you are going to run lwIP on a device with only one network
+ * interface, define this to 0.
+ */
+#define IP_FORWARD                      0
+
+/**
+ * IP_OPTIONS: Defines the behavior for IP options.
+ *      IP_OPTIONS_ALLOWED==0: All packets with IP options are dropped.
+ *      IP_OPTIONS_ALLOWED==1: IP options are allowed (but not parsed).
+ */
+#define IP_OPTIONS_ALLOWED              1
+
+/**
+ * IP_REASSEMBLY==1: Reassemble incoming fragmented IP packets. Note that
+ * this option does not affect outgoing packet sizes, which can be controlled
+ * via IP_FRAG.
+ */
+#define IP_REASSEMBLY                   1
+
+/**
+ * IP_FRAG==1: Fragment outgoing IP packets if their size exceeds MTU. Note
+ * that this option does not affect incoming packet sizes, which can be
+ * controlled via IP_REASSEMBLY.
+ */
+#define IP_FRAG                         1
+
+/**
+ * IP_REASS_MAXAGE: Maximum time (in multiples of IP_TMR_INTERVAL - so seconds, normally)
+ * a fragmented IP packet waits for all fragments to arrive. If not all fragments arrived
+ * in this time, the whole packet is discarded.
+ */
+#define IP_REASS_MAXAGE                 3
+
+/**
+ * IP_REASS_MAX_PBUFS: Total maximum amount of pbufs waiting to be reassembled.
+ * Since the received pbufs are enqueued, be sure to configure
+ * PBUF_POOL_SIZE > IP_REASS_MAX_PBUFS so that the stack is still able to receive
+ * packets even if the maximum amount of fragments is enqueued for reassembly!
+ */
+#define IP_REASS_MAX_PBUFS              4
+
+/**
+ * IP_FRAG_USES_STATIC_BUF==1: Use a static MTU-sized buffer for IP
+ * fragmentation. Otherwise pbufs are allocated and reference the original
+    * packet data to be fragmented.
+*/
+#define IP_FRAG_USES_STATIC_BUF         0
+
+/**
+ * IP_DEFAULT_TTL: Default value for Time-To-Live used by transport layers.
+ */
+#define IP_DEFAULT_TTL                  255
+
+/*
+   ----------------------------------
+   ---------- ICMP options ----------
+   ----------------------------------
+*/
+/**
+ * LWIP_ICMP==1: Enable ICMP module inside the IP stack.
+ * Be careful, disable that make your product non-compliant to RFC1122
+ */
+#define LWIP_ICMP                       1
+
+/*
+   ---------------------------------
+   ---------- RAW options ----------
+   ---------------------------------
+*/
+/**
+ * LWIP_RAW==1: Enable application layer to hook into the IP layer itself.
+ */
+#define LWIP_RAW                        1
+
+/*
+   ----------------------------------
+   ---------- DHCP options ----------
+   ----------------------------------
+*/
+/**
+ * LWIP_DHCP==1: Enable DHCP module.
+ */
+#define LWIP_DHCP                       0
+
+
+/*
+   ------------------------------------
+   ---------- AUTOIP options ----------
+   ------------------------------------
+*/
+/**
+ * LWIP_AUTOIP==1: Enable AUTOIP module.
+ */
+#define LWIP_AUTOIP                     0
+
+/*
+   ----------------------------------
+   ---------- SNMP options ----------
+   ----------------------------------
+*/
+/**
+ * LWIP_SNMP==1: Turn on SNMP module. UDP must be available for SNMP
+ * transport.
+ */
+#define LWIP_SNMP                       0
+
+/*
+   ----------------------------------
+   ---------- IGMP options ----------
+   ----------------------------------
+*/
+/**
+ * LWIP_IGMP==1: Turn on IGMP module.
+ */
+#define LWIP_IGMP                       0
+
+/*
+   ----------------------------------
+   ---------- DNS options -----------
+   ----------------------------------
+*/
+/**
+ * LWIP_DNS==1: Turn on DNS module. UDP must be available for DNS
+ * transport.
+ */
+#define LWIP_DNS                        0
+
+/*
+   ---------------------------------
+   ---------- UDP options ----------
+   ---------------------------------
+*/
+/**
+ * LWIP_UDP==1: Turn on UDP.
+ */
+#define LWIP_UDP                        1
+
+/*
+   ---------------------------------
+   ---------- TCP options ----------
+   ---------------------------------
+*/
+/**
+ * LWIP_TCP==1: Turn on TCP.
+ */
+#define LWIP_TCP                        1
+
+#define LWIP_LISTEN_BACKLOG             0
+
+/*
+   ----------------------------------
+   ---------- Pbuf options ----------
+   ----------------------------------
+*/
+/**
+ * PBUF_LINK_HLEN: the number of bytes that should be allocated for a
+ * link level header. The default is 14, the standard value for
+ * Ethernet.
+ */
+#define PBUF_LINK_HLEN                  16
+
+/**
+ * PBUF_POOL_BUFSIZE: the size of each pbuf in the pbuf pool. The default is
+ * designed to accomodate single full size TCP frame in one pbuf, including
+ * TCP_MSS, IP header, and link header.
+*
+ */
+#define PBUF_POOL_BUFSIZE               LWIP_MEM_ALIGN_SIZE(TCP_MSS+40+PBUF_LINK_HLEN)
+
+/*
+   ------------------------------------
+   ---------- LOOPIF options ----------
+   ------------------------------------
+*/
+/**
+ * LWIP_HAVE_LOOPIF==1: Support loop interface (127.0.0.1) and loopif.c
+ */
+#define LWIP_HAVE_LOOPIF                0
+
+/*
+   ----------------------------------------------
+   ---------- Sequential layer options ----------
+   ----------------------------------------------
+*/
+
+/**
+ * LWIP_NETCONN==1: Enable Netconn API (require to use api_lib.c)
+ */
+#define LWIP_NETCONN                    1
+
+/*
+   ------------------------------------
+   ---------- Socket options ----------
+   ------------------------------------
+*/
+/**
+ * LWIP_SOCKET==1: Enable Socket API (require to use sockets.c)
+ */
+#define LWIP_SOCKET                     1
+
+/**
+ * SO_REUSE==1: Enable SO_REUSEADDR
+ */
+#define SO_REUSE                        1
+
+/*
+   ----------------------------------------
+   ---------- Statistics options ----------
+   ----------------------------------------
+*/
+/**
+ * LWIP_STATS==1: Enable statistics collection in lwip_stats.
+ */
+#define LWIP_STATS                      0
+/*
+   ---------------------------------
+   ---------- PPP options ----------
+   ---------------------------------
+*/
+/**
+ * PPP_SUPPORT==1: Enable PPP.
+ */
+#define PPP_SUPPORT                     0
+
+
+
+/*
+   ---------------------------------------
+   ---------- Threading options ----------
+   ---------------------------------------
+*/
+
+#define LWIP_TCPIP_CORE_LOCKING    1
+
+#if !NO_SYS
+void sys_check_core_locking(void);
+#define LWIP_ASSERT_CORE_LOCKED()  sys_check_core_locking()
+void sys_mark_tcpip_thread(void);
+#define LWIP_MARK_TCPIP_THREAD()   sys_mark_tcpip_thread()
+
+#if LWIP_TCPIP_CORE_LOCKING
+void sys_lock_tcpip_core(void);
+#define LOCK_TCPIP_CORE()          sys_lock_tcpip_core()
+void sys_unlock_tcpip_core(void);
+#define UNLOCK_TCPIP_CORE()        sys_unlock_tcpip_core()
+#endif
+#endif
+
+#endif /* LWIP_LWIPOPTS_H */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/ports/unix/port/include/arch/cc.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/ports/unix/port/include/arch/cc.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/ports/unix/port/include/arch/cc.h	(revision 457)
@@ -0,0 +1,86 @@
+/*
+ * Copyright (c) 2001-2003 Swedish Institute of Computer Science.
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission. 
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ * 
+ * Author: Adam Dunkels <adam@sics.se>
+ *
+ */
+#ifndef LWIP_ARCH_CC_H
+#define LWIP_ARCH_CC_H
+
+/* see https://sourceforge.net/p/predef/wiki/OperatingSystems/ */
+#if defined __ANDROID__
+#define LWIP_UNIX_ANDROID
+#elif defined __linux__
+#define LWIP_UNIX_LINUX
+#elif defined __APPLE__
+#define LWIP_UNIX_MACH
+#elif defined __OpenBSD__
+#define LWIP_UNIX_OPENBSD
+#elif defined __CYGWIN__
+#define LWIP_UNIX_CYGWIN
+#elif defined __GNU__
+#define LWIP_UNIX_HURD
+#endif
+
+#define LWIP_TIMEVAL_PRIVATE 0
+#include <sys/time.h>
+
+#define LWIP_ERRNO_INCLUDE <errno.h>
+
+#if defined(LWIP_UNIX_LINUX) || defined(LWIP_UNIX_HURD)
+#define LWIP_ERRNO_STDINCLUDE	1
+#endif
+
+#define LWIP_RAND() ((u32_t)rand())
+
+/* different handling for unit test, normally not needed */
+#ifdef LWIP_NOASSERT_ON_ERROR
+#define LWIP_ERROR(message, expression, handler) do { if (!(expression)) { \
+  handler;}} while(0)
+#endif
+
+#if defined(LWIP_UNIX_ANDROID) && defined(FD_SET)
+typedef __kernel_fd_set fd_set;
+#endif
+
+#if defined(LWIP_UNIX_MACH)
+/* sys/types.h and signal.h bring in Darwin byte order macros. pull the
+   header here and disable LwIP's version so that apps still can get
+   the macros via LwIP headers and use system headers */
+#include <sys/types.h>
+#define LWIP_DONT_PROVIDE_BYTEORDER_FUNCTIONS
+#endif
+
+struct sio_status_s;
+typedef struct sio_status_s sio_status_t;
+#define sio_fd_t sio_status_t*
+#define __sio_fd_t_defined
+
+typedef unsigned int sys_prot_t;
+
+#endif /* LWIP_ARCH_CC_H */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/ports/unix/port/include/arch/perf.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/ports/unix/port/include/arch/perf.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/ports/unix/port/include/arch/perf.h	(revision 457)
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2001-2003 Swedish Institute of Computer Science.
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission. 
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ * 
+ * Author: Adam Dunkels <adam@sics.se>
+ *
+ */
+#ifndef LWIP_ARCH_PERF_H
+#define LWIP_ARCH_PERF_H
+
+#include <sys/times.h>
+
+#ifdef PERF
+#define PERF_START  { \
+                         unsigned long __c1l, __c1h, __c2l, __c2h; \
+                         __asm__(".byte 0x0f, 0x31" : "=a" (__c1l), "=d" (__c1h))
+#define PERF_STOP(x)   __asm__(".byte 0x0f, 0x31" : "=a" (__c2l), "=d" (__c2h)); \
+                       perf_print(__c1l, __c1h, __c2l, __c2h, x);}
+
+/*#define PERF_START do { \
+                     struct tms __perf_start, __perf_end; \
+                     times(&__perf_start)
+#define PERF_STOP(x) times(&__perf_end); \
+                     perf_print_times(&__perf_start, &__perf_end, x);\
+                     } while(0)*/
+#else /* PERF */
+#define PERF_START    /* null definition */
+#define PERF_STOP(x)  /* null definition */
+#endif /* PERF */
+
+void perf_print(unsigned long c1l, unsigned long c1h,
+		unsigned long c2l, unsigned long c2h,
+		char *key);
+
+void perf_print_times(struct tms *start, struct tms *end, char *key);
+
+void perf_init(char *fname);
+
+#endif /* LWIP_ARCH_PERF_H */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/ports/unix/port/include/arch/sys_arch.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/ports/unix/port/include/arch/sys_arch.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/ports/unix/port/include/arch/sys_arch.h	(revision 457)
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2001-2003 Swedish Institute of Computer Science.
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission. 
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ * 
+ * Author: Adam Dunkels <adam@sics.se>
+ *
+ */
+#ifndef LWIP_ARCH_SYS_ARCH_H
+#define LWIP_ARCH_SYS_ARCH_H
+
+#define SYS_MBOX_NULL NULL
+#define SYS_SEM_NULL  NULL
+
+/*typedef u32_t sys_prot_t;*/
+
+struct sys_sem;
+typedef struct sys_sem * sys_sem_t;
+#define sys_sem_valid(sem)             (((sem) != NULL) && (*(sem) != NULL))
+#define sys_sem_valid_val(sem)         ((sem) != NULL)
+#define sys_sem_set_invalid(sem)       do { if((sem) != NULL) { *(sem) = NULL; }}while(0)
+#define sys_sem_set_invalid_val(sem)   do { (sem) = NULL; }while(0)
+
+struct sys_mutex;
+typedef struct sys_mutex * sys_mutex_t;
+#define sys_mutex_valid(mutex)         sys_sem_valid(mutex)
+#define sys_mutex_set_invalid(mutex)   sys_sem_set_invalid(mutex)
+
+struct sys_mbox;
+typedef struct sys_mbox * sys_mbox_t;
+#define sys_mbox_valid(mbox)           sys_sem_valid(mbox)
+#define sys_mbox_valid_val(mbox)       sys_sem_valid_val(mbox)
+#define sys_mbox_set_invalid(mbox)     sys_sem_set_invalid(mbox)
+#define sys_mbox_set_invalid_val(mbox) sys_sem_set_invalid_val(mbox)
+
+struct sys_thread;
+typedef struct sys_thread * sys_thread_t;
+
+#endif /* LWIP_ARCH_SYS_ARCH_H */
+
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/ports/unix/port/include/netif/fifo.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/ports/unix/port/include/netif/fifo.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/ports/unix/port/include/netif/fifo.h	(revision 457)
@@ -0,0 +1,54 @@
+#ifndef FIFO_H
+#define FIFO_H
+
+#include "lwip/sys.h"
+
+/** How many bytes in fifo */
+#define FIFOSIZE 2048
+
+/** fifo data structure, this one is passed to all fifo functions */
+typedef struct fifo_t {
+  u8_t data[FIFOSIZE+10]; /* data segment, +10 is a hack probably not needed.. FIXME! */
+  int dataslot;			  /* index to next char to be read */
+  int emptyslot;		  /* index to next empty slot */
+  int len;				  /* len probably not needed, may be calculated from dataslot and emptyslot in conjunction with FIFOSIZE */
+
+  sys_sem_t sem;		/* semaphore protecting simultaneous data manipulation */
+  sys_sem_t getSem;		/* sepaphore used to signal new data if getWaiting is set */
+  u8_t getWaiting;		/* flag used to indicate that fifoget is waiting for data. fifoput is suposed to clear */
+  						/* this flag prior to signaling the getSem semaphore */
+} fifo_t;
+
+
+/**
+*   Get a character from fifo
+*   Blocking call.
+*	@param 	fifo pointer to fifo data structure
+*	@return	character read from fifo
+*/
+u8_t fifoGet(fifo_t * fifo);
+
+/**
+*   Get a character from fifo
+*   Non blocking call.
+*	@param 	fifo pointer to fifo data structure
+*	@return	character read from fifo, or < zero if non was available
+*/
+s16_t fifoGetNonBlock(fifo_t * fifo);
+
+/**
+*	fifoput is called by the signalhandler when new data has arrived (or some other event is indicated)
+*   fifoput reads directly from the serialport and is thus highly dependent on unix arch at this moment
+*	@param 	fifo pointer to fifo data structure
+*	@param	fd	unix file descriptor
+*/
+void fifoPut(fifo_t * fifo, int fd);
+
+/**
+*   fifoinit initiate fifo
+*	@param 	fifo	pointer to fifo data structure, allocated by the user
+*/
+void fifoInit(fifo_t * fifo);
+
+#endif
+
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/ports/unix/port/include/netif/list.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/ports/unix/port/include/netif/list.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/ports/unix/port/include/netif/list.h	(revision 457)
@@ -0,0 +1,26 @@
+
+#ifndef LWIP_LIST_H
+#define LWIP_LIST_H
+
+struct elem;
+
+struct list {
+  struct elem *first, *last;
+  int size, elems;
+};
+
+struct elem {
+  struct elem *next;
+  void *data;
+};
+
+struct list *list_new(int size);
+int list_push(struct list *list, void *data);
+void *list_pop(struct list *list);
+void *list_first(struct list *list);
+int list_elems(struct list *list);
+void list_delete(struct list *list);
+int list_remove(struct list *list, void *elem);
+void list_map(struct list *list, void (* func)(void *arg));
+
+#endif
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/ports/unix/port/include/netif/pcapif.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/ports/unix/port/include/netif/pcapif.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/ports/unix/port/include/netif/pcapif.h	(revision 457)
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2001-2003 Swedish Institute of Computer Science.
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission. 
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ * 
+ * Author: Adam Dunkels <adam@sics.se>
+ *
+ */
+#ifndef LWIP_PCAPIF_H
+#define LWIP_PCAPIF_H
+
+#include "lwip/netif.h"
+
+err_t pcapif_init(struct netif *netif);
+
+#endif /* LWIP_PCAPIF_H */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/ports/unix/port/include/netif/sio.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/ports/unix/port/include/netif/sio.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/ports/unix/port/include/netif/sio.h	(revision 457)
@@ -0,0 +1,60 @@
+#ifndef SIO_UNIX_H
+#define SIO_UNIX_H
+
+#include "lwip/sys.h"
+#include "lwip/netif.h"
+#include "netif/fifo.h"
+/*#include "netif/pppif.h"*/
+
+struct sio_status_s {
+	int fd;
+	fifo_t myfifo;
+};
+
+/* BAUDRATE is defined in sio.c as it is implementation specific */
+/** Baudrates */
+typedef enum sioBaudrates {
+	SIO_BAUD_9600,
+	SIO_BAUD_19200,
+	SIO_BAUD_38400,
+	SIO_BAUD_57600,	
+	SIO_BAUD_115200	
+} sioBaudrates;
+
+/**
+* Poll for a new character from incoming data stream
+* @param 	siostat siostatus struct, contains sio instance data, given by sio_open
+* @return 	char read from input stream, or < 0 if no char was available
+*/
+s16_t sio_poll(sio_status_t * siostat);
+
+/**
+*	Parse incoming characters until a string str is recieved, blocking call
+* @param	str		zero terminated string to expect
+* @param 	siostat siostatus struct, contains sio instance data, given by sio_open
+*/
+void sio_expect_string(u8_t *str, sio_status_t * siostat);
+
+/**
+* Write a char to output data stream
+* @param 	str		pointer to a zero terminated string
+* @param	siostat siostatus struct, contains sio instance data, given by sio_open
+*/
+void sio_send_string(u8_t *str, sio_status_t * siostat);
+
+/**
+*	Flush outbuffer (send everything in buffer now), useful if some layer below is 
+*	holding on to data, waitng to fill a buffer
+* @param 	siostat siostatus struct, contains sio instance data, given by sio_open
+*/
+void sio_flush( sio_status_t * siostat );
+
+/**
+*	Change baudrate of port, may close and reopen port
+* @param 	baud	new baudrate
+* @param 	siostat siostatus struct, contains sio instance data, given by sio_open
+*/
+void sio_change_baud( sioBaudrates baud, sio_status_t * siostat );
+
+#endif
+
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/ports/unix/port/include/netif/tapif.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/ports/unix/port/include/netif/tapif.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/ports/unix/port/include/netif/tapif.h	(revision 457)
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2001-2003 Swedish Institute of Computer Science.
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Adam Dunkels <adam@sics.se>
+ *
+ */
+#ifndef LWIP_TAPIF_H
+#define LWIP_TAPIF_H
+
+#include "lwip/netif.h"
+
+err_t tapif_init(struct netif *netif);
+void tapif_poll(struct netif *netif);
+#if NO_SYS
+int tapif_select(struct netif *netif);
+#endif /* NO_SYS */
+
+#endif /* LWIP_TAPIF_H */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/ports/unix/port/netif/fifo.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/ports/unix/port/netif/fifo.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/ports/unix/port/netif/fifo.c	(revision 457)
@@ -0,0 +1,139 @@
+/* Author: Magnus Ivarsson <magnus.ivarsson@volvo.com> */
+
+/* ---------------------------------------------- */
+/* --- fifo 4 unix ------------------------------ */
+/* ---------------------------------------------- */
+#include "lwip/err.h"
+#include "netif/fifo.h"
+#include "lwip/debug.h"
+#include "lwip/def.h"
+#include "lwip/sys.h"
+#include "lwip/arch.h"
+#include <unistd.h>
+
+#ifndef TRUE
+#define TRUE  1
+#endif
+#ifndef FALSE
+#define FALSE 0
+#endif
+
+#ifndef SIO_FIFO_DEBUG
+#define SIO_FIFO_DEBUG LWIP_DBG_OFF
+#endif
+
+u8_t fifoGet(fifo_t * fifo) 
+{
+	u8_t c;
+
+	sys_sem_wait(&fifo->sem);      /* enter critical section */
+
+	if (fifo->dataslot == fifo->emptyslot) 
+	{
+            fifo->getWaiting = TRUE;    /* tell putFifo to signal us when data is available */
+            sys_sem_signal(&fifo->sem);  /* leave critical section (allow input from serial port..) */
+            sys_sem_wait(&fifo->getSem); /* wait 4 data */
+            sys_sem_wait(&fifo->sem);    /* reenter critical section */
+	}
+
+	c = fifo->data[fifo->dataslot++];
+	fifo->len--;
+
+	if (fifo->dataslot == FIFOSIZE) 
+	{
+		fifo->dataslot = 0; 
+	}
+	sys_sem_signal(&fifo->sem);    /* leave critical section */
+	return c;
+}
+
+
+s16_t fifoGetNonBlock(fifo_t * fifo) 
+{
+	u16_t c;
+
+	sys_sem_wait(&fifo->sem);      /* enter critical section */
+
+	if (fifo->dataslot == fifo->emptyslot) 
+	{
+            /* empty fifo */
+		c = -1;
+	}
+	else
+	{
+		c = fifo->data[fifo->dataslot++];
+		fifo->len--;
+
+		if (fifo->dataslot == FIFOSIZE) 
+		{
+			fifo->dataslot = 0; 
+		}
+	}
+	sys_sem_signal(&fifo->sem);    /* leave critical section */
+	return c;
+}
+
+
+void fifoPut(fifo_t * fifo, int fd) 
+{
+	/* FIXME: mutex around struct data.. */
+	int cnt=0;
+
+	sys_sem_wait(&fifo->sem ); /* enter critical */
+
+	LWIP_DEBUGF( SIO_FIFO_DEBUG,("fifoput: len%d dat%d empt%d --> ", fifo->len, fifo->dataslot, fifo->emptyslot ) );
+
+	if ( fifo->emptyslot < fifo->dataslot )
+	{
+		cnt = read( fd, &fifo->data[fifo->emptyslot], fifo->dataslot - fifo->emptyslot );
+	} 
+	else
+	{
+		cnt = read( fd, &fifo->data[fifo->emptyslot], FIFOSIZE-fifo->emptyslot );
+	}
+	fifo->emptyslot += cnt;
+	fifo->len += cnt;
+
+	LWIP_DEBUGF( SIO_FIFO_DEBUG,("len%d dat%d empt%d\n", fifo->len, fifo->dataslot, fifo->emptyslot ) );
+
+	if ( fifo->len > FIFOSIZE )
+	{
+		printf( "ERROR: fifo overrun detected len=%d, flushing\n", fifo->len );
+		fifo->dataslot  = 0;
+		fifo->emptyslot = 0;
+		fifo->len = 0;
+	}
+
+	if ( fifo->emptyslot == FIFOSIZE )
+	{
+		fifo->emptyslot = 0;
+		LWIP_DEBUGF( SIO_FIFO_DEBUG, ("(WRAP) ") );
+
+		sys_sem_signal(&fifo->sem ); /* leave critical */
+		fifoPut( fifo, fd );
+		return;
+	}
+	if ( fifo->getWaiting )
+	{
+		fifo->getWaiting = FALSE;
+		sys_sem_signal(&fifo->getSem );
+	}
+
+	sys_sem_signal(&fifo->sem ); /* leave critical */
+	return;
+}
+
+
+void fifoInit(fifo_t * fifo)
+{
+  fifo->dataslot  = 0;
+  fifo->emptyslot = 0;
+  fifo->len       = 0;
+  if(sys_sem_new(&fifo->sem, 1) != ERR_OK) {  /* critical section 1=free to enter */
+    LWIP_ASSERT("Failed to create semaphore", 0);
+  }
+  if(sys_sem_new(&fifo->getSem, 0) != ERR_OK) {  /* 0 = no one waiting */
+    LWIP_ASSERT("Failed to create semaphore", 0);
+  }
+  fifo->getWaiting = FALSE;
+}
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/ports/unix/port/netif/list.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/ports/unix/port/netif/list.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/ports/unix/port/netif/list.c	(revision 457)
@@ -0,0 +1,153 @@
+/*
+ * Copyright (c) 2001-2003 Swedish Institute of Computer Science.
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission. 
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ * 
+ * Author: Adam Dunkels <adam@sics.se>
+ *
+ */
+
+
+
+#include <stdlib.h>
+#include <netif/list.h>
+
+
+/*-----------------------------------------------------------------------------------*/
+struct list *
+list_new(int size)
+{
+  struct list *list;
+  list = (struct list *)malloc(sizeof(struct list));
+  list->first = list->last = NULL;
+  list->size = size;
+  list->elems = 0;
+  return list;
+}
+/*-----------------------------------------------------------------------------------*/
+int
+list_push(struct list *list, void *data)
+{
+  struct elem *elem;
+
+  if (list->elems < list->size) {
+    elem = (struct elem *)malloc(sizeof(struct elem));
+    elem->data = data;
+    elem->next = NULL;
+    if (list->last != NULL) {
+      list->last->next = elem;
+    }
+    list->last = elem;
+    if (list->first == NULL) {
+      list->first = elem;
+    }
+    list->elems++;
+    return 1;
+  }
+  return 0;
+}
+/*-----------------------------------------------------------------------------------*/
+void *
+list_pop(struct list *list)
+{
+  struct elem *elem;
+  void *data;
+
+  if (list->elems > 0) {
+    elem = list->first;
+    if (elem == list->last) {
+      list->last = elem->next;
+    }
+    list->first = elem->next;
+
+    list->elems--;
+
+    data = elem->data;
+    free(elem);
+
+    return data;
+  }
+  return NULL;
+}
+/*-----------------------------------------------------------------------------------*/
+void *
+list_first(struct list *list)
+{
+  return list->first;
+}
+/*-----------------------------------------------------------------------------------*/
+int
+list_elems(struct list *list)
+{
+  return list->elems;
+}
+/*-----------------------------------------------------------------------------------*/
+void
+list_delete(struct list *list)
+{
+  while (list_pop(list) != NULL);
+  free(list);
+}
+/*-----------------------------------------------------------------------------------*/
+int
+list_remove(struct list *list, void *elem)
+{
+  struct elem *e, *p;
+
+  p = NULL;
+  for(e = list->first; e != NULL; e = e->next) {
+    if (e->data == elem) {
+      if (p != NULL) {
+        p->next = e->next;
+      } else {
+        list->first = e->next;
+      }
+      if (list->last == e) {
+        list->last = p;
+        if (p != NULL) {
+          p->next = NULL;
+        }
+      }
+      free(e);
+      list->elems--;
+      return 1;
+    }
+    p = e;
+  }
+  return 0;
+}
+/*-----------------------------------------------------------------------------------*/
+void
+list_map(struct list *list, void (* func)(void *arg))
+{
+  struct elem *e;
+
+  for(e = list->first; e != NULL; e = e->next) {
+    func(e->data);
+  }
+}
+/*-----------------------------------------------------------------------------------*/
+
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/ports/unix/port/netif/pcapif.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/ports/unix/port/netif/pcapif.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/ports/unix/port/netif/pcapif.c	(revision 457)
@@ -0,0 +1,207 @@
+/*
+ * Copyright (c) 2001-2003 Swedish Institute of Computer Science.
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission. 
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ * 
+ * Author: Adam Dunkels <adam@sics.se>
+ *
+ */
+
+#ifndef linux  /* Apparently, this doesn't work under Linux. */
+
+#include "lwip/debug.h"
+
+#include <fcntl.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/uio.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <sys/stat.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+
+#include <pcap.h>
+
+#include "netif/etharp.h"
+
+#include "lwip/stats.h"
+
+#include "lwip/def.h"
+#include "lwip/mem.h"
+#include "lwip/pbuf.h"
+#include "lwip/sys.h"
+
+#include "lwip/ip.h"
+
+
+struct pcapif {
+  pcap_t *pd;
+  sys_sem_t sem;
+  u8_t pkt[2048];
+  u32_t len;
+  u32_t lasttime;
+  struct pbuf *p;
+  struct eth_addr *ethaddr;
+};
+
+static char errbuf[PCAP_ERRBUF_SIZE];
+
+/*-----------------------------------------------------------------------------------*/
+static err_t
+pcapif_output(struct netif *netif, struct pbuf *p,
+	      ip_addr_t *ipaddr)
+{
+  return ERR_OK;
+}
+/*-----------------------------------------------------------------------------------*/
+static void
+timeout(void *arg)
+{
+  struct netif *netif;
+  struct pcapif *pcapif;
+  struct pbuf *p;
+  struct eth_hdr *ethhdr;
+  
+  netif = (struct netif *)arg;
+  pcapif = netif->state;
+  ethhdr = (struct eth_hdr *)pcapif->pkt;
+
+  
+  if (lwip_htons(ethhdr->type) != ETHTYPE_IP ||
+     ip_lookup(pcapif->pkt + 14, netif)) {
+    
+    /* We allocate a pbuf chain of pbufs from the pool. */
+    p = pbuf_alloc(PBUF_LINK, pcapif->len, PBUF_POOL);
+    
+    if (p != NULL) {
+      pbuf_take(p, pcapif->pkt, pcapif->len);
+
+      ethhdr = p->payload;
+      switch (lwip_htons(ethhdr->type)) {
+      /* IP or ARP packet? */
+      case ETHTYPE_IP:
+      case ETHTYPE_ARP:
+#if PPPOE_SUPPORT
+      /* PPPoE packet? */
+      case ETHTYPE_PPPOEDISC:
+      case ETHTYPE_PPPOE:
+#endif /* PPPOE_SUPPORT */
+        /* full packet send to tcpip_thread to process */
+        if (netif->input(p, netif) != ERR_OK) {
+          LWIP_DEBUGF(NETIF_DEBUG, ("ethernetif_input: IP input error\n"));
+          pbuf_free(p);
+          p = NULL;
+        }
+        break;
+      default:
+        pbuf_free(p);
+        break;
+      }
+    }
+  } else {
+    printf("ip_lookup dropped\n");
+  }
+
+  sys_sem_signal(&pcapif->sem);
+}
+/*-----------------------------------------------------------------------------------*/
+static void
+callback(u_char *arg, const struct pcap_pkthdr *hdr, const u_char *pkt)
+{
+  struct netif *netif;
+  struct pcapif *pcapif;
+  u32_t time, lasttime;
+  
+  netif = (struct netif *)arg;
+  pcapif = netif->state;
+
+  pcapif->len = hdr->len;
+  
+  bcopy(pkt, pcapif->pkt, hdr->len);
+
+  time = hdr->ts.tv_sec * 1000 + hdr->ts.tv_usec / 1000;
+
+  lasttime = pcapif->lasttime;
+  pcapif->lasttime = time;
+  
+
+  if (lasttime == 0) {
+    sys_timeout(1000, timeout, netif);
+  } else {
+    sys_timeout(time - lasttime, timeout, netif);
+  }
+}
+/*-----------------------------------------------------------------------------------*/
+static void
+pcapif_thread(void *arg)
+{
+  struct netif *netif;
+  struct pcapif *pcapif;
+  netif = arg;
+  pcapif = netif->state;
+
+  while (1) {
+    pcap_loop(pcapif->pd, 1, callback, (u_char *)netif);
+    sys_sem_wait(&pcapif->sem);
+    if (pcapif->p != NULL) {
+      netif->input(pcapif->p, netif);
+    }
+  }
+}
+/*-----------------------------------------------------------------------------------*/
+err_t
+pcapif_init(struct netif *netif)
+{
+  struct pcapif *p;
+    
+  p = malloc(sizeof(struct pcapif));
+  if (p == NULL)
+      return ERR_MEM;
+  netif->state = p;
+  netif->name[0] = 'p';
+  netif->name[1] = 'c';
+  netif->output = pcapif_output;
+
+  p->pd = pcap_open_offline("pcapdump", errbuf);
+  if (p->pd == NULL) {
+    printf("pcapif_init: failed %s\n", errbuf);
+    return ERR_IF;
+  }
+
+  if(sys_sem_new(&p->sem, 0) != ERR_OK) {
+    LWIP_ASSERT("Failed to create semaphore", 0);
+  }
+  p->p = NULL;
+  p->lasttime = 0; 
+  
+  sys_thread_new("pcapif_thread", pcapif_thread, netif, DEFAULT_THREAD_STACKSIZE, DEFAULT_THREAD_PRIO);
+  return ERR_OK;
+}
+/*-----------------------------------------------------------------------------------*/
+#endif /* linux */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/ports/unix/port/netif/sio.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/ports/unix/port/netif/sio.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/ports/unix/port/netif/sio.c	(revision 457)
@@ -0,0 +1,489 @@
+/* Author: Magnus Ivarsson <magnus.ivarsson@volvo.com> */
+
+/* to get rid of implicit function declarations */
+#define _XOPEN_SOURCE 600
+#define _GNU_SOURCE
+
+/* build with Darwin C extensions not part of POSIX, i.e. FASYNC, SIGIO.
+   we can't use LWIP_UNIX_MACH because extensions need to be turned
+   on before any system headers (which are pulled in through cc.h)
+   are included */
+#if defined(__APPLE__)
+#define _DARWIN_C_SOURCE
+#endif
+
+#include "netif/sio.h"
+#include "netif/fifo.h"
+#include "lwip/debug.h"
+#include "lwip/def.h"
+#include "lwip/sys.h"
+#include "lwip/arch.h"
+#include "lwip/sio.h"
+#include "netif/ppp/ppp_opts.h"
+
+/* Following #undefs are here to keep compiler from issuing warnings
+   about them being double defined. (They are defined in lwip/inet.h
+   as well as the Unix #includes below.) */
+#undef htonl
+#undef ntohl
+#undef htons
+#undef ntohs
+#undef HTONL
+#undef NTOHL
+#undef HTONS
+#undef NTOHS
+
+#include <stdlib.h>
+#include <stdio.h>
+#if defined(LWIP_UNIX_OPENBSD)
+#include <util.h>
+#endif
+#include <termios.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <signal.h>
+#include <string.h>
+#include <sys/signal.h>
+#include <sys/types.h>
+
+#ifndef LWIP_HAVE_SLIPIF
+#define LWIP_HAVE_SLIPIF 0
+#endif
+
+#if (PPP_SUPPORT || LWIP_HAVE_SLIPIF) && defined(LWIP_UNIX_LINUX)
+#include <pty.h>
+#endif
+
+/*#define BAUDRATE B19200 */
+/*#define BAUDRATE B57600 */
+#define BAUDRATE B115200
+
+#ifndef TRUE
+#define TRUE  1
+#endif
+#ifndef FALSE
+#define FALSE 0
+#endif
+
+/* for all of you who dont define SIO_DEBUG in debug.h */
+#ifndef SIO_DEBUG
+#define SIO_DEBUG 0
+#endif
+
+
+/*  typedef struct siostruct_t */
+/*  {  */
+/*  	sio_status_t *sio; */
+/*  } siostruct_t; */
+
+/** array of ((siostruct*)netif->state)->sio structs */
+static sio_status_t statusar[4];
+
+#if ! (PPP_SUPPORT || LWIP_HAVE_SLIPIF)
+/* --private-functions----------------------------------------------------------------- */
+/** 
+ * Signal handler for ttyXX0 to indicate bytes received 
+ * one per interface is needed since we cannot send a instance number / pointer as callback argument (?)
+ */
+static void	signal_handler_IO_0( int status )
+{
+	LWIP_UNUSED_ARG(status);
+	LWIP_DEBUGF(SIO_DEBUG, ("SigHand: rxSignal channel 0\n"));
+	fifoPut( &statusar[0].myfifo, statusar[0].fd );
+}
+
+/**
+ * Signal handler for ttyXX1 to indicate bytes received 
+ * one per interface is needed since we cannot send a instance number / pointer as callback argument (?)
+ */
+static void signal_handler_IO_1( int status )
+{
+	LWIP_UNUSED_ARG(status);
+	LWIP_DEBUGF(SIO_DEBUG, ("SigHand: rxSignal channel 1\n"));
+	fifoPut( &statusar[1].myfifo, statusar[1].fd );
+}
+#endif /* ! (PPP_SUPPORT || LWIP_HAVE_SLIPIF) */
+
+/**
+* Initiation of serial device 
+* @param device string with the device name and path, eg. "/dev/ttyS0"
+* @param devnum device number
+* @param siostat status
+* @return file handle to serial dev.
+*/
+static int sio_init( char * device, int devnum, sio_status_t * siostat )
+{
+	struct termios oldtio,newtio;
+#if ! (PPP_SUPPORT || LWIP_HAVE_SLIPIF)
+	struct sigaction saio;           /* definition of signal action */
+#endif
+	int fd;
+	LWIP_UNUSED_ARG(siostat);
+	LWIP_UNUSED_ARG(devnum);
+
+	/* open the device to be non-blocking (read will return immediately) */
+	fd = open( device, O_RDWR | O_NOCTTY | O_NONBLOCK );
+	if ( fd < 0 )
+	{
+		perror( device );
+		exit( -1 );
+	}
+
+#if ! (PPP_SUPPORT || LWIP_HAVE_SLIPIF)
+	/* install the signal handler before making the device asynchronous */
+	switch ( devnum )
+	{
+		case 0:
+			LWIP_DEBUGF( SIO_DEBUG, ("sioinit, signal_handler_IO_0\n") );
+			saio.sa_handler = signal_handler_IO_0;
+			break;
+		case 1:
+			LWIP_DEBUGF( SIO_DEBUG, ("sioinit, signal_handler_IO_1\n") );
+			saio.sa_handler = signal_handler_IO_1;
+			break;
+		default:
+			LWIP_DEBUGF( SIO_DEBUG,("sioinit, devnum not allowed\n") );
+			break;
+	}
+
+	saio.sa_flags = 0;
+#if defined(LWIP_UNIX_LINUX)
+	saio.sa_restorer = NULL;
+#endif /* LWIP_UNIX_LINUX */
+	sigaction( SIGIO,&saio,NULL );
+
+	/* allow the process to receive SIGIO */
+       	if ( fcntl( fd, F_SETOWN, getpid( ) ) != 0)
+	{
+		perror( device );
+		exit( -1 );
+	}
+	/* Make the file descriptor asynchronous (the manual page says only
+	O_APPEND and O_NONBLOCK, will work with F_SETFL...) */
+       	if ( fcntl( fd, F_SETFL, FASYNC ) != 0)
+	{
+		perror( device );
+		exit( -1 );
+	}
+#else
+       	if ( fcntl( fd, F_SETFL, 0 ) != 0)
+	{
+		perror( device );
+		exit( -1 );
+	}
+
+#endif /* ! (PPP_SUPPORT || LWIP_HAVE_SLIPIF) */
+
+	tcgetattr( fd,&oldtio ); /* save current port settings */
+	/* set new port settings */
+	/* see 'man termios' for further settings */
+        memset(&newtio, 0, sizeof(newtio));
+	newtio.c_cflag = BAUDRATE | CS8 | CLOCAL | CREAD | CRTSCTS;
+	newtio.c_iflag = 0;
+	newtio.c_oflag = 0;
+	newtio.c_lflag = 0; /*ECHO; */
+	newtio.c_cc[VMIN] = 1; /* Read 1 byte at a time, no timer */
+	newtio.c_cc[VTIME] = 0;
+
+	tcsetattr( fd,TCSANOW,&newtio );
+	tcflush( fd, TCIOFLUSH );
+
+	return fd;
+}
+
+/**
+*
+*/
+static void sio_speed( int fd, int speed )
+{
+	struct termios oldtio,newtio;
+	/*  int fd; */
+
+	LWIP_DEBUGF(SIO_DEBUG, ("sio_speed[%d]: baudcode:%d enter\n", fd, speed));
+
+	if ( fd < 0 )
+	{
+		LWIP_DEBUGF(SIO_DEBUG, ("sio_speed[%d]: fd ERROR\n", fd));
+		exit( -1 );
+	}
+
+	tcgetattr( fd,&oldtio ); /* get current port settings */
+
+	/* set new port settings 
+	* see 'man termios' for further settings */
+        memset(&newtio, 0, sizeof(newtio));
+	newtio.c_cflag = speed | CS8 | CLOCAL | CREAD; /* | CRTSCTS; */
+	newtio.c_iflag = 0;
+	newtio.c_oflag = 0;
+	newtio.c_lflag = 0; /*ECHO; */
+	newtio.c_cc[VMIN] = 1; /* Read 1 byte at a time, no timer */
+	newtio.c_cc[VTIME] = 0;
+
+	tcsetattr( fd,TCSANOW,&newtio );
+	tcflush( fd, TCIOFLUSH );
+
+	LWIP_DEBUGF(SIO_DEBUG, ("sio_speed[%d]: leave\n", fd));
+}
+
+/* --public-functions----------------------------------------------------------------------------- */
+void sio_send( u8_t c, sio_status_t * siostat )
+{
+    /*	sio_status_t * siostat = ((siostruct_t*)netif->state)->sio; */
+
+	if ( write( siostat->fd, &c, 1 ) <= 0 )
+	{
+		LWIP_DEBUGF(SIO_DEBUG, ("sio_send[%d]: write refused\n", siostat->fd));
+	}
+}
+
+void sio_send_string( u8_t *str, sio_status_t * siostat )
+{
+    /*	sio_status_t * siostat = ((siostruct_t*)netif->state)->sio; */
+	int len = strlen( (const char *)str );
+
+	if ( write( siostat->fd, str, len ) <= 0 )
+	{
+		LWIP_DEBUGF(SIO_DEBUG, ("sio_send_string[%d]: write refused\n", siostat->fd));
+	}
+	LWIP_DEBUGF(SIO_DEBUG, ("sio_send_string[%d]: sent: %s\n", siostat->fd, str));
+}
+
+
+void sio_flush( sio_status_t * siostat )
+{
+	LWIP_UNUSED_ARG(siostat);
+	/* not implemented in unix as it is not needed */
+ 	/*sio_status_t * siostat = ((siostruct_t*)netif->state)->sio; */
+}
+
+
+#if ! (PPP_SUPPORT || LWIP_HAVE_SLIPIF)
+/*u8_t sio_recv( struct netif * netif )*/
+u8_t sio_recv( sio_status_t * siostat )
+{
+    /*	sio_status_t * siostat = ((siostruct_t*)netif->state)->sio; */
+	return fifoGet( &(siostat->myfifo) );
+}
+
+s16_t sio_poll(sio_status_t * siostat)
+{
+    /*	sio_status_t * siostat = ((siostruct_t*)netif->state)->sio;*/
+	return fifoGetNonBlock( &(siostat->myfifo) );
+}
+
+
+void sio_expect_string( u8_t *str, sio_status_t * siostat )
+{
+    /*	sio_status_t * siostat = ((siostruct_t*)netif->state)->sio;*/
+	u8_t c;
+ 	int finger=0;
+  
+	LWIP_DEBUGF(SIO_DEBUG, ("sio_expect_string[%d]: %s\n", siostat->fd, str));
+	while ( 1 )
+	{
+		c=fifoGet( &(siostat->myfifo) );
+		LWIP_DEBUGF(SIO_DEBUG, ("_%c", c));
+		if ( c==str[finger] )
+		{
+			finger++;
+		} else if ( finger > 0 )
+		{
+                    /*it might fit in the beginning? */
+			if ( str[0] == c )
+			{
+				finger = 1;
+			}
+		}
+		if ( 0 == str[finger] ) 
+                    break;	/* done, we have a match */
+	}
+	LWIP_DEBUGF(SIO_DEBUG, ("sio_expect_string[%d]: [match]\n", siostat->fd));
+}
+#endif /* ! (PPP_SUPPORT || LWIP_HAVE_SLIPIF) */
+
+#if (PPP_SUPPORT || LWIP_HAVE_SLIPIF)
+u32_t sio_write(sio_status_t * siostat, u8_t *buf, u32_t size)
+{
+    ssize_t wsz = write( siostat->fd, buf, size );
+    return wsz < 0 ? 0 : wsz;
+}
+
+u32_t sio_read(sio_status_t * siostat, u8_t *buf, u32_t size)
+{
+    ssize_t rsz = read( siostat->fd, buf, size );
+    return rsz < 0 ? 0 : rsz;
+}
+
+void sio_read_abort(sio_status_t * siostat)
+{
+    LWIP_UNUSED_ARG(siostat);
+    printf("sio_read_abort[%d]: not yet implemented for unix\n", siostat->fd);
+}
+#endif /* (PPP_SUPPORT || LWIP_HAVE_SLIPIF) */
+
+sio_fd_t sio_open(u8_t devnum)
+{
+	char dev[20];
+
+	/* would be nice with dynamic memory alloc */
+	sio_status_t * siostate = &statusar[ devnum ];
+/* 	siostruct_t * tmp; */
+
+
+/* 	tmp = (siostruct_t*)(netif->state); */
+/* 	tmp->sio = siostate; */
+
+/* 	tmp = (siostruct_t*)(netif->state); */
+
+/* 	((sio_status_t*)(tmp->sio))->fd = 0; */
+
+	LWIP_DEBUGF(SIO_DEBUG, ("sio_open: for devnum %d\n", devnum));
+
+#if ! (PPP_SUPPORT || LWIP_HAVE_SLIPIF)
+	fifoInit( &siostate->myfifo );
+#endif /* ! PPP_SUPPORT */
+
+	snprintf( dev, sizeof(dev), "/dev/ttyS%d", devnum );
+
+	if ( (devnum == 1) || (devnum == 0) )
+	{
+		if ( ( siostate->fd = sio_init( dev, devnum, siostate ) ) == 0 )
+		{
+			LWIP_DEBUGF(SIO_DEBUG, ("sio_open: ERROR opening serial device dev=%s\n", dev));
+			abort( );
+			return NULL;
+		}
+		LWIP_DEBUGF(SIO_DEBUG, ("sio_open[%d]: dev=%s open.\n", siostate->fd, dev));
+	} 
+#if PPP_SUPPORT
+	else if (devnum == 2) {
+	    pid_t childpid;
+	    char name[256];
+	    childpid = forkpty(&siostate->fd, name, NULL, NULL);
+	    if(childpid < 0) {
+		perror("forkpty");
+		exit (1);
+	    }
+	    if(childpid == 0) {
+		execl("/usr/sbin/pppd", "pppd",
+			"ms-dns", "198.168.100.7",
+			"local", "crtscts",
+			"debug",
+#ifdef LWIP_PPP_CHAP_TEST
+			"auth",
+			"require-chap",
+			"remotename", "lwip",
+#else
+			"noauth",
+#endif
+#if LWIP_IPV6
+			"+ipv6",
+#endif
+			"192.168.1.1:192.168.1.2",
+			NULL);
+		perror("execl pppd");
+		exit (1);
+	    } else {
+		LWIP_DEBUGF(SIO_DEBUG, ("sio_open[%d]: spawned pppd pid %d on %s\n",
+			siostate->fd, childpid, name));
+	    }
+
+	}
+#endif
+#if LWIP_HAVE_SLIPIF
+	else if (devnum == 3) {
+	    pid_t childpid;
+	    /* create PTY pair */
+	    siostate->fd = posix_openpt(O_RDWR | O_NOCTTY);
+	    if (siostate->fd < 0) {
+		perror("open pty master");
+		exit (1);
+	    }
+	    if (grantpt(siostate->fd) != 0) {
+		perror("grant pty master");
+		exit (1);
+	    }
+	    if (unlockpt(siostate->fd) != 0) {
+		perror("unlock pty master");
+		exit (1);
+	    }
+	    LWIP_DEBUGF(SIO_DEBUG, ("sio_open[%d]: for %s\n",
+		    siostate->fd, ptsname(siostate->fd)));
+	    /* fork for slattach */
+	    childpid = fork();
+	    if(childpid < 0) {
+		perror("fork");
+		exit (1);
+	    }
+	    if(childpid == 0) {
+		/* esteblish SLIP interface on host side connected to PTY slave */
+		execl("/sbin/slattach", "slattach",
+			"-d", "-v", "-L", "-p", "slip",
+			ptsname(siostate->fd),
+			NULL);
+		perror("execl slattach");
+		exit (1);
+	    } else {
+		int ret;
+		char buf[1024];
+		LWIP_DEBUGF(SIO_DEBUG, ("sio_open[%d]: spawned slattach pid %d on %s\n",
+			siostate->fd, childpid, ptsname(siostate->fd)));
+		/* wait a moment for slattach startup */
+		sleep(1);
+		/* configure SLIP interface on host side as P2P interface */
+		snprintf(buf, sizeof(buf),
+			"/sbin/ifconfig sl0 mtu %d %s pointopoint %s up",
+			SLIP_MAX_SIZE, "192.168.2.1", "192.168.2.2");
+		LWIP_DEBUGF(SIO_DEBUG, ("sio_open[%d]: system(\"%s\");\n", siostate->fd, buf));
+		ret = system(buf);
+		if (ret < 0) {
+		    perror("ifconfig failed");
+		    exit(1);
+		}
+	    }
+	}
+#endif /* LWIP_HAVE_SLIPIF */
+	else
+	{
+		LWIP_DEBUGF(SIO_DEBUG, ("sio_open: device %s (%d) is not supported\n", dev, devnum));
+		return NULL;
+	}
+
+	return siostate;
+}
+
+/**
+*
+*/
+void sio_change_baud( sioBaudrates baud, sio_status_t * siostat )
+{
+    /*	sio_status_t * siostat = ((siostruct_t*)netif->state)->sio;*/
+
+	LWIP_DEBUGF(SIO_DEBUG, ("sio_change_baud[%d]\n", siostat->fd));
+
+	switch ( baud )
+	{
+		case SIO_BAUD_9600:
+			sio_speed( siostat->fd, B9600 );
+			break;
+		case SIO_BAUD_19200:
+			sio_speed( siostat->fd, B19200 );
+			break;
+		case SIO_BAUD_38400:
+			sio_speed( siostat->fd, B38400 );
+			break;
+		case SIO_BAUD_57600:
+			sio_speed( siostat->fd, B57600 );
+			break;
+		case SIO_BAUD_115200:
+			sio_speed( siostat->fd, B115200 );
+			break;
+
+		default:
+			LWIP_DEBUGF(SIO_DEBUG, ("sio_change_baud[%d]: Unknown baudrate, code:%d\n",
+					siostat->fd, baud));
+			break;
+	}
+}
+
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/ports/unix/port/netif/tapif.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/ports/unix/port/netif/tapif.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/ports/unix/port/netif/tapif.c	(revision 457)
@@ -0,0 +1,432 @@
+/*
+ * Copyright (c) 2001-2003 Swedish Institute of Computer Science.
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Adam Dunkels <adam@sics.se>
+ *
+ */
+
+#include <fcntl.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <string.h>
+#include <sys/ioctl.h>
+#include <sys/socket.h>
+#include <sys/types.h>
+#include <sys/time.h>
+#include <sys/uio.h>
+#include <sys/socket.h>
+
+#include "lwip/opt.h"
+
+#include "lwip/debug.h"
+#include "lwip/def.h"
+#include "lwip/ip.h"
+#include "lwip/mem.h"
+#include "lwip/stats.h"
+#include "lwip/snmp.h"
+#include "lwip/pbuf.h"
+#include "lwip/sys.h"
+#include "lwip/timeouts.h"
+#include "netif/etharp.h"
+#include "lwip/ethip6.h"
+
+#include "netif/tapif.h"
+
+#define IFCONFIG_BIN "/sbin/ifconfig "
+
+#if defined(LWIP_UNIX_LINUX)
+#include <sys/ioctl.h>
+#include <linux/if.h>
+#include <linux/if_tun.h>
+/*
+ * Creating a tap interface requires special privileges. If the interfaces
+ * is created in advance with `tunctl -u <user>` it can be opened as a regular
+ * user. The network must already be configured. If DEVTAP_IF is defined it
+ * will be opened instead of creating a new tap device.
+ *
+ * You can also use PRECONFIGURED_TAPIF environment variable to do so.
+ */
+#ifndef DEVTAP_DEFAULT_IF
+#define DEVTAP_DEFAULT_IF "tap0"
+#endif
+#ifndef DEVTAP
+#define DEVTAP "/dev/net/tun"
+#endif
+#define NETMASK_ARGS "netmask %d.%d.%d.%d"
+#define IFCONFIG_ARGS "tap0 inet %d.%d.%d.%d " NETMASK_ARGS
+#elif defined(LWIP_UNIX_OPENBSD)
+#define DEVTAP "/dev/tun0"
+#define NETMASK_ARGS "netmask %d.%d.%d.%d"
+#define IFCONFIG_ARGS "tun0 inet %d.%d.%d.%d " NETMASK_ARGS " link0"
+#else /* others */
+#define DEVTAP "/dev/tap0"
+#define NETMASK_ARGS "netmask %d.%d.%d.%d"
+#define IFCONFIG_ARGS "tap0 inet %d.%d.%d.%d " NETMASK_ARGS
+#endif
+
+/* Define those to better describe your network interface. */
+#define IFNAME0 't'
+#define IFNAME1 'p'
+
+#ifndef TAPIF_DEBUG
+#define TAPIF_DEBUG LWIP_DBG_OFF
+#endif
+
+struct tapif {
+  /* Add whatever per-interface state that is needed here. */
+  int fd;
+};
+
+/* Forward declarations. */
+static void tapif_input(struct netif *netif);
+#if !NO_SYS
+static void tapif_thread(void *arg);
+#endif /* !NO_SYS */
+
+/*-----------------------------------------------------------------------------------*/
+static void
+low_level_init(struct netif *netif)
+{
+  struct tapif *tapif;
+#if LWIP_IPV4
+  int ret;
+  char buf[1024];
+#endif /* LWIP_IPV4 */
+  char *preconfigured_tapif = getenv("PRECONFIGURED_TAPIF");
+  
+  tapif = (struct tapif *)netif->state;
+
+  /* Obtain MAC address from network interface. */
+
+  /* (We just fake an address...) */
+  netif->hwaddr[0] = 0x02;
+  netif->hwaddr[1] = 0x12;
+  netif->hwaddr[2] = 0x34;
+  netif->hwaddr[3] = 0x56;
+  netif->hwaddr[4] = 0x78;
+  netif->hwaddr[5] = 0xab;
+  netif->hwaddr_len = 6;
+
+  /* device capabilities */
+  netif->flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP | NETIF_FLAG_IGMP;
+
+  tapif->fd = open(DEVTAP, O_RDWR);
+  LWIP_DEBUGF(TAPIF_DEBUG, ("tapif_init: fd %d\n", tapif->fd));
+  if (tapif->fd == -1) {
+#ifdef LWIP_UNIX_LINUX
+    perror("tapif_init: try running \"modprobe tun\" or rebuilding your kernel with CONFIG_TUN; cannot open "DEVTAP);
+#else /* LWIP_UNIX_LINUX */
+    perror("tapif_init: cannot open "DEVTAP);
+#endif /* LWIP_UNIX_LINUX */
+    exit(1);
+  }
+
+#ifdef LWIP_UNIX_LINUX
+  {
+    struct ifreq ifr;
+    memset(&ifr, 0, sizeof(ifr));
+
+    if (preconfigured_tapif) {
+      strncpy(ifr.ifr_name, preconfigured_tapif, sizeof(ifr.ifr_name));
+    } else {
+      strncpy(ifr.ifr_name, DEVTAP_DEFAULT_IF, sizeof(ifr.ifr_name));
+    } 
+    ifr.ifr_name[sizeof(ifr.ifr_name)-1] = 0; /* ensure \0 termination */
+
+    ifr.ifr_flags = IFF_TAP|IFF_NO_PI;
+    if (ioctl(tapif->fd, TUNSETIFF, (void *) &ifr) < 0) {
+      perror("tapif_init: "DEVTAP" ioctl TUNSETIFF");
+      exit(1);
+    }
+  }
+#endif /* LWIP_UNIX_LINUX */
+
+  netif_set_link_up(netif);
+
+  if (preconfigured_tapif == NULL) {
+#if LWIP_IPV4
+    snprintf(buf, 1024, IFCONFIG_BIN IFCONFIG_ARGS,
+             ip4_addr1(netif_ip4_gw(netif)),
+             ip4_addr2(netif_ip4_gw(netif)),
+             ip4_addr3(netif_ip4_gw(netif)),
+             ip4_addr4(netif_ip4_gw(netif))
+#ifdef NETMASK_ARGS
+             ,
+             ip4_addr1(netif_ip4_netmask(netif)),
+             ip4_addr2(netif_ip4_netmask(netif)),
+             ip4_addr3(netif_ip4_netmask(netif)),
+             ip4_addr4(netif_ip4_netmask(netif))
+#endif /* NETMASK_ARGS */
+             );
+
+    LWIP_DEBUGF(TAPIF_DEBUG, ("tapif_init: system(\"%s\");\n", buf));
+    ret = system(buf);
+    if (ret < 0) {
+      perror("ifconfig failed");
+      exit(1);
+    }
+    if (ret != 0) {
+      printf("ifconfig returned %d\n", ret);
+    }
+#else /* LWIP_IPV4 */
+    perror("todo: support IPv6 support for non-preconfigured tapif");
+    exit(1);
+#endif /* LWIP_IPV4 */
+  }
+
+#if !NO_SYS
+  sys_thread_new("tapif_thread", tapif_thread, netif, DEFAULT_THREAD_STACKSIZE, DEFAULT_THREAD_PRIO);
+#endif /* !NO_SYS */
+}
+/*-----------------------------------------------------------------------------------*/
+/*
+ * low_level_output():
+ *
+ * Should do the actual transmission of the packet. The packet is
+ * contained in the pbuf that is passed to the function. This pbuf
+ * might be chained.
+ *
+ */
+/*-----------------------------------------------------------------------------------*/
+
+static err_t
+low_level_output(struct netif *netif, struct pbuf *p)
+{
+  struct tapif *tapif = (struct tapif *)netif->state;
+  char buf[1518]; /* max packet size including VLAN excluding CRC */
+  ssize_t written;
+
+#if 0
+  if (((double)rand()/(double)RAND_MAX) < 0.2) {
+    printf("drop output\n");
+    return ERR_OK; /* ERR_OK because we simulate packet loss on cable */
+  }
+#endif
+
+  if (p->tot_len > sizeof(buf)) {
+    MIB2_STATS_NETIF_INC(netif, ifoutdiscards);
+    perror("tapif: packet too large");
+    return ERR_IF;
+  }
+
+  /* initiate transfer(); */
+  pbuf_copy_partial(p, buf, p->tot_len, 0);
+
+  /* signal that packet should be sent(); */
+  written = write(tapif->fd, buf, p->tot_len);
+  if (written < p->tot_len) {
+    MIB2_STATS_NETIF_INC(netif, ifoutdiscards);
+    perror("tapif: write");
+    return ERR_IF;
+  } else {
+    MIB2_STATS_NETIF_ADD(netif, ifoutoctets, (u32_t)written);
+    return ERR_OK;
+  }
+}
+/*-----------------------------------------------------------------------------------*/
+/*
+ * low_level_input():
+ *
+ * Should allocate a pbuf and transfer the bytes of the incoming
+ * packet from the interface into the pbuf.
+ *
+ */
+/*-----------------------------------------------------------------------------------*/
+static struct pbuf *
+low_level_input(struct netif *netif)
+{
+  struct pbuf *p;
+  u16_t len;
+  ssize_t readlen;
+  char buf[1518]; /* max packet size including VLAN excluding CRC */
+  struct tapif *tapif = (struct tapif *)netif->state;
+
+  /* Obtain the size of the packet and put it into the "len"
+     variable. */
+  readlen = read(tapif->fd, buf, sizeof(buf));
+  if (readlen < 0) {
+    perror("read returned -1");
+    exit(1);
+  }
+  len = (u16_t)readlen;
+
+  MIB2_STATS_NETIF_ADD(netif, ifinoctets, len);
+
+#if 0
+  if (((double)rand()/(double)RAND_MAX) < 0.2) {
+    printf("drop\n");
+    return NULL;
+  }
+#endif
+
+  /* We allocate a pbuf chain of pbufs from the pool. */
+  p = pbuf_alloc(PBUF_RAW, len, PBUF_POOL);
+  if (p != NULL) {
+    pbuf_take(p, buf, len);
+    /* acknowledge that packet has been read(); */
+  } else {
+    /* drop packet(); */
+    MIB2_STATS_NETIF_INC(netif, ifindiscards);
+    LWIP_DEBUGF(NETIF_DEBUG, ("tapif_input: could not allocate pbuf\n"));
+  }
+
+  return p;
+}
+
+/*-----------------------------------------------------------------------------------*/
+/*
+ * tapif_input():
+ *
+ * This function should be called when a packet is ready to be read
+ * from the interface. It uses the function low_level_input() that
+ * should handle the actual reception of bytes from the network
+ * interface.
+ *
+ */
+/*-----------------------------------------------------------------------------------*/
+static void
+tapif_input(struct netif *netif)
+{
+  struct pbuf *p = low_level_input(netif);
+
+  if (p == NULL) {
+#if LINK_STATS
+    LINK_STATS_INC(link.recv);
+#endif /* LINK_STATS */
+    LWIP_DEBUGF(TAPIF_DEBUG, ("tapif_input: low_level_input returned NULL\n"));
+    return;
+  }
+
+  if (netif->input(p, netif) != ERR_OK) {
+    LWIP_DEBUGF(NETIF_DEBUG, ("tapif_input: netif input error\n"));
+    pbuf_free(p);
+  }
+}
+/*-----------------------------------------------------------------------------------*/
+/*
+ * tapif_init():
+ *
+ * Should be called at the beginning of the program to set up the
+ * network interface. It calls the function low_level_init() to do the
+ * actual setup of the hardware.
+ *
+ */
+/*-----------------------------------------------------------------------------------*/
+err_t
+tapif_init(struct netif *netif)
+{
+  struct tapif *tapif = (struct tapif *)mem_malloc(sizeof(struct tapif));
+
+  if (tapif == NULL) {
+    LWIP_DEBUGF(NETIF_DEBUG, ("tapif_init: out of memory for tapif\n"));
+    return ERR_MEM;
+  }
+  netif->state = tapif;
+  MIB2_INIT_NETIF(netif, snmp_ifType_other, 100000000);
+
+  netif->name[0] = IFNAME0;
+  netif->name[1] = IFNAME1;
+#if LWIP_IPV4
+  netif->output = etharp_output;
+#endif /* LWIP_IPV4 */
+#if LWIP_IPV6
+  netif->output_ip6 = ethip6_output;
+#endif /* LWIP_IPV6 */
+  netif->linkoutput = low_level_output;
+  netif->mtu = 1500;
+
+  low_level_init(netif);
+
+  return ERR_OK;
+}
+
+
+/*-----------------------------------------------------------------------------------*/
+void
+tapif_poll(struct netif *netif)
+{
+  tapif_input(netif);
+}
+
+#if NO_SYS
+
+int
+tapif_select(struct netif *netif)
+{
+  fd_set fdset;
+  int ret;
+  struct timeval tv;
+  struct tapif *tapif;
+  u32_t msecs = sys_timeouts_sleeptime();
+
+  tapif = (struct tapif *)netif->state;
+
+  tv.tv_sec = msecs / 1000;
+  tv.tv_usec = (msecs % 1000) * 1000;
+
+  FD_ZERO(&fdset);
+  FD_SET(tapif->fd, &fdset);
+
+  ret = select(tapif->fd + 1, &fdset, NULL, NULL, &tv);
+  if (ret > 0) {
+    tapif_input(netif);
+  }
+  return ret;
+}
+
+#else /* NO_SYS */
+
+static void
+tapif_thread(void *arg)
+{
+  struct netif *netif;
+  struct tapif *tapif;
+  fd_set fdset;
+  int ret;
+
+  netif = (struct netif *)arg;
+  tapif = (struct tapif *)netif->state;
+
+  while(1) {
+    FD_ZERO(&fdset);
+    FD_SET(tapif->fd, &fdset);
+
+    /* Wait for a packet to arrive. */
+    ret = select(tapif->fd + 1, &fdset, NULL, NULL, NULL);
+
+    if(ret == 1) {
+      /* Handle incoming packet. */
+      tapif_input(netif);
+    } else if(ret == -1) {
+      perror("tapif_thread: select");
+    }
+  }
+}
+
+#endif /* NO_SYS */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/ports/unix/port/perf.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/ports/unix/port/perf.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/ports/unix/port/perf.c	(revision 457)
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2001-2003 Swedish Institute of Computer Science.
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission. 
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ * 
+ * Author: Adam Dunkels <adam@sics.se>
+ *
+ */
+
+#include "arch/perf.h"
+
+#include <stdio.h>
+
+static FILE *f;
+
+void
+perf_print(unsigned long c1l, unsigned long c1h,
+	   unsigned long c2l, unsigned long c2h,
+	   char *key)
+{
+  unsigned long sub_ms, sub_ls;
+  
+  sub_ms = c2h - c1h;
+  sub_ls = c2l - c1l;
+  if (c2l < c1l) sub_ms--;
+  fprintf(f, "%s: %.8lu%.8lu\n", key, sub_ms, sub_ls);
+  fflush(NULL);
+}
+
+void
+perf_print_times(struct tms *start, struct tms *end, char *key)
+{
+  fprintf(f, "%s: %lu\n", key, end->tms_stime - start->tms_stime);
+  fflush(NULL);  
+}
+
+void
+perf_init(char *fname)
+{
+  f = fopen(fname, "w");  
+}
+	
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/ports/unix/port/sys_arch.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/ports/unix/port/sys_arch.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/ports/unix/port/sys_arch.c	(revision 457)
@@ -0,0 +1,719 @@
+/*
+ * Copyright (c) 2001-2003 Swedish Institute of Computer Science.
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission. 
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ * 
+ * Author: Adam Dunkels <adam@sics.se>
+ *
+ */
+
+/*
+ * Wed Apr 17 16:05:29 EDT 2002 (James Roth)
+ *
+ *  - Fixed an unlikely sys_thread_new() race condition.
+ *
+ *  - Made current_thread() work with threads which where
+ *    not created with sys_thread_new().  This includes
+ *    the main thread and threads made with pthread_create().
+ *
+ *  - Catch overflows where more than SYS_MBOX_SIZE messages
+ *    are waiting to be read.  The sys_mbox_post() routine
+ *    will block until there is more room instead of just
+ *    leaking messages.
+ */
+#include "lwip/debug.h"
+
+#include <string.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <pthread.h>
+#include <errno.h>
+
+#include "lwip/def.h"
+
+#ifdef LWIP_UNIX_MACH
+#include <mach/mach.h>
+#include <mach/mach_time.h>
+#endif
+
+#include "lwip/sys.h"
+#include "lwip/opt.h"
+#include "lwip/stats.h"
+#include "lwip/tcpip.h"
+
+static void
+get_monotonic_time(struct timespec *ts)
+{
+#ifdef LWIP_UNIX_MACH
+  /* darwin impl (no CLOCK_MONOTONIC) */
+  uint64_t t = mach_absolute_time();
+  mach_timebase_info_data_t timebase_info = {0, 0};
+  mach_timebase_info(&timebase_info);
+  uint64_t nano = (t * timebase_info.numer) / (timebase_info.denom);
+  uint64_t sec = nano/1000000000L;
+  nano -= sec * 1000000000L;
+  ts->tv_sec = sec;
+  ts->tv_nsec = nano;
+#else
+  clock_gettime(CLOCK_MONOTONIC, ts);
+#endif
+}
+
+#if SYS_LIGHTWEIGHT_PROT
+static pthread_mutex_t lwprot_mutex = PTHREAD_MUTEX_INITIALIZER;
+static pthread_t lwprot_thread = (pthread_t)0xDEAD;
+static int lwprot_count = 0;
+#endif /* SYS_LIGHTWEIGHT_PROT */
+
+#if !NO_SYS
+
+static struct sys_thread *threads = NULL;
+static pthread_mutex_t threads_mutex = PTHREAD_MUTEX_INITIALIZER;
+
+struct sys_mbox_msg {
+  struct sys_mbox_msg *next;
+  void *msg;
+};
+
+#define SYS_MBOX_SIZE 128
+
+struct sys_mbox {
+  int first, last;
+  void *msgs[SYS_MBOX_SIZE];
+  struct sys_sem *not_empty;
+  struct sys_sem *not_full;
+  struct sys_sem *mutex;
+  int wait_send;
+};
+
+struct sys_sem {
+  unsigned int c;
+  pthread_condattr_t condattr;
+  pthread_cond_t cond;
+  pthread_mutex_t mutex;
+};
+
+struct sys_mutex {
+  pthread_mutex_t mutex;
+};
+
+struct sys_thread {
+  struct sys_thread *next;
+  pthread_t pthread;
+};
+
+static struct sys_sem *sys_sem_new_internal(u8_t count);
+static void sys_sem_free_internal(struct sys_sem *sem);
+
+static u32_t cond_wait(pthread_cond_t * cond, pthread_mutex_t * mutex,
+                       u32_t timeout);
+
+/*-----------------------------------------------------------------------------------*/
+/* Threads */
+static struct sys_thread * 
+introduce_thread(pthread_t id)
+{
+  struct sys_thread *thread;
+
+  thread = (struct sys_thread *)malloc(sizeof(struct sys_thread));
+
+  if (thread != NULL) {
+    pthread_mutex_lock(&threads_mutex);
+    thread->next = threads;
+    thread->pthread = id;
+    threads = thread;
+    pthread_mutex_unlock(&threads_mutex);
+  }
+
+  return thread;
+}
+
+struct thread_wrapper_data
+{
+  lwip_thread_fn function;
+  void *arg;
+};
+
+static void *
+thread_wrapper(void *arg)
+{
+  struct thread_wrapper_data *thread_data = (struct thread_wrapper_data *)arg;
+
+  thread_data->function(thread_data->arg);
+
+  /* we should never get here */
+  free(arg);
+  return NULL;
+}
+
+sys_thread_t
+sys_thread_new(const char *name, lwip_thread_fn function, void *arg, int stacksize, int prio)
+{
+  int code;
+  pthread_t tmp;
+  struct sys_thread *st = NULL;
+  struct thread_wrapper_data *thread_data;
+  LWIP_UNUSED_ARG(name);
+  LWIP_UNUSED_ARG(stacksize);
+  LWIP_UNUSED_ARG(prio);
+
+  thread_data = (struct thread_wrapper_data *)malloc(sizeof(struct thread_wrapper_data));
+  thread_data->arg = arg;
+  thread_data->function = function;
+  code = pthread_create(&tmp,
+                        NULL, 
+                        thread_wrapper, 
+                        thread_data);
+  
+  if (0 == code) {
+    st = introduce_thread(tmp);
+  }
+
+  if (NULL == st) {
+    LWIP_DEBUGF(SYS_DEBUG, ("sys_thread_new: pthread_create %d, st = 0x%lx",
+                       code, (unsigned long)st));
+    abort();
+  }
+  return st;
+}
+
+#if LWIP_TCPIP_CORE_LOCKING
+static pthread_t lwip_core_lock_holder_thread_id;
+void sys_lock_tcpip_core(void)
+{
+  sys_mutex_lock(&lock_tcpip_core);
+  lwip_core_lock_holder_thread_id = pthread_self();
+}
+
+void sys_unlock_tcpip_core(void)
+{
+  lwip_core_lock_holder_thread_id = 0;
+  sys_mutex_unlock(&lock_tcpip_core);
+}
+#endif /* LWIP_TCPIP_CORE_LOCKING */
+
+static pthread_t lwip_tcpip_thread_id;
+void sys_mark_tcpip_thread(void)
+{
+  lwip_tcpip_thread_id = pthread_self();
+}
+
+void sys_check_core_locking(void)
+{
+  /* Embedded systems should check we are NOT in an interrupt context here */
+
+  if (lwip_tcpip_thread_id != 0) {
+    pthread_t current_thread_id = pthread_self();
+
+#if LWIP_TCPIP_CORE_LOCKING
+    LWIP_ASSERT("Function called without core lock", current_thread_id == lwip_core_lock_holder_thread_id);
+#else /* LWIP_TCPIP_CORE_LOCKING */
+    LWIP_ASSERT("Function called from wrong thread", current_thread_id == lwip_tcpip_thread_id);
+#endif /* LWIP_TCPIP_CORE_LOCKING */
+  }
+}
+
+/*-----------------------------------------------------------------------------------*/
+/* Mailbox */
+err_t
+sys_mbox_new(struct sys_mbox **mb, int size)
+{
+  struct sys_mbox *mbox;
+  LWIP_UNUSED_ARG(size);
+
+  mbox = (struct sys_mbox *)malloc(sizeof(struct sys_mbox));
+  if (mbox == NULL) {
+    return ERR_MEM;
+  }
+  mbox->first = mbox->last = 0;
+  mbox->not_empty = sys_sem_new_internal(0);
+  mbox->not_full = sys_sem_new_internal(0);
+  mbox->mutex = sys_sem_new_internal(1);
+  mbox->wait_send = 0;
+
+  SYS_STATS_INC_USED(mbox);
+  *mb = mbox;
+  return ERR_OK;
+}
+
+void
+sys_mbox_free(struct sys_mbox **mb)
+{
+  if ((mb != NULL) && (*mb != SYS_MBOX_NULL)) {
+    struct sys_mbox *mbox = *mb;
+    SYS_STATS_DEC(mbox.used);
+    sys_arch_sem_wait(&mbox->mutex, 0);
+    
+    sys_sem_free_internal(mbox->not_empty);
+    sys_sem_free_internal(mbox->not_full);
+    sys_sem_free_internal(mbox->mutex);
+    mbox->not_empty = mbox->not_full = mbox->mutex = NULL;
+    /*  LWIP_DEBUGF("sys_mbox_free: mbox 0x%lx\n", mbox); */
+    free(mbox);
+  }
+}
+
+err_t
+sys_mbox_trypost(struct sys_mbox **mb, void *msg)
+{
+  u8_t first;
+  struct sys_mbox *mbox;
+  LWIP_ASSERT("invalid mbox", (mb != NULL) && (*mb != NULL));
+  mbox = *mb;
+
+  sys_arch_sem_wait(&mbox->mutex, 0);
+
+  LWIP_DEBUGF(SYS_DEBUG, ("sys_mbox_trypost: mbox %p msg %p\n",
+                          (void *)mbox, (void *)msg));
+
+  if ((mbox->last + 1) >= (mbox->first + SYS_MBOX_SIZE)) {
+    sys_sem_signal(&mbox->mutex);
+    return ERR_MEM;
+  }
+
+  mbox->msgs[mbox->last % SYS_MBOX_SIZE] = msg;
+
+  if (mbox->last == mbox->first) {
+    first = 1;
+  } else {
+    first = 0;
+  }
+
+  mbox->last++;
+
+  if (first) {
+    sys_sem_signal(&mbox->not_empty);
+  }
+
+  sys_sem_signal(&mbox->mutex);
+
+  return ERR_OK;
+}
+
+err_t
+sys_mbox_trypost_fromisr(sys_mbox_t *q, void *msg)
+{
+  return sys_mbox_trypost(q, msg);
+}
+
+void
+sys_mbox_post(struct sys_mbox **mb, void *msg)
+{
+  u8_t first;
+  struct sys_mbox *mbox;
+  LWIP_ASSERT("invalid mbox", (mb != NULL) && (*mb != NULL));
+  mbox = *mb;
+
+  sys_arch_sem_wait(&mbox->mutex, 0);
+
+  LWIP_DEBUGF(SYS_DEBUG, ("sys_mbox_post: mbox %p msg %p\n", (void *)mbox, (void *)msg));
+
+  while ((mbox->last + 1) >= (mbox->first + SYS_MBOX_SIZE)) {
+    mbox->wait_send++;
+    sys_sem_signal(&mbox->mutex);
+    sys_arch_sem_wait(&mbox->not_full, 0);
+    sys_arch_sem_wait(&mbox->mutex, 0);
+    mbox->wait_send--;
+  }
+
+  mbox->msgs[mbox->last % SYS_MBOX_SIZE] = msg;
+
+  if (mbox->last == mbox->first) {
+    first = 1;
+  } else {
+    first = 0;
+  }
+
+  mbox->last++;
+
+  if (first) {
+    sys_sem_signal(&mbox->not_empty);
+  }
+
+  sys_sem_signal(&mbox->mutex);
+}
+
+u32_t
+sys_arch_mbox_tryfetch(struct sys_mbox **mb, void **msg)
+{
+  struct sys_mbox *mbox;
+  LWIP_ASSERT("invalid mbox", (mb != NULL) && (*mb != NULL));
+  mbox = *mb;
+
+  sys_arch_sem_wait(&mbox->mutex, 0);
+
+  if (mbox->first == mbox->last) {
+    sys_sem_signal(&mbox->mutex);
+    return SYS_MBOX_EMPTY;
+  }
+
+  if (msg != NULL) {
+    LWIP_DEBUGF(SYS_DEBUG, ("sys_mbox_tryfetch: mbox %p msg %p\n", (void *)mbox, *msg));
+    *msg = mbox->msgs[mbox->first % SYS_MBOX_SIZE];
+  }
+  else{
+    LWIP_DEBUGF(SYS_DEBUG, ("sys_mbox_tryfetch: mbox %p, null msg\n", (void *)mbox));
+  }
+
+  mbox->first++;
+
+  if (mbox->wait_send) {
+    sys_sem_signal(&mbox->not_full);
+  }
+
+  sys_sem_signal(&mbox->mutex);
+
+  return 0;
+}
+
+u32_t
+sys_arch_mbox_fetch(struct sys_mbox **mb, void **msg, u32_t timeout)
+{
+  u32_t time_needed = 0;
+  struct sys_mbox *mbox;
+  LWIP_ASSERT("invalid mbox", (mb != NULL) && (*mb != NULL));
+  mbox = *mb;
+
+  /* The mutex lock is quick so we don't bother with the timeout
+     stuff here. */
+  sys_arch_sem_wait(&mbox->mutex, 0);
+
+  while (mbox->first == mbox->last) {
+    sys_sem_signal(&mbox->mutex);
+
+    /* We block while waiting for a mail to arrive in the mailbox. We
+       must be prepared to timeout. */
+    if (timeout != 0) {
+      time_needed = sys_arch_sem_wait(&mbox->not_empty, timeout);
+
+      if (time_needed == SYS_ARCH_TIMEOUT) {
+        return SYS_ARCH_TIMEOUT;
+      }
+    } else {
+      sys_arch_sem_wait(&mbox->not_empty, 0);
+    }
+
+    sys_arch_sem_wait(&mbox->mutex, 0);
+  }
+
+  if (msg != NULL) {
+    LWIP_DEBUGF(SYS_DEBUG, ("sys_mbox_fetch: mbox %p msg %p\n", (void *)mbox, *msg));
+    *msg = mbox->msgs[mbox->first % SYS_MBOX_SIZE];
+  }
+  else{
+    LWIP_DEBUGF(SYS_DEBUG, ("sys_mbox_fetch: mbox %p, null msg\n", (void *)mbox));
+  }
+
+  mbox->first++;
+
+  if (mbox->wait_send) {
+    sys_sem_signal(&mbox->not_full);
+  }
+
+  sys_sem_signal(&mbox->mutex);
+
+  return time_needed;
+}
+
+/*-----------------------------------------------------------------------------------*/
+/* Semaphore */
+static struct sys_sem *
+sys_sem_new_internal(u8_t count)
+{
+  struct sys_sem *sem;
+
+  sem = (struct sys_sem *)malloc(sizeof(struct sys_sem));
+  if (sem != NULL) {
+    sem->c = count;
+    pthread_condattr_init(&(sem->condattr));
+#if !(defined(LWIP_UNIX_MACH) || (defined(LWIP_UNIX_ANDROID) && __ANDROID_API__ < 21))
+    pthread_condattr_setclock(&(sem->condattr), CLOCK_MONOTONIC);
+#endif
+    pthread_cond_init(&(sem->cond), &(sem->condattr));
+    pthread_mutex_init(&(sem->mutex), NULL);
+  }
+  return sem;
+}
+
+err_t
+sys_sem_new(struct sys_sem **sem, u8_t count)
+{
+  SYS_STATS_INC_USED(sem);
+  *sem = sys_sem_new_internal(count);
+  if (*sem == NULL) {
+    return ERR_MEM;
+  }
+  return ERR_OK;
+}
+
+static u32_t
+cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex, u32_t timeout)
+{
+  struct timespec rtime1, rtime2, ts;
+  int ret;
+
+#ifdef __GNU__
+  #define pthread_cond_wait pthread_hurd_cond_wait_np
+  #define pthread_cond_timedwait pthread_hurd_cond_timedwait_np
+#endif
+
+  if (timeout == 0) {
+    pthread_cond_wait(cond, mutex);
+    return 0;
+  }
+
+  /* Get a timestamp and add the timeout value. */
+  get_monotonic_time(&rtime1);
+#if defined(LWIP_UNIX_MACH) || (defined(LWIP_UNIX_ANDROID) && __ANDROID_API__ < 21)
+  ts.tv_sec = timeout / 1000L;
+  ts.tv_nsec = (timeout % 1000L) * 1000000L;
+  ret = pthread_cond_timedwait_relative_np(cond, mutex, &ts);
+#else
+  ts.tv_sec = rtime1.tv_sec + timeout / 1000L;
+  ts.tv_nsec = rtime1.tv_nsec + (timeout % 1000L) * 1000000L;
+  if (ts.tv_nsec >= 1000000000L) {
+    ts.tv_sec++;
+    ts.tv_nsec -= 1000000000L;
+  }
+
+  ret = pthread_cond_timedwait(cond, mutex, &ts);
+#endif
+  if (ret == ETIMEDOUT) {
+    return SYS_ARCH_TIMEOUT;
+  }
+
+  /* Calculate for how long we waited for the cond. */
+  get_monotonic_time(&rtime2);
+  ts.tv_sec = rtime2.tv_sec - rtime1.tv_sec;
+  ts.tv_nsec = rtime2.tv_nsec - rtime1.tv_nsec;
+  if (ts.tv_nsec < 0) {
+    ts.tv_sec--;
+    ts.tv_nsec += 1000000000L;
+  }
+  return (u32_t)(ts.tv_sec * 1000L + ts.tv_nsec / 1000000L);
+}
+
+u32_t
+sys_arch_sem_wait(struct sys_sem **s, u32_t timeout)
+{
+  u32_t time_needed = 0;
+  struct sys_sem *sem;
+  LWIP_ASSERT("invalid sem", (s != NULL) && (*s != NULL));
+  sem = *s;
+
+  pthread_mutex_lock(&(sem->mutex));
+  while (sem->c <= 0) {
+    if (timeout > 0) {
+      time_needed = cond_wait(&(sem->cond), &(sem->mutex), timeout);
+
+      if (time_needed == SYS_ARCH_TIMEOUT) {
+        pthread_mutex_unlock(&(sem->mutex));
+        return SYS_ARCH_TIMEOUT;
+      }
+      /*      pthread_mutex_unlock(&(sem->mutex));
+              return time_needed; */
+    } else {
+      cond_wait(&(sem->cond), &(sem->mutex), 0);
+    }
+  }
+  sem->c--;
+  pthread_mutex_unlock(&(sem->mutex));
+  return (u32_t)time_needed;
+}
+
+void
+sys_sem_signal(struct sys_sem **s)
+{
+  struct sys_sem *sem;
+  LWIP_ASSERT("invalid sem", (s != NULL) && (*s != NULL));
+  sem = *s;
+
+  pthread_mutex_lock(&(sem->mutex));
+  sem->c++;
+
+  if (sem->c > 1) {
+    sem->c = 1;
+  }
+
+  pthread_cond_broadcast(&(sem->cond));
+  pthread_mutex_unlock(&(sem->mutex));
+}
+
+static void
+sys_sem_free_internal(struct sys_sem *sem)
+{
+  pthread_cond_destroy(&(sem->cond));
+  pthread_condattr_destroy(&(sem->condattr));
+  pthread_mutex_destroy(&(sem->mutex));
+  free(sem);
+}
+
+void
+sys_sem_free(struct sys_sem **sem)
+{
+  if ((sem != NULL) && (*sem != SYS_SEM_NULL)) {
+    SYS_STATS_DEC(sem.used);
+    sys_sem_free_internal(*sem);
+  }
+}
+
+/*-----------------------------------------------------------------------------------*/
+/* Mutex */
+/** Create a new mutex
+ * @param mutex pointer to the mutex to create
+ * @return a new mutex */
+err_t
+sys_mutex_new(struct sys_mutex **mutex)
+{
+  struct sys_mutex *mtx;
+
+  mtx = (struct sys_mutex *)malloc(sizeof(struct sys_mutex));
+  if (mtx != NULL) {
+    pthread_mutex_init(&(mtx->mutex), NULL);
+    *mutex = mtx;
+    return ERR_OK;
+  }
+  else {
+    return ERR_MEM;
+  }
+}
+
+/** Lock a mutex
+ * @param mutex the mutex to lock */
+void
+sys_mutex_lock(struct sys_mutex **mutex)
+{
+  pthread_mutex_lock(&((*mutex)->mutex));
+}
+
+/** Unlock a mutex
+ * @param mutex the mutex to unlock */
+void
+sys_mutex_unlock(struct sys_mutex **mutex)
+{
+  pthread_mutex_unlock(&((*mutex)->mutex));
+}
+
+/** Delete a mutex
+ * @param mutex the mutex to delete */
+void
+sys_mutex_free(struct sys_mutex **mutex)
+{
+  pthread_mutex_destroy(&((*mutex)->mutex));
+  free(*mutex);
+}
+
+#endif /* !NO_SYS */
+
+/*-----------------------------------------------------------------------------------*/
+/* Time */
+u32_t
+sys_now(void)
+{
+  struct timespec ts;
+
+  get_monotonic_time(&ts);
+  return (u32_t)(ts.tv_sec * 1000L + ts.tv_nsec / 1000000L);
+}
+
+u32_t
+sys_jiffies(void)
+{
+  struct timespec ts;
+
+  get_monotonic_time(&ts);
+  return (u32_t)(ts.tv_sec * 1000000000L + ts.tv_nsec);
+}
+
+/*-----------------------------------------------------------------------------------*/
+/* Init */
+
+void
+sys_init(void)
+{
+}
+
+/*-----------------------------------------------------------------------------------*/
+/* Critical section */
+#if SYS_LIGHTWEIGHT_PROT
+/** sys_prot_t sys_arch_protect(void)
+
+This optional function does a "fast" critical region protection and returns
+the previous protection level. This function is only called during very short
+critical regions. An embedded system which supports ISR-based drivers might
+want to implement this function by disabling interrupts. Task-based systems
+might want to implement this by using a mutex or disabling tasking. This
+function should support recursive calls from the same task or interrupt. In
+other words, sys_arch_protect() could be called while already protected. In
+that case the return value indicates that it is already protected.
+
+sys_arch_protect() is only required if your port is supporting an operating
+system.
+*/
+sys_prot_t
+sys_arch_protect(void)
+{
+    /* Note that for the UNIX port, we are using a lightweight mutex, and our
+     * own counter (which is locked by the mutex). The return code is not actually
+     * used. */
+    if (lwprot_thread != pthread_self())
+    {
+        /* We are locking the mutex where it has not been locked before *
+        * or is being locked by another thread */
+        pthread_mutex_lock(&lwprot_mutex);
+        lwprot_thread = pthread_self();
+        lwprot_count = 1;
+    }
+    else
+        /* It is already locked by THIS thread */
+        lwprot_count++;
+    return 0;
+}
+
+/** void sys_arch_unprotect(sys_prot_t pval)
+
+This optional function does a "fast" set of critical region protection to the
+value specified by pval. See the documentation for sys_arch_protect() for
+more information. This function is only required if your port is supporting
+an operating system.
+*/
+void
+sys_arch_unprotect(sys_prot_t pval)
+{
+    LWIP_UNUSED_ARG(pval);
+    if (lwprot_thread == pthread_self())
+    {
+        lwprot_count--;
+        if (lwprot_count == 0)
+        {
+            lwprot_thread = (pthread_t) 0xDEAD;
+            pthread_mutex_unlock(&lwprot_mutex);
+        }
+    }
+}
+#endif /* SYS_LIGHTWEIGHT_PROT */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/ports/unix/setup-tapif
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/ports/unix/setup-tapif	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/ports/unix/setup-tapif	(revision 457)
@@ -0,0 +1,15 @@
+#!/bin/bash
+
+# Run me using "source setup-tapif" to get exported PRECONFIGURED_TAPIF variable
+# Alternatively, add "export PRECONFIGURED_TAPIF=tap0" to ~/.bashrc
+
+# http://backreference.org/2010/03/26/tuntap-interface-tutorial/
+
+# After executing this script, start unixsim/simhost.
+# Enter 192.168.0.2 or "http://simhost.local/" (Zeroconf)
+# in your webbrowser to see simhost webpage.
+
+sudo ip tuntap add dev tap0 mode tap user `whoami`
+sudo ip link set tap0 up
+sudo ip addr add 192.168.0.1/24 dev tap0
+export PRECONFIGURED_TAPIF=tap0
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/ports/win32/Common.mk
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/ports/win32/Common.mk	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/ports/win32/Common.mk	(revision 457)
@@ -0,0 +1,51 @@
+#
+# Copyright (c) 2001, 2002 Swedish Institute of Computer Science.
+# 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. The name of the author may not be used to endorse or promote products
+#    derived from this software without specific prior written permission. 
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+#
+# This file is part of the lwIP TCP/IP stack.
+# 
+# Author: Adam Dunkels <adam@sics.se>
+#
+
+CC=gcc
+
+# Architecture specific files.
+LWIPARCH?=$(CONTRIBDIR)/ports/win32
+SYSARCH?=$(LWIPARCH)/sys_arch.c
+ARCHFILES=$(SYSARCH) $(LWIPARCH)/pcapif.c \
+	$(LWIPARCH)/pcapif_helper.c $(LWIPARCH)/sio.c
+
+WIN32_COMMON_MK_DIR := $(dir $(abspath $(lastword $(MAKEFILE_LIST))))
+include $(WIN32_COMMON_MK_DIR)/../Common.allports.mk
+
+PCAPDIR=$(PCAP_DIR)/Include
+LDFLAGS+=-L$(PCAP_DIR)/lib -lwpcap -lpacket
+# -Wno-format: GCC complains about non-standard 64 bit modifier needed for MSVC runtime
+CFLAGS+=-I$(PCAPDIR) -Wno-format
+
+pcapif.o:
+	$(CC) $(CFLAGS) -Wno-error -Wno-redundant-decls -c $(<:.o=.c)
+pcapif_helper.o:
+	$(CC) $(CFLAGS) -std=c99 -Wno-redundant-decls -c $(<:.o=.c)
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/ports/win32/Filelists.cmake
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/ports/win32/Filelists.cmake	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/ports/win32/Filelists.cmake	(revision 457)
@@ -0,0 +1,27 @@
+# This file is indended to be included in end-user CMakeLists.txt
+# include(/path/to/Filelists.cmake)
+# It assumes the variable LWIP_CONTRIB_DIR is defined pointing to the
+# root path of lwIP contrib sources.
+#
+# This file is NOT designed (on purpose) to be used as cmake
+# subdir via add_subdirectory()
+# The intention is to provide greater flexibility to users to 
+# create their own targets using the *_SRCS variables.
+
+set(lwipcontribportwindows_SRCS
+    ${LWIP_CONTRIB_DIR}/ports/win32/sys_arch.c
+    ${LWIP_CONTRIB_DIR}/ports/win32/sio.c
+    ${LWIP_CONTRIB_DIR}/ports/win32/pcapif.c
+    ${LWIP_CONTRIB_DIR}/ports/win32/pcapif_helper.c
+)
+
+# pcapif needs WinPcap developer package: https://www.winpcap.org/devel.htm
+set(WPDPACK_DIR ${LWIP_CONTRIB_DIR}/../WpdPack)
+find_library(WPCAP  wpcap  HINTS ${WPDPACK_DIR}/lib)
+find_library(PACKET packet HINTS ${WPDPACK_DIR}/lib)
+
+add_library(lwipcontribportwindows EXCLUDE_FROM_ALL ${lwipcontribportwindows_SRCS})
+target_include_directories(lwipcontribportwindows PRIVATE ${LWIP_INCLUDE_DIRS} "${WPDPACK_DIR}/include" ${LWIP_MBEDTLS_INCLUDE_DIRS})
+target_compile_options(lwipcontribportwindows PRIVATE ${LWIP_COMPILER_FLAGS})
+target_compile_definitions(lwipcontribaddons PRIVATE ${LWIP_DEFINITIONS} ${LWIP_MBEDTLS_DEFINITIONS})
+target_link_libraries(lwipcontribportwindows PUBLIC ${WPCAP} ${PACKET} ${LWIP_MBEDTLS_LINK_LIBRARIES})
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/ports/win32/check/check_stdint.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/ports/win32/check/check_stdint.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/ports/win32/check/check_stdint.h	(revision 457)
@@ -0,0 +1,1 @@
+/* deliberateliy empty */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/ports/win32/check/config.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/ports/win32/check/config.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/ports/win32/check/config.h	(revision 457)
@@ -0,0 +1,30 @@
+/* config.h for check-0.11.0 on win32 under MSVC/MinGW */
+
+#ifdef _MSC_VER
+
+typedef unsigned int pid_t;
+typedef unsigned int uint32_t;
+
+typedef int ssize_t;
+#define snprintf _snprintf
+
+#define HAVE_DECL_STRDUP 1
+#define HAVE_DECL_FILENO 1
+#define HAVE_DECL_PUTENV 1
+
+#define _CRT_SECURE_NO_WARNINGS
+
+/* disable some warnings */
+#pragma warning (disable: 4090) /* const assigned to non-const */
+#pragma warning (disable: 4996) /* fileno is deprecated */
+
+#endif /* _ MSC_VER */
+
+
+#define LWIP_UNITTESTS_NOFORK
+
+#include <io.h>
+
+typedef unsigned int clockid_t;
+typedef unsigned int timer_t;
+#define STRUCT_TIMESPEC_DEFINITION_MISSING
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/ports/win32/check/stdbool.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/ports/win32/check/stdbool.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/ports/win32/check/stdbool.h	(revision 457)
@@ -0,0 +1,9 @@
+#ifndef MY_STDBOOL_H
+#define MY_STDBOOL_H
+
+typedef int bool;
+#define true 1
+#define false 0
+#define __bool_true_false_are_defined 1
+
+#endif
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/ports/win32/check/sys/time.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/ports/win32/check/sys/time.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/ports/win32/check/sys/time.h	(revision 457)
@@ -0,0 +1,12 @@
+#ifndef LWIP_SYS__TIME_H
+#define LWIP_SYS__TIME_H
+
+#include <stdlib.h> /* time_t */
+
+struct timeval {
+  time_t    tv_sec;         /* seconds */
+  long    tv_usec;        /* and microseconds */
+};
+int gettimeofday(struct timeval* tp, void* tzp);
+
+#endif
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/ports/win32/check/time.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/ports/win32/check/time.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/ports/win32/check/time.c	(revision 457)
@@ -0,0 +1,66 @@
+#include <time.h>
+
+#include <windows.h>
+#if defined(_MSC_VER) || defined(_MSC_EXTENSIONS)
+  #define DELTA_EPOCH_IN_MICROSECS  11644473600000000Ui64
+#else
+  #define DELTA_EPOCH_IN_MICROSECS  11644473600000000ULL
+#endif
+
+#include "config.h"
+
+struct timezone 
+{
+  int tz_minuteswest; /* minutes W of Greenwich */
+  int tz_dsttime;     /* type of dst correction */
+};
+ 
+int gettimeofday(struct timeval *tv, struct timezone *tz)
+{
+  FILETIME ft;
+  unsigned __int64 tmpres = 0;
+  static int tzflag;
+ 
+  if (NULL != tv) {
+    GetSystemTimeAsFileTime(&ft);
+ 
+    tmpres |= ft.dwHighDateTime;
+    tmpres <<= 32;
+    tmpres |= ft.dwLowDateTime;
+ 
+    /*converting file time to unix epoch*/
+    tmpres -= DELTA_EPOCH_IN_MICROSECS; 
+    tmpres /= 10;  /*convert into microseconds*/
+    tv->tv_sec = (long)(tmpres / 1000000UL);
+    tv->tv_usec = (long)(tmpres % 1000000UL);
+  }
+ 
+  if (NULL != tz) {
+    if (!tzflag) {
+      _tzset();
+      tzflag++;
+    }
+    tz->tz_minuteswest = _timezone / 60;
+    tz->tz_dsttime = _daylight;
+  }
+ 
+  return 0;
+}
+
+struct tm *
+localtime_r(const time_t *timer, struct tm *result)
+{
+  struct tm *local_result;
+
+  if (result == NULL) {
+    return NULL;
+  }
+
+  local_result = localtime (timer);
+  if (local_result == NULL) {
+    return NULL;
+  }
+
+  memcpy(result, local_result, sizeof(*result));
+  return result;
+}
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/ports/win32/check/unistd.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/ports/win32/check/unistd.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/ports/win32/check/unistd.h	(revision 457)
@@ -0,0 +1,7 @@
+#ifndef LWIP_UNISTD_H
+#define LWIP_UNISTD_H
+
+/* include io.h for read() and write() */
+#include <io.h>
+
+#endif
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/ports/win32/example_app/CMakeLists.txt
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/ports/win32/example_app/CMakeLists.txt	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/ports/win32/example_app/CMakeLists.txt	(revision 457)
@@ -0,0 +1,33 @@
+cmake_minimum_required(VERSION 3.8)
+
+project(example_app C)
+
+set (CMAKE_EXPORT_COMPILE_COMMANDS ON)
+
+set(LWIP_CONTRIB_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../../..)
+set(LWIP_DIR         ${CMAKE_CURRENT_SOURCE_DIR}/../../../../lwip)
+
+include(${LWIP_CONTRIB_DIR}/ports/CMakeCommon.cmake)
+
+set (LWIP_DEFINITIONS -DLWIP_DEBUG)
+set (LWIP_INCLUDE_DIRS
+    "${LWIP_DIR}/src/include"
+    "${LWIP_CONTRIB_DIR}/"
+    "${LWIP_CONTRIB_DIR}/ports/win32/include"
+    "${LWIP_CONTRIB_DIR}/examples/example_app"
+)
+
+include(${LWIP_DIR}/src/Filelists.cmake)
+include(${LWIP_CONTRIB_DIR}/Filelists.cmake)
+include(${LWIP_CONTRIB_DIR}/ports/win32/Filelists.cmake)
+
+add_executable(example_app ${LWIP_CONTRIB_DIR}/examples/example_app/test.c default_netif.c)
+target_include_directories(example_app PRIVATE ${LWIP_INCLUDE_DIRS})
+target_compile_options(example_app PRIVATE ${LWIP_COMPILER_FLAGS})
+target_compile_definitions(example_app PRIVATE ${LWIP_DEFINITIONS} ${LWIP_MBEDTLS_DEFINITIONS})
+target_link_libraries(example_app ${LWIP_SANITIZER_LIBS} lwipcontribexamples lwipcontribapps lwipcontribaddons lwipallapps lwipcore lwipcontribportwindows)
+
+add_executable(makefsdata ${lwipmakefsdata_SRCS})
+target_compile_options(makefsdata PRIVATE ${LWIP_COMPILER_FLAGS})
+target_include_directories(makefsdata PRIVATE ${LWIP_INCLUDE_DIRS})
+target_link_libraries(makefsdata ${LWIP_SANITIZER_LIBS} lwipcore lwipcontribportwindows)
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/ports/win32/example_app/Makefile
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/ports/win32/example_app/Makefile	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/ports/win32/example_app/Makefile	(revision 457)
@@ -0,0 +1,55 @@
+#
+# Copyright (c) 2001, 2002 Swedish Institute of Computer Science.
+# 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. The name of the author may not be used to endorse or promote products
+#    derived from this software without specific prior written permission. 
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+#
+# This file is part of the lwIP TCP/IP stack.
+# 
+# Author: Adam Dunkels <adam@sics.se>
+#
+
+all compile: example_app makefsdata
+.PHONY: all
+
+include ../Common.mk
+
+CFLAGS+=-I$(CONTRIBDIR)/examples/example_app
+
+MAKEFSDATAOBJS=$(notdir $(MAKEFSDATAFILES:.c=.o))
+
+clean:
+	cmd /c del /q *.o $(LWIPLIBCOMMON) $(APPLIB) test.exe *.s .depend* *.map
+
+depend dep: .depend
+
+include .depend
+
+.depend: $(CONTRIBDIR)/examples/example_app/test.c default_netif.c $(LWIPFILES) $(APPFILES) $(MAKEFSDATAFILES)
+	$(CCDEP) $(CFLAGS) -MM $^ > .depend || cmd /c del .depend
+
+example_app: .depend $(LWIPLIBCOMMON) $(APPLIB) default_netif.o test.o
+	$(CC) $(CFLAGS) -o example_app test.o default_netif.o -Wl,--start-group $(APPLIB) $(LWIPLIBCOMMON) -Wl,--end-group $(LDFLAGS) -Xlinker -Map=test.map
+
+makefsdata: .depend $(MAKEFSDATAOBJS)
+	$(CC) $(CFLAGS) -o makefsdata $(MAKEFSDATAOBJS)
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/ports/win32/example_app/default_netif.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/ports/win32/example_app/default_netif.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/ports/win32/example_app/default_netif.c	(revision 457)
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2001-2003 Swedish Institute of Computer Science.
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission. 
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ * 
+ * Author: Adam Dunkels <adam@sics.se>
+ *
+ */
+
+#include "lwip/opt.h"
+
+#include "lwip/netif.h"
+#include "lwip/ip_addr.h"
+#include "lwip/tcpip.h"
+#include "../pcapif.h"
+#include "examples/example_app/default_netif.h"
+
+static struct netif netif;
+
+#if LWIP_IPV4
+#define NETIF_ADDRS ipaddr, netmask, gw,
+void init_default_netif(const ip4_addr_t *ipaddr, const ip4_addr_t *netmask, const ip4_addr_t *gw)
+#else
+#define NETIF_ADDRS
+void init_default_netif(void)
+#endif
+{
+#if NO_SYS
+  netif_add(&netif, NETIF_ADDRS NULL, pcapif_init, netif_input);
+#else  /* NO_SYS */
+  netif_add(&netif, NETIF_ADDRS NULL, pcapif_init, tcpip_input);
+#endif /* NO_SYS */
+  netif_set_default(&netif);
+}
+
+void
+default_netif_poll(void)
+{
+#if !PCAPIF_RX_USE_THREAD
+  /* check for packets and link status*/
+  pcapif_poll(&netif);
+  /* When pcapif_poll comes back, there are not packets, so sleep to
+     prevent 100% CPU load. Don't do this in an embedded system since it
+     increases latency! */
+  sys_msleep(1);
+#else /* !PCAPIF_RX_USE_THREAD */
+  sys_msleep(50);
+#endif /* !PCAPIF_RX_USE_THREAD */
+}
+
+void
+default_netif_shutdown(void)
+{
+  /* release the pcap library... */
+  pcapif_shutdown(&netif);
+}
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/ports/win32/include/arch/bpstruct.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/ports/win32/include/arch/bpstruct.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/ports/win32/include/arch/bpstruct.h	(revision 457)
@@ -0,0 +1,1 @@
+#pragma pack(push,1)
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/ports/win32/include/arch/cc.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/ports/win32/include/arch/cc.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/ports/win32/include/arch/cc.h	(revision 457)
@@ -0,0 +1,112 @@
+/*
+ * Copyright (c) 2001-2003 Swedish Institute of Computer Science.
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission. 
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ * 
+ * Author: Adam Dunkels <adam@sics.se>
+ *
+ */
+#ifndef LWIP_ARCH_CC_H
+#define LWIP_ARCH_CC_H
+
+#ifdef _MSC_VER
+#pragma warning (disable: 4127) /* conditional expression is constant */
+#pragma warning (disable: 4996) /* 'strncpy' was declared deprecated */
+#pragma warning (disable: 4103) /* structure packing changed by including file */
+#pragma warning (disable: 4820) /* 'x' bytes padding added after data member 'y' */
+#pragma warning (disable: 4711) /* The compiler performed inlining on the given function, although it was not marked for inlining */
+#endif
+
+#ifdef _MSC_VER
+#if _MSC_VER >= 1910
+#include <errno.h> /* use MSVC errno for >= 2017 */
+#else
+#define LWIP_PROVIDE_ERRNO /* provide errno for MSVC pre-2017 */
+#endif
+#else /* _MSC_VER */
+#define LWIP_PROVIDE_ERRNO /* provide errno for non-MSVC */
+#endif /* _MSC_VER */
+
+/* Define platform endianness (might already be defined) */
+#ifndef BYTE_ORDER
+#define BYTE_ORDER LITTLE_ENDIAN
+#endif /* BYTE_ORDER */
+
+typedef int sys_prot_t;
+
+#ifdef _MSC_VER
+/* define _INTPTR for Win32 MSVC stdint.h */
+#define _INTPTR 2
+
+/* Do not use lwIP default definitions for format strings 
+ * because these do not work with MSVC 2010 compiler (no inttypes.h)
+ */
+#define LWIP_NO_INTTYPES_H 1
+
+/* Define (sn)printf formatters for these lwIP types */
+#define X8_F  "02x"
+#define U16_F "hu"
+#define U32_F "lu"
+#define S32_F "ld"
+#define X32_F "lx"
+
+#define S16_F "hd"
+#define X16_F "hx"
+#define SZT_F "lu"
+#endif /* _MSC_VER */
+
+/* Compiler hints for packing structures */
+#define PACK_STRUCT_USE_INCLUDES
+
+#define LWIP_ERROR(message, expression, handler) do { if (!(expression)) { \
+  printf("Assertion \"%s\" failed at line %d in %s\n", message, __LINE__, __FILE__); \
+  fflush(NULL);handler;} } while(0)
+
+#ifdef _MSC_VER
+/* C runtime functions redefined */
+#if _MSC_VER < 1910
+#define snprintf _snprintf
+#endif
+#define strdup   _strdup
+#endif
+
+/* Define an example for LWIP_PLATFORM_DIAG: since this uses varargs and the old
+ * C standard lwIP targets does not support this in macros, we have extra brackets
+ * around the arguments, which are left out in the following macro definition:
+ */
+#if !defined(LWIP_TESTMODE) || !LWIP_TESTMODE
+void lwip_win32_platform_diag(const char *format, ...);
+#define LWIP_PLATFORM_DIAG(x) lwip_win32_platform_diag x
+#endif
+
+#ifndef LWIP_NORAND
+extern unsigned int sys_win_rand(void);
+#define LWIP_RAND() (sys_win_rand())
+#endif
+
+#define PPP_INCLUDE_SETTINGS_HEADER
+
+#endif /* LWIP_ARCH_CC_H */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/ports/win32/include/arch/epstruct.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/ports/win32/include/arch/epstruct.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/ports/win32/include/arch/epstruct.h	(revision 457)
@@ -0,0 +1,1 @@
+#pragma pack(pop)
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/ports/win32/include/arch/perf.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/ports/win32/include/arch/perf.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/ports/win32/include/arch/perf.h	(revision 457)
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2001, Swedish Institute of Computer Science.
+ * 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 Institute 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 INSTITUTE 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 INSTITUTE 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. 
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ * 
+ * Author: Adam Dunkels <adam@sics.se>
+ *
+ */
+#ifndef LWIP_PERF_H
+#define LWIP_PERF_H
+
+#define PERF_START    /* null definition */
+#define PERF_STOP(x)  /* null definition */
+
+#endif /* LWIP_PERF_H */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/ports/win32/include/arch/sys_arch.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/ports/win32/include/arch/sys_arch.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/ports/win32/include/arch/sys_arch.h	(revision 457)
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 2001-2003 Swedish Institute of Computer Science.
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission. 
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ * 
+ * Author: Adam Dunkels <adam@sics.se>
+ *
+ */
+#ifndef LWIP_ARCH_SYS_ARCH_H
+#define LWIP_ARCH_SYS_ARCH_H
+
+/* HANDLE is used for sys_sem_t but we won't include windows.h */
+struct _sys_sem {
+  void *sem;
+};
+typedef struct _sys_sem sys_sem_t;
+#define sys_sem_valid_val(sema) (((sema).sem != NULL)  && ((sema).sem != (void*)-1))
+#define sys_sem_valid(sema) (((sema) != NULL) && sys_sem_valid_val(*(sema)))
+#define sys_sem_set_invalid(sema) ((sema)->sem = NULL)
+
+/* HANDLE is used for sys_mutex_t but we won't include windows.h */
+struct _sys_mut {
+  void *mut;
+};
+typedef struct _sys_mut sys_mutex_t;
+#define sys_mutex_valid_val(mutex) (((mutex).mut != NULL)  && ((mutex).mut != (void*)-1))
+#define sys_mutex_valid(mutex) (((mutex) != NULL) && sys_mutex_valid_val(*(mutex)))
+#define sys_mutex_set_invalid(mutex) ((mutex)->mut = NULL)
+
+#ifndef MAX_QUEUE_ENTRIES
+#define MAX_QUEUE_ENTRIES 100
+#endif
+struct lwip_mbox {
+  void* sem;
+  void* q_mem[MAX_QUEUE_ENTRIES];
+  u32_t head, tail;
+};
+typedef struct lwip_mbox sys_mbox_t;
+#define SYS_MBOX_NULL NULL
+#define sys_mbox_valid_val(mbox) (((mbox).sem != NULL)  && ((mbox).sem != (void*)-1))
+#define sys_mbox_valid(mbox) ((mbox != NULL) && sys_mbox_valid_val(*(mbox)))
+#define sys_mbox_set_invalid(mbox) ((mbox)->sem = NULL)
+
+/* DWORD (thread id) is used for sys_thread_t but we won't include windows.h */
+typedef u32_t sys_thread_t;
+
+sys_sem_t* sys_arch_netconn_sem_get(void);
+void sys_arch_netconn_sem_alloc(void);
+void sys_arch_netconn_sem_free(void);
+#define LWIP_NETCONN_THREAD_SEM_GET()   sys_arch_netconn_sem_get()
+#define LWIP_NETCONN_THREAD_SEM_ALLOC() sys_arch_netconn_sem_alloc()
+#define LWIP_NETCONN_THREAD_SEM_FREE()  sys_arch_netconn_sem_free()
+
+#define LWIP_EXAMPLE_APP_ABORT() lwip_win32_keypressed()
+int lwip_win32_keypressed(void);
+
+#endif /* LWIP_ARCH_SYS_ARCH_H */
+
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/ports/win32/msvc/build_coverity.cmd
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/ports/win32/msvc/build_coverity.cmd	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/ports/win32/msvc/build_coverity.cmd	(revision 457)
@@ -0,0 +1,26 @@
+@echo off
+rem Usage: pass the path to cov-build.exe (with trailing backslash, without the exe) as first parameter
+rem ATTENTION: this deletes the output folder "cov-int" and the output file "cov-int.zip" first!
+
+set devenv="%ProgramFiles%\Microsoft Visual Studio 10.0\Common7\IDE\devenv.exe"
+if not exist %devenv% set devenv="%ProgramFiles%\Microsoft Visual Studio 10.0\Common7\IDE\vcexpress.exe"
+if not exist %devenv% set devenv="%ProgramFiles(x86)%\Microsoft Visual Studio 10.0\Common7\IDE\devenv.exe"
+if not exist %devenv% set devenv="%ProgramFiles(x86)%\Microsoft Visual Studio 10.0\Common7\IDE\vcexpress.exe"
+set covbuild=%1cov-build.exe
+set covoutput=cov-int
+set zip7="c:\Program Files\7-Zip\7z.exe"
+
+pushd %~dp0
+
+if exist %covoutput% rd /s /q %covoutput%
+if exist %covoutput%.zip del %covoutput%.zip
+
+%covbuild% --dir %covoutput% %devenv% lwip_test.sln /build Debug || goto error
+
+if exist %zip7% goto dozip
+echo error: 7zip not found at \"%zip7%
+goto error
+:dozip
+%zip7% a %covoutput%.zip %covoutput%
+:error
+popd
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/ports/win32/msvc/libcheck.vcxproj
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/ports/win32/msvc/libcheck.vcxproj	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/ports/win32/msvc/libcheck.vcxproj	(revision 457)
@@ -0,0 +1,100 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup Label="ProjectConfigurations">
+    <ProjectConfiguration Include="Debug|Win32">
+      <Configuration>Debug</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|Win32">
+      <Configuration>Release</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+  </ItemGroup>
+  <PropertyGroup Label="Globals">
+    <ProjectGuid>{EBB156DC-01BF-47B2-B69C-1A750B6B5F09}</ProjectGuid>
+    <RootNamespace>libcheck</RootNamespace>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+    <ConfigurationType>StaticLibrary</ConfigurationType>
+    <CharacterSet>MultiByte</CharacterSet>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+    <ConfigurationType>StaticLibrary</ConfigurationType>
+    <CharacterSet>MultiByte</CharacterSet>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+  <ImportGroup Label="ExtensionSettings">
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <PropertyGroup Label="UserMacros" />
+  <PropertyGroup>
+    <_ProjectFileVersion>10.0.40219.1</_ProjectFileVersion>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(Configuration)\$(ProjectName)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(Configuration)\$(ProjectName)\</IntDir>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(Configuration)\$(ProjectName)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(Configuration)\$(ProjectName)\</IntDir>
+  </PropertyGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <ClCompile>
+      <Optimization>Disabled</Optimization>
+      <AdditionalIncludeDirectories>..\check;..\..\..\..\check\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>_LIB;WIN32;_DEBUG;HAVE_CONFIG_H;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <MinimalRebuild>true</MinimalRebuild>
+      <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+      <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
+      <WarningLevel>Level3</WarningLevel>
+      <DebugInformationFormat>EditAndContinue</DebugInformationFormat>
+    </ClCompile>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <ClCompile>
+      <Optimization>MaxSpeed</Optimization>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <AdditionalIncludeDirectories>..\check;..\..\..\..\check\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>WIN32;NDEBUG;_LIB;HAVE_CONFIG_H;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <WarningLevel>Level3</WarningLevel>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+    </ClCompile>
+  </ItemDefinitionGroup>
+  <ItemGroup>
+    <ClInclude Include="..\..\..\..\check\lib\libcompat.h" />
+    <ClInclude Include="..\check\config.h" />
+    <ClInclude Include="..\check\unistd.h" />
+    <ClInclude Include="..\check\sys\time.h" />
+    <ClInclude Include="..\..\..\..\check\src\check.h" />
+    <ClInclude Include="..\..\..\..\check\src\check_error.h" />
+    <ClInclude Include="..\..\..\..\check\src\check_impl.h" />
+    <ClInclude Include="..\..\..\..\check\src\check_list.h" />
+    <ClInclude Include="..\..\..\..\check\src\check_log.h" />
+    <ClInclude Include="..\..\..\..\check\src\check_msg.h" />
+    <ClInclude Include="..\..\..\..\check\src\check_pack.h" />
+    <ClInclude Include="..\..\..\..\check\src\check_print.h" />
+    <ClInclude Include="..\..\..\..\check\src\check_str.h" />
+  </ItemGroup>
+  <ItemGroup>
+    <ClCompile Include="..\..\..\..\check\lib\clock_gettime.c" />
+    <ClCompile Include="..\..\..\..\check\lib\libcompat.c" />
+    <ClCompile Include="..\check\time.c" />
+    <ClCompile Include="..\..\..\..\check\src\check.c" />
+    <ClCompile Include="..\..\..\..\check\src\check_error.c" />
+    <ClCompile Include="..\..\..\..\check\src\check_list.c" />
+    <ClCompile Include="..\..\..\..\check\src\check_log.c" />
+    <ClCompile Include="..\..\..\..\check\src\check_msg.c" />
+    <ClCompile Include="..\..\..\..\check\src\check_pack.c" />
+    <ClCompile Include="..\..\..\..\check\src\check_print.c" />
+    <ClCompile Include="..\..\..\..\check\src\check_run.c" />
+    <ClCompile Include="..\..\..\..\check\src\check_str.c" />
+  </ItemGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+  <ImportGroup Label="ExtensionTargets">
+  </ImportGroup>
+</Project>
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/ports/win32/msvc/libcheck.vcxproj.filters
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/ports/win32/msvc/libcheck.vcxproj.filters	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/ports/win32/msvc/libcheck.vcxproj.filters	(revision 457)
@@ -0,0 +1,96 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup>
+    <Filter Include="Win32">
+      <UniqueIdentifier>{05d172f9-8ca6-4d9c-96e4-2b0480a8222f}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="Win32\sys">
+      <UniqueIdentifier>{eb9ccf88-7e08-4202-bb4f-5a51443fa480}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="src">
+      <UniqueIdentifier>{3f044d95-ab52-45ce-b4ae-27797eb221b2}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="libcompat">
+      <UniqueIdentifier>{abb21abe-51c2-45df-bdc9-8e00ce7fe404}</UniqueIdentifier>
+    </Filter>
+  </ItemGroup>
+  <ItemGroup>
+    <ClInclude Include="..\check\config.h">
+      <Filter>Win32</Filter>
+    </ClInclude>
+    <ClInclude Include="..\check\unistd.h">
+      <Filter>Win32</Filter>
+    </ClInclude>
+    <ClInclude Include="..\check\sys\time.h">
+      <Filter>Win32\sys</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\..\check\src\check.h">
+      <Filter>src</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\..\check\src\check_error.h">
+      <Filter>src</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\..\check\src\check_impl.h">
+      <Filter>src</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\..\check\src\check_list.h">
+      <Filter>src</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\..\check\src\check_log.h">
+      <Filter>src</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\..\check\src\check_msg.h">
+      <Filter>src</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\..\check\src\check_pack.h">
+      <Filter>src</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\..\check\src\check_print.h">
+      <Filter>src</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\..\check\src\check_str.h">
+      <Filter>src</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\..\check\lib\libcompat.h">
+      <Filter>libcompat</Filter>
+    </ClInclude>
+  </ItemGroup>
+  <ItemGroup>
+    <ClCompile Include="..\check\time.c">
+      <Filter>Win32</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\check\src\check.c">
+      <Filter>src</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\check\src\check_error.c">
+      <Filter>src</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\check\src\check_list.c">
+      <Filter>src</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\check\src\check_log.c">
+      <Filter>src</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\check\src\check_msg.c">
+      <Filter>src</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\check\src\check_pack.c">
+      <Filter>src</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\check\src\check_print.c">
+      <Filter>src</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\check\src\check_run.c">
+      <Filter>src</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\check\src\check_str.c">
+      <Filter>src</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\check\lib\libcompat.c">
+      <Filter>libcompat</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\check\lib\clock_gettime.c">
+      <Filter>libcompat</Filter>
+    </ClCompile>
+  </ItemGroup>
+</Project>
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/ports/win32/msvc/lwIP.vcxproj
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/ports/win32/msvc/lwIP.vcxproj	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/ports/win32/msvc/lwIP.vcxproj	(revision 457)
@@ -0,0 +1,577 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup Label="ProjectConfigurations">
+    <ProjectConfiguration Include="Debug unittests|Win32">
+      <Configuration>Debug unittests</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Debug|Win32">
+      <Configuration>Debug</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release unittests|Win32">
+      <Configuration>Release unittests</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|Win32">
+      <Configuration>Release</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+  </ItemGroup>
+  <PropertyGroup Label="Globals">
+    <ProjectGuid>{2CC276FA-B226-49C9-8F82-7FCD5A228E28}</ProjectGuid>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release unittests|Win32'" Label="Configuration">
+    <ConfigurationType>StaticLibrary</ConfigurationType>
+    <UseOfMfc>false</UseOfMfc>
+    <CharacterSet>MultiByte</CharacterSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug unittests|Win32'" Label="Configuration">
+    <ConfigurationType>StaticLibrary</ConfigurationType>
+    <UseOfMfc>false</UseOfMfc>
+    <CharacterSet>MultiByte</CharacterSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+    <ConfigurationType>StaticLibrary</ConfigurationType>
+    <UseOfMfc>false</UseOfMfc>
+    <CharacterSet>MultiByte</CharacterSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+    <ConfigurationType>StaticLibrary</ConfigurationType>
+    <UseOfMfc>false</UseOfMfc>
+    <CharacterSet>MultiByte</CharacterSet>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+  <ImportGroup Label="ExtensionSettings">
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release unittests|Win32'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+    <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug unittests|Win32'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+    <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+    <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+    <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />
+  </ImportGroup>
+  <PropertyGroup Label="UserMacros" />
+  <PropertyGroup>
+    <_ProjectFileVersion>10.0.40219.1</_ProjectFileVersion>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(Configuration)\$(ProjectName)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(Configuration)\$(ProjectName)\</IntDir>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug unittests|Win32'">$(Configuration)\$(ProjectName)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug unittests|Win32'">$(Configuration)\$(ProjectName)\</IntDir>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Release unittests|Win32'">$(Configuration)\$(ProjectName)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Release unittests|Win32'">$(Configuration)\$(ProjectName)\</IntDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(Configuration)\$(ProjectName)\</IntDir>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(Configuration)\$(ProjectName)\</OutDir>
+  </PropertyGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <ClCompile>
+      <Optimization>MaxSpeed</Optimization>
+      <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+      <AdditionalIncludeDirectories>..\..\..\..\lwip\src\include;..\..\..\..\lwip\src\include\ipv4;..\..\..\..\lwip\src\include\ipv6;..\include;..\..\..\examples\example_app;..\..\..\apps\snmp_private_mib;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <StringPooling>true</StringPooling>
+      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <ProgramDataBaseFileName>$(IntDir)$(ProjectName).pdb</ProgramDataBaseFileName>
+      <WarningLevel>EnableAllWarnings</WarningLevel>
+      <SuppressStartupBanner>true</SuppressStartupBanner>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+      <CompileAs>Default</CompileAs>
+      <TreatWarningAsError>true</TreatWarningAsError>
+    </ClCompile>
+    <ResourceCompile>
+      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <Culture>0x0407</Culture>
+    </ResourceCompile>
+    <Lib>
+      <SuppressStartupBanner>true</SuppressStartupBanner>
+    </Lib>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <ClCompile>
+      <Optimization>Disabled</Optimization>
+      <AdditionalIncludeDirectories>..\..\..\..\lwip\src\include;..\..\..\..\lwip\src\include\ipv4;..\..\..\..\lwip\src\include\ipv6;..\include;..\..\..\examples\example_app;..\..\..\apps\snmp_private_mib;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>_LIB;WIN32;_DEBUG;LWIP_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+      <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <ProgramDataBaseFileName>$(IntDir)$(ProjectName).pdb</ProgramDataBaseFileName>
+      <WarningLevel>EnableAllWarnings</WarningLevel>
+      <SuppressStartupBanner>true</SuppressStartupBanner>
+      <DebugInformationFormat>EditAndContinue</DebugInformationFormat>
+      <CompileAs>Default</CompileAs>
+      <TreatWarningAsError>true</TreatWarningAsError>
+    </ClCompile>
+    <ResourceCompile>
+      <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <Culture>0x0407</Culture>
+    </ResourceCompile>
+    <Lib>
+      <SuppressStartupBanner>true</SuppressStartupBanner>
+    </Lib>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug unittests|Win32'">
+    <ClCompile>
+      <Optimization>Disabled</Optimization>
+      <AdditionalIncludeDirectories>..\..\..\..\lwip\test\unit;..\..\..\..\lwip\src\include;..\..\..\..\lwip\src\include\ipv4;..\..\..\..\lwip\src\include\ipv6;..\include;..\..\..\examples\example_app;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>LWIP_NORAND;_LIB;WIN32;_DEBUG;LWIP_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+      <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <ProgramDataBaseFileName>$(IntDir)$(ProjectName).pdb</ProgramDataBaseFileName>
+      <WarningLevel>EnableAllWarnings</WarningLevel>
+      <SuppressStartupBanner>true</SuppressStartupBanner>
+      <DebugInformationFormat>EditAndContinue</DebugInformationFormat>
+      <CompileAs>Default</CompileAs>
+      <TreatWarningAsError>true</TreatWarningAsError>
+    </ClCompile>
+    <ResourceCompile>
+      <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <Culture>0x0407</Culture>
+    </ResourceCompile>
+    <Lib>
+      <SuppressStartupBanner>true</SuppressStartupBanner>
+    </Lib>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release unittests|Win32'">
+    <ClCompile>
+      <Optimization>MaxSpeed</Optimization>
+      <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+      <AdditionalIncludeDirectories>..\..\..\..\lwip\test\unit;..\..\..\..\lwip\src\include;..\..\..\..\lwip\src\include\ipv4;..\..\..\..\lwip\src\include\ipv6;..\include;..\..\..\examples\example_app;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>LWIP_NORAND;WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <StringPooling>true</StringPooling>
+      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <ProgramDataBaseFileName>$(IntDir)$(ProjectName).pdb</ProgramDataBaseFileName>
+      <WarningLevel>EnableAllWarnings</WarningLevel>
+      <SuppressStartupBanner>true</SuppressStartupBanner>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+      <CompileAs>Default</CompileAs>
+      <TreatWarningAsError>true</TreatWarningAsError>
+    </ClCompile>
+    <ResourceCompile>
+      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <Culture>0x0407</Culture>
+    </ResourceCompile>
+    <Lib>
+      <SuppressStartupBanner>true</SuppressStartupBanner>
+    </Lib>
+  </ItemDefinitionGroup>
+  <ItemGroup>
+    <CustomBuildStep Include="..\..\..\..\lwip\doc\contrib.txt">
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug unittests|Win32'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release unittests|Win32'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
+    </CustomBuildStep>
+    <CustomBuildStep Include="..\..\..\..\lwip\doc\FILES">
+      <FileType>Document</FileType>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug unittests|Win32'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release unittests|Win32'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
+    </CustomBuildStep>
+    <CustomBuildStep Include="..\..\..\..\lwip\doc\rawapi.txt">
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug unittests|Win32'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release unittests|Win32'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
+    </CustomBuildStep>
+    <CustomBuildStep Include="..\..\..\..\lwip\doc\savannah.txt">
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug unittests|Win32'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release unittests|Win32'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
+    </CustomBuildStep>
+    <CustomBuildStep Include="..\..\..\..\lwip\doc\snmp_agent.txt">
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug unittests|Win32'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release unittests|Win32'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
+    </CustomBuildStep>
+    <CustomBuildStep Include="..\..\..\..\lwip\doc\sys_arch.txt">
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug unittests|Win32'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release unittests|Win32'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
+    </CustomBuildStep>
+    <CustomBuildStep Include="..\..\..\..\lwip\src\core\ipv6\README">
+      <FileType>Document</FileType>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug unittests|Win32'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release unittests|Win32'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
+    </CustomBuildStep>
+    <CustomBuildStep Include="..\..\..\..\lwip\src\netif\FILES">
+      <FileType>Document</FileType>
+    </CustomBuildStep>
+    <CustomBuildStep Include="..\lwipcfg_msvc.h.example">
+      <FileType>Document</FileType>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug unittests|Win32'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release unittests|Win32'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
+    </CustomBuildStep>
+    <None Include="..\..\..\..\lwip\CHANGELOG" />
+    <None Include="..\..\..\..\lwip\COPYING" />
+    <None Include="..\..\..\..\lwip\doc\contrib.txt" />
+    <None Include="..\..\..\..\lwip\doc\doxygen\generate.bat" />
+    <None Include="..\..\..\..\lwip\doc\doxygen\generate.sh" />
+    <None Include="..\..\..\..\lwip\doc\doxygen\lwip.Doxyfile" />
+    <None Include="..\..\..\..\lwip\doc\FILES" />
+    <None Include="..\..\..\..\lwip\doc\mdns.txt" />
+    <None Include="..\..\..\..\lwip\doc\ppp.txt" />
+    <None Include="..\..\..\..\lwip\doc\savannah.txt" />
+    <None Include="..\..\..\..\lwip\FILES" />
+    <None Include="..\..\..\..\lwip\README" />
+    <None Include="..\..\..\..\lwip\UPGRADING" />
+    <None Include="..\..\..\examples\example_app\lwipcfg.h.example">
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug unittests|Win32'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release unittests|Win32'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
+    </None>
+  </ItemGroup>
+  <ItemGroup>
+    <ClCompile Include="..\..\..\..\lwip\doc\NO_SYS_SampleCode.c">
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug unittests|Win32'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release unittests|Win32'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\lwip\src\api\api_lib.c" />
+    <ClCompile Include="..\..\..\..\lwip\src\api\api_msg.c" />
+    <ClCompile Include="..\..\..\..\lwip\src\api\err.c" />
+    <ClCompile Include="..\..\..\..\lwip\src\api\if_api.c" />
+    <ClCompile Include="..\..\..\..\lwip\src\api\netbuf.c" />
+    <ClCompile Include="..\..\..\..\lwip\src\api\netdb.c" />
+    <ClCompile Include="..\..\..\..\lwip\src\api\netifapi.c" />
+    <ClCompile Include="..\..\..\..\lwip\src\api\sockets.c" />
+    <ClCompile Include="..\..\..\..\lwip\src\api\tcpip.c" />
+    <ClCompile Include="..\..\..\..\lwip\src\apps\altcp_tls\altcp_tls_mbedtls.c">
+      <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">..\..\..\..\mbedtls\include;..\..\..\..\lwip\src\include;..\..\..\..\lwip\src\include\ipv4;..\..\..\..\lwip\src\include\ipv6;..\include;..;..\..\..\apps\snmp_private_mib;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">..\..\..\..\mbedtls\include;..\..\..\..\lwip\src\include;..\..\..\..\lwip\src\include\ipv4;..\..\..\..\lwip\src\include\ipv6;..\include;..;..\..\..\apps\snmp_private_mib;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug unittests|Win32'">..\..\..\..\mbedtls\include;..\..\..\..\lwip\test\unit;..\..\..\..\lwip\src\include;..\..\..\..\lwip\src\include\ipv4;..\..\..\..\lwip\src\include\ipv6;..\include;..;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release unittests|Win32'">..\..\..\..\mbedtls\include;..\..\..\..\lwip\test\unit;..\..\..\..\lwip\src\include;..\..\..\..\lwip\src\include\ipv4;..\..\..\..\lwip\src\include\ipv6;..\include;..;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\lwip\src\apps\altcp_tls\altcp_tls_mbedtls_mem.c">
+      <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">..\..\..\..\mbedtls\include;..\..\..\..\lwip\src\include;..\..\..\..\lwip\src\include\ipv4;..\..\..\..\lwip\src\include\ipv6;..\include;..;..\..\..\apps\snmp_private_mib;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">..\..\..\..\mbedtls\include;..\..\..\..\lwip\src\include;..\..\..\..\lwip\src\include\ipv4;..\..\..\..\lwip\src\include\ipv6;..\include;..;..\..\..\apps\snmp_private_mib;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug unittests|Win32'">..\..\..\..\mbedtls\include;..\..\..\..\lwip\test\unit;..\..\..\..\lwip\src\include;..\..\..\..\lwip\src\include\ipv4;..\..\..\..\lwip\src\include\ipv6;..\include;..;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release unittests|Win32'">..\..\..\..\mbedtls\include;..\..\..\..\lwip\test\unit;..\..\..\..\lwip\src\include;..\..\..\..\lwip\src\include\ipv4;..\..\..\..\lwip\src\include\ipv6;..\include;..;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\lwip\src\apps\http\altcp_proxyconnect.c" />
+    <ClCompile Include="..\..\..\..\lwip\src\apps\http\http_client.c" />
+    <ClCompile Include="..\..\..\..\lwip\src\apps\lwiperf\lwiperf.c" />
+    <ClCompile Include="..\..\..\..\lwip\src\apps\mqtt\mqtt.c" />
+    <ClCompile Include="..\..\..\..\lwip\src\apps\netbiosns\netbiosns.c" />
+    <ClCompile Include="..\..\..\..\lwip\src\apps\smtp\smtp.c" />
+    <ClCompile Include="..\..\..\..\lwip\src\apps\snmp\snmp_snmpv2_framework.c" />
+    <ClCompile Include="..\..\..\..\lwip\src\apps\snmp\snmp_snmpv2_usm.c" />
+    <ClCompile Include="..\..\..\..\lwip\src\apps\sntp\sntp.c" />
+    <ClCompile Include="..\..\..\..\lwip\src\apps\tftp\tftp_server.c" />
+    <ClCompile Include="..\..\..\..\lwip\src\core\altcp.c" />
+    <ClCompile Include="..\..\..\..\lwip\src\core\altcp_alloc.c" />
+    <ClCompile Include="..\..\..\..\lwip\src\core\altcp_tcp.c" />
+    <ClCompile Include="..\..\..\..\lwip\src\core\def.c" />
+    <ClCompile Include="..\..\..\..\lwip\src\core\dns.c" />
+    <ClCompile Include="..\..\..\..\lwip\src\core\inet_chksum.c" />
+    <ClCompile Include="..\..\..\..\lwip\src\core\init.c" />
+    <ClCompile Include="..\..\..\..\lwip\src\core\mem.c" />
+    <ClCompile Include="..\..\..\..\lwip\src\core\memp.c" />
+    <ClCompile Include="..\..\..\..\lwip\src\core\netif.c" />
+    <ClCompile Include="..\..\..\..\lwip\src\core\pbuf.c" />
+    <ClCompile Include="..\..\..\..\lwip\src\core\raw.c" />
+    <ClCompile Include="..\..\..\..\lwip\src\core\stats.c" />
+    <ClCompile Include="..\..\..\..\lwip\src\core\sys.c" />
+    <ClCompile Include="..\..\..\..\lwip\src\core\tcp.c" />
+    <ClCompile Include="..\..\..\..\lwip\src\core\tcp_in.c" />
+    <ClCompile Include="..\..\..\..\lwip\src\core\tcp_out.c" />
+    <ClCompile Include="..\..\..\..\lwip\src\core\udp.c" />
+    <ClCompile Include="..\..\..\..\lwip\src\core\ipv4\autoip.c" />
+    <ClCompile Include="..\..\..\..\lwip\src\core\ipv4\dhcp.c" />
+    <ClCompile Include="..\..\..\..\lwip\src\core\ipv4\etharp.c" />
+    <ClCompile Include="..\..\..\..\lwip\src\core\ipv4\icmp.c" />
+    <ClCompile Include="..\..\..\..\lwip\src\core\ipv4\igmp.c" />
+    <ClCompile Include="..\..\..\..\lwip\src\core\ipv4\ip4.c" />
+    <ClCompile Include="..\..\..\..\lwip\src\core\ipv4\ip4_addr.c" />
+    <ClCompile Include="..\..\..\..\lwip\src\core\ipv6\dhcp6.c" />
+    <ClCompile Include="..\..\..\..\lwip\src\core\ipv6\ethip6.c" />
+    <ClCompile Include="..\..\..\..\lwip\src\core\ipv6\icmp6.c" />
+    <ClCompile Include="..\..\..\..\lwip\src\core\ipv6\inet6.c" />
+    <ClCompile Include="..\..\..\..\lwip\src\core\ipv6\ip6.c" />
+    <ClCompile Include="..\..\..\..\lwip\src\core\ipv6\ip6_addr.c" />
+    <ClCompile Include="..\..\..\..\lwip\src\core\ipv6\ip6_frag.c" />
+    <ClCompile Include="..\..\..\..\lwip\src\core\ipv6\mld6.c" />
+    <ClCompile Include="..\..\..\..\lwip\src\core\ipv6\nd6.c" />
+    <ClCompile Include="..\..\..\..\lwip\src\netif\bridgeif.c" />
+    <ClCompile Include="..\..\..\..\lwip\src\netif\bridgeif_fdb.c" />
+    <ClCompile Include="..\..\..\..\lwip\src\netif\ethernet.c" />
+    <ClCompile Include="..\..\..\..\lwip\src\netif\lowpan6.c" />
+    <ClCompile Include="..\..\..\..\lwip\src\netif\lowpan6_ble.c" />
+    <ClCompile Include="..\..\..\..\lwip\src\netif\lowpan6_common.c" />
+    <ClCompile Include="..\..\..\..\lwip\src\netif\slipif.c" />
+    <ClCompile Include="..\..\..\..\lwip\src\netif\ppp\auth.c" />
+    <ClCompile Include="..\..\..\..\lwip\src\netif\ppp\ccp.c" />
+    <ClCompile Include="..\..\..\..\lwip\src\netif\ppp\chap-md5.c" />
+    <ClCompile Include="..\..\..\..\lwip\src\netif\ppp\chap-new.c" />
+    <ClCompile Include="..\..\..\..\lwip\src\netif\ppp\chap_ms.c" />
+    <ClCompile Include="..\..\..\..\lwip\src\netif\ppp\demand.c" />
+    <ClCompile Include="..\..\..\..\lwip\src\netif\ppp\eap.c" />
+    <ClCompile Include="..\..\..\..\lwip\src\netif\ppp\ecp.c" />
+    <ClCompile Include="..\..\..\..\lwip\src\netif\ppp\eui64.c" />
+    <ClCompile Include="..\..\..\..\lwip\src\netif\ppp\fsm.c" />
+    <ClCompile Include="..\..\..\..\lwip\src\netif\ppp\ipcp.c" />
+    <ClCompile Include="..\..\..\..\lwip\src\netif\ppp\ipv6cp.c" />
+    <ClCompile Include="..\..\..\..\lwip\src\netif\ppp\lcp.c" />
+    <ClCompile Include="..\..\..\..\lwip\src\netif\ppp\magic.c" />
+    <ClCompile Include="..\..\..\..\lwip\src\netif\ppp\mppe.c" />
+    <ClCompile Include="..\..\..\..\lwip\src\netif\ppp\multilink.c" />
+    <ClCompile Include="..\..\..\..\lwip\src\netif\ppp\ppp.c" />
+    <ClCompile Include="..\..\..\..\lwip\src\netif\ppp\pppcrypt.c" />
+    <ClCompile Include="..\..\..\..\lwip\src\netif\ppp\pppoe.c" />
+    <ClCompile Include="..\..\..\..\lwip\src\netif\ppp\pppol2tp.c" />
+    <ClCompile Include="..\..\..\..\lwip\src\netif\ppp\pppos.c" />
+    <ClCompile Include="..\..\..\..\lwip\src\netif\ppp\upap.c" />
+    <ClCompile Include="..\..\..\..\lwip\src\netif\ppp\utils.c" />
+    <ClCompile Include="..\..\..\..\lwip\src\netif\ppp\vj.c" />
+    <ClCompile Include="..\..\..\..\lwip\src\netif\ppp\polarssl\arc4.c" />
+    <ClCompile Include="..\..\..\..\lwip\src\netif\ppp\polarssl\des.c" />
+    <ClCompile Include="..\..\..\..\lwip\src\netif\ppp\polarssl\md4.c" />
+    <ClCompile Include="..\..\..\..\lwip\src\netif\ppp\polarssl\md5.c" />
+    <ClCompile Include="..\..\..\..\lwip\src\netif\ppp\polarssl\sha1.c" />
+    <ClCompile Include="..\..\..\..\lwip\src\apps\http\fs.c" />
+    <ClCompile Include="..\..\..\..\lwip\src\apps\http\fsdata.c">
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug unittests|Win32'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release unittests|Win32'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\lwip\src\apps\http\httpd.c" />
+    <ClCompile Include="..\..\..\..\lwip\src\apps\snmp\snmp_asn1.c" />
+    <ClCompile Include="..\..\..\..\lwip\src\apps\snmp\snmp_core.c" />
+    <ClCompile Include="..\..\..\..\lwip\src\apps\snmp\snmp_mib2.c" />
+    <ClCompile Include="..\..\..\..\lwip\src\apps\snmp\snmp_msg.c" />
+    <ClCompile Include="..\..\..\..\lwip\src\apps\snmp\snmp_netconn.c" />
+    <ClCompile Include="..\..\..\..\lwip\src\apps\snmp\snmp_pbuf_stream.c" />
+    <ClCompile Include="..\..\..\..\lwip\src\apps\snmp\snmp_raw.c" />
+    <ClCompile Include="..\..\..\..\lwip\src\apps\snmp\snmp_scalar.c" />
+    <ClCompile Include="..\..\..\..\lwip\src\apps\snmp\snmp_table.c" />
+    <ClCompile Include="..\..\..\..\lwip\src\apps\snmp\snmp_threadsync.c" />
+    <ClCompile Include="..\..\..\..\lwip\src\apps\snmp\snmp_traps.c" />
+    <ClCompile Include="..\..\..\..\lwip\src\core\ip.c" />
+    <ClCompile Include="..\..\..\..\lwip\src\apps\snmp\snmpv3.c" />
+    <ClCompile Include="..\..\..\..\lwip\src\apps\snmp\snmp_mib2_icmp.c" />
+    <ClCompile Include="..\..\..\..\lwip\src\apps\snmp\snmp_mib2_interfaces.c" />
+    <ClCompile Include="..\..\..\..\lwip\src\apps\snmp\snmp_mib2_ip.c" />
+    <ClCompile Include="..\..\..\..\lwip\src\apps\snmp\snmp_mib2_snmp.c" />
+    <ClCompile Include="..\..\..\..\lwip\src\apps\snmp\snmp_mib2_system.c" />
+    <ClCompile Include="..\..\..\..\lwip\src\apps\snmp\snmp_mib2_tcp.c" />
+    <ClCompile Include="..\..\..\..\lwip\src\apps\snmp\snmp_mib2_udp.c" />
+    <ClCompile Include="..\..\..\..\lwip\src\netif\ppp\pppapi.c" />
+    <ClCompile Include="..\..\..\..\lwip\src\core\ipv4\ip4_frag.c" />
+    <ClCompile Include="..\..\..\..\lwip\src\core\timeouts.c" />
+    <ClCompile Include="..\..\..\..\lwip\src\apps\mdns\mdns.c" />
+    <ClCompile Include="..\..\..\..\lwip\src\apps\snmp\snmpv3_mbedtls.c">
+      <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">..\..\..\..\mbedtls\include;..\..\..\..\lwip\src\include;..\..\..\..\lwip\src\include\ipv4;..\..\..\..\lwip\src\include\ipv6;..\include;..;..\..\..\apps\snmp_private_mib;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\lwip\src\netif\zepif.c" />
+    <ClCompile Include="..\sio.c" />
+    <ClCompile Include="..\sys_arch.c">
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug unittests|Win32'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release unittests|Win32'">true</ExcludedFromBuild>
+    </ClCompile>
+  </ItemGroup>
+  <ItemGroup>
+    <ClInclude Include="..\..\..\..\lwip\doc\doxygen\main_page.h" />
+    <ClInclude Include="..\..\..\..\lwip\src\apps\altcp_tls\altcp_tls_mbedtls_mem.h" />
+    <ClInclude Include="..\..\..\..\lwip\src\apps\altcp_tls\altcp_tls_mbedtls_structs.h" />
+    <ClInclude Include="..\..\..\..\lwip\src\apps\snmp\snmp_msg.h" />
+    <ClInclude Include="..\..\..\..\lwip\src\include\compat\stdc\errno.h" />
+    <ClInclude Include="..\..\..\..\lwip\src\include\compat\posix\arpa\inet.h" />
+    <ClInclude Include="..\..\..\..\lwip\src\include\compat\posix\netdb.h" />
+    <ClInclude Include="..\..\..\..\lwip\src\include\compat\posix\net\if.h" />
+    <ClInclude Include="..\..\..\..\lwip\src\include\compat\posix\sys\socket.h" />
+    <ClInclude Include="..\..\..\..\lwip\src\include\lwip\altcp.h" />
+    <ClInclude Include="..\..\..\..\lwip\src\include\lwip\altcp_tcp.h" />
+    <ClInclude Include="..\..\..\..\lwip\src\include\lwip\altcp_tls.h" />
+    <ClInclude Include="..\..\..\..\lwip\src\include\lwip\apps\altcp_proxyconnect.h" />
+    <ClInclude Include="..\..\..\..\lwip\src\include\lwip\apps\altcp_tls_mbedtls_opts.h" />
+    <ClInclude Include="..\..\..\..\lwip\src\include\lwip\apps\http_client.h" />
+    <ClInclude Include="..\..\..\..\lwip\src\include\lwip\apps\lwiperf.h" />
+    <ClInclude Include="..\..\..\..\lwip\src\include\lwip\apps\mdns_priv.h" />
+    <ClInclude Include="..\..\..\..\lwip\src\include\lwip\apps\mqtt.h" />
+    <ClInclude Include="..\..\..\..\lwip\src\include\lwip\apps\mqtt_opts.h" />
+    <ClInclude Include="..\..\..\..\lwip\src\include\lwip\apps\mqtt_priv.h" />
+    <ClInclude Include="..\..\..\..\lwip\src\include\lwip\apps\netbiosns.h" />
+    <ClInclude Include="..\..\..\..\lwip\src\include\lwip\apps\netbiosns_opts.h" />
+    <ClInclude Include="..\..\..\..\lwip\src\include\lwip\apps\smtp.h" />
+    <ClInclude Include="..\..\..\..\lwip\src\include\lwip\apps\smtp_opts.h" />
+    <ClInclude Include="..\..\..\..\lwip\src\include\lwip\apps\snmp.h" />
+    <ClInclude Include="..\..\..\..\lwip\src\include\lwip\apps\snmp_opts.h" />
+    <ClInclude Include="..\..\..\..\lwip\src\include\lwip\apps\snmp_snmpv2_framework.h" />
+    <ClInclude Include="..\..\..\..\lwip\src\include\lwip\apps\snmp_snmpv2_usm.h" />
+    <ClInclude Include="..\..\..\..\lwip\src\include\lwip\apps\sntp.h" />
+    <ClInclude Include="..\..\..\..\lwip\src\include\lwip\apps\sntp_opts.h" />
+    <ClInclude Include="..\..\..\..\lwip\src\include\lwip\apps\tftp_opts.h" />
+    <ClInclude Include="..\..\..\..\lwip\src\include\lwip\apps\tftp_server.h" />
+    <ClInclude Include="..\..\..\..\lwip\src\include\lwip\errno.h" />
+    <ClInclude Include="..\..\..\..\lwip\src\include\lwip\if_api.h" />
+    <ClInclude Include="..\..\..\..\lwip\src\include\lwip\ip6_zone.h" />
+    <ClInclude Include="..\..\..\..\lwip\src\include\lwip\priv\altcp_priv.h" />
+    <ClInclude Include="..\..\..\..\lwip\src\include\lwip\priv\api_msg.h" />
+    <ClInclude Include="..\..\..\..\lwip\src\include\lwip\priv\memp_priv.h" />
+    <ClInclude Include="..\..\..\..\lwip\src\include\lwip\priv\memp_std.h" />
+    <ClInclude Include="..\..\..\..\lwip\src\include\lwip\priv\mem_priv.h" />
+    <ClInclude Include="..\..\..\..\lwip\src\include\lwip\priv\nd6_priv.h" />
+    <ClInclude Include="..\..\..\..\lwip\src\include\lwip\priv\raw_priv.h" />
+    <ClInclude Include="..\..\..\..\lwip\src\include\lwip\priv\sockets_priv.h" />
+    <ClInclude Include="..\..\..\..\lwip\src\include\lwip\priv\tcpip_priv.h" />
+    <ClInclude Include="..\..\..\..\lwip\src\include\lwip\priv\tcp_priv.h" />
+    <ClInclude Include="..\..\..\..\lwip\src\include\lwip\api.h" />
+    <ClInclude Include="..\..\..\..\lwip\src\include\lwip\arch.h" />
+    <ClInclude Include="..\..\..\..\lwip\src\include\lwip\autoip.h" />
+    <ClInclude Include="..\..\..\..\lwip\src\include\lwip\debug.h" />
+    <ClInclude Include="..\..\..\..\lwip\src\include\lwip\def.h" />
+    <ClInclude Include="..\..\..\..\lwip\src\include\lwip\dhcp.h" />
+    <ClInclude Include="..\..\..\..\lwip\src\include\lwip\dhcp6.h" />
+    <ClInclude Include="..\..\..\..\lwip\src\include\lwip\dns.h" />
+    <ClInclude Include="..\..\..\..\lwip\src\include\lwip\err.h" />
+    <ClInclude Include="..\..\..\..\lwip\src\include\lwip\ethip6.h" />
+    <ClInclude Include="..\..\..\..\lwip\src\include\lwip\icmp.h" />
+    <ClInclude Include="..\..\..\..\lwip\src\include\lwip\icmp6.h" />
+    <ClInclude Include="..\..\..\..\lwip\src\include\lwip\igmp.h" />
+    <ClInclude Include="..\..\..\..\lwip\src\include\lwip\inet.h" />
+    <ClInclude Include="..\..\..\..\lwip\src\include\lwip\inet_chksum.h" />
+    <ClInclude Include="..\..\..\..\lwip\src\include\lwip\init.h" />
+    <ClInclude Include="..\..\..\..\lwip\src\include\lwip\ip.h" />
+    <ClInclude Include="..\..\..\..\lwip\src\include\lwip\ip4.h" />
+    <ClInclude Include="..\..\..\..\lwip\src\include\lwip\ip4_addr.h" />
+    <ClInclude Include="..\..\..\..\lwip\src\include\lwip\ip6.h" />
+    <ClInclude Include="..\..\..\..\lwip\src\include\lwip\ip6_addr.h" />
+    <ClInclude Include="..\..\..\..\lwip\src\include\lwip\ip6_frag.h" />
+    <ClInclude Include="..\..\..\..\lwip\src\include\lwip\ip_addr.h" />
+    <ClInclude Include="..\..\..\..\lwip\src\include\lwip\mem.h" />
+    <ClInclude Include="..\..\..\..\lwip\src\include\lwip\memp.h" />
+    <ClInclude Include="..\..\..\..\lwip\src\include\lwip\mld6.h" />
+    <ClInclude Include="..\..\..\..\lwip\src\include\lwip\nd6.h" />
+    <ClInclude Include="..\..\..\..\lwip\src\include\lwip\netbuf.h" />
+    <ClInclude Include="..\..\..\..\lwip\src\include\lwip\netdb.h" />
+    <ClInclude Include="..\..\..\..\lwip\src\include\lwip\netif.h" />
+    <ClInclude Include="..\..\..\..\lwip\src\include\lwip\netifapi.h" />
+    <ClInclude Include="..\..\..\..\lwip\src\include\lwip\opt.h" />
+    <ClInclude Include="..\..\..\..\lwip\src\include\lwip\pbuf.h" />
+    <ClInclude Include="..\..\..\..\lwip\src\include\lwip\prot\dhcp6.h" />
+    <ClInclude Include="..\..\..\..\lwip\src\include\lwip\prot\etharp.h" />
+    <ClInclude Include="..\..\..\..\lwip\src\include\lwip\prot\iana.h" />
+    <ClInclude Include="..\..\..\..\lwip\src\include\lwip\prot\ieee.h" />
+    <ClInclude Include="..\..\..\..\lwip\src\include\lwip\prot\igmp.h" />
+    <ClInclude Include="..\..\..\..\lwip\src\include\lwip\raw.h" />
+    <ClInclude Include="..\..\..\..\lwip\src\include\lwip\sio.h" />
+    <ClInclude Include="..\..\..\..\lwip\src\include\lwip\snmp.h" />
+    <ClInclude Include="..\..\..\..\lwip\src\include\lwip\sockets.h" />
+    <ClInclude Include="..\..\..\..\lwip\src\include\lwip\stats.h" />
+    <ClInclude Include="..\..\..\..\lwip\src\include\lwip\sys.h" />
+    <ClInclude Include="..\..\..\..\lwip\src\include\lwip\tcp.h" />
+    <ClInclude Include="..\..\..\..\lwip\src\include\lwip\tcpip.h" />
+    <ClInclude Include="..\..\..\..\lwip\src\include\lwip\udp.h" />
+    <ClInclude Include="..\..\..\..\lwip\src\include\netif\bridgeif.h" />
+    <ClInclude Include="..\..\..\..\lwip\src\include\netif\bridgeif_opts.h" />
+    <ClInclude Include="..\..\..\..\lwip\src\include\netif\etharp.h" />
+    <ClInclude Include="..\..\..\..\lwip\src\include\netif\ethernet.h" />
+    <ClInclude Include="..\..\..\..\lwip\src\include\netif\ieee802154.h" />
+    <ClInclude Include="..\..\..\..\lwip\src\include\netif\lowpan6.h" />
+    <ClInclude Include="..\..\..\..\lwip\src\include\netif\lowpan6_ble.h" />
+    <ClInclude Include="..\..\..\..\lwip\src\include\netif\lowpan6_common.h" />
+    <ClInclude Include="..\..\..\..\lwip\src\include\netif\lowpan6_opts.h" />
+    <ClInclude Include="..\..\..\..\lwip\src\include\netif\slipif.h" />
+    <ClInclude Include="..\..\..\..\lwip\src\include\netif\ppp\ccp.h" />
+    <ClInclude Include="..\..\..\..\lwip\src\include\netif\ppp\chap-md5.h" />
+    <ClInclude Include="..\..\..\..\lwip\src\include\netif\ppp\chap-new.h" />
+    <ClInclude Include="..\..\..\..\lwip\src\include\netif\ppp\chap_ms.h" />
+    <ClInclude Include="..\..\..\..\lwip\src\include\netif\ppp\eap.h" />
+    <ClInclude Include="..\..\..\..\lwip\src\include\netif\ppp\ecp.h" />
+    <ClInclude Include="..\..\..\..\lwip\src\include\netif\ppp\eui64.h" />
+    <ClInclude Include="..\..\..\..\lwip\src\include\netif\ppp\fsm.h" />
+    <ClInclude Include="..\..\..\..\lwip\src\include\netif\ppp\ipcp.h" />
+    <ClInclude Include="..\..\..\..\lwip\src\include\netif\ppp\ipv6cp.h" />
+    <ClInclude Include="..\..\..\..\lwip\src\include\netif\ppp\lcp.h" />
+    <ClInclude Include="..\..\..\..\lwip\src\include\netif\ppp\magic.h" />
+    <ClInclude Include="..\..\..\..\lwip\src\include\netif\ppp\mppe.h" />
+    <ClInclude Include="..\..\..\..\lwip\src\include\netif\ppp\ppp.h" />
+    <ClInclude Include="..\..\..\..\lwip\src\include\netif\ppp\ppp_impl.h" />
+    <ClInclude Include="..\..\..\..\lwip\src\include\netif\ppp\ppp_opts.h" />
+    <ClInclude Include="..\..\..\..\lwip\src\include\netif\ppp\pppcrypt.h" />
+    <ClInclude Include="..\..\..\..\lwip\src\include\netif\ppp\pppdebug.h" />
+    <ClInclude Include="..\..\..\..\lwip\src\include\netif\ppp\pppoe.h" />
+    <ClInclude Include="..\..\..\..\lwip\src\include\netif\ppp\pppol2tp.h" />
+    <ClInclude Include="..\..\..\..\lwip\src\include\netif\ppp\pppos.h" />
+    <ClInclude Include="..\..\..\..\lwip\src\include\netif\ppp\upap.h" />
+    <ClInclude Include="..\..\..\..\lwip\src\include\netif\ppp\vj.h" />
+    <ClInclude Include="..\..\..\..\lwip\src\include\netif\ppp\polarssl\arc4.h" />
+    <ClInclude Include="..\..\..\..\lwip\src\include\netif\ppp\polarssl\des.h" />
+    <ClInclude Include="..\..\..\..\lwip\src\include\netif\ppp\polarssl\md4.h" />
+    <ClInclude Include="..\..\..\..\lwip\src\include\netif\ppp\polarssl\md5.h" />
+    <ClInclude Include="..\..\..\..\lwip\src\include\netif\ppp\polarssl\sha1.h" />
+    <ClInclude Include="..\..\..\..\lwip\src\apps\http\fsdata.h" />
+    <ClInclude Include="..\..\..\..\lwip\src\apps\http\httpd_structs.h" />
+    <ClInclude Include="..\..\..\..\lwip\src\apps\snmp\snmp_asn1.h" />
+    <ClInclude Include="..\..\..\..\lwip\src\apps\snmp\snmp_core_priv.h" />
+    <ClInclude Include="..\..\..\..\lwip\src\apps\snmp\snmp_pbuf_stream.h" />
+    <ClInclude Include="..\..\..\..\lwip\src\include\lwip\apps\snmp_core.h" />
+    <ClInclude Include="..\..\..\..\lwip\src\include\lwip\apps\snmp_mib2.h" />
+    <ClInclude Include="..\..\..\..\lwip\src\include\lwip\apps\snmp_scalar.h" />
+    <ClInclude Include="..\..\..\..\lwip\src\include\lwip\apps\snmp_table.h" />
+    <ClInclude Include="..\..\..\..\lwip\src\include\lwip\apps\snmp_threadsync.h" />
+    <ClInclude Include="..\..\..\..\lwip\src\include\netif\ppp\pppapi.h" />
+    <ClInclude Include="..\..\..\..\lwip\src\include\lwip\apps\fs.h" />
+    <ClInclude Include="..\..\..\..\lwip\src\include\lwip\apps\httpd.h" />
+    <ClInclude Include="..\..\..\..\lwip\src\include\lwip\apps\httpd_opts.h" />
+    <ClInclude Include="..\..\..\..\lwip\src\include\lwip\apps\snmpv3.h" />
+    <ClInclude Include="..\..\..\..\lwip\src\include\lwip\etharp.h" />
+    <ClInclude Include="..\..\..\..\lwip\src\include\lwip\ip4_frag.h" />
+    <ClInclude Include="..\..\..\..\lwip\src\include\lwip\timeouts.h" />
+    <ClInclude Include="..\..\..\..\lwip\src\include\lwip\apps\mdns.h" />
+    <ClInclude Include="..\..\..\..\lwip\src\include\lwip\apps\mdns_opts.h" />
+    <ClInclude Include="..\..\..\..\lwip\src\include\lwip\prot\autoip.h" />
+    <ClInclude Include="..\..\..\..\lwip\src\include\lwip\prot\dhcp.h" />
+    <ClInclude Include="..\..\..\..\lwip\src\include\lwip\prot\dns.h" />
+    <ClInclude Include="..\..\..\..\lwip\src\include\lwip\prot\ip.h" />
+    <ClInclude Include="..\..\..\..\lwip\src\include\lwip\prot\ip4.h" />
+    <ClInclude Include="..\..\..\..\lwip\src\apps\snmp\snmpv3_priv.h" />
+    <ClInclude Include="..\..\..\..\lwip\src\include\lwip\prot\ethernet.h" />
+    <ClInclude Include="..\..\..\..\lwip\src\include\lwip\prot\icmp.h" />
+    <ClInclude Include="..\..\..\..\lwip\src\include\lwip\prot\icmp6.h" />
+    <ClInclude Include="..\..\..\..\lwip\src\include\lwip\prot\ip6.h" />
+    <ClInclude Include="..\..\..\..\lwip\src\include\lwip\prot\mld6.h" />
+    <ClInclude Include="..\..\..\..\lwip\src\include\lwip\prot\nd6.h" />
+    <ClInclude Include="..\..\..\..\lwip\src\include\lwip\prot\tcp.h" />
+    <ClInclude Include="..\..\..\..\lwip\src\include\lwip\prot\udp.h" />
+    <ClInclude Include="..\..\..\..\lwip\src\include\netif\zepif.h" />
+    <ClInclude Include="..\..\..\examples\example_app\default_netif.h" />
+    <ClInclude Include="..\..\..\examples\example_app\lwipcfg.h" />
+    <ClInclude Include="..\..\..\examples\example_app\lwipopts.h" />
+    <ClInclude Include="..\..\..\examples\example_app\lwippools.h" />
+    <ClInclude Include="..\..\..\examples\example_app\ppp_settings.h" />
+    <ClInclude Include="..\include\arch\bpstruct.h" />
+    <ClInclude Include="..\include\arch\cc.h" />
+    <ClInclude Include="..\include\arch\epstruct.h" />
+    <ClInclude Include="..\include\arch\perf.h" />
+    <ClInclude Include="..\include\arch\sys_arch.h" />
+  </ItemGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+  <ImportGroup Label="ExtensionTargets">
+  </ImportGroup>
+</Project>
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/ports/win32/msvc/lwIP.vcxproj.filters
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/ports/win32/msvc/lwIP.vcxproj.filters	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/ports/win32/msvc/lwIP.vcxproj.filters	(revision 457)
@@ -0,0 +1,1048 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup>
+    <Filter Include="doc">
+      <UniqueIdentifier>{51757ae3-05ca-4e6a-a745-19c9ffc62278}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="src">
+      <UniqueIdentifier>{e40d58ed-58be-4618-9664-6df29e27f835}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="src\api">
+      <UniqueIdentifier>{5752fd8f-90c3-4381-8b6a-86c09a2f9859}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="src\apps">
+      <UniqueIdentifier>{48a805a9-e5d2-4eed-b29c-02b57140a03d}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="src\apps\lwiperf">
+      <UniqueIdentifier>{8a8dba58-934c-4292-aa8d-d20e2b801bd4}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="src\apps\netbiosns">
+      <UniqueIdentifier>{20594706-d6e1-4503-bc38-f297892d752a}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="src\apps\snmp">
+      <UniqueIdentifier>{1075aec7-b001-47bd-9846-ed635687e26e}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="src\apps\sntp">
+      <UniqueIdentifier>{9b7b3b39-f3b0-4915-81d9-d66c3443c348}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="src\core">
+      <UniqueIdentifier>{75f75ac5-73a4-4458-bc23-eaed529c37e1}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="src\core\ipv4">
+      <UniqueIdentifier>{97772339-4210-4a32-82d0-d25269d3e3d6}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="src\core\ipv6">
+      <UniqueIdentifier>{06467ead-0683-44db-bc41-6aa5a82490f0}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="src\include">
+      <UniqueIdentifier>{166a3203-ccc3-4eff-9eaa-1e5648a7fb5b}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="src\include\lwip">
+      <UniqueIdentifier>{6b889738-b59a-450a-b4dd-0d1986bffca1}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="src\include\lwip\apps">
+      <UniqueIdentifier>{c64c0664-acd9-4f2f-8bd7-78250f4b7b4b}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="src\include\lwip\priv">
+      <UniqueIdentifier>{56e8d041-f1e0-4b02-a173-563190c0eb4a}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="src\include\netif">
+      <UniqueIdentifier>{dc783ea8-63ed-4de6-b576-a87c318a7ad1}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="src\include\netif\ppp">
+      <UniqueIdentifier>{7822191b-1cd0-4ce8-a852-da0474977fc4}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="src\include\netif\ppp\polarssl">
+      <UniqueIdentifier>{b22a3b7a-d076-44a5-9a16-1e6f49cd5a94}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="src\netif">
+      <UniqueIdentifier>{0109fdbb-3aed-45fa-a308-493988755364}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="src\netif\ppp">
+      <UniqueIdentifier>{32a9c4ed-7687-48bb-8b9d-482c2f6c7554}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="src\netif\ppp\polarssl">
+      <UniqueIdentifier>{c6c4a1a7-dab8-4463-b155-07e7303b54e4}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="arch">
+      <UniqueIdentifier>{2e87d0f7-38a3-45f8-870d-f8622c20e9d9}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="src\apps\http">
+      <UniqueIdentifier>{45f6a578-1f4b-4741-9b55-5b5084ecc1d9}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="src\apps\mdns">
+      <UniqueIdentifier>{92215272-cad9-4cf0-a2e1-705f6220e2a9}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="src\include\lwip\prot">
+      <UniqueIdentifier>{bdd3995a-aa34-4a4e-891e-a13c5373d618}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="doc\doxygen">
+      <UniqueIdentifier>{d0ce6e8b-4b30-498b-a1bb-aecee958df42}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="src\apps\tftp">
+      <UniqueIdentifier>{6db73869-23f6-48ab-8d92-c8e478e55892}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="src\apps\mqtt">
+      <UniqueIdentifier>{65542a97-c588-47b3-b1f6-ae51645c736e}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="src\apps\altcp_tls">
+      <UniqueIdentifier>{ffd283f4-44f0-4be2-83a3-8bd55f29e80f}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="src\apps\smtp">
+      <UniqueIdentifier>{d9456888-d299-48ff-8165-ff499e5a0ba3}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="src\include\compat">
+      <UniqueIdentifier>{5aa786e4-df26-432c-b32c-9c4fac00b951}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="src\include\compat\posix">
+      <UniqueIdentifier>{8fb42d78-1e77-4208-b457-44f41c4cc901}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="src\include\compat\posix\sys">
+      <UniqueIdentifier>{81578f11-9d3c-4bc8-a518-6f78f082fe0e}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="src\include\compat\posix\net">
+      <UniqueIdentifier>{f8d65087-0cee-46de-8d8c-dca719bf2a4b}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="src\include\compat\posix\arpa">
+      <UniqueIdentifier>{91d8473a-deb5-4943-8b63-b43d86c7fa1c}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="src\include\compat\stdc">
+      <UniqueIdentifier>{15855a74-48c6-473c-b4cb-40ec065698d4}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="example_app">
+      <UniqueIdentifier>{2c795490-531d-4a03-b30d-73760b09975a}</UniqueIdentifier>
+    </Filter>
+  </ItemGroup>
+  <ItemGroup>
+    <None Include="..\..\..\..\lwip\CHANGELOG" />
+    <None Include="..\..\..\..\lwip\COPYING" />
+    <None Include="..\..\..\..\lwip\FILES" />
+    <None Include="..\..\..\..\lwip\README" />
+    <None Include="..\..\..\..\lwip\UPGRADING" />
+    <None Include="..\..\..\..\lwip\doc\contrib.txt">
+      <Filter>doc</Filter>
+    </None>
+    <None Include="..\..\..\..\lwip\doc\FILES">
+      <Filter>doc</Filter>
+    </None>
+    <None Include="..\..\..\..\lwip\doc\mdns.txt">
+      <Filter>doc</Filter>
+    </None>
+    <None Include="..\..\..\..\lwip\doc\ppp.txt">
+      <Filter>doc</Filter>
+    </None>
+    <None Include="..\..\..\..\lwip\doc\savannah.txt">
+      <Filter>doc</Filter>
+    </None>
+    <None Include="..\..\..\..\lwip\doc\doxygen\generate.bat">
+      <Filter>doc\doxygen</Filter>
+    </None>
+    <None Include="..\..\..\..\lwip\doc\doxygen\generate.sh">
+      <Filter>doc\doxygen</Filter>
+    </None>
+    <None Include="..\..\..\..\lwip\doc\doxygen\lwip.Doxyfile">
+      <Filter>doc\doxygen</Filter>
+    </None>
+    <None Include="..\..\..\examples\example_app\lwipcfg.h.example">
+      <Filter>example_app</Filter>
+    </None>
+  </ItemGroup>
+  <ItemGroup>
+    <ClCompile Include="..\..\..\..\lwip\src\api\api_lib.c">
+      <Filter>src\api</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\lwip\src\api\api_msg.c">
+      <Filter>src\api</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\lwip\src\api\err.c">
+      <Filter>src\api</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\lwip\src\api\netbuf.c">
+      <Filter>src\api</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\lwip\src\api\netdb.c">
+      <Filter>src\api</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\lwip\src\api\netifapi.c">
+      <Filter>src\api</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\lwip\src\api\sockets.c">
+      <Filter>src\api</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\lwip\src\api\tcpip.c">
+      <Filter>src\api</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\lwip\src\apps\lwiperf\lwiperf.c">
+      <Filter>src\apps\lwiperf</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\lwip\src\apps\netbiosns\netbiosns.c">
+      <Filter>src\apps\netbiosns</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\lwip\src\apps\sntp\sntp.c">
+      <Filter>src\apps\sntp</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\lwip\src\core\def.c">
+      <Filter>src\core</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\lwip\src\core\dns.c">
+      <Filter>src\core</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\lwip\src\core\inet_chksum.c">
+      <Filter>src\core</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\lwip\src\core\init.c">
+      <Filter>src\core</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\lwip\src\core\mem.c">
+      <Filter>src\core</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\lwip\src\core\memp.c">
+      <Filter>src\core</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\lwip\src\core\netif.c">
+      <Filter>src\core</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\lwip\src\core\pbuf.c">
+      <Filter>src\core</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\lwip\src\core\raw.c">
+      <Filter>src\core</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\lwip\src\core\stats.c">
+      <Filter>src\core</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\lwip\src\core\sys.c">
+      <Filter>src\core</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\lwip\src\core\tcp.c">
+      <Filter>src\core</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\lwip\src\core\tcp_in.c">
+      <Filter>src\core</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\lwip\src\core\tcp_out.c">
+      <Filter>src\core</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\lwip\src\core\udp.c">
+      <Filter>src\core</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\lwip\src\core\ipv4\autoip.c">
+      <Filter>src\core\ipv4</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\lwip\src\core\ipv4\dhcp.c">
+      <Filter>src\core\ipv4</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\lwip\src\core\ipv4\icmp.c">
+      <Filter>src\core\ipv4</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\lwip\src\core\ipv4\igmp.c">
+      <Filter>src\core\ipv4</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\lwip\src\core\ipv4\ip4.c">
+      <Filter>src\core\ipv4</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\lwip\src\core\ipv4\ip4_addr.c">
+      <Filter>src\core\ipv4</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\lwip\src\core\ipv6\dhcp6.c">
+      <Filter>src\core\ipv6</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\lwip\src\core\ipv6\ethip6.c">
+      <Filter>src\core\ipv6</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\lwip\src\core\ipv6\icmp6.c">
+      <Filter>src\core\ipv6</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\lwip\src\core\ipv6\inet6.c">
+      <Filter>src\core\ipv6</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\lwip\src\core\ipv6\ip6.c">
+      <Filter>src\core\ipv6</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\lwip\src\core\ipv6\ip6_addr.c">
+      <Filter>src\core\ipv6</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\lwip\src\core\ipv6\ip6_frag.c">
+      <Filter>src\core\ipv6</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\lwip\src\core\ipv6\mld6.c">
+      <Filter>src\core\ipv6</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\lwip\src\core\ipv6\nd6.c">
+      <Filter>src\core\ipv6</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\lwip\src\netif\ethernet.c">
+      <Filter>src\netif</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\lwip\src\netif\lowpan6.c">
+      <Filter>src\netif</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\lwip\src\netif\slipif.c">
+      <Filter>src\netif</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\lwip\src\netif\ppp\auth.c">
+      <Filter>src\netif\ppp</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\lwip\src\netif\ppp\ccp.c">
+      <Filter>src\netif\ppp</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\lwip\src\netif\ppp\chap-md5.c">
+      <Filter>src\netif\ppp</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\lwip\src\netif\ppp\chap-new.c">
+      <Filter>src\netif\ppp</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\lwip\src\netif\ppp\chap_ms.c">
+      <Filter>src\netif\ppp</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\lwip\src\netif\ppp\demand.c">
+      <Filter>src\netif\ppp</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\lwip\src\netif\ppp\eap.c">
+      <Filter>src\netif\ppp</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\lwip\src\netif\ppp\ecp.c">
+      <Filter>src\netif\ppp</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\lwip\src\netif\ppp\eui64.c">
+      <Filter>src\netif\ppp</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\lwip\src\netif\ppp\fsm.c">
+      <Filter>src\netif\ppp</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\lwip\src\netif\ppp\ipcp.c">
+      <Filter>src\netif\ppp</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\lwip\src\netif\ppp\ipv6cp.c">
+      <Filter>src\netif\ppp</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\lwip\src\netif\ppp\lcp.c">
+      <Filter>src\netif\ppp</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\lwip\src\netif\ppp\magic.c">
+      <Filter>src\netif\ppp</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\lwip\src\netif\ppp\mppe.c">
+      <Filter>src\netif\ppp</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\lwip\src\netif\ppp\multilink.c">
+      <Filter>src\netif\ppp</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\lwip\src\netif\ppp\ppp.c">
+      <Filter>src\netif\ppp</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\lwip\src\netif\ppp\pppcrypt.c">
+      <Filter>src\netif\ppp</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\lwip\src\netif\ppp\pppoe.c">
+      <Filter>src\netif\ppp</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\lwip\src\netif\ppp\pppol2tp.c">
+      <Filter>src\netif\ppp</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\lwip\src\netif\ppp\pppos.c">
+      <Filter>src\netif\ppp</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\lwip\src\netif\ppp\upap.c">
+      <Filter>src\netif\ppp</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\lwip\src\netif\ppp\utils.c">
+      <Filter>src\netif\ppp</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\lwip\src\netif\ppp\vj.c">
+      <Filter>src\netif\ppp</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\lwip\src\netif\ppp\polarssl\arc4.c">
+      <Filter>src\netif\ppp\polarssl</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\lwip\src\netif\ppp\polarssl\des.c">
+      <Filter>src\netif\ppp\polarssl</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\lwip\src\netif\ppp\polarssl\md4.c">
+      <Filter>src\netif\ppp\polarssl</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\lwip\src\netif\ppp\polarssl\md5.c">
+      <Filter>src\netif\ppp\polarssl</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\lwip\src\netif\ppp\polarssl\sha1.c">
+      <Filter>src\netif\ppp\polarssl</Filter>
+    </ClCompile>
+    <ClCompile Include="..\sio.c">
+      <Filter>arch</Filter>
+    </ClCompile>
+    <ClCompile Include="..\sys_arch.c">
+      <Filter>arch</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\lwip\src\apps\http\httpd.c">
+      <Filter>src\apps\http</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\lwip\src\apps\http\fsdata.c">
+      <Filter>src\apps\http</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\lwip\src\apps\http\fs.c">
+      <Filter>src\apps\http</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\lwip\src\apps\snmp\snmp_asn1.c">
+      <Filter>src\apps\snmp</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\lwip\src\apps\snmp\snmp_core.c">
+      <Filter>src\apps\snmp</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\lwip\src\apps\snmp\snmp_mib2.c">
+      <Filter>src\apps\snmp</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\lwip\src\apps\snmp\snmp_msg.c">
+      <Filter>src\apps\snmp</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\lwip\src\apps\snmp\snmp_netconn.c">
+      <Filter>src\apps\snmp</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\lwip\src\apps\snmp\snmp_pbuf_stream.c">
+      <Filter>src\apps\snmp</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\lwip\src\apps\snmp\snmp_raw.c">
+      <Filter>src\apps\snmp</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\lwip\src\apps\snmp\snmp_scalar.c">
+      <Filter>src\apps\snmp</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\lwip\src\apps\snmp\snmp_table.c">
+      <Filter>src\apps\snmp</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\lwip\src\apps\snmp\snmp_threadsync.c">
+      <Filter>src\apps\snmp</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\lwip\src\apps\snmp\snmp_traps.c">
+      <Filter>src\apps\snmp</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\lwip\src\core\ip.c">
+      <Filter>src\core</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\lwip\src\apps\snmp\snmp_mib2_icmp.c">
+      <Filter>src\apps\snmp</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\lwip\src\apps\snmp\snmp_mib2_interfaces.c">
+      <Filter>src\apps\snmp</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\lwip\src\apps\snmp\snmp_mib2_ip.c">
+      <Filter>src\apps\snmp</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\lwip\src\apps\snmp\snmp_mib2_snmp.c">
+      <Filter>src\apps\snmp</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\lwip\src\apps\snmp\snmp_mib2_system.c">
+      <Filter>src\apps\snmp</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\lwip\src\apps\snmp\snmp_mib2_tcp.c">
+      <Filter>src\apps\snmp</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\lwip\src\apps\snmp\snmp_mib2_udp.c">
+      <Filter>src\apps\snmp</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\lwip\src\apps\snmp\snmpv3.c">
+      <Filter>src\apps\snmp</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\lwip\src\netif\ppp\pppapi.c">
+      <Filter>src\netif\ppp</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\lwip\src\core\ipv4\etharp.c">
+      <Filter>src\core\ipv4</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\lwip\src\core\ipv4\ip4_frag.c">
+      <Filter>src\core\ipv4</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\lwip\src\core\timeouts.c">
+      <Filter>src\core</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\lwip\src\apps\mdns\mdns.c">
+      <Filter>src\apps\mdns</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\lwip\src\apps\snmp\snmpv3_mbedtls.c">
+      <Filter>src\apps\snmp</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\lwip\doc\NO_SYS_SampleCode.c">
+      <Filter>doc</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\lwip\src\apps\tftp\tftp_server.c">
+      <Filter>src\apps\tftp</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\lwip\src\apps\mqtt\mqtt.c">
+      <Filter>src\apps\mqtt</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\lwip\src\api\if_api.c">
+      <Filter>src\api</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\lwip\src\netif\bridgeif.c">
+      <Filter>src\netif</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\lwip\src\apps\snmp\snmp_snmpv2_framework.c">
+      <Filter>src\apps\snmp</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\lwip\src\apps\snmp\snmp_snmpv2_usm.c">
+      <Filter>src\apps\snmp</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\lwip\src\core\altcp.c">
+      <Filter>src\core</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\lwip\src\core\altcp_tcp.c">
+      <Filter>src\core</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\lwip\src\apps\altcp_tls\altcp_tls_mbedtls.c">
+      <Filter>src\apps\altcp_tls</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\lwip\src\apps\altcp_tls\altcp_tls_mbedtls_mem.c">
+      <Filter>src\apps\altcp_tls</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\lwip\src\apps\smtp\smtp.c">
+      <Filter>src\apps\smtp</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\lwip\src\netif\bridgeif_fdb.c">
+      <Filter>src\netif</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\lwip\src\apps\http\http_client.c">
+      <Filter>src\apps\http</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\lwip\src\core\altcp_alloc.c">
+      <Filter>src\core</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\lwip\src\apps\http\altcp_proxyconnect.c">
+      <Filter>src\apps\http</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\lwip\src\netif\lowpan6_ble.c">
+      <Filter>src\netif</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\lwip\src\netif\zepif.c">
+      <Filter>src\netif</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\lwip\src\netif\lowpan6_common.c">
+      <Filter>src\netif</Filter>
+    </ClCompile>
+  </ItemGroup>
+  <ItemGroup>
+    <ClInclude Include="..\..\..\..\lwip\src\include\lwip\apps\lwiperf.h">
+      <Filter>src\include\lwip\apps</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\..\lwip\src\include\lwip\apps\netbiosns.h">
+      <Filter>src\include\lwip\apps</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\..\lwip\src\include\lwip\apps\netbiosns_opts.h">
+      <Filter>src\include\lwip\apps</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\..\lwip\src\include\lwip\apps\snmp.h">
+      <Filter>src\include\lwip\apps</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\..\lwip\src\include\lwip\apps\snmp_opts.h">
+      <Filter>src\include\lwip\apps</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\..\lwip\src\include\lwip\apps\sntp.h">
+      <Filter>src\include\lwip\apps</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\..\lwip\src\include\lwip\apps\sntp_opts.h">
+      <Filter>src\include\lwip\apps</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\..\lwip\src\include\lwip\api.h">
+      <Filter>src\include\lwip</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\..\lwip\src\include\lwip\arch.h">
+      <Filter>src\include\lwip</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\..\lwip\src\include\lwip\autoip.h">
+      <Filter>src\include\lwip</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\..\lwip\src\include\lwip\debug.h">
+      <Filter>src\include\lwip</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\..\lwip\src\include\lwip\def.h">
+      <Filter>src\include\lwip</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\..\lwip\src\include\lwip\dhcp.h">
+      <Filter>src\include\lwip</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\..\lwip\src\include\lwip\dhcp6.h">
+      <Filter>src\include\lwip</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\..\lwip\src\include\lwip\dns.h">
+      <Filter>src\include\lwip</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\..\lwip\src\include\lwip\err.h">
+      <Filter>src\include\lwip</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\..\lwip\src\include\lwip\ethip6.h">
+      <Filter>src\include\lwip</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\..\lwip\src\include\lwip\icmp.h">
+      <Filter>src\include\lwip</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\..\lwip\src\include\lwip\icmp6.h">
+      <Filter>src\include\lwip</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\..\lwip\src\include\lwip\igmp.h">
+      <Filter>src\include\lwip</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\..\lwip\src\include\lwip\inet.h">
+      <Filter>src\include\lwip</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\..\lwip\src\include\lwip\inet_chksum.h">
+      <Filter>src\include\lwip</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\..\lwip\src\include\lwip\init.h">
+      <Filter>src\include\lwip</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\..\lwip\src\include\lwip\ip.h">
+      <Filter>src\include\lwip</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\..\lwip\src\include\lwip\ip4.h">
+      <Filter>src\include\lwip</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\..\lwip\src\include\lwip\ip4_addr.h">
+      <Filter>src\include\lwip</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\..\lwip\src\include\lwip\ip6.h">
+      <Filter>src\include\lwip</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\..\lwip\src\include\lwip\ip6_addr.h">
+      <Filter>src\include\lwip</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\..\lwip\src\include\lwip\ip6_frag.h">
+      <Filter>src\include\lwip</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\..\lwip\src\include\lwip\ip_addr.h">
+      <Filter>src\include\lwip</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\..\lwip\src\include\lwip\mem.h">
+      <Filter>src\include\lwip</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\..\lwip\src\include\lwip\memp.h">
+      <Filter>src\include\lwip</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\..\lwip\src\include\lwip\mld6.h">
+      <Filter>src\include\lwip</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\..\lwip\src\include\lwip\nd6.h">
+      <Filter>src\include\lwip</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\..\lwip\src\include\lwip\netbuf.h">
+      <Filter>src\include\lwip</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\..\lwip\src\include\lwip\netdb.h">
+      <Filter>src\include\lwip</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\..\lwip\src\include\lwip\netif.h">
+      <Filter>src\include\lwip</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\..\lwip\src\include\lwip\netifapi.h">
+      <Filter>src\include\lwip</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\..\lwip\src\include\lwip\opt.h">
+      <Filter>src\include\lwip</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\..\lwip\src\include\lwip\pbuf.h">
+      <Filter>src\include\lwip</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\..\lwip\src\include\lwip\raw.h">
+      <Filter>src\include\lwip</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\..\lwip\src\include\lwip\sio.h">
+      <Filter>src\include\lwip</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\..\lwip\src\include\lwip\snmp.h">
+      <Filter>src\include\lwip</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\..\lwip\src\include\lwip\sockets.h">
+      <Filter>src\include\lwip</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\..\lwip\src\include\lwip\stats.h">
+      <Filter>src\include\lwip</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\..\lwip\src\include\lwip\sys.h">
+      <Filter>src\include\lwip</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\..\lwip\src\include\lwip\tcp.h">
+      <Filter>src\include\lwip</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\..\lwip\src\include\lwip\tcpip.h">
+      <Filter>src\include\lwip</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\..\lwip\src\include\lwip\udp.h">
+      <Filter>src\include\lwip</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\..\lwip\src\include\netif\etharp.h">
+      <Filter>src\include\netif</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\..\lwip\src\include\netif\ethernet.h">
+      <Filter>src\include\netif</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\..\lwip\src\include\netif\lowpan6.h">
+      <Filter>src\include\netif</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\..\lwip\src\include\netif\lowpan6_opts.h">
+      <Filter>src\include\netif</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\..\lwip\src\include\netif\slipif.h">
+      <Filter>src\include\netif</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\..\lwip\src\include\netif\ppp\ccp.h">
+      <Filter>src\include\netif\ppp</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\..\lwip\src\include\netif\ppp\chap-md5.h">
+      <Filter>src\include\netif\ppp</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\..\lwip\src\include\netif\ppp\chap-new.h">
+      <Filter>src\include\netif\ppp</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\..\lwip\src\include\netif\ppp\chap_ms.h">
+      <Filter>src\include\netif\ppp</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\..\lwip\src\include\netif\ppp\eap.h">
+      <Filter>src\include\netif\ppp</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\..\lwip\src\include\netif\ppp\ecp.h">
+      <Filter>src\include\netif\ppp</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\..\lwip\src\include\netif\ppp\eui64.h">
+      <Filter>src\include\netif\ppp</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\..\lwip\src\include\netif\ppp\fsm.h">
+      <Filter>src\include\netif\ppp</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\..\lwip\src\include\netif\ppp\ipcp.h">
+      <Filter>src\include\netif\ppp</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\..\lwip\src\include\netif\ppp\ipv6cp.h">
+      <Filter>src\include\netif\ppp</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\..\lwip\src\include\netif\ppp\lcp.h">
+      <Filter>src\include\netif\ppp</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\..\lwip\src\include\netif\ppp\magic.h">
+      <Filter>src\include\netif\ppp</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\..\lwip\src\include\netif\ppp\mppe.h">
+      <Filter>src\include\netif\ppp</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\..\lwip\src\include\netif\ppp\ppp.h">
+      <Filter>src\include\netif\ppp</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\..\lwip\src\include\netif\ppp\ppp_impl.h">
+      <Filter>src\include\netif\ppp</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\..\lwip\src\include\netif\ppp\ppp_opts.h">
+      <Filter>src\include\netif\ppp</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\..\lwip\src\include\netif\ppp\pppcrypt.h">
+      <Filter>src\include\netif\ppp</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\..\lwip\src\include\netif\ppp\pppdebug.h">
+      <Filter>src\include\netif\ppp</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\..\lwip\src\include\netif\ppp\pppoe.h">
+      <Filter>src\include\netif\ppp</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\..\lwip\src\include\netif\ppp\pppol2tp.h">
+      <Filter>src\include\netif\ppp</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\..\lwip\src\include\netif\ppp\pppos.h">
+      <Filter>src\include\netif\ppp</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\..\lwip\src\include\netif\ppp\upap.h">
+      <Filter>src\include\netif\ppp</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\..\lwip\src\include\netif\ppp\vj.h">
+      <Filter>src\include\netif\ppp</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\..\lwip\src\include\netif\ppp\polarssl\arc4.h">
+      <Filter>src\include\netif\ppp\polarssl</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\..\lwip\src\include\netif\ppp\polarssl\des.h">
+      <Filter>src\include\netif\ppp\polarssl</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\..\lwip\src\include\netif\ppp\polarssl\md4.h">
+      <Filter>src\include\netif\ppp\polarssl</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\..\lwip\src\include\netif\ppp\polarssl\md5.h">
+      <Filter>src\include\netif\ppp\polarssl</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\..\lwip\src\include\netif\ppp\polarssl\sha1.h">
+      <Filter>src\include\netif\ppp\polarssl</Filter>
+    </ClInclude>
+    <ClInclude Include="..\include\arch\bpstruct.h">
+      <Filter>arch</Filter>
+    </ClInclude>
+    <ClInclude Include="..\include\arch\cc.h">
+      <Filter>arch</Filter>
+    </ClInclude>
+    <ClInclude Include="..\include\arch\epstruct.h">
+      <Filter>arch</Filter>
+    </ClInclude>
+    <ClInclude Include="..\include\arch\perf.h">
+      <Filter>arch</Filter>
+    </ClInclude>
+    <ClInclude Include="..\include\arch\sys_arch.h">
+      <Filter>arch</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\..\lwip\src\include\lwip\priv\tcp_priv.h">
+      <Filter>src\include\lwip\priv</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\..\lwip\src\include\lwip\priv\tcpip_priv.h">
+      <Filter>src\include\lwip\priv</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\..\lwip\src\include\lwip\priv\memp_priv.h">
+      <Filter>src\include\lwip\priv</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\..\lwip\src\include\lwip\priv\memp_std.h">
+      <Filter>src\include\lwip\priv</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\..\lwip\src\include\lwip\priv\api_msg.h">
+      <Filter>src\include\lwip\priv</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\..\lwip\src\apps\http\httpd_structs.h">
+      <Filter>src\apps\http</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\..\lwip\src\apps\http\fsdata.h">
+      <Filter>src\apps\http</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\..\lwip\src\apps\snmp\snmp_asn1.h">
+      <Filter>src\apps\snmp</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\..\lwip\src\apps\snmp\snmp_core_priv.h">
+      <Filter>src\apps\snmp</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\..\lwip\src\apps\snmp\snmp_pbuf_stream.h">
+      <Filter>src\apps\snmp</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\..\lwip\src\include\lwip\apps\snmp_core.h">
+      <Filter>src\include\lwip\apps</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\..\lwip\src\include\lwip\apps\snmp_mib2.h">
+      <Filter>src\include\lwip\apps</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\..\lwip\src\include\lwip\apps\snmp_scalar.h">
+      <Filter>src\include\lwip\apps</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\..\lwip\src\include\lwip\apps\snmp_table.h">
+      <Filter>src\include\lwip\apps</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\..\lwip\src\include\lwip\apps\snmp_threadsync.h">
+      <Filter>src\include\lwip\apps</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\..\lwip\src\apps\snmp\snmp_msg.h">
+      <Filter>src\apps\snmp</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\..\lwip\src\include\netif\ppp\pppapi.h">
+      <Filter>src\include\netif\ppp</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\..\lwip\src\include\lwip\apps\fs.h">
+      <Filter>src\include\lwip\apps</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\..\lwip\src\include\lwip\apps\httpd.h">
+      <Filter>src\include\lwip\apps</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\..\lwip\src\include\lwip\apps\httpd_opts.h">
+      <Filter>src\include\lwip\apps</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\..\lwip\src\include\lwip\apps\snmpv3.h">
+      <Filter>src\include\lwip\apps</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\..\lwip\src\include\lwip\etharp.h">
+      <Filter>src\include\lwip</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\..\lwip\src\include\lwip\ip4_frag.h">
+      <Filter>src\include\lwip</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\..\lwip\src\include\lwip\timeouts.h">
+      <Filter>src\include\lwip</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\..\lwip\src\include\lwip\apps\mdns.h">
+      <Filter>src\include\lwip\apps</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\..\lwip\src\include\lwip\apps\mdns_opts.h">
+      <Filter>src\include\lwip\apps</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\..\lwip\src\include\lwip\prot\autoip.h">
+      <Filter>src\include\lwip\prot</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\..\lwip\src\include\lwip\prot\dhcp.h">
+      <Filter>src\include\lwip\prot</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\..\lwip\src\include\lwip\prot\dns.h">
+      <Filter>src\include\lwip\prot</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\..\lwip\src\include\lwip\prot\ip.h">
+      <Filter>src\include\lwip\prot</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\..\lwip\src\include\lwip\prot\ip4.h">
+      <Filter>src\include\lwip\prot</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\..\lwip\src\apps\snmp\snmpv3_priv.h">
+      <Filter>src\apps\snmp</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\..\lwip\src\include\lwip\prot\ethernet.h">
+      <Filter>src\include\lwip\prot</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\..\lwip\src\include\lwip\prot\icmp.h">
+      <Filter>src\include\lwip\prot</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\..\lwip\src\include\lwip\prot\icmp6.h">
+      <Filter>src\include\lwip\prot</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\..\lwip\src\include\lwip\prot\ip6.h">
+      <Filter>src\include\lwip\prot</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\..\lwip\src\include\lwip\prot\mld6.h">
+      <Filter>src\include\lwip\prot</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\..\lwip\src\include\lwip\prot\nd6.h">
+      <Filter>src\include\lwip\prot</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\..\lwip\src\include\lwip\prot\tcp.h">
+      <Filter>src\include\lwip\prot</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\..\lwip\src\include\lwip\prot\udp.h">
+      <Filter>src\include\lwip\prot</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\..\lwip\src\include\lwip\apps\mdns_priv.h">
+      <Filter>src\include\lwip\apps</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\..\lwip\src\include\lwip\prot\igmp.h">
+      <Filter>src\include\lwip\prot</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\..\lwip\src\include\lwip\prot\etharp.h">
+      <Filter>src\include\lwip\prot</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\..\lwip\doc\doxygen\main_page.h">
+      <Filter>doc\doxygen</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\..\lwip\src\include\lwip\apps\tftp_opts.h">
+      <Filter>src\include\lwip\apps</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\..\lwip\src\include\lwip\apps\tftp_server.h">
+      <Filter>src\include\lwip\apps</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\..\lwip\src\include\lwip\errno.h">
+      <Filter>src\include\lwip</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\..\lwip\src\include\lwip\priv\nd6_priv.h">
+      <Filter>src\include\lwip\priv</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\..\lwip\src\include\lwip\apps\mqtt.h">
+      <Filter>src\include\lwip\apps</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\..\lwip\src\include\lwip\if_api.h">
+      <Filter>src\include\lwip</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\..\lwip\src\include\lwip\ip6_zone.h">
+      <Filter>src\include\lwip</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\..\lwip\src\include\lwip\priv\sockets_priv.h">
+      <Filter>src\include\lwip\priv</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\..\lwip\src\include\netif\bridgeif.h">
+      <Filter>src\include\netif</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\..\lwip\src\include\netif\bridgeif_opts.h">
+      <Filter>src\include\netif</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\..\lwip\src\include\lwip\altcp.h">
+      <Filter>src\include\lwip</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\..\lwip\src\include\lwip\altcp_tcp.h">
+      <Filter>src\include\lwip</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\..\lwip\src\apps\altcp_tls\altcp_tls_mbedtls_mem.h">
+      <Filter>src\apps\altcp_tls</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\..\lwip\src\apps\altcp_tls\altcp_tls_mbedtls_structs.h">
+      <Filter>src\apps\altcp_tls</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\..\lwip\src\include\lwip\altcp_tls.h">
+      <Filter>src\include\lwip</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\..\lwip\src\include\lwip\apps\altcp_tls_mbedtls_opts.h">
+      <Filter>src\include\lwip\apps</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\..\lwip\src\include\lwip\apps\snmp_snmpv2_framework.h">
+      <Filter>src\include\lwip\apps</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\..\lwip\src\include\lwip\apps\snmp_snmpv2_usm.h">
+      <Filter>src\include\lwip\apps</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\..\lwip\src\include\lwip\apps\smtp.h">
+      <Filter>src\include\lwip\apps</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\..\lwip\src\include\lwip\apps\smtp_opts.h">
+      <Filter>src\include\lwip\apps</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\..\lwip\src\include\lwip\priv\altcp_priv.h">
+      <Filter>src\include\lwip\priv</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\..\lwip\src\include\lwip\apps\mqtt_priv.h">
+      <Filter>src\include\lwip\apps</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\..\lwip\src\include\lwip\apps\mqtt_opts.h">
+      <Filter>src\include\lwip\apps</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\..\lwip\src\include\compat\posix\sys\socket.h">
+      <Filter>src\include\compat\posix\sys</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\..\lwip\src\include\compat\posix\netdb.h">
+      <Filter>src\include\compat\posix</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\..\lwip\src\include\compat\posix\net\if.h">
+      <Filter>src\include\compat\posix\net</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\..\lwip\src\include\compat\posix\arpa\inet.h">
+      <Filter>src\include\compat\posix\arpa</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\..\lwip\src\include\compat\stdc\errno.h">
+      <Filter>src\include\compat\stdc</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\..\lwip\src\include\lwip\prot\iana.h">
+      <Filter>src\include\lwip\prot</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\..\lwip\src\include\lwip\prot\ieee.h">
+      <Filter>src\include\lwip\prot</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\..\lwip\src\include\lwip\priv\raw_priv.h">
+      <Filter>src\include\lwip\priv</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\..\lwip\src\include\lwip\priv\mem_priv.h">
+      <Filter>src\include\lwip\priv</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\..\lwip\src\include\lwip\apps\http_client.h">
+      <Filter>src\include\lwip\apps</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\..\lwip\src\include\lwip\apps\altcp_proxyconnect.h">
+      <Filter>src\include\lwip\apps</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\..\lwip\src\include\lwip\prot\dhcp6.h">
+      <Filter>src\include\lwip\prot</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\..\lwip\src\include\netif\lowpan6_ble.h">
+      <Filter>src\include\netif</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\..\lwip\src\include\netif\ieee802154.h">
+      <Filter>src\include\netif</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\..\lwip\src\include\netif\zepif.h">
+      <Filter>src\include\netif</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\..\lwip\src\include\netif\lowpan6_common.h">
+      <Filter>src\include\netif</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\examples\example_app\default_netif.h">
+      <Filter>example_app</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\examples\example_app\lwipcfg.h">
+      <Filter>example_app</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\examples\example_app\lwipopts.h">
+      <Filter>example_app</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\examples\example_app\lwippools.h">
+      <Filter>example_app</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\examples\example_app\ppp_settings.h">
+      <Filter>example_app</Filter>
+    </ClInclude>
+  </ItemGroup>
+</Project>
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/ports/win32/msvc/lwIP_Test.sln
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/ports/win32/msvc/lwIP_Test.sln	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/ports/win32/msvc/lwIP_Test.sln	(revision 457)
@@ -0,0 +1,37 @@
+Microsoft Visual Studio Solution File, Format Version 11.00
+# Visual C++ Express 2010
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "lwIP_Test", "lwIP_Test.vcxproj", "{8CC0CE51-32CF-4585-BFAF-A9343BC5A96D}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "lwIP pcapif", "lwIP_pcapif.vcxproj", "{6F44E49E-9F21-4144-91EC-53B92AEF62CE}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "lwIP", "lwIP.vcxproj", "{2CC276FA-B226-49C9-8F82-7FCD5A228E28}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "makefsdata", "makefsdata.vcxproj", "{0BFC0F21-8E84-4E68-A9E1-CE2A09B72F6D}"
+EndProject
+Global
+	GlobalSection(SolutionConfigurationPlatforms) = preSolution
+		Debug|Win32 = Debug|Win32
+		Release|Win32 = Release|Win32
+	EndGlobalSection
+	GlobalSection(ProjectConfigurationPlatforms) = postSolution
+		{8CC0CE51-32CF-4585-BFAF-A9343BC5A96D}.Debug|Win32.ActiveCfg = Debug|Win32
+		{8CC0CE51-32CF-4585-BFAF-A9343BC5A96D}.Debug|Win32.Build.0 = Debug|Win32
+		{8CC0CE51-32CF-4585-BFAF-A9343BC5A96D}.Release|Win32.ActiveCfg = Release|Win32
+		{8CC0CE51-32CF-4585-BFAF-A9343BC5A96D}.Release|Win32.Build.0 = Release|Win32
+		{6F44E49E-9F21-4144-91EC-53B92AEF62CE}.Debug|Win32.ActiveCfg = Debug|Win32
+		{6F44E49E-9F21-4144-91EC-53B92AEF62CE}.Debug|Win32.Build.0 = Debug|Win32
+		{6F44E49E-9F21-4144-91EC-53B92AEF62CE}.Release|Win32.ActiveCfg = Release|Win32
+		{6F44E49E-9F21-4144-91EC-53B92AEF62CE}.Release|Win32.Build.0 = Release|Win32
+		{2CC276FA-B226-49C9-8F82-7FCD5A228E28}.Debug|Win32.ActiveCfg = Debug|Win32
+		{2CC276FA-B226-49C9-8F82-7FCD5A228E28}.Debug|Win32.Build.0 = Debug|Win32
+		{2CC276FA-B226-49C9-8F82-7FCD5A228E28}.Release|Win32.ActiveCfg = Release|Win32
+		{2CC276FA-B226-49C9-8F82-7FCD5A228E28}.Release|Win32.Build.0 = Release|Win32
+		{0BFC0F21-8E84-4E68-A9E1-CE2A09B72F6D}.Debug|Win32.ActiveCfg = Debug|Win32
+		{0BFC0F21-8E84-4E68-A9E1-CE2A09B72F6D}.Debug|Win32.Build.0 = Debug|Win32
+		{0BFC0F21-8E84-4E68-A9E1-CE2A09B72F6D}.Release|Win32.ActiveCfg = Release|Win32
+		{0BFC0F21-8E84-4E68-A9E1-CE2A09B72F6D}.Release|Win32.Build.0 = Release|Win32
+	EndGlobalSection
+	GlobalSection(SolutionProperties) = preSolution
+		HideSolutionNode = FALSE
+	EndGlobalSection
+EndGlobal
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/ports/win32/msvc/lwIP_Test.vcxproj
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/ports/win32/msvc/lwIP_Test.vcxproj	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/ports/win32/msvc/lwIP_Test.vcxproj	(revision 457)
@@ -0,0 +1,203 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup Label="ProjectConfigurations">
+    <ProjectConfiguration Include="Debug|Win32">
+      <Configuration>Debug</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|Win32">
+      <Configuration>Release</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+  </ItemGroup>
+  <PropertyGroup Label="Globals">
+    <ProjectGuid>{8CC0CE51-32CF-4585-BFAF-A9343BC5A96D}</ProjectGuid>
+    <RootNamespace>lwIP_test</RootNamespace>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <UseOfMfc>false</UseOfMfc>
+    <CharacterSet>MultiByte</CharacterSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <UseOfMfc>false</UseOfMfc>
+    <CharacterSet>MultiByte</CharacterSet>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+  <ImportGroup Label="ExtensionSettings">
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+    <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+    <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />
+  </ImportGroup>
+  <PropertyGroup Label="UserMacros" />
+  <PropertyGroup>
+    <_ProjectFileVersion>10.0.40219.1</_ProjectFileVersion>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">.\$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">.\$(Configuration)\$(ProjectName)\</IntDir>
+    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</LinkIncremental>
+    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</LinkIncremental>
+  </PropertyGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <Midl>
+      <TypeLibraryName>.\Release/test.tlb</TypeLibraryName>
+      <HeaderFileName>
+      </HeaderFileName>
+    </Midl>
+    <ClCompile>
+      <Optimization>MaxSpeed</Optimization>
+      <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+      <AdditionalIncludeDirectories>..\..\..\..\lwip\src\include;..\..\..\..\lwip\src\include\ipv4;..\..\..\..\lwip\src\include\ipv6;..\include;..\..\..\examples\example_app;..\..\..;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <StringPooling>true</StringPooling>
+      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <PrecompiledHeaderOutputFile>$(IntDir)$(TargetName).pch</PrecompiledHeaderOutputFile>
+      <ProgramDataBaseFileName>$(IntDir)$(ProjectName).pdb</ProgramDataBaseFileName>
+      <WarningLevel>EnableAllWarnings</WarningLevel>
+      <SuppressStartupBanner>true</SuppressStartupBanner>
+      <CompileAs>Default</CompileAs>
+      <TreatWarningAsError>true</TreatWarningAsError>
+    </ClCompile>
+    <ResourceCompile>
+      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <Culture>0x0407</Culture>
+    </ResourceCompile>
+    <Link>
+      <AdditionalDependencies>Packet.lib;wpcap.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <SuppressStartupBanner>true</SuppressStartupBanner>
+      <AdditionalLibraryDirectories>$(PCAP_DIR)\Lib;..\..\..\..\winpcap\WpdPack\Lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+      <ProgramDatabaseFile>.\Release/test.pdb</ProgramDatabaseFile>
+      <SubSystem>Console</SubSystem>
+      <RandomizedBaseAddress>false</RandomizedBaseAddress>
+      <DataExecutionPrevention>
+      </DataExecutionPrevention>
+      <TargetMachine>MachineX86</TargetMachine>
+      <GenerateMapFile>true</GenerateMapFile>
+      <MapFileName>$(TargetDir)$(TargetName).map</MapFileName>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <Midl>
+      <TypeLibraryName>.\Debug/test.tlb</TypeLibraryName>
+      <HeaderFileName>
+      </HeaderFileName>
+    </Midl>
+    <ClCompile>
+      <Optimization>Disabled</Optimization>
+      <AdditionalIncludeDirectories>..\..\..\..\lwip\src\include;..\..\..\..\lwip\src\include\ipv4;..\..\..\..\lwip\src\include\ipv6;..\include;..\..\..\examples\example_app;..\..\..;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>_CONSOLE;WIN32;_DEBUG;LWIP_DEBUG;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+      <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <PrecompiledHeaderOutputFile>$(IntDir)$(TargetName).pch</PrecompiledHeaderOutputFile>
+      <ProgramDataBaseFileName>$(IntDir)$(ProjectName).pdb</ProgramDataBaseFileName>
+      <WarningLevel>EnableAllWarnings</WarningLevel>
+      <SuppressStartupBanner>true</SuppressStartupBanner>
+      <DebugInformationFormat>EditAndContinue</DebugInformationFormat>
+      <CompileAs>Default</CompileAs>
+      <TreatWarningAsError>true</TreatWarningAsError>
+    </ClCompile>
+    <ResourceCompile>
+      <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <Culture>0x0407</Culture>
+    </ResourceCompile>
+    <Link>
+      <AdditionalDependencies>Packet.lib;wpcap.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <SuppressStartupBanner>true</SuppressStartupBanner>
+      <AdditionalLibraryDirectories>$(PCAP_DIR)\Lib;..\..\..\..\winpcap\WpdPack\Lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <SubSystem>Console</SubSystem>
+      <RandomizedBaseAddress>false</RandomizedBaseAddress>
+      <DataExecutionPrevention>
+      </DataExecutionPrevention>
+      <TargetMachine>MachineX86</TargetMachine>
+      <GenerateMapFile>false</GenerateMapFile>
+      <MapFileName>$(TargetDir)$(TargetName).map</MapFileName>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemGroup>
+    <ClCompile Include="..\..\..\addons\ipv6_static_routing\ip6_route_table.c" />
+    <ClCompile Include="..\..\..\addons\tcp_isn\tcp_isn.c" />
+    <ClCompile Include="..\..\..\apps\tcpecho_raw\tcpecho_raw.c" />
+    <ClCompile Include="..\..\..\apps\udpecho_raw\udpecho_raw.c" />
+    <ClCompile Include="..\..\..\examples\example_app\test.c" />
+    <ClCompile Include="..\..\..\examples\httpd\cgi_example\cgi_example.c" />
+    <ClCompile Include="..\..\..\examples\httpd\fs_example\fs_example.c" />
+    <ClCompile Include="..\..\..\examples\httpd\genfiles_example\genfiles_example.c" />
+    <ClCompile Include="..\..\..\examples\httpd\post_example\post_example.c" />
+    <ClCompile Include="..\..\..\examples\httpd\ssi_example\ssi_example.c" />
+    <ClCompile Include="..\..\..\examples\lwiperf\lwiperf_example.c" />
+    <ClCompile Include="..\..\..\examples\mdns\mdns_example.c" />
+    <ClCompile Include="..\..\..\examples\mqtt\mqtt_example.c" />
+    <ClCompile Include="..\..\..\examples\ppp\pppos_example.c" />
+    <ClCompile Include="..\..\..\examples\snmp\snmp_example.c" />
+    <ClCompile Include="..\..\..\examples\snmp\snmp_private_mib\lwip_prvmib.c" />
+    <ClCompile Include="..\..\..\examples\snmp\snmp_v3\snmpv3_dummy.c" />
+    <ClCompile Include="..\..\..\examples\sntp\sntp_example.c" />
+    <ClCompile Include="..\..\..\examples\tftp\tftp_example.c" />
+    <ClCompile Include="..\..\..\apps\chargen\chargen.c" />
+    <ClCompile Include="..\..\..\apps\httpserver\httpserver-netconn.c" />
+    <ClCompile Include="..\..\..\apps\netio\netio.c" />
+    <ClCompile Include="..\..\..\apps\ping\ping.c" />
+    <ClCompile Include="..\..\..\apps\rtp\rtp.c" />
+    <ClCompile Include="..\..\..\apps\shell\shell.c" />
+    <ClCompile Include="..\..\..\apps\socket_examples\socket_examples.c" />
+    <ClCompile Include="..\..\..\apps\tcpecho\tcpecho.c" />
+    <ClCompile Include="..\..\..\apps\udpecho\udpecho.c" />
+    <ClCompile Include="..\example_app\default_netif.c" />
+  </ItemGroup>
+  <ItemGroup>
+    <ClInclude Include="..\..\..\addons\ipv6_static_routing\ip6_route_table.h" />
+    <ClInclude Include="..\..\..\addons\tcp_isn\tcp_isn.h" />
+    <ClInclude Include="..\..\..\apps\chargen\chargen.h" />
+    <ClInclude Include="..\..\..\apps\httpserver\httpserver-netconn.h" />
+    <ClInclude Include="..\..\..\apps\netio\netio.h" />
+    <ClInclude Include="..\..\..\apps\ping\ping.h" />
+    <ClInclude Include="..\..\..\apps\rtp\rtp.h" />
+    <ClInclude Include="..\..\..\apps\shell\shell.h" />
+    <ClInclude Include="..\..\..\apps\socket_examples\socket_examples.h" />
+    <ClInclude Include="..\..\..\apps\tcpecho\tcpecho.h" />
+    <ClInclude Include="..\..\..\apps\tcpecho_raw\tcpecho_raw.h" />
+    <ClInclude Include="..\..\..\apps\udpecho\udpecho.h" />
+    <ClInclude Include="..\..\..\apps\udpecho_raw\udpecho_raw.h" />
+    <ClInclude Include="..\..\..\examples\httpd\cgi_example\cgi_example.h" />
+    <ClInclude Include="..\..\..\examples\httpd\fs_example\fs_example.h" />
+    <ClInclude Include="..\..\..\examples\httpd\genfiles_example\genfiles_example.h" />
+    <ClInclude Include="..\..\..\examples\httpd\ssi_example\ssi_example.h" />
+    <ClInclude Include="..\..\..\examples\lwiperf\lwiperf_example.h" />
+    <ClInclude Include="..\..\..\examples\mdns\mdns_example.h" />
+    <ClInclude Include="..\..\..\examples\mqtt\mqtt_example.h" />
+    <ClInclude Include="..\..\..\examples\ppp\pppos_example.h" />
+    <ClInclude Include="..\..\..\examples\snmp\snmp_example.h" />
+    <ClInclude Include="..\..\..\examples\snmp\snmp_private_mib\private_mib.h" />
+    <ClInclude Include="..\..\..\examples\snmp\snmp_v3\snmpv3_dummy.h" />
+    <ClInclude Include="..\..\..\examples\sntp\sntp_example.h" />
+    <ClInclude Include="..\..\..\examples\tftp\tftp_example.h" />
+  </ItemGroup>
+  <ItemGroup>
+    <None Include="..\..\..\addons\ipv6_static_routing\README" />
+  </ItemGroup>
+  <ItemGroup>
+    <ProjectReference Include="lwIP.vcxproj">
+      <Project>{2cc276fa-b226-49c9-8f82-7fcd5a228e28}</Project>
+      <ReferenceOutputAssembly>false</ReferenceOutputAssembly>
+    </ProjectReference>
+    <ProjectReference Include="lwIP_pcapif.vcxproj">
+      <Project>{6f44e49e-9f21-4144-91ec-53b92aef62ce}</Project>
+      <ReferenceOutputAssembly>false</ReferenceOutputAssembly>
+    </ProjectReference>
+  </ItemGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+  <ImportGroup Label="ExtensionTargets">
+  </ImportGroup>
+</Project>
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/ports/win32/msvc/lwIP_Test.vcxproj.filters
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/ports/win32/msvc/lwIP_Test.vcxproj.filters	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/ports/win32/msvc/lwIP_Test.vcxproj.filters	(revision 457)
@@ -0,0 +1,243 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup>
+    <Filter Include="Source Files">
+      <UniqueIdentifier>{e858c3d0-1558-4d47-bc6a-9d4a55ce3d3a}</UniqueIdentifier>
+      <Extensions>cpp;c;cxx;rc;def;r;odl;idl;hpj;bat</Extensions>
+    </Filter>
+    <Filter Include="Source Files\apps">
+      <UniqueIdentifier>{0582eefd-a68e-45f8-b93c-f828c4794f30}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="Source Files\addons">
+      <UniqueIdentifier>{ed0627c2-099a-4da8-af0c-142003828f9f}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="Source Files\addons\tcp_isn">
+      <UniqueIdentifier>{4ffb2268-6fc6-44d7-8e3b-2a3f68b8d5a3}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="Source Files\addons\ipv6_static_routing">
+      <UniqueIdentifier>{93b36161-88b2-448c-9c45-ac6f27b98290}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="Source Files\examples">
+      <UniqueIdentifier>{6456d2d6-61e6-4c99-9f1f-1f225437a642}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="Source Files\examples\httpd">
+      <UniqueIdentifier>{75bb877e-aa45-4e2e-82fe-946ddadc6a64}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="Source Files\examples\snmp">
+      <UniqueIdentifier>{78411edf-fe39-4edb-a6bd-2833755e0342}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="Source Files\examples\httpd\fs_example">
+      <UniqueIdentifier>{531dd0cf-ec13-42b7-a3bb-b837382d4ecd}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="Source Files\examples\httpd\ssi_example">
+      <UniqueIdentifier>{d71bdb12-c5ed-4823-99f0-2d537765a2eb}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="Source Files\examples\snmp\snmp_private_mib">
+      <UniqueIdentifier>{0b9db8c7-f352-4ca6-86c6-1a6c58482c5d}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="Source Files\examples\snmp\snmp_v3">
+      <UniqueIdentifier>{97f0ea5c-16cf-4640-a6b3-ace059ed2388}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="Source Files\examples\httpd\cgi_example">
+      <UniqueIdentifier>{24079d2d-aab1-49f9-b0fa-57910a18b93a}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="Source Files\examples\httpd\genfiles_example">
+      <UniqueIdentifier>{d38ed32b-9498-429e-a02c-08332c463725}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="Source Files\examples\httpd\post_example">
+      <UniqueIdentifier>{672a49fd-94ff-4126-8de3-e96c9c32dfb8}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="Source Files\examples\mdns">
+      <UniqueIdentifier>{e5276e3f-3e2a-4376-aee3-85aafd12c77b}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="Source Files\examples\tftp">
+      <UniqueIdentifier>{f6d95ce0-df4f-4988-8654-624468dd4ecd}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="Source Files\examples\sntp">
+      <UniqueIdentifier>{a37e5539-232e-4d91-9c10-3d7a851b8c4c}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="Source Files\examples\ppp">
+      <UniqueIdentifier>{a2a65260-5055-4a0d-bd0b-4a3ca3560918}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="Source Files\examples\lwiperf">
+      <UniqueIdentifier>{aa359e5e-131e-4f20-9e5d-416f9ae76abd}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="Source Files\examples\mqtt">
+      <UniqueIdentifier>{bd6f1fcc-c88f-4b96-a267-401f6bf9898b}</UniqueIdentifier>
+    </Filter>
+  </ItemGroup>
+  <ItemGroup>
+    <ClCompile Include="..\..\..\apps\chargen\chargen.c">
+      <Filter>Source Files\apps</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\apps\httpserver\httpserver-netconn.c">
+      <Filter>Source Files\apps</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\apps\netio\netio.c">
+      <Filter>Source Files\apps</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\apps\ping\ping.c">
+      <Filter>Source Files\apps</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\apps\rtp\rtp.c">
+      <Filter>Source Files\apps</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\apps\shell\shell.c">
+      <Filter>Source Files\apps</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\apps\socket_examples\socket_examples.c">
+      <Filter>Source Files\apps</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\apps\tcpecho\tcpecho.c">
+      <Filter>Source Files\apps</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\apps\udpecho\udpecho.c">
+      <Filter>Source Files\apps</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\apps\tcpecho_raw\tcpecho_raw.c">
+      <Filter>Source Files\apps</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\apps\udpecho_raw\udpecho_raw.c">
+      <Filter>Source Files\apps</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\addons\tcp_isn\tcp_isn.c">
+      <Filter>Source Files\addons\tcp_isn</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\addons\ipv6_static_routing\ip6_route_table.c">
+      <Filter>Source Files\addons\ipv6_static_routing</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\examples\httpd\fs_example\fs_example.c">
+      <Filter>Source Files\examples\httpd\fs_example</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\examples\httpd\ssi_example\ssi_example.c">
+      <Filter>Source Files\examples\httpd\ssi_example</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\examples\snmp\snmp_private_mib\lwip_prvmib.c">
+      <Filter>Source Files\examples\snmp\snmp_private_mib</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\examples\snmp\snmp_v3\snmpv3_dummy.c">
+      <Filter>Source Files\examples\snmp\snmp_v3</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\examples\httpd\cgi_example\cgi_example.c">
+      <Filter>Source Files\examples\httpd\cgi_example</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\examples\httpd\genfiles_example\genfiles_example.c">
+      <Filter>Source Files\examples\httpd\genfiles_example</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\examples\httpd\post_example\post_example.c">
+      <Filter>Source Files\examples\httpd\post_example</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\examples\mdns\mdns_example.c">
+      <Filter>Source Files\examples\mdns</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\examples\tftp\tftp_example.c">
+      <Filter>Source Files\examples\tftp</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\examples\snmp\snmp_example.c">
+      <Filter>Source Files\examples\snmp</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\examples\sntp\sntp_example.c">
+      <Filter>Source Files\examples\sntp</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\examples\ppp\pppos_example.c">
+      <Filter>Source Files\examples\ppp</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\examples\lwiperf\lwiperf_example.c">
+      <Filter>Source Files\examples\lwiperf</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\examples\mqtt\mqtt_example.c">
+      <Filter>Source Files\examples\mqtt</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\examples\example_app\test.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\example_app\default_netif.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+  </ItemGroup>
+  <ItemGroup>
+    <ClInclude Include="..\..\..\apps\chargen\chargen.h">
+      <Filter>Source Files\apps</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\apps\httpserver\httpserver-netconn.h">
+      <Filter>Source Files\apps</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\apps\netio\netio.h">
+      <Filter>Source Files\apps</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\apps\ping\ping.h">
+      <Filter>Source Files\apps</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\apps\rtp\rtp.h">
+      <Filter>Source Files\apps</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\apps\shell\shell.h">
+      <Filter>Source Files\apps</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\apps\socket_examples\socket_examples.h">
+      <Filter>Source Files\apps</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\apps\tcpecho\tcpecho.h">
+      <Filter>Source Files\apps</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\apps\udpecho\udpecho.h">
+      <Filter>Source Files\apps</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\apps\tcpecho_raw\tcpecho_raw.h">
+      <Filter>Source Files\apps</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\apps\udpecho_raw\udpecho_raw.h">
+      <Filter>Source Files\apps</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\addons\tcp_isn\tcp_isn.h">
+      <Filter>Source Files\addons\tcp_isn</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\addons\ipv6_static_routing\ip6_route_table.h">
+      <Filter>Source Files\addons\ipv6_static_routing</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\examples\httpd\fs_example\fs_example.h">
+      <Filter>Source Files\examples\httpd\fs_example</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\examples\httpd\ssi_example\ssi_example.h">
+      <Filter>Source Files\examples\httpd\ssi_example</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\examples\snmp\snmp_private_mib\private_mib.h">
+      <Filter>Source Files\examples\snmp\snmp_private_mib</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\examples\snmp\snmp_v3\snmpv3_dummy.h">
+      <Filter>Source Files\examples\snmp\snmp_v3</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\examples\httpd\cgi_example\cgi_example.h">
+      <Filter>Source Files\examples\httpd\cgi_example</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\examples\httpd\genfiles_example\genfiles_example.h">
+      <Filter>Source Files\examples\httpd\genfiles_example</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\examples\mdns\mdns_example.h">
+      <Filter>Source Files\examples\mdns</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\examples\tftp\tftp_example.h">
+      <Filter>Source Files\examples\tftp</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\examples\snmp\snmp_example.h">
+      <Filter>Source Files\examples\snmp</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\examples\sntp\sntp_example.h">
+      <Filter>Source Files\examples\sntp</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\examples\ppp\pppos_example.h">
+      <Filter>Source Files\examples\ppp</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\examples\lwiperf\lwiperf_example.h">
+      <Filter>Source Files\examples\lwiperf</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\examples\mqtt\mqtt_example.h">
+      <Filter>Source Files\examples\mqtt</Filter>
+    </ClInclude>
+  </ItemGroup>
+  <ItemGroup>
+    <None Include="..\..\..\addons\ipv6_static_routing\README">
+      <Filter>Source Files\addons\ipv6_static_routing</Filter>
+    </None>
+  </ItemGroup>
+</Project>
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/ports/win32/msvc/lwIP_pcapif.vcxproj
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/ports/win32/msvc/lwIP_pcapif.vcxproj	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/ports/win32/msvc/lwIP_pcapif.vcxproj	(revision 457)
@@ -0,0 +1,111 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup Label="ProjectConfigurations">
+    <ProjectConfiguration Include="Debug|Win32">
+      <Configuration>Debug</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|Win32">
+      <Configuration>Release</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+  </ItemGroup>
+  <PropertyGroup Label="Globals">
+    <ProjectName>lwIP pcapif</ProjectName>
+    <ProjectGuid>{6F44E49E-9F21-4144-91EC-53B92AEF62CE}</ProjectGuid>
+    <RootNamespace>lwIP pcapif</RootNamespace>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+    <ConfigurationType>StaticLibrary</ConfigurationType>
+    <UseOfMfc>false</UseOfMfc>
+    <CharacterSet>MultiByte</CharacterSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+    <ConfigurationType>StaticLibrary</ConfigurationType>
+    <UseOfMfc>false</UseOfMfc>
+    <CharacterSet>MultiByte</CharacterSet>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+  <ImportGroup Label="ExtensionSettings">
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+    <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+    <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />
+  </ImportGroup>
+  <PropertyGroup Label="UserMacros" />
+  <PropertyGroup>
+    <_ProjectFileVersion>10.0.40219.1</_ProjectFileVersion>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">.\$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">.\$(Configuration)\$(ProjectName)\</IntDir>
+  </PropertyGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <ClCompile>
+      <Optimization>Disabled</Optimization>
+      <AdditionalIncludeDirectories>..\..\..\..\lwip\src\include;..\..\..\..\lwip\src\include\ipv4;..\..\..\..\lwip\src\include\ipv6;..\include;..\..\..\examples\example_app;.\;$(PCAP_DIR)\Include;..\..\..\..\winpcap\WpdPack\Include\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>_LIB;WIN32;_DEBUG;LWIP_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+      <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <ProgramDataBaseFileName>$(IntDir)$(ProjectName).pdb</ProgramDataBaseFileName>
+      <WarningLevel>EnableAllWarnings</WarningLevel>
+      <SuppressStartupBanner>true</SuppressStartupBanner>
+      <DebugInformationFormat>EditAndContinue</DebugInformationFormat>
+      <CompileAs>Default</CompileAs>
+      <TreatWarningAsError>true</TreatWarningAsError>
+    </ClCompile>
+    <ResourceCompile>
+      <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <Culture>0x0407</Culture>
+    </ResourceCompile>
+    <Lib />
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <ClCompile>
+      <Optimization>MaxSpeed</Optimization>
+      <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+      <AdditionalIncludeDirectories>..\..\..\..\lwip\src\include;..\..\..\..\lwip\src\include\ipv4;..\..\..\..\lwip\src\include\ipv6;..\include;..\..\..\examples\example_app;.\;$(PCAP_DIR)\Include;..\..\..\..\winpcap\WpdPack\Include\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <StringPooling>true</StringPooling>
+      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <PrecompiledHeaderOutputFile>$(IntDir)$(TargetName).pch</PrecompiledHeaderOutputFile>
+      <ProgramDataBaseFileName>$(IntDir)$(ProjectName).pdb</ProgramDataBaseFileName>
+      <WarningLevel>EnableAllWarnings</WarningLevel>
+      <SuppressStartupBanner>true</SuppressStartupBanner>
+      <CompileAs>Default</CompileAs>
+      <TreatWarningAsError>true</TreatWarningAsError>
+    </ClCompile>
+    <ResourceCompile>
+      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <Culture>0x0407</Culture>
+    </ResourceCompile>
+    <Lib>
+      <SuppressStartupBanner>true</SuppressStartupBanner>
+    </Lib>
+  </ItemDefinitionGroup>
+  <ItemGroup>
+    <ClCompile Include="..\pcapif.c" />
+    <ClCompile Include="..\pcapif_helper.c" />
+  </ItemGroup>
+  <ItemGroup>
+    <ClInclude Include="..\pcapif.h" />
+    <ClInclude Include="..\pcapif_helper.h" />
+  </ItemGroup>
+  <ItemGroup>
+    <ProjectReference Include="lwIP.vcxproj">
+      <Project>{2cc276fa-b226-49c9-8f82-7fcd5a228e28}</Project>
+      <ReferenceOutputAssembly>false</ReferenceOutputAssembly>
+    </ProjectReference>
+  </ItemGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+  <ImportGroup Label="ExtensionTargets">
+  </ImportGroup>
+</Project>
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/ports/win32/msvc/lwIP_pcapif.vcxproj.filters
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/ports/win32/msvc/lwIP_pcapif.vcxproj.filters	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/ports/win32/msvc/lwIP_pcapif.vcxproj.filters	(revision 457)
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup>
+    <Filter Include="Source Files">
+      <UniqueIdentifier>{0d38b8c3-e694-4572-89b8-fc6e825a092d}</UniqueIdentifier>
+      <Extensions>cpp;c;cxx;rc;def;r;odl;idl;hpj;bat</Extensions>
+    </Filter>
+    <Filter Include="Header Files">
+      <UniqueIdentifier>{e5ce29d5-319e-4e99-978b-b88e8d6167e4}</UniqueIdentifier>
+    </Filter>
+  </ItemGroup>
+  <ItemGroup>
+    <ClCompile Include="..\pcapif.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\pcapif_helper.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+  </ItemGroup>
+  <ItemGroup>
+    <ClInclude Include="..\pcapif.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\pcapif_helper.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+  </ItemGroup>
+</Project>
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/ports/win32/msvc/lwIP_unittests.sln
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/ports/win32/msvc/lwIP_unittests.sln	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/ports/win32/msvc/lwIP_unittests.sln	(revision 457)
@@ -0,0 +1,31 @@
+Microsoft Visual Studio Solution File, Format Version 11.00
+# Visual C++ Express 2010
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "lwip_unittests", "lwip_unittests.vcxproj", "{6CCABAA4-F86F-4119-AFF8-43C9A4A234C2}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "lwIP", "lwIP.vcxproj", "{2CC276FA-B226-49C9-8F82-7FCD5A228E28}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libcheck", "libcheck.vcxproj", "{EBB156DC-01BF-47B2-B69C-1A750B6B5F09}"
+EndProject
+Global
+	GlobalSection(SolutionConfigurationPlatforms) = preSolution
+		Debug|Win32 = Debug|Win32
+		Release|Win32 = Release|Win32
+	EndGlobalSection
+	GlobalSection(ProjectConfigurationPlatforms) = postSolution
+		{6CCABAA4-F86F-4119-AFF8-43C9A4A234C2}.Debug|Win32.ActiveCfg = Debug|Win32
+		{6CCABAA4-F86F-4119-AFF8-43C9A4A234C2}.Debug|Win32.Build.0 = Debug|Win32
+		{6CCABAA4-F86F-4119-AFF8-43C9A4A234C2}.Release|Win32.ActiveCfg = Release|Win32
+		{6CCABAA4-F86F-4119-AFF8-43C9A4A234C2}.Release|Win32.Build.0 = Release|Win32
+		{2CC276FA-B226-49C9-8F82-7FCD5A228E28}.Debug|Win32.ActiveCfg = Debug unittests|Win32
+		{2CC276FA-B226-49C9-8F82-7FCD5A228E28}.Debug|Win32.Build.0 = Debug unittests|Win32
+		{2CC276FA-B226-49C9-8F82-7FCD5A228E28}.Release|Win32.ActiveCfg = Release unittests|Win32
+		{2CC276FA-B226-49C9-8F82-7FCD5A228E28}.Release|Win32.Build.0 = Release unittests|Win32
+		{EBB156DC-01BF-47B2-B69C-1A750B6B5F09}.Debug|Win32.ActiveCfg = Debug|Win32
+		{EBB156DC-01BF-47B2-B69C-1A750B6B5F09}.Debug|Win32.Build.0 = Debug|Win32
+		{EBB156DC-01BF-47B2-B69C-1A750B6B5F09}.Release|Win32.ActiveCfg = Release|Win32
+		{EBB156DC-01BF-47B2-B69C-1A750B6B5F09}.Release|Win32.Build.0 = Release|Win32
+	EndGlobalSection
+	GlobalSection(SolutionProperties) = preSolution
+		HideSolutionNode = FALSE
+	EndGlobalSection
+EndGlobal
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/ports/win32/msvc/lwip_unittests.vcxproj
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/ports/win32/msvc/lwip_unittests.vcxproj	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/ports/win32/msvc/lwip_unittests.vcxproj	(revision 457)
@@ -0,0 +1,137 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup Label="ProjectConfigurations">
+    <ProjectConfiguration Include="Debug|Win32">
+      <Configuration>Debug</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|Win32">
+      <Configuration>Release</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+  </ItemGroup>
+  <PropertyGroup Label="Globals">
+    <ProjectGuid>{6CCABAA4-F86F-4119-AFF8-43C9A4A234C2}</ProjectGuid>
+    <RootNamespace>lwip_unittests</RootNamespace>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <CharacterSet>MultiByte</CharacterSet>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <CharacterSet>MultiByte</CharacterSet>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+  <ImportGroup Label="ExtensionSettings">
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <PropertyGroup Label="UserMacros" />
+  <PropertyGroup>
+    <_ProjectFileVersion>10.0.40219.1</_ProjectFileVersion>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(Configuration)\$(ProjectName)\</IntDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(Configuration)\$(ProjectName)\</IntDir>
+  </PropertyGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <ClCompile>
+      <Optimization>Disabled</Optimization>
+      <AdditionalIncludeDirectories>..\check;..\..\..\..\check\src;..\..\..\..\lwip\test\unit;..\..\..\..\lwip\src\include;..\..\..\..\lwip\src\include\ipv4;..\..\..\..\lwip\src\include\ipv6;..\include;..;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>_LIB;WIN32;_DEBUG;LWIP_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <MinimalRebuild>true</MinimalRebuild>
+      <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+      <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
+      <WarningLevel>EnableAllWarnings</WarningLevel>
+      <DebugInformationFormat>EditAndContinue</DebugInformationFormat>
+      <DisableSpecificWarnings>4820</DisableSpecificWarnings>
+    </ClCompile>
+    <Link>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <RandomizedBaseAddress>false</RandomizedBaseAddress>
+      <DataExecutionPrevention>
+      </DataExecutionPrevention>
+      <TargetMachine>MachineX86</TargetMachine>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <ClCompile>
+      <Optimization>MaxSpeed</Optimization>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <AdditionalIncludeDirectories>..\check;..\..\..\..\check\src;..\..\..\..\lwip\test\unit;..\..\..\..\lwip\src\include;..\..\..\..\lwip\src\include\ipv4;..\..\..\..\lwip\src\include\ipv6;..\include;..;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <WarningLevel>Level4</WarningLevel>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+    </ClCompile>
+    <Link>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <OptimizeReferences>true</OptimizeReferences>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <RandomizedBaseAddress>false</RandomizedBaseAddress>
+      <DataExecutionPrevention>
+      </DataExecutionPrevention>
+      <TargetMachine>MachineX86</TargetMachine>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemGroup>
+    <ClCompile Include="..\..\..\..\lwip\test\unit\api\test_sockets.c" />
+    <ClCompile Include="..\..\..\..\lwip\test\unit\arch\sys_arch.c" />
+    <ClCompile Include="..\..\..\..\lwip\test\unit\core\test_def.c" />
+    <ClCompile Include="..\..\..\..\lwip\test\unit\core\test_mem.c" />
+    <ClCompile Include="..\..\..\..\lwip\test\unit\core\test_netif.c" />
+    <ClCompile Include="..\..\..\..\lwip\test\unit\core\test_pbuf.c" />
+    <ClCompile Include="..\..\..\..\lwip\test\unit\core\test_timers.c" />
+    <ClCompile Include="..\..\..\..\lwip\test\unit\ip4\test_ip4.c" />
+    <ClCompile Include="..\..\..\..\lwip\test\unit\ip6\test_ip6.c" />
+    <ClCompile Include="..\..\..\..\lwip\test\unit\mdns\test_mdns.c" />
+    <ClCompile Include="..\..\..\..\lwip\test\unit\mqtt\test_mqtt.c" />
+    <ClCompile Include="..\..\..\..\lwip\test\unit\tcp\tcp_helper.c" />
+    <ClCompile Include="..\..\..\..\lwip\test\unit\tcp\test_tcp.c" />
+    <ClCompile Include="..\..\..\..\lwip\test\unit\tcp\test_tcp_oos.c" />
+    <ClCompile Include="..\..\..\..\lwip\test\unit\udp\test_udp.c" />
+    <ClCompile Include="..\..\..\..\lwip\test\unit\etharp\test_etharp.c" />
+    <ClCompile Include="..\..\..\..\lwip\test\unit\dhcp\test_dhcp.c" />
+    <ClCompile Include="..\..\..\..\lwip\test\unit\lwip_unittests.c" />
+  </ItemGroup>
+  <ItemGroup>
+    <ClInclude Include="..\..\..\..\lwip\test\unit\api\test_sockets.h" />
+    <ClInclude Include="..\..\..\..\lwip\test\unit\arch\sys_arch.h" />
+    <ClInclude Include="..\..\..\..\lwip\test\unit\core\test_def.h" />
+    <ClInclude Include="..\..\..\..\lwip\test\unit\core\test_mem.h" />
+    <ClInclude Include="..\..\..\..\lwip\test\unit\core\test_netif.h" />
+    <ClInclude Include="..\..\..\..\lwip\test\unit\core\test_pbuf.h" />
+    <ClInclude Include="..\..\..\..\lwip\test\unit\core\test_timers.h" />
+    <ClInclude Include="..\..\..\..\lwip\test\unit\ip4\test_ip4.h" />
+    <ClInclude Include="..\..\..\..\lwip\test\unit\ip6\test_ip6.h" />
+    <ClInclude Include="..\..\..\..\lwip\test\unit\mdns\test_mdns.h" />
+    <ClInclude Include="..\..\..\..\lwip\test\unit\mqtt\test_mqtt.h" />
+    <ClInclude Include="..\..\..\..\lwip\test\unit\tcp\tcp_helper.h" />
+    <ClInclude Include="..\..\..\..\lwip\test\unit\tcp\test_tcp.h" />
+    <ClInclude Include="..\..\..\..\lwip\test\unit\tcp\test_tcp_oos.h" />
+    <ClInclude Include="..\..\..\..\lwip\test\unit\udp\test_udp.h" />
+    <ClInclude Include="..\..\..\..\lwip\test\unit\etharp\test_etharp.h" />
+    <ClInclude Include="..\..\..\..\lwip\test\unit\dhcp\test_dhcp.h" />
+    <ClInclude Include="..\..\..\..\lwip\test\unit\lwip_check.h" />
+    <ClInclude Include="..\..\..\..\lwip\test\unit\lwipopts.h" />
+  </ItemGroup>
+  <ItemGroup>
+    <ProjectReference Include="libcheck.vcxproj">
+      <Project>{ebb156dc-01bf-47b2-b69c-1a750b6b5f09}</Project>
+      <ReferenceOutputAssembly>false</ReferenceOutputAssembly>
+    </ProjectReference>
+    <ProjectReference Include="lwIP.vcxproj">
+      <Project>{2cc276fa-b226-49c9-8f82-7fcd5a228e28}</Project>
+      <ReferenceOutputAssembly>false</ReferenceOutputAssembly>
+    </ProjectReference>
+  </ItemGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+  <ImportGroup Label="ExtensionTargets">
+  </ImportGroup>
+</Project>
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/ports/win32/msvc/lwip_unittests.vcxproj.filters
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/ports/win32/msvc/lwip_unittests.vcxproj.filters	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/ports/win32/msvc/lwip_unittests.vcxproj.filters	(revision 457)
@@ -0,0 +1,147 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup>
+    <Filter Include="core">
+      <UniqueIdentifier>{e351c538-9f2b-4a01-bf46-3ee8873cbc0f}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="tcp">
+      <UniqueIdentifier>{5805c4bc-32c1-49cf-a35e-af58757e2d7a}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="udp">
+      <UniqueIdentifier>{173ba4ab-b194-4933-8e02-319044c2a8fa}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="etharp">
+      <UniqueIdentifier>{70c655a7-f40f-4728-b586-33fd9598b355}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="dhcp">
+      <UniqueIdentifier>{a6b60d4e-4b81-44f2-9408-2e45cc769391}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="mdns">
+      <UniqueIdentifier>{d454902e-ce5b-48ae-a690-e6490bdbbf17}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="api">
+      <UniqueIdentifier>{d9501476-6102-4f14-90bd-35322fbd2fb2}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="arch">
+      <UniqueIdentifier>{b04f182c-1910-456d-9388-397dfe82dbc9}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="mqtt">
+      <UniqueIdentifier>{fd48ae04-ec85-478f-a97c-a7c8384a2d94}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="ip4">
+      <UniqueIdentifier>{fe93fc95-f1af-4a1f-a086-c1771dbf4d79}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="ipv6">
+      <UniqueIdentifier>{924d29be-e5e4-4b25-8bc4-92db91ce4c49}</UniqueIdentifier>
+    </Filter>
+  </ItemGroup>
+  <ItemGroup>
+    <ClCompile Include="..\..\..\..\lwip\test\unit\core\test_mem.c">
+      <Filter>core</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\lwip\test\unit\core\test_pbuf.c">
+      <Filter>core</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\lwip\test\unit\tcp\tcp_helper.c">
+      <Filter>tcp</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\lwip\test\unit\tcp\test_tcp.c">
+      <Filter>tcp</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\lwip\test\unit\tcp\test_tcp_oos.c">
+      <Filter>tcp</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\lwip\test\unit\udp\test_udp.c">
+      <Filter>udp</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\lwip\test\unit\etharp\test_etharp.c">
+      <Filter>etharp</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\lwip\test\unit\dhcp\test_dhcp.c">
+      <Filter>dhcp</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\lwip\test\unit\lwip_unittests.c" />
+    <ClCompile Include="..\..\..\..\lwip\test\unit\mdns\test_mdns.c">
+      <Filter>mdns</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\lwip\test\unit\api\test_sockets.c">
+      <Filter>api</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\lwip\test\unit\arch\sys_arch.c">
+      <Filter>arch</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\lwip\test\unit\mqtt\test_mqtt.c">
+      <Filter>mqtt</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\lwip\test\unit\ip4\test_ip4.c">
+      <Filter>ip4</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\lwip\test\unit\core\test_def.c">
+      <Filter>core</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\lwip\test\unit\core\test_timers.c">
+      <Filter>core</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\lwip\test\unit\core\test_netif.c">
+      <Filter>core</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\lwip\test\unit\ip6\test_ip6.c">
+      <Filter>ipv6</Filter>
+    </ClCompile>
+  </ItemGroup>
+  <ItemGroup>
+    <ClInclude Include="..\..\..\..\lwip\test\unit\core\test_mem.h">
+      <Filter>core</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\..\lwip\test\unit\core\test_pbuf.h">
+      <Filter>core</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\..\lwip\test\unit\tcp\tcp_helper.h">
+      <Filter>tcp</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\..\lwip\test\unit\tcp\test_tcp.h">
+      <Filter>tcp</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\..\lwip\test\unit\tcp\test_tcp_oos.h">
+      <Filter>tcp</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\..\lwip\test\unit\udp\test_udp.h">
+      <Filter>udp</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\..\lwip\test\unit\etharp\test_etharp.h">
+      <Filter>etharp</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\..\lwip\test\unit\dhcp\test_dhcp.h">
+      <Filter>dhcp</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\..\lwip\test\unit\lwip_check.h" />
+    <ClInclude Include="..\..\..\..\lwip\test\unit\lwipopts.h" />
+    <ClInclude Include="..\..\..\..\lwip\test\unit\mdns\test_mdns.h">
+      <Filter>mdns</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\..\lwip\test\unit\api\test_sockets.h">
+      <Filter>api</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\..\lwip\test\unit\arch\sys_arch.h">
+      <Filter>arch</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\..\lwip\test\unit\mqtt\test_mqtt.h">
+      <Filter>mqtt</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\..\lwip\test\unit\ip4\test_ip4.h">
+      <Filter>ip4</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\..\lwip\test\unit\core\test_def.h">
+      <Filter>core</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\..\lwip\test\unit\core\test_timers.h">
+      <Filter>core</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\..\lwip\test\unit\core\test_netif.h">
+      <Filter>core</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\..\lwip\test\unit\ip6\test_ip6.h">
+      <Filter>ipv6</Filter>
+    </ClInclude>
+  </ItemGroup>
+</Project>
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/ports/win32/msvc/makefsdata.vcxproj
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/ports/win32/msvc/makefsdata.vcxproj	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/ports/win32/msvc/makefsdata.vcxproj	(revision 457)
@@ -0,0 +1,99 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup Label="ProjectConfigurations">
+    <ProjectConfiguration Include="Debug|Win32">
+      <Configuration>Debug</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|Win32">
+      <Configuration>Release</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+  </ItemGroup>
+  <ItemGroup>
+    <ClCompile Include="..\..\..\..\lwip\src\apps\http\makefsdata\makefsdata.c" />
+  </ItemGroup>
+  <PropertyGroup Label="Globals">
+    <ProjectGuid>{0BFC0F21-8E84-4E68-A9E1-CE2A09B72F6D}</ProjectGuid>
+    <RootNamespace>makefsdata</RootNamespace>
+    <Keyword>Win32Proj</Keyword>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <CharacterSet>Unicode</CharacterSet>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <CharacterSet>Unicode</CharacterSet>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+  <ImportGroup Label="ExtensionSettings">
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <PropertyGroup Label="UserMacros" />
+  <PropertyGroup>
+    <_ProjectFileVersion>10.0.40219.1</_ProjectFileVersion>
+    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</LinkIncremental>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(SolutionDir)$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(Configuration)\</IntDir>
+    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</LinkIncremental>
+  </PropertyGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <ClCompile>
+      <Optimization>Disabled</Optimization>
+      <AdditionalIncludeDirectories>..\..\..\..\lwip\src\include;..\..\..\..\lwip\src\include\ipv4;..\..\..\..\lwip\src\include\ipv6;..\include;..\..\..\examples\example_app;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <MinimalRebuild>true</MinimalRebuild>
+      <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <WarningLevel>Level4</WarningLevel>
+      <TreatWarningAsError>true</TreatWarningAsError>
+      <DebugInformationFormat>EditAndContinue</DebugInformationFormat>
+    </ClCompile>
+    <Link>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <SubSystem>Console</SubSystem>
+      <RandomizedBaseAddress>false</RandomizedBaseAddress>
+      <DataExecutionPrevention>
+      </DataExecutionPrevention>
+      <TargetMachine>MachineX86</TargetMachine>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <ClCompile>
+      <Optimization>MaxSpeed</Optimization>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <AdditionalIncludeDirectories>..\..\..\..\lwip\src\include;..\..\..\..\lwip\src\include\ipv4;..\..\..\..\lwip\src\include\ipv6;..\include;..\..\..\examples\example_app;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <WarningLevel>Level4</WarningLevel>
+      <TreatWarningAsError>true</TreatWarningAsError>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+    </ClCompile>
+    <Link>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <SubSystem>Console</SubSystem>
+      <OptimizeReferences>true</OptimizeReferences>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <RandomizedBaseAddress>false</RandomizedBaseAddress>
+      <DataExecutionPrevention>
+      </DataExecutionPrevention>
+      <TargetMachine>MachineX86</TargetMachine>
+    </Link>
+  </ItemDefinitionGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+  <ImportGroup Label="ExtensionTargets">
+  </ImportGroup>
+</Project>
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/ports/win32/msvc/makefsdata.vcxproj.filters
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/ports/win32/msvc/makefsdata.vcxproj.filters	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/ports/win32/msvc/makefsdata.vcxproj.filters	(revision 457)
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup>
+    <Filter Include="Quelldateien">
+      <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
+      <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
+    </Filter>
+  </ItemGroup>
+  <ItemGroup>
+    <ClCompile Include="..\..\..\..\lwip\src\apps\http\makefsdata\makefsdata.c">
+      <Filter>Quelldateien</Filter>
+    </ClCompile>
+  </ItemGroup>
+</Project>
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/ports/win32/pcapif.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/ports/win32/pcapif.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/ports/win32/pcapif.c	(revision 457)
@@ -0,0 +1,1091 @@
+/**
+ * pcapif.c - This file is part of lwIP pcapif
+ *
+ ****************************************************************************
+ *
+ * This file is derived from an example in lwIP with the following license:
+ *
+ * Copyright (c) 2001, Swedish Institute of Computer Science.
+ * 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 Institute 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 INSTITUTE 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 INSTITUTE 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 the port-dependent configuration */
+#include "lwipcfg.h"
+
+#include <stdlib.h>
+#include <stdio.h>
+
+#ifdef _MSC_VER
+#pragma warning( push, 3 )
+#include "pcap.h"
+#pragma warning ( pop )
+#else
+/* e.g. mingw */
+#define _MSC_VER 1500
+#include "pcap.h"
+#undef _MSC_VER
+#endif
+
+#include "lwip/opt.h"
+
+#if LWIP_ETHERNET
+
+#include "pcapif.h"
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "lwip/debug.h"
+
+#include "lwip/def.h"
+#include "lwip/mem.h"
+#include "lwip/pbuf.h"
+#include "lwip/stats.h"
+#include "lwip/sys.h"
+#include "lwip/ip.h"
+#include "lwip/snmp.h"
+#include "lwip/tcpip.h"
+#include "lwip/timeouts.h"
+#include "lwip/ethip6.h"
+
+#include "lwip/etharp.h"
+
+/* For compatibility with old pcap */
+#ifndef PCAP_OPENFLAG_PROMISCUOUS
+#define PCAP_OPENFLAG_PROMISCUOUS     1
+#endif
+
+/** Set this to 0 to receive all multicast ethernet destination addresses */
+#ifndef PCAPIF_FILTER_GROUP_ADDRESSES
+#define PCAPIF_FILTER_GROUP_ADDRESSES 1
+#endif
+
+/** Set this to 1 to receive all frames (also unicast to other addresses)
+ * In this mode, filtering out our own tx packets from loopback receiving
+ * is done via matching rx against recent tx (memcmp).
+ */
+#ifndef PCAPIF_RECEIVE_PROMISCUOUS
+#define PCAPIF_RECEIVE_PROMISCUOUS    0
+#endif
+
+/* Define those to better describe your network interface.
+   For now, we use 'e0', 'e1', 'e2' and so on */
+#define IFNAME0                       'e'
+#define IFNAME1                       '0'
+
+/** index of the network adapter to use for lwIP */
+#ifndef PACKET_LIB_ADAPTER_NR
+#define PACKET_LIB_ADAPTER_NR         0
+#endif
+
+/** If 1, check link state and report it to lwIP.
+ *  If 0, don't check link state (lwIP link state is always UP).
+ */
+#ifndef PCAPIF_HANDLE_LINKSTATE
+#define PCAPIF_HANDLE_LINKSTATE       1
+#endif
+
+/** If 1, use PBUF_REF for RX (for testing purposes mainly).
+ * For this, LWIP_SUPPORT_CUSTOM_PBUF must be enabled.
+ */
+#ifndef PCAPIF_RX_REF
+#define PCAPIF_RX_REF                 0
+#endif
+
+/** This can be used when netif->state is used for something else in your
+ * application (e.g. when wrapping a class around this interface). Just
+ * make sure this define returns the state pointer set by
+ * pcapif_low_level_init() (e.g. by using an offset or a callback).
+ */
+#ifndef PCAPIF_GET_STATE_PTR
+#define PCAPIF_GET_STATE_PTR(netif)   ((netif)->state)
+#endif
+
+#if PCAPIF_HANDLE_LINKSTATE
+#include "pcapif_helper.h"
+
+/* Define "PHY" delay when "link up" */
+#ifndef PCAPIF_LINKUP_DELAY
+#define PCAPIF_LINKUP_DELAY           0
+#endif
+
+#define PCAPIF_LINKCHECK_INTERVAL_MS 500
+
+/* link state notification macro */
+#if PCAPIF_LINKUP_DELAY
+#define PCAPIF_NOTIFY_LINKSTATE(netif, linkfunc) sys_timeout(PCAPIF_LINKUP_DELAY, (sys_timeout_handler)linkfunc, netif)
+#else /* PHY_LINKUP_DELAY */
+#define PCAPIF_NOTIFY_LINKSTATE(netif, linkfunc) linkfunc(netif)
+#endif /* PHY_LINKUP_DELAY */
+
+#endif /* PCAPIF_HANDLE_LINKSTATE */
+
+/* Define PCAPIF_RX_LOCK_LWIP and PCAPIF_RX_UNLOCK_LWIP if you need to lock the lwIP core
+   before/after pbuf_alloc() or netif->input() are called on RX. */
+#ifndef PCAPIF_RX_LOCK_LWIP
+#define PCAPIF_RX_LOCK_LWIP()
+#endif
+#ifndef PCAPIF_RX_UNLOCK_LWIP
+#define PCAPIF_RX_UNLOCK_LWIP()
+#endif
+
+#define ETH_MIN_FRAME_LEN      60U
+#define ETH_MAX_FRAME_LEN      1518U
+
+#define ADAPTER_NAME_LEN       128
+#define ADAPTER_DESC_LEN       128
+
+#if PCAPIF_RECEIVE_PROMISCUOUS
+#ifndef PCAPIF_LOOPBACKFILTER_NUM_TX_PACKETS
+#define PCAPIF_LOOPBACKFILTER_NUM_TX_PACKETS  128
+#endif
+struct pcapipf_pending_packet {
+  struct pcapipf_pending_packet *next;
+  u16_t len;
+  u8_t data[ETH_MAX_FRAME_LEN];
+};
+#endif /* PCAPIF_RECEIVE_PROMISCUOUS */
+
+/* Packet Adapter informations */
+struct pcapif_private {
+  void            *input_fn_arg;
+  pcap_t          *adapter;
+  char             name[ADAPTER_NAME_LEN];
+  char             description[ADAPTER_DESC_LEN];
+  int              shutdown_called;
+#if PCAPIF_RX_USE_THREAD
+  volatile int     rx_run;
+  volatile int     rx_running;
+#endif /* PCAPIF_RX_USE_THREAD */
+#if PCAPIF_HANDLE_LINKSTATE
+  struct pcapifh_linkstate *link_state;
+  enum pcapifh_link_event last_link_event;
+#endif /* PCAPIF_HANDLE_LINKSTATE */
+#if PCAPIF_RECEIVE_PROMISCUOUS
+  struct pcapipf_pending_packet packets[PCAPIF_LOOPBACKFILTER_NUM_TX_PACKETS];
+  struct pcapipf_pending_packet *tx_packets;
+  struct pcapipf_pending_packet *free_packets;
+#endif /* PCAPIF_RECEIVE_PROMISCUOUS */
+};
+
+#if PCAPIF_RECEIVE_PROMISCUOUS
+static void
+pcapif_init_tx_packets(struct pcapif_private *priv)
+{
+  int i;
+  priv->tx_packets = NULL;
+  priv->free_packets = NULL;
+  for (i = 0; i < PCAPIF_LOOPBACKFILTER_NUM_TX_PACKETS; i++) {
+    struct pcapipf_pending_packet *pack = &priv->packets[i];
+    pack->len = 0;
+    pack->next = priv->free_packets;
+    priv->free_packets = pack;
+  }
+}
+
+static void
+pcapif_add_tx_packet(struct pcapif_private *priv, unsigned char *buf, u16_t tot_len)
+{
+  struct pcapipf_pending_packet *tx;
+  struct pcapipf_pending_packet *pack;
+  SYS_ARCH_DECL_PROTECT(lev);
+
+  /* get a free packet (locked) */
+  SYS_ARCH_PROTECT(lev);
+  pack = priv->free_packets;
+  if ((pack == NULL) && (priv->tx_packets != NULL)) {
+    /* no free packets, reuse the oldest */
+    pack = priv->tx_packets;
+    priv->tx_packets = pack->next;
+  }
+  LWIP_ASSERT("no free packet", pack != NULL);
+  priv->free_packets = pack->next;
+  pack->next = NULL;
+  SYS_ARCH_UNPROTECT(lev);
+
+  /* set up the packet (unlocked) */
+  pack->len = tot_len;
+  memcpy(pack->data, buf, tot_len);
+
+  /* put the packet on the list (locked) */
+  SYS_ARCH_PROTECT(lev);
+  if (priv->tx_packets != NULL) {
+    for (tx = priv->tx_packets; tx->next != NULL; tx = tx->next);
+    LWIP_ASSERT("bug", tx != NULL);
+    tx->next = pack;
+  } else {
+    priv->tx_packets = pack;
+  }
+  SYS_ARCH_UNPROTECT(lev);
+}
+
+static int
+pcapif_compare_packets(struct pcapipf_pending_packet *pack, const void *packet, int packet_len)
+{
+  if (pack->len == packet_len) {
+    if (!memcmp(pack->data, packet, packet_len)) {
+      return 1;
+    }
+  }
+  return 0;
+}
+
+static int
+pcaipf_is_tx_packet(struct netif *netif, const void *packet, int packet_len)
+{
+  struct pcapif_private *priv = (struct pcapif_private*)PCAPIF_GET_STATE_PTR(netif);
+  struct pcapipf_pending_packet *iter, *last;
+  SYS_ARCH_DECL_PROTECT(lev);
+
+  last = priv->tx_packets;
+  if (last == NULL) {
+    /* list is empty */
+    return 0;
+  }
+  /* compare the first packet */
+  if (pcapif_compare_packets(last, packet, packet_len)) {
+    SYS_ARCH_PROTECT(lev);
+    LWIP_ASSERT("list has changed", last == priv->tx_packets);
+    priv->tx_packets = last->next;
+    last->next = priv->free_packets;
+    priv->free_packets = last;
+    last->len = 0;
+    SYS_ARCH_UNPROTECT(lev);
+    return 1;
+  }
+  SYS_ARCH_PROTECT(lev);
+  for (iter = last->next; iter != NULL; last = iter, iter = iter->next) {
+    /* unlock while comparing (this works because we have a clean threading separation
+       of adding and removing items and adding is only done at the end) */
+    SYS_ARCH_UNPROTECT(lev);
+    if (pcapif_compare_packets(iter, packet, packet_len)) {
+      SYS_ARCH_PROTECT(lev);
+      LWIP_ASSERT("last != NULL", last != NULL);
+      last->next = iter->next;
+      iter->next = priv->free_packets;
+      priv->free_packets = iter;
+      last->len = 0;
+      SYS_ARCH_UNPROTECT(lev);
+      return 1;
+    }
+    SYS_ARCH_PROTECT(lev);
+  }
+  SYS_ARCH_UNPROTECT(lev);
+  return 0;
+}
+#else /* PCAPIF_RECEIVE_PROMISCUOUS */
+#define pcapif_init_tx_packets(priv)
+#define pcapif_add_tx_packet(priv, buf, tot_len)
+static int
+pcaipf_is_tx_packet(struct netif *netif, const void *packet, int packet_len)
+{
+  const struct eth_addr *src = (const struct eth_addr *)packet + 1;
+  if (packet_len >= (ETH_HWADDR_LEN * 2)) {
+    /* Don't let feedback packets through (limitation in winpcap?) */
+    if(!memcmp(src, netif->hwaddr, ETH_HWADDR_LEN)) {
+      return 1;
+    }
+  }
+  return 0;
+}
+#endif /* PCAPIF_RECEIVE_PROMISCUOUS */
+
+#if PCAPIF_RX_REF
+struct pcapif_pbuf_custom
+{
+   struct pbuf_custom pc;
+   struct pbuf* p;
+};
+#endif /* PCAPIF_RX_REF */
+
+/* Forward declarations. */
+static void pcapif_input(u_char *user, const struct pcap_pkthdr *pkt_header, const u_char *packet);
+
+#ifdef PACKET_LIB_GET_ADAPTER_NETADDRESS
+/** Get the index of an adapter by its network address
+ *
+ * @param netaddr network address of the adapter (e.g. 192.168.1.0)
+ * @return index of the adapter or negative on error
+ */
+static int
+get_adapter_index_from_addr(struct in_addr *netaddr, char *guid, size_t guid_len)
+{
+   pcap_if_t *alldevs;
+   pcap_if_t *d;
+   char errbuf[PCAP_ERRBUF_SIZE+1];
+   int index = 0;
+
+   memset(guid, 0, guid_len);
+
+   /* Retrieve the interfaces list */
+   if (pcap_findalldevs(&alldevs, errbuf) == -1) {
+      printf("Error in pcap_findalldevs: %s\n", errbuf);
+      return -1;
+   }
+   /* Scan the list printing every entry */
+   for (d = alldevs; d != NULL; d = d->next, index++) {
+      pcap_addr_t *a;
+      for(a = d->addresses; a != NULL; a = a->next) {
+         if (a->addr->sa_family == AF_INET) {
+            ULONG a_addr = ((struct sockaddr_in *)a->addr)->sin_addr.s_addr;
+            ULONG a_netmask = ((struct sockaddr_in *)a->netmask)->sin_addr.s_addr;
+            ULONG a_netaddr = a_addr & a_netmask;
+            ULONG addr = (*netaddr).s_addr;
+            if (a_netaddr == addr) {
+               int ret = -1;
+               char name[128];
+               char *start, *end;
+               size_t len = strlen(d->name);
+               if(len > 127) {
+                  len = 127;
+               }
+               MEMCPY(name, d->name, len);
+               name[len] = 0;
+               start = strstr(name, "{");
+               if (start != NULL) {
+                  end = strstr(start, "}");
+                  if (end != NULL) {
+                     size_t len = end - start + 1;
+                     MEMCPY(guid, start, len);
+                     ret = index;
+                  }
+               }
+               pcap_freealldevs(alldevs);
+               return ret;
+            }
+         }
+      }
+   }
+   printf("Network address not found.\n");
+
+   pcap_freealldevs(alldevs);
+   return -1;
+}
+#endif /* PACKET_LIB_GET_ADAPTER_NETADDRESS */
+
+#if defined(PACKET_LIB_GET_ADAPTER_NETADDRESS) || defined(PACKET_LIB_ADAPTER_GUID)
+/** Get the index of an adapter by its GUID
+ *
+ * @param adapter_guid GUID of the adapter
+ * @return index of the adapter or negative on error
+ */
+static int
+get_adapter_index(const char* adapter_guid)
+{
+  pcap_if_t *alldevs;
+  pcap_if_t *d;
+  char errbuf[PCAP_ERRBUF_SIZE+1];
+  int idx = 0;
+
+  /* Retrieve the interfaces list */
+  if (pcap_findalldevs(&alldevs, errbuf) == -1) {
+    printf("Error in pcap_findalldevs: %s\n", errbuf);
+    return -1;
+  }
+  /* Scan the list and compare name vs. adapter_guid */
+  for (d = alldevs; d != NULL; d = d->next, idx++) {
+    if(strstr(d->name, adapter_guid)) {
+      pcap_freealldevs(alldevs);
+      return idx;
+    }
+  }
+  /* not found, dump all adapters */
+  printf("%d available adapters:\n", idx);
+  for (d = alldevs, idx = 0; d != NULL; d = d->next, idx++) {
+    printf("- %d: %s\n", idx, d->name);
+  }
+  pcap_freealldevs(alldevs);
+  return -1;
+}
+#endif /* defined(PACKET_LIB_GET_ADAPTER_NETADDRESS) || defined(PACKET_LIB_ADAPTER_GUID) */
+
+static pcap_t*
+pcapif_open_adapter(const char* adapter_name, char* errbuf)
+{
+  pcap_t* adapter = pcap_open_live(adapter_name,/* name of the device */
+                               65536,             /* portion of the packet to capture */
+                                                  /* 65536 guarantees that the whole packet will be captured on all the link layers */
+                               PCAP_OPENFLAG_PROMISCUOUS,/* promiscuous mode */
+#if PCAPIF_RX_USE_THREAD
+                               /*-*/1,                /* don't wait at all for lower latency */
+#else
+                               1,                /* wait 1 ms in ethernetif_poll */
+#endif
+                               errbuf);           /* error buffer */
+  return adapter;
+}
+
+#if !PCAPIF_RX_USE_THREAD
+static void
+pcap_reopen_adapter(struct pcapif_private *pa)
+{
+  char errbuf[PCAP_ERRBUF_SIZE+1];
+  pcap_if_t *alldevs;
+  if (pa->adapter != NULL) {
+    pcap_close(pa->adapter);
+    pa->adapter = NULL;
+  }
+  if (pcap_findalldevs(&alldevs, errbuf) != -1) {
+    pcap_if_t *d;
+    for (d = alldevs; d != NULL; d = d->next) {
+      if (!strcmp(d->name, pa->name)) {
+        pa->adapter = pcapif_open_adapter(pa->name, errbuf);
+        if (pa->adapter == NULL) {
+          printf("failed to reopen pcap adapter after failure: %s\n", errbuf);
+        }
+        break;
+      }
+    }
+    pcap_freealldevs(alldevs);
+  }
+}
+#endif
+
+/**
+ * Open a network adapter and set it up for packet input
+ *
+ * @param adapter_num the index of the adapter to use
+ * @param arg argument to pass to input
+ * @return an adapter handle on success, NULL on failure
+ */
+static struct pcapif_private*
+pcapif_init_adapter(int adapter_num, void *arg)
+{
+  int i;
+  int number_of_adapters;
+  struct pcapif_private *pa;
+  char errbuf[PCAP_ERRBUF_SIZE+1];
+
+  pcap_if_t *alldevs;
+  pcap_if_t *d;
+  pcap_if_t *used_adapter = NULL;
+
+  pa = (struct pcapif_private *)malloc(sizeof(struct pcapif_private));
+  if (!pa) {
+    printf("Unable to alloc the adapter!\n");
+    return NULL;
+  }
+
+  memset(pa, 0, sizeof(struct pcapif_private));
+  pcapif_init_tx_packets(pa);
+  pa->input_fn_arg = arg;
+
+  /* Retrieve the interfaces list */
+  if (pcap_findalldevs(&alldevs, errbuf) == -1) {
+    free(pa);
+    return NULL; /* no adapters found */
+  }
+  /* get number of adapters and adapter pointer */
+  for (d = alldevs, number_of_adapters = 0; d != NULL; d = d->next, number_of_adapters++) {
+    if (number_of_adapters == adapter_num) {
+      char *desc = d->description;
+      size_t len;
+
+      len = strlen(d->name);
+      LWIP_ASSERT("len < ADAPTER_NAME_LEN", len < ADAPTER_NAME_LEN);
+      strcpy(pa->name, d->name);
+
+      used_adapter = d;
+      /* format vendor description */
+      if (desc != NULL) {
+        len = strlen(desc);
+        if (strstr(desc, " ' on local host") != NULL) {
+          len -= 16;
+        }
+        else if (strstr(desc, "' on local host") != NULL) {
+          len -= 15;
+        }
+        if (strstr(desc, "Network adapter '") == desc) {
+          len -= 17;
+          desc += 17;
+        }
+        len = LWIP_MIN(len, ADAPTER_DESC_LEN-1);
+        while ((desc[len-1] == ' ') || (desc[len-1] == '\t')) {
+          /* don't copy trailing whitespace */
+          len--;
+        }
+        strncpy(pa->description, desc, len);
+        pa->description[len] = 0;
+      } else {
+        strcpy(pa->description, "<no_desc>");
+      }
+    }
+  }
+
+#ifndef PCAPIF_LIB_QUIET
+  /* Scan the list printing every entry */
+  for (d = alldevs, i = 0; d != NULL; d = d->next, i++) {
+    char *desc = d->description;
+    char descBuf[128];
+    size_t len;
+    const char* devname = d->name;
+    if (d->name == NULL) {
+      devname = "<unnamed>";
+    } else {
+      if (strstr(devname, "\\Device\\") == devname) {
+        /* windows: strip the first part */
+        devname += 8;
+      }
+    }
+    printf("%2i: %s\n", i, devname);
+    if (desc != NULL) {
+      /* format vendor description */
+      len = strlen(desc);
+      if (strstr(desc, " ' on local host") != NULL) {
+        len -= 16;
+      }
+      else if (strstr(desc, "' on local host") != NULL) {
+        len -= 15;
+      }
+      if (strstr(desc, "Network adapter '") == desc) {
+        len -= 17;
+        desc += 17;
+      }
+      len = LWIP_MIN(len, 127);
+      while ((desc[len-1] == ' ') || (desc[len-1] == '\t')) {
+        /* don't copy trailing whitespace */
+        len--;
+      }
+      strncpy(descBuf, desc, len);
+      descBuf[len] = 0;
+      printf("     Desc: \"%s\"\n", descBuf);
+    }
+  }
+#endif /* PCAPIF_LIB_QUIET */
+
+  /* invalid adapter index -> check this after printing the adapters */
+  if (adapter_num < 0) {
+    printf("Invalid adapter_num: %d\n", adapter_num);
+    free(pa);
+    pcap_freealldevs(alldevs);
+    return NULL;
+  }
+  /* adapter index out of range */
+  if (adapter_num >= number_of_adapters) {
+    printf("Invalid adapter_num: %d\n", adapter_num);
+    free(pa);
+    pcap_freealldevs(alldevs);
+    return NULL;
+  }
+#ifndef PCAPIF_LIB_QUIET
+  printf("Using adapter_num: %d\n", adapter_num);
+#endif /* PCAPIF_LIB_QUIET */
+  /* set up the selected adapter */
+
+  LWIP_ASSERT("used_adapter != NULL", used_adapter != NULL);
+
+  /* Open the device */
+  pa->adapter = pcapif_open_adapter(used_adapter->name, errbuf);
+  if (pa->adapter == NULL) {
+    printf("\nUnable to open the adapter. %s is not supported by pcap (\"%s\").\n", used_adapter->name, errbuf);
+    /* Free the device list */
+    pcap_freealldevs(alldevs);
+    free(pa);
+    return NULL;
+  }
+  printf("Using adapter: \"%s\"\n", pa->description);
+  pcap_freealldevs(alldevs);
+
+#if PCAPIF_HANDLE_LINKSTATE
+  pa->link_state = pcapifh_linkstate_init(pa->name);
+  pa->last_link_event = PCAPIF_LINKEVENT_UNKNOWN;
+#endif /* PCAPIF_HANDLE_LINKSTATE */
+
+  return pa;
+}
+
+#if PCAPIF_HANDLE_LINKSTATE
+static void
+pcapif_check_linkstate(void *netif_ptr)
+{
+  struct netif *netif = (struct netif*)netif_ptr;
+  struct pcapif_private *pa = (struct pcapif_private*)PCAPIF_GET_STATE_PTR(netif);
+  enum pcapifh_link_event le;
+
+  le = pcapifh_linkstate_get(pa->link_state);
+
+  if (pa->last_link_event != le) {
+    pa->last_link_event = le;
+    switch (le) {
+      case PCAPIF_LINKEVENT_UP: {
+        PCAPIF_NOTIFY_LINKSTATE(netif, netif_set_link_up);
+        break;
+      }
+      case PCAPIF_LINKEVENT_DOWN: {
+        PCAPIF_NOTIFY_LINKSTATE(netif, netif_set_link_down);
+        break;
+      }
+      case PCAPIF_LINKEVENT_UNKNOWN: /* fall through */
+      default:
+        break;
+    }
+  }
+  sys_timeout(PCAPIF_LINKCHECK_INTERVAL_MS, pcapif_check_linkstate, netif);
+}
+#endif /* PCAPIF_HANDLE_LINKSTATE */
+
+
+/**
+ * Close the adapter (no more packets can be sent or received)
+ *
+ * @param netif netif to shutdown
+ */
+void
+pcapif_shutdown(struct netif *netif)
+{
+  struct pcapif_private *pa = (struct pcapif_private*)PCAPIF_GET_STATE_PTR(netif);
+  if (pa) {
+#if PCAPIF_RX_USE_THREAD
+    pa->rx_run = 0;
+#endif /* PCAPIF_RX_USE_THREAD */
+    if (pa->adapter) {
+      pcap_breakloop(pa->adapter);
+      pcap_close(pa->adapter);
+    }
+#if PCAPIF_RX_USE_THREAD
+    /* wait for rxthread to end */
+    while(pa->rx_running);
+#endif /* PCAPIF_RX_USE_THREAD */
+#if PCAPIF_HANDLE_LINKSTATE
+    pcapifh_linkstate_close(pa->link_state);
+#endif /* PCAPIF_HANDLE_LINKSTATE */
+    free(pa);
+  }
+}
+
+#if PCAPIF_RX_USE_THREAD
+/** RX running in its own thread */
+static void
+pcapif_input_thread(void *arg)
+{
+  struct netif *netif = (struct netif *)arg;
+  struct pcapif_private *pa = (struct pcapif_private*)PCAPIF_GET_STATE_PTR(netif);
+  do
+  {
+    struct pcap_pkthdr pkt_header;
+    const u_char *packet = pcap_next(pa->adapter, &pkt_header);
+    if(packet != NULL) {
+      pcapif_input((u_char*)pa, &pkt_header, packet);
+    }
+  } while (pa->rx_run);
+  pa->rx_running = 0;
+}
+#endif /* PCAPIF_RX_USE_THREAD */
+
+/** Low-level initialization: find the correct adapter and initialize it.
+ */
+static void
+pcapif_low_level_init(struct netif *netif)
+{
+  u8_t my_mac_addr[ETH_HWADDR_LEN] = LWIP_MAC_ADDR_BASE;
+  int adapter_num = PACKET_LIB_ADAPTER_NR;
+  struct pcapif_private *pa;
+#ifdef PACKET_LIB_GET_ADAPTER_NETADDRESS
+  ip4_addr_t netaddr;
+#define GUID_LEN 128
+  char guid[GUID_LEN + 1];
+#endif /* PACKET_LIB_GET_ADAPTER_NETADDRESS */
+
+  /* If 'state' is != NULL at this point, we assume it is an 'int' giving
+     the index of the adapter to use (+ 1 because 0==NULL is invalid).
+     This can be used to instantiate multiple PCAP drivers. */
+  if (netif->state != NULL) {
+    adapter_num = (LWIP_PTR_NUMERIC_CAST(int, netif->state)) - 1;
+    if (adapter_num < 0) {
+      printf("ERROR: invalid adapter index \"%d\"!\n", adapter_num);
+      LWIP_ASSERT("ERROR initializing network adapter!\n", 0);
+      return;
+    }
+  }
+
+#ifdef PACKET_LIB_GET_ADAPTER_NETADDRESS
+  memset(&guid, 0, sizeof(guid));
+  PACKET_LIB_GET_ADAPTER_NETADDRESS(&netaddr);
+  if (get_adapter_index_from_addr((struct in_addr *)&netaddr, guid, GUID_LEN) < 0) {
+     printf("ERROR initializing network adapter, failed to get GUID for network address %s\n", ip4addr_ntoa(&netaddr));
+     LWIP_ASSERT("ERROR initializing network adapter, failed to get GUID for network address!", 0);
+     return;
+  }
+  adapter_num = get_adapter_index(guid);
+  if (adapter_num < 0) {
+     printf("ERROR finding network adapter with GUID \"%s\"!\n", guid);
+     LWIP_ASSERT("ERROR finding network adapter with expected GUID!", 0);
+     return;
+  }
+
+#else /* PACKET_LIB_GET_ADAPTER_NETADDRESS */
+#ifdef PACKET_LIB_ADAPTER_GUID
+  /* get adapter index for guid string */
+  adapter_num = get_adapter_index(PACKET_LIB_ADAPTER_GUID);
+  if (adapter_num < 0) {
+    printf("ERROR finding network adapter with GUID \"%s\"!\n", PACKET_LIB_ADAPTER_GUID);
+    LWIP_ASSERT("ERROR initializing network adapter!\n", 0);
+    return;
+  }
+#endif /* PACKET_LIB_ADAPTER_GUID */
+#endif /* PACKET_LIB_GET_ADAPTER_NETADDRESS */
+
+  /* Do whatever else is needed to initialize interface. */
+  pa = pcapif_init_adapter(adapter_num, netif);
+  if (pa == NULL) {
+    printf("ERROR initializing network adapter %d!\n", adapter_num);
+    LWIP_ASSERT("ERROR initializing network adapter!", 0);
+    return;
+  }
+  netif->state = pa;
+
+  /* change the MAC address to a unique value
+     so that multiple ethernetifs are supported */
+  /* @todo: this does NOT support multiple processes using this adapter! */
+  my_mac_addr[ETH_HWADDR_LEN - 1] += netif->num;
+  /* Copy MAC addr */
+  SMEMCPY(&netif->hwaddr, my_mac_addr, ETH_HWADDR_LEN);
+
+  /* get the initial link state of the selected interface */
+#if PCAPIF_HANDLE_LINKSTATE
+  pa->last_link_event = pcapifh_linkstate_get(pa->link_state);
+  if (pa->last_link_event == PCAPIF_LINKEVENT_DOWN) {
+    netif_set_link_down(netif);
+  } else {
+    netif_set_link_up(netif);
+  }
+  sys_timeout(PCAPIF_LINKCHECK_INTERVAL_MS, pcapif_check_linkstate, netif);
+#else /* PCAPIF_HANDLE_LINKSTATE */
+  /* just set the link up so that lwIP can transmit */
+  netif_set_link_up(netif);
+#endif /* PCAPIF_HANDLE_LINKSTATE */
+
+#if PCAPIF_RX_USE_THREAD
+  pa->rx_run = 1;
+  pa->rx_running = 1;
+  sys_thread_new("pcapif_rxthread", pcapif_input_thread, netif, 0, 0);
+#endif
+
+  LWIP_DEBUGF(NETIF_DEBUG, ("pcapif: eth_addr %02X%02X%02X%02X%02X%02X\n",netif->hwaddr[0],netif->hwaddr[1],netif->hwaddr[2],netif->hwaddr[3],netif->hwaddr[4],netif->hwaddr[5]));
+}
+
+/** low_level_output():
+ * Transmit a packet. The packet is contained in the pbuf that is passed to
+ * the function. This pbuf might be chained.
+ */
+static err_t
+pcapif_low_level_output(struct netif *netif, struct pbuf *p)
+{
+  struct pbuf *q;
+  unsigned char buffer[ETH_MAX_FRAME_LEN + ETH_PAD_SIZE];
+  unsigned char *buf = buffer;
+  unsigned char *ptr;
+  struct eth_hdr *ethhdr;
+  u16_t tot_len = p->tot_len - ETH_PAD_SIZE;
+  struct pcapif_private *pa = (struct pcapif_private*)PCAPIF_GET_STATE_PTR(netif);
+
+#if defined(LWIP_DEBUG) && LWIP_NETIF_TX_SINGLE_PBUF && !(LWIP_IPV4 && IP_FRAG) && (LWIP_IPV6 && LWIP_IPV6_FRAG)
+  LWIP_ASSERT("p->next == NULL && p->len == p->tot_len", p->next == NULL && p->len == p->tot_len);
+#endif
+
+  /* initiate transfer */
+  if ((p->len == p->tot_len) && (p->len >= ETH_MIN_FRAME_LEN + ETH_PAD_SIZE)) {
+    /* no pbuf chain, don't have to copy -> faster */
+    buf = &((unsigned char*)p->payload)[ETH_PAD_SIZE];
+  } else {
+    /* pbuf chain, copy into contiguous buffer */
+    if (p->tot_len >= sizeof(buffer)) {
+      LINK_STATS_INC(link.lenerr);
+      LINK_STATS_INC(link.drop);
+      MIB2_STATS_NETIF_INC(netif, ifoutdiscards);
+      return ERR_BUF;
+    }
+    ptr = buffer;
+    for(q = p; q != NULL; q = q->next) {
+      /* Send the data from the pbuf to the interface, one pbuf at a
+         time. The size of the data in each pbuf is kept in the ->len
+         variable. */
+      /* send data from(q->payload, q->len); */
+      LWIP_DEBUGF(NETIF_DEBUG, ("netif: send ptr %p q->payload %p q->len %i q->next %p\n", ptr, q->payload, (int)q->len, (void*)q->next));
+      if (q == p) {
+        MEMCPY(ptr, &((char*)q->payload)[ETH_PAD_SIZE], q->len - ETH_PAD_SIZE);
+        ptr += q->len - ETH_PAD_SIZE;
+      } else {
+        MEMCPY(ptr, q->payload, q->len);
+        ptr += q->len;
+      }
+    }
+  }
+
+  if (tot_len < ETH_MIN_FRAME_LEN) {
+    /* ensure minimal frame length */
+    memset(&buf[tot_len], 0, ETH_MIN_FRAME_LEN - tot_len);
+    tot_len = ETH_MIN_FRAME_LEN;
+  }
+
+  /* signal that packet should be sent */
+  if (pcap_sendpacket(pa->adapter, buf, tot_len) < 0) {
+    LINK_STATS_INC(link.memerr);
+    LINK_STATS_INC(link.drop);
+    MIB2_STATS_NETIF_INC(netif, ifoutdiscards);
+    return ERR_BUF;
+  }
+  if (netif_is_link_up(netif)) {
+    pcapif_add_tx_packet(pa, buf, tot_len);
+  }
+
+  LINK_STATS_INC(link.xmit);
+  MIB2_STATS_NETIF_ADD(netif, ifoutoctets, tot_len);
+  ethhdr = (struct eth_hdr *)p->payload;
+  if ((ethhdr->dest.addr[0] & 1) != 0) {
+    /* broadcast or multicast packet*/
+    MIB2_STATS_NETIF_INC(netif, ifoutnucastpkts);
+  } else {
+    /* unicast packet */
+    MIB2_STATS_NETIF_INC(netif, ifoutucastpkts);
+  }
+  return ERR_OK;
+}
+
+/** low_level_input(): Allocate a pbuf and transfer the bytes of the incoming
+ * packet from the interface into the pbuf.
+ */
+static struct pbuf *
+pcapif_low_level_input(struct netif *netif, const void *packet, int packet_len)
+{
+  struct pbuf *p, *q;
+  int start;
+  int length = packet_len;
+  const struct eth_addr *dest = (const struct eth_addr*)packet;
+  int unicast;
+#if PCAPIF_FILTER_GROUP_ADDRESSES && !PCAPIF_RECEIVE_PROMISCUOUS
+  const u8_t bcast[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
+  const u8_t ipv4mcast[] = {0x01, 0x00, 0x5e};
+  const u8_t ipv6mcast[] = {0x33, 0x33};
+#endif /* PCAPIF_FILTER_GROUP_ADDRESSES && !PCAPIF_RECEIVE_PROMISCUOUS */
+
+  if (pcaipf_is_tx_packet(netif, packet, packet_len)) {
+    /* don't update counters here! */
+    return NULL;
+  }
+
+  unicast = ((dest->addr[0] & 0x01) == 0);
+#if !PCAPIF_RECEIVE_PROMISCUOUS
+  /* MAC filter: only let my MAC or non-unicast through (pcap receives loopback traffic, too) */
+  if (memcmp(dest, &netif->hwaddr, ETH_HWADDR_LEN) &&
+#if PCAPIF_FILTER_GROUP_ADDRESSES
+    (memcmp(dest, ipv4mcast, 3) || ((dest->addr[3] & 0x80) != 0)) && 
+    memcmp(dest, ipv6mcast, 2) &&
+    memcmp(dest, bcast, 6)
+#else /* PCAPIF_FILTER_GROUP_ADDRESSES */
+     unicast
+#endif /* PCAPIF_FILTER_GROUP_ADDRESSES */
+    ) {
+    /* don't update counters here! */
+    return NULL;
+  }
+#endif /* !PCAPIF_RECEIVE_PROMISCUOUS */
+
+  /* We allocate a pbuf chain of pbufs from the pool. */
+  p = pbuf_alloc(PBUF_RAW, (u16_t)length + ETH_PAD_SIZE, PBUF_POOL);
+  LWIP_DEBUGF(NETIF_DEBUG, ("netif: recv length %i p->tot_len %i\n", length, (int)p->tot_len));
+
+  if (p != NULL) {
+    /* We iterate over the pbuf chain until we have read the entire
+       packet into the pbuf. */
+    start = 0;
+    for (q = p; q != NULL; q = q->next) {
+      u16_t copy_len = q->len;
+      /* Read enough bytes to fill this pbuf in the chain. The
+         available data in the pbuf is given by the q->len
+         variable. */
+      /* read data into(q->payload, q->len); */
+      LWIP_DEBUGF(NETIF_DEBUG, ("netif: recv start %i length %i q->payload %p q->len %i q->next %p\n", start, length, q->payload, (int)q->len, (void*)q->next));
+      if (q == p) {
+#if ETH_PAD_SIZE
+        LWIP_ASSERT("q->len >= ETH_PAD_SIZE", q->len >= ETH_PAD_SIZE);
+        copy_len -= ETH_PAD_SIZE;
+#endif /* ETH_PAD_SIZE*/
+        MEMCPY(&((char*)q->payload)[ETH_PAD_SIZE], &((const char*)packet)[start], copy_len);
+      } else {
+        MEMCPY(q->payload, &((const char*)packet)[start], copy_len);
+      }
+      start += copy_len;
+      length -= copy_len;
+      if (length <= 0) {
+        break;
+      }
+    }
+    LINK_STATS_INC(link.recv);
+    MIB2_STATS_NETIF_ADD(netif, ifinoctets, p->tot_len - ETH_PAD_SIZE);
+    if (unicast) {
+      MIB2_STATS_NETIF_INC(netif, ifinucastpkts);
+    } else {
+      MIB2_STATS_NETIF_INC(netif, ifinnucastpkts);
+    }
+  } else {
+    /* drop packet */
+    LINK_STATS_INC(link.memerr);
+    LINK_STATS_INC(link.drop);
+    MIB2_STATS_NETIF_INC(netif, ifindiscards);
+  }
+
+  return p;
+}
+
+#if PCAPIF_RX_REF
+static void
+pcapif_rx_pbuf_free_custom(struct pbuf *p)
+{
+  struct pcapif_pbuf_custom* ppc;
+  LWIP_ASSERT("NULL pointer", p != NULL);
+  ppc = (struct pcapif_pbuf_custom*)p;
+  LWIP_ASSERT("NULL pointer", ppc->p != NULL);
+  pbuf_free(ppc->p);
+  ppc->p = NULL;
+  mem_free(p);
+}
+
+static struct pbuf*
+pcapif_rx_ref(struct pbuf* p)
+{
+  struct pcapif_pbuf_custom* ppc;
+  struct pbuf* q;
+
+  LWIP_ASSERT("NULL pointer", p != NULL);
+  LWIP_ASSERT("chained pbuf not supported here", p->next == NULL);
+
+  ppc = (struct pcapif_pbuf_custom*)mem_malloc(sizeof(struct pcapif_pbuf_custom));
+  LWIP_ASSERT("out of memory for RX", ppc != NULL);
+  ppc->pc.custom_free_function = pcapif_rx_pbuf_free_custom;
+  ppc->p = p;
+
+  q = pbuf_alloced_custom(PBUF_RAW, p->tot_len, PBUF_REF, &ppc->pc, p->payload, p->tot_len);
+  LWIP_ASSERT("pbuf_alloced_custom returned NULL", q != NULL);
+  return q;
+}
+#endif /* PCAPIF_RX_REF */
+
+/** pcapif_input: This function is called when a packet is ready to be read
+ * from the interface. It uses the function low_level_input() that should
+ * handle the actual reception of bytes from the network interface.
+ */
+static void
+pcapif_input(u_char *user, const struct pcap_pkthdr *pkt_header, const u_char *packet)
+{
+  struct pcapif_private *pa = (struct pcapif_private*)user;
+  int packet_len = pkt_header->caplen;
+  struct netif *netif = (struct netif *)pa->input_fn_arg;
+  struct pbuf *p;
+
+  PCAPIF_RX_LOCK_LWIP();
+
+  /* move received packet into a new pbuf */
+  p = pcapif_low_level_input(netif, packet, packet_len);
+  /* if no packet could be read, silently ignore this */
+  if (p != NULL) {
+#if PCAPIF_RX_REF
+    p = pcapif_rx_ref(p);
+#endif
+    /* pass all packets to ethernet_input, which decides what packets it supports */
+    if (netif->input(p, netif) != ERR_OK) {
+      LWIP_DEBUGF(NETIF_DEBUG, ("ethernetif_input: IP input error\n"));
+      pbuf_free(p);
+    }
+  }
+  PCAPIF_RX_UNLOCK_LWIP();
+}
+
+/**
+ * pcapif_init(): initialization function, pass to netif_add().
+ */
+err_t
+pcapif_init(struct netif *netif)
+{
+  static int ethernetif_index;
+
+  int local_index;
+  SYS_ARCH_DECL_PROTECT(lev);
+  SYS_ARCH_PROTECT(lev);
+  local_index = ethernetif_index++;
+  SYS_ARCH_UNPROTECT(lev);
+
+  LWIP_ASSERT("pcapif needs an input callback", netif->input != NULL);
+
+  netif->name[0] = IFNAME0;
+  netif->name[1] = (char)(IFNAME1 + local_index);
+  netif->linkoutput = pcapif_low_level_output;
+#if LWIP_IPV4
+#if LWIP_ARP
+  netif->output = etharp_output;
+#else /* LWIP_ARP */
+  netif->output = NULL; /* not used for PPPoE */
+#endif /* LWIP_ARP */
+#endif /* LWIP_IPV4 */
+#if LWIP_IPV6
+  netif->output_ip6 = ethip6_output;
+#endif /* LWIP_IPV6 */
+#if LWIP_NETIF_HOSTNAME
+  /* Initialize interface hostname */
+  netif_set_hostname(netif, "lwip");
+#endif /* LWIP_NETIF_HOSTNAME */
+
+  netif->mtu = 1500;
+  netif->flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP | NETIF_FLAG_ETHERNET | NETIF_FLAG_IGMP;
+#if LWIP_IPV6 && LWIP_IPV6_MLD
+  netif->flags |= NETIF_FLAG_MLD6;
+#endif /* LWIP_IPV6 && LWIP_IPV6_MLD */
+  netif->hwaddr_len = ETH_HWADDR_LEN;
+
+  NETIF_INIT_SNMP(netif, snmp_ifType_ethernet_csmacd, 100000000);
+
+  /* sets link up or down based on current status */
+  pcapif_low_level_init(netif);
+
+  return ERR_OK;
+}
+
+#if !PCAPIF_RX_USE_THREAD
+void
+pcapif_poll(struct netif *netif)
+{
+  struct pcapif_private *pa = (struct pcapif_private*)PCAPIF_GET_STATE_PTR(netif);
+
+  int ret;
+  do {
+    if (pa->adapter != NULL) {
+      ret = pcap_dispatch(pa->adapter, -1, pcapif_input, (u_char*)pa);
+    } else {
+      ret = -1;
+    }
+    if (ret < 0) {
+      /* error (e.g. adapter removed or resume from standby), try to reopen the adapter */
+      pcap_reopen_adapter(pa);
+    }
+  } while (ret > 0);
+
+}
+#endif /* !PCAPIF_RX_USE_THREAD */
+
+#endif /* LWIP_ETHERNET */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/ports/win32/pcapif.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/ports/win32/pcapif.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/ports/win32/pcapif.h	(revision 457)
@@ -0,0 +1,32 @@
+#ifndef LWIP_PCAPIF_H
+#define LWIP_PCAPIF_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "lwip/err.h"
+
+/** Set to 1 to let rx use an own thread (only for NO_SYS==0).
+ * If set to 0, ethernetif_poll is used to poll for packets.
+ */
+#ifndef PCAPIF_RX_USE_THREAD
+#define PCAPIF_RX_USE_THREAD !NO_SYS
+#endif
+#if PCAPIF_RX_USE_THREAD && NO_SYS
+#error "Can't create a dedicated RX thread with NO_SYS==1"
+#endif
+
+struct netif;
+
+err_t pcapif_init    (struct netif *netif);
+void  pcapif_shutdown(struct netif *netif);
+#if !PCAPIF_RX_USE_THREAD
+void  pcapif_poll    (struct netif *netif);
+#endif /* !PCAPIF_RX_USE_THREAD */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LWIP_PCAPIF_H */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/ports/win32/pcapif_helper.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/ports/win32/pcapif_helper.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/ports/win32/pcapif_helper.c	(revision 457)
@@ -0,0 +1,105 @@
+/**
+ * pcapif_helper.c - This file is part of lwIP pcapif and provides helper functions
+ * for managing the link state.
+ */
+
+#include "pcapif_helper.h"
+
+#include <stdlib.h>
+#include <stdio.h>
+
+#include "lwip/arch.h"
+
+#ifdef WIN32
+
+#define WIN32_LEAN_AND_MEAN
+
+#ifdef _MSC_VER
+#pragma warning( push, 3 )
+#endif
+#include <windows.h>
+#include <packet32.h>
+#include <ntddndis.h>
+#ifdef _MSC_VER
+#pragma warning ( pop )
+#endif
+
+struct pcapifh_linkstate {
+  LPADAPTER        lpAdapter;
+  PPACKET_OID_DATA ppacket_oid_data;
+};
+
+struct pcapifh_linkstate* pcapifh_linkstate_init(char *adapter_name)
+{
+  struct pcapifh_linkstate* state = (struct pcapifh_linkstate*)malloc(sizeof(struct pcapifh_linkstate));
+  if (state != NULL) {
+    memset(state, 0, sizeof(struct pcapifh_linkstate));
+    state->ppacket_oid_data = (PPACKET_OID_DATA)malloc(sizeof(PACKET_OID_DATA) + sizeof(NDIS_MEDIA_STATE));
+    if (state->ppacket_oid_data == NULL) {
+      free(state);
+      state = NULL;
+    } else {
+      state->lpAdapter = PacketOpenAdapter((char*)adapter_name);
+      if ((state->lpAdapter == NULL) || (state->lpAdapter->hFile == INVALID_HANDLE_VALUE)) {
+        /* failed to open adapter */
+        free(state);
+        state = NULL;
+      }
+    }
+  }
+  return state;
+}
+
+enum pcapifh_link_event pcapifh_linkstate_get(struct pcapifh_linkstate* state)
+{
+  enum pcapifh_link_event ret = PCAPIF_LINKEVENT_UNKNOWN;
+  if (state != NULL) {
+    state->ppacket_oid_data->Oid    = OID_GEN_MEDIA_CONNECT_STATUS;
+    state->ppacket_oid_data->Length = sizeof(NDIS_MEDIA_STATE);
+    if (PacketRequest(state->lpAdapter, FALSE, state->ppacket_oid_data)) {
+      NDIS_MEDIA_STATE fNdisMediaState;
+      fNdisMediaState = (*((PNDIS_MEDIA_STATE)(state->ppacket_oid_data->Data)));
+      ret = ((fNdisMediaState == NdisMediaStateConnected) ? PCAPIF_LINKEVENT_UP : PCAPIF_LINKEVENT_DOWN);
+    }
+  }
+  return ret;
+}
+
+void pcapifh_linkstate_close(struct pcapifh_linkstate* state)
+{
+  if (state != NULL) {
+    if (state->lpAdapter != NULL) {
+      PacketCloseAdapter(state->lpAdapter);
+    }
+    if (state->ppacket_oid_data != NULL) {
+      free(state->ppacket_oid_data);
+    }
+    free(state);
+  }
+}
+
+#else /* WIN32 */
+
+/* @todo: add linux/unix implementation? */
+
+struct pcapifh_linkstate {
+  u8_t empty;
+};
+
+struct pcapifh_linkstate* pcapifh_linkstate_init(char *adapter_name)
+{
+  LWIP_UNUSED_ARG(adapter_name);
+  return NULL;
+}
+
+enum pcapifh_link_event pcapifh_linkstate_get(struct pcapifh_linkstate* state)
+{
+  LWIP_UNUSED_ARG(state);
+  return PCAPIF_LINKEVENT_UP;
+}
+void pcapifh_linkstate_close(struct pcapifh_linkstate* state)
+{
+  LWIP_UNUSED_ARG(state);
+}
+
+#endif /* WIN32 */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/ports/win32/pcapif_helper.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/ports/win32/pcapif_helper.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/ports/win32/pcapif_helper.h	(revision 457)
@@ -0,0 +1,25 @@
+#ifndef LWIP_PCAPIF_HELPER_H
+#define LWIP_PCAPIF_HELPER_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct pcapifh_linkstate;
+
+enum pcapifh_link_event {
+  PCAPIF_LINKEVENT_UNKNOWN,
+  PCAPIF_LINKEVENT_UP,
+  PCAPIF_LINKEVENT_DOWN
+};
+
+struct pcapifh_linkstate* pcapifh_linkstate_init(char *adapter_name);
+enum pcapifh_link_event pcapifh_linkstate_get(struct pcapifh_linkstate* state);
+void pcapifh_linkstate_close(struct pcapifh_linkstate* state);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LWIP_PCAPIF_HELPER_H */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/ports/win32/readme.txt
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/ports/win32/readme.txt	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/ports/win32/readme.txt	(revision 457)
@@ -0,0 +1,26 @@
+lwIP for Win32
+
+This is an example port of lwIP for Win32. It uses WinPCAP to send & receive packets.
+To compile it, use the MSVC projects in the 'msvc' subdir or the Makefile in the 'mingw' subdir.
+
+For both compilers:
+- the lwIP core repository must be in a folder "lwip" next to the "contrib" folder
+- you have to set an environment variable PCAP_DIR pointing to the WinPcap Developer's
+  Pack (containing 'include' and 'lib')
+  alternatively, place the WinPcap Developer's pack next to the "lwip" and "contrib" folders:
+  "winpcap\WpdPack"
+
+You also will have to copy the file 'lwipcfg_msvc.h.example' to
+'lwipcfg_msvc.h' and modify to suit your needs (WinPcap adapter number,
+IP configuration, applications...).
+
+Included in the contrib\ports\win32 directory is the network interface driver
+using the winpcap library.
+
+lwIP: http://savannah.nongnu.org/projects/lwip/
+WinPCap: https://www.winpcap.org/devel.htm
+Visual C++: http://www.microsoft.com/express/download/
+
+To compile the unittests (msvc\lwIP_unittests.sln), download check (tested with v0.11.0) from
+https://github.com/libcheck/check/releases/
+and place it in a folder "check" next to the "contrib" folder.
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/ports/win32/sio.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/ports/win32/sio.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/ports/win32/sio.c	(revision 457)
@@ -0,0 +1,304 @@
+/*
+ * Copyright (c) 2001-2003 Swedish Institute of Computer Science.
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission. 
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ * 
+ */
+
+#include <lwip/opt.h>
+#include <lwip/sys.h>
+#include <lwip/sio.h>
+
+#include <stdio.h>
+#include <stdarg.h>
+
+#ifdef _MSC_VER
+#pragma warning (push, 3)
+#endif
+#include <windows.h>
+#ifdef _MSC_VER
+#pragma warning (pop)
+#endif
+#include "lwipcfg.h"
+
+/** When 1, use COM ports, when 0, use named pipes (for simulation). */
+#ifndef SIO_USE_COMPORT
+#define SIO_USE_COMPORT 1
+#endif
+
+/** If SIO_USE_COMPORT==1, use COMx, if 0, use a pipe (default) */
+#if SIO_USE_COMPORT
+#define SIO_DEVICENAME "\\\\.\\COM"
+#else
+#define SIO_DEVICENAME "\\\\.\\pipe\\lwip"
+#endif
+
+#if SIO_USE_COMPORT
+#ifndef SIO_COMPORT_SPEED
+#define SIO_COMPORT_SPEED 115200
+#endif
+#ifndef SIO_COMPORT_BYTESIZE
+#define SIO_COMPORT_BYTESIZE 8
+#endif
+#ifndef SIO_COMPORT_STOPBITS
+#define SIO_COMPORT_STOPBITS 0 /* ONESTOPBIT */
+#endif
+#ifndef SIO_COMPORT_PARITY
+#define SIO_COMPORT_PARITY 0 /* NOPARITY */
+#endif
+#endif /* SIO_USE_COMPORT */
+
+static int sio_abort = 0;
+
+/* \\.\pipe\lwip0 */
+/* pppd /dev/ttyS0 logfile mylog debug nocrtscts local noauth noccp ms-dns 212.27.54.252 192.168.0.4:192.168.0.5
+ */
+
+/**
+ * SIO_DEBUG: Enable debugging for SIO.
+ */
+#ifndef SIO_DEBUG
+#define SIO_DEBUG    LWIP_DBG_OFF
+#endif
+
+#if SIO_USE_COMPORT
+/** When using a real COM port, set up the
+ * serial line settings (baudrate etc.)
+ */
+static BOOL
+sio_setup(HANDLE fd)
+{
+  COMMTIMEOUTS cto;
+  DCB dcb;
+
+  /* set up baudrate and other communication settings */
+  memset(&dcb, 0, sizeof(dcb));
+  /* Obtain the DCB structure for the device */
+  if (!GetCommState(fd, &dcb)) {
+    return FALSE;
+  }
+  /* Set the new data */
+  dcb.BaudRate = SIO_COMPORT_SPEED;
+  dcb.ByteSize = SIO_COMPORT_BYTESIZE;
+  dcb.StopBits = 0; /* ONESTOPBIT */
+  dcb.Parity   = 0; /* NOPARITY */
+  dcb.fParity  = 0; /* parity is not used */
+  /* do not use flow control */
+  /*dcb.fOutxDsrFlow = dcb.fDtrControl = 0;
+  dcb.fOutxCtsFlow = dcb.fRtsControl = 0;
+  dcb.fErrorChar = dcb.fNull = 0;
+  dcb.fInX = dcb.fOutX = 0;
+  dcb.XonChar = dcb.XoffChar = 0;
+  dcb.XonLim = dcb.XoffLim = 100;*/
+
+  /* Set the new DCB structure */
+  if (!SetCommState(fd, &dcb)) {
+    return FALSE;
+  }
+
+  memset(&cto, 0, sizeof(cto));
+  if(!GetCommTimeouts(fd, &cto))
+  {
+    return FALSE;
+  }
+  /* change read timeout, leave write timeout as it is */
+  cto.ReadIntervalTimeout = 1;
+  cto.ReadTotalTimeoutMultiplier = 0;
+  cto.ReadTotalTimeoutConstant = 1; /* 1 ms */
+  if(!SetCommTimeouts(fd, &cto)) {
+    return FALSE;
+  }
+
+  return TRUE;
+}
+#endif /* SIO_USE_COMPORT */
+
+/**
+ * Opens a serial device for communication.
+ * 
+ * @param devnum device number
+ * @return handle to serial device if successful, NULL otherwise
+ */
+sio_fd_t sio_open(u8_t devnum)
+{
+  HANDLE fileHandle = INVALID_HANDLE_VALUE;
+  CHAR   fileName[256];
+  LWIP_DEBUGF(SIO_DEBUG, ("sio_open(%lu)\n", (DWORD)devnum));
+#if SIO_USE_COMPORT
+  snprintf(fileName, 255, SIO_DEVICENAME"%lu", (DWORD)(devnum));
+#else /* SIO_USE_COMPORT */
+  snprintf(fileName, 255, SIO_DEVICENAME"%lu", (DWORD)(devnum & ~1));
+  if ((devnum & 1) == 0) {
+    fileHandle = CreateNamedPipeA(fileName, PIPE_ACCESS_DUPLEX, PIPE_TYPE_BYTE | PIPE_NOWAIT,
+      PIPE_UNLIMITED_INSTANCES, 102400, 102400, 100, NULL);
+  } else
+#endif /* SIO_USE_COMPORT */
+  {
+    fileHandle = CreateFileA(fileName, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
+  }
+  if (fileHandle != INVALID_HANDLE_VALUE) {
+    sio_abort = 0;
+#if !SIO_USE_COMPORT
+    if (devnum & 1) {
+      DWORD mode = PIPE_NOWAIT;
+      if (!SetNamedPipeHandleState(fileHandle, &mode, NULL, NULL)) {
+        LWIP_DEBUGF(SIO_DEBUG, ("sio_open(%lu): SetNamedPipeHandleState failed. GetLastError() returns %d\n",
+                  (DWORD)devnum, GetLastError()));
+      }
+    } else
+#endif /* !SIO_USE_COMPORT */
+    {
+      FlushFileBuffers(fileHandle);
+    }
+#if SIO_USE_COMPORT
+    if(!sio_setup(fileHandle)) {
+      CloseHandle(fileHandle);
+      LWIP_DEBUGF(SIO_DEBUG, ("sio_open(%lu): sio_setup failed. GetLastError() returns %lu\n",
+                  (DWORD)devnum, GetLastError()));
+      return NULL;
+    }
+#endif /* SIO_USE_COMPORT */
+    LWIP_DEBUGF(SIO_DEBUG, ("sio_open: file \"%s\" successfully opened.\n", fileName));
+    printf("sio_open: file \"%s\" (%d) successfully opened: 0x%08x\n", fileName, devnum, LWIP_PTR_NUMERIC_CAST(unsigned int, fileHandle));
+    return (sio_fd_t)(fileHandle);
+  }
+  LWIP_DEBUGF(SIO_DEBUG, ("sio_open(%lu) failed. GetLastError() returns %lu\n",
+              (DWORD)devnum, GetLastError()));
+  printf("sio_open(%lu) failed. GetLastError() returns %lu\n",
+              (DWORD)devnum, GetLastError());
+  return NULL;
+}
+
+/**
+ * Sends a single character to the serial device.
+ * 
+ * @param c character to send
+ * @param fd serial device handle
+ * 
+ * @note This function will block until the character can be sent.
+ */
+void sio_send(u8_t c, sio_fd_t fd)
+{
+  DWORD dwNbBytesWritten = 0;
+  LWIP_DEBUGF(SIO_DEBUG, ("sio_send(%lu)\n", (DWORD)c));
+  while ((!WriteFile((HANDLE)(fd), &c, 1, &dwNbBytesWritten, NULL)) || (dwNbBytesWritten < 1)) {
+  }
+}
+
+/**
+ * Receives a single character from the serial device.
+ * 
+ * @param fd serial device handle
+ * 
+ * @note This function will block until a character is received.
+ */
+u8_t sio_recv(sio_fd_t fd)
+{
+  DWORD dwNbBytesReadden = 0;
+  u8_t byte = 0;
+  LWIP_DEBUGF(SIO_DEBUG, ("sio_recv()\n"));
+  while ((sio_abort == 0) && ((!ReadFile((HANDLE)(fd), &byte, 1, &dwNbBytesReadden, NULL)) || (dwNbBytesReadden < 1)));
+  LWIP_DEBUGF(SIO_DEBUG, ("sio_recv()=%lu\n", (DWORD)byte));
+  return byte;
+}
+
+/**
+ * Reads from the serial device.
+ * 
+ * @param fd serial device handle
+ * @param data pointer to data buffer for receiving
+ * @param len maximum length (in bytes) of data to receive
+ * @return number of bytes actually received - may be 0 if aborted by sio_read_abort
+ * 
+ * @note This function will block until data can be received. The blocking
+ * can be cancelled by calling sio_read_abort().
+ */
+u32_t sio_read(sio_fd_t fd, u8_t* data, u32_t len)
+{
+  BOOL ret;
+  DWORD dwNbBytesReadden = 0;
+  LWIP_DEBUGF(SIO_DEBUG, ("sio_read()...\n"));
+  ret = ReadFile((HANDLE)(fd), data, len, &dwNbBytesReadden, NULL);
+  LWIP_DEBUGF(SIO_DEBUG, ("sio_read()=%lu bytes -> %d\n", dwNbBytesReadden, ret));
+  LWIP_UNUSED_ARG(ret);
+  return dwNbBytesReadden;
+}
+
+/**
+ * Tries to read from the serial device. Same as sio_read but returns
+ * immediately if no data is available and never blocks.
+ * 
+ * @param fd serial device handle
+ * @param data pointer to data buffer for receiving
+ * @param len maximum length (in bytes) of data to receive
+ * @return number of bytes actually received
+ */
+u32_t sio_tryread(sio_fd_t fd, u8_t* data, u32_t len)
+{
+  /* @todo: implement non-blocking read */
+  BOOL ret;
+  DWORD dwNbBytesReadden = 0;
+  LWIP_DEBUGF(SIO_DEBUG, ("sio_read()...\n"));
+  ret = ReadFile((HANDLE)(fd), data, len, &dwNbBytesReadden, NULL);
+  LWIP_DEBUGF(SIO_DEBUG, ("sio_read()=%lu bytes -> %d\n", dwNbBytesReadden, ret));
+  LWIP_UNUSED_ARG(ret);
+  return dwNbBytesReadden;
+}
+
+/**
+ * Writes to the serial device.
+ * 
+ * @param fd serial device handle
+ * @param data pointer to data to send
+ * @param len length (in bytes) of data to send
+ * @return number of bytes actually sent
+ * 
+ * @note This function will block until all data can be sent.
+ */
+u32_t sio_write(sio_fd_t fd, u8_t* data, u32_t len)
+{
+  BOOL ret;
+  DWORD dwNbBytesWritten = 0;
+  LWIP_DEBUGF(SIO_DEBUG, ("sio_write()...\n"));
+  ret = WriteFile((HANDLE)(fd), data, len, &dwNbBytesWritten, NULL);
+  LWIP_DEBUGF(SIO_DEBUG, ("sio_write()=%lu bytes -> %d\n", dwNbBytesWritten, ret));
+  LWIP_UNUSED_ARG(ret);
+  return dwNbBytesWritten;
+}
+
+/**
+ * Aborts a blocking sio_read() call.
+ * @todo: This currently ignores fd and aborts all reads
+ * 
+ * @param fd serial device handle
+ */
+void sio_read_abort(sio_fd_t fd)
+{
+  LWIP_UNUSED_ARG(fd);
+  LWIP_DEBUGF(SIO_DEBUG, ("sio_read_abort() !!!!!...\n"));
+  sio_abort = 1;
+  return;
+}
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/ports/win32/sys_arch.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/ports/win32/sys_arch.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/ports/win32/sys_arch.c	(revision 457)
@@ -0,0 +1,772 @@
+/*
+ * Copyright (c) 2001-2003 Swedish Institute of Computer Science.
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission. 
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ * 
+ * Author: Adam Dunkels <adam@sics.se>
+ *         Simon Goldschmidt
+ *
+ */
+
+#include <stdlib.h>
+#include <stdio.h> /* sprintf() for task names */
+
+#ifdef _MSC_VER
+#pragma warning (push, 3)
+#endif
+#include <windows.h>
+#ifdef _MSC_VER
+#pragma warning (pop)
+#endif
+#include <time.h>
+
+#include <lwip/opt.h>
+#include <lwip/arch.h>
+#include <lwip/stats.h>
+#include <lwip/debug.h>
+#include <lwip/sys.h>
+#include <lwip/tcpip.h>
+
+/** Set this to 1 to enable assertion checks that SYS_ARCH_PROTECT() is only
+ * called once in a call stack (calling it nested might cause trouble in some
+ * implementations, so let's avoid this in core code as long as we can).
+ */
+#ifndef LWIP_SYS_ARCH_CHECK_NESTED_PROTECT
+#define LWIP_SYS_ARCH_CHECK_NESTED_PROTECT 1
+#endif
+
+/** Set this to 1 to enable assertion checks that SYS_ARCH_PROTECT() is *not*
+ * called before functions potentiolly involving the OS scheduler.
+ *
+ * This scheme is currently broken only for non-core-locking when waking up
+ * threads waiting on a socket via select/poll.
+ */
+#ifndef LWIP_SYS_ARCH_CHECK_SCHEDULING_UNPROTECTED
+#define LWIP_SYS_ARCH_CHECK_SCHEDULING_UNPROTECTED LWIP_TCPIP_CORE_LOCKING
+#endif
+
+#define LWIP_WIN32_SYS_ARCH_ENABLE_PROTECT_COUNTER (LWIP_SYS_ARCH_CHECK_NESTED_PROTECT || LWIP_SYS_ARCH_CHECK_SCHEDULING_UNPROTECTED)
+
+/* These functions are used from NO_SYS also, for precise timer triggering */
+static LARGE_INTEGER freq, sys_start_time;
+#define SYS_INITIALIZED() (freq.QuadPart != 0)
+
+static DWORD netconn_sem_tls_index;
+
+static HCRYPTPROV hcrypt;
+
+u32_t
+sys_win_rand(void)
+{
+  u32_t ret;
+  if (CryptGenRandom(hcrypt, sizeof(ret), (BYTE*)&ret)) {
+    return ret;
+  }
+  LWIP_ASSERT("CryptGenRandom failed", 0);
+  return 0;
+}
+
+static void
+sys_win_rand_init(void)
+{
+  if (!CryptAcquireContext(&hcrypt, NULL, NULL, PROV_RSA_FULL, 0)) {
+    DWORD err = GetLastError();
+    LWIP_PLATFORM_DIAG(("CryptAcquireContext failed with error %d, trying to create NEWKEYSET", (int)err));
+    if(!CryptAcquireContext(&hcrypt, NULL, NULL, PROV_RSA_FULL, CRYPT_NEWKEYSET)) {
+      char errbuf[128];
+      err = GetLastError();
+      snprintf(errbuf, sizeof(errbuf), "CryptAcquireContext failed with error %d", (int)err);
+      LWIP_UNUSED_ARG(err);
+      LWIP_ASSERT(errbuf, 0);
+    }
+  }
+}
+
+static void
+sys_init_timing(void)
+{
+  QueryPerformanceFrequency(&freq);
+  QueryPerformanceCounter(&sys_start_time);
+}
+
+static LONGLONG
+sys_get_ms_longlong(void)
+{
+  LONGLONG ret;
+  LARGE_INTEGER now;
+#if NO_SYS
+  if (!SYS_INITIALIZED()) {
+    sys_init();
+    LWIP_ASSERT("initialization failed", SYS_INITIALIZED());
+  }
+#endif /* NO_SYS */
+  QueryPerformanceCounter(&now);
+  ret = now.QuadPart-sys_start_time.QuadPart;
+  return (u32_t)(((ret)*1000)/freq.QuadPart);
+}
+
+u32_t
+sys_jiffies(void)
+{
+  return (u32_t)sys_get_ms_longlong();
+}
+
+u32_t
+sys_now(void)
+{
+  return (u32_t)sys_get_ms_longlong();
+}
+
+CRITICAL_SECTION critSec;
+#if LWIP_WIN32_SYS_ARCH_ENABLE_PROTECT_COUNTER
+static int protection_depth;
+#endif
+
+static void
+InitSysArchProtect(void)
+{
+  InitializeCriticalSection(&critSec);
+}
+
+sys_prot_t
+sys_arch_protect(void)
+{
+#if NO_SYS
+  if (!SYS_INITIALIZED()) {
+    sys_init();
+    LWIP_ASSERT("initialization failed", SYS_INITIALIZED());
+  }
+#endif
+  EnterCriticalSection(&critSec);
+#if LWIP_SYS_ARCH_CHECK_NESTED_PROTECT
+  LWIP_ASSERT("nested SYS_ARCH_PROTECT", protection_depth == 0);
+#endif
+#if LWIP_WIN32_SYS_ARCH_ENABLE_PROTECT_COUNTER
+  protection_depth++;
+#endif
+  return 0;
+}
+
+void
+sys_arch_unprotect(sys_prot_t pval)
+{
+  LWIP_UNUSED_ARG(pval);
+#if LWIP_SYS_ARCH_CHECK_NESTED_PROTECT
+  LWIP_ASSERT("missing SYS_ARCH_PROTECT", protection_depth == 1);
+#else
+  LWIP_ASSERT("missing SYS_ARCH_PROTECT", protection_depth > 0);
+#endif
+#if LWIP_WIN32_SYS_ARCH_ENABLE_PROTECT_COUNTER
+  protection_depth--;
+#endif
+  LeaveCriticalSection(&critSec);
+}
+
+#if LWIP_SYS_ARCH_CHECK_SCHEDULING_UNPROTECTED
+/** This checks that SYS_ARCH_PROTECT() hasn't been called by protecting
+ * and then checking the level
+ */
+static void
+sys_arch_check_not_protected(void)
+{
+  sys_arch_protect();
+  LWIP_ASSERT("SYS_ARCH_PROTECT before scheduling", protection_depth == 1);
+  sys_arch_unprotect(0);
+}
+#else
+#define sys_arch_check_not_protected()
+#endif
+
+static void
+msvc_sys_init(void)
+{
+  sys_win_rand_init();
+  sys_init_timing();
+  InitSysArchProtect();
+  netconn_sem_tls_index = TlsAlloc();
+  LWIP_ASSERT("TlsAlloc failed", netconn_sem_tls_index != TLS_OUT_OF_INDEXES);
+}
+
+void
+sys_init(void)
+{
+  msvc_sys_init();
+}
+
+#if !NO_SYS
+
+struct threadlist {
+  lwip_thread_fn function;
+  void *arg;
+  DWORD id;
+  struct threadlist *next;
+};
+
+static struct threadlist *lwip_win32_threads = NULL;
+
+err_t
+sys_sem_new(sys_sem_t *sem, u8_t count)
+{
+  HANDLE new_sem = NULL;
+
+  LWIP_ASSERT("sem != NULL", sem != NULL);
+
+  new_sem = CreateSemaphore(0, count, 100000, 0);
+  LWIP_ASSERT("Error creating semaphore", new_sem != NULL);
+  if(new_sem != NULL) {
+    if (SYS_INITIALIZED()) {
+      SYS_ARCH_LOCKED(SYS_STATS_INC_USED(sem));
+    } else {
+      SYS_STATS_INC_USED(sem);
+    }
+#if LWIP_STATS && SYS_STATS
+    LWIP_ASSERT("sys_sem_new() counter overflow", lwip_stats.sys.sem.used != 0);
+#endif /* LWIP_STATS && SYS_STATS*/
+    sem->sem = new_sem;
+    return ERR_OK;
+  }
+   
+  /* failed to allocate memory... */
+  if (SYS_INITIALIZED()) {
+    SYS_ARCH_LOCKED(SYS_STATS_INC(sem.err));
+  } else {
+    SYS_STATS_INC(sem.err);
+  }
+  sem->sem = NULL;
+  return ERR_MEM;
+}
+
+void
+sys_sem_free(sys_sem_t *sem)
+{
+  /* parameter check */
+  LWIP_ASSERT("sem != NULL", sem != NULL);
+  LWIP_ASSERT("sem->sem != NULL", sem->sem != NULL);
+  LWIP_ASSERT("sem->sem != INVALID_HANDLE_VALUE", sem->sem != INVALID_HANDLE_VALUE);
+  CloseHandle(sem->sem);
+
+  SYS_ARCH_LOCKED(SYS_STATS_DEC(sem.used));
+#if LWIP_STATS && SYS_STATS
+  LWIP_ASSERT("sys_sem_free() closed more than created", lwip_stats.sys.sem.used != (u16_t)-1);
+#endif /* LWIP_STATS && SYS_STATS */
+  sem->sem = NULL;
+}
+
+u32_t
+sys_arch_sem_wait(sys_sem_t *sem, u32_t timeout)
+{
+  DWORD ret;
+  LONGLONG starttime, endtime;
+  LWIP_ASSERT("sem != NULL", sem != NULL);
+  LWIP_ASSERT("sem->sem != NULL", sem->sem != NULL);
+  LWIP_ASSERT("sem->sem != INVALID_HANDLE_VALUE", sem->sem != INVALID_HANDLE_VALUE);
+  if (!timeout) {
+    /* wait infinite */
+    starttime = sys_get_ms_longlong();
+    ret = WaitForSingleObject(sem->sem, INFINITE);
+    LWIP_ASSERT("Error waiting for semaphore", ret == WAIT_OBJECT_0);
+    endtime = sys_get_ms_longlong();
+    /* return the time we waited for the sem */
+    return (u32_t)(endtime - starttime);
+  } else {
+    starttime = sys_get_ms_longlong();
+    ret = WaitForSingleObject(sem->sem, timeout);
+    LWIP_ASSERT("Error waiting for semaphore", (ret == WAIT_OBJECT_0) || (ret == WAIT_TIMEOUT));
+    if (ret == WAIT_OBJECT_0) {
+      endtime = sys_get_ms_longlong();
+      /* return the time we waited for the sem */
+      return (u32_t)(endtime - starttime);
+    } else {
+      /* timeout */
+      return SYS_ARCH_TIMEOUT;
+    }
+  }
+}
+
+void
+sys_sem_signal(sys_sem_t *sem)
+{
+  BOOL ret;
+  sys_arch_check_not_protected();
+  LWIP_ASSERT("sem != NULL", sem != NULL);
+  LWIP_ASSERT("sem->sem != NULL", sem->sem != NULL);
+  LWIP_ASSERT("sem->sem != INVALID_HANDLE_VALUE", sem->sem != INVALID_HANDLE_VALUE);
+  ret = ReleaseSemaphore(sem->sem, 1, NULL);
+  LWIP_ASSERT("Error releasing semaphore", ret != 0);
+  LWIP_UNUSED_ARG(ret);
+}
+
+err_t
+sys_mutex_new(sys_mutex_t *mutex)
+{
+  HANDLE new_mut = NULL;
+
+  LWIP_ASSERT("mutex != NULL", mutex != NULL);
+
+  new_mut = CreateMutex(NULL, FALSE, NULL);
+  LWIP_ASSERT("Error creating mutex", new_mut != NULL);
+  if (new_mut != NULL) {
+    SYS_ARCH_LOCKED(SYS_STATS_INC_USED(mutex));
+#if LWIP_STATS && SYS_STATS
+    LWIP_ASSERT("sys_mutex_new() counter overflow", lwip_stats.sys.mutex.used != 0);
+#endif /* LWIP_STATS && SYS_STATS*/
+    mutex->mut = new_mut;
+    return ERR_OK;
+  }
+   
+  /* failed to allocate memory... */
+  SYS_ARCH_LOCKED(SYS_STATS_INC(mutex.err));
+  mutex->mut = NULL;
+  return ERR_MEM;
+}
+
+void
+sys_mutex_free(sys_mutex_t *mutex)
+{
+  /* parameter check */
+  LWIP_ASSERT("mutex != NULL", mutex != NULL);
+  LWIP_ASSERT("mutex->mut != NULL", mutex->mut != NULL);
+  LWIP_ASSERT("mutex->mut != INVALID_HANDLE_VALUE", mutex->mut != INVALID_HANDLE_VALUE);
+  CloseHandle(mutex->mut);
+
+  SYS_ARCH_LOCKED(SYS_STATS_DEC(mutex.used));
+#if LWIP_STATS && SYS_STATS
+  LWIP_ASSERT("sys_mutex_free() closed more than created", lwip_stats.sys.mutex.used != (u16_t)-1);
+#endif /* LWIP_STATS && SYS_STATS */
+  mutex->mut = NULL;
+}
+
+void sys_mutex_lock(sys_mutex_t *mutex)
+{
+  DWORD ret;
+  LWIP_ASSERT("mutex != NULL", mutex != NULL);
+  LWIP_ASSERT("mutex->mut != NULL", mutex->mut != NULL);
+  LWIP_ASSERT("mutex->mut != INVALID_HANDLE_VALUE", mutex->mut != INVALID_HANDLE_VALUE);
+  /* wait infinite */
+  ret = WaitForSingleObject(mutex->mut, INFINITE);
+  LWIP_ASSERT("Error waiting for mutex", ret == WAIT_OBJECT_0);
+  LWIP_UNUSED_ARG(ret);
+}
+
+void
+sys_mutex_unlock(sys_mutex_t *mutex)
+{
+  sys_arch_check_not_protected();
+  LWIP_ASSERT("mutex != NULL", mutex != NULL);
+  LWIP_ASSERT("mutex->mut != NULL", mutex->mut != NULL);
+  LWIP_ASSERT("mutex->mut != INVALID_HANDLE_VALUE", mutex->mut != INVALID_HANDLE_VALUE);
+  /* wait infinite */
+  if (!ReleaseMutex(mutex->mut)) {
+    LWIP_ASSERT("Error releasing mutex", 0);
+  }
+}
+
+
+#ifdef _MSC_VER
+const DWORD MS_VC_EXCEPTION=0x406D1388;
+#pragma pack(push,8)
+typedef struct tagTHREADNAME_INFO
+{
+  DWORD dwType; /* Must be 0x1000. */
+  LPCSTR szName; /* Pointer to name (in user addr space). */
+  DWORD dwThreadID; /* Thread ID (-1=caller thread). */
+  DWORD dwFlags; /* Reserved for future use, must be zero. */
+} THREADNAME_INFO;
+#pragma pack(pop)
+
+static void
+SetThreadName(DWORD dwThreadID, const char* threadName)
+{
+  THREADNAME_INFO info;
+  info.dwType = 0x1000;
+  info.szName = threadName;
+  info.dwThreadID = dwThreadID;
+  info.dwFlags = 0;
+
+  __try {
+    RaiseException(MS_VC_EXCEPTION, 0, sizeof(info)/sizeof(ULONG_PTR), (ULONG_PTR*)&info);
+  }
+  __except(EXCEPTION_EXECUTE_HANDLER) {
+  }
+}
+#else /* _MSC_VER */
+static void
+SetThreadName(DWORD dwThreadID, const char* threadName)
+{
+  LWIP_UNUSED_ARG(dwThreadID);
+  LWIP_UNUSED_ARG(threadName);
+}
+#endif /* _MSC_VER */
+
+static void
+sys_thread_function(void* arg)
+{
+  struct threadlist* t = (struct threadlist*)arg;
+#if LWIP_NETCONN_SEM_PER_THREAD
+  sys_arch_netconn_sem_alloc();
+#endif
+  t->function(t->arg);
+#if LWIP_NETCONN_SEM_PER_THREAD
+  sys_arch_netconn_sem_free();
+#endif
+}
+
+sys_thread_t
+sys_thread_new(const char *name, lwip_thread_fn function, void *arg, int stacksize, int prio)
+{
+  struct threadlist *new_thread;
+  HANDLE h;
+  SYS_ARCH_DECL_PROTECT(lev);
+
+  LWIP_UNUSED_ARG(name);
+  LWIP_UNUSED_ARG(stacksize);
+  LWIP_UNUSED_ARG(prio);
+
+  new_thread = (struct threadlist*)malloc(sizeof(struct threadlist));
+  LWIP_ASSERT("new_thread != NULL", new_thread != NULL);
+  if (new_thread != NULL) {
+    new_thread->function = function;
+    new_thread->arg = arg;
+    SYS_ARCH_PROTECT(lev);
+    new_thread->next = lwip_win32_threads;
+    lwip_win32_threads = new_thread;
+
+    h = CreateThread(0, 0, (LPTHREAD_START_ROUTINE)sys_thread_function, new_thread, 0, &(new_thread->id));
+    LWIP_ASSERT("h != 0", h != 0);
+    LWIP_ASSERT("h != -1", h != INVALID_HANDLE_VALUE);
+    LWIP_UNUSED_ARG(h);
+    SetThreadName(new_thread->id, name);
+
+    SYS_ARCH_UNPROTECT(lev);
+    return new_thread->id;
+  }
+  return 0;
+}
+
+#if !NO_SYS
+#if LWIP_TCPIP_CORE_LOCKING
+
+static DWORD lwip_core_lock_holder_thread_id;
+
+void
+sys_lock_tcpip_core(void)
+{
+  sys_mutex_lock(&lock_tcpip_core);
+  lwip_core_lock_holder_thread_id = GetCurrentThreadId();
+}
+
+void
+sys_unlock_tcpip_core(void)
+{
+  lwip_core_lock_holder_thread_id = 0;
+  sys_mutex_unlock(&lock_tcpip_core);
+}
+#endif /* LWIP_TCPIP_CORE_LOCKING */
+
+static DWORD lwip_tcpip_thread_id;
+
+void
+sys_mark_tcpip_thread(void)
+{
+  lwip_tcpip_thread_id = GetCurrentThreadId();
+}
+
+void
+sys_check_core_locking(void)
+{
+  /* Embedded systems should check we are NOT in an interrupt context here */
+
+  if (lwip_tcpip_thread_id != 0) {
+    DWORD current_thread_id = GetCurrentThreadId();
+
+#if LWIP_TCPIP_CORE_LOCKING
+    LWIP_ASSERT("Function called without core lock", current_thread_id == lwip_core_lock_holder_thread_id);
+#else /* LWIP_TCPIP_CORE_LOCKING */
+    LWIP_ASSERT("Function called from wrong thread", current_thread_id == lwip_tcpip_thread_id);
+#endif /* LWIP_TCPIP_CORE_LOCKING */
+    LWIP_UNUSED_ARG(current_thread_id); /* for LWIP_NOASSERT */
+  }
+}
+#endif /* !NO_SYS */
+
+err_t
+sys_mbox_new(sys_mbox_t *mbox, int size)
+{
+  LWIP_ASSERT("mbox != NULL", mbox != NULL);
+  LWIP_UNUSED_ARG(size);
+
+  mbox->sem = CreateSemaphore(0, 0, MAX_QUEUE_ENTRIES, 0);
+  LWIP_ASSERT("Error creating semaphore", mbox->sem != NULL);
+  if (mbox->sem == NULL) {
+    SYS_ARCH_LOCKED(SYS_STATS_INC(mbox.err));
+    return ERR_MEM;
+  }
+  memset(&mbox->q_mem, 0, sizeof(u32_t)*MAX_QUEUE_ENTRIES);
+  mbox->head = 0;
+  mbox->tail = 0;
+  SYS_ARCH_LOCKED(SYS_STATS_INC_USED(mbox));
+#if LWIP_STATS && SYS_STATS
+  LWIP_ASSERT("sys_mbox_new() counter overflow", lwip_stats.sys.mbox.used != 0);
+#endif /* LWIP_STATS && SYS_STATS */
+  return ERR_OK;
+}
+
+void
+sys_mbox_free(sys_mbox_t *mbox)
+{
+  /* parameter check */
+  LWIP_ASSERT("mbox != NULL", mbox != NULL);
+  LWIP_ASSERT("mbox->sem != NULL", mbox->sem != NULL);
+  LWIP_ASSERT("mbox->sem != INVALID_HANDLE_VALUE", mbox->sem != INVALID_HANDLE_VALUE);
+
+  CloseHandle(mbox->sem);
+
+  SYS_STATS_DEC(mbox.used);
+#if LWIP_STATS && SYS_STATS
+  LWIP_ASSERT( "sys_mbox_free() ", lwip_stats.sys.mbox.used != (u16_t)-1);
+#endif /* LWIP_STATS && SYS_STATS */
+  mbox->sem = NULL;
+}
+
+void
+sys_mbox_post(sys_mbox_t *q, void *msg)
+{
+  BOOL ret;
+  SYS_ARCH_DECL_PROTECT(lev);
+  sys_arch_check_not_protected();
+
+  /* parameter check */
+  LWIP_ASSERT("q != SYS_MBOX_NULL", q != SYS_MBOX_NULL);
+  LWIP_ASSERT("q->sem != NULL", q->sem != NULL);
+  LWIP_ASSERT("q->sem != INVALID_HANDLE_VALUE", q->sem != INVALID_HANDLE_VALUE);
+
+  SYS_ARCH_PROTECT(lev);
+  q->q_mem[q->head] = msg;
+  q->head++;
+  if (q->head >= MAX_QUEUE_ENTRIES) {
+    q->head = 0;
+  }
+  LWIP_ASSERT("mbox is full!", q->head != q->tail);
+  ret = ReleaseSemaphore(q->sem, 1, 0);
+  LWIP_ASSERT("Error releasing sem", ret != 0);
+  LWIP_UNUSED_ARG(ret);
+
+  SYS_ARCH_UNPROTECT(lev);
+}
+
+err_t
+sys_mbox_trypost(sys_mbox_t *q, void *msg)
+{
+  u32_t new_head;
+  BOOL ret;
+  SYS_ARCH_DECL_PROTECT(lev);
+  sys_arch_check_not_protected();
+
+  /* parameter check */
+  LWIP_ASSERT("q != SYS_MBOX_NULL", q != SYS_MBOX_NULL);
+  LWIP_ASSERT("q->sem != NULL", q->sem != NULL);
+  LWIP_ASSERT("q->sem != INVALID_HANDLE_VALUE", q->sem != INVALID_HANDLE_VALUE);
+
+  SYS_ARCH_PROTECT(lev);
+
+  new_head = q->head + 1;
+  if (new_head >= MAX_QUEUE_ENTRIES) {
+    new_head = 0;
+  }
+  if (new_head == q->tail) {
+    SYS_ARCH_UNPROTECT(lev);
+    return ERR_MEM;
+  }
+
+  q->q_mem[q->head] = msg;
+  q->head = new_head;
+  LWIP_ASSERT("mbox is full!", q->head != q->tail);
+  ret = ReleaseSemaphore(q->sem, 1, 0);
+  LWIP_ASSERT("Error releasing sem", ret != 0);
+  LWIP_UNUSED_ARG(ret);
+
+  SYS_ARCH_UNPROTECT(lev);
+  return ERR_OK;
+}
+
+err_t
+sys_mbox_trypost_fromisr(sys_mbox_t *q, void *msg)
+{
+  return sys_mbox_trypost(q, msg);
+}
+
+u32_t
+sys_arch_mbox_fetch(sys_mbox_t *q, void **msg, u32_t timeout)
+{
+  DWORD ret;
+  LONGLONG starttime, endtime;
+  SYS_ARCH_DECL_PROTECT(lev);
+
+  /* parameter check */
+  LWIP_ASSERT("q != SYS_MBOX_NULL", q != SYS_MBOX_NULL);
+  LWIP_ASSERT("q->sem != NULL", q->sem != NULL);
+  LWIP_ASSERT("q->sem != INVALID_HANDLE_VALUE", q->sem != INVALID_HANDLE_VALUE);
+
+  if (timeout == 0) {
+    timeout = INFINITE;
+  }
+  starttime = sys_get_ms_longlong();
+  ret = WaitForSingleObject(q->sem, timeout);
+  if (ret == WAIT_OBJECT_0) {
+    SYS_ARCH_PROTECT(lev);
+    if (msg != NULL) {
+      *msg  = q->q_mem[q->tail];
+    }
+
+    q->tail++;
+    if (q->tail >= MAX_QUEUE_ENTRIES) {
+      q->tail = 0;
+    }
+    SYS_ARCH_UNPROTECT(lev);
+    endtime = sys_get_ms_longlong();
+    return (u32_t)(endtime - starttime);
+  } else {
+    LWIP_ASSERT("Error waiting for sem", ret == WAIT_TIMEOUT);
+    if (msg != NULL) {
+      *msg  = NULL;
+    }
+
+    return SYS_ARCH_TIMEOUT;
+  }
+}
+
+u32_t
+sys_arch_mbox_tryfetch(sys_mbox_t *q, void **msg)
+{
+  DWORD ret;
+  SYS_ARCH_DECL_PROTECT(lev);
+
+  /* parameter check */
+  LWIP_ASSERT("q != SYS_MBOX_NULL", q != SYS_MBOX_NULL);
+  LWIP_ASSERT("q->sem != NULL", q->sem != NULL);
+  LWIP_ASSERT("q->sem != INVALID_HANDLE_VALUE", q->sem != INVALID_HANDLE_VALUE);
+
+  ret = WaitForSingleObject(q->sem, 0);
+  if (ret == WAIT_OBJECT_0) {
+    SYS_ARCH_PROTECT(lev);
+    if (msg != NULL) {
+      *msg  = q->q_mem[q->tail];
+    }
+
+    q->tail++;
+    if (q->tail >= MAX_QUEUE_ENTRIES) {
+      q->tail = 0;
+    }
+    SYS_ARCH_UNPROTECT(lev);
+    return 0;
+  } else {
+    LWIP_ASSERT("Error waiting for sem", ret == WAIT_TIMEOUT);
+    if (msg != NULL) {
+      *msg  = NULL;
+    }
+
+    return SYS_ARCH_TIMEOUT;
+  }
+}
+
+#if LWIP_NETCONN_SEM_PER_THREAD
+sys_sem_t*
+sys_arch_netconn_sem_get(void)
+{
+  LPVOID tls_data = TlsGetValue(netconn_sem_tls_index);
+  return (sys_sem_t*)tls_data;
+}
+
+void
+sys_arch_netconn_sem_alloc(void)
+{
+  sys_sem_t *sem;
+  err_t err;
+  BOOL done;
+
+  sem = (sys_sem_t*)malloc(sizeof(sys_sem_t));
+  LWIP_ASSERT("failed to allocate memory for TLS semaphore", sem != NULL);
+  err = sys_sem_new(sem, 0);
+  LWIP_ASSERT("failed to initialise TLS semaphore", err == ERR_OK);
+  done = TlsSetValue(netconn_sem_tls_index, sem);
+  LWIP_UNUSED_ARG(done);
+  LWIP_ASSERT("failed to initialise TLS semaphore storage", done == TRUE);
+}
+
+void
+sys_arch_netconn_sem_free(void)
+{
+  LPVOID tls_data = TlsGetValue(netconn_sem_tls_index);
+  if (tls_data != NULL) {
+    BOOL done;
+    free(tls_data);
+    done = TlsSetValue(netconn_sem_tls_index, NULL);
+    LWIP_UNUSED_ARG(done);
+    LWIP_ASSERT("failed to de-init TLS semaphore storage", done == TRUE);
+  }
+}
+#endif /* LWIP_NETCONN_SEM_PER_THREAD */
+
+#endif /* !NO_SYS */
+
+/* get keyboard state to terminate the debug app on any kbhit event using win32 API */
+int
+lwip_win32_keypressed(void)
+{
+  INPUT_RECORD rec;
+  DWORD num = 0;
+  HANDLE h = GetStdHandle(STD_INPUT_HANDLE);
+  BOOL ret = PeekConsoleInput(h, &rec, 1, &num);
+  if (ret && num) {
+    ReadConsoleInput(h, &rec, 1, &num);
+    if (rec.EventType == KEY_EVENT) {
+      if (rec.Event.KeyEvent.bKeyDown) {
+        /* not a special key? */
+        if (rec.Event.KeyEvent.uChar.AsciiChar != 0) {
+          return 1;
+        }
+      }
+    }
+  }
+  return 0;
+}
+
+#include <stdarg.h>
+
+/* This is an example implementation for LWIP_PLATFORM_DIAG:
+ * format a string and pass it to your output function.
+ */
+void
+lwip_win32_platform_diag(const char *format, ...)
+{
+  va_list ap;
+  /* get the varargs */
+  va_start(ap, format);
+  /* print via varargs; to use another output function, you could use
+     vsnprintf here */
+  vprintf(format, ap);
+  va_end(ap);
+}
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/CHANGELOG
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/CHANGELOG	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/CHANGELOG	(revision 457)
@@ -0,0 +1,4548 @@
+HISTORY
+ * These are only the most important changes. For a full list, use git log:
+   http://git.savannah.nongnu.org/cgit/lwip.git
+
+(git master)
+
+  * [Enter new changes just after this line - do not remove this line]
+
+(STABLE-2.1.2):
+
+  ++ Bugfixes:
+
+  2018-11-21: Jens Nielsen
+  * netbiosns.c: fix expecting too large packet (bug #55069)
+
+  2018-11-19: Dirk Ziegelmeier
+  * smtp.c: fix compiling with strict C compatibility because of strnlen (bug #55034)
+
+  2018-11-12: Simon Goldschmidt
+  * tcp.c: fix overflow check in tcp_recved triggering invalid assertion (bug #55015)
+
+  2018-11-12: Simon Goldschmidt
+  * tcp.c: fix a bug in sending RST segments (sent from port 0)
+
+(STABLE-2.1.1):
+
+  ++ Bugfixes:
+
+  2018-11-01: Joan Lledå¦
+  * sockets.c: fix bad assertion in lwip_poll_dec_sockets_used() (bug #54933)
+
+  2018-11-01: Dirk Ziegelmeier
+  * ip4.c: don't send 127.* to default netif (bug #54670)
+
+  2018-10-23: David Girault
+  * altcp_tls_mbedtls.c: fix use-after free (bug #54774)
+
+  2018-10-23: Ognjen Bjelica, Dirk Ziegelmeier
+  * snmp_scalar.c: Avoid NULL pointer dereference (bug #54886)
+
+  2018-10-23: Simon Goldschmidt
+  * Fix missing standard includes in multiple files
+
+  2018-10-17: Ivan Warren
+  * def.h: fix casting htonX and ntohX to u16_t (bug #54850)
+
+  2018-10-12: Simon Goldschmidt
+  * Revert "tcp_abandon: no need to buffer pcb->local_port" (fix that source port was 0 for RST
+    called when aborting a connection)
+
+  2018-10-11: Jonas Rabenstein
+  * tcp.c: tcp_recved: check for overflow and warn about too big values (patch #9699)              
+
+  2018-10-06: Joan Lledå¦
+  * sockets.c: alloc_socket(): Check for LWIP_SOCKET_POLL when setting select-
+    related variables (patch #9696)
+
+  2018-10-04: Spencer
+  * tcp.c: Update prev pointer when skipping entries in tcp_slowtmr (patch #9694)
+
+  2018-09-27: Martine Lenders
+  * lowpan6.c: Fix IEEE 802.15.4 address setting (bug #54749)
+
+(STABLE-2.1.0):
+
+  ++ New features:
+
+  2018-06-17: Simon Goldschmidt
+  * lwiperf: implemented iPerf client mode
+
+  2018-04-23: Dirk Ziegelmeier
+  * added cmake build files
+
+  2018-03-04: Ray Abram
+  * netbios responder: respond to '*' queries
+
+  2018-02-23: Benjamin Aigner
+  * 6lowpan: add 6lowpan-over-BLE netif (based on existing 6lowpan netif)
+
+  2018-02-22: Simon Goldschmidt
+  * ipv6: add support for stateless DHCPv6 (to get DNS servers in SLAAC nets)
+
+  2018-02-16: Simon Goldschmidt
+  * add raw API http(s) client (with proxy support)
+
+  2018-02-01: Simon Goldschmidt
+  * tcp: add hooks to implement additional socket options
+
+  2018-02-01: Simon Goldschmidt
+  * tcp: add hooks to implement tcp md5 signatures or similar (see contrib/addons for an example)
+
+  2018-01-05: Simon Goldschmidt
+  * Added sys_mbox_trypost_fromisr() and tcpip_callbackmsg_trycallback_fromisr()
+    These can be used to post preallocated messages from an ISR to the tcpip thread
+    (e.g. when using FreeRTOS)
+
+  2018-01-02: Dirk Ziegelmeier
+  * task #14780: Add debug helper asserts to ensure threading/locking requirements are met
+
+  2017-11-21: Simon Goldschmidt
+  * task #14600: tcp_alloc(): kill TF_CLOSEPEND connections before other ESTABLISHED
+
+  2017-11-21: Simon Goldschmidt
+  * makefsdata: added option "-ssi:<filename>" to control SSI tag checking/insertion
+    through a list of filenames, not by checking the file extension at runtime
+
+  2017-11-20: Joel Cunningham
+  * netconn: add LWIP_HOOK_NETCONN_EXTERNAL_RESOLVE to use external DNS resolver (patch #9427)
+
+  2017-11-14: Joel Cunningham
+  * netifapi: Add thread safe ARP cache APIs (task #14724)
+
+  2017-11-06: Axel Lin
+  * TCP: kill existing connections with a LOWER priority than the one currently being opened.
+    Previous implementations also kill existing connections of the SAME priority.
+
+  2017-09-21: Kalle Olavi Niemitalo
+  * sockets: add poll() implementation (patch #9450)
+
+  2017-09-10: Joel Cunningham
+  * sockets: add readv() implementation (task #14610)
+
+  2017-08-04: Simon Goldschmidt
+  * Clean up DHCP a bit: no need keep msg_out and msg_in as members in struct
+    dhcp - they are used in a call stack only (p_out and options_out_len as well)
+
+  2017-08-04: Simon Goldschmidt
+  * pbuf: split pbuf_header(s16_t) into pbuf_add_header(size_t) and
+    pbuf_remove_header(size_t)
+
+  2017-07-20: Douglas
+  * sys: deprecate sys_arch_sem_wait and sys_arch_mbox_fetch returning the
+    time waited rather they are now defined to return != SYS_ARCH_TIMEOUT
+    on success.
+
+  2017-07-03: Jakub Schmidtke
+  * tcp: added support for sending TCP SACKs
+
+  2017-06-20: Joel Cunningham
+  * netconn/netdb: added core locking support to netconn_gethostbyname (task #14523)
+
+  2017-04-25: Simon Goldschmidt
+  * dhcp: added two hooks for adding and parsing user defined DHCP options
+
+  2017-04-25: Joel Cunningham
+  * sockets: added recvmsg for UDP (together with CMSG and IP_PKTINFO) (task #14247)
+
+  2017-04-20: Joel Cunningham
+  * tcp: added Appropriate Byte Counting support (task #14128)
+
+  2017-04-11: Simon Goldschmidt
+  * netconn/sockets: remove fatal error handling, fix asynchronous error handling,
+    ensure data before RST can be received
+
+  2017-03-30: Simon Goldschmidt
+  * added "application layered TCP" connection API (altcp) for seamless integration
+    of TLS or proxy connections
+
+  2017-03-09: Simon Goldschmidt
+  * sockets: add recvmsg for TCP
+
+  2017-03-02: Joel Cunningham
+  * netconn/sockets: vectorize netconn_write for TCP, treating a vectored I/O write
+    atomically in regards to TCP segmentation (patch #8882)
+
+  2017-03-02: Simon Goldschmidt
+  * netconn: added nonblocking accept/recv to netconn API (task #14396)
+
+  2017-02-28: Simon Goldschmidt
+  * Added LWIP_SINGLE_NETIF for small targets with only one netif
+
+  2017-02-10: David van Moolenbroek
+  * Implement UDP and RAW multicast support for IPv6 (core API, not netconn/sockets)
+
+  2017-02-04: David van Moolenbroek
+  * IPv6 scopes support
+
+  2017-01-20: Joel Cunningham
+  * sockets: add interface name/index APIs (task #14314)
+  
+  2017-01-08: David van Moolenbroek
+  * Extensions to RAW API (patch #9208)
+    - Connected RAW PCBs
+    - Add raw_sendto_if_src()
+    - Support IP_HDRINCL socket option
+
+  ++ Bugfixes:
+
+  2018-06-19: Simon Goldschmidt
+  * tcp: fix RTO timer not working if link is down
+
+  2018-06-15: Sylvain Rochet
+  * ppp: multiple smaller bugfixes
+
+  2018-05-17: Simon Goldschmidt
+  * etharp: arp table can now be bigger than 127 entries
+
+  2018-04-25: Jens Nielsen
+  * tftp server: correctly handle retransmissions
+
+  2018-04-18: Simon Goldschmidt
+  sockets: fix race conditions when closing full-duplex sockets
+
+  2018-03-09: Simon Goldschmidt
+  * 6lowpan: fix to work against contiki; added ZigBee encapsulation netif for tests
+
+  2018-02-04: Simon Goldschmidt
+  * sockets: fix inconsistencies on close (inconsistent error codes, double FIN)
+
+  2018-01-05: Dirk Ziegelmeier
+  * Fix bug #52748: the bug in timeouts.c by reimplementing timer logic to use
+    absolute instead of relative timeout values
+
+  2017-12-31: Dirk Ziegelmeier
+  * Fix bug #52704: DHCP and bad OFFER: Stop timeout only if offer is accepted
+
+  2017-11-08: Joel Cunningham
+  * netif: ensure link and admin states are up in issue reports (bug #52353)
+
+  2017-09-12: David Lockyer
+  * select: allocate select_cb from memp for LWIP_MPU_COMPATIBLE = 1 (bug #51990)
+
+  2017-09-11: Simon Goldschmidt
+  * tcp_in.c: fix bug #51937 (leaking tcp_pcbs on passive close with unacked data)
+
+  2017-08-11: Joel Cunningham
+  * lwip_itoa: fix converting the number 0 (previously converted to '\0') (bug #51729)
+
+  2017-08-08: Dirk Ziegelmeier
+  * ip4_route_src: parameter order is reversed: ip4_route_src(dest, src) -> ip4_route_src(src, dest)
+    to make parameter order consistent with other ip*_route*() functions
+    Same also applies to LWIP_HOOK_IP4_ROUTE_SRC() parameter order.
+
+  2017-08-04: Joel Cunningham
+  * tcp: re-work persist timer to fully close window (details in bug #50837)
+
+  2017-07-26: Simon Goldschmidt
+  * snmp_msg.c: fix bug #51578 (SNMP failed to decode some values on non 32bit platforms)
+
+  2017-07-20: Simon Goldschmidt
+  * compatibility headers: moved from 'src/include/posix' to 'src/include/compat/posix',
+    'src/include/compat/stdc' etc.
+
+  2017-05-09: Joel Cunningham
+  * tcp: add zero-window probe timeout (bug #50837)
+
+  2017-04-11: Simon Goldschmidt
+  * sockets.c: task #14420 (Remove sys_sem_signal from inside SYS_ARCH_PROTECT
+    crit section) done for LWIP_TCPIP_CORE_LOCKING==1
+
+  2017-02-24: Simon Goldschmidt
+  * sockets.c: fixed close race conditions in lwip_select (for LWIP_NETCONN_FULLDUPLEX)
+
+  2017-02-24: Simon Goldschmidt
+  * sockets.c: fixed that select ignored invalid/not open sockets in the fd_sets (bug #50392)
+
+  2017-01-11: David van Moolenbroek
+  * Lots of IPv6 related fixes and improvements
+
+(STABLE-2.0.3)
+
+  ++ Bugfixes:
+
+  2017-09-11: Simon Goldschmidt
+  * tcp_in.c: fix bug #51937 (leaking tcp_pcbs on passive close with unacked data)
+
+  2017-08-02: Abroz Bizjak/Simon Goldschmidt
+  * multiple fixes in IPv4 reassembly (leading to corrupted datagrams received)
+  
+  2017-03-30: Simon Goldschmidt
+  * dhcp.c: return ERR_VAL instead of asserting on offset-out-of-pbuf
+
+  2017-03-23: Dirk Ziegelmeier
+  * dhcp.h: fix bug #50618 (dhcp_remove_struct() macro does not work)
+
+(STABLE-2.0.2)
+
+  ++ New features:
+
+  2017-02-10: Dirk Ziegelmeier
+  * Implement task #14367: Hooks need a better place to be defined:
+    We now have a #define for a header file name that is #included in every .c
+    file that provides hooks.
+
+  2017-02-10: Simon Goldschmidt
+  * tcp_close does not fail on memory error (instead, FIN is sent from tcp_tmr)
+
+  ++ Bugfixes:
+
+  2017-03-08
+  * tcp: do not keep sending SYNs when getting ACKs
+
+  2017-03-08: Joel Cunningham
+  * tcp: Initialize ssthresh to TCP_SND_BUF (bug #50476)
+
+  2017-03-01: Simon Goldschmidt
+  * httpd: LWIP_HTTPD_POST_MANUAL_WND: fixed double-free when httpd_post_data_recved
+    is called nested from httpd_post_receive_data() (bug #50424)
+
+  2017-02-28: David van Moolenbroek/Simon Goldschmidt
+  * tcp: fixed bug #50418: LWIP_EVENT_API: fix invalid calbacks for SYN_RCVD pcb
+
+  2017-02-17: Simon Goldschmidt
+  * dns: Improved DNS_LOCAL_HOSTLIST interface (bug #50325)
+
+  2017-02-16: Simon Goldschmidt
+  * LWIP_NETCONN_FULLDUPLEX: fixed shutdown during write (bug #50274)
+
+  2017-02-13: Simon Goldschmidt/Dirk Ziegelmeier
+  * For tiny targtes, LWIP_RAND is optional (fix compile time checks)
+
+  2017-02-10: Simon Goldschmidt
+  * tcp: Fixed bug #47485 (tcp_close() should not fail on memory error) by retrying
+    to send FIN from tcp_fasttmr
+
+  2017-02-09: Simon Goldschmidt
+  * sockets: Fixed bug #44032 (LWIP_NETCONN_FULLDUPLEX: select might work on
+    invalid/reused socket) by not allowing to reallocate a socket that has
+    "select_waiting != 0"
+
+  2017-02-09: Simon Goldschmidt
+  * httpd: Fixed bug #50059 (httpd LWIP_HTTPD_SUPPORT_11_KEEPALIVE vs.
+    LWIP_HTTPD_KILL_OLD_ON_CONNECTIONS_EXCEEDED)
+
+  2017-02-08: Dirk Ziegelmeier
+  * Rename "IPv6 mapped IPv4 addresses" to their correct name from RFC4191:
+    "IPv4-mapped IPv6 address"
+
+  2017-02-08: Luc Revardel
+  * mld6.c: Fix bug #50220 (mld6_leavegroup does not send ICMP6_TYPE_MLD, even
+    if last reporter)
+
+  2017-02-08: David van Moolenbroek
+  * ip6.c: Patch #9250: fix source substitution in ip6_output_if()
+
+  2017-02-08: Simon Goldschmidt
+  * tcp_out.c: Fixed bug #50090 (last_unsent->oversize_left can become wrong value
+    in tcp_write error path)
+
+  2017-02-02: Dirk Ziegelmeier
+  * Fix bug #50206: UDP Netconn bind to IP6_ADDR_ANY fails
+
+  2017-01-18: Dirk Ziegelmeier
+  * Fix zero-copy RX, see bug bug #50064. PBUF_REFs were not supported as ARP requests.
+
+  2017-01-15: Axel Lin, Dirk Ziegelmeier
+  * minor bug fixes in mqtt
+
+  2017-01-11: Knut Andre Tidemann
+  * sockets/netconn: fix broken default ICMPv6 handling of checksums
+
+(STABLE-2.0.1)
+
+  ++ New features:
+
+  2016-12-31: Simon Goldschmidt
+  * tcp.h/.c: added function tcp_listen_with_backlog_and_err() to get the error
+    reason when listening fails (bug #49861)
+
+  2016-12-20: Erik Andersen
+  * Add MQTT client
+
+  2016-12-14: Jan Breuer:
+  * opt.h, ndc.h/.c: add support for RDNSS option (as per RFC 6106)
+
+  2016-12-14: David van Moolenbroek
+  * opt.h, nd6.c: Added LWIP_HOOK_ND6_GET_GW()
+
+  2016-12-09: Dirk Ziegelmeier
+  * ip6_frag.c: Implemented support for LWIP_NETIF_TX_SINGLE_PBUF
+
+  2016-12-09: Simon Goldschmidt
+  * dns.c: added one-shot multicast DNS queries
+
+  2016-11-24: Ambroz Bizjak, David van Moolenbroek
+  * tcp_out.c: Optimize passing contiguous nocopy buffers to tcp_write (bug #46290)
+
+  2016-11-16: Dirk Ziegelmeier
+  * sockets.c: added support for IPv6 mapped IPv4 addresses
+
+  ++ Bugfixes:
+
+  2016-12-16: Thomas Mueller
+  * api_lib.c: fixed race condition in return value of netconn_gethostbyname()
+    (and thus also lwip_gethostbyname/_r() and lwip_getaddrinfo())
+
+  2016-12-15: David van Moolenbroek
+  * opt.h, tcp: added LWIP_HOOK_TCP_ISN() to implement less predictable initial
+    sequence numbers (see contrib/addons/tcp_isn for an example implementation)
+
+  2016-12-05: Dirk Ziegelmeier
+  * fixed compiling with IPv4 disabled (IPv6 only case)
+
+  2016-11-28: Simon Goldschmidt
+  * api_lib.c: fixed bug #49725 (send-timeout: netconn_write() can return
+    ERR_OK without all bytes being written)
+
+  2016-11-28: Ambroz Bizjak
+  * tcpi_in.c: fixed bug #49717 (window size in received SYN and SYN-ACK
+    assumed scaled)
+
+  2016-11-25: Simon Goldschmidt
+  * dhcp.c: fixed bug #49676 (Possible endless loop when parsing dhcp options)
+
+  2016-11-23: Dirk Ziegelmeier
+  * udp.c: fixed bug #49662: multicast traffic is now only received on a UDP PCB
+   (and therefore on a UDP socket/netconn) when the PCB is bound to IP_ADDR_ANY
+
+  2016-11-16: Dirk Ziegelmeier
+  * *: Fixed dual-stack behaviour, IPv6 mapped IPv4 support in socket API
+
+  2016-11-14: Joel Cunningham
+  * tcp_out.c: fixed bug #49533 (start persist timer when unsent seg can't fit
+    in window) 
+
+  2016-11-16: Roberto Barbieri Carrera
+  * autoip.c: fixed bug #49610 (sometimes AutoIP fails to reuse the same address)
+
+  2016-11-11: Dirk Ziegelmeier
+  * sockets.c: fixed bug #49578 (dropping multicast membership does not work
+    with LWIP_SOCKET_OFFSET)
+
+(STABLE-2.0.0)
+
+  ++ New features:
+
+  2016-07-27: Simon Goldschmidt
+  * opt.h, timeouts.h/.c: added LWIP_TIMERS_CUSTOM to override the default
+    implementation of timeouts
+
+  2016-07-xx: Dirk Ziegelmeier
+  * Large overhaul of doxygen documentation
+
+  2016-04-05: Simon Goldschmidt
+  * timers.h/.c: prepare for overriding current timeout implementation: all
+    stack-internal caclic timers are avaliable in the lwip_cyclic_timers array
+
+  2016-03-23: Simon Goldschmidt
+  * tcp: call accept-callback with ERR_MEM when allocating a pcb fails on
+    passive open to inform the application about this error
+    ATTENTION: applications have to handle NULL pcb in accept callback!
+
+  2016-02-22: Ivan Delamer
+  * Initial 6LoWPAN support
+
+  2016-02-XX to 2016-03-XX: Dirk Ziegelmeier
+  * Cleanup TCPIP thread sync methods in a way that it is possibe to use them
+    in arbitrary code that needs things to be done in TCPIP thread. Used to
+    decouple netconn, netif, ppp and 6LoWPAN from LWIP core.
+
+  2016-02-XX: Dirk Ziegelmeier
+  * Implement dual-stack support in RAW, UDP and TCP. Add new IP address
+    type IPADDR_ANY_TYPE for this. Netconn/Socket API: Dual-stack is
+    automatically supported when an IPv6 netconn/socket is created.
+
+  2015-12-26: Martin Hentschel and Dirk Ziegelmeier
+  * Rewrite SNMP agent. SNMPv2c + MIB compiler.
+
+  2015-11-12: Dirk Ziegelmeier
+  * Decouple SNMP stack from lwIP core and move stack to apps/ directory.
+    Breaking change: Users have to call snmp_init() now!
+
+  2015-11-12: Dirk Ziegelmeier
+  * Implement possibility to declare private memory pools. This is useful to
+    decouple some apps from the core (SNMP stack) or make contrib app usage
+    simpler (httpserver_raw)
+
+  2015-10-09: Simon Goldschmidt
+  * started to move "private" header files containing implementation details to
+    "lwip/priv/" include directory to seperate the API from the implementation.
+
+  2015-10-07: Simon Goldschmidt
+  * added sntp client as first "supported" application layer protocol implementation
+    added 'apps' folder
+
+  2015-09-30: Dirk Ziegelmeier
+  * snmp_structs.h, mib_structs.c, mib2.c: snmp: fixed ugly inheritance
+    implementation by aggregating the "base class" (struct mib_node) in all
+    derived node classes to get more type-safe code
+
+  2015-09-23: Simon Goldschmidt
+  * netif.h/.c, nd6.c: task #13729: Convert netif addresses (IPv4 & IPv6) to
+    ip_addr_t (so they can be used without conversion/temporary storage)
+
+  2015-09-08: Dirk Ziegelmeier
+  * snmp: Separate mib2 counter/table callbacks from snmp agent. This both cleans
+    up the code and should allow integration of a 3rd party agent/mib2. Simple
+    counters are kept in MIB2_STATS, tree/table change function prototypes moved to
+    snmp_mib2.h.
+
+  2015-09-03: Simon Goldschmidt
+  * opt.h, dns.h/.c: DNS/IPv6: added support for AAAA records
+
+  2015-09-01: Simon Goldschmidt
+  * task #12178: hardware checksum capabilities can be configured per netif
+   (use NETIF_SET_CHECKSUM_CTRL() in your netif's init function)
+
+  2015-08-30: Simon Goldschmidt
+  * PBUF_REF with "custom" pbufs is now supported for RX pbufs (see pcapif in
+    contrib for an example, LWIP_SUPPORT_CUSTOM_PBUF is required)
+
+  2015-08-30: Simon Goldschmidt
+  * support IPv4 source based routing: define LWIP_HOOK_IP4_ROUTE_SRC to point
+    to a routing function
+
+  2015-08-05: Simon Goldschmidt
+  * many files: allow multicast socket options IP_MULTICAST_TTL, IP_MULTICAST_IF
+    and IP_MULTICAST_LOOP to be used without IGMP
+
+  2015-04-24: Simon Goldschmidt
+  * dhcp.h/c, autoip.h/.c: added functions dhcp/autoip_supplied_address() to
+    check for the source of address assignment (replacement for NETIF_FLAG_DHCP)
+
+  2015-04-10: Simon Goldschmidt
+  * many files: task #13480: added LWIP_IPV4 define - IPv4 can be disabled,
+    leaving an IPv6-only stack
+
+  2015-04-09: Simon Goldschmidt
+  * nearly all files: task #12722 (improve IPv4/v6 address handling): renamed
+    ip_addr_t to ip4_addr_t, renamed ipX_addr_t to ip_addr_t and added IP
+    version; ip_addr_t is used for all generic IP addresses for the API,
+    ip(4/6)_addr_t are only used internally or when initializing netifs or when
+    calling version-related functions
+
+  2015-03-24: Simon Goldschmidt
+  * opt.h, ip4_addr.h, ip4.c, ip6.c: loopif is not required for loopback traffic
+    any more but passed through any netif (ENABLE_LOOPBACK has to be enabled)
+
+  2015-03-23: Simon Goldschmidt
+  * opt.h, etharp.c: with ETHARP_TABLE_MATCH_NETIF== 1, duplicate (Auto)-IP
+    addresses on multiple netifs should now be working correctly (if correctly
+    addressed by routing, that is)
+
+  2015-03-23: Simon Goldschmidt
+  * etharp.c: Stable etharp entries that are about to expire are now refreshed
+    using unicast to prevent unnecessary broadcast. Only if no answer is received
+    after 15 seconds, broadcast is used.
+
+  2015-03-06: Philip Gladstone
+  * netif.h/.c: patch #8359 (Provide utility function to add an IPv6 address to
+    an interface)
+
+  2015-03-05: Simon Goldschmidt
+  * netif.c, ip4.c, dhcp.c, autoip.c: fixed bug #37068 (netif up/down handling
+    is unclear): correclty separated administrative status of a netif (up/down)
+    from 'valid address' status
+    ATTENTION: netif_set_up() now always has to be called, even when dhcp/autoip
+    is used!
+
+  2015-02-26: patch by TabascoEye
+  * netif.c, udp.h/.c: fixed bug #40753 (re-bind UDP pcbs on change of IP address)
+
+  2015-02-22: chrysn, Simon Goldschmidt
+  * *.*: Changed nearly all functions taking 'ip(X)_addr_t' pointer to take
+    const pointers (changed user callbacks: raw_recv_fn, udp_recv_fn; changed
+    port callbacks: netif_output_fn, netif_igmp_mac_filter_fn)
+
+  2015-02-19: Ivan Delamer
+  * netif.h, dhcp.c: Removed unused netif flag for DHCP. The preferred way to evaluate
+    if DHCP is active is through netif->dhcp field.
+
+  2015-02-19: Ivan Delamer
+  * netif.h, slipif.c, ppp.c: Removed unused netif flag for point to point connections
+
+  2015-02-18: Simon Goldschmidt
+  * api_lib.c: fixed bug #37958 "netconn API doesn't handle correctly
+    connections half-closed by peer"
+
+  2015-02-18: Simon Goldschmidt
+  * tcp.c: tcp_alloc() prefers killing CLOSING/LAST_ACK over active connections
+    (see bug #39565)
+
+  2015-02-16: Claudius Zingerli, Sergio Caprile
+  * opt.h, dhcp.h/.c: patch #8361 "Add support for NTP option in DHCP"
+
+  2015-02-14: Simon Goldschmidt
+  * opt.h, snmp*: added support for write-access community and dedicated
+    community for sending traps
+
+  2015-02-13: Simon Goldschmidt
+  * opt.h, memp.c: added hook LWIP_HOOK_MEMP_AVAILABLE() to get informed when
+    a memp pool was empty and an item is now available
+
+  2015-02-13: Simon Goldschmidt
+  * opt.h, pbuf.h/.c, etharp.c: Added the option PBUF_LINK_ENCAPSULATION_HLEN to
+    allocate additional header space for TX on netifs requiring additional headers
+
+  2015-02-12: chrysn
+  * timers.h/.c: introduce sys_timeouts_sleeptime (returns the time left before
+    the next timeout is due, for NO_SYS==1)
+
+  2015-02-11: Nick van Ijzendoorn
+  * opt.h, sockets.h/c: patch #7702 "Include ability to increase the socket number
+    with defined offset"
+
+  2015-02-11: Frederick Baksik
+  * opt.h, def.h, others: patch #8423 "arch/perf.h" should be made an optional item
+
+  2015-02-11: Simon Goldschmidt
+  * api_msg.c, opt.h: started to implement fullduplex sockets/netconns
+    (note that this is highly unstable yet!)
+
+  2015-01-17: Simon Goldschmidt
+  * api: allow enabling socket API without (public) netconn API - netconn API is
+    still used by sockets, but keeping it private (static) should allow better
+    compiler optimizations
+
+  2015-01-16: Simon Goldschmidt
+  * tcp_in.c: fixed bug #20506 "Initial congestion window is very small" again
+    by implementing the calculation formula from RFC3390
+
+  2014-12-10: Simon Goldschmidt
+  * api: added option LWIP_NETCONN_SEM_PER_THREAD to use a semaphore per thread
+    instead of using one per netconn and per select call
+
+  2014-12-08: Simon Goldschmidt
+  * ip6.h: fixed bug #43778: IPv6 header version not set on 16-bit platform
+    (macro IP6H_VTCFL_SET())
+
+  2014-12-08: Simon Goldschmidt
+  * icmp.c, ip4.c, pbuf.c, udp.c, pbuf.h: task #11472 Support PBUF_REF for RX
+    (IPv6 and IPv4/v6 reassembly might not work yet)
+
+  2014-11-06: Simon Goldschmidt
+  * sockets.c/.h, init.c: lwip_socket_init() is not needed any more
+    -> compatibility define
+
+  2014-09-16: Simon Goldschmidt
+  * dns.c, opt.h: reduced ram usage by parsing DNS responses in place
+
+  2014-09-16: Simon Goldschmidt
+  * pbuf.h/.c: added pbuf_take_at() and pbuf_put_at()
+
+  2014-09-15: Simon Goldschmidt
+  * dns.c: added source port randomization to make the DNS client more robust
+    (see bug #43144)
+
+  2013-09-02: Simon Goldschmidt
+  * arch.h and many other files: added optional macros PACK_STRUCT_FLD_8() and
+    PACK_STRUCT_FLD_S() to prevent gcc 4 from warning about struct members that
+    do not need packing
+
+  2013-08-19: Simon Goldschmidt
+  * netif.h: bug #42998: made NETIF_MAX_HWADDR_LEN overridable for some special
+    networks
+
+  2013-03-17: Simon Goldschmidt (patch by Ghobad Emadi)
+  * opt.h, etharp.c: Added LWIP_HOOK_ETHARP_GET_GW to implement IPv4 routing with
+    multiple gateways
+
+  2013-04-20: Fatih Asici
+  * opt.h, etharp.h/.c: patch #7993: Added support for transmitting packets
+    with VLAN headers via hook function LWIP_HOOK_VLAN_SET and to check them
+    via hook function LWIP_HOOK_VLAN_CHECK
+
+  2014-02-20: Simon Goldschmidt (based on patch by Artem Pisarenko)
+  * patch #7885: modification of api modules to support FreeRTOS-MPU
+    (don't pass stack-pointers to other threads)
+
+  2014-02-05: Simon Goldschmidt (patch by "xtian" and "alex_ab")
+  * patch #6537/#7858: TCP window scaling support
+
+  2014-01-17: Jiri Engelthaler
+  * icmp, icmp6, opt.h: patch #8027: Completed HW checksuming for IPv4 and
+    IPv6 ICMP's
+
+  2012-08-22: Sylvain Rochet
+  * New PPP stack for lwIP, developed in ppp-new branch.
+    Based from pppd 2.4.5, released 2009-11-17, with huge changes to match
+    code size and memory requirements for embedded devices, including:
+    - Gluing together the previous low-level PPP code in lwIP to pppd 2.4.5, which
+      is more or less what pppd sys-* files are, so that we get something working
+      using the unix port.
+    - Merged some patchs from lwIP Git repository which add interesting features
+      or fix bugs.
+    - Merged some patchs from Debian pppd package which add interesting features
+      or fix bugs.
+    - Ported PPP timeout handling to the lwIP timers system
+    - Disabled all the PPP code using filesystem access, replaced in necessary cases
+      to configuration variables.
+    - Disabled all the PPP code forking processes.
+    - Removed IPX support, lwIP does not support IPX.
+    - Ported and improved random module from the previous PPP port.
+    - Removed samba TDB (file-driven database) usage, because it needs a filesystem.
+    - MS-CHAP required a DES implementation, we added the latest PolarSSL DES
+      implementation which is under a BSD-ish license.
+    - Also switched to PolarSSL MD4,MD5,SHA1 implementations, which are meant to be
+      used in embedded devices with reduced memory footprint.
+    - Removed PPP configuration file parsing support. 
+    - Added macro definition EAP_SUPPORT to make EAP support optional.
+    - Added macro definition CHAP_SUPPORT to make CHAP support optional.
+    - Added macro definition MSCHAP_SUPPORT to make MSCHAP support optional.
+    - Added macro definition PAP_SUPPORT to make PAP support optional.
+    - Cleared all Linux syscall calls.
+    - Disabled demand support using a macro, so that it can be ported later.
+    - Disabled ECP support using a macro, so that it can be ported later.
+    - Disabled CCP support using a macro, so that it can be ported later.
+    - Disabled CBCP support using a macro, so that it can be ported later.
+    - Disabled LQR support using a macro, so that it can be ported later.
+    - Print packet debug feature optional, through PRINTPKT_SUPPORT
+    - Removed POSIX signal usage.
+    - Fully ported PPPoS code from the previous port.
+    - Fully ported PPPoE code from the previous port.
+    - Fully ported VJ compression protocol code from the previous port.
+    - Removed all malloc()/free() use from PPP, replaced by stack usage or PBUF.
+    - Disabled PPP server support using a macro, so that it can be ported later.
+    - Switched all PPP debug to lwIP debug system.
+    - Created PPP Control Block (PPP PCB), removed PPP unit integer everywhere,
+      removed all global variables everywhere, did everything necessary for
+      the PPP stack to support more than one PPP session (pppd only support
+      one session per process).
+    - Removed the statically allocated output buffer, now using PBUF.
+    - Improved structure size of all PPP modules, deep analyze of code to reduce
+      variables size to the bare minimum. Switched all boolean type (char type in
+      most architecture) to compiler generated bitfields.
+    - Added PPP IPv6 support, glued lwIP IPv6 support to PPP.
+    - Now using a persistent netif interface which can then be used in lwIP
+      functions requiring a netif.
+    - Now initializing PPP in lwip_init() function.
+    - Reworked completely the PPP state machine, so that we don't end up in
+      anymore in inconsistent state, especially with PPPoE.
+    - Improved the way we handle PPP reconnection after disconnect, cleaning
+      everything required so that we start the PPP connection again from a
+      clean state.
+    - Added PPP holdoff support, allow the lwIP user to wait a little bit before
+      reconnecting, prevents connection flood, especially when using PPPoL2TP.
+    - Added PPPoL2TP LAC support (a.k.a. UDP tunnels), adding a VPN client
+      feature to lwIP, L2TP being a widely used tunnel protocol.
+    - Switched all used PPP types to lwIP types (u8t, u16t, u32t, ...)
+    - Added PPP API "sequential" thread-safe API, based from NETIFAPI.
+
+  2011-07-21: Simon Goldschmidt
+  * sockets.c, opt.h: (bug #30185): added LWIP_FIONREAD_LINUXMODE that makes
+    ioctl/FIONREAD return the size of the next pending datagram.
+
+  2011-05-25: Simon Goldschmidt
+  * again nearly the whole stack, renamed ip.c to ip4.c, ip_addr.c to ip4_addr.c,
+    combined ipv4/ipv6 inet_chksum.c, added ip.h, ip_addr.h: Combined IPv4
+    and IPv6 code where possible, added defines to access IPv4/IPv6 in non-IP
+    code so that the code is more readable.
+
+  2011-05-17: Patch by Ivan Delamer (only checked in by Simon Goldschmidt)
+  * nearly the whole stack: Finally, we got decent IPv6 support, big thanks to
+    Ivan! (this is work in progress: we're just post release anyway :-)
+
+
+  ++ Bugfixes:
+
+  2016-08-23: Simon Goldschmidt
+  * etharp: removed ETHARP_TRUST_IP_MAC since it is insecure and we don't need
+    it any more after implementing unicast ARP renewal towards arp entry timeout
+
+  2016-07-20: Simon Goldschmidt
+  * memp.h/.c: fixed bug #48442 (memp stats don't work for MEMP_MEM_MALLOC)
+
+  2016-07-21: Simon Goldschmidt (patch by Ambroz Bizjak)
+  * tcp_in.c, tcp_out.c: fixed bug #48543 (TCP sent callback may prematurely
+    report sent data when only part of a segment is acked) and don't include
+    SYN/FIN in snd_buf counter
+
+  2016-07-19: Simon Goldschmidt
+  * etharp.c: fixed bug #48477 (ARP input packet might update static entry)
+
+  2016-07-11: Simon Goldschmidt
+  * tcp_in.c: fixed bug #48476 (TCP sent callback called wrongly due to picking
+    up old pcb->acked
+
+  2016-06-30: Simon Goldschmidt (original patch by Fabian Koch)
+  * tcp_in.c: fixed bug #48170 (Vulnerable to TCP RST spoofing)
+
+  2016-05-20: Dirk Ziegelmeier
+  * sntp.h/.c: Fix return value of sntp_getserver() call to return a pointer
+
+  2016-04-05: Simon Goldschmidt (patch by Philip Gladstone)
+  * udp.c: patch #8358: allow more combinations of listening PCB for IPv6
+
+  2016-04-05: Simon Goldschmidt
+  * netconn/socket API: fixed bug# 43739 (Accept not reporting errors about
+    aborted connections): netconn_accept() returns ERR_ABRT (sockets: ECONNABORTED)
+    for aborted connections, ERR_CLSD (sockets: EINVAL) if the listening netconn
+    is closed, which better seems to follow the standard.
+
+  2016-03-23: Florent Matignon
+  * dhcp.c: fixed bug #38203: DHCP options are not recorded in all DHCP ack messages
+
+  2016-03-22: Simon Goldschmidt
+  * tcp: changed accept handling to be done internally: the application does not
+    have to call tcp_accepted() any more. Instead, when delaying accept (e.g. sockets
+    do), call tcp_backlog_delayed()/tcp_backlog_accepted() (fixes bug #46696)
+
+  2016-03-22: Simon Goldschmidt
+  * dns.c: ignore dns response parsing errors, only abort resolving for correct
+    responses or error responses from correct server (bug #47459)
+
+  2016-03-17: Simon Goldschmidt
+  * api_msg.c: fixed bug #47448 (netconn/socket leak if RST is received during close)
+
+  2016-03-17: Joel Cunningham
+  * api_msg.c: don't fail closing a socket/netconn when failing to allocate the
+    FIN segment; blocking the calling thread for a while is better than risking
+    leaking a netconn/socket (see bug #46701)
+
+  2016-03-16: Joel Cunningham
+  * tcp_out.c: reset rto timer on fast retransmission
+
+  2016-03-16: Deomid Ryabkov
+  * tcp_out.c: fixed bug #46384 Segment size calculation bug with MSS != TCP_MSS
+
+  2016-03-05: Simon Goldschmidt
+  * err.h/.c, sockets.c: ERR_IF is not necessarily a fatal error
+
+  2015-11-19: fix by Kerem Hadimli
+  * sockets.c: fixed bug #46471: lwip_accept() leaks socket descriptors if new
+    netconn was already closed because of peer behavior
+
+  2015-11-12: fix by Valery Ushakov
+  * tcp_in.c: fixed bug #46365 tcp_accept_null() should call tcp_abort()
+
+  2015-10-02: Dirk Ziegelmeier/Simon Goldschmidt
+  * snmp: cleaned up snmp structs API (fixed race conditions from bug #46089,
+    reduce ram/rom usage of tables): incompatible change for private MIBs
+
+  2015-09-30: Simon Goldschmidt
+  * ip4_addr.c: fixed bug #46072: ip4addr_aton() does not check the number range
+    of all address parts
+
+  2015-08-28: Simon Goldschmidt
+  * tcp.c, tcp_in.c: fixed bug #44023: TCP ssthresh value is unclear: ssthresh
+    is set to the full send window for active open, too, and is updated once
+    after SYN to ensure the correct send window is used
+
+  2015-08-28: Simon Goldschmidt
+  * tcp: fixed bug #45559: Window scaling casts u32_t to u16_t without checks
+
+  2015-08-26: Simon Goldschmidt
+  * ip6_frag.h/.c: fixed bug bug #41009: IPv6 reassembly broken on 64-bit platforms:
+    define IPV6_FRAG_COPYHEADER==1 on these platforms to copy the IPv6 header
+    instead of referencing it, which gives more room for struct ip6_reass_helper
+
+  2015-08-25: Simon Goldschmidt
+  * sockets.c: fixed bug #45827: recvfrom: TCP window is updated with MSG_PEEK
+
+  2015-08-20: Manoj Kumar
+  * snmp_msg.h, msg_in.c: fixed bug #43790: Sending octet string of Length >255
+    from SNMP agent
+
+  2015-08-19: Jens Nielsen
+  * icmp.c, ip4.c, tcp_in.c, udp.c, raw.c: fixed bug #45120: Broadcast & multiple
+    interfaces handling
+
+  2015-08-19: Simon Goldschmidt (patch by "Sandra")
+  * dns.c: fixed bug #45004: dns response without answer might be discarded
+
+  2015-08-18: Chrysn
+  * timers.c: patch #8704 fix sys_timeouts_sleeptime function
+
+  2015-07-01: Erik Ekman
+  * puf.c: fixed bug #45454 (pbuf_take_at() skips write and returns OK if offset
+    is at start of pbuf in chain)
+
+  2015-05-19: Simon Goldschmidt
+  * dhcp.h/.c: fixed bugs #45140 and #45141 (dhcp was not stopped correctly after
+    fixing bug #38204)
+
+  2015-03-21: Simon Goldschmidt (patch by Homyak)
+  * tcp_in.c: fixed bug #44766 (LWIP_WND_SCALE: tcphdr->wnd was not scaled in
+    two places)
+
+  2015-03-21: Simon Goldschmidt
+  * tcp_impl.h, tcp.c, tcp_in.c: fixed bug #41318 (Bad memory ref in tcp_input()
+    after tcp_close())
+
+  2015-03-21: Simon Goldschmidt
+  * tcp_in.c: fixed bug #38468 (tcp_sent() not called on half-open connection for
+    data ACKed with the same ack as FIN)
+
+  2015-03-21: Simon Goldschmidt (patch by Christoffer Lind)
+  * dhcp.h/.c: fixed bug #38204 (DHCP lease time not handled correctly)
+
+  2015-03-20: Simon Goldschmidt
+  * dhcp.c: fixed bug #38714 (Missing option and client address in DHCPRELEASE message)
+
+  2015-03-19: Simon Goldschmidt
+  * api.h, tcpip.h, api_lib.c, api_msg.c: fixed race conditions in assigning
+    netconn->last_err (fixed bugs #38121 and #37676)
+
+  2015-03-09: Simon Goldschmidt
+  * ip4.c: fixed the IPv4 part of bug #43904 (ip_route() must detect linkup status)
+
+  2015-03-04: Simon Goldschmidt
+  * nd6.c: fixed bug #43784 (a host should send at least one Router Solicitation)
+
+  2015-03-04: Valery Ushakov
+  * ip6.c: fixed bug #41094 (Byte-order bug in IPv6 fragmentation header test)
+
+  2015-03-04: Zach Smith
+  * nd6.c: fixed bug #38153 (nd6_input() byte order issues)
+
+  2015-02-26: Simon Goldschmidt
+  * netif.c, tcp.h/.c: fixed bug #44378 (TCP connections are not aborted on netif
+    remove)
+
+  2015-02-25: Simon Goldschmidt
+  * ip4.c, etharp.c: fixed bug #40177 (System hangs when dealing with corrupted
+    packets), implemented task #12357 (Ensure that malicious packets don't
+    assert-fail): improved some pbuf_header calls to not assert-fail.
+
+  2015-02-25: patch by Joel Cunningham
+  * udp.h/.c, sockets.c: fixed bug #43028 (IP_MULTICAST_TTL affects unicast
+    datagrams)
+
+  2015-02-25: patch by Greg Renda
+  * ip4_frag.c: fixed bug #38210 (ip reassembly while remove oldest datagram)
+
+  2015-02-25: Simon Goldschmidt
+  * sockets.c: fixed bug #38165 (socket with mulicast): ensure igmp membership
+    are dropped when socket (not netconn!) is closed.
+
+  2015-02-25: Simon Goldschmidt
+  * ip4.h/.c, udp.c: fixed bug #38061 (wrong multicast routing in IPv4) by
+    adding an optional default netif for multicast routing
+
+  2015-02-25: Simon Goldschmidt
+  * netconn API: fixed that netconn_connect still used message passing for
+    LWIP_TCPIP_CORE_LOCKING==1
+
+  2015-02-22: patch by Jens Nielsen
+  * icmp.c: fixed bug #38803 (Source address in broadcast ping reply)
+
+  2015-02-22: Simon Goldschmidt
+  * udp.h, sockets.c: added proper accessor functions for pcb->multicast_ip
+    (previously used by get/setsockopt only)
+
+  2015-02-18: Simon Goldschmidt
+  * sockets.c: Fixed select not reporting received FIN as 'readable' in certain
+    rare cases (bug #43779: select(), close(), and TCP retransmission error)
+
+  2015-02-17: Simon Goldschmidt
+  * err.h, sockets.c, api_msg.c: fixed bug #38853 "connect() use a wrong errno":
+    return ERR_ALREADY/EALRADY during connect, ERR_ISCONN/EISCONN when already
+    connected
+
+  2015-02-17: Simon Goldschmidt
+  * tcp_impl.h, tcp_out.c, tcp.c, api_msg.c: fixed bug #37614 "Errors from
+    ipX_output are not processed". Now tcp_output(_segment) checks for the return
+    value of ipX_output and does not try to send more on error. A netif driver
+    can call tcp_txnow() (from tcpip_thread!) to try to send again if TX buffers
+    are available again.
+
+  2015-02-14: patches by Freddie Chopin
+  * snmp*: made community writable, fixed some const pointers
+
+  2015-02-13: Simon Goldschmidt
+  * msg_in.c: fixed bug #22070 "MIB_OBJECT_WRITE_ONLY not implemented in SNMP"
+
+  2015-02-12: Simon Goldschmidt
+  * ip.h, ip4.c, ip6.c: fixed bug #36403 "ip4_input() and ip6_input() always pass
+    inp to higher layers": now the accepting netif is passed up, but the input
+    netif is available through ip_current_input_netif() if required.
+
+  2015-02-11: patch by hichard
+  * tcpip.c: fixed bug #43094 "The function tcpip_input() forget to handle IPv6"
+
+  2015-02-10: Simon Goldschmidt
+  * netconn API: fixed that netconn_close/netconn_delete still used message passing
+    for LWIP_TCPIP_CORE_LOCKING==1
+
+  2015-02-10: Simon Goldschmidt
+  * netconn/socket api: fixed bug #44225 "closing TCP socket should time out
+    eventually", implemented task #6930 "Implement SO_LINGER": closing TCP sockets
+    times out after 20 seconds or after the configured SND_TIMEOUT or depending
+    on the linger settings.
+
+  2015-01-27: Simon Goldschmidt
+  * api_msg.c: fixed that SHUT_RD followed by SHUT_WR was different to SHUT_RDWR,
+    fixed return value of lwip_netconn_do_close on unconnected netconns
+
+  2015-01-17: Simon Goldschmidt
+  * sockets.c: fixed bug #43361 select() crashes with stale FDs
+
+  2015-01-17: Simon Goldschmidt
+  * sockets.c/.h, memp_std.h: fixed bug #40788 "lwip_setsockopt_internal() crashes"
+    by rewriting set/getsockopt functions to combine checks with the actual code
+    and add more NULL checks; this also fixes that CORE_LOCKING used message
+    passing for set/getsockopt.
+
+  2014-12-19: Simon Goldschmidt
+  * opt.h, dhcp.h/.c: prevent dhcp from starting when netif link is down (only
+    when LWIP_DHCP_CHECK_LINK_UP==1, which is disabled by default for
+    compatibility reasons)
+
+  2014-12-17: Simon Goldschmidt
+  * tcp_out.c: fixed bug #43840 Checksum error for TCP_CHECKSUM_ON_COPY==1 for
+    no-copy data with odd length
+
+  2014-12-10: Simon Goldschmidt
+  * sockets.c, tcp.c, others: fixed bug #43797 set/getsockopt: SO_SNDTIMEO/SO_RCVTIMEO
+    take int as option but should take timeval (LWIP_SO_SNDRCVTIMEO_STANDARD==0 can
+    be used to revert to the old 'winsock' style behaviour)
+    Fixed implementation of SO_ACCEPTCONN to just look at the pcb state
+
+  2014-12-09: Simon Goldschmidt
+  * ip4.c: fixed bug #43596 IGMP queries from 0.0.0.0 are discarded
+
+  2014-10-21: Simon Goldschmidt (patch by Joel Cunningham and Albert Huitsing)
+  * sockts.c: fixed bugs #41495 Possible threading issue in select() and #43278
+    event_callback() handle context switch when calling sys_sem_signal()
+
+  2014-10-21: Simon Goldschmidt
+  * api_msg.c: fixed bug #38219 Assert on TCP netconn_write with sndtimeout set
+
+  2014-09-16: Kevin Cernekee
+  * dns.c: patch #8480 Fix handling of dns_seqno wraparound
+
+  2014-09-16: Simon Goldschmidt
+  * tcp_out.c: fixed bug #43192 tcp_enqueue_flags() should not check TCP_SND_QUEUELEN
+    when sending FIN
+
+  2014-09-03: Simon Goldschmidt
+  * msg_in.c: fixed bug #39355 SNMP Memory Leak in case of error
+
+  2014-09-02: Simon Goldschmidt
+  * err.h/.c, sockets.c, api_msg.c: fixed bug #43110 call getpeername() before
+    listen() will cause a error
+
+  2014-09-02: Simon Goldschmidt
+  * sockets.c: fixed bug #42117 lwip_fcntl does not set errno
+
+  2014-09-02: Simon Goldschmidt
+  * tcp.c: fixed bug #42299 tcp_abort() leaves freed pcb on tcp_bound_pcbs list
+
+  2014-08-20: Simon Goldschmidt
+  * dns.c: fixed bug #42987 lwIP is vulnerable to DNS cache poisoning due to
+    non-randomized TXIDs
+
+  2014-06-03: Simon Goldschmidt
+  * tcp_impl.h, tcp_in.c: fixed bug #37969 SYN packet dropped as short packet in
+    tcp_input function
+
+  2014-05-20: Simon Goldschmidt
+  * tcp_out.c: fixed bug #37184 tcp_write problem for pcbs in the SYN_SENT state
+
+  2014-05-19: Simon Goldschmidt
+  * *.h: Fixed bug #35874 reserved identifier violation (removed leading underscores
+    from header include guards)
+
+  2014-04-08: Simon Goldschmidt
+  * tcp.c: Fixed bug #36167 tcp server crash when client closes (maximum window)
+
+  2014-04-06: Simon Goldschmidt
+  * tcp_in.c: Fixed bug #36210 lwIP does not elicit an empty ACK when received
+    unacceptable ACK
+
+  2014-04-06: Simon Goldschmidt
+  * dhcp.c, ip4.c/.h, ip6.c/.h, udp.c/.h, ip.h: Fixed bug #41787 DHCP Discovery
+    is invalid when an IP is set to thet netif.
+
+  2014-03-14: Simon Goldschmidt
+  * tcp_out.c: Fixed bug #36153 TCP Cheksum error if LWIP_CHECKSUM_ON_COPY=1
+
+  2014-03-11: Simon Goldschmidt (patch by Mason)
+  * opt.h, sockets.c: fixed bug #35928 BSD sockets functions must set errno for
+    POSIX-compliance
+
+  2014-02-27: Simon Goldschmidt
+  * dhcp.c: fixed bug #40303 DHCP xid renewed when sending a DHCPREQUEST
+
+  2014-02-27: Simon Goldschmidt
+  * raw.c: fixed bug #41680 raw socket can not receive IPv6 packet when
+    IP_SOF_BROADCAST_RECV==1
+
+  2014-02-27: Simon Goldschmidt
+  * api_msg.c, sockets.c: fixed bug #38404 getpeeraddr returns success on
+    unconnected/listening TCP sockets
+
+  2014-02-27: Simon Goldschmidt
+  * sockets.c: fixed bug #41729 Some socket functions return Exyz instead of -1
+
+  2014-02-25: Simon Goldschmidt
+  * ip4.c: fixed bug #39514 ip_route() may return an IPv6-only interface
+
+  2014-02-25: Simon Goldschmidt, patch by Fatih Asici
+  * pbuf.c: fixed bug #39356 Wrong increment in pbuf_memfind()
+
+  2014-02-25: Simon Goldschmidt
+  * netif.c/.h, udp.c: fixed bug #39225 udp.c uses netif_matches_ip6_addr() incorrectly;
+    renamed function netif_matches_ip6_addr() to netif_get_ip6_addr_match()
+
+  2014-02-25: Simon Goldschmidt
+  * igmp.c: fixed bug #39145 IGMP membership report for 224.0.0.1
+
+  2014-02-22: Simon Goldschmidt (patch by Amir Shalem)
+  * etharp.c, opt.h: fixed bug #34681 Limit ARP queue length by ARP_QUEUE_LEN (=3)
+
+  2014-02-22: Simon Goldschmidt (patch by Amir Shalem)
+  * etharp.h/.c: fixed bug #34682 Limit ARP request flood for unresolved entry
+
+  2014-02-20: Simon Goldschmidt
+  * tcp_out.c: fixed bug #39683 Assertion "seg->tcphdr not aligned" failed with
+    MEM_ALIGNMENT = 8
+
+  2014-02-20: Simon Goldschmidt
+  * sockets.c: fixed bug #39882 No function shall set errno to 0
+
+  2014-02-20: Simon Goldschmidt
+  * mib_structs.c: fixed bug #40050 SNMP problem with MIB arrays > 255
+
+  2014-02-20: Simon Goldschmidt
+  * api.h, sockets.c: fixed bug #41499 netconn::recv_avail can overflow
+
+  2014-01-08: Stathis Voukelatos
+  * memp_std.h: patch #7928 Fixed size calculation in MALLOC memory pool
+    creation macro
+
+  2014-01-18: Brian Fahs
+  * tcp_out.c: patch #8237: tcp_rexmit_rto fails to update pcb->unsent_oversize
+    when necessary
+
+  2014-01-17: Grant Erickson, Jay Logue, Simon Goldschmidt
+  * ipv6.c, netif.c: patch #7913 Enable Support for IPv6 Loopback
+
+  2014-01-16: Stathis Voukelatos
+  * netif.c: patch #7902 Fixed netif_poll() operation when LWIP_LOOPBACK_MAX_PBUFS > 0
+
+  2014-01-14: "Freddie Chopin"
+  * snmp.h, mib2.c: fixed constness and spelling of sysdescr
+
+  2014-01-14: Simon Goldschmidt (patch by Thomas Faber)
+  * tcpip.c: patch #8241: Fix implicit declaration of ip_input with
+    LWIP_TCPIP_CORE_LOCKING_INPUT disabled
+
+  2014-01-14: chrysn
+  * timers.c: patch #8244 make timeouts usable reliably from outside of the
+    timeout routine
+
+  2014-01-10: Simon Goldschmidt
+  * ip_frag.c, ip6_frag.c: fixed bug #41041 Potential use-after-free in IPv6 reassembly
+
+  2014-01-10: Simon Goldschmidt
+  * memp.c: fixed bug #41188 Alignment error in memp_init() when MEMP_SEPARATE_POOLS==1
+
+  2014-01-10: Simon Goldschmidt
+  * tcp.c: fixed bug #39898 tcp_fasttmr() possible lock due to infinte queue process loop
+
+  2013-06-29: Simon Goldschmidt
+  * inet.h, sockets.h: partially fixed bug #37585: IPv6 compatibility (in socket structs)
+
+  2013-06-29: Simon Goldschmidt
+  * inet6.h: bug #37585/task #12600: fixed struct in6_addr.s6_addr to conform to spec
+
+  2013-04-24: patch by Liam <morepork>
+  * api_msg.c: patch #8008 Fix a potential null pointer dereference in assert
+
+  2013-04-24: Simon Goldschmidt
+  * igmp.c: fixed possible division by zero
+
+  2013-04-24: Simon Goldschmidt
+  * ip6.h, some ipv6 C files: fixed bug #38526 Coverity: Recursive Header Inclusion in ip6.h
+
+  2013-04-24: Simon Goldschmidt (patch by Emil Ljungdahl):
+  * netif.c: fixed bug #38586 netif_loop_output() "deadlocks"
+
+  2013-01-15: Simon Goldschmidt
+  * ip4.c: fixed bug #37665 ip_canforward operates on address in wrong byte order
+
+  2013-01-15: Simon Goldschmidt
+  * pbuf.h: fixed bug #38097 pbuf_free_ooseq() warning
+
+  2013-01-14: Simon Goldschmidt
+  * dns.c: fixed bug #37705 Possible memory corruption in DNS query
+
+  2013-01-11: Simon Goldschmidt
+  * raw.c: fixed bug #38066 Raw pcbs can alter packet without eating it
+
+  2012-08-22: Simon Goldschmidt
+  * memp.c: fixed bug #37166: memp_sanity check loops itself
+
+  2012-08-13: Simon Goldschmidt
+  * dhcp.c: fixed bug #36645: Calling dhcp_release before dhcp_start
+    dereferences NULL
+
+  2012-08-13: Simon Goldschmidt
+  * msg_out.c: fixed bug #36840 snmp_send_trap() NULL de-reference if traps
+    configured but no interfaces available
+
+  2012-08-13: Simon Goldschmidt
+  * dns.c: fixed bug #36899 DNS TTL 0 is cached for a long time
+
+  2012-05-11: Simon Goldschmidt (patch by Marty)
+  * memp.c: fixed bug #36412: memp.c does not compile when
+    MEMP_OVERFLOW_CHECK > zero and MEMP_SEPARATE_POOLS == 1
+
+  2012-05-03: Simon Goldschmidt (patch by Sylvain Rochet)
+  * ppp.c: fixed bug #36283 (PPP struct used on header size computation and
+    not packed)
+
+  2012-05-03: Simon Goldschmidt (patch by David Empson)
+  * ppp.c: fixed bug #36388 (PPP: checksum-only in last pbuf leads to pbuf with
+    zero length)
+
+  2012-03-25: Simon Goldschmidt
+  * api_msg.c: Fixed bug #35817: do_connect() invalidly signals op_completed
+    for UDP/RAW with LWIP_TCPIP_CORE_LOCKING==1
+
+  2012-03-25: Simon Goldschmidt
+  * api_msg.h, api_lib.c, api_msg.c, netifapi.c: fixed bug #35931: Name space
+    pollution in api_msg.c and netifapi.c
+
+  2011-08-24: Simon Goldschmidt
+  * inet6.h: fixed bug #34124 struct in6_addr does not conform to the standard
+
+
+
+(STABLE-1.4.1)
+
+  ++ New features:
+
+  2012-03-25: Simon Goldschmidt (idea by Mason)
+  * posix/*: added posix-compatibility include files posix/netdb.h and posix/sys/socket.h
+    which are a simple wrapper to the correct lwIP include files.
+ 
+  2012-01-16: Simon Goldschmidt
+  * opt.h, icmp.c: Added option CHECKSUM_GEN_ICMP
+
+  2011-12-17: Simon Goldschmidt
+  * ip.h: implemented API functions to access so_options of IP pcbs (UDP, TCP, RAW)
+    (fixes bug #35061)
+
+  2011-09-27: Simon Goldschmidt
+  * opt.h, tcp.c, tcp_in.c: Implemented limiting data on ooseq queue (task #9989)
+    (define TCP_OOSEQ_MAX_BYTES / TCP_OOSEQ_MAX_PBUFS in lwipopts.h)
+
+  2011-09-21: Simon Goldschmidt
+  * opt.h, api.h, api_lib.c, api_msg.h/.c, sockets.c: Implemented timeout on
+    send (TCP only, bug #33820)
+
+  2011-09-21: Simon Goldschmidt
+  * init.c: Converted runtime-sanity-checks into compile-time checks that can
+    be disabled (since runtime checks can often not be seen on embedded targets)
+
+  2011-09-11: Simon Goldschmidt
+  * ppp.h, ppp_impl.h: splitted ppp.h to an internal and external header file
+    to get a clear separation of which functions an application or port may use
+    (task #11281)
+
+ 2011-09-11: Simon Goldschmidt
+  * opt.h, tcp_impl.h, tcp.c, udp.h/.c: Added a config option to randomize
+    initial local TCP/UDP ports (so that different port ranges are used after
+    a reboot; bug #33818; this one added tcp_init/udp_init functions again)
+
+  2011-09-03: Simon Goldschmidt
+  * dhcp.c: DHCP uses LWIP_RAND() for xid's (bug #30302)
+
+  2011-08-24: Simon Goldschmidt
+  * opt.h, netif.h/.c: added netif remove callback (bug #32397)
+
+  2011-07-26: Simon Goldschmidt
+  * etharp.c: ETHARP_SUPPORT_VLAN: add support for an external VLAN filter
+    function instead of only checking for one VLAN (define ETHARP_VLAN_CHECK_FN)
+
+  2011-07-21: Simon Goldschmidt (patch by hanhui)
+  * ip4.c, etharp.c, pbuf.h: bug #33634 ip_forward() have a faulty behaviour:
+    Added pbuf flags to mark incoming packets as link-layer broadcast/multicast.
+    Also added code to allow ip_forward() to forward non-broadcast packets to
+    the input netif (set IP_FORWARD_ALLOW_TX_ON_RX_NETIF==1).
+
+  2011-06-26: Simon Goldschmidt (patch by Cameron Gutman)
+  * tcp.c, tcp_out.c: bug #33604: added some more asserts to check that
+    pcb->state != LISTEN
+
+   2011-05-14: Simon Goldschmidt (patch by Stè¾¿phane Lesage)
+  * tcpip.c/.h: patch #7449 allow tcpip callback from interrupt with static
+    memory message
+
+
+  ++ Bugfixes:
+
+  2012-09-26: Simon Goldschmidt
+  * api_msg.c: fixed bug #37405 'err_tcp()' uses already freed 'netconn' object
+
+  2012-09-26: patch by Henrik Persson
+  * dhcp.c: patch #7843 Fix corner case with dhcp timeouts
+
+  2012-09-26: patch by Henrik Persson
+  * dhcp.c: patch #7840 Segfault in dhcp_parse_reply if no end marker in dhcp packet
+
+  2012-08-22: Simon Goldschmidt
+  * memp.c: fixed bug #37166: memp_sanity check loops itself
+
+  2012-05-08: Simon Goldschmidt
+  * tcp_out.c: fixed bug: #36380 unsent_oversize mismatch in 1.4.1RC1 (this was
+    a debug-check issue only)
+
+  2012-03-27: Simon Goldschmidt
+  * vj.c: fixed bug #35756 header length calculation problem in ppp/vj.c
+
+  2012-03-27: Simon Goldschmidt (patch by Mason)
+  * tcp_out.c: fixed bug #35945: SYN packet should provide the recv MSS not the
+    send MSS
+
+  2012-03-22: Simon Goldschmidt
+  * ip4.c: fixed bug #35927: missing refragmentaion in ip_forward
+ 
+  2012-03-20: Simon Goldschmidt (patch by Mason)
+  * netdb.c: fixed bug #35907: lwip_gethostbyname_r returns an invalid h_addr_list
+ 
+  2012-03-12: Simon Goldschmidt (patch by Bostjan Meglic)
+  * ppp.c: fixed bug #35809: PPP GetMask(): Compiler warning on big endian,
+    possible bug on little endian system
+
+  2012-02-23: Simon Goldschmidt
+  * etharp.c: fixed bug #35595: Impossible to send broadcast without a gateway
+    (introduced when fixing bug# 33551)
+
+  2012-02-16: Simon Goldschmidt
+  * ppp.c: fixed pbuf leak when PPP session is aborted through pppSigHUP()
+    (bug #35541: PPP Memory Leak)
+
+  2012-02-16: Simon Goldschmidt
+  * etharp.c: fixed bug #35531: Impossible to send multicast without a gateway
+    (introduced when fixing bug# 33551)
+
+  2012-02-16: Simon Goldschmidt (patch by Stè¾¿phane Lesage)
+  * msg_in.c, msg_out.c: fixed bug #35536 SNMP: error too big response is malformed
+
+  2012-02-15: Simon Goldschmidt
+  * init.c: fixed bug #35537: MEMP_NUM_* sanity checks should be disabled with
+    MEMP_MEM_MALLOC==1
+
+  2012-02-12: Simon Goldschmidt
+  * tcp.h, tcp_in.c, tcp_out.c: partly fixed bug #25882: TCP hangs on
+    MSS > pcb->snd_wnd (by not creating segments bigger than half the window)
+
+  2012-02-11: Simon Goldschmidt
+  * tcp.c: fixed bug #35435: No pcb state check before adding it to time-wait
+    queue while closing
+
+  2012-01-22: Simon Goldschmidt
+  * tcp.c, tcp_in.c: fixed bug #35305: pcb may be freed too early on shutdown(WR)
+
+  2012-01-21: Simon Goldschmidt
+  * tcp.c: fixed bug #34636: FIN_WAIT_2 - Incorrect shutdown of TCP pcb
+
+  2012-01-20: Simon Goldschmidt
+  * dhcp.c: fixed bug #35151: DHCP asserts on incoming option lengths
+
+ 2012-01-20: Simon Goldschmidt
+  * pbuf.c: fixed bug #35291: NULL pointer in pbuf_copy
+
+  2011-11-25: Simon Goldschmidt
+  * tcp.h/.c, tcp_impl.h, tcp_in.c: fixed bug #31177: tcp timers can corrupt
+    tcp_active_pcbs in some cases
+
+  2011-11-23: Simon Goldschmidt
+  * sys.c: fixed bug #34884: sys_msleep() body needs to be surrounded with
+    '#ifndef sys_msleep'
+
+  2011-11-22: Simon Goldschmidt
+  * netif.c, etharp.h/.c: fixed bug #34684: Clear the arp table cache when
+    netif is brought down
+
+  2011-10-28: Simon Goldschmidt
+  * tcp_in.c: fixed bug #34638: Dead code in tcp_receive - pcb->dupacks
+
+  2011-10-23: Simon Goldschmidt
+  * mem.c: fixed bug #34429: possible memory corruption with
+    LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT set to 1
+
+  2011-10-18: Simon Goldschmidt
+  * arch.h, netdb.c: fixed bug #34592: lwip_gethostbyname_r uses nonstandard
+    error value
+
+  2011-10-18: Simon Goldschmidt
+  * opt.h: fixed default values of TCP_SNDLOWAT and TCP_SNDQUEUELOWAT for small
+    windows (bug #34176 select after non-blocking send times out)
+
+  2011-10-18: Simon Goldschmidt
+  * tcp_impl.h, tcp_out.c: fixed bug #34587: TCP_BUILD_MSS_OPTION doesn't
+    consider netif->mtu, causes slow network
+
+  2011-10-18: Simon Goldschmidt
+  * sockets.c: fixed bug #34581 missing parentheses in udplite sockets code
+
+  2011-10-18: Simon Goldschmidt
+  * sockets.h: fixed bug #34580 fcntl() is missing in LWIP_COMPAT_SOCKETS
+
+  2011-10-17: Simon Goldschmidt
+  * api_msg.c: fixed bug #34569: shutdown(SHUT_WR) crashes netconn/socket api
+
+  2011-10-13: Simon Goldschmidt
+  * tcp_in.c, tcp_out.c: fixed bug #34517 (persist timer is started although no
+    zero window is received) by starting the persist timer when a zero window is
+    received, not when we have more data queued for sending than fits into the
+    window
+
+  2011-10-13: Simon Goldschmidt
+  * def.h, timers.c: fixed bug #34541: LWIP_U32_DIFF is unnecessarily complex
+
+  2011-10-13: Simon Goldschmidt
+  * sockets.c, api_lib.c: fixed bug #34540: compiler error when CORE_LOCKING is
+    used and not all protocols are enabled
+
+  2011-10-12: Simon Goldschmidt
+  * pbuf.c: fixed bug #34534: Error in sending fragmented IP if MEM_ALIGNMENT > 4
+
+  2011-10-09: Simon Goldschmidt
+  * tcp_out.c: fixed bug #34426: tcp_zero_window_probe() transmits incorrect
+    byte value when pcb->unacked != NULL
+
+  2011-10-09: Simon Goldschmidt
+  * ip4.c: fixed bug #34447 LWIP_IP_ACCEPT_UDP_PORT(dst_port) wrong
+
+  2011-09-27: Simon Goldschmidt
+  * tcp_in.c, tcp_out.c: Reset pcb->unsent_oversize in 2 more places...
+
+  2011-09-27: Simon Goldschmidt
+  * tcp_in.c: fixed bug #28288: Data after FIN in oos queue
+
+  2011-09-27: Simon Goldschmidt
+  * dhcp.c: fixed bug #34406 dhcp_option_hostname() can overflow the pbuf
+
+  2011-09-24: Simon Goldschmidt
+  * mem.h: fixed bug #34377 MEM_SIZE_F is not defined if MEM_LIBC_MALLOC==1
+
+  2011-09-23: Simon Goldschmidt
+  * pbuf.h, tcp.c, tcp_in.c: fixed bug #33871: rejecting TCP_EVENT_RECV() for
+    the last packet including FIN can lose data
+
+  2011-09-22: Simon Goldschmidt
+  * tcp_impl.h: fixed bug #34355: nagle does not take snd_buf/snd_queuelen into
+    account
+
+  2011-09-21: Simon Goldschmidt
+  * opt.h: fixed default value of TCP_SND_BUF to not violate the sanity checks
+    in init.c
+
+  2011-09-20: Simon Goldschmidt
+  * timers.c: fixed bug #34337 (possible NULL pointer in sys_check_timeouts)
+
+  2011-09-11: Simon Goldschmidt
+  * tcp_out.c: use pcb->mss instead of TCP_MSS for preallocate mss-sized pbufs
+    (bug #34019)
+
+  2011-09-09: Simon Goldschmidt
+  * udp.c: fixed bug #34072: UDP broadcast is received from wrong UDP pcb if
+    udp port matches
+
+  2011-09-03: Simon Goldschmidt
+  * tcp_in.c: fixed bug #33952 PUSH flag in incoming packet is lost when packet
+    is aggregated and sent to application
+
+  2011-09-01: Simon Goldschmidt
+  * opt.h: fixed bug #31809 LWIP_EVENT_API in opts.h is inconsistent compared
+    to other options
+
+  2011-09-01: Simon Goldschmidt
+  * tcp_in.c: fixed bug #34111 RST for ACK to listening pcb has wrong seqno
+
+  2011-08-24: Simon Goldschmidt
+  * api_msg.c, sockets.c: fixed bug #33956 Wrong error returned when calling
+    accept() on UDP connections
+
+  2011-08-24: Simon Goldschmidt
+  * sockets.h: fixed bug #34057 socklen_t should be a typedef
+
+  2011-08-24: Simon Goldschmidt
+  * pbuf.c: fixed bug #34112 Odd check in pbuf_alloced_custom (typo)
+
+  2011-08-24: Simon Goldschmidt
+  * dhcp.c: fixed bug #34122 dhcp: hostname can overflow
+
+  2011-08-24: Simon Goldschmidt
+  * netif.c: fixed bug #34121 netif_add/netif_set_ipaddr fail on NULL ipaddr
+
+  2011-08-22: Simon Goldschmidt
+  * tcp_out.c: fixed bug #33962 TF_FIN not always set after FIN is sent. (This
+    merely prevents nagle from not transmitting fast after closing.)
+
+  2011-07-22: Simon Goldschmidt
+  * api_lib.c, api_msg.c, sockets.c, api.h: fixed bug #31084 (socket API returns
+    always EMSGSIZE on non-blocking sockets if data size > send buffers) -> now
+    lwip_send() sends as much as possible for non-blocking sockets
+
+  2011-07-22: Simon Goldschmidt
+  * pbuf.c/.h, timers.c: freeing ooseq pbufs when the pbuf pool is empty implemented
+    for NO_SYS==1: when not using sys_check_timeouts(), call PBUF_CHECK_FREE_OOSEQ()
+    at regular intervals from main level.
+
+  2011-07-21: Simon Goldschmidt
+  * etharp.c: fixed bug #33551 (ARP entries may time out although in use) by
+    sending an ARP request when an ARP entry is used in the last minute before
+    it would time out.
+
+  2011-07-04: Simon Goldschmidt
+  * sys_arch.txt: Fixed documentation after changing sys arch prototypes for 1.4.0.
+
+  2011-06-26: Simon Goldschmidt
+  * tcp.c: fixed bug #31723 (tcp_kill_prio() kills pcbs with the same prio) by
+    updating its documentation only.
+
+ 2011-06-26: Simon Goldschmidt
+  * mem.c: fixed bug #33545: With MEM_USE_POOLS==1, mem_malloc can return an
+    unaligned pointer.
+
+  2011-06-26: Simon Goldschmidt
+  * mem.c: fixed bug #33544 "warning in mem.c in lwip 1.4.0 with NO_SYS=1"
+
+   2011-05-25: Simon Goldschmidt
+  * tcp.c: fixed bug #33398 (pointless conversion when checking TCP port range)
+
+
+
+(STABLE-1.4.0)
+
+  ++ New features:
+
+  2011-03-27: Simon Goldschmidt
+  * tcp_impl.h, tcp_in.c, tcp_out.c: Removed 'dataptr' from 'struct tcp_seg' and
+    calculate it in tcp_zero_window_probe (the only place where it was used).
+
+  2010-11-21: Simon Goldschmidt
+  * dhcp.c/.h: Added a function to deallocate the struct dhcp from a netif
+    (fixes bug #31525).
+
+  2010-07-12: Simon Goldschmidt (patch by Stephane Lesage)
+  * ip.c, udp.c/.h, pbuf.h, sockets.c: task #10495: Added support for
+    IP_MULTICAST_LOOP at socket- and raw-API level.
+
+  2010-06-16: Simon Goldschmidt
+  * ip.c: Added an optional define (LWIP_IP_ACCEPT_UDP_PORT) that can allow
+    link-layer-addressed UDP traffic to be received while a netif is down (just
+    like DHCP during configuration)
+
+  2010-05-22: Simon Goldschmidt
+  * many many files: bug #27352: removed packing from ip_addr_t, the packed
+    version is now only used in protocol headers. Added global storage for
+    current src/dest IP address while in input functions.
+
+  2010-05-16: Simon Goldschmidt
+  * def.h: task #10391: Add preprocessor-macros for compile-time htonl
+    calculation (and use them throughout the stack where applicable)
+
+  2010-05-16: Simon Goldschmidt
+  * opt.h, memp_std.h, memp.c, ppp_oe.h/.c: PPPoE now uses its own MEMP pool
+    instead of the heap (moved struct pppoe_softc from ppp_oe.c to ppp_oe.h)
+
+  2010-05-16: Simon Goldschmidt
+  * opt.h, memp_std.h, dns.h/.c: DNS_LOCAL_HOSTLIST_IS_DYNAMIC uses its own
+    MEMP pool instead of the heap
+
+  2010-05-13: Simon Goldschmidt
+  * tcp.c, udp.c: task #6995: Implement SO_REUSEADDR (correctly), added
+    new option SO_REUSE_RXTOALL to pass received UDP broadcast/multicast
+    packets to more than one pcb.
+
+  2010-05-02: Simon Goldschmidt
+  * netbuf.h/.c, sockets.c, api_msg.c: use checksum-on-copy for sending
+    UDP data for LWIP_NETIF_TX_SINGLE_PBUF==1
+
+  2010-04-30: Simon Goldschmidt
+  * udp.h/.c, pbuf.h/.c: task #6849: added udp_send(_to/_if) functions that
+    take a precalculated checksum, added pbuf_fill_chksum() to copy data
+    into a pbuf and at the same time calculating the checksum for that data
+
+  2010-04-29: Simon Goldschmidt
+  * ip_addr.h, etharp.h/.c, autoip.c: Create overridable macros for copying
+    2-byte-aligned IP addresses and MAC addresses
+
+  2010-04-28: Patch by Bill Auerbach
+  * ip.c: Inline generating IP checksum to save a function call
+
+  2010-04-14: Simon Goldschmidt
+  * tcpip.h/.c, timers.c: Added an overridable define to get informed when the
+    tcpip_thread processes messages or timeouts to implement a watchdog.
+
+  2010-03-28: Simon Goldschmidt
+  * ip_frag.c: create a new (contiguous) PBUF_RAM for every outgoing
+    fragment if LWIP_NETIF_TX_SINGLE_PBUF==1
+
+  2010-03-27: Simon Goldschmidt
+  * etharp.c: Speedup TX by moving code from find_entry to etharp_output/
+    etharp_query to prevent unnecessary function calls (inspired by
+    patch #7135).
+
+  2010-03-20: Simon Goldschmidt
+  * opt.h, tcpip.c/.h: Added an option to disable tcpip_(un)timeout code
+    since the linker cannot do this automatically to save space.
+
+  2010-03-20: Simon Goldschmidt
+  * opt.h, etharp.c/.h: Added support for static ARP table entries
+
+  2010-03-14: Simon Goldschmidt
+  * tcp_impl.h, tcp_out.c, inet_chksum.h/.c: task #6849: Calculate checksum
+    when creating TCP segments, not when (re-)transmitting them.
+
+  2010-03-07: Simon Goldschmidt
+  * sockets.c: bug #28775 (select/event_callback: only check select_cb_list
+    on change) plus use SYS_LIGHTWEIGHT_PROT to protect the select code.
+    This should speed up receiving data on sockets as the select code in
+    event_callback is only executed when select is waiting.
+
+  2010-03-06: Simon Goldschmidt
+  * tcp_out.c: task #7013 (Create option to have all packets delivered to
+    netif->output in one piece): Always copy to try to create single pbufs
+    in tcp_write.
+
+  2010-03-06: Simon Goldschmidt
+  * api.h, api_lib.c, sockets.c: task #10167 (sockets: speed up TCP recv
+    by not allocating a netbuf): added function netconn_recv_tcp_pbuf()
+    for tcp netconns to receive pbufs, not netbufs; use that function
+    for tcp sockets.
+
+  2010-03-05: Jakob Ole Stoklundsen / Simon Goldschmidt
+  * opt.h, tcp.h, tcp_impl.h, tcp.c, tcp_in.c, tcp_out.c: task #7040:
+    Work on tcp_enqueue: Don't waste memory when chaining segments,
+    added option TCP_OVERSIZE to prevent creating many small pbufs when
+    calling tcp_write with many small blocks of data. Instead, pbufs are
+    allocated larger than needed and the space is used for later calls to
+    tcp_write.
+
+  2010-02-21: Simon Goldschmidt
+  * stats.c/.h: Added const char* name to mem- and memp-stats for easier
+    debugging.
+
+  2010-02-21: Simon Goldschmidt
+  * tcp.h (and usages), added tcp_impl.h: Splitted API and internal
+    implementation of tcp to make API usage cleare to application programmers
+
+  2010-02-14: Simon Goldschmidt/Stephane Lesage
+  * ip_addr.h: Improved some defines working on ip addresses, added faster
+    macro to copy addresses that cannot be NULL
+
+  2010-02-13: Simon Goldschmidt
+  * api.h, api_lib.c, api_msg.c, sockets.c: task #7865 (implement non-
+    blocking send operation)
+
+  2010-02-12: Simon Goldschmidt
+  * sockets.c/.h: Added a minimal version of posix fctl() to have a
+    standardised way to set O_NONBLOCK for nonblocking sockets.
+
+  2010-02-12: Simon Goldschmidt
+  * dhcp.c/.h, autoip.c/.h: task #10139 (Prefer statically allocated
+    memory): added autoip_set_struct() and dhcp_set_struct() to let autoip
+    and dhcp work with user-allocated structs instead of callin mem_malloc
+
+  2010-02-12: Simon Goldschmidt/Jeff Barber
+  * tcp.c/h: patch #6865 (SO_REUSEADDR for TCP): if pcb.so_options has
+    SOF_REUSEADDR set, allow binding to endpoint in TIME_WAIT
+
+  2010-02-12: Simon Goldschmidt
+  * sys layer: task #10139 (Prefer statically allocated memory): converted
+    mbox and semaphore functions to take pointers to sys_mbox_t/sys_sem_t;
+    converted sys_mbox_new/sys_sem_new to take pointers and return err_t;
+    task #7212: Add Mutex concept in sys_arch (define LWIP_COMPAT_MUTEX
+    to let sys.h use binary semaphores instead of mutexes - as before)
+
+  2010-02-09: Simon Goldschmidt (Simon Kallweit)
+  * timers.c/.h: Added function sys_restart_timeouts() from patch #7085
+    (Restart system timeout handling)
+
+  2010-02-09: Simon Goldschmidt
+  * netif.c/.h, removed loopif.c/.h: task #10153 (Integrate loopif into
+    netif.c) - loopif does not have to be created by the port any more,
+    just define LWIP_HAVE_LOOPIF to 1.
+
+  2010-02-08: Simon Goldschmidt
+  * inet.h, ip_addr.c/.h: Added reentrant versions of inet_ntoa/ipaddr_ntoa
+    inet_ntoa_r/ipaddr_ntoa_r
+
+  2010-02-08: Simon Goldschmidt
+  * netif.h: Added netif_s/get_igmp_mac_filter() macros
+
+  2010-02-05: Simon Goldschmidt
+  * netif.h: Added function-like macros to get/set the hostname on a netif
+
+  2010-02-04: Simon Goldschmidt
+  * nearly every file: Replaced struct ip_addr by typedef ip_addr_t to
+    make changing the actual implementation behind the typedef easier.
+
+  2010-02-01: Simon Goldschmidt
+  * opt.h, memp_std.h, dns.h, netdb.c, memp.c: Let netdb use a memp pool
+    for allocating memory when getaddrinfo() is called.
+
+  2010-01-31: Simon Goldschmidt
+  * dhcp.h, dhcp.c: Reworked the code that parses DHCP options: parse
+    them once instead of parsing for every option. This also removes
+    the need for mem_malloc from dhcp_recv and makes it possible to
+    correctly retrieve the BOOTP file.
+
+  2010-01-30: simon Goldschmidt
+  * sockets.c: Use SYS_LIGHTWEIGHT_PROT instead of a semaphore to protect
+    the sockets array.
+
+  2010-01-29: Simon Goldschmidt (patch by Laura Garrett)
+  * api.h, api_msg.c, sockets.c: Added except set support in select
+    (patch #6860)
+
+  2010-01-29: Simon Goldschmidt (patch by Laura Garrett)
+  * api.h, sockets.h, err.h, api_lib.c, api_msg.c, sockets.c, err.c:
+    Add non-blocking support for connect (partly from patch #6860),
+    plus many cleanups in socket & netconn API.
+
+  2010-01-27: Simon Goldschmidt
+  * opt.h, tcp.h, init.c, api_msg.c: Added TCP_SNDQUEUELOWAT corresponding
+    to TCP_SNDLOWAT and added tcp_sndqueuelen() - this fixes bug #28605
+
+  2010-01-26: Simon Goldschmidt
+  * snmp: Use memp pools for snmp instead of the heap; added 4 new pools.
+
+  2010-01-14: Simon Goldschmidt
+  * ppp.c/.h: Fixed bug #27856: PPP: Set netif link- and status-callback
+    by adding ppp_set_netif_statuscallback()/ppp_set_netif_linkcallback()
+
+  2010-01-13: Simon Goldschmidt
+  * mem.c: The heap now may be moved to user-defined memory by defining
+    LWIP_RAM_HEAP_POINTER as a void pointer to that memory's address
+    (patch #6966 and bug #26133)
+
+  2010-01-10: Simon Goldschmidt (Bill Auerbach)
+  * opt.h, memp.c: patch #6822 (Add option to place memory pools in
+    separate arrays)
+
+  2010-01-10: Simon Goldschmidt
+  * init.c, igmp.c: patch #6463 (IGMP - Adding Random Delay): added define
+    LWIP_RAND() for lwip-wide randomization (to be defined in cc.h)
+
+  2009-12-31: Simon Goldschmidt
+  * tcpip.c, init.c, memp.c, sys.c, memp_std.h, sys.h, tcpip.h
+    added timers.c/.h: Separated timer implementation from semaphore/mbox
+    implementation, moved timer implementation to timers.c/.h, timers are
+    now only called from tcpip_thread or by explicitly checking them.
+    (TASK#7235)
+
+  2009-12-27: Simon Goldschmidt
+  * opt.h, etharp.h/.c, init.c, tcpip.c: Added an additional option
+    LWIP_ETHERNET to support ethernet without ARP (necessary for pure PPPoE)
+
+
+  ++ Bugfixes:
+
+  2011-04-20: Simon Goldschmidt
+  * sys_arch.txt: sys_arch_timeouts() is not needed any more.
+
+  2011-04-13: Simon Goldschmidt
+  * tcp.c, udp.c: Fixed bug #33048 (Bad range for IP source port numbers) by
+    using ports in the IANA private/dynamic range (49152 through 65535).
+
+  2011-03-29: Simon Goldschmidt, patch by Emil Lhungdahl:
+  * etharp.h/.c: Fixed broken VLAN support.
+
+  2011-03-27: Simon Goldschmidt
+  * tcp.c: Fixed bug #32926 (TCP_RMV(&tcp_bound_pcbs) is called on unbound tcp
+    pcbs) by checking if the pcb was bound (local_port != 0).
+
+  2011-03-27: Simon Goldschmidt
+  * ppp.c: Fixed bug #32280 (ppp: a pbuf is freed twice)
+
+  2011-03-27: Simon Goldschmidt
+  * sockets.c: Fixed bug #32906: lwip_connect+lwip_send did not work for udp and
+    raw pcbs with LWIP_TCPIP_CORE_LOCKING==1.
+  
+  2011-03-27: Simon Goldschmidt
+  * tcp_out.c: Fixed bug #32820 (Outgoing TCP connections created before route
+    is present never times out) by starting retransmission timer before checking
+    route.
+
+  2011-03-22: Simon Goldschmidt
+  * ppp.c: Fixed bug #32648 (PPP code crashes when terminating a link) by only
+    calling sio_read_abort() if the file descriptor is valid.
+
+  2011-03-14: Simon Goldschmidt
+  * err.h/.c, sockets.c, api_msg.c: fixed bug #31748 (Calling non-blocking connect
+    more than once can render a socket useless) since it mainly involves changing
+    "FATAL" classification of error codes: ERR_USE and ERR_ISCONN just aren't fatal.
+
+  2011-03-13: Simon Goldschmidt
+  * sockets.c: fixed bug #32769 (ESHUTDOWN is linux-specific) by fixing
+    err_to_errno_table (ERR_CLSD: ENOTCONN instead of ESHUTDOWN), ERR_ISCONN:
+    use EALRADY instead of -1
+
+  2011-03-13: Simon Goldschmidt
+  * api_lib.c: netconn_accept: return ERR_ABRT instead of ERR_CLSD if the
+    connection has been aborted by err_tcp (since this is not a normal closing
+    procedure).
+
+  2011-03-13: Simon Goldschmidt
+  * tcp.c: tcp_bind: return ERR_VAL instead of ERR_ISCONN when trying to bind
+    with pcb->state != CLOSED
+
+  2011-02-17: Simon Goldschmidt
+  * rawapi.txt: Fixed bug #32561 tcp_poll argument definition out-of-order in
+    documentation
+
+  2011-02-17: Simon Goldschmidt
+  * many files: Added missing U/UL modifiers to fix 16-bit-arch portability.
+
+  2011-01-24: Simon Goldschmidt
+  * sockets.c: Fixed bug #31741: lwip_select seems to have threading problems
+
+  2010-12-02: Simon Goldschmidt
+  * err.h: Fixed ERR_IS_FATAL so that ERR_WOULDBLOCK is not fatal.
+
+  2010-11-23: Simon Goldschmidt
+  * api.h, api_lib.c, api_msg.c, sockets.c: netconn.recv_avail is only used for
+    LWIP_SO_RCVBUF and ioctl/FIONREAD.
+
+  2010-11-23: Simon Goldschmidt
+  * etharp.c: Fixed bug #31720: ARP-queueing: RFC 1122 recommends to queue at
+    least 1 packet -> ARP_QUEUEING==0 now queues the most recent packet.
+
+  2010-11-23: Simon Goldschmidt
+  * tcp_in.c: Fixed bug #30577: tcp_input: don't discard ACK-only packets after
+    refusing 'refused_data' again.
+  
+  2010-11-22: Simon Goldschmidt
+  * sockets.c: Fixed bug #31590: getsockopt(... SO_ERROR ...) gives EINPROGRESS
+    after a successful nonblocking connection.
+
+  2010-11-22: Simon Goldschmidt
+  * etharp.c: Fixed bug #31722: IP packets sent with an AutoIP source addr
+    must be sent link-local
+
+  2010-11-22: Simon Goldschmidt
+  * timers.c: patch #7329: tcp_timer_needed prototype was ifdef'ed out for
+    LWIP_TIMERS==0
+
+  2010-11-20: Simon Goldschmidt
+  * sockets.c: Fixed bug #31170: lwip_setsockopt() does not set socket number
+
+  2010-11-20: Simon Goldschmidt
+  * sockets.h: Fixed bug #31304: Changed SHUT_RD, SHUT_WR and SHUT_RDWR to
+    resemble other stacks.
+
+  2010-11-20: Simon Goldschmidt
+  * dns.c: Fixed bug #31535: TCP_SND_QUEUELEN must be at least 2 or else
+    no-copy TCP writes will never succeed.
+
+  2010-11-20: Simon Goldschmidt
+  * dns.c: Fixed bug #31701: Error return value from dns_gethostbyname() does
+    not match documentation: return ERR_ARG instead of ERR_VAL if not
+    initialized or wrong argument.
+
+  2010-10-20: Simon Goldschmidt
+  * sockets.h: Fixed bug #31385: sizeof(struct sockaddr) is 30 but should be 16
+
+  2010-10-05: Simon Goldschmidt
+  * dhcp.c: Once again fixed #30038: DHCP/AutoIP cooperation failed when
+    replugging the network cable after an AutoIP address was assigned.
+
+  2010-08-10: Simon Goldschmidt
+  * tcp.c: Fixed bug #30728: tcp_new_port() did not check listen pcbs
+
+  2010-08-03: Simon Goldschmidt
+  * udp.c, raw.c: Don't chain empty pbufs when sending them (fixes bug #30625)
+
+  2010-08-01: Simon Goldschmidt (patch by Greg Renda)
+  * ppp.c: Applied patch #7264 (PPP protocols are rejected incorrectly on big
+    endian architectures)
+  
+  2010-07-28: Simon Goldschmidt
+  * api_lib.c, api_msg.c, sockets.c, mib2.c: Fixed compilation with TCP or UDP
+    disabled.
+  
+  2010-07-27: Simon Goldschmidt
+  * tcp.c: Fixed bug #30565 (tcp_connect() check bound list): that check did no
+    harm but never did anything
+  
+  2010-07-21: Simon Goldschmidt
+  * ip.c: Fixed invalid fix for bug #30402 (CHECKSUM_GEN_IP_INLINE does not
+    add IP options)
+
+  2010-07-16: Kieran Mansley
+  * msg_in.c: Fixed SNMP ASN constant defines to not use ! operator 
+
+  2010-07-10: Simon Goldschmidt
+  * ip.c: Fixed bug #30402: CHECKSUM_GEN_IP_INLINE does not add IP options
+
+  2010-06-30: Simon Goldschmidt
+  * api_msg.c: fixed bug #30300 (shutdown parameter was not initialized in
+    netconn_delete)
+
+  2010-06-28: Kieran Mansley
+  * timers.c remove unportable printing of C function pointers
+
+  2010-06-24: Simon Goldschmidt
+  * init.c, timers.c/.h, opt.h, memp_std.h: From patch #7221: added flag
+    NO_SYS_NO_TIMERS to drop timer support for NO_SYS==1 for easier upgrading
+
+  2010-06-24: Simon Goldschmidt
+  * api(_lib).c/.h, api_msg.c/.h, sockets.c/.h: Fixed bug #10088: Correctly
+    implemented shutdown at socket level.
+
+  2010-06-21: Simon Goldschmidt
+  * pbuf.c/.h, ip_frag.c/.h, opt.h, memp_std.h: Fixed bug #29361 (ip_frag has
+    problems with zero-copy DMA MACs) by adding custom pbufs and implementing
+    custom pbufs that reference other (original) pbufs. Additionally set
+    IP_FRAG_USES_STATIC_BUF=0 as default to be on the safe side.
+
+  2010-06-15: Simon Goldschmidt
+  * dhcp.c: Fixed bug #29970: DHCP endian issue parsing option responses
+
+  2010-06-14: Simon Goldschmidt
+  * autoip.c: Fixed bug #30039: AutoIP does not reuse previous addresses
+
+  2010-06-12: Simon Goldschmidt
+  * dhcp.c: Fixed bug #30038: dhcp_network_changed doesn't reset AUTOIP coop
+    state
+
+  2010-05-17: Simon Goldschmidt
+  * netdb.c: Correctly NULL-terminate h_addr_list
+
+  2010-05-16: Simon Goldschmidt
+  * def.h/.c: changed the semantics of LWIP_PREFIX_BYTEORDER_FUNCS to prevent
+    "symbol already defined" i.e. when linking to winsock
+
+  2010-05-05: Simon Goldschmidt
+  * def.h, timers.c: Fixed bug #29769 (sys_check_timeouts: sys_now() may
+    overflow)
+
+  2010-04-21: Simon Goldschmidt
+  * api_msg.c: Fixed bug #29617 (sometime cause stall on delete listening
+    connection)
+
+  2010-03-28: Luca Ceresoli
+  * ip_addr.c/.h: patch #7143: Add a few missing const qualifiers
+
+  2010-03-27: Luca Ceresoli
+  * mib2.c: patch #7130: remove meaningless const qualifiers
+
+  2010-03-26: Simon Goldschmidt
+  * tcp_out.c: Make LWIP_NETIF_TX_SINGLE_PBUF work for TCP, too
+
+  2010-03-26: Simon Goldschmidt
+  * various files: Fixed compiling with different options disabled (TCP/UDP),
+    triggered by bug #29345; don't allocate acceptmbox if LWIP_TCP is disabled
+
+  2010-03-25: Simon Goldschmidt
+  * sockets.c: Fixed bug #29332: lwip_select() processes readset incorrectly
+
+  2010-03-25: Simon Goldschmidt
+  * tcp_in.c, test_tcp_oos.c: Fixed bug #29080: Correctly handle remote side
+    overrunning our rcv_wnd in ooseq case.
+
+  2010-03-22: Simon Goldschmidt
+  * tcp.c: tcp_listen() did not copy the pcb's prio.
+
+  2010-03-19: Simon Goldschmidt
+  * snmp_msg.c: Fixed bug #29256: SNMP Trap address was not correctly set
+
+  2010-03-14: Simon Goldschmidt
+  * opt.h, etharp.h: Fixed bug #29148 (Incorrect PBUF_POOL_BUFSIZE for ports
+    where ETH_PAD_SIZE > 0) by moving definition of ETH_PAD_SIZE to opt.h
+    and basing PBUF_LINK_HLEN on it.
+
+  2010-03-08: Simon Goldschmidt
+  * netif.c, ipv4/ip.c: task #10241 (AutoIP: don't break existing connections
+    when assiging routable address): when checking incoming packets and
+    aborting existing connection on address change, filter out link-local
+    addresses.
+
+  2010-03-06: Simon Goldschmidt
+  * sockets.c: Fixed LWIP_NETIF_TX_SINGLE_PBUF for LWIP_TCPIP_CORE_LOCKING
+
+  2010-03-06: Simon Goldschmidt
+  * ipv4/ip.c: Don't try to forward link-local addresses
+
+  2010-03-06: Simon Goldschmidt
+  * etharp.c: Fixed bug #29087: etharp: don't send packets for LinkLocal-
+    addresses to gw
+
+  2010-03-05: Simon Goldschmidt
+  * dhcp.c: Fixed bug #29072: Correctly set ciaddr based on message-type
+    and state.
+
+  2010-03-05: Simon Goldschmidt
+  * api_msg.c: Correctly set TCP_WRITE_FLAG_MORE when netconn_write is split
+    into multiple calls to tcp_write.    
+
+  2010-02-21: Simon Goldschmidt
+  * opt.h, mem.h, dns.c: task #10140: Remove DNS_USES_STATIC_BUF (keep
+    the implementation of DNS_USES_STATIC_BUF==1)
+
+  2010-02-20: Simon Goldschmidt
+  * tcp.h, tcp.c, tcp_in.c, tcp_out.c: Task #10088: Correctly implement
+    close() vs. shutdown(). Now the application does not get any more
+    recv callbacks after calling tcp_close(). Added tcp_shutdown().
+
+  2010-02-19: Simon Goldschmidt
+  * mem.c/.h, pbuf.c: Renamed mem_realloc() to mem_trim() to prevent
+    confusion with realloc()
+
+  2010-02-15: Simon Goldschmidt/Stephane Lesage
+  * netif.c/.h: Link status does not depend on LWIP_NETIF_LINK_CALLBACK
+    (fixes bug #28899)
+
+  2010-02-14: Simon Goldschmidt
+  * netif.c: Fixed bug #28877 (Duplicate ARP gratuitous packet with
+    LWIP_NETIF_LINK_CALLBACK set on) by only sending if both link- and
+    admin-status of a netif are up
+
+  2010-02-14: Simon Goldschmidt
+  * opt.h: Disable ETHARP_TRUST_IP_MAC by default since it slows down packet
+    reception and is not really necessary
+
+  2010-02-14: Simon Goldschmidt
+  * etharp.c/.h: Fixed ARP input processing: only add a new entry if a
+    request was directed as us (RFC 826, Packet Reception), otherwise
+    only update existing entries; internalized some functions
+
+  2010-02-14: Simon Goldschmidt
+  * netif.h, etharp.c, tcpip.c: Fixed bug #28183 (ARP and TCP/IP cannot be
+    disabled on netif used for PPPoE) by adding a new netif flag
+    (NETIF_FLAG_ETHERNET) that tells the stack the device is an ethernet
+    device but prevents usage of ARP (so that ethernet_input can be used
+    for PPPoE).
+
+  2010-02-12: Simon Goldschmidt
+  * netif.c: netif_set_link_up/down: only do something if the link state
+    actually changes
+
+  2010-02-12: Simon Goldschmidt/Stephane Lesage
+  * api_msg.c: Fixed bug #28865 (Cannot close socket/netconn in non-blocking
+    connect)
+
+  2010-02-12: Simon Goldschmidt
+  * mem.h: Fixed bug #28866 (mem_realloc function defined in mem.h)
+
+  2010-02-09: Simon Goldschmidt
+  * api_lib.c, api_msg.c, sockets.c, api.h, api_msg.h: Fixed bug #22110
+   (recv() makes receive window update for data that wasn't received by
+    application)
+
+  2010-02-09: Simon Goldschmidt/Stephane Lesage
+  * sockets.c: Fixed bug #28853 (lwip_recvfrom() returns 0 on receive time-out
+    or any netconn_recv() error)
+
+  2010-02-09: Simon Goldschmidt
+  * ppp.c: task #10154 (PPP: Update snmp in/out counters for tx/rx packets)
+
+  2010-02-09: Simon Goldschmidt
+  * netif.c: For loopback packets, adjust the stats- and snmp-counters
+    for the loopback netif.
+
+  2010-02-08: Simon Goldschmidt
+  * igmp.c/.h, ip.h: Moved most defines from igmp.h to igmp.c for clarity
+    since they are not used anywhere else.
+
+  2010-02-08: Simon Goldschmidt (Stè¾¿phane Lesage)
+  * igmp.c, igmp.h, stats.c, stats.h: Improved IGMP stats
+    (patch from bug #28798)
+
+  2010-02-08: Simon Goldschmidt (Stè¾¿phane Lesage)
+  * igmp.c: Fixed bug #28798 (Error in "Max Response Time" processing) and
+    another bug when LWIP_RAND() returns zero.
+
+  2010-02-04: Simon Goldschmidt
+  * nearly every file: Use macros defined in ip_addr.h (some of them new)
+    to work with IP addresses (preparation for bug #27352 - Change ip_addr
+    from struct to typedef (u32_t) - and better code).
+
+  2010-01-31: Simon Goldschmidt
+  * netif.c: Don't call the link-callback from netif_set_up/down() since
+    this invalidly retriggers DHCP.
+
+  2010-01-29: Simon Goldschmidt
+  * ip_addr.h, inet.h, def.h, inet.c, def.c, more: Cleanly separate the
+    portability file inet.h and its contents from the stack: moved htonX-
+    functions to def.h (and the new def.c - they are not ipv4 dependent),
+    let inet.h depend on ip_addr.h and not the other way round.
+    This fixes bug #28732.
+
+  2010-01-28: Kieran Mansley
+  * tcp.c: Ensure ssthresh >= 2*MSS
+
+  2010-01-27: Simon Goldschmidt
+  * tcp.h, tcp.c, tcp_in.c: Fixed bug #27871: Calling tcp_abort() in recv
+    callback can lead to accessing unallocated memory. As a consequence,
+    ERR_ABRT means the application has called tcp_abort()!
+
+  2010-01-25: Simon Goldschmidt
+  * snmp_structs.h, msg_in.c: Partly fixed bug #22070 (MIB_OBJECT_WRITE_ONLY
+    not implemented in SNMP): write-only or not-accessible are still
+    returned by getnext (though not by get)
+
+  2010-01-24: Simon Goldschmidt
+  * snmp: Renamed the private mib node from 'private' to 'mib_private' to
+    not use reserved C/C++ keywords
+
+  2010-01-23: Simon Goldschmidt
+  * sockets.c: Fixed bug #28716: select() returns 0 after waiting for less
+    than 1 ms
+
+  2010-01-21: Simon Goldschmidt
+  * tcp.c, api_msg.c: Fixed bug #28651 (tcp_connect: no callbacks called
+    if tcp_enqueue fails) both in raw- and netconn-API
+
+  2010-01-19: Simon Goldschmidt
+  * api_msg.c: Fixed bug #27316: netconn: Possible deadlock in err_tcp
+
+  2010-01-18: Iordan Neshev/Simon Goldschmidt
+  * src/netif/ppp: reorganised PPP sourcecode to 2.3.11 including some
+    bugfix backports from 2.4.x.
+
+  2010-01-18: Simon Goldschmidt
+  * mem.c: Fixed bug #28679: mem_realloc calculates mem_stats wrong
+
+  2010-01-17: Simon Goldschmidt
+  * api_lib.c, api_msg.c, (api_msg.h, api.h, sockets.c, tcpip.c):
+    task #10102: "netconn: clean up conn->err threading issues" by adding
+    error return value to struct api_msg_msg
+
+  2010-01-17: Simon Goldschmidt
+  * api.h, api_lib.c, sockets.c: Changed netconn_recv() and netconn_accept()
+    to return err_t (bugs #27709 and #28087)
+
+  2010-01-14: Simon Goldschmidt
+  * ...: Use typedef for function prototypes throughout the stack.
+
+  2010-01-13: Simon Goldschmidt
+  * api_msg.h/.c, api_lib.c: Fixed bug #26672 (close connection when receive
+    window = 0) by correctly draining recvmbox/acceptmbox
+
+  2010-01-11: Simon Goldschmidt
+  * pap.c: Fixed bug #13315 (PPP PAP authentication can result in
+    erroneous callbacks) by copying the code from recent pppd
+
+  2010-01-10: Simon Goldschmidt
+  * raw.c: Fixed bug #28506 (raw_bind should filter received packets)
+
+  2010-01-10: Simon Goldschmidt
+  * tcp.h/.c: bug #28127 (remove call to tcp_output() from tcp_ack(_now)())
+
+  2010-01-08: Simon Goldschmidt
+  * sockets.c: Fixed bug #28519 (lwip_recvfrom bug with len > 65535)
+
+  2010-01-08: Simon Goldschmidt
+  * dns.c: Copy hostname for DNS_LOCAL_HOSTLIST_IS_DYNAMIC==1 since string
+    passed to dns_local_addhost() might be volatile
+
+  2010-01-07: Simon Goldschmidt
+  * timers.c, tcp.h: Call tcp_timer_needed() with NO_SYS==1, too
+
+  2010-01-06: Simon Goldschmidt
+  * netdb.h: Fixed bug #28496: missing include guards in netdb.h
+
+  2009-12-31: Simon Goldschmidt
+  * many ppp files: Reorganised PPP source code from ucip structure to pppd
+    structure to easily compare our code against the pppd code (around v2.3.1)
+
+  2009-12-27: Simon Goldschmidt
+  * tcp_in.c: Another fix for bug #28241 (ooseq processing) and adapted
+    unit test
+
+
+(STABLE-1.3.2)
+
+  ++ New features:
+
+  2009-10-27 Simon Goldschmidt/Stephan Lesage
+  * netifapi.c/.h: Added netifapi_netif_set_addr()
+
+  2009-10-07 Simon Goldschmidt/Fabian Koch
+  * api_msg.c, netbuf.c/.h, opt.h: patch #6888: Patch for UDP Netbufs to
+    support dest-addr and dest-port (optional: LWIP_NETBUF_RECVINFO)
+
+  2009-08-26 Simon Goldschmidt/Simon Kallweit
+  * slipif.c/.h: bug #26397: SLIP polling support
+
+  2009-08-25 Simon Goldschmidt
+  * opt.h, etharp.h/.c: task #9033: Support IEEE 802.1q tagged frame (VLAN),
+    New configuration options ETHARP_SUPPORT_VLAN and ETHARP_VLAN_CHECK.
+
+  2009-08-25 Simon Goldschmidt
+  * ip_addr.h, netdb.c: patch #6900: added define ip_ntoa(struct ip_addr*)
+
+  2009-08-24 Jakob Stoklund Olesen
+  * autoip.c, dhcp.c, netif.c: patch #6725: Teach AutoIP and DHCP to respond
+    to netif_set_link_up().
+
+  2009-08-23 Simon Goldschmidt
+  * tcp.h/.c: Added function tcp_debug_state_str() to convert a tcp state
+    to a human-readable string.
+
+  ++ Bugfixes:
+
+  2009-12-24: Kieran Mansley
+  * tcp_in.c Apply patches from Oleg Tyshev to improve OOS processing
+    (BUG#28241)
+
+  2009-12-06: Simon Goldschmidt
+  * ppp.h/.c: Fixed bug #27079 (Yet another leak in PPP): outpacket_buf can
+    be statically allocated (like in ucip)
+
+  2009-12-04: Simon Goldschmidt (patch by Ioardan Neshev)
+  * pap.c: patch #6969: PPP: missing PAP authentication UNTIMEOUT
+
+  2009-12-03: Simon Goldschmidt
+  * tcp.h, tcp_in.c, tcp_out.c: Fixed bug #28106: dup ack for fast retransmit
+    could have non-zero length
+
+  2009-12-02: Simon Goldschmidt
+  * tcp_in.c: Fixed bug #27904: TCP sends too many ACKs: delay resetting
+    tcp_input_pcb until after calling the pcb's callbacks
+
+  2009-11-29: Simon Goldschmidt
+  * tcp_in.c: Fixed bug #28054: Two segments with FIN flag on the out-of-
+    sequence queue, also fixed PBUF_POOL leak in the out-of-sequence code
+
+  2009-11-29: Simon Goldschmidt
+  * pbuf.c: Fixed bug #28064: pbuf_alloc(PBUF_POOL) is not thread-safe by
+    queueing a call into tcpip_thread to free ooseq-bufs if the pool is empty
+
+  2009-11-26: Simon Goldschmidt
+  * tcp.h: Fixed bug #28098: Nagle can prevent fast retransmit from sending
+    segment
+
+  2009-11-26: Simon Goldschmidt
+  * tcp.h, sockets.c: Fixed bug #28099: API required to disable Nagle
+    algorithm at PCB level
+
+  2009-11-22: Simon Goldschmidt
+  * tcp_out.c: Fixed bug #27905: FIN isn't combined with data on unsent
+
+  2009-11-22: Simon Goldschmidt (suggested by Bill Auerbach)
+  * tcp.c: tcp_alloc: prevent increasing stats.err for MEMP_TCP_PCB when
+    reusing time-wait pcb
+
+  2009-11-20: Simon Goldschmidt (patch by Albert Bartel)
+  * sockets.c: Fixed bug #28062: Data received directly after accepting
+    does not wake up select
+
+  2009-11-11: Simon Goldschmidt
+  * netdb.h: Fixed bug #27994: incorrect define for freeaddrinfo(addrinfo)
+
+  2009-10-30: Simon Goldschmidt
+  * opt.h: Increased default value for TCP_MSS to 536, updated default
+    value for TCP_WND to 4*TCP_MSS to keep delayed ACK working.
+
+  2009-10-28: Kieran Mansley
+  * tcp_in.c, tcp_out.c, tcp.h: re-work the fast retransmission code
+    to follow algorithm from TCP/IP Illustrated
+
+  2009-10-27: Kieran Mansley
+  * tcp_in.c: fix BUG#27445: grow cwnd with every duplicate ACK
+
+  2009-10-25: Simon Goldschmidt
+  * tcp.h: bug-fix in the TCP_EVENT_RECV macro (has to call tcp_recved if
+    pcb->recv is NULL to keep rcv_wnd correct)
+
+  2009-10-25: Simon Goldschmidt
+  * tcp_in.c: Fixed bug #26251: RST process in TIME_WAIT TCP state
+
+  2009-10-23: Simon Goldschmidt (David Empson)
+  * tcp.c: Fixed bug #27783: Silly window avoidance for small window sizes
+
+  2009-10-21: Simon Goldschmidt
+  * tcp_in.c: Fixed bug #27215: TCP sent() callback gives leading and
+    trailing 1 byte len (SYN/FIN)
+
+  2009-10-21: Simon Goldschmidt
+  * tcp_out.c: Fixed bug #27315: zero window probe and FIN
+
+  2009-10-19: Simon Goldschmidt
+  * dhcp.c/.h: Minor code simplification (don't store received pbuf, change
+    conditional code to assert where applicable), check pbuf length before
+    testing for valid reply
+
+  2009-10-19: Simon Goldschmidt
+  * dhcp.c: Removed most calls to udp_connect since they aren't necessary
+    when using udp_sendto_if() - always stay connected to IP_ADDR_ANY.
+
+  2009-10-16: Simon Goldschmidt
+  * ip.c: Fixed bug #27390: Source IP check in ip_input() causes it to drop
+    valid DHCP packets -> allow 0.0.0.0 as source address when LWIP_DHCP is
+    enabled
+
+  2009-10-15: Simon Goldschmidt (Oleg Tyshev)
+  * tcp_in.c: Fixed bug #27329: dupacks by unidirectional data transmit
+
+  2009-10-15: Simon Goldschmidt
+  * api_lib.c: Fixed bug #27709: conn->err race condition on netconn_recv()
+    timeout
+
+  2009-10-15: Simon Goldschmidt
+  * autoip.c: Fixed bug #27704: autoip starts with wrong address
+    LWIP_AUTOIP_CREATE_SEED_ADDR() returned address in host byte order instead
+    of network byte order
+
+  2009-10-11 Simon Goldschmidt (Jæ¦rg Kesten)
+  * tcp_out.c: Fixed bug #27504: tcp_enqueue wrongly concatenates segments
+    which are not consecutive when retransmitting unacked segments
+
+  2009-10-09 Simon Goldschmidt
+  * opt.h: Fixed default values of some stats to only be enabled if used
+    Fixes bug #27338: sys_stats is defined when NO_SYS = 1
+
+  2009-08-30 Simon Goldschmidt
+  * ip.c: Fixed bug bug #27345: "ip_frag() does not use the LWIP_NETIF_LOOPBACK
+    function" by checking for loopback before calling ip_frag
+
+  2009-08-25 Simon Goldschmidt
+  * dhcp.c: fixed invalid dependency to etharp_query if DHCP_DOES_ARP_CHECK==0
+
+  2009-08-23 Simon Goldschmidt
+  * ppp.c: bug #27078: Possible memory leak in pppInit()
+
+  2009-08-23 Simon Goldschmidt
+  * netdb.c, dns.c: bug #26657: DNS, if host name is "localhost", result
+    is error.
+
+  2009-08-23 Simon Goldschmidt
+  * opt.h, init.c: bug #26649: TCP fails when TCP_MSS > TCP_SND_BUF
+    Fixed wrong parenthesis, added check in init.c
+
+  2009-08-23 Simon Goldschmidt
+  * ppp.c: bug #27266: wait-state debug message in pppMain occurs every ms
+
+  2009-08-23 Simon Goldschmidt
+  * many ppp files: bug #27267: Added include to string.h where needed
+
+  2009-08-23 Simon Goldschmidt
+  * tcp.h: patch #6843: tcp.h macro optimization patch (for little endian)
+
+
+(STABLE-1.3.1)
+
+  ++ New features:
+
+  2009-05-10 Simon Goldschmidt
+  * opt.h, sockets.c, pbuf.c, netbuf.h, pbuf.h: task #7013: Added option
+    LWIP_NETIF_TX_SINGLE_PBUF to try to create transmit packets from only
+    one pbuf to help MACs that don't support scatter-gather DMA.
+
+  2009-05-09 Simon Goldschmidt
+  * icmp.h, icmp.c: Shrinked ICMP code, added option to NOT check icoming
+    ECHO pbuf for size (just use it): LWIP_ICMP_ECHO_CHECK_INPUT_PBUF_LEN
+
+  2009-05-05 Simon Goldschmidt, Jakob Stoklund Olesen
+  * ip.h, ip.c: Added ip_current_netif() & ip_current_header() to receive
+    extended info about the currently received packet.
+
+  2009-04-27 Simon Goldschmidt
+  * sys.h: Made SYS_LIGHTWEIGHT_PROT and sys_now() work with NO_SYS=1
+
+  2009-04-25 Simon Goldschmidt
+  * mem.c, opt.h: Added option MEM_USE_POOLS_TRY_BIGGER_POOL to try the next
+    bigger malloc pool if one is empty (only usable with MEM_USE_POOLS).
+
+  2009-04-21 Simon Goldschmidt
+  * dns.c, init.c, dns.h, opt.h: task #7507, patch #6786: DNS supports static
+    hosts table. New configuration options DNS_LOCAL_HOSTLIST and
+    DNS_LOCAL_HOSTLIST_IS_DYNAMIC. Also, DNS_LOOKUP_LOCAL_EXTERN() can be defined
+    as an external function for lookup.
+
+  2009-04-15 Simon Goldschmidt
+  * dhcp.c: patch #6763: Global DHCP XID can be redefined to something more unique
+
+  2009-03-31 Kieran Mansley
+  * tcp.c, tcp_out.c, tcp_in.c, sys.h, tcp.h, opts.h: add support for
+    TCP timestamp options, off by default.  Rework tcp_enqueue() to
+    take option flags rather than specified option data
+
+  2009-02-18 Simon Goldschmidt
+  * cc.h: Added printf formatter for size_t: SZT_F
+
+  2009-02-16 Simon Goldschmidt (patch by Rishi Khan)
+  * icmp.c, opt.h: patch #6539: (configurable) response to broadcast- and multicast
+    pings
+
+  2009-02-12 Simon Goldschmidt
+  * init.h: Added LWIP_VERSION to get the current version of the stack
+
+  2009-02-11 Simon Goldschmidt (suggested by Gottfried Spitaler)
+  * opt.h, memp.h/.c: added MEMP_MEM_MALLOC to use mem_malloc/mem_free instead
+    of the pool allocator (can save code size with MEM_LIBC_MALLOC if libc-malloc
+    is otherwise used)
+
+  2009-01-28 Jonathan Larmour (suggested by Bill Bauerbach)
+  * ipv4/inet_chksum.c, ipv4/lwip/inet_chksum.h: inet_chksum_pseudo_partial()
+  is only used by UDPLITE at present, so conditionalise it.
+
+  2008-12-03 Simon Goldschmidt (base on patch from Luca Ceresoli)
+  * autoip.c: checked in (slightly modified) patch #6683: Customizable AUTOIP
+    "seed" address. This should reduce AUTOIP conflicts if
+    LWIP_AUTOIP_CREATE_SEED_ADDR is overridden.
+
+  2008-10-02 Jonathan Larmour and Rishi Khan
+  * sockets.c (lwip_accept): Return EWOULDBLOCK if would block on non-blocking
+    socket.
+
+  2008-06-30 Simon Goldschmidt
+  * mem.c, opt.h, stats.h: fixed bug #21433: Calling mem_free/pbuf_free from
+    interrupt context isn't safe: LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT allows
+    mem_free to run between mem_malloc iterations. Added illegal counter for
+    mem stats.
+
+  2008-06-27 Simon Goldschmidt
+  * stats.h/.c, some other files: patch #6483: stats module improvement:
+    Added defines to display each module's statistic individually, added stats
+    defines for MEM, MEMP and SYS modules, removed (unused) rexmit counter.
+
+  2008-06-17 Simon Goldschmidt
+  * err.h: patch #6459: Made err_t overridable to use a more efficient type
+    (define LWIP_ERR_T in cc.h)
+
+  2008-06-17 Simon Goldschmidt
+  * slipif.c: patch #6480: Added a configuration option for slipif for symmetry
+    to loopif
+
+  2008-06-17 Simon Goldschmidt (patch by Luca Ceresoli)
+  * netif.c, loopif.c, ip.c, netif.h, loopif.h, opt.h: Checked in slightly
+    modified version of patch # 6370: Moved loopif code to netif.c so that
+    loopback traffic is supported on all netifs (all local IPs).
+    Added option to limit loopback packets for each netifs.
+
+
+  ++ Bugfixes:
+  2009-08-12 Kieran Mansley
+  * tcp_in.c, tcp.c: Fix bug #27209: handle trimming of segments when
+    out of window or out of order properly
+
+  2009-08-12 Kieran Mansley
+  * tcp_in.c: Fix bug #27199: use snd_wl2 instead of snd_wl1
+
+  2009-07-28 Simon Goldschmidt
+  * mem.h: Fixed bug #27105: "realloc() cannot replace mem_realloc()"s
+
+  2009-07-27 Kieran Mansley
+  * api.h api_msg.h netdb.h sockets.h: add missing #include directives
+
+  2009-07-09 Kieran Mansley
+  * api_msg.c, sockets.c, api.h: BUG23240 use signed counters for
+    recv_avail and don't increment counters until message successfully
+    sent to mbox
+
+  2009-06-25 Kieran Mansley
+  * api_msg.c api.h: BUG26722: initialise netconn write variables 
+    in netconn_alloc
+
+  2009-06-25 Kieran Mansley
+  * tcp.h: BUG26879: set ret value in TCP_EVENT macros when function is not set
+
+  2009-06-25 Kieran Mansley
+  * tcp.c, tcp_in.c, tcp_out.c, tcp.h: BUG26301 and BUG26267: correct
+    simultaneous close behaviour, and make snd_nxt have the same meaning 
+    as in the RFCs.
+
+  2009-05-12 Simon Goldschmidt
+  * etharp.h, etharp.c, netif.c: fixed bug #26507: "Gratuitous ARP depends on
+    arp_table / uses etharp_query" by adding etharp_gratuitous()
+
+  2009-05-12 Simon Goldschmidt
+  * ip.h, ip.c, igmp.c: bug #26487: Added ip_output_if_opt that can add IP options
+    to the IP header (used by igmp_ip_output_if)
+
+  2009-05-06 Simon Goldschmidt
+  * inet_chksum.c: On little endian architectures, use LWIP_PLATFORM_HTONS (if
+    defined) for SWAP_BYTES_IN_WORD to speed up checksumming.
+
+  2009-05-05 Simon Goldschmidt
+  * sockets.c: bug #26405: Prematurely released semaphore causes lwip_select()
+    to crash
+
+  2009-05-04 Simon Goldschmidt
+  * init.c: snmp was not initialized in lwip_init()
+
+  2009-05-04 Frè¾¿dè¾¿ric Bernon
+  * dhcp.c, netbios.c: Changes if IP_SOF_BROADCAST is enabled.
+
+  2009-05-03 Simon Goldschmidt
+  * tcp.h: bug #26349: Nagle algorithm doesn't send although segment is full
+    (and unsent->next == NULL)
+
+  2009-05-02 Simon Goldschmidt
+  * tcpip.h, tcpip.c: fixed tcpip_untimeout (does not need the time, broken after
+    1.3.0 in CVS only) - fixes compilation of ppp_oe.c
+
+  2009-05-02 Simon Goldschmidt
+  * msg_in.c: fixed bug #25636: SNMPSET value is ignored for integer fields
+
+  2009-05-01 Simon Goldschmidt
+  * pap.c: bug #21680: PPP upap_rauthnak() drops legal NAK packets
+
+  2009-05-01 Simon Goldschmidt
+  * ppp.c: bug #24228: Memory corruption with PPP and DHCP
+
+  2009-04-29 Frè¾¿dè¾¿ric Bernon
+  * raw.c, udp.c, init.c, opt.h, ip.h, sockets.h: bug #26309: Implement the
+    SO(F)_BROADCAST filter for all API layers. Avoid the unindented reception
+    of broadcast packets even when this option wasn't set. Port maintainers
+    which want to enable this filter have to set IP_SOF_BROADCAST=1 in opt.h.
+    If you want this option also filter broadcast on recv operations, you also
+    have to set IP_SOF_BROADCAST_RECV=1 in opt.h.
+
+  2009-04-28 Simon Goldschmidt, Jakob Stoklund Olesen
+  * dhcp.c: patch #6721, bugs #25575, #25576: Some small fixes to DHCP and
+    DHCP/AUTOIP cooperation
+
+  2009-04-25 Simon Goldschmidt, Oleg Tyshev
+  * tcp_out.c: bug #24212: Deadlocked tcp_retransmit due to exceeded pcb->cwnd
+    Fixed by sorting the unsent and unacked queues (segments are inserted at the
+    right place in tcp_output and tcp_rexmit).
+
+  2009-04-25 Simon Goldschmidt
+  * memp.c, mem.c, memp.h, mem_std.h: bug #26213 "Problem with memory allocation
+    when debugging": memp_sizes contained the wrong sizes (including sanity
+    regions); memp pools for MEM_USE_POOLS were too small
+
+  2009-04-24 Simon Goldschmidt, Frè¾¿dè¾¿ric Bernon
+  * inet.c: patch #6765: Fix a small problem with the last changes (incorrect
+    behavior, with with ip address string not ended by a '\0', a space or a
+    end of line)
+
+  2009-04-19 Simon Goldschmidt
+  * rawapi.txt: Fixed bug #26069: Corrected documentation: if tcp_connect fails,
+    pcb->err is called, not pcb->connected (with an error code).
+
+  2009-04-19 Simon Goldschmidt
+  * tcp_out.c: Fixed bug #26236: "TCP options (timestamp) don't work with
+    no-copy-tcpwrite": deallocate option data, only concat segments with same flags
+
+  2009-04-19 Simon Goldschmidt
+  * tcp_out.c: Fixed bug #25094: "Zero-length pbuf" (options are now allocated
+    in the header pbuf, not the data pbuf)
+
+  2009-04-18 Simon Goldschmidt
+  * api_msg.c: fixed bug #25695: Segmentation fault in do_writemore()
+
+  2009-04-15 Simon Goldschmidt
+  * sockets.c: tried to fix bug #23559: lwip_recvfrom problem with tcp
+
+  2009-04-15 Simon Goldschmidt
+  * dhcp.c: task #9192: mem_free of dhcp->options_in and dhcp->msg_in
+
+  2009-04-15 Simon Goldschmidt
+  * ip.c, ip6.c, tcp_out.c, ip.h: patch #6808: Add a utility function
+    ip_hinted_output() (for smaller code mainly)
+
+  2009-04-15 Simon Goldschmidt
+  * inet.c: patch #6765: Supporting new line characters in inet_aton()
+
+  2009-04-15 Simon Goldschmidt
+  * dhcp.c: patch #6764: DHCP rebind and renew did not send hostnam option;
+    Converted constant OPTION_MAX_MSG_SIZE to netif->mtu, check if netif->mtu
+    is big enough in dhcp_start
+
+  2009-04-15 Simon Goldschmidt
+  * netbuf.c: bug #26027: netbuf_chain resulted in pbuf memory leak
+
+  2009-04-15 Simon Goldschmidt
+  * sockets.c, ppp.c: bug #25763: corrected 4 occurrences of SMEMCPY to MEMCPY
+
+  2009-04-15 Simon Goldschmidt
+  * sockets.c: bug #26121: set_errno can be overridden
+
+  2009-04-09 Kieran Mansley (patch from Luca Ceresoli <lucaceresoli>)
+  * init.c, opt.h: Patch#6774 TCP_QUEUE_OOSEQ breaks compilation when
+    LWIP_TCP==0
+
+  2009-04-09 Kieran Mansley (patch from Roy Lee <roylee17>)
+  * tcp.h: Patch#6802 Add do-while-clauses to those function like
+    macros in tcp.h
+
+  2009-03-31 Kieran Mansley
+  * tcp.c, tcp_in.c, tcp_out.c, tcp.h, opt.h: Rework the way window
+    updates are calculated and sent (BUG20515)
+
+  * tcp_in.c: cope with SYN packets received during established states,
+    and retransmission of initial SYN.
+
+  * tcp_out.c: set push bit correctly when tcp segments are merged
+
+  2009-03-27 Kieran Mansley
+  * tcp_out.c set window correctly on probes (correcting change made
+    yesterday)
+
+  2009-03-26 Kieran Mansley
+  * tcp.c, tcp_in.c, tcp.h: add tcp_abandon() to cope with dropping
+    connections where no reset required (bug #25622)
+
+  * tcp_out.c: set TCP_ACK flag on keepalive and zero window probes 
+    (bug #20779)
+
+  2009-02-18 Simon Goldschmidt (Jonathan Larmour and Bill Auerbach)
+  * ip_frag.c: patch #6528: the buffer used for IP_FRAG_USES_STATIC_BUF could be
+    too small depending on MEM_ALIGNMENT
+
+  2009-02-16 Simon Goldschmidt
+  * sockets.h/.c, api_*.h/.c: fixed arguments of socket functions to match the standard;
+    converted size argument of netconn_write to 'size_t'
+
+  2009-02-16 Simon Goldschmidt
+  * tcp.h, tcp.c: fixed bug #24440: TCP connection close problem on 64-bit host
+    by moving accept callback function pointer to TCP_PCB_COMMON
+
+  2009-02-12 Simon Goldschmidt
+  * dhcp.c: fixed bug #25345 (DHCPDECLINE is sent with "Maximum message size"
+    option)
+
+  2009-02-11 Simon Goldschmidt
+  * dhcp.c: fixed bug #24480 (releasing old udp_pdb and pbuf in dhcp_start)
+
+  2009-02-11 Simon Goldschmidt
+  * opt.h, api_msg.c: added configurable default valud for netconn->recv_bufsize:
+    RECV_BUFSIZE_DEFAULT (fixes bug #23726: pbuf pool exhaustion on slow recv())
+
+  2009-02-10 Simon Goldschmidt
+  * tcp.c: fixed bug #25467: Listen backlog is not reset on timeout in SYN_RCVD:
+    Accepts_pending is decrease on a corresponding listen pcb when a connection
+    in state SYN_RCVD is close.
+
+  2009-01-28 Jonathan Larmour
+  * pbuf.c: reclaim pbufs from TCP out-of-sequence segments if we run
+    out of pool pbufs.
+
+  2008-12-19 Simon Goldschmidt
+  * many files: patch #6699: fixed some warnings on platform where sizeof(int) == 2 
+
+  2008-12-10 Tamas Somogyi, Frè¾¿dè¾¿ric Bernon
+  * sockets.c: fixed bug #25051: lwip_recvfrom problem with udp: fromaddr and
+    port uses deleted netbuf.
+
+  2008-10-18 Simon Goldschmidt
+  * tcp_in.c: fixed bug ##24596: Vulnerability on faulty TCP options length
+    in tcp_parseopt
+
+  2008-10-15 Simon Goldschmidt
+  * ip_frag.c: fixed bug #24517: IP reassembly crashes on unaligned IP headers
+    by packing the struct ip_reass_helper.
+
+  2008-10-03 David Woodhouse, Jonathan Larmour
+  * etharp.c (etharp_arp_input): Fix type aliasing problem copying ip address.
+
+  2008-10-02 Jonathan Larmour
+  * dns.c: Hard-code structure sizes, to avoid issues on some compilers where
+    padding is included.
+
+  2008-09-30 Jonathan Larmour
+  * sockets.c (lwip_accept): check addr isn't NULL. If it's valid, do an
+    assertion check that addrlen isn't NULL.
+
+  2008-09-30 Jonathan Larmour
+  * tcp.c: Fix bug #24227, wrong error message in tcp_bind.
+
+  2008-08-26 Simon Goldschmidt
+  * inet.h, ip_addr.h: fixed bug #24132: Cross-dependency between ip_addr.h and
+    inet.h -> moved declaration of struct in_addr from ip_addr.h to inet.h
+
+  2008-08-14 Simon Goldschmidt
+  * api_msg.c: fixed bug #23847: do_close_internal references freed memory (when
+    tcp_close returns != ERR_OK)
+
+  2008-07-08 Frè¾¿dè¾¿ric Bernon
+  * stats.h: Fix some build bugs introduced with patch #6483 (missing some parameters
+    in macros, mainly if MEM_STATS=0 and MEMP_STATS=0).
+
+  2008-06-24 Jonathan Larmour
+  * tcp_in.c: Fix for bug #23693 as suggested by Art R. Ensure cseg is unused
+    if tcp_seg_copy fails.
+
+  2008-06-17 Simon Goldschmidt
+  * inet_chksum.c: Checked in some ideas of patch #6460 (loop optimizations)
+    and created defines for swapping bytes and folding u32 to u16.
+
+  2008-05-30 Kieran Mansley
+  * tcp_in.c Remove redundant "if" statement, and use real rcv_wnd
+    rather than rcv_ann_wnd when deciding if packets are in-window.
+    Contributed by <arasmussen@consultant.datasys.swri.edu>
+
+  2008-05-30 Kieran Mansley
+  * mem.h: Fix BUG#23254.  Change macro definition of mem_* to allow
+    passing as function pointers when MEM_LIBC_MALLOC is defined.
+
+  2008-05-09 Jonathan Larmour
+  * err.h, err.c, sockets.c: Fix bug #23119: Reorder timeout error code to
+    stop it being treated as a fatal error.
+
+  2008-04-15 Simon Goldschmidt
+  * dhcp.c: fixed bug #22804: dhcp_stop doesn't clear NETIF_FLAG_DHCP
+    (flag now cleared)
+
+  2008-03-27 Simon Goldschmidt
+  * mem.c, tcpip.c, tcpip.h, opt.h: fixed bug #21433 (Calling mem_free/pbuf_free
+    from interrupt context isn't safe): set LWIP_USE_HEAP_FROM_INTERRUPT to 1
+    in lwipopts.h or use pbuf_free_callback(p)/mem_free_callback(m) to free pbufs
+    or heap memory from interrupt context
+
+  2008-03-26 Simon Goldschmidt
+  * tcp_in.c, tcp.c: fixed bug #22249: division by zero could occur if a remote
+    host sent a zero mss as TCP option.
+
+
+(STABLE-1.3.0)
+
+  ++ New features:
+
+  2008-03-10 Jonathan Larmour
+  * inet_chksum.c: Allow choice of one of the sample algorithms to be
+    made from lwipopts.h. Fix comment on how to override LWIP_CHKSUM.
+
+  2008-01-22 Frè¾¿dè¾¿ric Bernon
+  * tcp.c, tcp_in.c, tcp.h, opt.h: Rename LWIP_CALCULATE_EFF_SEND_MSS in 
+    TCP_CALCULATE_EFF_SEND_MSS to have coherent TCP options names.
+
+  2008-01-14 Frè¾¿dè¾¿ric Bernon
+  * rawapi.txt, api_msg.c, tcp.c, tcp_in.c, tcp.h: changes for task #7675 "Enable
+    to refuse data on a TCP_EVENT_RECV call". Important, behavior changes for the
+    tcp_recv callback (see rawapi.txt).
+
+  2008-01-14 Frè¾¿dè¾¿ric Bernon, Marc Chaland
+  * ip.c: Integrate patch #6369" ip_input : checking before realloc".
+  
+  2008-01-12 Frè¾¿dè¾¿ric Bernon
+  * tcpip.h, tcpip.c, api.h, api_lib.c, api_msg.c, sockets.c: replace the field
+    netconn::sem per netconn::op_completed like suggested for the task #7490
+    "Add return value to sys_mbox_post".
+
+  2008-01-12 Frè¾¿dè¾¿ric Bernon
+  * api_msg.c, opt.h: replace DEFAULT_RECVMBOX_SIZE per DEFAULT_TCP_RECVMBOX_SIZE,
+    DEFAULT_UDP_RECVMBOX_SIZE and DEFAULT_RAW_RECVMBOX_SIZE (to optimize queues
+    sizes), like suggested for the task #7490 "Add return value to sys_mbox_post".
+
+  2008-01-10 Frè¾¿dè¾¿ric Bernon
+  * tcpip.h, tcpip.c: add tcpip_callback_with_block function for the task #7490
+    "Add return value to sys_mbox_post". tcpip_callback is always defined as
+    "blocking" ("block" parameter = 1).
+
+  2008-01-10 Frè¾¿dè¾¿ric Bernon
+  * tcpip.h, tcpip.c, api.h, api_lib.c, api_msg.c, sockets.c: replace the field
+    netconn::mbox (sys_mbox_t) per netconn::sem (sys_sem_t) for the task #7490
+    "Add return value to sys_mbox_post".
+
+  2008-01-05 Frè¾¿dè¾¿ric Bernon
+  * sys_arch.txt, api.h, api_lib.c, api_msg.h, api_msg.c, tcpip.c, sys.h, opt.h:
+    Introduce changes for task #7490 "Add return value to sys_mbox_post" with some
+    modifications in the sys_mbox api: sys_mbox_new take a "size" parameters which
+    indicate the number of pointers query by the mailbox. There is three defines
+    in opt.h to indicate sizes for tcpip::mbox, netconn::recvmbox, and for the 
+    netconn::acceptmbox. Port maintainers, you can decide to just add this new 
+    parameter in your implementation, but to ignore it to keep the previous behavior.
+    The new sys_mbox_trypost function return a value to know if the mailbox is
+    full or if the message is posted. Take a look to sys_arch.txt for more details.
+    This new function is used in tcpip_input (so, can be called in an interrupt
+    context since the function is not blocking), and in recv_udp and recv_raw.
+
+  2008-01-04 Frè¾¿dè¾¿ric Bernon, Simon Goldschmidt, Jonathan Larmour
+  * rawapi.txt, api.h, api_lib.c, api_msg.h, api_msg.c, sockets.c, tcp.h, tcp.c,
+    tcp_in.c, init.c, opt.h: rename backlog options with TCP_ prefix, limit the
+    "backlog" parameter in an u8_t, 0 is interpreted as "smallest queue", add
+    documentation in the rawapi.txt file.
+
+  2007-12-31 Kieran Mansley (based on patch from Per-Henrik Lundbolm)
+  * tcp.c, tcp_in.c, tcp_out.c, tcp.h: Add TCP persist timer
+
+  2007-12-31 Frè¾¿dè¾¿ric Bernon, Luca Ceresoli
+  * autoip.c, etharp.c: ip_addr.h: Integrate patch #6348: "Broadcast ARP packets
+    in autoip". The change in etharp_raw could be removed, since all calls to
+    etharp_raw use ethbroadcast for the "ethdst_addr" parameter. But it could be
+    wrong in the future.
+
+  2007-12-30 Frè¾¿dè¾¿ric Bernon, Tom Evans
+  * ip.c: Fix bug #21846 "LwIP doesn't appear to perform any IP Source Address
+    Filtering" reported by Tom Evans.
+
+  2007-12-21 Frè¾¿dè¾¿ric Bernon, Simon Goldschmidt, Jonathan Larmour
+  * tcp.h, opt.h, api.h, api_msg.h, tcp.c, tcp_in.c, api_lib.c, api_msg.c,
+    sockets.c, init.c: task #7252: Implement TCP listen backlog: Warning: raw API
+    applications have to call 'tcp_accepted(pcb)' in their accept callback to
+    keep accepting new connections.
+
+  2007-12-13 Frè¾¿dè¾¿ric Bernon
+  * api_msg.c, err.h, err.c, sockets.c, dns.c, dns.h: replace "enum dns_result"
+    by err_t type. Add a new err_t code "ERR_INPROGRESS".
+
+  2007-12-12 Frè¾¿dè¾¿ric Bernon
+  * dns.h, dns.c, opt.h: move DNS options to the "right" place. Most visibles
+    are the one which have ram usage.
+
+  2007-12-05 Frè¾¿dè¾¿ric Bernon
+  * netdb.c: add a LWIP_DNS_API_HOSTENT_STORAGE option to decide to use a static
+    set of variables (=0) or a local one (=1). In this last case, your port should
+    provide a function "struct hostent* sys_thread_hostent( struct hostent* h)"
+    which have to do a copy of "h" and return a pointer ont the "per-thread" copy.
+
+  2007-12-03 Simon Goldschmidt
+  * ip.c: ip_input: check if a packet is for inp first before checking all other
+    netifs on netif_list (speeds up packet receiving in most cases)
+
+  2007-11-30 Simon Goldschmidt
+  * udp.c, raw.c: task #7497: Sort lists (pcb, netif, ...) for faster access
+    UDP: move a (connected) pcb selected for input to the front of the list of
+    pcbs so that it is found faster next time. Same for RAW pcbs that have eaten
+    a packet.
+
+  2007-11-28 Simon Goldschmidt
+  * etharp.c, stats.c, stats.h, opt.h: Introduced ETHARP_STATS
+
+  2007-11-25 Simon Goldschmidt
+  * dhcp.c: dhcp_unfold_reply() uses pbuf_copy_partial instead of its own copy
+    algorithm.
+
+  2007-11-24 Simon Goldschmidt
+  * netdb.h, netdb.c, sockets.h/.c: Moved lwip_gethostbyname from sockets.c
+    to the new file netdb.c; included lwip_getaddrinfo.
+
+  2007-11-21 Simon Goldschmidt
+  * tcp.h, opt.h, tcp.c, tcp_in.c: implemented calculating the effective send-mss
+    based on the MTU of the netif used to send. Enabled by default. Disable by
+    setting LWIP_CALCULATE_EFF_SEND_MSS to 0. This fixes bug #21492.
+
+  2007-11-19 Frè¾¿dè¾¿ric Bernon
+  * api_msg.c, dns.h, dns.c: Implement DNS_DOES_NAME_CHECK option (check if name
+    received match the name query), implement DNS_USES_STATIC_BUF (the place where
+    copy dns payload to parse the response), return an error if there is no place
+    for a new query, and fix some minor problems.
+
+  2007-11-16 Simon Goldschmidt
+  * new files: ipv4/inet.c, ipv4/inet_chksum.c, ipv6/inet6.c
+    removed files: core/inet.c, core/inet6.c
+    Moved inet files into ipv4/ipv6 directory; splitted inet.c/inet.h into
+    inet and chksum part; changed includes in all lwIP files as appropriate
+
+  2007-11-16 Simon Goldschmidt
+  * api.h, api_msg.h, api_lib.c, api_msg.c, socket.h, socket.c: Added sequential
+    dns resolver function for netconn api (netconn_gethostbyname) and socket api
+    (gethostbyname/gethostbyname_r).
+
+  2007-11-15 Jim Pettinato, Frè¾¿dè¾¿ric Bernon
+  * opt.h, init.c, tcpip.c, dhcp.c, dns.h, dns.c: add DNS client for simple name
+    requests with RAW api interface. Initialization is done in lwip_init() with
+    build time options. DNS timer is added in tcpip_thread context. DHCP can set
+    DNS server ip addresses when options are received. You need to set LWIP_DNS=1
+    in your lwipopts.h file (LWIP_DNS=0 in opt.h). DNS_DEBUG can be set to get
+    some traces with LWIP_DEBUGF. Sanity check have been added. There is a "todo"
+    list with points to improve.
+
+  2007-11-06 Simon Goldschmidt
+  * opt.h, mib2.c: Patch #6215: added ifAdminStatus write support (if explicitly
+    enabled by defining SNMP_SAFE_REQUESTS to 0); added code to check link status
+    for ifOperStatus if LWIP_NETIF_LINK_CALLBACK is defined.
+
+  2007-11-06 Simon Goldschmidt
+  * api.h, api_msg.h and dependent files: Task #7410: Removed the need to include
+    core header files in api.h (ip/tcp/udp/raw.h) to hide the internal
+    implementation from netconn api applications.
+
+  2007-11-03 Frè¾¿dè¾¿ric Bernon
+  * api.h, api_lib.c, api_msg.c, sockets.c, opt.h: add SO_RCVBUF option for UDP &
+    RAW netconn. You need to set LWIP_SO_RCVBUF=1 in your lwipopts.h (it's disabled
+    by default). Netconn API users can use the netconn_recv_bufsize macro to access
+    it. This is a first release which have to be improve for TCP. Note it used the
+    netconn::recv_avail which need to be more "thread-safe" (note there is already
+    the problem for FIONREAD with lwip_ioctl/ioctlsocket).
+
+  2007-11-01 Frè¾¿dè¾¿ric Bernon, Marc Chaland
+  * sockets.h, sockets.c, api.h, api_lib.c, api_msg.h, api_msg.c, tcp.h, tcp_out.c:
+    Integrate "patch #6250 : MSG_MORE flag for send". MSG_MORE is used at socket api
+    layer, NETCONN_MORE at netconn api layer, and TCP_WRITE_FLAG_MORE at raw api
+    layer. This option enable to delayed TCP PUSH flag on multiple "write" calls.
+    Note that previous "copy" parameter for "write" APIs is now called "apiflags".
+
+  2007-10-24 Frè¾¿dè¾¿ric Bernon
+  * api.h, api_lib.c, api_msg.c: Add macro API_EVENT in the same spirit than 
+    TCP_EVENT_xxx macros to get a code more readable. It could also help to remove
+    some code (like we have talk in "patch #5919 : Create compile switch to remove
+    select code"), but it could be done later.
+
+  2007-10-08 Simon Goldschmidt
+  * many files: Changed initialization: many init functions are not needed any
+    more since we now rely on the compiler initializing global and static
+    variables to zero!
+
+  2007-10-06 Simon Goldschmidt
+  * ip_frag.c, memp.c, mib2.c, ip_frag.h, memp_std.h, opt.h: Changed IP_REASSEMBLY
+    to enqueue the received pbufs so that multiple packets can be reassembled
+    simultaneously and no static reassembly buffer is needed.
+
+  2007-10-05 Simon Goldschmidt
+  * tcpip.c, etharp.h, etharp.c: moved ethernet_input from tcpip.c to etharp.c so
+    all netifs (or ports) can use it.
+
+  2007-10-05 Frè¾¿dè¾¿ric Bernon
+  * netifapi.h, netifapi.c: add function netifapi_netif_set_default. Change the 
+    common function to reduce a little bit the footprint (for all functions using
+    only the "netif" parameter).
+
+  2007-10-03 Frè¾¿dè¾¿ric Bernon
+  * netifapi.h, netifapi.c: add functions netifapi_netif_set_up, netifapi_netif_set_down,
+    netifapi_autoip_start and netifapi_autoip_stop. Use a common function to reduce
+    a little bit the footprint (for all functions using only the "netif" parameter).
+
+  2007-09-15 Frè¾¿dè¾¿ric Bernon
+  * udp.h, udp.c, sockets.c: Changes for "#20503 IGMP Improvement". Add IP_MULTICAST_IF
+    option in socket API, and a new field "multicast_ip" in "struct udp_pcb" (for
+    netconn and raw API users), only if LWIP_IGMP=1. Add getsockopt processing for
+    IP_MULTICAST_TTL and IP_MULTICAST_IF.
+
+  2007-09-10 Frè¾¿dè¾¿ric Bernon
+  * snmp.h, mib2.c: enable to remove SNMP timer (which consumne several cycles
+    even when it's not necessary). snmp_agent.txt tell to call snmp_inc_sysuptime()
+    each 10ms (but, it's intrusive if you use sys_timeout feature). Now, you can
+    decide to call snmp_add_sysuptime(100) each 1000ms (which is bigger "step", but
+    call to a lower frequency). Or, you can decide to not call snmp_inc_sysuptime()
+    or snmp_add_sysuptime(), and to define the SNMP_GET_SYSUPTIME(sysuptime) macro.
+    This one is undefined by default in mib2.c. SNMP_GET_SYSUPTIME is called inside
+    snmp_get_sysuptime(u32_t *value), and enable to change "sysuptime" value only
+    when it's queried (any direct call to "sysuptime" is changed by a call to 
+    snmp_get_sysuptime).
+
+  2007-09-09 Frè¾¿dè¾¿ric Bernon, Bill Florac
+  * igmp.h, igmp.c, netif.h, netif.c, ip.c: To enable to have interfaces with IGMP,
+    and others without it, there is a new NETIF_FLAG_IGMP flag to set in netif->flags
+    if you want IGMP on an interface. igmp_stop() is now called inside netif_remove().
+    igmp_report_groups() is now called inside netif_set_link_up() (need to have
+    LWIP_NETIF_LINK_CALLBACK=1) to resend reports once the link is up (avoid to wait
+    the next query message to receive the matching multicast streams).
+
+  2007-09-08 Frè¾¿dè¾¿ric Bernon
+  * sockets.c, ip.h, api.h, tcp.h: declare a "struct ip_pcb" which only contains
+    IP_PCB. Add in the netconn's "pcb" union a "struct ip_pcb *ip;" (no size change).
+    Use this new field to access to common pcb fields (ttl, tos, so_options, etc...).
+    Enable to access to these fields with LWIP_TCP=0.
+
+  2007-09-05 Frè¾¿dè¾¿ric Bernon
+  * udp.c, ipv4/icmp.c, ipv4/ip.c, ipv6/icmp.c, ipv6/ip6.c, ipv4/icmp.h,
+    ipv6/icmp.h, opt.h: Integrate "task #7272 : LWIP_ICMP option". The new option
+    LWIP_ICMP enable/disable ICMP module inside the IP stack (enable per default).
+    Be careful, disabling ICMP make your product non-compliant to RFC1122, but
+    help to reduce footprint, and to reduce "visibility" on the Internet.
+
+  2007-09-05 Frè¾¿dè¾¿ric Bernon, Bill Florac
+  * opt.h, sys.h, tcpip.c, slipif.c, ppp.c, sys_arch.txt: Change parameters list
+    for sys_thread_new (see "task #7252 : Create sys_thread_new_ex()"). Two new
+    parameters have to be provided: a task name, and a task stack size. For this
+    one, since it's platform dependant, you could define the best one for you in
+    your lwipopts.h. For port maintainers, you can just add these new parameters
+    in your sys_arch.c file, and but it's not mandatory, use them in your OS
+    specific functions.
+
+  2007-09-05 Frè¾¿dè¾¿ric Bernon
+  * inet.c, autoip.c, msg_in.c, msg_out.c, init.c: Move some build time checkings
+    inside init.c for task #7142 "Sanity check user-configurable values".
+
+  2007-09-04 Frè¾¿dè¾¿ric Bernon, Bill Florac
+  * igmp.h, igmp.c, memp_std.h, memp.c, init.c, opt.h: Replace mem_malloc call by
+    memp_malloc, and use a new MEMP_NUM_IGMP_GROUP option (see opt.h to define the
+    value). It will avoid potential fragmentation problems, use a counter to know
+    how many times a group is used on an netif, and free it when all applications
+    leave it. MEMP_NUM_IGMP_GROUP got 8 as default value (and init.c got a sanity
+    check if LWIP_IGMP!=0).
+
+  2007-09-03 Frè¾¿dè¾¿ric Bernon
+  * igmp.h, igmp.c, sockets.c, api_msg.c: Changes for "#20503 IGMP Improvement".
+    Initialize igmp_mac_filter to NULL in netif_add (this field should be set in
+    the netif's "init" function). Use the "imr_interface" field (for socket layer)
+    and/or the "interface" field (for netconn layer), for join/leave operations.
+    The igmp_join/leavegroup first parameter change from a netif to an ipaddr.
+    This field could be a netif's ipaddr, or "any" (same meaning than ip_addr_isany).
+
+  2007-08-30 Frè¾¿dè¾¿ric Bernon
+  * Add netbuf.h, netbuf.c, Change api.h, api_lib.c: #7249 "Split netbuf functions
+    from api/api_lib". Now netbuf API is independant of netconn, and can be used
+    with other API (application based on raw API, or future "socket2" API). Ports
+    maintainers just have to add src/api/netbuf.c in their makefile/projects.
+
+  2007-08-30 Frè¾¿dè¾¿ric Bernon, Jonathan Larmour
+  * init.c: Add first version of lwip_sanity_check for task #7142 "Sanity check
+    user-configurable values".
+
+  2007-08-29 Frè¾¿dè¾¿ric Bernon
+  * igmp.h, igmp.c, tcpip.c, init.c, netif.c: change igmp_init and add igmp_start.
+    igmp_start is call inside netif_add. Now, igmp initialization is in the same
+    spirit than the others modules. Modify some IGMP debug traces.
+
+  2007-08-29 Frè¾¿dè¾¿ric Bernon
+  * Add init.h, init.c, Change opt.h, tcpip.c: Task  #7213 "Add a lwip_init function"
+    Add lwip_init function to regroup all modules initializations, and to provide
+    a place to add code for task #7142 "Sanity check user-configurable values".
+    Ports maintainers should remove direct initializations calls from their code,
+    and add init.c in their makefiles. Note that lwip_init() function is called
+    inside tcpip_init, but can also be used by raw api users since all calls are
+    disabled when matching options are disabled. Also note that their is new options
+    in opt.h, you should configure in your lwipopts.h (they are enabled per default).
+
+  2007-08-26 Marc Boucher
+  * api_msg.c: do_close_internal(): Reset the callbacks and arg (conn) to NULL
+    since they can under certain circumstances be called with an invalid conn
+    pointer after the connection has been closed (and conn has been freed). 
+
+  2007-08-25 Frè¾¿dè¾¿ric Bernon (Artem Migaev's Patch)
+  * netif.h, netif.c: Integrate "patch #6163 : Function to check if link layer is up".
+    Add a netif_is_link_up() function if LWIP_NETIF_LINK_CALLBACK option is set.
+
+  2007-08-22 Frè¾¿dè¾¿ric Bernon
+  * netif.h, netif.c, opt.h: Rename LWIP_NETIF_CALLBACK in LWIP_NETIF_STATUS_CALLBACK
+    to be coherent with new LWIP_NETIF_LINK_CALLBACK option before next release.
+
+  2007-08-22 Frè¾¿dè¾¿ric Bernon
+  * tcpip.h, tcpip.c, ethernetif.c, opt.h: remove options ETHARP_TCPIP_INPUT &
+    ETHARP_TCPIP_ETHINPUT, now, only "ethinput" code is supported, even if the 
+    name is tcpip_input (we keep the name of 1.2.0 function).
+
+  2007-08-17 Jared Grubb
+  * memp_std.h, memp.h, memp.c, mem.c, stats.c: (Task #7136) Centralize mempool 
+    settings into new memp_std.h and optional user file lwippools.h. This adds
+    more dynamic mempools, and allows the user to create an arbitrary number of
+    mempools for mem_malloc.
+
+  2007-08-16 Marc Boucher
+  * api_msg.c: Initialize newconn->state to NETCONN_NONE in accept_function;
+    otherwise it was left to NETCONN_CLOSE and sent_tcp() could prematurely
+    close the connection.
+
+  2007-08-16 Marc Boucher
+  * sockets.c: lwip_accept(): check netconn_peer() error return.
+
+  2007-08-16 Marc Boucher
+  * mem.c, mem.h: Added mem_calloc().
+
+  2007-08-16 Marc Boucher
+  * tcpip.c, tcpip.h memp.c, memp.h: Added distinct memp (MEMP_TCPIP_MSG_INPKT)
+    for input packets to prevent floods from consuming all of MEMP_TCPIP_MSG
+    and starving other message types.
+    Renamed MEMP_TCPIP_MSG to MEMP_TCPIP_MSG_API
+
+  2007-08-16 Marc Boucher
+  * pbuf.c, pbuf.h, etharp.c, tcp_in.c, sockets.c: Split pbuf flags in pbuf
+    type and flgs (later renamed to flags).
+    Use enum pbuf_flag as pbuf_type.  Renumber PBUF_FLAG_*.
+    Improved lwip_recvfrom().  TCP push now propagated.
+
+  2007-08-16 Marc Boucher
+  * ethernetif.c, contrib/ports/various: ethbroadcast now a shared global
+    provided by etharp.
+
+  2007-08-16 Marc Boucher
+  * ppp_oe.c ppp_oe.h, auth.c chap.c fsm.c lcp.c ppp.c ppp.h,
+    etharp.c ethernetif.c, etharp.h, opt.h tcpip.h, tcpip.c:
+    Added PPPoE support and various PPP improvements.
+
+  2007-07-25 Simon Goldschmidt
+  * api_lib.c, ip_frag.c, pbuf.c, api.h, pbuf.h: Introduced pbuf_copy_partial,
+    making netbuf_copy_partial use this function.
+
+  2007-07-25 Simon Goldschmidt
+  * tcp_in.c: Fix bug #20506: Slow start / initial congestion window starts with
+    2 * mss (instead of 1 * mss previously) to comply with some newer RFCs and
+    other stacks.
+
+  2007-07-13 Jared Grubb (integrated by Frè¾¿dè¾¿ric Bernon)
+  * opt.h, netif.h, netif.c, ethernetif.c: Add new configuration option to add
+    a link callback in the netif struct, and functions to handle it. Be carefull
+    for port maintainers to add the NETIF_FLAG_LINK_UP flag (like in ethernetif.c)
+    if you want to be sure to be compatible with future changes...
+
+  2007-06-30 Frè¾¿dè¾¿ric Bernon
+  * sockets.h, sockets.c: Implement MSG_PEEK flag for recv/recvfrom functions.
+
+  2007-06-21 Simon Goldschmidt
+  * etharp.h, etharp.c: Combined etharp_request with etharp_raw for both
+    LWIP_AUTOIP =0 and =1 to remove redundant code.
+
+  2007-06-21 Simon Goldschmidt
+  * mem.c, memp.c, mem.h, memp.h, opt.h: task #6863: Introduced the option
+    MEM_USE_POOLS to use 4 pools with different sized elements instead of a
+    heap. This both prevents memory fragmentation and gives a higher speed
+    at the cost of more memory consumption. Turned off by default.
+
+  2007-06-21 Simon Goldschmidt
+  * api_lib.c, api_msg.c, api.h, api_msg.h: Converted the length argument of
+    netconn_write (and therefore also api_msg_msg.msg.w.len) from u16_t into
+    int to be able to send a bigger buffer than 64K with one time (mainly
+    used from lwip_send).
+
+  2007-06-21 Simon Goldschmidt
+  * tcp.h, api_msg.c: Moved the nagle algorithm from netconn_write/do_write
+    into a define (tcp_output_nagle) in tcp.h to provide it to raw api users, too.
+
+  2007-06-21 Simon Goldschmidt
+  * api.h, api_lib.c, api_msg.c: Fixed bug #20021: Moved sendbuf-processing in
+    netconn_write from api_lib.c to api_msg.c to also prevent multiple context-
+    changes on low memory or empty send-buffer.
+
+  2007-06-18 Simon Goldschmidt
+  * etharp.c, etharp.h: Changed etharp to use a defined hardware address length
+    of 6 to avoid loading netif->hwaddr_len every time (since this file is only
+    used for ethernet and struct eth_addr already had a defined length of 6).
+
+  2007-06-17 Simon Goldschmidt
+  * sockets.c, sockets.h: Implemented socket options SO_NO_CHECK for UDP sockets
+    to disable UDP checksum generation on transmit.
+
+  2007-06-13 Frè¾¿dè¾¿ric Bernon, Simon Goldschmidt
+  * debug.h, api_msg.c: change LWIP_ERROR to use it to check errors like invalid
+    pointers or parameters, and let the possibility to redefined it in cc.h. Use
+    this macro to check "conn" parameter in api_msg.c functions.
+
+  2007-06-11 Simon Goldschmidt
+  * sockets.c, sockets.h: Added UDP lite support for sockets
+
+  2007-06-10 Simon Goldschmidt
+  * udp.h, opt.h, api_msg.c, ip.c, udp.c: Included switch LWIP_UDPLITE (enabled
+    by default) to switch off UDP-Lite support if not needed (reduces udp.c code
+    size)
+
+  2007-06-09 Dominik Spies (integrated by Frè¾¿dè¾¿ric Bernon)
+  * autoip.h, autoip.c, dhcp.h, dhcp.c, netif.h, netif.c, etharp.h, etharp.c, opt.h:
+    AutoIP implementation available for IPv4, with new options LWIP_AUTOIP and
+    LWIP_DHCP_AUTOIP_COOP if you want to cooperate with DHCP. Some tips to adapt
+    (see TODO mark in the source code).
+
+  2007-06-09 Simon Goldschmidt
+  * etharp.h, etharp.c, ethernetif.c: Modified order of parameters for
+    etharp_output() to match netif->output so etharp_output() can be used
+    directly as netif->output to save one function call.
+
+  2007-06-08 Simon Goldschmidt
+  * netif.h, ethernetif.c, slipif.c, loopif.c: Added define
+    NETIF_INIT_SNMP(netif, type, speed) to initialize per-netif snmp variables,
+    added initialization of those to ethernetif, slipif and loopif.
+
+  2007-05-18 Simon Goldschmidt
+  * opt.h, ip_frag.c, ip_frag.h, ip.c: Added option IP_FRAG_USES_STATIC_BUF
+    (defaulting to off for now) that can be set to 0 to send fragmented
+    packets by passing PBUF_REFs down the stack.
+
+  2007-05-23 Frè¾¿dè¾¿ric Bernon
+  * api_lib.c: Implement SO_RCVTIMEO for accept and recv on TCP
+    connections, such present in patch #5959.
+
+  2007-05-23 Frè¾¿dè¾¿ric Bernon
+  * api.h, api_lib.c, api_msg.c, sockets.c: group the different NETCONN_UDPxxx
+    code in only one part...
+
+  2007-05-18 Simon Goldschmidt
+  * opt.h, memp.h, memp.c: Added option MEMP_OVERFLOW_CHECK to check for memp
+    elements to overflow. This is achieved by adding some bytes before and after
+    each pool element (increasing their size, of course), filling them with a
+    prominent value and checking them on freeing the element.
+    Set it to 2 to also check every element in every pool each time memp_malloc()
+    or memp_free() is called (slower but more helpful).
+
+  2007-05-10 Simon Goldschmidt
+  * opt.h, memp.h, memp.c, pbuf.c (see task #6831): use a new memp pool for
+    PBUF_POOL pbufs instead of the old pool implementation in pbuf.c to reduce
+    code size.
+
+  2007-05-11 Frè¾¿dè¾¿ric Bernon
+  * sockets.c, api_lib.c, api_msg.h, api_msg.c, netifapi.h, netifapi.c, tcpip.c:
+    Include a function pointer instead of a table index in the message to reduce
+    footprint. Disable some part of lwip_send and lwip_sendto if some options are
+    not set (LWIP_TCP, LWIP_UDP, LWIP_RAW).
+
+  2007-05-10 Simon Goldschmidt
+  * *.h (except netif/ppp/*.h): Included patch #5448: include '#ifdef __cplusplus
+    \ extern "C" {' in all header files. Now you can write your application using
+    the lwIP stack in C++ and simply #include the core files. Note I have left
+    out the netif/ppp/*h header files for now, since I don't know which files are
+    included by applications and which are for internal use only.
+
+  2007-05-09 Simon Goldschmidt
+  * opt.h, *.c/*.h: Included patch #5920: Create define to override C-library
+    memcpy. 2 Defines are created: MEMCPY() for normal memcpy, SMEMCPY() for
+    situations where some compilers might inline the copy and save a function
+    call. Also replaced all calls to memcpy() with calls to (S)MEMCPY().
+
+  2007-05-08 Simon Goldschmidt
+  * mem.h: If MEM_LIBC_MALLOC==1, allow the defines (e.g. mem_malloc() -> malloc())
+    to be overriden in case the C-library malloc implementation is not protected
+    against concurrent access.
+
+  2007-05-04 Simon Goldschmidt (Atte Kojo)
+  * etharp.c: Introduced fast one-entry-cache to speed up ARP lookup when sending
+    multiple packets to the same host.
+
+  2007-05-04 Frè¾¿dè¾¿ric Bernon, Jonathan Larmour
+  * sockets.c, api.h, api_lib.c, api_msg.h, api_msg.c: Fix bug #19162 "lwip_sento: a possible
+    to corrupt remote addr/port connection state". Reduce problems "not enought memory" with
+    netbuf (if we receive lot of datagrams). Improve lwip_sendto (only one exchange between
+    sockets api and api_msg which run in tcpip_thread context). Add netconn_sento function.
+    Warning, if you directly access to "fromaddr" & "fromport" field from netbuf struct,
+    these fields are now renamed "addr" & "port".
+
+  2007-04-11 Jonathan Larmour
+  * sys.h, api_lib.c: Provide new sys_mbox_tryfetch function. Require ports to provide new
+    sys_arch_mbox_tryfetch function to get a message if one is there, otherwise return
+    with SYS_MBOX_EMPTY. sys_arch_mbox_tryfetch can be implemented as a function-like macro
+    by the port in sys_arch.h if desired.
+
+  2007-04-06 Frè¾¿dè¾¿ric Bernon, Simon Goldschmidt
+  * opt.h, tcpip.h, tcpip.c, netifapi.h, netifapi.c: New configuration option LWIP_NETIF_API
+    allow to use thread-safe functions to add/remove netif in list, and to start/stop dhcp
+    clients, using new functions from netifapi.h. Disable as default (no port change to do).
+
+  2007-04-05 Frè¾¿dè¾¿ric Bernon
+  * sockets.c: remplace ENOBUFS errors on alloc_socket by ENFILE to be more BSD compliant.
+
+  2007-04-04 Simon Goldschmidt
+  * arch.h, api_msg.c, dhcp.c, msg_in.c, sockets.c: Introduced #define LWIP_UNUSED_ARG(x)
+    use this for and architecture-independent form to tell the compiler you intentionally
+    are not using this variable. Can be overriden in cc.h.
+
+  2007-03-28 Frè¾¿dè¾¿ric Bernon
+  * opt.h, netif.h, dhcp.h, dhcp.c: New configuration option LWIP_NETIF_HOSTNAME allow to
+    define a hostname in netif struct (this is just a pointer, so, you can use a hardcoded
+    string, point on one of your's ethernetif field, or alloc a string you will free yourself).
+    It will be used by DHCP to register a client hostname, but can also be use when you call
+    snmp_set_sysname.
+
+  2007-03-28 Frè¾¿dè¾¿ric Bernon
+  * netif.h, netif.c: A new NETIF_FLAG_ETHARP flag is defined in netif.h, to allow to 
+    initialize a network interface's flag with. It tell this interface is an ethernet
+    device, and we can use ARP with it to do a "gratuitous ARP" (RFC 3220 "IP Mobility
+    Support for IPv4" section 4.6) when interface is "up" with netif_set_up().
+
+  2007-03-26 Frè¾¿dè¾¿ric Bernon, Jonathan Larmour
+  * opt.h, tcpip.c: New configuration option LWIP_ARP allow to disable ARP init at build
+    time if you only use PPP or SLIP. The default is enable. Note we don't have to call 
+    etharp_init in your port's initilization sequence if you use tcpip.c, because this call
+    is done in tcpip_init function.
+
+  2007-03-22 Frè¾¿dè¾¿ric Bernon
+  * stats.h, stats.c, msg_in.c: Stats counters can be change to u32_t if necessary with the
+    new option LWIP_STATS_LARGE. If you need this option, define LWIP_STATS_LARGE to 1 in
+    your lwipopts.h. More, unused counters are not defined in the stats structs, and not 
+    display by stats_display(). Note that some options (SYS_STATS and RAW_STATS) are defined
+    but never used. Fix msg_in.c with the correct #if test for a stat display.
+
+  2007-03-21 Kieran Mansley
+  * netif.c, netif.h: Apply patch#4197 with some changes (originator: rireland@hmgsl.com). 
+    Provides callback on netif up/down state change.
+
+  2007-03-11 Frè¾¿dè¾¿ric Bernon, Mace Gael, Steve Reynolds
+  * sockets.h, sockets.c, api.h, api_lib.c, api_msg.h, api_msg.c, igmp.h, igmp.c,
+    ip.c, netif.h, tcpip.c, opt.h:
+    New configuration option LWIP_IGMP to enable IGMP processing. Based on only one 
+    filter per all network interfaces. Declare a new function in netif to enable to
+    control the MAC filter (to reduce lwIP traffic processing).
+
+  2007-03-11 Frè¾¿dè¾¿ric Bernon
+  * tcp.h, tcp.c, sockets.c, tcp_out.c, tcp_in.c, opt.h: Keepalive values can
+    be configured at run time with LWIP_TCP_KEEPALIVE, but don't change this
+    unless you know what you're doing (default are RFC1122 compliant). Note
+    that TCP_KEEPIDLE and TCP_KEEPINTVL have to be set in seconds.
+
+  2007-03-08 Frè¾¿dè¾¿ric Bernon
+  * tcp.h: Keepalive values can be configured at compile time, but don't change
+    this unless you know what you're doing (default are RFC1122 compliant).
+
+  2007-03-08 Frè¾¿dè¾¿ric Bernon
+  * sockets.c, api.h, api_lib.c, tcpip.c, sys.h, sys.c, err.c, opt.h:
+    Implement LWIP_SO_RCVTIMEO configuration option to enable/disable SO_RCVTIMEO
+    on UDP sockets/netconn.
+
+  2007-03-08 Simon Goldschmidt
+  * snmp_msg.h, msg_in.c: SNMP UDP ports can be configured at compile time.
+
+  2007-03-06 Frè¾¿dè¾¿ric Bernon
+  * api.h, api_lib.c, sockets.h, sockets.c, tcpip.c, sys.h, sys.c, err.h: 
+    Implement SO_RCVTIMEO on UDP sockets/netconn.
+
+  2007-02-28 Kieran Mansley (based on patch from Simon Goldschmidt)
+  * api_lib.c, tcpip.c, memp.c, memp.h: make API msg structs allocated
+    on the stack and remove the API msg type from memp
+
+  2007-02-26 Jonathan Larmour (based on patch from Simon Goldschmidt)
+  * sockets.h, sockets.c: Move socket initialization to new
+    lwip_socket_init() function.
+    NOTE: this changes the API with ports. Ports will have to be
+    updated to call lwip_socket_init() now.
+
+  2007-02-26 Jonathan Larmour (based on patch from Simon Goldschmidt)
+  * api_lib.c: Use memcpy in netbuf_copy_partial.
+
+
+  ++ Bug fixes:
+
+  2008-03-17 Frè¾¿dè¾¿ric Bernon, Ed Kerekes
+  * igmp.h, igmp.c: Fix bug #22613 "IGMP iphdr problem" (could have
+    some problems to fill the IP header on some targets, use now the
+    ip.h macros to do it).
+
+  2008-03-13 Frè¾¿dè¾¿ric Bernon
+  * sockets.c: Fix bug #22435 "lwip_recvfrom with TCP break;". Using
+    (lwip_)recvfrom with valid "from" and "fromlen" parameters, on a
+    TCP connection caused a crash. Note that using (lwip_)recvfrom
+    like this is a bit slow and that using (lwip)getpeername is the
+    good lwip way to do it (so, using recv is faster on tcp sockets).
+
+  2008-03-12 Frè¾¿dè¾¿ric Bernon, Jonathan Larmour
+  * api_msg.c, contrib/apps/ping.c: Fix bug #22530 "api_msg.c's
+    recv_raw() does not consume data", and the ping sample (with
+    LWIP_SOCKET=1, the code did the wrong supposition that lwip_recvfrom
+    returned the IP payload, without the IP header).
+
+  2008-03-04 Jonathan Larmour
+  * mem.c, stats.c, mem.h: apply patch #6414 to avoid compiler errors
+  and/or warnings on some systems where mem_size_t and size_t differ.
+  * pbuf.c, ppp.c: Fix warnings on some systems with mem_malloc.
+
+  2008-03-04 Kieran Mansley (contributions by others) 
+  * Numerous small compiler error/warning fixes from contributions to
+    mailing list after 1.3.0 release candidate made.
+
+  2008-01-25 Cui hengbin (integrated by Frè¾¿dè¾¿ric Bernon)
+  * dns.c: Fix bug #22108 "DNS problem" caused by unaligned structures.
+
+  2008-01-15 Kieran Mansley
+  * tcp_out.c: BUG20511.  Modify persist timer to start when we are
+    prevented from sending by a small send window, not just a zero
+    send window.
+
+  2008-01-09 Jonathan Larmour
+  * opt.h, ip.c: Rename IP_OPTIONS define to IP_OPTIONS_ALLOWED to avoid
+    conflict with Linux system headers.
+
+  2008-01-06 Jonathan Larmour
+  * dhcp.c: fix bug #19927: "DHCP NACK problem" by clearing any existing set IP
+    address entirely on receiving a DHCPNAK, and restarting discovery.
+
+  2007-12-21 Simon Goldschmidt
+  * sys.h, api_lib.c, api_msg.c, sockets.c: fix bug #21698: "netconn->recv_avail
+    is not protected" by using new macros for interlocked access to modify/test
+    netconn->recv_avail.
+
+  2007-12-20 Kieran Mansley (based on patch from Oleg Tyshev)
+  * tcp_in.c: fix bug# 21535 (nrtx not reset correctly in SYN_SENT state)
+
+  2007-12-20 Kieran Mansley (based on patch from Per-Henrik Lundbolm)
+  * tcp.c, tcp_in.c, tcp_out.c, tcp.h: fix bug #20199 (better handling
+    of silly window avoidance and prevent lwIP from shrinking the window)
+
+  2007-12-04 Simon Goldschmidt
+  * tcp.c, tcp_in.c: fix bug #21699 (segment leak in ooseq processing when last
+    data packet was lost): add assert that all segment lists are empty in
+    tcp_pcb_remove before setting pcb to CLOSED state; don't directly set CLOSED
+    state from LAST_ACK in tcp_process
+
+  2007-12-02 Simon Goldschmidt
+  * sockets.h: fix bug #21654: exclude definition of struct timeval from #ifndef FD_SET
+    If including <sys/time.h> for system-struct timeval, LWIP_TIMEVAL_PRIVATE now
+    has to be set to 0 in lwipopts.h
+
+  2007-12-02 Simon Goldschmidt
+  * api_msg.c, api_lib.c: fix bug #21656 (recvmbox problem in netconn API): always
+    allocate a recvmbox in netconn_new_with_proto_and_callback. For a tcp-listen
+    netconn, this recvmbox is later freed and a new mbox is allocated for acceptmbox.
+    This is a fix for thread-safety and allocates all items needed for a netconn
+    when the netconn is created.
+
+  2007-11-30 Simon Goldschmidt
+  * udp.c: first attempt to fix bug #21655 (DHCP doesn't work reliably with multiple
+    netifs): if LWIP_DHCP is enabled, UDP packets to DHCP_CLIENT_PORT are passed
+    to netif->dhcp->pcb only (if that exists) and not to any other pcb for the same
+    port (only solution to let UDP pcbs 'bind' to a netif instead of an IP address)
+
+  2007-11-27 Simon Goldschmidt
+  * ip.c: fixed bug #21643 (udp_send/raw_send don't fail if netif is down) by
+    letting ip_route only use netifs that are up.
+
+  2007-11-27 Simon Goldschmidt
+  * err.h, api_lib.c, api_msg.c, sockets.c: Changed error handling: ERR_MEM, ERR_BUF
+    and ERR_RTE are seen as non-fatal, all other errors are fatal. netconns and
+    sockets block most operations once they have seen a fatal error.
+
+  2007-11-27 Simon Goldschmidt
+  * udp.h, udp.c, dhcp.c: Implemented new function udp_sendto_if which takes the
+    netif to send as an argument (to be able to send on netifs that are down).
+
+  2007-11-26 Simon Goldschmidt
+  * tcp_in.c: Fixed bug #21582: pcb->acked accounting can be wrong when ACKs
+    arrive out-of-order
+
+  2007-11-21 Simon Goldschmidt
+  * tcp.h, tcp_out.c, api_msg.c: Fixed bug #20287: tcp_output_nagle sends too early
+    Fixed the nagle algorithm; nagle now also works for all raw API applications
+    and has to be explicitly disabled with 'tcp_pcb->flags |= TF_NODELAY'
+
+  2007-11-12 Frè¾¿dè¾¿ric Bernon
+  * sockets.c, api.h, api_lib.c, api_msg.h, api_msg.c: Fixed bug #20900. Now, most
+    of the netconn_peer and netconn_addr processing is done inside tcpip_thread
+    context in do_getaddr.
+
+  2007-11-10 Simon Goldschmidt
+  * etharp.c: Fixed bug: assert fired when MEMP_ARP_QUEUE was empty (which can
+    happen any time). Now the packet simply isn't enqueued when out of memory.
+
+  2007-11-01 Simon Goldschmidt
+  * tcp.c, tcp_in.c: Fixed bug #21494: The send mss (pcb->mss) is set to 536 (or
+    TCP_MSS if that is smaller) as long as no MSS option is received from the
+    remote host.
+
+  2007-11-01 Simon Goldschmidt
+  * tcp.h, tcp.c, tcp_in.c: Fixed bug #21491: The MSS option sent (with SYN)
+    is now based on TCP_MSS instead of pcb->mss (on passive open now effectively
+    sending our configured TCP_MSS instead of the one received).
+
+  2007-11-01 Simon Goldschmidt
+  * tcp_in.c: Fixed bug #21181: On active open, the initial congestion window was
+    calculated based on the configured TCP_MSS, not on the MSS option received
+    with SYN+ACK.
+
+  2007-10-09 Simon Goldschmidt
+  * udp.c, inet.c, inet.h: Fixed UDPLite: send: Checksum was always generated too
+    short and also was generated wrong if checksum coverage != tot_len;
+    receive: checksum was calculated wrong if checksum coverage != tot_len
+
+  2007-10-08 Simon Goldschmidt
+  * mem.c: lfree was not updated in mem_realloc!
+
+  2007-10-07 Frè¾¿dè¾¿ric Bernon
+  * sockets.c, api.h, api_lib.c: First step to fix "bug #20900 : Potential
+    crash error problem with netconn_peer & netconn_addr". VERY IMPORTANT:
+    this change cause an API breakage for netconn_addr, since a parameter
+    type change. Any compiler should cause an error without any changes in
+    yours netconn_peer calls (so, it can't be a "silent change"). It also
+    reduce a little bit the footprint for socket layer (lwip_getpeername &
+    lwip_getsockname use now a common lwip_getaddrname function since 
+    netconn_peer & netconn_addr have the same parameters).
+
+  2007-09-20 Simon Goldschmidt
+  * tcp.c: Fixed bug #21080 (tcp_bind without check pcbs in TIME_WAIT state)
+    by checking  tcp_tw_pcbs also
+
+  2007-09-19 Simon Goldschmidt
+  * icmp.c: Fixed bug #21107 (didn't reset IP TTL in ICMP echo replies)
+
+  2007-09-15 Mike Kleshov
+  * mem.c: Fixed bug #21077 (inaccuracy in calculation of lwip_stat.mem.used)
+
+  2007-09-06 Frè¾¿dè¾¿ric Bernon
+  * several-files: replace some #include "arch/cc.h" by "lwip/arch.h", or simply remove
+    it as long as "lwip/opt.h" is included before (this one include "lwip/debug.h" which
+    already include "lwip/arch.h"). Like that, default defines are provided by "lwip/arch.h"
+    if they are not defined in cc.h, in the same spirit than "lwip/opt.h" for lwipopts.h.
+
+  2007-08-30 Frè¾¿dè¾¿ric Bernon
+  * igmp.h, igmp.c: Some changes to remove some redundant code, add some traces, 
+    and fix some coding style.
+
+  2007-08-28 Frè¾¿dè¾¿ric Bernon
+  * tcpip.c: Fix TCPIP_MSG_INPKT processing: now, tcpip_input can be used for any
+    kind of packets. These packets are considered like Ethernet packets (payload 
+    pointing to ethhdr) if the netif got the NETIF_FLAG_ETHARP flag. Else, packets 
+    are considered like IP packets (payload pointing to iphdr).
+
+  2007-08-27 Frè¾¿dè¾¿ric Bernon
+  * api.h, api_lib.c, api_msg.c: First fix for "bug #20900 : Potential crash error
+    problem with netconn_peer & netconn_addr". Introduce NETCONN_LISTEN netconn_state
+    and remove obsolete ones (NETCONN_RECV & NETCONN_ACCEPT).
+
+  2007-08-24 Kieran Mansley
+  * inet.c Modify (acc >> 16) test to ((acc >> 16) != 0) to help buggy
+    compiler (Paradigm C++)
+
+  2007-08-09 Frè¾¿dè¾¿ric Bernon, Bill Florac
+  * stats.h, stats.c, igmp.h, igmp.c, opt.h: Fix for bug #20503 : IGMP Improvement.
+    Introduce IGMP_STATS to centralize statistics management.
+
+  2007-08-09 Frè¾¿dè¾¿ric Bernon, Bill Florac
+  * udp.c: Fix for bug #20503 : IGMP Improvement. Enable to receive a multicast
+    packet on a udp pcb binded on an netif's IP address, and not on "any".
+
+  2007-08-09 Frè¾¿dè¾¿ric Bernon, Bill Florac
+  * igmp.h, igmp.c, ip.c: Fix minor changes from bug #20503 : IGMP Improvement.
+    This is mainly on using lookup/lookfor, and some coding styles...
+
+  2007-07-26 Frè¾¿dè¾¿ric Bernon (and "thedoctor")
+  * igmp.c: Fix bug #20595 to accept IGMPv3 "Query" messages.
+
+  2007-07-25 Simon Goldschmidt
+  * api_msg.c, tcp.c: Another fix for bug #20021: by not returning an error if
+    tcp_output fails in tcp_close, the code in do_close_internal gets simpler
+    (tcp_output is called again later from tcp timers).
+
+  2007-07-25 Simon Goldschmidt
+  * ip_frag.c: Fixed bug #20429: use the new pbuf_copy_partial instead of the old
+    copy_from_pbuf, which illegally modified the given pbuf.
+
+  2007-07-25 Simon Goldschmidt
+  * tcp_out.c: tcp_enqueue: pcb->snd_queuelen didn't work for chaine PBUF_RAMs:
+    changed snd_queuelen++ to snd_queuelen += pbuf_clen(p).
+
+  2007-07-24 Simon Goldschmidt
+  * api_msg.c, tcp.c: Fix bug #20480: Check the pcb passed to tcp_listen() for the
+    correct state (must be CLOSED).
+
+  2007-07-13 Thomas Taranowski (commited by Jared Grubb)
+  * memp.c: Fix bug #20478: memp_malloc returned NULL+MEMP_SIZE on failed
+    allocation. It now returns NULL.
+
+  2007-07-13 Frè¾¿dè¾¿ric Bernon
+  * api_msg.c: Fix bug #20318: api_msg "recv" callbacks don't call pbuf_free in
+    all error cases.
+
+  2007-07-13 Frè¾¿dè¾¿ric Bernon
+  * api_msg.c: Fix bug #20315: possible memory leak problem if tcp_listen failed,
+    because current code doesn't follow rawapi.txt documentation.
+
+  2007-07-13 Kieran Mansley
+  * src/core/tcp_in.c Apply patch#5741 from Oleg Tyshev to fix bug in
+    out of sequence processing of received packets
+
+  2007-07-03 Simon Goldschmidt
+  * nearly-all-files: Added assertions where PBUF_RAM pbufs are used and an
+    assumption is made that this pbuf is in one piece (i.e. not chained). These
+    assumptions clash with the possibility of converting to fully pool-based
+    pbuf implementations, where PBUF_RAM pbufs might be chained.
+
+  2007-07-03 Simon Goldschmidt
+  * api.h, api_lib.c, api_msg.c: Final fix for bug #20021 and some other problems
+    when closing tcp netconns: removed conn->sem, less context switches when
+    closing, both netconn_close and netconn_delete should safely close tcp
+    connections.
+
+  2007-07-02 Simon Goldschmidt
+  * ipv4/ip.h, ipv6/ip.h, opt.h, netif.h, etharp.h, ipv4/ip.c, netif.c, raw.c,
+    tcp_out.c, udp.c, etharp.c: Added option LWIP_NETIF_HWADDRHINT (default=off)
+    to cache ARP table indices with each pcb instead of single-entry cache for
+    the complete stack.
+
+  2007-07-02 Simon Goldschmidt
+  * tcp.h, tcp.c, tcp_in.c, tcp_out.c: Added some ASSERTS and casts to prevent
+    warnings when assigning to smaller types.
+
+  2007-06-28 Simon Goldschmidt
+  * tcp_out.c: Added check to prevent tcp_pcb->snd_queuelen from overflowing.
+
+  2007-06-28 Simon Goldschmidt
+  * tcp.h: Fixed bug #20287: Fixed nagle algorithm (sending was done too early if
+    a segment contained chained pbufs)
+
+  2007-06-28 Frè¾¿dè¾¿ric Bernon
+  * autoip.c: replace most of rand() calls by a macro LWIP_AUTOIP_RAND which compute
+    a "pseudo-random" value based on netif's MAC and some autoip fields. It's always
+    possible to define this macro in your own lwipopts.h to always use C library's
+    rand(). Note that autoip_create_rand_addr doesn't use this macro.
+
+  2007-06-28 Frè¾¿dè¾¿ric Bernon
+  * netifapi.h, netifapi.c, tcpip.h, tcpip.c: Update code to handle the option
+    LWIP_TCPIP_CORE_LOCKING, and do some changes to be coherent with last modifications
+    in api_lib/api_msg (use pointers and not type with table, etc...) 
+
+  2007-06-26 Simon Goldschmidt
+  * udp.h: Fixed bug #20259: struct udp_hdr was lacking the packin defines.
+
+  2007-06-25 Simon Goldschmidt
+  * udp.c: Fixed bug #20253: icmp_dest_unreach was called with a wrong p->payload
+    for udp packets with no matching pcb.
+
+  2007-06-25 Simon Goldschmidt
+  * udp.c: Fixed bug #20220: UDP PCB search in udp_input(): a non-local match
+    could get udp input packets if the remote side matched.
+
+  2007-06-13 Simon Goldschmidt
+  * netif.c: Fixed bug #20180 (TCP pcbs listening on IP_ADDR_ANY could get
+    changed in netif_set_ipaddr if previous netif->ip_addr.addr was 0.
+
+  2007-06-13 Simon Goldschmidt
+  * api_msg.c: pcb_new sets conn->err if protocol is not implemented
+    -> netconn_new_..() does not allocate a new connection for unsupported
+    protocols.
+
+  2007-06-13 Frè¾¿dè¾¿ric Bernon, Simon Goldschmidt
+  * api_lib.c: change return expression in netconn_addr and netconn_peer, because
+    conn->err was reset to ERR_OK without any reasons (and error was lost)...
+
+  2007-06-13 Frè¾¿dè¾¿ric Bernon, Matthias Weisser
+  * opt.h, mem.h, mem.c, memp.c, pbuf.c, ip_frag.c, vj.c: Fix bug #20162. Rename
+    MEM_ALIGN in LWIP_MEM_ALIGN and MEM_ALIGN_SIZE in LWIP_MEM_ALIGN_SIZE to avoid
+    some macro names collision with some OS macros.
+
+  2007-06-11 Simon Goldschmidt
+  * udp.c: UDP Lite: corrected the use of chksum_len (based on RFC3828: if it's 0,
+    create checksum over the complete packet. On RX, if it's < 8 (and not 0),
+    discard the packet. Also removed the duplicate 'udphdr->chksum = 0' for both
+    UDP & UDP Lite.
+
+  2007-06-11 Srinivas Gollakota & Oleg Tyshev
+  * tcp_out.c: Fix for bug #20075 : "A problem with keep-alive timer and TCP flags"
+    where TCP flags wasn't initialized in tcp_keepalive.
+
+  2007-06-03 Simon Goldschmidt
+  * udp.c: udp_input(): Input pbuf was not freed if pcb had no recv function
+    registered, p->payload was modified without modifying p->len if sending
+    icmp_dest_unreach() (had no negative effect but was definitively wrong).
+
+  2007-06-03 Simon Goldschmidt
+  * icmp.c: Corrected bug #19937: For responding to an icmp echo request, icmp
+    re-used the input pbuf even if that didn't have enough space to include the
+    link headers. Now the space is tested and a new pbuf is allocated for the
+    echo response packet if the echo request pbuf isn't big enough.
+
+  2007-06-01 Simon Goldschmidt
+  * sockets.c: Checked in patch #5914: Moved sockopt processing into tcpip_thread.
+
+  2007-05-23 Frè¾¿dè¾¿ric Bernon
+  * api_lib.c, sockets.c: Fixed bug #5958 for netconn_listen (acceptmbox only
+    allocated by do_listen if success) and netconn_accept errors handling. In
+    most of api_lib functions, we replace some errors checkings like "if (conn==NULL)"
+    by ASSERT, except for netconn_delete.
+
+  2007-05-23 Frè¾¿dè¾¿ric Bernon
+  * api_lib.c: Fixed bug #5957 "Safe-thread problem inside netconn_recv" to return
+    an error code if it's impossible to fetch a pbuf on a TCP connection (and not
+    directly close the recvmbox).
+
+  2007-05-22 Simon Goldschmidt
+  * tcp.c: Fixed bug #1895 (tcp_bind not correct) by introducing a list of
+    bound but unconnected (and non-listening) tcp_pcbs.
+
+  2007-05-22 Frè¾¿dè¾¿ric Bernon
+  * sys.h, sys.c, api_lib.c, tcpip.c: remove sys_mbox_fetch_timeout() (was only
+    used for LWIP_SO_RCVTIMEO option) and use sys_arch_mbox_fetch() instead of
+    sys_mbox_fetch() in api files. Now, users SHOULD NOT use internal lwIP features
+    like "sys_timeout" in their application threads.
+
+  2007-05-22 Frè¾¿dè¾¿ric Bernon
+  * api.h, api_lib.c, api_msg.h, api_msg.c: change the struct api_msg_msg to see
+    which parameters are used by which do_xxx function, and to avoid "misusing"
+    parameters (patch #5938).
+
+  2007-05-22 Simon Goldschmidt
+  * api_lib.c, api_msg.c, raw.c, api.h, api_msg.h, raw.h: Included patch #5938:
+    changed raw_pcb.protocol from u16_t to u8_t since for IPv4 and IPv6, proto
+    is only 8 bits wide. This affects the api, as there, the protocol was
+    u16_t, too.
+
+  2007-05-18 Simon Goldschmidt
+  * memp.c: addition to patch #5913: smaller pointer was returned but
+    memp_memory was the same size -> did not save memory.
+
+  2007-05-16 Simon Goldschmidt
+  * loopif.c, slipif.c: Fix bug #19729: free pbuf if netif->input() returns
+    != ERR_OK.
+
+  2007-05-16 Simon Goldschmidt
+  * api_msg.c, udp.c: If a udp_pcb has a local_ip set, check if it is the same
+    as the one of the netif used for sending to prevent sending from old
+    addresses after a netif address gets changed (partly fixes bug #3168).
+
+  2007-05-16 Frè¾¿dè¾¿ric Bernon
+  * tcpip.c, igmp.h, igmp.c: Fixed bug "#19800 : IGMP: igmp_tick() will not work
+    with NO_SYS=1". Note that igmp_init is always in tcpip_thread (and not in 
+    tcpip_init) because we have to be sure that network interfaces are already
+    added (mac filter is updated only in igmp_init for the moment).
+
+  2007-05-16 Simon Goldschmidt
+  * mem.c, memp.c: Removed semaphores from memp, changed sys_sem_wait calls
+    into sys_arch_sem_wait calls to prevent timers from running while waiting
+    for the heap. This fixes bug #19167.
+
+  2007-05-13 Simon Goldschmidt
+  * tcp.h, sockets.h, sockets.c: Fixed bug from patch #5865 by moving the defines
+    for socket options (lwip_set/-getsockopt) used with level IPPROTO_TCP from
+    tcp.h to sockets.h.
+
+  2007-05-07 Simon Goldschmidt
+  * mem.c: Another attempt to fix bug #17922.
+
+  2007-05-04 Simon Goldschmidt
+  * pbuf.c, pbuf.h, etharp.c: Further update to ARP queueing: Changed pbuf_copy()
+    implementation so that it can be reused (don't allocate the target
+    pbuf inside pbuf_copy()).
+
+  2007-05-04 Simon Goldschmidt
+  * memp.c: checked in patch #5913: in memp_malloc() we can return memp as mem
+    to save a little RAM (next pointer of memp is not used while not in pool).
+
+  2007-05-03 "maq"
+  * sockets.c: Fix ioctl FIONREAD when some data remains from last recv.
+    (patch #3574).
+
+  2007-04-23 Simon Goldschmidt
+  * loopif.c, loopif.h, opt.h, src/netif/FILES: fix bug #2595: "loopif results
+    in NULL reference for incoming TCP packets". Loopif has to be configured
+    (using LWIP_LOOPIF_MULTITHREADING) to directly call netif->input()
+    (multithreading environments, e.g. netif->input() = tcpip_input()) or
+    putting packets on a list that is fed to the stack by calling loopif_poll()
+    (single-thread / NO_SYS / polling environment where e.g.
+    netif->input() = ip_input).
+
+  2007-04-17 Jonathan Larmour
+  * pbuf.c: Use s32_t in pbuf_realloc(), as an s16_t can't reliably hold
+    the difference between two u16_t's.
+  * sockets.h: FD_SETSIZE needs to match number of sockets, which is
+    MEMP_NUM_NETCONN in sockets.c right now.
+
+  2007-04-12 Jonathan Larmour
+  * icmp.c: Reset IP header TTL in ICMP ECHO responses (bug #19580).
+
+  2007-04-12 Kieran Mansley
+  * tcp.c, tcp_in.c, tcp_out.c, tcp.h: Modify way the retransmission
+    timer is reset to fix bug#19434, with help from Oleg Tyshev.
+
+  2007-04-11 Simon Goldschmidt
+  * etharp.c, pbuf.c, pbuf.h: 3rd fix for bug #11400 (arp-queuing): More pbufs than
+    previously thought need to be copied (everything but PBUF_ROM!). Cleaned up
+    pbuf.c: removed functions no needed any more (by etharp).
+
+  2007-04-11 Kieran Mansley
+  * inet.c, ip_addr.h, sockets.h, sys.h, tcp.h: Apply patch #5745: Fix
+    "Constant is long" warnings with 16bit compilers.  Contributed by
+    avatar@mmlab.cse.yzu.edu.tw
+
+  2007-04-05 Frè¾¿dè¾¿ric Bernon, Jonathan Larmour
+  * api_msg.c: Fix bug #16830: "err_tcp() posts to connection mailbox when no pend on
+    the mailbox is active". Now, the post is only done during a connect, and do_send,
+    do_write and do_join_leave_group don't do anything if a previous error was signaled.
+
+  2007-04-03 Frè¾¿dè¾¿ric Bernon
+  * ip.c: Don't set the IP_DF ("Don't fragment") flag in the IP header in IP output
+    packets. See patch #5834.
+
+  2007-03-30 Frè¾¿dè¾¿ric Bernon
+  * api_msg.c: add a "pcb_new" helper function to avoid redundant code, and to add
+    missing  pcb allocations checking (in do_bind, and for each raw_new). Fix style.
+
+  2007-03-30 Frè¾¿dè¾¿ric Bernon
+  * most of files: prefix all debug.h define with "LWIP_" to avoid any conflict with
+    others environment defines (these were too "generic").
+
+  2007-03-28 Frè¾¿dè¾¿ric Bernon
+  * api.h, api_lib.c, sockets.c: netbuf_ref doesn't check its internal pbuf_alloc call
+    result and can cause a crash. lwip_send now check netbuf_ref result.
+
+  2007-03-28 Simon Goldschmidt
+  * sockets.c Remove "#include <errno.h>" from sockets.c to avoid multiple
+    definition of macros (in errno.h and lwip/arch.h) if LWIP_PROVIDE_ERRNO is
+    defined. This is the way it should have been already (looking at
+    doc/sys_arch.txt)
+
+  2007-03-28 Kieran Mansley
+  * opt.h Change default PBUF_POOL_BUFSIZE (again) to accomodate default MSS +
+    IP and TCP headers *and* physical link headers
+
+  2007-03-26 Frè¾¿dè¾¿ric Bernon (based on patch from Dmitry Potapov)
+  * api_lib.c: patch for netconn_write(), fixes a possible race condition which cause
+    to send some garbage. It is not a definitive solution, but the patch does solve
+    the problem for most cases.
+
+  2007-03-22 Frè¾¿dè¾¿ric Bernon
+  * api_msg.h, api_msg.c: Remove obsolete API_MSG_ACCEPT and do_accept (never used).
+
+  2007-03-22 Frè¾¿dè¾¿ric Bernon
+  * api_lib.c: somes resources couldn't be freed if there was errors during
+    netconn_new_with_proto_and_callback.
+
+  2007-03-22 Frè¾¿dè¾¿ric Bernon
+  * ethernetif.c: update netif->input calls to check return value. In older ports,
+    it's a good idea to upgrade them, even if before, there could be another problem
+    (access to an uninitialized mailbox).
+
+  2007-03-21 Simon Goldschmidt
+  * sockets.c: fixed bug #5067 (essentialy a signed/unsigned warning fixed
+    by casting to unsigned).
+
+  2007-03-21 Frè¾¿dè¾¿ric Bernon
+  * api_lib.c, api_msg.c, tcpip.c: integrate sys_mbox_fetch(conn->mbox, NULL) calls from
+    api_lib.c to tcpip.c's tcpip_apimsg(). Now, use a local variable and not a
+    dynamic one from memp to send tcpip_msg to tcpip_thread in a synchrone call.
+    Free tcpip_msg from tcpip_apimsg is not done in tcpip_thread. This give a
+    faster and more reliable communication between api_lib and tcpip.
+
+  2007-03-21 Frè¾¿dè¾¿ric Bernon
+  * opt.h: Add LWIP_NETIF_CALLBACK (to avoid compiler warning) and set it to 0.
+
+  2007-03-21 Frè¾¿dè¾¿ric Bernon
+  * api_msg.c, igmp.c, igmp.h: Fix C++ style comments
+
+  2007-03-21 Kieran Mansley
+  * opt.h Change default PBUF_POOL_BUFSIZE to accomodate default MSS +
+    IP and TCP headers
+
+  2007-03-21 Kieran Mansley
+  * Fix all uses of pbuf_header to check the return value.  In some
+    cases just assert if it fails as I'm not sure how to fix them, but
+    this is no worse than before when they would carry on regardless
+    of the failure.
+
+  2007-03-21 Kieran Mansley
+  * sockets.c, igmp.c, igmp.h, memp.h: Fix C++ style comments and
+    comment out missing header include in icmp.c
+
+  2007-03-20 Frè¾¿dè¾¿ric Bernon
+  * memp.h, stats.c: Fix stats_display function where memp_names table wasn't
+    synchronized with memp.h.
+
+  2007-03-20 Frè¾¿dè¾¿ric Bernon
+  * tcpip.c: Initialize tcpip's mbox, and verify if initialized in tcpip_input,
+    tcpip_ethinput, tcpip_callback, tcpip_apimsg, to fix a init problem with 
+    network interfaces. Also fix a compiler warning.
+
+  2007-03-20 Kieran Mansley
+  * udp.c: Only try and use pbuf_header() to make space for headers if
+    not a ROM or REF pbuf.
+
+  2007-03-19 Frè¾¿dè¾¿ric Bernon
+  * api_msg.h, api_msg.c, tcpip.h, tcpip.c: Add return types to tcpip_apimsg()
+    and api_msg_post().
+
+  2007-03-19 Frè¾¿dè¾¿ric Bernon
+  * Remove unimplemented "memp_realloc" function from memp.h.
+
+  2007-03-11 Simon Goldschmidt
+  * pbuf.c: checked in patch #5796: pbuf_alloc: len field claculation caused
+    memory corruption.
+
+  2007-03-11 Simon Goldschmidt (based on patch from Dmitry Potapov)
+  * api_lib.c, sockets.c, api.h, api_msg.h, sockets.h: Fixed bug #19251
+    (missing `const' qualifier in socket functions), to get more compatible to
+    standard POSIX sockets.
+
+  2007-03-11 Frè¾¿dè¾¿ric Bernon (based on patch from Dmitry Potapov)
+  * sockets.c: Add asserts inside bind, connect and sendto to check input
+    parameters. Remove excessive set_errno() calls after get_socket(), because
+    errno is set inside of get_socket(). Move last sock_set_errno() inside
+    lwip_close.
+
+  2007-03-09 Simon Goldschmidt
+  * memp.c: Fixed bug #11400: New etharp queueing introduced bug: memp_memory
+    was allocated too small.
+
+  2007-03-06 Simon Goldschmidt
+  * tcpip.c: Initialize dhcp timers in tcpip_thread (if LWIP_DHCP) to protect
+    the stack from concurrent access.
+
+  2007-03-06 Frè¾¿dè¾¿ric Bernon, Dmitry Potapov
+  * tcpip.c, ip_frag.c, ethernetif.c: Fix some build problems, and a redundancy
+    call to "lwip_stats.link.recv++;" in low_level_input() & ethernetif_input().
+
+  2007-03-06 Simon Goldschmidt
+  * ip_frag.c, ip_frag.h: Reduce code size: don't include code in those files
+    if IP_FRAG == 0 and IP_REASSEMBLY == 0
+
+  2007-03-06 Frè¾¿dè¾¿ric Bernon, Simon Goldschmidt
+  * opt.h, ip_frag.h, tcpip.h, tcpip.c, ethernetif.c: add new configuration
+    option named ETHARP_TCPIP_ETHINPUT, which enable the new tcpip_ethinput.
+    Allow to do ARP processing for incoming packets inside tcpip_thread
+    (protecting ARP layer against concurrent access). You can also disable
+    old code using tcp_input with new define ETHARP_TCPIP_INPUT set to 0.
+    Older ports have to use tcpip_ethinput.
+
+  2007-03-06 Simon Goldschmidt (based on patch from Dmitry Potapov)
+  * err.h, err.c: fixed compiler warning "initialization dircards qualifiers
+    from pointer target type"
+
+  2007-03-05 Frè¾¿dè¾¿ric Bernon
+  * opt.h, sockets.h: add new configuration options (LWIP_POSIX_SOCKETS_IO_NAMES,
+    ETHARP_TRUST_IP_MAC, review SO_REUSE)
+
+  2007-03-04 Frè¾¿dè¾¿ric Bernon
+  * api_msg.c: Remove some compiler warnings : parameter "pcb" was never
+    referenced.
+
+  2007-03-04 Frè¾¿dè¾¿ric Bernon
+  * api_lib.c: Fix "[patch #5764] api_lib.c cleanup: after patch #5687" (from
+    Dmitry Potapov).
+    The api_msg struct stay on the stack (not moved to netconn struct).
+
+  2007-03-04 Simon Goldschmidt (based on patch from Dmitry Potapov)
+  * pbuf.c: Fix BUG#19168 - pbuf_free can cause deadlock (if
+    SYS_LIGHTWEIGHT_PROT=1 & freeing PBUF_RAM when mem_sem is not available)
+    Also fixed cast warning in pbuf_alloc()
+
+  2007-03-04 Simon Goldschmidt
+  * etharp.c, etharp.h, memp.c, memp.h, opt.h: Fix BUG#11400 - don't corrupt
+    existing pbuf chain when enqueuing multiple pbufs to a pending ARP request
+
+  2007-03-03 Frè¾¿dè¾¿ric Bernon
+  * udp.c: remove obsolete line "static struct udp_pcb *pcb_cache = NULL;"
+    It is static, and never used in udp.c except udp_init().
+
+  2007-03-02 Simon Goldschmidt
+  * tcpip.c: Moved call to ip_init(), udp_init() and tcp_init() from
+    tcpip_thread() to tcpip_init(). This way, raw API connections can be
+    initialized before tcpip_thread is running (e.g. before OS is started)
+
+  2007-03-02 Frè¾¿dè¾¿ric Bernon
+  * rawapi.txt: Fix documentation mismatch with etharp.h about etharp_tmr's call
+    interval.
+
+  2007-02-28 Kieran Mansley 
+  * pbuf.c: Fix BUG#17645 - ensure pbuf payload pointer is not moved
+    outside the region of the pbuf by pbuf_header()
+
+  2007-02-28 Kieran Mansley 
+  * sockets.c: Fix BUG#19161 - ensure milliseconds timeout is non-zero
+    when supplied timeout is also non-zero 
+
+(STABLE-1.2.0)
+
+  2006-12-05 Leon Woestenberg
+  * CHANGELOG: Mention STABLE-1.2.0 release.
+
+  ++ New features:
+
+  2006-12-01 Christiaan Simons
+  * mem.h, opt.h: Added MEM_LIBC_MALLOC option.
+    Note this is a workaround. Currently I have no other options left.
+
+  2006-10-26 Christiaan Simons (accepted patch by Jonathan Larmour)
+  * ipv4/ip_frag.c: rename MAX_MTU to IP_FRAG_MAX_MTU and move define
+    to include/lwip/opt.h.
+  * ipv4/lwip/ip_frag.h: Remove unused IP_REASS_INTERVAL.
+    Move IP_REASS_MAXAGE and IP_REASS_BUFSIZE to include/lwip/opt.h.
+  * opt.h: Add above new options.
+
+  2006-08-18 Christiaan Simons
+  * tcp_{in,out}.c: added SNMP counters.
+  * ipv4/ip.c: added SNMP counters.
+  * ipv4/ip_frag.c: added SNMP counters.
+
+  2006-08-08 Christiaan Simons
+  * etharp.{c,h}: added etharp_find_addr() to read
+    (stable) ethernet/IP address pair from ARP table
+
+  2006-07-14 Christiaan Simons
+  * mib_structs.c: added
+  * include/lwip/snmp_structs.h: added
+  * netif.{c,h}, netif/ethernetif.c: added SNMP statistics to netif struct
+
+  2006-07-06 Christiaan Simons
+  * snmp/asn1_{enc,dec}.c added
+  * snmp/mib2.c added
+  * snmp/msg_{in,out}.c added
+  * include/lwip/snmp_asn1.h added
+  * include/lwip/snmp_msg.h added
+  * doc/snmp_agent.txt added
+
+  2006-03-29 Christiaan Simons
+  * inet.c, inet.h: Added platform byteswap support.
+    Added LWIP_PLATFORM_BYTESWAP define (defaults to 0) and
+    optional LWIP_PLATFORM_HTONS(), LWIP_PLATFORM_HTONL() macros.
+
+  ++ Bug fixes:
+
+  2006-11-30 Christiaan Simons
+  * dhcp.c: Fixed false triggers of request_timeout.
+
+  2006-11-28 Christiaan Simons
+  * netif.c: In netif_add() fixed missing clear of ip_addr, netmask, gw and flags.
+
+  2006-10-11 Christiaan Simons
+  * api_lib.c etharp.c, ip.c, memp.c, stats.c, sys.{c,h} tcp.h:
+    Partially accepted patch #5449 for ANSI C compatibility / build fixes.
+  * ipv4/lwip/ip.h ipv6/lwip/ip.h: Corrected UDP-Lite protocol
+    identifier from 170 to 136 (bug #17574).
+
+  2006-10-10 Christiaan Simons
+  * api_msg.c: Fixed Nagle algorithm as reported by Bob Grice.
+
+  2006-08-17 Christiaan Simons
+  * udp.c: Fixed bug #17200, added check for broadcast
+    destinations for PCBs bound to a unicast address.
+
+  2006-08-07 Christiaan Simons
+  * api_msg.c: Flushing TCP output in do_close() (bug #15926).
+
+  2006-06-27 Christiaan Simons
+  * api_msg.c: Applied patch for cold case (bug #11135).
+    In accept_function() ensure newconn->callback is always initialized.
+
+  2006-06-15 Christiaan Simons
+  * mem.h: added MEM_SIZE_F alias to fix an ancient cold case (bug #1748),
+    facilitate printing of mem_size_t and u16_t statistics.
+
+  2006-06-14 Christiaan Simons
+  * api_msg.c: Applied patch #5146 to handle allocation failures
+    in accept() by Kevin Lawson.
+
+  2006-05-26 Christiaan Simons
+  * api_lib.c: Removed conn->sem creation and destruction 
+    from netconn_write() and added sys_sem_new to netconn_new_*.
+
+(STABLE-1_1_1)
+
+  2006-03-03  Christiaan Simons
+  * ipv4/ip_frag.c: Added bound-checking assertions on ip_reassbitmap
+    access and added pbuf_alloc() return value checks.
+
+  2006-01-01  Leon Woestenberg <leon.woestenberg@gmx.net>
+  * tcp_{in,out}.c, tcp_out.c: Removed 'even sndbuf' fix in TCP, which is
+    now handled by the checksum routine properly.
+
+  2006-02-27  Leon Woestenberg <leon.woestenberg@gmx.net>
+   * pbuf.c: Fix alignment; pbuf_init() would not work unless
+     pbuf_pool_memory[] was properly aligned. (Patch by Curt McDowell.)
+
+  2005-12-20  Leon Woestenberg <leon.woestenberg@gmx.net>
+  * tcp.c: Remove PCBs which stay in LAST_ACK state too long. Patch
+    submitted by Mitrani Hiroshi.
+
+  2005-12-15  Christiaan Simons
+  * inet.c: Disabled the added summing routine to preserve code space.
+
+  2005-12-14  Leon Woestenberg <leon.woestenberg@gmx.net>
+  * tcp_in.c: Duplicate FIN ACK race condition fix by Kelvin Lawson.
+    Added Curt McDowell's optimized checksumming routine for future
+    inclusion. Need to create test case for unaliged, aligned, odd,
+    even length combination of cases on various endianess machines.
+
+  2005-12-09  Christiaan Simons
+  * inet.c: Rewrote standard checksum routine in proper portable C.
+
+  2005-11-25  Christiaan Simons
+  * udp.c tcp.c: Removed SO_REUSE hack. Should reside in socket code only.
+  * *.c: introduced cc.h LWIP_DEBUG formatters matching the u16_t, s16_t,
+    u32_t, s32_t typedefs. This solves most debug word-length assumes.
+
+  2005-07-17 Leon Woestenberg <leon.woestenberg@gmx.net>
+  * inet.c: Fixed unaligned 16-bit access in the standard checksum
+    routine by Peter Jolasson.
+  * slipif.c: Fixed implementation assumption of single-pbuf datagrams.
+
+  2005-02-04 Leon Woestenberg <leon.woestenberg@gmx.net>
+  * tcp_out.c: Fixed uninitialized 'queue' referenced in memerr branch.
+  * tcp_{out|in}.c: Applied patch fixing unaligned access.
+
+  2005-01-04 Leon Woestenberg <leon.woestenberg@gmx.net>
+  * pbuf.c: Fixed missing semicolon after LWIP_DEBUG statement.
+
+  2005-01-03 Leon Woestenberg <leon.woestenberg@gmx.net>
+  * udp.c: UDP pcb->recv() was called even when it was NULL.
+
+(STABLE-1_1_0)
+
+  2004-12-28 Leon Woestenberg <leon.woestenberg@gmx.net>
+  * etharp.*: Disabled multiple packets on the ARP queue.
+    This clashes with TCP queueing.
+
+  2004-11-28 Leon Woestenberg <leon.woestenberg@gmx.net>
+  * etharp.*: Fixed race condition from ARP request to ARP timeout.
+    Halved the ARP period, doubled the period counts.
+    ETHARP_MAX_PENDING now should be at least 2. This prevents
+    the counter from reaching 0 right away (which would allow
+    too little time for ARP responses to be received).
+
+  2004-11-25 Leon Woestenberg <leon.woestenberg@gmx.net>
+  * dhcp.c: Decline messages were not multicast but unicast.
+  * etharp.c: ETHARP_CREATE is renamed to ETHARP_TRY_HARD.
+    Do not try hard to insert arbitrary packet's source address,
+    etharp_ip_input() now calls etharp_update() without ETHARP_TRY_HARD. 
+    etharp_query() now always DOES call ETHARP_TRY_HARD so that users
+    querying an address will see it appear in the cache (DHCP could
+    suffer from this when a server invalidly gave an in-use address.)
+  * ipv4/ip_addr.h: Renamed ip_addr_maskcmp() to _netcmp() as we are
+    comparing network addresses (identifiers), not the network masks
+    themselves.
+  * ipv4/ip_addr.c: ip_addr_isbroadcast() now checks that the given
+    IP address actually belongs to the network of the given interface.
+
+  2004-11-24 Kieran Mansley <kjm25@cam.ac.uk>
+  * tcp.c: Increment pcb->snd_buf when ACK is received in SYN_SENT state.
+
+(STABLE-1_1_0-RC1)
+
+  2004-10-16 Kieran Mansley <kjm25@cam.ac.uk>
+  * tcp.c: Add code to tcp_recved() to send an ACK (window update) immediately,
+    even if one is already pending, if the rcv_wnd is above a threshold
+    (currently TCP_WND/2). This avoids waiting for a timer to expire to send a
+    delayed ACK in order to open the window if the stack is only receiving data.
+
+  2004-09-12 Kieran Mansley <kjm25@cam.ac.uk>
+  * tcp*.*: Retransmit time-out handling improvement by Sam Jansen.
+
+  2004-08-20 Tony Mountifield <tony@softins.co.uk>
+  * etharp.c: Make sure the first pbuf queued on an ARP entry
+    is properly ref counted.
+
+  2004-07-27 Tony Mountifield <tony@softins.co.uk>
+  * debug.h: Added (int) cast in LWIP_DEBUGF() to avoid compiler
+    warnings about comparison.
+  * pbuf.c: Stopped compiler complaining of empty if statement
+    when LWIP_DEBUGF() empty.  Closed an unclosed comment.
+  * tcp.c: Stopped compiler complaining of empty if statement
+    when LWIP_DEBUGF() empty.
+  * ip.h Corrected IPH_TOS() macro: returns a byte, so doesn't need htons().
+  * inet.c: Added a couple of casts to quiet the compiler.
+    No need to test isascii(c) before isdigit(c) or isxdigit(c).
+
+  2004-07-22 Tony Mountifield <tony@softins.co.uk>
+  * inet.c: Made data types consistent in inet_ntoa().
+    Added casts for return values of checksum routines, to pacify compiler.
+  * ip_frag.c, tcp_out.c, sockets.c, pbuf.c
+    Small corrections to some debugging statements, to pacify compiler.
+
+  2004-07-21 Tony Mountifield <tony@softins.co.uk>
+  * etharp.c: Removed spurious semicolon and added missing end-of-comment.
+  * ethernetif.c Updated low_level_output() to match prototype for
+    netif->linkoutput and changed low_level_input() similarly for consistency.
+  * api_msg.c: Changed recv_raw() from int to u8_t, to match prototype
+    of raw_recv() in raw.h and so avoid compiler error.
+  * sockets.c: Added trivial (int) cast to keep compiler happier.
+  * ip.c, netif.c Changed debug statements to use the tidier ip4_addrN() macros.
+
+(STABLE-1_0_0)
+
+  ++ Changes:
+
+  2004-07-05 Leon Woestenberg <leon.woestenberg@gmx.net>
+  * sockets.*: Restructured LWIP_PRIVATE_TIMEVAL. Make sure
+    your cc.h file defines this either 1 or 0. If non-defined,
+    defaults to 1.
+  * .c: Added <string.h> and <errno.h> includes where used.
+  * etharp.c: Made some array indices unsigned.
+
+  2004-06-27 Leon Woestenberg <leon.woestenberg@gmx.net>
+  * netif.*: Added netif_set_up()/down().
+  * dhcp.c: Changes to restart program flow.
+
+  2004-05-07 Leon Woestenberg <leon.woestenberg@gmx.net>
+  * etharp.c: In find_entry(), instead of a list traversal per candidate, do a
+    single-pass lookup for different candidates. Should exploit locality.
+
+  2004-04-29 Leon Woestenberg <leon.woestenberg@gmx.net>
+  * tcp*.c: Cleaned up source comment documentation for Doxygen processing.
+  * opt.h: ETHARP_ALWAYS_INSERT option removed to comply with ARP RFC.
+  * etharp.c: update_arp_entry() only adds new ARP entries when adviced to by
+    the caller. This deprecates the ETHARP_ALWAYS_INSERT overrule option.
+
+  ++ Bug fixes:
+
+  2004-04-27 Leon Woestenberg <leon.woestenberg@gmx.net>
+  * etharp.c: Applied patch of bug #8708 by Toni Mountifield with a solution
+    suggested by Timmy Brolin. Fix for 32-bit processors that cannot access
+    non-aligned 32-bit words, such as soms 32-bit TCP/IP header fields. Fix
+    is to prefix the 14-bit Ethernet headers with two padding bytes.
+
+  2004-04-23 Leon Woestenberg <leon.woestenberg@gmx.net>
+  * ip_addr.c: Fix in the ip_addr_isbroadcast() check.
+  * etharp.c: Fixed the case where the packet that initiates the ARP request
+    is not queued, and gets lost. Fixed the case where the packets destination
+    address is already known; we now always queue the packet and perform an ARP
+    request.
+
+(STABLE-0_7_0)
+
+  ++ Bug fixes:
+
+  * Fixed TCP bug for SYN_SENT to ESTABLISHED state transition.
+  * Fixed TCP bug in dequeueing of FIN from out of order segment queue.
+  * Fixed two possible NULL references in rare cases.
+
+(STABLE-0_6_6)
+
+  ++ Bug fixes:
+
+  * Fixed DHCP which did not include the IP address in DECLINE messages.
+
+  ++ Changes:
+
+  * etharp.c has been hauled over a bit.
+
+(STABLE-0_6_5)
+
+  ++ Bug fixes:
+
+  * Fixed TCP bug induced by bad window resizing with unidirectional TCP traffic.
+  * Packets sent from ARP queue had invalid source hardware address.
+
+  ++ Changes:
+
+  * Pass-by ARP requests do now update the cache.
+
+  ++ New features:
+
+  * No longer dependent on ctype.h.
+  * New socket options.
+  * Raw IP pcb support.
+
+(STABLE-0_6_4)
+
+  ++ Bug fixes:
+
+  * Some debug formatters and casts fixed.
+  * Numereous fixes in PPP.
+
+  ++ Changes:
+
+  * DEBUGF now is LWIP_DEBUGF
+  * pbuf_dechain() has been re-enabled.
+  * Mentioned the changed use of CVS branches in README.
+
+(STABLE-0_6_3)
+
+  ++ Bug fixes:
+
+  * Fixed pool pbuf memory leak in pbuf_alloc().
+    Occured if not enough PBUF_POOL pbufs for a packet pbuf chain.
+    Reported by Savin Zlobec.
+
+  * PBUF_POOL chains had their tot_len field not set for non-first
+    pbufs. Fixed in pbuf_alloc().
+
+  ++ New features:
+
+  * Added PPP stack contributed by Marc Boucher
+
+  ++ Changes:
+
+  * Now drops short packets for ICMP/UDP/TCP protocols. More robust.
+
+  * ARP queueuing now queues the latest packet instead of the first.
+    This is the RFC recommended behaviour, but can be overridden in
+    lwipopts.h.
+
+(0.6.2)
+
+  ++ Bugfixes:
+
+  * TCP has been fixed to deal with the new use of the pbuf->ref
+    counter.
+
+  * DHCP dhcp_inform() crash bug fixed.
+
+  ++ Changes:
+
+  * Removed pbuf_pool_free_cache and pbuf_pool_alloc_cache. Also removed
+    pbuf_refresh(). This has sped up pbuf pool operations considerably.
+    Implemented by David Haas.
+
+(0.6.1)
+
+  ++ New features:
+
+  * The packet buffer implementation has been enhanced to support
+    zero-copy and copy-on-demand for packet buffers which have their
+    payloads in application-managed memory.
+    Implemented by David Haas.
+
+    Use PBUF_REF to make a pbuf refer to RAM. lwIP will use zero-copy
+    if an outgoing packet can be directly sent on the link, or perform
+    a copy-on-demand when necessary.
+
+    The application can safely assume the packet is sent, and the RAM
+    is available to the application directly after calling udp_send()
+    or similar function.
+
+  ++ Bugfixes:
+
+  * ARP_QUEUEING should now correctly work for all cases, including
+    PBUF_REF.
+    Implemented by Leon Woestenberg.
+
+  ++ Changes:
+
+  * IP_ADDR_ANY is no longer a NULL pointer. Instead, it is a pointer
+    to a '0.0.0.0' IP address.
+
+  * The packet buffer implementation is changed. The pbuf->ref counter
+    meaning has changed, and several pbuf functions have been
+    adapted accordingly.
+
+  * netif drivers have to be changed to set the hardware address length field
+    that must be initialized correctly by the driver (hint: 6 for Ethernet MAC).
+    See the contrib/ports/c16x cs8900 driver as a driver example.
+
+  * netif's have a dhcp field that must be initialized to NULL by the driver.
+    See the contrib/ports/c16x cs8900 driver as a driver example.
+
+(0.5.x) This file has been unmaintained up to 0.6.1. All changes are
+  logged in CVS but have not been explained here.
+
+(0.5.3) Changes since version 0.5.2
+
+  ++ Bugfixes:
+
+  * memp_malloc(MEMP_API_MSG) could fail with multiple application
+    threads because it wasn't protected by semaphores.
+
+  ++ Other changes:
+
+  * struct ip_addr now packed.
+
+  * The name of the time variable in arp.c has been changed to ctime
+    to avoid conflicts with the time() function.
+
+(0.5.2) Changes since version 0.5.1
+
+  ++ New features:
+
+  * A new TCP function, tcp_tmr(), now handles both TCP timers.
+
+  ++ Bugfixes:
+
+  * A bug in tcp_parseopt() could cause the stack to hang because of a
+    malformed TCP option.
+
+  * The address of new connections in the accept() function in the BSD
+    socket library was not handled correctly.
+
+  * pbuf_dechain() did not update the ->tot_len field of the tail.
+
+  * Aborted TCP connections were not handled correctly in all
+    situations.
+
+  ++ Other changes:
+
+  * All protocol header structs are now packed.
+
+  * The ->len field in the tcp_seg structure now counts the actual
+    amount of data, and does not add one for SYN and FIN segments.
+
+(0.5.1) Changes since version 0.5.0
+
+  ++ New features:
+
+  * Possible to run as a user process under Linux.
+
+  * Preliminary support for cross platform packed structs.
+
+  * ARP timer now implemented.
+
+  ++ Bugfixes:
+
+  * TCP output queue length was badly initialized when opening
+    connections.
+
+  * TCP delayed ACKs were not sent correctly.
+
+  * Explicit initialization of BSS segment variables.
+
+  * read() in BSD socket library could drop data.
+
+  * Problems with memory alignment.
+
+  * Situations when all TCP buffers were used could lead to
+    starvation.
+
+  * TCP MSS option wasn't parsed correctly.
+
+  * Problems with UDP checksum calculation.
+
+  * IP multicast address tests had endianess problems.
+
+  * ARP requests had wrong destination hardware address.
+
+  ++ Other changes:
+
+  * struct eth_addr changed from u16_t[3] array to u8_t[6].
+
+  * A ->linkoutput() member was added to struct netif.
+
+  * TCP and UDP ->dest_* struct members where changed to ->remote_*.
+
+  * ntoh* macros are now null definitions for big endian CPUs.
+
+(0.5.0) Changes since version 0.4.2
+
+  ++ New features:
+
+  * Redesigned operating system emulation layer to make porting easier.
+
+  * Better control over TCP output buffers.
+
+  * Documenation added.
+
+  ++ Bugfixes:
+
+  * Locking issues in buffer management.
+
+  * Bugfixes in the sequential API.
+
+  * IP forwarding could cause memory leakage. This has been fixed.
+
+  ++ Other changes:
+
+  * Directory structure somewhat changed; the core/ tree has been
+    collapsed.
+
+(0.4.2) Changes since version 0.4.1
+
+  ++ New features:
+
+  * Experimental ARP implementation added.
+
+  * Skeleton Ethernet driver added.
+
+  * Experimental BSD socket API library added.
+
+  ++ Bugfixes:
+
+  * In very intense situations, memory leakage could occur. This has
+    been fixed.
+
+  ++ Other changes:
+
+  * Variables named "data" and "code" have been renamed in order to
+    avoid name conflicts in certain compilers.
+
+  * Variable++ have in appliciable cases been translated to ++variable
+    since some compilers generate better code in the latter case.
+
+(0.4.1) Changes since version 0.4
+
+  ++ New features:
+
+  * TCP: Connection attempts time out earlier than data
+    transmissions. Nagle algorithm implemented. Push flag set on the
+    last segment in a burst.
+
+  * UDP: experimental support for UDP-Lite extensions.
+
+  ++ Bugfixes:
+
+  * TCP: out of order segments were in some cases handled incorrectly,
+    and this has now been fixed. Delayed acknowledgements was broken
+    in 0.4, has now been fixed. Binding to an address that is in use
+    now results in an error. Reset connections sometimes hung an
+    application; this has been fixed.
+
+  * Checksum calculation sometimes failed for chained pbufs with odd
+    lengths. This has been fixed.
+
+  * API: a lot of bug fixes in the API. The UDP API has been improved
+    and tested. Error reporting and handling has been
+    improved. Logical flaws and race conditions for incoming TCP
+    connections has been found and removed.
+
+  * Memory manager: alignment issues. Reallocating memory sometimes
+    failed, this has been fixed.
+
+  * Generic library: bcopy was flawed and has been fixed.
+
+  ++ Other changes:
+
+  * API: all datatypes has been changed from generic ones such as
+    ints, to specified ones such as u16_t. Functions that return
+    errors now have the correct type (err_t).
+
+  * General: A lot of code cleaned up and debugging code removed. Many
+    portability issues have been fixed.
+
+  * The license was changed; the advertising clause was removed.
+
+  * C64 port added.
+
+  * Thanks: Huge thanks go to Dagan Galarneau, Horst Garnetzke, Petri
+    Kosunen, Mikael Caleres, and Frits Wilmink for reporting and
+    fixing bugs!
+
+(0.4) Changes since version 0.3.1
+
+  * Memory management has been radically changed; instead of
+    allocating memory from a shared heap, memory for objects that are
+    rapidly allocated and deallocated is now kept in pools. Allocation
+    and deallocation from those memory pools is very fast. The shared
+    heap is still present but is used less frequently.
+
+  * The memory, memory pool, and packet buffer subsystems now support
+    4-, 2-, or 1-byte alignment.
+
+  * "Out of memory" situations are handled in a more robust way.
+
+  * Stack usage has been reduced.
+
+  * Easier configuration of lwIP parameters such as memory usage,
+    TTLs, statistics gathering, etc. All configuration parameters are
+    now kept in a single header file "lwipopts.h".
+
+  * The directory structure has been changed slightly so that all
+    architecture specific files are kept under the src/arch
+    hierarchy.
+
+  * Error propagation has been improved, both in the protocol modules
+    and in the API.
+
+  * The code for the RTXC architecture has been implemented, tested
+    and put to use.
+
+  * Bugs have been found and corrected in the TCP, UDP, IP, API, and
+    the Internet checksum modules.
+
+  * Bugs related to porting between a 32-bit and a 16-bit architecture
+    have been found and corrected.
+
+  * The license has been changed slightly to conform more with the
+    original BSD license, including the advertisement clause.
+
+(0.3.1) Changes since version 0.3
+
+  * Fix of a fatal bug in the buffer management. Pbufs with allocated
+    RAM never returned the RAM when the pbuf was deallocated.
+
+  * TCP congestion control, window updates and retransmissions did not
+    work correctly. This has now been fixed.
+
+  * Bugfixes in the API.
+
+(0.3) Changes since version 0.2
+
+  * New and improved directory structure. All include files are now
+    kept in a dedicated include/ directory.
+
+  * The API now has proper error handling. A new function,
+    netconn_err(), now returns an error code for the connection in
+    case of errors.
+
+  * Improvements in the memory management subsystem. The system now
+    keeps a pointer to the lowest free memory block. A new function,
+    mem_malloc2() tries to allocate memory once, and if it fails tries
+    to free some memory and retry the allocation.
+
+  * Much testing has been done with limited memory
+    configurations. lwIP now does a better job when overloaded.
+
+  * Some bugfixes and improvements to the buffer (pbuf) subsystem.
+
+  * Many bugfixes in the TCP code:
+
+    - Fixed a bug in tcp_close().
+
+    - The TCP receive window was incorrectly closed when out of
+      sequence segments was received. This has been fixed.
+
+    - Connections are now timed-out of the FIN-WAIT-2 state.
+
+    - The initial congestion window could in some cases be too
+      large. This has been fixed.
+
+    - The retransmission queue could in some cases be screwed up. This
+      has been fixed.
+
+    - TCP RST flag now handled correctly.
+
+    - Out of sequence data was in some cases never delivered to the
+      application. This has been fixed.
+
+    - Retransmitted segments now contain the correct acknowledgment
+      number and advertised window.
+
+    - TCP retransmission timeout backoffs are not correctly computed
+      (ala BSD). After a number of retransmissions, TCP now gives up
+      the connection.
+
+  * TCP connections now are kept on three lists, one for active
+    connections, one for listening connections, and one for
+    connections that are in TIME-WAIT. This greatly speeds up the fast
+    timeout processing for sending delayed ACKs.
+
+  * TCP now provides proper feedback to the application when a
+    connection has been successfully set up.
+
+  * More comments have been added to the code. The code has also been
+    somewhat cleaned up.
+
+(0.2) Initial public release.
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/CMakeLists.txt
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/CMakeLists.txt	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/CMakeLists.txt	(revision 457)
@@ -0,0 +1,20 @@
+cmake_minimum_required(VERSION 3.7)
+
+project(lwIP)
+
+set(LWIP_DIR ${CMAKE_CURRENT_SOURCE_DIR})
+include(src/Filelists.cmake)
+
+# Package generation
+set(CPACK_SOURCE_GENERATOR "ZIP")
+set(CPACK_SOURCE_PACKAGE_DESCRIPTION_SUMMARY "lwIP lightweight IP stack")
+set(CPACK_PACKAGE_VERSION_MAJOR "${LWIP_VERSION_MAJOR}")
+set(CPACK_PACKAGE_VERSION_MINOR "${LWIP_VERSION_MINOR}")
+set(CPACK_PACKAGE_VERSION_PATCH "${LWIP_VERSION_REVISION}")
+set(CPACK_SOURCE_IGNORE_FILES "/build/;${CPACK_SOURCE_IGNORE_FILES};.git")
+set(CPACK_SOURCE_PACKAGE_FILE_NAME "lwip-${LWIP_VERSION_MAJOR}.${LWIP_VERSION_MINOR}.${LWIP_VERSION_REVISION}")
+include(CPack)
+
+# Target for package generation
+add_custom_target(dist COMMAND ${CMAKE_MAKE_PROGRAM} package_source)
+add_dependencies(dist lwipdocs)
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/COPYING
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/COPYING	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/COPYING	(revision 457)
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2001, 2002 Swedish Institute of Computer Science.
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission. 
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ * 
+ * Author: Adam Dunkels <adam@sics.se>
+ *
+ */
+
+
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/FEATURES
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/FEATURES	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/FEATURES	(revision 457)
@@ -0,0 +1,11 @@
+lwIP is a small independent implementation of the TCP/IP protocol suite targeted at embedded systems.
+
+The focus of the lwIP TCP/IP implementation is to reduce resource usage while still having a full scale TCP. This makes lwIP suitable for use in embedded systems with tens of kilobytes of free RAM and room for around 40 kilobytes of code ROM.
+
+Main features include:
+- Protocols: IP, IPv6, ICMP, ND, MLD, UDP, TCP, IGMP, ARP, PPPoS, PPPoE, 6LowPAN (via IEEE 802.15.4, BLE or ZEP; since v2.1.0)
+- DHCP client, stateless DHCPv6 (since v2.1.0), DNS client (incl. mDNS hostname resolver), AutoIP/APIPA (Zeroconf), SNMP agent (v1, v2c, v3 (since v2.1.0), private MIB support & MIB compiler)
+- APIs: specialized APIs for enhanced performance & zero copy, optional Berkeley-alike socket API
+- Extended features: IP forwarding over multiple network interfaces
+- Extended TCP features: congestion control, RTT estimation and fast recovery/fast retransmit, sending SACKs (since v2.1.0), "altcp": nearly transparent TLS for any tcp pcb (since v2.1.0)
+- Addon applications: HTTP server (HTTPS via altcp), HTTP(S) client (since v2.1.0), SNTP client, SMTP client (SMTPS via altcp), ping, NetBIOS nameserver, mDNS responder, MQTT client (TLS support since v2.1.0), TFTP server, iPerf2 counterpart
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/FILES
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/FILES	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/FILES	(revision 457)
@@ -0,0 +1,5 @@
+src/      - The source code for the lwIP TCP/IP stack.
+doc/      - The documentation for lwIP.
+test/     - Some code to test whether the sources do what they should.
+
+See also the FILES file in each subdirectory.
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/README
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/README	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/README	(revision 457)
@@ -0,0 +1,106 @@
+INTRODUCTION
+
+lwIP is a small independent implementation of the TCP/IP protocol suite.
+
+The focus of the lwIP TCP/IP implementation is to reduce the RAM usage
+while still having a full scale TCP. This making lwIP suitable for use
+in embedded systems with tens of kilobytes of free RAM and room for
+around 40 kilobytes of code ROM.
+
+lwIP was originally developed by Adam Dunkels at the Computer and Networks
+Architectures (CNA) lab at the Swedish Institute of Computer Science (SICS)
+and is now developed and maintained by a worldwide network of developers.
+
+FEATURES
+
+  * IP (Internet Protocol, IPv4 and IPv6) including packet forwarding over
+    multiple network interfaces
+  * ICMP (Internet Control Message Protocol) for network maintenance and debugging
+  * IGMP (Internet Group Management Protocol) for multicast traffic management
+  * MLD (Multicast listener discovery for IPv6). Aims to be compliant with 
+    RFC 2710. No support for MLDv2
+  * ND (Neighbor discovery and stateless address autoconfiguration for IPv6).
+    Aims to be compliant with RFC 4861 (Neighbor discovery) and RFC 4862
+    (Address autoconfiguration)
+  * DHCP, AutoIP/APIPA (Zeroconf) and (stateless) DHCPv6
+  * UDP (User Datagram Protocol) including experimental UDP-lite extensions
+  * TCP (Transmission Control Protocol) with congestion control, RTT estimation
+    fast recovery/fast retransmit and sending SACKs
+  * raw/native API for enhanced performance
+  * Optional Berkeley-like socket API
+  * TLS: optional layered TCP ("altcp") for nearly transparent TLS for any
+    TCP-based protocol (ported to mbedTLS) (see changelog for more info)
+  * PPPoS and PPPoE (Point-to-point protocol over Serial/Ethernet)
+  * DNS (Domain name resolver incl. mDNS)
+  * 6LoWPAN (via IEEE 802.15.4, BLE or ZEP)
+
+
+APPLICATIONS
+
+  * HTTP server with SSI and CGI (HTTPS via altcp)
+  * SNMPv2c agent with MIB compiler (Simple Network Management Protocol), v3 via altcp
+  * SNTP (Simple network time protocol)
+  * NetBIOS name service responder
+  * MDNS (Multicast DNS) responder
+  * iPerf server implementation
+  * MQTT client (TLS support via altcp)
+
+
+LICENSE
+
+lwIP is freely available under a BSD license.
+
+
+DEVELOPMENT
+
+lwIP has grown into an excellent TCP/IP stack for embedded devices,
+and developers using the stack often submit bug fixes, improvements,
+and additions to the stack to further increase its usefulness.
+
+Development of lwIP is hosted on Savannah, a central point for
+software development, maintenance and distribution. Everyone can
+help improve lwIP by use of Savannah's interface, Git and the
+mailing list. A core team of developers will commit changes to the
+Git source tree.
+
+The lwIP TCP/IP stack is maintained in the 'lwip' Git module and
+contributions (such as platform ports) are in the 'contrib' Git module.
+
+See doc/savannah.txt for details on Git server access for users and
+developers.
+
+The current Git trees are web-browsable:
+  http://git.savannah.gnu.org/cgit/lwip.git
+  http://git.savannah.gnu.org/cgit/lwip/lwip-contrib.git
+
+Submit patches and bugs via the lwIP project page:
+  http://savannah.nongnu.org/projects/lwip/
+
+Continuous integration builds (GCC, clang):
+  https://travis-ci.org/yarrick/lwip-merged
+
+
+DOCUMENTATION
+
+Self documentation of the source code is regularly extracted from the current
+Git sources and is available from this web page:
+  http://www.nongnu.org/lwip/
+
+There is now a constantly growing wiki about lwIP at
+  http://lwip.wikia.com/wiki/LwIP_Wiki
+
+Also, there are mailing lists you can subscribe at
+  http://savannah.nongnu.org/mail/?group=lwip
+plus searchable archives:
+  http://lists.nongnu.org/archive/html/lwip-users/
+  http://lists.nongnu.org/archive/html/lwip-devel/
+
+lwIP was originally written by Adam Dunkels:
+  http://dunkels.com/adam/
+
+Reading Adam's papers, the files in docs/, browsing the source code
+documentation and browsing the mailing list archives is a good way to
+become familiar with the design of lwIP.
+
+Adam Dunkels <adam@sics.se>
+Leon Woestenberg <leon.woestenberg@gmx.net>
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/UPGRADING
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/UPGRADING	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/UPGRADING	(revision 457)
@@ -0,0 +1,278 @@
+This file lists major changes between release versions that require
+ports or applications to be changed. Use it to update a port or an
+application written for an older version of lwIP to correctly work
+with newer versions.
+
+
+(git master)
+
+  * [Enter new changes just after this line - do not remove this line]
+
+(2.1.0)
+
+  ++ Application changes:
+
+  * Use the new altcp API for seamless TLS integration into existing TCP applications (see changelog)
+  * TCP only kills existing connections with a LOWER priority than the one currently being opened.
+    Previous implementations also kill existing connections of the SAME priority.
+  * ip4_route_src: parameter order is reversed: ip4_route_src(dest, src) -> ip4_route_src(src, dest)
+    to make parameter order consistent with other ip*_route*() functions.
+    Same also applies to LWIP_HOOK_IP4_ROUTE_SRC() parameter order.
+  * pbuf API: pbuf->type (an u8_t holding the enum 'pbuf_type') has changed to only hold a
+    description of the pbuf (e.g. data following pbuf struct, data volatile, allocation
+    source heap/pool/etc.). As a consequence, applications can't test pbuf->type any more.
+    Use pbuf_match_type(pbuf, type) instead.
+  * socket API: according to the standard, SO_ERROR now only returns asynchronous errors.
+    All other/normal/synchronous errors are (and always were) available via 'errno'.
+    LWIP_SOCKET_SET_ERRNO has been removed - 'errno' is always set - and required!
+  * httpd LWIP_HTTPD_CGI_SSI: httpd_cgi_handler() has an additional parameter "struct fs_file *"
+
+  ++ Port changes:
+
+  * tcpip_trycallback() was renamed to tcpip_callbackmsg_trycallback() to avoid confusion
+    with tcpip_try_callback()
+  * compatibility headers: moved from 'src/include/posix' to 'src/include/compat/posix',
+    'src/include/compat/stdc' etc.
+  * The IPv6 implementation now supports address scopes. (See LWIP_IPV6_SCOPES documentation
+    and ip6_zone.h for more documentation)
+  * LWIP_HOOK_DHCP_APPEND_OPTIONS() has changed, see description in opt.h (options_out_len is not
+    available in struct dhcp any more)
+  * Added debug helper asserts to ensure threading/locking requirements are met (define
+    LWIP_MARK_TCPIP_THREAD() and LWIP_ASSERT_CORE_LOCKED()).
+  * Added sys_mbox_trypost_fromisr() and tcpip_callbackmsg_trycallback_fromisr()
+    These can be used to post preallocated messages from an ISR to the tcpip thread
+    (e.g. when using FreeRTOS)
+
+(2.0.2)
+
+  ++ Application changes:
+
+  * slipif: The way to pass serial port number has changed. netif->num is not
+    supported any more, netif->state is interpreted as an u8_t port number now
+    (it's not a POINTER to an u8_t any more!)
+
+(2.0.1)
+
+  ++ Application changes:
+
+  * UDP does NOT receive multicast traffic from ALL netifs on an UDP PCB bound to a specific
+    netif any more. Users need to bind to IP_ADDR_ANY to receive multicast traffic and compare 
+    ip_current_netif() to the desired netif for every packet.
+    See bug #49662 for an explanation.
+
+(2.0.0)
+
+  ++ Application changes:
+
+  * Changed netif "up" flag handling to be an administrative flag (as opposed to the previous meaning of
+    "ip4-address-valid", a netif will now not be used for transmission if not up) -> even a DHCP netif
+    has to be set "up" before starting the DHCP client
+  * Added IPv6 support (dual-stack or IPv4/IPv6 only)
+  * Changed ip_addr_t to be a union in dual-stack mode (use ip4_addr_t where referring to IPv4 only).
+  * Major rewrite of SNMP (added MIB parser that creates code stubs for custom MIBs);
+    supports SNMPv2c (experimental v3 support)
+  * Moved some core applications from contrib repository to src/apps (and include/lwip/apps)
+
+  +++ Raw API:
+    * Changed TCP listen backlog: removed tcp_accepted(), added the function pair tcp_backlog_delayed()/
+      tcp_backlog_accepted() to explicitly delay backlog handling on a connection pcb
+
+  +++ Socket API:
+    * Added an implementation for posix sendmsg()
+    * Added LWIP_FIONREAD_LINUXMODE that makes ioctl/FIONREAD return the size of the next pending datagram
+
+  ++ Port changes
+
+  +++ new files:
+    * MANY new and moved files! 
+    * Added src/Filelists.mk for use in Makefile projects
+    * Continued moving stack-internal parts from abc.h to abc_priv.h in sub-folder "priv"
+      to let abc.h only contain the actual application programmer's API
+
+  +++ sys layer:
+    * Made LWIP_TCPIP_CORE_LOCKING==1 the default as it usually performs better than
+      the traditional message passing (although with LWIP_COMPAT_MUTEX you are still
+      open to priority inversion, so this is not recommended any more)
+    * Added LWIP_NETCONN_SEM_PER_THREAD to use one "op_completed" semaphore per thread
+      instead of using one per netconn (these semaphores are used even with core locking
+      enabled as some longer lasting functions like big writes still need to delay)
+    * Added generalized abstraction for itoa(), strnicmp(), stricmp() and strnstr()
+      in def.h (to be overridden in cc.h) instead of config 
+      options for netbiosns, httpd, dns, etc. ...
+    * New abstraction for hton* and ntoh* functions in def.h.
+      To override them, use the following in cc.h: 
+      #define lwip_htons(x) <your_htons>
+      #define lwip_htonl(x) <your_htonl>
+
+  +++ new options:
+     * TODO
+
+  +++ new pools:
+     * Added LWIP_MEMPOOL_* (declare/init/alloc/free) to declare private memp pools
+       that share memp.c code but do not have to be made global via lwippools.h
+     * Added pools for IPv6, MPU_COMPATIBLE, dns-api, netif-api, etc.
+     * added hook LWIP_HOOK_MEMP_AVAILABLE() to get informed when a memp pool was empty and an item
+       is now available
+
+  * Signature of LWIP_HOOK_VLAN_SET macro was changed
+
+  * LWIP_DECLARE_MEMORY_ALIGNED() may be used to declare aligned memory buffers (mem/memp)
+    or to move buffers to dedicated memory using compiler attributes
+
+  * Standard C headers are used to define sized types and printf formatters
+    (disable by setting LWIP_NO_STDINT_H=1 or LWIP_NO_INTTYPES_H=1 if your compiler
+    does not support these)
+
+
+  ++ Major bugfixes/improvements
+
+  * Added IPv6 support (dual-stack or IPv4/IPv6 only)
+  * Major rewrite of PPP (incl. keep-up with apache pppd)
+    see doc/ppp.txt for an upgrading how-to
+  * Major rewrite of SNMP (incl. MIB parser)
+  * Fixed timing issues that might have lead to losing a DHCP lease
+  * Made rx processing path more robust against crafted errors
+  * TCP window scaling support
+  * modification of api modules to support FreeRTOS-MPU (don't pass stack-pointers to other threads)
+  * made DNS client more robust
+  * support PBUF_REF for RX packets
+  * LWIP_NETCONN_FULLDUPLEX allows netconn/sockets to be used for reading/writing from separate
+    threads each (needs LWIP_NETCONN_SEM_PER_THREAD)
+  * Moved and reordered stats (mainly memp/mib2)
+
+(1.4.0)
+
+  ++ Application changes:
+
+  * Replaced struct ip_addr by typedef ip_addr_t (struct ip_addr is kept for
+    compatibility to old applications, but will be removed in the future).
+
+  * Renamed mem_realloc() to mem_trim() to prevent confusion with realloc()
+
+  +++ Raw API:
+    * Changed the semantics of tcp_close() (since it was rather a
+      shutdown before): Now the application does *NOT* get any calls to the recv
+      callback (aside from NULL/closed) after calling tcp_close()
+
+    * When calling tcp_abort() from a raw API TCP callback function,
+      make sure you return ERR_ABRT to prevent accessing unallocated memory.
+      (ERR_ABRT now means the applicaiton has called tcp_abort!)
+
+  +++ Netconn API:
+    * Changed netconn_receive() and netconn_accept() to return
+      err_t, not a pointer to new data/netconn.
+
+  +++ Socket API:
+    * LWIP_SO_RCVTIMEO: when accept() or recv() time out, they
+      now set errno to EWOULDBLOCK/EAGAIN, not ETIMEDOUT.
+
+    * Added a minimal version of posix fctl() to have a
+      standardised way to set O_NONBLOCK for nonblocking sockets.
+
+  +++ all APIs:
+    * correctly implemented SO(F)_REUSEADDR
+
+  ++ Port changes
+
+  +++ new files:
+
+    * Added 4 new files: def.c, timers.c, timers.h, tcp_impl.h:
+
+    * Moved stack-internal parts of tcp.h to tcp_impl.h, tcp.h now only contains
+      the actual application programmer's API
+  
+    * Separated timer implementation from sys.h/.c, moved to timers.h/.c;
+      Added timer implementation for NO_SYS==1, set NO_SYS_NO_TIMERS==1 if you
+      still want to use your own timer implementation for NO_SYS==0 (as before).
+
+  +++ sys layer:
+
+    * Converted mbox- and semaphore-functions to take pointers to sys_mbox_t/
+      sys_sem_t;
+
+    * Converted sys_mbox_new/sys_sem_new to take pointers and return err_t;
+
+    * Added Mutex concept in sys_arch (define LWIP_COMPAT_MUTEX to let sys.h use
+      binary semaphores instead of mutexes - as before)
+
+  +++ new options:
+
+     * Don't waste memory when chaining segments, added option TCP_OVERSIZE to
+       prevent creating many small pbufs when calling tcp_write with many small
+       blocks of data. Instead, pbufs are allocated larger than needed and the
+       space is used for later calls to tcp_write.
+
+     * Added LWIP_NETIF_TX_SINGLE_PBUF to always copy to try to create single pbufs
+       in tcp_write/udp_send.
+
+    * Added an additional option LWIP_ETHERNET to support ethernet without ARP
+      (necessary for pure PPPoE)
+
+    * Add MEMP_SEPARATE_POOLS to place memory pools in separate arrays. This may
+      be used to place these pools into user-defined memory by using external
+      declaration.
+
+    * Added TCP_SNDQUEUELOWAT corresponding to TCP_SNDLOWAT
+
+  +++ new pools:
+
+     * Netdb uses a memp pool for allocating memory when getaddrinfo() is called,
+       so MEMP_NUM_NETDB has to be set accordingly.
+
+     * DNS_LOCAL_HOSTLIST_IS_DYNAMIC uses a memp pool instead of the heap, so
+       MEMP_NUM_LOCALHOSTLIST has to be set accordingly.
+
+     * Snmp-agent uses a memp pools instead of the heap, so MEMP_NUM_SNMP_* have
+       to be set accordingly.
+
+     * PPPoE uses a MEMP pool instead of the heap, so MEMP_NUM_PPPOE_INTERFACES
+       has to be set accordingly
+
+  * Integrated loopif into netif.c - loopif does not have to be created by the
+    port any more, just define LWIP_HAVE_LOOPIF to 1.
+
+  * Added define LWIP_RAND() for lwip-wide randomization (needs to be defined
+    in cc.h, e.g. used by igmp)
+
+  * Added printf-formatter X8_F to printf u8_t as hex
+
+  * The heap now may be moved to user-defined memory by defining
+    LWIP_RAM_HEAP_POINTER as a void pointer to that memory's address
+
+  * added autoip_set_struct() and dhcp_set_struct() to let autoip and dhcp work
+    with user-allocated structs instead of calling mem_malloc
+
+  * Added const char* name to mem- and memp-stats for easier debugging.
+
+  * Calculate the TCP/UDP checksum while copying to only fetch data once:
+    Define LWIP_CHKSUM_COPY to a memcpy-like function that returns the checksum
+
+  * Added SO_REUSE_RXTOALL to pass received UDP broadcast/multicast packets to
+    more than one pcb.
+
+  * Changed the semantics of ARP_QUEUEING==0: ARP_QUEUEING now cannot be turned
+    off any more, if this is set to 0, only one packet (the most recent one) is
+    queued (like demanded by RFC 1122).
+
+  
+  ++ Major bugfixes/improvements
+
+  * Implemented tcp_shutdown() to only shut down one end of a connection
+  * Implemented shutdown() at socket- and netconn-level
+  * Added errorset support to select() + improved select speed overhead
+  * Merged pppd to v2.3.11 (including some backported bugfixes from 2.4.x)
+  * Added timer implementation for NO_SYS==1 (may be disabled with NO_SYS_NO_TIMERS==1
+  * Use macros defined in ip_addr.h to work with IP addresses
+  * Implemented many nonblocking socket/netconn functions
+  * Fixed ARP input processing: only add a new entry if a request was directed as us
+  * mem_realloc() to mem_trim() to prevent confusion with realloc()
+  * Some improvements for AutoIP (don't route/forward link-local addresses, don't break
+    existing connections when assigning a routable address)
+  * Correctly handle remote side overrunning our rcv_wnd in ooseq case
+  * Removed packing from ip_addr_t, the packed version is now only used in protocol headers
+  * Corrected PBUF_POOL_BUFSIZE for ports where ETH_PAD_SIZE > 0
+  * Added support for static ARP table entries
+
+(STABLE-1.3.2)
+
+  * initial version of this file
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/FILES
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/FILES	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/FILES	(revision 457)
@@ -0,0 +1,15 @@
+api/      - The code for the high-level wrapper API. Not needed if
+            you use the lowel-level call-back/raw API.
+
+apps/     - Higher layer applications that are specifically programmed
+            with the lwIP low-level raw API.
+
+core/     - The core of the TPC/IP stack; protocol implementations,
+            memory and buffer management, and the low-level raw API.
+
+include/  - lwIP include files.
+
+netif/    - Generic network interface device drivers are kept here.
+
+For more information on the various subdirectories, check the FILES
+file in each directory.
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/Filelists.cmake
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/Filelists.cmake	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/Filelists.cmake	(revision 457)
@@ -0,0 +1,279 @@
+# This file is indended to be included in end-user CMakeLists.txt
+# include(/path/to/Filelists.cmake)
+# It assumes the variable LWIP_DIR is defined pointing to the
+# root path of lwIP sources.
+#
+# This file is NOT designed (on purpose) to be used as cmake
+# subdir via add_subdirectory()
+# The intention is to provide greater flexibility to users to 
+# create their own targets using the *_SRCS variables.
+
+set(LWIP_VERSION_MAJOR    "2")
+set(LWIP_VERSION_MINOR    "1")
+set(LWIP_VERSION_REVISION "2")
+# LWIP_VERSION_RC is set to LWIP_RC_RELEASE for official releases
+# LWIP_VERSION_RC is set to LWIP_RC_DEVELOPMENT for Git versions
+# Numbers 1..31 are reserved for release candidates
+set(LWIP_VERSION_RC       "LWIP_RC_RELEASE")
+
+if ("${LWIP_VERSION_RC}" STREQUAL "LWIP_RC_RELEASE")
+    set(LWIP_VERSION_STRING
+        "${LWIP_VERSION_MAJOR}.${LWIP_VERSION_MINOR}.${LWIP_VERSION_REVISION}"
+    )
+elseif ("${LWIP_VERSION_RC}" STREQUAL "LWIP_RC_DEVELOPMENT")
+    set(LWIP_VERSION_STRING
+        "${LWIP_VERSION_MAJOR}.${LWIP_VERSION_MINOR}.${LWIP_VERSION_REVISION}.dev"
+    )
+else ("${LWIP_VERSION_RC}" STREQUAL "LWIP_RC_RELEASE")
+    set(LWIP_VERSION_STRING
+        "${LWIP_VERSION_MAJOR}.${LWIP_VERSION_MINOR}.${LWIP_VERSION_REVISION}.rc${LWIP_VERSION_RC}"
+    )
+endif ("${LWIP_VERSION_RC}" STREQUAL "LWIP_RC_RELEASE")
+
+# The minimum set of files needed for lwIP.
+set(lwipcore_SRCS
+    ${LWIP_DIR}/src/core/init.c
+    ${LWIP_DIR}/src/core/def.c
+    ${LWIP_DIR}/src/core/dns.c
+    ${LWIP_DIR}/src/core/inet_chksum.c
+    ${LWIP_DIR}/src/core/ip.c
+    ${LWIP_DIR}/src/core/mem.c
+    ${LWIP_DIR}/src/core/memp.c
+    ${LWIP_DIR}/src/core/netif.c
+    ${LWIP_DIR}/src/core/pbuf.c
+    ${LWIP_DIR}/src/core/raw.c
+    ${LWIP_DIR}/src/core/stats.c
+    ${LWIP_DIR}/src/core/sys.c
+    ${LWIP_DIR}/src/core/altcp.c
+    ${LWIP_DIR}/src/core/altcp_alloc.c
+    ${LWIP_DIR}/src/core/altcp_tcp.c
+    ${LWIP_DIR}/src/core/tcp.c
+    ${LWIP_DIR}/src/core/tcp_in.c
+    ${LWIP_DIR}/src/core/tcp_out.c
+    ${LWIP_DIR}/src/core/timeouts.c
+    ${LWIP_DIR}/src/core/udp.c
+)
+set(lwipcore4_SRCS
+    ${LWIP_DIR}/src/core/ipv4/autoip.c
+    ${LWIP_DIR}/src/core/ipv4/dhcp.c
+    ${LWIP_DIR}/src/core/ipv4/etharp.c
+    ${LWIP_DIR}/src/core/ipv4/icmp.c
+    ${LWIP_DIR}/src/core/ipv4/igmp.c
+    ${LWIP_DIR}/src/core/ipv4/ip4_frag.c
+    ${LWIP_DIR}/src/core/ipv4/ip4.c
+    ${LWIP_DIR}/src/core/ipv4/ip4_addr.c
+)
+set(lwipcore6_SRCS
+    ${LWIP_DIR}/src/core/ipv6/dhcp6.c
+    ${LWIP_DIR}/src/core/ipv6/ethip6.c
+    ${LWIP_DIR}/src/core/ipv6/icmp6.c
+    ${LWIP_DIR}/src/core/ipv6/inet6.c
+    ${LWIP_DIR}/src/core/ipv6/ip6.c
+    ${LWIP_DIR}/src/core/ipv6/ip6_addr.c
+    ${LWIP_DIR}/src/core/ipv6/ip6_frag.c
+    ${LWIP_DIR}/src/core/ipv6/mld6.c
+    ${LWIP_DIR}/src/core/ipv6/nd6.c
+)
+
+# APIFILES: The files which implement the sequential and socket APIs.
+set(lwipapi_SRCS
+    ${LWIP_DIR}/src/api/api_lib.c
+    ${LWIP_DIR}/src/api/api_msg.c
+    ${LWIP_DIR}/src/api/err.c
+    ${LWIP_DIR}/src/api/if_api.c
+    ${LWIP_DIR}/src/api/netbuf.c
+    ${LWIP_DIR}/src/api/netdb.c
+    ${LWIP_DIR}/src/api/netifapi.c
+    ${LWIP_DIR}/src/api/sockets.c
+    ${LWIP_DIR}/src/api/tcpip.c
+)
+
+# Files implementing various generic network interface functions
+set(lwipnetif_SRCS
+    ${LWIP_DIR}/src/netif/ethernet.c
+    ${LWIP_DIR}/src/netif/bridgeif.c
+    ${LWIP_DIR}/src/netif/bridgeif_fdb.c
+    ${LWIP_DIR}/src/netif/slipif.c
+)
+
+# 6LoWPAN
+set(lwipsixlowpan_SRCS
+    ${LWIP_DIR}/src/netif/lowpan6_common.c
+    ${LWIP_DIR}/src/netif/lowpan6.c
+    ${LWIP_DIR}/src/netif/lowpan6_ble.c
+    ${LWIP_DIR}/src/netif/zepif.c
+)
+
+# PPP
+set(lwipppp_SRCS
+    ${LWIP_DIR}/src/netif/ppp/auth.c
+    ${LWIP_DIR}/src/netif/ppp/ccp.c
+    ${LWIP_DIR}/src/netif/ppp/chap-md5.c
+    ${LWIP_DIR}/src/netif/ppp/chap_ms.c
+    ${LWIP_DIR}/src/netif/ppp/chap-new.c
+    ${LWIP_DIR}/src/netif/ppp/demand.c
+    ${LWIP_DIR}/src/netif/ppp/eap.c
+    ${LWIP_DIR}/src/netif/ppp/ecp.c
+    ${LWIP_DIR}/src/netif/ppp/eui64.c
+    ${LWIP_DIR}/src/netif/ppp/fsm.c
+    ${LWIP_DIR}/src/netif/ppp/ipcp.c
+    ${LWIP_DIR}/src/netif/ppp/ipv6cp.c
+    ${LWIP_DIR}/src/netif/ppp/lcp.c
+    ${LWIP_DIR}/src/netif/ppp/magic.c
+    ${LWIP_DIR}/src/netif/ppp/mppe.c
+    ${LWIP_DIR}/src/netif/ppp/multilink.c
+    ${LWIP_DIR}/src/netif/ppp/ppp.c
+    ${LWIP_DIR}/src/netif/ppp/pppapi.c
+    ${LWIP_DIR}/src/netif/ppp/pppcrypt.c
+    ${LWIP_DIR}/src/netif/ppp/pppoe.c
+    ${LWIP_DIR}/src/netif/ppp/pppol2tp.c
+    ${LWIP_DIR}/src/netif/ppp/pppos.c
+    ${LWIP_DIR}/src/netif/ppp/upap.c
+    ${LWIP_DIR}/src/netif/ppp/utils.c
+    ${LWIP_DIR}/src/netif/ppp/vj.c
+    ${LWIP_DIR}/src/netif/ppp/polarssl/arc4.c
+    ${LWIP_DIR}/src/netif/ppp/polarssl/des.c
+    ${LWIP_DIR}/src/netif/ppp/polarssl/md4.c
+    ${LWIP_DIR}/src/netif/ppp/polarssl/md5.c
+    ${LWIP_DIR}/src/netif/ppp/polarssl/sha1.c
+)
+
+# SNMPv3 agent
+set(lwipsnmp_SRCS
+    ${LWIP_DIR}/src/apps/snmp/snmp_asn1.c
+    ${LWIP_DIR}/src/apps/snmp/snmp_core.c
+    ${LWIP_DIR}/src/apps/snmp/snmp_mib2.c
+    ${LWIP_DIR}/src/apps/snmp/snmp_mib2_icmp.c
+    ${LWIP_DIR}/src/apps/snmp/snmp_mib2_interfaces.c
+    ${LWIP_DIR}/src/apps/snmp/snmp_mib2_ip.c
+    ${LWIP_DIR}/src/apps/snmp/snmp_mib2_snmp.c
+    ${LWIP_DIR}/src/apps/snmp/snmp_mib2_system.c
+    ${LWIP_DIR}/src/apps/snmp/snmp_mib2_tcp.c
+    ${LWIP_DIR}/src/apps/snmp/snmp_mib2_udp.c
+    ${LWIP_DIR}/src/apps/snmp/snmp_snmpv2_framework.c
+    ${LWIP_DIR}/src/apps/snmp/snmp_snmpv2_usm.c
+    ${LWIP_DIR}/src/apps/snmp/snmp_msg.c
+    ${LWIP_DIR}/src/apps/snmp/snmpv3.c
+    ${LWIP_DIR}/src/apps/snmp/snmp_netconn.c
+    ${LWIP_DIR}/src/apps/snmp/snmp_pbuf_stream.c
+    ${LWIP_DIR}/src/apps/snmp/snmp_raw.c
+    ${LWIP_DIR}/src/apps/snmp/snmp_scalar.c
+    ${LWIP_DIR}/src/apps/snmp/snmp_table.c
+    ${LWIP_DIR}/src/apps/snmp/snmp_threadsync.c
+    ${LWIP_DIR}/src/apps/snmp/snmp_traps.c
+)
+
+# HTTP server + client
+set(lwiphttp_SRCS
+    ${LWIP_DIR}/src/apps/http/altcp_proxyconnect.c
+    ${LWIP_DIR}/src/apps/http/fs.c
+    ${LWIP_DIR}/src/apps/http/http_client.c
+    ${LWIP_DIR}/src/apps/http/httpd.c
+)
+
+# MAKEFSDATA HTTP server host utility
+set(lwipmakefsdata_SRCS
+    ${LWIP_DIR}/src/apps/http/makefsdata/makefsdata.c
+)
+
+# IPERF server
+set(lwipiperf_SRCS
+    ${LWIP_DIR}/src/apps/lwiperf/lwiperf.c
+)
+
+# SMTP client
+set(lwipsmtp_SRCS
+    ${LWIP_DIR}/src/apps/smtp/smtp.c
+)
+
+# SNTP client
+set(lwipsntp_SRCS
+    ${LWIP_DIR}/src/apps/sntp/sntp.c
+)
+
+# MDNS responder
+set(lwipmdns_SRCS
+    ${LWIP_DIR}/src/apps/mdns/mdns.c
+)
+
+# NetBIOS name server
+set(lwipnetbios_SRCS
+    ${LWIP_DIR}/src/apps/netbiosns/netbiosns.c
+)
+
+# TFTP server files
+set(lwiptftp_SRCS
+    ${LWIP_DIR}/src/apps/tftp/tftp_server.c
+)
+
+# MQTT client files
+set(lwipmqtt_SRCS
+    ${LWIP_DIR}/src/apps/mqtt/mqtt.c
+)
+
+# ARM MBEDTLS related files of lwIP rep
+set(lwipmbedtls_SRCS
+    ${LWIP_DIR}/src/apps/altcp_tls/altcp_tls_mbedtls.c
+    ${LWIP_DIR}/src/apps/altcp_tls/altcp_tls_mbedtls_mem.c
+    ${LWIP_DIR}/src/apps/snmp/snmpv3_mbedtls.c
+)
+
+# All LWIP files without apps
+set(lwipnoapps_SRCS
+    ${lwipcore_SRCS}
+    ${lwipcore4_SRCS}
+    ${lwipcore6_SRCS}
+    ${lwipapi_SRCS}
+    ${lwipnetif_SRCS}
+    ${lwipsixlowpan_SRCS}
+    ${lwipppp_SRCS}
+)
+
+# LWIPAPPFILES: All LWIP APPs
+set(lwipallapps_SRCS
+    ${lwipsnmp_SRCS}
+    ${lwiphttp_SRCS}
+    ${lwipiperf_SRCS}
+    ${lwipsmtp_SRCS}
+    ${lwipsntp_SRCS}
+    ${lwipmdns_SRCS}
+    ${lwipnetbios_SRCS}
+    ${lwiptftp_SRCS}
+    ${lwipmqtt_SRCS}
+    ${lwipmbedtls_SRCS}
+)
+
+# Generate lwip/init.h (version info)
+configure_file(${LWIP_DIR}/src/include/lwip/init.h.cmake.in ${LWIP_DIR}/src/include/lwip/init.h)
+
+# Documentation
+set(DOXYGEN_DIR ${LWIP_DIR}/doc/doxygen)
+set(DOXYGEN_OUTPUT_DIR output)
+set(DOXYGEN_IN  ${LWIP_DIR}/doc/doxygen/lwip.Doxyfile.cmake.in)
+set(DOXYGEN_OUT ${LWIP_DIR}/doc/doxygen/lwip.Doxyfile)
+configure_file(${DOXYGEN_IN} ${DOXYGEN_OUT})
+
+find_package(Doxygen)
+if (DOXYGEN_FOUND)
+    message("Doxygen build started")
+
+    add_custom_target(lwipdocs
+        COMMAND ${CMAKE_COMMAND} -E remove_directory ${DOXYGEN_DIR}/${DOXYGEN_OUTPUT_DIR}/html
+        COMMAND ${DOXYGEN_EXECUTABLE} ${DOXYGEN_OUT}
+        WORKING_DIRECTORY ${DOXYGEN_DIR}
+        COMMENT "Generating API documentation with Doxygen"
+        VERBATIM)
+else (DOXYGEN_FOUND)
+    message("Doxygen needs to be installed to generate the doxygen documentation")
+endif (DOXYGEN_FOUND)
+
+# lwIP libraries
+add_library(lwipcore EXCLUDE_FROM_ALL ${lwipnoapps_SRCS})
+target_compile_options(lwipcore PRIVATE ${LWIP_COMPILER_FLAGS})
+target_compile_definitions(lwipcore PRIVATE ${LWIP_DEFINITIONS}  ${LWIP_MBEDTLS_DEFINITIONS})
+target_include_directories(lwipcore PRIVATE ${LWIP_INCLUDE_DIRS} ${LWIP_MBEDTLS_INCLUDE_DIRS})
+
+add_library(lwipallapps EXCLUDE_FROM_ALL ${lwipallapps_SRCS})
+target_compile_options(lwipallapps PRIVATE ${LWIP_COMPILER_FLAGS})
+target_compile_definitions(lwipallapps PRIVATE ${LWIP_DEFINITIONS}  ${LWIP_MBEDTLS_DEFINITIONS})
+target_include_directories(lwipallapps PRIVATE ${LWIP_INCLUDE_DIRS} ${LWIP_MBEDTLS_INCLUDE_DIRS})
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/Filelists.mk
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/Filelists.mk	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/Filelists.mk	(revision 457)
@@ -0,0 +1,205 @@
+#
+# Copyright (c) 2001, 2002 Swedish Institute of Computer Science.
+# 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. The name of the author may not be used to endorse or promote products
+#    derived from this software without specific prior written permission. 
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+#
+# This file is part of the lwIP TCP/IP stack.
+# 
+# Author: Adam Dunkels <adam@sics.se>
+#
+
+# COREFILES, CORE4FILES: The minimum set of files needed for lwIP.
+COREFILES=$(LWIPDIR)/core/init.c \
+	$(LWIPDIR)/core/def.c \
+	$(LWIPDIR)/core/dns.c \
+	$(LWIPDIR)/core/inet_chksum.c \
+	$(LWIPDIR)/core/ip.c \
+	$(LWIPDIR)/core/mem.c \
+	$(LWIPDIR)/core/memp.c \
+	$(LWIPDIR)/core/netif.c \
+	$(LWIPDIR)/core/pbuf.c \
+	$(LWIPDIR)/core/raw.c \
+	$(LWIPDIR)/core/stats.c \
+	$(LWIPDIR)/core/sys.c \
+	$(LWIPDIR)/core/altcp.c \
+	$(LWIPDIR)/core/altcp_alloc.c \
+	$(LWIPDIR)/core/altcp_tcp.c \
+	$(LWIPDIR)/core/tcp.c \
+	$(LWIPDIR)/core/tcp_in.c \
+	$(LWIPDIR)/core/tcp_out.c \
+	$(LWIPDIR)/core/timeouts.c \
+	$(LWIPDIR)/core/udp.c
+
+CORE4FILES=$(LWIPDIR)/core/ipv4/autoip.c \
+	$(LWIPDIR)/core/ipv4/dhcp.c \
+	$(LWIPDIR)/core/ipv4/etharp.c \
+	$(LWIPDIR)/core/ipv4/icmp.c \
+	$(LWIPDIR)/core/ipv4/igmp.c \
+	$(LWIPDIR)/core/ipv4/ip4_frag.c \
+	$(LWIPDIR)/core/ipv4/ip4.c \
+	$(LWIPDIR)/core/ipv4/ip4_addr.c
+
+CORE6FILES=$(LWIPDIR)/core/ipv6/dhcp6.c \
+	$(LWIPDIR)/core/ipv6/ethip6.c \
+	$(LWIPDIR)/core/ipv6/icmp6.c \
+	$(LWIPDIR)/core/ipv6/inet6.c \
+	$(LWIPDIR)/core/ipv6/ip6.c \
+	$(LWIPDIR)/core/ipv6/ip6_addr.c \
+	$(LWIPDIR)/core/ipv6/ip6_frag.c \
+	$(LWIPDIR)/core/ipv6/mld6.c \
+	$(LWIPDIR)/core/ipv6/nd6.c
+
+# APIFILES: The files which implement the sequential and socket APIs.
+APIFILES=$(LWIPDIR)/api/api_lib.c \
+	$(LWIPDIR)/api/api_msg.c \
+	$(LWIPDIR)/api/err.c \
+	$(LWIPDIR)/api/if_api.c \
+	$(LWIPDIR)/api/netbuf.c \
+	$(LWIPDIR)/api/netdb.c \
+	$(LWIPDIR)/api/netifapi.c \
+	$(LWIPDIR)/api/sockets.c \
+	$(LWIPDIR)/api/tcpip.c
+
+# NETIFFILES: Files implementing various generic network interface functions
+NETIFFILES=$(LWIPDIR)/netif/ethernet.c \
+	$(LWIPDIR)/netif/bridgeif.c \
+	$(LWIPDIR)/netif/bridgeif_fdb.c \
+	$(LWIPDIR)/netif/slipif.c
+
+# SIXLOWPAN: 6LoWPAN
+SIXLOWPAN=$(LWIPDIR)/netif/lowpan6_common.c \
+        $(LWIPDIR)/netif/lowpan6.c \
+	$(LWIPDIR)/netif/lowpan6_ble.c \
+	$(LWIPDIR)/netif/zepif.c
+
+# PPPFILES: PPP
+PPPFILES=$(LWIPDIR)/netif/ppp/auth.c \
+	$(LWIPDIR)/netif/ppp/ccp.c \
+	$(LWIPDIR)/netif/ppp/chap-md5.c \
+	$(LWIPDIR)/netif/ppp/chap_ms.c \
+	$(LWIPDIR)/netif/ppp/chap-new.c \
+	$(LWIPDIR)/netif/ppp/demand.c \
+	$(LWIPDIR)/netif/ppp/eap.c \
+	$(LWIPDIR)/netif/ppp/ecp.c \
+	$(LWIPDIR)/netif/ppp/eui64.c \
+	$(LWIPDIR)/netif/ppp/fsm.c \
+	$(LWIPDIR)/netif/ppp/ipcp.c \
+	$(LWIPDIR)/netif/ppp/ipv6cp.c \
+	$(LWIPDIR)/netif/ppp/lcp.c \
+	$(LWIPDIR)/netif/ppp/magic.c \
+	$(LWIPDIR)/netif/ppp/mppe.c \
+	$(LWIPDIR)/netif/ppp/multilink.c \
+	$(LWIPDIR)/netif/ppp/ppp.c \
+	$(LWIPDIR)/netif/ppp/pppapi.c \
+	$(LWIPDIR)/netif/ppp/pppcrypt.c \
+	$(LWIPDIR)/netif/ppp/pppoe.c \
+	$(LWIPDIR)/netif/ppp/pppol2tp.c \
+	$(LWIPDIR)/netif/ppp/pppos.c \
+	$(LWIPDIR)/netif/ppp/upap.c \
+	$(LWIPDIR)/netif/ppp/utils.c \
+	$(LWIPDIR)/netif/ppp/vj.c \
+	$(LWIPDIR)/netif/ppp/polarssl/arc4.c \
+	$(LWIPDIR)/netif/ppp/polarssl/des.c \
+	$(LWIPDIR)/netif/ppp/polarssl/md4.c \
+	$(LWIPDIR)/netif/ppp/polarssl/md5.c \
+	$(LWIPDIR)/netif/ppp/polarssl/sha1.c
+
+# LWIPNOAPPSFILES: All LWIP files without apps
+LWIPNOAPPSFILES=$(COREFILES) \
+	$(CORE4FILES) \
+	$(CORE6FILES) \
+	$(APIFILES) \
+	$(NETIFFILES) \
+	$(PPPFILES) \
+	$(SIXLOWPAN)
+
+# SNMPFILES: SNMPv2c agent
+SNMPFILES=$(LWIPDIR)/apps/snmp/snmp_asn1.c \
+	$(LWIPDIR)/apps/snmp/snmp_core.c \
+	$(LWIPDIR)/apps/snmp/snmp_mib2.c \
+	$(LWIPDIR)/apps/snmp/snmp_mib2_icmp.c \
+	$(LWIPDIR)/apps/snmp/snmp_mib2_interfaces.c \
+	$(LWIPDIR)/apps/snmp/snmp_mib2_ip.c \
+	$(LWIPDIR)/apps/snmp/snmp_mib2_snmp.c \
+	$(LWIPDIR)/apps/snmp/snmp_mib2_system.c \
+	$(LWIPDIR)/apps/snmp/snmp_mib2_tcp.c \
+	$(LWIPDIR)/apps/snmp/snmp_mib2_udp.c \
+	$(LWIPDIR)/apps/snmp/snmp_snmpv2_framework.c \
+	$(LWIPDIR)/apps/snmp/snmp_snmpv2_usm.c \
+	$(LWIPDIR)/apps/snmp/snmp_msg.c \
+	$(LWIPDIR)/apps/snmp/snmpv3.c \
+	$(LWIPDIR)/apps/snmp/snmp_netconn.c \
+	$(LWIPDIR)/apps/snmp/snmp_pbuf_stream.c \
+	$(LWIPDIR)/apps/snmp/snmp_raw.c \
+	$(LWIPDIR)/apps/snmp/snmp_scalar.c \
+	$(LWIPDIR)/apps/snmp/snmp_table.c \
+	$(LWIPDIR)/apps/snmp/snmp_threadsync.c \
+	$(LWIPDIR)/apps/snmp/snmp_traps.c
+
+# HTTPFILES: HTTP server + client
+HTTPFILES=$(LWIPDIR)/apps/http/altcp_proxyconnect.c \
+	$(LWIPDIR)/apps/http/fs.c \
+	$(LWIPDIR)/apps/http/http_client.c \
+	$(LWIPDIR)/apps/http/httpd.c
+
+# MAKEFSDATA: MAKEFSDATA HTTP server host utility
+MAKEFSDATAFILES=$(LWIPDIR)/apps/http/makefsdata/makefsdata.c
+
+# LWIPERFFILES: IPERF server
+LWIPERFFILES=$(LWIPDIR)/apps/lwiperf/lwiperf.c
+
+# SMTPFILES: SMTP client
+SMTPFILES=$(LWIPDIR)/apps/smtp/smtp.c
+
+# SNTPFILES: SNTP client
+SNTPFILES=$(LWIPDIR)/apps/sntp/sntp.c
+
+# MDNSFILES: MDNS responder
+MDNSFILES=$(LWIPDIR)/apps/mdns/mdns.c
+
+# NETBIOSNSFILES: NetBIOS name server
+NETBIOSNSFILES=$(LWIPDIR)/apps/netbiosns/netbiosns.c
+
+# TFTPFILES: TFTP server files
+TFTPFILES=$(LWIPDIR)/apps/tftp/tftp_server.c
+
+# MQTTFILES: MQTT client files
+MQTTFILES=$(LWIPDIR)/apps/mqtt/mqtt.c
+
+# MBEDTLS_FILES: MBEDTLS related files of lwIP rep
+MBEDTLS_FILES=$(LWIPDIR)/apps/altcp_tls/altcp_tls_mbedtls.c \
+	$(LWIPDIR)/apps/altcp_tls/altcp_tls_mbedtls_mem.c \
+	$(LWIPDIR)/apps/snmp/snmpv3_mbedtls.c
+
+# LWIPAPPFILES: All LWIP APPs
+LWIPAPPFILES=$(SNMPFILES) \
+	$(HTTPFILES) \
+	$(LWIPERFFILES) \
+	$(SMTPFILES) \
+	$(SNTPFILES) \
+	$(MDNSFILES) \
+	$(NETBIOSNSFILES) \
+	$(TFTPFILES) \
+	$(MQTTFILES) \
+	$(MBEDTLS_FILES)
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/api/api_lib.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/api/api_lib.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/api/api_lib.c	(revision 457)
@@ -0,0 +1,1367 @@
+/**
+ * @file
+ * Sequential API External module
+ *
+ * @defgroup netconn Netconn API
+ * @ingroup sequential_api
+ * Thread-safe, to be called from non-TCPIP threads only.
+ * TX/RX handling based on @ref netbuf (containing @ref pbuf)
+ * to avoid copying data around.
+ *
+ * @defgroup netconn_common Common functions
+ * @ingroup netconn
+ * For use with TCP and UDP
+ *
+ * @defgroup netconn_tcp TCP only
+ * @ingroup netconn
+ * TCP only functions
+ *
+ * @defgroup netconn_udp UDP only
+ * @ingroup netconn
+ * UDP only functions
+ */
+
+/*
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Adam Dunkels <adam@sics.se>
+ */
+
+/* This is the part of the API that is linked with
+   the application */
+
+#include "lwip/opt.h"
+
+#if LWIP_NETCONN /* don't build if not configured for use in lwipopts.h */
+
+#include "lwip/api.h"
+#include "lwip/memp.h"
+
+#include "lwip/ip.h"
+#include "lwip/raw.h"
+#include "lwip/udp.h"
+#include "lwip/priv/api_msg.h"
+#include "lwip/priv/tcp_priv.h"
+#include "lwip/priv/tcpip_priv.h"
+
+#ifdef LWIP_HOOK_FILENAME
+#include LWIP_HOOK_FILENAME
+#endif
+
+#include <string.h>
+
+#define API_MSG_VAR_REF(name)               API_VAR_REF(name)
+#define API_MSG_VAR_DECLARE(name)           API_VAR_DECLARE(struct api_msg, name)
+#define API_MSG_VAR_ALLOC(name)             API_VAR_ALLOC(struct api_msg, MEMP_API_MSG, name, ERR_MEM)
+#define API_MSG_VAR_ALLOC_RETURN_NULL(name) API_VAR_ALLOC(struct api_msg, MEMP_API_MSG, name, NULL)
+#define API_MSG_VAR_FREE(name)              API_VAR_FREE(MEMP_API_MSG, name)
+
+#if TCP_LISTEN_BACKLOG
+/* need to allocate API message for accept so empty message pool does not result in event loss
+ * see bug #47512: MPU_COMPATIBLE may fail on empty pool */
+#define API_MSG_VAR_ALLOC_ACCEPT(msg) API_MSG_VAR_ALLOC(msg)
+#define API_MSG_VAR_FREE_ACCEPT(msg) API_MSG_VAR_FREE(msg)
+#else /* TCP_LISTEN_BACKLOG */
+#define API_MSG_VAR_ALLOC_ACCEPT(msg)
+#define API_MSG_VAR_FREE_ACCEPT(msg)
+#endif /* TCP_LISTEN_BACKLOG */
+
+#if LWIP_NETCONN_FULLDUPLEX
+#define NETCONN_RECVMBOX_WAITABLE(conn) (sys_mbox_valid(&(conn)->recvmbox) && (((conn)->flags & NETCONN_FLAG_MBOXINVALID) == 0))
+#define NETCONN_ACCEPTMBOX_WAITABLE(conn) (sys_mbox_valid(&(conn)->acceptmbox) && (((conn)->flags & (NETCONN_FLAG_MBOXCLOSED|NETCONN_FLAG_MBOXINVALID)) == 0))
+#define NETCONN_MBOX_WAITING_INC(conn) SYS_ARCH_INC(conn->mbox_threads_waiting, 1)
+#define NETCONN_MBOX_WAITING_DEC(conn) SYS_ARCH_DEC(conn->mbox_threads_waiting, 1)
+#else /* LWIP_NETCONN_FULLDUPLEX */
+#define NETCONN_RECVMBOX_WAITABLE(conn)   sys_mbox_valid(&(conn)->recvmbox)
+#define NETCONN_ACCEPTMBOX_WAITABLE(conn) (sys_mbox_valid(&(conn)->acceptmbox) && (((conn)->flags & NETCONN_FLAG_MBOXCLOSED) == 0))
+#define NETCONN_MBOX_WAITING_INC(conn)
+#define NETCONN_MBOX_WAITING_DEC(conn)
+#endif /* LWIP_NETCONN_FULLDUPLEX */
+
+static err_t netconn_close_shutdown(struct netconn *conn, u8_t how);
+
+/**
+ * Call the lower part of a netconn_* function
+ * This function is then running in the thread context
+ * of tcpip_thread and has exclusive access to lwIP core code.
+ *
+ * @param fn function to call
+ * @param apimsg a struct containing the function to call and its parameters
+ * @return ERR_OK if the function was called, another err_t if not
+ */
+static err_t
+netconn_apimsg(tcpip_callback_fn fn, struct api_msg *apimsg)
+{
+  err_t err;
+
+#ifdef LWIP_DEBUG
+  /* catch functions that don't set err */
+  apimsg->err = ERR_VAL;
+#endif /* LWIP_DEBUG */
+
+#if LWIP_NETCONN_SEM_PER_THREAD
+  apimsg->op_completed_sem = LWIP_NETCONN_THREAD_SEM_GET();
+#endif /* LWIP_NETCONN_SEM_PER_THREAD */
+
+  err = tcpip_send_msg_wait_sem(fn, apimsg, LWIP_API_MSG_SEM(apimsg));
+  if (err == ERR_OK) {
+    return apimsg->err;
+  }
+  return err;
+}
+
+/**
+ * Create a new netconn (of a specific type) that has a callback function.
+ * The corresponding pcb is also created.
+ *
+ * @param t the type of 'connection' to create (@see enum netconn_type)
+ * @param proto the IP protocol for RAW IP pcbs
+ * @param callback a function to call on status changes (RX available, TX'ed)
+ * @return a newly allocated struct netconn or
+ *         NULL on memory error
+ */
+struct netconn *
+netconn_new_with_proto_and_callback(enum netconn_type t, u8_t proto, netconn_callback callback)
+{
+  struct netconn *conn;
+  API_MSG_VAR_DECLARE(msg);
+  API_MSG_VAR_ALLOC_RETURN_NULL(msg);
+
+  conn = netconn_alloc(t, callback);
+  if (conn != NULL) {
+    err_t err;
+
+    API_MSG_VAR_REF(msg).msg.n.proto = proto;
+    API_MSG_VAR_REF(msg).conn = conn;
+    err = netconn_apimsg(lwip_netconn_do_newconn, &API_MSG_VAR_REF(msg));
+    if (err != ERR_OK) {
+      LWIP_ASSERT("freeing conn without freeing pcb", conn->pcb.tcp == NULL);
+      LWIP_ASSERT("conn has no recvmbox", sys_mbox_valid(&conn->recvmbox));
+#if LWIP_TCP
+      LWIP_ASSERT("conn->acceptmbox shouldn't exist", !sys_mbox_valid(&conn->acceptmbox));
+#endif /* LWIP_TCP */
+#if !LWIP_NETCONN_SEM_PER_THREAD
+      LWIP_ASSERT("conn has no op_completed", sys_sem_valid(&conn->op_completed));
+      sys_sem_free(&conn->op_completed);
+#endif /* !LWIP_NETCONN_SEM_PER_THREAD */
+      sys_mbox_free(&conn->recvmbox);
+      memp_free(MEMP_NETCONN, conn);
+      API_MSG_VAR_FREE(msg);
+      return NULL;
+    }
+  }
+  API_MSG_VAR_FREE(msg);
+  return conn;
+}
+
+/**
+ * @ingroup netconn_common
+ * Close a netconn 'connection' and free all its resources but not the netconn itself.
+ * UDP and RAW connection are completely closed, TCP pcbs might still be in a waitstate
+ * after this returns.
+ *
+ * @param conn the netconn to delete
+ * @return ERR_OK if the connection was deleted
+ */
+err_t
+netconn_prepare_delete(struct netconn *conn)
+{
+  err_t err;
+  API_MSG_VAR_DECLARE(msg);
+
+  /* No ASSERT here because possible to get a (conn == NULL) if we got an accept error */
+  if (conn == NULL) {
+    return ERR_OK;
+  }
+
+  API_MSG_VAR_ALLOC(msg);
+  API_MSG_VAR_REF(msg).conn = conn;
+#if LWIP_SO_SNDTIMEO || LWIP_SO_LINGER
+  /* get the time we started, which is later compared to
+     sys_now() + conn->send_timeout */
+  API_MSG_VAR_REF(msg).msg.sd.time_started = sys_now();
+#else /* LWIP_SO_SNDTIMEO || LWIP_SO_LINGER */
+#if LWIP_TCP
+  API_MSG_VAR_REF(msg).msg.sd.polls_left =
+    ((LWIP_TCP_CLOSE_TIMEOUT_MS_DEFAULT + TCP_SLOW_INTERVAL - 1) / TCP_SLOW_INTERVAL) + 1;
+#endif /* LWIP_TCP */
+#endif /* LWIP_SO_SNDTIMEO || LWIP_SO_LINGER */
+  err = netconn_apimsg(lwip_netconn_do_delconn, &API_MSG_VAR_REF(msg));
+  API_MSG_VAR_FREE(msg);
+
+  if (err != ERR_OK) {
+    return err;
+  }
+  return ERR_OK;
+}
+
+/**
+ * @ingroup netconn_common
+ * Close a netconn 'connection' and free its resources.
+ * UDP and RAW connection are completely closed, TCP pcbs might still be in a waitstate
+ * after this returns.
+ *
+ * @param conn the netconn to delete
+ * @return ERR_OK if the connection was deleted
+ */
+err_t
+netconn_delete(struct netconn *conn)
+{
+  err_t err;
+
+  /* No ASSERT here because possible to get a (conn == NULL) if we got an accept error */
+  if (conn == NULL) {
+    return ERR_OK;
+  }
+
+#if LWIP_NETCONN_FULLDUPLEX
+  if (conn->flags & NETCONN_FLAG_MBOXINVALID) {
+    /* Already called netconn_prepare_delete() before */
+    err = ERR_OK;
+  } else
+#endif /* LWIP_NETCONN_FULLDUPLEX */
+  {
+    err = netconn_prepare_delete(conn);
+  }
+  if (err == ERR_OK) {
+    netconn_free(conn);
+  }
+  return err;
+}
+
+/**
+ * Get the local or remote IP address and port of a netconn.
+ * For RAW netconns, this returns the protocol instead of a port!
+ *
+ * @param conn the netconn to query
+ * @param addr a pointer to which to save the IP address
+ * @param port a pointer to which to save the port (or protocol for RAW)
+ * @param local 1 to get the local IP address, 0 to get the remote one
+ * @return ERR_CONN for invalid connections
+ *         ERR_OK if the information was retrieved
+ */
+err_t
+netconn_getaddr(struct netconn *conn, ip_addr_t *addr, u16_t *port, u8_t local)
+{
+  API_MSG_VAR_DECLARE(msg);
+  err_t err;
+
+  LWIP_ERROR("netconn_getaddr: invalid conn", (conn != NULL), return ERR_ARG;);
+  LWIP_ERROR("netconn_getaddr: invalid addr", (addr != NULL), return ERR_ARG;);
+  LWIP_ERROR("netconn_getaddr: invalid port", (port != NULL), return ERR_ARG;);
+
+  API_MSG_VAR_ALLOC(msg);
+  API_MSG_VAR_REF(msg).conn = conn;
+  API_MSG_VAR_REF(msg).msg.ad.local = local;
+#if LWIP_MPU_COMPATIBLE
+  err = netconn_apimsg(lwip_netconn_do_getaddr, &API_MSG_VAR_REF(msg));
+  *addr = msg->msg.ad.ipaddr;
+  *port = msg->msg.ad.port;
+#else /* LWIP_MPU_COMPATIBLE */
+  msg.msg.ad.ipaddr = addr;
+  msg.msg.ad.port = port;
+  err = netconn_apimsg(lwip_netconn_do_getaddr, &msg);
+#endif /* LWIP_MPU_COMPATIBLE */
+  API_MSG_VAR_FREE(msg);
+
+  return err;
+}
+
+/**
+ * @ingroup netconn_common
+ * Bind a netconn to a specific local IP address and port.
+ * Binding one netconn twice might not always be checked correctly!
+ *
+ * @param conn the netconn to bind
+ * @param addr the local IP address to bind the netconn to
+ *             (use IP4_ADDR_ANY/IP6_ADDR_ANY to bind to all addresses)
+ * @param port the local port to bind the netconn to (not used for RAW)
+ * @return ERR_OK if bound, any other err_t on failure
+ */
+err_t
+netconn_bind(struct netconn *conn, const ip_addr_t *addr, u16_t port)
+{
+  API_MSG_VAR_DECLARE(msg);
+  err_t err;
+
+  LWIP_ERROR("netconn_bind: invalid conn", (conn != NULL), return ERR_ARG;);
+
+#if LWIP_IPV4
+  /* Don't propagate NULL pointer (IP_ADDR_ANY alias) to subsequent functions */
+  if (addr == NULL) {
+    addr = IP4_ADDR_ANY;
+  }
+#endif /* LWIP_IPV4 */
+
+#if LWIP_IPV4 && LWIP_IPV6
+  /* "Socket API like" dual-stack support: If IP to bind to is IP6_ADDR_ANY,
+   * and NETCONN_FLAG_IPV6_V6ONLY is 0, use IP_ANY_TYPE to bind
+   */
+  if ((netconn_get_ipv6only(conn) == 0) &&
+      ip_addr_cmp(addr, IP6_ADDR_ANY)) {
+    addr = IP_ANY_TYPE;
+  }
+#endif /* LWIP_IPV4 && LWIP_IPV6 */
+
+  API_MSG_VAR_ALLOC(msg);
+  API_MSG_VAR_REF(msg).conn = conn;
+  API_MSG_VAR_REF(msg).msg.bc.ipaddr = API_MSG_VAR_REF(addr);
+  API_MSG_VAR_REF(msg).msg.bc.port = port;
+  err = netconn_apimsg(lwip_netconn_do_bind, &API_MSG_VAR_REF(msg));
+  API_MSG_VAR_FREE(msg);
+
+  return err;
+}
+
+/**
+ * @ingroup netconn_common
+ * Bind a netconn to a specific interface and port.
+ * Binding one netconn twice might not always be checked correctly!
+ *
+ * @param conn the netconn to bind
+ * @param if_idx the local interface index to bind the netconn to
+ * @return ERR_OK if bound, any other err_t on failure
+ */
+err_t
+netconn_bind_if(struct netconn *conn, u8_t if_idx)
+{
+  API_MSG_VAR_DECLARE(msg);
+  err_t err;
+
+  LWIP_ERROR("netconn_bind_if: invalid conn", (conn != NULL), return ERR_ARG;);
+
+  API_MSG_VAR_ALLOC(msg);
+  API_MSG_VAR_REF(msg).conn = conn;
+  API_MSG_VAR_REF(msg).msg.bc.if_idx = if_idx;
+  err = netconn_apimsg(lwip_netconn_do_bind_if, &API_MSG_VAR_REF(msg));
+  API_MSG_VAR_FREE(msg);
+
+  return err;
+}
+
+/**
+ * @ingroup netconn_common
+ * Connect a netconn to a specific remote IP address and port.
+ *
+ * @param conn the netconn to connect
+ * @param addr the remote IP address to connect to
+ * @param port the remote port to connect to (no used for RAW)
+ * @return ERR_OK if connected, return value of tcp_/udp_/raw_connect otherwise
+ */
+err_t
+netconn_connect(struct netconn *conn, const ip_addr_t *addr, u16_t port)
+{
+  API_MSG_VAR_DECLARE(msg);
+  err_t err;
+
+  LWIP_ERROR("netconn_connect: invalid conn", (conn != NULL), return ERR_ARG;);
+
+#if LWIP_IPV4
+  /* Don't propagate NULL pointer (IP_ADDR_ANY alias) to subsequent functions */
+  if (addr == NULL) {
+    addr = IP4_ADDR_ANY;
+  }
+#endif /* LWIP_IPV4 */
+
+  API_MSG_VAR_ALLOC(msg);
+  API_MSG_VAR_REF(msg).conn = conn;
+  API_MSG_VAR_REF(msg).msg.bc.ipaddr = API_MSG_VAR_REF(addr);
+  API_MSG_VAR_REF(msg).msg.bc.port = port;
+  err = netconn_apimsg(lwip_netconn_do_connect, &API_MSG_VAR_REF(msg));
+  API_MSG_VAR_FREE(msg);
+
+  return err;
+}
+
+/**
+ * @ingroup netconn_udp
+ * Disconnect a netconn from its current peer (only valid for UDP netconns).
+ *
+ * @param conn the netconn to disconnect
+ * @return See @ref err_t
+ */
+err_t
+netconn_disconnect(struct netconn *conn)
+{
+  API_MSG_VAR_DECLARE(msg);
+  err_t err;
+
+  LWIP_ERROR("netconn_disconnect: invalid conn", (conn != NULL), return ERR_ARG;);
+
+  API_MSG_VAR_ALLOC(msg);
+  API_MSG_VAR_REF(msg).conn = conn;
+  err = netconn_apimsg(lwip_netconn_do_disconnect, &API_MSG_VAR_REF(msg));
+  API_MSG_VAR_FREE(msg);
+
+  return err;
+}
+
+/**
+ * @ingroup netconn_tcp
+ * Set a TCP netconn into listen mode
+ *
+ * @param conn the tcp netconn to set to listen mode
+ * @param backlog the listen backlog, only used if TCP_LISTEN_BACKLOG==1
+ * @return ERR_OK if the netconn was set to listen (UDP and RAW netconns
+ *         don't return any error (yet?))
+ */
+err_t
+netconn_listen_with_backlog(struct netconn *conn, u8_t backlog)
+{
+#if LWIP_TCP
+  API_MSG_VAR_DECLARE(msg);
+  err_t err;
+
+  /* This does no harm. If TCP_LISTEN_BACKLOG is off, backlog is unused. */
+  LWIP_UNUSED_ARG(backlog);
+
+  LWIP_ERROR("netconn_listen: invalid conn", (conn != NULL), return ERR_ARG;);
+
+  API_MSG_VAR_ALLOC(msg);
+  API_MSG_VAR_REF(msg).conn = conn;
+#if TCP_LISTEN_BACKLOG
+  API_MSG_VAR_REF(msg).msg.lb.backlog = backlog;
+#endif /* TCP_LISTEN_BACKLOG */
+  err = netconn_apimsg(lwip_netconn_do_listen, &API_MSG_VAR_REF(msg));
+  API_MSG_VAR_FREE(msg);
+
+  return err;
+#else /* LWIP_TCP */
+  LWIP_UNUSED_ARG(conn);
+  LWIP_UNUSED_ARG(backlog);
+  return ERR_ARG;
+#endif /* LWIP_TCP */
+}
+
+/**
+ * @ingroup netconn_tcp
+ * Accept a new connection on a TCP listening netconn.
+ *
+ * @param conn the TCP listen netconn
+ * @param new_conn pointer where the new connection is stored
+ * @return ERR_OK if a new connection has been received or an error
+ *                code otherwise
+ */
+err_t
+netconn_accept(struct netconn *conn, struct netconn **new_conn)
+{
+#if LWIP_TCP
+  err_t err;
+  void *accept_ptr;
+  struct netconn *newconn;
+#if TCP_LISTEN_BACKLOG
+  API_MSG_VAR_DECLARE(msg);
+#endif /* TCP_LISTEN_BACKLOG */
+
+  LWIP_ERROR("netconn_accept: invalid pointer",    (new_conn != NULL),                  return ERR_ARG;);
+  *new_conn = NULL;
+  LWIP_ERROR("netconn_accept: invalid conn",       (conn != NULL),                      return ERR_ARG;);
+
+  /* NOTE: Although the opengroup spec says a pending error shall be returned to
+           send/recv/getsockopt(SO_ERROR) only, we return it for listening
+           connections also, to handle embedded-system errors */
+  err = netconn_err(conn);
+  if (err != ERR_OK) {
+    /* return pending error */
+    return err;
+  }
+  if (!NETCONN_ACCEPTMBOX_WAITABLE(conn)) {
+    /* don't accept if closed: this might block the application task
+       waiting on acceptmbox forever! */
+    return ERR_CLSD;
+  }
+
+  API_MSG_VAR_ALLOC_ACCEPT(msg);
+
+  NETCONN_MBOX_WAITING_INC(conn);
+  if (netconn_is_nonblocking(conn)) {
+    if (sys_arch_mbox_tryfetch(&conn->acceptmbox, &accept_ptr) == SYS_ARCH_TIMEOUT) {
+      API_MSG_VAR_FREE_ACCEPT(msg);
+      NETCONN_MBOX_WAITING_DEC(conn);
+      return ERR_WOULDBLOCK;
+    }
+  } else {
+#if LWIP_SO_RCVTIMEO
+    if (sys_arch_mbox_fetch(&conn->acceptmbox, &accept_ptr, conn->recv_timeout) == SYS_ARCH_TIMEOUT) {
+      API_MSG_VAR_FREE_ACCEPT(msg);
+      NETCONN_MBOX_WAITING_DEC(conn);
+      return ERR_TIMEOUT;
+    }
+#else
+    sys_arch_mbox_fetch(&conn->acceptmbox, &accept_ptr, 0);
+#endif /* LWIP_SO_RCVTIMEO*/
+  }
+  NETCONN_MBOX_WAITING_DEC(conn);
+#if LWIP_NETCONN_FULLDUPLEX
+  if (conn->flags & NETCONN_FLAG_MBOXINVALID) {
+    if (lwip_netconn_is_deallocated_msg(accept_ptr)) {
+      /* the netconn has been closed from another thread */
+      API_MSG_VAR_FREE_ACCEPT(msg);
+      return ERR_CONN;
+    }
+  }
+#endif
+
+  /* Register event with callback */
+  API_EVENT(conn, NETCONN_EVT_RCVMINUS, 0);
+
+  if (lwip_netconn_is_err_msg(accept_ptr, &err)) {
+    /* a connection has been aborted: e.g. out of pcbs or out of netconns during accept */
+    API_MSG_VAR_FREE_ACCEPT(msg);
+    return err;
+  }
+  if (accept_ptr == NULL) {
+    /* connection has been aborted */
+    API_MSG_VAR_FREE_ACCEPT(msg);
+    return ERR_CLSD;
+  }
+  newconn = (struct netconn *)accept_ptr;
+#if TCP_LISTEN_BACKLOG
+  /* Let the stack know that we have accepted the connection. */
+  API_MSG_VAR_REF(msg).conn = newconn;
+  /* don't care for the return value of lwip_netconn_do_recv */
+  netconn_apimsg(lwip_netconn_do_accepted, &API_MSG_VAR_REF(msg));
+  API_MSG_VAR_FREE(msg);
+#endif /* TCP_LISTEN_BACKLOG */
+
+  *new_conn = newconn;
+  /* don't set conn->last_err: it's only ERR_OK, anyway */
+  return ERR_OK;
+#else /* LWIP_TCP */
+  LWIP_UNUSED_ARG(conn);
+  LWIP_UNUSED_ARG(new_conn);
+  return ERR_ARG;
+#endif /* LWIP_TCP */
+}
+
+/**
+ * @ingroup netconn_common
+ * Receive data: actual implementation that doesn't care whether pbuf or netbuf
+ * is received (this is internal, it's just here for describing common errors)
+ *
+ * @param conn the netconn from which to receive data
+ * @param new_buf pointer where a new pbuf/netbuf is stored when received data
+ * @param apiflags flags that control function behaviour. For now only:
+ * - NETCONN_DONTBLOCK: only read data that is available now, don't wait for more data
+ * @return ERR_OK if data has been received, an error code otherwise (timeout,
+ *                memory error or another error)
+ *         ERR_CONN if not connected
+ *         ERR_CLSD if TCP connection has been closed
+ *         ERR_WOULDBLOCK if the netconn is nonblocking but would block to wait for data
+ *         ERR_TIMEOUT if the netconn has a receive timeout and no data was received
+ */
+static err_t
+netconn_recv_data(struct netconn *conn, void **new_buf, u8_t apiflags)
+{
+  void *buf = NULL;
+  u16_t len;
+
+  LWIP_ERROR("netconn_recv: invalid pointer", (new_buf != NULL), return ERR_ARG;);
+  *new_buf = NULL;
+  LWIP_ERROR("netconn_recv: invalid conn",    (conn != NULL),    return ERR_ARG;);
+
+  if (!NETCONN_RECVMBOX_WAITABLE(conn)) {
+    err_t err = netconn_err(conn);
+    if (err != ERR_OK) {
+      /* return pending error */
+      return err;
+    }
+    return ERR_CONN;
+  }
+
+  NETCONN_MBOX_WAITING_INC(conn);
+  if (netconn_is_nonblocking(conn) || (apiflags & NETCONN_DONTBLOCK) ||
+      (conn->flags & NETCONN_FLAG_MBOXCLOSED) || (conn->pending_err != ERR_OK)) {
+    if (sys_arch_mbox_tryfetch(&conn->recvmbox, &buf) == SYS_ARCH_TIMEOUT) {
+      err_t err;
+      NETCONN_MBOX_WAITING_DEC(conn);
+      err = netconn_err(conn);
+      if (err != ERR_OK) {
+        /* return pending error */
+        return err;
+      }
+      if (conn->flags & NETCONN_FLAG_MBOXCLOSED) {
+        return ERR_CONN;
+      }
+      return ERR_WOULDBLOCK;
+    }
+  } else {
+#if LWIP_SO_RCVTIMEO
+    if (sys_arch_mbox_fetch(&conn->recvmbox, &buf, conn->recv_timeout) == SYS_ARCH_TIMEOUT) {
+      NETCONN_MBOX_WAITING_DEC(conn);
+      return ERR_TIMEOUT;
+    }
+#else
+    sys_arch_mbox_fetch(&conn->recvmbox, &buf, 0);
+#endif /* LWIP_SO_RCVTIMEO*/
+  }
+  NETCONN_MBOX_WAITING_DEC(conn);
+#if LWIP_NETCONN_FULLDUPLEX
+  if (conn->flags & NETCONN_FLAG_MBOXINVALID) {
+    if (lwip_netconn_is_deallocated_msg(buf)) {
+      /* the netconn has been closed from another thread */
+      API_MSG_VAR_FREE_ACCEPT(msg);
+      return ERR_CONN;
+    }
+  }
+#endif
+
+#if LWIP_TCP
+#if (LWIP_UDP || LWIP_RAW)
+  if (NETCONNTYPE_GROUP(conn->type) == NETCONN_TCP)
+#endif /* (LWIP_UDP || LWIP_RAW) */
+  {
+    err_t err;
+    /* Check if this is an error message or a pbuf */
+    if (lwip_netconn_is_err_msg(buf, &err)) {
+      /* new_buf has been zeroed above already */
+      if (err == ERR_CLSD) {
+        /* connection closed translates to ERR_OK with *new_buf == NULL */
+        return ERR_OK;
+      }
+      return err;
+    }
+    len = ((struct pbuf *)buf)->tot_len;
+  }
+#endif /* LWIP_TCP */
+#if LWIP_TCP && (LWIP_UDP || LWIP_RAW)
+  else
+#endif /* LWIP_TCP && (LWIP_UDP || LWIP_RAW) */
+#if (LWIP_UDP || LWIP_RAW)
+  {
+    LWIP_ASSERT("buf != NULL", buf != NULL);
+    len = netbuf_len((struct netbuf *)buf);
+  }
+#endif /* (LWIP_UDP || LWIP_RAW) */
+
+#if LWIP_SO_RCVBUF
+  SYS_ARCH_DEC(conn->recv_avail, len);
+#endif /* LWIP_SO_RCVBUF */
+  /* Register event with callback */
+  API_EVENT(conn, NETCONN_EVT_RCVMINUS, len);
+
+  LWIP_DEBUGF(API_LIB_DEBUG, ("netconn_recv_data: received %p, len=%"U16_F"\n", buf, len));
+
+  *new_buf = buf;
+  /* don't set conn->last_err: it's only ERR_OK, anyway */
+  return ERR_OK;
+}
+
+#if LWIP_TCP
+static err_t
+netconn_tcp_recvd_msg(struct netconn *conn, size_t len, struct api_msg *msg)
+{
+  LWIP_ERROR("netconn_recv_tcp_pbuf: invalid conn", (conn != NULL) &&
+             NETCONNTYPE_GROUP(netconn_type(conn)) == NETCONN_TCP, return ERR_ARG;);
+
+  msg->conn = conn;
+  msg->msg.r.len = len;
+
+  return netconn_apimsg(lwip_netconn_do_recv, msg);
+}
+
+err_t
+netconn_tcp_recvd(struct netconn *conn, size_t len)
+{
+  err_t err;
+  API_MSG_VAR_DECLARE(msg);
+  LWIP_ERROR("netconn_recv_tcp_pbuf: invalid conn", (conn != NULL) &&
+             NETCONNTYPE_GROUP(netconn_type(conn)) == NETCONN_TCP, return ERR_ARG;);
+
+  API_MSG_VAR_ALLOC(msg);
+  err = netconn_tcp_recvd_msg(conn, len, &API_VAR_REF(msg));
+  API_MSG_VAR_FREE(msg);
+  return err;
+}
+
+static err_t
+netconn_recv_data_tcp(struct netconn *conn, struct pbuf **new_buf, u8_t apiflags)
+{
+  err_t err;
+  struct pbuf *buf;
+  API_MSG_VAR_DECLARE(msg);
+#if LWIP_MPU_COMPATIBLE
+  msg = NULL;
+#endif
+
+  if (!NETCONN_RECVMBOX_WAITABLE(conn)) {
+    /* This only happens when calling this function more than once *after* receiving FIN */
+    return ERR_CONN;
+  }
+  if (netconn_is_flag_set(conn, NETCONN_FIN_RX_PENDING)) {
+    netconn_clear_flags(conn, NETCONN_FIN_RX_PENDING);
+    goto handle_fin;
+  }
+
+  if (!(apiflags & NETCONN_NOAUTORCVD)) {
+    /* need to allocate API message here so empty message pool does not result in event loss
+      * see bug #47512: MPU_COMPATIBLE may fail on empty pool */
+    API_MSG_VAR_ALLOC(msg);
+  }
+
+  err = netconn_recv_data(conn, (void **)new_buf, apiflags);
+  if (err != ERR_OK) {
+    if (!(apiflags & NETCONN_NOAUTORCVD)) {
+      API_MSG_VAR_FREE(msg);
+    }
+    return err;
+  }
+  buf = *new_buf;
+  if (!(apiflags & NETCONN_NOAUTORCVD)) {
+    /* Let the stack know that we have taken the data. */
+    u16_t len = buf ? buf->tot_len : 1;
+    /* don't care for the return value of lwip_netconn_do_recv */
+    /* @todo: this should really be fixed, e.g. by retrying in poll on error */
+    netconn_tcp_recvd_msg(conn, len,  &API_VAR_REF(msg));
+    API_MSG_VAR_FREE(msg);
+  }
+
+  /* If we are closed, we indicate that we no longer wish to use the socket */
+  if (buf == NULL) {
+    if (apiflags & NETCONN_NOFIN) {
+      /* received a FIN but the caller cannot handle it right now:
+         re-enqueue it and return "no data" */
+      netconn_set_flags(conn, NETCONN_FIN_RX_PENDING);
+      return ERR_WOULDBLOCK;
+    } else {
+handle_fin:
+      API_EVENT(conn, NETCONN_EVT_RCVMINUS, 0);
+      if (conn->pcb.ip == NULL) {
+        /* race condition: RST during recv */
+        err = netconn_err(conn);
+        if (err != ERR_OK) {
+          return err;
+        }
+        return ERR_RST;
+      }
+      /* RX side is closed, so deallocate the recvmbox */
+      netconn_close_shutdown(conn, NETCONN_SHUT_RD);
+      /* Don' store ERR_CLSD as conn->err since we are only half-closed */
+      return ERR_CLSD;
+    }
+  }
+  return err;
+}
+
+/**
+ * @ingroup netconn_tcp
+ * Receive data (in form of a pbuf) from a TCP netconn
+ *
+ * @param conn the netconn from which to receive data
+ * @param new_buf pointer where a new pbuf is stored when received data
+ * @return ERR_OK if data has been received, an error code otherwise (timeout,
+ *                memory error or another error, @see netconn_recv_data)
+ *         ERR_ARG if conn is not a TCP netconn
+ */
+err_t
+netconn_recv_tcp_pbuf(struct netconn *conn, struct pbuf **new_buf)
+{
+  LWIP_ERROR("netconn_recv_tcp_pbuf: invalid conn", (conn != NULL) &&
+             NETCONNTYPE_GROUP(netconn_type(conn)) == NETCONN_TCP, return ERR_ARG;);
+
+  return netconn_recv_data_tcp(conn, new_buf, 0);
+}
+
+/**
+ * @ingroup netconn_tcp
+ * Receive data (in form of a pbuf) from a TCP netconn
+ *
+ * @param conn the netconn from which to receive data
+ * @param new_buf pointer where a new pbuf is stored when received data
+ * @param apiflags flags that control function behaviour. For now only:
+ * - NETCONN_DONTBLOCK: only read data that is available now, don't wait for more data
+ * @return ERR_OK if data has been received, an error code otherwise (timeout,
+ *                memory error or another error, @see netconn_recv_data)
+ *         ERR_ARG if conn is not a TCP netconn
+ */
+err_t
+netconn_recv_tcp_pbuf_flags(struct netconn *conn, struct pbuf **new_buf, u8_t apiflags)
+{
+  LWIP_ERROR("netconn_recv_tcp_pbuf: invalid conn", (conn != NULL) &&
+             NETCONNTYPE_GROUP(netconn_type(conn)) == NETCONN_TCP, return ERR_ARG;);
+
+  return netconn_recv_data_tcp(conn, new_buf, apiflags);
+}
+#endif /* LWIP_TCP */
+
+/**
+ * Receive data (in form of a netbuf) from a UDP or RAW netconn
+ *
+ * @param conn the netconn from which to receive data
+ * @param new_buf pointer where a new netbuf is stored when received data
+ * @return ERR_OK if data has been received, an error code otherwise (timeout,
+ *                memory error or another error)
+ *         ERR_ARG if conn is not a UDP/RAW netconn
+ */
+err_t
+netconn_recv_udp_raw_netbuf(struct netconn *conn, struct netbuf **new_buf)
+{
+  LWIP_ERROR("netconn_recv_udp_raw_netbuf: invalid conn", (conn != NULL) &&
+             NETCONNTYPE_GROUP(netconn_type(conn)) != NETCONN_TCP, return ERR_ARG;);
+
+  return netconn_recv_data(conn, (void **)new_buf, 0);
+}
+
+/**
+ * Receive data (in form of a netbuf) from a UDP or RAW netconn
+ *
+ * @param conn the netconn from which to receive data
+ * @param new_buf pointer where a new netbuf is stored when received data
+ * @param apiflags flags that control function behaviour. For now only:
+ * - NETCONN_DONTBLOCK: only read data that is available now, don't wait for more data
+ * @return ERR_OK if data has been received, an error code otherwise (timeout,
+ *                memory error or another error)
+ *         ERR_ARG if conn is not a UDP/RAW netconn
+ */
+err_t
+netconn_recv_udp_raw_netbuf_flags(struct netconn *conn, struct netbuf **new_buf, u8_t apiflags)
+{
+  LWIP_ERROR("netconn_recv_udp_raw_netbuf: invalid conn", (conn != NULL) &&
+             NETCONNTYPE_GROUP(netconn_type(conn)) != NETCONN_TCP, return ERR_ARG;);
+
+  return netconn_recv_data(conn, (void **)new_buf, apiflags);
+}
+
+/**
+ * @ingroup netconn_common
+ * Receive data (in form of a netbuf containing a packet buffer) from a netconn
+ *
+ * @param conn the netconn from which to receive data
+ * @param new_buf pointer where a new netbuf is stored when received data
+ * @return ERR_OK if data has been received, an error code otherwise (timeout,
+ *                memory error or another error)
+ */
+err_t
+netconn_recv(struct netconn *conn, struct netbuf **new_buf)
+{
+#if LWIP_TCP
+  struct netbuf *buf = NULL;
+  err_t err;
+#endif /* LWIP_TCP */
+
+  LWIP_ERROR("netconn_recv: invalid pointer", (new_buf != NULL), return ERR_ARG;);
+  *new_buf = NULL;
+  LWIP_ERROR("netconn_recv: invalid conn",    (conn != NULL),    return ERR_ARG;);
+
+#if LWIP_TCP
+#if (LWIP_UDP || LWIP_RAW)
+  if (NETCONNTYPE_GROUP(conn->type) == NETCONN_TCP)
+#endif /* (LWIP_UDP || LWIP_RAW) */
+  {
+    struct pbuf *p = NULL;
+    /* This is not a listening netconn, since recvmbox is set */
+
+    buf = (struct netbuf *)memp_malloc(MEMP_NETBUF);
+    if (buf == NULL) {
+      return ERR_MEM;
+    }
+
+    err = netconn_recv_data_tcp(conn, &p, 0);
+    if (err != ERR_OK) {
+      memp_free(MEMP_NETBUF, buf);
+      return err;
+    }
+    LWIP_ASSERT("p != NULL", p != NULL);
+
+    buf->p = p;
+    buf->ptr = p;
+    buf->port = 0;
+    ip_addr_set_zero(&buf->addr);
+    *new_buf = buf;
+    /* don't set conn->last_err: it's only ERR_OK, anyway */
+    return ERR_OK;
+  }
+#endif /* LWIP_TCP */
+#if LWIP_TCP && (LWIP_UDP || LWIP_RAW)
+  else
+#endif /* LWIP_TCP && (LWIP_UDP || LWIP_RAW) */
+  {
+#if (LWIP_UDP || LWIP_RAW)
+    return netconn_recv_data(conn, (void **)new_buf, 0);
+#endif /* (LWIP_UDP || LWIP_RAW) */
+  }
+}
+
+/**
+ * @ingroup netconn_udp
+ * Send data (in form of a netbuf) to a specific remote IP address and port.
+ * Only to be used for UDP and RAW netconns (not TCP).
+ *
+ * @param conn the netconn over which to send data
+ * @param buf a netbuf containing the data to send
+ * @param addr the remote IP address to which to send the data
+ * @param port the remote port to which to send the data
+ * @return ERR_OK if data was sent, any other err_t on error
+ */
+err_t
+netconn_sendto(struct netconn *conn, struct netbuf *buf, const ip_addr_t *addr, u16_t port)
+{
+  if (buf != NULL) {
+    ip_addr_set(&buf->addr, addr);
+    buf->port = port;
+    return netconn_send(conn, buf);
+  }
+  return ERR_VAL;
+}
+
+/**
+ * @ingroup netconn_udp
+ * Send data over a UDP or RAW netconn (that is already connected).
+ *
+ * @param conn the UDP or RAW netconn over which to send data
+ * @param buf a netbuf containing the data to send
+ * @return ERR_OK if data was sent, any other err_t on error
+ */
+err_t
+netconn_send(struct netconn *conn, struct netbuf *buf)
+{
+  API_MSG_VAR_DECLARE(msg);
+  err_t err;
+
+  LWIP_ERROR("netconn_send: invalid conn",  (conn != NULL), return ERR_ARG;);
+
+  LWIP_DEBUGF(API_LIB_DEBUG, ("netconn_send: sending %"U16_F" bytes\n", buf->p->tot_len));
+
+  API_MSG_VAR_ALLOC(msg);
+  API_MSG_VAR_REF(msg).conn = conn;
+  API_MSG_VAR_REF(msg).msg.b = buf;
+  err = netconn_apimsg(lwip_netconn_do_send, &API_MSG_VAR_REF(msg));
+  API_MSG_VAR_FREE(msg);
+
+  return err;
+}
+
+/**
+ * @ingroup netconn_tcp
+ * Send data over a TCP netconn.
+ *
+ * @param conn the TCP netconn over which to send data
+ * @param dataptr pointer to the application buffer that contains the data to send
+ * @param size size of the application data to send
+ * @param apiflags combination of following flags :
+ * - NETCONN_COPY: data will be copied into memory belonging to the stack
+ * - NETCONN_MORE: for TCP connection, PSH flag will be set on last segment sent
+ * - NETCONN_DONTBLOCK: only write the data if all data can be written at once
+ * @param bytes_written pointer to a location that receives the number of written bytes
+ * @return ERR_OK if data was sent, any other err_t on error
+ */
+err_t
+netconn_write_partly(struct netconn *conn, const void *dataptr, size_t size,
+                     u8_t apiflags, size_t *bytes_written)
+{
+  struct netvector vector;
+  vector.ptr = dataptr;
+  vector.len = size;
+  return netconn_write_vectors_partly(conn, &vector, 1, apiflags, bytes_written);
+}
+
+/**
+ * Send vectorized data atomically over a TCP netconn.
+ *
+ * @param conn the TCP netconn over which to send data
+ * @param vectors array of vectors containing data to send
+ * @param vectorcnt number of vectors in the array
+ * @param apiflags combination of following flags :
+ * - NETCONN_COPY: data will be copied into memory belonging to the stack
+ * - NETCONN_MORE: for TCP connection, PSH flag will be set on last segment sent
+ * - NETCONN_DONTBLOCK: only write the data if all data can be written at once
+ * @param bytes_written pointer to a location that receives the number of written bytes
+ * @return ERR_OK if data was sent, any other err_t on error
+ */
+err_t
+netconn_write_vectors_partly(struct netconn *conn, struct netvector *vectors, u16_t vectorcnt,
+                             u8_t apiflags, size_t *bytes_written)
+{
+  API_MSG_VAR_DECLARE(msg);
+  err_t err;
+  u8_t dontblock;
+  size_t size;
+  int i;
+
+  LWIP_ERROR("netconn_write: invalid conn",  (conn != NULL), return ERR_ARG;);
+  LWIP_ERROR("netconn_write: invalid conn->type",  (NETCONNTYPE_GROUP(conn->type) == NETCONN_TCP), return ERR_VAL;);
+  dontblock = netconn_is_nonblocking(conn) || (apiflags & NETCONN_DONTBLOCK);
+#if LWIP_SO_SNDTIMEO
+  if (conn->send_timeout != 0) {
+    dontblock = 1;
+  }
+#endif /* LWIP_SO_SNDTIMEO */
+  if (dontblock && !bytes_written) {
+    /* This implies netconn_write() cannot be used for non-blocking send, since
+       it has no way to return the number of bytes written. */
+    return ERR_VAL;
+  }
+
+  /* sum up the total size */
+  size = 0;
+  for (i = 0; i < vectorcnt; i++) {
+    size += vectors[i].len;
+    if (size < vectors[i].len) {
+      /* overflow */
+      return ERR_VAL;
+    }
+  }
+  if (size == 0) {
+    return ERR_OK;
+  } else if (size > SSIZE_MAX) {
+    ssize_t limited;
+    /* this is required by the socket layer (cannot send full size_t range) */
+    if (!bytes_written) {
+      return ERR_VAL;
+    }
+    /* limit the amount of data to send */
+    limited = SSIZE_MAX;
+    size = (size_t)limited;
+  }
+
+  API_MSG_VAR_ALLOC(msg);
+  /* non-blocking write sends as much  */
+  API_MSG_VAR_REF(msg).conn = conn;
+  API_MSG_VAR_REF(msg).msg.w.vector = vectors;
+  API_MSG_VAR_REF(msg).msg.w.vector_cnt = vectorcnt;
+  API_MSG_VAR_REF(msg).msg.w.vector_off = 0;
+  API_MSG_VAR_REF(msg).msg.w.apiflags = apiflags;
+  API_MSG_VAR_REF(msg).msg.w.len = size;
+  API_MSG_VAR_REF(msg).msg.w.offset = 0;
+#if LWIP_SO_SNDTIMEO
+  if (conn->send_timeout != 0) {
+    /* get the time we started, which is later compared to
+        sys_now() + conn->send_timeout */
+    API_MSG_VAR_REF(msg).msg.w.time_started = sys_now();
+  } else {
+    API_MSG_VAR_REF(msg).msg.w.time_started = 0;
+  }
+#endif /* LWIP_SO_SNDTIMEO */
+
+  /* For locking the core: this _can_ be delayed on low memory/low send buffer,
+     but if it is, this is done inside api_msg.c:do_write(), so we can use the
+     non-blocking version here. */
+  err = netconn_apimsg(lwip_netconn_do_write, &API_MSG_VAR_REF(msg));
+  if (err == ERR_OK) {
+    if (bytes_written != NULL) {
+      *bytes_written = API_MSG_VAR_REF(msg).msg.w.offset;
+    }
+    /* for blocking, check all requested bytes were written, NOTE: send_timeout is
+       treated as dontblock (see dontblock assignment above) */
+    if (!dontblock) {
+      LWIP_ASSERT("do_write failed to write all bytes", API_MSG_VAR_REF(msg).msg.w.offset == size);
+    }
+  }
+  API_MSG_VAR_FREE(msg);
+
+  return err;
+}
+
+/**
+ * @ingroup netconn_tcp
+ * Close or shutdown a TCP netconn (doesn't delete it).
+ *
+ * @param conn the TCP netconn to close or shutdown
+ * @param how fully close or only shutdown one side?
+ * @return ERR_OK if the netconn was closed, any other err_t on error
+ */
+static err_t
+netconn_close_shutdown(struct netconn *conn, u8_t how)
+{
+  API_MSG_VAR_DECLARE(msg);
+  err_t err;
+  LWIP_UNUSED_ARG(how);
+
+  LWIP_ERROR("netconn_close: invalid conn",  (conn != NULL), return ERR_ARG;);
+
+  API_MSG_VAR_ALLOC(msg);
+  API_MSG_VAR_REF(msg).conn = conn;
+#if LWIP_TCP
+  /* shutting down both ends is the same as closing */
+  API_MSG_VAR_REF(msg).msg.sd.shut = how;
+#if LWIP_SO_SNDTIMEO || LWIP_SO_LINGER
+  /* get the time we started, which is later compared to
+     sys_now() + conn->send_timeout */
+  API_MSG_VAR_REF(msg).msg.sd.time_started = sys_now();
+#else /* LWIP_SO_SNDTIMEO || LWIP_SO_LINGER */
+  API_MSG_VAR_REF(msg).msg.sd.polls_left =
+    ((LWIP_TCP_CLOSE_TIMEOUT_MS_DEFAULT + TCP_SLOW_INTERVAL - 1) / TCP_SLOW_INTERVAL) + 1;
+#endif /* LWIP_SO_SNDTIMEO || LWIP_SO_LINGER */
+#endif /* LWIP_TCP */
+  err = netconn_apimsg(lwip_netconn_do_close, &API_MSG_VAR_REF(msg));
+  API_MSG_VAR_FREE(msg);
+
+  return err;
+}
+
+/**
+ * @ingroup netconn_tcp
+ * Close a TCP netconn (doesn't delete it).
+ *
+ * @param conn the TCP netconn to close
+ * @return ERR_OK if the netconn was closed, any other err_t on error
+ */
+err_t
+netconn_close(struct netconn *conn)
+{
+  /* shutting down both ends is the same as closing */
+  return netconn_close_shutdown(conn, NETCONN_SHUT_RDWR);
+}
+
+/**
+ * @ingroup netconn_common
+ * Get and reset pending error on a netconn
+ *
+ * @param conn the netconn to get the error from
+ * @return and pending error or ERR_OK if no error was pending
+ */
+err_t
+netconn_err(struct netconn *conn)
+{
+  err_t err;
+  SYS_ARCH_DECL_PROTECT(lev);
+  if (conn == NULL) {
+    return ERR_OK;
+  }
+  SYS_ARCH_PROTECT(lev);
+  err = conn->pending_err;
+  conn->pending_err = ERR_OK;
+  SYS_ARCH_UNPROTECT(lev);
+  return err;
+}
+
+/**
+ * @ingroup netconn_tcp
+ * Shut down one or both sides of a TCP netconn (doesn't delete it).
+ *
+ * @param conn the TCP netconn to shut down
+ * @param shut_rx shut down the RX side (no more read possible after this)
+ * @param shut_tx shut down the TX side (no more write possible after this)
+ * @return ERR_OK if the netconn was closed, any other err_t on error
+ */
+err_t
+netconn_shutdown(struct netconn *conn, u8_t shut_rx, u8_t shut_tx)
+{
+  return netconn_close_shutdown(conn, (u8_t)((shut_rx ? NETCONN_SHUT_RD : 0) | (shut_tx ? NETCONN_SHUT_WR : 0)));
+}
+
+#if LWIP_IGMP || (LWIP_IPV6 && LWIP_IPV6_MLD)
+/**
+ * @ingroup netconn_udp
+ * Join multicast groups for UDP netconns.
+ *
+ * @param conn the UDP netconn for which to change multicast addresses
+ * @param multiaddr IP address of the multicast group to join or leave
+ * @param netif_addr the IP address of the network interface on which to send
+ *                  the igmp message
+ * @param join_or_leave flag whether to send a join- or leave-message
+ * @return ERR_OK if the action was taken, any err_t on error
+ */
+err_t
+netconn_join_leave_group(struct netconn *conn,
+                         const ip_addr_t *multiaddr,
+                         const ip_addr_t *netif_addr,
+                         enum netconn_igmp join_or_leave)
+{
+  API_MSG_VAR_DECLARE(msg);
+  err_t err;
+
+  LWIP_ERROR("netconn_join_leave_group: invalid conn",  (conn != NULL), return ERR_ARG;);
+
+  API_MSG_VAR_ALLOC(msg);
+
+#if LWIP_IPV4
+  /* Don't propagate NULL pointer (IP_ADDR_ANY alias) to subsequent functions */
+  if (multiaddr == NULL) {
+    multiaddr = IP4_ADDR_ANY;
+  }
+  if (netif_addr == NULL) {
+    netif_addr = IP4_ADDR_ANY;
+  }
+#endif /* LWIP_IPV4 */
+
+  API_MSG_VAR_REF(msg).conn = conn;
+  API_MSG_VAR_REF(msg).msg.jl.multiaddr = API_MSG_VAR_REF(multiaddr);
+  API_MSG_VAR_REF(msg).msg.jl.netif_addr = API_MSG_VAR_REF(netif_addr);
+  API_MSG_VAR_REF(msg).msg.jl.join_or_leave = join_or_leave;
+  err = netconn_apimsg(lwip_netconn_do_join_leave_group, &API_MSG_VAR_REF(msg));
+  API_MSG_VAR_FREE(msg);
+
+  return err;
+}
+/**
+ * @ingroup netconn_udp
+ * Join multicast groups for UDP netconns.
+ *
+ * @param conn the UDP netconn for which to change multicast addresses
+ * @param multiaddr IP address of the multicast group to join or leave
+ * @param if_idx the index of the netif
+ * @param join_or_leave flag whether to send a join- or leave-message
+ * @return ERR_OK if the action was taken, any err_t on error
+ */
+err_t
+netconn_join_leave_group_netif(struct netconn *conn,
+                               const ip_addr_t *multiaddr,
+                               u8_t if_idx,
+                               enum netconn_igmp join_or_leave)
+{
+  API_MSG_VAR_DECLARE(msg);
+  err_t err;
+
+  LWIP_ERROR("netconn_join_leave_group: invalid conn",  (conn != NULL), return ERR_ARG;);
+
+  API_MSG_VAR_ALLOC(msg);
+
+#if LWIP_IPV4
+  /* Don't propagate NULL pointer (IP_ADDR_ANY alias) to subsequent functions */
+  if (multiaddr == NULL) {
+    multiaddr = IP4_ADDR_ANY;
+  }
+  if (if_idx == NETIF_NO_INDEX) {
+    return ERR_IF;
+  }
+#endif /* LWIP_IPV4 */
+
+  API_MSG_VAR_REF(msg).conn = conn;
+  API_MSG_VAR_REF(msg).msg.jl.multiaddr = API_MSG_VAR_REF(multiaddr);
+  API_MSG_VAR_REF(msg).msg.jl.if_idx = if_idx;
+  API_MSG_VAR_REF(msg).msg.jl.join_or_leave = join_or_leave;
+  err = netconn_apimsg(lwip_netconn_do_join_leave_group_netif, &API_MSG_VAR_REF(msg));
+  API_MSG_VAR_FREE(msg);
+
+  return err;
+}
+#endif /* LWIP_IGMP || (LWIP_IPV6 && LWIP_IPV6_MLD) */
+
+#if LWIP_DNS
+/**
+ * @ingroup netconn_common
+ * Execute a DNS query, only one IP address is returned
+ *
+ * @param name a string representation of the DNS host name to query
+ * @param addr a preallocated ip_addr_t where to store the resolved IP address
+ * @param dns_addrtype IP address type (IPv4 / IPv6)
+ * @return ERR_OK: resolving succeeded
+ *         ERR_MEM: memory error, try again later
+ *         ERR_ARG: dns client not initialized or invalid hostname
+ *         ERR_VAL: dns server response was invalid
+ */
+#if LWIP_IPV4 && LWIP_IPV6
+err_t
+netconn_gethostbyname_addrtype(const char *name, ip_addr_t *addr, u8_t dns_addrtype)
+#else
+err_t
+netconn_gethostbyname(const char *name, ip_addr_t *addr)
+#endif
+{
+  API_VAR_DECLARE(struct dns_api_msg, msg);
+#if !LWIP_MPU_COMPATIBLE
+  sys_sem_t sem;
+#endif /* LWIP_MPU_COMPATIBLE */
+  err_t err;
+  err_t cberr;
+
+  LWIP_ERROR("netconn_gethostbyname: invalid name", (name != NULL), return ERR_ARG;);
+  LWIP_ERROR("netconn_gethostbyname: invalid addr", (addr != NULL), return ERR_ARG;);
+#if LWIP_MPU_COMPATIBLE
+  if (strlen(name) >= DNS_MAX_NAME_LENGTH) {
+    return ERR_ARG;
+  }
+#endif
+
+#ifdef LWIP_HOOK_NETCONN_EXTERNAL_RESOLVE
+#if LWIP_IPV4 && LWIP_IPV6
+  if (LWIP_HOOK_NETCONN_EXTERNAL_RESOLVE(name, addr, dns_addrtype, &err)) {
+#else
+  if (LWIP_HOOK_NETCONN_EXTERNAL_RESOLVE(name, addr, NETCONN_DNS_DEFAULT, &err)) {
+#endif /* LWIP_IPV4 && LWIP_IPV6 */
+    return err;
+  }
+#endif /* LWIP_HOOK_NETCONN_EXTERNAL_RESOLVE */
+
+  API_VAR_ALLOC(struct dns_api_msg, MEMP_DNS_API_MSG, msg, ERR_MEM);
+#if LWIP_MPU_COMPATIBLE
+  strncpy(API_VAR_REF(msg).name, name, DNS_MAX_NAME_LENGTH - 1);
+  API_VAR_REF(msg).name[DNS_MAX_NAME_LENGTH - 1] = 0;
+#else /* LWIP_MPU_COMPATIBLE */
+  msg.err = &err;
+  msg.sem = &sem;
+  API_VAR_REF(msg).addr = API_VAR_REF(addr);
+  API_VAR_REF(msg).name = name;
+#endif /* LWIP_MPU_COMPATIBLE */
+#if LWIP_IPV4 && LWIP_IPV6
+  API_VAR_REF(msg).dns_addrtype = dns_addrtype;
+#endif /* LWIP_IPV4 && LWIP_IPV6 */
+#if LWIP_NETCONN_SEM_PER_THREAD
+  API_VAR_REF(msg).sem = LWIP_NETCONN_THREAD_SEM_GET();
+#else /* LWIP_NETCONN_SEM_PER_THREAD*/
+  err = sys_sem_new(API_EXPR_REF(API_VAR_REF(msg).sem), 0);
+  if (err != ERR_OK) {
+    API_VAR_FREE(MEMP_DNS_API_MSG, msg);
+    return err;
+  }
+#endif /* LWIP_NETCONN_SEM_PER_THREAD */
+
+  cberr = tcpip_send_msg_wait_sem(lwip_netconn_do_gethostbyname, &API_VAR_REF(msg), API_EXPR_REF(API_VAR_REF(msg).sem));
+#if !LWIP_NETCONN_SEM_PER_THREAD
+  sys_sem_free(API_EXPR_REF(API_VAR_REF(msg).sem));
+#endif /* !LWIP_NETCONN_SEM_PER_THREAD */
+  if (cberr != ERR_OK) {
+    API_VAR_FREE(MEMP_DNS_API_MSG, msg);
+    return cberr;
+  }
+
+#if LWIP_MPU_COMPATIBLE
+  *addr = msg->addr;
+  err = msg->err;
+#endif /* LWIP_MPU_COMPATIBLE */
+
+  API_VAR_FREE(MEMP_DNS_API_MSG, msg);
+  return err;
+}
+#endif /* LWIP_DNS*/
+
+#if LWIP_NETCONN_SEM_PER_THREAD
+void
+netconn_thread_init(void)
+{
+  sys_sem_t *sem = LWIP_NETCONN_THREAD_SEM_GET();
+  if ((sem == NULL) || !sys_sem_valid(sem)) {
+    /* call alloc only once */
+    LWIP_NETCONN_THREAD_SEM_ALLOC();
+    LWIP_ASSERT("LWIP_NETCONN_THREAD_SEM_ALLOC() failed", sys_sem_valid(LWIP_NETCONN_THREAD_SEM_GET()));
+  }
+}
+
+void
+netconn_thread_cleanup(void)
+{
+  sys_sem_t *sem = LWIP_NETCONN_THREAD_SEM_GET();
+  if ((sem != NULL) && sys_sem_valid(sem)) {
+    /* call free only once */
+    LWIP_NETCONN_THREAD_SEM_FREE();
+  }
+}
+#endif /* LWIP_NETCONN_SEM_PER_THREAD */
+
+#endif /* LWIP_NETCONN */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/api/api_msg.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/api/api_msg.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/api/api_msg.c	(revision 457)
@@ -0,0 +1,2173 @@
+/**
+ * @file
+ * Sequential API Internal module
+ *
+ */
+
+/*
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Adam Dunkels <adam@sics.se>
+ *
+ */
+
+#include "lwip/opt.h"
+
+#if LWIP_NETCONN /* don't build if not configured for use in lwipopts.h */
+
+#include "lwip/priv/api_msg.h"
+
+#include "lwip/ip.h"
+#include "lwip/ip_addr.h"
+#include "lwip/udp.h"
+#include "lwip/tcp.h"
+#include "lwip/raw.h"
+
+#include "lwip/memp.h"
+#include "lwip/igmp.h"
+#include "lwip/dns.h"
+#include "lwip/mld6.h"
+#include "lwip/priv/tcpip_priv.h"
+
+#include <string.h>
+
+/* netconns are polled once per second (e.g. continue write on memory error) */
+#define NETCONN_TCP_POLL_INTERVAL 2
+
+#define SET_NONBLOCKING_CONNECT(conn, val)  do { if (val) { \
+  netconn_set_flags(conn, NETCONN_FLAG_IN_NONBLOCKING_CONNECT); \
+} else { \
+  netconn_clear_flags(conn, NETCONN_FLAG_IN_NONBLOCKING_CONNECT); }} while(0)
+#define IN_NONBLOCKING_CONNECT(conn) netconn_is_flag_set(conn, NETCONN_FLAG_IN_NONBLOCKING_CONNECT)
+
+#if LWIP_NETCONN_FULLDUPLEX
+#define NETCONN_MBOX_VALID(conn, mbox) (sys_mbox_valid(mbox) && ((conn->flags & NETCONN_FLAG_MBOXINVALID) == 0))
+#else
+#define NETCONN_MBOX_VALID(conn, mbox) sys_mbox_valid(mbox)
+#endif
+
+/* forward declarations */
+#if LWIP_TCP
+#if LWIP_TCPIP_CORE_LOCKING
+#define WRITE_DELAYED         , 1
+#define WRITE_DELAYED_PARAM   , u8_t delayed
+#else /* LWIP_TCPIP_CORE_LOCKING */
+#define WRITE_DELAYED
+#define WRITE_DELAYED_PARAM
+#endif /* LWIP_TCPIP_CORE_LOCKING */
+static err_t lwip_netconn_do_writemore(struct netconn *conn  WRITE_DELAYED_PARAM);
+static err_t lwip_netconn_do_close_internal(struct netconn *conn  WRITE_DELAYED_PARAM);
+#endif
+
+static void netconn_drain(struct netconn *conn);
+
+#if LWIP_TCPIP_CORE_LOCKING
+#define TCPIP_APIMSG_ACK(m)
+#else /* LWIP_TCPIP_CORE_LOCKING */
+#define TCPIP_APIMSG_ACK(m)   do { sys_sem_signal(LWIP_API_MSG_SEM(m)); } while(0)
+#endif /* LWIP_TCPIP_CORE_LOCKING */
+
+#if LWIP_NETCONN_FULLDUPLEX
+const u8_t netconn_deleted = 0;
+
+int
+lwip_netconn_is_deallocated_msg(void *msg)
+{
+  if (msg == &netconn_deleted) {
+    return 1;
+  }
+  return 0;
+}
+#endif /* LWIP_NETCONN_FULLDUPLEX */
+
+#if LWIP_TCP
+const u8_t netconn_aborted = 0;
+const u8_t netconn_reset = 0;
+const u8_t netconn_closed = 0;
+
+/** Translate an error to a unique void* passed via an mbox */
+static void *
+lwip_netconn_err_to_msg(err_t err)
+{
+  switch (err) {
+    case ERR_ABRT:
+      return LWIP_CONST_CAST(void *, &netconn_aborted);
+    case ERR_RST:
+      return LWIP_CONST_CAST(void *, &netconn_reset);
+    case ERR_CLSD:
+      return LWIP_CONST_CAST(void *, &netconn_closed);
+    default:
+      LWIP_ASSERT("unhandled error", err == ERR_OK);
+      return NULL;
+  }
+}
+
+int
+lwip_netconn_is_err_msg(void *msg, err_t *err)
+{
+  LWIP_ASSERT("err != NULL", err != NULL);
+
+  if (msg == &netconn_aborted) {
+    *err = ERR_ABRT;
+    return 1;
+  } else if (msg == &netconn_reset) {
+    *err = ERR_RST;
+    return 1;
+  } else if (msg == &netconn_closed) {
+    *err = ERR_CLSD;
+    return 1;
+  }
+  return 0;
+}
+#endif /* LWIP_TCP */
+
+
+#if LWIP_RAW
+/**
+ * Receive callback function for RAW netconns.
+ * Doesn't 'eat' the packet, only copies it and sends it to
+ * conn->recvmbox
+ *
+ * @see raw.h (struct raw_pcb.recv) for parameters and return value
+ */
+static u8_t
+recv_raw(void *arg, struct raw_pcb *pcb, struct pbuf *p,
+         const ip_addr_t *addr)
+{
+  struct pbuf *q;
+  struct netbuf *buf;
+  struct netconn *conn;
+
+  LWIP_UNUSED_ARG(addr);
+  conn = (struct netconn *)arg;
+
+  if ((conn != NULL) && NETCONN_MBOX_VALID(conn, &conn->recvmbox)) {
+#if LWIP_SO_RCVBUF
+    int recv_avail;
+    SYS_ARCH_GET(conn->recv_avail, recv_avail);
+    if ((recv_avail + (int)(p->tot_len)) > conn->recv_bufsize) {
+      return 0;
+    }
+#endif /* LWIP_SO_RCVBUF */
+    /* copy the whole packet into new pbufs */
+    q = pbuf_clone(PBUF_RAW, PBUF_RAM, p);
+    if (q != NULL) {
+      u16_t len;
+      buf = (struct netbuf *)memp_malloc(MEMP_NETBUF);
+      if (buf == NULL) {
+        pbuf_free(q);
+        return 0;
+      }
+
+      buf->p = q;
+      buf->ptr = q;
+      ip_addr_copy(buf->addr, *ip_current_src_addr());
+      buf->port = pcb->protocol;
+
+      len = q->tot_len;
+      if (sys_mbox_trypost(&conn->recvmbox, buf) != ERR_OK) {
+        netbuf_delete(buf);
+        return 0;
+      } else {
+#if LWIP_SO_RCVBUF
+        SYS_ARCH_INC(conn->recv_avail, len);
+#endif /* LWIP_SO_RCVBUF */
+        /* Register event with callback */
+        API_EVENT(conn, NETCONN_EVT_RCVPLUS, len);
+      }
+    }
+  }
+
+  return 0; /* do not eat the packet */
+}
+#endif /* LWIP_RAW*/
+
+#if LWIP_UDP
+/**
+ * Receive callback function for UDP netconns.
+ * Posts the packet to conn->recvmbox or deletes it on memory error.
+ *
+ * @see udp.h (struct udp_pcb.recv) for parameters
+ */
+static void
+recv_udp(void *arg, struct udp_pcb *pcb, struct pbuf *p,
+         const ip_addr_t *addr, u16_t port)
+{
+  struct netbuf *buf;
+  struct netconn *conn;
+  u16_t len;
+#if LWIP_SO_RCVBUF
+  int recv_avail;
+#endif /* LWIP_SO_RCVBUF */
+
+  LWIP_UNUSED_ARG(pcb); /* only used for asserts... */
+  LWIP_ASSERT("recv_udp must have a pcb argument", pcb != NULL);
+  LWIP_ASSERT("recv_udp must have an argument", arg != NULL);
+  conn = (struct netconn *)arg;
+
+  if (conn == NULL) {
+    pbuf_free(p);
+    return;
+  }
+
+  LWIP_ASSERT("recv_udp: recv for wrong pcb!", conn->pcb.udp == pcb);
+
+#if LWIP_SO_RCVBUF
+  SYS_ARCH_GET(conn->recv_avail, recv_avail);
+  if (!NETCONN_MBOX_VALID(conn, &conn->recvmbox) ||
+      ((recv_avail + (int)(p->tot_len)) > conn->recv_bufsize)) {
+#else  /* LWIP_SO_RCVBUF */
+  if (!NETCONN_MBOX_VALID(conn, &conn->recvmbox)) {
+#endif /* LWIP_SO_RCVBUF */
+    pbuf_free(p);
+    return;
+  }
+
+  buf = (struct netbuf *)memp_malloc(MEMP_NETBUF);
+  if (buf == NULL) {
+    pbuf_free(p);
+    return;
+  } else {
+    buf->p = p;
+    buf->ptr = p;
+    ip_addr_set(&buf->addr, addr);
+    buf->port = port;
+#if LWIP_NETBUF_RECVINFO
+    if (conn->flags & NETCONN_FLAG_PKTINFO) {
+      /* get the UDP header - always in the first pbuf, ensured by udp_input */
+      const struct udp_hdr *udphdr = (const struct udp_hdr *)ip_next_header_ptr();
+      buf->flags = NETBUF_FLAG_DESTADDR;
+      ip_addr_set(&buf->toaddr, ip_current_dest_addr());
+      buf->toport_chksum = udphdr->dest;
+    }
+#endif /* LWIP_NETBUF_RECVINFO */
+  }
+
+  len = p->tot_len;
+  if (sys_mbox_trypost(&conn->recvmbox, buf) != ERR_OK) {
+    netbuf_delete(buf);
+    return;
+  } else {
+#if LWIP_SO_RCVBUF
+    SYS_ARCH_INC(conn->recv_avail, len);
+#endif /* LWIP_SO_RCVBUF */
+    /* Register event with callback */
+    API_EVENT(conn, NETCONN_EVT_RCVPLUS, len);
+  }
+}
+#endif /* LWIP_UDP */
+
+#if LWIP_TCP
+/**
+ * Receive callback function for TCP netconns.
+ * Posts the packet to conn->recvmbox, but doesn't delete it on errors.
+ *
+ * @see tcp.h (struct tcp_pcb.recv) for parameters and return value
+ */
+static err_t
+recv_tcp(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err)
+{
+  struct netconn *conn;
+  u16_t len;
+  void *msg;
+
+  LWIP_UNUSED_ARG(pcb);
+  LWIP_ASSERT("recv_tcp must have a pcb argument", pcb != NULL);
+  LWIP_ASSERT("recv_tcp must have an argument", arg != NULL);
+  LWIP_ASSERT("err != ERR_OK unhandled", err == ERR_OK);
+  LWIP_UNUSED_ARG(err); /* for LWIP_NOASSERT */
+  conn = (struct netconn *)arg;
+
+  if (conn == NULL) {
+    return ERR_VAL;
+  }
+  LWIP_ASSERT("recv_tcp: recv for wrong pcb!", conn->pcb.tcp == pcb);
+
+  if (!NETCONN_MBOX_VALID(conn, &conn->recvmbox)) {
+    /* recvmbox already deleted */
+    if (p != NULL) {
+      tcp_recved(pcb, p->tot_len);
+      pbuf_free(p);
+    }
+    return ERR_OK;
+  }
+  /* Unlike for UDP or RAW pcbs, don't check for available space
+     using recv_avail since that could break the connection
+     (data is already ACKed) */
+
+  if (p != NULL) {
+    msg = p;
+    len = p->tot_len;
+  } else {
+    msg = LWIP_CONST_CAST(void *, &netconn_closed);
+    len = 0;
+  }
+
+  if (sys_mbox_trypost(&conn->recvmbox, msg) != ERR_OK) {
+    /* don't deallocate p: it is presented to us later again from tcp_fasttmr! */
+    return ERR_MEM;
+  } else {
+#if LWIP_SO_RCVBUF
+    SYS_ARCH_INC(conn->recv_avail, len);
+#endif /* LWIP_SO_RCVBUF */
+    /* Register event with callback */
+    API_EVENT(conn, NETCONN_EVT_RCVPLUS, len);
+  }
+
+  return ERR_OK;
+}
+
+/**
+ * Poll callback function for TCP netconns.
+ * Wakes up an application thread that waits for a connection to close
+ * or data to be sent. The application thread then takes the
+ * appropriate action to go on.
+ *
+ * Signals the conn->sem.
+ * netconn_close waits for conn->sem if closing failed.
+ *
+ * @see tcp.h (struct tcp_pcb.poll) for parameters and return value
+ */
+static err_t
+poll_tcp(void *arg, struct tcp_pcb *pcb)
+{
+  struct netconn *conn = (struct netconn *)arg;
+
+  LWIP_UNUSED_ARG(pcb);
+  LWIP_ASSERT("conn != NULL", (conn != NULL));
+
+  if (conn->state == NETCONN_WRITE) {
+    lwip_netconn_do_writemore(conn  WRITE_DELAYED);
+  } else if (conn->state == NETCONN_CLOSE) {
+#if !LWIP_SO_SNDTIMEO && !LWIP_SO_LINGER
+    if (conn->current_msg && conn->current_msg->msg.sd.polls_left) {
+      conn->current_msg->msg.sd.polls_left--;
+    }
+#endif /* !LWIP_SO_SNDTIMEO && !LWIP_SO_LINGER */
+    lwip_netconn_do_close_internal(conn  WRITE_DELAYED);
+  }
+  /* @todo: implement connect timeout here? */
+
+  /* Did a nonblocking write fail before? Then check available write-space. */
+  if (conn->flags & NETCONN_FLAG_CHECK_WRITESPACE) {
+    /* If the queued byte- or pbuf-count drops below the configured low-water limit,
+       let select mark this pcb as writable again. */
+    if ((conn->pcb.tcp != NULL) && (tcp_sndbuf(conn->pcb.tcp) > TCP_SNDLOWAT) &&
+        (tcp_sndqueuelen(conn->pcb.tcp) < TCP_SNDQUEUELOWAT)) {
+      netconn_clear_flags(conn, NETCONN_FLAG_CHECK_WRITESPACE);
+      API_EVENT(conn, NETCONN_EVT_SENDPLUS, 0);
+    }
+  }
+
+  return ERR_OK;
+}
+
+/**
+ * Sent callback function for TCP netconns.
+ * Signals the conn->sem and calls API_EVENT.
+ * netconn_write waits for conn->sem if send buffer is low.
+ *
+ * @see tcp.h (struct tcp_pcb.sent) for parameters and return value
+ */
+static err_t
+sent_tcp(void *arg, struct tcp_pcb *pcb, u16_t len)
+{
+  struct netconn *conn = (struct netconn *)arg;
+
+  LWIP_UNUSED_ARG(pcb);
+  LWIP_ASSERT("conn != NULL", (conn != NULL));
+
+  if (conn) {
+    if (conn->state == NETCONN_WRITE) {
+      lwip_netconn_do_writemore(conn  WRITE_DELAYED);
+    } else if (conn->state == NETCONN_CLOSE) {
+      lwip_netconn_do_close_internal(conn  WRITE_DELAYED);
+    }
+
+    /* If the queued byte- or pbuf-count drops below the configured low-water limit,
+       let select mark this pcb as writable again. */
+    if ((conn->pcb.tcp != NULL) && (tcp_sndbuf(conn->pcb.tcp) > TCP_SNDLOWAT) &&
+        (tcp_sndqueuelen(conn->pcb.tcp) < TCP_SNDQUEUELOWAT)) {
+      netconn_clear_flags(conn, NETCONN_FLAG_CHECK_WRITESPACE);
+      API_EVENT(conn, NETCONN_EVT_SENDPLUS, len);
+    }
+  }
+
+  return ERR_OK;
+}
+
+/**
+ * Error callback function for TCP netconns.
+ * Signals conn->sem, posts to all conn mboxes and calls API_EVENT.
+ * The application thread has then to decide what to do.
+ *
+ * @see tcp.h (struct tcp_pcb.err) for parameters
+ */
+static void
+err_tcp(void *arg, err_t err)
+{
+  struct netconn *conn;
+  enum netconn_state old_state;
+  void *mbox_msg;
+  SYS_ARCH_DECL_PROTECT(lev);
+
+  conn = (struct netconn *)arg;
+  LWIP_ASSERT("conn != NULL", (conn != NULL));
+
+  SYS_ARCH_PROTECT(lev);
+
+  /* when err is called, the pcb is deallocated, so delete the reference */
+  conn->pcb.tcp = NULL;
+  /* store pending error */
+  conn->pending_err = err;
+  /* prevent application threads from blocking on 'recvmbox'/'acceptmbox' */
+  conn->flags |= NETCONN_FLAG_MBOXCLOSED;
+
+  /* reset conn->state now before waking up other threads */
+  old_state = conn->state;
+  conn->state = NETCONN_NONE;
+
+  SYS_ARCH_UNPROTECT(lev);
+
+  /* Notify the user layer about a connection error. Used to signal select. */
+  API_EVENT(conn, NETCONN_EVT_ERROR, 0);
+  /* Try to release selects pending on 'read' or 'write', too.
+     They will get an error if they actually try to read or write. */
+  API_EVENT(conn, NETCONN_EVT_RCVPLUS, 0);
+  API_EVENT(conn, NETCONN_EVT_SENDPLUS, 0);
+
+  mbox_msg = lwip_netconn_err_to_msg(err);
+  /* pass error message to recvmbox to wake up pending recv */
+  if (NETCONN_MBOX_VALID(conn, &conn->recvmbox)) {
+    /* use trypost to prevent deadlock */
+    sys_mbox_trypost(&conn->recvmbox, mbox_msg);
+  }
+  /* pass error message to acceptmbox to wake up pending accept */
+  if (NETCONN_MBOX_VALID(conn, &conn->acceptmbox)) {
+    /* use trypost to preven deadlock */
+    sys_mbox_trypost(&conn->acceptmbox, mbox_msg);
+  }
+
+  if ((old_state == NETCONN_WRITE) || (old_state == NETCONN_CLOSE) ||
+      (old_state == NETCONN_CONNECT)) {
+    /* calling lwip_netconn_do_writemore/lwip_netconn_do_close_internal is not necessary
+       since the pcb has already been deleted! */
+    int was_nonblocking_connect = IN_NONBLOCKING_CONNECT(conn);
+    SET_NONBLOCKING_CONNECT(conn, 0);
+
+    if (!was_nonblocking_connect) {
+      sys_sem_t *op_completed_sem;
+      /* set error return code */
+      LWIP_ASSERT("conn->current_msg != NULL", conn->current_msg != NULL);
+      if (old_state == NETCONN_CLOSE) {
+        /* let close succeed: the connection is closed after all... */
+        conn->current_msg->err = ERR_OK;
+      } else {
+        /* Write and connect fail */
+        conn->current_msg->err = err;
+      }
+      op_completed_sem = LWIP_API_MSG_SEM(conn->current_msg);
+      LWIP_ASSERT("inavlid op_completed_sem", sys_sem_valid(op_completed_sem));
+      conn->current_msg = NULL;
+      /* wake up the waiting task */
+      sys_sem_signal(op_completed_sem);
+    } else {
+      /* @todo: test what happens for error on nonblocking connect */
+    }
+  } else {
+    LWIP_ASSERT("conn->current_msg == NULL", conn->current_msg == NULL);
+  }
+}
+
+/**
+ * Setup a tcp_pcb with the correct callback function pointers
+ * and their arguments.
+ *
+ * @param conn the TCP netconn to setup
+ */
+static void
+setup_tcp(struct netconn *conn)
+{
+  struct tcp_pcb *pcb;
+
+  pcb = conn->pcb.tcp;
+  tcp_arg(pcb, conn);
+  tcp_recv(pcb, recv_tcp);
+  tcp_sent(pcb, sent_tcp);
+  tcp_poll(pcb, poll_tcp, NETCONN_TCP_POLL_INTERVAL);
+  tcp_err(pcb, err_tcp);
+}
+
+/**
+ * Accept callback function for TCP netconns.
+ * Allocates a new netconn and posts that to conn->acceptmbox.
+ *
+ * @see tcp.h (struct tcp_pcb_listen.accept) for parameters and return value
+ */
+static err_t
+accept_function(void *arg, struct tcp_pcb *newpcb, err_t err)
+{
+  struct netconn *newconn;
+  struct netconn *conn = (struct netconn *)arg;
+
+  if (conn == NULL) {
+    return ERR_VAL;
+  }
+  if (!NETCONN_MBOX_VALID(conn, &conn->acceptmbox)) {
+    LWIP_DEBUGF(API_MSG_DEBUG, ("accept_function: acceptmbox already deleted\n"));
+    return ERR_VAL;
+  }
+
+  if (newpcb == NULL) {
+    /* out-of-pcbs during connect: pass on this error to the application */
+    if (sys_mbox_trypost(&conn->acceptmbox, lwip_netconn_err_to_msg(ERR_ABRT)) == ERR_OK) {
+      /* Register event with callback */
+      API_EVENT(conn, NETCONN_EVT_RCVPLUS, 0);
+    }
+    return ERR_VAL;
+  }
+  LWIP_ASSERT("expect newpcb == NULL or err == ERR_OK", err == ERR_OK);
+  LWIP_UNUSED_ARG(err); /* for LWIP_NOASSERT */
+
+  LWIP_DEBUGF(API_MSG_DEBUG, ("accept_function: newpcb->state: %s\n", tcp_debug_state_str(newpcb->state)));
+
+  /* We have to set the callback here even though
+   * the new socket is unknown. newconn->socket is marked as -1. */
+  newconn = netconn_alloc(conn->type, conn->callback);
+  if (newconn == NULL) {
+    /* outof netconns: pass on this error to the application */
+    if (sys_mbox_trypost(&conn->acceptmbox, lwip_netconn_err_to_msg(ERR_ABRT)) == ERR_OK) {
+      /* Register event with callback */
+      API_EVENT(conn, NETCONN_EVT_RCVPLUS, 0);
+    }
+    return ERR_MEM;
+  }
+  newconn->pcb.tcp = newpcb;
+  setup_tcp(newconn);
+
+  /* handle backlog counter */
+  tcp_backlog_delayed(newpcb);
+
+  if (sys_mbox_trypost(&conn->acceptmbox, newconn) != ERR_OK) {
+    /* When returning != ERR_OK, the pcb is aborted in tcp_process(),
+       so do nothing here! */
+    /* remove all references to this netconn from the pcb */
+    struct tcp_pcb *pcb = newconn->pcb.tcp;
+    tcp_arg(pcb, NULL);
+    tcp_recv(pcb, NULL);
+    tcp_sent(pcb, NULL);
+    tcp_poll(pcb, NULL, 0);
+    tcp_err(pcb, NULL);
+    /* remove reference from to the pcb from this netconn */
+    newconn->pcb.tcp = NULL;
+    /* no need to drain since we know the recvmbox is empty. */
+    sys_mbox_free(&newconn->recvmbox);
+    sys_mbox_set_invalid(&newconn->recvmbox);
+    netconn_free(newconn);
+    return ERR_MEM;
+  } else {
+    /* Register event with callback */
+    API_EVENT(conn, NETCONN_EVT_RCVPLUS, 0);
+  }
+
+  return ERR_OK;
+}
+#endif /* LWIP_TCP */
+
+/**
+ * Create a new pcb of a specific type.
+ * Called from lwip_netconn_do_newconn().
+ *
+ * @param msg the api_msg describing the connection type
+ */
+static void
+pcb_new(struct api_msg *msg)
+{
+  enum lwip_ip_addr_type iptype = IPADDR_TYPE_V4;
+
+  LWIP_ASSERT("pcb_new: pcb already allocated", msg->conn->pcb.tcp == NULL);
+
+#if LWIP_IPV6 && LWIP_IPV4
+  /* IPv6: Dual-stack by default, unless netconn_set_ipv6only() is called */
+  if (NETCONNTYPE_ISIPV6(netconn_type(msg->conn))) {
+    iptype = IPADDR_TYPE_ANY;
+  }
+#endif
+
+  /* Allocate a PCB for this connection */
+  switch (NETCONNTYPE_GROUP(msg->conn->type)) {
+#if LWIP_RAW
+    case NETCONN_RAW:
+      msg->conn->pcb.raw = raw_new_ip_type(iptype, msg->msg.n.proto);
+      if (msg->conn->pcb.raw != NULL) {
+#if LWIP_IPV6
+        /* ICMPv6 packets should always have checksum calculated by the stack as per RFC 3542 chapter 3.1 */
+        if (NETCONNTYPE_ISIPV6(msg->conn->type) && msg->conn->pcb.raw->protocol == IP6_NEXTH_ICMP6) {
+          msg->conn->pcb.raw->chksum_reqd = 1;
+          msg->conn->pcb.raw->chksum_offset = 2;
+        }
+#endif /* LWIP_IPV6 */
+        raw_recv(msg->conn->pcb.raw, recv_raw, msg->conn);
+      }
+      break;
+#endif /* LWIP_RAW */
+#if LWIP_UDP
+    case NETCONN_UDP:
+      msg->conn->pcb.udp = udp_new_ip_type(iptype);
+      if (msg->conn->pcb.udp != NULL) {
+#if LWIP_UDPLITE
+        if (NETCONNTYPE_ISUDPLITE(msg->conn->type)) {
+          udp_setflags(msg->conn->pcb.udp, UDP_FLAGS_UDPLITE);
+        }
+#endif /* LWIP_UDPLITE */
+        if (NETCONNTYPE_ISUDPNOCHKSUM(msg->conn->type)) {
+          udp_setflags(msg->conn->pcb.udp, UDP_FLAGS_NOCHKSUM);
+        }
+        udp_recv(msg->conn->pcb.udp, recv_udp, msg->conn);
+      }
+      break;
+#endif /* LWIP_UDP */
+#if LWIP_TCP
+    case NETCONN_TCP:
+      msg->conn->pcb.tcp = tcp_new_ip_type(iptype);
+      if (msg->conn->pcb.tcp != NULL) {
+        setup_tcp(msg->conn);
+      }
+      break;
+#endif /* LWIP_TCP */
+    default:
+      /* Unsupported netconn type, e.g. protocol disabled */
+      msg->err = ERR_VAL;
+      return;
+  }
+  if (msg->conn->pcb.ip == NULL) {
+    msg->err = ERR_MEM;
+  }
+}
+
+/**
+ * Create a new pcb of a specific type inside a netconn.
+ * Called from netconn_new_with_proto_and_callback.
+ *
+ * @param m the api_msg describing the connection type
+ */
+void
+lwip_netconn_do_newconn(void *m)
+{
+  struct api_msg *msg = (struct api_msg *)m;
+
+  msg->err = ERR_OK;
+  if (msg->conn->pcb.tcp == NULL) {
+    pcb_new(msg);
+  }
+  /* Else? This "new" connection already has a PCB allocated. */
+  /* Is this an error condition? Should it be deleted? */
+  /* We currently just are happy and return. */
+
+  TCPIP_APIMSG_ACK(msg);
+}
+
+/**
+ * Create a new netconn (of a specific type) that has a callback function.
+ * The corresponding pcb is NOT created!
+ *
+ * @param t the type of 'connection' to create (@see enum netconn_type)
+ * @param callback a function to call on status changes (RX available, TX'ed)
+ * @return a newly allocated struct netconn or
+ *         NULL on memory error
+ */
+struct netconn *
+netconn_alloc(enum netconn_type t, netconn_callback callback)
+{
+  struct netconn *conn;
+  int size;
+  u8_t init_flags = 0;
+
+  conn = (struct netconn *)memp_malloc(MEMP_NETCONN);
+  if (conn == NULL) {
+    return NULL;
+  }
+
+  conn->pending_err = ERR_OK;
+  conn->type = t;
+  conn->pcb.tcp = NULL;
+
+  /* If all sizes are the same, every compiler should optimize this switch to nothing */
+  switch (NETCONNTYPE_GROUP(t)) {
+#if LWIP_RAW
+    case NETCONN_RAW:
+      size = DEFAULT_RAW_RECVMBOX_SIZE;
+      break;
+#endif /* LWIP_RAW */
+#if LWIP_UDP
+    case NETCONN_UDP:
+      size = DEFAULT_UDP_RECVMBOX_SIZE;
+#if LWIP_NETBUF_RECVINFO
+      init_flags |= NETCONN_FLAG_PKTINFO;
+#endif /* LWIP_NETBUF_RECVINFO */
+      break;
+#endif /* LWIP_UDP */
+#if LWIP_TCP
+    case NETCONN_TCP:
+      size = DEFAULT_TCP_RECVMBOX_SIZE;
+      break;
+#endif /* LWIP_TCP */
+    default:
+      LWIP_ASSERT("netconn_alloc: undefined netconn_type", 0);
+      goto free_and_return;
+  }
+
+  if (sys_mbox_new(&conn->recvmbox, size) != ERR_OK) {
+    goto free_and_return;
+  }
+#if !LWIP_NETCONN_SEM_PER_THREAD
+  if (sys_sem_new(&conn->op_completed, 0) != ERR_OK) {
+    sys_mbox_free(&conn->recvmbox);
+    goto free_and_return;
+  }
+#endif
+
+#if LWIP_TCP
+  sys_mbox_set_invalid(&conn->acceptmbox);
+#endif
+  conn->state        = NETCONN_NONE;
+#if LWIP_SOCKET
+  /* initialize socket to -1 since 0 is a valid socket */
+  conn->socket       = -1;
+#endif /* LWIP_SOCKET */
+  conn->callback     = callback;
+#if LWIP_TCP
+  conn->current_msg  = NULL;
+#endif /* LWIP_TCP */
+#if LWIP_SO_SNDTIMEO
+  conn->send_timeout = 0;
+#endif /* LWIP_SO_SNDTIMEO */
+#if LWIP_SO_RCVTIMEO
+  conn->recv_timeout = 0;
+#endif /* LWIP_SO_RCVTIMEO */
+#if LWIP_SO_RCVBUF
+  conn->recv_bufsize = RECV_BUFSIZE_DEFAULT;
+  conn->recv_avail   = 0;
+#endif /* LWIP_SO_RCVBUF */
+#if LWIP_SO_LINGER
+  conn->linger = -1;
+#endif /* LWIP_SO_LINGER */
+  conn->flags = init_flags;
+  return conn;
+free_and_return:
+  memp_free(MEMP_NETCONN, conn);
+  return NULL;
+}
+
+/**
+ * Delete a netconn and all its resources.
+ * The pcb is NOT freed (since we might not be in the right thread context do this).
+ *
+ * @param conn the netconn to free
+ */
+void
+netconn_free(struct netconn *conn)
+{
+  LWIP_ASSERT("PCB must be deallocated outside this function", conn->pcb.tcp == NULL);
+
+#if LWIP_NETCONN_FULLDUPLEX
+  /* in fullduplex, netconn is drained here */
+  netconn_drain(conn);
+#endif /* LWIP_NETCONN_FULLDUPLEX */
+
+  LWIP_ASSERT("recvmbox must be deallocated before calling this function",
+              !sys_mbox_valid(&conn->recvmbox));
+#if LWIP_TCP
+  LWIP_ASSERT("acceptmbox must be deallocated before calling this function",
+              !sys_mbox_valid(&conn->acceptmbox));
+#endif /* LWIP_TCP */
+
+#if !LWIP_NETCONN_SEM_PER_THREAD
+  sys_sem_free(&conn->op_completed);
+  sys_sem_set_invalid(&conn->op_completed);
+#endif
+
+  memp_free(MEMP_NETCONN, conn);
+}
+
+/**
+ * Delete rcvmbox and acceptmbox of a netconn and free the left-over data in
+ * these mboxes
+ *
+ * @param conn the netconn to free
+ * @bytes_drained bytes drained from recvmbox
+ * @accepts_drained pending connections drained from acceptmbox
+ */
+static void
+netconn_drain(struct netconn *conn)
+{
+  void *mem;
+
+  /* This runs when mbox and netconn are marked as closed,
+     so we don't need to lock against rx packets */
+#if LWIP_NETCONN_FULLDUPLEX
+  LWIP_ASSERT("netconn marked closed", conn->flags & NETCONN_FLAG_MBOXINVALID);
+#endif /* LWIP_NETCONN_FULLDUPLEX */
+
+  /* Delete and drain the recvmbox. */
+  if (sys_mbox_valid(&conn->recvmbox)) {
+    while (sys_mbox_tryfetch(&conn->recvmbox, &mem) != SYS_MBOX_EMPTY) {
+#if LWIP_NETCONN_FULLDUPLEX
+      if (!lwip_netconn_is_deallocated_msg(mem))
+#endif /* LWIP_NETCONN_FULLDUPLEX */
+      {
+#if LWIP_TCP
+        if (NETCONNTYPE_GROUP(conn->type) == NETCONN_TCP) {
+          err_t err;
+          if (!lwip_netconn_is_err_msg(mem, &err)) {
+            pbuf_free((struct pbuf *)mem);
+          }
+        } else
+#endif /* LWIP_TCP */
+        {
+          netbuf_delete((struct netbuf *)mem);
+        }
+      }
+    }
+    sys_mbox_free(&conn->recvmbox);
+    sys_mbox_set_invalid(&conn->recvmbox);
+  }
+
+  /* Delete and drain the acceptmbox. */
+#if LWIP_TCP
+  if (sys_mbox_valid(&conn->acceptmbox)) {
+    while (sys_mbox_tryfetch(&conn->acceptmbox, &mem) != SYS_MBOX_EMPTY) {
+#if LWIP_NETCONN_FULLDUPLEX
+      if (!lwip_netconn_is_deallocated_msg(mem))
+#endif /* LWIP_NETCONN_FULLDUPLEX */
+      {
+        err_t err;
+        if (!lwip_netconn_is_err_msg(mem, &err)) {
+          struct netconn *newconn = (struct netconn *)mem;
+          /* Only tcp pcbs have an acceptmbox, so no need to check conn->type */
+          /* pcb might be set to NULL already by err_tcp() */
+          /* drain recvmbox */
+          netconn_drain(newconn);
+          if (newconn->pcb.tcp != NULL) {
+            tcp_abort(newconn->pcb.tcp);
+            newconn->pcb.tcp = NULL;
+          }
+          netconn_free(newconn);
+        }
+      }
+    }
+    sys_mbox_free(&conn->acceptmbox);
+    sys_mbox_set_invalid(&conn->acceptmbox);
+  }
+#endif /* LWIP_TCP */
+}
+
+#if LWIP_NETCONN_FULLDUPLEX
+static void
+netconn_mark_mbox_invalid(struct netconn *conn)
+{
+  int i, num_waiting;
+  void *msg = LWIP_CONST_CAST(void *, &netconn_deleted);
+
+  /* Prevent new calls/threads from reading from the mbox */
+  conn->flags |= NETCONN_FLAG_MBOXINVALID;
+
+  SYS_ARCH_LOCKED(num_waiting = conn->mbox_threads_waiting);
+  for (i = 0; i < num_waiting; i++) {
+    if (sys_mbox_valid_val(conn->recvmbox)) {
+      sys_mbox_trypost(&conn->recvmbox, msg);
+    } else {
+      sys_mbox_trypost(&conn->acceptmbox, msg);
+    }
+  }
+}
+#endif /* LWIP_NETCONN_FULLDUPLEX */
+
+#if LWIP_TCP
+/**
+ * Internal helper function to close a TCP netconn: since this sometimes
+ * doesn't work at the first attempt, this function is called from multiple
+ * places.
+ *
+ * @param conn the TCP netconn to close
+ */
+static err_t
+lwip_netconn_do_close_internal(struct netconn *conn  WRITE_DELAYED_PARAM)
+{
+  err_t err;
+  u8_t shut, shut_rx, shut_tx, shut_close;
+  u8_t close_finished = 0;
+  struct tcp_pcb *tpcb;
+#if LWIP_SO_LINGER
+  u8_t linger_wait_required = 0;
+#endif /* LWIP_SO_LINGER */
+
+  LWIP_ASSERT("invalid conn", (conn != NULL));
+  LWIP_ASSERT("this is for tcp netconns only", (NETCONNTYPE_GROUP(conn->type) == NETCONN_TCP));
+  LWIP_ASSERT("conn must be in state NETCONN_CLOSE", (conn->state == NETCONN_CLOSE));
+  LWIP_ASSERT("pcb already closed", (conn->pcb.tcp != NULL));
+  LWIP_ASSERT("conn->current_msg != NULL", conn->current_msg != NULL);
+
+  tpcb = conn->pcb.tcp;
+  shut = conn->current_msg->msg.sd.shut;
+  shut_rx = shut & NETCONN_SHUT_RD;
+  shut_tx = shut & NETCONN_SHUT_WR;
+  /* shutting down both ends is the same as closing
+     (also if RD or WR side was shut down before already) */
+  if (shut == NETCONN_SHUT_RDWR) {
+    shut_close = 1;
+  } else if (shut_rx &&
+             ((tpcb->state == FIN_WAIT_1) ||
+              (tpcb->state == FIN_WAIT_2) ||
+              (tpcb->state == CLOSING))) {
+    shut_close = 1;
+  } else if (shut_tx && ((tpcb->flags & TF_RXCLOSED) != 0)) {
+    shut_close = 1;
+  } else {
+    shut_close = 0;
+  }
+
+  /* Set back some callback pointers */
+  if (shut_close) {
+    tcp_arg(tpcb, NULL);
+  }
+  if (tpcb->state == LISTEN) {
+    tcp_accept(tpcb, NULL);
+  } else {
+    /* some callbacks have to be reset if tcp_close is not successful */
+    if (shut_rx) {
+      tcp_recv(tpcb, NULL);
+      tcp_accept(tpcb, NULL);
+    }
+    if (shut_tx) {
+      tcp_sent(tpcb, NULL);
+    }
+    if (shut_close) {
+      tcp_poll(tpcb, NULL, 0);
+      tcp_err(tpcb, NULL);
+    }
+  }
+  /* Try to close the connection */
+  if (shut_close) {
+#if LWIP_SO_LINGER
+    /* check linger possibilites before calling tcp_close */
+    err = ERR_OK;
+    /* linger enabled/required at all? (i.e. is there untransmitted data left?) */
+    if ((conn->linger >= 0) && (conn->pcb.tcp->unsent || conn->pcb.tcp->unacked)) {
+      if ((conn->linger == 0)) {
+        /* data left but linger prevents waiting */
+        tcp_abort(tpcb);
+        tpcb = NULL;
+      } else if (conn->linger > 0) {
+        /* data left and linger says we should wait */
+        if (netconn_is_nonblocking(conn)) {
+          /* data left on a nonblocking netconn -> cannot linger */
+          err = ERR_WOULDBLOCK;
+        } else if ((s32_t)(sys_now() - conn->current_msg->msg.sd.time_started) >=
+                   (conn->linger * 1000)) {
+          /* data left but linger timeout has expired (this happens on further
+             calls to this function through poll_tcp */
+          tcp_abort(tpcb);
+          tpcb = NULL;
+        } else {
+          /* data left -> need to wait for ACK after successful close */
+          linger_wait_required = 1;
+        }
+      }
+    }
+    if ((err == ERR_OK) && (tpcb != NULL))
+#endif /* LWIP_SO_LINGER */
+    {
+      err = tcp_close(tpcb);
+    }
+  } else {
+    err = tcp_shutdown(tpcb, shut_rx, shut_tx);
+  }
+  if (err == ERR_OK) {
+    close_finished = 1;
+#if LWIP_SO_LINGER
+    if (linger_wait_required) {
+      /* wait for ACK of all unsent/unacked data by just getting called again */
+      close_finished = 0;
+      err = ERR_INPROGRESS;
+    }
+#endif /* LWIP_SO_LINGER */
+  } else {
+    if (err == ERR_MEM) {
+      /* Closing failed because of memory shortage, try again later. Even for
+         nonblocking netconns, we have to wait since no standard socket application
+         is prepared for close failing because of resource shortage.
+         Check the timeout: this is kind of an lwip addition to the standard sockets:
+         we wait for some time when failing to allocate a segment for the FIN */
+#if LWIP_SO_SNDTIMEO || LWIP_SO_LINGER
+      s32_t close_timeout = LWIP_TCP_CLOSE_TIMEOUT_MS_DEFAULT;
+#if LWIP_SO_SNDTIMEO
+      if (conn->send_timeout > 0) {
+        close_timeout = conn->send_timeout;
+      }
+#endif /* LWIP_SO_SNDTIMEO */
+#if LWIP_SO_LINGER
+      if (conn->linger >= 0) {
+        /* use linger timeout (seconds) */
+        close_timeout = conn->linger * 1000U;
+      }
+#endif
+      if ((s32_t)(sys_now() - conn->current_msg->msg.sd.time_started) >= close_timeout) {
+#else /* LWIP_SO_SNDTIMEO || LWIP_SO_LINGER */
+      if (conn->current_msg->msg.sd.polls_left == 0) {
+#endif /* LWIP_SO_SNDTIMEO || LWIP_SO_LINGER */
+        close_finished = 1;
+        if (shut_close) {
+          /* in this case, we want to RST the connection */
+          tcp_abort(tpcb);
+          err = ERR_OK;
+        }
+      }
+    } else {
+      /* Closing failed for a non-memory error: give up */
+      close_finished = 1;
+    }
+  }
+  if (close_finished) {
+    /* Closing done (succeeded, non-memory error, nonblocking error or timeout) */
+    sys_sem_t *op_completed_sem = LWIP_API_MSG_SEM(conn->current_msg);
+    conn->current_msg->err = err;
+    conn->current_msg = NULL;
+    conn->state = NETCONN_NONE;
+    if (err == ERR_OK) {
+      if (shut_close) {
+        /* Set back some callback pointers as conn is going away */
+        conn->pcb.tcp = NULL;
+        /* Trigger select() in socket layer. Make sure everybody notices activity
+         on the connection, error first! */
+        API_EVENT(conn, NETCONN_EVT_ERROR, 0);
+      }
+      if (shut_rx) {
+        API_EVENT(conn, NETCONN_EVT_RCVPLUS, 0);
+      }
+      if (shut_tx) {
+        API_EVENT(conn, NETCONN_EVT_SENDPLUS, 0);
+      }
+    }
+#if LWIP_TCPIP_CORE_LOCKING
+    if (delayed)
+#endif
+    {
+      /* wake up the application task */
+      sys_sem_signal(op_completed_sem);
+    }
+    return ERR_OK;
+  }
+  if (!close_finished) {
+    /* Closing failed and we want to wait: restore some of the callbacks */
+    /* Closing of listen pcb will never fail! */
+    LWIP_ASSERT("Closing a listen pcb may not fail!", (tpcb->state != LISTEN));
+    if (shut_tx) {
+      tcp_sent(tpcb, sent_tcp);
+    }
+    /* when waiting for close, set up poll interval to 500ms */
+    tcp_poll(tpcb, poll_tcp, 1);
+    tcp_err(tpcb, err_tcp);
+    tcp_arg(tpcb, conn);
+    /* don't restore recv callback: we don't want to receive any more data */
+  }
+  /* If closing didn't succeed, we get called again either
+     from poll_tcp or from sent_tcp */
+  LWIP_ASSERT("err != ERR_OK", err != ERR_OK);
+  return err;
+}
+#endif /* LWIP_TCP */
+
+/**
+ * Delete the pcb inside a netconn.
+ * Called from netconn_delete.
+ *
+ * @param m the api_msg pointing to the connection
+ */
+void
+lwip_netconn_do_delconn(void *m)
+{
+  struct api_msg *msg = (struct api_msg *)m;
+
+  enum netconn_state state = msg->conn->state;
+  LWIP_ASSERT("netconn state error", /* this only happens for TCP netconns */
+              (state == NETCONN_NONE) || (NETCONNTYPE_GROUP(msg->conn->type) == NETCONN_TCP));
+#if LWIP_NETCONN_FULLDUPLEX
+  /* In full duplex mode, blocking write/connect is aborted with ERR_CLSD */
+  if (state != NETCONN_NONE) {
+    if ((state == NETCONN_WRITE) ||
+        ((state == NETCONN_CONNECT) && !IN_NONBLOCKING_CONNECT(msg->conn))) {
+      /* close requested, abort running write/connect */
+      sys_sem_t *op_completed_sem;
+      LWIP_ASSERT("msg->conn->current_msg != NULL", msg->conn->current_msg != NULL);
+      op_completed_sem = LWIP_API_MSG_SEM(msg->conn->current_msg);
+      msg->conn->current_msg->err = ERR_CLSD;
+      msg->conn->current_msg = NULL;
+      msg->conn->state = NETCONN_NONE;
+      sys_sem_signal(op_completed_sem);
+    }
+  }
+#else /* LWIP_NETCONN_FULLDUPLEX */
+  if (((state != NETCONN_NONE) &&
+       (state != NETCONN_LISTEN) &&
+       (state != NETCONN_CONNECT)) ||
+      ((state == NETCONN_CONNECT) && !IN_NONBLOCKING_CONNECT(msg->conn))) {
+    /* This means either a blocking write or blocking connect is running
+       (nonblocking write returns and sets state to NONE) */
+    msg->err = ERR_INPROGRESS;
+  } else
+#endif /* LWIP_NETCONN_FULLDUPLEX */
+  {
+    LWIP_ASSERT("blocking connect in progress",
+                (state != NETCONN_CONNECT) || IN_NONBLOCKING_CONNECT(msg->conn));
+    msg->err = ERR_OK;
+#if LWIP_NETCONN_FULLDUPLEX
+    /* Mark mboxes invalid */
+    netconn_mark_mbox_invalid(msg->conn);
+#else /* LWIP_NETCONN_FULLDUPLEX */
+    netconn_drain(msg->conn);
+#endif /* LWIP_NETCONN_FULLDUPLEX */
+
+    if (msg->conn->pcb.tcp != NULL) {
+
+      switch (NETCONNTYPE_GROUP(msg->conn->type)) {
+#if LWIP_RAW
+        case NETCONN_RAW:
+          raw_remove(msg->conn->pcb.raw);
+          break;
+#endif /* LWIP_RAW */
+#if LWIP_UDP
+        case NETCONN_UDP:
+          msg->conn->pcb.udp->recv_arg = NULL;
+          udp_remove(msg->conn->pcb.udp);
+          break;
+#endif /* LWIP_UDP */
+#if LWIP_TCP
+        case NETCONN_TCP:
+          LWIP_ASSERT("already writing or closing", msg->conn->current_msg == NULL);
+          msg->conn->state = NETCONN_CLOSE;
+          msg->msg.sd.shut = NETCONN_SHUT_RDWR;
+          msg->conn->current_msg = msg;
+#if LWIP_TCPIP_CORE_LOCKING
+          if (lwip_netconn_do_close_internal(msg->conn, 0) != ERR_OK) {
+            LWIP_ASSERT("state!", msg->conn->state == NETCONN_CLOSE);
+            UNLOCK_TCPIP_CORE();
+            sys_arch_sem_wait(LWIP_API_MSG_SEM(msg), 0);
+            LOCK_TCPIP_CORE();
+            LWIP_ASSERT("state!", msg->conn->state == NETCONN_NONE);
+          }
+#else /* LWIP_TCPIP_CORE_LOCKING */
+          lwip_netconn_do_close_internal(msg->conn);
+#endif /* LWIP_TCPIP_CORE_LOCKING */
+          /* API_EVENT is called inside lwip_netconn_do_close_internal, before releasing
+             the application thread, so we can return at this point! */
+          return;
+#endif /* LWIP_TCP */
+        default:
+          break;
+      }
+      msg->conn->pcb.tcp = NULL;
+    }
+    /* tcp netconns don't come here! */
+
+    /* @todo: this lets select make the socket readable and writable,
+       which is wrong! errfd instead? */
+    API_EVENT(msg->conn, NETCONN_EVT_RCVPLUS, 0);
+    API_EVENT(msg->conn, NETCONN_EVT_SENDPLUS, 0);
+  }
+  if (sys_sem_valid(LWIP_API_MSG_SEM(msg))) {
+    TCPIP_APIMSG_ACK(msg);
+  }
+}
+
+/**
+ * Bind a pcb contained in a netconn
+ * Called from netconn_bind.
+ *
+ * @param m the api_msg pointing to the connection and containing
+ *          the IP address and port to bind to
+ */
+void
+lwip_netconn_do_bind(void *m)
+{
+  struct api_msg *msg = (struct api_msg *)m;
+  err_t err;
+
+  if (msg->conn->pcb.tcp != NULL) {
+    switch (NETCONNTYPE_GROUP(msg->conn->type)) {
+#if LWIP_RAW
+      case NETCONN_RAW:
+        err = raw_bind(msg->conn->pcb.raw, API_EXPR_REF(msg->msg.bc.ipaddr));
+        break;
+#endif /* LWIP_RAW */
+#if LWIP_UDP
+      case NETCONN_UDP:
+        err = udp_bind(msg->conn->pcb.udp, API_EXPR_REF(msg->msg.bc.ipaddr), msg->msg.bc.port);
+        break;
+#endif /* LWIP_UDP */
+#if LWIP_TCP
+      case NETCONN_TCP:
+        err = tcp_bind(msg->conn->pcb.tcp, API_EXPR_REF(msg->msg.bc.ipaddr), msg->msg.bc.port);
+        break;
+#endif /* LWIP_TCP */
+      default:
+        err = ERR_VAL;
+        break;
+    }
+  } else {
+    err = ERR_VAL;
+  }
+  msg->err = err;
+  TCPIP_APIMSG_ACK(msg);
+}
+/**
+ * Bind a pcb contained in a netconn to an interface
+ * Called from netconn_bind_if.
+ *
+ * @param m the api_msg pointing to the connection and containing
+ *          the IP address and port to bind to
+ */
+void
+lwip_netconn_do_bind_if(void *m)
+{
+  struct netif *netif;
+  struct api_msg *msg = (struct api_msg *)m;
+  err_t err;
+
+  netif = netif_get_by_index(msg->msg.bc.if_idx);
+
+  if ((netif != NULL) && (msg->conn->pcb.tcp != NULL)) {
+    err = ERR_OK;
+    switch (NETCONNTYPE_GROUP(msg->conn->type)) {
+#if LWIP_RAW
+      case NETCONN_RAW:
+        raw_bind_netif(msg->conn->pcb.raw, netif);
+        break;
+#endif /* LWIP_RAW */
+#if LWIP_UDP
+      case NETCONN_UDP:
+        udp_bind_netif(msg->conn->pcb.udp, netif);
+        break;
+#endif /* LWIP_UDP */
+#if LWIP_TCP
+      case NETCONN_TCP:
+        tcp_bind_netif(msg->conn->pcb.tcp, netif);
+        break;
+#endif /* LWIP_TCP */
+      default:
+        err = ERR_VAL;
+        break;
+    }
+  } else {
+    err = ERR_VAL;
+  }
+  msg->err = err;
+  TCPIP_APIMSG_ACK(msg);
+}
+
+#if LWIP_TCP
+/**
+ * TCP callback function if a connection (opened by tcp_connect/lwip_netconn_do_connect) has
+ * been established (or reset by the remote host).
+ *
+ * @see tcp.h (struct tcp_pcb.connected) for parameters and return values
+ */
+static err_t
+lwip_netconn_do_connected(void *arg, struct tcp_pcb *pcb, err_t err)
+{
+  struct netconn *conn;
+  int was_blocking;
+  sys_sem_t *op_completed_sem = NULL;
+
+  LWIP_UNUSED_ARG(pcb);
+
+  conn = (struct netconn *)arg;
+
+  if (conn == NULL) {
+    return ERR_VAL;
+  }
+
+  LWIP_ASSERT("conn->state == NETCONN_CONNECT", conn->state == NETCONN_CONNECT);
+  LWIP_ASSERT("(conn->current_msg != NULL) || conn->in_non_blocking_connect",
+              (conn->current_msg != NULL) || IN_NONBLOCKING_CONNECT(conn));
+
+  if (conn->current_msg != NULL) {
+    conn->current_msg->err = err;
+    op_completed_sem = LWIP_API_MSG_SEM(conn->current_msg);
+  }
+  if ((NETCONNTYPE_GROUP(conn->type) == NETCONN_TCP) && (err == ERR_OK)) {
+    setup_tcp(conn);
+  }
+  was_blocking = !IN_NONBLOCKING_CONNECT(conn);
+  SET_NONBLOCKING_CONNECT(conn, 0);
+  LWIP_ASSERT("blocking connect state error",
+              (was_blocking && op_completed_sem != NULL) ||
+              (!was_blocking && op_completed_sem == NULL));
+  conn->current_msg = NULL;
+  conn->state = NETCONN_NONE;
+  API_EVENT(conn, NETCONN_EVT_SENDPLUS, 0);
+
+  if (was_blocking) {
+    sys_sem_signal(op_completed_sem);
+  }
+  return ERR_OK;
+}
+#endif /* LWIP_TCP */
+
+/**
+ * Connect a pcb contained inside a netconn
+ * Called from netconn_connect.
+ *
+ * @param m the api_msg pointing to the connection and containing
+ *          the IP address and port to connect to
+ */
+void
+lwip_netconn_do_connect(void *m)
+{
+  struct api_msg *msg = (struct api_msg *)m;
+  err_t err;
+
+  if (msg->conn->pcb.tcp == NULL) {
+    /* This may happen when calling netconn_connect() a second time */
+    err = ERR_CLSD;
+  } else {
+    switch (NETCONNTYPE_GROUP(msg->conn->type)) {
+#if LWIP_RAW
+      case NETCONN_RAW:
+        err = raw_connect(msg->conn->pcb.raw, API_EXPR_REF(msg->msg.bc.ipaddr));
+        break;
+#endif /* LWIP_RAW */
+#if LWIP_UDP
+      case NETCONN_UDP:
+        err = udp_connect(msg->conn->pcb.udp, API_EXPR_REF(msg->msg.bc.ipaddr), msg->msg.bc.port);
+        break;
+#endif /* LWIP_UDP */
+#if LWIP_TCP
+      case NETCONN_TCP:
+        /* Prevent connect while doing any other action. */
+        if (msg->conn->state == NETCONN_CONNECT) {
+          err = ERR_ALREADY;
+        } else if (msg->conn->state != NETCONN_NONE) {
+          err = ERR_ISCONN;
+        } else {
+          setup_tcp(msg->conn);
+          err = tcp_connect(msg->conn->pcb.tcp, API_EXPR_REF(msg->msg.bc.ipaddr),
+                            msg->msg.bc.port, lwip_netconn_do_connected);
+          if (err == ERR_OK) {
+            u8_t non_blocking = netconn_is_nonblocking(msg->conn);
+            msg->conn->state = NETCONN_CONNECT;
+            SET_NONBLOCKING_CONNECT(msg->conn, non_blocking);
+            if (non_blocking) {
+              err = ERR_INPROGRESS;
+            } else {
+              msg->conn->current_msg = msg;
+              /* sys_sem_signal() is called from lwip_netconn_do_connected (or err_tcp()),
+                 when the connection is established! */
+#if LWIP_TCPIP_CORE_LOCKING
+              LWIP_ASSERT("state!", msg->conn->state == NETCONN_CONNECT);
+              UNLOCK_TCPIP_CORE();
+              sys_arch_sem_wait(LWIP_API_MSG_SEM(msg), 0);
+              LOCK_TCPIP_CORE();
+              LWIP_ASSERT("state!", msg->conn->state != NETCONN_CONNECT);
+#endif /* LWIP_TCPIP_CORE_LOCKING */
+              return;
+            }
+          }
+        }
+        break;
+#endif /* LWIP_TCP */
+      default:
+        LWIP_ERROR("Invalid netconn type", 0, do {
+          err = ERR_VAL;
+        } while (0));
+        break;
+    }
+  }
+  msg->err = err;
+  /* For all other protocols, netconn_connect() calls netconn_apimsg(),
+     so use TCPIP_APIMSG_ACK() here. */
+  TCPIP_APIMSG_ACK(msg);
+}
+
+/**
+ * Disconnect a pcb contained inside a netconn
+ * Only used for UDP netconns.
+ * Called from netconn_disconnect.
+ *
+ * @param m the api_msg pointing to the connection to disconnect
+ */
+void
+lwip_netconn_do_disconnect(void *m)
+{
+  struct api_msg *msg = (struct api_msg *)m;
+
+#if LWIP_UDP
+  if (NETCONNTYPE_GROUP(msg->conn->type) == NETCONN_UDP) {
+    udp_disconnect(msg->conn->pcb.udp);
+    msg->err = ERR_OK;
+  } else
+#endif /* LWIP_UDP */
+  {
+    msg->err = ERR_VAL;
+  }
+  TCPIP_APIMSG_ACK(msg);
+}
+
+#if LWIP_TCP
+/**
+ * Set a TCP pcb contained in a netconn into listen mode
+ * Called from netconn_listen.
+ *
+ * @param m the api_msg pointing to the connection
+ */
+void
+lwip_netconn_do_listen(void *m)
+{
+  struct api_msg *msg = (struct api_msg *)m;
+  err_t err;
+
+  if (msg->conn->pcb.tcp != NULL) {
+    if (NETCONNTYPE_GROUP(msg->conn->type) == NETCONN_TCP) {
+      if (msg->conn->state == NETCONN_NONE) {
+        struct tcp_pcb *lpcb;
+        if (msg->conn->pcb.tcp->state != CLOSED) {
+          /* connection is not closed, cannot listen */
+          err = ERR_VAL;
+        } else {
+          u8_t backlog;
+#if TCP_LISTEN_BACKLOG
+          backlog = msg->msg.lb.backlog;
+#else  /* TCP_LISTEN_BACKLOG */
+          backlog = TCP_DEFAULT_LISTEN_BACKLOG;
+#endif /* TCP_LISTEN_BACKLOG */
+#if LWIP_IPV4 && LWIP_IPV6
+          /* "Socket API like" dual-stack support: If IP to listen to is IP6_ADDR_ANY,
+            * and NETCONN_FLAG_IPV6_V6ONLY is NOT set, use IP_ANY_TYPE to listen
+            */
+          if (ip_addr_cmp(&msg->conn->pcb.ip->local_ip, IP6_ADDR_ANY) &&
+              (netconn_get_ipv6only(msg->conn) == 0)) {
+            /* change PCB type to IPADDR_TYPE_ANY */
+            IP_SET_TYPE_VAL(msg->conn->pcb.tcp->local_ip,  IPADDR_TYPE_ANY);
+            IP_SET_TYPE_VAL(msg->conn->pcb.tcp->remote_ip, IPADDR_TYPE_ANY);
+          }
+#endif /* LWIP_IPV4 && LWIP_IPV6 */
+
+          lpcb = tcp_listen_with_backlog_and_err(msg->conn->pcb.tcp, backlog, &err);
+
+          if (lpcb == NULL) {
+            /* in this case, the old pcb is still allocated */
+          } else {
+            /* delete the recvmbox and allocate the acceptmbox */
+            if (sys_mbox_valid(&msg->conn->recvmbox)) {
+              /** @todo: should we drain the recvmbox here? */
+              sys_mbox_free(&msg->conn->recvmbox);
+              sys_mbox_set_invalid(&msg->conn->recvmbox);
+            }
+            err = ERR_OK;
+            if (!sys_mbox_valid(&msg->conn->acceptmbox)) {
+              err = sys_mbox_new(&msg->conn->acceptmbox, DEFAULT_ACCEPTMBOX_SIZE);
+            }
+            if (err == ERR_OK) {
+              msg->conn->state = NETCONN_LISTEN;
+              msg->conn->pcb.tcp = lpcb;
+              tcp_arg(msg->conn->pcb.tcp, msg->conn);
+              tcp_accept(msg->conn->pcb.tcp, accept_function);
+            } else {
+              /* since the old pcb is already deallocated, free lpcb now */
+              tcp_close(lpcb);
+              msg->conn->pcb.tcp = NULL;
+            }
+          }
+        }
+      } else if (msg->conn->state == NETCONN_LISTEN) {
+        /* already listening, allow updating of the backlog */
+        err = ERR_OK;
+        tcp_backlog_set(msg->conn->pcb.tcp, msg->msg.lb.backlog);
+      } else {
+        err = ERR_CONN;
+      }
+    } else {
+      err = ERR_ARG;
+    }
+  } else {
+    err = ERR_CONN;
+  }
+  msg->err = err;
+  TCPIP_APIMSG_ACK(msg);
+}
+#endif /* LWIP_TCP */
+
+/**
+ * Send some data on a RAW or UDP pcb contained in a netconn
+ * Called from netconn_send
+ *
+ * @param m the api_msg pointing to the connection
+ */
+void
+lwip_netconn_do_send(void *m)
+{
+  struct api_msg *msg = (struct api_msg *)m;
+
+  err_t err = netconn_err(msg->conn);
+  if (err == ERR_OK) {
+    if (msg->conn->pcb.tcp != NULL) {
+      switch (NETCONNTYPE_GROUP(msg->conn->type)) {
+#if LWIP_RAW
+        case NETCONN_RAW:
+          if (ip_addr_isany(&msg->msg.b->addr) || IP_IS_ANY_TYPE_VAL(msg->msg.b->addr)) {
+            err = raw_send(msg->conn->pcb.raw, msg->msg.b->p);
+          } else {
+            err = raw_sendto(msg->conn->pcb.raw, msg->msg.b->p, &msg->msg.b->addr);
+          }
+          break;
+#endif
+#if LWIP_UDP
+        case NETCONN_UDP:
+#if LWIP_CHECKSUM_ON_COPY
+          if (ip_addr_isany(&msg->msg.b->addr) || IP_IS_ANY_TYPE_VAL(msg->msg.b->addr)) {
+            err = udp_send_chksum(msg->conn->pcb.udp, msg->msg.b->p,
+                                  msg->msg.b->flags & NETBUF_FLAG_CHKSUM, msg->msg.b->toport_chksum);
+          } else {
+            err = udp_sendto_chksum(msg->conn->pcb.udp, msg->msg.b->p,
+                                    &msg->msg.b->addr, msg->msg.b->port,
+                                    msg->msg.b->flags & NETBUF_FLAG_CHKSUM, msg->msg.b->toport_chksum);
+          }
+#else /* LWIP_CHECKSUM_ON_COPY */
+          if (ip_addr_isany_val(msg->msg.b->addr) || IP_IS_ANY_TYPE_VAL(msg->msg.b->addr)) {
+            err = udp_send(msg->conn->pcb.udp, msg->msg.b->p);
+          } else {
+            err = udp_sendto(msg->conn->pcb.udp, msg->msg.b->p, &msg->msg.b->addr, msg->msg.b->port);
+          }
+#endif /* LWIP_CHECKSUM_ON_COPY */
+          break;
+#endif /* LWIP_UDP */
+        default:
+          err = ERR_CONN;
+          break;
+      }
+    } else {
+      err = ERR_CONN;
+    }
+  }
+  msg->err = err;
+  TCPIP_APIMSG_ACK(msg);
+}
+
+#if LWIP_TCP
+/**
+ * Indicate data has been received from a TCP pcb contained in a netconn
+ * Called from netconn_recv
+ *
+ * @param m the api_msg pointing to the connection
+ */
+void
+lwip_netconn_do_recv(void *m)
+{
+  struct api_msg *msg = (struct api_msg *)m;
+
+  msg->err = ERR_OK;
+  if (msg->conn->pcb.tcp != NULL) {
+    if (NETCONNTYPE_GROUP(msg->conn->type) == NETCONN_TCP) {
+      size_t remaining = msg->msg.r.len;
+      do {
+        u16_t recved = (u16_t)((remaining > 0xffff) ? 0xffff : remaining);
+        tcp_recved(msg->conn->pcb.tcp, recved);
+        remaining -= recved;
+      } while (remaining != 0);
+    }
+  }
+  TCPIP_APIMSG_ACK(msg);
+}
+
+#if TCP_LISTEN_BACKLOG
+/** Indicate that a TCP pcb has been accepted
+ * Called from netconn_accept
+ *
+ * @param m the api_msg pointing to the connection
+ */
+void
+lwip_netconn_do_accepted(void *m)
+{
+  struct api_msg *msg = (struct api_msg *)m;
+
+  msg->err = ERR_OK;
+  if (msg->conn->pcb.tcp != NULL) {
+    if (NETCONNTYPE_GROUP(msg->conn->type) == NETCONN_TCP) {
+      tcp_backlog_accepted(msg->conn->pcb.tcp);
+    }
+  }
+  TCPIP_APIMSG_ACK(msg);
+}
+#endif /* TCP_LISTEN_BACKLOG */
+
+/**
+ * See if more data needs to be written from a previous call to netconn_write.
+ * Called initially from lwip_netconn_do_write. If the first call can't send all data
+ * (because of low memory or empty send-buffer), this function is called again
+ * from sent_tcp() or poll_tcp() to send more data. If all data is sent, the
+ * blocking application thread (waiting in netconn_write) is released.
+ *
+ * @param conn netconn (that is currently in state NETCONN_WRITE) to process
+ * @return ERR_OK
+ *         ERR_MEM if LWIP_TCPIP_CORE_LOCKING=1 and sending hasn't yet finished
+ */
+static err_t
+lwip_netconn_do_writemore(struct netconn *conn  WRITE_DELAYED_PARAM)
+{
+  err_t err;
+  const void *dataptr;
+  u16_t len, available;
+  u8_t write_finished = 0;
+  size_t diff;
+  u8_t dontblock;
+  u8_t apiflags;
+  u8_t write_more;
+
+  LWIP_ASSERT("conn != NULL", conn != NULL);
+  LWIP_ASSERT("conn->state == NETCONN_WRITE", (conn->state == NETCONN_WRITE));
+  LWIP_ASSERT("conn->current_msg != NULL", conn->current_msg != NULL);
+  LWIP_ASSERT("conn->pcb.tcp != NULL", conn->pcb.tcp != NULL);
+  LWIP_ASSERT("conn->current_msg->msg.w.offset < conn->current_msg->msg.w.len",
+              conn->current_msg->msg.w.offset < conn->current_msg->msg.w.len);
+  LWIP_ASSERT("conn->current_msg->msg.w.vector_cnt > 0", conn->current_msg->msg.w.vector_cnt > 0);
+
+  apiflags = conn->current_msg->msg.w.apiflags;
+  dontblock = netconn_is_nonblocking(conn) || (apiflags & NETCONN_DONTBLOCK);
+
+#if LWIP_SO_SNDTIMEO
+  if ((conn->send_timeout != 0) &&
+      ((s32_t)(sys_now() - conn->current_msg->msg.w.time_started) >= conn->send_timeout)) {
+    write_finished = 1;
+    if (conn->current_msg->msg.w.offset == 0) {
+      /* nothing has been written */
+      err = ERR_WOULDBLOCK;
+    } else {
+      /* partial write */
+      err = ERR_OK;
+    }
+  } else
+#endif /* LWIP_SO_SNDTIMEO */
+  {
+    do {
+      dataptr = (const u8_t *)conn->current_msg->msg.w.vector->ptr + conn->current_msg->msg.w.vector_off;
+      diff = conn->current_msg->msg.w.vector->len - conn->current_msg->msg.w.vector_off;
+      if (diff > 0xffffUL) { /* max_u16_t */
+        len = 0xffff;
+        apiflags |= TCP_WRITE_FLAG_MORE;
+      } else {
+        len = (u16_t)diff;
+      }
+      available = tcp_sndbuf(conn->pcb.tcp);
+      if (available < len) {
+        /* don't try to write more than sendbuf */
+        len = available;
+        if (dontblock) {
+          if (!len) {
+            /* set error according to partial write or not */
+            err = (conn->current_msg->msg.w.offset == 0) ? ERR_WOULDBLOCK : ERR_OK;
+            goto err_mem;
+          }
+        } else {
+          apiflags |= TCP_WRITE_FLAG_MORE;
+        }
+      }
+      LWIP_ASSERT("lwip_netconn_do_writemore: invalid length!",
+                  ((conn->current_msg->msg.w.vector_off + len) <= conn->current_msg->msg.w.vector->len));
+      /* we should loop around for more sending in the following cases:
+           1) We couldn't finish the current vector because of 16-bit size limitations.
+              tcp_write() and tcp_sndbuf() both are limited to 16-bit sizes
+           2) We are sending the remainder of the current vector and have more */
+      if ((len == 0xffff && diff > 0xffffUL) ||
+          (len == (u16_t)diff && conn->current_msg->msg.w.vector_cnt > 1)) {
+        write_more = 1;
+        apiflags |= TCP_WRITE_FLAG_MORE;
+      } else {
+        write_more = 0;
+      }
+      err = tcp_write(conn->pcb.tcp, dataptr, len, apiflags);
+      if (err == ERR_OK) {
+        conn->current_msg->msg.w.offset += len;
+        conn->current_msg->msg.w.vector_off += len;
+        /* check if current vector is finished */
+        if (conn->current_msg->msg.w.vector_off == conn->current_msg->msg.w.vector->len) {
+          conn->current_msg->msg.w.vector_cnt--;
+          /* if we have additional vectors, move on to them */
+          if (conn->current_msg->msg.w.vector_cnt > 0) {
+            conn->current_msg->msg.w.vector++;
+            conn->current_msg->msg.w.vector_off = 0;
+          }
+        }
+      }
+    } while (write_more && err == ERR_OK);
+    /* if OK or memory error, check available space */
+    if ((err == ERR_OK) || (err == ERR_MEM)) {
+err_mem:
+      if (dontblock && (conn->current_msg->msg.w.offset < conn->current_msg->msg.w.len)) {
+        /* non-blocking write did not write everything: mark the pcb non-writable
+           and let poll_tcp check writable space to mark the pcb writable again */
+        API_EVENT(conn, NETCONN_EVT_SENDMINUS, 0);
+        conn->flags |= NETCONN_FLAG_CHECK_WRITESPACE;
+      } else if ((tcp_sndbuf(conn->pcb.tcp) <= TCP_SNDLOWAT) ||
+                 (tcp_sndqueuelen(conn->pcb.tcp) >= TCP_SNDQUEUELOWAT)) {
+        /* The queued byte- or pbuf-count exceeds the configured low-water limit,
+           let select mark this pcb as non-writable. */
+        API_EVENT(conn, NETCONN_EVT_SENDMINUS, 0);
+      }
+    }
+
+    if (err == ERR_OK) {
+      err_t out_err;
+      if ((conn->current_msg->msg.w.offset == conn->current_msg->msg.w.len) || dontblock) {
+        /* return sent length (caller reads length from msg.w.offset) */
+        write_finished = 1;
+      }
+      out_err = tcp_output(conn->pcb.tcp);
+      if (out_err == ERR_RTE) {
+        /* If tcp_output fails because no route is found,
+           don't try writing any more but return the error
+           to the application thread. */
+        err = out_err;
+        write_finished = 1;
+      }
+    } else if (err == ERR_MEM) {
+      /* If ERR_MEM, we wait for sent_tcp or poll_tcp to be called.
+         For blocking sockets, we do NOT return to the application
+         thread, since ERR_MEM is only a temporary error! Non-blocking
+         will remain non-writable until sent_tcp/poll_tcp is called */
+
+      /* tcp_write returned ERR_MEM, try tcp_output anyway */
+      err_t out_err = tcp_output(conn->pcb.tcp);
+      if (out_err == ERR_RTE) {
+        /* If tcp_output fails because no route is found,
+           don't try writing any more but return the error
+           to the application thread. */
+        err = out_err;
+        write_finished = 1;
+      } else if (dontblock) {
+        /* non-blocking write is done on ERR_MEM, set error according
+           to partial write or not */
+        err = (conn->current_msg->msg.w.offset == 0) ? ERR_WOULDBLOCK : ERR_OK;
+        write_finished = 1;
+      }
+    } else {
+      /* On errors != ERR_MEM, we don't try writing any more but return
+         the error to the application thread. */
+      write_finished = 1;
+    }
+  }
+  if (write_finished) {
+    /* everything was written: set back connection state
+       and back to application task */
+    sys_sem_t *op_completed_sem = LWIP_API_MSG_SEM(conn->current_msg);
+    conn->current_msg->err = err;
+    conn->current_msg = NULL;
+    conn->state = NETCONN_NONE;
+#if LWIP_TCPIP_CORE_LOCKING
+    if (delayed)
+#endif
+    {
+      sys_sem_signal(op_completed_sem);
+    }
+  }
+#if LWIP_TCPIP_CORE_LOCKING
+  else {
+    return ERR_MEM;
+  }
+#endif
+  return ERR_OK;
+}
+#endif /* LWIP_TCP */
+
+/**
+ * Send some data on a TCP pcb contained in a netconn
+ * Called from netconn_write
+ *
+ * @param m the api_msg pointing to the connection
+ */
+void
+lwip_netconn_do_write(void *m)
+{
+  struct api_msg *msg = (struct api_msg *)m;
+
+  err_t err = netconn_err(msg->conn);
+  if (err == ERR_OK) {
+    if (NETCONNTYPE_GROUP(msg->conn->type) == NETCONN_TCP) {
+#if LWIP_TCP
+      if (msg->conn->state != NETCONN_NONE) {
+        /* netconn is connecting, closing or in blocking write */
+        err = ERR_INPROGRESS;
+      } else if (msg->conn->pcb.tcp != NULL) {
+        msg->conn->state = NETCONN_WRITE;
+        /* set all the variables used by lwip_netconn_do_writemore */
+        LWIP_ASSERT("already writing or closing", msg->conn->current_msg == NULL);
+        LWIP_ASSERT("msg->msg.w.len != 0", msg->msg.w.len != 0);
+        msg->conn->current_msg = msg;
+#if LWIP_TCPIP_CORE_LOCKING
+        if (lwip_netconn_do_writemore(msg->conn, 0) != ERR_OK) {
+          LWIP_ASSERT("state!", msg->conn->state == NETCONN_WRITE);
+          UNLOCK_TCPIP_CORE();
+          sys_arch_sem_wait(LWIP_API_MSG_SEM(msg), 0);
+          LOCK_TCPIP_CORE();
+          LWIP_ASSERT("state!", msg->conn->state != NETCONN_WRITE);
+        }
+#else /* LWIP_TCPIP_CORE_LOCKING */
+        lwip_netconn_do_writemore(msg->conn);
+#endif /* LWIP_TCPIP_CORE_LOCKING */
+        /* for both cases: if lwip_netconn_do_writemore was called, don't ACK the APIMSG
+           since lwip_netconn_do_writemore ACKs it! */
+        return;
+      } else {
+        err = ERR_CONN;
+      }
+#else /* LWIP_TCP */
+      err = ERR_VAL;
+#endif /* LWIP_TCP */
+#if (LWIP_UDP || LWIP_RAW)
+    } else {
+      err = ERR_VAL;
+#endif /* (LWIP_UDP || LWIP_RAW) */
+    }
+  }
+  msg->err = err;
+  TCPIP_APIMSG_ACK(msg);
+}
+
+/**
+ * Return a connection's local or remote address
+ * Called from netconn_getaddr
+ *
+ * @param m the api_msg pointing to the connection
+ */
+void
+lwip_netconn_do_getaddr(void *m)
+{
+  struct api_msg *msg = (struct api_msg *)m;
+
+  if (msg->conn->pcb.ip != NULL) {
+    if (msg->msg.ad.local) {
+      ip_addr_copy(API_EXPR_DEREF(msg->msg.ad.ipaddr),
+                   msg->conn->pcb.ip->local_ip);
+    } else {
+      ip_addr_copy(API_EXPR_DEREF(msg->msg.ad.ipaddr),
+                   msg->conn->pcb.ip->remote_ip);
+    }
+
+    msg->err = ERR_OK;
+    switch (NETCONNTYPE_GROUP(msg->conn->type)) {
+#if LWIP_RAW
+      case NETCONN_RAW:
+        if (msg->msg.ad.local) {
+          API_EXPR_DEREF(msg->msg.ad.port) = msg->conn->pcb.raw->protocol;
+        } else {
+          /* return an error as connecting is only a helper for upper layers */
+          msg->err = ERR_CONN;
+        }
+        break;
+#endif /* LWIP_RAW */
+#if LWIP_UDP
+      case NETCONN_UDP:
+        if (msg->msg.ad.local) {
+          API_EXPR_DEREF(msg->msg.ad.port) = msg->conn->pcb.udp->local_port;
+        } else {
+          if ((msg->conn->pcb.udp->flags & UDP_FLAGS_CONNECTED) == 0) {
+            msg->err = ERR_CONN;
+          } else {
+            API_EXPR_DEREF(msg->msg.ad.port) = msg->conn->pcb.udp->remote_port;
+          }
+        }
+        break;
+#endif /* LWIP_UDP */
+#if LWIP_TCP
+      case NETCONN_TCP:
+        if ((msg->msg.ad.local == 0) &&
+            ((msg->conn->pcb.tcp->state == CLOSED) || (msg->conn->pcb.tcp->state == LISTEN))) {
+          /* pcb is not connected and remote name is requested */
+          msg->err = ERR_CONN;
+        } else {
+          API_EXPR_DEREF(msg->msg.ad.port) = (msg->msg.ad.local ? msg->conn->pcb.tcp->local_port : msg->conn->pcb.tcp->remote_port);
+        }
+        break;
+#endif /* LWIP_TCP */
+      default:
+        LWIP_ASSERT("invalid netconn_type", 0);
+        break;
+    }
+  } else {
+    msg->err = ERR_CONN;
+  }
+  TCPIP_APIMSG_ACK(msg);
+}
+
+/**
+ * Close or half-shutdown a TCP pcb contained in a netconn
+ * Called from netconn_close
+ * In contrast to closing sockets, the netconn is not deallocated.
+ *
+ * @param m the api_msg pointing to the connection
+ */
+void
+lwip_netconn_do_close(void *m)
+{
+  struct api_msg *msg = (struct api_msg *)m;
+
+#if LWIP_TCP
+  enum netconn_state state = msg->conn->state;
+  /* First check if this is a TCP netconn and if it is in a correct state
+      (LISTEN doesn't support half shutdown) */
+  if ((msg->conn->pcb.tcp != NULL) &&
+      (NETCONNTYPE_GROUP(msg->conn->type) == NETCONN_TCP) &&
+      ((msg->msg.sd.shut == NETCONN_SHUT_RDWR) || (state != NETCONN_LISTEN))) {
+    /* Check if we are in a connected state */
+    if (state == NETCONN_CONNECT) {
+      /* TCP connect in progress: cannot shutdown */
+      msg->err = ERR_CONN;
+    } else if (state == NETCONN_WRITE) {
+#if LWIP_NETCONN_FULLDUPLEX
+      if (msg->msg.sd.shut & NETCONN_SHUT_WR) {
+        /* close requested, abort running write */
+        sys_sem_t *write_completed_sem;
+        LWIP_ASSERT("msg->conn->current_msg != NULL", msg->conn->current_msg != NULL);
+        write_completed_sem = LWIP_API_MSG_SEM(msg->conn->current_msg);
+        msg->conn->current_msg->err = ERR_CLSD;
+        msg->conn->current_msg = NULL;
+        msg->conn->state = NETCONN_NONE;
+        state = NETCONN_NONE;
+        sys_sem_signal(write_completed_sem);
+      } else {
+        LWIP_ASSERT("msg->msg.sd.shut == NETCONN_SHUT_RD", msg->msg.sd.shut == NETCONN_SHUT_RD);
+        /* In this case, let the write continue and do not interfere with
+           conn->current_msg or conn->state! */
+        msg->err = tcp_shutdown(msg->conn->pcb.tcp, 1, 0);
+      }
+    }
+    if (state == NETCONN_NONE) {
+#else /* LWIP_NETCONN_FULLDUPLEX */
+      msg->err = ERR_INPROGRESS;
+    } else {
+#endif /* LWIP_NETCONN_FULLDUPLEX */
+      if (msg->msg.sd.shut & NETCONN_SHUT_RD) {
+#if LWIP_NETCONN_FULLDUPLEX
+        /* Mark mboxes invalid */
+        netconn_mark_mbox_invalid(msg->conn);
+#else /* LWIP_NETCONN_FULLDUPLEX */
+        netconn_drain(msg->conn);
+#endif /* LWIP_NETCONN_FULLDUPLEX */
+      }
+      LWIP_ASSERT("already writing or closing", msg->conn->current_msg == NULL);
+      msg->conn->state = NETCONN_CLOSE;
+      msg->conn->current_msg = msg;
+#if LWIP_TCPIP_CORE_LOCKING
+      if (lwip_netconn_do_close_internal(msg->conn, 0) != ERR_OK) {
+        LWIP_ASSERT("state!", msg->conn->state == NETCONN_CLOSE);
+        UNLOCK_TCPIP_CORE();
+        sys_arch_sem_wait(LWIP_API_MSG_SEM(msg), 0);
+        LOCK_TCPIP_CORE();
+        LWIP_ASSERT("state!", msg->conn->state == NETCONN_NONE);
+      }
+#else /* LWIP_TCPIP_CORE_LOCKING */
+      lwip_netconn_do_close_internal(msg->conn);
+#endif /* LWIP_TCPIP_CORE_LOCKING */
+      /* for tcp netconns, lwip_netconn_do_close_internal ACKs the message */
+      return;
+    }
+  } else
+#endif /* LWIP_TCP */
+  {
+    msg->err = ERR_CONN;
+  }
+  TCPIP_APIMSG_ACK(msg);
+}
+
+#if LWIP_IGMP || (LWIP_IPV6 && LWIP_IPV6_MLD)
+/**
+ * Join multicast groups for UDP netconns.
+ * Called from netconn_join_leave_group
+ *
+ * @param m the api_msg pointing to the connection
+ */
+void
+lwip_netconn_do_join_leave_group(void *m)
+{
+  struct api_msg *msg = (struct api_msg *)m;
+
+  msg->err = ERR_CONN;
+  if (msg->conn->pcb.tcp != NULL) {
+    if (NETCONNTYPE_GROUP(msg->conn->type) == NETCONN_UDP) {
+#if LWIP_UDP
+#if LWIP_IPV6 && LWIP_IPV6_MLD
+      if (NETCONNTYPE_ISIPV6(msg->conn->type)) {
+        if (msg->msg.jl.join_or_leave == NETCONN_JOIN) {
+          msg->err = mld6_joingroup(ip_2_ip6(API_EXPR_REF(msg->msg.jl.netif_addr)),
+                                    ip_2_ip6(API_EXPR_REF(msg->msg.jl.multiaddr)));
+        } else {
+          msg->err = mld6_leavegroup(ip_2_ip6(API_EXPR_REF(msg->msg.jl.netif_addr)),
+                                     ip_2_ip6(API_EXPR_REF(msg->msg.jl.multiaddr)));
+        }
+      } else
+#endif /* LWIP_IPV6 && LWIP_IPV6_MLD */
+      {
+#if LWIP_IGMP
+        if (msg->msg.jl.join_or_leave == NETCONN_JOIN) {
+          msg->err = igmp_joingroup(ip_2_ip4(API_EXPR_REF(msg->msg.jl.netif_addr)),
+                                    ip_2_ip4(API_EXPR_REF(msg->msg.jl.multiaddr)));
+        } else {
+          msg->err = igmp_leavegroup(ip_2_ip4(API_EXPR_REF(msg->msg.jl.netif_addr)),
+                                     ip_2_ip4(API_EXPR_REF(msg->msg.jl.multiaddr)));
+        }
+#endif /* LWIP_IGMP */
+      }
+#endif /* LWIP_UDP */
+#if (LWIP_TCP || LWIP_RAW)
+    } else {
+      msg->err = ERR_VAL;
+#endif /* (LWIP_TCP || LWIP_RAW) */
+    }
+  }
+  TCPIP_APIMSG_ACK(msg);
+}
+/**
+ * Join multicast groups for UDP netconns.
+ * Called from netconn_join_leave_group_netif
+ *
+ * @param m the api_msg pointing to the connection
+ */
+void
+lwip_netconn_do_join_leave_group_netif(void *m)
+{
+  struct api_msg *msg = (struct api_msg *)m;
+  struct netif *netif;
+
+  netif = netif_get_by_index(msg->msg.jl.if_idx);
+  if (netif == NULL) {
+    msg->err = ERR_IF;
+    goto done;
+  }
+
+  msg->err = ERR_CONN;
+  if (msg->conn->pcb.tcp != NULL) {
+    if (NETCONNTYPE_GROUP(msg->conn->type) == NETCONN_UDP) {
+#if LWIP_UDP
+#if LWIP_IPV6 && LWIP_IPV6_MLD
+      if (NETCONNTYPE_ISIPV6(msg->conn->type)) {
+        if (msg->msg.jl.join_or_leave == NETCONN_JOIN) {
+          msg->err = mld6_joingroup_netif(netif,
+                                          ip_2_ip6(API_EXPR_REF(msg->msg.jl.multiaddr)));
+        } else {
+          msg->err = mld6_leavegroup_netif(netif,
+                                           ip_2_ip6(API_EXPR_REF(msg->msg.jl.multiaddr)));
+        }
+      } else
+#endif /* LWIP_IPV6 && LWIP_IPV6_MLD */
+      {
+#if LWIP_IGMP
+        if (msg->msg.jl.join_or_leave == NETCONN_JOIN) {
+          msg->err = igmp_joingroup_netif(netif,
+                                          ip_2_ip4(API_EXPR_REF(msg->msg.jl.multiaddr)));
+        } else {
+          msg->err = igmp_leavegroup_netif(netif,
+                                           ip_2_ip4(API_EXPR_REF(msg->msg.jl.multiaddr)));
+        }
+#endif /* LWIP_IGMP */
+      }
+#endif /* LWIP_UDP */
+#if (LWIP_TCP || LWIP_RAW)
+    } else {
+      msg->err = ERR_VAL;
+#endif /* (LWIP_TCP || LWIP_RAW) */
+    }
+  }
+
+done:
+  TCPIP_APIMSG_ACK(msg);
+}
+#endif /* LWIP_IGMP || (LWIP_IPV6 && LWIP_IPV6_MLD) */
+
+#if LWIP_DNS
+/**
+ * Callback function that is called when DNS name is resolved
+ * (or on timeout). A waiting application thread is waked up by
+ * signaling the semaphore.
+ */
+static void
+lwip_netconn_do_dns_found(const char *name, const ip_addr_t *ipaddr, void *arg)
+{
+  struct dns_api_msg *msg = (struct dns_api_msg *)arg;
+
+  /* we trust the internal implementation to be correct :-) */
+  LWIP_UNUSED_ARG(name);
+
+  if (ipaddr == NULL) {
+    /* timeout or memory error */
+    API_EXPR_DEREF(msg->err) = ERR_VAL;
+  } else {
+    /* address was resolved */
+    API_EXPR_DEREF(msg->err) = ERR_OK;
+    API_EXPR_DEREF(msg->addr) = *ipaddr;
+  }
+  /* wake up the application task waiting in netconn_gethostbyname */
+  sys_sem_signal(API_EXPR_REF_SEM(msg->sem));
+}
+
+/**
+ * Execute a DNS query
+ * Called from netconn_gethostbyname
+ *
+ * @param arg the dns_api_msg pointing to the query
+ */
+void
+lwip_netconn_do_gethostbyname(void *arg)
+{
+  struct dns_api_msg *msg = (struct dns_api_msg *)arg;
+  u8_t addrtype =
+#if LWIP_IPV4 && LWIP_IPV6
+    msg->dns_addrtype;
+#else
+    LWIP_DNS_ADDRTYPE_DEFAULT;
+#endif
+
+  API_EXPR_DEREF(msg->err) = dns_gethostbyname_addrtype(msg->name,
+                             API_EXPR_REF(msg->addr), lwip_netconn_do_dns_found, msg, addrtype);
+#if LWIP_TCPIP_CORE_LOCKING
+  /* For core locking, only block if we need to wait for answer/timeout */
+  if (API_EXPR_DEREF(msg->err) == ERR_INPROGRESS) {
+    UNLOCK_TCPIP_CORE();
+    sys_sem_wait(API_EXPR_REF_SEM(msg->sem));
+    LOCK_TCPIP_CORE();
+    LWIP_ASSERT("do_gethostbyname still in progress!!", API_EXPR_DEREF(msg->err) != ERR_INPROGRESS);
+  }
+#else /* LWIP_TCPIP_CORE_LOCKING */
+  if (API_EXPR_DEREF(msg->err) != ERR_INPROGRESS) {
+    /* on error or immediate success, wake up the application
+     * task waiting in netconn_gethostbyname */
+    sys_sem_signal(API_EXPR_REF_SEM(msg->sem));
+  }
+#endif /* LWIP_TCPIP_CORE_LOCKING */
+}
+#endif /* LWIP_DNS */
+
+#endif /* LWIP_NETCONN */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/api/err.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/api/err.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/api/err.c	(revision 457)
@@ -0,0 +1,115 @@
+/**
+ * @file
+ * Error Management module
+ *
+ */
+
+/*
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Adam Dunkels <adam@sics.se>
+ *
+ */
+
+#include "lwip/err.h"
+#include "lwip/def.h"
+#include "lwip/sys.h"
+
+#include "lwip/errno.h"
+
+#if !NO_SYS
+/** Table to quickly map an lwIP error (err_t) to a socket error
+  * by using -err as an index */
+static const int err_to_errno_table[] = {
+  0,             /* ERR_OK          0      No error, everything OK. */
+  ENOMEM,        /* ERR_MEM        -1      Out of memory error.     */
+  ENOBUFS,       /* ERR_BUF        -2      Buffer error.            */
+  EWOULDBLOCK,   /* ERR_TIMEOUT    -3      Timeout                  */
+  EHOSTUNREACH,  /* ERR_RTE        -4      Routing problem.         */
+  EINPROGRESS,   /* ERR_INPROGRESS -5      Operation in progress    */
+  EINVAL,        /* ERR_VAL        -6      Illegal value.           */
+  EWOULDBLOCK,   /* ERR_WOULDBLOCK -7      Operation would block.   */
+  EADDRINUSE,    /* ERR_USE        -8      Address in use.          */
+  EALREADY,      /* ERR_ALREADY    -9      Already connecting.      */
+  EISCONN,       /* ERR_ISCONN     -10     Conn already established.*/
+  ENOTCONN,      /* ERR_CONN       -11     Not connected.           */
+  -1,            /* ERR_IF         -12     Low-level netif error    */
+  ECONNABORTED,  /* ERR_ABRT       -13     Connection aborted.      */
+  ECONNRESET,    /* ERR_RST        -14     Connection reset.        */
+  ENOTCONN,      /* ERR_CLSD       -15     Connection closed.       */
+  EIO            /* ERR_ARG        -16     Illegal argument.        */
+};
+
+int
+err_to_errno(err_t err)
+{
+  if ((err > 0) || (-err >= (err_t)LWIP_ARRAYSIZE(err_to_errno_table))) {
+    return EIO;
+  }
+  return err_to_errno_table[-err];
+}
+#endif /* !NO_SYS */
+
+#ifdef LWIP_DEBUG
+
+static const char *err_strerr[] = {
+  "Ok.",                    /* ERR_OK          0  */
+  "Out of memory error.",   /* ERR_MEM        -1  */
+  "Buffer error.",          /* ERR_BUF        -2  */
+  "Timeout.",               /* ERR_TIMEOUT    -3  */
+  "Routing problem.",       /* ERR_RTE        -4  */
+  "Operation in progress.", /* ERR_INPROGRESS -5  */
+  "Illegal value.",         /* ERR_VAL        -6  */
+  "Operation would block.", /* ERR_WOULDBLOCK -7  */
+  "Address in use.",        /* ERR_USE        -8  */
+  "Already connecting.",    /* ERR_ALREADY    -9  */
+  "Already connected.",     /* ERR_ISCONN     -10 */
+  "Not connected.",         /* ERR_CONN       -11 */
+  "Low-level netif error.", /* ERR_IF         -12 */
+  "Connection aborted.",    /* ERR_ABRT       -13 */
+  "Connection reset.",      /* ERR_RST        -14 */
+  "Connection closed.",     /* ERR_CLSD       -15 */
+  "Illegal argument."       /* ERR_ARG        -16 */
+};
+
+/**
+ * Convert an lwip internal error to a string representation.
+ *
+ * @param err an lwip internal err_t
+ * @return a string representation for err
+ */
+const char *
+lwip_strerr(err_t err)
+{
+  if ((err > 0) || (-err >= (err_t)LWIP_ARRAYSIZE(err_strerr))) {
+    return "Unknown error.";
+  }
+  return err_strerr[-err];
+}
+
+#endif /* LWIP_DEBUG */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/api/if_api.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/api/if_api.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/api/if_api.c	(revision 457)
@@ -0,0 +1,102 @@
+/**
+ * @file
+ * Interface Identification APIs from:
+ *              RFC 3493: Basic Socket Interface Extensions for IPv6
+ *                  Section 4: Interface Identification
+ *
+ * @defgroup if_api Interface Identification API
+ * @ingroup socket
+ */
+
+/*
+ * Copyright (c) 2017 Joel Cunningham, Garmin International, Inc. <joel.cunningham@garmin.com>
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Joel Cunningham <joel.cunningham@me.com>
+ *
+ */
+#include "lwip/opt.h"
+
+#if LWIP_SOCKET
+
+#include "lwip/errno.h"
+#include "lwip/if_api.h"
+#include "lwip/netifapi.h"
+#include "lwip/priv/sockets_priv.h"
+
+/**
+ * @ingroup if_api
+ * Maps an interface index to its corresponding name.
+ * @param ifindex interface index
+ * @param ifname shall point to a buffer of at least {IF_NAMESIZE} bytes
+ * @return If ifindex is an interface index, then the function shall return the
+ * value supplied in ifname, which points to a buffer now containing the interface name.
+ * Otherwise, the function shall return a NULL pointer.
+ */
+char *
+lwip_if_indextoname(unsigned int ifindex, char *ifname)
+{
+#if LWIP_NETIF_API
+  if (ifindex <= 0xff) {
+    err_t err = netifapi_netif_index_to_name((u8_t)ifindex, ifname);
+    if (!err && ifname[0] != '\0') {
+      return ifname;
+    }
+  }
+#else /* LWIP_NETIF_API */
+  LWIP_UNUSED_ARG(ifindex);
+  LWIP_UNUSED_ARG(ifname);
+#endif /* LWIP_NETIF_API */
+  set_errno(ENXIO);
+  return NULL;
+}
+
+/**
+ * @ingroup if_api
+ * Returs the interface index corresponding to name ifname.
+ * @param ifname Interface name
+ * @return The corresponding index if ifname is the name of an interface;
+ * otherwise, zero.
+ */
+unsigned int
+lwip_if_nametoindex(const char *ifname)
+{
+#if LWIP_NETIF_API
+  err_t err;
+  u8_t idx;
+
+  err = netifapi_netif_name_to_index(ifname, &idx);
+  if (!err) {
+    return idx;
+  }
+#else /* LWIP_NETIF_API */
+  LWIP_UNUSED_ARG(ifname);
+#endif /* LWIP_NETIF_API */
+  return 0; /* invalid index */
+}
+
+#endif /* LWIP_SOCKET */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/api/netbuf.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/api/netbuf.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/api/netbuf.c	(revision 457)
@@ -0,0 +1,250 @@
+/**
+ * @file
+ * Network buffer management
+ *
+ * @defgroup netbuf Network buffers
+ * @ingroup netconn
+ * Network buffer descriptor for @ref netconn. Based on @ref pbuf internally
+ * to avoid copying data around.\n
+ * Buffers must not be shared accross multiple threads, all functions except
+ * netbuf_new() and netbuf_delete() are not thread-safe.
+ */
+
+/*
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Adam Dunkels <adam@sics.se>
+ *
+ */
+
+#include "lwip/opt.h"
+
+#if LWIP_NETCONN /* don't build if not configured for use in lwipopts.h */
+
+#include "lwip/netbuf.h"
+#include "lwip/memp.h"
+
+#include <string.h>
+
+/**
+ * @ingroup netbuf
+ * Create (allocate) and initialize a new netbuf.
+ * The netbuf doesn't yet contain a packet buffer!
+ *
+ * @return a pointer to a new netbuf
+ *         NULL on lack of memory
+ */
+struct
+netbuf *netbuf_new(void)
+{
+  struct netbuf *buf;
+
+  buf = (struct netbuf *)memp_malloc(MEMP_NETBUF);
+  if (buf != NULL) {
+    memset(buf, 0, sizeof(struct netbuf));
+  }
+  return buf;
+}
+
+/**
+ * @ingroup netbuf
+ * Deallocate a netbuf allocated by netbuf_new().
+ *
+ * @param buf pointer to a netbuf allocated by netbuf_new()
+ */
+void
+netbuf_delete(struct netbuf *buf)
+{
+  if (buf != NULL) {
+    if (buf->p != NULL) {
+      pbuf_free(buf->p);
+      buf->p = buf->ptr = NULL;
+    }
+    memp_free(MEMP_NETBUF, buf);
+  }
+}
+
+/**
+ * @ingroup netbuf
+ * Allocate memory for a packet buffer for a given netbuf.
+ *
+ * @param buf the netbuf for which to allocate a packet buffer
+ * @param size the size of the packet buffer to allocate
+ * @return pointer to the allocated memory
+ *         NULL if no memory could be allocated
+ */
+void *
+netbuf_alloc(struct netbuf *buf, u16_t size)
+{
+  LWIP_ERROR("netbuf_alloc: invalid buf", (buf != NULL), return NULL;);
+
+  /* Deallocate any previously allocated memory. */
+  if (buf->p != NULL) {
+    pbuf_free(buf->p);
+  }
+  buf->p = pbuf_alloc(PBUF_TRANSPORT, size, PBUF_RAM);
+  if (buf->p == NULL) {
+    return NULL;
+  }
+  LWIP_ASSERT("check that first pbuf can hold size",
+              (buf->p->len >= size));
+  buf->ptr = buf->p;
+  return buf->p->payload;
+}
+
+/**
+ * @ingroup netbuf
+ * Free the packet buffer included in a netbuf
+ *
+ * @param buf pointer to the netbuf which contains the packet buffer to free
+ */
+void
+netbuf_free(struct netbuf *buf)
+{
+  LWIP_ERROR("netbuf_free: invalid buf", (buf != NULL), return;);
+  if (buf->p != NULL) {
+    pbuf_free(buf->p);
+  }
+  buf->p = buf->ptr = NULL;
+#if LWIP_CHECKSUM_ON_COPY
+  buf->flags = 0;
+  buf->toport_chksum = 0;
+#endif /* LWIP_CHECKSUM_ON_COPY */
+}
+
+/**
+ * @ingroup netbuf
+ * Let a netbuf reference existing (non-volatile) data.
+ *
+ * @param buf netbuf which should reference the data
+ * @param dataptr pointer to the data to reference
+ * @param size size of the data
+ * @return ERR_OK if data is referenced
+ *         ERR_MEM if data couldn't be referenced due to lack of memory
+ */
+err_t
+netbuf_ref(struct netbuf *buf, const void *dataptr, u16_t size)
+{
+  LWIP_ERROR("netbuf_ref: invalid buf", (buf != NULL), return ERR_ARG;);
+  if (buf->p != NULL) {
+    pbuf_free(buf->p);
+  }
+  buf->p = pbuf_alloc(PBUF_TRANSPORT, 0, PBUF_REF);
+  if (buf->p == NULL) {
+    buf->ptr = NULL;
+    return ERR_MEM;
+  }
+  ((struct pbuf_rom *)buf->p)->payload = dataptr;
+  buf->p->len = buf->p->tot_len = size;
+  buf->ptr = buf->p;
+  return ERR_OK;
+}
+
+/**
+ * @ingroup netbuf
+ * Chain one netbuf to another (@see pbuf_chain)
+ *
+ * @param head the first netbuf
+ * @param tail netbuf to chain after head, freed by this function, may not be reference after returning
+ */
+void
+netbuf_chain(struct netbuf *head, struct netbuf *tail)
+{
+  LWIP_ERROR("netbuf_chain: invalid head", (head != NULL), return;);
+  LWIP_ERROR("netbuf_chain: invalid tail", (tail != NULL), return;);
+  pbuf_cat(head->p, tail->p);
+  head->ptr = head->p;
+  memp_free(MEMP_NETBUF, tail);
+}
+
+/**
+ * @ingroup netbuf
+ * Get the data pointer and length of the data inside a netbuf.
+ *
+ * @param buf netbuf to get the data from
+ * @param dataptr pointer to a void pointer where to store the data pointer
+ * @param len pointer to an u16_t where the length of the data is stored
+ * @return ERR_OK if the information was retrieved,
+ *         ERR_BUF on error.
+ */
+err_t
+netbuf_data(struct netbuf *buf, void **dataptr, u16_t *len)
+{
+  LWIP_ERROR("netbuf_data: invalid buf", (buf != NULL), return ERR_ARG;);
+  LWIP_ERROR("netbuf_data: invalid dataptr", (dataptr != NULL), return ERR_ARG;);
+  LWIP_ERROR("netbuf_data: invalid len", (len != NULL), return ERR_ARG;);
+
+  if (buf->ptr == NULL) {
+    return ERR_BUF;
+  }
+  *dataptr = buf->ptr->payload;
+  *len = buf->ptr->len;
+  return ERR_OK;
+}
+
+/**
+ * @ingroup netbuf
+ * Move the current data pointer of a packet buffer contained in a netbuf
+ * to the next part.
+ * The packet buffer itself is not modified.
+ *
+ * @param buf the netbuf to modify
+ * @return -1 if there is no next part
+ *         1  if moved to the next part but now there is no next part
+ *         0  if moved to the next part and there are still more parts
+ */
+s8_t
+netbuf_next(struct netbuf *buf)
+{
+  LWIP_ERROR("netbuf_next: invalid buf", (buf != NULL), return -1;);
+  if (buf->ptr->next == NULL) {
+    return -1;
+  }
+  buf->ptr = buf->ptr->next;
+  if (buf->ptr->next == NULL) {
+    return 1;
+  }
+  return 0;
+}
+
+/**
+ * @ingroup netbuf
+ * Move the current data pointer of a packet buffer contained in a netbuf
+ * to the beginning of the packet.
+ * The packet buffer itself is not modified.
+ *
+ * @param buf the netbuf to modify
+ */
+void
+netbuf_first(struct netbuf *buf)
+{
+  LWIP_ERROR("netbuf_first: invalid buf", (buf != NULL), return;);
+  buf->ptr = buf->p;
+}
+
+#endif /* LWIP_NETCONN */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/api/netdb.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/api/netdb.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/api/netdb.c	(revision 457)
@@ -0,0 +1,414 @@
+/**
+ * @file
+ * API functions for name resolving
+ *
+ * @defgroup netdbapi NETDB API
+ * @ingroup socket
+ */
+
+/*
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Simon Goldschmidt
+ *
+ */
+
+#include "lwip/netdb.h"
+
+#if LWIP_DNS && LWIP_SOCKET
+
+#include "lwip/err.h"
+#include "lwip/mem.h"
+#include "lwip/memp.h"
+#include "lwip/ip_addr.h"
+#include "lwip/api.h"
+#include "lwip/dns.h"
+
+#include <string.h> /* memset */
+#include <stdlib.h> /* atoi */
+
+/** helper struct for gethostbyname_r to access the char* buffer */
+struct gethostbyname_r_helper {
+  ip_addr_t *addr_list[2];
+  ip_addr_t addr;
+  char *aliases;
+};
+
+/** h_errno is exported in netdb.h for access by applications. */
+#if LWIP_DNS_API_DECLARE_H_ERRNO
+int h_errno;
+#endif /* LWIP_DNS_API_DECLARE_H_ERRNO */
+
+/** define "hostent" variables storage: 0 if we use a static (but unprotected)
+ * set of variables for lwip_gethostbyname, 1 if we use a local storage */
+#ifndef LWIP_DNS_API_HOSTENT_STORAGE
+#define LWIP_DNS_API_HOSTENT_STORAGE 0
+#endif
+
+/** define "hostent" variables storage */
+#if LWIP_DNS_API_HOSTENT_STORAGE
+#define HOSTENT_STORAGE
+#else
+#define HOSTENT_STORAGE static
+#endif /* LWIP_DNS_API_STATIC_HOSTENT */
+
+/**
+ * Returns an entry containing addresses of address family AF_INET
+ * for the host with name name.
+ * Due to dns_gethostbyname limitations, only one address is returned.
+ *
+ * @param name the hostname to resolve
+ * @return an entry containing addresses of address family AF_INET
+ *         for the host with name name
+ */
+struct hostent *
+lwip_gethostbyname(const char *name)
+{
+  err_t err;
+  ip_addr_t addr;
+
+  /* buffer variables for lwip_gethostbyname() */
+  HOSTENT_STORAGE struct hostent s_hostent;
+  HOSTENT_STORAGE char *s_aliases;
+  HOSTENT_STORAGE ip_addr_t s_hostent_addr;
+  HOSTENT_STORAGE ip_addr_t *s_phostent_addr[2];
+  HOSTENT_STORAGE char s_hostname[DNS_MAX_NAME_LENGTH + 1];
+
+  /* query host IP address */
+  err = netconn_gethostbyname(name, &addr);
+  if (err != ERR_OK) {
+    LWIP_DEBUGF(DNS_DEBUG, ("lwip_gethostbyname(%s) failed, err=%d\n", name, err));
+    h_errno = HOST_NOT_FOUND;
+    return NULL;
+  }
+
+  /* fill hostent */
+  s_hostent_addr = addr;
+  s_phostent_addr[0] = &s_hostent_addr;
+  s_phostent_addr[1] = NULL;
+  strncpy(s_hostname, name, DNS_MAX_NAME_LENGTH);
+  s_hostname[DNS_MAX_NAME_LENGTH] = 0;
+  s_hostent.h_name = s_hostname;
+  s_aliases = NULL;
+  s_hostent.h_aliases = &s_aliases;
+  s_hostent.h_addrtype = AF_INET;
+  s_hostent.h_length = sizeof(ip_addr_t);
+  s_hostent.h_addr_list = (char **)&s_phostent_addr;
+
+#if DNS_DEBUG
+  /* dump hostent */
+  LWIP_DEBUGF(DNS_DEBUG, ("hostent.h_name           == %s\n", s_hostent.h_name));
+  LWIP_DEBUGF(DNS_DEBUG, ("hostent.h_aliases        == %p\n", (void *)s_hostent.h_aliases));
+  /* h_aliases are always empty */
+  LWIP_DEBUGF(DNS_DEBUG, ("hostent.h_addrtype       == %d\n", s_hostent.h_addrtype));
+  LWIP_DEBUGF(DNS_DEBUG, ("hostent.h_length         == %d\n", s_hostent.h_length));
+  LWIP_DEBUGF(DNS_DEBUG, ("hostent.h_addr_list      == %p\n", (void *)s_hostent.h_addr_list));
+  if (s_hostent.h_addr_list != NULL) {
+    u8_t idx;
+    for (idx = 0; s_hostent.h_addr_list[idx]; idx++) {
+      LWIP_DEBUGF(DNS_DEBUG, ("hostent.h_addr_list[%i]   == %p\n", idx, s_hostent.h_addr_list[idx]));
+      LWIP_DEBUGF(DNS_DEBUG, ("hostent.h_addr_list[%i]-> == %s\n", idx, ipaddr_ntoa((ip_addr_t *)s_hostent.h_addr_list[idx])));
+    }
+  }
+#endif /* DNS_DEBUG */
+
+#if LWIP_DNS_API_HOSTENT_STORAGE
+  /* this function should return the "per-thread" hostent after copy from s_hostent */
+  return sys_thread_hostent(&s_hostent);
+#else
+  return &s_hostent;
+#endif /* LWIP_DNS_API_HOSTENT_STORAGE */
+}
+
+/**
+ * Thread-safe variant of lwip_gethostbyname: instead of using a static
+ * buffer, this function takes buffer and errno pointers as arguments
+ * and uses these for the result.
+ *
+ * @param name the hostname to resolve
+ * @param ret pre-allocated struct where to store the result
+ * @param buf pre-allocated buffer where to store additional data
+ * @param buflen the size of buf
+ * @param result pointer to a hostent pointer that is set to ret on success
+ *               and set to zero on error
+ * @param h_errnop pointer to an int where to store errors (instead of modifying
+ *                 the global h_errno)
+ * @return 0 on success, non-zero on error, additional error information
+ *         is stored in *h_errnop instead of h_errno to be thread-safe
+ */
+int
+lwip_gethostbyname_r(const char *name, struct hostent *ret, char *buf,
+                     size_t buflen, struct hostent **result, int *h_errnop)
+{
+  err_t err;
+  struct gethostbyname_r_helper *h;
+  char *hostname;
+  size_t namelen;
+  int lh_errno;
+
+  if (h_errnop == NULL) {
+    /* ensure h_errnop is never NULL */
+    h_errnop = &lh_errno;
+  }
+
+  if (result == NULL) {
+    /* not all arguments given */
+    *h_errnop = EINVAL;
+    return -1;
+  }
+  /* first thing to do: set *result to nothing */
+  *result = NULL;
+  if ((name == NULL) || (ret == NULL) || (buf == NULL)) {
+    /* not all arguments given */
+    *h_errnop = EINVAL;
+    return -1;
+  }
+
+  namelen = strlen(name);
+  if (buflen < (sizeof(struct gethostbyname_r_helper) + LWIP_MEM_ALIGN_BUFFER(namelen + 1))) {
+    /* buf can't hold the data needed + a copy of name */
+    *h_errnop = ERANGE;
+    return -1;
+  }
+
+  h = (struct gethostbyname_r_helper *)LWIP_MEM_ALIGN(buf);
+  hostname = ((char *)h) + sizeof(struct gethostbyname_r_helper);
+
+  /* query host IP address */
+  err = netconn_gethostbyname(name, &h->addr);
+  if (err != ERR_OK) {
+    LWIP_DEBUGF(DNS_DEBUG, ("lwip_gethostbyname(%s) failed, err=%d\n", name, err));
+    *h_errnop = HOST_NOT_FOUND;
+    return -1;
+  }
+
+  /* copy the hostname into buf */
+  MEMCPY(hostname, name, namelen);
+  hostname[namelen] = 0;
+
+  /* fill hostent */
+  h->addr_list[0] = &h->addr;
+  h->addr_list[1] = NULL;
+  h->aliases = NULL;
+  ret->h_name = hostname;
+  ret->h_aliases = &h->aliases;
+  ret->h_addrtype = AF_INET;
+  ret->h_length = sizeof(ip_addr_t);
+  ret->h_addr_list = (char **)&h->addr_list;
+
+  /* set result != NULL */
+  *result = ret;
+
+  /* return success */
+  return 0;
+}
+
+/**
+ * Frees one or more addrinfo structures returned by getaddrinfo(), along with
+ * any additional storage associated with those structures. If the ai_next field
+ * of the structure is not null, the entire list of structures is freed.
+ *
+ * @param ai struct addrinfo to free
+ */
+void
+lwip_freeaddrinfo(struct addrinfo *ai)
+{
+  struct addrinfo *next;
+
+  while (ai != NULL) {
+    next = ai->ai_next;
+    memp_free(MEMP_NETDB, ai);
+    ai = next;
+  }
+}
+
+/**
+ * Translates the name of a service location (for example, a host name) and/or
+ * a service name and returns a set of socket addresses and associated
+ * information to be used in creating a socket with which to address the
+ * specified service.
+ * Memory for the result is allocated internally and must be freed by calling
+ * lwip_freeaddrinfo()!
+ *
+ * Due to a limitation in dns_gethostbyname, only the first address of a
+ * host is returned.
+ * Also, service names are not supported (only port numbers)!
+ *
+ * @param nodename descriptive name or address string of the host
+ *                 (may be NULL -> local address)
+ * @param servname port number as string of NULL
+ * @param hints structure containing input values that set socktype and protocol
+ * @param res pointer to a pointer where to store the result (set to NULL on failure)
+ * @return 0 on success, non-zero on failure
+ *
+ * @todo: implement AI_V4MAPPED, AI_ADDRCONFIG
+ */
+int
+lwip_getaddrinfo(const char *nodename, const char *servname,
+                 const struct addrinfo *hints, struct addrinfo **res)
+{
+  err_t err;
+  ip_addr_t addr;
+  struct addrinfo *ai;
+  struct sockaddr_storage *sa = NULL;
+  int port_nr = 0;
+  size_t total_size;
+  size_t namelen = 0;
+  int ai_family;
+
+  if (res == NULL) {
+    return EAI_FAIL;
+  }
+  *res = NULL;
+  if ((nodename == NULL) && (servname == NULL)) {
+    return EAI_NONAME;
+  }
+
+  if (hints != NULL) {
+    ai_family = hints->ai_family;
+    if ((ai_family != AF_UNSPEC)
+#if LWIP_IPV4
+        && (ai_family != AF_INET)
+#endif /* LWIP_IPV4 */
+#if LWIP_IPV6
+        && (ai_family != AF_INET6)
+#endif /* LWIP_IPV6 */
+       ) {
+      return EAI_FAMILY;
+    }
+  } else {
+    ai_family = AF_UNSPEC;
+  }
+
+  if (servname != NULL) {
+    /* service name specified: convert to port number
+     * @todo?: currently, only ASCII integers (port numbers) are supported (AI_NUMERICSERV)! */
+    port_nr = atoi(servname);
+    if ((port_nr <= 0) || (port_nr > 0xffff)) {
+      return EAI_SERVICE;
+    }
+  }
+
+  if (nodename != NULL) {
+    /* service location specified, try to resolve */
+    if ((hints != NULL) && (hints->ai_flags & AI_NUMERICHOST)) {
+      /* no DNS lookup, just parse for an address string */
+      if (!ipaddr_aton(nodename, &addr)) {
+        return EAI_NONAME;
+      }
+#if LWIP_IPV4 && LWIP_IPV6
+      if ((IP_IS_V6_VAL(addr) && ai_family == AF_INET) ||
+          (IP_IS_V4_VAL(addr) && ai_family == AF_INET6)) {
+        return EAI_NONAME;
+      }
+#endif /* LWIP_IPV4 && LWIP_IPV6 */
+    } else {
+#if LWIP_IPV4 && LWIP_IPV6
+      /* AF_UNSPEC: prefer IPv4 */
+      u8_t type = NETCONN_DNS_IPV4_IPV6;
+      if (ai_family == AF_INET) {
+        type = NETCONN_DNS_IPV4;
+      } else if (ai_family == AF_INET6) {
+        type = NETCONN_DNS_IPV6;
+      }
+#endif /* LWIP_IPV4 && LWIP_IPV6 */
+      err = netconn_gethostbyname_addrtype(nodename, &addr, type);
+      if (err != ERR_OK) {
+        return EAI_FAIL;
+      }
+    }
+  } else {
+    /* service location specified, use loopback address */
+    if ((hints != NULL) && (hints->ai_flags & AI_PASSIVE)) {
+      ip_addr_set_any_val(ai_family == AF_INET6, addr);
+    } else {
+      ip_addr_set_loopback_val(ai_family == AF_INET6, addr);
+    }
+  }
+
+  total_size = sizeof(struct addrinfo) + sizeof(struct sockaddr_storage);
+  if (nodename != NULL) {
+    namelen = strlen(nodename);
+    if (namelen > DNS_MAX_NAME_LENGTH) {
+      /* invalid name length */
+      return EAI_FAIL;
+    }
+    LWIP_ASSERT("namelen is too long", total_size + namelen + 1 > total_size);
+    total_size += namelen + 1;
+  }
+  /* If this fails, please report to lwip-devel! :-) */
+  LWIP_ASSERT("total_size <= NETDB_ELEM_SIZE: please report this!",
+              total_size <= NETDB_ELEM_SIZE);
+  ai = (struct addrinfo *)memp_malloc(MEMP_NETDB);
+  if (ai == NULL) {
+    return EAI_MEMORY;
+  }
+  memset(ai, 0, total_size);
+  /* cast through void* to get rid of alignment warnings */
+  sa = (struct sockaddr_storage *)(void *)((u8_t *)ai + sizeof(struct addrinfo));
+  if (IP_IS_V6_VAL(addr)) {
+#if LWIP_IPV6
+    struct sockaddr_in6 *sa6 = (struct sockaddr_in6 *)sa;
+    /* set up sockaddr */
+    inet6_addr_from_ip6addr(&sa6->sin6_addr, ip_2_ip6(&addr));
+    sa6->sin6_family = AF_INET6;
+    sa6->sin6_len = sizeof(struct sockaddr_in6);
+    sa6->sin6_port = lwip_htons((u16_t)port_nr);
+    sa6->sin6_scope_id = ip6_addr_zone(ip_2_ip6(&addr));
+    ai->ai_family = AF_INET6;
+#endif /* LWIP_IPV6 */
+  } else {
+#if LWIP_IPV4
+    struct sockaddr_in *sa4 = (struct sockaddr_in *)sa;
+    /* set up sockaddr */
+    inet_addr_from_ip4addr(&sa4->sin_addr, ip_2_ip4(&addr));
+    sa4->sin_family = AF_INET;
+    sa4->sin_len = sizeof(struct sockaddr_in);
+    sa4->sin_port = lwip_htons((u16_t)port_nr);
+    ai->ai_family = AF_INET;
+#endif /* LWIP_IPV4 */
+  }
+
+  /* set up addrinfo */
+  if (hints != NULL) {
+    /* copy socktype & protocol from hints if specified */
+    ai->ai_socktype = hints->ai_socktype;
+    ai->ai_protocol = hints->ai_protocol;
+  }
+  if (nodename != NULL) {
+    /* copy nodename to canonname if specified */
+    ai->ai_canonname = ((char *)ai + sizeof(struct addrinfo) + sizeof(struct sockaddr_storage));
+    MEMCPY(ai->ai_canonname, nodename, namelen);
+    ai->ai_canonname[namelen] = 0;
+  }
+  ai->ai_addrlen = sizeof(struct sockaddr_storage);
+  ai->ai_addr = (struct sockaddr *)sa;
+
+  *res = ai;
+
+  return 0;
+}
+
+#endif /* LWIP_DNS && LWIP_SOCKET */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/api/netifapi.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/api/netifapi.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/api/netifapi.c	(revision 457)
@@ -0,0 +1,380 @@
+/**
+ * @file
+ * Network Interface Sequential API module
+ *
+ * @defgroup netifapi NETIF API
+ * @ingroup sequential_api
+ * Thread-safe functions to be called from non-TCPIP threads
+ *
+ * @defgroup netifapi_netif NETIF related
+ * @ingroup netifapi
+ * To be called from non-TCPIP threads
+ */
+
+/*
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ */
+
+#include "lwip/opt.h"
+
+#if LWIP_NETIF_API /* don't build if not configured for use in lwipopts.h */
+
+#include "lwip/etharp.h"
+#include "lwip/netifapi.h"
+#include "lwip/memp.h"
+#include "lwip/priv/tcpip_priv.h"
+
+#include <string.h> /* strncpy */
+
+#define NETIFAPI_VAR_REF(name)      API_VAR_REF(name)
+#define NETIFAPI_VAR_DECLARE(name)  API_VAR_DECLARE(struct netifapi_msg, name)
+#define NETIFAPI_VAR_ALLOC(name)    API_VAR_ALLOC(struct netifapi_msg, MEMP_NETIFAPI_MSG, name, ERR_MEM)
+#define NETIFAPI_VAR_FREE(name)     API_VAR_FREE(MEMP_NETIFAPI_MSG, name)
+
+/**
+ * Call netif_add() inside the tcpip_thread context.
+ */
+static err_t
+netifapi_do_netif_add(struct tcpip_api_call_data *m)
+{
+  /* cast through void* to silence alignment warnings.
+   * We know it works because the structs have been instantiated as struct netifapi_msg */
+  struct netifapi_msg *msg = (struct netifapi_msg *)(void *)m;
+
+  if (!netif_add( msg->netif,
+#if LWIP_IPV4
+                  API_EXPR_REF(msg->msg.add.ipaddr),
+                  API_EXPR_REF(msg->msg.add.netmask),
+                  API_EXPR_REF(msg->msg.add.gw),
+#endif /* LWIP_IPV4 */
+                  msg->msg.add.state,
+                  msg->msg.add.init,
+                  msg->msg.add.input)) {
+    return ERR_IF;
+  } else {
+    return ERR_OK;
+  }
+}
+
+#if LWIP_IPV4
+/**
+ * Call netif_set_addr() inside the tcpip_thread context.
+ */
+static err_t
+netifapi_do_netif_set_addr(struct tcpip_api_call_data *m)
+{
+  /* cast through void* to silence alignment warnings.
+   * We know it works because the structs have been instantiated as struct netifapi_msg */
+  struct netifapi_msg *msg = (struct netifapi_msg *)(void *)m;
+
+  netif_set_addr( msg->netif,
+                  API_EXPR_REF(msg->msg.add.ipaddr),
+                  API_EXPR_REF(msg->msg.add.netmask),
+                  API_EXPR_REF(msg->msg.add.gw));
+  return ERR_OK;
+}
+#endif /* LWIP_IPV4 */
+
+/**
+* Call netif_name_to_index() inside the tcpip_thread context.
+*/
+static err_t
+netifapi_do_name_to_index(struct tcpip_api_call_data *m)
+{
+  /* cast through void* to silence alignment warnings.
+   * We know it works because the structs have been instantiated as struct netifapi_msg */
+  struct netifapi_msg *msg = (struct netifapi_msg *)(void *)m;
+
+  msg->msg.ifs.index = netif_name_to_index(msg->msg.ifs.name);
+  return ERR_OK;
+}
+
+/**
+* Call netif_index_to_name() inside the tcpip_thread context.
+*/
+static err_t
+netifapi_do_index_to_name(struct tcpip_api_call_data *m)
+{
+  /* cast through void* to silence alignment warnings.
+   * We know it works because the structs have been instantiated as struct netifapi_msg */
+  struct netifapi_msg *msg = (struct netifapi_msg *)(void *)m;
+
+  if (!netif_index_to_name(msg->msg.ifs.index, msg->msg.ifs.name)) {
+    /* return failure via empty name */
+    msg->msg.ifs.name[0] = '\0';
+  }
+  return ERR_OK;
+}
+
+/**
+ * Call the "errtfunc" (or the "voidfunc" if "errtfunc" is NULL) inside the
+ * tcpip_thread context.
+ */
+static err_t
+netifapi_do_netif_common(struct tcpip_api_call_data *m)
+{
+  /* cast through void* to silence alignment warnings.
+   * We know it works because the structs have been instantiated as struct netifapi_msg */
+  struct netifapi_msg *msg = (struct netifapi_msg *)(void *)m;
+
+  if (msg->msg.common.errtfunc != NULL) {
+    return msg->msg.common.errtfunc(msg->netif);
+  } else {
+    msg->msg.common.voidfunc(msg->netif);
+    return ERR_OK;
+  }
+}
+
+#if LWIP_ARP && LWIP_IPV4
+/**
+ * @ingroup netifapi_arp
+ * Add or update an entry in the ARP cache.
+ * For an update, ipaddr is used to find the cache entry.
+ *
+ * @param ipaddr IPv4 address of cache entry
+ * @param ethaddr hardware address mapped to ipaddr
+ * @param type type of ARP cache entry
+ * @return ERR_OK: entry added/updated, else error from err_t
+ */
+err_t
+netifapi_arp_add(const ip4_addr_t *ipaddr, struct eth_addr *ethaddr, enum netifapi_arp_entry type)
+{
+  err_t err;
+
+  /* We only support permanent entries currently */
+  LWIP_UNUSED_ARG(type);
+
+#if ETHARP_SUPPORT_STATIC_ENTRIES && LWIP_TCPIP_CORE_LOCKING
+  LOCK_TCPIP_CORE();
+  err = etharp_add_static_entry(ipaddr, ethaddr);
+  UNLOCK_TCPIP_CORE();
+#else
+  /* @todo add new vars to struct netifapi_msg and create a 'do' func */
+  LWIP_UNUSED_ARG(ipaddr);
+  LWIP_UNUSED_ARG(ethaddr);
+  err = ERR_VAL;
+#endif /* ETHARP_SUPPORT_STATIC_ENTRIES && LWIP_TCPIP_CORE_LOCKING */
+
+  return err;
+}
+
+/**
+ * @ingroup netifapi_arp
+ * Remove an entry in the ARP cache identified by ipaddr
+ *
+ * @param ipaddr IPv4 address of cache entry
+ * @param type type of ARP cache entry
+ * @return ERR_OK: entry removed, else error from err_t
+ */
+err_t
+netifapi_arp_remove(const ip4_addr_t *ipaddr, enum netifapi_arp_entry type)
+{
+  err_t err;
+
+  /* We only support permanent entries currently */
+  LWIP_UNUSED_ARG(type);
+
+#if ETHARP_SUPPORT_STATIC_ENTRIES && LWIP_TCPIP_CORE_LOCKING
+  LOCK_TCPIP_CORE();
+  err = etharp_remove_static_entry(ipaddr);
+  UNLOCK_TCPIP_CORE();
+#else
+  /* @todo add new vars to struct netifapi_msg and create a 'do' func */
+  LWIP_UNUSED_ARG(ipaddr);
+  err = ERR_VAL;
+#endif /* ETHARP_SUPPORT_STATIC_ENTRIES && LWIP_TCPIP_CORE_LOCKING */
+
+  return err;
+}
+#endif /* LWIP_ARP && LWIP_IPV4 */
+
+/**
+ * @ingroup netifapi_netif
+ * Call netif_add() in a thread-safe way by running that function inside the
+ * tcpip_thread context.
+ *
+ * @note for params @see netif_add()
+ */
+err_t
+netifapi_netif_add(struct netif *netif,
+#if LWIP_IPV4
+                   const ip4_addr_t *ipaddr, const ip4_addr_t *netmask, const ip4_addr_t *gw,
+#endif /* LWIP_IPV4 */
+                   void *state, netif_init_fn init, netif_input_fn input)
+{
+  err_t err;
+  NETIFAPI_VAR_DECLARE(msg);
+  NETIFAPI_VAR_ALLOC(msg);
+
+#if LWIP_IPV4
+  if (ipaddr == NULL) {
+    ipaddr = IP4_ADDR_ANY4;
+  }
+  if (netmask == NULL) {
+    netmask = IP4_ADDR_ANY4;
+  }
+  if (gw == NULL) {
+    gw = IP4_ADDR_ANY4;
+  }
+#endif /* LWIP_IPV4 */
+
+  NETIFAPI_VAR_REF(msg).netif = netif;
+#if LWIP_IPV4
+  NETIFAPI_VAR_REF(msg).msg.add.ipaddr  = NETIFAPI_VAR_REF(ipaddr);
+  NETIFAPI_VAR_REF(msg).msg.add.netmask = NETIFAPI_VAR_REF(netmask);
+  NETIFAPI_VAR_REF(msg).msg.add.gw      = NETIFAPI_VAR_REF(gw);
+#endif /* LWIP_IPV4 */
+  NETIFAPI_VAR_REF(msg).msg.add.state   = state;
+  NETIFAPI_VAR_REF(msg).msg.add.init    = init;
+  NETIFAPI_VAR_REF(msg).msg.add.input   = input;
+  err = tcpip_api_call(netifapi_do_netif_add, &API_VAR_REF(msg).call);
+  NETIFAPI_VAR_FREE(msg);
+  return err;
+}
+
+#if LWIP_IPV4
+/**
+ * @ingroup netifapi_netif
+ * Call netif_set_addr() in a thread-safe way by running that function inside the
+ * tcpip_thread context.
+ *
+ * @note for params @see netif_set_addr()
+ */
+err_t
+netifapi_netif_set_addr(struct netif *netif,
+                        const ip4_addr_t *ipaddr,
+                        const ip4_addr_t *netmask,
+                        const ip4_addr_t *gw)
+{
+  err_t err;
+  NETIFAPI_VAR_DECLARE(msg);
+  NETIFAPI_VAR_ALLOC(msg);
+
+  if (ipaddr == NULL) {
+    ipaddr = IP4_ADDR_ANY4;
+  }
+  if (netmask == NULL) {
+    netmask = IP4_ADDR_ANY4;
+  }
+  if (gw == NULL) {
+    gw = IP4_ADDR_ANY4;
+  }
+
+  NETIFAPI_VAR_REF(msg).netif = netif;
+  NETIFAPI_VAR_REF(msg).msg.add.ipaddr  = NETIFAPI_VAR_REF(ipaddr);
+  NETIFAPI_VAR_REF(msg).msg.add.netmask = NETIFAPI_VAR_REF(netmask);
+  NETIFAPI_VAR_REF(msg).msg.add.gw      = NETIFAPI_VAR_REF(gw);
+  err = tcpip_api_call(netifapi_do_netif_set_addr, &API_VAR_REF(msg).call);
+  NETIFAPI_VAR_FREE(msg);
+  return err;
+}
+#endif /* LWIP_IPV4 */
+
+/**
+ * call the "errtfunc" (or the "voidfunc" if "errtfunc" is NULL) in a thread-safe
+ * way by running that function inside the tcpip_thread context.
+ *
+ * @note use only for functions where there is only "netif" parameter.
+ */
+err_t
+netifapi_netif_common(struct netif *netif, netifapi_void_fn voidfunc,
+                      netifapi_errt_fn errtfunc)
+{
+  err_t err;
+  NETIFAPI_VAR_DECLARE(msg);
+  NETIFAPI_VAR_ALLOC(msg);
+
+  NETIFAPI_VAR_REF(msg).netif = netif;
+  NETIFAPI_VAR_REF(msg).msg.common.voidfunc = voidfunc;
+  NETIFAPI_VAR_REF(msg).msg.common.errtfunc = errtfunc;
+  err = tcpip_api_call(netifapi_do_netif_common, &API_VAR_REF(msg).call);
+  NETIFAPI_VAR_FREE(msg);
+  return err;
+}
+
+/**
+* @ingroup netifapi_netif
+* Call netif_name_to_index() in a thread-safe way by running that function inside the
+* tcpip_thread context.
+*
+* @param name the interface name of the netif
+* @param idx output index of the found netif
+*/
+err_t
+netifapi_netif_name_to_index(const char *name, u8_t *idx)
+{
+  err_t err;
+  NETIFAPI_VAR_DECLARE(msg);
+  NETIFAPI_VAR_ALLOC(msg);
+
+  *idx = 0;
+
+#if LWIP_MPU_COMPATIBLE
+  strncpy(NETIFAPI_VAR_REF(msg).msg.ifs.name, name, NETIF_NAMESIZE - 1);
+  NETIFAPI_VAR_REF(msg).msg.ifs.name[NETIF_NAMESIZE - 1] = '\0';
+#else
+  NETIFAPI_VAR_REF(msg).msg.ifs.name = LWIP_CONST_CAST(char *, name);
+#endif /* LWIP_MPU_COMPATIBLE */
+  err = tcpip_api_call(netifapi_do_name_to_index, &API_VAR_REF(msg).call);
+  if (!err) {
+    *idx = NETIFAPI_VAR_REF(msg).msg.ifs.index;
+  }
+  NETIFAPI_VAR_FREE(msg);
+  return err;
+}
+
+/**
+* @ingroup netifapi_netif
+* Call netif_index_to_name() in a thread-safe way by running that function inside the
+* tcpip_thread context.
+*
+* @param idx the interface index of the netif
+* @param name output name of the found netif, empty '\0' string if netif not found.
+*             name should be of at least NETIF_NAMESIZE bytes
+*/
+err_t
+netifapi_netif_index_to_name(u8_t idx, char *name)
+{
+  err_t err;
+  NETIFAPI_VAR_DECLARE(msg);
+  NETIFAPI_VAR_ALLOC(msg);
+
+  NETIFAPI_VAR_REF(msg).msg.ifs.index = idx;
+#if !LWIP_MPU_COMPATIBLE
+  NETIFAPI_VAR_REF(msg).msg.ifs.name = name;
+#endif /* LWIP_MPU_COMPATIBLE */
+  err = tcpip_api_call(netifapi_do_index_to_name, &API_VAR_REF(msg).call);
+#if LWIP_MPU_COMPATIBLE
+  if (!err) {
+    strncpy(name, NETIFAPI_VAR_REF(msg).msg.ifs.name, NETIF_NAMESIZE - 1);
+    name[NETIF_NAMESIZE - 1] = '\0';
+  }
+#endif /* LWIP_MPU_COMPATIBLE */
+  NETIFAPI_VAR_FREE(msg);
+  return err;
+}
+
+#endif /* LWIP_NETIF_API */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/api/sockets.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/api/sockets.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/api/sockets.c	(revision 457)
@@ -0,0 +1,4160 @@
+/**
+ * @file
+ * Sockets BSD-Like API module
+ */
+
+/*
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Adam Dunkels <adam@sics.se>
+ *
+ * Improved by Marc Boucher <marc@mbsi.ca> and David Haas <dhaas@alum.rpi.edu>
+ *
+ */
+
+#include "lwip/opt.h"
+
+#if LWIP_SOCKET /* don't build if not configured for use in lwipopts.h */
+
+#include "lwip/sockets.h"
+#include "lwip/priv/sockets_priv.h"
+#include "lwip/api.h"
+#include "lwip/igmp.h"
+#include "lwip/inet.h"
+#include "lwip/tcp.h"
+#include "lwip/raw.h"
+#include "lwip/udp.h"
+#include "lwip/memp.h"
+#include "lwip/pbuf.h"
+#include "lwip/netif.h"
+#include "lwip/priv/tcpip_priv.h"
+#include "lwip/mld6.h"
+#if LWIP_CHECKSUM_ON_COPY
+#include "lwip/inet_chksum.h"
+#endif
+
+#if LWIP_COMPAT_SOCKETS == 2 && LWIP_POSIX_SOCKETS_IO_NAMES
+#include <stdarg.h>
+#endif
+
+#include <string.h>
+
+#ifdef LWIP_HOOK_FILENAME
+#include LWIP_HOOK_FILENAME
+#endif
+
+/* If the netconn API is not required publicly, then we include the necessary
+   files here to get the implementation */
+#if !LWIP_NETCONN
+#undef LWIP_NETCONN
+#define LWIP_NETCONN 1
+#include "api_msg.c"
+#include "api_lib.c"
+#include "netbuf.c"
+#undef LWIP_NETCONN
+#define LWIP_NETCONN 0
+#endif
+
+#define API_SELECT_CB_VAR_REF(name)               API_VAR_REF(name)
+#define API_SELECT_CB_VAR_DECLARE(name)           API_VAR_DECLARE(struct lwip_select_cb, name)
+#define API_SELECT_CB_VAR_ALLOC(name, retblock)   API_VAR_ALLOC_EXT(struct lwip_select_cb, MEMP_SELECT_CB, name, retblock)
+#define API_SELECT_CB_VAR_FREE(name)              API_VAR_FREE(MEMP_SELECT_CB, name)
+
+#if LWIP_IPV4
+#define IP4ADDR_PORT_TO_SOCKADDR(sin, ipaddr, port) do { \
+      (sin)->sin_len = sizeof(struct sockaddr_in); \
+      (sin)->sin_family = AF_INET; \
+      (sin)->sin_port = lwip_htons((port)); \
+      inet_addr_from_ip4addr(&(sin)->sin_addr, ipaddr); \
+      memset((sin)->sin_zero, 0, SIN_ZERO_LEN); }while(0)
+#define SOCKADDR4_TO_IP4ADDR_PORT(sin, ipaddr, port) do { \
+    inet_addr_to_ip4addr(ip_2_ip4(ipaddr), &((sin)->sin_addr)); \
+    (port) = lwip_ntohs((sin)->sin_port); }while(0)
+#endif /* LWIP_IPV4 */
+
+#if LWIP_IPV6
+#define IP6ADDR_PORT_TO_SOCKADDR(sin6, ipaddr, port) do { \
+      (sin6)->sin6_len = sizeof(struct sockaddr_in6); \
+      (sin6)->sin6_family = AF_INET6; \
+      (sin6)->sin6_port = lwip_htons((port)); \
+      (sin6)->sin6_flowinfo = 0; \
+      inet6_addr_from_ip6addr(&(sin6)->sin6_addr, ipaddr); \
+      (sin6)->sin6_scope_id = ip6_addr_zone(ipaddr); }while(0)
+#define SOCKADDR6_TO_IP6ADDR_PORT(sin6, ipaddr, port) do { \
+    inet6_addr_to_ip6addr(ip_2_ip6(ipaddr), &((sin6)->sin6_addr)); \
+    if (ip6_addr_has_scope(ip_2_ip6(ipaddr), IP6_UNKNOWN)) { \
+      ip6_addr_set_zone(ip_2_ip6(ipaddr), (u8_t)((sin6)->sin6_scope_id)); \
+    } \
+    (port) = lwip_ntohs((sin6)->sin6_port); }while(0)
+#endif /* LWIP_IPV6 */
+
+#if LWIP_IPV4 && LWIP_IPV6
+static void sockaddr_to_ipaddr_port(const struct sockaddr *sockaddr, ip_addr_t *ipaddr, u16_t *port);
+
+#define IS_SOCK_ADDR_LEN_VALID(namelen)  (((namelen) == sizeof(struct sockaddr_in)) || \
+                                         ((namelen) == sizeof(struct sockaddr_in6)))
+#define IS_SOCK_ADDR_TYPE_VALID(name)    (((name)->sa_family == AF_INET) || \
+                                         ((name)->sa_family == AF_INET6))
+#define SOCK_ADDR_TYPE_MATCH(name, sock) \
+       ((((name)->sa_family == AF_INET) && !(NETCONNTYPE_ISIPV6((sock)->conn->type))) || \
+       (((name)->sa_family == AF_INET6) && (NETCONNTYPE_ISIPV6((sock)->conn->type))))
+#define IPADDR_PORT_TO_SOCKADDR(sockaddr, ipaddr, port) do { \
+    if (IP_IS_ANY_TYPE_VAL(*ipaddr) || IP_IS_V6_VAL(*ipaddr)) { \
+      IP6ADDR_PORT_TO_SOCKADDR((struct sockaddr_in6*)(void*)(sockaddr), ip_2_ip6(ipaddr), port); \
+    } else { \
+      IP4ADDR_PORT_TO_SOCKADDR((struct sockaddr_in*)(void*)(sockaddr), ip_2_ip4(ipaddr), port); \
+    } } while(0)
+#define SOCKADDR_TO_IPADDR_PORT(sockaddr, ipaddr, port) sockaddr_to_ipaddr_port(sockaddr, ipaddr, &(port))
+#define DOMAIN_TO_NETCONN_TYPE(domain, type) (((domain) == AF_INET) ? \
+  (type) : (enum netconn_type)((type) | NETCONN_TYPE_IPV6))
+#elif LWIP_IPV6 /* LWIP_IPV4 && LWIP_IPV6 */
+#define IS_SOCK_ADDR_LEN_VALID(namelen)  ((namelen) == sizeof(struct sockaddr_in6))
+#define IS_SOCK_ADDR_TYPE_VALID(name)    ((name)->sa_family == AF_INET6)
+#define SOCK_ADDR_TYPE_MATCH(name, sock) 1
+#define IPADDR_PORT_TO_SOCKADDR(sockaddr, ipaddr, port) \
+        IP6ADDR_PORT_TO_SOCKADDR((struct sockaddr_in6*)(void*)(sockaddr), ip_2_ip6(ipaddr), port)
+#define SOCKADDR_TO_IPADDR_PORT(sockaddr, ipaddr, port) \
+        SOCKADDR6_TO_IP6ADDR_PORT((const struct sockaddr_in6*)(const void*)(sockaddr), ipaddr, port)
+#define DOMAIN_TO_NETCONN_TYPE(domain, netconn_type) (netconn_type)
+#else /*-> LWIP_IPV4: LWIP_IPV4 && LWIP_IPV6 */
+#define IS_SOCK_ADDR_LEN_VALID(namelen)  ((namelen) == sizeof(struct sockaddr_in))
+#define IS_SOCK_ADDR_TYPE_VALID(name)    ((name)->sa_family == AF_INET)
+#define SOCK_ADDR_TYPE_MATCH(name, sock) 1
+#define IPADDR_PORT_TO_SOCKADDR(sockaddr, ipaddr, port) \
+        IP4ADDR_PORT_TO_SOCKADDR((struct sockaddr_in*)(void*)(sockaddr), ip_2_ip4(ipaddr), port)
+#define SOCKADDR_TO_IPADDR_PORT(sockaddr, ipaddr, port) \
+        SOCKADDR4_TO_IP4ADDR_PORT((const struct sockaddr_in*)(const void*)(sockaddr), ipaddr, port)
+#define DOMAIN_TO_NETCONN_TYPE(domain, netconn_type) (netconn_type)
+#endif /* LWIP_IPV6 */
+
+#define IS_SOCK_ADDR_TYPE_VALID_OR_UNSPEC(name)    (((name)->sa_family == AF_UNSPEC) || \
+                                                    IS_SOCK_ADDR_TYPE_VALID(name))
+#define SOCK_ADDR_TYPE_MATCH_OR_UNSPEC(name, sock) (((name)->sa_family == AF_UNSPEC) || \
+                                                    SOCK_ADDR_TYPE_MATCH(name, sock))
+#define IS_SOCK_ADDR_ALIGNED(name)      ((((mem_ptr_t)(name)) % 4) == 0)
+
+
+#define LWIP_SOCKOPT_CHECK_OPTLEN(sock, optlen, opttype) do { if ((optlen) < sizeof(opttype)) { done_socket(sock); return EINVAL; }}while(0)
+#define LWIP_SOCKOPT_CHECK_OPTLEN_CONN(sock, optlen, opttype) do { \
+  LWIP_SOCKOPT_CHECK_OPTLEN(sock, optlen, opttype); \
+  if ((sock)->conn == NULL) { done_socket(sock); return EINVAL; } }while(0)
+#define LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB(sock, optlen, opttype) do { \
+  LWIP_SOCKOPT_CHECK_OPTLEN(sock, optlen, opttype); \
+  if (((sock)->conn == NULL) || ((sock)->conn->pcb.tcp == NULL)) { done_socket(sock); return EINVAL; } }while(0)
+#define LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB_TYPE(sock, optlen, opttype, netconntype) do { \
+  LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB(sock, optlen, opttype); \
+  if (NETCONNTYPE_GROUP(netconn_type((sock)->conn)) != netconntype) { done_socket(sock); return ENOPROTOOPT; } }while(0)
+
+
+#define LWIP_SETGETSOCKOPT_DATA_VAR_REF(name)     API_VAR_REF(name)
+#define LWIP_SETGETSOCKOPT_DATA_VAR_DECLARE(name) API_VAR_DECLARE(struct lwip_setgetsockopt_data, name)
+#define LWIP_SETGETSOCKOPT_DATA_VAR_FREE(name)    API_VAR_FREE(MEMP_SOCKET_SETGETSOCKOPT_DATA, name)
+#if LWIP_MPU_COMPATIBLE
+#define LWIP_SETGETSOCKOPT_DATA_VAR_ALLOC(name, sock) do { \
+  name = (struct lwip_setgetsockopt_data *)memp_malloc(MEMP_SOCKET_SETGETSOCKOPT_DATA); \
+  if (name == NULL) { \
+    sock_set_errno(sock, ENOMEM); \
+    done_socket(sock); \
+    return -1; \
+  } }while(0)
+#else /* LWIP_MPU_COMPATIBLE */
+#define LWIP_SETGETSOCKOPT_DATA_VAR_ALLOC(name, sock)
+#endif /* LWIP_MPU_COMPATIBLE */
+
+#if LWIP_SO_SNDRCVTIMEO_NONSTANDARD
+#define LWIP_SO_SNDRCVTIMEO_OPTTYPE int
+#define LWIP_SO_SNDRCVTIMEO_SET(optval, val) (*(int *)(optval) = (val))
+#define LWIP_SO_SNDRCVTIMEO_GET_MS(optval)   ((long)*(const int*)(optval))
+#else
+#define LWIP_SO_SNDRCVTIMEO_OPTTYPE struct timeval
+#define LWIP_SO_SNDRCVTIMEO_SET(optval, val)  do { \
+  u32_t loc = (val); \
+  ((struct timeval *)(optval))->tv_sec = (long)((loc) / 1000U); \
+  ((struct timeval *)(optval))->tv_usec = (long)(((loc) % 1000U) * 1000U); }while(0)
+#define LWIP_SO_SNDRCVTIMEO_GET_MS(optval) ((((const struct timeval *)(optval))->tv_sec * 1000) + (((const struct timeval *)(optval))->tv_usec / 1000))
+#endif
+
+
+/** A struct sockaddr replacement that has the same alignment as sockaddr_in/
+ *  sockaddr_in6 if instantiated.
+ */
+union sockaddr_aligned {
+  struct sockaddr sa;
+#if LWIP_IPV6
+  struct sockaddr_in6 sin6;
+#endif /* LWIP_IPV6 */
+#if LWIP_IPV4
+  struct sockaddr_in sin;
+#endif /* LWIP_IPV4 */
+};
+
+/* Define the number of IPv4 multicast memberships, default is one per socket */
+#ifndef LWIP_SOCKET_MAX_MEMBERSHIPS
+#define LWIP_SOCKET_MAX_MEMBERSHIPS NUM_SOCKETS
+#endif
+
+#if LWIP_IGMP
+/* This is to keep track of IP_ADD_MEMBERSHIP calls to drop the membership when
+   a socket is closed */
+struct lwip_socket_multicast_pair {
+  /** the socket */
+  struct lwip_sock *sock;
+  /** the interface address */
+  ip4_addr_t if_addr;
+  /** the group address */
+  ip4_addr_t multi_addr;
+};
+
+static struct lwip_socket_multicast_pair socket_ipv4_multicast_memberships[LWIP_SOCKET_MAX_MEMBERSHIPS];
+
+static int  lwip_socket_register_membership(int s, const ip4_addr_t *if_addr, const ip4_addr_t *multi_addr);
+static void lwip_socket_unregister_membership(int s, const ip4_addr_t *if_addr, const ip4_addr_t *multi_addr);
+static void lwip_socket_drop_registered_memberships(int s);
+#endif /* LWIP_IGMP */
+
+#if LWIP_IPV6_MLD
+/* This is to keep track of IP_JOIN_GROUP calls to drop the membership when
+   a socket is closed */
+struct lwip_socket_multicast_mld6_pair {
+  /** the socket */
+  struct lwip_sock *sock;
+  /** the interface index */
+  u8_t if_idx;
+  /** the group address */
+  ip6_addr_t multi_addr;
+};
+
+static struct lwip_socket_multicast_mld6_pair socket_ipv6_multicast_memberships[LWIP_SOCKET_MAX_MEMBERSHIPS];
+
+static int  lwip_socket_register_mld6_membership(int s, unsigned int if_idx, const ip6_addr_t *multi_addr);
+static void lwip_socket_unregister_mld6_membership(int s, unsigned int if_idx, const ip6_addr_t *multi_addr);
+static void lwip_socket_drop_registered_mld6_memberships(int s);
+#endif /* LWIP_IPV6_MLD */
+
+/** The global array of available sockets */
+static struct lwip_sock sockets[NUM_SOCKETS];
+
+#if LWIP_SOCKET_SELECT || LWIP_SOCKET_POLL
+#if LWIP_TCPIP_CORE_LOCKING
+/* protect the select_cb_list using core lock */
+#define LWIP_SOCKET_SELECT_DECL_PROTECT(lev)
+#define LWIP_SOCKET_SELECT_PROTECT(lev)   LOCK_TCPIP_CORE()
+#define LWIP_SOCKET_SELECT_UNPROTECT(lev) UNLOCK_TCPIP_CORE()
+#else /* LWIP_TCPIP_CORE_LOCKING */
+/* protect the select_cb_list using SYS_LIGHTWEIGHT_PROT */
+#define LWIP_SOCKET_SELECT_DECL_PROTECT(lev)  SYS_ARCH_DECL_PROTECT(lev)
+#define LWIP_SOCKET_SELECT_PROTECT(lev)       SYS_ARCH_PROTECT(lev)
+#define LWIP_SOCKET_SELECT_UNPROTECT(lev)     SYS_ARCH_UNPROTECT(lev)
+/** This counter is increased from lwip_select when the list is changed
+    and checked in select_check_waiters to see if it has changed. */
+static volatile int select_cb_ctr;
+#endif /* LWIP_TCPIP_CORE_LOCKING */
+/** The global list of tasks waiting for select */
+static struct lwip_select_cb *select_cb_list;
+#endif /* LWIP_SOCKET_SELECT || LWIP_SOCKET_POLL */
+
+#define sock_set_errno(sk, e) do { \
+  const int sockerr = (e); \
+  set_errno(sockerr); \
+} while (0)
+
+/* Forward declaration of some functions */
+#if LWIP_SOCKET_SELECT || LWIP_SOCKET_POLL
+static void event_callback(struct netconn *conn, enum netconn_evt evt, u16_t len);
+#define DEFAULT_SOCKET_EVENTCB event_callback
+static void select_check_waiters(int s, int has_recvevent, int has_sendevent, int has_errevent);
+#else
+#define DEFAULT_SOCKET_EVENTCB NULL
+#endif
+#if !LWIP_TCPIP_CORE_LOCKING
+static void lwip_getsockopt_callback(void *arg);
+static void lwip_setsockopt_callback(void *arg);
+#endif
+static int lwip_getsockopt_impl(int s, int level, int optname, void *optval, socklen_t *optlen);
+static int lwip_setsockopt_impl(int s, int level, int optname, const void *optval, socklen_t optlen);
+static int free_socket_locked(struct lwip_sock *sock, int is_tcp, struct netconn **conn,
+                              union lwip_sock_lastdata *lastdata);
+static void free_socket_free_elements(int is_tcp, struct netconn *conn, union lwip_sock_lastdata *lastdata);
+
+#if LWIP_IPV4 && LWIP_IPV6
+static void
+sockaddr_to_ipaddr_port(const struct sockaddr *sockaddr, ip_addr_t *ipaddr, u16_t *port)
+{
+  if ((sockaddr->sa_family) == AF_INET6) {
+    SOCKADDR6_TO_IP6ADDR_PORT((const struct sockaddr_in6 *)(const void *)(sockaddr), ipaddr, *port);
+    ipaddr->type = IPADDR_TYPE_V6;
+  } else {
+    SOCKADDR4_TO_IP4ADDR_PORT((const struct sockaddr_in *)(const void *)(sockaddr), ipaddr, *port);
+    ipaddr->type = IPADDR_TYPE_V4;
+  }
+}
+#endif /* LWIP_IPV4 && LWIP_IPV6 */
+
+/** LWIP_NETCONN_SEM_PER_THREAD==1: initialize thread-local semaphore */
+void
+lwip_socket_thread_init(void)
+{
+  netconn_thread_init();
+}
+
+/** LWIP_NETCONN_SEM_PER_THREAD==1: destroy thread-local semaphore */
+void
+lwip_socket_thread_cleanup(void)
+{
+  netconn_thread_cleanup();
+}
+
+#if LWIP_NETCONN_FULLDUPLEX
+/* Thread-safe increment of sock->fd_used, with overflow check */
+static int
+sock_inc_used(struct lwip_sock *sock)
+{
+  int ret;
+  SYS_ARCH_DECL_PROTECT(lev);
+
+  LWIP_ASSERT("sock != NULL", sock != NULL);
+
+  SYS_ARCH_PROTECT(lev);
+  if (sock->fd_free_pending) {
+    /* prevent new usage of this socket if free is pending */
+    ret = 0;
+  } else {
+    ++sock->fd_used;
+    ret = 1;
+    LWIP_ASSERT("sock->fd_used != 0", sock->fd_used != 0);
+  }
+  SYS_ARCH_UNPROTECT(lev);
+  return ret;
+}
+
+/* Like sock_inc_used(), but called under SYS_ARCH_PROTECT lock. */
+static int
+sock_inc_used_locked(struct lwip_sock *sock)
+{
+  LWIP_ASSERT("sock != NULL", sock != NULL);
+
+  if (sock->fd_free_pending) {
+    LWIP_ASSERT("sock->fd_used != 0", sock->fd_used != 0);
+    return 0;
+  }
+
+  ++sock->fd_used;
+  LWIP_ASSERT("sock->fd_used != 0", sock->fd_used != 0);
+  return 1;
+}
+
+/* In full-duplex mode,sock->fd_used != 0 prevents a socket descriptor from being
+ * released (and possibly reused) when used from more than one thread
+ * (e.g. read-while-write or close-while-write, etc)
+ * This function is called at the end of functions using (try)get_socket*().
+ */
+static void
+done_socket(struct lwip_sock *sock)
+{
+  int freed = 0;
+  int is_tcp = 0;
+  struct netconn *conn = NULL;
+  union lwip_sock_lastdata lastdata;
+  SYS_ARCH_DECL_PROTECT(lev);
+  LWIP_ASSERT("sock != NULL", sock != NULL);
+
+  SYS_ARCH_PROTECT(lev);
+  LWIP_ASSERT("sock->fd_used > 0", sock->fd_used > 0);
+  if (--sock->fd_used == 0) {
+    if (sock->fd_free_pending) {
+      /* free the socket */
+      sock->fd_used = 1;
+      is_tcp = sock->fd_free_pending & LWIP_SOCK_FD_FREE_TCP;
+      freed = free_socket_locked(sock, is_tcp, &conn, &lastdata);
+    }
+  }
+  SYS_ARCH_UNPROTECT(lev);
+
+  if (freed) {
+    free_socket_free_elements(is_tcp, conn, &lastdata);
+  }
+}
+
+#else /* LWIP_NETCONN_FULLDUPLEX */
+#define sock_inc_used(sock)         1
+#define sock_inc_used_locked(sock)  1
+#define done_socket(sock)
+#endif /* LWIP_NETCONN_FULLDUPLEX */
+
+/* Translate a socket 'int' into a pointer (only fails if the index is invalid) */
+static struct lwip_sock *
+tryget_socket_unconn_nouse(int fd)
+{
+  int s = fd - LWIP_SOCKET_OFFSET;
+  if ((s < 0) || (s >= NUM_SOCKETS)) {
+    LWIP_DEBUGF(SOCKETS_DEBUG, ("tryget_socket_unconn(%d): invalid\n", fd));
+    return NULL;
+  }
+  return &sockets[s];
+}
+
+struct lwip_sock *
+lwip_socket_dbg_get_socket(int fd)
+{
+  return tryget_socket_unconn_nouse(fd);
+}
+
+/* Translate a socket 'int' into a pointer (only fails if the index is invalid) */
+static struct lwip_sock *
+tryget_socket_unconn(int fd)
+{
+  struct lwip_sock *ret = tryget_socket_unconn_nouse(fd);
+  if (ret != NULL) {
+    if (!sock_inc_used(ret)) {
+      return NULL;
+    }
+  }
+  return ret;
+}
+
+/* Like tryget_socket_unconn(), but called under SYS_ARCH_PROTECT lock. */
+static struct lwip_sock *
+tryget_socket_unconn_locked(int fd)
+{
+  struct lwip_sock *ret = tryget_socket_unconn_nouse(fd);
+  if (ret != NULL) {
+    if (!sock_inc_used_locked(ret)) {
+      return NULL;
+    }
+  }
+  return ret;
+}
+
+/**
+ * Same as get_socket but doesn't set errno
+ *
+ * @param fd externally used socket index
+ * @return struct lwip_sock for the socket or NULL if not found
+ */
+static struct lwip_sock *
+tryget_socket(int fd)
+{
+  struct lwip_sock *sock = tryget_socket_unconn(fd);
+  if (sock != NULL) {
+    if (sock->conn) {
+      return sock;
+    }
+    done_socket(sock);
+  }
+  return NULL;
+}
+
+/**
+ * Map a externally used socket index to the internal socket representation.
+ *
+ * @param fd externally used socket index
+ * @return struct lwip_sock for the socket or NULL if not found
+ */
+static struct lwip_sock *
+get_socket(int fd)
+{
+  struct lwip_sock *sock = tryget_socket(fd);
+  if (!sock) {
+    if ((fd < LWIP_SOCKET_OFFSET) || (fd >= (LWIP_SOCKET_OFFSET + NUM_SOCKETS))) {
+      LWIP_DEBUGF(SOCKETS_DEBUG, ("get_socket(%d): invalid\n", fd));
+    }
+    set_errno(EBADF);
+    return NULL;
+  }
+  return sock;
+}
+
+/**
+ * Allocate a new socket for a given netconn.
+ *
+ * @param newconn the netconn for which to allocate a socket
+ * @param accepted 1 if socket has been created by accept(),
+ *                 0 if socket has been created by socket()
+ * @return the index of the new socket; -1 on error
+ */
+static int
+alloc_socket(struct netconn *newconn, int accepted)
+{
+  int i;
+  SYS_ARCH_DECL_PROTECT(lev);
+  LWIP_UNUSED_ARG(accepted);
+
+  /* allocate a new socket identifier */
+  for (i = 0; i < NUM_SOCKETS; ++i) {
+    /* Protect socket array */
+    SYS_ARCH_PROTECT(lev);
+    if (!sockets[i].conn) {
+#if LWIP_NETCONN_FULLDUPLEX
+      if (sockets[i].fd_used) {
+        SYS_ARCH_UNPROTECT(lev);
+        continue;
+      }
+      sockets[i].fd_used    = 1;
+      sockets[i].fd_free_pending = 0;
+#endif
+      sockets[i].conn       = newconn;
+      /* The socket is not yet known to anyone, so no need to protect
+         after having marked it as used. */
+      SYS_ARCH_UNPROTECT(lev);
+      sockets[i].lastdata.pbuf = NULL;
+#if LWIP_SOCKET_SELECT || LWIP_SOCKET_POLL
+      LWIP_ASSERT("sockets[i].select_waiting == 0", sockets[i].select_waiting == 0);
+      sockets[i].rcvevent   = 0;
+      /* TCP sendbuf is empty, but the socket is not yet writable until connected
+       * (unless it has been created by accept()). */
+      sockets[i].sendevent  = (NETCONNTYPE_GROUP(newconn->type) == NETCONN_TCP ? (accepted != 0) : 1);
+      sockets[i].errevent   = 0;
+#endif /* LWIP_SOCKET_SELECT || LWIP_SOCKET_POLL */
+      return i + LWIP_SOCKET_OFFSET;
+    }
+    SYS_ARCH_UNPROTECT(lev);
+  }
+  return -1;
+}
+
+/** Free a socket (under lock)
+ *
+ * @param sock the socket to free
+ * @param is_tcp != 0 for TCP sockets, used to free lastdata
+ * @param conn the socekt's netconn is stored here, must be freed externally
+ * @param lastdata lastdata is stored here, must be freed externally
+ */
+static int
+free_socket_locked(struct lwip_sock *sock, int is_tcp, struct netconn **conn,
+                   union lwip_sock_lastdata *lastdata)
+{
+#if LWIP_NETCONN_FULLDUPLEX
+  LWIP_ASSERT("sock->fd_used > 0", sock->fd_used > 0);
+  sock->fd_used--;
+  if (sock->fd_used > 0) {
+    sock->fd_free_pending = LWIP_SOCK_FD_FREE_FREE | (is_tcp ? LWIP_SOCK_FD_FREE_TCP : 0);
+    return 0;
+  }
+#else /* LWIP_NETCONN_FULLDUPLEX */
+  LWIP_UNUSED_ARG(is_tcp);
+#endif /* LWIP_NETCONN_FULLDUPLEX */
+
+  *lastdata = sock->lastdata;
+  sock->lastdata.pbuf = NULL;
+  *conn = sock->conn;
+  sock->conn = NULL;
+  return 1;
+}
+
+/** Free a socket's leftover members.
+ */
+static void
+free_socket_free_elements(int is_tcp, struct netconn *conn, union lwip_sock_lastdata *lastdata)
+{
+  if (lastdata->pbuf != NULL) {
+    if (is_tcp) {
+      pbuf_free(lastdata->pbuf);
+    } else {
+      netbuf_delete(lastdata->netbuf);
+    }
+  }
+  if (conn != NULL) {
+    /* netconn_prepare_delete() has already been called, here we only free the conn */
+    netconn_delete(conn);
+  }
+}
+
+/** Free a socket. The socket's netconn must have been
+ * delete before!
+ *
+ * @param sock the socket to free
+ * @param is_tcp != 0 for TCP sockets, used to free lastdata
+ */
+static void
+free_socket(struct lwip_sock *sock, int is_tcp)
+{
+  int freed;
+  struct netconn *conn;
+  union lwip_sock_lastdata lastdata;
+  SYS_ARCH_DECL_PROTECT(lev);
+
+  /* Protect socket array */
+  SYS_ARCH_PROTECT(lev);
+
+  freed = free_socket_locked(sock, is_tcp, &conn, &lastdata);
+  SYS_ARCH_UNPROTECT(lev);
+  /* don't use 'sock' after this line, as another task might have allocated it */
+
+  if (freed) {
+    free_socket_free_elements(is_tcp, conn, &lastdata);
+  }
+}
+
+/* Below this, the well-known socket functions are implemented.
+ * Use google.com or opengroup.org to get a good description :-)
+ *
+ * Exceptions are documented!
+ */
+
+int
+lwip_accept(int s, struct sockaddr *addr, socklen_t *addrlen)
+{
+  struct lwip_sock *sock, *nsock;
+  struct netconn *newconn;
+  ip_addr_t naddr;
+  u16_t port = 0;
+  int newsock;
+  err_t err;
+  int recvevent;
+  SYS_ARCH_DECL_PROTECT(lev);
+
+  LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_accept(%d)...\n", s));
+  sock = get_socket(s);
+  if (!sock) {
+    return -1;
+  }
+
+  /* wait for a new connection */
+  err = netconn_accept(sock->conn, &newconn);
+  if (err != ERR_OK) {
+    LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_accept(%d): netconn_acept failed, err=%d\n", s, err));
+    if (NETCONNTYPE_GROUP(netconn_type(sock->conn)) != NETCONN_TCP) {
+      sock_set_errno(sock, EOPNOTSUPP);
+    } else if (err == ERR_CLSD) {
+      sock_set_errno(sock, EINVAL);
+    } else {
+      sock_set_errno(sock, err_to_errno(err));
+    }
+    done_socket(sock);
+    return -1;
+  }
+  LWIP_ASSERT("newconn != NULL", newconn != NULL);
+
+  newsock = alloc_socket(newconn, 1);
+  if (newsock == -1) {
+    netconn_delete(newconn);
+    sock_set_errno(sock, ENFILE);
+    done_socket(sock);
+    return -1;
+  }
+  LWIP_ASSERT("invalid socket index", (newsock >= LWIP_SOCKET_OFFSET) && (newsock < NUM_SOCKETS + LWIP_SOCKET_OFFSET));
+  nsock = &sockets[newsock - LWIP_SOCKET_OFFSET];
+
+  /* See event_callback: If data comes in right away after an accept, even
+   * though the server task might not have created a new socket yet.
+   * In that case, newconn->socket is counted down (newconn->socket--),
+   * so nsock->rcvevent is >= 1 here!
+   */
+  SYS_ARCH_PROTECT(lev);
+  recvevent = (s16_t)(-1 - newconn->socket);
+  newconn->socket = newsock;
+  SYS_ARCH_UNPROTECT(lev);
+
+  if (newconn->callback) {
+    LOCK_TCPIP_CORE();
+    while (recvevent > 0) {
+      recvevent--;
+      newconn->callback(newconn, NETCONN_EVT_RCVPLUS, 0);
+    }
+    UNLOCK_TCPIP_CORE();
+  }
+
+  /* Note that POSIX only requires us to check addr is non-NULL. addrlen must
+   * not be NULL if addr is valid.
+   */
+  if ((addr != NULL) && (addrlen != NULL)) {
+    union sockaddr_aligned tempaddr;
+    /* get the IP address and port of the remote host */
+    err = netconn_peer(newconn, &naddr, &port);
+    if (err != ERR_OK) {
+      LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_accept(%d): netconn_peer failed, err=%d\n", s, err));
+      netconn_delete(newconn);
+      free_socket(nsock, 1);
+      sock_set_errno(sock, err_to_errno(err));
+      done_socket(sock);
+      return -1;
+    }
+
+    IPADDR_PORT_TO_SOCKADDR(&tempaddr, &naddr, port);
+    if (*addrlen > tempaddr.sa.sa_len) {
+      *addrlen = tempaddr.sa.sa_len;
+    }
+    MEMCPY(addr, &tempaddr, *addrlen);
+
+    LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_accept(%d) returning new sock=%d addr=", s, newsock));
+    ip_addr_debug_print_val(SOCKETS_DEBUG, naddr);
+    LWIP_DEBUGF(SOCKETS_DEBUG, (" port=%"U16_F"\n", port));
+  } else {
+    LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_accept(%d) returning new sock=%d", s, newsock));
+  }
+
+  sock_set_errno(sock, 0);
+  done_socket(sock);
+  done_socket(nsock);
+  return newsock;
+}
+
+int
+lwip_bind(int s, const struct sockaddr *name, socklen_t namelen)
+{
+  struct lwip_sock *sock;
+  ip_addr_t local_addr;
+  u16_t local_port;
+  err_t err;
+
+  sock = get_socket(s);
+  if (!sock) {
+    return -1;
+  }
+
+  if (!SOCK_ADDR_TYPE_MATCH(name, sock)) {
+    /* sockaddr does not match socket type (IPv4/IPv6) */
+    sock_set_errno(sock, err_to_errno(ERR_VAL));
+    done_socket(sock);
+    return -1;
+  }
+
+  /* check size, family and alignment of 'name' */
+  LWIP_ERROR("lwip_bind: invalid address", (IS_SOCK_ADDR_LEN_VALID(namelen) &&
+             IS_SOCK_ADDR_TYPE_VALID(name) && IS_SOCK_ADDR_ALIGNED(name)),
+             sock_set_errno(sock, err_to_errno(ERR_ARG)); done_socket(sock); return -1;);
+  LWIP_UNUSED_ARG(namelen);
+
+  SOCKADDR_TO_IPADDR_PORT(name, &local_addr, local_port);
+  LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_bind(%d, addr=", s));
+  ip_addr_debug_print_val(SOCKETS_DEBUG, local_addr);
+  LWIP_DEBUGF(SOCKETS_DEBUG, (" port=%"U16_F")\n", local_port));
+
+#if LWIP_IPV4 && LWIP_IPV6
+  /* Dual-stack: Unmap IPv4 mapped IPv6 addresses */
+  if (IP_IS_V6_VAL(local_addr) && ip6_addr_isipv4mappedipv6(ip_2_ip6(&local_addr))) {
+    unmap_ipv4_mapped_ipv6(ip_2_ip4(&local_addr), ip_2_ip6(&local_addr));
+    IP_SET_TYPE_VAL(local_addr, IPADDR_TYPE_V4);
+  }
+#endif /* LWIP_IPV4 && LWIP_IPV6 */
+
+  err = netconn_bind(sock->conn, &local_addr, local_port);
+
+  if (err != ERR_OK) {
+    LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_bind(%d) failed, err=%d\n", s, err));
+    sock_set_errno(sock, err_to_errno(err));
+    done_socket(sock);
+    return -1;
+  }
+
+  LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_bind(%d) succeeded\n", s));
+  sock_set_errno(sock, 0);
+  done_socket(sock);
+  return 0;
+}
+
+int
+lwip_close(int s)
+{
+  struct lwip_sock *sock;
+  int is_tcp = 0;
+  err_t err;
+
+  LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_close(%d)\n", s));
+
+  sock = get_socket(s);
+  if (!sock) {
+    return -1;
+  }
+
+  if (sock->conn != NULL) {
+    is_tcp = NETCONNTYPE_GROUP(netconn_type(sock->conn)) == NETCONN_TCP;
+  } else {
+    LWIP_ASSERT("sock->lastdata == NULL", sock->lastdata.pbuf == NULL);
+  }
+
+#if LWIP_IGMP
+  /* drop all possibly joined IGMP memberships */
+  lwip_socket_drop_registered_memberships(s);
+#endif /* LWIP_IGMP */
+#if LWIP_IPV6_MLD
+  /* drop all possibly joined MLD6 memberships */
+  lwip_socket_drop_registered_mld6_memberships(s);
+#endif /* LWIP_IPV6_MLD */
+
+  err = netconn_prepare_delete(sock->conn);
+  if (err != ERR_OK) {
+    sock_set_errno(sock, err_to_errno(err));
+    done_socket(sock);
+    return -1;
+  }
+
+  free_socket(sock, is_tcp);
+  set_errno(0);
+  return 0;
+}
+
+int
+lwip_connect(int s, const struct sockaddr *name, socklen_t namelen)
+{
+  struct lwip_sock *sock;
+  err_t err;
+
+  sock = get_socket(s);
+  if (!sock) {
+    return -1;
+  }
+
+  if (!SOCK_ADDR_TYPE_MATCH_OR_UNSPEC(name, sock)) {
+    /* sockaddr does not match socket type (IPv4/IPv6) */
+    sock_set_errno(sock, err_to_errno(ERR_VAL));
+    done_socket(sock);
+    return -1;
+  }
+
+  LWIP_UNUSED_ARG(namelen);
+  if (name->sa_family == AF_UNSPEC) {
+    LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_connect(%d, AF_UNSPEC)\n", s));
+    err = netconn_disconnect(sock->conn);
+  } else {
+    ip_addr_t remote_addr;
+    u16_t remote_port;
+
+    /* check size, family and alignment of 'name' */
+    LWIP_ERROR("lwip_connect: invalid address", IS_SOCK_ADDR_LEN_VALID(namelen) &&
+               IS_SOCK_ADDR_TYPE_VALID_OR_UNSPEC(name) && IS_SOCK_ADDR_ALIGNED(name),
+               sock_set_errno(sock, err_to_errno(ERR_ARG)); done_socket(sock); return -1;);
+
+    SOCKADDR_TO_IPADDR_PORT(name, &remote_addr, remote_port);
+    LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_connect(%d, addr=", s));
+    ip_addr_debug_print_val(SOCKETS_DEBUG, remote_addr);
+    LWIP_DEBUGF(SOCKETS_DEBUG, (" port=%"U16_F")\n", remote_port));
+
+#if LWIP_IPV4 && LWIP_IPV6
+    /* Dual-stack: Unmap IPv4 mapped IPv6 addresses */
+    if (IP_IS_V6_VAL(remote_addr) && ip6_addr_isipv4mappedipv6(ip_2_ip6(&remote_addr))) {
+      unmap_ipv4_mapped_ipv6(ip_2_ip4(&remote_addr), ip_2_ip6(&remote_addr));
+      IP_SET_TYPE_VAL(remote_addr, IPADDR_TYPE_V4);
+    }
+#endif /* LWIP_IPV4 && LWIP_IPV6 */
+
+    err = netconn_connect(sock->conn, &remote_addr, remote_port);
+  }
+
+  if (err != ERR_OK) {
+    LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_connect(%d) failed, err=%d\n", s, err));
+    sock_set_errno(sock, err_to_errno(err));
+    done_socket(sock);
+    return -1;
+  }
+
+  LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_connect(%d) succeeded\n", s));
+  sock_set_errno(sock, 0);
+  done_socket(sock);
+  return 0;
+}
+
+/**
+ * Set a socket into listen mode.
+ * The socket may not have been used for another connection previously.
+ *
+ * @param s the socket to set to listening mode
+ * @param backlog (ATTENTION: needs TCP_LISTEN_BACKLOG=1)
+ * @return 0 on success, non-zero on failure
+ */
+int
+lwip_listen(int s, int backlog)
+{
+  struct lwip_sock *sock;
+  err_t err;
+
+  LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_listen(%d, backlog=%d)\n", s, backlog));
+
+  sock = get_socket(s);
+  if (!sock) {
+    return -1;
+  }
+
+  /* limit the "backlog" parameter to fit in an u8_t */
+  backlog = LWIP_MIN(LWIP_MAX(backlog, 0), 0xff);
+
+  err = netconn_listen_with_backlog(sock->conn, (u8_t)backlog);
+
+  if (err != ERR_OK) {
+    LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_listen(%d) failed, err=%d\n", s, err));
+    if (NETCONNTYPE_GROUP(netconn_type(sock->conn)) != NETCONN_TCP) {
+      sock_set_errno(sock, EOPNOTSUPP);
+    } else {
+      sock_set_errno(sock, err_to_errno(err));
+    }
+    done_socket(sock);
+    return -1;
+  }
+
+  sock_set_errno(sock, 0);
+  done_socket(sock);
+  return 0;
+}
+
+#if LWIP_TCP
+/* Helper function to loop over receiving pbufs from netconn
+ * until "len" bytes are received or we're otherwise done.
+ * Keeps sock->lastdata for peeking or partly copying.
+ */
+static ssize_t
+lwip_recv_tcp(struct lwip_sock *sock, void *mem, size_t len, int flags)
+{
+  u8_t apiflags = NETCONN_NOAUTORCVD;
+  ssize_t recvd = 0;
+  ssize_t recv_left = (len <= SSIZE_MAX) ? (ssize_t)len : SSIZE_MAX;
+
+  LWIP_ASSERT("no socket given", sock != NULL);
+  LWIP_ASSERT("this should be checked internally", NETCONNTYPE_GROUP(netconn_type(sock->conn)) == NETCONN_TCP);
+
+  if (flags & MSG_DONTWAIT) {
+    apiflags |= NETCONN_DONTBLOCK;
+  }
+
+  do {
+    struct pbuf *p;
+    err_t err;
+    u16_t copylen;
+
+    LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_recv_tcp: top while sock->lastdata=%p\n", (void *)sock->lastdata.pbuf));
+    /* Check if there is data left from the last recv operation. */
+    if (sock->lastdata.pbuf) {
+      p = sock->lastdata.pbuf;
+    } else {
+      /* No data was left from the previous operation, so we try to get
+         some from the network. */
+      err = netconn_recv_tcp_pbuf_flags(sock->conn, &p, apiflags);
+      LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_recv_tcp: netconn_recv err=%d, pbuf=%p\n",
+                                  err, (void *)p));
+
+      if (err != ERR_OK) {
+        if (recvd > 0) {
+          /* already received data, return that (this trusts in getting the same error from
+             netconn layer again next time netconn_recv is called) */
+          goto lwip_recv_tcp_done;
+        }
+        /* We should really do some error checking here. */
+        LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_recv_tcp: p == NULL, error is \"%s\"!\n",
+                                    lwip_strerr(err)));
+        sock_set_errno(sock, err_to_errno(err));
+        if (err == ERR_CLSD) {
+          return 0;
+        } else {
+          return -1;
+        }
+      }
+      LWIP_ASSERT("p != NULL", p != NULL);
+      sock->lastdata.pbuf = p;
+    }
+
+    LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_recv_tcp: buflen=%"U16_F" recv_left=%d off=%d\n",
+                                p->tot_len, (int)recv_left, (int)recvd));
+
+    if (recv_left > p->tot_len) {
+      copylen = p->tot_len;
+    } else {
+      copylen = (u16_t)recv_left;
+    }
+    if (recvd + copylen < recvd) {
+      /* overflow */
+      copylen = (u16_t)(SSIZE_MAX - recvd);
+    }
+
+    /* copy the contents of the received buffer into
+    the supplied memory pointer mem */
+    pbuf_copy_partial(p, (u8_t *)mem + recvd, copylen, 0);
+
+    recvd += copylen;
+
+    /* TCP combines multiple pbufs for one recv */
+    LWIP_ASSERT("invalid copylen, len would underflow", recv_left >= copylen);
+    recv_left -= copylen;
+
+    /* Unless we peek the incoming message... */
+    if ((flags & MSG_PEEK) == 0) {
+      /* ... check if there is data left in the pbuf */
+      LWIP_ASSERT("invalid copylen", p->tot_len >= copylen);
+      if (p->tot_len - copylen > 0) {
+        /* If so, it should be saved in the sock structure for the next recv call.
+           We store the pbuf but hide/free the consumed data: */
+        sock->lastdata.pbuf = pbuf_free_header(p, copylen);
+        LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_recv_tcp: lastdata now pbuf=%p\n", (void *)sock->lastdata.pbuf));
+      } else {
+        sock->lastdata.pbuf = NULL;
+        LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_recv_tcp: deleting pbuf=%p\n", (void *)p));
+        pbuf_free(p);
+      }
+    }
+    /* once we have some data to return, only add more if we don't need to wait */
+    apiflags |= NETCONN_DONTBLOCK | NETCONN_NOFIN;
+    /* @todo: do we need to support peeking more than one pbuf? */
+  } while ((recv_left > 0) && !(flags & MSG_PEEK));
+lwip_recv_tcp_done:
+  if ((recvd > 0) && !(flags & MSG_PEEK)) {
+    /* ensure window update after copying all data */
+    netconn_tcp_recvd(sock->conn, (size_t)recvd);
+  }
+  sock_set_errno(sock, 0);
+  return recvd;
+}
+#endif
+
+/* Convert a netbuf's address data to struct sockaddr */
+static int
+lwip_sock_make_addr(struct netconn *conn, ip_addr_t *fromaddr, u16_t port,
+                    struct sockaddr *from, socklen_t *fromlen)
+{
+  int truncated = 0;
+  union sockaddr_aligned saddr;
+
+  LWIP_UNUSED_ARG(conn);
+
+  LWIP_ASSERT("fromaddr != NULL", fromaddr != NULL);
+  LWIP_ASSERT("from != NULL", from != NULL);
+  LWIP_ASSERT("fromlen != NULL", fromlen != NULL);
+
+#if LWIP_IPV4 && LWIP_IPV6
+  /* Dual-stack: Map IPv4 addresses to IPv4 mapped IPv6 */
+  if (NETCONNTYPE_ISIPV6(netconn_type(conn)) && IP_IS_V4(fromaddr)) {
+    ip4_2_ipv4_mapped_ipv6(ip_2_ip6(fromaddr), ip_2_ip4(fromaddr));
+    IP_SET_TYPE(fromaddr, IPADDR_TYPE_V6);
+  }
+#endif /* LWIP_IPV4 && LWIP_IPV6 */
+
+  IPADDR_PORT_TO_SOCKADDR(&saddr, fromaddr, port);
+  if (*fromlen < saddr.sa.sa_len) {
+    truncated = 1;
+  } else if (*fromlen > saddr.sa.sa_len) {
+    *fromlen = saddr.sa.sa_len;
+  }
+  MEMCPY(from, &saddr, *fromlen);
+  return truncated;
+}
+
+#if LWIP_TCP
+/* Helper function to get a tcp socket's remote address info */
+static int
+lwip_recv_tcp_from(struct lwip_sock *sock, struct sockaddr *from, socklen_t *fromlen, const char *dbg_fn, int dbg_s, ssize_t dbg_ret)
+{
+  if (sock == NULL) {
+    return 0;
+  }
+  LWIP_UNUSED_ARG(dbg_fn);
+  LWIP_UNUSED_ARG(dbg_s);
+  LWIP_UNUSED_ARG(dbg_ret);
+
+#if !SOCKETS_DEBUG
+  if (from && fromlen)
+#endif /* !SOCKETS_DEBUG */
+  {
+    /* get remote addr/port from tcp_pcb */
+    u16_t port;
+    ip_addr_t tmpaddr;
+    netconn_getaddr(sock->conn, &tmpaddr, &port, 0);
+    LWIP_DEBUGF(SOCKETS_DEBUG, ("%s(%d):  addr=", dbg_fn, dbg_s));
+    ip_addr_debug_print_val(SOCKETS_DEBUG, tmpaddr);
+    LWIP_DEBUGF(SOCKETS_DEBUG, (" port=%"U16_F" len=%d\n", port, (int)dbg_ret));
+    if (from && fromlen) {
+      return lwip_sock_make_addr(sock->conn, &tmpaddr, port, from, fromlen);
+    }
+  }
+  return 0;
+}
+#endif
+
+/* Helper function to receive a netbuf from a udp or raw netconn.
+ * Keeps sock->lastdata for peeking.
+ */
+static err_t
+lwip_recvfrom_udp_raw(struct lwip_sock *sock, int flags, struct msghdr *msg, u16_t *datagram_len, int dbg_s)
+{
+  struct netbuf *buf;
+  u8_t apiflags;
+  err_t err;
+  u16_t buflen, copylen, copied;
+  int i;
+
+  LWIP_UNUSED_ARG(dbg_s);
+  LWIP_ERROR("lwip_recvfrom_udp_raw: invalid arguments", (msg->msg_iov != NULL) || (msg->msg_iovlen <= 0), return ERR_ARG;);
+
+  if (flags & MSG_DONTWAIT) {
+    apiflags = NETCONN_DONTBLOCK;
+  } else {
+    apiflags = 0;
+  }
+
+  LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_recvfrom_udp_raw[UDP/RAW]: top sock->lastdata=%p\n", (void *)sock->lastdata.netbuf));
+  /* Check if there is data left from the last recv operation. */
+  buf = sock->lastdata.netbuf;
+  if (buf == NULL) {
+    /* No data was left from the previous operation, so we try to get
+        some from the network. */
+    err = netconn_recv_udp_raw_netbuf_flags(sock->conn, &buf, apiflags);
+    LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_recvfrom_udp_raw[UDP/RAW]: netconn_recv err=%d, netbuf=%p\n",
+                                err, (void *)buf));
+
+    if (err != ERR_OK) {
+      return err;
+    }
+    LWIP_ASSERT("buf != NULL", buf != NULL);
+    sock->lastdata.netbuf = buf;
+  }
+  buflen = buf->p->tot_len;
+  LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_recvfrom_udp_raw: buflen=%"U16_F"\n", buflen));
+
+  copied = 0;
+  /* copy the pbuf payload into the iovs */
+  for (i = 0; (i < msg->msg_iovlen) && (copied < buflen); i++) {
+    u16_t len_left = (u16_t)(buflen - copied);
+    if (msg->msg_iov[i].iov_len > len_left) {
+      copylen = len_left;
+    } else {
+      copylen = (u16_t)msg->msg_iov[i].iov_len;
+    }
+
+    /* copy the contents of the received buffer into
+        the supplied memory buffer */
+    pbuf_copy_partial(buf->p, (u8_t *)msg->msg_iov[i].iov_base, copylen, copied);
+    copied = (u16_t)(copied + copylen);
+  }
+
+  /* Check to see from where the data was.*/
+#if !SOCKETS_DEBUG
+  if (msg->msg_name && msg->msg_namelen)
+#endif /* !SOCKETS_DEBUG */
+  {
+    LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_recvfrom_udp_raw(%d):  addr=", dbg_s));
+    ip_addr_debug_print_val(SOCKETS_DEBUG, *netbuf_fromaddr(buf));
+    LWIP_DEBUGF(SOCKETS_DEBUG, (" port=%"U16_F" len=%d\n", netbuf_fromport(buf), copied));
+    if (msg->msg_name && msg->msg_namelen) {
+      lwip_sock_make_addr(sock->conn, netbuf_fromaddr(buf), netbuf_fromport(buf),
+                          (struct sockaddr *)msg->msg_name, &msg->msg_namelen);
+    }
+  }
+
+  /* Initialize flag output */
+  msg->msg_flags = 0;
+
+  if (msg->msg_control) {
+    u8_t wrote_msg = 0;
+#if LWIP_NETBUF_RECVINFO
+    /* Check if packet info was recorded */
+    if (buf->flags & NETBUF_FLAG_DESTADDR) {
+      if (IP_IS_V4(&buf->toaddr)) {
+#if LWIP_IPV4
+        if (msg->msg_controllen >= CMSG_SPACE(sizeof(struct in_pktinfo))) {
+          struct cmsghdr *chdr = CMSG_FIRSTHDR(msg); /* This will always return a header!! */
+          struct in_pktinfo *pkti = (struct in_pktinfo *)CMSG_DATA(chdr);
+          chdr->cmsg_level = IPPROTO_IP;
+          chdr->cmsg_type = IP_PKTINFO;
+          chdr->cmsg_len = CMSG_LEN(sizeof(struct in_pktinfo));
+          pkti->ipi_ifindex = buf->p->if_idx;
+          inet_addr_from_ip4addr(&pkti->ipi_addr, ip_2_ip4(netbuf_destaddr(buf)));
+          msg->msg_controllen = CMSG_SPACE(sizeof(struct in_pktinfo));
+          wrote_msg = 1;
+        } else {
+          msg->msg_flags |= MSG_CTRUNC;
+        }
+#endif /* LWIP_IPV4 */
+      }
+    }
+#endif /* LWIP_NETBUF_RECVINFO */
+
+    if (!wrote_msg) {
+      msg->msg_controllen = 0;
+    }
+  }
+
+  /* If we don't peek the incoming message: zero lastdata pointer and free the netbuf */
+  if ((flags & MSG_PEEK) == 0) {
+    sock->lastdata.netbuf = NULL;
+    netbuf_delete(buf);
+  }
+  if (datagram_len) {
+    *datagram_len = buflen;
+  }
+  return ERR_OK;
+}
+
+ssize_t
+lwip_recvfrom(int s, void *mem, size_t len, int flags,
+              struct sockaddr *from, socklen_t *fromlen)
+{
+  struct lwip_sock *sock;
+  ssize_t ret;
+
+  LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_recvfrom(%d, %p, %"SZT_F", 0x%x, ..)\n", s, mem, len, flags));
+  sock = get_socket(s);
+  if (!sock) {
+    return -1;
+  }
+#if LWIP_TCP
+  if (NETCONNTYPE_GROUP(netconn_type(sock->conn)) == NETCONN_TCP) {
+    ret = lwip_recv_tcp(sock, mem, len, flags);
+    lwip_recv_tcp_from(sock, from, fromlen, "lwip_recvfrom", s, ret);
+    done_socket(sock);
+    return ret;
+  } else
+#endif
+  {
+    u16_t datagram_len = 0;
+    struct iovec vec;
+    struct msghdr msg;
+    err_t err;
+    vec.iov_base = mem;
+    vec.iov_len = len;
+    msg.msg_control = NULL;
+    msg.msg_controllen = 0;
+    msg.msg_flags = 0;
+    msg.msg_iov = &vec;
+    msg.msg_iovlen = 1;
+    msg.msg_name = from;
+    msg.msg_namelen = (fromlen ? *fromlen : 0);
+    err = lwip_recvfrom_udp_raw(sock, flags, &msg, &datagram_len, s);
+    if (err != ERR_OK) {
+      LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_recvfrom[UDP/RAW](%d): buf == NULL, error is \"%s\"!\n",
+                                  s, lwip_strerr(err)));
+      sock_set_errno(sock, err_to_errno(err));
+      done_socket(sock);
+      return -1;
+    }
+    ret = (ssize_t)LWIP_MIN(LWIP_MIN(len, datagram_len), SSIZE_MAX);
+    if (fromlen) {
+      *fromlen = msg.msg_namelen;
+    }
+  }
+
+  sock_set_errno(sock, 0);
+  done_socket(sock);
+  return ret;
+}
+
+ssize_t
+lwip_read(int s, void *mem, size_t len)
+{
+  return lwip_recvfrom(s, mem, len, 0, NULL, NULL);
+}
+
+ssize_t
+lwip_readv(int s, const struct iovec *iov, int iovcnt)
+{
+  struct msghdr msg;
+
+  msg.msg_name = NULL;
+  msg.msg_namelen = 0;
+  /* Hack: we have to cast via number to cast from 'const' pointer to non-const.
+     Blame the opengroup standard for this inconsistency. */
+  msg.msg_iov = LWIP_CONST_CAST(struct iovec *, iov);
+  msg.msg_iovlen = iovcnt;
+  msg.msg_control = NULL;
+  msg.msg_controllen = 0;
+  msg.msg_flags = 0;
+  return lwip_recvmsg(s, &msg, 0);
+}
+
+ssize_t
+lwip_recv(int s, void *mem, size_t len, int flags)
+{
+  return lwip_recvfrom(s, mem, len, flags, NULL, NULL);
+}
+
+ssize_t
+lwip_recvmsg(int s, struct msghdr *message, int flags)
+{
+  struct lwip_sock *sock;
+  int i;
+  ssize_t buflen;
+
+  LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_recvmsg(%d, message=%p, flags=0x%x)\n", s, (void *)message, flags));
+  LWIP_ERROR("lwip_recvmsg: invalid message pointer", message != NULL, return ERR_ARG;);
+  LWIP_ERROR("lwip_recvmsg: unsupported flags", (flags & ~(MSG_PEEK|MSG_DONTWAIT)) == 0,
+             set_errno(EOPNOTSUPP); return -1;);
+
+  if ((message->msg_iovlen <= 0) || (message->msg_iovlen > IOV_MAX)) {
+    set_errno(EMSGSIZE);
+    return -1;
+  }
+
+  sock = get_socket(s);
+  if (!sock) {
+    return -1;
+  }
+
+  /* check for valid vectors */
+  buflen = 0;
+  for (i = 0; i < message->msg_iovlen; i++) {
+    if ((message->msg_iov[i].iov_base == NULL) || ((ssize_t)message->msg_iov[i].iov_len <= 0) ||
+        ((size_t)(ssize_t)message->msg_iov[i].iov_len != message->msg_iov[i].iov_len) ||
+        ((ssize_t)(buflen + (ssize_t)message->msg_iov[i].iov_len) <= 0)) {
+      sock_set_errno(sock, err_to_errno(ERR_VAL));
+      done_socket(sock);
+      return -1;
+    }
+    buflen = (ssize_t)(buflen + (ssize_t)message->msg_iov[i].iov_len);
+  }
+
+  if (NETCONNTYPE_GROUP(netconn_type(sock->conn)) == NETCONN_TCP) {
+#if LWIP_TCP
+    int recv_flags = flags;
+    message->msg_flags = 0;
+    /* recv the data */
+    buflen = 0;
+    for (i = 0; i < message->msg_iovlen; i++) {
+      /* try to receive into this vector's buffer */
+      ssize_t recvd_local = lwip_recv_tcp(sock, message->msg_iov[i].iov_base, message->msg_iov[i].iov_len, recv_flags);
+      if (recvd_local > 0) {
+        /* sum up received bytes */
+        buflen += recvd_local;
+      }
+      if ((recvd_local < 0) || (recvd_local < (int)message->msg_iov[i].iov_len) ||
+          (flags & MSG_PEEK)) {
+        /* returned prematurely (or peeking, which might actually be limitated to the first iov) */
+        if (buflen <= 0) {
+          /* nothing received at all, propagate the error */
+          buflen = recvd_local;
+        }
+        break;
+      }
+      /* pass MSG_DONTWAIT to lwip_recv_tcp() to prevent waiting for more data */
+      recv_flags |= MSG_DONTWAIT;
+    }
+    if (buflen > 0) {
+      /* reset socket error since we have received something */
+      sock_set_errno(sock, 0);
+    }
+    /* " If the socket is connected, the msg_name and msg_namelen members shall be ignored." */
+    done_socket(sock);
+    return buflen;
+#else /* LWIP_TCP */
+    sock_set_errno(sock, err_to_errno(ERR_ARG));
+    done_socket(sock);
+    return -1;
+#endif /* LWIP_TCP */
+  }
+  /* else, UDP and RAW NETCONNs */
+#if LWIP_UDP || LWIP_RAW
+  {
+    u16_t datagram_len = 0;
+    err_t err;
+    err = lwip_recvfrom_udp_raw(sock, flags, message, &datagram_len, s);
+    if (err != ERR_OK) {
+      LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_recvmsg[UDP/RAW](%d): buf == NULL, error is \"%s\"!\n",
+                                  s, lwip_strerr(err)));
+      sock_set_errno(sock, err_to_errno(err));
+      done_socket(sock);
+      return -1;
+    }
+    if (datagram_len > buflen) {
+      message->msg_flags |= MSG_TRUNC;
+    }
+
+    sock_set_errno(sock, 0);
+    done_socket(sock);
+    return (int)datagram_len;
+  }
+#else /* LWIP_UDP || LWIP_RAW */
+  sock_set_errno(sock, err_to_errno(ERR_ARG));
+  done_socket(sock);
+  return -1;
+#endif /* LWIP_UDP || LWIP_RAW */
+}
+
+ssize_t
+lwip_send(int s, const void *data, size_t size, int flags)
+{
+  struct lwip_sock *sock;
+  err_t err;
+  u8_t write_flags;
+  size_t written;
+
+  LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_send(%d, data=%p, size=%"SZT_F", flags=0x%x)\n",
+                              s, data, size, flags));
+
+  sock = get_socket(s);
+  if (!sock) {
+    return -1;
+  }
+
+  if (NETCONNTYPE_GROUP(netconn_type(sock->conn)) != NETCONN_TCP) {
+#if (LWIP_UDP || LWIP_RAW)
+    done_socket(sock);
+    return lwip_sendto(s, data, size, flags, NULL, 0);
+#else /* (LWIP_UDP || LWIP_RAW) */
+    sock_set_errno(sock, err_to_errno(ERR_ARG));
+    done_socket(sock);
+    return -1;
+#endif /* (LWIP_UDP || LWIP_RAW) */
+  }
+
+  write_flags = (u8_t)(NETCONN_COPY |
+                       ((flags & MSG_MORE)     ? NETCONN_MORE      : 0) |
+                       ((flags & MSG_DONTWAIT) ? NETCONN_DONTBLOCK : 0));
+  written = 0;
+  err = netconn_write_partly(sock->conn, data, size, write_flags, &written);
+
+  LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_send(%d) err=%d written=%"SZT_F"\n", s, err, written));
+  sock_set_errno(sock, err_to_errno(err));
+  done_socket(sock);
+  /* casting 'written' to ssize_t is OK here since the netconn API limits it to SSIZE_MAX */
+  return (err == ERR_OK ? (ssize_t)written : -1);
+}
+
+ssize_t
+lwip_sendmsg(int s, const struct msghdr *msg, int flags)
+{
+  struct lwip_sock *sock;
+#if LWIP_TCP
+  u8_t write_flags;
+  size_t written;
+#endif
+  err_t err = ERR_OK;
+
+  sock = get_socket(s);
+  if (!sock) {
+    return -1;
+  }
+
+  LWIP_ERROR("lwip_sendmsg: invalid msghdr", msg != NULL,
+             sock_set_errno(sock, err_to_errno(ERR_ARG)); done_socket(sock); return -1;);
+  LWIP_ERROR("lwip_sendmsg: invalid msghdr iov", msg->msg_iov != NULL,
+             sock_set_errno(sock, err_to_errno(ERR_ARG)); done_socket(sock); return -1;);
+  LWIP_ERROR("lwip_sendmsg: maximum iovs exceeded", (msg->msg_iovlen > 0) && (msg->msg_iovlen <= IOV_MAX),
+             sock_set_errno(sock, EMSGSIZE); done_socket(sock); return -1;);
+  LWIP_ERROR("lwip_sendmsg: unsupported flags", (flags & ~(MSG_DONTWAIT | MSG_MORE)) == 0,
+             sock_set_errno(sock, EOPNOTSUPP); done_socket(sock); return -1;);
+
+  LWIP_UNUSED_ARG(msg->msg_control);
+  LWIP_UNUSED_ARG(msg->msg_controllen);
+  LWIP_UNUSED_ARG(msg->msg_flags);
+
+  if (NETCONNTYPE_GROUP(netconn_type(sock->conn)) == NETCONN_TCP) {
+#if LWIP_TCP
+    write_flags = (u8_t)(NETCONN_COPY |
+                         ((flags & MSG_MORE)     ? NETCONN_MORE      : 0) |
+                         ((flags & MSG_DONTWAIT) ? NETCONN_DONTBLOCK : 0));
+
+    written = 0;
+    err = netconn_write_vectors_partly(sock->conn, (struct netvector *)msg->msg_iov, (u16_t)msg->msg_iovlen, write_flags, &written);
+    sock_set_errno(sock, err_to_errno(err));
+    done_socket(sock);
+    /* casting 'written' to ssize_t is OK here since the netconn API limits it to SSIZE_MAX */
+    return (err == ERR_OK ? (ssize_t)written : -1);
+#else /* LWIP_TCP */
+    sock_set_errno(sock, err_to_errno(ERR_ARG));
+    done_socket(sock);
+    return -1;
+#endif /* LWIP_TCP */
+  }
+  /* else, UDP and RAW NETCONNs */
+#if LWIP_UDP || LWIP_RAW
+  {
+    struct netbuf chain_buf;
+    int i;
+    ssize_t size = 0;
+
+    LWIP_UNUSED_ARG(flags);
+    LWIP_ERROR("lwip_sendmsg: invalid msghdr name", (((msg->msg_name == NULL) && (msg->msg_namelen == 0)) ||
+               IS_SOCK_ADDR_LEN_VALID(msg->msg_namelen)),
+               sock_set_errno(sock, err_to_errno(ERR_ARG)); done_socket(sock); return -1;);
+
+    /* initialize chain buffer with destination */
+    memset(&chain_buf, 0, sizeof(struct netbuf));
+    if (msg->msg_name) {
+      u16_t remote_port;
+      SOCKADDR_TO_IPADDR_PORT((const struct sockaddr *)msg->msg_name, &chain_buf.addr, remote_port);
+      netbuf_fromport(&chain_buf) = remote_port;
+    }
+#if LWIP_NETIF_TX_SINGLE_PBUF
+    for (i = 0; i < msg->msg_iovlen; i++) {
+      size += msg->msg_iov[i].iov_len;
+      if ((msg->msg_iov[i].iov_len > INT_MAX) || (size < (int)msg->msg_iov[i].iov_len)) {
+        /* overflow */
+        goto sendmsg_emsgsize;
+      }
+    }
+    if (size > 0xFFFF) {
+      /* overflow */
+      goto sendmsg_emsgsize;
+    }
+    /* Allocate a new netbuf and copy the data into it. */
+    if (netbuf_alloc(&chain_buf, (u16_t)size) == NULL) {
+      err = ERR_MEM;
+    } else {
+      /* flatten the IO vectors */
+      size_t offset = 0;
+      for (i = 0; i < msg->msg_iovlen; i++) {
+        MEMCPY(&((u8_t *)chain_buf.p->payload)[offset], msg->msg_iov[i].iov_base, msg->msg_iov[i].iov_len);
+        offset += msg->msg_iov[i].iov_len;
+      }
+#if LWIP_CHECKSUM_ON_COPY
+      {
+        /* This can be improved by using LWIP_CHKSUM_COPY() and aggregating the checksum for each IO vector */
+        u16_t chksum = ~inet_chksum_pbuf(chain_buf.p);
+        netbuf_set_chksum(&chain_buf, chksum);
+      }
+#endif /* LWIP_CHECKSUM_ON_COPY */
+      err = ERR_OK;
+    }
+#else /* LWIP_NETIF_TX_SINGLE_PBUF */
+    /* create a chained netbuf from the IO vectors. NOTE: we assemble a pbuf chain
+       manually to avoid having to allocate, chain, and delete a netbuf for each iov */
+    for (i = 0; i < msg->msg_iovlen; i++) {
+      struct pbuf *p;
+      if (msg->msg_iov[i].iov_len > 0xFFFF) {
+        /* overflow */
+        goto sendmsg_emsgsize;
+      }
+      p = pbuf_alloc(PBUF_TRANSPORT, 0, PBUF_REF);
+      if (p == NULL) {
+        err = ERR_MEM; /* let netbuf_delete() cleanup chain_buf */
+        break;
+      }
+      p->payload = msg->msg_iov[i].iov_base;
+      p->len = p->tot_len = (u16_t)msg->msg_iov[i].iov_len;
+      /* netbuf empty, add new pbuf */
+      if (chain_buf.p == NULL) {
+        chain_buf.p = chain_buf.ptr = p;
+        /* add pbuf to existing pbuf chain */
+      } else {
+        if (chain_buf.p->tot_len + p->len > 0xffff) {
+          /* overflow */
+          pbuf_free(p);
+          goto sendmsg_emsgsize;
+        }
+        pbuf_cat(chain_buf.p, p);
+      }
+    }
+    /* save size of total chain */
+    if (err == ERR_OK) {
+      size = netbuf_len(&chain_buf);
+    }
+#endif /* LWIP_NETIF_TX_SINGLE_PBUF */
+
+    if (err == ERR_OK) {
+#if LWIP_IPV4 && LWIP_IPV6
+      /* Dual-stack: Unmap IPv4 mapped IPv6 addresses */
+      if (IP_IS_V6_VAL(chain_buf.addr) && ip6_addr_isipv4mappedipv6(ip_2_ip6(&chain_buf.addr))) {
+        unmap_ipv4_mapped_ipv6(ip_2_ip4(&chain_buf.addr), ip_2_ip6(&chain_buf.addr));
+        IP_SET_TYPE_VAL(chain_buf.addr, IPADDR_TYPE_V4);
+      }
+#endif /* LWIP_IPV4 && LWIP_IPV6 */
+
+      /* send the data */
+      err = netconn_send(sock->conn, &chain_buf);
+    }
+
+    /* deallocated the buffer */
+    netbuf_free(&chain_buf);
+
+    sock_set_errno(sock, err_to_errno(err));
+    done_socket(sock);
+    return (err == ERR_OK ? size : -1);
+sendmsg_emsgsize:
+    sock_set_errno(sock, EMSGSIZE);
+    netbuf_free(&chain_buf);
+    done_socket(sock);
+    return -1;
+  }
+#else /* LWIP_UDP || LWIP_RAW */
+  sock_set_errno(sock, err_to_errno(ERR_ARG));
+  done_socket(sock);
+  return -1;
+#endif /* LWIP_UDP || LWIP_RAW */
+}
+
+ssize_t
+lwip_sendto(int s, const void *data, size_t size, int flags,
+            const struct sockaddr *to, socklen_t tolen)
+{
+  struct lwip_sock *sock;
+  err_t err;
+  u16_t short_size;
+  u16_t remote_port;
+  struct netbuf buf;
+
+  sock = get_socket(s);
+  if (!sock) {
+    return -1;
+  }
+
+  if (NETCONNTYPE_GROUP(netconn_type(sock->conn)) == NETCONN_TCP) {
+#if LWIP_TCP
+    done_socket(sock);
+    return lwip_send(s, data, size, flags);
+#else /* LWIP_TCP */
+    LWIP_UNUSED_ARG(flags);
+    sock_set_errno(sock, err_to_errno(ERR_ARG));
+    done_socket(sock);
+    return -1;
+#endif /* LWIP_TCP */
+  }
+
+  if (size > LWIP_MIN(0xFFFF, SSIZE_MAX)) {
+    /* cannot fit into one datagram (at least for us) */
+    sock_set_errno(sock, EMSGSIZE);
+    done_socket(sock);
+    return -1;
+  }
+  short_size = (u16_t)size;
+  LWIP_ERROR("lwip_sendto: invalid address", (((to == NULL) && (tolen == 0)) ||
+             (IS_SOCK_ADDR_LEN_VALID(tolen) &&
+              ((to != NULL) && (IS_SOCK_ADDR_TYPE_VALID(to) && IS_SOCK_ADDR_ALIGNED(to))))),
+             sock_set_errno(sock, err_to_errno(ERR_ARG)); done_socket(sock); return -1;);
+  LWIP_UNUSED_ARG(tolen);
+
+  /* initialize a buffer */
+  buf.p = buf.ptr = NULL;
+#if LWIP_CHECKSUM_ON_COPY
+  buf.flags = 0;
+#endif /* LWIP_CHECKSUM_ON_COPY */
+  if (to) {
+    SOCKADDR_TO_IPADDR_PORT(to, &buf.addr, remote_port);
+  } else {
+    remote_port = 0;
+    ip_addr_set_any(NETCONNTYPE_ISIPV6(netconn_type(sock->conn)), &buf.addr);
+  }
+  netbuf_fromport(&buf) = remote_port;
+
+
+  LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_sendto(%d, data=%p, short_size=%"U16_F", flags=0x%x to=",
+                              s, data, short_size, flags));
+  ip_addr_debug_print_val(SOCKETS_DEBUG, buf.addr);
+  LWIP_DEBUGF(SOCKETS_DEBUG, (" port=%"U16_F"\n", remote_port));
+
+  /* make the buffer point to the data that should be sent */
+#if LWIP_NETIF_TX_SINGLE_PBUF
+  /* Allocate a new netbuf and copy the data into it. */
+  if (netbuf_alloc(&buf, short_size) == NULL) {
+    err = ERR_MEM;
+  } else {
+#if LWIP_CHECKSUM_ON_COPY
+    if (NETCONNTYPE_GROUP(netconn_type(sock->conn)) != NETCONN_RAW) {
+      u16_t chksum = LWIP_CHKSUM_COPY(buf.p->payload, data, short_size);
+      netbuf_set_chksum(&buf, chksum);
+    } else
+#endif /* LWIP_CHECKSUM_ON_COPY */
+    {
+      MEMCPY(buf.p->payload, data, short_size);
+    }
+    err = ERR_OK;
+  }
+#else /* LWIP_NETIF_TX_SINGLE_PBUF */
+  err = netbuf_ref(&buf, data, short_size);
+#endif /* LWIP_NETIF_TX_SINGLE_PBUF */
+  if (err == ERR_OK) {
+#if LWIP_IPV4 && LWIP_IPV6
+    /* Dual-stack: Unmap IPv4 mapped IPv6 addresses */
+    if (IP_IS_V6_VAL(buf.addr) && ip6_addr_isipv4mappedipv6(ip_2_ip6(&buf.addr))) {
+      unmap_ipv4_mapped_ipv6(ip_2_ip4(&buf.addr), ip_2_ip6(&buf.addr));
+      IP_SET_TYPE_VAL(buf.addr, IPADDR_TYPE_V4);
+    }
+#endif /* LWIP_IPV4 && LWIP_IPV6 */
+
+    /* send the data */
+    err = netconn_send(sock->conn, &buf);
+  }
+
+  /* deallocated the buffer */
+  netbuf_free(&buf);
+
+  sock_set_errno(sock, err_to_errno(err));
+  done_socket(sock);
+  return (err == ERR_OK ? short_size : -1);
+}
+
+int
+lwip_socket(int domain, int type, int protocol)
+{
+  struct netconn *conn;
+  int i;
+
+  LWIP_UNUSED_ARG(domain); /* @todo: check this */
+
+  /* create a netconn */
+  switch (type) {
+    case SOCK_RAW:
+      conn = netconn_new_with_proto_and_callback(DOMAIN_TO_NETCONN_TYPE(domain, NETCONN_RAW),
+             (u8_t)protocol, DEFAULT_SOCKET_EVENTCB);
+      LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_socket(%s, SOCK_RAW, %d) = ",
+                                  domain == PF_INET ? "PF_INET" : "UNKNOWN", protocol));
+      break;
+    case SOCK_DGRAM:
+      conn = netconn_new_with_callback(DOMAIN_TO_NETCONN_TYPE(domain,
+                                       ((protocol == IPPROTO_UDPLITE) ? NETCONN_UDPLITE : NETCONN_UDP)),
+                                       DEFAULT_SOCKET_EVENTCB);
+      LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_socket(%s, SOCK_DGRAM, %d) = ",
+                                  domain == PF_INET ? "PF_INET" : "UNKNOWN", protocol));
+#if LWIP_NETBUF_RECVINFO
+      if (conn) {
+        /* netconn layer enables pktinfo by default, sockets default to off */
+        conn->flags &= ~NETCONN_FLAG_PKTINFO;
+      }
+#endif /* LWIP_NETBUF_RECVINFO */
+      break;
+    case SOCK_STREAM:
+      conn = netconn_new_with_callback(DOMAIN_TO_NETCONN_TYPE(domain, NETCONN_TCP), DEFAULT_SOCKET_EVENTCB);
+      LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_socket(%s, SOCK_STREAM, %d) = ",
+                                  domain == PF_INET ? "PF_INET" : "UNKNOWN", protocol));
+      break;
+    default:
+      LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_socket(%d, %d/UNKNOWN, %d) = -1\n",
+                                  domain, type, protocol));
+      set_errno(EINVAL);
+      return -1;
+  }
+
+  if (!conn) {
+    LWIP_DEBUGF(SOCKETS_DEBUG, ("-1 / ENOBUFS (could not create netconn)\n"));
+    set_errno(ENOBUFS);
+    return -1;
+  }
+
+  i = alloc_socket(conn, 0);
+
+  if (i == -1) {
+    netconn_delete(conn);
+    set_errno(ENFILE);
+    return -1;
+  }
+  conn->socket = i;
+  done_socket(&sockets[i - LWIP_SOCKET_OFFSET]);
+  LWIP_DEBUGF(SOCKETS_DEBUG, ("%d\n", i));
+  set_errno(0);
+  return i;
+}
+
+ssize_t
+lwip_write(int s, const void *data, size_t size)
+{
+  return lwip_send(s, data, size, 0);
+}
+
+ssize_t
+lwip_writev(int s, const struct iovec *iov, int iovcnt)
+{
+  struct msghdr msg;
+
+  msg.msg_name = NULL;
+  msg.msg_namelen = 0;
+  /* Hack: we have to cast via number to cast from 'const' pointer to non-const.
+     Blame the opengroup standard for this inconsistency. */
+  msg.msg_iov = LWIP_CONST_CAST(struct iovec *, iov);
+  msg.msg_iovlen = iovcnt;
+  msg.msg_control = NULL;
+  msg.msg_controllen = 0;
+  msg.msg_flags = 0;
+  return lwip_sendmsg(s, &msg, 0);
+}
+
+#if LWIP_SOCKET_SELECT || LWIP_SOCKET_POLL
+/* Add select_cb to select_cb_list. */
+static void
+lwip_link_select_cb(struct lwip_select_cb *select_cb)
+{
+  LWIP_SOCKET_SELECT_DECL_PROTECT(lev);
+
+  /* Protect the select_cb_list */
+  LWIP_SOCKET_SELECT_PROTECT(lev);
+
+  /* Put this select_cb on top of list */
+  select_cb->next = select_cb_list;
+  if (select_cb_list != NULL) {
+    select_cb_list->prev = select_cb;
+  }
+  select_cb_list = select_cb;
+#if !LWIP_TCPIP_CORE_LOCKING
+  /* Increasing this counter tells select_check_waiters that the list has changed. */
+  select_cb_ctr++;
+#endif
+
+  /* Now we can safely unprotect */
+  LWIP_SOCKET_SELECT_UNPROTECT(lev);
+}
+
+/* Remove select_cb from select_cb_list. */
+static void
+lwip_unlink_select_cb(struct lwip_select_cb *select_cb)
+{
+  LWIP_SOCKET_SELECT_DECL_PROTECT(lev);
+
+  /* Take us off the list */
+  LWIP_SOCKET_SELECT_PROTECT(lev);
+  if (select_cb->next != NULL) {
+    select_cb->next->prev = select_cb->prev;
+  }
+  if (select_cb_list == select_cb) {
+    LWIP_ASSERT("select_cb->prev == NULL", select_cb->prev == NULL);
+    select_cb_list = select_cb->next;
+  } else {
+    LWIP_ASSERT("select_cb->prev != NULL", select_cb->prev != NULL);
+    select_cb->prev->next = select_cb->next;
+  }
+#if !LWIP_TCPIP_CORE_LOCKING
+  /* Increasing this counter tells select_check_waiters that the list has changed. */
+  select_cb_ctr++;
+#endif
+  LWIP_SOCKET_SELECT_UNPROTECT(lev);
+}
+#endif /* LWIP_SOCKET_SELECT || LWIP_SOCKET_POLL */
+
+#if LWIP_SOCKET_SELECT
+/**
+ * Go through the readset and writeset lists and see which socket of the sockets
+ * set in the sets has events. On return, readset, writeset and exceptset have
+ * the sockets enabled that had events.
+ *
+ * @param maxfdp1 the highest socket index in the sets
+ * @param readset_in    set of sockets to check for read events
+ * @param writeset_in   set of sockets to check for write events
+ * @param exceptset_in  set of sockets to check for error events
+ * @param readset_out   set of sockets that had read events
+ * @param writeset_out  set of sockets that had write events
+ * @param exceptset_out set os sockets that had error events
+ * @return number of sockets that had events (read/write/exception) (>= 0)
+ */
+static int
+lwip_selscan(int maxfdp1, fd_set *readset_in, fd_set *writeset_in, fd_set *exceptset_in,
+             fd_set *readset_out, fd_set *writeset_out, fd_set *exceptset_out)
+{
+  int i, nready = 0;
+  fd_set lreadset, lwriteset, lexceptset;
+  struct lwip_sock *sock;
+  SYS_ARCH_DECL_PROTECT(lev);
+
+  FD_ZERO(&lreadset);
+  FD_ZERO(&lwriteset);
+  FD_ZERO(&lexceptset);
+
+  /* Go through each socket in each list to count number of sockets which
+     currently match */
+  for (i = LWIP_SOCKET_OFFSET; i < maxfdp1; i++) {
+    /* if this FD is not in the set, continue */
+    if (!(readset_in && FD_ISSET(i, readset_in)) &&
+        !(writeset_in && FD_ISSET(i, writeset_in)) &&
+        !(exceptset_in && FD_ISSET(i, exceptset_in))) {
+      continue;
+    }
+    /* First get the socket's status (protected)... */
+    SYS_ARCH_PROTECT(lev);
+    sock = tryget_socket_unconn_locked(i);
+    if (sock != NULL) {
+      void *lastdata = sock->lastdata.pbuf;
+      s16_t rcvevent = sock->rcvevent;
+      u16_t sendevent = sock->sendevent;
+      u16_t errevent = sock->errevent;
+      SYS_ARCH_UNPROTECT(lev);
+
+      /* ... then examine it: */
+      /* See if netconn of this socket is ready for read */
+      if (readset_in && FD_ISSET(i, readset_in) && ((lastdata != NULL) || (rcvevent > 0))) {
+        FD_SET(i, &lreadset);
+        LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_selscan: fd=%d ready for reading\n", i));
+        nready++;
+      }
+      /* See if netconn of this socket is ready for write */
+      if (writeset_in && FD_ISSET(i, writeset_in) && (sendevent != 0)) {
+        FD_SET(i, &lwriteset);
+        LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_selscan: fd=%d ready for writing\n", i));
+        nready++;
+      }
+      /* See if netconn of this socket had an error */
+      if (exceptset_in && FD_ISSET(i, exceptset_in) && (errevent != 0)) {
+        FD_SET(i, &lexceptset);
+        LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_selscan: fd=%d ready for exception\n", i));
+        nready++;
+      }
+      done_socket(sock);
+    } else {
+      SYS_ARCH_UNPROTECT(lev);
+      /* no a valid open socket */
+      return -1;
+    }
+  }
+  /* copy local sets to the ones provided as arguments */
+  *readset_out = lreadset;
+  *writeset_out = lwriteset;
+  *exceptset_out = lexceptset;
+
+  LWIP_ASSERT("nready >= 0", nready >= 0);
+  return nready;
+}
+
+#if LWIP_NETCONN_FULLDUPLEX
+/* Mark all of the set sockets in one of the three fdsets passed to select as used.
+ * All sockets are marked (and later unmarked), whether they are open or not.
+ * This is OK as lwip_selscan aborts select when non-open sockets are found.
+ */
+static void
+lwip_select_inc_sockets_used_set(int maxfdp, fd_set *fdset, fd_set *used_sockets)
+{
+  SYS_ARCH_DECL_PROTECT(lev);
+  if (fdset) {
+    int i;
+    for (i = LWIP_SOCKET_OFFSET; i < maxfdp; i++) {
+      /* if this FD is in the set, lock it (unless already done) */
+      if (FD_ISSET(i, fdset) && !FD_ISSET(i, used_sockets)) {
+        struct lwip_sock *sock;
+        SYS_ARCH_PROTECT(lev);
+        sock = tryget_socket_unconn_locked(i);
+        if (sock != NULL) {
+          /* leave the socket used until released by lwip_select_dec_sockets_used */
+          FD_SET(i, used_sockets);
+        }
+        SYS_ARCH_UNPROTECT(lev);
+      }
+    }
+  }
+}
+
+/* Mark all sockets passed to select as used to prevent them from being freed
+ * from other threads while select is running.
+ * Marked sockets are added to 'used_sockets' to mark them only once an be able
+ * to unmark them correctly.
+ */
+static void
+lwip_select_inc_sockets_used(int maxfdp, fd_set *fdset1, fd_set *fdset2, fd_set *fdset3, fd_set *used_sockets)
+{
+  FD_ZERO(used_sockets);
+  lwip_select_inc_sockets_used_set(maxfdp, fdset1, used_sockets);
+  lwip_select_inc_sockets_used_set(maxfdp, fdset2, used_sockets);
+  lwip_select_inc_sockets_used_set(maxfdp, fdset3, used_sockets);
+}
+
+/* Let go all sockets that were marked as used when starting select */
+static void
+lwip_select_dec_sockets_used(int maxfdp, fd_set *used_sockets)
+{
+  int i;
+  for (i = LWIP_SOCKET_OFFSET; i < maxfdp; i++) {
+    /* if this FD is not in the set, continue */
+    if (FD_ISSET(i, used_sockets)) {
+      struct lwip_sock *sock = tryget_socket_unconn_nouse(i);
+      LWIP_ASSERT("socket gone at the end of select", sock != NULL);
+      if (sock != NULL) {
+        done_socket(sock);
+      }
+    }
+  }
+}
+#else /* LWIP_NETCONN_FULLDUPLEX */
+#define lwip_select_inc_sockets_used(maxfdp1, readset, writeset, exceptset, used_sockets)
+#define lwip_select_dec_sockets_used(maxfdp1, used_sockets)
+#endif /* LWIP_NETCONN_FULLDUPLEX */
+
+int
+lwip_select(int maxfdp1, fd_set *readset, fd_set *writeset, fd_set *exceptset,
+            struct timeval *timeout)
+{
+  u32_t waitres = 0;
+  int nready;
+  fd_set lreadset, lwriteset, lexceptset;
+  u32_t msectimeout;
+  int i;
+  int maxfdp2;
+#if LWIP_NETCONN_SEM_PER_THREAD
+  int waited = 0;
+#endif
+#if LWIP_NETCONN_FULLDUPLEX
+  fd_set used_sockets;
+#endif
+  SYS_ARCH_DECL_PROTECT(lev);
+
+  LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_select(%d, %p, %p, %p, tvsec=%"S32_F" tvusec=%"S32_F")\n",
+                              maxfdp1, (void *)readset, (void *) writeset, (void *) exceptset,
+                              timeout ? (s32_t)timeout->tv_sec : (s32_t) - 1,
+                              timeout ? (s32_t)timeout->tv_usec : (s32_t) - 1));
+
+  if ((maxfdp1 < 0) || (maxfdp1 > LWIP_SELECT_MAXNFDS)) {
+    set_errno(EINVAL);
+    return -1;
+  }
+
+  lwip_select_inc_sockets_used(maxfdp1, readset, writeset, exceptset, &used_sockets);
+
+  /* Go through each socket in each list to count number of sockets which
+     currently match */
+  nready = lwip_selscan(maxfdp1, readset, writeset, exceptset, &lreadset, &lwriteset, &lexceptset);
+
+  if (nready < 0) {
+    /* one of the sockets in one of the fd_sets was invalid */
+    set_errno(EBADF);
+    lwip_select_dec_sockets_used(maxfdp1, &used_sockets);
+    return -1;
+  } else if (nready > 0) {
+    /* one or more sockets are set, no need to wait */
+    LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_select: nready=%d\n", nready));
+  } else {
+    /* If we don't have any current events, then suspend if we are supposed to */
+    if (timeout && timeout->tv_sec == 0 && timeout->tv_usec == 0) {
+      LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_select: no timeout, returning 0\n"));
+      /* This is OK as the local fdsets are empty and nready is zero,
+         or we would have returned earlier. */
+    } else {
+      /* None ready: add our semaphore to list:
+         We don't actually need any dynamic memory. Our entry on the
+         list is only valid while we are in this function, so it's ok
+         to use local variables (unless we're running in MPU compatible
+         mode). */
+      API_SELECT_CB_VAR_DECLARE(select_cb);
+      API_SELECT_CB_VAR_ALLOC(select_cb, set_errno(ENOMEM); lwip_select_dec_sockets_used(maxfdp1, &used_sockets); return -1);
+      memset(&API_SELECT_CB_VAR_REF(select_cb), 0, sizeof(struct lwip_select_cb));
+
+      API_SELECT_CB_VAR_REF(select_cb).readset = readset;
+      API_SELECT_CB_VAR_REF(select_cb).writeset = writeset;
+      API_SELECT_CB_VAR_REF(select_cb).exceptset = exceptset;
+#if LWIP_NETCONN_SEM_PER_THREAD
+      API_SELECT_CB_VAR_REF(select_cb).sem = LWIP_NETCONN_THREAD_SEM_GET();
+#else /* LWIP_NETCONN_SEM_PER_THREAD */
+      if (sys_sem_new(&API_SELECT_CB_VAR_REF(select_cb).sem, 0) != ERR_OK) {
+        /* failed to create semaphore */
+        set_errno(ENOMEM);
+        lwip_select_dec_sockets_used(maxfdp1, &used_sockets);
+        API_SELECT_CB_VAR_FREE(select_cb);
+        return -1;
+      }
+#endif /* LWIP_NETCONN_SEM_PER_THREAD */
+
+      lwip_link_select_cb(&API_SELECT_CB_VAR_REF(select_cb));
+
+      /* Increase select_waiting for each socket we are interested in */
+      maxfdp2 = maxfdp1;
+      for (i = LWIP_SOCKET_OFFSET; i < maxfdp1; i++) {
+        if ((readset && FD_ISSET(i, readset)) ||
+            (writeset && FD_ISSET(i, writeset)) ||
+            (exceptset && FD_ISSET(i, exceptset))) {
+          struct lwip_sock *sock;
+          SYS_ARCH_PROTECT(lev);
+          sock = tryget_socket_unconn_locked(i);
+          if (sock != NULL) {
+            sock->select_waiting++;
+            if (sock->select_waiting == 0) {
+              /* overflow - too many threads waiting */
+              sock->select_waiting--;
+              nready = -1;
+              maxfdp2 = i;
+              SYS_ARCH_UNPROTECT(lev);
+              done_socket(sock);
+              set_errno(EBUSY);
+              break;
+            }
+            SYS_ARCH_UNPROTECT(lev);
+            done_socket(sock);
+          } else {
+            /* Not a valid socket */
+            nready = -1;
+            maxfdp2 = i;
+            SYS_ARCH_UNPROTECT(lev);
+            set_errno(EBADF);
+            break;
+          }
+        }
+      }
+
+      if (nready >= 0) {
+        /* Call lwip_selscan again: there could have been events between
+           the last scan (without us on the list) and putting us on the list! */
+        nready = lwip_selscan(maxfdp1, readset, writeset, exceptset, &lreadset, &lwriteset, &lexceptset);
+        if (!nready) {
+          /* Still none ready, just wait to be woken */
+          if (timeout == 0) {
+            /* Wait forever */
+            msectimeout = 0;
+          } else {
+            long msecs_long = ((timeout->tv_sec * 1000) + ((timeout->tv_usec + 500) / 1000));
+            if (msecs_long <= 0) {
+              /* Wait 1ms at least (0 means wait forever) */
+              msectimeout = 1;
+            } else {
+              msectimeout = (u32_t)msecs_long;
+            }
+          }
+
+          waitres = sys_arch_sem_wait(SELECT_SEM_PTR(API_SELECT_CB_VAR_REF(select_cb).sem), msectimeout);
+#if LWIP_NETCONN_SEM_PER_THREAD
+          waited = 1;
+#endif
+        }
+      }
+
+      /* Decrease select_waiting for each socket we are interested in */
+      for (i = LWIP_SOCKET_OFFSET; i < maxfdp2; i++) {
+        if ((readset && FD_ISSET(i, readset)) ||
+            (writeset && FD_ISSET(i, writeset)) ||
+            (exceptset && FD_ISSET(i, exceptset))) {
+          struct lwip_sock *sock;
+          SYS_ARCH_PROTECT(lev);
+          sock = tryget_socket_unconn_locked(i);
+          if (sock != NULL) {
+            /* for now, handle select_waiting==0... */
+            LWIP_ASSERT("sock->select_waiting > 0", sock->select_waiting > 0);
+            if (sock->select_waiting > 0) {
+              sock->select_waiting--;
+            }
+            SYS_ARCH_UNPROTECT(lev);
+            done_socket(sock);
+          } else {
+            SYS_ARCH_UNPROTECT(lev);
+            /* Not a valid socket */
+            nready = -1;
+            set_errno(EBADF);
+          }
+        }
+      }
+
+      lwip_unlink_select_cb(&API_SELECT_CB_VAR_REF(select_cb));
+
+#if LWIP_NETCONN_SEM_PER_THREAD
+      if (API_SELECT_CB_VAR_REF(select_cb).sem_signalled && (!waited || (waitres == SYS_ARCH_TIMEOUT))) {
+        /* don't leave the thread-local semaphore signalled */
+        sys_arch_sem_wait(API_SELECT_CB_VAR_REF(select_cb).sem, 1);
+      }
+#else /* LWIP_NETCONN_SEM_PER_THREAD */
+      sys_sem_free(&API_SELECT_CB_VAR_REF(select_cb).sem);
+#endif /* LWIP_NETCONN_SEM_PER_THREAD */
+      API_SELECT_CB_VAR_FREE(select_cb);
+
+      if (nready < 0) {
+        /* This happens when a socket got closed while waiting */
+        lwip_select_dec_sockets_used(maxfdp1, &used_sockets);
+        return -1;
+      }
+
+      if (waitres == SYS_ARCH_TIMEOUT) {
+        /* Timeout */
+        LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_select: timeout expired\n"));
+        /* This is OK as the local fdsets are empty and nready is zero,
+           or we would have returned earlier. */
+      } else {
+        /* See what's set now after waiting */
+        nready = lwip_selscan(maxfdp1, readset, writeset, exceptset, &lreadset, &lwriteset, &lexceptset);
+        LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_select: nready=%d\n", nready));
+      }
+    }
+  }
+
+  lwip_select_dec_sockets_used(maxfdp1, &used_sockets);
+  set_errno(0);
+  if (readset) {
+    *readset = lreadset;
+  }
+  if (writeset) {
+    *writeset = lwriteset;
+  }
+  if (exceptset) {
+    *exceptset = lexceptset;
+  }
+  return nready;
+}
+#endif /* LWIP_SOCKET_SELECT */
+
+#if LWIP_SOCKET_POLL
+/** Options for the lwip_pollscan function. */
+enum lwip_pollscan_opts
+{
+  /** Clear revents in each struct pollfd. */
+  LWIP_POLLSCAN_CLEAR = 1,
+
+  /** Increment select_waiting in each struct lwip_sock. */
+  LWIP_POLLSCAN_INC_WAIT = 2,
+
+  /** Decrement select_waiting in each struct lwip_sock. */
+  LWIP_POLLSCAN_DEC_WAIT = 4
+};
+
+/**
+ * Update revents in each struct pollfd.
+ * Optionally update select_waiting in struct lwip_sock.
+ *
+ * @param fds          array of structures to update
+ * @param nfds         number of structures in fds
+ * @param opts         what to update and how
+ * @return number of structures that have revents != 0
+ */
+static int
+lwip_pollscan(struct pollfd *fds, nfds_t nfds, enum lwip_pollscan_opts opts)
+{
+  int nready = 0;
+  nfds_t fdi;
+  struct lwip_sock *sock;
+  SYS_ARCH_DECL_PROTECT(lev);
+
+  /* Go through each struct pollfd in the array. */
+  for (fdi = 0; fdi < nfds; fdi++) {
+    if ((opts & LWIP_POLLSCAN_CLEAR) != 0) {
+      fds[fdi].revents = 0;
+    }
+
+    /* Negative fd means the caller wants us to ignore this struct.
+       POLLNVAL means we already detected that the fd is invalid;
+       if another thread has since opened a new socket with that fd,
+       we must not use that socket. */
+    if (fds[fdi].fd >= 0 && (fds[fdi].revents & POLLNVAL) == 0) {
+      /* First get the socket's status (protected)... */
+      SYS_ARCH_PROTECT(lev);
+      sock = tryget_socket_unconn_locked(fds[fdi].fd);
+      if (sock != NULL) {
+        void* lastdata = sock->lastdata.pbuf;
+        s16_t rcvevent = sock->rcvevent;
+        u16_t sendevent = sock->sendevent;
+        u16_t errevent = sock->errevent;
+
+        if ((opts & LWIP_POLLSCAN_INC_WAIT) != 0) {
+          sock->select_waiting++;
+          if (sock->select_waiting == 0) {
+            /* overflow - too many threads waiting */
+            sock->select_waiting--;
+            nready = -1;
+            SYS_ARCH_UNPROTECT(lev);
+            done_socket(sock);
+            break;
+          }
+        } else if ((opts & LWIP_POLLSCAN_DEC_WAIT) != 0) {
+          /* for now, handle select_waiting==0... */
+          LWIP_ASSERT("sock->select_waiting > 0", sock->select_waiting > 0);
+          if (sock->select_waiting > 0) {
+            sock->select_waiting--;
+          }
+        }
+        SYS_ARCH_UNPROTECT(lev);
+        done_socket(sock);
+
+        /* ... then examine it: */
+        /* See if netconn of this socket is ready for read */
+        if ((fds[fdi].events & POLLIN) != 0 && ((lastdata != NULL) || (rcvevent > 0))) {
+          fds[fdi].revents |= POLLIN;
+          LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_pollscan: fd=%d ready for reading\n", fds[fdi].fd));
+        }
+        /* See if netconn of this socket is ready for write */
+        if ((fds[fdi].events & POLLOUT) != 0 && (sendevent != 0)) {
+          fds[fdi].revents |= POLLOUT;
+          LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_pollscan: fd=%d ready for writing\n", fds[fdi].fd));
+        }
+        /* See if netconn of this socket had an error */
+        if (errevent != 0) {
+          /* POLLERR is output only. */
+          fds[fdi].revents |= POLLERR;
+          LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_pollscan: fd=%d ready for exception\n", fds[fdi].fd));
+        }
+      } else {
+        /* Not a valid socket */
+        SYS_ARCH_UNPROTECT(lev);
+        /* POLLNVAL is output only. */
+        fds[fdi].revents |= POLLNVAL;
+        return -1;
+      }
+    }
+
+    /* Will return the number of structures that have events,
+       not the number of events. */
+    if (fds[fdi].revents != 0) {
+      nready++;
+    }
+  }
+
+  LWIP_ASSERT("nready >= 0", nready >= 0);
+  return nready;
+}
+
+#if LWIP_NETCONN_FULLDUPLEX
+/* Mark all sockets as used.
+ *
+ * All sockets are marked (and later unmarked), whether they are open or not.
+ * This is OK as lwip_pollscan aborts select when non-open sockets are found.
+ */
+static void
+lwip_poll_inc_sockets_used(struct pollfd *fds, nfds_t nfds)
+{
+  nfds_t fdi;
+
+  if(fds) {
+    /* Go through each struct pollfd in the array. */
+    for (fdi = 0; fdi < nfds; fdi++) {
+      /* Increase the reference counter */
+      tryget_socket_unconn(fds[fdi].fd);
+    }
+  }
+}
+
+/* Let go all sockets that were marked as used when starting poll */
+static void
+lwip_poll_dec_sockets_used(struct pollfd *fds, nfds_t nfds)
+{
+  nfds_t fdi;
+
+  if(fds) {
+    /* Go through each struct pollfd in the array. */
+    for (fdi = 0; fdi < nfds; fdi++) {
+      struct lwip_sock *sock = tryget_socket_unconn_nouse(fds[fdi].fd);
+      if (sock != NULL) {
+        done_socket(sock);
+      }
+    }
+  }
+}
+#else /* LWIP_NETCONN_FULLDUPLEX */
+#define lwip_poll_inc_sockets_used(fds, nfds)
+#define lwip_poll_dec_sockets_used(fds, nfds)
+#endif /* LWIP_NETCONN_FULLDUPLEX */
+
+int
+lwip_poll(struct pollfd *fds, nfds_t nfds, int timeout)
+{
+  u32_t waitres = 0;
+  int nready;
+  u32_t msectimeout;
+#if LWIP_NETCONN_SEM_PER_THREAD
+  int waited = 0;
+#endif
+
+  LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_poll(%p, %d, %d)\n",
+                  (void*)fds, (int)nfds, timeout));
+  LWIP_ERROR("lwip_poll: invalid fds", ((fds != NULL && nfds > 0) || (fds == NULL && nfds == 0)),
+             set_errno(EINVAL); return -1;);
+
+  lwip_poll_inc_sockets_used(fds, nfds);
+
+  /* Go through each struct pollfd to count number of structures
+     which currently match */
+  nready = lwip_pollscan(fds, nfds, LWIP_POLLSCAN_CLEAR);
+
+  if (nready < 0) {
+    lwip_poll_dec_sockets_used(fds, nfds);
+    return -1;
+  }
+
+  /* If we don't have any current events, then suspend if we are supposed to */
+  if (!nready) {
+    API_SELECT_CB_VAR_DECLARE(select_cb);
+
+    if (timeout == 0) {
+      LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_poll: no timeout, returning 0\n"));
+      goto return_success;
+    }
+    API_SELECT_CB_VAR_ALLOC(select_cb, set_errno(EAGAIN); lwip_poll_dec_sockets_used(fds, nfds); return -1);
+    memset(&API_SELECT_CB_VAR_REF(select_cb), 0, sizeof(struct lwip_select_cb));
+
+    /* None ready: add our semaphore to list:
+       We don't actually need any dynamic memory. Our entry on the
+       list is only valid while we are in this function, so it's ok
+       to use local variables. */
+
+    API_SELECT_CB_VAR_REF(select_cb).poll_fds = fds;
+    API_SELECT_CB_VAR_REF(select_cb).poll_nfds = nfds;
+#if LWIP_NETCONN_SEM_PER_THREAD
+    API_SELECT_CB_VAR_REF(select_cb).sem = LWIP_NETCONN_THREAD_SEM_GET();
+#else /* LWIP_NETCONN_SEM_PER_THREAD */
+    if (sys_sem_new(&API_SELECT_CB_VAR_REF(select_cb).sem, 0) != ERR_OK) {
+      /* failed to create semaphore */
+      set_errno(EAGAIN);
+      lwip_poll_dec_sockets_used(fds, nfds);
+      API_SELECT_CB_VAR_FREE(select_cb);
+      return -1;
+    }
+#endif /* LWIP_NETCONN_SEM_PER_THREAD */
+
+    lwip_link_select_cb(&API_SELECT_CB_VAR_REF(select_cb));
+
+    /* Increase select_waiting for each socket we are interested in.
+       Also, check for events again: there could have been events between
+       the last scan (without us on the list) and putting us on the list! */
+    nready = lwip_pollscan(fds, nfds, LWIP_POLLSCAN_INC_WAIT);
+
+    if (!nready) {
+      /* Still none ready, just wait to be woken */
+      if (timeout < 0) {
+        /* Wait forever */
+        msectimeout = 0;
+      } else {
+        /* timeout == 0 would have been handled earlier. */
+        LWIP_ASSERT("timeout > 0", timeout > 0);
+        msectimeout = timeout;
+      }
+      waitres = sys_arch_sem_wait(SELECT_SEM_PTR(API_SELECT_CB_VAR_REF(select_cb).sem), msectimeout);
+#if LWIP_NETCONN_SEM_PER_THREAD
+      waited = 1;
+#endif
+    }
+
+    /* Decrease select_waiting for each socket we are interested in,
+       and check which events occurred while we waited. */
+    nready = lwip_pollscan(fds, nfds, LWIP_POLLSCAN_DEC_WAIT);
+
+    lwip_unlink_select_cb(&API_SELECT_CB_VAR_REF(select_cb));
+
+#if LWIP_NETCONN_SEM_PER_THREAD
+    if (select_cb.sem_signalled && (!waited || (waitres == SYS_ARCH_TIMEOUT))) {
+      /* don't leave the thread-local semaphore signalled */
+      sys_arch_sem_wait(API_SELECT_CB_VAR_REF(select_cb).sem, 1);
+    }
+#else /* LWIP_NETCONN_SEM_PER_THREAD */
+    sys_sem_free(&API_SELECT_CB_VAR_REF(select_cb).sem);
+#endif /* LWIP_NETCONN_SEM_PER_THREAD */
+    API_SELECT_CB_VAR_FREE(select_cb);
+
+    if (nready < 0) {
+      /* This happens when a socket got closed while waiting */
+      lwip_poll_dec_sockets_used(fds, nfds);
+      return -1;
+    }
+
+    if (waitres == SYS_ARCH_TIMEOUT) {
+      /* Timeout */
+      LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_poll: timeout expired\n"));
+      goto return_success;
+    }
+  }
+
+  LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_poll: nready=%d\n", nready));
+return_success:
+  lwip_poll_dec_sockets_used(fds, nfds);
+  set_errno(0);
+  return nready;
+}
+
+/**
+ * Check whether event_callback should wake up a thread waiting in
+ * lwip_poll.
+ */
+static int
+lwip_poll_should_wake(const struct lwip_select_cb *scb, int fd, int has_recvevent, int has_sendevent, int has_errevent)
+{
+  nfds_t fdi;
+  for (fdi = 0; fdi < scb->poll_nfds; fdi++) {
+    const struct pollfd *pollfd = &scb->poll_fds[fdi];
+    if (pollfd->fd == fd) {
+      /* Do not update pollfd->revents right here;
+         that would be a data race because lwip_pollscan
+         accesses revents without protecting. */
+      if (has_recvevent && (pollfd->events & POLLIN) != 0) {
+        return 1;
+      }
+      if (has_sendevent && (pollfd->events & POLLOUT) != 0) {
+        return 1;
+      }
+      if (has_errevent) {
+        /* POLLERR is output only. */
+        return 1;
+      }
+    }
+  }
+  return 0;
+}
+#endif /* LWIP_SOCKET_POLL */
+
+#if LWIP_SOCKET_SELECT || LWIP_SOCKET_POLL
+/**
+ * Callback registered in the netconn layer for each socket-netconn.
+ * Processes recvevent (data available) and wakes up tasks waiting for select.
+ *
+ * @note for LWIP_TCPIP_CORE_LOCKING any caller of this function
+ * must have the core lock held when signaling the following events
+ * as they might cause select_list_cb to be checked:
+ *   NETCONN_EVT_RCVPLUS
+ *   NETCONN_EVT_SENDPLUS
+ *   NETCONN_EVT_ERROR
+ * This requirement will be asserted in select_check_waiters()
+ */
+static void
+event_callback(struct netconn *conn, enum netconn_evt evt, u16_t len)
+{
+  int s, check_waiters;
+  struct lwip_sock *sock;
+  SYS_ARCH_DECL_PROTECT(lev);
+
+  LWIP_UNUSED_ARG(len);
+
+  /* Get socket */
+  if (conn) {
+    s = conn->socket;
+    if (s < 0) {
+      /* Data comes in right away after an accept, even though
+       * the server task might not have created a new socket yet.
+       * Just count down (or up) if that's the case and we
+       * will use the data later. Note that only receive events
+       * can happen before the new socket is set up. */
+      SYS_ARCH_PROTECT(lev);
+      if (conn->socket < 0) {
+        if (evt == NETCONN_EVT_RCVPLUS) {
+          /* conn->socket is -1 on initialization
+             lwip_accept adjusts sock->recvevent if conn->socket < -1 */
+          conn->socket--;
+        }
+        SYS_ARCH_UNPROTECT(lev);
+        return;
+      }
+      s = conn->socket;
+      SYS_ARCH_UNPROTECT(lev);
+    }
+
+    sock = get_socket(s);
+    if (!sock) {
+      return;
+    }
+  } else {
+    return;
+  }
+
+  check_waiters = 1;
+  SYS_ARCH_PROTECT(lev);
+  /* Set event as required */
+  switch (evt) {
+    case NETCONN_EVT_RCVPLUS:
+      sock->rcvevent++;
+      if (sock->rcvevent > 1) {
+        check_waiters = 0;
+      }
+      break;
+    case NETCONN_EVT_RCVMINUS:
+      sock->rcvevent--;
+      check_waiters = 0;
+      break;
+    case NETCONN_EVT_SENDPLUS:
+      if (sock->sendevent) {
+        check_waiters = 0;
+      }
+      sock->sendevent = 1;
+      break;
+    case NETCONN_EVT_SENDMINUS:
+      sock->sendevent = 0;
+      check_waiters = 0;
+      break;
+    case NETCONN_EVT_ERROR:
+      sock->errevent = 1;
+      break;
+    default:
+      LWIP_ASSERT("unknown event", 0);
+      break;
+  }
+
+  if (sock->select_waiting && check_waiters) {
+    /* Save which events are active */
+    int has_recvevent, has_sendevent, has_errevent;
+    has_recvevent = sock->rcvevent > 0;
+    has_sendevent = sock->sendevent != 0;
+    has_errevent = sock->errevent != 0;
+    SYS_ARCH_UNPROTECT(lev);
+    /* Check any select calls waiting on this socket */
+    select_check_waiters(s, has_recvevent, has_sendevent, has_errevent);
+  } else {
+    SYS_ARCH_UNPROTECT(lev);
+  }
+  done_socket(sock);
+}
+
+/**
+ * Check if any select waiters are waiting on this socket and its events
+ *
+ * @note on synchronization of select_cb_list:
+ * LWIP_TCPIP_CORE_LOCKING: the select_cb_list must only be accessed while holding
+ * the core lock. We do a single pass through the list and signal any waiters.
+ * Core lock should already be held when calling here!!!!
+
+ * !LWIP_TCPIP_CORE_LOCKING: we use SYS_ARCH_PROTECT but unlock on each iteration
+ * of the loop, thus creating a possibility where a thread could modify the
+ * select_cb_list during our UNPROTECT/PROTECT. We use a generational counter to
+ * detect this change and restart the list walk. The list is expected to be small
+ */
+static void select_check_waiters(int s, int has_recvevent, int has_sendevent, int has_errevent)
+{
+  struct lwip_select_cb *scb;
+#if !LWIP_TCPIP_CORE_LOCKING
+  int last_select_cb_ctr;
+  SYS_ARCH_DECL_PROTECT(lev);
+#endif /* !LWIP_TCPIP_CORE_LOCKING */
+
+  LWIP_ASSERT_CORE_LOCKED();
+
+#if !LWIP_TCPIP_CORE_LOCKING
+  SYS_ARCH_PROTECT(lev);
+again:
+  /* remember the state of select_cb_list to detect changes */
+  last_select_cb_ctr = select_cb_ctr;
+#endif /* !LWIP_TCPIP_CORE_LOCKING */
+  for (scb = select_cb_list; scb != NULL; scb = scb->next) {
+    if (scb->sem_signalled == 0) {
+      /* semaphore not signalled yet */
+      int do_signal = 0;
+#if LWIP_SOCKET_POLL
+      if (scb->poll_fds != NULL) {
+        do_signal = lwip_poll_should_wake(scb, s, has_recvevent, has_sendevent, has_errevent);
+      }
+#endif /* LWIP_SOCKET_POLL */
+#if LWIP_SOCKET_SELECT && LWIP_SOCKET_POLL
+      else
+#endif /* LWIP_SOCKET_SELECT && LWIP_SOCKET_POLL */
+#if LWIP_SOCKET_SELECT
+      {
+        /* Test this select call for our socket */
+        if (has_recvevent) {
+          if (scb->readset && FD_ISSET(s, scb->readset)) {
+            do_signal = 1;
+          }
+        }
+        if (has_sendevent) {
+          if (!do_signal && scb->writeset && FD_ISSET(s, scb->writeset)) {
+            do_signal = 1;
+          }
+        }
+        if (has_errevent) {
+          if (!do_signal && scb->exceptset && FD_ISSET(s, scb->exceptset)) {
+            do_signal = 1;
+          }
+        }
+      }
+#endif /* LWIP_SOCKET_SELECT */
+      if (do_signal) {
+        scb->sem_signalled = 1;
+        /* For !LWIP_TCPIP_CORE_LOCKING, we don't call SYS_ARCH_UNPROTECT() before signaling
+           the semaphore, as this might lead to the select thread taking itself off the list,
+           invalidating the semaphore. */
+        sys_sem_signal(SELECT_SEM_PTR(scb->sem));
+      }
+    }
+#if LWIP_TCPIP_CORE_LOCKING
+  }
+#else
+    /* unlock interrupts with each step */
+    SYS_ARCH_UNPROTECT(lev);
+    /* this makes sure interrupt protection time is short */
+    SYS_ARCH_PROTECT(lev);
+    if (last_select_cb_ctr != select_cb_ctr) {
+      /* someone has changed select_cb_list, restart at the beginning */
+      goto again;
+    }
+    /* remember the state of select_cb_list to detect changes */
+    last_select_cb_ctr = select_cb_ctr;
+  }
+  SYS_ARCH_UNPROTECT(lev);
+#endif
+}
+#endif /* LWIP_SOCKET_SELECT || LWIP_SOCKET_POLL */
+
+/**
+ * Close one end of a full-duplex connection.
+ */
+int
+lwip_shutdown(int s, int how)
+{
+  struct lwip_sock *sock;
+  err_t err;
+  u8_t shut_rx = 0, shut_tx = 0;
+
+  LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_shutdown(%d, how=%d)\n", s, how));
+
+  sock = get_socket(s);
+  if (!sock) {
+    return -1;
+  }
+
+  if (sock->conn != NULL) {
+    if (NETCONNTYPE_GROUP(netconn_type(sock->conn)) != NETCONN_TCP) {
+      sock_set_errno(sock, EOPNOTSUPP);
+      done_socket(sock);
+      return -1;
+    }
+  } else {
+    sock_set_errno(sock, ENOTCONN);
+    done_socket(sock);
+    return -1;
+  }
+
+  if (how == SHUT_RD) {
+    shut_rx = 1;
+  } else if (how == SHUT_WR) {
+    shut_tx = 1;
+  } else if (how == SHUT_RDWR) {
+    shut_rx = 1;
+    shut_tx = 1;
+  } else {
+    sock_set_errno(sock, EINVAL);
+    done_socket(sock);
+    return -1;
+  }
+  err = netconn_shutdown(sock->conn, shut_rx, shut_tx);
+
+  sock_set_errno(sock, err_to_errno(err));
+  done_socket(sock);
+  return (err == ERR_OK ? 0 : -1);
+}
+
+static int
+lwip_getaddrname(int s, struct sockaddr *name, socklen_t *namelen, u8_t local)
+{
+  struct lwip_sock *sock;
+  union sockaddr_aligned saddr;
+  ip_addr_t naddr;
+  u16_t port;
+  err_t err;
+
+  sock = get_socket(s);
+  if (!sock) {
+    return -1;
+  }
+
+  /* get the IP address and port */
+  err = netconn_getaddr(sock->conn, &naddr, &port, local);
+  if (err != ERR_OK) {
+    sock_set_errno(sock, err_to_errno(err));
+    done_socket(sock);
+    return -1;
+  }
+
+#if LWIP_IPV4 && LWIP_IPV6
+  /* Dual-stack: Map IPv4 addresses to IPv4 mapped IPv6 */
+  if (NETCONNTYPE_ISIPV6(netconn_type(sock->conn)) &&
+      IP_IS_V4_VAL(naddr)) {
+    ip4_2_ipv4_mapped_ipv6(ip_2_ip6(&naddr), ip_2_ip4(&naddr));
+    IP_SET_TYPE_VAL(naddr, IPADDR_TYPE_V6);
+  }
+#endif /* LWIP_IPV4 && LWIP_IPV6 */
+
+  IPADDR_PORT_TO_SOCKADDR(&saddr, &naddr, port);
+
+  LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getaddrname(%d, addr=", s));
+  ip_addr_debug_print_val(SOCKETS_DEBUG, naddr);
+  LWIP_DEBUGF(SOCKETS_DEBUG, (" port=%"U16_F")\n", port));
+
+  if (*namelen > saddr.sa.sa_len) {
+    *namelen = saddr.sa.sa_len;
+  }
+  MEMCPY(name, &saddr, *namelen);
+
+  sock_set_errno(sock, 0);
+  done_socket(sock);
+  return 0;
+}
+
+int
+lwip_getpeername(int s, struct sockaddr *name, socklen_t *namelen)
+{
+  return lwip_getaddrname(s, name, namelen, 0);
+}
+
+int
+lwip_getsockname(int s, struct sockaddr *name, socklen_t *namelen)
+{
+  return lwip_getaddrname(s, name, namelen, 1);
+}
+
+int
+lwip_getsockopt(int s, int level, int optname, void *optval, socklen_t *optlen)
+{
+  int err;
+  struct lwip_sock *sock = get_socket(s);
+#if !LWIP_TCPIP_CORE_LOCKING
+  err_t cberr;
+  LWIP_SETGETSOCKOPT_DATA_VAR_DECLARE(data);
+#endif /* !LWIP_TCPIP_CORE_LOCKING */
+
+  if (!sock) {
+    return -1;
+  }
+
+  if ((NULL == optval) || (NULL == optlen)) {
+    sock_set_errno(sock, EFAULT);
+    done_socket(sock);
+    return -1;
+  }
+
+#if LWIP_TCPIP_CORE_LOCKING
+  /* core-locking can just call the -impl function */
+  LOCK_TCPIP_CORE();
+  err = lwip_getsockopt_impl(s, level, optname, optval, optlen);
+  UNLOCK_TCPIP_CORE();
+
+#else /* LWIP_TCPIP_CORE_LOCKING */
+
+#if LWIP_MPU_COMPATIBLE
+  /* MPU_COMPATIBLE copies the optval data, so check for max size here */
+  if (*optlen > LWIP_SETGETSOCKOPT_MAXOPTLEN) {
+    sock_set_errno(sock, ENOBUFS);
+    done_socket(sock);
+    return -1;
+  }
+#endif /* LWIP_MPU_COMPATIBLE */
+
+  LWIP_SETGETSOCKOPT_DATA_VAR_ALLOC(data, sock);
+  LWIP_SETGETSOCKOPT_DATA_VAR_REF(data).s = s;
+  LWIP_SETGETSOCKOPT_DATA_VAR_REF(data).level = level;
+  LWIP_SETGETSOCKOPT_DATA_VAR_REF(data).optname = optname;
+  LWIP_SETGETSOCKOPT_DATA_VAR_REF(data).optlen = *optlen;
+#if !LWIP_MPU_COMPATIBLE
+  LWIP_SETGETSOCKOPT_DATA_VAR_REF(data).optval.p = optval;
+#endif /* !LWIP_MPU_COMPATIBLE */
+  LWIP_SETGETSOCKOPT_DATA_VAR_REF(data).err = 0;
+#if LWIP_NETCONN_SEM_PER_THREAD
+  LWIP_SETGETSOCKOPT_DATA_VAR_REF(data).completed_sem = LWIP_NETCONN_THREAD_SEM_GET();
+#else
+  LWIP_SETGETSOCKOPT_DATA_VAR_REF(data).completed_sem = &sock->conn->op_completed;
+#endif
+  cberr = tcpip_callback(lwip_getsockopt_callback, &LWIP_SETGETSOCKOPT_DATA_VAR_REF(data));
+  if (cberr != ERR_OK) {
+    LWIP_SETGETSOCKOPT_DATA_VAR_FREE(data);
+    sock_set_errno(sock, err_to_errno(cberr));
+    done_socket(sock);
+    return -1;
+  }
+  sys_arch_sem_wait((sys_sem_t *)(LWIP_SETGETSOCKOPT_DATA_VAR_REF(data).completed_sem), 0);
+
+  /* write back optlen and optval */
+  *optlen = LWIP_SETGETSOCKOPT_DATA_VAR_REF(data).optlen;
+#if LWIP_MPU_COMPATIBLE
+  MEMCPY(optval, LWIP_SETGETSOCKOPT_DATA_VAR_REF(data).optval,
+         LWIP_SETGETSOCKOPT_DATA_VAR_REF(data).optlen);
+#endif /* LWIP_MPU_COMPATIBLE */
+
+  /* maybe lwip_getsockopt_internal has changed err */
+  err = LWIP_SETGETSOCKOPT_DATA_VAR_REF(data).err;
+  LWIP_SETGETSOCKOPT_DATA_VAR_FREE(data);
+#endif /* LWIP_TCPIP_CORE_LOCKING */
+
+  sock_set_errno(sock, err);
+  done_socket(sock);
+  return err ? -1 : 0;
+}
+
+#if !LWIP_TCPIP_CORE_LOCKING
+/** lwip_getsockopt_callback: only used without CORE_LOCKING
+ * to get into the tcpip_thread
+ */
+static void
+lwip_getsockopt_callback(void *arg)
+{
+  struct lwip_setgetsockopt_data *data;
+  LWIP_ASSERT("arg != NULL", arg != NULL);
+  data = (struct lwip_setgetsockopt_data *)arg;
+
+  data->err = lwip_getsockopt_impl(data->s, data->level, data->optname,
+#if LWIP_MPU_COMPATIBLE
+                                   data->optval,
+#else /* LWIP_MPU_COMPATIBLE */
+                                   data->optval.p,
+#endif /* LWIP_MPU_COMPATIBLE */
+                                   &data->optlen);
+
+  sys_sem_signal((sys_sem_t *)(data->completed_sem));
+}
+#endif  /* LWIP_TCPIP_CORE_LOCKING */
+
+static int
+lwip_sockopt_to_ipopt(int optname)
+{
+  /* Map SO_* values to our internal SOF_* values
+   * We should not rely on #defines in socket.h
+   * being in sync with ip.h.
+   */
+  switch (optname) {
+  case SO_BROADCAST:
+    return SOF_BROADCAST;
+  case SO_KEEPALIVE:
+    return SOF_KEEPALIVE;
+  case SO_REUSEADDR:
+    return SOF_REUSEADDR;
+  default:
+    LWIP_ASSERT("Unknown socket option", 0);
+    return 0;
+  }
+}
+
+/** lwip_getsockopt_impl: the actual implementation of getsockopt:
+ * same argument as lwip_getsockopt, either called directly or through callback
+ */
+static int
+lwip_getsockopt_impl(int s, int level, int optname, void *optval, socklen_t *optlen)
+{
+  int err = 0;
+  struct lwip_sock *sock = tryget_socket(s);
+  if (!sock) {
+    return EBADF;
+  }
+
+#ifdef LWIP_HOOK_SOCKETS_GETSOCKOPT
+  if (LWIP_HOOK_SOCKETS_GETSOCKOPT(s, sock, level, optname, optval, optlen, &err)) {
+    return err;
+  }
+#endif
+
+  switch (level) {
+
+    /* Level: SOL_SOCKET */
+    case SOL_SOCKET:
+      switch (optname) {
+
+#if LWIP_TCP
+        case SO_ACCEPTCONN:
+          LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB(sock, *optlen, int);
+          if (NETCONNTYPE_GROUP(sock->conn->type) != NETCONN_TCP) {
+            done_socket(sock);
+            return ENOPROTOOPT;
+          }
+          if ((sock->conn->pcb.tcp != NULL) && (sock->conn->pcb.tcp->state == LISTEN)) {
+            *(int *)optval = 1;
+          } else {
+            *(int *)optval = 0;
+          }
+          break;
+#endif /* LWIP_TCP */
+
+        /* The option flags */
+        case SO_BROADCAST:
+        case SO_KEEPALIVE:
+#if SO_REUSE
+        case SO_REUSEADDR:
+#endif /* SO_REUSE */
+          if ((optname == SO_BROADCAST) &&
+              (NETCONNTYPE_GROUP(sock->conn->type) != NETCONN_UDP)) {
+            done_socket(sock);
+            return ENOPROTOOPT;
+          }
+
+          optname = lwip_sockopt_to_ipopt(optname);
+
+          LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB(sock, *optlen, int);
+          *(int *)optval = ip_get_option(sock->conn->pcb.ip, optname);
+          LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, SOL_SOCKET, optname=0x%x, ..) = %s\n",
+                                      s, optname, (*(int *)optval ? "on" : "off")));
+          break;
+
+        case SO_TYPE:
+          LWIP_SOCKOPT_CHECK_OPTLEN_CONN(sock, *optlen, int);
+          switch (NETCONNTYPE_GROUP(netconn_type(sock->conn))) {
+            case NETCONN_RAW:
+              *(int *)optval = SOCK_RAW;
+              break;
+            case NETCONN_TCP:
+              *(int *)optval = SOCK_STREAM;
+              break;
+            case NETCONN_UDP:
+              *(int *)optval = SOCK_DGRAM;
+              break;
+            default: /* unrecognized socket type */
+              *(int *)optval = netconn_type(sock->conn);
+              LWIP_DEBUGF(SOCKETS_DEBUG,
+                          ("lwip_getsockopt(%d, SOL_SOCKET, SO_TYPE): unrecognized socket type %d\n",
+                           s, *(int *)optval));
+          }  /* switch (netconn_type(sock->conn)) */
+          LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, SOL_SOCKET, SO_TYPE) = %d\n",
+                                      s, *(int *)optval));
+          break;
+
+        case SO_ERROR:
+          LWIP_SOCKOPT_CHECK_OPTLEN(sock, *optlen, int);
+          *(int *)optval = err_to_errno(netconn_err(sock->conn));
+          LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, SOL_SOCKET, SO_ERROR) = %d\n",
+                                      s, *(int *)optval));
+          break;
+
+#if LWIP_SO_SNDTIMEO
+        case SO_SNDTIMEO:
+          LWIP_SOCKOPT_CHECK_OPTLEN_CONN(sock, *optlen, LWIP_SO_SNDRCVTIMEO_OPTTYPE);
+          LWIP_SO_SNDRCVTIMEO_SET(optval, netconn_get_sendtimeout(sock->conn));
+          break;
+#endif /* LWIP_SO_SNDTIMEO */
+#if LWIP_SO_RCVTIMEO
+        case SO_RCVTIMEO:
+          LWIP_SOCKOPT_CHECK_OPTLEN_CONN(sock, *optlen, LWIP_SO_SNDRCVTIMEO_OPTTYPE);
+          LWIP_SO_SNDRCVTIMEO_SET(optval, netconn_get_recvtimeout(sock->conn));
+          break;
+#endif /* LWIP_SO_RCVTIMEO */
+#if LWIP_SO_RCVBUF
+        case SO_RCVBUF:
+          LWIP_SOCKOPT_CHECK_OPTLEN_CONN(sock, *optlen, int);
+          *(int *)optval = netconn_get_recvbufsize(sock->conn);
+          break;
+#endif /* LWIP_SO_RCVBUF */
+#if LWIP_SO_LINGER
+        case SO_LINGER: {
+          s16_t conn_linger;
+          struct linger *linger = (struct linger *)optval;
+          LWIP_SOCKOPT_CHECK_OPTLEN_CONN(sock, *optlen, struct linger);
+          conn_linger = sock->conn->linger;
+          if (conn_linger >= 0) {
+            linger->l_onoff = 1;
+            linger->l_linger = (int)conn_linger;
+          } else {
+            linger->l_onoff = 0;
+            linger->l_linger = 0;
+          }
+        }
+        break;
+#endif /* LWIP_SO_LINGER */
+#if LWIP_UDP
+        case SO_NO_CHECK:
+          LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB_TYPE(sock, *optlen, int, NETCONN_UDP);
+#if LWIP_UDPLITE
+          if (udp_is_flag_set(sock->conn->pcb.udp, UDP_FLAGS_UDPLITE)) {
+            /* this flag is only available for UDP, not for UDP lite */
+            done_socket(sock);
+            return EAFNOSUPPORT;
+          }
+#endif /* LWIP_UDPLITE */
+          *(int *)optval = udp_is_flag_set(sock->conn->pcb.udp, UDP_FLAGS_NOCHKSUM) ? 1 : 0;
+          break;
+#endif /* LWIP_UDP*/
+        default:
+          LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, SOL_SOCKET, UNIMPL: optname=0x%x, ..)\n",
+                                      s, optname));
+          err = ENOPROTOOPT;
+          break;
+      }  /* switch (optname) */
+      break;
+
+    /* Level: IPPROTO_IP */
+    case IPPROTO_IP:
+      switch (optname) {
+        case IP_TTL:
+          LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB(sock, *optlen, int);
+          *(int *)optval = sock->conn->pcb.ip->ttl;
+          LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_IP, IP_TTL) = %d\n",
+                                      s, *(int *)optval));
+          break;
+        case IP_TOS:
+          LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB(sock, *optlen, int);
+          *(int *)optval = sock->conn->pcb.ip->tos;
+          LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_IP, IP_TOS) = %d\n",
+                                      s, *(int *)optval));
+          break;
+#if LWIP_IPV4 && LWIP_MULTICAST_TX_OPTIONS && LWIP_UDP
+        case IP_MULTICAST_TTL:
+          LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB(sock, *optlen, u8_t);
+          if (NETCONNTYPE_GROUP(netconn_type(sock->conn)) != NETCONN_UDP) {
+            done_socket(sock);
+            return ENOPROTOOPT;
+          }
+          *(u8_t *)optval = udp_get_multicast_ttl(sock->conn->pcb.udp);
+          LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_IP, IP_MULTICAST_TTL) = %d\n",
+                                      s, *(int *)optval));
+          break;
+        case IP_MULTICAST_IF:
+          LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB(sock, *optlen, struct in_addr);
+          if (NETCONNTYPE_GROUP(netconn_type(sock->conn)) != NETCONN_UDP) {
+            done_socket(sock);
+            return ENOPROTOOPT;
+          }
+          inet_addr_from_ip4addr((struct in_addr *)optval, udp_get_multicast_netif_addr(sock->conn->pcb.udp));
+          LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_IP, IP_MULTICAST_IF) = 0x%"X32_F"\n",
+                                      s, *(u32_t *)optval));
+          break;
+        case IP_MULTICAST_LOOP:
+          LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB(sock, *optlen, u8_t);
+          if ((sock->conn->pcb.udp->flags & UDP_FLAGS_MULTICAST_LOOP) != 0) {
+            *(u8_t *)optval = 1;
+          } else {
+            *(u8_t *)optval = 0;
+          }
+          LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_IP, IP_MULTICAST_LOOP) = %d\n",
+                                      s, *(int *)optval));
+          break;
+#endif /* LWIP_IPV4 && LWIP_MULTICAST_TX_OPTIONS && LWIP_UDP */
+        default:
+          LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_IP, UNIMPL: optname=0x%x, ..)\n",
+                                      s, optname));
+          err = ENOPROTOOPT;
+          break;
+      }  /* switch (optname) */
+      break;
+
+#if LWIP_TCP
+    /* Level: IPPROTO_TCP */
+    case IPPROTO_TCP:
+      /* Special case: all IPPROTO_TCP option take an int */
+      LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB_TYPE(sock, *optlen, int, NETCONN_TCP);
+      if (sock->conn->pcb.tcp->state == LISTEN) {
+        done_socket(sock);
+        return EINVAL;
+      }
+      switch (optname) {
+        case TCP_NODELAY:
+          *(int *)optval = tcp_nagle_disabled(sock->conn->pcb.tcp);
+          LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_TCP, TCP_NODELAY) = %s\n",
+                                      s, (*(int *)optval) ? "on" : "off") );
+          break;
+        case TCP_KEEPALIVE:
+          *(int *)optval = (int)sock->conn->pcb.tcp->keep_idle;
+          LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_TCP, TCP_KEEPALIVE) = %d\n",
+                                      s, *(int *)optval));
+          break;
+
+#if LWIP_TCP_KEEPALIVE
+        case TCP_KEEPIDLE:
+          *(int *)optval = (int)(sock->conn->pcb.tcp->keep_idle / 1000);
+          LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_TCP, TCP_KEEPIDLE) = %d\n",
+                                      s, *(int *)optval));
+          break;
+        case TCP_KEEPINTVL:
+          *(int *)optval = (int)(sock->conn->pcb.tcp->keep_intvl / 1000);
+          LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_TCP, TCP_KEEPINTVL) = %d\n",
+                                      s, *(int *)optval));
+          break;
+        case TCP_KEEPCNT:
+          *(int *)optval = (int)sock->conn->pcb.tcp->keep_cnt;
+          LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_TCP, TCP_KEEPCNT) = %d\n",
+                                      s, *(int *)optval));
+          break;
+#endif /* LWIP_TCP_KEEPALIVE */
+        default:
+          LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_TCP, UNIMPL: optname=0x%x, ..)\n",
+                                      s, optname));
+          err = ENOPROTOOPT;
+          break;
+      }  /* switch (optname) */
+      break;
+#endif /* LWIP_TCP */
+
+#if LWIP_IPV6
+    /* Level: IPPROTO_IPV6 */
+    case IPPROTO_IPV6:
+      switch (optname) {
+        case IPV6_V6ONLY:
+          LWIP_SOCKOPT_CHECK_OPTLEN_CONN(sock, *optlen, int);
+          *(int *)optval = (netconn_get_ipv6only(sock->conn) ? 1 : 0);
+          LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_IPV6, IPV6_V6ONLY) = %d\n",
+                                      s, *(int *)optval));
+          break;
+        default:
+          LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_IPV6, UNIMPL: optname=0x%x, ..)\n",
+                                      s, optname));
+          err = ENOPROTOOPT;
+          break;
+      }  /* switch (optname) */
+      break;
+#endif /* LWIP_IPV6 */
+
+#if LWIP_UDP && LWIP_UDPLITE
+    /* Level: IPPROTO_UDPLITE */
+    case IPPROTO_UDPLITE:
+      /* Special case: all IPPROTO_UDPLITE option take an int */
+      LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB(sock, *optlen, int);
+      /* If this is no UDP lite socket, ignore any options. */
+      if (!NETCONNTYPE_ISUDPLITE(netconn_type(sock->conn))) {
+        done_socket(sock);
+        return ENOPROTOOPT;
+      }
+      switch (optname) {
+        case UDPLITE_SEND_CSCOV:
+          *(int *)optval = sock->conn->pcb.udp->chksum_len_tx;
+          LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_UDPLITE, UDPLITE_SEND_CSCOV) = %d\n",
+                                      s, (*(int *)optval)) );
+          break;
+        case UDPLITE_RECV_CSCOV:
+          *(int *)optval = sock->conn->pcb.udp->chksum_len_rx;
+          LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_UDPLITE, UDPLITE_RECV_CSCOV) = %d\n",
+                                      s, (*(int *)optval)) );
+          break;
+        default:
+          LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_UDPLITE, UNIMPL: optname=0x%x, ..)\n",
+                                      s, optname));
+          err = ENOPROTOOPT;
+          break;
+      }  /* switch (optname) */
+      break;
+#endif /* LWIP_UDP */
+    /* Level: IPPROTO_RAW */
+    case IPPROTO_RAW:
+      switch (optname) {
+#if LWIP_IPV6 && LWIP_RAW
+        case IPV6_CHECKSUM:
+          LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB_TYPE(sock, *optlen, int, NETCONN_RAW);
+          if (sock->conn->pcb.raw->chksum_reqd == 0) {
+            *(int *)optval = -1;
+          } else {
+            *(int *)optval = sock->conn->pcb.raw->chksum_offset;
+          }
+          LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_RAW, IPV6_CHECKSUM) = %d\n",
+                                      s, (*(int *)optval)) );
+          break;
+#endif /* LWIP_IPV6 && LWIP_RAW */
+        default:
+          LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_RAW, UNIMPL: optname=0x%x, ..)\n",
+                                      s, optname));
+          err = ENOPROTOOPT;
+          break;
+      }  /* switch (optname) */
+      break;
+    default:
+      LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, level=0x%x, UNIMPL: optname=0x%x, ..)\n",
+                                  s, level, optname));
+      err = ENOPROTOOPT;
+      break;
+  } /* switch (level) */
+
+  done_socket(sock);
+  return err;
+}
+
+int
+lwip_setsockopt(int s, int level, int optname, const void *optval, socklen_t optlen)
+{
+  int err = 0;
+  struct lwip_sock *sock = get_socket(s);
+#if !LWIP_TCPIP_CORE_LOCKING
+  err_t cberr;
+  LWIP_SETGETSOCKOPT_DATA_VAR_DECLARE(data);
+#endif /* !LWIP_TCPIP_CORE_LOCKING */
+
+  if (!sock) {
+    return -1;
+  }
+
+  if (NULL == optval) {
+    sock_set_errno(sock, EFAULT);
+    done_socket(sock);
+    return -1;
+  }
+
+#if LWIP_TCPIP_CORE_LOCKING
+  /* core-locking can just call the -impl function */
+  LOCK_TCPIP_CORE();
+  err = lwip_setsockopt_impl(s, level, optname, optval, optlen);
+  UNLOCK_TCPIP_CORE();
+
+#else /* LWIP_TCPIP_CORE_LOCKING */
+
+#if LWIP_MPU_COMPATIBLE
+  /* MPU_COMPATIBLE copies the optval data, so check for max size here */
+  if (optlen > LWIP_SETGETSOCKOPT_MAXOPTLEN) {
+    sock_set_errno(sock, ENOBUFS);
+    done_socket(sock);
+    return -1;
+  }
+#endif /* LWIP_MPU_COMPATIBLE */
+
+  LWIP_SETGETSOCKOPT_DATA_VAR_ALLOC(data, sock);
+  LWIP_SETGETSOCKOPT_DATA_VAR_REF(data).s = s;
+  LWIP_SETGETSOCKOPT_DATA_VAR_REF(data).level = level;
+  LWIP_SETGETSOCKOPT_DATA_VAR_REF(data).optname = optname;
+  LWIP_SETGETSOCKOPT_DATA_VAR_REF(data).optlen = optlen;
+#if LWIP_MPU_COMPATIBLE
+  MEMCPY(LWIP_SETGETSOCKOPT_DATA_VAR_REF(data).optval, optval, optlen);
+#else /* LWIP_MPU_COMPATIBLE */
+  LWIP_SETGETSOCKOPT_DATA_VAR_REF(data).optval.pc = (const void *)optval;
+#endif /* LWIP_MPU_COMPATIBLE */
+  LWIP_SETGETSOCKOPT_DATA_VAR_REF(data).err = 0;
+#if LWIP_NETCONN_SEM_PER_THREAD
+  LWIP_SETGETSOCKOPT_DATA_VAR_REF(data).completed_sem = LWIP_NETCONN_THREAD_SEM_GET();
+#else
+  LWIP_SETGETSOCKOPT_DATA_VAR_REF(data).completed_sem = &sock->conn->op_completed;
+#endif
+  cberr = tcpip_callback(lwip_setsockopt_callback, &LWIP_SETGETSOCKOPT_DATA_VAR_REF(data));
+  if (cberr != ERR_OK) {
+    LWIP_SETGETSOCKOPT_DATA_VAR_FREE(data);
+    sock_set_errno(sock, err_to_errno(cberr));
+    done_socket(sock);
+    return -1;
+  }
+  sys_arch_sem_wait((sys_sem_t *)(LWIP_SETGETSOCKOPT_DATA_VAR_REF(data).completed_sem), 0);
+
+  /* maybe lwip_getsockopt_internal has changed err */
+  err = LWIP_SETGETSOCKOPT_DATA_VAR_REF(data).err;
+  LWIP_SETGETSOCKOPT_DATA_VAR_FREE(data);
+#endif  /* LWIP_TCPIP_CORE_LOCKING */
+
+  sock_set_errno(sock, err);
+  done_socket(sock);
+  return err ? -1 : 0;
+}
+
+#if !LWIP_TCPIP_CORE_LOCKING
+/** lwip_setsockopt_callback: only used without CORE_LOCKING
+ * to get into the tcpip_thread
+ */
+static void
+lwip_setsockopt_callback(void *arg)
+{
+  struct lwip_setgetsockopt_data *data;
+  LWIP_ASSERT("arg != NULL", arg != NULL);
+  data = (struct lwip_setgetsockopt_data *)arg;
+
+  data->err = lwip_setsockopt_impl(data->s, data->level, data->optname,
+#if LWIP_MPU_COMPATIBLE
+                                   data->optval,
+#else /* LWIP_MPU_COMPATIBLE */
+                                   data->optval.pc,
+#endif /* LWIP_MPU_COMPATIBLE */
+                                   data->optlen);
+
+  sys_sem_signal((sys_sem_t *)(data->completed_sem));
+}
+#endif  /* LWIP_TCPIP_CORE_LOCKING */
+
+/** lwip_setsockopt_impl: the actual implementation of setsockopt:
+ * same argument as lwip_setsockopt, either called directly or through callback
+ */
+static int
+lwip_setsockopt_impl(int s, int level, int optname, const void *optval, socklen_t optlen)
+{
+  int err = 0;
+  struct lwip_sock *sock = tryget_socket(s);
+  if (!sock) {
+    return EBADF;
+  }
+
+#ifdef LWIP_HOOK_SOCKETS_SETSOCKOPT
+  if (LWIP_HOOK_SOCKETS_SETSOCKOPT(s, sock, level, optname, optval, optlen, &err)) {
+    return err;
+  }
+#endif
+
+  switch (level) {
+
+    /* Level: SOL_SOCKET */
+    case SOL_SOCKET:
+      switch (optname) {
+
+        /* SO_ACCEPTCONN is get-only */
+
+        /* The option flags */
+        case SO_BROADCAST:
+        case SO_KEEPALIVE:
+#if SO_REUSE
+        case SO_REUSEADDR:
+#endif /* SO_REUSE */
+          if ((optname == SO_BROADCAST) &&
+              (NETCONNTYPE_GROUP(sock->conn->type) != NETCONN_UDP)) {
+            done_socket(sock);
+            return ENOPROTOOPT;
+          }
+
+          optname = lwip_sockopt_to_ipopt(optname);
+
+          LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB(sock, optlen, int);
+          if (*(const int *)optval) {
+            ip_set_option(sock->conn->pcb.ip, optname);
+          } else {
+            ip_reset_option(sock->conn->pcb.ip, optname);
+          }
+          LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, SOL_SOCKET, optname=0x%x, ..) -> %s\n",
+                                      s, optname, (*(const int *)optval ? "on" : "off")));
+          break;
+
+          /* SO_TYPE is get-only */
+          /* SO_ERROR is get-only */
+
+#if LWIP_SO_SNDTIMEO
+        case SO_SNDTIMEO: {
+          long ms_long;
+          LWIP_SOCKOPT_CHECK_OPTLEN_CONN(sock, optlen, LWIP_SO_SNDRCVTIMEO_OPTTYPE);
+          ms_long = LWIP_SO_SNDRCVTIMEO_GET_MS(optval);
+          if (ms_long < 0) {
+            done_socket(sock);
+            return EINVAL;
+          }
+          netconn_set_sendtimeout(sock->conn, ms_long);
+          break;
+        }
+#endif /* LWIP_SO_SNDTIMEO */
+#if LWIP_SO_RCVTIMEO
+        case SO_RCVTIMEO: {
+          long ms_long;
+          LWIP_SOCKOPT_CHECK_OPTLEN_CONN(sock, optlen, LWIP_SO_SNDRCVTIMEO_OPTTYPE);
+          ms_long = LWIP_SO_SNDRCVTIMEO_GET_MS(optval);
+          if (ms_long < 0) {
+            done_socket(sock);
+            return EINVAL;
+          }
+          netconn_set_recvtimeout(sock->conn, (u32_t)ms_long);
+          break;
+        }
+#endif /* LWIP_SO_RCVTIMEO */
+#if LWIP_SO_RCVBUF
+        case SO_RCVBUF:
+          LWIP_SOCKOPT_CHECK_OPTLEN_CONN(sock, optlen, int);
+          netconn_set_recvbufsize(sock->conn, *(const int *)optval);
+          break;
+#endif /* LWIP_SO_RCVBUF */
+#if LWIP_SO_LINGER
+        case SO_LINGER: {
+          const struct linger *linger = (const struct linger *)optval;
+          LWIP_SOCKOPT_CHECK_OPTLEN_CONN(sock, optlen, struct linger);
+          if (linger->l_onoff) {
+            int lingersec = linger->l_linger;
+            if (lingersec < 0) {
+              done_socket(sock);
+              return EINVAL;
+            }
+            if (lingersec > 0xFFFF) {
+              lingersec = 0xFFFF;
+            }
+            sock->conn->linger = (s16_t)lingersec;
+          } else {
+            sock->conn->linger = -1;
+          }
+        }
+        break;
+#endif /* LWIP_SO_LINGER */
+#if LWIP_UDP
+        case SO_NO_CHECK:
+          LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB_TYPE(sock, optlen, int, NETCONN_UDP);
+#if LWIP_UDPLITE
+          if (udp_is_flag_set(sock->conn->pcb.udp, UDP_FLAGS_UDPLITE)) {
+            /* this flag is only available for UDP, not for UDP lite */
+            done_socket(sock);
+            return EAFNOSUPPORT;
+          }
+#endif /* LWIP_UDPLITE */
+          if (*(const int *)optval) {
+            udp_set_flags(sock->conn->pcb.udp, UDP_FLAGS_NOCHKSUM);
+          } else {
+            udp_clear_flags(sock->conn->pcb.udp, UDP_FLAGS_NOCHKSUM);
+          }
+          break;
+#endif /* LWIP_UDP */
+        case SO_BINDTODEVICE: {
+          const struct ifreq *iface;
+          struct netif *n = NULL;
+
+          LWIP_SOCKOPT_CHECK_OPTLEN_CONN(sock, optlen, struct ifreq);
+
+          iface = (const struct ifreq *)optval;
+          if (iface->ifr_name[0] != 0) {
+            n = netif_find(iface->ifr_name);
+            if (n == NULL) {
+              done_socket(sock);
+              return ENODEV;
+            }
+          }
+
+          switch (NETCONNTYPE_GROUP(netconn_type(sock->conn))) {
+#if LWIP_TCP
+            case NETCONN_TCP:
+              tcp_bind_netif(sock->conn->pcb.tcp, n);
+              break;
+#endif
+#if LWIP_UDP
+            case NETCONN_UDP:
+              udp_bind_netif(sock->conn->pcb.udp, n);
+              break;
+#endif
+#if LWIP_RAW
+            case NETCONN_RAW:
+              raw_bind_netif(sock->conn->pcb.raw, n);
+              break;
+#endif
+            default:
+              LWIP_ASSERT("Unhandled netconn type in SO_BINDTODEVICE", 0);
+              break;
+          }
+        }
+        break;
+        default:
+          LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, SOL_SOCKET, UNIMPL: optname=0x%x, ..)\n",
+                                      s, optname));
+          err = ENOPROTOOPT;
+          break;
+      }  /* switch (optname) */
+      break;
+
+    /* Level: IPPROTO_IP */
+    case IPPROTO_IP:
+      switch (optname) {
+        case IP_TTL:
+          LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB(sock, optlen, int);
+          sock->conn->pcb.ip->ttl = (u8_t)(*(const int *)optval);
+          LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_IP, IP_TTL, ..) -> %d\n",
+                                      s, sock->conn->pcb.ip->ttl));
+          break;
+        case IP_TOS:
+          LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB(sock, optlen, int);
+          sock->conn->pcb.ip->tos = (u8_t)(*(const int *)optval);
+          LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_IP, IP_TOS, ..)-> %d\n",
+                                      s, sock->conn->pcb.ip->tos));
+          break;
+#if LWIP_NETBUF_RECVINFO
+        case IP_PKTINFO:
+          LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB_TYPE(sock, optlen, int, NETCONN_UDP);
+          if (*(const int *)optval) {
+            sock->conn->flags |= NETCONN_FLAG_PKTINFO;
+          } else {
+            sock->conn->flags &= ~NETCONN_FLAG_PKTINFO;
+          }
+          break;
+#endif /* LWIP_NETBUF_RECVINFO */
+#if LWIP_IPV4 && LWIP_MULTICAST_TX_OPTIONS && LWIP_UDP
+        case IP_MULTICAST_TTL:
+          LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB_TYPE(sock, optlen, u8_t, NETCONN_UDP);
+          udp_set_multicast_ttl(sock->conn->pcb.udp, (u8_t)(*(const u8_t *)optval));
+          break;
+        case IP_MULTICAST_IF: {
+          ip4_addr_t if_addr;
+          LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB_TYPE(sock, optlen, struct in_addr, NETCONN_UDP);
+          inet_addr_to_ip4addr(&if_addr, (const struct in_addr *)optval);
+          udp_set_multicast_netif_addr(sock->conn->pcb.udp, &if_addr);
+        }
+        break;
+        case IP_MULTICAST_LOOP:
+          LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB_TYPE(sock, optlen, u8_t, NETCONN_UDP);
+          if (*(const u8_t *)optval) {
+            udp_set_flags(sock->conn->pcb.udp, UDP_FLAGS_MULTICAST_LOOP);
+          } else {
+            udp_clear_flags(sock->conn->pcb.udp, UDP_FLAGS_MULTICAST_LOOP);
+          }
+          break;
+#endif /* LWIP_IPV4 && LWIP_MULTICAST_TX_OPTIONS && LWIP_UDP */
+#if LWIP_IGMP
+        case IP_ADD_MEMBERSHIP:
+        case IP_DROP_MEMBERSHIP: {
+          /* If this is a TCP or a RAW socket, ignore these options. */
+          err_t igmp_err;
+          const struct ip_mreq *imr = (const struct ip_mreq *)optval;
+          ip4_addr_t if_addr;
+          ip4_addr_t multi_addr;
+          LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB_TYPE(sock, optlen, struct ip_mreq, NETCONN_UDP);
+          inet_addr_to_ip4addr(&if_addr, &imr->imr_interface);
+          inet_addr_to_ip4addr(&multi_addr, &imr->imr_multiaddr);
+          if (optname == IP_ADD_MEMBERSHIP) {
+            if (!lwip_socket_register_membership(s, &if_addr, &multi_addr)) {
+              /* cannot track membership (out of memory) */
+              err = ENOMEM;
+              igmp_err = ERR_OK;
+            } else {
+              igmp_err = igmp_joingroup(&if_addr, &multi_addr);
+            }
+          } else {
+            igmp_err = igmp_leavegroup(&if_addr, &multi_addr);
+            lwip_socket_unregister_membership(s, &if_addr, &multi_addr);
+          }
+          if (igmp_err != ERR_OK) {
+            err = EADDRNOTAVAIL;
+          }
+        }
+        break;
+#endif /* LWIP_IGMP */
+        default:
+          LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_IP, UNIMPL: optname=0x%x, ..)\n",
+                                      s, optname));
+          err = ENOPROTOOPT;
+          break;
+      }  /* switch (optname) */
+      break;
+
+#if LWIP_TCP
+    /* Level: IPPROTO_TCP */
+    case IPPROTO_TCP:
+      /* Special case: all IPPROTO_TCP option take an int */
+      LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB_TYPE(sock, optlen, int, NETCONN_TCP);
+      if (sock->conn->pcb.tcp->state == LISTEN) {
+        done_socket(sock);
+        return EINVAL;
+      }
+      switch (optname) {
+        case TCP_NODELAY:
+          if (*(const int *)optval) {
+            tcp_nagle_disable(sock->conn->pcb.tcp);
+          } else {
+            tcp_nagle_enable(sock->conn->pcb.tcp);
+          }
+          LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_TCP, TCP_NODELAY) -> %s\n",
+                                      s, (*(const int *)optval) ? "on" : "off") );
+          break;
+        case TCP_KEEPALIVE:
+          sock->conn->pcb.tcp->keep_idle = (u32_t)(*(const int *)optval);
+          LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_TCP, TCP_KEEPALIVE) -> %"U32_F"\n",
+                                      s, sock->conn->pcb.tcp->keep_idle));
+          break;
+
+#if LWIP_TCP_KEEPALIVE
+        case TCP_KEEPIDLE:
+          sock->conn->pcb.tcp->keep_idle = 1000 * (u32_t)(*(const int *)optval);
+          LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_TCP, TCP_KEEPIDLE) -> %"U32_F"\n",
+                                      s, sock->conn->pcb.tcp->keep_idle));
+          break;
+        case TCP_KEEPINTVL:
+          sock->conn->pcb.tcp->keep_intvl = 1000 * (u32_t)(*(const int *)optval);
+          LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_TCP, TCP_KEEPINTVL) -> %"U32_F"\n",
+                                      s, sock->conn->pcb.tcp->keep_intvl));
+          break;
+        case TCP_KEEPCNT:
+          sock->conn->pcb.tcp->keep_cnt = (u32_t)(*(const int *)optval);
+          LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_TCP, TCP_KEEPCNT) -> %"U32_F"\n",
+                                      s, sock->conn->pcb.tcp->keep_cnt));
+          break;
+#endif /* LWIP_TCP_KEEPALIVE */
+        default:
+          LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_TCP, UNIMPL: optname=0x%x, ..)\n",
+                                      s, optname));
+          err = ENOPROTOOPT;
+          break;
+      }  /* switch (optname) */
+      break;
+#endif /* LWIP_TCP*/
+
+#if LWIP_IPV6
+    /* Level: IPPROTO_IPV6 */
+    case IPPROTO_IPV6:
+      switch (optname) {
+        case IPV6_V6ONLY:
+          LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB(sock, optlen, int);
+          if (*(const int *)optval) {
+            netconn_set_ipv6only(sock->conn, 1);
+          } else {
+            netconn_set_ipv6only(sock->conn, 0);
+          }
+          LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_IPV6, IPV6_V6ONLY, ..) -> %d\n",
+                                      s, (netconn_get_ipv6only(sock->conn) ? 1 : 0)));
+          break;
+#if LWIP_IPV6_MLD
+        case IPV6_JOIN_GROUP:
+        case IPV6_LEAVE_GROUP: {
+          /* If this is a TCP or a RAW socket, ignore these options. */
+          err_t mld6_err;
+          struct netif *netif;
+          ip6_addr_t multi_addr;
+          const struct ipv6_mreq *imr = (const struct ipv6_mreq *)optval;
+          LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB_TYPE(sock, optlen, struct ipv6_mreq, NETCONN_UDP);
+          inet6_addr_to_ip6addr(&multi_addr, &imr->ipv6mr_multiaddr);
+          LWIP_ASSERT("Invalid netif index", imr->ipv6mr_interface <= 0xFFu);
+          netif = netif_get_by_index((u8_t)imr->ipv6mr_interface);
+          if (netif == NULL) {
+            err = EADDRNOTAVAIL;
+            break;
+          }
+
+          if (optname == IPV6_JOIN_GROUP) {
+            if (!lwip_socket_register_mld6_membership(s, imr->ipv6mr_interface, &multi_addr)) {
+              /* cannot track membership (out of memory) */
+              err = ENOMEM;
+              mld6_err = ERR_OK;
+            } else {
+              mld6_err = mld6_joingroup_netif(netif, &multi_addr);
+            }
+          } else {
+            mld6_err = mld6_leavegroup_netif(netif, &multi_addr);
+            lwip_socket_unregister_mld6_membership(s, imr->ipv6mr_interface, &multi_addr);
+          }
+          if (mld6_err != ERR_OK) {
+            err = EADDRNOTAVAIL;
+          }
+        }
+        break;
+#endif /* LWIP_IPV6_MLD */
+        default:
+          LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_IPV6, UNIMPL: optname=0x%x, ..)\n",
+                                      s, optname));
+          err = ENOPROTOOPT;
+          break;
+      }  /* switch (optname) */
+      break;
+#endif /* LWIP_IPV6 */
+
+#if LWIP_UDP && LWIP_UDPLITE
+    /* Level: IPPROTO_UDPLITE */
+    case IPPROTO_UDPLITE:
+      /* Special case: all IPPROTO_UDPLITE option take an int */
+      LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB(sock, optlen, int);
+      /* If this is no UDP lite socket, ignore any options. */
+      if (!NETCONNTYPE_ISUDPLITE(netconn_type(sock->conn))) {
+        done_socket(sock);
+        return ENOPROTOOPT;
+      }
+      switch (optname) {
+        case UDPLITE_SEND_CSCOV:
+          if ((*(const int *)optval != 0) && ((*(const int *)optval < 8) || (*(const int *)optval > 0xffff))) {
+            /* don't allow illegal values! */
+            sock->conn->pcb.udp->chksum_len_tx = 8;
+          } else {
+            sock->conn->pcb.udp->chksum_len_tx = (u16_t) * (const int *)optval;
+          }
+          LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_UDPLITE, UDPLITE_SEND_CSCOV) -> %d\n",
+                                      s, (*(const int *)optval)) );
+          break;
+        case UDPLITE_RECV_CSCOV:
+          if ((*(const int *)optval != 0) && ((*(const int *)optval < 8) || (*(const int *)optval > 0xffff))) {
+            /* don't allow illegal values! */
+            sock->conn->pcb.udp->chksum_len_rx = 8;
+          } else {
+            sock->conn->pcb.udp->chksum_len_rx = (u16_t) * (const int *)optval;
+          }
+          LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_UDPLITE, UDPLITE_RECV_CSCOV) -> %d\n",
+                                      s, (*(const int *)optval)) );
+          break;
+        default:
+          LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_UDPLITE, UNIMPL: optname=0x%x, ..)\n",
+                                      s, optname));
+          err = ENOPROTOOPT;
+          break;
+      }  /* switch (optname) */
+      break;
+#endif /* LWIP_UDP */
+    /* Level: IPPROTO_RAW */
+    case IPPROTO_RAW:
+      switch (optname) {
+#if LWIP_IPV6 && LWIP_RAW
+        case IPV6_CHECKSUM:
+          /* It should not be possible to disable the checksum generation with ICMPv6
+           * as per RFC 3542 chapter 3.1 */
+          if (sock->conn->pcb.raw->protocol == IPPROTO_ICMPV6) {
+            done_socket(sock);
+            return EINVAL;
+          }
+
+          LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB_TYPE(sock, optlen, int, NETCONN_RAW);
+          if (*(const int *)optval < 0) {
+            sock->conn->pcb.raw->chksum_reqd = 0;
+          } else if (*(const int *)optval & 1) {
+            /* Per RFC3542, odd offsets are not allowed */
+            done_socket(sock);
+            return EINVAL;
+          } else {
+            sock->conn->pcb.raw->chksum_reqd = 1;
+            sock->conn->pcb.raw->chksum_offset = (u16_t) * (const int *)optval;
+          }
+          LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_RAW, IPV6_CHECKSUM, ..) -> %d\n",
+                                      s, sock->conn->pcb.raw->chksum_reqd));
+          break;
+#endif /* LWIP_IPV6 && LWIP_RAW */
+        default:
+          LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_RAW, UNIMPL: optname=0x%x, ..)\n",
+                                      s, optname));
+          err = ENOPROTOOPT;
+          break;
+      }  /* switch (optname) */
+      break;
+    default:
+      LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, level=0x%x, UNIMPL: optname=0x%x, ..)\n",
+                                  s, level, optname));
+      err = ENOPROTOOPT;
+      break;
+  }  /* switch (level) */
+
+  done_socket(sock);
+  return err;
+}
+
+int
+lwip_ioctl(int s, long cmd, void *argp)
+{
+  struct lwip_sock *sock = get_socket(s);
+  u8_t val;
+#if LWIP_SO_RCVBUF
+  int recv_avail;
+#endif /* LWIP_SO_RCVBUF */
+
+  if (!sock) {
+    return -1;
+  }
+
+  switch (cmd) {
+#if LWIP_SO_RCVBUF || LWIP_FIONREAD_LINUXMODE
+    case FIONREAD:
+      if (!argp) {
+        sock_set_errno(sock, EINVAL);
+        done_socket(sock);
+        return -1;
+      }
+#if LWIP_FIONREAD_LINUXMODE
+      if (NETCONNTYPE_GROUP(netconn_type(sock->conn)) != NETCONN_TCP) {
+        struct netbuf *nb;
+        if (sock->lastdata.netbuf) {
+          nb = sock->lastdata.netbuf;
+          *((int *)argp) = nb->p->tot_len;
+        } else {
+          struct netbuf *rxbuf;
+          err_t err = netconn_recv_udp_raw_netbuf_flags(sock->conn, &rxbuf, NETCONN_DONTBLOCK);
+          if (err != ERR_OK) {
+            *((int *)argp) = 0;
+          } else {
+            sock->lastdata.netbuf = rxbuf;
+            *((int *)argp) = rxbuf->p->tot_len;
+          }
+        }
+        done_socket(sock);
+        return 0;
+      }
+#endif /* LWIP_FIONREAD_LINUXMODE */
+
+#if LWIP_SO_RCVBUF
+      /* we come here if either LWIP_FIONREAD_LINUXMODE==0 or this is a TCP socket */
+      SYS_ARCH_GET(sock->conn->recv_avail, recv_avail);
+      if (recv_avail < 0) {
+        recv_avail = 0;
+      }
+
+      /* Check if there is data left from the last recv operation. /maq 041215 */
+      if (sock->lastdata.netbuf) {
+        if (NETCONNTYPE_GROUP(netconn_type(sock->conn)) == NETCONN_TCP) {
+          recv_avail += sock->lastdata.pbuf->tot_len;
+        } else {
+          recv_avail += sock->lastdata.netbuf->p->tot_len;
+        }
+      }
+      *((int *)argp) = recv_avail;
+
+      LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_ioctl(%d, FIONREAD, %p) = %"U16_F"\n", s, argp, *((u16_t *)argp)));
+      sock_set_errno(sock, 0);
+      done_socket(sock);
+      return 0;
+#else /* LWIP_SO_RCVBUF */
+      break;
+#endif /* LWIP_SO_RCVBUF */
+#endif /* LWIP_SO_RCVBUF || LWIP_FIONREAD_LINUXMODE */
+
+    case (long)FIONBIO:
+      val = 0;
+      if (argp && *(int *)argp) {
+        val = 1;
+      }
+      netconn_set_nonblocking(sock->conn, val);
+      LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_ioctl(%d, FIONBIO, %d)\n", s, val));
+      sock_set_errno(sock, 0);
+      done_socket(sock);
+      return 0;
+
+    default:
+      break;
+  } /* switch (cmd) */
+  LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_ioctl(%d, UNIMPL: 0x%lx, %p)\n", s, cmd, argp));
+  sock_set_errno(sock, ENOSYS); /* not yet implemented */
+  done_socket(sock);
+  return -1;
+}
+
+/** A minimal implementation of fcntl.
+ * Currently only the commands F_GETFL and F_SETFL are implemented.
+ * The flag O_NONBLOCK and access modes are supported for F_GETFL, only
+ * the flag O_NONBLOCK is implemented for F_SETFL.
+ */
+int
+lwip_fcntl(int s, int cmd, int val)
+{
+  struct lwip_sock *sock = get_socket(s);
+  int ret = -1;
+  int op_mode = 0;
+
+  if (!sock) {
+    return -1;
+  }
+
+  switch (cmd) {
+    case F_GETFL:
+      ret = netconn_is_nonblocking(sock->conn) ? O_NONBLOCK : 0;
+      sock_set_errno(sock, 0);
+
+      if (NETCONNTYPE_GROUP(netconn_type(sock->conn)) == NETCONN_TCP) {
+#if LWIP_TCPIP_CORE_LOCKING
+        LOCK_TCPIP_CORE();
+#else
+        SYS_ARCH_DECL_PROTECT(lev);
+        /* the proper thing to do here would be to get into the tcpip_thread,
+           but locking should be OK as well since we only *read* some flags */
+        SYS_ARCH_PROTECT(lev);
+#endif
+#if LWIP_TCP
+        if (sock->conn->pcb.tcp) {
+          if (!(sock->conn->pcb.tcp->flags & TF_RXCLOSED)) {
+            op_mode |= O_RDONLY;
+          }
+          if (!(sock->conn->pcb.tcp->flags & TF_FIN)) {
+            op_mode |= O_WRONLY;
+          }
+        }
+#endif
+#if LWIP_TCPIP_CORE_LOCKING
+        UNLOCK_TCPIP_CORE();
+#else
+        SYS_ARCH_UNPROTECT(lev);
+#endif
+      } else {
+        op_mode |= O_RDWR;
+      }
+
+      /* ensure O_RDWR for (O_RDONLY|O_WRONLY) != O_RDWR cases */
+      ret |= (op_mode == (O_RDONLY | O_WRONLY)) ? O_RDWR : op_mode;
+
+      break;
+    case F_SETFL:
+      /* Bits corresponding to the file access mode and the file creation flags [..] that are set in arg shall be ignored */
+      val &= ~(O_RDONLY | O_WRONLY | O_RDWR);
+      if ((val & ~O_NONBLOCK) == 0) {
+        /* only O_NONBLOCK, all other bits are zero */
+        netconn_set_nonblocking(sock->conn, val & O_NONBLOCK);
+        ret = 0;
+        sock_set_errno(sock, 0);
+      } else {
+        sock_set_errno(sock, ENOSYS); /* not yet implemented */
+      }
+      break;
+    default:
+      LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_fcntl(%d, UNIMPL: %d, %d)\n", s, cmd, val));
+      sock_set_errno(sock, ENOSYS); /* not yet implemented */
+      break;
+  }
+  done_socket(sock);
+  return ret;
+}
+
+#if LWIP_COMPAT_SOCKETS == 2 && LWIP_POSIX_SOCKETS_IO_NAMES
+int
+fcntl(int s, int cmd, ...)
+{
+  va_list ap;
+  int val;
+
+  va_start(ap, cmd);
+  val = va_arg(ap, int);
+  va_end(ap);
+  return lwip_fcntl(s, cmd, val);
+}
+#endif
+
+const char *
+lwip_inet_ntop(int af, const void *src, char *dst, socklen_t size)
+{
+  const char *ret = NULL;
+  int size_int = (int)size;
+  if (size_int < 0) {
+    set_errno(ENOSPC);
+    return NULL;
+  }
+  switch (af) {
+#if LWIP_IPV4
+    case AF_INET:
+      ret = ip4addr_ntoa_r((const ip4_addr_t *)src, dst, size_int);
+      if (ret == NULL) {
+        set_errno(ENOSPC);
+      }
+      break;
+#endif
+#if LWIP_IPV6
+    case AF_INET6:
+      ret = ip6addr_ntoa_r((const ip6_addr_t *)src, dst, size_int);
+      if (ret == NULL) {
+        set_errno(ENOSPC);
+      }
+      break;
+#endif
+    default:
+      set_errno(EAFNOSUPPORT);
+      break;
+  }
+  return ret;
+}
+
+int
+lwip_inet_pton(int af, const char *src, void *dst)
+{
+  int err;
+  switch (af) {
+#if LWIP_IPV4
+    case AF_INET:
+      err = ip4addr_aton(src, (ip4_addr_t *)dst);
+      break;
+#endif
+#if LWIP_IPV6
+    case AF_INET6: {
+      /* convert into temporary variable since ip6_addr_t might be larger
+         than in6_addr when scopes are enabled */
+      ip6_addr_t addr;
+      err = ip6addr_aton(src, &addr);
+      if (err) {
+        memcpy(dst, &addr.addr, sizeof(addr.addr));
+      }
+      break;
+    }
+#endif
+    default:
+      err = -1;
+      set_errno(EAFNOSUPPORT);
+      break;
+  }
+  return err;
+}
+
+#if LWIP_IGMP
+/** Register a new IGMP membership. On socket close, the membership is dropped automatically.
+ *
+ * ATTENTION: this function is called from tcpip_thread (or under CORE_LOCK).
+ *
+ * @return 1 on success, 0 on failure
+ */
+static int
+lwip_socket_register_membership(int s, const ip4_addr_t *if_addr, const ip4_addr_t *multi_addr)
+{
+  struct lwip_sock *sock = get_socket(s);
+  int i;
+
+  if (!sock) {
+    return 0;
+  }
+
+  for (i = 0; i < LWIP_SOCKET_MAX_MEMBERSHIPS; i++) {
+    if (socket_ipv4_multicast_memberships[i].sock == NULL) {
+      socket_ipv4_multicast_memberships[i].sock = sock;
+      ip4_addr_copy(socket_ipv4_multicast_memberships[i].if_addr, *if_addr);
+      ip4_addr_copy(socket_ipv4_multicast_memberships[i].multi_addr, *multi_addr);
+      done_socket(sock);
+      return 1;
+    }
+  }
+  done_socket(sock);
+  return 0;
+}
+
+/** Unregister a previously registered membership. This prevents dropping the membership
+ * on socket close.
+ *
+ * ATTENTION: this function is called from tcpip_thread (or under CORE_LOCK).
+ */
+static void
+lwip_socket_unregister_membership(int s, const ip4_addr_t *if_addr, const ip4_addr_t *multi_addr)
+{
+  struct lwip_sock *sock = get_socket(s);
+  int i;
+
+  if (!sock) {
+    return;
+  }
+
+  for (i = 0; i < LWIP_SOCKET_MAX_MEMBERSHIPS; i++) {
+    if ((socket_ipv4_multicast_memberships[i].sock == sock) &&
+        ip4_addr_cmp(&socket_ipv4_multicast_memberships[i].if_addr, if_addr) &&
+        ip4_addr_cmp(&socket_ipv4_multicast_memberships[i].multi_addr, multi_addr)) {
+      socket_ipv4_multicast_memberships[i].sock = NULL;
+      ip4_addr_set_zero(&socket_ipv4_multicast_memberships[i].if_addr);
+      ip4_addr_set_zero(&socket_ipv4_multicast_memberships[i].multi_addr);
+      break;
+    }
+  }
+  done_socket(sock);
+}
+
+/** Drop all memberships of a socket that were not dropped explicitly via setsockopt.
+ *
+ * ATTENTION: this function is NOT called from tcpip_thread (or under CORE_LOCK).
+ */
+static void
+lwip_socket_drop_registered_memberships(int s)
+{
+  struct lwip_sock *sock = get_socket(s);
+  int i;
+
+  if (!sock) {
+    return;
+  }
+
+  for (i = 0; i < LWIP_SOCKET_MAX_MEMBERSHIPS; i++) {
+    if (socket_ipv4_multicast_memberships[i].sock == sock) {
+      ip_addr_t multi_addr, if_addr;
+      ip_addr_copy_from_ip4(multi_addr, socket_ipv4_multicast_memberships[i].multi_addr);
+      ip_addr_copy_from_ip4(if_addr, socket_ipv4_multicast_memberships[i].if_addr);
+      socket_ipv4_multicast_memberships[i].sock = NULL;
+      ip4_addr_set_zero(&socket_ipv4_multicast_memberships[i].if_addr);
+      ip4_addr_set_zero(&socket_ipv4_multicast_memberships[i].multi_addr);
+
+      netconn_join_leave_group(sock->conn, &multi_addr, &if_addr, NETCONN_LEAVE);
+    }
+  }
+  done_socket(sock);
+}
+#endif /* LWIP_IGMP */
+
+#if LWIP_IPV6_MLD
+/** Register a new MLD6 membership. On socket close, the membership is dropped automatically.
+ *
+ * ATTENTION: this function is called from tcpip_thread (or under CORE_LOCK).
+ *
+ * @return 1 on success, 0 on failure
+ */
+static int
+lwip_socket_register_mld6_membership(int s, unsigned int if_idx, const ip6_addr_t *multi_addr)
+{
+  struct lwip_sock *sock = get_socket(s);
+  int i;
+
+  if (!sock) {
+    return 0;
+  }
+
+  for (i = 0; i < LWIP_SOCKET_MAX_MEMBERSHIPS; i++) {
+    if (socket_ipv6_multicast_memberships[i].sock == NULL) {
+      socket_ipv6_multicast_memberships[i].sock   = sock;
+      socket_ipv6_multicast_memberships[i].if_idx = (u8_t)if_idx;
+      ip6_addr_copy(socket_ipv6_multicast_memberships[i].multi_addr, *multi_addr);
+      done_socket(sock);
+      return 1;
+    }
+  }
+  done_socket(sock);
+  return 0;
+}
+
+/** Unregister a previously registered MLD6 membership. This prevents dropping the membership
+ * on socket close.
+ *
+ * ATTENTION: this function is called from tcpip_thread (or under CORE_LOCK).
+ */
+static void
+lwip_socket_unregister_mld6_membership(int s, unsigned int if_idx, const ip6_addr_t *multi_addr)
+{
+  struct lwip_sock *sock = get_socket(s);
+  int i;
+
+  if (!sock) {
+    return;
+  }
+
+  for (i = 0; i < LWIP_SOCKET_MAX_MEMBERSHIPS; i++) {
+    if ((socket_ipv6_multicast_memberships[i].sock   == sock) &&
+        (socket_ipv6_multicast_memberships[i].if_idx == if_idx) &&
+        ip6_addr_cmp(&socket_ipv6_multicast_memberships[i].multi_addr, multi_addr)) {
+      socket_ipv6_multicast_memberships[i].sock   = NULL;
+      socket_ipv6_multicast_memberships[i].if_idx = NETIF_NO_INDEX;
+      ip6_addr_set_zero(&socket_ipv6_multicast_memberships[i].multi_addr);
+      break;
+    }
+  }
+  done_socket(sock);
+}
+
+/** Drop all MLD6 memberships of a socket that were not dropped explicitly via setsockopt.
+ *
+ * ATTENTION: this function is NOT called from tcpip_thread (or under CORE_LOCK).
+ */
+static void
+lwip_socket_drop_registered_mld6_memberships(int s)
+{
+  struct lwip_sock *sock = get_socket(s);
+  int i;
+
+  if (!sock) {
+    return;
+  }
+
+  for (i = 0; i < LWIP_SOCKET_MAX_MEMBERSHIPS; i++) {
+    if (socket_ipv6_multicast_memberships[i].sock == sock) {
+      ip_addr_t multi_addr;
+      u8_t if_idx;
+
+      ip_addr_copy_from_ip6(multi_addr, socket_ipv6_multicast_memberships[i].multi_addr);
+      if_idx = socket_ipv6_multicast_memberships[i].if_idx;
+
+      socket_ipv6_multicast_memberships[i].sock   = NULL;
+      socket_ipv6_multicast_memberships[i].if_idx = NETIF_NO_INDEX;
+      ip6_addr_set_zero(&socket_ipv6_multicast_memberships[i].multi_addr);
+
+      netconn_join_leave_group_netif(sock->conn, &multi_addr, if_idx, NETCONN_LEAVE);
+    }
+  }
+  done_socket(sock);
+}
+#endif /* LWIP_IPV6_MLD */
+
+#endif /* LWIP_SOCKET */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/api/tcpip.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/api/tcpip.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/api/tcpip.c	(revision 457)
@@ -0,0 +1,658 @@
+/**
+ * @file
+ * Sequential API Main thread module
+ *
+ */
+
+/*
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Adam Dunkels <adam@sics.se>
+ *
+ */
+
+#include "lwip/opt.h"
+
+#if !NO_SYS /* don't build if not configured for use in lwipopts.h */
+
+#include "lwip/priv/tcpip_priv.h"
+#include "lwip/sys.h"
+#include "lwip/memp.h"
+#include "lwip/mem.h"
+#include "lwip/init.h"
+#include "lwip/ip.h"
+#include "lwip/pbuf.h"
+#include "lwip/etharp.h"
+#include "netif/ethernet.h"
+
+#define TCPIP_MSG_VAR_REF(name)     API_VAR_REF(name)
+#define TCPIP_MSG_VAR_DECLARE(name) API_VAR_DECLARE(struct tcpip_msg, name)
+#define TCPIP_MSG_VAR_ALLOC(name)   API_VAR_ALLOC(struct tcpip_msg, MEMP_TCPIP_MSG_API, name, ERR_MEM)
+#define TCPIP_MSG_VAR_FREE(name)    API_VAR_FREE(MEMP_TCPIP_MSG_API, name)
+
+/* global variables */
+static tcpip_init_done_fn tcpip_init_done;
+static void *tcpip_init_done_arg;
+static sys_mbox_t tcpip_mbox;
+
+#if LWIP_TCPIP_CORE_LOCKING
+/** The global semaphore to lock the stack. */
+sys_mutex_t lock_tcpip_core;
+#endif /* LWIP_TCPIP_CORE_LOCKING */
+
+static void tcpip_thread_handle_msg(struct tcpip_msg *msg);
+
+#if !LWIP_TIMERS
+/* wait for a message with timers disabled (e.g. pass a timer-check trigger into tcpip_thread) */
+#define TCPIP_MBOX_FETCH(mbox, msg) sys_mbox_fetch(mbox, msg)
+#else /* !LWIP_TIMERS */
+/* wait for a message, timeouts are processed while waiting */
+#define TCPIP_MBOX_FETCH(mbox, msg) tcpip_timeouts_mbox_fetch(mbox, msg)
+/**
+ * Wait (forever) for a message to arrive in an mbox.
+ * While waiting, timeouts are processed.
+ *
+ * @param mbox the mbox to fetch the message from
+ * @param msg the place to store the message
+ */
+static void
+tcpip_timeouts_mbox_fetch(sys_mbox_t *mbox, void **msg)
+{
+  u32_t sleeptime, res;
+
+again:
+  LWIP_ASSERT_CORE_LOCKED();
+
+  sleeptime = sys_timeouts_sleeptime();
+  if (sleeptime == SYS_TIMEOUTS_SLEEPTIME_INFINITE) {
+    UNLOCK_TCPIP_CORE();
+    sys_arch_mbox_fetch(mbox, msg, 0);
+    LOCK_TCPIP_CORE();
+    return;
+  } else if (sleeptime == 0) {
+    sys_check_timeouts();
+    /* We try again to fetch a message from the mbox. */
+    goto again;
+  }
+
+  UNLOCK_TCPIP_CORE();
+  res = sys_arch_mbox_fetch(mbox, msg, sleeptime);
+  LOCK_TCPIP_CORE();
+  if (res == SYS_ARCH_TIMEOUT) {
+    /* If a SYS_ARCH_TIMEOUT value is returned, a timeout occurred
+       before a message could be fetched. */
+    sys_check_timeouts();
+    /* We try again to fetch a message from the mbox. */
+    goto again;
+  }
+}
+#endif /* !LWIP_TIMERS */
+
+/**
+ * The main lwIP thread. This thread has exclusive access to lwIP core functions
+ * (unless access to them is not locked). Other threads communicate with this
+ * thread using message boxes.
+ *
+ * It also starts all the timers to make sure they are running in the right
+ * thread context.
+ *
+ * @param arg unused argument
+ */
+static void
+tcpip_thread(void *arg)
+{
+  struct tcpip_msg *msg;
+  LWIP_UNUSED_ARG(arg);
+
+  LWIP_MARK_TCPIP_THREAD();
+
+  LOCK_TCPIP_CORE();
+  if (tcpip_init_done != NULL) {
+    tcpip_init_done(tcpip_init_done_arg);
+  }
+
+  while (1) {                          /* MAIN Loop */
+    LWIP_TCPIP_THREAD_ALIVE();
+    /* wait for a message, timeouts are processed while waiting */
+    TCPIP_MBOX_FETCH(&tcpip_mbox, (void **)&msg);
+    if (msg == NULL) {
+      LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: invalid message: NULL\n"));
+      LWIP_ASSERT("tcpip_thread: invalid message", 0);
+      continue;
+    }
+    tcpip_thread_handle_msg(msg);
+  }
+}
+
+/* Handle a single tcpip_msg
+ * This is in its own function for access by tests only.
+ */
+static void
+tcpip_thread_handle_msg(struct tcpip_msg *msg)
+{
+  switch (msg->type) {
+#if !LWIP_TCPIP_CORE_LOCKING
+    case TCPIP_MSG_API:
+      LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: API message %p\n", (void *)msg));
+      msg->msg.api_msg.function(msg->msg.api_msg.msg);
+      break;
+    case TCPIP_MSG_API_CALL:
+      LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: API CALL message %p\n", (void *)msg));
+      msg->msg.api_call.arg->err = msg->msg.api_call.function(msg->msg.api_call.arg);
+      sys_sem_signal(msg->msg.api_call.sem);
+      break;
+#endif /* !LWIP_TCPIP_CORE_LOCKING */
+
+#if !LWIP_TCPIP_CORE_LOCKING_INPUT
+    case TCPIP_MSG_INPKT:
+      LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: PACKET %p\n", (void *)msg));
+      if (msg->msg.inp.input_fn(msg->msg.inp.p, msg->msg.inp.netif) != ERR_OK) {
+        pbuf_free(msg->msg.inp.p);
+      }
+      memp_free(MEMP_TCPIP_MSG_INPKT, msg);
+      break;
+#endif /* !LWIP_TCPIP_CORE_LOCKING_INPUT */
+
+#if LWIP_TCPIP_TIMEOUT && LWIP_TIMERS
+    case TCPIP_MSG_TIMEOUT:
+      LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: TIMEOUT %p\n", (void *)msg));
+      sys_timeout(msg->msg.tmo.msecs, msg->msg.tmo.h, msg->msg.tmo.arg);
+      memp_free(MEMP_TCPIP_MSG_API, msg);
+      break;
+    case TCPIP_MSG_UNTIMEOUT:
+      LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: UNTIMEOUT %p\n", (void *)msg));
+      sys_untimeout(msg->msg.tmo.h, msg->msg.tmo.arg);
+      memp_free(MEMP_TCPIP_MSG_API, msg);
+      break;
+#endif /* LWIP_TCPIP_TIMEOUT && LWIP_TIMERS */
+
+    case TCPIP_MSG_CALLBACK:
+      LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: CALLBACK %p\n", (void *)msg));
+      msg->msg.cb.function(msg->msg.cb.ctx);
+      memp_free(MEMP_TCPIP_MSG_API, msg);
+      break;
+
+    case TCPIP_MSG_CALLBACK_STATIC:
+      LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: CALLBACK_STATIC %p\n", (void *)msg));
+      msg->msg.cb.function(msg->msg.cb.ctx);
+      break;
+
+    default:
+      LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: invalid message: %d\n", msg->type));
+      LWIP_ASSERT("tcpip_thread: invalid message", 0);
+      break;
+  }
+}
+
+#ifdef TCPIP_THREAD_TEST
+/** Work on queued items in single-threaded test mode */
+int
+tcpip_thread_poll_one(void)
+{
+  int ret = 0;
+  struct tcpip_msg *msg;
+
+  if (sys_arch_mbox_tryfetch(&tcpip_mbox, (void **)&msg) != SYS_ARCH_TIMEOUT) {
+    LOCK_TCPIP_CORE();
+    if (msg != NULL) {
+      tcpip_thread_handle_msg(msg);
+      ret = 1;
+    }
+    UNLOCK_TCPIP_CORE();
+  }
+  return ret;
+}
+#endif
+
+/**
+ * Pass a received packet to tcpip_thread for input processing
+ *
+ * @param p the received packet
+ * @param inp the network interface on which the packet was received
+ * @param input_fn input function to call
+ */
+err_t
+tcpip_inpkt(struct pbuf *p, struct netif *inp, netif_input_fn input_fn)
+{
+#if LWIP_TCPIP_CORE_LOCKING_INPUT
+  err_t ret;
+  LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_inpkt: PACKET %p/%p\n", (void *)p, (void *)inp));
+  LOCK_TCPIP_CORE();
+  ret = input_fn(p, inp);
+  UNLOCK_TCPIP_CORE();
+  return ret;
+#else /* LWIP_TCPIP_CORE_LOCKING_INPUT */
+  struct tcpip_msg *msg;
+
+  LWIP_ASSERT("Invalid mbox", sys_mbox_valid_val(tcpip_mbox));
+
+  msg = (struct tcpip_msg *)memp_malloc(MEMP_TCPIP_MSG_INPKT);
+  if (msg == NULL) {
+    return ERR_MEM;
+  }
+
+  msg->type = TCPIP_MSG_INPKT;
+  msg->msg.inp.p = p;
+  msg->msg.inp.netif = inp;
+  msg->msg.inp.input_fn = input_fn;
+  if (sys_mbox_trypost(&tcpip_mbox, msg) != ERR_OK) {
+    memp_free(MEMP_TCPIP_MSG_INPKT, msg);
+    return ERR_MEM;
+  }
+  return ERR_OK;
+#endif /* LWIP_TCPIP_CORE_LOCKING_INPUT */
+}
+
+/**
+ * @ingroup lwip_os
+ * Pass a received packet to tcpip_thread for input processing with
+ * ethernet_input or ip_input. Don't call directly, pass to netif_add()
+ * and call netif->input().
+ *
+ * @param p the received packet, p->payload pointing to the Ethernet header or
+ *          to an IP header (if inp doesn't have NETIF_FLAG_ETHARP or
+ *          NETIF_FLAG_ETHERNET flags)
+ * @param inp the network interface on which the packet was received
+ */
+err_t
+tcpip_input(struct pbuf *p, struct netif *inp)
+{
+#if LWIP_ETHERNET
+  if (inp->flags & (NETIF_FLAG_ETHARP | NETIF_FLAG_ETHERNET)) {
+    return tcpip_inpkt(p, inp, ethernet_input);
+  } else
+#endif /* LWIP_ETHERNET */
+    return tcpip_inpkt(p, inp, ip_input);
+}
+
+/**
+ * @ingroup lwip_os
+ * Call a specific function in the thread context of
+ * tcpip_thread for easy access synchronization.
+ * A function called in that way may access lwIP core code
+ * without fearing concurrent access.
+ * Blocks until the request is posted.
+ * Must not be called from interrupt context!
+ *
+ * @param function the function to call
+ * @param ctx parameter passed to f
+ * @return ERR_OK if the function was called, another err_t if not
+ *
+ * @see tcpip_try_callback
+ */
+err_t
+tcpip_callback(tcpip_callback_fn function, void *ctx)
+{
+  struct tcpip_msg *msg;
+
+  LWIP_ASSERT("Invalid mbox", sys_mbox_valid_val(tcpip_mbox));
+
+  msg = (struct tcpip_msg *)memp_malloc(MEMP_TCPIP_MSG_API);
+  if (msg == NULL) {
+    return ERR_MEM;
+  }
+
+  msg->type = TCPIP_MSG_CALLBACK;
+  msg->msg.cb.function = function;
+  msg->msg.cb.ctx = ctx;
+
+  sys_mbox_post(&tcpip_mbox, msg);
+  return ERR_OK;
+}
+
+/**
+ * @ingroup lwip_os
+ * Call a specific function in the thread context of
+ * tcpip_thread for easy access synchronization.
+ * A function called in that way may access lwIP core code
+ * without fearing concurrent access.
+ * Does NOT block when the request cannot be posted because the
+ * tcpip_mbox is full, but returns ERR_MEM instead.
+ * Can be called from interrupt context.
+ *
+ * @param function the function to call
+ * @param ctx parameter passed to f
+ * @return ERR_OK if the function was called, another err_t if not
+ *
+ * @see tcpip_callback
+ */
+err_t
+tcpip_try_callback(tcpip_callback_fn function, void *ctx)
+{
+  struct tcpip_msg *msg;
+
+  LWIP_ASSERT("Invalid mbox", sys_mbox_valid_val(tcpip_mbox));
+
+  msg = (struct tcpip_msg *)memp_malloc(MEMP_TCPIP_MSG_API);
+  if (msg == NULL) {
+    return ERR_MEM;
+  }
+
+  msg->type = TCPIP_MSG_CALLBACK;
+  msg->msg.cb.function = function;
+  msg->msg.cb.ctx = ctx;
+
+  if (sys_mbox_trypost(&tcpip_mbox, msg) != ERR_OK) {
+    memp_free(MEMP_TCPIP_MSG_API, msg);
+    return ERR_MEM;
+  }
+  return ERR_OK;
+}
+
+#if LWIP_TCPIP_TIMEOUT && LWIP_TIMERS
+/**
+ * call sys_timeout in tcpip_thread
+ *
+ * @param msecs time in milliseconds for timeout
+ * @param h function to be called on timeout
+ * @param arg argument to pass to timeout function h
+ * @return ERR_MEM on memory error, ERR_OK otherwise
+ */
+err_t
+tcpip_timeout(u32_t msecs, sys_timeout_handler h, void *arg)
+{
+  struct tcpip_msg *msg;
+
+  LWIP_ASSERT("Invalid mbox", sys_mbox_valid_val(tcpip_mbox));
+
+  msg = (struct tcpip_msg *)memp_malloc(MEMP_TCPIP_MSG_API);
+  if (msg == NULL) {
+    return ERR_MEM;
+  }
+
+  msg->type = TCPIP_MSG_TIMEOUT;
+  msg->msg.tmo.msecs = msecs;
+  msg->msg.tmo.h = h;
+  msg->msg.tmo.arg = arg;
+  sys_mbox_post(&tcpip_mbox, msg);
+  return ERR_OK;
+}
+
+/**
+ * call sys_untimeout in tcpip_thread
+ *
+ * @param h function to be called on timeout
+ * @param arg argument to pass to timeout function h
+ * @return ERR_MEM on memory error, ERR_OK otherwise
+ */
+err_t
+tcpip_untimeout(sys_timeout_handler h, void *arg)
+{
+  struct tcpip_msg *msg;
+
+  LWIP_ASSERT("Invalid mbox", sys_mbox_valid_val(tcpip_mbox));
+
+  msg = (struct tcpip_msg *)memp_malloc(MEMP_TCPIP_MSG_API);
+  if (msg == NULL) {
+    return ERR_MEM;
+  }
+
+  msg->type = TCPIP_MSG_UNTIMEOUT;
+  msg->msg.tmo.h = h;
+  msg->msg.tmo.arg = arg;
+  sys_mbox_post(&tcpip_mbox, msg);
+  return ERR_OK;
+}
+#endif /* LWIP_TCPIP_TIMEOUT && LWIP_TIMERS */
+
+
+/**
+ * Sends a message to TCPIP thread to call a function. Caller thread blocks on
+ * on a provided semaphore, which ist NOT automatically signalled by TCPIP thread,
+ * this has to be done by the user.
+ * It is recommended to use LWIP_TCPIP_CORE_LOCKING since this is the way
+ * with least runtime overhead.
+ *
+ * @param fn function to be called from TCPIP thread
+ * @param apimsg argument to API function
+ * @param sem semaphore to wait on
+ * @return ERR_OK if the function was called, another err_t if not
+ */
+err_t
+tcpip_send_msg_wait_sem(tcpip_callback_fn fn, void *apimsg, sys_sem_t *sem)
+{
+#if LWIP_TCPIP_CORE_LOCKING
+  LWIP_UNUSED_ARG(sem);
+  LOCK_TCPIP_CORE();
+  fn(apimsg);
+  UNLOCK_TCPIP_CORE();
+  return ERR_OK;
+#else /* LWIP_TCPIP_CORE_LOCKING */
+  TCPIP_MSG_VAR_DECLARE(msg);
+
+  LWIP_ASSERT("semaphore not initialized", sys_sem_valid(sem));
+  LWIP_ASSERT("Invalid mbox", sys_mbox_valid_val(tcpip_mbox));
+
+  TCPIP_MSG_VAR_ALLOC(msg);
+  TCPIP_MSG_VAR_REF(msg).type = TCPIP_MSG_API;
+  TCPIP_MSG_VAR_REF(msg).msg.api_msg.function = fn;
+  TCPIP_MSG_VAR_REF(msg).msg.api_msg.msg = apimsg;
+  sys_mbox_post(&tcpip_mbox, &TCPIP_MSG_VAR_REF(msg));
+  sys_arch_sem_wait(sem, 0);
+  TCPIP_MSG_VAR_FREE(msg);
+  return ERR_OK;
+#endif /* LWIP_TCPIP_CORE_LOCKING */
+}
+
+/**
+ * Synchronously calls function in TCPIP thread and waits for its completion.
+ * It is recommended to use LWIP_TCPIP_CORE_LOCKING (preferred) or
+ * LWIP_NETCONN_SEM_PER_THREAD.
+ * If not, a semaphore is created and destroyed on every call which is usually
+ * an expensive/slow operation.
+ * @param fn Function to call
+ * @param call Call parameters
+ * @return Return value from tcpip_api_call_fn
+ */
+err_t
+tcpip_api_call(tcpip_api_call_fn fn, struct tcpip_api_call_data *call)
+{
+#if LWIP_TCPIP_CORE_LOCKING
+  err_t err;
+  LOCK_TCPIP_CORE();
+  err = fn(call);
+  UNLOCK_TCPIP_CORE();
+  return err;
+#else /* LWIP_TCPIP_CORE_LOCKING */
+  TCPIP_MSG_VAR_DECLARE(msg);
+
+#if !LWIP_NETCONN_SEM_PER_THREAD
+  err_t err = sys_sem_new(&call->sem, 0);
+  if (err != ERR_OK) {
+    return err;
+  }
+#endif /* LWIP_NETCONN_SEM_PER_THREAD */
+
+  LWIP_ASSERT("Invalid mbox", sys_mbox_valid_val(tcpip_mbox));
+
+  TCPIP_MSG_VAR_ALLOC(msg);
+  TCPIP_MSG_VAR_REF(msg).type = TCPIP_MSG_API_CALL;
+  TCPIP_MSG_VAR_REF(msg).msg.api_call.arg = call;
+  TCPIP_MSG_VAR_REF(msg).msg.api_call.function = fn;
+#if LWIP_NETCONN_SEM_PER_THREAD
+  TCPIP_MSG_VAR_REF(msg).msg.api_call.sem = LWIP_NETCONN_THREAD_SEM_GET();
+#else /* LWIP_NETCONN_SEM_PER_THREAD */
+  TCPIP_MSG_VAR_REF(msg).msg.api_call.sem = &call->sem;
+#endif /* LWIP_NETCONN_SEM_PER_THREAD */
+  sys_mbox_post(&tcpip_mbox, &TCPIP_MSG_VAR_REF(msg));
+  sys_arch_sem_wait(TCPIP_MSG_VAR_REF(msg).msg.api_call.sem, 0);
+  TCPIP_MSG_VAR_FREE(msg);
+
+#if !LWIP_NETCONN_SEM_PER_THREAD
+  sys_sem_free(&call->sem);
+#endif /* LWIP_NETCONN_SEM_PER_THREAD */
+
+  return call->err;
+#endif /* LWIP_TCPIP_CORE_LOCKING */
+}
+
+/**
+ * @ingroup lwip_os
+ * Allocate a structure for a static callback message and initialize it.
+ * The message has a special type such that lwIP never frees it.
+ * This is intended to be used to send "static" messages from interrupt context,
+ * e.g. the message is allocated once and posted several times from an IRQ
+ * using tcpip_callbackmsg_trycallback().
+ * Example usage: Trigger execution of an ethernet IRQ DPC routine in lwIP thread context.
+ * 
+ * @param function the function to call
+ * @param ctx parameter passed to function
+ * @return a struct pointer to pass to tcpip_callbackmsg_trycallback().
+ *
+ * @see tcpip_callbackmsg_trycallback()
+ * @see tcpip_callbackmsg_delete()
+ */
+struct tcpip_callback_msg *
+tcpip_callbackmsg_new(tcpip_callback_fn function, void *ctx)
+{
+  struct tcpip_msg *msg = (struct tcpip_msg *)memp_malloc(MEMP_TCPIP_MSG_API);
+  if (msg == NULL) {
+    return NULL;
+  }
+  msg->type = TCPIP_MSG_CALLBACK_STATIC;
+  msg->msg.cb.function = function;
+  msg->msg.cb.ctx = ctx;
+  return (struct tcpip_callback_msg *)msg;
+}
+
+/**
+ * @ingroup lwip_os
+ * Free a callback message allocated by tcpip_callbackmsg_new().
+ *
+ * @param msg the message to free
+ *
+ * @see tcpip_callbackmsg_new()
+ */
+void
+tcpip_callbackmsg_delete(struct tcpip_callback_msg *msg)
+{
+  memp_free(MEMP_TCPIP_MSG_API, msg);
+}
+
+/**
+ * @ingroup lwip_os
+ * Try to post a callback-message to the tcpip_thread tcpip_mbox.
+ *
+ * @param msg pointer to the message to post
+ * @return sys_mbox_trypost() return code
+ *
+ * @see tcpip_callbackmsg_new()
+ */
+err_t
+tcpip_callbackmsg_trycallback(struct tcpip_callback_msg *msg)
+{
+  LWIP_ASSERT("Invalid mbox", sys_mbox_valid_val(tcpip_mbox));
+  return sys_mbox_trypost(&tcpip_mbox, msg);
+}
+
+/**
+ * @ingroup lwip_os
+ * Try to post a callback-message to the tcpip_thread mbox.
+ * Same as @ref tcpip_callbackmsg_trycallback but calls sys_mbox_trypost_fromisr(),
+ * mainly to help FreeRTOS, where calls differ between task level and ISR level.
+ *
+ * @param msg pointer to the message to post
+ * @return sys_mbox_trypost_fromisr() return code (without change, so this
+ *         knowledge can be used to e.g. propagate "bool needs_scheduling")
+ *
+ * @see tcpip_callbackmsg_new()
+ */
+err_t
+tcpip_callbackmsg_trycallback_fromisr(struct tcpip_callback_msg *msg)
+{
+  LWIP_ASSERT("Invalid mbox", sys_mbox_valid_val(tcpip_mbox));
+  return sys_mbox_trypost_fromisr(&tcpip_mbox, msg);
+}
+
+/**
+ * @ingroup lwip_os
+ * Initialize this module:
+ * - initialize all sub modules
+ * - start the tcpip_thread
+ *
+ * @param initfunc a function to call when tcpip_thread is running and finished initializing
+ * @param arg argument to pass to initfunc
+ */
+void
+tcpip_init(tcpip_init_done_fn initfunc, void *arg)
+{
+  lwip_init();
+
+  tcpip_init_done = initfunc;
+  tcpip_init_done_arg = arg;
+  if (sys_mbox_new(&tcpip_mbox, TCPIP_MBOX_SIZE) != ERR_OK) {
+    LWIP_ASSERT("failed to create tcpip_thread mbox", 0);
+  }
+#if LWIP_TCPIP_CORE_LOCKING
+  if (sys_mutex_new(&lock_tcpip_core) != ERR_OK) {
+    LWIP_ASSERT("failed to create lock_tcpip_core", 0);
+  }
+#endif /* LWIP_TCPIP_CORE_LOCKING */
+
+  sys_thread_new(TCPIP_THREAD_NAME, tcpip_thread, NULL, TCPIP_THREAD_STACKSIZE, TCPIP_THREAD_PRIO);
+}
+
+/**
+ * Simple callback function used with tcpip_callback to free a pbuf
+ * (pbuf_free has a wrong signature for tcpip_callback)
+ *
+ * @param p The pbuf (chain) to be dereferenced.
+ */
+static void
+pbuf_free_int(void *p)
+{
+  struct pbuf *q = (struct pbuf *)p;
+  pbuf_free(q);
+}
+
+/**
+ * A simple wrapper function that allows you to free a pbuf from interrupt context.
+ *
+ * @param p The pbuf (chain) to be dereferenced.
+ * @return ERR_OK if callback could be enqueued, an err_t if not
+ */
+err_t
+pbuf_free_callback(struct pbuf *p)
+{
+  return tcpip_try_callback(pbuf_free_int, p);
+}
+
+/**
+ * A simple wrapper function that allows you to free heap memory from
+ * interrupt context.
+ *
+ * @param m the heap memory to free
+ * @return ERR_OK if callback could be enqueued, an err_t if not
+ */
+err_t
+mem_free_callback(void *m)
+{
+  return tcpip_try_callback(mem_free, m);
+}
+
+#endif /* !NO_SYS */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/apps/altcp_tls/altcp_tls_mbedtls.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/apps/altcp_tls/altcp_tls_mbedtls.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/apps/altcp_tls/altcp_tls_mbedtls.c	(revision 457)
@@ -0,0 +1,1178 @@
+/**
+ * @file
+ * Application layered TCP/TLS connection API (to be used from TCPIP thread)
+ *
+ * This file provides a TLS layer using mbedTLS
+ */
+
+/*
+ * Copyright (c) 2017 Simon Goldschmidt
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Simon Goldschmidt <goldsimon@gmx.de>
+ *
+ * Watch out:
+ * - 'sent' is always called with len==0 to the upper layer. This is because keeping
+ *   track of the ratio of application data and TLS overhead would be too much.
+ *
+ * Mandatory security-related configuration:
+ * - define ALTCP_MBEDTLS_RNG_FN to mbedtls_entropy_func to use the standard mbedTLS
+ *   entropy and ensure to add at least one strong entropy source to your mbedtls port
+ *   (implement mbedtls_platform_entropy_poll or mbedtls_hardware_poll providing strong
+ *   entropy)
+ * - define ALTCP_MBEDTLS_ENTROPY_PTR and ALTCP_MBEDTLS_ENTROPY_LEN to something providing
+ *   GOOD custom entropy
+ *
+ * Missing things / @todo:
+ * - some unhandled/untested things migh be caught by LWIP_ASSERTs...
+ */
+
+#include "lwip/opt.h"
+
+#if LWIP_ALTCP /* don't build if not configured for use in lwipopts.h */
+
+#include "lwip/apps/altcp_tls_mbedtls_opts.h"
+
+#if LWIP_ALTCP_TLS && LWIP_ALTCP_TLS_MBEDTLS
+
+#include "lwip/altcp.h"
+#include "lwip/altcp_tls.h"
+#include "lwip/priv/altcp_priv.h"
+
+#include "altcp_tls_mbedtls_structs.h"
+#include "altcp_tls_mbedtls_mem.h"
+
+/* @todo: which includes are really needed? */
+#include "mbedtls/entropy.h"
+#include "mbedtls/ctr_drbg.h"
+#include "mbedtls/certs.h"
+#include "mbedtls/x509.h"
+#include "mbedtls/ssl.h"
+#include "mbedtls/net.h"
+#include "mbedtls/error.h"
+#include "mbedtls/debug.h"
+#include "mbedtls/platform.h"
+#include "mbedtls/memory_buffer_alloc.h"
+#include "mbedtls/ssl_cache.h"
+
+#include "mbedtls/ssl_internal.h" /* to call mbedtls_flush_output after ERR_MEM */
+
+#include <string.h>
+
+#ifndef ALTCP_MBEDTLS_ENTROPY_PTR
+#define ALTCP_MBEDTLS_ENTROPY_PTR   NULL
+#endif
+#ifndef ALTCP_MBEDTLS_ENTROPY_LEN
+#define ALTCP_MBEDTLS_ENTROPY_LEN   0
+#endif
+
+/* Variable prototype, the actual declaration is at the end of this file
+   since it contains pointers to static functions declared here */
+extern const struct altcp_functions altcp_mbedtls_functions;
+
+/** Our global mbedTLS configuration (server-specific, not connection-specific) */
+struct altcp_tls_config {
+  mbedtls_ssl_config conf;
+  mbedtls_entropy_context entropy;
+  mbedtls_ctr_drbg_context ctr_drbg;
+  mbedtls_x509_crt *cert;
+  mbedtls_pk_context *pkey;
+  mbedtls_x509_crt *ca;
+#if defined(MBEDTLS_SSL_CACHE_C) && ALTCP_MBEDTLS_SESSION_CACHE_TIMEOUT_SECONDS
+  /** Inter-connection cache for fast connection startup */
+  struct mbedtls_ssl_cache_context cache;
+#endif
+};
+
+static err_t altcp_mbedtls_lower_recv(void *arg, struct altcp_pcb *inner_conn, struct pbuf *p, err_t err);
+static err_t altcp_mbedtls_setup(void *conf, struct altcp_pcb *conn, struct altcp_pcb *inner_conn);
+static err_t altcp_mbedtls_lower_recv_process(struct altcp_pcb *conn, altcp_mbedtls_state_t *state);
+static err_t altcp_mbedtls_handle_rx_appldata(struct altcp_pcb *conn, altcp_mbedtls_state_t *state);
+static int altcp_mbedtls_bio_send(void *ctx, const unsigned char *dataptr, size_t size);
+
+
+/* callback functions from inner/lower connection: */
+
+/** Accept callback from lower connection (i.e. TCP)
+ * Allocate one of our structures, assign it to the new connection's 'state' and
+ * call the new connection's 'accepted' callback. If that succeeds, we wait
+ * to receive connection setup handshake bytes from the client.
+ */
+static err_t
+altcp_mbedtls_lower_accept(void *arg, struct altcp_pcb *accepted_conn, err_t err)
+{
+  struct altcp_pcb *listen_conn = (struct altcp_pcb *)arg;
+  if (listen_conn && listen_conn->state && listen_conn->accept) {
+    err_t setup_err;
+    altcp_mbedtls_state_t *listen_state = (altcp_mbedtls_state_t *)listen_conn->state;
+    /* create a new altcp_conn to pass to the next 'accept' callback */
+    struct altcp_pcb *new_conn = altcp_alloc();
+    if (new_conn == NULL) {
+      return ERR_MEM;
+    }
+    setup_err = altcp_mbedtls_setup(listen_state->conf, new_conn, accepted_conn);
+    if (setup_err != ERR_OK) {
+      altcp_free(new_conn);
+      return setup_err;
+    }
+    return listen_conn->accept(listen_conn->arg, new_conn, err);
+  }
+  return ERR_ARG;
+}
+
+/** Connected callback from lower connection (i.e. TCP).
+ * Not really implemented/tested yet...
+ */
+static err_t
+altcp_mbedtls_lower_connected(void *arg, struct altcp_pcb *inner_conn, err_t err)
+{
+  struct altcp_pcb *conn = (struct altcp_pcb *)arg;
+  LWIP_UNUSED_ARG(inner_conn); /* for LWIP_NOASSERT */
+  if (conn && conn->state) {
+    LWIP_ASSERT("pcb mismatch", conn->inner_conn == inner_conn);
+    /* upper connected is called when handshake is done */
+    if (err != ERR_OK) {
+      if (conn->connected) {
+        return conn->connected(conn->arg, conn, err);
+      }
+    }
+    return altcp_mbedtls_lower_recv_process(conn, (altcp_mbedtls_state_t *)conn->state);
+  }
+  return ERR_VAL;
+}
+
+/* Call recved for possibly more than an u16_t */
+static void
+altcp_mbedtls_lower_recved(struct altcp_pcb *inner_conn, int recvd_cnt)
+{
+  while (recvd_cnt > 0) {
+    u16_t recvd_part = (u16_t)LWIP_MIN(recvd_cnt, 0xFFFF);
+    altcp_recved(inner_conn, recvd_part);
+    recvd_cnt -= recvd_part;
+  }
+}
+
+/** Recv callback from lower connection (i.e. TCP)
+ * This one mainly differs between connection setup/handshake (data is fed into mbedTLS only)
+ * and application phase (data is decoded by mbedTLS and passed on to the application).
+ */
+static err_t
+altcp_mbedtls_lower_recv(void *arg, struct altcp_pcb *inner_conn, struct pbuf *p, err_t err)
+{
+  altcp_mbedtls_state_t *state;
+  struct altcp_pcb *conn = (struct altcp_pcb *)arg;
+
+  LWIP_ASSERT("no err expected", err == ERR_OK);
+  LWIP_UNUSED_ARG(err);
+
+  if (!conn) {
+    /* no connection given as arg? should not happen, but prevent pbuf/conn leaks */
+    if (p != NULL) {
+      pbuf_free(p);
+    }
+    altcp_close(inner_conn);
+    return ERR_CLSD;
+  }
+  state = (altcp_mbedtls_state_t *)conn->state;
+  LWIP_ASSERT("pcb mismatch", conn->inner_conn == inner_conn);
+  if (!state) {
+    /* already closed */
+    if (p != NULL) {
+      pbuf_free(p);
+    }
+    altcp_close(inner_conn);
+    return ERR_CLSD;
+  }
+
+  /* handle NULL pbuf (inner connection closed) */
+  if (p == NULL) {
+    /* remote host sent FIN, remember this (SSL state is destroyed
+        when both sides are closed only!) */
+    if ((state->flags & (ALTCP_MBEDTLS_FLAGS_HANDSHAKE_DONE | ALTCP_MBEDTLS_FLAGS_UPPER_CALLED)) ==
+        (ALTCP_MBEDTLS_FLAGS_HANDSHAKE_DONE | ALTCP_MBEDTLS_FLAGS_UPPER_CALLED)) {
+      /* need to notify upper layer (e.g. 'accept' called or 'connect' succeeded) */
+      if ((state->rx != NULL) || (state->rx_app != NULL)) {
+        state->flags |= ALTCP_MBEDTLS_FLAGS_RX_CLOSE_QUEUED;
+        /* this is a normal close (FIN) but we have unprocessed data, so delay the FIN */
+        altcp_mbedtls_handle_rx_appldata(conn, state);
+        return ERR_OK;
+      }
+      state->flags |= ALTCP_MBEDTLS_FLAGS_RX_CLOSED;
+      if (conn->recv) {
+        return conn->recv(conn->arg, conn, NULL, ERR_OK);
+      }
+    } else {
+      /* before connection setup is done: call 'err' */
+      if (conn->err) {
+        conn->err(conn->arg, ERR_CLSD);
+      }
+      altcp_close(conn);
+    }
+    return ERR_OK;
+  }
+
+  /* If we come here, the connection is in good state (handshake phase or application data phase).
+     Queue up the pbuf for processing as handshake data or application data. */
+  if (state->rx == NULL) {
+    state->rx = p;
+  } else {
+    LWIP_ASSERT("rx pbuf overflow", (int)p->tot_len + (int)p->len <= 0xFFFF);
+    pbuf_cat(state->rx, p);
+  }
+  return altcp_mbedtls_lower_recv_process(conn, state);
+}
+
+static err_t
+altcp_mbedtls_lower_recv_process(struct altcp_pcb *conn, altcp_mbedtls_state_t *state)
+{
+  if (!(state->flags & ALTCP_MBEDTLS_FLAGS_HANDSHAKE_DONE)) {
+    /* handle connection setup (handshake not done) */
+    int ret = mbedtls_ssl_handshake(&state->ssl_context);
+    /* try to send data... */
+    altcp_output(conn->inner_conn);
+    if (state->bio_bytes_read) {
+      /* acknowledge all bytes read */
+      altcp_mbedtls_lower_recved(conn->inner_conn, state->bio_bytes_read);
+      state->bio_bytes_read = 0;
+    }
+
+    if (ret == MBEDTLS_ERR_SSL_WANT_READ || ret == MBEDTLS_ERR_SSL_WANT_WRITE) {
+      /* handshake not done, wait for more recv calls */
+      LWIP_ASSERT("in this state, the rx chain should be empty", state->rx == NULL);
+      return ERR_OK;
+    }
+    if (ret != 0) {
+      LWIP_DEBUGF(ALTCP_MBEDTLS_DEBUG, ("mbedtls_ssl_handshake failed: %d\n", ret));
+      /* handshake failed, connection has to be closed */
+      if (conn->err) {
+        conn->err(conn->arg, ERR_CLSD);
+      }
+
+      if (altcp_close(conn) != ERR_OK) {
+        altcp_abort(conn);
+      }
+      return ERR_OK;
+    }
+    /* If we come here, handshake succeeded. */
+    LWIP_ASSERT("state", state->bio_bytes_read == 0);
+    LWIP_ASSERT("state", state->bio_bytes_appl == 0);
+    state->flags |= ALTCP_MBEDTLS_FLAGS_HANDSHAKE_DONE;
+    /* issue "connect" callback" to upper connection (this can only happen for active open) */
+    if (conn->connected) {
+      err_t err;
+      err = conn->connected(conn->arg, conn, ERR_OK);
+      if (err != ERR_OK) {
+        return err;
+      }
+    }
+    if (state->rx == NULL) {
+      return ERR_OK;
+    }
+  }
+  /* handle application data */
+  return altcp_mbedtls_handle_rx_appldata(conn, state);
+}
+
+/* Pass queued decoded rx data to application */
+static err_t
+altcp_mbedtls_pass_rx_data(struct altcp_pcb *conn, altcp_mbedtls_state_t *state)
+{
+  err_t err;
+  struct pbuf *buf;
+  LWIP_ASSERT("conn != NULL", conn != NULL);
+  LWIP_ASSERT("state != NULL", state != NULL);
+  buf = state->rx_app;
+  if (buf) {
+    state->rx_app = NULL;
+    if (conn->recv) {
+      u16_t tot_len = buf->tot_len;
+      /* this needs to be increased first because the 'recved' call may come nested */
+      state->rx_passed_unrecved += tot_len;
+      state->flags |= ALTCP_MBEDTLS_FLAGS_UPPER_CALLED;
+      err = conn->recv(conn->arg, conn, buf, ERR_OK);
+      if (err != ERR_OK) {
+        if (err == ERR_ABRT) {
+          return ERR_ABRT;
+        }
+        /* not received, leave the pbuf(s) queued (and decrease 'unrecved' again) */
+        LWIP_ASSERT("state == conn->state", state == conn->state);
+        state->rx_app = buf;
+        state->rx_passed_unrecved -= tot_len;
+        LWIP_ASSERT("state->rx_passed_unrecved >= 0", state->rx_passed_unrecved >= 0);
+        if (state->rx_passed_unrecved < 0) {
+          state->rx_passed_unrecved = 0;
+        }
+        return err;
+      }
+    } else {
+      pbuf_free(buf);
+    }
+  } else if ((state->flags & (ALTCP_MBEDTLS_FLAGS_RX_CLOSE_QUEUED | ALTCP_MBEDTLS_FLAGS_RX_CLOSED)) ==
+             ALTCP_MBEDTLS_FLAGS_RX_CLOSE_QUEUED) {
+    state->flags |= ALTCP_MBEDTLS_FLAGS_RX_CLOSED;
+    if (conn->recv) {
+      return conn->recv(conn->arg, conn, NULL, ERR_OK);
+    }
+  }
+
+  /* application may have close the connection */
+  if (conn->state != state) {
+    /* return error code to ensure altcp_mbedtls_handle_rx_appldata() exits the loop */
+    return ERR_CLSD;
+  }
+  return ERR_OK;
+}
+
+/* Helper function that processes rx application data stored in rx pbuf chain */
+static err_t
+altcp_mbedtls_handle_rx_appldata(struct altcp_pcb *conn, altcp_mbedtls_state_t *state)
+{
+  int ret;
+  LWIP_ASSERT("state != NULL", state != NULL);
+  if (!(state->flags & ALTCP_MBEDTLS_FLAGS_HANDSHAKE_DONE)) {
+    /* handshake not done yet */
+    return ERR_VAL;
+  }
+  do {
+    /* allocate a full-sized unchained PBUF_POOL: this is for RX! */
+    struct pbuf *buf = pbuf_alloc(PBUF_RAW, PBUF_POOL_BUFSIZE, PBUF_POOL);
+    if (buf == NULL) {
+      /* We're short on pbufs, try again later from 'poll' or 'recv' callbacks.
+         @todo: close on excessive allocation failures or leave this up to upper conn? */
+      return ERR_OK;
+    }
+
+    /* decrypt application data, this pulls encrypted RX data off state->rx pbuf chain */
+    ret = mbedtls_ssl_read(&state->ssl_context, (unsigned char *)buf->payload, PBUF_POOL_BUFSIZE);
+    if (ret < 0) {
+      if (ret == MBEDTLS_ERR_SSL_CLIENT_RECONNECT) {
+        /* client is initiating a new connection using the same source port -> close connection or make handshake */
+        LWIP_DEBUGF(ALTCP_MBEDTLS_DEBUG, ("new connection on same source port\n"));
+        LWIP_ASSERT("TODO: new connection on same source port, close this connection", 0);
+      } else if ((ret != MBEDTLS_ERR_SSL_WANT_READ) && (ret != MBEDTLS_ERR_SSL_WANT_WRITE)) {
+        if (ret == MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY) {
+          LWIP_DEBUGF(ALTCP_MBEDTLS_DEBUG, ("connection was closed gracefully\n"));
+        } else if (ret == MBEDTLS_ERR_NET_CONN_RESET) {
+          LWIP_DEBUGF(ALTCP_MBEDTLS_DEBUG, ("connection was reset by peer\n"));
+        }
+        pbuf_free(buf);
+        return ERR_OK;
+      } else {
+        pbuf_free(buf);
+        return ERR_OK;
+      }
+      pbuf_free(buf);
+      altcp_abort(conn);
+      return ERR_ABRT;
+    } else {
+      err_t err;
+      if (ret) {
+        LWIP_ASSERT("bogus receive length", ret <= PBUF_POOL_BUFSIZE);
+        /* trim pool pbuf to actually decoded length */
+        pbuf_realloc(buf, (u16_t)ret);
+
+        state->bio_bytes_appl += ret;
+        if (mbedtls_ssl_get_bytes_avail(&state->ssl_context) == 0) {
+          /* Record is done, now we know the share between application and protocol bytes
+             and can adjust the RX window by the protocol bytes.
+             The rest is 'recved' by the application calling our 'recved' fn. */
+          int overhead_bytes;
+          LWIP_ASSERT("bogus byte counts", state->bio_bytes_read > state->bio_bytes_appl);
+          overhead_bytes = state->bio_bytes_read - state->bio_bytes_appl;
+          altcp_mbedtls_lower_recved(conn->inner_conn, overhead_bytes);
+          state->bio_bytes_read = 0;
+          state->bio_bytes_appl = 0;
+        }
+
+        if (state->rx_app == NULL) {
+          state->rx_app = buf;
+        } else {
+          pbuf_cat(state->rx_app, buf);
+        }
+      } else {
+        pbuf_free(buf);
+        buf = NULL;
+      }
+      err = altcp_mbedtls_pass_rx_data(conn, state);
+      if (err != ERR_OK) {
+        if (err == ERR_ABRT) {
+          /* recv callback needs to return this as the pcb is deallocated */
+          return ERR_ABRT;
+        }
+        /* we hide all other errors as we retry feeding the pbuf to the app later */
+        return ERR_OK;
+      }
+    }
+  } while (ret > 0);
+  return ERR_OK;
+}
+
+/** Receive callback function called from mbedtls (set via mbedtls_ssl_set_bio)
+ * This function mainly copies data from pbufs and frees the pbufs after copying.
+ */
+static int
+altcp_mbedtls_bio_recv(void *ctx, unsigned char *buf, size_t len)
+{
+  struct altcp_pcb *conn = (struct altcp_pcb *)ctx;
+  altcp_mbedtls_state_t *state;
+  struct pbuf *p;
+  u16_t ret;
+  u16_t copy_len;
+  err_t err;
+
+  LWIP_UNUSED_ARG(err); /* for LWIP_NOASSERT */
+  if ((conn == NULL) || (conn->state == NULL)) {
+    return MBEDTLS_ERR_NET_INVALID_CONTEXT;
+  }
+  state = (altcp_mbedtls_state_t *)conn->state;
+  p = state->rx;
+
+  /* @todo: return MBEDTLS_ERR_NET_CONN_RESET/MBEDTLS_ERR_NET_RECV_FAILED? */
+
+  if ((p == NULL) || ((p->len == 0) && (p->next == NULL))) {
+    if (p) {
+      pbuf_free(p);
+    }
+    state->rx = NULL;
+    if ((state->flags & (ALTCP_MBEDTLS_FLAGS_RX_CLOSE_QUEUED | ALTCP_MBEDTLS_FLAGS_RX_CLOSED)) ==
+        ALTCP_MBEDTLS_FLAGS_RX_CLOSE_QUEUED) {
+      /* close queued but not passed up yet */
+      return 0;
+    }
+    return MBEDTLS_ERR_SSL_WANT_READ;
+  }
+  /* limit number of bytes again to copy from first pbuf in a chain only */
+  copy_len = (u16_t)LWIP_MIN(len, p->len);
+  /* copy the data */
+  ret = pbuf_copy_partial(p, buf, copy_len, 0);
+  LWIP_ASSERT("ret == copy_len", ret == copy_len);
+  /* hide the copied bytes from the pbuf */
+  err = pbuf_remove_header(p, ret);
+  LWIP_ASSERT("error", err == ERR_OK);
+  if (p->len == 0) {
+    /* the first pbuf has been fully read, free it */
+    state->rx = p->next;
+    p->next = NULL;
+    pbuf_free(p);
+  }
+
+  state->bio_bytes_read += (int)ret;
+  return ret;
+}
+
+/** Sent callback from lower connection (i.e. TCP)
+ * This only informs the upper layer to try to send more, not about
+ * the number of ACKed bytes.
+ */
+static err_t
+altcp_mbedtls_lower_sent(void *arg, struct altcp_pcb *inner_conn, u16_t len)
+{
+  struct altcp_pcb *conn = (struct altcp_pcb *)arg;
+  LWIP_UNUSED_ARG(inner_conn); /* for LWIP_NOASSERT */
+  LWIP_UNUSED_ARG(len);
+  if (conn) {
+    altcp_mbedtls_state_t *state = (altcp_mbedtls_state_t *)conn->state;
+    LWIP_ASSERT("pcb mismatch", conn->inner_conn == inner_conn);
+    if (!state || !(state->flags & ALTCP_MBEDTLS_FLAGS_HANDSHAKE_DONE)) {
+      /* @todo: do something here? */
+      return ERR_OK;
+    }
+    /* try to send more if we failed before */
+    mbedtls_ssl_flush_output(&state->ssl_context);
+    /* call upper sent with len==0 if the application already sent data */
+    if ((state->flags & ALTCP_MBEDTLS_FLAGS_APPLDATA_SENT) && conn->sent) {
+      return conn->sent(conn->arg, conn, 0);
+    }
+  }
+  return ERR_OK;
+}
+
+/** Poll callback from lower connection (i.e. TCP)
+ * Just pass this on to the application.
+ * @todo: retry sending?
+ */
+static err_t
+altcp_mbedtls_lower_poll(void *arg, struct altcp_pcb *inner_conn)
+{
+  struct altcp_pcb *conn = (struct altcp_pcb *)arg;
+  LWIP_UNUSED_ARG(inner_conn); /* for LWIP_NOASSERT */
+  if (conn) {
+    LWIP_ASSERT("pcb mismatch", conn->inner_conn == inner_conn);
+    /* check if there's unreceived rx data */
+    if (conn->state) {
+      altcp_mbedtls_state_t *state = (altcp_mbedtls_state_t *)conn->state;
+      /* try to send more if we failed before */
+      mbedtls_ssl_flush_output(&state->ssl_context);
+      if (altcp_mbedtls_handle_rx_appldata(conn, state) == ERR_ABRT) {
+        return ERR_ABRT;
+      }
+    }
+    if (conn->poll) {
+      return conn->poll(conn->arg, conn);
+    }
+  }
+  return ERR_OK;
+}
+
+static void
+altcp_mbedtls_lower_err(void *arg, err_t err)
+{
+  struct altcp_pcb *conn = (struct altcp_pcb *)arg;
+  if (conn) {
+    conn->inner_conn = NULL; /* already freed */
+    if (conn->err) {
+      conn->err(conn->arg, err);
+    }
+    altcp_free(conn);
+  }
+}
+
+/* setup functions */
+
+static void
+altcp_mbedtls_remove_callbacks(struct altcp_pcb *inner_conn)
+{
+  altcp_arg(inner_conn, NULL);
+  altcp_recv(inner_conn, NULL);
+  altcp_sent(inner_conn, NULL);
+  altcp_err(inner_conn, NULL);
+  altcp_poll(inner_conn, NULL, inner_conn->pollinterval);
+}
+
+static void
+altcp_mbedtls_setup_callbacks(struct altcp_pcb *conn, struct altcp_pcb *inner_conn)
+{
+  altcp_arg(inner_conn, conn);
+  altcp_recv(inner_conn, altcp_mbedtls_lower_recv);
+  altcp_sent(inner_conn, altcp_mbedtls_lower_sent);
+  altcp_err(inner_conn, altcp_mbedtls_lower_err);
+  /* tcp_poll is set when interval is set by application */
+  /* listen is set totally different :-) */
+}
+
+static err_t
+altcp_mbedtls_setup(void *conf, struct altcp_pcb *conn, struct altcp_pcb *inner_conn)
+{
+  int ret;
+  struct altcp_tls_config *config = (struct altcp_tls_config *)conf;
+  altcp_mbedtls_state_t *state;
+  if (!conf) {
+    return ERR_ARG;
+  }
+  LWIP_ASSERT("invalid inner_conn", conn != inner_conn);
+
+  /* allocate mbedtls context */
+  state = altcp_mbedtls_alloc(conf);
+  if (state == NULL) {
+    return ERR_MEM;
+  }
+  /* initialize mbedtls context: */
+  mbedtls_ssl_init(&state->ssl_context);
+  ret = mbedtls_ssl_setup(&state->ssl_context, &config->conf);
+  if (ret != 0) {
+    LWIP_DEBUGF(ALTCP_MBEDTLS_DEBUG, ("mbedtls_ssl_setup failed\n"));
+    /* @todo: convert 'ret' to err_t */
+    altcp_mbedtls_free(conf, state);
+    return ERR_MEM;
+  }
+  /* tell mbedtls about our I/O functions */
+  mbedtls_ssl_set_bio(&state->ssl_context, conn, altcp_mbedtls_bio_send, altcp_mbedtls_bio_recv, NULL);
+
+  altcp_mbedtls_setup_callbacks(conn, inner_conn);
+  conn->inner_conn = inner_conn;
+  conn->fns = &altcp_mbedtls_functions;
+  conn->state = state;
+  return ERR_OK;
+}
+
+struct altcp_pcb *
+altcp_tls_wrap(struct altcp_tls_config *config, struct altcp_pcb *inner_pcb)
+{
+  struct altcp_pcb *ret;
+  if (inner_pcb == NULL) {
+    return NULL;
+  }
+  ret = altcp_alloc();
+  if (ret != NULL) {
+    if (altcp_mbedtls_setup(config, ret, inner_pcb) != ERR_OK) {
+      altcp_free(ret);
+      return NULL;
+    }
+  }
+  return ret;
+}
+
+void *
+altcp_tls_context(struct altcp_pcb *conn)
+{
+  if (conn && conn->state) {
+    altcp_mbedtls_state_t *state = (altcp_mbedtls_state_t *)conn->state;
+    return &state->ssl_context;
+  }
+  return NULL;
+}
+
+#if ALTCP_MBEDTLS_DEBUG != LWIP_DBG_OFF
+static void
+altcp_mbedtls_debug(void *ctx, int level, const char *file, int line, const char *str)
+{
+  LWIP_UNUSED_ARG(ctx);
+  LWIP_UNUSED_ARG(level);
+  LWIP_UNUSED_ARG(file);
+  LWIP_UNUSED_ARG(line);
+  LWIP_UNUSED_ARG(str);
+
+  LWIP_DEBUGF(ALTCP_MBEDTLS_DEBUG, ("%s:%04d: %s", file, line, str));
+}
+#endif
+
+#ifndef ALTCP_MBEDTLS_RNG_FN
+/** ATTENTION: It is *really* important to *NOT* use this dummy RNG in production code!!!! */
+static int
+dummy_rng(void *ctx, unsigned char *buffer, size_t len)
+{
+  static size_t ctr;
+  size_t i;
+  LWIP_UNUSED_ARG(ctx);
+  for (i = 0; i < len; i++) {
+    buffer[i] = (unsigned char)++ctr;
+  }
+  return 0;
+}
+#define ALTCP_MBEDTLS_RNG_FN dummy_rng
+#endif /* ALTCP_MBEDTLS_RNG_FN */
+
+/** Create new TLS configuration
+ * ATTENTION: Server certificate and private key have to be added outside this function!
+ */
+static struct altcp_tls_config *
+altcp_tls_create_config(int is_server, int have_cert, int have_pkey, int have_ca)
+{
+  size_t sz;
+  int ret;
+  struct altcp_tls_config *conf;
+  mbedtls_x509_crt *mem;
+
+  if (TCP_WND < MBEDTLS_SSL_MAX_CONTENT_LEN) {
+    LWIP_DEBUGF(ALTCP_MBEDTLS_DEBUG|LWIP_DBG_LEVEL_SERIOUS,
+      ("altcp_tls: TCP_WND is smaller than the RX decryption buffer, connection RX might stall!\n"));
+  }
+
+  altcp_mbedtls_mem_init();
+
+  sz = sizeof(struct altcp_tls_config);
+  if (have_cert) {
+    sz += sizeof(mbedtls_x509_crt);
+  }
+  if (have_ca) {
+    sz += sizeof(mbedtls_x509_crt);
+  }
+  if (have_pkey) {
+    sz += sizeof(mbedtls_pk_context);
+  }
+
+  conf = (struct altcp_tls_config *)altcp_mbedtls_alloc_config(sz);
+  if (conf == NULL) {
+    return NULL;
+  }
+  mem = (mbedtls_x509_crt *)(conf + 1);
+  if (have_cert) {
+    conf->cert = mem;
+    mem++;
+  }
+  if (have_ca) {
+    conf->ca = mem;
+    mem++;
+  }
+  if (have_pkey) {
+    conf->pkey = (mbedtls_pk_context *)mem;
+  }
+
+  mbedtls_ssl_config_init(&conf->conf);
+  mbedtls_entropy_init(&conf->entropy);
+  mbedtls_ctr_drbg_init(&conf->ctr_drbg);
+
+  /* Seed the RNG */
+  ret = mbedtls_ctr_drbg_seed(&conf->ctr_drbg, ALTCP_MBEDTLS_RNG_FN, &conf->entropy, ALTCP_MBEDTLS_ENTROPY_PTR, ALTCP_MBEDTLS_ENTROPY_LEN);
+  if (ret != 0) {
+    LWIP_DEBUGF(ALTCP_MBEDTLS_DEBUG, ("mbedtls_ctr_drbg_seed failed: %d\n", ret));
+    altcp_mbedtls_free_config(conf);
+    return NULL;
+  }
+
+  /* Setup ssl context (@todo: what's different for a client here? -> might better be done on listen/connect) */
+  ret = mbedtls_ssl_config_defaults(&conf->conf, is_server ? MBEDTLS_SSL_IS_SERVER : MBEDTLS_SSL_IS_CLIENT,
+                                    MBEDTLS_SSL_TRANSPORT_STREAM, MBEDTLS_SSL_PRESET_DEFAULT);
+  if (ret != 0) {
+    LWIP_DEBUGF(ALTCP_MBEDTLS_DEBUG, ("mbedtls_ssl_config_defaults failed: %d\n", ret));
+    altcp_mbedtls_free_config(conf);
+    return NULL;
+  }
+  mbedtls_ssl_conf_authmode(&conf->conf, MBEDTLS_SSL_VERIFY_OPTIONAL);
+
+  mbedtls_ssl_conf_rng(&conf->conf, mbedtls_ctr_drbg_random, &conf->ctr_drbg);
+#if ALTCP_MBEDTLS_DEBUG != LWIP_DBG_OFF
+  mbedtls_ssl_conf_dbg(&conf->conf, altcp_mbedtls_debug, stdout);
+#endif
+#if defined(MBEDTLS_SSL_CACHE_C) && ALTCP_MBEDTLS_SESSION_CACHE_TIMEOUT_SECONDS
+  mbedtls_ssl_conf_session_cache(&conf->conf, &conf->cache, mbedtls_ssl_cache_get, mbedtls_ssl_cache_set);
+  mbedtls_ssl_cache_set_timeout(&conf->cache, 30);
+  mbedtls_ssl_cache_set_max_entries(&conf->cache, 30);
+#endif
+
+  return conf;
+}
+
+/** Create new TLS configuration
+ * This is a suboptimal version that gets the encrypted private key and its password,
+ * as well as the server certificate.
+ */
+struct altcp_tls_config *
+altcp_tls_create_config_server_privkey_cert(const u8_t *privkey, size_t privkey_len,
+    const u8_t *privkey_pass, size_t privkey_pass_len,
+    const u8_t *cert, size_t cert_len)
+{
+  int ret;
+  mbedtls_x509_crt *srvcert;
+  mbedtls_pk_context *pkey;
+  struct altcp_tls_config *conf = altcp_tls_create_config(1, 1, 1, 0);
+  if (conf == NULL) {
+    return NULL;
+  }
+
+  srvcert = conf->cert;
+  mbedtls_x509_crt_init(srvcert);
+
+  pkey = conf->pkey;
+  mbedtls_pk_init(pkey);
+
+  /* Load the certificates and private key */
+  ret = mbedtls_x509_crt_parse(srvcert, cert, cert_len);
+  if (ret != 0) {
+    LWIP_DEBUGF(ALTCP_MBEDTLS_DEBUG, ("mbedtls_x509_crt_parse failed: %d\n", ret));
+    altcp_mbedtls_free_config(conf);
+    return NULL;
+  }
+
+  ret = mbedtls_pk_parse_key(pkey, (const unsigned char *) privkey, privkey_len, privkey_pass, privkey_pass_len);
+  if (ret != 0) {
+    LWIP_DEBUGF(ALTCP_MBEDTLS_DEBUG, ("mbedtls_pk_parse_public_key failed: %d\n", ret));
+    mbedtls_x509_crt_free(srvcert);
+    altcp_mbedtls_free_config(conf);
+    return NULL;
+  }
+
+  mbedtls_ssl_conf_ca_chain(&conf->conf, srvcert->next, NULL);
+  ret = mbedtls_ssl_conf_own_cert(&conf->conf, srvcert, pkey);
+  if (ret != 0) {
+    LWIP_DEBUGF(ALTCP_MBEDTLS_DEBUG, ("mbedtls_ssl_conf_own_cert failed: %d\n", ret));
+    mbedtls_x509_crt_free(srvcert);
+    mbedtls_pk_free(pkey);
+    altcp_mbedtls_free_config(conf);
+    return NULL;
+  }
+  return conf;
+}
+
+static struct altcp_tls_config *
+altcp_tls_create_config_client_common(const u8_t *ca, size_t ca_len, int is_2wayauth)
+{
+  int ret;
+  struct altcp_tls_config *conf = altcp_tls_create_config(0, is_2wayauth, is_2wayauth, ca != NULL);
+  if (conf == NULL) {
+    return NULL;
+  }
+
+  /* Initialize the CA certificate if provided
+   * CA certificate is optional (to save memory) but recommended for production environment
+   * Without CA certificate, connection will be prone to man-in-the-middle attacks */
+  if (ca) {
+    mbedtls_x509_crt_init(conf->ca);
+    ret = mbedtls_x509_crt_parse(conf->ca, ca, ca_len);
+    if (ret != 0) {
+      LWIP_DEBUGF(ALTCP_MBEDTLS_DEBUG, ("mbedtls_x509_crt_parse ca failed: %d 0x%x", ret, -1*ret));
+      altcp_mbedtls_free_config(conf);
+      return NULL;
+    }
+
+    mbedtls_ssl_conf_ca_chain(&conf->conf, conf->ca, NULL);
+  }
+  return conf;
+}
+
+struct altcp_tls_config *
+altcp_tls_create_config_client(const u8_t *ca, size_t ca_len)
+{
+  return altcp_tls_create_config_client_common(ca, ca_len, 0);
+}
+
+struct altcp_tls_config *
+altcp_tls_create_config_client_2wayauth(const u8_t *ca, size_t ca_len, const u8_t *privkey, size_t privkey_len,
+                                        const u8_t *privkey_pass, size_t privkey_pass_len,
+                                        const u8_t *cert, size_t cert_len)
+{
+  int ret;
+  struct altcp_tls_config *conf;
+
+  if (!cert || !privkey) {
+    LWIP_DEBUGF(ALTCP_MBEDTLS_DEBUG, ("altcp_tls_create_config_client_2wayauth: certificate and priv key required"));
+    return NULL;
+  }
+
+  conf = altcp_tls_create_config_client_common(ca, ca_len, 1);
+  if (conf == NULL) {
+    return NULL;
+  }
+
+  /* Initialize the client certificate and corresponding private key */
+  mbedtls_x509_crt_init(conf->cert);
+  ret = mbedtls_x509_crt_parse(conf->cert, cert, cert_len);
+  if (ret != 0) {
+    LWIP_DEBUGF(ALTCP_MBEDTLS_DEBUG, ("mbedtls_x509_crt_parse cert failed: %d 0x%x", ret, -1*ret));
+    altcp_mbedtls_free_config(conf->cert);
+    return NULL;
+  }
+
+  mbedtls_pk_init(conf->pkey);
+  ret = mbedtls_pk_parse_key(conf->pkey, privkey, privkey_len, privkey_pass, privkey_pass_len);
+  if (ret != 0) {
+    LWIP_DEBUGF(ALTCP_MBEDTLS_DEBUG, ("mbedtls_pk_parse_key failed: %d 0x%x", ret, -1*ret));
+    altcp_mbedtls_free_config(conf);
+    return NULL;
+  }
+
+  ret = mbedtls_ssl_conf_own_cert(&conf->conf, conf->cert, conf->pkey);
+  if (ret != 0) {
+    LWIP_DEBUGF(ALTCP_MBEDTLS_DEBUG, ("mbedtls_ssl_conf_own_cert failed: %d 0x%x", ret, -1*ret));
+    altcp_mbedtls_free_config(conf);
+    return NULL;
+  }
+
+  return conf;
+}
+
+void
+altcp_tls_free_config(struct altcp_tls_config *conf)
+{
+  if (conf->pkey) {
+    mbedtls_pk_free(conf->pkey);
+  }
+  if (conf->cert) {
+    mbedtls_x509_crt_free(conf->cert);
+  }
+  if (conf->ca) {
+    mbedtls_x509_crt_free(conf->ca);
+  }  
+  altcp_mbedtls_free_config(conf);
+}
+
+/* "virtual" functions */
+static void
+altcp_mbedtls_set_poll(struct altcp_pcb *conn, u8_t interval)
+{
+  if (conn != NULL) {
+    altcp_poll(conn->inner_conn, altcp_mbedtls_lower_poll, interval);
+  }
+}
+
+static void
+altcp_mbedtls_recved(struct altcp_pcb *conn, u16_t len)
+{
+  u16_t lower_recved;
+  altcp_mbedtls_state_t *state;
+  if (conn == NULL) {
+    return;
+  }
+  state = (altcp_mbedtls_state_t *)conn->state;
+  if (state == NULL) {
+    return;
+  }
+  if (!(state->flags & ALTCP_MBEDTLS_FLAGS_HANDSHAKE_DONE)) {
+    return;
+  }
+  lower_recved = len;
+  if (lower_recved > state->rx_passed_unrecved) {
+    LWIP_DEBUGF(ALTCP_MBEDTLS_DEBUG, ("bogus recved count (len > state->rx_passed_unrecved / %d / %d)",
+                                      len, state->rx_passed_unrecved));
+    lower_recved = (u16_t)state->rx_passed_unrecved;
+  }
+  state->rx_passed_unrecved -= lower_recved;
+
+  altcp_recved(conn->inner_conn, lower_recved);
+}
+
+static err_t
+altcp_mbedtls_connect(struct altcp_pcb *conn, const ip_addr_t *ipaddr, u16_t port, altcp_connected_fn connected)
+{
+  if (conn == NULL) {
+    return ERR_VAL;
+  }
+  conn->connected = connected;
+  return altcp_connect(conn->inner_conn, ipaddr, port, altcp_mbedtls_lower_connected);
+}
+
+static struct altcp_pcb *
+altcp_mbedtls_listen(struct altcp_pcb *conn, u8_t backlog, err_t *err)
+{
+  struct altcp_pcb *lpcb;
+  if (conn == NULL) {
+    return NULL;
+  }
+  lpcb = altcp_listen_with_backlog_and_err(conn->inner_conn, backlog, err);
+  if (lpcb != NULL) {
+    conn->inner_conn = lpcb;
+    altcp_accept(lpcb, altcp_mbedtls_lower_accept);
+    return conn;
+  }
+  return NULL;
+}
+
+static void
+altcp_mbedtls_abort(struct altcp_pcb *conn)
+{
+  if (conn != NULL) {
+    altcp_abort(conn->inner_conn);
+  }
+}
+
+static err_t
+altcp_mbedtls_close(struct altcp_pcb *conn)
+{
+  struct altcp_pcb *inner_conn;
+  if (conn == NULL) {
+    return ERR_VAL;
+  }
+  inner_conn = conn->inner_conn;
+  if (inner_conn) {
+    err_t err;
+    altcp_poll_fn oldpoll = inner_conn->poll;
+    altcp_mbedtls_remove_callbacks(conn->inner_conn);
+    err = altcp_close(conn->inner_conn);
+    if (err != ERR_OK) {
+      /* not closed, set up all callbacks again */
+      altcp_mbedtls_setup_callbacks(conn, inner_conn);
+      /* poll callback is not included in the above */
+      altcp_poll(inner_conn, oldpoll, inner_conn->pollinterval);
+      return err;
+    }
+    conn->inner_conn = NULL;
+  }
+  altcp_free(conn);
+  return ERR_OK;
+}
+
+/** Allow caller of altcp_write() to limit to negotiated chunk size
+ *  or remaining sndbuf space of inner_conn.
+ */
+static u16_t
+altcp_mbedtls_sndbuf(struct altcp_pcb *conn)
+{
+  if (conn) {
+    altcp_mbedtls_state_t *state;
+    state = (altcp_mbedtls_state_t*)conn->state;
+    if (!state || !(state->flags & ALTCP_MBEDTLS_FLAGS_HANDSHAKE_DONE)) {
+      return 0;
+    }
+    if (conn->inner_conn) {
+      u16_t sndbuf = altcp_sndbuf(conn->inner_conn);
+      /* Take care of record header, IV, AuthTag */
+      int ssl_expan = mbedtls_ssl_get_record_expansion(&state->ssl_context);
+      if (ssl_expan > 0) {
+        size_t ssl_added = (u16_t)LWIP_MIN(ssl_expan, 0xFFFF);
+        /* internal sndbuf smaller than our offset */
+        if (ssl_added < sndbuf) {
+          size_t max_len = 0xFFFF;
+          size_t ret;
+#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH)
+          /* @todo: adjust ssl_added to real value related to negociated cipher */
+          size_t max_frag_len = mbedtls_ssl_get_max_frag_len(&state->ssl_context);
+          max_len = LWIP_MIN(max_frag_len, max_len);
+#endif
+          /* Adjust sndbuf of inner_conn with what added by SSL */
+          ret = LWIP_MIN(sndbuf - ssl_added, max_len);
+          LWIP_ASSERT("sndbuf overflow", ret <= 0xFFFF);
+          return (u16_t)ret;
+        }
+      }
+    }
+  }
+  /* fallback: use sendbuf of the inner connection */
+  return altcp_default_sndbuf(conn);
+}
+
+/** Write data to a TLS connection. Calls into mbedTLS, which in turn calls into
+ * @ref altcp_mbedtls_bio_send() to send the encrypted data
+ */
+static err_t
+altcp_mbedtls_write(struct altcp_pcb *conn, const void *dataptr, u16_t len, u8_t apiflags)
+{
+  int ret;
+  altcp_mbedtls_state_t *state;
+
+  LWIP_UNUSED_ARG(apiflags);
+
+  if (conn == NULL) {
+    return ERR_VAL;
+  }
+
+  state = (altcp_mbedtls_state_t *)conn->state;
+  if (state == NULL) {
+    /* @todo: which error? */
+    return ERR_CLSD;
+  }
+  if (!(state->flags & ALTCP_MBEDTLS_FLAGS_HANDSHAKE_DONE)) {
+    /* @todo: which error? */
+    return ERR_VAL;
+  }
+
+  /* HACK: if thre is something left to send, try to flush it and only
+     allow sending more if this succeeded (this is a hack because neither
+     returning 0 nor MBEDTLS_ERR_SSL_WANT_WRITE worked for me) */
+  if (state->ssl_context.out_left) {
+    mbedtls_ssl_flush_output(&state->ssl_context);
+    if (state->ssl_context.out_left) {
+      return ERR_MEM;
+    }
+  }
+  ret = mbedtls_ssl_write(&state->ssl_context, (const unsigned char *)dataptr, len);
+  /* try to send data... */
+  altcp_output(conn->inner_conn);
+  if (ret >= 0) {
+    if (ret == len) {
+      state->flags |= ALTCP_MBEDTLS_FLAGS_APPLDATA_SENT;
+      return ERR_OK;
+    } else {
+      /* @todo/@fixme: assumption: either everything sent or error */
+      LWIP_ASSERT("ret <= 0", 0);
+      return ERR_MEM;
+    }
+  } else {
+    if (ret == MBEDTLS_ERR_SSL_WANT_WRITE) {
+      /* @todo: convert error to err_t */
+      return ERR_MEM;
+    }
+    LWIP_ASSERT("unhandled error", 0);
+    return ERR_VAL;
+  }
+}
+
+/** Send callback function called from mbedtls (set via mbedtls_ssl_set_bio)
+ * This function is either called during handshake or when sending application
+ * data via @ref altcp_mbedtls_write (or altcp_write)
+ */
+static int
+altcp_mbedtls_bio_send(void *ctx, const unsigned char *dataptr, size_t size)
+{
+  struct altcp_pcb *conn = (struct altcp_pcb *) ctx;
+  int written = 0;
+  size_t size_left = size;
+  u8_t apiflags = TCP_WRITE_FLAG_COPY;
+
+  LWIP_ASSERT("conn != NULL", conn != NULL);
+  if ((conn == NULL) || (conn->inner_conn == NULL)) {
+    return MBEDTLS_ERR_NET_INVALID_CONTEXT;
+  }
+
+  while (size_left) {
+    u16_t write_len = (u16_t)LWIP_MIN(size_left, 0xFFFF);
+    err_t err = altcp_write(conn->inner_conn, (const void *)dataptr, write_len, apiflags);
+    if (err == ERR_OK) {
+      written += write_len;
+      size_left -= write_len;
+    } else if (err == ERR_MEM) {
+      if (written) {
+        return written;
+      }
+      return 0; /* MBEDTLS_ERR_SSL_WANT_WRITE; */
+    } else {
+      LWIP_ASSERT("tls_write, tcp_write: err != ERR MEM", 0);
+      /* @todo: return MBEDTLS_ERR_NET_CONN_RESET or MBEDTLS_ERR_NET_SEND_FAILED */
+      return MBEDTLS_ERR_NET_SEND_FAILED;
+    }
+  }
+  return written;
+}
+
+static u16_t
+altcp_mbedtls_mss(struct altcp_pcb *conn)
+{
+  if (conn == NULL) {
+    return 0;
+  }
+  /* @todo: LWIP_MIN(mss, mbedtls_ssl_get_max_frag_len()) ? */
+  return altcp_mss(conn->inner_conn);
+}
+
+static void
+altcp_mbedtls_dealloc(struct altcp_pcb *conn)
+{
+  /* clean up and free tls state */
+  if (conn) {
+    altcp_mbedtls_state_t *state = (altcp_mbedtls_state_t *)conn->state;
+    if (state) {
+      mbedtls_ssl_free(&state->ssl_context);
+      state->flags = 0;
+      if (state->rx) {
+        /* free leftover (unhandled) rx pbufs */
+        pbuf_free(state->rx);
+        state->rx = NULL;
+      }
+      altcp_mbedtls_free(state->conf, state);
+      conn->state = NULL;
+    }
+  }
+}
+
+const struct altcp_functions altcp_mbedtls_functions = {
+  altcp_mbedtls_set_poll,
+  altcp_mbedtls_recved,
+  altcp_default_bind,
+  altcp_mbedtls_connect,
+  altcp_mbedtls_listen,
+  altcp_mbedtls_abort,
+  altcp_mbedtls_close,
+  altcp_default_shutdown,
+  altcp_mbedtls_write,
+  altcp_default_output,
+  altcp_mbedtls_mss,
+  altcp_mbedtls_sndbuf,
+  altcp_default_sndqueuelen,
+  altcp_default_nagle_disable,
+  altcp_default_nagle_enable,
+  altcp_default_nagle_disabled,
+  altcp_default_setprio,
+  altcp_mbedtls_dealloc,
+  altcp_default_get_tcp_addrinfo,
+  altcp_default_get_ip,
+  altcp_default_get_port
+#ifdef LWIP_DEBUG
+  , altcp_default_dbg_get_tcp_state
+#endif
+};
+
+#endif /* LWIP_ALTCP_TLS && LWIP_ALTCP_TLS_MBEDTLS */
+#endif /* LWIP_ALTCP */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/apps/altcp_tls/altcp_tls_mbedtls_mem.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/apps/altcp_tls/altcp_tls_mbedtls_mem.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/apps/altcp_tls/altcp_tls_mbedtls_mem.c	(revision 457)
@@ -0,0 +1,210 @@
+/**
+ * @file
+ * Application layered TCP connection API (to be used from TCPIP thread)
+ *
+ * This file contains memory management functions for a TLS layer using mbedTLS.
+ *
+ * ATTENTION: For production usage, you might want to override this file with
+ *            your own implementation since this implementation simply uses the
+ *            lwIP heap without caring for fragmentation or leaving heap for
+ *            other parts of lwIP!
+ */
+
+/*
+ * Copyright (c) 2017 Simon Goldschmidt
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Simon Goldschmidt <goldsimon@gmx.de>
+ *
+ * Missing things / @todo:
+ * - RX data is acknowledged after receiving (tcp_recved is called when enqueueing
+ *   the pbuf for mbedTLS receive, not when processed by mbedTLS or the inner
+ *   connection; altcp_recved() from inner connection does nothing)
+ * - TX data is marked as 'sent' (i.e. acknowledged; sent callback is called) right
+ *   after enqueueing for transmission, not when actually ACKed be the remote host.
+ */
+
+#include "lwip/opt.h"
+
+#if LWIP_ALTCP /* don't build if not configured for use in lwipopts.h */
+
+#include "lwip/apps/altcp_tls_mbedtls_opts.h"
+
+#if LWIP_ALTCP_TLS && LWIP_ALTCP_TLS_MBEDTLS
+
+#include "altcp_tls_mbedtls_mem.h"
+#include "altcp_tls_mbedtls_structs.h"
+#include "lwip/mem.h"
+
+#include "mbedtls/platform.h"
+
+#include <string.h>
+
+#ifndef ALTCP_MBEDTLS_MEM_DEBUG
+#define ALTCP_MBEDTLS_MEM_DEBUG   LWIP_DBG_OFF
+#endif
+
+#if defined(MBEDTLS_PLATFORM_MEMORY) && \
+   (!defined(MBEDTLS_PLATFORM_FREE_MACRO) || \
+    defined(MBEDTLS_PLATFORM_CALLOC_MACRO))
+#define ALTCP_MBEDTLS_PLATFORM_ALLOC 1
+#else
+#define ALTCP_MBEDTLS_PLATFORM_ALLOC 0
+#endif
+
+#if ALTCP_MBEDTLS_PLATFORM_ALLOC
+
+#ifndef ALTCP_MBEDTLS_PLATFORM_ALLOC_STATS
+#define ALTCP_MBEDTLS_PLATFORM_ALLOC_STATS 0
+#endif
+
+/* This is an example/debug implementation of alloc/free functions only */
+typedef struct altcp_mbedtls_malloc_helper_s {
+  size_t c;
+  size_t len;
+} altcp_mbedtls_malloc_helper_t;
+
+#if ALTCP_MBEDTLS_PLATFORM_ALLOC_STATS
+typedef struct altcp_mbedtls_malloc_stats_s {
+  size_t allocedBytes;
+  size_t allocCnt;
+  size_t maxBytes;
+  size_t totalBytes;
+} altcp_mbedtls_malloc_stats_t;
+altcp_mbedtls_malloc_stats_t altcp_mbedtls_malloc_stats;
+volatile int altcp_mbedtls_malloc_clear_stats;
+#endif
+
+static void *
+tls_malloc(size_t c, size_t len)
+{
+  altcp_mbedtls_malloc_helper_t *hlpr;
+  void *ret;
+  size_t alloc_size;
+#if ALTCP_MBEDTLS_PLATFORM_ALLOC_STATS
+  if (altcp_mbedtls_malloc_clear_stats) {
+    altcp_mbedtls_malloc_clear_stats = 0;
+    memset(&altcp_mbedtls_malloc_stats, 0, sizeof(altcp_mbedtls_malloc_stats));
+  }
+#endif
+  alloc_size = sizeof(altcp_mbedtls_malloc_helper_t) + (c * len);
+  /* check for maximum allocation size, mainly to prevent mem_size_t overflow */
+  if (alloc_size > MEM_SIZE) {
+    LWIP_DEBUGF(ALTCP_MBEDTLS_MEM_DEBUG, ("mbedtls allocation too big: %c * %d bytes vs MEM_SIZE=%d",
+                                          (int)c, (int)len, (int)MEM_SIZE));
+    return NULL;
+  }
+  hlpr = (altcp_mbedtls_malloc_helper_t *)mem_malloc((mem_size_t)alloc_size);
+  if (hlpr == NULL) {
+    LWIP_DEBUGF(ALTCP_MBEDTLS_MEM_DEBUG, ("mbedtls alloc callback failed for %c * %d bytes", (int)c, (int)len));
+    return NULL;
+  }
+#if ALTCP_MBEDTLS_PLATFORM_ALLOC_STATS
+  altcp_mbedtls_malloc_stats.allocCnt++;
+  altcp_mbedtls_malloc_stats.allocedBytes += c * len;
+  if (altcp_mbedtls_malloc_stats.allocedBytes > altcp_mbedtls_malloc_stats.maxBytes) {
+    altcp_mbedtls_malloc_stats.maxBytes = altcp_mbedtls_malloc_stats.allocedBytes;
+  }
+  altcp_mbedtls_malloc_stats.totalBytes += c * len;
+#endif
+  hlpr->c = c;
+  hlpr->len = len;
+  ret = hlpr + 1;
+  /* zeroing the allocated chunk is required by mbedTLS! */
+  memset(ret, 0, c * len);
+  return ret;
+}
+
+static void
+tls_free(void *ptr)
+{
+  altcp_mbedtls_malloc_helper_t *hlpr;
+  if (ptr == NULL) {
+    /* this obviously happened in mbedtls... */
+    return;
+  }
+  hlpr = ((altcp_mbedtls_malloc_helper_t *)ptr) - 1;
+#if ALTCP_MBEDTLS_PLATFORM_ALLOC_STATS
+  if (!altcp_mbedtls_malloc_clear_stats) {
+    altcp_mbedtls_malloc_stats.allocedBytes -= hlpr->c * hlpr->len;
+  }
+#endif
+  mem_free(hlpr);
+}
+#endif /* ALTCP_MBEDTLS_PLATFORM_ALLOC*/
+
+void
+altcp_mbedtls_mem_init(void)
+{
+  /* not much to do here when using the heap */
+
+#if ALTCP_MBEDTLS_PLATFORM_ALLOC
+  /* set mbedtls allocation methods */
+  mbedtls_platform_set_calloc_free(&tls_malloc, &tls_free);
+#endif
+}
+
+altcp_mbedtls_state_t *
+altcp_mbedtls_alloc(void *conf)
+{
+  altcp_mbedtls_state_t *ret = (altcp_mbedtls_state_t *)mem_calloc(1, sizeof(altcp_mbedtls_state_t));
+  if (ret != NULL) {
+    ret->conf = conf;
+  }
+  return ret;
+}
+
+void
+altcp_mbedtls_free(void *conf, altcp_mbedtls_state_t *state)
+{
+  LWIP_UNUSED_ARG(conf);
+  LWIP_ASSERT("state != NULL", state != NULL);
+  mem_free(state);
+}
+
+void *
+altcp_mbedtls_alloc_config(size_t size)
+{
+  void *ret;
+  size_t checked_size = (mem_size_t)size;
+  if (size != checked_size) {
+    /* allocation too big (mem_size_t overflow) */
+    return NULL;
+  }
+  ret = (altcp_mbedtls_state_t *)mem_calloc(1, (mem_size_t)size);
+  return ret;
+}
+
+void
+altcp_mbedtls_free_config(void *item)
+{
+  LWIP_ASSERT("item != NULL", item != NULL);
+  mem_free(item);
+}
+
+#endif /* LWIP_ALTCP_TLS && LWIP_ALTCP_TLS_MBEDTLS */
+#endif /* LWIP_ALTCP */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/apps/altcp_tls/altcp_tls_mbedtls_mem.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/apps/altcp_tls/altcp_tls_mbedtls_mem.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/apps/altcp_tls/altcp_tls_mbedtls_mem.h	(revision 457)
@@ -0,0 +1,72 @@
+/**
+ * @file
+ * Application layered TCP/TLS connection API (to be used from TCPIP thread)
+ *
+ * This file contains memory management function prototypes for a TLS layer using mbedTLS.
+ *
+ * Memory management contains:
+ * - allocating/freeing altcp_mbedtls_state_t
+ * - allocating/freeing memory used in the mbedTLS library
+ */
+
+/*
+ * Copyright (c) 2017 Simon Goldschmidt
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Simon Goldschmidt <goldsimon@gmx.de>
+ *
+ */
+#ifndef LWIP_HDR_ALTCP_MBEDTLS_MEM_H
+#define LWIP_HDR_ALTCP_MBEDTLS_MEM_H
+
+#include "lwip/opt.h"
+
+#if LWIP_ALTCP /* don't build if not configured for use in lwipopts.h */
+
+#include "lwip/apps/altcp_tls_mbedtls_opts.h"
+
+#if LWIP_ALTCP_TLS && LWIP_ALTCP_TLS_MBEDTLS
+
+#include "altcp_tls_mbedtls_structs.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void altcp_mbedtls_mem_init(void);
+altcp_mbedtls_state_t *altcp_mbedtls_alloc(void *conf);
+void altcp_mbedtls_free(void *conf, altcp_mbedtls_state_t *state);
+void *altcp_mbedtls_alloc_config(size_t size);
+void altcp_mbedtls_free_config(void *item);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LWIP_ALTCP_TLS && LWIP_ALTCP_TLS_MBEDTLS */
+#endif /* LWIP_ALTCP */
+#endif /* LWIP_HDR_ALTCP_MBEDTLS_MEM_H */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/apps/altcp_tls/altcp_tls_mbedtls_structs.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/apps/altcp_tls/altcp_tls_mbedtls_structs.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/apps/altcp_tls/altcp_tls_mbedtls_structs.h	(revision 457)
@@ -0,0 +1,83 @@
+/**
+ * @file
+ * Application layered TCP/TLS connection API (to be used from TCPIP thread)
+ *
+ * This file contains structure definitions for a TLS layer using mbedTLS.
+ */
+
+/*
+ * Copyright (c) 2017 Simon Goldschmidt
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Simon Goldschmidt <goldsimon@gmx.de>
+ *
+ */
+#ifndef LWIP_HDR_ALTCP_MBEDTLS_STRUCTS_H
+#define LWIP_HDR_ALTCP_MBEDTLS_STRUCTS_H
+
+#include "lwip/opt.h"
+
+#if LWIP_ALTCP /* don't build if not configured for use in lwipopts.h */
+
+#include "lwip/apps/altcp_tls_mbedtls_opts.h"
+
+#if LWIP_ALTCP_TLS && LWIP_ALTCP_TLS_MBEDTLS
+
+#include "lwip/altcp.h"
+#include "lwip/pbuf.h"
+
+#include "mbedtls/ssl.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define ALTCP_MBEDTLS_FLAGS_HANDSHAKE_DONE    0x01
+#define ALTCP_MBEDTLS_FLAGS_UPPER_CALLED      0x02
+#define ALTCP_MBEDTLS_FLAGS_RX_CLOSE_QUEUED   0x04
+#define ALTCP_MBEDTLS_FLAGS_RX_CLOSED         0x08
+#define ALTCP_MBEDTLS_FLAGS_APPLDATA_SENT     0x10
+
+typedef struct altcp_mbedtls_state_s {
+  void *conf;
+  mbedtls_ssl_context ssl_context;
+  /* chain of rx pbufs (before decryption) */
+  struct pbuf *rx;
+  struct pbuf *rx_app;
+  u8_t flags;
+  int rx_passed_unrecved;
+  int bio_bytes_read;
+  int bio_bytes_appl;
+} altcp_mbedtls_state_t;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LWIP_ALTCP_TLS && LWIP_ALTCP_TLS_MBEDTLS */
+#endif /* LWIP_ALTCP */
+#endif /* LWIP_HDR_ALTCP_MBEDTLS_STRUCTS_H */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/apps/http/altcp_proxyconnect.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/apps/http/altcp_proxyconnect.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/apps/http/altcp_proxyconnect.c	(revision 457)
@@ -0,0 +1,584 @@
+/**
+ * @file
+ * Application layered TCP connection API that executes a proxy-connect.
+ *
+ * This file provides a starting layer that executes a proxy-connect e.g. to
+ * set up TLS connections through a http proxy.
+ */
+
+/*
+ * Copyright (c) 2018 Simon Goldschmidt
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Simon Goldschmidt <goldsimon@gmx.de>
+ *
+ */
+
+#include "lwip/apps/altcp_proxyconnect.h"
+
+#if LWIP_ALTCP /* don't build if not configured for use in lwipopts.h */
+
+#include "lwip/altcp.h"
+#include "lwip/priv/altcp_priv.h"
+
+#include "lwip/altcp_tcp.h"
+#include "lwip/altcp_tls.h"
+
+#include "lwip/mem.h"
+#include "lwip/init.h"
+
+#include <stdio.h>
+
+/** This string is passed in the HTTP header as "User-Agent: " */
+#ifndef ALTCP_PROXYCONNECT_CLIENT_AGENT
+#define ALTCP_PROXYCONNECT_CLIENT_AGENT "lwIP/" LWIP_VERSION_STRING " (http://savannah.nongnu.org/projects/lwip)"
+#endif
+
+#define ALTCP_PROXYCONNECT_FLAGS_CONNECT_STARTED  0x01
+#define ALTCP_PROXYCONNECT_FLAGS_HANDSHAKE_DONE   0x02
+
+typedef struct altcp_proxyconnect_state_s
+{
+  ip_addr_t outer_addr;
+  u16_t outer_port;
+  struct altcp_proxyconnect_config *conf;
+  u8_t flags;
+} altcp_proxyconnect_state_t;
+
+/* Variable prototype, the actual declaration is at the end of this file
+   since it contains pointers to static functions declared here */
+extern const struct altcp_functions altcp_proxyconnect_functions;
+
+/* memory management functions: */
+
+static altcp_proxyconnect_state_t *
+altcp_proxyconnect_state_alloc(void)
+{
+  altcp_proxyconnect_state_t *ret = (altcp_proxyconnect_state_t *)mem_calloc(1, sizeof(altcp_proxyconnect_state_t));
+  return ret;
+}
+
+static void
+altcp_proxyconnect_state_free(altcp_proxyconnect_state_t *state)
+{
+  LWIP_ASSERT("state != NULL", state != NULL);
+  mem_free(state);
+}
+
+/* helper functions */
+
+#define PROXY_CONNECT "CONNECT %s:%d HTTP/1.1\r\n" /* HOST, PORT */ \
+  "User-Agent: %s\r\n" /* User-Agent */\
+  "Proxy-Connection: keep-alive\r\n" \
+  "Connection: keep-alive\r\n" \
+  "\r\n"
+#define PROXY_CONNECT_FORMAT(host, port) PROXY_CONNECT, host, port, ALTCP_PROXYCONNECT_CLIENT_AGENT
+
+/* Format the http proxy connect request via snprintf */
+static int
+altcp_proxyconnect_format_request(char *buffer, size_t bufsize, const char *host, int port)
+{
+  return snprintf(buffer, bufsize, PROXY_CONNECT_FORMAT(host, port));
+}
+
+/* Create and send the http proxy connect request */
+static err_t
+altcp_proxyconnect_send_request(struct altcp_pcb *conn)
+{
+  int len, len2;
+  mem_size_t alloc_len;
+  char *buffer, *host;
+  altcp_proxyconnect_state_t *state = (altcp_proxyconnect_state_t *)conn->state;
+
+  if (!state) {
+    return ERR_VAL;
+  }
+  /* Use printf with zero length to get the required allocation size */
+  len = altcp_proxyconnect_format_request(NULL, 0, "", state->outer_port);
+  if (len < 0) {
+    return ERR_VAL;
+  }
+  /* add allocation size for IP address strings */
+#if LWIP_IPV6
+  len += 40; /* worst-case IPv6 address length */
+#else
+  len += 16; /* worst-case IPv4 address length */
+#endif
+  alloc_len = (mem_size_t)len;
+  if ((len < 0) || (int)alloc_len != len) {
+    /* overflow */
+    return ERR_MEM;
+  }
+  /* Allocate a bufer for the request string */
+  buffer = (char *)mem_malloc(alloc_len);
+  if (buffer == NULL) {
+    return ERR_MEM;
+  }
+  host = ipaddr_ntoa(&state->outer_addr);
+  len2 = altcp_proxyconnect_format_request(buffer, alloc_len, host, state->outer_port);
+  if ((len2 > 0) && (len2 <= len) && (len2 <= 0xFFFF)) {
+    err_t err = altcp_write(conn->inner_conn, buffer, (u16_t)len2, TCP_WRITE_FLAG_COPY);
+    if (err != ERR_OK) {
+      /* @todo: abort? */
+      mem_free(buffer);
+      return err;
+    }
+  }
+  mem_free(buffer);
+  return ERR_OK;
+}
+
+/* callback functions from inner/lower connection: */
+
+/** Connected callback from lower connection (i.e. TCP).
+ * Not really implemented/tested yet...
+ */
+static err_t
+altcp_proxyconnect_lower_connected(void *arg, struct altcp_pcb *inner_conn, err_t err)
+{
+  struct altcp_pcb *conn = (struct altcp_pcb *)arg;
+  if (conn && conn->state) {
+    LWIP_ASSERT("pcb mismatch", conn->inner_conn == inner_conn);
+    LWIP_UNUSED_ARG(inner_conn); /* for LWIP_NOASSERT */
+    /* upper connected is called when handshake is done */
+    if (err != ERR_OK) {
+      if (conn->connected) {
+        if (conn->connected(conn->arg, conn, err) == ERR_ABRT) {
+          return ERR_ABRT;
+        }
+        return ERR_OK;
+      }
+    }
+    /* send proxy connect request here */
+    return altcp_proxyconnect_send_request(conn);
+  }
+  return ERR_VAL;
+}
+
+/** Recv callback from lower connection (i.e. TCP)
+ * This one mainly differs between connection setup (wait for proxy OK string)
+ * and application phase (data is passed on to the application).
+ */
+static err_t
+altcp_proxyconnect_lower_recv(void *arg, struct altcp_pcb *inner_conn, struct pbuf *p, err_t err)
+{
+  altcp_proxyconnect_state_t *state;
+  struct altcp_pcb *conn = (struct altcp_pcb *)arg;
+
+  LWIP_ASSERT("no err expected", err == ERR_OK);
+  LWIP_UNUSED_ARG(err);
+
+  if (!conn) {
+    /* no connection given as arg? should not happen, but prevent pbuf/conn leaks */
+    if (p != NULL) {
+      pbuf_free(p);
+    }
+    altcp_close(inner_conn);
+    return ERR_CLSD;
+  }
+  state = (altcp_proxyconnect_state_t *)conn->state;
+  LWIP_ASSERT("pcb mismatch", conn->inner_conn == inner_conn);
+  if (!state) {
+    /* already closed */
+    if (p != NULL) {
+      pbuf_free(p);
+    }
+    altcp_close(inner_conn);
+    return ERR_CLSD;
+  }
+  if (state->flags & ALTCP_PROXYCONNECT_FLAGS_HANDSHAKE_DONE) {
+    /* application phase, just pass this through */
+    if (conn->recv) {
+      return conn->recv(conn->arg, conn, p, err);
+    }
+    pbuf_free(p);
+    return ERR_OK;
+  } else {
+    /* setup phase */
+    /* handle NULL pbuf (inner connection closed) */
+    if (p == NULL) {
+      if (altcp_close(conn) != ERR_OK) {
+        altcp_abort(conn);
+        return ERR_ABRT;
+      }
+      return ERR_OK;
+    } else {
+      /* @todo: parse setup phase rx data
+         for now, we just wait for the end of the header... */
+      u16_t idx = pbuf_memfind(p, "\r\n\r\n", 4, 0);
+      altcp_recved(inner_conn, p->tot_len);
+      pbuf_free(p);
+      if (idx != 0xFFFF) {
+        state->flags |= ALTCP_PROXYCONNECT_FLAGS_HANDSHAKE_DONE;
+        if (conn->connected) {
+          return conn->connected(conn->arg, conn, ERR_OK);
+        }
+      }
+      return ERR_OK;
+    }
+  }
+}
+
+/** Sent callback from lower connection (i.e. TCP)
+ * This only informs the upper layer to try to send more, not about
+ * the number of ACKed bytes.
+ */
+static err_t
+altcp_proxyconnect_lower_sent(void *arg, struct altcp_pcb *inner_conn, u16_t len)
+{
+  struct altcp_pcb *conn = (struct altcp_pcb *)arg;
+  LWIP_UNUSED_ARG(len);
+  if (conn) {
+    altcp_proxyconnect_state_t *state = (altcp_proxyconnect_state_t *)conn->state;
+    LWIP_ASSERT("pcb mismatch", conn->inner_conn == inner_conn);
+    LWIP_UNUSED_ARG(inner_conn); /* for LWIP_NOASSERT */
+    if (!state || !(state->flags & ALTCP_PROXYCONNECT_FLAGS_HANDSHAKE_DONE)) {
+      /* @todo: do something here? */
+      return ERR_OK;
+    }
+    /* pass this on to upper sent */
+    if (conn->sent) {
+      return conn->sent(conn->arg, conn, len);
+    }
+  }
+  return ERR_OK;
+}
+
+/** Poll callback from lower connection (i.e. TCP)
+ * Just pass this on to the application.
+ * @todo: retry sending?
+ */
+static err_t
+altcp_proxyconnect_lower_poll(void *arg, struct altcp_pcb *inner_conn)
+{
+  struct altcp_pcb *conn = (struct altcp_pcb *)arg;
+  if (conn) {
+    LWIP_ASSERT("pcb mismatch", conn->inner_conn == inner_conn);
+    LWIP_UNUSED_ARG(inner_conn); /* for LWIP_NOASSERT */
+    if (conn->poll) {
+      return conn->poll(conn->arg, conn);
+    }
+  }
+  return ERR_OK;
+}
+
+static void
+altcp_proxyconnect_lower_err(void *arg, err_t err)
+{
+  struct altcp_pcb *conn = (struct altcp_pcb *)arg;
+  if (conn) {
+    conn->inner_conn = NULL; /* already freed */
+    if (conn->err) {
+      conn->err(conn->arg, err);
+    }
+    altcp_free(conn);
+  }
+}
+
+
+/* setup functions */
+
+static void
+altcp_proxyconnect_setup_callbacks(struct altcp_pcb *conn, struct altcp_pcb *inner_conn)
+{
+  altcp_arg(inner_conn, conn);
+  altcp_recv(inner_conn, altcp_proxyconnect_lower_recv);
+  altcp_sent(inner_conn, altcp_proxyconnect_lower_sent);
+  altcp_err(inner_conn, altcp_proxyconnect_lower_err);
+  /* tcp_poll is set when interval is set by application */
+  /* listen is set totally different :-) */
+}
+
+static err_t
+altcp_proxyconnect_setup(struct altcp_proxyconnect_config *config, struct altcp_pcb *conn, struct altcp_pcb *inner_conn)
+{
+  altcp_proxyconnect_state_t *state;
+  if (!config) {
+    return ERR_ARG;
+  }
+  LWIP_ASSERT("invalid inner_conn", conn != inner_conn);
+
+  /* allocate proxyconnect context */
+  state = altcp_proxyconnect_state_alloc();
+  if (state == NULL) {
+    return ERR_MEM;
+  }
+  state->flags = 0;
+  state->conf = config;
+  altcp_proxyconnect_setup_callbacks(conn, inner_conn);
+  conn->inner_conn = inner_conn;
+  conn->fns = &altcp_proxyconnect_functions;
+  conn->state = state;
+  return ERR_OK;
+}
+
+/** Allocate a new altcp layer connecting through a proxy.
+ * This function gets the inner pcb passed.
+ *
+ * @param config struct altcp_proxyconnect_config that contains the proxy settings
+ * @param inner_pcb pcb that makes the connection to the proxy (i.e. tcp pcb)
+ */
+struct altcp_pcb *
+altcp_proxyconnect_new(struct altcp_proxyconnect_config *config, struct altcp_pcb *inner_pcb)
+{
+  struct altcp_pcb *ret;
+  if (inner_pcb == NULL) {
+    return NULL;
+  }
+  ret = altcp_alloc();
+  if (ret != NULL) {
+    if (altcp_proxyconnect_setup(config, ret, inner_pcb) != ERR_OK) {
+      altcp_free(ret);
+      return NULL;
+    }
+  }
+  return ret;
+}
+
+/** Allocate a new altcp layer connecting through a proxy.
+ * This function allocates the inner pcb as tcp pcb, resulting in a direct tcp
+ * connection to the proxy.
+ *
+ * @param config struct altcp_proxyconnect_config that contains the proxy settings
+ * @param ip_type IP type of the connection (@ref lwip_ip_addr_type)
+ */
+struct altcp_pcb *
+altcp_proxyconnect_new_tcp(struct altcp_proxyconnect_config *config, u8_t ip_type)
+{
+  struct altcp_pcb *inner_pcb, *ret;
+
+  /* inner pcb is tcp */
+  inner_pcb = altcp_tcp_new_ip_type(ip_type);
+  if (inner_pcb == NULL) {
+    return NULL;
+  }
+  ret = altcp_proxyconnect_new(config, inner_pcb);
+  if (ret == NULL) {
+    altcp_close(inner_pcb);
+  }
+  return ret;
+}
+
+/** Allocator function to allocate a proxy connect altcp pcb connecting directly
+ * via tcp to the proxy.
+ *
+ * The returned pcb is a chain: altcp_proxyconnect - altcp_tcp - tcp pcb
+ *
+ * This function is meant for use with @ref altcp_new.
+ *
+ * @param arg struct altcp_proxyconnect_config that contains the proxy settings
+ * @param ip_type IP type of the connection (@ref lwip_ip_addr_type)
+ */
+struct altcp_pcb *
+altcp_proxyconnect_alloc(void *arg, u8_t ip_type)
+{
+  return altcp_proxyconnect_new_tcp((struct altcp_proxyconnect_config *)arg, ip_type);
+}
+
+
+#if LWIP_ALTCP_TLS
+
+/** Allocator function to allocate a TLS connection through a proxy.
+ *
+ * The returned pcb is a chain: altcp_tls - altcp_proxyconnect - altcp_tcp - tcp pcb
+ *
+ * This function is meant for use with @ref altcp_new.
+ *
+ * @param arg struct altcp_proxyconnect_tls_config that contains the proxy settings
+ *        and tls settings
+ * @param ip_type IP type of the connection (@ref lwip_ip_addr_type)
+ */
+struct altcp_pcb *
+altcp_proxyconnect_tls_alloc(void *arg, u8_t ip_type)
+{
+  struct altcp_proxyconnect_tls_config *cfg = (struct altcp_proxyconnect_tls_config *)arg;
+  struct altcp_pcb *proxy_pcb;
+  struct altcp_pcb *tls_pcb;
+
+  proxy_pcb = altcp_proxyconnect_new_tcp(&cfg->proxy, ip_type);
+  tls_pcb = altcp_tls_wrap(cfg->tls_config, proxy_pcb);
+
+  if (tls_pcb == NULL) {
+    altcp_close(proxy_pcb);
+  }
+  return tls_pcb;
+}
+#endif /* LWIP_ALTCP_TLS */
+
+/* "virtual" functions */
+static void
+altcp_proxyconnect_set_poll(struct altcp_pcb *conn, u8_t interval)
+{
+  if (conn != NULL) {
+    altcp_poll(conn->inner_conn, altcp_proxyconnect_lower_poll, interval);
+  }
+}
+
+static void
+altcp_proxyconnect_recved(struct altcp_pcb *conn, u16_t len)
+{
+  altcp_proxyconnect_state_t *state;
+  if (conn == NULL) {
+    return;
+  }
+  state = (altcp_proxyconnect_state_t *)conn->state;
+  if (state == NULL) {
+    return;
+  }
+  if (!(state->flags & ALTCP_PROXYCONNECT_FLAGS_HANDSHAKE_DONE)) {
+    return;
+  }
+  altcp_recved(conn->inner_conn, len);
+}
+
+static err_t
+altcp_proxyconnect_connect(struct altcp_pcb *conn, const ip_addr_t *ipaddr, u16_t port, altcp_connected_fn connected)
+{
+  altcp_proxyconnect_state_t *state;
+
+  if ((conn == NULL) || (ipaddr == NULL)) {
+    return ERR_VAL;
+  }
+  state = (altcp_proxyconnect_state_t *)conn->state;
+  if (state == NULL) {
+    return ERR_VAL;
+  }
+  if (state->flags & ALTCP_PROXYCONNECT_FLAGS_CONNECT_STARTED) {
+    return ERR_VAL;
+  }
+  state->flags |= ALTCP_PROXYCONNECT_FLAGS_CONNECT_STARTED;
+
+  conn->connected = connected;
+  /* connect to our proxy instead, but store the requested address and port */
+  ip_addr_copy(state->outer_addr, *ipaddr);
+  state->outer_port = port;
+
+  return altcp_connect(conn->inner_conn, &state->conf->proxy_addr, state->conf->proxy_port, altcp_proxyconnect_lower_connected);
+}
+
+static struct altcp_pcb *
+altcp_proxyconnect_listen(struct altcp_pcb *conn, u8_t backlog, err_t *err)
+{
+  LWIP_UNUSED_ARG(conn);
+  LWIP_UNUSED_ARG(backlog);
+  LWIP_UNUSED_ARG(err);
+  /* listen not supported! */
+  return NULL;
+}
+
+static void
+altcp_proxyconnect_abort(struct altcp_pcb *conn)
+{
+  if (conn != NULL) {
+    if (conn->inner_conn != NULL) {
+      altcp_abort(conn->inner_conn);
+    }
+    altcp_free(conn);
+  }
+}
+
+static err_t
+altcp_proxyconnect_close(struct altcp_pcb *conn)
+{
+  if (conn == NULL) {
+    return ERR_VAL;
+  }
+  if (conn->inner_conn != NULL) {
+    err_t err = altcp_close(conn->inner_conn);
+    if (err != ERR_OK) {
+      /* closing inner conn failed, return the error */
+      return err;
+    }
+  }
+  /* no inner conn or closing it succeeded, deallocate myself */
+  altcp_free(conn);
+  return ERR_OK;
+}
+
+static err_t
+altcp_proxyconnect_write(struct altcp_pcb *conn, const void *dataptr, u16_t len, u8_t apiflags)
+{
+  altcp_proxyconnect_state_t *state;
+
+  LWIP_UNUSED_ARG(apiflags);
+
+  if (conn == NULL) {
+    return ERR_VAL;
+  }
+
+  state = (altcp_proxyconnect_state_t *)conn->state;
+  if (state == NULL) {
+    /* @todo: which error? */
+    return ERR_CLSD;
+  }
+  if (!(state->flags & ALTCP_PROXYCONNECT_FLAGS_HANDSHAKE_DONE)) {
+    /* @todo: which error? */
+    return ERR_VAL;
+  }
+  return altcp_write(conn->inner_conn, dataptr, len, apiflags);
+}
+
+static void
+altcp_proxyconnect_dealloc(struct altcp_pcb *conn)
+{
+  /* clean up and free tls state */
+  if (conn) {
+    altcp_proxyconnect_state_t *state = (altcp_proxyconnect_state_t *)conn->state;
+    if (state) {
+      altcp_proxyconnect_state_free(state);
+      conn->state = NULL;
+    }
+  }
+}
+const struct altcp_functions altcp_proxyconnect_functions = {
+  altcp_proxyconnect_set_poll,
+  altcp_proxyconnect_recved,
+  altcp_default_bind,
+  altcp_proxyconnect_connect,
+  altcp_proxyconnect_listen,
+  altcp_proxyconnect_abort,
+  altcp_proxyconnect_close,
+  altcp_default_shutdown,
+  altcp_proxyconnect_write,
+  altcp_default_output,
+  altcp_default_mss,
+  altcp_default_sndbuf,
+  altcp_default_sndqueuelen,
+  altcp_default_nagle_disable,
+  altcp_default_nagle_enable,
+  altcp_default_nagle_disabled,
+  altcp_default_setprio,
+  altcp_proxyconnect_dealloc,
+  altcp_default_get_tcp_addrinfo,
+  altcp_default_get_ip,
+  altcp_default_get_port
+#ifdef LWIP_DEBUG
+  , altcp_default_dbg_get_tcp_state
+#endif
+};
+
+#endif /* LWIP_ALTCP */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/apps/http/fs.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/apps/http/fs.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/apps/http/fs.c	(revision 457)
@@ -0,0 +1,174 @@
+/*
+ * Copyright (c) 2001-2003 Swedish Institute of Computer Science.
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Adam Dunkels <adam@sics.se>
+ *
+ */
+
+#include "lwip/apps/httpd_opts.h"
+#include "lwip/def.h"
+#include "lwip/apps/fs.h"
+#include <string.h>
+
+
+#include HTTPD_FSDATA_FILE
+
+/*-----------------------------------------------------------------------------------*/
+
+#if LWIP_HTTPD_CUSTOM_FILES
+int fs_open_custom(struct fs_file *file, const char *name);
+void fs_close_custom(struct fs_file *file);
+#if LWIP_HTTPD_FS_ASYNC_READ
+u8_t fs_canread_custom(struct fs_file *file);
+u8_t fs_wait_read_custom(struct fs_file *file, fs_wait_cb callback_fn, void *callback_arg);
+int fs_read_async_custom(struct fs_file *file, char *buffer, int count, fs_wait_cb callback_fn, void *callback_arg);
+#else /* LWIP_HTTPD_FS_ASYNC_READ */
+int fs_read_custom(struct fs_file *file, char *buffer, int count);
+#endif /* LWIP_HTTPD_FS_ASYNC_READ */
+#endif /* LWIP_HTTPD_CUSTOM_FILES */
+
+/*-----------------------------------------------------------------------------------*/
+err_t
+fs_open(struct fs_file *file, const char *name)
+{
+  const struct fsdata_file *f;
+
+  if ((file == NULL) || (name == NULL)) {
+    return ERR_ARG;
+  }
+
+#if LWIP_HTTPD_CUSTOM_FILES
+  if (fs_open_custom(file, name)) {
+    file->is_custom_file = 1;
+    return ERR_OK;
+  }
+  file->is_custom_file = 0;
+#endif /* LWIP_HTTPD_CUSTOM_FILES */
+
+  for (f = FS_ROOT; f != NULL; f = f->next) {
+    if (!strcmp(name, (const char *)f->name)) {
+      file->data = (const char *)f->data;
+      file->len = f->len;
+      file->index = f->len;
+      file->pextension = NULL;
+      file->flags = f->flags;
+#if HTTPD_PRECALCULATED_CHECKSUM
+      file->chksum_count = f->chksum_count;
+      file->chksum = f->chksum;
+#endif /* HTTPD_PRECALCULATED_CHECKSUM */
+#if LWIP_HTTPD_FILE_STATE
+      file->state = fs_state_init(file, name);
+#endif /* #if LWIP_HTTPD_FILE_STATE */
+      return ERR_OK;
+    }
+  }
+  /* file not found */
+  return ERR_VAL;
+}
+
+/*-----------------------------------------------------------------------------------*/
+void
+fs_close(struct fs_file *file)
+{
+#if LWIP_HTTPD_CUSTOM_FILES
+  if (file->is_custom_file) {
+    fs_close_custom(file);
+  }
+#endif /* LWIP_HTTPD_CUSTOM_FILES */
+#if LWIP_HTTPD_FILE_STATE
+  fs_state_free(file, file->state);
+#endif /* #if LWIP_HTTPD_FILE_STATE */
+  LWIP_UNUSED_ARG(file);
+}
+/*-----------------------------------------------------------------------------------*/
+#if LWIP_HTTPD_DYNAMIC_FILE_READ
+#if LWIP_HTTPD_FS_ASYNC_READ
+int
+fs_read_async(struct fs_file *file, char *buffer, int count, fs_wait_cb callback_fn, void *callback_arg)
+#else /* LWIP_HTTPD_FS_ASYNC_READ */
+int
+fs_read(struct fs_file *file, char *buffer, int count)
+#endif /* LWIP_HTTPD_FS_ASYNC_READ */
+{
+  int read;
+  if (file->index == file->len) {
+    return FS_READ_EOF;
+  }
+#if LWIP_HTTPD_FS_ASYNC_READ
+  LWIP_UNUSED_ARG(callback_fn);
+  LWIP_UNUSED_ARG(callback_arg);
+#endif /* LWIP_HTTPD_FS_ASYNC_READ */
+#if LWIP_HTTPD_CUSTOM_FILES
+  if (file->is_custom_file) {
+#if LWIP_HTTPD_FS_ASYNC_READ
+    return fs_read_async_custom(file, buffer, count, callback_fn, callback_arg);
+#else /* LWIP_HTTPD_FS_ASYNC_READ */
+    return fs_read_custom(file, buffer, count);
+#endif /* LWIP_HTTPD_FS_ASYNC_READ */
+  }
+#endif /* LWIP_HTTPD_CUSTOM_FILES */
+
+  read = file->len - file->index;
+  if (read > count) {
+    read = count;
+  }
+
+  MEMCPY(buffer, (file->data + file->index), read);
+  file->index += read;
+
+  return (read);
+}
+#endif /* LWIP_HTTPD_DYNAMIC_FILE_READ */
+/*-----------------------------------------------------------------------------------*/
+#if LWIP_HTTPD_FS_ASYNC_READ
+int
+fs_is_file_ready(struct fs_file *file, fs_wait_cb callback_fn, void *callback_arg)
+{
+  if (file != NULL) {
+#if LWIP_HTTPD_FS_ASYNC_READ
+#if LWIP_HTTPD_CUSTOM_FILES
+    if (!fs_canread_custom(file)) {
+      if (fs_wait_read_custom(file, callback_fn, callback_arg)) {
+        return 0;
+      }
+    }
+#else /* LWIP_HTTPD_CUSTOM_FILES */
+    LWIP_UNUSED_ARG(callback_fn);
+    LWIP_UNUSED_ARG(callback_arg);
+#endif /* LWIP_HTTPD_CUSTOM_FILES */
+#endif /* LWIP_HTTPD_FS_ASYNC_READ */
+  }
+  return 1;
+}
+#endif /* LWIP_HTTPD_FS_ASYNC_READ */
+/*-----------------------------------------------------------------------------------*/
+int
+fs_bytes_left(struct fs_file *file)
+{
+  return file->len - file->index;
+}
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/apps/http/fs/404.html
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/apps/http/fs/404.html	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/apps/http/fs/404.html	(revision 457)
@@ -0,0 +1,21 @@
+<html>
+<head><title>lwIP - A Lightweight TCP/IP Stack</title></head>
+<body bgcolor="white" text="black">
+
+    <table width="100%">
+      <tr valign="top"><td width="80">	  
+	  <a href="http://www.sics.se/"><img src="/img/sics.gif"
+	  border="0" alt="SICS logo" title="SICS logo"></a>
+	</td><td width="500">	  
+	  <h1>lwIP - A Lightweight TCP/IP Stack</h1>
+	  <h2>404 - Page not found</h2>
+	  <p>
+	    Sorry, the page you are requesting was not found on this
+	    server. 
+	  </p>
+	</td><td>
+	  &nbsp;
+	</td></tr>
+      </table>
+</body>
+</html>
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/apps/http/fs/index.html
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/apps/http/fs/index.html	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/apps/http/fs/index.html	(revision 457)
@@ -0,0 +1,47 @@
+<html>
+<head><title>lwIP - A Lightweight TCP/IP Stack</title></head>
+<body bgcolor="white" text="black">
+
+    <table width="100%">
+      <tr valign="top"><td width="80">	  
+	  <a href="http://www.sics.se/"><img src="/img/sics.gif"
+	  border="0" alt="SICS logo" title="SICS logo"></a>
+	</td><td width="500">	  
+	  <h1>lwIP - A Lightweight TCP/IP Stack</h1>
+	  <p>
+	    The web page you are watching was served by a simple web
+	    server running on top of the lightweight TCP/IP stack <a
+	    href="http://www.sics.se/~adam/lwip/">lwIP</a>.
+	  </p>
+	  <p>
+	    lwIP is an open source implementation of the TCP/IP
+	    protocol suite that was originally written by <a
+	    href="http://www.sics.se/~adam/lwip/">Adam Dunkels
+	    of the Swedish Institute of Computer Science</a> but now is
+	    being actively developed by a team of developers
+	    distributed world-wide. Since it's release, lwIP has
+	    spurred a lot of interest and has been ported to several
+	    platforms and operating systems. lwIP can be used either
+	    with or without an underlying OS.
+	  </p>
+	  <p>
+	    The focus of the lwIP TCP/IP implementation is to reduce
+	    the RAM usage while still having a full scale TCP. This
+	    makes lwIP suitable for use in embedded systems with tens
+	    of kilobytes of free RAM and room for around 40 kilobytes
+	    of code ROM.
+	  </p>
+	  <p>
+	    More information about lwIP can be found at the lwIP
+	    homepage at <a
+	    href="http://savannah.nongnu.org/projects/lwip/">http://savannah.nongnu.org/projects/lwip/</a>
+	    or at the lwIP wiki at <a
+	    href="http://lwip.wikia.com/">http://lwip.wikia.com/</a>.
+	  </p>
+	</td><td>
+	  &nbsp;
+	</td></tr>
+      </table>
+</body>
+</html>
+
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/apps/http/fsdata.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/apps/http/fsdata.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/apps/http/fsdata.c	(revision 457)
@@ -0,0 +1,337 @@
+#include "lwip/apps/fs.h"
+#include "lwip/def.h"
+
+
+#define file_NULL (struct fsdata_file *) NULL
+
+
+#ifndef FS_FILE_FLAGS_HEADER_INCLUDED
+#define FS_FILE_FLAGS_HEADER_INCLUDED 1
+#endif
+#ifndef FS_FILE_FLAGS_HEADER_PERSISTENT
+#define FS_FILE_FLAGS_HEADER_PERSISTENT 0
+#endif
+/* FSDATA_FILE_ALIGNMENT: 0=off, 1=by variable, 2=by include */
+#ifndef FSDATA_FILE_ALIGNMENT
+#define FSDATA_FILE_ALIGNMENT 0
+#endif
+#ifndef FSDATA_ALIGN_PRE
+#define FSDATA_ALIGN_PRE
+#endif
+#ifndef FSDATA_ALIGN_POST
+#define FSDATA_ALIGN_POST
+#endif
+#if FSDATA_FILE_ALIGNMENT==2
+#include "fsdata_alignment.h"
+#endif
+#if FSDATA_FILE_ALIGNMENT==1
+static const unsigned int dummy_align__img_sics_gif = 0;
+#endif
+static const unsigned char FSDATA_ALIGN_PRE data__img_sics_gif[] FSDATA_ALIGN_POST = {
+/* /img/sics.gif (14 chars) */
+0x2f,0x69,0x6d,0x67,0x2f,0x73,0x69,0x63,0x73,0x2e,0x67,0x69,0x66,0x00,0x00,0x00,
+
+/* HTTP header */
+/* "HTTP/1.0 200 OK
+" (17 bytes) */
+0x48,0x54,0x54,0x50,0x2f,0x31,0x2e,0x30,0x20,0x32,0x30,0x30,0x20,0x4f,0x4b,0x0d,
+0x0a,
+/* "Server: lwIP/2.0.3d (http://savannah.nongnu.org/projects/lwip)
+" (64 bytes) */
+0x53,0x65,0x72,0x76,0x65,0x72,0x3a,0x20,0x6c,0x77,0x49,0x50,0x2f,0x32,0x2e,0x30,
+0x2e,0x33,0x64,0x20,0x28,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x73,0x61,0x76,0x61,
+0x6e,0x6e,0x61,0x68,0x2e,0x6e,0x6f,0x6e,0x67,0x6e,0x75,0x2e,0x6f,0x72,0x67,0x2f,
+0x70,0x72,0x6f,0x6a,0x65,0x63,0x74,0x73,0x2f,0x6c,0x77,0x69,0x70,0x29,0x0d,0x0a,
+
+/* "Content-Length: 724
+" (18+ bytes) */
+0x43,0x6f,0x6e,0x74,0x65,0x6e,0x74,0x2d,0x4c,0x65,0x6e,0x67,0x74,0x68,0x3a,0x20,
+0x37,0x32,0x34,0x0d,0x0a,
+/* "Content-Type: image/gif
+
+" (27 bytes) */
+0x43,0x6f,0x6e,0x74,0x65,0x6e,0x74,0x2d,0x54,0x79,0x70,0x65,0x3a,0x20,0x69,0x6d,
+0x61,0x67,0x65,0x2f,0x67,0x69,0x66,0x0d,0x0a,0x0d,0x0a,
+/* raw file data (724 bytes) */
+0x47,0x49,0x46,0x38,0x39,0x61,0x46,0x00,0x22,0x00,0xa5,0x00,0x00,0xd9,0x2b,0x39,
+0x6a,0x6a,0x6a,0xbf,0xbf,0xbf,0x93,0x93,0x93,0x0f,0x0f,0x0f,0xb0,0xb0,0xb0,0xa6,
+0xa6,0xa6,0x80,0x80,0x80,0x76,0x76,0x76,0x1e,0x1e,0x1e,0x9d,0x9d,0x9d,0x2e,0x2e,
+0x2e,0x49,0x49,0x49,0x54,0x54,0x54,0x8a,0x8a,0x8a,0x60,0x60,0x60,0xc6,0xa6,0x99,
+0xbd,0xb5,0xb2,0xc2,0xab,0xa1,0xd9,0x41,0x40,0xd5,0x67,0x55,0xc0,0xb0,0xaa,0xd5,
+0x5e,0x4e,0xd6,0x50,0x45,0xcc,0x93,0x7d,0xc8,0xa1,0x90,0xce,0x8b,0x76,0xd2,0x7b,
+0x65,0xd1,0x84,0x6d,0xc9,0x99,0x86,0x3a,0x3a,0x3a,0x00,0x00,0x00,0xb8,0xb8,0xb8,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x2c,0x00,0x00,
+0x00,0x00,0x46,0x00,0x22,0x00,0x00,0x06,0xfe,0x40,0x90,0x70,0x48,0x2c,0x1a,0x8f,
+0xc8,0xa4,0x72,0xc9,0x6c,0x3a,0x9f,0xd0,0xa8,0x74,0x4a,0xad,0x5a,0xaf,0xd8,0xac,
+0x76,0xa9,0x40,0x04,0xbe,0x83,0xe2,0x60,0x3c,0x50,0x20,0x0d,0x8e,0x6f,0x00,0x31,
+0x28,0x1c,0x0d,0x07,0xb5,0xc3,0x60,0x75,0x24,0x3e,0xf8,0xfc,0x87,0x11,0x06,0xe9,
+0x3d,0x46,0x07,0x0b,0x7a,0x7a,0x7c,0x43,0x06,0x1e,0x84,0x78,0x0b,0x07,0x6e,0x51,
+0x01,0x8a,0x84,0x08,0x7e,0x79,0x80,0x87,0x89,0x91,0x7a,0x93,0x0a,0x04,0x99,0x78,
+0x96,0x4f,0x03,0x9e,0x79,0x01,0x94,0x9f,0x43,0x9c,0xa3,0xa4,0x05,0x77,0xa3,0xa0,
+0x4e,0x98,0x79,0x0b,0x1e,0x83,0xa4,0xa6,0x1f,0x96,0x05,0x9d,0xaa,0x78,0x01,0x07,
+0x84,0x04,0x1e,0x1e,0xbb,0xb8,0x51,0x84,0x0e,0x43,0x05,0x07,0x77,0xa5,0x7f,0x42,
+0xb1,0xb2,0x01,0x63,0x08,0x0d,0xbb,0x01,0x0c,0x7a,0x0d,0x44,0x0e,0xd8,0xaf,0x4c,
+0x05,0x7a,0x04,0x47,0x07,0x07,0xb7,0x80,0xa2,0xe1,0x7d,0x44,0x05,0x01,0x04,0x01,
+0xd0,0xea,0x87,0x93,0x4f,0xe0,0x9a,0x49,0xce,0xd8,0x79,0x04,0x66,0x20,0x15,0x10,
+0x10,0x11,0x92,0x29,0x80,0xb6,0xc0,0x91,0x15,0x45,0x1e,0x90,0x19,0x71,0x46,0xa8,
+0x5c,0x04,0x0e,0x00,0x22,0x4e,0xe8,0x40,0x24,0x9f,0x3e,0x04,0x06,0xa7,0x58,0xd4,
+0x93,0xa0,0x1c,0x91,0x3f,0xe8,0xf0,0x88,0x03,0xb1,0x21,0xa2,0x49,0x00,0x19,0x86,
+0xfc,0x52,0x44,0xe0,0x01,0x9d,0x29,0x21,0x15,0x25,0x50,0xf7,0x67,0x25,0x1e,0x06,
+0xfd,0x4e,0x9a,0xb4,0x90,0xac,0x15,0xfa,0xcb,0x52,0x53,0x1e,0x8c,0xf2,0xf8,0x07,
+0x92,0x2d,0x08,0x3a,0x4d,0x12,0x49,0x95,0x49,0xdb,0x14,0x04,0xc4,0x14,0x85,0x29,
+0xaa,0xe7,0x01,0x08,0xa4,0x49,0x01,0x14,0x51,0xe0,0x53,0x91,0xd5,0x29,0x06,0x1a,
+0x64,0x02,0xf4,0xc7,0x81,0x9e,0x05,0x20,0x22,0x64,0xa5,0x30,0xae,0xab,0x9e,0x97,
+0x53,0xd8,0xb9,0xfd,0x50,0xef,0x93,0x02,0x42,0x74,0x34,0xe8,0x9c,0x20,0x21,0xc9,
+0x01,0x68,0x78,0xe6,0x55,0x29,0x20,0x56,0x4f,0x4c,0x40,0x51,0x71,0x82,0xc0,0x70,
+0x21,0x22,0x85,0xbe,0x4b,0x1c,0x44,0x05,0xea,0xa4,0x01,0xbf,0x22,0xb5,0xf0,0x1c,
+0x06,0x51,0x38,0x8f,0xe0,0x22,0xec,0x18,0xac,0x39,0x22,0xd4,0xd6,0x93,0x44,0x01,
+0x32,0x82,0xc8,0xfc,0x61,0xb3,0x01,0x45,0x0c,0x2e,0x83,0x30,0xd0,0x0e,0x17,0x24,
+0x0f,0x70,0x85,0x94,0xee,0x05,0x05,0x53,0x4b,0x32,0x1b,0x3f,0x98,0xd3,0x1d,0x29,
+0x81,0xb0,0xae,0x1e,0x8c,0x7e,0x68,0xe0,0x60,0x5a,0x54,0x8f,0xb0,0x78,0x69,0x73,
+0x06,0xa2,0x00,0x6b,0x57,0xca,0x3d,0x11,0x50,0xbd,0x04,0x30,0x4b,0x3a,0xd4,0xab,
+0x5f,0x1f,0x9b,0x3d,0x13,0x74,0x27,0x88,0x3c,0x25,0xe0,0x17,0xbe,0x7a,0x79,0x45,
+0x0d,0x0c,0xb0,0x8b,0xda,0x90,0xca,0x80,0x06,0x5d,0x17,0x60,0x1c,0x22,0x4c,0xd8,
+0x57,0x22,0x06,0x20,0x00,0x98,0x07,0x08,0xe4,0x56,0x80,0x80,0x1c,0xc5,0xb7,0xc5,
+0x82,0x0c,0x36,0xe8,0xe0,0x83,0x10,0x46,0x28,0xe1,0x84,0x14,0x56,0x68,0xa1,0x10,
+0x41,0x00,0x00,0x3b,};
+
+#if FSDATA_FILE_ALIGNMENT==1
+static const unsigned int dummy_align__404_html = 1;
+#endif
+static const unsigned char FSDATA_ALIGN_PRE data__404_html[] FSDATA_ALIGN_POST = {
+/* /404.html (10 chars) */
+0x2f,0x34,0x30,0x34,0x2e,0x68,0x74,0x6d,0x6c,0x00,0x00,0x00,
+
+/* HTTP header */
+/* "HTTP/1.0 404 File not found
+" (29 bytes) */
+0x48,0x54,0x54,0x50,0x2f,0x31,0x2e,0x30,0x20,0x34,0x30,0x34,0x20,0x46,0x69,0x6c,
+0x65,0x20,0x6e,0x6f,0x74,0x20,0x66,0x6f,0x75,0x6e,0x64,0x0d,0x0a,
+/* "Server: lwIP/2.0.3d (http://savannah.nongnu.org/projects/lwip)
+" (64 bytes) */
+0x53,0x65,0x72,0x76,0x65,0x72,0x3a,0x20,0x6c,0x77,0x49,0x50,0x2f,0x32,0x2e,0x30,
+0x2e,0x33,0x64,0x20,0x28,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x73,0x61,0x76,0x61,
+0x6e,0x6e,0x61,0x68,0x2e,0x6e,0x6f,0x6e,0x67,0x6e,0x75,0x2e,0x6f,0x72,0x67,0x2f,
+0x70,0x72,0x6f,0x6a,0x65,0x63,0x74,0x73,0x2f,0x6c,0x77,0x69,0x70,0x29,0x0d,0x0a,
+
+/* "Content-Length: 565
+" (18+ bytes) */
+0x43,0x6f,0x6e,0x74,0x65,0x6e,0x74,0x2d,0x4c,0x65,0x6e,0x67,0x74,0x68,0x3a,0x20,
+0x35,0x36,0x35,0x0d,0x0a,
+/* "Content-Type: text/html
+
+" (27 bytes) */
+0x43,0x6f,0x6e,0x74,0x65,0x6e,0x74,0x2d,0x54,0x79,0x70,0x65,0x3a,0x20,0x74,0x65,
+0x78,0x74,0x2f,0x68,0x74,0x6d,0x6c,0x0d,0x0a,0x0d,0x0a,
+/* raw file data (565 bytes) */
+0x3c,0x68,0x74,0x6d,0x6c,0x3e,0x0d,0x0a,0x3c,0x68,0x65,0x61,0x64,0x3e,0x3c,0x74,
+0x69,0x74,0x6c,0x65,0x3e,0x6c,0x77,0x49,0x50,0x20,0x2d,0x20,0x41,0x20,0x4c,0x69,
+0x67,0x68,0x74,0x77,0x65,0x69,0x67,0x68,0x74,0x20,0x54,0x43,0x50,0x2f,0x49,0x50,
+0x20,0x53,0x74,0x61,0x63,0x6b,0x3c,0x2f,0x74,0x69,0x74,0x6c,0x65,0x3e,0x3c,0x2f,
+0x68,0x65,0x61,0x64,0x3e,0x0d,0x0a,0x3c,0x62,0x6f,0x64,0x79,0x20,0x62,0x67,0x63,
+0x6f,0x6c,0x6f,0x72,0x3d,0x22,0x77,0x68,0x69,0x74,0x65,0x22,0x20,0x74,0x65,0x78,
+0x74,0x3d,0x22,0x62,0x6c,0x61,0x63,0x6b,0x22,0x3e,0x0d,0x0a,0x0d,0x0a,0x20,0x20,
+0x20,0x20,0x3c,0x74,0x61,0x62,0x6c,0x65,0x20,0x77,0x69,0x64,0x74,0x68,0x3d,0x22,
+0x31,0x30,0x30,0x25,0x22,0x3e,0x0d,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x3c,0x74,
+0x72,0x20,0x76,0x61,0x6c,0x69,0x67,0x6e,0x3d,0x22,0x74,0x6f,0x70,0x22,0x3e,0x3c,
+0x74,0x64,0x20,0x77,0x69,0x64,0x74,0x68,0x3d,0x22,0x38,0x30,0x22,0x3e,0x09,0x20,
+0x20,0x0d,0x0a,0x09,0x20,0x20,0x3c,0x61,0x20,0x68,0x72,0x65,0x66,0x3d,0x22,0x68,
+0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77,0x77,0x77,0x2e,0x73,0x69,0x63,0x73,0x2e,0x73,
+0x65,0x2f,0x22,0x3e,0x3c,0x69,0x6d,0x67,0x20,0x73,0x72,0x63,0x3d,0x22,0x2f,0x69,
+0x6d,0x67,0x2f,0x73,0x69,0x63,0x73,0x2e,0x67,0x69,0x66,0x22,0x0d,0x0a,0x09,0x20,
+0x20,0x62,0x6f,0x72,0x64,0x65,0x72,0x3d,0x22,0x30,0x22,0x20,0x61,0x6c,0x74,0x3d,
+0x22,0x53,0x49,0x43,0x53,0x20,0x6c,0x6f,0x67,0x6f,0x22,0x20,0x74,0x69,0x74,0x6c,
+0x65,0x3d,0x22,0x53,0x49,0x43,0x53,0x20,0x6c,0x6f,0x67,0x6f,0x22,0x3e,0x3c,0x2f,
+0x61,0x3e,0x0d,0x0a,0x09,0x3c,0x2f,0x74,0x64,0x3e,0x3c,0x74,0x64,0x20,0x77,0x69,
+0x64,0x74,0x68,0x3d,0x22,0x35,0x30,0x30,0x22,0x3e,0x09,0x20,0x20,0x0d,0x0a,0x09,
+0x20,0x20,0x3c,0x68,0x31,0x3e,0x6c,0x77,0x49,0x50,0x20,0x2d,0x20,0x41,0x20,0x4c,
+0x69,0x67,0x68,0x74,0x77,0x65,0x69,0x67,0x68,0x74,0x20,0x54,0x43,0x50,0x2f,0x49,
+0x50,0x20,0x53,0x74,0x61,0x63,0x6b,0x3c,0x2f,0x68,0x31,0x3e,0x0d,0x0a,0x09,0x20,
+0x20,0x3c,0x68,0x32,0x3e,0x34,0x30,0x34,0x20,0x2d,0x20,0x50,0x61,0x67,0x65,0x20,
+0x6e,0x6f,0x74,0x20,0x66,0x6f,0x75,0x6e,0x64,0x3c,0x2f,0x68,0x32,0x3e,0x0d,0x0a,
+0x09,0x20,0x20,0x3c,0x70,0x3e,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x53,0x6f,0x72,
+0x72,0x79,0x2c,0x20,0x74,0x68,0x65,0x20,0x70,0x61,0x67,0x65,0x20,0x79,0x6f,0x75,
+0x20,0x61,0x72,0x65,0x20,0x72,0x65,0x71,0x75,0x65,0x73,0x74,0x69,0x6e,0x67,0x20,
+0x77,0x61,0x73,0x20,0x6e,0x6f,0x74,0x20,0x66,0x6f,0x75,0x6e,0x64,0x20,0x6f,0x6e,
+0x20,0x74,0x68,0x69,0x73,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x73,0x65,0x72,0x76,
+0x65,0x72,0x2e,0x20,0x0d,0x0a,0x09,0x20,0x20,0x3c,0x2f,0x70,0x3e,0x0d,0x0a,0x09,
+0x3c,0x2f,0x74,0x64,0x3e,0x3c,0x74,0x64,0x3e,0x0d,0x0a,0x09,0x20,0x20,0x26,0x6e,
+0x62,0x73,0x70,0x3b,0x0d,0x0a,0x09,0x3c,0x2f,0x74,0x64,0x3e,0x3c,0x2f,0x74,0x72,
+0x3e,0x0d,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x3c,0x2f,0x74,0x61,0x62,0x6c,0x65,
+0x3e,0x0d,0x0a,0x3c,0x2f,0x62,0x6f,0x64,0x79,0x3e,0x0d,0x0a,0x3c,0x2f,0x68,0x74,
+0x6d,0x6c,0x3e,0x0d,0x0a,};
+
+#if FSDATA_FILE_ALIGNMENT==1
+static const unsigned int dummy_align__index_html = 2;
+#endif
+static const unsigned char FSDATA_ALIGN_PRE data__index_html[] FSDATA_ALIGN_POST = {
+/* /index.html (12 chars) */
+0x2f,0x69,0x6e,0x64,0x65,0x78,0x2e,0x68,0x74,0x6d,0x6c,0x00,
+
+/* HTTP header */
+/* "HTTP/1.0 200 OK
+" (17 bytes) */
+0x48,0x54,0x54,0x50,0x2f,0x31,0x2e,0x30,0x20,0x32,0x30,0x30,0x20,0x4f,0x4b,0x0d,
+0x0a,
+/* "Server: lwIP/2.0.3d (http://savannah.nongnu.org/projects/lwip)
+" (64 bytes) */
+0x53,0x65,0x72,0x76,0x65,0x72,0x3a,0x20,0x6c,0x77,0x49,0x50,0x2f,0x32,0x2e,0x30,
+0x2e,0x33,0x64,0x20,0x28,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x73,0x61,0x76,0x61,
+0x6e,0x6e,0x61,0x68,0x2e,0x6e,0x6f,0x6e,0x67,0x6e,0x75,0x2e,0x6f,0x72,0x67,0x2f,
+0x70,0x72,0x6f,0x6a,0x65,0x63,0x74,0x73,0x2f,0x6c,0x77,0x69,0x70,0x29,0x0d,0x0a,
+
+/* "Content-Length: 1751
+" (18+ bytes) */
+0x43,0x6f,0x6e,0x74,0x65,0x6e,0x74,0x2d,0x4c,0x65,0x6e,0x67,0x74,0x68,0x3a,0x20,
+0x31,0x37,0x35,0x31,0x0d,0x0a,
+/* "Content-Type: text/html
+
+" (27 bytes) */
+0x43,0x6f,0x6e,0x74,0x65,0x6e,0x74,0x2d,0x54,0x79,0x70,0x65,0x3a,0x20,0x74,0x65,
+0x78,0x74,0x2f,0x68,0x74,0x6d,0x6c,0x0d,0x0a,0x0d,0x0a,
+/* raw file data (1751 bytes) */
+0x3c,0x68,0x74,0x6d,0x6c,0x3e,0x0d,0x0a,0x3c,0x68,0x65,0x61,0x64,0x3e,0x3c,0x74,
+0x69,0x74,0x6c,0x65,0x3e,0x6c,0x77,0x49,0x50,0x20,0x2d,0x20,0x41,0x20,0x4c,0x69,
+0x67,0x68,0x74,0x77,0x65,0x69,0x67,0x68,0x74,0x20,0x54,0x43,0x50,0x2f,0x49,0x50,
+0x20,0x53,0x74,0x61,0x63,0x6b,0x3c,0x2f,0x74,0x69,0x74,0x6c,0x65,0x3e,0x3c,0x2f,
+0x68,0x65,0x61,0x64,0x3e,0x0d,0x0a,0x3c,0x62,0x6f,0x64,0x79,0x20,0x62,0x67,0x63,
+0x6f,0x6c,0x6f,0x72,0x3d,0x22,0x77,0x68,0x69,0x74,0x65,0x22,0x20,0x74,0x65,0x78,
+0x74,0x3d,0x22,0x62,0x6c,0x61,0x63,0x6b,0x22,0x3e,0x0d,0x0a,0x0d,0x0a,0x20,0x20,
+0x20,0x20,0x3c,0x74,0x61,0x62,0x6c,0x65,0x20,0x77,0x69,0x64,0x74,0x68,0x3d,0x22,
+0x31,0x30,0x30,0x25,0x22,0x3e,0x0d,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x3c,0x74,
+0x72,0x20,0x76,0x61,0x6c,0x69,0x67,0x6e,0x3d,0x22,0x74,0x6f,0x70,0x22,0x3e,0x3c,
+0x74,0x64,0x20,0x77,0x69,0x64,0x74,0x68,0x3d,0x22,0x38,0x30,0x22,0x3e,0x09,0x20,
+0x20,0x0d,0x0a,0x09,0x20,0x20,0x3c,0x61,0x20,0x68,0x72,0x65,0x66,0x3d,0x22,0x68,
+0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77,0x77,0x77,0x2e,0x73,0x69,0x63,0x73,0x2e,0x73,
+0x65,0x2f,0x22,0x3e,0x3c,0x69,0x6d,0x67,0x20,0x73,0x72,0x63,0x3d,0x22,0x2f,0x69,
+0x6d,0x67,0x2f,0x73,0x69,0x63,0x73,0x2e,0x67,0x69,0x66,0x22,0x0d,0x0a,0x09,0x20,
+0x20,0x62,0x6f,0x72,0x64,0x65,0x72,0x3d,0x22,0x30,0x22,0x20,0x61,0x6c,0x74,0x3d,
+0x22,0x53,0x49,0x43,0x53,0x20,0x6c,0x6f,0x67,0x6f,0x22,0x20,0x74,0x69,0x74,0x6c,
+0x65,0x3d,0x22,0x53,0x49,0x43,0x53,0x20,0x6c,0x6f,0x67,0x6f,0x22,0x3e,0x3c,0x2f,
+0x61,0x3e,0x0d,0x0a,0x09,0x3c,0x2f,0x74,0x64,0x3e,0x3c,0x74,0x64,0x20,0x77,0x69,
+0x64,0x74,0x68,0x3d,0x22,0x35,0x30,0x30,0x22,0x3e,0x09,0x20,0x20,0x0d,0x0a,0x09,
+0x20,0x20,0x3c,0x68,0x31,0x3e,0x6c,0x77,0x49,0x50,0x20,0x2d,0x20,0x41,0x20,0x4c,
+0x69,0x67,0x68,0x74,0x77,0x65,0x69,0x67,0x68,0x74,0x20,0x54,0x43,0x50,0x2f,0x49,
+0x50,0x20,0x53,0x74,0x61,0x63,0x6b,0x3c,0x2f,0x68,0x31,0x3e,0x0d,0x0a,0x09,0x20,
+0x20,0x3c,0x70,0x3e,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x54,0x68,0x65,0x20,0x77,
+0x65,0x62,0x20,0x70,0x61,0x67,0x65,0x20,0x79,0x6f,0x75,0x20,0x61,0x72,0x65,0x20,
+0x77,0x61,0x74,0x63,0x68,0x69,0x6e,0x67,0x20,0x77,0x61,0x73,0x20,0x73,0x65,0x72,
+0x76,0x65,0x64,0x20,0x62,0x79,0x20,0x61,0x20,0x73,0x69,0x6d,0x70,0x6c,0x65,0x20,
+0x77,0x65,0x62,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x73,0x65,0x72,0x76,0x65,0x72,
+0x20,0x72,0x75,0x6e,0x6e,0x69,0x6e,0x67,0x20,0x6f,0x6e,0x20,0x74,0x6f,0x70,0x20,
+0x6f,0x66,0x20,0x74,0x68,0x65,0x20,0x6c,0x69,0x67,0x68,0x74,0x77,0x65,0x69,0x67,
+0x68,0x74,0x20,0x54,0x43,0x50,0x2f,0x49,0x50,0x20,0x73,0x74,0x61,0x63,0x6b,0x20,
+0x3c,0x61,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x68,0x72,0x65,0x66,0x3d,0x22,0x68,
+0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77,0x77,0x77,0x2e,0x73,0x69,0x63,0x73,0x2e,0x73,
+0x65,0x2f,0x7e,0x61,0x64,0x61,0x6d,0x2f,0x6c,0x77,0x69,0x70,0x2f,0x22,0x3e,0x6c,
+0x77,0x49,0x50,0x3c,0x2f,0x61,0x3e,0x2e,0x0d,0x0a,0x09,0x20,0x20,0x3c,0x2f,0x70,
+0x3e,0x0d,0x0a,0x09,0x20,0x20,0x3c,0x70,0x3e,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,
+0x6c,0x77,0x49,0x50,0x20,0x69,0x73,0x20,0x61,0x6e,0x20,0x6f,0x70,0x65,0x6e,0x20,
+0x73,0x6f,0x75,0x72,0x63,0x65,0x20,0x69,0x6d,0x70,0x6c,0x65,0x6d,0x65,0x6e,0x74,
+0x61,0x74,0x69,0x6f,0x6e,0x20,0x6f,0x66,0x20,0x74,0x68,0x65,0x20,0x54,0x43,0x50,
+0x2f,0x49,0x50,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x70,0x72,0x6f,0x74,0x6f,0x63,
+0x6f,0x6c,0x20,0x73,0x75,0x69,0x74,0x65,0x20,0x74,0x68,0x61,0x74,0x20,0x77,0x61,
+0x73,0x20,0x6f,0x72,0x69,0x67,0x69,0x6e,0x61,0x6c,0x6c,0x79,0x20,0x77,0x72,0x69,
+0x74,0x74,0x65,0x6e,0x20,0x62,0x79,0x20,0x3c,0x61,0x0d,0x0a,0x09,0x20,0x20,0x20,
+0x20,0x68,0x72,0x65,0x66,0x3d,0x22,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77,0x77,
+0x77,0x2e,0x73,0x69,0x63,0x73,0x2e,0x73,0x65,0x2f,0x7e,0x61,0x64,0x61,0x6d,0x2f,
+0x6c,0x77,0x69,0x70,0x2f,0x22,0x3e,0x41,0x64,0x61,0x6d,0x20,0x44,0x75,0x6e,0x6b,
+0x65,0x6c,0x73,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x6f,0x66,0x20,0x74,0x68,0x65,
+0x20,0x53,0x77,0x65,0x64,0x69,0x73,0x68,0x20,0x49,0x6e,0x73,0x74,0x69,0x74,0x75,
+0x74,0x65,0x20,0x6f,0x66,0x20,0x43,0x6f,0x6d,0x70,0x75,0x74,0x65,0x72,0x20,0x53,
+0x63,0x69,0x65,0x6e,0x63,0x65,0x3c,0x2f,0x61,0x3e,0x20,0x62,0x75,0x74,0x20,0x6e,
+0x6f,0x77,0x20,0x69,0x73,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x62,0x65,0x69,0x6e,
+0x67,0x20,0x61,0x63,0x74,0x69,0x76,0x65,0x6c,0x79,0x20,0x64,0x65,0x76,0x65,0x6c,
+0x6f,0x70,0x65,0x64,0x20,0x62,0x79,0x20,0x61,0x20,0x74,0x65,0x61,0x6d,0x20,0x6f,
+0x66,0x20,0x64,0x65,0x76,0x65,0x6c,0x6f,0x70,0x65,0x72,0x73,0x0d,0x0a,0x09,0x20,
+0x20,0x20,0x20,0x64,0x69,0x73,0x74,0x72,0x69,0x62,0x75,0x74,0x65,0x64,0x20,0x77,
+0x6f,0x72,0x6c,0x64,0x2d,0x77,0x69,0x64,0x65,0x2e,0x20,0x53,0x69,0x6e,0x63,0x65,
+0x20,0x69,0x74,0x27,0x73,0x20,0x72,0x65,0x6c,0x65,0x61,0x73,0x65,0x2c,0x20,0x6c,
+0x77,0x49,0x50,0x20,0x68,0x61,0x73,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x73,0x70,
+0x75,0x72,0x72,0x65,0x64,0x20,0x61,0x20,0x6c,0x6f,0x74,0x20,0x6f,0x66,0x20,0x69,
+0x6e,0x74,0x65,0x72,0x65,0x73,0x74,0x20,0x61,0x6e,0x64,0x20,0x68,0x61,0x73,0x20,
+0x62,0x65,0x65,0x6e,0x20,0x70,0x6f,0x72,0x74,0x65,0x64,0x20,0x74,0x6f,0x20,0x73,
+0x65,0x76,0x65,0x72,0x61,0x6c,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x70,0x6c,0x61,
+0x74,0x66,0x6f,0x72,0x6d,0x73,0x20,0x61,0x6e,0x64,0x20,0x6f,0x70,0x65,0x72,0x61,
+0x74,0x69,0x6e,0x67,0x20,0x73,0x79,0x73,0x74,0x65,0x6d,0x73,0x2e,0x20,0x6c,0x77,
+0x49,0x50,0x20,0x63,0x61,0x6e,0x20,0x62,0x65,0x20,0x75,0x73,0x65,0x64,0x20,0x65,
+0x69,0x74,0x68,0x65,0x72,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x77,0x69,0x74,0x68,
+0x20,0x6f,0x72,0x20,0x77,0x69,0x74,0x68,0x6f,0x75,0x74,0x20,0x61,0x6e,0x20,0x75,
+0x6e,0x64,0x65,0x72,0x6c,0x79,0x69,0x6e,0x67,0x20,0x4f,0x53,0x2e,0x0d,0x0a,0x09,
+0x20,0x20,0x3c,0x2f,0x70,0x3e,0x0d,0x0a,0x09,0x20,0x20,0x3c,0x70,0x3e,0x0d,0x0a,
+0x09,0x20,0x20,0x20,0x20,0x54,0x68,0x65,0x20,0x66,0x6f,0x63,0x75,0x73,0x20,0x6f,
+0x66,0x20,0x74,0x68,0x65,0x20,0x6c,0x77,0x49,0x50,0x20,0x54,0x43,0x50,0x2f,0x49,
+0x50,0x20,0x69,0x6d,0x70,0x6c,0x65,0x6d,0x65,0x6e,0x74,0x61,0x74,0x69,0x6f,0x6e,
+0x20,0x69,0x73,0x20,0x74,0x6f,0x20,0x72,0x65,0x64,0x75,0x63,0x65,0x0d,0x0a,0x09,
+0x20,0x20,0x20,0x20,0x74,0x68,0x65,0x20,0x52,0x41,0x4d,0x20,0x75,0x73,0x61,0x67,
+0x65,0x20,0x77,0x68,0x69,0x6c,0x65,0x20,0x73,0x74,0x69,0x6c,0x6c,0x20,0x68,0x61,
+0x76,0x69,0x6e,0x67,0x20,0x61,0x20,0x66,0x75,0x6c,0x6c,0x20,0x73,0x63,0x61,0x6c,
+0x65,0x20,0x54,0x43,0x50,0x2e,0x20,0x54,0x68,0x69,0x73,0x0d,0x0a,0x09,0x20,0x20,
+0x20,0x20,0x6d,0x61,0x6b,0x65,0x73,0x20,0x6c,0x77,0x49,0x50,0x20,0x73,0x75,0x69,
+0x74,0x61,0x62,0x6c,0x65,0x20,0x66,0x6f,0x72,0x20,0x75,0x73,0x65,0x20,0x69,0x6e,
+0x20,0x65,0x6d,0x62,0x65,0x64,0x64,0x65,0x64,0x20,0x73,0x79,0x73,0x74,0x65,0x6d,
+0x73,0x20,0x77,0x69,0x74,0x68,0x20,0x74,0x65,0x6e,0x73,0x0d,0x0a,0x09,0x20,0x20,
+0x20,0x20,0x6f,0x66,0x20,0x6b,0x69,0x6c,0x6f,0x62,0x79,0x74,0x65,0x73,0x20,0x6f,
+0x66,0x20,0x66,0x72,0x65,0x65,0x20,0x52,0x41,0x4d,0x20,0x61,0x6e,0x64,0x20,0x72,
+0x6f,0x6f,0x6d,0x20,0x66,0x6f,0x72,0x20,0x61,0x72,0x6f,0x75,0x6e,0x64,0x20,0x34,
+0x30,0x20,0x6b,0x69,0x6c,0x6f,0x62,0x79,0x74,0x65,0x73,0x0d,0x0a,0x09,0x20,0x20,
+0x20,0x20,0x6f,0x66,0x20,0x63,0x6f,0x64,0x65,0x20,0x52,0x4f,0x4d,0x2e,0x0d,0x0a,
+0x09,0x20,0x20,0x3c,0x2f,0x70,0x3e,0x0d,0x0a,0x09,0x20,0x20,0x3c,0x70,0x3e,0x0d,
+0x0a,0x09,0x20,0x20,0x20,0x20,0x4d,0x6f,0x72,0x65,0x20,0x69,0x6e,0x66,0x6f,0x72,
+0x6d,0x61,0x74,0x69,0x6f,0x6e,0x20,0x61,0x62,0x6f,0x75,0x74,0x20,0x6c,0x77,0x49,
+0x50,0x20,0x63,0x61,0x6e,0x20,0x62,0x65,0x20,0x66,0x6f,0x75,0x6e,0x64,0x20,0x61,
+0x74,0x20,0x74,0x68,0x65,0x20,0x6c,0x77,0x49,0x50,0x0d,0x0a,0x09,0x20,0x20,0x20,
+0x20,0x68,0x6f,0x6d,0x65,0x70,0x61,0x67,0x65,0x20,0x61,0x74,0x20,0x3c,0x61,0x0d,
+0x0a,0x09,0x20,0x20,0x20,0x20,0x68,0x72,0x65,0x66,0x3d,0x22,0x68,0x74,0x74,0x70,
+0x3a,0x2f,0x2f,0x73,0x61,0x76,0x61,0x6e,0x6e,0x61,0x68,0x2e,0x6e,0x6f,0x6e,0x67,
+0x6e,0x75,0x2e,0x6f,0x72,0x67,0x2f,0x70,0x72,0x6f,0x6a,0x65,0x63,0x74,0x73,0x2f,
+0x6c,0x77,0x69,0x70,0x2f,0x22,0x3e,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x73,0x61,
+0x76,0x61,0x6e,0x6e,0x61,0x68,0x2e,0x6e,0x6f,0x6e,0x67,0x6e,0x75,0x2e,0x6f,0x72,
+0x67,0x2f,0x70,0x72,0x6f,0x6a,0x65,0x63,0x74,0x73,0x2f,0x6c,0x77,0x69,0x70,0x2f,
+0x3c,0x2f,0x61,0x3e,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x6f,0x72,0x20,0x61,0x74,
+0x20,0x74,0x68,0x65,0x20,0x6c,0x77,0x49,0x50,0x20,0x77,0x69,0x6b,0x69,0x20,0x61,
+0x74,0x20,0x3c,0x61,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x68,0x72,0x65,0x66,0x3d,
+0x22,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x6c,0x77,0x69,0x70,0x2e,0x77,0x69,0x6b,
+0x69,0x61,0x2e,0x63,0x6f,0x6d,0x2f,0x22,0x3e,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,
+0x6c,0x77,0x69,0x70,0x2e,0x77,0x69,0x6b,0x69,0x61,0x2e,0x63,0x6f,0x6d,0x2f,0x3c,
+0x2f,0x61,0x3e,0x2e,0x0d,0x0a,0x09,0x20,0x20,0x3c,0x2f,0x70,0x3e,0x0d,0x0a,0x09,
+0x3c,0x2f,0x74,0x64,0x3e,0x3c,0x74,0x64,0x3e,0x0d,0x0a,0x09,0x20,0x20,0x26,0x6e,
+0x62,0x73,0x70,0x3b,0x0d,0x0a,0x09,0x3c,0x2f,0x74,0x64,0x3e,0x3c,0x2f,0x74,0x72,
+0x3e,0x0d,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x3c,0x2f,0x74,0x61,0x62,0x6c,0x65,
+0x3e,0x0d,0x0a,0x3c,0x2f,0x62,0x6f,0x64,0x79,0x3e,0x0d,0x0a,0x3c,0x2f,0x68,0x74,
+0x6d,0x6c,0x3e,0x0d,0x0a,0x0d,0x0a,};
+
+
+
+const struct fsdata_file file__img_sics_gif[] = { {
+file_NULL,
+data__img_sics_gif,
+data__img_sics_gif + 16,
+sizeof(data__img_sics_gif) - 16,
+FS_FILE_FLAGS_HEADER_INCLUDED | FS_FILE_FLAGS_HEADER_PERSISTENT,
+}};
+
+const struct fsdata_file file__404_html[] = { {
+file__img_sics_gif,
+data__404_html,
+data__404_html + 12,
+sizeof(data__404_html) - 12,
+FS_FILE_FLAGS_HEADER_INCLUDED | FS_FILE_FLAGS_HEADER_PERSISTENT,
+}};
+
+const struct fsdata_file file__index_html[] = { {
+file__404_html,
+data__index_html,
+data__index_html + 12,
+sizeof(data__index_html) - 12,
+FS_FILE_FLAGS_HEADER_INCLUDED | FS_FILE_FLAGS_HEADER_PERSISTENT,
+}};
+
+#define FS_ROOT file__index_html
+#define FS_NUMFILES 3
+
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/apps/http/fsdata.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/apps/http/fsdata.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/apps/http/fsdata.h	(revision 457)
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2001-2003 Swedish Institute of Computer Science.
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Adam Dunkels <adam@sics.se>
+ *
+ */
+#ifndef LWIP_FSDATA_H
+#define LWIP_FSDATA_H
+
+#include "lwip/apps/httpd_opts.h"
+#include "lwip/apps/fs.h"
+
+/* THIS FILE IS DEPRECATED AND WILL BE REMOVED IN THE FUTURE */
+/* content was moved to fs.h to simplify #include structure */
+
+#endif /* LWIP_FSDATA_H */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/apps/http/http_client.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/apps/http/http_client.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/apps/http/http_client.c	(revision 457)
@@ -0,0 +1,909 @@
+/**
+ * @file
+ * HTTP client
+ */
+
+/*
+ * Copyright (c) 2018 Simon Goldschmidt <goldsimon@gmx.de>
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Simon Goldschmidt <goldsimon@gmx.de>
+ */
+
+/**
+ * @defgroup httpc HTTP client
+ * @ingroup apps
+ * @todo:
+ * - persistent connections
+ * - select outgoing http version
+ * - optionally follow redirect
+ * - check request uri for invalid characters? (e.g. encode spaces)
+ * - IPv6 support
+ */
+
+#include "lwip/apps/http_client.h"
+
+#include "lwip/altcp_tcp.h"
+#include "lwip/dns.h"
+#include "lwip/debug.h"
+#include "lwip/mem.h"
+#include "lwip/altcp_tls.h"
+#include "lwip/init.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#if LWIP_TCP && LWIP_CALLBACK_API
+
+/**
+ * HTTPC_DEBUG: Enable debugging for HTTP client.
+ */
+#ifndef HTTPC_DEBUG
+#define HTTPC_DEBUG                 LWIP_DBG_OFF
+#endif
+
+/** Set this to 1 to keep server name and uri in request state */
+#ifndef HTTPC_DEBUG_REQUEST
+#define HTTPC_DEBUG_REQUEST         0
+#endif
+
+/** This string is passed in the HTTP header as "User-Agent: " */
+#ifndef HTTPC_CLIENT_AGENT
+#define HTTPC_CLIENT_AGENT "lwIP/" LWIP_VERSION_STRING " (http://savannah.nongnu.org/projects/lwip)"
+#endif
+
+/* the various debug levels for this file */
+#define HTTPC_DEBUG_TRACE        (HTTPC_DEBUG | LWIP_DBG_TRACE)
+#define HTTPC_DEBUG_STATE        (HTTPC_DEBUG | LWIP_DBG_STATE)
+#define HTTPC_DEBUG_WARN         (HTTPC_DEBUG | LWIP_DBG_LEVEL_WARNING)
+#define HTTPC_DEBUG_WARN_STATE   (HTTPC_DEBUG | LWIP_DBG_LEVEL_WARNING | LWIP_DBG_STATE)
+#define HTTPC_DEBUG_SERIOUS      (HTTPC_DEBUG | LWIP_DBG_LEVEL_SERIOUS)
+
+#define HTTPC_POLL_INTERVAL     1
+#define HTTPC_POLL_TIMEOUT      30 /* 15 seconds */
+
+#define HTTPC_CONTENT_LEN_INVALID 0xFFFFFFFF
+
+/* GET request basic */
+#define HTTPC_REQ_11 "GET %s HTTP/1.1\r\n" /* URI */\
+    "User-Agent: %s\r\n" /* User-Agent */ \
+    "Accept: */*\r\n" \
+    "Connection: Close\r\n" /* we don't support persistent connections, yet */ \
+    "\r\n"
+#define HTTPC_REQ_11_FORMAT(uri) HTTPC_REQ_11, uri, HTTPC_CLIENT_AGENT
+
+/* GET request with host */
+#define HTTPC_REQ_11_HOST "GET %s HTTP/1.1\r\n" /* URI */\
+    "User-Agent: %s\r\n" /* User-Agent */ \
+    "Accept: */*\r\n" \
+    "Host: %s\r\n" /* server name */ \
+    "Connection: Close\r\n" /* we don't support persistent connections, yet */ \
+    "\r\n"
+#define HTTPC_REQ_11_HOST_FORMAT(uri, srv_name) HTTPC_REQ_11_HOST, uri, HTTPC_CLIENT_AGENT, srv_name
+
+/* GET request with proxy */
+#define HTTPC_REQ_11_PROXY "GET http://%s%s HTTP/1.1\r\n" /* HOST, URI */\
+    "User-Agent: %s\r\n" /* User-Agent */ \
+    "Accept: */*\r\n" \
+    "Host: %s\r\n" /* server name */ \
+    "Connection: Close\r\n" /* we don't support persistent connections, yet */ \
+    "\r\n"
+#define HTTPC_REQ_11_PROXY_FORMAT(host, uri, srv_name) HTTPC_REQ_11_PROXY, host, uri, HTTPC_CLIENT_AGENT, srv_name
+
+/* GET request with proxy (non-default server port) */
+#define HTTPC_REQ_11_PROXY_PORT "GET http://%s:%d%s HTTP/1.1\r\n" /* HOST, host-port, URI */\
+    "User-Agent: %s\r\n" /* User-Agent */ \
+    "Accept: */*\r\n" \
+    "Host: %s\r\n" /* server name */ \
+    "Connection: Close\r\n" /* we don't support persistent connections, yet */ \
+    "\r\n"
+#define HTTPC_REQ_11_PROXY_PORT_FORMAT(host, host_port, uri, srv_name) HTTPC_REQ_11_PROXY_PORT, host, host_port, uri, HTTPC_CLIENT_AGENT, srv_name
+
+typedef enum ehttpc_parse_state {
+  HTTPC_PARSE_WAIT_FIRST_LINE = 0,
+  HTTPC_PARSE_WAIT_HEADERS,
+  HTTPC_PARSE_RX_DATA
+} httpc_parse_state_t;
+
+typedef struct _httpc_state
+{
+  struct altcp_pcb* pcb;
+  ip_addr_t remote_addr;
+  u16_t remote_port;
+  int timeout_ticks;
+  struct pbuf *request;
+  struct pbuf *rx_hdrs;
+  u16_t rx_http_version;
+  u16_t rx_status;
+  altcp_recv_fn recv_fn;
+  const httpc_connection_t *conn_settings;
+  void* callback_arg;
+  u32_t rx_content_len;
+  u32_t hdr_content_len;
+  httpc_parse_state_t parse_state;
+#if HTTPC_DEBUG_REQUEST
+  char* server_name;
+  char* uri;
+#endif
+} httpc_state_t;
+
+/** Free http client state and deallocate all resources within */
+static err_t
+httpc_free_state(httpc_state_t* req)
+{
+  struct altcp_pcb* tpcb;
+
+  if (req->request != NULL) {
+    pbuf_free(req->request);
+    req->request = NULL;
+  }
+  if (req->rx_hdrs != NULL) {
+    pbuf_free(req->rx_hdrs);
+    req->rx_hdrs = NULL;
+  }
+
+  tpcb = req->pcb;
+  mem_free(req);
+  req = NULL;
+
+  if (tpcb != NULL) {
+    err_t r;
+    altcp_arg(tpcb, NULL);
+    altcp_recv(tpcb, NULL);
+    altcp_err(tpcb, NULL);
+    altcp_poll(tpcb, NULL, 0);
+    altcp_sent(tpcb, NULL);
+    r = altcp_close(tpcb);
+    if (r != ERR_OK) {
+      altcp_abort(tpcb);
+      return ERR_ABRT;
+    }
+  }
+  return ERR_OK;
+}
+
+/** Close the connection: call finished callback and free the state */
+static err_t
+httpc_close(httpc_state_t* req, httpc_result_t result, u32_t server_response, err_t err)
+{
+  if (req != NULL) {
+    if (req->conn_settings != NULL) {
+      if (req->conn_settings->result_fn != NULL) {
+        req->conn_settings->result_fn(req->callback_arg, result, req->rx_content_len, server_response, err);
+      }
+    }
+    return httpc_free_state(req);
+  }
+  return ERR_OK;
+}
+
+/** Parse http header response line 1 */
+static err_t
+http_parse_response_status(struct pbuf *p, u16_t *http_version, u16_t *http_status, u16_t *http_status_str_offset)
+{
+  u16_t end1 = pbuf_memfind(p, "\r\n", 2, 0);
+  if (end1 != 0xFFFF) {
+    /* get parts of first line */
+    u16_t space1, space2;
+    space1 = pbuf_memfind(p, " ", 1, 0);
+    if (space1 != 0xFFFF) {
+      if ((pbuf_memcmp(p, 0, "HTTP/", 5) == 0)  && (pbuf_get_at(p, 6) == '.')) {
+        char status_num[10];
+        size_t status_num_len;
+        /* parse http version */
+        u16_t version = pbuf_get_at(p, 5) - '0';
+        version <<= 8;
+        version |= pbuf_get_at(p, 7) - '0';
+        *http_version = version;
+
+        /* parse http status number */
+        space2 = pbuf_memfind(p, " ", 1, space1 + 1);
+        if (space2 != 0xFFFF) {
+          *http_status_str_offset = space2 + 1;
+          status_num_len = space2 - space1 - 1;
+        } else {
+          status_num_len = end1 - space1 - 1;
+        }
+        memset(status_num, 0, sizeof(status_num));
+        if (pbuf_copy_partial(p, status_num, (u16_t)status_num_len, space1 + 1) == status_num_len) {
+          int status = atoi(status_num);
+          if ((status > 0) && (status <= 0xFFFF)) {
+            *http_status = (u16_t)status;
+            return ERR_OK;
+          }
+        }
+      }
+    }
+  }
+  return ERR_VAL;
+}
+
+/** Wait for all headers to be received, return its length and content-length (if available) */
+static err_t
+http_wait_headers(struct pbuf *p, u32_t *content_length, u16_t *total_header_len)
+{
+  u16_t end1 = pbuf_memfind(p, "\r\n\r\n", 4, 0);
+  if (end1 < (0xFFFF - 2)) {
+    /* all headers received */
+    /* check if we have a content length (@todo: case insensitive?) */
+    u16_t content_len_hdr;
+    *content_length = HTTPC_CONTENT_LEN_INVALID;
+    *total_header_len = end1 + 4;
+
+    content_len_hdr = pbuf_memfind(p, "Content-Length: ", 16, 0);
+    if (content_len_hdr != 0xFFFF) {
+      u16_t content_len_line_end = pbuf_memfind(p, "\r\n", 2, content_len_hdr);
+      if (content_len_line_end != 0xFFFF) {
+        char content_len_num[16];
+        u16_t content_len_num_len = (u16_t)(content_len_line_end - content_len_hdr - 16);
+        memset(content_len_num, 0, sizeof(content_len_num));
+        if (pbuf_copy_partial(p, content_len_num, content_len_num_len, content_len_hdr + 16) == content_len_num_len) {
+          int len = atoi(content_len_num);
+          if ((len >= 0) && ((u32_t)len < HTTPC_CONTENT_LEN_INVALID)) {
+            *content_length = (u32_t)len;
+          }
+        }
+      }
+    }
+    return ERR_OK;
+  }
+  return ERR_VAL;
+}
+
+/** http client tcp recv callback */
+static err_t
+httpc_tcp_recv(void *arg, struct altcp_pcb *pcb, struct pbuf *p, err_t r)
+{
+  httpc_state_t* req = (httpc_state_t*)arg;
+  LWIP_UNUSED_ARG(r);
+
+  if (p == NULL) {
+    httpc_result_t result;
+    if (req->parse_state != HTTPC_PARSE_RX_DATA) {
+      /* did not get RX data yet */
+      result = HTTPC_RESULT_ERR_CLOSED;
+    } else if ((req->hdr_content_len != HTTPC_CONTENT_LEN_INVALID) &&
+      (req->hdr_content_len != req->rx_content_len)) {
+      /* header has been received with content length but not all data received */
+      result = HTTPC_RESULT_ERR_CONTENT_LEN;
+    } else {
+      /* receiving data and either all data received or no content length header */
+      result = HTTPC_RESULT_OK;
+    }
+    return httpc_close(req, result, req->rx_status, ERR_OK);
+  }
+  if (req->parse_state != HTTPC_PARSE_RX_DATA) {
+    if (req->rx_hdrs == NULL) {
+      req->rx_hdrs = p;
+    } else {
+      pbuf_cat(req->rx_hdrs, p);
+    }
+    if (req->parse_state == HTTPC_PARSE_WAIT_FIRST_LINE) {
+      u16_t status_str_off;
+      err_t err = http_parse_response_status(req->rx_hdrs, &req->rx_http_version, &req->rx_status, &status_str_off);
+      if (err == ERR_OK) {
+        /* don't care status string */
+        req->parse_state = HTTPC_PARSE_WAIT_HEADERS;
+      }
+    }
+    if (req->parse_state == HTTPC_PARSE_WAIT_HEADERS) {
+      u16_t total_header_len;
+      err_t err = http_wait_headers(req->rx_hdrs, &req->hdr_content_len, &total_header_len);
+      if (err == ERR_OK) {
+        struct pbuf *q;
+        /* full header received, send window update for header bytes and call into client callback */
+        altcp_recved(pcb, total_header_len);
+        if (req->conn_settings) {
+          if (req->conn_settings->headers_done_fn) {
+            err = req->conn_settings->headers_done_fn(req, req->callback_arg, req->rx_hdrs, total_header_len, req->hdr_content_len);
+            if (err != ERR_OK) {
+              return httpc_close(req, HTTPC_RESULT_LOCAL_ABORT, req->rx_status, err);
+            }
+          }
+        }
+        /* hide header bytes in pbuf */
+        q = pbuf_free_header(req->rx_hdrs, total_header_len);
+        p = q;
+        req->rx_hdrs = NULL;
+        /* go on with data */
+        req->parse_state = HTTPC_PARSE_RX_DATA;
+      }
+    }
+  }
+  if ((p != NULL) && (req->parse_state == HTTPC_PARSE_RX_DATA)) {
+    req->rx_content_len += p->tot_len;
+    if (req->recv_fn != NULL) {
+      /* directly return here: the connection migth already be aborted from the callback! */
+      return req->recv_fn(req->callback_arg, pcb, p, r);
+    } else {
+      altcp_recved(pcb, p->tot_len);
+      pbuf_free(p);
+    }
+  }
+  return ERR_OK;
+}
+
+/** http client tcp err callback */
+static void
+httpc_tcp_err(void *arg, err_t err)
+{
+  httpc_state_t* req = (httpc_state_t*)arg;
+  if (req != NULL) {
+    /* pcb has already been deallocated */
+    req->pcb = NULL;
+    httpc_close(req, HTTPC_RESULT_ERR_CLOSED, 0, err);
+  }
+}
+
+/** http client tcp poll callback */
+static err_t
+httpc_tcp_poll(void *arg, struct altcp_pcb *pcb)
+{
+  /* implement timeout */
+  httpc_state_t* req = (httpc_state_t*)arg;
+  LWIP_UNUSED_ARG(pcb);
+  if (req != NULL) {
+    if (req->timeout_ticks) {
+      req->timeout_ticks--;
+    }
+    if (!req->timeout_ticks) {
+      return httpc_close(req, HTTPC_RESULT_ERR_TIMEOUT, 0, ERR_OK);
+    }
+  }
+  return ERR_OK;
+}
+
+/** http client tcp sent callback */
+static err_t
+httpc_tcp_sent(void *arg, struct altcp_pcb *pcb, u16_t len)
+{
+  /* nothing to do here for now */
+  LWIP_UNUSED_ARG(arg);
+  LWIP_UNUSED_ARG(pcb);
+  LWIP_UNUSED_ARG(len);
+  return ERR_OK;
+}
+
+/** http client tcp connected callback */
+static err_t
+httpc_tcp_connected(void *arg, struct altcp_pcb *pcb, err_t err)
+{
+  err_t r;
+  httpc_state_t* req = (httpc_state_t*)arg;
+  LWIP_UNUSED_ARG(pcb);
+  LWIP_UNUSED_ARG(err);
+
+  /* send request; last char is zero termination */
+  r = altcp_write(req->pcb, req->request->payload, req->request->len - 1, TCP_WRITE_FLAG_COPY);
+  if (r != ERR_OK) {
+     /* could not write the single small request -> fail, don't retry */
+     return httpc_close(req, HTTPC_RESULT_ERR_MEM, 0, r);
+  }
+  /* everything written, we can free the request */
+  pbuf_free(req->request);
+  req->request = NULL;
+
+  altcp_output(req->pcb);
+  return ERR_OK;
+}
+
+/** Start the http request when the server IP addr is known */
+static err_t
+httpc_get_internal_addr(httpc_state_t* req, const ip_addr_t *ipaddr)
+{
+  err_t err;
+  LWIP_ASSERT("req != NULL", req != NULL);
+
+  if (&req->remote_addr != ipaddr) {
+    /* fill in remote addr if called externally */
+    req->remote_addr = *ipaddr;
+  }
+
+  err = altcp_connect(req->pcb, &req->remote_addr, req->remote_port, httpc_tcp_connected);
+  if (err == ERR_OK) {
+    return ERR_OK;
+  }
+  LWIP_DEBUGF(HTTPC_DEBUG_WARN_STATE, ("tcp_connect failed: %d\n", (int)err));
+  return err;
+}
+
+#if LWIP_DNS
+/** DNS callback
+ * If ipaddr is non-NULL, resolving succeeded and the request can be sent, otherwise it failed.
+ */
+static void
+httpc_dns_found(const char* hostname, const ip_addr_t *ipaddr, void *arg)
+{
+  httpc_state_t* req = (httpc_state_t*)arg;
+  err_t err;
+  httpc_result_t result;
+
+  LWIP_UNUSED_ARG(hostname);
+
+  if (ipaddr != NULL) {
+    err = httpc_get_internal_addr(req, ipaddr);
+    if (err == ERR_OK) {
+      return;
+    }
+    result = HTTPC_RESULT_ERR_CONNECT;
+  } else {
+    LWIP_DEBUGF(HTTPC_DEBUG_WARN_STATE, ("httpc_dns_found: failed to resolve hostname: %s\n",
+      hostname));
+    result = HTTPC_RESULT_ERR_HOSTNAME;
+    err = ERR_ARG;
+  }
+  httpc_close(req, result, 0, err);
+}
+#endif /* LWIP_DNS */
+
+/** Start the http request after converting 'server_name' to ip address (DNS or address string) */
+static err_t
+httpc_get_internal_dns(httpc_state_t* req, const char* server_name)
+{
+  err_t err;
+  LWIP_ASSERT("req != NULL", req != NULL);
+
+#if LWIP_DNS
+  err = dns_gethostbyname(server_name, &req->remote_addr, httpc_dns_found, req);
+#else
+  err = ipaddr_aton(server_name, &req->remote_addr) ? ERR_OK : ERR_ARG;
+#endif
+
+  if (err == ERR_OK) {
+    /* cached or IP-string */
+    err = httpc_get_internal_addr(req, &req->remote_addr);
+  } else if (err == ERR_INPROGRESS) {
+    return ERR_OK;
+  }
+  return err;
+}
+
+static int
+httpc_create_request_string(const httpc_connection_t *settings, const char* server_name, int server_port, const char* uri,
+                            int use_host, char *buffer, size_t buffer_size)
+{
+  if (settings->use_proxy) {
+    LWIP_ASSERT("server_name != NULL", server_name != NULL);
+    if (server_port != HTTP_DEFAULT_PORT) {
+      return snprintf(buffer, buffer_size, HTTPC_REQ_11_PROXY_PORT_FORMAT(server_name, server_port, uri, server_name));
+    } else {
+      return snprintf(buffer, buffer_size, HTTPC_REQ_11_PROXY_FORMAT(server_name, uri, server_name));
+    }
+  } else if (use_host) {
+    LWIP_ASSERT("server_name != NULL", server_name != NULL);
+    return snprintf(buffer, buffer_size, HTTPC_REQ_11_HOST_FORMAT(uri, server_name));
+  } else {
+    return snprintf(buffer, buffer_size, HTTPC_REQ_11_FORMAT(uri));
+  }
+}
+
+/** Initialize the connection struct */
+static err_t
+httpc_init_connection_common(httpc_state_t **connection, const httpc_connection_t *settings, const char* server_name,
+                      u16_t server_port, const char* uri, altcp_recv_fn recv_fn, void* callback_arg, int use_host)
+{
+  size_t alloc_len;
+  mem_size_t mem_alloc_len;
+  int req_len, req_len2;
+  httpc_state_t *req;
+#if HTTPC_DEBUG_REQUEST
+  size_t server_name_len, uri_len;
+#endif
+
+  LWIP_ASSERT("uri != NULL", uri != NULL);
+
+  /* get request len */
+  req_len = httpc_create_request_string(settings, server_name, server_port, uri, use_host, NULL, 0);
+  if ((req_len < 0) || (req_len > 0xFFFF)) {
+    return ERR_VAL;
+  }
+  /* alloc state and request in one block */
+  alloc_len = sizeof(httpc_state_t);
+#if HTTPC_DEBUG_REQUEST
+  server_name_len = server_name ? strlen(server_name) : 0;
+  uri_len = strlen(uri);
+  alloc_len += server_name_len + 1 + uri_len + 1;
+#endif
+  mem_alloc_len = (mem_size_t)alloc_len;
+  if ((mem_alloc_len < alloc_len) || (req_len + 1 > 0xFFFF)) {
+    return ERR_VAL;
+  }
+
+  req = (httpc_state_t*)mem_malloc((mem_size_t)alloc_len);
+  if(req == NULL) {
+    return ERR_MEM;
+  }
+  memset(req, 0, sizeof(httpc_state_t));
+  req->timeout_ticks = HTTPC_POLL_TIMEOUT;
+  req->request = pbuf_alloc(PBUF_RAW, (u16_t)(req_len + 1), PBUF_RAM);
+  if (req->request == NULL) {
+    httpc_free_state(req);
+    return ERR_MEM;
+  }
+  if (req->request->next != NULL) {
+    /* need a pbuf in one piece */
+    httpc_free_state(req);
+    return ERR_MEM;
+  }
+  req->hdr_content_len = HTTPC_CONTENT_LEN_INVALID;
+#if HTTPC_DEBUG_REQUEST
+  req->server_name = (char*)(req + 1);
+  if (server_name) {
+    memcpy(req->server_name, server_name, server_name_len + 1);
+  }
+  req->uri = req->server_name + server_name_len + 1;
+  memcpy(req->uri, uri, uri_len + 1);
+#endif
+  req->pcb = altcp_new(settings->altcp_allocator);
+  if(req->pcb == NULL) {
+    httpc_free_state(req);
+    return ERR_MEM;
+  }
+  req->remote_port = settings->use_proxy ? settings->proxy_port : server_port;
+  altcp_arg(req->pcb, req);
+  altcp_recv(req->pcb, httpc_tcp_recv);
+  altcp_err(req->pcb, httpc_tcp_err);
+  altcp_poll(req->pcb, httpc_tcp_poll, HTTPC_POLL_INTERVAL);
+  altcp_sent(req->pcb, httpc_tcp_sent);
+
+  /* set up request buffer */
+  req_len2 = httpc_create_request_string(settings, server_name, server_port, uri, use_host,
+    (char *)req->request->payload, req_len + 1);
+  if (req_len2 != req_len) {
+    httpc_free_state(req);
+    return ERR_VAL;
+  }
+
+  req->recv_fn = recv_fn;
+  req->conn_settings = settings;
+  req->callback_arg = callback_arg;
+
+  *connection = req;
+  return ERR_OK;
+}
+
+/**
+ * Initialize the connection struct
+ */
+static err_t
+httpc_init_connection(httpc_state_t **connection, const httpc_connection_t *settings, const char* server_name,
+                      u16_t server_port, const char* uri, altcp_recv_fn recv_fn, void* callback_arg)
+{
+  return httpc_init_connection_common(connection, settings, server_name, server_port, uri, recv_fn, callback_arg, 1);
+}
+
+
+/**
+ * Initialize the connection struct (from IP address)
+ */
+static err_t
+httpc_init_connection_addr(httpc_state_t **connection, const httpc_connection_t *settings,
+                           const ip_addr_t* server_addr, u16_t server_port, const char* uri,
+                           altcp_recv_fn recv_fn, void* callback_arg)
+{
+  char *server_addr_str = ipaddr_ntoa(server_addr);
+  if (server_addr_str == NULL) {
+    return ERR_VAL;
+  }
+  return httpc_init_connection_common(connection, settings, server_addr_str, server_port, uri,
+    recv_fn, callback_arg, 1);
+}
+
+/**
+ * @ingroup httpc 
+ * HTTP client API: get a file by passing server IP address
+ *
+ * @param server_addr IP address of the server to connect
+ * @param port tcp port of the server
+ * @param uri uri to get from the server, remember leading "/"!
+ * @param settings connection settings (callbacks, proxy, etc.)
+ * @param recv_fn the http body (not the headers) are passed to this callback
+ * @param callback_arg argument passed to all the callbacks
+ * @param connection retreives the connection handle (to match in callbacks)
+ * @return ERR_OK if starting the request succeeds (callback_fn will be called later)
+ *         or an error code
+ */
+err_t
+httpc_get_file(const ip_addr_t* server_addr, u16_t port, const char* uri, const httpc_connection_t *settings,
+               altcp_recv_fn recv_fn, void* callback_arg, httpc_state_t **connection)
+{
+  err_t err;
+  httpc_state_t* req;
+
+  LWIP_ERROR("invalid parameters", (server_addr != NULL) && (uri != NULL) && (recv_fn != NULL), return ERR_ARG;);
+
+  err = httpc_init_connection_addr(&req, settings, server_addr, port,
+    uri, recv_fn, callback_arg);
+  if (err != ERR_OK) {
+    return err;
+  }
+
+  if (settings->use_proxy) {
+    err = httpc_get_internal_addr(req, &settings->proxy_addr);
+  } else {
+    err = httpc_get_internal_addr(req, server_addr);
+  }
+  if(err != ERR_OK) {
+    httpc_free_state(req);
+    return err;
+  }
+
+  if (connection != NULL) {
+    *connection = req;
+  }
+  return ERR_OK;
+}
+
+/**
+ * @ingroup httpc 
+ * HTTP client API: get a file by passing server name as string (DNS name or IP address string)
+ *
+ * @param server_name server name as string (DNS name or IP address string)
+ * @param port tcp port of the server
+ * @param uri uri to get from the server, remember leading "/"!
+ * @param settings connection settings (callbacks, proxy, etc.)
+ * @param recv_fn the http body (not the headers) are passed to this callback
+ * @param callback_arg argument passed to all the callbacks
+ * @param connection retreives the connection handle (to match in callbacks)
+ * @return ERR_OK if starting the request succeeds (callback_fn will be called later)
+ *         or an error code
+ */
+err_t
+httpc_get_file_dns(const char* server_name, u16_t port, const char* uri, const httpc_connection_t *settings,
+                   altcp_recv_fn recv_fn, void* callback_arg, httpc_state_t **connection)
+{
+  err_t err;
+  httpc_state_t* req;
+
+  LWIP_ERROR("invalid parameters", (server_name != NULL) && (uri != NULL) && (recv_fn != NULL), return ERR_ARG;);
+
+  err = httpc_init_connection(&req, settings, server_name, port, uri, recv_fn, callback_arg);
+  if (err != ERR_OK) {
+    return err;
+  }
+
+  if (settings->use_proxy) {
+    err = httpc_get_internal_addr(req, &settings->proxy_addr);
+  } else {
+    err = httpc_get_internal_dns(req, server_name);
+  }
+  if(err != ERR_OK) {
+    httpc_free_state(req);
+    return err;
+  }
+
+  if (connection != NULL) {
+    *connection = req;
+  }
+  return ERR_OK;
+}
+
+#if LWIP_HTTPC_HAVE_FILE_IO
+/* Implementation to disk via fopen/fwrite/fclose follows */
+
+typedef struct _httpc_filestate
+{
+  const char* local_file_name;
+  FILE *file;
+  httpc_connection_t settings;
+  const httpc_connection_t *client_settings;
+  void *callback_arg;
+} httpc_filestate_t;
+
+static void httpc_fs_result(void *arg, httpc_result_t httpc_result, u32_t rx_content_len,
+  u32_t srv_res, err_t err);
+
+/** Initalize http client state for download to file system */
+static err_t
+httpc_fs_init(httpc_filestate_t **filestate_out, const char* local_file_name,
+              const httpc_connection_t *settings, void* callback_arg)
+{
+  httpc_filestate_t *filestate;
+  size_t file_len, alloc_len;
+  FILE *f;
+
+  file_len = strlen(local_file_name);
+  alloc_len = sizeof(httpc_filestate_t) + file_len + 1;
+
+  filestate = (httpc_filestate_t *)mem_malloc((mem_size_t)alloc_len);
+  if (filestate == NULL) {
+    return ERR_MEM;
+  }
+  memset(filestate, 0, sizeof(httpc_filestate_t));
+  filestate->local_file_name = (const char *)(filestate + 1);
+  memcpy((char *)(filestate + 1), local_file_name, file_len + 1);
+  filestate->file = NULL;
+  filestate->client_settings = settings;
+  filestate->callback_arg = callback_arg;
+  /* copy client settings but override result callback */
+  memcpy(&filestate->settings, settings, sizeof(httpc_connection_t));
+  filestate->settings.result_fn = httpc_fs_result;
+
+  f = fopen(local_file_name, "wb");
+  if(f == NULL) {
+    /* could not open file */
+    mem_free(filestate);
+    return ERR_VAL;
+  }
+  filestate->file = f;
+  *filestate_out = filestate;
+  return ERR_OK;
+}
+
+/** Free http client state for download to file system */
+static void
+httpc_fs_free(httpc_filestate_t *filestate)
+{
+  if (filestate != NULL) {
+    if (filestate->file != NULL) {
+      fclose(filestate->file);
+      filestate->file = NULL;
+    }
+    mem_free(filestate);
+  }
+}
+
+/** Connection closed (success or error) */
+static void
+httpc_fs_result(void *arg, httpc_result_t httpc_result, u32_t rx_content_len,
+                u32_t srv_res, err_t err)
+{
+  httpc_filestate_t *filestate = (httpc_filestate_t *)arg;
+  if (filestate != NULL) {
+    if (filestate->client_settings->result_fn != NULL) {
+      filestate->client_settings->result_fn(filestate->callback_arg, httpc_result, rx_content_len,
+        srv_res, err);
+    }
+    httpc_fs_free(filestate);
+  }
+}
+
+/** tcp recv callback */
+static err_t
+httpc_fs_tcp_recv(void *arg, struct altcp_pcb *pcb, struct pbuf *p, err_t err)
+{
+  httpc_filestate_t *filestate = (httpc_filestate_t*)arg;
+  struct pbuf* q;
+  LWIP_UNUSED_ARG(err);
+
+  LWIP_ASSERT("p != NULL", p != NULL);
+
+  for (q = p; q != NULL; q = q->next) {
+    fwrite(q->payload, 1, q->len, filestate->file);
+  }
+  altcp_recved(pcb, p->tot_len);
+  pbuf_free(p);
+  return ERR_OK;
+}
+
+/**
+ * @ingroup httpc 
+ * HTTP client API: get a file to disk by passing server IP address
+ *
+ * @param server_addr IP address of the server to connect
+ * @param port tcp port of the server
+ * @param uri uri to get from the server, remember leading "/"!
+ * @param settings connection settings (callbacks, proxy, etc.)
+ * @param callback_arg argument passed to all the callbacks
+ * @param connection retreives the connection handle (to match in callbacks)
+ * @return ERR_OK if starting the request succeeds (callback_fn will be called later)
+ *         or an error code
+ */
+err_t
+httpc_get_file_to_disk(const ip_addr_t* server_addr, u16_t port, const char* uri, const httpc_connection_t *settings,
+                       void* callback_arg, const char* local_file_name, httpc_state_t **connection)
+{
+  err_t err;
+  httpc_state_t* req;
+  httpc_filestate_t *filestate;
+
+  LWIP_ERROR("invalid parameters", (server_addr != NULL) && (uri != NULL) && (local_file_name != NULL), return ERR_ARG;);
+
+  err = httpc_fs_init(&filestate, local_file_name, settings, callback_arg);
+  if (err != ERR_OK) {
+    return err;
+  }
+
+  err = httpc_init_connection_addr(&req, &filestate->settings, server_addr, port,
+    uri, httpc_fs_tcp_recv, filestate);
+  if (err != ERR_OK) {
+    httpc_fs_free(filestate);
+    return err;
+  }
+
+  if (settings->use_proxy) {
+    err = httpc_get_internal_addr(req, &settings->proxy_addr);
+  } else {
+    err = httpc_get_internal_addr(req, server_addr);
+  }
+  if(err != ERR_OK) {
+    httpc_fs_free(filestate);
+    httpc_free_state(req);
+    return err;
+  }
+
+  if (connection != NULL) {
+    *connection = req;
+  }
+  return ERR_OK;
+}
+
+/**
+ * @ingroup httpc 
+ * HTTP client API: get a file to disk by passing server name as string (DNS name or IP address string)
+ *
+ * @param server_name server name as string (DNS name or IP address string)
+ * @param port tcp port of the server
+ * @param uri uri to get from the server, remember leading "/"!
+ * @param settings connection settings (callbacks, proxy, etc.)
+ * @param callback_arg argument passed to all the callbacks
+ * @param connection retreives the connection handle (to match in callbacks)
+ * @return ERR_OK if starting the request succeeds (callback_fn will be called later)
+ *         or an error code
+ */
+err_t
+httpc_get_file_dns_to_disk(const char* server_name, u16_t port, const char* uri, const httpc_connection_t *settings,
+                           void* callback_arg, const char* local_file_name, httpc_state_t **connection)
+{
+  err_t err;
+  httpc_state_t* req;
+  httpc_filestate_t *filestate;
+
+  LWIP_ERROR("invalid parameters", (server_name != NULL) && (uri != NULL) && (local_file_name != NULL), return ERR_ARG;);
+
+  err = httpc_fs_init(&filestate, local_file_name, settings, callback_arg);
+  if (err != ERR_OK) {
+    return err;
+  }
+
+  err = httpc_init_connection(&req, &filestate->settings, server_name, port,
+    uri, httpc_fs_tcp_recv, filestate);
+  if (err != ERR_OK) {
+    httpc_fs_free(filestate);
+    return err;
+  }
+
+  if (settings->use_proxy) {
+    err = httpc_get_internal_addr(req, &settings->proxy_addr);
+  } else {
+    err = httpc_get_internal_dns(req, server_name);
+  }
+  if(err != ERR_OK) {
+    httpc_fs_free(filestate);
+    httpc_free_state(req);
+    return err;
+  }
+
+  if (connection != NULL) {
+    *connection = req;
+  }
+  return ERR_OK;
+}
+#endif /* LWIP_HTTPC_HAVE_FILE_IO */
+
+#endif /* LWIP_TCP && LWIP_CALLBACK_API */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/apps/http/httpd.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/apps/http/httpd.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/apps/http/httpd.c	(revision 457)
@@ -0,0 +1,2746 @@
+/**
+ * @file
+ * LWIP HTTP server implementation
+ */
+
+/*
+ * Copyright (c) 2001-2003 Swedish Institute of Computer Science.
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Adam Dunkels <adam@sics.se>
+ *         Simon Goldschmidt
+ *
+ */
+
+/**
+ * @defgroup httpd HTTP server
+ * @ingroup apps
+ *
+ * This httpd supports for a
+ * rudimentary server-side-include facility which will replace tags of the form
+ * <!--#tag--> in any file whose extension is .shtml, .shtm or .ssi with
+ * strings provided by an include handler whose pointer is provided to the
+ * module via function http_set_ssi_handler().
+ * Additionally, a simple common
+ * gateway interface (CGI) handling mechanism has been added to allow clients
+ * to hook functions to particular request URIs.
+ *
+ * To enable SSI support, define label LWIP_HTTPD_SSI in lwipopts.h.
+ * To enable CGI support, define label LWIP_HTTPD_CGI in lwipopts.h.
+ *
+ * By default, the server assumes that HTTP headers are already present in
+ * each file stored in the file system.  By defining LWIP_HTTPD_DYNAMIC_HEADERS in
+ * lwipopts.h, this behavior can be changed such that the server inserts the
+ * headers automatically based on the extension of the file being served.  If
+ * this mode is used, be careful to ensure that the file system image used
+ * does not already contain the header information.
+ *
+ * File system images without headers can be created using the makefsfile
+ * tool with the -h command line option.
+ *
+ *
+ * Notes about valid SSI tags
+ * --------------------------
+ *
+ * The following assumptions are made about tags used in SSI markers:
+ *
+ * 1. No tag may contain '-' or whitespace characters within the tag name.
+ * 2. Whitespace is allowed between the tag leadin "<!--#" and the start of
+ *    the tag name and between the tag name and the leadout string "-->".
+ * 3. The maximum tag name length is LWIP_HTTPD_MAX_TAG_NAME_LEN, currently 8 characters.
+ *
+ * Notes on CGI usage
+ * ------------------
+ *
+ * The simple CGI support offered here works with GET method requests only
+ * and can handle up to 16 parameters encoded into the URI. The handler
+ * function may not write directly to the HTTP output but must return a
+ * filename that the HTTP server will send to the browser as a response to
+ * the incoming CGI request.
+ *
+ *
+ *
+ * The list of supported file types is quite short, so if makefsdata complains
+ * about an unknown extension, make sure to add it (and its doctype) to
+ * the 'g_psHTTPHeaders' list.
+ */
+#include "lwip/init.h"
+#include "lwip/apps/httpd.h"
+#include "lwip/debug.h"
+#include "lwip/stats.h"
+#include "lwip/apps/fs.h"
+#include "httpd_structs.h"
+#include "lwip/def.h"
+
+#include "lwip/altcp.h"
+#include "lwip/altcp_tcp.h"
+#if HTTPD_ENABLE_HTTPS
+#include "lwip/altcp_tls.h"
+#endif
+#ifdef LWIP_HOOK_FILENAME
+#include LWIP_HOOK_FILENAME
+#endif
+#if LWIP_HTTPD_TIMING
+#include "lwip/sys.h"
+#endif /* LWIP_HTTPD_TIMING */
+
+#include <string.h> /* memset */
+#include <stdlib.h> /* atoi */
+#include <stdio.h>
+
+#if LWIP_TCP && LWIP_CALLBACK_API
+
+/** Minimum length for a valid HTTP/0.9 request: "GET /\r\n" -> 7 bytes */
+#define MIN_REQ_LEN   7
+
+#define CRLF "\r\n"
+#if LWIP_HTTPD_SUPPORT_11_KEEPALIVE
+#define HTTP11_CONNECTIONKEEPALIVE  "Connection: keep-alive"
+#define HTTP11_CONNECTIONKEEPALIVE2 "Connection: Keep-Alive"
+#endif
+
+#if LWIP_HTTPD_DYNAMIC_FILE_READ
+#define HTTP_IS_DYNAMIC_FILE(hs) ((hs)->buf != NULL)
+#else
+#define HTTP_IS_DYNAMIC_FILE(hs) 0
+#endif
+
+/* This defines checks whether tcp_write has to copy data or not */
+
+#ifndef HTTP_IS_DATA_VOLATILE
+/** tcp_write does not have to copy data when sent from rom-file-system directly */
+#define HTTP_IS_DATA_VOLATILE(hs)       (HTTP_IS_DYNAMIC_FILE(hs) ? TCP_WRITE_FLAG_COPY : 0)
+#endif
+/** Default: dynamic headers are sent from ROM (non-dynamic headers are handled like file data) */
+#ifndef HTTP_IS_HDR_VOLATILE
+#define HTTP_IS_HDR_VOLATILE(hs, ptr)   0
+#endif
+
+/* Return values for http_send_*() */
+#define HTTP_DATA_TO_SEND_FREED    3
+#define HTTP_DATA_TO_SEND_BREAK    2
+#define HTTP_DATA_TO_SEND_CONTINUE 1
+#define HTTP_NO_DATA_TO_SEND       0
+
+typedef struct {
+  const char *name;
+  u8_t shtml;
+} default_filename;
+
+static const default_filename httpd_default_filenames[] = {
+  {"/index.shtml", 1 },
+  {"/index.ssi",   1 },
+  {"/index.shtm",  1 },
+  {"/index.html",  0 },
+  {"/index.htm",   0 }
+};
+
+#define NUM_DEFAULT_FILENAMES LWIP_ARRAYSIZE(httpd_default_filenames)
+
+#if LWIP_HTTPD_SUPPORT_REQUESTLIST
+/** HTTP request is copied here from pbufs for simple parsing */
+static char httpd_req_buf[LWIP_HTTPD_MAX_REQ_LENGTH + 1];
+#endif /* LWIP_HTTPD_SUPPORT_REQUESTLIST */
+
+#if LWIP_HTTPD_SUPPORT_POST
+#if LWIP_HTTPD_POST_MAX_RESPONSE_URI_LEN > LWIP_HTTPD_MAX_REQUEST_URI_LEN
+#define LWIP_HTTPD_URI_BUF_LEN LWIP_HTTPD_POST_MAX_RESPONSE_URI_LEN
+#endif
+#endif
+#ifndef LWIP_HTTPD_URI_BUF_LEN
+#define LWIP_HTTPD_URI_BUF_LEN LWIP_HTTPD_MAX_REQUEST_URI_LEN
+#endif
+#if LWIP_HTTPD_URI_BUF_LEN
+/* Filename for response file to send when POST is finished or
+ * search for default files when a directory is requested. */
+static char http_uri_buf[LWIP_HTTPD_URI_BUF_LEN + 1];
+#endif
+
+#if LWIP_HTTPD_DYNAMIC_HEADERS
+/* The number of individual strings that comprise the headers sent before each
+ * requested file.
+ */
+#define NUM_FILE_HDR_STRINGS 5
+#define HDR_STRINGS_IDX_HTTP_STATUS           0 /* e.g. "HTTP/1.0 200 OK\r\n" */
+#define HDR_STRINGS_IDX_SERVER_NAME           1 /* e.g. "Server: "HTTPD_SERVER_AGENT"\r\n" */
+#define HDR_STRINGS_IDX_CONTENT_LEN_KEEPALIVE 2 /* e.g. "Content-Length: xy\r\n" and/or "Connection: keep-alive\r\n" */
+#define HDR_STRINGS_IDX_CONTENT_LEN_NR        3 /* the byte count, when content-length is used */
+#define HDR_STRINGS_IDX_CONTENT_TYPE          4 /* the content type (or default answer content type including default document) */
+
+/* The dynamically generated Content-Length buffer needs space for CRLF + NULL */
+#define LWIP_HTTPD_MAX_CONTENT_LEN_OFFSET 3
+#ifndef LWIP_HTTPD_MAX_CONTENT_LEN_SIZE
+/* The dynamically generated Content-Length buffer shall be able to work with
+   ~953 MB (9 digits) */
+#define LWIP_HTTPD_MAX_CONTENT_LEN_SIZE   (9 + LWIP_HTTPD_MAX_CONTENT_LEN_OFFSET)
+#endif
+#endif /* LWIP_HTTPD_DYNAMIC_HEADERS */
+
+#if LWIP_HTTPD_SSI
+
+#define HTTPD_LAST_TAG_PART 0xFFFF
+
+enum tag_check_state {
+  TAG_NONE,       /* Not processing an SSI tag */
+  TAG_LEADIN,     /* Tag lead in "<!--#" being processed */
+  TAG_FOUND,      /* Tag name being read, looking for lead-out start */
+  TAG_LEADOUT,    /* Tag lead out "-->" being processed */
+  TAG_SENDING     /* Sending tag replacement string */
+};
+
+struct http_ssi_state {
+  const char *parsed;     /* Pointer to the first unparsed byte in buf. */
+#if !LWIP_HTTPD_SSI_INCLUDE_TAG
+  const char *tag_started;/* Pointer to the first opening '<' of the tag. */
+#endif /* !LWIP_HTTPD_SSI_INCLUDE_TAG */
+  const char *tag_end;    /* Pointer to char after the closing '>' of the tag. */
+  u32_t parse_left; /* Number of unparsed bytes in buf. */
+  u16_t tag_index;   /* Counter used by tag parsing state machine */
+  u16_t tag_insert_len; /* Length of insert in string tag_insert */
+#if LWIP_HTTPD_SSI_MULTIPART
+  u16_t tag_part; /* Counter passed to and changed by tag insertion function to insert multiple times */
+#endif /* LWIP_HTTPD_SSI_MULTIPART */
+  u8_t tag_type; /* index into http_ssi_tag_desc array */
+  u8_t tag_name_len; /* Length of the tag name in string tag_name */
+  char tag_name[LWIP_HTTPD_MAX_TAG_NAME_LEN + 1]; /* Last tag name extracted */
+  char tag_insert[LWIP_HTTPD_MAX_TAG_INSERT_LEN + 1]; /* Insert string for tag_name */
+  enum tag_check_state tag_state; /* State of the tag processor */
+};
+
+struct http_ssi_tag_description {
+  const char *lead_in;
+  const char *lead_out; 
+};
+
+#endif /* LWIP_HTTPD_SSI */
+
+struct http_state {
+#if LWIP_HTTPD_KILL_OLD_ON_CONNECTIONS_EXCEEDED
+  struct http_state *next;
+#endif /* LWIP_HTTPD_KILL_OLD_ON_CONNECTIONS_EXCEEDED */
+  struct fs_file file_handle;
+  struct fs_file *handle;
+  const char *file;       /* Pointer to first unsent byte in buf. */
+
+  struct altcp_pcb *pcb;
+#if LWIP_HTTPD_SUPPORT_REQUESTLIST
+  struct pbuf *req;
+#endif /* LWIP_HTTPD_SUPPORT_REQUESTLIST */
+
+#if LWIP_HTTPD_DYNAMIC_FILE_READ
+  char *buf;        /* File read buffer. */
+  int buf_len;      /* Size of file read buffer, buf. */
+#endif /* LWIP_HTTPD_DYNAMIC_FILE_READ */
+  u32_t left;       /* Number of unsent bytes in buf. */
+  u8_t retries;
+#if LWIP_HTTPD_SUPPORT_11_KEEPALIVE
+  u8_t keepalive;
+#endif /* LWIP_HTTPD_SUPPORT_11_KEEPALIVE */
+#if LWIP_HTTPD_SSI
+  struct http_ssi_state *ssi;
+#endif /* LWIP_HTTPD_SSI */
+#if LWIP_HTTPD_CGI
+  char *params[LWIP_HTTPD_MAX_CGI_PARAMETERS]; /* Params extracted from the request URI */
+  char *param_vals[LWIP_HTTPD_MAX_CGI_PARAMETERS]; /* Values for each extracted param */
+#endif /* LWIP_HTTPD_CGI */
+#if LWIP_HTTPD_DYNAMIC_HEADERS
+  const char *hdrs[NUM_FILE_HDR_STRINGS]; /* HTTP headers to be sent. */
+  char hdr_content_len[LWIP_HTTPD_MAX_CONTENT_LEN_SIZE];
+  u16_t hdr_pos;     /* The position of the first unsent header byte in the
+                        current string */
+  u16_t hdr_index;   /* The index of the hdr string currently being sent. */
+#endif /* LWIP_HTTPD_DYNAMIC_HEADERS */
+#if LWIP_HTTPD_TIMING
+  u32_t time_started;
+#endif /* LWIP_HTTPD_TIMING */
+#if LWIP_HTTPD_SUPPORT_POST
+  u32_t post_content_len_left;
+#if LWIP_HTTPD_POST_MANUAL_WND
+  u32_t unrecved_bytes;
+  u8_t no_auto_wnd;
+  u8_t post_finished;
+#endif /* LWIP_HTTPD_POST_MANUAL_WND */
+#endif /* LWIP_HTTPD_SUPPORT_POST*/
+};
+
+#if HTTPD_USE_MEM_POOL
+LWIP_MEMPOOL_DECLARE(HTTPD_STATE,     MEMP_NUM_PARALLEL_HTTPD_CONNS,     sizeof(struct http_state),     "HTTPD_STATE")
+#if LWIP_HTTPD_SSI
+LWIP_MEMPOOL_DECLARE(HTTPD_SSI_STATE, MEMP_NUM_PARALLEL_HTTPD_SSI_CONNS, sizeof(struct http_ssi_state), "HTTPD_SSI_STATE")
+#define HTTP_FREE_SSI_STATE(x)  LWIP_MEMPOOL_FREE(HTTPD_SSI_STATE, (x))
+#define HTTP_ALLOC_SSI_STATE()  (struct http_ssi_state *)LWIP_MEMPOOL_ALLOC(HTTPD_SSI_STATE)
+#endif /* LWIP_HTTPD_SSI */
+#define HTTP_ALLOC_HTTP_STATE() (struct http_state *)LWIP_MEMPOOL_ALLOC(HTTPD_STATE)
+#define HTTP_FREE_HTTP_STATE(x) LWIP_MEMPOOL_FREE(HTTPD_STATE, (x))
+#else /* HTTPD_USE_MEM_POOL */
+#define HTTP_ALLOC_HTTP_STATE() (struct http_state *)mem_malloc(sizeof(struct http_state))
+#define HTTP_FREE_HTTP_STATE(x) mem_free(x)
+#if LWIP_HTTPD_SSI
+#define HTTP_ALLOC_SSI_STATE()  (struct http_ssi_state *)mem_malloc(sizeof(struct http_ssi_state))
+#define HTTP_FREE_SSI_STATE(x)  mem_free(x)
+#endif /* LWIP_HTTPD_SSI */
+#endif /* HTTPD_USE_MEM_POOL */
+
+static err_t http_close_conn(struct altcp_pcb *pcb, struct http_state *hs);
+static err_t http_close_or_abort_conn(struct altcp_pcb *pcb, struct http_state *hs, u8_t abort_conn);
+static err_t http_find_file(struct http_state *hs, const char *uri, int is_09);
+static err_t http_init_file(struct http_state *hs, struct fs_file *file, int is_09, const char *uri, u8_t tag_check, char *params);
+static err_t http_poll(void *arg, struct altcp_pcb *pcb);
+static u8_t http_check_eof(struct altcp_pcb *pcb, struct http_state *hs);
+#if LWIP_HTTPD_FS_ASYNC_READ
+static void http_continue(void *connection);
+#endif /* LWIP_HTTPD_FS_ASYNC_READ */
+
+#if LWIP_HTTPD_SSI
+/* SSI insert handler function pointer. */
+static tSSIHandler httpd_ssi_handler;
+#if !LWIP_HTTPD_SSI_RAW
+static int httpd_num_tags;
+static const char **httpd_tags;
+#endif /* !LWIP_HTTPD_SSI_RAW */
+
+/* Define the available tag lead-ins and corresponding lead-outs.
+ * ATTENTION: for the algorithm below using this array, it is essential
+ * that the lead in differs in the first character! */
+const struct http_ssi_tag_description http_ssi_tag_desc[] = {
+  {"<!--#", "-->"},
+  {"/*#", "*/"}
+};
+
+#endif /* LWIP_HTTPD_SSI */
+
+#if LWIP_HTTPD_CGI
+/* CGI handler information */
+static const tCGI *httpd_cgis;
+static int httpd_num_cgis;
+static int http_cgi_paramcount;
+#define http_cgi_params     hs->params
+#define http_cgi_param_vals hs->param_vals
+#elif LWIP_HTTPD_CGI_SSI
+static char *http_cgi_params[LWIP_HTTPD_MAX_CGI_PARAMETERS]; /* Params extracted from the request URI */
+static char *http_cgi_param_vals[LWIP_HTTPD_MAX_CGI_PARAMETERS]; /* Values for each extracted param */
+#endif /* LWIP_HTTPD_CGI */
+
+#if LWIP_HTTPD_KILL_OLD_ON_CONNECTIONS_EXCEEDED
+/** global list of active HTTP connections, use to kill the oldest when
+    running out of memory */
+static struct http_state *http_connections;
+
+static void
+http_add_connection(struct http_state *hs)
+{
+  /* add the connection to the list */
+  hs->next = http_connections;
+  http_connections = hs;
+}
+
+static void
+http_remove_connection(struct http_state *hs)
+{
+  /* take the connection off the list */
+  if (http_connections) {
+    if (http_connections == hs) {
+      http_connections = hs->next;
+    } else {
+      struct http_state *last;
+      for (last = http_connections; last->next != NULL; last = last->next) {
+        if (last->next == hs) {
+          last->next = hs->next;
+          break;
+        }
+      }
+    }
+  }
+}
+
+static void
+http_kill_oldest_connection(u8_t ssi_required)
+{
+  struct http_state *hs = http_connections;
+  struct http_state *hs_free_next = NULL;
+  while (hs && hs->next) {
+#if LWIP_HTTPD_SSI
+    if (ssi_required) {
+      if (hs->next->ssi != NULL) {
+        hs_free_next = hs;
+      }
+    } else
+#else /* LWIP_HTTPD_SSI */
+    LWIP_UNUSED_ARG(ssi_required);
+#endif /* LWIP_HTTPD_SSI */
+    {
+      hs_free_next = hs;
+    }
+    LWIP_ASSERT("broken list", hs != hs->next);
+    hs = hs->next;
+  }
+  if (hs_free_next != NULL) {
+    LWIP_ASSERT("hs_free_next->next != NULL", hs_free_next->next != NULL);
+    LWIP_ASSERT("hs_free_next->next->pcb != NULL", hs_free_next->next->pcb != NULL);
+    /* send RST when killing a connection because of memory shortage */
+    http_close_or_abort_conn(hs_free_next->next->pcb, hs_free_next->next, 1); /* this also unlinks the http_state from the list */
+  }
+}
+#else /* LWIP_HTTPD_KILL_OLD_ON_CONNECTIONS_EXCEEDED */
+
+#define http_add_connection(hs)
+#define http_remove_connection(hs)
+
+#endif /* LWIP_HTTPD_KILL_OLD_ON_CONNECTIONS_EXCEEDED */
+
+#if LWIP_HTTPD_SSI
+/** Allocate as struct http_ssi_state. */
+static struct http_ssi_state *
+http_ssi_state_alloc(void)
+{
+  struct http_ssi_state *ret = HTTP_ALLOC_SSI_STATE();
+#if LWIP_HTTPD_KILL_OLD_ON_CONNECTIONS_EXCEEDED
+  if (ret == NULL) {
+    http_kill_oldest_connection(1);
+    ret = HTTP_ALLOC_SSI_STATE();
+  }
+#endif /* LWIP_HTTPD_KILL_OLD_ON_CONNECTIONS_EXCEEDED */
+  if (ret != NULL) {
+    memset(ret, 0, sizeof(struct http_ssi_state));
+  }
+  return ret;
+}
+
+/** Free a struct http_ssi_state. */
+static void
+http_ssi_state_free(struct http_ssi_state *ssi)
+{
+  if (ssi != NULL) {
+    HTTP_FREE_SSI_STATE(ssi);
+  }
+}
+#endif /* LWIP_HTTPD_SSI */
+
+/** Initialize a struct http_state.
+ */
+static void
+http_state_init(struct http_state *hs)
+{
+  /* Initialize the structure. */
+  memset(hs, 0, sizeof(struct http_state));
+#if LWIP_HTTPD_DYNAMIC_HEADERS
+  /* Indicate that the headers are not yet valid */
+  hs->hdr_index = NUM_FILE_HDR_STRINGS;
+#endif /* LWIP_HTTPD_DYNAMIC_HEADERS */
+}
+
+/** Allocate a struct http_state. */
+static struct http_state *
+http_state_alloc(void)
+{
+  struct http_state *ret = HTTP_ALLOC_HTTP_STATE();
+#if LWIP_HTTPD_KILL_OLD_ON_CONNECTIONS_EXCEEDED
+  if (ret == NULL) {
+    http_kill_oldest_connection(0);
+    ret = HTTP_ALLOC_HTTP_STATE();
+  }
+#endif /* LWIP_HTTPD_KILL_OLD_ON_CONNECTIONS_EXCEEDED */
+  if (ret != NULL) {
+    http_state_init(ret);
+    http_add_connection(ret);
+  }
+  return ret;
+}
+
+/** Free a struct http_state.
+ * Also frees the file data if dynamic.
+ */
+static void
+http_state_eof(struct http_state *hs)
+{
+  if (hs->handle) {
+#if LWIP_HTTPD_TIMING
+    u32_t ms_needed = sys_now() - hs->time_started;
+    u32_t needed = LWIP_MAX(1, (ms_needed / 100));
+    LWIP_DEBUGF(HTTPD_DEBUG_TIMING, ("httpd: needed %"U32_F" ms to send file of %d bytes -> %"U32_F" bytes/sec\n",
+                                     ms_needed, hs->handle->len, ((((u32_t)hs->handle->len) * 10) / needed)));
+#endif /* LWIP_HTTPD_TIMING */
+    fs_close(hs->handle);
+    hs->handle = NULL;
+  }
+#if LWIP_HTTPD_DYNAMIC_FILE_READ
+  if (hs->buf != NULL) {
+    mem_free(hs->buf);
+    hs->buf = NULL;
+  }
+#endif /* LWIP_HTTPD_DYNAMIC_FILE_READ */
+#if LWIP_HTTPD_SSI
+  if (hs->ssi) {
+    http_ssi_state_free(hs->ssi);
+    hs->ssi = NULL;
+  }
+#endif /* LWIP_HTTPD_SSI */
+#if LWIP_HTTPD_SUPPORT_REQUESTLIST
+  if (hs->req) {
+    pbuf_free(hs->req);
+    hs->req = NULL;
+  }
+#endif /* LWIP_HTTPD_SUPPORT_REQUESTLIST */
+}
+
+/** Free a struct http_state.
+ * Also frees the file data if dynamic.
+ */
+static void
+http_state_free(struct http_state *hs)
+{
+  if (hs != NULL) {
+    http_state_eof(hs);
+    http_remove_connection(hs);
+    HTTP_FREE_HTTP_STATE(hs);
+  }
+}
+
+/** Call tcp_write() in a loop trying smaller and smaller length
+ *
+ * @param pcb altcp_pcb to send
+ * @param ptr Data to send
+ * @param length Length of data to send (in/out: on return, contains the
+ *        amount of data sent)
+ * @param apiflags directly passed to tcp_write
+ * @return the return value of tcp_write
+ */
+static err_t
+http_write(struct altcp_pcb *pcb, const void *ptr, u16_t *length, u8_t apiflags)
+{
+  u16_t len, max_len;
+  err_t err;
+  LWIP_ASSERT("length != NULL", length != NULL);
+  len = *length;
+  if (len == 0) {
+    return ERR_OK;
+  }
+  /* We cannot send more data than space available in the send buffer. */
+  max_len = altcp_sndbuf(pcb);
+  if (max_len < len) {
+    len = max_len;
+  }
+#ifdef HTTPD_MAX_WRITE_LEN
+  /* Additional limitation: e.g. don't enqueue more than 2*mss at once */
+  max_len = HTTPD_MAX_WRITE_LEN(pcb);
+  if (len > max_len) {
+    len = max_len;
+  }
+#endif /* HTTPD_MAX_WRITE_LEN */
+  do {
+    LWIP_DEBUGF(HTTPD_DEBUG | LWIP_DBG_TRACE, ("Trying to send %d bytes\n", len));
+    err = altcp_write(pcb, ptr, len, apiflags);
+    if (err == ERR_MEM) {
+      if ((altcp_sndbuf(pcb) == 0) ||
+          (altcp_sndqueuelen(pcb) >= TCP_SND_QUEUELEN)) {
+        /* no need to try smaller sizes */
+        len = 1;
+      } else {
+        len /= 2;
+      }
+      LWIP_DEBUGF(HTTPD_DEBUG | LWIP_DBG_TRACE,
+                  ("Send failed, trying less (%d bytes)\n", len));
+    }
+  } while ((err == ERR_MEM) && (len > 1));
+
+  if (err == ERR_OK) {
+    LWIP_DEBUGF(HTTPD_DEBUG | LWIP_DBG_TRACE, ("Sent %d bytes\n", len));
+    *length = len;
+  } else {
+    LWIP_DEBUGF(HTTPD_DEBUG | LWIP_DBG_TRACE, ("Send failed with err %d (\"%s\")\n", err, lwip_strerr(err)));
+    *length = 0;
+  }
+
+#if LWIP_HTTPD_SUPPORT_11_KEEPALIVE
+  /* ensure nagle is normally enabled (only disabled for persistent connections
+     when all data has been enqueued but the connection stays open for the next
+     request */
+  altcp_nagle_enable(pcb);
+#endif
+
+  return err;
+}
+
+/**
+ * The connection shall be actively closed (using RST to close from fault states).
+ * Reset the sent- and recv-callbacks.
+ *
+ * @param pcb the tcp pcb to reset callbacks
+ * @param hs connection state to free
+ */
+static err_t
+http_close_or_abort_conn(struct altcp_pcb *pcb, struct http_state *hs, u8_t abort_conn)
+{
+  err_t err;
+  LWIP_DEBUGF(HTTPD_DEBUG, ("Closing connection %p\n", (void *)pcb));
+
+#if LWIP_HTTPD_SUPPORT_POST
+  if (hs != NULL) {
+    if ((hs->post_content_len_left != 0)
+#if LWIP_HTTPD_POST_MANUAL_WND
+        || ((hs->no_auto_wnd != 0) && (hs->unrecved_bytes != 0))
+#endif /* LWIP_HTTPD_POST_MANUAL_WND */
+       ) {
+      /* make sure the post code knows that the connection is closed */
+      http_uri_buf[0] = 0;
+      httpd_post_finished(hs, http_uri_buf, LWIP_HTTPD_URI_BUF_LEN);
+    }
+  }
+#endif /* LWIP_HTTPD_SUPPORT_POST*/
+
+
+  altcp_arg(pcb, NULL);
+  altcp_recv(pcb, NULL);
+  altcp_err(pcb, NULL);
+  altcp_poll(pcb, NULL, 0);
+  altcp_sent(pcb, NULL);
+  if (hs != NULL) {
+    http_state_free(hs);
+  }
+
+  if (abort_conn) {
+    altcp_abort(pcb);
+    return ERR_OK;
+  }
+  err = altcp_close(pcb);
+  if (err != ERR_OK) {
+    LWIP_DEBUGF(HTTPD_DEBUG, ("Error %d closing %p\n", err, (void *)pcb));
+    /* error closing, try again later in poll */
+    altcp_poll(pcb, http_poll, HTTPD_POLL_INTERVAL);
+  }
+  return err;
+}
+
+/**
+ * The connection shall be actively closed.
+ * Reset the sent- and recv-callbacks.
+ *
+ * @param pcb the tcp pcb to reset callbacks
+ * @param hs connection state to free
+ */
+static err_t
+http_close_conn(struct altcp_pcb *pcb, struct http_state *hs)
+{
+  return http_close_or_abort_conn(pcb, hs, 0);
+}
+
+/** End of file: either close the connection (Connection: close) or
+ * close the file (Connection: keep-alive)
+ */
+static void
+http_eof(struct altcp_pcb *pcb, struct http_state *hs)
+{
+  /* HTTP/1.1 persistent connection? (Not supported for SSI) */
+#if LWIP_HTTPD_SUPPORT_11_KEEPALIVE
+  if (hs->keepalive) {
+    http_remove_connection(hs);
+
+    http_state_eof(hs);
+    http_state_init(hs);
+    /* restore state: */
+    hs->pcb = pcb;
+    hs->keepalive = 1;
+    http_add_connection(hs);
+    /* ensure nagle doesn't interfere with sending all data as fast as possible: */
+    altcp_nagle_disable(pcb);
+  } else
+#endif /* LWIP_HTTPD_SUPPORT_11_KEEPALIVE */
+  {
+    http_close_conn(pcb, hs);
+  }
+}
+
+#if LWIP_HTTPD_CGI || LWIP_HTTPD_CGI_SSI
+/**
+ * Extract URI parameters from the parameter-part of an URI in the form
+ * "test.cgi?x=y" @todo: better explanation!
+ * Pointers to the parameters are stored in hs->param_vals.
+ *
+ * @param hs http connection state
+ * @param params pointer to the NULL-terminated parameter string from the URI
+ * @return number of parameters extracted
+ */
+static int
+extract_uri_parameters(struct http_state *hs, char *params)
+{
+  char *pair;
+  char *equals;
+  int loop;
+
+  LWIP_UNUSED_ARG(hs);
+
+  /* If we have no parameters at all, return immediately. */
+  if (!params || (params[0] == '\0')) {
+    return (0);
+  }
+
+  /* Get a pointer to our first parameter */
+  pair = params;
+
+  /* Parse up to LWIP_HTTPD_MAX_CGI_PARAMETERS from the passed string and ignore the
+   * remainder (if any) */
+  for (loop = 0; (loop < LWIP_HTTPD_MAX_CGI_PARAMETERS) && pair; loop++) {
+
+    /* Save the name of the parameter */
+    http_cgi_params[loop] = pair;
+
+    /* Remember the start of this name=value pair */
+    equals = pair;
+
+    /* Find the start of the next name=value pair and replace the delimiter
+     * with a 0 to terminate the previous pair string. */
+    pair = strchr(pair, '&');
+    if (pair) {
+      *pair = '\0';
+      pair++;
+    } else {
+      /* We didn't find a new parameter so find the end of the URI and
+       * replace the space with a '\0' */
+      pair = strchr(equals, ' ');
+      if (pair) {
+        *pair = '\0';
+      }
+
+      /* Revert to NULL so that we exit the loop as expected. */
+      pair = NULL;
+    }
+
+    /* Now find the '=' in the previous pair, replace it with '\0' and save
+     * the parameter value string. */
+    equals = strchr(equals, '=');
+    if (equals) {
+      *equals = '\0';
+      http_cgi_param_vals[loop] = equals + 1;
+    } else {
+      http_cgi_param_vals[loop] = NULL;
+    }
+  }
+
+  return loop;
+}
+#endif /* LWIP_HTTPD_CGI || LWIP_HTTPD_CGI_SSI */
+
+#if LWIP_HTTPD_SSI
+/**
+ * Insert a tag (found in an shtml in the form of "<!--#tagname-->" into the file.
+ * The tag's name is stored in ssi->tag_name (NULL-terminated), the replacement
+ * should be written to hs->tag_insert (up to a length of LWIP_HTTPD_MAX_TAG_INSERT_LEN).
+ * The amount of data written is stored to ssi->tag_insert_len.
+ *
+ * @todo: return tag_insert_len - maybe it can be removed from struct http_state?
+ *
+ * @param hs http connection state
+ */
+static void
+get_tag_insert(struct http_state *hs)
+{
+#if LWIP_HTTPD_SSI_RAW
+  const char *tag;
+#else /* LWIP_HTTPD_SSI_RAW */
+  int tag;
+#endif /* LWIP_HTTPD_SSI_RAW */
+  size_t len;
+  struct http_ssi_state *ssi;
+#if LWIP_HTTPD_SSI_MULTIPART
+  u16_t current_tag_part;
+#endif /* LWIP_HTTPD_SSI_MULTIPART */
+
+  LWIP_ASSERT("hs != NULL", hs != NULL);
+  ssi = hs->ssi;
+  LWIP_ASSERT("ssi != NULL", ssi != NULL);
+#if LWIP_HTTPD_SSI_MULTIPART
+  current_tag_part = ssi->tag_part;
+  ssi->tag_part = HTTPD_LAST_TAG_PART;
+#endif /* LWIP_HTTPD_SSI_MULTIPART */
+#if LWIP_HTTPD_SSI_RAW
+  tag = ssi->tag_name;
+#endif
+
+  if (httpd_ssi_handler
+#if !LWIP_HTTPD_SSI_RAW
+      && httpd_tags && httpd_num_tags
+#endif /* !LWIP_HTTPD_SSI_RAW */
+     ) {
+
+    /* Find this tag in the list we have been provided. */
+#if LWIP_HTTPD_SSI_RAW
+    {
+#else /* LWIP_HTTPD_SSI_RAW */
+    for (tag = 0; tag < httpd_num_tags; tag++) {
+      if (strcmp(ssi->tag_name, httpd_tags[tag]) == 0)
+#endif /* LWIP_HTTPD_SSI_RAW */
+      {
+        ssi->tag_insert_len = httpd_ssi_handler(tag, ssi->tag_insert,
+                                              LWIP_HTTPD_MAX_TAG_INSERT_LEN
+#if LWIP_HTTPD_SSI_MULTIPART
+                                              , current_tag_part, &ssi->tag_part
+#endif /* LWIP_HTTPD_SSI_MULTIPART */
+#if LWIP_HTTPD_FILE_STATE
+                                              , (hs->handle ? hs->handle->state : NULL)
+#endif /* LWIP_HTTPD_FILE_STATE */
+                                             );
+#if LWIP_HTTPD_SSI_RAW
+        if (ssi->tag_insert_len != HTTPD_SSI_TAG_UNKNOWN)
+#endif /* LWIP_HTTPD_SSI_RAW */
+        {
+          return;
+        }
+      }
+    }
+  }
+
+  /* If we drop out, we were asked to serve a page which contains tags that
+   * we don't have a handler for. Merely echo back the tags with an error
+   * marker. */
+#define UNKNOWN_TAG1_TEXT "<b>***UNKNOWN TAG "
+#define UNKNOWN_TAG1_LEN  18
+#define UNKNOWN_TAG2_TEXT "***</b>"
+#define UNKNOWN_TAG2_LEN  7
+  len = LWIP_MIN(sizeof(ssi->tag_name), LWIP_MIN(strlen(ssi->tag_name),
+                 LWIP_HTTPD_MAX_TAG_INSERT_LEN - (UNKNOWN_TAG1_LEN + UNKNOWN_TAG2_LEN)));
+  MEMCPY(ssi->tag_insert, UNKNOWN_TAG1_TEXT, UNKNOWN_TAG1_LEN);
+  MEMCPY(&ssi->tag_insert[UNKNOWN_TAG1_LEN], ssi->tag_name, len);
+  MEMCPY(&ssi->tag_insert[UNKNOWN_TAG1_LEN + len], UNKNOWN_TAG2_TEXT, UNKNOWN_TAG2_LEN);
+  ssi->tag_insert[UNKNOWN_TAG1_LEN + len + UNKNOWN_TAG2_LEN] = 0;
+
+  len = strlen(ssi->tag_insert);
+  LWIP_ASSERT("len <= 0xffff", len <= 0xffff);
+  ssi->tag_insert_len = (u16_t)len;
+}
+#endif /* LWIP_HTTPD_SSI */
+
+#if LWIP_HTTPD_DYNAMIC_HEADERS
+/**
+ * Generate the relevant HTTP headers for the given filename and write
+ * them into the supplied buffer.
+ */
+static void
+get_http_headers(struct http_state *hs, const char *uri)
+{
+  size_t content_type;
+  char *tmp;
+  char *ext;
+  char *vars;
+
+  /* In all cases, the second header we send is the server identification
+     so set it here. */
+  hs->hdrs[HDR_STRINGS_IDX_SERVER_NAME] = g_psHTTPHeaderStrings[HTTP_HDR_SERVER];
+  hs->hdrs[HDR_STRINGS_IDX_CONTENT_LEN_KEEPALIVE] = NULL;
+  hs->hdrs[HDR_STRINGS_IDX_CONTENT_LEN_NR] = NULL;
+
+  /* Is this a normal file or the special case we use to send back the
+     default "404: Page not found" response? */
+  if (uri == NULL) {
+    hs->hdrs[HDR_STRINGS_IDX_HTTP_STATUS] = g_psHTTPHeaderStrings[HTTP_HDR_NOT_FOUND];
+#if LWIP_HTTPD_SUPPORT_11_KEEPALIVE
+    if (hs->keepalive) {
+      hs->hdrs[HDR_STRINGS_IDX_CONTENT_TYPE] = g_psHTTPHeaderStrings[DEFAULT_404_HTML_PERSISTENT];
+    } else
+#endif
+    {
+      hs->hdrs[HDR_STRINGS_IDX_CONTENT_TYPE] = g_psHTTPHeaderStrings[DEFAULT_404_HTML];
+    }
+
+    /* Set up to send the first header string. */
+    hs->hdr_index = 0;
+    hs->hdr_pos = 0;
+    return;
+  }
+  /* We are dealing with a particular filename. Look for one other
+      special case.  We assume that any filename with "404" in it must be
+      indicative of a 404 server error whereas all other files require
+      the 200 OK header. */
+  if (strstr(uri, "404")) {
+    hs->hdrs[HDR_STRINGS_IDX_HTTP_STATUS] = g_psHTTPHeaderStrings[HTTP_HDR_NOT_FOUND];
+  } else if (strstr(uri, "400")) {
+    hs->hdrs[HDR_STRINGS_IDX_HTTP_STATUS] = g_psHTTPHeaderStrings[HTTP_HDR_BAD_REQUEST];
+  } else if (strstr(uri, "501")) {
+    hs->hdrs[HDR_STRINGS_IDX_HTTP_STATUS] = g_psHTTPHeaderStrings[HTTP_HDR_NOT_IMPL];
+  } else {
+    hs->hdrs[HDR_STRINGS_IDX_HTTP_STATUS] = g_psHTTPHeaderStrings[HTTP_HDR_OK];
+  }
+
+  /* Determine if the URI has any variables and, if so, temporarily remove
+      them. */
+  vars = strchr(uri, '?');
+  if (vars) {
+    *vars = '\0';
+  }
+
+  /* Get a pointer to the file extension.  We find this by looking for the
+      last occurrence of "." in the filename passed. */
+  ext = NULL;
+  tmp = strchr(uri, '.');
+  while (tmp) {
+    ext = tmp + 1;
+    tmp = strchr(ext, '.');
+  }
+  if (ext != NULL) {
+    /* Now determine the content type and add the relevant header for that. */
+    for (content_type = 0; content_type < NUM_HTTP_HEADERS; content_type++) {
+      /* Have we found a matching extension? */
+      if (!lwip_stricmp(g_psHTTPHeaders[content_type].extension, ext)) {
+        break;
+      }
+    }
+  } else {
+    content_type = NUM_HTTP_HEADERS;
+  }
+
+  /* Reinstate the parameter marker if there was one in the original URI. */
+  if (vars) {
+    *vars = '?';
+  }
+
+#if LWIP_HTTPD_OMIT_HEADER_FOR_EXTENSIONLESS_URI
+  /* Does the URL passed have any file extension?  If not, we assume it
+     is a special-case URL used for control state notification and we do
+     not send any HTTP headers with the response. */
+  if (!ext) {
+    /* Force the header index to a value indicating that all headers
+       have already been sent. */
+    hs->hdr_index = NUM_FILE_HDR_STRINGS;
+    return;
+  }
+#endif /* LWIP_HTTPD_OMIT_HEADER_FOR_EXTENSIONLESS_URI */
+  /* Did we find a matching extension? */
+  if (content_type < NUM_HTTP_HEADERS) {
+    /* yes, store it */
+    hs->hdrs[HDR_STRINGS_IDX_CONTENT_TYPE] = g_psHTTPHeaders[content_type].content_type;
+  } else if (!ext) {
+    /* no, no extension found -> use binary transfer to prevent the browser adding '.txt' on save */
+    hs->hdrs[HDR_STRINGS_IDX_CONTENT_TYPE] = HTTP_HDR_APP;
+  } else {
+    /* No - use the default, plain text file type. */
+    hs->hdrs[HDR_STRINGS_IDX_CONTENT_TYPE] = HTTP_HDR_DEFAULT_TYPE;
+  }
+  /* Set up to send the first header string. */
+  hs->hdr_index = 0;
+  hs->hdr_pos = 0;
+}
+
+/* Add content-length header? */
+static void
+get_http_content_length(struct http_state *hs)
+{
+  u8_t add_content_len = 0;
+
+  LWIP_ASSERT("already been here?", hs->hdrs[HDR_STRINGS_IDX_CONTENT_LEN_KEEPALIVE] == NULL);
+
+  add_content_len = 0;
+#if LWIP_HTTPD_SSI
+  if (hs->ssi == NULL) /* @todo: get maximum file length from SSI */
+#endif /* LWIP_HTTPD_SSI */
+  {
+    if ((hs->handle != NULL) && (hs->handle->flags & FS_FILE_FLAGS_HEADER_PERSISTENT)) {
+      add_content_len = 1;
+    }
+  }
+  if (add_content_len) {
+    size_t len;
+    lwip_itoa(hs->hdr_content_len, (size_t)LWIP_HTTPD_MAX_CONTENT_LEN_SIZE,
+              hs->handle->len);
+    len = strlen(hs->hdr_content_len);
+    if (len <= LWIP_HTTPD_MAX_CONTENT_LEN_SIZE - LWIP_HTTPD_MAX_CONTENT_LEN_OFFSET) {
+      SMEMCPY(&hs->hdr_content_len[len], CRLF, 3);
+      hs->hdrs[HDR_STRINGS_IDX_CONTENT_LEN_NR] = hs->hdr_content_len;
+    } else {
+      add_content_len = 0;
+    }
+  }
+#if LWIP_HTTPD_SUPPORT_11_KEEPALIVE
+  if (add_content_len) {
+    hs->hdrs[HDR_STRINGS_IDX_CONTENT_LEN_KEEPALIVE] = g_psHTTPHeaderStrings[HTTP_HDR_KEEPALIVE_LEN];
+  } else {
+    hs->hdrs[HDR_STRINGS_IDX_CONTENT_LEN_KEEPALIVE] = g_psHTTPHeaderStrings[HTTP_HDR_CONN_CLOSE];
+    hs->keepalive = 0;
+  }
+#else /* LWIP_HTTPD_SUPPORT_11_KEEPALIVE */
+  if (add_content_len) {
+    hs->hdrs[HDR_STRINGS_IDX_CONTENT_LEN_KEEPALIVE] = g_psHTTPHeaderStrings[HTTP_HDR_CONTENT_LENGTH];
+  }
+#endif /* LWIP_HTTPD_SUPPORT_11_KEEPALIVE */
+}
+
+/** Sub-function of http_send(): send dynamic headers
+ *
+ * @returns: - HTTP_NO_DATA_TO_SEND: no new data has been enqueued
+ *           - HTTP_DATA_TO_SEND_CONTINUE: continue with sending HTTP body
+ *           - HTTP_DATA_TO_SEND_BREAK: data has been enqueued, headers pending,
+ *                                      so don't send HTTP body yet
+ *           - HTTP_DATA_TO_SEND_FREED: http_state and pcb are already freed
+ */
+static u8_t
+http_send_headers(struct altcp_pcb *pcb, struct http_state *hs)
+{
+  err_t err;
+  u16_t len;
+  u8_t data_to_send = HTTP_NO_DATA_TO_SEND;
+  u16_t hdrlen, sendlen;
+
+  if (hs->hdrs[HDR_STRINGS_IDX_CONTENT_LEN_KEEPALIVE] == NULL) {
+    /* set up "content-length" and "connection:" headers */
+    get_http_content_length(hs);
+  }
+
+  /* How much data can we send? */
+  len = altcp_sndbuf(pcb);
+  sendlen = len;
+
+  while (len && (hs->hdr_index < NUM_FILE_HDR_STRINGS) && sendlen) {
+    const void *ptr;
+    u16_t old_sendlen;
+    u8_t apiflags;
+    /* How much do we have to send from the current header? */
+    hdrlen = (u16_t)strlen(hs->hdrs[hs->hdr_index]);
+
+    /* How much of this can we send? */
+    sendlen = (len < (hdrlen - hs->hdr_pos)) ? len : (hdrlen - hs->hdr_pos);
+
+    /* Send this amount of data or as much as we can given memory
+     * constraints. */
+    ptr = (const void *)(hs->hdrs[hs->hdr_index] + hs->hdr_pos);
+    old_sendlen = sendlen;
+    apiflags = HTTP_IS_HDR_VOLATILE(hs, ptr);
+    if (hs->hdr_index == HDR_STRINGS_IDX_CONTENT_LEN_NR) {
+      /* content-length is always volatile */
+      apiflags |= TCP_WRITE_FLAG_COPY;
+    }
+    if (hs->hdr_index < NUM_FILE_HDR_STRINGS - 1) {
+      apiflags |= TCP_WRITE_FLAG_MORE;
+    }
+    err = http_write(pcb, ptr, &sendlen, apiflags);
+    if ((err == ERR_OK) && (old_sendlen != sendlen)) {
+      /* Remember that we added some more data to be transmitted. */
+      data_to_send = HTTP_DATA_TO_SEND_CONTINUE;
+    } else if (err != ERR_OK) {
+      /* special case: http_write does not try to send 1 byte */
+      sendlen = 0;
+    }
+
+    /* Fix up the header position for the next time round. */
+    hs->hdr_pos += sendlen;
+    len -= sendlen;
+
+    /* Have we finished sending this string? */
+    if (hs->hdr_pos == hdrlen) {
+      /* Yes - move on to the next one */
+      hs->hdr_index++;
+      /* skip headers that are NULL (not all headers are required) */
+      while ((hs->hdr_index < NUM_FILE_HDR_STRINGS) &&
+             (hs->hdrs[hs->hdr_index] == NULL)) {
+        hs->hdr_index++;
+      }
+      hs->hdr_pos = 0;
+    }
+  }
+
+  if ((hs->hdr_index >= NUM_FILE_HDR_STRINGS) && (hs->file == NULL)) {
+    /* When we are at the end of the headers, check for data to send
+     * instead of waiting for ACK from remote side to continue
+     * (which would happen when sending files from async read). */
+    if (http_check_eof(pcb, hs)) {
+      data_to_send = HTTP_DATA_TO_SEND_BREAK;
+    } else {
+      /* At this point, for non-keepalive connections, hs is deallocated an
+         pcb is closed. */
+      return HTTP_DATA_TO_SEND_FREED;
+    }
+  }
+  /* If we get here and there are still header bytes to send, we send
+   * the header information we just wrote immediately. If there are no
+   * more headers to send, but we do have file data to send, drop through
+   * to try to send some file data too. */
+  if ((hs->hdr_index < NUM_FILE_HDR_STRINGS) || !hs->file) {
+    LWIP_DEBUGF(HTTPD_DEBUG, ("tcp_output\n"));
+    return HTTP_DATA_TO_SEND_BREAK;
+  }
+  return data_to_send;
+}
+#endif /* LWIP_HTTPD_DYNAMIC_HEADERS */
+
+/** Sub-function of http_send(): end-of-file (or block) is reached,
+ * either close the file or read the next block (if supported).
+ *
+ * @returns: 0 if the file is finished or no data has been read
+ *           1 if the file is not finished and data has been read
+ */
+static u8_t
+http_check_eof(struct altcp_pcb *pcb, struct http_state *hs)
+{
+  int bytes_left;
+#if LWIP_HTTPD_DYNAMIC_FILE_READ
+  int count;
+#ifdef HTTPD_MAX_WRITE_LEN
+  int max_write_len;
+#endif /* HTTPD_MAX_WRITE_LEN */
+#endif /* LWIP_HTTPD_DYNAMIC_FILE_READ */
+
+  /* Do we have a valid file handle? */
+  if (hs->handle == NULL) {
+    /* No - close the connection. */
+    http_eof(pcb, hs);
+    return 0;
+  }
+  bytes_left = fs_bytes_left(hs->handle);
+  if (bytes_left <= 0) {
+    /* We reached the end of the file so this request is done. */
+    LWIP_DEBUGF(HTTPD_DEBUG, ("End of file.\n"));
+    http_eof(pcb, hs);
+    return 0;
+  }
+#if LWIP_HTTPD_DYNAMIC_FILE_READ
+  /* Do we already have a send buffer allocated? */
+  if (hs->buf) {
+    /* Yes - get the length of the buffer */
+    count = LWIP_MIN(hs->buf_len, bytes_left);
+  } else {
+    /* We don't have a send buffer so allocate one now */
+    count = altcp_sndbuf(pcb);
+    if (bytes_left < count) {
+      count = bytes_left;
+    }
+#ifdef HTTPD_MAX_WRITE_LEN
+    /* Additional limitation: e.g. don't enqueue more than 2*mss at once */
+    max_write_len = HTTPD_MAX_WRITE_LEN(pcb);
+    if (count > max_write_len) {
+      count = max_write_len;
+    }
+#endif /* HTTPD_MAX_WRITE_LEN */
+    do {
+      hs->buf = (char *)mem_malloc((mem_size_t)count);
+      if (hs->buf != NULL) {
+        hs->buf_len = count;
+        break;
+      }
+      count = count / 2;
+    } while (count > 100);
+
+    /* Did we get a send buffer? If not, return immediately. */
+    if (hs->buf == NULL) {
+      LWIP_DEBUGF(HTTPD_DEBUG, ("No buff\n"));
+      return 0;
+    }
+  }
+
+  /* Read a block of data from the file. */
+  LWIP_DEBUGF(HTTPD_DEBUG, ("Trying to read %d bytes.\n", count));
+
+#if LWIP_HTTPD_FS_ASYNC_READ
+  count = fs_read_async(hs->handle, hs->buf, count, http_continue, hs);
+#else /* LWIP_HTTPD_FS_ASYNC_READ */
+  count = fs_read(hs->handle, hs->buf, count);
+#endif /* LWIP_HTTPD_FS_ASYNC_READ */
+  if (count < 0) {
+    if (count == FS_READ_DELAYED) {
+      /* Delayed read, wait for FS to unblock us */
+      return 0;
+    }
+    /* We reached the end of the file so this request is done.
+     * @todo: close here for HTTP/1.1 when reading file fails */
+    LWIP_DEBUGF(HTTPD_DEBUG, ("End of file.\n"));
+    http_eof(pcb, hs);
+    return 0;
+  }
+
+  /* Set up to send the block of data we just read */
+  LWIP_DEBUGF(HTTPD_DEBUG, ("Read %d bytes.\n", count));
+  hs->left = count;
+  hs->file = hs->buf;
+#if LWIP_HTTPD_SSI
+  if (hs->ssi) {
+    hs->ssi->parse_left = count;
+    hs->ssi->parsed = hs->buf;
+  }
+#endif /* LWIP_HTTPD_SSI */
+#else /* LWIP_HTTPD_DYNAMIC_FILE_READ */
+  LWIP_ASSERT("SSI and DYNAMIC_HEADERS turned off but eof not reached", 0);
+#endif /* LWIP_HTTPD_SSI || LWIP_HTTPD_DYNAMIC_HEADERS */
+  return 1;
+}
+
+/** Sub-function of http_send(): This is the normal send-routine for non-ssi files
+ *
+ * @returns: - 1: data has been written (so call tcp_ouput)
+ *           - 0: no data has been written (no need to call tcp_output)
+ */
+static u8_t
+http_send_data_nonssi(struct altcp_pcb *pcb, struct http_state *hs)
+{
+  err_t err;
+  u16_t len;
+  u8_t data_to_send = 0;
+
+  /* We are not processing an SHTML file so no tag checking is necessary.
+   * Just send the data as we received it from the file. */
+  len = (u16_t)LWIP_MIN(hs->left, 0xffff);
+
+  err = http_write(pcb, hs->file, &len, HTTP_IS_DATA_VOLATILE(hs));
+  if (err == ERR_OK) {
+    data_to_send = 1;
+    hs->file += len;
+    hs->left -= len;
+  }
+
+  return data_to_send;
+}
+
+#if LWIP_HTTPD_SSI
+/** Sub-function of http_send(): This is the send-routine for ssi files
+ *
+ * @returns: - 1: data has been written (so call tcp_ouput)
+ *           - 0: no data has been written (no need to call tcp_output)
+ */
+static u8_t
+http_send_data_ssi(struct altcp_pcb *pcb, struct http_state *hs)
+{
+  err_t err = ERR_OK;
+  u16_t len;
+  u8_t data_to_send = 0;
+  u8_t tag_type;
+
+  struct http_ssi_state *ssi = hs->ssi;
+  LWIP_ASSERT("ssi != NULL", ssi != NULL);
+  /* We are processing an SHTML file so need to scan for tags and replace
+   * them with insert strings. We need to be careful here since a tag may
+   * straddle the boundary of two blocks read from the file and we may also
+   * have to split the insert string between two tcp_write operations. */
+
+  /* How much data could we send? */
+  len = altcp_sndbuf(pcb);
+
+  /* Do we have remaining data to send before parsing more? */
+  if (ssi->parsed > hs->file) {
+    len = (u16_t)LWIP_MIN(ssi->parsed - hs->file, 0xffff);
+
+    err = http_write(pcb, hs->file, &len, HTTP_IS_DATA_VOLATILE(hs));
+    if (err == ERR_OK) {
+      data_to_send = 1;
+      hs->file += len;
+      hs->left -= len;
+    }
+
+    /* If the send buffer is full, return now. */
+    if (altcp_sndbuf(pcb) == 0) {
+      return data_to_send;
+    }
+  }
+
+  LWIP_DEBUGF(HTTPD_DEBUG, ("State %d, %d left\n", ssi->tag_state, (int)ssi->parse_left));
+
+  /* We have sent all the data that was already parsed so continue parsing
+   * the buffer contents looking for SSI tags. */
+  while (((ssi->tag_state == TAG_SENDING) || ssi->parse_left) && (err == ERR_OK)) {
+    if (len == 0) {
+      return data_to_send;
+    }
+    switch (ssi->tag_state) {
+      case TAG_NONE:
+        /* We are not currently processing an SSI tag so scan for the
+         * start of the lead-in marker. */
+        for (tag_type = 0; tag_type < LWIP_ARRAYSIZE(http_ssi_tag_desc); tag_type++) {
+          if (*ssi->parsed == http_ssi_tag_desc[tag_type].lead_in[0]) {
+            /* We found what could be the lead-in for a new tag so change
+             * state appropriately. */
+            ssi->tag_type = tag_type;
+            ssi->tag_state = TAG_LEADIN;
+            ssi->tag_index = 1;
+  #if !LWIP_HTTPD_SSI_INCLUDE_TAG
+            ssi->tag_started = ssi->parsed;
+  #endif /* !LWIP_HTTPD_SSI_INCLUDE_TAG */
+            break;
+          }
+        }
+
+        /* Move on to the next character in the buffer */
+        ssi->parse_left--;
+        ssi->parsed++;
+        break;
+
+      case TAG_LEADIN:
+        /* We are processing the lead-in marker, looking for the start of
+         * the tag name. */
+
+        /* Have we reached the end of the leadin? */
+        if (http_ssi_tag_desc[ssi->tag_type].lead_in[ssi->tag_index] == 0) {
+          ssi->tag_index = 0;
+          ssi->tag_state = TAG_FOUND;
+        } else {
+          /* Have we found the next character we expect for the tag leadin? */
+          if (*ssi->parsed == http_ssi_tag_desc[ssi->tag_type].lead_in[ssi->tag_index]) {
+            /* Yes - move to the next one unless we have found the complete
+             * leadin, in which case we start looking for the tag itself */
+            ssi->tag_index++;
+          } else {
+            /* We found an unexpected character so this is not a tag. Move
+             * back to idle state. */
+            ssi->tag_state = TAG_NONE;
+          }
+
+          /* Move on to the next character in the buffer */
+          ssi->parse_left--;
+          ssi->parsed++;
+        }
+        break;
+
+      case TAG_FOUND:
+        /* We are reading the tag name, looking for the start of the
+         * lead-out marker and removing any whitespace found. */
+
+        /* Remove leading whitespace between the tag leading and the first
+         * tag name character. */
+        if ((ssi->tag_index == 0) && ((*ssi->parsed == ' ') ||
+                                      (*ssi->parsed == '\t') || (*ssi->parsed == '\n') ||
+                                      (*ssi->parsed == '\r'))) {
+          /* Move on to the next character in the buffer */
+          ssi->parse_left--;
+          ssi->parsed++;
+          break;
+        }
+
+        /* Have we found the end of the tag name? This is signalled by
+         * us finding the first leadout character or whitespace */
+        if ((*ssi->parsed == http_ssi_tag_desc[ssi->tag_type].lead_out[0]) ||
+            (*ssi->parsed == ' ')  || (*ssi->parsed == '\t') ||
+            (*ssi->parsed == '\n') || (*ssi->parsed == '\r')) {
+
+          if (ssi->tag_index == 0) {
+            /* We read a zero length tag so ignore it. */
+            ssi->tag_state = TAG_NONE;
+          } else {
+            /* We read a non-empty tag so go ahead and look for the
+             * leadout string. */
+            ssi->tag_state = TAG_LEADOUT;
+            LWIP_ASSERT("ssi->tag_index <= 0xff", ssi->tag_index <= 0xff);
+            ssi->tag_name_len = (u8_t)ssi->tag_index;
+            ssi->tag_name[ssi->tag_index] = '\0';
+            if (*ssi->parsed == http_ssi_tag_desc[ssi->tag_type].lead_out[0]) {
+              ssi->tag_index = 1;
+            } else {
+              ssi->tag_index = 0;
+            }
+          }
+        } else {
+          /* This character is part of the tag name so save it */
+          if (ssi->tag_index < LWIP_HTTPD_MAX_TAG_NAME_LEN) {
+            ssi->tag_name[ssi->tag_index++] = *ssi->parsed;
+          } else {
+            /* The tag was too long so ignore it. */
+            ssi->tag_state = TAG_NONE;
+          }
+        }
+
+        /* Move on to the next character in the buffer */
+        ssi->parse_left--;
+        ssi->parsed++;
+
+        break;
+
+      /* We are looking for the end of the lead-out marker. */
+      case TAG_LEADOUT:
+        /* Remove leading whitespace between the tag leading and the first
+         * tag leadout character. */
+        if ((ssi->tag_index == 0) && ((*ssi->parsed == ' ') ||
+                                      (*ssi->parsed == '\t') || (*ssi->parsed == '\n') ||
+                                      (*ssi->parsed == '\r'))) {
+          /* Move on to the next character in the buffer */
+          ssi->parse_left--;
+          ssi->parsed++;
+          break;
+        }
+
+        /* Have we found the next character we expect for the tag leadout? */
+        if (*ssi->parsed == http_ssi_tag_desc[ssi->tag_type].lead_out[ssi->tag_index]) {
+          /* Yes - move to the next one unless we have found the complete
+           * leadout, in which case we need to call the client to process
+           * the tag. */
+
+          /* Move on to the next character in the buffer */
+          ssi->parse_left--;
+          ssi->parsed++;
+          ssi->tag_index++;
+
+          if (http_ssi_tag_desc[ssi->tag_type].lead_out[ssi->tag_index] == 0) {
+            /* Call the client to ask for the insert string for the
+             * tag we just found. */
+#if LWIP_HTTPD_SSI_MULTIPART
+            ssi->tag_part = 0; /* start with tag part 0 */
+#endif /* LWIP_HTTPD_SSI_MULTIPART */
+            get_tag_insert(hs);
+
+            /* Next time through, we are going to be sending data
+             * immediately, either the end of the block we start
+             * sending here or the insert string. */
+            ssi->tag_index = 0;
+            ssi->tag_state = TAG_SENDING;
+            ssi->tag_end = ssi->parsed;
+#if !LWIP_HTTPD_SSI_INCLUDE_TAG
+            ssi->parsed = ssi->tag_started;
+#endif /* !LWIP_HTTPD_SSI_INCLUDE_TAG*/
+
+            /* If there is any unsent data in the buffer prior to the
+             * tag, we need to send it now. */
+            if (ssi->tag_end > hs->file) {
+              /* How much of the data can we send? */
+#if LWIP_HTTPD_SSI_INCLUDE_TAG
+              len = (u16_t)LWIP_MIN(ssi->tag_end - hs->file, 0xffff);
+#else /* LWIP_HTTPD_SSI_INCLUDE_TAG*/
+              /* we would include the tag in sending */
+              len = (u16_t)LWIP_MIN(ssi->tag_started - hs->file, 0xffff);
+#endif /* LWIP_HTTPD_SSI_INCLUDE_TAG*/
+
+              err = http_write(pcb, hs->file, &len, HTTP_IS_DATA_VOLATILE(hs));
+              if (err == ERR_OK) {
+                data_to_send = 1;
+#if !LWIP_HTTPD_SSI_INCLUDE_TAG
+                if (ssi->tag_started <= hs->file) {
+                  /* pretend to have sent the tag, too */
+                  len += (u16_t)(ssi->tag_end - ssi->tag_started);
+                }
+#endif /* !LWIP_HTTPD_SSI_INCLUDE_TAG*/
+                hs->file += len;
+                hs->left -= len;
+              }
+            }
+          }
+        } else {
+          /* We found an unexpected character so this is not a tag. Move
+           * back to idle state. */
+          ssi->parse_left--;
+          ssi->parsed++;
+          ssi->tag_state = TAG_NONE;
+        }
+        break;
+
+      /*
+       * We have found a valid tag and are in the process of sending
+       * data as a result of that discovery. We send either remaining data
+       * from the file prior to the insert point or the insert string itself.
+       */
+      case TAG_SENDING:
+        /* Do we have any remaining file data to send from the buffer prior
+         * to the tag? */
+        if (ssi->tag_end > hs->file) {
+          /* How much of the data can we send? */
+#if LWIP_HTTPD_SSI_INCLUDE_TAG
+          len = (u16_t)LWIP_MIN(ssi->tag_end - hs->file, 0xffff);
+#else /* LWIP_HTTPD_SSI_INCLUDE_TAG*/
+          LWIP_ASSERT("hs->started >= hs->file", ssi->tag_started >= hs->file);
+          /* we would include the tag in sending */
+          len = (u16_t)LWIP_MIN(ssi->tag_started - hs->file, 0xffff);
+#endif /* LWIP_HTTPD_SSI_INCLUDE_TAG*/
+          if (len != 0) {
+            err = http_write(pcb, hs->file, &len, HTTP_IS_DATA_VOLATILE(hs));
+          } else {
+            err = ERR_OK;
+          }
+          if (err == ERR_OK) {
+            data_to_send = 1;
+#if !LWIP_HTTPD_SSI_INCLUDE_TAG
+            if (ssi->tag_started <= hs->file) {
+              /* pretend to have sent the tag, too */
+              len += (u16_t)(ssi->tag_end - ssi->tag_started);
+            }
+#endif /* !LWIP_HTTPD_SSI_INCLUDE_TAG*/
+            hs->file += len;
+            hs->left -= len;
+          }
+        } else {
+#if LWIP_HTTPD_SSI_MULTIPART
+          if (ssi->tag_index >= ssi->tag_insert_len) {
+            /* Did the last SSIHandler have more to send? */
+            if (ssi->tag_part != HTTPD_LAST_TAG_PART) {
+              /* If so, call it again */
+              ssi->tag_index = 0;
+              get_tag_insert(hs);
+            }
+          }
+#endif /* LWIP_HTTPD_SSI_MULTIPART */
+
+          /* Do we still have insert data left to send? */
+          if (ssi->tag_index < ssi->tag_insert_len) {
+            /* We are sending the insert string itself. How much of the
+             * insert can we send? */
+            len = (ssi->tag_insert_len - ssi->tag_index);
+
+            /* Note that we set the copy flag here since we only have a
+             * single tag insert buffer per connection. If we don't do
+             * this, insert corruption can occur if more than one insert
+             * is processed before we call tcp_output. */
+            err = http_write(pcb, &(ssi->tag_insert[ssi->tag_index]), &len,
+                             HTTP_IS_TAG_VOLATILE(hs));
+            if (err == ERR_OK) {
+              data_to_send = 1;
+              ssi->tag_index += len;
+              /* Don't return here: keep on sending data */
+            }
+          } else {
+#if LWIP_HTTPD_SSI_MULTIPART
+            if (ssi->tag_part == HTTPD_LAST_TAG_PART)
+#endif /* LWIP_HTTPD_SSI_MULTIPART */
+            {
+              /* We have sent all the insert data so go back to looking for
+               * a new tag. */
+              LWIP_DEBUGF(HTTPD_DEBUG, ("Everything sent.\n"));
+              ssi->tag_index = 0;
+              ssi->tag_state = TAG_NONE;
+#if !LWIP_HTTPD_SSI_INCLUDE_TAG
+              ssi->parsed = ssi->tag_end;
+#endif /* !LWIP_HTTPD_SSI_INCLUDE_TAG*/
+            }
+          }
+          break;
+        default:
+          break;
+        }
+    }
+  }
+
+  /* If we drop out of the end of the for loop, this implies we must have
+   * file data to send so send it now. In TAG_SENDING state, we've already
+   * handled this so skip the send if that's the case. */
+  if ((ssi->tag_state != TAG_SENDING) && (ssi->parsed > hs->file)) {
+#if LWIP_HTTPD_DYNAMIC_FILE_READ && !LWIP_HTTPD_SSI_INCLUDE_TAG
+    if ((ssi->tag_state != TAG_NONE) && (ssi->tag_started > ssi->tag_end)) {
+      /* If we found tag on the edge of the read buffer: just throw away the first part
+         (we have copied/saved everything required for parsing on later). */
+      len = (u16_t)(ssi->tag_started - hs->file);
+      hs->left -= (ssi->parsed - ssi->tag_started);
+      ssi->parsed = ssi->tag_started;
+      ssi->tag_started = hs->buf;
+    } else
+#endif /* LWIP_HTTPD_DYNAMIC_FILE_READ && !LWIP_HTTPD_SSI_INCLUDE_TAG */
+    {
+      len = (u16_t)LWIP_MIN(ssi->parsed - hs->file, 0xffff);
+    }
+
+    err = http_write(pcb, hs->file, &len, HTTP_IS_DATA_VOLATILE(hs));
+    if (err == ERR_OK) {
+      data_to_send = 1;
+      hs->file += len;
+      hs->left -= len;
+    }
+  }
+  return data_to_send;
+}
+#endif /* LWIP_HTTPD_SSI */
+
+/**
+ * Try to send more data on this pcb.
+ *
+ * @param pcb the pcb to send data
+ * @param hs connection state
+ */
+static u8_t
+http_send(struct altcp_pcb *pcb, struct http_state *hs)
+{
+  u8_t data_to_send = HTTP_NO_DATA_TO_SEND;
+
+  LWIP_DEBUGF(HTTPD_DEBUG | LWIP_DBG_TRACE, ("http_send: pcb=%p hs=%p left=%d\n", (void *)pcb,
+              (void *)hs, hs != NULL ? (int)hs->left : 0));
+
+#if LWIP_HTTPD_SUPPORT_POST && LWIP_HTTPD_POST_MANUAL_WND
+  if (hs->unrecved_bytes != 0) {
+    return 0;
+  }
+#endif /* LWIP_HTTPD_SUPPORT_POST && LWIP_HTTPD_POST_MANUAL_WND */
+
+  /* If we were passed a NULL state structure pointer, ignore the call. */
+  if (hs == NULL) {
+    return 0;
+  }
+
+#if LWIP_HTTPD_FS_ASYNC_READ
+  /* Check if we are allowed to read from this file.
+     (e.g. SSI might want to delay sending until data is available) */
+  if (!fs_is_file_ready(hs->handle, http_continue, hs)) {
+    return 0;
+  }
+#endif /* LWIP_HTTPD_FS_ASYNC_READ */
+
+#if LWIP_HTTPD_DYNAMIC_HEADERS
+  /* Do we have any more header data to send for this file? */
+  if (hs->hdr_index < NUM_FILE_HDR_STRINGS) {
+    data_to_send = http_send_headers(pcb, hs);
+    if ((data_to_send == HTTP_DATA_TO_SEND_FREED) ||
+        ((data_to_send != HTTP_DATA_TO_SEND_CONTINUE) &&
+         (hs->hdr_index < NUM_FILE_HDR_STRINGS))) {
+      return data_to_send;
+    }
+  }
+#endif /* LWIP_HTTPD_DYNAMIC_HEADERS */
+
+  /* Have we run out of file data to send? If so, we need to read the next
+   * block from the file. */
+  if (hs->left == 0) {
+    if (!http_check_eof(pcb, hs)) {
+      return 0;
+    }
+  }
+
+#if LWIP_HTTPD_SSI
+  if (hs->ssi) {
+    data_to_send = http_send_data_ssi(pcb, hs);
+  } else
+#endif /* LWIP_HTTPD_SSI */
+  {
+    data_to_send = http_send_data_nonssi(pcb, hs);
+  }
+
+  if ((hs->left == 0) && (fs_bytes_left(hs->handle) <= 0)) {
+    /* We reached the end of the file so this request is done.
+     * This adds the FIN flag right into the last data segment. */
+    LWIP_DEBUGF(HTTPD_DEBUG, ("End of file.\n"));
+    http_eof(pcb, hs);
+    return 0;
+  }
+  LWIP_DEBUGF(HTTPD_DEBUG | LWIP_DBG_TRACE, ("send_data end.\n"));
+  return data_to_send;
+}
+
+#if LWIP_HTTPD_SUPPORT_EXTSTATUS
+/** Initialize a http connection with a file to send for an error message
+ *
+ * @param hs http connection state
+ * @param error_nr HTTP error number
+ * @return ERR_OK if file was found and hs has been initialized correctly
+ *         another err_t otherwise
+ */
+static err_t
+http_find_error_file(struct http_state *hs, u16_t error_nr)
+{
+  const char *uri, *uri1, *uri2, *uri3;
+
+  if (error_nr == 501) {
+    uri1 = "/501.html";
+    uri2 = "/501.htm";
+    uri3 = "/501.shtml";
+  } else {
+    /* 400 (bad request is the default) */
+    uri1 = "/400.html";
+    uri2 = "/400.htm";
+    uri3 = "/400.shtml";
+  }
+  if (fs_open(&hs->file_handle, uri1) == ERR_OK) {
+    uri = uri1;
+  } else if (fs_open(&hs->file_handle, uri2) == ERR_OK) {
+    uri = uri2;
+  } else if (fs_open(&hs->file_handle, uri3) == ERR_OK) {
+    uri = uri3;
+  } else {
+    LWIP_DEBUGF(HTTPD_DEBUG, ("Error page for error %"U16_F" not found\n",
+                              error_nr));
+    return ERR_ARG;
+  }
+  return http_init_file(hs, &hs->file_handle, 0, uri, 0, NULL);
+}
+#else /* LWIP_HTTPD_SUPPORT_EXTSTATUS */
+#define http_find_error_file(hs, error_nr) ERR_ARG
+#endif /* LWIP_HTTPD_SUPPORT_EXTSTATUS */
+
+/**
+ * Get the file struct for a 404 error page.
+ * Tries some file names and returns NULL if none found.
+ *
+ * @param uri pointer that receives the actual file name URI
+ * @return file struct for the error page or NULL no matching file was found
+ */
+static struct fs_file *
+http_get_404_file(struct http_state *hs, const char **uri)
+{
+  err_t err;
+
+  *uri = "/404.html";
+  err = fs_open(&hs->file_handle, *uri);
+  if (err != ERR_OK) {
+    /* 404.html doesn't exist. Try 404.htm instead. */
+    *uri = "/404.htm";
+    err = fs_open(&hs->file_handle, *uri);
+    if (err != ERR_OK) {
+      /* 404.htm doesn't exist either. Try 404.shtml instead. */
+      *uri = "/404.shtml";
+      err = fs_open(&hs->file_handle, *uri);
+      if (err != ERR_OK) {
+        /* 404.htm doesn't exist either. Indicate to the caller that it should
+         * send back a default 404 page.
+         */
+        *uri = NULL;
+        return NULL;
+      }
+    }
+  }
+
+  return &hs->file_handle;
+}
+
+#if LWIP_HTTPD_SUPPORT_POST
+static err_t
+http_handle_post_finished(struct http_state *hs)
+{
+#if LWIP_HTTPD_POST_MANUAL_WND
+  /* Prevent multiple calls to httpd_post_finished, since it might have already
+     been called before from httpd_post_data_recved(). */
+  if (hs->post_finished) {
+    return ERR_OK;
+  }
+  hs->post_finished = 1;
+#endif /* LWIP_HTTPD_POST_MANUAL_WND */
+  /* application error or POST finished */
+  /* NULL-terminate the buffer */
+  http_uri_buf[0] = 0;
+  httpd_post_finished(hs, http_uri_buf, LWIP_HTTPD_URI_BUF_LEN);
+  return http_find_file(hs, http_uri_buf, 0);
+}
+
+/** Pass received POST body data to the application and correctly handle
+ * returning a response document or closing the connection.
+ * ATTENTION: The application is responsible for the pbuf now, so don't free it!
+ *
+ * @param hs http connection state
+ * @param p pbuf to pass to the application
+ * @return ERR_OK if passed successfully, another err_t if the response file
+ *         hasn't been found (after POST finished)
+ */
+static err_t
+http_post_rxpbuf(struct http_state *hs, struct pbuf *p)
+{
+  err_t err;
+
+  if (p != NULL) {
+    /* adjust remaining Content-Length */
+    if (hs->post_content_len_left < p->tot_len) {
+      hs->post_content_len_left = 0;
+    } else {
+      hs->post_content_len_left -= p->tot_len;
+    }
+  }
+#if LWIP_HTTPD_SUPPORT_POST && LWIP_HTTPD_POST_MANUAL_WND
+  /* prevent connection being closed if httpd_post_data_recved() is called nested */
+  hs->unrecved_bytes++;
+#endif
+  if (p != NULL) {
+    err = httpd_post_receive_data(hs, p);
+  } else {
+    err = ERR_OK;
+  }
+#if LWIP_HTTPD_SUPPORT_POST && LWIP_HTTPD_POST_MANUAL_WND
+  hs->unrecved_bytes--;
+#endif
+  if (err != ERR_OK) {
+    /* Ignore remaining content in case of application error */
+    hs->post_content_len_left = 0;
+  }
+  if (hs->post_content_len_left == 0) {
+#if LWIP_HTTPD_SUPPORT_POST && LWIP_HTTPD_POST_MANUAL_WND
+    if (hs->unrecved_bytes != 0) {
+      return ERR_OK;
+    }
+#endif /* LWIP_HTTPD_SUPPORT_POST && LWIP_HTTPD_POST_MANUAL_WND */
+    /* application error or POST finished */
+    return http_handle_post_finished(hs);
+  }
+
+  return ERR_OK;
+}
+
+/** Handle a post request. Called from http_parse_request when method 'POST'
+ * is found.
+ *
+ * @param p The input pbuf (containing the POST header and body).
+ * @param hs The http connection state.
+ * @param data HTTP request (header and part of body) from input pbuf(s).
+ * @param data_len Size of 'data'.
+ * @param uri The HTTP URI parsed from input pbuf(s).
+ * @param uri_end Pointer to the end of 'uri' (here, the rest of the HTTP
+ *                header starts).
+ * @return ERR_OK: POST correctly parsed and accepted by the application.
+ *         ERR_INPROGRESS: POST not completely parsed (no error yet)
+ *         another err_t: Error parsing POST or denied by the application
+ */
+static err_t
+http_post_request(struct pbuf *inp, struct http_state *hs,
+                  char *data, u16_t data_len, char *uri, char *uri_end)
+{
+  err_t err;
+  /* search for end-of-header (first double-CRLF) */
+  char *crlfcrlf = lwip_strnstr(uri_end + 1, CRLF CRLF, data_len - (uri_end + 1 - data));
+
+  if (crlfcrlf != NULL) {
+    /* search for "Content-Length: " */
+#define HTTP_HDR_CONTENT_LEN                "Content-Length: "
+#define HTTP_HDR_CONTENT_LEN_LEN            16
+#define HTTP_HDR_CONTENT_LEN_DIGIT_MAX_LEN  10
+    char *scontent_len = lwip_strnstr(uri_end + 1, HTTP_HDR_CONTENT_LEN, crlfcrlf - (uri_end + 1));
+    if (scontent_len != NULL) {
+      char *scontent_len_end = lwip_strnstr(scontent_len + HTTP_HDR_CONTENT_LEN_LEN, CRLF, HTTP_HDR_CONTENT_LEN_DIGIT_MAX_LEN);
+      if (scontent_len_end != NULL) {
+        int content_len;
+        char *content_len_num = scontent_len + HTTP_HDR_CONTENT_LEN_LEN;
+        content_len = atoi(content_len_num);
+        if (content_len == 0) {
+          /* if atoi returns 0 on error, fix this */
+          if ((content_len_num[0] != '0') || (content_len_num[1] != '\r')) {
+            content_len = -1;
+          }
+        }
+        if (content_len >= 0) {
+          /* adjust length of HTTP header passed to application */
+          const char *hdr_start_after_uri = uri_end + 1;
+          u16_t hdr_len = (u16_t)LWIP_MIN(data_len, crlfcrlf + 4 - data);
+          u16_t hdr_data_len = (u16_t)LWIP_MIN(data_len, crlfcrlf + 4 - hdr_start_after_uri);
+          u8_t post_auto_wnd = 1;
+          http_uri_buf[0] = 0;
+          /* trim http header */
+          *crlfcrlf = 0;
+          err = httpd_post_begin(hs, uri, hdr_start_after_uri, hdr_data_len, content_len,
+                                 http_uri_buf, LWIP_HTTPD_URI_BUF_LEN, &post_auto_wnd);
+          if (err == ERR_OK) {
+            /* try to pass in data of the first pbuf(s) */
+            struct pbuf *q = inp;
+            u16_t start_offset = hdr_len;
+#if LWIP_HTTPD_POST_MANUAL_WND
+            hs->no_auto_wnd = !post_auto_wnd;
+#endif /* LWIP_HTTPD_POST_MANUAL_WND */
+            /* set the Content-Length to be received for this POST */
+            hs->post_content_len_left = (u32_t)content_len;
+
+            /* get to the pbuf where the body starts */
+            while ((q != NULL) && (q->len <= start_offset)) {
+              start_offset -= q->len;
+              q = q->next;
+            }
+            if (q != NULL) {
+              /* hide the remaining HTTP header */
+              pbuf_remove_header(q, start_offset);
+#if LWIP_HTTPD_POST_MANUAL_WND
+              if (!post_auto_wnd) {
+                /* already tcp_recved() this data... */
+                hs->unrecved_bytes = q->tot_len;
+              }
+#endif /* LWIP_HTTPD_POST_MANUAL_WND */
+              pbuf_ref(q);
+              return http_post_rxpbuf(hs, q);
+            } else if (hs->post_content_len_left == 0) {
+              q = pbuf_alloc(PBUF_RAW, 0, PBUF_REF);
+              return http_post_rxpbuf(hs, q);
+            } else {
+              return ERR_OK;
+            }
+          } else {
+            /* return file passed from application */
+            return http_find_file(hs, http_uri_buf, 0);
+          }
+        } else {
+          LWIP_DEBUGF(HTTPD_DEBUG, ("POST received invalid Content-Length: %s\n",
+                                    content_len_num));
+          return ERR_ARG;
+        }
+      }
+    }
+    /* If we come here, headers are fully received (double-crlf), but Content-Length
+       was not included. Since this is currently the only supported method, we have
+       to fail in this case! */
+    LWIP_DEBUGF(HTTPD_DEBUG, ("Error when parsing Content-Length\n"));
+    return ERR_ARG;
+  }
+  /* if we come here, the POST is incomplete */
+#if LWIP_HTTPD_SUPPORT_REQUESTLIST
+  return ERR_INPROGRESS;
+#else /* LWIP_HTTPD_SUPPORT_REQUESTLIST */
+  return ERR_ARG;
+#endif /* LWIP_HTTPD_SUPPORT_REQUESTLIST */
+}
+
+#if LWIP_HTTPD_POST_MANUAL_WND
+/**
+ * @ingroup httpd
+ * A POST implementation can call this function to update the TCP window.
+ * This can be used to throttle data reception (e.g. when received data is
+ * programmed to flash and data is received faster than programmed).
+ *
+ * @param connection A connection handle passed to httpd_post_begin for which
+ *        httpd_post_finished has *NOT* been called yet!
+ * @param recved_len Length of data received (for window update)
+ */
+void httpd_post_data_recved(void *connection, u16_t recved_len)
+{
+  struct http_state *hs = (struct http_state *)connection;
+  if (hs != NULL) {
+    if (hs->no_auto_wnd) {
+      u16_t len = recved_len;
+      if (hs->unrecved_bytes >= recved_len) {
+        hs->unrecved_bytes -= recved_len;
+      } else {
+        LWIP_DEBUGF(HTTPD_DEBUG | LWIP_DBG_LEVEL_WARNING, ("httpd_post_data_recved: recved_len too big\n"));
+        len = (u16_t)hs->unrecved_bytes;
+        hs->unrecved_bytes = 0;
+      }
+      if (hs->pcb != NULL) {
+        if (len != 0) {
+          altcp_recved(hs->pcb, len);
+        }
+        if ((hs->post_content_len_left == 0) && (hs->unrecved_bytes == 0)) {
+          /* finished handling POST */
+          http_handle_post_finished(hs);
+          http_send(hs->pcb, hs);
+        }
+      }
+    }
+  }
+}
+#endif /* LWIP_HTTPD_POST_MANUAL_WND */
+
+#endif /* LWIP_HTTPD_SUPPORT_POST */
+
+#if LWIP_HTTPD_FS_ASYNC_READ
+/** Try to send more data if file has been blocked before
+ * This is a callback function passed to fs_read_async().
+ */
+static void
+http_continue(void *connection)
+{
+  struct http_state *hs = (struct http_state *)connection;
+  LWIP_ASSERT_CORE_LOCKED();
+  if (hs && (hs->pcb) && (hs->handle)) {
+    LWIP_ASSERT("hs->pcb != NULL", hs->pcb != NULL);
+    LWIP_DEBUGF(HTTPD_DEBUG | LWIP_DBG_TRACE, ("httpd_continue: try to send more data\n"));
+    if (http_send(hs->pcb, hs)) {
+      /* If we wrote anything to be sent, go ahead and send it now. */
+      LWIP_DEBUGF(HTTPD_DEBUG | LWIP_DBG_TRACE, ("tcp_output\n"));
+      altcp_output(hs->pcb);
+    }
+  }
+}
+#endif /* LWIP_HTTPD_FS_ASYNC_READ */
+
+/**
+ * When data has been received in the correct state, try to parse it
+ * as a HTTP request.
+ *
+ * @param inp the received pbuf
+ * @param hs the connection state
+ * @param pcb the altcp_pcb which received this packet
+ * @return ERR_OK if request was OK and hs has been initialized correctly
+ *         ERR_INPROGRESS if request was OK so far but not fully received
+ *         another err_t otherwise
+ */
+static err_t
+http_parse_request(struct pbuf *inp, struct http_state *hs, struct altcp_pcb *pcb)
+{
+  char *data;
+  char *crlf;
+  u16_t data_len;
+  struct pbuf *p = inp;
+#if LWIP_HTTPD_SUPPORT_REQUESTLIST
+  u16_t clen;
+#endif /* LWIP_HTTPD_SUPPORT_REQUESTLIST */
+#if LWIP_HTTPD_SUPPORT_POST
+  err_t err;
+#endif /* LWIP_HTTPD_SUPPORT_POST */
+
+  LWIP_UNUSED_ARG(pcb); /* only used for post */
+  LWIP_ASSERT("p != NULL", p != NULL);
+  LWIP_ASSERT("hs != NULL", hs != NULL);
+
+  if ((hs->handle != NULL) || (hs->file != NULL)) {
+    LWIP_DEBUGF(HTTPD_DEBUG, ("Received data while sending a file\n"));
+    /* already sending a file */
+    /* @todo: abort? */
+    return ERR_USE;
+  }
+
+#if LWIP_HTTPD_SUPPORT_REQUESTLIST
+
+  LWIP_DEBUGF(HTTPD_DEBUG, ("Received %"U16_F" bytes\n", p->tot_len));
+
+  /* first check allowed characters in this pbuf? */
+
+  /* enqueue the pbuf */
+  if (hs->req == NULL) {
+    LWIP_DEBUGF(HTTPD_DEBUG, ("First pbuf\n"));
+    hs->req = p;
+  } else {
+    LWIP_DEBUGF(HTTPD_DEBUG, ("pbuf enqueued\n"));
+    pbuf_cat(hs->req, p);
+  }
+  /* increase pbuf ref counter as it is freed when we return but we want to
+     keep it on the req list */
+  pbuf_ref(p);
+
+  if (hs->req->next != NULL) {
+    data_len = LWIP_MIN(hs->req->tot_len, LWIP_HTTPD_MAX_REQ_LENGTH);
+    pbuf_copy_partial(hs->req, httpd_req_buf, data_len, 0);
+    data = httpd_req_buf;
+  } else
+#endif /* LWIP_HTTPD_SUPPORT_REQUESTLIST */
+  {
+    data = (char *)p->payload;
+    data_len = p->len;
+    if (p->len != p->tot_len) {
+      LWIP_DEBUGF(HTTPD_DEBUG, ("Warning: incomplete header due to chained pbufs\n"));
+    }
+  }
+
+  /* received enough data for minimal request? */
+  if (data_len >= MIN_REQ_LEN) {
+    /* wait for CRLF before parsing anything */
+    crlf = lwip_strnstr(data, CRLF, data_len);
+    if (crlf != NULL) {
+#if LWIP_HTTPD_SUPPORT_POST
+      int is_post = 0;
+#endif /* LWIP_HTTPD_SUPPORT_POST */
+      int is_09 = 0;
+      char *sp1, *sp2;
+      u16_t left_len, uri_len;
+      LWIP_DEBUGF(HTTPD_DEBUG | LWIP_DBG_TRACE, ("CRLF received, parsing request\n"));
+      /* parse method */
+      if (!strncmp(data, "GET ", 4)) {
+        sp1 = data + 3;
+        /* received GET request */
+        LWIP_DEBUGF(HTTPD_DEBUG | LWIP_DBG_TRACE, ("Received GET request\"\n"));
+#if LWIP_HTTPD_SUPPORT_POST
+      } else if (!strncmp(data, "POST ", 5)) {
+        /* store request type */
+        is_post = 1;
+        sp1 = data + 4;
+        /* received GET request */
+        LWIP_DEBUGF(HTTPD_DEBUG | LWIP_DBG_TRACE, ("Received POST request\n"));
+#endif /* LWIP_HTTPD_SUPPORT_POST */
+      } else {
+        /* null-terminate the METHOD (pbuf is freed anyway wen returning) */
+        data[4] = 0;
+        /* unsupported method! */
+        LWIP_DEBUGF(HTTPD_DEBUG, ("Unsupported request method (not implemented): \"%s\"\n",
+                                  data));
+        return http_find_error_file(hs, 501);
+      }
+      /* if we come here, method is OK, parse URI */
+      left_len = (u16_t)(data_len - ((sp1 + 1) - data));
+      sp2 = lwip_strnstr(sp1 + 1, " ", left_len);
+#if LWIP_HTTPD_SUPPORT_V09
+      if (sp2 == NULL) {
+        /* HTTP 0.9: respond with correct protocol version */
+        sp2 = lwip_strnstr(sp1 + 1, CRLF, left_len);
+        is_09 = 1;
+#if LWIP_HTTPD_SUPPORT_POST
+        if (is_post) {
+          /* HTTP/0.9 does not support POST */
+          goto badrequest;
+        }
+#endif /* LWIP_HTTPD_SUPPORT_POST */
+      }
+#endif /* LWIP_HTTPD_SUPPORT_V09 */
+      uri_len = (u16_t)(sp2 - (sp1 + 1));
+      if ((sp2 != 0) && (sp2 > sp1)) {
+        /* wait for CRLFCRLF (indicating end of HTTP headers) before parsing anything */
+        if (lwip_strnstr(data, CRLF CRLF, data_len) != NULL) {
+          char *uri = sp1 + 1;
+#if LWIP_HTTPD_SUPPORT_11_KEEPALIVE
+          /* This is HTTP/1.0 compatible: for strict 1.1, a connection
+             would always be persistent unless "close" was specified. */
+          if (!is_09 && (lwip_strnstr(data, HTTP11_CONNECTIONKEEPALIVE, data_len) ||
+                         lwip_strnstr(data, HTTP11_CONNECTIONKEEPALIVE2, data_len))) {
+            hs->keepalive = 1;
+          } else {
+            hs->keepalive = 0;
+          }
+#endif /* LWIP_HTTPD_SUPPORT_11_KEEPALIVE */
+          /* null-terminate the METHOD (pbuf is freed anyway wen returning) */
+          *sp1 = 0;
+          uri[uri_len] = 0;
+          LWIP_DEBUGF(HTTPD_DEBUG, ("Received \"%s\" request for URI: \"%s\"\n",
+                                    data, uri));
+#if LWIP_HTTPD_SUPPORT_POST
+          if (is_post) {
+#if LWIP_HTTPD_SUPPORT_REQUESTLIST
+            struct pbuf *q = hs->req;
+#else /* LWIP_HTTPD_SUPPORT_REQUESTLIST */
+            struct pbuf *q = inp;
+#endif /* LWIP_HTTPD_SUPPORT_REQUESTLIST */
+            err = http_post_request(q, hs, data, data_len, uri, sp2);
+            if (err != ERR_OK) {
+              /* restore header for next try */
+              *sp1 = ' ';
+              *sp2 = ' ';
+              uri[uri_len] = ' ';
+            }
+            if (err == ERR_ARG) {
+              goto badrequest;
+            }
+            return err;
+          } else
+#endif /* LWIP_HTTPD_SUPPORT_POST */
+          {
+            return http_find_file(hs, uri, is_09);
+          }
+        }
+      } else {
+        LWIP_DEBUGF(HTTPD_DEBUG, ("invalid URI\n"));
+      }
+    }
+  }
+
+#if LWIP_HTTPD_SUPPORT_REQUESTLIST
+  clen = pbuf_clen(hs->req);
+  if ((hs->req->tot_len <= LWIP_HTTPD_REQ_BUFSIZE) &&
+      (clen <= LWIP_HTTPD_REQ_QUEUELEN)) {
+    /* request not fully received (too short or CRLF is missing) */
+    return ERR_INPROGRESS;
+  } else
+#endif /* LWIP_HTTPD_SUPPORT_REQUESTLIST */
+  {
+#if LWIP_HTTPD_SUPPORT_POST
+badrequest:
+#endif /* LWIP_HTTPD_SUPPORT_POST */
+    LWIP_DEBUGF(HTTPD_DEBUG, ("bad request\n"));
+    /* could not parse request */
+    return http_find_error_file(hs, 400);
+  }
+}
+
+#if LWIP_HTTPD_SSI && (LWIP_HTTPD_SSI_BY_FILE_EXTENSION == 1)
+/* Check if SSI should be parsed for this file/URL
+ * (With LWIP_HTTPD_SSI_BY_FILE_EXTENSION == 2, this function can be
+ * overridden by an external implementation.)
+ *
+ * @return 1 for SSI, 0 for standard files
+ */
+static u8_t
+http_uri_is_ssi(struct fs_file *file, const char *uri)
+{
+  size_t loop;
+  u8_t tag_check = 0;
+  if (file != NULL) {
+    /* See if we have been asked for an shtml file and, if so,
+        enable tag checking. */
+    const char *ext = NULL, *sub;
+    char *param = (char *)strstr(uri, "?");
+    if (param != NULL) {
+      /* separate uri from parameters for now, set back later */
+      *param = 0;
+    }
+    sub = uri;
+    ext = uri;
+    for (sub = strstr(sub, "."); sub != NULL; sub = strstr(sub, ".")) {
+      ext = sub;
+      sub++;
+    }
+    for (loop = 0; loop < NUM_SHTML_EXTENSIONS; loop++) {
+      if (!lwip_stricmp(ext, g_pcSSIExtensions[loop])) {
+        tag_check = 1;
+        break;
+      }
+    }
+    if (param != NULL) {
+      *param = '?';
+    }
+  }
+  return tag_check;
+}
+#endif /* LWIP_HTTPD_SSI */
+
+/** Try to find the file specified by uri and, if found, initialize hs
+ * accordingly.
+ *
+ * @param hs the connection state
+ * @param uri the HTTP header URI
+ * @param is_09 1 if the request is HTTP/0.9 (no HTTP headers in response)
+ * @return ERR_OK if file was found and hs has been initialized correctly
+ *         another err_t otherwise
+ */
+static err_t
+http_find_file(struct http_state *hs, const char *uri, int is_09)
+{
+  size_t loop;
+  struct fs_file *file = NULL;
+  char *params = NULL;
+  err_t err;
+#if LWIP_HTTPD_CGI
+  int i;
+#endif /* LWIP_HTTPD_CGI */
+#if !LWIP_HTTPD_SSI
+  const
+#endif /* !LWIP_HTTPD_SSI */
+  /* By default, assume we will not be processing server-side-includes tags */
+  u8_t tag_check = 0;
+
+  /* Have we been asked for the default file (in root or a directory) ? */
+#if LWIP_HTTPD_MAX_REQUEST_URI_LEN
+  size_t uri_len = strlen(uri);
+  if ((uri_len > 0) && (uri[uri_len - 1] == '/') &&
+      ((uri != http_uri_buf) || (uri_len == 1))) {
+    size_t copy_len = LWIP_MIN(sizeof(http_uri_buf) - 1, uri_len - 1);
+    if (copy_len > 0) {
+      MEMCPY(http_uri_buf, uri, copy_len);
+      http_uri_buf[copy_len] = 0;
+    }
+#else /* LWIP_HTTPD_MAX_REQUEST_URI_LEN */
+  if ((uri[0] == '/') &&  (uri[1] == 0)) {
+#endif /* LWIP_HTTPD_MAX_REQUEST_URI_LEN */
+    /* Try each of the configured default filenames until we find one
+       that exists. */
+    for (loop = 0; loop < NUM_DEFAULT_FILENAMES; loop++) {
+      const char *file_name;
+#if LWIP_HTTPD_MAX_REQUEST_URI_LEN
+      if (copy_len > 0) {
+        size_t len_left = sizeof(http_uri_buf) - copy_len - 1;
+        if (len_left > 0) {
+          size_t name_len = strlen(httpd_default_filenames[loop].name);
+          size_t name_copy_len = LWIP_MIN(len_left, name_len);
+          MEMCPY(&http_uri_buf[copy_len], httpd_default_filenames[loop].name, name_copy_len);
+          http_uri_buf[copy_len + name_copy_len] = 0;
+        }
+        file_name = http_uri_buf;
+      } else
+#endif /* LWIP_HTTPD_MAX_REQUEST_URI_LEN */
+      {
+        file_name = httpd_default_filenames[loop].name;
+      }
+      LWIP_DEBUGF(HTTPD_DEBUG | LWIP_DBG_TRACE, ("Looking for %s...\n", file_name));
+      err = fs_open(&hs->file_handle, file_name);
+      if (err == ERR_OK) {
+        uri = file_name;
+        file = &hs->file_handle;
+        LWIP_DEBUGF(HTTPD_DEBUG | LWIP_DBG_TRACE, ("Opened.\n"));
+#if LWIP_HTTPD_SSI
+        tag_check = httpd_default_filenames[loop].shtml;
+#endif /* LWIP_HTTPD_SSI */
+        break;
+      }
+    }
+  }
+  if (file == NULL) {
+    /* No - we've been asked for a specific file. */
+    /* First, isolate the base URI (without any parameters) */
+    params = (char *)strchr(uri, '?');
+    if (params != NULL) {
+      /* URI contains parameters. NULL-terminate the base URI */
+      *params = '\0';
+      params++;
+    }
+
+#if LWIP_HTTPD_CGI
+    http_cgi_paramcount = -1;
+    /* Does the base URI we have isolated correspond to a CGI handler? */
+    if (httpd_num_cgis && httpd_cgis) {
+      for (i = 0; i < httpd_num_cgis; i++) {
+        if (strcmp(uri, httpd_cgis[i].pcCGIName) == 0) {
+          /*
+           * We found a CGI that handles this URI so extract the
+           * parameters and call the handler.
+           */
+          http_cgi_paramcount = extract_uri_parameters(hs, params);
+          uri = httpd_cgis[i].pfnCGIHandler(i, http_cgi_paramcount, hs->params,
+                                         hs->param_vals);
+          break;
+        }
+      }
+    }
+#endif /* LWIP_HTTPD_CGI */
+
+    LWIP_DEBUGF(HTTPD_DEBUG | LWIP_DBG_TRACE, ("Opening %s\n", uri));
+
+    err = fs_open(&hs->file_handle, uri);
+    if (err == ERR_OK) {
+      file = &hs->file_handle;
+    } else {
+      file = http_get_404_file(hs, &uri);
+    }
+#if LWIP_HTTPD_SSI
+    if (file != NULL) {
+      if (file->flags & FS_FILE_FLAGS_SSI) {
+        tag_check = 1;
+      } else {
+#if LWIP_HTTPD_SSI_BY_FILE_EXTENSION
+        tag_check = http_uri_is_ssi(file, uri);
+#endif /* LWIP_HTTPD_SSI_BY_FILE_EXTENSION */
+      }
+    }
+#endif /* LWIP_HTTPD_SSI */
+  }
+  if (file == NULL) {
+    /* None of the default filenames exist so send back a 404 page */
+    file = http_get_404_file(hs, &uri);
+  }
+  return http_init_file(hs, file, is_09, uri, tag_check, params);
+}
+
+/** Initialize a http connection with a file to send (if found).
+ * Called by http_find_file and http_find_error_file.
+ *
+ * @param hs http connection state
+ * @param file file structure to send (or NULL if not found)
+ * @param is_09 1 if the request is HTTP/0.9 (no HTTP headers in response)
+ * @param uri the HTTP header URI
+ * @param tag_check enable SSI tag checking
+ * @param params != NULL if URI has parameters (separated by '?')
+ * @return ERR_OK if file was found and hs has been initialized correctly
+ *         another err_t otherwise
+ */
+static err_t
+http_init_file(struct http_state *hs, struct fs_file *file, int is_09, const char *uri,
+               u8_t tag_check, char *params)
+{
+#if !LWIP_HTTPD_SUPPORT_V09
+  LWIP_UNUSED_ARG(is_09);
+#endif
+  if (file != NULL) {
+    /* file opened, initialise struct http_state */
+#if !LWIP_HTTPD_DYNAMIC_FILE_READ
+    /* If dynamic read is disabled, file data must be in one piece and available now */
+    LWIP_ASSERT("file->data != NULL", file->data != NULL);
+#endif
+
+#if LWIP_HTTPD_SSI
+    if (tag_check) {
+      struct http_ssi_state *ssi = http_ssi_state_alloc();
+      if (ssi != NULL) {
+        ssi->tag_index = 0;
+        ssi->tag_state = TAG_NONE;
+        ssi->parsed = file->data;
+        ssi->parse_left = file->len;
+        ssi->tag_end = file->data;
+        hs->ssi = ssi;
+      }
+    }
+#else /* LWIP_HTTPD_SSI */
+    LWIP_UNUSED_ARG(tag_check);
+#endif /* LWIP_HTTPD_SSI */
+    hs->handle = file;
+#if LWIP_HTTPD_CGI_SSI
+    if (params != NULL) {
+      /* URI contains parameters, call generic CGI handler */
+      int count;
+#if LWIP_HTTPD_CGI
+      if (http_cgi_paramcount >= 0) {
+        count = http_cgi_paramcount;
+      } else
+#endif
+      {
+        count = extract_uri_parameters(hs, params);
+      }
+      httpd_cgi_handler(file, uri, count, http_cgi_params, http_cgi_param_vals
+#if defined(LWIP_HTTPD_FILE_STATE) && LWIP_HTTPD_FILE_STATE
+                        , file->state
+#endif /* LWIP_HTTPD_FILE_STATE */
+                       );
+    }
+#else /* LWIP_HTTPD_CGI_SSI */
+    LWIP_UNUSED_ARG(params);
+#endif /* LWIP_HTTPD_CGI_SSI */
+    hs->file = file->data;
+    LWIP_ASSERT("File length must be positive!", (file->len >= 0));
+#if LWIP_HTTPD_CUSTOM_FILES
+    if (file->is_custom_file && (file->data == NULL)) {
+      /* custom file, need to read data first (via fs_read_custom) */
+      hs->left = 0;
+    } else
+#endif /* LWIP_HTTPD_CUSTOM_FILES */
+    {
+      hs->left = (u32_t)file->len;
+    }
+    hs->retries = 0;
+#if LWIP_HTTPD_TIMING
+    hs->time_started = sys_now();
+#endif /* LWIP_HTTPD_TIMING */
+#if !LWIP_HTTPD_DYNAMIC_HEADERS
+    LWIP_ASSERT("HTTP headers not included in file system",
+                (hs->handle->flags & FS_FILE_FLAGS_HEADER_INCLUDED) != 0);
+#endif /* !LWIP_HTTPD_DYNAMIC_HEADERS */
+#if LWIP_HTTPD_SUPPORT_V09
+    if (is_09 && ((hs->handle->flags & FS_FILE_FLAGS_HEADER_INCLUDED) != 0)) {
+      /* HTTP/0.9 responses are sent without HTTP header,
+         search for the end of the header. */
+      char *file_start = lwip_strnstr(hs->file, CRLF CRLF, hs->left);
+      if (file_start != NULL) {
+        int diff = file_start + 4 - hs->file;
+        hs->file += diff;
+        hs->left -= (u32_t)diff;
+      }
+    }
+#endif /* LWIP_HTTPD_SUPPORT_V09*/
+  } else {
+    hs->handle = NULL;
+    hs->file = NULL;
+    hs->left = 0;
+    hs->retries = 0;
+  }
+#if LWIP_HTTPD_DYNAMIC_HEADERS
+  /* Determine the HTTP headers to send based on the file extension of
+   * the requested URI. */
+  if ((hs->handle == NULL) || ((hs->handle->flags & FS_FILE_FLAGS_HEADER_INCLUDED) == 0)) {
+    get_http_headers(hs, uri);
+  }
+#else /* LWIP_HTTPD_DYNAMIC_HEADERS */
+  LWIP_UNUSED_ARG(uri);
+#endif /* LWIP_HTTPD_DYNAMIC_HEADERS */
+#if LWIP_HTTPD_SUPPORT_11_KEEPALIVE
+  if (hs->keepalive) {
+#if LWIP_HTTPD_SSI
+    if (hs->ssi != NULL) {
+      hs->keepalive = 0;
+    } else
+#endif /* LWIP_HTTPD_SSI */
+    {
+      if ((hs->handle != NULL) &&
+          ((hs->handle->flags & (FS_FILE_FLAGS_HEADER_INCLUDED | FS_FILE_FLAGS_HEADER_PERSISTENT)) == FS_FILE_FLAGS_HEADER_INCLUDED)) {
+        hs->keepalive = 0;
+      }
+    }
+  }
+#endif /* LWIP_HTTPD_SUPPORT_11_KEEPALIVE */
+  return ERR_OK;
+}
+
+/**
+ * The pcb had an error and is already deallocated.
+ * The argument might still be valid (if != NULL).
+ */
+static void
+http_err(void *arg, err_t err)
+{
+  struct http_state *hs = (struct http_state *)arg;
+  LWIP_UNUSED_ARG(err);
+
+  LWIP_DEBUGF(HTTPD_DEBUG, ("http_err: %s", lwip_strerr(err)));
+
+  if (hs != NULL) {
+    http_state_free(hs);
+  }
+}
+
+/**
+ * Data has been sent and acknowledged by the remote host.
+ * This means that more data can be sent.
+ */
+static err_t
+http_sent(void *arg, struct altcp_pcb *pcb, u16_t len)
+{
+  struct http_state *hs = (struct http_state *)arg;
+
+  LWIP_DEBUGF(HTTPD_DEBUG | LWIP_DBG_TRACE, ("http_sent %p\n", (void *)pcb));
+
+  LWIP_UNUSED_ARG(len);
+
+  if (hs == NULL) {
+    return ERR_OK;
+  }
+
+  hs->retries = 0;
+
+  http_send(pcb, hs);
+
+  return ERR_OK;
+}
+
+/**
+ * The poll function is called every 2nd second.
+ * If there has been no data sent (which resets the retries) in 8 seconds, close.
+ * If the last portion of a file has not been sent in 2 seconds, close.
+ *
+ * This could be increased, but we don't want to waste resources for bad connections.
+ */
+static err_t
+http_poll(void *arg, struct altcp_pcb *pcb)
+{
+  struct http_state *hs = (struct http_state *)arg;
+  LWIP_DEBUGF(HTTPD_DEBUG | LWIP_DBG_TRACE, ("http_poll: pcb=%p hs=%p pcb_state=%s\n",
+              (void *)pcb, (void *)hs, tcp_debug_state_str(altcp_dbg_get_tcp_state(pcb))));
+
+  if (hs == NULL) {
+    err_t closed;
+    /* arg is null, close. */
+    LWIP_DEBUGF(HTTPD_DEBUG, ("http_poll: arg is NULL, close\n"));
+    closed = http_close_conn(pcb, NULL);
+    LWIP_UNUSED_ARG(closed);
+#if LWIP_HTTPD_ABORT_ON_CLOSE_MEM_ERROR
+    if (closed == ERR_MEM) {
+      altcp_abort(pcb);
+      return ERR_ABRT;
+    }
+#endif /* LWIP_HTTPD_ABORT_ON_CLOSE_MEM_ERROR */
+    return ERR_OK;
+  } else {
+    hs->retries++;
+    if (hs->retries == HTTPD_MAX_RETRIES) {
+      LWIP_DEBUGF(HTTPD_DEBUG, ("http_poll: too many retries, close\n"));
+      http_close_conn(pcb, hs);
+      return ERR_OK;
+    }
+
+    /* If this connection has a file open, try to send some more data. If
+     * it has not yet received a GET request, don't do this since it will
+     * cause the connection to close immediately. */
+    if (hs->handle) {
+      LWIP_DEBUGF(HTTPD_DEBUG | LWIP_DBG_TRACE, ("http_poll: try to send more data\n"));
+      if (http_send(pcb, hs)) {
+        /* If we wrote anything to be sent, go ahead and send it now. */
+        LWIP_DEBUGF(HTTPD_DEBUG | LWIP_DBG_TRACE, ("tcp_output\n"));
+        altcp_output(pcb);
+      }
+    }
+  }
+
+  return ERR_OK;
+}
+
+/**
+ * Data has been received on this pcb.
+ * For HTTP 1.0, this should normally only happen once (if the request fits in one packet).
+ */
+static err_t
+http_recv(void *arg, struct altcp_pcb *pcb, struct pbuf *p, err_t err)
+{
+  struct http_state *hs = (struct http_state *)arg;
+  LWIP_DEBUGF(HTTPD_DEBUG | LWIP_DBG_TRACE, ("http_recv: pcb=%p pbuf=%p err=%s\n", (void *)pcb,
+              (void *)p, lwip_strerr(err)));
+
+  if ((err != ERR_OK) || (p == NULL) || (hs == NULL)) {
+    /* error or closed by other side? */
+    if (p != NULL) {
+      /* Inform TCP that we have taken the data. */
+      altcp_recved(pcb, p->tot_len);
+      pbuf_free(p);
+    }
+    if (hs == NULL) {
+      /* this should not happen, only to be robust */
+      LWIP_DEBUGF(HTTPD_DEBUG, ("Error, http_recv: hs is NULL, close\n"));
+    }
+    http_close_conn(pcb, hs);
+    return ERR_OK;
+  }
+
+#if LWIP_HTTPD_SUPPORT_POST && LWIP_HTTPD_POST_MANUAL_WND
+  if (hs->no_auto_wnd) {
+    hs->unrecved_bytes += p->tot_len;
+  } else
+#endif /* LWIP_HTTPD_SUPPORT_POST && LWIP_HTTPD_POST_MANUAL_WND */
+  {
+    /* Inform TCP that we have taken the data. */
+    altcp_recved(pcb, p->tot_len);
+  }
+
+#if LWIP_HTTPD_SUPPORT_POST
+  if (hs->post_content_len_left > 0) {
+    /* reset idle counter when POST data is received */
+    hs->retries = 0;
+    /* this is data for a POST, pass the complete pbuf to the application */
+    http_post_rxpbuf(hs, p);
+    /* pbuf is passed to the application, don't free it! */
+    if (hs->post_content_len_left == 0) {
+      /* all data received, send response or close connection */
+      http_send(pcb, hs);
+    }
+    return ERR_OK;
+  } else
+#endif /* LWIP_HTTPD_SUPPORT_POST */
+  {
+    if (hs->handle == NULL) {
+      err_t parsed = http_parse_request(p, hs, pcb);
+      LWIP_ASSERT("http_parse_request: unexpected return value", parsed == ERR_OK
+                  || parsed == ERR_INPROGRESS || parsed == ERR_ARG || parsed == ERR_USE);
+#if LWIP_HTTPD_SUPPORT_REQUESTLIST
+      if (parsed != ERR_INPROGRESS) {
+        /* request fully parsed or error */
+        if (hs->req != NULL) {
+          pbuf_free(hs->req);
+          hs->req = NULL;
+        }
+      }
+#endif /* LWIP_HTTPD_SUPPORT_REQUESTLIST */
+      pbuf_free(p);
+      if (parsed == ERR_OK) {
+#if LWIP_HTTPD_SUPPORT_POST
+        if (hs->post_content_len_left == 0)
+#endif /* LWIP_HTTPD_SUPPORT_POST */
+        {
+          LWIP_DEBUGF(HTTPD_DEBUG | LWIP_DBG_TRACE, ("http_recv: data %p len %"S32_F"\n", (const void *)hs->file, hs->left));
+          http_send(pcb, hs);
+        }
+      } else if (parsed == ERR_ARG) {
+        /* @todo: close on ERR_USE? */
+        http_close_conn(pcb, hs);
+      }
+    } else {
+      LWIP_DEBUGF(HTTPD_DEBUG, ("http_recv: already sending data\n"));
+      /* already sending but still receiving data, we might want to RST here? */
+      pbuf_free(p);
+    }
+  }
+  return ERR_OK;
+}
+
+/**
+ * A new incoming connection has been accepted.
+ */
+static err_t
+http_accept(void *arg, struct altcp_pcb *pcb, err_t err)
+{
+  struct http_state *hs;
+  LWIP_UNUSED_ARG(err);
+  LWIP_UNUSED_ARG(arg);
+  LWIP_DEBUGF(HTTPD_DEBUG, ("http_accept %p / %p\n", (void *)pcb, arg));
+
+  if ((err != ERR_OK) || (pcb == NULL)) {
+    return ERR_VAL;
+  }
+
+  /* Set priority */
+  altcp_setprio(pcb, HTTPD_TCP_PRIO);
+
+  /* Allocate memory for the structure that holds the state of the
+     connection - initialized by that function. */
+  hs = http_state_alloc();
+  if (hs == NULL) {
+    LWIP_DEBUGF(HTTPD_DEBUG, ("http_accept: Out of memory, RST\n"));
+    return ERR_MEM;
+  }
+  hs->pcb = pcb;
+
+  /* Tell TCP that this is the structure we wish to be passed for our
+     callbacks. */
+  altcp_arg(pcb, hs);
+
+  /* Set up the various callback functions */
+  altcp_recv(pcb, http_recv);
+  altcp_err(pcb, http_err);
+  altcp_poll(pcb, http_poll, HTTPD_POLL_INTERVAL);
+  altcp_sent(pcb, http_sent);
+
+  return ERR_OK;
+}
+
+static void
+httpd_init_pcb(struct altcp_pcb *pcb, u16_t port)
+{
+  err_t err;
+
+  if (pcb) {
+    altcp_setprio(pcb, HTTPD_TCP_PRIO);
+    /* set SOF_REUSEADDR here to explicitly bind httpd to multiple interfaces */
+    err = altcp_bind(pcb, IP_ANY_TYPE, port);
+    LWIP_UNUSED_ARG(err); /* in case of LWIP_NOASSERT */
+    LWIP_ASSERT("httpd_init: tcp_bind failed", err == ERR_OK);
+    pcb = altcp_listen(pcb);
+    LWIP_ASSERT("httpd_init: tcp_listen failed", pcb != NULL);
+    altcp_accept(pcb, http_accept);
+  }
+}
+
+/**
+ * @ingroup httpd
+ * Initialize the httpd: set up a listening PCB and bind it to the defined port
+ */
+void
+httpd_init(void)
+{
+  struct altcp_pcb *pcb;
+
+#if HTTPD_USE_MEM_POOL
+  LWIP_MEMPOOL_INIT(HTTPD_STATE);
+#if LWIP_HTTPD_SSI
+  LWIP_MEMPOOL_INIT(HTTPD_SSI_STATE);
+#endif
+#endif
+  LWIP_DEBUGF(HTTPD_DEBUG, ("httpd_init\n"));
+
+  /* LWIP_ASSERT_CORE_LOCKED(); is checked by tcp_new() */
+
+  pcb = altcp_tcp_new_ip_type(IPADDR_TYPE_ANY);
+  LWIP_ASSERT("httpd_init: tcp_new failed", pcb != NULL);
+  httpd_init_pcb(pcb, HTTPD_SERVER_PORT);
+}
+
+#if HTTPD_ENABLE_HTTPS
+/**
+ * @ingroup httpd
+ * Initialize the httpd: set up a listening PCB and bind it to the defined port.
+ * Also set up TLS connection handling (HTTPS).
+ */
+void
+httpd_inits(struct altcp_tls_config *conf)
+{
+#if LWIP_ALTCP_TLS
+  struct altcp_pcb *pcb_tls = altcp_tls_new(conf, IPADDR_TYPE_ANY);
+  LWIP_ASSERT("httpd_init: altcp_tls_new failed", pcb_tls != NULL);
+  httpd_init_pcb(pcb_tls, HTTPD_SERVER_PORT_HTTPS);
+#else /* LWIP_ALTCP_TLS */
+  LWIP_UNUSED_ARG(conf);
+#endif /* LWIP_ALTCP_TLS */
+}
+#endif /* HTTPD_ENABLE_HTTPS */
+
+#if LWIP_HTTPD_SSI
+/**
+ * @ingroup httpd
+ * Set the SSI handler function.
+ *
+ * @param ssi_handler the SSI handler function
+ * @param tags an array of SSI tag strings to search for in SSI-enabled files
+ * @param num_tags number of tags in the 'tags' array
+ */
+void
+http_set_ssi_handler(tSSIHandler ssi_handler, const char **tags, int num_tags)
+{
+  LWIP_DEBUGF(HTTPD_DEBUG, ("http_set_ssi_handler\n"));
+
+  LWIP_ASSERT("no ssi_handler given", ssi_handler != NULL);
+  httpd_ssi_handler = ssi_handler;
+
+#if LWIP_HTTPD_SSI_RAW
+  LWIP_UNUSED_ARG(tags);
+  LWIP_UNUSED_ARG(num_tags);
+#else /* LWIP_HTTPD_SSI_RAW */
+  LWIP_ASSERT("no tags given", tags != NULL);
+  LWIP_ASSERT("invalid number of tags", num_tags > 0);
+
+  httpd_tags = tags;
+  httpd_num_tags = num_tags;
+#endif /* !LWIP_HTTPD_SSI_RAW */
+}
+#endif /* LWIP_HTTPD_SSI */
+
+#if LWIP_HTTPD_CGI
+/**
+ * @ingroup httpd
+ * Set an array of CGI filenames/handler functions
+ *
+ * @param cgis an array of CGI filenames/handler functions
+ * @param num_handlers number of elements in the 'cgis' array
+ */
+void
+http_set_cgi_handlers(const tCGI *cgis, int num_handlers)
+{
+  LWIP_ASSERT("no cgis given", cgis != NULL);
+  LWIP_ASSERT("invalid number of handlers", num_handlers > 0);
+
+  httpd_cgis = cgis;
+  httpd_num_cgis = num_handlers;
+}
+#endif /* LWIP_HTTPD_CGI */
+
+#endif /* LWIP_TCP && LWIP_CALLBACK_API */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/apps/http/httpd_structs.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/apps/http/httpd_structs.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/apps/http/httpd_structs.h	(revision 457)
@@ -0,0 +1,123 @@
+#ifndef LWIP_HTTPD_STRUCTS_H
+#define LWIP_HTTPD_STRUCTS_H
+
+#include "lwip/apps/httpd.h"
+
+#if LWIP_HTTPD_DYNAMIC_HEADERS
+/** This struct is used for a list of HTTP header strings for various
+ * filename extensions. */
+typedef struct {
+  const char *extension;
+  const char *content_type;
+} tHTTPHeader;
+
+/** A list of strings used in HTTP headers (see RFC 1945 HTTP/1.0 and
+ * RFC 2616 HTTP/1.1 for header field definitions) */
+static const char *const g_psHTTPHeaderStrings[] = {
+  "HTTP/1.0 200 OK\r\n",
+  "HTTP/1.0 404 File not found\r\n",
+  "HTTP/1.0 400 Bad Request\r\n",
+  "HTTP/1.0 501 Not Implemented\r\n",
+  "HTTP/1.1 200 OK\r\n",
+  "HTTP/1.1 404 File not found\r\n",
+  "HTTP/1.1 400 Bad Request\r\n",
+  "HTTP/1.1 501 Not Implemented\r\n",
+  "Content-Length: ",
+  "Connection: Close\r\n",
+  "Connection: keep-alive\r\n",
+  "Connection: keep-alive\r\nContent-Length: ",
+  "Server: "HTTPD_SERVER_AGENT"\r\n",
+  "\r\n<html><body><h2>404: The requested file cannot be found.</h2></body></html>\r\n"
+#if LWIP_HTTPD_SUPPORT_11_KEEPALIVE
+  , "Connection: keep-alive\r\nContent-Length: 77\r\n\r\n<html><body><h2>404: The requested file cannot be found.</h2></body></html>\r\n"
+#endif
+};
+
+/* Indexes into the g_psHTTPHeaderStrings array */
+#define HTTP_HDR_OK             0 /* 200 OK */
+#define HTTP_HDR_NOT_FOUND      1 /* 404 File not found */
+#define HTTP_HDR_BAD_REQUEST    2 /* 400 Bad request */
+#define HTTP_HDR_NOT_IMPL       3 /* 501 Not Implemented */
+#define HTTP_HDR_OK_11          4 /* 200 OK */
+#define HTTP_HDR_NOT_FOUND_11   5 /* 404 File not found */
+#define HTTP_HDR_BAD_REQUEST_11 6 /* 400 Bad request */
+#define HTTP_HDR_NOT_IMPL_11    7 /* 501 Not Implemented */
+#define HTTP_HDR_CONTENT_LENGTH 8 /* Content-Length: (HTTP 1.0)*/
+#define HTTP_HDR_CONN_CLOSE     9 /* Connection: Close (HTTP 1.1) */
+#define HTTP_HDR_CONN_KEEPALIVE 10 /* Connection: keep-alive (HTTP 1.1) */
+#define HTTP_HDR_KEEPALIVE_LEN  11 /* Connection: keep-alive + Content-Length: (HTTP 1.1)*/
+#define HTTP_HDR_SERVER         12 /* Server: HTTPD_SERVER_AGENT */
+#define DEFAULT_404_HTML        13 /* default 404 body */
+#if LWIP_HTTPD_SUPPORT_11_KEEPALIVE
+#define DEFAULT_404_HTML_PERSISTENT 14 /* default 404 body, but including Connection: keep-alive */
+#endif
+
+#define HTTP_CONTENT_TYPE(contenttype) "Content-Type: "contenttype"\r\n\r\n"
+#define HTTP_CONTENT_TYPE_ENCODING(contenttype, encoding) "Content-Type: "contenttype"\r\nContent-Encoding: "encoding"\r\n\r\n"
+
+#define HTTP_HDR_HTML           HTTP_CONTENT_TYPE("text/html")
+#define HTTP_HDR_SSI            HTTP_CONTENT_TYPE("text/html\r\nExpires: Fri, 10 Apr 2008 14:00:00 GMT\r\nPragma: no-cache")
+#define HTTP_HDR_GIF            HTTP_CONTENT_TYPE("image/gif")
+#define HTTP_HDR_PNG            HTTP_CONTENT_TYPE("image/png")
+#define HTTP_HDR_JPG            HTTP_CONTENT_TYPE("image/jpeg")
+#define HTTP_HDR_BMP            HTTP_CONTENT_TYPE("image/bmp")
+#define HTTP_HDR_ICO            HTTP_CONTENT_TYPE("image/x-icon")
+#define HTTP_HDR_APP            HTTP_CONTENT_TYPE("application/octet-stream")
+#define HTTP_HDR_JS             HTTP_CONTENT_TYPE("application/javascript")
+#define HTTP_HDR_RA             HTTP_CONTENT_TYPE("application/javascript")
+#define HTTP_HDR_CSS            HTTP_CONTENT_TYPE("text/css")
+#define HTTP_HDR_SWF            HTTP_CONTENT_TYPE("application/x-shockwave-flash")
+#define HTTP_HDR_XML            HTTP_CONTENT_TYPE("text/xml")
+#define HTTP_HDR_PDF            HTTP_CONTENT_TYPE("application/pdf")
+#define HTTP_HDR_JSON           HTTP_CONTENT_TYPE("application/json")
+#define HTTP_HDR_CSV            HTTP_CONTENT_TYPE("text/csv")
+#define HTTP_HDR_TSV            HTTP_CONTENT_TYPE("text/tsv")
+#define HTTP_HDR_SVG            HTTP_CONTENT_TYPE("image/svg+xml")
+#define HTTP_HDR_SVGZ           HTTP_CONTENT_TYPE_ENCODING("image/svg+xml", "gzip")
+
+#define HTTP_HDR_DEFAULT_TYPE   HTTP_CONTENT_TYPE("text/plain")
+
+/** A list of extension-to-HTTP header strings (see outdated RFC 1700 MEDIA TYPES
+ * and http://www.iana.org/assignments/media-types for registered content types
+ * and subtypes) */
+static const tHTTPHeader g_psHTTPHeaders[] = {
+  { "html", HTTP_HDR_HTML},
+  { "htm",  HTTP_HDR_HTML},
+  { "shtml", HTTP_HDR_SSI},
+  { "shtm", HTTP_HDR_SSI},
+  { "ssi",  HTTP_HDR_SSI},
+  { "gif",  HTTP_HDR_GIF},
+  { "png",  HTTP_HDR_PNG},
+  { "jpg",  HTTP_HDR_JPG},
+  { "bmp",  HTTP_HDR_BMP},
+  { "ico",  HTTP_HDR_ICO},
+  { "class", HTTP_HDR_APP},
+  { "cls",  HTTP_HDR_APP},
+  { "js",   HTTP_HDR_JS},
+  { "ram",  HTTP_HDR_RA},
+  { "css",  HTTP_HDR_CSS},
+  { "swf",  HTTP_HDR_SWF},
+  { "xml",  HTTP_HDR_XML},
+  { "xsl",  HTTP_HDR_XML},
+  { "pdf",  HTTP_HDR_PDF},
+  { "json", HTTP_HDR_JSON}
+#ifdef HTTPD_ADDITIONAL_CONTENT_TYPES
+  /* If you need to add content types not listed here:
+   * #define HTTPD_ADDITIONAL_CONTENT_TYPES {"ct1", HTTP_CONTENT_TYPE("text/ct1")}, {"exe", HTTP_CONTENT_TYPE("application/exe")}
+   */
+  , HTTPD_ADDITIONAL_CONTENT_TYPES
+#endif
+};
+
+#define NUM_HTTP_HEADERS LWIP_ARRAYSIZE(g_psHTTPHeaders)
+
+#endif /* LWIP_HTTPD_DYNAMIC_HEADERS */
+
+#if LWIP_HTTPD_SSI
+static const char *const g_pcSSIExtensions[] = {
+  ".shtml", ".shtm", ".ssi", ".xml", ".json"
+};
+#define NUM_SHTML_EXTENSIONS LWIP_ARRAYSIZE(g_pcSSIExtensions)
+#endif /* LWIP_HTTPD_SSI */
+
+#endif /* LWIP_HTTPD_STRUCTS_H */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/apps/http/makefsdata/makefsdata
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/apps/http/makefsdata/makefsdata	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/apps/http/makefsdata/makefsdata	(revision 457)
@@ -0,0 +1,97 @@
+#!/usr/bin/perl
+
+open(OUTPUT, "> fsdata.c");
+
+chdir("fs");
+open(FILES, "find . -type f |");
+
+while($file = <FILES>) {
+
+    # Do not include files in CVS directories nor backup files.
+    if($file =~ /(CVS|~)/) {
+    	next;
+    }
+    
+    chop($file);
+    
+    open(HEADER, "> /tmp/header") || die $!;
+    if($file =~ /404/) {
+	print(HEADER "HTTP/1.0 404 File not found\r\n");
+    } else {
+	print(HEADER "HTTP/1.0 200 OK\r\n");
+    }
+    print(HEADER "Server: lwIP/pre-0.6 (http://www.sics.se/~adam/lwip/)\r\n");
+    if($file =~ /\.html$/) {
+	print(HEADER "Content-type: text/html\r\n");
+    } elsif($file =~ /\.gif$/) {
+	print(HEADER "Content-type: image/gif\r\n");
+    } elsif($file =~ /\.png$/) {
+	print(HEADER "Content-type: image/png\r\n");
+    } elsif($file =~ /\.jpg$/) {
+	print(HEADER "Content-type: image/jpeg\r\n");
+    } elsif($file =~ /\.class$/) {
+	print(HEADER "Content-type: application/octet-stream\r\n");
+    } elsif($file =~ /\.ram$/) {
+	print(HEADER "Content-type: audio/x-pn-realaudio\r\n");    
+    } else {
+	print(HEADER "Content-type: text/plain\r\n");
+    }
+    print(HEADER "\r\n");
+    close(HEADER);
+
+    unless($file =~ /\.plain$/ || $file =~ /cgi/) {
+	system("cat /tmp/header $file > /tmp/file");
+    } else {
+	system("cp $file /tmp/file");
+    }
+    
+    open(FILE, "/tmp/file");
+    unlink("/tmp/file");
+    unlink("/tmp/header");
+
+    $file =~ s/\.//;
+    $fvar = $file;
+    $fvar =~ s-/-_-g;
+    $fvar =~ s-\.-_-g;
+    print(OUTPUT "static const unsigned char data".$fvar."[] = {\n");
+    print(OUTPUT "\t/* $file */\n\t");
+    for($j = 0; $j < length($file); $j++) {
+	printf(OUTPUT "%#02x, ", unpack("C", substr($file, $j, 1)));
+    }
+    printf(OUTPUT "0,\n");
+    
+    
+    $i = 0;
+    while(read(FILE, $data, 1)) {
+        if($i == 0) {
+            print(OUTPUT "\t");
+        }
+        printf(OUTPUT "%#02x, ", unpack("C", $data));
+        $i++;
+        if($i == 10) {
+            print(OUTPUT "\n");
+            $i = 0;
+        }
+    }
+    print(OUTPUT "};\n\n");
+    close(FILE);
+    push(@fvars, $fvar);
+    push(@files, $file);
+}
+
+for($i = 0; $i < @fvars; $i++) {
+    $file = $files[$i];
+    $fvar = $fvars[$i];
+
+    if($i == 0) {
+        $prevfile = "NULL";
+    } else {
+        $prevfile = "file" . $fvars[$i - 1];
+    }
+    print(OUTPUT "const struct fsdata_file file".$fvar."[] = {{$prevfile, data$fvar, ");
+    print(OUTPUT "data$fvar + ". (length($file) + 1) .", ");
+    print(OUTPUT "sizeof(data$fvar) - ". (length($file) + 1) ."}};\n\n");
+}
+
+print(OUTPUT "#define FS_ROOT file$fvars[$i - 1]\n\n");
+print(OUTPUT "#define FS_NUMFILES $i\n");
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/apps/http/makefsdata/makefsdata.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/apps/http/makefsdata/makefsdata.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/apps/http/makefsdata/makefsdata.c	(revision 457)
@@ -0,0 +1,1251 @@
+/**
+ * makefsdata: Converts a directory structure for use with the lwIP httpd.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Jim Pettinato
+ *         Simon Goldschmidt
+ *
+ * @todo:
+ * - take TCP_MSS, LWIP_TCP_TIMESTAMPS and
+ *   PAYLOAD_ALIGN_TYPE/PAYLOAD_ALIGNMENT as arguments
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include <sys/stat.h>
+
+#include "tinydir.h"
+
+/** Makefsdata can generate *all* files deflate-compressed (where file size shrinks).
+ * Since nearly all browsers support this, this is a good way to reduce ROM size.
+ * To compress the files, "miniz.c" must be downloaded seperately.
+ */
+#ifndef MAKEFS_SUPPORT_DEFLATE
+#define MAKEFS_SUPPORT_DEFLATE 0
+#endif
+
+#define COPY_BUFSIZE (1024*1024) /* 1 MByte */
+
+#if MAKEFS_SUPPORT_DEFLATE
+#include "../miniz.c"
+
+typedef unsigned char uint8;
+typedef unsigned short uint16;
+typedef unsigned int uint;
+
+#define my_max(a,b) (((a) > (b)) ? (a) : (b))
+#define my_min(a,b) (((a) < (b)) ? (a) : (b))
+
+/* COMP_OUT_BUF_SIZE is the size of the output buffer used during compression.
+   COMP_OUT_BUF_SIZE must be >= 1 and <= OUT_BUF_SIZE */
+#define COMP_OUT_BUF_SIZE COPY_BUFSIZE
+
+/* OUT_BUF_SIZE is the size of the output buffer used during decompression.
+   OUT_BUF_SIZE must be a power of 2 >= TINFL_LZ_DICT_SIZE (because the low-level decompressor not only writes, but reads from the output buffer as it decompresses) */
+#define OUT_BUF_SIZE COPY_BUFSIZE
+static uint8 s_outbuf[OUT_BUF_SIZE];
+static uint8 s_checkbuf[OUT_BUF_SIZE];
+
+/* tdefl_compressor contains all the state needed by the low-level compressor so it's a pretty big struct (~300k).
+   This example makes it a global vs. putting it on the stack, of course in real-world usage you'll probably malloc() or new it. */
+tdefl_compressor g_deflator;
+tinfl_decompressor g_inflator;
+
+int deflate_level = 10; /* default compression level, can be changed via command line */
+#define USAGE_ARG_DEFLATE " [-defl<:compr_level>]"
+#else /* MAKEFS_SUPPORT_DEFLATE */
+#define USAGE_ARG_DEFLATE ""
+#endif /* MAKEFS_SUPPORT_DEFLATE */
+
+#ifdef WIN32
+
+#define GETCWD(path, len)             GetCurrentDirectoryA(len, path)
+#define CHDIR(path)                   SetCurrentDirectoryA(path)
+#define CHDIR_SUCCEEDED(ret)          (ret == TRUE)
+
+#elif __linux__
+
+#define GETCWD(path, len)             getcwd(path, len)
+#define CHDIR(path)                   chdir(path)
+#define CHDIR_SUCCEEDED(ret)          (ret == 0)
+
+#else
+
+#error makefsdata not supported on this platform
+
+#endif
+
+#define NEWLINE     "\r\n"
+#define NEWLINE_LEN 2
+
+/* define this to get the header variables we use to build HTTP headers */
+#define LWIP_HTTPD_DYNAMIC_HEADERS 1
+#define LWIP_HTTPD_SSI             1
+#include "lwip/init.h"
+#include "../httpd_structs.h"
+#include "lwip/apps/fs.h"
+
+#include "../core/inet_chksum.c"
+#include "../core/def.c"
+
+/** (Your server name here) */
+const char *serverID = "Server: "HTTPD_SERVER_AGENT"\r\n";
+char serverIDBuffer[1024];
+
+/* change this to suit your MEM_ALIGNMENT */
+#define PAYLOAD_ALIGNMENT 4
+/* set this to 0 to prevent aligning payload */
+#define ALIGN_PAYLOAD 1
+/* define this to a type that has the required alignment */
+#define PAYLOAD_ALIGN_TYPE "unsigned int"
+static int payload_alingment_dummy_counter = 0;
+
+#define HEX_BYTES_PER_LINE 16
+
+#define MAX_PATH_LEN 256
+
+struct file_entry {
+  struct file_entry *next;
+  const char *filename_c;
+};
+
+int process_sub(FILE *data_file, FILE *struct_file);
+int process_file(FILE *data_file, FILE *struct_file, const char *filename);
+int file_write_http_header(FILE *data_file, const char *filename, int file_size, u16_t *http_hdr_len,
+                           u16_t *http_hdr_chksum, u8_t provide_content_len, int is_compressed);
+int file_put_ascii(FILE *file, const char *ascii_string, int len, int *i);
+int s_put_ascii(char *buf, const char *ascii_string, int len, int *i);
+void concat_files(const char *file1, const char *file2, const char *targetfile);
+int check_path(char *path, size_t size);
+static int checkSsiByFilelist(const char* filename_listfile);
+static int ext_in_list(const char* filename, const char *ext_list);
+static int file_to_exclude(const char* filename);
+static int file_can_be_compressed(const char* filename);
+
+/* 5 bytes per char + 3 bytes per line */
+static char file_buffer_c[COPY_BUFSIZE * 5 + ((COPY_BUFSIZE / HEX_BYTES_PER_LINE) * 3)];
+
+char curSubdir[MAX_PATH_LEN];
+char lastFileVar[MAX_PATH_LEN];
+char hdr_buf[4096];
+
+unsigned char processSubs = 1;
+unsigned char includeHttpHeader = 1;
+unsigned char useHttp11 = 0;
+unsigned char supportSsi = 1;
+unsigned char precalcChksum = 0;
+unsigned char includeLastModified = 0;
+#if MAKEFS_SUPPORT_DEFLATE
+unsigned char deflateNonSsiFiles = 0;
+size_t deflatedBytesReduced = 0;
+size_t overallDataBytes = 0;
+#endif
+const char *exclude_list = NULL;
+const char *ncompress_list = NULL;
+
+struct file_entry *first_file = NULL;
+struct file_entry *last_file = NULL;
+
+static char *ssi_file_buffer;
+static char **ssi_file_lines;
+static size_t ssi_file_num_lines;
+
+static void print_usage(void)
+{
+  printf(" Usage: htmlgen [targetdir] [-s] [-e] [-11] [-nossi] [-ssi:<filename>] [-c] [-f:<filename>] [-m] [-svr:<name>] [-x:<ext_list>] [-xc:<ext_list>" USAGE_ARG_DEFLATE NEWLINE NEWLINE);
+  printf("   targetdir: relative or absolute path to files to convert" NEWLINE);
+  printf("   switch -s: toggle processing of subdirectories (default is on)" NEWLINE);
+  printf("   switch -e: exclude HTTP header from file (header is created at runtime, default is off)" NEWLINE);
+  printf("   switch -11: include HTTP 1.1 header (1.0 is default)" NEWLINE);
+  printf("   switch -nossi: no support for SSI (cannot calculate Content-Length for SSI)" NEWLINE);
+  printf("   switch -ssi: ssi filename (ssi support controlled by file list, not by extension)" NEWLINE);
+  printf("   switch -c: precalculate checksums for all pages (default is off)" NEWLINE);
+  printf("   switch -f: target filename (default is \"fsdata.c\")" NEWLINE);
+  printf("   switch -m: include \"Last-Modified\" header based on file time" NEWLINE);
+  printf("   switch -svr: server identifier sent in HTTP response header ('Server' field)" NEWLINE);
+  printf("   switch -x: comma separated list of extensions of files to exclude (e.g., -x:json,txt)" NEWLINE);
+  printf("   switch -xc: comma separated list of extensions of files to not compress (e.g., -xc:mp3,jpg)" NEWLINE);
+#if MAKEFS_SUPPORT_DEFLATE
+  printf("   switch -defl: deflate-compress all non-SSI files (with opt. compr.-level, default=10)" NEWLINE);
+  printf("                 ATTENTION: browser has to support \"Content-Encoding: deflate\"!" NEWLINE);
+#endif
+  printf("   if targetdir not specified, htmlgen will attempt to" NEWLINE);
+  printf("   process files in subdirectory 'fs'" NEWLINE);
+}
+
+int main(int argc, char *argv[])
+{
+  char path[MAX_PATH_LEN];
+  char appPath[MAX_PATH_LEN];
+  FILE *data_file;
+  FILE *struct_file;
+  int filesProcessed;
+  int i;
+  char targetfile[MAX_PATH_LEN];
+  strcpy(targetfile, "fsdata.c");
+
+  memset(path, 0, sizeof(path));
+  memset(appPath, 0, sizeof(appPath));
+
+  printf(NEWLINE " makefsdata - HTML to C source converter" NEWLINE);
+  printf("     by Jim Pettinato               - circa 2003 " NEWLINE);
+  printf("     extended by Simon Goldschmidt  - 2009 " NEWLINE NEWLINE);
+
+  LWIP_ASSERT("sizeof(hdr_buf) must fit into an u16_t", sizeof(hdr_buf) <= 0xffff);
+
+  strcpy(path, "fs");
+  for (i = 1; i < argc; i++) {
+    if (argv[i] == NULL) {
+      continue;
+    }
+    if (argv[i][0] == '-') {
+      if (strstr(argv[i], "-svr:") == argv[i]) {
+        snprintf(serverIDBuffer, sizeof(serverIDBuffer), "Server: %s\r\n", &argv[i][5]);
+        serverID = serverIDBuffer;
+        printf("Using Server-ID: \"%s\"\n", serverID);
+      } else if (!strcmp(argv[i], "-s")) {
+        processSubs = 0;
+      } else if (!strcmp(argv[i], "-e")) {
+        includeHttpHeader = 0;
+      } else if (!strcmp(argv[i], "-11")) {
+        useHttp11 = 1;
+      } else if (!strcmp(argv[i], "-nossi")) {
+        supportSsi = 0;
+      } else if (strstr(argv[i], "-ssi:") == argv[i]) {
+        const char* ssi_list_filename = &argv[i][5];
+        if (checkSsiByFilelist(ssi_list_filename)) {
+          printf("Reading list of SSI files from \"%s\"\n", ssi_list_filename);
+        } else {
+          printf("Failed to load list of SSI files from \"%s\"\n", ssi_list_filename);
+        }
+      } else if (!strcmp(argv[i], "-c")) {
+        precalcChksum = 1;
+      } else if (strstr(argv[i], "-f:") == argv[i]) {
+        strncpy(targetfile, &argv[i][3], sizeof(targetfile) - 1);
+        targetfile[sizeof(targetfile) - 1] = 0;
+        printf("Writing to file \"%s\"\n", targetfile);
+      } else if (!strcmp(argv[i], "-m")) {
+        includeLastModified = 1;
+      } else if (!strcmp(argv[i], "-defl")) {
+#if MAKEFS_SUPPORT_DEFLATE
+        char *colon = strstr(argv[i], ":");
+        if (colon) {
+          if (colon[1] != 0) {
+            int defl_level = atoi(&colon[1]);
+            if ((defl_level >= 0) && (defl_level <= 10)) {
+              deflate_level = defl_level;
+            } else {
+              printf("ERROR: deflate level must be [0..10]" NEWLINE);
+              exit(0);
+            }
+          }
+        }
+        deflateNonSsiFiles = 1;
+        printf("Deflating all non-SSI files with level %d (but only if size is reduced)" NEWLINE, deflate_level);
+#else
+        printf("WARNING: Deflate support is disabled\n");
+#endif
+      } else if (strstr(argv[i], "-x:") == argv[i]) {
+        exclude_list = &argv[i][3];
+        printf("Excluding files with extensions %s" NEWLINE, exclude_list);
+      } else if (strstr(argv[i], "-xc:") == argv[i]) {
+        ncompress_list = &argv[i][4];
+        printf("Skipping compresion for files with extensions %s" NEWLINE, ncompress_list);
+      } else if ((strstr(argv[i], "-?")) || (strstr(argv[i], "-h"))) {
+        print_usage();
+        exit(0);
+      }
+    } else if ((argv[i][0] == '/') && (argv[i][1] == '?') && (argv[i][2] == 0)) {
+      print_usage();
+      exit(0);
+    } else {
+      strncpy(path, argv[i], sizeof(path) - 1);
+      path[sizeof(path) - 1] = 0;
+    }
+  }
+
+  if (!check_path(path, sizeof(path))) {
+    printf("Invalid path: \"%s\"." NEWLINE, path);
+    exit(-1);
+  }
+
+  GETCWD(appPath, MAX_PATH_LEN);
+  /* if command line param or subdir named 'fs' not found spout usage verbiage */
+  if (!CHDIR_SUCCEEDED(CHDIR(path))) {
+    /* if no subdir named 'fs' (or the one which was given) exists, spout usage verbiage */
+    printf(" Failed to open directory \"%s\"." NEWLINE NEWLINE, path);
+    print_usage();
+    exit(-1);
+  }
+  CHDIR(appPath);
+
+  printf("HTTP %sheader will %s statically included." NEWLINE,
+         (includeHttpHeader ? (useHttp11 ? "1.1 " : "1.0 ") : ""),
+         (includeHttpHeader ? "be" : "not be"));
+
+  curSubdir[0] = '\0'; /* start off in web page's root directory - relative paths */
+  printf("  Processing all files in directory %s", path);
+  if (processSubs) {
+    printf(" and subdirectories..." NEWLINE NEWLINE);
+  } else {
+    printf("..." NEWLINE NEWLINE);
+  }
+
+  data_file = fopen("fsdata.tmp", "wb");
+  if (data_file == NULL) {
+    printf("Failed to create file \"fsdata.tmp\"\n");
+    exit(-1);
+  }
+  struct_file = fopen("fshdr.tmp", "wb");
+  if (struct_file == NULL) {
+    printf("Failed to create file \"fshdr.tmp\"\n");
+    fclose(data_file);
+    exit(-1);
+  }
+
+  CHDIR(path);
+
+  fprintf(data_file, "#include \"lwip/apps/fs.h\"" NEWLINE);
+  fprintf(data_file, "#include \"lwip/def.h\"" NEWLINE NEWLINE NEWLINE);
+
+  fprintf(data_file, "#define file_NULL (struct fsdata_file *) NULL" NEWLINE NEWLINE NEWLINE);
+  /* define FS_FILE_FLAGS_HEADER_INCLUDED to 1 if not defined (compatibility with older httpd/fs) */
+  fprintf(data_file, "#ifndef FS_FILE_FLAGS_HEADER_INCLUDED" NEWLINE "#define FS_FILE_FLAGS_HEADER_INCLUDED 1" NEWLINE "#endif" NEWLINE);
+  /* define FS_FILE_FLAGS_HEADER_PERSISTENT to 0 if not defined (compatibility with older httpd/fs: wasn't supported back then) */
+  fprintf(data_file, "#ifndef FS_FILE_FLAGS_HEADER_PERSISTENT" NEWLINE "#define FS_FILE_FLAGS_HEADER_PERSISTENT 0" NEWLINE "#endif" NEWLINE);
+
+  /* define alignment defines */
+#if ALIGN_PAYLOAD
+  fprintf(data_file, "/* FSDATA_FILE_ALIGNMENT: 0=off, 1=by variable, 2=by include */" NEWLINE "#ifndef FSDATA_FILE_ALIGNMENT" NEWLINE "#define FSDATA_FILE_ALIGNMENT 0" NEWLINE "#endif" NEWLINE);
+#endif
+  fprintf(data_file, "#ifndef FSDATA_ALIGN_PRE"  NEWLINE "#define FSDATA_ALIGN_PRE"  NEWLINE "#endif" NEWLINE);
+  fprintf(data_file, "#ifndef FSDATA_ALIGN_POST" NEWLINE "#define FSDATA_ALIGN_POST" NEWLINE "#endif" NEWLINE);
+#if ALIGN_PAYLOAD
+  fprintf(data_file, "#if FSDATA_FILE_ALIGNMENT==2" NEWLINE "#include \"fsdata_alignment.h\"" NEWLINE "#endif" NEWLINE);
+#endif
+
+  sprintf(lastFileVar, "NULL");
+
+  filesProcessed = process_sub(data_file, struct_file);
+
+  /* data_file now contains all of the raw data.. now append linked list of
+   * file header structs to allow embedded app to search for a file name */
+  fprintf(data_file, NEWLINE NEWLINE);
+  fprintf(struct_file, "#define FS_ROOT file_%s" NEWLINE, lastFileVar);
+  fprintf(struct_file, "#define FS_NUMFILES %d" NEWLINE NEWLINE, filesProcessed);
+
+  fclose(data_file);
+  fclose(struct_file);
+
+  CHDIR(appPath);
+  /* append struct_file to data_file */
+  printf(NEWLINE "Creating target file..." NEWLINE NEWLINE);
+  concat_files("fsdata.tmp", "fshdr.tmp", targetfile);
+
+  /* if succeeded, delete the temporary files */
+  if (remove("fsdata.tmp") != 0) {
+    printf("Warning: failed to delete fsdata.tmp\n");
+  }
+  if (remove("fshdr.tmp") != 0) {
+    printf("Warning: failed to delete fshdr.tmp\n");
+  }
+
+  printf(NEWLINE "Processed %d files - done." NEWLINE, filesProcessed);
+#if MAKEFS_SUPPORT_DEFLATE
+  if (deflateNonSsiFiles) {
+    printf("(Deflated total byte reduction: %d bytes -> %d bytes (%.02f%%)" NEWLINE,
+           (int)overallDataBytes, (int)deflatedBytesReduced, (float)((deflatedBytesReduced * 100.0) / overallDataBytes));
+  }
+#endif
+  printf(NEWLINE);
+
+  while (first_file != NULL) {
+    struct file_entry *fe = first_file;
+    first_file = fe->next;
+    free(fe);
+  }
+
+  if (ssi_file_buffer) {
+    free(ssi_file_buffer);
+  }
+  if (ssi_file_lines) {
+    free(ssi_file_lines);
+  }
+
+  return 0;
+}
+
+int check_path(char *path, size_t size)
+{
+  size_t slen;
+  if (path[0] == 0) {
+    /* empty */
+    return 0;
+  }
+  slen = strlen(path);
+  if (slen >= size) {
+    /* not NULL-terminated */
+    return 0;
+  }
+  while ((slen > 0) && ((path[slen] == '\\') || (path[slen] == '/'))) {
+    /* path should not end with trailing backslash */
+    path[slen] = 0;
+    slen--;
+  }
+  if (slen == 0) {
+    return 0;
+  }
+  return 1;
+}
+
+static void copy_file(const char *filename_in, FILE *fout)
+{
+  FILE *fin;
+  size_t len;
+  void *buf;
+  fin = fopen(filename_in, "rb");
+  if (fin == NULL) {
+    printf("Failed to open file \"%s\"\n", filename_in);
+    exit(-1);
+  }
+  buf = malloc(COPY_BUFSIZE);
+  while ((len = fread(buf, 1, COPY_BUFSIZE, fin)) > 0) {
+    fwrite(buf, 1, len, fout);
+  }
+  free(buf);
+  fclose(fin);
+}
+
+void concat_files(const char *file1, const char *file2, const char *targetfile)
+{
+  FILE *fout;
+  fout = fopen(targetfile, "wb");
+  if (fout == NULL) {
+    printf("Failed to open file \"%s\"\n", targetfile);
+    exit(-1);
+  }
+  copy_file(file1, fout);
+  copy_file(file2, fout);
+  fclose(fout);
+}
+
+int process_sub(FILE *data_file, FILE *struct_file)
+{
+  tinydir_dir dir;
+  int filesProcessed = 0;
+
+  if (processSubs) {
+    /* process subs recursively */
+    size_t sublen = strlen(curSubdir);
+    size_t freelen = sizeof(curSubdir) - sublen - 1;
+    int ret;
+    LWIP_ASSERT("sublen < sizeof(curSubdir)", sublen < sizeof(curSubdir));
+
+    ret = tinydir_open_sorted(&dir, TINYDIR_STRING("."));
+
+    if (ret == 0) {
+      unsigned int i;
+      for (i = 0; i < dir.n_files; i++) {
+        tinydir_file file;
+
+        ret = tinydir_readfile_n(&dir, &file, i);
+
+        if (ret == 0) {
+#if (defined _MSC_VER || defined __MINGW32__) && (defined _UNICODE)
+          size_t num_char_converted;
+          char currName[256];
+          wcstombs_s(&num_char_converted, currName, sizeof(currName), file.name, sizeof(currName));
+#else
+          const char *currName = file.name;
+#endif
+
+          if (currName[0] == '.') {
+            continue;
+          }
+          if (!file.is_dir) {
+            continue;
+          }
+          if (freelen > 0) {
+            CHDIR(currName);
+            strncat(curSubdir, "/", freelen);
+            strncat(curSubdir, currName, freelen - 1);
+            curSubdir[sizeof(curSubdir) - 1] = 0;
+            printf("processing subdirectory %s/..." NEWLINE, curSubdir);
+            filesProcessed += process_sub(data_file, struct_file);
+            CHDIR("..");
+            curSubdir[sublen] = 0;
+          } else {
+            printf("WARNING: cannot process sub due to path length restrictions: \"%s/%s\"\n", curSubdir, currName);
+          }
+        }
+      }
+    }
+
+    ret = tinydir_open_sorted(&dir, TINYDIR_STRING("."));
+    if (ret == 0) {
+      unsigned int i;
+      for (i = 0; i < dir.n_files; i++) {
+        tinydir_file file;
+
+        ret = tinydir_readfile_n(&dir, &file, i);
+
+        if (ret == 0) {
+          if (!file.is_dir) {
+#if (defined _MSC_VER || defined __MINGW32__) && (defined _UNICODE)
+            size_t num_char_converted;
+            char curName[256];
+            wcstombs_s(&num_char_converted, curName, sizeof(curName), file.name, sizeof(curName));
+#else
+            const char *curName = file.name;
+#endif
+
+            if (strcmp(curName, "fsdata.tmp") == 0) {
+              continue;
+            }
+            if (strcmp(curName, "fshdr.tmp") == 0) {
+              continue;
+            }
+            if (file_to_exclude(curName)) {
+              printf("skipping %s/%s by exclude list (-x option)..." NEWLINE, curSubdir, curName);
+              continue;
+            }
+
+            printf("processing %s/%s..." NEWLINE, curSubdir, curName);
+
+            if (process_file(data_file, struct_file, curName) < 0) {
+              printf(NEWLINE "Error... aborting" NEWLINE);
+              return -1;
+            }
+            filesProcessed++;
+          }
+        }
+      }
+    }
+  }
+
+  return filesProcessed;
+}
+
+static u8_t *get_file_data(const char *filename, int *file_size, int can_be_compressed, int *is_compressed)
+{
+  FILE *inFile;
+  size_t fsize = 0;
+  u8_t *buf;
+  size_t r;
+  int rs;
+  LWIP_UNUSED_ARG(r); /* for LWIP_NOASSERT */
+  inFile = fopen(filename, "rb");
+  if (inFile == NULL) {
+    printf("Failed to open file \"%s\"\n", filename);
+    exit(-1);
+  }
+  fseek(inFile, 0, SEEK_END);
+  rs = ftell(inFile);
+  if (rs < 0) {
+    printf("ftell failed with %d\n", errno);
+    exit(-1);
+  }
+  fsize = (size_t)rs;
+  fseek(inFile, 0, SEEK_SET);
+  buf = (u8_t *)malloc(fsize);
+  LWIP_ASSERT("buf != NULL", buf != NULL);
+  r = fread(buf, 1, fsize, inFile);
+  LWIP_ASSERT("r == fsize", r == fsize);
+  *file_size = fsize;
+  *is_compressed = 0;
+#if MAKEFS_SUPPORT_DEFLATE
+  overallDataBytes += fsize;
+  if (deflateNonSsiFiles) {
+    if (can_be_compressed) {
+      if (fsize < OUT_BUF_SIZE) {
+        u8_t *ret_buf;
+        tdefl_status status;
+        size_t in_bytes = fsize;
+        size_t out_bytes = OUT_BUF_SIZE;
+        const void *next_in = buf;
+        void *next_out = s_outbuf;
+        /* create tdefl() compatible flags (we have to compose the low-level flags ourselves, or use tdefl_create_comp_flags_from_zip_params() but that means MINIZ_NO_ZLIB_APIS can't be defined). */
+        mz_uint comp_flags = s_tdefl_num_probes[MZ_MIN(10, deflate_level)] | ((deflate_level <= 3) ? TDEFL_GREEDY_PARSING_FLAG : 0);
+        if (!deflate_level) {
+          comp_flags |= TDEFL_FORCE_ALL_RAW_BLOCKS;
+        }
+        status = tdefl_init(&g_deflator, NULL, NULL, comp_flags);
+        if (status != TDEFL_STATUS_OKAY) {
+          printf("tdefl_init() failed!\n");
+          exit(-1);
+        }
+        memset(s_outbuf, 0, sizeof(s_outbuf));
+        status = tdefl_compress(&g_deflator, next_in, &in_bytes, next_out, &out_bytes, TDEFL_FINISH);
+        if (status != TDEFL_STATUS_DONE) {
+          printf("deflate failed: %d\n", status);
+          exit(-1);
+        }
+        LWIP_ASSERT("out_bytes <= COPY_BUFSIZE", out_bytes <= OUT_BUF_SIZE);
+        if (out_bytes < fsize) {
+          ret_buf = (u8_t *)malloc(out_bytes);
+          LWIP_ASSERT("ret_buf != NULL", ret_buf != NULL);
+          memcpy(ret_buf, s_outbuf, out_bytes);
+          {
+            /* sanity-check compression be inflating and comparing to the original */
+            tinfl_status dec_status;
+            tinfl_decompressor inflator;
+            size_t dec_in_bytes = out_bytes;
+            size_t dec_out_bytes = OUT_BUF_SIZE;
+            next_out = s_checkbuf;
+
+            tinfl_init(&inflator);
+            memset(s_checkbuf, 0, sizeof(s_checkbuf));
+            dec_status = tinfl_decompress(&inflator, (const mz_uint8 *)ret_buf, &dec_in_bytes, s_checkbuf, (mz_uint8 *)next_out, &dec_out_bytes, 0);
+            LWIP_ASSERT("tinfl_decompress failed", dec_status == TINFL_STATUS_DONE);
+            LWIP_ASSERT("tinfl_decompress size mismatch", fsize == dec_out_bytes);
+            LWIP_ASSERT("decompressed memcmp failed", !memcmp(s_checkbuf, buf, fsize));
+          }
+          /* free original buffer, use compressed data + size */
+          free(buf);
+          buf = ret_buf;
+          *file_size = out_bytes;
+          printf(" - deflate: %d bytes -> %d bytes (%.02f%%)" NEWLINE, (int)fsize, (int)out_bytes, (float)((out_bytes * 100.0) / fsize));
+          deflatedBytesReduced += (size_t)(fsize - out_bytes);
+          *is_compressed = 1;
+        } else {
+          printf(" - uncompressed: (would be %d bytes larger using deflate)" NEWLINE, (int)(out_bytes - fsize));
+        }
+      } else {
+        printf(" - uncompressed: (file is larger than deflate bufer)" NEWLINE);
+      }
+    } else {
+      printf(" - cannot be compressed" NEWLINE);
+    }
+  }
+#else
+  LWIP_UNUSED_ARG(can_be_compressed);
+#endif
+  fclose(inFile);
+  return buf;
+}
+
+static void process_file_data(FILE *data_file, u8_t *file_data, size_t file_size)
+{
+  size_t written, i, src_off = 0;
+  size_t off = 0;
+  LWIP_UNUSED_ARG(written); /* for LWIP_NOASSERT */
+  for (i = 0; i < file_size; i++) {
+    LWIP_ASSERT("file_buffer_c overflow", off < sizeof(file_buffer_c) - 5);
+    sprintf(&file_buffer_c[off], "0x%02x,", file_data[i]);
+    off += 5;
+    if ((++src_off % HEX_BYTES_PER_LINE) == 0) {
+      LWIP_ASSERT("file_buffer_c overflow", off < sizeof(file_buffer_c) - NEWLINE_LEN);
+      memcpy(&file_buffer_c[off], NEWLINE, NEWLINE_LEN);
+      off += NEWLINE_LEN;
+    }
+    if (off + 20 >= sizeof(file_buffer_c)) {
+      written = fwrite(file_buffer_c, 1, off, data_file);
+      LWIP_ASSERT("written == off", written == off);
+      off = 0;
+    }
+  }
+  written = fwrite(file_buffer_c, 1, off, data_file);
+  LWIP_ASSERT("written == off", written == off);
+}
+
+static int write_checksums(FILE *struct_file, const char *varname,
+                           u16_t hdr_len, u16_t hdr_chksum, const u8_t *file_data, size_t file_size)
+{
+  int chunk_size = TCP_MSS;
+  int offset, src_offset;
+  size_t len;
+  int i = 0;
+#if LWIP_TCP_TIMESTAMPS
+  /* when timestamps are used, usable space is 12 bytes less per segment */
+  chunk_size -= 12;
+#endif
+
+  fprintf(struct_file, "#if HTTPD_PRECALCULATED_CHECKSUM" NEWLINE);
+  fprintf(struct_file, "const struct fsdata_chksum chksums_%s[] = {" NEWLINE, varname);
+
+  if (hdr_len > 0) {
+    /* add checksum for HTTP header */
+    fprintf(struct_file, "{%d, 0x%04x, %d}," NEWLINE, 0, hdr_chksum, hdr_len);
+    i++;
+  }
+  src_offset = 0;
+  for (offset = hdr_len; ; offset += len) {
+    unsigned short chksum;
+    const void *data = (const void *)&file_data[src_offset];
+    len = LWIP_MIN(chunk_size, (int)file_size - src_offset);
+    if (len == 0) {
+      break;
+    }
+    chksum = ~inet_chksum(data, (u16_t)len);
+    /* add checksum for data */
+    fprintf(struct_file, "{%d, 0x%04x, %"SZT_F"}," NEWLINE, offset, chksum, len);
+    i++;
+  }
+  fprintf(struct_file, "};" NEWLINE);
+  fprintf(struct_file, "#endif /* HTTPD_PRECALCULATED_CHECKSUM */" NEWLINE);
+  return i;
+}
+
+static int is_valid_char_for_c_var(char x)
+{
+  if (((x >= 'A') && (x <= 'Z')) ||
+      ((x >= 'a') && (x <= 'z')) ||
+      ((x >= '0') && (x <= '9')) ||
+      (x == '_')) {
+    return 1;
+  }
+  return 0;
+}
+
+static void fix_filename_for_c(char *qualifiedName, size_t max_len)
+{
+  struct file_entry *f;
+  size_t len = strlen(qualifiedName);
+  char *new_name = (char *)malloc(len + 2);
+  int filename_ok;
+  int cnt = 0;
+  size_t i;
+  if (len + 3 == max_len) {
+    printf("File name too long: \"%s\"\n", qualifiedName);
+    exit(-1);
+  }
+  strcpy(new_name, qualifiedName);
+  for (i = 0; i < len; i++) {
+    if (!is_valid_char_for_c_var(new_name[i])) {
+      new_name[i] = '_';
+    }
+  }
+  do {
+    filename_ok = 1;
+    for (f = first_file; f != NULL; f = f->next) {
+      if (!strcmp(f->filename_c, new_name)) {
+        filename_ok = 0;
+        cnt++;
+        /* try next unique file name */
+        sprintf(&new_name[len], "%d", cnt);
+        break;
+      }
+    }
+  } while (!filename_ok && (cnt < 999));
+  if (!filename_ok) {
+    printf("Failed to get unique file name: \"%s\"\n", qualifiedName);
+    exit(-1);
+  }
+  strcpy(qualifiedName, new_name);
+  free(new_name);
+}
+
+static void register_filename(const char *qualifiedName)
+{
+  struct file_entry *fe = (struct file_entry *)malloc(sizeof(struct file_entry));
+  fe->filename_c = strdup(qualifiedName);
+  fe->next = NULL;
+  if (first_file == NULL) {
+    first_file = last_file = fe;
+  } else {
+    last_file->next = fe;
+    last_file = fe;
+  }
+}
+
+static int checkSsiByFilelist(const char* filename_listfile)
+{
+  FILE *f = fopen(filename_listfile, "r");
+  if (f != NULL) {
+    char *buf;
+    long rs;
+    size_t fsize, readcount;
+    size_t i, l, num_lines;
+    char **lines;
+    int state;
+
+    fseek(f, 0, SEEK_END);
+    rs = ftell(f);
+    if (rs < 0) {
+      printf("ftell failed with %d\n", errno);
+      fclose(f);
+      return 0;
+    }
+    fsize = (size_t)rs;
+    fseek(f, 0, SEEK_SET);
+    buf = (char*)malloc(fsize);
+    if (!buf) {
+      printf("failed to allocate ssi file buffer\n");
+      fclose(f);
+      return 0;
+    }
+    memset(buf, 0, fsize);
+    readcount = fread(buf, 1, fsize, f);
+    fclose(f);
+    if ((readcount > fsize) || !readcount) {
+      printf("failed to read data from ssi file\n");
+      free(buf);
+      return 0;
+    }
+
+    /* first pass: get the number of lines (and convert newlines to '0') */
+    num_lines = 1;
+    for (i = 0; i < readcount; i++) {
+      if (buf[i] == '\n') {
+        num_lines++;
+        buf[i] = 0;
+      } else if (buf[i] == '\r') {
+        buf[i] = 0;
+      }
+    }
+    /* allocate the line pointer array */
+    lines = (char**)malloc(sizeof(char*) * num_lines);
+    if (!lines) {
+      printf("failed to allocate ssi line buffer\n");
+      free(buf);
+      return 0;
+    }
+    memset(lines, 0, sizeof(char*) * num_lines);
+    l = 0;
+    state = 0;
+    for (i = 0; i < readcount; i++) {
+      if (state) {
+        /* waiting for null */
+        if (buf[i] == 0) {
+          state = 0;
+        }
+      } else {
+        /* waiting for beginning of new string */
+        if (buf[i] != 0) {
+          LWIP_ASSERT("lines array overflow", l < num_lines);
+          lines[l] = &buf[i];
+          state = 1;
+          l++;
+        }
+      }
+    }
+    LWIP_ASSERT("lines array overflow", l < num_lines);
+
+    ssi_file_buffer = buf;
+    ssi_file_lines = lines;
+    ssi_file_num_lines = l;
+  }
+  return 0;
+}
+
+static int is_ssi_file(const char *filename)
+{
+  if (supportSsi) {
+    if (ssi_file_buffer) {
+      /* compare by list */
+      size_t i;
+      int ret = 0;
+      /* build up the relative path to this file */
+      size_t sublen = strlen(curSubdir);
+      size_t freelen = sizeof(curSubdir) - sublen - 1;
+      strncat(curSubdir, "/", freelen);
+      strncat(curSubdir, filename, freelen - 1);
+      curSubdir[sizeof(curSubdir) - 1] = 0;
+      for (i = 0; i < ssi_file_num_lines; i++) {
+        const char *listed_file = ssi_file_lines[i];
+        /* compare without the leading '/' */
+        if (!strcmp(&curSubdir[1], listed_file)) {
+          ret = 1;
+        }
+      }
+      curSubdir[sublen] = 0;
+      return ret;
+    } else {
+      /* check file extension */
+      size_t loop;
+      for (loop = 0; loop < NUM_SHTML_EXTENSIONS; loop++) {
+        if (strstr(filename, g_pcSSIExtensions[loop])) {
+          return 1;
+        }
+      }
+    }
+  }
+  return 0;
+}
+
+static int ext_in_list(const char* filename, const char *ext_list)
+{
+  int found = 0;
+  const char *ext = ext_list;
+  if (ext_list == NULL) {
+    return 0;
+  }
+  while(*ext != '\0') {
+    const char *comma = strchr(ext, ',');
+    size_t ext_size;
+    size_t filename_size = strlen(filename);
+    if (comma == NULL) {
+      comma = strchr(ext, '\0');
+    }
+    ext_size = comma - ext;
+    if ((filename[filename_size - ext_size - 1] == '.') &&
+      !strncmp(&filename[filename_size - ext_size], ext, ext_size)) {
+        found = 1;
+        break;
+    }
+    ext = comma + 1;
+  }
+
+  return found;
+}
+
+static int file_to_exclude(const char *filename)
+{
+    return (exclude_list != NULL) && ext_in_list(filename, exclude_list);
+}
+
+static int file_can_be_compressed(const char *filename)
+{
+    return (ncompress_list == NULL) || !ext_in_list(filename, ncompress_list);
+}
+
+int process_file(FILE *data_file, FILE *struct_file, const char *filename)
+{
+  char varname[MAX_PATH_LEN];
+  int i = 0;
+  char qualifiedName[MAX_PATH_LEN];
+  int file_size;
+  u16_t http_hdr_chksum = 0;
+  u16_t http_hdr_len = 0;
+  int chksum_count = 0;
+  u8_t flags = 0;
+  u8_t has_content_len;
+  u8_t *file_data;
+  int is_ssi;
+  int can_be_compressed;
+  int is_compressed = 0;
+  int flags_printed;
+
+  /* create qualified name (@todo: prepend slash or not?) */
+  sprintf(qualifiedName, "%s/%s", curSubdir, filename);
+  /* create C variable name */
+  strcpy(varname, qualifiedName);
+  /* convert slashes & dots to underscores */
+  fix_filename_for_c(varname, MAX_PATH_LEN);
+  register_filename(varname);
+#if ALIGN_PAYLOAD
+  /* to force even alignment of array, type 1 */
+  fprintf(data_file, "#if FSDATA_FILE_ALIGNMENT==1" NEWLINE);
+  fprintf(data_file, "static const " PAYLOAD_ALIGN_TYPE " dummy_align_%s = %d;" NEWLINE, varname, payload_alingment_dummy_counter++);
+  fprintf(data_file, "#endif" NEWLINE);
+#endif /* ALIGN_PAYLOAD */
+  fprintf(data_file, "static const unsigned char FSDATA_ALIGN_PRE data_%s[] FSDATA_ALIGN_POST = {" NEWLINE, varname);
+  /* encode source file name (used by file system, not returned to browser) */
+  fprintf(data_file, "/* %s (%"SZT_F" chars) */" NEWLINE, qualifiedName, strlen(qualifiedName) + 1);
+  file_put_ascii(data_file, qualifiedName, strlen(qualifiedName) + 1, &i);
+#if ALIGN_PAYLOAD
+  /* pad to even number of bytes to assure payload is on aligned boundary */
+  while (i % PAYLOAD_ALIGNMENT != 0) {
+    fprintf(data_file, "0x%02x,", 0);
+    i++;
+  }
+#endif /* ALIGN_PAYLOAD */
+  fprintf(data_file, NEWLINE);
+
+  is_ssi = is_ssi_file(filename);
+  if (is_ssi) {
+    flags |= FS_FILE_FLAGS_SSI;
+  }
+  has_content_len = !is_ssi;
+  can_be_compressed = includeHttpHeader && !is_ssi && file_can_be_compressed(filename);
+  file_data = get_file_data(filename, &file_size, can_be_compressed, &is_compressed);
+  if (includeHttpHeader) {
+    file_write_http_header(data_file, filename, file_size, &http_hdr_len, &http_hdr_chksum, has_content_len, is_compressed);
+    flags |= FS_FILE_FLAGS_HEADER_INCLUDED;
+    if (has_content_len) {
+      flags |= FS_FILE_FLAGS_HEADER_PERSISTENT;
+      if (useHttp11) {
+        flags |= FS_FILE_FLAGS_HEADER_HTTPVER_1_1;
+      }
+    }
+  }
+  if (precalcChksum) {
+    chksum_count = write_checksums(struct_file, varname, http_hdr_len, http_hdr_chksum, file_data, file_size);
+  }
+
+  /* build declaration of struct fsdata_file in temp file */
+  fprintf(struct_file, "const struct fsdata_file file_%s[] = { {" NEWLINE, varname);
+  fprintf(struct_file, "file_%s," NEWLINE, lastFileVar);
+  fprintf(struct_file, "data_%s," NEWLINE, varname);
+  fprintf(struct_file, "data_%s + %d," NEWLINE, varname, i);
+  fprintf(struct_file, "sizeof(data_%s) - %d," NEWLINE, varname, i);
+
+  flags_printed = 0;
+  if (flags & FS_FILE_FLAGS_HEADER_INCLUDED) {
+    fputs("FS_FILE_FLAGS_HEADER_INCLUDED", struct_file);
+    flags_printed = 1;
+  }
+  if (flags & FS_FILE_FLAGS_HEADER_PERSISTENT) {
+    if (flags_printed) {
+      fputs(" | ", struct_file);
+    }
+    fputs("FS_FILE_FLAGS_HEADER_PERSISTENT", struct_file);
+    flags_printed = 1;
+  }
+  if (flags & FS_FILE_FLAGS_HEADER_HTTPVER_1_1) {
+    if (flags_printed) {
+      fputs(" | ", struct_file);
+    }
+    fputs("FS_FILE_FLAGS_HEADER_HTTPVER_1_1", struct_file);
+    flags_printed = 1;
+  }
+  if (flags & FS_FILE_FLAGS_SSI) {
+    if (flags_printed) {
+      fputs(" | ", struct_file);
+    }
+    fputs("FS_FILE_FLAGS_SSI", struct_file);
+    flags_printed = 1;
+  }
+  if (!flags_printed) {
+    fputs("0", struct_file);
+  }
+  fputs("," NEWLINE, struct_file);
+  if (precalcChksum) {
+    fprintf(struct_file, "#if HTTPD_PRECALCULATED_CHECKSUM" NEWLINE);
+    fprintf(struct_file, "%d, chksums_%s," NEWLINE, chksum_count, varname);
+    fprintf(struct_file, "#endif /* HTTPD_PRECALCULATED_CHECKSUM */" NEWLINE);
+  }
+  fprintf(struct_file, "}};" NEWLINE NEWLINE);
+  strcpy(lastFileVar, varname);
+
+  /* write actual file contents */
+  i = 0;
+  fprintf(data_file, NEWLINE "/* raw file data (%d bytes) */" NEWLINE, file_size);
+  process_file_data(data_file, file_data, file_size);
+  fprintf(data_file, "};" NEWLINE NEWLINE);
+  free(file_data);
+  return 0;
+}
+
+int file_write_http_header(FILE *data_file, const char *filename, int file_size, u16_t *http_hdr_len,
+                           u16_t *http_hdr_chksum, u8_t provide_content_len, int is_compressed)
+{
+  int i = 0;
+  int response_type = HTTP_HDR_OK;
+  const char *file_type;
+  const char *cur_string;
+  size_t cur_len;
+  int written = 0;
+  size_t hdr_len = 0;
+  u16_t acc;
+  const char *file_ext;
+  size_t j;
+  u8_t provide_last_modified = includeLastModified;
+
+  memset(hdr_buf, 0, sizeof(hdr_buf));
+
+  if (useHttp11) {
+    response_type = HTTP_HDR_OK_11;
+  }
+
+  fprintf(data_file, NEWLINE "/* HTTP header */");
+  if (strstr(filename, "404") == filename) {
+    response_type = HTTP_HDR_NOT_FOUND;
+    if (useHttp11) {
+      response_type = HTTP_HDR_NOT_FOUND_11;
+    }
+  } else if (strstr(filename, "400") == filename) {
+    response_type = HTTP_HDR_BAD_REQUEST;
+    if (useHttp11) {
+      response_type = HTTP_HDR_BAD_REQUEST_11;
+    }
+  } else if (strstr(filename, "501") == filename) {
+    response_type = HTTP_HDR_NOT_IMPL;
+    if (useHttp11) {
+      response_type = HTTP_HDR_NOT_IMPL_11;
+    }
+  }
+  cur_string = g_psHTTPHeaderStrings[response_type];
+  cur_len = strlen(cur_string);
+  fprintf(data_file, NEWLINE "/* \"%s\" (%"SZT_F" bytes) */" NEWLINE, cur_string, cur_len);
+  written += file_put_ascii(data_file, cur_string, cur_len, &i);
+  i = 0;
+  if (precalcChksum) {
+    memcpy(&hdr_buf[hdr_len], cur_string, cur_len);
+    hdr_len += cur_len;
+  }
+
+  cur_string = serverID;
+  cur_len = strlen(cur_string);
+  fprintf(data_file, NEWLINE "/* \"%s\" (%"SZT_F" bytes) */" NEWLINE, cur_string, cur_len);
+  written += file_put_ascii(data_file, cur_string, cur_len, &i);
+  i = 0;
+  if (precalcChksum) {
+    memcpy(&hdr_buf[hdr_len], cur_string, cur_len);
+    hdr_len += cur_len;
+  }
+
+  file_ext = filename;
+  if (file_ext != NULL) {
+    while (strstr(file_ext, ".") != NULL) {
+      file_ext = strstr(file_ext, ".");
+      file_ext++;
+    }
+  }
+  if ((file_ext == NULL) || (*file_ext == 0)) {
+    printf("failed to get extension for file \"%s\", using default.\n", filename);
+    file_type = HTTP_HDR_DEFAULT_TYPE;
+  } else {
+    file_type = NULL;
+    for (j = 0; j < NUM_HTTP_HEADERS; j++) {
+      if (!strcmp(file_ext, g_psHTTPHeaders[j].extension)) {
+        file_type = g_psHTTPHeaders[j].content_type;
+        break;
+      }
+    }
+    if (file_type == NULL) {
+      printf("failed to get file type for extension \"%s\", using default.\n", file_ext);
+      file_type = HTTP_HDR_DEFAULT_TYPE;
+    }
+  }
+
+  /* Content-Length is used for persistent connections in HTTP/1.1 but also for
+     download progress in older versions
+     @todo: just use a big-enough buffer and let the HTTPD send spaces? */
+  if (provide_content_len) {
+    char intbuf[MAX_PATH_LEN];
+    int content_len = file_size;
+    memset(intbuf, 0, sizeof(intbuf));
+    cur_string = g_psHTTPHeaderStrings[HTTP_HDR_CONTENT_LENGTH];
+    cur_len = strlen(cur_string);
+    fprintf(data_file, NEWLINE "/* \"%s%d\r\n\" (%"SZT_F"+ bytes) */" NEWLINE, cur_string, content_len, cur_len + 2);
+    written += file_put_ascii(data_file, cur_string, cur_len, &i);
+    if (precalcChksum) {
+      memcpy(&hdr_buf[hdr_len], cur_string, cur_len);
+      hdr_len += cur_len;
+    }
+
+    lwip_itoa(intbuf, sizeof(intbuf), content_len);
+    strcat(intbuf, "\r\n");
+    cur_len = strlen(intbuf);
+    written += file_put_ascii(data_file, intbuf, cur_len, &i);
+    i = 0;
+    if (precalcChksum) {
+      memcpy(&hdr_buf[hdr_len], intbuf, cur_len);
+      hdr_len += cur_len;
+    }
+  }
+  if (provide_last_modified) {
+    char modbuf[256];
+    struct stat stat_data;
+    struct tm *t;
+    memset(modbuf, 0, sizeof(modbuf));
+    memset(&stat_data, 0, sizeof(stat_data));
+    cur_string = modbuf;
+    strcpy(modbuf, "Last-Modified: ");
+    if (stat(filename, &stat_data) != 0) {
+      printf("stat(%s) failed with error %d\n", filename, errno);
+      exit(-1);
+    }
+    t = gmtime(&stat_data.st_mtime);
+    if (t == NULL) {
+      printf("gmtime() failed with error %d\n", errno);
+      exit(-1);
+    }
+    strftime(&modbuf[15], sizeof(modbuf) - 15, "%a, %d %b %Y %H:%M:%S GMT", t);
+    cur_len = strlen(cur_string);
+    fprintf(data_file, NEWLINE "/* \"%s\"\r\n\" (%"SZT_F"+ bytes) */" NEWLINE, cur_string, cur_len + 2);
+    written += file_put_ascii(data_file, cur_string, cur_len, &i);
+    if (precalcChksum) {
+      memcpy(&hdr_buf[hdr_len], cur_string, cur_len);
+      hdr_len += cur_len;
+    }
+
+    modbuf[0] = 0;
+    strcat(modbuf, "\r\n");
+    cur_len = strlen(modbuf);
+    written += file_put_ascii(data_file, modbuf, cur_len, &i);
+    i = 0;
+    if (precalcChksum) {
+      memcpy(&hdr_buf[hdr_len], modbuf, cur_len);
+      hdr_len += cur_len;
+    }
+  }
+
+  /* HTTP/1.1 implements persistent connections */
+  if (useHttp11) {
+    if (provide_content_len) {
+      cur_string = g_psHTTPHeaderStrings[HTTP_HDR_CONN_KEEPALIVE];
+    } else {
+      /* no Content-Length available, so a persistent connection is no possible
+         because the client does not know the data length */
+      cur_string = g_psHTTPHeaderStrings[HTTP_HDR_CONN_CLOSE];
+    }
+    cur_len = strlen(cur_string);
+    fprintf(data_file, NEWLINE "/* \"%s\" (%"SZT_F" bytes) */" NEWLINE, cur_string, cur_len);
+    written += file_put_ascii(data_file, cur_string, cur_len, &i);
+    i = 0;
+    if (precalcChksum) {
+      memcpy(&hdr_buf[hdr_len], cur_string, cur_len);
+      hdr_len += cur_len;
+    }
+  }
+
+#if MAKEFS_SUPPORT_DEFLATE
+  if (is_compressed) {
+    /* tell the client about the deflate encoding */
+    LWIP_ASSERT("error", deflateNonSsiFiles);
+    cur_string = "Content-Encoding: deflate\r\n";
+    cur_len = strlen(cur_string);
+    fprintf(data_file, NEWLINE "/* \"%s\" (%d bytes) */" NEWLINE, cur_string, cur_len);
+    written += file_put_ascii(data_file, cur_string, cur_len, &i);
+    i = 0;
+  }
+#else
+  LWIP_UNUSED_ARG(is_compressed);
+#endif
+
+  /* write content-type, ATTENTION: this includes the double-CRLF! */
+  cur_string = file_type;
+  cur_len = strlen(cur_string);
+  fprintf(data_file, NEWLINE "/* \"%s\" (%"SZT_F" bytes) */" NEWLINE, cur_string, cur_len);
+  written += file_put_ascii(data_file, cur_string, cur_len, &i);
+  i = 0;
+
+  /* ATTENTION: headers are done now (double-CRLF has been written!) */
+
+  if (precalcChksum) {
+    LWIP_ASSERT("hdr_len + cur_len <= sizeof(hdr_buf)", hdr_len + cur_len <= sizeof(hdr_buf));
+    memcpy(&hdr_buf[hdr_len], cur_string, cur_len);
+    hdr_len += cur_len;
+
+    LWIP_ASSERT("strlen(hdr_buf) == hdr_len", strlen(hdr_buf) == hdr_len);
+    acc = ~inet_chksum(hdr_buf, (u16_t)hdr_len);
+    *http_hdr_len = (u16_t)hdr_len;
+    *http_hdr_chksum = acc;
+  }
+
+  return written;
+}
+
+int file_put_ascii(FILE *file, const char *ascii_string, int len, int *i)
+{
+  int x;
+  for (x = 0; x < len; x++) {
+    unsigned char cur = ascii_string[x];
+    fprintf(file, "0x%02x,", cur);
+    if ((++(*i) % HEX_BYTES_PER_LINE) == 0) {
+      fprintf(file, NEWLINE);
+    }
+  }
+  return len;
+}
+
+int s_put_ascii(char *buf, const char *ascii_string, int len, int *i)
+{
+  int x;
+  int idx = 0;
+  for (x = 0; x < len; x++) {
+    unsigned char cur = ascii_string[x];
+    sprintf(&buf[idx], "0x%02x,", cur);
+    idx += 5;
+    if ((++(*i) % HEX_BYTES_PER_LINE) == 0) {
+      sprintf(&buf[idx], NEWLINE);
+      idx += NEWLINE_LEN;
+    }
+  }
+  return len;
+}
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/apps/http/makefsdata/readme.txt
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/apps/http/makefsdata/readme.txt	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/apps/http/makefsdata/readme.txt	(revision 457)
@@ -0,0 +1,13 @@
+This directory contains a script ('makefsdata') to create C code suitable for
+httpd for given html pages (or other files) in a directory.
+
+There is also a plain C console application doing the same and extended a bit.
+
+Usage: htmlgen [targetdir] [-s] [-i]s
+   targetdir: relative or absolute path to files to convert
+   switch -s: toggle processing of subdirectories (default is on)
+   switch -e: exclude HTTP header from file (header is created at runtime, default is on)
+   switch -11: include HTTP 1.1 header (1.0 is default)
+
+  if targetdir not specified, makefsdata will attempt to
+  process files in subdirectory 'fs'.
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/apps/http/makefsdata/tinydir.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/apps/http/makefsdata/tinydir.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/apps/http/makefsdata/tinydir.h	(revision 457)
@@ -0,0 +1,808 @@
+/*
+Copyright (c) 2013-2017, tinydir authors:
+- Cong Xu
+- Lautis Sun
+- Baudouin Feildel
+- Andargor <andargor@yahoo.com>
+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.
+
+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 TINYDIR_H
+#define TINYDIR_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if ((defined _UNICODE) && !(defined UNICODE))
+#define UNICODE
+#endif
+
+#if ((defined UNICODE) && !(defined _UNICODE))
+#define _UNICODE
+#endif
+
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+#ifdef _MSC_VER
+# define WIN32_LEAN_AND_MEAN
+# include <windows.h>
+# include <tchar.h>
+# pragma warning(push)
+# pragma warning (disable : 4996)
+#else
+# include <dirent.h>
+# include <libgen.h>
+# include <sys/stat.h>
+# include <stddef.h>
+#endif
+#ifdef __MINGW32__
+# include <tchar.h>
+#endif
+
+
+/* types */
+
+/* Windows UNICODE wide character support */
+#if defined _MSC_VER || defined __MINGW32__
+#define _tinydir_char_t TCHAR
+#define TINYDIR_STRING(s) _TEXT(s)
+#define _tinydir_strlen _tcslen
+#define _tinydir_strcpy _tcscpy
+#define _tinydir_strcat _tcscat
+#define _tinydir_strcmp _tcscmp
+#define _tinydir_strrchr _tcsrchr
+#define _tinydir_strncmp _tcsncmp
+#else
+#define _tinydir_char_t char
+#define TINYDIR_STRING(s) s
+#define _tinydir_strlen strlen
+#define _tinydir_strcpy strcpy
+#define _tinydir_strcat strcat
+#define _tinydir_strcmp strcmp
+#define _tinydir_strrchr strrchr
+#define _tinydir_strncmp strncmp
+#endif
+
+#if (defined _MSC_VER || defined __MINGW32__)
+#include <windows.h>
+#define _TINYDIR_PATH_MAX MAX_PATH
+#elif defined  __linux__
+#include <linux/limits.h>
+#define _TINYDIR_PATH_MAX PATH_MAX
+#else
+#define _TINYDIR_PATH_MAX 4096
+#endif
+
+#ifdef _MSC_VER
+/* extra chars for the "\\*" mask */
+# define _TINYDIR_PATH_EXTRA 2
+#else
+# define _TINYDIR_PATH_EXTRA 0
+#endif
+
+#define _TINYDIR_FILENAME_MAX 256
+
+#if (defined _MSC_VER || defined __MINGW32__)
+#define _TINYDIR_DRIVE_MAX 3
+#endif
+
+#ifdef _MSC_VER
+# define _TINYDIR_FUNC static __inline
+#elif !defined __STDC_VERSION__ || __STDC_VERSION__ < 199901L
+# define _TINYDIR_FUNC static __inline__
+#else
+# define _TINYDIR_FUNC static inline
+#endif
+
+/* readdir_r usage; define TINYDIR_USE_READDIR_R to use it (if supported) */
+#ifdef TINYDIR_USE_READDIR_R
+
+/* readdir_r is a POSIX-only function, and may not be available under various
+ * environments/settings, e.g. MinGW. Use readdir fallback */
+#if _POSIX_C_SOURCE >= 1 || _XOPEN_SOURCE || _BSD_SOURCE || _SVID_SOURCE ||\
+	_POSIX_SOURCE
+# define _TINYDIR_HAS_READDIR_R
+#endif
+#if _POSIX_C_SOURCE >= 200112L
+# define _TINYDIR_HAS_FPATHCONF
+# include <unistd.h>
+#endif
+#if _BSD_SOURCE || _SVID_SOURCE || \
+	(_POSIX_C_SOURCE >= 200809L || _XOPEN_SOURCE >= 700)
+# define _TINYDIR_HAS_DIRFD
+# include <sys/types.h>
+#endif
+#if defined _TINYDIR_HAS_FPATHCONF && defined _TINYDIR_HAS_DIRFD &&\
+	defined _PC_NAME_MAX
+# define _TINYDIR_USE_FPATHCONF
+#endif
+#if defined __MINGW32__ || !defined _TINYDIR_HAS_READDIR_R ||\
+	!(defined _TINYDIR_USE_FPATHCONF || defined NAME_MAX)
+# define _TINYDIR_USE_READDIR
+#endif
+
+/* Use readdir by default */
+#else
+# define _TINYDIR_USE_READDIR
+#endif
+
+/* MINGW32 has two versions of dirent, ASCII and UNICODE*/
+#ifndef _MSC_VER
+#if (defined __MINGW32__) && (defined _UNICODE)
+#define _TINYDIR_DIR _WDIR
+#define _tinydir_dirent _wdirent
+#define _tinydir_opendir _wopendir
+#define _tinydir_readdir _wreaddir
+#define _tinydir_closedir _wclosedir
+#else
+#define _TINYDIR_DIR DIR
+#define _tinydir_dirent dirent
+#define _tinydir_opendir opendir
+#define _tinydir_readdir readdir
+#define _tinydir_closedir closedir
+#endif
+#endif
+
+/* Allow user to use a custom allocator by defining _TINYDIR_MALLOC and _TINYDIR_FREE. */
+#if    defined(_TINYDIR_MALLOC) &&  defined(_TINYDIR_FREE)
+#elif !defined(_TINYDIR_MALLOC) && !defined(_TINYDIR_FREE)
+#else
+#error "Either define both alloc and free or none of them!"
+#endif
+
+#if !defined(_TINYDIR_MALLOC)
+	#define _TINYDIR_MALLOC(_size) malloc(_size)
+	#define _TINYDIR_FREE(_ptr)    free(_ptr)
+#endif /* !defined(_TINYDIR_MALLOC) */
+
+typedef struct tinydir_file
+{
+	_tinydir_char_t path[_TINYDIR_PATH_MAX];
+	_tinydir_char_t name[_TINYDIR_FILENAME_MAX];
+	_tinydir_char_t *extension;
+	int is_dir;
+	int is_reg;
+
+#ifndef _MSC_VER
+#ifdef __MINGW32__
+	struct _stat _s;
+#else
+	struct stat _s;
+#endif
+#endif
+} tinydir_file;
+
+typedef struct tinydir_dir
+{
+	_tinydir_char_t path[_TINYDIR_PATH_MAX];
+	int has_next;
+	size_t n_files;
+
+	tinydir_file *_files;
+#ifdef _MSC_VER
+	HANDLE _h;
+	WIN32_FIND_DATA _f;
+#else
+	_TINYDIR_DIR *_d;
+	struct _tinydir_dirent *_e;
+#ifndef _TINYDIR_USE_READDIR
+	struct _tinydir_dirent *_ep;
+#endif
+#endif
+} tinydir_dir;
+
+
+/* declarations */
+
+_TINYDIR_FUNC
+int tinydir_open(tinydir_dir *dir, const _tinydir_char_t *path);
+_TINYDIR_FUNC
+int tinydir_open_sorted(tinydir_dir *dir, const _tinydir_char_t *path);
+_TINYDIR_FUNC
+void tinydir_close(tinydir_dir *dir);
+
+_TINYDIR_FUNC
+int tinydir_next(tinydir_dir *dir);
+_TINYDIR_FUNC
+int tinydir_readfile(const tinydir_dir *dir, tinydir_file *file);
+_TINYDIR_FUNC
+int tinydir_readfile_n(const tinydir_dir *dir, tinydir_file *file, size_t i);
+_TINYDIR_FUNC
+int tinydir_open_subdir_n(tinydir_dir *dir, size_t i);
+
+_TINYDIR_FUNC
+int tinydir_file_open(tinydir_file *file, const _tinydir_char_t *path);
+_TINYDIR_FUNC
+void _tinydir_get_ext(tinydir_file *file);
+_TINYDIR_FUNC
+int _tinydir_file_cmp(const void *a, const void *b);
+#ifndef _MSC_VER
+#ifndef _TINYDIR_USE_READDIR
+_TINYDIR_FUNC
+size_t _tinydir_dirent_buf_size(_TINYDIR_DIR *dirp);
+#endif
+#endif
+
+
+/* definitions*/
+
+_TINYDIR_FUNC
+int tinydir_open(tinydir_dir *dir, const _tinydir_char_t *path)
+{
+#ifndef _MSC_VER
+#ifndef _TINYDIR_USE_READDIR
+	int error;
+	int size;	/* using int size */
+#endif
+#else
+	_tinydir_char_t path_buf[_TINYDIR_PATH_MAX];
+#endif
+	_tinydir_char_t *pathp;
+
+	if (dir == NULL || path == NULL || _tinydir_strlen(path) == 0)
+	{
+		errno = EINVAL;
+		return -1;
+	}
+	if (_tinydir_strlen(path) + _TINYDIR_PATH_EXTRA >= _TINYDIR_PATH_MAX)
+	{
+		errno = ENAMETOOLONG;
+		return -1;
+	}
+
+	/* initialise dir */
+	dir->_files = NULL;
+#ifdef _MSC_VER
+	dir->_h = INVALID_HANDLE_VALUE;
+#else
+	dir->_d = NULL;
+#ifndef _TINYDIR_USE_READDIR
+	dir->_ep = NULL;
+#endif
+#endif
+	tinydir_close(dir);
+
+	_tinydir_strcpy(dir->path, path);
+	/* Remove trailing slashes */
+	pathp = &dir->path[_tinydir_strlen(dir->path) - 1];
+	while (pathp != dir->path && (*pathp == TINYDIR_STRING('\\') || *pathp == TINYDIR_STRING('/')))
+	{
+		*pathp = TINYDIR_STRING('\0');
+		pathp++;
+	}
+#ifdef _MSC_VER
+	_tinydir_strcpy(path_buf, dir->path);
+	_tinydir_strcat(path_buf, TINYDIR_STRING("\\*"));
+#if (defined WINAPI_FAMILY) && (WINAPI_FAMILY != WINAPI_FAMILY_DESKTOP_APP)
+	dir->_h = FindFirstFileEx(path_buf, FindExInfoStandard, &dir->_f, FindExSearchNameMatch, NULL, 0);
+#else
+	dir->_h = FindFirstFile(path_buf, &dir->_f);
+#endif
+	if (dir->_h == INVALID_HANDLE_VALUE)
+	{
+		errno = ENOENT;
+#else
+	dir->_d = _tinydir_opendir(path);
+	if (dir->_d == NULL)
+	{
+#endif
+		goto bail;
+	}
+
+	/* read first file */
+	dir->has_next = 1;
+#ifndef _MSC_VER
+#ifdef _TINYDIR_USE_READDIR
+	dir->_e = _tinydir_readdir(dir->_d);
+#else
+	/* allocate dirent buffer for readdir_r */
+	size = _tinydir_dirent_buf_size(dir->_d); /* conversion to int */
+	if (size == -1) return -1;
+	dir->_ep = (struct _tinydir_dirent*)_TINYDIR_MALLOC(size);
+	if (dir->_ep == NULL) return -1;
+
+	error = readdir_r(dir->_d, dir->_ep, &dir->_e);
+	if (error != 0) return -1;
+#endif
+	if (dir->_e == NULL)
+	{
+		dir->has_next = 0;
+	}
+#endif
+
+	return 0;
+
+bail:
+	tinydir_close(dir);
+	return -1;
+}
+
+_TINYDIR_FUNC
+int tinydir_open_sorted(tinydir_dir *dir, const _tinydir_char_t *path)
+{
+	/* Count the number of files first, to pre-allocate the files array */
+	size_t n_files = 0;
+	if (tinydir_open(dir, path) == -1)
+	{
+		return -1;
+	}
+	while (dir->has_next)
+	{
+		n_files++;
+		if (tinydir_next(dir) == -1)
+		{
+			goto bail;
+		}
+	}
+	tinydir_close(dir);
+
+	if (tinydir_open(dir, path) == -1)
+	{
+		return -1;
+	}
+
+	dir->n_files = 0;
+	dir->_files = (tinydir_file *)_TINYDIR_MALLOC(sizeof *dir->_files * n_files);
+	if (dir->_files == NULL)
+	{
+		goto bail;
+	}
+	while (dir->has_next)
+	{
+		tinydir_file *p_file;
+		dir->n_files++;
+
+		p_file = &dir->_files[dir->n_files - 1];
+		if (tinydir_readfile(dir, p_file) == -1)
+		{
+			goto bail;
+		}
+
+		if (tinydir_next(dir) == -1)
+		{
+			goto bail;
+		}
+
+		/* Just in case the number of files has changed between the first and
+		second reads, terminate without writing into unallocated memory */
+		if (dir->n_files == n_files)
+		{
+			break;
+		}
+	}
+
+	qsort(dir->_files, dir->n_files, sizeof(tinydir_file), _tinydir_file_cmp);
+
+	return 0;
+
+bail:
+	tinydir_close(dir);
+	return -1;
+}
+
+_TINYDIR_FUNC
+void tinydir_close(tinydir_dir *dir)
+{
+	if (dir == NULL)
+	{
+		return;
+	}
+
+	memset(dir->path, 0, sizeof(dir->path));
+	dir->has_next = 0;
+	dir->n_files = 0;
+	_TINYDIR_FREE(dir->_files);
+	dir->_files = NULL;
+#ifdef _MSC_VER
+	if (dir->_h != INVALID_HANDLE_VALUE)
+	{
+		FindClose(dir->_h);
+	}
+	dir->_h = INVALID_HANDLE_VALUE;
+#else
+	if (dir->_d)
+	{
+		_tinydir_closedir(dir->_d);
+	}
+	dir->_d = NULL;
+	dir->_e = NULL;
+#ifndef _TINYDIR_USE_READDIR
+	_TINYDIR_FREE(dir->_ep);
+	dir->_ep = NULL;
+#endif
+#endif
+}
+
+_TINYDIR_FUNC
+int tinydir_next(tinydir_dir *dir)
+{
+	if (dir == NULL)
+	{
+		errno = EINVAL;
+		return -1;
+	}
+	if (!dir->has_next)
+	{
+		errno = ENOENT;
+		return -1;
+	}
+
+#ifdef _MSC_VER
+	if (FindNextFile(dir->_h, &dir->_f) == 0)
+#else
+#ifdef _TINYDIR_USE_READDIR
+	dir->_e = _tinydir_readdir(dir->_d);
+#else
+	if (dir->_ep == NULL)
+	{
+		return -1;
+	}
+	if (readdir_r(dir->_d, dir->_ep, &dir->_e) != 0)
+	{
+		return -1;
+	}
+#endif
+	if (dir->_e == NULL)
+#endif
+	{
+		dir->has_next = 0;
+#ifdef _MSC_VER
+		if (GetLastError() != ERROR_SUCCESS &&
+			GetLastError() != ERROR_NO_MORE_FILES)
+		{
+			tinydir_close(dir);
+			errno = EIO;
+			return -1;
+		}
+#endif
+	}
+
+	return 0;
+}
+
+_TINYDIR_FUNC
+int tinydir_readfile(const tinydir_dir *dir, tinydir_file *file)
+{
+	if (dir == NULL || file == NULL)
+	{
+		errno = EINVAL;
+		return -1;
+	}
+#ifdef _MSC_VER
+	if (dir->_h == INVALID_HANDLE_VALUE)
+#else
+	if (dir->_e == NULL)
+#endif
+	{
+		errno = ENOENT;
+		return -1;
+	}
+	if (_tinydir_strlen(dir->path) +
+		_tinydir_strlen(
+#ifdef _MSC_VER
+			dir->_f.cFileName
+#else
+			dir->_e->d_name
+#endif
+		) + 1 + _TINYDIR_PATH_EXTRA >=
+		_TINYDIR_PATH_MAX)
+	{
+		/* the path for the file will be too long */
+		errno = ENAMETOOLONG;
+		return -1;
+	}
+	if (_tinydir_strlen(
+#ifdef _MSC_VER
+			dir->_f.cFileName
+#else
+			dir->_e->d_name
+#endif
+		) >= _TINYDIR_FILENAME_MAX)
+	{
+		errno = ENAMETOOLONG;
+		return -1;
+	}
+
+	_tinydir_strcpy(file->path, dir->path);
+	_tinydir_strcat(file->path, TINYDIR_STRING("/"));
+	_tinydir_strcpy(file->name,
+#ifdef _MSC_VER
+		dir->_f.cFileName
+#else
+		dir->_e->d_name
+#endif
+	);
+	_tinydir_strcat(file->path, file->name);
+#ifndef _MSC_VER
+#ifdef __MINGW32__
+	if (_tstat(
+#else
+	if (stat(
+#endif
+		file->path, &file->_s) == -1)
+	{
+		return -1;
+	}
+#endif
+	_tinydir_get_ext(file);
+
+	file->is_dir =
+#ifdef _MSC_VER
+		!!(dir->_f.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY);
+#else
+		S_ISDIR(file->_s.st_mode);
+#endif
+	file->is_reg =
+#ifdef _MSC_VER
+		!!(dir->_f.dwFileAttributes & FILE_ATTRIBUTE_NORMAL) ||
+		(
+			!(dir->_f.dwFileAttributes & FILE_ATTRIBUTE_DEVICE) &&
+			!(dir->_f.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) &&
+			!(dir->_f.dwFileAttributes & FILE_ATTRIBUTE_ENCRYPTED) &&
+#ifdef FILE_ATTRIBUTE_INTEGRITY_STREAM
+			!(dir->_f.dwFileAttributes & FILE_ATTRIBUTE_INTEGRITY_STREAM) &&
+#endif
+#ifdef FILE_ATTRIBUTE_NO_SCRUB_DATA
+			!(dir->_f.dwFileAttributes & FILE_ATTRIBUTE_NO_SCRUB_DATA) &&
+#endif
+			!(dir->_f.dwFileAttributes & FILE_ATTRIBUTE_OFFLINE) &&
+			!(dir->_f.dwFileAttributes & FILE_ATTRIBUTE_TEMPORARY));
+#else
+		S_ISREG(file->_s.st_mode);
+#endif
+
+	return 0;
+}
+
+_TINYDIR_FUNC
+int tinydir_readfile_n(const tinydir_dir *dir, tinydir_file *file, size_t i)
+{
+	if (dir == NULL || file == NULL)
+	{
+		errno = EINVAL;
+		return -1;
+	}
+	if (i >= dir->n_files)
+	{
+		errno = ENOENT;
+		return -1;
+	}
+
+	memcpy(file, &dir->_files[i], sizeof(tinydir_file));
+	_tinydir_get_ext(file);
+
+	return 0;
+}
+
+_TINYDIR_FUNC
+int tinydir_open_subdir_n(tinydir_dir *dir, size_t i)
+{
+	_tinydir_char_t path[_TINYDIR_PATH_MAX];
+	if (dir == NULL)
+	{
+		errno = EINVAL;
+		return -1;
+	}
+	if (i >= dir->n_files || !dir->_files[i].is_dir)
+	{
+		errno = ENOENT;
+		return -1;
+	}
+
+	_tinydir_strcpy(path, dir->_files[i].path);
+	tinydir_close(dir);
+	if (tinydir_open_sorted(dir, path) == -1)
+	{
+		return -1;
+	}
+
+	return 0;
+}
+
+/* Open a single file given its path */
+_TINYDIR_FUNC
+int tinydir_file_open(tinydir_file *file, const _tinydir_char_t *path)
+{
+	tinydir_dir dir;
+	int result = 0;
+	int found = 0;
+	_tinydir_char_t dir_name_buf[_TINYDIR_PATH_MAX];
+	_tinydir_char_t file_name_buf[_TINYDIR_FILENAME_MAX];
+	_tinydir_char_t *dir_name;
+	_tinydir_char_t *base_name;
+#if (defined _MSC_VER || defined __MINGW32__)
+	_tinydir_char_t drive_buf[_TINYDIR_PATH_MAX];
+	_tinydir_char_t ext_buf[_TINYDIR_FILENAME_MAX];
+#endif
+
+	if (file == NULL || path == NULL || _tinydir_strlen(path) == 0)
+	{
+		errno = EINVAL;
+		return -1;
+	}
+	if (_tinydir_strlen(path) + _TINYDIR_PATH_EXTRA >= _TINYDIR_PATH_MAX)
+	{
+		errno = ENAMETOOLONG;
+		return -1;
+	}
+
+	/* Get the parent path */
+#if (defined _MSC_VER || defined __MINGW32__)
+#if ((defined _MSC_VER) && (_MSC_VER >= 1400))
+		_tsplitpath_s(
+			path,
+			drive_buf, _TINYDIR_DRIVE_MAX,
+			dir_name_buf, _TINYDIR_FILENAME_MAX,
+			file_name_buf, _TINYDIR_FILENAME_MAX,
+			ext_buf, _TINYDIR_FILENAME_MAX);
+#else
+		_tsplitpath(
+			path,
+			drive_buf,
+			dir_name_buf,
+			file_name_buf,
+			ext_buf);
+#endif
+
+/* _splitpath_s not work fine with only filename and widechar support */
+#ifdef _UNICODE
+		if (drive_buf[0] == L'\xFEFE')
+			drive_buf[0] = '\0';
+		if (dir_name_buf[0] == L'\xFEFE')
+			dir_name_buf[0] = '\0';
+#endif
+
+	if (errno)
+	{
+		errno = EINVAL;
+		return -1;
+	}
+	/* Emulate the behavior of dirname by returning "." for dir name if it's
+	empty */
+	if (drive_buf[0] == '\0' && dir_name_buf[0] == '\0')
+	{
+		_tinydir_strcpy(dir_name_buf, TINYDIR_STRING("."));
+	}
+	/* Concatenate the drive letter and dir name to form full dir name */
+	_tinydir_strcat(drive_buf, dir_name_buf);
+	dir_name = drive_buf;
+	/* Concatenate the file name and extension to form base name */
+	_tinydir_strcat(file_name_buf, ext_buf);
+	base_name = file_name_buf;
+#else
+	_tinydir_strcpy(dir_name_buf, path);
+	dir_name = dirname(dir_name_buf);
+	_tinydir_strcpy(file_name_buf, path);
+	base_name =basename(file_name_buf);
+#endif
+
+	/* Open the parent directory */
+	if (tinydir_open(&dir, dir_name) == -1)
+	{
+		return -1;
+	}
+
+	/* Read through the parent directory and look for the file */
+	while (dir.has_next)
+	{
+		if (tinydir_readfile(&dir, file) == -1)
+		{
+			result = -1;
+			goto bail;
+		}
+		if (_tinydir_strcmp(file->name, base_name) == 0)
+		{
+			/* File found */
+			found = 1;
+			break;
+		}
+		tinydir_next(&dir);
+	}
+	if (!found)
+	{
+		result = -1;
+		errno = ENOENT;
+	}
+
+bail:
+	tinydir_close(&dir);
+	return result;
+}
+
+_TINYDIR_FUNC
+void _tinydir_get_ext(tinydir_file *file)
+{
+	_tinydir_char_t *period = _tinydir_strrchr(file->name, TINYDIR_STRING('.'));
+	if (period == NULL)
+	{
+		file->extension = &(file->name[_tinydir_strlen(file->name)]);
+	}
+	else
+	{
+		file->extension = period + 1;
+	}
+}
+
+_TINYDIR_FUNC
+int _tinydir_file_cmp(const void *a, const void *b)
+{
+	const tinydir_file *fa = (const tinydir_file *)a;
+	const tinydir_file *fb = (const tinydir_file *)b;
+	if (fa->is_dir != fb->is_dir)
+	{
+		return -(fa->is_dir - fb->is_dir);
+	}
+	return _tinydir_strncmp(fa->name, fb->name, _TINYDIR_FILENAME_MAX);
+}
+
+#ifndef _MSC_VER
+#ifndef _TINYDIR_USE_READDIR
+/*
+The following authored by Ben Hutchings <ben@decadent.org.uk>
+from https://womble.decadent.org.uk/readdir_r-advisory.html
+*/
+/* Calculate the required buffer size (in bytes) for directory      *
+* entries read from the given directory handle.  Return -1 if this  *
+* this cannot be done.                                              *
+*                                                                   *
+* This code does not trust values of NAME_MAX that are less than    *
+* 255, since some systems (including at least HP-UX) incorrectly    *
+* define it to be a smaller value.                                  */
+_TINYDIR_FUNC
+size_t _tinydir_dirent_buf_size(_TINYDIR_DIR *dirp)
+{
+	long name_max;
+	size_t name_end;
+	/* parameter may be unused */
+	(void)dirp;
+
+#if defined _TINYDIR_USE_FPATHCONF
+	name_max = fpathconf(dirfd(dirp), _PC_NAME_MAX);
+	if (name_max == -1)
+#if defined(NAME_MAX)
+		name_max = (NAME_MAX > 255) ? NAME_MAX : 255;
+#else
+		return (size_t)(-1);
+#endif
+#elif defined(NAME_MAX)
+ 	name_max = (NAME_MAX > 255) ? NAME_MAX : 255;
+#else
+#error "buffer size for readdir_r cannot be determined"
+#endif
+	name_end = (size_t)offsetof(struct _tinydir_dirent, d_name) + name_max + 1;
+	return (name_end > sizeof(struct _tinydir_dirent) ?
+		name_end : sizeof(struct _tinydir_dirent));
+}
+#endif
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+# if defined (_MSC_VER)
+# pragma warning(pop)
+# endif
+
+#endif
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/apps/lwiperf/lwiperf.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/apps/lwiperf/lwiperf.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/apps/lwiperf/lwiperf.c	(revision 457)
@@ -0,0 +1,841 @@
+/**
+ * @file
+ * lwIP iPerf server implementation
+ */
+
+/**
+ * @defgroup iperf Iperf server
+ * @ingroup apps
+ *
+ * This is a simple performance measuring client/server to check your bandwith using
+ * iPerf2 on a PC as server/client.
+ * It is currently a minimal implementation providing a TCP client/server only.
+ *
+ * @todo:
+ * - implement UDP mode
+ * - protect combined sessions handling (via 'related_master_state') against reallocation
+ *   (this is a pointer address, currently, so if the same memory is allocated again,
+ *    session pairs (tx/rx) can be confused on reallocation)
+ */
+
+/*
+ * Copyright (c) 2014 Simon Goldschmidt
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Simon Goldschmidt
+ */
+
+#include "lwip/apps/lwiperf.h"
+
+#include "lwip/tcp.h"
+#include "lwip/sys.h"
+
+#include <string.h>
+
+/* Currently, only TCP is implemented */
+#if LWIP_TCP && LWIP_CALLBACK_API
+
+/** Specify the idle timeout (in seconds) after that the test fails */
+#ifndef LWIPERF_TCP_MAX_IDLE_SEC
+#define LWIPERF_TCP_MAX_IDLE_SEC    10U
+#endif
+#if LWIPERF_TCP_MAX_IDLE_SEC > 255
+#error LWIPERF_TCP_MAX_IDLE_SEC must fit into an u8_t
+#endif
+
+/** Change this if you don't want to lwiperf to listen to any IP version */
+#ifndef LWIPERF_SERVER_IP_TYPE
+#define LWIPERF_SERVER_IP_TYPE      IPADDR_TYPE_ANY
+#endif
+
+/* File internal memory allocation (struct lwiperf_*): this defaults to
+   the heap */
+#ifndef LWIPERF_ALLOC
+#define LWIPERF_ALLOC(type)         mem_malloc(sizeof(type))
+#define LWIPERF_FREE(type, item)    mem_free(item)
+#endif
+
+/** If this is 1, check that received data has the correct format */
+#ifndef LWIPERF_CHECK_RX_DATA
+#define LWIPERF_CHECK_RX_DATA       0
+#endif
+
+/** This is the Iperf settings struct sent from the client */
+typedef struct _lwiperf_settings {
+#define LWIPERF_FLAGS_ANSWER_TEST 0x80000000
+#define LWIPERF_FLAGS_ANSWER_NOW  0x00000001
+  u32_t flags;
+  u32_t num_threads; /* unused for now */
+  u32_t remote_port;
+  u32_t buffer_len; /* unused for now */
+  u32_t win_band; /* TCP window / UDP rate: unused for now */
+  u32_t amount; /* pos. value: bytes?; neg. values: time (unit is 10ms: 1/100 second) */
+} lwiperf_settings_t;
+
+/** Basic connection handle */
+struct _lwiperf_state_base;
+typedef struct _lwiperf_state_base lwiperf_state_base_t;
+struct _lwiperf_state_base {
+  /* linked list */
+  lwiperf_state_base_t *next;
+  /* 1=tcp, 0=udp */
+  u8_t tcp;
+  /* 1=server, 0=client */
+  u8_t server;
+  /* master state used to abort sessions (e.g. listener, main client) */
+  lwiperf_state_base_t *related_master_state;
+};
+
+/** Connection handle for a TCP iperf session */
+typedef struct _lwiperf_state_tcp {
+  lwiperf_state_base_t base;
+  struct tcp_pcb *server_pcb;
+  struct tcp_pcb *conn_pcb;
+  u32_t time_started;
+  lwiperf_report_fn report_fn;
+  void *report_arg;
+  u8_t poll_count;
+  u8_t next_num;
+  /* 1=start server when client is closed */
+  u8_t client_tradeoff_mode;
+  u32_t bytes_transferred;
+  lwiperf_settings_t settings;
+  u8_t have_settings_buf;
+  u8_t specific_remote;
+  ip_addr_t remote_addr;
+} lwiperf_state_tcp_t;
+
+/** List of active iperf sessions */
+static lwiperf_state_base_t *lwiperf_all_connections;
+/** A const buffer to send from: we want to measure sending, not copying! */
+static const u8_t lwiperf_txbuf_const[1600] = {
+  '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
+  '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
+  '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
+  '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
+  '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
+  '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
+  '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
+  '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
+  '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
+  '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
+  '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
+  '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
+  '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
+  '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
+  '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
+  '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
+  '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
+  '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
+  '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
+  '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
+  '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
+  '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
+  '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
+  '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
+  '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
+  '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
+  '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
+  '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
+  '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
+  '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
+  '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
+  '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
+  '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
+  '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
+  '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
+  '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
+  '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
+  '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
+  '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
+  '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
+};
+
+static err_t lwiperf_tcp_poll(void *arg, struct tcp_pcb *tpcb);
+static void lwiperf_tcp_err(void *arg, err_t err);
+static err_t lwiperf_start_tcp_server_impl(const ip_addr_t *local_addr, u16_t local_port,
+                                           lwiperf_report_fn report_fn, void *report_arg,
+                                           lwiperf_state_base_t *related_master_state, lwiperf_state_tcp_t **state);
+
+
+/** Add an iperf session to the 'active' list */
+static void
+lwiperf_list_add(lwiperf_state_base_t *item)
+{
+  item->next = lwiperf_all_connections;
+  lwiperf_all_connections = item;
+}
+
+/** Remove an iperf session from the 'active' list */
+static void
+lwiperf_list_remove(lwiperf_state_base_t *item)
+{
+  lwiperf_state_base_t *prev = NULL;
+  lwiperf_state_base_t *iter;
+  for (iter = lwiperf_all_connections; iter != NULL; prev = iter, iter = iter->next) {
+    if (iter == item) {
+      if (prev == NULL) {
+        lwiperf_all_connections = iter->next;
+      } else {
+        prev->next = iter->next;
+      }
+      /* @debug: ensure this item is listed only once */
+      for (iter = iter->next; iter != NULL; iter = iter->next) {
+        LWIP_ASSERT("duplicate entry", iter != item);
+      }
+      break;
+    }
+  }
+}
+
+static lwiperf_state_base_t *
+lwiperf_list_find(lwiperf_state_base_t *item)
+{
+  lwiperf_state_base_t *iter;
+  for (iter = lwiperf_all_connections; iter != NULL; iter = iter->next) {
+    if (iter == item) {
+      return item;
+    }
+  }
+  return NULL;
+}
+
+/** Call the report function of an iperf tcp session */
+static void
+lwip_tcp_conn_report(lwiperf_state_tcp_t *conn, enum lwiperf_report_type report_type)
+{
+  if ((conn != NULL) && (conn->report_fn != NULL)) {
+    u32_t now, duration_ms, bandwidth_kbitpsec;
+    now = sys_now();
+    duration_ms = now - conn->time_started;
+    if (duration_ms == 0) {
+      bandwidth_kbitpsec = 0;
+    } else {
+      bandwidth_kbitpsec = (conn->bytes_transferred / duration_ms) * 8U;
+    }
+    conn->report_fn(conn->report_arg, report_type,
+                    &conn->conn_pcb->local_ip, conn->conn_pcb->local_port,
+                    &conn->conn_pcb->remote_ip, conn->conn_pcb->remote_port,
+                    conn->bytes_transferred, duration_ms, bandwidth_kbitpsec);
+  }
+}
+
+/** Close an iperf tcp session */
+static void
+lwiperf_tcp_close(lwiperf_state_tcp_t *conn, enum lwiperf_report_type report_type)
+{
+  err_t err;
+
+  lwiperf_list_remove(&conn->base);
+  lwip_tcp_conn_report(conn, report_type);
+  if (conn->conn_pcb != NULL) {
+    tcp_arg(conn->conn_pcb, NULL);
+    tcp_poll(conn->conn_pcb, NULL, 0);
+    tcp_sent(conn->conn_pcb, NULL);
+    tcp_recv(conn->conn_pcb, NULL);
+    tcp_err(conn->conn_pcb, NULL);
+    err = tcp_close(conn->conn_pcb);
+    if (err != ERR_OK) {
+      /* don't want to wait for free memory here... */
+      tcp_abort(conn->conn_pcb);
+    }
+  } else {
+    /* no conn pcb, this is the listener pcb */
+    err = tcp_close(conn->server_pcb);
+    LWIP_ASSERT("error", err == ERR_OK);
+  }
+  LWIPERF_FREE(lwiperf_state_tcp_t, conn);
+}
+
+/** Try to send more data on an iperf tcp session */
+static err_t
+lwiperf_tcp_client_send_more(lwiperf_state_tcp_t *conn)
+{
+  int send_more;
+  err_t err;
+  u16_t txlen;
+  u16_t txlen_max;
+  void *txptr;
+  u8_t apiflags;
+
+  LWIP_ASSERT("conn invalid", (conn != NULL) && conn->base.tcp && (conn->base.server == 0));
+
+  do {
+    send_more = 0;
+    if (conn->settings.amount & PP_HTONL(0x80000000)) {
+      /* this session is time-limited */
+      u32_t now = sys_now();
+      u32_t diff_ms = now - conn->time_started;
+      u32_t time = (u32_t) - (s32_t)lwip_htonl(conn->settings.amount);
+      u32_t time_ms = time * 10;
+      if (diff_ms >= time_ms) {
+        /* time specified by the client is over -> close the connection */
+        lwiperf_tcp_close(conn, LWIPERF_TCP_DONE_CLIENT);
+        return ERR_OK;
+      }
+    } else {
+      /* this session is byte-limited */
+      u32_t amount_bytes = lwip_htonl(conn->settings.amount);
+      /* @todo: this can send up to 1*MSS more than requested... */
+      if (amount_bytes >= conn->bytes_transferred) {
+        /* all requested bytes transferred -> close the connection */
+        lwiperf_tcp_close(conn, LWIPERF_TCP_DONE_CLIENT);
+        return ERR_OK;
+      }
+    }
+
+    if (conn->bytes_transferred < 24) {
+      /* transmit the settings a first time */
+      txptr = &((u8_t *)&conn->settings)[conn->bytes_transferred];
+      txlen_max = (u16_t)(24 - conn->bytes_transferred);
+      apiflags = TCP_WRITE_FLAG_COPY;
+    } else if (conn->bytes_transferred < 48) {
+      /* transmit the settings a second time */
+      txptr = &((u8_t *)&conn->settings)[conn->bytes_transferred - 24];
+      txlen_max = (u16_t)(48 - conn->bytes_transferred);
+      apiflags = TCP_WRITE_FLAG_COPY | TCP_WRITE_FLAG_MORE;
+      send_more = 1;
+    } else {
+      /* transmit data */
+      /* @todo: every x bytes, transmit the settings again */
+      txptr = LWIP_CONST_CAST(void *, &lwiperf_txbuf_const[conn->bytes_transferred % 10]);
+      txlen_max = TCP_MSS;
+      if (conn->bytes_transferred == 48) { /* @todo: fix this for intermediate settings, too */
+        txlen_max = TCP_MSS - 24;
+      }
+      apiflags = 0; /* no copying needed */
+      send_more = 1;
+    }
+    txlen = txlen_max;
+    do {
+      err = tcp_write(conn->conn_pcb, txptr, txlen, apiflags);
+      if (err ==  ERR_MEM) {
+        txlen /= 2;
+      }
+    } while ((err == ERR_MEM) && (txlen >= (TCP_MSS / 2)));
+
+    if (err == ERR_OK) {
+      conn->bytes_transferred += txlen;
+    } else {
+      send_more = 0;
+    }
+  } while (send_more);
+
+  tcp_output(conn->conn_pcb);
+  return ERR_OK;
+}
+
+/** TCP sent callback, try to send more data */
+static err_t
+lwiperf_tcp_client_sent(void *arg, struct tcp_pcb *tpcb, u16_t len)
+{
+  lwiperf_state_tcp_t *conn = (lwiperf_state_tcp_t *)arg;
+  /* @todo: check 'len' (e.g. to time ACK of all data)? for now, we just send more... */
+  LWIP_ASSERT("invalid conn", conn->conn_pcb == tpcb);
+  LWIP_UNUSED_ARG(tpcb);
+  LWIP_UNUSED_ARG(len);
+
+  conn->poll_count = 0;
+
+  return lwiperf_tcp_client_send_more(conn);
+}
+
+/** TCP connected callback (active connection), send data now */
+static err_t
+lwiperf_tcp_client_connected(void *arg, struct tcp_pcb *tpcb, err_t err)
+{
+  lwiperf_state_tcp_t *conn = (lwiperf_state_tcp_t *)arg;
+  LWIP_ASSERT("invalid conn", conn->conn_pcb == tpcb);
+  LWIP_UNUSED_ARG(tpcb);
+  if (err != ERR_OK) {
+    lwiperf_tcp_close(conn, LWIPERF_TCP_ABORTED_REMOTE);
+    return ERR_OK;
+  }
+  conn->poll_count = 0;
+  conn->time_started = sys_now();
+  return lwiperf_tcp_client_send_more(conn);
+}
+
+/** Start TCP connection back to the client (either parallel or after the
+ * receive test has finished.
+ */
+static err_t
+lwiperf_tx_start_impl(const ip_addr_t *remote_ip, u16_t remote_port, lwiperf_settings_t *settings, lwiperf_report_fn report_fn,
+                      void *report_arg, lwiperf_state_base_t *related_master_state, lwiperf_state_tcp_t **new_conn)
+{
+  err_t err;
+  lwiperf_state_tcp_t *client_conn;
+  struct tcp_pcb *newpcb;
+  ip_addr_t remote_addr;
+
+  LWIP_ASSERT("remote_ip != NULL", remote_ip != NULL);
+  LWIP_ASSERT("remote_ip != NULL", settings != NULL);
+  LWIP_ASSERT("new_conn != NULL", new_conn != NULL);
+  *new_conn = NULL;
+
+  client_conn = (lwiperf_state_tcp_t *)LWIPERF_ALLOC(lwiperf_state_tcp_t);
+  if (client_conn == NULL) {
+    return ERR_MEM;
+  }
+  newpcb = tcp_new_ip_type(IP_GET_TYPE(remote_ip));
+  if (newpcb == NULL) {
+    LWIPERF_FREE(lwiperf_state_tcp_t, client_conn);
+    return ERR_MEM;
+  }
+  memset(client_conn, 0, sizeof(lwiperf_state_tcp_t));
+  client_conn->base.tcp = 1;
+  client_conn->base.related_master_state = related_master_state;
+  client_conn->conn_pcb = newpcb;
+  client_conn->time_started = sys_now(); /* @todo: set this again on 'connected' */
+  client_conn->report_fn = report_fn;
+  client_conn->report_arg = report_arg;
+  client_conn->next_num = 4; /* initial nr is '4' since the header has 24 byte */
+  client_conn->bytes_transferred = 0;
+  memcpy(&client_conn->settings, settings, sizeof(*settings));
+  client_conn->have_settings_buf = 1;
+
+  tcp_arg(newpcb, client_conn);
+  tcp_sent(newpcb, lwiperf_tcp_client_sent);
+  tcp_poll(newpcb, lwiperf_tcp_poll, 2U);
+  tcp_err(newpcb, lwiperf_tcp_err);
+
+  ip_addr_copy(remote_addr, *remote_ip);
+
+  err = tcp_connect(newpcb, &remote_addr, remote_port, lwiperf_tcp_client_connected);
+  if (err != ERR_OK) {
+    lwiperf_tcp_close(client_conn, LWIPERF_TCP_ABORTED_LOCAL);
+    return err;
+  }
+  lwiperf_list_add(&client_conn->base);
+  *new_conn = client_conn;
+  return ERR_OK;
+}
+
+static err_t
+lwiperf_tx_start_passive(lwiperf_state_tcp_t *conn)
+{
+  err_t ret;
+  lwiperf_state_tcp_t *new_conn = NULL;
+  u16_t remote_port = (u16_t)lwip_htonl(conn->settings.remote_port);
+
+  ret = lwiperf_tx_start_impl(&conn->conn_pcb->remote_ip, remote_port, &conn->settings, conn->report_fn, conn->report_arg,
+    conn->base.related_master_state, &new_conn);
+  if (ret == ERR_OK) {
+    LWIP_ASSERT("new_conn != NULL", new_conn != NULL);
+    new_conn->settings.flags = 0; /* prevent the remote side starting back as client again */
+  }
+  return ret;
+}
+
+/** Receive data on an iperf tcp session */
+static err_t
+lwiperf_tcp_recv(void *arg, struct tcp_pcb *tpcb, struct pbuf *p, err_t err)
+{
+  u8_t tmp;
+  u16_t tot_len;
+  u32_t packet_idx;
+  struct pbuf *q;
+  lwiperf_state_tcp_t *conn = (lwiperf_state_tcp_t *)arg;
+
+  LWIP_ASSERT("pcb mismatch", conn->conn_pcb == tpcb);
+  LWIP_UNUSED_ARG(tpcb);
+
+  if (err != ERR_OK) {
+    lwiperf_tcp_close(conn, LWIPERF_TCP_ABORTED_REMOTE);
+    return ERR_OK;
+  }
+  if (p == NULL) {
+    /* connection closed -> test done */
+    if (conn->settings.flags & PP_HTONL(LWIPERF_FLAGS_ANSWER_TEST)) {
+      if ((conn->settings.flags & PP_HTONL(LWIPERF_FLAGS_ANSWER_NOW)) == 0) {
+        /* client requested transmission after end of test */
+        lwiperf_tx_start_passive(conn);
+      }
+    }
+    lwiperf_tcp_close(conn, LWIPERF_TCP_DONE_SERVER);
+    return ERR_OK;
+  }
+  tot_len = p->tot_len;
+
+  conn->poll_count = 0;
+
+  if ((!conn->have_settings_buf) || ((conn->bytes_transferred - 24) % (1024 * 128) == 0)) {
+    /* wait for 24-byte header */
+    if (p->tot_len < sizeof(lwiperf_settings_t)) {
+      lwiperf_tcp_close(conn, LWIPERF_TCP_ABORTED_LOCAL_DATAERROR);
+      pbuf_free(p);
+      return ERR_OK;
+    }
+    if (!conn->have_settings_buf) {
+      if (pbuf_copy_partial(p, &conn->settings, sizeof(lwiperf_settings_t), 0) != sizeof(lwiperf_settings_t)) {
+        lwiperf_tcp_close(conn, LWIPERF_TCP_ABORTED_LOCAL);
+        pbuf_free(p);
+        return ERR_OK;
+      }
+      conn->have_settings_buf = 1;
+      if (conn->settings.flags & PP_HTONL(LWIPERF_FLAGS_ANSWER_TEST)) {
+        if (conn->settings.flags & PP_HTONL(LWIPERF_FLAGS_ANSWER_NOW)) {
+          /* client requested parallel transmission test */
+          err_t err2 = lwiperf_tx_start_passive(conn);
+          if (err2 != ERR_OK) {
+            lwiperf_tcp_close(conn, LWIPERF_TCP_ABORTED_LOCAL_TXERROR);
+            pbuf_free(p);
+            return ERR_OK;
+          }
+        }
+      }
+    } else {
+      if (conn->settings.flags & PP_HTONL(LWIPERF_FLAGS_ANSWER_TEST)) {
+        if (pbuf_memcmp(p, 0, &conn->settings, sizeof(lwiperf_settings_t)) != 0) {
+          lwiperf_tcp_close(conn, LWIPERF_TCP_ABORTED_LOCAL_DATAERROR);
+          pbuf_free(p);
+          return ERR_OK;
+        }
+      }
+    }
+    conn->bytes_transferred += sizeof(lwiperf_settings_t);
+    if (conn->bytes_transferred <= 24) {
+      conn->time_started = sys_now();
+      tcp_recved(tpcb, p->tot_len);
+      pbuf_free(p);
+      return ERR_OK;
+    }
+    conn->next_num = 4; /* 24 bytes received... */
+    tmp = pbuf_remove_header(p, 24);
+    LWIP_ASSERT("pbuf_remove_header failed", tmp == 0);
+    LWIP_UNUSED_ARG(tmp); /* for LWIP_NOASSERT */
+  }
+
+  packet_idx = 0;
+  for (q = p; q != NULL; q = q->next) {
+#if LWIPERF_CHECK_RX_DATA
+    const u8_t *payload = (const u8_t *)q->payload;
+    u16_t i;
+    for (i = 0; i < q->len; i++) {
+      u8_t val = payload[i];
+      u8_t num = val - '0';
+      if (num == conn->next_num) {
+        conn->next_num++;
+        if (conn->next_num == 10) {
+          conn->next_num = 0;
+        }
+      } else {
+        lwiperf_tcp_close(conn, LWIPERF_TCP_ABORTED_LOCAL_DATAERROR);
+        pbuf_free(p);
+        return ERR_OK;
+      }
+    }
+#endif
+    packet_idx += q->len;
+  }
+  LWIP_ASSERT("count mismatch", packet_idx == p->tot_len);
+  conn->bytes_transferred += packet_idx;
+  tcp_recved(tpcb, tot_len);
+  pbuf_free(p);
+  return ERR_OK;
+}
+
+/** Error callback, iperf tcp session aborted */
+static void
+lwiperf_tcp_err(void *arg, err_t err)
+{
+  lwiperf_state_tcp_t *conn = (lwiperf_state_tcp_t *)arg;
+  LWIP_UNUSED_ARG(err);
+  lwiperf_tcp_close(conn, LWIPERF_TCP_ABORTED_REMOTE);
+}
+
+/** TCP poll callback, try to send more data */
+static err_t
+lwiperf_tcp_poll(void *arg, struct tcp_pcb *tpcb)
+{
+  lwiperf_state_tcp_t *conn = (lwiperf_state_tcp_t *)arg;
+  LWIP_ASSERT("pcb mismatch", conn->conn_pcb == tpcb);
+  LWIP_UNUSED_ARG(tpcb);
+  if (++conn->poll_count >= LWIPERF_TCP_MAX_IDLE_SEC) {
+    lwiperf_tcp_close(conn, LWIPERF_TCP_ABORTED_LOCAL);
+    return ERR_OK; /* lwiperf_tcp_close frees conn */
+  }
+
+  if (!conn->base.server) {
+    lwiperf_tcp_client_send_more(conn);
+  }
+
+  return ERR_OK;
+}
+
+/** This is called when a new client connects for an iperf tcp session */
+static err_t
+lwiperf_tcp_accept(void *arg, struct tcp_pcb *newpcb, err_t err)
+{
+  lwiperf_state_tcp_t *s, *conn;
+  if ((err != ERR_OK) || (newpcb == NULL) || (arg == NULL)) {
+    return ERR_VAL;
+  }
+
+  s = (lwiperf_state_tcp_t *)arg;
+  LWIP_ASSERT("invalid session", s->base.server);
+  LWIP_ASSERT("invalid listen pcb", s->server_pcb != NULL);
+  LWIP_ASSERT("invalid conn pcb", s->conn_pcb == NULL);
+  if (s->specific_remote) {
+    LWIP_ASSERT("s->base.related_master_state != NULL", s->base.related_master_state != NULL);
+    if (!ip_addr_cmp(&newpcb->remote_ip, &s->remote_addr)) {
+      /* this listener belongs to a client session, and this is not the correct remote */
+      return ERR_VAL;
+    }
+  } else {
+    LWIP_ASSERT("s->base.related_master_state == NULL", s->base.related_master_state == NULL);
+  }
+
+  conn = (lwiperf_state_tcp_t *)LWIPERF_ALLOC(lwiperf_state_tcp_t);
+  if (conn == NULL) {
+    return ERR_MEM;
+  }
+  memset(conn, 0, sizeof(lwiperf_state_tcp_t));
+  conn->base.tcp = 1;
+  conn->base.server = 1;
+  conn->base.related_master_state = &s->base;
+  conn->conn_pcb = newpcb;
+  conn->time_started = sys_now();
+  conn->report_fn = s->report_fn;
+  conn->report_arg = s->report_arg;
+
+  /* setup the tcp rx connection */
+  tcp_arg(newpcb, conn);
+  tcp_recv(newpcb, lwiperf_tcp_recv);
+  tcp_poll(newpcb, lwiperf_tcp_poll, 2U);
+  tcp_err(conn->conn_pcb, lwiperf_tcp_err);
+
+  if (s->specific_remote) {
+    /* this listener belongs to a client, so make the client the master of the newly created connection */
+    conn->base.related_master_state = s->base.related_master_state;
+    /* if dual mode or (tradeoff mode AND client is done): close the listener */
+    if (!s->client_tradeoff_mode || !lwiperf_list_find(s->base.related_master_state)) {
+      /* prevent report when closing: this is expected */
+      s->report_fn = NULL;
+      lwiperf_tcp_close(s, LWIPERF_TCP_ABORTED_LOCAL);
+    }
+  }
+  lwiperf_list_add(&conn->base);
+  return ERR_OK;
+}
+
+/**
+ * @ingroup iperf
+ * Start a TCP iperf server on the default TCP port (5001) and listen for
+ * incoming connections from iperf clients.
+ *
+ * @returns a connection handle that can be used to abort the server
+ *          by calling @ref lwiperf_abort()
+ */
+void *
+lwiperf_start_tcp_server_default(lwiperf_report_fn report_fn, void *report_arg)
+{
+  return lwiperf_start_tcp_server(IP_ADDR_ANY, LWIPERF_TCP_PORT_DEFAULT,
+                                  report_fn, report_arg);
+}
+
+/**
+ * @ingroup iperf
+ * Start a TCP iperf server on a specific IP address and port and listen for
+ * incoming connections from iperf clients.
+ *
+ * @returns a connection handle that can be used to abort the server
+ *          by calling @ref lwiperf_abort()
+ */
+void *
+lwiperf_start_tcp_server(const ip_addr_t *local_addr, u16_t local_port,
+                         lwiperf_report_fn report_fn, void *report_arg)
+{
+  err_t err;
+  lwiperf_state_tcp_t *state = NULL;
+
+  err = lwiperf_start_tcp_server_impl(local_addr, local_port, report_fn, report_arg,
+    NULL, &state);
+  if (err == ERR_OK) {
+    return state;
+  }
+  return NULL;
+}
+
+static err_t lwiperf_start_tcp_server_impl(const ip_addr_t *local_addr, u16_t local_port,
+                                           lwiperf_report_fn report_fn, void *report_arg,
+                                           lwiperf_state_base_t *related_master_state, lwiperf_state_tcp_t **state)
+{
+  err_t err;
+  struct tcp_pcb *pcb;
+  lwiperf_state_tcp_t *s;
+
+  LWIP_ASSERT_CORE_LOCKED();
+
+  LWIP_ASSERT("state != NULL", state != NULL);
+
+  if (local_addr == NULL) {
+    return ERR_ARG;
+  }
+
+  s = (lwiperf_state_tcp_t *)LWIPERF_ALLOC(lwiperf_state_tcp_t);
+  if (s == NULL) {
+    return ERR_MEM;
+  }
+  memset(s, 0, sizeof(lwiperf_state_tcp_t));
+  s->base.tcp = 1;
+  s->base.server = 1;
+  s->base.related_master_state = related_master_state;
+  s->report_fn = report_fn;
+  s->report_arg = report_arg;
+
+  pcb = tcp_new_ip_type(LWIPERF_SERVER_IP_TYPE);
+  if (pcb == NULL) {
+    return ERR_MEM;
+  }
+  err = tcp_bind(pcb, local_addr, local_port);
+  if (err != ERR_OK) {
+    return err;
+  }
+  s->server_pcb = tcp_listen_with_backlog(pcb, 1);
+  if (s->server_pcb == NULL) {
+    if (pcb != NULL) {
+      tcp_close(pcb);
+    }
+    LWIPERF_FREE(lwiperf_state_tcp_t, s);
+    return ERR_MEM;
+  }
+  pcb = NULL;
+
+  tcp_arg(s->server_pcb, s);
+  tcp_accept(s->server_pcb, lwiperf_tcp_accept);
+
+  lwiperf_list_add(&s->base);
+  *state = s;
+  return ERR_OK;
+}
+
+/**
+ * @ingroup iperf
+ * Start a TCP iperf client to the default TCP port (5001).
+ *
+ * @returns a connection handle that can be used to abort the client
+ *          by calling @ref lwiperf_abort()
+ */
+void* lwiperf_start_tcp_client_default(const ip_addr_t* remote_addr,
+                               lwiperf_report_fn report_fn, void* report_arg)
+{
+  return lwiperf_start_tcp_client(remote_addr, LWIPERF_TCP_PORT_DEFAULT, LWIPERF_CLIENT,
+                                  report_fn, report_arg);
+}
+
+/**
+ * @ingroup iperf
+ * Start a TCP iperf client to a specific IP address and port.
+ *
+ * @returns a connection handle that can be used to abort the client
+ *          by calling @ref lwiperf_abort()
+ */
+void* lwiperf_start_tcp_client(const ip_addr_t* remote_addr, u16_t remote_port,
+  enum lwiperf_client_type type, lwiperf_report_fn report_fn, void* report_arg)
+{
+  err_t ret;
+  lwiperf_settings_t settings;
+  lwiperf_state_tcp_t *state = NULL;
+
+  memset(&settings, 0, sizeof(settings));
+  switch (type) {
+  case LWIPERF_CLIENT:
+    /* Unidirectional tx only test */
+    settings.flags = 0;
+    break;
+  case LWIPERF_DUAL:
+    /* Do a bidirectional test simultaneously */
+    settings.flags = htonl(LWIPERF_FLAGS_ANSWER_TEST | LWIPERF_FLAGS_ANSWER_NOW);
+    break;
+  case LWIPERF_TRADEOFF:
+    /* Do a bidirectional test individually */
+    settings.flags = htonl(LWIPERF_FLAGS_ANSWER_TEST);
+    break;
+  default:
+    /* invalid argument */
+    return NULL;
+  }
+  settings.num_threads = htonl(1);
+  settings.remote_port = htonl(LWIPERF_TCP_PORT_DEFAULT);
+  /* TODO: implement passing duration/amount of bytes to transfer */
+  settings.amount = htonl((u32_t)-1000);
+
+  ret = lwiperf_tx_start_impl(remote_addr, remote_port, &settings, report_fn, report_arg, NULL, &state);
+  if (ret == ERR_OK) {
+    LWIP_ASSERT("state != NULL", state != NULL);
+    if (type != LWIPERF_CLIENT) {
+      /* start corresponding server now */
+      lwiperf_state_tcp_t *server = NULL;
+      ret = lwiperf_start_tcp_server_impl(&state->conn_pcb->local_ip, LWIPERF_TCP_PORT_DEFAULT,
+        report_fn, report_arg, (lwiperf_state_base_t *)state, &server);
+      if (ret != ERR_OK) {
+        /* starting server failed, abort client */
+        lwiperf_abort(state);
+        return NULL;
+      }
+      /* make this server accept one connection only */
+      server->specific_remote = 1;
+      server->remote_addr = state->conn_pcb->remote_ip;
+      if (type == LWIPERF_TRADEOFF) {
+        /* tradeoff means that the remote host connects only after the client is done,
+           so keep the listen pcb open until the client is done */
+        server->client_tradeoff_mode = 1;
+      }
+    }
+    return state;
+  }
+  return NULL;
+}
+
+/**
+ * @ingroup iperf
+ * Abort an iperf session (handle returned by lwiperf_start_tcp_server*())
+ */
+void
+lwiperf_abort(void *lwiperf_session)
+{
+  lwiperf_state_base_t *i, *dealloc, *last = NULL;
+
+  LWIP_ASSERT_CORE_LOCKED();
+
+  for (i = lwiperf_all_connections; i != NULL; ) {
+    if ((i == lwiperf_session) || (i->related_master_state == lwiperf_session)) {
+      dealloc = i;
+      i = i->next;
+      if (last != NULL) {
+        last->next = i;
+      }
+      LWIPERF_FREE(lwiperf_state_tcp_t, dealloc); /* @todo: type? */
+    } else {
+      last = i;
+      i = i->next;
+    }
+  }
+}
+
+#endif /* LWIP_TCP && LWIP_CALLBACK_API */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/apps/mdns/mdns.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/apps/mdns/mdns.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/apps/mdns/mdns.c	(revision 457)
@@ -0,0 +1,2407 @@
+/**
+ * @file
+ * MDNS responder implementation
+ *
+ * @defgroup mdns MDNS
+ * @ingroup apps
+ *
+ * RFC 6762 - Multicast DNS\n
+ * RFC 6763 - DNS-Based Service Discovery\n
+ *
+ * @verbinclude mdns.txt
+ *
+ * Things left to implement:
+ * -------------------------
+ *
+ * - Tiebreaking for simultaneous probing
+ * - Sending goodbye messages (zero ttl) - shutdown, DHCP lease about to expire, DHCP turned off...
+ * - Checking that source address of unicast requests are on the same network
+ * - Limiting multicast responses to 1 per second per resource record
+ * - Fragmenting replies if required
+ * - Handling multi-packet known answers
+ * - Individual known answer detection for all local IPv6 addresses
+ * - Dynamic size of outgoing packet
+ */
+
+/*
+ * Copyright (c) 2015 Verisure Innovation AB
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Erik Ekman <erik@kryo.se>
+ *
+ */
+
+#include "lwip/apps/mdns.h"
+#include "lwip/apps/mdns_priv.h"
+#include "lwip/netif.h"
+#include "lwip/udp.h"
+#include "lwip/ip_addr.h"
+#include "lwip/mem.h"
+#include "lwip/prot/dns.h"
+#include "lwip/prot/iana.h"
+#include "lwip/timeouts.h"
+
+#include <string.h>
+
+#if LWIP_MDNS_RESPONDER
+
+#if (LWIP_IPV4 && !LWIP_IGMP)
+#error "If you want to use MDNS with IPv4, you have to define LWIP_IGMP=1 in your lwipopts.h"
+#endif
+#if (LWIP_IPV6 && !LWIP_IPV6_MLD)
+#error "If you want to use MDNS with IPv6, you have to define LWIP_IPV6_MLD=1 in your lwipopts.h"
+#endif
+#if (!LWIP_UDP)
+#error "If you want to use MDNS, you have to define LWIP_UDP=1 in your lwipopts.h"
+#endif
+
+#if LWIP_IPV4
+#include "lwip/igmp.h"
+/* IPv4 multicast group 224.0.0.251 */
+static const ip_addr_t v4group = DNS_MQUERY_IPV4_GROUP_INIT;
+#endif
+
+#if LWIP_IPV6
+#include "lwip/mld6.h"
+/* IPv6 multicast group FF02::FB */
+static const ip_addr_t v6group = DNS_MQUERY_IPV6_GROUP_INIT;
+#endif
+
+#define MDNS_TTL  255
+
+/* Stored offsets to beginning of domain names
+ * Used for compression.
+ */
+#define NUM_DOMAIN_OFFSETS 10
+#define DOMAIN_JUMP_SIZE 2
+#define DOMAIN_JUMP 0xc000
+
+static u8_t mdns_netif_client_id;
+static struct udp_pcb *mdns_pcb;
+#if MDNS_RESP_USENETIF_EXTCALLBACK
+NETIF_DECLARE_EXT_CALLBACK(netif_callback)
+#endif
+static mdns_name_result_cb_t mdns_name_result_cb;
+
+#define NETIF_TO_HOST(netif) (struct mdns_host*)(netif_get_client_data(netif, mdns_netif_client_id))
+
+#define TOPDOMAIN_LOCAL "local"
+
+#define REVERSE_PTR_TOPDOMAIN "arpa"
+#define REVERSE_PTR_V4_DOMAIN "in-addr"
+#define REVERSE_PTR_V6_DOMAIN "ip6"
+
+#define SRV_PRIORITY 0
+#define SRV_WEIGHT   0
+
+/* Payload size allocated for each outgoing UDP packet */
+#define OUTPACKET_SIZE 500
+
+/* Lookup from hostname -> IPv4 */
+#define REPLY_HOST_A            0x01
+/* Lookup from IPv4/v6 -> hostname */
+#define REPLY_HOST_PTR_V4       0x02
+/* Lookup from hostname -> IPv6 */
+#define REPLY_HOST_AAAA         0x04
+/* Lookup from hostname -> IPv6 */
+#define REPLY_HOST_PTR_V6       0x08
+
+/* Lookup for service types */
+#define REPLY_SERVICE_TYPE_PTR  0x10
+/* Lookup for instances of service */
+#define REPLY_SERVICE_NAME_PTR  0x20
+/* Lookup for location of service instance */
+#define REPLY_SERVICE_SRV       0x40
+/* Lookup for text info on service instance */
+#define REPLY_SERVICE_TXT       0x80
+
+#define MDNS_PROBE_DELAY_MS       250
+#define MDNS_PROBE_COUNT          3
+#ifdef LWIP_RAND
+/* first probe timeout SHOULD be random 0-250 ms*/
+#define MDNS_INITIAL_PROBE_DELAY_MS (LWIP_RAND() % MDNS_PROBE_DELAY_MS)
+#else
+#define MDNS_INITIAL_PROBE_DELAY_MS MDNS_PROBE_DELAY_MS
+#endif
+
+#define MDNS_PROBING_NOT_STARTED  0
+#define MDNS_PROBING_ONGOING      1
+#define MDNS_PROBING_COMPLETE     2
+
+static const char *dnssd_protos[] = {
+  "_udp", /* DNSSD_PROTO_UDP */
+  "_tcp", /* DNSSD_PROTO_TCP */
+};
+
+/** Description of a service */
+struct mdns_service {
+  /** TXT record to answer with */
+  struct mdns_domain txtdata;
+  /** Name of service, like 'myweb' */
+  char name[MDNS_LABEL_MAXLEN + 1];
+  /** Type of service, like '_http' */
+  char service[MDNS_LABEL_MAXLEN + 1];
+  /** Callback function and userdata
+   * to update txtdata buffer */
+  service_get_txt_fn_t txt_fn;
+  void *txt_userdata;
+  /** TTL in seconds of SRV/TXT replies */
+  u32_t dns_ttl;
+  /** Protocol, TCP or UDP */
+  u16_t proto;
+  /** Port of the service */
+  u16_t port;
+};
+
+/** Description of a host/netif */
+struct mdns_host {
+  /** Hostname */
+  char name[MDNS_LABEL_MAXLEN + 1];
+  /** Pointer to services */
+  struct mdns_service *services[MDNS_MAX_SERVICES];
+  /** TTL in seconds of A/AAAA/PTR replies */
+  u32_t dns_ttl;
+  /** Number of probes sent for the current name */
+  u8_t probes_sent;
+  /** State in probing sequence */
+  u8_t probing_state;
+};
+
+/** Information about received packet */
+struct mdns_packet {
+  /** Sender IP/port */
+  ip_addr_t source_addr;
+  u16_t source_port;
+  /** If packet was received unicast */
+  u16_t recv_unicast;
+  /** Netif that received the packet */
+  struct netif *netif;
+  /** Packet data */
+  struct pbuf *pbuf;
+  /** Current parsing offset in packet */
+  u16_t parse_offset;
+  /** Identifier. Used in legacy queries */
+  u16_t tx_id;
+  /** Number of questions in packet,
+   *  read from packet header */
+  u16_t questions;
+  /** Number of unparsed questions */
+  u16_t questions_left;
+  /** Number of answers in packet,
+   *  (sum of normal, authoritative and additional answers)
+   *  read from packet header */
+  u16_t answers;
+  /** Number of unparsed answers */
+  u16_t answers_left;
+};
+
+/** Information about outgoing packet */
+struct mdns_outpacket {
+  /** Netif to send the packet on */
+  struct netif *netif;
+  /** Packet data */
+  struct pbuf *pbuf;
+  /** Current write offset in packet */
+  u16_t write_offset;
+  /** Identifier. Used in legacy queries */
+  u16_t tx_id;
+  /** Destination IP/port if sent unicast */
+  ip_addr_t dest_addr;
+  u16_t dest_port;
+  /** Number of questions written */
+  u16_t questions;
+  /** Number of normal answers written */
+  u16_t answers;
+  /** Number of authoritative answers written */
+  u16_t authoritative;
+  /** Number of additional answers written */
+  u16_t additional;
+  /** Offsets for written domain names in packet.
+   *  Used for compression */
+  u16_t domain_offsets[NUM_DOMAIN_OFFSETS];
+  /** If all answers in packet should set cache_flush bit */
+  u8_t cache_flush;
+  /** If reply should be sent unicast */
+  u8_t unicast_reply;
+  /** If legacy query. (tx_id needed, and write
+   *  question again in reply before answer) */
+  u8_t legacy_query;
+  /* Reply bitmask for host information */
+  u8_t host_replies;
+  /* Bitmask for which reverse IPv6 hosts to answer */
+  u8_t host_reverse_v6_replies;
+  /* Reply bitmask per service */
+  u8_t serv_replies[MDNS_MAX_SERVICES];
+};
+
+/** Domain, type and class.
+ *  Shared between questions and answers */
+struct mdns_rr_info {
+  struct mdns_domain domain;
+  u16_t type;
+  u16_t klass;
+};
+
+struct mdns_question {
+  struct mdns_rr_info info;
+  /** unicast reply requested */
+  u16_t unicast;
+};
+
+struct mdns_answer {
+  struct mdns_rr_info info;
+  /** cache flush command bit */
+  u16_t cache_flush;
+  /* Validity time in seconds */
+  u32_t ttl;
+  /** Length of variable answer */
+  u16_t rd_length;
+  /** Offset of start of variable answer in packet */
+  u16_t rd_offset;
+};
+
+static err_t mdns_send_outpacket(struct mdns_outpacket *outpkt, u8_t flags);
+static void mdns_probe(void* arg);
+
+static err_t
+mdns_domain_add_label_base(struct mdns_domain *domain, u8_t len)
+{
+  if (len > MDNS_LABEL_MAXLEN) {
+    return ERR_VAL;
+  }
+  if (len > 0 && (1 + len + domain->length >= MDNS_DOMAIN_MAXLEN)) {
+    return ERR_VAL;
+  }
+  /* Allow only zero marker on last byte */
+  if (len == 0 && (1 + domain->length > MDNS_DOMAIN_MAXLEN)) {
+    return ERR_VAL;
+  }
+  domain->name[domain->length] = len;
+  domain->length++;
+  return ERR_OK;
+}
+
+/**
+ * Add a label part to a domain
+ * @param domain The domain to add a label to
+ * @param label The label to add, like &lt;hostname&gt;, 'local', 'com' or ''
+ * @param len The length of the label
+ * @return ERR_OK on success, an err_t otherwise if label too long
+ */
+err_t
+mdns_domain_add_label(struct mdns_domain *domain, const char *label, u8_t len)
+{
+  err_t err = mdns_domain_add_label_base(domain, len);
+  if (err != ERR_OK) {
+    return err;
+  }
+  if (len) {
+    MEMCPY(&domain->name[domain->length], label, len);
+    domain->length += len;
+  }
+  return ERR_OK;
+}
+
+/**
+ * Add a label part to a domain (@see mdns_domain_add_label but copy directly from pbuf)
+ */
+static err_t
+mdns_domain_add_label_pbuf(struct mdns_domain *domain, const struct pbuf *p, u16_t offset, u8_t len)
+{
+  err_t err = mdns_domain_add_label_base(domain, len);
+  if (err != ERR_OK) {
+    return err;
+  }
+  if (len) {
+    if (pbuf_copy_partial(p, &domain->name[domain->length], len, offset) != len) {
+      /* take back the ++ done before */
+      domain->length--;
+      return ERR_ARG;
+    }
+    domain->length += len;
+  }
+  return ERR_OK;
+}
+
+/**
+ * Internal readname function with max 6 levels of recursion following jumps
+ * while decompressing name
+ */
+static u16_t
+mdns_readname_loop(struct pbuf *p, u16_t offset, struct mdns_domain *domain, unsigned depth)
+{
+  u8_t c;
+
+  do {
+    if (depth > 5) {
+      /* Too many jumps */
+      return MDNS_READNAME_ERROR;
+    }
+
+    c = pbuf_get_at(p, offset);
+    offset++;
+
+    /* is this a compressed label? */
+    if ((c & 0xc0) == 0xc0) {
+      u16_t jumpaddr;
+      if (offset >= p->tot_len) {
+        /* Make sure both jump bytes fit in the packet */
+        return MDNS_READNAME_ERROR;
+      }
+      jumpaddr = (((c & 0x3f) << 8) | (pbuf_get_at(p, offset) & 0xff));
+      offset++;
+      if (jumpaddr >= SIZEOF_DNS_HDR && jumpaddr < p->tot_len) {
+        u16_t res;
+        /* Recursive call, maximum depth will be checked */
+        res = mdns_readname_loop(p, jumpaddr, domain, depth + 1);
+        /* Dont return offset since new bytes were not read (jumped to somewhere in packet) */
+        if (res == MDNS_READNAME_ERROR) {
+          return res;
+        }
+      } else {
+        return MDNS_READNAME_ERROR;
+      }
+      break;
+    }
+
+    /* normal label */
+    if (c <= MDNS_LABEL_MAXLEN) {
+      err_t res;
+
+      if (c + domain->length >= MDNS_DOMAIN_MAXLEN) {
+        return MDNS_READNAME_ERROR;
+      }
+      res = mdns_domain_add_label_pbuf(domain, p, offset, c);
+      if (res != ERR_OK) {
+        return MDNS_READNAME_ERROR;
+      }
+      offset += c;
+    } else {
+      /* bad length byte */
+      return MDNS_READNAME_ERROR;
+    }
+  } while (c != 0);
+
+  return offset;
+}
+
+/**
+ * Read possibly compressed domain name from packet buffer
+ * @param p The packet
+ * @param offset start position of domain name in packet
+ * @param domain The domain name destination
+ * @return The new offset after the domain, or MDNS_READNAME_ERROR
+ *         if reading failed
+ */
+u16_t
+mdns_readname(struct pbuf *p, u16_t offset, struct mdns_domain *domain)
+{
+  memset(domain, 0, sizeof(struct mdns_domain));
+  return mdns_readname_loop(p, offset, domain, 0);
+}
+
+/**
+ * Print domain name to debug output
+ * @param domain The domain name
+ */
+static void
+mdns_domain_debug_print(struct mdns_domain *domain)
+{
+  u8_t *src = domain->name;
+  u8_t i;
+
+  while (*src) {
+    u8_t label_len = *src;
+    src++;
+    for (i = 0; i < label_len; i++) {
+      LWIP_DEBUGF(MDNS_DEBUG, ("%c", src[i]));
+    }
+    src += label_len;
+    LWIP_DEBUGF(MDNS_DEBUG, ("."));
+  }
+}
+
+/**
+ * Return 1 if contents of domains match (case-insensitive)
+ * @param a Domain name to compare 1
+ * @param b Domain name to compare 2
+ * @return 1 if domains are equal ignoring case, 0 otherwise
+ */
+int
+mdns_domain_eq(struct mdns_domain *a, struct mdns_domain *b)
+{
+  u8_t *ptra, *ptrb;
+  u8_t len;
+  int res;
+
+  if (a->length != b->length) {
+    return 0;
+  }
+
+  ptra = a->name;
+  ptrb = b->name;
+  while (*ptra && *ptrb && ptra < &a->name[a->length]) {
+    if (*ptra != *ptrb) {
+      return 0;
+    }
+    len = *ptra;
+    ptra++;
+    ptrb++;
+    res = lwip_strnicmp((char *) ptra, (char *) ptrb, len);
+    if (res != 0) {
+      return 0;
+    }
+    ptra += len;
+    ptrb += len;
+  }
+  if (*ptra != *ptrb && ptra < &a->name[a->length]) {
+    return 0;
+  }
+  return 1;
+}
+
+/**
+ * Call user supplied function to setup TXT data
+ * @param service The service to build TXT record for
+ */
+static void
+mdns_prepare_txtdata(struct mdns_service *service)
+{
+  memset(&service->txtdata, 0, sizeof(struct mdns_domain));
+  if (service->txt_fn) {
+    service->txt_fn(service, service->txt_userdata);
+  }
+}
+
+#if LWIP_IPV4
+/**
+ * Build domain for reverse lookup of IPv4 address
+ * like 12.0.168.192.in-addr.arpa. for 192.168.0.12
+ * @param domain Where to write the domain name
+ * @param addr Pointer to an IPv4 address to encode
+ * @return ERR_OK if domain was written, an err_t otherwise
+ */
+static err_t
+mdns_build_reverse_v4_domain(struct mdns_domain *domain, const ip4_addr_t *addr)
+{
+  int i;
+  err_t res;
+  const u8_t *ptr;
+
+  LWIP_UNUSED_ARG(res);
+  if (!domain || !addr) {
+    return ERR_ARG;
+  }
+  memset(domain, 0, sizeof(struct mdns_domain));
+  ptr = (const u8_t *) addr;
+  for (i = sizeof(ip4_addr_t) - 1; i >= 0; i--) {
+    char buf[4];
+    u8_t val = ptr[i];
+
+    lwip_itoa(buf, sizeof(buf), val);
+    res = mdns_domain_add_label(domain, buf, (u8_t)strlen(buf));
+    LWIP_ERROR("mdns_build_reverse_v4_domain: Failed to add label", (res == ERR_OK), return res);
+  }
+  res = mdns_domain_add_label(domain, REVERSE_PTR_V4_DOMAIN, (u8_t)(sizeof(REVERSE_PTR_V4_DOMAIN) - 1));
+  LWIP_ERROR("mdns_build_reverse_v4_domain: Failed to add label", (res == ERR_OK), return res);
+  res = mdns_domain_add_label(domain, REVERSE_PTR_TOPDOMAIN, (u8_t)(sizeof(REVERSE_PTR_TOPDOMAIN) - 1));
+  LWIP_ERROR("mdns_build_reverse_v4_domain: Failed to add label", (res == ERR_OK), return res);
+  res = mdns_domain_add_label(domain, NULL, 0);
+  LWIP_ERROR("mdns_build_reverse_v4_domain: Failed to add label", (res == ERR_OK), return res);
+
+  return ERR_OK;
+}
+#endif
+
+#if LWIP_IPV6
+/**
+ * Build domain for reverse lookup of IP address
+ * like b.a.9.8.7.6.5.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.8.b.d.0.1.0.0.2.ip6.arpa. for 2001:db8::567:89ab
+ * @param domain Where to write the domain name
+ * @param addr Pointer to an IPv6 address to encode
+ * @return ERR_OK if domain was written, an err_t otherwise
+ */
+static err_t
+mdns_build_reverse_v6_domain(struct mdns_domain *domain, const ip6_addr_t *addr)
+{
+  int i;
+  err_t res;
+  const u8_t *ptr;
+  LWIP_UNUSED_ARG(res);
+  if (!domain || !addr) {
+    return ERR_ARG;
+  }
+  memset(domain, 0, sizeof(struct mdns_domain));
+  ptr = (const u8_t *) addr;
+  for (i = sizeof(ip6_addr_p_t) - 1; i >= 0; i--) {
+    char buf;
+    u8_t byte = ptr[i];
+    int j;
+    for (j = 0; j < 2; j++) {
+      if ((byte & 0x0F) < 0xA) {
+        buf = '0' + (byte & 0x0F);
+      } else {
+        buf = 'a' + (byte & 0x0F) - 0xA;
+      }
+      res = mdns_domain_add_label(domain, &buf, sizeof(buf));
+      LWIP_ERROR("mdns_build_reverse_v6_domain: Failed to add label", (res == ERR_OK), return res);
+      byte >>= 4;
+    }
+  }
+  res = mdns_domain_add_label(domain, REVERSE_PTR_V6_DOMAIN, (u8_t)(sizeof(REVERSE_PTR_V6_DOMAIN) - 1));
+  LWIP_ERROR("mdns_build_reverse_v6_domain: Failed to add label", (res == ERR_OK), return res);
+  res = mdns_domain_add_label(domain, REVERSE_PTR_TOPDOMAIN, (u8_t)(sizeof(REVERSE_PTR_TOPDOMAIN) - 1));
+  LWIP_ERROR("mdns_build_reverse_v6_domain: Failed to add label", (res == ERR_OK), return res);
+  res = mdns_domain_add_label(domain, NULL, 0);
+  LWIP_ERROR("mdns_build_reverse_v6_domain: Failed to add label", (res == ERR_OK), return res);
+
+  return ERR_OK;
+}
+#endif
+
+/* Add .local. to domain */
+static err_t
+mdns_add_dotlocal(struct mdns_domain *domain)
+{
+  err_t res = mdns_domain_add_label(domain, TOPDOMAIN_LOCAL, (u8_t)(sizeof(TOPDOMAIN_LOCAL) - 1));
+  LWIP_UNUSED_ARG(res);
+  LWIP_ERROR("mdns_add_dotlocal: Failed to add label", (res == ERR_OK), return res);
+  return mdns_domain_add_label(domain, NULL, 0);
+}
+
+/**
+ * Build the <hostname>.local. domain name
+ * @param domain Where to write the domain name
+ * @param mdns TMDNS netif descriptor.
+ * @return ERR_OK if domain <hostname>.local. was written, an err_t otherwise
+ */
+static err_t
+mdns_build_host_domain(struct mdns_domain *domain, struct mdns_host *mdns)
+{
+  err_t res;
+  LWIP_UNUSED_ARG(res);
+  memset(domain, 0, sizeof(struct mdns_domain));
+  LWIP_ERROR("mdns_build_host_domain: mdns != NULL", (mdns != NULL), return ERR_VAL);
+  res = mdns_domain_add_label(domain, mdns->name, (u8_t)strlen(mdns->name));
+  LWIP_ERROR("mdns_build_host_domain: Failed to add label", (res == ERR_OK), return res);
+  return mdns_add_dotlocal(domain);
+}
+
+/**
+ * Build the lookup-all-services special DNS-SD domain name
+ * @param domain Where to write the domain name
+ * @return ERR_OK if domain _services._dns-sd._udp.local. was written, an err_t otherwise
+ */
+static err_t
+mdns_build_dnssd_domain(struct mdns_domain *domain)
+{
+  err_t res;
+  LWIP_UNUSED_ARG(res);
+  memset(domain, 0, sizeof(struct mdns_domain));
+  res = mdns_domain_add_label(domain, "_services", (u8_t)(sizeof("_services") - 1));
+  LWIP_ERROR("mdns_build_dnssd_domain: Failed to add label", (res == ERR_OK), return res);
+  res = mdns_domain_add_label(domain, "_dns-sd", (u8_t)(sizeof("_dns-sd") - 1));
+  LWIP_ERROR("mdns_build_dnssd_domain: Failed to add label", (res == ERR_OK), return res);
+  res = mdns_domain_add_label(domain, dnssd_protos[DNSSD_PROTO_UDP], (u8_t)strlen(dnssd_protos[DNSSD_PROTO_UDP]));
+  LWIP_ERROR("mdns_build_dnssd_domain: Failed to add label", (res == ERR_OK), return res);
+  return mdns_add_dotlocal(domain);
+}
+
+/**
+ * Build domain name for a service
+ * @param domain Where to write the domain name
+ * @param service The service struct, containing service name, type and protocol
+ * @param include_name Whether to include the service name in the domain
+ * @return ERR_OK if domain was written. If service name is included,
+ *         <name>.<type>.<proto>.local. will be written, otherwise <type>.<proto>.local.
+ *         An err_t is returned on error.
+ */
+static err_t
+mdns_build_service_domain(struct mdns_domain *domain, struct mdns_service *service, int include_name)
+{
+  err_t res;
+  LWIP_UNUSED_ARG(res);
+  memset(domain, 0, sizeof(struct mdns_domain));
+  if (include_name) {
+    res = mdns_domain_add_label(domain, service->name, (u8_t)strlen(service->name));
+    LWIP_ERROR("mdns_build_service_domain: Failed to add label", (res == ERR_OK), return res);
+  }
+  res = mdns_domain_add_label(domain, service->service, (u8_t)strlen(service->service));
+  LWIP_ERROR("mdns_build_service_domain: Failed to add label", (res == ERR_OK), return res);
+  res = mdns_domain_add_label(domain, dnssd_protos[service->proto], (u8_t)strlen(dnssd_protos[service->proto]));
+  LWIP_ERROR("mdns_build_service_domain: Failed to add label", (res == ERR_OK), return res);
+  return mdns_add_dotlocal(domain);
+}
+
+/**
+ * Check which replies we should send for a host/netif based on question
+ * @param netif The network interface that received the question
+ * @param rr Domain/type/class from a question
+ * @param reverse_v6_reply Bitmask of which IPv6 addresses to send reverse PTRs for
+ *                         if reply bit has REPLY_HOST_PTR_V6 set
+ * @return Bitmask of which replies to send
+ */
+static int
+check_host(struct netif *netif, struct mdns_rr_info *rr, u8_t *reverse_v6_reply)
+{
+  err_t res;
+  int replies = 0;
+  struct mdns_domain mydomain;
+
+  LWIP_UNUSED_ARG(reverse_v6_reply); /* if ipv6 is disabled */
+
+  if (rr->klass != DNS_RRCLASS_IN && rr->klass != DNS_RRCLASS_ANY) {
+    /* Invalid class */
+    return replies;
+  }
+
+  /* Handle PTR for our addresses */
+  if (rr->type == DNS_RRTYPE_PTR || rr->type == DNS_RRTYPE_ANY) {
+#if LWIP_IPV6
+    int i;
+    for (i = 0; i < LWIP_IPV6_NUM_ADDRESSES; i++) {
+      if (ip6_addr_isvalid(netif_ip6_addr_state(netif, i))) {
+        res = mdns_build_reverse_v6_domain(&mydomain, netif_ip6_addr(netif, i));
+        if (res == ERR_OK && mdns_domain_eq(&rr->domain, &mydomain)) {
+          replies |= REPLY_HOST_PTR_V6;
+          /* Mark which addresses where requested */
+          if (reverse_v6_reply) {
+            *reverse_v6_reply |= (1 << i);
+          }
+        }
+      }
+    }
+#endif
+#if LWIP_IPV4
+    if (!ip4_addr_isany_val(*netif_ip4_addr(netif))) {
+      res = mdns_build_reverse_v4_domain(&mydomain, netif_ip4_addr(netif));
+      if (res == ERR_OK && mdns_domain_eq(&rr->domain, &mydomain)) {
+        replies |= REPLY_HOST_PTR_V4;
+      }
+    }
+#endif
+  }
+
+  res = mdns_build_host_domain(&mydomain, NETIF_TO_HOST(netif));
+  /* Handle requests for our hostname */
+  if (res == ERR_OK && mdns_domain_eq(&rr->domain, &mydomain)) {
+    /* TODO return NSEC if unsupported protocol requested */
+#if LWIP_IPV4
+    if (!ip4_addr_isany_val(*netif_ip4_addr(netif))
+        && (rr->type == DNS_RRTYPE_A || rr->type == DNS_RRTYPE_ANY)) {
+      replies |= REPLY_HOST_A;
+    }
+#endif
+#if LWIP_IPV6
+    if (rr->type == DNS_RRTYPE_AAAA || rr->type == DNS_RRTYPE_ANY) {
+      replies |= REPLY_HOST_AAAA;
+    }
+#endif
+  }
+
+  return replies;
+}
+
+/**
+ * Check which replies we should send for a service based on question
+ * @param service A registered MDNS service
+ * @param rr Domain/type/class from a question
+ * @return Bitmask of which replies to send
+ */
+static int
+check_service(struct mdns_service *service, struct mdns_rr_info *rr)
+{
+  err_t res;
+  int replies = 0;
+  struct mdns_domain mydomain;
+
+  if (rr->klass != DNS_RRCLASS_IN && rr->klass != DNS_RRCLASS_ANY) {
+    /* Invalid class */
+    return 0;
+  }
+
+  res = mdns_build_dnssd_domain(&mydomain);
+  if (res == ERR_OK && mdns_domain_eq(&rr->domain, &mydomain) &&
+      (rr->type == DNS_RRTYPE_PTR || rr->type == DNS_RRTYPE_ANY)) {
+    /* Request for all service types */
+    replies |= REPLY_SERVICE_TYPE_PTR;
+  }
+
+  res = mdns_build_service_domain(&mydomain, service, 0);
+  if (res == ERR_OK && mdns_domain_eq(&rr->domain, &mydomain) &&
+      (rr->type == DNS_RRTYPE_PTR || rr->type == DNS_RRTYPE_ANY)) {
+    /* Request for the instance of my service */
+    replies |= REPLY_SERVICE_NAME_PTR;
+  }
+
+  res = mdns_build_service_domain(&mydomain, service, 1);
+  if (res == ERR_OK && mdns_domain_eq(&rr->domain, &mydomain)) {
+    /* Request for info about my service */
+    if (rr->type == DNS_RRTYPE_SRV || rr->type == DNS_RRTYPE_ANY) {
+      replies |= REPLY_SERVICE_SRV;
+    }
+    if (rr->type == DNS_RRTYPE_TXT || rr->type == DNS_RRTYPE_ANY) {
+      replies |= REPLY_SERVICE_TXT;
+    }
+  }
+
+  return replies;
+}
+
+/**
+ * Return bytes needed to write before jump for best result of compressing supplied domain
+ * against domain in outpacket starting at specified offset.
+ * If a match is found, offset is updated to where to jump to
+ * @param pbuf Pointer to pbuf with the partially constructed DNS packet
+ * @param offset Start position of a domain written earlier. If this location is suitable
+ *               for compression, the pointer is updated to where in the domain to jump to.
+ * @param domain The domain to write
+ * @return Number of bytes to write of the new domain before writing a jump to the offset.
+ *         If compression can not be done against this previous domain name, the full new
+ *         domain length is returned.
+ */
+u16_t
+mdns_compress_domain(struct pbuf *pbuf, u16_t *offset, struct mdns_domain *domain)
+{
+  struct mdns_domain target;
+  u16_t target_end;
+  u8_t target_len;
+  u8_t writelen = 0;
+  u8_t *ptr;
+  if (pbuf == NULL) {
+    return domain->length;
+  }
+  target_end = mdns_readname(pbuf, *offset, &target);
+  if (target_end == MDNS_READNAME_ERROR) {
+    return domain->length;
+  }
+  target_len = (u8_t)(target_end - *offset);
+  ptr = domain->name;
+  while (writelen < domain->length) {
+    u8_t domainlen = (u8_t)(domain->length - writelen);
+    u8_t labellen;
+    if (domainlen <= target.length && domainlen > DOMAIN_JUMP_SIZE) {
+      /* Compare domains if target is long enough, and we have enough left of the domain */
+      u8_t targetpos = (u8_t)(target.length - domainlen);
+      if ((targetpos + DOMAIN_JUMP_SIZE) >= target_len) {
+        /* We are checking at or beyond a jump in the original, stop looking */
+        break;
+      }
+      if (target.length >= domainlen &&
+          memcmp(&domain->name[writelen], &target.name[targetpos], domainlen) == 0) {
+        *offset += targetpos;
+        return writelen;
+      }
+    }
+    /* Skip to next label in domain */
+    labellen = *ptr;
+    writelen += 1 + labellen;
+    ptr += 1 + labellen;
+  }
+  /* Nothing found */
+  return domain->length;
+}
+
+/**
+ * Write domain to outpacket. Compression will be attempted,
+ * unless domain->skip_compression is set.
+ * @param outpkt The outpacket to write to
+ * @param domain The domain name to write
+ * @return ERR_OK on success, an err_t otherwise
+ */
+static err_t
+mdns_write_domain(struct mdns_outpacket *outpkt, struct mdns_domain *domain)
+{
+  int i;
+  err_t res;
+  u16_t writelen = domain->length;
+  u16_t jump_offset = 0;
+  u16_t jump;
+
+  if (!domain->skip_compression) {
+    for (i = 0; i < NUM_DOMAIN_OFFSETS; i++) {
+      u16_t offset = outpkt->domain_offsets[i];
+      if (offset) {
+        u16_t len = mdns_compress_domain(outpkt->pbuf, &offset, domain);
+        if (len < writelen) {
+          writelen = len;
+          jump_offset = offset;
+        }
+      }
+    }
+  }
+
+  if (writelen) {
+    /* Write uncompressed part of name */
+    res = pbuf_take_at(outpkt->pbuf, domain->name, writelen, outpkt->write_offset);
+    if (res != ERR_OK) {
+      return res;
+    }
+
+    /* Store offset of this new domain */
+    for (i = 0; i < NUM_DOMAIN_OFFSETS; i++) {
+      if (outpkt->domain_offsets[i] == 0) {
+        outpkt->domain_offsets[i] = outpkt->write_offset;
+        break;
+      }
+    }
+
+    outpkt->write_offset += writelen;
+  }
+  if (jump_offset) {
+    /* Write jump */
+    jump = lwip_htons(DOMAIN_JUMP | jump_offset);
+    res = pbuf_take_at(outpkt->pbuf, &jump, DOMAIN_JUMP_SIZE, outpkt->write_offset);
+    if (res != ERR_OK) {
+      return res;
+    }
+    outpkt->write_offset += DOMAIN_JUMP_SIZE;
+  }
+  return ERR_OK;
+}
+
+/**
+ * Write a question to an outpacket
+ * A question contains domain, type and class. Since an answer also starts with these fields this function is also
+ * called from mdns_add_answer().
+ * @param outpkt The outpacket to write to
+ * @param domain The domain name the answer is for
+ * @param type The DNS type of the answer (like 'AAAA', 'SRV')
+ * @param klass The DNS type of the answer (like 'IN')
+ * @param unicast If highest bit in class should be set, to instruct the responder to
+ *                reply with a unicast packet
+ * @return ERR_OK on success, an err_t otherwise
+ */
+static err_t
+mdns_add_question(struct mdns_outpacket *outpkt, struct mdns_domain *domain, u16_t type, u16_t klass, u16_t unicast)
+{
+  u16_t question_len;
+  u16_t field16;
+  err_t res;
+
+  if (!outpkt->pbuf) {
+    /* If no pbuf is active, allocate one */
+    outpkt->pbuf = pbuf_alloc(PBUF_TRANSPORT, OUTPACKET_SIZE, PBUF_RAM);
+    if (!outpkt->pbuf) {
+      return ERR_MEM;
+    }
+    outpkt->write_offset = SIZEOF_DNS_HDR;
+  }
+
+  /* Worst case calculation. Domain string might be compressed */
+  question_len = domain->length + sizeof(type) + sizeof(klass);
+  if (outpkt->write_offset + question_len > outpkt->pbuf->tot_len) {
+    /* No space */
+    return ERR_MEM;
+  }
+
+  /* Write name */
+  res = mdns_write_domain(outpkt, domain);
+  if (res != ERR_OK) {
+    return res;
+  }
+
+  /* Write type */
+  field16 = lwip_htons(type);
+  res = pbuf_take_at(outpkt->pbuf, &field16, sizeof(field16), outpkt->write_offset);
+  if (res != ERR_OK) {
+    return res;
+  }
+  outpkt->write_offset += sizeof(field16);
+
+  /* Write class */
+  if (unicast) {
+    klass |= 0x8000;
+  }
+  field16 = lwip_htons(klass);
+  res = pbuf_take_at(outpkt->pbuf, &field16, sizeof(field16), outpkt->write_offset);
+  if (res != ERR_OK) {
+    return res;
+  }
+  outpkt->write_offset += sizeof(field16);
+
+  return ERR_OK;
+}
+
+/**
+ * Write answer to reply packet.
+ * buf or answer_domain can be null. The rd_length written will be buf_length +
+ * size of (compressed) domain. Most uses will need either buf or answer_domain,
+ * special case is SRV that starts with 3 u16 and then a domain name.
+ * @param reply The outpacket to write to
+ * @param domain The domain name the answer is for
+ * @param type The DNS type of the answer (like 'AAAA', 'SRV')
+ * @param klass The DNS type of the answer (like 'IN')
+ * @param cache_flush If highest bit in class should be set, to instruct receiver that
+ *                    this reply replaces any earlier answer for this domain/type/class
+ * @param ttl Validity time in seconds to send out for IP address data in DNS replies
+ * @param buf Pointer to buffer of answer data
+ * @param buf_length Length of variable data
+ * @param answer_domain A domain to write after any buffer data as answer
+ * @return ERR_OK on success, an err_t otherwise
+ */
+static err_t
+mdns_add_answer(struct mdns_outpacket *reply, struct mdns_domain *domain, u16_t type, u16_t klass, u16_t cache_flush,
+                u32_t ttl, const u8_t *buf, size_t buf_length, struct mdns_domain *answer_domain)
+{
+  u16_t answer_len;
+  u16_t field16;
+  u16_t rdlen_offset;
+  u16_t answer_offset;
+  u32_t field32;
+  err_t res;
+
+  if (!reply->pbuf) {
+    /* If no pbuf is active, allocate one */
+    reply->pbuf = pbuf_alloc(PBUF_TRANSPORT, OUTPACKET_SIZE, PBUF_RAM);
+    if (!reply->pbuf) {
+      return ERR_MEM;
+    }
+    reply->write_offset = SIZEOF_DNS_HDR;
+  }
+
+  /* Worst case calculation. Domain strings might be compressed */
+  answer_len = domain->length + sizeof(type) + sizeof(klass) + sizeof(ttl) + sizeof(field16)/*rd_length*/;
+  if (buf) {
+    answer_len += (u16_t)buf_length;
+  }
+  if (answer_domain) {
+    answer_len += answer_domain->length;
+  }
+  if (reply->write_offset + answer_len > reply->pbuf->tot_len) {
+    /* No space */
+    return ERR_MEM;
+  }
+
+  /* Answer starts with same data as question, then more fields */
+  mdns_add_question(reply, domain, type, klass, cache_flush);
+
+  /* Write TTL */
+  field32 = lwip_htonl(ttl);
+  res = pbuf_take_at(reply->pbuf, &field32, sizeof(field32), reply->write_offset);
+  if (res != ERR_OK) {
+    return res;
+  }
+  reply->write_offset += sizeof(field32);
+
+  /* Store offsets and skip forward to the data */
+  rdlen_offset = reply->write_offset;
+  reply->write_offset += sizeof(field16);
+  answer_offset = reply->write_offset;
+
+  if (buf) {
+    /* Write static data */
+    res = pbuf_take_at(reply->pbuf, buf, (u16_t)buf_length, reply->write_offset);
+    if (res != ERR_OK) {
+      return res;
+    }
+    reply->write_offset += (u16_t)buf_length;
+  }
+
+  if (answer_domain) {
+    /* Write name answer (compressed if possible) */
+    res = mdns_write_domain(reply, answer_domain);
+    if (res != ERR_OK) {
+      return res;
+    }
+  }
+
+  /* Write rd_length after when we know the answer size */
+  field16 = lwip_htons(reply->write_offset - answer_offset);
+  res = pbuf_take_at(reply->pbuf, &field16, sizeof(field16), rdlen_offset);
+
+  return res;
+}
+
+/**
+ * Helper function for mdns_read_question/mdns_read_answer
+ * Reads a domain, type and class from the packet
+ * @param pkt The MDNS packet to read from. The parse_offset field will be
+ *            incremented to point to the next unparsed byte.
+ * @param info The struct to fill with domain, type and class
+ * @return ERR_OK on success, an err_t otherwise
+ */
+static err_t
+mdns_read_rr_info(struct mdns_packet *pkt, struct mdns_rr_info *info)
+{
+  u16_t field16, copied;
+  pkt->parse_offset = mdns_readname(pkt->pbuf, pkt->parse_offset, &info->domain);
+  if (pkt->parse_offset == MDNS_READNAME_ERROR) {
+    return ERR_VAL;
+  }
+
+  copied = pbuf_copy_partial(pkt->pbuf, &field16, sizeof(field16), pkt->parse_offset);
+  if (copied != sizeof(field16)) {
+    return ERR_VAL;
+  }
+  pkt->parse_offset += copied;
+  info->type = lwip_ntohs(field16);
+
+  copied = pbuf_copy_partial(pkt->pbuf, &field16, sizeof(field16), pkt->parse_offset);
+  if (copied != sizeof(field16)) {
+    return ERR_VAL;
+  }
+  pkt->parse_offset += copied;
+  info->klass = lwip_ntohs(field16);
+
+  return ERR_OK;
+}
+
+/**
+ * Read a question from the packet.
+ * All questions have to be read before the answers.
+ * @param pkt The MDNS packet to read from. The questions_left field will be decremented
+ *            and the parse_offset will be updated.
+ * @param question The struct to fill with question data
+ * @return ERR_OK on success, an err_t otherwise
+ */
+static err_t
+mdns_read_question(struct mdns_packet *pkt, struct mdns_question *question)
+{
+  /* Safety check */
+  if (pkt->pbuf->tot_len < pkt->parse_offset) {
+    return ERR_VAL;
+  }
+
+  if (pkt->questions_left) {
+    err_t res;
+    pkt->questions_left--;
+
+    memset(question, 0, sizeof(struct mdns_question));
+    res = mdns_read_rr_info(pkt, &question->info);
+    if (res != ERR_OK) {
+      return res;
+    }
+
+    /* Extract unicast flag from class field */
+    question->unicast = question->info.klass & 0x8000;
+    question->info.klass &= 0x7FFF;
+
+    return ERR_OK;
+  }
+  return ERR_VAL;
+}
+
+/**
+ * Read an answer from the packet
+ * The variable length reply is not copied, its pbuf offset and length is stored instead.
+ * @param pkt The MDNS packet to read. The answers_left field will be decremented and
+ *            the parse_offset will be updated.
+ * @param answer The struct to fill with answer data
+ * @return ERR_OK on success, an err_t otherwise
+ */
+static err_t
+mdns_read_answer(struct mdns_packet *pkt, struct mdns_answer *answer)
+{
+  /* Read questions first */
+  if (pkt->questions_left) {
+    return ERR_VAL;
+  }
+
+  /* Safety check */
+  if (pkt->pbuf->tot_len < pkt->parse_offset) {
+    return ERR_VAL;
+  }
+
+  if (pkt->answers_left) {
+    u16_t copied, field16;
+    u32_t ttl;
+    err_t res;
+    pkt->answers_left--;
+
+    memset(answer, 0, sizeof(struct mdns_answer));
+    res = mdns_read_rr_info(pkt, &answer->info);
+    if (res != ERR_OK) {
+      return res;
+    }
+
+    /* Extract cache_flush flag from class field */
+    answer->cache_flush = answer->info.klass & 0x8000;
+    answer->info.klass &= 0x7FFF;
+
+    copied = pbuf_copy_partial(pkt->pbuf, &ttl, sizeof(ttl), pkt->parse_offset);
+    if (copied != sizeof(ttl)) {
+      return ERR_VAL;
+    }
+    pkt->parse_offset += copied;
+    answer->ttl = lwip_ntohl(ttl);
+
+    copied = pbuf_copy_partial(pkt->pbuf, &field16, sizeof(field16), pkt->parse_offset);
+    if (copied != sizeof(field16)) {
+      return ERR_VAL;
+    }
+    pkt->parse_offset += copied;
+    answer->rd_length = lwip_ntohs(field16);
+
+    answer->rd_offset = pkt->parse_offset;
+    pkt->parse_offset += answer->rd_length;
+
+    return ERR_OK;
+  }
+  return ERR_VAL;
+}
+
+#if LWIP_IPV4
+/** Write an IPv4 address (A) RR to outpacket */
+static err_t
+mdns_add_a_answer(struct mdns_outpacket *reply, u16_t cache_flush, struct netif *netif)
+{
+  struct mdns_domain host;
+  mdns_build_host_domain(&host, NETIF_TO_HOST(netif));
+  LWIP_DEBUGF(MDNS_DEBUG, ("MDNS: Responding with A record\n"));
+  return mdns_add_answer(reply, &host, DNS_RRTYPE_A, DNS_RRCLASS_IN, cache_flush, (NETIF_TO_HOST(netif))->dns_ttl, (const u8_t *) netif_ip4_addr(netif), sizeof(ip4_addr_t), NULL);
+}
+
+/** Write a 4.3.2.1.in-addr.arpa -> hostname.local PTR RR to outpacket */
+static err_t
+mdns_add_hostv4_ptr_answer(struct mdns_outpacket *reply, u16_t cache_flush, struct netif *netif)
+{
+  struct mdns_domain host, revhost;
+  mdns_build_host_domain(&host, NETIF_TO_HOST(netif));
+  mdns_build_reverse_v4_domain(&revhost, netif_ip4_addr(netif));
+  LWIP_DEBUGF(MDNS_DEBUG, ("MDNS: Responding with v4 PTR record\n"));
+  return mdns_add_answer(reply, &revhost, DNS_RRTYPE_PTR, DNS_RRCLASS_IN, cache_flush, (NETIF_TO_HOST(netif))->dns_ttl, NULL, 0, &host);
+}
+#endif
+
+#if LWIP_IPV6
+/** Write an IPv6 address (AAAA) RR to outpacket */
+static err_t
+mdns_add_aaaa_answer(struct mdns_outpacket *reply, u16_t cache_flush, struct netif *netif, int addrindex)
+{
+  struct mdns_domain host;
+  mdns_build_host_domain(&host, NETIF_TO_HOST(netif));
+  LWIP_DEBUGF(MDNS_DEBUG, ("MDNS: Responding with AAAA record\n"));
+  return mdns_add_answer(reply, &host, DNS_RRTYPE_AAAA, DNS_RRCLASS_IN, cache_flush, (NETIF_TO_HOST(netif))->dns_ttl, (const u8_t *) netif_ip6_addr(netif, addrindex), sizeof(ip6_addr_p_t), NULL);
+}
+
+/** Write a x.y.z.ip6.arpa -> hostname.local PTR RR to outpacket */
+static err_t
+mdns_add_hostv6_ptr_answer(struct mdns_outpacket *reply, u16_t cache_flush, struct netif *netif, int addrindex)
+{
+  struct mdns_domain host, revhost;
+  mdns_build_host_domain(&host, NETIF_TO_HOST(netif));
+  mdns_build_reverse_v6_domain(&revhost, netif_ip6_addr(netif, addrindex));
+  LWIP_DEBUGF(MDNS_DEBUG, ("MDNS: Responding with v6 PTR record\n"));
+  return mdns_add_answer(reply, &revhost, DNS_RRTYPE_PTR, DNS_RRCLASS_IN, cache_flush, (NETIF_TO_HOST(netif))->dns_ttl, NULL, 0, &host);
+}
+#endif
+
+/** Write an all-services -> servicetype PTR RR to outpacket */
+static err_t
+mdns_add_servicetype_ptr_answer(struct mdns_outpacket *reply, struct mdns_service *service)
+{
+  struct mdns_domain service_type, service_dnssd;
+  mdns_build_service_domain(&service_type, service, 0);
+  mdns_build_dnssd_domain(&service_dnssd);
+  LWIP_DEBUGF(MDNS_DEBUG, ("MDNS: Responding with service type PTR record\n"));
+  return mdns_add_answer(reply, &service_dnssd, DNS_RRTYPE_PTR, DNS_RRCLASS_IN, 0, service->dns_ttl, NULL, 0, &service_type);
+}
+
+/** Write a servicetype -> servicename PTR RR to outpacket */
+static err_t
+mdns_add_servicename_ptr_answer(struct mdns_outpacket *reply, struct mdns_service *service)
+{
+  struct mdns_domain service_type, service_instance;
+  mdns_build_service_domain(&service_type, service, 0);
+  mdns_build_service_domain(&service_instance, service, 1);
+  LWIP_DEBUGF(MDNS_DEBUG, ("MDNS: Responding with service name PTR record\n"));
+  return mdns_add_answer(reply, &service_type, DNS_RRTYPE_PTR, DNS_RRCLASS_IN, 0, service->dns_ttl, NULL, 0, &service_instance);
+}
+
+/** Write a SRV RR to outpacket */
+static err_t
+mdns_add_srv_answer(struct mdns_outpacket *reply, u16_t cache_flush, struct mdns_host *mdns, struct mdns_service *service)
+{
+  struct mdns_domain service_instance, srvhost;
+  u16_t srvdata[3];
+  mdns_build_service_domain(&service_instance, service, 1);
+  mdns_build_host_domain(&srvhost, mdns);
+  if (reply->legacy_query) {
+    /* RFC 6762 section 18.14:
+     * In legacy unicast responses generated to answer legacy queries,
+     * name compression MUST NOT be performed on SRV records.
+     */
+    srvhost.skip_compression = 1;
+  }
+  srvdata[0] = lwip_htons(SRV_PRIORITY);
+  srvdata[1] = lwip_htons(SRV_WEIGHT);
+  srvdata[2] = lwip_htons(service->port);
+  LWIP_DEBUGF(MDNS_DEBUG, ("MDNS: Responding with SRV record\n"));
+  return mdns_add_answer(reply, &service_instance, DNS_RRTYPE_SRV, DNS_RRCLASS_IN, cache_flush, service->dns_ttl,
+                         (const u8_t *) &srvdata, sizeof(srvdata), &srvhost);
+}
+
+/** Write a TXT RR to outpacket */
+static err_t
+mdns_add_txt_answer(struct mdns_outpacket *reply, u16_t cache_flush, struct mdns_service *service)
+{
+  struct mdns_domain service_instance;
+  mdns_build_service_domain(&service_instance, service, 1);
+  mdns_prepare_txtdata(service);
+  LWIP_DEBUGF(MDNS_DEBUG, ("MDNS: Responding with TXT record\n"));
+  return mdns_add_answer(reply, &service_instance, DNS_RRTYPE_TXT, DNS_RRCLASS_IN, cache_flush, service->dns_ttl,
+                         (u8_t *) &service->txtdata.name, service->txtdata.length, NULL);
+}
+
+/**
+ * Setup outpacket as a reply to the incoming packet
+ */
+static void
+mdns_init_outpacket(struct mdns_outpacket *out, struct mdns_packet *in)
+{
+  memset(out, 0, sizeof(struct mdns_outpacket));
+  out->cache_flush = 1;
+  out->netif = in->netif;
+
+  /* Copy source IP/port to use when responding unicast, or to choose
+   * which pcb to use for multicast (IPv4/IPv6)
+   */
+  SMEMCPY(&out->dest_addr, &in->source_addr, sizeof(ip_addr_t));
+  out->dest_port = in->source_port;
+
+  if (in->source_port != LWIP_IANA_PORT_MDNS) {
+    out->unicast_reply = 1;
+    out->cache_flush = 0;
+    if (in->questions == 1) {
+      out->legacy_query = 1;
+      out->tx_id = in->tx_id;
+    }
+  }
+
+  if (in->recv_unicast) {
+    out->unicast_reply = 1;
+  }
+}
+
+/**
+ * Send chosen answers as a reply
+ *
+ * Add all selected answers (first write will allocate pbuf)
+ * Add additional answers based on the selected answers
+ * Send the packet
+ */
+static err_t
+mdns_send_outpacket(struct mdns_outpacket *outpkt, u8_t flags)
+{
+  struct mdns_service *service;
+  err_t res = ERR_ARG;
+  int i;
+  struct mdns_host *mdns = NETIF_TO_HOST(outpkt->netif);
+  u16_t answers = 0;
+
+  /* Write answers to host questions */
+#if LWIP_IPV4
+  if (outpkt->host_replies & REPLY_HOST_A) {
+    res = mdns_add_a_answer(outpkt, outpkt->cache_flush, outpkt->netif);
+    if (res != ERR_OK) {
+      goto cleanup;
+    }
+    answers++;
+  }
+  if (outpkt->host_replies & REPLY_HOST_PTR_V4) {
+    res = mdns_add_hostv4_ptr_answer(outpkt, outpkt->cache_flush, outpkt->netif);
+    if (res != ERR_OK) {
+      goto cleanup;
+    }
+    answers++;
+  }
+#endif
+#if LWIP_IPV6
+  if (outpkt->host_replies & REPLY_HOST_AAAA) {
+    int addrindex;
+    for (addrindex = 0; addrindex < LWIP_IPV6_NUM_ADDRESSES; addrindex++) {
+      if (ip6_addr_isvalid(netif_ip6_addr_state(outpkt->netif, addrindex))) {
+        res = mdns_add_aaaa_answer(outpkt, outpkt->cache_flush, outpkt->netif, addrindex);
+        if (res != ERR_OK) {
+          goto cleanup;
+        }
+        answers++;
+      }
+    }
+  }
+  if (outpkt->host_replies & REPLY_HOST_PTR_V6) {
+    u8_t rev_addrs = outpkt->host_reverse_v6_replies;
+    int addrindex = 0;
+    while (rev_addrs) {
+      if (rev_addrs & 1) {
+        res = mdns_add_hostv6_ptr_answer(outpkt, outpkt->cache_flush, outpkt->netif, addrindex);
+        if (res != ERR_OK) {
+          goto cleanup;
+        }
+        answers++;
+      }
+      addrindex++;
+      rev_addrs >>= 1;
+    }
+  }
+#endif
+
+  /* Write answers to service questions */
+  for (i = 0; i < MDNS_MAX_SERVICES; i++) {
+    service = mdns->services[i];
+    if (!service) {
+      continue;
+    }
+
+    if (outpkt->serv_replies[i] & REPLY_SERVICE_TYPE_PTR) {
+      res = mdns_add_servicetype_ptr_answer(outpkt, service);
+      if (res != ERR_OK) {
+        goto cleanup;
+      }
+      answers++;
+    }
+
+    if (outpkt->serv_replies[i] & REPLY_SERVICE_NAME_PTR) {
+      res = mdns_add_servicename_ptr_answer(outpkt, service);
+      if (res != ERR_OK) {
+        goto cleanup;
+      }
+      answers++;
+    }
+
+    if (outpkt->serv_replies[i] & REPLY_SERVICE_SRV) {
+      res = mdns_add_srv_answer(outpkt, outpkt->cache_flush, mdns, service);
+      if (res != ERR_OK) {
+        goto cleanup;
+      }
+      answers++;
+    }
+
+    if (outpkt->serv_replies[i] & REPLY_SERVICE_TXT) {
+      res = mdns_add_txt_answer(outpkt, outpkt->cache_flush, service);
+      if (res != ERR_OK) {
+        goto cleanup;
+      }
+      answers++;
+    }
+  }
+
+  /* if this is a response, the data above is anwers, else this is a probe and the answers above goes into auth section */
+  if (flags & DNS_FLAG1_RESPONSE) {
+    outpkt->answers += answers;
+  } else {
+    outpkt->authoritative += answers;
+  }
+
+  /* All answers written, add additional RRs */
+  for (i = 0; i < MDNS_MAX_SERVICES; i++) {
+    service = mdns->services[i];
+    if (!service) {
+      continue;
+    }
+
+    if (outpkt->serv_replies[i] & REPLY_SERVICE_NAME_PTR) {
+      /* Our service instance requested, include SRV & TXT
+       * if they are already not requested. */
+      if (!(outpkt->serv_replies[i] & REPLY_SERVICE_SRV)) {
+        res = mdns_add_srv_answer(outpkt, outpkt->cache_flush, mdns, service);
+        if (res != ERR_OK) {
+          goto cleanup;
+        }
+        outpkt->additional++;
+      }
+
+      if (!(outpkt->serv_replies[i] & REPLY_SERVICE_TXT)) {
+        res = mdns_add_txt_answer(outpkt, outpkt->cache_flush, service);
+        if (res != ERR_OK) {
+          goto cleanup;
+        }
+        outpkt->additional++;
+      }
+    }
+
+    /* If service instance, SRV, record or an IP address is requested,
+     * supply all addresses for the host
+     */
+    if ((outpkt->serv_replies[i] & (REPLY_SERVICE_NAME_PTR | REPLY_SERVICE_SRV)) ||
+        (outpkt->host_replies & (REPLY_HOST_A | REPLY_HOST_AAAA))) {
+#if LWIP_IPV6
+      if (!(outpkt->host_replies & REPLY_HOST_AAAA)) {
+        int addrindex;
+        for (addrindex = 0; addrindex < LWIP_IPV6_NUM_ADDRESSES; addrindex++) {
+          if (ip6_addr_isvalid(netif_ip6_addr_state(outpkt->netif, addrindex))) {
+            res = mdns_add_aaaa_answer(outpkt, outpkt->cache_flush, outpkt->netif, addrindex);
+            if (res != ERR_OK) {
+              goto cleanup;
+            }
+            outpkt->additional++;
+          }
+        }
+      }
+#endif
+#if LWIP_IPV4
+      if (!(outpkt->host_replies & REPLY_HOST_A) &&
+          !ip4_addr_isany_val(*netif_ip4_addr(outpkt->netif))) {
+        res = mdns_add_a_answer(outpkt, outpkt->cache_flush, outpkt->netif);
+        if (res != ERR_OK) {
+          goto cleanup;
+        }
+        outpkt->additional++;
+      }
+#endif
+    }
+  }
+
+  if (outpkt->pbuf) {
+    const ip_addr_t *mcast_destaddr;
+    struct dns_hdr hdr;
+
+    /* Write header */
+    memset(&hdr, 0, sizeof(hdr));
+    hdr.flags1 = flags;
+    hdr.numquestions = lwip_htons(outpkt->questions);
+    hdr.numanswers = lwip_htons(outpkt->answers);
+    hdr.numauthrr = lwip_htons(outpkt->authoritative);
+    hdr.numextrarr = lwip_htons(outpkt->additional);
+    hdr.id = lwip_htons(outpkt->tx_id);
+    pbuf_take(outpkt->pbuf, &hdr, sizeof(hdr));
+
+    /* Shrink packet */
+    pbuf_realloc(outpkt->pbuf, outpkt->write_offset);
+
+    if (IP_IS_V6_VAL(outpkt->dest_addr)) {
+#if LWIP_IPV6
+      mcast_destaddr = &v6group;
+#endif
+    } else {
+#if LWIP_IPV4
+      mcast_destaddr = &v4group;
+#endif
+    }
+    /* Send created packet */
+    LWIP_DEBUGF(MDNS_DEBUG, ("MDNS: Sending packet, len=%d, unicast=%d\n", outpkt->write_offset, outpkt->unicast_reply));
+    if (outpkt->unicast_reply) {
+      res = udp_sendto_if(mdns_pcb, outpkt->pbuf, &outpkt->dest_addr, outpkt->dest_port, outpkt->netif);
+    } else {
+      res = udp_sendto_if(mdns_pcb, outpkt->pbuf, mcast_destaddr, LWIP_IANA_PORT_MDNS, outpkt->netif);
+    }
+  }
+
+cleanup:
+  if (outpkt->pbuf) {
+    pbuf_free(outpkt->pbuf);
+    outpkt->pbuf = NULL;
+  }
+  return res;
+}
+
+/**
+ * Send unsolicited answer containing all our known data
+ * @param netif The network interface to send on
+ * @param destination The target address to send to (usually multicast address)
+ */
+static void
+mdns_announce(struct netif *netif, const ip_addr_t *destination)
+{
+  struct mdns_outpacket announce;
+  int i;
+  struct mdns_host *mdns = NETIF_TO_HOST(netif);
+
+  memset(&announce, 0, sizeof(announce));
+  announce.netif = netif;
+  announce.cache_flush = 1;
+#if LWIP_IPV4
+  if (!ip4_addr_isany_val(*netif_ip4_addr(netif))) {
+    announce.host_replies = REPLY_HOST_A | REPLY_HOST_PTR_V4;
+  }
+#endif
+#if LWIP_IPV6
+  for (i = 0; i < LWIP_IPV6_NUM_ADDRESSES; i++) {
+    if (ip6_addr_isvalid(netif_ip6_addr_state(netif, i))) {
+      announce.host_replies |= REPLY_HOST_AAAA | REPLY_HOST_PTR_V6;
+      announce.host_reverse_v6_replies |= (1 << i);
+    }
+  }
+#endif
+
+  for (i = 0; i < MDNS_MAX_SERVICES; i++) {
+    struct mdns_service *serv = mdns->services[i];
+    if (serv) {
+      announce.serv_replies[i] = REPLY_SERVICE_TYPE_PTR | REPLY_SERVICE_NAME_PTR |
+                                 REPLY_SERVICE_SRV | REPLY_SERVICE_TXT;
+    }
+  }
+
+  announce.dest_port = LWIP_IANA_PORT_MDNS;
+  SMEMCPY(&announce.dest_addr, destination, sizeof(announce.dest_addr));
+  mdns_send_outpacket(&announce, DNS_FLAG1_RESPONSE | DNS_FLAG1_AUTHORATIVE);
+}
+
+/**
+ * Handle question MDNS packet
+ * 1. Parse all questions and set bits what answers to send
+ * 2. Clear pending answers if known answers are supplied
+ * 3. Put chosen answers in new packet and send as reply
+ */
+static void
+mdns_handle_question(struct mdns_packet *pkt)
+{
+  struct mdns_service *service;
+  struct mdns_outpacket reply;
+  int replies = 0;
+  int i;
+  err_t res;
+  struct mdns_host *mdns = NETIF_TO_HOST(pkt->netif);
+
+  if (mdns->probing_state != MDNS_PROBING_COMPLETE) {
+    /* Don't answer questions until we've verified our domains via probing */
+    /* @todo we should check incoming questions during probing for tiebreaking */
+    return;
+  }
+
+  mdns_init_outpacket(&reply, pkt);
+
+  while (pkt->questions_left) {
+    struct mdns_question q;
+
+    res = mdns_read_question(pkt, &q);
+    if (res != ERR_OK) {
+      LWIP_DEBUGF(MDNS_DEBUG, ("MDNS: Failed to parse question, skipping query packet\n"));
+      return;
+    }
+
+    LWIP_DEBUGF(MDNS_DEBUG, ("MDNS: Query for domain "));
+    mdns_domain_debug_print(&q.info.domain);
+    LWIP_DEBUGF(MDNS_DEBUG, (" type %d class %d\n", q.info.type, q.info.klass));
+
+    if (q.unicast) {
+      /* Reply unicast if any question is unicast */
+      reply.unicast_reply = 1;
+    }
+
+    reply.host_replies |= check_host(pkt->netif, &q.info, &reply.host_reverse_v6_replies);
+    replies |= reply.host_replies;
+
+    for (i = 0; i < MDNS_MAX_SERVICES; i++) {
+      service = mdns->services[i];
+      if (!service) {
+        continue;
+      }
+      reply.serv_replies[i] |= check_service(service, &q.info);
+      replies |= reply.serv_replies[i];
+    }
+
+    if (replies && reply.legacy_query) {
+      /* Add question to reply packet (legacy packet only has 1 question) */
+      res = mdns_add_question(&reply, &q.info.domain, q.info.type, q.info.klass, 0);
+      reply.questions = 1;
+      if (res != ERR_OK) {
+        goto cleanup;
+      }
+    }
+  }
+
+  /* Handle known answers */
+  while (pkt->answers_left) {
+    struct mdns_answer ans;
+    u8_t rev_v6;
+    int match;
+
+    res = mdns_read_answer(pkt, &ans);
+    if (res != ERR_OK) {
+      LWIP_DEBUGF(MDNS_DEBUG, ("MDNS: Failed to parse answer, skipping query packet\n"));
+      goto cleanup;
+    }
+
+    LWIP_DEBUGF(MDNS_DEBUG, ("MDNS: Known answer for domain "));
+    mdns_domain_debug_print(&ans.info.domain);
+    LWIP_DEBUGF(MDNS_DEBUG, (" type %d class %d\n", ans.info.type, ans.info.klass));
+
+
+    if (ans.info.type == DNS_RRTYPE_ANY || ans.info.klass == DNS_RRCLASS_ANY) {
+      /* Skip known answers for ANY type & class */
+      continue;
+    }
+
+    rev_v6 = 0;
+    match = reply.host_replies & check_host(pkt->netif, &ans.info, &rev_v6);
+    if (match && (ans.ttl > (mdns->dns_ttl / 2))) {
+      /* The RR in the known answer matches an RR we are planning to send,
+       * and the TTL is less than half gone.
+       * If the payload matches we should not send that answer.
+       */
+      if (ans.info.type == DNS_RRTYPE_PTR) {
+        /* Read domain and compare */
+        struct mdns_domain known_ans, my_ans;
+        u16_t len;
+        len = mdns_readname(pkt->pbuf, ans.rd_offset, &known_ans);
+        res = mdns_build_host_domain(&my_ans, mdns);
+        if (len != MDNS_READNAME_ERROR && res == ERR_OK && mdns_domain_eq(&known_ans, &my_ans)) {
+#if LWIP_IPV4
+          if (match & REPLY_HOST_PTR_V4) {
+            LWIP_DEBUGF(MDNS_DEBUG, ("MDNS: Skipping known answer: v4 PTR\n"));
+            reply.host_replies &= ~REPLY_HOST_PTR_V4;
+          }
+#endif
+#if LWIP_IPV6
+          if (match & REPLY_HOST_PTR_V6) {
+            LWIP_DEBUGF(MDNS_DEBUG, ("MDNS: Skipping known answer: v6 PTR\n"));
+            reply.host_reverse_v6_replies &= ~rev_v6;
+            if (reply.host_reverse_v6_replies == 0) {
+              reply.host_replies &= ~REPLY_HOST_PTR_V6;
+            }
+          }
+#endif
+        }
+      } else if (match & REPLY_HOST_A) {
+#if LWIP_IPV4
+        if (ans.rd_length == sizeof(ip4_addr_t) &&
+            pbuf_memcmp(pkt->pbuf, ans.rd_offset, netif_ip4_addr(pkt->netif), ans.rd_length) == 0) {
+          LWIP_DEBUGF(MDNS_DEBUG, ("MDNS: Skipping known answer: A\n"));
+          reply.host_replies &= ~REPLY_HOST_A;
+        }
+#endif
+      } else if (match & REPLY_HOST_AAAA) {
+#if LWIP_IPV6
+        if (ans.rd_length == sizeof(ip6_addr_p_t) &&
+            /* TODO this clears all AAAA responses if first addr is set as known */
+            pbuf_memcmp(pkt->pbuf, ans.rd_offset, netif_ip6_addr(pkt->netif, 0), ans.rd_length) == 0) {
+          LWIP_DEBUGF(MDNS_DEBUG, ("MDNS: Skipping known answer: AAAA\n"));
+          reply.host_replies &= ~REPLY_HOST_AAAA;
+        }
+#endif
+      }
+    }
+
+    for (i = 0; i < MDNS_MAX_SERVICES; i++) {
+      service = mdns->services[i];
+      if (!service) {
+        continue;
+      }
+      match = reply.serv_replies[i] & check_service(service, &ans.info);
+      if (match && (ans.ttl > (service->dns_ttl / 2))) {
+        /* The RR in the known answer matches an RR we are planning to send,
+         * and the TTL is less than half gone.
+         * If the payload matches we should not send that answer.
+         */
+        if (ans.info.type == DNS_RRTYPE_PTR) {
+          /* Read domain and compare */
+          struct mdns_domain known_ans, my_ans;
+          u16_t len;
+          len = mdns_readname(pkt->pbuf, ans.rd_offset, &known_ans);
+          if (len != MDNS_READNAME_ERROR) {
+            if (match & REPLY_SERVICE_TYPE_PTR) {
+              res = mdns_build_service_domain(&my_ans, service, 0);
+              if (res == ERR_OK && mdns_domain_eq(&known_ans, &my_ans)) {
+                LWIP_DEBUGF(MDNS_DEBUG, ("MDNS: Skipping known answer: service type PTR\n"));
+                reply.serv_replies[i] &= ~REPLY_SERVICE_TYPE_PTR;
+              }
+            }
+            if (match & REPLY_SERVICE_NAME_PTR) {
+              res = mdns_build_service_domain(&my_ans, service, 1);
+              if (res == ERR_OK && mdns_domain_eq(&known_ans, &my_ans)) {
+                LWIP_DEBUGF(MDNS_DEBUG, ("MDNS: Skipping known answer: service name PTR\n"));
+                reply.serv_replies[i] &= ~REPLY_SERVICE_NAME_PTR;
+              }
+            }
+          }
+        } else if (match & REPLY_SERVICE_SRV) {
+          /* Read and compare to my SRV record */
+          u16_t field16, len, read_pos;
+          struct mdns_domain known_ans, my_ans;
+          read_pos = ans.rd_offset;
+          do {
+            /* Check priority field */
+            len = pbuf_copy_partial(pkt->pbuf, &field16, sizeof(field16), read_pos);
+            if (len != sizeof(field16) || lwip_ntohs(field16) != SRV_PRIORITY) {
+              break;
+            }
+            read_pos += len;
+            /* Check weight field */
+            len = pbuf_copy_partial(pkt->pbuf, &field16, sizeof(field16), read_pos);
+            if (len != sizeof(field16) || lwip_ntohs(field16) != SRV_WEIGHT) {
+              break;
+            }
+            read_pos += len;
+            /* Check port field */
+            len = pbuf_copy_partial(pkt->pbuf, &field16, sizeof(field16), read_pos);
+            if (len != sizeof(field16) || lwip_ntohs(field16) != service->port) {
+              break;
+            }
+            read_pos += len;
+            /* Check host field */
+            len = mdns_readname(pkt->pbuf, read_pos, &known_ans);
+            mdns_build_host_domain(&my_ans, mdns);
+            if (len == MDNS_READNAME_ERROR || !mdns_domain_eq(&known_ans, &my_ans)) {
+              break;
+            }
+            LWIP_DEBUGF(MDNS_DEBUG, ("MDNS: Skipping known answer: SRV\n"));
+            reply.serv_replies[i] &= ~REPLY_SERVICE_SRV;
+          } while (0);
+        } else if (match & REPLY_SERVICE_TXT) {
+          mdns_prepare_txtdata(service);
+          if (service->txtdata.length == ans.rd_length &&
+              pbuf_memcmp(pkt->pbuf, ans.rd_offset, service->txtdata.name, ans.rd_length) == 0) {
+            LWIP_DEBUGF(MDNS_DEBUG, ("MDNS: Skipping known answer: TXT\n"));
+            reply.serv_replies[i] &= ~REPLY_SERVICE_TXT;
+          }
+        }
+      }
+    }
+  }
+
+  mdns_send_outpacket(&reply, DNS_FLAG1_RESPONSE | DNS_FLAG1_AUTHORATIVE);
+
+cleanup:
+  if (reply.pbuf) {
+    /* This should only happen if we fail to alloc/write question for legacy query */
+    pbuf_free(reply.pbuf);
+    reply.pbuf = NULL;
+  }
+}
+
+/**
+ * Handle response MDNS packet
+ * Only prints debug for now. Will need more code to do conflict resolution.
+ */
+static void
+mdns_handle_response(struct mdns_packet *pkt)
+{
+  struct mdns_host* mdns = NETIF_TO_HOST(pkt->netif);
+
+  /* Ignore all questions */
+  while (pkt->questions_left) {
+    struct mdns_question q;
+    err_t res;
+
+    res = mdns_read_question(pkt, &q);
+    if (res != ERR_OK) {
+      LWIP_DEBUGF(MDNS_DEBUG, ("MDNS: Failed to parse question, skipping response packet\n"));
+      return;
+    }
+  }
+
+  while (pkt->answers_left) {
+    struct mdns_answer ans;
+    err_t res;
+
+    res = mdns_read_answer(pkt, &ans);
+    if (res != ERR_OK) {
+      LWIP_DEBUGF(MDNS_DEBUG, ("MDNS: Failed to parse answer, skipping response packet\n"));
+      return;
+    }
+
+    LWIP_DEBUGF(MDNS_DEBUG, ("MDNS: Answer for domain "));
+    mdns_domain_debug_print(&ans.info.domain);
+    LWIP_DEBUGF(MDNS_DEBUG, (" type %d class %d\n", ans.info.type, ans.info.klass));
+
+    /*"Apparently conflicting Multicast DNS responses received *before* the first probe packet is sent MUST
+      be silently ignored" so drop answer if we haven't started probing yet*/
+    if ((mdns->probing_state == MDNS_PROBING_ONGOING) && (mdns->probes_sent > 0)) {
+      struct mdns_domain domain;
+      u8_t i;
+      u8_t conflict = 0;
+
+      res = mdns_build_host_domain(&domain, mdns);
+      if (res == ERR_OK && mdns_domain_eq(&ans.info.domain, &domain)) {
+        LWIP_DEBUGF(MDNS_DEBUG, ("MDNS: Probe response matches host domain!"));
+        conflict = 1;
+      }
+
+      for (i = 0; i < MDNS_MAX_SERVICES; i++) {
+        struct mdns_service* service = mdns->services[i];
+        if (!service) {
+          continue;
+        }
+        res = mdns_build_service_domain(&domain, service, 1);
+        if ((res == ERR_OK) && mdns_domain_eq(&ans.info.domain, &domain)) {
+          LWIP_DEBUGF(MDNS_DEBUG, ("MDNS: Probe response matches service domain!"));
+          conflict = 1;
+        }
+      }
+
+      if (conflict != 0) {
+        sys_untimeout(mdns_probe, pkt->netif);
+        if (mdns_name_result_cb != NULL) {
+          mdns_name_result_cb(pkt->netif, MDNS_PROBING_CONFLICT);
+        }
+      }
+    }
+  }
+}
+
+/**
+ * Receive input function for MDNS packets.
+ * Handles both IPv4 and IPv6 UDP pcbs.
+ */
+static void
+mdns_recv(void *arg, struct udp_pcb *pcb, struct pbuf *p, const ip_addr_t *addr, u16_t port)
+{
+  struct dns_hdr hdr;
+  struct mdns_packet packet;
+  struct netif *recv_netif = ip_current_input_netif();
+  u16_t offset = 0;
+
+  LWIP_UNUSED_ARG(arg);
+  LWIP_UNUSED_ARG(pcb);
+
+  LWIP_DEBUGF(MDNS_DEBUG, ("MDNS: Received IPv%d MDNS packet, len %d\n", IP_IS_V6(addr) ? 6 : 4, p->tot_len));
+
+  if (NETIF_TO_HOST(recv_netif) == NULL) {
+    /* From netif not configured for MDNS */
+    goto dealloc;
+  }
+
+  if (pbuf_copy_partial(p, &hdr, SIZEOF_DNS_HDR, offset) < SIZEOF_DNS_HDR) {
+    /* Too small */
+    goto dealloc;
+  }
+  offset += SIZEOF_DNS_HDR;
+
+  if (DNS_HDR_GET_OPCODE(&hdr)) {
+    /* Ignore non-standard queries in multicast packets (RFC 6762, section 18.3) */
+    goto dealloc;
+  }
+
+  memset(&packet, 0, sizeof(packet));
+  SMEMCPY(&packet.source_addr, addr, sizeof(packet.source_addr));
+  packet.source_port = port;
+  packet.netif = recv_netif;
+  packet.pbuf = p;
+  packet.parse_offset = offset;
+  packet.tx_id = lwip_ntohs(hdr.id);
+  packet.questions = packet.questions_left = lwip_ntohs(hdr.numquestions);
+  packet.answers = packet.answers_left = lwip_ntohs(hdr.numanswers) + lwip_ntohs(hdr.numauthrr) + lwip_ntohs(hdr.numextrarr);
+
+#if LWIP_IPV6
+  if (IP_IS_V6(ip_current_dest_addr())) {
+    /* instead of having one 'v6group' per netif, just compare zoneless here */
+    if (!ip_addr_cmp_zoneless(ip_current_dest_addr(), &v6group)) {
+      packet.recv_unicast = 1;
+    }
+  }
+#endif
+#if LWIP_IPV4
+  if (!IP_IS_V6(ip_current_dest_addr())) {
+    if (!ip_addr_cmp(ip_current_dest_addr(), &v4group)) {
+      packet.recv_unicast = 1;
+    }
+  }
+#endif
+
+  if (hdr.flags1 & DNS_FLAG1_RESPONSE) {
+    mdns_handle_response(&packet);
+  } else {
+    mdns_handle_question(&packet);
+  }
+
+dealloc:
+  pbuf_free(p);
+}
+
+#if LWIP_NETIF_EXT_STATUS_CALLBACK && MDNS_RESP_USENETIF_EXTCALLBACK
+static void
+mdns_netif_ext_status_callback(struct netif *netif, netif_nsc_reason_t reason, const netif_ext_callback_args_t *args)
+{
+  LWIP_UNUSED_ARG(args);
+
+  /* MDNS enabled on netif? */
+  if (NETIF_TO_HOST(netif) == NULL) {
+    return;
+  }
+
+  if (reason & LWIP_NSC_STATUS_CHANGED) {
+    if (args->status_changed.state != 0) {
+      mdns_resp_restart(netif);
+    }
+    /* TODO: send goodbye message */
+  }
+  if (reason & LWIP_NSC_LINK_CHANGED) {
+    if (args->link_changed.state != 0) {
+      mdns_resp_restart(netif);
+    }
+  }
+  if (reason & (LWIP_NSC_IPV4_ADDRESS_CHANGED | LWIP_NSC_IPV4_GATEWAY_CHANGED |
+      LWIP_NSC_IPV4_NETMASK_CHANGED | LWIP_NSC_IPV4_SETTINGS_CHANGED |
+      LWIP_NSC_IPV6_SET | LWIP_NSC_IPV6_ADDR_STATE_CHANGED)) {
+    mdns_resp_announce(netif);
+  }
+}
+#endif /* LWIP_NETIF_EXT_STATUS_CALLBACK && MDNS_RESP_USENETIF_EXTCALLBACK */
+
+static err_t
+mdns_send_probe(struct netif* netif, const ip_addr_t *destination)
+{
+  struct mdns_host* mdns;
+  struct mdns_outpacket pkt;
+  struct mdns_domain domain;
+  u8_t i;
+  err_t res;
+
+  mdns = NETIF_TO_HOST(netif);
+
+  memset(&pkt, 0, sizeof(pkt));
+  pkt.netif = netif;
+
+  /* Add unicast questions with rtype ANY for all our desired records */
+  mdns_build_host_domain(&domain, mdns);
+  res = mdns_add_question(&pkt, &domain, DNS_RRTYPE_ANY, DNS_RRCLASS_IN, 1);
+  if (res != ERR_OK) {
+    goto cleanup;
+  }
+  pkt.questions++;
+  for (i = 0; i < MDNS_MAX_SERVICES; i++) {
+    struct mdns_service* service = mdns->services[i];
+    if (!service) {
+      continue;
+    }
+    mdns_build_service_domain(&domain, service, 1);
+    res = mdns_add_question(&pkt, &domain, DNS_RRTYPE_ANY, DNS_RRCLASS_IN, 1);
+    if (res != ERR_OK) {
+      goto cleanup;
+    }
+    pkt.questions++;
+  }
+
+  /* Add answers to the questions above into the authority section for tiebreaking */
+#if LWIP_IPV4
+  if (!ip4_addr_isany_val(*netif_ip4_addr(netif))) {
+    pkt.host_replies = REPLY_HOST_A;
+  }
+#endif
+#if LWIP_IPV6
+  for (i = 0; i < LWIP_IPV6_NUM_ADDRESSES; i++) {
+    if (ip6_addr_isvalid(netif_ip6_addr_state(netif, i))) {
+      pkt.host_replies |= REPLY_HOST_AAAA;
+    }
+  }
+#endif
+
+  for (i = 0; i < MDNS_MAX_SERVICES; i++) {
+    struct mdns_service *serv = mdns->services[i];
+    if (serv) {
+      pkt.serv_replies[i] = REPLY_SERVICE_SRV | REPLY_SERVICE_TXT;
+    }
+  }
+
+  pkt.tx_id = 0;
+  pkt.dest_port = LWIP_IANA_PORT_MDNS;
+  SMEMCPY(&pkt.dest_addr, destination, sizeof(pkt.dest_addr));
+  res = mdns_send_outpacket(&pkt, 0);
+
+cleanup:
+  if (pkt.pbuf) {
+    pbuf_free(pkt.pbuf);
+    pkt.pbuf = NULL;
+  }
+  return res;
+}
+
+/**
+ * Timer callback for probing network.
+ */
+static void
+mdns_probe(void* arg)
+{
+  struct netif *netif = (struct netif *)arg;
+  struct mdns_host* mdns = NETIF_TO_HOST(netif);
+
+  if(mdns->probes_sent >= MDNS_PROBE_COUNT) {
+    /* probing successful, announce the new name */
+    mdns->probing_state = MDNS_PROBING_COMPLETE;
+    mdns_resp_announce(netif);
+    if (mdns_name_result_cb != NULL) {
+      mdns_name_result_cb(netif, MDNS_PROBING_SUCCESSFUL);
+    }
+  } else {
+#if LWIP_IPV4
+    /*if ipv4 wait with probing until address is set*/
+    if (!ip4_addr_isany_val(*netif_ip4_addr(netif)) &&
+        mdns_send_probe(netif, IP4_ADDR_ANY) == ERR_OK)
+#endif
+    {
+#if LWIP_IPV6
+      if (mdns_send_probe(netif, IP6_ADDR_ANY) == ERR_OK)
+#endif
+      {
+        mdns->probes_sent++;
+      }
+    }
+    sys_timeout(MDNS_PROBE_DELAY_MS, mdns_probe, netif);
+  }
+}
+
+/**
+ * @ingroup mdns
+ * Activate MDNS responder for a network interface.
+ * @param netif The network interface to activate.
+ * @param hostname Name to use. Queries for &lt;hostname&gt;.local will be answered
+ *                 with the IP addresses of the netif. The hostname will be copied, the
+ *                 given pointer can be on the stack.
+ * @param dns_ttl Validity time in seconds to send out for IP address data in DNS replies
+ * @return ERR_OK if netif was added, an err_t otherwise
+ */
+err_t
+mdns_resp_add_netif(struct netif *netif, const char *hostname, u32_t dns_ttl)
+{
+  err_t res;
+  struct mdns_host *mdns;
+
+  LWIP_ASSERT_CORE_LOCKED();
+  LWIP_ERROR("mdns_resp_add_netif: netif != NULL", (netif != NULL), return ERR_VAL);
+  LWIP_ERROR("mdns_resp_add_netif: Hostname too long", (strlen(hostname) <= MDNS_LABEL_MAXLEN), return ERR_VAL);
+
+  LWIP_ASSERT("mdns_resp_add_netif: Double add", NETIF_TO_HOST(netif) == NULL);
+  mdns = (struct mdns_host *) mem_calloc(1, sizeof(struct mdns_host));
+  LWIP_ERROR("mdns_resp_add_netif: Alloc failed", (mdns != NULL), return ERR_MEM);
+
+  netif_set_client_data(netif, mdns_netif_client_id, mdns);
+
+  MEMCPY(&mdns->name, hostname, LWIP_MIN(MDNS_LABEL_MAXLEN, strlen(hostname)));
+  mdns->dns_ttl = dns_ttl;
+  mdns->probes_sent = 0;
+  mdns->probing_state = MDNS_PROBING_NOT_STARTED;
+
+  /* Join multicast groups */
+#if LWIP_IPV4
+  res = igmp_joingroup_netif(netif, ip_2_ip4(&v4group));
+  if (res != ERR_OK) {
+    goto cleanup;
+  }
+#endif
+#if LWIP_IPV6
+  res = mld6_joingroup_netif(netif, ip_2_ip6(&v6group));
+  if (res != ERR_OK) {
+    goto cleanup;
+  }
+#endif
+
+  mdns_resp_restart(netif);
+
+  return ERR_OK;
+
+cleanup:
+  mem_free(mdns);
+  netif_set_client_data(netif, mdns_netif_client_id, NULL);
+  return res;
+}
+
+/**
+ * @ingroup mdns
+ * Stop responding to MDNS queries on this interface, leave multicast groups,
+ * and free the helper structure and any of its services.
+ * @param netif The network interface to remove.
+ * @return ERR_OK if netif was removed, an err_t otherwise
+ */
+err_t
+mdns_resp_remove_netif(struct netif *netif)
+{
+  int i;
+  struct mdns_host *mdns;
+
+  LWIP_ASSERT_CORE_LOCKED();
+  LWIP_ASSERT("mdns_resp_remove_netif: Null pointer", netif);
+  mdns = NETIF_TO_HOST(netif);
+  LWIP_ERROR("mdns_resp_remove_netif: Not an active netif", (mdns != NULL), return ERR_VAL);
+
+  if (mdns->probing_state == MDNS_PROBING_ONGOING) {
+    sys_untimeout(mdns_probe, netif);
+  }
+
+  for (i = 0; i < MDNS_MAX_SERVICES; i++) {
+    struct mdns_service *service = mdns->services[i];
+    if (service) {
+      mem_free(service);
+    }
+  }
+
+  /* Leave multicast groups */
+#if LWIP_IPV4
+  igmp_leavegroup_netif(netif, ip_2_ip4(&v4group));
+#endif
+#if LWIP_IPV6
+  mld6_leavegroup_netif(netif, ip_2_ip6(&v6group));
+#endif
+
+  mem_free(mdns);
+  netif_set_client_data(netif, mdns_netif_client_id, NULL);
+  return ERR_OK;
+}
+
+/**
+ * @ingroup mdns
+ * Update MDNS hostname for a network interface.
+ * @param netif The network interface to activate.
+ * @param hostname Name to use. Queries for &lt;hostname&gt;.local will be answered
+ *                 with the IP addresses of the netif. The hostname will be copied, the
+ *                 given pointer can be on the stack.
+ * @return ERR_OK if name could be set on netif, an err_t otherwise
+ */
+err_t
+mdns_resp_rename_netif(struct netif *netif, const char *hostname)
+{
+  struct mdns_host *mdns;
+  size_t len;
+
+  LWIP_ASSERT_CORE_LOCKED();
+  len = strlen(hostname);
+  LWIP_ERROR("mdns_resp_rename_netif: netif != NULL", (netif != NULL), return ERR_VAL);
+  LWIP_ERROR("mdns_resp_rename_netif: Hostname too long", (len <= MDNS_LABEL_MAXLEN), return ERR_VAL);
+  mdns = NETIF_TO_HOST(netif);
+  LWIP_ERROR("mdns_resp_rename_netif: Not an mdns netif", (mdns != NULL), return ERR_VAL);
+
+  MEMCPY(&mdns->name, hostname, LWIP_MIN(MDNS_LABEL_MAXLEN, len));
+  mdns->name[len] = '\0'; /* null termination in case new name is shorter than previous */
+
+  mdns_resp_restart(netif);
+
+  return ERR_OK;
+}
+
+/**
+ * @ingroup mdns
+ * Add a service to the selected network interface.
+ * @param netif The network interface to publish this service on
+ * @param name The name of the service
+ * @param service The service type, like "_http"
+ * @param proto The service protocol, DNSSD_PROTO_TCP for TCP ("_tcp") and DNSSD_PROTO_UDP
+ *              for others ("_udp")
+ * @param port The port the service listens to
+ * @param dns_ttl Validity time in seconds to send out for service data in DNS replies
+ * @param txt_fn Callback to get TXT data. Will be called each time a TXT reply is created to
+ *               allow dynamic replies.
+ * @param txt_data Userdata pointer for txt_fn
+ * @return service_id if the service was added to the netif, an err_t otherwise
+ */
+s8_t
+mdns_resp_add_service(struct netif *netif, const char *name, const char *service, enum mdns_sd_proto proto, u16_t port, u32_t dns_ttl, service_get_txt_fn_t txt_fn, void *txt_data)
+{
+  s8_t i;
+  s8_t slot = -1;
+  struct mdns_service *srv;
+  struct mdns_host *mdns;
+
+  LWIP_ASSERT_CORE_LOCKED();
+  LWIP_ASSERT("mdns_resp_add_service: netif != NULL", netif);
+  mdns = NETIF_TO_HOST(netif);
+  LWIP_ERROR("mdns_resp_add_service: Not an mdns netif", (mdns != NULL), return ERR_VAL);
+
+  LWIP_ERROR("mdns_resp_add_service: Name too long", (strlen(name) <= MDNS_LABEL_MAXLEN), return ERR_VAL);
+  LWIP_ERROR("mdns_resp_add_service: Service too long", (strlen(service) <= MDNS_LABEL_MAXLEN), return ERR_VAL);
+  LWIP_ERROR("mdns_resp_add_service: Bad proto (need TCP or UDP)", (proto == DNSSD_PROTO_TCP || proto == DNSSD_PROTO_UDP), return ERR_VAL);
+
+  for (i = 0; i < MDNS_MAX_SERVICES; i++) {
+    if (mdns->services[i] == NULL) {
+      slot = i;
+      break;
+    }
+  }
+  LWIP_ERROR("mdns_resp_add_service: Service list full (increase MDNS_MAX_SERVICES)", (slot >= 0), return ERR_MEM);
+
+  srv = (struct mdns_service *)mem_calloc(1, sizeof(struct mdns_service));
+  LWIP_ERROR("mdns_resp_add_service: Alloc failed", (srv != NULL), return ERR_MEM);
+
+  MEMCPY(&srv->name, name, LWIP_MIN(MDNS_LABEL_MAXLEN, strlen(name)));
+  MEMCPY(&srv->service, service, LWIP_MIN(MDNS_LABEL_MAXLEN, strlen(service)));
+  srv->txt_fn = txt_fn;
+  srv->txt_userdata = txt_data;
+  srv->proto = (u16_t)proto;
+  srv->port = port;
+  srv->dns_ttl = dns_ttl;
+
+  mdns->services[slot] = srv;
+
+  mdns_resp_restart(netif);
+
+  return slot;
+}
+
+/**
+ * @ingroup mdns
+ * Delete a service on the selected network interface.
+ * @param netif The network interface on which service should be removed
+ * @param slot The service slot number returned by mdns_resp_add_service
+ * @return ERR_OK if the service was removed from the netif, an err_t otherwise
+ */
+err_t
+mdns_resp_del_service(struct netif *netif, s8_t slot)
+{
+  struct mdns_host *mdns;
+  struct mdns_service *srv;
+  LWIP_ASSERT("mdns_resp_del_service: netif != NULL", netif);
+  mdns = NETIF_TO_HOST(netif);
+  LWIP_ERROR("mdns_resp_del_service: Not an mdns netif", (mdns != NULL), return ERR_VAL);
+  LWIP_ERROR("mdns_resp_del_service: Invalid Service ID", (slot >= 0) && (slot < MDNS_MAX_SERVICES), return ERR_VAL);
+  LWIP_ERROR("mdns_resp_del_service: Invalid Service ID", (mdns->services[slot] != NULL), return ERR_VAL);
+
+  srv = mdns->services[slot];
+  mdns->services[slot] = NULL;
+  mem_free(srv);
+  return ERR_OK;
+}
+
+/**
+ * @ingroup mdns
+ * Update name for an MDNS service.
+ * @param netif The network interface to activate.
+ * @param slot The service slot number returned by mdns_resp_add_service
+ * @param name The new name for the service
+ * @return ERR_OK if name could be set on service, an err_t otherwise
+ */
+err_t
+mdns_resp_rename_service(struct netif *netif, s8_t slot, const char *name)
+{
+  struct mdns_service *srv;
+  struct mdns_host *mdns;
+  size_t len;
+
+  LWIP_ASSERT_CORE_LOCKED();
+  len = strlen(name);
+  LWIP_ASSERT("mdns_resp_rename_service: netif != NULL", netif);
+  mdns = NETIF_TO_HOST(netif);
+  LWIP_ERROR("mdns_resp_rename_service: Not an mdns netif", (mdns != NULL), return ERR_VAL);
+  LWIP_ERROR("mdns_resp_rename_service: Name too long", (len <= MDNS_LABEL_MAXLEN), return ERR_VAL);
+  LWIP_ERROR("mdns_resp_rename_service: Invalid Service ID", (slot >= 0) && (slot < MDNS_MAX_SERVICES), return ERR_VAL);
+  LWIP_ERROR("mdns_resp_rename_service: Invalid Service ID", (mdns->services[slot] != NULL), return ERR_VAL);
+
+  srv = mdns->services[slot];
+
+  MEMCPY(&srv->name, name, LWIP_MIN(MDNS_LABEL_MAXLEN, len));
+  srv->name[len] = '\0'; /* null termination in case new name is shorter than previous */
+
+  mdns_resp_restart(netif);
+
+  return ERR_OK;
+}
+
+/**
+ * @ingroup mdns
+ * Call this function from inside the service_get_txt_fn_t callback to add text data.
+ * Buffer for TXT data is 256 bytes, and each field is prefixed with a length byte.
+ * @param service The service provided to the get_txt callback
+ * @param txt String to add to the TXT field.
+ * @param txt_len Length of string
+ * @return ERR_OK if the string was added to the reply, an err_t otherwise
+ */
+err_t
+mdns_resp_add_service_txtitem(struct mdns_service *service, const char *txt, u8_t txt_len)
+{
+  LWIP_ASSERT_CORE_LOCKED();
+  LWIP_ASSERT("mdns_resp_add_service_txtitem: service != NULL", service);
+
+  /* Use a mdns_domain struct to store txt chunks since it is the same encoding */
+  return mdns_domain_add_label(&service->txtdata, txt, txt_len);
+}
+
+/**
+ * @ingroup mdns
+ * Send unsolicited answer containing all our known data
+ * @param netif The network interface to send on
+ */
+void
+mdns_resp_announce(struct netif *netif)
+{
+  struct mdns_host* mdns;
+  LWIP_ASSERT_CORE_LOCKED();
+  LWIP_ERROR("mdns_resp_announce: netif != NULL", (netif != NULL), return);
+
+  mdns = NETIF_TO_HOST(netif);
+  if (mdns == NULL) {
+    return;
+  }
+
+  if (mdns->probing_state == MDNS_PROBING_COMPLETE) {
+    /* Announce on IPv6 and IPv4 */
+#if LWIP_IPV6
+    mdns_announce(netif, IP6_ADDR_ANY);
+#endif
+#if LWIP_IPV4
+    if (!ip4_addr_isany_val(*netif_ip4_addr(netif))) {
+      mdns_announce(netif, IP4_ADDR_ANY);
+    }
+#endif
+  } /* else: ip address changed while probing was ongoing? @todo reset counter to restart? */
+}
+
+/** Register a callback function that is called if probing is completed successfully
+ * or with a conflict. */
+void
+mdns_resp_register_name_result_cb(mdns_name_result_cb_t cb)
+{
+  mdns_name_result_cb = cb;
+}
+
+/**
+ * @ingroup mdns
+ * Restart mdns responder. Call this when cable is connected after being disconnected or
+ * administrative interface is set up after being down
+ * @param netif The network interface to send on
+ */
+void
+mdns_resp_restart(struct netif *netif)
+{
+  struct mdns_host* mdns;
+  LWIP_ASSERT_CORE_LOCKED();
+  LWIP_ERROR("mdns_resp_restart: netif != NULL", (netif != NULL), return);
+
+  mdns = NETIF_TO_HOST(netif);
+  if (mdns == NULL) {
+    return;
+  }
+
+  if (mdns->probing_state == MDNS_PROBING_ONGOING) {
+    sys_untimeout(mdns_probe, netif);
+  }
+  /* @todo if we've failed 15 times within a 10 second period we MUST wait 5 seconds (or wait 5 seconds every time except first)*/
+  mdns->probes_sent = 0;
+  mdns->probing_state = MDNS_PROBING_ONGOING;
+  sys_timeout(MDNS_INITIAL_PROBE_DELAY_MS, mdns_probe, netif);
+}
+
+/**
+ * @ingroup mdns
+ * Initiate MDNS responder. Will open UDP sockets on port 5353
+ */
+void
+mdns_resp_init(void)
+{
+  err_t res;
+
+  /* LWIP_ASSERT_CORE_LOCKED(); is checked by udp_new() */
+
+  mdns_pcb = udp_new_ip_type(IPADDR_TYPE_ANY);
+  LWIP_ASSERT("Failed to allocate pcb", mdns_pcb != NULL);
+#if LWIP_MULTICAST_TX_OPTIONS
+  udp_set_multicast_ttl(mdns_pcb, MDNS_TTL);
+#else
+  mdns_pcb->ttl = MDNS_TTL;
+#endif
+  res = udp_bind(mdns_pcb, IP_ANY_TYPE, LWIP_IANA_PORT_MDNS);
+  LWIP_UNUSED_ARG(res); /* in case of LWIP_NOASSERT */
+  LWIP_ASSERT("Failed to bind pcb", res == ERR_OK);
+  udp_recv(mdns_pcb, mdns_recv, NULL);
+
+  mdns_netif_client_id = netif_alloc_client_data_id();
+
+#if MDNS_RESP_USENETIF_EXTCALLBACK
+  /* register for netif events when started on first netif */
+  netif_add_ext_callback(&netif_callback, mdns_netif_ext_status_callback);
+#endif
+}
+
+#endif /* LWIP_MDNS_RESPONDER */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/apps/mqtt/mqtt.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/apps/mqtt/mqtt.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/apps/mqtt/mqtt.c	(revision 457)
@@ -0,0 +1,1463 @@
+/**
+ * @file
+ * MQTT client
+ *
+ * @defgroup mqtt MQTT client
+ * @ingroup apps
+ * @verbinclude mqtt_client.txt
+ */
+
+/*
+ * Copyright (c) 2016 Erik Andersson <erian747@gmail.com>
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack
+ *
+ * Author: Erik Andersson <erian747@gmail.com>
+ *
+ *
+ * @todo:
+ * - Handle large outgoing payloads for PUBLISH messages
+ * - Fix restriction of a single topic in each (UN)SUBSCRIBE message (protocol has support for multiple topics)
+ * - Add support for legacy MQTT protocol version
+ *
+ * Please coordinate changes and requests with Erik Andersson
+ * Erik Andersson <erian747@gmail.com>
+ *
+ */
+#include "lwip/apps/mqtt.h"
+#include "lwip/apps/mqtt_priv.h"
+#include "lwip/timeouts.h"
+#include "lwip/ip_addr.h"
+#include "lwip/mem.h"
+#include "lwip/err.h"
+#include "lwip/pbuf.h"
+#include "lwip/altcp.h"
+#include "lwip/altcp_tcp.h"
+#include "lwip/altcp_tls.h"
+#include <string.h>
+
+#if LWIP_TCP && LWIP_CALLBACK_API
+
+/**
+ * MQTT_DEBUG: Default is off.
+ */
+#if !defined MQTT_DEBUG || defined __DOXYGEN__
+#define MQTT_DEBUG                  LWIP_DBG_OFF
+#endif
+
+#define MQTT_DEBUG_TRACE        (MQTT_DEBUG | LWIP_DBG_TRACE)
+#define MQTT_DEBUG_STATE        (MQTT_DEBUG | LWIP_DBG_STATE)
+#define MQTT_DEBUG_WARN         (MQTT_DEBUG | LWIP_DBG_LEVEL_WARNING)
+#define MQTT_DEBUG_WARN_STATE   (MQTT_DEBUG | LWIP_DBG_LEVEL_WARNING | LWIP_DBG_STATE)
+#define MQTT_DEBUG_SERIOUS      (MQTT_DEBUG | LWIP_DBG_LEVEL_SERIOUS)
+
+
+
+/**
+ * MQTT client connection states
+ */
+enum {
+  TCP_DISCONNECTED,
+  TCP_CONNECTING,
+  MQTT_CONNECTING,
+  MQTT_CONNECTED
+};
+
+/**
+ * MQTT control message types
+ */
+enum mqtt_message_type {
+  MQTT_MSG_TYPE_CONNECT = 1,
+  MQTT_MSG_TYPE_CONNACK = 2,
+  MQTT_MSG_TYPE_PUBLISH = 3,
+  MQTT_MSG_TYPE_PUBACK = 4,
+  MQTT_MSG_TYPE_PUBREC = 5,
+  MQTT_MSG_TYPE_PUBREL = 6,
+  MQTT_MSG_TYPE_PUBCOMP = 7,
+  MQTT_MSG_TYPE_SUBSCRIBE = 8,
+  MQTT_MSG_TYPE_SUBACK = 9,
+  MQTT_MSG_TYPE_UNSUBSCRIBE = 10,
+  MQTT_MSG_TYPE_UNSUBACK = 11,
+  MQTT_MSG_TYPE_PINGREQ = 12,
+  MQTT_MSG_TYPE_PINGRESP = 13,
+  MQTT_MSG_TYPE_DISCONNECT = 14
+};
+
+/** Helpers to extract control packet type and qos from first byte in fixed header */
+#define MQTT_CTL_PACKET_TYPE(fixed_hdr_byte0) ((fixed_hdr_byte0 & 0xf0) >> 4)
+#define MQTT_CTL_PACKET_QOS(fixed_hdr_byte0) ((fixed_hdr_byte0 & 0x6) >> 1)
+
+/**
+ * MQTT connect flags, only used in CONNECT message
+ */
+enum mqtt_connect_flag {
+  MQTT_CONNECT_FLAG_USERNAME = 1 << 7,
+  MQTT_CONNECT_FLAG_PASSWORD = 1 << 6,
+  MQTT_CONNECT_FLAG_WILL_RETAIN = 1 << 5,
+  MQTT_CONNECT_FLAG_WILL = 1 << 2,
+  MQTT_CONNECT_FLAG_CLEAN_SESSION = 1 << 1
+};
+
+
+static void mqtt_cyclic_timer(void *arg);
+
+#if defined(LWIP_DEBUG)
+static const char *const mqtt_message_type_str[15] = {
+  "UNDEFINED",
+  "CONNECT",
+  "CONNACK",
+  "PUBLISH",
+  "PUBACK",
+  "PUBREC",
+  "PUBREL",
+  "PUBCOMP",
+  "SUBSCRIBE",
+  "SUBACK",
+  "UNSUBSCRIBE",
+  "UNSUBACK",
+  "PINGREQ",
+  "PINGRESP",
+  "DISCONNECT"
+};
+
+/**
+ * Message type value to string
+ * @param msg_type see enum mqtt_message_type
+ *
+ * @return Control message type text string
+ */
+static const char *
+mqtt_msg_type_to_str(u8_t msg_type)
+{
+  if (msg_type >= LWIP_ARRAYSIZE(mqtt_message_type_str)) {
+    msg_type = 0;
+  }
+  return mqtt_message_type_str[msg_type];
+}
+
+#endif
+
+
+/**
+ * Generate MQTT packet identifier
+ * @param client MQTT client
+ * @return New packet identifier, range 1 to 65535
+ */
+static u16_t
+msg_generate_packet_id(mqtt_client_t *client)
+{
+  client->pkt_id_seq++;
+  if (client->pkt_id_seq == 0) {
+    client->pkt_id_seq++;
+  }
+  return client->pkt_id_seq;
+}
+
+/*--------------------------------------------------------------------------------------------------------------------- */
+/* Output ring buffer */
+
+/** Add single item to ring buffer */
+static void
+mqtt_ringbuf_put(struct mqtt_ringbuf_t *rb, u8_t item)
+{
+  rb->buf[rb->put] = item;
+  rb->put++;
+  if (rb->put >= MQTT_OUTPUT_RINGBUF_SIZE) {
+    rb->put = 0;
+  }
+}
+
+/** Return pointer to ring buffer get position */
+static u8_t *
+mqtt_ringbuf_get_ptr(struct mqtt_ringbuf_t *rb)
+{
+  return &rb->buf[rb->get];
+}
+
+static void
+mqtt_ringbuf_advance_get_idx(struct mqtt_ringbuf_t *rb, u16_t len)
+{
+  LWIP_ASSERT("mqtt_ringbuf_advance_get_idx: len < MQTT_OUTPUT_RINGBUF_SIZE", len < MQTT_OUTPUT_RINGBUF_SIZE);
+
+  rb->get += len;
+  if (rb->get >= MQTT_OUTPUT_RINGBUF_SIZE) {
+    rb->get = rb->get - MQTT_OUTPUT_RINGBUF_SIZE;
+  }
+}
+
+/** Return number of bytes in ring buffer */
+static u16_t
+mqtt_ringbuf_len(struct mqtt_ringbuf_t *rb)
+{
+  u32_t len = rb->put - rb->get;
+  if (len > 0xFFFF) {
+    len += MQTT_OUTPUT_RINGBUF_SIZE;
+  }
+  return (u16_t)len;
+}
+
+/** Return number of bytes free in ring buffer */
+#define mqtt_ringbuf_free(rb) (MQTT_OUTPUT_RINGBUF_SIZE - mqtt_ringbuf_len(rb))
+
+/** Return number of bytes possible to read without wrapping around */
+#define mqtt_ringbuf_linear_read_length(rb) LWIP_MIN(mqtt_ringbuf_len(rb), (MQTT_OUTPUT_RINGBUF_SIZE - (rb)->get))
+
+/**
+ * Try send as many bytes as possible from output ring buffer
+ * @param rb Output ring buffer
+ * @param tpcb TCP connection handle
+ */
+static void
+mqtt_output_send(struct mqtt_ringbuf_t *rb, struct altcp_pcb *tpcb)
+{
+  err_t err;
+  u8_t wrap = 0;
+  u16_t ringbuf_lin_len = mqtt_ringbuf_linear_read_length(rb);
+  u16_t send_len = altcp_sndbuf(tpcb);
+  LWIP_ASSERT("mqtt_output_send: tpcb != NULL", tpcb != NULL);
+
+  if (send_len == 0 || ringbuf_lin_len == 0) {
+    return;
+  }
+
+  LWIP_DEBUGF(MQTT_DEBUG_TRACE, ("mqtt_output_send: tcp_sndbuf: %d bytes, ringbuf_linear_available: %d, get %d, put %d\n",
+                                 send_len, ringbuf_lin_len, rb->get, rb->put));
+
+  if (send_len > ringbuf_lin_len) {
+    /* Space in TCP output buffer is larger than available in ring buffer linear portion */
+    send_len = ringbuf_lin_len;
+    /* Wrap around if more data in ring buffer after linear portion */
+    wrap = (mqtt_ringbuf_len(rb) > ringbuf_lin_len);
+  }
+  err = altcp_write(tpcb, mqtt_ringbuf_get_ptr(rb), send_len, TCP_WRITE_FLAG_COPY | (wrap ? TCP_WRITE_FLAG_MORE : 0));
+  if ((err == ERR_OK) && wrap) {
+    mqtt_ringbuf_advance_get_idx(rb, send_len);
+    /* Use the lesser one of ring buffer linear length and TCP send buffer size */
+    send_len = LWIP_MIN(altcp_sndbuf(tpcb), mqtt_ringbuf_linear_read_length(rb));
+    err = altcp_write(tpcb, mqtt_ringbuf_get_ptr(rb), send_len, TCP_WRITE_FLAG_COPY);
+  }
+
+  if (err == ERR_OK) {
+    mqtt_ringbuf_advance_get_idx(rb, send_len);
+    /* Flush */
+    altcp_output(tpcb);
+  } else {
+    LWIP_DEBUGF(MQTT_DEBUG_WARN, ("mqtt_output_send: Send failed with err %d (\"%s\")\n", err, lwip_strerr(err)));
+  }
+}
+
+
+
+/*--------------------------------------------------------------------------------------------------------------------- */
+/* Request queue */
+
+/**
+ * Create request item
+ * @param r_objs Pointer to request objects
+ * @param r_objs_len Number of array entries
+ * @param pkt_id Packet identifier of request
+ * @param cb Packet callback to call when requests lifetime ends
+ * @param arg Parameter following callback
+ * @return Request or NULL if failed to create
+ */
+static struct mqtt_request_t *
+mqtt_create_request(struct mqtt_request_t *r_objs, size_t r_objs_len, u16_t pkt_id, mqtt_request_cb_t cb, void *arg)
+{
+  struct mqtt_request_t *r = NULL;
+  u8_t n;
+  LWIP_ASSERT("mqtt_create_request: r_objs != NULL", r_objs != NULL);
+  for (n = 0; n < r_objs_len; n++) {
+    /* Item point to itself if not in use */
+    if (r_objs[n].next == &r_objs[n]) {
+      r = &r_objs[n];
+      r->next = NULL;
+      r->cb = cb;
+      r->arg = arg;
+      r->pkt_id = pkt_id;
+      break;
+    }
+  }
+  return r;
+}
+
+
+/**
+ * Append request to pending request queue
+ * @param tail Pointer to request queue tail pointer
+ * @param r Request to append
+ */
+static void
+mqtt_append_request(struct mqtt_request_t **tail, struct mqtt_request_t *r)
+{
+  struct mqtt_request_t *head = NULL;
+  s16_t time_before = 0;
+  struct mqtt_request_t *iter;
+
+  LWIP_ASSERT("mqtt_append_request: tail != NULL", tail != NULL);
+
+  /* Iterate trough queue to find head, and count total timeout time */
+  for (iter = *tail; iter != NULL; iter = iter->next) {
+    time_before += iter->timeout_diff;
+    head = iter;
+  }
+
+  LWIP_ASSERT("mqtt_append_request: time_before <= MQTT_REQ_TIMEOUT", time_before <= MQTT_REQ_TIMEOUT);
+  r->timeout_diff = MQTT_REQ_TIMEOUT - time_before;
+  if (head == NULL) {
+    *tail = r;
+  } else {
+    head->next = r;
+  }
+}
+
+
+/**
+ * Delete request item
+ * @param r Request item to delete
+ */
+static void
+mqtt_delete_request(struct mqtt_request_t *r)
+{
+  if (r != NULL) {
+    r->next = r;
+  }
+}
+
+/**
+ * Remove a request item with a specific packet identifier from request queue
+ * @param tail Pointer to request queue tail pointer
+ * @param pkt_id Packet identifier of request to take
+ * @return Request item if found, NULL if not
+ */
+static struct mqtt_request_t *
+mqtt_take_request(struct mqtt_request_t **tail, u16_t pkt_id)
+{
+  struct mqtt_request_t *iter = NULL, *prev = NULL;
+  LWIP_ASSERT("mqtt_take_request: tail != NULL", tail != NULL);
+  /* Search all request for pkt_id */
+  for (iter = *tail; iter != NULL; iter = iter->next) {
+    if (iter->pkt_id == pkt_id) {
+      break;
+    }
+    prev = iter;
+  }
+
+  /* If request was found */
+  if (iter != NULL) {
+    /* unchain */
+    if (prev == NULL) {
+      *tail = iter->next;
+    } else {
+      prev->next = iter->next;
+    }
+    /* If exists, add remaining timeout time for the request to next */
+    if (iter->next != NULL) {
+      iter->next->timeout_diff += iter->timeout_diff;
+    }
+    iter->next = NULL;
+  }
+  return iter;
+}
+
+/**
+ * Handle requests timeout
+ * @param tail Pointer to request queue tail pointer
+ * @param t Time since last call in seconds
+ */
+static void
+mqtt_request_time_elapsed(struct mqtt_request_t **tail, u8_t t)
+{
+  struct mqtt_request_t *r;
+  LWIP_ASSERT("mqtt_request_time_elapsed: tail != NULL", tail != NULL);
+  r = *tail;
+  while (t > 0 && r != NULL) {
+    if (t >= r->timeout_diff) {
+      t -= (u8_t)r->timeout_diff;
+      /* Unchain */
+      *tail = r->next;
+      /* Notify upper layer about timeout */
+      if (r->cb != NULL) {
+        r->cb(r->arg, ERR_TIMEOUT);
+      }
+      mqtt_delete_request(r);
+      /* Tail might be be modified in callback, so re-read it in every iteration */
+      r = *(struct mqtt_request_t *const volatile *)tail;
+    } else {
+      r->timeout_diff -= t;
+      t = 0;
+    }
+  }
+}
+
+/**
+ * Free all request items
+ * @param tail Pointer to request queue tail pointer
+ */
+static void
+mqtt_clear_requests(struct mqtt_request_t **tail)
+{
+  struct mqtt_request_t *iter, *next;
+  LWIP_ASSERT("mqtt_clear_requests: tail != NULL", tail != NULL);
+  for (iter = *tail; iter != NULL; iter = next) {
+    next = iter->next;
+    mqtt_delete_request(iter);
+  }
+  *tail = NULL;
+}
+/**
+ * Initialize all request items
+ * @param r_objs Pointer to request objects
+ * @param r_objs_len Number of array entries
+ */
+static void
+mqtt_init_requests(struct mqtt_request_t *r_objs, size_t r_objs_len)
+{
+  u8_t n;
+  LWIP_ASSERT("mqtt_init_requests: r_objs != NULL", r_objs != NULL);
+  for (n = 0; n < r_objs_len; n++) {
+    /* Item pointing to itself indicates unused */
+    r_objs[n].next = &r_objs[n];
+  }
+}
+
+/*--------------------------------------------------------------------------------------------------------------------- */
+/* Output message build helpers */
+
+
+static void
+mqtt_output_append_u8(struct mqtt_ringbuf_t *rb, u8_t value)
+{
+  mqtt_ringbuf_put(rb, value);
+}
+
+static
+void mqtt_output_append_u16(struct mqtt_ringbuf_t *rb, u16_t value)
+{
+  mqtt_ringbuf_put(rb, value >> 8);
+  mqtt_ringbuf_put(rb, value & 0xff);
+}
+
+static void
+mqtt_output_append_buf(struct mqtt_ringbuf_t *rb, const void *data, u16_t length)
+{
+  u16_t n;
+  for (n = 0; n < length; n++) {
+    mqtt_ringbuf_put(rb, ((const u8_t *)data)[n]);
+  }
+}
+
+static void
+mqtt_output_append_string(struct mqtt_ringbuf_t *rb, const char *str, u16_t length)
+{
+  u16_t n;
+  mqtt_ringbuf_put(rb, length >> 8);
+  mqtt_ringbuf_put(rb, length & 0xff);
+  for (n = 0; n < length; n++) {
+    mqtt_ringbuf_put(rb, str[n]);
+  }
+}
+
+/**
+ * Append fixed header
+ * @param rb Output ring buffer
+ * @param msg_type see enum mqtt_message_type
+ * @param fdup MQTT DUP flag
+ * @param fqos MQTT QoS field
+ * @param fretain MQTT retain flag
+ * @param r_length Remaining length after fixed header
+ */
+
+static void
+mqtt_output_append_fixed_header(struct mqtt_ringbuf_t *rb, u8_t msg_type, u8_t fdup,
+                                u8_t fqos, u8_t fretain, u16_t r_length)
+{
+  /* Start with control byte */
+  mqtt_output_append_u8(rb, (((msg_type & 0x0f) << 4) | ((fdup & 1) << 3) | ((fqos & 3) << 1) | (fretain & 1)));
+  /* Encode remaining length field */
+  do {
+    mqtt_output_append_u8(rb, (r_length & 0x7f) | (r_length >= 128 ? 0x80 : 0));
+    r_length >>= 7;
+  } while (r_length > 0);
+}
+
+
+/**
+ * Check output buffer space
+ * @param rb Output ring buffer
+ * @param r_length Remaining length after fixed header
+ * @return 1 if message will fit, 0 if not enough buffer space
+ */
+static u8_t
+mqtt_output_check_space(struct mqtt_ringbuf_t *rb, u16_t r_length)
+{
+  /* Start with length of type byte + remaining length */
+  u16_t total_len = 1 + r_length;
+
+  LWIP_ASSERT("mqtt_output_check_space: rb != NULL", rb != NULL);
+
+  /* Calculate number of required bytes to contain the remaining bytes field and add to total*/
+  do {
+    total_len++;
+    r_length >>= 7;
+  } while (r_length > 0);
+
+  return (total_len <= mqtt_ringbuf_free(rb));
+}
+
+
+/**
+ * Close connection to server
+ * @param client MQTT client
+ * @param reason Reason for disconnection
+ */
+static void
+mqtt_close(mqtt_client_t *client, mqtt_connection_status_t reason)
+{
+  LWIP_ASSERT("mqtt_close: client != NULL", client != NULL);
+
+  /* Bring down TCP connection if not already done */
+  if (client->conn != NULL) {
+    err_t res;
+    altcp_recv(client->conn, NULL);
+    altcp_err(client->conn,  NULL);
+    altcp_sent(client->conn, NULL);
+    res = altcp_close(client->conn);
+    if (res != ERR_OK) {
+      altcp_abort(client->conn);
+      LWIP_DEBUGF(MQTT_DEBUG_TRACE, ("mqtt_close: Close err=%s\n", lwip_strerr(res)));
+    }
+    client->conn = NULL;
+  }
+
+  /* Remove all pending requests */
+  mqtt_clear_requests(&client->pend_req_queue);
+  /* Stop cyclic timer */
+  sys_untimeout(mqtt_cyclic_timer, client);
+
+  /* Notify upper layer of disconnection if changed state */
+  if (client->conn_state != TCP_DISCONNECTED) {
+
+    client->conn_state = TCP_DISCONNECTED;
+    if (client->connect_cb != NULL) {
+      client->connect_cb(client, client->connect_arg, reason);
+    }
+  }
+}
+
+
+/**
+ * Interval timer, called every MQTT_CYCLIC_TIMER_INTERVAL seconds in MQTT_CONNECTING and MQTT_CONNECTED states
+ * @param arg MQTT client
+ */
+static void
+mqtt_cyclic_timer(void *arg)
+{
+  u8_t restart_timer = 1;
+  mqtt_client_t *client = (mqtt_client_t *)arg;
+  LWIP_ASSERT("mqtt_cyclic_timer: client != NULL", client != NULL);
+
+  if (client->conn_state == MQTT_CONNECTING) {
+    client->cyclic_tick++;
+    if ((client->cyclic_tick * MQTT_CYCLIC_TIMER_INTERVAL) >= MQTT_CONNECT_TIMOUT) {
+      LWIP_DEBUGF(MQTT_DEBUG_TRACE, ("mqtt_cyclic_timer: CONNECT attempt to server timed out\n"));
+      /* Disconnect TCP */
+      mqtt_close(client, MQTT_CONNECT_TIMEOUT);
+      restart_timer = 0;
+    }
+  } else if (client->conn_state == MQTT_CONNECTED) {
+    /* Handle timeout for pending requests */
+    mqtt_request_time_elapsed(&client->pend_req_queue, MQTT_CYCLIC_TIMER_INTERVAL);
+
+    /* keep_alive > 0 means keep alive functionality shall be used */
+    if (client->keep_alive > 0) {
+
+      client->server_watchdog++;
+      /* If reception from server has been idle for 1.5*keep_alive time, server is considered unresponsive */
+      if ((client->server_watchdog * MQTT_CYCLIC_TIMER_INTERVAL) > (client->keep_alive + client->keep_alive / 2)) {
+        LWIP_DEBUGF(MQTT_DEBUG_WARN, ("mqtt_cyclic_timer: Server incoming keep-alive timeout\n"));
+        mqtt_close(client, MQTT_CONNECT_TIMEOUT);
+        restart_timer = 0;
+      }
+
+      /* If time for a keep alive message to be sent, transmission has been idle for keep_alive time */
+      if ((client->cyclic_tick * MQTT_CYCLIC_TIMER_INTERVAL) >= client->keep_alive) {
+        LWIP_DEBUGF(MQTT_DEBUG_TRACE, ("mqtt_cyclic_timer: Sending keep-alive message to server\n"));
+        if (mqtt_output_check_space(&client->output, 0) != 0) {
+          mqtt_output_append_fixed_header(&client->output, MQTT_MSG_TYPE_PINGREQ, 0, 0, 0, 0);
+          client->cyclic_tick = 0;
+        }
+      } else {
+        client->cyclic_tick++;
+      }
+    }
+  } else {
+    LWIP_DEBUGF(MQTT_DEBUG_WARN, ("mqtt_cyclic_timer: Timer should not be running in state %d\n", client->conn_state));
+    restart_timer = 0;
+  }
+  if (restart_timer) {
+    sys_timeout(MQTT_CYCLIC_TIMER_INTERVAL * 1000, mqtt_cyclic_timer, arg);
+  }
+}
+
+
+/**
+ * Send PUBACK, PUBREC or PUBREL response message
+ * @param client MQTT client
+ * @param msg PUBACK, PUBREC or PUBREL
+ * @param pkt_id Packet identifier
+ * @param qos QoS value
+ * @return ERR_OK if successful, ERR_MEM if out of memory
+ */
+static err_t
+pub_ack_rec_rel_response(mqtt_client_t *client, u8_t msg, u16_t pkt_id, u8_t qos)
+{
+  err_t err = ERR_OK;
+  if (mqtt_output_check_space(&client->output, 2)) {
+    mqtt_output_append_fixed_header(&client->output, msg, 0, qos, 0, 2);
+    mqtt_output_append_u16(&client->output, pkt_id);
+    mqtt_output_send(&client->output, client->conn);
+  } else {
+    LWIP_DEBUGF(MQTT_DEBUG_TRACE, ("pub_ack_rec_rel_response: OOM creating response: %s with pkt_id: %d\n",
+                                   mqtt_msg_type_to_str(msg), pkt_id));
+    err = ERR_MEM;
+  }
+  return err;
+}
+
+/**
+ * Subscribe response from server
+ * @param r Matching request
+ * @param result Result code from server
+ */
+static void
+mqtt_incomming_suback(struct mqtt_request_t *r, u8_t result)
+{
+  if (r->cb != NULL) {
+    r->cb(r->arg, result < 3 ? ERR_OK : ERR_ABRT);
+  }
+}
+
+
+/**
+ * Complete MQTT message received or buffer full
+ * @param client MQTT client
+ * @param fixed_hdr_idx header index
+ * @param length length received part
+ * @param remaining_length Remaining length of complete message
+ */
+static mqtt_connection_status_t
+mqtt_message_received(mqtt_client_t *client, u8_t fixed_hdr_idx, u16_t length, u32_t remaining_length)
+{
+  mqtt_connection_status_t res = MQTT_CONNECT_ACCEPTED;
+
+  u8_t *var_hdr_payload = client->rx_buffer + fixed_hdr_idx;
+  size_t var_hdr_payload_bufsize = sizeof(client->rx_buffer) - fixed_hdr_idx;
+
+  /* Control packet type */
+  u8_t pkt_type = MQTT_CTL_PACKET_TYPE(client->rx_buffer[0]);
+  u16_t pkt_id = 0;
+
+  LWIP_ASSERT("client->msg_idx < MQTT_VAR_HEADER_BUFFER_LEN", client->msg_idx < MQTT_VAR_HEADER_BUFFER_LEN);
+  LWIP_ASSERT("fixed_hdr_idx <= client->msg_idx", fixed_hdr_idx <= client->msg_idx);
+  LWIP_ERROR("buffer length mismatch", fixed_hdr_idx + length <= MQTT_VAR_HEADER_BUFFER_LEN,
+             return MQTT_CONNECT_DISCONNECTED);
+
+  if (pkt_type == MQTT_MSG_TYPE_CONNACK) {
+    if (client->conn_state == MQTT_CONNECTING) {
+      if (length < 2) {
+        LWIP_DEBUGF(MQTT_DEBUG_WARN,( "mqtt_message_received: Received short CONNACK message\n"));
+        goto out_disconnect;
+      }
+      /* Get result code from CONNACK */
+      res = (mqtt_connection_status_t)var_hdr_payload[1];
+      LWIP_DEBUGF(MQTT_DEBUG_TRACE, ("mqtt_message_received: Connect response code %d\n", res));
+      if (res == MQTT_CONNECT_ACCEPTED) {
+        /* Reset cyclic_tick when changing to connected state */
+        client->cyclic_tick = 0;
+        client->conn_state = MQTT_CONNECTED;
+        /* Notify upper layer */
+        if (client->connect_cb != 0) {
+          client->connect_cb(client, client->connect_arg, res);
+        }
+      }
+    } else {
+      LWIP_DEBUGF(MQTT_DEBUG_WARN, ("mqtt_message_received: Received CONNACK in connected state\n"));
+    }
+  } else if (pkt_type == MQTT_MSG_TYPE_PINGRESP) {
+    LWIP_DEBUGF(MQTT_DEBUG_TRACE, ( "mqtt_message_received: Received PINGRESP from server\n"));
+
+  } else if (pkt_type == MQTT_MSG_TYPE_PUBLISH) {
+    u16_t payload_offset = 0;
+    u16_t payload_length = length;
+    u8_t qos = MQTT_CTL_PACKET_QOS(client->rx_buffer[0]);
+
+    if (client->msg_idx <= MQTT_VAR_HEADER_BUFFER_LEN) {
+      /* Should have topic and pkt id*/
+      u8_t *topic;
+      u16_t after_topic;
+      u8_t bkp;
+      u16_t topic_len;
+      u16_t qos_len = (qos ? 2U : 0U);
+      if (length < 2 + qos_len) {
+        LWIP_DEBUGF(MQTT_DEBUG_WARN,( "mqtt_message_received: Received short PUBLISH packet\n"));
+        goto out_disconnect;
+      }
+      topic_len = var_hdr_payload[0];
+      topic_len = (topic_len << 8) + (u16_t)(var_hdr_payload[1]);
+      if ((topic_len > length - (2 + qos_len)) ||
+          (topic_len > var_hdr_payload_bufsize - (2 + qos_len))) {
+        LWIP_DEBUGF(MQTT_DEBUG_WARN,( "mqtt_message_received: Received short PUBLISH packet (topic)\n"));
+        goto out_disconnect;
+      }
+
+      topic = var_hdr_payload + 2;
+      after_topic = 2 + topic_len;
+      /* Check buffer length, add one byte even for QoS 0 so that zero termination will fit */
+      if ((after_topic + (qos ? 2U : 1U)) > var_hdr_payload_bufsize) {
+        LWIP_DEBUGF(MQTT_DEBUG_WARN, ("mqtt_message_received: Receive buffer can not fit topic + pkt_id\n"));
+        goto out_disconnect;
+      }
+
+      /* id for QoS 1 and 2 */
+      if (qos > 0) {
+        if (length < after_topic + 2U) {
+          LWIP_DEBUGF(MQTT_DEBUG_WARN,( "mqtt_message_received: Received short PUBLISH packet (after_topic)\n"));
+          goto out_disconnect;
+        }
+        client->inpub_pkt_id = ((u16_t)var_hdr_payload[after_topic] << 8) + (u16_t)var_hdr_payload[after_topic + 1];
+        after_topic += 2;
+      } else {
+        client->inpub_pkt_id = 0;
+      }
+      /* Take backup of byte after topic */
+      bkp = topic[topic_len];
+      /* Zero terminate string */
+      topic[topic_len] = 0;
+      /* Payload data remaining in receive buffer */
+      payload_length = length - after_topic;
+      payload_offset = after_topic;
+
+      LWIP_DEBUGF(MQTT_DEBUG_TRACE, ("mqtt_incomming_publish: Received message with QoS %d at topic: %s, payload length %"U32_F"\n",
+                                     qos, topic, remaining_length + payload_length));
+      if (client->pub_cb != NULL) {
+        client->pub_cb(client->inpub_arg, (const char *)topic, remaining_length + payload_length);
+      }
+      /* Restore byte after topic */
+      topic[topic_len] = bkp;
+    }
+    if (payload_length > 0 || remaining_length == 0) {
+      if (length < (size_t)(payload_offset + payload_length)) {
+        LWIP_DEBUGF(MQTT_DEBUG_WARN,( "mqtt_message_received: Received short packet (payload)\n"));
+        goto out_disconnect;
+      }
+      client->data_cb(client->inpub_arg, var_hdr_payload + payload_offset, payload_length, remaining_length == 0 ? MQTT_DATA_FLAG_LAST : 0);
+      /* Reply if QoS > 0 */
+      if (remaining_length == 0 && qos > 0) {
+        /* Send PUBACK for QoS 1 or PUBREC for QoS 2 */
+        u8_t resp_msg = (qos == 1) ? MQTT_MSG_TYPE_PUBACK : MQTT_MSG_TYPE_PUBREC;
+        LWIP_DEBUGF(MQTT_DEBUG_TRACE, ("mqtt_incomming_publish: Sending publish response: %s with pkt_id: %d\n",
+                                       mqtt_msg_type_to_str(resp_msg), client->inpub_pkt_id));
+        pub_ack_rec_rel_response(client, resp_msg, client->inpub_pkt_id, 0);
+      }
+    }
+  } else {
+    /* Get packet identifier */
+    pkt_id = (u16_t)var_hdr_payload[0] << 8;
+    pkt_id |= (u16_t)var_hdr_payload[1];
+    if (pkt_id == 0) {
+      LWIP_DEBUGF(MQTT_DEBUG_WARN, ("mqtt_message_received: Got message with illegal packet identifier: 0\n"));
+      goto out_disconnect;
+    }
+    if (pkt_type == MQTT_MSG_TYPE_PUBREC) {
+      LWIP_DEBUGF(MQTT_DEBUG_TRACE, ("mqtt_message_received: PUBREC, sending PUBREL with pkt_id: %d\n", pkt_id));
+      pub_ack_rec_rel_response(client, MQTT_MSG_TYPE_PUBREL, pkt_id, 1);
+
+    } else if (pkt_type == MQTT_MSG_TYPE_PUBREL) {
+      LWIP_DEBUGF(MQTT_DEBUG_TRACE, ("mqtt_message_received: PUBREL, sending PUBCOMP response with pkt_id: %d\n", pkt_id));
+      pub_ack_rec_rel_response(client, MQTT_MSG_TYPE_PUBCOMP, pkt_id, 0);
+
+    } else if (pkt_type == MQTT_MSG_TYPE_SUBACK || pkt_type == MQTT_MSG_TYPE_UNSUBACK ||
+               pkt_type == MQTT_MSG_TYPE_PUBCOMP || pkt_type == MQTT_MSG_TYPE_PUBACK) {
+      struct mqtt_request_t *r = mqtt_take_request(&client->pend_req_queue, pkt_id);
+      if (r != NULL) {
+        LWIP_DEBUGF(MQTT_DEBUG_TRACE, ("mqtt_message_received: %s response with id %d\n", mqtt_msg_type_to_str(pkt_type), pkt_id));
+        if (pkt_type == MQTT_MSG_TYPE_SUBACK) {
+          if (length < 3) {
+            LWIP_DEBUGF(MQTT_DEBUG_WARN, ("mqtt_message_received: To small SUBACK packet\n"));
+            goto out_disconnect;
+          } else {
+            mqtt_incomming_suback(r, var_hdr_payload[2]);
+          }
+        } else if (r->cb != NULL) {
+          r->cb(r->arg, ERR_OK);
+        }
+        mqtt_delete_request(r);
+      } else {
+        LWIP_DEBUGF(MQTT_DEBUG_WARN, ( "mqtt_message_received: Received %s reply, with wrong pkt_id: %d\n", mqtt_msg_type_to_str(pkt_type), pkt_id));
+      }
+    } else {
+      LWIP_DEBUGF(MQTT_DEBUG_WARN, ( "mqtt_message_received: Received unknown message type: %d\n", pkt_type));
+      goto out_disconnect;
+    }
+  }
+  return res;
+out_disconnect:
+  return MQTT_CONNECT_DISCONNECTED;
+}
+
+
+/**
+ * MQTT incoming message parser
+ * @param client MQTT client
+ * @param p PBUF chain of received data
+ * @return Connection status
+ */
+static mqtt_connection_status_t
+mqtt_parse_incoming(mqtt_client_t *client, struct pbuf *p)
+{
+  u16_t in_offset = 0;
+  u32_t msg_rem_len = 0;
+  u8_t fixed_hdr_idx = 0;
+  u8_t b = 0;
+
+  while (p->tot_len > in_offset) {
+    /* We ALWAYS parse the header here first. Even if the header was not
+       included in this segment, we re-parse it here by buffering it in
+       client->rx_buffer. client->msg_idx keeps track of this. */
+    if ((fixed_hdr_idx < 2) || ((b & 0x80) != 0)) {
+
+      if (fixed_hdr_idx < client->msg_idx) {
+        /* parse header from old pbuf (buffered in client->rx_buffer) */
+        b = client->rx_buffer[fixed_hdr_idx];
+      } else {
+        /* parse header from this pbuf and save it in client->rx_buffer in case
+           it comes in segmented */
+        b = pbuf_get_at(p, in_offset++);
+        client->rx_buffer[client->msg_idx++] = b;
+      }
+      fixed_hdr_idx++;
+
+      if (fixed_hdr_idx >= 2) {
+        /* fixed header contains at least 2 bytes but can contain more, depending on
+           'remaining length'. All bytes but the last of this have 0x80 set to
+           indicate more bytes are coming. */
+        msg_rem_len |= (u32_t)(b & 0x7f) << ((fixed_hdr_idx - 2) * 7);
+        if ((b & 0x80) == 0) {
+          /* fixed header is done */
+          LWIP_DEBUGF(MQTT_DEBUG_TRACE, ("mqtt_parse_incoming: Remaining length after fixed header: %"U32_F"\n", msg_rem_len));
+          if (msg_rem_len == 0) {
+            /* Complete message with no extra headers of payload received */
+            mqtt_message_received(client, fixed_hdr_idx, 0, 0);
+            client->msg_idx = 0;
+            fixed_hdr_idx = 0;
+          } else {
+            /* Bytes remaining in message (changes remaining length if this is
+               not the first segment of this message) */
+            msg_rem_len = (msg_rem_len + fixed_hdr_idx) - client->msg_idx;
+          }
+        }
+      }
+    } else {
+      /* Fixed header has been parsed, parse variable header */
+      u16_t cpy_len, cpy_start, buffer_space;
+
+      cpy_start = (client->msg_idx - fixed_hdr_idx) % (MQTT_VAR_HEADER_BUFFER_LEN - fixed_hdr_idx) + fixed_hdr_idx;
+
+      /* Allow to copy the lesser one of available length in input data or bytes remaining in message */
+      cpy_len = (u16_t)LWIP_MIN((u16_t)(p->tot_len - in_offset), msg_rem_len);
+
+      /* Limit to available space in buffer */
+      buffer_space = MQTT_VAR_HEADER_BUFFER_LEN - cpy_start;
+      if (cpy_len > buffer_space) {
+        cpy_len = buffer_space;
+      }
+      pbuf_copy_partial(p, client->rx_buffer + cpy_start, cpy_len, in_offset);
+
+      /* Advance get and put indexes  */
+      client->msg_idx += cpy_len;
+      in_offset += cpy_len;
+      msg_rem_len -= cpy_len;
+
+      LWIP_DEBUGF(MQTT_DEBUG_TRACE, ("mqtt_parse_incoming: msg_idx: %"U32_F", cpy_len: %"U16_F", remaining %"U32_F"\n", client->msg_idx, cpy_len, msg_rem_len));
+      if ((msg_rem_len == 0) || (cpy_len == buffer_space)) {
+        /* Whole message received or buffer is full */
+        mqtt_connection_status_t res = mqtt_message_received(client, fixed_hdr_idx, (cpy_start + cpy_len) - fixed_hdr_idx, msg_rem_len);
+        if (res != MQTT_CONNECT_ACCEPTED) {
+          return res;
+        }
+        if (msg_rem_len == 0) {
+          /* Reset parser state */
+          client->msg_idx = 0;
+          /* msg_tot_len = 0; */
+          fixed_hdr_idx = 0;
+        }
+      }
+    }
+  }
+  return MQTT_CONNECT_ACCEPTED;
+}
+
+
+/**
+ * TCP received callback function. @see tcp_recv_fn
+ * @param arg MQTT client
+ * @param p PBUF chain of received data
+ * @param err Passed as return value if not ERR_OK
+ * @return ERR_OK or err passed into callback
+ */
+static err_t
+mqtt_tcp_recv_cb(void *arg, struct altcp_pcb *pcb, struct pbuf *p, err_t err)
+{
+  mqtt_client_t *client = (mqtt_client_t *)arg;
+  LWIP_ASSERT("mqtt_tcp_recv_cb: client != NULL", client != NULL);
+  LWIP_ASSERT("mqtt_tcp_recv_cb: client->conn == pcb", client->conn == pcb);
+
+  if (p == NULL) {
+    LWIP_DEBUGF(MQTT_DEBUG_TRACE, ("mqtt_tcp_recv_cb: Recv pbuf=NULL, remote has closed connection\n"));
+    mqtt_close(client, MQTT_CONNECT_DISCONNECTED);
+  } else {
+    mqtt_connection_status_t res;
+    if (err != ERR_OK) {
+      LWIP_DEBUGF(MQTT_DEBUG_WARN, ("mqtt_tcp_recv_cb: Recv err=%d\n", err));
+      pbuf_free(p);
+      return err;
+    }
+
+    /* Tell remote that data has been received */
+    altcp_recved(pcb, p->tot_len);
+    res = mqtt_parse_incoming(client, p);
+    pbuf_free(p);
+
+    if (res != MQTT_CONNECT_ACCEPTED) {
+      mqtt_close(client, res);
+    }
+    /* If keep alive functionality is used */
+    if (client->keep_alive != 0) {
+      /* Reset server alive watchdog */
+      client->server_watchdog = 0;
+    }
+
+  }
+  return ERR_OK;
+}
+
+
+/**
+ * TCP data sent callback function. @see tcp_sent_fn
+ * @param arg MQTT client
+ * @param tpcb TCP connection handle
+ * @param len Number of bytes sent
+ * @return ERR_OK
+ */
+static err_t
+mqtt_tcp_sent_cb(void *arg, struct altcp_pcb *tpcb, u16_t len)
+{
+  mqtt_client_t *client = (mqtt_client_t *)arg;
+
+  LWIP_UNUSED_ARG(tpcb);
+  LWIP_UNUSED_ARG(len);
+
+  if (client->conn_state == MQTT_CONNECTED) {
+    struct mqtt_request_t *r;
+
+    /* Reset keep-alive send timer and server watchdog */
+    client->cyclic_tick = 0;
+    client->server_watchdog = 0;
+    /* QoS 0 publish has no response from server, so call its callbacks here */
+    while ((r = mqtt_take_request(&client->pend_req_queue, 0)) != NULL) {
+      LWIP_DEBUGF(MQTT_DEBUG_TRACE, ("mqtt_tcp_sent_cb: Calling QoS 0 publish complete callback\n"));
+      if (r->cb != NULL) {
+        r->cb(r->arg, ERR_OK);
+      }
+      mqtt_delete_request(r);
+    }
+    /* Try send any remaining buffers from output queue */
+    mqtt_output_send(&client->output, client->conn);
+  }
+  return ERR_OK;
+}
+
+/**
+ * TCP error callback function. @see tcp_err_fn
+ * @param arg MQTT client
+ * @param err Error encountered
+ */
+static void
+mqtt_tcp_err_cb(void *arg, err_t err)
+{
+  mqtt_client_t *client = (mqtt_client_t *)arg;
+  LWIP_UNUSED_ARG(err); /* only used for debug output */
+  LWIP_DEBUGF(MQTT_DEBUG_TRACE, ("mqtt_tcp_err_cb: TCP error callback: error %d, arg: %p\n", err, arg));
+  LWIP_ASSERT("mqtt_tcp_err_cb: client != NULL", client != NULL);
+  /* Set conn to null before calling close as pcb is already deallocated*/
+  client->conn = 0;
+  mqtt_close(client, MQTT_CONNECT_DISCONNECTED);
+}
+
+/**
+ * TCP poll callback function. @see tcp_poll_fn
+ * @param arg MQTT client
+ * @param tpcb TCP connection handle
+ * @return err ERR_OK
+ */
+static err_t
+mqtt_tcp_poll_cb(void *arg, struct altcp_pcb *tpcb)
+{
+  mqtt_client_t *client = (mqtt_client_t *)arg;
+  if (client->conn_state == MQTT_CONNECTED) {
+    /* Try send any remaining buffers from output queue */
+    mqtt_output_send(&client->output, tpcb);
+  }
+  return ERR_OK;
+}
+
+/**
+ * TCP connect callback function. @see tcp_connected_fn
+ * @param arg MQTT client
+ * @param err Always ERR_OK, mqtt_tcp_err_cb is called in case of error
+ * @return ERR_OK
+ */
+static err_t
+mqtt_tcp_connect_cb(void *arg, struct altcp_pcb *tpcb, err_t err)
+{
+  mqtt_client_t *client = (mqtt_client_t *)arg;
+
+  if (err != ERR_OK) {
+    LWIP_DEBUGF(MQTT_DEBUG_WARN, ("mqtt_tcp_connect_cb: TCP connect error %d\n", err));
+    return err;
+  }
+
+  /* Initiate receiver state */
+  client->msg_idx = 0;
+
+  /* Setup TCP callbacks */
+  altcp_recv(tpcb, mqtt_tcp_recv_cb);
+  altcp_sent(tpcb, mqtt_tcp_sent_cb);
+  altcp_poll(tpcb, mqtt_tcp_poll_cb, 2);
+
+  LWIP_DEBUGF(MQTT_DEBUG_TRACE, ("mqtt_tcp_connect_cb: TCP connection established to server\n"));
+  /* Enter MQTT connect state */
+  client->conn_state = MQTT_CONNECTING;
+
+  /* Start cyclic timer */
+  sys_timeout(MQTT_CYCLIC_TIMER_INTERVAL * 1000, mqtt_cyclic_timer, client);
+  client->cyclic_tick = 0;
+
+  /* Start transmission from output queue, connect message is the first one out*/
+  mqtt_output_send(&client->output, client->conn);
+
+  return ERR_OK;
+}
+
+
+
+/*---------------------------------------------------------------------------------------------------- */
+/* Public API */
+
+
+/**
+ * @ingroup mqtt
+ * MQTT publish function.
+ * @param client MQTT client
+ * @param topic Publish topic string
+ * @param payload Data to publish (NULL is allowed)
+ * @param payload_length Length of payload (0 is allowed)
+ * @param qos Quality of service, 0 1 or 2
+ * @param retain MQTT retain flag
+ * @param cb Callback to call when publish is complete or has timed out
+ * @param arg User supplied argument to publish callback
+ * @return ERR_OK if successful
+ *         ERR_CONN if client is disconnected
+ *         ERR_MEM if short on memory
+ */
+err_t
+mqtt_publish(mqtt_client_t *client, const char *topic, const void *payload, u16_t payload_length, u8_t qos, u8_t retain,
+             mqtt_request_cb_t cb, void *arg)
+{
+  struct mqtt_request_t *r;
+  u16_t pkt_id;
+  size_t topic_strlen;
+  size_t total_len;
+  u16_t topic_len;
+  u16_t remaining_length;
+
+  LWIP_ASSERT_CORE_LOCKED();
+  LWIP_ASSERT("mqtt_publish: client != NULL", client);
+  LWIP_ASSERT("mqtt_publish: topic != NULL", topic);
+  LWIP_ERROR("mqtt_publish: TCP disconnected", (client->conn_state != TCP_DISCONNECTED), return ERR_CONN);
+
+  topic_strlen = strlen(topic);
+  LWIP_ERROR("mqtt_publish: topic length overflow", (topic_strlen <= (0xFFFF - 2)), return ERR_ARG);
+  topic_len = (u16_t)topic_strlen;
+  total_len = 2 + topic_len + payload_length;
+
+  if (qos > 0) {
+    total_len += 2;
+    /* Generate pkt_id id for QoS1 and 2 */
+    pkt_id = msg_generate_packet_id(client);
+  } else {
+    /* Use reserved value pkt_id 0 for QoS 0 in request handle */
+    pkt_id = 0;
+  }
+  LWIP_ERROR("mqtt_publish: total length overflow", (total_len <= 0xFFFF), return ERR_ARG);
+  remaining_length = (u16_t)total_len;
+
+  LWIP_DEBUGF(MQTT_DEBUG_TRACE, ("mqtt_publish: Publish with payload length %d to topic \"%s\"\n", payload_length, topic));
+
+  r = mqtt_create_request(client->req_list, LWIP_ARRAYSIZE(client->req_list), pkt_id, cb, arg);
+  if (r == NULL) {
+    return ERR_MEM;
+  }
+
+  if (mqtt_output_check_space(&client->output, remaining_length) == 0) {
+    mqtt_delete_request(r);
+    return ERR_MEM;
+  }
+  /* Append fixed header */
+  mqtt_output_append_fixed_header(&client->output, MQTT_MSG_TYPE_PUBLISH, 0, qos, retain, remaining_length);
+
+  /* Append Topic */
+  mqtt_output_append_string(&client->output, topic, topic_len);
+
+  /* Append packet if for QoS 1 and 2*/
+  if (qos > 0) {
+    mqtt_output_append_u16(&client->output, pkt_id);
+  }
+
+  /* Append optional publish payload */
+  if ((payload != NULL) && (payload_length > 0)) {
+    mqtt_output_append_buf(&client->output, payload, payload_length);
+  }
+
+  mqtt_append_request(&client->pend_req_queue, r);
+  mqtt_output_send(&client->output, client->conn);
+  return ERR_OK;
+}
+
+
+/**
+ * @ingroup mqtt
+ * MQTT subscribe/unsubscribe function.
+ * @param client MQTT client
+ * @param topic topic to subscribe to
+ * @param qos Quality of service, 0 1 or 2 (only used for subscribe)
+ * @param cb Callback to call when subscribe/unsubscribe reponse is received
+ * @param arg User supplied argument to publish callback
+ * @param sub 1 for subscribe, 0 for unsubscribe
+ * @return ERR_OK if successful, @see err_t enum for other results
+ */
+err_t
+mqtt_sub_unsub(mqtt_client_t *client, const char *topic, u8_t qos, mqtt_request_cb_t cb, void *arg, u8_t sub)
+{
+  size_t topic_strlen;
+  size_t total_len;
+  u16_t topic_len;
+  u16_t remaining_length;
+  u16_t pkt_id;
+  struct mqtt_request_t *r;
+
+  LWIP_ASSERT_CORE_LOCKED();
+  LWIP_ASSERT("mqtt_sub_unsub: client != NULL", client);
+  LWIP_ASSERT("mqtt_sub_unsub: topic != NULL", topic);
+
+  topic_strlen = strlen(topic);
+  LWIP_ERROR("mqtt_sub_unsub: topic length overflow", (topic_strlen <= (0xFFFF - 2)), return ERR_ARG);
+  topic_len = (u16_t)topic_strlen;
+  /* Topic string, pkt_id, qos for subscribe */
+  total_len =  topic_len + 2 + 2 + (sub != 0);
+  LWIP_ERROR("mqtt_sub_unsub: total length overflow", (total_len <= 0xFFFF), return ERR_ARG);
+  remaining_length = (u16_t)total_len;
+
+  LWIP_ASSERT("mqtt_sub_unsub: qos < 3", qos < 3);
+  if (client->conn_state == TCP_DISCONNECTED) {
+    LWIP_DEBUGF(MQTT_DEBUG_WARN, ("mqtt_sub_unsub: Can not (un)subscribe in disconnected state\n"));
+    return ERR_CONN;
+  }
+
+  pkt_id = msg_generate_packet_id(client);
+  r = mqtt_create_request(client->req_list, LWIP_ARRAYSIZE(client->req_list), pkt_id, cb, arg);
+  if (r == NULL) {
+    return ERR_MEM;
+  }
+
+  if (mqtt_output_check_space(&client->output, remaining_length) == 0) {
+    mqtt_delete_request(r);
+    return ERR_MEM;
+  }
+
+  LWIP_DEBUGF(MQTT_DEBUG_TRACE, ("mqtt_sub_unsub: Client (un)subscribe to topic \"%s\", id: %d\n", topic, pkt_id));
+
+  mqtt_output_append_fixed_header(&client->output, sub ? MQTT_MSG_TYPE_SUBSCRIBE : MQTT_MSG_TYPE_UNSUBSCRIBE, 0, 1, 0, remaining_length);
+  /* Packet id */
+  mqtt_output_append_u16(&client->output, pkt_id);
+  /* Topic */
+  mqtt_output_append_string(&client->output, topic, topic_len);
+  /* QoS */
+  if (sub != 0) {
+    mqtt_output_append_u8(&client->output, LWIP_MIN(qos, 2));
+  }
+
+  mqtt_append_request(&client->pend_req_queue, r);
+  mqtt_output_send(&client->output, client->conn);
+  return ERR_OK;
+}
+
+
+/**
+ * @ingroup mqtt
+ * Set callback to handle incoming publish requests from server
+ * @param client MQTT client
+ * @param pub_cb Callback invoked when publish starts, contain topic and total length of payload
+ * @param data_cb Callback for each fragment of payload that arrives
+ * @param arg User supplied argument to both callbacks
+ */
+void
+mqtt_set_inpub_callback(mqtt_client_t *client, mqtt_incoming_publish_cb_t pub_cb,
+                        mqtt_incoming_data_cb_t data_cb, void *arg)
+{
+  LWIP_ASSERT_CORE_LOCKED();
+  LWIP_ASSERT("mqtt_set_inpub_callback: client != NULL", client != NULL);
+  client->data_cb = data_cb;
+  client->pub_cb = pub_cb;
+  client->inpub_arg = arg;
+}
+
+/**
+ * @ingroup mqtt
+ * Create a new MQTT client instance
+ * @return Pointer to instance on success, NULL otherwise
+ */
+mqtt_client_t *
+mqtt_client_new(void)
+{
+  LWIP_ASSERT_CORE_LOCKED();
+  return (mqtt_client_t *)mem_calloc(1, sizeof(mqtt_client_t));
+}
+
+/**
+ * @ingroup mqtt
+ * Free MQTT client instance
+ * @param client Pointer to instance to be freed
+ */
+void
+mqtt_client_free(mqtt_client_t *client)
+{
+  mem_free(client);
+}
+
+/**
+ * @ingroup mqtt
+ * Connect to MQTT server
+ * @param client MQTT client
+ * @param ip_addr Server IP
+ * @param port Server port
+ * @param cb Connection state change callback
+ * @param arg User supplied argument to connection callback
+ * @param client_info Client identification and connection options
+ * @return ERR_OK if successful, @see err_t enum for other results
+ */
+err_t
+mqtt_client_connect(mqtt_client_t *client, const ip_addr_t *ip_addr, u16_t port, mqtt_connection_cb_t cb, void *arg,
+                    const struct mqtt_connect_client_info_t *client_info)
+{
+  err_t err;
+  size_t len;
+  u16_t client_id_length;
+  /* Length is the sum of 2+"MQTT", protocol level, flags and keep alive */
+  u16_t remaining_length = 2 + 4 + 1 + 1 + 2;
+  u8_t flags = 0, will_topic_len = 0, will_msg_len = 0;
+  u16_t client_user_len = 0, client_pass_len = 0;
+
+  LWIP_ASSERT_CORE_LOCKED();
+  LWIP_ASSERT("mqtt_client_connect: client != NULL", client != NULL);
+  LWIP_ASSERT("mqtt_client_connect: ip_addr != NULL", ip_addr != NULL);
+  LWIP_ASSERT("mqtt_client_connect: client_info != NULL", client_info != NULL);
+  LWIP_ASSERT("mqtt_client_connect: client_info->client_id != NULL", client_info->client_id != NULL);
+
+  if (client->conn_state != TCP_DISCONNECTED) {
+    LWIP_DEBUGF(MQTT_DEBUG_WARN, ("mqtt_client_connect: Already connected\n"));
+    return ERR_ISCONN;
+  }
+
+  /* Wipe clean */
+  memset(client, 0, sizeof(mqtt_client_t));
+  client->connect_arg = arg;
+  client->connect_cb = cb;
+  client->keep_alive = client_info->keep_alive;
+  mqtt_init_requests(client->req_list, LWIP_ARRAYSIZE(client->req_list));
+
+  /* Build connect message */
+  if (client_info->will_topic != NULL && client_info->will_msg != NULL) {
+    flags |= MQTT_CONNECT_FLAG_WILL;
+    flags |= (client_info->will_qos & 3) << 3;
+    if (client_info->will_retain) {
+      flags |= MQTT_CONNECT_FLAG_WILL_RETAIN;
+    }
+    len = strlen(client_info->will_topic);
+    LWIP_ERROR("mqtt_client_connect: client_info->will_topic length overflow", len <= 0xFF, return ERR_VAL);
+    LWIP_ERROR("mqtt_client_connect: client_info->will_topic length must be > 0", len > 0, return ERR_VAL);
+    will_topic_len = (u8_t)len;
+    len = strlen(client_info->will_msg);
+    LWIP_ERROR("mqtt_client_connect: client_info->will_msg length overflow", len <= 0xFF, return ERR_VAL);
+    will_msg_len = (u8_t)len;
+    len = remaining_length + 2 + will_topic_len + 2 + will_msg_len;
+    LWIP_ERROR("mqtt_client_connect: remaining_length overflow", len <= 0xFFFF, return ERR_VAL);
+    remaining_length = (u16_t)len;
+  }
+  if (client_info->client_user != NULL) {
+    flags |= MQTT_CONNECT_FLAG_USERNAME;
+    len = strlen(client_info->client_user);
+    LWIP_ERROR("mqtt_client_connect: client_info->client_user length overflow", len <= 0xFFFF, return ERR_VAL);
+    LWIP_ERROR("mqtt_client_connect: client_info->client_user length must be > 0", len > 0, return ERR_VAL);
+    client_user_len = (u16_t)len;
+    len = remaining_length + 2 + client_user_len;
+    LWIP_ERROR("mqtt_client_connect: remaining_length overflow", len <= 0xFFFF, return ERR_VAL);
+    remaining_length = (u16_t)len;
+  }
+  if (client_info->client_pass != NULL) {
+    flags |= MQTT_CONNECT_FLAG_PASSWORD;
+    len = strlen(client_info->client_pass);
+    LWIP_ERROR("mqtt_client_connect: client_info->client_pass length overflow", len <= 0xFFFF, return ERR_VAL);
+    LWIP_ERROR("mqtt_client_connect: client_info->client_pass length must be > 0", len > 0, return ERR_VAL);
+    client_pass_len = (u16_t)len;
+    len = remaining_length + 2 + client_pass_len;
+    LWIP_ERROR("mqtt_client_connect: remaining_length overflow", len <= 0xFFFF, return ERR_VAL);
+    remaining_length = (u16_t)len;
+  }
+
+  /* Don't complicate things, always connect using clean session */
+  flags |= MQTT_CONNECT_FLAG_CLEAN_SESSION;
+
+  len = strlen(client_info->client_id);
+  LWIP_ERROR("mqtt_client_connect: client_info->client_id length overflow", len <= 0xFFFF, return ERR_VAL);
+  client_id_length = (u16_t)len;
+  len = remaining_length + 2 + client_id_length;
+  LWIP_ERROR("mqtt_client_connect: remaining_length overflow", len <= 0xFFFF, return ERR_VAL);
+  remaining_length = (u16_t)len;
+
+  if (mqtt_output_check_space(&client->output, remaining_length) == 0) {
+    return ERR_MEM;
+  }
+
+#if LWIP_ALTCP && LWIP_ALTCP_TLS
+  if (client_info->tls_config) {
+    client->conn = altcp_tls_new(client_info->tls_config, IP_GET_TYPE(ip_addr));
+  } else
+#endif
+  {
+    client->conn = altcp_tcp_new_ip_type(IP_GET_TYPE(ip_addr));
+  }
+  if (client->conn == NULL) {
+    return ERR_MEM;
+  }
+
+  /* Set arg pointer for callbacks */
+  altcp_arg(client->conn, client);
+  /* Any local address, pick random local port number */
+  err = altcp_bind(client->conn, IP_ADDR_ANY, 0);
+  if (err != ERR_OK) {
+    LWIP_DEBUGF(MQTT_DEBUG_WARN, ("mqtt_client_connect: Error binding to local ip/port, %d\n", err));
+    goto tcp_fail;
+  }
+  LWIP_DEBUGF(MQTT_DEBUG_TRACE, ("mqtt_client_connect: Connecting to host: %s at port:%"U16_F"\n", ipaddr_ntoa(ip_addr), port));
+
+  /* Connect to server */
+  err = altcp_connect(client->conn, ip_addr, port, mqtt_tcp_connect_cb);
+  if (err != ERR_OK) {
+    LWIP_DEBUGF(MQTT_DEBUG_TRACE, ("mqtt_client_connect: Error connecting to remote ip/port, %d\n", err));
+    goto tcp_fail;
+  }
+  /* Set error callback */
+  altcp_err(client->conn, mqtt_tcp_err_cb);
+  client->conn_state = TCP_CONNECTING;
+
+  /* Append fixed header */
+  mqtt_output_append_fixed_header(&client->output, MQTT_MSG_TYPE_CONNECT, 0, 0, 0, remaining_length);
+  /* Append Protocol string */
+  mqtt_output_append_string(&client->output, "MQTT", 4);
+  /* Append Protocol level */
+  mqtt_output_append_u8(&client->output, 4);
+  /* Append connect flags */
+  mqtt_output_append_u8(&client->output, flags);
+  /* Append keep-alive */
+  mqtt_output_append_u16(&client->output, client_info->keep_alive);
+  /* Append client id */
+  mqtt_output_append_string(&client->output, client_info->client_id, client_id_length);
+  /* Append will message if used */
+  if ((flags & MQTT_CONNECT_FLAG_WILL) != 0) {
+    mqtt_output_append_string(&client->output, client_info->will_topic, will_topic_len);
+    mqtt_output_append_string(&client->output, client_info->will_msg, will_msg_len);
+  }
+  /* Append user name if given */
+  if ((flags & MQTT_CONNECT_FLAG_USERNAME) != 0) {
+    mqtt_output_append_string(&client->output, client_info->client_user, client_user_len);
+  }
+  /* Append password if given */
+  if ((flags & MQTT_CONNECT_FLAG_PASSWORD) != 0) {
+    mqtt_output_append_string(&client->output, client_info->client_pass, client_pass_len);
+  }
+  return ERR_OK;
+
+tcp_fail:
+  altcp_abort(client->conn);
+  client->conn = NULL;
+  return err;
+}
+
+
+/**
+ * @ingroup mqtt
+ * Disconnect from MQTT server
+ * @param client MQTT client
+ */
+void
+mqtt_disconnect(mqtt_client_t *client)
+{
+  LWIP_ASSERT_CORE_LOCKED();
+  LWIP_ASSERT("mqtt_disconnect: client != NULL", client);
+  /* If connection in not already closed */
+  if (client->conn_state != TCP_DISCONNECTED) {
+    /* Set conn_state before calling mqtt_close to prevent callback from being called */
+    client->conn_state = TCP_DISCONNECTED;
+    mqtt_close(client, (mqtt_connection_status_t)0);
+  }
+}
+
+/**
+ * @ingroup mqtt
+ * Check connection with server
+ * @param client MQTT client
+ * @return 1 if connected to server, 0 otherwise
+ */
+u8_t
+mqtt_client_is_connected(mqtt_client_t *client)
+{
+  LWIP_ASSERT_CORE_LOCKED();
+  LWIP_ASSERT("mqtt_client_is_connected: client != NULL", client);
+  return client->conn_state == MQTT_CONNECTED;
+}
+
+#endif /* LWIP_TCP && LWIP_CALLBACK_API */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/apps/netbiosns/netbiosns.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/apps/netbiosns/netbiosns.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/apps/netbiosns/netbiosns.c	(revision 457)
@@ -0,0 +1,536 @@
+  /**
+ * @file
+ * NetBIOS name service responder
+ */
+
+/**
+ * @defgroup netbiosns NETBIOS responder
+ * @ingroup apps
+ *
+ * This is an example implementation of a NetBIOS name server.
+ * It responds to name queries for a configurable name.
+ * Name resolving is not supported.
+ *
+ * Note that the device doesn't broadcast it's own name so can't
+ * detect duplicate names!
+ */
+
+/*
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Modifications by Ray Abram to respond to NetBIOS name requests when Incoming name = *
+ * - based on code from "https://github.com/esp8266/Arduino/commit/1f7989b31d26d7df9776a08f36d685eae7ac8f99"
+ * - with permission to relicense to BSD from original author:
+ *   http://www.xpablo.cz/?p=751#more-751
+ */
+
+#include "lwip/apps/netbiosns.h"
+
+#if LWIP_IPV4 && LWIP_UDP  /* don't build if not configured for use in lwipopts.h */
+
+#include "lwip/def.h"
+#include "lwip/udp.h"
+#include "lwip/ip.h"
+#include "lwip/netif.h"
+#include "lwip/prot/iana.h"
+
+#include <string.h>
+
+/** size of a NetBIOS name */
+#define NETBIOS_NAME_LEN 16
+
+/** The Time-To-Live for NetBIOS name responds (in seconds)
+ * Default is 300000 seconds (3 days, 11 hours, 20 minutes) */
+#define NETBIOS_NAME_TTL 300000u
+
+/** NetBIOS header flags */
+#define NETB_HFLAG_RESPONSE           0x8000U
+#define NETB_HFLAG_OPCODE             0x7800U
+#define NETB_HFLAG_OPCODE_NAME_QUERY  0x0000U
+#define NETB_HFLAG_AUTHORATIVE        0x0400U
+#define NETB_HFLAG_TRUNCATED          0x0200U
+#define NETB_HFLAG_RECURS_DESIRED     0x0100U
+#define NETB_HFLAG_RECURS_AVAILABLE   0x0080U
+#define NETB_HFLAG_BROADCAST          0x0010U
+#define NETB_HFLAG_REPLYCODE          0x0008U
+#define NETB_HFLAG_REPLYCODE_NOERROR  0x0000U
+
+/* NetBIOS question types */
+#define NETB_QTYPE_NB                 0x0020U
+#define NETB_QTYPE_NBSTAT             0x0021U
+
+/** NetBIOS name flags */
+#define NETB_NFLAG_UNIQUE             0x8000U
+#define NETB_NFLAG_NODETYPE           0x6000U
+#define NETB_NFLAG_NODETYPE_HNODE     0x6000U
+#define NETB_NFLAG_NODETYPE_MNODE     0x4000U
+#define NETB_NFLAG_NODETYPE_PNODE     0x2000U
+#define NETB_NFLAG_NODETYPE_BNODE     0x0000U
+
+#define NETB_NFLAG_NAME_IN_CONFLICT   0x0800U /* 1=Yes, 0=No */
+#define NETB_NFLAG_NAME_IS_ACTIVE     0x0400U /* 1=Yes, 0=No */
+#define NETB_NFLAG_NAME_IS_PERMANENT  0x0200U /* 1=Yes (Name is Permanent Node Name), 0=No */
+
+/** NetBIOS message header */
+#ifdef PACK_STRUCT_USE_INCLUDES
+#  include "arch/bpstruct.h"
+#endif
+PACK_STRUCT_BEGIN
+struct netbios_hdr {
+  PACK_STRUCT_FIELD(u16_t trans_id);
+  PACK_STRUCT_FIELD(u16_t flags);
+  PACK_STRUCT_FIELD(u16_t questions);
+  PACK_STRUCT_FIELD(u16_t answerRRs);
+  PACK_STRUCT_FIELD(u16_t authorityRRs);
+  PACK_STRUCT_FIELD(u16_t additionalRRs);
+} PACK_STRUCT_STRUCT;
+PACK_STRUCT_END
+#ifdef PACK_STRUCT_USE_INCLUDES
+#  include "arch/epstruct.h"
+#endif
+
+/** NetBIOS message question part */
+#ifdef PACK_STRUCT_USE_INCLUDES
+#  include "arch/bpstruct.h"
+#endif
+PACK_STRUCT_BEGIN
+struct netbios_question_hdr {
+  PACK_STRUCT_FLD_8(u8_t  nametype);
+  PACK_STRUCT_FLD_8(u8_t  encname[(NETBIOS_NAME_LEN * 2) + 1]);
+  PACK_STRUCT_FIELD(u16_t type);
+  PACK_STRUCT_FIELD(u16_t cls);
+} PACK_STRUCT_STRUCT;
+PACK_STRUCT_END
+#ifdef PACK_STRUCT_USE_INCLUDES
+#  include "arch/epstruct.h"
+#endif
+
+/** NetBIOS message name part */
+#ifdef PACK_STRUCT_USE_INCLUDES
+#  include "arch/bpstruct.h"
+#endif
+PACK_STRUCT_BEGIN
+struct netbios_name_hdr {
+  PACK_STRUCT_FLD_8(u8_t  nametype);
+  PACK_STRUCT_FLD_8(u8_t  encname[(NETBIOS_NAME_LEN * 2) + 1]);
+  PACK_STRUCT_FIELD(u16_t type);
+  PACK_STRUCT_FIELD(u16_t cls);
+  PACK_STRUCT_FIELD(u32_t ttl);
+  PACK_STRUCT_FIELD(u16_t datalen);
+  PACK_STRUCT_FIELD(u16_t flags);
+  PACK_STRUCT_FLD_S(ip4_addr_p_t addr);
+} PACK_STRUCT_STRUCT;
+PACK_STRUCT_END
+#ifdef PACK_STRUCT_USE_INCLUDES
+#  include "arch/epstruct.h"
+#endif
+
+/** NetBIOS message */
+#ifdef PACK_STRUCT_USE_INCLUDES
+#  include "arch/bpstruct.h"
+#endif
+PACK_STRUCT_BEGIN
+struct netbios_resp {
+  struct netbios_hdr      resp_hdr;
+  struct netbios_name_hdr resp_name;
+} PACK_STRUCT_STRUCT;
+PACK_STRUCT_END
+#ifdef PACK_STRUCT_USE_INCLUDES
+#  include "arch/epstruct.h"
+#endif
+
+/** The NBNS Structure Responds to a Name Query */
+#ifdef PACK_STRUCT_USE_INCLUDES
+#  include "arch/bpstruct.h"
+#endif
+PACK_STRUCT_BEGIN
+struct netbios_answer {
+  struct netbios_hdr      answer_hdr;
+  /** the length of the next string */
+  PACK_STRUCT_FIELD(u8_t  name_size);
+  /** WARNING!!! this item may be of a different length (we use this struct for transmission) */
+  PACK_STRUCT_FLD_8(u8_t  query_name[(NETBIOS_NAME_LEN * 2) + 1]);
+  PACK_STRUCT_FIELD(u16_t packet_type);
+  PACK_STRUCT_FIELD(u16_t cls);
+  PACK_STRUCT_FIELD(u32_t ttl);
+  PACK_STRUCT_FIELD(u16_t data_length);
+#define OFFSETOF_STRUCT_NETBIOS_ANSWER_NUMBER_OF_NAMES 56
+  /** number of names */
+  PACK_STRUCT_FLD_8(u8_t  number_of_names);
+  /** node name */
+  PACK_STRUCT_FLD_8(u8_t  answer_name[NETBIOS_NAME_LEN]);
+  /** node flags */
+  PACK_STRUCT_FIELD(u16_t answer_name_flags);
+  /** Unit ID */
+  PACK_STRUCT_FLD_8(u8_t  unit_id[6]);
+  /** Jumpers */
+  PACK_STRUCT_FLD_8(u8_t  jumpers);
+  /** Test result */
+  PACK_STRUCT_FLD_8(u8_t  test_result);
+  /** Version number */
+  PACK_STRUCT_FIELD(u16_t version_number);
+  /** Period of statistics */
+  PACK_STRUCT_FIELD(u16_t period_of_statistics);
+  /** Statistics */
+  PACK_STRUCT_FIELD(u16_t number_of_crcs);
+  /** Statistics */
+  PACK_STRUCT_FIELD(u16_t number_of_alignment_errors);
+  /** Statistics */
+  PACK_STRUCT_FIELD(u16_t number_of_collisions);
+  /** Statistics */
+  PACK_STRUCT_FIELD(u16_t number_of_send_aborts);
+  /** Statistics */
+  PACK_STRUCT_FIELD(u32_t number_of_good_sends);
+  /** Statistics */
+  PACK_STRUCT_FIELD(u32_t number_of_good_receives);
+  /** Statistics */
+  PACK_STRUCT_FIELD(u16_t number_of_retransmits);
+  /** Statistics */
+  PACK_STRUCT_FIELD(u16_t number_of_no_resource_condition);
+  /** Statistics */
+  PACK_STRUCT_FIELD(u16_t number_of_free_command_blocks);
+  /** Statistics */
+  PACK_STRUCT_FIELD(u16_t total_number_of_command_blocks);
+  /** Statistics */
+  PACK_STRUCT_FIELD(u16_t max_total_number_of_command_blocks);
+  /** Statistics */
+  PACK_STRUCT_FIELD(u16_t number_of_pending_sessions);
+  /** Statistics */
+  PACK_STRUCT_FIELD(u16_t max_number_of_pending_sessions);
+  /** Statistics */
+  PACK_STRUCT_FIELD(u16_t max_total_sessions_possible);
+  /** Statistics */
+  PACK_STRUCT_FIELD(u16_t session_data_packet_size);
+} PACK_STRUCT_STRUCT;
+PACK_STRUCT_END
+#ifdef PACK_STRUCT_USE_INCLUDES
+#  include "arch/epstruct.h"
+#endif
+
+#ifdef NETBIOS_LWIP_NAME
+#define NETBIOS_LOCAL_NAME NETBIOS_LWIP_NAME
+#else
+static char netbiosns_local_name[NETBIOS_NAME_LEN];
+#define NETBIOS_LOCAL_NAME netbiosns_local_name
+#endif
+
+static struct udp_pcb *netbiosns_pcb;
+
+/** Decode a NetBIOS name (from packet to string) */
+static int
+netbiosns_name_decode(char *name_enc, char *name_dec, int name_dec_len)
+{
+  char *pname;
+  char  cname;
+  char  cnbname;
+  int   idx = 0;
+
+  LWIP_UNUSED_ARG(name_dec_len);
+
+  /* Start decoding netbios name. */
+  pname  = name_enc;
+  for (;;) {
+    /* Every two characters of the first level-encoded name
+     * turn into one character in the decoded name. */
+    cname = *pname;
+    if (cname == '\0') {
+      break;  /* no more characters */
+    }
+    if (cname == '.') {
+      break;  /* scope ID follows */
+    }
+    if (!lwip_isupper(cname)) {
+      /* Not legal. */
+      return -1;
+    }
+    cname -= 'A';
+    cnbname = cname << 4;
+    pname++;
+
+    cname = *pname;
+    if (!lwip_isupper(cname)) {
+      /* Not legal. */
+      return -1;
+    }
+    cname -= 'A';
+    cnbname |= cname;
+    pname++;
+
+    /* Do we have room to store the character? */
+    if (idx < NETBIOS_NAME_LEN) {
+      /* Yes - store the character. */
+      name_dec[idx++] = (cnbname != ' ' ? cnbname : '\0');
+    }
+  }
+
+  return 0;
+}
+
+#if 0 /* function currently unused */
+/** Encode a NetBIOS name (from string to packet) - currently unused because
+    we don't ask for names. */
+static int
+netbiosns_name_encode(char *name_enc, char *name_dec, int name_dec_len)
+{
+  char         *pname;
+  char          cname;
+  unsigned char ucname;
+  int           idx = 0;
+
+  /* Start encoding netbios name. */
+  pname = name_enc;
+
+  for (;;) {
+    /* Every two characters of the first level-encoded name
+     * turn into one character in the decoded name. */
+    cname = *pname;
+    if (cname == '\0') {
+      break;  /* no more characters */
+    }
+    if (cname == '.') {
+      break;  /* scope ID follows */
+    }
+    if ((cname < 'A' || cname > 'Z') && (cname < '0' || cname > '9')) {
+      /* Not legal. */
+      return -1;
+    }
+
+    /* Do we have room to store the character? */
+    if (idx >= name_dec_len) {
+      return -1;
+    }
+
+    /* Yes - store the character. */
+    ucname = cname;
+    name_dec[idx++] = ('A' + ((ucname >> 4) & 0x0F));
+    name_dec[idx++] = ('A' + ( ucname     & 0x0F));
+    pname++;
+  }
+
+  /* Fill with "space" coding */
+  for (; idx < name_dec_len - 1;) {
+    name_dec[idx++] = 'C';
+    name_dec[idx++] = 'A';
+  }
+
+  /* Terminate string */
+  name_dec[idx] = '\0';
+
+  return 0;
+}
+#endif /* 0 */
+
+/** NetBIOS Name service recv callback */
+static void
+netbiosns_recv(void *arg, struct udp_pcb *upcb, struct pbuf *p, const ip_addr_t *addr, u16_t port)
+{
+  LWIP_UNUSED_ARG(arg);
+
+  /* if packet is valid */
+  if (p != NULL) {
+    char   netbios_name[NETBIOS_NAME_LEN + 1];
+    struct netbios_hdr          *netbios_hdr          = (struct netbios_hdr *)p->payload;
+    struct netbios_question_hdr *netbios_question_hdr = (struct netbios_question_hdr *)(netbios_hdr + 1);
+
+    /* is the packet long enough (we need the header in one piece) */
+    if (p->len < (sizeof(struct netbios_hdr) + sizeof(struct netbios_question_hdr))) {
+      /* packet too short */
+      pbuf_free(p);
+      return;
+    }
+    /* we only answer if we got a default interface */
+    if (netif_default != NULL) {
+      /* @todo: do we need to check answerRRs/authorityRRs/additionalRRs? */
+      /* if the packet is a NetBIOS name query question */
+      if (((netbios_hdr->flags & PP_NTOHS(NETB_HFLAG_OPCODE)) == PP_NTOHS(NETB_HFLAG_OPCODE_NAME_QUERY)) &&
+          ((netbios_hdr->flags & PP_NTOHS(NETB_HFLAG_RESPONSE)) == 0) &&
+          (netbios_hdr->questions == PP_NTOHS(1))) {
+        /* decode the NetBIOS name */
+        netbiosns_name_decode((char *)(netbios_question_hdr->encname), netbios_name, sizeof(netbios_name));
+        /* check the request type */
+        if (netbios_question_hdr->type == PP_HTONS(NETB_QTYPE_NB)) {
+          /* if the packet is for us */
+          if (lwip_strnicmp(netbios_name, NETBIOS_LOCAL_NAME, sizeof(NETBIOS_LOCAL_NAME)) == 0) {
+            struct pbuf *q;
+            struct netbios_resp *resp;
+
+            q = pbuf_alloc(PBUF_TRANSPORT, sizeof(struct netbios_resp), PBUF_RAM);
+            if (q != NULL) {
+              resp = (struct netbios_resp *)q->payload;
+
+              /* prepare NetBIOS header response */
+              resp->resp_hdr.trans_id      = netbios_hdr->trans_id;
+              resp->resp_hdr.flags         = PP_HTONS(NETB_HFLAG_RESPONSE |
+                                                      NETB_HFLAG_OPCODE_NAME_QUERY |
+                                                      NETB_HFLAG_AUTHORATIVE |
+                                                      NETB_HFLAG_RECURS_DESIRED);
+              resp->resp_hdr.questions     = 0;
+              resp->resp_hdr.answerRRs     = PP_HTONS(1);
+              resp->resp_hdr.authorityRRs  = 0;
+              resp->resp_hdr.additionalRRs = 0;
+
+              /* prepare NetBIOS header datas */
+              MEMCPY( resp->resp_name.encname, netbios_question_hdr->encname, sizeof(netbios_question_hdr->encname));
+              resp->resp_name.nametype     = netbios_question_hdr->nametype;
+              resp->resp_name.type         = netbios_question_hdr->type;
+              resp->resp_name.cls          = netbios_question_hdr->cls;
+              {
+                uint32_t tty = PP_HTONL(NETBIOS_NAME_TTL);
+                MEMCPY(&resp->resp_name.ttl, &tty, 4);
+              }
+              resp->resp_name.datalen      = PP_HTONS(sizeof(resp->resp_name.flags) + sizeof(resp->resp_name.addr));
+              resp->resp_name.flags        = PP_HTONS(NETB_NFLAG_NODETYPE_BNODE);
+              ip4_addr_copy(resp->resp_name.addr, *netif_ip4_addr(netif_default));
+
+              /* send the NetBIOS response */
+              udp_sendto(upcb, q, addr, port);
+
+              /* free the "reference" pbuf */
+              pbuf_free(q);
+            }
+          }
+#if LWIP_NETBIOS_RESPOND_NAME_QUERY
+        } else if (netbios_question_hdr->type == PP_HTONS(NETB_QTYPE_NBSTAT)) {
+          /* if the packet is for us or general query */
+          if (!lwip_strnicmp(netbios_name, NETBIOS_LOCAL_NAME, sizeof(NETBIOS_LOCAL_NAME)) ||
+              !lwip_strnicmp(netbios_name, "*", sizeof(NETBIOS_LOCAL_NAME))) {
+            /* general query - ask for our IP address */
+            struct pbuf *q;
+            struct netbios_answer *resp;
+
+            q = pbuf_alloc(PBUF_TRANSPORT, sizeof(struct netbios_answer), PBUF_RAM);
+            if (q != NULL) {
+              /* buffer to which a response is compiled */
+              resp = (struct netbios_answer *) q->payload;
+
+              /* Init response to zero, especially the statistics fields */
+              memset(resp, 0, sizeof(*resp));
+
+              /* copy the query to the response ID */
+              resp->answer_hdr.trans_id        = netbios_hdr->trans_id;
+              /* acknowledgment of termination */
+              resp->answer_hdr.flags           = PP_HTONS(NETB_HFLAG_RESPONSE | NETB_HFLAG_OPCODE_NAME_QUERY | NETB_HFLAG_AUTHORATIVE);
+              /* resp->answer_hdr.questions       = PP_HTONS(0); done by memset() */
+              /* serial number of the answer */
+              resp->answer_hdr.answerRRs       = PP_HTONS(1);
+              /* resp->answer_hdr.authorityRRs    = PP_HTONS(0); done by memset() */
+              /* resp->answer_hdr.additionalRRs   = PP_HTONS(0); done by memset() */
+              /* we will copy the length of the station name */
+              resp->name_size                  = netbios_question_hdr->nametype;
+              /* we will copy the queried name */
+              MEMCPY(resp->query_name, netbios_question_hdr->encname, (NETBIOS_NAME_LEN * 2) + 1);
+              /* NBSTAT */
+              resp->packet_type                = PP_HTONS(0x21);
+              /* Internet name */
+              resp->cls                        = PP_HTONS(1);
+              /* resp->ttl                        = PP_HTONL(0); done by memset() */
+              resp->data_length                = PP_HTONS(sizeof(struct netbios_answer) - offsetof(struct netbios_answer, number_of_names));
+              resp->number_of_names            = 1;
+
+              /* make windows see us as workstation, not as a server */
+              memset(resp->answer_name, 0x20, NETBIOS_NAME_LEN - 1);
+              /* strlen is checked to be < NETBIOS_NAME_LEN during initialization */
+              MEMCPY(resp->answer_name, NETBIOS_LOCAL_NAME, strlen(NETBIOS_LOCAL_NAME));
+
+              /* b-node, unique, active */
+              resp->answer_name_flags          = PP_HTONS(NETB_NFLAG_NAME_IS_ACTIVE);
+
+              /* Set responder netif MAC address */
+              SMEMCPY(resp->unit_id, ip_current_input_netif()->hwaddr, sizeof(resp->unit_id));
+
+              udp_sendto(upcb, q, addr, port);
+              pbuf_free(q);
+            }
+          }
+#endif /* LWIP_NETBIOS_RESPOND_NAME_QUERY */
+        }
+      }
+    }
+    /* free the pbuf */
+    pbuf_free(p);
+  }
+}
+
+/**
+ * @ingroup netbiosns
+ * Init netbios responder
+ */
+void
+netbiosns_init(void)
+{
+  /* LWIP_ASSERT_CORE_LOCKED(); is checked by udp_new() */
+#ifdef NETBIOS_LWIP_NAME
+  LWIP_ASSERT("NetBIOS name is too long!", strlen(NETBIOS_LWIP_NAME) < NETBIOS_NAME_LEN);
+#endif
+
+  netbiosns_pcb = udp_new_ip_type(IPADDR_TYPE_ANY);
+  if (netbiosns_pcb != NULL) {
+    /* we have to be allowed to send broadcast packets! */
+    ip_set_option(netbiosns_pcb, SOF_BROADCAST);
+    udp_bind(netbiosns_pcb, IP_ANY_TYPE, LWIP_IANA_PORT_NETBIOS);
+    udp_recv(netbiosns_pcb, netbiosns_recv, netbiosns_pcb);
+  }
+}
+
+#ifndef NETBIOS_LWIP_NAME
+/**
+ * @ingroup netbiosns
+ * Set netbios name. ATTENTION: the hostname must be less than 15 characters!
+ *                              the NetBIOS name spec says the name MUST be upper case, so incoming name is forced into uppercase :-)
+ */
+void
+netbiosns_set_name(const char *hostname)
+{
+  size_t i;
+  size_t copy_len = strlen(hostname);
+  LWIP_ASSERT_CORE_LOCKED();
+  LWIP_ASSERT("NetBIOS name is too long!", copy_len < NETBIOS_NAME_LEN);
+  if (copy_len >= NETBIOS_NAME_LEN) {
+    copy_len = NETBIOS_NAME_LEN - 1;
+  }
+
+  /* make name into upper case */
+  for (i = 0; i < copy_len; i++ ) {
+    netbiosns_local_name[i] = (char)lwip_toupper(hostname[i]);
+  }
+  netbiosns_local_name[copy_len] = '\0';
+}
+#endif /* NETBIOS_LWIP_NAME */
+
+/**
+ * @ingroup netbiosns
+ * Stop netbios responder
+ */
+void
+netbiosns_stop(void)
+{
+  LWIP_ASSERT_CORE_LOCKED();
+  if (netbiosns_pcb != NULL) {
+    udp_remove(netbiosns_pcb);
+    netbiosns_pcb = NULL;
+  }
+}
+
+#endif /* LWIP_IPV4 && LWIP_UDP */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/apps/smtp/smtp.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/apps/smtp/smtp.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/apps/smtp/smtp.c	(revision 457)
@@ -0,0 +1,1555 @@
+/**
+ * @file
+ * SMTP client module
+ * 
+ * Author: Simon Goldschmidt
+ *
+ * @defgroup smtp SMTP client
+ * @ingroup apps
+ * 
+ * This is simple SMTP client for raw API.
+ * It is a minimal implementation of SMTP as specified in RFC 5321.
+ *
+ * Example usage:
+@code{.c}
+ void my_smtp_result_fn(void *arg, u8_t smtp_result, u16_t srv_err, err_t err)
+ {
+   printf("mail (%p) sent with results: 0x%02x, 0x%04x, 0x%08x\n", arg,
+          smtp_result, srv_err, err);
+ }
+ static void my_smtp_test(void)
+ {
+   smtp_set_server_addr("mymailserver.org");
+   -> set both username and password as NULL if no auth needed
+   smtp_set_auth("username", "password");
+   smtp_send_mail("sender", "recipient", "subject", "body", my_smtp_result_fn,
+                  some_argument);
+ }
+@endcode
+
+ * When using from any other thread than the tcpip_thread (for NO_SYS==0), use
+ * smtp_send_mail_int()!
+ * 
+ * SMTP_BODYDH usage:
+@code{.c}
+ int my_smtp_bodydh_fn(void *arg, struct smtp_bodydh *bdh)
+ {
+    if(bdh->state >= 10) {
+       return BDH_DONE;
+    }
+    sprintf(bdh->buffer,"Line #%2d\r\n",bdh->state);
+    bdh->length = strlen(bdh->buffer);
+    ++bdh->state;
+    return BDH_WORKING;
+ }
+ 
+ smtp_send_mail_bodycback("sender", "recipient", "subject", 
+                my_smtp_bodydh_fn, my_smtp_result_fn, some_argument);
+@endcode
+ * 
+ * @todo:
+ * - attachments (the main difficulty here is streaming base64-encoding to
+ *   prevent having to allocate a buffer for the whole encoded file at once)
+ * - test with more mail servers...
+ *
+ */
+
+#include "lwip/apps/smtp.h"
+
+#if LWIP_TCP && LWIP_CALLBACK_API
+#include "lwip/sys.h"
+#include "lwip/sockets.h"
+#include "lwip/altcp.h"
+#include "lwip/dns.h"
+#include "lwip/mem.h"
+#include "lwip/altcp_tcp.h"
+#include "lwip/altcp_tls.h"
+
+#include <string.h> /* strlen, memcpy */
+#include <stdlib.h>
+
+/** TCP poll interval. Unit is 0.5 sec. */
+#define SMTP_POLL_INTERVAL      4
+/** TCP poll timeout while sending message body, reset after every
+ * successful write. 3 minutes */
+#define SMTP_TIMEOUT_DATABLOCK  ( 3 * 60 * SMTP_POLL_INTERVAL / 2)
+/** TCP poll timeout while waiting for confirmation after sending the body.
+ * 10 minutes */
+#define SMTP_TIMEOUT_DATATERM   (10 * 60 * SMTP_POLL_INTERVAL / 2)
+/** TCP poll timeout while not sending the body.
+ * This is somewhat lower than the RFC states (5 minutes for initial, MAIL
+ * and RCPT) but still OK for us here.
+ * 2 minutes */
+#define SMTP_TIMEOUT            ( 2 * 60 * SMTP_POLL_INTERVAL / 2)
+
+/* the various debug levels for this file */
+#define SMTP_DEBUG_TRACE        (SMTP_DEBUG | LWIP_DBG_TRACE)
+#define SMTP_DEBUG_STATE        (SMTP_DEBUG | LWIP_DBG_STATE)
+#define SMTP_DEBUG_WARN         (SMTP_DEBUG | LWIP_DBG_LEVEL_WARNING)
+#define SMTP_DEBUG_WARN_STATE   (SMTP_DEBUG | LWIP_DBG_LEVEL_WARNING | LWIP_DBG_STATE)
+#define SMTP_DEBUG_SERIOUS      (SMTP_DEBUG | LWIP_DBG_LEVEL_SERIOUS)
+
+
+#define SMTP_RX_BUF_LEN         255
+#define SMTP_TX_BUF_LEN         255
+#define SMTP_CRLF               "\r\n"
+#define SMTP_CRLF_LEN           2
+
+#define SMTP_RESP_220           "220"
+#define SMTP_RESP_235           "235"
+#define SMTP_RESP_250           "250"
+#define SMTP_RESP_334           "334"
+#define SMTP_RESP_354           "354"
+#define SMTP_RESP_LOGIN_UNAME   "VXNlcm5hbWU6"
+#define SMTP_RESP_LOGIN_PASS    "UGFzc3dvcmQ6"
+
+#define SMTP_KEYWORD_AUTH_SP    "AUTH "
+#define SMTP_KEYWORD_AUTH_EQ    "AUTH="
+#define SMTP_KEYWORD_AUTH_LEN   5
+#define SMTP_AUTH_PARAM_PLAIN   "PLAIN"
+#define SMTP_AUTH_PARAM_LOGIN   "LOGIN"
+
+#define SMTP_CMD_EHLO_1           "EHLO ["
+#define SMTP_CMD_EHLO_1_LEN       6
+#define SMTP_CMD_EHLO_2           "]\r\n"
+#define SMTP_CMD_EHLO_2_LEN       3
+#define SMTP_CMD_AUTHPLAIN_1      "AUTH PLAIN "
+#define SMTP_CMD_AUTHPLAIN_1_LEN  11
+#define SMTP_CMD_AUTHPLAIN_2      "\r\n"
+#define SMTP_CMD_AUTHPLAIN_2_LEN  2
+#define SMTP_CMD_AUTHLOGIN        "AUTH LOGIN\r\n"
+#define SMTP_CMD_AUTHLOGIN_LEN    12
+#define SMTP_CMD_MAIL_1           "MAIL FROM: <"
+#define SMTP_CMD_MAIL_1_LEN       12
+#define SMTP_CMD_MAIL_2           ">\r\n"
+#define SMTP_CMD_MAIL_2_LEN       3
+#define SMTP_CMD_RCPT_1           "RCPT TO: <"
+#define SMTP_CMD_RCPT_1_LEN       10
+#define SMTP_CMD_RCPT_2           ">\r\n"
+#define SMTP_CMD_RCPT_2_LEN       3
+#define SMTP_CMD_DATA             "DATA\r\n"
+#define SMTP_CMD_DATA_LEN         6
+#define SMTP_CMD_HEADER_1         "From: <"
+#define SMTP_CMD_HEADER_1_LEN     7
+#define SMTP_CMD_HEADER_2         ">\r\nTo: <"
+#define SMTP_CMD_HEADER_2_LEN     8
+#define SMTP_CMD_HEADER_3         ">\r\nSubject: "
+#define SMTP_CMD_HEADER_3_LEN     12
+#define SMTP_CMD_HEADER_4         "\r\n\r\n"
+#define SMTP_CMD_HEADER_4_LEN     4
+#define SMTP_CMD_BODY_FINISHED    "\r\n.\r\n"
+#define SMTP_CMD_BODY_FINISHED_LEN 5
+#define SMTP_CMD_QUIT             "QUIT\r\n"
+#define SMTP_CMD_QUIT_LEN         6
+
+#if defined(SMTP_STAT_TX_BUF_MAX) && SMTP_STAT_TX_BUF_MAX
+#define SMTP_TX_BUF_MAX(len) LWIP_MACRO(if((len) > smtp_tx_buf_len_max) smtp_tx_buf_len_max = (len);)
+#else /* SMTP_STAT_TX_BUF_MAX */
+#define SMTP_TX_BUF_MAX(len)
+#endif /* SMTP_STAT_TX_BUF_MAX */
+
+#if SMTP_COPY_AUTHDATA
+#define SMTP_USERNAME(session)        (session)->username
+#define SMTP_PASS(session)            (session)->pass
+#define SMTP_AUTH_PLAIN_DATA(session) (session)->auth_plain
+#define SMTP_AUTH_PLAIN_LEN(session)  (session)->auth_plain_len
+#else /* SMTP_COPY_AUTHDATA */
+#define SMTP_USERNAME(session)        smtp_username
+#define SMTP_PASS(session)            smtp_pass
+#define SMTP_AUTH_PLAIN_DATA(session) smtp_auth_plain
+#define SMTP_AUTH_PLAIN_LEN(session)  smtp_auth_plain_len
+#endif /* SMTP_COPY_AUTHDATA */
+
+#if SMTP_BODYDH
+#ifndef SMTP_BODYDH_MALLOC
+#define SMTP_BODYDH_MALLOC(size)      mem_malloc(size)
+#define SMTP_BODYDH_FREE(ptr)         mem_free(ptr)
+#endif
+
+/* Some internal state return values */
+#define BDHALLDATASENT                2
+#define BDHSOMEDATASENT               1
+
+enum bdh_handler_state {
+  BDH_SENDING,         /* Serving the user function generating body content */
+  BDH_STOP             /* User function stopped, closing */
+};
+#endif
+
+/** State for SMTP client state machine */
+enum smtp_session_state {
+  SMTP_NULL,
+  SMTP_HELO,
+  SMTP_AUTH_PLAIN,
+  SMTP_AUTH_LOGIN_UNAME,
+  SMTP_AUTH_LOGIN_PASS,
+  SMTP_AUTH_LOGIN,
+  SMTP_MAIL,
+  SMTP_RCPT,
+  SMTP_DATA,
+  SMTP_BODY,
+  SMTP_QUIT,
+  SMTP_CLOSED
+};
+
+#ifdef LWIP_DEBUG
+/** State-to-string table for debugging */
+static const char *smtp_state_str[] = {
+  "SMTP_NULL",
+  "SMTP_HELO",
+  "SMTP_AUTH_PLAIN",
+  "SMTP_AUTH_LOGIN_UNAME",
+  "SMTP_AUTH_LOGIN_PASS",
+  "SMTP_AUTH_LOGIN",
+  "SMTP_MAIL",
+  "SMTP_RCPT",
+  "SMTP_DATA",
+  "SMTP_BODY",
+  "SMTP_QUIT",
+  "SMTP_CLOSED",
+};
+
+static const char *smtp_result_strs[] = {
+  "SMTP_RESULT_OK",
+  "SMTP_RESULT_ERR_UNKNOWN",
+  "SMTP_RESULT_ERR_CONNECT",
+  "SMTP_RESULT_ERR_HOSTNAME",
+  "SMTP_RESULT_ERR_CLOSED",
+  "SMTP_RESULT_ERR_TIMEOUT",
+  "SMTP_RESULT_ERR_SVR_RESP",
+  "SMTP_RESULT_ERR_MEM"
+};
+#endif /* LWIP_DEBUG */
+
+#if SMTP_BODYDH
+struct smtp_bodydh_state {
+  smtp_bodycback_fn callback_fn;  /* The function to call (again) */
+  u16_t state;
+  struct smtp_bodydh exposed;     /* the user function structure */
+};
+#endif /* SMTP_BODYDH */
+
+/** struct keeping the body and state of an smtp session */
+struct smtp_session {
+  /** keeping the state of the smtp session */
+  enum smtp_session_state state;
+  /** timeout handling, if this reaches 0, the connection is closed */
+  u16_t timer;
+  /** helper buffer for transmit, not used for sending body */
+  char tx_buf[SMTP_TX_BUF_LEN + 1];
+  struct pbuf* p;
+  /** source email address */
+  const char* from;
+  /** size of the sourceemail address */
+  u16_t from_len;
+  /** target email address */
+  const char* to;
+  /** size of the target email address */
+  u16_t to_len;
+  /** subject of the email */
+  const char *subject;
+  /** length of the subject string */
+  u16_t subject_len;
+  /** this is the body of the mail to be sent */
+  const char* body;
+  /** this is the length of the body to be sent */
+  u16_t body_len;
+  /** amount of data from body already sent */
+  u16_t body_sent;
+  /** callback function to call when closed */
+  smtp_result_fn callback_fn;
+  /** argument for callback function */
+  void *callback_arg;
+#if SMTP_COPY_AUTHDATA
+  /** Username to use for this request */
+  char *username;
+  /** Password to use for this request */
+  char *pass;
+  /** Username and password combined as necessary for PLAIN authentication */
+  char auth_plain[SMTP_MAX_USERNAME_LEN + SMTP_MAX_PASS_LEN + 3];
+  /** Length of smtp_auth_plain string (cannot use strlen since it includes \0) */
+  size_t auth_plain_len;
+#endif /* SMTP_COPY_AUTHDATA */
+#if SMTP_BODYDH
+  struct smtp_bodydh_state *bodydh;
+#endif /* SMTP_BODYDH */
+};
+
+/** IP address or DNS name of the server to use for next SMTP request */
+static char smtp_server[SMTP_MAX_SERVERNAME_LEN + 1];
+/** TCP port of the server to use for next SMTP request */
+static u16_t smtp_server_port = SMTP_DEFAULT_PORT;
+#if LWIP_ALTCP && LWIP_ALTCP_TLS
+/** If this is set, mail is sent using SMTPS */
+static struct altcp_tls_config *smtp_server_tls_config;
+#endif
+/** Username to use for the next SMTP request */
+static char *smtp_username;
+/** Password to use for the next SMTP request */
+static char *smtp_pass;
+/** Username and password combined as necessary for PLAIN authentication */
+static char smtp_auth_plain[SMTP_MAX_USERNAME_LEN + SMTP_MAX_PASS_LEN + 3];
+/** Length of smtp_auth_plain string (cannot use strlen since it includes \0) */
+static size_t smtp_auth_plain_len;
+
+#if SMTP_CHECK_DATA
+static err_t  smtp_verify(const char *data, size_t data_len, u8_t linebreaks_allowed);
+#endif /* SMTP_CHECK_DATA */
+static err_t  smtp_tcp_recv(void *arg, struct altcp_pcb *pcb, struct pbuf *p, err_t err);
+static void   smtp_tcp_err(void *arg, err_t err);
+static err_t  smtp_tcp_poll(void *arg, struct altcp_pcb *pcb);
+static err_t  smtp_tcp_sent(void *arg, struct altcp_pcb *pcb, u16_t len);
+static err_t  smtp_tcp_connected(void *arg, struct altcp_pcb *pcb, err_t err);
+#if LWIP_DNS
+static void   smtp_dns_found(const char* hostname, const ip_addr_t *ipaddr, void *arg);
+#endif /* LWIP_DNS */
+#if SMTP_SUPPORT_AUTH_PLAIN || SMTP_SUPPORT_AUTH_LOGIN
+static size_t smtp_base64_encode(char* target, size_t target_len, const char* source, size_t source_len);
+#endif /* SMTP_SUPPORT_AUTH_PLAIN || SMTP_SUPPORT_AUTH_LOGIN */
+static enum   smtp_session_state smtp_prepare_mail(struct smtp_session *s, u16_t *tx_buf_len);
+static void   smtp_send_body(struct smtp_session *s, struct altcp_pcb *pcb);
+static void   smtp_process(void *arg, struct altcp_pcb *pcb, struct pbuf *p);
+#if SMTP_BODYDH
+static void   smtp_send_body_data_handler(struct smtp_session *s, struct altcp_pcb *pcb);
+#endif /* SMTP_BODYDH */
+
+
+#ifdef LWIP_DEBUG
+/** Convert an smtp result to a string */
+const char*
+smtp_result_str(u8_t smtp_result)
+{
+  if (smtp_result >= LWIP_ARRAYSIZE(smtp_result_strs)) {
+    return "UNKNOWN";
+  }
+  return smtp_result_strs[smtp_result];
+}
+
+/** Null-terminates the payload of p for printing out messages.
+ * WARNING: use this only if p is not needed any more as the last byte of
+ *          payload is deleted!
+ */
+static const char*
+smtp_pbuf_str(struct pbuf* p)
+{
+  if ((p == NULL) || (p->len == 0)) {
+    return "";
+  }
+  ((char*)p->payload)[p->len] = 0;
+  return (const char*)p->payload;
+}
+#endif /* LWIP_DEBUG */
+
+/** @ingroup smtp
+ * Set IP address or DNS name for next SMTP connection
+ *
+ * @param server IP address (in ASCII representation) or DNS name of the server
+ */
+err_t
+smtp_set_server_addr(const char* server)
+{
+  size_t len = 0;
+
+  LWIP_ASSERT_CORE_LOCKED();
+
+  if (server != NULL) {
+    /* strlen: returns length WITHOUT terminating 0 byte */
+    len = strlen(server);
+  }
+  if (len > SMTP_MAX_SERVERNAME_LEN) {
+    return ERR_MEM;
+  }
+  if (len != 0) {
+    MEMCPY(smtp_server, server, len);
+  }
+  smtp_server[len] = 0; /* always OK because of smtp_server[SMTP_MAX_SERVERNAME_LEN + 1] */
+  return ERR_OK;
+}
+
+/** @ingroup smtp
+ * Set TCP port for next SMTP connection
+ *
+ * @param port TCP port
+ */
+void
+smtp_set_server_port(u16_t port)
+{
+  LWIP_ASSERT_CORE_LOCKED();
+  smtp_server_port = port;
+}
+
+#if LWIP_ALTCP && LWIP_ALTCP_TLS
+/** @ingroup smtp
+ * Set TLS configuration for next SMTP connection
+ *
+ * @param tls_config TLS configuration
+ */
+void
+smtp_set_tls_config(struct altcp_tls_config *tls_config)
+{
+  LWIP_ASSERT_CORE_LOCKED();
+  smtp_server_tls_config = tls_config;
+}
+#endif
+
+/** @ingroup smtp
+ * Set authentication parameters for next SMTP connection
+ *
+ * @param username login name as passed to the server
+ * @param pass password passed to the server together with username
+ */
+err_t
+smtp_set_auth(const char* username, const char* pass)
+{
+  size_t uname_len = 0;
+  size_t pass_len = 0;
+
+  LWIP_ASSERT_CORE_LOCKED();
+
+  memset(smtp_auth_plain, 0xfa, 64);
+  if (username != NULL) {
+    uname_len = strlen(username);
+    if (uname_len > SMTP_MAX_USERNAME_LEN) {
+      LWIP_DEBUGF(SMTP_DEBUG_SERIOUS, ("Username is too long, %d instead of %d\n",
+        (int)uname_len, SMTP_MAX_USERNAME_LEN));
+      return ERR_ARG;
+    }
+  }
+  if (pass != NULL) {
+#if SMTP_SUPPORT_AUTH_LOGIN || SMTP_SUPPORT_AUTH_PLAIN
+    pass_len = strlen(pass);
+    if (pass_len > SMTP_MAX_PASS_LEN) {
+      LWIP_DEBUGF(SMTP_DEBUG_SERIOUS, ("Password is too long, %d instead of %d\n",
+        (int)uname_len, SMTP_MAX_USERNAME_LEN));
+      return ERR_ARG;
+    }
+#else /* SMTP_SUPPORT_AUTH_LOGIN || SMTP_SUPPORT_AUTH_PLAIN */
+    LWIP_DEBUGF(SMTP_DEBUG_WARN, ("Password not supported as no authentication methods are activated\n"));
+#endif /* SMTP_SUPPORT_AUTH_LOGIN || SMTP_SUPPORT_AUTH_PLAIN */
+  }
+  *smtp_auth_plain = 0;
+  if (username != NULL) {
+    smtp_username = smtp_auth_plain + 1;
+    strcpy(smtp_username, username);
+  }
+  if (pass != NULL) {
+    smtp_pass = smtp_auth_plain + uname_len + 2;
+    strcpy(smtp_pass, pass);
+  }
+  smtp_auth_plain_len = uname_len + pass_len + 2;
+
+  return ERR_OK;
+}
+
+#if SMTP_BODYDH
+static void smtp_free_struct(struct smtp_session *s)
+{
+  if (s->bodydh != NULL) {
+    SMTP_BODYDH_FREE(s->bodydh);
+  }
+  SMTP_STATE_FREE(s);
+}
+#else /* SMTP_BODYDH */
+#define smtp_free_struct(x) SMTP_STATE_FREE(x)
+#endif /* SMTP_BODYDH */
+
+static struct altcp_pcb*
+smtp_setup_pcb(struct smtp_session *s, const ip_addr_t* remote_ip)
+{
+  struct altcp_pcb* pcb;
+  LWIP_UNUSED_ARG(remote_ip);
+
+#if LWIP_ALTCP && LWIP_ALTCP_TLS
+  if (smtp_server_tls_config) {
+    pcb = altcp_tls_new(smtp_server_tls_config, IP_GET_TYPE(remote_ip));
+  } else
+#endif
+  {
+    pcb = altcp_tcp_new_ip_type(IP_GET_TYPE(remote_ip));
+  }
+  if (pcb != NULL) {
+    altcp_arg(pcb, s);
+    altcp_recv(pcb, smtp_tcp_recv);
+    altcp_err(pcb, smtp_tcp_err);
+    altcp_poll(pcb, smtp_tcp_poll, SMTP_POLL_INTERVAL);
+    altcp_sent(pcb, smtp_tcp_sent);
+  }
+  return pcb;
+}
+
+/** The actual mail-sending function, called by smtp_send_mail and
+ * smtp_send_mail_static after setting up the struct smtp_session.
+ */
+static err_t
+smtp_send_mail_alloced(struct smtp_session *s)
+{
+  err_t err;
+  struct altcp_pcb* pcb = NULL;
+  ip_addr_t addr;
+
+  LWIP_ASSERT("no smtp_session supplied", s != NULL);
+
+#if SMTP_CHECK_DATA
+  /* check that body conforms to RFC:
+   * - convert all single-CR or -LF in body to CRLF
+   * - only 7-bit ASCII is allowed
+   */
+  if (smtp_verify(s->to, s->to_len, 0) != ERR_OK) {
+    err = ERR_ARG;
+    goto leave;
+  }
+  if (smtp_verify(s->from, s->from_len, 0) != ERR_OK) {
+    err = ERR_ARG;
+    goto leave;
+  }
+  if (smtp_verify(s->subject, s->subject_len, 0) != ERR_OK) {
+    err = ERR_ARG;
+    goto leave;
+  }
+#if SMTP_BODYDH
+  if (s->bodydh == NULL)
+#endif /* SMTP_BODYDH */
+  {
+    if (smtp_verify(s->body, s->body_len, 0) != ERR_OK) {
+      err = ERR_ARG;
+      goto leave;
+    }
+  }
+#endif /* SMTP_CHECK_DATA */
+
+#if SMTP_COPY_AUTHDATA
+  /* copy auth data, ensuring the first byte is always zero */
+  MEMCPY(s->auth_plain + 1, smtp_auth_plain + 1, smtp_auth_plain_len - 1);
+  s->auth_plain_len = smtp_auth_plain_len;
+  /* default username and pass is empty string */
+  s->username = s->auth_plain;
+  s->pass = s->auth_plain;
+  if (smtp_username != NULL) {
+    s->username += smtp_username - smtp_auth_plain;
+  }
+  if (smtp_pass != NULL) {
+    s->pass += smtp_pass - smtp_auth_plain;
+  }
+#endif /* SMTP_COPY_AUTHDATA */
+
+  s->state = SMTP_NULL;
+  s->timer = SMTP_TIMEOUT;
+
+#if LWIP_DNS
+  err = dns_gethostbyname(smtp_server, &addr, smtp_dns_found, s);
+#else /* LWIP_DNS */
+  err = ipaddr_aton(smtp_server, &addr) ? ERR_OK : ERR_ARG;
+#endif /* LWIP_DNS */
+  if (err == ERR_OK) {
+    pcb = smtp_setup_pcb(s, &addr);
+    if (pcb == NULL) {
+      err = ERR_MEM;
+      goto leave;
+    }
+    err = altcp_connect(pcb, &addr, smtp_server_port, smtp_tcp_connected);
+    if (err != ERR_OK) {
+      LWIP_DEBUGF(SMTP_DEBUG_WARN_STATE, ("tcp_connect failed: %d\n", (int)err));
+      goto deallocate_and_leave;
+    }
+  } else if (err != ERR_INPROGRESS) {
+    LWIP_DEBUGF(SMTP_DEBUG_WARN_STATE, ("dns_gethostbyname failed: %d\n", (int)err));
+    goto deallocate_and_leave;
+  }
+  return ERR_OK;
+
+deallocate_and_leave:
+  if (pcb != NULL) {
+    altcp_arg(pcb, NULL);
+    altcp_close(pcb);
+  }
+leave:
+  smtp_free_struct(s);
+  /* no need to call the callback here since we return != ERR_OK */
+  return err;
+}
+
+/** @ingroup smtp
+ *  Send an email via the currently selected server, username and password.
+ *
+ * @param from source email address (must be NULL-terminated)
+ * @param to target email address (must be NULL-terminated)
+ * @param subject email subject (must be NULL-terminated)
+ * @param body email body (must be NULL-terminated)
+ * @param callback_fn callback function
+ * @param callback_arg user argument to callback_fn
+ * @returns - ERR_OK if structures were allocated and no error occured starting the connection
+ *            (this does not mean the email has been successfully sent!)
+ *          - another err_t on error.
+ */
+err_t
+smtp_send_mail(const char* from, const char* to, const char* subject, const char* body,
+               smtp_result_fn callback_fn, void* callback_arg)
+{
+  struct smtp_session* s;
+  size_t from_len = strlen(from);
+  size_t to_len = strlen(to);
+  size_t subject_len = strlen(subject);
+  size_t body_len = strlen(body);
+  size_t mem_len = sizeof(struct smtp_session);
+  char *sfrom, *sto, *ssubject, *sbody;
+
+  LWIP_ASSERT_CORE_LOCKED();
+
+  mem_len += from_len + to_len + subject_len + body_len + 4;
+  if (mem_len > 0xffff) {
+    /* too long! */
+    return ERR_MEM;
+  }
+
+  /* Allocate memory to keep this email's session state */
+  s = (struct smtp_session *)SMTP_STATE_MALLOC((mem_size_t)mem_len);
+  if (s == NULL) {
+    return ERR_MEM;
+  }
+  /* initialize the structure */
+  memset(s, 0, mem_len);
+  s->from = sfrom = (char*)s + sizeof(struct smtp_session);
+  s->from_len = (u16_t)from_len;
+  s->to = sto = sfrom + from_len + 1;
+  s->to_len = (u16_t)to_len;
+  s->subject = ssubject = sto + to_len + 1;
+  s->subject_len = (u16_t)subject_len;
+  s->body = sbody = ssubject + subject_len + 1;
+  s->body_len = (u16_t)body_len;
+  /* copy source and target email address */
+  /* cast to size_t is a hack to cast away constness */
+  MEMCPY(sfrom, from, from_len + 1);
+  MEMCPY(sto, to, to_len + 1);
+  MEMCPY(ssubject, subject, subject_len + 1);
+  MEMCPY(sbody, body, body_len + 1);
+
+  s->callback_fn = callback_fn;
+  s->callback_arg = callback_arg;
+
+  /* call the actual implementation of this function */
+  return smtp_send_mail_alloced(s);
+}
+
+/** @ingroup smtp
+ * Same as smtp_send_mail, but doesn't copy from, to, subject and body into
+ * an internal buffer to save memory.
+ * WARNING: the above data must stay untouched until the callback function is
+ *          called (unless the function returns != ERR_OK)
+ */
+err_t
+smtp_send_mail_static(const char *from, const char* to, const char* subject,
+  const char* body, smtp_result_fn callback_fn, void* callback_arg)
+{
+  struct smtp_session* s;
+  size_t len;
+
+  LWIP_ASSERT_CORE_LOCKED();
+
+  s = (struct smtp_session*)SMTP_STATE_MALLOC(sizeof(struct smtp_session));
+  if (s == NULL) {
+    return ERR_MEM;
+  }
+  memset(s, 0, sizeof(struct smtp_session));
+  /* initialize the structure */
+  s->from = from;
+  len = strlen(from);
+  LWIP_ASSERT("string is too long", len <= 0xffff);
+  s->from_len = (u16_t)len;
+  s->to = to;
+  len = strlen(to);
+  LWIP_ASSERT("string is too long", len <= 0xffff);
+  s->to_len = (u16_t)len;
+  s->subject = subject;
+  len = strlen(subject);
+  LWIP_ASSERT("string is too long", len <= 0xffff);
+  s->subject_len = (u16_t)len;
+  s->body = body;
+  len = strlen(body);
+  LWIP_ASSERT("string is too long", len <= 0xffff);
+  s->body_len = (u16_t)len;
+  s->callback_fn = callback_fn;
+  s->callback_arg = callback_arg;
+  /* call the actual implementation of this function */
+  return smtp_send_mail_alloced(s);
+}
+
+
+/** @ingroup smtp
+ * Same as smtp_send_mail but takes a struct smtp_send_request as single
+ * parameter which contains all the other parameters.
+ * To be used with tcpip_callback to send mail from interrupt context or from
+ * another thread.
+ *
+ * WARNING: server and authentication must stay untouched until this function has run!
+ *
+ * Usage example:
+ * - allocate a struct smtp_send_request (in a way that is allowed in interrupt context)
+ * - fill the members of the struct as if calling smtp_send_mail
+ * - specify a callback_function
+ * - set callback_arg to the structure itself
+ * - call this function
+ * - wait for the callback function to be called
+ * - in the callback function, deallocate the structure (passed as arg)
+ */
+void
+smtp_send_mail_int(void *arg)
+{
+  struct smtp_send_request *req = (struct smtp_send_request*)arg;
+  err_t err;
+
+  LWIP_ASSERT_CORE_LOCKED();
+  LWIP_ASSERT("smtp_send_mail_int: no argument given", arg != NULL);
+
+  if (req->static_data) {
+    err = smtp_send_mail_static(req->from, req->to, req->subject, req->body,
+      req->callback_fn, req->callback_arg);
+  } else {
+    err = smtp_send_mail(req->from, req->to, req->subject, req->body,
+      req->callback_fn, req->callback_arg);
+  }
+  if ((err != ERR_OK) && (req->callback_fn != NULL)) {
+    req->callback_fn(req->callback_arg, SMTP_RESULT_ERR_UNKNOWN, 0, err);
+  }
+}
+
+#if SMTP_CHECK_DATA
+/** Verify that a given string conforms to the SMTP rules
+ * (7-bit only, no single CR or LF,
+ *  @todo: no line consisting of a single dot only)
+ */
+static err_t
+smtp_verify(const char *data, size_t data_len, u8_t linebreaks_allowed)
+{
+  size_t i;
+  u8_t last_was_cr = 0;
+  for (i = 0; i < data_len; i++) {
+    char current = data[i];
+    if ((current & 0x80) != 0) {
+      LWIP_DEBUGF(SMTP_DEBUG_WARN, ("smtp_verify: no 8-bit data supported: %s\n", data));
+      return ERR_ARG;
+    }
+    if (current == '\r') {
+      if (!linebreaks_allowed) {
+        LWIP_DEBUGF(SMTP_DEBUG_WARN, ("smtp_verify: found CR where no linebreaks allowed: %s\n", data));
+        return ERR_ARG;
+      }
+      if (last_was_cr) {
+        LWIP_DEBUGF(SMTP_DEBUG_WARN, ("smtp_verify: found double CR: %s\n", data));
+        return ERR_ARG;
+      }
+      last_was_cr = 1;
+    } else {
+      if (current == '\n') {
+        if (!last_was_cr) {
+          LWIP_DEBUGF(SMTP_DEBUG_WARN, ("smtp_verify: found LF without CR before: %s\n", data));
+          return ERR_ARG;
+        }
+      }
+      last_was_cr = 0;
+    }
+  }
+  return ERR_OK;
+}
+#endif /* SMTP_CHECK_DATA */
+
+/** Frees the smtp_session and calls the callback function */
+static void
+smtp_free(struct smtp_session *s, u8_t result, u16_t srv_err, err_t err)
+{
+  smtp_result_fn fn = s->callback_fn;
+  void *arg = s->callback_arg;
+  if (s->p != NULL) {
+    pbuf_free(s->p);
+  }
+  smtp_free_struct(s);
+  if (fn != NULL) {
+    fn(arg, result, srv_err, err);
+  }
+}
+
+/** Try to close a pcb and free the arg if successful */
+static void
+smtp_close(struct smtp_session *s, struct altcp_pcb *pcb, u8_t result,
+           u16_t srv_err, err_t err)
+{
+  if (pcb != NULL) {
+     altcp_arg(pcb, NULL);
+     if (altcp_close(pcb) == ERR_OK) {
+       if (s != NULL) {
+         smtp_free(s, result, srv_err, err);
+       }
+     } else {
+       /* close failed, set back arg */
+       altcp_arg(pcb, s);
+     }
+  } else {
+    if (s != NULL) {
+      smtp_free(s, result, srv_err, err);
+    }
+  }
+}
+
+/** Raw API TCP err callback: pcb is already deallocated */
+static void
+smtp_tcp_err(void *arg, err_t err)
+{
+  LWIP_UNUSED_ARG(err);
+  if (arg != NULL) {
+    LWIP_DEBUGF(SMTP_DEBUG_WARN_STATE, ("smtp_tcp_err: connection reset by remote host\n"));
+    smtp_free((struct smtp_session*)arg, SMTP_RESULT_ERR_CLOSED, 0, err);
+  }
+}
+
+/** Raw API TCP poll callback */
+static err_t
+smtp_tcp_poll(void *arg, struct altcp_pcb *pcb)
+{
+  if (arg != NULL) {
+    struct smtp_session *s = (struct smtp_session*)arg;
+    if (s->timer != 0) {
+      s->timer--;
+    }
+  }
+  smtp_process(arg, pcb, NULL);
+  return ERR_OK;
+}
+
+/** Raw API TCP sent callback */
+static err_t
+smtp_tcp_sent(void *arg, struct altcp_pcb *pcb, u16_t len)
+{
+  LWIP_UNUSED_ARG(len);
+
+  smtp_process(arg, pcb, NULL);
+
+  return ERR_OK;
+}
+
+/** Raw API TCP recv callback */
+static err_t
+smtp_tcp_recv(void *arg, struct altcp_pcb *pcb, struct pbuf *p, err_t err)
+{
+  LWIP_UNUSED_ARG(err);
+  if (p != NULL) {
+    altcp_recved(pcb, p->tot_len);
+    smtp_process(arg, pcb, p);
+  } else {
+    LWIP_DEBUGF(SMTP_DEBUG_WARN_STATE, ("smtp_tcp_recv: connection closed by remote host\n"));
+    smtp_close((struct smtp_session*)arg, pcb, SMTP_RESULT_ERR_CLOSED, 0, err);
+  }
+  return ERR_OK;
+}
+
+static err_t
+smtp_tcp_connected(void *arg, struct altcp_pcb *pcb, err_t err)
+{
+  LWIP_UNUSED_ARG(arg);
+
+  if (err == ERR_OK) {
+    LWIP_DEBUGF(SMTP_DEBUG_STATE, ("smtp_connected: Waiting for 220\n"));
+  } else {
+    /* shouldn't happen, but we still check 'err', only to be sure */
+    LWIP_DEBUGF(SMTP_DEBUG_WARN, ("smtp_connected: %d\n", (int)err));
+    smtp_close((struct smtp_session*)arg, pcb, SMTP_RESULT_ERR_CONNECT, 0, err);
+  }
+  return ERR_OK;
+}
+
+#if LWIP_DNS
+/** DNS callback
+ * If ipaddr is non-NULL, resolving succeeded, otherwise it failed.
+ */
+static void
+smtp_dns_found(const char* hostname, const ip_addr_t *ipaddr, void *arg)
+{
+  struct smtp_session *s = (struct smtp_session*)arg;
+  struct altcp_pcb *pcb;
+  err_t err;
+  u8_t result;
+
+  LWIP_UNUSED_ARG(hostname);
+
+  if (ipaddr != NULL) {
+    pcb = smtp_setup_pcb(s, ipaddr);
+    if (pcb != NULL) {
+      LWIP_DEBUGF(SMTP_DEBUG_STATE, ("smtp_dns_found: hostname resolved, connecting\n"));
+      err = altcp_connect(pcb, ipaddr, smtp_server_port, smtp_tcp_connected);
+      if (err == ERR_OK) {
+        return;
+      }
+      LWIP_DEBUGF(SMTP_DEBUG_WARN_STATE, ("tcp_connect failed: %d\n", (int)err));
+      result = SMTP_RESULT_ERR_CONNECT;
+    } else {
+      LWIP_DEBUGF(SMTP_DEBUG_STATE, ("smtp_dns_found: failed to allocate tcp pcb\n"));
+      result = SMTP_RESULT_ERR_MEM;
+      err = ERR_MEM;
+    }
+  } else {
+    LWIP_DEBUGF(SMTP_DEBUG_WARN_STATE, ("smtp_dns_found: failed to resolve hostname: %s\n",
+      hostname));
+    pcb = NULL;
+    result = SMTP_RESULT_ERR_HOSTNAME;
+    err = ERR_ARG;
+  }
+  smtp_close(s, pcb, result, 0, err);
+}
+#endif /* LWIP_DNS */
+
+#if SMTP_SUPPORT_AUTH_PLAIN || SMTP_SUPPORT_AUTH_LOGIN
+
+/** Table 6-bit-index-to-ASCII used for base64-encoding */
+static const char base64_table[] = {
+  'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H',
+  'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
+  'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
+  'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h',
+  'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p',
+  'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
+  '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
+  '+', '/'
+};
+
+/** Base64 encoding */
+static size_t
+smtp_base64_encode(char* target, size_t target_len, const char* source, size_t source_len)
+{
+  size_t i;
+  s8_t j;
+  size_t target_idx = 0;
+  size_t longer = (source_len % 3) ? (3 - (source_len % 3)) : 0;
+  size_t source_len_b64 = source_len + longer;
+  size_t len = (((source_len_b64) * 4) / 3);
+  u8_t x = 5;
+  u8_t current = 0;
+  LWIP_UNUSED_ARG(target_len);
+
+  LWIP_ASSERT("target_len is too short", target_len >= len);
+
+  for (i = 0; i < source_len_b64; i++) {
+    u8_t b = (i < source_len ? (u8_t)source[i] : 0);
+    for (j = 7; j >= 0; j--, x--) {
+      if ((b & (1 << j)) != 0) {
+        current = (u8_t)(current | (1U << x));
+      }
+      if (x == 0) {
+        target[target_idx++] = base64_table[current];
+        x = 6;
+        current = 0;
+      }
+    }
+  }
+  for (i = len - longer; i < len; i++) {
+    target[i] = '=';
+  }
+  return len;
+}
+#endif /* SMTP_SUPPORT_AUTH_PLAIN || SMTP_SUPPORT_AUTH_LOGIN */
+
+/** Parse pbuf to see if it contains the beginning of an answer.
+ * If so, it returns the contained response code as number between 1 and 999.
+ * If not, zero is returned.
+ *
+ * @param s smtp session struct
+ */
+static u16_t
+smtp_is_response(struct smtp_session *s)
+{
+  char digits[4];
+  long num;
+
+  if (s->p == NULL) {
+    return 0;
+  }
+  /* copy three digits and convert them to int */
+  if (pbuf_copy_partial(s->p, digits, 3, 0) != 3) {
+    /* pbuf was too short */
+    return 0;
+  }
+  digits[3] = 0;
+  num = strtol(digits, NULL, 10);
+  if ((num <= 0) || (num >= 1000)) {
+    /* failed to find response code at start of line */
+    return 0;
+  }
+  return (u16_t)num;
+}
+
+/** Parse pbuf to see if it contains a fully received answer.
+ * If one is found, ERR_OK is returned.
+ * If none is found, ERR_VAL is returned.
+ *
+ * A fully received answer is a 3-digit number followed by a space,
+ * some string and a CRLF as line ending.
+ *
+ * @param s smtp session struct
+ */
+static err_t
+smtp_is_response_finished(struct smtp_session *s)
+{
+  u8_t sp;
+  u16_t crlf;
+  u16_t offset;
+
+  if (s->p == NULL) {
+    return ERR_VAL;
+  }
+  offset = 0;
+again:
+  /* We could check the response number here, but we trust the
+   * protocol definition which says the client can rely on it being
+   * the same on every line. */
+
+  /* find CRLF */
+  if (offset > 0xFFFF - 4) {
+    /* would overflow */
+    return ERR_VAL;
+  }
+  crlf = pbuf_memfind(s->p, SMTP_CRLF, SMTP_CRLF_LEN, (u16_t)(offset + 4));
+  if (crlf == 0xFFFF) {
+    /* no CRLF found */
+    return ERR_VAL;
+  }
+  sp = pbuf_get_at(s->p, (u16_t)(offset + 3));
+  if (sp == '-') {
+    /* no space after response code -> try next line */
+    offset = (u16_t)(crlf + 2);
+    if (offset < crlf) {
+      /* overflow */
+      return ERR_VAL;
+    }
+    goto again;
+  } else if (sp == ' ') {
+    /* CRLF found after response code + space -> valid response */
+    return ERR_OK;
+  }
+  /* sp contains invalid character */
+  return ERR_VAL;
+}
+
+/** Prepare HELO/EHLO message */
+static enum smtp_session_state
+smtp_prepare_helo(struct smtp_session *s, u16_t *tx_buf_len, struct altcp_pcb *pcb)
+{
+  size_t ipa_len;
+  const char *ipa = ipaddr_ntoa(altcp_get_ip(pcb, 1));
+  LWIP_ASSERT("ipaddr_ntoa returned NULL", ipa != NULL);
+  ipa_len = strlen(ipa);
+  LWIP_ASSERT("string too long", ipa_len <= (SMTP_TX_BUF_LEN-SMTP_CMD_EHLO_1_LEN-SMTP_CMD_EHLO_2_LEN));
+
+  *tx_buf_len = (u16_t)(SMTP_CMD_EHLO_1_LEN + (u16_t)ipa_len + SMTP_CMD_EHLO_2_LEN);
+  LWIP_ASSERT("tx_buf overflow detected", *tx_buf_len <= SMTP_TX_BUF_LEN);
+
+  SMEMCPY(s->tx_buf, SMTP_CMD_EHLO_1, SMTP_CMD_EHLO_1_LEN);
+  MEMCPY(&s->tx_buf[SMTP_CMD_EHLO_1_LEN], ipa, ipa_len);
+  SMEMCPY(&s->tx_buf[SMTP_CMD_EHLO_1_LEN + ipa_len], SMTP_CMD_EHLO_2, SMTP_CMD_EHLO_2_LEN);
+  return SMTP_HELO;
+}
+
+#if SMTP_SUPPORT_AUTH_PLAIN || SMTP_SUPPORT_AUTH_LOGIN
+/** Parse last server response (in rx_buf) for supported authentication method,
+ * create data to send out (to tx_buf), set tx_data_len correctly
+ * and return the next state.
+ */
+static enum smtp_session_state
+smtp_prepare_auth_or_mail(struct smtp_session *s, u16_t *tx_buf_len)
+{
+  /* check response for supported authentication method */
+  u16_t auth = pbuf_strstr(s->p, SMTP_KEYWORD_AUTH_SP);
+  if (auth == 0xFFFF) {
+    auth = pbuf_strstr(s->p, SMTP_KEYWORD_AUTH_EQ);
+  }
+  if (auth != 0xFFFF) {
+    u16_t crlf = pbuf_memfind(s->p, SMTP_CRLF, SMTP_CRLF_LEN, auth);
+    if ((crlf != 0xFFFF) && (crlf > auth)) {
+      /* use tx_buf temporarily */
+      u16_t copied = pbuf_copy_partial(s->p, s->tx_buf, (u16_t)(crlf - auth), auth);
+      if (copied != 0) {
+        char *sep = s->tx_buf + SMTP_KEYWORD_AUTH_LEN;
+        s->tx_buf[copied] = 0;
+#if SMTP_SUPPORT_AUTH_PLAIN
+        /* favour PLAIN over LOGIN since it involves less requests */
+        if (strstr(sep, SMTP_AUTH_PARAM_PLAIN) != NULL) {
+          size_t auth_len;
+          /* server supports AUTH PLAIN */
+          SMEMCPY(s->tx_buf, SMTP_CMD_AUTHPLAIN_1, SMTP_CMD_AUTHPLAIN_1_LEN);
+
+          /* add base64-encoded string "\0username\0password" */
+          auth_len = smtp_base64_encode(&s->tx_buf[SMTP_CMD_AUTHPLAIN_1_LEN],
+            SMTP_TX_BUF_LEN - SMTP_CMD_AUTHPLAIN_1_LEN, SMTP_AUTH_PLAIN_DATA(s),
+            SMTP_AUTH_PLAIN_LEN(s));
+          LWIP_ASSERT("string too long", auth_len <= (SMTP_TX_BUF_LEN-SMTP_CMD_AUTHPLAIN_1_LEN-SMTP_CMD_AUTHPLAIN_2_LEN));
+          *tx_buf_len = (u16_t)(SMTP_CMD_AUTHPLAIN_1_LEN + SMTP_CMD_AUTHPLAIN_2_LEN + (u16_t)auth_len);
+          SMEMCPY(&s->tx_buf[SMTP_CMD_AUTHPLAIN_1_LEN + auth_len], SMTP_CMD_AUTHPLAIN_2,
+            SMTP_CMD_AUTHPLAIN_2_LEN);
+          return SMTP_AUTH_PLAIN;
+        } else
+#endif /* SMTP_SUPPORT_AUTH_PLAIN */
+        {
+#if SMTP_SUPPORT_AUTH_LOGIN
+          if (strstr(sep, SMTP_AUTH_PARAM_LOGIN) != NULL) {
+            /* server supports AUTH LOGIN */
+            *tx_buf_len = SMTP_CMD_AUTHLOGIN_LEN;
+            SMEMCPY(s->tx_buf, SMTP_CMD_AUTHLOGIN, SMTP_CMD_AUTHLOGIN_LEN);
+            return SMTP_AUTH_LOGIN_UNAME;
+          }
+#endif /* SMTP_SUPPORT_AUTH_LOGIN */
+        }
+      }
+    }
+  }
+  /* server didnt's send correct keywords for AUTH, try sending directly */
+  return smtp_prepare_mail(s, tx_buf_len);
+}
+#endif /* SMTP_SUPPORT_AUTH_PLAIN || SMTP_SUPPORT_AUTH_LOGIN */
+
+#if SMTP_SUPPORT_AUTH_LOGIN
+/** Send base64-encoded username */
+static enum smtp_session_state
+smtp_prepare_auth_login_uname(struct smtp_session *s, u16_t *tx_buf_len)
+{
+  size_t base64_len = smtp_base64_encode(s->tx_buf, SMTP_TX_BUF_LEN,
+    SMTP_USERNAME(s), strlen(SMTP_USERNAME(s)));
+  /* @todo: support base64-encoded longer than 64k */
+  LWIP_ASSERT("string too long", base64_len <= 0xffff);
+  LWIP_ASSERT("tx_buf overflow detected", base64_len <= SMTP_TX_BUF_LEN - SMTP_CRLF_LEN);
+  *tx_buf_len = (u16_t)(base64_len + SMTP_CRLF_LEN);
+
+  SMEMCPY(&s->tx_buf[base64_len], SMTP_CRLF, SMTP_CRLF_LEN);
+  s->tx_buf[*tx_buf_len] = 0;
+  return SMTP_AUTH_LOGIN_PASS;
+}
+
+/** Send base64-encoded password */
+static enum smtp_session_state
+smtp_prepare_auth_login_pass(struct smtp_session *s, u16_t *tx_buf_len)
+{
+  size_t base64_len = smtp_base64_encode(s->tx_buf, SMTP_TX_BUF_LEN,
+    SMTP_PASS(s), strlen(SMTP_PASS(s)));
+  /* @todo: support base64-encoded longer than 64k */
+  LWIP_ASSERT("string too long", base64_len <= 0xffff);
+  LWIP_ASSERT("tx_buf overflow detected", base64_len <= SMTP_TX_BUF_LEN - SMTP_CRLF_LEN);
+  *tx_buf_len = (u16_t)(base64_len + SMTP_CRLF_LEN);
+
+  SMEMCPY(&s->tx_buf[base64_len], SMTP_CRLF, SMTP_CRLF_LEN);
+  s->tx_buf[*tx_buf_len] = 0;
+  return SMTP_AUTH_LOGIN;
+}
+#endif /* SMTP_SUPPORT_AUTH_LOGIN */
+
+/** Prepare MAIL message */
+static enum smtp_session_state
+smtp_prepare_mail(struct smtp_session *s, u16_t *tx_buf_len)
+{
+  char *target = s->tx_buf;
+  LWIP_ASSERT("tx_buf overflow detected", s->from_len <= (SMTP_TX_BUF_LEN - SMTP_CMD_MAIL_1_LEN - SMTP_CMD_MAIL_2_LEN));
+  *tx_buf_len = (u16_t)(SMTP_CMD_MAIL_1_LEN + SMTP_CMD_MAIL_2_LEN + s->from_len);
+  target[*tx_buf_len] = 0;
+
+  SMEMCPY(target, SMTP_CMD_MAIL_1, SMTP_CMD_MAIL_1_LEN);
+  target += SMTP_CMD_MAIL_1_LEN;
+  MEMCPY(target, s->from, s->from_len);
+  target += s->from_len;
+  SMEMCPY(target, SMTP_CMD_MAIL_2, SMTP_CMD_MAIL_2_LEN);
+  return SMTP_MAIL;
+}
+
+/** Prepare RCPT message */
+static enum smtp_session_state
+smtp_prepare_rcpt(struct smtp_session *s, u16_t *tx_buf_len)
+{
+  char *target = s->tx_buf;
+  LWIP_ASSERT("tx_buf overflow detected", s->to_len <= (SMTP_TX_BUF_LEN - SMTP_CMD_RCPT_1_LEN - SMTP_CMD_RCPT_2_LEN));
+  *tx_buf_len = (u16_t)(SMTP_CMD_RCPT_1_LEN + SMTP_CMD_RCPT_2_LEN + s->to_len);
+  target[*tx_buf_len] = 0;
+
+  SMEMCPY(target, SMTP_CMD_RCPT_1, SMTP_CMD_RCPT_1_LEN);
+  target += SMTP_CMD_RCPT_1_LEN;
+  MEMCPY(target, s->to, s->to_len);
+  target += s->to_len;
+  SMEMCPY(target, SMTP_CMD_RCPT_2, SMTP_CMD_RCPT_2_LEN);
+  return SMTP_RCPT;
+}
+
+/** Prepare header of body */
+static enum smtp_session_state
+smtp_prepare_header(struct smtp_session *s, u16_t *tx_buf_len)
+{
+  char *target = s->tx_buf;
+  int len = SMTP_CMD_HEADER_1_LEN + SMTP_CMD_HEADER_2_LEN +
+    SMTP_CMD_HEADER_3_LEN + SMTP_CMD_HEADER_4_LEN + s->from_len + s->to_len +
+    s->subject_len;
+  LWIP_ASSERT("tx_buf overflow detected", len > 0 && len <= SMTP_TX_BUF_LEN);
+  *tx_buf_len = (u16_t)len;
+  target[*tx_buf_len] = 0;
+
+  SMEMCPY(target, SMTP_CMD_HEADER_1, SMTP_CMD_HEADER_1_LEN);
+  target += SMTP_CMD_HEADER_1_LEN;
+  MEMCPY(target, s->from, s->from_len);
+  target += s->from_len;
+  SMEMCPY(target, SMTP_CMD_HEADER_2, SMTP_CMD_HEADER_2_LEN);
+  target += SMTP_CMD_HEADER_2_LEN;
+  MEMCPY(target, s->to, s->to_len);
+  target += s->to_len;
+  SMEMCPY(target, SMTP_CMD_HEADER_3, SMTP_CMD_HEADER_3_LEN);
+  target += SMTP_CMD_HEADER_3_LEN;
+  MEMCPY(target, s->subject, s->subject_len);
+  target += s->subject_len;
+  SMEMCPY(target, SMTP_CMD_HEADER_4, SMTP_CMD_HEADER_4_LEN);
+
+  return SMTP_BODY;
+}
+
+/** Prepare QUIT message */
+static enum smtp_session_state
+smtp_prepare_quit(struct smtp_session *s, u16_t *tx_buf_len)
+{
+  *tx_buf_len = SMTP_CMD_QUIT_LEN;
+  s->tx_buf[*tx_buf_len] = 0;
+  SMEMCPY(s->tx_buf, SMTP_CMD_QUIT, SMTP_CMD_QUIT_LEN);
+  LWIP_ASSERT("tx_buf overflow detected", *tx_buf_len <= SMTP_TX_BUF_LEN);
+  return SMTP_CLOSED;
+}
+
+/** If in state SMTP_BODY, try to send more body data */
+static void
+smtp_send_body(struct smtp_session *s, struct altcp_pcb *pcb)
+{
+  err_t err;
+
+  if (s->state == SMTP_BODY) {
+#if SMTP_BODYDH
+    if (s->bodydh) {
+      smtp_send_body_data_handler(s, pcb);
+    } else
+#endif /* SMTP_BODYDH */
+    {
+      u16_t send_len = (u16_t)(s->body_len - s->body_sent);
+      if (send_len > 0) {
+        u16_t snd_buf = altcp_sndbuf(pcb);
+        if (send_len > snd_buf) {
+          send_len = snd_buf;
+        }
+        if (send_len > 0) {
+          /* try to send something out */
+          err = altcp_write(pcb, &s->body[s->body_sent], (u16_t)send_len, TCP_WRITE_FLAG_COPY);
+          if (err == ERR_OK) {
+            s->timer = SMTP_TIMEOUT_DATABLOCK;
+            s->body_sent = (u16_t)(s->body_sent + send_len);
+            if (s->body_sent < s->body_len) {
+              LWIP_DEBUGF(SMTP_DEBUG_STATE, ("smtp_send_body: %d of %d bytes written\n",
+                s->body_sent, s->body_len));
+            }
+          }
+        }
+      }
+    }
+    if (s->body_sent == s->body_len) {
+      /* the whole body has been written, write last line */
+      LWIP_DEBUGF(SMTP_DEBUG_STATE, ("smtp_send_body: body completely written (%d bytes), appending end-of-body\n",
+        s->body_len));
+      err = altcp_write(pcb, SMTP_CMD_BODY_FINISHED, SMTP_CMD_BODY_FINISHED_LEN, 0);
+      if (err == ERR_OK) {
+        s->timer = SMTP_TIMEOUT_DATATERM;
+        LWIP_DEBUGF(SMTP_DEBUG_STATE, ("smtp_send_body: end-of-body written, changing state to %s\n",
+          smtp_state_str[SMTP_QUIT]));
+        /* last line written, change state, wait for confirmation */
+        s->state = SMTP_QUIT;
+      }
+    }
+  }
+}
+
+/** State machine-like implementation of an SMTP client.
+ */
+static void
+smtp_process(void *arg, struct altcp_pcb *pcb, struct pbuf *p)
+{
+  struct smtp_session* s = (struct smtp_session*)arg;
+  u16_t response_code = 0;
+  u16_t tx_buf_len = 0;
+  enum smtp_session_state next_state;
+
+  if (arg == NULL) {
+    /* already closed SMTP connection */
+    if (p != NULL) {
+      LWIP_DEBUGF(SMTP_DEBUG_TRACE, ("Received %d bytes after closing: %s\n",
+        p->tot_len, smtp_pbuf_str(p)));
+      pbuf_free(p);
+    }
+    return;
+  }
+
+  next_state = s->state;
+
+  if (p != NULL) {
+    /* received data */
+    if (s->p == NULL) {
+      s->p = p;
+    } else {
+      pbuf_cat(s->p, p);
+    }
+  } else {
+    /* idle timer, close connection if timed out */
+    if (s->timer == 0) {
+      LWIP_DEBUGF(SMTP_DEBUG_WARN_STATE, ("smtp_process: connection timed out, closing\n"));
+      smtp_close(s, pcb, SMTP_RESULT_ERR_TIMEOUT, 0, ERR_TIMEOUT);
+      return;
+    }
+    if (s->state == SMTP_BODY) {
+      smtp_send_body(s, pcb);
+      return;
+    }
+  }
+  response_code = smtp_is_response(s);
+  if (response_code) {
+    LWIP_DEBUGF(SMTP_DEBUG_TRACE, ("smtp_process: received response code: %d\n", response_code));
+    if (smtp_is_response_finished(s) != ERR_OK) {
+      LWIP_DEBUGF(SMTP_DEBUG_TRACE, ("smtp_process: partly received response code: %d\n", response_code));
+      /* wait for next packet to complete the respone */
+      return;
+    }
+  } else {
+    if (s->p != NULL) {
+      LWIP_DEBUGF(SMTP_DEBUG_WARN, ("smtp_process: unknown data received (%s)\n",
+        smtp_pbuf_str(s->p)));
+      pbuf_free(s->p);
+      s->p = NULL;
+    }
+    return;
+  }
+
+  switch(s->state)
+  {
+  case(SMTP_NULL):
+    /* wait for 220 */
+    if (response_code == 220) {
+      /* then send EHLO */
+      next_state = smtp_prepare_helo(s, &tx_buf_len, pcb);
+    }
+    break;
+  case(SMTP_HELO):
+    /* wait for 250 */
+    if (response_code == 250) {
+#if SMTP_SUPPORT_AUTH_PLAIN || SMTP_SUPPORT_AUTH_LOGIN
+      /* then send AUTH or MAIL */
+      next_state = smtp_prepare_auth_or_mail(s, &tx_buf_len);
+    }
+    break;
+  case(SMTP_AUTH_LOGIN):
+  case(SMTP_AUTH_PLAIN):
+    /* wait for 235 */
+    if (response_code == 235) {
+#endif /* SMTP_SUPPORT_AUTH_PLAIN || SMTP_SUPPORT_AUTH_LOGIN */
+      /* send MAIL */
+      next_state = smtp_prepare_mail(s, &tx_buf_len);
+    }
+    break;
+#if SMTP_SUPPORT_AUTH_LOGIN
+  case(SMTP_AUTH_LOGIN_UNAME):
+    /* wait for 334 Username */
+    if (response_code == 334) {
+      if (pbuf_strstr(s->p, SMTP_RESP_LOGIN_UNAME) != 0xFFFF) {
+        /* send username */
+        next_state = smtp_prepare_auth_login_uname(s, &tx_buf_len);
+      }
+    }
+    break;
+  case(SMTP_AUTH_LOGIN_PASS):
+    /* wait for 334 Password */
+    if (response_code == 334) {
+      if (pbuf_strstr(s->p, SMTP_RESP_LOGIN_PASS) != 0xFFFF) {
+        /* send username */
+        next_state = smtp_prepare_auth_login_pass(s, &tx_buf_len);
+      }
+    }
+    break;
+#endif /* SMTP_SUPPORT_AUTH_LOGIN */
+  case(SMTP_MAIL):
+    /* wait for 250 */
+    if (response_code == 250) {
+      /* send RCPT */
+      next_state = smtp_prepare_rcpt(s, &tx_buf_len);
+    }
+    break;
+  case(SMTP_RCPT):
+    /* wait for 250 */
+    if (response_code == 250) {
+      /* send DATA */
+      SMEMCPY(s->tx_buf, SMTP_CMD_DATA, SMTP_CMD_DATA_LEN);
+      tx_buf_len = SMTP_CMD_DATA_LEN;
+      next_state = SMTP_DATA;
+    }
+    break;
+  case(SMTP_DATA):
+    /* wait for 354 */
+    if (response_code == 354) {
+      /* send email header */
+      next_state = smtp_prepare_header(s, &tx_buf_len);
+    }
+    break;
+  case(SMTP_BODY):
+    /* nothing to be done here, handled somewhere else */
+    break;
+  case(SMTP_QUIT):
+    /* wait for 250 */
+    if (response_code == 250) {
+      /* send QUIT */
+      next_state = smtp_prepare_quit(s, &tx_buf_len);
+    }
+    break;
+  case(SMTP_CLOSED):
+    /* nothing to do, wait for connection closed from server */
+    return;
+  default:
+    LWIP_DEBUGF(SMTP_DEBUG_SERIOUS, ("Invalid state: %d/%s\n", (int)s->state,
+      smtp_state_str[s->state]));
+    break;
+  }
+  if (s->state == next_state) {
+    LWIP_DEBUGF(SMTP_DEBUG_WARN_STATE, ("smtp_process[%s]: unexpected response_code, closing: %d (%s)\n",
+      smtp_state_str[s->state], response_code, smtp_pbuf_str(s->p)));
+    /* close connection */
+    smtp_close(s, pcb, SMTP_RESULT_ERR_SVR_RESP, response_code, ERR_OK);
+    return;
+  }
+  if (tx_buf_len > 0) {
+    SMTP_TX_BUF_MAX(tx_buf_len);
+    if (altcp_write(pcb, s->tx_buf, tx_buf_len, TCP_WRITE_FLAG_COPY) == ERR_OK) {
+      LWIP_DEBUGF(SMTP_DEBUG_TRACE, ("smtp_process[%s]: received command %d (%s)\n",
+        smtp_state_str[s->state], response_code, smtp_pbuf_str(s->p)));
+      LWIP_DEBUGF(SMTP_DEBUG_TRACE, ("smtp_process[%s]: sent %"U16_F" bytes: \"%s\"\n",
+        smtp_state_str[s->state], tx_buf_len, s->tx_buf));
+      s->timer = SMTP_TIMEOUT;
+      pbuf_free(s->p);
+      s->p = NULL;
+      LWIP_DEBUGF(SMTP_DEBUG_STATE, ("smtp_process: changing state from %s to %s\n",
+        smtp_state_str[s->state], smtp_state_str[next_state]));
+      s->state = next_state;
+      if (next_state == SMTP_BODY) {
+        /* try to stream-send body data right now */
+        smtp_send_body(s, pcb);
+      } else if (next_state == SMTP_CLOSED) {
+        /* sent out all data, delete structure */
+        altcp_arg(pcb, NULL);
+        smtp_free(s, SMTP_RESULT_OK, 0, ERR_OK);
+      }
+    }
+  }
+}
+
+#if SMTP_BODYDH
+/** Elementary sub-function to send data
+ *
+ * @returns: BDHALLDATASENT all data has been written
+ *           BDHSOMEDATASENT some data has been written
+ *           0 no data has been written
+ */
+static int
+smtp_send_bodyh_data(struct altcp_pcb *pcb, const char **from, u16_t *howmany)
+{
+  err_t err;
+  u16_t len = *howmany;
+
+  len = (u16_t)LWIP_MIN(len, altcp_sndbuf(pcb));
+  err = altcp_write(pcb, *from, len, TCP_WRITE_FLAG_COPY);
+  if (err == ERR_OK) {
+    *from += len;
+    if ((*howmany -= len) > 0) {
+      return BDHSOMEDATASENT;
+    }
+    return BDHALLDATASENT;
+  }
+  return 0;
+}
+
+/** Same as smtp_send_mail_static, but uses a callback function to send body data
+ */
+err_t
+smtp_send_mail_bodycback(const char *from, const char* to, const char* subject,
+  smtp_bodycback_fn bodycback_fn, smtp_result_fn callback_fn, void* callback_arg)
+{
+  struct smtp_session* s;
+  size_t len;
+
+  LWIP_ASSERT_CORE_LOCKED();
+
+  s = (struct smtp_session*)SMTP_STATE_MALLOC(sizeof(struct smtp_session));
+  if (s == NULL) {
+    return ERR_MEM;
+  }
+  memset(s, 0, sizeof(struct smtp_session));
+  s->bodydh = (struct smtp_bodydh_state*)SMTP_BODYDH_MALLOC(sizeof(struct smtp_bodydh_state));
+  if (s->bodydh == NULL) {
+    SMTP_STATE_FREE(s);
+    return ERR_MEM;
+  }
+  memset(s->bodydh, 0, sizeof(struct smtp_bodydh_state));
+  /* initialize the structure */
+  s->from = from;
+  len = strlen(from);
+  LWIP_ASSERT("string is too long", len <= 0xffff);
+  s->from_len = (u16_t)len;
+  s->to = to;
+  len = strlen(to);
+  LWIP_ASSERT("string is too long", len <= 0xffff);
+  s->to_len = (u16_t)len;
+  s->subject = subject;
+  len = strlen(subject);
+  LWIP_ASSERT("string is too long", len <= 0xffff);
+  s->subject_len = (u16_t)len;
+  s->body = NULL;
+  LWIP_ASSERT("string is too long", len <= 0xffff);
+  s->callback_fn = callback_fn;
+  s->callback_arg = callback_arg;
+  s->bodydh->callback_fn = bodycback_fn;
+  s->bodydh->state = BDH_SENDING;
+  /* call the actual implementation of this function */
+  return smtp_send_mail_alloced(s);
+}
+
+static void
+smtp_send_body_data_handler(struct smtp_session *s, struct altcp_pcb *pcb)
+{
+  struct smtp_bodydh_state *bdh;
+  int res = 0, ret;
+  LWIP_ASSERT("s != NULL", s != NULL);
+  bdh = s->bodydh;
+  LWIP_ASSERT("bodydh != NULL", bdh != NULL);
+
+  /* resume any leftovers from prior memory constraints */
+  if (s->body_len) {
+    LWIP_DEBUGF(SMTP_DEBUG_TRACE, ("smtp_send_body_data_handler: resume\n"));
+    if((res = smtp_send_bodyh_data(pcb, (const char **)&s->body, &s->body_len))
+        != BDHALLDATASENT) {
+      s->body_sent = s->body_len - 1;
+      return;
+    }
+  }
+  ret = res;
+  /* all data on buffer has been queued, resume execution */
+  if (bdh->state == BDH_SENDING) {
+    LWIP_DEBUGF(SMTP_DEBUG_TRACE, ("smtp_send_body_data_handler: run\n"));
+    do {
+      ret |= res; /* remember if we once queued something to send */
+      bdh->exposed.length = 0;
+      if (bdh->callback_fn(s->callback_arg, &bdh->exposed) == BDH_DONE) {
+        bdh->state = BDH_STOP;
+      }
+      s->body = bdh->exposed.buffer;
+      s->body_len = bdh->exposed.length;
+      LWIP_DEBUGF(SMTP_DEBUG_TRACE, ("smtp_send_body_data_handler: trying to send %u bytes\n", (unsigned int)s->body_len));
+    } while (s->body_len &&
+            ((res = smtp_send_bodyh_data(pcb, (const char **)&s->body, &s->body_len)) == BDHALLDATASENT)
+            && (bdh->state != BDH_STOP));
+  }
+  if ((bdh->state != BDH_SENDING) && (ret != BDHSOMEDATASENT)) {
+    LWIP_DEBUGF(SMTP_DEBUG_TRACE, ("smtp_send_body_data_handler: stop\n"));
+    s->body_sent = s->body_len;
+  } else {
+    LWIP_DEBUGF(SMTP_DEBUG_TRACE, ("smtp_send_body_data_handler: pause\n"));
+    s->body_sent = s->body_len - 1;
+  }
+}
+#endif /* SMTP_BODYDH */
+
+#endif /* LWIP_TCP && LWIP_CALLBACK_API */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/apps/snmp/snmp_asn1.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/apps/snmp/snmp_asn1.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/apps/snmp/snmp_asn1.c	(revision 457)
@@ -0,0 +1,704 @@
+/**
+ * @file
+ * Abstract Syntax Notation One (ISO 8824, 8825) encoding
+ *
+ * @todo not optimised (yet), favor correctness over speed, favor speed over size
+ */
+
+/*
+ * Copyright (c) 2006 Axon Digital Design B.V., The Netherlands.
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * Author: Christiaan Simons <christiaan.simons@axon.tv>
+ *         Martin Hentschel <info@cl-soft.de>
+ */
+
+#include "lwip/apps/snmp_opts.h"
+
+#if LWIP_SNMP /* don't build if not configured for use in lwipopts.h */
+
+#include "snmp_asn1.h"
+
+#define PBUF_OP_EXEC(code) \
+  if ((code) != ERR_OK) { \
+    return ERR_BUF; \
+  }
+
+/**
+ * Encodes a TLV into a pbuf stream.
+ *
+ * @param pbuf_stream points to a pbuf stream
+ * @param tlv TLV to encode
+ * @return ERR_OK if successful, ERR_ARG if we can't (or won't) encode
+ */
+err_t
+snmp_ans1_enc_tlv(struct snmp_pbuf_stream *pbuf_stream, struct snmp_asn1_tlv *tlv)
+{
+  u8_t data;
+  u8_t length_bytes_required;
+
+  /* write type */
+  if ((tlv->type & SNMP_ASN1_DATATYPE_MASK) == SNMP_ASN1_DATATYPE_EXTENDED) {
+    /* extended format is not used by SNMP so we do not accept those values */
+    return ERR_ARG;
+  }
+  if (tlv->type_len != 0) {
+    /* any other value as auto is not accepted for type (we always use one byte because extended syntax is prohibited) */
+    return ERR_ARG;
+  }
+
+  PBUF_OP_EXEC(snmp_pbuf_stream_write(pbuf_stream, tlv->type));
+  tlv->type_len = 1;
+
+  /* write length */
+  if (tlv->value_len <= 127) {
+    length_bytes_required = 1;
+  } else if (tlv->value_len <= 255) {
+    length_bytes_required = 2;
+  } else  {
+    length_bytes_required = 3;
+  }
+
+  /* check for forced min length */
+  if (tlv->length_len > 0) {
+    if (tlv->length_len < length_bytes_required) {
+      /* unable to code requested length in requested number of bytes */
+      return ERR_ARG;
+    }
+
+    length_bytes_required = tlv->length_len;
+  } else {
+    tlv->length_len = length_bytes_required;
+  }
+
+  if (length_bytes_required > 1) {
+    /* multi byte representation required */
+    length_bytes_required--;
+    data = 0x80 | length_bytes_required; /* extended length definition, 1 length byte follows */
+
+    PBUF_OP_EXEC(snmp_pbuf_stream_write(pbuf_stream, data));
+
+    while (length_bytes_required > 1) {
+      if (length_bytes_required == 2) {
+        /* append high byte */
+        data = (u8_t)(tlv->value_len >> 8);
+      } else {
+        /* append leading 0x00 */
+        data = 0x00;
+      }
+
+      PBUF_OP_EXEC(snmp_pbuf_stream_write(pbuf_stream, data));
+      length_bytes_required--;
+    }
+  }
+
+  /* append low byte */
+  data = (u8_t)(tlv->value_len & 0xFF);
+  PBUF_OP_EXEC(snmp_pbuf_stream_write(pbuf_stream, data));
+
+  return ERR_OK;
+}
+
+/**
+ * Encodes raw data (octet string, opaque) into a pbuf chained ASN1 msg.
+ *
+ * @param pbuf_stream points to a pbuf stream
+ * @param raw_len raw data length
+ * @param raw points raw data
+ * @return ERR_OK if successful, ERR_ARG if we can't (or won't) encode
+ */
+err_t
+snmp_asn1_enc_raw(struct snmp_pbuf_stream *pbuf_stream, const u8_t *raw, u16_t raw_len)
+{
+  PBUF_OP_EXEC(snmp_pbuf_stream_writebuf(pbuf_stream, raw, raw_len));
+
+  return ERR_OK;
+}
+
+/**
+ * Encodes u32_t (counter, gauge, timeticks) into a pbuf chained ASN1 msg.
+ *
+ * @param pbuf_stream points to a pbuf stream
+ * @param octets_needed encoding length (from snmp_asn1_enc_u32t_cnt())
+ * @param value is the host order u32_t value to be encoded
+ * @return ERR_OK if successful, ERR_ARG if we can't (or won't) encode
+ *
+ * @see snmp_asn1_enc_u32t_cnt()
+ */
+err_t
+snmp_asn1_enc_u32t(struct snmp_pbuf_stream *pbuf_stream, u16_t octets_needed, u32_t value)
+{
+  if (octets_needed > 5) {
+    return ERR_ARG;
+  }
+  if (octets_needed == 5) {
+    /* not enough bits in 'value' add leading 0x00 */
+    PBUF_OP_EXEC(snmp_pbuf_stream_write(pbuf_stream, 0x00));
+    octets_needed--;
+  }
+
+  while (octets_needed > 1) {
+    octets_needed--;
+    PBUF_OP_EXEC(snmp_pbuf_stream_write(pbuf_stream, (u8_t)(value >> (octets_needed << 3))));
+  }
+
+  /* (only) one least significant octet */
+  PBUF_OP_EXEC(snmp_pbuf_stream_write(pbuf_stream, (u8_t)value));
+
+  return ERR_OK;
+}
+/**
+ * Encodes s32_t integer into a pbuf chained ASN1 msg.
+ *
+ * @param pbuf_stream points to a pbuf stream
+ * @param octets_needed encoding length (from snmp_asn1_enc_s32t_cnt())
+ * @param value is the host order s32_t value to be encoded
+ * @return ERR_OK if successful, ERR_ARG if we can't (or won't) encode
+ *
+ * @see snmp_asn1_enc_s32t_cnt()
+ */
+err_t
+snmp_asn1_enc_s32t(struct snmp_pbuf_stream *pbuf_stream, u16_t octets_needed, s32_t value)
+{
+  while (octets_needed > 1) {
+    octets_needed--;
+
+    PBUF_OP_EXEC(snmp_pbuf_stream_write(pbuf_stream, (u8_t)(value >> (octets_needed << 3))));
+  }
+
+  /* (only) one least significant octet */
+  PBUF_OP_EXEC(snmp_pbuf_stream_write(pbuf_stream, (u8_t)value));
+
+  return ERR_OK;
+}
+
+/**
+ * Encodes object identifier into a pbuf chained ASN1 msg.
+ *
+ * @param pbuf_stream points to a pbuf stream
+ * @param oid points to object identifier array
+ * @param oid_len object identifier array length
+ * @return ERR_OK if successful, ERR_ARG if we can't (or won't) encode
+ */
+err_t
+snmp_asn1_enc_oid(struct snmp_pbuf_stream *pbuf_stream, const u32_t *oid, u16_t oid_len)
+{
+  if (oid_len > 1) {
+    /* write compressed first two sub id's */
+    u32_t compressed_byte = ((oid[0] * 40) + oid[1]);
+    PBUF_OP_EXEC(snmp_pbuf_stream_write(pbuf_stream, (u8_t)compressed_byte));
+    oid_len -= 2;
+    oid += 2;
+  } else {
+    /* @bug:  allow empty varbinds for symmetry (we must decode them for getnext), allow partial compression?? */
+    /* ident_len <= 1, at least we need zeroDotZero (0.0) (ident_len == 2) */
+    return ERR_ARG;
+  }
+
+  while (oid_len > 0) {
+    u32_t sub_id;
+    u8_t shift, tail;
+
+    oid_len--;
+    sub_id = *oid;
+    tail = 0;
+    shift = 28;
+    while (shift > 0) {
+      u8_t code;
+
+      code = (u8_t)(sub_id >> shift);
+      if ((code != 0) || (tail != 0)) {
+        tail = 1;
+        PBUF_OP_EXEC(snmp_pbuf_stream_write(pbuf_stream, code | 0x80));
+      }
+      shift -= 7;
+    }
+    PBUF_OP_EXEC(snmp_pbuf_stream_write(pbuf_stream, (u8_t)sub_id & 0x7F));
+
+    /* proceed to next sub-identifier */
+    oid++;
+  }
+  return ERR_OK;
+}
+
+/**
+ * Returns octet count for length.
+ *
+ * @param length parameter length
+ * @param octets_needed points to the return value
+ */
+void
+snmp_asn1_enc_length_cnt(u16_t length, u8_t *octets_needed)
+{
+  if (length < 0x80U) {
+    *octets_needed = 1;
+  } else if (length < 0x100U) {
+    *octets_needed = 2;
+  } else {
+    *octets_needed = 3;
+  }
+}
+
+/**
+ * Returns octet count for an u32_t.
+ *
+ * @param value value to be encoded
+ * @param octets_needed points to the return value
+ *
+ * @note ASN coded integers are _always_ signed. E.g. +0xFFFF is coded
+ * as 0x00,0xFF,0xFF. Note the leading sign octet. A positive value
+ * of 0xFFFFFFFF is preceded with 0x00 and the length is 5 octets!!
+ */
+void
+snmp_asn1_enc_u32t_cnt(u32_t value, u16_t *octets_needed)
+{
+  if (value < 0x80UL) {
+    *octets_needed = 1;
+  } else if (value < 0x8000UL) {
+    *octets_needed = 2;
+  } else if (value < 0x800000UL) {
+    *octets_needed = 3;
+  } else if (value < 0x80000000UL) {
+    *octets_needed = 4;
+  } else {
+    *octets_needed = 5;
+  }
+}
+
+/**
+ * Returns octet count for an s32_t.
+ *
+ * @param value value to be encoded
+ * @param octets_needed points to the return value
+ *
+ * @note ASN coded integers are _always_ signed.
+ */
+void
+snmp_asn1_enc_s32t_cnt(s32_t value, u16_t *octets_needed)
+{
+  if (value < 0) {
+    value = ~value;
+  }
+  if (value < 0x80L) {
+    *octets_needed = 1;
+  } else if (value < 0x8000L) {
+    *octets_needed = 2;
+  } else if (value < 0x800000L) {
+    *octets_needed = 3;
+  } else {
+    *octets_needed = 4;
+  }
+}
+
+/**
+ * Returns octet count for an object identifier.
+ *
+ * @param oid points to object identifier array
+ * @param oid_len object identifier array length
+ * @param octets_needed points to the return value
+ */
+void
+snmp_asn1_enc_oid_cnt(const u32_t *oid, u16_t oid_len, u16_t *octets_needed)
+{
+  u32_t sub_id;
+
+  *octets_needed = 0;
+  if (oid_len > 1) {
+    /* compressed prefix in one octet */
+    (*octets_needed)++;
+    oid_len -= 2;
+    oid += 2;
+  }
+  while (oid_len > 0) {
+    oid_len--;
+    sub_id = *oid;
+
+    sub_id >>= 7;
+    (*octets_needed)++;
+    while (sub_id > 0) {
+      sub_id >>= 7;
+      (*octets_needed)++;
+    }
+    oid++;
+  }
+}
+
+/**
+ * Decodes a TLV from a pbuf stream.
+ *
+ * @param pbuf_stream points to a pbuf stream
+ * @param tlv returns decoded TLV
+ * @return ERR_OK if successful, ERR_VAL if we can't decode
+ */
+err_t
+snmp_asn1_dec_tlv(struct snmp_pbuf_stream *pbuf_stream, struct snmp_asn1_tlv *tlv)
+{
+  u8_t data;
+
+  /* decode type first */
+  PBUF_OP_EXEC(snmp_pbuf_stream_read(pbuf_stream, &data));
+  tlv->type = data;
+
+  if ((tlv->type & SNMP_ASN1_DATATYPE_MASK) == SNMP_ASN1_DATATYPE_EXTENDED) {
+    /* extended format is not used by SNMP so we do not accept those values */
+    return ERR_VAL;
+  }
+  tlv->type_len = 1;
+
+  /* now, decode length */
+  PBUF_OP_EXEC(snmp_pbuf_stream_read(pbuf_stream, &data));
+
+  if (data < 0x80) { /* short form */
+    tlv->length_len = 1;
+    tlv->value_len  = data;
+  } else if (data > 0x80) { /* long form */
+    u8_t length_bytes = data - 0x80;
+    if (length_bytes > pbuf_stream->length) {
+      return ERR_VAL;
+    }
+    tlv->length_len = length_bytes + 1; /* this byte + defined number of length bytes following */
+    tlv->value_len = 0;
+
+    while (length_bytes > 0) {
+      /* we only support up to u16.maxvalue-1 (2 bytes) but have to accept leading zero bytes */
+      if (tlv->value_len > 0xFF) {
+        return ERR_VAL;
+      }
+      PBUF_OP_EXEC(snmp_pbuf_stream_read(pbuf_stream, &data));
+      tlv->value_len <<= 8;
+      tlv->value_len |= data;
+
+      /* take care for special value used for indefinite length */
+      if (tlv->value_len == 0xFFFF) {
+        return ERR_VAL;
+      }
+
+      length_bytes--;
+    }
+  } else { /* data == 0x80 indefinite length form */
+    /* (not allowed for SNMP; RFC 1157, 3.2.2) */
+    return ERR_VAL;
+  }
+
+  return ERR_OK;
+}
+
+/**
+ * Decodes positive integer (counter, gauge, timeticks) into u32_t.
+ *
+ * @param pbuf_stream points to a pbuf stream
+ * @param len length of the coded integer field
+ * @param value return host order integer
+ * @return ERR_OK if successful, ERR_ARG if we can't (or won't) decode
+ *
+ * @note ASN coded integers are _always_ signed. E.g. +0xFFFF is coded
+ * as 0x00,0xFF,0xFF. Note the leading sign octet. A positive value
+ * of 0xFFFFFFFF is preceded with 0x00 and the length is 5 octets!!
+ */
+err_t
+snmp_asn1_dec_u32t(struct snmp_pbuf_stream *pbuf_stream, u16_t len, u32_t *value)
+{
+  u8_t data;
+
+  if ((len > 0) && (len <= 5)) {
+    PBUF_OP_EXEC(snmp_pbuf_stream_read(pbuf_stream, &data));
+
+    /* expecting sign bit to be zero, only unsigned please! */
+    if (((len == 5) && (data == 0x00)) || ((len < 5) && ((data & 0x80) == 0))) {
+      *value = data;
+      len--;
+
+      while (len > 0) {
+        PBUF_OP_EXEC(snmp_pbuf_stream_read(pbuf_stream, &data));
+        len--;
+
+        *value <<= 8;
+        *value |= data;
+      }
+
+      return ERR_OK;
+    }
+  }
+
+  return ERR_VAL;
+}
+
+/**
+ * Decodes integer into s32_t.
+ *
+ * @param pbuf_stream points to a pbuf stream
+ * @param len length of the coded integer field
+ * @param value return host order integer
+ * @return ERR_OK if successful, ERR_ARG if we can't (or won't) decode
+ *
+ * @note ASN coded integers are _always_ signed!
+ */
+err_t
+snmp_asn1_dec_s32t(struct snmp_pbuf_stream *pbuf_stream, u16_t len, s32_t *value)
+{
+  u8_t data;
+
+  if ((len > 0) && (len < 5)) {
+    PBUF_OP_EXEC(snmp_pbuf_stream_read(pbuf_stream, &data));
+
+    if (data & 0x80) {
+      /* negative, start from -1 */
+      *value = -1;
+      *value = (*value << 8) | data;
+    } else {
+      /* positive, start from 0 */
+      *value = data;
+    }
+    len--;
+    /* shift in the remaining value */
+    while (len > 0) {
+      PBUF_OP_EXEC(snmp_pbuf_stream_read(pbuf_stream, &data));
+      *value = (*value << 8) | data;
+      len--;
+    }
+    return ERR_OK;
+  }
+
+  return ERR_VAL;
+}
+
+/**
+ * Decodes object identifier from incoming message into array of u32_t.
+ *
+ * @param pbuf_stream points to a pbuf stream
+ * @param len length of the coded object identifier
+ * @param oid return decoded object identifier
+ * @param oid_len return decoded object identifier length
+ * @param oid_max_len size of oid buffer
+ * @return ERR_OK if successful, ERR_ARG if we can't (or won't) decode
+ */
+err_t
+snmp_asn1_dec_oid(struct snmp_pbuf_stream *pbuf_stream, u16_t len, u32_t *oid, u8_t *oid_len, u8_t oid_max_len)
+{
+  u32_t *oid_ptr;
+  u8_t data;
+
+  *oid_len = 0;
+  oid_ptr = oid;
+  if (len > 0) {
+    if (oid_max_len < 2) {
+      return ERR_MEM;
+    }
+
+    PBUF_OP_EXEC(snmp_pbuf_stream_read(pbuf_stream, &data));
+    len--;
+
+    /* first compressed octet */
+    if (data == 0x2B) {
+      /* (most) common case 1.3 (iso.org) */
+      *oid_ptr = 1;
+      oid_ptr++;
+      *oid_ptr = 3;
+      oid_ptr++;
+    } else if (data < 40) {
+      *oid_ptr = 0;
+      oid_ptr++;
+      *oid_ptr = data;
+      oid_ptr++;
+    } else if (data < 80) {
+      *oid_ptr = 1;
+      oid_ptr++;
+      *oid_ptr = data - 40;
+      oid_ptr++;
+    } else {
+      *oid_ptr = 2;
+      oid_ptr++;
+      *oid_ptr = data - 80;
+      oid_ptr++;
+    }
+    *oid_len = 2;
+  } else {
+    /* accepting zero length identifiers e.g. for getnext operation. uncommon but valid */
+    return ERR_OK;
+  }
+
+  while ((len > 0) && (*oid_len < oid_max_len)) {
+    PBUF_OP_EXEC(snmp_pbuf_stream_read(pbuf_stream, &data));
+    len--;
+
+    if ((data & 0x80) == 0x00) {
+      /* sub-identifier uses single octet */
+      *oid_ptr = data;
+    } else {
+      /* sub-identifier uses multiple octets */
+      u32_t sub_id = (data & ~0x80);
+      while ((len > 0) && ((data & 0x80) != 0)) {
+        PBUF_OP_EXEC(snmp_pbuf_stream_read(pbuf_stream, &data));
+        len--;
+
+        sub_id = (sub_id << 7) + (data & ~0x80);
+      }
+
+      if ((data & 0x80) != 0) {
+        /* "more bytes following" bit still set at end of len */
+        return ERR_VAL;
+      }
+      *oid_ptr = sub_id;
+    }
+    oid_ptr++;
+    (*oid_len)++;
+  }
+
+  if (len > 0) {
+    /* OID to long to fit in our buffer */
+    return ERR_MEM;
+  }
+
+  return ERR_OK;
+}
+
+/**
+ * Decodes (copies) raw data (ip-addresses, octet strings, opaque encoding)
+ * from incoming message into array.
+ *
+ * @param pbuf_stream points to a pbuf stream
+ * @param len length of the coded raw data (zero is valid, e.g. empty string!)
+ * @param buf return raw bytes
+ * @param buf_len returns length of the raw return value
+ * @param buf_max_len buffer size
+ * @return ERR_OK if successful, ERR_ARG if we can't (or won't) decode
+ */
+err_t
+snmp_asn1_dec_raw(struct snmp_pbuf_stream *pbuf_stream, u16_t len, u8_t *buf, u16_t *buf_len, u16_t buf_max_len)
+{
+  if (len > buf_max_len) {
+    /* not enough dst space */
+    return ERR_MEM;
+  }
+  *buf_len = len;
+
+  while (len > 0) {
+    PBUF_OP_EXEC(snmp_pbuf_stream_read(pbuf_stream, buf));
+    buf++;
+    len--;
+  }
+
+  return ERR_OK;
+}
+
+#if LWIP_HAVE_INT64
+/**
+ * Returns octet count for an u64_t.
+ *
+ * @param value value to be encoded
+ * @param octets_needed points to the return value
+ *
+ * @note ASN coded integers are _always_ signed. E.g. +0xFFFF is coded
+ * as 0x00,0xFF,0xFF. Note the leading sign octet. A positive value
+ * of 0xFFFFFFFFFFFFFFFF is preceded with 0x00 and the length is 9 octets!!
+ */
+void
+snmp_asn1_enc_u64t_cnt(u64_t value, u16_t *octets_needed)
+{
+  /* check if high u32 is 0 */
+  if ((value >> 32) == 0) {
+    /* only low u32 is important */
+    snmp_asn1_enc_u32t_cnt((u32_t)value, octets_needed);
+  } else {
+    /* low u32 does not matter for length determination */
+    snmp_asn1_enc_u32t_cnt((u32_t)(value >> 32), octets_needed);
+    *octets_needed = *octets_needed + 4; /* add the 4 bytes of low u32 */
+  }
+}
+
+/**
+ * Decodes large positive integer (counter64) into 2x u32_t.
+ *
+ * @param pbuf_stream points to a pbuf stream
+ * @param len length of the coded integer field
+ * @param value return 64 bit integer
+ * @return ERR_OK if successful, ERR_ARG if we can't (or won't) decode
+ *
+ * @note ASN coded integers are _always_ signed. E.g. +0xFFFF is coded
+ * as 0x00,0xFF,0xFF. Note the leading sign octet. A positive value
+ * of 0xFFFFFFFFFFFFFFFF is preceded with 0x00 and the length is 9 octets!!
+ */
+err_t
+snmp_asn1_dec_u64t(struct snmp_pbuf_stream *pbuf_stream, u16_t len, u64_t *value)
+{
+  u8_t data;
+
+  if ((len > 0) && (len <= 9)) {
+    PBUF_OP_EXEC(snmp_pbuf_stream_read(pbuf_stream, &data));
+
+    /* expecting sign bit to be zero, only unsigned please! */
+    if (((len == 9) && (data == 0x00)) || ((len < 9) && ((data & 0x80) == 0))) {
+      *value = data;
+      len--;
+
+      while (len > 0) {
+        PBUF_OP_EXEC(snmp_pbuf_stream_read(pbuf_stream, &data));
+        *value <<= 8;
+        *value |= data;
+        len--;
+      }
+
+      return ERR_OK;
+    }
+  }
+
+  return ERR_VAL;
+}
+
+/**
+ * Encodes u64_t (counter64) into a pbuf chained ASN1 msg.
+ *
+ * @param pbuf_stream points to a pbuf stream
+ * @param octets_needed encoding length (from snmp_asn1_enc_u32t_cnt())
+ * @param value is the value to be encoded
+ * @return ERR_OK if successful, ERR_ARG if we can't (or won't) encode
+ *
+ * @see snmp_asn1_enc_u64t_cnt()
+ */
+err_t
+snmp_asn1_enc_u64t(struct snmp_pbuf_stream *pbuf_stream, u16_t octets_needed, u64_t value)
+{
+  if (octets_needed > 9) {
+    return ERR_ARG;
+  }
+  if (octets_needed == 9) {
+    /* not enough bits in 'value' add leading 0x00 */
+    PBUF_OP_EXEC(snmp_pbuf_stream_write(pbuf_stream, 0x00));
+    octets_needed--;
+  }
+
+  while (octets_needed > 1) {
+    octets_needed--;
+    PBUF_OP_EXEC(snmp_pbuf_stream_write(pbuf_stream, (u8_t)(value >> (octets_needed << 3))));
+  }
+
+  /* always write at least one octet (also in case of value == 0) */
+  PBUF_OP_EXEC(snmp_pbuf_stream_write(pbuf_stream, (u8_t)(value)));
+
+  return ERR_OK;
+}
+#endif
+
+#endif /* LWIP_SNMP */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/apps/snmp/snmp_asn1.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/apps/snmp/snmp_asn1.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/apps/snmp/snmp_asn1.h	(revision 457)
@@ -0,0 +1,113 @@
+/**
+ * @file
+ * Abstract Syntax Notation One (ISO 8824, 8825) codec.
+ */
+
+/*
+ * Copyright (c) 2006 Axon Digital Design B.V., The Netherlands.
+ * Copyright (c) 2016 Elias Oenal.
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * Author: Christiaan Simons <christiaan.simons@axon.tv>
+ *         Martin Hentschel <info@cl-soft.de>
+ *         Elias Oenal <lwip@eliasoenal.com>
+ */
+
+#ifndef LWIP_HDR_APPS_SNMP_ASN1_H
+#define LWIP_HDR_APPS_SNMP_ASN1_H
+
+#include "lwip/apps/snmp_opts.h"
+
+#if LWIP_SNMP
+
+#include "lwip/err.h"
+#include "lwip/apps/snmp_core.h"
+#include "snmp_pbuf_stream.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define SNMP_ASN1_TLV_INDEFINITE_LENGTH 0x80
+
+#define SNMP_ASN1_CLASS_MASK        0xC0
+#define SNMP_ASN1_CONTENTTYPE_MASK  0x20
+#define SNMP_ASN1_DATATYPE_MASK     0x1F
+#define SNMP_ASN1_DATATYPE_EXTENDED 0x1F /* DataType indicating that datatype is encoded in following bytes */
+
+/* context specific (SNMP) tags (from SNMP spec. RFC1157 and RFC1905) */
+#define SNMP_ASN1_CONTEXT_PDU_GET_REQ      0
+#define SNMP_ASN1_CONTEXT_PDU_GET_NEXT_REQ 1
+#define SNMP_ASN1_CONTEXT_PDU_GET_RESP     2
+#define SNMP_ASN1_CONTEXT_PDU_SET_REQ      3
+#define SNMP_ASN1_CONTEXT_PDU_TRAP         4
+#define SNMP_ASN1_CONTEXT_PDU_GET_BULK_REQ 5
+#define SNMP_ASN1_CONTEXT_PDU_INFORM_REQ   6
+#define SNMP_ASN1_CONTEXT_PDU_V2_TRAP      7
+#define SNMP_ASN1_CONTEXT_PDU_REPORT       8
+
+#define SNMP_ASN1_CONTEXT_VARBIND_NO_SUCH_OBJECT      0
+#define SNMP_ASN1_CONTEXT_VARBIND_END_OF_MIB_VIEW     2
+
+struct snmp_asn1_tlv {
+  u8_t  type;       /* only U8 because extended types are not specified by SNMP */
+  u8_t  type_len;   /* encoded length of 'type' field (normally 1) */
+  u8_t  length_len; /* indicates how many bytes are required to encode the 'value_len' field */
+  u16_t value_len;  /* encoded length of the value */
+};
+#define SNMP_ASN1_TLV_HDR_LENGTH(tlv) ((tlv).type_len + (tlv).length_len)
+#define SNMP_ASN1_TLV_LENGTH(tlv) ((tlv).type_len + (tlv).length_len + (tlv).value_len)
+#define SNMP_ASN1_SET_TLV_PARAMS(tlv, type_, length_len_, value_len_) do { (tlv).type = (type_); (tlv).type_len = 0; (tlv).length_len = (length_len_); (tlv).value_len = (value_len_); } while (0);
+
+err_t snmp_asn1_dec_tlv(struct snmp_pbuf_stream *pbuf_stream, struct snmp_asn1_tlv *tlv);
+err_t snmp_asn1_dec_u32t(struct snmp_pbuf_stream *pbuf_stream, u16_t len, u32_t *value);
+err_t snmp_asn1_dec_s32t(struct snmp_pbuf_stream *pbuf_stream, u16_t len, s32_t *value);
+err_t snmp_asn1_dec_oid(struct snmp_pbuf_stream *pbuf_stream, u16_t len, u32_t *oid, u8_t *oid_len, u8_t oid_max_len);
+err_t snmp_asn1_dec_raw(struct snmp_pbuf_stream *pbuf_stream, u16_t len, u8_t *buf, u16_t *buf_len, u16_t buf_max_len);
+
+err_t snmp_ans1_enc_tlv(struct snmp_pbuf_stream *pbuf_stream, struct snmp_asn1_tlv *tlv);
+
+void snmp_asn1_enc_length_cnt(u16_t length, u8_t *octets_needed);
+void snmp_asn1_enc_u32t_cnt(u32_t value, u16_t *octets_needed);
+void snmp_asn1_enc_s32t_cnt(s32_t value, u16_t *octets_needed);
+void snmp_asn1_enc_oid_cnt(const u32_t *oid, u16_t oid_len, u16_t *octets_needed);
+err_t snmp_asn1_enc_oid(struct snmp_pbuf_stream *pbuf_stream, const u32_t *oid, u16_t oid_len);
+err_t snmp_asn1_enc_s32t(struct snmp_pbuf_stream *pbuf_stream, u16_t octets_needed, s32_t value);
+err_t snmp_asn1_enc_u32t(struct snmp_pbuf_stream *pbuf_stream, u16_t octets_needed, u32_t value);
+err_t snmp_asn1_enc_raw(struct snmp_pbuf_stream *pbuf_stream, const u8_t *raw, u16_t raw_len);
+
+#if LWIP_HAVE_INT64
+err_t snmp_asn1_dec_u64t(struct snmp_pbuf_stream *pbuf_stream, u16_t len, u64_t *value);
+void snmp_asn1_enc_u64t_cnt(u64_t value, u16_t *octets_needed);
+err_t snmp_asn1_enc_u64t(struct snmp_pbuf_stream *pbuf_stream, u16_t octets_needed, u64_t value);
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LWIP_SNMP */
+
+#endif /* LWIP_HDR_APPS_SNMP_ASN1_H */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/apps/snmp/snmp_core.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/apps/snmp/snmp_core.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/apps/snmp/snmp_core.c	(revision 457)
@@ -0,0 +1,1353 @@
+/**
+ * @file
+ * MIB tree access/construction functions.
+ */
+
+/*
+ * Copyright (c) 2006 Axon Digital Design B.V., The Netherlands.
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * Author: Christiaan Simons <christiaan.simons@axon.tv>
+ *         Martin Hentschel <info@cl-soft.de>
+*/
+
+/**
+ * @defgroup snmp SNMPv2c/v3 agent
+ * @ingroup apps
+ * SNMPv2c and SNMPv3 compatible agent\n
+ * There is also a MIB compiler and a MIB viewer in lwIP contrib repository
+ * (lwip-contrib/apps/LwipMibCompiler).\n
+ * The agent implements the most important MIB2 MIBs including IPv6 support
+ * (interfaces, UDP, TCP, SNMP, ICMP, SYSTEM). IP MIB is an older version
+ * without IPv6 statistics (TODO).\n
+ * Rewritten by Martin Hentschel <info@cl-soft.de> and
+ * Dirk Ziegelmeier <dziegel@gmx.de>\n
+ *
+ * 0 Agent Capabilities
+ * ====================
+ *
+ * Features:
+ * ---------
+ * - SNMPv2c support.
+ * - SNMPv3 support (a port to ARM mbedtls is provided, LWIP_SNMP_V3_MBEDTLS option).
+ * - Low RAM usage - no memory pools, stack only.
+ * - MIB2 implementation is separated from SNMP stack.
+ * - Support for multiple MIBs (snmp_set_mibs() call) - e.g. for private MIB.
+ * - Simple and generic API for MIB implementation.
+ * - Comfortable node types and helper functions for scalar arrays and tables.
+ * - Counter64, bit and truthvalue datatype support.
+ * - Callbacks for SNMP writes e.g. to implement persistency.
+ * - Runs on two APIs: RAW and netconn.
+ * - Async API is gone - the stack now supports netconn API instead,
+ *   so blocking operations can be done in MIB calls.
+ *   SNMP runs in a worker thread when netconn API is used.
+ * - Simplified thread sync support for MIBs - useful when MIBs
+ *   need to access variables shared with other threads where no locking is
+ *   possible. Used in MIB2 to access lwIP stats from lwIP thread.
+ *
+ * MIB compiler (code generator):
+ * ------------------------------
+ * - Provided in lwIP contrib repository.
+ * - Written in C#. MIB viewer used Windows Forms.
+ * - Developed on Windows with Visual Studio 2010.
+ * - Can be compiled and used on all platforms with http://www.monodevelop.com/.
+ * - Based on a heavily modified version of of SharpSnmpLib (a4bd05c6afb4)
+ *   (https://sharpsnmplib.codeplex.com/SourceControl/network/forks/Nemo157/MIBParserUpdate).
+ * - MIB parser, C file generation framework and LWIP code generation are cleanly
+ *   separated, which means the code may be useful as a base for code generation
+ *   of other SNMP agents.
+ *
+ * Notes:
+ * ------
+ * - Stack and MIB compiler were used to implement a Profinet device.
+ *   Compiled/implemented MIBs: LLDP-MIB, LLDP-EXT-DOT3-MIB, LLDP-EXT-PNO-MIB.
+ *
+ * SNMPv1 per RFC1157 and SNMPv2c per RFC 3416
+ * -------------------------------------------
+ *   Note the S in SNMP stands for "Simple". Note that "Simple" is
+ *   relative. SNMP is simple compared to the complex ISO network
+ *   management protocols CMIP (Common Management Information Protocol)
+ *   and CMOT (CMip Over Tcp).
+ *
+ * SNMPv3
+ * ------
+ * When SNMPv3 is used, several functions from snmpv3.h must be implemented
+ * by the user. This is mainly user management and persistence handling.
+ * The sample provided in lwip-contrib is insecure, don't use it in production
+ * systems, especially the missing persistence for engine boots variable
+ * simplifies replay attacks.
+ *
+ * MIB II
+ * ------
+ *   The standard lwIP stack management information base.
+ *   This is a required MIB, so this is always enabled.
+ *   The groups EGP, CMOT and transmission are disabled by default.
+ *
+ *   Most mib-2 objects are not writable except:
+ *   sysName, sysLocation, sysContact, snmpEnableAuthenTraps.
+ *   Writing to or changing the ARP and IP address and route
+ *   tables is not possible.
+ *
+ *   Note lwIP has a very limited notion of IP routing. It currently
+ *   doen't have a route table and doesn't have a notion of the U,G,H flags.
+ *   Instead lwIP uses the interface list with only one default interface
+ *   acting as a single gateway interface (G) for the default route.
+ *
+ *   The agent returns a "virtual table" with the default route 0.0.0.0
+ *   for the default interface and network routes (no H) for each
+ *   network interface in the netif_list.
+ *   All routes are considered to be up (U).
+ *
+ * Loading additional MIBs
+ * -----------------------
+ *   MIBs can only be added in compile-time, not in run-time.
+ *
+ *
+ * 1 Building the Agent
+ * ====================
+ * First of all you'll need to add the following define
+ * to your local lwipopts.h:
+ * \#define LWIP_SNMP               1
+ *
+ * and add the source files your makefile.
+ *
+ * Note you'll might need to adapt you network driver to update
+ * the mib2 variables for your interface.
+ *
+ * 2 Running the Agent
+ * ===================
+ * The following function calls must be made in your program to
+ * actually get the SNMP agent running.
+ *
+ * Before starting the agent you should supply pointers
+ * for sysContact, sysLocation, and snmpEnableAuthenTraps.
+ * You can do this by calling
+ *
+ * - snmp_mib2_set_syscontact()
+ * - snmp_mib2_set_syslocation()
+ * - snmp_set_auth_traps_enabled()
+ *
+ * You can register a callback which is called on successful write access:
+ * snmp_set_write_callback().
+ *
+ * Additionally you may want to set
+ *
+ * - snmp_mib2_set_sysdescr()
+ * - snmp_set_device_enterprise_oid()
+ * - snmp_mib2_set_sysname()
+ *
+ * Also before starting the agent you need to setup
+ * one or more trap destinations using these calls:
+ *
+ * - snmp_trap_dst_enable()
+ * - snmp_trap_dst_ip_set()
+ *
+ * If you need more than MIB2, set the MIBs you want to use
+ * by snmp_set_mibs().
+ *
+ * Finally, enable the agent by calling snmp_init()
+ *
+ * @defgroup snmp_core Core
+ * @ingroup snmp
+ *
+ * @defgroup snmp_traps Traps
+ * @ingroup snmp
+ */
+
+#include "lwip/apps/snmp_opts.h"
+
+#if LWIP_SNMP /* don't build if not configured for use in lwipopts.h */
+
+#include "lwip/apps/snmp.h"
+#include "lwip/apps/snmp_core.h"
+#include "snmp_core_priv.h"
+#include "lwip/netif.h"
+#include <string.h>
+
+
+#if (LWIP_SNMP && (SNMP_TRAP_DESTINATIONS<=0))
+#error "If you want to use SNMP, you have to define SNMP_TRAP_DESTINATIONS>=1 in your lwipopts.h"
+#endif
+#if (!LWIP_UDP && LWIP_SNMP)
+#error "If you want to use SNMP, you have to define LWIP_UDP=1 in your lwipopts.h"
+#endif
+#if SNMP_MAX_OBJ_ID_LEN > 255
+#error "SNMP_MAX_OBJ_ID_LEN must fit into an u8_t"
+#endif
+
+struct snmp_statistics snmp_stats;
+static const struct snmp_obj_id  snmp_device_enterprise_oid_default = {SNMP_DEVICE_ENTERPRISE_OID_LEN, SNMP_DEVICE_ENTERPRISE_OID};
+static const struct snmp_obj_id *snmp_device_enterprise_oid         = &snmp_device_enterprise_oid_default;
+
+const u32_t snmp_zero_dot_zero_values[] = { 0, 0 };
+const struct snmp_obj_id_const_ref snmp_zero_dot_zero = { LWIP_ARRAYSIZE(snmp_zero_dot_zero_values), snmp_zero_dot_zero_values };
+
+#if SNMP_LWIP_MIB2 && LWIP_SNMP_V3
+#include "lwip/apps/snmp_mib2.h"
+#include "lwip/apps/snmp_snmpv2_framework.h"
+#include "lwip/apps/snmp_snmpv2_usm.h"
+static const struct snmp_mib *const default_mibs[] = { &mib2, &snmpframeworkmib, &snmpusmmib };
+static u8_t snmp_num_mibs                          = LWIP_ARRAYSIZE(default_mibs);
+#elif SNMP_LWIP_MIB2
+#include "lwip/apps/snmp_mib2.h"
+static const struct snmp_mib *const default_mibs[] = { &mib2 };
+static u8_t snmp_num_mibs                          = LWIP_ARRAYSIZE(default_mibs);
+#else
+static const struct snmp_mib *const default_mibs[] = { NULL };
+static u8_t snmp_num_mibs                          = 0;
+#endif
+
+/* List of known mibs */
+static struct snmp_mib const *const *snmp_mibs = default_mibs;
+
+/**
+ * @ingroup snmp_core
+ * Sets the MIBs to use.
+ * Example: call snmp_set_mibs() as follows:
+ * static const struct snmp_mib *my_snmp_mibs[] = {
+ *   &mib2,
+ *   &private_mib
+ * };
+ * snmp_set_mibs(my_snmp_mibs, LWIP_ARRAYSIZE(my_snmp_mibs));
+ */
+void
+snmp_set_mibs(const struct snmp_mib **mibs, u8_t num_mibs)
+{
+  LWIP_ASSERT_CORE_LOCKED();
+  LWIP_ASSERT("mibs pointer must be != NULL", (mibs != NULL));
+  LWIP_ASSERT("num_mibs pointer must be != 0", (num_mibs != 0));
+  snmp_mibs     = mibs;
+  snmp_num_mibs = num_mibs;
+}
+
+/**
+ * @ingroup snmp_core
+ * 'device enterprise oid' is used for 'device OID' field in trap PDU's (for identification of generating device)
+ * as well as for value returned by MIB-2 'sysObjectID' field (if internal MIB2 implementation is used).
+ * The 'device enterprise oid' shall point to an OID located under 'private-enterprises' branch (1.3.6.1.4.1.XXX). If a vendor
+ * wants to provide a custom object there, he has to get its own enterprise oid from IANA (http://www.iana.org). It
+ * is not allowed to use LWIP enterprise ID!
+ * In order to identify a specific device it is recommended to create a dedicated OID for each device type under its own
+ * enterprise oid.
+ * e.g.
+ * device a > 1.3.6.1.4.1.XXX(ent-oid).1(devices).1(device a)
+ * device b > 1.3.6.1.4.1.XXX(ent-oid).1(devices).2(device b)
+ * for more details see description of 'sysObjectID' field in RFC1213-MIB
+ */
+void snmp_set_device_enterprise_oid(const struct snmp_obj_id *device_enterprise_oid)
+{
+  LWIP_ASSERT_CORE_LOCKED();
+  if (device_enterprise_oid == NULL) {
+    snmp_device_enterprise_oid = &snmp_device_enterprise_oid_default;
+  } else {
+    snmp_device_enterprise_oid = device_enterprise_oid;
+  }
+}
+
+/**
+ * @ingroup snmp_core
+ * Get 'device enterprise oid'
+ */
+const struct snmp_obj_id *snmp_get_device_enterprise_oid(void)
+{
+  LWIP_ASSERT_CORE_LOCKED();
+  return snmp_device_enterprise_oid;
+}
+
+#if LWIP_IPV4
+/**
+ * Conversion from InetAddressIPv4 oid to lwIP ip4_addr
+ * @param oid points to u32_t ident[4] input
+ * @param ip points to output struct
+ */
+u8_t
+snmp_oid_to_ip4(const u32_t *oid, ip4_addr_t *ip)
+{
+  if ((oid[0] > 0xFF) ||
+      (oid[1] > 0xFF) ||
+      (oid[2] > 0xFF) ||
+      (oid[3] > 0xFF)) {
+    ip4_addr_copy(*ip, *IP4_ADDR_ANY4);
+    return 0;
+  }
+
+  IP4_ADDR(ip, oid[0], oid[1], oid[2], oid[3]);
+  return 1;
+}
+
+/**
+ * Convert ip4_addr to InetAddressIPv4 (no InetAddressType)
+ * @param ip points to input struct
+ * @param oid points to u32_t ident[4] output
+ */
+void
+snmp_ip4_to_oid(const ip4_addr_t *ip, u32_t *oid)
+{
+  oid[0] = ip4_addr1(ip);
+  oid[1] = ip4_addr2(ip);
+  oid[2] = ip4_addr3(ip);
+  oid[3] = ip4_addr4(ip);
+}
+#endif /* LWIP_IPV4 */
+
+#if LWIP_IPV6
+/**
+ * Conversion from InetAddressIPv6 oid to lwIP ip6_addr
+ * @param oid points to u32_t oid[16] input
+ * @param ip points to output struct
+ */
+u8_t
+snmp_oid_to_ip6(const u32_t *oid, ip6_addr_t *ip)
+{
+  if ((oid[0]  > 0xFF) ||
+      (oid[1]  > 0xFF) ||
+      (oid[2]  > 0xFF) ||
+      (oid[3]  > 0xFF) ||
+      (oid[4]  > 0xFF) ||
+      (oid[5]  > 0xFF) ||
+      (oid[6]  > 0xFF) ||
+      (oid[7]  > 0xFF) ||
+      (oid[8]  > 0xFF) ||
+      (oid[9]  > 0xFF) ||
+      (oid[10] > 0xFF) ||
+      (oid[11] > 0xFF) ||
+      (oid[12] > 0xFF) ||
+      (oid[13] > 0xFF) ||
+      (oid[14] > 0xFF) ||
+      (oid[15] > 0xFF)) {
+    ip6_addr_set_any(ip);
+    return 0;
+  }
+
+  ip->addr[0] = (oid[0]  << 24) | (oid[1]  << 16) | (oid[2]  << 8) | (oid[3]  << 0);
+  ip->addr[1] = (oid[4]  << 24) | (oid[5]  << 16) | (oid[6]  << 8) | (oid[7]  << 0);
+  ip->addr[2] = (oid[8]  << 24) | (oid[9]  << 16) | (oid[10] << 8) | (oid[11] << 0);
+  ip->addr[3] = (oid[12] << 24) | (oid[13] << 16) | (oid[14] << 8) | (oid[15] << 0);
+  return 1;
+}
+
+/**
+ * Convert ip6_addr to InetAddressIPv6 (no InetAddressType)
+ * @param ip points to input struct
+ * @param oid points to u32_t ident[16] output
+ */
+void
+snmp_ip6_to_oid(const ip6_addr_t *ip, u32_t *oid)
+{
+  oid[0]  = (ip->addr[0] & 0xFF000000) >> 24;
+  oid[1]  = (ip->addr[0] & 0x00FF0000) >> 16;
+  oid[2]  = (ip->addr[0] & 0x0000FF00) >>  8;
+  oid[3]  = (ip->addr[0] & 0x000000FF) >>  0;
+  oid[4]  = (ip->addr[1] & 0xFF000000) >> 24;
+  oid[5]  = (ip->addr[1] & 0x00FF0000) >> 16;
+  oid[6]  = (ip->addr[1] & 0x0000FF00) >>  8;
+  oid[7]  = (ip->addr[1] & 0x000000FF) >>  0;
+  oid[8]  = (ip->addr[2] & 0xFF000000) >> 24;
+  oid[9]  = (ip->addr[2] & 0x00FF0000) >> 16;
+  oid[10] = (ip->addr[2] & 0x0000FF00) >>  8;
+  oid[11] = (ip->addr[2] & 0x000000FF) >>  0;
+  oid[12] = (ip->addr[3] & 0xFF000000) >> 24;
+  oid[13] = (ip->addr[3] & 0x00FF0000) >> 16;
+  oid[14] = (ip->addr[3] & 0x0000FF00) >>  8;
+  oid[15] = (ip->addr[3] & 0x000000FF) >>  0;
+}
+#endif /* LWIP_IPV6 */
+
+#if LWIP_IPV4 || LWIP_IPV6
+/**
+ * Convert to InetAddressType+InetAddress+InetPortNumber
+ * @param ip IP address
+ * @param port Port
+ * @param oid OID
+ * @return OID length
+ */
+u8_t
+snmp_ip_port_to_oid(const ip_addr_t *ip, u16_t port, u32_t *oid)
+{
+  u8_t idx;
+
+  idx = snmp_ip_to_oid(ip, oid);
+  oid[idx] = port;
+  idx++;
+
+  return idx;
+}
+
+/**
+ * Convert to InetAddressType+InetAddress
+ * @param ip IP address
+ * @param oid OID
+ * @return OID length
+ */
+u8_t
+snmp_ip_to_oid(const ip_addr_t *ip, u32_t *oid)
+{
+  if (IP_IS_ANY_TYPE_VAL(*ip)) {
+    oid[0] = 0; /* any */
+    oid[1] = 0; /* no IP OIDs follow */
+    return 2;
+  } else if (IP_IS_V6(ip)) {
+#if LWIP_IPV6
+    oid[0] = 2; /* ipv6 */
+    oid[1] = 16; /* 16 InetAddressIPv6 OIDs follow */
+    snmp_ip6_to_oid(ip_2_ip6(ip), &oid[2]);
+    return 18;
+#else /* LWIP_IPV6 */
+    return 0;
+#endif /* LWIP_IPV6 */
+  } else {
+#if LWIP_IPV4
+    oid[0] = 1; /* ipv4 */
+    oid[1] = 4; /* 4 InetAddressIPv4 OIDs follow */
+    snmp_ip4_to_oid(ip_2_ip4(ip), &oid[2]);
+    return 6;
+#else /* LWIP_IPV4 */
+    return 0;
+#endif /* LWIP_IPV4 */
+  }
+}
+
+/**
+ * Convert from InetAddressType+InetAddress to ip_addr_t
+ * @param oid OID
+ * @param oid_len OID length
+ * @param ip IP address
+ * @return Parsed OID length
+ */
+u8_t
+snmp_oid_to_ip(const u32_t *oid, u8_t oid_len, ip_addr_t *ip)
+{
+  /* InetAddressType */
+  if (oid_len < 1) {
+    return 0;
+  }
+
+  if (oid[0] == 0) { /* any */
+    /* 1x InetAddressType, 1x OID len */
+    if (oid_len < 2) {
+      return 0;
+    }
+    if (oid[1] != 0) {
+      return 0;
+    }
+
+    memset(ip, 0, sizeof(*ip));
+    IP_SET_TYPE(ip, IPADDR_TYPE_ANY);
+
+    return 2;
+  } else if (oid[0] == 1) { /* ipv4 */
+#if LWIP_IPV4
+    /* 1x InetAddressType, 1x OID len, 4x InetAddressIPv4 */
+    if (oid_len < 6) {
+      return 0;
+    }
+
+    /* 4x ipv4 OID */
+    if (oid[1] != 4) {
+      return 0;
+    }
+
+    IP_SET_TYPE(ip, IPADDR_TYPE_V4);
+    if (!snmp_oid_to_ip4(&oid[2], ip_2_ip4(ip))) {
+      return 0;
+    }
+
+    return 6;
+#else /* LWIP_IPV4 */
+    return 0;
+#endif /* LWIP_IPV4 */
+  } else if (oid[0] == 2) { /* ipv6 */
+#if LWIP_IPV6
+    /* 1x InetAddressType, 1x OID len, 16x InetAddressIPv6 */
+    if (oid_len < 18) {
+      return 0;
+    }
+
+    /* 16x ipv6 OID */
+    if (oid[1] != 16) {
+      return 0;
+    }
+
+    IP_SET_TYPE(ip, IPADDR_TYPE_V6);
+    if (!snmp_oid_to_ip6(&oid[2], ip_2_ip6(ip))) {
+      return 0;
+    }
+
+    return 18;
+#else /* LWIP_IPV6 */
+    return 0;
+#endif /* LWIP_IPV6 */
+  } else { /* unsupported InetAddressType */
+    return 0;
+  }
+}
+
+/**
+ * Convert from InetAddressType+InetAddress+InetPortNumber to ip_addr_t and u16_t
+ * @param oid OID
+ * @param oid_len OID length
+ * @param ip IP address
+ * @param port Port
+ * @return Parsed OID length
+ */
+u8_t
+snmp_oid_to_ip_port(const u32_t *oid, u8_t oid_len, ip_addr_t *ip, u16_t *port)
+{
+  u8_t idx;
+
+  /* InetAddressType + InetAddress */
+  idx = snmp_oid_to_ip(&oid[0], oid_len, ip);
+  if (idx == 0) {
+    return 0;
+  }
+
+  /* InetPortNumber */
+  if (oid_len < (idx + 1)) {
+    return 0;
+  }
+  if (oid[idx] > 0xffff) {
+    return 0;
+  }
+  *port = (u16_t)oid[idx];
+  idx++;
+
+  return idx;
+}
+
+#endif /* LWIP_IPV4 || LWIP_IPV6 */
+
+/**
+ * Assign an OID to struct snmp_obj_id
+ * @param target Assignment target
+ * @param oid OID
+ * @param oid_len OID length
+ */
+void
+snmp_oid_assign(struct snmp_obj_id *target, const u32_t *oid, u8_t oid_len)
+{
+  LWIP_ASSERT("oid_len <= SNMP_MAX_OBJ_ID_LEN", oid_len <= SNMP_MAX_OBJ_ID_LEN);
+
+  target->len = oid_len;
+
+  if (oid_len > 0) {
+    MEMCPY(target->id, oid, oid_len * sizeof(u32_t));
+  }
+}
+
+/**
+ * Prefix an OID to OID in struct snmp_obj_id
+ * @param target Assignment target to prefix
+ * @param oid OID
+ * @param oid_len OID length
+ */
+void
+snmp_oid_prefix(struct snmp_obj_id *target, const u32_t *oid, u8_t oid_len)
+{
+  LWIP_ASSERT("target->len + oid_len <= SNMP_MAX_OBJ_ID_LEN", (target->len + oid_len) <= SNMP_MAX_OBJ_ID_LEN);
+
+  if (oid_len > 0) {
+    /* move existing OID to make room at the beginning for OID to insert */
+    int i;
+    for (i = target->len - 1; i >= 0; i--) {
+      target->id[i + oid_len] = target->id[i];
+    }
+
+    /* paste oid at the beginning */
+    MEMCPY(target->id, oid, oid_len * sizeof(u32_t));
+  }
+}
+
+/**
+ * Combine two OIDs into struct snmp_obj_id
+ * @param target Assignmet target
+ * @param oid1 OID 1
+ * @param oid1_len OID 1 length
+ * @param oid2 OID 2
+ * @param oid2_len OID 2 length
+ */
+void
+snmp_oid_combine(struct snmp_obj_id *target, const u32_t *oid1, u8_t oid1_len, const u32_t *oid2, u8_t oid2_len)
+{
+  snmp_oid_assign(target, oid1, oid1_len);
+  snmp_oid_append(target, oid2, oid2_len);
+}
+
+/**
+ * Append OIDs to struct snmp_obj_id
+ * @param target Assignment target to append to
+ * @param oid OID
+ * @param oid_len OID length
+ */
+void
+snmp_oid_append(struct snmp_obj_id *target, const u32_t *oid, u8_t oid_len)
+{
+  LWIP_ASSERT("offset + oid_len <= SNMP_MAX_OBJ_ID_LEN", (target->len + oid_len) <= SNMP_MAX_OBJ_ID_LEN);
+
+  if (oid_len > 0) {
+    MEMCPY(&target->id[target->len], oid, oid_len * sizeof(u32_t));
+    target->len = (u8_t)(target->len + oid_len);
+  }
+}
+
+/**
+ * Compare two OIDs
+ * @param oid1 OID 1
+ * @param oid1_len OID 1 length
+ * @param oid2 OID 2
+ * @param oid2_len OID 2 length
+ * @return -1: OID1&lt;OID2  1: OID1 &gt;OID2 0: equal
+ */
+s8_t
+snmp_oid_compare(const u32_t *oid1, u8_t oid1_len, const u32_t *oid2, u8_t oid2_len)
+{
+  u8_t level = 0;
+  LWIP_ASSERT("'oid1' param must not be NULL or 'oid1_len' param be 0!", (oid1 != NULL) || (oid1_len == 0));
+  LWIP_ASSERT("'oid2' param must not be NULL or 'oid2_len' param be 0!", (oid2 != NULL) || (oid2_len == 0));
+
+  while ((level < oid1_len) && (level < oid2_len)) {
+    if (*oid1 < *oid2) {
+      return -1;
+    }
+    if (*oid1 > *oid2) {
+      return 1;
+    }
+
+    level++;
+    oid1++;
+    oid2++;
+  }
+
+  /* common part of both OID's is equal, compare length */
+  if (oid1_len < oid2_len) {
+    return -1;
+  }
+  if (oid1_len > oid2_len) {
+    return 1;
+  }
+
+  /* they are equal */
+  return 0;
+}
+
+
+/**
+ * Check of two OIDs are equal
+ * @param oid1 OID 1
+ * @param oid1_len OID 1 length
+ * @param oid2 OID 2
+ * @param oid2_len OID 2 length
+ * @return 1: equal 0: non-equal
+ */
+u8_t
+snmp_oid_equal(const u32_t *oid1, u8_t oid1_len, const u32_t *oid2, u8_t oid2_len)
+{
+  return (snmp_oid_compare(oid1, oid1_len, oid2, oid2_len) == 0) ? 1 : 0;
+}
+
+/**
+ * Convert netif to interface index
+ * @param netif netif
+ * @return index
+ */
+u8_t
+netif_to_num(const struct netif *netif)
+{
+  return netif_get_index(netif);
+}
+
+static const struct snmp_mib *
+snmp_get_mib_from_oid(const u32_t *oid, u8_t oid_len)
+{
+  const u32_t *list_oid;
+  const u32_t *searched_oid;
+  u8_t i, l;
+
+  u8_t max_match_len = 0;
+  const struct snmp_mib *matched_mib = NULL;
+
+  LWIP_ASSERT("'oid' param must not be NULL!", (oid != NULL));
+
+  if (oid_len == 0) {
+    return NULL;
+  }
+
+  for (i = 0; i < snmp_num_mibs; i++) {
+    LWIP_ASSERT("MIB array not initialized correctly", (snmp_mibs[i] != NULL));
+    LWIP_ASSERT("MIB array not initialized correctly - base OID is NULL", (snmp_mibs[i]->base_oid != NULL));
+
+    if (oid_len >= snmp_mibs[i]->base_oid_len) {
+      l            = snmp_mibs[i]->base_oid_len;
+      list_oid     = snmp_mibs[i]->base_oid;
+      searched_oid = oid;
+
+      while (l > 0) {
+        if (*list_oid != *searched_oid) {
+          break;
+        }
+
+        l--;
+        list_oid++;
+        searched_oid++;
+      }
+
+      if ((l == 0) && (snmp_mibs[i]->base_oid_len > max_match_len)) {
+        max_match_len = snmp_mibs[i]->base_oid_len;
+        matched_mib = snmp_mibs[i];
+      }
+    }
+  }
+
+  return matched_mib;
+}
+
+static const struct snmp_mib *
+snmp_get_next_mib(const u32_t *oid, u8_t oid_len)
+{
+  u8_t i;
+  const struct snmp_mib *next_mib = NULL;
+
+  LWIP_ASSERT("'oid' param must not be NULL!", (oid != NULL));
+
+  if (oid_len == 0) {
+    return NULL;
+  }
+
+  for (i = 0; i < snmp_num_mibs; i++) {
+    if (snmp_mibs[i]->base_oid != NULL) {
+      /* check if mib is located behind starting point */
+      if (snmp_oid_compare(snmp_mibs[i]->base_oid, snmp_mibs[i]->base_oid_len, oid, oid_len) > 0) {
+        if ((next_mib == NULL) ||
+            (snmp_oid_compare(snmp_mibs[i]->base_oid, snmp_mibs[i]->base_oid_len,
+                              next_mib->base_oid, next_mib->base_oid_len) < 0)) {
+          next_mib = snmp_mibs[i];
+        }
+      }
+    }
+  }
+
+  return next_mib;
+}
+
+static const struct snmp_mib *
+snmp_get_mib_between(const u32_t *oid1, u8_t oid1_len, const u32_t *oid2, u8_t oid2_len)
+{
+  const struct snmp_mib *next_mib = snmp_get_next_mib(oid1, oid1_len);
+
+  LWIP_ASSERT("'oid2' param must not be NULL!", (oid2 != NULL));
+  LWIP_ASSERT("'oid2_len' param must be greater than 0!", (oid2_len > 0));
+
+  if (next_mib != NULL) {
+    if (snmp_oid_compare(next_mib->base_oid, next_mib->base_oid_len, oid2, oid2_len) < 0) {
+      return next_mib;
+    }
+  }
+
+  return NULL;
+}
+
+u8_t
+snmp_get_node_instance_from_oid(const u32_t *oid, u8_t oid_len, struct snmp_node_instance *node_instance)
+{
+  u8_t result = SNMP_ERR_NOSUCHOBJECT;
+  const struct snmp_mib *mib;
+  const struct snmp_node *mn = NULL;
+
+  mib = snmp_get_mib_from_oid(oid, oid_len);
+  if (mib != NULL) {
+    u8_t oid_instance_len;
+
+    mn = snmp_mib_tree_resolve_exact(mib, oid, oid_len, &oid_instance_len);
+    if ((mn != NULL) && (mn->node_type != SNMP_NODE_TREE)) {
+      /* get instance */
+      const struct snmp_leaf_node *leaf_node = (const struct snmp_leaf_node *)(const void *)mn;
+
+      node_instance->node = mn;
+      snmp_oid_assign(&node_instance->instance_oid, oid + (oid_len - oid_instance_len), oid_instance_len);
+
+      result = leaf_node->get_instance(
+                 oid,
+                 oid_len - oid_instance_len,
+                 node_instance);
+
+#ifdef LWIP_DEBUG
+      if (result == SNMP_ERR_NOERROR) {
+        if (((node_instance->access & SNMP_NODE_INSTANCE_ACCESS_READ) != 0) && (node_instance->get_value == NULL)) {
+          LWIP_DEBUGF(SNMP_DEBUG, ("SNMP inconsistent access: node is readable but no get_value function is specified\n"));
+        }
+        if (((node_instance->access & SNMP_NODE_INSTANCE_ACCESS_WRITE) != 0) && (node_instance->set_value == NULL)) {
+          LWIP_DEBUGF(SNMP_DEBUG, ("SNMP inconsistent access: node is writable but no set_value and/or set_test function is specified\n"));
+        }
+      }
+#endif
+    }
+  }
+
+  return result;
+}
+
+u8_t
+snmp_get_next_node_instance_from_oid(const u32_t *oid, u8_t oid_len, snmp_validate_node_instance_method validate_node_instance_method, void *validate_node_instance_arg, struct snmp_obj_id *node_oid, struct snmp_node_instance *node_instance)
+{
+  const struct snmp_mib      *mib;
+  const struct snmp_node *mn = NULL;
+  const u32_t *start_oid     = NULL;
+  u8_t         start_oid_len = 0;
+
+  /* resolve target MIB from passed OID */
+  mib = snmp_get_mib_from_oid(oid, oid_len);
+  if (mib == NULL) {
+    /* passed OID does not reference any known MIB, start at the next closest MIB */
+    mib = snmp_get_next_mib(oid, oid_len);
+
+    if (mib != NULL) {
+      start_oid     = mib->base_oid;
+      start_oid_len = mib->base_oid_len;
+    }
+  } else {
+    start_oid     = oid;
+    start_oid_len = oid_len;
+  }
+
+  /* resolve target node from MIB, skip to next MIB if no suitable node is found in current MIB */
+  while ((mib != NULL) && (mn == NULL)) {
+    u8_t oid_instance_len;
+
+    /* check if OID directly references a node inside current MIB, in this case we have to ask this node for the next instance */
+    mn = snmp_mib_tree_resolve_exact(mib, start_oid, start_oid_len, &oid_instance_len);
+    if (mn != NULL) {
+      snmp_oid_assign(node_oid, start_oid, start_oid_len - oid_instance_len); /* set oid to node */
+      snmp_oid_assign(&node_instance->instance_oid, start_oid + (start_oid_len - oid_instance_len), oid_instance_len); /* set (relative) instance oid */
+    } else {
+      /* OID does not reference a node, search for the next closest node inside MIB; set instance_oid.len to zero because we want the first instance of this node */
+      mn = snmp_mib_tree_resolve_next(mib, start_oid, start_oid_len, node_oid);
+      node_instance->instance_oid.len = 0;
+    }
+
+    /* validate the node; if the node has no further instance or the returned instance is invalid, search for the next in MIB and validate again */
+    node_instance->node = mn;
+    while (mn != NULL) {
+      u8_t result;
+
+      /* clear fields which may have values from previous loops */
+      node_instance->asn1_type        = 0;
+      node_instance->access           = SNMP_NODE_INSTANCE_NOT_ACCESSIBLE;
+      node_instance->get_value        = NULL;
+      node_instance->set_test         = NULL;
+      node_instance->set_value        = NULL;
+      node_instance->release_instance = NULL;
+      node_instance->reference.ptr    = NULL;
+      node_instance->reference_len    = 0;
+
+      result = ((const struct snmp_leaf_node *)(const void *)mn)->get_next_instance(
+                 node_oid->id,
+                 node_oid->len,
+                 node_instance);
+
+      if (result == SNMP_ERR_NOERROR) {
+#ifdef LWIP_DEBUG
+        if (((node_instance->access & SNMP_NODE_INSTANCE_ACCESS_READ) != 0) && (node_instance->get_value == NULL)) {
+          LWIP_DEBUGF(SNMP_DEBUG, ("SNMP inconsistent access: node is readable but no get_value function is specified\n"));
+        }
+        if (((node_instance->access & SNMP_NODE_INSTANCE_ACCESS_WRITE) != 0) && (node_instance->set_value == NULL)) {
+          LWIP_DEBUGF(SNMP_DEBUG, ("SNMP inconsistent access: node is writable but no set_value function is specified\n"));
+        }
+#endif
+
+        /* validate node because the node may be not accessible for example (but let the caller decide what is valid */
+        if ((validate_node_instance_method == NULL) ||
+            (validate_node_instance_method(node_instance, validate_node_instance_arg) == SNMP_ERR_NOERROR)) {
+          /* node_oid "returns" the full result OID (including the instance part) */
+          snmp_oid_append(node_oid, node_instance->instance_oid.id, node_instance->instance_oid.len);
+          break;
+        }
+
+        if (node_instance->release_instance != NULL) {
+          node_instance->release_instance(node_instance);
+        }
+        /*
+        the instance itself is not valid, ask for next instance from same node.
+        we don't have to change any variables because node_instance->instance_oid is used as input (starting point)
+        as well as output (resulting next OID), so we have to simply call get_next_instance method again
+        */
+      } else {
+        if (node_instance->release_instance != NULL) {
+          node_instance->release_instance(node_instance);
+        }
+
+        /* the node has no further instance, skip to next node */
+        mn = snmp_mib_tree_resolve_next(mib, node_oid->id, node_oid->len, &node_instance->instance_oid); /* misuse node_instance->instance_oid as tmp buffer */
+        if (mn != NULL) {
+          /* prepare for next loop */
+          snmp_oid_assign(node_oid, node_instance->instance_oid.id, node_instance->instance_oid.len);
+          node_instance->instance_oid.len = 0;
+          node_instance->node = mn;
+        }
+      }
+    }
+
+    if (mn != NULL) {
+      /*
+      we found a suitable next node,
+      now we have to check if a inner MIB is located between the searched OID and the resulting OID.
+      this is possible because MIB's may be located anywhere in the global tree, that means also in
+      the subtree of another MIB (e.g. if searched OID is .2 and resulting OID is .4, then another
+      MIB having .3 as root node may exist)
+      */
+      const struct snmp_mib *intermediate_mib;
+      intermediate_mib = snmp_get_mib_between(start_oid, start_oid_len, node_oid->id, node_oid->len);
+
+      if (intermediate_mib != NULL) {
+        /* search for first node inside intermediate mib in next loop */
+        if (node_instance->release_instance != NULL) {
+          node_instance->release_instance(node_instance);
+        }
+
+        mn            = NULL;
+        mib           = intermediate_mib;
+        start_oid     = mib->base_oid;
+        start_oid_len = mib->base_oid_len;
+      }
+      /* else { we found out target node } */
+    } else {
+      /*
+      there is no further (suitable) node inside this MIB, search for the next MIB with following priority
+      1. search for inner MIB's (whose root is located inside tree of current MIB)
+      2. search for surrouding MIB's (where the current MIB is the inner MIB) and continue there if any
+      3. take the next closest MIB (not being related to the current MIB)
+      */
+      const struct snmp_mib *next_mib;
+      next_mib = snmp_get_next_mib(start_oid, start_oid_len); /* returns MIB's related to point 1 and 3 */
+
+      /* is the found MIB an inner MIB? (point 1) */
+      if ((next_mib != NULL) && (next_mib->base_oid_len > mib->base_oid_len) &&
+          (snmp_oid_compare(next_mib->base_oid, mib->base_oid_len, mib->base_oid, mib->base_oid_len) == 0)) {
+        /* yes it is -> continue at inner MIB */
+        mib = next_mib;
+        start_oid     = mib->base_oid;
+        start_oid_len = mib->base_oid_len;
+      } else {
+        /* check if there is a surrounding mib where to continue (point 2) (only possible if OID length > 1) */
+        if (mib->base_oid_len > 1) {
+          mib = snmp_get_mib_from_oid(mib->base_oid, mib->base_oid_len - 1);
+
+          if (mib == NULL) {
+            /* no surrounding mib, use next mib encountered above (point 3) */
+            mib = next_mib;
+
+            if (mib != NULL) {
+              start_oid     = mib->base_oid;
+              start_oid_len = mib->base_oid_len;
+            }
+          }
+          /* else { start_oid stays the same because we want to continue from current offset in surrounding mib (point 2) } */
+        }
+      }
+    }
+  }
+
+  if (mib == NULL) {
+    /* loop is only left when mib == null (error) or mib_node != NULL (success) */
+    return SNMP_ERR_ENDOFMIBVIEW;
+  }
+
+  return SNMP_ERR_NOERROR;
+}
+
+/**
+ * Searches tree for the supplied object identifier.
+ *
+ */
+const struct snmp_node *
+snmp_mib_tree_resolve_exact(const struct snmp_mib *mib, const u32_t *oid, u8_t oid_len, u8_t *oid_instance_len)
+{
+  const struct snmp_node *const *node = &mib->root_node;
+  u8_t oid_offset = mib->base_oid_len;
+
+  while ((oid_offset < oid_len) && ((*node)->node_type == SNMP_NODE_TREE)) {
+    /* search for matching sub node */
+    u32_t subnode_oid = *(oid + oid_offset);
+
+    u32_t i = (*(const struct snmp_tree_node * const *)node)->subnode_count;
+    node    = (*(const struct snmp_tree_node * const *)node)->subnodes;
+    while ((i > 0) && ((*node)->oid != subnode_oid)) {
+      node++;
+      i--;
+    }
+
+    if (i == 0) {
+      /* no matching subnode found */
+      return NULL;
+    }
+
+    oid_offset++;
+  }
+
+  if ((*node)->node_type != SNMP_NODE_TREE) {
+    /* we found a leaf node */
+    *oid_instance_len = oid_len - oid_offset;
+    return (*node);
+  }
+
+  return NULL;
+}
+
+const struct snmp_node *
+snmp_mib_tree_resolve_next(const struct snmp_mib *mib, const u32_t *oid, u8_t oid_len, struct snmp_obj_id *oidret)
+{
+  u8_t  oid_offset = mib->base_oid_len;
+  const struct snmp_node *const *node;
+  const struct snmp_tree_node *node_stack[SNMP_MAX_OBJ_ID_LEN];
+  s32_t nsi = 0; /* NodeStackIndex */
+  u32_t subnode_oid;
+
+  if (mib->root_node->node_type != SNMP_NODE_TREE) {
+    /* a next operation on a mib with only a leaf node will always return NULL because there is no other node */
+    return NULL;
+  }
+
+  /* first build node stack related to passed oid (as far as possible), then go backwards to determine the next node */
+  node_stack[nsi] = (const struct snmp_tree_node *)(const void *)mib->root_node;
+  while (oid_offset < oid_len) {
+    /* search for matching sub node */
+    u32_t i = node_stack[nsi]->subnode_count;
+    node    = node_stack[nsi]->subnodes;
+
+    subnode_oid = *(oid + oid_offset);
+
+    while ((i > 0) && ((*node)->oid != subnode_oid)) {
+      node++;
+      i--;
+    }
+
+    if ((i == 0) || ((*node)->node_type != SNMP_NODE_TREE)) {
+      /* no (matching) tree-subnode found */
+      break;
+    }
+    nsi++;
+    node_stack[nsi] = (const struct snmp_tree_node *)(const void *)(*node);
+
+    oid_offset++;
+  }
+
+
+  if (oid_offset >= oid_len) {
+    /* passed oid references a tree node -> return first useable sub node of it */
+    subnode_oid = 0;
+  } else {
+    subnode_oid = *(oid + oid_offset) + 1;
+  }
+
+  while (nsi >= 0) {
+    const struct snmp_node *subnode = NULL;
+
+    /* find next node on current level */
+    s32_t i        = node_stack[nsi]->subnode_count;
+    node           = node_stack[nsi]->subnodes;
+    while (i > 0) {
+      if ((*node)->oid == subnode_oid) {
+        subnode = *node;
+        break;
+      } else if (((*node)->oid > subnode_oid) && ((subnode == NULL) || ((*node)->oid < subnode->oid))) {
+        subnode = *node;
+      }
+
+      node++;
+      i--;
+    }
+
+    if (subnode == NULL) {
+      /* no further node found on this level, go one level up and start searching with index of current node*/
+      subnode_oid = node_stack[nsi]->node.oid + 1;
+      nsi--;
+    } else {
+      if (subnode->node_type == SNMP_NODE_TREE) {
+        /* next is a tree node, go into it and start searching */
+        nsi++;
+        node_stack[nsi] = (const struct snmp_tree_node *)(const void *)subnode;
+        subnode_oid = 0;
+      } else {
+        /* we found a leaf node -> fill oidret and return it */
+        snmp_oid_assign(oidret, mib->base_oid, mib->base_oid_len);
+        i = 1;
+        while (i <= nsi) {
+          oidret->id[oidret->len] = node_stack[i]->node.oid;
+          oidret->len++;
+          i++;
+        }
+
+        oidret->id[oidret->len] = subnode->oid;
+        oidret->len++;
+
+        return subnode;
+      }
+    }
+  }
+
+  return NULL;
+}
+
+/** initialize struct next_oid_state using this function before passing it to next_oid_check */
+void
+snmp_next_oid_init(struct snmp_next_oid_state *state,
+                   const u32_t *start_oid, u8_t start_oid_len,
+                   u32_t *next_oid_buf, u8_t next_oid_max_len)
+{
+  state->start_oid        = start_oid;
+  state->start_oid_len    = start_oid_len;
+  state->next_oid         = next_oid_buf;
+  state->next_oid_len     = 0;
+  state->next_oid_max_len = next_oid_max_len;
+  state->status           = SNMP_NEXT_OID_STATUS_NO_MATCH;
+}
+
+/** checks if the passed incomplete OID may be a possible candidate for snmp_next_oid_check();
+this methid is intended if the complete OID is not yet known but it is very expensive to build it up,
+so it is possible to test the starting part before building up the complete oid and pass it to snmp_next_oid_check()*/
+u8_t
+snmp_next_oid_precheck(struct snmp_next_oid_state *state, const u32_t *oid, u8_t oid_len)
+{
+  if (state->status != SNMP_NEXT_OID_STATUS_BUF_TO_SMALL) {
+    u8_t start_oid_len = (oid_len < state->start_oid_len) ? oid_len : state->start_oid_len;
+
+    /* check passed OID is located behind start offset */
+    if (snmp_oid_compare(oid, oid_len, state->start_oid, start_oid_len) >= 0) {
+      /* check if new oid is located closer to start oid than current closest oid */
+      if ((state->status == SNMP_NEXT_OID_STATUS_NO_MATCH) ||
+          (snmp_oid_compare(oid, oid_len, state->next_oid, state->next_oid_len) < 0)) {
+        return 1;
+      }
+    }
+  }
+
+  return 0;
+}
+
+/** checks the passed OID if it is a candidate to be the next one (get_next); returns !=0 if passed oid is currently closest, otherwise 0 */
+u8_t
+snmp_next_oid_check(struct snmp_next_oid_state *state, const u32_t *oid, u8_t oid_len, void *reference)
+{
+  /* do not overwrite a fail result */
+  if (state->status != SNMP_NEXT_OID_STATUS_BUF_TO_SMALL) {
+    /* check passed OID is located behind start offset */
+    if (snmp_oid_compare(oid, oid_len, state->start_oid, state->start_oid_len) > 0) {
+      /* check if new oid is located closer to start oid than current closest oid */
+      if ((state->status == SNMP_NEXT_OID_STATUS_NO_MATCH) ||
+          (snmp_oid_compare(oid, oid_len, state->next_oid, state->next_oid_len) < 0)) {
+        if (oid_len <= state->next_oid_max_len) {
+          MEMCPY(state->next_oid, oid, oid_len * sizeof(u32_t));
+          state->next_oid_len = oid_len;
+          state->status       = SNMP_NEXT_OID_STATUS_SUCCESS;
+          state->reference    = reference;
+          return 1;
+        } else {
+          state->status = SNMP_NEXT_OID_STATUS_BUF_TO_SMALL;
+        }
+      }
+    }
+  }
+
+  return 0;
+}
+
+u8_t
+snmp_oid_in_range(const u32_t *oid_in, u8_t oid_len, const struct snmp_oid_range *oid_ranges, u8_t oid_ranges_len)
+{
+  u8_t i;
+
+  if (oid_len != oid_ranges_len) {
+    return 0;
+  }
+
+  for (i = 0; i < oid_ranges_len; i++) {
+    if ((oid_in[i] < oid_ranges[i].min) || (oid_in[i] > oid_ranges[i].max)) {
+      return 0;
+    }
+  }
+
+  return 1;
+}
+
+snmp_err_t
+snmp_set_test_ok(struct snmp_node_instance *instance, u16_t value_len, void *value)
+{
+  LWIP_UNUSED_ARG(instance);
+  LWIP_UNUSED_ARG(value_len);
+  LWIP_UNUSED_ARG(value);
+
+  return SNMP_ERR_NOERROR;
+}
+
+/**
+ * Decodes BITS pseudotype value from ASN.1 OctetString.
+ *
+ * @note Because BITS pseudo type is encoded as OCTET STRING, it cannot directly
+ * be encoded/decoded by the agent. Instead call this function as required from
+ * get/test/set methods.
+ *
+ * @param buf points to a buffer holding the ASN1 octet string
+ * @param buf_len length of octet string
+ * @param bit_value decoded Bit value with Bit0 == LSB
+ * @return ERR_OK if successful, ERR_ARG if bit value contains more than 32 bit
+ */
+err_t
+snmp_decode_bits(const u8_t *buf, u32_t buf_len, u32_t *bit_value)
+{
+  u8_t b;
+  u8_t bits_processed = 0;
+  *bit_value = 0;
+
+  while (buf_len > 0) {
+    /* any bit set in this byte? */
+    if (*buf != 0x00) {
+      if (bits_processed >= 32) {
+        /* accept more than 4 bytes, but only when no bits are set */
+        return ERR_VAL;
+      }
+
+      b = *buf;
+      do {
+        if (b & 0x80) {
+          *bit_value |= (1 << bits_processed);
+        }
+        bits_processed++;
+        b <<= 1;
+      } while ((bits_processed & 0x07) != 0); /* &0x07 -> % 8 */
+    } else {
+      bits_processed += 8;
+    }
+
+    buf_len--;
+    buf++;
+  }
+
+  return ERR_OK;
+}
+
+err_t
+snmp_decode_truthvalue(const s32_t *asn1_value, u8_t *bool_value)
+{
+  /* defined by RFC1443:
+   TruthValue ::= TEXTUAL-CONVENTION
+    STATUS       current
+    DESCRIPTION
+     "Represents a boolean value."
+    SYNTAX       INTEGER { true(1), false(2) }
+  */
+
+  if ((asn1_value == NULL) || (bool_value == NULL)) {
+    return ERR_ARG;
+  }
+
+  if (*asn1_value == 1) {
+    *bool_value = 1;
+  } else if (*asn1_value == 2) {
+    *bool_value = 0;
+  } else {
+    return ERR_VAL;
+  }
+
+  return ERR_OK;
+}
+
+/**
+ * Encodes BITS pseudotype value into ASN.1 OctetString.
+ *
+ * @note Because BITS pseudo type is encoded as OCTET STRING, it cannot directly
+ * be encoded/decoded by the agent. Instead call this function as required from
+ * get/test/set methods.
+ *
+ * @param buf points to a buffer where the resulting ASN1 octet string is stored to
+ * @param buf_len max length of the bufffer
+ * @param bit_value Bit value to encode with Bit0 == LSB
+ * @param bit_count Number of possible bits for the bit value (according to rfc we have to send all bits independant from their truth value)
+ * @return number of bytes used from buffer to store the resulting OctetString
+ */
+u8_t
+snmp_encode_bits(u8_t *buf, u32_t buf_len, u32_t bit_value, u8_t bit_count)
+{
+  u8_t len = 0;
+  u8_t min_bytes = (bit_count + 7) >> 3; /* >>3 -> / 8 */
+
+  while ((buf_len > 0) && (bit_value != 0x00)) {
+    s8_t i = 7;
+    *buf = 0x00;
+    while (i >= 0) {
+      if (bit_value & 0x01) {
+        *buf |= 0x01;
+      }
+
+      if (i > 0) {
+        *buf <<= 1;
+      }
+
+      bit_value >>= 1;
+      i--;
+    }
+
+    buf++;
+    buf_len--;
+    len++;
+  }
+
+  if (len < min_bytes) {
+    buf     += len;
+    buf_len -= len;
+
+    while ((len < min_bytes) && (buf_len > 0)) {
+      *buf = 0x00;
+      buf++;
+      buf_len--;
+      len++;
+    }
+  }
+
+  return len;
+}
+
+u8_t
+snmp_encode_truthvalue(s32_t *asn1_value, u32_t bool_value)
+{
+  /* defined by RFC1443:
+   TruthValue ::= TEXTUAL-CONVENTION
+    STATUS       current
+    DESCRIPTION
+     "Represents a boolean value."
+    SYNTAX       INTEGER { true(1), false(2) }
+  */
+
+  if (asn1_value == NULL) {
+    return 0;
+  }
+
+  if (bool_value) {
+    *asn1_value = 1; /* defined by RFC1443 */
+  } else {
+    *asn1_value = 2; /* defined by RFC1443 */
+  }
+
+  return sizeof(s32_t);
+}
+
+#endif /* LWIP_SNMP */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/apps/snmp/snmp_core_priv.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/apps/snmp/snmp_core_priv.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/apps/snmp/snmp_core_priv.h	(revision 457)
@@ -0,0 +1,83 @@
+/*
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Martin Hentschel <info@cl-soft.de>
+ *
+ */
+
+#ifndef LWIP_HDR_APPS_SNMP_CORE_PRIV_H
+#define LWIP_HDR_APPS_SNMP_CORE_PRIV_H
+
+#include "lwip/apps/snmp_opts.h"
+
+#if LWIP_SNMP /* don't build if not configured for use in lwipopts.h */
+
+#include "lwip/apps/snmp_core.h"
+#include "snmp_asn1.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* (outdated) SNMPv1 error codes
+ * shall not be used by MIBS anymore, nevertheless required from core for properly answering a v1 request
+ */
+#define SNMP_ERR_NOSUCHNAME 2
+#define SNMP_ERR_BADVALUE   3
+#define SNMP_ERR_READONLY   4
+/* error codes which are internal and shall not be used by MIBS
+ * shall not be used by MIBS anymore, nevertheless required from core for properly answering a v1 request
+ */
+#define SNMP_ERR_TOOBIG               1
+#define SNMP_ERR_AUTHORIZATIONERROR   16
+
+#define SNMP_ERR_UNKNOWN_ENGINEID     30
+#define SNMP_ERR_UNKNOWN_SECURITYNAME 31
+#define SNMP_ERR_UNSUPPORTED_SECLEVEL 32
+#define SNMP_ERR_NOTINTIMEWINDOW      33
+#define SNMP_ERR_DECRYIPTION_ERROR    34
+
+#define SNMP_ERR_NOSUCHOBJECT         SNMP_VARBIND_EXCEPTION_OFFSET + SNMP_ASN1_CONTEXT_VARBIND_NO_SUCH_OBJECT
+#define SNMP_ERR_ENDOFMIBVIEW         SNMP_VARBIND_EXCEPTION_OFFSET + SNMP_ASN1_CONTEXT_VARBIND_END_OF_MIB_VIEW
+
+
+const struct snmp_node *snmp_mib_tree_resolve_exact(const struct snmp_mib *mib, const u32_t *oid, u8_t oid_len, u8_t *oid_instance_len);
+const struct snmp_node *snmp_mib_tree_resolve_next(const struct snmp_mib *mib, const u32_t *oid, u8_t oid_len, struct snmp_obj_id *oidret);
+
+typedef u8_t (*snmp_validate_node_instance_method)(struct snmp_node_instance *, void *);
+
+u8_t snmp_get_node_instance_from_oid(const u32_t *oid, u8_t oid_len, struct snmp_node_instance *node_instance);
+u8_t snmp_get_next_node_instance_from_oid(const u32_t *oid, u8_t oid_len, snmp_validate_node_instance_method validate_node_instance_method, void *validate_node_instance_arg, struct snmp_obj_id *node_oid, struct snmp_node_instance *node_instance);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LWIP_SNMP */
+
+#endif /* LWIP_HDR_APPS_SNMP_CORE_PRIV_H */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/apps/snmp/snmp_mib2.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/apps/snmp/snmp_mib2.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/apps/snmp/snmp_mib2.c	(revision 457)
@@ -0,0 +1,116 @@
+/**
+ * @file
+ * Management Information Base II (RFC1213) objects and functions.
+ */
+
+/*
+ * Copyright (c) 2006 Axon Digital Design B.V., The Netherlands.
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * Author: Dirk Ziegelmeier <dziegel@gmx.de>
+ *         Christiaan Simons <christiaan.simons@axon.tv>
+ */
+
+/**
+ * @defgroup snmp_mib2 MIB2
+ * @ingroup snmp
+ */
+
+#include "lwip/apps/snmp_opts.h"
+
+#if LWIP_SNMP && SNMP_LWIP_MIB2 /* don't build if not configured for use in lwipopts.h */
+
+#if !LWIP_STATS
+#error LWIP_SNMP MIB2 needs LWIP_STATS (for MIB2)
+#endif
+#if !MIB2_STATS
+#error LWIP_SNMP MIB2 needs MIB2_STATS (for MIB2)
+#endif
+
+#include "lwip/snmp.h"
+#include "lwip/apps/snmp.h"
+#include "lwip/apps/snmp_core.h"
+#include "lwip/apps/snmp_mib2.h"
+#include "lwip/apps/snmp_scalar.h"
+
+#if SNMP_USE_NETCONN
+#include "lwip/tcpip.h"
+#include "lwip/priv/tcpip_priv.h"
+void
+snmp_mib2_lwip_synchronizer(snmp_threadsync_called_fn fn, void *arg)
+{
+#if LWIP_TCPIP_CORE_LOCKING
+  LOCK_TCPIP_CORE();
+  fn(arg);
+  UNLOCK_TCPIP_CORE();
+#else
+  tcpip_callback(fn, arg);
+#endif
+}
+
+struct snmp_threadsync_instance snmp_mib2_lwip_locks;
+#endif
+
+/* dot3 and EtherLike MIB not planned. (transmission .1.3.6.1.2.1.10) */
+/* historical (some say hysterical). (cmot .1.3.6.1.2.1.9) */
+/* lwIP has no EGP, thus may not implement it. (egp .1.3.6.1.2.1.8) */
+
+/* --- mib-2 .1.3.6.1.2.1 ----------------------------------------------------- */
+extern const struct snmp_scalar_array_node snmp_mib2_snmp_root;
+extern const struct snmp_tree_node snmp_mib2_udp_root;
+extern const struct snmp_tree_node snmp_mib2_tcp_root;
+extern const struct snmp_scalar_array_node snmp_mib2_icmp_root;
+extern const struct snmp_tree_node snmp_mib2_interface_root;
+extern const struct snmp_scalar_array_node snmp_mib2_system_node;
+extern const struct snmp_tree_node snmp_mib2_at_root;
+extern const struct snmp_tree_node snmp_mib2_ip_root;
+
+static const struct snmp_node *const mib2_nodes[] = {
+  &snmp_mib2_system_node.node.node,
+  &snmp_mib2_interface_root.node,
+#if LWIP_ARP && LWIP_IPV4
+  &snmp_mib2_at_root.node,
+#endif /* LWIP_ARP && LWIP_IPV4 */
+#if LWIP_IPV4
+  &snmp_mib2_ip_root.node,
+#endif /* LWIP_IPV4 */
+#if LWIP_ICMP
+  &snmp_mib2_icmp_root.node.node,
+#endif /* LWIP_ICMP */
+#if LWIP_TCP
+  &snmp_mib2_tcp_root.node,
+#endif /* LWIP_TCP */
+#if LWIP_UDP
+  &snmp_mib2_udp_root.node,
+#endif /* LWIP_UDP */
+  &snmp_mib2_snmp_root.node.node
+};
+
+static const struct snmp_tree_node mib2_root = SNMP_CREATE_TREE_NODE(1, mib2_nodes);
+
+static const u32_t  mib2_base_oid_arr[] = { 1, 3, 6, 1, 2, 1 };
+const struct snmp_mib mib2 = SNMP_MIB_CREATE(mib2_base_oid_arr, &mib2_root.node);
+
+#endif /* LWIP_SNMP && SNMP_LWIP_MIB2 */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/apps/snmp/snmp_mib2_icmp.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/apps/snmp/snmp_mib2_icmp.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/apps/snmp/snmp_mib2_icmp.c	(revision 457)
@@ -0,0 +1,182 @@
+/**
+ * @file
+ * Management Information Base II (RFC1213) ICMP objects and functions.
+ */
+
+/*
+ * Copyright (c) 2006 Axon Digital Design B.V., The Netherlands.
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * Author: Dirk Ziegelmeier <dziegel@gmx.de>
+ *         Christiaan Simons <christiaan.simons@axon.tv>
+ */
+
+#include "lwip/snmp.h"
+#include "lwip/apps/snmp.h"
+#include "lwip/apps/snmp_core.h"
+#include "lwip/apps/snmp_mib2.h"
+#include "lwip/apps/snmp_table.h"
+#include "lwip/apps/snmp_scalar.h"
+#include "lwip/icmp.h"
+#include "lwip/stats.h"
+
+#if LWIP_SNMP && SNMP_LWIP_MIB2 && LWIP_ICMP
+
+#if SNMP_USE_NETCONN
+#define SYNC_NODE_NAME(node_name) node_name ## _synced
+#define CREATE_LWIP_SYNC_NODE(oid, node_name) \
+   static const struct snmp_threadsync_node node_name ## _synced = SNMP_CREATE_THREAD_SYNC_NODE(oid, &node_name.node, &snmp_mib2_lwip_locks);
+#else
+#define SYNC_NODE_NAME(node_name) node_name
+#define CREATE_LWIP_SYNC_NODE(oid, node_name)
+#endif
+
+/* --- icmp .1.3.6.1.2.1.5 ----------------------------------------------------- */
+
+static s16_t
+icmp_get_value(const struct snmp_scalar_array_node_def *node, void *value)
+{
+  u32_t *uint_ptr = (u32_t *)value;
+
+  switch (node->oid) {
+    case 1: /* icmpInMsgs */
+      *uint_ptr = STATS_GET(mib2.icmpinmsgs);
+      return sizeof(*uint_ptr);
+    case 2: /* icmpInErrors */
+      *uint_ptr = STATS_GET(mib2.icmpinerrors);
+      return sizeof(*uint_ptr);
+    case 3: /* icmpInDestUnreachs */
+      *uint_ptr = STATS_GET(mib2.icmpindestunreachs);
+      return sizeof(*uint_ptr);
+    case 4: /* icmpInTimeExcds */
+      *uint_ptr = STATS_GET(mib2.icmpintimeexcds);
+      return sizeof(*uint_ptr);
+    case 5: /* icmpInParmProbs */
+      *uint_ptr = STATS_GET(mib2.icmpinparmprobs);
+      return sizeof(*uint_ptr);
+    case 6: /* icmpInSrcQuenchs */
+      *uint_ptr = STATS_GET(mib2.icmpinsrcquenchs);
+      return sizeof(*uint_ptr);
+    case 7: /* icmpInRedirects */
+      *uint_ptr = STATS_GET(mib2.icmpinredirects);
+      return sizeof(*uint_ptr);
+    case 8: /* icmpInEchos */
+      *uint_ptr = STATS_GET(mib2.icmpinechos);
+      return sizeof(*uint_ptr);
+    case 9: /* icmpInEchoReps */
+      *uint_ptr = STATS_GET(mib2.icmpinechoreps);
+      return sizeof(*uint_ptr);
+    case 10: /* icmpInTimestamps */
+      *uint_ptr = STATS_GET(mib2.icmpintimestamps);
+      return sizeof(*uint_ptr);
+    case 11: /* icmpInTimestampReps */
+      *uint_ptr = STATS_GET(mib2.icmpintimestampreps);
+      return sizeof(*uint_ptr);
+    case 12: /* icmpInAddrMasks */
+      *uint_ptr = STATS_GET(mib2.icmpinaddrmasks);
+      return sizeof(*uint_ptr);
+    case 13: /* icmpInAddrMaskReps */
+      *uint_ptr = STATS_GET(mib2.icmpinaddrmaskreps);
+      return sizeof(*uint_ptr);
+    case 14: /* icmpOutMsgs */
+      *uint_ptr = STATS_GET(mib2.icmpoutmsgs);
+      return sizeof(*uint_ptr);
+    case 15: /* icmpOutErrors */
+      *uint_ptr = STATS_GET(mib2.icmpouterrors);
+      return sizeof(*uint_ptr);
+    case 16: /* icmpOutDestUnreachs */
+      *uint_ptr = STATS_GET(mib2.icmpoutdestunreachs);
+      return sizeof(*uint_ptr);
+    case 17: /* icmpOutTimeExcds */
+      *uint_ptr = STATS_GET(mib2.icmpouttimeexcds);
+      return sizeof(*uint_ptr);
+    case 18: /* icmpOutParmProbs: not supported -> always 0 */
+      *uint_ptr = 0;
+      return sizeof(*uint_ptr);
+    case 19: /* icmpOutSrcQuenchs: not supported -> always 0 */
+      *uint_ptr = 0;
+      return sizeof(*uint_ptr);
+    case 20: /* icmpOutRedirects: not supported -> always 0 */
+      *uint_ptr = 0;
+      return sizeof(*uint_ptr);
+    case 21: /* icmpOutEchos */
+      *uint_ptr = STATS_GET(mib2.icmpoutechos);
+      return sizeof(*uint_ptr);
+    case 22: /* icmpOutEchoReps */
+      *uint_ptr = STATS_GET(mib2.icmpoutechoreps);
+      return sizeof(*uint_ptr);
+    case 23: /* icmpOutTimestamps: not supported -> always 0 */
+      *uint_ptr = 0;
+      return sizeof(*uint_ptr);
+    case 24: /* icmpOutTimestampReps: not supported -> always 0 */
+      *uint_ptr = 0;
+      return sizeof(*uint_ptr);
+    case 25: /* icmpOutAddrMasks: not supported -> always 0 */
+      *uint_ptr = 0;
+      return sizeof(*uint_ptr);
+    case 26: /* icmpOutAddrMaskReps: not supported -> always 0 */
+      *uint_ptr = 0;
+      return sizeof(*uint_ptr);
+    default:
+      LWIP_DEBUGF(SNMP_MIB_DEBUG, ("icmp_get_value(): unknown id: %"S32_F"\n", node->oid));
+      break;
+  }
+
+  return 0;
+}
+
+
+static const struct snmp_scalar_array_node_def icmp_nodes[] = {
+  { 1, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY},
+  { 2, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY},
+  { 3, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY},
+  { 4, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY},
+  { 5, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY},
+  { 6, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY},
+  { 7, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY},
+  { 8, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY},
+  { 9, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY},
+  {10, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY},
+  {11, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY},
+  {12, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY},
+  {13, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY},
+  {14, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY},
+  {15, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY},
+  {16, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY},
+  {17, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY},
+  {18, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY},
+  {19, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY},
+  {20, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY},
+  {21, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY},
+  {22, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY},
+  {23, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY},
+  {24, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY},
+  {25, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY},
+  {26, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY}
+};
+
+const struct snmp_scalar_array_node snmp_mib2_icmp_root = SNMP_SCALAR_CREATE_ARRAY_NODE(5, icmp_nodes, icmp_get_value, NULL, NULL);
+
+#endif /* LWIP_SNMP && SNMP_LWIP_MIB2 && LWIP_ICMP */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/apps/snmp/snmp_mib2_interfaces.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/apps/snmp/snmp_mib2_interfaces.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/apps/snmp/snmp_mib2_interfaces.c	(revision 457)
@@ -0,0 +1,368 @@
+/**
+ * @file
+ * Management Information Base II (RFC1213) INTERFACES objects and functions.
+ */
+
+/*
+ * Copyright (c) 2006 Axon Digital Design B.V., The Netherlands.
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * Author: Dirk Ziegelmeier <dziegel@gmx.de>
+ *         Christiaan Simons <christiaan.simons@axon.tv>
+ */
+
+#include "lwip/snmp.h"
+#include "lwip/apps/snmp.h"
+#include "lwip/apps/snmp_core.h"
+#include "lwip/apps/snmp_mib2.h"
+#include "lwip/apps/snmp_table.h"
+#include "lwip/apps/snmp_scalar.h"
+#include "lwip/netif.h"
+#include "lwip/stats.h"
+
+#include <string.h>
+
+#if LWIP_SNMP && SNMP_LWIP_MIB2
+
+#if SNMP_USE_NETCONN
+#define SYNC_NODE_NAME(node_name) node_name ## _synced
+#define CREATE_LWIP_SYNC_NODE(oid, node_name) \
+   static const struct snmp_threadsync_node node_name ## _synced = SNMP_CREATE_THREAD_SYNC_NODE(oid, &node_name.node, &snmp_mib2_lwip_locks);
+#else
+#define SYNC_NODE_NAME(node_name) node_name
+#define CREATE_LWIP_SYNC_NODE(oid, node_name)
+#endif
+
+
+/* --- interfaces .1.3.6.1.2.1.2 ----------------------------------------------------- */
+
+static s16_t
+interfaces_get_value(struct snmp_node_instance *instance, void *value)
+{
+  if (instance->node->oid == 1) {
+    s32_t *sint_ptr = (s32_t *)value;
+    s32_t num_netifs = 0;
+
+    struct netif *netif;
+    NETIF_FOREACH(netif) {
+      num_netifs++;
+    }
+
+    *sint_ptr = num_netifs;
+    return sizeof(*sint_ptr);
+  }
+
+  return 0;
+}
+
+/* list of allowed value ranges for incoming OID */
+static const struct snmp_oid_range interfaces_Table_oid_ranges[] = {
+  { 1, 0xff } /* netif->num is u8_t */
+};
+
+static const u8_t iftable_ifOutQLen         = 0;
+
+static const u8_t iftable_ifOperStatus_up   = 1;
+static const u8_t iftable_ifOperStatus_down = 2;
+
+static const u8_t iftable_ifAdminStatus_up             = 1;
+static const u8_t iftable_ifAdminStatus_lowerLayerDown = 7;
+static const u8_t iftable_ifAdminStatus_down           = 2;
+
+static snmp_err_t
+interfaces_Table_get_cell_instance(const u32_t *column, const u32_t *row_oid, u8_t row_oid_len, struct snmp_node_instance *cell_instance)
+{
+  u32_t ifIndex;
+  struct netif *netif;
+
+  LWIP_UNUSED_ARG(column);
+
+  /* check if incoming OID length and if values are in plausible range */
+  if (!snmp_oid_in_range(row_oid, row_oid_len, interfaces_Table_oid_ranges, LWIP_ARRAYSIZE(interfaces_Table_oid_ranges))) {
+    return SNMP_ERR_NOSUCHINSTANCE;
+  }
+
+  /* get netif index from incoming OID */
+  ifIndex = row_oid[0];
+
+  /* find netif with index */
+  NETIF_FOREACH(netif) {
+    if (netif_to_num(netif) == ifIndex) {
+      /* store netif pointer for subsequent operations (get/test/set) */
+      cell_instance->reference.ptr = netif;
+      return SNMP_ERR_NOERROR;
+    }
+  }
+
+  /* not found */
+  return SNMP_ERR_NOSUCHINSTANCE;
+}
+
+static snmp_err_t
+interfaces_Table_get_next_cell_instance(const u32_t *column, struct snmp_obj_id *row_oid, struct snmp_node_instance *cell_instance)
+{
+  struct netif *netif;
+  struct snmp_next_oid_state state;
+  u32_t result_temp[LWIP_ARRAYSIZE(interfaces_Table_oid_ranges)];
+
+  LWIP_UNUSED_ARG(column);
+
+  /* init struct to search next oid */
+  snmp_next_oid_init(&state, row_oid->id, row_oid->len, result_temp, LWIP_ARRAYSIZE(interfaces_Table_oid_ranges));
+
+  /* iterate over all possible OIDs to find the next one */
+  NETIF_FOREACH(netif) {
+    u32_t test_oid[LWIP_ARRAYSIZE(interfaces_Table_oid_ranges)];
+    test_oid[0] = netif_to_num(netif);
+
+    /* check generated OID: is it a candidate for the next one? */
+    snmp_next_oid_check(&state, test_oid, LWIP_ARRAYSIZE(interfaces_Table_oid_ranges), netif);
+  }
+
+  /* did we find a next one? */
+  if (state.status == SNMP_NEXT_OID_STATUS_SUCCESS) {
+    snmp_oid_assign(row_oid, state.next_oid, state.next_oid_len);
+    /* store netif pointer for subsequent operations (get/test/set) */
+    cell_instance->reference.ptr = /* (struct netif*) */state.reference;
+    return SNMP_ERR_NOERROR;
+  }
+
+  /* not found */
+  return SNMP_ERR_NOSUCHINSTANCE;
+}
+
+static s16_t
+interfaces_Table_get_value(struct snmp_node_instance *instance, void *value)
+{
+  struct netif *netif = (struct netif *)instance->reference.ptr;
+  u32_t *value_u32 = (u32_t *)value;
+  s32_t *value_s32 = (s32_t *)value;
+  u16_t value_len;
+
+  switch (SNMP_TABLE_GET_COLUMN_FROM_OID(instance->instance_oid.id)) {
+    case 1: /* ifIndex */
+      *value_s32 = netif_to_num(netif);
+      value_len = sizeof(*value_s32);
+      break;
+    case 2: /* ifDescr */
+      value_len = sizeof(netif->name);
+      MEMCPY(value, netif->name, value_len);
+      break;
+    case 3: /* ifType */
+      *value_s32 = netif->link_type;
+      value_len = sizeof(*value_s32);
+      break;
+    case 4: /* ifMtu */
+      *value_s32 = netif->mtu;
+      value_len = sizeof(*value_s32);
+      break;
+    case 5: /* ifSpeed */
+      *value_u32 = netif->link_speed;
+      value_len = sizeof(*value_u32);
+      break;
+    case 6: /* ifPhysAddress */
+      value_len = sizeof(netif->hwaddr);
+      MEMCPY(value, &netif->hwaddr, value_len);
+      break;
+    case 7: /* ifAdminStatus */
+      if (netif_is_up(netif)) {
+        *value_s32 = iftable_ifOperStatus_up;
+      } else {
+        *value_s32 = iftable_ifOperStatus_down;
+      }
+      value_len = sizeof(*value_s32);
+      break;
+    case 8: /* ifOperStatus */
+      if (netif_is_up(netif)) {
+        if (netif_is_link_up(netif)) {
+          *value_s32 = iftable_ifAdminStatus_up;
+        } else {
+          *value_s32 = iftable_ifAdminStatus_lowerLayerDown;
+        }
+      } else {
+        *value_s32 = iftable_ifAdminStatus_down;
+      }
+      value_len = sizeof(*value_s32);
+      break;
+    case 9: /* ifLastChange */
+      *value_u32 = netif->ts;
+      value_len = sizeof(*value_u32);
+      break;
+    case 10: /* ifInOctets */
+      *value_u32 = netif->mib2_counters.ifinoctets;
+      value_len = sizeof(*value_u32);
+      break;
+    case 11: /* ifInUcastPkts */
+      *value_u32 = netif->mib2_counters.ifinucastpkts;
+      value_len = sizeof(*value_u32);
+      break;
+    case 12: /* ifInNUcastPkts */
+      *value_u32 = netif->mib2_counters.ifinnucastpkts;
+      value_len = sizeof(*value_u32);
+      break;
+    case 13: /* ifInDiscards */
+      *value_u32 = netif->mib2_counters.ifindiscards;
+      value_len = sizeof(*value_u32);
+      break;
+    case 14: /* ifInErrors */
+      *value_u32 = netif->mib2_counters.ifinerrors;
+      value_len = sizeof(*value_u32);
+      break;
+    case 15: /* ifInUnkownProtos */
+      *value_u32 = netif->mib2_counters.ifinunknownprotos;
+      value_len = sizeof(*value_u32);
+      break;
+    case 16: /* ifOutOctets */
+      *value_u32 = netif->mib2_counters.ifoutoctets;
+      value_len = sizeof(*value_u32);
+      break;
+    case 17: /* ifOutUcastPkts */
+      *value_u32 = netif->mib2_counters.ifoutucastpkts;
+      value_len = sizeof(*value_u32);
+      break;
+    case 18: /* ifOutNUcastPkts */
+      *value_u32 = netif->mib2_counters.ifoutnucastpkts;
+      value_len = sizeof(*value_u32);
+      break;
+    case 19: /* ifOutDiscarts */
+      *value_u32 = netif->mib2_counters.ifoutdiscards;
+      value_len = sizeof(*value_u32);
+      break;
+    case 20: /* ifOutErrors */
+      *value_u32 = netif->mib2_counters.ifouterrors;
+      value_len = sizeof(*value_u32);
+      break;
+    case 21: /* ifOutQLen */
+      *value_u32 = iftable_ifOutQLen;
+      value_len = sizeof(*value_u32);
+      break;
+    /** @note returning zeroDotZero (0.0) no media specific MIB support */
+    case 22: /* ifSpecific */
+      value_len = snmp_zero_dot_zero.len * sizeof(u32_t);
+      MEMCPY(value, snmp_zero_dot_zero.id, value_len);
+      break;
+    default:
+      return 0;
+  }
+
+  return value_len;
+}
+
+#if !SNMP_SAFE_REQUESTS
+
+static snmp_err_t
+interfaces_Table_set_test(struct snmp_node_instance *instance, u16_t len, void *value)
+{
+  s32_t *sint_ptr = (s32_t *)value;
+
+  /* stack should never call this method for another column,
+  because all other columns are set to readonly */
+  LWIP_ASSERT("Invalid column", (SNMP_TABLE_GET_COLUMN_FROM_OID(instance->instance_oid.id) == 7));
+  LWIP_UNUSED_ARG(len);
+
+  if (*sint_ptr == 1 || *sint_ptr == 2) {
+    return SNMP_ERR_NOERROR;
+  }
+
+  return SNMP_ERR_WRONGVALUE;
+}
+
+static snmp_err_t
+interfaces_Table_set_value(struct snmp_node_instance *instance, u16_t len, void *value)
+{
+  struct netif *netif = (struct netif *)instance->reference.ptr;
+  s32_t *sint_ptr = (s32_t *)value;
+
+  /* stack should never call this method for another column,
+  because all other columns are set to readonly */
+  LWIP_ASSERT("Invalid column", (SNMP_TABLE_GET_COLUMN_FROM_OID(instance->instance_oid.id) == 7));
+  LWIP_UNUSED_ARG(len);
+
+  if (*sint_ptr == 1) {
+    netif_set_up(netif);
+  } else if (*sint_ptr == 2) {
+    netif_set_down(netif);
+  }
+
+  return SNMP_ERR_NOERROR;
+}
+
+#endif /* SNMP_SAFE_REQUESTS */
+
+static const struct snmp_scalar_node interfaces_Number = SNMP_SCALAR_CREATE_NODE_READONLY(1, SNMP_ASN1_TYPE_INTEGER, interfaces_get_value);
+
+static const struct snmp_table_col_def interfaces_Table_columns[] = {
+  {  1, SNMP_ASN1_TYPE_INTEGER,      SNMP_NODE_INSTANCE_READ_ONLY }, /* ifIndex */
+  {  2, SNMP_ASN1_TYPE_OCTET_STRING, SNMP_NODE_INSTANCE_READ_ONLY }, /* ifDescr */
+  {  3, SNMP_ASN1_TYPE_INTEGER,      SNMP_NODE_INSTANCE_READ_ONLY }, /* ifType */
+  {  4, SNMP_ASN1_TYPE_INTEGER,      SNMP_NODE_INSTANCE_READ_ONLY }, /* ifMtu */
+  {  5, SNMP_ASN1_TYPE_GAUGE,        SNMP_NODE_INSTANCE_READ_ONLY }, /* ifSpeed */
+  {  6, SNMP_ASN1_TYPE_OCTET_STRING, SNMP_NODE_INSTANCE_READ_ONLY }, /* ifPhysAddress */
+#if !SNMP_SAFE_REQUESTS
+  {  7, SNMP_ASN1_TYPE_INTEGER,      SNMP_NODE_INSTANCE_READ_WRITE }, /* ifAdminStatus */
+#else
+  {  7, SNMP_ASN1_TYPE_INTEGER,      SNMP_NODE_INSTANCE_READ_ONLY }, /* ifAdminStatus */
+#endif
+  {  8, SNMP_ASN1_TYPE_INTEGER,      SNMP_NODE_INSTANCE_READ_ONLY }, /* ifOperStatus */
+  {  9, SNMP_ASN1_TYPE_TIMETICKS,    SNMP_NODE_INSTANCE_READ_ONLY }, /* ifLastChange */
+  { 10, SNMP_ASN1_TYPE_COUNTER,      SNMP_NODE_INSTANCE_READ_ONLY }, /* ifInOctets */
+  { 11, SNMP_ASN1_TYPE_COUNTER,      SNMP_NODE_INSTANCE_READ_ONLY }, /* ifInUcastPkts */
+  { 12, SNMP_ASN1_TYPE_COUNTER,      SNMP_NODE_INSTANCE_READ_ONLY }, /* ifInNUcastPkts */
+  { 13, SNMP_ASN1_TYPE_COUNTER,      SNMP_NODE_INSTANCE_READ_ONLY }, /* ifInDiscarts */
+  { 14, SNMP_ASN1_TYPE_COUNTER,      SNMP_NODE_INSTANCE_READ_ONLY }, /* ifInErrors */
+  { 15, SNMP_ASN1_TYPE_COUNTER,      SNMP_NODE_INSTANCE_READ_ONLY }, /* ifInUnkownProtos */
+  { 16, SNMP_ASN1_TYPE_COUNTER,      SNMP_NODE_INSTANCE_READ_ONLY }, /* ifOutOctets */
+  { 17, SNMP_ASN1_TYPE_COUNTER,      SNMP_NODE_INSTANCE_READ_ONLY }, /* ifOutUcastPkts */
+  { 18, SNMP_ASN1_TYPE_COUNTER,      SNMP_NODE_INSTANCE_READ_ONLY }, /* ifOutNUcastPkts */
+  { 19, SNMP_ASN1_TYPE_COUNTER,      SNMP_NODE_INSTANCE_READ_ONLY }, /* ifOutDiscarts */
+  { 20, SNMP_ASN1_TYPE_COUNTER,      SNMP_NODE_INSTANCE_READ_ONLY }, /* ifOutErrors */
+  { 21, SNMP_ASN1_TYPE_GAUGE,        SNMP_NODE_INSTANCE_READ_ONLY }, /* ifOutQLen */
+  { 22, SNMP_ASN1_TYPE_OBJECT_ID,    SNMP_NODE_INSTANCE_READ_ONLY }  /* ifSpecific */
+};
+
+#if !SNMP_SAFE_REQUESTS
+static const struct snmp_table_node interfaces_Table = SNMP_TABLE_CREATE(
+      2, interfaces_Table_columns,
+      interfaces_Table_get_cell_instance, interfaces_Table_get_next_cell_instance,
+      interfaces_Table_get_value, interfaces_Table_set_test, interfaces_Table_set_value);
+#else
+static const struct snmp_table_node interfaces_Table = SNMP_TABLE_CREATE(
+      2, interfaces_Table_columns,
+      interfaces_Table_get_cell_instance, interfaces_Table_get_next_cell_instance,
+      interfaces_Table_get_value, NULL, NULL);
+#endif
+
+/* the following nodes access variables in LWIP stack from SNMP worker thread and must therefore be synced to LWIP (TCPIP) thread */
+CREATE_LWIP_SYNC_NODE(1, interfaces_Number)
+CREATE_LWIP_SYNC_NODE(2, interfaces_Table)
+
+static const struct snmp_node *const interface_nodes[] = {
+  &SYNC_NODE_NAME(interfaces_Number).node.node,
+  &SYNC_NODE_NAME(interfaces_Table).node.node
+};
+
+const struct snmp_tree_node snmp_mib2_interface_root = SNMP_CREATE_TREE_NODE(2, interface_nodes);
+
+#endif /* LWIP_SNMP && SNMP_LWIP_MIB2 */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/apps/snmp/snmp_mib2_ip.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/apps/snmp/snmp_mib2_ip.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/apps/snmp/snmp_mib2_ip.c	(revision 457)
@@ -0,0 +1,731 @@
+/**
+ * @file
+ * Management Information Base II (RFC1213) IP objects and functions.
+ */
+
+/*
+ * Copyright (c) 2006 Axon Digital Design B.V., The Netherlands.
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * Author: Dirk Ziegelmeier <dziegel@gmx.de>
+ *         Christiaan Simons <christiaan.simons@axon.tv>
+ */
+
+#include "lwip/snmp.h"
+#include "lwip/apps/snmp.h"
+#include "lwip/apps/snmp_core.h"
+#include "lwip/apps/snmp_mib2.h"
+#include "lwip/apps/snmp_table.h"
+#include "lwip/apps/snmp_scalar.h"
+#include "lwip/stats.h"
+#include "lwip/netif.h"
+#include "lwip/ip.h"
+#include "lwip/etharp.h"
+
+#if LWIP_SNMP && SNMP_LWIP_MIB2
+
+#if SNMP_USE_NETCONN
+#define SYNC_NODE_NAME(node_name) node_name ## _synced
+#define CREATE_LWIP_SYNC_NODE(oid, node_name) \
+   static const struct snmp_threadsync_node node_name ## _synced = SNMP_CREATE_THREAD_SYNC_NODE(oid, &node_name.node, &snmp_mib2_lwip_locks);
+#else
+#define SYNC_NODE_NAME(node_name) node_name
+#define CREATE_LWIP_SYNC_NODE(oid, node_name)
+#endif
+
+#if LWIP_IPV4
+/* --- ip .1.3.6.1.2.1.4 ----------------------------------------------------- */
+
+static s16_t
+ip_get_value(struct snmp_node_instance *instance, void *value)
+{
+  s32_t *sint_ptr = (s32_t *)value;
+  u32_t *uint_ptr = (u32_t *)value;
+
+  switch (instance->node->oid) {
+    case 1: /* ipForwarding */
+#if IP_FORWARD
+      /* forwarding */
+      *sint_ptr = 1;
+#else
+      /* not-forwarding */
+      *sint_ptr = 2;
+#endif
+      return sizeof(*sint_ptr);
+    case 2: /* ipDefaultTTL */
+      *sint_ptr = IP_DEFAULT_TTL;
+      return sizeof(*sint_ptr);
+    case 3: /* ipInReceives */
+      *uint_ptr = STATS_GET(mib2.ipinreceives);
+      return sizeof(*uint_ptr);
+    case 4: /* ipInHdrErrors */
+      *uint_ptr = STATS_GET(mib2.ipinhdrerrors);
+      return sizeof(*uint_ptr);
+    case 5: /* ipInAddrErrors */
+      *uint_ptr = STATS_GET(mib2.ipinaddrerrors);
+      return sizeof(*uint_ptr);
+    case 6: /* ipForwDatagrams */
+      *uint_ptr = STATS_GET(mib2.ipforwdatagrams);
+      return sizeof(*uint_ptr);
+    case 7: /* ipInUnknownProtos */
+      *uint_ptr = STATS_GET(mib2.ipinunknownprotos);
+      return sizeof(*uint_ptr);
+    case 8: /* ipInDiscards */
+      *uint_ptr = STATS_GET(mib2.ipindiscards);
+      return sizeof(*uint_ptr);
+    case 9: /* ipInDelivers */
+      *uint_ptr = STATS_GET(mib2.ipindelivers);
+      return sizeof(*uint_ptr);
+    case 10: /* ipOutRequests */
+      *uint_ptr = STATS_GET(mib2.ipoutrequests);
+      return sizeof(*uint_ptr);
+    case 11: /* ipOutDiscards */
+      *uint_ptr = STATS_GET(mib2.ipoutdiscards);
+      return sizeof(*uint_ptr);
+    case 12: /* ipOutNoRoutes */
+      *uint_ptr = STATS_GET(mib2.ipoutnoroutes);
+      return sizeof(*uint_ptr);
+    case 13: /* ipReasmTimeout */
+#if IP_REASSEMBLY
+      *sint_ptr = IP_REASS_MAXAGE;
+#else
+      *sint_ptr = 0;
+#endif
+      return sizeof(*sint_ptr);
+    case 14: /* ipReasmReqds */
+      *uint_ptr = STATS_GET(mib2.ipreasmreqds);
+      return sizeof(*uint_ptr);
+    case 15: /* ipReasmOKs */
+      *uint_ptr = STATS_GET(mib2.ipreasmoks);
+      return sizeof(*uint_ptr);
+    case 16: /* ipReasmFails */
+      *uint_ptr = STATS_GET(mib2.ipreasmfails);
+      return sizeof(*uint_ptr);
+    case 17: /* ipFragOKs */
+      *uint_ptr = STATS_GET(mib2.ipfragoks);
+      return sizeof(*uint_ptr);
+    case 18: /* ipFragFails */
+      *uint_ptr = STATS_GET(mib2.ipfragfails);
+      return sizeof(*uint_ptr);
+    case 19: /* ipFragCreates */
+      *uint_ptr = STATS_GET(mib2.ipfragcreates);
+      return sizeof(*uint_ptr);
+    case 23: /* ipRoutingDiscards: not supported -> always 0 */
+      *uint_ptr = 0;
+      return sizeof(*uint_ptr);
+    default:
+      LWIP_DEBUGF(SNMP_MIB_DEBUG, ("ip_get_value(): unknown id: %"S32_F"\n", instance->node->oid));
+      break;
+  }
+
+  return 0;
+}
+
+/**
+ * Test ip object value before setting.
+ *
+ * @param instance node instance
+ * @param len return value space (in bytes)
+ * @param value points to (varbind) space to copy value from.
+ *
+ * @note we allow set if the value matches the hardwired value,
+ *   otherwise return badvalue.
+ */
+static snmp_err_t
+ip_set_test(struct snmp_node_instance *instance, u16_t len, void *value)
+{
+  snmp_err_t ret = SNMP_ERR_WRONGVALUE;
+  s32_t *sint_ptr = (s32_t *)value;
+
+  LWIP_UNUSED_ARG(len);
+  switch (instance->node->oid) {
+    case 1: /* ipForwarding */
+#if IP_FORWARD
+      /* forwarding */
+      if (*sint_ptr == 1)
+#else
+      /* not-forwarding */
+      if (*sint_ptr == 2)
+#endif
+      {
+        ret = SNMP_ERR_NOERROR;
+      }
+      break;
+    case 2: /* ipDefaultTTL */
+      if (*sint_ptr == IP_DEFAULT_TTL) {
+        ret = SNMP_ERR_NOERROR;
+      }
+      break;
+    default:
+      LWIP_DEBUGF(SNMP_MIB_DEBUG, ("ip_set_test(): unknown id: %"S32_F"\n", instance->node->oid));
+      break;
+  }
+
+  return ret;
+}
+
+static snmp_err_t
+ip_set_value(struct snmp_node_instance *instance, u16_t len, void *value)
+{
+  LWIP_UNUSED_ARG(instance);
+  LWIP_UNUSED_ARG(len);
+  LWIP_UNUSED_ARG(value);
+  /* nothing to do here because in set_test we only accept values being the same as our own stored value -> no need to store anything */
+  return SNMP_ERR_NOERROR;
+}
+
+/* --- ipAddrTable --- */
+
+/* list of allowed value ranges for incoming OID */
+static const struct snmp_oid_range ip_AddrTable_oid_ranges[] = {
+  { 0, 0xff }, /* IP A */
+  { 0, 0xff }, /* IP B */
+  { 0, 0xff }, /* IP C */
+  { 0, 0xff }  /* IP D */
+};
+
+static snmp_err_t
+ip_AddrTable_get_cell_value_core(struct netif *netif, const u32_t *column, union snmp_variant_value *value, u32_t *value_len)
+{
+  LWIP_UNUSED_ARG(value_len);
+
+  switch (*column) {
+    case 1: /* ipAdEntAddr */
+      value->u32 = netif_ip4_addr(netif)->addr;
+      break;
+    case 2: /* ipAdEntIfIndex */
+      value->u32 = netif_to_num(netif);
+      break;
+    case 3: /* ipAdEntNetMask */
+      value->u32 = netif_ip4_netmask(netif)->addr;
+      break;
+    case 4: /* ipAdEntBcastAddr */
+      /* lwIP oddity, there's no broadcast
+         address in the netif we can rely on */
+      value->u32 = IPADDR_BROADCAST & 1;
+      break;
+    case 5: /* ipAdEntReasmMaxSize */
+#if IP_REASSEMBLY
+      /* @todo The theoretical maximum is IP_REASS_MAX_PBUFS * size of the pbufs,
+       * but only if receiving one fragmented packet at a time.
+       * The current solution is to calculate for 2 simultaneous packets...
+       */
+      value->u32 = (IP_HLEN + ((IP_REASS_MAX_PBUFS / 2) *
+                               (PBUF_POOL_BUFSIZE - PBUF_LINK_ENCAPSULATION_HLEN - PBUF_LINK_HLEN - IP_HLEN)));
+#else
+      /** @todo returning MTU would be a bad thing and
+          returning a wild guess like '576' isn't good either */
+      value->u32 = 0;
+#endif
+      break;
+    default:
+      return SNMP_ERR_NOSUCHINSTANCE;
+  }
+
+  return SNMP_ERR_NOERROR;
+}
+
+static snmp_err_t
+ip_AddrTable_get_cell_value(const u32_t *column, const u32_t *row_oid, u8_t row_oid_len, union snmp_variant_value *value, u32_t *value_len)
+{
+  ip4_addr_t ip;
+  struct netif *netif;
+
+  /* check if incoming OID length and if values are in plausible range */
+  if (!snmp_oid_in_range(row_oid, row_oid_len, ip_AddrTable_oid_ranges, LWIP_ARRAYSIZE(ip_AddrTable_oid_ranges))) {
+    return SNMP_ERR_NOSUCHINSTANCE;
+  }
+
+  /* get IP from incoming OID */
+  snmp_oid_to_ip4(&row_oid[0], &ip); /* we know it succeeds because of oid_in_range check above */
+
+  /* find netif with requested ip */
+  NETIF_FOREACH(netif) {
+    if (ip4_addr_cmp(&ip, netif_ip4_addr(netif))) {
+      /* fill in object properties */
+      return ip_AddrTable_get_cell_value_core(netif, column, value, value_len);
+    }
+  }
+
+  /* not found */
+  return SNMP_ERR_NOSUCHINSTANCE;
+}
+
+static snmp_err_t
+ip_AddrTable_get_next_cell_instance_and_value(const u32_t *column, struct snmp_obj_id *row_oid, union snmp_variant_value *value, u32_t *value_len)
+{
+  struct netif *netif;
+  struct snmp_next_oid_state state;
+  u32_t result_temp[LWIP_ARRAYSIZE(ip_AddrTable_oid_ranges)];
+
+  /* init struct to search next oid */
+  snmp_next_oid_init(&state, row_oid->id, row_oid->len, result_temp, LWIP_ARRAYSIZE(ip_AddrTable_oid_ranges));
+
+  /* iterate over all possible OIDs to find the next one */
+  NETIF_FOREACH(netif) {
+    u32_t test_oid[LWIP_ARRAYSIZE(ip_AddrTable_oid_ranges)];
+    snmp_ip4_to_oid(netif_ip4_addr(netif), &test_oid[0]);
+
+    /* check generated OID: is it a candidate for the next one? */
+    snmp_next_oid_check(&state, test_oid, LWIP_ARRAYSIZE(ip_AddrTable_oid_ranges), netif);
+  }
+
+  /* did we find a next one? */
+  if (state.status == SNMP_NEXT_OID_STATUS_SUCCESS) {
+    snmp_oid_assign(row_oid, state.next_oid, state.next_oid_len);
+    /* fill in object properties */
+    return ip_AddrTable_get_cell_value_core((struct netif *)state.reference, column, value, value_len);
+  }
+
+  /* not found */
+  return SNMP_ERR_NOSUCHINSTANCE;
+}
+
+/* --- ipRouteTable --- */
+
+/* list of allowed value ranges for incoming OID */
+static const struct snmp_oid_range ip_RouteTable_oid_ranges[] = {
+  { 0, 0xff }, /* IP A */
+  { 0, 0xff }, /* IP B */
+  { 0, 0xff }, /* IP C */
+  { 0, 0xff }, /* IP D */
+};
+
+static snmp_err_t
+ip_RouteTable_get_cell_value_core(struct netif *netif, u8_t default_route, const u32_t *column, union snmp_variant_value *value, u32_t *value_len)
+{
+  switch (*column) {
+    case 1: /* ipRouteDest */
+      if (default_route) {
+        /* default rte has 0.0.0.0 dest */
+        value->u32 = IP4_ADDR_ANY4->addr;
+      } else {
+        /* netifs have netaddress dest */
+        ip4_addr_t tmp;
+        ip4_addr_get_network(&tmp, netif_ip4_addr(netif), netif_ip4_netmask(netif));
+        value->u32 = tmp.addr;
+      }
+      break;
+    case 2: /* ipRouteIfIndex */
+      value->u32 = netif_to_num(netif);
+      break;
+    case 3: /* ipRouteMetric1 */
+      if (default_route) {
+        value->s32 = 1; /* default */
+      } else {
+        value->s32 = 0; /* normal */
+      }
+      break;
+    case 4: /* ipRouteMetric2 */
+    case 5: /* ipRouteMetric3 */
+    case 6: /* ipRouteMetric4 */
+      value->s32 = -1; /* none */
+      break;
+    case 7: /* ipRouteNextHop */
+      if (default_route) {
+        /* default rte: gateway */
+        value->u32 = netif_ip4_gw(netif)->addr;
+      } else {
+        /* other rtes: netif ip_addr  */
+        value->u32 = netif_ip4_addr(netif)->addr;
+      }
+      break;
+    case 8: /* ipRouteType */
+      if (default_route) {
+        /* default rte is indirect */
+        value->u32 = 4; /* indirect */
+      } else {
+        /* other rtes are direct */
+        value->u32 = 3; /* direct */
+      }
+      break;
+    case 9: /* ipRouteProto */
+      /* locally defined routes */
+      value->u32 = 2; /* local */
+      break;
+    case 10: /* ipRouteAge */
+      /* @todo (sysuptime - timestamp last change) / 100 */
+      value->u32 = 0;
+      break;
+    case 11: /* ipRouteMask */
+      if (default_route) {
+        /* default rte use 0.0.0.0 mask */
+        value->u32 = IP4_ADDR_ANY4->addr;
+      } else {
+        /* other rtes use netmask */
+        value->u32 = netif_ip4_netmask(netif)->addr;
+      }
+      break;
+    case 12: /* ipRouteMetric5 */
+      value->s32 = -1; /* none */
+      break;
+    case 13: /* ipRouteInfo */
+      value->const_ptr = snmp_zero_dot_zero.id;
+      *value_len = snmp_zero_dot_zero.len * sizeof(u32_t);
+      break;
+    default:
+      return SNMP_ERR_NOSUCHINSTANCE;
+  }
+
+  return SNMP_ERR_NOERROR;
+}
+
+static snmp_err_t
+ip_RouteTable_get_cell_value(const u32_t *column, const u32_t *row_oid, u8_t row_oid_len, union snmp_variant_value *value, u32_t *value_len)
+{
+  ip4_addr_t test_ip;
+  struct netif *netif;
+
+  /* check if incoming OID length and if values are in plausible range */
+  if (!snmp_oid_in_range(row_oid, row_oid_len, ip_RouteTable_oid_ranges, LWIP_ARRAYSIZE(ip_RouteTable_oid_ranges))) {
+    return SNMP_ERR_NOSUCHINSTANCE;
+  }
+
+  /* get IP and port from incoming OID */
+  snmp_oid_to_ip4(&row_oid[0], &test_ip); /* we know it succeeds because of oid_in_range check above */
+
+  /* default route is on default netif */
+  if (ip4_addr_isany_val(test_ip) && (netif_default != NULL)) {
+    /* fill in object properties */
+    return ip_RouteTable_get_cell_value_core(netif_default, 1, column, value, value_len);
+  }
+
+  /* find netif with requested route */
+  NETIF_FOREACH(netif) {
+    ip4_addr_t dst;
+    ip4_addr_get_network(&dst, netif_ip4_addr(netif), netif_ip4_netmask(netif));
+
+    if (ip4_addr_cmp(&dst, &test_ip)) {
+      /* fill in object properties */
+      return ip_RouteTable_get_cell_value_core(netif, 0, column, value, value_len);
+    }
+  }
+
+  /* not found */
+  return SNMP_ERR_NOSUCHINSTANCE;
+}
+
+static snmp_err_t
+ip_RouteTable_get_next_cell_instance_and_value(const u32_t *column, struct snmp_obj_id *row_oid, union snmp_variant_value *value, u32_t *value_len)
+{
+  struct netif *netif;
+  struct snmp_next_oid_state state;
+  u32_t result_temp[LWIP_ARRAYSIZE(ip_RouteTable_oid_ranges)];
+  u32_t test_oid[LWIP_ARRAYSIZE(ip_RouteTable_oid_ranges)];
+
+  /* init struct to search next oid */
+  snmp_next_oid_init(&state, row_oid->id, row_oid->len, result_temp, LWIP_ARRAYSIZE(ip_RouteTable_oid_ranges));
+
+  /* check default route */
+  if (netif_default != NULL) {
+    snmp_ip4_to_oid(IP4_ADDR_ANY4, &test_oid[0]);
+    snmp_next_oid_check(&state, test_oid, LWIP_ARRAYSIZE(ip_RouteTable_oid_ranges), netif_default);
+  }
+
+  /* iterate over all possible OIDs to find the next one */
+  NETIF_FOREACH(netif) {
+    ip4_addr_t dst;
+    ip4_addr_get_network(&dst, netif_ip4_addr(netif), netif_ip4_netmask(netif));
+
+    /* check generated OID: is it a candidate for the next one? */
+    if (!ip4_addr_isany_val(dst)) {
+      snmp_ip4_to_oid(&dst, &test_oid[0]);
+      snmp_next_oid_check(&state, test_oid, LWIP_ARRAYSIZE(ip_RouteTable_oid_ranges), netif);
+    }
+  }
+
+  /* did we find a next one? */
+  if (state.status == SNMP_NEXT_OID_STATUS_SUCCESS) {
+    ip4_addr_t dst;
+    snmp_oid_to_ip4(&result_temp[0], &dst);
+    snmp_oid_assign(row_oid, state.next_oid, state.next_oid_len);
+    /* fill in object properties */
+    return ip_RouteTable_get_cell_value_core((struct netif *)state.reference, ip4_addr_isany_val(dst), column, value, value_len);
+  } else {
+    /* not found */
+    return SNMP_ERR_NOSUCHINSTANCE;
+  }
+}
+
+#if LWIP_ARP && LWIP_IPV4
+/* --- ipNetToMediaTable --- */
+
+/* list of allowed value ranges for incoming OID */
+static const struct snmp_oid_range ip_NetToMediaTable_oid_ranges[] = {
+  { 1, 0xff }, /* IfIndex */
+  { 0, 0xff }, /* IP A    */
+  { 0, 0xff }, /* IP B    */
+  { 0, 0xff }, /* IP C    */
+  { 0, 0xff }  /* IP D    */
+};
+
+static snmp_err_t
+ip_NetToMediaTable_get_cell_value_core(size_t arp_table_index, const u32_t *column, union snmp_variant_value *value, u32_t *value_len)
+{
+  ip4_addr_t *ip;
+  struct netif *netif;
+  struct eth_addr *ethaddr;
+
+  etharp_get_entry(arp_table_index, &ip, &netif, &ethaddr);
+
+  /* value */
+  switch (*column) {
+    case 1: /* atIfIndex / ipNetToMediaIfIndex */
+      value->u32 = netif_to_num(netif);
+      break;
+    case 2: /* atPhysAddress / ipNetToMediaPhysAddress */
+      value->ptr = ethaddr;
+      *value_len = sizeof(*ethaddr);
+      break;
+    case 3: /* atNetAddress / ipNetToMediaNetAddress */
+      value->u32 = ip->addr;
+      break;
+    case 4: /* ipNetToMediaType */
+      value->u32 = 3; /* dynamic*/
+      break;
+    default:
+      return SNMP_ERR_NOSUCHINSTANCE;
+  }
+
+  return SNMP_ERR_NOERROR;
+}
+
+static snmp_err_t
+ip_NetToMediaTable_get_cell_value(const u32_t *column, const u32_t *row_oid, u8_t row_oid_len, union snmp_variant_value *value, u32_t *value_len)
+{
+  ip4_addr_t ip_in;
+  u8_t netif_index;
+  size_t i;
+
+  /* check if incoming OID length and if values are in plausible range */
+  if (!snmp_oid_in_range(row_oid, row_oid_len, ip_NetToMediaTable_oid_ranges, LWIP_ARRAYSIZE(ip_NetToMediaTable_oid_ranges))) {
+    return SNMP_ERR_NOSUCHINSTANCE;
+  }
+
+  /* get IP from incoming OID */
+  netif_index = (u8_t)row_oid[0];
+  snmp_oid_to_ip4(&row_oid[1], &ip_in); /* we know it succeeds because of oid_in_range check above */
+
+  /* find requested entry */
+  for (i = 0; i < ARP_TABLE_SIZE; i++) {
+    ip4_addr_t *ip;
+    struct netif *netif;
+    struct eth_addr *ethaddr;
+
+    if (etharp_get_entry(i, &ip, &netif, &ethaddr)) {
+      if ((netif_index == netif_to_num(netif)) && ip4_addr_cmp(&ip_in, ip)) {
+        /* fill in object properties */
+        return ip_NetToMediaTable_get_cell_value_core(i, column, value, value_len);
+      }
+    }
+  }
+
+  /* not found */
+  return SNMP_ERR_NOSUCHINSTANCE;
+}
+
+static snmp_err_t
+ip_NetToMediaTable_get_next_cell_instance_and_value(const u32_t *column, struct snmp_obj_id *row_oid, union snmp_variant_value *value, u32_t *value_len)
+{
+  size_t i;
+  struct snmp_next_oid_state state;
+  u32_t result_temp[LWIP_ARRAYSIZE(ip_NetToMediaTable_oid_ranges)];
+
+  /* init struct to search next oid */
+  snmp_next_oid_init(&state, row_oid->id, row_oid->len, result_temp, LWIP_ARRAYSIZE(ip_NetToMediaTable_oid_ranges));
+
+  /* iterate over all possible OIDs to find the next one */
+  for (i = 0; i < ARP_TABLE_SIZE; i++) {
+    ip4_addr_t *ip;
+    struct netif *netif;
+    struct eth_addr *ethaddr;
+
+    if (etharp_get_entry(i, &ip, &netif, &ethaddr)) {
+      u32_t test_oid[LWIP_ARRAYSIZE(ip_NetToMediaTable_oid_ranges)];
+
+      test_oid[0] = netif_to_num(netif);
+      snmp_ip4_to_oid(ip, &test_oid[1]);
+
+      /* check generated OID: is it a candidate for the next one? */
+      snmp_next_oid_check(&state, test_oid, LWIP_ARRAYSIZE(ip_NetToMediaTable_oid_ranges), LWIP_PTR_NUMERIC_CAST(void *, i));
+    }
+  }
+
+  /* did we find a next one? */
+  if (state.status == SNMP_NEXT_OID_STATUS_SUCCESS) {
+    snmp_oid_assign(row_oid, state.next_oid, state.next_oid_len);
+    /* fill in object properties */
+    return ip_NetToMediaTable_get_cell_value_core(LWIP_PTR_NUMERIC_CAST(size_t, state.reference), column, value, value_len);
+  }
+
+  /* not found */
+  return SNMP_ERR_NOSUCHINSTANCE;
+}
+
+#endif /* LWIP_ARP && LWIP_IPV4 */
+
+static const struct snmp_scalar_node ip_Forwarding      = SNMP_SCALAR_CREATE_NODE(1, SNMP_NODE_INSTANCE_READ_WRITE, SNMP_ASN1_TYPE_INTEGER, ip_get_value, ip_set_test, ip_set_value);
+static const struct snmp_scalar_node ip_DefaultTTL      = SNMP_SCALAR_CREATE_NODE(2, SNMP_NODE_INSTANCE_READ_WRITE, SNMP_ASN1_TYPE_INTEGER, ip_get_value, ip_set_test, ip_set_value);
+static const struct snmp_scalar_node ip_InReceives      = SNMP_SCALAR_CREATE_NODE_READONLY(3, SNMP_ASN1_TYPE_COUNTER, ip_get_value);
+static const struct snmp_scalar_node ip_InHdrErrors     = SNMP_SCALAR_CREATE_NODE_READONLY(4, SNMP_ASN1_TYPE_COUNTER, ip_get_value);
+static const struct snmp_scalar_node ip_InAddrErrors    = SNMP_SCALAR_CREATE_NODE_READONLY(5, SNMP_ASN1_TYPE_COUNTER, ip_get_value);
+static const struct snmp_scalar_node ip_ForwDatagrams   = SNMP_SCALAR_CREATE_NODE_READONLY(6, SNMP_ASN1_TYPE_COUNTER, ip_get_value);
+static const struct snmp_scalar_node ip_InUnknownProtos = SNMP_SCALAR_CREATE_NODE_READONLY(7, SNMP_ASN1_TYPE_COUNTER, ip_get_value);
+static const struct snmp_scalar_node ip_InDiscards      = SNMP_SCALAR_CREATE_NODE_READONLY(8, SNMP_ASN1_TYPE_COUNTER, ip_get_value);
+static const struct snmp_scalar_node ip_InDelivers      = SNMP_SCALAR_CREATE_NODE_READONLY(9, SNMP_ASN1_TYPE_COUNTER, ip_get_value);
+static const struct snmp_scalar_node ip_OutRequests     = SNMP_SCALAR_CREATE_NODE_READONLY(10, SNMP_ASN1_TYPE_COUNTER, ip_get_value);
+static const struct snmp_scalar_node ip_OutDiscards     = SNMP_SCALAR_CREATE_NODE_READONLY(11, SNMP_ASN1_TYPE_COUNTER, ip_get_value);
+static const struct snmp_scalar_node ip_OutNoRoutes     = SNMP_SCALAR_CREATE_NODE_READONLY(12, SNMP_ASN1_TYPE_COUNTER, ip_get_value);
+static const struct snmp_scalar_node ip_ReasmTimeout    = SNMP_SCALAR_CREATE_NODE_READONLY(13, SNMP_ASN1_TYPE_INTEGER, ip_get_value);
+static const struct snmp_scalar_node ip_ReasmReqds      = SNMP_SCALAR_CREATE_NODE_READONLY(14, SNMP_ASN1_TYPE_COUNTER, ip_get_value);
+static const struct snmp_scalar_node ip_ReasmOKs        = SNMP_SCALAR_CREATE_NODE_READONLY(15, SNMP_ASN1_TYPE_COUNTER, ip_get_value);
+static const struct snmp_scalar_node ip_ReasmFails      = SNMP_SCALAR_CREATE_NODE_READONLY(16, SNMP_ASN1_TYPE_COUNTER, ip_get_value);
+static const struct snmp_scalar_node ip_FragOKs         = SNMP_SCALAR_CREATE_NODE_READONLY(17, SNMP_ASN1_TYPE_COUNTER, ip_get_value);
+static const struct snmp_scalar_node ip_FragFails       = SNMP_SCALAR_CREATE_NODE_READONLY(18, SNMP_ASN1_TYPE_COUNTER, ip_get_value);
+static const struct snmp_scalar_node ip_FragCreates     = SNMP_SCALAR_CREATE_NODE_READONLY(19, SNMP_ASN1_TYPE_COUNTER, ip_get_value);
+static const struct snmp_scalar_node ip_RoutingDiscards = SNMP_SCALAR_CREATE_NODE_READONLY(23, SNMP_ASN1_TYPE_COUNTER, ip_get_value);
+
+static const struct snmp_table_simple_col_def ip_AddrTable_columns[] = {
+  { 1, SNMP_ASN1_TYPE_IPADDR,  SNMP_VARIANT_VALUE_TYPE_U32 }, /* ipAdEntAddr */
+  { 2, SNMP_ASN1_TYPE_INTEGER, SNMP_VARIANT_VALUE_TYPE_U32 }, /* ipAdEntIfIndex */
+  { 3, SNMP_ASN1_TYPE_IPADDR,  SNMP_VARIANT_VALUE_TYPE_U32 }, /* ipAdEntNetMask */
+  { 4, SNMP_ASN1_TYPE_INTEGER, SNMP_VARIANT_VALUE_TYPE_U32 }, /* ipAdEntBcastAddr */
+  { 5, SNMP_ASN1_TYPE_INTEGER, SNMP_VARIANT_VALUE_TYPE_U32 }  /* ipAdEntReasmMaxSize */
+};
+
+static const struct snmp_table_simple_node ip_AddrTable = SNMP_TABLE_CREATE_SIMPLE(20, ip_AddrTable_columns, ip_AddrTable_get_cell_value, ip_AddrTable_get_next_cell_instance_and_value);
+
+static const struct snmp_table_simple_col_def ip_RouteTable_columns[] = {
+  {  1, SNMP_ASN1_TYPE_IPADDR,    SNMP_VARIANT_VALUE_TYPE_U32 }, /* ipRouteDest */
+  {  2, SNMP_ASN1_TYPE_INTEGER,   SNMP_VARIANT_VALUE_TYPE_U32 }, /* ipRouteIfIndex */
+  {  3, SNMP_ASN1_TYPE_INTEGER,   SNMP_VARIANT_VALUE_TYPE_S32 }, /* ipRouteMetric1 */
+  {  4, SNMP_ASN1_TYPE_INTEGER,   SNMP_VARIANT_VALUE_TYPE_S32 }, /* ipRouteMetric2 */
+  {  5, SNMP_ASN1_TYPE_INTEGER,   SNMP_VARIANT_VALUE_TYPE_S32 }, /* ipRouteMetric3 */
+  {  6, SNMP_ASN1_TYPE_INTEGER,   SNMP_VARIANT_VALUE_TYPE_S32 }, /* ipRouteMetric4 */
+  {  7, SNMP_ASN1_TYPE_IPADDR,    SNMP_VARIANT_VALUE_TYPE_U32 }, /* ipRouteNextHop */
+  {  8, SNMP_ASN1_TYPE_INTEGER,   SNMP_VARIANT_VALUE_TYPE_U32 }, /* ipRouteType */
+  {  9, SNMP_ASN1_TYPE_INTEGER,   SNMP_VARIANT_VALUE_TYPE_U32 }, /* ipRouteProto */
+  { 10, SNMP_ASN1_TYPE_INTEGER,   SNMP_VARIANT_VALUE_TYPE_U32 }, /* ipRouteAge */
+  { 11, SNMP_ASN1_TYPE_IPADDR,    SNMP_VARIANT_VALUE_TYPE_U32 }, /* ipRouteMask */
+  { 12, SNMP_ASN1_TYPE_INTEGER,   SNMP_VARIANT_VALUE_TYPE_S32 }, /* ipRouteMetric5 */
+  { 13, SNMP_ASN1_TYPE_OBJECT_ID, SNMP_VARIANT_VALUE_TYPE_PTR }  /* ipRouteInfo */
+};
+
+static const struct snmp_table_simple_node ip_RouteTable = SNMP_TABLE_CREATE_SIMPLE(21, ip_RouteTable_columns, ip_RouteTable_get_cell_value, ip_RouteTable_get_next_cell_instance_and_value);
+#endif /* LWIP_IPV4 */
+
+#if LWIP_ARP && LWIP_IPV4
+static const struct snmp_table_simple_col_def ip_NetToMediaTable_columns[] = {
+  {  1, SNMP_ASN1_TYPE_INTEGER,      SNMP_VARIANT_VALUE_TYPE_U32 }, /* ipNetToMediaIfIndex */
+  {  2, SNMP_ASN1_TYPE_OCTET_STRING, SNMP_VARIANT_VALUE_TYPE_PTR }, /* ipNetToMediaPhysAddress */
+  {  3, SNMP_ASN1_TYPE_IPADDR,       SNMP_VARIANT_VALUE_TYPE_U32 }, /* ipNetToMediaNetAddress */
+  {  4, SNMP_ASN1_TYPE_INTEGER,      SNMP_VARIANT_VALUE_TYPE_U32 }  /* ipNetToMediaType */
+};
+
+static const struct snmp_table_simple_node ip_NetToMediaTable = SNMP_TABLE_CREATE_SIMPLE(22, ip_NetToMediaTable_columns, ip_NetToMediaTable_get_cell_value, ip_NetToMediaTable_get_next_cell_instance_and_value);
+#endif /* LWIP_ARP && LWIP_IPV4 */
+
+#if LWIP_IPV4
+/* the following nodes access variables in LWIP stack from SNMP worker thread and must therefore be synced to LWIP (TCPIP) thread */
+CREATE_LWIP_SYNC_NODE( 1, ip_Forwarding)
+CREATE_LWIP_SYNC_NODE( 2, ip_DefaultTTL)
+CREATE_LWIP_SYNC_NODE( 3, ip_InReceives)
+CREATE_LWIP_SYNC_NODE( 4, ip_InHdrErrors)
+CREATE_LWIP_SYNC_NODE( 5, ip_InAddrErrors)
+CREATE_LWIP_SYNC_NODE( 6, ip_ForwDatagrams)
+CREATE_LWIP_SYNC_NODE( 7, ip_InUnknownProtos)
+CREATE_LWIP_SYNC_NODE( 8, ip_InDiscards)
+CREATE_LWIP_SYNC_NODE( 9, ip_InDelivers)
+CREATE_LWIP_SYNC_NODE(10, ip_OutRequests)
+CREATE_LWIP_SYNC_NODE(11, ip_OutDiscards)
+CREATE_LWIP_SYNC_NODE(12, ip_OutNoRoutes)
+CREATE_LWIP_SYNC_NODE(13, ip_ReasmTimeout)
+CREATE_LWIP_SYNC_NODE(14, ip_ReasmReqds)
+CREATE_LWIP_SYNC_NODE(15, ip_ReasmOKs)
+CREATE_LWIP_SYNC_NODE(15, ip_ReasmFails)
+CREATE_LWIP_SYNC_NODE(17, ip_FragOKs)
+CREATE_LWIP_SYNC_NODE(18, ip_FragFails)
+CREATE_LWIP_SYNC_NODE(19, ip_FragCreates)
+CREATE_LWIP_SYNC_NODE(20, ip_AddrTable)
+CREATE_LWIP_SYNC_NODE(21, ip_RouteTable)
+#if LWIP_ARP
+CREATE_LWIP_SYNC_NODE(22, ip_NetToMediaTable)
+#endif /* LWIP_ARP */
+CREATE_LWIP_SYNC_NODE(23, ip_RoutingDiscards)
+
+static const struct snmp_node *const ip_nodes[] = {
+  &SYNC_NODE_NAME(ip_Forwarding).node.node,
+  &SYNC_NODE_NAME(ip_DefaultTTL).node.node,
+  &SYNC_NODE_NAME(ip_InReceives).node.node,
+  &SYNC_NODE_NAME(ip_InHdrErrors).node.node,
+  &SYNC_NODE_NAME(ip_InAddrErrors).node.node,
+  &SYNC_NODE_NAME(ip_ForwDatagrams).node.node,
+  &SYNC_NODE_NAME(ip_InUnknownProtos).node.node,
+  &SYNC_NODE_NAME(ip_InDiscards).node.node,
+  &SYNC_NODE_NAME(ip_InDelivers).node.node,
+  &SYNC_NODE_NAME(ip_OutRequests).node.node,
+  &SYNC_NODE_NAME(ip_OutDiscards).node.node,
+  &SYNC_NODE_NAME(ip_OutNoRoutes).node.node,
+  &SYNC_NODE_NAME(ip_ReasmTimeout).node.node,
+  &SYNC_NODE_NAME(ip_ReasmReqds).node.node,
+  &SYNC_NODE_NAME(ip_ReasmOKs).node.node,
+  &SYNC_NODE_NAME(ip_ReasmFails).node.node,
+  &SYNC_NODE_NAME(ip_FragOKs).node.node,
+  &SYNC_NODE_NAME(ip_FragFails).node.node,
+  &SYNC_NODE_NAME(ip_FragCreates).node.node,
+  &SYNC_NODE_NAME(ip_AddrTable).node.node,
+  &SYNC_NODE_NAME(ip_RouteTable).node.node,
+#if LWIP_ARP
+  &SYNC_NODE_NAME(ip_NetToMediaTable).node.node,
+#endif /* LWIP_ARP */
+  &SYNC_NODE_NAME(ip_RoutingDiscards).node.node
+};
+
+const struct snmp_tree_node snmp_mib2_ip_root = SNMP_CREATE_TREE_NODE(4, ip_nodes);
+#endif /* LWIP_IPV4 */
+
+/* --- at .1.3.6.1.2.1.3 ----------------------------------------------------- */
+
+#if LWIP_ARP && LWIP_IPV4
+/* at node table is a subset of ip_nettomedia table (same rows but less columns) */
+static const struct snmp_table_simple_col_def at_Table_columns[] = {
+  { 1, SNMP_ASN1_TYPE_INTEGER,      SNMP_VARIANT_VALUE_TYPE_U32 }, /* atIfIndex */
+  { 2, SNMP_ASN1_TYPE_OCTET_STRING, SNMP_VARIANT_VALUE_TYPE_PTR }, /* atPhysAddress */
+  { 3, SNMP_ASN1_TYPE_IPADDR,       SNMP_VARIANT_VALUE_TYPE_U32 }  /* atNetAddress */
+};
+
+static const struct snmp_table_simple_node at_Table = SNMP_TABLE_CREATE_SIMPLE(1, at_Table_columns, ip_NetToMediaTable_get_cell_value, ip_NetToMediaTable_get_next_cell_instance_and_value);
+
+/* the following nodes access variables in LWIP stack from SNMP worker thread and must therefore be synced to LWIP (TCPIP) thread */
+CREATE_LWIP_SYNC_NODE(1, at_Table)
+
+static const struct snmp_node *const at_nodes[] = {
+  &SYNC_NODE_NAME(at_Table).node.node
+};
+
+const struct snmp_tree_node snmp_mib2_at_root = SNMP_CREATE_TREE_NODE(3, at_nodes);
+#endif /* LWIP_ARP && LWIP_IPV4 */
+
+#endif /* LWIP_SNMP && SNMP_LWIP_MIB2 */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/apps/snmp/snmp_mib2_snmp.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/apps/snmp/snmp_mib2_snmp.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/apps/snmp/snmp_mib2_snmp.c	(revision 457)
@@ -0,0 +1,227 @@
+/**
+ * @file
+ * Management Information Base II (RFC1213) SNMP objects and functions.
+ */
+
+/*
+ * Copyright (c) 2006 Axon Digital Design B.V., The Netherlands.
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * Author: Dirk Ziegelmeier <dziegel@gmx.de>
+ *         Christiaan Simons <christiaan.simons@axon.tv>
+ */
+
+#include "lwip/snmp.h"
+#include "lwip/apps/snmp.h"
+#include "lwip/apps/snmp_core.h"
+#include "lwip/apps/snmp_mib2.h"
+#include "lwip/apps/snmp_scalar.h"
+
+#if LWIP_SNMP && SNMP_LWIP_MIB2
+
+#define MIB2_AUTH_TRAPS_ENABLED  1
+#define MIB2_AUTH_TRAPS_DISABLED 2
+
+/* --- snmp .1.3.6.1.2.1.11 ----------------------------------------------------- */
+static s16_t
+snmp_get_value(const struct snmp_scalar_array_node_def *node, void *value)
+{
+  u32_t *uint_ptr = (u32_t *)value;
+  switch (node->oid) {
+    case 1: /* snmpInPkts */
+      *uint_ptr = snmp_stats.inpkts;
+      break;
+    case 2: /* snmpOutPkts */
+      *uint_ptr = snmp_stats.outpkts;
+      break;
+    case 3: /* snmpInBadVersions */
+      *uint_ptr = snmp_stats.inbadversions;
+      break;
+    case 4: /* snmpInBadCommunityNames */
+      *uint_ptr = snmp_stats.inbadcommunitynames;
+      break;
+    case 5: /* snmpInBadCommunityUses */
+      *uint_ptr = snmp_stats.inbadcommunityuses;
+      break;
+    case 6: /* snmpInASNParseErrs */
+      *uint_ptr = snmp_stats.inasnparseerrs;
+      break;
+    case 8: /* snmpInTooBigs */
+      *uint_ptr = snmp_stats.intoobigs;
+      break;
+    case 9: /* snmpInNoSuchNames */
+      *uint_ptr = snmp_stats.innosuchnames;
+      break;
+    case 10: /* snmpInBadValues */
+      *uint_ptr = snmp_stats.inbadvalues;
+      break;
+    case 11: /* snmpInReadOnlys */
+      *uint_ptr = snmp_stats.inreadonlys;
+      break;
+    case 12: /* snmpInGenErrs */
+      *uint_ptr = snmp_stats.ingenerrs;
+      break;
+    case 13: /* snmpInTotalReqVars */
+      *uint_ptr = snmp_stats.intotalreqvars;
+      break;
+    case 14: /* snmpInTotalSetVars */
+      *uint_ptr = snmp_stats.intotalsetvars;
+      break;
+    case 15: /* snmpInGetRequests */
+      *uint_ptr = snmp_stats.ingetrequests;
+      break;
+    case 16: /* snmpInGetNexts */
+      *uint_ptr = snmp_stats.ingetnexts;
+      break;
+    case 17: /* snmpInSetRequests */
+      *uint_ptr = snmp_stats.insetrequests;
+      break;
+    case 18: /* snmpInGetResponses */
+      *uint_ptr = snmp_stats.ingetresponses;
+      break;
+    case 19: /* snmpInTraps */
+      *uint_ptr = snmp_stats.intraps;
+      break;
+    case 20: /* snmpOutTooBigs */
+      *uint_ptr = snmp_stats.outtoobigs;
+      break;
+    case 21: /* snmpOutNoSuchNames */
+      *uint_ptr = snmp_stats.outnosuchnames;
+      break;
+    case 22: /* snmpOutBadValues */
+      *uint_ptr = snmp_stats.outbadvalues;
+      break;
+    case 24: /* snmpOutGenErrs */
+      *uint_ptr = snmp_stats.outgenerrs;
+      break;
+    case 25: /* snmpOutGetRequests */
+      *uint_ptr = snmp_stats.outgetrequests;
+      break;
+    case 26: /* snmpOutGetNexts */
+      *uint_ptr = snmp_stats.outgetnexts;
+      break;
+    case 27: /* snmpOutSetRequests */
+      *uint_ptr = snmp_stats.outsetrequests;
+      break;
+    case 28: /* snmpOutGetResponses */
+      *uint_ptr = snmp_stats.outgetresponses;
+      break;
+    case 29: /* snmpOutTraps */
+      *uint_ptr = snmp_stats.outtraps;
+      break;
+    case 30: /* snmpEnableAuthenTraps */
+      if (snmp_get_auth_traps_enabled() == SNMP_AUTH_TRAPS_DISABLED) {
+        *uint_ptr = MIB2_AUTH_TRAPS_DISABLED;
+      } else {
+        *uint_ptr = MIB2_AUTH_TRAPS_ENABLED;
+      }
+      break;
+    case 31: /* snmpSilentDrops */
+      *uint_ptr = 0; /* not supported */
+      break;
+    case 32: /* snmpProxyDrops */
+      *uint_ptr = 0; /* not supported */
+      break;
+    default:
+      LWIP_DEBUGF(SNMP_MIB_DEBUG, ("snmp_get_value(): unknown id: %"S32_F"\n", node->oid));
+      return 0;
+  }
+
+  return sizeof(*uint_ptr);
+}
+
+static snmp_err_t
+snmp_set_test(const struct snmp_scalar_array_node_def *node, u16_t len, void *value)
+{
+  snmp_err_t ret = SNMP_ERR_WRONGVALUE;
+  LWIP_UNUSED_ARG(len);
+
+  if (node->oid == 30) {
+    /* snmpEnableAuthenTraps */
+    s32_t *sint_ptr = (s32_t *)value;
+
+    /* we should have writable non-volatile mem here */
+    if ((*sint_ptr == MIB2_AUTH_TRAPS_DISABLED) || (*sint_ptr == MIB2_AUTH_TRAPS_ENABLED)) {
+      ret = SNMP_ERR_NOERROR;
+    }
+  }
+  return ret;
+}
+
+static snmp_err_t
+snmp_set_value(const struct snmp_scalar_array_node_def *node, u16_t len, void *value)
+{
+  LWIP_UNUSED_ARG(len);
+
+  if (node->oid == 30) {
+    /* snmpEnableAuthenTraps */
+    s32_t *sint_ptr = (s32_t *)value;
+    if (*sint_ptr == MIB2_AUTH_TRAPS_DISABLED) {
+      snmp_set_auth_traps_enabled(SNMP_AUTH_TRAPS_DISABLED);
+    } else {
+      snmp_set_auth_traps_enabled(SNMP_AUTH_TRAPS_ENABLED);
+    }
+  }
+
+  return SNMP_ERR_NOERROR;
+}
+
+/* the following nodes access variables in SNMP stack (snmp_stats) from SNMP worker thread -> OK, no sync needed */
+static const struct snmp_scalar_array_node_def snmp_nodes[] = {
+  { 1, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY},  /* snmpInPkts */
+  { 2, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY},  /* snmpOutPkts */
+  { 3, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY},  /* snmpInBadVersions */
+  { 4, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY},  /* snmpInBadCommunityNames */
+  { 5, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY},  /* snmpInBadCommunityUses */
+  { 6, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY},  /* snmpInASNParseErrs */
+  { 8, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY},  /* snmpInTooBigs */
+  { 9, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY},  /* snmpInNoSuchNames */
+  {10, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY},  /* snmpInBadValues */
+  {11, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY},  /* snmpInReadOnlys */
+  {12, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY},  /* snmpInGenErrs */
+  {13, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY},  /* snmpInTotalReqVars */
+  {14, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY},  /* snmpInTotalSetVars */
+  {15, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY},  /* snmpInGetRequests */
+  {16, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY},  /* snmpInGetNexts */
+  {17, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY},  /* snmpInSetRequests */
+  {18, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY},  /* snmpInGetResponses */
+  {19, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY},  /* snmpInTraps */
+  {20, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY},  /* snmpOutTooBigs */
+  {21, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY},  /* snmpOutNoSuchNames */
+  {22, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY},  /* snmpOutBadValues */
+  {24, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY},  /* snmpOutGenErrs */
+  {25, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY},  /* snmpOutGetRequests */
+  {26, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY},  /* snmpOutGetNexts */
+  {27, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY},  /* snmpOutSetRequests */
+  {28, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY},  /* snmpOutGetResponses */
+  {29, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY},  /* snmpOutTraps */
+  {30, SNMP_ASN1_TYPE_INTEGER, SNMP_NODE_INSTANCE_READ_WRITE}, /* snmpEnableAuthenTraps */
+  {31, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY},  /* snmpSilentDrops */
+  {32, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY}   /* snmpProxyDrops */
+};
+
+const struct snmp_scalar_array_node snmp_mib2_snmp_root = SNMP_SCALAR_CREATE_ARRAY_NODE(11, snmp_nodes, snmp_get_value, snmp_set_test, snmp_set_value);
+
+#endif /* LWIP_SNMP && SNMP_LWIP_MIB2 */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/apps/snmp/snmp_mib2_system.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/apps/snmp/snmp_mib2_system.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/apps/snmp/snmp_mib2_system.c	(revision 457)
@@ -0,0 +1,376 @@
+/**
+ * @file
+ * Management Information Base II (RFC1213) SYSTEM objects and functions.
+ */
+
+/*
+ * Copyright (c) 2006 Axon Digital Design B.V., The Netherlands.
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * Author: Dirk Ziegelmeier <dziegel@gmx.de>
+ *         Christiaan Simons <christiaan.simons@axon.tv>
+ */
+
+#include "lwip/snmp.h"
+#include "lwip/apps/snmp.h"
+#include "lwip/apps/snmp_core.h"
+#include "lwip/apps/snmp_mib2.h"
+#include "lwip/apps/snmp_table.h"
+#include "lwip/apps/snmp_scalar.h"
+#include "lwip/sys.h"
+
+#include <string.h>
+
+#if LWIP_SNMP && SNMP_LWIP_MIB2
+
+#if SNMP_USE_NETCONN
+#define SYNC_NODE_NAME(node_name) node_name ## _synced
+#define CREATE_LWIP_SYNC_NODE(oid, node_name) \
+   static const struct snmp_threadsync_node node_name ## _synced = SNMP_CREATE_THREAD_SYNC_NODE(oid, &node_name.node, &snmp_mib2_lwip_locks);
+#else
+#define SYNC_NODE_NAME(node_name) node_name
+#define CREATE_LWIP_SYNC_NODE(oid, node_name)
+#endif
+
+/* --- system .1.3.6.1.2.1.1 ----------------------------------------------------- */
+
+/** mib-2.system.sysDescr */
+static const u8_t   sysdescr_default[] = SNMP_LWIP_MIB2_SYSDESC;
+static const u8_t  *sysdescr           = sysdescr_default;
+static const u16_t *sysdescr_len       = NULL; /* use strlen for determining len */
+
+/** mib-2.system.sysContact */
+static const u8_t   syscontact_default[]     = SNMP_LWIP_MIB2_SYSCONTACT;
+static const u8_t  *syscontact               = syscontact_default;
+static const u16_t *syscontact_len           = NULL; /* use strlen for determining len */
+static u8_t        *syscontact_wr            = NULL; /* if writable, points to the same buffer as syscontact (required for correct constness) */
+static u16_t       *syscontact_wr_len        = NULL; /* if writable, points to the same buffer as syscontact_len (required for correct constness) */
+static u16_t        syscontact_bufsize       = 0;    /* 0=not writable */
+
+/** mib-2.system.sysName */
+static const u8_t   sysname_default[]        = SNMP_LWIP_MIB2_SYSNAME;
+static const u8_t  *sysname                  = sysname_default;
+static const u16_t *sysname_len              = NULL; /* use strlen for determining len */
+static u8_t        *sysname_wr               = NULL; /* if writable, points to the same buffer as sysname (required for correct constness) */
+static u16_t       *sysname_wr_len           = NULL; /* if writable, points to the same buffer as sysname_len (required for correct constness) */
+static u16_t        sysname_bufsize          = 0;    /* 0=not writable */
+
+/** mib-2.system.sysLocation */
+static const u8_t   syslocation_default[]    = SNMP_LWIP_MIB2_SYSLOCATION;
+static const u8_t  *syslocation              = syslocation_default;
+static const u16_t *syslocation_len           = NULL; /* use strlen for determining len */
+static u8_t        *syslocation_wr            = NULL; /* if writable, points to the same buffer as syslocation (required for correct constness) */
+static u16_t       *syslocation_wr_len        = NULL; /* if writable, points to the same buffer as syslocation_len (required for correct constness) */
+static u16_t        syslocation_bufsize       = 0;    /* 0=not writable */
+
+/**
+ * @ingroup snmp_mib2
+ * Initializes sysDescr pointers.
+ *
+ * @param str if non-NULL then copy str pointer
+ * @param len points to string length, excluding zero terminator
+ */
+void
+snmp_mib2_set_sysdescr(const u8_t *str, const u16_t *len)
+{
+  if (str != NULL) {
+    sysdescr     = str;
+    sysdescr_len = len;
+  }
+}
+
+/**
+ * @ingroup snmp_mib2
+ * Initializes sysContact pointers
+ *
+ * @param ocstr if non-NULL then copy str pointer
+ * @param ocstrlen points to string length, excluding zero terminator.
+ *        if set to NULL it is assumed that ocstr is NULL-terminated.
+ * @param bufsize size of the buffer in bytes.
+ *        (this is required because the buffer can be overwritten by snmp-set)
+ *        if ocstrlen is NULL buffer needs space for terminating 0 byte.
+ *        otherwise complete buffer is used for string.
+ *        if bufsize is set to 0, the value is regarded as read-only.
+ */
+void
+snmp_mib2_set_syscontact(u8_t *ocstr, u16_t *ocstrlen, u16_t bufsize)
+{
+  if (ocstr != NULL) {
+    syscontact         = ocstr;
+    syscontact_wr      = ocstr;
+    syscontact_len     = ocstrlen;
+    syscontact_wr_len  = ocstrlen;
+    syscontact_bufsize = bufsize;
+  }
+}
+
+/**
+ * @ingroup snmp_mib2
+ * see \ref snmp_mib2_set_syscontact but set pointer to readonly memory
+ */
+void
+snmp_mib2_set_syscontact_readonly(const u8_t *ocstr, const u16_t *ocstrlen)
+{
+  if (ocstr != NULL) {
+    syscontact         = ocstr;
+    syscontact_len     = ocstrlen;
+    syscontact_wr      = NULL;
+    syscontact_wr_len  = NULL;
+    syscontact_bufsize = 0;
+  }
+}
+
+
+/**
+ * @ingroup snmp_mib2
+ * Initializes sysName pointers
+ *
+ * @param ocstr if non-NULL then copy str pointer
+ * @param ocstrlen points to string length, excluding zero terminator.
+ *        if set to NULL it is assumed that ocstr is NULL-terminated.
+ * @param bufsize size of the buffer in bytes.
+ *        (this is required because the buffer can be overwritten by snmp-set)
+ *        if ocstrlen is NULL buffer needs space for terminating 0 byte.
+ *        otherwise complete buffer is used for string.
+ *        if bufsize is set to 0, the value is regarded as read-only.
+ */
+void
+snmp_mib2_set_sysname(u8_t *ocstr, u16_t *ocstrlen, u16_t bufsize)
+{
+  if (ocstr != NULL) {
+    sysname         = ocstr;
+    sysname_wr      = ocstr;
+    sysname_len     = ocstrlen;
+    sysname_wr_len  = ocstrlen;
+    sysname_bufsize = bufsize;
+  }
+}
+
+/**
+ * @ingroup snmp_mib2
+ * see \ref snmp_mib2_set_sysname but set pointer to readonly memory
+ */
+void
+snmp_mib2_set_sysname_readonly(const u8_t *ocstr, const u16_t *ocstrlen)
+{
+  if (ocstr != NULL) {
+    sysname         = ocstr;
+    sysname_len     = ocstrlen;
+    sysname_wr      = NULL;
+    sysname_wr_len  = NULL;
+    sysname_bufsize = 0;
+  }
+}
+
+/**
+ * @ingroup snmp_mib2
+ * Initializes sysLocation pointers
+ *
+ * @param ocstr if non-NULL then copy str pointer
+ * @param ocstrlen points to string length, excluding zero terminator.
+ *        if set to NULL it is assumed that ocstr is NULL-terminated.
+ * @param bufsize size of the buffer in bytes.
+ *        (this is required because the buffer can be overwritten by snmp-set)
+ *        if ocstrlen is NULL buffer needs space for terminating 0 byte.
+ *        otherwise complete buffer is used for string.
+ *        if bufsize is set to 0, the value is regarded as read-only.
+ */
+void
+snmp_mib2_set_syslocation(u8_t *ocstr, u16_t *ocstrlen, u16_t bufsize)
+{
+  if (ocstr != NULL) {
+    syslocation         = ocstr;
+    syslocation_wr      = ocstr;
+    syslocation_len     = ocstrlen;
+    syslocation_wr_len  = ocstrlen;
+    syslocation_bufsize = bufsize;
+  }
+}
+
+/**
+ * @ingroup snmp_mib2
+ * see \ref snmp_mib2_set_syslocation but set pointer to readonly memory
+ */
+void
+snmp_mib2_set_syslocation_readonly(const u8_t *ocstr, const u16_t *ocstrlen)
+{
+  if (ocstr != NULL) {
+    syslocation         = ocstr;
+    syslocation_len     = ocstrlen;
+    syslocation_wr      = NULL;
+    syslocation_wr_len  = NULL;
+    syslocation_bufsize = 0;
+  }
+}
+
+
+static s16_t
+system_get_value(const struct snmp_scalar_array_node_def *node, void *value)
+{
+  const u8_t  *var = NULL;
+  const s16_t *var_len;
+  u16_t result;
+
+  switch (node->oid) {
+    case 1: /* sysDescr */
+      var     = sysdescr;
+      var_len = (const s16_t *)sysdescr_len;
+      break;
+    case 2: { /* sysObjectID */
+      const struct snmp_obj_id *dev_enterprise_oid = snmp_get_device_enterprise_oid();
+      MEMCPY(value, dev_enterprise_oid->id, dev_enterprise_oid->len * sizeof(u32_t));
+      return dev_enterprise_oid->len * sizeof(u32_t);
+    }
+    case 3: /* sysUpTime */
+      MIB2_COPY_SYSUPTIME_TO((u32_t *)value);
+      return sizeof(u32_t);
+    case 4: /* sysContact */
+      var     = syscontact;
+      var_len = (const s16_t *)syscontact_len;
+      break;
+    case 5: /* sysName */
+      var     = sysname;
+      var_len = (const s16_t *)sysname_len;
+      break;
+    case 6: /* sysLocation */
+      var     = syslocation;
+      var_len = (const s16_t *)syslocation_len;
+      break;
+    case 7: /* sysServices */
+      *(s32_t *)value = SNMP_SYSSERVICES;
+      return sizeof(s32_t);
+    default:
+      LWIP_DEBUGF(SNMP_MIB_DEBUG, ("system_get_value(): unknown id: %"S32_F"\n", node->oid));
+      return 0;
+  }
+
+  /* handle string values (OID 1,4,5 and 6) */
+  LWIP_ASSERT("", (value != NULL));
+  if (var_len == NULL) {
+    result = (s16_t)strlen((const char *)var);
+  } else {
+    result = *var_len;
+  }
+  MEMCPY(value, var, result);
+  return result;
+}
+
+static snmp_err_t
+system_set_test(const struct snmp_scalar_array_node_def *node, u16_t len, void *value)
+{
+  snmp_err_t ret = SNMP_ERR_WRONGVALUE;
+  const u16_t *var_bufsize  = NULL;
+  const u16_t *var_wr_len;
+
+  LWIP_UNUSED_ARG(value);
+
+  switch (node->oid) {
+    case 4: /* sysContact */
+      var_bufsize  = &syscontact_bufsize;
+      var_wr_len   = syscontact_wr_len;
+      break;
+    case 5: /* sysName */
+      var_bufsize  = &sysname_bufsize;
+      var_wr_len   = sysname_wr_len;
+      break;
+    case 6: /* sysLocation */
+      var_bufsize  = &syslocation_bufsize;
+      var_wr_len   = syslocation_wr_len;
+      break;
+    default:
+      LWIP_DEBUGF(SNMP_MIB_DEBUG, ("system_set_test(): unknown id: %"S32_F"\n", node->oid));
+      return ret;
+  }
+
+  /* check if value is writable at all */
+  if (*var_bufsize > 0) {
+    if (var_wr_len == NULL) {
+      /* we have to take the terminating 0 into account */
+      if (len < *var_bufsize) {
+        ret = SNMP_ERR_NOERROR;
+      }
+    } else {
+      if (len <= *var_bufsize) {
+        ret = SNMP_ERR_NOERROR;
+      }
+    }
+  } else {
+    ret = SNMP_ERR_NOTWRITABLE;
+  }
+
+  return ret;
+}
+
+static snmp_err_t
+system_set_value(const struct snmp_scalar_array_node_def *node, u16_t len, void *value)
+{
+  u8_t  *var_wr = NULL;
+  u16_t *var_wr_len;
+
+  switch (node->oid) {
+    case 4: /* sysContact */
+      var_wr     = syscontact_wr;
+      var_wr_len = syscontact_wr_len;
+      break;
+    case 5: /* sysName */
+      var_wr     = sysname_wr;
+      var_wr_len = sysname_wr_len;
+      break;
+    case 6: /* sysLocation */
+      var_wr     = syslocation_wr;
+      var_wr_len = syslocation_wr_len;
+      break;
+    default:
+      LWIP_DEBUGF(SNMP_MIB_DEBUG, ("system_set_value(): unknown id: %"S32_F"\n", node->oid));
+      return SNMP_ERR_GENERROR;
+  }
+
+  /* no need to check size of target buffer, this was already done in set_test method */
+  LWIP_ASSERT("", var_wr != NULL);
+  MEMCPY(var_wr, value, len);
+
+  if (var_wr_len == NULL) {
+    /* add terminating 0 */
+    var_wr[len] = 0;
+  } else {
+    *var_wr_len = len;
+  }
+
+  return SNMP_ERR_NOERROR;
+}
+
+static const struct snmp_scalar_array_node_def system_nodes[] = {
+  {1, SNMP_ASN1_TYPE_OCTET_STRING, SNMP_NODE_INSTANCE_READ_ONLY},  /* sysDescr */
+  {2, SNMP_ASN1_TYPE_OBJECT_ID,    SNMP_NODE_INSTANCE_READ_ONLY},  /* sysObjectID */
+  {3, SNMP_ASN1_TYPE_TIMETICKS,    SNMP_NODE_INSTANCE_READ_ONLY},  /* sysUpTime */
+  {4, SNMP_ASN1_TYPE_OCTET_STRING, SNMP_NODE_INSTANCE_READ_WRITE}, /* sysContact */
+  {5, SNMP_ASN1_TYPE_OCTET_STRING, SNMP_NODE_INSTANCE_READ_WRITE}, /* sysName */
+  {6, SNMP_ASN1_TYPE_OCTET_STRING, SNMP_NODE_INSTANCE_READ_WRITE}, /* sysLocation */
+  {7, SNMP_ASN1_TYPE_INTEGER,      SNMP_NODE_INSTANCE_READ_ONLY}   /* sysServices */
+};
+
+const struct snmp_scalar_array_node snmp_mib2_system_node = SNMP_SCALAR_CREATE_ARRAY_NODE(1, system_nodes, system_get_value, system_set_test, system_set_value);
+
+#endif /* LWIP_SNMP && SNMP_LWIP_MIB2 */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/apps/snmp/snmp_mib2_tcp.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/apps/snmp/snmp_mib2_tcp.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/apps/snmp/snmp_mib2_tcp.c	(revision 457)
@@ -0,0 +1,607 @@
+/**
+ * @file
+ * Management Information Base II (RFC1213) TCP objects and functions.
+ */
+
+/*
+ * Copyright (c) 2006 Axon Digital Design B.V., The Netherlands.
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * Author: Dirk Ziegelmeier <dziegel@gmx.de>
+ *         Christiaan Simons <christiaan.simons@axon.tv>
+ */
+
+#include "lwip/snmp.h"
+#include "lwip/apps/snmp.h"
+#include "lwip/apps/snmp_core.h"
+#include "lwip/apps/snmp_mib2.h"
+#include "lwip/apps/snmp_table.h"
+#include "lwip/apps/snmp_scalar.h"
+#include "lwip/tcp.h"
+#include "lwip/priv/tcp_priv.h"
+#include "lwip/stats.h"
+
+#include <string.h>
+
+#if LWIP_SNMP && SNMP_LWIP_MIB2 && LWIP_TCP
+
+#if SNMP_USE_NETCONN
+#define SYNC_NODE_NAME(node_name) node_name ## _synced
+#define CREATE_LWIP_SYNC_NODE(oid, node_name) \
+   static const struct snmp_threadsync_node node_name ## _synced = SNMP_CREATE_THREAD_SYNC_NODE(oid, &node_name.node, &snmp_mib2_lwip_locks);
+#else
+#define SYNC_NODE_NAME(node_name) node_name
+#define CREATE_LWIP_SYNC_NODE(oid, node_name)
+#endif
+
+/* --- tcp .1.3.6.1.2.1.6 ----------------------------------------------------- */
+
+static s16_t
+tcp_get_value(struct snmp_node_instance *instance, void *value)
+{
+  u32_t *uint_ptr = (u32_t *)value;
+  s32_t *sint_ptr = (s32_t *)value;
+
+  switch (instance->node->oid) {
+    case 1: /* tcpRtoAlgorithm, vanj(4) */
+      *sint_ptr = 4;
+      return sizeof(*sint_ptr);
+    case 2: /* tcpRtoMin */
+      /* @todo not the actual value, a guess,
+          needs to be calculated */
+      *sint_ptr = 1000;
+      return sizeof(*sint_ptr);
+    case 3: /* tcpRtoMax */
+      /* @todo not the actual value, a guess,
+          needs to be calculated */
+      *sint_ptr = 60000;
+      return sizeof(*sint_ptr);
+    case 4: /* tcpMaxConn */
+      *sint_ptr = MEMP_NUM_TCP_PCB;
+      return sizeof(*sint_ptr);
+    case 5: /* tcpActiveOpens */
+      *uint_ptr = STATS_GET(mib2.tcpactiveopens);
+      return sizeof(*uint_ptr);
+    case 6: /* tcpPassiveOpens */
+      *uint_ptr = STATS_GET(mib2.tcppassiveopens);
+      return sizeof(*uint_ptr);
+    case 7: /* tcpAttemptFails */
+      *uint_ptr = STATS_GET(mib2.tcpattemptfails);
+      return sizeof(*uint_ptr);
+    case 8: /* tcpEstabResets */
+      *uint_ptr = STATS_GET(mib2.tcpestabresets);
+      return sizeof(*uint_ptr);
+    case 9: { /* tcpCurrEstab */
+      u16_t tcpcurrestab = 0;
+      struct tcp_pcb *pcb = tcp_active_pcbs;
+      while (pcb != NULL) {
+        if ((pcb->state == ESTABLISHED) ||
+            (pcb->state == CLOSE_WAIT)) {
+          tcpcurrestab++;
+        }
+        pcb = pcb->next;
+      }
+      *uint_ptr = tcpcurrestab;
+    }
+    return sizeof(*uint_ptr);
+    case 10: /* tcpInSegs */
+      *uint_ptr = STATS_GET(mib2.tcpinsegs);
+      return sizeof(*uint_ptr);
+    case 11: /* tcpOutSegs */
+      *uint_ptr = STATS_GET(mib2.tcpoutsegs);
+      return sizeof(*uint_ptr);
+    case 12: /* tcpRetransSegs */
+      *uint_ptr = STATS_GET(mib2.tcpretranssegs);
+      return sizeof(*uint_ptr);
+    case 14: /* tcpInErrs */
+      *uint_ptr = STATS_GET(mib2.tcpinerrs);
+      return sizeof(*uint_ptr);
+    case 15: /* tcpOutRsts */
+      *uint_ptr = STATS_GET(mib2.tcpoutrsts);
+      return sizeof(*uint_ptr);
+#if LWIP_HAVE_INT64
+    case 17: { /* tcpHCInSegs */
+      /* use the 32 bit counter for now... */
+      u64_t val64 = STATS_GET(mib2.tcpinsegs);
+      *((u64_t *)value) = val64;
+    }
+    return sizeof(u64_t);
+    case 18: { /* tcpHCOutSegs */
+      /* use the 32 bit counter for now... */
+      u64_t val64 = STATS_GET(mib2.tcpoutsegs);
+      *((u64_t *)value) = val64;
+    }
+    return sizeof(u64_t);
+#endif
+    default:
+      LWIP_DEBUGF(SNMP_MIB_DEBUG, ("tcp_get_value(): unknown id: %"S32_F"\n", instance->node->oid));
+      break;
+  }
+
+  return 0;
+}
+
+/* --- tcpConnTable --- */
+
+#if LWIP_IPV4
+
+/* list of allowed value ranges for incoming OID */
+static const struct snmp_oid_range tcp_ConnTable_oid_ranges[] = {
+  { 0, 0xff   }, /* IP A */
+  { 0, 0xff   }, /* IP B */
+  { 0, 0xff   }, /* IP C */
+  { 0, 0xff   }, /* IP D */
+  { 0, 0xffff }, /* Port */
+  { 0, 0xff   }, /* IP A */
+  { 0, 0xff   }, /* IP B */
+  { 0, 0xff   }, /* IP C */
+  { 0, 0xff   }, /* IP D */
+  { 0, 0xffff }  /* Port */
+};
+
+static snmp_err_t
+tcp_ConnTable_get_cell_value_core(struct tcp_pcb *pcb, const u32_t *column, union snmp_variant_value *value, u32_t *value_len)
+{
+  LWIP_UNUSED_ARG(value_len);
+
+  /* value */
+  switch (*column) {
+    case 1: /* tcpConnState */
+      value->u32 = pcb->state + 1;
+      break;
+    case 2: /* tcpConnLocalAddress */
+      value->u32 = ip_2_ip4(&pcb->local_ip)->addr;
+      break;
+    case 3: /* tcpConnLocalPort */
+      value->u32 = pcb->local_port;
+      break;
+    case 4: /* tcpConnRemAddress */
+      if (pcb->state == LISTEN) {
+        value->u32 = IP4_ADDR_ANY4->addr;
+      } else {
+        value->u32 = ip_2_ip4(&pcb->remote_ip)->addr;
+      }
+      break;
+    case 5: /* tcpConnRemPort */
+      if (pcb->state == LISTEN) {
+        value->u32 = 0;
+      } else {
+        value->u32 = pcb->remote_port;
+      }
+      break;
+    default:
+      LWIP_ASSERT("invalid id", 0);
+      return SNMP_ERR_NOSUCHINSTANCE;
+  }
+
+  return SNMP_ERR_NOERROR;
+}
+
+static snmp_err_t
+tcp_ConnTable_get_cell_value(const u32_t *column, const u32_t *row_oid, u8_t row_oid_len, union snmp_variant_value *value, u32_t *value_len)
+{
+  u8_t i;
+  ip4_addr_t local_ip;
+  ip4_addr_t remote_ip;
+  u16_t local_port;
+  u16_t remote_port;
+  struct tcp_pcb *pcb;
+
+  /* check if incoming OID length and if values are in plausible range */
+  if (!snmp_oid_in_range(row_oid, row_oid_len, tcp_ConnTable_oid_ranges, LWIP_ARRAYSIZE(tcp_ConnTable_oid_ranges))) {
+    return SNMP_ERR_NOSUCHINSTANCE;
+  }
+
+  /* get IPs and ports from incoming OID */
+  snmp_oid_to_ip4(&row_oid[0], &local_ip); /* we know it succeeds because of oid_in_range check above */
+  local_port = (u16_t)row_oid[4];
+  snmp_oid_to_ip4(&row_oid[5], &remote_ip); /* we know it succeeds because of oid_in_range check above */
+  remote_port = (u16_t)row_oid[9];
+
+  /* find tcp_pcb with requested ips and ports */
+  for (i = 0; i < LWIP_ARRAYSIZE(tcp_pcb_lists); i++) {
+    pcb = *tcp_pcb_lists[i];
+
+    while (pcb != NULL) {
+      /* do local IP and local port match? */
+      if (IP_IS_V4_VAL(pcb->local_ip) &&
+          ip4_addr_cmp(&local_ip, ip_2_ip4(&pcb->local_ip)) && (local_port == pcb->local_port)) {
+
+        /* PCBs in state LISTEN are not connected and have no remote_ip or remote_port */
+        if (pcb->state == LISTEN) {
+          if (ip4_addr_cmp(&remote_ip, IP4_ADDR_ANY4) && (remote_port == 0)) {
+            /* fill in object properties */
+            return tcp_ConnTable_get_cell_value_core(pcb, column, value, value_len);
+          }
+        } else {
+          if (IP_IS_V4_VAL(pcb->remote_ip) &&
+              ip4_addr_cmp(&remote_ip, ip_2_ip4(&pcb->remote_ip)) && (remote_port == pcb->remote_port)) {
+            /* fill in object properties */
+            return tcp_ConnTable_get_cell_value_core(pcb, column, value, value_len);
+          }
+        }
+      }
+
+      pcb = pcb->next;
+    }
+  }
+
+  /* not found */
+  return SNMP_ERR_NOSUCHINSTANCE;
+}
+
+static snmp_err_t
+tcp_ConnTable_get_next_cell_instance_and_value(const u32_t *column, struct snmp_obj_id *row_oid, union snmp_variant_value *value, u32_t *value_len)
+{
+  u8_t i;
+  struct tcp_pcb *pcb;
+  struct snmp_next_oid_state state;
+  u32_t result_temp[LWIP_ARRAYSIZE(tcp_ConnTable_oid_ranges)];
+
+  /* init struct to search next oid */
+  snmp_next_oid_init(&state, row_oid->id, row_oid->len, result_temp, LWIP_ARRAYSIZE(tcp_ConnTable_oid_ranges));
+
+  /* iterate over all possible OIDs to find the next one */
+  for (i = 0; i < LWIP_ARRAYSIZE(tcp_pcb_lists); i++) {
+    pcb = *tcp_pcb_lists[i];
+    while (pcb != NULL) {
+      u32_t test_oid[LWIP_ARRAYSIZE(tcp_ConnTable_oid_ranges)];
+
+      if (IP_IS_V4_VAL(pcb->local_ip)) {
+        snmp_ip4_to_oid(ip_2_ip4(&pcb->local_ip), &test_oid[0]);
+        test_oid[4] = pcb->local_port;
+
+        /* PCBs in state LISTEN are not connected and have no remote_ip or remote_port */
+        if (pcb->state == LISTEN) {
+          snmp_ip4_to_oid(IP4_ADDR_ANY4, &test_oid[5]);
+          test_oid[9] = 0;
+        } else {
+          if (IP_IS_V6_VAL(pcb->remote_ip)) { /* should never happen */
+            continue;
+          }
+          snmp_ip4_to_oid(ip_2_ip4(&pcb->remote_ip), &test_oid[5]);
+          test_oid[9] = pcb->remote_port;
+        }
+
+        /* check generated OID: is it a candidate for the next one? */
+        snmp_next_oid_check(&state, test_oid, LWIP_ARRAYSIZE(tcp_ConnTable_oid_ranges), pcb);
+      }
+
+      pcb = pcb->next;
+    }
+  }
+
+  /* did we find a next one? */
+  if (state.status == SNMP_NEXT_OID_STATUS_SUCCESS) {
+    snmp_oid_assign(row_oid, state.next_oid, state.next_oid_len);
+    /* fill in object properties */
+    return tcp_ConnTable_get_cell_value_core((struct tcp_pcb *)state.reference, column, value, value_len);
+  }
+
+  /* not found */
+  return SNMP_ERR_NOSUCHINSTANCE;
+}
+
+#endif /* LWIP_IPV4 */
+
+/* --- tcpConnectionTable --- */
+
+static snmp_err_t
+tcp_ConnectionTable_get_cell_value_core(const u32_t *column, struct tcp_pcb *pcb, union snmp_variant_value *value)
+{
+  /* all items except tcpConnectionState and tcpConnectionProcess are declared as not-accessible */
+  switch (*column) {
+    case 7: /* tcpConnectionState */
+      value->u32 = pcb->state + 1;
+      break;
+    case 8: /* tcpConnectionProcess */
+      value->u32 = 0; /* not supported */
+      break;
+    default:
+      return SNMP_ERR_NOSUCHINSTANCE;
+  }
+
+  return SNMP_ERR_NOERROR;
+}
+
+static snmp_err_t
+tcp_ConnectionTable_get_cell_value(const u32_t *column, const u32_t *row_oid, u8_t row_oid_len, union snmp_variant_value *value, u32_t *value_len)
+{
+  ip_addr_t local_ip, remote_ip;
+  u16_t local_port, remote_port;
+  struct tcp_pcb *pcb;
+  u8_t idx = 0;
+  u8_t i;
+  struct tcp_pcb **const tcp_pcb_nonlisten_lists[] = {&tcp_bound_pcbs, &tcp_active_pcbs, &tcp_tw_pcbs};
+
+  LWIP_UNUSED_ARG(value_len);
+
+  /* tcpConnectionLocalAddressType + tcpConnectionLocalAddress + tcpConnectionLocalPort */
+  idx += snmp_oid_to_ip_port(&row_oid[idx], row_oid_len - idx, &local_ip, &local_port);
+  if (idx == 0) {
+    return SNMP_ERR_NOSUCHINSTANCE;
+  }
+
+  /* tcpConnectionRemAddressType + tcpConnectionRemAddress + tcpConnectionRemPort */
+  idx += snmp_oid_to_ip_port(&row_oid[idx], row_oid_len - idx, &remote_ip, &remote_port);
+  if (idx == 0) {
+    return SNMP_ERR_NOSUCHINSTANCE;
+  }
+
+  /* find tcp_pcb with requested ip and port*/
+  for (i = 0; i < LWIP_ARRAYSIZE(tcp_pcb_nonlisten_lists); i++) {
+    pcb = *tcp_pcb_nonlisten_lists[i];
+
+    while (pcb != NULL) {
+      if (ip_addr_cmp(&local_ip, &pcb->local_ip) &&
+          (local_port == pcb->local_port) &&
+          ip_addr_cmp(&remote_ip, &pcb->remote_ip) &&
+          (remote_port == pcb->remote_port)) {
+        /* fill in object properties */
+        return tcp_ConnectionTable_get_cell_value_core(column, pcb, value);
+      }
+      pcb = pcb->next;
+    }
+  }
+
+  /* not found */
+  return SNMP_ERR_NOSUCHINSTANCE;
+}
+
+static snmp_err_t
+tcp_ConnectionTable_get_next_cell_instance_and_value(const u32_t *column, struct snmp_obj_id *row_oid, union snmp_variant_value *value, u32_t *value_len)
+{
+  struct tcp_pcb *pcb;
+  struct snmp_next_oid_state state;
+  /* 1x tcpConnectionLocalAddressType + 1x OID len + 16x tcpConnectionLocalAddress  + 1x tcpConnectionLocalPort
+   * 1x tcpConnectionRemAddressType   + 1x OID len + 16x tcpConnectionRemAddress    + 1x tcpConnectionRemPort */
+  u32_t  result_temp[38];
+  u8_t i;
+  struct tcp_pcb **const tcp_pcb_nonlisten_lists[] = {&tcp_bound_pcbs, &tcp_active_pcbs, &tcp_tw_pcbs};
+
+  LWIP_UNUSED_ARG(value_len);
+
+  /* init struct to search next oid */
+  snmp_next_oid_init(&state, row_oid->id, row_oid->len, result_temp, LWIP_ARRAYSIZE(result_temp));
+
+  /* iterate over all possible OIDs to find the next one */
+  for (i = 0; i < LWIP_ARRAYSIZE(tcp_pcb_nonlisten_lists); i++) {
+    pcb = *tcp_pcb_nonlisten_lists[i];
+
+    while (pcb != NULL) {
+      u8_t idx = 0;
+      u32_t test_oid[LWIP_ARRAYSIZE(result_temp)];
+
+      /* tcpConnectionLocalAddressType + tcpConnectionLocalAddress + tcpConnectionLocalPort */
+      idx += snmp_ip_port_to_oid(&pcb->local_ip, pcb->local_port, &test_oid[idx]);
+
+      /* tcpConnectionRemAddressType + tcpConnectionRemAddress + tcpConnectionRemPort */
+      idx += snmp_ip_port_to_oid(&pcb->remote_ip, pcb->remote_port, &test_oid[idx]);
+
+      /* check generated OID: is it a candidate for the next one? */
+      snmp_next_oid_check(&state, test_oid, idx, pcb);
+
+      pcb = pcb->next;
+    }
+  }
+
+  /* did we find a next one? */
+  if (state.status == SNMP_NEXT_OID_STATUS_SUCCESS) {
+    snmp_oid_assign(row_oid, state.next_oid, state.next_oid_len);
+    /* fill in object properties */
+    return tcp_ConnectionTable_get_cell_value_core(column, (struct tcp_pcb *)state.reference, value);
+  } else {
+    /* not found */
+    return SNMP_ERR_NOSUCHINSTANCE;
+  }
+}
+
+/* --- tcpListenerTable --- */
+
+static snmp_err_t
+tcp_ListenerTable_get_cell_value_core(const u32_t *column, union snmp_variant_value *value)
+{
+  /* all items except tcpListenerProcess are declared as not-accessible */
+  switch (*column) {
+    case 4: /* tcpListenerProcess */
+      value->u32 = 0; /* not supported */
+      break;
+    default:
+      return SNMP_ERR_NOSUCHINSTANCE;
+  }
+
+  return SNMP_ERR_NOERROR;
+}
+
+static snmp_err_t
+tcp_ListenerTable_get_cell_value(const u32_t *column, const u32_t *row_oid, u8_t row_oid_len, union snmp_variant_value *value, u32_t *value_len)
+{
+  ip_addr_t local_ip;
+  u16_t local_port;
+  struct tcp_pcb_listen *pcb;
+  u8_t idx = 0;
+
+  LWIP_UNUSED_ARG(value_len);
+
+  /* tcpListenerLocalAddressType + tcpListenerLocalAddress + tcpListenerLocalPort */
+  idx += snmp_oid_to_ip_port(&row_oid[idx], row_oid_len - idx, &local_ip, &local_port);
+  if (idx == 0) {
+    return SNMP_ERR_NOSUCHINSTANCE;
+  }
+
+  /* find tcp_pcb with requested ip and port*/
+  pcb = tcp_listen_pcbs.listen_pcbs;
+  while (pcb != NULL) {
+    if (ip_addr_cmp(&local_ip, &pcb->local_ip) &&
+        (local_port == pcb->local_port)) {
+      /* fill in object properties */
+      return tcp_ListenerTable_get_cell_value_core(column, value);
+    }
+    pcb = pcb->next;
+  }
+
+  /* not found */
+  return SNMP_ERR_NOSUCHINSTANCE;
+}
+
+static snmp_err_t
+tcp_ListenerTable_get_next_cell_instance_and_value(const u32_t *column, struct snmp_obj_id *row_oid, union snmp_variant_value *value, u32_t *value_len)
+{
+  struct tcp_pcb_listen *pcb;
+  struct snmp_next_oid_state state;
+  /* 1x tcpListenerLocalAddressType + 1x OID len + 16x tcpListenerLocalAddress  + 1x tcpListenerLocalPort */
+  u32_t  result_temp[19];
+
+  LWIP_UNUSED_ARG(value_len);
+
+  /* init struct to search next oid */
+  snmp_next_oid_init(&state, row_oid->id, row_oid->len, result_temp, LWIP_ARRAYSIZE(result_temp));
+
+  /* iterate over all possible OIDs to find the next one */
+  pcb = tcp_listen_pcbs.listen_pcbs;
+  while (pcb != NULL) {
+    u8_t idx = 0;
+    u32_t test_oid[LWIP_ARRAYSIZE(result_temp)];
+
+    /* tcpListenerLocalAddressType + tcpListenerLocalAddress + tcpListenerLocalPort */
+    idx += snmp_ip_port_to_oid(&pcb->local_ip, pcb->local_port, &test_oid[idx]);
+
+    /* check generated OID: is it a candidate for the next one? */
+    snmp_next_oid_check(&state, test_oid, idx, NULL);
+
+    pcb = pcb->next;
+  }
+
+  /* did we find a next one? */
+  if (state.status == SNMP_NEXT_OID_STATUS_SUCCESS) {
+    snmp_oid_assign(row_oid, state.next_oid, state.next_oid_len);
+    /* fill in object properties */
+    return tcp_ListenerTable_get_cell_value_core(column, value);
+  } else {
+    /* not found */
+    return SNMP_ERR_NOSUCHINSTANCE;
+  }
+}
+
+static const struct snmp_scalar_node tcp_RtoAlgorithm  = SNMP_SCALAR_CREATE_NODE_READONLY(1, SNMP_ASN1_TYPE_INTEGER, tcp_get_value);
+static const struct snmp_scalar_node tcp_RtoMin        = SNMP_SCALAR_CREATE_NODE_READONLY(2, SNMP_ASN1_TYPE_INTEGER, tcp_get_value);
+static const struct snmp_scalar_node tcp_RtoMax        = SNMP_SCALAR_CREATE_NODE_READONLY(3, SNMP_ASN1_TYPE_INTEGER, tcp_get_value);
+static const struct snmp_scalar_node tcp_MaxConn       = SNMP_SCALAR_CREATE_NODE_READONLY(4, SNMP_ASN1_TYPE_INTEGER, tcp_get_value);
+static const struct snmp_scalar_node tcp_ActiveOpens   = SNMP_SCALAR_CREATE_NODE_READONLY(5, SNMP_ASN1_TYPE_COUNTER, tcp_get_value);
+static const struct snmp_scalar_node tcp_PassiveOpens  = SNMP_SCALAR_CREATE_NODE_READONLY(6, SNMP_ASN1_TYPE_COUNTER, tcp_get_value);
+static const struct snmp_scalar_node tcp_AttemptFails  = SNMP_SCALAR_CREATE_NODE_READONLY(7, SNMP_ASN1_TYPE_COUNTER, tcp_get_value);
+static const struct snmp_scalar_node tcp_EstabResets   = SNMP_SCALAR_CREATE_NODE_READONLY(8, SNMP_ASN1_TYPE_COUNTER, tcp_get_value);
+static const struct snmp_scalar_node tcp_CurrEstab     = SNMP_SCALAR_CREATE_NODE_READONLY(9, SNMP_ASN1_TYPE_GAUGE, tcp_get_value);
+static const struct snmp_scalar_node tcp_InSegs        = SNMP_SCALAR_CREATE_NODE_READONLY(10, SNMP_ASN1_TYPE_COUNTER, tcp_get_value);
+static const struct snmp_scalar_node tcp_OutSegs       = SNMP_SCALAR_CREATE_NODE_READONLY(11, SNMP_ASN1_TYPE_COUNTER, tcp_get_value);
+static const struct snmp_scalar_node tcp_RetransSegs   = SNMP_SCALAR_CREATE_NODE_READONLY(12, SNMP_ASN1_TYPE_COUNTER, tcp_get_value);
+static const struct snmp_scalar_node tcp_InErrs        = SNMP_SCALAR_CREATE_NODE_READONLY(14, SNMP_ASN1_TYPE_COUNTER, tcp_get_value);
+static const struct snmp_scalar_node tcp_OutRsts       = SNMP_SCALAR_CREATE_NODE_READONLY(15, SNMP_ASN1_TYPE_COUNTER, tcp_get_value);
+#if LWIP_HAVE_INT64
+static const struct snmp_scalar_node tcp_HCInSegs      = SNMP_SCALAR_CREATE_NODE_READONLY(17, SNMP_ASN1_TYPE_COUNTER64, tcp_get_value);
+static const struct snmp_scalar_node tcp_HCOutSegs     = SNMP_SCALAR_CREATE_NODE_READONLY(18, SNMP_ASN1_TYPE_COUNTER64, tcp_get_value);
+#endif
+
+#if LWIP_IPV4
+static const struct snmp_table_simple_col_def tcp_ConnTable_columns[] = {
+  {  1, SNMP_ASN1_TYPE_INTEGER, SNMP_VARIANT_VALUE_TYPE_U32 }, /* tcpConnState */
+  {  2, SNMP_ASN1_TYPE_IPADDR,  SNMP_VARIANT_VALUE_TYPE_U32 }, /* tcpConnLocalAddress */
+  {  3, SNMP_ASN1_TYPE_INTEGER, SNMP_VARIANT_VALUE_TYPE_U32 }, /* tcpConnLocalPort */
+  {  4, SNMP_ASN1_TYPE_IPADDR,  SNMP_VARIANT_VALUE_TYPE_U32 }, /* tcpConnRemAddress */
+  {  5, SNMP_ASN1_TYPE_INTEGER, SNMP_VARIANT_VALUE_TYPE_U32 }  /* tcpConnRemPort */
+};
+
+static const struct snmp_table_simple_node tcp_ConnTable = SNMP_TABLE_CREATE_SIMPLE(13, tcp_ConnTable_columns, tcp_ConnTable_get_cell_value, tcp_ConnTable_get_next_cell_instance_and_value);
+#endif /* LWIP_IPV4 */
+
+static const struct snmp_table_simple_col_def tcp_ConnectionTable_columns[] = {
+  /* all items except tcpConnectionState and tcpConnectionProcess are declared as not-accessible */
+  { 7, SNMP_ASN1_TYPE_INTEGER,    SNMP_VARIANT_VALUE_TYPE_U32 }, /* tcpConnectionState */
+  { 8, SNMP_ASN1_TYPE_UNSIGNED32, SNMP_VARIANT_VALUE_TYPE_U32 }  /* tcpConnectionProcess */
+};
+
+static const struct snmp_table_simple_node tcp_ConnectionTable = SNMP_TABLE_CREATE_SIMPLE(19, tcp_ConnectionTable_columns, tcp_ConnectionTable_get_cell_value, tcp_ConnectionTable_get_next_cell_instance_and_value);
+
+
+static const struct snmp_table_simple_col_def tcp_ListenerTable_columns[] = {
+  /* all items except tcpListenerProcess are declared as not-accessible */
+  { 4, SNMP_ASN1_TYPE_UNSIGNED32, SNMP_VARIANT_VALUE_TYPE_U32 }  /* tcpListenerProcess */
+};
+
+static const struct snmp_table_simple_node tcp_ListenerTable = SNMP_TABLE_CREATE_SIMPLE(20, tcp_ListenerTable_columns, tcp_ListenerTable_get_cell_value, tcp_ListenerTable_get_next_cell_instance_and_value);
+
+/* the following nodes access variables in LWIP stack from SNMP worker thread and must therefore be synced to LWIP (TCPIP) thread */
+CREATE_LWIP_SYNC_NODE( 1, tcp_RtoAlgorithm)
+CREATE_LWIP_SYNC_NODE( 2, tcp_RtoMin)
+CREATE_LWIP_SYNC_NODE( 3, tcp_RtoMax)
+CREATE_LWIP_SYNC_NODE( 4, tcp_MaxConn)
+CREATE_LWIP_SYNC_NODE( 5, tcp_ActiveOpens)
+CREATE_LWIP_SYNC_NODE( 6, tcp_PassiveOpens)
+CREATE_LWIP_SYNC_NODE( 7, tcp_AttemptFails)
+CREATE_LWIP_SYNC_NODE( 8, tcp_EstabResets)
+CREATE_LWIP_SYNC_NODE( 9, tcp_CurrEstab)
+CREATE_LWIP_SYNC_NODE(10, tcp_InSegs)
+CREATE_LWIP_SYNC_NODE(11, tcp_OutSegs)
+CREATE_LWIP_SYNC_NODE(12, tcp_RetransSegs)
+#if LWIP_IPV4
+CREATE_LWIP_SYNC_NODE(13, tcp_ConnTable)
+#endif /* LWIP_IPV4 */
+CREATE_LWIP_SYNC_NODE(14, tcp_InErrs)
+CREATE_LWIP_SYNC_NODE(15, tcp_OutRsts)
+#if LWIP_HAVE_INT64
+CREATE_LWIP_SYNC_NODE(17, tcp_HCInSegs)
+CREATE_LWIP_SYNC_NODE(18, tcp_HCOutSegs)
+#endif
+CREATE_LWIP_SYNC_NODE(19, tcp_ConnectionTable)
+CREATE_LWIP_SYNC_NODE(20, tcp_ListenerTable)
+
+static const struct snmp_node *const tcp_nodes[] = {
+  &SYNC_NODE_NAME(tcp_RtoAlgorithm).node.node,
+  &SYNC_NODE_NAME(tcp_RtoMin).node.node,
+  &SYNC_NODE_NAME(tcp_RtoMax).node.node,
+  &SYNC_NODE_NAME(tcp_MaxConn).node.node,
+  &SYNC_NODE_NAME(tcp_ActiveOpens).node.node,
+  &SYNC_NODE_NAME(tcp_PassiveOpens).node.node,
+  &SYNC_NODE_NAME(tcp_AttemptFails).node.node,
+  &SYNC_NODE_NAME(tcp_EstabResets).node.node,
+  &SYNC_NODE_NAME(tcp_CurrEstab).node.node,
+  &SYNC_NODE_NAME(tcp_InSegs).node.node,
+  &SYNC_NODE_NAME(tcp_OutSegs).node.node,
+  &SYNC_NODE_NAME(tcp_RetransSegs).node.node,
+#if LWIP_IPV4
+  &SYNC_NODE_NAME(tcp_ConnTable).node.node,
+#endif /* LWIP_IPV4 */
+  &SYNC_NODE_NAME(tcp_InErrs).node.node,
+  &SYNC_NODE_NAME(tcp_OutRsts).node.node,
+  &SYNC_NODE_NAME(tcp_HCInSegs).node.node,
+#if LWIP_HAVE_INT64
+  &SYNC_NODE_NAME(tcp_HCOutSegs).node.node,
+  &SYNC_NODE_NAME(tcp_ConnectionTable).node.node,
+#endif
+  &SYNC_NODE_NAME(tcp_ListenerTable).node.node
+};
+
+const struct snmp_tree_node snmp_mib2_tcp_root = SNMP_CREATE_TREE_NODE(6, tcp_nodes);
+#endif /* LWIP_SNMP && SNMP_LWIP_MIB2 && LWIP_TCP */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/apps/snmp/snmp_mib2_udp.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/apps/snmp/snmp_mib2_udp.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/apps/snmp/snmp_mib2_udp.c	(revision 457)
@@ -0,0 +1,372 @@
+/**
+ * @file
+ * Management Information Base II (RFC1213) UDP objects and functions.
+ */
+
+/*
+ * Copyright (c) 2006 Axon Digital Design B.V., The Netherlands.
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * Author: Dirk Ziegelmeier <dziegel@gmx.de>
+ *         Christiaan Simons <christiaan.simons@axon.tv>
+ */
+
+#include "lwip/snmp.h"
+#include "lwip/apps/snmp.h"
+#include "lwip/apps/snmp_core.h"
+#include "lwip/apps/snmp_mib2.h"
+#include "lwip/apps/snmp_table.h"
+#include "lwip/apps/snmp_scalar.h"
+#include "lwip/udp.h"
+#include "lwip/stats.h"
+
+#include <string.h>
+
+#if LWIP_SNMP && SNMP_LWIP_MIB2 && LWIP_UDP
+
+#if SNMP_USE_NETCONN
+#define SYNC_NODE_NAME(node_name) node_name ## _synced
+#define CREATE_LWIP_SYNC_NODE(oid, node_name) \
+   static const struct snmp_threadsync_node node_name ## _synced = SNMP_CREATE_THREAD_SYNC_NODE(oid, &node_name.node, &snmp_mib2_lwip_locks);
+#else
+#define SYNC_NODE_NAME(node_name) node_name
+#define CREATE_LWIP_SYNC_NODE(oid, node_name)
+#endif
+
+/* --- udp .1.3.6.1.2.1.7 ----------------------------------------------------- */
+
+static s16_t
+udp_get_value(struct snmp_node_instance *instance, void *value)
+{
+  u32_t *uint_ptr = (u32_t *)value;
+
+  switch (instance->node->oid) {
+    case 1: /* udpInDatagrams */
+      *uint_ptr = STATS_GET(mib2.udpindatagrams);
+      return sizeof(*uint_ptr);
+    case 2: /* udpNoPorts */
+      *uint_ptr = STATS_GET(mib2.udpnoports);
+      return sizeof(*uint_ptr);
+    case 3: /* udpInErrors */
+      *uint_ptr = STATS_GET(mib2.udpinerrors);
+      return sizeof(*uint_ptr);
+    case 4: /* udpOutDatagrams */
+      *uint_ptr = STATS_GET(mib2.udpoutdatagrams);
+      return sizeof(*uint_ptr);
+#if LWIP_HAVE_INT64
+    case 8: { /* udpHCInDatagrams */
+      /* use the 32 bit counter for now... */
+      u64_t val64 = STATS_GET(mib2.udpindatagrams);
+      *((u64_t *)value) = val64;
+    }
+    return sizeof(u64_t);
+    case 9: { /* udpHCOutDatagrams */
+      /* use the 32 bit counter for now... */
+      u64_t val64 = STATS_GET(mib2.udpoutdatagrams);
+      *((u64_t *)value) = val64;
+    }
+    return sizeof(u64_t);
+#endif
+    default:
+      LWIP_DEBUGF(SNMP_MIB_DEBUG, ("udp_get_value(): unknown id: %"S32_F"\n", instance->node->oid));
+      break;
+  }
+
+  return 0;
+}
+
+/* --- udpEndpointTable --- */
+
+static snmp_err_t
+udp_endpointTable_get_cell_value_core(const u32_t *column, union snmp_variant_value *value)
+{
+  /* all items except udpEndpointProcess are declared as not-accessible */
+  switch (*column) {
+    case 8: /* udpEndpointProcess */
+      value->u32 = 0; /* not supported */
+      break;
+    default:
+      return SNMP_ERR_NOSUCHINSTANCE;
+  }
+
+  return SNMP_ERR_NOERROR;
+}
+
+static snmp_err_t
+udp_endpointTable_get_cell_value(const u32_t *column, const u32_t *row_oid, u8_t row_oid_len, union snmp_variant_value *value, u32_t *value_len)
+{
+  ip_addr_t local_ip, remote_ip;
+  u16_t local_port, remote_port;
+  struct udp_pcb *pcb;
+  u8_t idx = 0;
+
+  LWIP_UNUSED_ARG(value_len);
+
+  /* udpEndpointLocalAddressType + udpEndpointLocalAddress + udpEndpointLocalPort */
+  idx += snmp_oid_to_ip_port(&row_oid[idx], row_oid_len - idx, &local_ip, &local_port);
+  if (idx == 0) {
+    return SNMP_ERR_NOSUCHINSTANCE;
+  }
+
+  /* udpEndpointRemoteAddressType + udpEndpointRemoteAddress + udpEndpointRemotePort */
+  idx += snmp_oid_to_ip_port(&row_oid[idx], row_oid_len - idx, &remote_ip, &remote_port);
+  if (idx == 0) {
+    return SNMP_ERR_NOSUCHINSTANCE;
+  }
+
+  /* udpEndpointInstance */
+  if (row_oid_len < (idx + 1)) {
+    return SNMP_ERR_NOSUCHINSTANCE;
+  }
+  if (row_oid[idx] != 0) {
+    return SNMP_ERR_NOSUCHINSTANCE;
+  }
+
+  /* find udp_pcb with requested ip and port*/
+  pcb = udp_pcbs;
+  while (pcb != NULL) {
+    if (ip_addr_cmp(&local_ip, &pcb->local_ip) &&
+        (local_port == pcb->local_port) &&
+        ip_addr_cmp(&remote_ip, &pcb->remote_ip) &&
+        (remote_port == pcb->remote_port)) {
+      /* fill in object properties */
+      return udp_endpointTable_get_cell_value_core(column, value);
+    }
+    pcb = pcb->next;
+  }
+
+  /* not found */
+  return SNMP_ERR_NOSUCHINSTANCE;
+}
+
+static snmp_err_t
+udp_endpointTable_get_next_cell_instance_and_value(const u32_t *column, struct snmp_obj_id *row_oid, union snmp_variant_value *value, u32_t *value_len)
+{
+  struct udp_pcb *pcb;
+  struct snmp_next_oid_state state;
+  /* 1x udpEndpointLocalAddressType  + 1x OID len + 16x udpEndpointLocalAddress  + 1x udpEndpointLocalPort  +
+   * 1x udpEndpointRemoteAddressType + 1x OID len + 16x udpEndpointRemoteAddress + 1x udpEndpointRemotePort +
+   * 1x udpEndpointInstance = 39
+   */
+  u32_t  result_temp[39];
+
+  LWIP_UNUSED_ARG(value_len);
+
+  /* init struct to search next oid */
+  snmp_next_oid_init(&state, row_oid->id, row_oid->len, result_temp, LWIP_ARRAYSIZE(result_temp));
+
+  /* iterate over all possible OIDs to find the next one */
+  pcb = udp_pcbs;
+  while (pcb != NULL) {
+    u32_t test_oid[LWIP_ARRAYSIZE(result_temp)];
+    u8_t idx = 0;
+
+    /* udpEndpointLocalAddressType + udpEndpointLocalAddress + udpEndpointLocalPort */
+    idx += snmp_ip_port_to_oid(&pcb->local_ip, pcb->local_port, &test_oid[idx]);
+
+    /* udpEndpointRemoteAddressType + udpEndpointRemoteAddress + udpEndpointRemotePort */
+    idx += snmp_ip_port_to_oid(&pcb->remote_ip, pcb->remote_port, &test_oid[idx]);
+
+    test_oid[idx] = 0; /* udpEndpointInstance */
+    idx++;
+
+    /* check generated OID: is it a candidate for the next one? */
+    snmp_next_oid_check(&state, test_oid, idx, NULL);
+
+    pcb = pcb->next;
+  }
+
+  /* did we find a next one? */
+  if (state.status == SNMP_NEXT_OID_STATUS_SUCCESS) {
+    snmp_oid_assign(row_oid, state.next_oid, state.next_oid_len);
+    /* fill in object properties */
+    return udp_endpointTable_get_cell_value_core(column, value);
+  } else {
+    /* not found */
+    return SNMP_ERR_NOSUCHINSTANCE;
+  }
+}
+
+/* --- udpTable --- */
+
+#if LWIP_IPV4
+
+/* list of allowed value ranges for incoming OID */
+static const struct snmp_oid_range udp_Table_oid_ranges[] = {
+  { 0, 0xff   }, /* IP A        */
+  { 0, 0xff   }, /* IP B        */
+  { 0, 0xff   }, /* IP C        */
+  { 0, 0xff   }, /* IP D        */
+  { 1, 0xffff }  /* Port        */
+};
+
+static snmp_err_t
+udp_Table_get_cell_value_core(struct udp_pcb *pcb, const u32_t *column, union snmp_variant_value *value, u32_t *value_len)
+{
+  LWIP_UNUSED_ARG(value_len);
+
+  switch (*column) {
+    case 1: /* udpLocalAddress */
+      /* set reference to PCB local IP and return a generic node that copies IP4 addresses */
+      value->u32 = ip_2_ip4(&pcb->local_ip)->addr;
+      break;
+    case 2: /* udpLocalPort */
+      /* set reference to PCB local port and return a generic node that copies u16_t values */
+      value->u32 = pcb->local_port;
+      break;
+    default:
+      return SNMP_ERR_NOSUCHINSTANCE;
+  }
+
+  return SNMP_ERR_NOERROR;
+}
+
+static snmp_err_t
+udp_Table_get_cell_value(const u32_t *column, const u32_t *row_oid, u8_t row_oid_len, union snmp_variant_value *value, u32_t *value_len)
+{
+  ip4_addr_t ip;
+  u16_t port;
+  struct udp_pcb *pcb;
+
+  /* check if incoming OID length and if values are in plausible range */
+  if (!snmp_oid_in_range(row_oid, row_oid_len, udp_Table_oid_ranges, LWIP_ARRAYSIZE(udp_Table_oid_ranges))) {
+    return SNMP_ERR_NOSUCHINSTANCE;
+  }
+
+  /* get IP and port from incoming OID */
+  snmp_oid_to_ip4(&row_oid[0], &ip); /* we know it succeeds because of oid_in_range check above */
+  port = (u16_t)row_oid[4];
+
+  /* find udp_pcb with requested ip and port*/
+  pcb = udp_pcbs;
+  while (pcb != NULL) {
+    if (IP_IS_V4_VAL(pcb->local_ip)) {
+      if (ip4_addr_cmp(&ip, ip_2_ip4(&pcb->local_ip)) && (port == pcb->local_port)) {
+        /* fill in object properties */
+        return udp_Table_get_cell_value_core(pcb, column, value, value_len);
+      }
+    }
+    pcb = pcb->next;
+  }
+
+  /* not found */
+  return SNMP_ERR_NOSUCHINSTANCE;
+}
+
+static snmp_err_t
+udp_Table_get_next_cell_instance_and_value(const u32_t *column, struct snmp_obj_id *row_oid, union snmp_variant_value *value, u32_t *value_len)
+{
+  struct udp_pcb *pcb;
+  struct snmp_next_oid_state state;
+  u32_t  result_temp[LWIP_ARRAYSIZE(udp_Table_oid_ranges)];
+
+  /* init struct to search next oid */
+  snmp_next_oid_init(&state, row_oid->id, row_oid->len, result_temp, LWIP_ARRAYSIZE(udp_Table_oid_ranges));
+
+  /* iterate over all possible OIDs to find the next one */
+  pcb = udp_pcbs;
+  while (pcb != NULL) {
+    u32_t test_oid[LWIP_ARRAYSIZE(udp_Table_oid_ranges)];
+
+    if (IP_IS_V4_VAL(pcb->local_ip)) {
+      snmp_ip4_to_oid(ip_2_ip4(&pcb->local_ip), &test_oid[0]);
+      test_oid[4] = pcb->local_port;
+
+      /* check generated OID: is it a candidate for the next one? */
+      snmp_next_oid_check(&state, test_oid, LWIP_ARRAYSIZE(udp_Table_oid_ranges), pcb);
+    }
+
+    pcb = pcb->next;
+  }
+
+  /* did we find a next one? */
+  if (state.status == SNMP_NEXT_OID_STATUS_SUCCESS) {
+    snmp_oid_assign(row_oid, state.next_oid, state.next_oid_len);
+    /* fill in object properties */
+    return udp_Table_get_cell_value_core((struct udp_pcb *)state.reference, column, value, value_len);
+  } else {
+    /* not found */
+    return SNMP_ERR_NOSUCHINSTANCE;
+  }
+}
+
+#endif /* LWIP_IPV4 */
+
+static const struct snmp_scalar_node udp_inDatagrams    = SNMP_SCALAR_CREATE_NODE_READONLY(1, SNMP_ASN1_TYPE_COUNTER,   udp_get_value);
+static const struct snmp_scalar_node udp_noPorts        = SNMP_SCALAR_CREATE_NODE_READONLY(2, SNMP_ASN1_TYPE_COUNTER,   udp_get_value);
+static const struct snmp_scalar_node udp_inErrors       = SNMP_SCALAR_CREATE_NODE_READONLY(3, SNMP_ASN1_TYPE_COUNTER,   udp_get_value);
+static const struct snmp_scalar_node udp_outDatagrams   = SNMP_SCALAR_CREATE_NODE_READONLY(4, SNMP_ASN1_TYPE_COUNTER,   udp_get_value);
+#if LWIP_HAVE_INT64
+static const struct snmp_scalar_node udp_HCInDatagrams  = SNMP_SCALAR_CREATE_NODE_READONLY(8, SNMP_ASN1_TYPE_COUNTER64, udp_get_value);
+static const struct snmp_scalar_node udp_HCOutDatagrams = SNMP_SCALAR_CREATE_NODE_READONLY(9, SNMP_ASN1_TYPE_COUNTER64, udp_get_value);
+#endif
+
+#if LWIP_IPV4
+static const struct snmp_table_simple_col_def udp_Table_columns[] = {
+  { 1, SNMP_ASN1_TYPE_IPADDR,  SNMP_VARIANT_VALUE_TYPE_U32 }, /* udpLocalAddress */
+  { 2, SNMP_ASN1_TYPE_INTEGER, SNMP_VARIANT_VALUE_TYPE_U32 }  /* udpLocalPort */
+};
+static const struct snmp_table_simple_node udp_Table = SNMP_TABLE_CREATE_SIMPLE(5, udp_Table_columns, udp_Table_get_cell_value, udp_Table_get_next_cell_instance_and_value);
+#endif /* LWIP_IPV4 */
+
+static const struct snmp_table_simple_col_def udp_endpointTable_columns[] = {
+  /* all items except udpEndpointProcess are declared as not-accessible */
+  { 8, SNMP_ASN1_TYPE_UNSIGNED32, SNMP_VARIANT_VALUE_TYPE_U32 }  /* udpEndpointProcess */
+};
+
+static const struct snmp_table_simple_node udp_endpointTable = SNMP_TABLE_CREATE_SIMPLE(7, udp_endpointTable_columns, udp_endpointTable_get_cell_value, udp_endpointTable_get_next_cell_instance_and_value);
+
+/* the following nodes access variables in LWIP stack from SNMP worker thread and must therefore be synced to LWIP (TCPIP) thread */
+CREATE_LWIP_SYNC_NODE(1, udp_inDatagrams)
+CREATE_LWIP_SYNC_NODE(2, udp_noPorts)
+CREATE_LWIP_SYNC_NODE(3, udp_inErrors)
+CREATE_LWIP_SYNC_NODE(4, udp_outDatagrams)
+#if LWIP_IPV4
+CREATE_LWIP_SYNC_NODE(5, udp_Table)
+#endif /* LWIP_IPV4 */
+CREATE_LWIP_SYNC_NODE(7, udp_endpointTable)
+#if LWIP_HAVE_INT64
+CREATE_LWIP_SYNC_NODE(8, udp_HCInDatagrams)
+CREATE_LWIP_SYNC_NODE(9, udp_HCOutDatagrams)
+#endif
+
+static const struct snmp_node *const udp_nodes[] = {
+  &SYNC_NODE_NAME(udp_inDatagrams).node.node,
+  &SYNC_NODE_NAME(udp_noPorts).node.node,
+  &SYNC_NODE_NAME(udp_inErrors).node.node,
+  &SYNC_NODE_NAME(udp_outDatagrams).node.node,
+#if LWIP_IPV4
+  &SYNC_NODE_NAME(udp_Table).node.node,
+#endif /* LWIP_IPV4 */
+  &SYNC_NODE_NAME(udp_endpointTable).node.node
+#if LWIP_HAVE_INT64
+  ,
+  &SYNC_NODE_NAME(udp_HCInDatagrams).node.node,
+  &SYNC_NODE_NAME(udp_HCOutDatagrams).node.node
+#endif
+};
+
+const struct snmp_tree_node snmp_mib2_udp_root = SNMP_CREATE_TREE_NODE(7, udp_nodes);
+#endif /* LWIP_SNMP && SNMP_LWIP_MIB2 && LWIP_UDP */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/apps/snmp/snmp_msg.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/apps/snmp/snmp_msg.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/apps/snmp/snmp_msg.c	(revision 457)
@@ -0,0 +1,1951 @@
+/**
+ * @file
+ * SNMP message processing (RFC1157).
+ */
+
+/*
+ * Copyright (c) 2006 Axon Digital Design B.V., The Netherlands.
+ * Copyright (c) 2016 Elias Oenal.
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * Author: Christiaan Simons <christiaan.simons@axon.tv>
+ *         Martin Hentschel <info@cl-soft.de>
+ *         Elias Oenal <lwip@eliasoenal.com>
+ */
+
+#include "lwip/apps/snmp_opts.h"
+
+#if LWIP_SNMP /* don't build if not configured for use in lwipopts.h */
+
+#include "snmp_msg.h"
+#include "snmp_asn1.h"
+#include "snmp_core_priv.h"
+#include "lwip/ip_addr.h"
+#include "lwip/stats.h"
+
+#if LWIP_SNMP_V3
+#include "lwip/apps/snmpv3.h"
+#include "snmpv3_priv.h"
+#ifdef LWIP_HOOK_FILENAME
+#include LWIP_HOOK_FILENAME
+#endif
+#endif
+
+#include <string.h>
+
+#define SNMP_V3_AUTH_FLAG      0x01
+#define SNMP_V3_PRIV_FLAG      0x02
+
+/* Security levels */
+#define SNMP_V3_NOAUTHNOPRIV   0x00
+#define SNMP_V3_AUTHNOPRIV     SNMP_V3_AUTH_FLAG
+#define SNMP_V3_AUTHPRIV       (SNMP_V3_AUTH_FLAG | SNMP_V3_PRIV_FLAG)
+
+/* public (non-static) constants */
+/** SNMP community string */
+const char *snmp_community = SNMP_COMMUNITY;
+/** SNMP community string for write access */
+const char *snmp_community_write = SNMP_COMMUNITY_WRITE;
+/** SNMP community string for sending traps */
+const char *snmp_community_trap = SNMP_COMMUNITY_TRAP;
+
+snmp_write_callback_fct snmp_write_callback     = NULL;
+void                   *snmp_write_callback_arg = NULL;
+
+#if LWIP_SNMP_CONFIGURE_VERSIONS
+
+static u8_t v1_enabled = 1;
+static u8_t v2c_enabled = 1;
+static u8_t v3_enabled = 1;
+
+static u8_t
+snmp_version_enabled(u8_t version)
+{
+  if (version == SNMP_VERSION_1) {
+    return v1_enabled;
+  } else if (version == SNMP_VERSION_2c) {
+    return v2c_enabled;
+  }
+#if LWIP_SNMP_V3
+  else if (version == SNMP_VERSION_3) {
+    return v3_enabled;
+  }
+#endif
+  else {
+    LWIP_ASSERT("Invalid SNMP version", 0);
+    return 0;
+  }
+}
+
+u8_t
+snmp_v1_enabled(void)
+{
+  return snmp_version_enabled(SNMP_VERSION_1);
+}
+
+u8_t
+snmp_v2c_enabled(void)
+{
+  return snmp_version_enabled(SNMP_VERSION_2c);
+}
+
+u8_t
+snmp_v3_enabled(void)
+{
+  return snmp_version_enabled(SNMP_VERSION_3);
+}
+
+static void
+snmp_version_enable(u8_t version, u8_t enable)
+{
+  if (version == SNMP_VERSION_1) {
+    v1_enabled = enable;
+  } else if (version == SNMP_VERSION_2c) {
+    v2c_enabled = enable;
+  }
+#if LWIP_SNMP_V3
+  else if (version == SNMP_VERSION_3) {
+    v3_enabled = enable;
+  }
+#endif
+  else {
+    LWIP_ASSERT("Invalid SNMP version", 0);
+  }
+}
+
+void
+snmp_v1_enable(u8_t enable)
+{
+  snmp_version_enable(SNMP_VERSION_1, enable);
+}
+
+void
+snmp_v2c_enable(u8_t enable)
+{
+  snmp_version_enable(SNMP_VERSION_2c, enable);
+}
+
+void
+snmp_v3_enable(u8_t enable)
+{
+  snmp_version_enable(SNMP_VERSION_3, enable);
+}
+
+#endif
+
+/**
+ * @ingroup snmp_core
+ * Returns current SNMP community string.
+ * @return current SNMP community string
+ */
+const char *
+snmp_get_community(void)
+{
+  return snmp_community;
+}
+
+/**
+ * @ingroup snmp_core
+ * Sets SNMP community string.
+ * The string itself (its storage) must be valid throughout the whole life of
+ * program (or until it is changed to sth else).
+ *
+ * @param community is a pointer to new community string
+ */
+void
+snmp_set_community(const char *const community)
+{
+  LWIP_ASSERT_CORE_LOCKED();
+  LWIP_ASSERT("community string is too long!", strlen(community) <= SNMP_MAX_COMMUNITY_STR_LEN);
+  snmp_community = community;
+}
+
+/**
+ * @ingroup snmp_core
+ * Returns current SNMP write-access community string.
+ * @return current SNMP write-access community string
+ */
+const char *
+snmp_get_community_write(void)
+{
+  return snmp_community_write;
+}
+
+/**
+ * @ingroup snmp_traps
+ * Returns current SNMP community string used for sending traps.
+ * @return current SNMP community string used for sending traps
+ */
+const char *
+snmp_get_community_trap(void)
+{
+  return snmp_community_trap;
+}
+
+/**
+ * @ingroup snmp_core
+ * Sets SNMP community string for write-access.
+ * The string itself (its storage) must be valid throughout the whole life of
+ * program (or until it is changed to sth else).
+ *
+ * @param community is a pointer to new write-access community string
+ */
+void
+snmp_set_community_write(const char *const community)
+{
+  LWIP_ASSERT_CORE_LOCKED();
+  LWIP_ASSERT("community string must not be NULL", community != NULL);
+  LWIP_ASSERT("community string is too long!", strlen(community) <= SNMP_MAX_COMMUNITY_STR_LEN);
+  snmp_community_write = community;
+}
+
+/**
+ * @ingroup snmp_traps
+ * Sets SNMP community string used for sending traps.
+ * The string itself (its storage) must be valid throughout the whole life of
+ * program (or until it is changed to sth else).
+ *
+ * @param community is a pointer to new trap community string
+ */
+void
+snmp_set_community_trap(const char *const community)
+{
+  LWIP_ASSERT_CORE_LOCKED();
+  LWIP_ASSERT("community string is too long!", strlen(community) <= SNMP_MAX_COMMUNITY_STR_LEN);
+  snmp_community_trap = community;
+}
+
+/**
+ * @ingroup snmp_core
+ * Callback fired on every successful write access
+ */
+void
+snmp_set_write_callback(snmp_write_callback_fct write_callback, void *callback_arg)
+{
+  LWIP_ASSERT_CORE_LOCKED();
+  snmp_write_callback     = write_callback;
+  snmp_write_callback_arg = callback_arg;
+}
+
+/* ----------------------------------------------------------------------- */
+/* forward declarations */
+/* ----------------------------------------------------------------------- */
+
+static err_t snmp_process_get_request(struct snmp_request *request);
+static err_t snmp_process_getnext_request(struct snmp_request *request);
+static err_t snmp_process_getbulk_request(struct snmp_request *request);
+static err_t snmp_process_set_request(struct snmp_request *request);
+
+static err_t snmp_parse_inbound_frame(struct snmp_request *request);
+static err_t snmp_prepare_outbound_frame(struct snmp_request *request);
+static err_t snmp_complete_outbound_frame(struct snmp_request *request);
+static void snmp_execute_write_callbacks(struct snmp_request *request);
+
+
+/* ----------------------------------------------------------------------- */
+/* implementation */
+/* ----------------------------------------------------------------------- */
+
+void
+snmp_receive(void *handle, struct pbuf *p, const ip_addr_t *source_ip, u16_t port)
+{
+  err_t err;
+  struct snmp_request request;
+
+  memset(&request, 0, sizeof(request));
+  request.handle       = handle;
+  request.source_ip    = source_ip;
+  request.source_port  = port;
+  request.inbound_pbuf = p;
+
+  snmp_stats.inpkts++;
+
+  err = snmp_parse_inbound_frame(&request);
+  if (err == ERR_OK) {
+    err = snmp_prepare_outbound_frame(&request);
+    if (err == ERR_OK) {
+
+      if (request.error_status == SNMP_ERR_NOERROR) {
+        /* only process frame if we do not already have an error to return (e.g. all readonly) */
+        if (request.request_type == SNMP_ASN1_CONTEXT_PDU_GET_REQ) {
+          err = snmp_process_get_request(&request);
+        } else if (request.request_type == SNMP_ASN1_CONTEXT_PDU_GET_NEXT_REQ) {
+          err = snmp_process_getnext_request(&request);
+        } else if (request.request_type == SNMP_ASN1_CONTEXT_PDU_GET_BULK_REQ) {
+          err = snmp_process_getbulk_request(&request);
+        } else if (request.request_type == SNMP_ASN1_CONTEXT_PDU_SET_REQ) {
+          err = snmp_process_set_request(&request);
+        }
+      }
+#if LWIP_SNMP_V3
+      else {
+        struct snmp_varbind vb;
+
+        vb.next = NULL;
+        vb.prev = NULL;
+        vb.type = SNMP_ASN1_TYPE_COUNTER32;
+        vb.value_len = sizeof(u32_t);
+
+        switch (request.error_status) {
+          case SNMP_ERR_AUTHORIZATIONERROR: {
+            static const u32_t oid[] = { 1, 3, 6, 1, 6, 3, 15, 1, 1, 5, 0 };
+            snmp_oid_assign(&vb.oid, oid, LWIP_ARRAYSIZE(oid));
+            vb.value = &snmp_stats.wrongdigests;
+          }
+          break;
+          case SNMP_ERR_UNKNOWN_ENGINEID: {
+            static const u32_t oid[] = { 1, 3, 6, 1, 6, 3, 15, 1, 1, 4, 0 };
+            snmp_oid_assign(&vb.oid, oid, LWIP_ARRAYSIZE(oid));
+            vb.value = &snmp_stats.unknownengineids;
+          }
+          break;
+          case SNMP_ERR_UNKNOWN_SECURITYNAME: {
+            static const u32_t oid[] = { 1, 3, 6, 1, 6, 3, 15, 1, 1, 3, 0 };
+            snmp_oid_assign(&vb.oid, oid, LWIP_ARRAYSIZE(oid));
+            vb.value = &snmp_stats.unknownusernames;
+          }
+          break;
+          case SNMP_ERR_UNSUPPORTED_SECLEVEL: {
+            static const u32_t oid[] = { 1, 3, 6, 1, 6, 3, 15, 1, 1, 1, 0 };
+            snmp_oid_assign(&vb.oid, oid, LWIP_ARRAYSIZE(oid));
+            vb.value = &snmp_stats.unsupportedseclevels;
+          }
+          break;
+          case SNMP_ERR_NOTINTIMEWINDOW: {
+            static const u32_t oid[] = { 1, 3, 6, 1, 6, 3, 15, 1, 1, 2, 0 };
+            snmp_oid_assign(&vb.oid, oid, LWIP_ARRAYSIZE(oid));
+            vb.value = &snmp_stats.notintimewindows;
+          }
+          break;
+          case SNMP_ERR_DECRYIPTION_ERROR: {
+            static const u32_t oid[] = { 1, 3, 6, 1, 6, 3, 15, 1, 1, 6, 0 };
+            snmp_oid_assign(&vb.oid, oid, LWIP_ARRAYSIZE(oid));
+            vb.value = &snmp_stats.decryptionerrors;
+          }
+          break;
+          default:
+            /* Unknown or unhandled error_status */
+            err = ERR_ARG;
+        }
+
+        if (err == ERR_OK) {
+          snmp_append_outbound_varbind(&(request.outbound_pbuf_stream), &vb);
+          request.error_status = SNMP_ERR_NOERROR;
+        }
+
+        request.request_out_type = (SNMP_ASN1_CLASS_CONTEXT | SNMP_ASN1_CONTENTTYPE_CONSTRUCTED | SNMP_ASN1_CONTEXT_PDU_REPORT);
+        request.request_id = request.msg_id;
+      }
+#endif
+
+      if (err == ERR_OK) {
+        err = snmp_complete_outbound_frame(&request);
+
+        if (err == ERR_OK) {
+          err = snmp_sendto(request.handle, request.outbound_pbuf, request.source_ip, request.source_port);
+
+          if ((request.request_type == SNMP_ASN1_CONTEXT_PDU_SET_REQ)
+              && (request.error_status == SNMP_ERR_NOERROR)
+              && (snmp_write_callback != NULL)) {
+            /* raise write notification for all written objects */
+            snmp_execute_write_callbacks(&request);
+          }
+        }
+      }
+    }
+
+    if (request.outbound_pbuf != NULL) {
+      pbuf_free(request.outbound_pbuf);
+    }
+  }
+}
+
+static u8_t
+snmp_msg_getnext_validate_node_inst(struct snmp_node_instance *node_instance, void *validate_arg)
+{
+  if (((node_instance->access & SNMP_NODE_INSTANCE_ACCESS_READ) != SNMP_NODE_INSTANCE_ACCESS_READ) || (node_instance->get_value == NULL)) {
+    return SNMP_ERR_NOSUCHINSTANCE;
+  }
+
+#if LWIP_HAVE_INT64
+  if ((node_instance->asn1_type == SNMP_ASN1_TYPE_COUNTER64) && (((struct snmp_request *)validate_arg)->version == SNMP_VERSION_1)) {
+    /* according to RFC 2089 skip Counter64 objects in GetNext requests from v1 clients */
+    return SNMP_ERR_NOSUCHINSTANCE;
+  }
+#endif
+
+  return SNMP_ERR_NOERROR;
+}
+
+static void
+snmp_process_varbind(struct snmp_request *request, struct snmp_varbind *vb, u8_t get_next)
+{
+  err_t err;
+  struct snmp_node_instance node_instance;
+  memset(&node_instance, 0, sizeof(node_instance));
+
+  if (get_next) {
+    struct snmp_obj_id result_oid;
+    request->error_status = snmp_get_next_node_instance_from_oid(vb->oid.id, vb->oid.len, snmp_msg_getnext_validate_node_inst, request,  &result_oid, &node_instance);
+
+    if (request->error_status == SNMP_ERR_NOERROR) {
+      snmp_oid_assign(&vb->oid, result_oid.id, result_oid.len);
+    }
+  } else {
+    request->error_status = snmp_get_node_instance_from_oid(vb->oid.id, vb->oid.len, &node_instance);
+
+    if (request->error_status == SNMP_ERR_NOERROR) {
+      /* use 'getnext_validate' method for validation to avoid code duplication (some checks have to be executed here) */
+      request->error_status = snmp_msg_getnext_validate_node_inst(&node_instance, request);
+
+      if (request->error_status != SNMP_ERR_NOERROR) {
+        if (node_instance.release_instance != NULL) {
+          node_instance.release_instance(&node_instance);
+        }
+      }
+    }
+  }
+
+  if (request->error_status != SNMP_ERR_NOERROR)  {
+    if (request->error_status >= SNMP_VARBIND_EXCEPTION_OFFSET) {
+      if ((request->version == SNMP_VERSION_2c) || request->version == SNMP_VERSION_3) {
+        /* in SNMP v2c a varbind related exception is stored in varbind and not in frame header */
+        vb->type = (SNMP_ASN1_CONTENTTYPE_PRIMITIVE | SNMP_ASN1_CLASS_CONTEXT | (request->error_status & SNMP_VARBIND_EXCEPTION_MASK));
+        vb->value_len = 0;
+
+        err = snmp_append_outbound_varbind(&(request->outbound_pbuf_stream), vb);
+        if (err == ERR_OK) {
+          /* we stored the exception in varbind -> go on */
+          request->error_status = SNMP_ERR_NOERROR;
+        } else if (err == ERR_BUF) {
+          request->error_status = SNMP_ERR_TOOBIG;
+        } else {
+          request->error_status = SNMP_ERR_GENERROR;
+        }
+      }
+    } else {
+      /* according to RFC 1157/1905, all other errors only return genError */
+      request->error_status = SNMP_ERR_GENERROR;
+    }
+  } else {
+    s16_t len = node_instance.get_value(&node_instance, vb->value);
+
+    if (len >= 0) {
+      vb->value_len = (u16_t)len; /* cast is OK because we checked >= 0 above */
+      vb->type = node_instance.asn1_type;
+
+      LWIP_ASSERT("SNMP_MAX_VALUE_SIZE is configured too low", (vb->value_len & ~SNMP_GET_VALUE_RAW_DATA) <= SNMP_MAX_VALUE_SIZE);
+      err = snmp_append_outbound_varbind(&request->outbound_pbuf_stream, vb);
+
+      if (err == ERR_BUF) {
+        request->error_status = SNMP_ERR_TOOBIG;
+      } else if (err != ERR_OK) {
+        request->error_status = SNMP_ERR_GENERROR;
+      }
+    } else {
+      request->error_status = SNMP_ERR_GENERROR;
+    }
+
+    if (node_instance.release_instance != NULL) {
+      node_instance.release_instance(&node_instance);
+    }
+  }
+}
+
+
+/**
+ * Service an internal or external event for SNMP GET.
+ *
+ * @param request points to the associated message process state
+ */
+static err_t
+snmp_process_get_request(struct snmp_request *request)
+{
+  snmp_vb_enumerator_err_t err;
+  struct snmp_varbind vb;
+  vb.value = request->value_buffer;
+
+  LWIP_DEBUGF(SNMP_DEBUG, ("SNMP get request\n"));
+
+  while (request->error_status == SNMP_ERR_NOERROR) {
+    err = snmp_vb_enumerator_get_next(&request->inbound_varbind_enumerator, &vb);
+    if (err == SNMP_VB_ENUMERATOR_ERR_OK) {
+      if ((vb.type == SNMP_ASN1_TYPE_NULL) && (vb.value_len == 0)) {
+        snmp_process_varbind(request, &vb, 0);
+      } else {
+        request->error_status = SNMP_ERR_GENERROR;
+      }
+    } else if (err == SNMP_VB_ENUMERATOR_ERR_EOVB) {
+      /* no more varbinds in request */
+      break;
+    } else if (err == SNMP_VB_ENUMERATOR_ERR_ASN1ERROR) {
+      /* malformed ASN.1, don't answer */
+      return ERR_ARG;
+    } else {
+      request->error_status = SNMP_ERR_GENERROR;
+    }
+  }
+
+  return ERR_OK;
+}
+
+/**
+ * Service an internal or external event for SNMP GET.
+ *
+ * @param request points to the associated message process state
+ */
+static err_t
+snmp_process_getnext_request(struct snmp_request *request)
+{
+  snmp_vb_enumerator_err_t err;
+  struct snmp_varbind vb;
+  vb.value = request->value_buffer;
+
+  LWIP_DEBUGF(SNMP_DEBUG, ("SNMP get-next request\n"));
+
+  while (request->error_status == SNMP_ERR_NOERROR) {
+    err = snmp_vb_enumerator_get_next(&request->inbound_varbind_enumerator, &vb);
+    if (err == SNMP_VB_ENUMERATOR_ERR_OK) {
+      if ((vb.type == SNMP_ASN1_TYPE_NULL) && (vb.value_len == 0)) {
+        snmp_process_varbind(request, &vb, 1);
+      } else {
+        request->error_status = SNMP_ERR_GENERROR;
+      }
+    } else if (err == SNMP_VB_ENUMERATOR_ERR_EOVB) {
+      /* no more varbinds in request */
+      break;
+    } else if (err == SNMP_VB_ENUMERATOR_ERR_ASN1ERROR) {
+      /* malformed ASN.1, don't answer */
+      return ERR_ARG;
+    } else {
+      request->error_status = SNMP_ERR_GENERROR;
+    }
+  }
+
+  return ERR_OK;
+}
+
+/**
+ * Service an internal or external event for SNMP GETBULKT.
+ *
+ * @param request points to the associated message process state
+ */
+static err_t
+snmp_process_getbulk_request(struct snmp_request *request)
+{
+  snmp_vb_enumerator_err_t err;
+  s32_t non_repeaters     = request->non_repeaters;
+  s32_t repetitions;
+  u16_t repetition_offset = 0;
+  struct snmp_varbind_enumerator repetition_varbind_enumerator;
+  struct snmp_varbind vb;
+  vb.value = request->value_buffer;
+
+  if (SNMP_LWIP_GETBULK_MAX_REPETITIONS > 0) {
+    repetitions = LWIP_MIN(request->max_repetitions, SNMP_LWIP_GETBULK_MAX_REPETITIONS);
+  } else {
+    repetitions = request->max_repetitions;
+  }
+
+  LWIP_DEBUGF(SNMP_DEBUG, ("SNMP get-bulk request\n"));
+
+  /* process non repeaters and first repetition */
+  while (request->error_status == SNMP_ERR_NOERROR) {
+    if (non_repeaters == 0) {
+      repetition_offset = request->outbound_pbuf_stream.offset;
+
+      if (repetitions == 0) {
+        /* do not resolve repeaters when repetitions is set to 0 */
+        break;
+      }
+      repetitions--;
+    }
+
+    err = snmp_vb_enumerator_get_next(&request->inbound_varbind_enumerator, &vb);
+    if (err == SNMP_VB_ENUMERATOR_ERR_EOVB) {
+      /* no more varbinds in request */
+      break;
+    } else if (err == SNMP_VB_ENUMERATOR_ERR_ASN1ERROR) {
+      /* malformed ASN.1, don't answer */
+      return ERR_ARG;
+    } else if ((err != SNMP_VB_ENUMERATOR_ERR_OK) || (vb.type != SNMP_ASN1_TYPE_NULL) || (vb.value_len != 0)) {
+      request->error_status = SNMP_ERR_GENERROR;
+    } else {
+      snmp_process_varbind(request, &vb, 1);
+      non_repeaters--;
+    }
+  }
+
+  /* process repetitions > 1 */
+  while ((request->error_status == SNMP_ERR_NOERROR) && (repetitions > 0) && (request->outbound_pbuf_stream.offset != repetition_offset)) {
+
+    u8_t all_endofmibview = 1;
+
+    snmp_vb_enumerator_init(&repetition_varbind_enumerator, request->outbound_pbuf, repetition_offset, request->outbound_pbuf_stream.offset - repetition_offset);
+    repetition_offset = request->outbound_pbuf_stream.offset; /* for next loop */
+
+    while (request->error_status == SNMP_ERR_NOERROR) {
+      vb.value = NULL; /* do NOT decode value (we enumerate outbound buffer here, so all varbinds have values assigned) */
+      err = snmp_vb_enumerator_get_next(&repetition_varbind_enumerator, &vb);
+      if (err == SNMP_VB_ENUMERATOR_ERR_OK) {
+        vb.value = request->value_buffer;
+        snmp_process_varbind(request, &vb, 1);
+
+        if (request->error_status != SNMP_ERR_NOERROR) {
+          /* already set correct error-index (here it cannot be taken from inbound varbind enumerator) */
+          request->error_index = request->non_repeaters + repetition_varbind_enumerator.varbind_count;
+        } else if (vb.type != (SNMP_ASN1_CONTENTTYPE_PRIMITIVE | SNMP_ASN1_CLASS_CONTEXT | SNMP_ASN1_CONTEXT_VARBIND_END_OF_MIB_VIEW)) {
+          all_endofmibview = 0;
+        }
+      } else if (err == SNMP_VB_ENUMERATOR_ERR_EOVB) {
+        /* no more varbinds in request */
+        break;
+      } else {
+        LWIP_DEBUGF(SNMP_DEBUG, ("Very strange, we cannot parse the varbind output that we created just before!"));
+        request->error_status = SNMP_ERR_GENERROR;
+        request->error_index  = request->non_repeaters + repetition_varbind_enumerator.varbind_count;
+      }
+    }
+
+    if ((request->error_status == SNMP_ERR_NOERROR) && all_endofmibview) {
+      /* stop when all varbinds in a loop return EndOfMibView */
+      break;
+    }
+
+    repetitions--;
+  }
+
+  if (request->error_status == SNMP_ERR_TOOBIG) {
+    /* for GetBulk it is ok, if not all requested variables fit into the response -> just return the varbinds added so far */
+    request->error_status = SNMP_ERR_NOERROR;
+  }
+
+  return ERR_OK;
+}
+
+/**
+ * Service an internal or external event for SNMP SET.
+ *
+ * @param request points to the associated message process state
+ */
+static err_t
+snmp_process_set_request(struct snmp_request *request)
+{
+  snmp_vb_enumerator_err_t err;
+  struct snmp_varbind vb;
+  vb.value = request->value_buffer;
+
+  LWIP_DEBUGF(SNMP_DEBUG, ("SNMP set request\n"));
+
+  /* perform set test on all objects */
+  while (request->error_status == SNMP_ERR_NOERROR) {
+    err = snmp_vb_enumerator_get_next(&request->inbound_varbind_enumerator, &vb);
+    if (err == SNMP_VB_ENUMERATOR_ERR_OK) {
+      struct snmp_node_instance node_instance;
+      memset(&node_instance, 0, sizeof(node_instance));
+
+      request->error_status = snmp_get_node_instance_from_oid(vb.oid.id, vb.oid.len, &node_instance);
+      if (request->error_status == SNMP_ERR_NOERROR) {
+        if (node_instance.asn1_type != vb.type) {
+          request->error_status = SNMP_ERR_WRONGTYPE;
+        } else if (((node_instance.access & SNMP_NODE_INSTANCE_ACCESS_WRITE) != SNMP_NODE_INSTANCE_ACCESS_WRITE) || (node_instance.set_value == NULL)) {
+          request->error_status = SNMP_ERR_NOTWRITABLE;
+        } else {
+          if (node_instance.set_test != NULL) {
+            request->error_status = node_instance.set_test(&node_instance, vb.value_len, vb.value);
+          }
+        }
+
+        if (node_instance.release_instance != NULL) {
+          node_instance.release_instance(&node_instance);
+        }
+      }
+    } else if (err == SNMP_VB_ENUMERATOR_ERR_EOVB) {
+      /* no more varbinds in request */
+      break;
+    } else if (err == SNMP_VB_ENUMERATOR_ERR_INVALIDLENGTH) {
+      request->error_status = SNMP_ERR_WRONGLENGTH;
+    } else if (err == SNMP_VB_ENUMERATOR_ERR_ASN1ERROR) {
+      /* malformed ASN.1, don't answer */
+      return ERR_ARG;
+    } else {
+      request->error_status = SNMP_ERR_GENERROR;
+    }
+  }
+
+  /* perform real set operation on all objects */
+  if (request->error_status == SNMP_ERR_NOERROR) {
+    snmp_vb_enumerator_init(&request->inbound_varbind_enumerator, request->inbound_pbuf, request->inbound_varbind_offset, request->inbound_varbind_len);
+    while (request->error_status == SNMP_ERR_NOERROR) {
+      err = snmp_vb_enumerator_get_next(&request->inbound_varbind_enumerator, &vb);
+      if (err == SNMP_VB_ENUMERATOR_ERR_OK) {
+        struct snmp_node_instance node_instance;
+        memset(&node_instance, 0, sizeof(node_instance));
+        request->error_status = snmp_get_node_instance_from_oid(vb.oid.id, vb.oid.len, &node_instance);
+        if (request->error_status == SNMP_ERR_NOERROR) {
+          if (node_instance.set_value(&node_instance, vb.value_len, vb.value) != SNMP_ERR_NOERROR) {
+            if (request->inbound_varbind_enumerator.varbind_count == 1) {
+              request->error_status = SNMP_ERR_COMMITFAILED;
+            } else {
+              /* we cannot undo the set operations done so far */
+              request->error_status = SNMP_ERR_UNDOFAILED;
+            }
+          }
+
+          if (node_instance.release_instance != NULL) {
+            node_instance.release_instance(&node_instance);
+          }
+        }
+      } else if (err == SNMP_VB_ENUMERATOR_ERR_EOVB) {
+        /* no more varbinds in request */
+        break;
+      } else {
+        /* first time enumerating varbinds work but second time not, although nothing should have changed in between ??? */
+        request->error_status = SNMP_ERR_GENERROR;
+      }
+    }
+  }
+
+  return ERR_OK;
+}
+
+#define PARSE_EXEC(code, retValue) \
+  if ((code) != ERR_OK) { \
+    LWIP_DEBUGF(SNMP_DEBUG, ("Malformed ASN.1 detected.\n")); \
+    snmp_stats.inasnparseerrs++; \
+    return retValue; \
+  }
+
+#define PARSE_ASSERT(cond, retValue) \
+  if (!(cond)) { \
+    LWIP_DEBUGF(SNMP_DEBUG, ("SNMP parse assertion failed!: " # cond)); \
+    snmp_stats.inasnparseerrs++; \
+    return retValue; \
+  }
+
+#define BUILD_EXEC(code, retValue) \
+  if ((code) != ERR_OK) { \
+    LWIP_DEBUGF(SNMP_DEBUG, ("SNMP error during creation of outbound frame!: " # code)); \
+    return retValue; \
+  }
+
+#define IF_PARSE_EXEC(code)   PARSE_EXEC(code, ERR_ARG)
+#define IF_PARSE_ASSERT(code) PARSE_ASSERT(code, ERR_ARG)
+
+/**
+ * Checks and decodes incoming SNMP message header, logs header errors.
+ *
+ * @param request points to the current message request state return
+ * @return
+ * - ERR_OK SNMP header is sane and accepted
+ * - ERR_VAL SNMP header is either malformed or rejected
+ */
+static err_t
+snmp_parse_inbound_frame(struct snmp_request *request)
+{
+  struct snmp_pbuf_stream pbuf_stream;
+  struct snmp_asn1_tlv tlv;
+  s32_t parent_tlv_value_len;
+  s32_t s32_value;
+  err_t err;
+#if LWIP_SNMP_V3
+  snmpv3_auth_algo_t auth;
+  snmpv3_priv_algo_t priv;
+#endif
+
+  IF_PARSE_EXEC(snmp_pbuf_stream_init(&pbuf_stream, request->inbound_pbuf, 0, request->inbound_pbuf->tot_len));
+
+  /* decode main container consisting of version, community and PDU */
+  IF_PARSE_EXEC(snmp_asn1_dec_tlv(&pbuf_stream, &tlv));
+  IF_PARSE_ASSERT((tlv.type == SNMP_ASN1_TYPE_SEQUENCE) && (tlv.value_len == pbuf_stream.length));
+  parent_tlv_value_len = tlv.value_len;
+
+  /* decode version */
+  IF_PARSE_EXEC(snmp_asn1_dec_tlv(&pbuf_stream, &tlv));
+  IF_PARSE_ASSERT(tlv.type == SNMP_ASN1_TYPE_INTEGER);
+  parent_tlv_value_len -= SNMP_ASN1_TLV_LENGTH(tlv);
+  IF_PARSE_ASSERT(parent_tlv_value_len > 0);
+
+  IF_PARSE_EXEC(snmp_asn1_dec_s32t(&pbuf_stream, tlv.value_len, &s32_value));
+
+  if (((s32_value != SNMP_VERSION_1) &&
+       (s32_value != SNMP_VERSION_2c)
+#if LWIP_SNMP_V3
+       && (s32_value != SNMP_VERSION_3)
+#endif
+      )
+#if LWIP_SNMP_CONFIGURE_VERSIONS
+      || (!snmp_version_enabled(s32_value))
+#endif
+     ) {
+    /* unsupported SNMP version */
+    snmp_stats.inbadversions++;
+    return ERR_ARG;
+  }
+  request->version = (u8_t)s32_value;
+
+#if LWIP_SNMP_V3
+  if (request->version == SNMP_VERSION_3) {
+    u16_t u16_value;
+    u16_t inbound_msgAuthenticationParameters_offset;
+
+    /* SNMPv3 doesn't use communities */
+    /* @todo: Differentiate read/write access */
+    strncpy((char *)request->community, snmp_community, SNMP_MAX_COMMUNITY_STR_LEN);
+    request->community[SNMP_MAX_COMMUNITY_STR_LEN] = 0; /* ensure NULL termination (strncpy does NOT guarantee it!) */
+    request->community_strlen = (u16_t)strnlen((char *)request->community, SNMP_MAX_COMMUNITY_STR_LEN);
+
+    /* RFC3414 globalData */
+    IF_PARSE_EXEC(snmp_asn1_dec_tlv(&pbuf_stream, &tlv));
+    IF_PARSE_ASSERT(tlv.type == SNMP_ASN1_TYPE_SEQUENCE);
+    parent_tlv_value_len -= SNMP_ASN1_TLV_HDR_LENGTH(tlv);
+    IF_PARSE_ASSERT(parent_tlv_value_len > 0);
+
+    /* decode msgID */
+    IF_PARSE_EXEC(snmp_asn1_dec_tlv(&pbuf_stream, &tlv));
+    IF_PARSE_ASSERT(tlv.type == SNMP_ASN1_TYPE_INTEGER);
+    parent_tlv_value_len -= SNMP_ASN1_TLV_LENGTH(tlv);
+    IF_PARSE_ASSERT(parent_tlv_value_len > 0);
+
+    IF_PARSE_EXEC(snmp_asn1_dec_s32t(&pbuf_stream, tlv.value_len, &s32_value));
+    request->msg_id = s32_value;
+
+    /* decode msgMaxSize */
+    IF_PARSE_EXEC(snmp_asn1_dec_tlv(&pbuf_stream, &tlv));
+    IF_PARSE_ASSERT(tlv.type == SNMP_ASN1_TYPE_INTEGER);
+    parent_tlv_value_len -= SNMP_ASN1_TLV_LENGTH(tlv);
+    IF_PARSE_ASSERT(parent_tlv_value_len > 0);
+
+    IF_PARSE_EXEC(snmp_asn1_dec_s32t(&pbuf_stream, tlv.value_len, &s32_value));
+    request->msg_max_size = s32_value;
+
+    /* decode msgFlags */
+    IF_PARSE_EXEC(snmp_asn1_dec_tlv(&pbuf_stream, &tlv));
+    IF_PARSE_ASSERT(tlv.type == SNMP_ASN1_TYPE_OCTET_STRING);
+    parent_tlv_value_len -= SNMP_ASN1_TLV_LENGTH(tlv);
+    IF_PARSE_ASSERT(parent_tlv_value_len > 0);
+
+    IF_PARSE_EXEC(snmp_asn1_dec_s32t(&pbuf_stream, tlv.value_len, &s32_value));
+    request->msg_flags = (u8_t)s32_value;
+
+    /* decode msgSecurityModel */
+    IF_PARSE_EXEC(snmp_asn1_dec_tlv(&pbuf_stream, &tlv));
+    IF_PARSE_ASSERT(tlv.type == SNMP_ASN1_TYPE_INTEGER);
+    parent_tlv_value_len -= SNMP_ASN1_TLV_LENGTH(tlv);
+    IF_PARSE_ASSERT(parent_tlv_value_len > 0);
+
+    IF_PARSE_EXEC(snmp_asn1_dec_s32t(&pbuf_stream, tlv.value_len, &s32_value));
+    request->msg_security_model = s32_value;
+
+    /* RFC3414 msgSecurityParameters
+     * The User-based Security Model defines the contents of the OCTET
+     * STRING as a SEQUENCE.
+     *
+     * We skip the protective dummy OCTET STRING header
+     * to access the SEQUENCE header.
+     */
+    IF_PARSE_EXEC(snmp_asn1_dec_tlv(&pbuf_stream, &tlv));
+    IF_PARSE_ASSERT(tlv.type == SNMP_ASN1_TYPE_OCTET_STRING);
+    parent_tlv_value_len -= SNMP_ASN1_TLV_HDR_LENGTH(tlv);
+    IF_PARSE_ASSERT(parent_tlv_value_len > 0);
+
+    /* msgSecurityParameters SEQUENCE header */
+    IF_PARSE_EXEC(snmp_asn1_dec_tlv(&pbuf_stream, &tlv));
+    IF_PARSE_ASSERT(tlv.type == SNMP_ASN1_TYPE_SEQUENCE);
+    parent_tlv_value_len -= SNMP_ASN1_TLV_HDR_LENGTH(tlv);
+    IF_PARSE_ASSERT(parent_tlv_value_len > 0);
+
+    /* decode msgAuthoritativeEngineID */
+    IF_PARSE_EXEC(snmp_asn1_dec_tlv(&pbuf_stream, &tlv));
+    IF_PARSE_ASSERT(tlv.type == SNMP_ASN1_TYPE_OCTET_STRING);
+    parent_tlv_value_len -= SNMP_ASN1_TLV_LENGTH(tlv);
+    IF_PARSE_ASSERT(parent_tlv_value_len > 0);
+
+    IF_PARSE_EXEC(snmp_asn1_dec_raw(&pbuf_stream, tlv.value_len, request->msg_authoritative_engine_id,
+                                    &u16_value, SNMP_V3_MAX_ENGINE_ID_LENGTH));
+    request->msg_authoritative_engine_id_len = (u8_t)u16_value;
+
+    /* msgAuthoritativeEngineBoots */
+    IF_PARSE_EXEC(snmp_asn1_dec_tlv(&pbuf_stream, &tlv));
+    IF_PARSE_ASSERT(tlv.type == SNMP_ASN1_TYPE_INTEGER);
+    parent_tlv_value_len -= SNMP_ASN1_TLV_LENGTH(tlv);
+    IF_PARSE_ASSERT(parent_tlv_value_len > 0);
+    IF_PARSE_EXEC(snmp_asn1_dec_s32t(&pbuf_stream, tlv.value_len, &request->msg_authoritative_engine_boots));
+
+    /* msgAuthoritativeEngineTime */
+    IF_PARSE_EXEC(snmp_asn1_dec_tlv(&pbuf_stream, &tlv));
+    IF_PARSE_ASSERT(tlv.type == SNMP_ASN1_TYPE_INTEGER);
+    parent_tlv_value_len -= SNMP_ASN1_TLV_LENGTH(tlv);
+    IF_PARSE_ASSERT(parent_tlv_value_len > 0);
+    IF_PARSE_EXEC(snmp_asn1_dec_s32t(&pbuf_stream, tlv.value_len, &request->msg_authoritative_engine_time));
+
+    /* msgUserName */
+    IF_PARSE_EXEC(snmp_asn1_dec_tlv(&pbuf_stream, &tlv));
+    IF_PARSE_ASSERT(tlv.type == SNMP_ASN1_TYPE_OCTET_STRING);
+    parent_tlv_value_len -= SNMP_ASN1_TLV_LENGTH(tlv);
+    IF_PARSE_ASSERT(parent_tlv_value_len > 0);
+
+    IF_PARSE_EXEC(snmp_asn1_dec_raw(&pbuf_stream, tlv.value_len, request->msg_user_name,
+                                    &u16_value, SNMP_V3_MAX_USER_LENGTH));
+    request->msg_user_name_len = (u8_t)u16_value;
+
+    /* msgAuthenticationParameters */
+    memset(request->msg_authentication_parameters, 0, SNMP_V3_MAX_AUTH_PARAM_LENGTH);
+    IF_PARSE_EXEC(snmp_asn1_dec_tlv(&pbuf_stream, &tlv));
+    IF_PARSE_ASSERT(tlv.type == SNMP_ASN1_TYPE_OCTET_STRING);
+    parent_tlv_value_len -= SNMP_ASN1_TLV_LENGTH(tlv);
+    IF_PARSE_ASSERT(parent_tlv_value_len > 0);
+    /* Remember position */
+    inbound_msgAuthenticationParameters_offset = pbuf_stream.offset;
+    LWIP_UNUSED_ARG(inbound_msgAuthenticationParameters_offset);
+    /* Read auth parameters */
+    /* IF_PARSE_ASSERT(tlv.value_len <= SNMP_V3_MAX_AUTH_PARAM_LENGTH); */
+    IF_PARSE_EXEC(snmp_asn1_dec_raw(&pbuf_stream, tlv.value_len, request->msg_authentication_parameters,
+                                    &u16_value, tlv.value_len));
+    request->msg_authentication_parameters_len = (u8_t)u16_value;
+
+    /* msgPrivacyParameters */
+    memset(request->msg_privacy_parameters, 0, SNMP_V3_MAX_PRIV_PARAM_LENGTH);
+    IF_PARSE_EXEC(snmp_asn1_dec_tlv(&pbuf_stream, &tlv));
+    IF_PARSE_ASSERT(tlv.type == SNMP_ASN1_TYPE_OCTET_STRING);
+    parent_tlv_value_len -= SNMP_ASN1_TLV_LENGTH(tlv);
+    IF_PARSE_ASSERT(parent_tlv_value_len > 0);
+
+    IF_PARSE_EXEC(snmp_asn1_dec_raw(&pbuf_stream, tlv.value_len, request->msg_privacy_parameters,
+                                    &u16_value, SNMP_V3_MAX_PRIV_PARAM_LENGTH));
+    request->msg_privacy_parameters_len = (u8_t)u16_value;
+
+    /* validate securityParameters here (do this after decoding because we don't want to increase other counters for wrong frames)
+     * 1) securityParameters was correctly serialized if we reach here.
+     * 2) securityParameters are already cached.
+     * 3) if msgAuthoritativeEngineID is unknown, zero-length or too long:
+         b) https://tools.ietf.org/html/rfc3414#section-7
+     */
+    {
+      const char *eid;
+      u8_t eid_len;
+
+      snmpv3_get_engine_id(&eid, &eid_len);
+
+      if ((request->msg_authoritative_engine_id_len == 0) ||
+          (request->msg_authoritative_engine_id_len != eid_len) ||
+          (memcmp(eid, request->msg_authoritative_engine_id, eid_len) != 0)) {
+        snmp_stats.unknownengineids++;
+        request->msg_flags = 0; /* noauthnopriv */
+        request->error_status = SNMP_ERR_UNKNOWN_ENGINEID;
+        return ERR_OK;
+      }
+    }
+
+    /* 4) verify username */
+    if (snmpv3_get_user((char *)request->msg_user_name, &auth, NULL, &priv, NULL)) {
+      snmp_stats.unknownusernames++;
+      request->msg_flags = 0; /* noauthnopriv */
+      request->error_status = SNMP_ERR_UNKNOWN_SECURITYNAME;
+      return ERR_OK;
+    }
+
+    /* 5) verify security level */
+    switch (request->msg_flags & (SNMP_V3_AUTH_FLAG | SNMP_V3_PRIV_FLAG)) {
+      case SNMP_V3_NOAUTHNOPRIV:
+        if ((auth != SNMP_V3_AUTH_ALGO_INVAL) || (priv != SNMP_V3_PRIV_ALGO_INVAL)) {
+          /* Invalid security level for user */
+          snmp_stats.unsupportedseclevels++;
+          request->msg_flags = SNMP_V3_NOAUTHNOPRIV;
+          request->error_status = SNMP_ERR_UNSUPPORTED_SECLEVEL;
+          return ERR_OK;
+        }
+        break;
+#if LWIP_SNMP_V3_CRYPTO
+      case SNMP_V3_AUTHNOPRIV:
+        if ((auth == SNMP_V3_AUTH_ALGO_INVAL) || (priv != SNMP_V3_PRIV_ALGO_INVAL)) {
+          /* Invalid security level for user */
+          snmp_stats.unsupportedseclevels++;
+          request->msg_flags = SNMP_V3_NOAUTHNOPRIV;
+          request->error_status = SNMP_ERR_UNSUPPORTED_SECLEVEL;
+          return ERR_OK;
+        }
+        break;
+      case SNMP_V3_AUTHPRIV:
+        if ((auth == SNMP_V3_AUTH_ALGO_INVAL) || (priv == SNMP_V3_PRIV_ALGO_INVAL)) {
+          /* Invalid security level for user */
+          snmp_stats.unsupportedseclevels++;
+          request->msg_flags = SNMP_V3_NOAUTHNOPRIV;
+          request->error_status = SNMP_ERR_UNSUPPORTED_SECLEVEL;
+          return ERR_OK;
+        }
+        break;
+#endif
+      default:
+        snmp_stats.unsupportedseclevels++;
+        request->msg_flags = SNMP_V3_NOAUTHNOPRIV;
+        request->error_status = SNMP_ERR_UNSUPPORTED_SECLEVEL;
+        return ERR_OK;
+    }
+
+    /* 6) if securitylevel specifies authentication, authenticate message. */
+#if LWIP_SNMP_V3_CRYPTO
+    if (request->msg_flags & SNMP_V3_AUTH_FLAG) {
+      const u8_t zero_arr[SNMP_V3_MAX_AUTH_PARAM_LENGTH] = { 0 };
+      u8_t key[20];
+      u8_t hmac[LWIP_MAX(SNMP_V3_SHA_LEN, SNMP_V3_MD5_LEN)];
+      struct snmp_pbuf_stream auth_stream;
+
+      if (request->msg_authentication_parameters_len > SNMP_V3_MAX_AUTH_PARAM_LENGTH) {
+        snmp_stats.wrongdigests++;
+        request->msg_flags = SNMP_V3_NOAUTHNOPRIV;
+        request->error_status = SNMP_ERR_AUTHORIZATIONERROR;
+        return ERR_OK;
+      }
+
+      /* Rewind stream */
+      IF_PARSE_EXEC(snmp_pbuf_stream_init(&auth_stream, request->inbound_pbuf, 0, request->inbound_pbuf->tot_len));
+      IF_PARSE_EXEC(snmp_pbuf_stream_seek_abs(&auth_stream, inbound_msgAuthenticationParameters_offset));
+      /* Set auth parameters to zero for verification */
+      IF_PARSE_EXEC(snmp_asn1_enc_raw(&auth_stream, zero_arr, request->msg_authentication_parameters_len));
+
+      /* Verify authentication */
+      IF_PARSE_EXEC(snmp_pbuf_stream_init(&auth_stream, request->inbound_pbuf, 0, request->inbound_pbuf->tot_len));
+
+      IF_PARSE_EXEC(snmpv3_get_user((char *)request->msg_user_name, &auth, key, NULL, NULL));
+      IF_PARSE_EXEC(snmpv3_auth(&auth_stream, request->inbound_pbuf->tot_len, key, auth, hmac));
+
+      if (memcmp(request->msg_authentication_parameters, hmac, SNMP_V3_MAX_AUTH_PARAM_LENGTH)) {
+        snmp_stats.wrongdigests++;
+        request->msg_flags = SNMP_V3_NOAUTHNOPRIV;
+        request->error_status = SNMP_ERR_AUTHORIZATIONERROR;
+        return ERR_OK;
+      }
+
+      /* 7) if securitylevel specifies authentication, verify engineboots, enginetime and lastenginetime */
+      {
+        s32_t boots = snmpv3_get_engine_boots_internal();
+        if ((request->msg_authoritative_engine_boots != boots) || (boots == 2147483647UL)) {
+          snmp_stats.notintimewindows++;
+          request->msg_flags = SNMP_V3_AUTHNOPRIV;
+          request->error_status = SNMP_ERR_NOTINTIMEWINDOW;
+          return ERR_OK;
+        }
+      }
+      {
+        s32_t time = snmpv3_get_engine_time_internal();
+        if (request->msg_authoritative_engine_time > (time + 150)) {
+          snmp_stats.notintimewindows++;
+          request->msg_flags = SNMP_V3_AUTHNOPRIV;
+          request->error_status = SNMP_ERR_NOTINTIMEWINDOW;
+          return ERR_OK;
+        } else if (time > 150) {
+          if (request->msg_authoritative_engine_time < (time - 150)) {
+            snmp_stats.notintimewindows++;
+            request->msg_flags = SNMP_V3_AUTHNOPRIV;
+            request->error_status = SNMP_ERR_NOTINTIMEWINDOW;
+            return ERR_OK;
+          }
+        }
+      }
+    }
+#endif
+
+    /* 8) if securitylevel specifies privacy, decrypt message. */
+#if LWIP_SNMP_V3_CRYPTO
+    if (request->msg_flags & SNMP_V3_PRIV_FLAG) {
+      /* Decrypt message */
+
+      u8_t key[20];
+
+      IF_PARSE_EXEC(snmp_asn1_dec_tlv(&pbuf_stream, &tlv));
+      IF_PARSE_ASSERT(tlv.type == SNMP_ASN1_TYPE_OCTET_STRING);
+      parent_tlv_value_len -= SNMP_ASN1_TLV_HDR_LENGTH(tlv);
+      IF_PARSE_ASSERT(parent_tlv_value_len > 0);
+
+      IF_PARSE_EXEC(snmpv3_get_user((char *)request->msg_user_name, NULL, NULL, &priv, key));
+      if (snmpv3_crypt(&pbuf_stream, tlv.value_len, key,
+                       request->msg_privacy_parameters, request->msg_authoritative_engine_boots,
+                       request->msg_authoritative_engine_time, priv, SNMP_V3_PRIV_MODE_DECRYPT) != ERR_OK) {
+        snmp_stats.decryptionerrors++;
+        request->msg_flags = SNMP_V3_AUTHNOPRIV;
+        request->error_status = SNMP_ERR_DECRYIPTION_ERROR;
+        return ERR_OK;
+      }
+    }
+#endif
+    /* 9) calculate max size of scoped pdu?
+     * 10) securityname for user is retrieved from usertable?
+     * 11) security data is cached?
+     * 12)
+     */
+
+    /* Scoped PDU
+     * Encryption context
+     */
+    IF_PARSE_EXEC(snmp_asn1_dec_tlv(&pbuf_stream, &tlv));
+    IF_PARSE_ASSERT(tlv.type == SNMP_ASN1_TYPE_SEQUENCE);
+    parent_tlv_value_len -= SNMP_ASN1_TLV_HDR_LENGTH(tlv);
+    IF_PARSE_ASSERT(parent_tlv_value_len > 0);
+
+    /* contextEngineID */
+    IF_PARSE_EXEC(snmp_asn1_dec_tlv(&pbuf_stream, &tlv));
+    IF_PARSE_ASSERT(tlv.type == SNMP_ASN1_TYPE_OCTET_STRING);
+    parent_tlv_value_len -= SNMP_ASN1_TLV_LENGTH(tlv);
+    IF_PARSE_ASSERT(parent_tlv_value_len > 0);
+
+    IF_PARSE_EXEC(snmp_asn1_dec_raw(&pbuf_stream, tlv.value_len, request->context_engine_id,
+                                    &u16_value, SNMP_V3_MAX_ENGINE_ID_LENGTH));
+    request->context_engine_id_len = (u8_t)u16_value;
+    /* TODO: do we need to verify this contextengineid too? */
+
+    /* contextName */
+    IF_PARSE_EXEC(snmp_asn1_dec_tlv(&pbuf_stream, &tlv));
+    IF_PARSE_ASSERT(tlv.type == SNMP_ASN1_TYPE_OCTET_STRING);
+    parent_tlv_value_len -= SNMP_ASN1_TLV_LENGTH(tlv);
+    IF_PARSE_ASSERT(parent_tlv_value_len > 0);
+
+    IF_PARSE_EXEC(snmp_asn1_dec_raw(&pbuf_stream, tlv.value_len, request->context_name,
+                                    &u16_value, SNMP_V3_MAX_ENGINE_ID_LENGTH));
+    request->context_name_len = (u8_t)u16_value;
+    /* TODO: do we need to verify this contextname too? */
+  } else
+#endif
+  {
+    /* decode community */
+    IF_PARSE_EXEC(snmp_asn1_dec_tlv(&pbuf_stream, &tlv));
+    IF_PARSE_ASSERT(tlv.type == SNMP_ASN1_TYPE_OCTET_STRING);
+    parent_tlv_value_len -= SNMP_ASN1_TLV_LENGTH(tlv);
+    IF_PARSE_ASSERT(parent_tlv_value_len > 0);
+
+    err = snmp_asn1_dec_raw(&pbuf_stream, tlv.value_len, request->community, &request->community_strlen, SNMP_MAX_COMMUNITY_STR_LEN);
+    if (err == ERR_MEM) {
+      /* community string does not fit in our buffer -> its too long -> its invalid */
+      request->community_strlen = 0;
+      snmp_pbuf_stream_seek(&pbuf_stream, tlv.value_len);
+    } else {
+      IF_PARSE_ASSERT(err == ERR_OK);
+    }
+    /* add zero terminator */
+    request->community[request->community_strlen] = 0;
+  }
+
+  /* decode PDU type (next container level) */
+  IF_PARSE_EXEC(snmp_asn1_dec_tlv(&pbuf_stream, &tlv));
+  IF_PARSE_ASSERT(tlv.value_len <= pbuf_stream.length);
+  request->inbound_padding_len = pbuf_stream.length - tlv.value_len;
+  parent_tlv_value_len = tlv.value_len;
+
+  /* validate PDU type */
+  switch (tlv.type) {
+    case (SNMP_ASN1_CLASS_CONTEXT | SNMP_ASN1_CONTENTTYPE_CONSTRUCTED | SNMP_ASN1_CONTEXT_PDU_GET_REQ):
+      /* GetRequest PDU */
+      snmp_stats.ingetrequests++;
+      break;
+    case (SNMP_ASN1_CLASS_CONTEXT | SNMP_ASN1_CONTENTTYPE_CONSTRUCTED | SNMP_ASN1_CONTEXT_PDU_GET_NEXT_REQ):
+      /* GetNextRequest PDU */
+      snmp_stats.ingetnexts++;
+      break;
+    case (SNMP_ASN1_CLASS_CONTEXT | SNMP_ASN1_CONTENTTYPE_CONSTRUCTED | SNMP_ASN1_CONTEXT_PDU_GET_BULK_REQ):
+      /* GetBulkRequest PDU */
+      if (request->version < SNMP_VERSION_2c) {
+        /* RFC2089: invalid, drop packet */
+        return ERR_ARG;
+      }
+      break;
+    case (SNMP_ASN1_CLASS_CONTEXT | SNMP_ASN1_CONTENTTYPE_CONSTRUCTED | SNMP_ASN1_CONTEXT_PDU_SET_REQ):
+      /* SetRequest PDU */
+      snmp_stats.insetrequests++;
+      break;
+    default:
+      /* unsupported input PDU for this agent (no parse error) */
+      LWIP_DEBUGF(SNMP_DEBUG, ("Unknown/Invalid SNMP PDU type received: %d", tlv.type)); \
+      return ERR_ARG;
+  }
+  request->request_type = tlv.type & SNMP_ASN1_DATATYPE_MASK;
+  request->request_out_type = (SNMP_ASN1_CLASS_CONTEXT | SNMP_ASN1_CONTENTTYPE_CONSTRUCTED | SNMP_ASN1_CONTEXT_PDU_GET_RESP);
+
+  /* validate community (do this after decoding PDU type because we don't want to increase 'inbadcommunitynames' for wrong frame types */
+  if (request->community_strlen == 0) {
+    /* community string was too long or really empty*/
+    snmp_stats.inbadcommunitynames++;
+    snmp_authfail_trap();
+    return ERR_ARG;
+  } else if (request->request_type == SNMP_ASN1_CONTEXT_PDU_SET_REQ) {
+    if (snmp_community_write[0] == 0) {
+      /* our write community is empty, that means all our objects are readonly */
+      request->error_status = SNMP_ERR_NOTWRITABLE;
+      request->error_index  = 1;
+    } else if (strncmp(snmp_community_write, (const char *)request->community, SNMP_MAX_COMMUNITY_STR_LEN) != 0) {
+      /* community name does not match */
+      snmp_stats.inbadcommunitynames++;
+      snmp_authfail_trap();
+      return ERR_ARG;
+    }
+  } else {
+    if (strncmp(snmp_community, (const char *)request->community, SNMP_MAX_COMMUNITY_STR_LEN) != 0) {
+      /* community name does not match */
+      snmp_stats.inbadcommunitynames++;
+      snmp_authfail_trap();
+      return ERR_ARG;
+    }
+  }
+
+  /* decode request ID */
+  IF_PARSE_EXEC(snmp_asn1_dec_tlv(&pbuf_stream, &tlv));
+  IF_PARSE_ASSERT(tlv.type == SNMP_ASN1_TYPE_INTEGER);
+  parent_tlv_value_len -= SNMP_ASN1_TLV_LENGTH(tlv);
+  IF_PARSE_ASSERT(parent_tlv_value_len > 0);
+
+  IF_PARSE_EXEC(snmp_asn1_dec_s32t(&pbuf_stream, tlv.value_len, &request->request_id));
+
+  /* decode error status / non-repeaters */
+  IF_PARSE_EXEC(snmp_asn1_dec_tlv(&pbuf_stream, &tlv));
+  IF_PARSE_ASSERT(tlv.type == SNMP_ASN1_TYPE_INTEGER);
+  parent_tlv_value_len -= SNMP_ASN1_TLV_LENGTH(tlv);
+  IF_PARSE_ASSERT(parent_tlv_value_len > 0);
+
+  if (request->request_type == SNMP_ASN1_CONTEXT_PDU_GET_BULK_REQ) {
+    IF_PARSE_EXEC(snmp_asn1_dec_s32t(&pbuf_stream, tlv.value_len, &request->non_repeaters));
+    if (request->non_repeaters < 0) {
+      /* RFC 1905, 4.2.3 */
+      request->non_repeaters = 0;
+    }
+  } else {
+    /* only check valid value, don't touch 'request->error_status', maybe a response error status was already set to above; */
+    IF_PARSE_EXEC(snmp_asn1_dec_s32t(&pbuf_stream, tlv.value_len, &s32_value));
+    IF_PARSE_ASSERT(s32_value == SNMP_ERR_NOERROR);
+  }
+
+  /* decode error index / max-repetitions */
+  IF_PARSE_EXEC(snmp_asn1_dec_tlv(&pbuf_stream, &tlv));
+  IF_PARSE_ASSERT(tlv.type == SNMP_ASN1_TYPE_INTEGER);
+  parent_tlv_value_len -= SNMP_ASN1_TLV_LENGTH(tlv);
+  IF_PARSE_ASSERT(parent_tlv_value_len > 0);
+
+  if (request->request_type == SNMP_ASN1_CONTEXT_PDU_GET_BULK_REQ) {
+    IF_PARSE_EXEC(snmp_asn1_dec_s32t(&pbuf_stream, tlv.value_len, &request->max_repetitions));
+    if (request->max_repetitions < 0) {
+      /* RFC 1905, 4.2.3 */
+      request->max_repetitions = 0;
+    }
+  } else {
+    IF_PARSE_EXEC(snmp_asn1_dec_s32t(&pbuf_stream, tlv.value_len, &request->error_index));
+    IF_PARSE_ASSERT(s32_value == 0);
+  }
+
+  /* decode varbind-list type (next container level) */
+  IF_PARSE_EXEC(snmp_asn1_dec_tlv(&pbuf_stream, &tlv));
+  IF_PARSE_ASSERT((tlv.type == SNMP_ASN1_TYPE_SEQUENCE) && (tlv.value_len <= pbuf_stream.length));
+
+  request->inbound_varbind_offset = pbuf_stream.offset;
+  request->inbound_varbind_len    = pbuf_stream.length - request->inbound_padding_len;
+  snmp_vb_enumerator_init(&(request->inbound_varbind_enumerator), request->inbound_pbuf, request->inbound_varbind_offset, request->inbound_varbind_len);
+
+  return ERR_OK;
+}
+
+#define OF_BUILD_EXEC(code) BUILD_EXEC(code, ERR_ARG)
+
+static err_t
+snmp_prepare_outbound_frame(struct snmp_request *request)
+{
+  struct snmp_asn1_tlv tlv;
+  struct snmp_pbuf_stream *pbuf_stream = &(request->outbound_pbuf_stream);
+
+  /* try allocating pbuf(s) for maximum response size */
+  request->outbound_pbuf = pbuf_alloc(PBUF_TRANSPORT, 1472, PBUF_RAM);
+  if (request->outbound_pbuf == NULL) {
+    return ERR_MEM;
+  }
+
+  snmp_pbuf_stream_init(pbuf_stream, request->outbound_pbuf, 0, request->outbound_pbuf->tot_len);
+
+  /* 'Message' sequence */
+  SNMP_ASN1_SET_TLV_PARAMS(tlv, SNMP_ASN1_TYPE_SEQUENCE, 3, 0);
+  OF_BUILD_EXEC( snmp_ans1_enc_tlv(pbuf_stream, &tlv) );
+
+  /* version */
+  SNMP_ASN1_SET_TLV_PARAMS(tlv, SNMP_ASN1_TYPE_INTEGER, 0, 0);
+  snmp_asn1_enc_s32t_cnt(request->version, &tlv.value_len);
+  OF_BUILD_EXEC( snmp_ans1_enc_tlv(pbuf_stream, &tlv) );
+  OF_BUILD_EXEC( snmp_asn1_enc_s32t(pbuf_stream, tlv.value_len, request->version) );
+
+#if LWIP_SNMP_V3
+  if (request->version < SNMP_VERSION_3) {
+#endif
+    /* community */
+    SNMP_ASN1_SET_TLV_PARAMS(tlv, SNMP_ASN1_TYPE_OCTET_STRING, 0, request->community_strlen);
+    OF_BUILD_EXEC( snmp_ans1_enc_tlv(pbuf_stream, &tlv) );
+    OF_BUILD_EXEC( snmp_asn1_enc_raw(pbuf_stream, request->community, request->community_strlen) );
+#if LWIP_SNMP_V3
+  } else {
+    const char *id;
+
+    /* globalData */
+    request->outbound_msg_global_data_offset = pbuf_stream->offset;
+    SNMP_ASN1_SET_TLV_PARAMS(tlv, SNMP_ASN1_TYPE_SEQUENCE, 1, 0);
+    OF_BUILD_EXEC(snmp_ans1_enc_tlv(pbuf_stream, &tlv));
+
+    /* msgID */
+    SNMP_ASN1_SET_TLV_PARAMS(tlv, SNMP_ASN1_TYPE_INTEGER, 0, 1);
+    snmp_asn1_enc_s32t_cnt(request->msg_id, &tlv.value_len);
+    OF_BUILD_EXEC(snmp_ans1_enc_tlv(pbuf_stream, &tlv));
+    OF_BUILD_EXEC(snmp_asn1_enc_s32t(pbuf_stream, tlv.value_len, request->msg_id));
+
+    /* msgMaxSize */
+    SNMP_ASN1_SET_TLV_PARAMS(tlv, SNMP_ASN1_TYPE_INTEGER, 0, 1);
+    snmp_asn1_enc_s32t_cnt(request->msg_max_size, &tlv.value_len);
+    OF_BUILD_EXEC(snmp_ans1_enc_tlv(pbuf_stream, &tlv));
+    OF_BUILD_EXEC(snmp_asn1_enc_s32t(pbuf_stream, tlv.value_len, request->msg_max_size));
+
+    /* msgFlags */
+    SNMP_ASN1_SET_TLV_PARAMS(tlv, SNMP_ASN1_TYPE_OCTET_STRING, 0, 1);
+    OF_BUILD_EXEC(snmp_ans1_enc_tlv(pbuf_stream, &tlv));
+    OF_BUILD_EXEC(snmp_asn1_enc_raw(pbuf_stream, &request->msg_flags, 1));
+
+    /* msgSecurityModel */
+    SNMP_ASN1_SET_TLV_PARAMS(tlv, SNMP_ASN1_TYPE_INTEGER, 0, 1);
+    snmp_asn1_enc_s32t_cnt(request->msg_security_model, &tlv.value_len);
+    OF_BUILD_EXEC(snmp_ans1_enc_tlv(pbuf_stream, &tlv));
+    OF_BUILD_EXEC(snmp_asn1_enc_s32t(pbuf_stream, tlv.value_len, request->msg_security_model));
+
+    /* end of msgGlobalData */
+    request->outbound_msg_global_data_end = pbuf_stream->offset;
+
+    /* msgSecurityParameters */
+    request->outbound_msg_security_parameters_str_offset = pbuf_stream->offset;
+    SNMP_ASN1_SET_TLV_PARAMS(tlv, SNMP_ASN1_TYPE_OCTET_STRING, 1, 0);
+    OF_BUILD_EXEC(snmp_ans1_enc_tlv(pbuf_stream, &tlv));
+
+    request->outbound_msg_security_parameters_seq_offset = pbuf_stream->offset;
+    SNMP_ASN1_SET_TLV_PARAMS(tlv, SNMP_ASN1_TYPE_SEQUENCE, 1, 0);
+    OF_BUILD_EXEC(snmp_ans1_enc_tlv(pbuf_stream, &tlv));
+
+    /* msgAuthoritativeEngineID */
+    snmpv3_get_engine_id(&id, &request->msg_authoritative_engine_id_len);
+    MEMCPY(request->msg_authoritative_engine_id, id, request->msg_authoritative_engine_id_len);
+    SNMP_ASN1_SET_TLV_PARAMS(tlv, SNMP_ASN1_TYPE_OCTET_STRING, 0, request->msg_authoritative_engine_id_len);
+    OF_BUILD_EXEC(snmp_ans1_enc_tlv(pbuf_stream, &tlv));
+    OF_BUILD_EXEC(snmp_asn1_enc_raw(pbuf_stream, request->msg_authoritative_engine_id, request->msg_authoritative_engine_id_len));
+
+    request->msg_authoritative_engine_time = snmpv3_get_engine_time();
+    request->msg_authoritative_engine_boots = snmpv3_get_engine_boots();
+
+    /* msgAuthoritativeEngineBoots */
+    SNMP_ASN1_SET_TLV_PARAMS(tlv, SNMP_ASN1_TYPE_INTEGER, 0, 0);
+    snmp_asn1_enc_s32t_cnt(request->msg_authoritative_engine_boots, &tlv.value_len);
+    OF_BUILD_EXEC(snmp_ans1_enc_tlv(pbuf_stream, &tlv));
+    OF_BUILD_EXEC(snmp_asn1_enc_s32t(pbuf_stream, tlv.value_len, request->msg_authoritative_engine_boots));
+
+    /* msgAuthoritativeEngineTime */
+    SNMP_ASN1_SET_TLV_PARAMS(tlv, SNMP_ASN1_TYPE_INTEGER, 0, 0);
+    snmp_asn1_enc_s32t_cnt(request->msg_authoritative_engine_time, &tlv.value_len);
+    OF_BUILD_EXEC(snmp_ans1_enc_tlv(pbuf_stream, &tlv));
+    OF_BUILD_EXEC(snmp_asn1_enc_s32t(pbuf_stream, tlv.value_len, request->msg_authoritative_engine_time));
+
+    /* msgUserName */
+    SNMP_ASN1_SET_TLV_PARAMS(tlv, SNMP_ASN1_TYPE_OCTET_STRING, 0, request->msg_user_name_len);
+    OF_BUILD_EXEC(snmp_ans1_enc_tlv(pbuf_stream, &tlv));
+    OF_BUILD_EXEC(snmp_asn1_enc_raw(pbuf_stream, request->msg_user_name, request->msg_user_name_len));
+
+#if LWIP_SNMP_V3_CRYPTO
+    /* msgAuthenticationParameters */
+    if (request->msg_flags & SNMP_V3_AUTH_FLAG) {
+      memset(request->msg_authentication_parameters, 0, SNMP_V3_MAX_AUTH_PARAM_LENGTH);
+      request->outbound_msg_authentication_parameters_offset = pbuf_stream->offset;
+      SNMP_ASN1_SET_TLV_PARAMS(tlv, SNMP_ASN1_TYPE_OCTET_STRING, 1, SNMP_V3_MAX_AUTH_PARAM_LENGTH);
+      OF_BUILD_EXEC(snmp_ans1_enc_tlv(pbuf_stream, &tlv));
+      OF_BUILD_EXEC(snmp_asn1_enc_raw(pbuf_stream, request->msg_authentication_parameters, SNMP_V3_MAX_AUTH_PARAM_LENGTH));
+    } else
+#endif
+    {
+      SNMP_ASN1_SET_TLV_PARAMS(tlv, SNMP_ASN1_TYPE_OCTET_STRING, 0, 0);
+      OF_BUILD_EXEC(snmp_ans1_enc_tlv(pbuf_stream, &tlv));
+    }
+
+#if LWIP_SNMP_V3_CRYPTO
+    /* msgPrivacyParameters */
+    if (request->msg_flags & SNMP_V3_PRIV_FLAG) {
+      snmpv3_build_priv_param(request->msg_privacy_parameters);
+
+      SNMP_ASN1_SET_TLV_PARAMS(tlv, SNMP_ASN1_TYPE_OCTET_STRING, 0, SNMP_V3_MAX_PRIV_PARAM_LENGTH);
+      OF_BUILD_EXEC(snmp_ans1_enc_tlv(pbuf_stream, &tlv));
+      OF_BUILD_EXEC(snmp_asn1_enc_raw(pbuf_stream, request->msg_privacy_parameters, SNMP_V3_MAX_PRIV_PARAM_LENGTH));
+    } else
+#endif
+    {
+      SNMP_ASN1_SET_TLV_PARAMS(tlv, SNMP_ASN1_TYPE_OCTET_STRING, 0, 0);
+      OF_BUILD_EXEC(snmp_ans1_enc_tlv(pbuf_stream, &tlv) );
+    }
+
+    /* End of msgSecurityParameters, so we can calculate the length of this sequence later */
+    request->outbound_msg_security_parameters_end = pbuf_stream->offset;
+
+#if LWIP_SNMP_V3_CRYPTO
+    /* For encryption we have to encapsulate the payload in an octet string */
+    if (request->msg_flags & SNMP_V3_PRIV_FLAG) {
+      request->outbound_scoped_pdu_string_offset = pbuf_stream->offset;
+      SNMP_ASN1_SET_TLV_PARAMS(tlv, SNMP_ASN1_TYPE_OCTET_STRING, 3, 0);
+      OF_BUILD_EXEC(snmp_ans1_enc_tlv(pbuf_stream, &tlv));
+    }
+#endif
+    /* Scoped PDU
+     * Encryption context
+     */
+    request->outbound_scoped_pdu_seq_offset = pbuf_stream->offset;
+    SNMP_ASN1_SET_TLV_PARAMS(tlv, SNMP_ASN1_TYPE_SEQUENCE, 3, 0);
+    OF_BUILD_EXEC(snmp_ans1_enc_tlv(pbuf_stream, &tlv));
+
+    /* contextEngineID */
+    snmpv3_get_engine_id(&id, &request->context_engine_id_len);
+    MEMCPY(request->context_engine_id, id, request->context_engine_id_len);
+    SNMP_ASN1_SET_TLV_PARAMS(tlv, SNMP_ASN1_TYPE_OCTET_STRING, 0, request->context_engine_id_len);
+    OF_BUILD_EXEC(snmp_ans1_enc_tlv(pbuf_stream, &tlv));
+    OF_BUILD_EXEC(snmp_asn1_enc_raw(pbuf_stream, request->context_engine_id, request->context_engine_id_len));
+
+    /* contextName */
+    SNMP_ASN1_SET_TLV_PARAMS(tlv, SNMP_ASN1_TYPE_OCTET_STRING, 0, request->context_name_len);
+    OF_BUILD_EXEC(snmp_ans1_enc_tlv(pbuf_stream, &tlv));
+    OF_BUILD_EXEC(snmp_asn1_enc_raw(pbuf_stream, request->context_name, request->context_name_len));
+  }
+#endif
+
+  /* 'PDU' sequence */
+  request->outbound_pdu_offset = pbuf_stream->offset;
+  SNMP_ASN1_SET_TLV_PARAMS(tlv, request->request_out_type, 3, 0);
+  OF_BUILD_EXEC( snmp_ans1_enc_tlv(pbuf_stream, &tlv) );
+
+  /* request ID */
+  SNMP_ASN1_SET_TLV_PARAMS(tlv, SNMP_ASN1_TYPE_INTEGER, 0, 0);
+  snmp_asn1_enc_s32t_cnt(request->request_id, &tlv.value_len);
+  OF_BUILD_EXEC( snmp_ans1_enc_tlv(pbuf_stream, &tlv) );
+  OF_BUILD_EXEC( snmp_asn1_enc_s32t(pbuf_stream, tlv.value_len, request->request_id) );
+
+  /* error status */
+  SNMP_ASN1_SET_TLV_PARAMS(tlv, SNMP_ASN1_TYPE_INTEGER, 0, 1);
+  OF_BUILD_EXEC( snmp_ans1_enc_tlv(pbuf_stream, &tlv) );
+  request->outbound_error_status_offset = pbuf_stream->offset;
+  OF_BUILD_EXEC( snmp_pbuf_stream_write(pbuf_stream, 0) );
+
+  /* error index */
+  SNMP_ASN1_SET_TLV_PARAMS(tlv, SNMP_ASN1_TYPE_INTEGER, 0, 1);
+  OF_BUILD_EXEC( snmp_ans1_enc_tlv(pbuf_stream, &tlv) );
+  request->outbound_error_index_offset = pbuf_stream->offset;
+  OF_BUILD_EXEC( snmp_pbuf_stream_write(pbuf_stream, 0) );
+
+  /* 'VarBindList' sequence */
+  SNMP_ASN1_SET_TLV_PARAMS(tlv, SNMP_ASN1_TYPE_SEQUENCE, 3, 0);
+  OF_BUILD_EXEC( snmp_ans1_enc_tlv(pbuf_stream, &tlv) );
+
+  request->outbound_varbind_offset = pbuf_stream->offset;
+
+  return ERR_OK;
+}
+
+/** Calculate the length of a varbind list */
+err_t
+snmp_varbind_length(struct snmp_varbind *varbind, struct snmp_varbind_len *len)
+{
+  /* calculate required lengths */
+  snmp_asn1_enc_oid_cnt(varbind->oid.id, varbind->oid.len, &len->oid_value_len);
+  snmp_asn1_enc_length_cnt(len->oid_value_len, &len->oid_len_len);
+
+  if (varbind->value_len == 0) {
+    len->value_value_len = 0;
+  } else if (varbind->value_len & SNMP_GET_VALUE_RAW_DATA) {
+    len->value_value_len = varbind->value_len & (~SNMP_GET_VALUE_RAW_DATA);
+  } else {
+    switch (varbind->type) {
+      case SNMP_ASN1_TYPE_INTEGER:
+        if (varbind->value_len != sizeof (s32_t)) {
+          return ERR_VAL;
+        }
+        snmp_asn1_enc_s32t_cnt(*((s32_t *) varbind->value), &len->value_value_len);
+        break;
+      case SNMP_ASN1_TYPE_COUNTER:
+      case SNMP_ASN1_TYPE_GAUGE:
+      case SNMP_ASN1_TYPE_TIMETICKS:
+        if (varbind->value_len != sizeof (u32_t)) {
+          return ERR_VAL;
+        }
+        snmp_asn1_enc_u32t_cnt(*((u32_t *) varbind->value), &len->value_value_len);
+        break;
+      case SNMP_ASN1_TYPE_OCTET_STRING:
+      case SNMP_ASN1_TYPE_IPADDR:
+      case SNMP_ASN1_TYPE_OPAQUE:
+        len->value_value_len = varbind->value_len;
+        break;
+      case SNMP_ASN1_TYPE_NULL:
+        if (varbind->value_len != 0) {
+          return ERR_VAL;
+        }
+        len->value_value_len = 0;
+        break;
+      case SNMP_ASN1_TYPE_OBJECT_ID:
+        if ((varbind->value_len & 0x03) != 0) {
+          return ERR_VAL;
+        }
+        snmp_asn1_enc_oid_cnt((u32_t *) varbind->value, varbind->value_len >> 2, &len->value_value_len);
+        break;
+#if LWIP_HAVE_INT64
+      case SNMP_ASN1_TYPE_COUNTER64:
+        if (varbind->value_len != sizeof(u64_t)) {
+          return ERR_VAL;
+        }
+        snmp_asn1_enc_u64t_cnt(*(u64_t *)varbind->value, &len->value_value_len);
+        break;
+#endif
+      default:
+        /* unsupported type */
+        return ERR_VAL;
+    }
+  }
+  snmp_asn1_enc_length_cnt(len->value_value_len, &len->value_len_len);
+
+  len->vb_value_len = 1 + len->oid_len_len + len->oid_value_len + 1 + len->value_len_len + len->value_value_len;
+  snmp_asn1_enc_length_cnt(len->vb_value_len, &len->vb_len_len);
+
+  return ERR_OK;
+}
+
+#define OVB_BUILD_EXEC(code) BUILD_EXEC(code, ERR_ARG)
+
+err_t
+snmp_append_outbound_varbind(struct snmp_pbuf_stream *pbuf_stream, struct snmp_varbind *varbind)
+{
+  struct snmp_asn1_tlv tlv;
+  struct snmp_varbind_len len;
+  err_t err;
+
+  err = snmp_varbind_length(varbind, &len);
+
+  if (err != ERR_OK) {
+    return err;
+  }
+
+  /* check length already before adding first data because in case of GetBulk,
+   *  data added so far is returned and therefore no partial data shall be added
+   */
+  if ((1 + len.vb_len_len + len.vb_value_len) > pbuf_stream->length) {
+    return ERR_BUF;
+  }
+
+  /* 'VarBind' sequence */
+  SNMP_ASN1_SET_TLV_PARAMS(tlv, SNMP_ASN1_TYPE_SEQUENCE, len.vb_len_len, len.vb_value_len);
+  OVB_BUILD_EXEC(snmp_ans1_enc_tlv(pbuf_stream, &tlv));
+
+  /* VarBind OID */
+  SNMP_ASN1_SET_TLV_PARAMS(tlv, SNMP_ASN1_TYPE_OBJECT_ID, len.oid_len_len, len.oid_value_len);
+  OVB_BUILD_EXEC(snmp_ans1_enc_tlv(pbuf_stream, &tlv));
+  OVB_BUILD_EXEC(snmp_asn1_enc_oid(pbuf_stream, varbind->oid.id, varbind->oid.len));
+
+  /* VarBind value */
+  SNMP_ASN1_SET_TLV_PARAMS(tlv, varbind->type, len.value_len_len, len.value_value_len);
+  OVB_BUILD_EXEC(snmp_ans1_enc_tlv(pbuf_stream, &tlv));
+
+  if (len.value_value_len > 0) {
+    if (varbind->value_len & SNMP_GET_VALUE_RAW_DATA) {
+      OVB_BUILD_EXEC(snmp_asn1_enc_raw(pbuf_stream, (u8_t *) varbind->value, len.value_value_len));
+    } else {
+      switch (varbind->type) {
+        case SNMP_ASN1_TYPE_INTEGER:
+          OVB_BUILD_EXEC(snmp_asn1_enc_s32t(pbuf_stream, len.value_value_len, *((s32_t *) varbind->value)));
+          break;
+        case SNMP_ASN1_TYPE_COUNTER:
+        case SNMP_ASN1_TYPE_GAUGE:
+        case SNMP_ASN1_TYPE_TIMETICKS:
+          OVB_BUILD_EXEC(snmp_asn1_enc_u32t(pbuf_stream, len.value_value_len, *((u32_t *) varbind->value)));
+          break;
+        case SNMP_ASN1_TYPE_OCTET_STRING:
+        case SNMP_ASN1_TYPE_IPADDR:
+        case SNMP_ASN1_TYPE_OPAQUE:
+          OVB_BUILD_EXEC(snmp_asn1_enc_raw(pbuf_stream, (u8_t *) varbind->value, len.value_value_len));
+          len.value_value_len = varbind->value_len;
+          break;
+        case SNMP_ASN1_TYPE_OBJECT_ID:
+          OVB_BUILD_EXEC(snmp_asn1_enc_oid(pbuf_stream, (u32_t *) varbind->value, varbind->value_len / sizeof (u32_t)));
+          break;
+#if LWIP_HAVE_INT64
+        case SNMP_ASN1_TYPE_COUNTER64:
+          OVB_BUILD_EXEC(snmp_asn1_enc_u64t(pbuf_stream, len.value_value_len, *(u64_t *) varbind->value));
+          break;
+#endif
+        default:
+          LWIP_ASSERT("Unknown variable type", 0);
+          break;
+      }
+    }
+  }
+
+  return ERR_OK;
+}
+
+static err_t
+snmp_complete_outbound_frame(struct snmp_request *request)
+{
+  struct snmp_asn1_tlv tlv;
+  u16_t frame_size;
+  u8_t outbound_padding = 0;
+
+  if (request->version == SNMP_VERSION_1) {
+    if (request->error_status != SNMP_ERR_NOERROR) {
+      /* map v2c error codes to v1 compliant error code (according to RFC 2089) */
+      switch (request->error_status) {
+        /* mapping of implementation specific "virtual" error codes
+         * (during processing of frame we already stored them in error_status field,
+         * so no need to check all varbinds here for those exceptions as suggested by RFC) */
+        case SNMP_ERR_NOSUCHINSTANCE:
+        case SNMP_ERR_NOSUCHOBJECT:
+        case SNMP_ERR_ENDOFMIBVIEW:
+          request->error_status = SNMP_ERR_NOSUCHNAME;
+          break;
+        /* mapping according to RFC */
+        case SNMP_ERR_WRONGVALUE:
+        case SNMP_ERR_WRONGENCODING:
+        case SNMP_ERR_WRONGTYPE:
+        case SNMP_ERR_WRONGLENGTH:
+        case SNMP_ERR_INCONSISTENTVALUE:
+          request->error_status = SNMP_ERR_BADVALUE;
+          break;
+        case SNMP_ERR_NOACCESS:
+        case SNMP_ERR_NOTWRITABLE:
+        case SNMP_ERR_NOCREATION:
+        case SNMP_ERR_INCONSISTENTNAME:
+        case SNMP_ERR_AUTHORIZATIONERROR:
+          request->error_status = SNMP_ERR_NOSUCHNAME;
+          break;
+        case SNMP_ERR_RESOURCEUNAVAILABLE:
+        case SNMP_ERR_COMMITFAILED:
+        case SNMP_ERR_UNDOFAILED:
+        default:
+          request->error_status = SNMP_ERR_GENERROR;
+          break;
+      }
+    }
+  } else {
+    if (request->request_type == SNMP_ASN1_CONTEXT_PDU_SET_REQ) {
+      /* map error codes to according to RFC 1905 (4.2.5.  The SetRequest-PDU) return 'NotWritable' for unknown OIDs) */
+      switch (request->error_status) {
+        case SNMP_ERR_NOSUCHINSTANCE:
+        case SNMP_ERR_NOSUCHOBJECT:
+        case SNMP_ERR_ENDOFMIBVIEW:
+          request->error_status = SNMP_ERR_NOTWRITABLE;
+          break;
+        default:
+          break;
+      }
+    }
+
+    if (request->error_status >= SNMP_VARBIND_EXCEPTION_OFFSET) {
+      /* should never occur because v2 frames store exceptions directly inside varbinds and not as frame error_status */
+      LWIP_DEBUGF(SNMP_DEBUG, ("snmp_complete_outbound_frame() > Found v2 request with varbind exception code stored as error status!\n"));
+      return ERR_ARG;
+    }
+  }
+
+  if ((request->error_status != SNMP_ERR_NOERROR) || (request->request_type == SNMP_ASN1_CONTEXT_PDU_SET_REQ)) {
+    /* all inbound vars are returned in response without any modification for error responses and successful set requests*/
+    struct snmp_pbuf_stream inbound_stream;
+    OF_BUILD_EXEC( snmp_pbuf_stream_init(&inbound_stream, request->inbound_pbuf, request->inbound_varbind_offset, request->inbound_varbind_len) );
+    OF_BUILD_EXEC( snmp_pbuf_stream_init(&(request->outbound_pbuf_stream), request->outbound_pbuf, request->outbound_varbind_offset, request->outbound_pbuf->tot_len - request->outbound_varbind_offset) );
+    OF_BUILD_EXEC( snmp_pbuf_stream_writeto(&inbound_stream, &(request->outbound_pbuf_stream), 0) );
+  }
+
+  frame_size = request->outbound_pbuf_stream.offset;
+
+#if LWIP_SNMP_V3 && LWIP_SNMP_V3_CRYPTO
+  /* Calculate padding for encryption */
+  if (request->version == SNMP_VERSION_3 && (request->msg_flags & SNMP_V3_PRIV_FLAG)) {
+    u8_t i;
+    outbound_padding = (8 - (u8_t)((frame_size - request->outbound_scoped_pdu_seq_offset) & 0x07)) & 0x07;
+    for (i = 0; i < outbound_padding; i++) {
+      OF_BUILD_EXEC( snmp_pbuf_stream_write(&request->outbound_pbuf_stream, 0) );
+    }
+  }
+#endif
+
+  /* complete missing length in 'Message' sequence ; 'Message' tlv is located at the beginning (offset 0) */
+  SNMP_ASN1_SET_TLV_PARAMS(tlv, SNMP_ASN1_TYPE_SEQUENCE, 3, frame_size + outbound_padding - 1 - 3); /* - type - length_len(fixed, see snmp_prepare_outbound_frame()) */
+  OF_BUILD_EXEC( snmp_pbuf_stream_init(&(request->outbound_pbuf_stream), request->outbound_pbuf, 0, request->outbound_pbuf->tot_len) );
+  OF_BUILD_EXEC( snmp_ans1_enc_tlv(&(request->outbound_pbuf_stream), &tlv) );
+
+#if LWIP_SNMP_V3
+  if (request->version == SNMP_VERSION_3) {
+    /* complete missing length in 'globalData' sequence */
+    /* - type - length_len(fixed, see snmp_prepare_outbound_frame()) */
+    SNMP_ASN1_SET_TLV_PARAMS(tlv, SNMP_ASN1_TYPE_SEQUENCE, 1, request->outbound_msg_global_data_end
+                             - request->outbound_msg_global_data_offset - 1 - 1);
+    OF_BUILD_EXEC(snmp_pbuf_stream_seek_abs(&(request->outbound_pbuf_stream), request->outbound_msg_global_data_offset));
+    OF_BUILD_EXEC(snmp_ans1_enc_tlv(&(request->outbound_pbuf_stream), &tlv));
+
+    /* complete missing length in 'msgSecurityParameters' sequence */
+    SNMP_ASN1_SET_TLV_PARAMS(tlv, SNMP_ASN1_TYPE_OCTET_STRING, 1, request->outbound_msg_security_parameters_end
+                             - request->outbound_msg_security_parameters_str_offset - 1 - 1);
+    OF_BUILD_EXEC(snmp_pbuf_stream_seek_abs(&(request->outbound_pbuf_stream), request->outbound_msg_security_parameters_str_offset));
+    OF_BUILD_EXEC(snmp_ans1_enc_tlv(&(request->outbound_pbuf_stream), &tlv));
+
+    SNMP_ASN1_SET_TLV_PARAMS(tlv, SNMP_ASN1_TYPE_SEQUENCE, 1, request->outbound_msg_security_parameters_end
+                             - request->outbound_msg_security_parameters_seq_offset - 1 - 1);
+    OF_BUILD_EXEC(snmp_pbuf_stream_seek_abs(&(request->outbound_pbuf_stream), request->outbound_msg_security_parameters_seq_offset));
+    OF_BUILD_EXEC(snmp_ans1_enc_tlv(&(request->outbound_pbuf_stream), &tlv));
+
+    /* complete missing length in scoped PDU sequence */
+    SNMP_ASN1_SET_TLV_PARAMS(tlv, SNMP_ASN1_TYPE_SEQUENCE, 3, frame_size - request->outbound_scoped_pdu_seq_offset - 1 - 3);
+    OF_BUILD_EXEC(snmp_pbuf_stream_seek_abs(&(request->outbound_pbuf_stream), request->outbound_scoped_pdu_seq_offset));
+    OF_BUILD_EXEC(snmp_ans1_enc_tlv(&(request->outbound_pbuf_stream), &tlv));
+  }
+#endif
+
+  /* complete missing length in 'PDU' sequence */
+  SNMP_ASN1_SET_TLV_PARAMS(tlv, request->request_out_type, 3,
+                           frame_size - request->outbound_pdu_offset - 1 - 3); /* - type - length_len(fixed, see snmp_prepare_outbound_frame()) */
+  OF_BUILD_EXEC( snmp_pbuf_stream_seek_abs(&(request->outbound_pbuf_stream), request->outbound_pdu_offset) );
+  OF_BUILD_EXEC( snmp_ans1_enc_tlv(&(request->outbound_pbuf_stream), &tlv) );
+
+  /* process and encode final error status */
+  if (request->error_status != 0) {
+    u16_t len;
+    snmp_asn1_enc_s32t_cnt(request->error_status, &len);
+    if (len != 1) {
+      /* error, we only reserved one byte for it */
+      return ERR_ARG;
+    }
+    OF_BUILD_EXEC( snmp_pbuf_stream_seek_abs(&(request->outbound_pbuf_stream), request->outbound_error_status_offset) );
+    OF_BUILD_EXEC( snmp_asn1_enc_s32t(&(request->outbound_pbuf_stream), len, request->error_status) );
+
+    /* for compatibility to v1, log statistics; in v2 (RFC 1907) these statistics are obsoleted */
+    switch (request->error_status) {
+      case SNMP_ERR_TOOBIG:
+        snmp_stats.outtoobigs++;
+        break;
+      case SNMP_ERR_NOSUCHNAME:
+        snmp_stats.outnosuchnames++;
+        break;
+      case SNMP_ERR_BADVALUE:
+        snmp_stats.outbadvalues++;
+        break;
+      case SNMP_ERR_GENERROR:
+      default:
+        snmp_stats.outgenerrs++;
+        break;
+    }
+
+    if (request->error_status == SNMP_ERR_TOOBIG) {
+      request->error_index = 0; /* defined by RFC 1157 */
+    } else if (request->error_index == 0) {
+      /* set index to varbind where error occured (if not already set before, e.g. during GetBulk processing) */
+      request->error_index = request->inbound_varbind_enumerator.varbind_count;
+    }
+  } else {
+    if (request->request_type == SNMP_ASN1_CONTEXT_PDU_SET_REQ) {
+      snmp_stats.intotalsetvars += request->inbound_varbind_enumerator.varbind_count;
+    } else {
+      snmp_stats.intotalreqvars += request->inbound_varbind_enumerator.varbind_count;
+    }
+  }
+
+  /* encode final error index*/
+  if (request->error_index != 0) {
+    u16_t len;
+    snmp_asn1_enc_s32t_cnt(request->error_index, &len);
+    if (len != 1) {
+      /* error, we only reserved one byte for it */
+      return ERR_VAL;
+    }
+    OF_BUILD_EXEC( snmp_pbuf_stream_seek_abs(&(request->outbound_pbuf_stream), request->outbound_error_index_offset) );
+    OF_BUILD_EXEC( snmp_asn1_enc_s32t(&(request->outbound_pbuf_stream), len, request->error_index) );
+  }
+
+  /* complete missing length in 'VarBindList' sequence ; 'VarBindList' tlv is located directly before varbind offset */
+  SNMP_ASN1_SET_TLV_PARAMS(tlv, SNMP_ASN1_TYPE_SEQUENCE, 3, frame_size - request->outbound_varbind_offset);
+  OF_BUILD_EXEC( snmp_pbuf_stream_seek_abs(&(request->outbound_pbuf_stream), request->outbound_varbind_offset - 1 - 3) ); /* - type - length_len(fixed, see snmp_prepare_outbound_frame()) */
+  OF_BUILD_EXEC( snmp_ans1_enc_tlv(&(request->outbound_pbuf_stream), &tlv) );
+
+  /* Authenticate response */
+#if LWIP_SNMP_V3 && LWIP_SNMP_V3_CRYPTO
+  /* Encrypt response */
+  if (request->version == SNMP_VERSION_3 && (request->msg_flags & SNMP_V3_PRIV_FLAG)) {
+    u8_t key[20];
+    snmpv3_priv_algo_t algo;
+
+    /* complete missing length in PDU sequence */
+    OF_BUILD_EXEC(snmp_pbuf_stream_init(&request->outbound_pbuf_stream, request->outbound_pbuf, 0, request->outbound_pbuf->tot_len));
+    OF_BUILD_EXEC(snmp_pbuf_stream_seek_abs(&(request->outbound_pbuf_stream), request->outbound_scoped_pdu_string_offset));
+    SNMP_ASN1_SET_TLV_PARAMS(tlv, SNMP_ASN1_TYPE_OCTET_STRING, 3, frame_size + outbound_padding
+                             - request->outbound_scoped_pdu_string_offset - 1 - 3);
+    OF_BUILD_EXEC(snmp_ans1_enc_tlv(&(request->outbound_pbuf_stream), &tlv));
+
+    OF_BUILD_EXEC(snmpv3_get_user((char *)request->msg_user_name, NULL, NULL, &algo, key));
+
+    OF_BUILD_EXEC(snmpv3_crypt(&request->outbound_pbuf_stream, tlv.value_len, key,
+                               request->msg_privacy_parameters, request->msg_authoritative_engine_boots,
+                               request->msg_authoritative_engine_time, algo, SNMP_V3_PRIV_MODE_ENCRYPT));
+  }
+
+  if (request->version == SNMP_VERSION_3 && (request->msg_flags & SNMP_V3_AUTH_FLAG)) {
+    u8_t key[20];
+    snmpv3_auth_algo_t algo;
+    u8_t hmac[20];
+
+    OF_BUILD_EXEC(snmpv3_get_user((char *)request->msg_user_name, &algo, key, NULL, NULL));
+    OF_BUILD_EXEC(snmp_pbuf_stream_init(&(request->outbound_pbuf_stream),
+                                        request->outbound_pbuf, 0, request->outbound_pbuf->tot_len));
+    OF_BUILD_EXEC(snmpv3_auth(&request->outbound_pbuf_stream, frame_size + outbound_padding, key, algo, hmac));
+
+    MEMCPY(request->msg_authentication_parameters, hmac, SNMP_V3_MAX_AUTH_PARAM_LENGTH);
+    OF_BUILD_EXEC(snmp_pbuf_stream_init(&request->outbound_pbuf_stream,
+                                        request->outbound_pbuf, 0, request->outbound_pbuf->tot_len));
+    OF_BUILD_EXEC(snmp_pbuf_stream_seek_abs(&request->outbound_pbuf_stream,
+                                            request->outbound_msg_authentication_parameters_offset));
+
+    SNMP_ASN1_SET_TLV_PARAMS(tlv, SNMP_ASN1_TYPE_OCTET_STRING, 1, SNMP_V3_MAX_AUTH_PARAM_LENGTH);
+    OF_BUILD_EXEC(snmp_ans1_enc_tlv(&request->outbound_pbuf_stream, &tlv));
+    OF_BUILD_EXEC(snmp_asn1_enc_raw(&request->outbound_pbuf_stream,
+                                    request->msg_authentication_parameters, SNMP_V3_MAX_AUTH_PARAM_LENGTH));
+  }
+#endif
+
+  pbuf_realloc(request->outbound_pbuf, frame_size + outbound_padding);
+
+  snmp_stats.outgetresponses++;
+  snmp_stats.outpkts++;
+
+  return ERR_OK;
+}
+
+static void
+snmp_execute_write_callbacks(struct snmp_request *request)
+{
+  struct snmp_varbind_enumerator inbound_varbind_enumerator;
+  struct snmp_varbind vb;
+
+  snmp_vb_enumerator_init(&inbound_varbind_enumerator, request->inbound_pbuf, request->inbound_varbind_offset, request->inbound_varbind_len);
+  vb.value = NULL; /* do NOT decode value (we enumerate outbound buffer here, so all varbinds have values assigned, which we don't need here) */
+
+  while (snmp_vb_enumerator_get_next(&inbound_varbind_enumerator, &vb) == SNMP_VB_ENUMERATOR_ERR_OK) {
+    snmp_write_callback(vb.oid.id, vb.oid.len, snmp_write_callback_arg);
+  }
+}
+
+
+/* ----------------------------------------------------------------------- */
+/* VarBind enumerator methods */
+/* ----------------------------------------------------------------------- */
+
+void
+snmp_vb_enumerator_init(struct snmp_varbind_enumerator *enumerator, struct pbuf *p, u16_t offset, u16_t length)
+{
+  snmp_pbuf_stream_init(&(enumerator->pbuf_stream), p, offset, length);
+  enumerator->varbind_count = 0;
+}
+
+#define VB_PARSE_EXEC(code)   PARSE_EXEC(code, SNMP_VB_ENUMERATOR_ERR_ASN1ERROR)
+#define VB_PARSE_ASSERT(code) PARSE_ASSERT(code, SNMP_VB_ENUMERATOR_ERR_ASN1ERROR)
+
+snmp_vb_enumerator_err_t
+snmp_vb_enumerator_get_next(struct snmp_varbind_enumerator *enumerator, struct snmp_varbind *varbind)
+{
+  struct snmp_asn1_tlv tlv;
+  u16_t  varbind_len;
+  err_t  err;
+
+  if (enumerator->pbuf_stream.length == 0) {
+    return SNMP_VB_ENUMERATOR_ERR_EOVB;
+  }
+  enumerator->varbind_count++;
+
+  /* decode varbind itself (parent container of a varbind) */
+  VB_PARSE_EXEC(snmp_asn1_dec_tlv(&(enumerator->pbuf_stream), &tlv));
+  VB_PARSE_ASSERT((tlv.type == SNMP_ASN1_TYPE_SEQUENCE) && (tlv.value_len <= enumerator->pbuf_stream.length));
+  varbind_len = tlv.value_len;
+
+  /* decode varbind name (object id) */
+  VB_PARSE_EXEC(snmp_asn1_dec_tlv(&(enumerator->pbuf_stream), &tlv));
+  VB_PARSE_ASSERT((tlv.type == SNMP_ASN1_TYPE_OBJECT_ID) && (SNMP_ASN1_TLV_LENGTH(tlv) < varbind_len) && (tlv.value_len < enumerator->pbuf_stream.length));
+
+  VB_PARSE_EXEC(snmp_asn1_dec_oid(&(enumerator->pbuf_stream), tlv.value_len, varbind->oid.id, &(varbind->oid.len), SNMP_MAX_OBJ_ID_LEN));
+  varbind_len -= SNMP_ASN1_TLV_LENGTH(tlv);
+
+  /* decode varbind value (object id) */
+  VB_PARSE_EXEC(snmp_asn1_dec_tlv(&(enumerator->pbuf_stream), &tlv));
+  VB_PARSE_ASSERT((SNMP_ASN1_TLV_LENGTH(tlv) == varbind_len) && (tlv.value_len <= enumerator->pbuf_stream.length));
+  varbind->type = tlv.type;
+
+  /* shall the value be decoded ? */
+  if (varbind->value != NULL) {
+    switch (varbind->type) {
+      case SNMP_ASN1_TYPE_INTEGER:
+        VB_PARSE_EXEC(snmp_asn1_dec_s32t(&(enumerator->pbuf_stream), tlv.value_len, (s32_t *)varbind->value));
+        varbind->value_len = sizeof(s32_t);
+        break;
+      case SNMP_ASN1_TYPE_COUNTER:
+      case SNMP_ASN1_TYPE_GAUGE:
+      case SNMP_ASN1_TYPE_TIMETICKS:
+        VB_PARSE_EXEC(snmp_asn1_dec_u32t(&(enumerator->pbuf_stream), tlv.value_len, (u32_t *)varbind->value));
+        varbind->value_len = sizeof(u32_t);
+        break;
+      case SNMP_ASN1_TYPE_OCTET_STRING:
+      case SNMP_ASN1_TYPE_OPAQUE:
+        err = snmp_asn1_dec_raw(&(enumerator->pbuf_stream), tlv.value_len, (u8_t *)varbind->value, &varbind->value_len, SNMP_MAX_VALUE_SIZE);
+        if (err == ERR_MEM) {
+          return SNMP_VB_ENUMERATOR_ERR_INVALIDLENGTH;
+        }
+        VB_PARSE_ASSERT(err == ERR_OK);
+        break;
+      case SNMP_ASN1_TYPE_NULL:
+        varbind->value_len = 0;
+        break;
+      case SNMP_ASN1_TYPE_OBJECT_ID:
+        /* misuse tlv.length_len as OID_length transporter */
+        err = snmp_asn1_dec_oid(&(enumerator->pbuf_stream), tlv.value_len, (u32_t *)varbind->value, &tlv.length_len, SNMP_MAX_OBJ_ID_LEN);
+        if (err == ERR_MEM) {
+          return SNMP_VB_ENUMERATOR_ERR_INVALIDLENGTH;
+        }
+        VB_PARSE_ASSERT(err == ERR_OK);
+        varbind->value_len = tlv.length_len * sizeof(u32_t);
+        break;
+      case SNMP_ASN1_TYPE_IPADDR:
+        if (tlv.value_len == 4) {
+          /* must be exactly 4 octets! */
+          VB_PARSE_EXEC(snmp_asn1_dec_raw(&(enumerator->pbuf_stream), tlv.value_len, (u8_t *)varbind->value, &varbind->value_len, SNMP_MAX_VALUE_SIZE));
+        } else {
+          VB_PARSE_ASSERT(0);
+        }
+        break;
+#if LWIP_HAVE_INT64
+      case SNMP_ASN1_TYPE_COUNTER64:
+        VB_PARSE_EXEC(snmp_asn1_dec_u64t(&(enumerator->pbuf_stream), tlv.value_len, (u64_t *)varbind->value));
+        varbind->value_len = sizeof(u64_t);
+        break;
+#endif
+      default:
+        VB_PARSE_ASSERT(0);
+        break;
+    }
+  } else {
+    snmp_pbuf_stream_seek(&(enumerator->pbuf_stream), tlv.value_len);
+    varbind->value_len = tlv.value_len;
+  }
+
+  return SNMP_VB_ENUMERATOR_ERR_OK;
+}
+
+#endif /* LWIP_SNMP */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/apps/snmp/snmp_msg.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/apps/snmp/snmp_msg.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/apps/snmp/snmp_msg.h	(revision 457)
@@ -0,0 +1,185 @@
+/**
+ * @file
+ * SNMP Agent message handling structures (internal API, do not use in client code).
+ */
+
+/*
+ * Copyright (c) 2006 Axon Digital Design B.V., The Netherlands.
+ * Copyright (c) 2016 Elias Oenal.
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * Author: Christiaan Simons <christiaan.simons@axon.tv>
+ *         Martin Hentschel <info@cl-soft.de>
+ *         Elias Oenal <lwip@eliasoenal.com>
+ */
+
+#ifndef LWIP_HDR_APPS_SNMP_MSG_H
+#define LWIP_HDR_APPS_SNMP_MSG_H
+
+#include "lwip/apps/snmp_opts.h"
+
+#if LWIP_SNMP
+
+#include "lwip/apps/snmp.h"
+#include "lwip/apps/snmp_core.h"
+#include "snmp_pbuf_stream.h"
+#include "lwip/ip_addr.h"
+#include "lwip/err.h"
+
+#if LWIP_SNMP_V3
+#include "snmpv3_priv.h"
+#endif
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* version defines used in PDU */
+#define SNMP_VERSION_1  0
+#define SNMP_VERSION_2c 1
+#define SNMP_VERSION_3  3
+
+struct snmp_varbind_enumerator {
+  struct snmp_pbuf_stream pbuf_stream;
+  u16_t varbind_count;
+};
+
+typedef enum {
+  SNMP_VB_ENUMERATOR_ERR_OK            = 0,
+  SNMP_VB_ENUMERATOR_ERR_EOVB          = 1,
+  SNMP_VB_ENUMERATOR_ERR_ASN1ERROR     = 2,
+  SNMP_VB_ENUMERATOR_ERR_INVALIDLENGTH = 3
+} snmp_vb_enumerator_err_t;
+
+void snmp_vb_enumerator_init(struct snmp_varbind_enumerator *enumerator, struct pbuf *p, u16_t offset, u16_t length);
+snmp_vb_enumerator_err_t snmp_vb_enumerator_get_next(struct snmp_varbind_enumerator *enumerator, struct snmp_varbind *varbind);
+
+struct snmp_request {
+  /* Communication handle */
+  void *handle;
+  /* source IP address */
+  const ip_addr_t *source_ip;
+  /* source UDP port */
+  u16_t source_port;
+  /* incoming snmp version */
+  u8_t version;
+  /* community name (zero terminated) */
+  u8_t community[SNMP_MAX_COMMUNITY_STR_LEN + 1];
+  /* community string length (exclusive zero term) */
+  u16_t community_strlen;
+  /* request type */
+  u8_t request_type;
+  /* request ID */
+  s32_t request_id;
+  /* error status */
+  s32_t error_status;
+  /* error index */
+  s32_t error_index;
+  /* non-repeaters (getBulkRequest (SNMPv2c)) */
+  s32_t non_repeaters;
+  /* max-repetitions (getBulkRequest (SNMPv2c)) */
+  s32_t max_repetitions;
+
+  /* Usually response-pdu (2). When snmpv3 errors are detected report-pdu(8) */
+  u8_t request_out_type;
+
+#if LWIP_SNMP_V3
+  s32_t msg_id;
+  s32_t msg_max_size;
+  u8_t  msg_flags;
+  s32_t msg_security_model;
+  u8_t  msg_authoritative_engine_id[SNMP_V3_MAX_ENGINE_ID_LENGTH];
+  u8_t  msg_authoritative_engine_id_len;
+  s32_t msg_authoritative_engine_boots;
+  s32_t msg_authoritative_engine_time;
+  u8_t  msg_user_name[SNMP_V3_MAX_USER_LENGTH];
+  u8_t  msg_user_name_len;
+  u8_t  msg_authentication_parameters[SNMP_V3_MAX_AUTH_PARAM_LENGTH];
+  u8_t  msg_authentication_parameters_len;
+  u8_t  msg_privacy_parameters[SNMP_V3_MAX_PRIV_PARAM_LENGTH];
+  u8_t  msg_privacy_parameters_len;
+  u8_t  context_engine_id[SNMP_V3_MAX_ENGINE_ID_LENGTH];
+  u8_t  context_engine_id_len;
+  u8_t  context_name[SNMP_V3_MAX_ENGINE_ID_LENGTH];
+  u8_t  context_name_len;
+#endif
+
+  struct pbuf *inbound_pbuf;
+  struct snmp_varbind_enumerator inbound_varbind_enumerator;
+  u16_t inbound_varbind_offset;
+  u16_t inbound_varbind_len;
+  u16_t inbound_padding_len;
+
+  struct pbuf *outbound_pbuf;
+  struct snmp_pbuf_stream outbound_pbuf_stream;
+  u16_t outbound_pdu_offset;
+  u16_t outbound_error_status_offset;
+  u16_t outbound_error_index_offset;
+  u16_t outbound_varbind_offset;
+#if LWIP_SNMP_V3
+  u16_t outbound_msg_global_data_offset;
+  u16_t outbound_msg_global_data_end;
+  u16_t outbound_msg_security_parameters_str_offset;
+  u16_t outbound_msg_security_parameters_seq_offset;
+  u16_t outbound_msg_security_parameters_end;
+  u16_t outbound_msg_authentication_parameters_offset;
+  u16_t outbound_scoped_pdu_seq_offset;
+  u16_t outbound_scoped_pdu_string_offset;
+#endif
+
+  u8_t value_buffer[SNMP_MAX_VALUE_SIZE];
+};
+
+/** A helper struct keeping length information about varbinds */
+struct snmp_varbind_len {
+  u8_t  vb_len_len;
+  u16_t vb_value_len;
+  u8_t  oid_len_len;
+  u16_t oid_value_len;
+  u8_t  value_len_len;
+  u16_t value_value_len;
+};
+
+/** Agent community string */
+extern const char *snmp_community;
+/** Agent community string for write access */
+extern const char *snmp_community_write;
+/** handle for sending traps */
+extern void *snmp_traps_handle;
+
+void snmp_receive(void *handle, struct pbuf *p, const ip_addr_t *source_ip, u16_t port);
+err_t snmp_sendto(void *handle, struct pbuf *p, const ip_addr_t *dst, u16_t port);
+u8_t snmp_get_local_ip_for_dst(void *handle, const ip_addr_t *dst, ip_addr_t *result);
+err_t snmp_varbind_length(struct snmp_varbind *varbind, struct snmp_varbind_len *len);
+err_t snmp_append_outbound_varbind(struct snmp_pbuf_stream *pbuf_stream, struct snmp_varbind *varbind);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LWIP_SNMP */
+
+#endif /* LWIP_HDR_APPS_SNMP_MSG_H */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/apps/snmp/snmp_netconn.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/apps/snmp/snmp_netconn.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/apps/snmp/snmp_netconn.c	(revision 457)
@@ -0,0 +1,123 @@
+/**
+ * @file
+ * SNMP netconn frontend.
+ */
+
+/*
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * Author: Dirk Ziegelmeier <dziegel@gmx.de>
+ */
+
+#include "lwip/apps/snmp_opts.h"
+
+#if LWIP_SNMP && SNMP_USE_NETCONN
+
+#include <string.h>
+#include "lwip/api.h"
+#include "lwip/ip.h"
+#include "lwip/udp.h"
+#include "snmp_msg.h"
+#include "lwip/sys.h"
+#include "lwip/prot/iana.h"
+
+/** SNMP netconn API worker thread */
+static void
+snmp_netconn_thread(void *arg)
+{
+  struct netconn *conn;
+  struct netbuf *buf;
+  err_t err;
+  LWIP_UNUSED_ARG(arg);
+
+  /* Bind to SNMP port with default IP address */
+#if LWIP_IPV6
+  conn = netconn_new(NETCONN_UDP_IPV6);
+  netconn_bind(conn, IP6_ADDR_ANY, LWIP_IANA_PORT_SNMP);
+#else /* LWIP_IPV6 */
+  conn = netconn_new(NETCONN_UDP);
+  netconn_bind(conn, IP4_ADDR_ANY, LWIP_IANA_PORT_SNMP);
+#endif /* LWIP_IPV6 */
+  LWIP_ERROR("snmp_netconn: invalid conn", (conn != NULL), return;);
+
+  snmp_traps_handle = conn;
+
+  do {
+    err = netconn_recv(conn, &buf);
+
+    if (err == ERR_OK) {
+      snmp_receive(conn, buf->p, &buf->addr, buf->port);
+    }
+
+    if (buf != NULL) {
+      netbuf_delete(buf);
+    }
+  } while (1);
+}
+
+err_t
+snmp_sendto(void *handle, struct pbuf *p, const ip_addr_t *dst, u16_t port)
+{
+  err_t result;
+  struct netbuf buf;
+
+  memset(&buf, 0, sizeof(buf));
+  buf.p = p;
+  result = netconn_sendto((struct netconn *)handle, &buf, dst, port);
+
+  return result;
+}
+
+u8_t
+snmp_get_local_ip_for_dst(void *handle, const ip_addr_t *dst, ip_addr_t *result)
+{
+  struct netconn *conn = (struct netconn *)handle;
+  struct netif *dst_if;
+  const ip_addr_t *dst_ip;
+
+  LWIP_UNUSED_ARG(conn); /* unused in case of IPV4 only configuration */
+
+  ip_route_get_local_ip(&conn->pcb.udp->local_ip, dst, dst_if, dst_ip);
+
+  if ((dst_if != NULL) && (dst_ip != NULL)) {
+    ip_addr_copy(*result, *dst_ip);
+    return 1;
+  } else {
+    return 0;
+  }
+}
+
+/**
+ * Starts SNMP Agent.
+ */
+void
+snmp_init(void)
+{
+  LWIP_ASSERT_CORE_LOCKED();
+  sys_thread_new("snmp_netconn", snmp_netconn_thread, NULL, SNMP_STACK_SIZE, SNMP_THREAD_PRIO);
+}
+
+#endif /* LWIP_SNMP && SNMP_USE_NETCONN */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/apps/snmp/snmp_pbuf_stream.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/apps/snmp/snmp_pbuf_stream.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/apps/snmp/snmp_pbuf_stream.c	(revision 457)
@@ -0,0 +1,156 @@
+/**
+ * @file
+ * SNMP pbuf stream wrapper implementation (internal API, do not use in client code).
+ */
+
+/*
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Martin Hentschel <info@cl-soft.de>
+ *
+ */
+
+#include "lwip/apps/snmp_opts.h"
+
+#if LWIP_SNMP /* don't build if not configured for use in lwipopts.h */
+
+#include "snmp_pbuf_stream.h"
+#include "lwip/def.h"
+#include <string.h>
+
+err_t
+snmp_pbuf_stream_init(struct snmp_pbuf_stream *pbuf_stream, struct pbuf *p, u16_t offset, u16_t length)
+{
+  pbuf_stream->offset = offset;
+  pbuf_stream->length = length;
+  pbuf_stream->pbuf   = p;
+
+  return ERR_OK;
+}
+
+err_t
+snmp_pbuf_stream_read(struct snmp_pbuf_stream *pbuf_stream, u8_t *data)
+{
+  if (pbuf_stream->length == 0) {
+    return ERR_BUF;
+  }
+
+  if (pbuf_copy_partial(pbuf_stream->pbuf, data, 1, pbuf_stream->offset) == 0) {
+    return ERR_BUF;
+  }
+
+  pbuf_stream->offset++;
+  pbuf_stream->length--;
+
+  return ERR_OK;
+}
+
+err_t
+snmp_pbuf_stream_write(struct snmp_pbuf_stream *pbuf_stream, u8_t data)
+{
+  return snmp_pbuf_stream_writebuf(pbuf_stream, &data, 1);
+}
+
+err_t
+snmp_pbuf_stream_writebuf(struct snmp_pbuf_stream *pbuf_stream, const void *buf, u16_t buf_len)
+{
+  if (pbuf_stream->length < buf_len) {
+    return ERR_BUF;
+  }
+
+  if (pbuf_take_at(pbuf_stream->pbuf, buf, buf_len, pbuf_stream->offset) != ERR_OK) {
+    return ERR_BUF;
+  }
+
+  pbuf_stream->offset += buf_len;
+  pbuf_stream->length -= buf_len;
+
+  return ERR_OK;
+}
+
+err_t
+snmp_pbuf_stream_writeto(struct snmp_pbuf_stream *pbuf_stream, struct snmp_pbuf_stream *target_pbuf_stream, u16_t len)
+{
+
+  if ((pbuf_stream == NULL) || (target_pbuf_stream == NULL)) {
+    return ERR_ARG;
+  }
+  if ((len > pbuf_stream->length) || (len > target_pbuf_stream->length)) {
+    return ERR_ARG;
+  }
+
+  if (len == 0) {
+    len = LWIP_MIN(pbuf_stream->length, target_pbuf_stream->length);
+  }
+
+  while (len > 0) {
+    u16_t chunk_len;
+    err_t err;
+    u16_t target_offset;
+    struct pbuf *pbuf = pbuf_skip(pbuf_stream->pbuf, pbuf_stream->offset, &target_offset);
+
+    if ((pbuf == NULL) || (pbuf->len == 0)) {
+      return ERR_BUF;
+    }
+
+    chunk_len = LWIP_MIN(len, pbuf->len);
+    err = snmp_pbuf_stream_writebuf(target_pbuf_stream, &((u8_t *)pbuf->payload)[target_offset], chunk_len);
+    if (err != ERR_OK) {
+      return err;
+    }
+
+    pbuf_stream->offset   += chunk_len;
+    pbuf_stream->length   -= chunk_len;
+    len -= chunk_len;
+  }
+
+  return ERR_OK;
+}
+
+err_t
+snmp_pbuf_stream_seek(struct snmp_pbuf_stream *pbuf_stream, s32_t offset)
+{
+  if ((offset < 0) || (offset > pbuf_stream->length)) {
+    /* we cannot seek backwards or forward behind stream end */
+    return ERR_ARG;
+  }
+
+  pbuf_stream->offset += (u16_t)offset;
+  pbuf_stream->length -= (u16_t)offset;
+
+  return ERR_OK;
+}
+
+err_t
+snmp_pbuf_stream_seek_abs(struct snmp_pbuf_stream *pbuf_stream, u32_t offset)
+{
+  s32_t rel_offset = offset - pbuf_stream->offset;
+  return snmp_pbuf_stream_seek(pbuf_stream, rel_offset);
+}
+
+#endif /* LWIP_SNMP */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/apps/snmp/snmp_pbuf_stream.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/apps/snmp/snmp_pbuf_stream.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/apps/snmp/snmp_pbuf_stream.h	(revision 457)
@@ -0,0 +1,72 @@
+/**
+ * @file
+ * SNMP pbuf stream wrapper (internal API, do not use in client code).
+ */
+
+/*
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Martin Hentschel <info@cl-soft.de>
+ *
+ */
+
+#ifndef LWIP_HDR_APPS_SNMP_PBUF_STREAM_H
+#define LWIP_HDR_APPS_SNMP_PBUF_STREAM_H
+
+#include "lwip/apps/snmp_opts.h"
+
+#if LWIP_SNMP
+
+#include "lwip/err.h"
+#include "lwip/pbuf.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct snmp_pbuf_stream {
+  struct pbuf *pbuf;
+  u16_t offset;
+  u16_t length;
+};
+
+err_t snmp_pbuf_stream_init(struct snmp_pbuf_stream *pbuf_stream, struct pbuf *p, u16_t offset, u16_t length);
+err_t snmp_pbuf_stream_read(struct snmp_pbuf_stream *pbuf_stream, u8_t *data);
+err_t snmp_pbuf_stream_write(struct snmp_pbuf_stream *pbuf_stream, u8_t data);
+err_t snmp_pbuf_stream_writebuf(struct snmp_pbuf_stream *pbuf_stream, const void *buf, u16_t buf_len);
+err_t snmp_pbuf_stream_writeto(struct snmp_pbuf_stream *pbuf_stream, struct snmp_pbuf_stream *target_pbuf_stream, u16_t len);
+err_t snmp_pbuf_stream_seek(struct snmp_pbuf_stream *pbuf_stream, s32_t offset);
+err_t snmp_pbuf_stream_seek_abs(struct snmp_pbuf_stream *pbuf_stream, u32_t offset);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LWIP_SNMP */
+
+#endif /* LWIP_HDR_APPS_SNMP_PBUF_STREAM_H */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/apps/snmp/snmp_raw.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/apps/snmp/snmp_raw.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/apps/snmp/snmp_raw.c	(revision 457)
@@ -0,0 +1,103 @@
+/**
+ * @file
+ * SNMP RAW API frontend.
+ */
+
+/*
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * Author: Dirk Ziegelmeier <dziegel@gmx.de>
+ */
+
+#include "lwip/apps/snmp_opts.h"
+#include "lwip/ip_addr.h"
+
+#if LWIP_SNMP && SNMP_USE_RAW
+
+#include "lwip/udp.h"
+#include "lwip/ip.h"
+#include "lwip/prot/iana.h"
+#include "snmp_msg.h"
+
+/* lwIP UDP receive callback function */
+static void
+snmp_recv(void *arg, struct udp_pcb *pcb, struct pbuf *p, const ip_addr_t *addr, u16_t port)
+{
+  LWIP_UNUSED_ARG(arg);
+
+  snmp_receive(pcb, p, addr, port);
+
+  pbuf_free(p);
+}
+
+err_t
+snmp_sendto(void *handle, struct pbuf *p, const ip_addr_t *dst, u16_t port)
+{
+  return udp_sendto((struct udp_pcb *)handle, p, dst, port);
+}
+
+u8_t
+snmp_get_local_ip_for_dst(void *handle, const ip_addr_t *dst, ip_addr_t *result)
+{
+  struct udp_pcb *udp_pcb = (struct udp_pcb *)handle;
+  struct netif *dst_if;
+  const ip_addr_t *dst_ip;
+
+  LWIP_UNUSED_ARG(udp_pcb); /* unused in case of IPV4 only configuration */
+
+  ip_route_get_local_ip(&udp_pcb->local_ip, dst, dst_if, dst_ip);
+
+  if ((dst_if != NULL) && (dst_ip != NULL)) {
+    ip_addr_copy(*result, *dst_ip);
+    return 1;
+  } else {
+    return 0;
+  }
+}
+
+/**
+ * @ingroup snmp_core
+ * Starts SNMP Agent.
+ * Allocates UDP pcb and binds it to IP_ANY_TYPE port 161.
+ */
+void
+snmp_init(void)
+{
+  err_t err;
+
+  struct udp_pcb *snmp_pcb = udp_new_ip_type(IPADDR_TYPE_ANY);
+  LWIP_ERROR("snmp_raw: no PCB", (snmp_pcb != NULL), return;);
+
+  LWIP_ASSERT_CORE_LOCKED();
+
+  snmp_traps_handle = snmp_pcb;
+
+  udp_recv(snmp_pcb, snmp_recv, NULL);
+  err = udp_bind(snmp_pcb, IP_ANY_TYPE, LWIP_IANA_PORT_SNMP);
+  LWIP_ERROR("snmp_raw: Unable to bind PCB", (err == ERR_OK), return;);
+}
+
+#endif /* LWIP_SNMP && SNMP_USE_RAW */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/apps/snmp/snmp_scalar.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/apps/snmp/snmp_scalar.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/apps/snmp/snmp_scalar.c	(revision 457)
@@ -0,0 +1,232 @@
+/**
+ * @file
+ * SNMP scalar node support implementation.
+ */
+
+/*
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Martin Hentschel <info@cl-soft.de>
+ *
+ */
+
+#include "lwip/apps/snmp_opts.h"
+
+#if LWIP_SNMP /* don't build if not configured for use in lwipopts.h */
+
+#include "lwip/apps/snmp_scalar.h"
+#include "lwip/apps/snmp_core.h"
+
+static s16_t snmp_scalar_array_get_value(struct snmp_node_instance *instance, void *value);
+static snmp_err_t  snmp_scalar_array_set_test(struct snmp_node_instance *instance, u16_t value_len, void *value);
+static snmp_err_t  snmp_scalar_array_set_value(struct snmp_node_instance *instance, u16_t value_len, void *value);
+
+snmp_err_t
+snmp_scalar_get_instance(const u32_t *root_oid, u8_t root_oid_len, struct snmp_node_instance *instance)
+{
+  const struct snmp_scalar_node *scalar_node = (const struct snmp_scalar_node *)(const void *)instance->node;
+
+  LWIP_UNUSED_ARG(root_oid);
+  LWIP_UNUSED_ARG(root_oid_len);
+
+  /* scalar only has one dedicated instance: .0 */
+  if ((instance->instance_oid.len != 1) || (instance->instance_oid.id[0] != 0)) {
+    return SNMP_ERR_NOSUCHINSTANCE;
+  }
+
+  instance->access    = scalar_node->access;
+  instance->asn1_type = scalar_node->asn1_type;
+  instance->get_value = scalar_node->get_value;
+  instance->set_test  = scalar_node->set_test;
+  instance->set_value = scalar_node->set_value;
+  return SNMP_ERR_NOERROR;
+}
+
+snmp_err_t
+snmp_scalar_get_next_instance(const u32_t *root_oid, u8_t root_oid_len, struct snmp_node_instance *instance)
+{
+  /* because our only instance is .0 we can only return a next instance if no instance oid is passed */
+  if (instance->instance_oid.len == 0) {
+    instance->instance_oid.len   = 1;
+    instance->instance_oid.id[0] = 0;
+
+    return snmp_scalar_get_instance(root_oid, root_oid_len, instance);
+  }
+
+  return SNMP_ERR_NOSUCHINSTANCE;
+}
+
+
+snmp_err_t
+snmp_scalar_array_get_instance(const u32_t *root_oid, u8_t root_oid_len, struct snmp_node_instance *instance)
+{
+  LWIP_UNUSED_ARG(root_oid);
+  LWIP_UNUSED_ARG(root_oid_len);
+
+  if ((instance->instance_oid.len == 2) && (instance->instance_oid.id[1] == 0)) {
+    const struct snmp_scalar_array_node *array_node = (const struct snmp_scalar_array_node *)(const void *)instance->node;
+    const struct snmp_scalar_array_node_def *array_node_def = array_node->array_nodes;
+    u32_t i = 0;
+
+    while (i < array_node->array_node_count) {
+      if (array_node_def->oid == instance->instance_oid.id[0]) {
+        break;
+      }
+
+      array_node_def++;
+      i++;
+    }
+
+    if (i < array_node->array_node_count) {
+      instance->access              = array_node_def->access;
+      instance->asn1_type           = array_node_def->asn1_type;
+      instance->get_value           = snmp_scalar_array_get_value;
+      instance->set_test            = snmp_scalar_array_set_test;
+      instance->set_value           = snmp_scalar_array_set_value;
+      instance->reference.const_ptr = array_node_def;
+
+      return SNMP_ERR_NOERROR;
+    }
+  }
+
+  return SNMP_ERR_NOSUCHINSTANCE;
+}
+
+snmp_err_t
+snmp_scalar_array_get_next_instance(const u32_t *root_oid, u8_t root_oid_len, struct snmp_node_instance *instance)
+{
+  const struct snmp_scalar_array_node *array_node = (const struct snmp_scalar_array_node *)(const void *)instance->node;
+  const struct snmp_scalar_array_node_def *array_node_def = array_node->array_nodes;
+  const struct snmp_scalar_array_node_def *result = NULL;
+
+  LWIP_UNUSED_ARG(root_oid);
+  LWIP_UNUSED_ARG(root_oid_len);
+
+  if ((instance->instance_oid.len == 0) && (array_node->array_node_count > 0)) {
+    /* return node with lowest OID */
+    u16_t i = 0;
+
+    result = array_node_def;
+    array_node_def++;
+
+    for (i = 1; i < array_node->array_node_count; i++) {
+      if (array_node_def->oid < result->oid) {
+        result = array_node_def;
+      }
+      array_node_def++;
+    }
+  } else if (instance->instance_oid.len >= 1) {
+    if (instance->instance_oid.len == 1) {
+      /* if we have the requested OID we return its instance, otherwise we search for the next available */
+      u16_t i = 0;
+      while (i < array_node->array_node_count) {
+        if (array_node_def->oid == instance->instance_oid.id[0]) {
+          result = array_node_def;
+          break;
+        }
+
+        array_node_def++;
+        i++;
+      }
+    }
+    if (result == NULL) {
+      u32_t oid_dist = 0xFFFFFFFFUL;
+      u16_t i        = 0;
+      array_node_def = array_node->array_nodes; /* may be already at the end when if case before was executed without result -> reinitialize to start */
+      while (i < array_node->array_node_count) {
+        if ((array_node_def->oid > instance->instance_oid.id[0]) &&
+            ((u32_t)(array_node_def->oid - instance->instance_oid.id[0]) < oid_dist)) {
+          result   = array_node_def;
+          oid_dist = array_node_def->oid - instance->instance_oid.id[0];
+        }
+
+        array_node_def++;
+        i++;
+      }
+    }
+  }
+
+  if (result == NULL) {
+    /* nothing to return */
+    return SNMP_ERR_NOSUCHINSTANCE;
+  }
+
+  instance->instance_oid.len   = 2;
+  instance->instance_oid.id[0] = result->oid;
+  instance->instance_oid.id[1] = 0;
+
+  instance->access              = result->access;
+  instance->asn1_type           = result->asn1_type;
+  instance->get_value           = snmp_scalar_array_get_value;
+  instance->set_test            = snmp_scalar_array_set_test;
+  instance->set_value           = snmp_scalar_array_set_value;
+  instance->reference.const_ptr = result;
+
+  return SNMP_ERR_NOERROR;
+}
+
+static s16_t
+snmp_scalar_array_get_value(struct snmp_node_instance *instance, void *value)
+{
+  s16_t result = -1;
+  const struct snmp_scalar_array_node *array_node = (const struct snmp_scalar_array_node *)(const void *)instance->node;
+  const struct snmp_scalar_array_node_def *array_node_def = (const struct snmp_scalar_array_node_def *)instance->reference.const_ptr;
+
+  if (array_node->get_value != NULL) {
+    result = array_node->get_value(array_node_def, value);
+  }
+  return result;
+}
+
+static snmp_err_t
+snmp_scalar_array_set_test(struct snmp_node_instance *instance, u16_t value_len, void *value)
+{
+  snmp_err_t result = SNMP_ERR_NOTWRITABLE;
+  const struct snmp_scalar_array_node *array_node = (const struct snmp_scalar_array_node *)(const void *)instance->node;
+  const struct snmp_scalar_array_node_def *array_node_def = (const struct snmp_scalar_array_node_def *)instance->reference.const_ptr;
+
+  if (array_node->set_test != NULL) {
+    result = array_node->set_test(array_node_def, value_len, value);
+  }
+  return result;
+}
+
+static snmp_err_t
+snmp_scalar_array_set_value(struct snmp_node_instance *instance, u16_t value_len, void *value)
+{
+  snmp_err_t result = SNMP_ERR_NOTWRITABLE;
+  const struct snmp_scalar_array_node *array_node = (const struct snmp_scalar_array_node *)(const void *)instance->node;
+  const struct snmp_scalar_array_node_def *array_node_def = (const struct snmp_scalar_array_node_def *)instance->reference.const_ptr;
+
+  if (array_node->set_value != NULL) {
+    result = array_node->set_value(array_node_def, value_len, value);
+  }
+  return result;
+}
+
+#endif /* LWIP_SNMP */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/apps/snmp/snmp_snmpv2_framework.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/apps/snmp/snmp_snmpv2_framework.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/apps/snmp/snmp_snmpv2_framework.c	(revision 457)
@@ -0,0 +1,90 @@
+/*
+Generated by LwipMibCompiler
+*/
+
+#include "lwip/apps/snmp_opts.h"
+
+#if LWIP_SNMP && LWIP_SNMP_V3 /* don't build if not configured for use in lwipopts.h */
+
+#include "lwip/apps/snmp_snmpv2_framework.h"
+#include "lwip/apps/snmp.h"
+#include "lwip/apps/snmp_core.h"
+#include "lwip/apps/snmp_scalar.h"
+#include "lwip/apps/snmp_table.h"
+#include "lwip/apps/snmpv3.h"
+#include "snmpv3_priv.h"
+
+#include "lwip/sys.h"
+
+#include <string.h>
+
+const struct snmp_obj_id usmNoAuthProtocol      = { 10, { 1, 3, 6, 1, 6, 3, 10, 1, 1, 1 } };
+const struct snmp_obj_id usmHMACMD5AuthProtocol = { 10, { 1, 3, 6, 1, 6, 3, 10, 1, 1, 2 } };
+const struct snmp_obj_id usmHMACSHAAuthProtocol = { 10, { 1, 3, 6, 1, 6, 3, 10, 1, 1, 3 } };
+/* .4 sha-224
+ * .5 sha-256
+ * .6 sha-384
+ * .7 sha-512
+ */
+
+const struct snmp_obj_id usmNoPrivProtocol  = { 10, { 1, 3, 6, 1, 6, 3, 10, 1, 2, 1 } };
+const struct snmp_obj_id usmDESPrivProtocol = { 10, { 1, 3, 6, 1, 6, 3, 10, 1, 2, 2 } };
+/* .3 3des-ede */
+const struct snmp_obj_id usmAESPrivProtocol = { 10, { 1, 3, 6, 1, 6, 3, 10, 1, 2, 4 } };
+/* .5 unknown
+ * .6 unknown
+ * .7 unknown
+ */
+
+/* TODO: where should this value come from? */
+#define SNMP_FRAMEWORKMIB_SNMPENGINEMAXMESSAGESIZE 1500
+
+/* --- snmpFrameworkMIBObjects 1.3.6.1.6.3.10.2 ----------------------------------------------------- */
+static s16_t snmpengine_scalars_get_value(const struct snmp_scalar_array_node_def *node, void *value)
+{
+  const char *engineid;
+  u8_t engineid_len;
+
+  switch (node->oid) {
+    case 1: /* snmpEngineID */
+      snmpv3_get_engine_id(&engineid, &engineid_len);
+      MEMCPY(value, engineid, engineid_len);
+      return engineid_len;
+    case 2: /* snmpEngineBoots */
+      *(s32_t *)value = snmpv3_get_engine_boots_internal();
+      return sizeof(s32_t);
+    case 3: /* snmpEngineTime */
+      *(s32_t *)value = snmpv3_get_engine_time_internal();
+      return sizeof(s32_t);
+    case 4: /* snmpEngineMaxMessageSize */
+      *(s32_t *)value = SNMP_FRAMEWORKMIB_SNMPENGINEMAXMESSAGESIZE;
+      return sizeof(s32_t);
+    default:
+      LWIP_DEBUGF(SNMP_MIB_DEBUG, ("snmpengine_scalars_get_value(): unknown id: %"S32_F"\n", node->oid));
+      return 0;
+  }
+}
+
+static const struct snmp_scalar_array_node_def snmpengine_scalars_nodes[] = {
+  {1, SNMP_ASN1_TYPE_OCTET_STRING, SNMP_NODE_INSTANCE_READ_ONLY}, /* snmpEngineID */
+  {2, SNMP_ASN1_TYPE_INTEGER,      SNMP_NODE_INSTANCE_READ_ONLY}, /* snmpEngineBoots */
+  {3, SNMP_ASN1_TYPE_INTEGER,      SNMP_NODE_INSTANCE_READ_ONLY}, /* snmpEngineTime */
+  {4, SNMP_ASN1_TYPE_INTEGER,      SNMP_NODE_INSTANCE_READ_ONLY}, /* snmpEngineMaxMessageSize */
+};
+static const struct snmp_scalar_array_node snmpengine_scalars = SNMP_SCALAR_CREATE_ARRAY_NODE(1, snmpengine_scalars_nodes, snmpengine_scalars_get_value, NULL, NULL);
+
+static const struct snmp_node *const snmpframeworkmibobjects_subnodes[] = {
+  &snmpengine_scalars.node.node
+};
+static const struct snmp_tree_node snmpframeworkmibobjects_treenode = SNMP_CREATE_TREE_NODE(2, snmpframeworkmibobjects_subnodes);
+
+/* --- snmpFrameworkMIB  ----------------------------------------------------- */
+static const struct snmp_node *const snmpframeworkmib_subnodes[] = {
+  &snmpframeworkmibobjects_treenode.node
+};
+static const struct snmp_tree_node snmpframeworkmib_root = SNMP_CREATE_TREE_NODE(10, snmpframeworkmib_subnodes);
+static const u32_t snmpframeworkmib_base_oid[] = {1, 3, 6, 1, 6, 3, 10};
+const struct snmp_mib snmpframeworkmib = {snmpframeworkmib_base_oid, LWIP_ARRAYSIZE(snmpframeworkmib_base_oid), &snmpframeworkmib_root.node};
+
+/* --- snmpFrameworkMIB  ----------------------------------------------------- */
+#endif /* LWIP_SNMP */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/apps/snmp/snmp_snmpv2_usm.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/apps/snmp/snmp_snmpv2_usm.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/apps/snmp/snmp_snmpv2_usm.c	(revision 457)
@@ -0,0 +1,410 @@
+/*
+Generated by LwipMibCompiler
+*/
+
+#include "lwip/apps/snmp_opts.h"
+#if LWIP_SNMP && LWIP_SNMP_V3
+
+#include "lwip/apps/snmp_snmpv2_usm.h"
+#include "lwip/apps/snmp.h"
+#include "lwip/apps/snmp_core.h"
+#include "lwip/apps/snmp_scalar.h"
+#include "lwip/apps/snmp_table.h"
+#include "lwip/apps/snmpv3.h"
+#include "snmpv3_priv.h"
+
+#include "lwip/apps/snmp_snmpv2_framework.h"
+
+#include <string.h>
+
+/* --- usmUser 1.3.6.1.6.3.15.1.2 ----------------------------------------------------- */
+
+static const struct snmp_oid_range usmUserTable_oid_ranges[] = {
+  { 0, 0xff }, { 0, 0xff }, { 0, 0xff }, { 0, 0xff },
+  { 0, 0xff }, { 0, 0xff }, { 0, 0xff }, { 0, 0xff },
+  { 0, 0xff }, { 0, 0xff }, { 0, 0xff }, { 0, 0xff },
+  { 0, 0xff }, { 0, 0xff }, { 0, 0xff }, { 0, 0xff },
+  { 0, 0xff }, { 0, 0xff }, { 0, 0xff }, { 0, 0xff },
+  { 0, 0xff }, { 0, 0xff }, { 0, 0xff }, { 0, 0xff },
+  { 0, 0xff }, { 0, 0xff }, { 0, 0xff }, { 0, 0xff },
+  { 0, 0xff }, { 0, 0xff }, { 0, 0xff }, { 0, 0xff }
+};
+
+static void snmp_engineid_to_oid(const char *engineid, u32_t *oid, u32_t len)
+{
+  u8_t i;
+
+  for (i = 0; i < len; i++) {
+    oid[i] = engineid[i];
+  }
+}
+
+static void snmp_oid_to_name(char *name, const u32_t *oid, size_t len)
+{
+  u8_t i;
+
+  for (i = 0; i < len; i++) {
+    name[i] = (char)oid[i];
+  }
+}
+
+static void snmp_name_to_oid(const char *name, u32_t *oid, size_t len)
+{
+  u8_t i;
+
+  for (i = 0; i < len; i++) {
+    oid[i] = name[i];
+  }
+}
+
+static const struct snmp_obj_id *snmp_auth_algo_to_oid(snmpv3_auth_algo_t algo)
+{
+  if (algo == SNMP_V3_AUTH_ALGO_MD5) {
+    return &usmHMACMD5AuthProtocol;
+  } else if (algo ==  SNMP_V3_AUTH_ALGO_SHA) {
+    return &usmHMACMD5AuthProtocol;
+  }
+
+  return &usmNoAuthProtocol;
+}
+
+static const struct snmp_obj_id *snmp_priv_algo_to_oid(snmpv3_priv_algo_t algo)
+{
+  if (algo == SNMP_V3_PRIV_ALGO_DES) {
+    return &usmDESPrivProtocol;
+  } else if (algo == SNMP_V3_PRIV_ALGO_AES) {
+    return &usmAESPrivProtocol;
+  }
+
+  return &usmNoPrivProtocol;
+}
+
+char username[32];
+
+static snmp_err_t usmusertable_get_instance(const u32_t *column, const u32_t *row_oid, u8_t row_oid_len, struct snmp_node_instance *cell_instance)
+{
+  const char *engineid;
+  u8_t eid_len;
+
+  u32_t engineid_oid[SNMP_V3_MAX_ENGINE_ID_LENGTH];
+
+  u8_t name_len;
+  u8_t engineid_len;
+
+  u8_t name_start;
+  u8_t engineid_start;
+
+  LWIP_UNUSED_ARG(column);
+
+  snmpv3_get_engine_id(&engineid, &eid_len);
+
+  engineid_len = (u8_t)row_oid[0];
+  engineid_start = 1;
+
+  if (engineid_len != eid_len) {
+    /* EngineID length does not match! */
+    return SNMP_ERR_NOSUCHINSTANCE;
+  }
+
+  if (engineid_len > row_oid_len) {
+    /* row OID doesn't contain enough data according to engineid_len.*/
+    return SNMP_ERR_NOSUCHINSTANCE;
+  }
+
+  /* check if incoming OID length and if values are in plausible range */
+  if (!snmp_oid_in_range(&row_oid[engineid_start], engineid_len, usmUserTable_oid_ranges, engineid_len)) {
+    return SNMP_ERR_NOSUCHINSTANCE;
+  }
+
+  snmp_engineid_to_oid(engineid, engineid_oid, engineid_len);
+
+  /* Verify EngineID */
+  if (snmp_oid_equal(&row_oid[engineid_start], engineid_len, engineid_oid, engineid_len)) {
+    return SNMP_ERR_NOSUCHINSTANCE;
+  }
+
+  name_len = (u8_t)row_oid[engineid_start + engineid_len];
+  name_start = engineid_start + engineid_len + 1;
+
+  if (name_len > SNMP_V3_MAX_USER_LENGTH) {
+    /* specified name is too long */
+    return SNMP_ERR_NOSUCHINSTANCE;
+  }
+
+  if (1 + engineid_len + 1 + name_len != row_oid_len) {
+    /* Length of EngineID and name does not match row oid length. (+2 for length fields)*/
+    return SNMP_ERR_NOSUCHINSTANCE;
+  }
+
+  /* check if incoming OID length and if values are in plausible range */
+  if (!snmp_oid_in_range(&row_oid[name_start], name_len, usmUserTable_oid_ranges, name_len)) {
+    return SNMP_ERR_NOSUCHINSTANCE;
+  }
+
+  /* Verify if user exists */
+  memset(username, 0, sizeof(username));
+  snmp_oid_to_name(username, &row_oid[name_start], name_len);
+  if (snmpv3_get_user(username, NULL, NULL, NULL, NULL) != ERR_OK) {
+    return SNMP_ERR_NOSUCHINSTANCE;
+  }
+
+  /* Save name in reference pointer to make it easier to handle later on */
+  cell_instance->reference.ptr = username;
+  cell_instance->reference_len = name_len;
+
+  /* user was found */
+  return SNMP_ERR_NOERROR;
+}
+
+/*
+ * valid oid options
+ * <oid>
+ * <oid>.<EngineID length>
+ * <oid>.<EngineID length>.<partial EngineID>
+ * <oid>.<EngineID length>.<EngineID>
+ * <oid>.<EngineID length>.<EngineID>.<UserName length>
+ * <oid>.<EngineID length>.<EngineID>.<UserName length>.<partial UserName>
+ * <oid>.<EngineID length>.<EngineID>.<UserName length>.<UserName>
+ *
+ */
+static snmp_err_t usmusertable_get_next_instance(const u32_t *column, struct snmp_obj_id *row_oid, struct snmp_node_instance *cell_instance)
+{
+  const char *engineid;
+  u8_t eid_len;
+
+  u32_t engineid_oid[SNMP_V3_MAX_ENGINE_ID_LENGTH];
+
+  u8_t name_len;
+  u8_t engineid_len;
+
+  u8_t name_start;
+  u8_t engineid_start = 1;
+  u8_t i;
+
+  struct snmp_next_oid_state state;
+
+  u32_t result_temp[LWIP_ARRAYSIZE(usmUserTable_oid_ranges)];
+
+  LWIP_UNUSED_ARG(column);
+
+  snmpv3_get_engine_id(&engineid, &eid_len);
+
+  /* If EngineID might be given */
+  if (row_oid->len > 0) {
+    engineid_len = (u8_t)row_oid->id[0];
+    engineid_start = 1;
+
+    if (engineid_len != eid_len) {
+      /* EngineID length does not match! */
+      return SNMP_ERR_NOSUCHINSTANCE;
+    }
+
+    if (engineid_len > row_oid->len) {
+      /* Verify partial EngineID */
+      snmp_engineid_to_oid(engineid, engineid_oid, row_oid->len - 1);
+      if (!snmp_oid_equal(&row_oid->id[engineid_start], row_oid->len - 1, engineid_oid, row_oid->len - 1)) {
+        return SNMP_ERR_NOSUCHINSTANCE;
+      }
+    } else {
+      /* Verify complete EngineID */
+      snmp_engineid_to_oid(engineid, engineid_oid, engineid_len);
+      if (!snmp_oid_equal(&row_oid->id[engineid_start], engineid_len, engineid_oid, engineid_len)) {
+        return SNMP_ERR_NOSUCHINSTANCE;
+      }
+    }
+
+    /* At this point, the given EngineID (partially) matches the local EngineID.*/
+
+    /* If name might also be given */
+    if (row_oid->len > engineid_start + engineid_len) {
+      name_len = (u8_t)row_oid->id[engineid_start + engineid_len];
+      name_start = engineid_start + engineid_len + 1;
+
+      if (name_len > SNMP_V3_MAX_USER_LENGTH) {
+        /* specified name is too long, max length is 32 according to mib file.*/
+        return SNMP_ERR_NOSUCHINSTANCE;
+      }
+
+      if (row_oid->len < engineid_len + name_len + 2) {
+        /* Partial name given according to oid.*/
+        u8_t tmplen = row_oid->len - engineid_len - 2;
+        if (!snmp_oid_in_range(&row_oid->id[name_start], tmplen, usmUserTable_oid_ranges, tmplen)) {
+          return SNMP_ERR_NOSUCHINSTANCE;
+        }
+      } else {
+        /* Full name given according to oid. Also test for too much data.*/
+        u8_t tmplen = row_oid->len - engineid_len - 2;
+        if (!snmp_oid_in_range(&row_oid->id[name_start], name_len, usmUserTable_oid_ranges, tmplen)) {
+          return SNMP_ERR_NOSUCHINSTANCE;
+        }
+      }
+
+      /* At this point the EngineID and (partial) UserName match the local EngineID and UserName.*/
+    }
+  }
+
+  /* init struct to search next oid */
+  snmp_next_oid_init(&state, row_oid->id, row_oid->len, result_temp, LWIP_ARRAYSIZE(usmUserTable_oid_ranges));
+
+  for (i = 0; i < snmpv3_get_amount_of_users(); i++) {
+    u32_t test_oid[LWIP_ARRAYSIZE(usmUserTable_oid_ranges)];
+
+    test_oid[0] = eid_len;
+    snmp_engineid_to_oid(engineid, &test_oid[1], eid_len);
+
+    snmpv3_get_username(username, i);
+
+    test_oid[1 + eid_len] = strlen(username);
+    snmp_name_to_oid(username, &test_oid[2 + eid_len], strlen(username));
+
+    /* check generated OID: is it a candidate for the next one? */
+    snmp_next_oid_check(&state, test_oid, (u8_t)(1 + eid_len + 1 + strlen(username)), LWIP_PTR_NUMERIC_CAST(void *, i));
+  }
+
+  /* did we find a next one? */
+  if (state.status == SNMP_NEXT_OID_STATUS_SUCCESS) {
+    snmp_oid_assign(row_oid, state.next_oid, state.next_oid_len);
+    /* store username for subsequent operations (get/test/set) */
+    memset(username, 0, sizeof(username));
+    snmpv3_get_username(username, LWIP_PTR_NUMERIC_CAST(u8_t, state.reference));
+    cell_instance->reference.ptr = username;
+    cell_instance->reference_len = strlen(username);
+    return SNMP_ERR_NOERROR;
+  }
+
+  /* not found */
+  return SNMP_ERR_NOSUCHINSTANCE;
+}
+
+static s16_t usmusertable_get_value(struct snmp_node_instance *cell_instance, void *value)
+{
+  snmpv3_user_storagetype_t storage_type;
+
+  switch (SNMP_TABLE_GET_COLUMN_FROM_OID(cell_instance->instance_oid.id)) {
+    case 3: /* usmUserSecurityName */
+      MEMCPY(value, cell_instance->reference.ptr, cell_instance->reference_len);
+      return (s16_t)cell_instance->reference_len;
+    case 4: /* usmUserCloneFrom */
+      MEMCPY(value, snmp_zero_dot_zero.id, snmp_zero_dot_zero.len * sizeof(u32_t));
+      return snmp_zero_dot_zero.len * sizeof(u32_t);
+    case 5: { /* usmUserAuthProtocol */
+      const struct snmp_obj_id *auth_algo;
+      snmpv3_auth_algo_t auth_algo_val;
+      snmpv3_get_user((const char *)cell_instance->reference.ptr, &auth_algo_val, NULL, NULL, NULL);
+      auth_algo = snmp_auth_algo_to_oid(auth_algo_val);
+      MEMCPY(value, auth_algo->id, auth_algo->len * sizeof(u32_t));
+      return auth_algo->len * sizeof(u32_t);
+    }
+    case 6: /* usmUserAuthKeyChange */
+      return 0;
+    case 7: /* usmUserOwnAuthKeyChange */
+      return 0;
+    case 8: { /* usmUserPrivProtocol */
+      const struct snmp_obj_id *priv_algo;
+      snmpv3_priv_algo_t priv_algo_val;
+      snmpv3_get_user((const char *)cell_instance->reference.ptr, NULL, NULL, &priv_algo_val, NULL);
+      priv_algo = snmp_priv_algo_to_oid(priv_algo_val);
+      MEMCPY(value, priv_algo->id, priv_algo->len * sizeof(u32_t));
+      return priv_algo->len * sizeof(u32_t);
+    }
+    case 9: /* usmUserPrivKeyChange */
+      return 0;
+    case 10: /* usmUserOwnPrivKeyChange */
+      return 0;
+    case 11: /* usmUserPublic */
+      /* TODO: Implement usmUserPublic */
+      return 0;
+    case 12: /* usmUserStorageType */
+      snmpv3_get_user_storagetype((const char *)cell_instance->reference.ptr, &storage_type);
+      *(s32_t *)value = storage_type;
+      return sizeof(s32_t);
+    case 13: /* usmUserStatus */
+      *(s32_t *)value = 1; /* active */
+      return sizeof(s32_t);
+    default:
+      LWIP_DEBUGF(SNMP_MIB_DEBUG, ("usmusertable_get_value(): unknown id: %"S32_F"\n", SNMP_TABLE_GET_COLUMN_FROM_OID(cell_instance->instance_oid.id)));
+      return 0;
+  }
+}
+
+/* --- usmMIBObjects 1.3.6.1.6.3.15.1 ----------------------------------------------------- */
+static s16_t usmstats_scalars_get_value(const struct snmp_scalar_array_node_def *node, void *value)
+{
+  u32_t *uint_ptr = (u32_t *)value;
+  switch (node->oid) {
+    case 1: /* usmStatsUnsupportedSecLevels */
+      *uint_ptr = snmp_stats.unsupportedseclevels;
+      break;
+    case 2: /* usmStatsNotInTimeWindows */
+      *uint_ptr = snmp_stats.notintimewindows;
+      break;
+    case 3: /* usmStatsUnknownUserNames */
+      *uint_ptr = snmp_stats.unknownusernames;
+      break;
+    case 4: /* usmStatsUnknownEngineIDs */
+      *uint_ptr = snmp_stats.unknownengineids;
+      break;
+    case 5: /* usmStatsWrongDigests */
+      *uint_ptr = snmp_stats.wrongdigests;
+      break;
+    case 6: /* usmStatsDecryptionErrors */
+      *uint_ptr = snmp_stats.decryptionerrors;
+      break;
+    default:
+      LWIP_DEBUGF(SNMP_MIB_DEBUG, ("usmstats_scalars_get_value(): unknown id: %"S32_F"\n", node->oid));
+      return 0;
+  }
+
+  return sizeof(*uint_ptr);
+}
+
+/* --- snmpUsmMIB  ----------------------------------------------------- */
+
+/* --- usmUser 1.3.6.1.6.3.15.1.2 ----------------------------------------------------- */
+
+static const struct snmp_table_col_def usmusertable_columns[] = {
+  {3,  SNMP_ASN1_TYPE_OCTET_STRING, SNMP_NODE_INSTANCE_READ_ONLY}, /* usmUserSecurityName */
+  {4,  SNMP_ASN1_TYPE_OBJECT_ID,    SNMP_NODE_INSTANCE_READ_ONLY}, /* usmUserCloneFrom */
+  {5,  SNMP_ASN1_TYPE_OBJECT_ID,    SNMP_NODE_INSTANCE_READ_ONLY}, /* usmUserAuthProtocol */
+  {6,  SNMP_ASN1_TYPE_OCTET_STRING, SNMP_NODE_INSTANCE_READ_ONLY}, /* usmUserAuthKeyChange */
+  {7,  SNMP_ASN1_TYPE_OCTET_STRING, SNMP_NODE_INSTANCE_READ_ONLY}, /* usmUserOwnAuthKeyChange */
+  {8,  SNMP_ASN1_TYPE_OBJECT_ID,    SNMP_NODE_INSTANCE_READ_ONLY}, /* usmUserPrivProtocol */
+  {9,  SNMP_ASN1_TYPE_OCTET_STRING, SNMP_NODE_INSTANCE_READ_ONLY}, /* usmUserPrivKeyChange */
+  {10, SNMP_ASN1_TYPE_OCTET_STRING, SNMP_NODE_INSTANCE_READ_ONLY}, /* usmUserOwnPrivKeyChange */
+  {11, SNMP_ASN1_TYPE_OCTET_STRING, SNMP_NODE_INSTANCE_READ_ONLY}, /* usmUserPublic */
+  {12, SNMP_ASN1_TYPE_INTEGER,      SNMP_NODE_INSTANCE_READ_ONLY}, /* usmUserStorageType */
+  {13, SNMP_ASN1_TYPE_INTEGER,      SNMP_NODE_INSTANCE_READ_ONLY}, /* usmUserStatus */
+};
+static const struct snmp_table_node usmusertable = SNMP_TABLE_CREATE(2, usmusertable_columns, usmusertable_get_instance, usmusertable_get_next_instance, usmusertable_get_value, NULL, NULL);
+
+static const struct snmp_node *const usmuser_subnodes[] = {
+  &usmusertable.node.node
+};
+static const struct snmp_tree_node usmuser_treenode = SNMP_CREATE_TREE_NODE(2, usmuser_subnodes);
+
+/* --- usmMIBObjects 1.3.6.1.6.3.15.1 ----------------------------------------------------- */
+static const struct snmp_scalar_array_node_def usmstats_scalars_nodes[] = {
+  {1, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY}, /* usmStatsUnsupportedSecLevels */
+  {2, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY}, /* usmStatsNotInTimeWindows */
+  {3, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY}, /* usmStatsUnknownUserNames */
+  {4, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY}, /* usmStatsUnknownEngineIDs */
+  {5, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY}, /* usmStatsWrongDigests */
+  {6, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY}, /* usmStatsDecryptionErrors */
+};
+static const struct snmp_scalar_array_node usmstats_scalars = SNMP_SCALAR_CREATE_ARRAY_NODE(1, usmstats_scalars_nodes, usmstats_scalars_get_value, NULL, NULL);
+
+static const struct snmp_node *const usmmibobjects_subnodes[] = {
+  &usmstats_scalars.node.node,
+  &usmuser_treenode.node
+};
+static const struct snmp_tree_node usmmibobjects_treenode = SNMP_CREATE_TREE_NODE(1, usmmibobjects_subnodes);
+
+/* --- snmpUsmMIB  ----------------------------------------------------- */
+static const struct snmp_node *const snmpusmmib_subnodes[] = {
+  &usmmibobjects_treenode.node
+};
+static const struct snmp_tree_node snmpusmmib_root = SNMP_CREATE_TREE_NODE(15, snmpusmmib_subnodes);
+static const u32_t snmpusmmib_base_oid[] = {1, 3, 6, 1, 6, 3, 15};
+const struct snmp_mib snmpusmmib = {snmpusmmib_base_oid, LWIP_ARRAYSIZE(snmpusmmib_base_oid), &snmpusmmib_root.node};
+
+#endif /* LWIP_SNMP */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/apps/snmp/snmp_table.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/apps/snmp/snmp_table.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/apps/snmp/snmp_table.c	(revision 457)
@@ -0,0 +1,342 @@
+/**
+ * @file
+ * SNMP table support implementation.
+ */
+
+/*
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Martin Hentschel <info@cl-soft.de>
+ *
+ */
+
+#include "lwip/apps/snmp_opts.h"
+
+#if LWIP_SNMP /* don't build if not configured for use in lwipopts.h */
+
+#include "lwip/apps/snmp_core.h"
+#include "lwip/apps/snmp_table.h"
+#include <string.h>
+
+snmp_err_t snmp_table_get_instance(const u32_t *root_oid, u8_t root_oid_len, struct snmp_node_instance *instance)
+{
+  snmp_err_t ret = SNMP_ERR_NOSUCHINSTANCE;
+  const struct snmp_table_node *table_node = (const struct snmp_table_node *)(const void *)instance->node;
+
+  LWIP_UNUSED_ARG(root_oid);
+  LWIP_UNUSED_ARG(root_oid_len);
+
+  /* check min. length (fixed row entry definition, column, row instance oid with at least one entry */
+  /* fixed row entry always has oid 1 */
+  if ((instance->instance_oid.len >= 3) && (instance->instance_oid.id[0] == 1)) {
+    /* search column */
+    const struct snmp_table_col_def *col_def = table_node->columns;
+    u16_t i = table_node->column_count;
+    while (i > 0) {
+      if (col_def->index == instance->instance_oid.id[1]) {
+        break;
+      }
+
+      col_def++;
+      i--;
+    }
+
+    if (i > 0) {
+      /* everything may be overwritten by get_cell_instance_method() in order to implement special handling for single columns/cells */
+      instance->asn1_type = col_def->asn1_type;
+      instance->access    = col_def->access;
+      instance->get_value = table_node->get_value;
+      instance->set_test  = table_node->set_test;
+      instance->set_value = table_node->set_value;
+
+      ret = table_node->get_cell_instance(
+              &(instance->instance_oid.id[1]),
+              &(instance->instance_oid.id[2]),
+              instance->instance_oid.len - 2,
+              instance);
+    }
+  }
+
+  return ret;
+}
+
+snmp_err_t snmp_table_get_next_instance(const u32_t *root_oid, u8_t root_oid_len, struct snmp_node_instance *instance)
+{
+  const struct snmp_table_node *table_node = (const struct snmp_table_node *)(const void *)instance->node;
+  const struct snmp_table_col_def *col_def;
+  struct snmp_obj_id row_oid;
+  u32_t column = 0;
+  snmp_err_t result;
+
+  LWIP_UNUSED_ARG(root_oid);
+  LWIP_UNUSED_ARG(root_oid_len);
+
+  /* check that first part of id is 0 or 1, referencing fixed row entry */
+  if ((instance->instance_oid.len > 0) && (instance->instance_oid.id[0] > 1)) {
+    return SNMP_ERR_NOSUCHINSTANCE;
+  }
+  if (instance->instance_oid.len > 1) {
+    column = instance->instance_oid.id[1];
+  }
+  if (instance->instance_oid.len > 2) {
+    snmp_oid_assign(&row_oid, &(instance->instance_oid.id[2]), instance->instance_oid.len - 2);
+  } else {
+    row_oid.len = 0;
+  }
+
+  instance->get_value    = table_node->get_value;
+  instance->set_test     = table_node->set_test;
+  instance->set_value    = table_node->set_value;
+
+  /* resolve column and value */
+  do {
+    u16_t i;
+    const struct snmp_table_col_def *next_col_def = NULL;
+    col_def = table_node->columns;
+
+    for (i = 0; i < table_node->column_count; i++) {
+      if (col_def->index == column) {
+        next_col_def = col_def;
+        break;
+      } else if ((col_def->index > column) && ((next_col_def == NULL) || (col_def->index < next_col_def->index))) {
+        next_col_def = col_def;
+      }
+      col_def++;
+    }
+
+    if (next_col_def == NULL) {
+      /* no further column found */
+      return SNMP_ERR_NOSUCHINSTANCE;
+    }
+
+    instance->asn1_type          = next_col_def->asn1_type;
+    instance->access             = next_col_def->access;
+
+    result = table_node->get_next_cell_instance(
+               &next_col_def->index,
+               &row_oid,
+               instance);
+
+    if (result == SNMP_ERR_NOERROR) {
+      col_def = next_col_def;
+      break;
+    }
+
+    row_oid.len = 0; /* reset row_oid because we switch to next column and start with the first entry there */
+    column = next_col_def->index + 1;
+  } while (1);
+
+  /* build resulting oid */
+  instance->instance_oid.len   = 2;
+  instance->instance_oid.id[0] = 1;
+  instance->instance_oid.id[1] = col_def->index;
+  snmp_oid_append(&instance->instance_oid, row_oid.id, row_oid.len);
+
+  return SNMP_ERR_NOERROR;
+}
+
+
+snmp_err_t snmp_table_simple_get_instance(const u32_t *root_oid, u8_t root_oid_len, struct snmp_node_instance *instance)
+{
+  snmp_err_t ret = SNMP_ERR_NOSUCHINSTANCE;
+  const struct snmp_table_simple_node *table_node = (const struct snmp_table_simple_node *)(const void *)instance->node;
+
+  LWIP_UNUSED_ARG(root_oid);
+  LWIP_UNUSED_ARG(root_oid_len);
+
+  /* check min. length (fixed row entry definition, column, row instance oid with at least one entry */
+  /* fixed row entry always has oid 1 */
+  if ((instance->instance_oid.len >= 3) && (instance->instance_oid.id[0] == 1)) {
+    ret = table_node->get_cell_value(
+            &(instance->instance_oid.id[1]),
+            &(instance->instance_oid.id[2]),
+            instance->instance_oid.len - 2,
+            &instance->reference,
+            &instance->reference_len);
+
+    if (ret == SNMP_ERR_NOERROR) {
+      /* search column */
+      const struct snmp_table_simple_col_def *col_def = table_node->columns;
+      u32_t i = table_node->column_count;
+      while (i > 0) {
+        if (col_def->index == instance->instance_oid.id[1]) {
+          break;
+        }
+
+        col_def++;
+        i--;
+      }
+
+      if (i > 0) {
+        instance->asn1_type = col_def->asn1_type;
+        instance->access    = SNMP_NODE_INSTANCE_READ_ONLY;
+        instance->set_test  = NULL;
+        instance->set_value = NULL;
+
+        switch (col_def->data_type) {
+          case SNMP_VARIANT_VALUE_TYPE_U32:
+            instance->get_value = snmp_table_extract_value_from_u32ref;
+            break;
+          case SNMP_VARIANT_VALUE_TYPE_S32:
+            instance->get_value = snmp_table_extract_value_from_s32ref;
+            break;
+          case SNMP_VARIANT_VALUE_TYPE_PTR: /* fall through */
+          case SNMP_VARIANT_VALUE_TYPE_CONST_PTR:
+            instance->get_value = snmp_table_extract_value_from_refconstptr;
+            break;
+          default:
+            LWIP_DEBUGF(SNMP_DEBUG, ("snmp_table_simple_get_instance(): unknown column data_type: %d\n", col_def->data_type));
+            return SNMP_ERR_GENERROR;
+        }
+
+        ret = SNMP_ERR_NOERROR;
+      } else {
+        ret = SNMP_ERR_NOSUCHINSTANCE;
+      }
+    }
+  }
+
+  return ret;
+}
+
+snmp_err_t snmp_table_simple_get_next_instance(const u32_t *root_oid, u8_t root_oid_len, struct snmp_node_instance *instance)
+{
+  const struct snmp_table_simple_node *table_node = (const struct snmp_table_simple_node *)(const void *)instance->node;
+  const struct snmp_table_simple_col_def *col_def;
+  struct snmp_obj_id row_oid;
+  u32_t column = 0;
+  snmp_err_t result;
+
+  LWIP_UNUSED_ARG(root_oid);
+  LWIP_UNUSED_ARG(root_oid_len);
+
+  /* check that first part of id is 0 or 1, referencing fixed row entry */
+  if ((instance->instance_oid.len > 0) && (instance->instance_oid.id[0] > 1)) {
+    return SNMP_ERR_NOSUCHINSTANCE;
+  }
+  if (instance->instance_oid.len > 1) {
+    column = instance->instance_oid.id[1];
+  }
+  if (instance->instance_oid.len > 2) {
+    snmp_oid_assign(&row_oid, &(instance->instance_oid.id[2]), instance->instance_oid.len - 2);
+  } else {
+    row_oid.len = 0;
+  }
+
+  /* resolve column and value */
+  do {
+    u32_t i;
+    const struct snmp_table_simple_col_def *next_col_def = NULL;
+    col_def = table_node->columns;
+
+    for (i = 0; i < table_node->column_count; i++) {
+      if (col_def->index == column) {
+        next_col_def = col_def;
+        break;
+      } else if ((col_def->index > column) && ((next_col_def == NULL) ||
+                 (col_def->index < next_col_def->index))) {
+        next_col_def = col_def;
+      }
+      col_def++;
+    }
+
+    if (next_col_def == NULL) {
+      /* no further column found */
+      return SNMP_ERR_NOSUCHINSTANCE;
+    }
+
+    result = table_node->get_next_cell_instance_and_value(
+               &next_col_def->index,
+               &row_oid,
+               &instance->reference,
+               &instance->reference_len);
+
+    if (result == SNMP_ERR_NOERROR) {
+      col_def = next_col_def;
+      break;
+    }
+
+    row_oid.len = 0; /* reset row_oid because we switch to next column and start with the first entry there */
+    column = next_col_def->index + 1;
+  } while (1);
+
+  instance->asn1_type = col_def->asn1_type;
+  instance->access    = SNMP_NODE_INSTANCE_READ_ONLY;
+  instance->set_test  = NULL;
+  instance->set_value = NULL;
+
+  switch (col_def->data_type) {
+    case SNMP_VARIANT_VALUE_TYPE_U32:
+      instance->get_value = snmp_table_extract_value_from_u32ref;
+      break;
+    case SNMP_VARIANT_VALUE_TYPE_S32:
+      instance->get_value = snmp_table_extract_value_from_s32ref;
+      break;
+    case SNMP_VARIANT_VALUE_TYPE_PTR: /* fall through */
+    case SNMP_VARIANT_VALUE_TYPE_CONST_PTR:
+      instance->get_value = snmp_table_extract_value_from_refconstptr;
+      break;
+    default:
+      LWIP_DEBUGF(SNMP_DEBUG, ("snmp_table_simple_get_instance(): unknown column data_type: %d\n", col_def->data_type));
+      return SNMP_ERR_GENERROR;
+  }
+
+  /* build resulting oid */
+  instance->instance_oid.len   = 2;
+  instance->instance_oid.id[0] = 1;
+  instance->instance_oid.id[1] = col_def->index;
+  snmp_oid_append(&instance->instance_oid, row_oid.id, row_oid.len);
+
+  return SNMP_ERR_NOERROR;
+}
+
+
+s16_t
+snmp_table_extract_value_from_s32ref(struct snmp_node_instance *instance, void *value)
+{
+  s32_t *dst = (s32_t *)value;
+  *dst = instance->reference.s32;
+  return sizeof(*dst);
+}
+
+s16_t
+snmp_table_extract_value_from_u32ref(struct snmp_node_instance *instance, void *value)
+{
+  u32_t *dst = (u32_t *)value;
+  *dst = instance->reference.u32;
+  return sizeof(*dst);
+}
+
+s16_t
+snmp_table_extract_value_from_refconstptr(struct snmp_node_instance *instance, void *value)
+{
+  MEMCPY(value, instance->reference.const_ptr, instance->reference_len);
+  return (u16_t)instance->reference_len;
+}
+
+#endif /* LWIP_SNMP */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/apps/snmp/snmp_threadsync.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/apps/snmp/snmp_threadsync.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/apps/snmp/snmp_threadsync.c	(revision 457)
@@ -0,0 +1,231 @@
+/**
+ * @file
+ * SNMP thread synchronization implementation.
+ */
+
+/*
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * Author: Dirk Ziegelmeier <dziegel@gmx.de>
+ */
+
+#include "lwip/apps/snmp_opts.h"
+
+#if LWIP_SNMP && (NO_SYS == 0) /* don't build if not configured for use in lwipopts.h */
+
+#include "lwip/apps/snmp_threadsync.h"
+#include "lwip/apps/snmp_core.h"
+#include "lwip/sys.h"
+#include <string.h>
+
+static void
+call_synced_function(struct threadsync_data *call_data, snmp_threadsync_called_fn fn)
+{
+  sys_mutex_lock(&call_data->threadsync_node->instance->sem_usage_mutex);
+  call_data->threadsync_node->instance->sync_fn(fn, call_data);
+  sys_sem_wait(&call_data->threadsync_node->instance->sem);
+  sys_mutex_unlock(&call_data->threadsync_node->instance->sem_usage_mutex);
+}
+
+static void
+threadsync_get_value_synced(void *ctx)
+{
+  struct threadsync_data *call_data = (struct threadsync_data *)ctx;
+
+  if (call_data->proxy_instance.get_value != NULL) {
+    call_data->retval.s16 = call_data->proxy_instance.get_value(&call_data->proxy_instance, call_data->arg1.value);
+  } else {
+    call_data->retval.s16 = -1;
+  }
+
+  sys_sem_signal(&call_data->threadsync_node->instance->sem);
+}
+
+static s16_t
+threadsync_get_value(struct snmp_node_instance *instance, void *value)
+{
+  struct threadsync_data *call_data = (struct threadsync_data *)instance->reference.ptr;
+
+  call_data->arg1.value = value;
+  call_synced_function(call_data, threadsync_get_value_synced);
+
+  return call_data->retval.s16;
+}
+
+static void
+threadsync_set_test_synced(void *ctx)
+{
+  struct threadsync_data *call_data = (struct threadsync_data *)ctx;
+
+  if (call_data->proxy_instance.set_test != NULL) {
+    call_data->retval.err = call_data->proxy_instance.set_test(&call_data->proxy_instance, call_data->arg2.len, call_data->arg1.value);
+  } else {
+    call_data->retval.err = SNMP_ERR_NOTWRITABLE;
+  }
+
+  sys_sem_signal(&call_data->threadsync_node->instance->sem);
+}
+
+static snmp_err_t
+threadsync_set_test(struct snmp_node_instance *instance, u16_t len, void *value)
+{
+  struct threadsync_data *call_data = (struct threadsync_data *)instance->reference.ptr;
+
+  call_data->arg1.value = value;
+  call_data->arg2.len = len;
+  call_synced_function(call_data, threadsync_set_test_synced);
+
+  return call_data->retval.err;
+}
+
+static void
+threadsync_set_value_synced(void *ctx)
+{
+  struct threadsync_data *call_data = (struct threadsync_data *)ctx;
+
+  if (call_data->proxy_instance.set_value != NULL) {
+    call_data->retval.err = call_data->proxy_instance.set_value(&call_data->proxy_instance, call_data->arg2.len, call_data->arg1.value);
+  } else {
+    call_data->retval.err = SNMP_ERR_NOTWRITABLE;
+  }
+
+  sys_sem_signal(&call_data->threadsync_node->instance->sem);
+}
+
+static snmp_err_t
+threadsync_set_value(struct snmp_node_instance *instance, u16_t len, void *value)
+{
+  struct threadsync_data *call_data = (struct threadsync_data *)instance->reference.ptr;
+
+  call_data->arg1.value = value;
+  call_data->arg2.len = len;
+  call_synced_function(call_data, threadsync_set_value_synced);
+
+  return call_data->retval.err;
+}
+
+static void
+threadsync_release_instance_synced(void *ctx)
+{
+  struct threadsync_data *call_data = (struct threadsync_data *)ctx;
+
+  call_data->proxy_instance.release_instance(&call_data->proxy_instance);
+
+  sys_sem_signal(&call_data->threadsync_node->instance->sem);
+}
+
+static void
+threadsync_release_instance(struct snmp_node_instance *instance)
+{
+  struct threadsync_data *call_data = (struct threadsync_data *)instance->reference.ptr;
+
+  if (call_data->proxy_instance.release_instance != NULL) {
+    call_synced_function(call_data, threadsync_release_instance_synced);
+  }
+}
+
+static void
+get_instance_synced(void *ctx)
+{
+  struct threadsync_data *call_data   = (struct threadsync_data *)ctx;
+  const struct snmp_leaf_node *leaf   = (const struct snmp_leaf_node *)(const void *)call_data->proxy_instance.node;
+
+  call_data->retval.err = leaf->get_instance(call_data->arg1.root_oid, call_data->arg2.root_oid_len, &call_data->proxy_instance);
+
+  sys_sem_signal(&call_data->threadsync_node->instance->sem);
+}
+
+static void
+get_next_instance_synced(void *ctx)
+{
+  struct threadsync_data *call_data   = (struct threadsync_data *)ctx;
+  const struct snmp_leaf_node *leaf   = (const struct snmp_leaf_node *)(const void *)call_data->proxy_instance.node;
+
+  call_data->retval.err = leaf->get_next_instance(call_data->arg1.root_oid, call_data->arg2.root_oid_len, &call_data->proxy_instance);
+
+  sys_sem_signal(&call_data->threadsync_node->instance->sem);
+}
+
+static snmp_err_t
+do_sync(const u32_t *root_oid, u8_t root_oid_len, struct snmp_node_instance *instance, snmp_threadsync_called_fn fn)
+{
+  const struct snmp_threadsync_node *threadsync_node = (const struct snmp_threadsync_node *)(const void *)instance->node;
+  struct threadsync_data *call_data = &threadsync_node->instance->data;
+
+  if (threadsync_node->node.node.oid != threadsync_node->target->node.oid) {
+    LWIP_DEBUGF(SNMP_DEBUG, ("Sync node OID does not match target node OID"));
+    return SNMP_ERR_NOSUCHINSTANCE;
+  }
+
+  memset(&call_data->proxy_instance, 0, sizeof(call_data->proxy_instance));
+
+  instance->reference.ptr = call_data;
+  snmp_oid_assign(&call_data->proxy_instance.instance_oid, instance->instance_oid.id, instance->instance_oid.len);
+
+  call_data->proxy_instance.node = &threadsync_node->target->node;
+  call_data->threadsync_node     = threadsync_node;
+
+  call_data->arg1.root_oid       = root_oid;
+  call_data->arg2.root_oid_len   = root_oid_len;
+  call_synced_function(call_data, fn);
+
+  if (call_data->retval.err == SNMP_ERR_NOERROR) {
+    instance->access           = call_data->proxy_instance.access;
+    instance->asn1_type        = call_data->proxy_instance.asn1_type;
+    instance->release_instance = threadsync_release_instance;
+    instance->get_value        = (call_data->proxy_instance.get_value != NULL) ? threadsync_get_value : NULL;
+    instance->set_value        = (call_data->proxy_instance.set_value != NULL) ? threadsync_set_value : NULL;
+    instance->set_test         = (call_data->proxy_instance.set_test != NULL) ?  threadsync_set_test  : NULL;
+    snmp_oid_assign(&instance->instance_oid, call_data->proxy_instance.instance_oid.id, call_data->proxy_instance.instance_oid.len);
+  }
+
+  return call_data->retval.err;
+}
+
+snmp_err_t
+snmp_threadsync_get_instance(const u32_t *root_oid, u8_t root_oid_len, struct snmp_node_instance *instance)
+{
+  return do_sync(root_oid, root_oid_len, instance, get_instance_synced);
+}
+
+snmp_err_t
+snmp_threadsync_get_next_instance(const u32_t *root_oid, u8_t root_oid_len, struct snmp_node_instance *instance)
+{
+  return do_sync(root_oid, root_oid_len, instance, get_next_instance_synced);
+}
+
+/** Initializes thread synchronization instance */
+void snmp_threadsync_init(struct snmp_threadsync_instance *instance, snmp_threadsync_synchronizer_fn sync_fn)
+{
+  err_t err = sys_mutex_new(&instance->sem_usage_mutex);
+  LWIP_ASSERT("Failed to set up mutex", err == ERR_OK);
+  err = sys_sem_new(&instance->sem, 0);
+  LWIP_UNUSED_ARG(err); /* in case of LWIP_NOASSERT */
+  LWIP_ASSERT("Failed to set up semaphore", err == ERR_OK);
+  instance->sync_fn = sync_fn;
+}
+
+#endif /* LWIP_SNMP */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/apps/snmp/snmp_traps.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/apps/snmp/snmp_traps.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/apps/snmp/snmp_traps.c	(revision 457)
@@ -0,0 +1,458 @@
+/**
+ * @file
+ * SNMPv1 traps implementation.
+ */
+
+/*
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Martin Hentschel
+ *         Christiaan Simons <christiaan.simons@axon.tv>
+ *
+ */
+
+#include "lwip/apps/snmp_opts.h"
+
+#if LWIP_SNMP /* don't build if not configured for use in lwipopts.h */
+
+#include <string.h>
+
+#include "lwip/snmp.h"
+#include "lwip/sys.h"
+#include "lwip/apps/snmp.h"
+#include "lwip/apps/snmp_core.h"
+#include "lwip/prot/iana.h"
+#include "snmp_msg.h"
+#include "snmp_asn1.h"
+#include "snmp_core_priv.h"
+
+struct snmp_msg_trap {
+  /* source enterprise ID (sysObjectID) */
+  const struct snmp_obj_id *enterprise;
+  /* source IP address, raw network order format */
+  ip_addr_t sip;
+  /* generic trap code */
+  u32_t gen_trap;
+  /* specific trap code */
+  u32_t spc_trap;
+  /* timestamp */
+  u32_t ts;
+  /* snmp_version */
+  u32_t snmp_version;
+
+  /* output trap lengths used in ASN encoding */
+  /* encoding pdu length */
+  u16_t pdulen;
+  /* encoding community length */
+  u16_t comlen;
+  /* encoding sequence length */
+  u16_t seqlen;
+  /* encoding varbinds sequence length */
+  u16_t vbseqlen;
+};
+
+static u16_t snmp_trap_varbind_sum(struct snmp_msg_trap *trap, struct snmp_varbind *varbinds);
+static u16_t snmp_trap_header_sum(struct snmp_msg_trap *trap, u16_t vb_len);
+static err_t snmp_trap_header_enc(struct snmp_msg_trap *trap, struct snmp_pbuf_stream *pbuf_stream);
+static err_t snmp_trap_varbind_enc(struct snmp_msg_trap *trap, struct snmp_pbuf_stream *pbuf_stream, struct snmp_varbind *varbinds);
+
+#define BUILD_EXEC(code) \
+  if ((code) != ERR_OK) { \
+    LWIP_DEBUGF(SNMP_DEBUG, ("SNMP error during creation of outbound trap frame!")); \
+    return ERR_ARG; \
+  }
+
+/** Agent community string for sending traps */
+extern const char *snmp_community_trap;
+
+void *snmp_traps_handle;
+
+struct snmp_trap_dst {
+  /* destination IP address in network order */
+  ip_addr_t dip;
+  /* set to 0 when disabled, >0 when enabled */
+  u8_t enable;
+};
+static struct snmp_trap_dst trap_dst[SNMP_TRAP_DESTINATIONS];
+
+static u8_t snmp_auth_traps_enabled = 0;
+
+/**
+ * @ingroup snmp_traps
+ * Sets enable switch for this trap destination.
+ * @param dst_idx index in 0 .. SNMP_TRAP_DESTINATIONS-1
+ * @param enable switch if 0 destination is disabled >0 enabled.
+ */
+void
+snmp_trap_dst_enable(u8_t dst_idx, u8_t enable)
+{
+  LWIP_ASSERT_CORE_LOCKED();
+  if (dst_idx < SNMP_TRAP_DESTINATIONS) {
+    trap_dst[dst_idx].enable = enable;
+  }
+}
+
+/**
+ * @ingroup snmp_traps
+ * Sets IPv4 address for this trap destination.
+ * @param dst_idx index in 0 .. SNMP_TRAP_DESTINATIONS-1
+ * @param dst IPv4 address in host order.
+ */
+void
+snmp_trap_dst_ip_set(u8_t dst_idx, const ip_addr_t *dst)
+{
+  LWIP_ASSERT_CORE_LOCKED();
+  if (dst_idx < SNMP_TRAP_DESTINATIONS) {
+    ip_addr_set(&trap_dst[dst_idx].dip, dst);
+  }
+}
+
+/**
+ * @ingroup snmp_traps
+ * Enable/disable authentication traps
+ */
+void
+snmp_set_auth_traps_enabled(u8_t enable)
+{
+  snmp_auth_traps_enabled = enable;
+}
+
+/**
+ * @ingroup snmp_traps
+ * Get authentication traps enabled state
+ */
+u8_t
+snmp_get_auth_traps_enabled(void)
+{
+  return snmp_auth_traps_enabled;
+}
+
+
+/**
+ * @ingroup snmp_traps
+ * Sends a generic or enterprise specific trap message.
+ *
+ * @param eoid points to enterprise object identifier
+ * @param generic_trap is the trap code
+ * @param specific_trap used for enterprise traps when generic_trap == 6
+ * @param varbinds linked list of varbinds to be sent
+ * @return ERR_OK when success, ERR_MEM if we're out of memory
+ *
+ * @note the use of the enterprise identifier field
+ * is per RFC1215.
+ * Use .iso.org.dod.internet.mgmt.mib-2.snmp for generic traps
+ * and .iso.org.dod.internet.private.enterprises.yourenterprise
+ * (sysObjectID) for specific traps.
+ */
+err_t
+snmp_send_trap(const struct snmp_obj_id *eoid, s32_t generic_trap, s32_t specific_trap, struct snmp_varbind *varbinds)
+{
+  struct snmp_msg_trap trap_msg;
+  struct snmp_trap_dst *td;
+  struct pbuf *p;
+  u16_t i, tot_len;
+  err_t err = ERR_OK;
+
+  LWIP_ASSERT_CORE_LOCKED();
+
+  trap_msg.snmp_version = 0;
+
+  for (i = 0, td = &trap_dst[0]; i < SNMP_TRAP_DESTINATIONS; i++, td++) {
+    if ((td->enable != 0) && !ip_addr_isany(&td->dip)) {
+      /* lookup current source address for this dst */
+      if (snmp_get_local_ip_for_dst(snmp_traps_handle, &td->dip, &trap_msg.sip)) {
+        if (eoid == NULL) {
+          trap_msg.enterprise = snmp_get_device_enterprise_oid();
+        } else {
+          trap_msg.enterprise = eoid;
+        }
+
+        trap_msg.gen_trap = generic_trap;
+        if (generic_trap == SNMP_GENTRAP_ENTERPRISE_SPECIFIC) {
+          trap_msg.spc_trap = specific_trap;
+        } else {
+          trap_msg.spc_trap = 0;
+        }
+
+        MIB2_COPY_SYSUPTIME_TO(&trap_msg.ts);
+
+        /* pass 0, calculate length fields */
+        tot_len = snmp_trap_varbind_sum(&trap_msg, varbinds);
+        tot_len = snmp_trap_header_sum(&trap_msg, tot_len);
+
+        /* allocate pbuf(s) */
+        p = pbuf_alloc(PBUF_TRANSPORT, tot_len, PBUF_RAM);
+        if (p != NULL) {
+          struct snmp_pbuf_stream pbuf_stream;
+          snmp_pbuf_stream_init(&pbuf_stream, p, 0, tot_len);
+
+          /* pass 1, encode packet into the pbuf(s) */
+          snmp_trap_header_enc(&trap_msg, &pbuf_stream);
+          snmp_trap_varbind_enc(&trap_msg, &pbuf_stream, varbinds);
+
+          snmp_stats.outtraps++;
+          snmp_stats.outpkts++;
+
+          /** send to the TRAP destination */
+          snmp_sendto(snmp_traps_handle, p, &td->dip, LWIP_IANA_PORT_SNMP_TRAP);
+          pbuf_free(p);
+        } else {
+          err = ERR_MEM;
+        }
+      } else {
+        /* routing error */
+        err = ERR_RTE;
+      }
+    }
+  }
+  return err;
+}
+
+/**
+ * @ingroup snmp_traps
+ * Send generic SNMP trap
+ */
+err_t
+snmp_send_trap_generic(s32_t generic_trap)
+{
+  static const struct snmp_obj_id oid = { 7, { 1, 3, 6, 1, 2, 1, 11 } };
+  return snmp_send_trap(&oid, generic_trap, 0, NULL);
+}
+
+/**
+ * @ingroup snmp_traps
+ * Send specific SNMP trap with variable bindings
+ */
+err_t
+snmp_send_trap_specific(s32_t specific_trap, struct snmp_varbind *varbinds)
+{
+  return snmp_send_trap(NULL, SNMP_GENTRAP_ENTERPRISE_SPECIFIC, specific_trap, varbinds);
+}
+
+/**
+ * @ingroup snmp_traps
+ * Send coldstart trap
+ */
+void
+snmp_coldstart_trap(void)
+{
+  snmp_send_trap_generic(SNMP_GENTRAP_COLDSTART);
+}
+
+/**
+ * @ingroup snmp_traps
+ * Send authentication failure trap (used internally by agent)
+ */
+void
+snmp_authfail_trap(void)
+{
+  if (snmp_auth_traps_enabled != 0) {
+    snmp_send_trap_generic(SNMP_GENTRAP_AUTH_FAILURE);
+  }
+}
+
+static u16_t
+snmp_trap_varbind_sum(struct snmp_msg_trap *trap, struct snmp_varbind *varbinds)
+{
+  struct snmp_varbind *varbind;
+  u16_t tot_len;
+  u8_t tot_len_len;
+
+  tot_len = 0;
+  varbind = varbinds;
+  while (varbind != NULL) {
+    struct snmp_varbind_len len;
+
+    if (snmp_varbind_length(varbind, &len) == ERR_OK) {
+      tot_len += 1 + len.vb_len_len + len.vb_value_len;
+    }
+
+    varbind = varbind->next;
+  }
+
+  trap->vbseqlen = tot_len;
+  snmp_asn1_enc_length_cnt(trap->vbseqlen, &tot_len_len);
+  tot_len += 1 + tot_len_len;
+
+  return tot_len;
+}
+
+/**
+ * Sums trap header field lengths from tail to head and
+ * returns trap_header_lengths for second encoding pass.
+ *
+ * @param trap Trap message
+ * @param vb_len varbind-list length
+ * @return the required length for encoding the trap header
+ */
+static u16_t
+snmp_trap_header_sum(struct snmp_msg_trap *trap, u16_t vb_len)
+{
+  u16_t tot_len;
+  u16_t len;
+  u8_t lenlen;
+
+  tot_len = vb_len;
+
+  snmp_asn1_enc_u32t_cnt(trap->ts, &len);
+  snmp_asn1_enc_length_cnt(len, &lenlen);
+  tot_len += 1 + len + lenlen;
+
+  snmp_asn1_enc_s32t_cnt(trap->spc_trap, &len);
+  snmp_asn1_enc_length_cnt(len, &lenlen);
+  tot_len += 1 + len + lenlen;
+
+  snmp_asn1_enc_s32t_cnt(trap->gen_trap, &len);
+  snmp_asn1_enc_length_cnt(len, &lenlen);
+  tot_len += 1 + len + lenlen;
+
+  if (IP_IS_V6_VAL(trap->sip)) {
+#if LWIP_IPV6
+    len = sizeof(ip_2_ip6(&trap->sip)->addr);
+#endif
+  } else {
+#if LWIP_IPV4
+    len = sizeof(ip_2_ip4(&trap->sip)->addr);
+#endif
+  }
+  snmp_asn1_enc_length_cnt(len, &lenlen);
+  tot_len += 1 + len + lenlen;
+
+  snmp_asn1_enc_oid_cnt(trap->enterprise->id, trap->enterprise->len, &len);
+  snmp_asn1_enc_length_cnt(len, &lenlen);
+  tot_len += 1 + len + lenlen;
+
+  trap->pdulen = tot_len;
+  snmp_asn1_enc_length_cnt(trap->pdulen, &lenlen);
+  tot_len += 1 + lenlen;
+
+  trap->comlen = (u16_t)LWIP_MIN(strlen(snmp_community_trap), 0xFFFF);
+  snmp_asn1_enc_length_cnt(trap->comlen, &lenlen);
+  tot_len += 1 + lenlen + trap->comlen;
+
+  snmp_asn1_enc_s32t_cnt(trap->snmp_version, &len);
+  snmp_asn1_enc_length_cnt(len, &lenlen);
+  tot_len += 1 + len + lenlen;
+
+  trap->seqlen = tot_len;
+  snmp_asn1_enc_length_cnt(trap->seqlen, &lenlen);
+  tot_len += 1 + lenlen;
+
+  return tot_len;
+}
+
+static err_t
+snmp_trap_varbind_enc(struct snmp_msg_trap *trap, struct snmp_pbuf_stream *pbuf_stream, struct snmp_varbind *varbinds)
+{
+  struct snmp_asn1_tlv tlv;
+  struct snmp_varbind *varbind;
+
+  varbind = varbinds;
+
+  SNMP_ASN1_SET_TLV_PARAMS(tlv, SNMP_ASN1_TYPE_SEQUENCE, 0, trap->vbseqlen);
+  BUILD_EXEC( snmp_ans1_enc_tlv(pbuf_stream, &tlv) );
+
+  while (varbind != NULL) {
+    BUILD_EXEC( snmp_append_outbound_varbind(pbuf_stream, varbind) );
+
+    varbind = varbind->next;
+  }
+
+  return ERR_OK;
+}
+
+/**
+ * Encodes trap header from head to tail.
+ */
+static err_t
+snmp_trap_header_enc(struct snmp_msg_trap *trap, struct snmp_pbuf_stream *pbuf_stream)
+{
+  struct snmp_asn1_tlv tlv;
+
+  /* 'Message' sequence */
+  SNMP_ASN1_SET_TLV_PARAMS(tlv, SNMP_ASN1_TYPE_SEQUENCE, 0, trap->seqlen);
+  BUILD_EXEC( snmp_ans1_enc_tlv(pbuf_stream, &tlv) );
+
+  /* version */
+  SNMP_ASN1_SET_TLV_PARAMS(tlv, SNMP_ASN1_TYPE_INTEGER, 0, 0);
+  snmp_asn1_enc_s32t_cnt(trap->snmp_version, &tlv.value_len);
+  BUILD_EXEC( snmp_ans1_enc_tlv(pbuf_stream, &tlv) );
+  BUILD_EXEC( snmp_asn1_enc_s32t(pbuf_stream, tlv.value_len, trap->snmp_version) );
+
+  /* community */
+  SNMP_ASN1_SET_TLV_PARAMS(tlv, SNMP_ASN1_TYPE_OCTET_STRING, 0, trap->comlen);
+  BUILD_EXEC( snmp_ans1_enc_tlv(pbuf_stream, &tlv) );
+  BUILD_EXEC( snmp_asn1_enc_raw(pbuf_stream,  (const u8_t *)snmp_community_trap, trap->comlen) );
+
+  /* 'PDU' sequence */
+  SNMP_ASN1_SET_TLV_PARAMS(tlv, (SNMP_ASN1_CLASS_CONTEXT | SNMP_ASN1_CONTENTTYPE_CONSTRUCTED | SNMP_ASN1_CONTEXT_PDU_TRAP), 0, trap->pdulen);
+  BUILD_EXEC( snmp_ans1_enc_tlv(pbuf_stream, &tlv) );
+
+  /* object ID */
+  SNMP_ASN1_SET_TLV_PARAMS(tlv, SNMP_ASN1_TYPE_OBJECT_ID, 0, 0);
+  snmp_asn1_enc_oid_cnt(trap->enterprise->id, trap->enterprise->len, &tlv.value_len);
+  BUILD_EXEC( snmp_ans1_enc_tlv(pbuf_stream, &tlv) );
+  BUILD_EXEC( snmp_asn1_enc_oid(pbuf_stream, trap->enterprise->id, trap->enterprise->len) );
+
+  /* IP addr */
+  if (IP_IS_V6_VAL(trap->sip)) {
+#if LWIP_IPV6
+    SNMP_ASN1_SET_TLV_PARAMS(tlv, SNMP_ASN1_TYPE_IPADDR, 0, sizeof(ip_2_ip6(&trap->sip)->addr));
+    BUILD_EXEC( snmp_ans1_enc_tlv(pbuf_stream, &tlv) );
+    BUILD_EXEC( snmp_asn1_enc_raw(pbuf_stream, (const u8_t *)&ip_2_ip6(&trap->sip)->addr, sizeof(ip_2_ip6(&trap->sip)->addr)) );
+#endif
+  } else {
+#if LWIP_IPV4
+    SNMP_ASN1_SET_TLV_PARAMS(tlv, SNMP_ASN1_TYPE_IPADDR, 0, sizeof(ip_2_ip4(&trap->sip)->addr));
+    BUILD_EXEC( snmp_ans1_enc_tlv(pbuf_stream, &tlv) );
+    BUILD_EXEC( snmp_asn1_enc_raw(pbuf_stream, (const u8_t *)&ip_2_ip4(&trap->sip)->addr, sizeof(ip_2_ip4(&trap->sip)->addr)) );
+#endif
+  }
+
+  /* trap length */
+  SNMP_ASN1_SET_TLV_PARAMS(tlv, SNMP_ASN1_TYPE_INTEGER, 0, 0);
+  snmp_asn1_enc_s32t_cnt(trap->gen_trap, &tlv.value_len);
+  BUILD_EXEC( snmp_ans1_enc_tlv(pbuf_stream, &tlv) );
+  BUILD_EXEC( snmp_asn1_enc_s32t(pbuf_stream, tlv.value_len, trap->gen_trap) );
+
+  /* specific trap */
+  SNMP_ASN1_SET_TLV_PARAMS(tlv, SNMP_ASN1_TYPE_INTEGER, 0, 0);
+  snmp_asn1_enc_s32t_cnt(trap->spc_trap, &tlv.value_len);
+  BUILD_EXEC( snmp_ans1_enc_tlv(pbuf_stream, &tlv) );
+  BUILD_EXEC( snmp_asn1_enc_s32t(pbuf_stream, tlv.value_len, trap->spc_trap) );
+
+  /* timestamp */
+  SNMP_ASN1_SET_TLV_PARAMS(tlv, SNMP_ASN1_TYPE_TIMETICKS, 0, 0);
+  snmp_asn1_enc_s32t_cnt(trap->ts, &tlv.value_len);
+  BUILD_EXEC( snmp_ans1_enc_tlv(pbuf_stream, &tlv) );
+  BUILD_EXEC( snmp_asn1_enc_s32t(pbuf_stream, tlv.value_len, trap->ts) );
+
+  return ERR_OK;
+}
+
+#endif /* LWIP_SNMP */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/apps/snmp/snmpv3.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/apps/snmp/snmpv3.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/apps/snmp/snmpv3.c	(revision 457)
@@ -0,0 +1,136 @@
+/**
+ * @file
+ * Additional SNMPv3 functionality RFC3414 and RFC3826.
+ */
+
+/*
+ * Copyright (c) 2016 Elias Oenal.
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * Author: Elias Oenal <lwip@eliasoenal.com>
+ */
+
+#include "snmpv3_priv.h"
+#include "lwip/apps/snmpv3.h"
+#include "lwip/sys.h"
+#include <string.h>
+
+#if LWIP_SNMP && LWIP_SNMP_V3
+
+#ifdef LWIP_SNMPV3_INCLUDE_ENGINE
+#include LWIP_SNMPV3_INCLUDE_ENGINE
+#endif
+
+#define SNMP_MAX_TIME_BOOT 2147483647UL
+
+/** Call this if engine has been changed. Has to reset boots, see below */
+void
+snmpv3_engine_id_changed(void)
+{
+  snmpv3_set_engine_boots(0);
+}
+
+/** According to RFC3414 2.2.2.
+ *
+ * The number of times that the SNMP engine has
+ * (re-)initialized itself since snmpEngineID
+ * was last configured.
+ */
+s32_t
+snmpv3_get_engine_boots_internal(void)
+{
+  if (snmpv3_get_engine_boots() == 0 ||
+      snmpv3_get_engine_boots() < SNMP_MAX_TIME_BOOT) {
+    return snmpv3_get_engine_boots();
+  }
+
+  snmpv3_set_engine_boots(SNMP_MAX_TIME_BOOT);
+  return snmpv3_get_engine_boots();
+}
+
+/** RFC3414 2.2.2.
+ *
+ * Once the timer reaches 2147483647 it gets reset to zero and the
+ * engine boot ups get incremented.
+ */
+s32_t
+snmpv3_get_engine_time_internal(void)
+{
+  if (snmpv3_get_engine_time() >= SNMP_MAX_TIME_BOOT) {
+    snmpv3_reset_engine_time();
+
+    if (snmpv3_get_engine_boots() < SNMP_MAX_TIME_BOOT - 1) {
+      snmpv3_set_engine_boots(snmpv3_get_engine_boots() + 1);
+    } else {
+      snmpv3_set_engine_boots(SNMP_MAX_TIME_BOOT);
+    }
+  }
+
+  return snmpv3_get_engine_time();
+}
+
+#if LWIP_SNMP_V3_CRYPTO
+
+/* This function ignores the byte order suggestion in RFC3414
+ * since it simply doesn't influence the effectiveness of an IV.
+ *
+ * Implementing RFC3826 priv param algorithm if LWIP_RAND is available.
+ *
+ * @todo: This is a potential thread safety issue.
+ */
+err_t
+snmpv3_build_priv_param(u8_t *priv_param)
+{
+#ifdef LWIP_RAND /* Based on RFC3826 */
+  static u8_t init;
+  static u32_t priv1, priv2;
+
+  /* Lazy initialisation */
+  if (init == 0) {
+    init = 1;
+    priv1 = LWIP_RAND();
+    priv2 = LWIP_RAND();
+  }
+
+  SMEMCPY(&priv_param[0], &priv1, sizeof(priv1));
+  SMEMCPY(&priv_param[4], &priv2, sizeof(priv2));
+
+  /* Emulate 64bit increment */
+  priv1++;
+  if (!priv1) { /* Overflow */
+    priv2++;
+  }
+#else /* Based on RFC3414 */
+  static u32_t ctr;
+  u32_t boots = snmpv3_get_engine_boots_internal();
+  SMEMCPY(&priv_param[0], &boots, 4);
+  SMEMCPY(&priv_param[4], &ctr, 4);
+  ctr++;
+#endif
+  return ERR_OK;
+}
+#endif /* LWIP_SNMP_V3_CRYPTO */
+
+#endif
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/apps/snmp/snmpv3_mbedtls.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/apps/snmp/snmpv3_mbedtls.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/apps/snmp/snmpv3_mbedtls.c	(revision 457)
@@ -0,0 +1,342 @@
+/**
+ * @file
+ * SNMPv3 crypto/auth functions implemented for ARM mbedtls.
+ */
+
+/*
+ * Copyright (c) 2016 Elias Oenal and Dirk Ziegelmeier.
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * Author: Elias Oenal <lwip@eliasoenal.com>
+ *         Dirk Ziegelmeier <dirk@ziegelmeier.net>
+ */
+
+#include "lwip/apps/snmpv3.h"
+#include "snmpv3_priv.h"
+#include "lwip/arch.h"
+#include "snmp_msg.h"
+#include "lwip/sys.h"
+#include <string.h>
+
+#if LWIP_SNMP && LWIP_SNMP_V3 && LWIP_SNMP_V3_MBEDTLS
+
+#include "mbedtls/md.h"
+#include "mbedtls/cipher.h"
+
+#include "mbedtls/md5.h"
+#include "mbedtls/sha1.h"
+
+err_t
+snmpv3_auth(struct snmp_pbuf_stream *stream, u16_t length,
+            const u8_t *key, snmpv3_auth_algo_t algo, u8_t *hmac_out)
+{
+  u32_t i;
+  u8_t key_len;
+  const mbedtls_md_info_t *md_info;
+  mbedtls_md_context_t ctx;
+  struct snmp_pbuf_stream read_stream;
+  snmp_pbuf_stream_init(&read_stream, stream->pbuf, stream->offset, stream->length);
+
+  if (algo == SNMP_V3_AUTH_ALGO_MD5) {
+    md_info = mbedtls_md_info_from_type(MBEDTLS_MD_MD5);
+    key_len = SNMP_V3_MD5_LEN;
+  } else if (algo == SNMP_V3_AUTH_ALGO_SHA) {
+    md_info = mbedtls_md_info_from_type(MBEDTLS_MD_SHA1);
+    key_len = SNMP_V3_SHA_LEN;
+  } else {
+    return ERR_ARG;
+  }
+
+  mbedtls_md_init(&ctx);
+  if (mbedtls_md_setup(&ctx, md_info, 1) != 0) {
+    return ERR_ARG;
+  }
+
+  if (mbedtls_md_hmac_starts(&ctx, key, key_len) != 0) {
+    goto free_md;
+  }
+
+  for (i = 0; i < length; i++) {
+    u8_t byte;
+
+    if (snmp_pbuf_stream_read(&read_stream, &byte)) {
+      goto free_md;
+    }
+
+    if (mbedtls_md_hmac_update(&ctx, &byte, 1) != 0) {
+      goto free_md;
+    }
+  }
+
+  if (mbedtls_md_hmac_finish(&ctx, hmac_out) != 0) {
+    goto free_md;
+  }
+
+  mbedtls_md_free(&ctx);
+  return ERR_OK;
+
+free_md:
+  mbedtls_md_free(&ctx);
+  return ERR_ARG;
+}
+
+#if LWIP_SNMP_V3_CRYPTO
+
+err_t
+snmpv3_crypt(struct snmp_pbuf_stream *stream, u16_t length,
+             const u8_t *key, const u8_t *priv_param, const u32_t engine_boots,
+             const u32_t engine_time, snmpv3_priv_algo_t algo, snmpv3_priv_mode_t mode)
+{
+  size_t i;
+  mbedtls_cipher_context_t ctx;
+  const mbedtls_cipher_info_t *cipher_info;
+
+  struct snmp_pbuf_stream read_stream;
+  struct snmp_pbuf_stream write_stream;
+  snmp_pbuf_stream_init(&read_stream, stream->pbuf, stream->offset, stream->length);
+  snmp_pbuf_stream_init(&write_stream, stream->pbuf, stream->offset, stream->length);
+  mbedtls_cipher_init(&ctx);
+
+  if (algo == SNMP_V3_PRIV_ALGO_DES) {
+    u8_t iv_local[8];
+    u8_t out_bytes[8];
+    size_t out_len;
+
+    /* RFC 3414 mandates padding for DES */
+    if ((length & 0x07) != 0) {
+      return ERR_ARG;
+    }
+
+    cipher_info = mbedtls_cipher_info_from_type(MBEDTLS_CIPHER_DES_CBC);
+    if (mbedtls_cipher_setup(&ctx, cipher_info) != 0) {
+      return ERR_ARG;
+    }
+    if (mbedtls_cipher_set_padding_mode(&ctx, MBEDTLS_PADDING_NONE) != 0) {
+      return ERR_ARG;
+    }
+    if (mbedtls_cipher_setkey(&ctx, key, 8 * 8, (mode == SNMP_V3_PRIV_MODE_ENCRYPT) ? MBEDTLS_ENCRYPT : MBEDTLS_DECRYPT) != 0) {
+      goto error;
+    }
+
+    /* Prepare IV */
+    for (i = 0; i < LWIP_ARRAYSIZE(iv_local); i++) {
+      iv_local[i] = priv_param[i] ^ key[i + 8];
+    }
+    if (mbedtls_cipher_set_iv(&ctx, iv_local, LWIP_ARRAYSIZE(iv_local)) != 0) {
+      goto error;
+    }
+
+    for (i = 0; i < length; i += 8) {
+      size_t j;
+      u8_t in_bytes[8];
+      out_len = LWIP_ARRAYSIZE(out_bytes) ;
+
+      for (j = 0; j < LWIP_ARRAYSIZE(in_bytes); j++) {
+        if (snmp_pbuf_stream_read(&read_stream, &in_bytes[j]) != ERR_OK) {
+          goto error;
+        }
+      }
+
+      if (mbedtls_cipher_update(&ctx, in_bytes, LWIP_ARRAYSIZE(in_bytes), out_bytes, &out_len) != 0) {
+        goto error;
+      }
+
+      if (snmp_pbuf_stream_writebuf(&write_stream, out_bytes, (u16_t)out_len) != ERR_OK) {
+        goto error;
+      }
+    }
+
+    out_len = LWIP_ARRAYSIZE(out_bytes);
+    if (mbedtls_cipher_finish(&ctx, out_bytes, &out_len) != 0) {
+      goto error;
+    }
+
+    if (snmp_pbuf_stream_writebuf(&write_stream, out_bytes, (u16_t)out_len) != ERR_OK) {
+      goto error;
+    }
+  } else if (algo == SNMP_V3_PRIV_ALGO_AES) {
+    u8_t iv_local[16];
+
+    cipher_info = mbedtls_cipher_info_from_type(MBEDTLS_CIPHER_AES_128_CFB128);
+    if (mbedtls_cipher_setup(&ctx, cipher_info) != 0) {
+      return ERR_ARG;
+    }
+    if (mbedtls_cipher_setkey(&ctx, key, 16 * 8, (mode == SNMP_V3_PRIV_MODE_ENCRYPT) ? MBEDTLS_ENCRYPT : MBEDTLS_DECRYPT) != 0) {
+      goto error;
+    }
+
+    /*
+     * IV is the big endian concatenation of boots,
+     * uptime and priv param - see RFC3826.
+     */
+    iv_local[0 + 0] = (engine_boots >> 24) & 0xFF;
+    iv_local[0 + 1] = (engine_boots >> 16) & 0xFF;
+    iv_local[0 + 2] = (engine_boots >>  8) & 0xFF;
+    iv_local[0 + 3] = (engine_boots >>  0) & 0xFF;
+    iv_local[4 + 0] = (engine_time  >> 24) & 0xFF;
+    iv_local[4 + 1] = (engine_time  >> 16) & 0xFF;
+    iv_local[4 + 2] = (engine_time  >>  8) & 0xFF;
+    iv_local[4 + 3] = (engine_time  >>  0) & 0xFF;
+    SMEMCPY(iv_local + 8, priv_param, 8);
+    if (mbedtls_cipher_set_iv(&ctx, iv_local, LWIP_ARRAYSIZE(iv_local)) != 0) {
+      goto error;
+    }
+
+    for (i = 0; i < length; i++) {
+      u8_t in_byte;
+      u8_t out_byte;
+      size_t out_len = sizeof(out_byte);
+
+      if (snmp_pbuf_stream_read(&read_stream, &in_byte) != ERR_OK) {
+        goto error;
+      }
+      if (mbedtls_cipher_update(&ctx, &in_byte, sizeof(in_byte), &out_byte, &out_len) != 0) {
+        goto error;
+      }
+      if (snmp_pbuf_stream_write(&write_stream, out_byte) != ERR_OK) {
+        goto error;
+      }
+    }
+  } else {
+    return ERR_ARG;
+  }
+
+  mbedtls_cipher_free(&ctx);
+  return ERR_OK;
+
+error:
+  mbedtls_cipher_free(&ctx);
+  return ERR_OK;
+}
+
+#endif /* LWIP_SNMP_V3_CRYPTO */
+
+/* A.2.1. Password to Key Sample Code for MD5 */
+void
+snmpv3_password_to_key_md5(
+  const u8_t *password,    /* IN */
+  size_t      passwordlen, /* IN */
+  const u8_t *engineID,    /* IN  - pointer to snmpEngineID  */
+  u8_t        engineLength,/* IN  - length of snmpEngineID */
+  u8_t       *key)         /* OUT - pointer to caller 16-octet buffer */
+{
+  mbedtls_md5_context MD;
+  u8_t *cp, password_buf[64];
+  u32_t password_index = 0;
+  u8_t i;
+  u32_t count = 0;
+
+  mbedtls_md5_init(&MD); /* initialize MD5 */
+  mbedtls_md5_starts(&MD);
+
+  /**********************************************/
+  /* Use while loop until we've done 1 Megabyte */
+  /**********************************************/
+  while (count < 1048576) {
+    cp = password_buf;
+    for (i = 0; i < 64; i++) {
+      /*************************************************/
+      /* Take the next octet of the password, wrapping */
+      /* to the beginning of the password as necessary.*/
+      /*************************************************/
+      *cp++ = password[password_index++ % passwordlen];
+    }
+    mbedtls_md5_update(&MD, password_buf, 64);
+    count += 64;
+  }
+  mbedtls_md5_finish(&MD, key); /* tell MD5 we're done */
+
+  /*****************************************************/
+  /* Now localize the key with the engineID and pass   */
+  /* through MD5 to produce final key                  */
+  /* May want to ensure that engineLength <= 32,       */
+  /* otherwise need to use a buffer larger than 64     */
+  /*****************************************************/
+  SMEMCPY(password_buf, key, 16);
+  MEMCPY(password_buf + 16, engineID, engineLength);
+  SMEMCPY(password_buf + 16 + engineLength, key, 16);
+
+  mbedtls_md5_starts(&MD);
+  mbedtls_md5_update(&MD, password_buf, 32 + engineLength);
+  mbedtls_md5_finish(&MD, key);
+
+  mbedtls_md5_free(&MD);
+  return;
+}
+
+/* A.2.2. Password to Key Sample Code for SHA */
+void
+snmpv3_password_to_key_sha(
+  const u8_t *password,    /* IN */
+  size_t      passwordlen, /* IN */
+  const u8_t *engineID,    /* IN  - pointer to snmpEngineID  */
+  u8_t        engineLength,/* IN  - length of snmpEngineID */
+  u8_t       *key)         /* OUT - pointer to caller 20-octet buffer */
+{
+  mbedtls_sha1_context SH;
+  u8_t *cp, password_buf[72];
+  u32_t password_index = 0;
+  u8_t i;
+  u32_t count = 0;
+
+  mbedtls_sha1_init(&SH); /* initialize SHA */
+  mbedtls_sha1_starts(&SH);
+
+  /**********************************************/
+  /* Use while loop until we've done 1 Megabyte */
+  /**********************************************/
+  while (count < 1048576) {
+    cp = password_buf;
+    for (i = 0; i < 64; i++) {
+      /*************************************************/
+      /* Take the next octet of the password, wrapping */
+      /* to the beginning of the password as necessary.*/
+      /*************************************************/
+      *cp++ = password[password_index++ % passwordlen];
+    }
+    mbedtls_sha1_update(&SH, password_buf, 64);
+    count += 64;
+  }
+  mbedtls_sha1_finish(&SH, key); /* tell SHA we're done */
+
+  /*****************************************************/
+  /* Now localize the key with the engineID and pass   */
+  /* through SHA to produce final key                  */
+  /* May want to ensure that engineLength <= 32,       */
+  /* otherwise need to use a buffer larger than 72     */
+  /*****************************************************/
+  SMEMCPY(password_buf, key, 20);
+  MEMCPY(password_buf + 20, engineID, engineLength);
+  SMEMCPY(password_buf + 20 + engineLength, key, 20);
+
+  mbedtls_sha1_starts(&SH);
+  mbedtls_sha1_update(&SH, password_buf, 40 + engineLength);
+  mbedtls_sha1_finish(&SH, key);
+
+  mbedtls_sha1_free(&SH);
+  return;
+}
+
+#endif /* LWIP_SNMP && LWIP_SNMP_V3 && LWIP_SNMP_V3_MBEDTLS */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/apps/snmp/snmpv3_priv.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/apps/snmp/snmpv3_priv.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/apps/snmp/snmpv3_priv.h	(revision 457)
@@ -0,0 +1,69 @@
+/**
+ * @file
+ * Additional SNMPv3 functionality RFC3414 and RFC3826 (internal API, do not use in client code).
+ */
+
+/*
+ * Copyright (c) 2016 Elias Oenal.
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * Author: Elias Oenal <lwip@eliasoenal.com>
+ */
+
+#ifndef LWIP_HDR_APPS_SNMP_V3_PRIV_H
+#define LWIP_HDR_APPS_SNMP_V3_PRIV_H
+
+#include "lwip/apps/snmp_opts.h"
+
+#if LWIP_SNMP && LWIP_SNMP_V3
+
+#include "lwip/apps/snmpv3.h"
+#include "snmp_pbuf_stream.h"
+
+/* According to RFC 3411 */
+#define SNMP_V3_MAX_ENGINE_ID_LENGTH  32
+#define SNMP_V3_MAX_USER_LENGTH       32
+
+#define SNMP_V3_MAX_AUTH_PARAM_LENGTH  12
+#define SNMP_V3_MAX_PRIV_PARAM_LENGTH  8
+
+#define SNMP_V3_MD5_LEN        16
+#define SNMP_V3_SHA_LEN        20
+
+typedef enum {
+  SNMP_V3_PRIV_MODE_DECRYPT = 0,
+  SNMP_V3_PRIV_MODE_ENCRYPT = 1
+} snmpv3_priv_mode_t;
+
+s32_t snmpv3_get_engine_boots_internal(void);
+err_t snmpv3_auth(struct snmp_pbuf_stream *stream, u16_t length, const u8_t *key, snmpv3_auth_algo_t algo, u8_t *hmac_out);
+err_t snmpv3_crypt(struct snmp_pbuf_stream *stream, u16_t length, const u8_t *key,
+                   const u8_t *priv_param, const u32_t engine_boots, const u32_t engine_time, snmpv3_priv_algo_t algo, snmpv3_priv_mode_t mode);
+err_t snmpv3_build_priv_param(u8_t *priv_param);
+void snmpv3_enginetime_timer(void *arg);
+
+#endif
+
+#endif /* LWIP_HDR_APPS_SNMP_V3_PRIV_H */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/apps/sntp/sntp.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/apps/sntp/sntp.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/apps/sntp/sntp.c	(revision 457)
@@ -0,0 +1,872 @@
+/**
+ * @file
+ * SNTP client module
+ */
+
+/*
+ * Copyright (c) 2007-2009 Fr辿d辿ric Bernon, Simon Goldschmidt
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Fr辿d辿ric Bernon, Simon Goldschmidt
+ */
+
+
+/**
+ * @defgroup sntp SNTP
+ * @ingroup apps
+ *
+ * This is simple "SNTP" client for the lwIP raw API.
+ * It is a minimal implementation of SNTPv4 as specified in RFC 4330.
+ *
+ * For a list of some public NTP servers, see this link:
+ * http://support.ntp.org/bin/view/Servers/NTPPoolServers
+ *
+ * @todo:
+ * - complete SNTP_CHECK_RESPONSE checks 3 and 4
+ */
+
+#include "lwip/apps/sntp.h"
+
+#include "lwip/opt.h"
+#include "lwip/timeouts.h"
+#include "lwip/udp.h"
+#include "lwip/dns.h"
+#include "lwip/ip_addr.h"
+#include "lwip/pbuf.h"
+#include "lwip/dhcp.h"
+
+#include <string.h>
+#include <time.h>
+
+#if LWIP_UDP
+
+/* Handle support for more than one server via SNTP_MAX_SERVERS */
+#if SNTP_MAX_SERVERS > 1
+#define SNTP_SUPPORT_MULTIPLE_SERVERS 1
+#else /* NTP_MAX_SERVERS > 1 */
+#define SNTP_SUPPORT_MULTIPLE_SERVERS 0
+#endif /* NTP_MAX_SERVERS > 1 */
+
+#ifndef SNTP_SUPPRESS_DELAY_CHECK
+#if SNTP_UPDATE_DELAY < 15000
+#error "SNTPv4 RFC 4330 enforces a minimum update time of 15 seconds (define SNTP_SUPPRESS_DELAY_CHECK to disable this error)!"
+#endif
+#endif
+
+/* the various debug levels for this file */
+#define SNTP_DEBUG_TRACE        (SNTP_DEBUG | LWIP_DBG_TRACE)
+#define SNTP_DEBUG_STATE        (SNTP_DEBUG | LWIP_DBG_STATE)
+#define SNTP_DEBUG_WARN         (SNTP_DEBUG | LWIP_DBG_LEVEL_WARNING)
+#define SNTP_DEBUG_WARN_STATE   (SNTP_DEBUG | LWIP_DBG_LEVEL_WARNING | LWIP_DBG_STATE)
+#define SNTP_DEBUG_SERIOUS      (SNTP_DEBUG | LWIP_DBG_LEVEL_SERIOUS)
+
+#define SNTP_ERR_KOD                1
+
+/* SNTP protocol defines */
+#define SNTP_MSG_LEN                48
+
+#define SNTP_OFFSET_LI_VN_MODE      0
+#define SNTP_LI_MASK                0xC0
+#define SNTP_LI_NO_WARNING          (0x00 << 6)
+#define SNTP_LI_LAST_MINUTE_61_SEC  (0x01 << 6)
+#define SNTP_LI_LAST_MINUTE_59_SEC  (0x02 << 6)
+#define SNTP_LI_ALARM_CONDITION     (0x03 << 6) /* (clock not synchronized) */
+
+#define SNTP_VERSION_MASK           0x38
+#define SNTP_VERSION                (4/* NTP Version 4*/<<3)
+
+#define SNTP_MODE_MASK              0x07
+#define SNTP_MODE_CLIENT            0x03
+#define SNTP_MODE_SERVER            0x04
+#define SNTP_MODE_BROADCAST         0x05
+
+#define SNTP_OFFSET_STRATUM         1
+#define SNTP_STRATUM_KOD            0x00
+
+#define SNTP_OFFSET_ORIGINATE_TIME  24
+#define SNTP_OFFSET_RECEIVE_TIME    32
+#define SNTP_OFFSET_TRANSMIT_TIME   40
+
+/* Number of seconds between 1970 and Feb 7, 2036 06:28:16 UTC (epoch 1) */
+#define DIFF_SEC_1970_2036          ((u32_t)2085978496L)
+
+/** Convert NTP timestamp fraction to microseconds.
+ */
+#ifndef SNTP_FRAC_TO_US
+# if LWIP_HAVE_INT64
+#  define SNTP_FRAC_TO_US(f)        ((u32_t)(((u64_t)(f) * 1000000UL) >> 32))
+# else
+#  define SNTP_FRAC_TO_US(f)        ((u32_t)(f) / 4295)
+# endif
+#endif /* !SNTP_FRAC_TO_US */
+
+/* Configure behaviour depending on native, microsecond or second precision.
+ * Treat NTP timestamps as signed two's-complement integers. This way,
+ * timestamps that have the MSB set simply become negative offsets from
+ * the epoch (Feb 7, 2036 06:28:16 UTC). Representable dates range from
+ * 1968 to 2104.
+ */
+#ifndef SNTP_SET_SYSTEM_TIME_NTP
+# ifdef SNTP_SET_SYSTEM_TIME_US
+#  define SNTP_SET_SYSTEM_TIME_NTP(s, f) \
+    SNTP_SET_SYSTEM_TIME_US((u32_t)((s) + DIFF_SEC_1970_2036), SNTP_FRAC_TO_US(f))
+# else
+#  define SNTP_SET_SYSTEM_TIME_NTP(s, f) \
+    SNTP_SET_SYSTEM_TIME((u32_t)((s) + DIFF_SEC_1970_2036))
+# endif
+#endif /* !SNTP_SET_SYSTEM_TIME_NTP */
+
+/* Get the system time either natively as NTP timestamp or convert from
+ * Unix time in seconds and microseconds. Take care to avoid overflow if the
+ * microsecond value is at the maximum of 999999. Also add 0.5 us fudge to
+ * avoid special values like 0, and to mask round-off errors that would
+ * otherwise break round-trip conversion identity.
+ */
+#ifndef SNTP_GET_SYSTEM_TIME_NTP
+# define SNTP_GET_SYSTEM_TIME_NTP(s, f) do { \
+    u32_t sec_, usec_; \
+    SNTP_GET_SYSTEM_TIME(sec_, usec_); \
+    (s) = (s32_t)(sec_ - DIFF_SEC_1970_2036); \
+    (f) = usec_ * 4295 - ((usec_ * 2143) >> 16) + 2147; \
+  } while (0)
+#endif /* !SNTP_GET_SYSTEM_TIME_NTP */
+
+/* Start offset of the timestamps to extract from the SNTP packet */
+#define SNTP_OFFSET_TIMESTAMPS \
+    (SNTP_OFFSET_TRANSMIT_TIME + 8 - sizeof(struct sntp_timestamps))
+
+/* Round-trip delay arithmetic helpers */
+#if SNTP_COMP_ROUNDTRIP
+# if !LWIP_HAVE_INT64
+#  error "SNTP round-trip delay compensation requires 64-bit arithmetic"
+# endif
+# define SNTP_SEC_FRAC_TO_S64(s, f) \
+    ((s64_t)(((u64_t)(s) << 32) | (u32_t)(f)))
+# define SNTP_TIMESTAMP_TO_S64(t) \
+    SNTP_SEC_FRAC_TO_S64(lwip_ntohl((t).sec), lwip_ntohl((t).frac))
+#endif /* SNTP_COMP_ROUNDTRIP */
+
+/**
+ * 64-bit NTP timestamp, in network byte order.
+ */
+struct sntp_time {
+  u32_t sec;
+  u32_t frac;
+};
+
+/**
+ * Timestamps to be extracted from the NTP header.
+ */
+struct sntp_timestamps {
+#if SNTP_COMP_ROUNDTRIP || SNTP_CHECK_RESPONSE >= 2
+  struct sntp_time orig;
+  struct sntp_time recv;
+#endif
+  struct sntp_time xmit;
+};
+
+/**
+ * SNTP packet format (without optional fields)
+ * Timestamps are coded as 64 bits:
+ * - signed 32 bits seconds since Feb 07, 2036, 06:28:16 UTC (epoch 1)
+ * - unsigned 32 bits seconds fraction (2^32 = 1 second)
+ */
+#ifdef PACK_STRUCT_USE_INCLUDES
+#  include "arch/bpstruct.h"
+#endif
+PACK_STRUCT_BEGIN
+struct sntp_msg {
+  PACK_STRUCT_FLD_8(u8_t  li_vn_mode);
+  PACK_STRUCT_FLD_8(u8_t  stratum);
+  PACK_STRUCT_FLD_8(u8_t  poll);
+  PACK_STRUCT_FLD_8(u8_t  precision);
+  PACK_STRUCT_FIELD(u32_t root_delay);
+  PACK_STRUCT_FIELD(u32_t root_dispersion);
+  PACK_STRUCT_FIELD(u32_t reference_identifier);
+  PACK_STRUCT_FIELD(u32_t reference_timestamp[2]);
+  PACK_STRUCT_FIELD(u32_t originate_timestamp[2]);
+  PACK_STRUCT_FIELD(u32_t receive_timestamp[2]);
+  PACK_STRUCT_FIELD(u32_t transmit_timestamp[2]);
+} PACK_STRUCT_STRUCT;
+PACK_STRUCT_END
+#ifdef PACK_STRUCT_USE_INCLUDES
+#  include "arch/epstruct.h"
+#endif
+
+/* function prototypes */
+static void sntp_request(void *arg);
+
+/** The operating mode */
+static u8_t sntp_opmode;
+
+/** The UDP pcb used by the SNTP client */
+static struct udp_pcb *sntp_pcb;
+/** Names/Addresses of servers */
+struct sntp_server {
+#if SNTP_SERVER_DNS
+  const char *name;
+#endif /* SNTP_SERVER_DNS */
+  ip_addr_t addr;
+#if SNTP_MONITOR_SERVER_REACHABILITY
+  /** Reachability shift register as described in RFC 5905 */
+  u8_t reachability;
+#endif /* SNTP_MONITOR_SERVER_REACHABILITY */
+};
+static struct sntp_server sntp_servers[SNTP_MAX_SERVERS];
+
+#if SNTP_GET_SERVERS_FROM_DHCP
+static u8_t sntp_set_servers_from_dhcp;
+#endif /* SNTP_GET_SERVERS_FROM_DHCP */
+#if SNTP_SUPPORT_MULTIPLE_SERVERS
+/** The currently used server (initialized to 0) */
+static u8_t sntp_current_server;
+#else /* SNTP_SUPPORT_MULTIPLE_SERVERS */
+#define sntp_current_server 0
+#endif /* SNTP_SUPPORT_MULTIPLE_SERVERS */
+
+#if SNTP_RETRY_TIMEOUT_EXP
+#define SNTP_RESET_RETRY_TIMEOUT() sntp_retry_timeout = SNTP_RETRY_TIMEOUT
+/** Retry time, initialized with SNTP_RETRY_TIMEOUT and doubled with each retry. */
+static u32_t sntp_retry_timeout;
+#else /* SNTP_RETRY_TIMEOUT_EXP */
+#define SNTP_RESET_RETRY_TIMEOUT()
+#define sntp_retry_timeout SNTP_RETRY_TIMEOUT
+#endif /* SNTP_RETRY_TIMEOUT_EXP */
+
+#if SNTP_CHECK_RESPONSE >= 1
+/** Saves the last server address to compare with response */
+static ip_addr_t sntp_last_server_address;
+#endif /* SNTP_CHECK_RESPONSE >= 1 */
+
+#if SNTP_CHECK_RESPONSE >= 2
+/** Saves the last timestamp sent (which is sent back by the server)
+ * to compare against in response. Stored in network byte order. */
+static struct sntp_time sntp_last_timestamp_sent;
+#endif /* SNTP_CHECK_RESPONSE >= 2 */
+
+#if defined(LWIP_DEBUG) && !defined(sntp_format_time)
+/* Debug print helper. */
+static const char *
+sntp_format_time(s32_t sec)
+{
+  time_t ut;
+  ut = (u32_t)((u32_t)sec + DIFF_SEC_1970_2036);
+  return ctime(&ut);
+}
+#endif /* LWIP_DEBUG && !sntp_format_time */
+
+/**
+ * SNTP processing of received timestamp
+ */
+static void
+sntp_process(const struct sntp_timestamps *timestamps)
+{
+  s32_t sec;
+  u32_t frac;
+
+  sec  = (s32_t)lwip_ntohl(timestamps->xmit.sec);
+  frac = lwip_ntohl(timestamps->xmit.frac);
+
+#if SNTP_COMP_ROUNDTRIP
+# if SNTP_CHECK_RESPONSE >= 2
+  if (timestamps->recv.sec != 0 || timestamps->recv.frac != 0)
+# endif
+  {
+    s32_t dest_sec;
+    u32_t dest_frac;
+    u32_t step_sec;
+
+    /* Get the destination time stamp, i.e. the current system time */
+    SNTP_GET_SYSTEM_TIME_NTP(dest_sec, dest_frac);
+
+    step_sec = (dest_sec < sec) ? ((u32_t)sec - (u32_t)dest_sec)
+               : ((u32_t)dest_sec - (u32_t)sec);
+    /* In order to avoid overflows, skip the compensation if the clock step
+     * is larger than about 34 years. */
+    if ((step_sec >> 30) == 0) {
+      s64_t t1, t2, t3, t4;
+
+      t4 = SNTP_SEC_FRAC_TO_S64(dest_sec, dest_frac);
+      t3 = SNTP_SEC_FRAC_TO_S64(sec, frac);
+      t1 = SNTP_TIMESTAMP_TO_S64(timestamps->orig);
+      t2 = SNTP_TIMESTAMP_TO_S64(timestamps->recv);
+      /* Clock offset calculation according to RFC 4330 */
+      t4 += ((t2 - t1) + (t3 - t4)) / 2;
+
+      sec  = (s32_t)((u64_t)t4 >> 32);
+      frac = (u32_t)((u64_t)t4);
+    }
+  }
+#endif /* SNTP_COMP_ROUNDTRIP */
+
+  SNTP_SET_SYSTEM_TIME_NTP(sec, frac);
+  LWIP_UNUSED_ARG(frac); /* might be unused if only seconds are set */
+  LWIP_DEBUGF(SNTP_DEBUG_TRACE, ("sntp_process: %s, %" U32_F " us\n",
+                                 sntp_format_time(sec), SNTP_FRAC_TO_US(frac)));
+}
+
+/**
+ * Initialize request struct to be sent to server.
+ */
+static void
+sntp_initialize_request(struct sntp_msg *req)
+{
+  memset(req, 0, SNTP_MSG_LEN);
+  req->li_vn_mode = SNTP_LI_NO_WARNING | SNTP_VERSION | SNTP_MODE_CLIENT;
+
+#if SNTP_CHECK_RESPONSE >= 2 || SNTP_COMP_ROUNDTRIP
+  {
+    s32_t secs;
+    u32_t sec, frac;
+    /* Get the transmit timestamp */
+    SNTP_GET_SYSTEM_TIME_NTP(secs, frac);
+    sec  = lwip_htonl((u32_t)secs);
+    frac = lwip_htonl(frac);
+
+# if SNTP_CHECK_RESPONSE >= 2
+    sntp_last_timestamp_sent.sec  = sec;
+    sntp_last_timestamp_sent.frac = frac;
+# endif
+    req->transmit_timestamp[0] = sec;
+    req->transmit_timestamp[1] = frac;
+  }
+#endif /* SNTP_CHECK_RESPONSE >= 2 || SNTP_COMP_ROUNDTRIP */
+}
+
+/**
+ * Retry: send a new request (and increase retry timeout).
+ *
+ * @param arg is unused (only necessary to conform to sys_timeout)
+ */
+static void
+sntp_retry(void *arg)
+{
+  LWIP_UNUSED_ARG(arg);
+
+  LWIP_DEBUGF(SNTP_DEBUG_STATE, ("sntp_retry: Next request will be sent in %"U32_F" ms\n",
+                                 sntp_retry_timeout));
+
+  /* set up a timer to send a retry and increase the retry delay */
+  sys_timeout(sntp_retry_timeout, sntp_request, NULL);
+
+#if SNTP_RETRY_TIMEOUT_EXP
+  {
+    u32_t new_retry_timeout;
+    /* increase the timeout for next retry */
+    new_retry_timeout = sntp_retry_timeout << 1;
+    /* limit to maximum timeout and prevent overflow */
+    if ((new_retry_timeout <= SNTP_RETRY_TIMEOUT_MAX) &&
+        (new_retry_timeout > sntp_retry_timeout)) {
+      sntp_retry_timeout = new_retry_timeout;
+    }
+  }
+#endif /* SNTP_RETRY_TIMEOUT_EXP */
+}
+
+#if SNTP_SUPPORT_MULTIPLE_SERVERS
+/**
+ * If Kiss-of-Death is received (or another packet parsing error),
+ * try the next server or retry the current server and increase the retry
+ * timeout if only one server is available.
+ * (implicitly, SNTP_MAX_SERVERS > 1)
+ *
+ * @param arg is unused (only necessary to conform to sys_timeout)
+ */
+static void
+sntp_try_next_server(void *arg)
+{
+  u8_t old_server, i;
+  LWIP_UNUSED_ARG(arg);
+
+  old_server = sntp_current_server;
+  for (i = 0; i < SNTP_MAX_SERVERS - 1; i++) {
+    sntp_current_server++;
+    if (sntp_current_server >= SNTP_MAX_SERVERS) {
+      sntp_current_server = 0;
+    }
+    if (!ip_addr_isany(&sntp_servers[sntp_current_server].addr)
+#if SNTP_SERVER_DNS
+        || (sntp_servers[sntp_current_server].name != NULL)
+#endif
+       ) {
+      LWIP_DEBUGF(SNTP_DEBUG_STATE, ("sntp_try_next_server: Sending request to server %"U16_F"\n",
+                                     (u16_t)sntp_current_server));
+      /* new server: reset retry timeout */
+      SNTP_RESET_RETRY_TIMEOUT();
+      /* instantly send a request to the next server */
+      sntp_request(NULL);
+      return;
+    }
+  }
+  /* no other valid server found */
+  sntp_current_server = old_server;
+  sntp_retry(NULL);
+}
+#else /* SNTP_SUPPORT_MULTIPLE_SERVERS */
+/* Always retry on error if only one server is supported */
+#define sntp_try_next_server    sntp_retry
+#endif /* SNTP_SUPPORT_MULTIPLE_SERVERS */
+
+/** UDP recv callback for the sntp pcb */
+static void
+sntp_recv(void *arg, struct udp_pcb *pcb, struct pbuf *p, const ip_addr_t *addr, u16_t port)
+{
+  struct sntp_timestamps timestamps;
+  u8_t mode;
+  u8_t stratum;
+  err_t err;
+
+  LWIP_UNUSED_ARG(arg);
+  LWIP_UNUSED_ARG(pcb);
+
+  err = ERR_ARG;
+#if SNTP_CHECK_RESPONSE >= 1
+  /* check server address and port */
+  if (((sntp_opmode != SNTP_OPMODE_POLL) || ip_addr_cmp(addr, &sntp_last_server_address)) &&
+      (port == SNTP_PORT))
+#else /* SNTP_CHECK_RESPONSE >= 1 */
+  LWIP_UNUSED_ARG(addr);
+  LWIP_UNUSED_ARG(port);
+#endif /* SNTP_CHECK_RESPONSE >= 1 */
+  {
+    /* process the response */
+    if (p->tot_len == SNTP_MSG_LEN) {
+      mode = pbuf_get_at(p, SNTP_OFFSET_LI_VN_MODE) & SNTP_MODE_MASK;
+      /* if this is a SNTP response... */
+      if (((sntp_opmode == SNTP_OPMODE_POLL)       && (mode == SNTP_MODE_SERVER)) ||
+          ((sntp_opmode == SNTP_OPMODE_LISTENONLY) && (mode == SNTP_MODE_BROADCAST))) {
+        stratum = pbuf_get_at(p, SNTP_OFFSET_STRATUM);
+
+        if (stratum == SNTP_STRATUM_KOD) {
+          /* Kiss-of-death packet. Use another server or increase UPDATE_DELAY. */
+          err = SNTP_ERR_KOD;
+          LWIP_DEBUGF(SNTP_DEBUG_STATE, ("sntp_recv: Received Kiss-of-Death\n"));
+        } else {
+          pbuf_copy_partial(p, &timestamps, sizeof(timestamps), SNTP_OFFSET_TIMESTAMPS);
+#if SNTP_CHECK_RESPONSE >= 2
+          /* check originate_timetamp against sntp_last_timestamp_sent */
+          if (timestamps.orig.sec != sntp_last_timestamp_sent.sec ||
+              timestamps.orig.frac != sntp_last_timestamp_sent.frac) {
+            LWIP_DEBUGF(SNTP_DEBUG_WARN,
+                        ("sntp_recv: Invalid originate timestamp in response\n"));
+          } else
+#endif /* SNTP_CHECK_RESPONSE >= 2 */
+            /* @todo: add code for SNTP_CHECK_RESPONSE >= 3 and >= 4 here */
+          {
+            /* correct answer */
+            err = ERR_OK;
+          }
+        }
+      } else {
+        LWIP_DEBUGF(SNTP_DEBUG_WARN, ("sntp_recv: Invalid mode in response: %"U16_F"\n", (u16_t)mode));
+        /* wait for correct response */
+        err = ERR_TIMEOUT;
+      }
+    } else {
+      LWIP_DEBUGF(SNTP_DEBUG_WARN, ("sntp_recv: Invalid packet length: %"U16_F"\n", p->tot_len));
+    }
+  }
+#if SNTP_CHECK_RESPONSE >= 1
+  else {
+    /* packet from wrong remote address or port, wait for correct response */
+    err = ERR_TIMEOUT;
+  }
+#endif /* SNTP_CHECK_RESPONSE >= 1 */
+
+  pbuf_free(p);
+
+  if (err == ERR_OK) {
+    /* correct packet received: process it it */
+    sntp_process(&timestamps);
+
+#if SNTP_MONITOR_SERVER_REACHABILITY
+    /* indicate that server responded */
+    sntp_servers[sntp_current_server].reachability |= 1;
+#endif /* SNTP_MONITOR_SERVER_REACHABILITY */
+    /* Set up timeout for next request (only if poll response was received)*/
+    if (sntp_opmode == SNTP_OPMODE_POLL) {
+      u32_t sntp_update_delay;
+      sys_untimeout(sntp_try_next_server, NULL);
+      sys_untimeout(sntp_request, NULL);
+
+      /* Correct response, reset retry timeout */
+      SNTP_RESET_RETRY_TIMEOUT();
+
+      sntp_update_delay = (u32_t)SNTP_UPDATE_DELAY;
+      sys_timeout(sntp_update_delay, sntp_request, NULL);
+      LWIP_DEBUGF(SNTP_DEBUG_STATE, ("sntp_recv: Scheduled next time request: %"U32_F" ms\n",
+                                     sntp_update_delay));
+    }
+  } else if (err == SNTP_ERR_KOD) {
+    /* KOD errors are only processed in case of an explicit poll response */
+    if (sntp_opmode == SNTP_OPMODE_POLL) {
+      /* Kiss-of-death packet. Use another server or increase UPDATE_DELAY. */
+      sntp_try_next_server(NULL);
+    }
+  } else {
+    /* ignore any broken packet, poll mode: retry after timeout to avoid flooding */
+  }
+}
+
+/** Actually send an sntp request to a server.
+ *
+ * @param server_addr resolved IP address of the SNTP server
+ */
+static void
+sntp_send_request(const ip_addr_t *server_addr)
+{
+  struct pbuf *p;
+
+  LWIP_ASSERT("server_addr != NULL", server_addr != NULL);
+
+  p = pbuf_alloc(PBUF_TRANSPORT, SNTP_MSG_LEN, PBUF_RAM);
+  if (p != NULL) {
+    struct sntp_msg *sntpmsg = (struct sntp_msg *)p->payload;
+    LWIP_DEBUGF(SNTP_DEBUG_STATE, ("sntp_send_request: Sending request to server\n"));
+    /* initialize request message */
+    sntp_initialize_request(sntpmsg);
+    /* send request */
+    udp_sendto(sntp_pcb, p, server_addr, SNTP_PORT);
+    /* free the pbuf after sending it */
+    pbuf_free(p);
+#if SNTP_MONITOR_SERVER_REACHABILITY
+    /* indicate new packet has been sent */
+    sntp_servers[sntp_current_server].reachability <<= 1;
+#endif /* SNTP_MONITOR_SERVER_REACHABILITY */
+    /* set up receive timeout: try next server or retry on timeout */
+    sys_timeout((u32_t)SNTP_RECV_TIMEOUT, sntp_try_next_server, NULL);
+#if SNTP_CHECK_RESPONSE >= 1
+    /* save server address to verify it in sntp_recv */
+    ip_addr_copy(sntp_last_server_address, *server_addr);
+#endif /* SNTP_CHECK_RESPONSE >= 1 */
+  } else {
+    LWIP_DEBUGF(SNTP_DEBUG_SERIOUS, ("sntp_send_request: Out of memory, trying again in %"U32_F" ms\n",
+                                     (u32_t)SNTP_RETRY_TIMEOUT));
+    /* out of memory: set up a timer to send a retry */
+    sys_timeout((u32_t)SNTP_RETRY_TIMEOUT, sntp_request, NULL);
+  }
+}
+
+#if SNTP_SERVER_DNS
+/**
+ * DNS found callback when using DNS names as server address.
+ */
+static void
+sntp_dns_found(const char *hostname, const ip_addr_t *ipaddr, void *arg)
+{
+  LWIP_UNUSED_ARG(hostname);
+  LWIP_UNUSED_ARG(arg);
+
+  if (ipaddr != NULL) {
+    /* Address resolved, send request */
+    LWIP_DEBUGF(SNTP_DEBUG_STATE, ("sntp_dns_found: Server address resolved, sending request\n"));
+    sntp_servers[sntp_current_server].addr = *ipaddr;
+    sntp_send_request(ipaddr);
+  } else {
+    /* DNS resolving failed -> try another server */
+    LWIP_DEBUGF(SNTP_DEBUG_WARN_STATE, ("sntp_dns_found: Failed to resolve server address resolved, trying next server\n"));
+    sntp_try_next_server(NULL);
+  }
+}
+#endif /* SNTP_SERVER_DNS */
+
+/**
+ * Send out an sntp request.
+ *
+ * @param arg is unused (only necessary to conform to sys_timeout)
+ */
+static void
+sntp_request(void *arg)
+{
+  ip_addr_t sntp_server_address;
+  err_t err;
+
+  LWIP_UNUSED_ARG(arg);
+
+  /* initialize SNTP server address */
+#if SNTP_SERVER_DNS
+  if (sntp_servers[sntp_current_server].name) {
+    /* always resolve the name and rely on dns-internal caching & timeout */
+    ip_addr_set_zero(&sntp_servers[sntp_current_server].addr);
+    err = dns_gethostbyname(sntp_servers[sntp_current_server].name, &sntp_server_address,
+                            sntp_dns_found, NULL);
+    if (err == ERR_INPROGRESS) {
+      /* DNS request sent, wait for sntp_dns_found being called */
+      LWIP_DEBUGF(SNTP_DEBUG_STATE, ("sntp_request: Waiting for server address to be resolved.\n"));
+      return;
+    } else if (err == ERR_OK) {
+      sntp_servers[sntp_current_server].addr = sntp_server_address;
+    }
+  } else
+#endif /* SNTP_SERVER_DNS */
+  {
+    sntp_server_address = sntp_servers[sntp_current_server].addr;
+    err = (ip_addr_isany_val(sntp_server_address)) ? ERR_ARG : ERR_OK;
+  }
+
+  if (err == ERR_OK) {
+    LWIP_DEBUGF(SNTP_DEBUG_TRACE, ("sntp_request: current server address is %s\n",
+                                   ipaddr_ntoa(&sntp_server_address)));
+    sntp_send_request(&sntp_server_address);
+  } else {
+    /* address conversion failed, try another server */
+    LWIP_DEBUGF(SNTP_DEBUG_WARN_STATE, ("sntp_request: Invalid server address, trying next server.\n"));
+    sys_timeout((u32_t)SNTP_RETRY_TIMEOUT, sntp_try_next_server, NULL);
+  }
+}
+
+/**
+ * @ingroup sntp
+ * Initialize this module.
+ * Send out request instantly or after SNTP_STARTUP_DELAY(_FUNC).
+ */
+void
+sntp_init(void)
+{
+  /* LWIP_ASSERT_CORE_LOCKED(); is checked by udp_new() */
+
+#ifdef SNTP_SERVER_ADDRESS
+#if SNTP_SERVER_DNS
+  sntp_setservername(0, SNTP_SERVER_ADDRESS);
+#else
+#error SNTP_SERVER_ADDRESS string not supported SNTP_SERVER_DNS==0
+#endif
+#endif /* SNTP_SERVER_ADDRESS */
+
+  if (sntp_pcb == NULL) {
+    sntp_pcb = udp_new_ip_type(IPADDR_TYPE_ANY);
+    LWIP_ASSERT("Failed to allocate udp pcb for sntp client", sntp_pcb != NULL);
+    if (sntp_pcb != NULL) {
+      udp_recv(sntp_pcb, sntp_recv, NULL);
+
+      if (sntp_opmode == SNTP_OPMODE_POLL) {
+        SNTP_RESET_RETRY_TIMEOUT();
+#if SNTP_STARTUP_DELAY
+        sys_timeout((u32_t)SNTP_STARTUP_DELAY_FUNC, sntp_request, NULL);
+#else
+        sntp_request(NULL);
+#endif
+      } else if (sntp_opmode == SNTP_OPMODE_LISTENONLY) {
+        ip_set_option(sntp_pcb, SOF_BROADCAST);
+        udp_bind(sntp_pcb, IP_ANY_TYPE, SNTP_PORT);
+      }
+    }
+  }
+}
+
+/**
+ * @ingroup sntp
+ * Stop this module.
+ */
+void
+sntp_stop(void)
+{
+  LWIP_ASSERT_CORE_LOCKED();
+  if (sntp_pcb != NULL) {
+#if SNTP_MONITOR_SERVER_REACHABILITY
+    u8_t i;
+    for (i = 0; i < SNTP_MAX_SERVERS; i++) {
+      sntp_servers[i].reachability = 0;
+    }
+#endif /* SNTP_MONITOR_SERVER_REACHABILITY */
+    sys_untimeout(sntp_request, NULL);
+    sys_untimeout(sntp_try_next_server, NULL);
+    udp_remove(sntp_pcb);
+    sntp_pcb = NULL;
+  }
+}
+
+/**
+ * @ingroup sntp
+ * Get enabled state.
+ */
+u8_t sntp_enabled(void)
+{
+  return (sntp_pcb != NULL) ? 1 : 0;
+}
+
+/**
+ * @ingroup sntp
+ * Sets the operating mode.
+ * @param operating_mode one of the available operating modes
+ */
+void
+sntp_setoperatingmode(u8_t operating_mode)
+{
+  LWIP_ASSERT_CORE_LOCKED();
+  LWIP_ASSERT("Invalid operating mode", operating_mode <= SNTP_OPMODE_LISTENONLY);
+  LWIP_ASSERT("Operating mode must not be set while SNTP client is running", sntp_pcb == NULL);
+  sntp_opmode = operating_mode;
+}
+
+/**
+ * @ingroup sntp
+ * Gets the operating mode.
+ */
+u8_t
+sntp_getoperatingmode(void)
+{
+  return sntp_opmode;
+}
+
+#if SNTP_MONITOR_SERVER_REACHABILITY
+/**
+ * @ingroup sntp
+ * Gets the server reachability shift register as described in RFC 5905.
+ *
+ * @param idx the index of the NTP server
+ */
+u8_t
+sntp_getreachability(u8_t idx)
+{
+  if (idx < SNTP_MAX_SERVERS) {
+    return sntp_servers[idx].reachability;
+  }
+  return 0;
+}
+#endif /* SNTP_MONITOR_SERVER_REACHABILITY */
+
+#if SNTP_GET_SERVERS_FROM_DHCP
+/**
+ * Config SNTP server handling by IP address, name, or DHCP; clear table
+ * @param set_servers_from_dhcp enable or disable getting server addresses from dhcp
+ */
+void
+sntp_servermode_dhcp(int set_servers_from_dhcp)
+{
+  u8_t new_mode = set_servers_from_dhcp ? 1 : 0;
+  LWIP_ASSERT_CORE_LOCKED();
+  if (sntp_set_servers_from_dhcp != new_mode) {
+    sntp_set_servers_from_dhcp = new_mode;
+  }
+}
+#endif /* SNTP_GET_SERVERS_FROM_DHCP */
+
+/**
+ * @ingroup sntp
+ * Initialize one of the NTP servers by IP address
+ *
+ * @param idx the index of the NTP server to set must be < SNTP_MAX_SERVERS
+ * @param server IP address of the NTP server to set
+ */
+void
+sntp_setserver(u8_t idx, const ip_addr_t *server)
+{
+  LWIP_ASSERT_CORE_LOCKED();
+  if (idx < SNTP_MAX_SERVERS) {
+    if (server != NULL) {
+      sntp_servers[idx].addr = (*server);
+    } else {
+      ip_addr_set_zero(&sntp_servers[idx].addr);
+    }
+#if SNTP_SERVER_DNS
+    sntp_servers[idx].name = NULL;
+#endif
+  }
+}
+
+#if LWIP_DHCP && SNTP_GET_SERVERS_FROM_DHCP
+/**
+ * Initialize one of the NTP servers by IP address, required by DHCP
+ *
+ * @param num the index of the NTP server to set must be < SNTP_MAX_SERVERS
+ * @param server IP address of the NTP server to set
+ */
+void
+dhcp_set_ntp_servers(u8_t num, const ip4_addr_t *server)
+{
+  LWIP_DEBUGF(SNTP_DEBUG_TRACE, ("sntp: %s %u.%u.%u.%u as NTP server #%u via DHCP\n",
+                                 (sntp_set_servers_from_dhcp ? "Got" : "Rejected"),
+                                 num ? ip4_addr1(server) : 0,
+                                 num ? ip4_addr2(server) : 0,
+                                 num ? ip4_addr3(server) : 0,
+                                 num ? ip4_addr4(server) : 0, num));
+  if (sntp_set_servers_from_dhcp && num) {
+    u8_t i;
+    for (i = 0; (i < num) && (i < SNTP_MAX_SERVERS); i++) {
+      ip_addr_t addr;
+      ip_addr_copy_from_ip4(addr, server[i]);
+      sntp_setserver(i, &addr);
+    }
+    for (i = num; i < SNTP_MAX_SERVERS; i++) {
+      sntp_setserver(i, NULL);
+    }
+  }
+}
+#endif /* LWIP_DHCP && SNTP_GET_SERVERS_FROM_DHCP */
+
+/**
+ * @ingroup sntp
+ * Obtain one of the currently configured by IP address (or DHCP) NTP servers
+ *
+ * @param idx the index of the NTP server
+ * @return IP address of the indexed NTP server or "ip_addr_any" if the NTP
+ *         server has not been configured by address (or at all).
+ */
+const ip_addr_t *
+sntp_getserver(u8_t idx)
+{
+  if (idx < SNTP_MAX_SERVERS) {
+    return &sntp_servers[idx].addr;
+  }
+  return IP_ADDR_ANY;
+}
+
+#if SNTP_SERVER_DNS
+/**
+ * Initialize one of the NTP servers by name
+ *
+ * @param idx the index of the NTP server to set must be < SNTP_MAX_SERVERS
+ * @param server DNS name of the NTP server to set, to be resolved at contact time
+ */
+void
+sntp_setservername(u8_t idx, const char *server)
+{
+  LWIP_ASSERT_CORE_LOCKED();
+  if (idx < SNTP_MAX_SERVERS) {
+    sntp_servers[idx].name = server;
+  }
+}
+
+/**
+ * Obtain one of the currently configured by name NTP servers.
+ *
+ * @param idx the index of the NTP server
+ * @return IP address of the indexed NTP server or NULL if the NTP
+ *         server has not been configured by name (or at all)
+ */
+const char *
+sntp_getservername(u8_t idx)
+{
+  if (idx < SNTP_MAX_SERVERS) {
+    return sntp_servers[idx].name;
+  }
+  return NULL;
+}
+#endif /* SNTP_SERVER_DNS */
+
+#endif /* LWIP_UDP */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/apps/tftp/tftp_server.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/apps/tftp/tftp_server.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/apps/tftp/tftp_server.c	(revision 457)
@@ -0,0 +1,435 @@
+/**
+ *
+ * @file tftp_server.c
+ *
+ * @author   Logan Gunthorpe <logang@deltatee.com>
+ *           Dirk Ziegelmeier <dziegel@gmx.de>
+ *
+ * @brief    Trivial File Transfer Protocol (RFC 1350)
+ *
+ * Copyright (c) Deltatee Enterprises Ltd. 2013
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * Author: Logan Gunthorpe <logang@deltatee.com>
+ *         Dirk Ziegelmeier <dziegel@gmx.de>
+ *
+ */
+
+/**
+ * @defgroup tftp TFTP server
+ * @ingroup apps
+ *
+ * This is simple TFTP server for the lwIP raw API.
+ */
+
+#include "lwip/apps/tftp_server.h"
+
+#if LWIP_UDP
+
+#include "lwip/udp.h"
+#include "lwip/timeouts.h"
+#include "lwip/debug.h"
+
+#define TFTP_MAX_PAYLOAD_SIZE 512
+#define TFTP_HEADER_LENGTH    4
+
+#define TFTP_RRQ   1
+#define TFTP_WRQ   2
+#define TFTP_DATA  3
+#define TFTP_ACK   4
+#define TFTP_ERROR 5
+
+enum tftp_error {
+  TFTP_ERROR_FILE_NOT_FOUND    = 1,
+  TFTP_ERROR_ACCESS_VIOLATION  = 2,
+  TFTP_ERROR_DISK_FULL         = 3,
+  TFTP_ERROR_ILLEGAL_OPERATION = 4,
+  TFTP_ERROR_UNKNOWN_TRFR_ID   = 5,
+  TFTP_ERROR_FILE_EXISTS       = 6,
+  TFTP_ERROR_NO_SUCH_USER      = 7
+};
+
+#include <string.h>
+
+struct tftp_state {
+  const struct tftp_context *ctx;
+  void *handle;
+  struct pbuf *last_data;
+  struct udp_pcb *upcb;
+  ip_addr_t addr;
+  u16_t port;
+  int timer;
+  int last_pkt;
+  u16_t blknum;
+  u8_t retries;
+  u8_t mode_write;
+};
+
+static struct tftp_state tftp_state;
+
+static void tftp_tmr(void *arg);
+
+static void
+close_handle(void)
+{
+  tftp_state.port = 0;
+  ip_addr_set_any(0, &tftp_state.addr);
+
+  if (tftp_state.last_data != NULL) {
+    pbuf_free(tftp_state.last_data);
+    tftp_state.last_data = NULL;
+  }
+
+  sys_untimeout(tftp_tmr, NULL);
+
+  if (tftp_state.handle) {
+    tftp_state.ctx->close(tftp_state.handle);
+    tftp_state.handle = NULL;
+    LWIP_DEBUGF(TFTP_DEBUG | LWIP_DBG_STATE, ("tftp: closing\n"));
+  }
+}
+
+static void
+send_error(const ip_addr_t *addr, u16_t port, enum tftp_error code, const char *str)
+{
+  int str_length = strlen(str);
+  struct pbuf *p;
+  u16_t *payload;
+
+  p = pbuf_alloc(PBUF_TRANSPORT, (u16_t)(TFTP_HEADER_LENGTH + str_length + 1), PBUF_RAM);
+  if (p == NULL) {
+    return;
+  }
+
+  payload = (u16_t *) p->payload;
+  payload[0] = PP_HTONS(TFTP_ERROR);
+  payload[1] = lwip_htons(code);
+  MEMCPY(&payload[2], str, str_length + 1);
+
+  udp_sendto(tftp_state.upcb, p, addr, port);
+  pbuf_free(p);
+}
+
+static void
+send_ack(u16_t blknum)
+{
+  struct pbuf *p;
+  u16_t *payload;
+
+  p = pbuf_alloc(PBUF_TRANSPORT, TFTP_HEADER_LENGTH, PBUF_RAM);
+  if (p == NULL) {
+    return;
+  }
+  payload = (u16_t *) p->payload;
+
+  payload[0] = PP_HTONS(TFTP_ACK);
+  payload[1] = lwip_htons(blknum);
+  udp_sendto(tftp_state.upcb, p, &tftp_state.addr, tftp_state.port);
+  pbuf_free(p);
+}
+
+static void
+resend_data(void)
+{
+  struct pbuf *p = pbuf_alloc(PBUF_TRANSPORT, tftp_state.last_data->len, PBUF_RAM);
+  if (p == NULL) {
+    return;
+  }
+
+  if (pbuf_copy(p, tftp_state.last_data) != ERR_OK) {
+    pbuf_free(p);
+    return;
+  }
+
+  udp_sendto(tftp_state.upcb, p, &tftp_state.addr, tftp_state.port);
+  pbuf_free(p);
+}
+
+static void
+send_data(void)
+{
+  u16_t *payload;
+  int ret;
+
+  if (tftp_state.last_data != NULL) {
+    pbuf_free(tftp_state.last_data);
+  }
+
+  tftp_state.last_data = pbuf_alloc(PBUF_TRANSPORT, TFTP_HEADER_LENGTH + TFTP_MAX_PAYLOAD_SIZE, PBUF_RAM);
+  if (tftp_state.last_data == NULL) {
+    return;
+  }
+
+  payload = (u16_t *) tftp_state.last_data->payload;
+  payload[0] = PP_HTONS(TFTP_DATA);
+  payload[1] = lwip_htons(tftp_state.blknum);
+
+  ret = tftp_state.ctx->read(tftp_state.handle, &payload[2], TFTP_MAX_PAYLOAD_SIZE);
+  if (ret < 0) {
+    send_error(&tftp_state.addr, tftp_state.port, TFTP_ERROR_ACCESS_VIOLATION, "Error occured while reading the file.");
+    close_handle();
+    return;
+  }
+
+  pbuf_realloc(tftp_state.last_data, (u16_t)(TFTP_HEADER_LENGTH + ret));
+  resend_data();
+}
+
+static void
+recv(void *arg, struct udp_pcb *upcb, struct pbuf *p, const ip_addr_t *addr, u16_t port)
+{
+  u16_t *sbuf = (u16_t *) p->payload;
+  int opcode;
+
+  LWIP_UNUSED_ARG(arg);
+  LWIP_UNUSED_ARG(upcb);
+
+  if (((tftp_state.port != 0) && (port != tftp_state.port)) ||
+      (!ip_addr_isany_val(tftp_state.addr) && !ip_addr_cmp(&tftp_state.addr, addr))) {
+    send_error(addr, port, TFTP_ERROR_ACCESS_VIOLATION, "Only one connection at a time is supported");
+    pbuf_free(p);
+    return;
+  }
+
+  opcode = sbuf[0];
+
+  tftp_state.last_pkt = tftp_state.timer;
+  tftp_state.retries = 0;
+
+  switch (opcode) {
+    case PP_HTONS(TFTP_RRQ): /* fall through */
+    case PP_HTONS(TFTP_WRQ): {
+      const char tftp_null = 0;
+      char filename[TFTP_MAX_FILENAME_LEN + 1];
+      char mode[TFTP_MAX_MODE_LEN + 1];
+      u16_t filename_end_offset;
+      u16_t mode_end_offset;
+
+      if (tftp_state.handle != NULL) {
+        send_error(addr, port, TFTP_ERROR_ACCESS_VIOLATION, "Only one connection at a time is supported");
+        break;
+      }
+
+      sys_timeout(TFTP_TIMER_MSECS, tftp_tmr, NULL);
+
+      /* find \0 in pbuf -> end of filename string */
+      filename_end_offset = pbuf_memfind(p, &tftp_null, sizeof(tftp_null), 2);
+      if ((u16_t)(filename_end_offset - 1) > sizeof(filename)) {
+        send_error(addr, port, TFTP_ERROR_ACCESS_VIOLATION, "Filename too long/not NULL terminated");
+        break;
+      }
+      pbuf_copy_partial(p, filename, filename_end_offset - 1, 2);
+
+      /* find \0 in pbuf -> end of mode string */
+      mode_end_offset = pbuf_memfind(p, &tftp_null, sizeof(tftp_null), filename_end_offset + 1);
+      if ((u16_t)(mode_end_offset - filename_end_offset) > sizeof(mode)) {
+        send_error(addr, port, TFTP_ERROR_ACCESS_VIOLATION, "Mode too long/not NULL terminated");
+        break;
+      }
+      pbuf_copy_partial(p, mode, mode_end_offset - filename_end_offset, filename_end_offset + 1);
+
+      tftp_state.handle = tftp_state.ctx->open(filename, mode, opcode == PP_HTONS(TFTP_WRQ));
+      tftp_state.blknum = 1;
+
+      if (!tftp_state.handle) {
+        send_error(addr, port, TFTP_ERROR_FILE_NOT_FOUND, "Unable to open requested file.");
+        break;
+      }
+
+      LWIP_DEBUGF(TFTP_DEBUG | LWIP_DBG_STATE, ("tftp: %s request from ", (opcode == PP_HTONS(TFTP_WRQ)) ? "write" : "read"));
+      ip_addr_debug_print(TFTP_DEBUG | LWIP_DBG_STATE, addr);
+      LWIP_DEBUGF(TFTP_DEBUG | LWIP_DBG_STATE, (" for '%s' mode '%s'\n", filename, mode));
+
+      ip_addr_copy(tftp_state.addr, *addr);
+      tftp_state.port = port;
+
+      if (opcode == PP_HTONS(TFTP_WRQ)) {
+        tftp_state.mode_write = 1;
+        send_ack(0);
+      } else {
+        tftp_state.mode_write = 0;
+        send_data();
+      }
+
+      break;
+    }
+
+    case PP_HTONS(TFTP_DATA): {
+      int ret;
+      u16_t blknum;
+
+      if (tftp_state.handle == NULL) {
+        send_error(addr, port, TFTP_ERROR_ACCESS_VIOLATION, "No connection");
+        break;
+      }
+
+      if (tftp_state.mode_write != 1) {
+        send_error(addr, port, TFTP_ERROR_ACCESS_VIOLATION, "Not a write connection");
+        break;
+      }
+
+      blknum = lwip_ntohs(sbuf[1]);
+      if (blknum == tftp_state.blknum) {
+        pbuf_remove_header(p, TFTP_HEADER_LENGTH);
+
+        ret = tftp_state.ctx->write(tftp_state.handle, p);
+        if (ret < 0) {
+          send_error(addr, port, TFTP_ERROR_ACCESS_VIOLATION, "error writing file");
+          close_handle();
+        } else {
+          send_ack(blknum);
+        }
+
+        if (p->tot_len < TFTP_MAX_PAYLOAD_SIZE) {
+          close_handle();
+        } else {
+          tftp_state.blknum++;
+        }
+      } else if ((u16_t)(blknum + 1) == tftp_state.blknum) {
+        /* retransmit of previous block, ack again (casting to u16_t to care for overflow) */
+        send_ack(blknum);
+      } else {
+        send_error(addr, port, TFTP_ERROR_UNKNOWN_TRFR_ID, "Wrong block number");
+      }
+      break;
+    }
+
+    case PP_HTONS(TFTP_ACK): {
+      u16_t blknum;
+      int lastpkt;
+
+      if (tftp_state.handle == NULL) {
+        send_error(addr, port, TFTP_ERROR_ACCESS_VIOLATION, "No connection");
+        break;
+      }
+
+      if (tftp_state.mode_write != 0) {
+        send_error(addr, port, TFTP_ERROR_ACCESS_VIOLATION, "Not a read connection");
+        break;
+      }
+
+      blknum = lwip_ntohs(sbuf[1]);
+      if (blknum != tftp_state.blknum) {
+        send_error(addr, port, TFTP_ERROR_UNKNOWN_TRFR_ID, "Wrong block number");
+        break;
+      }
+
+      lastpkt = 0;
+
+      if (tftp_state.last_data != NULL) {
+        lastpkt = tftp_state.last_data->tot_len != (TFTP_MAX_PAYLOAD_SIZE + TFTP_HEADER_LENGTH);
+      }
+
+      if (!lastpkt) {
+        tftp_state.blknum++;
+        send_data();
+      } else {
+        close_handle();
+      }
+
+      break;
+    }
+
+    default:
+      send_error(addr, port, TFTP_ERROR_ILLEGAL_OPERATION, "Unknown operation");
+      break;
+  }
+
+  pbuf_free(p);
+}
+
+static void
+tftp_tmr(void *arg)
+{
+  LWIP_UNUSED_ARG(arg);
+
+  tftp_state.timer++;
+
+  if (tftp_state.handle == NULL) {
+    return;
+  }
+
+  sys_timeout(TFTP_TIMER_MSECS, tftp_tmr, NULL);
+
+  if ((tftp_state.timer - tftp_state.last_pkt) > (TFTP_TIMEOUT_MSECS / TFTP_TIMER_MSECS)) {
+    if ((tftp_state.last_data != NULL) && (tftp_state.retries < TFTP_MAX_RETRIES)) {
+      LWIP_DEBUGF(TFTP_DEBUG | LWIP_DBG_STATE, ("tftp: timeout, retrying\n"));
+      resend_data();
+      tftp_state.retries++;
+    } else {
+      LWIP_DEBUGF(TFTP_DEBUG | LWIP_DBG_STATE, ("tftp: timeout\n"));
+      close_handle();
+    }
+  }
+}
+
+/** @ingroup tftp
+ * Initialize TFTP server.
+ * @param ctx TFTP callback struct
+ */
+err_t
+tftp_init(const struct tftp_context *ctx)
+{
+  err_t ret;
+
+  /* LWIP_ASSERT_CORE_LOCKED(); is checked by udp_new() */
+  struct udp_pcb *pcb = udp_new_ip_type(IPADDR_TYPE_ANY);
+  if (pcb == NULL) {
+    return ERR_MEM;
+  }
+
+  ret = udp_bind(pcb, IP_ANY_TYPE, TFTP_PORT);
+  if (ret != ERR_OK) {
+    udp_remove(pcb);
+    return ret;
+  }
+
+  tftp_state.handle    = NULL;
+  tftp_state.port      = 0;
+  tftp_state.ctx       = ctx;
+  tftp_state.timer     = 0;
+  tftp_state.last_data = NULL;
+  tftp_state.upcb      = pcb;
+
+  udp_recv(pcb, recv, NULL);
+
+  return ERR_OK;
+}
+
+/** @ingroup tftp
+ * Deinitialize ("turn off") TFTP server.
+ */
+void tftp_cleanup(void)
+{
+  LWIP_ASSERT("Cleanup called on non-initialized TFTP", tftp_state.upcb != NULL);
+  udp_remove(tftp_state.upcb);
+  close_handle();
+  memset(&tftp_state, 0, sizeof(tftp_state));
+}
+
+#endif /* LWIP_UDP */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/core/altcp.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/core/altcp.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/core/altcp.c	(revision 457)
@@ -0,0 +1,681 @@
+/**
+ * @file
+ * @defgroup altcp Application layered TCP Functions
+ * @ingroup altcp_api
+ *
+ * This file contains the common functions for altcp to work.
+ * For more details see @ref altcp_api.
+ */
+
+/**
+ * @defgroup altcp_api Application layered TCP Introduction
+ * @ingroup callbackstyle_api
+ *
+ * Overview
+ * --------
+ * altcp (application layered TCP connection API; to be used from TCPIP thread)
+ * is an abstraction layer that prevents applications linking hard against the
+ * @ref tcp.h functions while providing the same functionality. It is used to
+ * e.g. add SSL/TLS (see LWIP_ALTCP_TLS) or proxy-connect support to an application
+ * written for the tcp callback API without that application knowing the
+ * protocol details.
+ *
+ * * This interface mimics the tcp callback API to the application while preventing
+ *   direct linking (much like virtual functions).
+ * * This way, an application can make use of other application layer protocols
+ *   on top of TCP without knowing the details (e.g. TLS, proxy connection).
+ * * This is achieved by simply including "lwip/altcp.h" instead of "lwip/tcp.h",
+ *   replacing "struct tcp_pcb" with "struct altcp_pcb" and prefixing all functions
+ *   with "altcp_" instead of "tcp_".
+ *
+ * With altcp support disabled (LWIP_ALTCP==0), applications written against the
+ * altcp API can still be compiled but are directly linked against the tcp.h
+ * callback API and then cannot use layered protocols. To minimize code changes
+ * in this case, the use of altcp_allocators is strongly suggested.
+ *
+ * Usage
+ * -----
+ * To make use of this API from an existing tcp raw API application:
+ * * Include "lwip/altcp.h" instead of "lwip/tcp.h"
+ * * Replace "struct tcp_pcb" with "struct altcp_pcb"
+ * * Prefix all called tcp API functions with "altcp_" instead of "tcp_" to link
+ *   against the altcp functions
+ * * @ref altcp_new (and @ref altcp_new_ip_type/@ref altcp_new_ip6) take
+ *   an @ref altcp_allocator_t as an argument, whereas the original tcp API
+ *   functions take no arguments.
+ * * An @ref altcp_allocator_t allocator is an object that holds a pointer to an
+ *   allocator object and a corresponding state (e.g. for TLS, the corresponding
+ *   state may hold certificates or keys). This way, the application does not
+ *   even need to know if it uses TLS or pure TCP, this is handled at runtime
+ *   by passing a specific allocator.
+ * * An application can alternatively bind hard to the altcp_tls API by calling
+ *   @ref altcp_tls_new or @ref altcp_tls_wrap.
+ * * The TLS layer is not directly implemented by lwIP, but a port to mbedTLS is
+ *   provided.
+ * * Another altcp layer is proxy-connect to use TLS behind a HTTP proxy (see
+ *   @ref altcp_proxyconnect.h)
+ *
+ * altcp_allocator_t
+ * -----------------
+ * An altcp allocator is created by the application by combining an allocator
+ * callback function and a corresponding state, e.g.:\code{.c}
+ * static const unsigned char cert[] = {0x2D, ... (see mbedTLS doc for how to create this)};
+ * struct altcp_tls_config * conf = altcp_tls_create_config_client(cert, sizeof(cert));
+ * altcp_allocator_t tls_allocator = {
+ *   altcp_tls_alloc, conf
+ * };
+ * \endcode
+ *
+ *
+ * struct altcp_tls_config
+ * -----------------------
+ * The struct altcp_tls_config holds state that is needed to create new TLS client
+ * or server connections (e.g. certificates and private keys).
+ *
+ * It is not defined by lwIP itself but by the TLS port (e.g. altcp_tls to mbedTLS
+ * adaption). However, the parameters used to create it are defined in @ref
+ * altcp_tls.h (see @ref altcp_tls_create_config_server_privkey_cert for servers
+ * and @ref altcp_tls_create_config_client/@ref altcp_tls_create_config_client_2wayauth
+ * for clients).
+ *
+ * For mbedTLS, ensure that certificates can be parsed by 'mbedtls_x509_crt_parse()' and
+ * private keys can be parsed by 'mbedtls_pk_parse_key()'.
+ */
+
+/*
+ * Copyright (c) 2017 Simon Goldschmidt
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Simon Goldschmidt <goldsimon@gmx.de>
+ *
+ */
+
+#include "lwip/opt.h"
+
+#if LWIP_ALTCP /* don't build if not configured for use in lwipopts.h */
+
+#include "lwip/altcp.h"
+#include "lwip/priv/altcp_priv.h"
+#include "lwip/altcp_tcp.h"
+#include "lwip/tcp.h"
+#include "lwip/mem.h"
+
+#include <string.h>
+
+extern const struct altcp_functions altcp_tcp_functions;
+
+/**
+ * For altcp layer implementations only: allocate a new struct altcp_pcb from the pool
+ * and zero the memory
+ */
+struct altcp_pcb *
+altcp_alloc(void)
+{
+  struct altcp_pcb *ret = (struct altcp_pcb *)memp_malloc(MEMP_ALTCP_PCB);
+  if (ret != NULL) {
+    memset(ret, 0, sizeof(struct altcp_pcb));
+  }
+  return ret;
+}
+
+/**
+ * For altcp layer implementations only: return a struct altcp_pcb to the pool
+ */
+void
+altcp_free(struct altcp_pcb *conn)
+{
+  if (conn) {
+    if (conn->fns && conn->fns->dealloc) {
+      conn->fns->dealloc(conn);
+    }
+    memp_free(MEMP_ALTCP_PCB, conn);
+  }
+}
+
+/**
+ * @ingroup altcp
+ * altcp_new_ip6: @ref altcp_new for IPv6 
+ */
+struct altcp_pcb *
+altcp_new_ip6(altcp_allocator_t *allocator)
+{
+  return altcp_new_ip_type(allocator, IPADDR_TYPE_V6);
+}
+
+/** 
+ * @ingroup altcp
+ * altcp_new: @ref altcp_new for IPv4 
+ */
+struct altcp_pcb *
+altcp_new(altcp_allocator_t *allocator)
+{
+  return altcp_new_ip_type(allocator, IPADDR_TYPE_V4);
+}
+
+/**
+ * @ingroup altcp
+ * altcp_new_ip_type: called by applications to allocate a new pcb with the help of an
+ * allocator function.
+ *
+ * @param allocator allocator function and argument
+ * @param ip_type IP version of the pcb (@ref lwip_ip_addr_type)
+ * @return a new altcp_pcb or NULL on error
+ */
+struct altcp_pcb *
+altcp_new_ip_type(altcp_allocator_t *allocator, u8_t ip_type)
+{
+  struct altcp_pcb *conn;
+  if (allocator == NULL) {
+    /* no allocator given, create a simple TCP connection */
+    return altcp_tcp_new_ip_type(ip_type);
+  }
+  if (allocator->alloc == NULL) {
+    /* illegal allocator */
+    return NULL;
+  }
+  conn = allocator->alloc(allocator->arg, ip_type);
+  if (conn == NULL) {
+    /* allocation failed */
+    return NULL;
+  }
+  return conn;
+}
+
+/**
+ * @ingroup altcp
+ * @see tcp_arg()
+ */
+void
+altcp_arg(struct altcp_pcb *conn, void *arg)
+{
+  if (conn) {
+    conn->arg = arg;
+  }
+}
+
+/**
+ * @ingroup altcp
+ * @see tcp_accept()
+ */
+void
+altcp_accept(struct altcp_pcb *conn, altcp_accept_fn accept)
+{
+  if (conn != NULL) {
+    conn->accept = accept;
+  }
+}
+
+/**
+ * @ingroup altcp
+ * @see tcp_recv()
+ */
+void
+altcp_recv(struct altcp_pcb *conn, altcp_recv_fn recv)
+{
+  if (conn) {
+    conn->recv = recv;
+  }
+}
+
+/**
+ * @ingroup altcp
+ * @see tcp_sent()
+ */
+void
+altcp_sent(struct altcp_pcb *conn, altcp_sent_fn sent)
+{
+  if (conn) {
+    conn->sent = sent;
+  }
+}
+
+/**
+ * @ingroup altcp
+ * @see tcp_poll()
+ */
+void
+altcp_poll(struct altcp_pcb *conn, altcp_poll_fn poll, u8_t interval)
+{
+  if (conn) {
+    conn->poll = poll;
+    conn->pollinterval = interval;
+    if (conn->fns && conn->fns->set_poll) {
+      conn->fns->set_poll(conn, interval);
+    }
+  }
+}
+
+/**
+ * @ingroup altcp
+ * @see tcp_err()
+ */
+void
+altcp_err(struct altcp_pcb *conn, altcp_err_fn err)
+{
+  if (conn) {
+    conn->err = err;
+  }
+}
+
+/* Generic functions calling the "virtual" ones */
+
+/**
+ * @ingroup altcp
+ * @see tcp_recved()
+ */
+void
+altcp_recved(struct altcp_pcb *conn, u16_t len)
+{
+  if (conn && conn->fns && conn->fns->recved) {
+    conn->fns->recved(conn, len);
+  }
+}
+
+/**
+ * @ingroup altcp
+ * @see tcp_bind()
+ */
+err_t
+altcp_bind(struct altcp_pcb *conn, const ip_addr_t *ipaddr, u16_t port)
+{
+  if (conn && conn->fns && conn->fns->bind) {
+    return conn->fns->bind(conn, ipaddr, port);
+  }
+  return ERR_VAL;
+}
+
+/**
+ * @ingroup altcp
+ * @see tcp_connect()
+ */
+err_t
+altcp_connect(struct altcp_pcb *conn, const ip_addr_t *ipaddr, u16_t port, altcp_connected_fn connected)
+{
+  if (conn && conn->fns && conn->fns->connect) {
+    return conn->fns->connect(conn, ipaddr, port, connected);
+  }
+  return ERR_VAL;
+}
+
+/**
+ * @ingroup altcp
+ * @see tcp_listen_with_backlog_and_err()
+ */
+struct altcp_pcb *
+altcp_listen_with_backlog_and_err(struct altcp_pcb *conn, u8_t backlog, err_t *err)
+{
+  if (conn && conn->fns && conn->fns->listen) {
+    return conn->fns->listen(conn, backlog, err);
+  }
+  return NULL;
+}
+
+/**
+ * @ingroup altcp
+ * @see tcp_abort()
+ */
+void
+altcp_abort(struct altcp_pcb *conn)
+{
+  if (conn && conn->fns && conn->fns->abort) {
+    conn->fns->abort(conn);
+  }
+}
+
+/**
+ * @ingroup altcp
+ * @see tcp_close()
+ */
+err_t
+altcp_close(struct altcp_pcb *conn)
+{
+  if (conn && conn->fns && conn->fns->close) {
+    return conn->fns->close(conn);
+  }
+  return ERR_VAL;
+}
+
+/**
+ * @ingroup altcp
+ * @see tcp_shutdown()
+ */
+err_t
+altcp_shutdown(struct altcp_pcb *conn, int shut_rx, int shut_tx)
+{
+  if (conn && conn->fns && conn->fns->shutdown) {
+    return conn->fns->shutdown(conn, shut_rx, shut_tx);
+  }
+  return ERR_VAL;
+}
+
+/**
+ * @ingroup altcp
+ * @see tcp_write()
+ */
+err_t
+altcp_write(struct altcp_pcb *conn, const void *dataptr, u16_t len, u8_t apiflags)
+{
+  if (conn && conn->fns && conn->fns->write) {
+    return conn->fns->write(conn, dataptr, len, apiflags);
+  }
+  return ERR_VAL;
+}
+
+/**
+ * @ingroup altcp
+ * @see tcp_output()
+ */
+err_t
+altcp_output(struct altcp_pcb *conn)
+{
+  if (conn && conn->fns && conn->fns->output) {
+    return conn->fns->output(conn);
+  }
+  return ERR_VAL;
+}
+
+/**
+ * @ingroup altcp
+ * @see tcp_mss()
+ */
+u16_t
+altcp_mss(struct altcp_pcb *conn)
+{
+  if (conn && conn->fns && conn->fns->mss) {
+    return conn->fns->mss(conn);
+  }
+  return 0;
+}
+
+/**
+ * @ingroup altcp
+ * @see tcp_sndbuf()
+ */
+u16_t
+altcp_sndbuf(struct altcp_pcb *conn)
+{
+  if (conn && conn->fns && conn->fns->sndbuf) {
+    return conn->fns->sndbuf(conn);
+  }
+  return 0;
+}
+
+/**
+ * @ingroup altcp
+ * @see tcp_sndqueuelen()
+ */
+u16_t
+altcp_sndqueuelen(struct altcp_pcb *conn)
+{
+  if (conn && conn->fns && conn->fns->sndqueuelen) {
+    return conn->fns->sndqueuelen(conn);
+  }
+  return 0;
+}
+
+void
+altcp_nagle_disable(struct altcp_pcb *conn)
+{
+  if (conn && conn->fns && conn->fns->nagle_disable) {
+    conn->fns->nagle_disable(conn);
+  }
+}
+
+void
+altcp_nagle_enable(struct altcp_pcb *conn)
+{
+  if (conn && conn->fns && conn->fns->nagle_enable) {
+    conn->fns->nagle_enable(conn);
+  }
+}
+
+int
+altcp_nagle_disabled(struct altcp_pcb *conn)
+{
+  if (conn && conn->fns && conn->fns->nagle_disabled) {
+    return conn->fns->nagle_disabled(conn);
+  }
+  return 0;
+}
+
+/**
+ * @ingroup altcp
+ * @see tcp_setprio()
+ */
+void
+altcp_setprio(struct altcp_pcb *conn, u8_t prio)
+{
+  if (conn && conn->fns && conn->fns->setprio) {
+    conn->fns->setprio(conn, prio);
+  }
+}
+
+err_t
+altcp_get_tcp_addrinfo(struct altcp_pcb *conn, int local, ip_addr_t *addr, u16_t *port)
+{
+  if (conn && conn->fns && conn->fns->addrinfo) {
+    return conn->fns->addrinfo(conn, local, addr, port);
+  }
+  return ERR_VAL;
+}
+
+ip_addr_t *
+altcp_get_ip(struct altcp_pcb *conn, int local)
+{
+  if (conn && conn->fns && conn->fns->getip) {
+    return conn->fns->getip(conn, local);
+  }
+  return NULL;
+}
+
+u16_t
+altcp_get_port(struct altcp_pcb *conn, int local)
+{
+  if (conn && conn->fns && conn->fns->getport) {
+    return conn->fns->getport(conn, local);
+  }
+  return 0;
+}
+
+#ifdef LWIP_DEBUG
+enum tcp_state
+altcp_dbg_get_tcp_state(struct altcp_pcb *conn)
+{
+  if (conn && conn->fns && conn->fns->dbg_get_tcp_state) {
+    return conn->fns->dbg_get_tcp_state(conn);
+  }
+  return CLOSED;
+}
+#endif
+
+/* Default implementations for the "virtual" functions */
+
+void
+altcp_default_set_poll(struct altcp_pcb *conn, u8_t interval)
+{
+  if (conn && conn->inner_conn) {
+    altcp_poll(conn->inner_conn, conn->poll, interval);
+  }
+}
+
+void
+altcp_default_recved(struct altcp_pcb *conn, u16_t len)
+{
+  if (conn && conn->inner_conn) {
+    altcp_recved(conn->inner_conn, len);
+  }
+}
+
+err_t
+altcp_default_bind(struct altcp_pcb *conn, const ip_addr_t *ipaddr, u16_t port)
+{
+  if (conn && conn->inner_conn) {
+    return altcp_bind(conn->inner_conn, ipaddr, port);
+  }
+  return ERR_VAL;
+}
+
+err_t
+altcp_default_shutdown(struct altcp_pcb *conn, int shut_rx, int shut_tx)
+{
+  if (conn) {
+    if (shut_rx && shut_tx && conn->fns && conn->fns->close) {
+      /* default shutdown for both sides is close */
+      return conn->fns->close(conn);
+    }
+    if (conn->inner_conn) {
+      return altcp_shutdown(conn->inner_conn, shut_rx, shut_tx);
+    }
+  }
+  return ERR_VAL;
+}
+
+err_t
+altcp_default_write(struct altcp_pcb *conn, const void *dataptr, u16_t len, u8_t apiflags)
+{
+  if (conn && conn->inner_conn) {
+    return altcp_write(conn->inner_conn, dataptr, len, apiflags);
+  }
+  return ERR_VAL;
+}
+
+err_t
+altcp_default_output(struct altcp_pcb *conn)
+{
+  if (conn && conn->inner_conn) {
+    return altcp_output(conn->inner_conn);
+  }
+  return ERR_VAL;
+}
+
+u16_t
+altcp_default_mss(struct altcp_pcb *conn)
+{
+  if (conn && conn->inner_conn) {
+    return altcp_mss(conn->inner_conn);
+  }
+  return 0;
+}
+
+u16_t
+altcp_default_sndbuf(struct altcp_pcb *conn)
+{
+  if (conn && conn->inner_conn) {
+    return altcp_sndbuf(conn->inner_conn);
+  }
+  return 0;
+}
+
+u16_t
+altcp_default_sndqueuelen(struct altcp_pcb *conn)
+{
+  if (conn && conn->inner_conn) {
+    return altcp_sndqueuelen(conn->inner_conn);
+  }
+  return 0;
+}
+
+void
+altcp_default_nagle_disable(struct altcp_pcb *conn)
+{
+  if (conn && conn->inner_conn) {
+    altcp_nagle_disable(conn->inner_conn);
+  }
+}
+
+void
+altcp_default_nagle_enable(struct altcp_pcb *conn)
+{
+  if (conn && conn->inner_conn) {
+    altcp_nagle_enable(conn->inner_conn);
+  }
+}
+
+int
+altcp_default_nagle_disabled(struct altcp_pcb *conn)
+{
+  if (conn && conn->inner_conn) {
+    return altcp_nagle_disabled(conn->inner_conn);
+  }
+  return 0;
+}
+
+void
+altcp_default_setprio(struct altcp_pcb *conn, u8_t prio)
+{
+  if (conn && conn->inner_conn) {
+    altcp_setprio(conn->inner_conn, prio);
+  }
+}
+
+void
+altcp_default_dealloc(struct altcp_pcb *conn)
+{
+  LWIP_UNUSED_ARG(conn);
+  /* nothing to do */
+}
+
+err_t
+altcp_default_get_tcp_addrinfo(struct altcp_pcb *conn, int local, ip_addr_t *addr, u16_t *port)
+{
+  if (conn && conn->inner_conn) {
+    return altcp_get_tcp_addrinfo(conn->inner_conn, local, addr, port);
+  }
+  return ERR_VAL;
+}
+
+ip_addr_t *
+altcp_default_get_ip(struct altcp_pcb *conn, int local)
+{
+  if (conn && conn->inner_conn) {
+    return altcp_get_ip(conn->inner_conn, local);
+  }
+  return NULL;
+}
+
+u16_t
+altcp_default_get_port(struct altcp_pcb *conn, int local)
+{
+  if (conn && conn->inner_conn) {
+    return altcp_get_port(conn->inner_conn, local);
+  }
+  return 0;
+}
+
+#ifdef LWIP_DEBUG
+enum tcp_state
+altcp_default_dbg_get_tcp_state(struct altcp_pcb *conn)
+{
+  if (conn && conn->inner_conn) {
+    return altcp_dbg_get_tcp_state(conn->inner_conn);
+  }
+  return CLOSED;
+}
+#endif
+
+
+#endif /* LWIP_ALTCP */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/core/altcp_alloc.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/core/altcp_alloc.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/core/altcp_alloc.c	(revision 457)
@@ -0,0 +1,87 @@
+/**
+ * @file
+ * Application layered TCP connection API (to be used from TCPIP thread)\n
+ * This interface mimics the tcp callback API to the application while preventing
+ * direct linking (much like virtual functions).
+ * This way, an application can make use of other application layer protocols
+ * on top of TCP without knowing the details (e.g. TLS, proxy connection).
+ *
+ * This file contains allocation implementation that combine several layers.
+ */
+
+/*
+ * Copyright (c) 2017 Simon Goldschmidt
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Simon Goldschmidt <goldsimon@gmx.de>
+ *
+ */
+
+#include "lwip/opt.h"
+
+#if LWIP_ALTCP /* don't build if not configured for use in lwipopts.h */
+
+#include "lwip/altcp.h"
+#include "lwip/altcp_tcp.h"
+#include "lwip/altcp_tls.h"
+#include "lwip/priv/altcp_priv.h"
+#include "lwip/mem.h"
+
+#include <string.h>
+
+#if LWIP_ALTCP_TLS
+
+/** This standard allocator function creates an altcp pcb for
+ * TLS over TCP */
+struct altcp_pcb *
+altcp_tls_new(struct altcp_tls_config *config, u8_t ip_type)
+{
+  struct altcp_pcb *inner_conn, *ret;
+  LWIP_UNUSED_ARG(ip_type);
+
+  inner_conn = altcp_tcp_new_ip_type(ip_type);
+  if (inner_conn == NULL) {
+    return NULL;
+  }
+  ret = altcp_tls_wrap(config, inner_conn);
+  if (ret == NULL) {
+    altcp_close(inner_conn);
+  }
+  return ret;
+}
+
+/** This standard allocator function creates an altcp pcb for
+ * TLS over TCP */
+struct altcp_pcb *
+altcp_tls_alloc(void *arg, u8_t ip_type)
+{
+  return altcp_tls_new((struct altcp_tls_config *)arg, ip_type);
+}
+
+#endif /* LWIP_ALTCP_TLS */
+
+#endif /* LWIP_ALTCP */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/core/altcp_tcp.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/core/altcp_tcp.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/core/altcp_tcp.c	(revision 457)
@@ -0,0 +1,543 @@
+/**
+ * @file
+ * Application layered TCP connection API (to be used from TCPIP thread)\n
+ * This interface mimics the tcp callback API to the application while preventing
+ * direct linking (much like virtual functions).
+ * This way, an application can make use of other application layer protocols
+ * on top of TCP without knowing the details (e.g. TLS, proxy connection).
+ *
+ * This file contains the base implementation calling into tcp.
+ */
+
+/*
+ * Copyright (c) 2017 Simon Goldschmidt
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Simon Goldschmidt <goldsimon@gmx.de>
+ *
+ */
+
+#include "lwip/opt.h"
+
+#if LWIP_ALTCP /* don't build if not configured for use in lwipopts.h */
+
+#include "lwip/altcp.h"
+#include "lwip/altcp_tcp.h"
+#include "lwip/priv/altcp_priv.h"
+#include "lwip/tcp.h"
+#include "lwip/mem.h"
+
+#include <string.h>
+
+#define ALTCP_TCP_ASSERT_CONN(conn) do { \
+  LWIP_ASSERT("conn->inner_conn == NULL", (conn)->inner_conn == NULL); \
+  LWIP_UNUSED_ARG(conn); /* for LWIP_NOASSERT */ } while(0)
+#define ALTCP_TCP_ASSERT_CONN_PCB(conn, tpcb) do { \
+  LWIP_ASSERT("pcb mismatch", (conn)->state == tpcb); \
+  LWIP_UNUSED_ARG(tpcb); /* for LWIP_NOASSERT */ \
+  ALTCP_TCP_ASSERT_CONN(conn); } while(0)
+
+
+/* Variable prototype, the actual declaration is at the end of this file
+   since it contains pointers to static functions declared here */
+extern const struct altcp_functions altcp_tcp_functions;
+
+static void altcp_tcp_setup(struct altcp_pcb *conn, struct tcp_pcb *tpcb);
+
+/* callback functions for TCP */
+static err_t
+altcp_tcp_accept(void *arg, struct tcp_pcb *new_tpcb, err_t err)
+{
+  struct altcp_pcb *listen_conn = (struct altcp_pcb *)arg;
+  if (listen_conn && listen_conn->accept) {
+    /* create a new altcp_conn to pass to the next 'accept' callback */
+    struct altcp_pcb *new_conn = altcp_alloc();
+    if (new_conn == NULL) {
+      return ERR_MEM;
+    }
+    altcp_tcp_setup(new_conn, new_tpcb);
+    return listen_conn->accept(listen_conn->arg, new_conn, err);
+  }
+  return ERR_ARG;
+}
+
+static err_t
+altcp_tcp_connected(void *arg, struct tcp_pcb *tpcb, err_t err)
+{
+  struct altcp_pcb *conn = (struct altcp_pcb *)arg;
+  if (conn) {
+    ALTCP_TCP_ASSERT_CONN_PCB(conn, tpcb);
+    if (conn->connected) {
+      return conn->connected(conn->arg, conn, err);
+    }
+  }
+  return ERR_OK;
+}
+
+static err_t
+altcp_tcp_recv(void *arg, struct tcp_pcb *tpcb, struct pbuf *p, err_t err)
+{
+  struct altcp_pcb *conn = (struct altcp_pcb *)arg;
+  if (conn) {
+    ALTCP_TCP_ASSERT_CONN_PCB(conn, tpcb);
+    if (conn->recv) {
+      return conn->recv(conn->arg, conn, p, err);
+    }
+  }
+  if (p != NULL) {
+    /* prevent memory leaks */
+    pbuf_free(p);
+  }
+  return ERR_OK;
+}
+
+static err_t
+altcp_tcp_sent(void *arg, struct tcp_pcb *tpcb, u16_t len)
+{
+  struct altcp_pcb *conn = (struct altcp_pcb *)arg;
+  if (conn) {
+    ALTCP_TCP_ASSERT_CONN_PCB(conn, tpcb);
+    if (conn->sent) {
+      return conn->sent(conn->arg, conn, len);
+    }
+  }
+  return ERR_OK;
+}
+
+static err_t
+altcp_tcp_poll(void *arg, struct tcp_pcb *tpcb)
+{
+  struct altcp_pcb *conn = (struct altcp_pcb *)arg;
+  if (conn) {
+    ALTCP_TCP_ASSERT_CONN_PCB(conn, tpcb);
+    if (conn->poll) {
+      return conn->poll(conn->arg, conn);
+    }
+  }
+  return ERR_OK;
+}
+
+static void
+altcp_tcp_err(void *arg, err_t err)
+{
+  struct altcp_pcb *conn = (struct altcp_pcb *)arg;
+  if (conn) {
+    conn->state = NULL; /* already freed */
+    if (conn->err) {
+      conn->err(conn->arg, err);
+    }
+    altcp_free(conn);
+  }
+}
+
+/* setup functions */
+
+static void
+altcp_tcp_remove_callbacks(struct tcp_pcb *tpcb)
+{
+  tcp_arg(tpcb, NULL);
+  tcp_recv(tpcb, NULL);
+  tcp_sent(tpcb, NULL);
+  tcp_err(tpcb, NULL);
+  tcp_poll(tpcb, NULL, tpcb->pollinterval);
+}
+
+static void
+altcp_tcp_setup_callbacks(struct altcp_pcb *conn, struct tcp_pcb *tpcb)
+{
+  tcp_arg(tpcb, conn);
+  tcp_recv(tpcb, altcp_tcp_recv);
+  tcp_sent(tpcb, altcp_tcp_sent);
+  tcp_err(tpcb, altcp_tcp_err);
+  /* tcp_poll is set when interval is set by application */
+  /* listen is set totally different :-) */
+}
+
+static void
+altcp_tcp_setup(struct altcp_pcb *conn, struct tcp_pcb *tpcb)
+{
+  altcp_tcp_setup_callbacks(conn, tpcb);
+  conn->state = tpcb;
+  conn->fns = &altcp_tcp_functions;
+}
+
+struct altcp_pcb *
+altcp_tcp_new_ip_type(u8_t ip_type)
+{
+  /* Allocate the tcp pcb first to invoke the priority handling code
+     if we're out of pcbs */
+  struct tcp_pcb *tpcb = tcp_new_ip_type(ip_type);
+  if (tpcb != NULL) {
+    struct altcp_pcb *ret = altcp_alloc();
+    if (ret != NULL) {
+      altcp_tcp_setup(ret, tpcb);
+      return ret;
+    } else {
+      /* altcp_pcb allocation failed -> free the tcp_pcb too */
+      tcp_close(tpcb);
+    }
+  }
+  return NULL;
+}
+
+/** altcp_tcp allocator function fitting to @ref altcp_allocator_t / @ref altcp_new.
+*
+* arg pointer is not used for TCP.
+*/
+struct altcp_pcb *
+altcp_tcp_alloc(void *arg, u8_t ip_type)
+{
+  LWIP_UNUSED_ARG(arg);
+  return altcp_tcp_new_ip_type(ip_type);
+}
+
+struct altcp_pcb *
+altcp_tcp_wrap(struct tcp_pcb *tpcb)
+{
+  if (tpcb != NULL) {
+    struct altcp_pcb *ret = altcp_alloc();
+    if (ret != NULL) {
+      altcp_tcp_setup(ret, tpcb);
+      return ret;
+    }
+  }
+  return NULL;
+}
+
+
+/* "virtual" functions calling into tcp */
+static void
+altcp_tcp_set_poll(struct altcp_pcb *conn, u8_t interval)
+{
+  if (conn != NULL) {
+    struct tcp_pcb *pcb = (struct tcp_pcb *)conn->state;
+    ALTCP_TCP_ASSERT_CONN(conn);
+    tcp_poll(pcb, altcp_tcp_poll, interval);
+  }
+}
+
+static void
+altcp_tcp_recved(struct altcp_pcb *conn, u16_t len)
+{
+  if (conn != NULL) {
+    struct tcp_pcb *pcb = (struct tcp_pcb *)conn->state;
+    ALTCP_TCP_ASSERT_CONN(conn);
+    tcp_recved(pcb, len);
+  }
+}
+
+static err_t
+altcp_tcp_bind(struct altcp_pcb *conn, const ip_addr_t *ipaddr, u16_t port)
+{
+  struct tcp_pcb *pcb;
+  if (conn == NULL) {
+    return ERR_VAL;
+  }
+  ALTCP_TCP_ASSERT_CONN(conn);
+  pcb = (struct tcp_pcb *)conn->state;
+  return tcp_bind(pcb, ipaddr, port);
+}
+
+static err_t
+altcp_tcp_connect(struct altcp_pcb *conn, const ip_addr_t *ipaddr, u16_t port, altcp_connected_fn connected)
+{
+  struct tcp_pcb *pcb;
+  if (conn == NULL) {
+    return ERR_VAL;
+  }
+  ALTCP_TCP_ASSERT_CONN(conn);
+  conn->connected = connected;
+  pcb = (struct tcp_pcb *)conn->state;
+  return tcp_connect(pcb, ipaddr, port, altcp_tcp_connected);
+}
+
+static struct altcp_pcb *
+altcp_tcp_listen(struct altcp_pcb *conn, u8_t backlog, err_t *err)
+{
+  struct tcp_pcb *pcb;
+  struct tcp_pcb *lpcb;
+  if (conn == NULL) {
+    return NULL;
+  }
+  ALTCP_TCP_ASSERT_CONN(conn);
+  pcb = (struct tcp_pcb *)conn->state;
+  lpcb = tcp_listen_with_backlog_and_err(pcb, backlog, err);
+  if (lpcb != NULL) {
+    conn->state = lpcb;
+    tcp_accept(lpcb, altcp_tcp_accept);
+    return conn;
+  }
+  return NULL;
+}
+
+static void
+altcp_tcp_abort(struct altcp_pcb *conn)
+{
+  if (conn != NULL) {
+    struct tcp_pcb *pcb = (struct tcp_pcb *)conn->state;
+    ALTCP_TCP_ASSERT_CONN(conn);
+    if (pcb) {
+      tcp_abort(pcb);
+    }
+  }
+}
+
+static err_t
+altcp_tcp_close(struct altcp_pcb *conn)
+{
+  struct tcp_pcb *pcb;
+  if (conn == NULL) {
+    return ERR_VAL;
+  }
+  ALTCP_TCP_ASSERT_CONN(conn);
+  pcb = (struct tcp_pcb *)conn->state;
+  if (pcb) {
+    err_t err;
+    tcp_poll_fn oldpoll = pcb->poll;
+    altcp_tcp_remove_callbacks(pcb);
+    err = tcp_close(pcb);
+    if (err != ERR_OK) {
+      /* not closed, set up all callbacks again */
+      altcp_tcp_setup_callbacks(conn, pcb);
+      /* poll callback is not included in the above */
+      tcp_poll(pcb, oldpoll, pcb->pollinterval);
+      return err;
+    }
+    conn->state = NULL; /* unsafe to reference pcb after tcp_close(). */
+  }
+  altcp_free(conn);
+  return ERR_OK;
+}
+
+static err_t
+altcp_tcp_shutdown(struct altcp_pcb *conn, int shut_rx, int shut_tx)
+{
+  struct tcp_pcb *pcb;
+  if (conn == NULL) {
+    return ERR_VAL;
+  }
+  ALTCP_TCP_ASSERT_CONN(conn);
+  pcb = (struct tcp_pcb *)conn->state;
+  return tcp_shutdown(pcb, shut_rx, shut_tx);
+}
+
+static err_t
+altcp_tcp_write(struct altcp_pcb *conn, const void *dataptr, u16_t len, u8_t apiflags)
+{
+  struct tcp_pcb *pcb;
+  if (conn == NULL) {
+    return ERR_VAL;
+  }
+  ALTCP_TCP_ASSERT_CONN(conn);
+  pcb = (struct tcp_pcb *)conn->state;
+  return tcp_write(pcb, dataptr, len, apiflags);
+}
+
+static err_t
+altcp_tcp_output(struct altcp_pcb *conn)
+{
+  struct tcp_pcb *pcb;
+  if (conn == NULL) {
+    return ERR_VAL;
+  }
+  ALTCP_TCP_ASSERT_CONN(conn);
+  pcb = (struct tcp_pcb *)conn->state;
+  return tcp_output(pcb);
+}
+
+static u16_t
+altcp_tcp_mss(struct altcp_pcb *conn)
+{
+  struct tcp_pcb *pcb;
+  if (conn == NULL) {
+    return 0;
+  }
+  ALTCP_TCP_ASSERT_CONN(conn);
+  pcb = (struct tcp_pcb *)conn->state;
+  return tcp_mss(pcb);
+}
+
+static u16_t
+altcp_tcp_sndbuf(struct altcp_pcb *conn)
+{
+  struct tcp_pcb *pcb;
+  if (conn == NULL) {
+    return 0;
+  }
+  ALTCP_TCP_ASSERT_CONN(conn);
+  pcb = (struct tcp_pcb *)conn->state;
+  return tcp_sndbuf(pcb);
+}
+
+static u16_t
+altcp_tcp_sndqueuelen(struct altcp_pcb *conn)
+{
+  struct tcp_pcb *pcb;
+  if (conn == NULL) {
+    return 0;
+  }
+  ALTCP_TCP_ASSERT_CONN(conn);
+  pcb = (struct tcp_pcb *)conn->state;
+  return tcp_sndqueuelen(pcb);
+}
+
+static void
+altcp_tcp_nagle_disable(struct altcp_pcb *conn)
+{
+  if (conn && conn->state) {
+    struct tcp_pcb *pcb = (struct tcp_pcb *)conn->state;
+    ALTCP_TCP_ASSERT_CONN(conn);
+    tcp_nagle_disable(pcb);
+  }
+}
+
+static void
+altcp_tcp_nagle_enable(struct altcp_pcb *conn)
+{
+  if (conn && conn->state) {
+    struct tcp_pcb *pcb = (struct tcp_pcb *)conn->state;
+    ALTCP_TCP_ASSERT_CONN(conn);
+    tcp_nagle_enable(pcb);
+  }
+}
+
+static int
+altcp_tcp_nagle_disabled(struct altcp_pcb *conn)
+{
+  if (conn && conn->state) {
+    struct tcp_pcb *pcb = (struct tcp_pcb *)conn->state;
+    ALTCP_TCP_ASSERT_CONN(conn);
+    return tcp_nagle_disabled(pcb);
+  }
+  return 0;
+}
+
+static void
+altcp_tcp_setprio(struct altcp_pcb *conn, u8_t prio)
+{
+  if (conn != NULL) {
+    struct tcp_pcb *pcb = (struct tcp_pcb *)conn->state;
+    ALTCP_TCP_ASSERT_CONN(conn);
+    tcp_setprio(pcb, prio);
+  }
+}
+
+static void
+altcp_tcp_dealloc(struct altcp_pcb *conn)
+{
+  LWIP_UNUSED_ARG(conn);
+  ALTCP_TCP_ASSERT_CONN(conn);
+  /* no private state to clean up */
+}
+
+static err_t
+altcp_tcp_get_tcp_addrinfo(struct altcp_pcb *conn, int local, ip_addr_t *addr, u16_t *port)
+{
+  if (conn) {
+    struct tcp_pcb *pcb = (struct tcp_pcb *)conn->state;
+    ALTCP_TCP_ASSERT_CONN(conn);
+    return tcp_tcp_get_tcp_addrinfo(pcb, local, addr, port);
+  }
+  return ERR_VAL;
+}
+
+static ip_addr_t *
+altcp_tcp_get_ip(struct altcp_pcb *conn, int local)
+{
+  if (conn) {
+    struct tcp_pcb *pcb = (struct tcp_pcb *)conn->state;
+    ALTCP_TCP_ASSERT_CONN(conn);
+    if (pcb) {
+      if (local) {
+        return &pcb->local_ip;
+      } else {
+        return &pcb->remote_ip;
+      }
+    }
+  }
+  return NULL;
+}
+
+static u16_t
+altcp_tcp_get_port(struct altcp_pcb *conn, int local)
+{
+  if (conn) {
+    struct tcp_pcb *pcb = (struct tcp_pcb *)conn->state;
+    ALTCP_TCP_ASSERT_CONN(conn);
+    if (pcb) {
+      if (local) {
+        return pcb->local_port;
+      } else {
+        return pcb->remote_port;
+      }
+    }
+  }
+  return 0;
+}
+
+#ifdef LWIP_DEBUG
+static enum tcp_state
+altcp_tcp_dbg_get_tcp_state(struct altcp_pcb *conn)
+{
+  if (conn) {
+    struct tcp_pcb *pcb = (struct tcp_pcb *)conn->state;
+    ALTCP_TCP_ASSERT_CONN(conn);
+    if (pcb) {
+      return pcb->state;
+    }
+  }
+  return CLOSED;
+}
+#endif
+const struct altcp_functions altcp_tcp_functions = {
+  altcp_tcp_set_poll,
+  altcp_tcp_recved,
+  altcp_tcp_bind,
+  altcp_tcp_connect,
+  altcp_tcp_listen,
+  altcp_tcp_abort,
+  altcp_tcp_close,
+  altcp_tcp_shutdown,
+  altcp_tcp_write,
+  altcp_tcp_output,
+  altcp_tcp_mss,
+  altcp_tcp_sndbuf,
+  altcp_tcp_sndqueuelen,
+  altcp_tcp_nagle_disable,
+  altcp_tcp_nagle_enable,
+  altcp_tcp_nagle_disabled,
+  altcp_tcp_setprio,
+  altcp_tcp_dealloc,
+  altcp_tcp_get_tcp_addrinfo,
+  altcp_tcp_get_ip,
+  altcp_tcp_get_port
+#ifdef LWIP_DEBUG
+  , altcp_tcp_dbg_get_tcp_state
+#endif
+};
+
+#endif /* LWIP_ALTCP */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/core/def.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/core/def.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/core/def.c	(revision 457)
@@ -0,0 +1,240 @@
+/**
+ * @file
+ * Common functions used throughout the stack.
+ *
+ * These are reference implementations of the byte swapping functions.
+ * Again with the aim of being simple, correct and fully portable.
+ * Byte swapping is the second thing you would want to optimize. You will
+ * need to port it to your architecture and in your cc.h:
+ *
+ * \#define lwip_htons(x) your_htons
+ * \#define lwip_htonl(x) your_htonl
+ *
+ * Note lwip_ntohs() and lwip_ntohl() are merely references to the htonx counterparts.
+ *
+ * If you \#define them to htons() and htonl(), you should
+ * \#define LWIP_DONT_PROVIDE_BYTEORDER_FUNCTIONS to prevent lwIP from
+ * defining htonx/ntohx compatibility macros.
+
+ * @defgroup sys_nonstandard Non-standard functions
+ * @ingroup sys_layer
+ * lwIP provides default implementations for non-standard functions.
+ * These can be mapped to OS functions to reduce code footprint if desired.
+ * All defines related to this section must not be placed in lwipopts.h,
+ * but in arch/cc.h!
+ * These options cannot be \#defined in lwipopts.h since they are not options
+ * of lwIP itself, but options of the lwIP port to your system.
+ */
+
+/*
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Simon Goldschmidt
+ *
+ */
+
+#include "lwip/opt.h"
+#include "lwip/def.h"
+
+#include <string.h>
+
+#if BYTE_ORDER == LITTLE_ENDIAN
+
+#if !defined(lwip_htons)
+/**
+ * Convert an u16_t from host- to network byte order.
+ *
+ * @param n u16_t in host byte order
+ * @return n in network byte order
+ */
+u16_t
+lwip_htons(u16_t n)
+{
+  return PP_HTONS(n);
+}
+#endif /* lwip_htons */
+
+#if !defined(lwip_htonl)
+/**
+ * Convert an u32_t from host- to network byte order.
+ *
+ * @param n u32_t in host byte order
+ * @return n in network byte order
+ */
+u32_t
+lwip_htonl(u32_t n)
+{
+  return PP_HTONL(n);
+}
+#endif /* lwip_htonl */
+
+#endif /* BYTE_ORDER == LITTLE_ENDIAN */
+
+#ifndef lwip_strnstr
+/**
+ * @ingroup sys_nonstandard
+ * lwIP default implementation for strnstr() non-standard function.
+ * This can be \#defined to strnstr() depending on your platform port.
+ */
+char *
+lwip_strnstr(const char *buffer, const char *token, size_t n)
+{
+  const char *p;
+  size_t tokenlen = strlen(token);
+  if (tokenlen == 0) {
+    return LWIP_CONST_CAST(char *, buffer);
+  }
+  for (p = buffer; *p && (p + tokenlen <= buffer + n); p++) {
+    if ((*p == *token) && (strncmp(p, token, tokenlen) == 0)) {
+      return LWIP_CONST_CAST(char *, p);
+    }
+  }
+  return NULL;
+}
+#endif
+
+#ifndef lwip_stricmp
+/**
+ * @ingroup sys_nonstandard
+ * lwIP default implementation for stricmp() non-standard function.
+ * This can be \#defined to stricmp() depending on your platform port.
+ */
+int
+lwip_stricmp(const char *str1, const char *str2)
+{
+  char c1, c2;
+
+  do {
+    c1 = *str1++;
+    c2 = *str2++;
+    if (c1 != c2) {
+      char c1_upc = c1 | 0x20;
+      if ((c1_upc >= 'a') && (c1_upc <= 'z')) {
+        /* characters are not equal an one is in the alphabet range:
+        downcase both chars and check again */
+        char c2_upc = c2 | 0x20;
+        if (c1_upc != c2_upc) {
+          /* still not equal */
+          /* don't care for < or > */
+          return 1;
+        }
+      } else {
+        /* characters are not equal but none is in the alphabet range */
+        return 1;
+      }
+    }
+  } while (c1 != 0);
+  return 0;
+}
+#endif
+
+#ifndef lwip_strnicmp
+/**
+ * @ingroup sys_nonstandard
+ * lwIP default implementation for strnicmp() non-standard function.
+ * This can be \#defined to strnicmp() depending on your platform port.
+ */
+int
+lwip_strnicmp(const char *str1, const char *str2, size_t len)
+{
+  char c1, c2;
+
+  do {
+    c1 = *str1++;
+    c2 = *str2++;
+    if (c1 != c2) {
+      char c1_upc = c1 | 0x20;
+      if ((c1_upc >= 'a') && (c1_upc <= 'z')) {
+        /* characters are not equal an one is in the alphabet range:
+        downcase both chars and check again */
+        char c2_upc = c2 | 0x20;
+        if (c1_upc != c2_upc) {
+          /* still not equal */
+          /* don't care for < or > */
+          return 1;
+        }
+      } else {
+        /* characters are not equal but none is in the alphabet range */
+        return 1;
+      }
+    }
+    len--;
+  } while ((len != 0) && (c1 != 0));
+  return 0;
+}
+#endif
+
+#ifndef lwip_itoa
+/**
+ * @ingroup sys_nonstandard
+ * lwIP default implementation for itoa() non-standard function.
+ * This can be \#defined to itoa() or snprintf(result, bufsize, "%d", number) depending on your platform port.
+ */
+void
+lwip_itoa(char *result, size_t bufsize, int number)
+{
+  char *res = result;
+  char *tmp = result + bufsize - 1;
+  int n = (number >= 0) ? number : -number;
+
+  /* handle invalid bufsize */
+  if (bufsize < 2) {
+    if (bufsize == 1) {
+      *result = 0;
+    }
+    return;
+  }
+
+  /* First, add sign */
+  if (number < 0) {
+    *res++ = '-';
+  }
+  /* Then create the string from the end and stop if buffer full,
+     and ensure output string is zero terminated */
+  *tmp = 0;
+  while ((n != 0) && (tmp > res)) {
+    char val = (char)('0' + (n % 10));
+    tmp--;
+    *tmp = val;
+    n = n / 10;
+  }
+  if (n) {
+    /* buffer is too small */
+    *result = 0;
+    return;
+  }
+  if (*tmp == 0) {
+    /* Nothing added? */
+    *res++ = '0';
+    *res++ = 0;
+    return;
+  }
+  /* move from temporary buffer to output buffer (sign is not moved) */
+  memmove(res, tmp, (size_t)((result + bufsize) - tmp));
+}
+#endif
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/core/dns.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/core/dns.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/core/dns.c	(revision 457)
@@ -0,0 +1,1631 @@
+/**
+ * @file
+ * DNS - host name to IP address resolver.
+ *
+ * @defgroup dns DNS
+ * @ingroup callbackstyle_api
+ *
+ * Implements a DNS host name to IP address resolver.
+ *
+ * The lwIP DNS resolver functions are used to lookup a host name and
+ * map it to a numerical IP address. It maintains a list of resolved
+ * hostnames that can be queried with the dns_lookup() function.
+ * New hostnames can be resolved using the dns_query() function.
+ *
+ * The lwIP version of the resolver also adds a non-blocking version of
+ * gethostbyname() that will work with a raw API application. This function
+ * checks for an IP address string first and converts it if it is valid.
+ * gethostbyname() then does a dns_lookup() to see if the name is
+ * already in the table. If so, the IP is returned. If not, a query is
+ * issued and the function returns with a ERR_INPROGRESS status. The app
+ * using the dns client must then go into a waiting state.
+ *
+ * Once a hostname has been resolved (or found to be non-existent),
+ * the resolver code calls a specified callback function (which
+ * must be implemented by the module that uses the resolver).
+ *
+ * Multicast DNS queries are supported for names ending on ".local".
+ * However, only "One-Shot Multicast DNS Queries" are supported (RFC 6762
+ * chapter 5.1), this is not a fully compliant implementation of continuous
+ * mDNS querying!
+ *
+ * All functions must be called from TCPIP thread.
+ *
+ * @see DNS_MAX_SERVERS
+ * @see LWIP_DHCP_MAX_DNS_SERVERS
+ * @see @ref netconn_common for thread-safe access.
+ */
+
+/*
+ * Port to lwIP from uIP
+ * by Jim Pettinato April 2007
+ *
+ * security fixes and more by Simon Goldschmidt
+ *
+ * uIP version Copyright (c) 2002-2003, Adam Dunkels.
+ * 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. The name of the author may not be used to endorse or promote
+ *    products derived from this software without specific prior
+ *    written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ */
+
+/*-----------------------------------------------------------------------------
+ * RFC 1035 - Domain names - implementation and specification
+ * RFC 2181 - Clarifications to the DNS Specification
+ *----------------------------------------------------------------------------*/
+
+/** @todo: define good default values (rfc compliance) */
+/** @todo: improve answer parsing, more checkings... */
+/** @todo: check RFC1035 - 7.3. Processing responses */
+/** @todo: one-shot mDNS: dual-stack fallback to another IP version */
+
+/*-----------------------------------------------------------------------------
+ * Includes
+ *----------------------------------------------------------------------------*/
+
+#include "lwip/opt.h"
+
+#if LWIP_DNS /* don't build if not configured for use in lwipopts.h */
+
+#include "lwip/def.h"
+#include "lwip/udp.h"
+#include "lwip/mem.h"
+#include "lwip/memp.h"
+#include "lwip/dns.h"
+#include "lwip/prot/dns.h"
+
+#include <string.h>
+
+/** Random generator function to create random TXIDs and source ports for queries */
+#ifndef DNS_RAND_TXID
+#if ((LWIP_DNS_SECURE & LWIP_DNS_SECURE_RAND_XID) != 0)
+#define DNS_RAND_TXID LWIP_RAND
+#else
+static u16_t dns_txid;
+#define DNS_RAND_TXID() (++dns_txid)
+#endif
+#endif
+
+/** Limits the source port to be >= 1024 by default */
+#ifndef DNS_PORT_ALLOWED
+#define DNS_PORT_ALLOWED(port) ((port) >= 1024)
+#endif
+
+/** DNS resource record max. TTL (one week as default) */
+#ifndef DNS_MAX_TTL
+#define DNS_MAX_TTL               604800
+#elif DNS_MAX_TTL > 0x7FFFFFFF
+#error DNS_MAX_TTL must be a positive 32-bit value
+#endif
+
+#if DNS_TABLE_SIZE > 255
+#error DNS_TABLE_SIZE must fit into an u8_t
+#endif
+#if DNS_MAX_SERVERS > 255
+#error DNS_MAX_SERVERS must fit into an u8_t
+#endif
+
+/* The number of parallel requests (i.e. calls to dns_gethostbyname
+ * that cannot be answered from the DNS table.
+ * This is set to the table size by default.
+ */
+#if ((LWIP_DNS_SECURE & LWIP_DNS_SECURE_NO_MULTIPLE_OUTSTANDING) != 0)
+#ifndef DNS_MAX_REQUESTS
+#define DNS_MAX_REQUESTS          DNS_TABLE_SIZE
+#else
+#if DNS_MAX_REQUESTS > 255
+#error DNS_MAX_REQUESTS must fit into an u8_t
+#endif
+#endif
+#else
+/* In this configuration, both arrays have to have the same size and are used
+ * like one entry (used/free) */
+#define DNS_MAX_REQUESTS          DNS_TABLE_SIZE
+#endif
+
+/* The number of UDP source ports used in parallel */
+#if ((LWIP_DNS_SECURE & LWIP_DNS_SECURE_RAND_SRC_PORT) != 0)
+#ifndef DNS_MAX_SOURCE_PORTS
+#define DNS_MAX_SOURCE_PORTS      DNS_MAX_REQUESTS
+#else
+#if DNS_MAX_SOURCE_PORTS > 255
+#error DNS_MAX_SOURCE_PORTS must fit into an u8_t
+#endif
+#endif
+#else
+#ifdef DNS_MAX_SOURCE_PORTS
+#undef DNS_MAX_SOURCE_PORTS
+#endif
+#define DNS_MAX_SOURCE_PORTS      1
+#endif
+
+#if LWIP_IPV4 && LWIP_IPV6
+#define LWIP_DNS_ADDRTYPE_IS_IPV6(t) (((t) == LWIP_DNS_ADDRTYPE_IPV6_IPV4) || ((t) == LWIP_DNS_ADDRTYPE_IPV6))
+#define LWIP_DNS_ADDRTYPE_MATCH_IP(t, ip) (IP_IS_V6_VAL(ip) ? LWIP_DNS_ADDRTYPE_IS_IPV6(t) : (!LWIP_DNS_ADDRTYPE_IS_IPV6(t)))
+#define LWIP_DNS_ADDRTYPE_ARG(x) , x
+#define LWIP_DNS_ADDRTYPE_ARG_OR_ZERO(x) x
+#define LWIP_DNS_SET_ADDRTYPE(x, y) do { x = y; } while(0)
+#else
+#if LWIP_IPV6
+#define LWIP_DNS_ADDRTYPE_IS_IPV6(t) 1
+#else
+#define LWIP_DNS_ADDRTYPE_IS_IPV6(t) 0
+#endif
+#define LWIP_DNS_ADDRTYPE_MATCH_IP(t, ip) 1
+#define LWIP_DNS_ADDRTYPE_ARG(x)
+#define LWIP_DNS_ADDRTYPE_ARG_OR_ZERO(x) 0
+#define LWIP_DNS_SET_ADDRTYPE(x, y)
+#endif /* LWIP_IPV4 && LWIP_IPV6 */
+
+#if LWIP_DNS_SUPPORT_MDNS_QUERIES
+#define LWIP_DNS_ISMDNS_ARG(x) , x
+#else
+#define LWIP_DNS_ISMDNS_ARG(x)
+#endif
+
+/** DNS query message structure.
+    No packing needed: only used locally on the stack. */
+struct dns_query {
+  /* DNS query record starts with either a domain name or a pointer
+     to a name already present somewhere in the packet. */
+  u16_t type;
+  u16_t cls;
+};
+#define SIZEOF_DNS_QUERY 4
+
+/** DNS answer message structure.
+    No packing needed: only used locally on the stack. */
+struct dns_answer {
+  /* DNS answer record starts with either a domain name or a pointer
+     to a name already present somewhere in the packet. */
+  u16_t type;
+  u16_t cls;
+  u32_t ttl;
+  u16_t len;
+};
+#define SIZEOF_DNS_ANSWER 10
+/* maximum allowed size for the struct due to non-packed */
+#define SIZEOF_DNS_ANSWER_ASSERT 12
+
+/* DNS table entry states */
+typedef enum {
+  DNS_STATE_UNUSED           = 0,
+  DNS_STATE_NEW              = 1,
+  DNS_STATE_ASKING           = 2,
+  DNS_STATE_DONE             = 3
+} dns_state_enum_t;
+
+/** DNS table entry */
+struct dns_table_entry {
+  u32_t ttl;
+  ip_addr_t ipaddr;
+  u16_t txid;
+  u8_t  state;
+  u8_t  server_idx;
+  u8_t  tmr;
+  u8_t  retries;
+  u8_t  seqno;
+#if ((LWIP_DNS_SECURE & LWIP_DNS_SECURE_RAND_SRC_PORT) != 0)
+  u8_t pcb_idx;
+#endif
+  char name[DNS_MAX_NAME_LENGTH];
+#if LWIP_IPV4 && LWIP_IPV6
+  u8_t reqaddrtype;
+#endif /* LWIP_IPV4 && LWIP_IPV6 */
+#if LWIP_DNS_SUPPORT_MDNS_QUERIES
+  u8_t is_mdns;
+#endif
+};
+
+/** DNS request table entry: used when dns_gehostbyname cannot answer the
+ * request from the DNS table */
+struct dns_req_entry {
+  /* pointer to callback on DNS query done */
+  dns_found_callback found;
+  /* argument passed to the callback function */
+  void *arg;
+#if ((LWIP_DNS_SECURE & LWIP_DNS_SECURE_NO_MULTIPLE_OUTSTANDING) != 0)
+  u8_t dns_table_idx;
+#endif
+#if LWIP_IPV4 && LWIP_IPV6
+  u8_t reqaddrtype;
+#endif /* LWIP_IPV4 && LWIP_IPV6 */
+};
+
+#if DNS_LOCAL_HOSTLIST
+
+#if DNS_LOCAL_HOSTLIST_IS_DYNAMIC
+/** Local host-list. For hostnames in this list, no
+ *  external name resolution is performed */
+static struct local_hostlist_entry *local_hostlist_dynamic;
+#else /* DNS_LOCAL_HOSTLIST_IS_DYNAMIC */
+
+/** Defining this allows the local_hostlist_static to be placed in a different
+ * linker section (e.g. FLASH) */
+#ifndef DNS_LOCAL_HOSTLIST_STORAGE_PRE
+#define DNS_LOCAL_HOSTLIST_STORAGE_PRE static
+#endif /* DNS_LOCAL_HOSTLIST_STORAGE_PRE */
+/** Defining this allows the local_hostlist_static to be placed in a different
+ * linker section (e.g. FLASH) */
+#ifndef DNS_LOCAL_HOSTLIST_STORAGE_POST
+#define DNS_LOCAL_HOSTLIST_STORAGE_POST
+#endif /* DNS_LOCAL_HOSTLIST_STORAGE_POST */
+DNS_LOCAL_HOSTLIST_STORAGE_PRE struct local_hostlist_entry local_hostlist_static[]
+  DNS_LOCAL_HOSTLIST_STORAGE_POST = DNS_LOCAL_HOSTLIST_INIT;
+
+#endif /* DNS_LOCAL_HOSTLIST_IS_DYNAMIC */
+
+static void dns_init_local(void);
+static err_t dns_lookup_local(const char *hostname, ip_addr_t *addr LWIP_DNS_ADDRTYPE_ARG(u8_t dns_addrtype));
+#endif /* DNS_LOCAL_HOSTLIST */
+
+
+/* forward declarations */
+static void dns_recv(void *s, struct udp_pcb *pcb, struct pbuf *p, const ip_addr_t *addr, u16_t port);
+static void dns_check_entries(void);
+static void dns_call_found(u8_t idx, ip_addr_t *addr);
+
+/*-----------------------------------------------------------------------------
+ * Globals
+ *----------------------------------------------------------------------------*/
+
+/* DNS variables */
+static struct udp_pcb        *dns_pcbs[DNS_MAX_SOURCE_PORTS];
+#if ((LWIP_DNS_SECURE & LWIP_DNS_SECURE_RAND_SRC_PORT) != 0)
+static u8_t                   dns_last_pcb_idx;
+#endif
+static u8_t                   dns_seqno;
+static struct dns_table_entry dns_table[DNS_TABLE_SIZE];
+static struct dns_req_entry   dns_requests[DNS_MAX_REQUESTS];
+static ip_addr_t              dns_servers[DNS_MAX_SERVERS];
+
+#if LWIP_IPV4
+const ip_addr_t dns_mquery_v4group = DNS_MQUERY_IPV4_GROUP_INIT;
+#endif /* LWIP_IPV4 */
+#if LWIP_IPV6
+const ip_addr_t dns_mquery_v6group = DNS_MQUERY_IPV6_GROUP_INIT;
+#endif /* LWIP_IPV6 */
+
+/**
+ * Initialize the resolver: set up the UDP pcb and configure the default server
+ * (if DNS_SERVER_ADDRESS is set).
+ */
+void
+dns_init(void)
+{
+#ifdef DNS_SERVER_ADDRESS
+  /* initialize default DNS server address */
+  ip_addr_t dnsserver;
+  DNS_SERVER_ADDRESS(&dnsserver);
+  dns_setserver(0, &dnsserver);
+#endif /* DNS_SERVER_ADDRESS */
+
+  LWIP_ASSERT("sanity check SIZEOF_DNS_QUERY",
+              sizeof(struct dns_query) == SIZEOF_DNS_QUERY);
+  LWIP_ASSERT("sanity check SIZEOF_DNS_ANSWER",
+              sizeof(struct dns_answer) <= SIZEOF_DNS_ANSWER_ASSERT);
+
+  LWIP_DEBUGF(DNS_DEBUG, ("dns_init: initializing\n"));
+
+  /* if dns client not yet initialized... */
+#if ((LWIP_DNS_SECURE & LWIP_DNS_SECURE_RAND_SRC_PORT) == 0)
+  if (dns_pcbs[0] == NULL) {
+    dns_pcbs[0] = udp_new_ip_type(IPADDR_TYPE_ANY);
+    LWIP_ASSERT("dns_pcbs[0] != NULL", dns_pcbs[0] != NULL);
+
+    /* initialize DNS table not needed (initialized to zero since it is a
+     * global variable) */
+    LWIP_ASSERT("For implicit initialization to work, DNS_STATE_UNUSED needs to be 0",
+                DNS_STATE_UNUSED == 0);
+
+    /* initialize DNS client */
+    udp_bind(dns_pcbs[0], IP_ANY_TYPE, 0);
+    udp_recv(dns_pcbs[0], dns_recv, NULL);
+  }
+#endif
+
+#if DNS_LOCAL_HOSTLIST
+  dns_init_local();
+#endif
+}
+
+/**
+ * @ingroup dns
+ * Initialize one of the DNS servers.
+ *
+ * @param numdns the index of the DNS server to set must be < DNS_MAX_SERVERS
+ * @param dnsserver IP address of the DNS server to set
+ */
+void
+dns_setserver(u8_t numdns, const ip_addr_t *dnsserver)
+{
+  if (numdns < DNS_MAX_SERVERS) {
+    if (dnsserver != NULL) {
+      dns_servers[numdns] = (*dnsserver);
+    } else {
+      dns_servers[numdns] = *IP_ADDR_ANY;
+    }
+  }
+}
+
+/**
+ * @ingroup dns
+ * Obtain one of the currently configured DNS server.
+ *
+ * @param numdns the index of the DNS server
+ * @return IP address of the indexed DNS server or "ip_addr_any" if the DNS
+ *         server has not been configured.
+ */
+const ip_addr_t *
+dns_getserver(u8_t numdns)
+{
+  if (numdns < DNS_MAX_SERVERS) {
+    return &dns_servers[numdns];
+  } else {
+    return IP_ADDR_ANY;
+  }
+}
+
+/**
+ * The DNS resolver client timer - handle retries and timeouts and should
+ * be called every DNS_TMR_INTERVAL milliseconds (every second by default).
+ */
+void
+dns_tmr(void)
+{
+  LWIP_DEBUGF(DNS_DEBUG, ("dns_tmr: dns_check_entries\n"));
+  dns_check_entries();
+}
+
+#if DNS_LOCAL_HOSTLIST
+static void
+dns_init_local(void)
+{
+#if DNS_LOCAL_HOSTLIST_IS_DYNAMIC && defined(DNS_LOCAL_HOSTLIST_INIT)
+  size_t i;
+  struct local_hostlist_entry *entry;
+  /* Dynamic: copy entries from DNS_LOCAL_HOSTLIST_INIT to list */
+  struct local_hostlist_entry local_hostlist_init[] = DNS_LOCAL_HOSTLIST_INIT;
+  size_t namelen;
+  for (i = 0; i < LWIP_ARRAYSIZE(local_hostlist_init); i++) {
+    struct local_hostlist_entry *init_entry = &local_hostlist_init[i];
+    LWIP_ASSERT("invalid host name (NULL)", init_entry->name != NULL);
+    namelen = strlen(init_entry->name);
+    LWIP_ASSERT("namelen <= DNS_LOCAL_HOSTLIST_MAX_NAMELEN", namelen <= DNS_LOCAL_HOSTLIST_MAX_NAMELEN);
+    entry = (struct local_hostlist_entry *)memp_malloc(MEMP_LOCALHOSTLIST);
+    LWIP_ASSERT("mem-error in dns_init_local", entry != NULL);
+    if (entry != NULL) {
+      char *entry_name = (char *)entry + sizeof(struct local_hostlist_entry);
+      MEMCPY(entry_name, init_entry->name, namelen);
+      entry_name[namelen] = 0;
+      entry->name = entry_name;
+      entry->addr = init_entry->addr;
+      entry->next = local_hostlist_dynamic;
+      local_hostlist_dynamic = entry;
+    }
+  }
+#endif /* DNS_LOCAL_HOSTLIST_IS_DYNAMIC && defined(DNS_LOCAL_HOSTLIST_INIT) */
+}
+
+/**
+ * @ingroup dns
+ * Iterate the local host-list for a hostname.
+ *
+ * @param iterator_fn a function that is called for every entry in the local host-list
+ * @param iterator_arg 3rd argument passed to iterator_fn
+ * @return the number of entries in the local host-list
+ */
+size_t
+dns_local_iterate(dns_found_callback iterator_fn, void *iterator_arg)
+{
+  size_t i;
+#if DNS_LOCAL_HOSTLIST_IS_DYNAMIC
+  struct local_hostlist_entry *entry = local_hostlist_dynamic;
+  i = 0;
+  while (entry != NULL) {
+    if (iterator_fn != NULL) {
+      iterator_fn(entry->name, &entry->addr, iterator_arg);
+    }
+    i++;
+    entry = entry->next;
+  }
+#else /* DNS_LOCAL_HOSTLIST_IS_DYNAMIC */
+  for (i = 0; i < LWIP_ARRAYSIZE(local_hostlist_static); i++) {
+    if (iterator_fn != NULL) {
+      iterator_fn(local_hostlist_static[i].name, &local_hostlist_static[i].addr, iterator_arg);
+    }
+  }
+#endif /* DNS_LOCAL_HOSTLIST_IS_DYNAMIC */
+  return i;
+}
+
+/**
+ * @ingroup dns
+ * Scans the local host-list for a hostname.
+ *
+ * @param hostname Hostname to look for in the local host-list
+ * @param addr the first IP address for the hostname in the local host-list or
+ *         IPADDR_NONE if not found.
+ * @param dns_addrtype - LWIP_DNS_ADDRTYPE_IPV4_IPV6: try to resolve IPv4 (ATTENTION: no fallback here!)
+ *                     - LWIP_DNS_ADDRTYPE_IPV6_IPV4: try to resolve IPv6 (ATTENTION: no fallback here!)
+ *                     - LWIP_DNS_ADDRTYPE_IPV4: try to resolve IPv4 only
+ *                     - LWIP_DNS_ADDRTYPE_IPV6: try to resolve IPv6 only
+ * @return ERR_OK if found, ERR_ARG if not found
+ */
+err_t
+dns_local_lookup(const char *hostname, ip_addr_t *addr, u8_t dns_addrtype)
+{
+  LWIP_UNUSED_ARG(dns_addrtype);
+  return dns_lookup_local(hostname, addr LWIP_DNS_ADDRTYPE_ARG(dns_addrtype));
+}
+
+/* Internal implementation for dns_local_lookup and dns_lookup */
+static err_t
+dns_lookup_local(const char *hostname, ip_addr_t *addr LWIP_DNS_ADDRTYPE_ARG(u8_t dns_addrtype))
+{
+#if DNS_LOCAL_HOSTLIST_IS_DYNAMIC
+  struct local_hostlist_entry *entry = local_hostlist_dynamic;
+  while (entry != NULL) {
+    if ((lwip_stricmp(entry->name, hostname) == 0) &&
+        LWIP_DNS_ADDRTYPE_MATCH_IP(dns_addrtype, entry->addr)) {
+      if (addr) {
+        ip_addr_copy(*addr, entry->addr);
+      }
+      return ERR_OK;
+    }
+    entry = entry->next;
+  }
+#else /* DNS_LOCAL_HOSTLIST_IS_DYNAMIC */
+  size_t i;
+  for (i = 0; i < LWIP_ARRAYSIZE(local_hostlist_static); i++) {
+    if ((lwip_stricmp(local_hostlist_static[i].name, hostname) == 0) &&
+        LWIP_DNS_ADDRTYPE_MATCH_IP(dns_addrtype, local_hostlist_static[i].addr)) {
+      if (addr) {
+        ip_addr_copy(*addr, local_hostlist_static[i].addr);
+      }
+      return ERR_OK;
+    }
+  }
+#endif /* DNS_LOCAL_HOSTLIST_IS_DYNAMIC */
+  return ERR_ARG;
+}
+
+#if DNS_LOCAL_HOSTLIST_IS_DYNAMIC
+/**
+ * @ingroup dns
+ * Remove all entries from the local host-list for a specific hostname
+ * and/or IP address
+ *
+ * @param hostname hostname for which entries shall be removed from the local
+ *                 host-list
+ * @param addr address for which entries shall be removed from the local host-list
+ * @return the number of removed entries
+ */
+int
+dns_local_removehost(const char *hostname, const ip_addr_t *addr)
+{
+  int removed = 0;
+  struct local_hostlist_entry *entry = local_hostlist_dynamic;
+  struct local_hostlist_entry *last_entry = NULL;
+  while (entry != NULL) {
+    if (((hostname == NULL) || !lwip_stricmp(entry->name, hostname)) &&
+        ((addr == NULL) || ip_addr_cmp(&entry->addr, addr))) {
+      struct local_hostlist_entry *free_entry;
+      if (last_entry != NULL) {
+        last_entry->next = entry->next;
+      } else {
+        local_hostlist_dynamic = entry->next;
+      }
+      free_entry = entry;
+      entry = entry->next;
+      memp_free(MEMP_LOCALHOSTLIST, free_entry);
+      removed++;
+    } else {
+      last_entry = entry;
+      entry = entry->next;
+    }
+  }
+  return removed;
+}
+
+/**
+ * @ingroup dns
+ * Add a hostname/IP address pair to the local host-list.
+ * Duplicates are not checked.
+ *
+ * @param hostname hostname of the new entry
+ * @param addr IP address of the new entry
+ * @return ERR_OK if succeeded or ERR_MEM on memory error
+ */
+err_t
+dns_local_addhost(const char *hostname, const ip_addr_t *addr)
+{
+  struct local_hostlist_entry *entry;
+  size_t namelen;
+  char *entry_name;
+  LWIP_ASSERT("invalid host name (NULL)", hostname != NULL);
+  namelen = strlen(hostname);
+  LWIP_ASSERT("namelen <= DNS_LOCAL_HOSTLIST_MAX_NAMELEN", namelen <= DNS_LOCAL_HOSTLIST_MAX_NAMELEN);
+  entry = (struct local_hostlist_entry *)memp_malloc(MEMP_LOCALHOSTLIST);
+  if (entry == NULL) {
+    return ERR_MEM;
+  }
+  entry_name = (char *)entry + sizeof(struct local_hostlist_entry);
+  MEMCPY(entry_name, hostname, namelen);
+  entry_name[namelen] = 0;
+  entry->name = entry_name;
+  ip_addr_copy(entry->addr, *addr);
+  entry->next = local_hostlist_dynamic;
+  local_hostlist_dynamic = entry;
+  return ERR_OK;
+}
+#endif /* DNS_LOCAL_HOSTLIST_IS_DYNAMIC*/
+#endif /* DNS_LOCAL_HOSTLIST */
+
+/**
+ * @ingroup dns
+ * Look up a hostname in the array of known hostnames.
+ *
+ * @note This function only looks in the internal array of known
+ * hostnames, it does not send out a query for the hostname if none
+ * was found. The function dns_enqueue() can be used to send a query
+ * for a hostname.
+ *
+ * @param name the hostname to look up
+ * @param addr the hostname's IP address, as u32_t (instead of ip_addr_t to
+ *         better check for failure: != IPADDR_NONE) or IPADDR_NONE if the hostname
+ *         was not found in the cached dns_table.
+ * @return ERR_OK if found, ERR_ARG if not found
+ */
+static err_t
+dns_lookup(const char *name, ip_addr_t *addr LWIP_DNS_ADDRTYPE_ARG(u8_t dns_addrtype))
+{
+  u8_t i;
+#if DNS_LOCAL_HOSTLIST
+  if (dns_lookup_local(name, addr LWIP_DNS_ADDRTYPE_ARG(dns_addrtype)) == ERR_OK) {
+    return ERR_OK;
+  }
+#endif /* DNS_LOCAL_HOSTLIST */
+#ifdef DNS_LOOKUP_LOCAL_EXTERN
+  if (DNS_LOOKUP_LOCAL_EXTERN(name, addr, LWIP_DNS_ADDRTYPE_ARG_OR_ZERO(dns_addrtype)) == ERR_OK) {
+    return ERR_OK;
+  }
+#endif /* DNS_LOOKUP_LOCAL_EXTERN */
+
+  /* Walk through name list, return entry if found. If not, return NULL. */
+  for (i = 0; i < DNS_TABLE_SIZE; ++i) {
+    if ((dns_table[i].state == DNS_STATE_DONE) &&
+        (lwip_strnicmp(name, dns_table[i].name, sizeof(dns_table[i].name)) == 0) &&
+        LWIP_DNS_ADDRTYPE_MATCH_IP(dns_addrtype, dns_table[i].ipaddr)) {
+      LWIP_DEBUGF(DNS_DEBUG, ("dns_lookup: \"%s\": found = ", name));
+      ip_addr_debug_print_val(DNS_DEBUG, dns_table[i].ipaddr);
+      LWIP_DEBUGF(DNS_DEBUG, ("\n"));
+      if (addr) {
+        ip_addr_copy(*addr, dns_table[i].ipaddr);
+      }
+      return ERR_OK;
+    }
+  }
+
+  return ERR_ARG;
+}
+
+/**
+ * Compare the "dotted" name "query" with the encoded name "response"
+ * to make sure an answer from the DNS server matches the current dns_table
+ * entry (otherwise, answers might arrive late for hostname not on the list
+ * any more).
+ *
+ * For now, this function compares case-insensitive to cope with all kinds of
+ * servers. This also means that "dns 0x20 bit encoding" must be checked
+ * externally, if we want to implement it.
+ * Currently, the request is sent exactly as passed in by he user request.
+ *
+ * @param query hostname (not encoded) from the dns_table
+ * @param p pbuf containing the encoded hostname in the DNS response
+ * @param start_offset offset into p where the name starts
+ * @return 0xFFFF: names differ, other: names equal -> offset behind name
+ */
+static u16_t
+dns_compare_name(const char *query, struct pbuf *p, u16_t start_offset)
+{
+  int n;
+  u16_t response_offset = start_offset;
+
+  do {
+    n = pbuf_try_get_at(p, response_offset);
+    if ((n < 0) || (response_offset == 0xFFFF)) {
+      /* error or overflow */
+      return 0xFFFF;
+    }
+    response_offset++;
+    /** @see RFC 1035 - 4.1.4. Message compression */
+    if ((n & 0xc0) == 0xc0) {
+      /* Compressed name: cannot be equal since we don't send them */
+      return 0xFFFF;
+    } else {
+      /* Not compressed name */
+      while (n > 0) {
+        int c = pbuf_try_get_at(p, response_offset);
+        if (c < 0) {
+          return 0xFFFF;
+        }
+        if (lwip_tolower((*query)) != lwip_tolower((u8_t)c)) {
+          return 0xFFFF;
+        }
+        if (response_offset == 0xFFFF) {
+          /* would overflow */
+          return 0xFFFF;
+        }
+        response_offset++;
+        ++query;
+        --n;
+      }
+      ++query;
+    }
+    n = pbuf_try_get_at(p, response_offset);
+    if (n < 0) {
+      return 0xFFFF;
+    }
+  } while (n != 0);
+
+  if (response_offset == 0xFFFF) {
+    /* would overflow */
+    return 0xFFFF;
+  }
+  return (u16_t)(response_offset + 1);
+}
+
+/**
+ * Walk through a compact encoded DNS name and return the end of the name.
+ *
+ * @param p pbuf containing the name
+ * @param query_idx start index into p pointing to encoded DNS name in the DNS server response
+ * @return index to end of the name
+ */
+static u16_t
+dns_skip_name(struct pbuf *p, u16_t query_idx)
+{
+  int n;
+  u16_t offset = query_idx;
+
+  do {
+    n = pbuf_try_get_at(p, offset++);
+    if ((n < 0) || (offset == 0)) {
+      return 0xFFFF;
+    }
+    /** @see RFC 1035 - 4.1.4. Message compression */
+    if ((n & 0xc0) == 0xc0) {
+      /* Compressed name: since we only want to skip it (not check it), stop here */
+      break;
+    } else {
+      /* Not compressed name */
+      if (offset + n >= p->tot_len) {
+        return 0xFFFF;
+      }
+      offset = (u16_t)(offset + n);
+    }
+    n = pbuf_try_get_at(p, offset);
+    if (n < 0) {
+      return 0xFFFF;
+    }
+  } while (n != 0);
+
+  if (offset == 0xFFFF) {
+    return 0xFFFF;
+  }
+  return (u16_t)(offset + 1);
+}
+
+/**
+ * Send a DNS query packet.
+ *
+ * @param idx the DNS table entry index for which to send a request
+ * @return ERR_OK if packet is sent; an err_t indicating the problem otherwise
+ */
+static err_t
+dns_send(u8_t idx)
+{
+  err_t err;
+  struct dns_hdr hdr;
+  struct dns_query qry;
+  struct pbuf *p;
+  u16_t query_idx, copy_len;
+  const char *hostname, *hostname_part;
+  u8_t n;
+  u8_t pcb_idx;
+  struct dns_table_entry *entry = &dns_table[idx];
+
+  LWIP_DEBUGF(DNS_DEBUG, ("dns_send: dns_servers[%"U16_F"] \"%s\": request\n",
+                          (u16_t)(entry->server_idx), entry->name));
+  LWIP_ASSERT("dns server out of array", entry->server_idx < DNS_MAX_SERVERS);
+  if (ip_addr_isany_val(dns_servers[entry->server_idx])
+#if LWIP_DNS_SUPPORT_MDNS_QUERIES
+      && !entry->is_mdns
+#endif
+     ) {
+    /* DNS server not valid anymore, e.g. PPP netif has been shut down */
+    /* call specified callback function if provided */
+    dns_call_found(idx, NULL);
+    /* flush this entry */
+    entry->state = DNS_STATE_UNUSED;
+    return ERR_OK;
+  }
+
+  /* if here, we have either a new query or a retry on a previous query to process */
+  p = pbuf_alloc(PBUF_TRANSPORT, (u16_t)(SIZEOF_DNS_HDR + strlen(entry->name) + 2 +
+                                         SIZEOF_DNS_QUERY), PBUF_RAM);
+  if (p != NULL) {
+    const ip_addr_t *dst;
+    u16_t dst_port;
+    /* fill dns header */
+    memset(&hdr, 0, SIZEOF_DNS_HDR);
+    hdr.id = lwip_htons(entry->txid);
+    hdr.flags1 = DNS_FLAG1_RD;
+    hdr.numquestions = PP_HTONS(1);
+    pbuf_take(p, &hdr, SIZEOF_DNS_HDR);
+    hostname = entry->name;
+    --hostname;
+
+    /* convert hostname into suitable query format. */
+    query_idx = SIZEOF_DNS_HDR;
+    do {
+      ++hostname;
+      hostname_part = hostname;
+      for (n = 0; *hostname != '.' && *hostname != 0; ++hostname) {
+        ++n;
+      }
+      copy_len = (u16_t)(hostname - hostname_part);
+      if (query_idx + n + 1 > 0xFFFF) {
+        /* u16_t overflow */
+        goto overflow_return;
+      }
+      pbuf_put_at(p, query_idx, n);
+      pbuf_take_at(p, hostname_part, copy_len, (u16_t)(query_idx + 1));
+      query_idx = (u16_t)(query_idx + n + 1);
+    } while (*hostname != 0);
+    pbuf_put_at(p, query_idx, 0);
+    query_idx++;
+
+    /* fill dns query */
+    if (LWIP_DNS_ADDRTYPE_IS_IPV6(entry->reqaddrtype)) {
+      qry.type = PP_HTONS(DNS_RRTYPE_AAAA);
+    } else {
+      qry.type = PP_HTONS(DNS_RRTYPE_A);
+    }
+    qry.cls = PP_HTONS(DNS_RRCLASS_IN);
+    pbuf_take_at(p, &qry, SIZEOF_DNS_QUERY, query_idx);
+
+#if ((LWIP_DNS_SECURE & LWIP_DNS_SECURE_RAND_SRC_PORT) != 0)
+    pcb_idx = entry->pcb_idx;
+#else
+    pcb_idx = 0;
+#endif
+    /* send dns packet */
+    LWIP_DEBUGF(DNS_DEBUG, ("sending DNS request ID %d for name \"%s\" to server %d\r\n",
+                            entry->txid, entry->name, entry->server_idx));
+#if LWIP_DNS_SUPPORT_MDNS_QUERIES
+    if (entry->is_mdns) {
+      dst_port = DNS_MQUERY_PORT;
+#if LWIP_IPV6
+      if (LWIP_DNS_ADDRTYPE_IS_IPV6(entry->reqaddrtype)) {
+        dst = &dns_mquery_v6group;
+      }
+#endif
+#if LWIP_IPV4 && LWIP_IPV6
+      else
+#endif
+#if LWIP_IPV4
+      {
+        dst = &dns_mquery_v4group;
+      }
+#endif
+    } else
+#endif /* LWIP_DNS_SUPPORT_MDNS_QUERIES */
+    {
+      dst_port = DNS_SERVER_PORT;
+      dst = &dns_servers[entry->server_idx];
+    }
+    err = udp_sendto(dns_pcbs[pcb_idx], p, dst, dst_port);
+
+    /* free pbuf */
+    pbuf_free(p);
+  } else {
+    err = ERR_MEM;
+  }
+
+  return err;
+overflow_return:
+  pbuf_free(p);
+  return ERR_VAL;
+}
+
+#if ((LWIP_DNS_SECURE & LWIP_DNS_SECURE_RAND_SRC_PORT) != 0)
+static struct udp_pcb *
+dns_alloc_random_port(void)
+{
+  err_t err;
+  struct udp_pcb *pcb;
+
+  pcb = udp_new_ip_type(IPADDR_TYPE_ANY);
+  if (pcb == NULL) {
+    /* out of memory, have to reuse an existing pcb */
+    return NULL;
+  }
+  do {
+    u16_t port = (u16_t)DNS_RAND_TXID();
+    if (DNS_PORT_ALLOWED(port)) {
+      err = udp_bind(pcb, IP_ANY_TYPE, port);
+    } else {
+      /* this port is not allowed, try again */
+      err = ERR_USE;
+    }
+  } while (err == ERR_USE);
+  if (err != ERR_OK) {
+    udp_remove(pcb);
+    return NULL;
+  }
+  udp_recv(pcb, dns_recv, NULL);
+  return pcb;
+}
+
+/**
+ * dns_alloc_pcb() - allocates a new pcb (or reuses an existing one) to be used
+ * for sending a request
+ *
+ * @return an index into dns_pcbs
+ */
+static u8_t
+dns_alloc_pcb(void)
+{
+  u8_t i;
+  u8_t idx;
+
+  for (i = 0; i < DNS_MAX_SOURCE_PORTS; i++) {
+    if (dns_pcbs[i] == NULL) {
+      break;
+    }
+  }
+  if (i < DNS_MAX_SOURCE_PORTS) {
+    dns_pcbs[i] = dns_alloc_random_port();
+    if (dns_pcbs[i] != NULL) {
+      /* succeeded */
+      dns_last_pcb_idx = i;
+      return i;
+    }
+  }
+  /* if we come here, creating a new UDP pcb failed, so we have to use
+     an already existing one (so overflow is no issue) */
+  for (i = 0, idx = (u8_t)(dns_last_pcb_idx + 1); i < DNS_MAX_SOURCE_PORTS; i++, idx++) {
+    if (idx >= DNS_MAX_SOURCE_PORTS) {
+      idx = 0;
+    }
+    if (dns_pcbs[idx] != NULL) {
+      dns_last_pcb_idx = idx;
+      return idx;
+    }
+  }
+  return DNS_MAX_SOURCE_PORTS;
+}
+#endif /* ((LWIP_DNS_SECURE & LWIP_DNS_SECURE_RAND_SRC_PORT) != 0) */
+
+/**
+ * dns_call_found() - call the found callback and check if there are duplicate
+ * entries for the given hostname. If there are any, their found callback will
+ * be called and they will be removed.
+ *
+ * @param idx dns table index of the entry that is resolved or removed
+ * @param addr IP address for the hostname (or NULL on error or memory shortage)
+ */
+static void
+dns_call_found(u8_t idx, ip_addr_t *addr)
+{
+#if ((LWIP_DNS_SECURE & (LWIP_DNS_SECURE_NO_MULTIPLE_OUTSTANDING | LWIP_DNS_SECURE_RAND_SRC_PORT)) != 0)
+  u8_t i;
+#endif
+
+#if LWIP_IPV4 && LWIP_IPV6
+  if (addr != NULL) {
+    /* check that address type matches the request and adapt the table entry */
+    if (IP_IS_V6_VAL(*addr)) {
+      LWIP_ASSERT("invalid response", LWIP_DNS_ADDRTYPE_IS_IPV6(dns_table[idx].reqaddrtype));
+      dns_table[idx].reqaddrtype = LWIP_DNS_ADDRTYPE_IPV6;
+    } else {
+      LWIP_ASSERT("invalid response", !LWIP_DNS_ADDRTYPE_IS_IPV6(dns_table[idx].reqaddrtype));
+      dns_table[idx].reqaddrtype = LWIP_DNS_ADDRTYPE_IPV4;
+    }
+  }
+#endif /* LWIP_IPV4 && LWIP_IPV6 */
+
+#if ((LWIP_DNS_SECURE & LWIP_DNS_SECURE_NO_MULTIPLE_OUTSTANDING) != 0)
+  for (i = 0; i < DNS_MAX_REQUESTS; i++) {
+    if (dns_requests[i].found && (dns_requests[i].dns_table_idx == idx)) {
+      (*dns_requests[i].found)(dns_table[idx].name, addr, dns_requests[i].arg);
+      /* flush this entry */
+      dns_requests[i].found = NULL;
+    }
+  }
+#else
+  if (dns_requests[idx].found) {
+    (*dns_requests[idx].found)(dns_table[idx].name, addr, dns_requests[idx].arg);
+  }
+  dns_requests[idx].found = NULL;
+#endif
+#if ((LWIP_DNS_SECURE & LWIP_DNS_SECURE_RAND_SRC_PORT) != 0)
+  /* close the pcb used unless other request are using it */
+  for (i = 0; i < DNS_MAX_REQUESTS; i++) {
+    if (i == idx) {
+      continue; /* only check other requests */
+    }
+    if (dns_table[i].state == DNS_STATE_ASKING) {
+      if (dns_table[i].pcb_idx == dns_table[idx].pcb_idx) {
+        /* another request is still using the same pcb */
+        dns_table[idx].pcb_idx = DNS_MAX_SOURCE_PORTS;
+        break;
+      }
+    }
+  }
+  if (dns_table[idx].pcb_idx < DNS_MAX_SOURCE_PORTS) {
+    /* if we come here, the pcb is not used any more and can be removed */
+    udp_remove(dns_pcbs[dns_table[idx].pcb_idx]);
+    dns_pcbs[dns_table[idx].pcb_idx] = NULL;
+    dns_table[idx].pcb_idx = DNS_MAX_SOURCE_PORTS;
+  }
+#endif
+}
+
+/* Create a query transmission ID that is unique for all outstanding queries */
+static u16_t
+dns_create_txid(void)
+{
+  u16_t txid;
+  u8_t i;
+
+again:
+  txid = (u16_t)DNS_RAND_TXID();
+
+  /* check whether the ID is unique */
+  for (i = 0; i < DNS_TABLE_SIZE; i++) {
+    if ((dns_table[i].state == DNS_STATE_ASKING) &&
+        (dns_table[i].txid == txid)) {
+      /* ID already used by another pending query */
+      goto again;
+    }
+  }
+
+  return txid;
+}
+
+/**
+ * Check whether there are other backup DNS servers available to try
+ */
+static u8_t
+dns_backupserver_available(struct dns_table_entry *pentry)
+{
+  u8_t ret = 0;
+
+  if (pentry) {
+    if ((pentry->server_idx + 1 < DNS_MAX_SERVERS) && !ip_addr_isany_val(dns_servers[pentry->server_idx + 1])) {
+      ret = 1;
+    }
+  }
+
+  return ret;
+}
+
+/**
+ * dns_check_entry() - see if entry has not yet been queried and, if so, sends out a query.
+ * Check an entry in the dns_table:
+ * - send out query for new entries
+ * - retry old pending entries on timeout (also with different servers)
+ * - remove completed entries from the table if their TTL has expired
+ *
+ * @param i index of the dns_table entry to check
+ */
+static void
+dns_check_entry(u8_t i)
+{
+  err_t err;
+  struct dns_table_entry *entry = &dns_table[i];
+
+  LWIP_ASSERT("array index out of bounds", i < DNS_TABLE_SIZE);
+
+  switch (entry->state) {
+    case DNS_STATE_NEW:
+      /* initialize new entry */
+      entry->txid = dns_create_txid();
+      entry->state = DNS_STATE_ASKING;
+      entry->server_idx = 0;
+      entry->tmr = 1;
+      entry->retries = 0;
+
+      /* send DNS packet for this entry */
+      err = dns_send(i);
+      if (err != ERR_OK) {
+        LWIP_DEBUGF(DNS_DEBUG | LWIP_DBG_LEVEL_WARNING,
+                    ("dns_send returned error: %s\n", lwip_strerr(err)));
+      }
+      break;
+    case DNS_STATE_ASKING:
+      if (--entry->tmr == 0) {
+        if (++entry->retries == DNS_MAX_RETRIES) {
+          if (dns_backupserver_available(entry)
+#if LWIP_DNS_SUPPORT_MDNS_QUERIES
+              && !entry->is_mdns
+#endif /* LWIP_DNS_SUPPORT_MDNS_QUERIES */
+             ) {
+            /* change of server */
+            entry->server_idx++;
+            entry->tmr = 1;
+            entry->retries = 0;
+          } else {
+            LWIP_DEBUGF(DNS_DEBUG, ("dns_check_entry: \"%s\": timeout\n", entry->name));
+            /* call specified callback function if provided */
+            dns_call_found(i, NULL);
+            /* flush this entry */
+            entry->state = DNS_STATE_UNUSED;
+            break;
+          }
+        } else {
+          /* wait longer for the next retry */
+          entry->tmr = entry->retries;
+        }
+
+        /* send DNS packet for this entry */
+        err = dns_send(i);
+        if (err != ERR_OK) {
+          LWIP_DEBUGF(DNS_DEBUG | LWIP_DBG_LEVEL_WARNING,
+                      ("dns_send returned error: %s\n", lwip_strerr(err)));
+        }
+      }
+      break;
+    case DNS_STATE_DONE:
+      /* if the time to live is nul */
+      if ((entry->ttl == 0) || (--entry->ttl == 0)) {
+        LWIP_DEBUGF(DNS_DEBUG, ("dns_check_entry: \"%s\": flush\n", entry->name));
+        /* flush this entry, there cannot be any related pending entries in this state */
+        entry->state = DNS_STATE_UNUSED;
+      }
+      break;
+    case DNS_STATE_UNUSED:
+      /* nothing to do */
+      break;
+    default:
+      LWIP_ASSERT("unknown dns_table entry state:", 0);
+      break;
+  }
+}
+
+/**
+ * Call dns_check_entry for each entry in dns_table - check all entries.
+ */
+static void
+dns_check_entries(void)
+{
+  u8_t i;
+
+  for (i = 0; i < DNS_TABLE_SIZE; ++i) {
+    dns_check_entry(i);
+  }
+}
+
+/**
+ * Save TTL and call dns_call_found for correct response.
+ */
+static void
+dns_correct_response(u8_t idx, u32_t ttl)
+{
+  struct dns_table_entry *entry = &dns_table[idx];
+
+  entry->state = DNS_STATE_DONE;
+
+  LWIP_DEBUGF(DNS_DEBUG, ("dns_recv: \"%s\": response = ", entry->name));
+  ip_addr_debug_print_val(DNS_DEBUG, entry->ipaddr);
+  LWIP_DEBUGF(DNS_DEBUG, ("\n"));
+
+  /* read the answer resource record's TTL, and maximize it if needed */
+  entry->ttl = ttl;
+  if (entry->ttl > DNS_MAX_TTL) {
+    entry->ttl = DNS_MAX_TTL;
+  }
+  dns_call_found(idx, &entry->ipaddr);
+
+  if (entry->ttl == 0) {
+    /* RFC 883, page 29: "Zero values are
+       interpreted to mean that the RR can only be used for the
+       transaction in progress, and should not be cached."
+       -> flush this entry now */
+    /* entry reused during callback? */
+    if (entry->state == DNS_STATE_DONE) {
+      entry->state = DNS_STATE_UNUSED;
+    }
+  }
+}
+
+/**
+ * Receive input function for DNS response packets arriving for the dns UDP pcb.
+ */
+static void
+dns_recv(void *arg, struct udp_pcb *pcb, struct pbuf *p, const ip_addr_t *addr, u16_t port)
+{
+  u8_t i;
+  u16_t txid;
+  u16_t res_idx;
+  struct dns_hdr hdr;
+  struct dns_answer ans;
+  struct dns_query qry;
+  u16_t nquestions, nanswers;
+
+  LWIP_UNUSED_ARG(arg);
+  LWIP_UNUSED_ARG(pcb);
+  LWIP_UNUSED_ARG(port);
+
+  /* is the dns message big enough ? */
+  if (p->tot_len < (SIZEOF_DNS_HDR + SIZEOF_DNS_QUERY)) {
+    LWIP_DEBUGF(DNS_DEBUG, ("dns_recv: pbuf too small\n"));
+    /* free pbuf and return */
+    goto ignore_packet;
+  }
+
+  /* copy dns payload inside static buffer for processing */
+  if (pbuf_copy_partial(p, &hdr, SIZEOF_DNS_HDR, 0) == SIZEOF_DNS_HDR) {
+    /* Match the ID in the DNS header with the name table. */
+    txid = lwip_htons(hdr.id);
+    for (i = 0; i < DNS_TABLE_SIZE; i++) {
+      struct dns_table_entry *entry = &dns_table[i];
+      if ((entry->state == DNS_STATE_ASKING) &&
+          (entry->txid == txid)) {
+
+        /* We only care about the question(s) and the answers. The authrr
+           and the extrarr are simply discarded. */
+        nquestions = lwip_htons(hdr.numquestions);
+        nanswers   = lwip_htons(hdr.numanswers);
+
+        /* Check for correct response. */
+        if ((hdr.flags1 & DNS_FLAG1_RESPONSE) == 0) {
+          LWIP_DEBUGF(DNS_DEBUG, ("dns_recv: \"%s\": not a response\n", entry->name));
+          goto ignore_packet; /* ignore this packet */
+        }
+        if (nquestions != 1) {
+          LWIP_DEBUGF(DNS_DEBUG, ("dns_recv: \"%s\": response not match to query\n", entry->name));
+          goto ignore_packet; /* ignore this packet */
+        }
+
+#if LWIP_DNS_SUPPORT_MDNS_QUERIES
+        if (!entry->is_mdns)
+#endif /* LWIP_DNS_SUPPORT_MDNS_QUERIES */
+        {
+          /* Check whether response comes from the same network address to which the
+             question was sent. (RFC 5452) */
+          if (!ip_addr_cmp(addr, &dns_servers[entry->server_idx])) {
+            goto ignore_packet; /* ignore this packet */
+          }
+        }
+
+        /* Check if the name in the "question" part match with the name in the entry and
+           skip it if equal. */
+        res_idx = dns_compare_name(entry->name, p, SIZEOF_DNS_HDR);
+        if (res_idx == 0xFFFF) {
+          LWIP_DEBUGF(DNS_DEBUG, ("dns_recv: \"%s\": response not match to query\n", entry->name));
+          goto ignore_packet; /* ignore this packet */
+        }
+
+        /* check if "question" part matches the request */
+        if (pbuf_copy_partial(p, &qry, SIZEOF_DNS_QUERY, res_idx) != SIZEOF_DNS_QUERY) {
+          goto ignore_packet; /* ignore this packet */
+        }
+        if ((qry.cls != PP_HTONS(DNS_RRCLASS_IN)) ||
+            (LWIP_DNS_ADDRTYPE_IS_IPV6(entry->reqaddrtype) && (qry.type != PP_HTONS(DNS_RRTYPE_AAAA))) ||
+            (!LWIP_DNS_ADDRTYPE_IS_IPV6(entry->reqaddrtype) && (qry.type != PP_HTONS(DNS_RRTYPE_A)))) {
+          LWIP_DEBUGF(DNS_DEBUG, ("dns_recv: \"%s\": response not match to query\n", entry->name));
+          goto ignore_packet; /* ignore this packet */
+        }
+        /* skip the rest of the "question" part */
+        if (res_idx + SIZEOF_DNS_QUERY > 0xFFFF) {
+          goto ignore_packet;
+        }
+        res_idx = (u16_t)(res_idx + SIZEOF_DNS_QUERY);
+
+        /* Check for error. If so, call callback to inform. */
+        if (hdr.flags2 & DNS_FLAG2_ERR_MASK) {
+          LWIP_DEBUGF(DNS_DEBUG, ("dns_recv: \"%s\": error in flags\n", entry->name));
+
+          /* if there is another backup DNS server to try
+           * then don't stop the DNS request
+           */
+          if (dns_backupserver_available(entry)) {
+            /* avoid retrying the same server */
+            entry->retries = DNS_MAX_RETRIES-1;
+            entry->tmr     = 1;
+
+            /* contact next available server for this entry */
+            dns_check_entry(i);
+
+            goto ignore_packet;
+          }
+        } else {
+          while ((nanswers > 0) && (res_idx < p->tot_len)) {
+            /* skip answer resource record's host name */
+            res_idx = dns_skip_name(p, res_idx);
+            if (res_idx == 0xFFFF) {
+              goto ignore_packet; /* ignore this packet */
+            }
+
+            /* Check for IP address type and Internet class. Others are discarded. */
+            if (pbuf_copy_partial(p, &ans, SIZEOF_DNS_ANSWER, res_idx) != SIZEOF_DNS_ANSWER) {
+              goto ignore_packet; /* ignore this packet */
+            }
+            if (res_idx + SIZEOF_DNS_ANSWER > 0xFFFF) {
+              goto ignore_packet;
+            }
+            res_idx = (u16_t)(res_idx + SIZEOF_DNS_ANSWER);
+
+            if (ans.cls == PP_HTONS(DNS_RRCLASS_IN)) {
+#if LWIP_IPV4
+              if ((ans.type == PP_HTONS(DNS_RRTYPE_A)) && (ans.len == PP_HTONS(sizeof(ip4_addr_t)))) {
+#if LWIP_IPV4 && LWIP_IPV6
+                if (!LWIP_DNS_ADDRTYPE_IS_IPV6(entry->reqaddrtype))
+#endif /* LWIP_IPV4 && LWIP_IPV6 */
+                {
+                  ip4_addr_t ip4addr;
+                  /* read the IP address after answer resource record's header */
+                  if (pbuf_copy_partial(p, &ip4addr, sizeof(ip4_addr_t), res_idx) != sizeof(ip4_addr_t)) {
+                    goto ignore_packet; /* ignore this packet */
+                  }
+                  ip_addr_copy_from_ip4(dns_table[i].ipaddr, ip4addr);
+                  pbuf_free(p);
+                  /* handle correct response */
+                  dns_correct_response(i, lwip_ntohl(ans.ttl));
+                  return;
+                }
+              }
+#endif /* LWIP_IPV4 */
+#if LWIP_IPV6
+              if ((ans.type == PP_HTONS(DNS_RRTYPE_AAAA)) && (ans.len == PP_HTONS(sizeof(ip6_addr_p_t)))) {
+#if LWIP_IPV4 && LWIP_IPV6
+                if (LWIP_DNS_ADDRTYPE_IS_IPV6(entry->reqaddrtype))
+#endif /* LWIP_IPV4 && LWIP_IPV6 */
+                {
+                  ip6_addr_p_t ip6addr;
+                  /* read the IP address after answer resource record's header */
+                  if (pbuf_copy_partial(p, &ip6addr, sizeof(ip6_addr_p_t), res_idx) != sizeof(ip6_addr_p_t)) {
+                    goto ignore_packet; /* ignore this packet */
+                  }
+                  /* @todo: scope ip6addr? Might be required for link-local addresses at least? */
+                  ip_addr_copy_from_ip6_packed(dns_table[i].ipaddr, ip6addr);
+                  pbuf_free(p);
+                  /* handle correct response */
+                  dns_correct_response(i, lwip_ntohl(ans.ttl));
+                  return;
+                }
+              }
+#endif /* LWIP_IPV6 */
+            }
+            /* skip this answer */
+            if ((int)(res_idx + lwip_htons(ans.len)) > 0xFFFF) {
+              goto ignore_packet; /* ignore this packet */
+            }
+            res_idx = (u16_t)(res_idx + lwip_htons(ans.len));
+            --nanswers;
+          }
+#if LWIP_IPV4 && LWIP_IPV6
+          if ((entry->reqaddrtype == LWIP_DNS_ADDRTYPE_IPV4_IPV6) ||
+              (entry->reqaddrtype == LWIP_DNS_ADDRTYPE_IPV6_IPV4)) {
+            if (entry->reqaddrtype == LWIP_DNS_ADDRTYPE_IPV4_IPV6) {
+              /* IPv4 failed, try IPv6 */
+              dns_table[i].reqaddrtype = LWIP_DNS_ADDRTYPE_IPV6;
+            } else {
+              /* IPv6 failed, try IPv4 */
+              dns_table[i].reqaddrtype = LWIP_DNS_ADDRTYPE_IPV4;
+            }
+            pbuf_free(p);
+            dns_table[i].state = DNS_STATE_NEW;
+            dns_check_entry(i);
+            return;
+          }
+#endif /* LWIP_IPV4 && LWIP_IPV6 */
+          LWIP_DEBUGF(DNS_DEBUG, ("dns_recv: \"%s\": error in response\n", entry->name));
+        }
+        /* call callback to indicate error, clean up memory and return */
+        pbuf_free(p);
+        dns_call_found(i, NULL);
+        dns_table[i].state = DNS_STATE_UNUSED;
+        return;
+      }
+    }
+  }
+
+ignore_packet:
+  /* deallocate memory and return */
+  pbuf_free(p);
+  return;
+}
+
+/**
+ * Queues a new hostname to resolve and sends out a DNS query for that hostname
+ *
+ * @param name the hostname that is to be queried
+ * @param hostnamelen length of the hostname
+ * @param found a callback function to be called on success, failure or timeout
+ * @param callback_arg argument to pass to the callback function
+ * @return err_t return code.
+ */
+static err_t
+dns_enqueue(const char *name, size_t hostnamelen, dns_found_callback found,
+            void *callback_arg LWIP_DNS_ADDRTYPE_ARG(u8_t dns_addrtype) LWIP_DNS_ISMDNS_ARG(u8_t is_mdns))
+{
+  u8_t i;
+  u8_t lseq, lseqi;
+  struct dns_table_entry *entry = NULL;
+  size_t namelen;
+  struct dns_req_entry *req;
+
+#if ((LWIP_DNS_SECURE & LWIP_DNS_SECURE_NO_MULTIPLE_OUTSTANDING) != 0)
+  u8_t r;
+  /* check for duplicate entries */
+  for (i = 0; i < DNS_TABLE_SIZE; i++) {
+    if ((dns_table[i].state == DNS_STATE_ASKING) &&
+        (lwip_strnicmp(name, dns_table[i].name, sizeof(dns_table[i].name)) == 0)) {
+#if LWIP_IPV4 && LWIP_IPV6
+      if (dns_table[i].reqaddrtype != dns_addrtype) {
+        /* requested address types don't match
+           this can lead to 2 concurrent requests, but mixing the address types
+           for the same host should not be that common */
+        continue;
+      }
+#endif /* LWIP_IPV4 && LWIP_IPV6 */
+      /* this is a duplicate entry, find a free request entry */
+      for (r = 0; r < DNS_MAX_REQUESTS; r++) {
+        if (dns_requests[r].found == 0) {
+          dns_requests[r].found = found;
+          dns_requests[r].arg = callback_arg;
+          dns_requests[r].dns_table_idx = i;
+          LWIP_DNS_SET_ADDRTYPE(dns_requests[r].reqaddrtype, dns_addrtype);
+          LWIP_DEBUGF(DNS_DEBUG, ("dns_enqueue: \"%s\": duplicate request\n", name));
+          return ERR_INPROGRESS;
+        }
+      }
+    }
+  }
+  /* no duplicate entries found */
+#endif
+
+  /* search an unused entry, or the oldest one */
+  lseq = 0;
+  lseqi = DNS_TABLE_SIZE;
+  for (i = 0; i < DNS_TABLE_SIZE; ++i) {
+    entry = &dns_table[i];
+    /* is it an unused entry ? */
+    if (entry->state == DNS_STATE_UNUSED) {
+      break;
+    }
+    /* check if this is the oldest completed entry */
+    if (entry->state == DNS_STATE_DONE) {
+      u8_t age = (u8_t)(dns_seqno - entry->seqno);
+      if (age > lseq) {
+        lseq = age;
+        lseqi = i;
+      }
+    }
+  }
+
+  /* if we don't have found an unused entry, use the oldest completed one */
+  if (i == DNS_TABLE_SIZE) {
+    if ((lseqi >= DNS_TABLE_SIZE) || (dns_table[lseqi].state != DNS_STATE_DONE)) {
+      /* no entry can be used now, table is full */
+      LWIP_DEBUGF(DNS_DEBUG, ("dns_enqueue: \"%s\": DNS entries table is full\n", name));
+      return ERR_MEM;
+    } else {
+      /* use the oldest completed one */
+      i = lseqi;
+      entry = &dns_table[i];
+    }
+  }
+
+#if ((LWIP_DNS_SECURE & LWIP_DNS_SECURE_NO_MULTIPLE_OUTSTANDING) != 0)
+  /* find a free request entry */
+  req = NULL;
+  for (r = 0; r < DNS_MAX_REQUESTS; r++) {
+    if (dns_requests[r].found == NULL) {
+      req = &dns_requests[r];
+      break;
+    }
+  }
+  if (req == NULL) {
+    /* no request entry can be used now, table is full */
+    LWIP_DEBUGF(DNS_DEBUG, ("dns_enqueue: \"%s\": DNS request entries table is full\n", name));
+    return ERR_MEM;
+  }
+  req->dns_table_idx = i;
+#else
+  /* in this configuration, the entry index is the same as the request index */
+  req = &dns_requests[i];
+#endif
+
+  /* use this entry */
+  LWIP_DEBUGF(DNS_DEBUG, ("dns_enqueue: \"%s\": use DNS entry %"U16_F"\n", name, (u16_t)(i)));
+
+  /* fill the entry */
+  entry->state = DNS_STATE_NEW;
+  entry->seqno = dns_seqno;
+  LWIP_DNS_SET_ADDRTYPE(entry->reqaddrtype, dns_addrtype);
+  LWIP_DNS_SET_ADDRTYPE(req->reqaddrtype, dns_addrtype);
+  req->found = found;
+  req->arg   = callback_arg;
+  namelen = LWIP_MIN(hostnamelen, DNS_MAX_NAME_LENGTH - 1);
+  MEMCPY(entry->name, name, namelen);
+  entry->name[namelen] = 0;
+
+#if ((LWIP_DNS_SECURE & LWIP_DNS_SECURE_RAND_SRC_PORT) != 0)
+  entry->pcb_idx = dns_alloc_pcb();
+  if (entry->pcb_idx >= DNS_MAX_SOURCE_PORTS) {
+    /* failed to get a UDP pcb */
+    LWIP_DEBUGF(DNS_DEBUG, ("dns_enqueue: \"%s\": failed to allocate a pcb\n", name));
+    entry->state = DNS_STATE_UNUSED;
+    req->found = NULL;
+    return ERR_MEM;
+  }
+  LWIP_DEBUGF(DNS_DEBUG, ("dns_enqueue: \"%s\": use DNS pcb %"U16_F"\n", name, (u16_t)(entry->pcb_idx)));
+#endif
+
+#if LWIP_DNS_SUPPORT_MDNS_QUERIES
+  entry->is_mdns = is_mdns;
+#endif
+
+  dns_seqno++;
+
+  /* force to send query without waiting timer */
+  dns_check_entry(i);
+
+  /* dns query is enqueued */
+  return ERR_INPROGRESS;
+}
+
+/**
+ * @ingroup dns
+ * Resolve a hostname (string) into an IP address.
+ * NON-BLOCKING callback version for use with raw API!!!
+ *
+ * Returns immediately with one of err_t return codes:
+ * - ERR_OK if hostname is a valid IP address string or the host
+ *   name is already in the local names table.
+ * - ERR_INPROGRESS enqueue a request to be sent to the DNS server
+ *   for resolution if no errors are present.
+ * - ERR_ARG: dns client not initialized or invalid hostname
+ *
+ * @param hostname the hostname that is to be queried
+ * @param addr pointer to a ip_addr_t where to store the address if it is already
+ *             cached in the dns_table (only valid if ERR_OK is returned!)
+ * @param found a callback function to be called on success, failure or timeout (only if
+ *              ERR_INPROGRESS is returned!)
+ * @param callback_arg argument to pass to the callback function
+ * @return a err_t return code.
+ */
+err_t
+dns_gethostbyname(const char *hostname, ip_addr_t *addr, dns_found_callback found,
+                  void *callback_arg)
+{
+  return dns_gethostbyname_addrtype(hostname, addr, found, callback_arg, LWIP_DNS_ADDRTYPE_DEFAULT);
+}
+
+/**
+ * @ingroup dns
+ * Like dns_gethostbyname, but returned address type can be controlled:
+ * @param hostname the hostname that is to be queried
+ * @param addr pointer to a ip_addr_t where to store the address if it is already
+ *             cached in the dns_table (only valid if ERR_OK is returned!)
+ * @param found a callback function to be called on success, failure or timeout (only if
+ *              ERR_INPROGRESS is returned!)
+ * @param callback_arg argument to pass to the callback function
+ * @param dns_addrtype - LWIP_DNS_ADDRTYPE_IPV4_IPV6: try to resolve IPv4 first, try IPv6 if IPv4 fails only
+ *                     - LWIP_DNS_ADDRTYPE_IPV6_IPV4: try to resolve IPv6 first, try IPv4 if IPv6 fails only
+ *                     - LWIP_DNS_ADDRTYPE_IPV4: try to resolve IPv4 only
+ *                     - LWIP_DNS_ADDRTYPE_IPV6: try to resolve IPv6 only
+ */
+err_t
+dns_gethostbyname_addrtype(const char *hostname, ip_addr_t *addr, dns_found_callback found,
+                           void *callback_arg, u8_t dns_addrtype)
+{
+  size_t hostnamelen;
+#if LWIP_DNS_SUPPORT_MDNS_QUERIES
+  u8_t is_mdns;
+#endif
+  /* not initialized or no valid server yet, or invalid addr pointer
+   * or invalid hostname or invalid hostname length */
+  if ((addr == NULL) ||
+      (!hostname) || (!hostname[0])) {
+    return ERR_ARG;
+  }
+#if ((LWIP_DNS_SECURE & LWIP_DNS_SECURE_RAND_SRC_PORT) == 0)
+  if (dns_pcbs[0] == NULL) {
+    return ERR_ARG;
+  }
+#endif
+  hostnamelen = strlen(hostname);
+  if (hostnamelen >= DNS_MAX_NAME_LENGTH) {
+    LWIP_DEBUGF(DNS_DEBUG, ("dns_gethostbyname: name too long to resolve"));
+    return ERR_ARG;
+  }
+
+
+#if LWIP_HAVE_LOOPIF
+  if (strcmp(hostname, "localhost") == 0) {
+    ip_addr_set_loopback(LWIP_DNS_ADDRTYPE_IS_IPV6(dns_addrtype), addr);
+    return ERR_OK;
+  }
+#endif /* LWIP_HAVE_LOOPIF */
+
+  /* host name already in octet notation? set ip addr and return ERR_OK */
+  if (ipaddr_aton(hostname, addr)) {
+#if LWIP_IPV4 && LWIP_IPV6
+    if ((IP_IS_V6(addr) && (dns_addrtype != LWIP_DNS_ADDRTYPE_IPV4)) ||
+        (IP_IS_V4(addr) && (dns_addrtype != LWIP_DNS_ADDRTYPE_IPV6)))
+#endif /* LWIP_IPV4 && LWIP_IPV6 */
+    {
+      return ERR_OK;
+    }
+  }
+  /* already have this address cached? */
+  if (dns_lookup(hostname, addr LWIP_DNS_ADDRTYPE_ARG(dns_addrtype)) == ERR_OK) {
+    return ERR_OK;
+  }
+#if LWIP_IPV4 && LWIP_IPV6
+  if ((dns_addrtype == LWIP_DNS_ADDRTYPE_IPV4_IPV6) || (dns_addrtype == LWIP_DNS_ADDRTYPE_IPV6_IPV4)) {
+    /* fallback to 2nd IP type and try again to lookup */
+    u8_t fallback;
+    if (dns_addrtype == LWIP_DNS_ADDRTYPE_IPV4_IPV6) {
+      fallback = LWIP_DNS_ADDRTYPE_IPV6;
+    } else {
+      fallback = LWIP_DNS_ADDRTYPE_IPV4;
+    }
+    if (dns_lookup(hostname, addr LWIP_DNS_ADDRTYPE_ARG(fallback)) == ERR_OK) {
+      return ERR_OK;
+    }
+  }
+#else /* LWIP_IPV4 && LWIP_IPV6 */
+  LWIP_UNUSED_ARG(dns_addrtype);
+#endif /* LWIP_IPV4 && LWIP_IPV6 */
+
+#if LWIP_DNS_SUPPORT_MDNS_QUERIES
+  if (strstr(hostname, ".local") == &hostname[hostnamelen] - 6) {
+    is_mdns = 1;
+  } else {
+    is_mdns = 0;
+  }
+
+  if (!is_mdns)
+#endif /* LWIP_DNS_SUPPORT_MDNS_QUERIES */
+  {
+    /* prevent calling found callback if no server is set, return error instead */
+    if (ip_addr_isany_val(dns_servers[0])) {
+      return ERR_VAL;
+    }
+  }
+
+  /* queue query with specified callback */
+  return dns_enqueue(hostname, hostnamelen, found, callback_arg LWIP_DNS_ADDRTYPE_ARG(dns_addrtype)
+                     LWIP_DNS_ISMDNS_ARG(is_mdns));
+}
+
+#endif /* LWIP_DNS */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/core/inet_chksum.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/core/inet_chksum.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/core/inet_chksum.c	(revision 457)
@@ -0,0 +1,608 @@
+/**
+ * @file
+ * Internet checksum functions.\n
+ *
+ * These are some reference implementations of the checksum algorithm, with the
+ * aim of being simple, correct and fully portable. Checksumming is the
+ * first thing you would want to optimize for your platform. If you create
+ * your own version, link it in and in your cc.h put:
+ *
+ * \#define LWIP_CHKSUM your_checksum_routine
+ *
+ * Or you can select from the implementations below by defining
+ * LWIP_CHKSUM_ALGORITHM to 1, 2 or 3.
+ */
+
+/*
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Adam Dunkels <adam@sics.se>
+ *
+ */
+
+#include "lwip/opt.h"
+
+#include "lwip/inet_chksum.h"
+#include "lwip/def.h"
+#include "lwip/ip_addr.h"
+
+#include <string.h>
+
+#ifndef LWIP_CHKSUM
+# define LWIP_CHKSUM lwip_standard_chksum
+# ifndef LWIP_CHKSUM_ALGORITHM
+#  define LWIP_CHKSUM_ALGORITHM 2
+# endif
+u16_t lwip_standard_chksum(const void *dataptr, int len);
+#endif
+/* If none set: */
+#ifndef LWIP_CHKSUM_ALGORITHM
+# define LWIP_CHKSUM_ALGORITHM 0
+#endif
+
+#if (LWIP_CHKSUM_ALGORITHM == 1) /* Version #1 */
+/**
+ * lwip checksum
+ *
+ * @param dataptr points to start of data to be summed at any boundary
+ * @param len length of data to be summed
+ * @return host order (!) lwip checksum (non-inverted Internet sum)
+ *
+ * @note accumulator size limits summable length to 64k
+ * @note host endianess is irrelevant (p3 RFC1071)
+ */
+u16_t
+lwip_standard_chksum(const void *dataptr, int len)
+{
+  u32_t acc;
+  u16_t src;
+  const u8_t *octetptr;
+
+  acc = 0;
+  /* dataptr may be at odd or even addresses */
+  octetptr = (const u8_t *)dataptr;
+  while (len > 1) {
+    /* declare first octet as most significant
+       thus assume network order, ignoring host order */
+    src = (*octetptr) << 8;
+    octetptr++;
+    /* declare second octet as least significant */
+    src |= (*octetptr);
+    octetptr++;
+    acc += src;
+    len -= 2;
+  }
+  if (len > 0) {
+    /* accumulate remaining octet */
+    src = (*octetptr) << 8;
+    acc += src;
+  }
+  /* add deferred carry bits */
+  acc = (acc >> 16) + (acc & 0x0000ffffUL);
+  if ((acc & 0xffff0000UL) != 0) {
+    acc = (acc >> 16) + (acc & 0x0000ffffUL);
+  }
+  /* This maybe a little confusing: reorder sum using lwip_htons()
+     instead of lwip_ntohs() since it has a little less call overhead.
+     The caller must invert bits for Internet sum ! */
+  return lwip_htons((u16_t)acc);
+}
+#endif
+
+#if (LWIP_CHKSUM_ALGORITHM == 2) /* Alternative version #2 */
+/*
+ * Curt McDowell
+ * Broadcom Corp.
+ * csm@broadcom.com
+ *
+ * IP checksum two bytes at a time with support for
+ * unaligned buffer.
+ * Works for len up to and including 0x20000.
+ * by Curt McDowell, Broadcom Corp. 12/08/2005
+ *
+ * @param dataptr points to start of data to be summed at any boundary
+ * @param len length of data to be summed
+ * @return host order (!) lwip checksum (non-inverted Internet sum)
+ */
+u16_t
+lwip_standard_chksum(const void *dataptr, int len)
+{
+  const u8_t *pb = (const u8_t *)dataptr;
+  const u16_t *ps;
+  u16_t t = 0;
+  u32_t sum = 0;
+  int odd = ((mem_ptr_t)pb & 1);
+
+  /* Get aligned to u16_t */
+  if (odd && len > 0) {
+    ((u8_t *)&t)[1] = *pb++;
+    len--;
+  }
+
+  /* Add the bulk of the data */
+  ps = (const u16_t *)(const void *)pb;
+  while (len > 1) {
+    sum += *ps++;
+    len -= 2;
+  }
+
+  /* Consume left-over byte, if any */
+  if (len > 0) {
+    ((u8_t *)&t)[0] = *(const u8_t *)ps;
+  }
+
+  /* Add end bytes */
+  sum += t;
+
+  /* Fold 32-bit sum to 16 bits
+     calling this twice is probably faster than if statements... */
+  sum = FOLD_U32T(sum);
+  sum = FOLD_U32T(sum);
+
+  /* Swap if alignment was odd */
+  if (odd) {
+    sum = SWAP_BYTES_IN_WORD(sum);
+  }
+
+  return (u16_t)sum;
+}
+#endif
+
+#if (LWIP_CHKSUM_ALGORITHM == 3) /* Alternative version #3 */
+/**
+ * An optimized checksum routine. Basically, it uses loop-unrolling on
+ * the checksum loop, treating the head and tail bytes specially, whereas
+ * the inner loop acts on 8 bytes at a time.
+ *
+ * @arg start of buffer to be checksummed. May be an odd byte address.
+ * @len number of bytes in the buffer to be checksummed.
+ * @return host order (!) lwip checksum (non-inverted Internet sum)
+ *
+ * by Curt McDowell, Broadcom Corp. December 8th, 2005
+ */
+u16_t
+lwip_standard_chksum(const void *dataptr, int len)
+{
+  const u8_t *pb = (const u8_t *)dataptr;
+  const u16_t *ps;
+  u16_t t = 0;
+  const u32_t *pl;
+  u32_t sum = 0, tmp;
+  /* starts at odd byte address? */
+  int odd = ((mem_ptr_t)pb & 1);
+
+  if (odd && len > 0) {
+    ((u8_t *)&t)[1] = *pb++;
+    len--;
+  }
+
+  ps = (const u16_t *)(const void *)pb;
+
+  if (((mem_ptr_t)ps & 3) && len > 1) {
+    sum += *ps++;
+    len -= 2;
+  }
+
+  pl = (const u32_t *)(const void *)ps;
+
+  while (len > 7)  {
+    tmp = sum + *pl++;          /* ping */
+    if (tmp < sum) {
+      tmp++;                    /* add back carry */
+    }
+
+    sum = tmp + *pl++;          /* pong */
+    if (sum < tmp) {
+      sum++;                    /* add back carry */
+    }
+
+    len -= 8;
+  }
+
+  /* make room in upper bits */
+  sum = FOLD_U32T(sum);
+
+  ps = (const u16_t *)pl;
+
+  /* 16-bit aligned word remaining? */
+  while (len > 1) {
+    sum += *ps++;
+    len -= 2;
+  }
+
+  /* dangling tail byte remaining? */
+  if (len > 0) {                /* include odd byte */
+    ((u8_t *)&t)[0] = *(const u8_t *)ps;
+  }
+
+  sum += t;                     /* add end bytes */
+
+  /* Fold 32-bit sum to 16 bits
+     calling this twice is probably faster than if statements... */
+  sum = FOLD_U32T(sum);
+  sum = FOLD_U32T(sum);
+
+  if (odd) {
+    sum = SWAP_BYTES_IN_WORD(sum);
+  }
+
+  return (u16_t)sum;
+}
+#endif
+
+/** Parts of the pseudo checksum which are common to IPv4 and IPv6 */
+static u16_t
+inet_cksum_pseudo_base(struct pbuf *p, u8_t proto, u16_t proto_len, u32_t acc)
+{
+  struct pbuf *q;
+  int swapped = 0;
+
+  /* iterate through all pbuf in chain */
+  for (q = p; q != NULL; q = q->next) {
+    LWIP_DEBUGF(INET_DEBUG, ("inet_chksum_pseudo(): checksumming pbuf %p (has next %p) \n",
+                             (void *)q, (void *)q->next));
+    acc += LWIP_CHKSUM(q->payload, q->len);
+    /*LWIP_DEBUGF(INET_DEBUG, ("inet_chksum_pseudo(): unwrapped lwip_chksum()=%"X32_F" \n", acc));*/
+    /* just executing this next line is probably faster that the if statement needed
+       to check whether we really need to execute it, and does no harm */
+    acc = FOLD_U32T(acc);
+    if (q->len % 2 != 0) {
+      swapped = !swapped;
+      acc = SWAP_BYTES_IN_WORD(acc);
+    }
+    /*LWIP_DEBUGF(INET_DEBUG, ("inet_chksum_pseudo(): wrapped lwip_chksum()=%"X32_F" \n", acc));*/
+  }
+
+  if (swapped) {
+    acc = SWAP_BYTES_IN_WORD(acc);
+  }
+
+  acc += (u32_t)lwip_htons((u16_t)proto);
+  acc += (u32_t)lwip_htons(proto_len);
+
+  /* Fold 32-bit sum to 16 bits
+     calling this twice is probably faster than if statements... */
+  acc = FOLD_U32T(acc);
+  acc = FOLD_U32T(acc);
+  LWIP_DEBUGF(INET_DEBUG, ("inet_chksum_pseudo(): pbuf chain lwip_chksum()=%"X32_F"\n", acc));
+  return (u16_t)~(acc & 0xffffUL);
+}
+
+#if LWIP_IPV4
+/* inet_chksum_pseudo:
+ *
+ * Calculates the IPv4 pseudo Internet checksum used by TCP and UDP for a pbuf chain.
+ * IP addresses are expected to be in network byte order.
+ *
+ * @param p chain of pbufs over that a checksum should be calculated (ip data part)
+ * @param src source ip address (used for checksum of pseudo header)
+ * @param dst destination ip address (used for checksum of pseudo header)
+ * @param proto ip protocol (used for checksum of pseudo header)
+ * @param proto_len length of the ip data part (used for checksum of pseudo header)
+ * @return checksum (as u16_t) to be saved directly in the protocol header
+ */
+u16_t
+inet_chksum_pseudo(struct pbuf *p, u8_t proto, u16_t proto_len,
+                   const ip4_addr_t *src, const ip4_addr_t *dest)
+{
+  u32_t acc;
+  u32_t addr;
+
+  addr = ip4_addr_get_u32(src);
+  acc = (addr & 0xffffUL);
+  acc = (u32_t)(acc + ((addr >> 16) & 0xffffUL));
+  addr = ip4_addr_get_u32(dest);
+  acc = (u32_t)(acc + (addr & 0xffffUL));
+  acc = (u32_t)(acc + ((addr >> 16) & 0xffffUL));
+  /* fold down to 16 bits */
+  acc = FOLD_U32T(acc);
+  acc = FOLD_U32T(acc);
+
+  return inet_cksum_pseudo_base(p, proto, proto_len, acc);
+}
+#endif /* LWIP_IPV4 */
+
+#if LWIP_IPV6
+/**
+ * Calculates the checksum with IPv6 pseudo header used by TCP and UDP for a pbuf chain.
+ * IPv6 addresses are expected to be in network byte order.
+ *
+ * @param p chain of pbufs over that a checksum should be calculated (ip data part)
+ * @param proto ipv6 protocol/next header (used for checksum of pseudo header)
+ * @param proto_len length of the ipv6 payload (used for checksum of pseudo header)
+ * @param src source ipv6 address (used for checksum of pseudo header)
+ * @param dest destination ipv6 address (used for checksum of pseudo header)
+ * @return checksum (as u16_t) to be saved directly in the protocol header
+ */
+u16_t
+ip6_chksum_pseudo(struct pbuf *p, u8_t proto, u16_t proto_len,
+                  const ip6_addr_t *src, const ip6_addr_t *dest)
+{
+  u32_t acc = 0;
+  u32_t addr;
+  u8_t addr_part;
+
+  for (addr_part = 0; addr_part < 4; addr_part++) {
+    addr = src->addr[addr_part];
+    acc = (u32_t)(acc + (addr & 0xffffUL));
+    acc = (u32_t)(acc + ((addr >> 16) & 0xffffUL));
+    addr = dest->addr[addr_part];
+    acc = (u32_t)(acc + (addr & 0xffffUL));
+    acc = (u32_t)(acc + ((addr >> 16) & 0xffffUL));
+  }
+  /* fold down to 16 bits */
+  acc = FOLD_U32T(acc);
+  acc = FOLD_U32T(acc);
+
+  return inet_cksum_pseudo_base(p, proto, proto_len, acc);
+}
+#endif /* LWIP_IPV6 */
+
+/* ip_chksum_pseudo:
+ *
+ * Calculates the IPv4 or IPv6 pseudo Internet checksum used by TCP and UDP for a pbuf chain.
+ * IP addresses are expected to be in network byte order.
+ *
+ * @param p chain of pbufs over that a checksum should be calculated (ip data part)
+ * @param src source ip address (used for checksum of pseudo header)
+ * @param dst destination ip address (used for checksum of pseudo header)
+ * @param proto ip protocol (used for checksum of pseudo header)
+ * @param proto_len length of the ip data part (used for checksum of pseudo header)
+ * @return checksum (as u16_t) to be saved directly in the protocol header
+ */
+u16_t
+ip_chksum_pseudo(struct pbuf *p, u8_t proto, u16_t proto_len,
+                 const ip_addr_t *src, const ip_addr_t *dest)
+{
+#if LWIP_IPV6
+  if (IP_IS_V6(dest)) {
+    return ip6_chksum_pseudo(p, proto, proto_len, ip_2_ip6(src), ip_2_ip6(dest));
+  }
+#endif /* LWIP_IPV6 */
+#if LWIP_IPV4 && LWIP_IPV6
+  else
+#endif /* LWIP_IPV4 && LWIP_IPV6 */
+#if LWIP_IPV4
+  {
+    return inet_chksum_pseudo(p, proto, proto_len, ip_2_ip4(src), ip_2_ip4(dest));
+  }
+#endif /* LWIP_IPV4 */
+}
+
+/** Parts of the pseudo checksum which are common to IPv4 and IPv6 */
+static u16_t
+inet_cksum_pseudo_partial_base(struct pbuf *p, u8_t proto, u16_t proto_len,
+                               u16_t chksum_len, u32_t acc)
+{
+  struct pbuf *q;
+  int swapped = 0;
+  u16_t chklen;
+
+  /* iterate through all pbuf in chain */
+  for (q = p; (q != NULL) && (chksum_len > 0); q = q->next) {
+    LWIP_DEBUGF(INET_DEBUG, ("inet_chksum_pseudo(): checksumming pbuf %p (has next %p) \n",
+                             (void *)q, (void *)q->next));
+    chklen = q->len;
+    if (chklen > chksum_len) {
+      chklen = chksum_len;
+    }
+    acc += LWIP_CHKSUM(q->payload, chklen);
+    chksum_len = (u16_t)(chksum_len - chklen);
+    LWIP_ASSERT("delete me", chksum_len < 0x7fff);
+    /*LWIP_DEBUGF(INET_DEBUG, ("inet_chksum_pseudo(): unwrapped lwip_chksum()=%"X32_F" \n", acc));*/
+    /* fold the upper bit down */
+    acc = FOLD_U32T(acc);
+    if (q->len % 2 != 0) {
+      swapped = !swapped;
+      acc = SWAP_BYTES_IN_WORD(acc);
+    }
+    /*LWIP_DEBUGF(INET_DEBUG, ("inet_chksum_pseudo(): wrapped lwip_chksum()=%"X32_F" \n", acc));*/
+  }
+
+  if (swapped) {
+    acc = SWAP_BYTES_IN_WORD(acc);
+  }
+
+  acc += (u32_t)lwip_htons((u16_t)proto);
+  acc += (u32_t)lwip_htons(proto_len);
+
+  /* Fold 32-bit sum to 16 bits
+     calling this twice is probably faster than if statements... */
+  acc = FOLD_U32T(acc);
+  acc = FOLD_U32T(acc);
+  LWIP_DEBUGF(INET_DEBUG, ("inet_chksum_pseudo(): pbuf chain lwip_chksum()=%"X32_F"\n", acc));
+  return (u16_t)~(acc & 0xffffUL);
+}
+
+#if LWIP_IPV4
+/* inet_chksum_pseudo_partial:
+ *
+ * Calculates the IPv4 pseudo Internet checksum used by TCP and UDP for a pbuf chain.
+ * IP addresses are expected to be in network byte order.
+ *
+ * @param p chain of pbufs over that a checksum should be calculated (ip data part)
+ * @param src source ip address (used for checksum of pseudo header)
+ * @param dst destination ip address (used for checksum of pseudo header)
+ * @param proto ip protocol (used for checksum of pseudo header)
+ * @param proto_len length of the ip data part (used for checksum of pseudo header)
+ * @return checksum (as u16_t) to be saved directly in the protocol header
+ */
+u16_t
+inet_chksum_pseudo_partial(struct pbuf *p, u8_t proto, u16_t proto_len,
+                           u16_t chksum_len, const ip4_addr_t *src, const ip4_addr_t *dest)
+{
+  u32_t acc;
+  u32_t addr;
+
+  addr = ip4_addr_get_u32(src);
+  acc = (addr & 0xffffUL);
+  acc = (u32_t)(acc + ((addr >> 16) & 0xffffUL));
+  addr = ip4_addr_get_u32(dest);
+  acc = (u32_t)(acc + (addr & 0xffffUL));
+  acc = (u32_t)(acc + ((addr >> 16) & 0xffffUL));
+  /* fold down to 16 bits */
+  acc = FOLD_U32T(acc);
+  acc = FOLD_U32T(acc);
+
+  return inet_cksum_pseudo_partial_base(p, proto, proto_len, chksum_len, acc);
+}
+#endif /* LWIP_IPV4 */
+
+#if LWIP_IPV6
+/**
+ * Calculates the checksum with IPv6 pseudo header used by TCP and UDP for a pbuf chain.
+ * IPv6 addresses are expected to be in network byte order. Will only compute for a
+ * portion of the payload.
+ *
+ * @param p chain of pbufs over that a checksum should be calculated (ip data part)
+ * @param proto ipv6 protocol/next header (used for checksum of pseudo header)
+ * @param proto_len length of the ipv6 payload (used for checksum of pseudo header)
+ * @param chksum_len number of payload bytes used to compute chksum
+ * @param src source ipv6 address (used for checksum of pseudo header)
+ * @param dest destination ipv6 address (used for checksum of pseudo header)
+ * @return checksum (as u16_t) to be saved directly in the protocol header
+ */
+u16_t
+ip6_chksum_pseudo_partial(struct pbuf *p, u8_t proto, u16_t proto_len,
+                          u16_t chksum_len, const ip6_addr_t *src, const ip6_addr_t *dest)
+{
+  u32_t acc = 0;
+  u32_t addr;
+  u8_t addr_part;
+
+  for (addr_part = 0; addr_part < 4; addr_part++) {
+    addr = src->addr[addr_part];
+    acc = (u32_t)(acc + (addr & 0xffffUL));
+    acc = (u32_t)(acc + ((addr >> 16) & 0xffffUL));
+    addr = dest->addr[addr_part];
+    acc = (u32_t)(acc + (addr & 0xffffUL));
+    acc = (u32_t)(acc + ((addr >> 16) & 0xffffUL));
+  }
+  /* fold down to 16 bits */
+  acc = FOLD_U32T(acc);
+  acc = FOLD_U32T(acc);
+
+  return inet_cksum_pseudo_partial_base(p, proto, proto_len, chksum_len, acc);
+}
+#endif /* LWIP_IPV6 */
+
+/* ip_chksum_pseudo_partial:
+ *
+ * Calculates the IPv4 or IPv6 pseudo Internet checksum used by TCP and UDP for a pbuf chain.
+ *
+ * @param p chain of pbufs over that a checksum should be calculated (ip data part)
+ * @param src source ip address (used for checksum of pseudo header)
+ * @param dst destination ip address (used for checksum of pseudo header)
+ * @param proto ip protocol (used for checksum of pseudo header)
+ * @param proto_len length of the ip data part (used for checksum of pseudo header)
+ * @return checksum (as u16_t) to be saved directly in the protocol header
+ */
+u16_t
+ip_chksum_pseudo_partial(struct pbuf *p, u8_t proto, u16_t proto_len,
+                         u16_t chksum_len, const ip_addr_t *src, const ip_addr_t *dest)
+{
+#if LWIP_IPV6
+  if (IP_IS_V6(dest)) {
+    return ip6_chksum_pseudo_partial(p, proto, proto_len, chksum_len, ip_2_ip6(src), ip_2_ip6(dest));
+  }
+#endif /* LWIP_IPV6 */
+#if LWIP_IPV4 && LWIP_IPV6
+  else
+#endif /* LWIP_IPV4 && LWIP_IPV6 */
+#if LWIP_IPV4
+  {
+    return inet_chksum_pseudo_partial(p, proto, proto_len, chksum_len, ip_2_ip4(src), ip_2_ip4(dest));
+  }
+#endif /* LWIP_IPV4 */
+}
+
+/* inet_chksum:
+ *
+ * Calculates the Internet checksum over a portion of memory. Used primarily for IP
+ * and ICMP.
+ *
+ * @param dataptr start of the buffer to calculate the checksum (no alignment needed)
+ * @param len length of the buffer to calculate the checksum
+ * @return checksum (as u16_t) to be saved directly in the protocol header
+ */
+
+u16_t
+inet_chksum(const void *dataptr, u16_t len)
+{
+  return (u16_t)~(unsigned int)LWIP_CHKSUM(dataptr, len);
+}
+
+/**
+ * Calculate a checksum over a chain of pbufs (without pseudo-header, much like
+ * inet_chksum only pbufs are used).
+ *
+ * @param p pbuf chain over that the checksum should be calculated
+ * @return checksum (as u16_t) to be saved directly in the protocol header
+ */
+u16_t
+inet_chksum_pbuf(struct pbuf *p)
+{
+  u32_t acc;
+  struct pbuf *q;
+  int swapped = 0;
+
+  acc = 0;
+  for (q = p; q != NULL; q = q->next) {
+    acc += LWIP_CHKSUM(q->payload, q->len);
+    acc = FOLD_U32T(acc);
+    if (q->len % 2 != 0) {
+      swapped = !swapped;
+      acc = SWAP_BYTES_IN_WORD(acc);
+    }
+  }
+
+  if (swapped) {
+    acc = SWAP_BYTES_IN_WORD(acc);
+  }
+  return (u16_t)~(acc & 0xffffUL);
+}
+
+/* These are some implementations for LWIP_CHKSUM_COPY, which copies data
+ * like MEMCPY but generates a checksum at the same time. Since this is a
+ * performance-sensitive function, you might want to create your own version
+ * in assembly targeted at your hardware by defining it in lwipopts.h:
+ *   #define LWIP_CHKSUM_COPY(dst, src, len) your_chksum_copy(dst, src, len)
+ */
+
+#if (LWIP_CHKSUM_COPY_ALGORITHM == 1) /* Version #1 */
+/** Safe but slow: first call MEMCPY, then call LWIP_CHKSUM.
+ * For architectures with big caches, data might still be in cache when
+ * generating the checksum after copying.
+ */
+u16_t
+lwip_chksum_copy(void *dst, const void *src, u16_t len)
+{
+  MEMCPY(dst, src, len);
+  return LWIP_CHKSUM(dst, len);
+}
+#endif /* (LWIP_CHKSUM_COPY_ALGORITHM == 1) */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/core/init.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/core/init.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/core/init.c	(revision 457)
@@ -0,0 +1,380 @@
+/**
+ * @file
+ * Modules initialization
+ *
+ */
+
+/*
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Adam Dunkels <adam@sics.se>
+ */
+
+#include "lwip/opt.h"
+
+#include "lwip/init.h"
+#include "lwip/stats.h"
+#include "lwip/sys.h"
+#include "lwip/mem.h"
+#include "lwip/memp.h"
+#include "lwip/pbuf.h"
+#include "lwip/netif.h"
+#include "lwip/sockets.h"
+#include "lwip/ip.h"
+#include "lwip/raw.h"
+#include "lwip/udp.h"
+#include "lwip/priv/tcp_priv.h"
+#include "lwip/igmp.h"
+#include "lwip/dns.h"
+#include "lwip/timeouts.h"
+#include "lwip/etharp.h"
+#include "lwip/ip6.h"
+#include "lwip/nd6.h"
+#include "lwip/mld6.h"
+#include "lwip/api.h"
+
+#include "netif/ppp/ppp_opts.h"
+#include "netif/ppp/ppp_impl.h"
+
+#ifndef LWIP_SKIP_PACKING_CHECK
+
+#ifdef PACK_STRUCT_USE_INCLUDES
+#  include "arch/bpstruct.h"
+#endif
+PACK_STRUCT_BEGIN
+struct packed_struct_test {
+  PACK_STRUCT_FLD_8(u8_t  dummy1);
+  PACK_STRUCT_FIELD(u32_t dummy2);
+} PACK_STRUCT_STRUCT;
+PACK_STRUCT_END
+#ifdef PACK_STRUCT_USE_INCLUDES
+#  include "arch/epstruct.h"
+#endif
+#define PACKED_STRUCT_TEST_EXPECTED_SIZE 5
+
+#endif
+
+/* Compile-time sanity checks for configuration errors.
+ * These can be done independently of LWIP_DEBUG, without penalty.
+ */
+#ifndef BYTE_ORDER
+#error "BYTE_ORDER is not defined, you have to define it in your cc.h"
+#endif
+#if (!IP_SOF_BROADCAST && IP_SOF_BROADCAST_RECV)
+#error "If you want to use broadcast filter per pcb on recv operations, you have to define IP_SOF_BROADCAST=1 in your lwipopts.h"
+#endif
+#if (!LWIP_UDP && LWIP_UDPLITE)
+#error "If you want to use UDP Lite, you have to define LWIP_UDP=1 in your lwipopts.h"
+#endif
+#if (!LWIP_UDP && LWIP_DHCP)
+#error "If you want to use DHCP, you have to define LWIP_UDP=1 in your lwipopts.h"
+#endif
+#if (!LWIP_UDP && !LWIP_RAW && LWIP_MULTICAST_TX_OPTIONS)
+#error "If you want to use LWIP_MULTICAST_TX_OPTIONS, you have to define LWIP_UDP=1 and/or LWIP_RAW=1 in your lwipopts.h"
+#endif
+#if (!LWIP_UDP && LWIP_DNS)
+#error "If you want to use DNS, you have to define LWIP_UDP=1 in your lwipopts.h"
+#endif
+#if !MEMP_MEM_MALLOC /* MEMP_NUM_* checks are disabled when not using the pool allocator */
+#if (LWIP_ARP && ARP_QUEUEING && (MEMP_NUM_ARP_QUEUE<=0))
+#error "If you want to use ARP Queueing, you have to define MEMP_NUM_ARP_QUEUE>=1 in your lwipopts.h"
+#endif
+#if (LWIP_RAW && (MEMP_NUM_RAW_PCB<=0))
+#error "If you want to use RAW, you have to define MEMP_NUM_RAW_PCB>=1 in your lwipopts.h"
+#endif
+#if (LWIP_UDP && (MEMP_NUM_UDP_PCB<=0))
+#error "If you want to use UDP, you have to define MEMP_NUM_UDP_PCB>=1 in your lwipopts.h"
+#endif
+#if (LWIP_TCP && (MEMP_NUM_TCP_PCB<=0))
+#error "If you want to use TCP, you have to define MEMP_NUM_TCP_PCB>=1 in your lwipopts.h"
+#endif
+#if (LWIP_IGMP && (MEMP_NUM_IGMP_GROUP<=1))
+#error "If you want to use IGMP, you have to define MEMP_NUM_IGMP_GROUP>1 in your lwipopts.h"
+#endif
+#if (LWIP_IGMP && !LWIP_MULTICAST_TX_OPTIONS)
+#error "If you want to use IGMP, you have to define LWIP_MULTICAST_TX_OPTIONS==1 in your lwipopts.h"
+#endif
+#if (LWIP_IGMP && !LWIP_IPV4)
+#error "IGMP needs LWIP_IPV4 enabled in your lwipopts.h"
+#endif
+#if ((LWIP_NETCONN || LWIP_SOCKET) && (MEMP_NUM_TCPIP_MSG_API<=0))
+#error "If you want to use Sequential API, you have to define MEMP_NUM_TCPIP_MSG_API>=1 in your lwipopts.h"
+#endif
+/* There must be sufficient timeouts, taking into account requirements of the subsystems. */
+#if LWIP_TIMERS && (MEMP_NUM_SYS_TIMEOUT < LWIP_NUM_SYS_TIMEOUT_INTERNAL)
+#error "MEMP_NUM_SYS_TIMEOUT is too low to accomodate all required timeouts"
+#endif
+#if (IP_REASSEMBLY && (MEMP_NUM_REASSDATA > IP_REASS_MAX_PBUFS))
+#error "MEMP_NUM_REASSDATA > IP_REASS_MAX_PBUFS doesn't make sense since each struct ip_reassdata must hold 2 pbufs at least!"
+#endif
+#endif /* !MEMP_MEM_MALLOC */
+#if LWIP_WND_SCALE
+#if (LWIP_TCP && (TCP_WND > 0xffffffff))
+#error "If you want to use TCP, TCP_WND must fit in an u32_t, so, you have to reduce it in your lwipopts.h"
+#endif
+#if (LWIP_TCP && (TCP_RCV_SCALE > 14))
+#error "The maximum valid window scale value is 14!"
+#endif
+#if (LWIP_TCP && (TCP_WND > (0xFFFFU << TCP_RCV_SCALE)))
+#error "TCP_WND is bigger than the configured LWIP_WND_SCALE allows!"
+#endif
+#if (LWIP_TCP && ((TCP_WND >> TCP_RCV_SCALE) == 0))
+#error "TCP_WND is too small for the configured LWIP_WND_SCALE (results in zero window)!"
+#endif
+#else /* LWIP_WND_SCALE */
+#if (LWIP_TCP && (TCP_WND > 0xffff))
+#error "If you want to use TCP, TCP_WND must fit in an u16_t, so, you have to reduce it in your lwipopts.h (or enable window scaling)"
+#endif
+#endif /* LWIP_WND_SCALE */
+#if (LWIP_TCP && (TCP_SND_QUEUELEN > 0xffff))
+#error "If you want to use TCP, TCP_SND_QUEUELEN must fit in an u16_t, so, you have to reduce it in your lwipopts.h"
+#endif
+#if (LWIP_TCP && (TCP_SND_QUEUELEN < 2))
+#error "TCP_SND_QUEUELEN must be at least 2 for no-copy TCP writes to work"
+#endif
+#if (LWIP_TCP && ((TCP_MAXRTX > 12) || (TCP_SYNMAXRTX > 12)))
+#error "If you want to use TCP, TCP_MAXRTX and TCP_SYNMAXRTX must less or equal to 12 (due to tcp_backoff table), so, you have to reduce them in your lwipopts.h"
+#endif
+#if (LWIP_TCP && TCP_LISTEN_BACKLOG && ((TCP_DEFAULT_LISTEN_BACKLOG < 0) || (TCP_DEFAULT_LISTEN_BACKLOG > 0xff)))
+#error "If you want to use TCP backlog, TCP_DEFAULT_LISTEN_BACKLOG must fit into an u8_t"
+#endif
+#if (LWIP_TCP && LWIP_TCP_SACK_OUT && !TCP_QUEUE_OOSEQ)
+#error "To use LWIP_TCP_SACK_OUT, TCP_QUEUE_OOSEQ needs to be enabled"
+#endif
+#if (LWIP_TCP && LWIP_TCP_SACK_OUT && (LWIP_TCP_MAX_SACK_NUM < 1))
+#error "LWIP_TCP_MAX_SACK_NUM must be greater than 0"
+#endif
+#if (LWIP_NETIF_API && (NO_SYS==1))
+#error "If you want to use NETIF API, you have to define NO_SYS=0 in your lwipopts.h"
+#endif
+#if ((LWIP_SOCKET || LWIP_NETCONN) && (NO_SYS==1))
+#error "If you want to use Sequential API, you have to define NO_SYS=0 in your lwipopts.h"
+#endif
+#if (LWIP_PPP_API && (NO_SYS==1))
+#error "If you want to use PPP API, you have to define NO_SYS=0 in your lwipopts.h"
+#endif
+#if (LWIP_PPP_API && (PPP_SUPPORT==0))
+#error "If you want to use PPP API, you have to enable PPP_SUPPORT in your lwipopts.h"
+#endif
+#if (((!LWIP_DHCP) || (!LWIP_AUTOIP)) && LWIP_DHCP_AUTOIP_COOP)
+#error "If you want to use DHCP/AUTOIP cooperation mode, you have to define LWIP_DHCP=1 and LWIP_AUTOIP=1 in your lwipopts.h"
+#endif
+#if (((!LWIP_DHCP) || (!LWIP_ARP)) && DHCP_DOES_ARP_CHECK)
+#error "If you want to use DHCP ARP checking, you have to define LWIP_DHCP=1 and LWIP_ARP=1 in your lwipopts.h"
+#endif
+#if (!LWIP_ARP && LWIP_AUTOIP)
+#error "If you want to use AUTOIP, you have to define LWIP_ARP=1 in your lwipopts.h"
+#endif
+#if (LWIP_TCP && ((LWIP_EVENT_API && LWIP_CALLBACK_API) || (!LWIP_EVENT_API && !LWIP_CALLBACK_API)))
+#error "One and exactly one of LWIP_EVENT_API and LWIP_CALLBACK_API has to be enabled in your lwipopts.h"
+#endif
+#if (LWIP_ALTCP && LWIP_EVENT_API)
+#error "The application layered tcp API does not work with LWIP_EVENT_API"
+#endif
+#if (MEM_LIBC_MALLOC && MEM_USE_POOLS)
+#error "MEM_LIBC_MALLOC and MEM_USE_POOLS may not both be simultaneously enabled in your lwipopts.h"
+#endif
+#if (MEM_USE_POOLS && !MEMP_USE_CUSTOM_POOLS)
+#error "MEM_USE_POOLS requires custom pools (MEMP_USE_CUSTOM_POOLS) to be enabled in your lwipopts.h"
+#endif
+#if (PBUF_POOL_BUFSIZE <= MEM_ALIGNMENT)
+#error "PBUF_POOL_BUFSIZE must be greater than MEM_ALIGNMENT or the offset may take the full first pbuf"
+#endif
+#if (DNS_LOCAL_HOSTLIST && !DNS_LOCAL_HOSTLIST_IS_DYNAMIC && !(defined(DNS_LOCAL_HOSTLIST_INIT)))
+#error "you have to define define DNS_LOCAL_HOSTLIST_INIT {{'host1', 0x123}, {'host2', 0x234}} to initialize DNS_LOCAL_HOSTLIST"
+#endif
+#if PPP_SUPPORT && !PPPOS_SUPPORT && !PPPOE_SUPPORT && !PPPOL2TP_SUPPORT
+#error "PPP_SUPPORT needs at least one of PPPOS_SUPPORT, PPPOE_SUPPORT or PPPOL2TP_SUPPORT turned on"
+#endif
+#if PPP_SUPPORT && !PPP_IPV4_SUPPORT && !PPP_IPV6_SUPPORT
+#error "PPP_SUPPORT needs PPP_IPV4_SUPPORT and/or PPP_IPV6_SUPPORT turned on"
+#endif
+#if PPP_SUPPORT && PPP_IPV4_SUPPORT && !LWIP_IPV4
+#error "PPP_IPV4_SUPPORT needs LWIP_IPV4 turned on"
+#endif
+#if PPP_SUPPORT && PPP_IPV6_SUPPORT && !LWIP_IPV6
+#error "PPP_IPV6_SUPPORT needs LWIP_IPV6 turned on"
+#endif
+#if !LWIP_ETHERNET && (LWIP_ARP || PPPOE_SUPPORT)
+#error "LWIP_ETHERNET needs to be turned on for LWIP_ARP or PPPOE_SUPPORT"
+#endif
+#if LWIP_TCPIP_CORE_LOCKING_INPUT && !LWIP_TCPIP_CORE_LOCKING
+#error "When using LWIP_TCPIP_CORE_LOCKING_INPUT, LWIP_TCPIP_CORE_LOCKING must be enabled, too"
+#endif
+#if LWIP_TCP && LWIP_NETIF_TX_SINGLE_PBUF && !TCP_OVERSIZE
+#error "LWIP_NETIF_TX_SINGLE_PBUF needs TCP_OVERSIZE enabled to create single-pbuf TCP packets"
+#endif
+#if LWIP_NETCONN && LWIP_TCP
+#if NETCONN_COPY != TCP_WRITE_FLAG_COPY
+#error "NETCONN_COPY != TCP_WRITE_FLAG_COPY"
+#endif
+#if NETCONN_MORE != TCP_WRITE_FLAG_MORE
+#error "NETCONN_MORE != TCP_WRITE_FLAG_MORE"
+#endif
+#endif /* LWIP_NETCONN && LWIP_TCP */
+#if LWIP_SOCKET
+#endif /* LWIP_SOCKET */
+
+
+/* Compile-time checks for deprecated options.
+ */
+#ifdef MEMP_NUM_TCPIP_MSG
+#error "MEMP_NUM_TCPIP_MSG option is deprecated. Remove it from your lwipopts.h."
+#endif
+#ifdef TCP_REXMIT_DEBUG
+#error "TCP_REXMIT_DEBUG option is deprecated. Remove it from your lwipopts.h."
+#endif
+#ifdef RAW_STATS
+#error "RAW_STATS option is deprecated. Remove it from your lwipopts.h."
+#endif
+#ifdef ETHARP_QUEUE_FIRST
+#error "ETHARP_QUEUE_FIRST option is deprecated. Remove it from your lwipopts.h."
+#endif
+#ifdef ETHARP_ALWAYS_INSERT
+#error "ETHARP_ALWAYS_INSERT option is deprecated. Remove it from your lwipopts.h."
+#endif
+#if !NO_SYS && LWIP_TCPIP_CORE_LOCKING && LWIP_COMPAT_MUTEX && !defined(LWIP_COMPAT_MUTEX_ALLOWED)
+#error "LWIP_COMPAT_MUTEX cannot prevent priority inversion. It is recommended to implement priority-aware mutexes. (Define LWIP_COMPAT_MUTEX_ALLOWED to disable this error.)"
+#endif
+
+#ifndef LWIP_DISABLE_TCP_SANITY_CHECKS
+#define LWIP_DISABLE_TCP_SANITY_CHECKS  0
+#endif
+#ifndef LWIP_DISABLE_MEMP_SANITY_CHECKS
+#define LWIP_DISABLE_MEMP_SANITY_CHECKS 0
+#endif
+
+/* MEMP sanity checks */
+#if MEMP_MEM_MALLOC
+#if !LWIP_DISABLE_MEMP_SANITY_CHECKS
+#if LWIP_NETCONN || LWIP_SOCKET
+#if !MEMP_NUM_NETCONN && LWIP_SOCKET
+#error "lwip_sanity_check: WARNING: MEMP_NUM_NETCONN cannot be 0 when using sockets!"
+#endif
+#else /* MEMP_MEM_MALLOC */
+#if MEMP_NUM_NETCONN > (MEMP_NUM_TCP_PCB+MEMP_NUM_TCP_PCB_LISTEN+MEMP_NUM_UDP_PCB+MEMP_NUM_RAW_PCB)
+#error "lwip_sanity_check: WARNING: MEMP_NUM_NETCONN should be less than the sum of MEMP_NUM_{TCP,RAW,UDP}_PCB+MEMP_NUM_TCP_PCB_LISTEN. If you know what you are doing, define LWIP_DISABLE_MEMP_SANITY_CHECKS to 1 to disable this error."
+#endif
+#endif /* LWIP_NETCONN || LWIP_SOCKET */
+#endif /* !LWIP_DISABLE_MEMP_SANITY_CHECKS */
+#if MEM_USE_POOLS
+#error "MEMP_MEM_MALLOC and MEM_USE_POOLS cannot be enabled at the same time"
+#endif
+#ifdef LWIP_HOOK_MEMP_AVAILABLE
+#error "LWIP_HOOK_MEMP_AVAILABLE doesn't make sense with MEMP_MEM_MALLOC"
+#endif
+#endif /* MEMP_MEM_MALLOC */
+
+/* TCP sanity checks */
+#if !LWIP_DISABLE_TCP_SANITY_CHECKS
+#if LWIP_TCP
+#if !MEMP_MEM_MALLOC && (MEMP_NUM_TCP_SEG < TCP_SND_QUEUELEN)
+#error "lwip_sanity_check: WARNING: MEMP_NUM_TCP_SEG should be at least as big as TCP_SND_QUEUELEN. If you know what you are doing, define LWIP_DISABLE_TCP_SANITY_CHECKS to 1 to disable this error."
+#endif
+#if TCP_SND_BUF < (2 * TCP_MSS)
+#error "lwip_sanity_check: WARNING: TCP_SND_BUF must be at least as much as (2 * TCP_MSS) for things to work smoothly. If you know what you are doing, define LWIP_DISABLE_TCP_SANITY_CHECKS to 1 to disable this error."
+#endif
+#if TCP_SND_QUEUELEN < (2 * (TCP_SND_BUF / TCP_MSS))
+#error "lwip_sanity_check: WARNING: TCP_SND_QUEUELEN must be at least as much as (2 * TCP_SND_BUF/TCP_MSS) for things to work. If you know what you are doing, define LWIP_DISABLE_TCP_SANITY_CHECKS to 1 to disable this error."
+#endif
+#if TCP_SNDLOWAT >= TCP_SND_BUF
+#error "lwip_sanity_check: WARNING: TCP_SNDLOWAT must be less than TCP_SND_BUF. If you know what you are doing, define LWIP_DISABLE_TCP_SANITY_CHECKS to 1 to disable this error."
+#endif
+#if TCP_SNDLOWAT >= (0xFFFF - (4 * TCP_MSS))
+#error "lwip_sanity_check: WARNING: TCP_SNDLOWAT must at least be 4*MSS below u16_t overflow!"
+#endif
+#if TCP_SNDQUEUELOWAT >= TCP_SND_QUEUELEN
+#error "lwip_sanity_check: WARNING: TCP_SNDQUEUELOWAT must be less than TCP_SND_QUEUELEN. If you know what you are doing, define LWIP_DISABLE_TCP_SANITY_CHECKS to 1 to disable this error."
+#endif
+#if !MEMP_MEM_MALLOC && PBUF_POOL_SIZE && (PBUF_POOL_BUFSIZE <= (PBUF_LINK_ENCAPSULATION_HLEN + PBUF_LINK_HLEN + PBUF_IP_HLEN + PBUF_TRANSPORT_HLEN))
+#error "lwip_sanity_check: WARNING: PBUF_POOL_BUFSIZE does not provide enough space for protocol headers. If you know what you are doing, define LWIP_DISABLE_TCP_SANITY_CHECKS to 1 to disable this error."
+#endif
+#if !MEMP_MEM_MALLOC && PBUF_POOL_SIZE && (TCP_WND > (PBUF_POOL_SIZE * (PBUF_POOL_BUFSIZE - (PBUF_LINK_ENCAPSULATION_HLEN + PBUF_LINK_HLEN + PBUF_IP_HLEN + PBUF_TRANSPORT_HLEN))))
+#error "lwip_sanity_check: WARNING: TCP_WND is larger than space provided by PBUF_POOL_SIZE * (PBUF_POOL_BUFSIZE - protocol headers). If you know what you are doing, define LWIP_DISABLE_TCP_SANITY_CHECKS to 1 to disable this error."
+#endif
+#if TCP_WND < TCP_MSS
+#error "lwip_sanity_check: WARNING: TCP_WND is smaller than MSS. If you know what you are doing, define LWIP_DISABLE_TCP_SANITY_CHECKS to 1 to disable this error."
+#endif
+#endif /* LWIP_TCP */
+#endif /* !LWIP_DISABLE_TCP_SANITY_CHECKS */
+
+/**
+ * @ingroup lwip_nosys
+ * Initialize all modules.
+ * Use this in NO_SYS mode. Use tcpip_init() otherwise.
+ */
+void
+lwip_init(void)
+{
+#ifndef LWIP_SKIP_CONST_CHECK
+  int a = 0;
+  LWIP_UNUSED_ARG(a);
+  LWIP_ASSERT("LWIP_CONST_CAST not implemented correctly. Check your lwIP port.", LWIP_CONST_CAST(void *, &a) == &a);
+#endif
+#ifndef LWIP_SKIP_PACKING_CHECK
+  LWIP_ASSERT("Struct packing not implemented correctly. Check your lwIP port.", sizeof(struct packed_struct_test) == PACKED_STRUCT_TEST_EXPECTED_SIZE);
+#endif
+
+  /* Modules initialization */
+  stats_init();
+#if !NO_SYS
+  sys_init();
+#endif /* !NO_SYS */
+  mem_init();
+  memp_init();
+  pbuf_init();
+  netif_init();
+#if LWIP_IPV4
+  ip_init();
+#if LWIP_ARP
+  etharp_init();
+#endif /* LWIP_ARP */
+#endif /* LWIP_IPV4 */
+#if LWIP_RAW
+  raw_init();
+#endif /* LWIP_RAW */
+#if LWIP_UDP
+  udp_init();
+#endif /* LWIP_UDP */
+#if LWIP_TCP
+  tcp_init();
+#endif /* LWIP_TCP */
+#if LWIP_IGMP
+  igmp_init();
+#endif /* LWIP_IGMP */
+#if LWIP_DNS
+  dns_init();
+#endif /* LWIP_DNS */
+#if PPP_SUPPORT
+  ppp_init();
+#endif
+
+#if LWIP_TIMERS
+  sys_timeouts_init();
+#endif /* LWIP_TIMERS */
+}
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/core/ip.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/core/ip.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/core/ip.c	(revision 457)
@@ -0,0 +1,167 @@
+/**
+ * @file
+ * Common IPv4 and IPv6 code
+ *
+ * @defgroup ip IP
+ * @ingroup callbackstyle_api
+ *
+ * @defgroup ip4 IPv4
+ * @ingroup ip
+ *
+ * @defgroup ip6 IPv6
+ * @ingroup ip
+ *
+ * @defgroup ipaddr IP address handling
+ * @ingroup infrastructure
+ *
+ * @defgroup ip4addr IPv4 only
+ * @ingroup ipaddr
+ *
+ * @defgroup ip6addr IPv6 only
+ * @ingroup ipaddr
+ */
+
+/*
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Adam Dunkels <adam@sics.se>
+ *
+ */
+
+#include "lwip/opt.h"
+
+#if LWIP_IPV4 || LWIP_IPV6
+
+#include "lwip/ip_addr.h"
+#include "lwip/ip.h"
+
+/** Global data for both IPv4 and IPv6 */
+struct ip_globals ip_data;
+
+#if LWIP_IPV4 && LWIP_IPV6
+
+const ip_addr_t ip_addr_any_type = IPADDR_ANY_TYPE_INIT;
+
+/**
+ * @ingroup ipaddr
+ * Convert numeric IP address (both versions) into ASCII representation.
+ * returns ptr to static buffer; not reentrant!
+ *
+ * @param addr ip address in network order to convert
+ * @return pointer to a global static (!) buffer that holds the ASCII
+ *         representation of addr
+ */
+char *ipaddr_ntoa(const ip_addr_t *addr)
+{
+  if (addr == NULL) {
+    return NULL;
+  }
+  if (IP_IS_V6(addr)) {
+    return ip6addr_ntoa(ip_2_ip6(addr));
+  } else {
+    return ip4addr_ntoa(ip_2_ip4(addr));
+  }
+}
+
+/**
+ * @ingroup ipaddr
+ * Same as ipaddr_ntoa, but reentrant since a user-supplied buffer is used.
+ *
+ * @param addr ip address in network order to convert
+ * @param buf target buffer where the string is stored
+ * @param buflen length of buf
+ * @return either pointer to buf which now holds the ASCII
+ *         representation of addr or NULL if buf was too small
+ */
+char *ipaddr_ntoa_r(const ip_addr_t *addr, char *buf, int buflen)
+{
+  if (addr == NULL) {
+    return NULL;
+  }
+  if (IP_IS_V6(addr)) {
+    return ip6addr_ntoa_r(ip_2_ip6(addr), buf, buflen);
+  } else {
+    return ip4addr_ntoa_r(ip_2_ip4(addr), buf, buflen);
+  }
+}
+
+/**
+ * @ingroup ipaddr
+ * Convert IP address string (both versions) to numeric.
+ * The version is auto-detected from the string.
+ *
+ * @param cp IP address string to convert
+ * @param addr conversion result is stored here
+ * @return 1 on success, 0 on error
+ */
+int
+ipaddr_aton(const char *cp, ip_addr_t *addr)
+{
+  if (cp != NULL) {
+    const char *c;
+    for (c = cp; *c != 0; c++) {
+      if (*c == ':') {
+        /* contains a colon: IPv6 address */
+        if (addr) {
+          IP_SET_TYPE_VAL(*addr, IPADDR_TYPE_V6);
+        }
+        return ip6addr_aton(cp, ip_2_ip6(addr));
+      } else if (*c == '.') {
+        /* contains a dot: IPv4 address */
+        break;
+      }
+    }
+    /* call ip4addr_aton as fallback or if IPv4 was found */
+    if (addr) {
+      IP_SET_TYPE_VAL(*addr, IPADDR_TYPE_V4);
+    }
+    return ip4addr_aton(cp, ip_2_ip4(addr));
+  }
+  return 0;
+}
+
+/**
+ * @ingroup lwip_nosys
+ * If both IP versions are enabled, this function can dispatch packets to the correct one.
+ * Don't call directly, pass to netif_add() and call netif->input().
+ */
+err_t
+ip_input(struct pbuf *p, struct netif *inp)
+{
+  if (p != NULL) {
+    if (IP_HDR_GET_VERSION(p->payload) == 6) {
+      return ip6_input(p, inp);
+    }
+    return ip4_input(p, inp);
+  }
+  return ERR_VAL;
+}
+
+#endif /* LWIP_IPV4 && LWIP_IPV6 */
+
+#endif /* LWIP_IPV4 || LWIP_IPV6 */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/core/ipv4/autoip.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/core/ipv4/autoip.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/core/ipv4/autoip.c	(revision 457)
@@ -0,0 +1,527 @@
+/**
+ * @file
+ * AutoIP Automatic LinkLocal IP Configuration
+ *
+ * This is a AutoIP implementation for the lwIP TCP/IP stack. It aims to conform
+ * with RFC 3927.
+ *
+ * @defgroup autoip AUTOIP
+ * @ingroup ip4
+ * AUTOIP related functions
+ * USAGE:
+ *
+ * define @ref LWIP_AUTOIP 1 in your lwipopts.h
+ * Options:
+ * AUTOIP_TMR_INTERVAL msecs,
+ *   I recommend a value of 100. The value must divide 1000 with a remainder almost 0.
+ *   Possible values are 1000, 500, 333, 250, 200, 166, 142, 125, 111, 100 ....
+ *
+ * Without DHCP:
+ * - Call autoip_start() after netif_add().
+ *
+ * With DHCP:
+ * - define @ref LWIP_DHCP_AUTOIP_COOP 1 in your lwipopts.h.
+ * - Configure your DHCP Client.
+ *
+ * @see netifapi_autoip
+ */
+
+/*
+ *
+ * Copyright (c) 2007 Dominik Spies <kontakt@dspies.de>
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * Author: Dominik Spies <kontakt@dspies.de>
+ */
+
+#include "lwip/opt.h"
+
+#if LWIP_IPV4 && LWIP_AUTOIP /* don't build if not configured for use in lwipopts.h */
+
+#include "lwip/mem.h"
+/* #include "lwip/udp.h" */
+#include "lwip/ip_addr.h"
+#include "lwip/netif.h"
+#include "lwip/autoip.h"
+#include "lwip/etharp.h"
+#include "lwip/prot/autoip.h"
+
+#include <string.h>
+
+/** Pseudo random macro based on netif informations.
+ * You could use "rand()" from the C Library if you define LWIP_AUTOIP_RAND in lwipopts.h */
+#ifndef LWIP_AUTOIP_RAND
+#define LWIP_AUTOIP_RAND(netif) ( (((u32_t)((netif->hwaddr[5]) & 0xff) << 24) | \
+                                   ((u32_t)((netif->hwaddr[3]) & 0xff) << 16) | \
+                                   ((u32_t)((netif->hwaddr[2]) & 0xff) << 8) | \
+                                   ((u32_t)((netif->hwaddr[4]) & 0xff))) + \
+                                   (netif_autoip_data(netif)? netif_autoip_data(netif)->tried_llipaddr : 0))
+#endif /* LWIP_AUTOIP_RAND */
+
+/**
+ * Macro that generates the initial IP address to be tried by AUTOIP.
+ * If you want to override this, define it to something else in lwipopts.h.
+ */
+#ifndef LWIP_AUTOIP_CREATE_SEED_ADDR
+#define LWIP_AUTOIP_CREATE_SEED_ADDR(netif) \
+  lwip_htonl(AUTOIP_RANGE_START + ((u32_t)(((u8_t)(netif->hwaddr[4])) | \
+                 ((u32_t)((u8_t)(netif->hwaddr[5]))) << 8)))
+#endif /* LWIP_AUTOIP_CREATE_SEED_ADDR */
+
+/* static functions */
+static err_t autoip_arp_announce(struct netif *netif);
+static void autoip_start_probing(struct netif *netif);
+
+/**
+ * @ingroup autoip
+ * Set a statically allocated struct autoip to work with.
+ * Using this prevents autoip_start to allocate it using mem_malloc.
+ *
+ * @param netif the netif for which to set the struct autoip
+ * @param autoip (uninitialised) autoip struct allocated by the application
+ */
+void
+autoip_set_struct(struct netif *netif, struct autoip *autoip)
+{
+  LWIP_ASSERT_CORE_LOCKED();
+  LWIP_ASSERT("netif != NULL", netif != NULL);
+  LWIP_ASSERT("autoip != NULL", autoip != NULL);
+  LWIP_ASSERT("netif already has a struct autoip set",
+              netif_autoip_data(netif) == NULL);
+
+  /* clear data structure */
+  memset(autoip, 0, sizeof(struct autoip));
+  /* autoip->state = AUTOIP_STATE_OFF; */
+  netif_set_client_data(netif, LWIP_NETIF_CLIENT_DATA_INDEX_AUTOIP, autoip);
+}
+
+/** Restart AutoIP client and check the next address (conflict detected)
+ *
+ * @param netif The netif under AutoIP control
+ */
+static void
+autoip_restart(struct netif *netif)
+{
+  struct autoip *autoip = netif_autoip_data(netif);
+  autoip->tried_llipaddr++;
+  autoip_start(netif);
+}
+
+/**
+ * Handle a IP address conflict after an ARP conflict detection
+ */
+static void
+autoip_handle_arp_conflict(struct netif *netif)
+{
+  struct autoip *autoip = netif_autoip_data(netif);
+
+  /* RFC3927, 2.5 "Conflict Detection and Defense" allows two options where
+     a) means retreat on the first conflict and
+     b) allows to keep an already configured address when having only one
+        conflict in 10 seconds
+     We use option b) since it helps to improve the chance that one of the two
+     conflicting hosts may be able to retain its address. */
+
+  if (autoip->lastconflict > 0) {
+    /* retreat, there was a conflicting ARP in the last DEFEND_INTERVAL seconds */
+    LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE,
+                ("autoip_handle_arp_conflict(): we are defending, but in DEFEND_INTERVAL, retreating\n"));
+
+    /* Active TCP sessions are aborted when removing the ip addresss */
+    autoip_restart(netif);
+  } else {
+    LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE,
+                ("autoip_handle_arp_conflict(): we are defend, send ARP Announce\n"));
+    autoip_arp_announce(netif);
+    autoip->lastconflict = DEFEND_INTERVAL * AUTOIP_TICKS_PER_SECOND;
+  }
+}
+
+/**
+ * Create an IP-Address out of range 169.254.1.0 to 169.254.254.255
+ *
+ * @param netif network interface on which create the IP-Address
+ * @param ipaddr ip address to initialize
+ */
+static void
+autoip_create_addr(struct netif *netif, ip4_addr_t *ipaddr)
+{
+  struct autoip *autoip = netif_autoip_data(netif);
+
+  /* Here we create an IP-Address out of range 169.254.1.0 to 169.254.254.255
+   * compliant to RFC 3927 Section 2.1
+   * We have 254 * 256 possibilities */
+
+  u32_t addr = lwip_ntohl(LWIP_AUTOIP_CREATE_SEED_ADDR(netif));
+  addr += autoip->tried_llipaddr;
+  addr = AUTOIP_NET | (addr & 0xffff);
+  /* Now, 169.254.0.0 <= addr <= 169.254.255.255 */
+
+  if (addr < AUTOIP_RANGE_START) {
+    addr += AUTOIP_RANGE_END - AUTOIP_RANGE_START + 1;
+  }
+  if (addr > AUTOIP_RANGE_END) {
+    addr -= AUTOIP_RANGE_END - AUTOIP_RANGE_START + 1;
+  }
+  LWIP_ASSERT("AUTOIP address not in range", (addr >= AUTOIP_RANGE_START) &&
+              (addr <= AUTOIP_RANGE_END));
+  ip4_addr_set_u32(ipaddr, lwip_htonl(addr));
+
+  LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE,
+              ("autoip_create_addr(): tried_llipaddr=%"U16_F", %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n",
+               (u16_t)(autoip->tried_llipaddr), ip4_addr1_16(ipaddr), ip4_addr2_16(ipaddr),
+               ip4_addr3_16(ipaddr), ip4_addr4_16(ipaddr)));
+}
+
+/**
+ * Sends an ARP probe from a network interface
+ *
+ * @param netif network interface used to send the probe
+ */
+static err_t
+autoip_arp_probe(struct netif *netif)
+{
+  struct autoip *autoip = netif_autoip_data(netif);
+  /* this works because netif->ip_addr is ANY */
+  return etharp_request(netif, &autoip->llipaddr);
+}
+
+/**
+ * Sends an ARP announce from a network interface
+ *
+ * @param netif network interface used to send the announce
+ */
+static err_t
+autoip_arp_announce(struct netif *netif)
+{
+  return etharp_gratuitous(netif);
+}
+
+/**
+ * Configure interface for use with current LL IP-Address
+ *
+ * @param netif network interface to configure with current LL IP-Address
+ */
+static err_t
+autoip_bind(struct netif *netif)
+{
+  struct autoip *autoip = netif_autoip_data(netif);
+  ip4_addr_t sn_mask, gw_addr;
+
+  LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE,
+              ("autoip_bind(netif=%p) %c%c%"U16_F" %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n",
+               (void *)netif, netif->name[0], netif->name[1], (u16_t)netif->num,
+               ip4_addr1_16(&autoip->llipaddr), ip4_addr2_16(&autoip->llipaddr),
+               ip4_addr3_16(&autoip->llipaddr), ip4_addr4_16(&autoip->llipaddr)));
+
+  IP4_ADDR(&sn_mask, 255, 255, 0, 0);
+  IP4_ADDR(&gw_addr, 0, 0, 0, 0);
+
+  netif_set_addr(netif, &autoip->llipaddr, &sn_mask, &gw_addr);
+  /* interface is used by routing now that an address is set */
+
+  return ERR_OK;
+}
+
+/**
+ * @ingroup autoip
+ * Start AutoIP client
+ *
+ * @param netif network interface on which start the AutoIP client
+ */
+err_t
+autoip_start(struct netif *netif)
+{
+  struct autoip *autoip = netif_autoip_data(netif);
+  err_t result = ERR_OK;
+
+  LWIP_ASSERT_CORE_LOCKED();
+  LWIP_ERROR("netif is not up, old style port?", netif_is_up(netif), return ERR_ARG;);
+
+  /* Set IP-Address, Netmask and Gateway to 0 to make sure that
+   * ARP Packets are formed correctly
+   */
+  netif_set_addr(netif, IP4_ADDR_ANY4, IP4_ADDR_ANY4, IP4_ADDR_ANY4);
+
+  LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE,
+              ("autoip_start(netif=%p) %c%c%"U16_F"\n", (void *)netif, netif->name[0],
+               netif->name[1], (u16_t)netif->num));
+  if (autoip == NULL) {
+    /* no AutoIP client attached yet? */
+    LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE,
+                ("autoip_start(): starting new AUTOIP client\n"));
+    autoip = (struct autoip *)mem_calloc(1, sizeof(struct autoip));
+    if (autoip == NULL) {
+      LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE,
+                  ("autoip_start(): could not allocate autoip\n"));
+      return ERR_MEM;
+    }
+    /* store this AutoIP client in the netif */
+    netif_set_client_data(netif, LWIP_NETIF_CLIENT_DATA_INDEX_AUTOIP, autoip);
+    LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE, ("autoip_start(): allocated autoip"));
+  } else {
+    autoip->state = AUTOIP_STATE_OFF;
+    autoip->ttw = 0;
+    autoip->sent_num = 0;
+    ip4_addr_set_zero(&autoip->llipaddr);
+    autoip->lastconflict = 0;
+  }
+
+  autoip_create_addr(netif, &(autoip->llipaddr));
+  autoip_start_probing(netif);
+
+  return result;
+}
+
+static void
+autoip_start_probing(struct netif *netif)
+{
+  struct autoip *autoip = netif_autoip_data(netif);
+
+  autoip->state = AUTOIP_STATE_PROBING;
+  autoip->sent_num = 0;
+  LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE,
+              ("autoip_start_probing(): changing state to PROBING: %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n",
+               ip4_addr1_16(&autoip->llipaddr), ip4_addr2_16(&autoip->llipaddr),
+               ip4_addr3_16(&autoip->llipaddr), ip4_addr4_16(&autoip->llipaddr)));
+
+  /* time to wait to first probe, this is randomly
+   * chosen out of 0 to PROBE_WAIT seconds.
+   * compliant to RFC 3927 Section 2.2.1
+   */
+  autoip->ttw = (u16_t)(LWIP_AUTOIP_RAND(netif) % (PROBE_WAIT * AUTOIP_TICKS_PER_SECOND));
+
+  /*
+   * if we tried more then MAX_CONFLICTS we must limit our rate for
+   * acquiring and probing address
+   * compliant to RFC 3927 Section 2.2.1
+   */
+  if (autoip->tried_llipaddr > MAX_CONFLICTS) {
+    autoip->ttw = RATE_LIMIT_INTERVAL * AUTOIP_TICKS_PER_SECOND;
+  }
+}
+
+/**
+ * Handle a possible change in the network configuration.
+ *
+ * If there is an AutoIP address configured, take the interface down
+ * and begin probing with the same address.
+ */
+void
+autoip_network_changed(struct netif *netif)
+{
+  struct autoip *autoip = netif_autoip_data(netif);
+
+  if (autoip && (autoip->state != AUTOIP_STATE_OFF)) {
+    autoip_start_probing(netif);
+  }
+}
+
+/**
+ * @ingroup autoip
+ * Stop AutoIP client
+ *
+ * @param netif network interface on which stop the AutoIP client
+ */
+err_t
+autoip_stop(struct netif *netif)
+{
+  struct autoip *autoip = netif_autoip_data(netif);
+
+  LWIP_ASSERT_CORE_LOCKED();
+  if (autoip != NULL) {
+    autoip->state = AUTOIP_STATE_OFF;
+    if (ip4_addr_islinklocal(netif_ip4_addr(netif))) {
+      netif_set_addr(netif, IP4_ADDR_ANY4, IP4_ADDR_ANY4, IP4_ADDR_ANY4);
+    }
+  }
+  return ERR_OK;
+}
+
+/**
+ * Has to be called in loop every AUTOIP_TMR_INTERVAL milliseconds
+ */
+void
+autoip_tmr(void)
+{
+  struct netif *netif;
+  /* loop through netif's */
+  NETIF_FOREACH(netif) {
+    struct autoip *autoip = netif_autoip_data(netif);
+    /* only act on AutoIP configured interfaces */
+    if (autoip != NULL) {
+      if (autoip->lastconflict > 0) {
+        autoip->lastconflict--;
+      }
+
+      LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE,
+                  ("autoip_tmr() AutoIP-State: %"U16_F", ttw=%"U16_F"\n",
+                   (u16_t)(autoip->state), autoip->ttw));
+
+      if (autoip->ttw > 0) {
+        autoip->ttw--;
+      }
+
+      switch (autoip->state) {
+        case AUTOIP_STATE_PROBING:
+          if (autoip->ttw == 0) {
+            if (autoip->sent_num >= PROBE_NUM) {
+              /* Switch to ANNOUNCING: now we can bind to an IP address and use it */
+              autoip->state = AUTOIP_STATE_ANNOUNCING;
+              autoip_bind(netif);
+              /* autoip_bind() calls netif_set_addr(): this triggers a gratuitous ARP
+                 which counts as an announcement */
+              autoip->sent_num = 1;
+              autoip->ttw = ANNOUNCE_WAIT * AUTOIP_TICKS_PER_SECOND;
+              LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE,
+                          ("autoip_tmr(): changing state to ANNOUNCING: %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n",
+                           ip4_addr1_16(&autoip->llipaddr), ip4_addr2_16(&autoip->llipaddr),
+                           ip4_addr3_16(&autoip->llipaddr), ip4_addr4_16(&autoip->llipaddr)));
+            } else {
+              autoip_arp_probe(netif);
+              LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE, ("autoip_tmr() PROBING Sent Probe\n"));
+              autoip->sent_num++;
+              if (autoip->sent_num == PROBE_NUM) {
+                /* calculate time to wait to for announce */
+                autoip->ttw = ANNOUNCE_WAIT * AUTOIP_TICKS_PER_SECOND;
+              } else {
+                /* calculate time to wait to next probe */
+                autoip->ttw = (u16_t)((LWIP_AUTOIP_RAND(netif) %
+                                       ((PROBE_MAX - PROBE_MIN) * AUTOIP_TICKS_PER_SECOND) ) +
+                                      PROBE_MIN * AUTOIP_TICKS_PER_SECOND);
+              }
+            }
+          }
+          break;
+
+        case AUTOIP_STATE_ANNOUNCING:
+          if (autoip->ttw == 0) {
+            autoip_arp_announce(netif);
+            LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE, ("autoip_tmr() ANNOUNCING Sent Announce\n"));
+            autoip->ttw = ANNOUNCE_INTERVAL * AUTOIP_TICKS_PER_SECOND;
+            autoip->sent_num++;
+
+            if (autoip->sent_num >= ANNOUNCE_NUM) {
+              autoip->state = AUTOIP_STATE_BOUND;
+              autoip->sent_num = 0;
+              autoip->ttw = 0;
+              LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE,
+                          ("autoip_tmr(): changing state to BOUND: %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n",
+                           ip4_addr1_16(&autoip->llipaddr), ip4_addr2_16(&autoip->llipaddr),
+                           ip4_addr3_16(&autoip->llipaddr), ip4_addr4_16(&autoip->llipaddr)));
+            }
+          }
+          break;
+
+        default:
+          /* nothing to do in other states */
+          break;
+      }
+    }
+  }
+}
+
+/**
+ * Handles every incoming ARP Packet, called by etharp_input().
+ *
+ * @param netif network interface to use for autoip processing
+ * @param hdr Incoming ARP packet
+ */
+void
+autoip_arp_reply(struct netif *netif, struct etharp_hdr *hdr)
+{
+  struct autoip *autoip = netif_autoip_data(netif);
+
+  LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE, ("autoip_arp_reply()\n"));
+  if ((autoip != NULL) && (autoip->state != AUTOIP_STATE_OFF)) {
+    /* when ip.src == llipaddr && hw.src != netif->hwaddr
+     *
+     * when probing  ip.dst == llipaddr && hw.src != netif->hwaddr
+     * we have a conflict and must solve it
+     */
+    ip4_addr_t sipaddr, dipaddr;
+    struct eth_addr netifaddr;
+    SMEMCPY(netifaddr.addr, netif->hwaddr, ETH_HWADDR_LEN);
+
+    /* Copy struct ip4_addr_wordaligned to aligned ip4_addr, to support compilers without
+     * structure packing (not using structure copy which breaks strict-aliasing rules).
+     */
+    IPADDR_WORDALIGNED_COPY_TO_IP4_ADDR_T(&sipaddr, &hdr->sipaddr);
+    IPADDR_WORDALIGNED_COPY_TO_IP4_ADDR_T(&dipaddr, &hdr->dipaddr);
+
+    if (autoip->state == AUTOIP_STATE_PROBING) {
+      /* RFC 3927 Section 2.2.1:
+       * from beginning to after ANNOUNCE_WAIT
+       * seconds we have a conflict if
+       * ip.src == llipaddr OR
+       * ip.dst == llipaddr && hw.src != own hwaddr
+       */
+      if ((ip4_addr_cmp(&sipaddr, &autoip->llipaddr)) ||
+          (ip4_addr_isany_val(sipaddr) &&
+           ip4_addr_cmp(&dipaddr, &autoip->llipaddr) &&
+           !eth_addr_cmp(&netifaddr, &hdr->shwaddr))) {
+        LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE | LWIP_DBG_LEVEL_WARNING,
+                    ("autoip_arp_reply(): Probe Conflict detected\n"));
+        autoip_restart(netif);
+      }
+    } else {
+      /* RFC 3927 Section 2.5:
+       * in any state we have a conflict if
+       * ip.src == llipaddr && hw.src != own hwaddr
+       */
+      if (ip4_addr_cmp(&sipaddr, &autoip->llipaddr) &&
+          !eth_addr_cmp(&netifaddr, &hdr->shwaddr)) {
+        LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE | LWIP_DBG_LEVEL_WARNING,
+                    ("autoip_arp_reply(): Conflicting ARP-Packet detected\n"));
+        autoip_handle_arp_conflict(netif);
+      }
+    }
+  }
+}
+
+/** check if AutoIP supplied netif->ip_addr
+ *
+ * @param netif the netif to check
+ * @return 1 if AutoIP supplied netif->ip_addr (state BOUND or ANNOUNCING),
+ *         0 otherwise
+ */
+u8_t
+autoip_supplied_address(const struct netif *netif)
+{
+  if ((netif != NULL) && (netif_autoip_data(netif) != NULL)) {
+    struct autoip *autoip = netif_autoip_data(netif);
+    return (autoip->state == AUTOIP_STATE_BOUND) || (autoip->state == AUTOIP_STATE_ANNOUNCING);
+  }
+  return 0;
+}
+
+u8_t
+autoip_accept_packet(struct netif *netif, const ip4_addr_t *addr)
+{
+  struct autoip *autoip = netif_autoip_data(netif);
+  return (autoip != NULL) && ip4_addr_cmp(addr, &(autoip->llipaddr));
+}
+
+#endif /* LWIP_IPV4 && LWIP_AUTOIP */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/core/ipv4/dhcp.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/core/ipv4/dhcp.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/core/ipv4/dhcp.c	(revision 457)
@@ -0,0 +1,1990 @@
+/**
+ * @file
+ * Dynamic Host Configuration Protocol client
+ *
+ * @defgroup dhcp4 DHCPv4
+ * @ingroup ip4
+ * DHCP (IPv4) related functions
+ * This is a DHCP client for the lwIP TCP/IP stack. It aims to conform
+ * with RFC 2131 and RFC 2132.
+ *
+ * @todo:
+ * - Support for interfaces other than Ethernet (SLIP, PPP, ...)
+ *
+ * Options:
+ * @ref DHCP_COARSE_TIMER_SECS (recommended 60 which is a minute)
+ * @ref DHCP_FINE_TIMER_MSECS (recommended 500 which equals TCP coarse timer)
+ *
+ * dhcp_start() starts a DHCP client instance which
+ * configures the interface by obtaining an IP address lease and maintaining it.
+ *
+ * Use dhcp_release() to end the lease and use dhcp_stop()
+ * to remove the DHCP client.
+ *
+ * @see LWIP_HOOK_DHCP_APPEND_OPTIONS
+ * @see LWIP_HOOK_DHCP_PARSE_OPTION
+ *
+ * @see netifapi_dhcp4
+ */
+
+/*
+ * Copyright (c) 2001-2004 Leon Woestenberg <leon.woestenberg@gmx.net>
+ * Copyright (c) 2001-2004 Axon Digital Design B.V., The Netherlands.
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ * The Swedish Institute of Computer Science and Adam Dunkels
+ * are specifically granted permission to redistribute this
+ * source code.
+ *
+ * Author: Leon Woestenberg <leon.woestenberg@gmx.net>
+ *
+ */
+
+#include "lwip/opt.h"
+
+#if LWIP_IPV4 && LWIP_DHCP /* don't build if not configured for use in lwipopts.h */
+
+#include "lwip/stats.h"
+#include "lwip/mem.h"
+#include "lwip/udp.h"
+#include "lwip/ip_addr.h"
+#include "lwip/netif.h"
+#include "lwip/def.h"
+#include "lwip/dhcp.h"
+#include "lwip/autoip.h"
+#include "lwip/dns.h"
+#include "lwip/etharp.h"
+#include "lwip/prot/dhcp.h"
+#include "lwip/prot/iana.h"
+
+#include <string.h>
+
+#ifdef LWIP_HOOK_FILENAME
+#include LWIP_HOOK_FILENAME
+#endif
+#ifndef LWIP_HOOK_DHCP_APPEND_OPTIONS
+#define LWIP_HOOK_DHCP_APPEND_OPTIONS(netif, dhcp, state, msg, msg_type, options_len_ptr)
+#endif
+#ifndef LWIP_HOOK_DHCP_PARSE_OPTION
+#define LWIP_HOOK_DHCP_PARSE_OPTION(netif, dhcp, state, msg, msg_type, option, len, pbuf, offset) do { LWIP_UNUSED_ARG(msg); } while(0)
+#endif
+
+/** DHCP_CREATE_RAND_XID: if this is set to 1, the xid is created using
+ * LWIP_RAND() (this overrides DHCP_GLOBAL_XID)
+ */
+#ifndef DHCP_CREATE_RAND_XID
+#define DHCP_CREATE_RAND_XID        1
+#endif
+
+/** Default for DHCP_GLOBAL_XID is 0xABCD0000
+ * This can be changed by defining DHCP_GLOBAL_XID and DHCP_GLOBAL_XID_HEADER, e.g.
+ *  \#define DHCP_GLOBAL_XID_HEADER "stdlib.h"
+ *  \#define DHCP_GLOBAL_XID rand()
+ */
+#ifdef DHCP_GLOBAL_XID_HEADER
+#include DHCP_GLOBAL_XID_HEADER /* include optional starting XID generation prototypes */
+#endif
+
+/** DHCP_OPTION_MAX_MSG_SIZE is set to the MTU
+ * MTU is checked to be big enough in dhcp_start */
+#define DHCP_MAX_MSG_LEN(netif)        (netif->mtu)
+#define DHCP_MAX_MSG_LEN_MIN_REQUIRED  576
+/** Minimum length for reply before packet is parsed */
+#define DHCP_MIN_REPLY_LEN             44
+
+#define REBOOT_TRIES                2
+
+#if LWIP_DNS && LWIP_DHCP_MAX_DNS_SERVERS
+#if DNS_MAX_SERVERS > LWIP_DHCP_MAX_DNS_SERVERS
+#define LWIP_DHCP_PROVIDE_DNS_SERVERS LWIP_DHCP_MAX_DNS_SERVERS
+#else
+#define LWIP_DHCP_PROVIDE_DNS_SERVERS DNS_MAX_SERVERS
+#endif
+#else
+#define LWIP_DHCP_PROVIDE_DNS_SERVERS 0
+#endif
+
+/** Option handling: options are parsed in dhcp_parse_reply
+ * and saved in an array where other functions can load them from.
+ * This might be moved into the struct dhcp (not necessarily since
+ * lwIP is single-threaded and the array is only used while in recv
+ * callback). */
+enum dhcp_option_idx {
+  DHCP_OPTION_IDX_OVERLOAD = 0,
+  DHCP_OPTION_IDX_MSG_TYPE,
+  DHCP_OPTION_IDX_SERVER_ID,
+  DHCP_OPTION_IDX_LEASE_TIME,
+  DHCP_OPTION_IDX_T1,
+  DHCP_OPTION_IDX_T2,
+  DHCP_OPTION_IDX_SUBNET_MASK,
+  DHCP_OPTION_IDX_ROUTER,
+#if LWIP_DHCP_PROVIDE_DNS_SERVERS
+  DHCP_OPTION_IDX_DNS_SERVER,
+  DHCP_OPTION_IDX_DNS_SERVER_LAST = DHCP_OPTION_IDX_DNS_SERVER + LWIP_DHCP_PROVIDE_DNS_SERVERS - 1,
+#endif /* LWIP_DHCP_PROVIDE_DNS_SERVERS */
+#if LWIP_DHCP_GET_NTP_SRV
+  DHCP_OPTION_IDX_NTP_SERVER,
+  DHCP_OPTION_IDX_NTP_SERVER_LAST = DHCP_OPTION_IDX_NTP_SERVER + LWIP_DHCP_MAX_NTP_SERVERS - 1,
+#endif /* LWIP_DHCP_GET_NTP_SRV */
+  DHCP_OPTION_IDX_MAX
+};
+
+/** Holds the decoded option values, only valid while in dhcp_recv.
+    @todo: move this into struct dhcp? */
+u32_t dhcp_rx_options_val[DHCP_OPTION_IDX_MAX];
+/** Holds a flag which option was received and is contained in dhcp_rx_options_val,
+    only valid while in dhcp_recv.
+    @todo: move this into struct dhcp? */
+u8_t  dhcp_rx_options_given[DHCP_OPTION_IDX_MAX];
+
+static u8_t dhcp_discover_request_options[] = {
+  DHCP_OPTION_SUBNET_MASK,
+  DHCP_OPTION_ROUTER,
+  DHCP_OPTION_BROADCAST
+#if LWIP_DHCP_PROVIDE_DNS_SERVERS
+  , DHCP_OPTION_DNS_SERVER
+#endif /* LWIP_DHCP_PROVIDE_DNS_SERVERS */
+#if LWIP_DHCP_GET_NTP_SRV
+  , DHCP_OPTION_NTP
+#endif /* LWIP_DHCP_GET_NTP_SRV */
+};
+
+#ifdef DHCP_GLOBAL_XID
+static u32_t xid;
+static u8_t xid_initialised;
+#endif /* DHCP_GLOBAL_XID */
+
+#define dhcp_option_given(dhcp, idx)          (dhcp_rx_options_given[idx] != 0)
+#define dhcp_got_option(dhcp, idx)            (dhcp_rx_options_given[idx] = 1)
+#define dhcp_clear_option(dhcp, idx)          (dhcp_rx_options_given[idx] = 0)
+#define dhcp_clear_all_options(dhcp)          (MEMSET(dhcp_rx_options_given, 0, sizeof(dhcp_rx_options_given)))
+#define dhcp_get_option_value(dhcp, idx)      (dhcp_rx_options_val[idx])
+#define dhcp_set_option_value(dhcp, idx, val) (dhcp_rx_options_val[idx] = (val))
+
+static struct udp_pcb *dhcp_pcb;
+static u8_t dhcp_pcb_refcount;
+
+/* DHCP client state machine functions */
+static err_t dhcp_discover(struct netif *netif);
+static err_t dhcp_select(struct netif *netif);
+static void dhcp_bind(struct netif *netif);
+#if DHCP_DOES_ARP_CHECK
+static err_t dhcp_decline(struct netif *netif);
+#endif /* DHCP_DOES_ARP_CHECK */
+static err_t dhcp_rebind(struct netif *netif);
+static err_t dhcp_reboot(struct netif *netif);
+static void dhcp_set_state(struct dhcp *dhcp, u8_t new_state);
+
+/* receive, unfold, parse and free incoming messages */
+static void dhcp_recv(void *arg, struct udp_pcb *pcb, struct pbuf *p, const ip_addr_t *addr, u16_t port);
+
+/* set the DHCP timers */
+static void dhcp_timeout(struct netif *netif);
+static void dhcp_t1_timeout(struct netif *netif);
+static void dhcp_t2_timeout(struct netif *netif);
+
+/* build outgoing messages */
+/* create a DHCP message, fill in common headers */
+static struct pbuf *dhcp_create_msg(struct netif *netif, struct dhcp *dhcp, u8_t message_type, u16_t *options_out_len);
+/* add a DHCP option (type, then length in bytes) */
+static u16_t dhcp_option(u16_t options_out_len, u8_t *options, u8_t option_type, u8_t option_len);
+/* add option values */
+static u16_t dhcp_option_byte(u16_t options_out_len, u8_t *options, u8_t value);
+static u16_t dhcp_option_short(u16_t options_out_len, u8_t *options, u16_t value);
+static u16_t dhcp_option_long(u16_t options_out_len, u8_t *options, u32_t value);
+#if LWIP_NETIF_HOSTNAME
+static u16_t dhcp_option_hostname(u16_t options_out_len, u8_t *options, struct netif *netif);
+#endif /* LWIP_NETIF_HOSTNAME */
+/* always add the DHCP options trailer to end and pad */
+static void dhcp_option_trailer(u16_t options_out_len, u8_t *options, struct pbuf *p_out);
+
+/** Ensure DHCP PCB is allocated and bound */
+static err_t
+dhcp_inc_pcb_refcount(void)
+{
+  if (dhcp_pcb_refcount == 0) {
+    LWIP_ASSERT("dhcp_inc_pcb_refcount(): memory leak", dhcp_pcb == NULL);
+
+    /* allocate UDP PCB */
+    dhcp_pcb = udp_new();
+
+    if (dhcp_pcb == NULL) {
+      return ERR_MEM;
+    }
+
+    ip_set_option(dhcp_pcb, SOF_BROADCAST);
+
+    /* set up local and remote port for the pcb -> listen on all interfaces on all src/dest IPs */
+    udp_bind(dhcp_pcb, IP4_ADDR_ANY, LWIP_IANA_PORT_DHCP_CLIENT);
+    udp_connect(dhcp_pcb, IP4_ADDR_ANY, LWIP_IANA_PORT_DHCP_SERVER);
+    udp_recv(dhcp_pcb, dhcp_recv, NULL);
+  }
+
+  dhcp_pcb_refcount++;
+
+  return ERR_OK;
+}
+
+/** Free DHCP PCB if the last netif stops using it */
+static void
+dhcp_dec_pcb_refcount(void)
+{
+  LWIP_ASSERT("dhcp_pcb_refcount(): refcount error", (dhcp_pcb_refcount > 0));
+  dhcp_pcb_refcount--;
+
+  if (dhcp_pcb_refcount == 0) {
+    udp_remove(dhcp_pcb);
+    dhcp_pcb = NULL;
+  }
+}
+
+/**
+ * Back-off the DHCP client (because of a received NAK response).
+ *
+ * Back-off the DHCP client because of a received NAK. Receiving a
+ * NAK means the client asked for something non-sensible, for
+ * example when it tries to renew a lease obtained on another network.
+ *
+ * We clear any existing set IP address and restart DHCP negotiation
+ * afresh (as per RFC2131 3.2.3).
+ *
+ * @param netif the netif under DHCP control
+ */
+static void
+dhcp_handle_nak(struct netif *netif)
+{
+  struct dhcp *dhcp = netif_dhcp_data(netif);
+
+  LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_handle_nak(netif=%p) %c%c%"U16_F"\n",
+              (void *)netif, netif->name[0], netif->name[1], (u16_t)netif->num));
+  /* Change to a defined state - set this before assigning the address
+     to ensure the callback can use dhcp_supplied_address() */
+  dhcp_set_state(dhcp, DHCP_STATE_BACKING_OFF);
+  /* remove IP address from interface (must no longer be used, as per RFC2131) */
+  netif_set_addr(netif, IP4_ADDR_ANY4, IP4_ADDR_ANY4, IP4_ADDR_ANY4);
+  /* We can immediately restart discovery */
+  dhcp_discover(netif);
+}
+
+#if DHCP_DOES_ARP_CHECK
+/**
+ * Checks if the offered IP address is already in use.
+ *
+ * It does so by sending an ARP request for the offered address and
+ * entering CHECKING state. If no ARP reply is received within a small
+ * interval, the address is assumed to be free for use by us.
+ *
+ * @param netif the netif under DHCP control
+ */
+static void
+dhcp_check(struct netif *netif)
+{
+  struct dhcp *dhcp = netif_dhcp_data(netif);
+  err_t result;
+  u16_t msecs;
+  LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_check(netif=%p) %c%c\n", (void *)netif, (s16_t)netif->name[0],
+              (s16_t)netif->name[1]));
+  dhcp_set_state(dhcp, DHCP_STATE_CHECKING);
+  /* create an ARP query for the offered IP address, expecting that no host
+     responds, as the IP address should not be in use. */
+  result = etharp_query(netif, &dhcp->offered_ip_addr, NULL);
+  if (result != ERR_OK) {
+    LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_WARNING, ("dhcp_check: could not perform ARP query\n"));
+  }
+  if (dhcp->tries < 255) {
+    dhcp->tries++;
+  }
+  msecs = 500;
+  dhcp->request_timeout = (u16_t)((msecs + DHCP_FINE_TIMER_MSECS - 1) / DHCP_FINE_TIMER_MSECS);
+  LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_check(): set request timeout %"U16_F" msecs\n", msecs));
+}
+#endif /* DHCP_DOES_ARP_CHECK */
+
+/**
+ * Remember the configuration offered by a DHCP server.
+ *
+ * @param netif the netif under DHCP control
+ */
+static void
+dhcp_handle_offer(struct netif *netif, struct dhcp_msg *msg_in)
+{
+  struct dhcp *dhcp = netif_dhcp_data(netif);
+
+  LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_handle_offer(netif=%p) %c%c%"U16_F"\n",
+              (void *)netif, netif->name[0], netif->name[1], (u16_t)netif->num));
+  /* obtain the server address */
+  if (dhcp_option_given(dhcp, DHCP_OPTION_IDX_SERVER_ID)) {
+    dhcp->request_timeout = 0; /* stop timer */
+
+    ip_addr_set_ip4_u32(&dhcp->server_ip_addr, lwip_htonl(dhcp_get_option_value(dhcp, DHCP_OPTION_IDX_SERVER_ID)));
+    LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_STATE, ("dhcp_handle_offer(): server 0x%08"X32_F"\n",
+                ip4_addr_get_u32(ip_2_ip4(&dhcp->server_ip_addr))));
+    /* remember offered address */
+    ip4_addr_copy(dhcp->offered_ip_addr, msg_in->yiaddr);
+    LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_STATE, ("dhcp_handle_offer(): offer for 0x%08"X32_F"\n",
+                ip4_addr_get_u32(&dhcp->offered_ip_addr)));
+
+    dhcp_select(netif);
+  } else {
+    LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS,
+                ("dhcp_handle_offer(netif=%p) did not get server ID!\n", (void *)netif));
+  }
+}
+
+/**
+ * Select a DHCP server offer out of all offers.
+ *
+ * Simply select the first offer received.
+ *
+ * @param netif the netif under DHCP control
+ * @return lwIP specific error (see error.h)
+ */
+static err_t
+dhcp_select(struct netif *netif)
+{
+  struct dhcp *dhcp;
+  err_t result;
+  u16_t msecs;
+  u8_t i;
+  struct pbuf *p_out;
+  u16_t options_out_len;
+
+  LWIP_ERROR("dhcp_select: netif != NULL", (netif != NULL), return ERR_ARG;);
+  dhcp = netif_dhcp_data(netif);
+  LWIP_ERROR("dhcp_select: dhcp != NULL", (dhcp != NULL), return ERR_VAL;);
+
+  LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_select(netif=%p) %c%c%"U16_F"\n", (void *)netif, netif->name[0], netif->name[1], (u16_t)netif->num));
+  dhcp_set_state(dhcp, DHCP_STATE_REQUESTING);
+
+  /* create and initialize the DHCP message header */
+  p_out = dhcp_create_msg(netif, dhcp, DHCP_REQUEST, &options_out_len);
+  if (p_out != NULL) {
+    struct dhcp_msg *msg_out = (struct dhcp_msg *)p_out->payload;
+    options_out_len = dhcp_option(options_out_len, msg_out->options, DHCP_OPTION_MAX_MSG_SIZE, DHCP_OPTION_MAX_MSG_SIZE_LEN);
+    options_out_len = dhcp_option_short(options_out_len, msg_out->options, DHCP_MAX_MSG_LEN(netif));
+
+    /* MUST request the offered IP address */
+    options_out_len = dhcp_option(options_out_len, msg_out->options, DHCP_OPTION_REQUESTED_IP, 4);
+    options_out_len = dhcp_option_long(options_out_len, msg_out->options, lwip_ntohl(ip4_addr_get_u32(&dhcp->offered_ip_addr)));
+
+    options_out_len = dhcp_option(options_out_len, msg_out->options, DHCP_OPTION_SERVER_ID, 4);
+    options_out_len = dhcp_option_long(options_out_len, msg_out->options, lwip_ntohl(ip4_addr_get_u32(ip_2_ip4(&dhcp->server_ip_addr))));
+
+    options_out_len = dhcp_option(options_out_len, msg_out->options, DHCP_OPTION_PARAMETER_REQUEST_LIST, LWIP_ARRAYSIZE(dhcp_discover_request_options));
+    for (i = 0; i < LWIP_ARRAYSIZE(dhcp_discover_request_options); i++) {
+      options_out_len = dhcp_option_byte(options_out_len, msg_out->options, dhcp_discover_request_options[i]);
+    }
+
+#if LWIP_NETIF_HOSTNAME
+    options_out_len = dhcp_option_hostname(options_out_len, msg_out->options, netif);
+#endif /* LWIP_NETIF_HOSTNAME */
+
+    LWIP_HOOK_DHCP_APPEND_OPTIONS(netif, dhcp, DHCP_STATE_REQUESTING, msg_out, DHCP_REQUEST, &options_out_len);
+    dhcp_option_trailer(options_out_len, msg_out->options, p_out);
+
+    /* send broadcast to any DHCP server */
+    result = udp_sendto_if_src(dhcp_pcb, p_out, IP_ADDR_BROADCAST, LWIP_IANA_PORT_DHCP_SERVER, netif, IP4_ADDR_ANY);
+    pbuf_free(p_out);
+    LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_select: REQUESTING\n"));
+  } else {
+    LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_WARNING, ("dhcp_select: could not allocate DHCP request\n"));
+    result = ERR_MEM;
+  }
+  if (dhcp->tries < 255) {
+    dhcp->tries++;
+  }
+  msecs = (u16_t)((dhcp->tries < 6 ? 1 << dhcp->tries : 60) * 1000);
+  dhcp->request_timeout = (u16_t)((msecs + DHCP_FINE_TIMER_MSECS - 1) / DHCP_FINE_TIMER_MSECS);
+  LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_STATE, ("dhcp_select(): set request timeout %"U16_F" msecs\n", msecs));
+  return result;
+}
+
+/**
+ * The DHCP timer that checks for lease renewal/rebind timeouts.
+ * Must be called once a minute (see @ref DHCP_COARSE_TIMER_SECS).
+ */
+void
+dhcp_coarse_tmr(void)
+{
+  struct netif *netif;
+  LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_coarse_tmr()\n"));
+  /* iterate through all network interfaces */
+  NETIF_FOREACH(netif) {
+    /* only act on DHCP configured interfaces */
+    struct dhcp *dhcp = netif_dhcp_data(netif);
+    if ((dhcp != NULL) && (dhcp->state != DHCP_STATE_OFF)) {
+      /* compare lease time to expire timeout */
+      if (dhcp->t0_timeout && (++dhcp->lease_used == dhcp->t0_timeout)) {
+        LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_coarse_tmr(): t0 timeout\n"));
+        /* this clients' lease time has expired */
+        dhcp_release_and_stop(netif);
+        dhcp_start(netif);
+        /* timer is active (non zero), and triggers (zeroes) now? */
+      } else if (dhcp->t2_rebind_time && (dhcp->t2_rebind_time-- == 1)) {
+        LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_coarse_tmr(): t2 timeout\n"));
+        /* this clients' rebind timeout triggered */
+        dhcp_t2_timeout(netif);
+        /* timer is active (non zero), and triggers (zeroes) now */
+      } else if (dhcp->t1_renew_time && (dhcp->t1_renew_time-- == 1)) {
+        LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_coarse_tmr(): t1 timeout\n"));
+        /* this clients' renewal timeout triggered */
+        dhcp_t1_timeout(netif);
+      }
+    }
+  }
+}
+
+/**
+ * DHCP transaction timeout handling (this function must be called every 500ms,
+ * see @ref DHCP_FINE_TIMER_MSECS).
+ *
+ * A DHCP server is expected to respond within a short period of time.
+ * This timer checks whether an outstanding DHCP request is timed out.
+ */
+void
+dhcp_fine_tmr(void)
+{
+  struct netif *netif;
+  /* loop through netif's */
+  NETIF_FOREACH(netif) {
+    struct dhcp *dhcp = netif_dhcp_data(netif);
+    /* only act on DHCP configured interfaces */
+    if (dhcp != NULL) {
+      /* timer is active (non zero), and is about to trigger now */
+      if (dhcp->request_timeout > 1) {
+        dhcp->request_timeout--;
+      } else if (dhcp->request_timeout == 1) {
+        dhcp->request_timeout--;
+        /* { dhcp->request_timeout == 0 } */
+        LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_fine_tmr(): request timeout\n"));
+        /* this client's request timeout triggered */
+        dhcp_timeout(netif);
+      }
+    }
+  }
+}
+
+/**
+ * A DHCP negotiation transaction, or ARP request, has timed out.
+ *
+ * The timer that was started with the DHCP or ARP request has
+ * timed out, indicating no response was received in time.
+ *
+ * @param netif the netif under DHCP control
+ */
+static void
+dhcp_timeout(struct netif *netif)
+{
+  struct dhcp *dhcp = netif_dhcp_data(netif);
+
+  LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_timeout()\n"));
+  /* back-off period has passed, or server selection timed out */
+  if ((dhcp->state == DHCP_STATE_BACKING_OFF) || (dhcp->state == DHCP_STATE_SELECTING)) {
+    LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_timeout(): restarting discovery\n"));
+    dhcp_discover(netif);
+    /* receiving the requested lease timed out */
+  } else if (dhcp->state == DHCP_STATE_REQUESTING) {
+    LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_timeout(): REQUESTING, DHCP request timed out\n"));
+    if (dhcp->tries <= 5) {
+      dhcp_select(netif);
+    } else {
+      LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_timeout(): REQUESTING, releasing, restarting\n"));
+      dhcp_release_and_stop(netif);
+      dhcp_start(netif);
+    }
+#if DHCP_DOES_ARP_CHECK
+    /* received no ARP reply for the offered address (which is good) */
+  } else if (dhcp->state == DHCP_STATE_CHECKING) {
+    LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_timeout(): CHECKING, ARP request timed out\n"));
+    if (dhcp->tries <= 1) {
+      dhcp_check(netif);
+      /* no ARP replies on the offered address,
+         looks like the IP address is indeed free */
+    } else {
+      /* bind the interface to the offered address */
+      dhcp_bind(netif);
+    }
+#endif /* DHCP_DOES_ARP_CHECK */
+  } else if (dhcp->state == DHCP_STATE_REBOOTING) {
+    if (dhcp->tries < REBOOT_TRIES) {
+      dhcp_reboot(netif);
+    } else {
+      dhcp_discover(netif);
+    }
+  }
+}
+
+/**
+ * The renewal period has timed out.
+ *
+ * @param netif the netif under DHCP control
+ */
+static void
+dhcp_t1_timeout(struct netif *netif)
+{
+  struct dhcp *dhcp = netif_dhcp_data(netif);
+
+  LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_STATE, ("dhcp_t1_timeout()\n"));
+  if ((dhcp->state == DHCP_STATE_REQUESTING) || (dhcp->state == DHCP_STATE_BOUND) ||
+      (dhcp->state == DHCP_STATE_RENEWING)) {
+    /* just retry to renew - note that the rebind timer (t2) will
+     * eventually time-out if renew tries fail. */
+    LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE,
+                ("dhcp_t1_timeout(): must renew\n"));
+    /* This slightly different to RFC2131: DHCPREQUEST will be sent from state
+       DHCP_STATE_RENEWING, not DHCP_STATE_BOUND */
+    dhcp_renew(netif);
+    /* Calculate next timeout */
+    if (((dhcp->t2_timeout - dhcp->lease_used) / 2) >= ((60 + DHCP_COARSE_TIMER_SECS / 2) / DHCP_COARSE_TIMER_SECS)) {
+      dhcp->t1_renew_time = (u16_t)((dhcp->t2_timeout - dhcp->lease_used) / 2);
+    }
+  }
+}
+
+/**
+ * The rebind period has timed out.
+ *
+ * @param netif the netif under DHCP control
+ */
+static void
+dhcp_t2_timeout(struct netif *netif)
+{
+  struct dhcp *dhcp = netif_dhcp_data(netif);
+
+  LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_t2_timeout()\n"));
+  if ((dhcp->state == DHCP_STATE_REQUESTING) || (dhcp->state == DHCP_STATE_BOUND) ||
+      (dhcp->state == DHCP_STATE_RENEWING) || (dhcp->state == DHCP_STATE_REBINDING)) {
+    /* just retry to rebind */
+    LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE,
+                ("dhcp_t2_timeout(): must rebind\n"));
+    /* This slightly different to RFC2131: DHCPREQUEST will be sent from state
+       DHCP_STATE_REBINDING, not DHCP_STATE_BOUND */
+    dhcp_rebind(netif);
+    /* Calculate next timeout */
+    if (((dhcp->t0_timeout - dhcp->lease_used) / 2) >= ((60 + DHCP_COARSE_TIMER_SECS / 2) / DHCP_COARSE_TIMER_SECS)) {
+      dhcp->t2_rebind_time = (u16_t)((dhcp->t0_timeout - dhcp->lease_used) / 2);
+    }
+  }
+}
+
+/**
+ * Handle a DHCP ACK packet
+ *
+ * @param netif the netif under DHCP control
+ */
+static void
+dhcp_handle_ack(struct netif *netif, struct dhcp_msg *msg_in)
+{
+  struct dhcp *dhcp = netif_dhcp_data(netif);
+
+#if LWIP_DHCP_PROVIDE_DNS_SERVERS || LWIP_DHCP_GET_NTP_SRV
+  u8_t n;
+#endif /* LWIP_DHCP_PROVIDE_DNS_SERVERS || LWIP_DHCP_GET_NTP_SRV */
+#if LWIP_DHCP_GET_NTP_SRV
+  ip4_addr_t ntp_server_addrs[LWIP_DHCP_MAX_NTP_SERVERS];
+#endif
+
+  /* clear options we might not get from the ACK */
+  ip4_addr_set_zero(&dhcp->offered_sn_mask);
+  ip4_addr_set_zero(&dhcp->offered_gw_addr);
+#if LWIP_DHCP_BOOTP_FILE
+  ip4_addr_set_zero(&dhcp->offered_si_addr);
+#endif /* LWIP_DHCP_BOOTP_FILE */
+
+  /* lease time given? */
+  if (dhcp_option_given(dhcp, DHCP_OPTION_IDX_LEASE_TIME)) {
+    /* remember offered lease time */
+    dhcp->offered_t0_lease = dhcp_get_option_value(dhcp, DHCP_OPTION_IDX_LEASE_TIME);
+  }
+  /* renewal period given? */
+  if (dhcp_option_given(dhcp, DHCP_OPTION_IDX_T1)) {
+    /* remember given renewal period */
+    dhcp->offered_t1_renew = dhcp_get_option_value(dhcp, DHCP_OPTION_IDX_T1);
+  } else {
+    /* calculate safe periods for renewal */
+    dhcp->offered_t1_renew = dhcp->offered_t0_lease / 2;
+  }
+
+  /* renewal period given? */
+  if (dhcp_option_given(dhcp, DHCP_OPTION_IDX_T2)) {
+    /* remember given rebind period */
+    dhcp->offered_t2_rebind = dhcp_get_option_value(dhcp, DHCP_OPTION_IDX_T2);
+  } else {
+    /* calculate safe periods for rebinding (offered_t0_lease * 0.875 -> 87.5%)*/
+    dhcp->offered_t2_rebind = (dhcp->offered_t0_lease * 7U) / 8U;
+  }
+
+  /* (y)our internet address */
+  ip4_addr_copy(dhcp->offered_ip_addr, msg_in->yiaddr);
+
+#if LWIP_DHCP_BOOTP_FILE
+  /* copy boot server address,
+     boot file name copied in dhcp_parse_reply if not overloaded */
+  ip4_addr_copy(dhcp->offered_si_addr, msg_in->siaddr);
+#endif /* LWIP_DHCP_BOOTP_FILE */
+
+  /* subnet mask given? */
+  if (dhcp_option_given(dhcp, DHCP_OPTION_IDX_SUBNET_MASK)) {
+    /* remember given subnet mask */
+    ip4_addr_set_u32(&dhcp->offered_sn_mask, lwip_htonl(dhcp_get_option_value(dhcp, DHCP_OPTION_IDX_SUBNET_MASK)));
+    dhcp->subnet_mask_given = 1;
+  } else {
+    dhcp->subnet_mask_given = 0;
+  }
+
+  /* gateway router */
+  if (dhcp_option_given(dhcp, DHCP_OPTION_IDX_ROUTER)) {
+    ip4_addr_set_u32(&dhcp->offered_gw_addr, lwip_htonl(dhcp_get_option_value(dhcp, DHCP_OPTION_IDX_ROUTER)));
+  }
+
+#if LWIP_DHCP_GET_NTP_SRV
+  /* NTP servers */
+  for (n = 0; (n < LWIP_DHCP_MAX_NTP_SERVERS) && dhcp_option_given(dhcp, DHCP_OPTION_IDX_NTP_SERVER + n); n++) {
+    ip4_addr_set_u32(&ntp_server_addrs[n], lwip_htonl(dhcp_get_option_value(dhcp, DHCP_OPTION_IDX_NTP_SERVER + n)));
+  }
+  dhcp_set_ntp_servers(n, ntp_server_addrs);
+#endif /* LWIP_DHCP_GET_NTP_SRV */
+
+#if LWIP_DHCP_PROVIDE_DNS_SERVERS
+  /* DNS servers */
+  for (n = 0; (n < LWIP_DHCP_PROVIDE_DNS_SERVERS) && dhcp_option_given(dhcp, DHCP_OPTION_IDX_DNS_SERVER + n); n++) {
+    ip_addr_t dns_addr;
+    ip_addr_set_ip4_u32_val(dns_addr, lwip_htonl(dhcp_get_option_value(dhcp, DHCP_OPTION_IDX_DNS_SERVER + n)));
+    dns_setserver(n, &dns_addr);
+  }
+#endif /* LWIP_DHCP_PROVIDE_DNS_SERVERS */
+}
+
+/**
+ * @ingroup dhcp4
+ * Set a statically allocated struct dhcp to work with.
+ * Using this prevents dhcp_start to allocate it using mem_malloc.
+ *
+ * @param netif the netif for which to set the struct dhcp
+ * @param dhcp (uninitialised) dhcp struct allocated by the application
+ */
+void
+dhcp_set_struct(struct netif *netif, struct dhcp *dhcp)
+{
+  LWIP_ASSERT_CORE_LOCKED();
+  LWIP_ASSERT("netif != NULL", netif != NULL);
+  LWIP_ASSERT("dhcp != NULL", dhcp != NULL);
+  LWIP_ASSERT("netif already has a struct dhcp set", netif_dhcp_data(netif) == NULL);
+
+  /* clear data structure */
+  memset(dhcp, 0, sizeof(struct dhcp));
+  /* dhcp_set_state(&dhcp, DHCP_STATE_OFF); */
+  netif_set_client_data(netif, LWIP_NETIF_CLIENT_DATA_INDEX_DHCP, dhcp);
+}
+
+/**
+ * @ingroup dhcp4
+ * Removes a struct dhcp from a netif.
+ *
+ * ATTENTION: Only use this when not using dhcp_set_struct() to allocate the
+ *            struct dhcp since the memory is passed back to the heap.
+ *
+ * @param netif the netif from which to remove the struct dhcp
+ */
+void dhcp_cleanup(struct netif *netif)
+{
+  LWIP_ASSERT_CORE_LOCKED();
+  LWIP_ASSERT("netif != NULL", netif != NULL);
+
+  if (netif_dhcp_data(netif) != NULL) {
+    mem_free(netif_dhcp_data(netif));
+    netif_set_client_data(netif, LWIP_NETIF_CLIENT_DATA_INDEX_DHCP, NULL);
+  }
+}
+
+/**
+ * @ingroup dhcp4
+ * Start DHCP negotiation for a network interface.
+ *
+ * If no DHCP client instance was attached to this interface,
+ * a new client is created first. If a DHCP client instance
+ * was already present, it restarts negotiation.
+ *
+ * @param netif The lwIP network interface
+ * @return lwIP error code
+ * - ERR_OK - No error
+ * - ERR_MEM - Out of memory
+ */
+err_t
+dhcp_start(struct netif *netif)
+{
+  struct dhcp *dhcp;
+  err_t result;
+
+  LWIP_ASSERT_CORE_LOCKED();
+  LWIP_ERROR("netif != NULL", (netif != NULL), return ERR_ARG;);
+  LWIP_ERROR("netif is not up, old style port?", netif_is_up(netif), return ERR_ARG;);
+  dhcp = netif_dhcp_data(netif);
+  LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_start(netif=%p) %c%c%"U16_F"\n", (void *)netif, netif->name[0], netif->name[1], (u16_t)netif->num));
+
+  /* check MTU of the netif */
+  if (netif->mtu < DHCP_MAX_MSG_LEN_MIN_REQUIRED) {
+    LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_start(): Cannot use this netif with DHCP: MTU is too small\n"));
+    return ERR_MEM;
+  }
+
+  /* no DHCP client attached yet? */
+  if (dhcp == NULL) {
+    LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_start(): mallocing new DHCP client\n"));
+    dhcp = (struct dhcp *)mem_malloc(sizeof(struct dhcp));
+    if (dhcp == NULL) {
+      LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_start(): could not allocate dhcp\n"));
+      return ERR_MEM;
+    }
+
+    /* store this dhcp client in the netif */
+    netif_set_client_data(netif, LWIP_NETIF_CLIENT_DATA_INDEX_DHCP, dhcp);
+    LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_start(): allocated dhcp"));
+    /* already has DHCP client attached */
+  } else {
+    LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_start(): restarting DHCP configuration\n"));
+
+    if (dhcp->pcb_allocated != 0) {
+      dhcp_dec_pcb_refcount(); /* free DHCP PCB if not needed any more */
+    }
+    /* dhcp is cleared below, no need to reset flag*/
+  }
+
+  /* clear data structure */
+  memset(dhcp, 0, sizeof(struct dhcp));
+  /* dhcp_set_state(&dhcp, DHCP_STATE_OFF); */
+
+  LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_start(): starting DHCP configuration\n"));
+
+  if (dhcp_inc_pcb_refcount() != ERR_OK) { /* ensure DHCP PCB is allocated */
+    return ERR_MEM;
+  }
+  dhcp->pcb_allocated = 1;
+
+  if (!netif_is_link_up(netif)) {
+    /* set state INIT and wait for dhcp_network_changed() to call dhcp_discover() */
+    dhcp_set_state(dhcp, DHCP_STATE_INIT);
+    return ERR_OK;
+  }
+
+  /* (re)start the DHCP negotiation */
+  result = dhcp_discover(netif);
+  if (result != ERR_OK) {
+    /* free resources allocated above */
+    dhcp_release_and_stop(netif);
+    return ERR_MEM;
+  }
+  return result;
+}
+
+/**
+ * @ingroup dhcp4
+ * Inform a DHCP server of our manual configuration.
+ *
+ * This informs DHCP servers of our fixed IP address configuration
+ * by sending an INFORM message. It does not involve DHCP address
+ * configuration, it is just here to be nice to the network.
+ *
+ * @param netif The lwIP network interface
+ */
+void
+dhcp_inform(struct netif *netif)
+{
+  struct dhcp dhcp;
+  struct pbuf *p_out;
+  u16_t options_out_len;
+
+  LWIP_ASSERT_CORE_LOCKED();
+  LWIP_ERROR("netif != NULL", (netif != NULL), return;);
+
+  if (dhcp_inc_pcb_refcount() != ERR_OK) { /* ensure DHCP PCB is allocated */
+    return;
+  }
+
+  memset(&dhcp, 0, sizeof(struct dhcp));
+  dhcp_set_state(&dhcp, DHCP_STATE_INFORMING);
+
+  /* create and initialize the DHCP message header */
+  p_out = dhcp_create_msg(netif, &dhcp, DHCP_INFORM, &options_out_len);
+  if (p_out != NULL) {
+    struct dhcp_msg *msg_out = (struct dhcp_msg *)p_out->payload;
+    options_out_len = dhcp_option(options_out_len, msg_out->options, DHCP_OPTION_MAX_MSG_SIZE, DHCP_OPTION_MAX_MSG_SIZE_LEN);
+    options_out_len = dhcp_option_short(options_out_len, msg_out->options, DHCP_MAX_MSG_LEN(netif));
+
+    LWIP_HOOK_DHCP_APPEND_OPTIONS(netif, &dhcp, DHCP_STATE_INFORMING, msg_out, DHCP_INFORM, &options_out_len);
+    dhcp_option_trailer(options_out_len, msg_out->options, p_out);
+
+    LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_inform: INFORMING\n"));
+
+    udp_sendto_if(dhcp_pcb, p_out, IP_ADDR_BROADCAST, LWIP_IANA_PORT_DHCP_SERVER, netif);
+
+    pbuf_free(p_out);
+  } else {
+    LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS, ("dhcp_inform: could not allocate DHCP request\n"));
+  }
+
+  dhcp_dec_pcb_refcount(); /* delete DHCP PCB if not needed any more */
+}
+
+/** Handle a possible change in the network configuration.
+ *
+ * This enters the REBOOTING state to verify that the currently bound
+ * address is still valid.
+ */
+void
+dhcp_network_changed(struct netif *netif)
+{
+  struct dhcp *dhcp = netif_dhcp_data(netif);
+
+  if (!dhcp) {
+    return;
+  }
+  switch (dhcp->state) {
+    case DHCP_STATE_REBINDING:
+    case DHCP_STATE_RENEWING:
+    case DHCP_STATE_BOUND:
+    case DHCP_STATE_REBOOTING:
+      dhcp->tries = 0;
+      dhcp_reboot(netif);
+      break;
+    case DHCP_STATE_OFF:
+      /* stay off */
+      break;
+    default:
+      LWIP_ASSERT("invalid dhcp->state", dhcp->state <= DHCP_STATE_BACKING_OFF);
+      /* INIT/REQUESTING/CHECKING/BACKING_OFF restart with new 'rid' because the
+         state changes, SELECTING: continue with current 'rid' as we stay in the
+         same state */
+#if LWIP_DHCP_AUTOIP_COOP
+      if (dhcp->autoip_coop_state == DHCP_AUTOIP_COOP_STATE_ON) {
+        autoip_stop(netif);
+        dhcp->autoip_coop_state = DHCP_AUTOIP_COOP_STATE_OFF;
+      }
+#endif /* LWIP_DHCP_AUTOIP_COOP */
+      /* ensure we start with short timeouts, even if already discovering */
+      dhcp->tries = 0;
+      dhcp_discover(netif);
+      break;
+  }
+}
+
+#if DHCP_DOES_ARP_CHECK
+/**
+ * Match an ARP reply with the offered IP address:
+ * check whether the offered IP address is not in use using ARP
+ *
+ * @param netif the network interface on which the reply was received
+ * @param addr The IP address we received a reply from
+ */
+void
+dhcp_arp_reply(struct netif *netif, const ip4_addr_t *addr)
+{
+  struct dhcp *dhcp;
+
+  LWIP_ERROR("netif != NULL", (netif != NULL), return;);
+  dhcp = netif_dhcp_data(netif);
+  LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_arp_reply()\n"));
+  /* is a DHCP client doing an ARP check? */
+  if ((dhcp != NULL) && (dhcp->state == DHCP_STATE_CHECKING)) {
+    LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_arp_reply(): CHECKING, arp reply for 0x%08"X32_F"\n",
+                ip4_addr_get_u32(addr)));
+    /* did a host respond with the address we
+       were offered by the DHCP server? */
+    if (ip4_addr_cmp(addr, &dhcp->offered_ip_addr)) {
+      /* we will not accept the offered address */
+      LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE | LWIP_DBG_LEVEL_WARNING,
+                  ("dhcp_arp_reply(): arp reply matched with offered address, declining\n"));
+      dhcp_decline(netif);
+    }
+  }
+}
+
+/**
+ * Decline an offered lease.
+ *
+ * Tell the DHCP server we do not accept the offered address.
+ * One reason to decline the lease is when we find out the address
+ * is already in use by another host (through ARP).
+ *
+ * @param netif the netif under DHCP control
+ */
+static err_t
+dhcp_decline(struct netif *netif)
+{
+  struct dhcp *dhcp = netif_dhcp_data(netif);
+  err_t result;
+  u16_t msecs;
+  struct pbuf *p_out;
+  u16_t options_out_len;
+
+  LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_decline()\n"));
+  dhcp_set_state(dhcp, DHCP_STATE_BACKING_OFF);
+  /* create and initialize the DHCP message header */
+  p_out = dhcp_create_msg(netif, dhcp, DHCP_DECLINE, &options_out_len);
+  if (p_out != NULL) {
+    struct dhcp_msg *msg_out = (struct dhcp_msg *)p_out->payload;
+    options_out_len = dhcp_option(options_out_len, msg_out->options, DHCP_OPTION_REQUESTED_IP, 4);
+    options_out_len = dhcp_option_long(options_out_len, msg_out->options, lwip_ntohl(ip4_addr_get_u32(&dhcp->offered_ip_addr)));
+
+    LWIP_HOOK_DHCP_APPEND_OPTIONS(netif, dhcp, DHCP_STATE_BACKING_OFF, msg_out, DHCP_DECLINE, &options_out_len);
+    dhcp_option_trailer(options_out_len, msg_out->options, p_out);
+
+    /* per section 4.4.4, broadcast DECLINE messages */
+    result = udp_sendto_if_src(dhcp_pcb, p_out, IP_ADDR_BROADCAST, LWIP_IANA_PORT_DHCP_SERVER, netif, IP4_ADDR_ANY);
+    pbuf_free(p_out);
+    LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_decline: BACKING OFF\n"));
+  } else {
+    LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS,
+                ("dhcp_decline: could not allocate DHCP request\n"));
+    result = ERR_MEM;
+  }
+  if (dhcp->tries < 255) {
+    dhcp->tries++;
+  }
+  msecs = 10 * 1000;
+  dhcp->request_timeout = (u16_t)((msecs + DHCP_FINE_TIMER_MSECS - 1) / DHCP_FINE_TIMER_MSECS);
+  LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_decline(): set request timeout %"U16_F" msecs\n", msecs));
+  return result;
+}
+#endif /* DHCP_DOES_ARP_CHECK */
+
+
+/**
+ * Start the DHCP process, discover a DHCP server.
+ *
+ * @param netif the netif under DHCP control
+ */
+static err_t
+dhcp_discover(struct netif *netif)
+{
+  struct dhcp *dhcp = netif_dhcp_data(netif);
+  err_t result = ERR_OK;
+  u16_t msecs;
+  u8_t i;
+  struct pbuf *p_out;
+  u16_t options_out_len;
+
+  LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_discover()\n"));
+
+  ip4_addr_set_any(&dhcp->offered_ip_addr);
+  dhcp_set_state(dhcp, DHCP_STATE_SELECTING);
+  /* create and initialize the DHCP message header */
+  p_out = dhcp_create_msg(netif, dhcp, DHCP_DISCOVER, &options_out_len);
+  if (p_out != NULL) {
+    struct dhcp_msg *msg_out = (struct dhcp_msg *)p_out->payload;
+    LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_discover: making request\n"));
+
+    options_out_len = dhcp_option(options_out_len, msg_out->options, DHCP_OPTION_MAX_MSG_SIZE, DHCP_OPTION_MAX_MSG_SIZE_LEN);
+    options_out_len = dhcp_option_short(options_out_len, msg_out->options, DHCP_MAX_MSG_LEN(netif));
+
+    options_out_len = dhcp_option(options_out_len, msg_out->options, DHCP_OPTION_PARAMETER_REQUEST_LIST, LWIP_ARRAYSIZE(dhcp_discover_request_options));
+    for (i = 0; i < LWIP_ARRAYSIZE(dhcp_discover_request_options); i++) {
+      options_out_len = dhcp_option_byte(options_out_len, msg_out->options, dhcp_discover_request_options[i]);
+    }
+    LWIP_HOOK_DHCP_APPEND_OPTIONS(netif, dhcp, DHCP_STATE_SELECTING, msg_out, DHCP_DISCOVER, &options_out_len);
+    dhcp_option_trailer(options_out_len, msg_out->options, p_out);
+
+    LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_discover: sendto(DISCOVER, IP_ADDR_BROADCAST, LWIP_IANA_PORT_DHCP_SERVER)\n"));
+    udp_sendto_if_src(dhcp_pcb, p_out, IP_ADDR_BROADCAST, LWIP_IANA_PORT_DHCP_SERVER, netif, IP4_ADDR_ANY);
+    LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_discover: deleting()ing\n"));
+    pbuf_free(p_out);
+    LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_discover: SELECTING\n"));
+  } else {
+    LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS, ("dhcp_discover: could not allocate DHCP request\n"));
+  }
+  if (dhcp->tries < 255) {
+    dhcp->tries++;
+  }
+#if LWIP_DHCP_AUTOIP_COOP
+  if (dhcp->tries >= LWIP_DHCP_AUTOIP_COOP_TRIES && dhcp->autoip_coop_state == DHCP_AUTOIP_COOP_STATE_OFF) {
+    dhcp->autoip_coop_state = DHCP_AUTOIP_COOP_STATE_ON;
+    autoip_start(netif);
+  }
+#endif /* LWIP_DHCP_AUTOIP_COOP */
+  msecs = (u16_t)((dhcp->tries < 6 ? 1 << dhcp->tries : 60) * 1000);
+  dhcp->request_timeout = (u16_t)((msecs + DHCP_FINE_TIMER_MSECS - 1) / DHCP_FINE_TIMER_MSECS);
+  LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_discover(): set request timeout %"U16_F" msecs\n", msecs));
+  return result;
+}
+
+
+/**
+ * Bind the interface to the offered IP address.
+ *
+ * @param netif network interface to bind to the offered address
+ */
+static void
+dhcp_bind(struct netif *netif)
+{
+  u32_t timeout;
+  struct dhcp *dhcp;
+  ip4_addr_t sn_mask, gw_addr;
+  LWIP_ERROR("dhcp_bind: netif != NULL", (netif != NULL), return;);
+  dhcp = netif_dhcp_data(netif);
+  LWIP_ERROR("dhcp_bind: dhcp != NULL", (dhcp != NULL), return;);
+  LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_bind(netif=%p) %c%c%"U16_F"\n", (void *)netif, netif->name[0], netif->name[1], (u16_t)netif->num));
+
+  /* reset time used of lease */
+  dhcp->lease_used = 0;
+
+  if (dhcp->offered_t0_lease != 0xffffffffUL) {
+    /* set renewal period timer */
+    LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_bind(): t0 renewal timer %"U32_F" secs\n", dhcp->offered_t0_lease));
+    timeout = (dhcp->offered_t0_lease + DHCP_COARSE_TIMER_SECS / 2) / DHCP_COARSE_TIMER_SECS;
+    if (timeout > 0xffff) {
+      timeout = 0xffff;
+    }
+    dhcp->t0_timeout = (u16_t)timeout;
+    if (dhcp->t0_timeout == 0) {
+      dhcp->t0_timeout = 1;
+    }
+    LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_bind(): set request timeout %"U32_F" msecs\n", dhcp->offered_t0_lease * 1000));
+  }
+
+  /* temporary DHCP lease? */
+  if (dhcp->offered_t1_renew != 0xffffffffUL) {
+    /* set renewal period timer */
+    LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_bind(): t1 renewal timer %"U32_F" secs\n", dhcp->offered_t1_renew));
+    timeout = (dhcp->offered_t1_renew + DHCP_COARSE_TIMER_SECS / 2) / DHCP_COARSE_TIMER_SECS;
+    if (timeout > 0xffff) {
+      timeout = 0xffff;
+    }
+    dhcp->t1_timeout = (u16_t)timeout;
+    if (dhcp->t1_timeout == 0) {
+      dhcp->t1_timeout = 1;
+    }
+    LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_bind(): set request timeout %"U32_F" msecs\n", dhcp->offered_t1_renew * 1000));
+    dhcp->t1_renew_time = dhcp->t1_timeout;
+  }
+  /* set renewal period timer */
+  if (dhcp->offered_t2_rebind != 0xffffffffUL) {
+    LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_bind(): t2 rebind timer %"U32_F" secs\n", dhcp->offered_t2_rebind));
+    timeout = (dhcp->offered_t2_rebind + DHCP_COARSE_TIMER_SECS / 2) / DHCP_COARSE_TIMER_SECS;
+    if (timeout > 0xffff) {
+      timeout = 0xffff;
+    }
+    dhcp->t2_timeout = (u16_t)timeout;
+    if (dhcp->t2_timeout == 0) {
+      dhcp->t2_timeout = 1;
+    }
+    LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_bind(): set request timeout %"U32_F" msecs\n", dhcp->offered_t2_rebind * 1000));
+    dhcp->t2_rebind_time = dhcp->t2_timeout;
+  }
+
+  /* If we have sub 1 minute lease, t2 and t1 will kick in at the same time. */
+  if ((dhcp->t1_timeout >= dhcp->t2_timeout) && (dhcp->t2_timeout > 0)) {
+    dhcp->t1_timeout = 0;
+  }
+
+  if (dhcp->subnet_mask_given) {
+    /* copy offered network mask */
+    ip4_addr_copy(sn_mask, dhcp->offered_sn_mask);
+  } else {
+    /* subnet mask not given, choose a safe subnet mask given the network class */
+    u8_t first_octet = ip4_addr1(&dhcp->offered_ip_addr);
+    if (first_octet <= 127) {
+      ip4_addr_set_u32(&sn_mask, PP_HTONL(0xff000000UL));
+    } else if (first_octet >= 192) {
+      ip4_addr_set_u32(&sn_mask, PP_HTONL(0xffffff00UL));
+    } else {
+      ip4_addr_set_u32(&sn_mask, PP_HTONL(0xffff0000UL));
+    }
+  }
+
+  ip4_addr_copy(gw_addr, dhcp->offered_gw_addr);
+  /* gateway address not given? */
+  if (ip4_addr_isany_val(gw_addr)) {
+    /* copy network address */
+    ip4_addr_get_network(&gw_addr, &dhcp->offered_ip_addr, &sn_mask);
+    /* use first host address on network as gateway */
+    ip4_addr_set_u32(&gw_addr, ip4_addr_get_u32(&gw_addr) | PP_HTONL(0x00000001UL));
+  }
+
+#if LWIP_DHCP_AUTOIP_COOP
+  if (dhcp->autoip_coop_state == DHCP_AUTOIP_COOP_STATE_ON) {
+    autoip_stop(netif);
+    dhcp->autoip_coop_state = DHCP_AUTOIP_COOP_STATE_OFF;
+  }
+#endif /* LWIP_DHCP_AUTOIP_COOP */
+
+  LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_STATE, ("dhcp_bind(): IP: 0x%08"X32_F" SN: 0x%08"X32_F" GW: 0x%08"X32_F"\n",
+              ip4_addr_get_u32(&dhcp->offered_ip_addr), ip4_addr_get_u32(&sn_mask), ip4_addr_get_u32(&gw_addr)));
+  /* netif is now bound to DHCP leased address - set this before assigning the address
+     to ensure the callback can use dhcp_supplied_address() */
+  dhcp_set_state(dhcp, DHCP_STATE_BOUND);
+
+  netif_set_addr(netif, &dhcp->offered_ip_addr, &sn_mask, &gw_addr);
+  /* interface is used by routing now that an address is set */
+}
+
+/**
+ * @ingroup dhcp4
+ * Renew an existing DHCP lease at the involved DHCP server.
+ *
+ * @param netif network interface which must renew its lease
+ */
+err_t
+dhcp_renew(struct netif *netif)
+{
+  struct dhcp *dhcp = netif_dhcp_data(netif);
+  err_t result;
+  u16_t msecs;
+  u8_t i;
+  struct pbuf *p_out;
+  u16_t options_out_len;
+
+  LWIP_ASSERT_CORE_LOCKED();
+  LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_renew()\n"));
+  dhcp_set_state(dhcp, DHCP_STATE_RENEWING);
+
+  /* create and initialize the DHCP message header */
+  p_out = dhcp_create_msg(netif, dhcp, DHCP_REQUEST, &options_out_len);
+  if (p_out != NULL) {
+    struct dhcp_msg *msg_out = (struct dhcp_msg *)p_out->payload;
+    options_out_len = dhcp_option(options_out_len, msg_out->options, DHCP_OPTION_MAX_MSG_SIZE, DHCP_OPTION_MAX_MSG_SIZE_LEN);
+    options_out_len = dhcp_option_short(options_out_len, msg_out->options, DHCP_MAX_MSG_LEN(netif));
+
+    options_out_len = dhcp_option(options_out_len, msg_out->options, DHCP_OPTION_PARAMETER_REQUEST_LIST, LWIP_ARRAYSIZE(dhcp_discover_request_options));
+    for (i = 0; i < LWIP_ARRAYSIZE(dhcp_discover_request_options); i++) {
+      options_out_len = dhcp_option_byte(options_out_len, msg_out->options, dhcp_discover_request_options[i]);
+    }
+
+#if LWIP_NETIF_HOSTNAME
+    options_out_len = dhcp_option_hostname(options_out_len, msg_out->options, netif);
+#endif /* LWIP_NETIF_HOSTNAME */
+
+    LWIP_HOOK_DHCP_APPEND_OPTIONS(netif, dhcp, DHCP_STATE_RENEWING, msg_out, DHCP_REQUEST, &options_out_len);
+    dhcp_option_trailer(options_out_len, msg_out->options, p_out);
+
+    result = udp_sendto_if(dhcp_pcb, p_out, &dhcp->server_ip_addr, LWIP_IANA_PORT_DHCP_SERVER, netif);
+    pbuf_free(p_out);
+
+    LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_renew: RENEWING\n"));
+  } else {
+    LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS, ("dhcp_renew: could not allocate DHCP request\n"));
+    result = ERR_MEM;
+  }
+  if (dhcp->tries < 255) {
+    dhcp->tries++;
+  }
+  /* back-off on retries, but to a maximum of 20 seconds */
+  msecs = (u16_t)(dhcp->tries < 10 ? dhcp->tries * 2000 : 20 * 1000);
+  dhcp->request_timeout = (u16_t)((msecs + DHCP_FINE_TIMER_MSECS - 1) / DHCP_FINE_TIMER_MSECS);
+  LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_renew(): set request timeout %"U16_F" msecs\n", msecs));
+  return result;
+}
+
+/**
+ * Rebind with a DHCP server for an existing DHCP lease.
+ *
+ * @param netif network interface which must rebind with a DHCP server
+ */
+static err_t
+dhcp_rebind(struct netif *netif)
+{
+  struct dhcp *dhcp = netif_dhcp_data(netif);
+  err_t result;
+  u16_t msecs;
+  u8_t i;
+  struct pbuf *p_out;
+  u16_t options_out_len;
+
+  LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_rebind()\n"));
+  dhcp_set_state(dhcp, DHCP_STATE_REBINDING);
+
+  /* create and initialize the DHCP message header */
+  p_out = dhcp_create_msg(netif, dhcp, DHCP_REQUEST, &options_out_len);
+  if (p_out != NULL) {
+    struct dhcp_msg *msg_out = (struct dhcp_msg *)p_out->payload;
+    options_out_len = dhcp_option(options_out_len, msg_out->options, DHCP_OPTION_MAX_MSG_SIZE, DHCP_OPTION_MAX_MSG_SIZE_LEN);
+    options_out_len = dhcp_option_short(options_out_len, msg_out->options, DHCP_MAX_MSG_LEN(netif));
+
+    options_out_len = dhcp_option(options_out_len, msg_out->options, DHCP_OPTION_PARAMETER_REQUEST_LIST, LWIP_ARRAYSIZE(dhcp_discover_request_options));
+    for (i = 0; i < LWIP_ARRAYSIZE(dhcp_discover_request_options); i++) {
+      options_out_len = dhcp_option_byte(options_out_len, msg_out->options, dhcp_discover_request_options[i]);
+    }
+
+#if LWIP_NETIF_HOSTNAME
+    options_out_len = dhcp_option_hostname(options_out_len, msg_out->options, netif);
+#endif /* LWIP_NETIF_HOSTNAME */
+
+    LWIP_HOOK_DHCP_APPEND_OPTIONS(netif, dhcp, DHCP_STATE_REBINDING, msg_out, DHCP_DISCOVER, &options_out_len);
+    dhcp_option_trailer(options_out_len, msg_out->options, p_out);
+
+    /* broadcast to server */
+    result = udp_sendto_if(dhcp_pcb, p_out, IP_ADDR_BROADCAST, LWIP_IANA_PORT_DHCP_SERVER, netif);
+    pbuf_free(p_out);
+    LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_rebind: REBINDING\n"));
+  } else {
+    LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS, ("dhcp_rebind: could not allocate DHCP request\n"));
+    result = ERR_MEM;
+  }
+  if (dhcp->tries < 255) {
+    dhcp->tries++;
+  }
+  msecs = (u16_t)(dhcp->tries < 10 ? dhcp->tries * 1000 : 10 * 1000);
+  dhcp->request_timeout = (u16_t)((msecs + DHCP_FINE_TIMER_MSECS - 1) / DHCP_FINE_TIMER_MSECS);
+  LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_rebind(): set request timeout %"U16_F" msecs\n", msecs));
+  return result;
+}
+
+/**
+ * Enter REBOOTING state to verify an existing lease
+ *
+ * @param netif network interface which must reboot
+ */
+static err_t
+dhcp_reboot(struct netif *netif)
+{
+  struct dhcp *dhcp = netif_dhcp_data(netif);
+  err_t result;
+  u16_t msecs;
+  u8_t i;
+  struct pbuf *p_out;
+  u16_t options_out_len;
+
+  LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_reboot()\n"));
+  dhcp_set_state(dhcp, DHCP_STATE_REBOOTING);
+
+  /* create and initialize the DHCP message header */
+  p_out = dhcp_create_msg(netif, dhcp, DHCP_REQUEST, &options_out_len);
+  if (p_out != NULL) {
+    struct dhcp_msg *msg_out = (struct dhcp_msg *)p_out->payload;
+    options_out_len = dhcp_option(options_out_len, msg_out->options, DHCP_OPTION_MAX_MSG_SIZE, DHCP_OPTION_MAX_MSG_SIZE_LEN);
+    options_out_len = dhcp_option_short(options_out_len, msg_out->options, DHCP_MAX_MSG_LEN_MIN_REQUIRED);
+
+    options_out_len = dhcp_option(options_out_len, msg_out->options, DHCP_OPTION_REQUESTED_IP, 4);
+    options_out_len = dhcp_option_long(options_out_len, msg_out->options, lwip_ntohl(ip4_addr_get_u32(&dhcp->offered_ip_addr)));
+
+    options_out_len = dhcp_option(options_out_len, msg_out->options, DHCP_OPTION_PARAMETER_REQUEST_LIST, LWIP_ARRAYSIZE(dhcp_discover_request_options));
+    for (i = 0; i < LWIP_ARRAYSIZE(dhcp_discover_request_options); i++) {
+      options_out_len = dhcp_option_byte(options_out_len, msg_out->options, dhcp_discover_request_options[i]);
+    }
+
+#if LWIP_NETIF_HOSTNAME
+    options_out_len = dhcp_option_hostname(options_out_len, msg_out->options, netif);
+#endif /* LWIP_NETIF_HOSTNAME */
+
+    LWIP_HOOK_DHCP_APPEND_OPTIONS(netif, dhcp, DHCP_STATE_REBOOTING, msg_out, DHCP_REQUEST, &options_out_len);
+    dhcp_option_trailer(options_out_len, msg_out->options, p_out);
+
+    /* broadcast to server */
+    result = udp_sendto_if(dhcp_pcb, p_out, IP_ADDR_BROADCAST, LWIP_IANA_PORT_DHCP_SERVER, netif);
+    pbuf_free(p_out);
+    LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_reboot: REBOOTING\n"));
+  } else {
+    LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS, ("dhcp_reboot: could not allocate DHCP request\n"));
+    result = ERR_MEM;
+  }
+  if (dhcp->tries < 255) {
+    dhcp->tries++;
+  }
+  msecs = (u16_t)(dhcp->tries < 10 ? dhcp->tries * 1000 : 10 * 1000);
+  dhcp->request_timeout = (u16_t)((msecs + DHCP_FINE_TIMER_MSECS - 1) / DHCP_FINE_TIMER_MSECS);
+  LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_reboot(): set request timeout %"U16_F" msecs\n", msecs));
+  return result;
+}
+
+/**
+ * @ingroup dhcp4
+ * Release a DHCP lease and stop DHCP statemachine (and AUTOIP if LWIP_DHCP_AUTOIP_COOP).
+ *
+ * @param netif network interface
+ */
+void
+dhcp_release_and_stop(struct netif *netif)
+{
+  struct dhcp *dhcp = netif_dhcp_data(netif);
+  ip_addr_t server_ip_addr;
+
+  LWIP_ASSERT_CORE_LOCKED();
+  LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_release_and_stop()\n"));
+  if (dhcp == NULL) {
+    return;
+  }
+
+  /* already off? -> nothing to do */
+  if (dhcp->state == DHCP_STATE_OFF) {
+    return;
+  }
+
+  ip_addr_copy(server_ip_addr, dhcp->server_ip_addr);
+
+  /* clean old DHCP offer */
+  ip_addr_set_zero_ip4(&dhcp->server_ip_addr);
+  ip4_addr_set_zero(&dhcp->offered_ip_addr);
+  ip4_addr_set_zero(&dhcp->offered_sn_mask);
+  ip4_addr_set_zero(&dhcp->offered_gw_addr);
+#if LWIP_DHCP_BOOTP_FILE
+  ip4_addr_set_zero(&dhcp->offered_si_addr);
+#endif /* LWIP_DHCP_BOOTP_FILE */
+  dhcp->offered_t0_lease = dhcp->offered_t1_renew = dhcp->offered_t2_rebind = 0;
+  dhcp->t1_renew_time = dhcp->t2_rebind_time = dhcp->lease_used = dhcp->t0_timeout = 0;
+
+  /* send release message when current IP was assigned via DHCP */
+  if (dhcp_supplied_address(netif)) {
+    /* create and initialize the DHCP message header */
+    struct pbuf *p_out;
+    u16_t options_out_len;
+    p_out = dhcp_create_msg(netif, dhcp, DHCP_RELEASE, &options_out_len);
+    if (p_out != NULL) {
+      struct dhcp_msg *msg_out = (struct dhcp_msg *)p_out->payload;
+      options_out_len = dhcp_option(options_out_len, msg_out->options, DHCP_OPTION_SERVER_ID, 4);
+      options_out_len = dhcp_option_long(options_out_len, msg_out->options, lwip_ntohl(ip4_addr_get_u32(ip_2_ip4(&server_ip_addr))));
+
+      LWIP_HOOK_DHCP_APPEND_OPTIONS(netif, dhcp, dhcp->state, msg_out, DHCP_RELEASE, &options_out_len);
+      dhcp_option_trailer(options_out_len, msg_out->options, p_out);
+
+      udp_sendto_if(dhcp_pcb, p_out, &server_ip_addr, LWIP_IANA_PORT_DHCP_SERVER, netif);
+      pbuf_free(p_out);
+      LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_release: RELEASED, DHCP_STATE_OFF\n"));
+    } else {
+      /* sending release failed, but that's not a problem since the correct behaviour of dhcp does not rely on release */
+      LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS, ("dhcp_release: could not allocate DHCP request\n"));
+    }
+  }
+
+  /* remove IP address from interface (prevents routing from selecting this interface) */
+  netif_set_addr(netif, IP4_ADDR_ANY4, IP4_ADDR_ANY4, IP4_ADDR_ANY4);
+
+#if LWIP_DHCP_AUTOIP_COOP
+  if (dhcp->autoip_coop_state == DHCP_AUTOIP_COOP_STATE_ON) {
+    autoip_stop(netif);
+    dhcp->autoip_coop_state = DHCP_AUTOIP_COOP_STATE_OFF;
+  }
+#endif /* LWIP_DHCP_AUTOIP_COOP */
+
+  dhcp_set_state(dhcp, DHCP_STATE_OFF);
+
+  if (dhcp->pcb_allocated != 0) {
+    dhcp_dec_pcb_refcount(); /* free DHCP PCB if not needed any more */
+    dhcp->pcb_allocated = 0;
+  }
+}
+
+/**
+ * @ingroup dhcp4
+ * This function calls dhcp_release_and_stop() internally.
+ * @deprecated Use dhcp_release_and_stop() instead.
+ */
+err_t
+dhcp_release(struct netif *netif)
+{
+  dhcp_release_and_stop(netif);
+  return ERR_OK;
+}
+
+/**
+ * @ingroup dhcp4
+ * This function calls dhcp_release_and_stop() internally.
+ * @deprecated Use dhcp_release_and_stop() instead.
+ */
+void
+dhcp_stop(struct netif *netif)
+{
+  dhcp_release_and_stop(netif);
+}
+
+/*
+ * Set the DHCP state of a DHCP client.
+ *
+ * If the state changed, reset the number of tries.
+ */
+static void
+dhcp_set_state(struct dhcp *dhcp, u8_t new_state)
+{
+  if (new_state != dhcp->state) {
+    dhcp->state = new_state;
+    dhcp->tries = 0;
+    dhcp->request_timeout = 0;
+  }
+}
+
+/*
+ * Concatenate an option type and length field to the outgoing
+ * DHCP message.
+ *
+ */
+static u16_t
+dhcp_option(u16_t options_out_len, u8_t *options, u8_t option_type, u8_t option_len)
+{
+  LWIP_ASSERT("dhcp_option: options_out_len + 2 + option_len <= DHCP_OPTIONS_LEN", options_out_len + 2U + option_len <= DHCP_OPTIONS_LEN);
+  options[options_out_len++] = option_type;
+  options[options_out_len++] = option_len;
+  return options_out_len;
+}
+/*
+ * Concatenate a single byte to the outgoing DHCP message.
+ *
+ */
+static u16_t
+dhcp_option_byte(u16_t options_out_len, u8_t *options, u8_t value)
+{
+  LWIP_ASSERT("dhcp_option_byte: options_out_len < DHCP_OPTIONS_LEN", options_out_len < DHCP_OPTIONS_LEN);
+  options[options_out_len++] = value;
+  return options_out_len;
+}
+
+static u16_t
+dhcp_option_short(u16_t options_out_len, u8_t *options, u16_t value)
+{
+  LWIP_ASSERT("dhcp_option_short: options_out_len + 2 <= DHCP_OPTIONS_LEN", options_out_len + 2U <= DHCP_OPTIONS_LEN);
+  options[options_out_len++] = (u8_t)((value & 0xff00U) >> 8);
+  options[options_out_len++] = (u8_t) (value & 0x00ffU);
+  return options_out_len;
+}
+
+static u16_t
+dhcp_option_long(u16_t options_out_len, u8_t *options, u32_t value)
+{
+  LWIP_ASSERT("dhcp_option_long: options_out_len + 4 <= DHCP_OPTIONS_LEN", options_out_len + 4U <= DHCP_OPTIONS_LEN);
+  options[options_out_len++] = (u8_t)((value & 0xff000000UL) >> 24);
+  options[options_out_len++] = (u8_t)((value & 0x00ff0000UL) >> 16);
+  options[options_out_len++] = (u8_t)((value & 0x0000ff00UL) >> 8);
+  options[options_out_len++] = (u8_t)((value & 0x000000ffUL));
+  return options_out_len;
+}
+
+#if LWIP_NETIF_HOSTNAME
+static u16_t
+dhcp_option_hostname(u16_t options_out_len, u8_t *options, struct netif *netif)
+{
+  if (netif->hostname != NULL) {
+    size_t namelen = strlen(netif->hostname);
+    if (namelen > 0) {
+      size_t len;
+      const char *p = netif->hostname;
+      /* Shrink len to available bytes (need 2 bytes for OPTION_HOSTNAME
+         and 1 byte for trailer) */
+      size_t available = DHCP_OPTIONS_LEN - options_out_len - 3;
+      LWIP_ASSERT("DHCP: hostname is too long!", namelen <= available);
+      len = LWIP_MIN(namelen, available);
+      LWIP_ASSERT("DHCP: hostname is too long!", len <= 0xFF);
+      options_out_len = dhcp_option(options_out_len, options, DHCP_OPTION_HOSTNAME, (u8_t)len);
+      while (len--) {
+        options_out_len = dhcp_option_byte(options_out_len, options, *p++);
+      }
+    }
+  }
+  return options_out_len;
+}
+#endif /* LWIP_NETIF_HOSTNAME */
+
+/**
+ * Extract the DHCP message and the DHCP options.
+ *
+ * Extract the DHCP message and the DHCP options, each into a contiguous
+ * piece of memory. As a DHCP message is variable sized by its options,
+ * and also allows overriding some fields for options, the easy approach
+ * is to first unfold the options into a contiguous piece of memory, and
+ * use that further on.
+ *
+ */
+static err_t
+dhcp_parse_reply(struct pbuf *p, struct dhcp *dhcp)
+{
+  u8_t *options;
+  u16_t offset;
+  u16_t offset_max;
+  u16_t options_idx;
+  u16_t options_idx_max;
+  struct pbuf *q;
+  int parse_file_as_options = 0;
+  int parse_sname_as_options = 0;
+  struct dhcp_msg *msg_in;
+#if LWIP_DHCP_BOOTP_FILE
+  int file_overloaded = 0;
+#endif
+
+  LWIP_UNUSED_ARG(dhcp);
+
+  /* clear received options */
+  dhcp_clear_all_options(dhcp);
+  /* check that beginning of dhcp_msg (up to and including chaddr) is in first pbuf */
+  if (p->len < DHCP_SNAME_OFS) {
+    return ERR_BUF;
+  }
+  msg_in = (struct dhcp_msg *)p->payload;
+#if LWIP_DHCP_BOOTP_FILE
+  /* clear boot file name */
+  dhcp->boot_file_name[0] = 0;
+#endif /* LWIP_DHCP_BOOTP_FILE */
+
+  /* parse options */
+
+  /* start with options field */
+  options_idx = DHCP_OPTIONS_OFS;
+  /* parse options to the end of the received packet */
+  options_idx_max = p->tot_len;
+again:
+  q = p;
+  while ((q != NULL) && (options_idx >= q->len)) {
+    options_idx = (u16_t)(options_idx - q->len);
+    options_idx_max = (u16_t)(options_idx_max - q->len);
+    q = q->next;
+  }
+  if (q == NULL) {
+    return ERR_BUF;
+  }
+  offset = options_idx;
+  offset_max = options_idx_max;
+  options = (u8_t *)q->payload;
+  /* at least 1 byte to read and no end marker, then at least 3 bytes to read? */
+  while ((q != NULL) && (offset < offset_max) && (options[offset] != DHCP_OPTION_END)) {
+    u8_t op = options[offset];
+    u8_t len;
+    u8_t decode_len = 0;
+    int decode_idx = -1;
+    u16_t val_offset = (u16_t)(offset + 2);
+    if (val_offset < offset) {
+      /* overflow */
+      return ERR_BUF;
+    }
+    /* len byte might be in the next pbuf */
+    if ((offset + 1) < q->len) {
+      len = options[offset + 1];
+    } else {
+      len = (q->next != NULL ? ((u8_t *)q->next->payload)[0] : 0);
+    }
+    /* LWIP_DEBUGF(DHCP_DEBUG, ("msg_offset=%"U16_F", q->len=%"U16_F, msg_offset, q->len)); */
+    decode_len = len;
+    switch (op) {
+      /* case(DHCP_OPTION_END): handled above */
+      case (DHCP_OPTION_PAD):
+        /* special option: no len encoded */
+        decode_len = len = 0;
+        /* will be increased below */
+        break;
+      case (DHCP_OPTION_SUBNET_MASK):
+        LWIP_ERROR("len == 4", len == 4, return ERR_VAL;);
+        decode_idx = DHCP_OPTION_IDX_SUBNET_MASK;
+        break;
+      case (DHCP_OPTION_ROUTER):
+        decode_len = 4; /* only copy the first given router */
+        LWIP_ERROR("len >= decode_len", len >= decode_len, return ERR_VAL;);
+        decode_idx = DHCP_OPTION_IDX_ROUTER;
+        break;
+#if LWIP_DHCP_PROVIDE_DNS_SERVERS
+      case (DHCP_OPTION_DNS_SERVER):
+        /* special case: there might be more than one server */
+        LWIP_ERROR("len %% 4 == 0", len % 4 == 0, return ERR_VAL;);
+        /* limit number of DNS servers */
+        decode_len = LWIP_MIN(len, 4 * DNS_MAX_SERVERS);
+        LWIP_ERROR("len >= decode_len", len >= decode_len, return ERR_VAL;);
+        decode_idx = DHCP_OPTION_IDX_DNS_SERVER;
+        break;
+#endif /* LWIP_DHCP_PROVIDE_DNS_SERVERS */
+      case (DHCP_OPTION_LEASE_TIME):
+        LWIP_ERROR("len == 4", len == 4, return ERR_VAL;);
+        decode_idx = DHCP_OPTION_IDX_LEASE_TIME;
+        break;
+#if LWIP_DHCP_GET_NTP_SRV
+      case (DHCP_OPTION_NTP):
+        /* special case: there might be more than one server */
+        LWIP_ERROR("len %% 4 == 0", len % 4 == 0, return ERR_VAL;);
+        /* limit number of NTP servers */
+        decode_len = LWIP_MIN(len, 4 * LWIP_DHCP_MAX_NTP_SERVERS);
+        LWIP_ERROR("len >= decode_len", len >= decode_len, return ERR_VAL;);
+        decode_idx = DHCP_OPTION_IDX_NTP_SERVER;
+        break;
+#endif /* LWIP_DHCP_GET_NTP_SRV*/
+      case (DHCP_OPTION_OVERLOAD):
+        LWIP_ERROR("len == 1", len == 1, return ERR_VAL;);
+        /* decode overload only in options, not in file/sname: invalid packet */
+        LWIP_ERROR("overload in file/sname", options_idx == DHCP_OPTIONS_OFS, return ERR_VAL;);
+        decode_idx = DHCP_OPTION_IDX_OVERLOAD;
+        break;
+      case (DHCP_OPTION_MESSAGE_TYPE):
+        LWIP_ERROR("len == 1", len == 1, return ERR_VAL;);
+        decode_idx = DHCP_OPTION_IDX_MSG_TYPE;
+        break;
+      case (DHCP_OPTION_SERVER_ID):
+        LWIP_ERROR("len == 4", len == 4, return ERR_VAL;);
+        decode_idx = DHCP_OPTION_IDX_SERVER_ID;
+        break;
+      case (DHCP_OPTION_T1):
+        LWIP_ERROR("len == 4", len == 4, return ERR_VAL;);
+        decode_idx = DHCP_OPTION_IDX_T1;
+        break;
+      case (DHCP_OPTION_T2):
+        LWIP_ERROR("len == 4", len == 4, return ERR_VAL;);
+        decode_idx = DHCP_OPTION_IDX_T2;
+        break;
+      default:
+        decode_len = 0;
+        LWIP_DEBUGF(DHCP_DEBUG, ("skipping option %"U16_F" in options\n", (u16_t)op));
+        LWIP_HOOK_DHCP_PARSE_OPTION(ip_current_netif(), dhcp, dhcp->state, msg_in,
+                                    dhcp_option_given(dhcp, DHCP_OPTION_IDX_MSG_TYPE) ? (u8_t)dhcp_get_option_value(dhcp, DHCP_OPTION_IDX_MSG_TYPE) : 0,
+                                    op, len, q, val_offset);
+        break;
+    }
+    if (op == DHCP_OPTION_PAD) {
+      offset++;
+    } else {
+      if (offset + len + 2 > 0xFFFF) {
+        /* overflow */
+        return ERR_BUF;
+      }
+      offset = (u16_t)(offset + len + 2);
+      if (decode_len > 0) {
+        u32_t value = 0;
+        u16_t copy_len;
+decode_next:
+        LWIP_ASSERT("check decode_idx", decode_idx >= 0 && decode_idx < DHCP_OPTION_IDX_MAX);
+        if (!dhcp_option_given(dhcp, decode_idx)) {
+          copy_len = LWIP_MIN(decode_len, 4);
+          if (pbuf_copy_partial(q, &value, copy_len, val_offset) != copy_len) {
+            return ERR_BUF;
+          }
+          if (decode_len > 4) {
+            /* decode more than one u32_t */
+            u16_t next_val_offset;
+            LWIP_ERROR("decode_len %% 4 == 0", decode_len % 4 == 0, return ERR_VAL;);
+            dhcp_got_option(dhcp, decode_idx);
+            dhcp_set_option_value(dhcp, decode_idx, lwip_htonl(value));
+            decode_len = (u8_t)(decode_len - 4);
+            next_val_offset = (u16_t)(val_offset + 4);
+            if (next_val_offset < val_offset) {
+              /* overflow */
+              return ERR_BUF;
+            }
+            val_offset = next_val_offset;
+            decode_idx++;
+            goto decode_next;
+          } else if (decode_len == 4) {
+            value = lwip_ntohl(value);
+          } else {
+            LWIP_ERROR("invalid decode_len", decode_len == 1, return ERR_VAL;);
+            value = ((u8_t *)&value)[0];
+          }
+          dhcp_got_option(dhcp, decode_idx);
+          dhcp_set_option_value(dhcp, decode_idx, value);
+        }
+      }
+    }
+    if (offset >= q->len) {
+      offset = (u16_t)(offset - q->len);
+      offset_max = (u16_t)(offset_max - q->len);
+      if (offset < offset_max) {
+        q = q->next;
+        LWIP_ERROR("next pbuf was null", q != NULL, return ERR_VAL;);
+        options = (u8_t *)q->payload;
+      } else {
+        /* We've run out of bytes, probably no end marker. Don't proceed. */
+        return ERR_BUF;
+      }
+    }
+  }
+  /* is this an overloaded message? */
+  if (dhcp_option_given(dhcp, DHCP_OPTION_IDX_OVERLOAD)) {
+    u32_t overload = dhcp_get_option_value(dhcp, DHCP_OPTION_IDX_OVERLOAD);
+    dhcp_clear_option(dhcp, DHCP_OPTION_IDX_OVERLOAD);
+    if (overload == DHCP_OVERLOAD_FILE) {
+      parse_file_as_options = 1;
+      LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("overloaded file field\n"));
+    } else if (overload == DHCP_OVERLOAD_SNAME) {
+      parse_sname_as_options = 1;
+      LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("overloaded sname field\n"));
+    } else if (overload == DHCP_OVERLOAD_SNAME_FILE) {
+      parse_sname_as_options = 1;
+      parse_file_as_options = 1;
+      LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("overloaded sname and file field\n"));
+    } else {
+      LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("invalid overload option: %d\n", (int)overload));
+    }
+  }
+  if (parse_file_as_options) {
+    /* if both are overloaded, parse file first and then sname (RFC 2131 ch. 4.1) */
+    parse_file_as_options = 0;
+    options_idx = DHCP_FILE_OFS;
+    options_idx_max = DHCP_FILE_OFS + DHCP_FILE_LEN;
+#if LWIP_DHCP_BOOTP_FILE
+    file_overloaded = 1;
+#endif
+    goto again;
+  } else if (parse_sname_as_options) {
+    parse_sname_as_options = 0;
+    options_idx = DHCP_SNAME_OFS;
+    options_idx_max = DHCP_SNAME_OFS + DHCP_SNAME_LEN;
+    goto again;
+  }
+#if LWIP_DHCP_BOOTP_FILE
+  if (!file_overloaded) {
+    /* only do this for ACK messages */
+    if (dhcp_option_given(dhcp, DHCP_OPTION_IDX_MSG_TYPE) &&
+      (dhcp_get_option_value(dhcp, DHCP_OPTION_IDX_MSG_TYPE) == DHCP_ACK))
+    /* copy bootp file name, don't care for sname (server hostname) */
+    if (pbuf_copy_partial(p, dhcp->boot_file_name, DHCP_FILE_LEN-1, DHCP_FILE_OFS) != (DHCP_FILE_LEN-1)) {
+      return ERR_BUF;
+    }
+    /* make sure the string is really NULL-terminated */
+    dhcp->boot_file_name[DHCP_FILE_LEN-1] = 0;
+  }
+#endif /* LWIP_DHCP_BOOTP_FILE */ 
+  return ERR_OK;
+}
+
+/**
+ * If an incoming DHCP message is in response to us, then trigger the state machine
+ */
+static void
+dhcp_recv(void *arg, struct udp_pcb *pcb, struct pbuf *p, const ip_addr_t *addr, u16_t port)
+{
+  struct netif *netif = ip_current_input_netif();
+  struct dhcp *dhcp = netif_dhcp_data(netif);
+  struct dhcp_msg *reply_msg = (struct dhcp_msg *)p->payload;
+  u8_t msg_type;
+  u8_t i;
+  struct dhcp_msg *msg_in;
+
+  LWIP_UNUSED_ARG(arg);
+
+  /* Caught DHCP message from netif that does not have DHCP enabled? -> not interested */
+  if ((dhcp == NULL) || (dhcp->pcb_allocated == 0)) {
+    goto free_pbuf_and_return;
+  }
+
+  LWIP_ASSERT("invalid server address type", IP_IS_V4(addr));
+
+  LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_recv(pbuf = %p) from DHCP server %"U16_F".%"U16_F".%"U16_F".%"U16_F" port %"U16_F"\n", (void *)p,
+              ip4_addr1_16(ip_2_ip4(addr)), ip4_addr2_16(ip_2_ip4(addr)), ip4_addr3_16(ip_2_ip4(addr)), ip4_addr4_16(ip_2_ip4(addr)), port));
+  LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("pbuf->len = %"U16_F"\n", p->len));
+  LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("pbuf->tot_len = %"U16_F"\n", p->tot_len));
+  /* prevent warnings about unused arguments */
+  LWIP_UNUSED_ARG(pcb);
+  LWIP_UNUSED_ARG(addr);
+  LWIP_UNUSED_ARG(port);
+
+  if (p->len < DHCP_MIN_REPLY_LEN) {
+    LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_WARNING, ("DHCP reply message or pbuf too short\n"));
+    goto free_pbuf_and_return;
+  }
+
+  if (reply_msg->op != DHCP_BOOTREPLY) {
+    LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_WARNING, ("not a DHCP reply message, but type %"U16_F"\n", (u16_t)reply_msg->op));
+    goto free_pbuf_and_return;
+  }
+  /* iterate through hardware address and match against DHCP message */
+  for (i = 0; i < netif->hwaddr_len && i < LWIP_MIN(DHCP_CHADDR_LEN, NETIF_MAX_HWADDR_LEN); i++) {
+    if (netif->hwaddr[i] != reply_msg->chaddr[i]) {
+      LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_WARNING,
+                  ("netif->hwaddr[%"U16_F"]==%02"X16_F" != reply_msg->chaddr[%"U16_F"]==%02"X16_F"\n",
+                   (u16_t)i, (u16_t)netif->hwaddr[i], (u16_t)i, (u16_t)reply_msg->chaddr[i]));
+      goto free_pbuf_and_return;
+    }
+  }
+  /* match transaction ID against what we expected */
+  if (lwip_ntohl(reply_msg->xid) != dhcp->xid) {
+    LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_WARNING,
+                ("transaction id mismatch reply_msg->xid(%"X32_F")!=dhcp->xid(%"X32_F")\n", lwip_ntohl(reply_msg->xid), dhcp->xid));
+    goto free_pbuf_and_return;
+  }
+  /* option fields could be unfold? */
+  if (dhcp_parse_reply(p, dhcp) != ERR_OK) {
+    LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS,
+                ("problem unfolding DHCP message - too short on memory?\n"));
+    goto free_pbuf_and_return;
+  }
+
+  LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("searching DHCP_OPTION_MESSAGE_TYPE\n"));
+  /* obtain pointer to DHCP message type */
+  if (!dhcp_option_given(dhcp, DHCP_OPTION_IDX_MSG_TYPE)) {
+    LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_WARNING, ("DHCP_OPTION_MESSAGE_TYPE option not found\n"));
+    goto free_pbuf_and_return;
+  }
+
+  msg_in = (struct dhcp_msg *)p->payload;
+  /* read DHCP message type */
+  msg_type = (u8_t)dhcp_get_option_value(dhcp, DHCP_OPTION_IDX_MSG_TYPE);
+  /* message type is DHCP ACK? */
+  if (msg_type == DHCP_ACK) {
+    LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("DHCP_ACK received\n"));
+    /* in requesting state? */
+    if (dhcp->state == DHCP_STATE_REQUESTING) {
+      dhcp_handle_ack(netif, msg_in);
+#if DHCP_DOES_ARP_CHECK
+      if ((netif->flags & NETIF_FLAG_ETHARP) != 0) {
+        /* check if the acknowledged lease address is already in use */
+        dhcp_check(netif);
+      } else {
+        /* bind interface to the acknowledged lease address */
+        dhcp_bind(netif);
+      }
+#else
+      /* bind interface to the acknowledged lease address */
+      dhcp_bind(netif);
+#endif
+    }
+    /* already bound to the given lease address? */
+    else if ((dhcp->state == DHCP_STATE_REBOOTING) || (dhcp->state == DHCP_STATE_REBINDING) ||
+             (dhcp->state == DHCP_STATE_RENEWING)) {
+      dhcp_handle_ack(netif, msg_in);
+      dhcp_bind(netif);
+    }
+  }
+  /* received a DHCP_NAK in appropriate state? */
+  else if ((msg_type == DHCP_NAK) &&
+           ((dhcp->state == DHCP_STATE_REBOOTING) || (dhcp->state == DHCP_STATE_REQUESTING) ||
+            (dhcp->state == DHCP_STATE_REBINDING) || (dhcp->state == DHCP_STATE_RENEWING  ))) {
+    LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("DHCP_NAK received\n"));
+    dhcp_handle_nak(netif);
+  }
+  /* received a DHCP_OFFER in DHCP_STATE_SELECTING state? */
+  else if ((msg_type == DHCP_OFFER) && (dhcp->state == DHCP_STATE_SELECTING)) {
+    LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("DHCP_OFFER received in DHCP_STATE_SELECTING state\n"));
+    /* remember offered lease */
+    dhcp_handle_offer(netif, msg_in);
+  }
+
+free_pbuf_and_return:
+  pbuf_free(p);
+}
+
+/**
+ * Create a DHCP request, fill in common headers
+ *
+ * @param netif the netif under DHCP control
+ * @param dhcp dhcp control struct
+ * @param message_type message type of the request
+ */
+static struct pbuf *
+dhcp_create_msg(struct netif *netif, struct dhcp *dhcp, u8_t message_type, u16_t *options_out_len)
+{
+  u16_t i;
+  struct pbuf *p_out;
+  struct dhcp_msg *msg_out;
+  u16_t options_out_len_loc;
+
+#ifndef DHCP_GLOBAL_XID
+  /** default global transaction identifier starting value (easy to match
+   *  with a packet analyser). We simply increment for each new request.
+   *  Predefine DHCP_GLOBAL_XID to a better value or a function call to generate one
+   *  at runtime, any supporting function prototypes can be defined in DHCP_GLOBAL_XID_HEADER */
+#if DHCP_CREATE_RAND_XID && defined(LWIP_RAND)
+  static u32_t xid;
+#else /* DHCP_CREATE_RAND_XID && defined(LWIP_RAND) */
+  static u32_t xid = 0xABCD0000;
+#endif /* DHCP_CREATE_RAND_XID && defined(LWIP_RAND) */
+#else
+  if (!xid_initialised) {
+    xid = DHCP_GLOBAL_XID;
+    xid_initialised = !xid_initialised;
+  }
+#endif
+  LWIP_ERROR("dhcp_create_msg: netif != NULL", (netif != NULL), return NULL;);
+  LWIP_ERROR("dhcp_create_msg: dhcp != NULL", (dhcp != NULL), return NULL;);
+  p_out = pbuf_alloc(PBUF_TRANSPORT, sizeof(struct dhcp_msg), PBUF_RAM);
+  if (p_out == NULL) {
+    LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS,
+                ("dhcp_create_msg(): could not allocate pbuf\n"));
+    return NULL;
+  }
+  LWIP_ASSERT("dhcp_create_msg: check that first pbuf can hold struct dhcp_msg",
+              (p_out->len >= sizeof(struct dhcp_msg)));
+
+  /* DHCP_REQUEST should reuse 'xid' from DHCPOFFER */
+  if ((message_type != DHCP_REQUEST) || (dhcp->state == DHCP_STATE_REBOOTING)) {
+    /* reuse transaction identifier in retransmissions */
+    if (dhcp->tries == 0) {
+#if DHCP_CREATE_RAND_XID && defined(LWIP_RAND)
+      xid = LWIP_RAND();
+#else /* DHCP_CREATE_RAND_XID && defined(LWIP_RAND) */
+      xid++;
+#endif /* DHCP_CREATE_RAND_XID && defined(LWIP_RAND) */
+    }
+    dhcp->xid = xid;
+  }
+  LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE,
+              ("transaction id xid(%"X32_F")\n", xid));
+
+  msg_out = (struct dhcp_msg *)p_out->payload;
+  memset(msg_out, 0, sizeof(struct dhcp_msg));
+
+  msg_out->op = DHCP_BOOTREQUEST;
+  /* @todo: make link layer independent */
+  msg_out->htype = LWIP_IANA_HWTYPE_ETHERNET;
+  msg_out->hlen = netif->hwaddr_len;
+  msg_out->xid = lwip_htonl(dhcp->xid);
+  /* we don't need the broadcast flag since we can receive unicast traffic
+     before being fully configured! */
+  /* set ciaddr to netif->ip_addr based on message_type and state */
+  if ((message_type == DHCP_INFORM) || (message_type == DHCP_DECLINE) || (message_type == DHCP_RELEASE) ||
+      ((message_type == DHCP_REQUEST) && /* DHCP_STATE_BOUND not used for sending! */
+       ((dhcp->state == DHCP_STATE_RENEWING) || dhcp->state == DHCP_STATE_REBINDING))) {
+    ip4_addr_copy(msg_out->ciaddr, *netif_ip4_addr(netif));
+  }
+  for (i = 0; i < LWIP_MIN(DHCP_CHADDR_LEN, NETIF_MAX_HWADDR_LEN); i++) {
+    /* copy netif hardware address (padded with zeroes through memset already) */
+    msg_out->chaddr[i] = netif->hwaddr[i];
+  }
+  msg_out->cookie = PP_HTONL(DHCP_MAGIC_COOKIE);
+  /* Add option MESSAGE_TYPE */
+  options_out_len_loc = dhcp_option(0, msg_out->options, DHCP_OPTION_MESSAGE_TYPE, DHCP_OPTION_MESSAGE_TYPE_LEN);
+  options_out_len_loc = dhcp_option_byte(options_out_len_loc, msg_out->options, message_type);
+  if (options_out_len) {
+    *options_out_len = options_out_len_loc;
+  }
+  return p_out;
+}
+
+/**
+ * Add a DHCP message trailer
+ *
+ * Adds the END option to the DHCP message, and if
+ * necessary, up to three padding bytes.
+ */
+static void
+dhcp_option_trailer(u16_t options_out_len, u8_t *options, struct pbuf *p_out)
+{
+  options[options_out_len++] = DHCP_OPTION_END;
+  /* packet is too small, or not 4 byte aligned? */
+  while (((options_out_len < DHCP_MIN_OPTIONS_LEN) || (options_out_len & 3)) &&
+         (options_out_len < DHCP_OPTIONS_LEN)) {
+    /* add a fill/padding byte */
+    options[options_out_len++] = 0;
+  }
+  /* shrink the pbuf to the actual content length */
+  pbuf_realloc(p_out, (u16_t)(sizeof(struct dhcp_msg) - DHCP_OPTIONS_LEN + options_out_len));
+}
+
+/** check if DHCP supplied netif->ip_addr
+ *
+ * @param netif the netif to check
+ * @return 1 if DHCP supplied netif->ip_addr (states BOUND or RENEWING),
+ *         0 otherwise
+ */
+u8_t
+dhcp_supplied_address(const struct netif *netif)
+{
+  if ((netif != NULL) && (netif_dhcp_data(netif) != NULL)) {
+    struct dhcp *dhcp = netif_dhcp_data(netif);
+    return (dhcp->state == DHCP_STATE_BOUND) || (dhcp->state == DHCP_STATE_RENEWING) ||
+           (dhcp->state == DHCP_STATE_REBINDING);
+  }
+  return 0;
+}
+
+#endif /* LWIP_IPV4 && LWIP_DHCP */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/core/ipv4/etharp.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/core/ipv4/etharp.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/core/ipv4/etharp.c	(revision 457)
@@ -0,0 +1,1204 @@
+/**
+ * @file
+ * Address Resolution Protocol module for IP over Ethernet
+ *
+ * Functionally, ARP is divided into two parts. The first maps an IP address
+ * to a physical address when sending a packet, and the second part answers
+ * requests from other machines for our physical address.
+ *
+ * This implementation complies with RFC 826 (Ethernet ARP). It supports
+ * Gratuitious ARP from RFC3220 (IP Mobility Support for IPv4) section 4.6
+ * if an interface calls etharp_gratuitous(our_netif) upon address change.
+ */
+
+/*
+ * Copyright (c) 2001-2003 Swedish Institute of Computer Science.
+ * Copyright (c) 2003-2004 Leon Woestenberg <leon.woestenberg@axon.tv>
+ * Copyright (c) 2003-2004 Axon Digital Design B.V., The Netherlands.
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ */
+
+#include "lwip/opt.h"
+
+#if LWIP_IPV4 && LWIP_ARP /* don't build if not configured for use in lwipopts.h */
+
+#include "lwip/etharp.h"
+#include "lwip/stats.h"
+#include "lwip/snmp.h"
+#include "lwip/dhcp.h"
+#include "lwip/autoip.h"
+#include "lwip/prot/iana.h"
+#include "netif/ethernet.h"
+
+#include <string.h>
+
+#ifdef LWIP_HOOK_FILENAME
+#include LWIP_HOOK_FILENAME
+#endif
+
+/** Re-request a used ARP entry 1 minute before it would expire to prevent
+ *  breaking a steadily used connection because the ARP entry timed out. */
+#define ARP_AGE_REREQUEST_USED_UNICAST   (ARP_MAXAGE - 30)
+#define ARP_AGE_REREQUEST_USED_BROADCAST (ARP_MAXAGE - 15)
+
+/** the time an ARP entry stays pending after first request,
+ *  for ARP_TMR_INTERVAL = 1000, this is
+ *  10 seconds.
+ *
+ *  @internal Keep this number at least 2, otherwise it might
+ *  run out instantly if the timeout occurs directly after a request.
+ */
+#define ARP_MAXPENDING 5
+
+/** ARP states */
+enum etharp_state {
+  ETHARP_STATE_EMPTY = 0,
+  ETHARP_STATE_PENDING,
+  ETHARP_STATE_STABLE,
+  ETHARP_STATE_STABLE_REREQUESTING_1,
+  ETHARP_STATE_STABLE_REREQUESTING_2
+#if ETHARP_SUPPORT_STATIC_ENTRIES
+  , ETHARP_STATE_STATIC
+#endif /* ETHARP_SUPPORT_STATIC_ENTRIES */
+};
+
+struct etharp_entry {
+#if ARP_QUEUEING
+  /** Pointer to queue of pending outgoing packets on this ARP entry. */
+  struct etharp_q_entry *q;
+#else /* ARP_QUEUEING */
+  /** Pointer to a single pending outgoing packet on this ARP entry. */
+  struct pbuf *q;
+#endif /* ARP_QUEUEING */
+  ip4_addr_t ipaddr;
+  struct netif *netif;
+  struct eth_addr ethaddr;
+  u16_t ctime;
+  u8_t state;
+};
+
+static struct etharp_entry arp_table[ARP_TABLE_SIZE];
+
+#if !LWIP_NETIF_HWADDRHINT
+static netif_addr_idx_t etharp_cached_entry;
+#endif /* !LWIP_NETIF_HWADDRHINT */
+
+/** Try hard to create a new entry - we want the IP address to appear in
+    the cache (even if this means removing an active entry or so). */
+#define ETHARP_FLAG_TRY_HARD     1
+#define ETHARP_FLAG_FIND_ONLY    2
+#if ETHARP_SUPPORT_STATIC_ENTRIES
+#define ETHARP_FLAG_STATIC_ENTRY 4
+#endif /* ETHARP_SUPPORT_STATIC_ENTRIES */
+
+#if LWIP_NETIF_HWADDRHINT
+#define ETHARP_SET_ADDRHINT(netif, addrhint)  do { if (((netif) != NULL) && ((netif)->hints != NULL)) { \
+                                              (netif)->hints->addr_hint = (addrhint); }} while(0)
+#else /* LWIP_NETIF_HWADDRHINT */
+#define ETHARP_SET_ADDRHINT(netif, addrhint)  (etharp_cached_entry = (addrhint))
+#endif /* LWIP_NETIF_HWADDRHINT */
+
+
+/* Check for maximum ARP_TABLE_SIZE */
+#if (ARP_TABLE_SIZE > NETIF_ADDR_IDX_MAX)
+#error "ARP_TABLE_SIZE must fit in an s16_t, you have to reduce it in your lwipopts.h"
+#endif
+
+
+static err_t etharp_request_dst(struct netif *netif, const ip4_addr_t *ipaddr, const struct eth_addr *hw_dst_addr);
+static err_t etharp_raw(struct netif *netif,
+                        const struct eth_addr *ethsrc_addr, const struct eth_addr *ethdst_addr,
+                        const struct eth_addr *hwsrc_addr, const ip4_addr_t *ipsrc_addr,
+                        const struct eth_addr *hwdst_addr, const ip4_addr_t *ipdst_addr,
+                        const u16_t opcode);
+
+#if ARP_QUEUEING
+/**
+ * Free a complete queue of etharp entries
+ *
+ * @param q a qeueue of etharp_q_entry's to free
+ */
+static void
+free_etharp_q(struct etharp_q_entry *q)
+{
+  struct etharp_q_entry *r;
+  LWIP_ASSERT("q != NULL", q != NULL);
+  while (q) {
+    r = q;
+    q = q->next;
+    LWIP_ASSERT("r->p != NULL", (r->p != NULL));
+    pbuf_free(r->p);
+    memp_free(MEMP_ARP_QUEUE, r);
+  }
+}
+#else /* ARP_QUEUEING */
+
+/** Compatibility define: free the queued pbuf */
+#define free_etharp_q(q) pbuf_free(q)
+
+#endif /* ARP_QUEUEING */
+
+/** Clean up ARP table entries */
+static void
+etharp_free_entry(int i)
+{
+  /* remove from SNMP ARP index tree */
+  mib2_remove_arp_entry(arp_table[i].netif, &arp_table[i].ipaddr);
+  /* and empty packet queue */
+  if (arp_table[i].q != NULL) {
+    /* remove all queued packets */
+    LWIP_DEBUGF(ETHARP_DEBUG, ("etharp_free_entry: freeing entry %"U16_F", packet queue %p.\n", (u16_t)i, (void *)(arp_table[i].q)));
+    free_etharp_q(arp_table[i].q);
+    arp_table[i].q = NULL;
+  }
+  /* recycle entry for re-use */
+  arp_table[i].state = ETHARP_STATE_EMPTY;
+#ifdef LWIP_DEBUG
+  /* for debugging, clean out the complete entry */
+  arp_table[i].ctime = 0;
+  arp_table[i].netif = NULL;
+  ip4_addr_set_zero(&arp_table[i].ipaddr);
+  arp_table[i].ethaddr = ethzero;
+#endif /* LWIP_DEBUG */
+}
+
+/**
+ * Clears expired entries in the ARP table.
+ *
+ * This function should be called every ARP_TMR_INTERVAL milliseconds (1 second),
+ * in order to expire entries in the ARP table.
+ */
+void
+etharp_tmr(void)
+{
+  int i;
+
+  LWIP_DEBUGF(ETHARP_DEBUG, ("etharp_timer\n"));
+  /* remove expired entries from the ARP table */
+  for (i = 0; i < ARP_TABLE_SIZE; ++i) {
+    u8_t state = arp_table[i].state;
+    if (state != ETHARP_STATE_EMPTY
+#if ETHARP_SUPPORT_STATIC_ENTRIES
+        && (state != ETHARP_STATE_STATIC)
+#endif /* ETHARP_SUPPORT_STATIC_ENTRIES */
+       ) {
+      arp_table[i].ctime++;
+      if ((arp_table[i].ctime >= ARP_MAXAGE) ||
+          ((arp_table[i].state == ETHARP_STATE_PENDING)  &&
+           (arp_table[i].ctime >= ARP_MAXPENDING))) {
+        /* pending or stable entry has become old! */
+        LWIP_DEBUGF(ETHARP_DEBUG, ("etharp_timer: expired %s entry %d.\n",
+                                   arp_table[i].state >= ETHARP_STATE_STABLE ? "stable" : "pending", i));
+        /* clean up entries that have just been expired */
+        etharp_free_entry(i);
+      } else if (arp_table[i].state == ETHARP_STATE_STABLE_REREQUESTING_1) {
+        /* Don't send more than one request every 2 seconds. */
+        arp_table[i].state = ETHARP_STATE_STABLE_REREQUESTING_2;
+      } else if (arp_table[i].state == ETHARP_STATE_STABLE_REREQUESTING_2) {
+        /* Reset state to stable, so that the next transmitted packet will
+           re-send an ARP request. */
+        arp_table[i].state = ETHARP_STATE_STABLE;
+      } else if (arp_table[i].state == ETHARP_STATE_PENDING) {
+        /* still pending, resend an ARP query */
+        etharp_request(arp_table[i].netif, &arp_table[i].ipaddr);
+      }
+    }
+  }
+}
+
+/**
+ * Search the ARP table for a matching or new entry.
+ *
+ * If an IP address is given, return a pending or stable ARP entry that matches
+ * the address. If no match is found, create a new entry with this address set,
+ * but in state ETHARP_EMPTY. The caller must check and possibly change the
+ * state of the returned entry.
+ *
+ * If ipaddr is NULL, return a initialized new entry in state ETHARP_EMPTY.
+ *
+ * In all cases, attempt to create new entries from an empty entry. If no
+ * empty entries are available and ETHARP_FLAG_TRY_HARD flag is set, recycle
+ * old entries. Heuristic choose the least important entry for recycling.
+ *
+ * @param ipaddr IP address to find in ARP cache, or to add if not found.
+ * @param flags See @ref etharp_state
+ * @param netif netif related to this address (used for NETIF_HWADDRHINT)
+ *
+ * @return The ARP entry index that matched or is created, ERR_MEM if no
+ * entry is found or could be recycled.
+ */
+static s16_t
+etharp_find_entry(const ip4_addr_t *ipaddr, u8_t flags, struct netif *netif)
+{
+  s16_t old_pending = ARP_TABLE_SIZE, old_stable = ARP_TABLE_SIZE;
+  s16_t empty = ARP_TABLE_SIZE;
+  s16_t i = 0;
+  /* oldest entry with packets on queue */
+  s16_t old_queue = ARP_TABLE_SIZE;
+  /* its age */
+  u16_t age_queue = 0, age_pending = 0, age_stable = 0;
+
+  LWIP_UNUSED_ARG(netif);
+
+  /**
+   * a) do a search through the cache, remember candidates
+   * b) select candidate entry
+   * c) create new entry
+   */
+
+  /* a) in a single search sweep, do all of this
+   * 1) remember the first empty entry (if any)
+   * 2) remember the oldest stable entry (if any)
+   * 3) remember the oldest pending entry without queued packets (if any)
+   * 4) remember the oldest pending entry with queued packets (if any)
+   * 5) search for a matching IP entry, either pending or stable
+   *    until 5 matches, or all entries are searched for.
+   */
+
+  for (i = 0; i < ARP_TABLE_SIZE; ++i) {
+    u8_t state = arp_table[i].state;
+    /* no empty entry found yet and now we do find one? */
+    if ((empty == ARP_TABLE_SIZE) && (state == ETHARP_STATE_EMPTY)) {
+      LWIP_DEBUGF(ETHARP_DEBUG, ("etharp_find_entry: found empty entry %d\n", (int)i));
+      /* remember first empty entry */
+      empty = i;
+    } else if (state != ETHARP_STATE_EMPTY) {
+      LWIP_ASSERT("state == ETHARP_STATE_PENDING || state >= ETHARP_STATE_STABLE",
+                  state == ETHARP_STATE_PENDING || state >= ETHARP_STATE_STABLE);
+      /* if given, does IP address match IP address in ARP entry? */
+      if (ipaddr && ip4_addr_cmp(ipaddr, &arp_table[i].ipaddr)
+#if ETHARP_TABLE_MATCH_NETIF
+          && ((netif == NULL) || (netif == arp_table[i].netif))
+#endif /* ETHARP_TABLE_MATCH_NETIF */
+         ) {
+        LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_find_entry: found matching entry %d\n", (int)i));
+        /* found exact IP address match, simply bail out */
+        return i;
+      }
+      /* pending entry? */
+      if (state == ETHARP_STATE_PENDING) {
+        /* pending with queued packets? */
+        if (arp_table[i].q != NULL) {
+          if (arp_table[i].ctime >= age_queue) {
+            old_queue = i;
+            age_queue = arp_table[i].ctime;
+          }
+        } else
+          /* pending without queued packets? */
+        {
+          if (arp_table[i].ctime >= age_pending) {
+            old_pending = i;
+            age_pending = arp_table[i].ctime;
+          }
+        }
+        /* stable entry? */
+      } else if (state >= ETHARP_STATE_STABLE) {
+#if ETHARP_SUPPORT_STATIC_ENTRIES
+        /* don't record old_stable for static entries since they never expire */
+        if (state < ETHARP_STATE_STATIC)
+#endif /* ETHARP_SUPPORT_STATIC_ENTRIES */
+        {
+          /* remember entry with oldest stable entry in oldest, its age in maxtime */
+          if (arp_table[i].ctime >= age_stable) {
+            old_stable = i;
+            age_stable = arp_table[i].ctime;
+          }
+        }
+      }
+    }
+  }
+  /* { we have no match } => try to create a new entry */
+
+  /* don't create new entry, only search? */
+  if (((flags & ETHARP_FLAG_FIND_ONLY) != 0) ||
+      /* or no empty entry found and not allowed to recycle? */
+      ((empty == ARP_TABLE_SIZE) && ((flags & ETHARP_FLAG_TRY_HARD) == 0))) {
+    LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_find_entry: no empty entry found and not allowed to recycle\n"));
+    return (s16_t)ERR_MEM;
+  }
+
+  /* b) choose the least destructive entry to recycle:
+   * 1) empty entry
+   * 2) oldest stable entry
+   * 3) oldest pending entry without queued packets
+   * 4) oldest pending entry with queued packets
+   *
+   * { ETHARP_FLAG_TRY_HARD is set at this point }
+   */
+
+  /* 1) empty entry available? */
+  if (empty < ARP_TABLE_SIZE) {
+    i = empty;
+    LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_find_entry: selecting empty entry %d\n", (int)i));
+  } else {
+    /* 2) found recyclable stable entry? */
+    if (old_stable < ARP_TABLE_SIZE) {
+      /* recycle oldest stable*/
+      i = old_stable;
+      LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_find_entry: selecting oldest stable entry %d\n", (int)i));
+      /* no queued packets should exist on stable entries */
+      LWIP_ASSERT("arp_table[i].q == NULL", arp_table[i].q == NULL);
+      /* 3) found recyclable pending entry without queued packets? */
+    } else if (old_pending < ARP_TABLE_SIZE) {
+      /* recycle oldest pending */
+      i = old_pending;
+      LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_find_entry: selecting oldest pending entry %d (without queue)\n", (int)i));
+      /* 4) found recyclable pending entry with queued packets? */
+    } else if (old_queue < ARP_TABLE_SIZE) {
+      /* recycle oldest pending (queued packets are free in etharp_free_entry) */
+      i = old_queue;
+      LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_find_entry: selecting oldest pending entry %d, freeing packet queue %p\n", (int)i, (void *)(arp_table[i].q)));
+      /* no empty or recyclable entries found */
+    } else {
+      LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_find_entry: no empty or recyclable entries found\n"));
+      return (s16_t)ERR_MEM;
+    }
+
+    /* { empty or recyclable entry found } */
+    LWIP_ASSERT("i < ARP_TABLE_SIZE", i < ARP_TABLE_SIZE);
+    etharp_free_entry(i);
+  }
+
+  LWIP_ASSERT("i < ARP_TABLE_SIZE", i < ARP_TABLE_SIZE);
+  LWIP_ASSERT("arp_table[i].state == ETHARP_STATE_EMPTY",
+              arp_table[i].state == ETHARP_STATE_EMPTY);
+
+  /* IP address given? */
+  if (ipaddr != NULL) {
+    /* set IP address */
+    ip4_addr_copy(arp_table[i].ipaddr, *ipaddr);
+  }
+  arp_table[i].ctime = 0;
+#if ETHARP_TABLE_MATCH_NETIF
+  arp_table[i].netif = netif;
+#endif /* ETHARP_TABLE_MATCH_NETIF */
+  return (s16_t)i;
+}
+
+/**
+ * Update (or insert) a IP/MAC address pair in the ARP cache.
+ *
+ * If a pending entry is resolved, any queued packets will be sent
+ * at this point.
+ *
+ * @param netif netif related to this entry (used for NETIF_ADDRHINT)
+ * @param ipaddr IP address of the inserted ARP entry.
+ * @param ethaddr Ethernet address of the inserted ARP entry.
+ * @param flags See @ref etharp_state
+ *
+ * @return
+ * - ERR_OK Successfully updated ARP cache.
+ * - ERR_MEM If we could not add a new ARP entry when ETHARP_FLAG_TRY_HARD was set.
+ * - ERR_ARG Non-unicast address given, those will not appear in ARP cache.
+ *
+ * @see pbuf_free()
+ */
+static err_t
+etharp_update_arp_entry(struct netif *netif, const ip4_addr_t *ipaddr, struct eth_addr *ethaddr, u8_t flags)
+{
+  s16_t i;
+  LWIP_ASSERT("netif->hwaddr_len == ETH_HWADDR_LEN", netif->hwaddr_len == ETH_HWADDR_LEN);
+  LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_update_arp_entry: %"U16_F".%"U16_F".%"U16_F".%"U16_F" - %02"X16_F":%02"X16_F":%02"X16_F":%02"X16_F":%02"X16_F":%02"X16_F"\n",
+              ip4_addr1_16(ipaddr), ip4_addr2_16(ipaddr), ip4_addr3_16(ipaddr), ip4_addr4_16(ipaddr),
+              (u16_t)ethaddr->addr[0], (u16_t)ethaddr->addr[1], (u16_t)ethaddr->addr[2],
+              (u16_t)ethaddr->addr[3], (u16_t)ethaddr->addr[4], (u16_t)ethaddr->addr[5]));
+  /* non-unicast address? */
+  if (ip4_addr_isany(ipaddr) ||
+      ip4_addr_isbroadcast(ipaddr, netif) ||
+      ip4_addr_ismulticast(ipaddr)) {
+    LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_update_arp_entry: will not add non-unicast IP address to ARP cache\n"));
+    return ERR_ARG;
+  }
+  /* find or create ARP entry */
+  i = etharp_find_entry(ipaddr, flags, netif);
+  /* bail out if no entry could be found */
+  if (i < 0) {
+    return (err_t)i;
+  }
+
+#if ETHARP_SUPPORT_STATIC_ENTRIES
+  if (flags & ETHARP_FLAG_STATIC_ENTRY) {
+    /* record static type */
+    arp_table[i].state = ETHARP_STATE_STATIC;
+  } else if (arp_table[i].state == ETHARP_STATE_STATIC) {
+    /* found entry is a static type, don't overwrite it */
+    return ERR_VAL;
+  } else
+#endif /* ETHARP_SUPPORT_STATIC_ENTRIES */
+  {
+    /* mark it stable */
+    arp_table[i].state = ETHARP_STATE_STABLE;
+  }
+
+  /* record network interface */
+  arp_table[i].netif = netif;
+  /* insert in SNMP ARP index tree */
+  mib2_add_arp_entry(netif, &arp_table[i].ipaddr);
+
+  LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_update_arp_entry: updating stable entry %"S16_F"\n", i));
+  /* update address */
+  SMEMCPY(&arp_table[i].ethaddr, ethaddr, ETH_HWADDR_LEN);
+  /* reset time stamp */
+  arp_table[i].ctime = 0;
+  /* this is where we will send out queued packets! */
+#if ARP_QUEUEING
+  while (arp_table[i].q != NULL) {
+    struct pbuf *p;
+    /* remember remainder of queue */
+    struct etharp_q_entry *q = arp_table[i].q;
+    /* pop first item off the queue */
+    arp_table[i].q = q->next;
+    /* get the packet pointer */
+    p = q->p;
+    /* now queue entry can be freed */
+    memp_free(MEMP_ARP_QUEUE, q);
+#else /* ARP_QUEUEING */
+  if (arp_table[i].q != NULL) {
+    struct pbuf *p = arp_table[i].q;
+    arp_table[i].q = NULL;
+#endif /* ARP_QUEUEING */
+    /* send the queued IP packet */
+    ethernet_output(netif, p, (struct eth_addr *)(netif->hwaddr), ethaddr, ETHTYPE_IP);
+    /* free the queued IP packet */
+    pbuf_free(p);
+  }
+  return ERR_OK;
+}
+
+#if ETHARP_SUPPORT_STATIC_ENTRIES
+/** Add a new static entry to the ARP table. If an entry exists for the
+ * specified IP address, this entry is overwritten.
+ * If packets are queued for the specified IP address, they are sent out.
+ *
+ * @param ipaddr IP address for the new static entry
+ * @param ethaddr ethernet address for the new static entry
+ * @return See return values of etharp_add_static_entry
+ */
+err_t
+etharp_add_static_entry(const ip4_addr_t *ipaddr, struct eth_addr *ethaddr)
+{
+  struct netif *netif;
+  LWIP_ASSERT_CORE_LOCKED();
+  LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_add_static_entry: %"U16_F".%"U16_F".%"U16_F".%"U16_F" - %02"X16_F":%02"X16_F":%02"X16_F":%02"X16_F":%02"X16_F":%02"X16_F"\n",
+              ip4_addr1_16(ipaddr), ip4_addr2_16(ipaddr), ip4_addr3_16(ipaddr), ip4_addr4_16(ipaddr),
+              (u16_t)ethaddr->addr[0], (u16_t)ethaddr->addr[1], (u16_t)ethaddr->addr[2],
+              (u16_t)ethaddr->addr[3], (u16_t)ethaddr->addr[4], (u16_t)ethaddr->addr[5]));
+
+  netif = ip4_route(ipaddr);
+  if (netif == NULL) {
+    return ERR_RTE;
+  }
+
+  return etharp_update_arp_entry(netif, ipaddr, ethaddr, ETHARP_FLAG_TRY_HARD | ETHARP_FLAG_STATIC_ENTRY);
+}
+
+/** Remove a static entry from the ARP table previously added with a call to
+ * etharp_add_static_entry.
+ *
+ * @param ipaddr IP address of the static entry to remove
+ * @return ERR_OK: entry removed
+ *         ERR_MEM: entry wasn't found
+ *         ERR_ARG: entry wasn't a static entry but a dynamic one
+ */
+err_t
+etharp_remove_static_entry(const ip4_addr_t *ipaddr)
+{
+  s16_t i;
+  LWIP_ASSERT_CORE_LOCKED();
+  LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_remove_static_entry: %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n",
+              ip4_addr1_16(ipaddr), ip4_addr2_16(ipaddr), ip4_addr3_16(ipaddr), ip4_addr4_16(ipaddr)));
+
+  /* find or create ARP entry */
+  i = etharp_find_entry(ipaddr, ETHARP_FLAG_FIND_ONLY, NULL);
+  /* bail out if no entry could be found */
+  if (i < 0) {
+    return (err_t)i;
+  }
+
+  if (arp_table[i].state != ETHARP_STATE_STATIC) {
+    /* entry wasn't a static entry, cannot remove it */
+    return ERR_ARG;
+  }
+  /* entry found, free it */
+  etharp_free_entry(i);
+  return ERR_OK;
+}
+#endif /* ETHARP_SUPPORT_STATIC_ENTRIES */
+
+/**
+ * Remove all ARP table entries of the specified netif.
+ *
+ * @param netif points to a network interface
+ */
+void
+etharp_cleanup_netif(struct netif *netif)
+{
+  int i;
+
+  for (i = 0; i < ARP_TABLE_SIZE; ++i) {
+    u8_t state = arp_table[i].state;
+    if ((state != ETHARP_STATE_EMPTY) && (arp_table[i].netif == netif)) {
+      etharp_free_entry(i);
+    }
+  }
+}
+
+/**
+ * Finds (stable) ethernet/IP address pair from ARP table
+ * using interface and IP address index.
+ * @note the addresses in the ARP table are in network order!
+ *
+ * @param netif points to interface index
+ * @param ipaddr points to the (network order) IP address index
+ * @param eth_ret points to return pointer
+ * @param ip_ret points to return pointer
+ * @return table index if found, -1 otherwise
+ */
+ssize_t
+etharp_find_addr(struct netif *netif, const ip4_addr_t *ipaddr,
+                 struct eth_addr **eth_ret, const ip4_addr_t **ip_ret)
+{
+  s16_t i;
+
+  LWIP_ASSERT("eth_ret != NULL && ip_ret != NULL",
+              eth_ret != NULL && ip_ret != NULL);
+
+  LWIP_UNUSED_ARG(netif);
+
+  i = etharp_find_entry(ipaddr, ETHARP_FLAG_FIND_ONLY, netif);
+  if ((i >= 0) && (arp_table[i].state >= ETHARP_STATE_STABLE)) {
+    *eth_ret = &arp_table[i].ethaddr;
+    *ip_ret = &arp_table[i].ipaddr;
+    return i;
+  }
+  return -1;
+}
+
+/**
+ * Possibility to iterate over stable ARP table entries
+ *
+ * @param i entry number, 0 to ARP_TABLE_SIZE
+ * @param ipaddr return value: IP address
+ * @param netif return value: points to interface
+ * @param eth_ret return value: ETH address
+ * @return 1 on valid index, 0 otherwise
+ */
+int
+etharp_get_entry(size_t i, ip4_addr_t **ipaddr, struct netif **netif, struct eth_addr **eth_ret)
+{
+  LWIP_ASSERT("ipaddr != NULL", ipaddr != NULL);
+  LWIP_ASSERT("netif != NULL", netif != NULL);
+  LWIP_ASSERT("eth_ret != NULL", eth_ret != NULL);
+
+  if ((i < ARP_TABLE_SIZE) && (arp_table[i].state >= ETHARP_STATE_STABLE)) {
+    *ipaddr  = &arp_table[i].ipaddr;
+    *netif   = arp_table[i].netif;
+    *eth_ret = &arp_table[i].ethaddr;
+    return 1;
+  } else {
+    return 0;
+  }
+}
+
+/**
+ * Responds to ARP requests to us. Upon ARP replies to us, add entry to cache
+ * send out queued IP packets. Updates cache with snooped address pairs.
+ *
+ * Should be called for incoming ARP packets. The pbuf in the argument
+ * is freed by this function.
+ *
+ * @param p The ARP packet that arrived on netif. Is freed by this function.
+ * @param netif The lwIP network interface on which the ARP packet pbuf arrived.
+ *
+ * @see pbuf_free()
+ */
+void
+etharp_input(struct pbuf *p, struct netif *netif)
+{
+  struct etharp_hdr *hdr;
+  /* these are aligned properly, whereas the ARP header fields might not be */
+  ip4_addr_t sipaddr, dipaddr;
+  u8_t for_us;
+
+  LWIP_ASSERT_CORE_LOCKED();
+
+  LWIP_ERROR("netif != NULL", (netif != NULL), return;);
+
+  hdr = (struct etharp_hdr *)p->payload;
+
+  /* RFC 826 "Packet Reception": */
+  if ((hdr->hwtype != PP_HTONS(LWIP_IANA_HWTYPE_ETHERNET)) ||
+      (hdr->hwlen != ETH_HWADDR_LEN) ||
+      (hdr->protolen != sizeof(ip4_addr_t)) ||
+      (hdr->proto != PP_HTONS(ETHTYPE_IP)))  {
+    LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_WARNING,
+                ("etharp_input: packet dropped, wrong hw type, hwlen, proto, protolen or ethernet type (%"U16_F"/%"U16_F"/%"U16_F"/%"U16_F")\n",
+                 hdr->hwtype, (u16_t)hdr->hwlen, hdr->proto, (u16_t)hdr->protolen));
+    ETHARP_STATS_INC(etharp.proterr);
+    ETHARP_STATS_INC(etharp.drop);
+    pbuf_free(p);
+    return;
+  }
+  ETHARP_STATS_INC(etharp.recv);
+
+#if LWIP_AUTOIP
+  /* We have to check if a host already has configured our random
+   * created link local address and continuously check if there is
+   * a host with this IP-address so we can detect collisions */
+  autoip_arp_reply(netif, hdr);
+#endif /* LWIP_AUTOIP */
+
+  /* Copy struct ip4_addr_wordaligned to aligned ip4_addr, to support compilers without
+   * structure packing (not using structure copy which breaks strict-aliasing rules). */
+  IPADDR_WORDALIGNED_COPY_TO_IP4_ADDR_T(&sipaddr, &hdr->sipaddr);
+  IPADDR_WORDALIGNED_COPY_TO_IP4_ADDR_T(&dipaddr, &hdr->dipaddr);
+
+  /* this interface is not configured? */
+  if (ip4_addr_isany_val(*netif_ip4_addr(netif))) {
+    for_us = 0;
+  } else {
+    /* ARP packet directed to us? */
+    for_us = (u8_t)ip4_addr_cmp(&dipaddr, netif_ip4_addr(netif));
+  }
+
+  /* ARP message directed to us?
+      -> add IP address in ARP cache; assume requester wants to talk to us,
+         can result in directly sending the queued packets for this host.
+     ARP message not directed to us?
+      ->  update the source IP address in the cache, if present */
+  etharp_update_arp_entry(netif, &sipaddr, &(hdr->shwaddr),
+                          for_us ? ETHARP_FLAG_TRY_HARD : ETHARP_FLAG_FIND_ONLY);
+
+  /* now act on the message itself */
+  switch (hdr->opcode) {
+    /* ARP request? */
+    case PP_HTONS(ARP_REQUEST):
+      /* ARP request. If it asked for our address, we send out a
+       * reply. In any case, we time-stamp any existing ARP entry,
+       * and possibly send out an IP packet that was queued on it. */
+
+      LWIP_DEBUGF (ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_input: incoming ARP request\n"));
+      /* ARP request for our address? */
+      if (for_us) {
+        /* send ARP response */
+        etharp_raw(netif,
+                   (struct eth_addr *)netif->hwaddr, &hdr->shwaddr,
+                   (struct eth_addr *)netif->hwaddr, netif_ip4_addr(netif),
+                   &hdr->shwaddr, &sipaddr,
+                   ARP_REPLY);
+        /* we are not configured? */
+      } else if (ip4_addr_isany_val(*netif_ip4_addr(netif))) {
+        /* { for_us == 0 and netif->ip_addr.addr == 0 } */
+        LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_input: we are unconfigured, ARP request ignored.\n"));
+        /* request was not directed to us */
+      } else {
+        /* { for_us == 0 and netif->ip_addr.addr != 0 } */
+        LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_input: ARP request was not for us.\n"));
+      }
+      break;
+    case PP_HTONS(ARP_REPLY):
+      /* ARP reply. We already updated the ARP cache earlier. */
+      LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_input: incoming ARP reply\n"));
+#if (LWIP_DHCP && DHCP_DOES_ARP_CHECK)
+      /* DHCP wants to know about ARP replies from any host with an
+       * IP address also offered to us by the DHCP server. We do not
+       * want to take a duplicate IP address on a single network.
+       * @todo How should we handle redundant (fail-over) interfaces? */
+      dhcp_arp_reply(netif, &sipaddr);
+#endif /* (LWIP_DHCP && DHCP_DOES_ARP_CHECK) */
+      break;
+    default:
+      LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_input: ARP unknown opcode type %"S16_F"\n", lwip_htons(hdr->opcode)));
+      ETHARP_STATS_INC(etharp.err);
+      break;
+  }
+  /* free ARP packet */
+  pbuf_free(p);
+}
+
+/** Just a small helper function that sends a pbuf to an ethernet address
+ * in the arp_table specified by the index 'arp_idx'.
+ */
+static err_t
+etharp_output_to_arp_index(struct netif *netif, struct pbuf *q, netif_addr_idx_t arp_idx)
+{
+  LWIP_ASSERT("arp_table[arp_idx].state >= ETHARP_STATE_STABLE",
+              arp_table[arp_idx].state >= ETHARP_STATE_STABLE);
+  /* if arp table entry is about to expire: re-request it,
+     but only if its state is ETHARP_STATE_STABLE to prevent flooding the
+     network with ARP requests if this address is used frequently. */
+  if (arp_table[arp_idx].state == ETHARP_STATE_STABLE) {
+    if (arp_table[arp_idx].ctime >= ARP_AGE_REREQUEST_USED_BROADCAST) {
+      /* issue a standard request using broadcast */
+      if (etharp_request(netif, &arp_table[arp_idx].ipaddr) == ERR_OK) {
+        arp_table[arp_idx].state = ETHARP_STATE_STABLE_REREQUESTING_1;
+      }
+    } else if (arp_table[arp_idx].ctime >= ARP_AGE_REREQUEST_USED_UNICAST) {
+      /* issue a unicast request (for 15 seconds) to prevent unnecessary broadcast */
+      if (etharp_request_dst(netif, &arp_table[arp_idx].ipaddr, &arp_table[arp_idx].ethaddr) == ERR_OK) {
+        arp_table[arp_idx].state = ETHARP_STATE_STABLE_REREQUESTING_1;
+      }
+    }
+  }
+
+  return ethernet_output(netif, q, (struct eth_addr *)(netif->hwaddr), &arp_table[arp_idx].ethaddr, ETHTYPE_IP);
+}
+
+/**
+ * Resolve and fill-in Ethernet address header for outgoing IP packet.
+ *
+ * For IP multicast and broadcast, corresponding Ethernet addresses
+ * are selected and the packet is transmitted on the link.
+ *
+ * For unicast addresses, the packet is submitted to etharp_query(). In
+ * case the IP address is outside the local network, the IP address of
+ * the gateway is used.
+ *
+ * @param netif The lwIP network interface which the IP packet will be sent on.
+ * @param q The pbuf(s) containing the IP packet to be sent.
+ * @param ipaddr The IP address of the packet destination.
+ *
+ * @return
+ * - ERR_RTE No route to destination (no gateway to external networks),
+ * or the return type of either etharp_query() or ethernet_output().
+ */
+err_t
+etharp_output(struct netif *netif, struct pbuf *q, const ip4_addr_t *ipaddr)
+{
+  const struct eth_addr *dest;
+  struct eth_addr mcastaddr;
+  const ip4_addr_t *dst_addr = ipaddr;
+
+  LWIP_ASSERT_CORE_LOCKED();
+  LWIP_ASSERT("netif != NULL", netif != NULL);
+  LWIP_ASSERT("q != NULL", q != NULL);
+  LWIP_ASSERT("ipaddr != NULL", ipaddr != NULL);
+
+  /* Determine on destination hardware address. Broadcasts and multicasts
+   * are special, other IP addresses are looked up in the ARP table. */
+
+  /* broadcast destination IP address? */
+  if (ip4_addr_isbroadcast(ipaddr, netif)) {
+    /* broadcast on Ethernet also */
+    dest = (const struct eth_addr *)&ethbroadcast;
+    /* multicast destination IP address? */
+  } else if (ip4_addr_ismulticast(ipaddr)) {
+    /* Hash IP multicast address to MAC address.*/
+    mcastaddr.addr[0] = LL_IP4_MULTICAST_ADDR_0;
+    mcastaddr.addr[1] = LL_IP4_MULTICAST_ADDR_1;
+    mcastaddr.addr[2] = LL_IP4_MULTICAST_ADDR_2;
+    mcastaddr.addr[3] = ip4_addr2(ipaddr) & 0x7f;
+    mcastaddr.addr[4] = ip4_addr3(ipaddr);
+    mcastaddr.addr[5] = ip4_addr4(ipaddr);
+    /* destination Ethernet address is multicast */
+    dest = &mcastaddr;
+    /* unicast destination IP address? */
+  } else {
+    netif_addr_idx_t i;
+    /* outside local network? if so, this can neither be a global broadcast nor
+       a subnet broadcast. */
+    if (!ip4_addr_netcmp(ipaddr, netif_ip4_addr(netif), netif_ip4_netmask(netif)) &&
+        !ip4_addr_islinklocal(ipaddr)) {
+#if LWIP_AUTOIP
+      struct ip_hdr *iphdr = LWIP_ALIGNMENT_CAST(struct ip_hdr *, q->payload);
+      /* According to RFC 3297, chapter 2.6.2 (Forwarding Rules), a packet with
+         a link-local source address must always be "directly to its destination
+         on the same physical link. The host MUST NOT send the packet to any
+         router for forwarding". */
+      if (!ip4_addr_islinklocal(&iphdr->src))
+#endif /* LWIP_AUTOIP */
+      {
+#ifdef LWIP_HOOK_ETHARP_GET_GW
+        /* For advanced routing, a single default gateway might not be enough, so get
+           the IP address of the gateway to handle the current destination address. */
+        dst_addr = LWIP_HOOK_ETHARP_GET_GW(netif, ipaddr);
+        if (dst_addr == NULL)
+#endif /* LWIP_HOOK_ETHARP_GET_GW */
+        {
+          /* interface has default gateway? */
+          if (!ip4_addr_isany_val(*netif_ip4_gw(netif))) {
+            /* send to hardware address of default gateway IP address */
+            dst_addr = netif_ip4_gw(netif);
+            /* no default gateway available */
+          } else {
+            /* no route to destination error (default gateway missing) */
+            return ERR_RTE;
+          }
+        }
+      }
+    }
+#if LWIP_NETIF_HWADDRHINT
+    if (netif->hints != NULL) {
+      /* per-pcb cached entry was given */
+      netif_addr_idx_t etharp_cached_entry = netif->hints->addr_hint;
+      if (etharp_cached_entry < ARP_TABLE_SIZE) {
+#endif /* LWIP_NETIF_HWADDRHINT */
+        if ((arp_table[etharp_cached_entry].state >= ETHARP_STATE_STABLE) &&
+#if ETHARP_TABLE_MATCH_NETIF
+            (arp_table[etharp_cached_entry].netif == netif) &&
+#endif
+            (ip4_addr_cmp(dst_addr, &arp_table[etharp_cached_entry].ipaddr))) {
+          /* the per-pcb-cached entry is stable and the right one! */
+          ETHARP_STATS_INC(etharp.cachehit);
+          return etharp_output_to_arp_index(netif, q, etharp_cached_entry);
+        }
+#if LWIP_NETIF_HWADDRHINT
+      }
+    }
+#endif /* LWIP_NETIF_HWADDRHINT */
+
+    /* find stable entry: do this here since this is a critical path for
+       throughput and etharp_find_entry() is kind of slow */
+    for (i = 0; i < ARP_TABLE_SIZE; i++) {
+      if ((arp_table[i].state >= ETHARP_STATE_STABLE) &&
+#if ETHARP_TABLE_MATCH_NETIF
+          (arp_table[i].netif == netif) &&
+#endif
+          (ip4_addr_cmp(dst_addr, &arp_table[i].ipaddr))) {
+        /* found an existing, stable entry */
+        ETHARP_SET_ADDRHINT(netif, i);
+        return etharp_output_to_arp_index(netif, q, i);
+      }
+    }
+    /* no stable entry found, use the (slower) query function:
+       queue on destination Ethernet address belonging to ipaddr */
+    return etharp_query(netif, dst_addr, q);
+  }
+
+  /* continuation for multicast/broadcast destinations */
+  /* obtain source Ethernet address of the given interface */
+  /* send packet directly on the link */
+  return ethernet_output(netif, q, (struct eth_addr *)(netif->hwaddr), dest, ETHTYPE_IP);
+}
+
+/**
+ * Send an ARP request for the given IP address and/or queue a packet.
+ *
+ * If the IP address was not yet in the cache, a pending ARP cache entry
+ * is added and an ARP request is sent for the given address. The packet
+ * is queued on this entry.
+ *
+ * If the IP address was already pending in the cache, a new ARP request
+ * is sent for the given address. The packet is queued on this entry.
+ *
+ * If the IP address was already stable in the cache, and a packet is
+ * given, it is directly sent and no ARP request is sent out.
+ *
+ * If the IP address was already stable in the cache, and no packet is
+ * given, an ARP request is sent out.
+ *
+ * @param netif The lwIP network interface on which ipaddr
+ * must be queried for.
+ * @param ipaddr The IP address to be resolved.
+ * @param q If non-NULL, a pbuf that must be delivered to the IP address.
+ * q is not freed by this function.
+ *
+ * @note q must only be ONE packet, not a packet queue!
+ *
+ * @return
+ * - ERR_BUF Could not make room for Ethernet header.
+ * - ERR_MEM Hardware address unknown, and no more ARP entries available
+ *   to query for address or queue the packet.
+ * - ERR_MEM Could not queue packet due to memory shortage.
+ * - ERR_RTE No route to destination (no gateway to external networks).
+ * - ERR_ARG Non-unicast address given, those will not appear in ARP cache.
+ *
+ */
+err_t
+etharp_query(struct netif *netif, const ip4_addr_t *ipaddr, struct pbuf *q)
+{
+  struct eth_addr *srcaddr = (struct eth_addr *)netif->hwaddr;
+  err_t result = ERR_MEM;
+  int is_new_entry = 0;
+  s16_t i_err;
+  netif_addr_idx_t i;
+
+  /* non-unicast address? */
+  if (ip4_addr_isbroadcast(ipaddr, netif) ||
+      ip4_addr_ismulticast(ipaddr) ||
+      ip4_addr_isany(ipaddr)) {
+    LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_query: will not add non-unicast IP address to ARP cache\n"));
+    return ERR_ARG;
+  }
+
+  /* find entry in ARP cache, ask to create entry if queueing packet */
+  i_err = etharp_find_entry(ipaddr, ETHARP_FLAG_TRY_HARD, netif);
+
+  /* could not find or create entry? */
+  if (i_err < 0) {
+    LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_query: could not create ARP entry\n"));
+    if (q) {
+      LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_query: packet dropped\n"));
+      ETHARP_STATS_INC(etharp.memerr);
+    }
+    return (err_t)i_err;
+  }
+  LWIP_ASSERT("type overflow", (size_t)i_err < NETIF_ADDR_IDX_MAX);
+  i = (netif_addr_idx_t)i_err;
+
+  /* mark a fresh entry as pending (we just sent a request) */
+  if (arp_table[i].state == ETHARP_STATE_EMPTY) {
+    is_new_entry = 1;
+    arp_table[i].state = ETHARP_STATE_PENDING;
+    /* record network interface for re-sending arp request in etharp_tmr */
+    arp_table[i].netif = netif;
+  }
+
+  /* { i is either a STABLE or (new or existing) PENDING entry } */
+  LWIP_ASSERT("arp_table[i].state == PENDING or STABLE",
+              ((arp_table[i].state == ETHARP_STATE_PENDING) ||
+               (arp_table[i].state >= ETHARP_STATE_STABLE)));
+
+  /* do we have a new entry? or an implicit query request? */
+  if (is_new_entry || (q == NULL)) {
+    /* try to resolve it; send out ARP request */
+    result = etharp_request(netif, ipaddr);
+    if (result != ERR_OK) {
+      /* ARP request couldn't be sent */
+      /* We don't re-send arp request in etharp_tmr, but we still queue packets,
+         since this failure could be temporary, and the next packet calling
+         etharp_query again could lead to sending the queued packets. */
+    }
+    if (q == NULL) {
+      return result;
+    }
+  }
+
+  /* packet given? */
+  LWIP_ASSERT("q != NULL", q != NULL);
+  /* stable entry? */
+  if (arp_table[i].state >= ETHARP_STATE_STABLE) {
+    /* we have a valid IP->Ethernet address mapping */
+    ETHARP_SET_ADDRHINT(netif, i);
+    /* send the packet */
+    result = ethernet_output(netif, q, srcaddr, &(arp_table[i].ethaddr), ETHTYPE_IP);
+    /* pending entry? (either just created or already pending */
+  } else if (arp_table[i].state == ETHARP_STATE_PENDING) {
+    /* entry is still pending, queue the given packet 'q' */
+    struct pbuf *p;
+    int copy_needed = 0;
+    /* IF q includes a pbuf that must be copied, copy the whole chain into a
+     * new PBUF_RAM. See the definition of PBUF_NEEDS_COPY for details. */
+    p = q;
+    while (p) {
+      LWIP_ASSERT("no packet queues allowed!", (p->len != p->tot_len) || (p->next == 0));
+      if (PBUF_NEEDS_COPY(p)) {
+        copy_needed = 1;
+        break;
+      }
+      p = p->next;
+    }
+    if (copy_needed) {
+      /* copy the whole packet into new pbufs */
+      p = pbuf_clone(PBUF_LINK, PBUF_RAM, q);
+    } else {
+      /* referencing the old pbuf is enough */
+      p = q;
+      pbuf_ref(p);
+    }
+    /* packet could be taken over? */
+    if (p != NULL) {
+      /* queue packet ... */
+#if ARP_QUEUEING
+      struct etharp_q_entry *new_entry;
+      /* allocate a new arp queue entry */
+      new_entry = (struct etharp_q_entry *)memp_malloc(MEMP_ARP_QUEUE);
+      if (new_entry != NULL) {
+        unsigned int qlen = 0;
+        new_entry->next = 0;
+        new_entry->p = p;
+        if (arp_table[i].q != NULL) {
+          /* queue was already existent, append the new entry to the end */
+          struct etharp_q_entry *r;
+          r = arp_table[i].q;
+          qlen++;
+          while (r->next != NULL) {
+            r = r->next;
+            qlen++;
+          }
+          r->next = new_entry;
+        } else {
+          /* queue did not exist, first item in queue */
+          arp_table[i].q = new_entry;
+        }
+#if ARP_QUEUE_LEN
+        if (qlen >= ARP_QUEUE_LEN) {
+          struct etharp_q_entry *old;
+          old = arp_table[i].q;
+          arp_table[i].q = arp_table[i].q->next;
+          pbuf_free(old->p);
+          memp_free(MEMP_ARP_QUEUE, old);
+        }
+#endif
+        LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_query: queued packet %p on ARP entry %"U16_F"\n", (void *)q, i));
+        result = ERR_OK;
+      } else {
+        /* the pool MEMP_ARP_QUEUE is empty */
+        pbuf_free(p);
+        LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_query: could not queue a copy of PBUF_REF packet %p (out of memory)\n", (void *)q));
+        result = ERR_MEM;
+      }
+#else /* ARP_QUEUEING */
+      /* always queue one packet per ARP request only, freeing a previously queued packet */
+      if (arp_table[i].q != NULL) {
+        LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_query: dropped previously queued packet %p for ARP entry %"U16_F"\n", (void *)q, (u16_t)i));
+        pbuf_free(arp_table[i].q);
+      }
+      arp_table[i].q = p;
+      result = ERR_OK;
+      LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_query: queued packet %p on ARP entry %"U16_F"\n", (void *)q, (u16_t)i));
+#endif /* ARP_QUEUEING */
+    } else {
+      ETHARP_STATS_INC(etharp.memerr);
+      LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_query: could not queue a copy of PBUF_REF packet %p (out of memory)\n", (void *)q));
+      result = ERR_MEM;
+    }
+  }
+  return result;
+}
+
+/**
+ * Send a raw ARP packet (opcode and all addresses can be modified)
+ *
+ * @param netif the lwip network interface on which to send the ARP packet
+ * @param ethsrc_addr the source MAC address for the ethernet header
+ * @param ethdst_addr the destination MAC address for the ethernet header
+ * @param hwsrc_addr the source MAC address for the ARP protocol header
+ * @param ipsrc_addr the source IP address for the ARP protocol header
+ * @param hwdst_addr the destination MAC address for the ARP protocol header
+ * @param ipdst_addr the destination IP address for the ARP protocol header
+ * @param opcode the type of the ARP packet
+ * @return ERR_OK if the ARP packet has been sent
+ *         ERR_MEM if the ARP packet couldn't be allocated
+ *         any other err_t on failure
+ */
+static err_t
+etharp_raw(struct netif *netif, const struct eth_addr *ethsrc_addr,
+           const struct eth_addr *ethdst_addr,
+           const struct eth_addr *hwsrc_addr, const ip4_addr_t *ipsrc_addr,
+           const struct eth_addr *hwdst_addr, const ip4_addr_t *ipdst_addr,
+           const u16_t opcode)
+{
+  struct pbuf *p;
+  err_t result = ERR_OK;
+  struct etharp_hdr *hdr;
+
+  LWIP_ASSERT("netif != NULL", netif != NULL);
+
+  /* allocate a pbuf for the outgoing ARP request packet */
+  p = pbuf_alloc(PBUF_LINK, SIZEOF_ETHARP_HDR, PBUF_RAM);
+  /* could allocate a pbuf for an ARP request? */
+  if (p == NULL) {
+    LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS,
+                ("etharp_raw: could not allocate pbuf for ARP request.\n"));
+    ETHARP_STATS_INC(etharp.memerr);
+    return ERR_MEM;
+  }
+  LWIP_ASSERT("check that first pbuf can hold struct etharp_hdr",
+              (p->len >= SIZEOF_ETHARP_HDR));
+
+  hdr = (struct etharp_hdr *)p->payload;
+  LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_raw: sending raw ARP packet.\n"));
+  hdr->opcode = lwip_htons(opcode);
+
+  LWIP_ASSERT("netif->hwaddr_len must be the same as ETH_HWADDR_LEN for etharp!",
+              (netif->hwaddr_len == ETH_HWADDR_LEN));
+
+  /* Write the ARP MAC-Addresses */
+  SMEMCPY(&hdr->shwaddr, hwsrc_addr, ETH_HWADDR_LEN);
+  SMEMCPY(&hdr->dhwaddr, hwdst_addr, ETH_HWADDR_LEN);
+  /* Copy struct ip4_addr_wordaligned to aligned ip4_addr, to support compilers without
+   * structure packing. */
+  IPADDR_WORDALIGNED_COPY_FROM_IP4_ADDR_T(&hdr->sipaddr, ipsrc_addr);
+  IPADDR_WORDALIGNED_COPY_FROM_IP4_ADDR_T(&hdr->dipaddr, ipdst_addr);
+
+  hdr->hwtype = PP_HTONS(LWIP_IANA_HWTYPE_ETHERNET);
+  hdr->proto = PP_HTONS(ETHTYPE_IP);
+  /* set hwlen and protolen */
+  hdr->hwlen = ETH_HWADDR_LEN;
+  hdr->protolen = sizeof(ip4_addr_t);
+
+  /* send ARP query */
+#if LWIP_AUTOIP
+  /* If we are using Link-Local, all ARP packets that contain a Link-Local
+   * 'sender IP address' MUST be sent using link-layer broadcast instead of
+   * link-layer unicast. (See RFC3927 Section 2.5, last paragraph) */
+  if (ip4_addr_islinklocal(ipsrc_addr)) {
+    ethernet_output(netif, p, ethsrc_addr, &ethbroadcast, ETHTYPE_ARP);
+  } else
+#endif /* LWIP_AUTOIP */
+  {
+    ethernet_output(netif, p, ethsrc_addr, ethdst_addr, ETHTYPE_ARP);
+  }
+
+  ETHARP_STATS_INC(etharp.xmit);
+  /* free ARP query packet */
+  pbuf_free(p);
+  p = NULL;
+  /* could not allocate pbuf for ARP request */
+
+  return result;
+}
+
+/**
+ * Send an ARP request packet asking for ipaddr to a specific eth address.
+ * Used to send unicast request to refresh the ARP table just before an entry
+ * times out
+ *
+ * @param netif the lwip network interface on which to send the request
+ * @param ipaddr the IP address for which to ask
+ * @param hw_dst_addr the ethernet address to send this packet to
+ * @return ERR_OK if the request has been sent
+ *         ERR_MEM if the ARP packet couldn't be allocated
+ *         any other err_t on failure
+ */
+static err_t
+etharp_request_dst(struct netif *netif, const ip4_addr_t *ipaddr, const struct eth_addr *hw_dst_addr)
+{
+  return etharp_raw(netif, (struct eth_addr *)netif->hwaddr, hw_dst_addr,
+                    (struct eth_addr *)netif->hwaddr, netif_ip4_addr(netif), &ethzero,
+                    ipaddr, ARP_REQUEST);
+}
+
+/**
+ * Send an ARP request packet asking for ipaddr.
+ *
+ * @param netif the lwip network interface on which to send the request
+ * @param ipaddr the IP address for which to ask
+ * @return ERR_OK if the request has been sent
+ *         ERR_MEM if the ARP packet couldn't be allocated
+ *         any other err_t on failure
+ */
+err_t
+etharp_request(struct netif *netif, const ip4_addr_t *ipaddr)
+{
+  LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_request: sending ARP request.\n"));
+  return etharp_request_dst(netif, ipaddr, &ethbroadcast);
+}
+
+#endif /* LWIP_IPV4 && LWIP_ARP */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/core/ipv4/icmp.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/core/ipv4/icmp.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/core/ipv4/icmp.c	(revision 457)
@@ -0,0 +1,404 @@
+/**
+ * @file
+ * ICMP - Internet Control Message Protocol
+ *
+ */
+
+/*
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Adam Dunkels <adam@sics.se>
+ *
+ */
+
+/* Some ICMP messages should be passed to the transport protocols. This
+   is not implemented. */
+
+#include "lwip/opt.h"
+
+#if LWIP_IPV4 && LWIP_ICMP /* don't build if not configured for use in lwipopts.h */
+
+#include "lwip/icmp.h"
+#include "lwip/inet_chksum.h"
+#include "lwip/ip.h"
+#include "lwip/def.h"
+#include "lwip/stats.h"
+
+#include <string.h>
+
+#ifdef LWIP_HOOK_FILENAME
+#include LWIP_HOOK_FILENAME
+#endif
+
+/** Small optimization: set to 0 if incoming PBUF_POOL pbuf always can be
+ * used to modify and send a response packet (and to 1 if this is not the case,
+ * e.g. when link header is stripped off when receiving) */
+#ifndef LWIP_ICMP_ECHO_CHECK_INPUT_PBUF_LEN
+#define LWIP_ICMP_ECHO_CHECK_INPUT_PBUF_LEN 1
+#endif /* LWIP_ICMP_ECHO_CHECK_INPUT_PBUF_LEN */
+
+/* The amount of data from the original packet to return in a dest-unreachable */
+#define ICMP_DEST_UNREACH_DATASIZE 8
+
+static void icmp_send_response(struct pbuf *p, u8_t type, u8_t code);
+
+/**
+ * Processes ICMP input packets, called from ip_input().
+ *
+ * Currently only processes icmp echo requests and sends
+ * out the echo response.
+ *
+ * @param p the icmp echo request packet, p->payload pointing to the icmp header
+ * @param inp the netif on which this packet was received
+ */
+void
+icmp_input(struct pbuf *p, struct netif *inp)
+{
+  u8_t type;
+#ifdef LWIP_DEBUG
+  u8_t code;
+#endif /* LWIP_DEBUG */
+  struct icmp_echo_hdr *iecho;
+  const struct ip_hdr *iphdr_in;
+  u16_t hlen;
+  const ip4_addr_t *src;
+
+  ICMP_STATS_INC(icmp.recv);
+  MIB2_STATS_INC(mib2.icmpinmsgs);
+
+  iphdr_in = ip4_current_header();
+  hlen = IPH_HL_BYTES(iphdr_in);
+  if (hlen < IP_HLEN) {
+    LWIP_DEBUGF(ICMP_DEBUG, ("icmp_input: short IP header (%"S16_F" bytes) received\n", hlen));
+    goto lenerr;
+  }
+  if (p->len < sizeof(u16_t) * 2) {
+    LWIP_DEBUGF(ICMP_DEBUG, ("icmp_input: short ICMP (%"U16_F" bytes) received\n", p->tot_len));
+    goto lenerr;
+  }
+
+  type = *((u8_t *)p->payload);
+#ifdef LWIP_DEBUG
+  code = *(((u8_t *)p->payload) + 1);
+  /* if debug is enabled but debug statement below is somehow disabled: */
+  LWIP_UNUSED_ARG(code);
+#endif /* LWIP_DEBUG */
+  switch (type) {
+    case ICMP_ER:
+      /* This is OK, echo reply might have been parsed by a raw PCB
+         (as obviously, an echo request has been sent, too). */
+      MIB2_STATS_INC(mib2.icmpinechoreps);
+      break;
+    case ICMP_ECHO:
+      MIB2_STATS_INC(mib2.icmpinechos);
+      src = ip4_current_dest_addr();
+      /* multicast destination address? */
+      if (ip4_addr_ismulticast(ip4_current_dest_addr())) {
+#if LWIP_MULTICAST_PING
+        /* For multicast, use address of receiving interface as source address */
+        src = netif_ip4_addr(inp);
+#else /* LWIP_MULTICAST_PING */
+        LWIP_DEBUGF(ICMP_DEBUG, ("icmp_input: Not echoing to multicast pings\n"));
+        goto icmperr;
+#endif /* LWIP_MULTICAST_PING */
+      }
+      /* broadcast destination address? */
+      if (ip4_addr_isbroadcast(ip4_current_dest_addr(), ip_current_netif())) {
+#if LWIP_BROADCAST_PING
+        /* For broadcast, use address of receiving interface as source address */
+        src = netif_ip4_addr(inp);
+#else /* LWIP_BROADCAST_PING */
+        LWIP_DEBUGF(ICMP_DEBUG, ("icmp_input: Not echoing to broadcast pings\n"));
+        goto icmperr;
+#endif /* LWIP_BROADCAST_PING */
+      }
+      LWIP_DEBUGF(ICMP_DEBUG, ("icmp_input: ping\n"));
+      if (p->tot_len < sizeof(struct icmp_echo_hdr)) {
+        LWIP_DEBUGF(ICMP_DEBUG, ("icmp_input: bad ICMP echo received\n"));
+        goto lenerr;
+      }
+#if CHECKSUM_CHECK_ICMP
+      IF__NETIF_CHECKSUM_ENABLED(inp, NETIF_CHECKSUM_CHECK_ICMP) {
+        if (inet_chksum_pbuf(p) != 0) {
+          LWIP_DEBUGF(ICMP_DEBUG, ("icmp_input: checksum failed for received ICMP echo\n"));
+          pbuf_free(p);
+          ICMP_STATS_INC(icmp.chkerr);
+          MIB2_STATS_INC(mib2.icmpinerrors);
+          return;
+        }
+      }
+#endif
+#if LWIP_ICMP_ECHO_CHECK_INPUT_PBUF_LEN
+      if (pbuf_add_header(p, hlen + PBUF_LINK_HLEN + PBUF_LINK_ENCAPSULATION_HLEN)) {
+        /* p is not big enough to contain link headers
+         * allocate a new one and copy p into it
+         */
+        struct pbuf *r;
+        u16_t alloc_len = (u16_t)(p->tot_len + hlen);
+        if (alloc_len < p->tot_len) {
+          LWIP_DEBUGF(ICMP_DEBUG, ("icmp_input: allocating new pbuf failed (tot_len overflow)\n"));
+          goto icmperr;
+        }
+        /* allocate new packet buffer with space for link headers */
+        r = pbuf_alloc(PBUF_LINK, alloc_len, PBUF_RAM);
+        if (r == NULL) {
+          LWIP_DEBUGF(ICMP_DEBUG, ("icmp_input: allocating new pbuf failed\n"));
+          goto icmperr;
+        }
+        if (r->len < hlen + sizeof(struct icmp_echo_hdr)) {
+          LWIP_DEBUGF(ICMP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("first pbuf cannot hold the ICMP header"));
+          pbuf_free(r);
+          goto icmperr;
+        }
+        /* copy the ip header */
+        MEMCPY(r->payload, iphdr_in, hlen);
+        /* switch r->payload back to icmp header (cannot fail) */
+        if (pbuf_remove_header(r, hlen)) {
+          LWIP_ASSERT("icmp_input: moving r->payload to icmp header failed\n", 0);
+          pbuf_free(r);
+          goto icmperr;
+        }
+        /* copy the rest of the packet without ip header */
+        if (pbuf_copy(r, p) != ERR_OK) {
+          LWIP_DEBUGF(ICMP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("icmp_input: copying to new pbuf failed"));
+          pbuf_free(r);
+          goto icmperr;
+        }
+        /* free the original p */
+        pbuf_free(p);
+        /* we now have an identical copy of p that has room for link headers */
+        p = r;
+      } else {
+        /* restore p->payload to point to icmp header (cannot fail) */
+        if (pbuf_remove_header(p, hlen + PBUF_LINK_HLEN + PBUF_LINK_ENCAPSULATION_HLEN)) {
+          LWIP_ASSERT("icmp_input: restoring original p->payload failed\n", 0);
+          goto icmperr;
+        }
+      }
+#endif /* LWIP_ICMP_ECHO_CHECK_INPUT_PBUF_LEN */
+      /* At this point, all checks are OK. */
+      /* We generate an answer by switching the dest and src ip addresses,
+       * setting the icmp type to ECHO_RESPONSE and updating the checksum. */
+      iecho = (struct icmp_echo_hdr *)p->payload;
+      if (pbuf_add_header(p, hlen)) {
+        LWIP_DEBUGF(ICMP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("Can't move over header in packet"));
+      } else {
+        err_t ret;
+        struct ip_hdr *iphdr = (struct ip_hdr *)p->payload;
+        ip4_addr_copy(iphdr->src, *src);
+        ip4_addr_copy(iphdr->dest, *ip4_current_src_addr());
+        ICMPH_TYPE_SET(iecho, ICMP_ER);
+#if CHECKSUM_GEN_ICMP
+        IF__NETIF_CHECKSUM_ENABLED(inp, NETIF_CHECKSUM_GEN_ICMP) {
+          /* adjust the checksum */
+          if (iecho->chksum > PP_HTONS(0xffffU - (ICMP_ECHO << 8))) {
+            iecho->chksum = (u16_t)(iecho->chksum + PP_HTONS((u16_t)(ICMP_ECHO << 8)) + 1);
+          } else {
+            iecho->chksum = (u16_t)(iecho->chksum + PP_HTONS(ICMP_ECHO << 8));
+          }
+        }
+#if LWIP_CHECKSUM_CTRL_PER_NETIF
+        else {
+          iecho->chksum = 0;
+        }
+#endif /* LWIP_CHECKSUM_CTRL_PER_NETIF */
+#else /* CHECKSUM_GEN_ICMP */
+        iecho->chksum = 0;
+#endif /* CHECKSUM_GEN_ICMP */
+
+        /* Set the correct TTL and recalculate the header checksum. */
+        IPH_TTL_SET(iphdr, ICMP_TTL);
+        IPH_CHKSUM_SET(iphdr, 0);
+#if CHECKSUM_GEN_IP
+        IF__NETIF_CHECKSUM_ENABLED(inp, NETIF_CHECKSUM_GEN_IP) {
+          IPH_CHKSUM_SET(iphdr, inet_chksum(iphdr, hlen));
+        }
+#endif /* CHECKSUM_GEN_IP */
+
+        ICMP_STATS_INC(icmp.xmit);
+        /* increase number of messages attempted to send */
+        MIB2_STATS_INC(mib2.icmpoutmsgs);
+        /* increase number of echo replies attempted to send */
+        MIB2_STATS_INC(mib2.icmpoutechoreps);
+
+        /* send an ICMP packet */
+        ret = ip4_output_if(p, src, LWIP_IP_HDRINCL,
+                            ICMP_TTL, 0, IP_PROTO_ICMP, inp);
+        if (ret != ERR_OK) {
+          LWIP_DEBUGF(ICMP_DEBUG, ("icmp_input: ip_output_if returned an error: %s\n", lwip_strerr(ret)));
+        }
+      }
+      break;
+    default:
+      if (type == ICMP_DUR) {
+        MIB2_STATS_INC(mib2.icmpindestunreachs);
+      } else if (type == ICMP_TE) {
+        MIB2_STATS_INC(mib2.icmpintimeexcds);
+      } else if (type == ICMP_PP) {
+        MIB2_STATS_INC(mib2.icmpinparmprobs);
+      } else if (type == ICMP_SQ) {
+        MIB2_STATS_INC(mib2.icmpinsrcquenchs);
+      } else if (type == ICMP_RD) {
+        MIB2_STATS_INC(mib2.icmpinredirects);
+      } else if (type == ICMP_TS) {
+        MIB2_STATS_INC(mib2.icmpintimestamps);
+      } else if (type == ICMP_TSR) {
+        MIB2_STATS_INC(mib2.icmpintimestampreps);
+      } else if (type == ICMP_AM) {
+        MIB2_STATS_INC(mib2.icmpinaddrmasks);
+      } else if (type == ICMP_AMR) {
+        MIB2_STATS_INC(mib2.icmpinaddrmaskreps);
+      }
+      LWIP_DEBUGF(ICMP_DEBUG, ("icmp_input: ICMP type %"S16_F" code %"S16_F" not supported.\n",
+                               (s16_t)type, (s16_t)code));
+      ICMP_STATS_INC(icmp.proterr);
+      ICMP_STATS_INC(icmp.drop);
+  }
+  pbuf_free(p);
+  return;
+lenerr:
+  pbuf_free(p);
+  ICMP_STATS_INC(icmp.lenerr);
+  MIB2_STATS_INC(mib2.icmpinerrors);
+  return;
+#if LWIP_ICMP_ECHO_CHECK_INPUT_PBUF_LEN || !LWIP_MULTICAST_PING || !LWIP_BROADCAST_PING
+icmperr:
+  pbuf_free(p);
+  ICMP_STATS_INC(icmp.err);
+  MIB2_STATS_INC(mib2.icmpinerrors);
+  return;
+#endif /* LWIP_ICMP_ECHO_CHECK_INPUT_PBUF_LEN || !LWIP_MULTICAST_PING || !LWIP_BROADCAST_PING */
+}
+
+/**
+ * Send an icmp 'destination unreachable' packet, called from ip_input() if
+ * the transport layer protocol is unknown and from udp_input() if the local
+ * port is not bound.
+ *
+ * @param p the input packet for which the 'unreachable' should be sent,
+ *          p->payload pointing to the IP header
+ * @param t type of the 'unreachable' packet
+ */
+void
+icmp_dest_unreach(struct pbuf *p, enum icmp_dur_type t)
+{
+  MIB2_STATS_INC(mib2.icmpoutdestunreachs);
+  icmp_send_response(p, ICMP_DUR, t);
+}
+
+#if IP_FORWARD || IP_REASSEMBLY
+/**
+ * Send a 'time exceeded' packet, called from ip_forward() if TTL is 0.
+ *
+ * @param p the input packet for which the 'time exceeded' should be sent,
+ *          p->payload pointing to the IP header
+ * @param t type of the 'time exceeded' packet
+ */
+void
+icmp_time_exceeded(struct pbuf *p, enum icmp_te_type t)
+{
+  MIB2_STATS_INC(mib2.icmpouttimeexcds);
+  icmp_send_response(p, ICMP_TE, t);
+}
+
+#endif /* IP_FORWARD || IP_REASSEMBLY */
+
+/**
+ * Send an icmp packet in response to an incoming packet.
+ *
+ * @param p the input packet for which the 'unreachable' should be sent,
+ *          p->payload pointing to the IP header
+ * @param type Type of the ICMP header
+ * @param code Code of the ICMP header
+ */
+static void
+icmp_send_response(struct pbuf *p, u8_t type, u8_t code)
+{
+  struct pbuf *q;
+  struct ip_hdr *iphdr;
+  /* we can use the echo header here */
+  struct icmp_echo_hdr *icmphdr;
+  ip4_addr_t iphdr_src;
+  struct netif *netif;
+
+  /* increase number of messages attempted to send */
+  MIB2_STATS_INC(mib2.icmpoutmsgs);
+
+  /* ICMP header + IP header + 8 bytes of data */
+  q = pbuf_alloc(PBUF_IP, sizeof(struct icmp_echo_hdr) + IP_HLEN + ICMP_DEST_UNREACH_DATASIZE,
+                 PBUF_RAM);
+  if (q == NULL) {
+    LWIP_DEBUGF(ICMP_DEBUG, ("icmp_time_exceeded: failed to allocate pbuf for ICMP packet.\n"));
+    MIB2_STATS_INC(mib2.icmpouterrors);
+    return;
+  }
+  LWIP_ASSERT("check that first pbuf can hold icmp message",
+              (q->len >= (sizeof(struct icmp_echo_hdr) + IP_HLEN + ICMP_DEST_UNREACH_DATASIZE)));
+
+  iphdr = (struct ip_hdr *)p->payload;
+  LWIP_DEBUGF(ICMP_DEBUG, ("icmp_time_exceeded from "));
+  ip4_addr_debug_print_val(ICMP_DEBUG, iphdr->src);
+  LWIP_DEBUGF(ICMP_DEBUG, (" to "));
+  ip4_addr_debug_print_val(ICMP_DEBUG, iphdr->dest);
+  LWIP_DEBUGF(ICMP_DEBUG, ("\n"));
+
+  icmphdr = (struct icmp_echo_hdr *)q->payload;
+  icmphdr->type = type;
+  icmphdr->code = code;
+  icmphdr->id = 0;
+  icmphdr->seqno = 0;
+
+  /* copy fields from original packet */
+  SMEMCPY((u8_t *)q->payload + sizeof(struct icmp_echo_hdr), (u8_t *)p->payload,
+          IP_HLEN + ICMP_DEST_UNREACH_DATASIZE);
+
+  ip4_addr_copy(iphdr_src, iphdr->src);
+#ifdef LWIP_HOOK_IP4_ROUTE_SRC
+  {
+    ip4_addr_t iphdr_dst;
+    ip4_addr_copy(iphdr_dst, iphdr->dest);
+    netif = ip4_route_src(&iphdr_dst, &iphdr_src);
+  }
+#else
+  netif = ip4_route(&iphdr_src);
+#endif
+  if (netif != NULL) {
+    /* calculate checksum */
+    icmphdr->chksum = 0;
+#if CHECKSUM_GEN_ICMP
+    IF__NETIF_CHECKSUM_ENABLED(netif, NETIF_CHECKSUM_GEN_ICMP) {
+      icmphdr->chksum = inet_chksum(icmphdr, q->len);
+    }
+#endif
+    ICMP_STATS_INC(icmp.xmit);
+    ip4_output_if(q, NULL, &iphdr_src, ICMP_TTL, 0, IP_PROTO_ICMP, netif);
+  }
+  pbuf_free(q);
+}
+
+#endif /* LWIP_IPV4 && LWIP_ICMP */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/core/ipv4/igmp.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/core/ipv4/igmp.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/core/ipv4/igmp.c	(revision 457)
@@ -0,0 +1,801 @@
+/**
+ * @file
+ * IGMP - Internet Group Management Protocol
+ *
+ * @defgroup igmp IGMP
+ * @ingroup ip4
+ * To be called from TCPIP thread
+ */
+
+/*
+ * Copyright (c) 2002 CITEL Technologies Ltd.
+ * 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 CITEL Technologies Ltd 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 CITEL TECHNOLOGIES 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 CITEL TECHNOLOGIES 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.
+ *
+ * This file is a contribution to the lwIP TCP/IP stack.
+ * The Swedish Institute of Computer Science and Adam Dunkels
+ * are specifically granted permission to redistribute this
+ * source code.
+*/
+
+/*-------------------------------------------------------------
+Note 1)
+Although the rfc requires V1 AND V2 capability
+we will only support v2 since now V1 is very old (August 1989)
+V1 can be added if required
+
+a debug print and statistic have been implemented to
+show this up.
+-------------------------------------------------------------
+-------------------------------------------------------------
+Note 2)
+A query for a specific group address (as opposed to ALLHOSTS)
+has now been implemented as I am unsure if it is required
+
+a debug print and statistic have been implemented to
+show this up.
+-------------------------------------------------------------
+-------------------------------------------------------------
+Note 3)
+The router alert rfc 2113 is implemented in outgoing packets
+but not checked rigorously incoming
+-------------------------------------------------------------
+Steve Reynolds
+------------------------------------------------------------*/
+
+/*-----------------------------------------------------------------------------
+ * RFC 988  - Host extensions for IP multicasting                         - V0
+ * RFC 1054 - Host extensions for IP multicasting                         -
+ * RFC 1112 - Host extensions for IP multicasting                         - V1
+ * RFC 2236 - Internet Group Management Protocol, Version 2               - V2  <- this code is based on this RFC (it's the "de facto" standard)
+ * RFC 3376 - Internet Group Management Protocol, Version 3               - V3
+ * RFC 4604 - Using Internet Group Management Protocol Version 3...       - V3+
+ * RFC 2113 - IP Router Alert Option                                      -
+ *----------------------------------------------------------------------------*/
+
+/*-----------------------------------------------------------------------------
+ * Includes
+ *----------------------------------------------------------------------------*/
+
+#include "lwip/opt.h"
+
+#if LWIP_IPV4 && LWIP_IGMP /* don't build if not configured for use in lwipopts.h */
+
+#include "lwip/igmp.h"
+#include "lwip/debug.h"
+#include "lwip/def.h"
+#include "lwip/mem.h"
+#include "lwip/ip.h"
+#include "lwip/inet_chksum.h"
+#include "lwip/netif.h"
+#include "lwip/stats.h"
+#include "lwip/prot/igmp.h"
+
+#include <string.h>
+
+static struct igmp_group *igmp_lookup_group(struct netif *ifp, const ip4_addr_t *addr);
+static err_t  igmp_remove_group(struct netif *netif, struct igmp_group *group);
+static void   igmp_timeout(struct netif *netif, struct igmp_group *group);
+static void   igmp_start_timer(struct igmp_group *group, u8_t max_time);
+static void   igmp_delaying_member(struct igmp_group *group, u8_t maxresp);
+static err_t  igmp_ip_output_if(struct pbuf *p, const ip4_addr_t *src, const ip4_addr_t *dest, struct netif *netif);
+static void   igmp_send(struct netif *netif, struct igmp_group *group, u8_t type);
+
+static ip4_addr_t     allsystems;
+static ip4_addr_t     allrouters;
+
+/**
+ * Initialize the IGMP module
+ */
+void
+igmp_init(void)
+{
+  LWIP_DEBUGF(IGMP_DEBUG, ("igmp_init: initializing\n"));
+
+  IP4_ADDR(&allsystems, 224, 0, 0, 1);
+  IP4_ADDR(&allrouters, 224, 0, 0, 2);
+}
+
+/**
+ * Start IGMP processing on interface
+ *
+ * @param netif network interface on which start IGMP processing
+ */
+err_t
+igmp_start(struct netif *netif)
+{
+  struct igmp_group *group;
+
+  LWIP_DEBUGF(IGMP_DEBUG, ("igmp_start: starting IGMP processing on if %p\n", (void *)netif));
+
+  group = igmp_lookup_group(netif, &allsystems);
+
+  if (group != NULL) {
+    group->group_state = IGMP_GROUP_IDLE_MEMBER;
+    group->use++;
+
+    /* Allow the igmp messages at the MAC level */
+    if (netif->igmp_mac_filter != NULL) {
+      LWIP_DEBUGF(IGMP_DEBUG, ("igmp_start: igmp_mac_filter(ADD "));
+      ip4_addr_debug_print_val(IGMP_DEBUG, allsystems);
+      LWIP_DEBUGF(IGMP_DEBUG, (") on if %p\n", (void *)netif));
+      netif->igmp_mac_filter(netif, &allsystems, NETIF_ADD_MAC_FILTER);
+    }
+
+    return ERR_OK;
+  }
+
+  return ERR_MEM;
+}
+
+/**
+ * Stop IGMP processing on interface
+ *
+ * @param netif network interface on which stop IGMP processing
+ */
+err_t
+igmp_stop(struct netif *netif)
+{
+  struct igmp_group *group = netif_igmp_data(netif);
+
+  netif_set_client_data(netif, LWIP_NETIF_CLIENT_DATA_INDEX_IGMP, NULL);
+
+  while (group != NULL) {
+    struct igmp_group *next = group->next; /* avoid use-after-free below */
+
+    /* disable the group at the MAC level */
+    if (netif->igmp_mac_filter != NULL) {
+      LWIP_DEBUGF(IGMP_DEBUG, ("igmp_stop: igmp_mac_filter(DEL "));
+      ip4_addr_debug_print_val(IGMP_DEBUG, group->group_address);
+      LWIP_DEBUGF(IGMP_DEBUG, (") on if %p\n", (void *)netif));
+      netif->igmp_mac_filter(netif, &(group->group_address), NETIF_DEL_MAC_FILTER);
+    }
+
+    /* free group */
+    memp_free(MEMP_IGMP_GROUP, group);
+
+    /* move to "next" */
+    group = next;
+  }
+  return ERR_OK;
+}
+
+/**
+ * Report IGMP memberships for this interface
+ *
+ * @param netif network interface on which report IGMP memberships
+ */
+void
+igmp_report_groups(struct netif *netif)
+{
+  struct igmp_group *group = netif_igmp_data(netif);
+
+  LWIP_DEBUGF(IGMP_DEBUG, ("igmp_report_groups: sending IGMP reports on if %p\n", (void *)netif));
+
+  /* Skip the first group in the list, it is always the allsystems group added in igmp_start() */
+  if (group != NULL) {
+    group = group->next;
+  }
+
+  while (group != NULL) {
+    igmp_delaying_member(group, IGMP_JOIN_DELAYING_MEMBER_TMR);
+    group = group->next;
+  }
+}
+
+/**
+ * Search for a group in the netif's igmp group list
+ *
+ * @param ifp the network interface for which to look
+ * @param addr the group ip address to search for
+ * @return a struct igmp_group* if the group has been found,
+ *         NULL if the group wasn't found.
+ */
+struct igmp_group *
+igmp_lookfor_group(struct netif *ifp, const ip4_addr_t *addr)
+{
+  struct igmp_group *group = netif_igmp_data(ifp);
+
+  while (group != NULL) {
+    if (ip4_addr_cmp(&(group->group_address), addr)) {
+      return group;
+    }
+    group = group->next;
+  }
+
+  /* to be clearer, we return NULL here instead of
+   * 'group' (which is also NULL at this point).
+   */
+  return NULL;
+}
+
+/**
+ * Search for a specific igmp group and create a new one if not found-
+ *
+ * @param ifp the network interface for which to look
+ * @param addr the group ip address to search
+ * @return a struct igmp_group*,
+ *         NULL on memory error.
+ */
+static struct igmp_group *
+igmp_lookup_group(struct netif *ifp, const ip4_addr_t *addr)
+{
+  struct igmp_group *group;
+  struct igmp_group *list_head = netif_igmp_data(ifp);
+
+  /* Search if the group already exists */
+  group = igmp_lookfor_group(ifp, addr);
+  if (group != NULL) {
+    /* Group already exists. */
+    return group;
+  }
+
+  /* Group doesn't exist yet, create a new one */
+  group = (struct igmp_group *)memp_malloc(MEMP_IGMP_GROUP);
+  if (group != NULL) {
+    ip4_addr_set(&(group->group_address), addr);
+    group->timer              = 0; /* Not running */
+    group->group_state        = IGMP_GROUP_NON_MEMBER;
+    group->last_reporter_flag = 0;
+    group->use                = 0;
+
+    /* Ensure allsystems group is always first in list */
+    if (list_head == NULL) {
+      /* this is the first entry in linked list */
+      LWIP_ASSERT("igmp_lookup_group: first group must be allsystems",
+                  (ip4_addr_cmp(addr, &allsystems) != 0));
+      group->next = NULL;
+      netif_set_client_data(ifp, LWIP_NETIF_CLIENT_DATA_INDEX_IGMP, group);
+    } else {
+      /* append _after_ first entry */
+      LWIP_ASSERT("igmp_lookup_group: all except first group must not be allsystems",
+                  (ip4_addr_cmp(addr, &allsystems) == 0));
+      group->next = list_head->next;
+      list_head->next = group;
+    }
+  }
+
+  LWIP_DEBUGF(IGMP_DEBUG, ("igmp_lookup_group: %sallocated a new group with address ", (group ? "" : "impossible to ")));
+  ip4_addr_debug_print(IGMP_DEBUG, addr);
+  LWIP_DEBUGF(IGMP_DEBUG, (" on if %p\n", (void *)ifp));
+
+  return group;
+}
+
+/**
+ * Remove a group from netif's igmp group list, but don't free it yet
+ *
+ * @param group the group to remove from the netif's igmp group list
+ * @return ERR_OK if group was removed from the list, an err_t otherwise
+ */
+static err_t
+igmp_remove_group(struct netif *netif, struct igmp_group *group)
+{
+  err_t err = ERR_OK;
+  struct igmp_group *tmp_group;
+
+  /* Skip the first group in the list, it is always the allsystems group added in igmp_start() */
+  for (tmp_group = netif_igmp_data(netif); tmp_group != NULL; tmp_group = tmp_group->next) {
+    if (tmp_group->next == group) {
+      tmp_group->next = group->next;
+      break;
+    }
+  }
+  /* Group not found in netif's igmp group list */
+  if (tmp_group == NULL) {
+    err = ERR_ARG;
+  }
+
+  return err;
+}
+
+/**
+ * Called from ip_input() if a new IGMP packet is received.
+ *
+ * @param p received igmp packet, p->payload pointing to the igmp header
+ * @param inp network interface on which the packet was received
+ * @param dest destination ip address of the igmp packet
+ */
+void
+igmp_input(struct pbuf *p, struct netif *inp, const ip4_addr_t *dest)
+{
+  struct igmp_msg   *igmp;
+  struct igmp_group *group;
+  struct igmp_group *groupref;
+
+  IGMP_STATS_INC(igmp.recv);
+
+  /* Note that the length CAN be greater than 8 but only 8 are used - All are included in the checksum */
+  if (p->len < IGMP_MINLEN) {
+    pbuf_free(p);
+    IGMP_STATS_INC(igmp.lenerr);
+    LWIP_DEBUGF(IGMP_DEBUG, ("igmp_input: length error\n"));
+    return;
+  }
+
+  LWIP_DEBUGF(IGMP_DEBUG, ("igmp_input: message from "));
+  ip4_addr_debug_print_val(IGMP_DEBUG, ip4_current_header()->src);
+  LWIP_DEBUGF(IGMP_DEBUG, (" to address "));
+  ip4_addr_debug_print_val(IGMP_DEBUG, ip4_current_header()->dest);
+  LWIP_DEBUGF(IGMP_DEBUG, (" on if %p\n", (void *)inp));
+
+  /* Now calculate and check the checksum */
+  igmp = (struct igmp_msg *)p->payload;
+  if (inet_chksum(igmp, p->len)) {
+    pbuf_free(p);
+    IGMP_STATS_INC(igmp.chkerr);
+    LWIP_DEBUGF(IGMP_DEBUG, ("igmp_input: checksum error\n"));
+    return;
+  }
+
+  /* Packet is ok so find an existing group */
+  group = igmp_lookfor_group(inp, dest); /* use the destination IP address of incoming packet */
+
+  /* If group can be found or create... */
+  if (!group) {
+    pbuf_free(p);
+    IGMP_STATS_INC(igmp.drop);
+    LWIP_DEBUGF(IGMP_DEBUG, ("igmp_input: IGMP frame not for us\n"));
+    return;
+  }
+
+  /* NOW ACT ON THE INCOMING MESSAGE TYPE... */
+  switch (igmp->igmp_msgtype) {
+    case IGMP_MEMB_QUERY:
+      /* IGMP_MEMB_QUERY to the "all systems" address ? */
+      if ((ip4_addr_cmp(dest, &allsystems)) && ip4_addr_isany(&igmp->igmp_group_address)) {
+        /* THIS IS THE GENERAL QUERY */
+        LWIP_DEBUGF(IGMP_DEBUG, ("igmp_input: General IGMP_MEMB_QUERY on \"ALL SYSTEMS\" address (224.0.0.1) [igmp_maxresp=%i]\n", (int)(igmp->igmp_maxresp)));
+
+        if (igmp->igmp_maxresp == 0) {
+          IGMP_STATS_INC(igmp.rx_v1);
+          LWIP_DEBUGF(IGMP_DEBUG, ("igmp_input: got an all hosts query with time== 0 - this is V1 and not implemented - treat as v2\n"));
+          igmp->igmp_maxresp = IGMP_V1_DELAYING_MEMBER_TMR;
+        } else {
+          IGMP_STATS_INC(igmp.rx_general);
+        }
+
+        groupref = netif_igmp_data(inp);
+
+        /* Do not send messages on the all systems group address! */
+        /* Skip the first group in the list, it is always the allsystems group added in igmp_start() */
+        if (groupref != NULL) {
+          groupref = groupref->next;
+        }
+
+        while (groupref) {
+          igmp_delaying_member(groupref, igmp->igmp_maxresp);
+          groupref = groupref->next;
+        }
+      } else {
+        /* IGMP_MEMB_QUERY to a specific group ? */
+        if (!ip4_addr_isany(&igmp->igmp_group_address)) {
+          LWIP_DEBUGF(IGMP_DEBUG, ("igmp_input: IGMP_MEMB_QUERY to a specific group "));
+          ip4_addr_debug_print_val(IGMP_DEBUG, igmp->igmp_group_address);
+          if (ip4_addr_cmp(dest, &allsystems)) {
+            ip4_addr_t groupaddr;
+            LWIP_DEBUGF(IGMP_DEBUG, (" using \"ALL SYSTEMS\" address (224.0.0.1) [igmp_maxresp=%i]\n", (int)(igmp->igmp_maxresp)));
+            /* we first need to re-look for the group since we used dest last time */
+            ip4_addr_copy(groupaddr, igmp->igmp_group_address);
+            group = igmp_lookfor_group(inp, &groupaddr);
+          } else {
+            LWIP_DEBUGF(IGMP_DEBUG, (" with the group address as destination [igmp_maxresp=%i]\n", (int)(igmp->igmp_maxresp)));
+          }
+
+          if (group != NULL) {
+            IGMP_STATS_INC(igmp.rx_group);
+            igmp_delaying_member(group, igmp->igmp_maxresp);
+          } else {
+            IGMP_STATS_INC(igmp.drop);
+          }
+        } else {
+          IGMP_STATS_INC(igmp.proterr);
+        }
+      }
+      break;
+    case IGMP_V2_MEMB_REPORT:
+      LWIP_DEBUGF(IGMP_DEBUG, ("igmp_input: IGMP_V2_MEMB_REPORT\n"));
+      IGMP_STATS_INC(igmp.rx_report);
+      if (group->group_state == IGMP_GROUP_DELAYING_MEMBER) {
+        /* This is on a specific group we have already looked up */
+        group->timer = 0; /* stopped */
+        group->group_state = IGMP_GROUP_IDLE_MEMBER;
+        group->last_reporter_flag = 0;
+      }
+      break;
+    default:
+      LWIP_DEBUGF(IGMP_DEBUG, ("igmp_input: unexpected msg %d in state %d on group %p on if %p\n",
+                               igmp->igmp_msgtype, group->group_state, (void *)&group, (void *)inp));
+      IGMP_STATS_INC(igmp.proterr);
+      break;
+  }
+
+  pbuf_free(p);
+  return;
+}
+
+/**
+ * @ingroup igmp
+ * Join a group on one network interface.
+ *
+ * @param ifaddr ip address of the network interface which should join a new group
+ * @param groupaddr the ip address of the group which to join
+ * @return ERR_OK if group was joined on the netif(s), an err_t otherwise
+ */
+err_t
+igmp_joingroup(const ip4_addr_t *ifaddr, const ip4_addr_t *groupaddr)
+{
+  err_t err = ERR_VAL; /* no matching interface */
+  struct netif *netif;
+
+  LWIP_ASSERT_CORE_LOCKED();
+
+  /* make sure it is multicast address */
+  LWIP_ERROR("igmp_joingroup: attempt to join non-multicast address", ip4_addr_ismulticast(groupaddr), return ERR_VAL;);
+  LWIP_ERROR("igmp_joingroup: attempt to join allsystems address", (!ip4_addr_cmp(groupaddr, &allsystems)), return ERR_VAL;);
+
+  /* loop through netif's */
+  NETIF_FOREACH(netif) {
+    /* Should we join this interface ? */
+    if ((netif->flags & NETIF_FLAG_IGMP) && ((ip4_addr_isany(ifaddr) || ip4_addr_cmp(netif_ip4_addr(netif), ifaddr)))) {
+      err = igmp_joingroup_netif(netif, groupaddr);
+      if (err != ERR_OK) {
+        /* Return an error even if some network interfaces are joined */
+        /** @todo undo any other netif already joined */
+        return err;
+      }
+    }
+  }
+
+  return err;
+}
+
+/**
+ * @ingroup igmp
+ * Join a group on one network interface.
+ *
+ * @param netif the network interface which should join a new group
+ * @param groupaddr the ip address of the group which to join
+ * @return ERR_OK if group was joined on the netif, an err_t otherwise
+ */
+err_t
+igmp_joingroup_netif(struct netif *netif, const ip4_addr_t *groupaddr)
+{
+  struct igmp_group *group;
+
+  LWIP_ASSERT_CORE_LOCKED();
+
+  /* make sure it is multicast address */
+  LWIP_ERROR("igmp_joingroup_netif: attempt to join non-multicast address", ip4_addr_ismulticast(groupaddr), return ERR_VAL;);
+  LWIP_ERROR("igmp_joingroup_netif: attempt to join allsystems address", (!ip4_addr_cmp(groupaddr, &allsystems)), return ERR_VAL;);
+
+  /* make sure it is an igmp-enabled netif */
+  LWIP_ERROR("igmp_joingroup_netif: attempt to join on non-IGMP netif", netif->flags & NETIF_FLAG_IGMP, return ERR_VAL;);
+
+  /* find group or create a new one if not found */
+  group = igmp_lookup_group(netif, groupaddr);
+
+  if (group != NULL) {
+    /* This should create a new group, check the state to make sure */
+    if (group->group_state != IGMP_GROUP_NON_MEMBER) {
+      LWIP_DEBUGF(IGMP_DEBUG, ("igmp_joingroup_netif: join to group not in state IGMP_GROUP_NON_MEMBER\n"));
+    } else {
+      /* OK - it was new group */
+      LWIP_DEBUGF(IGMP_DEBUG, ("igmp_joingroup_netif: join to new group: "));
+      ip4_addr_debug_print(IGMP_DEBUG, groupaddr);
+      LWIP_DEBUGF(IGMP_DEBUG, ("\n"));
+
+      /* If first use of the group, allow the group at the MAC level */
+      if ((group->use == 0) && (netif->igmp_mac_filter != NULL)) {
+        LWIP_DEBUGF(IGMP_DEBUG, ("igmp_joingroup_netif: igmp_mac_filter(ADD "));
+        ip4_addr_debug_print(IGMP_DEBUG, groupaddr);
+        LWIP_DEBUGF(IGMP_DEBUG, (") on if %p\n", (void *)netif));
+        netif->igmp_mac_filter(netif, groupaddr, NETIF_ADD_MAC_FILTER);
+      }
+
+      IGMP_STATS_INC(igmp.tx_join);
+      igmp_send(netif, group, IGMP_V2_MEMB_REPORT);
+
+      igmp_start_timer(group, IGMP_JOIN_DELAYING_MEMBER_TMR);
+
+      /* Need to work out where this timer comes from */
+      group->group_state = IGMP_GROUP_DELAYING_MEMBER;
+    }
+    /* Increment group use */
+    group->use++;
+    /* Join on this interface */
+    return ERR_OK;
+  } else {
+    LWIP_DEBUGF(IGMP_DEBUG, ("igmp_joingroup_netif: Not enough memory to join to group\n"));
+    return ERR_MEM;
+  }
+}
+
+/**
+ * @ingroup igmp
+ * Leave a group on one network interface.
+ *
+ * @param ifaddr ip address of the network interface which should leave a group
+ * @param groupaddr the ip address of the group which to leave
+ * @return ERR_OK if group was left on the netif(s), an err_t otherwise
+ */
+err_t
+igmp_leavegroup(const ip4_addr_t *ifaddr, const ip4_addr_t *groupaddr)
+{
+  err_t err = ERR_VAL; /* no matching interface */
+  struct netif *netif;
+
+  LWIP_ASSERT_CORE_LOCKED();
+
+  /* make sure it is multicast address */
+  LWIP_ERROR("igmp_leavegroup: attempt to leave non-multicast address", ip4_addr_ismulticast(groupaddr), return ERR_VAL;);
+  LWIP_ERROR("igmp_leavegroup: attempt to leave allsystems address", (!ip4_addr_cmp(groupaddr, &allsystems)), return ERR_VAL;);
+
+  /* loop through netif's */
+  NETIF_FOREACH(netif) {
+    /* Should we leave this interface ? */
+    if ((netif->flags & NETIF_FLAG_IGMP) && ((ip4_addr_isany(ifaddr) || ip4_addr_cmp(netif_ip4_addr(netif), ifaddr)))) {
+      err_t res = igmp_leavegroup_netif(netif, groupaddr);
+      if (err != ERR_OK) {
+        /* Store this result if we have not yet gotten a success */
+        err = res;
+      }
+    }
+  }
+
+  return err;
+}
+
+/**
+ * @ingroup igmp
+ * Leave a group on one network interface.
+ *
+ * @param netif the network interface which should leave a group
+ * @param groupaddr the ip address of the group which to leave
+ * @return ERR_OK if group was left on the netif, an err_t otherwise
+ */
+err_t
+igmp_leavegroup_netif(struct netif *netif, const ip4_addr_t *groupaddr)
+{
+  struct igmp_group *group;
+
+  LWIP_ASSERT_CORE_LOCKED();
+
+  /* make sure it is multicast address */
+  LWIP_ERROR("igmp_leavegroup_netif: attempt to leave non-multicast address", ip4_addr_ismulticast(groupaddr), return ERR_VAL;);
+  LWIP_ERROR("igmp_leavegroup_netif: attempt to leave allsystems address", (!ip4_addr_cmp(groupaddr, &allsystems)), return ERR_VAL;);
+
+  /* make sure it is an igmp-enabled netif */
+  LWIP_ERROR("igmp_leavegroup_netif: attempt to leave on non-IGMP netif", netif->flags & NETIF_FLAG_IGMP, return ERR_VAL;);
+
+  /* find group */
+  group = igmp_lookfor_group(netif, groupaddr);
+
+  if (group != NULL) {
+    /* Only send a leave if the flag is set according to the state diagram */
+    LWIP_DEBUGF(IGMP_DEBUG, ("igmp_leavegroup_netif: Leaving group: "));
+    ip4_addr_debug_print(IGMP_DEBUG, groupaddr);
+    LWIP_DEBUGF(IGMP_DEBUG, ("\n"));
+
+    /* If there is no other use of the group */
+    if (group->use <= 1) {
+      /* Remove the group from the list */
+      igmp_remove_group(netif, group);
+
+      /* If we are the last reporter for this group */
+      if (group->last_reporter_flag) {
+        LWIP_DEBUGF(IGMP_DEBUG, ("igmp_leavegroup_netif: sending leaving group\n"));
+        IGMP_STATS_INC(igmp.tx_leave);
+        igmp_send(netif, group, IGMP_LEAVE_GROUP);
+      }
+
+      /* Disable the group at the MAC level */
+      if (netif->igmp_mac_filter != NULL) {
+        LWIP_DEBUGF(IGMP_DEBUG, ("igmp_leavegroup_netif: igmp_mac_filter(DEL "));
+        ip4_addr_debug_print(IGMP_DEBUG, groupaddr);
+        LWIP_DEBUGF(IGMP_DEBUG, (") on if %p\n", (void *)netif));
+        netif->igmp_mac_filter(netif, groupaddr, NETIF_DEL_MAC_FILTER);
+      }
+
+      /* Free group struct */
+      memp_free(MEMP_IGMP_GROUP, group);
+    } else {
+      /* Decrement group use */
+      group->use--;
+    }
+    return ERR_OK;
+  } else {
+    LWIP_DEBUGF(IGMP_DEBUG, ("igmp_leavegroup_netif: not member of group\n"));
+    return ERR_VAL;
+  }
+}
+
+/**
+ * The igmp timer function (both for NO_SYS=1 and =0)
+ * Should be called every IGMP_TMR_INTERVAL milliseconds (100 ms is default).
+ */
+void
+igmp_tmr(void)
+{
+  struct netif *netif;
+
+  NETIF_FOREACH(netif) {
+    struct igmp_group *group = netif_igmp_data(netif);
+
+    while (group != NULL) {
+      if (group->timer > 0) {
+        group->timer--;
+        if (group->timer == 0) {
+          igmp_timeout(netif, group);
+        }
+      }
+      group = group->next;
+    }
+  }
+}
+
+/**
+ * Called if a timeout for one group is reached.
+ * Sends a report for this group.
+ *
+ * @param group an igmp_group for which a timeout is reached
+ */
+static void
+igmp_timeout(struct netif *netif, struct igmp_group *group)
+{
+  /* If the state is IGMP_GROUP_DELAYING_MEMBER then we send a report for this group
+     (unless it is the allsystems group) */
+  if ((group->group_state == IGMP_GROUP_DELAYING_MEMBER) &&
+      (!(ip4_addr_cmp(&(group->group_address), &allsystems)))) {
+    LWIP_DEBUGF(IGMP_DEBUG, ("igmp_timeout: report membership for group with address "));
+    ip4_addr_debug_print_val(IGMP_DEBUG, group->group_address);
+    LWIP_DEBUGF(IGMP_DEBUG, (" on if %p\n", (void *)netif));
+
+    group->group_state = IGMP_GROUP_IDLE_MEMBER;
+
+    IGMP_STATS_INC(igmp.tx_report);
+    igmp_send(netif, group, IGMP_V2_MEMB_REPORT);
+  }
+}
+
+/**
+ * Start a timer for an igmp group
+ *
+ * @param group the igmp_group for which to start a timer
+ * @param max_time the time in multiples of IGMP_TMR_INTERVAL (decrease with
+ *        every call to igmp_tmr())
+ */
+static void
+igmp_start_timer(struct igmp_group *group, u8_t max_time)
+{
+#ifdef LWIP_RAND
+  group->timer = (u16_t)(max_time > 2 ? (LWIP_RAND() % max_time) : 1);
+#else /* LWIP_RAND */
+  /* ATTENTION: use this only if absolutely necessary! */
+  group->timer = max_time / 2;
+#endif /* LWIP_RAND */
+
+  if (group->timer == 0) {
+    group->timer = 1;
+  }
+}
+
+/**
+ * Delaying membership report for a group if necessary
+ *
+ * @param group the igmp_group for which "delaying" membership report
+ * @param maxresp query delay
+ */
+static void
+igmp_delaying_member(struct igmp_group *group, u8_t maxresp)
+{
+  if ((group->group_state == IGMP_GROUP_IDLE_MEMBER) ||
+      ((group->group_state == IGMP_GROUP_DELAYING_MEMBER) &&
+       ((group->timer == 0) || (maxresp < group->timer)))) {
+    igmp_start_timer(group, maxresp);
+    group->group_state = IGMP_GROUP_DELAYING_MEMBER;
+  }
+}
+
+
+/**
+ * Sends an IP packet on a network interface. This function constructs the IP header
+ * and calculates the IP header checksum. If the source IP address is NULL,
+ * the IP address of the outgoing network interface is filled in as source address.
+ *
+ * @param p the packet to send (p->payload points to the data, e.g. next
+            protocol header; if dest == LWIP_IP_HDRINCL, p already includes an
+            IP header and p->payload points to that IP header)
+ * @param src the source IP address to send from (if src == IP4_ADDR_ANY, the
+ *         IP  address of the netif used to send is used as source address)
+ * @param dest the destination IP address to send the packet to
+ * @param netif the netif on which to send this packet
+ * @return ERR_OK if the packet was sent OK
+ *         ERR_BUF if p doesn't have enough space for IP/LINK headers
+ *         returns errors returned by netif->output
+ */
+static err_t
+igmp_ip_output_if(struct pbuf *p, const ip4_addr_t *src, const ip4_addr_t *dest, struct netif *netif)
+{
+  /* This is the "router alert" option */
+  u16_t ra[2];
+  ra[0] = PP_HTONS(ROUTER_ALERT);
+  ra[1] = 0x0000; /* Router shall examine packet */
+  IGMP_STATS_INC(igmp.xmit);
+  return ip4_output_if_opt(p, src, dest, IGMP_TTL, 0, IP_PROTO_IGMP, netif, ra, ROUTER_ALERTLEN);
+}
+
+/**
+ * Send an igmp packet to a specific group.
+ *
+ * @param group the group to which to send the packet
+ * @param type the type of igmp packet to send
+ */
+static void
+igmp_send(struct netif *netif, struct igmp_group *group, u8_t type)
+{
+  struct pbuf     *p    = NULL;
+  struct igmp_msg *igmp = NULL;
+  ip4_addr_t   src  = *IP4_ADDR_ANY4;
+  ip4_addr_t  *dest = NULL;
+
+  /* IP header + "router alert" option + IGMP header */
+  p = pbuf_alloc(PBUF_TRANSPORT, IGMP_MINLEN, PBUF_RAM);
+
+  if (p) {
+    igmp = (struct igmp_msg *)p->payload;
+    LWIP_ASSERT("igmp_send: check that first pbuf can hold struct igmp_msg",
+                (p->len >= sizeof(struct igmp_msg)));
+    ip4_addr_copy(src, *netif_ip4_addr(netif));
+
+    if (type == IGMP_V2_MEMB_REPORT) {
+      dest = &(group->group_address);
+      ip4_addr_copy(igmp->igmp_group_address, group->group_address);
+      group->last_reporter_flag = 1; /* Remember we were the last to report */
+    } else {
+      if (type == IGMP_LEAVE_GROUP) {
+        dest = &allrouters;
+        ip4_addr_copy(igmp->igmp_group_address, group->group_address);
+      }
+    }
+
+    if ((type == IGMP_V2_MEMB_REPORT) || (type == IGMP_LEAVE_GROUP)) {
+      igmp->igmp_msgtype  = type;
+      igmp->igmp_maxresp  = 0;
+      igmp->igmp_checksum = 0;
+      igmp->igmp_checksum = inet_chksum(igmp, IGMP_MINLEN);
+
+      igmp_ip_output_if(p, &src, dest, netif);
+    }
+
+    pbuf_free(p);
+  } else {
+    LWIP_DEBUGF(IGMP_DEBUG, ("igmp_send: not enough memory for igmp_send\n"));
+    IGMP_STATS_INC(igmp.memerr);
+  }
+}
+
+#endif /* LWIP_IPV4 && LWIP_IGMP */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/core/ipv4/ip4.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/core/ipv4/ip4.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/core/ipv4/ip4.c	(revision 457)
@@ -0,0 +1,1139 @@
+/**
+ * @file
+ * This is the IPv4 layer implementation for incoming and outgoing IP traffic.
+ *
+ * @see ip_frag.c
+ *
+ */
+
+/*
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Adam Dunkels <adam@sics.se>
+ *
+ */
+
+#include "lwip/opt.h"
+
+#if LWIP_IPV4
+
+#include "lwip/ip.h"
+#include "lwip/def.h"
+#include "lwip/mem.h"
+#include "lwip/ip4_frag.h"
+#include "lwip/inet_chksum.h"
+#include "lwip/netif.h"
+#include "lwip/icmp.h"
+#include "lwip/igmp.h"
+#include "lwip/priv/raw_priv.h"
+#include "lwip/udp.h"
+#include "lwip/priv/tcp_priv.h"
+#include "lwip/autoip.h"
+#include "lwip/stats.h"
+#include "lwip/prot/iana.h"
+
+#include <string.h>
+
+#ifdef LWIP_HOOK_FILENAME
+#include LWIP_HOOK_FILENAME
+#endif
+
+/** Set this to 0 in the rare case of wanting to call an extra function to
+ * generate the IP checksum (in contrast to calculating it on-the-fly). */
+#ifndef LWIP_INLINE_IP_CHKSUM
+#if LWIP_CHECKSUM_CTRL_PER_NETIF
+#define LWIP_INLINE_IP_CHKSUM   0
+#else /* LWIP_CHECKSUM_CTRL_PER_NETIF */
+#define LWIP_INLINE_IP_CHKSUM   1
+#endif /* LWIP_CHECKSUM_CTRL_PER_NETIF */
+#endif
+
+#if LWIP_INLINE_IP_CHKSUM && CHECKSUM_GEN_IP
+#define CHECKSUM_GEN_IP_INLINE  1
+#else
+#define CHECKSUM_GEN_IP_INLINE  0
+#endif
+
+#if LWIP_DHCP || defined(LWIP_IP_ACCEPT_UDP_PORT)
+#define IP_ACCEPT_LINK_LAYER_ADDRESSING 1
+
+/** Some defines for DHCP to let link-layer-addressed packets through while the
+ * netif is down.
+ * To use this in your own application/protocol, define LWIP_IP_ACCEPT_UDP_PORT(port)
+ * to return 1 if the port is accepted and 0 if the port is not accepted.
+ */
+#if LWIP_DHCP && defined(LWIP_IP_ACCEPT_UDP_PORT)
+/* accept DHCP client port and custom port */
+#define IP_ACCEPT_LINK_LAYER_ADDRESSED_PORT(port) (((port) == PP_NTOHS(LWIP_IANA_PORT_DHCP_CLIENT)) \
+         || (LWIP_IP_ACCEPT_UDP_PORT(port)))
+#elif defined(LWIP_IP_ACCEPT_UDP_PORT) /* LWIP_DHCP && defined(LWIP_IP_ACCEPT_UDP_PORT) */
+/* accept custom port only */
+#define IP_ACCEPT_LINK_LAYER_ADDRESSED_PORT(port) (LWIP_IP_ACCEPT_UDP_PORT(port))
+#else /* LWIP_DHCP && defined(LWIP_IP_ACCEPT_UDP_PORT) */
+/* accept DHCP client port only */
+#define IP_ACCEPT_LINK_LAYER_ADDRESSED_PORT(port) ((port) == PP_NTOHS(LWIP_IANA_PORT_DHCP_CLIENT))
+#endif /* LWIP_DHCP && defined(LWIP_IP_ACCEPT_UDP_PORT) */
+
+#else /* LWIP_DHCP */
+#define IP_ACCEPT_LINK_LAYER_ADDRESSING 0
+#endif /* LWIP_DHCP */
+
+/** The IP header ID of the next outgoing IP packet */
+static u16_t ip_id;
+
+#if LWIP_MULTICAST_TX_OPTIONS
+/** The default netif used for multicast */
+static struct netif *ip4_default_multicast_netif;
+
+/**
+ * @ingroup ip4
+ * Set a default netif for IPv4 multicast. */
+void
+ip4_set_default_multicast_netif(struct netif *default_multicast_netif)
+{
+  ip4_default_multicast_netif = default_multicast_netif;
+}
+#endif /* LWIP_MULTICAST_TX_OPTIONS */
+
+#ifdef LWIP_HOOK_IP4_ROUTE_SRC
+/**
+ * Source based IPv4 routing must be fully implemented in
+ * LWIP_HOOK_IP4_ROUTE_SRC(). This function only provides the parameters.
+ */
+struct netif *
+ip4_route_src(const ip4_addr_t *src, const ip4_addr_t *dest)
+{
+  if (src != NULL) {
+    /* when src==NULL, the hook is called from ip4_route(dest) */
+    struct netif *netif = LWIP_HOOK_IP4_ROUTE_SRC(src, dest);
+    if (netif != NULL) {
+      return netif;
+    }
+  }
+  return ip4_route(dest);
+}
+#endif /* LWIP_HOOK_IP4_ROUTE_SRC */
+
+/**
+ * Finds the appropriate network interface for a given IP address. It
+ * searches the list of network interfaces linearly. A match is found
+ * if the masked IP address of the network interface equals the masked
+ * IP address given to the function.
+ *
+ * @param dest the destination IP address for which to find the route
+ * @return the netif on which to send to reach dest
+ */
+struct netif *
+ip4_route(const ip4_addr_t *dest)
+{
+#if !LWIP_SINGLE_NETIF
+  struct netif *netif;
+
+  LWIP_ASSERT_CORE_LOCKED();
+
+#if LWIP_MULTICAST_TX_OPTIONS
+  /* Use administratively selected interface for multicast by default */
+  if (ip4_addr_ismulticast(dest) && ip4_default_multicast_netif) {
+    return ip4_default_multicast_netif;
+  }
+#endif /* LWIP_MULTICAST_TX_OPTIONS */
+
+  /* bug #54569: in case LWIP_SINGLE_NETIF=1 and LWIP_DEBUGF() disabled, the following loop is optimized away */
+  LWIP_UNUSED_ARG(dest);
+
+  /* iterate through netifs */
+  NETIF_FOREACH(netif) {
+    /* is the netif up, does it have a link and a valid address? */
+    if (netif_is_up(netif) && netif_is_link_up(netif) && !ip4_addr_isany_val(*netif_ip4_addr(netif))) {
+      /* network mask matches? */
+      if (ip4_addr_netcmp(dest, netif_ip4_addr(netif), netif_ip4_netmask(netif))) {
+        /* return netif on which to forward IP packet */
+        return netif;
+      }
+      /* gateway matches on a non broadcast interface? (i.e. peer in a point to point interface) */
+      if (((netif->flags & NETIF_FLAG_BROADCAST) == 0) && ip4_addr_cmp(dest, netif_ip4_gw(netif))) {
+        /* return netif on which to forward IP packet */
+        return netif;
+      }
+    }
+  }
+
+#if LWIP_NETIF_LOOPBACK && !LWIP_HAVE_LOOPIF
+  /* loopif is disabled, looopback traffic is passed through any netif */
+  if (ip4_addr_isloopback(dest)) {
+    /* don't check for link on loopback traffic */
+    if (netif_default != NULL && netif_is_up(netif_default)) {
+      return netif_default;
+    }
+    /* default netif is not up, just use any netif for loopback traffic */
+    NETIF_FOREACH(netif) {
+      if (netif_is_up(netif)) {
+        return netif;
+      }
+    }
+    return NULL;
+  }
+#endif /* LWIP_NETIF_LOOPBACK && !LWIP_HAVE_LOOPIF */
+
+#ifdef LWIP_HOOK_IP4_ROUTE_SRC
+  netif = LWIP_HOOK_IP4_ROUTE_SRC(NULL, dest);
+  if (netif != NULL) {
+    return netif;
+  }
+#elif defined(LWIP_HOOK_IP4_ROUTE)
+  netif = LWIP_HOOK_IP4_ROUTE(dest);
+  if (netif != NULL) {
+    return netif;
+  }
+#endif
+#endif /* !LWIP_SINGLE_NETIF */
+
+  if ((netif_default == NULL) || !netif_is_up(netif_default) || !netif_is_link_up(netif_default) ||
+      ip4_addr_isany_val(*netif_ip4_addr(netif_default)) || ip4_addr_isloopback(dest)) {
+    /* No matching netif found and default netif is not usable.
+       If this is not good enough for you, use LWIP_HOOK_IP4_ROUTE() */
+    LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("ip4_route: No route to %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n",
+                ip4_addr1_16(dest), ip4_addr2_16(dest), ip4_addr3_16(dest), ip4_addr4_16(dest)));
+    IP_STATS_INC(ip.rterr);
+    MIB2_STATS_INC(mib2.ipoutnoroutes);
+    return NULL;
+  }
+
+  return netif_default;
+}
+
+#if IP_FORWARD
+/**
+ * Determine whether an IP address is in a reserved set of addresses
+ * that may not be forwarded, or whether datagrams to that destination
+ * may be forwarded.
+ * @param p the packet to forward
+ * @return 1: can forward 0: discard
+ */
+static int
+ip4_canforward(struct pbuf *p)
+{
+  u32_t addr = lwip_htonl(ip4_addr_get_u32(ip4_current_dest_addr()));
+
+#ifdef LWIP_HOOK_IP4_CANFORWARD
+  int ret = LWIP_HOOK_IP4_CANFORWARD(p, addr);
+  if (ret >= 0) {
+    return ret;
+  }
+#endif /* LWIP_HOOK_IP4_CANFORWARD */
+
+  if (p->flags & PBUF_FLAG_LLBCAST) {
+    /* don't route link-layer broadcasts */
+    return 0;
+  }
+  if ((p->flags & PBUF_FLAG_LLMCAST) || IP_MULTICAST(addr)) {
+    /* don't route link-layer multicasts (use LWIP_HOOK_IP4_CANFORWARD instead) */
+    return 0;
+  }
+  if (IP_EXPERIMENTAL(addr)) {
+    return 0;
+  }
+  if (IP_CLASSA(addr)) {
+    u32_t net = addr & IP_CLASSA_NET;
+    if ((net == 0) || (net == ((u32_t)IP_LOOPBACKNET << IP_CLASSA_NSHIFT))) {
+      /* don't route loopback packets */
+      return 0;
+    }
+  }
+  return 1;
+}
+
+/**
+ * Forwards an IP packet. It finds an appropriate route for the
+ * packet, decrements the TTL value of the packet, adjusts the
+ * checksum and outputs the packet on the appropriate interface.
+ *
+ * @param p the packet to forward (p->payload points to IP header)
+ * @param iphdr the IP header of the input packet
+ * @param inp the netif on which this packet was received
+ */
+static void
+ip4_forward(struct pbuf *p, struct ip_hdr *iphdr, struct netif *inp)
+{
+  struct netif *netif;
+
+  PERF_START;
+  LWIP_UNUSED_ARG(inp);
+
+  if (!ip4_canforward(p)) {
+    goto return_noroute;
+  }
+
+  /* RFC3927 2.7: do not forward link-local addresses */
+  if (ip4_addr_islinklocal(ip4_current_dest_addr())) {
+    LWIP_DEBUGF(IP_DEBUG, ("ip4_forward: not forwarding LLA %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n",
+                           ip4_addr1_16(ip4_current_dest_addr()), ip4_addr2_16(ip4_current_dest_addr()),
+                           ip4_addr3_16(ip4_current_dest_addr()), ip4_addr4_16(ip4_current_dest_addr())));
+    goto return_noroute;
+  }
+
+  /* Find network interface where to forward this IP packet to. */
+  netif = ip4_route_src(ip4_current_src_addr(), ip4_current_dest_addr());
+  if (netif == NULL) {
+    LWIP_DEBUGF(IP_DEBUG, ("ip4_forward: no forwarding route for %"U16_F".%"U16_F".%"U16_F".%"U16_F" found\n",
+                           ip4_addr1_16(ip4_current_dest_addr()), ip4_addr2_16(ip4_current_dest_addr()),
+                           ip4_addr3_16(ip4_current_dest_addr()), ip4_addr4_16(ip4_current_dest_addr())));
+    /* @todo: send ICMP_DUR_NET? */
+    goto return_noroute;
+  }
+#if !IP_FORWARD_ALLOW_TX_ON_RX_NETIF
+  /* Do not forward packets onto the same network interface on which
+   * they arrived. */
+  if (netif == inp) {
+    LWIP_DEBUGF(IP_DEBUG, ("ip4_forward: not bouncing packets back on incoming interface.\n"));
+    goto return_noroute;
+  }
+#endif /* IP_FORWARD_ALLOW_TX_ON_RX_NETIF */
+
+  /* decrement TTL */
+  IPH_TTL_SET(iphdr, IPH_TTL(iphdr) - 1);
+  /* send ICMP if TTL == 0 */
+  if (IPH_TTL(iphdr) == 0) {
+    MIB2_STATS_INC(mib2.ipinhdrerrors);
+#if LWIP_ICMP
+    /* Don't send ICMP messages in response to ICMP messages */
+    if (IPH_PROTO(iphdr) != IP_PROTO_ICMP) {
+      icmp_time_exceeded(p, ICMP_TE_TTL);
+    }
+#endif /* LWIP_ICMP */
+    return;
+  }
+
+  /* Incrementally update the IP checksum. */
+  if (IPH_CHKSUM(iphdr) >= PP_HTONS(0xffffU - 0x100)) {
+    IPH_CHKSUM_SET(iphdr, (u16_t)(IPH_CHKSUM(iphdr) + PP_HTONS(0x100) + 1));
+  } else {
+    IPH_CHKSUM_SET(iphdr, (u16_t)(IPH_CHKSUM(iphdr) + PP_HTONS(0x100)));
+  }
+
+  LWIP_DEBUGF(IP_DEBUG, ("ip4_forward: forwarding packet to %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n",
+                         ip4_addr1_16(ip4_current_dest_addr()), ip4_addr2_16(ip4_current_dest_addr()),
+                         ip4_addr3_16(ip4_current_dest_addr()), ip4_addr4_16(ip4_current_dest_addr())));
+
+  IP_STATS_INC(ip.fw);
+  MIB2_STATS_INC(mib2.ipforwdatagrams);
+  IP_STATS_INC(ip.xmit);
+
+  PERF_STOP("ip4_forward");
+  /* don't fragment if interface has mtu set to 0 [loopif] */
+  if (netif->mtu && (p->tot_len > netif->mtu)) {
+    if ((IPH_OFFSET(iphdr) & PP_NTOHS(IP_DF)) == 0) {
+#if IP_FRAG
+      ip4_frag(p, netif, ip4_current_dest_addr());
+#else /* IP_FRAG */
+      /* @todo: send ICMP Destination Unreachable code 13 "Communication administratively prohibited"? */
+#endif /* IP_FRAG */
+    } else {
+#if LWIP_ICMP
+      /* send ICMP Destination Unreachable code 4: "Fragmentation Needed and DF Set" */
+      icmp_dest_unreach(p, ICMP_DUR_FRAG);
+#endif /* LWIP_ICMP */
+    }
+    return;
+  }
+  /* transmit pbuf on chosen interface */
+  netif->output(netif, p, ip4_current_dest_addr());
+  return;
+return_noroute:
+  MIB2_STATS_INC(mib2.ipoutnoroutes);
+}
+#endif /* IP_FORWARD */
+
+/** Return true if the current input packet should be accepted on this netif */
+static int
+ip4_input_accept(struct netif *netif)
+{
+  LWIP_DEBUGF(IP_DEBUG, ("ip_input: iphdr->dest 0x%"X32_F" netif->ip_addr 0x%"X32_F" (0x%"X32_F", 0x%"X32_F", 0x%"X32_F")\n",
+                         ip4_addr_get_u32(ip4_current_dest_addr()), ip4_addr_get_u32(netif_ip4_addr(netif)),
+                         ip4_addr_get_u32(ip4_current_dest_addr()) & ip4_addr_get_u32(netif_ip4_netmask(netif)),
+                         ip4_addr_get_u32(netif_ip4_addr(netif)) & ip4_addr_get_u32(netif_ip4_netmask(netif)),
+                         ip4_addr_get_u32(ip4_current_dest_addr()) & ~ip4_addr_get_u32(netif_ip4_netmask(netif))));
+
+  /* interface is up and configured? */
+  if ((netif_is_up(netif)) && (!ip4_addr_isany_val(*netif_ip4_addr(netif)))) {
+    /* unicast to this interface address? */
+    if (ip4_addr_cmp(ip4_current_dest_addr(), netif_ip4_addr(netif)) ||
+        /* or broadcast on this interface network address? */
+        ip4_addr_isbroadcast(ip4_current_dest_addr(), netif)
+#if LWIP_NETIF_LOOPBACK && !LWIP_HAVE_LOOPIF
+        || (ip4_addr_get_u32(ip4_current_dest_addr()) == PP_HTONL(IPADDR_LOOPBACK))
+#endif /* LWIP_NETIF_LOOPBACK && !LWIP_HAVE_LOOPIF */
+       ) {
+      LWIP_DEBUGF(IP_DEBUG, ("ip4_input: packet accepted on interface %c%c\n",
+                             netif->name[0], netif->name[1]));
+      /* accept on this netif */
+      return 1;
+    }
+#if LWIP_AUTOIP
+    /* connections to link-local addresses must persist after changing
+        the netif's address (RFC3927 ch. 1.9) */
+    if (autoip_accept_packet(netif, ip4_current_dest_addr())) {
+      LWIP_DEBUGF(IP_DEBUG, ("ip4_input: LLA packet accepted on interface %c%c\n",
+                             netif->name[0], netif->name[1]));
+      /* accept on this netif */
+      return 1;
+    }
+#endif /* LWIP_AUTOIP */
+  }
+  return 0;
+}
+
+/**
+ * This function is called by the network interface device driver when
+ * an IP packet is received. The function does the basic checks of the
+ * IP header such as packet size being at least larger than the header
+ * size etc. If the packet was not destined for us, the packet is
+ * forwarded (using ip_forward). The IP checksum is always checked.
+ *
+ * Finally, the packet is sent to the upper layer protocol input function.
+ *
+ * @param p the received IP packet (p->payload points to IP header)
+ * @param inp the netif on which this packet was received
+ * @return ERR_OK if the packet was processed (could return ERR_* if it wasn't
+ *         processed, but currently always returns ERR_OK)
+ */
+err_t
+ip4_input(struct pbuf *p, struct netif *inp)
+{
+  const struct ip_hdr *iphdr;
+  struct netif *netif;
+  u16_t iphdr_hlen;
+  u16_t iphdr_len;
+#if IP_ACCEPT_LINK_LAYER_ADDRESSING || LWIP_IGMP
+  int check_ip_src = 1;
+#endif /* IP_ACCEPT_LINK_LAYER_ADDRESSING || LWIP_IGMP */
+#if LWIP_RAW
+  raw_input_state_t raw_status;
+#endif /* LWIP_RAW */
+#if ETHARP_SUPPORT_STATIC_ENTRIES && LWIP_DHCP
+  struct etharp_hdr *hdr = (struct etharp_hdr *)(p->payload - SIZEOF_ETH_HDR);
+#endif /* ETHARP_SUPPORT_STATIC_ENTRIES */
+
+  LWIP_ASSERT_CORE_LOCKED();
+
+  IP_STATS_INC(ip.recv);
+  MIB2_STATS_INC(mib2.ipinreceives);
+
+  /* identify the IP header */
+  iphdr = (struct ip_hdr *)p->payload;
+  if (IPH_V(iphdr) != 4) {
+    LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_LEVEL_WARNING, ("IP packet dropped due to bad version number %"U16_F"\n", (u16_t)IPH_V(iphdr)));
+    ip4_debug_print(p);
+    pbuf_free(p);
+    IP_STATS_INC(ip.err);
+    IP_STATS_INC(ip.drop);
+    MIB2_STATS_INC(mib2.ipinhdrerrors);
+    return ERR_OK;
+  }
+
+#ifdef LWIP_HOOK_IP4_INPUT
+  if (LWIP_HOOK_IP4_INPUT(p, inp)) {
+    /* the packet has been eaten */
+    return ERR_OK;
+  }
+#endif
+
+  /* obtain IP header length in bytes */
+  iphdr_hlen = IPH_HL_BYTES(iphdr);
+  /* obtain ip length in bytes */
+  iphdr_len = lwip_ntohs(IPH_LEN(iphdr));
+
+  /* Trim pbuf. This is especially required for packets < 60 bytes. */
+  if (iphdr_len < p->tot_len) {
+    pbuf_realloc(p, iphdr_len);
+  }
+
+  /* header length exceeds first pbuf length, or ip length exceeds total pbuf length? */
+  if ((iphdr_hlen > p->len) || (iphdr_len > p->tot_len) || (iphdr_hlen < IP_HLEN)) {
+    if (iphdr_hlen < IP_HLEN) {
+      LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_LEVEL_SERIOUS,
+                  ("ip4_input: short IP header (%"U16_F" bytes) received, IP packet dropped\n", iphdr_hlen));
+    }
+    if (iphdr_hlen > p->len) {
+      LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_LEVEL_SERIOUS,
+                  ("IP header (len %"U16_F") does not fit in first pbuf (len %"U16_F"), IP packet dropped.\n",
+                   iphdr_hlen, p->len));
+    }
+    if (iphdr_len > p->tot_len) {
+      LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_LEVEL_SERIOUS,
+                  ("IP (len %"U16_F") is longer than pbuf (len %"U16_F"), IP packet dropped.\n",
+                   iphdr_len, p->tot_len));
+    }
+    /* free (drop) packet pbufs */
+    pbuf_free(p);
+    IP_STATS_INC(ip.lenerr);
+    IP_STATS_INC(ip.drop);
+    MIB2_STATS_INC(mib2.ipindiscards);
+    return ERR_OK;
+  }
+
+  /* verify checksum */
+#if CHECKSUM_CHECK_IP
+  IF__NETIF_CHECKSUM_ENABLED(inp, NETIF_CHECKSUM_CHECK_IP) {
+    if (inet_chksum(iphdr, iphdr_hlen) != 0) {
+
+      LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_LEVEL_SERIOUS,
+                  ("Checksum (0x%"X16_F") failed, IP packet dropped.\n", inet_chksum(iphdr, iphdr_hlen)));
+      ip4_debug_print(p);
+      pbuf_free(p);
+      IP_STATS_INC(ip.chkerr);
+      IP_STATS_INC(ip.drop);
+      MIB2_STATS_INC(mib2.ipinhdrerrors);
+      return ERR_OK;
+    }
+  }
+#endif
+
+  /* copy IP addresses to aligned ip_addr_t */
+  ip_addr_copy_from_ip4(ip_data.current_iphdr_dest, iphdr->dest);
+  ip_addr_copy_from_ip4(ip_data.current_iphdr_src, iphdr->src);
+
+  /* match packet against an interface, i.e. is this packet for us? */
+  if (ip4_addr_ismulticast(ip4_current_dest_addr())) {
+#if LWIP_IGMP
+    if ((inp->flags & NETIF_FLAG_IGMP) && (igmp_lookfor_group(inp, ip4_current_dest_addr()))) {
+      /* IGMP snooping switches need 0.0.0.0 to be allowed as source address (RFC 4541) */
+      ip4_addr_t allsystems;
+      IP4_ADDR(&allsystems, 224, 0, 0, 1);
+      if (ip4_addr_cmp(ip4_current_dest_addr(), &allsystems) &&
+          ip4_addr_isany(ip4_current_src_addr())) {
+        check_ip_src = 0;
+      }
+      netif = inp;
+    } else {
+      netif = NULL;
+    }
+#else /* LWIP_IGMP */
+    if ((netif_is_up(inp)) && (!ip4_addr_isany_val(*netif_ip4_addr(inp)))) {
+      netif = inp;
+    } else {
+      netif = NULL;
+    }
+#endif /* LWIP_IGMP */
+  } else {
+    /* start trying with inp. if that's not acceptable, start walking the
+       list of configured netifs. */
+    if (ip4_input_accept(inp)) {
+      netif = inp;
+    } else {
+      netif = NULL;
+#if !LWIP_NETIF_LOOPBACK || LWIP_HAVE_LOOPIF
+      /* Packets sent to the loopback address must not be accepted on an
+       * interface that does not have the loopback address assigned to it,
+       * unless a non-loopback interface is used for loopback traffic. */
+      if (!ip4_addr_isloopback(ip4_current_dest_addr()))
+#endif /* !LWIP_NETIF_LOOPBACK || LWIP_HAVE_LOOPIF */
+      {
+#if !LWIP_SINGLE_NETIF
+        NETIF_FOREACH(netif) {
+          if (netif == inp) {
+            /* we checked that before already */
+            continue;
+          }
+          if (ip4_input_accept(netif)) {
+            break;
+          }
+        }
+#endif /* !LWIP_SINGLE_NETIF */
+      }
+    }
+  }
+
+#if IP_ACCEPT_LINK_LAYER_ADDRESSING
+  /* Pass DHCP messages regardless of destination address. DHCP traffic is addressed
+   * using link layer addressing (such as Ethernet MAC) so we must not filter on IP.
+   * According to RFC 1542 section 3.1.1, referred by RFC 2131).
+   *
+   * If you want to accept private broadcast communication while a netif is down,
+   * define LWIP_IP_ACCEPT_UDP_PORT(dst_port), e.g.:
+   *
+   * #define LWIP_IP_ACCEPT_UDP_PORT(dst_port) ((dst_port) == PP_NTOHS(12345))
+   */
+  if (netif == NULL) {
+    /* remote port is DHCP server? */
+    if (IPH_PROTO(iphdr) == IP_PROTO_UDP) {
+      const struct udp_hdr *udphdr = (const struct udp_hdr *)((const u8_t *)iphdr + iphdr_hlen);
+      LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_TRACE, ("ip4_input: UDP packet to DHCP client port %"U16_F"\n",
+                                              lwip_ntohs(udphdr->dest)));
+      if (IP_ACCEPT_LINK_LAYER_ADDRESSED_PORT(udphdr->dest)) {
+        LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_TRACE, ("ip4_input: DHCP packet accepted.\n"));
+        netif = inp;
+        check_ip_src = 0;
+      }
+    }
+  }
+#endif /* IP_ACCEPT_LINK_LAYER_ADDRESSING */
+
+  /* broadcast or multicast packet source address? Compliant with RFC 1122: 3.2.1.3 */
+#if LWIP_IGMP || IP_ACCEPT_LINK_LAYER_ADDRESSING
+  if (check_ip_src
+#if IP_ACCEPT_LINK_LAYER_ADDRESSING
+      /* DHCP servers need 0.0.0.0 to be allowed as source address (RFC 1.1.2.2: 3.2.1.3/a) */
+      && !ip4_addr_isany_val(*ip4_current_src_addr())
+#endif /* IP_ACCEPT_LINK_LAYER_ADDRESSING */
+     )
+#endif /* LWIP_IGMP || IP_ACCEPT_LINK_LAYER_ADDRESSING */
+  {
+    if ((ip4_addr_isbroadcast(ip4_current_src_addr(), inp)) ||
+        (ip4_addr_ismulticast(ip4_current_src_addr()))) {
+      /* packet source is not valid */
+      LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_WARNING, ("ip4_input: packet source is not valid.\n"));
+      /* free (drop) packet pbufs */
+      pbuf_free(p);
+      IP_STATS_INC(ip.drop);
+      MIB2_STATS_INC(mib2.ipinaddrerrors);
+      MIB2_STATS_INC(mib2.ipindiscards);
+      return ERR_OK;
+    }
+  }
+
+  /* packet not for us? */
+  if (netif == NULL) {
+    /* packet not for us, route or discard */
+    LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_TRACE, ("ip4_input: packet not for us.\n"));
+#if IP_FORWARD
+    /* non-broadcast packet? */
+    if (!ip4_addr_isbroadcast(ip4_current_dest_addr(), inp)) {
+      /* try to forward IP packet on (other) interfaces */
+      ip4_forward(p, (struct ip_hdr *)p->payload, inp);
+    } else
+#endif /* IP_FORWARD */
+    {
+      IP_STATS_INC(ip.drop);
+      MIB2_STATS_INC(mib2.ipinaddrerrors);
+      MIB2_STATS_INC(mib2.ipindiscards);
+    }
+    pbuf_free(p);
+    return ERR_OK;
+  }
+  /* packet consists of multiple fragments? */
+  if ((IPH_OFFSET(iphdr) & PP_HTONS(IP_OFFMASK | IP_MF)) != 0) {
+#if IP_REASSEMBLY /* packet fragment reassembly code present? */
+    LWIP_DEBUGF(IP_DEBUG, ("IP packet is a fragment (id=0x%04"X16_F" tot_len=%"U16_F" len=%"U16_F" MF=%"U16_F" offset=%"U16_F"), calling ip4_reass()\n",
+                           lwip_ntohs(IPH_ID(iphdr)), p->tot_len, lwip_ntohs(IPH_LEN(iphdr)), (u16_t)!!(IPH_OFFSET(iphdr) & PP_HTONS(IP_MF)), (u16_t)((lwip_ntohs(IPH_OFFSET(iphdr)) & IP_OFFMASK) * 8)));
+    /* reassemble the packet*/
+    p = ip4_reass(p);
+    /* packet not fully reassembled yet? */
+    if (p == NULL) {
+      return ERR_OK;
+    }
+    iphdr = (const struct ip_hdr *)p->payload;
+#else /* IP_REASSEMBLY == 0, no packet fragment reassembly code present */
+    pbuf_free(p);
+    LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("IP packet dropped since it was fragmented (0x%"X16_F") (while IP_REASSEMBLY == 0).\n",
+                lwip_ntohs(IPH_OFFSET(iphdr))));
+    IP_STATS_INC(ip.opterr);
+    IP_STATS_INC(ip.drop);
+    /* unsupported protocol feature */
+    MIB2_STATS_INC(mib2.ipinunknownprotos);
+    return ERR_OK;
+#endif /* IP_REASSEMBLY */
+  }
+
+#if IP_OPTIONS_ALLOWED == 0 /* no support for IP options in the IP header? */
+
+#if LWIP_IGMP
+  /* there is an extra "router alert" option in IGMP messages which we allow for but do not police */
+  if ((iphdr_hlen > IP_HLEN) &&  (IPH_PROTO(iphdr) != IP_PROTO_IGMP)) {
+#else
+  if (iphdr_hlen > IP_HLEN) {
+#endif /* LWIP_IGMP */
+    LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("IP packet dropped since there were IP options (while IP_OPTIONS_ALLOWED == 0).\n"));
+    pbuf_free(p);
+    IP_STATS_INC(ip.opterr);
+    IP_STATS_INC(ip.drop);
+    /* unsupported protocol feature */
+    MIB2_STATS_INC(mib2.ipinunknownprotos);
+    return ERR_OK;
+  }
+#endif /* IP_OPTIONS_ALLOWED == 0 */
+
+  /* send to upper layers */
+  LWIP_DEBUGF(IP_DEBUG, ("ip4_input: \n"));
+  ip4_debug_print(p);
+  LWIP_DEBUGF(IP_DEBUG, ("ip4_input: p->len %"U16_F" p->tot_len %"U16_F"\n", p->len, p->tot_len));
+
+  ip_data.current_netif = netif;
+  ip_data.current_input_netif = inp;
+  ip_data.current_ip4_header = iphdr;
+  ip_data.current_ip_header_tot_len = IPH_HL_BYTES(iphdr);
+
+#if LWIP_RAW
+  /* raw input did not eat the packet? */
+  raw_status = raw_input(p, inp);
+  if (raw_status != RAW_INPUT_EATEN)
+#endif /* LWIP_RAW */
+  {
+    pbuf_remove_header(p, iphdr_hlen); /* Move to payload, no check necessary. */
+
+    switch (IPH_PROTO(iphdr)) {
+#if LWIP_UDP
+      case IP_PROTO_UDP:
+#if LWIP_UDPLITE
+      case IP_PROTO_UDPLITE:
+#endif /* LWIP_UDPLITE */
+        MIB2_STATS_INC(mib2.ipindelivers);
+        udp_input(p, inp);
+        break;
+#endif /* LWIP_UDP */
+#if LWIP_TCP
+      case IP_PROTO_TCP:
+        MIB2_STATS_INC(mib2.ipindelivers);
+        tcp_input(p, inp);
+        break;
+#endif /* LWIP_TCP */
+#if LWIP_ICMP
+      case IP_PROTO_ICMP:
+        MIB2_STATS_INC(mib2.ipindelivers);
+#if ETHARP_SUPPORT_STATIC_ENTRIES && LWIP_DHCP
+      /* FOR PING ERROR WHEN NO ARP PAKCET */
+        etharp_add_static_entry(ip4_current_src_addr(), &(hdr->shwaddr));
+#endif /* ETHARP_SUPPORT_STATIC_ENTRIES */
+        icmp_input(p, inp);
+        break;
+#endif /* LWIP_ICMP */
+#if LWIP_IGMP
+      case IP_PROTO_IGMP:
+        igmp_input(p, inp, ip4_current_dest_addr());
+        break;
+#endif /* LWIP_IGMP */
+      default:
+#if LWIP_RAW
+        if (raw_status == RAW_INPUT_DELIVERED) {
+          MIB2_STATS_INC(mib2.ipindelivers);
+        } else
+#endif /* LWIP_RAW */
+        {
+#if LWIP_ICMP
+          /* send ICMP destination protocol unreachable unless is was a broadcast */
+          if (!ip4_addr_isbroadcast(ip4_current_dest_addr(), netif) &&
+              !ip4_addr_ismulticast(ip4_current_dest_addr())) {
+            pbuf_header_force(p, (s16_t)iphdr_hlen); /* Move to ip header, no check necessary. */
+            icmp_dest_unreach(p, ICMP_DUR_PROTO);
+          }
+#endif /* LWIP_ICMP */
+
+          LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("Unsupported transport protocol %"U16_F"\n", (u16_t)IPH_PROTO(iphdr)));
+
+          IP_STATS_INC(ip.proterr);
+          IP_STATS_INC(ip.drop);
+          MIB2_STATS_INC(mib2.ipinunknownprotos);
+        }
+        pbuf_free(p);
+        break;
+    }
+  }
+
+  /* @todo: this is not really necessary... */
+  ip_data.current_netif = NULL;
+  ip_data.current_input_netif = NULL;
+  ip_data.current_ip4_header = NULL;
+  ip_data.current_ip_header_tot_len = 0;
+  ip4_addr_set_any(ip4_current_src_addr());
+  ip4_addr_set_any(ip4_current_dest_addr());
+
+  return ERR_OK;
+}
+
+/**
+ * Sends an IP packet on a network interface. This function constructs
+ * the IP header and calculates the IP header checksum. If the source
+ * IP address is NULL, the IP address of the outgoing network
+ * interface is filled in as source address.
+ * If the destination IP address is LWIP_IP_HDRINCL, p is assumed to already
+ * include an IP header and p->payload points to it instead of the data.
+ *
+ * @param p the packet to send (p->payload points to the data, e.g. next
+            protocol header; if dest == LWIP_IP_HDRINCL, p already includes an
+            IP header and p->payload points to that IP header)
+ * @param src the source IP address to send from (if src == IP4_ADDR_ANY, the
+ *         IP  address of the netif used to send is used as source address)
+ * @param dest the destination IP address to send the packet to
+ * @param ttl the TTL value to be set in the IP header
+ * @param tos the TOS value to be set in the IP header
+ * @param proto the PROTOCOL to be set in the IP header
+ * @param netif the netif on which to send this packet
+ * @return ERR_OK if the packet was sent OK
+ *         ERR_BUF if p doesn't have enough space for IP/LINK headers
+ *         returns errors returned by netif->output
+ *
+ * @note ip_id: RFC791 "some host may be able to simply use
+ *  unique identifiers independent of destination"
+ */
+err_t
+ip4_output_if(struct pbuf *p, const ip4_addr_t *src, const ip4_addr_t *dest,
+              u8_t ttl, u8_t tos,
+              u8_t proto, struct netif *netif)
+{
+#if IP_OPTIONS_SEND
+  return ip4_output_if_opt(p, src, dest, ttl, tos, proto, netif, NULL, 0);
+}
+
+/**
+ * Same as ip_output_if() but with the possibility to include IP options:
+ *
+ * @ param ip_options pointer to the IP options, copied into the IP header
+ * @ param optlen length of ip_options
+ */
+err_t
+ip4_output_if_opt(struct pbuf *p, const ip4_addr_t *src, const ip4_addr_t *dest,
+                  u8_t ttl, u8_t tos, u8_t proto, struct netif *netif, void *ip_options,
+                  u16_t optlen)
+{
+#endif /* IP_OPTIONS_SEND */
+  const ip4_addr_t *src_used = src;
+  if (dest != LWIP_IP_HDRINCL) {
+    if (ip4_addr_isany(src)) {
+      src_used = netif_ip4_addr(netif);
+    }
+  }
+
+#if IP_OPTIONS_SEND
+  return ip4_output_if_opt_src(p, src_used, dest, ttl, tos, proto, netif,
+                               ip_options, optlen);
+#else /* IP_OPTIONS_SEND */
+  return ip4_output_if_src(p, src_used, dest, ttl, tos, proto, netif);
+#endif /* IP_OPTIONS_SEND */
+}
+
+/**
+ * Same as ip_output_if() but 'src' address is not replaced by netif address
+ * when it is 'any'.
+ */
+err_t
+ip4_output_if_src(struct pbuf *p, const ip4_addr_t *src, const ip4_addr_t *dest,
+                  u8_t ttl, u8_t tos,
+                  u8_t proto, struct netif *netif)
+{
+#if IP_OPTIONS_SEND
+  return ip4_output_if_opt_src(p, src, dest, ttl, tos, proto, netif, NULL, 0);
+}
+
+/**
+ * Same as ip_output_if_opt() but 'src' address is not replaced by netif address
+ * when it is 'any'.
+ */
+err_t
+ip4_output_if_opt_src(struct pbuf *p, const ip4_addr_t *src, const ip4_addr_t *dest,
+                      u8_t ttl, u8_t tos, u8_t proto, struct netif *netif, void *ip_options,
+                      u16_t optlen)
+{
+#endif /* IP_OPTIONS_SEND */
+  struct ip_hdr *iphdr;
+  ip4_addr_t dest_addr;
+#if CHECKSUM_GEN_IP_INLINE
+  u32_t chk_sum = 0;
+#endif /* CHECKSUM_GEN_IP_INLINE */
+
+  LWIP_ASSERT_CORE_LOCKED();
+  LWIP_IP_CHECK_PBUF_REF_COUNT_FOR_TX(p);
+
+  MIB2_STATS_INC(mib2.ipoutrequests);
+
+  /* Should the IP header be generated or is it already included in p? */
+  if (dest != LWIP_IP_HDRINCL) {
+    u16_t ip_hlen = IP_HLEN;
+#if IP_OPTIONS_SEND
+    u16_t optlen_aligned = 0;
+    if (optlen != 0) {
+#if CHECKSUM_GEN_IP_INLINE
+      int i;
+#endif /* CHECKSUM_GEN_IP_INLINE */
+      if (optlen > (IP_HLEN_MAX - IP_HLEN)) {
+        /* optlen too long */
+        LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("ip4_output_if_opt: optlen too long\n"));
+        IP_STATS_INC(ip.err);
+        MIB2_STATS_INC(mib2.ipoutdiscards);
+        return ERR_VAL;
+      }
+      /* round up to a multiple of 4 */
+      optlen_aligned = (u16_t)((optlen + 3) & ~3);
+      ip_hlen = (u16_t)(ip_hlen + optlen_aligned);
+      /* First write in the IP options */
+      if (pbuf_add_header(p, optlen_aligned)) {
+        LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("ip4_output_if_opt: not enough room for IP options in pbuf\n"));
+        IP_STATS_INC(ip.err);
+        MIB2_STATS_INC(mib2.ipoutdiscards);
+        return ERR_BUF;
+      }
+      MEMCPY(p->payload, ip_options, optlen);
+      if (optlen < optlen_aligned) {
+        /* zero the remaining bytes */
+        memset(((char *)p->payload) + optlen, 0, (size_t)(optlen_aligned - optlen));
+      }
+#if CHECKSUM_GEN_IP_INLINE
+      for (i = 0; i < optlen_aligned / 2; i++) {
+        chk_sum += ((u16_t *)p->payload)[i];
+      }
+#endif /* CHECKSUM_GEN_IP_INLINE */
+    }
+#endif /* IP_OPTIONS_SEND */
+    /* generate IP header */
+    if (pbuf_add_header(p, IP_HLEN)) {
+      LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("ip4_output: not enough room for IP header in pbuf\n"));
+
+      IP_STATS_INC(ip.err);
+      MIB2_STATS_INC(mib2.ipoutdiscards);
+      return ERR_BUF;
+    }
+
+    iphdr = (struct ip_hdr *)p->payload;
+    LWIP_ASSERT("check that first pbuf can hold struct ip_hdr",
+                (p->len >= sizeof(struct ip_hdr)));
+
+    IPH_TTL_SET(iphdr, ttl);
+    IPH_PROTO_SET(iphdr, proto);
+#if CHECKSUM_GEN_IP_INLINE
+    chk_sum += PP_NTOHS(proto | (ttl << 8));
+#endif /* CHECKSUM_GEN_IP_INLINE */
+
+    /* dest cannot be NULL here */
+    ip4_addr_copy(iphdr->dest, *dest);
+#if CHECKSUM_GEN_IP_INLINE
+    chk_sum += ip4_addr_get_u32(&iphdr->dest) & 0xFFFF;
+    chk_sum += ip4_addr_get_u32(&iphdr->dest) >> 16;
+#endif /* CHECKSUM_GEN_IP_INLINE */
+
+    IPH_VHL_SET(iphdr, 4, ip_hlen / 4);
+    IPH_TOS_SET(iphdr, tos);
+#if CHECKSUM_GEN_IP_INLINE
+    chk_sum += PP_NTOHS(tos | (iphdr->_v_hl << 8));
+#endif /* CHECKSUM_GEN_IP_INLINE */
+    IPH_LEN_SET(iphdr, lwip_htons(p->tot_len));
+#if CHECKSUM_GEN_IP_INLINE
+    chk_sum += iphdr->_len;
+#endif /* CHECKSUM_GEN_IP_INLINE */
+    IPH_OFFSET_SET(iphdr, 0);
+    IPH_ID_SET(iphdr, lwip_htons(ip_id));
+#if CHECKSUM_GEN_IP_INLINE
+    chk_sum += iphdr->_id;
+#endif /* CHECKSUM_GEN_IP_INLINE */
+    ++ip_id;
+
+    if (src == NULL) {
+      ip4_addr_copy(iphdr->src, *IP4_ADDR_ANY4);
+    } else {
+      /* src cannot be NULL here */
+      ip4_addr_copy(iphdr->src, *src);
+    }
+
+#if CHECKSUM_GEN_IP_INLINE
+    chk_sum += ip4_addr_get_u32(&iphdr->src) & 0xFFFF;
+    chk_sum += ip4_addr_get_u32(&iphdr->src) >> 16;
+    chk_sum = (chk_sum >> 16) + (chk_sum & 0xFFFF);
+    chk_sum = (chk_sum >> 16) + chk_sum;
+    chk_sum = ~chk_sum;
+    IF__NETIF_CHECKSUM_ENABLED(netif, NETIF_CHECKSUM_GEN_IP) {
+      iphdr->_chksum = (u16_t)chk_sum; /* network order */
+    }
+#if LWIP_CHECKSUM_CTRL_PER_NETIF
+    else {
+      IPH_CHKSUM_SET(iphdr, 0);
+    }
+#endif /* LWIP_CHECKSUM_CTRL_PER_NETIF*/
+#else /* CHECKSUM_GEN_IP_INLINE */
+    IPH_CHKSUM_SET(iphdr, 0);
+#if CHECKSUM_GEN_IP
+    IF__NETIF_CHECKSUM_ENABLED(netif, NETIF_CHECKSUM_GEN_IP) {
+      IPH_CHKSUM_SET(iphdr, inet_chksum(iphdr, ip_hlen));
+    }
+#endif /* CHECKSUM_GEN_IP */
+#endif /* CHECKSUM_GEN_IP_INLINE */
+  } else {
+    /* IP header already included in p */
+    if (p->len < IP_HLEN) {
+      LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("ip4_output: LWIP_IP_HDRINCL but pbuf is too short\n"));
+      IP_STATS_INC(ip.err);
+      MIB2_STATS_INC(mib2.ipoutdiscards);
+      return ERR_BUF;
+    }
+    iphdr = (struct ip_hdr *)p->payload;
+    ip4_addr_copy(dest_addr, iphdr->dest);
+    dest = &dest_addr;
+  }
+
+  IP_STATS_INC(ip.xmit);
+
+  LWIP_DEBUGF(IP_DEBUG, ("ip4_output_if: %c%c%"U16_F"\n", netif->name[0], netif->name[1], (u16_t)netif->num));
+  ip4_debug_print(p);
+
+#if ENABLE_LOOPBACK
+  if (ip4_addr_cmp(dest, netif_ip4_addr(netif))
+#if !LWIP_HAVE_LOOPIF
+      || ip4_addr_isloopback(dest)
+#endif /* !LWIP_HAVE_LOOPIF */
+     ) {
+    /* Packet to self, enqueue it for loopback */
+    LWIP_DEBUGF(IP_DEBUG, ("netif_loop_output()"));
+    return netif_loop_output(netif, p);
+  }
+#if LWIP_MULTICAST_TX_OPTIONS
+  if ((p->flags & PBUF_FLAG_MCASTLOOP) != 0) {
+    netif_loop_output(netif, p);
+  }
+#endif /* LWIP_MULTICAST_TX_OPTIONS */
+#endif /* ENABLE_LOOPBACK */
+#if IP_FRAG
+  /* don't fragment if interface has mtu set to 0 [loopif] */
+  if (netif->mtu && (p->tot_len > netif->mtu)) {
+    return ip4_frag(p, netif, dest);
+  }
+#endif /* IP_FRAG */
+
+  LWIP_DEBUGF(IP_DEBUG, ("ip4_output_if: call netif->output()\n"));
+  return netif->output(netif, p, dest);
+}
+
+/**
+ * Simple interface to ip_output_if. It finds the outgoing network
+ * interface and calls upon ip_output_if to do the actual work.
+ *
+ * @param p the packet to send (p->payload points to the data, e.g. next
+            protocol header; if dest == LWIP_IP_HDRINCL, p already includes an
+            IP header and p->payload points to that IP header)
+ * @param src the source IP address to send from (if src == IP4_ADDR_ANY, the
+ *         IP  address of the netif used to send is used as source address)
+ * @param dest the destination IP address to send the packet to
+ * @param ttl the TTL value to be set in the IP header
+ * @param tos the TOS value to be set in the IP header
+ * @param proto the PROTOCOL to be set in the IP header
+ *
+ * @return ERR_RTE if no route is found
+ *         see ip_output_if() for more return values
+ */
+err_t
+ip4_output(struct pbuf *p, const ip4_addr_t *src, const ip4_addr_t *dest,
+           u8_t ttl, u8_t tos, u8_t proto)
+{
+  struct netif *netif;
+
+  LWIP_IP_CHECK_PBUF_REF_COUNT_FOR_TX(p);
+
+  if ((netif = ip4_route_src(src, dest)) == NULL) {
+    LWIP_DEBUGF(IP_DEBUG, ("ip4_output: No route to %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n",
+                           ip4_addr1_16(dest), ip4_addr2_16(dest), ip4_addr3_16(dest), ip4_addr4_16(dest)));
+    IP_STATS_INC(ip.rterr);
+    return ERR_RTE;
+  }
+
+  return ip4_output_if(p, src, dest, ttl, tos, proto, netif);
+}
+
+#if LWIP_NETIF_USE_HINTS
+/** Like ip_output, but takes and addr_hint pointer that is passed on to netif->addr_hint
+ *  before calling ip_output_if.
+ *
+ * @param p the packet to send (p->payload points to the data, e.g. next
+            protocol header; if dest == LWIP_IP_HDRINCL, p already includes an
+            IP header and p->payload points to that IP header)
+ * @param src the source IP address to send from (if src == IP4_ADDR_ANY, the
+ *         IP  address of the netif used to send is used as source address)
+ * @param dest the destination IP address to send the packet to
+ * @param ttl the TTL value to be set in the IP header
+ * @param tos the TOS value to be set in the IP header
+ * @param proto the PROTOCOL to be set in the IP header
+ * @param netif_hint netif output hint pointer set to netif->hint before
+ *        calling ip_output_if()
+ *
+ * @return ERR_RTE if no route is found
+ *         see ip_output_if() for more return values
+ */
+err_t
+ip4_output_hinted(struct pbuf *p, const ip4_addr_t *src, const ip4_addr_t *dest,
+                  u8_t ttl, u8_t tos, u8_t proto, struct netif_hint *netif_hint)
+{
+  struct netif *netif;
+  err_t err;
+
+  LWIP_IP_CHECK_PBUF_REF_COUNT_FOR_TX(p);
+
+  if ((netif = ip4_route_src(src, dest)) == NULL) {
+    LWIP_DEBUGF(IP_DEBUG, ("ip4_output: No route to %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n",
+                           ip4_addr1_16(dest), ip4_addr2_16(dest), ip4_addr3_16(dest), ip4_addr4_16(dest)));
+    IP_STATS_INC(ip.rterr);
+    return ERR_RTE;
+  }
+
+  NETIF_SET_HINTS(netif, netif_hint);
+  err = ip4_output_if(p, src, dest, ttl, tos, proto, netif);
+  NETIF_RESET_HINTS(netif);
+
+  return err;
+}
+#endif /* LWIP_NETIF_USE_HINTS*/
+
+#if IP_DEBUG
+/* Print an IP header by using LWIP_DEBUGF
+ * @param p an IP packet, p->payload pointing to the IP header
+ */
+void
+ip4_debug_print(struct pbuf *p)
+{
+  struct ip_hdr *iphdr = (struct ip_hdr *)p->payload;
+
+  LWIP_DEBUGF(IP_DEBUG, ("IP header:\n"));
+  LWIP_DEBUGF(IP_DEBUG, ("+-------------------------------+\n"));
+  LWIP_DEBUGF(IP_DEBUG, ("|%2"S16_F" |%2"S16_F" |  0x%02"X16_F" |     %5"U16_F"     | (v, hl, tos, len)\n",
+                         (u16_t)IPH_V(iphdr),
+                         (u16_t)IPH_HL(iphdr),
+                         (u16_t)IPH_TOS(iphdr),
+                         lwip_ntohs(IPH_LEN(iphdr))));
+  LWIP_DEBUGF(IP_DEBUG, ("+-------------------------------+\n"));
+  LWIP_DEBUGF(IP_DEBUG, ("|    %5"U16_F"      |%"U16_F"%"U16_F"%"U16_F"|    %4"U16_F"   | (id, flags, offset)\n",
+                         lwip_ntohs(IPH_ID(iphdr)),
+                         (u16_t)(lwip_ntohs(IPH_OFFSET(iphdr)) >> 15 & 1),
+                         (u16_t)(lwip_ntohs(IPH_OFFSET(iphdr)) >> 14 & 1),
+                         (u16_t)(lwip_ntohs(IPH_OFFSET(iphdr)) >> 13 & 1),
+                         (u16_t)(lwip_ntohs(IPH_OFFSET(iphdr)) & IP_OFFMASK)));
+  LWIP_DEBUGF(IP_DEBUG, ("+-------------------------------+\n"));
+  LWIP_DEBUGF(IP_DEBUG, ("|  %3"U16_F"  |  %3"U16_F"  |    0x%04"X16_F"     | (ttl, proto, chksum)\n",
+                         (u16_t)IPH_TTL(iphdr),
+                         (u16_t)IPH_PROTO(iphdr),
+                         lwip_ntohs(IPH_CHKSUM(iphdr))));
+  LWIP_DEBUGF(IP_DEBUG, ("+-------------------------------+\n"));
+  LWIP_DEBUGF(IP_DEBUG, ("|  %3"U16_F"  |  %3"U16_F"  |  %3"U16_F"  |  %3"U16_F"  | (src)\n",
+                         ip4_addr1_16_val(iphdr->src),
+                         ip4_addr2_16_val(iphdr->src),
+                         ip4_addr3_16_val(iphdr->src),
+                         ip4_addr4_16_val(iphdr->src)));
+  LWIP_DEBUGF(IP_DEBUG, ("+-------------------------------+\n"));
+  LWIP_DEBUGF(IP_DEBUG, ("|  %3"U16_F"  |  %3"U16_F"  |  %3"U16_F"  |  %3"U16_F"  | (dest)\n",
+                         ip4_addr1_16_val(iphdr->dest),
+                         ip4_addr2_16_val(iphdr->dest),
+                         ip4_addr3_16_val(iphdr->dest),
+                         ip4_addr4_16_val(iphdr->dest)));
+  LWIP_DEBUGF(IP_DEBUG, ("+-------------------------------+\n"));
+}
+#endif /* IP_DEBUG */
+
+#endif /* LWIP_IPV4 */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/core/ipv4/ip4_addr.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/core/ipv4/ip4_addr.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/core/ipv4/ip4_addr.c	(revision 457)
@@ -0,0 +1,321 @@
+/**
+ * @file
+ * This is the IPv4 address tools implementation.
+ *
+ */
+
+/*
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Adam Dunkels <adam@sics.se>
+ *
+ */
+
+#include "lwip/opt.h"
+
+#if LWIP_IPV4
+
+#include "lwip/ip_addr.h"
+#include "lwip/netif.h"
+
+/* used by IP4_ADDR_ANY and IP_ADDR_BROADCAST in ip_addr.h */
+const ip_addr_t ip_addr_any = IPADDR4_INIT(IPADDR_ANY);
+const ip_addr_t ip_addr_broadcast = IPADDR4_INIT(IPADDR_BROADCAST);
+
+/**
+ * Determine if an address is a broadcast address on a network interface
+ *
+ * @param addr address to be checked
+ * @param netif the network interface against which the address is checked
+ * @return returns non-zero if the address is a broadcast address
+ */
+u8_t
+ip4_addr_isbroadcast_u32(u32_t addr, const struct netif *netif)
+{
+  ip4_addr_t ipaddr;
+  ip4_addr_set_u32(&ipaddr, addr);
+
+  /* all ones (broadcast) or all zeroes (old skool broadcast) */
+  if ((~addr == IPADDR_ANY) ||
+      (addr == IPADDR_ANY)) {
+    return 1;
+    /* no broadcast support on this network interface? */
+  } else if ((netif->flags & NETIF_FLAG_BROADCAST) == 0) {
+    /* the given address cannot be a broadcast address
+     * nor can we check against any broadcast addresses */
+    return 0;
+    /* address matches network interface address exactly? => no broadcast */
+  } else if (addr == ip4_addr_get_u32(netif_ip4_addr(netif))) {
+    return 0;
+    /*  on the same (sub) network... */
+  } else if (ip4_addr_netcmp(&ipaddr, netif_ip4_addr(netif), netif_ip4_netmask(netif))
+             /* ...and host identifier bits are all ones? =>... */
+             && ((addr & ~ip4_addr_get_u32(netif_ip4_netmask(netif))) ==
+                 (IPADDR_BROADCAST & ~ip4_addr_get_u32(netif_ip4_netmask(netif))))) {
+    /* => network broadcast address */
+    return 1;
+  } else {
+    return 0;
+  }
+}
+
+/** Checks if a netmask is valid (starting with ones, then only zeros)
+ *
+ * @param netmask the IPv4 netmask to check (in network byte order!)
+ * @return 1 if the netmask is valid, 0 if it is not
+ */
+u8_t
+ip4_addr_netmask_valid(u32_t netmask)
+{
+  u32_t mask;
+  u32_t nm_hostorder = lwip_htonl(netmask);
+
+  /* first, check for the first zero */
+  for (mask = 1UL << 31 ; mask != 0; mask >>= 1) {
+    if ((nm_hostorder & mask) == 0) {
+      break;
+    }
+  }
+  /* then check that there is no one */
+  for (; mask != 0; mask >>= 1) {
+    if ((nm_hostorder & mask) != 0) {
+      /* there is a one after the first zero -> invalid */
+      return 0;
+    }
+  }
+  /* no one after the first zero -> valid */
+  return 1;
+}
+
+/**
+ * Ascii internet address interpretation routine.
+ * The value returned is in network order.
+ *
+ * @param cp IP address in ascii representation (e.g. "127.0.0.1")
+ * @return ip address in network order
+ */
+u32_t
+ipaddr_addr(const char *cp)
+{
+  ip4_addr_t val;
+
+  if (ip4addr_aton(cp, &val)) {
+    return ip4_addr_get_u32(&val);
+  }
+  return (IPADDR_NONE);
+}
+
+/**
+ * Check whether "cp" is a valid ascii representation
+ * of an Internet address and convert to a binary address.
+ * Returns 1 if the address is valid, 0 if not.
+ * This replaces inet_addr, the return value from which
+ * cannot distinguish between failure and a local broadcast address.
+ *
+ * @param cp IP address in ascii representation (e.g. "127.0.0.1")
+ * @param addr pointer to which to save the ip address in network order
+ * @return 1 if cp could be converted to addr, 0 on failure
+ */
+int
+ip4addr_aton(const char *cp, ip4_addr_t *addr)
+{
+  u32_t val;
+  u8_t base;
+  char c;
+  u32_t parts[4];
+  u32_t *pp = parts;
+
+  c = *cp;
+  for (;;) {
+    /*
+     * Collect number up to ``.''.
+     * Values are specified as for C:
+     * 0x=hex, 0=octal, 1-9=decimal.
+     */
+    if (!lwip_isdigit(c)) {
+      return 0;
+    }
+    val = 0;
+    base = 10;
+    if (c == '0') {
+      c = *++cp;
+      if (c == 'x' || c == 'X') {
+        base = 16;
+        c = *++cp;
+      } else {
+        base = 8;
+      }
+    }
+    for (;;) {
+      if (lwip_isdigit(c)) {
+        val = (val * base) + (u32_t)(c - '0');
+        c = *++cp;
+      } else if (base == 16 && lwip_isxdigit(c)) {
+        val = (val << 4) | (u32_t)(c + 10 - (lwip_islower(c) ? 'a' : 'A'));
+        c = *++cp;
+      } else {
+        break;
+      }
+    }
+    if (c == '.') {
+      /*
+       * Internet format:
+       *  a.b.c.d
+       *  a.b.c   (with c treated as 16 bits)
+       *  a.b (with b treated as 24 bits)
+       */
+      if (pp >= parts + 3) {
+        return 0;
+      }
+      *pp++ = val;
+      c = *++cp;
+    } else {
+      break;
+    }
+  }
+  /*
+   * Check for trailing characters.
+   */
+  if (c != '\0' && !lwip_isspace(c)) {
+    return 0;
+  }
+  /*
+   * Concoct the address according to
+   * the number of parts specified.
+   */
+  switch (pp - parts + 1) {
+
+    case 0:
+      return 0;       /* initial nondigit */
+
+    case 1:             /* a -- 32 bits */
+      break;
+
+    case 2:             /* a.b -- 8.24 bits */
+      if (val > 0xffffffUL) {
+        return 0;
+      }
+      if (parts[0] > 0xff) {
+        return 0;
+      }
+      val |= parts[0] << 24;
+      break;
+
+    case 3:             /* a.b.c -- 8.8.16 bits */
+      if (val > 0xffff) {
+        return 0;
+      }
+      if ((parts[0] > 0xff) || (parts[1] > 0xff)) {
+        return 0;
+      }
+      val |= (parts[0] << 24) | (parts[1] << 16);
+      break;
+
+    case 4:             /* a.b.c.d -- 8.8.8.8 bits */
+      if (val > 0xff) {
+        return 0;
+      }
+      if ((parts[0] > 0xff) || (parts[1] > 0xff) || (parts[2] > 0xff)) {
+        return 0;
+      }
+      val |= (parts[0] << 24) | (parts[1] << 16) | (parts[2] << 8);
+      break;
+    default:
+      LWIP_ASSERT("unhandled", 0);
+      break;
+  }
+  if (addr) {
+    ip4_addr_set_u32(addr, lwip_htonl(val));
+  }
+  return 1;
+}
+
+/**
+ * Convert numeric IP address into decimal dotted ASCII representation.
+ * returns ptr to static buffer; not reentrant!
+ *
+ * @param addr ip address in network order to convert
+ * @return pointer to a global static (!) buffer that holds the ASCII
+ *         representation of addr
+ */
+char *
+ip4addr_ntoa(const ip4_addr_t *addr)
+{
+  static char str[IP4ADDR_STRLEN_MAX];
+  return ip4addr_ntoa_r(addr, str, IP4ADDR_STRLEN_MAX);
+}
+
+/**
+ * Same as ip4addr_ntoa, but reentrant since a user-supplied buffer is used.
+ *
+ * @param addr ip address in network order to convert
+ * @param buf target buffer where the string is stored
+ * @param buflen length of buf
+ * @return either pointer to buf which now holds the ASCII
+ *         representation of addr or NULL if buf was too small
+ */
+char *
+ip4addr_ntoa_r(const ip4_addr_t *addr, char *buf, int buflen)
+{
+  u32_t s_addr;
+  char inv[3];
+  char *rp;
+  u8_t *ap;
+  u8_t rem;
+  u8_t n;
+  u8_t i;
+  int len = 0;
+
+  s_addr = ip4_addr_get_u32(addr);
+
+  rp = buf;
+  ap = (u8_t *)&s_addr;
+  for (n = 0; n < 4; n++) {
+    i = 0;
+    do {
+      rem = *ap % (u8_t)10;
+      *ap /= (u8_t)10;
+      inv[i++] = (char)('0' + rem);
+    } while (*ap);
+    while (i--) {
+      if (len++ >= buflen) {
+        return NULL;
+      }
+      *rp++ = inv[i];
+    }
+    if (len++ >= buflen) {
+      return NULL;
+    }
+    *rp++ = '.';
+    ap++;
+  }
+  *--rp = 0;
+  return buf;
+}
+
+#endif /* LWIP_IPV4 */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/core/ipv4/ip4_frag.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/core/ipv4/ip4_frag.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/core/ipv4/ip4_frag.c	(revision 457)
@@ -0,0 +1,894 @@
+/**
+ * @file
+ * This is the IPv4 packet segmentation and reassembly implementation.
+ *
+ */
+
+/*
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Jani Monoses <jani@iv.ro>
+ *         Simon Goldschmidt
+ * original reassembly code by Adam Dunkels <adam@sics.se>
+ *
+ */
+
+#include "lwip/opt.h"
+
+#if LWIP_IPV4
+
+#include "lwip/ip4_frag.h"
+#include "lwip/def.h"
+#include "lwip/inet_chksum.h"
+#include "lwip/netif.h"
+#include "lwip/stats.h"
+#include "lwip/icmp.h"
+
+#include <string.h>
+
+#if IP_REASSEMBLY
+/**
+ * The IP reassembly code currently has the following limitations:
+ * - IP header options are not supported
+ * - fragments must not overlap (e.g. due to different routes),
+ *   currently, overlapping or duplicate fragments are thrown away
+ *   if IP_REASS_CHECK_OVERLAP=1 (the default)!
+ *
+ * @todo: work with IP header options
+ */
+
+/** Setting this to 0, you can turn off checking the fragments for overlapping
+ * regions. The code gets a little smaller. Only use this if you know that
+ * overlapping won't occur on your network! */
+#ifndef IP_REASS_CHECK_OVERLAP
+#define IP_REASS_CHECK_OVERLAP 1
+#endif /* IP_REASS_CHECK_OVERLAP */
+
+/** Set to 0 to prevent freeing the oldest datagram when the reassembly buffer is
+ * full (IP_REASS_MAX_PBUFS pbufs are enqueued). The code gets a little smaller.
+ * Datagrams will be freed by timeout only. Especially useful when MEMP_NUM_REASSDATA
+ * is set to 1, so one datagram can be reassembled at a time, only. */
+#ifndef IP_REASS_FREE_OLDEST
+#define IP_REASS_FREE_OLDEST 1
+#endif /* IP_REASS_FREE_OLDEST */
+
+#define IP_REASS_FLAG_LASTFRAG 0x01
+
+#define IP_REASS_VALIDATE_TELEGRAM_FINISHED  1
+#define IP_REASS_VALIDATE_PBUF_QUEUED        0
+#define IP_REASS_VALIDATE_PBUF_DROPPED       -1
+
+/** This is a helper struct which holds the starting
+ * offset and the ending offset of this fragment to
+ * easily chain the fragments.
+ * It has the same packing requirements as the IP header, since it replaces
+ * the IP header in memory in incoming fragments (after copying it) to keep
+ * track of the various fragments. (-> If the IP header doesn't need packing,
+ * this struct doesn't need packing, too.)
+ */
+#ifdef PACK_STRUCT_USE_INCLUDES
+#  include "arch/bpstruct.h"
+#endif
+PACK_STRUCT_BEGIN
+struct ip_reass_helper {
+  PACK_STRUCT_FIELD(struct pbuf *next_pbuf);
+  PACK_STRUCT_FIELD(u16_t start);
+  PACK_STRUCT_FIELD(u16_t end);
+} PACK_STRUCT_STRUCT;
+PACK_STRUCT_END
+#ifdef PACK_STRUCT_USE_INCLUDES
+#  include "arch/epstruct.h"
+#endif
+
+#define IP_ADDRESSES_AND_ID_MATCH(iphdrA, iphdrB)  \
+  (ip4_addr_cmp(&(iphdrA)->src, &(iphdrB)->src) && \
+   ip4_addr_cmp(&(iphdrA)->dest, &(iphdrB)->dest) && \
+   IPH_ID(iphdrA) == IPH_ID(iphdrB)) ? 1 : 0
+
+/* global variables */
+static struct ip_reassdata *reassdatagrams;
+static u16_t ip_reass_pbufcount;
+
+/* function prototypes */
+static void ip_reass_dequeue_datagram(struct ip_reassdata *ipr, struct ip_reassdata *prev);
+static int ip_reass_free_complete_datagram(struct ip_reassdata *ipr, struct ip_reassdata *prev);
+
+/**
+ * Reassembly timer base function
+ * for both NO_SYS == 0 and 1 (!).
+ *
+ * Should be called every 1000 msec (defined by IP_TMR_INTERVAL).
+ */
+void
+ip_reass_tmr(void)
+{
+  struct ip_reassdata *r, *prev = NULL;
+
+  r = reassdatagrams;
+  while (r != NULL) {
+    /* Decrement the timer. Once it reaches 0,
+     * clean up the incomplete fragment assembly */
+    if (r->timer > 0) {
+      r->timer--;
+      LWIP_DEBUGF(IP_REASS_DEBUG, ("ip_reass_tmr: timer dec %"U16_F"\n", (u16_t)r->timer));
+      prev = r;
+      r = r->next;
+    } else {
+      /* reassembly timed out */
+      struct ip_reassdata *tmp;
+      LWIP_DEBUGF(IP_REASS_DEBUG, ("ip_reass_tmr: timer timed out\n"));
+      tmp = r;
+      /* get the next pointer before freeing */
+      r = r->next;
+      /* free the helper struct and all enqueued pbufs */
+      ip_reass_free_complete_datagram(tmp, prev);
+    }
+  }
+}
+
+/**
+ * Free a datagram (struct ip_reassdata) and all its pbufs.
+ * Updates the total count of enqueued pbufs (ip_reass_pbufcount),
+ * SNMP counters and sends an ICMP time exceeded packet.
+ *
+ * @param ipr datagram to free
+ * @param prev the previous datagram in the linked list
+ * @return the number of pbufs freed
+ */
+static int
+ip_reass_free_complete_datagram(struct ip_reassdata *ipr, struct ip_reassdata *prev)
+{
+  u16_t pbufs_freed = 0;
+  u16_t clen;
+  struct pbuf *p;
+  struct ip_reass_helper *iprh;
+
+  LWIP_ASSERT("prev != ipr", prev != ipr);
+  if (prev != NULL) {
+    LWIP_ASSERT("prev->next == ipr", prev->next == ipr);
+  }
+
+  MIB2_STATS_INC(mib2.ipreasmfails);
+#if LWIP_ICMP
+  iprh = (struct ip_reass_helper *)ipr->p->payload;
+  if (iprh->start == 0) {
+    /* The first fragment was received, send ICMP time exceeded. */
+    /* First, de-queue the first pbuf from r->p. */
+    p = ipr->p;
+    ipr->p = iprh->next_pbuf;
+    /* Then, copy the original header into it. */
+    SMEMCPY(p->payload, &ipr->iphdr, IP_HLEN);
+    icmp_time_exceeded(p, ICMP_TE_FRAG);
+    clen = pbuf_clen(p);
+    LWIP_ASSERT("pbufs_freed + clen <= 0xffff", pbufs_freed + clen <= 0xffff);
+    pbufs_freed = (u16_t)(pbufs_freed + clen);
+    pbuf_free(p);
+  }
+#endif /* LWIP_ICMP */
+
+  /* First, free all received pbufs.  The individual pbufs need to be released
+     separately as they have not yet been chained */
+  p = ipr->p;
+  while (p != NULL) {
+    struct pbuf *pcur;
+    iprh = (struct ip_reass_helper *)p->payload;
+    pcur = p;
+    /* get the next pointer before freeing */
+    p = iprh->next_pbuf;
+    clen = pbuf_clen(pcur);
+    LWIP_ASSERT("pbufs_freed + clen <= 0xffff", pbufs_freed + clen <= 0xffff);
+    pbufs_freed = (u16_t)(pbufs_freed + clen);
+    pbuf_free(pcur);
+  }
+  /* Then, unchain the struct ip_reassdata from the list and free it. */
+  ip_reass_dequeue_datagram(ipr, prev);
+  LWIP_ASSERT("ip_reass_pbufcount >= pbufs_freed", ip_reass_pbufcount >= pbufs_freed);
+  ip_reass_pbufcount = (u16_t)(ip_reass_pbufcount - pbufs_freed);
+
+  return pbufs_freed;
+}
+
+#if IP_REASS_FREE_OLDEST
+/**
+ * Free the oldest datagram to make room for enqueueing new fragments.
+ * The datagram 'fraghdr' belongs to is not freed!
+ *
+ * @param fraghdr IP header of the current fragment
+ * @param pbufs_needed number of pbufs needed to enqueue
+ *        (used for freeing other datagrams if not enough space)
+ * @return the number of pbufs freed
+ */
+static int
+ip_reass_remove_oldest_datagram(struct ip_hdr *fraghdr, int pbufs_needed)
+{
+  /* @todo Can't we simply remove the last datagram in the
+   *       linked list behind reassdatagrams?
+   */
+  struct ip_reassdata *r, *oldest, *prev, *oldest_prev;
+  int pbufs_freed = 0, pbufs_freed_current;
+  int other_datagrams;
+
+  /* Free datagrams until being allowed to enqueue 'pbufs_needed' pbufs,
+   * but don't free the datagram that 'fraghdr' belongs to! */
+  do {
+    oldest = NULL;
+    prev = NULL;
+    oldest_prev = NULL;
+    other_datagrams = 0;
+    r = reassdatagrams;
+    while (r != NULL) {
+      if (!IP_ADDRESSES_AND_ID_MATCH(&r->iphdr, fraghdr)) {
+        /* Not the same datagram as fraghdr */
+        other_datagrams++;
+        if (oldest == NULL) {
+          oldest = r;
+          oldest_prev = prev;
+        } else if (r->timer <= oldest->timer) {
+          /* older than the previous oldest */
+          oldest = r;
+          oldest_prev = prev;
+        }
+      }
+      if (r->next != NULL) {
+        prev = r;
+      }
+      r = r->next;
+    }
+    if (oldest != NULL) {
+      pbufs_freed_current = ip_reass_free_complete_datagram(oldest, oldest_prev);
+      pbufs_freed += pbufs_freed_current;
+    }
+  } while ((pbufs_freed < pbufs_needed) && (other_datagrams > 1));
+  return pbufs_freed;
+}
+#endif /* IP_REASS_FREE_OLDEST */
+
+/**
+ * Enqueues a new fragment into the fragment queue
+ * @param fraghdr points to the new fragments IP hdr
+ * @param clen number of pbufs needed to enqueue (used for freeing other datagrams if not enough space)
+ * @return A pointer to the queue location into which the fragment was enqueued
+ */
+static struct ip_reassdata *
+ip_reass_enqueue_new_datagram(struct ip_hdr *fraghdr, int clen)
+{
+  struct ip_reassdata *ipr;
+#if ! IP_REASS_FREE_OLDEST
+  LWIP_UNUSED_ARG(clen);
+#endif
+
+  /* No matching previous fragment found, allocate a new reassdata struct */
+  ipr = (struct ip_reassdata *)memp_malloc(MEMP_REASSDATA);
+  if (ipr == NULL) {
+#if IP_REASS_FREE_OLDEST
+    if (ip_reass_remove_oldest_datagram(fraghdr, clen) >= clen) {
+      ipr = (struct ip_reassdata *)memp_malloc(MEMP_REASSDATA);
+    }
+    if (ipr == NULL)
+#endif /* IP_REASS_FREE_OLDEST */
+    {
+      IPFRAG_STATS_INC(ip_frag.memerr);
+      LWIP_DEBUGF(IP_REASS_DEBUG, ("Failed to alloc reassdata struct\n"));
+      return NULL;
+    }
+  }
+  memset(ipr, 0, sizeof(struct ip_reassdata));
+  ipr->timer = IP_REASS_MAXAGE;
+
+  /* enqueue the new structure to the front of the list */
+  ipr->next = reassdatagrams;
+  reassdatagrams = ipr;
+  /* copy the ip header for later tests and input */
+  /* @todo: no ip options supported? */
+  SMEMCPY(&(ipr->iphdr), fraghdr, IP_HLEN);
+  return ipr;
+}
+
+/**
+ * Dequeues a datagram from the datagram queue. Doesn't deallocate the pbufs.
+ * @param ipr points to the queue entry to dequeue
+ */
+static void
+ip_reass_dequeue_datagram(struct ip_reassdata *ipr, struct ip_reassdata *prev)
+{
+  /* dequeue the reass struct  */
+  if (reassdatagrams == ipr) {
+    /* it was the first in the list */
+    reassdatagrams = ipr->next;
+  } else {
+    /* it wasn't the first, so it must have a valid 'prev' */
+    LWIP_ASSERT("sanity check linked list", prev != NULL);
+    prev->next = ipr->next;
+  }
+
+  /* now we can free the ip_reassdata struct */
+  memp_free(MEMP_REASSDATA, ipr);
+}
+
+/**
+ * Chain a new pbuf into the pbuf list that composes the datagram.  The pbuf list
+ * will grow over time as  new pbufs are rx.
+ * Also checks that the datagram passes basic continuity checks (if the last
+ * fragment was received at least once).
+ * @param ipr points to the reassembly state
+ * @param new_p points to the pbuf for the current fragment
+ * @param is_last is 1 if this pbuf has MF==0 (ipr->flags not updated yet)
+ * @return see IP_REASS_VALIDATE_* defines
+ */
+static int
+ip_reass_chain_frag_into_datagram_and_validate(struct ip_reassdata *ipr, struct pbuf *new_p, int is_last)
+{
+  struct ip_reass_helper *iprh, *iprh_tmp, *iprh_prev = NULL;
+  struct pbuf *q;
+  u16_t offset, len;
+  u8_t hlen;
+  struct ip_hdr *fraghdr;
+  int valid = 1;
+
+  /* Extract length and fragment offset from current fragment */
+  fraghdr = (struct ip_hdr *)new_p->payload;
+  len = lwip_ntohs(IPH_LEN(fraghdr));
+  hlen = IPH_HL_BYTES(fraghdr);
+  if (hlen > len) {
+    /* invalid datagram */
+    return IP_REASS_VALIDATE_PBUF_DROPPED;
+  }
+  len = (u16_t)(len - hlen);
+  offset = IPH_OFFSET_BYTES(fraghdr);
+
+  /* overwrite the fragment's ip header from the pbuf with our helper struct,
+   * and setup the embedded helper structure. */
+  /* make sure the struct ip_reass_helper fits into the IP header */
+  LWIP_ASSERT("sizeof(struct ip_reass_helper) <= IP_HLEN",
+              sizeof(struct ip_reass_helper) <= IP_HLEN);
+  iprh = (struct ip_reass_helper *)new_p->payload;
+  iprh->next_pbuf = NULL;
+  iprh->start = offset;
+  iprh->end = (u16_t)(offset + len);
+  if (iprh->end < offset) {
+    /* u16_t overflow, cannot handle this */
+    return IP_REASS_VALIDATE_PBUF_DROPPED;
+  }
+
+  /* Iterate through until we either get to the end of the list (append),
+   * or we find one with a larger offset (insert). */
+  for (q = ipr->p; q != NULL;) {
+    iprh_tmp = (struct ip_reass_helper *)q->payload;
+    if (iprh->start < iprh_tmp->start) {
+      /* the new pbuf should be inserted before this */
+      iprh->next_pbuf = q;
+      if (iprh_prev != NULL) {
+        /* not the fragment with the lowest offset */
+#if IP_REASS_CHECK_OVERLAP
+        if ((iprh->start < iprh_prev->end) || (iprh->end > iprh_tmp->start)) {
+          /* fragment overlaps with previous or following, throw away */
+          return IP_REASS_VALIDATE_PBUF_DROPPED;
+        }
+#endif /* IP_REASS_CHECK_OVERLAP */
+        iprh_prev->next_pbuf = new_p;
+        if (iprh_prev->end != iprh->start) {
+          /* There is a fragment missing between the current
+           * and the previous fragment */
+          valid = 0;
+        }
+      } else {
+#if IP_REASS_CHECK_OVERLAP
+        if (iprh->end > iprh_tmp->start) {
+          /* fragment overlaps with following, throw away */
+          return IP_REASS_VALIDATE_PBUF_DROPPED;
+        }
+#endif /* IP_REASS_CHECK_OVERLAP */
+        /* fragment with the lowest offset */
+        ipr->p = new_p;
+      }
+      break;
+    } else if (iprh->start == iprh_tmp->start) {
+      /* received the same datagram twice: no need to keep the datagram */
+      return IP_REASS_VALIDATE_PBUF_DROPPED;
+#if IP_REASS_CHECK_OVERLAP
+    } else if (iprh->start < iprh_tmp->end) {
+      /* overlap: no need to keep the new datagram */
+      return IP_REASS_VALIDATE_PBUF_DROPPED;
+#endif /* IP_REASS_CHECK_OVERLAP */
+    } else {
+      /* Check if the fragments received so far have no holes. */
+      if (iprh_prev != NULL) {
+        if (iprh_prev->end != iprh_tmp->start) {
+          /* There is a fragment missing between the current
+           * and the previous fragment */
+          valid = 0;
+        }
+      }
+    }
+    q = iprh_tmp->next_pbuf;
+    iprh_prev = iprh_tmp;
+  }
+
+  /* If q is NULL, then we made it to the end of the list. Determine what to do now */
+  if (q == NULL) {
+    if (iprh_prev != NULL) {
+      /* this is (for now), the fragment with the highest offset:
+       * chain it to the last fragment */
+#if IP_REASS_CHECK_OVERLAP
+      LWIP_ASSERT("check fragments don't overlap", iprh_prev->end <= iprh->start);
+#endif /* IP_REASS_CHECK_OVERLAP */
+      iprh_prev->next_pbuf = new_p;
+      if (iprh_prev->end != iprh->start) {
+        valid = 0;
+      }
+    } else {
+#if IP_REASS_CHECK_OVERLAP
+      LWIP_ASSERT("no previous fragment, this must be the first fragment!",
+                  ipr->p == NULL);
+#endif /* IP_REASS_CHECK_OVERLAP */
+      /* this is the first fragment we ever received for this ip datagram */
+      ipr->p = new_p;
+    }
+  }
+
+  /* At this point, the validation part begins: */
+  /* If we already received the last fragment */
+  if (is_last || ((ipr->flags & IP_REASS_FLAG_LASTFRAG) != 0)) {
+    /* and had no holes so far */
+    if (valid) {
+      /* then check if the rest of the fragments is here */
+      /* Check if the queue starts with the first datagram */
+      if ((ipr->p == NULL) || (((struct ip_reass_helper *)ipr->p->payload)->start != 0)) {
+        valid = 0;
+      } else {
+        /* and check that there are no holes after this datagram */
+        iprh_prev = iprh;
+        q = iprh->next_pbuf;
+        while (q != NULL) {
+          iprh = (struct ip_reass_helper *)q->payload;
+          if (iprh_prev->end != iprh->start) {
+            valid = 0;
+            break;
+          }
+          iprh_prev = iprh;
+          q = iprh->next_pbuf;
+        }
+        /* if still valid, all fragments are received
+         * (because to the MF==0 already arrived */
+        if (valid) {
+          LWIP_ASSERT("sanity check", ipr->p != NULL);
+          LWIP_ASSERT("sanity check",
+                      ((struct ip_reass_helper *)ipr->p->payload) != iprh);
+          LWIP_ASSERT("validate_datagram:next_pbuf!=NULL",
+                      iprh->next_pbuf == NULL);
+        }
+      }
+    }
+    /* If valid is 0 here, there are some fragments missing in the middle
+     * (since MF == 0 has already arrived). Such datagrams simply time out if
+     * no more fragments are received... */
+    return valid ? IP_REASS_VALIDATE_TELEGRAM_FINISHED : IP_REASS_VALIDATE_PBUF_QUEUED;
+  }
+  /* If we come here, not all fragments were received, yet! */
+  return IP_REASS_VALIDATE_PBUF_QUEUED; /* not yet valid! */
+}
+
+/**
+ * Reassembles incoming IP fragments into an IP datagram.
+ *
+ * @param p points to a pbuf chain of the fragment
+ * @return NULL if reassembly is incomplete, ? otherwise
+ */
+struct pbuf *
+ip4_reass(struct pbuf *p)
+{
+  struct pbuf *r;
+  struct ip_hdr *fraghdr;
+  struct ip_reassdata *ipr;
+  struct ip_reass_helper *iprh;
+  u16_t offset, len, clen;
+  u8_t hlen;
+  int valid;
+  int is_last;
+
+  IPFRAG_STATS_INC(ip_frag.recv);
+  MIB2_STATS_INC(mib2.ipreasmreqds);
+
+  fraghdr = (struct ip_hdr *)p->payload;
+
+  if (IPH_HL_BYTES(fraghdr) != IP_HLEN) {
+    LWIP_DEBUGF(IP_REASS_DEBUG, ("ip4_reass: IP options currently not supported!\n"));
+    IPFRAG_STATS_INC(ip_frag.err);
+    goto nullreturn;
+  }
+
+  offset = IPH_OFFSET_BYTES(fraghdr);
+  len = lwip_ntohs(IPH_LEN(fraghdr));
+  hlen = IPH_HL_BYTES(fraghdr);
+  if (hlen > len) {
+    /* invalid datagram */
+    goto nullreturn;
+  }
+  len = (u16_t)(len - hlen);
+
+  /* Check if we are allowed to enqueue more datagrams. */
+  clen = pbuf_clen(p);
+  if ((ip_reass_pbufcount + clen) > IP_REASS_MAX_PBUFS) {
+#if IP_REASS_FREE_OLDEST
+    if (!ip_reass_remove_oldest_datagram(fraghdr, clen) ||
+        ((ip_reass_pbufcount + clen) > IP_REASS_MAX_PBUFS))
+#endif /* IP_REASS_FREE_OLDEST */
+    {
+      /* No datagram could be freed and still too many pbufs enqueued */
+      LWIP_DEBUGF(IP_REASS_DEBUG, ("ip4_reass: Overflow condition: pbufct=%d, clen=%d, MAX=%d\n",
+                                   ip_reass_pbufcount, clen, IP_REASS_MAX_PBUFS));
+      IPFRAG_STATS_INC(ip_frag.memerr);
+      /* @todo: send ICMP time exceeded here? */
+      /* drop this pbuf */
+      goto nullreturn;
+    }
+  }
+
+  /* Look for the datagram the fragment belongs to in the current datagram queue,
+   * remembering the previous in the queue for later dequeueing. */
+  for (ipr = reassdatagrams; ipr != NULL; ipr = ipr->next) {
+    /* Check if the incoming fragment matches the one currently present
+       in the reassembly buffer. If so, we proceed with copying the
+       fragment into the buffer. */
+    if (IP_ADDRESSES_AND_ID_MATCH(&ipr->iphdr, fraghdr)) {
+      LWIP_DEBUGF(IP_REASS_DEBUG, ("ip4_reass: matching previous fragment ID=%"X16_F"\n",
+                                   lwip_ntohs(IPH_ID(fraghdr))));
+      IPFRAG_STATS_INC(ip_frag.cachehit);
+      break;
+    }
+  }
+
+  if (ipr == NULL) {
+    /* Enqueue a new datagram into the datagram queue */
+    ipr = ip_reass_enqueue_new_datagram(fraghdr, clen);
+    /* Bail if unable to enqueue */
+    if (ipr == NULL) {
+      goto nullreturn;
+    }
+  } else {
+    if (((lwip_ntohs(IPH_OFFSET(fraghdr)) & IP_OFFMASK) == 0) &&
+        ((lwip_ntohs(IPH_OFFSET(&ipr->iphdr)) & IP_OFFMASK) != 0)) {
+      /* ipr->iphdr is not the header from the first fragment, but fraghdr is
+       * -> copy fraghdr into ipr->iphdr since we want to have the header
+       * of the first fragment (for ICMP time exceeded and later, for copying
+       * all options, if supported)*/
+      SMEMCPY(&ipr->iphdr, fraghdr, IP_HLEN);
+    }
+  }
+
+  /* At this point, we have either created a new entry or pointing
+   * to an existing one */
+
+  /* check for 'no more fragments', and update queue entry*/
+  is_last = (IPH_OFFSET(fraghdr) & PP_NTOHS(IP_MF)) == 0;
+  if (is_last) {
+    u16_t datagram_len = (u16_t)(offset + len);
+    if ((datagram_len < offset) || (datagram_len > (0xFFFF - IP_HLEN))) {
+      /* u16_t overflow, cannot handle this */
+      goto nullreturn_ipr;
+    }
+  }
+  /* find the right place to insert this pbuf */
+  /* @todo: trim pbufs if fragments are overlapping */
+  valid = ip_reass_chain_frag_into_datagram_and_validate(ipr, p, is_last);
+  if (valid == IP_REASS_VALIDATE_PBUF_DROPPED) {
+    goto nullreturn_ipr;
+  }
+  /* if we come here, the pbuf has been enqueued */
+
+  /* Track the current number of pbufs current 'in-flight', in order to limit
+     the number of fragments that may be enqueued at any one time
+     (overflow checked by testing against IP_REASS_MAX_PBUFS) */
+  ip_reass_pbufcount = (u16_t)(ip_reass_pbufcount + clen);
+  if (is_last) {
+    u16_t datagram_len = (u16_t)(offset + len);
+    ipr->datagram_len = datagram_len;
+    ipr->flags |= IP_REASS_FLAG_LASTFRAG;
+    LWIP_DEBUGF(IP_REASS_DEBUG,
+                ("ip4_reass: last fragment seen, total len %"S16_F"\n",
+                 ipr->datagram_len));
+  }
+
+  if (valid == IP_REASS_VALIDATE_TELEGRAM_FINISHED) {
+    struct ip_reassdata *ipr_prev;
+    /* the totally last fragment (flag more fragments = 0) was received at least
+     * once AND all fragments are received */
+    u16_t datagram_len = (u16_t)(ipr->datagram_len + IP_HLEN);
+
+    /* save the second pbuf before copying the header over the pointer */
+    r = ((struct ip_reass_helper *)ipr->p->payload)->next_pbuf;
+
+    /* copy the original ip header back to the first pbuf */
+    fraghdr = (struct ip_hdr *)(ipr->p->payload);
+    SMEMCPY(fraghdr, &ipr->iphdr, IP_HLEN);
+    IPH_LEN_SET(fraghdr, lwip_htons(datagram_len));
+    IPH_OFFSET_SET(fraghdr, 0);
+    IPH_CHKSUM_SET(fraghdr, 0);
+    /* @todo: do we need to set/calculate the correct checksum? */
+#if CHECKSUM_GEN_IP
+    IF__NETIF_CHECKSUM_ENABLED(ip_current_input_netif(), NETIF_CHECKSUM_GEN_IP) {
+      IPH_CHKSUM_SET(fraghdr, inet_chksum(fraghdr, IP_HLEN));
+    }
+#endif /* CHECKSUM_GEN_IP */
+
+    p = ipr->p;
+
+    /* chain together the pbufs contained within the reass_data list. */
+    while (r != NULL) {
+      iprh = (struct ip_reass_helper *)r->payload;
+
+      /* hide the ip header for every succeeding fragment */
+      pbuf_remove_header(r, IP_HLEN);
+      pbuf_cat(p, r);
+      r = iprh->next_pbuf;
+    }
+
+    /* find the previous entry in the linked list */
+    if (ipr == reassdatagrams) {
+      ipr_prev = NULL;
+    } else {
+      for (ipr_prev = reassdatagrams; ipr_prev != NULL; ipr_prev = ipr_prev->next) {
+        if (ipr_prev->next == ipr) {
+          break;
+        }
+      }
+    }
+
+    /* release the sources allocate for the fragment queue entry */
+    ip_reass_dequeue_datagram(ipr, ipr_prev);
+
+    /* and adjust the number of pbufs currently queued for reassembly. */
+    clen = pbuf_clen(p);
+    LWIP_ASSERT("ip_reass_pbufcount >= clen", ip_reass_pbufcount >= clen);
+    ip_reass_pbufcount = (u16_t)(ip_reass_pbufcount - clen);
+
+    MIB2_STATS_INC(mib2.ipreasmoks);
+
+    /* Return the pbuf chain */
+    return p;
+  }
+  /* the datagram is not (yet?) reassembled completely */
+  LWIP_DEBUGF(IP_REASS_DEBUG, ("ip_reass_pbufcount: %d out\n", ip_reass_pbufcount));
+  return NULL;
+
+nullreturn_ipr:
+  LWIP_ASSERT("ipr != NULL", ipr != NULL);
+  if (ipr->p == NULL) {
+    /* dropped pbuf after creating a new datagram entry: remove the entry, too */
+    LWIP_ASSERT("not firstalthough just enqueued", ipr == reassdatagrams);
+    ip_reass_dequeue_datagram(ipr, NULL);
+  }
+
+nullreturn:
+  LWIP_DEBUGF(IP_REASS_DEBUG, ("ip4_reass: nullreturn\n"));
+  IPFRAG_STATS_INC(ip_frag.drop);
+  pbuf_free(p);
+  return NULL;
+}
+#endif /* IP_REASSEMBLY */
+
+#if IP_FRAG
+#if !LWIP_NETIF_TX_SINGLE_PBUF
+/** Allocate a new struct pbuf_custom_ref */
+static struct pbuf_custom_ref *
+ip_frag_alloc_pbuf_custom_ref(void)
+{
+  return (struct pbuf_custom_ref *)memp_malloc(MEMP_FRAG_PBUF);
+}
+
+/** Free a struct pbuf_custom_ref */
+static void
+ip_frag_free_pbuf_custom_ref(struct pbuf_custom_ref *p)
+{
+  LWIP_ASSERT("p != NULL", p != NULL);
+  memp_free(MEMP_FRAG_PBUF, p);
+}
+
+/** Free-callback function to free a 'struct pbuf_custom_ref', called by
+ * pbuf_free. */
+static void
+ipfrag_free_pbuf_custom(struct pbuf *p)
+{
+  struct pbuf_custom_ref *pcr = (struct pbuf_custom_ref *)p;
+  LWIP_ASSERT("pcr != NULL", pcr != NULL);
+  LWIP_ASSERT("pcr == p", (void *)pcr == (void *)p);
+  if (pcr->original != NULL) {
+    pbuf_free(pcr->original);
+  }
+  ip_frag_free_pbuf_custom_ref(pcr);
+}
+#endif /* !LWIP_NETIF_TX_SINGLE_PBUF */
+
+/**
+ * Fragment an IP datagram if too large for the netif.
+ *
+ * Chop the datagram in MTU sized chunks and send them in order
+ * by pointing PBUF_REFs into p.
+ *
+ * @param p ip packet to send
+ * @param netif the netif on which to send
+ * @param dest destination ip address to which to send
+ *
+ * @return ERR_OK if sent successfully, err_t otherwise
+ */
+err_t
+ip4_frag(struct pbuf *p, struct netif *netif, const ip4_addr_t *dest)
+{
+  struct pbuf *rambuf;
+#if !LWIP_NETIF_TX_SINGLE_PBUF
+  struct pbuf *newpbuf;
+  u16_t newpbuflen = 0;
+  u16_t left_to_copy;
+#endif
+  struct ip_hdr *original_iphdr;
+  struct ip_hdr *iphdr;
+  const u16_t nfb = (u16_t)((netif->mtu - IP_HLEN) / 8);
+  u16_t left, fragsize;
+  u16_t ofo;
+  int last;
+  u16_t poff = IP_HLEN;
+  u16_t tmp;
+  int mf_set;
+
+  original_iphdr = (struct ip_hdr *)p->payload;
+  iphdr = original_iphdr;
+  if (IPH_HL_BYTES(iphdr) != IP_HLEN) {
+    /* ip4_frag() does not support IP options */
+    return ERR_VAL;
+  }
+  LWIP_ERROR("ip4_frag(): pbuf too short", p->len >= IP_HLEN, return ERR_VAL);
+
+  /* Save original offset */
+  tmp = lwip_ntohs(IPH_OFFSET(iphdr));
+  ofo = tmp & IP_OFFMASK;
+  /* already fragmented? if so, the last fragment we create must have MF, too */
+  mf_set = tmp & IP_MF;
+
+  left = (u16_t)(p->tot_len - IP_HLEN);
+
+  while (left) {
+    /* Fill this fragment */
+    fragsize = LWIP_MIN(left, (u16_t)(nfb * 8));
+
+#if LWIP_NETIF_TX_SINGLE_PBUF
+    rambuf = pbuf_alloc(PBUF_IP, fragsize, PBUF_RAM);
+    if (rambuf == NULL) {
+      goto memerr;
+    }
+    LWIP_ASSERT("this needs a pbuf in one piece!",
+                (rambuf->len == rambuf->tot_len) && (rambuf->next == NULL));
+    poff += pbuf_copy_partial(p, rambuf->payload, fragsize, poff);
+    /* make room for the IP header */
+    if (pbuf_add_header(rambuf, IP_HLEN)) {
+      pbuf_free(rambuf);
+      goto memerr;
+    }
+    /* fill in the IP header */
+    SMEMCPY(rambuf->payload, original_iphdr, IP_HLEN);
+    iphdr = (struct ip_hdr *)rambuf->payload;
+#else /* LWIP_NETIF_TX_SINGLE_PBUF */
+    /* When not using a static buffer, create a chain of pbufs.
+     * The first will be a PBUF_RAM holding the link and IP header.
+     * The rest will be PBUF_REFs mirroring the pbuf chain to be fragged,
+     * but limited to the size of an mtu.
+     */
+    rambuf = pbuf_alloc(PBUF_LINK, IP_HLEN, PBUF_RAM);
+    if (rambuf == NULL) {
+      goto memerr;
+    }
+    LWIP_ASSERT("this needs a pbuf in one piece!",
+                (rambuf->len >= (IP_HLEN)));
+    SMEMCPY(rambuf->payload, original_iphdr, IP_HLEN);
+    iphdr = (struct ip_hdr *)rambuf->payload;
+
+    left_to_copy = fragsize;
+    while (left_to_copy) {
+      struct pbuf_custom_ref *pcr;
+      u16_t plen = (u16_t)(p->len - poff);
+      LWIP_ASSERT("p->len >= poff", p->len >= poff);
+      newpbuflen = LWIP_MIN(left_to_copy, plen);
+      /* Is this pbuf already empty? */
+      if (!newpbuflen) {
+        poff = 0;
+        p = p->next;
+        continue;
+      }
+      pcr = ip_frag_alloc_pbuf_custom_ref();
+      if (pcr == NULL) {
+        pbuf_free(rambuf);
+        goto memerr;
+      }
+      /* Mirror this pbuf, although we might not need all of it. */
+      newpbuf = pbuf_alloced_custom(PBUF_RAW, newpbuflen, PBUF_REF, &pcr->pc,
+                                    (u8_t *)p->payload + poff, newpbuflen);
+      if (newpbuf == NULL) {
+        ip_frag_free_pbuf_custom_ref(pcr);
+        pbuf_free(rambuf);
+        goto memerr;
+      }
+      pbuf_ref(p);
+      pcr->original = p;
+      pcr->pc.custom_free_function = ipfrag_free_pbuf_custom;
+
+      /* Add it to end of rambuf's chain, but using pbuf_cat, not pbuf_chain
+       * so that it is removed when pbuf_dechain is later called on rambuf.
+       */
+      pbuf_cat(rambuf, newpbuf);
+      left_to_copy = (u16_t)(left_to_copy - newpbuflen);
+      if (left_to_copy) {
+        poff = 0;
+        p = p->next;
+      }
+    }
+    poff = (u16_t)(poff + newpbuflen);
+#endif /* LWIP_NETIF_TX_SINGLE_PBUF */
+
+    /* Correct header */
+    last = (left <= netif->mtu - IP_HLEN);
+
+    /* Set new offset and MF flag */
+    tmp = (IP_OFFMASK & (ofo));
+    if (!last || mf_set) {
+      /* the last fragment has MF set if the input frame had it */
+      tmp = tmp | IP_MF;
+    }
+    IPH_OFFSET_SET(iphdr, lwip_htons(tmp));
+    IPH_LEN_SET(iphdr, lwip_htons((u16_t)(fragsize + IP_HLEN)));
+    IPH_CHKSUM_SET(iphdr, 0);
+#if CHECKSUM_GEN_IP
+    IF__NETIF_CHECKSUM_ENABLED(netif, NETIF_CHECKSUM_GEN_IP) {
+      IPH_CHKSUM_SET(iphdr, inet_chksum(iphdr, IP_HLEN));
+    }
+#endif /* CHECKSUM_GEN_IP */
+
+    /* No need for separate header pbuf - we allowed room for it in rambuf
+     * when allocated.
+     */
+    netif->output(netif, rambuf, dest);
+    IPFRAG_STATS_INC(ip_frag.xmit);
+
+    /* Unfortunately we can't reuse rambuf - the hardware may still be
+     * using the buffer. Instead we free it (and the ensuing chain) and
+     * recreate it next time round the loop. If we're lucky the hardware
+     * will have already sent the packet, the free will really free, and
+     * there will be zero memory penalty.
+     */
+
+    pbuf_free(rambuf);
+    left = (u16_t)(left - fragsize);
+    ofo = (u16_t)(ofo + nfb);
+  }
+  MIB2_STATS_INC(mib2.ipfragoks);
+  return ERR_OK;
+memerr:
+  MIB2_STATS_INC(mib2.ipfragfails);
+  return ERR_MEM;
+}
+#endif /* IP_FRAG */
+
+#endif /* LWIP_IPV4 */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/core/ipv6/dhcp6.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/core/ipv6/dhcp6.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/core/ipv6/dhcp6.c	(revision 457)
@@ -0,0 +1,812 @@
+/**
+ * @file
+ *
+ * @defgroup dhcp6 DHCPv6
+ * @ingroup ip6
+ * DHCPv6 client: IPv6 address autoconfiguration as per
+ * RFC 3315 (stateful DHCPv6) and
+ * RFC 3736 (stateless DHCPv6).
+ *
+ * For now, only stateless DHCPv6 is implemented!
+ *
+ * TODO:
+ * - enable/disable API to not always start when RA is received
+ * - stateful DHCPv6 (for now, only stateless DHCPv6 for DNS and NTP servers works)
+ * - create Client Identifier?
+ * - only start requests if a valid local address is available on the netif
+ * - only start information requests if required (not for every RA)
+ *
+ * dhcp6_enable_stateful() enables stateful DHCPv6 for a netif (stateless disabled)\n
+ * dhcp6_enable_stateless() enables stateless DHCPv6 for a netif (stateful disabled)\n
+ * dhcp6_disable() disable DHCPv6 for a netif
+ *
+ * When enabled, requests are only issued after receipt of RA with the
+ * corresponding bits set.
+ */
+
+/*
+ * Copyright (c) 2018 Simon Goldschmidt
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Simon Goldschmidt <goldsimon@gmx.de>
+ */
+
+#include "lwip/opt.h"
+
+#if LWIP_IPV6 && LWIP_IPV6_DHCP6 /* don't build if not configured for use in lwipopts.h */
+
+#include "lwip/dhcp6.h"
+#include "lwip/prot/dhcp6.h"
+#include "lwip/def.h"
+#include "lwip/udp.h"
+#include "lwip/dns.h"
+
+#include <string.h>
+
+#ifdef LWIP_HOOK_FILENAME
+#include LWIP_HOOK_FILENAME
+#endif
+#ifndef LWIP_HOOK_DHCP6_APPEND_OPTIONS
+#define LWIP_HOOK_DHCP6_APPEND_OPTIONS(netif, dhcp6, state, msg, msg_type, options_len_ptr, max_len)
+#endif
+#ifndef LWIP_HOOK_DHCP6_PARSE_OPTION
+#define LWIP_HOOK_DHCP6_PARSE_OPTION(netif, dhcp6, state, msg, msg_type, option, len, pbuf, offset) do { LWIP_UNUSED_ARG(msg); } while(0)
+#endif
+
+#if LWIP_DNS && LWIP_DHCP6_MAX_DNS_SERVERS
+#if DNS_MAX_SERVERS > LWIP_DHCP6_MAX_DNS_SERVERS
+#define LWIP_DHCP6_PROVIDE_DNS_SERVERS LWIP_DHCP6_MAX_DNS_SERVERS
+#else
+#define LWIP_DHCP6_PROVIDE_DNS_SERVERS DNS_MAX_SERVERS
+#endif
+#else
+#define LWIP_DHCP6_PROVIDE_DNS_SERVERS 0
+#endif
+
+
+/** Option handling: options are parsed in dhcp6_parse_reply
+ * and saved in an array where other functions can load them from.
+ * This might be moved into the struct dhcp6 (not necessarily since
+ * lwIP is single-threaded and the array is only used while in recv
+ * callback). */
+enum dhcp6_option_idx {
+  DHCP6_OPTION_IDX_CLI_ID = 0,
+  DHCP6_OPTION_IDX_SERVER_ID,
+#if LWIP_DHCP6_PROVIDE_DNS_SERVERS
+  DHCP6_OPTION_IDX_DNS_SERVER,
+  DHCP6_OPTION_IDX_DOMAIN_LIST,
+#endif /* LWIP_DHCP_PROVIDE_DNS_SERVERS */
+#if LWIP_DHCP6_GET_NTP_SRV
+  DHCP6_OPTION_IDX_NTP_SERVER,
+#endif /* LWIP_DHCP_GET_NTP_SRV */
+  DHCP6_OPTION_IDX_MAX
+};
+
+struct dhcp6_option_info {
+  u8_t option_given;
+  u16_t val_start;
+  u16_t val_length;
+};
+
+/** Holds the decoded option info, only valid while in dhcp6_recv. */
+struct dhcp6_option_info dhcp6_rx_options[DHCP6_OPTION_IDX_MAX];
+
+#define dhcp6_option_given(dhcp6, idx)           (dhcp6_rx_options[idx].option_given != 0)
+#define dhcp6_got_option(dhcp6, idx)             (dhcp6_rx_options[idx].option_given = 1)
+#define dhcp6_clear_option(dhcp6, idx)           (dhcp6_rx_options[idx].option_given = 0)
+#define dhcp6_clear_all_options(dhcp6)           (memset(dhcp6_rx_options, 0, sizeof(dhcp6_rx_options)))
+#define dhcp6_get_option_start(dhcp6, idx)       (dhcp6_rx_options[idx].val_start)
+#define dhcp6_get_option_length(dhcp6, idx)      (dhcp6_rx_options[idx].val_length)
+#define dhcp6_set_option(dhcp6, idx, start, len) do { dhcp6_rx_options[idx].val_start = (start); dhcp6_rx_options[idx].val_length = (len); }while(0)
+
+
+const ip_addr_t dhcp6_All_DHCP6_Relay_Agents_and_Servers = IPADDR6_INIT_HOST(0xFF020000, 0, 0, 0x00010002);
+const ip_addr_t dhcp6_All_DHCP6_Servers = IPADDR6_INIT_HOST(0xFF020000, 0, 0, 0x00010003);
+
+static struct udp_pcb *dhcp6_pcb;
+static u8_t dhcp6_pcb_refcount;
+
+
+/* receive, unfold, parse and free incoming messages */
+static void dhcp6_recv(void *arg, struct udp_pcb *pcb, struct pbuf *p, const ip_addr_t *addr, u16_t port);
+
+/** Ensure DHCP PCB is allocated and bound */
+static err_t
+dhcp6_inc_pcb_refcount(void)
+{
+  if (dhcp6_pcb_refcount == 0) {
+    LWIP_ASSERT("dhcp6_inc_pcb_refcount(): memory leak", dhcp6_pcb == NULL);
+
+    /* allocate UDP PCB */
+    dhcp6_pcb = udp_new_ip6();
+
+    if (dhcp6_pcb == NULL) {
+      return ERR_MEM;
+    }
+
+    ip_set_option(dhcp6_pcb, SOF_BROADCAST);
+
+    /* set up local and remote port for the pcb -> listen on all interfaces on all src/dest IPs */
+    udp_bind(dhcp6_pcb, IP6_ADDR_ANY, DHCP6_CLIENT_PORT);
+    udp_recv(dhcp6_pcb, dhcp6_recv, NULL);
+  }
+
+  dhcp6_pcb_refcount++;
+
+  return ERR_OK;
+}
+
+/** Free DHCP PCB if the last netif stops using it */
+static void
+dhcp6_dec_pcb_refcount(void)
+{
+  LWIP_ASSERT("dhcp6_pcb_refcount(): refcount error", (dhcp6_pcb_refcount > 0));
+  dhcp6_pcb_refcount--;
+
+  if (dhcp6_pcb_refcount == 0) {
+    udp_remove(dhcp6_pcb);
+    dhcp6_pcb = NULL;
+  }
+}
+
+/**
+ * @ingroup dhcp6
+ * Set a statically allocated struct dhcp6 to work with.
+ * Using this prevents dhcp6_start to allocate it using mem_malloc.
+ *
+ * @param netif the netif for which to set the struct dhcp
+ * @param dhcp6 (uninitialised) dhcp6 struct allocated by the application
+ */
+void
+dhcp6_set_struct(struct netif *netif, struct dhcp6 *dhcp6)
+{
+  LWIP_ASSERT("netif != NULL", netif != NULL);
+  LWIP_ASSERT("dhcp6 != NULL", dhcp6 != NULL);
+  LWIP_ASSERT("netif already has a struct dhcp6 set", netif_dhcp6_data(netif) == NULL);
+
+  /* clear data structure */
+  memset(dhcp6, 0, sizeof(struct dhcp6));
+  /* dhcp6_set_state(&dhcp, DHCP6_STATE_OFF); */
+  netif_set_client_data(netif, LWIP_NETIF_CLIENT_DATA_INDEX_DHCP6, dhcp6);
+}
+
+/**
+ * @ingroup dhcp6
+ * Removes a struct dhcp6 from a netif.
+ *
+ * ATTENTION: Only use this when not using dhcp6_set_struct() to allocate the
+ *            struct dhcp6 since the memory is passed back to the heap.
+ *
+ * @param netif the netif from which to remove the struct dhcp
+ */
+void dhcp6_cleanup(struct netif *netif)
+{
+  LWIP_ASSERT("netif != NULL", netif != NULL);
+
+  if (netif_dhcp6_data(netif) != NULL) {
+    mem_free(netif_dhcp6_data(netif));
+    netif_set_client_data(netif, LWIP_NETIF_CLIENT_DATA_INDEX_DHCP6, NULL);
+  }
+}
+
+static struct dhcp6*
+dhcp6_get_struct(struct netif *netif, const char *dbg_requester)
+{
+  struct dhcp6 *dhcp6 = netif_dhcp6_data(netif);
+  if (dhcp6 == NULL) {
+    LWIP_DEBUGF(DHCP6_DEBUG | LWIP_DBG_TRACE, ("%s: mallocing new DHCPv6 client\n", dbg_requester));
+    dhcp6 = (struct dhcp6 *)mem_malloc(sizeof(struct dhcp6));
+    if (dhcp6 == NULL) {
+      LWIP_DEBUGF(DHCP6_DEBUG | LWIP_DBG_TRACE, ("%s: could not allocate dhcp6\n", dbg_requester));
+      return NULL;
+    }
+
+    /* clear data structure, this implies DHCP6_STATE_OFF */
+    memset(dhcp6, 0, sizeof(struct dhcp6));
+    /* store this dhcp6 client in the netif */
+    netif_set_client_data(netif, LWIP_NETIF_CLIENT_DATA_INDEX_DHCP6, dhcp6);
+  } else {
+    /* already has DHCP6 client attached */
+    LWIP_DEBUGF(DHCP6_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("%s: using existing DHCPv6 client\n", dbg_requester));
+  }
+
+  if (!dhcp6->pcb_allocated) {
+    if (dhcp6_inc_pcb_refcount() != ERR_OK) { /* ensure DHCP6 PCB is allocated */
+      mem_free(dhcp6);
+      netif_set_client_data(netif, LWIP_NETIF_CLIENT_DATA_INDEX_DHCP6, NULL);
+      return NULL;
+    }
+    LWIP_DEBUGF(DHCP6_DEBUG | LWIP_DBG_TRACE, ("%s: allocated dhcp6", dbg_requester));
+    dhcp6->pcb_allocated = 1;
+  }
+  return dhcp6;
+}
+
+/*
+ * Set the DHCPv6 state
+ * If the state changed, reset the number of tries.
+ */
+static void
+dhcp6_set_state(struct dhcp6 *dhcp6, u8_t new_state, const char *dbg_caller)
+{
+  LWIP_DEBUGF(DHCP6_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("DHCPv6 state: %d -> %d (%s)\n",
+    dhcp6->state, new_state, dbg_caller));
+  if (new_state != dhcp6->state) {
+    dhcp6->state = new_state;
+    dhcp6->tries = 0;
+    dhcp6->request_timeout = 0;
+  }
+}
+
+static int
+dhcp6_stateless_enabled(struct dhcp6 *dhcp6)
+{
+  if ((dhcp6->state == DHCP6_STATE_STATELESS_IDLE) ||
+      (dhcp6->state == DHCP6_STATE_REQUESTING_CONFIG)) {
+    return 1;
+  }
+  return 0;
+}
+
+/*static int
+dhcp6_stateful_enabled(struct dhcp6 *dhcp6)
+{
+  if (dhcp6->state == DHCP6_STATE_OFF) {
+    return 0;
+  }
+  if (dhcp6_stateless_enabled(dhcp6)) {
+    return 0;
+  }
+  return 1;
+}*/
+
+/**
+ * @ingroup dhcp6
+ * Enable stateful DHCPv6 on this netif
+ * Requests are sent on receipt of an RA message with the
+ * ND6_RA_FLAG_MANAGED_ADDR_CONFIG flag set.
+ *
+ * A struct dhcp6 will be allocated for this netif if not
+ * set via @ref dhcp6_set_struct before.
+ *
+ * @todo: stateful DHCPv6 not supported, yet
+ */
+err_t
+dhcp6_enable_stateful(struct netif *netif)
+{
+  LWIP_UNUSED_ARG(netif);
+  LWIP_DEBUGF(DHCP6_DEBUG | LWIP_DBG_TRACE, ("stateful dhcp6 not implemented yet"));
+  return ERR_VAL;
+}
+
+/**
+ * @ingroup dhcp6
+ * Enable stateless DHCPv6 on this netif
+ * Requests are sent on receipt of an RA message with the
+ * ND6_RA_FLAG_OTHER_CONFIG flag set.
+ *
+ * A struct dhcp6 will be allocated for this netif if not
+ * set via @ref dhcp6_set_struct before.
+ */
+err_t
+dhcp6_enable_stateless(struct netif *netif)
+{
+  struct dhcp6 *dhcp6;
+
+  LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp6_enable_stateless(netif=%p) %c%c%"U16_F"\n", (void *)netif, netif->name[0], netif->name[1], (u16_t)netif->num));
+
+  dhcp6 = dhcp6_get_struct(netif, "dhcp6_enable_stateless()");
+  if (dhcp6 == NULL) {
+    return ERR_MEM;
+  }
+  if (dhcp6_stateless_enabled(dhcp6)) {
+    LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp6_enable_stateless(): stateless DHCPv6 already enabled"));
+    return ERR_OK;
+  } else if (dhcp6->state != DHCP6_STATE_OFF) {
+    /* stateful running */
+    /* @todo: stop stateful once it is implemented */
+    LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp6_enable_stateless(): switching from stateful to stateless DHCPv6"));
+  }
+  LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp6_enable_stateless(): stateless DHCPv6 enabled\n"));
+  dhcp6_set_state(dhcp6, DHCP6_STATE_STATELESS_IDLE, "dhcp6_enable_stateless");
+  return ERR_OK;
+}
+
+/**
+ * @ingroup dhcp6
+ * Disable stateful or stateless DHCPv6 on this netif
+ * Requests are sent on receipt of an RA message with the
+ * ND6_RA_FLAG_OTHER_CONFIG flag set.
+ */
+void
+dhcp6_disable(struct netif *netif)
+{
+  struct dhcp6 *dhcp6;
+
+  LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp6_disable(netif=%p) %c%c%"U16_F"\n", (void *)netif, netif->name[0], netif->name[1], (u16_t)netif->num));
+
+  dhcp6 = netif_dhcp6_data(netif);
+  if (dhcp6 != NULL) {
+    if (dhcp6->state != DHCP6_STATE_OFF) {
+      LWIP_DEBUGF(DHCP6_DEBUG | LWIP_DBG_TRACE, ("dhcp6_disable(): DHCPv6 disabled (old state: %s)\n",
+        (dhcp6_stateless_enabled(dhcp6) ? "stateless" : "stateful")));
+      dhcp6_set_state(dhcp6, DHCP6_STATE_OFF, "dhcp6_disable");
+      if (dhcp6->pcb_allocated != 0) {
+        dhcp6_dec_pcb_refcount(); /* free DHCPv6 PCB if not needed any more */
+        dhcp6->pcb_allocated = 0;
+      }
+    }
+  }
+}
+
+/**
+ * Create a DHCPv6 request, fill in common headers
+ *
+ * @param netif the netif under DHCPv6 control
+ * @param dhcp6 dhcp6 control struct
+ * @param message_type message type of the request
+ * @param opt_len_alloc option length to allocate
+ * @param options_out_len option length on exit
+ * @return a pbuf for the message
+ */
+static struct pbuf *
+dhcp6_create_msg(struct netif *netif, struct dhcp6 *dhcp6, u8_t message_type,
+                 u16_t opt_len_alloc, u16_t *options_out_len)
+{
+  struct pbuf *p_out;
+  struct dhcp6_msg *msg_out;
+
+  LWIP_ERROR("dhcp6_create_msg: netif != NULL", (netif != NULL), return NULL;);
+  LWIP_ERROR("dhcp6_create_msg: dhcp6 != NULL", (dhcp6 != NULL), return NULL;);
+  p_out = pbuf_alloc(PBUF_TRANSPORT, sizeof(struct dhcp6_msg) + opt_len_alloc, PBUF_RAM);
+  if (p_out == NULL) {
+    LWIP_DEBUGF(DHCP6_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS,
+                ("dhcp6_create_msg(): could not allocate pbuf\n"));
+    return NULL;
+  }
+  LWIP_ASSERT("dhcp6_create_msg: check that first pbuf can hold struct dhcp6_msg",
+              (p_out->len >= sizeof(struct dhcp6_msg) + opt_len_alloc));
+
+  /* @todo: limit new xid for certain message types? */
+  /* reuse transaction identifier in retransmissions */
+  if (dhcp6->tries == 0) {
+    dhcp6->xid = LWIP_RAND() & 0xFFFFFF;
+  }
+
+  LWIP_DEBUGF(DHCP6_DEBUG | LWIP_DBG_TRACE,
+              ("transaction id xid(%"X32_F")\n", dhcp6->xid));
+
+  msg_out = (struct dhcp6_msg *)p_out->payload;
+  memset(msg_out, 0, sizeof(struct dhcp6_msg) + opt_len_alloc);
+
+  msg_out->msgtype = message_type;
+  msg_out->transaction_id[0] = (u8_t)(dhcp6->xid >> 16);
+  msg_out->transaction_id[1] = (u8_t)(dhcp6->xid >> 8);
+  msg_out->transaction_id[2] = (u8_t)dhcp6->xid;
+  *options_out_len = 0;
+  return p_out;
+}
+
+static u16_t
+dhcp6_option_short(u16_t options_out_len, u8_t *options, u16_t value)
+{
+  options[options_out_len++] = (u8_t)((value & 0xff00U) >> 8);
+  options[options_out_len++] = (u8_t) (value & 0x00ffU);
+  return options_out_len;
+}
+
+static u16_t
+dhcp6_option_optionrequest(u16_t options_out_len, u8_t *options, const u16_t *req_options,
+                           u16_t num_req_options, u16_t max_len)
+{
+  size_t i;
+  u16_t ret;
+
+  LWIP_ASSERT("dhcp6_option_optionrequest: options_out_len + sizeof(struct dhcp6_msg) + addlen <= max_len",
+    sizeof(struct dhcp6_msg) + options_out_len + 4U + (2U * num_req_options) <= max_len);
+  LWIP_UNUSED_ARG(max_len);
+
+  ret = dhcp6_option_short(options_out_len, options, DHCP6_OPTION_ORO);
+  ret = dhcp6_option_short(ret, options, 2 * num_req_options);
+  for (i = 0; i < num_req_options; i++) {
+    ret = dhcp6_option_short(ret, options, req_options[i]);
+  }
+  return ret;
+}
+
+/* All options are added, shrink the pbuf to the required size */
+static void
+dhcp6_msg_finalize(u16_t options_out_len, struct pbuf *p_out)
+{
+  /* shrink the pbuf to the actual content length */
+  pbuf_realloc(p_out, (u16_t)(sizeof(struct dhcp6_msg) + options_out_len));
+}
+
+
+#if LWIP_IPV6_DHCP6_STATELESS
+static void
+dhcp6_information_request(struct netif *netif, struct dhcp6 *dhcp6)
+{
+  const u16_t requested_options[] = {DHCP6_OPTION_DNS_SERVERS, DHCP6_OPTION_DOMAIN_LIST, DHCP6_OPTION_SNTP_SERVERS};
+  u16_t msecs;
+  struct pbuf *p_out;
+  u16_t options_out_len;
+  LWIP_DEBUGF(DHCP6_DEBUG | LWIP_DBG_TRACE, ("dhcp6_information_request()\n"));
+  /* create and initialize the DHCP message header */
+  p_out = dhcp6_create_msg(netif, dhcp6, DHCP6_INFOREQUEST, 4 + sizeof(requested_options), &options_out_len);
+  if (p_out != NULL) {
+    err_t err;
+    struct dhcp6_msg *msg_out = (struct dhcp6_msg *)p_out->payload;
+    u8_t *options = (u8_t *)(msg_out + 1);
+    LWIP_DEBUGF(DHCP6_DEBUG | LWIP_DBG_TRACE, ("dhcp6_information_request: making request\n"));
+
+    options_out_len = dhcp6_option_optionrequest(options_out_len, options, requested_options,
+      LWIP_ARRAYSIZE(requested_options), p_out->len);
+    LWIP_HOOK_DHCP6_APPEND_OPTIONS(netif, dhcp6, DHCP6_STATE_REQUESTING_CONFIG, msg_out,
+      DHCP6_INFOREQUEST, options_out_len, p_out->len);
+    dhcp6_msg_finalize(options_out_len, p_out);
+
+    err = udp_sendto_if(dhcp6_pcb, p_out, &dhcp6_All_DHCP6_Relay_Agents_and_Servers, DHCP6_SERVER_PORT, netif);
+    pbuf_free(p_out);
+    LWIP_DEBUGF(DHCP6_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp6_information_request: INFOREQUESTING -> %d\n", (int)err));
+    LWIP_UNUSED_ARG(err);
+  } else {
+    LWIP_DEBUGF(DHCP6_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS, ("dhcp6_information_request: could not allocate DHCP6 request\n"));
+  }
+  dhcp6_set_state(dhcp6, DHCP6_STATE_REQUESTING_CONFIG, "dhcp6_information_request");
+  if (dhcp6->tries < 255) {
+    dhcp6->tries++;
+  }
+  msecs = (u16_t)((dhcp6->tries < 6 ? 1 << dhcp6->tries : 60) * 1000);
+  dhcp6->request_timeout = (u16_t)((msecs + DHCP6_TIMER_MSECS - 1) / DHCP6_TIMER_MSECS);
+  LWIP_DEBUGF(DHCP6_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp6_information_request(): set request timeout %"U16_F" msecs\n", msecs));
+}
+
+static err_t
+dhcp6_request_config(struct netif *netif, struct dhcp6 *dhcp6)
+{
+  /* stateless mode enabled and no request running? */
+  if (dhcp6->state == DHCP6_STATE_STATELESS_IDLE) {
+    /* send Information-request and wait for answer; setup receive timeout */
+    dhcp6_information_request(netif, dhcp6);
+  }
+
+  return ERR_OK;
+}
+
+static void
+dhcp6_abort_config_request(struct dhcp6 *dhcp6)
+{
+  if (dhcp6->state == DHCP6_STATE_REQUESTING_CONFIG) {
+    /* abort running request */
+    dhcp6_set_state(dhcp6, DHCP6_STATE_STATELESS_IDLE, "dhcp6_abort_config_request");
+  }
+}
+
+/* Handle a REPLY to INFOREQUEST
+ * This parses DNS and NTP server addresses from the reply.
+ */
+static void
+dhcp6_handle_config_reply(struct netif *netif, struct pbuf *p_msg_in)
+{
+  struct dhcp6 *dhcp6 = netif_dhcp6_data(netif);
+
+  LWIP_UNUSED_ARG(dhcp6);
+  LWIP_UNUSED_ARG(p_msg_in);
+
+#if LWIP_DHCP6_PROVIDE_DNS_SERVERS
+  if (dhcp6_option_given(dhcp6, DHCP6_OPTION_IDX_DNS_SERVER)) {
+    ip_addr_t dns_addr;
+    ip6_addr_t *dns_addr6;
+    u16_t op_start = dhcp6_get_option_start(dhcp6, DHCP6_OPTION_IDX_DNS_SERVER);
+    u16_t op_len = dhcp6_get_option_length(dhcp6, DHCP6_OPTION_IDX_DNS_SERVER);
+    u16_t idx;
+    u8_t n;
+
+    memset(&dns_addr, 0, sizeof(dns_addr));
+    dns_addr6 = ip_2_ip6(&dns_addr);
+    for (n = 0, idx = op_start; (idx < op_start + op_len) && (n < LWIP_DHCP6_PROVIDE_DNS_SERVERS);
+         n++, idx += sizeof(struct ip6_addr_packed)) {
+      u16_t copied = pbuf_copy_partial(p_msg_in, dns_addr6, sizeof(struct ip6_addr_packed), idx);
+      if (copied != sizeof(struct ip6_addr_packed)) {
+        /* pbuf length mismatch */
+        return;
+      }
+      ip6_addr_assign_zone(dns_addr6, IP6_UNKNOWN, netif);
+      /* @todo: do we need a different offset than DHCP(v4)? */
+      dns_setserver(n, &dns_addr);
+    }
+  }
+  /* @ todo: parse and set Domain Search List */
+#endif /* LWIP_DHCP6_PROVIDE_DNS_SERVERS */
+
+#if LWIP_DHCP6_GET_NTP_SRV
+  if (dhcp6_option_given(dhcp6, DHCP6_OPTION_IDX_NTP_SERVER)) {
+    ip_addr_t ntp_server_addrs[LWIP_DHCP6_MAX_NTP_SERVERS];
+    u16_t op_start = dhcp6_get_option_start(dhcp6, DHCP6_OPTION_IDX_NTP_SERVER);
+    u16_t op_len = dhcp6_get_option_length(dhcp6, DHCP6_OPTION_IDX_NTP_SERVER);
+    u16_t idx;
+    u8_t n;
+
+    for (n = 0, idx = op_start; (idx < op_start + op_len) && (n < LWIP_DHCP6_MAX_NTP_SERVERS);
+         n++, idx += sizeof(struct ip6_addr_packed)) {
+      u16_t copied;
+      ip6_addr_t *ntp_addr6 = ip_2_ip6(&ntp_server_addrs[n]);
+      ip_addr_set_zero_ip6(&ntp_server_addrs[n]);
+      copied = pbuf_copy_partial(p_msg_in, ntp_addr6, sizeof(struct ip6_addr_packed), idx);
+      if (copied != sizeof(struct ip6_addr_packed)) {
+        /* pbuf length mismatch */
+        return;
+      }
+      ip6_addr_assign_zone(ntp_addr6, IP6_UNKNOWN, netif);
+    }
+    dhcp6_set_ntp_servers(n, ntp_server_addrs);
+  }
+#endif /* LWIP_DHCP6_GET_NTP_SRV */
+}
+#endif /* LWIP_IPV6_DHCP6_STATELESS */
+
+/** This function is called from nd6 module when an RA messsage is received
+ * It triggers DHCPv6 requests (if enabled).
+ */
+void
+dhcp6_nd6_ra_trigger(struct netif *netif, u8_t managed_addr_config, u8_t other_config)
+{
+  struct dhcp6 *dhcp6;
+
+  LWIP_ASSERT("netif != NULL", netif != NULL);
+  dhcp6 = netif_dhcp6_data(netif);
+
+  LWIP_UNUSED_ARG(managed_addr_config);
+  LWIP_UNUSED_ARG(other_config);
+  LWIP_UNUSED_ARG(dhcp6);
+
+#if LWIP_IPV6_DHCP6_STATELESS
+  if (dhcp6 != NULL) {
+    if (dhcp6_stateless_enabled(dhcp6)) {
+      if (other_config) {
+        dhcp6_request_config(netif, dhcp6);
+      } else {
+        dhcp6_abort_config_request(dhcp6);
+      }
+    }
+  }
+#endif /* LWIP_IPV6_DHCP6_STATELESS */
+}
+
+/**
+ * Parse the DHCPv6 message and extract the DHCPv6 options.
+ *
+ * Extract the DHCPv6 options (offset + length) so that we can later easily
+ * check for them or extract the contents.
+ */
+static err_t
+dhcp6_parse_reply(struct pbuf *p, struct dhcp6 *dhcp6)
+{
+  u16_t offset;
+  u16_t offset_max;
+  u16_t options_idx;
+  struct dhcp6_msg *msg_in;
+
+  LWIP_UNUSED_ARG(dhcp6);
+
+  /* clear received options */
+  dhcp6_clear_all_options(dhcp6);
+  msg_in = (struct dhcp6_msg *)p->payload;
+
+  /* parse options */
+
+  options_idx = sizeof(struct dhcp6_msg);
+  /* parse options to the end of the received packet */
+  offset_max = p->tot_len;
+
+  offset = options_idx;
+  /* at least 4 byte to read? */
+  while ((offset + 4 <= offset_max)) {
+    u8_t op_len_buf[4];
+    u8_t *op_len;
+    u16_t op;
+    u16_t len;
+    u16_t val_offset = (u16_t)(offset + 4);
+    if (val_offset < offset) {
+      /* overflow */
+      return ERR_BUF;
+    }
+    /* copy option + length, might be split accross pbufs */
+    op_len = (u8_t *)pbuf_get_contiguous(p, op_len_buf, 4, 4, offset);
+    if (op_len == NULL) {
+      /* failed to get option and length */
+      return ERR_VAL;
+    }
+    op = (op_len[0] << 8) | op_len[1];
+    len = (op_len[2] << 8) | op_len[3];
+    offset = val_offset + len;
+    if (offset < val_offset) {
+      /* overflow */
+      return ERR_BUF;
+    }
+
+    switch (op) {
+      case (DHCP6_OPTION_CLIENTID):
+        dhcp6_got_option(dhcp6, DHCP6_OPTION_IDX_CLI_ID);
+        dhcp6_set_option(dhcp6, DHCP6_OPTION_IDX_CLI_ID, val_offset, len);
+        break;
+      case (DHCP6_OPTION_SERVERID):
+        dhcp6_got_option(dhcp6, DHCP6_OPTION_IDX_SERVER_ID);
+        dhcp6_set_option(dhcp6, DHCP6_OPTION_IDX_SERVER_ID, val_offset, len);
+        break;
+#if LWIP_DHCP6_PROVIDE_DNS_SERVERS
+      case (DHCP6_OPTION_DNS_SERVERS):
+        dhcp6_got_option(dhcp6, DHCP6_OPTION_IDX_DNS_SERVER);
+        dhcp6_set_option(dhcp6, DHCP6_OPTION_IDX_DNS_SERVER, val_offset, len);
+        break;
+      case (DHCP6_OPTION_DOMAIN_LIST):
+        dhcp6_got_option(dhcp6, DHCP6_OPTION_IDX_DOMAIN_LIST);
+        dhcp6_set_option(dhcp6, DHCP6_OPTION_IDX_DOMAIN_LIST, val_offset, len);
+        break;
+#endif /* LWIP_DHCP6_PROVIDE_DNS_SERVERS */
+#if LWIP_DHCP6_GET_NTP_SRV
+      case (DHCP6_OPTION_SNTP_SERVERS):
+        dhcp6_got_option(dhcp6, DHCP6_OPTION_IDX_NTP_SERVER);
+        dhcp6_set_option(dhcp6, DHCP6_OPTION_IDX_NTP_SERVER, val_offset, len);
+        break;
+#endif /* LWIP_DHCP6_GET_NTP_SRV*/
+      default:
+        LWIP_DEBUGF(DHCP6_DEBUG, ("skipping option %"U16_F" in options\n", op));
+        LWIP_HOOK_DHCP6_PARSE_OPTION(ip_current_netif(), dhcp6, dhcp6->state, msg_in,
+          msg_in->msgtype, op, len, q, val_offset);
+        break;
+    }
+  }
+  return ERR_OK;
+}
+
+static void
+dhcp6_recv(void *arg, struct udp_pcb *pcb, struct pbuf *p, const ip_addr_t *addr, u16_t port)
+{
+  struct netif *netif = ip_current_input_netif();
+  struct dhcp6 *dhcp6 = netif_dhcp6_data(netif);
+  struct dhcp6_msg *reply_msg = (struct dhcp6_msg *)p->payload;
+  u8_t msg_type;
+  u32_t xid;
+
+  LWIP_UNUSED_ARG(arg);
+
+  /* Caught DHCPv6 message from netif that does not have DHCPv6 enabled? -> not interested */
+  if ((dhcp6 == NULL) || (dhcp6->pcb_allocated == 0)) {
+    goto free_pbuf_and_return;
+  }
+
+  LWIP_ERROR("invalid server address type", IP_IS_V6(addr), goto free_pbuf_and_return;);
+
+  LWIP_DEBUGF(DHCP6_DEBUG | LWIP_DBG_TRACE, ("dhcp6_recv(pbuf = %p) from DHCPv6 server %s port %"U16_F"\n", (void *)p,
+    ipaddr_ntoa(addr), port));
+  LWIP_DEBUGF(DHCP6_DEBUG | LWIP_DBG_TRACE, ("pbuf->len = %"U16_F"\n", p->len));
+  LWIP_DEBUGF(DHCP6_DEBUG | LWIP_DBG_TRACE, ("pbuf->tot_len = %"U16_F"\n", p->tot_len));
+  /* prevent warnings about unused arguments */
+  LWIP_UNUSED_ARG(pcb);
+  LWIP_UNUSED_ARG(addr);
+  LWIP_UNUSED_ARG(port);
+
+  if (p->len < sizeof(struct dhcp6_msg)) {
+    LWIP_DEBUGF(DHCP6_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_WARNING, ("DHCPv6 reply message or pbuf too short\n"));
+    goto free_pbuf_and_return;
+  }
+
+  /* match transaction ID against what we expected */
+  xid = reply_msg->transaction_id[0] << 16;
+  xid |= reply_msg->transaction_id[1] << 8;
+  xid |= reply_msg->transaction_id[2];
+  if (xid != dhcp6->xid) {
+    LWIP_DEBUGF(DHCP6_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_WARNING,
+                ("transaction id mismatch reply_msg->xid(%"X32_F")!= dhcp6->xid(%"X32_F")\n", xid, dhcp6->xid));
+    goto free_pbuf_and_return;
+  }
+  /* option fields could be unfold? */
+  if (dhcp6_parse_reply(p, dhcp6) != ERR_OK) {
+    LWIP_DEBUGF(DHCP6_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS,
+                ("problem unfolding DHCPv6 message - too short on memory?\n"));
+    goto free_pbuf_and_return;
+  }
+
+  /* read DHCP message type */
+  msg_type = reply_msg->msgtype;
+  /* message type is DHCP6 REPLY? */
+  if (msg_type == DHCP6_REPLY) {
+    LWIP_DEBUGF(DHCP6_DEBUG | LWIP_DBG_TRACE, ("DHCP6_REPLY received\n"));
+#if LWIP_IPV6_DHCP6_STATELESS
+    /* in info-requesting state? */
+    if (dhcp6->state == DHCP6_STATE_REQUESTING_CONFIG) {
+      dhcp6_set_state(dhcp6, DHCP6_STATE_STATELESS_IDLE, "dhcp6_recv");
+      dhcp6_handle_config_reply(netif, p);
+    } else
+#endif /* LWIP_IPV6_DHCP6_STATELESS */
+    {
+      /* @todo: handle reply in other states? */
+    }
+  } else {
+    /* @todo: handle other message types */
+  }
+
+free_pbuf_and_return:
+  pbuf_free(p);
+}
+
+/**
+ * A DHCPv6 request has timed out.
+ *
+ * The timer that was started with the DHCPv6 request has
+ * timed out, indicating no response was received in time.
+ */
+static void
+dhcp6_timeout(struct netif *netif, struct dhcp6 *dhcp6)
+{
+  LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp6_timeout()\n"));
+
+  LWIP_UNUSED_ARG(netif);
+  LWIP_UNUSED_ARG(dhcp6);
+
+#if LWIP_IPV6_DHCP6_STATELESS
+  /* back-off period has passed, or server selection timed out */
+  if (dhcp6->state == DHCP6_STATE_REQUESTING_CONFIG) {
+    LWIP_DEBUGF(DHCP6_DEBUG | LWIP_DBG_TRACE, ("dhcp6_timeout(): retrying information request\n"));
+    dhcp6_information_request(netif, dhcp6);
+  }
+#endif /* LWIP_IPV6_DHCP6_STATELESS */
+}
+
+/**
+ * DHCPv6 timeout handling (this function must be called every 500ms,
+ * see @ref DHCP6_TIMER_MSECS).
+ *
+ * A DHCPv6 server is expected to respond within a short period of time.
+ * This timer checks whether an outstanding DHCPv6 request is timed out.
+ */
+void
+dhcp6_tmr(void)
+{
+  struct netif *netif;
+  /* loop through netif's */
+  NETIF_FOREACH(netif) {
+    struct dhcp6 *dhcp6 = netif_dhcp6_data(netif);
+    /* only act on DHCPv6 configured interfaces */
+    if (dhcp6 != NULL) {
+      /* timer is active (non zero), and is about to trigger now */
+      if (dhcp6->request_timeout > 1) {
+        dhcp6->request_timeout--;
+      } else if (dhcp6->request_timeout == 1) {
+        dhcp6->request_timeout--;
+        /* { dhcp6->request_timeout == 0 } */
+        LWIP_DEBUGF(DHCP6_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp6_tmr(): request timeout\n"));
+        /* this client's request timeout triggered */
+        dhcp6_timeout(netif, dhcp6);
+      }
+    }
+  }
+}
+
+#endif /* LWIP_IPV6 && LWIP_IPV6_DHCP6 */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/core/ipv6/ethip6.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/core/ipv6/ethip6.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/core/ipv6/ethip6.c	(revision 457)
@@ -0,0 +1,123 @@
+/**
+ * @file
+ *
+ * Ethernet output for IPv6. Uses ND tables for link-layer addressing.
+ */
+
+/*
+ * Copyright (c) 2010 Inico Technologies Ltd.
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Ivan Delamer <delamer@inicotech.com>
+ *
+ *
+ * Please coordinate changes and requests with Ivan Delamer
+ * <delamer@inicotech.com>
+ */
+
+#include "lwip/opt.h"
+
+#if LWIP_IPV6 && LWIP_ETHERNET
+
+#include "lwip/ethip6.h"
+#include "lwip/nd6.h"
+#include "lwip/pbuf.h"
+#include "lwip/ip6.h"
+#include "lwip/ip6_addr.h"
+#include "lwip/inet_chksum.h"
+#include "lwip/netif.h"
+#include "lwip/icmp6.h"
+#include "lwip/prot/ethernet.h"
+#include "netif/ethernet.h"
+
+#include <string.h>
+
+/**
+ * Resolve and fill-in Ethernet address header for outgoing IPv6 packet.
+ *
+ * For IPv6 multicast, corresponding Ethernet addresses
+ * are selected and the packet is transmitted on the link.
+ *
+ * For unicast addresses, ask the ND6 module what to do. It will either let us
+ * send the the packet right away, or queue the packet for later itself, unless
+ * an error occurs.
+ *
+ * @todo anycast addresses
+ *
+ * @param netif The lwIP network interface which the IP packet will be sent on.
+ * @param q The pbuf(s) containing the IP packet to be sent.
+ * @param ip6addr The IP address of the packet destination.
+ *
+ * @return
+ * - ERR_OK or the return value of @ref nd6_get_next_hop_addr_or_queue.
+ */
+err_t
+ethip6_output(struct netif *netif, struct pbuf *q, const ip6_addr_t *ip6addr)
+{
+  struct eth_addr dest;
+  const u8_t *hwaddr;
+  err_t result;
+
+  LWIP_ASSERT_CORE_LOCKED();
+
+  /* The destination IP address must be properly zoned from here on down. */
+  IP6_ADDR_ZONECHECK_NETIF(ip6addr, netif);
+
+  /* multicast destination IP address? */
+  if (ip6_addr_ismulticast(ip6addr)) {
+    /* Hash IP multicast address to MAC address.*/
+    dest.addr[0] = 0x33;
+    dest.addr[1] = 0x33;
+    dest.addr[2] = ((const u8_t *)(&(ip6addr->addr[3])))[0];
+    dest.addr[3] = ((const u8_t *)(&(ip6addr->addr[3])))[1];
+    dest.addr[4] = ((const u8_t *)(&(ip6addr->addr[3])))[2];
+    dest.addr[5] = ((const u8_t *)(&(ip6addr->addr[3])))[3];
+
+    /* Send out. */
+    return ethernet_output(netif, q, (const struct eth_addr*)(netif->hwaddr), &dest, ETHTYPE_IPV6);
+  }
+
+  /* We have a unicast destination IP address */
+  /* @todo anycast? */
+
+  /* Ask ND6 what to do with the packet. */
+  result = nd6_get_next_hop_addr_or_queue(netif, q, ip6addr, &hwaddr);
+  if (result != ERR_OK) {
+    return result;
+  }
+
+  /* If no hardware address is returned, nd6 has queued the packet for later. */
+  if (hwaddr == NULL) {
+    return ERR_OK;
+  }
+
+  /* Send out the packet using the returned hardware address. */
+  SMEMCPY(dest.addr, hwaddr, 6);
+  return ethernet_output(netif, q, (const struct eth_addr*)(netif->hwaddr), &dest, ETHTYPE_IPV6);
+}
+
+#endif /* LWIP_IPV6 && LWIP_ETHERNET */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/core/ipv6/icmp6.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/core/ipv6/icmp6.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/core/ipv6/icmp6.c	(revision 457)
@@ -0,0 +1,425 @@
+/**
+ * @file
+ *
+ * IPv6 version of ICMP, as per RFC 4443.
+ */
+
+/*
+ * Copyright (c) 2010 Inico Technologies Ltd.
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Ivan Delamer <delamer@inicotech.com>
+ *
+ *
+ * Please coordinate changes and requests with Ivan Delamer
+ * <delamer@inicotech.com>
+ */
+
+#include "lwip/opt.h"
+
+#if LWIP_ICMP6 && LWIP_IPV6 /* don't build if not configured for use in lwipopts.h */
+
+#include "lwip/icmp6.h"
+#include "lwip/prot/icmp6.h"
+#include "lwip/ip6.h"
+#include "lwip/ip6_addr.h"
+#include "lwip/inet_chksum.h"
+#include "lwip/pbuf.h"
+#include "lwip/netif.h"
+#include "lwip/nd6.h"
+#include "lwip/mld6.h"
+#include "lwip/ip.h"
+#include "lwip/stats.h"
+
+#include <string.h>
+
+#if LWIP_ICMP6_DATASIZE == 0
+#undef LWIP_ICMP6_DATASIZE
+#define LWIP_ICMP6_DATASIZE   8
+#endif
+
+/* Forward declarations */
+static void icmp6_send_response(struct pbuf *p, u8_t code, u32_t data, u8_t type);
+static void icmp6_send_response_with_addrs(struct pbuf *p, u8_t code, u32_t data,
+    u8_t type, const ip6_addr_t *src_addr, const ip6_addr_t *dest_addr);
+static void icmp6_send_response_with_addrs_and_netif(struct pbuf *p, u8_t code, u32_t data,
+    u8_t type, const ip6_addr_t *src_addr, const ip6_addr_t *dest_addr, struct netif *netif);
+
+
+/**
+ * Process an input ICMPv6 message. Called by ip6_input.
+ *
+ * Will generate a reply for echo requests. Other messages are forwarded
+ * to nd6_input, or mld6_input.
+ *
+ * @param p the mld packet, p->payload pointing to the icmpv6 header
+ * @param inp the netif on which this packet was received
+ */
+void
+icmp6_input(struct pbuf *p, struct netif *inp)
+{
+  struct icmp6_hdr *icmp6hdr;
+  struct pbuf *r;
+  const ip6_addr_t *reply_src;
+
+  ICMP6_STATS_INC(icmp6.recv);
+
+  /* Check that ICMPv6 header fits in payload */
+  if (p->len < sizeof(struct icmp6_hdr)) {
+    /* drop short packets */
+    pbuf_free(p);
+    ICMP6_STATS_INC(icmp6.lenerr);
+    ICMP6_STATS_INC(icmp6.drop);
+    return;
+  }
+
+  icmp6hdr = (struct icmp6_hdr *)p->payload;
+
+#if CHECKSUM_CHECK_ICMP6
+  IF__NETIF_CHECKSUM_ENABLED(inp, NETIF_CHECKSUM_CHECK_ICMP6) {
+    if (ip6_chksum_pseudo(p, IP6_NEXTH_ICMP6, p->tot_len, ip6_current_src_addr(),
+                          ip6_current_dest_addr()) != 0) {
+      /* Checksum failed */
+      pbuf_free(p);
+      ICMP6_STATS_INC(icmp6.chkerr);
+      ICMP6_STATS_INC(icmp6.drop);
+      return;
+    }
+  }
+#endif /* CHECKSUM_CHECK_ICMP6 */
+
+  switch (icmp6hdr->type) {
+  case ICMP6_TYPE_NA: /* Neighbor advertisement */
+  case ICMP6_TYPE_NS: /* Neighbor solicitation */
+  case ICMP6_TYPE_RA: /* Router advertisement */
+  case ICMP6_TYPE_RD: /* Redirect */
+  case ICMP6_TYPE_PTB: /* Packet too big */
+    nd6_input(p, inp);
+    return;
+  case ICMP6_TYPE_RS:
+#if LWIP_IPV6_FORWARD
+    /* @todo implement router functionality */
+#endif
+    break;
+#if LWIP_IPV6_MLD
+  case ICMP6_TYPE_MLQ:
+  case ICMP6_TYPE_MLR:
+  case ICMP6_TYPE_MLD:
+    mld6_input(p, inp);
+    return;
+#endif
+  case ICMP6_TYPE_EREQ:
+#if !LWIP_MULTICAST_PING
+    /* multicast destination address? */
+    if (ip6_addr_ismulticast(ip6_current_dest_addr())) {
+      /* drop */
+      pbuf_free(p);
+      ICMP6_STATS_INC(icmp6.drop);
+      return;
+    }
+#endif /* LWIP_MULTICAST_PING */
+
+    /* Allocate reply. */
+    r = pbuf_alloc(PBUF_IP, p->tot_len, PBUF_RAM);
+    if (r == NULL) {
+      /* drop */
+      pbuf_free(p);
+      ICMP6_STATS_INC(icmp6.memerr);
+      return;
+    }
+
+    /* Copy echo request. */
+    if (pbuf_copy(r, p) != ERR_OK) {
+      /* drop */
+      pbuf_free(p);
+      pbuf_free(r);
+      ICMP6_STATS_INC(icmp6.err);
+      return;
+    }
+
+    /* Determine reply source IPv6 address. */
+#if LWIP_MULTICAST_PING
+    if (ip6_addr_ismulticast(ip6_current_dest_addr())) {
+      reply_src = ip_2_ip6(ip6_select_source_address(inp, ip6_current_src_addr()));
+      if (reply_src == NULL) {
+        /* drop */
+        pbuf_free(p);
+        pbuf_free(r);
+        ICMP6_STATS_INC(icmp6.rterr);
+        return;
+      }
+    }
+    else
+#endif /* LWIP_MULTICAST_PING */
+    {
+      reply_src = ip6_current_dest_addr();
+    }
+
+    /* Set fields in reply. */
+    ((struct icmp6_echo_hdr *)(r->payload))->type = ICMP6_TYPE_EREP;
+    ((struct icmp6_echo_hdr *)(r->payload))->chksum = 0;
+#if CHECKSUM_GEN_ICMP6
+    IF__NETIF_CHECKSUM_ENABLED(inp, NETIF_CHECKSUM_GEN_ICMP6) {
+      ((struct icmp6_echo_hdr *)(r->payload))->chksum = ip6_chksum_pseudo(r,
+          IP6_NEXTH_ICMP6, r->tot_len, reply_src, ip6_current_src_addr());
+    }
+#endif /* CHECKSUM_GEN_ICMP6 */
+
+    /* Send reply. */
+    ICMP6_STATS_INC(icmp6.xmit);
+    ip6_output_if(r, reply_src, ip6_current_src_addr(),
+        LWIP_ICMP6_HL, 0, IP6_NEXTH_ICMP6, inp);
+    pbuf_free(r);
+
+    break;
+  default:
+    ICMP6_STATS_INC(icmp6.proterr);
+    ICMP6_STATS_INC(icmp6.drop);
+    break;
+  }
+
+  pbuf_free(p);
+}
+
+
+/**
+ * Send an icmpv6 'destination unreachable' packet.
+ *
+ * This function must be used only in direct response to a packet that is being
+ * received right now. Otherwise, address zones would be lost.
+ *
+ * @param p the input packet for which the 'unreachable' should be sent,
+ *          p->payload pointing to the IPv6 header
+ * @param c ICMPv6 code for the unreachable type
+ */
+void
+icmp6_dest_unreach(struct pbuf *p, enum icmp6_dur_code c)
+{
+  icmp6_send_response(p, c, 0, ICMP6_TYPE_DUR);
+}
+
+/**
+ * Send an icmpv6 'packet too big' packet.
+ *
+ * This function must be used only in direct response to a packet that is being
+ * received right now. Otherwise, address zones would be lost.
+ *
+ * @param p the input packet for which the 'packet too big' should be sent,
+ *          p->payload pointing to the IPv6 header
+ * @param mtu the maximum mtu that we can accept
+ */
+void
+icmp6_packet_too_big(struct pbuf *p, u32_t mtu)
+{
+  icmp6_send_response(p, 0, mtu, ICMP6_TYPE_PTB);
+}
+
+/**
+ * Send an icmpv6 'time exceeded' packet.
+ *
+ * This function must be used only in direct response to a packet that is being
+ * received right now. Otherwise, address zones would be lost.
+ *
+ * @param p the input packet for which the 'time exceeded' should be sent,
+ *          p->payload pointing to the IPv6 header
+ * @param c ICMPv6 code for the time exceeded type
+ */
+void
+icmp6_time_exceeded(struct pbuf *p, enum icmp6_te_code c)
+{
+  icmp6_send_response(p, c, 0, ICMP6_TYPE_TE);
+}
+
+/**
+ * Send an icmpv6 'time exceeded' packet, with explicit source and destination
+ * addresses.
+ *
+ * This function may be used to send a response sometime after receiving the
+ * packet for which this response is meant. The provided source and destination
+ * addresses are used primarily to retain their zone information.
+ *
+ * @param p the input packet for which the 'time exceeded' should be sent,
+ *          p->payload pointing to the IPv6 header
+ * @param c ICMPv6 code for the time exceeded type
+ * @param src_addr source address of the original packet, with zone information
+ * @param dest_addr destination address of the original packet, with zone
+ *                  information
+ */
+void
+icmp6_time_exceeded_with_addrs(struct pbuf *p, enum icmp6_te_code c,
+    const ip6_addr_t *src_addr, const ip6_addr_t *dest_addr)
+{
+  icmp6_send_response_with_addrs(p, c, 0, ICMP6_TYPE_TE, src_addr, dest_addr);
+}
+
+/**
+ * Send an icmpv6 'parameter problem' packet.
+ *
+ * This function must be used only in direct response to a packet that is being
+ * received right now. Otherwise, address zones would be lost and the calculated
+ * offset would be wrong (calculated against ip6_current_header()).
+ *
+ * @param p the input packet for which the 'param problem' should be sent,
+ *          p->payload pointing to the IP header
+ * @param c ICMPv6 code for the param problem type
+ * @param pointer the pointer to the byte where the parameter is found
+ */
+void
+icmp6_param_problem(struct pbuf *p, enum icmp6_pp_code c, const void *pointer)
+{
+  u32_t pointer_u32 = (u32_t)((const u8_t *)pointer - (const u8_t *)ip6_current_header());
+  icmp6_send_response(p, c, pointer_u32, ICMP6_TYPE_PP);
+}
+
+/**
+ * Send an ICMPv6 packet in response to an incoming packet.
+ * The packet is sent *to* ip_current_src_addr() on ip_current_netif().
+ *
+ * @param p the input packet for which the response should be sent,
+ *          p->payload pointing to the IPv6 header
+ * @param code Code of the ICMPv6 header
+ * @param data Additional 32-bit parameter in the ICMPv6 header
+ * @param type Type of the ICMPv6 header
+ */
+static void
+icmp6_send_response(struct pbuf *p, u8_t code, u32_t data, u8_t type)
+{
+  const struct ip6_addr *reply_src, *reply_dest;
+  struct netif *netif = ip_current_netif();
+
+  LWIP_ASSERT("icmpv6 packet not a direct response", netif != NULL);
+  reply_dest = ip6_current_src_addr();
+
+  /* Select an address to use as source. */
+  reply_src = ip_2_ip6(ip6_select_source_address(netif, reply_dest));
+  if (reply_src == NULL) {
+    ICMP6_STATS_INC(icmp6.rterr);
+    return;
+  }
+  icmp6_send_response_with_addrs_and_netif(p, code, data, type, reply_src, reply_dest, netif);
+}
+
+/**
+ * Send an ICMPv6 packet in response to an incoming packet.
+ *
+ * Call this function if the packet is NOT sent as a direct response to an
+ * incoming packet, but rather sometime later (e.g. for a fragment reassembly
+ * timeout). The caller must provide the zoned source and destination addresses
+ * from the original packet with the src_addr and dest_addr parameters. The
+ * reason for this approach is that while the addresses themselves are part of
+ * the original packet, their zone information is not, thus possibly resulting
+ * in a link-local response being sent over the wrong link.
+ *
+ * @param p the input packet for which the response should be sent,
+ *          p->payload pointing to the IPv6 header
+ * @param code Code of the ICMPv6 header
+ * @param data Additional 32-bit parameter in the ICMPv6 header
+ * @param type Type of the ICMPv6 header
+ * @param src_addr original source address
+ * @param dest_addr original destination address
+ */
+static void
+icmp6_send_response_with_addrs(struct pbuf *p, u8_t code, u32_t data, u8_t type,
+    const ip6_addr_t *src_addr, const ip6_addr_t *dest_addr)
+{
+  const struct ip6_addr *reply_src, *reply_dest;
+  struct netif *netif;
+
+  /* Get the destination address and netif for this ICMP message. */
+  LWIP_ASSERT("must provide both source and destination", src_addr != NULL);
+  LWIP_ASSERT("must provide both source and destination", dest_addr != NULL);
+
+  /* Special case, as ip6_current_xxx is either NULL, or points
+     to a different packet than the one that expired. */
+  IP6_ADDR_ZONECHECK(src_addr);
+  IP6_ADDR_ZONECHECK(dest_addr);
+  /* Swap source and destination for the reply. */
+  reply_dest = src_addr;
+  reply_src = dest_addr;
+  netif = ip6_route(reply_src, reply_dest);
+  if (netif == NULL) {
+    ICMP6_STATS_INC(icmp6.rterr);
+    return;
+  }
+  icmp6_send_response_with_addrs_and_netif(p, code, data, type, reply_src,
+    reply_dest, netif);
+}
+
+/**
+ * Send an ICMPv6 packet (with srd/dst address and netif given).
+ *
+ * @param p the input packet for which the response should be sent,
+ *          p->payload pointing to the IPv6 header
+ * @param code Code of the ICMPv6 header
+ * @param data Additional 32-bit parameter in the ICMPv6 header
+ * @param type Type of the ICMPv6 header
+ * @param reply_src source address of the packet to send
+ * @param reply_dest destination address of the packet to send
+ * @param netif netif to send the packet
+ */
+static void
+icmp6_send_response_with_addrs_and_netif(struct pbuf *p, u8_t code, u32_t data, u8_t type,
+    const ip6_addr_t *reply_src, const ip6_addr_t *reply_dest, struct netif *netif)
+{
+  struct pbuf *q;
+  struct icmp6_hdr *icmp6hdr;
+
+  /* ICMPv6 header + IPv6 header + data */
+  q = pbuf_alloc(PBUF_IP, sizeof(struct icmp6_hdr) + IP6_HLEN + LWIP_ICMP6_DATASIZE,
+                 PBUF_RAM);
+  if (q == NULL) {
+    LWIP_DEBUGF(ICMP_DEBUG, ("icmp_time_exceeded: failed to allocate pbuf for ICMPv6 packet.\n"));
+    ICMP6_STATS_INC(icmp6.memerr);
+    return;
+  }
+  LWIP_ASSERT("check that first pbuf can hold icmp 6message",
+             (q->len >= (sizeof(struct icmp6_hdr) + IP6_HLEN + LWIP_ICMP6_DATASIZE)));
+
+  icmp6hdr = (struct icmp6_hdr *)q->payload;
+  icmp6hdr->type = type;
+  icmp6hdr->code = code;
+  icmp6hdr->data = lwip_htonl(data);
+
+  /* copy fields from original packet */
+  SMEMCPY((u8_t *)q->payload + sizeof(struct icmp6_hdr), (u8_t *)p->payload,
+          IP6_HLEN + LWIP_ICMP6_DATASIZE);
+
+  /* calculate checksum */
+  icmp6hdr->chksum = 0;
+#if CHECKSUM_GEN_ICMP6
+  IF__NETIF_CHECKSUM_ENABLED(netif, NETIF_CHECKSUM_GEN_ICMP6) {
+    icmp6hdr->chksum = ip6_chksum_pseudo(q, IP6_NEXTH_ICMP6, q->tot_len,
+      reply_src, reply_dest);
+  }
+#endif /* CHECKSUM_GEN_ICMP6 */
+
+  ICMP6_STATS_INC(icmp6.xmit);
+  ip6_output_if(q, reply_src, reply_dest, LWIP_ICMP6_HL, 0, IP6_NEXTH_ICMP6, netif);
+  pbuf_free(q);
+}
+
+#endif /* LWIP_ICMP6 && LWIP_IPV6 */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/core/ipv6/inet6.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/core/ipv6/inet6.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/core/ipv6/inet6.c	(revision 457)
@@ -0,0 +1,53 @@
+/**
+ * @file
+ *
+ * INET v6 addresses.
+ */
+
+/*
+ * Copyright (c) 2010 Inico Technologies Ltd.
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Ivan Delamer <delamer@inicotech.com>
+ *
+ *
+ * Please coordinate changes and requests with Ivan Delamer
+ * <delamer@inicotech.com>
+ */
+
+#include "lwip/opt.h"
+
+#if LWIP_IPV6 && LWIP_SOCKET /* don't build if not configured for use in lwipopts.h */
+
+#include "lwip/def.h"
+#include "lwip/inet.h"
+
+/** This variable is initialized by the system to contain the wildcard IPv6 address.
+ */
+const struct in6_addr in6addr_any = IN6ADDR_ANY_INIT;
+
+#endif /* LWIP_IPV6 */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/core/ipv6/ip6.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/core/ipv6/ip6.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/core/ipv6/ip6.c	(revision 457)
@@ -0,0 +1,1492 @@
+/**
+ * @file
+ *
+ * IPv6 layer.
+ */
+
+/*
+ * Copyright (c) 2010 Inico Technologies Ltd.
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Ivan Delamer <delamer@inicotech.com>
+ *
+ *
+ * Please coordinate changes and requests with Ivan Delamer
+ * <delamer@inicotech.com>
+ */
+
+#include "lwip/opt.h"
+
+#if LWIP_IPV6  /* don't build if not configured for use in lwipopts.h */
+
+#include "lwip/def.h"
+#include "lwip/mem.h"
+#include "lwip/netif.h"
+#include "lwip/ip.h"
+#include "lwip/ip6.h"
+#include "lwip/ip6_addr.h"
+#include "lwip/ip6_frag.h"
+#include "lwip/icmp6.h"
+#include "lwip/priv/raw_priv.h"
+#include "lwip/udp.h"
+#include "lwip/priv/tcp_priv.h"
+#include "lwip/dhcp6.h"
+#include "lwip/nd6.h"
+#include "lwip/mld6.h"
+#include "lwip/debug.h"
+#include "lwip/stats.h"
+
+#ifdef LWIP_HOOK_FILENAME
+#include LWIP_HOOK_FILENAME
+#endif
+
+/**
+ * Finds the appropriate network interface for a given IPv6 address. It tries to select
+ * a netif following a sequence of heuristics:
+ * 1) if there is only 1 netif, return it
+ * 2) if the destination is a zoned address, match its zone to a netif
+ * 3) if the either the source or destination address is a scoped address,
+ *    match the source address's zone (if set) or address (if not) to a netif
+ * 4) tries to match the destination subnet to a configured address
+ * 5) tries to find a router-announced route
+ * 6) tries to match the (unscoped) source address to the netif
+ * 7) returns the default netif, if configured
+ *
+ * Note that each of the two given addresses may or may not be properly zoned.
+ *
+ * @param src the source IPv6 address, if known
+ * @param dest the destination IPv6 address for which to find the route
+ * @return the netif on which to send to reach dest
+ */
+struct netif *
+ip6_route(const ip6_addr_t *src, const ip6_addr_t *dest)
+{
+#if LWIP_SINGLE_NETIF
+  LWIP_UNUSED_ARG(src);
+  LWIP_UNUSED_ARG(dest);
+#else /* LWIP_SINGLE_NETIF */
+  struct netif *netif;
+  s8_t i;
+
+  LWIP_ASSERT_CORE_LOCKED();
+
+  /* If single netif configuration, fast return. */
+  if ((netif_list != NULL) && (netif_list->next == NULL)) {
+    if (!netif_is_up(netif_list) || !netif_is_link_up(netif_list) ||
+        (ip6_addr_has_zone(dest) && !ip6_addr_test_zone(dest, netif_list))) {
+      return NULL;
+    }
+    return netif_list;
+  }
+
+#if LWIP_IPV6_SCOPES
+  /* Special processing for zoned destination addresses. This includes link-
+   * local unicast addresses and interface/link-local multicast addresses. Use
+   * the zone to find a matching netif. If the address is not zoned, then there
+   * is technically no "wrong" netif to choose, and we leave routing to other
+   * rules; in most cases this should be the scoped-source rule below. */
+  if (ip6_addr_has_zone(dest)) {
+    IP6_ADDR_ZONECHECK(dest);
+    /* Find a netif based on the zone. For custom mappings, one zone may map
+     * to multiple netifs, so find one that can actually send a packet. */
+    NETIF_FOREACH(netif) {
+      if (ip6_addr_test_zone(dest, netif) &&
+          netif_is_up(netif) && netif_is_link_up(netif)) {
+        return netif;
+      }
+    }
+    /* No matching netif found. Do no try to route to a different netif,
+     * as that would be a zone violation, resulting in any packets sent to
+     * that netif being dropped on output. */
+    return NULL;
+  }
+#endif /* LWIP_IPV6_SCOPES */
+
+  /* Special processing for scoped source and destination addresses. If we get
+   * here, the destination address does not have a zone, so either way we need
+   * to look at the source address, which may or may not have a zone. If it
+   * does, the zone is restrictive: there is (typically) only one matching
+   * netif for it, and we should avoid routing to any other netif as that would
+   * result in guaranteed zone violations. For scoped source addresses that do
+   * not have a zone, use (only) a netif that has that source address locally
+   * assigned. This case also applies to the loopback source address, which has
+   * an implied link-local scope. If only the destination address is scoped
+   * (but, again, not zoned), we still want to use only the source address to
+   * determine its zone because that's most likely what the user/application
+   * wants, regardless of whether the source address is scoped. Finally, some
+   * of this story also applies if scoping is disabled altogether. */
+#if LWIP_IPV6_SCOPES
+  if (ip6_addr_has_scope(dest, IP6_UNKNOWN) ||
+      ip6_addr_has_scope(src, IP6_UNICAST) ||
+#else /* LWIP_IPV6_SCOPES */
+  if (ip6_addr_islinklocal(dest) || ip6_addr_ismulticast_iflocal(dest) ||
+      ip6_addr_ismulticast_linklocal(dest) || ip6_addr_islinklocal(src) ||
+#endif /* LWIP_IPV6_SCOPES */
+      ip6_addr_isloopback(src)) {
+#if LWIP_IPV6_SCOPES
+    if (ip6_addr_has_zone(src)) {
+      /* Find a netif matching the source zone (relatively cheap). */
+      NETIF_FOREACH(netif) {
+        if (netif_is_up(netif) && netif_is_link_up(netif) &&
+            ip6_addr_test_zone(src, netif)) {
+          return netif;
+        }
+      }
+    } else
+#endif /* LWIP_IPV6_SCOPES */
+    {
+      /* Find a netif matching the source address (relatively expensive). */
+      NETIF_FOREACH(netif) {
+        if (!netif_is_up(netif) || !netif_is_link_up(netif)) {
+          continue;
+        }
+        for (i = 0; i < LWIP_IPV6_NUM_ADDRESSES; i++) {
+          if (ip6_addr_isvalid(netif_ip6_addr_state(netif, i)) &&
+              ip6_addr_cmp_zoneless(src, netif_ip6_addr(netif, i))) {
+            return netif;
+          }
+        }
+      }
+    }
+    /* Again, do not use any other netif in this case, as that could result in
+     * zone boundary violations. */
+    return NULL;
+  }
+
+  /* We come here only if neither source nor destination is scoped. */
+  IP6_ADDR_ZONECHECK(src);
+
+#ifdef LWIP_HOOK_IP6_ROUTE
+  netif = LWIP_HOOK_IP6_ROUTE(src, dest);
+  if (netif != NULL) {
+    return netif;
+  }
+#endif
+
+  /* See if the destination subnet matches a configured address. In accordance
+   * with RFC 5942, dynamically configured addresses do not have an implied
+   * local subnet, and thus should be considered /128 assignments. However, as
+   * such, the destination address may still match a local address, and so we
+   * still need to check for exact matches here. By (lwIP) policy, statically
+   * configured addresses do always have an implied local /64 subnet. */
+  NETIF_FOREACH(netif) {
+    if (!netif_is_up(netif) || !netif_is_link_up(netif)) {
+      continue;
+    }
+    for (i = 0; i < LWIP_IPV6_NUM_ADDRESSES; i++) {
+      if (ip6_addr_isvalid(netif_ip6_addr_state(netif, i)) &&
+          ip6_addr_netcmp(dest, netif_ip6_addr(netif, i)) &&
+          (netif_ip6_addr_isstatic(netif, i) ||
+          ip6_addr_nethostcmp(dest, netif_ip6_addr(netif, i)))) {
+        return netif;
+      }
+    }
+  }
+
+  /* Get the netif for a suitable router-announced route. */
+  netif = nd6_find_route(dest);
+  if (netif != NULL) {
+    return netif;
+  }
+
+  /* Try with the netif that matches the source address. Given the earlier rule
+   * for scoped source addresses, this applies to unscoped addresses only. */
+  if (!ip6_addr_isany(src)) {
+    NETIF_FOREACH(netif) {
+      if (!netif_is_up(netif) || !netif_is_link_up(netif)) {
+        continue;
+      }
+      for (i = 0; i < LWIP_IPV6_NUM_ADDRESSES; i++) {
+        if (ip6_addr_isvalid(netif_ip6_addr_state(netif, i)) &&
+            ip6_addr_cmp(src, netif_ip6_addr(netif, i))) {
+          return netif;
+        }
+      }
+    }
+  }
+
+#if LWIP_NETIF_LOOPBACK && !LWIP_HAVE_LOOPIF
+  /* loopif is disabled, loopback traffic is passed through any netif */
+  if (ip6_addr_isloopback(dest)) {
+    /* don't check for link on loopback traffic */
+    if (netif_default != NULL && netif_is_up(netif_default)) {
+      return netif_default;
+    }
+    /* default netif is not up, just use any netif for loopback traffic */
+    NETIF_FOREACH(netif) {
+      if (netif_is_up(netif)) {
+        return netif;
+      }
+    }
+    return NULL;
+  }
+#endif /* LWIP_NETIF_LOOPBACK && !LWIP_HAVE_LOOPIF */
+#endif /* !LWIP_SINGLE_NETIF */
+
+  /* no matching netif found, use default netif, if up */
+  if ((netif_default == NULL) || !netif_is_up(netif_default) || !netif_is_link_up(netif_default)) {
+    return NULL;
+  }
+  return netif_default;
+}
+
+/**
+ * @ingroup ip6
+ * Select the best IPv6 source address for a given destination IPv6 address.
+ *
+ * This implementation follows RFC 6724 Sec. 5 to the following extent:
+ * - Rules 1, 2, 3: fully implemented
+ * - Rules 4, 5, 5.5: not applicable
+ * - Rule 6: not implemented
+ * - Rule 7: not applicable
+ * - Rule 8: limited to "prefer /64 subnet match over non-match"
+ *
+ * For Rule 2, we deliberately deviate from RFC 6724 Sec. 3.1 by considering
+ * ULAs to be of smaller scope than global addresses, to avoid that a preferred
+ * ULA is picked over a deprecated global address when given a global address
+ * as destination, as that would likely result in broken two-way communication.
+ *
+ * As long as temporary addresses are not supported (as used in Rule 7), a
+ * proper implementation of Rule 8 would obviate the need to implement Rule 6.
+ *
+ * @param netif the netif on which to send a packet
+ * @param dest the destination we are trying to reach (possibly not properly
+ *             zoned)
+ * @return the most suitable source address to use, or NULL if no suitable
+ *         source address is found
+ */
+const ip_addr_t *
+ip6_select_source_address(struct netif *netif, const ip6_addr_t *dest)
+{
+  const ip_addr_t *best_addr;
+  const ip6_addr_t *cand_addr;
+  s8_t dest_scope, cand_scope;
+  s8_t best_scope = IP6_MULTICAST_SCOPE_RESERVED;
+  u8_t i, cand_pref, cand_bits;
+  u8_t best_pref = 0;
+  u8_t best_bits = 0;
+
+  /* Start by determining the scope of the given destination address. These
+   * tests are hopefully (roughly) in order of likeliness to match. */
+  if (ip6_addr_isglobal(dest)) {
+    dest_scope = IP6_MULTICAST_SCOPE_GLOBAL;
+  } else if (ip6_addr_islinklocal(dest) || ip6_addr_isloopback(dest)) {
+    dest_scope = IP6_MULTICAST_SCOPE_LINK_LOCAL;
+  } else if (ip6_addr_isuniquelocal(dest)) {
+    dest_scope = IP6_MULTICAST_SCOPE_ORGANIZATION_LOCAL;
+  } else if (ip6_addr_ismulticast(dest)) {
+    dest_scope = ip6_addr_multicast_scope(dest);
+  } else if (ip6_addr_issitelocal(dest)) {
+    dest_scope = IP6_MULTICAST_SCOPE_SITE_LOCAL;
+  } else {
+    /* no match, consider scope global */
+    dest_scope = IP6_MULTICAST_SCOPE_GLOBAL;
+  }
+
+  best_addr = NULL;
+
+  for (i = 0; i < LWIP_IPV6_NUM_ADDRESSES; i++) {
+    /* Consider only valid (= preferred and deprecated) addresses. */
+    if (!ip6_addr_isvalid(netif_ip6_addr_state(netif, i))) {
+      continue;
+    }
+    /* Determine the scope of this candidate address. Same ordering idea. */
+    cand_addr = netif_ip6_addr(netif, i);
+    if (ip6_addr_isglobal(cand_addr)) {
+      cand_scope = IP6_MULTICAST_SCOPE_GLOBAL;
+    } else if (ip6_addr_islinklocal(cand_addr)) {
+      cand_scope = IP6_MULTICAST_SCOPE_LINK_LOCAL;
+    } else if (ip6_addr_isuniquelocal(cand_addr)) {
+      cand_scope = IP6_MULTICAST_SCOPE_ORGANIZATION_LOCAL;
+    } else if (ip6_addr_issitelocal(cand_addr)) {
+      cand_scope = IP6_MULTICAST_SCOPE_SITE_LOCAL;
+    } else {
+      /* no match, treat as low-priority global scope */
+      cand_scope = IP6_MULTICAST_SCOPE_RESERVEDF;
+    }
+    cand_pref = ip6_addr_ispreferred(netif_ip6_addr_state(netif, i));
+    /* @todo compute the actual common bits, for longest matching prefix. */
+    /* We cannot count on the destination address having a proper zone
+     * assignment, so do not compare zones in this case. */
+    cand_bits = ip6_addr_netcmp_zoneless(cand_addr, dest); /* just 1 or 0 for now */
+    if (cand_bits && ip6_addr_nethostcmp(cand_addr, dest)) {
+      return netif_ip_addr6(netif, i); /* Rule 1 */
+    }
+    if ((best_addr == NULL) || /* no alternative yet */
+        ((cand_scope < best_scope) && (cand_scope >= dest_scope)) ||
+        ((cand_scope > best_scope) && (best_scope < dest_scope)) || /* Rule 2 */
+        ((cand_scope == best_scope) && ((cand_pref > best_pref) || /* Rule 3 */
+        ((cand_pref == best_pref) && (cand_bits > best_bits))))) { /* Rule 8 */
+      /* We found a new "winning" candidate. */
+      best_addr = netif_ip_addr6(netif, i);
+      best_scope = cand_scope;
+      best_pref = cand_pref;
+      best_bits = cand_bits;
+    }
+  }
+
+  return best_addr; /* may be NULL */
+}
+
+#if LWIP_IPV6_FORWARD
+/**
+ * Forwards an IPv6 packet. It finds an appropriate route for the
+ * packet, decrements the HL value of the packet, and outputs
+ * the packet on the appropriate interface.
+ *
+ * @param p the packet to forward (p->payload points to IP header)
+ * @param iphdr the IPv6 header of the input packet
+ * @param inp the netif on which this packet was received
+ */
+static void
+ip6_forward(struct pbuf *p, struct ip6_hdr *iphdr, struct netif *inp)
+{
+  struct netif *netif;
+
+  /* do not forward link-local or loopback addresses */
+  if (ip6_addr_islinklocal(ip6_current_dest_addr()) ||
+      ip6_addr_isloopback(ip6_current_dest_addr())) {
+    LWIP_DEBUGF(IP6_DEBUG, ("ip6_forward: not forwarding link-local address.\n"));
+    IP6_STATS_INC(ip6.rterr);
+    IP6_STATS_INC(ip6.drop);
+    return;
+  }
+
+  /* Find network interface where to forward this IP packet to. */
+  netif = ip6_route(IP6_ADDR_ANY6, ip6_current_dest_addr());
+  if (netif == NULL) {
+    LWIP_DEBUGF(IP6_DEBUG, ("ip6_forward: no route for %"X16_F":%"X16_F":%"X16_F":%"X16_F":%"X16_F":%"X16_F":%"X16_F":%"X16_F"\n",
+        IP6_ADDR_BLOCK1(ip6_current_dest_addr()),
+        IP6_ADDR_BLOCK2(ip6_current_dest_addr()),
+        IP6_ADDR_BLOCK3(ip6_current_dest_addr()),
+        IP6_ADDR_BLOCK4(ip6_current_dest_addr()),
+        IP6_ADDR_BLOCK5(ip6_current_dest_addr()),
+        IP6_ADDR_BLOCK6(ip6_current_dest_addr()),
+        IP6_ADDR_BLOCK7(ip6_current_dest_addr()),
+        IP6_ADDR_BLOCK8(ip6_current_dest_addr())));
+#if LWIP_ICMP6
+    /* Don't send ICMP messages in response to ICMP messages */
+    if (IP6H_NEXTH(iphdr) != IP6_NEXTH_ICMP6) {
+      icmp6_dest_unreach(p, ICMP6_DUR_NO_ROUTE);
+    }
+#endif /* LWIP_ICMP6 */
+    IP6_STATS_INC(ip6.rterr);
+    IP6_STATS_INC(ip6.drop);
+    return;
+  }
+#if LWIP_IPV6_SCOPES
+  /* Do not forward packets with a zoned (e.g., link-local) source address
+   * outside of their zone. We determined the zone a bit earlier, so we know
+   * that the address is properly zoned here, so we can safely use has_zone.
+   * Also skip packets with a loopback source address (link-local implied). */
+  if ((ip6_addr_has_zone(ip6_current_src_addr()) &&
+      !ip6_addr_test_zone(ip6_current_src_addr(), netif)) ||
+      ip6_addr_isloopback(ip6_current_src_addr())) {
+    LWIP_DEBUGF(IP6_DEBUG, ("ip6_forward: not forwarding packet beyond its source address zone.\n"));
+    IP6_STATS_INC(ip6.rterr);
+    IP6_STATS_INC(ip6.drop);
+    return;
+  }
+#endif /* LWIP_IPV6_SCOPES */
+  /* Do not forward packets onto the same network interface on which
+   * they arrived. */
+  if (netif == inp) {
+    LWIP_DEBUGF(IP6_DEBUG, ("ip6_forward: not bouncing packets back on incoming interface.\n"));
+    IP6_STATS_INC(ip6.rterr);
+    IP6_STATS_INC(ip6.drop);
+    return;
+  }
+
+  /* decrement HL */
+  IP6H_HOPLIM_SET(iphdr, IP6H_HOPLIM(iphdr) - 1);
+  /* send ICMP6 if HL == 0 */
+  if (IP6H_HOPLIM(iphdr) == 0) {
+#if LWIP_ICMP6
+    /* Don't send ICMP messages in response to ICMP messages */
+    if (IP6H_NEXTH(iphdr) != IP6_NEXTH_ICMP6) {
+      icmp6_time_exceeded(p, ICMP6_TE_HL);
+    }
+#endif /* LWIP_ICMP6 */
+    IP6_STATS_INC(ip6.drop);
+    return;
+  }
+
+  if (netif->mtu && (p->tot_len > netif->mtu)) {
+#if LWIP_ICMP6
+    /* Don't send ICMP messages in response to ICMP messages */
+    if (IP6H_NEXTH(iphdr) != IP6_NEXTH_ICMP6) {
+      icmp6_packet_too_big(p, netif->mtu);
+    }
+#endif /* LWIP_ICMP6 */
+    IP6_STATS_INC(ip6.drop);
+    return;
+  }
+
+  LWIP_DEBUGF(IP6_DEBUG, ("ip6_forward: forwarding packet to %"X16_F":%"X16_F":%"X16_F":%"X16_F":%"X16_F":%"X16_F":%"X16_F":%"X16_F"\n",
+      IP6_ADDR_BLOCK1(ip6_current_dest_addr()),
+      IP6_ADDR_BLOCK2(ip6_current_dest_addr()),
+      IP6_ADDR_BLOCK3(ip6_current_dest_addr()),
+      IP6_ADDR_BLOCK4(ip6_current_dest_addr()),
+      IP6_ADDR_BLOCK5(ip6_current_dest_addr()),
+      IP6_ADDR_BLOCK6(ip6_current_dest_addr()),
+      IP6_ADDR_BLOCK7(ip6_current_dest_addr()),
+      IP6_ADDR_BLOCK8(ip6_current_dest_addr())));
+
+  /* transmit pbuf on chosen interface */
+  netif->output_ip6(netif, p, ip6_current_dest_addr());
+  IP6_STATS_INC(ip6.fw);
+  IP6_STATS_INC(ip6.xmit);
+  return;
+}
+#endif /* LWIP_IPV6_FORWARD */
+
+/** Return true if the current input packet should be accepted on this netif */
+static int
+ip6_input_accept(struct netif *netif)
+{
+  /* interface is up? */
+  if (netif_is_up(netif)) {
+    u8_t i;
+    /* unicast to this interface address? address configured? */
+    /* If custom scopes are used, the destination zone will be tested as
+      * part of the local-address comparison, but we need to test the source
+      * scope as well (e.g., is this interface on the same link?). */
+    for (i = 0; i < LWIP_IPV6_NUM_ADDRESSES; i++) {
+      if (ip6_addr_isvalid(netif_ip6_addr_state(netif, i)) &&
+          ip6_addr_cmp(ip6_current_dest_addr(), netif_ip6_addr(netif, i))
+#if IPV6_CUSTOM_SCOPES
+          && (!ip6_addr_has_zone(ip6_current_src_addr()) ||
+              ip6_addr_test_zone(ip6_current_src_addr(), netif))
+#endif /* IPV6_CUSTOM_SCOPES */
+      ) {
+        /* accept on this netif */
+        return 1;
+      }
+    }
+  }
+  return 0;
+}
+
+/**
+ * This function is called by the network interface device driver when
+ * an IPv6 packet is received. The function does the basic checks of the
+ * IP header such as packet size being at least larger than the header
+ * size etc. If the packet was not destined for us, the packet is
+ * forwarded (using ip6_forward).
+ *
+ * Finally, the packet is sent to the upper layer protocol input function.
+ *
+ * @param p the received IPv6 packet (p->payload points to IPv6 header)
+ * @param inp the netif on which this packet was received
+ * @return ERR_OK if the packet was processed (could return ERR_* if it wasn't
+ *         processed, but currently always returns ERR_OK)
+ */
+err_t
+ip6_input(struct pbuf *p, struct netif *inp)
+{
+  struct ip6_hdr *ip6hdr;
+  struct netif *netif;
+  const u8_t *nexth;
+  u16_t hlen, hlen_tot; /* the current header length */
+#if 0 /*IP_ACCEPT_LINK_LAYER_ADDRESSING*/
+  @todo
+  int check_ip_src=1;
+#endif /* IP_ACCEPT_LINK_LAYER_ADDRESSING */
+#if LWIP_RAW
+  raw_input_state_t raw_status;
+#endif /* LWIP_RAW */
+
+  LWIP_ASSERT_CORE_LOCKED();
+
+  IP6_STATS_INC(ip6.recv);
+
+  /* identify the IP header */
+  ip6hdr = (struct ip6_hdr *)p->payload;
+  if (IP6H_V(ip6hdr) != 6) {
+    LWIP_DEBUGF(IP6_DEBUG | LWIP_DBG_LEVEL_WARNING, ("IPv6 packet dropped due to bad version number %"U32_F"\n",
+        IP6H_V(ip6hdr)));
+    pbuf_free(p);
+    IP6_STATS_INC(ip6.err);
+    IP6_STATS_INC(ip6.drop);
+    return ERR_OK;
+  }
+
+#ifdef LWIP_HOOK_IP6_INPUT
+  if (LWIP_HOOK_IP6_INPUT(p, inp)) {
+    /* the packet has been eaten */
+    return ERR_OK;
+  }
+#endif
+
+  /* header length exceeds first pbuf length, or ip length exceeds total pbuf length? */
+  if ((IP6_HLEN > p->len) || (IP6H_PLEN(ip6hdr) > (p->tot_len - IP6_HLEN))) {
+    if (IP6_HLEN > p->len) {
+      LWIP_DEBUGF(IP6_DEBUG | LWIP_DBG_LEVEL_SERIOUS,
+        ("IPv6 header (len %"U16_F") does not fit in first pbuf (len %"U16_F"), IP packet dropped.\n",
+            (u16_t)IP6_HLEN, p->len));
+    }
+    if ((IP6H_PLEN(ip6hdr) + IP6_HLEN) > p->tot_len) {
+      LWIP_DEBUGF(IP6_DEBUG | LWIP_DBG_LEVEL_SERIOUS,
+        ("IPv6 (plen %"U16_F") is longer than pbuf (len %"U16_F"), IP packet dropped.\n",
+            (u16_t)(IP6H_PLEN(ip6hdr) + IP6_HLEN), p->tot_len));
+    }
+    /* free (drop) packet pbufs */
+    pbuf_free(p);
+    IP6_STATS_INC(ip6.lenerr);
+    IP6_STATS_INC(ip6.drop);
+    return ERR_OK;
+  }
+
+  /* Trim pbuf. This should have been done at the netif layer,
+   * but we'll do it anyway just to be sure that its done. */
+  pbuf_realloc(p, (u16_t)(IP6_HLEN + IP6H_PLEN(ip6hdr)));
+
+  /* copy IP addresses to aligned ip6_addr_t */
+  ip_addr_copy_from_ip6_packed(ip_data.current_iphdr_dest, ip6hdr->dest);
+  ip_addr_copy_from_ip6_packed(ip_data.current_iphdr_src, ip6hdr->src);
+
+  /* Don't accept virtual IPv4 mapped IPv6 addresses.
+   * Don't accept multicast source addresses. */
+  if (ip6_addr_isipv4mappedipv6(ip_2_ip6(&ip_data.current_iphdr_dest)) ||
+     ip6_addr_isipv4mappedipv6(ip_2_ip6(&ip_data.current_iphdr_src)) ||
+     ip6_addr_ismulticast(ip_2_ip6(&ip_data.current_iphdr_src))) {
+    /* free (drop) packet pbufs */
+    pbuf_free(p);
+    IP6_STATS_INC(ip6.err);
+    IP6_STATS_INC(ip6.drop);
+    return ERR_OK;
+  }
+
+  /* Set the appropriate zone identifier on the addresses. */
+  ip6_addr_assign_zone(ip_2_ip6(&ip_data.current_iphdr_dest), IP6_UNKNOWN, inp);
+  ip6_addr_assign_zone(ip_2_ip6(&ip_data.current_iphdr_src), IP6_UNICAST, inp);
+
+  /* current header pointer. */
+  ip_data.current_ip6_header = ip6hdr;
+
+  /* In netif, used in case we need to send ICMPv6 packets back. */
+  ip_data.current_netif = inp;
+  ip_data.current_input_netif = inp;
+
+  /* match packet against an interface, i.e. is this packet for us? */
+  if (ip6_addr_ismulticast(ip6_current_dest_addr())) {
+    /* Always joined to multicast if-local and link-local all-nodes group. */
+    if (ip6_addr_isallnodes_iflocal(ip6_current_dest_addr()) ||
+        ip6_addr_isallnodes_linklocal(ip6_current_dest_addr())) {
+      netif = inp;
+    }
+#if LWIP_IPV6_MLD
+    else if (mld6_lookfor_group(inp, ip6_current_dest_addr())) {
+      netif = inp;
+    }
+#else /* LWIP_IPV6_MLD */
+    else if (ip6_addr_issolicitednode(ip6_current_dest_addr())) {
+      u8_t i;
+      /* Filter solicited node packets when MLD is not enabled
+       * (for Neighbor discovery). */
+      netif = NULL;
+      for (i = 0; i < LWIP_IPV6_NUM_ADDRESSES; i++) {
+        if (ip6_addr_isvalid(netif_ip6_addr_state(inp, i)) &&
+            ip6_addr_cmp_solicitednode(ip6_current_dest_addr(), netif_ip6_addr(inp, i))) {
+          netif = inp;
+          LWIP_DEBUGF(IP6_DEBUG, ("ip6_input: solicited node packet accepted on interface %c%c\n",
+              netif->name[0], netif->name[1]));
+          break;
+        }
+      }
+    }
+#endif /* LWIP_IPV6_MLD */
+    else {
+      netif = NULL;
+    }
+  } else {
+    /* start trying with inp. if that's not acceptable, start walking the
+       list of configured netifs. */
+    if (ip6_input_accept(inp)) {
+      netif = inp;
+    } else {
+      netif = NULL;
+#if !IPV6_CUSTOM_SCOPES
+      /* Shortcut: stop looking for other interfaces if either the source or
+        * the destination has a scope constrained to this interface. Custom
+        * scopes may break the 1:1 link/interface mapping, however. */
+      if (ip6_addr_islinklocal(ip6_current_dest_addr()) ||
+          ip6_addr_islinklocal(ip6_current_src_addr())) {
+        goto netif_found;
+      }
+#endif /* !IPV6_CUSTOM_SCOPES */
+#if !LWIP_NETIF_LOOPBACK || LWIP_HAVE_LOOPIF
+      /* The loopback address is to be considered link-local. Packets to it
+        * should be dropped on other interfaces, as per RFC 4291 Sec. 2.5.3.
+        * Its implied scope means packets *from* the loopback address should
+        * not be accepted on other interfaces, either. These requirements
+        * cannot be implemented in the case that loopback traffic is sent
+        * across a non-loopback interface, however. */
+      if (ip6_addr_isloopback(ip6_current_dest_addr()) ||
+          ip6_addr_isloopback(ip6_current_src_addr())) {
+        goto netif_found;
+      }
+#endif /* !LWIP_NETIF_LOOPBACK || LWIP_HAVE_LOOPIF */
+#if !LWIP_SINGLE_NETIF
+      NETIF_FOREACH(netif) {
+        if (netif == inp) {
+          /* we checked that before already */
+          continue;
+        }
+        if (ip6_input_accept(netif)) {
+          break;
+        }
+      }
+#endif /* !LWIP_SINGLE_NETIF */
+    }
+netif_found:
+    LWIP_DEBUGF(IP6_DEBUG, ("ip6_input: packet accepted on interface %c%c\n",
+        netif ? netif->name[0] : 'X', netif? netif->name[1] : 'X'));
+  }
+
+  /* "::" packet source address? (used in duplicate address detection) */
+  if (ip6_addr_isany(ip6_current_src_addr()) &&
+      (!ip6_addr_issolicitednode(ip6_current_dest_addr()))) {
+    /* packet source is not valid */
+    /* free (drop) packet pbufs */
+    LWIP_DEBUGF(IP6_DEBUG, ("ip6_input: packet with src ANY_ADDRESS dropped\n"));
+    pbuf_free(p);
+    IP6_STATS_INC(ip6.drop);
+    goto ip6_input_cleanup;
+  }
+
+  /* packet not for us? */
+  if (netif == NULL) {
+    /* packet not for us, route or discard */
+    LWIP_DEBUGF(IP6_DEBUG | LWIP_DBG_TRACE, ("ip6_input: packet not for us.\n"));
+#if LWIP_IPV6_FORWARD
+    /* non-multicast packet? */
+    if (!ip6_addr_ismulticast(ip6_current_dest_addr())) {
+      /* try to forward IP packet on (other) interfaces */
+      ip6_forward(p, ip6hdr, inp);
+    }
+#endif /* LWIP_IPV6_FORWARD */
+    pbuf_free(p);
+    goto ip6_input_cleanup;
+  }
+
+  /* current netif pointer. */
+  ip_data.current_netif = netif;
+
+  /* Save next header type. */
+  nexth = &IP6H_NEXTH(ip6hdr);
+
+  /* Init header length. */
+  hlen = hlen_tot = IP6_HLEN;
+
+  /* Move to payload. */
+  pbuf_remove_header(p, IP6_HLEN);
+
+  /* Process known option extension headers, if present. */
+  while (*nexth != IP6_NEXTH_NONE)
+  {
+    switch (*nexth) {
+    case IP6_NEXTH_HOPBYHOP:
+    {
+      s32_t opt_offset;
+      struct ip6_hbh_hdr *hbh_hdr;
+      struct ip6_opt_hdr *opt_hdr;
+      LWIP_DEBUGF(IP6_DEBUG, ("ip6_input: packet with Hop-by-Hop options header\n"));
+
+      /* Get and check the header length, while staying in packet bounds. */
+      hbh_hdr = (struct ip6_hbh_hdr *)p->payload;
+
+      /* Get next header type. */
+      nexth = &IP6_HBH_NEXTH(hbh_hdr);
+
+      /* Get the header length. */
+      hlen = (u16_t)(8 * (1 + hbh_hdr->_hlen));
+
+      if ((p->len < 8) || (hlen > p->len)) {
+        LWIP_DEBUGF(IP6_DEBUG | LWIP_DBG_LEVEL_SERIOUS,
+          ("IPv6 options header (hlen %"U16_F") does not fit in first pbuf (len %"U16_F"), IPv6 packet dropped.\n",
+              hlen, p->len));
+        /* free (drop) packet pbufs */
+        pbuf_free(p);
+        IP6_STATS_INC(ip6.lenerr);
+        IP6_STATS_INC(ip6.drop);
+        goto ip6_input_cleanup;
+      }
+
+      hlen_tot = (u16_t)(hlen_tot + hlen);
+
+      /* The extended option header starts right after Hop-by-Hop header. */
+      opt_offset = IP6_HBH_HLEN;
+      while (opt_offset < hlen)
+      {
+        s32_t opt_dlen = 0;
+
+        opt_hdr = (struct ip6_opt_hdr *)((u8_t *)hbh_hdr + opt_offset);
+
+        switch (IP6_OPT_TYPE(opt_hdr)) {
+        /* @todo: process IPV6 Hop-by-Hop option data */
+        case IP6_PAD1_OPTION:
+          /* PAD1 option doesn't have length and value field */
+          opt_dlen = -1;
+          break;
+        case IP6_PADN_OPTION:
+          opt_dlen = IP6_OPT_DLEN(opt_hdr);
+          break;
+        case IP6_ROUTER_ALERT_OPTION:
+          opt_dlen = IP6_OPT_DLEN(opt_hdr);
+          break;
+        case IP6_JUMBO_OPTION:
+          opt_dlen = IP6_OPT_DLEN(opt_hdr);
+          break;
+        default:
+          /* Check 2 MSB of Hop-by-Hop header type. */
+          switch (IP6_OPT_TYPE_ACTION(opt_hdr)) {
+          case 1:
+            /* Discard the packet. */
+            LWIP_DEBUGF(IP6_DEBUG, ("ip6_input: packet with invalid Hop-by-Hop option type dropped.\n"));
+            pbuf_free(p);
+            IP6_STATS_INC(ip6.drop);
+            goto ip6_input_cleanup;
+          case 2:
+            /* Send ICMP Parameter Problem */
+            icmp6_param_problem(p, ICMP6_PP_OPTION, opt_hdr);
+            LWIP_DEBUGF(IP6_DEBUG, ("ip6_input: packet with invalid Hop-by-Hop option type dropped.\n"));
+            pbuf_free(p);
+            IP6_STATS_INC(ip6.drop);
+            goto ip6_input_cleanup;
+          case 3:
+            /* Send ICMP Parameter Problem if destination address is not a multicast address */
+            if (!ip6_addr_ismulticast(ip6_current_dest_addr())) {
+              icmp6_param_problem(p, ICMP6_PP_OPTION, opt_hdr);
+            }
+            LWIP_DEBUGF(IP6_DEBUG, ("ip6_input: packet with invalid Hop-by-Hop option type dropped.\n"));
+            pbuf_free(p);
+            IP6_STATS_INC(ip6.drop);
+            goto ip6_input_cleanup;
+          default:
+            /* Skip over this option. */
+            opt_dlen = IP6_OPT_DLEN(opt_hdr);
+            break;
+          }
+          break;
+        }
+
+        /* Adjust the offset to move to the next extended option header */
+        opt_offset = opt_offset + IP6_OPT_HLEN + opt_dlen;
+      }
+      pbuf_remove_header(p, hlen);
+      break;
+    }
+    case IP6_NEXTH_DESTOPTS:
+    {
+      s32_t opt_offset;
+      struct ip6_dest_hdr *dest_hdr;
+      struct ip6_opt_hdr *opt_hdr;
+      LWIP_DEBUGF(IP6_DEBUG, ("ip6_input: packet with Destination options header\n"));
+
+      dest_hdr = (struct ip6_dest_hdr *)p->payload;
+
+      /* Get next header type. */
+      nexth = &IP6_DEST_NEXTH(dest_hdr);
+
+      /* Get the header length. */
+      hlen = 8 * (1 + dest_hdr->_hlen);
+      if ((p->len < 8) || (hlen > p->len)) {
+        LWIP_DEBUGF(IP6_DEBUG | LWIP_DBG_LEVEL_SERIOUS,
+          ("IPv6 options header (hlen %"U16_F") does not fit in first pbuf (len %"U16_F"), IPv6 packet dropped.\n",
+              hlen, p->len));
+        /* free (drop) packet pbufs */
+        pbuf_free(p);
+        IP6_STATS_INC(ip6.lenerr);
+        IP6_STATS_INC(ip6.drop);
+        goto ip6_input_cleanup;
+      }
+
+      hlen_tot = (u16_t)(hlen_tot + hlen);
+
+      /* The extended option header starts right after Destination header. */
+      opt_offset = IP6_DEST_HLEN;
+      while (opt_offset < hlen)
+      {
+        s32_t opt_dlen = 0;
+
+        opt_hdr = (struct ip6_opt_hdr *)((u8_t *)dest_hdr + opt_offset);
+
+        switch (IP6_OPT_TYPE(opt_hdr))
+        {
+        /* @todo: process IPV6 Destination option data */
+        case IP6_PAD1_OPTION:
+          /* PAD1 option deosn't have length and value field */
+          opt_dlen = -1;
+          break;
+        case IP6_PADN_OPTION:
+          opt_dlen = IP6_OPT_DLEN(opt_hdr);
+          break;
+        case IP6_ROUTER_ALERT_OPTION:
+          opt_dlen = IP6_OPT_DLEN(opt_hdr);
+          break;
+        case IP6_JUMBO_OPTION:
+          opt_dlen = IP6_OPT_DLEN(opt_hdr);
+          break;
+        case IP6_HOME_ADDRESS_OPTION:
+          opt_dlen = IP6_OPT_DLEN(opt_hdr);
+          break;
+        default:
+          /* Check 2 MSB of Destination header type. */
+          switch (IP6_OPT_TYPE_ACTION(opt_hdr))
+          {
+          case 1:
+            /* Discard the packet. */
+            LWIP_DEBUGF(IP6_DEBUG, ("ip6_input: packet with invalid destination option type dropped.\n"));
+            pbuf_free(p);
+            IP6_STATS_INC(ip6.drop);
+            goto ip6_input_cleanup;
+          case 2:
+            /* Send ICMP Parameter Problem */
+            icmp6_param_problem(p, ICMP6_PP_OPTION, opt_hdr);
+            LWIP_DEBUGF(IP6_DEBUG, ("ip6_input: packet with invalid destination option type dropped.\n"));
+            pbuf_free(p);
+            IP6_STATS_INC(ip6.drop);
+            goto ip6_input_cleanup;
+          case 3:
+            /* Send ICMP Parameter Problem if destination address is not a multicast address */
+            if (!ip6_addr_ismulticast(ip6_current_dest_addr())) {
+              icmp6_param_problem(p, ICMP6_PP_OPTION, opt_hdr);
+            }
+            LWIP_DEBUGF(IP6_DEBUG, ("ip6_input: packet with invalid destination option type dropped.\n"));
+            pbuf_free(p);
+            IP6_STATS_INC(ip6.drop);
+            goto ip6_input_cleanup;
+          default:
+            /* Skip over this option. */
+            opt_dlen = IP6_OPT_DLEN(opt_hdr);
+            break;
+          }
+          break;
+        }
+
+        /* Adjust the offset to move to the next extended option header */
+        opt_offset = opt_offset + IP6_OPT_HLEN + opt_dlen;
+      }
+
+      pbuf_remove_header(p, hlen);
+      break;
+    }
+    case IP6_NEXTH_ROUTING:
+    {
+      struct ip6_rout_hdr *rout_hdr;
+      LWIP_DEBUGF(IP6_DEBUG, ("ip6_input: packet with Routing header\n"));
+
+      rout_hdr = (struct ip6_rout_hdr *)p->payload;
+
+      /* Get next header type. */
+      nexth = &IP6_ROUT_NEXTH(rout_hdr);
+
+      /* Get the header length. */
+      hlen = 8 * (1 + rout_hdr->_hlen);
+
+      if ((p->len < 8) || (hlen > p->len)) {
+        LWIP_DEBUGF(IP6_DEBUG | LWIP_DBG_LEVEL_SERIOUS,
+          ("IPv6 options header (hlen %"U16_F") does not fit in first pbuf (len %"U16_F"), IPv6 packet dropped.\n",
+              hlen, p->len));
+        /* free (drop) packet pbufs */
+        pbuf_free(p);
+        IP6_STATS_INC(ip6.lenerr);
+        IP6_STATS_INC(ip6.drop);
+        goto ip6_input_cleanup;
+      }
+
+      /* Skip over this header. */
+      hlen_tot = (u16_t)(hlen_tot + hlen);
+
+      /* if segment left value is 0 in routing header, ignore the option */
+      if (IP6_ROUT_SEG_LEFT(rout_hdr)) {
+        /* The length field of routing option header must be even */
+        if (rout_hdr->_hlen & 0x1) {
+          /* Discard and send parameter field error */
+          icmp6_param_problem(p, ICMP6_PP_FIELD, &rout_hdr->_hlen);
+          LWIP_DEBUGF(IP6_DEBUG, ("ip6_input: packet with invalid routing type dropped\n"));
+          pbuf_free(p);
+          IP6_STATS_INC(ip6.drop);
+          goto ip6_input_cleanup;
+        }
+
+        switch (IP6_ROUT_TYPE(rout_hdr))
+        {
+        /* TODO: process routing by the type */
+        case IP6_ROUT_TYPE2:
+          break;
+        case IP6_ROUT_RPL:
+          break;
+        default:
+          /* Discard unrecognized routing type and send parameter field error */
+          icmp6_param_problem(p, ICMP6_PP_FIELD, &IP6_ROUT_TYPE(rout_hdr));
+          LWIP_DEBUGF(IP6_DEBUG, ("ip6_input: packet with invalid routing type dropped\n"));
+          pbuf_free(p);
+          IP6_STATS_INC(ip6.drop);
+          goto ip6_input_cleanup;
+        }
+      }
+
+      pbuf_remove_header(p, hlen);
+      break;
+    }
+    case IP6_NEXTH_FRAGMENT:
+    {
+      struct ip6_frag_hdr *frag_hdr;
+      LWIP_DEBUGF(IP6_DEBUG, ("ip6_input: packet with Fragment header\n"));
+
+      frag_hdr = (struct ip6_frag_hdr *)p->payload;
+
+      /* Get next header type. */
+      nexth = &IP6_FRAG_NEXTH(frag_hdr);
+
+      /* Fragment Header length. */
+      hlen = 8;
+
+      /* Make sure this header fits in current pbuf. */
+      if (hlen > p->len) {
+        LWIP_DEBUGF(IP6_DEBUG | LWIP_DBG_LEVEL_SERIOUS,
+          ("IPv6 options header (hlen %"U16_F") does not fit in first pbuf (len %"U16_F"), IPv6 packet dropped.\n",
+              hlen, p->len));
+        /* free (drop) packet pbufs */
+        pbuf_free(p);
+        IP6_FRAG_STATS_INC(ip6_frag.lenerr);
+        IP6_FRAG_STATS_INC(ip6_frag.drop);
+        goto ip6_input_cleanup;
+      }
+
+      hlen_tot = (u16_t)(hlen_tot + hlen);
+
+      /* check payload length is multiple of 8 octets when mbit is set */
+      if (IP6_FRAG_MBIT(frag_hdr) && (IP6H_PLEN(ip6hdr) & 0x7)) {
+        /* ipv6 payload length is not multiple of 8 octets */
+        icmp6_param_problem(p, ICMP6_PP_FIELD, LWIP_PACKED_CAST(const void *, &ip6hdr->_plen));
+        LWIP_DEBUGF(IP6_DEBUG, ("ip6_input: packet with invalid payload length dropped\n"));
+        pbuf_free(p);
+        IP6_STATS_INC(ip6.drop);
+        goto ip6_input_cleanup;
+      }
+
+      /* Offset == 0 and more_fragments == 0? */
+      if ((frag_hdr->_fragment_offset &
+           PP_HTONS(IP6_FRAG_OFFSET_MASK | IP6_FRAG_MORE_FLAG)) == 0) {
+        /* This is a 1-fragment packet. Skip this header and continue. */
+        pbuf_remove_header(p, hlen);
+      } else {
+#if LWIP_IPV6_REASS
+        /* reassemble the packet */
+        ip_data.current_ip_header_tot_len = hlen_tot;
+        p = ip6_reass(p);
+        /* packet not fully reassembled yet? */
+        if (p == NULL) {
+          goto ip6_input_cleanup;
+        }
+
+        /* Returned p point to IPv6 header.
+         * Update all our variables and pointers and continue. */
+        ip6hdr = (struct ip6_hdr *)p->payload;
+        nexth = &IP6H_NEXTH(ip6hdr);
+        hlen = hlen_tot = IP6_HLEN;
+        pbuf_remove_header(p, IP6_HLEN);
+
+#else /* LWIP_IPV6_REASS */
+        /* free (drop) packet pbufs */
+        LWIP_DEBUGF(IP6_DEBUG, ("ip6_input: packet with Fragment header dropped (with LWIP_IPV6_REASS==0)\n"));
+        pbuf_free(p);
+        IP6_STATS_INC(ip6.opterr);
+        IP6_STATS_INC(ip6.drop);
+        goto ip6_input_cleanup;
+#endif /* LWIP_IPV6_REASS */
+      }
+      break;
+    }
+    default:
+      goto options_done;
+    }
+
+    if (*nexth == IP6_NEXTH_HOPBYHOP) {
+      /* Hop-by-Hop header comes only as a first option */
+      icmp6_param_problem(p, ICMP6_PP_HEADER, nexth);
+      LWIP_DEBUGF(IP6_DEBUG, ("ip6_input: packet with Hop-by-Hop options header dropped (only valid as a first option)\n"));
+      pbuf_free(p);
+      IP6_STATS_INC(ip6.drop);
+      goto ip6_input_cleanup;
+    }
+  }
+
+options_done:
+
+  /* send to upper layers */
+  LWIP_DEBUGF(IP6_DEBUG, ("ip6_input: \n"));
+  ip6_debug_print(p);
+  LWIP_DEBUGF(IP6_DEBUG, ("ip6_input: p->len %"U16_F" p->tot_len %"U16_F"\n", p->len, p->tot_len));
+
+  ip_data.current_ip_header_tot_len = hlen_tot;
+  
+#if LWIP_RAW
+  /* p points to IPv6 header again for raw_input. */
+  pbuf_add_header_force(p, hlen_tot);
+  /* raw input did not eat the packet? */
+  raw_status = raw_input(p, inp);
+  if (raw_status != RAW_INPUT_EATEN)
+  {
+    /* Point to payload. */
+    pbuf_remove_header(p, hlen_tot);
+#else /* LWIP_RAW */
+  {
+#endif /* LWIP_RAW */
+    switch (*nexth) {
+    case IP6_NEXTH_NONE:
+      pbuf_free(p);
+      break;
+#if LWIP_UDP
+    case IP6_NEXTH_UDP:
+#if LWIP_UDPLITE
+    case IP6_NEXTH_UDPLITE:
+#endif /* LWIP_UDPLITE */
+      udp_input(p, inp);
+      break;
+#endif /* LWIP_UDP */
+#if LWIP_TCP
+    case IP6_NEXTH_TCP:
+      tcp_input(p, inp);
+      break;
+#endif /* LWIP_TCP */
+#if LWIP_ICMP6
+    case IP6_NEXTH_ICMP6:
+      icmp6_input(p, inp);
+      break;
+#endif /* LWIP_ICMP */
+    default:
+#if LWIP_RAW
+        if (raw_status == RAW_INPUT_DELIVERED) {
+          /* @todo: ipv6 mib in-delivers? */
+        } else
+#endif /* LWIP_RAW */
+        {
+#if LWIP_ICMP6
+        /* p points to IPv6 header again for raw_input. */
+        pbuf_add_header_force(p, hlen_tot);
+        /* send ICMP parameter problem unless it was a multicast or ICMPv6 */
+        if ((!ip6_addr_ismulticast(ip6_current_dest_addr())) &&
+            (IP6H_NEXTH(ip6hdr) != IP6_NEXTH_ICMP6)) {
+          icmp6_param_problem(p, ICMP6_PP_HEADER, nexth);
+        }
+#endif /* LWIP_ICMP */
+        LWIP_DEBUGF(IP6_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("ip6_input: Unsupported transport protocol %"U16_F"\n", (u16_t)IP6H_NEXTH(ip6hdr)));
+        IP6_STATS_INC(ip6.proterr);
+        IP6_STATS_INC(ip6.drop);
+      }
+      pbuf_free(p);
+      break;
+    }
+  }
+
+ip6_input_cleanup:
+  ip_data.current_netif = NULL;
+  ip_data.current_input_netif = NULL;
+  ip_data.current_ip6_header = NULL;
+  ip_data.current_ip_header_tot_len = 0;
+  ip6_addr_set_zero(ip6_current_src_addr());
+  ip6_addr_set_zero(ip6_current_dest_addr());
+
+  return ERR_OK;
+}
+
+
+/**
+ * Sends an IPv6 packet on a network interface. This function constructs
+ * the IPv6 header. If the source IPv6 address is NULL, the IPv6 "ANY" address is
+ * used as source (usually during network startup). If the source IPv6 address it
+ * IP6_ADDR_ANY, the most appropriate IPv6 address of the outgoing network
+ * interface is filled in as source address. If the destination IPv6 address is
+ * LWIP_IP_HDRINCL, p is assumed to already include an IPv6 header and
+ * p->payload points to it instead of the data.
+ *
+ * @param p the packet to send (p->payload points to the data, e.g. next
+            protocol header; if dest == LWIP_IP_HDRINCL, p already includes an
+            IPv6 header and p->payload points to that IPv6 header)
+ * @param src the source IPv6 address to send from (if src == IP6_ADDR_ANY, an
+ *         IP address of the netif is selected and used as source address.
+ *         if src == NULL, IP6_ADDR_ANY is used as source) (src is possibly not
+ *         properly zoned)
+ * @param dest the destination IPv6 address to send the packet to (possibly not
+ *             properly zoned)
+ * @param hl the Hop Limit value to be set in the IPv6 header
+ * @param tc the Traffic Class value to be set in the IPv6 header
+ * @param nexth the Next Header to be set in the IPv6 header
+ * @param netif the netif on which to send this packet
+ * @return ERR_OK if the packet was sent OK
+ *         ERR_BUF if p doesn't have enough space for IPv6/LINK headers
+ *         returns errors returned by netif->output_ip6
+ */
+err_t
+ip6_output_if(struct pbuf *p, const ip6_addr_t *src, const ip6_addr_t *dest,
+             u8_t hl, u8_t tc,
+             u8_t nexth, struct netif *netif)
+{
+  const ip6_addr_t *src_used = src;
+  if (dest != LWIP_IP_HDRINCL) {
+    if (src != NULL && ip6_addr_isany(src)) {
+      src_used = ip_2_ip6(ip6_select_source_address(netif, dest));
+      if ((src_used == NULL) || ip6_addr_isany(src_used)) {
+        /* No appropriate source address was found for this packet. */
+        LWIP_DEBUGF(IP6_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("ip6_output: No suitable source address for packet.\n"));
+        IP6_STATS_INC(ip6.rterr);
+        return ERR_RTE;
+      }
+    }
+  }
+  return ip6_output_if_src(p, src_used, dest, hl, tc, nexth, netif);
+}
+
+/**
+ * Same as ip6_output_if() but 'src' address is not replaced by netif address
+ * when it is 'any'.
+ */
+err_t
+ip6_output_if_src(struct pbuf *p, const ip6_addr_t *src, const ip6_addr_t *dest,
+             u8_t hl, u8_t tc,
+             u8_t nexth, struct netif *netif)
+{
+  struct ip6_hdr *ip6hdr;
+  ip6_addr_t dest_addr;
+
+  LWIP_ASSERT_CORE_LOCKED();
+  LWIP_IP_CHECK_PBUF_REF_COUNT_FOR_TX(p);
+
+  /* Should the IPv6 header be generated or is it already included in p? */
+  if (dest != LWIP_IP_HDRINCL) {
+#if LWIP_IPV6_SCOPES
+    /* If the destination address is scoped but lacks a zone, add a zone now,
+     * based on the outgoing interface. The lower layers (e.g., nd6) absolutely
+     * require addresses to be properly zoned for correctness. In some cases,
+     * earlier attempts will have been made to add a zone to the destination,
+     * but this function is the only one that is called in all (other) cases,
+     * so we must do this here. */
+    if (ip6_addr_lacks_zone(dest, IP6_UNKNOWN)) {
+      ip6_addr_copy(dest_addr, *dest);
+      ip6_addr_assign_zone(&dest_addr, IP6_UNKNOWN, netif);
+      dest = &dest_addr;
+    }
+#endif /* LWIP_IPV6_SCOPES */
+
+    /* generate IPv6 header */
+    if (pbuf_add_header(p, IP6_HLEN)) {
+      LWIP_DEBUGF(IP6_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("ip6_output: not enough room for IPv6 header in pbuf\n"));
+      IP6_STATS_INC(ip6.err);
+      return ERR_BUF;
+    }
+
+    ip6hdr = (struct ip6_hdr *)p->payload;
+    LWIP_ASSERT("check that first pbuf can hold struct ip6_hdr",
+               (p->len >= sizeof(struct ip6_hdr)));
+
+    IP6H_HOPLIM_SET(ip6hdr, hl);
+    IP6H_NEXTH_SET(ip6hdr, nexth);
+
+    /* dest cannot be NULL here */
+    ip6_addr_copy_to_packed(ip6hdr->dest, *dest);
+
+    IP6H_VTCFL_SET(ip6hdr, 6, tc, 0);
+    IP6H_PLEN_SET(ip6hdr, (u16_t)(p->tot_len - IP6_HLEN));
+
+    if (src == NULL) {
+      src = IP6_ADDR_ANY6;
+    }
+    /* src cannot be NULL here */
+    ip6_addr_copy_to_packed(ip6hdr->src, *src);
+
+  } else {
+    /* IP header already included in p */
+    ip6hdr = (struct ip6_hdr *)p->payload;
+    ip6_addr_copy_from_packed(dest_addr, ip6hdr->dest);
+    ip6_addr_assign_zone(&dest_addr, IP6_UNKNOWN, netif);
+    dest = &dest_addr;
+  }
+
+  IP6_STATS_INC(ip6.xmit);
+
+  LWIP_DEBUGF(IP6_DEBUG, ("ip6_output_if: %c%c%"U16_F"\n", netif->name[0], netif->name[1], (u16_t)netif->num));
+  ip6_debug_print(p);
+
+#if ENABLE_LOOPBACK
+  {
+    int i;
+#if !LWIP_HAVE_LOOPIF
+    if (ip6_addr_isloopback(dest)) {
+      return netif_loop_output(netif, p);
+    }
+#endif /* !LWIP_HAVE_LOOPIF */
+    for (i = 0; i < LWIP_IPV6_NUM_ADDRESSES; i++) {
+      if (ip6_addr_isvalid(netif_ip6_addr_state(netif, i)) &&
+          ip6_addr_cmp(dest, netif_ip6_addr(netif, i))) {
+        /* Packet to self, enqueue it for loopback */
+        LWIP_DEBUGF(IP6_DEBUG, ("netif_loop_output()\n"));
+        return netif_loop_output(netif, p);
+      }
+    }
+  }
+#if LWIP_MULTICAST_TX_OPTIONS
+  if ((p->flags & PBUF_FLAG_MCASTLOOP) != 0) {
+    netif_loop_output(netif, p);
+  }
+#endif /* LWIP_MULTICAST_TX_OPTIONS */
+#endif /* ENABLE_LOOPBACK */
+#if LWIP_IPV6_FRAG
+  /* don't fragment if interface has mtu set to 0 [loopif] */
+  if (netif_mtu6(netif) && (p->tot_len > nd6_get_destination_mtu(dest, netif))) {
+    return ip6_frag(p, netif, dest);
+  }
+#endif /* LWIP_IPV6_FRAG */
+
+  LWIP_DEBUGF(IP6_DEBUG, ("netif->output_ip6()\n"));
+  return netif->output_ip6(netif, p, dest);
+}
+
+/**
+ * Simple interface to ip6_output_if. It finds the outgoing network
+ * interface and calls upon ip6_output_if to do the actual work.
+ *
+ * @param p the packet to send (p->payload points to the data, e.g. next
+            protocol header; if dest == LWIP_IP_HDRINCL, p already includes an
+            IPv6 header and p->payload points to that IPv6 header)
+ * @param src the source IPv6 address to send from (if src == IP6_ADDR_ANY, an
+ *         IP address of the netif is selected and used as source address.
+ *         if src == NULL, IP6_ADDR_ANY is used as source)
+ * @param dest the destination IPv6 address to send the packet to
+ * @param hl the Hop Limit value to be set in the IPv6 header
+ * @param tc the Traffic Class value to be set in the IPv6 header
+ * @param nexth the Next Header to be set in the IPv6 header
+ *
+ * @return ERR_RTE if no route is found
+ *         see ip_output_if() for more return values
+ */
+err_t
+ip6_output(struct pbuf *p, const ip6_addr_t *src, const ip6_addr_t *dest,
+          u8_t hl, u8_t tc, u8_t nexth)
+{
+  struct netif *netif;
+  struct ip6_hdr *ip6hdr;
+  ip6_addr_t src_addr, dest_addr;
+
+  LWIP_IP_CHECK_PBUF_REF_COUNT_FOR_TX(p);
+
+  if (dest != LWIP_IP_HDRINCL) {
+    netif = ip6_route(src, dest);
+  } else {
+    /* IP header included in p, read addresses. */
+    ip6hdr = (struct ip6_hdr *)p->payload;
+    ip6_addr_copy_from_packed(src_addr, ip6hdr->src);
+    ip6_addr_copy_from_packed(dest_addr, ip6hdr->dest);
+    netif = ip6_route(&src_addr, &dest_addr);
+  }
+
+  if (netif == NULL) {
+    LWIP_DEBUGF(IP6_DEBUG, ("ip6_output: no route for %"X16_F":%"X16_F":%"X16_F":%"X16_F":%"X16_F":%"X16_F":%"X16_F":%"X16_F"\n",
+        IP6_ADDR_BLOCK1(dest),
+        IP6_ADDR_BLOCK2(dest),
+        IP6_ADDR_BLOCK3(dest),
+        IP6_ADDR_BLOCK4(dest),
+        IP6_ADDR_BLOCK5(dest),
+        IP6_ADDR_BLOCK6(dest),
+        IP6_ADDR_BLOCK7(dest),
+        IP6_ADDR_BLOCK8(dest)));
+    IP6_STATS_INC(ip6.rterr);
+    return ERR_RTE;
+  }
+
+  return ip6_output_if(p, src, dest, hl, tc, nexth, netif);
+}
+
+
+#if LWIP_NETIF_USE_HINTS
+/** Like ip6_output, but takes and addr_hint pointer that is passed on to netif->addr_hint
+ *  before calling ip6_output_if.
+ *
+ * @param p the packet to send (p->payload points to the data, e.g. next
+            protocol header; if dest == LWIP_IP_HDRINCL, p already includes an
+            IPv6 header and p->payload points to that IPv6 header)
+ * @param src the source IPv6 address to send from (if src == IP6_ADDR_ANY, an
+ *         IP address of the netif is selected and used as source address.
+ *         if src == NULL, IP6_ADDR_ANY is used as source)
+ * @param dest the destination IPv6 address to send the packet to
+ * @param hl the Hop Limit value to be set in the IPv6 header
+ * @param tc the Traffic Class value to be set in the IPv6 header
+ * @param nexth the Next Header to be set in the IPv6 header
+ * @param netif_hint netif output hint pointer set to netif->hint before
+ *        calling ip_output_if()
+ *
+ * @return ERR_RTE if no route is found
+ *         see ip_output_if() for more return values
+ */
+err_t
+ip6_output_hinted(struct pbuf *p, const ip6_addr_t *src, const ip6_addr_t *dest,
+          u8_t hl, u8_t tc, u8_t nexth, struct netif_hint *netif_hint)
+{
+  struct netif *netif;
+  struct ip6_hdr *ip6hdr;
+  ip6_addr_t src_addr, dest_addr;
+  err_t err;
+
+  LWIP_IP_CHECK_PBUF_REF_COUNT_FOR_TX(p);
+
+  if (dest != LWIP_IP_HDRINCL) {
+    netif = ip6_route(src, dest);
+  } else {
+    /* IP header included in p, read addresses. */
+    ip6hdr = (struct ip6_hdr *)p->payload;
+    ip6_addr_copy_from_packed(src_addr, ip6hdr->src);
+    ip6_addr_copy_from_packed(dest_addr, ip6hdr->dest);
+    netif = ip6_route(&src_addr, &dest_addr);
+  }
+
+  if (netif == NULL) {
+    LWIP_DEBUGF(IP6_DEBUG, ("ip6_output: no route for %"X16_F":%"X16_F":%"X16_F":%"X16_F":%"X16_F":%"X16_F":%"X16_F":%"X16_F"\n",
+        IP6_ADDR_BLOCK1(dest),
+        IP6_ADDR_BLOCK2(dest),
+        IP6_ADDR_BLOCK3(dest),
+        IP6_ADDR_BLOCK4(dest),
+        IP6_ADDR_BLOCK5(dest),
+        IP6_ADDR_BLOCK6(dest),
+        IP6_ADDR_BLOCK7(dest),
+        IP6_ADDR_BLOCK8(dest)));
+    IP6_STATS_INC(ip6.rterr);
+    return ERR_RTE;
+  }
+
+  NETIF_SET_HINTS(netif, netif_hint);
+  err = ip6_output_if(p, src, dest, hl, tc, nexth, netif);
+  NETIF_RESET_HINTS(netif);
+
+  return err;
+}
+#endif /* LWIP_NETIF_USE_HINTS*/
+
+#if LWIP_IPV6_MLD
+/**
+ * Add a hop-by-hop options header with a router alert option and padding.
+ *
+ * Used by MLD when sending a Multicast listener report/done message.
+ *
+ * @param p the packet to which we will prepend the options header
+ * @param nexth the next header protocol number (e.g. IP6_NEXTH_ICMP6)
+ * @param value the value of the router alert option data (e.g. IP6_ROUTER_ALERT_VALUE_MLD)
+ * @return ERR_OK if hop-by-hop header was added, ERR_* otherwise
+ */
+err_t
+ip6_options_add_hbh_ra(struct pbuf *p, u8_t nexth, u8_t value)
+{
+  u8_t *opt_data;
+  u32_t offset = 0;
+  struct ip6_hbh_hdr *hbh_hdr;
+  struct ip6_opt_hdr *opt_hdr;
+
+  /* fixed 4 bytes for router alert option and 2 bytes padding */
+  const u8_t hlen = (sizeof(struct ip6_opt_hdr) * 2) + IP6_ROUTER_ALERT_DLEN;
+  /* Move pointer to make room for hop-by-hop options header. */
+  if (pbuf_add_header(p, sizeof(struct ip6_hbh_hdr) + hlen)) {
+    LWIP_DEBUGF(IP6_DEBUG, ("ip6_options: no space for options header\n"));
+    IP6_STATS_INC(ip6.err);
+    return ERR_BUF;
+  }
+
+  /* Set fields of Hop-by-Hop header */
+  hbh_hdr = (struct ip6_hbh_hdr *)p->payload;
+  IP6_HBH_NEXTH(hbh_hdr) = nexth;
+  hbh_hdr->_hlen = 0;
+  offset = IP6_HBH_HLEN;
+
+  /* Set router alert options to Hop-by-Hop extended option header */
+  opt_hdr = (struct ip6_opt_hdr *)((u8_t *)hbh_hdr + offset);
+  IP6_OPT_TYPE(opt_hdr) = IP6_ROUTER_ALERT_OPTION;
+  IP6_OPT_DLEN(opt_hdr) = IP6_ROUTER_ALERT_DLEN;
+  offset += IP6_OPT_HLEN;
+
+  /* Set router alert option data */
+  opt_data = (u8_t *)hbh_hdr + offset;
+  opt_data[0] = value;
+  opt_data[1] = 0;
+  offset += IP6_OPT_DLEN(opt_hdr);
+
+  /* add 2 bytes padding to make 8 bytes Hop-by-Hop header length */
+  opt_hdr = (struct ip6_opt_hdr *)((u8_t *)hbh_hdr + offset);
+  IP6_OPT_TYPE(opt_hdr) = IP6_PADN_OPTION;
+  IP6_OPT_DLEN(opt_hdr) = 0;
+
+  return ERR_OK;
+}
+#endif /* LWIP_IPV6_MLD */
+
+#if IP6_DEBUG
+/* Print an IPv6 header by using LWIP_DEBUGF
+ * @param p an IPv6 packet, p->payload pointing to the IPv6 header
+ */
+void
+ip6_debug_print(struct pbuf *p)
+{
+  struct ip6_hdr *ip6hdr = (struct ip6_hdr *)p->payload;
+
+  LWIP_DEBUGF(IP6_DEBUG, ("IPv6 header:\n"));
+  LWIP_DEBUGF(IP6_DEBUG, ("+-------------------------------+\n"));
+  LWIP_DEBUGF(IP6_DEBUG, ("| %2"U16_F" |  %3"U16_F"  |      %7"U32_F"     | (ver, class, flow)\n",
+                    IP6H_V(ip6hdr),
+                    IP6H_TC(ip6hdr),
+                    IP6H_FL(ip6hdr)));
+  LWIP_DEBUGF(IP6_DEBUG, ("+-------------------------------+\n"));
+  LWIP_DEBUGF(IP6_DEBUG, ("|     %5"U16_F"     |  %3"U16_F"  |  %3"U16_F"  | (plen, nexth, hopl)\n",
+                    IP6H_PLEN(ip6hdr),
+                    IP6H_NEXTH(ip6hdr),
+                    IP6H_HOPLIM(ip6hdr)));
+  LWIP_DEBUGF(IP6_DEBUG, ("+-------------------------------+\n"));
+  LWIP_DEBUGF(IP6_DEBUG, ("|  %4"X32_F" |  %4"X32_F" |  %4"X32_F" |  %4"X32_F" | (src)\n",
+                    IP6_ADDR_BLOCK1(&(ip6hdr->src)),
+                    IP6_ADDR_BLOCK2(&(ip6hdr->src)),
+                    IP6_ADDR_BLOCK3(&(ip6hdr->src)),
+                    IP6_ADDR_BLOCK4(&(ip6hdr->src))));
+  LWIP_DEBUGF(IP6_DEBUG, ("|  %4"X32_F" |  %4"X32_F" |  %4"X32_F" |  %4"X32_F" |\n",
+                    IP6_ADDR_BLOCK5(&(ip6hdr->src)),
+                    IP6_ADDR_BLOCK6(&(ip6hdr->src)),
+                    IP6_ADDR_BLOCK7(&(ip6hdr->src)),
+                    IP6_ADDR_BLOCK8(&(ip6hdr->src))));
+  LWIP_DEBUGF(IP6_DEBUG, ("+-------------------------------+\n"));
+  LWIP_DEBUGF(IP6_DEBUG, ("|  %4"X32_F" |  %4"X32_F" |  %4"X32_F" |  %4"X32_F" | (dest)\n",
+                    IP6_ADDR_BLOCK1(&(ip6hdr->dest)),
+                    IP6_ADDR_BLOCK2(&(ip6hdr->dest)),
+                    IP6_ADDR_BLOCK3(&(ip6hdr->dest)),
+                    IP6_ADDR_BLOCK4(&(ip6hdr->dest))));
+  LWIP_DEBUGF(IP6_DEBUG, ("|  %4"X32_F" |  %4"X32_F" |  %4"X32_F" |  %4"X32_F" |\n",
+                    IP6_ADDR_BLOCK5(&(ip6hdr->dest)),
+                    IP6_ADDR_BLOCK6(&(ip6hdr->dest)),
+                    IP6_ADDR_BLOCK7(&(ip6hdr->dest)),
+                    IP6_ADDR_BLOCK8(&(ip6hdr->dest))));
+  LWIP_DEBUGF(IP6_DEBUG, ("+-------------------------------+\n"));
+}
+#endif /* IP6_DEBUG */
+
+#endif /* LWIP_IPV6 */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/core/ipv6/ip6_addr.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/core/ipv6/ip6_addr.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/core/ipv6/ip6_addr.c	(revision 457)
@@ -0,0 +1,343 @@
+/**
+ * @file
+ *
+ * IPv6 addresses.
+ */
+
+/*
+ * Copyright (c) 2010 Inico Technologies Ltd.
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Ivan Delamer <delamer@inicotech.com>
+ *
+ * Functions for handling IPv6 addresses.
+ *
+ * Please coordinate changes and requests with Ivan Delamer
+ * <delamer@inicotech.com>
+ */
+
+#include "lwip/opt.h"
+
+#if LWIP_IPV6  /* don't build if not configured for use in lwipopts.h */
+
+#include "lwip/ip_addr.h"
+#include "lwip/def.h"
+
+#include <string.h>
+
+#if LWIP_IPV4
+#include "lwip/ip4_addr.h" /* for ip6addr_aton to handle IPv4-mapped addresses */
+#endif /* LWIP_IPV4 */
+
+/* used by IP6_ADDR_ANY(6) in ip6_addr.h */
+const ip_addr_t ip6_addr_any = IPADDR6_INIT(0ul, 0ul, 0ul, 0ul);
+
+#define lwip_xchar(i)        ((char)((i) < 10 ? '0' + (i) : 'A' + (i) - 10))
+
+/**
+ * Check whether "cp" is a valid ascii representation
+ * of an IPv6 address and convert to a binary address.
+ * Returns 1 if the address is valid, 0 if not.
+ *
+ * @param cp IPv6 address in ascii representation (e.g. "FF01::1")
+ * @param addr pointer to which to save the ip address in network order
+ * @return 1 if cp could be converted to addr, 0 on failure
+ */
+int
+ip6addr_aton(const char *cp, ip6_addr_t *addr)
+{
+  u32_t addr_index, zero_blocks, current_block_index, current_block_value;
+  const char *s;
+#if LWIP_IPV4
+  int check_ipv4_mapped = 0;
+#endif /* LWIP_IPV4 */
+
+  /* Count the number of colons, to count the number of blocks in a "::" sequence
+     zero_blocks may be 1 even if there are no :: sequences */
+  zero_blocks = 8;
+  for (s = cp; *s != 0; s++) {
+    if (*s == ':') {
+      zero_blocks--;
+#if LWIP_IPV4
+    } else if (*s == '.') {
+      if ((zero_blocks == 5) ||(zero_blocks == 2)) {
+        check_ipv4_mapped = 1;
+        /* last block could be the start of an IPv4 address */
+        zero_blocks--;
+      } else {
+        /* invalid format */
+        return 0;
+      }
+      break;
+#endif /* LWIP_IPV4 */
+    } else if (!lwip_isxdigit(*s)) {
+      break;
+    }
+  }
+
+  /* parse each block */
+  addr_index = 0;
+  current_block_index = 0;
+  current_block_value = 0;
+  for (s = cp; *s != 0; s++) {
+    if (*s == ':') {
+      if (addr) {
+        if (current_block_index & 0x1) {
+          addr->addr[addr_index++] |= current_block_value;
+        }
+        else {
+          addr->addr[addr_index] = current_block_value << 16;
+        }
+      }
+      current_block_index++;
+#if LWIP_IPV4
+      if (check_ipv4_mapped) {
+        if (current_block_index == 6) {
+          ip4_addr_t ip4;
+          int ret = ip4addr_aton(s + 1, &ip4);
+          if (ret) {
+            if (addr) {
+              addr->addr[3] = lwip_htonl(ip4.addr);
+              current_block_index++;
+              goto fix_byte_order_and_return;
+            }
+            return 1;
+          }
+        }
+      }
+#endif /* LWIP_IPV4 */
+      current_block_value = 0;
+      if (current_block_index > 7) {
+        /* address too long! */
+        return 0;
+      }
+      if (s[1] == ':') {
+        if (s[2] == ':') {
+          /* invalid format: three successive colons */
+          return 0;
+        }
+        s++;
+        /* "::" found, set zeros */
+        while (zero_blocks > 0) {
+          zero_blocks--;
+          if (current_block_index & 0x1) {
+            addr_index++;
+          } else {
+            if (addr) {
+              addr->addr[addr_index] = 0;
+            }
+          }
+          current_block_index++;
+          if (current_block_index > 7) {
+            /* address too long! */
+            return 0;
+          }
+        }
+      }
+    } else if (lwip_isxdigit(*s)) {
+      /* add current digit */
+      current_block_value = (current_block_value << 4) +
+          (lwip_isdigit(*s) ? (u32_t)(*s - '0') :
+          (u32_t)(10 + (lwip_islower(*s) ? *s - 'a' : *s - 'A')));
+    } else {
+      /* unexpected digit, space? CRLF? */
+      break;
+    }
+  }
+
+  if (addr) {
+    if (current_block_index & 0x1) {
+      addr->addr[addr_index++] |= current_block_value;
+    }
+    else {
+      addr->addr[addr_index] = current_block_value << 16;
+    }
+#if LWIP_IPV4
+fix_byte_order_and_return:
+#endif
+    /* convert to network byte order. */
+    for (addr_index = 0; addr_index < 4; addr_index++) {
+      addr->addr[addr_index] = lwip_htonl(addr->addr[addr_index]);
+    }
+
+    ip6_addr_clear_zone(addr);
+  }
+
+  if (current_block_index != 7) {
+    return 0;
+  }
+
+  return 1;
+}
+
+/**
+ * Convert numeric IPv6 address into ASCII representation.
+ * returns ptr to static buffer; not reentrant!
+ *
+ * @param addr ip6 address in network order to convert
+ * @return pointer to a global static (!) buffer that holds the ASCII
+ *         representation of addr
+ */
+char *
+ip6addr_ntoa(const ip6_addr_t *addr)
+{
+  static char str[40];
+  return ip6addr_ntoa_r(addr, str, 40);
+}
+
+/**
+ * Same as ipaddr_ntoa, but reentrant since a user-supplied buffer is used.
+ *
+ * @param addr ip6 address in network order to convert
+ * @param buf target buffer where the string is stored
+ * @param buflen length of buf
+ * @return either pointer to buf which now holds the ASCII
+ *         representation of addr or NULL if buf was too small
+ */
+char *
+ip6addr_ntoa_r(const ip6_addr_t *addr, char *buf, int buflen)
+{
+  u32_t current_block_index, current_block_value, next_block_value;
+  s32_t i;
+  u8_t zero_flag, empty_block_flag;
+
+#if LWIP_IPV4
+  if (ip6_addr_isipv4mappedipv6(addr)) {
+    /* This is an IPv4 mapped address */
+    ip4_addr_t addr4;
+    char *ret;
+#define IP4MAPPED_HEADER "::FFFF:"
+    char *buf_ip4 = buf + sizeof(IP4MAPPED_HEADER) - 1;
+    int buflen_ip4 = buflen - sizeof(IP4MAPPED_HEADER) + 1;
+    if (buflen < (int)sizeof(IP4MAPPED_HEADER)) {
+      return NULL;
+    }
+    memcpy(buf, IP4MAPPED_HEADER, sizeof(IP4MAPPED_HEADER));
+    addr4.addr = addr->addr[3];
+    ret = ip4addr_ntoa_r(&addr4, buf_ip4, buflen_ip4);
+    if (ret != buf_ip4) {
+      return NULL;
+    }
+    return buf;
+  }
+#endif /* LWIP_IPV4 */
+  i = 0;
+  empty_block_flag = 0; /* used to indicate a zero chain for "::' */
+
+  for (current_block_index = 0; current_block_index < 8; current_block_index++) {
+    /* get the current 16-bit block */
+    current_block_value = lwip_htonl(addr->addr[current_block_index >> 1]);
+    if ((current_block_index & 0x1) == 0) {
+      current_block_value = current_block_value >> 16;
+    }
+    current_block_value &= 0xffff;
+
+    /* Check for empty block. */
+    if (current_block_value == 0) {
+      if (current_block_index == 7 && empty_block_flag == 1) {
+        /* special case, we must render a ':' for the last block. */
+        buf[i++] = ':';
+        if (i >= buflen) {
+          return NULL;
+        }
+        break;
+      }
+      if (empty_block_flag == 0) {
+        /* generate empty block "::", but only if more than one contiguous zero block,
+         * according to current formatting suggestions RFC 5952. */
+        next_block_value = lwip_htonl(addr->addr[(current_block_index + 1) >> 1]);
+        if ((current_block_index & 0x1) == 0x01) {
+            next_block_value = next_block_value >> 16;
+        }
+        next_block_value &= 0xffff;
+        if (next_block_value == 0) {
+          empty_block_flag = 1;
+          buf[i++] = ':';
+          if (i >= buflen) {
+            return NULL;
+          }
+          continue; /* move on to next block. */
+        }
+      } else if (empty_block_flag == 1) {
+        /* move on to next block. */
+        continue;
+      }
+    } else if (empty_block_flag == 1) {
+      /* Set this flag value so we don't produce multiple empty blocks. */
+      empty_block_flag = 2;
+    }
+
+    if (current_block_index > 0) {
+      buf[i++] = ':';
+      if (i >= buflen) {
+        return NULL;
+      }
+    }
+
+    if ((current_block_value & 0xf000) == 0) {
+      zero_flag = 1;
+    } else {
+      buf[i++] = lwip_xchar(((current_block_value & 0xf000) >> 12));
+      zero_flag = 0;
+      if (i >= buflen) {
+        return NULL;
+      }
+    }
+
+    if (((current_block_value & 0xf00) == 0) && (zero_flag)) {
+      /* do nothing */
+    } else {
+      buf[i++] = lwip_xchar(((current_block_value & 0xf00) >> 8));
+      zero_flag = 0;
+      if (i >= buflen) {
+        return NULL;
+      }
+    }
+
+    if (((current_block_value & 0xf0) == 0) && (zero_flag)) {
+      /* do nothing */
+    }
+    else {
+      buf[i++] = lwip_xchar(((current_block_value & 0xf0) >> 4));
+      zero_flag = 0;
+      if (i >= buflen) {
+        return NULL;
+      }
+    }
+
+    buf[i++] = lwip_xchar((current_block_value & 0xf));
+    if (i >= buflen) {
+      return NULL;
+    }
+  }
+
+  buf[i] = 0;
+
+  return buf;
+}
+
+#endif /* LWIP_IPV6 */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/core/ipv6/ip6_frag.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/core/ipv6/ip6_frag.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/core/ipv6/ip6_frag.c	(revision 457)
@@ -0,0 +1,862 @@
+/**
+ * @file
+ *
+ * IPv6 fragmentation and reassembly.
+ */
+
+/*
+ * Copyright (c) 2010 Inico Technologies Ltd.
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Ivan Delamer <delamer@inicotech.com>
+ *
+ *
+ * Please coordinate changes and requests with Ivan Delamer
+ * <delamer@inicotech.com>
+ */
+
+#include "lwip/opt.h"
+#include "lwip/ip6_frag.h"
+#include "lwip/ip6.h"
+#include "lwip/icmp6.h"
+#include "lwip/nd6.h"
+#include "lwip/ip.h"
+
+#include "lwip/pbuf.h"
+#include "lwip/memp.h"
+#include "lwip/stats.h"
+
+#include <string.h>
+
+#if LWIP_IPV6 && LWIP_IPV6_REASS  /* don't build if not configured for use in lwipopts.h */
+
+
+/** Setting this to 0, you can turn off checking the fragments for overlapping
+ * regions. The code gets a little smaller. Only use this if you know that
+ * overlapping won't occur on your network! */
+#ifndef IP_REASS_CHECK_OVERLAP
+#define IP_REASS_CHECK_OVERLAP 1
+#endif /* IP_REASS_CHECK_OVERLAP */
+
+/** Set to 0 to prevent freeing the oldest datagram when the reassembly buffer is
+ * full (IP_REASS_MAX_PBUFS pbufs are enqueued). The code gets a little smaller.
+ * Datagrams will be freed by timeout only. Especially useful when MEMP_NUM_REASSDATA
+ * is set to 1, so one datagram can be reassembled at a time, only. */
+#ifndef IP_REASS_FREE_OLDEST
+#define IP_REASS_FREE_OLDEST 1
+#endif /* IP_REASS_FREE_OLDEST */
+
+#if IPV6_FRAG_COPYHEADER
+/* The number of bytes we need to "borrow" from (i.e., overwrite in) the header
+ * that precedes the fragment header for reassembly pruposes. */
+#define IPV6_FRAG_REQROOM ((s16_t)(sizeof(struct ip6_reass_helper) - IP6_FRAG_HLEN))
+#endif
+
+#define IP_REASS_FLAG_LASTFRAG 0x01
+
+/** This is a helper struct which holds the starting
+ * offset and the ending offset of this fragment to
+ * easily chain the fragments.
+ * It has the same packing requirements as the IPv6 header, since it replaces
+ * the Fragment Header in memory in incoming fragments to keep
+ * track of the various fragments.
+ */
+#ifdef PACK_STRUCT_USE_INCLUDES
+#  include "arch/bpstruct.h"
+#endif
+PACK_STRUCT_BEGIN
+struct ip6_reass_helper {
+  PACK_STRUCT_FIELD(struct pbuf *next_pbuf);
+  PACK_STRUCT_FIELD(u16_t start);
+  PACK_STRUCT_FIELD(u16_t end);
+} PACK_STRUCT_STRUCT;
+PACK_STRUCT_END
+#ifdef PACK_STRUCT_USE_INCLUDES
+#  include "arch/epstruct.h"
+#endif
+
+/* static variables */
+static struct ip6_reassdata *reassdatagrams;
+static u16_t ip6_reass_pbufcount;
+
+/* Forward declarations. */
+static void ip6_reass_free_complete_datagram(struct ip6_reassdata *ipr);
+#if IP_REASS_FREE_OLDEST
+static void ip6_reass_remove_oldest_datagram(struct ip6_reassdata *ipr, int pbufs_needed);
+#endif /* IP_REASS_FREE_OLDEST */
+
+void
+ip6_reass_tmr(void)
+{
+  struct ip6_reassdata *r, *tmp;
+
+#if !IPV6_FRAG_COPYHEADER
+  LWIP_ASSERT("sizeof(struct ip6_reass_helper) <= IP6_FRAG_HLEN, set IPV6_FRAG_COPYHEADER to 1",
+    sizeof(struct ip6_reass_helper) <= IP6_FRAG_HLEN);
+#endif /* !IPV6_FRAG_COPYHEADER */
+
+  r = reassdatagrams;
+  while (r != NULL) {
+    /* Decrement the timer. Once it reaches 0,
+     * clean up the incomplete fragment assembly */
+    if (r->timer > 0) {
+      r->timer--;
+      r = r->next;
+    } else {
+      /* reassembly timed out */
+      tmp = r;
+      /* get the next pointer before freeing */
+      r = r->next;
+      /* free the helper struct and all enqueued pbufs */
+      ip6_reass_free_complete_datagram(tmp);
+     }
+   }
+}
+
+/**
+ * Free a datagram (struct ip6_reassdata) and all its pbufs.
+ * Updates the total count of enqueued pbufs (ip6_reass_pbufcount),
+ * sends an ICMP time exceeded packet.
+ *
+ * @param ipr datagram to free
+ */
+static void
+ip6_reass_free_complete_datagram(struct ip6_reassdata *ipr)
+{
+  struct ip6_reassdata *prev;
+  u16_t pbufs_freed = 0;
+  u16_t clen;
+  struct pbuf *p;
+  struct ip6_reass_helper *iprh;
+
+#if LWIP_ICMP6
+  iprh = (struct ip6_reass_helper *)ipr->p->payload;
+  if (iprh->start == 0) {
+    /* The first fragment was received, send ICMP time exceeded. */
+    /* First, de-queue the first pbuf from r->p. */
+    p = ipr->p;
+    ipr->p = iprh->next_pbuf;
+    /* Restore the part that we've overwritten with our helper structure, or we
+     * might send garbage (and disclose a pointer) in the ICMPv6 reply. */
+    MEMCPY(p->payload, ipr->orig_hdr, sizeof(iprh));
+    /* Then, move back to the original ipv6 header (we are now pointing to Fragment header).
+       This cannot fail since we already checked when receiving this fragment. */
+    if (pbuf_header_force(p, (s16_t)((u8_t*)p->payload - (u8_t*)ipr->iphdr))) {
+      LWIP_ASSERT("ip6_reass_free: moving p->payload to ip6 header failed\n", 0);
+    }
+    else {
+      /* Reconstruct the zoned source and destination addresses, so that we do
+       * not end up sending the ICMP response over the wrong link. */
+      ip6_addr_t src_addr, dest_addr;
+      ip6_addr_copy_from_packed(src_addr, IPV6_FRAG_SRC(ipr));
+      ip6_addr_set_zone(&src_addr, ipr->src_zone);
+      ip6_addr_copy_from_packed(dest_addr, IPV6_FRAG_DEST(ipr));
+      ip6_addr_set_zone(&dest_addr, ipr->dest_zone);
+      /* Send the actual ICMP response. */
+      icmp6_time_exceeded_with_addrs(p, ICMP6_TE_FRAG, &src_addr, &dest_addr);
+    }
+    clen = pbuf_clen(p);
+    LWIP_ASSERT("pbufs_freed + clen <= 0xffff", pbufs_freed + clen <= 0xffff);
+    pbufs_freed = (u16_t)(pbufs_freed + clen);
+    pbuf_free(p);
+  }
+#endif /* LWIP_ICMP6 */
+
+  /* First, free all received pbufs.  The individual pbufs need to be released
+     separately as they have not yet been chained */
+  p = ipr->p;
+  while (p != NULL) {
+    struct pbuf *pcur;
+    iprh = (struct ip6_reass_helper *)p->payload;
+    pcur = p;
+    /* get the next pointer before freeing */
+    p = iprh->next_pbuf;
+    clen = pbuf_clen(pcur);
+    LWIP_ASSERT("pbufs_freed + clen <= 0xffff", pbufs_freed + clen <= 0xffff);
+    pbufs_freed = (u16_t)(pbufs_freed + clen);
+    pbuf_free(pcur);
+  }
+
+  /* Then, unchain the struct ip6_reassdata from the list and free it. */
+  if (ipr == reassdatagrams) {
+    reassdatagrams = ipr->next;
+  } else {
+    prev = reassdatagrams;
+    while (prev != NULL) {
+      if (prev->next == ipr) {
+        break;
+      }
+      prev = prev->next;
+    }
+    if (prev != NULL) {
+      prev->next = ipr->next;
+    }
+  }
+  memp_free(MEMP_IP6_REASSDATA, ipr);
+
+  /* Finally, update number of pbufs in reassembly queue */
+  LWIP_ASSERT("ip_reass_pbufcount >= clen", ip6_reass_pbufcount >= pbufs_freed);
+  ip6_reass_pbufcount = (u16_t)(ip6_reass_pbufcount - pbufs_freed);
+}
+
+#if IP_REASS_FREE_OLDEST
+/**
+ * Free the oldest datagram to make room for enqueueing new fragments.
+ * The datagram ipr is not freed!
+ *
+ * @param ipr ip6_reassdata for the current fragment
+ * @param pbufs_needed number of pbufs needed to enqueue
+ *        (used for freeing other datagrams if not enough space)
+ */
+static void
+ip6_reass_remove_oldest_datagram(struct ip6_reassdata *ipr, int pbufs_needed)
+{
+  struct ip6_reassdata *r, *oldest;
+
+  /* Free datagrams until being allowed to enqueue 'pbufs_needed' pbufs,
+   * but don't free the current datagram! */
+  do {
+    r = oldest = reassdatagrams;
+    while (r != NULL) {
+      if (r != ipr) {
+        if (r->timer <= oldest->timer) {
+          /* older than the previous oldest */
+          oldest = r;
+        }
+      }
+      r = r->next;
+    }
+    if (oldest == ipr) {
+      /* nothing to free, ipr is the only element on the list */
+      return;
+    }
+    if (oldest != NULL) {
+      ip6_reass_free_complete_datagram(oldest);
+    }
+  } while (((ip6_reass_pbufcount + pbufs_needed) > IP_REASS_MAX_PBUFS) && (reassdatagrams != NULL));
+}
+#endif /* IP_REASS_FREE_OLDEST */
+
+/**
+ * Reassembles incoming IPv6 fragments into an IPv6 datagram.
+ *
+ * @param p points to the IPv6 Fragment Header
+ * @return NULL if reassembly is incomplete, pbuf pointing to
+ *         IPv6 Header if reassembly is complete
+ */
+struct pbuf *
+ip6_reass(struct pbuf *p)
+{
+  struct ip6_reassdata *ipr, *ipr_prev;
+  struct ip6_reass_helper *iprh, *iprh_tmp, *iprh_prev=NULL;
+  struct ip6_frag_hdr *frag_hdr;
+  u16_t offset, len, start, end;
+  ptrdiff_t hdrdiff;
+  u16_t clen;
+  u8_t valid = 1;
+  struct pbuf *q, *next_pbuf;
+
+  IP6_FRAG_STATS_INC(ip6_frag.recv);
+
+  /* ip6_frag_hdr must be in the first pbuf, not chained. Checked by caller. */
+  LWIP_ASSERT("IPv6 fragment header does not fit in first pbuf",
+    p->len >= sizeof(struct ip6_frag_hdr));
+
+  frag_hdr = (struct ip6_frag_hdr *) p->payload;
+
+  clen = pbuf_clen(p);
+
+  offset = lwip_ntohs(frag_hdr->_fragment_offset);
+
+  /* Calculate fragment length from IPv6 payload length.
+   * Adjust for headers before Fragment Header.
+   * And finally adjust by Fragment Header length. */
+  len = lwip_ntohs(ip6_current_header()->_plen);
+  hdrdiff = (u8_t*)p->payload - (const u8_t*)ip6_current_header();
+  LWIP_ASSERT("not a valid pbuf (ip6_input check missing?)", hdrdiff <= 0xFFFF);
+  LWIP_ASSERT("not a valid pbuf (ip6_input check missing?)", hdrdiff >= IP6_HLEN);
+  hdrdiff -= IP6_HLEN;
+  hdrdiff += IP6_FRAG_HLEN;
+  if (hdrdiff > len) {
+    IP6_FRAG_STATS_INC(ip6_frag.proterr);
+    goto nullreturn;
+  }
+  len = (u16_t)(len - hdrdiff);
+  start = (offset & IP6_FRAG_OFFSET_MASK);
+  if (start > (0xFFFF - len)) {
+    /* u16_t overflow, cannot handle this */
+    IP6_FRAG_STATS_INC(ip6_frag.proterr);
+    goto nullreturn;
+  }
+
+  /* Look for the datagram the fragment belongs to in the current datagram queue,
+   * remembering the previous in the queue for later dequeueing. */
+  for (ipr = reassdatagrams, ipr_prev = NULL; ipr != NULL; ipr = ipr->next) {
+    /* Check if the incoming fragment matches the one currently present
+       in the reassembly buffer. If so, we proceed with copying the
+       fragment into the buffer. */
+    if ((frag_hdr->_identification == ipr->identification) &&
+        ip6_addr_cmp_packed(ip6_current_src_addr(), &(IPV6_FRAG_SRC(ipr)), ipr->src_zone) &&
+        ip6_addr_cmp_packed(ip6_current_dest_addr(), &(IPV6_FRAG_DEST(ipr)), ipr->dest_zone)) {
+      IP6_FRAG_STATS_INC(ip6_frag.cachehit);
+      break;
+    }
+    ipr_prev = ipr;
+  }
+
+  if (ipr == NULL) {
+  /* Enqueue a new datagram into the datagram queue */
+    ipr = (struct ip6_reassdata *)memp_malloc(MEMP_IP6_REASSDATA);
+    if (ipr == NULL) {
+#if IP_REASS_FREE_OLDEST
+      /* Make room and try again. */
+      ip6_reass_remove_oldest_datagram(ipr, clen);
+      ipr = (struct ip6_reassdata *)memp_malloc(MEMP_IP6_REASSDATA);
+      if (ipr != NULL) {
+        /* re-search ipr_prev since it might have been removed */
+        for (ipr_prev = reassdatagrams; ipr_prev != NULL; ipr_prev = ipr_prev->next) {
+          if (ipr_prev->next == ipr) {
+            break;
+          }
+        }
+      } else
+#endif /* IP_REASS_FREE_OLDEST */
+      {
+        IP6_FRAG_STATS_INC(ip6_frag.memerr);
+        goto nullreturn;
+      }
+    }
+
+    memset(ipr, 0, sizeof(struct ip6_reassdata));
+    ipr->timer = IPV6_REASS_MAXAGE;
+
+    /* enqueue the new structure to the front of the list */
+    ipr->next = reassdatagrams;
+    reassdatagrams = ipr;
+
+    /* Use the current IPv6 header for src/dest address reference.
+     * Eventually, we will replace it when we get the first fragment
+     * (it might be this one, in any case, it is done later). */
+    /* need to use the none-const pointer here: */
+    ipr->iphdr = ip_data.current_ip6_header;
+#if IPV6_FRAG_COPYHEADER
+    MEMCPY(&ipr->src, &ip6_current_header()->src, sizeof(ipr->src));
+    MEMCPY(&ipr->dest, &ip6_current_header()->dest, sizeof(ipr->dest));
+#endif /* IPV6_FRAG_COPYHEADER */
+#if LWIP_IPV6_SCOPES
+    /* Also store the address zone information.
+     * @todo It is possible that due to netif destruction and recreation, the
+     * stored zones end up resolving to a different interface. In that case, we
+     * risk sending a "time exceeded" ICMP response over the wrong link.
+     * Ideally, netif destruction would clean up matching pending reassembly
+     * structures, but custom zone mappings would make that non-trivial. */
+    ipr->src_zone = ip6_addr_zone(ip6_current_src_addr());
+    ipr->dest_zone = ip6_addr_zone(ip6_current_dest_addr());
+#endif /* LWIP_IPV6_SCOPES */
+    /* copy the fragmented packet id. */
+    ipr->identification = frag_hdr->_identification;
+
+    /* copy the nexth field */
+    ipr->nexth = frag_hdr->_nexth;
+  }
+
+  /* Check if we are allowed to enqueue more datagrams. */
+  if ((ip6_reass_pbufcount + clen) > IP_REASS_MAX_PBUFS) {
+#if IP_REASS_FREE_OLDEST
+    ip6_reass_remove_oldest_datagram(ipr, clen);
+    if ((ip6_reass_pbufcount + clen) <= IP_REASS_MAX_PBUFS) {
+      /* re-search ipr_prev since it might have been removed */
+      for (ipr_prev = reassdatagrams; ipr_prev != NULL; ipr_prev = ipr_prev->next) {
+        if (ipr_prev->next == ipr) {
+          break;
+        }
+      }
+    } else
+#endif /* IP_REASS_FREE_OLDEST */
+    {
+      /* @todo: send ICMPv6 time exceeded here? */
+      /* drop this pbuf */
+      IP6_FRAG_STATS_INC(ip6_frag.memerr);
+      goto nullreturn;
+    }
+  }
+
+  /* Overwrite Fragment Header with our own helper struct. */
+#if IPV6_FRAG_COPYHEADER
+  if (IPV6_FRAG_REQROOM > 0) {
+    /* Make room for struct ip6_reass_helper (only required if sizeof(void*) > 4).
+       This cannot fail since we already checked when receiving this fragment. */
+    u8_t hdrerr = pbuf_header_force(p, IPV6_FRAG_REQROOM);
+    LWIP_UNUSED_ARG(hdrerr); /* in case of LWIP_NOASSERT */
+    LWIP_ASSERT("no room for struct ip6_reass_helper", hdrerr == 0);
+  }
+#else /* IPV6_FRAG_COPYHEADER */
+  LWIP_ASSERT("sizeof(struct ip6_reass_helper) <= IP6_FRAG_HLEN, set IPV6_FRAG_COPYHEADER to 1",
+    sizeof(struct ip6_reass_helper) <= IP6_FRAG_HLEN);
+#endif /* IPV6_FRAG_COPYHEADER */
+
+  /* Prepare the pointer to the helper structure, and its initial values.
+   * Do not yet write to the structure itself, as we still have to make a
+   * backup of the original data, and we should not do that until we know for
+   * sure that we are going to add this packet to the list. */
+  iprh = (struct ip6_reass_helper *)p->payload;
+  next_pbuf = NULL;
+  end = (u16_t)(start + len);
+
+  /* find the right place to insert this pbuf */
+  /* Iterate through until we either get to the end of the list (append),
+   * or we find on with a larger offset (insert). */
+  for (q = ipr->p; q != NULL;) {
+    iprh_tmp = (struct ip6_reass_helper*)q->payload;
+    if (start < iprh_tmp->start) {
+#if IP_REASS_CHECK_OVERLAP
+      if (end > iprh_tmp->start) {
+        /* fragment overlaps with following, throw away */
+        IP6_FRAG_STATS_INC(ip6_frag.proterr);
+        goto nullreturn;
+      }
+      if (iprh_prev != NULL) {
+        if (start < iprh_prev->end) {
+          /* fragment overlaps with previous, throw away */
+          IP6_FRAG_STATS_INC(ip6_frag.proterr);
+          goto nullreturn;
+        }
+      }
+#endif /* IP_REASS_CHECK_OVERLAP */
+      /* the new pbuf should be inserted before this */
+      next_pbuf = q;
+      if (iprh_prev != NULL) {
+        /* not the fragment with the lowest offset */
+        iprh_prev->next_pbuf = p;
+      } else {
+        /* fragment with the lowest offset */
+        ipr->p = p;
+      }
+      break;
+    } else if (start == iprh_tmp->start) {
+      /* received the same datagram twice: no need to keep the datagram */
+      goto nullreturn;
+#if IP_REASS_CHECK_OVERLAP
+    } else if (start < iprh_tmp->end) {
+      /* overlap: no need to keep the new datagram */
+      IP6_FRAG_STATS_INC(ip6_frag.proterr);
+      goto nullreturn;
+#endif /* IP_REASS_CHECK_OVERLAP */
+    } else {
+      /* Check if the fragments received so far have no gaps. */
+      if (iprh_prev != NULL) {
+        if (iprh_prev->end != iprh_tmp->start) {
+          /* There is a fragment missing between the current
+           * and the previous fragment */
+          valid = 0;
+        }
+      }
+    }
+    q = iprh_tmp->next_pbuf;
+    iprh_prev = iprh_tmp;
+  }
+
+  /* If q is NULL, then we made it to the end of the list. Determine what to do now */
+  if (q == NULL) {
+    if (iprh_prev != NULL) {
+      /* this is (for now), the fragment with the highest offset:
+       * chain it to the last fragment */
+#if IP_REASS_CHECK_OVERLAP
+      LWIP_ASSERT("check fragments don't overlap", iprh_prev->end <= start);
+#endif /* IP_REASS_CHECK_OVERLAP */
+      iprh_prev->next_pbuf = p;
+      if (iprh_prev->end != start) {
+        valid = 0;
+      }
+    } else {
+#if IP_REASS_CHECK_OVERLAP
+      LWIP_ASSERT("no previous fragment, this must be the first fragment!",
+        ipr->p == NULL);
+#endif /* IP_REASS_CHECK_OVERLAP */
+      /* this is the first fragment we ever received for this ip datagram */
+      ipr->p = p;
+    }
+  }
+
+  /* Track the current number of pbufs current 'in-flight', in order to limit
+  the number of fragments that may be enqueued at any one time */
+  ip6_reass_pbufcount = (u16_t)(ip6_reass_pbufcount + clen);
+
+  /* Remember IPv6 header if this is the first fragment. */
+  if (start == 0) {
+    /* need to use the none-const pointer here: */
+    ipr->iphdr = ip_data.current_ip6_header;
+    /* Make a backup of the part of the packet data that we are about to
+     * overwrite, so that we can restore the original later. */
+    MEMCPY(ipr->orig_hdr, p->payload, sizeof(*iprh));
+    /* For IPV6_FRAG_COPYHEADER there is no need to copy src/dst again, as they
+     * will be the same as they were. With LWIP_IPV6_SCOPES, the same applies
+     * to the source/destination zones. */
+  }
+  /* Only after the backup do we get to fill in the actual helper structure. */
+  iprh->next_pbuf = next_pbuf;
+  iprh->start = start;
+  iprh->end = end;
+
+  /* If this is the last fragment, calculate total packet length. */
+  if ((offset & IP6_FRAG_MORE_FLAG) == 0) {
+    ipr->datagram_len = iprh->end;
+  }
+
+  /* Additional validity tests: we have received first and last fragment. */
+  iprh_tmp = (struct ip6_reass_helper*)ipr->p->payload;
+  if (iprh_tmp->start != 0) {
+    valid = 0;
+  }
+  if (ipr->datagram_len == 0) {
+    valid = 0;
+  }
+
+  /* Final validity test: no gaps between current and last fragment. */
+  iprh_prev = iprh;
+  q = iprh->next_pbuf;
+  while ((q != NULL) && valid) {
+    iprh = (struct ip6_reass_helper*)q->payload;
+    if (iprh_prev->end != iprh->start) {
+      valid = 0;
+      break;
+    }
+    iprh_prev = iprh;
+    q = iprh->next_pbuf;
+  }
+
+  if (valid) {
+    /* All fragments have been received */
+    struct ip6_hdr* iphdr_ptr;
+
+    /* chain together the pbufs contained within the ip6_reassdata list. */
+    iprh = (struct ip6_reass_helper*) ipr->p->payload;
+    while (iprh != NULL) {
+      next_pbuf = iprh->next_pbuf;
+      if (next_pbuf != NULL) {
+        /* Save next helper struct (will be hidden in next step). */
+        iprh_tmp = (struct ip6_reass_helper*)next_pbuf->payload;
+
+        /* hide the fragment header for every succeeding fragment */
+        pbuf_remove_header(next_pbuf, IP6_FRAG_HLEN);
+#if IPV6_FRAG_COPYHEADER
+        if (IPV6_FRAG_REQROOM > 0) {
+          /* hide the extra bytes borrowed from ip6_hdr for struct ip6_reass_helper */
+          u8_t hdrerr = pbuf_remove_header(next_pbuf, IPV6_FRAG_REQROOM);
+          LWIP_UNUSED_ARG(hdrerr); /* in case of LWIP_NOASSERT */
+          LWIP_ASSERT("no room for struct ip6_reass_helper", hdrerr == 0);
+        }
+#endif
+        pbuf_cat(ipr->p, next_pbuf);
+      }
+      else {
+        iprh_tmp = NULL;
+      }
+
+      iprh = iprh_tmp;
+    }
+
+    /* Get the first pbuf. */
+    p = ipr->p;
+
+#if IPV6_FRAG_COPYHEADER
+    if (IPV6_FRAG_REQROOM > 0) {
+      u8_t hdrerr;
+      /* Restore (only) the bytes that we overwrote beyond the fragment header.
+       * Those bytes may belong to either the IPv6 header or an extension
+       * header placed before the fragment header. */
+      MEMCPY(p->payload, ipr->orig_hdr, IPV6_FRAG_REQROOM);
+      /* get back room for struct ip6_reass_helper (only required if sizeof(void*) > 4) */
+      hdrerr = pbuf_remove_header(p, IPV6_FRAG_REQROOM);
+      LWIP_UNUSED_ARG(hdrerr); /* in case of LWIP_NOASSERT */
+      LWIP_ASSERT("no room for struct ip6_reass_helper", hdrerr == 0);
+    }
+#endif
+
+    /* We need to get rid of the fragment header itself, which is somewhere in
+     * the middle of the packet (but still in the first pbuf of the chain).
+     * Getting rid of the header is required by RFC 2460 Sec. 4.5 and necessary
+     * in order to be able to reassemble packets that are close to full size
+     * (i.e., around 65535 bytes). We simply move up all the headers before the
+     * fragment header, including the IPv6 header, and adjust the payload start
+     * accordingly. This works because all these headers are in the first pbuf
+     * of the chain, and because the caller adjusts all its pointers on
+     * successful reassembly. */
+    MEMMOVE((u8_t*)ipr->iphdr + sizeof(struct ip6_frag_hdr), ipr->iphdr,
+      (size_t)((u8_t*)p->payload - (u8_t*)ipr->iphdr));
+
+    /* This is where the IPv6 header is now. */
+    iphdr_ptr = (struct ip6_hdr*)((u8_t*)ipr->iphdr +
+      sizeof(struct ip6_frag_hdr));
+
+    /* Adjust datagram length by adding header lengths. */
+    ipr->datagram_len = (u16_t)(ipr->datagram_len + ((u8_t*)p->payload - (u8_t*)iphdr_ptr)
+                         - IP6_HLEN);
+
+    /* Set payload length in ip header. */
+    iphdr_ptr->_plen = lwip_htons(ipr->datagram_len);
+
+    /* With the fragment header gone, we now need to adjust the next-header
+     * field of whatever header was originally before it. Since the packet made
+     * it through the original header processing routines at least up to the
+     * fragment header, we do not need any further sanity checks here. */
+    if (IP6H_NEXTH(iphdr_ptr) == IP6_NEXTH_FRAGMENT) {
+      iphdr_ptr->_nexth = ipr->nexth;
+    } else {
+      u8_t *ptr = (u8_t *)iphdr_ptr + IP6_HLEN;
+      while (*ptr != IP6_NEXTH_FRAGMENT) {
+        ptr += 8 * (1 + ptr[1]);
+      }
+      *ptr = ipr->nexth;
+    }
+
+    /* release the resources allocated for the fragment queue entry */
+    if (reassdatagrams == ipr) {
+      /* it was the first in the list */
+      reassdatagrams = ipr->next;
+    } else {
+      /* it wasn't the first, so it must have a valid 'prev' */
+      LWIP_ASSERT("sanity check linked list", ipr_prev != NULL);
+      ipr_prev->next = ipr->next;
+    }
+    memp_free(MEMP_IP6_REASSDATA, ipr);
+
+    /* adjust the number of pbufs currently queued for reassembly. */
+    clen = pbuf_clen(p);
+    LWIP_ASSERT("ip6_reass_pbufcount >= clen", ip6_reass_pbufcount >= clen);
+    ip6_reass_pbufcount = (u16_t)(ip6_reass_pbufcount - clen);
+
+    /* Move pbuf back to IPv6 header. This should never fail. */
+    if (pbuf_header_force(p, (s16_t)((u8_t*)p->payload - (u8_t*)iphdr_ptr))) {
+      LWIP_ASSERT("ip6_reass: moving p->payload to ip6 header failed\n", 0);
+      pbuf_free(p);
+      return NULL;
+    }
+
+    /* Return the pbuf chain */
+    return p;
+  }
+  /* the datagram is not (yet?) reassembled completely */
+  return NULL;
+
+nullreturn:
+  IP6_FRAG_STATS_INC(ip6_frag.drop);
+  pbuf_free(p);
+  return NULL;
+}
+
+#endif /* LWIP_IPV6 && LWIP_IPV6_REASS */
+
+#if LWIP_IPV6 && LWIP_IPV6_FRAG
+
+#if !LWIP_NETIF_TX_SINGLE_PBUF
+/** Allocate a new struct pbuf_custom_ref */
+static struct pbuf_custom_ref*
+ip6_frag_alloc_pbuf_custom_ref(void)
+{
+  return (struct pbuf_custom_ref*)memp_malloc(MEMP_FRAG_PBUF);
+}
+
+/** Free a struct pbuf_custom_ref */
+static void
+ip6_frag_free_pbuf_custom_ref(struct pbuf_custom_ref* p)
+{
+  LWIP_ASSERT("p != NULL", p != NULL);
+  memp_free(MEMP_FRAG_PBUF, p);
+}
+
+/** Free-callback function to free a 'struct pbuf_custom_ref', called by
+ * pbuf_free. */
+static void
+ip6_frag_free_pbuf_custom(struct pbuf *p)
+{
+  struct pbuf_custom_ref *pcr = (struct pbuf_custom_ref*)p;
+  LWIP_ASSERT("pcr != NULL", pcr != NULL);
+  LWIP_ASSERT("pcr == p", (void*)pcr == (void*)p);
+  if (pcr->original != NULL) {
+    pbuf_free(pcr->original);
+  }
+  ip6_frag_free_pbuf_custom_ref(pcr);
+}
+#endif /* !LWIP_NETIF_TX_SINGLE_PBUF */
+
+/**
+ * Fragment an IPv6 datagram if too large for the netif or path MTU.
+ *
+ * Chop the datagram in MTU sized chunks and send them in order
+ * by pointing PBUF_REFs into p
+ *
+ * @param p ipv6 packet to send
+ * @param netif the netif on which to send
+ * @param dest destination ipv6 address to which to send
+ *
+ * @return ERR_OK if sent successfully, err_t otherwise
+ */
+err_t
+ip6_frag(struct pbuf *p, struct netif *netif, const ip6_addr_t *dest)
+{
+  struct ip6_hdr *original_ip6hdr;
+  struct ip6_hdr *ip6hdr;
+  struct ip6_frag_hdr *frag_hdr;
+  struct pbuf *rambuf;
+#if !LWIP_NETIF_TX_SINGLE_PBUF
+  struct pbuf *newpbuf;
+  u16_t newpbuflen = 0;
+  u16_t left_to_copy;
+#endif
+  static u32_t identification;
+  u16_t left, cop;
+  const u16_t mtu = nd6_get_destination_mtu(dest, netif);
+  const u16_t nfb = (u16_t)((mtu - (IP6_HLEN + IP6_FRAG_HLEN)) & IP6_FRAG_OFFSET_MASK);
+  u16_t fragment_offset = 0;
+  u16_t last;
+  u16_t poff = IP6_HLEN;
+
+  identification++;
+
+  original_ip6hdr = (struct ip6_hdr *)p->payload;
+
+  /* @todo we assume there are no options in the unfragmentable part (IPv6 header). */
+  LWIP_ASSERT("p->tot_len >= IP6_HLEN", p->tot_len >= IP6_HLEN);
+  left = (u16_t)(p->tot_len - IP6_HLEN);
+
+  while (left) {
+    last = (left <= nfb);
+
+    /* Fill this fragment */
+    cop = last ? left : nfb;
+
+#if LWIP_NETIF_TX_SINGLE_PBUF
+    rambuf = pbuf_alloc(PBUF_IP, cop + IP6_FRAG_HLEN, PBUF_RAM);
+    if (rambuf == NULL) {
+      IP6_FRAG_STATS_INC(ip6_frag.memerr);
+      return ERR_MEM;
+    }
+    LWIP_ASSERT("this needs a pbuf in one piece!",
+      (rambuf->len == rambuf->tot_len) && (rambuf->next == NULL));
+    poff += pbuf_copy_partial(p, (u8_t*)rambuf->payload + IP6_FRAG_HLEN, cop, poff);
+    /* make room for the IP header */
+    if (pbuf_add_header(rambuf, IP6_HLEN)) {
+      pbuf_free(rambuf);
+      IP6_FRAG_STATS_INC(ip6_frag.memerr);
+      return ERR_MEM;
+    }
+    /* fill in the IP header */
+    SMEMCPY(rambuf->payload, original_ip6hdr, IP6_HLEN);
+    ip6hdr = (struct ip6_hdr *)rambuf->payload;
+    frag_hdr = (struct ip6_frag_hdr *)((u8_t*)rambuf->payload + IP6_HLEN);
+#else
+    /* When not using a static buffer, create a chain of pbufs.
+     * The first will be a PBUF_RAM holding the link, IPv6, and Fragment header.
+     * The rest will be PBUF_REFs mirroring the pbuf chain to be fragged,
+     * but limited to the size of an mtu.
+     */
+    rambuf = pbuf_alloc(PBUF_LINK, IP6_HLEN + IP6_FRAG_HLEN, PBUF_RAM);
+    if (rambuf == NULL) {
+      IP6_FRAG_STATS_INC(ip6_frag.memerr);
+      return ERR_MEM;
+    }
+    LWIP_ASSERT("this needs a pbuf in one piece!",
+                (p->len >= (IP6_HLEN)));
+    SMEMCPY(rambuf->payload, original_ip6hdr, IP6_HLEN);
+    ip6hdr = (struct ip6_hdr *)rambuf->payload;
+    frag_hdr = (struct ip6_frag_hdr *)((u8_t*)rambuf->payload + IP6_HLEN);
+
+    /* Can just adjust p directly for needed offset. */
+    p->payload = (u8_t *)p->payload + poff;
+    p->len = (u16_t)(p->len - poff);
+    p->tot_len = (u16_t)(p->tot_len - poff);
+
+    left_to_copy = cop;
+    while (left_to_copy) {
+      struct pbuf_custom_ref *pcr;
+      newpbuflen = (left_to_copy < p->len) ? left_to_copy : p->len;
+      /* Is this pbuf already empty? */
+      if (!newpbuflen) {
+        p = p->next;
+        continue;
+      }
+      pcr = ip6_frag_alloc_pbuf_custom_ref();
+      if (pcr == NULL) {
+        pbuf_free(rambuf);
+        IP6_FRAG_STATS_INC(ip6_frag.memerr);
+        return ERR_MEM;
+      }
+      /* Mirror this pbuf, although we might not need all of it. */
+      newpbuf = pbuf_alloced_custom(PBUF_RAW, newpbuflen, PBUF_REF, &pcr->pc, p->payload, newpbuflen);
+      if (newpbuf == NULL) {
+        ip6_frag_free_pbuf_custom_ref(pcr);
+        pbuf_free(rambuf);
+        IP6_FRAG_STATS_INC(ip6_frag.memerr);
+        return ERR_MEM;
+      }
+      pbuf_ref(p);
+      pcr->original = p;
+      pcr->pc.custom_free_function = ip6_frag_free_pbuf_custom;
+
+      /* Add it to end of rambuf's chain, but using pbuf_cat, not pbuf_chain
+       * so that it is removed when pbuf_dechain is later called on rambuf.
+       */
+      pbuf_cat(rambuf, newpbuf);
+      left_to_copy = (u16_t)(left_to_copy - newpbuflen);
+      if (left_to_copy) {
+        p = p->next;
+      }
+    }
+    poff = newpbuflen;
+#endif /* LWIP_NETIF_TX_SINGLE_PBUF */
+
+    /* Set headers */
+    frag_hdr->_nexth = original_ip6hdr->_nexth;
+    frag_hdr->reserved = 0;
+    frag_hdr->_fragment_offset = lwip_htons((u16_t)((fragment_offset & IP6_FRAG_OFFSET_MASK) | (last ? 0 : IP6_FRAG_MORE_FLAG)));
+    frag_hdr->_identification = lwip_htonl(identification);
+
+    IP6H_NEXTH_SET(ip6hdr, IP6_NEXTH_FRAGMENT);
+    IP6H_PLEN_SET(ip6hdr, (u16_t)(cop + IP6_FRAG_HLEN));
+
+    /* No need for separate header pbuf - we allowed room for it in rambuf
+     * when allocated.
+     */
+    IP6_FRAG_STATS_INC(ip6_frag.xmit);
+    netif->output_ip6(netif, rambuf, dest);
+
+    /* Unfortunately we can't reuse rambuf - the hardware may still be
+     * using the buffer. Instead we free it (and the ensuing chain) and
+     * recreate it next time round the loop. If we're lucky the hardware
+     * will have already sent the packet, the free will really free, and
+     * there will be zero memory penalty.
+     */
+
+    pbuf_free(rambuf);
+    left = (u16_t)(left - cop);
+    fragment_offset = (u16_t)(fragment_offset + cop);
+  }
+  return ERR_OK;
+}
+
+#endif /* LWIP_IPV6 && LWIP_IPV6_FRAG */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/core/ipv6/mld6.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/core/ipv6/mld6.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/core/ipv6/mld6.c	(revision 457)
@@ -0,0 +1,626 @@
+/**
+ * @file
+ * Multicast listener discovery
+ *
+ * @defgroup mld6 MLD6
+ * @ingroup ip6
+ * Multicast listener discovery for IPv6. Aims to be compliant with RFC 2710.
+ * No support for MLDv2.\n
+ * Note: The allnodes (ff01::1, ff02::1) group is assumed be received by your 
+ * netif since it must always be received for correct IPv6 operation (e.g. SLAAC).
+ * Ensure the netif filters are configured accordingly!\n
+ * The netif flags also need NETIF_FLAG_MLD6 flag set to enable MLD6 on a
+ * netif ("netif->flags |= NETIF_FLAG_MLD6;").\n
+ * To be called from TCPIP thread.
+ */
+
+/*
+ * Copyright (c) 2010 Inico Technologies Ltd.
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Ivan Delamer <delamer@inicotech.com>
+ *
+ *
+ * Please coordinate changes and requests with Ivan Delamer
+ * <delamer@inicotech.com>
+ */
+
+/* Based on igmp.c implementation of igmp v2 protocol */
+
+#include "lwip/opt.h"
+
+#if LWIP_IPV6 && LWIP_IPV6_MLD  /* don't build if not configured for use in lwipopts.h */
+
+#include "lwip/mld6.h"
+#include "lwip/prot/mld6.h"
+#include "lwip/icmp6.h"
+#include "lwip/ip6.h"
+#include "lwip/ip6_addr.h"
+#include "lwip/ip.h"
+#include "lwip/inet_chksum.h"
+#include "lwip/pbuf.h"
+#include "lwip/netif.h"
+#include "lwip/memp.h"
+#include "lwip/stats.h"
+
+#include <string.h>
+
+
+/*
+ * MLD constants
+ */
+#define MLD6_HL                           1
+#define MLD6_JOIN_DELAYING_MEMBER_TMR_MS  (500)
+
+#define MLD6_GROUP_NON_MEMBER             0
+#define MLD6_GROUP_DELAYING_MEMBER        1
+#define MLD6_GROUP_IDLE_MEMBER            2
+
+/* Forward declarations. */
+static struct mld_group *mld6_new_group(struct netif *ifp, const ip6_addr_t *addr);
+static err_t mld6_remove_group(struct netif *netif, struct mld_group *group);
+static void mld6_delayed_report(struct mld_group *group, u16_t maxresp);
+static void mld6_send(struct netif *netif, struct mld_group *group, u8_t type);
+
+
+/**
+ * Stop MLD processing on interface
+ *
+ * @param netif network interface on which stop MLD processing
+ */
+err_t
+mld6_stop(struct netif *netif)
+{
+  struct mld_group *group = netif_mld6_data(netif);
+
+  netif_set_client_data(netif, LWIP_NETIF_CLIENT_DATA_INDEX_MLD6, NULL);
+
+  while (group != NULL) {
+    struct mld_group *next = group->next; /* avoid use-after-free below */
+
+    /* disable the group at the MAC level */
+    if (netif->mld_mac_filter != NULL) {
+      netif->mld_mac_filter(netif, &(group->group_address), NETIF_DEL_MAC_FILTER);
+    }
+
+    /* free group */
+    memp_free(MEMP_MLD6_GROUP, group);
+
+    /* move to "next" */
+    group = next;
+  }
+  return ERR_OK;
+}
+
+/**
+ * Report MLD memberships for this interface
+ *
+ * @param netif network interface on which report MLD memberships
+ */
+void
+mld6_report_groups(struct netif *netif)
+{
+  struct mld_group *group = netif_mld6_data(netif);
+
+  while (group != NULL) {
+    mld6_delayed_report(group, MLD6_JOIN_DELAYING_MEMBER_TMR_MS);
+    group = group->next;
+  }
+}
+
+/**
+ * Search for a group that is joined on a netif
+ *
+ * @param ifp the network interface for which to look
+ * @param addr the group ipv6 address to search for
+ * @return a struct mld_group* if the group has been found,
+ *         NULL if the group wasn't found.
+ */
+struct mld_group *
+mld6_lookfor_group(struct netif *ifp, const ip6_addr_t *addr)
+{
+  struct mld_group *group = netif_mld6_data(ifp);
+
+  while (group != NULL) {
+    if (ip6_addr_cmp(&(group->group_address), addr)) {
+      return group;
+    }
+    group = group->next;
+  }
+
+  return NULL;
+}
+
+
+/**
+ * create a new group
+ *
+ * @param ifp the network interface for which to create
+ * @param addr the new group ipv6
+ * @return a struct mld_group*,
+ *         NULL on memory error.
+ */
+static struct mld_group *
+mld6_new_group(struct netif *ifp, const ip6_addr_t *addr)
+{
+  struct mld_group *group;
+
+  group = (struct mld_group *)memp_malloc(MEMP_MLD6_GROUP);
+  if (group != NULL) {
+    ip6_addr_set(&(group->group_address), addr);
+    group->timer              = 0; /* Not running */
+    group->group_state        = MLD6_GROUP_IDLE_MEMBER;
+    group->last_reporter_flag = 0;
+    group->use                = 0;
+    group->next               = netif_mld6_data(ifp);
+
+    netif_set_client_data(ifp, LWIP_NETIF_CLIENT_DATA_INDEX_MLD6, group);
+  }
+
+  return group;
+}
+
+/**
+ * Remove a group from the mld_group_list, but do not free it yet
+ *
+ * @param group the group to remove
+ * @return ERR_OK if group was removed from the list, an err_t otherwise
+ */
+static err_t
+mld6_remove_group(struct netif *netif, struct mld_group *group)
+{
+  err_t err = ERR_OK;
+
+  /* Is it the first group? */
+  if (netif_mld6_data(netif) == group) {
+    netif_set_client_data(netif, LWIP_NETIF_CLIENT_DATA_INDEX_MLD6, group->next);
+  } else {
+    /* look for group further down the list */
+    struct mld_group *tmpGroup;
+    for (tmpGroup = netif_mld6_data(netif); tmpGroup != NULL; tmpGroup = tmpGroup->next) {
+      if (tmpGroup->next == group) {
+        tmpGroup->next = group->next;
+        break;
+      }
+    }
+    /* Group not find group */
+    if (tmpGroup == NULL) {
+      err = ERR_ARG;
+    }
+  }
+
+  return err;
+}
+
+
+/**
+ * Process an input MLD message. Called by icmp6_input.
+ *
+ * @param p the mld packet, p->payload pointing to the icmpv6 header
+ * @param inp the netif on which this packet was received
+ */
+void
+mld6_input(struct pbuf *p, struct netif *inp)
+{
+  struct mld_header *mld_hdr;
+  struct mld_group *group;
+
+  MLD6_STATS_INC(mld6.recv);
+
+  /* Check that mld header fits in packet. */
+  if (p->len < sizeof(struct mld_header)) {
+    /* @todo debug message */
+    pbuf_free(p);
+    MLD6_STATS_INC(mld6.lenerr);
+    MLD6_STATS_INC(mld6.drop);
+    return;
+  }
+
+  mld_hdr = (struct mld_header *)p->payload;
+
+  switch (mld_hdr->type) {
+  case ICMP6_TYPE_MLQ: /* Multicast listener query. */
+    /* Is it a general query? */
+    if (ip6_addr_isallnodes_linklocal(ip6_current_dest_addr()) &&
+        ip6_addr_isany(&(mld_hdr->multicast_address))) {
+      MLD6_STATS_INC(mld6.rx_general);
+      /* Report all groups, except all nodes group, and if-local groups. */
+      group = netif_mld6_data(inp);
+      while (group != NULL) {
+        if ((!(ip6_addr_ismulticast_iflocal(&(group->group_address)))) &&
+            (!(ip6_addr_isallnodes_linklocal(&(group->group_address))))) {
+          mld6_delayed_report(group, mld_hdr->max_resp_delay);
+        }
+        group = group->next;
+      }
+    } else {
+      /* Have we joined this group?
+       * We use IP6 destination address to have a memory aligned copy.
+       * mld_hdr->multicast_address should be the same. */
+      MLD6_STATS_INC(mld6.rx_group);
+      group = mld6_lookfor_group(inp, ip6_current_dest_addr());
+      if (group != NULL) {
+        /* Schedule a report. */
+        mld6_delayed_report(group, mld_hdr->max_resp_delay);
+      }
+    }
+    break; /* ICMP6_TYPE_MLQ */
+  case ICMP6_TYPE_MLR: /* Multicast listener report. */
+    /* Have we joined this group?
+     * We use IP6 destination address to have a memory aligned copy.
+     * mld_hdr->multicast_address should be the same. */
+    MLD6_STATS_INC(mld6.rx_report);
+    group = mld6_lookfor_group(inp, ip6_current_dest_addr());
+    if (group != NULL) {
+      /* If we are waiting to report, cancel it. */
+      if (group->group_state == MLD6_GROUP_DELAYING_MEMBER) {
+        group->timer = 0; /* stopped */
+        group->group_state = MLD6_GROUP_IDLE_MEMBER;
+        group->last_reporter_flag = 0;
+      }
+    }
+    break; /* ICMP6_TYPE_MLR */
+  case ICMP6_TYPE_MLD: /* Multicast listener done. */
+    /* Do nothing, router will query us. */
+    break; /* ICMP6_TYPE_MLD */
+  default:
+    MLD6_STATS_INC(mld6.proterr);
+    MLD6_STATS_INC(mld6.drop);
+    break;
+  }
+
+  pbuf_free(p);
+}
+
+/**
+ * @ingroup mld6
+ * Join a group on one or all network interfaces.
+ *
+ * If the group is to be joined on all interfaces, the given group address must
+ * not have a zone set (i.e., it must have its zone index set to IP6_NO_ZONE).
+ * If the group is to be joined on one particular interface, the given group
+ * address may or may not have a zone set.
+ *
+ * @param srcaddr ipv6 address (zoned) of the network interface which should
+ *                join a new group. If IP6_ADDR_ANY6, join on all netifs
+ * @param groupaddr the ipv6 address of the group to join (possibly but not
+ *                  necessarily zoned)
+ * @return ERR_OK if group was joined on the netif(s), an err_t otherwise
+ */
+err_t
+mld6_joingroup(const ip6_addr_t *srcaddr, const ip6_addr_t *groupaddr)
+{
+  err_t         err = ERR_VAL; /* no matching interface */
+  struct netif *netif;
+
+  LWIP_ASSERT_CORE_LOCKED();
+
+  /* loop through netif's */
+  NETIF_FOREACH(netif) {
+    /* Should we join this interface ? */
+    if (ip6_addr_isany(srcaddr) ||
+        netif_get_ip6_addr_match(netif, srcaddr) >= 0) {
+      err = mld6_joingroup_netif(netif, groupaddr);
+      if (err != ERR_OK) {
+        return err;
+      }
+    }
+  }
+
+  return err;
+}
+
+/**
+ * @ingroup mld6
+ * Join a group on a network interface.
+ *
+ * @param netif the network interface which should join a new group.
+ * @param groupaddr the ipv6 address of the group to join (possibly but not
+ *                  necessarily zoned)
+ * @return ERR_OK if group was joined on the netif, an err_t otherwise
+ */
+err_t
+mld6_joingroup_netif(struct netif *netif, const ip6_addr_t *groupaddr)
+{
+  struct mld_group *group;
+#if LWIP_IPV6_SCOPES
+  ip6_addr_t ip6addr;
+
+  /* If the address has a particular scope but no zone set, use the netif to
+   * set one now. Within the mld6 module, all addresses are properly zoned. */
+  if (ip6_addr_lacks_zone(groupaddr, IP6_MULTICAST)) {
+    ip6_addr_set(&ip6addr, groupaddr);
+    ip6_addr_assign_zone(&ip6addr, IP6_MULTICAST, netif);
+    groupaddr = &ip6addr;
+  }
+  IP6_ADDR_ZONECHECK_NETIF(groupaddr, netif);
+#endif /* LWIP_IPV6_SCOPES */
+
+  LWIP_ASSERT_CORE_LOCKED();
+
+  /* find group or create a new one if not found */
+  group = mld6_lookfor_group(netif, groupaddr);
+
+  if (group == NULL) {
+    /* Joining a new group. Create a new group entry. */
+    group = mld6_new_group(netif, groupaddr);
+    if (group == NULL) {
+      return ERR_MEM;
+    }
+
+    /* Activate this address on the MAC layer. */
+    if (netif->mld_mac_filter != NULL) {
+      netif->mld_mac_filter(netif, groupaddr, NETIF_ADD_MAC_FILTER);
+    }
+
+    /* Report our membership. */
+    MLD6_STATS_INC(mld6.tx_report);
+    mld6_send(netif, group, ICMP6_TYPE_MLR);
+    mld6_delayed_report(group, MLD6_JOIN_DELAYING_MEMBER_TMR_MS);
+  }
+
+  /* Increment group use */
+  group->use++;
+  return ERR_OK;
+}
+
+/**
+ * @ingroup mld6
+ * Leave a group on a network interface.
+ *
+ * Zoning of address follows the same rules as @ref mld6_joingroup.
+ *
+ * @param srcaddr ipv6 address (zoned) of the network interface which should
+ *                leave the group. If IP6_ADDR_ANY6, leave on all netifs
+ * @param groupaddr the ipv6 address of the group to leave (possibly, but not
+ *                  necessarily zoned)
+ * @return ERR_OK if group was left on the netif(s), an err_t otherwise
+ */
+err_t
+mld6_leavegroup(const ip6_addr_t *srcaddr, const ip6_addr_t *groupaddr)
+{
+  err_t         err = ERR_VAL; /* no matching interface */
+  struct netif *netif;
+
+  LWIP_ASSERT_CORE_LOCKED();
+
+  /* loop through netif's */
+  NETIF_FOREACH(netif) {
+    /* Should we leave this interface ? */
+    if (ip6_addr_isany(srcaddr) ||
+        netif_get_ip6_addr_match(netif, srcaddr) >= 0) {
+      err_t res = mld6_leavegroup_netif(netif, groupaddr);
+      if (err != ERR_OK) {
+        /* Store this result if we have not yet gotten a success */
+        err = res;
+      }
+    }
+  }
+
+  return err;
+}
+
+/**
+ * @ingroup mld6
+ * Leave a group on a network interface.
+ *
+ * @param netif the network interface which should leave the group.
+ * @param groupaddr the ipv6 address of the group to leave (possibly, but not
+ *                  necessarily zoned)
+ * @return ERR_OK if group was left on the netif, an err_t otherwise
+ */
+err_t
+mld6_leavegroup_netif(struct netif *netif, const ip6_addr_t *groupaddr)
+{
+  struct mld_group *group;
+#if LWIP_IPV6_SCOPES
+  ip6_addr_t ip6addr;
+
+  if (ip6_addr_lacks_zone(groupaddr, IP6_MULTICAST)) {
+    ip6_addr_set(&ip6addr, groupaddr);
+    ip6_addr_assign_zone(&ip6addr, IP6_MULTICAST, netif);
+    groupaddr = &ip6addr;
+  }
+  IP6_ADDR_ZONECHECK_NETIF(groupaddr, netif);
+#endif /* LWIP_IPV6_SCOPES */
+
+  LWIP_ASSERT_CORE_LOCKED();
+
+  /* find group */
+  group = mld6_lookfor_group(netif, groupaddr);
+
+  if (group != NULL) {
+    /* Leave if there is no other use of the group */
+    if (group->use <= 1) {
+      /* Remove the group from the list */
+      mld6_remove_group(netif, group);
+
+      /* If we are the last reporter for this group */
+      if (group->last_reporter_flag) {
+        MLD6_STATS_INC(mld6.tx_leave);
+        mld6_send(netif, group, ICMP6_TYPE_MLD);
+      }
+
+      /* Disable the group at the MAC level */
+      if (netif->mld_mac_filter != NULL) {
+        netif->mld_mac_filter(netif, groupaddr, NETIF_DEL_MAC_FILTER);
+      }
+
+      /* free group struct */
+      memp_free(MEMP_MLD6_GROUP, group);
+    } else {
+      /* Decrement group use */
+      group->use--;
+    }
+
+    /* Left group */
+    return ERR_OK;
+  }
+
+  /* Group not found */
+  return ERR_VAL;
+}
+
+
+/**
+ * Periodic timer for mld processing. Must be called every
+ * MLD6_TMR_INTERVAL milliseconds (100).
+ *
+ * When a delaying member expires, a membership report is sent.
+ */
+void
+mld6_tmr(void)
+{
+  struct netif *netif;
+
+  NETIF_FOREACH(netif) {
+    struct mld_group *group = netif_mld6_data(netif);
+
+    while (group != NULL) {
+      if (group->timer > 0) {
+        group->timer--;
+        if (group->timer == 0) {
+          /* If the state is MLD6_GROUP_DELAYING_MEMBER then we send a report for this group */
+          if (group->group_state == MLD6_GROUP_DELAYING_MEMBER) {
+            MLD6_STATS_INC(mld6.tx_report);
+            mld6_send(netif, group, ICMP6_TYPE_MLR);
+            group->group_state = MLD6_GROUP_IDLE_MEMBER;
+          }
+        }
+      }
+      group = group->next;
+    }
+  }
+}
+
+/**
+ * Schedule a delayed membership report for a group
+ *
+ * @param group the mld_group for which "delaying" membership report
+ *              should be sent
+ * @param maxresp_in the max resp delay provided in the query
+ */
+static void
+mld6_delayed_report(struct mld_group *group, u16_t maxresp_in)
+{
+  /* Convert maxresp from milliseconds to tmr ticks */
+  u16_t maxresp = maxresp_in / MLD6_TMR_INTERVAL;
+  if (maxresp == 0) {
+    maxresp = 1;
+  }
+
+#ifdef LWIP_RAND
+  /* Randomize maxresp. (if LWIP_RAND is supported) */
+  maxresp = (u16_t)(LWIP_RAND() % maxresp);
+  if (maxresp == 0) {
+    maxresp = 1;
+  }
+#endif /* LWIP_RAND */
+
+  /* Apply timer value if no report has been scheduled already. */
+  if ((group->group_state == MLD6_GROUP_IDLE_MEMBER) ||
+     ((group->group_state == MLD6_GROUP_DELAYING_MEMBER) &&
+      ((group->timer == 0) || (maxresp < group->timer)))) {
+    group->timer = maxresp;
+    group->group_state = MLD6_GROUP_DELAYING_MEMBER;
+  }
+}
+
+/**
+ * Send a MLD message (report or done).
+ *
+ * An IPv6 hop-by-hop options header with a router alert option
+ * is prepended.
+ *
+ * @param group the group to report or quit
+ * @param type ICMP6_TYPE_MLR (report) or ICMP6_TYPE_MLD (done)
+ */
+static void
+mld6_send(struct netif *netif, struct mld_group *group, u8_t type)
+{
+  struct mld_header *mld_hdr;
+  struct pbuf *p;
+  const ip6_addr_t *src_addr;
+
+  /* Allocate a packet. Size is MLD header + IPv6 Hop-by-hop options header. */
+  p = pbuf_alloc(PBUF_IP, sizeof(struct mld_header) + MLD6_HBH_HLEN, PBUF_RAM);
+  if (p == NULL) {
+    MLD6_STATS_INC(mld6.memerr);
+    return;
+  }
+
+  /* Move to make room for Hop-by-hop options header. */
+  if (pbuf_remove_header(p, MLD6_HBH_HLEN)) {
+    pbuf_free(p);
+    MLD6_STATS_INC(mld6.lenerr);
+    return;
+  }
+
+  /* Select our source address. */
+  if (!ip6_addr_isvalid(netif_ip6_addr_state(netif, 0))) {
+    /* This is a special case, when we are performing duplicate address detection.
+     * We must join the multicast group, but we don't have a valid address yet. */
+    src_addr = IP6_ADDR_ANY6;
+  } else {
+    /* Use link-local address as source address. */
+    src_addr = netif_ip6_addr(netif, 0);
+  }
+
+  /* MLD message header pointer. */
+  mld_hdr = (struct mld_header *)p->payload;
+
+  /* Set fields. */
+  mld_hdr->type = type;
+  mld_hdr->code = 0;
+  mld_hdr->chksum = 0;
+  mld_hdr->max_resp_delay = 0;
+  mld_hdr->reserved = 0;
+  ip6_addr_copy_to_packed(mld_hdr->multicast_address, group->group_address);
+
+#if CHECKSUM_GEN_ICMP6
+  IF__NETIF_CHECKSUM_ENABLED(netif, NETIF_CHECKSUM_GEN_ICMP6) {
+    mld_hdr->chksum = ip6_chksum_pseudo(p, IP6_NEXTH_ICMP6, p->len,
+      src_addr, &(group->group_address));
+  }
+#endif /* CHECKSUM_GEN_ICMP6 */
+
+  /* Add hop-by-hop headers options: router alert with MLD value. */
+  ip6_options_add_hbh_ra(p, IP6_NEXTH_ICMP6, IP6_ROUTER_ALERT_VALUE_MLD);
+
+  if (type == ICMP6_TYPE_MLR) {
+    /* Remember we were the last to report */
+    group->last_reporter_flag = 1;
+  }
+
+  /* Send the packet out. */
+  MLD6_STATS_INC(mld6.xmit);
+  ip6_output_if(p, (ip6_addr_isany(src_addr)) ? NULL : src_addr, &(group->group_address),
+      MLD6_HL, 0, IP6_NEXTH_HOPBYHOP, netif);
+  pbuf_free(p);
+}
+
+#endif /* LWIP_IPV6 */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/core/ipv6/nd6.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/core/ipv6/nd6.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/core/ipv6/nd6.c	(revision 457)
@@ -0,0 +1,2434 @@
+/**
+ * @file
+ *
+ * Neighbor discovery and stateless address autoconfiguration for IPv6.
+ * Aims to be compliant with RFC 4861 (Neighbor discovery) and RFC 4862
+ * (Address autoconfiguration).
+ */
+
+/*
+ * Copyright (c) 2010 Inico Technologies Ltd.
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Ivan Delamer <delamer@inicotech.com>
+ *
+ *
+ * Please coordinate changes and requests with Ivan Delamer
+ * <delamer@inicotech.com>
+ */
+
+#include "lwip/opt.h"
+
+#if LWIP_IPV6  /* don't build if not configured for use in lwipopts.h */
+
+#include "lwip/nd6.h"
+#include "lwip/priv/nd6_priv.h"
+#include "lwip/prot/nd6.h"
+#include "lwip/prot/icmp6.h"
+#include "lwip/pbuf.h"
+#include "lwip/mem.h"
+#include "lwip/memp.h"
+#include "lwip/ip6.h"
+#include "lwip/ip6_addr.h"
+#include "lwip/inet_chksum.h"
+#include "lwip/netif.h"
+#include "lwip/icmp6.h"
+#include "lwip/mld6.h"
+#include "lwip/dhcp6.h"
+#include "lwip/ip.h"
+#include "lwip/stats.h"
+#include "lwip/dns.h"
+
+#include <string.h>
+
+#ifdef LWIP_HOOK_FILENAME
+#include LWIP_HOOK_FILENAME
+#endif
+
+#if LWIP_IPV6_DUP_DETECT_ATTEMPTS > IP6_ADDR_TENTATIVE_COUNT_MASK
+#error LWIP_IPV6_DUP_DETECT_ATTEMPTS > IP6_ADDR_TENTATIVE_COUNT_MASK
+#endif
+
+/* Router tables. */
+struct nd6_neighbor_cache_entry neighbor_cache[LWIP_ND6_NUM_NEIGHBORS];
+struct nd6_destination_cache_entry destination_cache[LWIP_ND6_NUM_DESTINATIONS];
+struct nd6_prefix_list_entry prefix_list[LWIP_ND6_NUM_PREFIXES];
+struct nd6_router_list_entry default_router_list[LWIP_ND6_NUM_ROUTERS];
+
+/* Default values, can be updated by a RA message. */
+u32_t reachable_time = LWIP_ND6_REACHABLE_TIME;
+u32_t retrans_timer = LWIP_ND6_RETRANS_TIMER; /* @todo implement this value in timer */
+
+/* Index for cache entries. */
+static u8_t nd6_cached_neighbor_index;
+static netif_addr_idx_t nd6_cached_destination_index;
+
+/* Multicast address holder. */
+static ip6_addr_t multicast_address;
+
+static u8_t nd6_tmr_rs_reduction;
+
+/* Static buffer to parse RA packet options */
+union ra_options {
+  struct lladdr_option  lladdr;
+  struct mtu_option     mtu;
+  struct prefix_option  prefix;
+#if LWIP_ND6_RDNSS_MAX_DNS_SERVERS
+  struct rdnss_option   rdnss;
+#endif
+};
+static union ra_options nd6_ra_buffer;
+
+/* Forward declarations. */
+static s8_t nd6_find_neighbor_cache_entry(const ip6_addr_t *ip6addr);
+static s8_t nd6_new_neighbor_cache_entry(void);
+static void nd6_free_neighbor_cache_entry(s8_t i);
+static s16_t nd6_find_destination_cache_entry(const ip6_addr_t *ip6addr);
+static s16_t nd6_new_destination_cache_entry(void);
+static int nd6_is_prefix_in_netif(const ip6_addr_t *ip6addr, struct netif *netif);
+static s8_t nd6_select_router(const ip6_addr_t *ip6addr, struct netif *netif);
+static s8_t nd6_get_router(const ip6_addr_t *router_addr, struct netif *netif);
+static s8_t nd6_new_router(const ip6_addr_t *router_addr, struct netif *netif);
+static s8_t nd6_get_onlink_prefix(const ip6_addr_t *prefix, struct netif *netif);
+static s8_t nd6_new_onlink_prefix(const ip6_addr_t *prefix, struct netif *netif);
+static s8_t nd6_get_next_hop_entry(const ip6_addr_t *ip6addr, struct netif *netif);
+static err_t nd6_queue_packet(s8_t neighbor_index, struct pbuf *q);
+
+#define ND6_SEND_FLAG_MULTICAST_DEST 0x01
+#define ND6_SEND_FLAG_ALLNODES_DEST 0x02
+#define ND6_SEND_FLAG_ANY_SRC 0x04
+static void nd6_send_ns(struct netif *netif, const ip6_addr_t *target_addr, u8_t flags);
+static void nd6_send_na(struct netif *netif, const ip6_addr_t *target_addr, u8_t flags);
+static void nd6_send_neighbor_cache_probe(struct nd6_neighbor_cache_entry *entry, u8_t flags);
+#if LWIP_IPV6_SEND_ROUTER_SOLICIT
+static err_t nd6_send_rs(struct netif *netif);
+#endif /* LWIP_IPV6_SEND_ROUTER_SOLICIT */
+
+#if LWIP_ND6_QUEUEING
+static void nd6_free_q(struct nd6_q_entry *q);
+#else /* LWIP_ND6_QUEUEING */
+#define nd6_free_q(q) pbuf_free(q)
+#endif /* LWIP_ND6_QUEUEING */
+static void nd6_send_q(s8_t i);
+
+
+/**
+ * A local address has been determined to be a duplicate. Take the appropriate
+ * action(s) on the address and the interface as a whole.
+ *
+ * @param netif the netif that owns the address
+ * @param addr_idx the index of the address detected to be a duplicate
+ */
+static void
+nd6_duplicate_addr_detected(struct netif *netif, s8_t addr_idx)
+{
+
+  /* Mark the address as duplicate, but leave its lifetimes alone. If this was
+   * a manually assigned address, it will remain in existence as duplicate, and
+   * as such be unusable for any practical purposes until manual intervention.
+   * If this was an autogenerated address, the address will follow normal
+   * expiration rules, and thus disappear once its valid lifetime expires. */
+  netif_ip6_addr_set_state(netif, addr_idx, IP6_ADDR_DUPLICATED);
+
+#if LWIP_IPV6_AUTOCONFIG
+  /* If the affected address was the link-local address that we use to generate
+   * all other addresses, then we should not continue to use those derived
+   * addresses either, so mark them as duplicate as well. For autoconfig-only
+   * setups, this will make the interface effectively unusable, approaching the
+   * intention of RFC 4862 Sec. 5.4.5. @todo implement the full requirements */
+  if (addr_idx == 0) {
+    s8_t i;
+    for (i = 1; i < LWIP_IPV6_NUM_ADDRESSES; i++) {
+      if (!ip6_addr_isinvalid(netif_ip6_addr_state(netif, i)) &&
+          !netif_ip6_addr_isstatic(netif, i)) {
+        netif_ip6_addr_set_state(netif, i, IP6_ADDR_DUPLICATED);
+      }
+    }
+  }
+#endif /* LWIP_IPV6_AUTOCONFIG */
+}
+
+#if LWIP_IPV6_AUTOCONFIG
+/**
+ * We received a router advertisement that contains a prefix with the
+ * autoconfiguration flag set. Add or update an associated autogenerated
+ * address.
+ *
+ * @param netif the netif on which the router advertisement arrived
+ * @param prefix_opt a pointer to the prefix option data
+ * @param prefix_addr an aligned copy of the prefix address
+ */
+static void
+nd6_process_autoconfig_prefix(struct netif *netif,
+  struct prefix_option *prefix_opt, const ip6_addr_t *prefix_addr)
+{
+  ip6_addr_t ip6addr;
+  u32_t valid_life, pref_life;
+  u8_t addr_state;
+  s8_t i, free_idx;
+
+  /* The caller already checks RFC 4862 Sec. 5.5.3 points (a) and (b). We do
+   * the rest, starting with checks for (c) and (d) here. */
+  valid_life = lwip_htonl(prefix_opt->valid_lifetime);
+  pref_life = lwip_htonl(prefix_opt->preferred_lifetime);
+  if (pref_life > valid_life || prefix_opt->prefix_length != 64) {
+    return; /* silently ignore this prefix for autoconfiguration purposes */
+  }
+
+  /* If an autogenerated address already exists for this prefix, update its
+   * lifetimes. An address is considered autogenerated if 1) it is not static
+   * (i.e., manually assigned), and 2) there is an advertised autoconfiguration
+   * prefix for it (the one we are processing here). This does not necessarily
+   * exclude the possibility that the address was actually assigned by, say,
+   * DHCPv6. If that distinction becomes important in the future, more state
+   * must be kept. As explained elsewhere we also update lifetimes of tentative
+   * and duplicate addresses. Skip address slot 0 (the link-local address). */
+  for (i = 1; i < LWIP_IPV6_NUM_ADDRESSES; i++) {
+    addr_state = netif_ip6_addr_state(netif, i);
+    if (!ip6_addr_isinvalid(addr_state) && !netif_ip6_addr_isstatic(netif, i) &&
+        ip6_addr_netcmp(prefix_addr, netif_ip6_addr(netif, i))) {
+      /* Update the valid lifetime, as per RFC 4862 Sec. 5.5.3 point (e).
+       * The valid lifetime will never drop to zero as a result of this. */
+      u32_t remaining_life = netif_ip6_addr_valid_life(netif, i);
+      if (valid_life > ND6_2HRS || valid_life > remaining_life) {
+        netif_ip6_addr_set_valid_life(netif, i, valid_life);
+      } else if (remaining_life > ND6_2HRS) {
+        netif_ip6_addr_set_valid_life(netif, i, ND6_2HRS);
+      }
+      LWIP_ASSERT("bad valid lifetime", !netif_ip6_addr_isstatic(netif, i));
+      /* Update the preferred lifetime. No bounds checks are needed here. In
+       * rare cases the advertisement may un-deprecate the address, though.
+       * Deprecation is left to the timer code where it is handled anyway. */
+      if (pref_life > 0 && addr_state == IP6_ADDR_DEPRECATED) {
+        netif_ip6_addr_set_state(netif, i, IP6_ADDR_PREFERRED);
+      }
+      netif_ip6_addr_set_pref_life(netif, i, pref_life);
+      return; /* there should be at most one matching address */
+    }
+  }
+
+  /* No autogenerated address exists for this prefix yet. See if we can add a
+   * new one. However, if IPv6 autoconfiguration is administratively disabled,
+   * do not generate new addresses, but do keep updating lifetimes for existing
+   * addresses. Also, when adding new addresses, we must protect explicitly
+   * against a valid lifetime of zero, because again, we use that as a special
+   * value. The generated address would otherwise expire immediately anyway.
+   * Finally, the original link-local address must be usable at all. We start
+   * creating addresses even if the link-local address is still in tentative
+   * state though, and deal with the fallout of that upon DAD collision. */
+  addr_state = netif_ip6_addr_state(netif, 0);
+  if (!netif->ip6_autoconfig_enabled || valid_life == IP6_ADDR_LIFE_STATIC ||
+      ip6_addr_isinvalid(addr_state) || ip6_addr_isduplicated(addr_state)) {
+    return;
+  }
+
+  /* Construct the new address that we intend to use, and then see if that
+   * address really does not exist. It might have been added manually, after
+   * all. As a side effect, find a free slot. Note that we cannot use
+   * netif_add_ip6_address() here, as it would return ERR_OK if the address
+   * already did exist, resulting in that address being given lifetimes. */
+  IP6_ADDR(&ip6addr, prefix_addr->addr[0], prefix_addr->addr[1],
+    netif_ip6_addr(netif, 0)->addr[2], netif_ip6_addr(netif, 0)->addr[3]);
+  ip6_addr_assign_zone(&ip6addr, IP6_UNICAST, netif);
+
+  free_idx = 0;
+  for (i = 1; i < LWIP_IPV6_NUM_ADDRESSES; i++) {
+    if (!ip6_addr_isinvalid(netif_ip6_addr_state(netif, i))) {
+      if (ip6_addr_cmp(&ip6addr, netif_ip6_addr(netif, i))) {
+        return; /* formed address already exists */
+      }
+    } else if (free_idx == 0) {
+      free_idx = i;
+    }
+  }
+  if (free_idx == 0) {
+    return; /* no address slots available, try again on next advertisement */
+  }
+
+  /* Assign the new address to the interface. */
+  ip_addr_copy_from_ip6(netif->ip6_addr[free_idx], ip6addr);
+  netif_ip6_addr_set_valid_life(netif, free_idx, valid_life);
+  netif_ip6_addr_set_pref_life(netif, free_idx, pref_life);
+  netif_ip6_addr_set_state(netif, free_idx, IP6_ADDR_TENTATIVE);
+}
+#endif /* LWIP_IPV6_AUTOCONFIG */
+
+/**
+ * Process an incoming neighbor discovery message
+ *
+ * @param p the nd packet, p->payload pointing to the icmpv6 header
+ * @param inp the netif on which this packet was received
+ */
+void
+nd6_input(struct pbuf *p, struct netif *inp)
+{
+  u8_t msg_type;
+  s8_t i;
+  s16_t dest_idx;
+
+  ND6_STATS_INC(nd6.recv);
+
+  msg_type = *((u8_t *)p->payload);
+  switch (msg_type) {
+  case ICMP6_TYPE_NA: /* Neighbor Advertisement. */
+  {
+    struct na_header *na_hdr;
+    struct lladdr_option *lladdr_opt;
+    ip6_addr_t target_address;
+
+    /* Check that na header fits in packet. */
+    if (p->len < (sizeof(struct na_header))) {
+      /* @todo debug message */
+      pbuf_free(p);
+      ND6_STATS_INC(nd6.lenerr);
+      ND6_STATS_INC(nd6.drop);
+      return;
+    }
+
+    na_hdr = (struct na_header *)p->payload;
+
+    /* Create an aligned, zoned copy of the target address. */
+    ip6_addr_copy_from_packed(target_address, na_hdr->target_address);
+    ip6_addr_assign_zone(&target_address, IP6_UNICAST, inp);
+
+    /* Check a subset of the other RFC 4861 Sec. 7.1.2 requirements. */
+    if (IP6H_HOPLIM(ip6_current_header()) != ND6_HOPLIM || na_hdr->code != 0 ||
+        ip6_addr_ismulticast(&target_address)) {
+      pbuf_free(p);
+      ND6_STATS_INC(nd6.proterr);
+      ND6_STATS_INC(nd6.drop);
+      return;
+    }
+
+    /* @todo RFC MUST: if IP destination is multicast, Solicited flag is zero */
+    /* @todo RFC MUST: all included options have a length greater than zero */
+
+    /* Unsolicited NA?*/
+    if (ip6_addr_ismulticast(ip6_current_dest_addr())) {
+      /* This is an unsolicited NA.
+       * link-layer changed?
+       * part of DAD mechanism? */
+
+#if LWIP_IPV6_DUP_DETECT_ATTEMPTS
+      /* If the target address matches this netif, it is a DAD response. */
+      for (i = 0; i < LWIP_IPV6_NUM_ADDRESSES; i++) {
+        if (!ip6_addr_isinvalid(netif_ip6_addr_state(inp, i)) &&
+            !ip6_addr_isduplicated(netif_ip6_addr_state(inp, i)) &&
+            ip6_addr_cmp(&target_address, netif_ip6_addr(inp, i))) {
+          /* We are using a duplicate address. */
+          nd6_duplicate_addr_detected(inp, i);
+
+          pbuf_free(p);
+          return;
+        }
+      }
+#endif /* LWIP_IPV6_DUP_DETECT_ATTEMPTS */
+
+      /* Check that link-layer address option also fits in packet. */
+      if (p->len < (sizeof(struct na_header) + 2)) {
+        /* @todo debug message */
+        pbuf_free(p);
+        ND6_STATS_INC(nd6.lenerr);
+        ND6_STATS_INC(nd6.drop);
+        return;
+      }
+
+      lladdr_opt = (struct lladdr_option *)((u8_t*)p->payload + sizeof(struct na_header));
+
+      if (p->len < (sizeof(struct na_header) + (lladdr_opt->length << 3))) {
+        /* @todo debug message */
+        pbuf_free(p);
+        ND6_STATS_INC(nd6.lenerr);
+        ND6_STATS_INC(nd6.drop);
+        return;
+      }
+
+      /* This is an unsolicited NA, most likely there was a LLADDR change. */
+      i = nd6_find_neighbor_cache_entry(&target_address);
+      if (i >= 0) {
+        if (na_hdr->flags & ND6_FLAG_OVERRIDE) {
+          MEMCPY(neighbor_cache[i].lladdr, lladdr_opt->addr, inp->hwaddr_len);
+        }
+      }
+    } else {
+      /* This is a solicited NA.
+       * neighbor address resolution response?
+       * neighbor unreachability detection response? */
+
+      /* Find the cache entry corresponding to this na. */
+      i = nd6_find_neighbor_cache_entry(&target_address);
+      if (i < 0) {
+        /* We no longer care about this target address. drop it. */
+        pbuf_free(p);
+        return;
+      }
+
+      /* Update cache entry. */
+      if ((na_hdr->flags & ND6_FLAG_OVERRIDE) ||
+          (neighbor_cache[i].state == ND6_INCOMPLETE)) {
+        /* Check that link-layer address option also fits in packet. */
+        if (p->len < (sizeof(struct na_header) + 2)) {
+          /* @todo debug message */
+          pbuf_free(p);
+          ND6_STATS_INC(nd6.lenerr);
+          ND6_STATS_INC(nd6.drop);
+          return;
+        }
+
+        lladdr_opt = (struct lladdr_option *)((u8_t*)p->payload + sizeof(struct na_header));
+
+        if (p->len < (sizeof(struct na_header) + (lladdr_opt->length << 3))) {
+          /* @todo debug message */
+          pbuf_free(p);
+          ND6_STATS_INC(nd6.lenerr);
+          ND6_STATS_INC(nd6.drop);
+          return;
+        }
+
+        MEMCPY(neighbor_cache[i].lladdr, lladdr_opt->addr, inp->hwaddr_len);
+      }
+
+      neighbor_cache[i].netif = inp;
+      neighbor_cache[i].state = ND6_REACHABLE;
+      neighbor_cache[i].counter.reachable_time = reachable_time;
+
+      /* Send queued packets, if any. */
+      if (neighbor_cache[i].q != NULL) {
+        nd6_send_q(i);
+      }
+    }
+
+    break; /* ICMP6_TYPE_NA */
+  }
+  case ICMP6_TYPE_NS: /* Neighbor solicitation. */
+  {
+    struct ns_header *ns_hdr;
+    struct lladdr_option *lladdr_opt;
+    ip6_addr_t target_address;
+    u8_t accepted;
+
+    /* Check that ns header fits in packet. */
+    if (p->len < sizeof(struct ns_header)) {
+      /* @todo debug message */
+      pbuf_free(p);
+      ND6_STATS_INC(nd6.lenerr);
+      ND6_STATS_INC(nd6.drop);
+      return;
+    }
+
+    ns_hdr = (struct ns_header *)p->payload;
+
+    /* Create an aligned, zoned copy of the target address. */
+    ip6_addr_copy_from_packed(target_address, ns_hdr->target_address);
+    ip6_addr_assign_zone(&target_address, IP6_UNICAST, inp);
+
+    /* Check a subset of the other RFC 4861 Sec. 7.1.1 requirements. */
+    if (IP6H_HOPLIM(ip6_current_header()) != ND6_HOPLIM || ns_hdr->code != 0 ||
+       ip6_addr_ismulticast(&target_address)) {
+      pbuf_free(p);
+      ND6_STATS_INC(nd6.proterr);
+      ND6_STATS_INC(nd6.drop);
+      return;
+    }
+
+    /* @todo RFC MUST: all included options have a length greater than zero */
+    /* @todo RFC MUST: if IP source is 'any', destination is solicited-node multicast address */
+    /* @todo RFC MUST: if IP source is 'any', there is no source LL address option */
+
+    /* Check if there is a link-layer address provided. Only point to it if in this buffer. */
+    if (p->len >= (sizeof(struct ns_header) + 2)) {
+      lladdr_opt = (struct lladdr_option *)((u8_t*)p->payload + sizeof(struct ns_header));
+      if (p->len < (sizeof(struct ns_header) + (lladdr_opt->length << 3))) {
+        lladdr_opt = NULL;
+      }
+    } else {
+      lladdr_opt = NULL;
+    }
+
+    /* Check if the target address is configured on the receiving netif. */
+    accepted = 0;
+    for (i = 0; i < LWIP_IPV6_NUM_ADDRESSES; ++i) {
+      if ((ip6_addr_isvalid(netif_ip6_addr_state(inp, i)) ||
+           (ip6_addr_istentative(netif_ip6_addr_state(inp, i)) &&
+            ip6_addr_isany(ip6_current_src_addr()))) &&
+          ip6_addr_cmp(&target_address, netif_ip6_addr(inp, i))) {
+        accepted = 1;
+        break;
+      }
+    }
+
+    /* NS not for us? */
+    if (!accepted) {
+      pbuf_free(p);
+      return;
+    }
+
+    /* Check for ANY address in src (DAD algorithm). */
+    if (ip6_addr_isany(ip6_current_src_addr())) {
+      /* Sender is validating this address. */
+      for (i = 0; i < LWIP_IPV6_NUM_ADDRESSES; ++i) {
+        if (!ip6_addr_isinvalid(netif_ip6_addr_state(inp, i)) &&
+            ip6_addr_cmp(&target_address, netif_ip6_addr(inp, i))) {
+          /* Send a NA back so that the sender does not use this address. */
+          nd6_send_na(inp, netif_ip6_addr(inp, i), ND6_FLAG_OVERRIDE | ND6_SEND_FLAG_ALLNODES_DEST);
+          if (ip6_addr_istentative(netif_ip6_addr_state(inp, i))) {
+            /* We shouldn't use this address either. */
+            nd6_duplicate_addr_detected(inp, i);
+          }
+        }
+      }
+    } else {
+      /* Sender is trying to resolve our address. */
+      /* Verify that they included their own link-layer address. */
+      if (lladdr_opt == NULL) {
+        /* Not a valid message. */
+        pbuf_free(p);
+        ND6_STATS_INC(nd6.proterr);
+        ND6_STATS_INC(nd6.drop);
+        return;
+      }
+
+      i = nd6_find_neighbor_cache_entry(ip6_current_src_addr());
+      if (i>= 0) {
+        /* We already have a record for the solicitor. */
+        if (neighbor_cache[i].state == ND6_INCOMPLETE) {
+          neighbor_cache[i].netif = inp;
+          MEMCPY(neighbor_cache[i].lladdr, lladdr_opt->addr, inp->hwaddr_len);
+
+          /* Delay probe in case we get confirmation of reachability from upper layer (TCP). */
+          neighbor_cache[i].state = ND6_DELAY;
+          neighbor_cache[i].counter.delay_time = LWIP_ND6_DELAY_FIRST_PROBE_TIME / ND6_TMR_INTERVAL;
+        }
+      } else {
+        /* Add their IPv6 address and link-layer address to neighbor cache.
+         * We will need it at least to send a unicast NA message, but most
+         * likely we will also be communicating with this node soon. */
+        i = nd6_new_neighbor_cache_entry();
+        if (i < 0) {
+          /* We couldn't assign a cache entry for this neighbor.
+           * we won't be able to reply. drop it. */
+          pbuf_free(p);
+          ND6_STATS_INC(nd6.memerr);
+          return;
+        }
+        neighbor_cache[i].netif = inp;
+        MEMCPY(neighbor_cache[i].lladdr, lladdr_opt->addr, inp->hwaddr_len);
+        ip6_addr_set(&(neighbor_cache[i].next_hop_address), ip6_current_src_addr());
+
+        /* Receiving a message does not prove reachability: only in one direction.
+         * Delay probe in case we get confirmation of reachability from upper layer (TCP). */
+        neighbor_cache[i].state = ND6_DELAY;
+        neighbor_cache[i].counter.delay_time = LWIP_ND6_DELAY_FIRST_PROBE_TIME / ND6_TMR_INTERVAL;
+      }
+
+      /* Send back a NA for us. Allocate the reply pbuf. */
+      nd6_send_na(inp, &target_address, ND6_FLAG_SOLICITED | ND6_FLAG_OVERRIDE);
+    }
+
+    break; /* ICMP6_TYPE_NS */
+  }
+  case ICMP6_TYPE_RA: /* Router Advertisement. */
+  {
+    struct ra_header *ra_hdr;
+    u8_t *buffer; /* Used to copy options. */
+    u16_t offset;
+#if LWIP_ND6_RDNSS_MAX_DNS_SERVERS
+    /* There can be multiple RDNSS options per RA */
+    u8_t rdnss_server_idx = 0;
+#endif /* LWIP_ND6_RDNSS_MAX_DNS_SERVERS */
+
+    /* Check that RA header fits in packet. */
+    if (p->len < sizeof(struct ra_header)) {
+      /* @todo debug message */
+      pbuf_free(p);
+      ND6_STATS_INC(nd6.lenerr);
+      ND6_STATS_INC(nd6.drop);
+      return;
+    }
+
+    ra_hdr = (struct ra_header *)p->payload;
+
+    /* Check a subset of the other RFC 4861 Sec. 6.1.2 requirements. */
+    if (!ip6_addr_islinklocal(ip6_current_src_addr()) ||
+        IP6H_HOPLIM(ip6_current_header()) != ND6_HOPLIM || ra_hdr->code != 0) {
+      pbuf_free(p);
+      ND6_STATS_INC(nd6.proterr);
+      ND6_STATS_INC(nd6.drop);
+      return;
+    }
+
+    /* @todo RFC MUST: all included options have a length greater than zero */
+
+    /* If we are sending RS messages, stop. */
+#if LWIP_IPV6_SEND_ROUTER_SOLICIT
+    /* ensure at least one solicitation is sent (see RFC 4861, ch. 6.3.7) */
+    if ((inp->rs_count < LWIP_ND6_MAX_MULTICAST_SOLICIT) ||
+        (nd6_send_rs(inp) == ERR_OK)) {
+      inp->rs_count = 0;
+    } else {
+      inp->rs_count = 1;
+    }
+#endif /* LWIP_IPV6_SEND_ROUTER_SOLICIT */
+
+    /* Get the matching default router entry. */
+    i = nd6_get_router(ip6_current_src_addr(), inp);
+    if (i < 0) {
+      /* Create a new router entry. */
+      i = nd6_new_router(ip6_current_src_addr(), inp);
+    }
+
+    if (i < 0) {
+      /* Could not create a new router entry. */
+      pbuf_free(p);
+      ND6_STATS_INC(nd6.memerr);
+      return;
+    }
+
+    /* Re-set invalidation timer. */
+    default_router_list[i].invalidation_timer = lwip_htons(ra_hdr->router_lifetime);
+
+    /* Re-set default timer values. */
+#if LWIP_ND6_ALLOW_RA_UPDATES
+    if (ra_hdr->retrans_timer > 0) {
+      retrans_timer = lwip_htonl(ra_hdr->retrans_timer);
+    }
+    if (ra_hdr->reachable_time > 0) {
+      reachable_time = lwip_htonl(ra_hdr->reachable_time);
+    }
+#endif /* LWIP_ND6_ALLOW_RA_UPDATES */
+
+    /* @todo set default hop limit... */
+    /* ra_hdr->current_hop_limit;*/
+
+    /* Update flags in local entry (incl. preference). */
+    default_router_list[i].flags = ra_hdr->flags;
+
+#if LWIP_IPV6_DHCP6
+    /* Trigger DHCPv6 if enabled */
+    dhcp6_nd6_ra_trigger(inp, ra_hdr->flags & ND6_RA_FLAG_MANAGED_ADDR_CONFIG,
+      ra_hdr->flags & ND6_RA_FLAG_OTHER_CONFIG);
+#endif
+
+    /* Offset to options. */
+    offset = sizeof(struct ra_header);
+
+    /* Process each option. */
+    while ((p->tot_len - offset) >= 2) {
+      u8_t option_type;
+      u16_t option_len;
+      int option_len8 = pbuf_try_get_at(p, offset + 1);
+      if (option_len8 <= 0) {
+        /* read beyond end or zero length */
+        goto lenerr_drop_free_return;
+      }
+      option_len = ((u8_t)option_len8) << 3;
+      if (option_len > p->tot_len - offset) {
+        /* short packet (option does not fit in) */
+        goto lenerr_drop_free_return;
+      }
+      if (p->len == p->tot_len) {
+        /* no need to copy from contiguous pbuf */
+        buffer = &((u8_t*)p->payload)[offset];
+      } else {
+        /* check if this option fits into our buffer */
+        if (option_len > sizeof(nd6_ra_buffer)) {
+          option_type = pbuf_get_at(p, offset);
+          /* invalid option length */
+          if (option_type != ND6_OPTION_TYPE_RDNSS) {
+            goto lenerr_drop_free_return;
+          }
+          /* we allow RDNSS option to be longer - we'll just drop some servers */
+          option_len = sizeof(nd6_ra_buffer);
+        }
+        buffer = (u8_t*)&nd6_ra_buffer;
+        option_len = pbuf_copy_partial(p, &nd6_ra_buffer, option_len, offset);
+      }
+      option_type = buffer[0];
+      switch (option_type) {
+      case ND6_OPTION_TYPE_SOURCE_LLADDR:
+      {
+        struct lladdr_option *lladdr_opt;
+        if (option_len < sizeof(struct lladdr_option)) {
+          goto lenerr_drop_free_return;
+        }
+        lladdr_opt = (struct lladdr_option *)buffer;
+        if ((default_router_list[i].neighbor_entry != NULL) &&
+            (default_router_list[i].neighbor_entry->state == ND6_INCOMPLETE)) {
+          SMEMCPY(default_router_list[i].neighbor_entry->lladdr, lladdr_opt->addr, inp->hwaddr_len);
+          default_router_list[i].neighbor_entry->state = ND6_REACHABLE;
+          default_router_list[i].neighbor_entry->counter.reachable_time = reachable_time;
+        }
+        break;
+      }
+      case ND6_OPTION_TYPE_MTU:
+      {
+        struct mtu_option *mtu_opt;
+        u32_t mtu32;
+        if (option_len < sizeof(struct mtu_option)) {
+          goto lenerr_drop_free_return;
+        }
+        mtu_opt = (struct mtu_option *)buffer;
+        mtu32 = lwip_htonl(mtu_opt->mtu);
+        if ((mtu32 >= 1280) && (mtu32 <= 0xffff)) {
+#if LWIP_ND6_ALLOW_RA_UPDATES
+          if (inp->mtu) {
+            /* don't set the mtu for IPv6 higher than the netif driver supports */
+            inp->mtu6 = LWIP_MIN(inp->mtu, (u16_t)mtu32);
+          } else {
+            inp->mtu6 = (u16_t)mtu32;
+          }
+#endif /* LWIP_ND6_ALLOW_RA_UPDATES */
+        }
+        break;
+      }
+      case ND6_OPTION_TYPE_PREFIX_INFO:
+      {
+        struct prefix_option *prefix_opt;
+        ip6_addr_t prefix_addr;
+        if (option_len < sizeof(struct prefix_option)) {
+          goto lenerr_drop_free_return;
+        }
+
+        prefix_opt = (struct prefix_option *)buffer;
+
+        /* Get a memory-aligned copy of the prefix. */
+        ip6_addr_copy_from_packed(prefix_addr, prefix_opt->prefix);
+        ip6_addr_assign_zone(&prefix_addr, IP6_UNICAST, inp);
+
+        if (!ip6_addr_islinklocal(&prefix_addr)) {
+          if ((prefix_opt->flags & ND6_PREFIX_FLAG_ON_LINK) &&
+              (prefix_opt->prefix_length == 64)) {
+            /* Add to on-link prefix list. */
+            u32_t valid_life;
+            s8_t prefix;
+
+            valid_life = lwip_htonl(prefix_opt->valid_lifetime);
+
+            /* find cache entry for this prefix. */
+            prefix = nd6_get_onlink_prefix(&prefix_addr, inp);
+            if (prefix < 0 && valid_life > 0) {
+              /* Create a new cache entry. */
+              prefix = nd6_new_onlink_prefix(&prefix_addr, inp);
+            }
+            if (prefix >= 0) {
+              prefix_list[prefix].invalidation_timer = valid_life;
+            }
+          }
+#if LWIP_IPV6_AUTOCONFIG
+          if (prefix_opt->flags & ND6_PREFIX_FLAG_AUTONOMOUS) {
+            /* Perform processing for autoconfiguration. */
+            nd6_process_autoconfig_prefix(inp, prefix_opt, &prefix_addr);
+          }
+#endif /* LWIP_IPV6_AUTOCONFIG */
+        }
+
+        break;
+      }
+      case ND6_OPTION_TYPE_ROUTE_INFO:
+        /* @todo implement preferred routes.
+        struct route_option * route_opt;
+        route_opt = (struct route_option *)buffer;*/
+
+        break;
+#if LWIP_ND6_RDNSS_MAX_DNS_SERVERS
+      case ND6_OPTION_TYPE_RDNSS:
+      {
+        u8_t num, n;
+        u16_t copy_offset = offset + SIZEOF_RDNSS_OPTION_BASE;
+        struct rdnss_option * rdnss_opt;
+        if (option_len < SIZEOF_RDNSS_OPTION_BASE) {
+          goto lenerr_drop_free_return;
+        }
+
+        rdnss_opt = (struct rdnss_option *)buffer;
+        num = (rdnss_opt->length - 1) / 2;
+        for (n = 0; (rdnss_server_idx < DNS_MAX_SERVERS) && (n < num); n++) {
+          ip_addr_t rdnss_address;
+
+          /* Copy directly from pbuf to get an aligned, zoned copy of the prefix. */
+          if (pbuf_copy_partial(p, &rdnss_address, sizeof(ip6_addr_p_t), copy_offset) == sizeof(ip6_addr_p_t)) {
+            IP_SET_TYPE_VAL(rdnss_address, IPADDR_TYPE_V6);
+            ip6_addr_assign_zone(ip_2_ip6(&rdnss_address), IP6_UNKNOWN, inp);
+
+            if (htonl(rdnss_opt->lifetime) > 0) {
+              /* TODO implement Lifetime > 0 */
+              dns_setserver(rdnss_server_idx++, &rdnss_address);
+            } else {
+              /* TODO implement DNS removal in dns.c */
+              u8_t s;
+              for (s = 0; s < DNS_MAX_SERVERS; s++) {
+                const ip_addr_t *addr = dns_getserver(s);
+                if(ip_addr_cmp(addr, &rdnss_address)) {
+                  dns_setserver(s, NULL);
+                }
+              }
+            }
+          }
+        }
+        break;
+      }
+#endif /* LWIP_ND6_RDNSS_MAX_DNS_SERVERS */
+      default:
+        /* Unrecognized option, abort. */
+        ND6_STATS_INC(nd6.proterr);
+        break;
+      }
+      /* option length is checked earlier to be non-zero to make sure loop ends */
+      offset += 8 * (u8_t)option_len8;
+    }
+
+    break; /* ICMP6_TYPE_RA */
+  }
+  case ICMP6_TYPE_RD: /* Redirect */
+  {
+    struct redirect_header *redir_hdr;
+    struct lladdr_option *lladdr_opt;
+    ip6_addr_t destination_address, target_address;
+
+    /* Check that Redir header fits in packet. */
+    if (p->len < sizeof(struct redirect_header)) {
+      /* @todo debug message */
+      pbuf_free(p);
+      ND6_STATS_INC(nd6.lenerr);
+      ND6_STATS_INC(nd6.drop);
+      return;
+    }
+
+    redir_hdr = (struct redirect_header *)p->payload;
+
+    /* Create an aligned, zoned copy of the destination address. */
+    ip6_addr_copy_from_packed(destination_address, redir_hdr->destination_address);
+    ip6_addr_assign_zone(&destination_address, IP6_UNICAST, inp);
+
+    /* Check a subset of the other RFC 4861 Sec. 8.1 requirements. */
+    if (!ip6_addr_islinklocal(ip6_current_src_addr()) ||
+        IP6H_HOPLIM(ip6_current_header()) != ND6_HOPLIM ||
+        redir_hdr->code != 0 || ip6_addr_ismulticast(&destination_address)) {
+      pbuf_free(p);
+      ND6_STATS_INC(nd6.proterr);
+      ND6_STATS_INC(nd6.drop);
+      return;
+    }
+
+    /* @todo RFC MUST: IP source address equals first-hop router for destination_address */
+    /* @todo RFC MUST: ICMP target address is either link-local address or same as destination_address */
+    /* @todo RFC MUST: all included options have a length greater than zero */
+
+    if (p->len >= (sizeof(struct redirect_header) + 2)) {
+      lladdr_opt = (struct lladdr_option *)((u8_t*)p->payload + sizeof(struct redirect_header));
+      if (p->len < (sizeof(struct redirect_header) + (lladdr_opt->length << 3))) {
+        lladdr_opt = NULL;
+      }
+    } else {
+      lladdr_opt = NULL;
+    }
+
+    /* Find dest address in cache */
+    dest_idx = nd6_find_destination_cache_entry(&destination_address);
+    if (dest_idx < 0) {
+      /* Destination not in cache, drop packet. */
+      pbuf_free(p);
+      return;
+    }
+
+    /* Create an aligned, zoned copy of the target address. */
+    ip6_addr_copy_from_packed(target_address, redir_hdr->target_address);
+    ip6_addr_assign_zone(&target_address, IP6_UNICAST, inp);
+
+    /* Set the new target address. */
+    ip6_addr_copy(destination_cache[dest_idx].next_hop_addr, target_address);
+
+    /* If Link-layer address of other router is given, try to add to neighbor cache. */
+    if (lladdr_opt != NULL) {
+      if (lladdr_opt->type == ND6_OPTION_TYPE_TARGET_LLADDR) {
+        i = nd6_find_neighbor_cache_entry(&target_address);
+        if (i < 0) {
+          i = nd6_new_neighbor_cache_entry();
+          if (i >= 0) {
+            neighbor_cache[i].netif = inp;
+            MEMCPY(neighbor_cache[i].lladdr, lladdr_opt->addr, inp->hwaddr_len);
+            ip6_addr_copy(neighbor_cache[i].next_hop_address, target_address);
+
+            /* Receiving a message does not prove reachability: only in one direction.
+             * Delay probe in case we get confirmation of reachability from upper layer (TCP). */
+            neighbor_cache[i].state = ND6_DELAY;
+            neighbor_cache[i].counter.delay_time = LWIP_ND6_DELAY_FIRST_PROBE_TIME / ND6_TMR_INTERVAL;
+          }
+        }
+        if (i >= 0) {
+          if (neighbor_cache[i].state == ND6_INCOMPLETE) {
+            MEMCPY(neighbor_cache[i].lladdr, lladdr_opt->addr, inp->hwaddr_len);
+            /* Receiving a message does not prove reachability: only in one direction.
+             * Delay probe in case we get confirmation of reachability from upper layer (TCP). */
+            neighbor_cache[i].state = ND6_DELAY;
+            neighbor_cache[i].counter.delay_time = LWIP_ND6_DELAY_FIRST_PROBE_TIME / ND6_TMR_INTERVAL;
+          }
+        }
+      }
+    }
+    break; /* ICMP6_TYPE_RD */
+  }
+  case ICMP6_TYPE_PTB: /* Packet too big */
+  {
+    struct icmp6_hdr *icmp6hdr; /* Packet too big message */
+    struct ip6_hdr *ip6hdr; /* IPv6 header of the packet which caused the error */
+    u32_t pmtu;
+    ip6_addr_t destination_address;
+
+    /* Check that ICMPv6 header + IPv6 header fit in payload */
+    if (p->len < (sizeof(struct icmp6_hdr) + IP6_HLEN)) {
+      /* drop short packets */
+      pbuf_free(p);
+      ND6_STATS_INC(nd6.lenerr);
+      ND6_STATS_INC(nd6.drop);
+      return;
+    }
+
+    icmp6hdr = (struct icmp6_hdr *)p->payload;
+    ip6hdr = (struct ip6_hdr *)((u8_t*)p->payload + sizeof(struct icmp6_hdr));
+
+    /* Create an aligned, zoned copy of the destination address. */
+    ip6_addr_copy_from_packed(destination_address, ip6hdr->dest);
+    ip6_addr_assign_zone(&destination_address, IP6_UNKNOWN, inp);
+
+    /* Look for entry in destination cache. */
+    dest_idx = nd6_find_destination_cache_entry(&destination_address);
+    if (dest_idx < 0) {
+      /* Destination not in cache, drop packet. */
+      pbuf_free(p);
+      return;
+    }
+
+    /* Change the Path MTU. */
+    pmtu = lwip_htonl(icmp6hdr->data);
+    destination_cache[dest_idx].pmtu = (u16_t)LWIP_MIN(pmtu, 0xFFFF);
+
+    break; /* ICMP6_TYPE_PTB */
+  }
+
+  default:
+    ND6_STATS_INC(nd6.proterr);
+    ND6_STATS_INC(nd6.drop);
+    break; /* default */
+  }
+
+  pbuf_free(p);
+  return;
+lenerr_drop_free_return:
+  ND6_STATS_INC(nd6.lenerr);
+  ND6_STATS_INC(nd6.drop);
+  pbuf_free(p);
+}
+
+
+/**
+ * Periodic timer for Neighbor discovery functions:
+ *
+ * - Update neighbor reachability states
+ * - Update destination cache entries age
+ * - Update invalidation timers of default routers and on-link prefixes
+ * - Update lifetimes of our addresses
+ * - Perform duplicate address detection (DAD) for our addresses
+ * - Send router solicitations
+ */
+void
+nd6_tmr(void)
+{
+  s8_t i;
+  struct netif *netif;
+
+  /* Process neighbor entries. */
+  for (i = 0; i < LWIP_ND6_NUM_NEIGHBORS; i++) {
+    switch (neighbor_cache[i].state) {
+    case ND6_INCOMPLETE:
+      if ((neighbor_cache[i].counter.probes_sent >= LWIP_ND6_MAX_MULTICAST_SOLICIT) &&
+          (!neighbor_cache[i].isrouter)) {
+        /* Retries exceeded. */
+        nd6_free_neighbor_cache_entry(i);
+      } else {
+        /* Send a NS for this entry. */
+        neighbor_cache[i].counter.probes_sent++;
+        nd6_send_neighbor_cache_probe(&neighbor_cache[i], ND6_SEND_FLAG_MULTICAST_DEST);
+      }
+      break;
+    case ND6_REACHABLE:
+      /* Send queued packets, if any are left. Should have been sent already. */
+      if (neighbor_cache[i].q != NULL) {
+        nd6_send_q(i);
+      }
+      if (neighbor_cache[i].counter.reachable_time <= ND6_TMR_INTERVAL) {
+        /* Change to stale state. */
+        neighbor_cache[i].state = ND6_STALE;
+        neighbor_cache[i].counter.stale_time = 0;
+      } else {
+        neighbor_cache[i].counter.reachable_time -= ND6_TMR_INTERVAL;
+      }
+      break;
+    case ND6_STALE:
+      neighbor_cache[i].counter.stale_time++;
+      break;
+    case ND6_DELAY:
+      if (neighbor_cache[i].counter.delay_time <= 1) {
+        /* Change to PROBE state. */
+        neighbor_cache[i].state = ND6_PROBE;
+        neighbor_cache[i].counter.probes_sent = 0;
+      } else {
+        neighbor_cache[i].counter.delay_time--;
+      }
+      break;
+    case ND6_PROBE:
+      if ((neighbor_cache[i].counter.probes_sent >= LWIP_ND6_MAX_MULTICAST_SOLICIT) &&
+          (!neighbor_cache[i].isrouter)) {
+        /* Retries exceeded. */
+        nd6_free_neighbor_cache_entry(i);
+      } else {
+        /* Send a NS for this entry. */
+        neighbor_cache[i].counter.probes_sent++;
+        nd6_send_neighbor_cache_probe(&neighbor_cache[i], 0);
+      }
+      break;
+    case ND6_NO_ENTRY:
+    default:
+      /* Do nothing. */
+      break;
+    }
+  }
+
+  /* Process destination entries. */
+  for (i = 0; i < LWIP_ND6_NUM_DESTINATIONS; i++) {
+    destination_cache[i].age++;
+  }
+
+  /* Process router entries. */
+  for (i = 0; i < LWIP_ND6_NUM_ROUTERS; i++) {
+    if (default_router_list[i].neighbor_entry != NULL) {
+      /* Active entry. */
+      if (default_router_list[i].invalidation_timer <= ND6_TMR_INTERVAL / 1000) {
+        /* No more than 1 second remaining. Clear this entry. Also clear any of
+         * its destination cache entries, as per RFC 4861 Sec. 5.3 and 6.3.5. */
+        s8_t j;
+        for (j = 0; j < LWIP_ND6_NUM_DESTINATIONS; j++) {
+          if (ip6_addr_cmp(&destination_cache[j].next_hop_addr,
+               &default_router_list[i].neighbor_entry->next_hop_address)) {
+             ip6_addr_set_any(&destination_cache[j].destination_addr);
+          }
+        }
+        default_router_list[i].neighbor_entry->isrouter = 0;
+        default_router_list[i].neighbor_entry = NULL;
+        default_router_list[i].invalidation_timer = 0;
+        default_router_list[i].flags = 0;
+      } else {
+        default_router_list[i].invalidation_timer -= ND6_TMR_INTERVAL / 1000;
+      }
+    }
+  }
+
+  /* Process prefix entries. */
+  for (i = 0; i < LWIP_ND6_NUM_PREFIXES; i++) {
+    if (prefix_list[i].netif != NULL) {
+      if (prefix_list[i].invalidation_timer <= ND6_TMR_INTERVAL / 1000) {
+        /* Entry timed out, remove it */
+        prefix_list[i].invalidation_timer = 0;
+        prefix_list[i].netif = NULL;
+      } else {
+        prefix_list[i].invalidation_timer -= ND6_TMR_INTERVAL / 1000;
+      }
+    }
+  }
+
+  /* Process our own addresses, updating address lifetimes and/or DAD state. */
+  NETIF_FOREACH(netif) {
+    for (i = 0; i < LWIP_IPV6_NUM_ADDRESSES; ++i) {
+      u8_t addr_state;
+#if LWIP_IPV6_ADDRESS_LIFETIMES
+      /* Step 1: update address lifetimes (valid and preferred). */
+      addr_state = netif_ip6_addr_state(netif, i);
+      /* RFC 4862 is not entirely clear as to whether address lifetimes affect
+       * tentative addresses, and is even less clear as to what should happen
+       * with duplicate addresses. We choose to track and update lifetimes for
+       * both those types, although for different reasons:
+       * - for tentative addresses, the line of thought of Sec. 5.7 combined
+       *   with the potentially long period that an address may be in tentative
+       *   state (due to the interface being down) suggests that lifetimes
+       *   should be independent of external factors which would include DAD;
+       * - for duplicate addresses, retiring them early could result in a new
+       *   but unwanted attempt at marking them as valid, while retiring them
+       *   late/never could clog up address slots on the netif.
+       * As a result, we may end up expiring addresses of either type here.
+       */
+      if (!ip6_addr_isinvalid(addr_state) &&
+          !netif_ip6_addr_isstatic(netif, i)) {
+        u32_t life = netif_ip6_addr_valid_life(netif, i);
+        if (life <= ND6_TMR_INTERVAL / 1000) {
+          /* The address has expired. */
+          netif_ip6_addr_set_valid_life(netif, i, 0);
+          netif_ip6_addr_set_pref_life(netif, i, 0);
+          netif_ip6_addr_set_state(netif, i, IP6_ADDR_INVALID);
+        } else {
+          if (!ip6_addr_life_isinfinite(life)) {
+            life -= ND6_TMR_INTERVAL / 1000;
+            LWIP_ASSERT("bad valid lifetime", life != IP6_ADDR_LIFE_STATIC);
+            netif_ip6_addr_set_valid_life(netif, i, life);
+          }
+          /* The address is still here. Update the preferred lifetime too. */
+          life = netif_ip6_addr_pref_life(netif, i);
+          if (life <= ND6_TMR_INTERVAL / 1000) {
+            /* This case must also trigger if 'life' was already zero, so as to
+             * deal correctly with advertised preferred-lifetime reductions. */
+            netif_ip6_addr_set_pref_life(netif, i, 0);
+            if (addr_state == IP6_ADDR_PREFERRED)
+              netif_ip6_addr_set_state(netif, i, IP6_ADDR_DEPRECATED);
+          } else if (!ip6_addr_life_isinfinite(life)) {
+            life -= ND6_TMR_INTERVAL / 1000;
+            netif_ip6_addr_set_pref_life(netif, i, life);
+          }
+        }
+      }
+      /* The address state may now have changed, so reobtain it next. */
+#endif /* LWIP_IPV6_ADDRESS_LIFETIMES */
+      /* Step 2: update DAD state. */
+      addr_state = netif_ip6_addr_state(netif, i);
+      if (ip6_addr_istentative(addr_state)) {
+        if ((addr_state & IP6_ADDR_TENTATIVE_COUNT_MASK) >= LWIP_IPV6_DUP_DETECT_ATTEMPTS) {
+          /* No NA received in response. Mark address as valid. For dynamic
+           * addresses with an expired preferred lifetime, the state is set to
+           * deprecated right away. That should almost never happen, though. */
+          addr_state = IP6_ADDR_PREFERRED;
+#if LWIP_IPV6_ADDRESS_LIFETIMES
+          if (!netif_ip6_addr_isstatic(netif, i) &&
+              netif_ip6_addr_pref_life(netif, i) == 0) {
+            addr_state = IP6_ADDR_DEPRECATED;
+          }
+#endif /* LWIP_IPV6_ADDRESS_LIFETIMES */
+          netif_ip6_addr_set_state(netif, i, addr_state);
+        } else if (netif_is_up(netif) && netif_is_link_up(netif)) {
+          /* tentative: set next state by increasing by one */
+          netif_ip6_addr_set_state(netif, i, addr_state + 1);
+          /* Send a NS for this address. Use the unspecified address as source
+           * address in all cases (RFC 4862 Sec. 5.4.2), not in the least
+           * because as it is, we only consider multicast replies for DAD. */
+          nd6_send_ns(netif, netif_ip6_addr(netif, i),
+            ND6_SEND_FLAG_MULTICAST_DEST | ND6_SEND_FLAG_ANY_SRC);
+        }
+      }
+    }
+  }
+
+#if LWIP_IPV6_SEND_ROUTER_SOLICIT
+  /* Send router solicitation messages, if necessary. */
+  if (!nd6_tmr_rs_reduction) {
+    nd6_tmr_rs_reduction = (ND6_RTR_SOLICITATION_INTERVAL / ND6_TMR_INTERVAL) - 1;
+    NETIF_FOREACH(netif) {
+      if ((netif->rs_count > 0) && netif_is_up(netif) &&
+          netif_is_link_up(netif) &&
+          !ip6_addr_isinvalid(netif_ip6_addr_state(netif, 0)) &&
+          !ip6_addr_isduplicated(netif_ip6_addr_state(netif, 0))) {
+        if (nd6_send_rs(netif) == ERR_OK) {
+          netif->rs_count--;
+        }
+      }
+    }
+  } else {
+    nd6_tmr_rs_reduction--;
+  }
+#endif /* LWIP_IPV6_SEND_ROUTER_SOLICIT */
+
+}
+
+/** Send a neighbor solicitation message for a specific neighbor cache entry
+ *
+ * @param entry the neightbor cache entry for wich to send the message
+ * @param flags one of ND6_SEND_FLAG_*
+ */
+static void
+nd6_send_neighbor_cache_probe(struct nd6_neighbor_cache_entry *entry, u8_t flags)
+{
+  nd6_send_ns(entry->netif, &entry->next_hop_address, flags);
+}
+
+/**
+ * Send a neighbor solicitation message
+ *
+ * @param netif the netif on which to send the message
+ * @param target_addr the IPv6 target address for the ND message
+ * @param flags one of ND6_SEND_FLAG_*
+ */
+static void
+nd6_send_ns(struct netif *netif, const ip6_addr_t *target_addr, u8_t flags)
+{
+  struct ns_header *ns_hdr;
+  struct pbuf *p;
+  const ip6_addr_t *src_addr;
+  u16_t lladdr_opt_len;
+
+  LWIP_ASSERT("target address is required", target_addr != NULL);
+
+  if (!(flags & ND6_SEND_FLAG_ANY_SRC) &&
+      ip6_addr_isvalid(netif_ip6_addr_state(netif,0))) {
+    /* Use link-local address as source address. */
+    src_addr = netif_ip6_addr(netif, 0);
+    /* calculate option length (in 8-byte-blocks) */
+    lladdr_opt_len = ((netif->hwaddr_len + 2) + 7) >> 3;
+  } else {
+    src_addr = IP6_ADDR_ANY6;
+    /* Option "MUST NOT be included when the source IP address is the unspecified address." */
+    lladdr_opt_len = 0;
+  }
+
+  /* Allocate a packet. */
+  p = pbuf_alloc(PBUF_IP, sizeof(struct ns_header) + (lladdr_opt_len << 3), PBUF_RAM);
+  if (p == NULL) {
+    ND6_STATS_INC(nd6.memerr);
+    return;
+  }
+
+  /* Set fields. */
+  ns_hdr = (struct ns_header *)p->payload;
+
+  ns_hdr->type = ICMP6_TYPE_NS;
+  ns_hdr->code = 0;
+  ns_hdr->chksum = 0;
+  ns_hdr->reserved = 0;
+  ip6_addr_copy_to_packed(ns_hdr->target_address, *target_addr);
+
+  if (lladdr_opt_len != 0) {
+    struct lladdr_option *lladdr_opt = (struct lladdr_option *)((u8_t*)p->payload + sizeof(struct ns_header));
+    lladdr_opt->type = ND6_OPTION_TYPE_SOURCE_LLADDR;
+    lladdr_opt->length = (u8_t)lladdr_opt_len;
+    SMEMCPY(lladdr_opt->addr, netif->hwaddr, netif->hwaddr_len);
+  }
+
+  /* Generate the solicited node address for the target address. */
+  if (flags & ND6_SEND_FLAG_MULTICAST_DEST) {
+    ip6_addr_set_solicitednode(&multicast_address, target_addr->addr[3]);
+    ip6_addr_assign_zone(&multicast_address, IP6_MULTICAST, netif);
+    target_addr = &multicast_address;
+  }
+
+#if CHECKSUM_GEN_ICMP6
+  IF__NETIF_CHECKSUM_ENABLED(netif, NETIF_CHECKSUM_GEN_ICMP6) {
+    ns_hdr->chksum = ip6_chksum_pseudo(p, IP6_NEXTH_ICMP6, p->len, src_addr,
+      target_addr);
+  }
+#endif /* CHECKSUM_GEN_ICMP6 */
+
+  /* Send the packet out. */
+  ND6_STATS_INC(nd6.xmit);
+  ip6_output_if(p, (src_addr == IP6_ADDR_ANY6) ? NULL : src_addr, target_addr,
+      ND6_HOPLIM, 0, IP6_NEXTH_ICMP6, netif);
+  pbuf_free(p);
+}
+
+/**
+ * Send a neighbor advertisement message
+ *
+ * @param netif the netif on which to send the message
+ * @param target_addr the IPv6 target address for the ND message
+ * @param flags one of ND6_SEND_FLAG_*
+ */
+static void
+nd6_send_na(struct netif *netif, const ip6_addr_t *target_addr, u8_t flags)
+{
+  struct na_header *na_hdr;
+  struct lladdr_option *lladdr_opt;
+  struct pbuf *p;
+  const ip6_addr_t *src_addr;
+  const ip6_addr_t *dest_addr;
+  u16_t lladdr_opt_len;
+
+  LWIP_ASSERT("target address is required", target_addr != NULL);
+
+  /* Use link-local address as source address. */
+  /* src_addr = netif_ip6_addr(netif, 0); */
+  /* Use target address as source address. */
+  src_addr = target_addr;
+
+  /* Allocate a packet. */
+  lladdr_opt_len = ((netif->hwaddr_len + 2) >> 3) + (((netif->hwaddr_len + 2) & 0x07) ? 1 : 0);
+  p = pbuf_alloc(PBUF_IP, sizeof(struct na_header) + (lladdr_opt_len << 3), PBUF_RAM);
+  if (p == NULL) {
+    ND6_STATS_INC(nd6.memerr);
+    return;
+  }
+
+  /* Set fields. */
+  na_hdr = (struct na_header *)p->payload;
+  lladdr_opt = (struct lladdr_option *)((u8_t*)p->payload + sizeof(struct na_header));
+
+  na_hdr->type = ICMP6_TYPE_NA;
+  na_hdr->code = 0;
+  na_hdr->chksum = 0;
+  na_hdr->flags = flags & 0xf0;
+  na_hdr->reserved[0] = 0;
+  na_hdr->reserved[1] = 0;
+  na_hdr->reserved[2] = 0;
+  ip6_addr_copy_to_packed(na_hdr->target_address, *target_addr);
+
+  lladdr_opt->type = ND6_OPTION_TYPE_TARGET_LLADDR;
+  lladdr_opt->length = (u8_t)lladdr_opt_len;
+  SMEMCPY(lladdr_opt->addr, netif->hwaddr, netif->hwaddr_len);
+
+  /* Generate the solicited node address for the target address. */
+  if (flags & ND6_SEND_FLAG_MULTICAST_DEST) {
+    ip6_addr_set_solicitednode(&multicast_address, target_addr->addr[3]);
+    ip6_addr_assign_zone(&multicast_address, IP6_MULTICAST, netif);
+    dest_addr = &multicast_address;
+  } else if (flags & ND6_SEND_FLAG_ALLNODES_DEST) {
+    ip6_addr_set_allnodes_linklocal(&multicast_address);
+    ip6_addr_assign_zone(&multicast_address, IP6_MULTICAST, netif);
+    dest_addr = &multicast_address;
+  } else {
+    dest_addr = ip6_current_src_addr();
+  }
+
+#if CHECKSUM_GEN_ICMP6
+  IF__NETIF_CHECKSUM_ENABLED(netif, NETIF_CHECKSUM_GEN_ICMP6) {
+    na_hdr->chksum = ip6_chksum_pseudo(p, IP6_NEXTH_ICMP6, p->len, src_addr,
+      dest_addr);
+  }
+#endif /* CHECKSUM_GEN_ICMP6 */
+
+  /* Send the packet out. */
+  ND6_STATS_INC(nd6.xmit);
+  ip6_output_if(p, src_addr, dest_addr,
+      ND6_HOPLIM, 0, IP6_NEXTH_ICMP6, netif);
+  pbuf_free(p);
+}
+
+#if LWIP_IPV6_SEND_ROUTER_SOLICIT
+/**
+ * Send a router solicitation message
+ *
+ * @param netif the netif on which to send the message
+ */
+static err_t
+nd6_send_rs(struct netif *netif)
+{
+  struct rs_header *rs_hdr;
+  struct lladdr_option *lladdr_opt;
+  struct pbuf *p;
+  const ip6_addr_t *src_addr;
+  err_t err;
+  u16_t lladdr_opt_len = 0;
+
+  /* Link-local source address, or unspecified address? */
+  if (ip6_addr_isvalid(netif_ip6_addr_state(netif, 0))) {
+    src_addr = netif_ip6_addr(netif, 0);
+  } else {
+    src_addr = IP6_ADDR_ANY6;
+  }
+
+  /* Generate the all routers target address. */
+  ip6_addr_set_allrouters_linklocal(&multicast_address);
+  ip6_addr_assign_zone(&multicast_address, IP6_MULTICAST, netif);
+
+  /* Allocate a packet. */
+  if (src_addr != IP6_ADDR_ANY6) {
+    lladdr_opt_len = ((netif->hwaddr_len + 2) >> 3) + (((netif->hwaddr_len + 2) & 0x07) ? 1 : 0);
+  }
+  p = pbuf_alloc(PBUF_IP, sizeof(struct rs_header) + (lladdr_opt_len << 3), PBUF_RAM);
+  if (p == NULL) {
+    ND6_STATS_INC(nd6.memerr);
+    return ERR_BUF;
+  }
+
+  /* Set fields. */
+  rs_hdr = (struct rs_header *)p->payload;
+
+  rs_hdr->type = ICMP6_TYPE_RS;
+  rs_hdr->code = 0;
+  rs_hdr->chksum = 0;
+  rs_hdr->reserved = 0;
+
+  if (src_addr != IP6_ADDR_ANY6) {
+    /* Include our hw address. */
+    lladdr_opt = (struct lladdr_option *)((u8_t*)p->payload + sizeof(struct rs_header));
+    lladdr_opt->type = ND6_OPTION_TYPE_SOURCE_LLADDR;
+    lladdr_opt->length = (u8_t)lladdr_opt_len;
+    SMEMCPY(lladdr_opt->addr, netif->hwaddr, netif->hwaddr_len);
+  }
+
+#if CHECKSUM_GEN_ICMP6
+  IF__NETIF_CHECKSUM_ENABLED(netif, NETIF_CHECKSUM_GEN_ICMP6) {
+    rs_hdr->chksum = ip6_chksum_pseudo(p, IP6_NEXTH_ICMP6, p->len, src_addr,
+      &multicast_address);
+  }
+#endif /* CHECKSUM_GEN_ICMP6 */
+
+  /* Send the packet out. */
+  ND6_STATS_INC(nd6.xmit);
+
+  err = ip6_output_if(p, (src_addr == IP6_ADDR_ANY6) ? NULL : src_addr, &multicast_address,
+      ND6_HOPLIM, 0, IP6_NEXTH_ICMP6, netif);
+  pbuf_free(p);
+
+  return err;
+}
+#endif /* LWIP_IPV6_SEND_ROUTER_SOLICIT */
+
+/**
+ * Search for a neighbor cache entry
+ *
+ * @param ip6addr the IPv6 address of the neighbor
+ * @return The neighbor cache entry index that matched, -1 if no
+ * entry is found
+ */
+static s8_t
+nd6_find_neighbor_cache_entry(const ip6_addr_t *ip6addr)
+{
+  s8_t i;
+  for (i = 0; i < LWIP_ND6_NUM_NEIGHBORS; i++) {
+    if (ip6_addr_cmp(ip6addr, &(neighbor_cache[i].next_hop_address))) {
+      return i;
+    }
+  }
+  return -1;
+}
+
+/**
+ * Create a new neighbor cache entry.
+ *
+ * If no unused entry is found, will try to recycle an old entry
+ * according to ad-hoc "age" heuristic.
+ *
+ * @return The neighbor cache entry index that was created, -1 if no
+ * entry could be created
+ */
+static s8_t
+nd6_new_neighbor_cache_entry(void)
+{
+  s8_t i;
+  s8_t j;
+  u32_t time;
+
+
+  /* First, try to find an empty entry. */
+  for (i = 0; i < LWIP_ND6_NUM_NEIGHBORS; i++) {
+    if (neighbor_cache[i].state == ND6_NO_ENTRY) {
+      return i;
+    }
+  }
+
+  /* We need to recycle an entry. in general, do not recycle if it is a router. */
+
+  /* Next, try to find a Stale entry. */
+  for (i = 0; i < LWIP_ND6_NUM_NEIGHBORS; i++) {
+    if ((neighbor_cache[i].state == ND6_STALE) &&
+        (!neighbor_cache[i].isrouter)) {
+      nd6_free_neighbor_cache_entry(i);
+      return i;
+    }
+  }
+
+  /* Next, try to find a Probe entry. */
+  for (i = 0; i < LWIP_ND6_NUM_NEIGHBORS; i++) {
+    if ((neighbor_cache[i].state == ND6_PROBE) &&
+        (!neighbor_cache[i].isrouter)) {
+      nd6_free_neighbor_cache_entry(i);
+      return i;
+    }
+  }
+
+  /* Next, try to find a Delayed entry. */
+  for (i = 0; i < LWIP_ND6_NUM_NEIGHBORS; i++) {
+    if ((neighbor_cache[i].state == ND6_DELAY) &&
+        (!neighbor_cache[i].isrouter)) {
+      nd6_free_neighbor_cache_entry(i);
+      return i;
+    }
+  }
+
+  /* Next, try to find the oldest reachable entry. */
+  time = 0xfffffffful;
+  j = -1;
+  for (i = 0; i < LWIP_ND6_NUM_NEIGHBORS; i++) {
+    if ((neighbor_cache[i].state == ND6_REACHABLE) &&
+        (!neighbor_cache[i].isrouter)) {
+      if (neighbor_cache[i].counter.reachable_time < time) {
+        j = i;
+        time = neighbor_cache[i].counter.reachable_time;
+      }
+    }
+  }
+  if (j >= 0) {
+    nd6_free_neighbor_cache_entry(j);
+    return j;
+  }
+
+  /* Next, find oldest incomplete entry without queued packets. */
+  time = 0;
+  j = -1;
+  for (i = 0; i < LWIP_ND6_NUM_NEIGHBORS; i++) {
+    if (
+        (neighbor_cache[i].q == NULL) &&
+        (neighbor_cache[i].state == ND6_INCOMPLETE) &&
+        (!neighbor_cache[i].isrouter)) {
+      if (neighbor_cache[i].counter.probes_sent >= time) {
+        j = i;
+        time = neighbor_cache[i].counter.probes_sent;
+      }
+    }
+  }
+  if (j >= 0) {
+    nd6_free_neighbor_cache_entry(j);
+    return j;
+  }
+
+  /* Next, find oldest incomplete entry with queued packets. */
+  time = 0;
+  j = -1;
+  for (i = 0; i < LWIP_ND6_NUM_NEIGHBORS; i++) {
+    if ((neighbor_cache[i].state == ND6_INCOMPLETE) &&
+        (!neighbor_cache[i].isrouter)) {
+      if (neighbor_cache[i].counter.probes_sent >= time) {
+        j = i;
+        time = neighbor_cache[i].counter.probes_sent;
+      }
+    }
+  }
+  if (j >= 0) {
+    nd6_free_neighbor_cache_entry(j);
+    return j;
+  }
+
+  /* No more entries to try. */
+  return -1;
+}
+
+/**
+ * Will free any resources associated with a neighbor cache
+ * entry, and will mark it as unused.
+ *
+ * @param i the neighbor cache entry index to free
+ */
+static void
+nd6_free_neighbor_cache_entry(s8_t i)
+{
+  if ((i < 0) || (i >= LWIP_ND6_NUM_NEIGHBORS)) {
+    return;
+  }
+  if (neighbor_cache[i].isrouter) {
+    /* isrouter needs to be cleared before deleting a neighbor cache entry */
+    return;
+  }
+
+  /* Free any queued packets. */
+  if (neighbor_cache[i].q != NULL) {
+    nd6_free_q(neighbor_cache[i].q);
+    neighbor_cache[i].q = NULL;
+  }
+
+  neighbor_cache[i].state = ND6_NO_ENTRY;
+  neighbor_cache[i].isrouter = 0;
+  neighbor_cache[i].netif = NULL;
+  neighbor_cache[i].counter.reachable_time = 0;
+  ip6_addr_set_zero(&(neighbor_cache[i].next_hop_address));
+}
+
+/**
+ * Search for a destination cache entry
+ *
+ * @param ip6addr the IPv6 address of the destination
+ * @return The destination cache entry index that matched, -1 if no
+ * entry is found
+ */
+static s16_t
+nd6_find_destination_cache_entry(const ip6_addr_t *ip6addr)
+{
+  s16_t i;
+
+  IP6_ADDR_ZONECHECK(ip6addr);
+
+  for (i = 0; i < LWIP_ND6_NUM_DESTINATIONS; i++) {
+    if (ip6_addr_cmp(ip6addr, &(destination_cache[i].destination_addr))) {
+      return i;
+    }
+  }
+  return -1;
+}
+
+/**
+ * Create a new destination cache entry. If no unused entry is found,
+ * will recycle oldest entry.
+ *
+ * @return The destination cache entry index that was created, -1 if no
+ * entry was created
+ */
+static s16_t
+nd6_new_destination_cache_entry(void)
+{
+  s16_t i, j;
+  u32_t age;
+
+  /* Find an empty entry. */
+  for (i = 0; i < LWIP_ND6_NUM_DESTINATIONS; i++) {
+    if (ip6_addr_isany(&(destination_cache[i].destination_addr))) {
+      return i;
+    }
+  }
+
+  /* Find oldest entry. */
+  age = 0;
+  j = LWIP_ND6_NUM_DESTINATIONS - 1;
+  for (i = 0; i < LWIP_ND6_NUM_DESTINATIONS; i++) {
+    if (destination_cache[i].age > age) {
+      j = i;
+    }
+  }
+
+  return j;
+}
+
+/**
+ * Clear the destination cache.
+ *
+ * This operation may be necessary for consistency in the light of changing
+ * local addresses and/or use of the gateway hook.
+ */
+void
+nd6_clear_destination_cache(void)
+{
+  int i;
+
+  for (i = 0; i < LWIP_ND6_NUM_DESTINATIONS; i++) {
+    ip6_addr_set_any(&destination_cache[i].destination_addr);
+  }
+}
+
+/**
+ * Determine whether an address matches an on-link prefix or the subnet of a
+ * statically assigned address.
+ *
+ * @param ip6addr the IPv6 address to match
+ * @return 1 if the address is on-link, 0 otherwise
+ */
+static int
+nd6_is_prefix_in_netif(const ip6_addr_t *ip6addr, struct netif *netif)
+{
+  s8_t i;
+
+  /* Check to see if the address matches an on-link prefix. */
+  for (i = 0; i < LWIP_ND6_NUM_PREFIXES; i++) {
+    if ((prefix_list[i].netif == netif) &&
+        (prefix_list[i].invalidation_timer > 0) &&
+        ip6_addr_netcmp(ip6addr, &(prefix_list[i].prefix))) {
+      return 1;
+    }
+  }
+  /* Check to see if address prefix matches a manually configured (= static)
+   * address. Static addresses have an implied /64 subnet assignment. Dynamic
+   * addresses (from autoconfiguration) have no implied subnet assignment, and
+   * are thus effectively /128 assignments. See RFC 5942 for more on this. */
+  for (i = 0; i < LWIP_IPV6_NUM_ADDRESSES; i++) {
+    if (ip6_addr_isvalid(netif_ip6_addr_state(netif, i)) &&
+        netif_ip6_addr_isstatic(netif, i) &&
+        ip6_addr_netcmp(ip6addr, netif_ip6_addr(netif, i))) {
+      return 1;
+    }
+  }
+  return 0;
+}
+
+/**
+ * Select a default router for a destination.
+ *
+ * This function is used both for routing and for finding a next-hop target for
+ * a packet. In the former case, the given netif is NULL, and the returned
+ * router entry must be for a netif suitable for sending packets (up, link up).
+ * In the latter case, the given netif is not NULL and restricts router choice.
+ *
+ * @param ip6addr the destination address
+ * @param netif the netif for the outgoing packet, if known
+ * @return the default router entry index, or -1 if no suitable
+ *         router is found
+ */
+static s8_t
+nd6_select_router(const ip6_addr_t *ip6addr, struct netif *netif)
+{
+  struct netif *router_netif;
+  s8_t i, j, valid_router;
+  static s8_t last_router;
+
+  LWIP_UNUSED_ARG(ip6addr); /* @todo match preferred routes!! (must implement ND6_OPTION_TYPE_ROUTE_INFO) */
+
+  /* @todo: implement default router preference */
+
+  /* Look for valid routers. A reachable router is preferred. */
+  valid_router = -1;
+  for (i = 0; i < LWIP_ND6_NUM_ROUTERS; i++) {
+    /* Is the router netif both set and apppropriate? */
+    if (default_router_list[i].neighbor_entry != NULL) {
+      router_netif = default_router_list[i].neighbor_entry->netif;
+      if ((router_netif != NULL) && (netif != NULL ? netif == router_netif :
+          (netif_is_up(router_netif) && netif_is_link_up(router_netif)))) {
+        /* Is the router valid, i.e., reachable or probably reachable as per
+         * RFC 4861 Sec. 6.3.6? Note that we will never return a router that
+         * has no neighbor cache entry, due to the netif association tests. */
+        if (default_router_list[i].neighbor_entry->state != ND6_INCOMPLETE) {
+          /* Is the router known to be reachable? */
+          if (default_router_list[i].neighbor_entry->state == ND6_REACHABLE) {
+            return i; /* valid and reachable - done! */
+          } else if (valid_router < 0) {
+            valid_router = i; /* valid but not known to be reachable */
+          }
+        }
+      }
+    }
+  }
+  if (valid_router >= 0) {
+    return valid_router;
+  }
+
+  /* Look for any router for which we have any information at all. */
+  /* last_router is used for round-robin selection of incomplete routers, as
+   * recommended in RFC 4861 Sec. 6.3.6 point (2). Advance only when picking a
+   * route, to select the same router as next-hop target in the common case. */
+  if ((netif == NULL) && (++last_router >= LWIP_ND6_NUM_ROUTERS)) {
+    last_router = 0;
+  }
+  i = last_router;
+  for (j = 0; j < LWIP_ND6_NUM_ROUTERS; j++) {
+    if (default_router_list[i].neighbor_entry != NULL) {
+      router_netif = default_router_list[i].neighbor_entry->netif;
+      if ((router_netif != NULL) && (netif != NULL ? netif == router_netif :
+          (netif_is_up(router_netif) && netif_is_link_up(router_netif)))) {
+        return i;
+      }
+    }
+    if (++i >= LWIP_ND6_NUM_ROUTERS) {
+      i = 0;
+    }
+  }
+
+  /* no suitable router found. */
+  return -1;
+}
+
+/**
+ * Find a router-announced route to the given destination. This route may be
+ * based on an on-link prefix or a default router.
+ *
+ * If a suitable route is found, the returned netif is guaranteed to be in a
+ * suitable state (up, link up) to be used for packet transmission.
+ *
+ * @param ip6addr the destination IPv6 address
+ * @return the netif to use for the destination, or NULL if none found
+ */
+struct netif *
+nd6_find_route(const ip6_addr_t *ip6addr)
+{
+  struct netif *netif;
+  s8_t i;
+
+  /* @todo decide if it makes sense to check the destination cache first */
+
+  /* Check if there is a matching on-link prefix. There may be multiple
+   * matches. Pick the first one that is associated with a suitable netif. */
+  for (i = 0; i < LWIP_ND6_NUM_PREFIXES; ++i) {
+    netif = prefix_list[i].netif;
+    if ((netif != NULL) && ip6_addr_netcmp(&prefix_list[i].prefix, ip6addr) &&
+        netif_is_up(netif) && netif_is_link_up(netif)) {
+      return netif;
+    }
+  }
+
+  /* No on-link prefix match. Find a router that can forward the packet. */
+  i = nd6_select_router(ip6addr, NULL);
+  if (i >= 0) {
+    LWIP_ASSERT("selected router must have a neighbor entry",
+      default_router_list[i].neighbor_entry != NULL);
+    return default_router_list[i].neighbor_entry->netif;
+  }
+
+  return NULL;
+}
+
+/**
+ * Find an entry for a default router.
+ *
+ * @param router_addr the IPv6 address of the router
+ * @param netif the netif on which the router is found, if known
+ * @return the index of the router entry, or -1 if not found
+ */
+static s8_t
+nd6_get_router(const ip6_addr_t *router_addr, struct netif *netif)
+{
+  s8_t i;
+
+  IP6_ADDR_ZONECHECK_NETIF(router_addr, netif);
+
+  /* Look for router. */
+  for (i = 0; i < LWIP_ND6_NUM_ROUTERS; i++) {
+    if ((default_router_list[i].neighbor_entry != NULL) &&
+        ((netif != NULL) ? netif == default_router_list[i].neighbor_entry->netif : 1) &&
+        ip6_addr_cmp(router_addr, &(default_router_list[i].neighbor_entry->next_hop_address))) {
+      return i;
+    }
+  }
+
+  /* router not found. */
+  return -1;
+}
+
+/**
+ * Create a new entry for a default router.
+ *
+ * @param router_addr the IPv6 address of the router
+ * @param netif the netif on which the router is connected, if known
+ * @return the index on the router table, or -1 if could not be created
+ */
+static s8_t
+nd6_new_router(const ip6_addr_t *router_addr, struct netif *netif)
+{
+  s8_t router_index;
+  s8_t free_router_index;
+  s8_t neighbor_index;
+
+  IP6_ADDR_ZONECHECK_NETIF(router_addr, netif);
+
+  /* Do we have a neighbor entry for this router? */
+  neighbor_index = nd6_find_neighbor_cache_entry(router_addr);
+  if (neighbor_index < 0) {
+    /* Create a neighbor entry for this router. */
+    neighbor_index = nd6_new_neighbor_cache_entry();
+    if (neighbor_index < 0) {
+      /* Could not create neighbor entry for this router. */
+      return -1;
+    }
+    ip6_addr_set(&(neighbor_cache[neighbor_index].next_hop_address), router_addr);
+    neighbor_cache[neighbor_index].netif = netif;
+    neighbor_cache[neighbor_index].q = NULL;
+    neighbor_cache[neighbor_index].state = ND6_INCOMPLETE;
+    neighbor_cache[neighbor_index].counter.probes_sent = 1;
+    nd6_send_neighbor_cache_probe(&neighbor_cache[neighbor_index], ND6_SEND_FLAG_MULTICAST_DEST);
+  }
+
+  /* Mark neighbor as router. */
+  neighbor_cache[neighbor_index].isrouter = 1;
+
+  /* Look for empty entry. */
+  free_router_index = LWIP_ND6_NUM_ROUTERS;
+  for (router_index = LWIP_ND6_NUM_ROUTERS - 1; router_index >= 0; router_index--) {
+    /* check if router already exists (this is a special case for 2 netifs on the same subnet
+       - e.g. wifi and cable) */
+    if(default_router_list[router_index].neighbor_entry == &(neighbor_cache[neighbor_index])){ 
+      return router_index; 
+    } 
+    if (default_router_list[router_index].neighbor_entry == NULL) {
+      /* remember lowest free index to create a new entry */
+      free_router_index = router_index;
+    }
+  }
+  if (free_router_index < LWIP_ND6_NUM_ROUTERS) {
+    default_router_list[free_router_index].neighbor_entry = &(neighbor_cache[neighbor_index]);
+    return free_router_index;
+  }
+
+  /* Could not create a router entry. */
+
+  /* Mark neighbor entry as not-router. Entry might be useful as neighbor still. */
+  neighbor_cache[neighbor_index].isrouter = 0;
+
+  /* router not found. */
+  return -1;
+}
+
+/**
+ * Find the cached entry for an on-link prefix.
+ *
+ * @param prefix the IPv6 prefix that is on-link
+ * @param netif the netif on which the prefix is on-link
+ * @return the index on the prefix table, or -1 if not found
+ */
+static s8_t
+nd6_get_onlink_prefix(const ip6_addr_t *prefix, struct netif *netif)
+{
+  s8_t i;
+
+  /* Look for prefix in list. */
+  for (i = 0; i < LWIP_ND6_NUM_PREFIXES; ++i) {
+    if ((ip6_addr_netcmp(&(prefix_list[i].prefix), prefix)) &&
+        (prefix_list[i].netif == netif)) {
+      return i;
+    }
+  }
+
+  /* Entry not available. */
+  return -1;
+}
+
+/**
+ * Creates a new entry for an on-link prefix.
+ *
+ * @param prefix the IPv6 prefix that is on-link
+ * @param netif the netif on which the prefix is on-link
+ * @return the index on the prefix table, or -1 if not created
+ */
+static s8_t
+nd6_new_onlink_prefix(const ip6_addr_t *prefix, struct netif *netif)
+{
+  s8_t i;
+
+  /* Create new entry. */
+  for (i = 0; i < LWIP_ND6_NUM_PREFIXES; ++i) {
+    if ((prefix_list[i].netif == NULL) ||
+        (prefix_list[i].invalidation_timer == 0)) {
+      /* Found empty prefix entry. */
+      prefix_list[i].netif = netif;
+      ip6_addr_set(&(prefix_list[i].prefix), prefix);
+      return i;
+    }
+  }
+
+  /* Entry not available. */
+  return -1;
+}
+
+/**
+ * Determine the next hop for a destination. Will determine if the
+ * destination is on-link, else a suitable on-link router is selected.
+ *
+ * The last entry index is cached for fast entry search.
+ *
+ * @param ip6addr the destination address
+ * @param netif the netif on which the packet will be sent
+ * @return the neighbor cache entry for the next hop, ERR_RTE if no
+ *         suitable next hop was found, ERR_MEM if no cache entry
+ *         could be created
+ */
+static s8_t
+nd6_get_next_hop_entry(const ip6_addr_t *ip6addr, struct netif *netif)
+{
+#ifdef LWIP_HOOK_ND6_GET_GW
+  const ip6_addr_t *next_hop_addr;
+#endif /* LWIP_HOOK_ND6_GET_GW */
+  s8_t i;
+  s16_t dst_idx;
+
+  IP6_ADDR_ZONECHECK_NETIF(ip6addr, netif);
+
+#if LWIP_NETIF_HWADDRHINT
+  if (netif->hints != NULL) {
+    /* per-pcb cached entry was given */
+    netif_addr_idx_t addr_hint = netif->hints->addr_hint;
+    if (addr_hint < LWIP_ND6_NUM_DESTINATIONS) {
+      nd6_cached_destination_index = addr_hint;
+    }
+  }
+#endif /* LWIP_NETIF_HWADDRHINT */
+
+  /* Look for ip6addr in destination cache. */
+  if (ip6_addr_cmp(ip6addr, &(destination_cache[nd6_cached_destination_index].destination_addr))) {
+    /* the cached entry index is the right one! */
+    /* do nothing. */
+    ND6_STATS_INC(nd6.cachehit);
+  } else {
+    /* Search destination cache. */
+    dst_idx = nd6_find_destination_cache_entry(ip6addr);
+    if (dst_idx >= 0) {
+      /* found destination entry. make it our new cached index. */
+      LWIP_ASSERT("type overflow", (size_t)dst_idx < NETIF_ADDR_IDX_MAX);
+      nd6_cached_destination_index = (netif_addr_idx_t)dst_idx;
+    } else {
+      /* Not found. Create a new destination entry. */
+      dst_idx = nd6_new_destination_cache_entry();
+      if (dst_idx >= 0) {
+        /* got new destination entry. make it our new cached index. */
+        LWIP_ASSERT("type overflow", (size_t)dst_idx < NETIF_ADDR_IDX_MAX);
+        nd6_cached_destination_index = (netif_addr_idx_t)dst_idx;
+      } else {
+        /* Could not create a destination cache entry. */
+        return ERR_MEM;
+      }
+
+      /* Copy dest address to destination cache. */
+      ip6_addr_set(&(destination_cache[nd6_cached_destination_index].destination_addr), ip6addr);
+
+      /* Now find the next hop. is it a neighbor? */
+      if (ip6_addr_islinklocal(ip6addr) ||
+          nd6_is_prefix_in_netif(ip6addr, netif)) {
+        /* Destination in local link. */
+        destination_cache[nd6_cached_destination_index].pmtu = netif_mtu6(netif);
+        ip6_addr_copy(destination_cache[nd6_cached_destination_index].next_hop_addr, destination_cache[nd6_cached_destination_index].destination_addr);
+#ifdef LWIP_HOOK_ND6_GET_GW
+      } else if ((next_hop_addr = LWIP_HOOK_ND6_GET_GW(netif, ip6addr)) != NULL) {
+        /* Next hop for destination provided by hook function. */
+        destination_cache[nd6_cached_destination_index].pmtu = netif->mtu;
+        ip6_addr_set(&destination_cache[nd6_cached_destination_index].next_hop_addr, next_hop_addr);
+#endif /* LWIP_HOOK_ND6_GET_GW */
+      } else {
+        /* We need to select a router. */
+        i = nd6_select_router(ip6addr, netif);
+        if (i < 0) {
+          /* No router found. */
+          ip6_addr_set_any(&(destination_cache[nd6_cached_destination_index].destination_addr));
+          return ERR_RTE;
+        }
+        destination_cache[nd6_cached_destination_index].pmtu = netif_mtu6(netif); /* Start with netif mtu, correct through ICMPv6 if necessary */
+        ip6_addr_copy(destination_cache[nd6_cached_destination_index].next_hop_addr, default_router_list[i].neighbor_entry->next_hop_address);
+      }
+    }
+  }
+
+#if LWIP_NETIF_HWADDRHINT
+  if (netif->hints != NULL) {
+    /* per-pcb cached entry was given */
+    netif->hints->addr_hint = nd6_cached_destination_index;
+  }
+#endif /* LWIP_NETIF_HWADDRHINT */
+
+  /* Look in neighbor cache for the next-hop address. */
+  if (ip6_addr_cmp(&(destination_cache[nd6_cached_destination_index].next_hop_addr),
+                   &(neighbor_cache[nd6_cached_neighbor_index].next_hop_address))) {
+    /* Cache hit. */
+    /* Do nothing. */
+    ND6_STATS_INC(nd6.cachehit);
+  } else {
+    i = nd6_find_neighbor_cache_entry(&(destination_cache[nd6_cached_destination_index].next_hop_addr));
+    if (i >= 0) {
+      /* Found a matching record, make it new cached entry. */
+      nd6_cached_neighbor_index = i;
+    } else {
+      /* Neighbor not in cache. Make a new entry. */
+      i = nd6_new_neighbor_cache_entry();
+      if (i >= 0) {
+        /* got new neighbor entry. make it our new cached index. */
+        nd6_cached_neighbor_index = i;
+      } else {
+        /* Could not create a neighbor cache entry. */
+        return ERR_MEM;
+      }
+
+      /* Initialize fields. */
+      ip6_addr_copy(neighbor_cache[i].next_hop_address,
+                   destination_cache[nd6_cached_destination_index].next_hop_addr);
+      neighbor_cache[i].isrouter = 0;
+      neighbor_cache[i].netif = netif;
+      neighbor_cache[i].state = ND6_INCOMPLETE;
+      neighbor_cache[i].counter.probes_sent = 1;
+      nd6_send_neighbor_cache_probe(&neighbor_cache[i], ND6_SEND_FLAG_MULTICAST_DEST);
+    }
+  }
+
+  /* Reset this destination's age. */
+  destination_cache[nd6_cached_destination_index].age = 0;
+
+  return nd6_cached_neighbor_index;
+}
+
+/**
+ * Queue a packet for a neighbor.
+ *
+ * @param neighbor_index the index in the neighbor cache table
+ * @param q packet to be queued
+ * @return ERR_OK if succeeded, ERR_MEM if out of memory
+ */
+static err_t
+nd6_queue_packet(s8_t neighbor_index, struct pbuf *q)
+{
+  err_t result = ERR_MEM;
+  struct pbuf *p;
+  int copy_needed = 0;
+#if LWIP_ND6_QUEUEING
+  struct nd6_q_entry *new_entry, *r;
+#endif /* LWIP_ND6_QUEUEING */
+
+  if ((neighbor_index < 0) || (neighbor_index >= LWIP_ND6_NUM_NEIGHBORS)) {
+    return ERR_ARG;
+  }
+
+  /* IF q includes a pbuf that must be copied, we have to copy the whole chain
+   * into a new PBUF_RAM. See the definition of PBUF_NEEDS_COPY for details. */
+  p = q;
+  while (p) {
+    if (PBUF_NEEDS_COPY(p)) {
+      copy_needed = 1;
+      break;
+    }
+    p = p->next;
+  }
+  if (copy_needed) {
+    /* copy the whole packet into new pbufs */
+    p = pbuf_clone(PBUF_LINK, PBUF_RAM, q);
+    while ((p == NULL) && (neighbor_cache[neighbor_index].q != NULL)) {
+      /* Free oldest packet (as per RFC recommendation) */
+#if LWIP_ND6_QUEUEING
+      r = neighbor_cache[neighbor_index].q;
+      neighbor_cache[neighbor_index].q = r->next;
+      r->next = NULL;
+      nd6_free_q(r);
+#else /* LWIP_ND6_QUEUEING */
+      pbuf_free(neighbor_cache[neighbor_index].q);
+      neighbor_cache[neighbor_index].q = NULL;
+#endif /* LWIP_ND6_QUEUEING */
+      p = pbuf_clone(PBUF_LINK, PBUF_RAM, q);
+    }
+  } else {
+    /* referencing the old pbuf is enough */
+    p = q;
+    pbuf_ref(p);
+  }
+  /* packet was copied/ref'd? */
+  if (p != NULL) {
+    /* queue packet ... */
+#if LWIP_ND6_QUEUEING
+    /* allocate a new nd6 queue entry */
+    new_entry = (struct nd6_q_entry *)memp_malloc(MEMP_ND6_QUEUE);
+    if ((new_entry == NULL) && (neighbor_cache[neighbor_index].q != NULL)) {
+      /* Free oldest packet (as per RFC recommendation) */
+      r = neighbor_cache[neighbor_index].q;
+      neighbor_cache[neighbor_index].q = r->next;
+      r->next = NULL;
+      nd6_free_q(r);
+      new_entry = (struct nd6_q_entry *)memp_malloc(MEMP_ND6_QUEUE);
+    }
+    if (new_entry != NULL) {
+      new_entry->next = NULL;
+      new_entry->p = p;
+      if (neighbor_cache[neighbor_index].q != NULL) {
+        /* queue was already existent, append the new entry to the end */
+        r = neighbor_cache[neighbor_index].q;
+        while (r->next != NULL) {
+          r = r->next;
+        }
+        r->next = new_entry;
+      } else {
+        /* queue did not exist, first item in queue */
+        neighbor_cache[neighbor_index].q = new_entry;
+      }
+      LWIP_DEBUGF(LWIP_DBG_TRACE, ("ipv6: queued packet %p on neighbor entry %"S16_F"\n", (void *)p, (s16_t)neighbor_index));
+      result = ERR_OK;
+    } else {
+      /* the pool MEMP_ND6_QUEUE is empty */
+      pbuf_free(p);
+      LWIP_DEBUGF(LWIP_DBG_TRACE, ("ipv6: could not queue a copy of packet %p (out of memory)\n", (void *)p));
+      /* { result == ERR_MEM } through initialization */
+    }
+#else /* LWIP_ND6_QUEUEING */
+    /* Queue a single packet. If an older packet is already queued, free it as per RFC. */
+    if (neighbor_cache[neighbor_index].q != NULL) {
+      pbuf_free(neighbor_cache[neighbor_index].q);
+    }
+    neighbor_cache[neighbor_index].q = p;
+    LWIP_DEBUGF(LWIP_DBG_TRACE, ("ipv6: queued packet %p on neighbor entry %"S16_F"\n", (void *)p, (s16_t)neighbor_index));
+    result = ERR_OK;
+#endif /* LWIP_ND6_QUEUEING */
+  } else {
+    LWIP_DEBUGF(LWIP_DBG_TRACE, ("ipv6: could not queue a copy of packet %p (out of memory)\n", (void *)q));
+    /* { result == ERR_MEM } through initialization */
+  }
+
+  return result;
+}
+
+#if LWIP_ND6_QUEUEING
+/**
+ * Free a complete queue of nd6 q entries
+ *
+ * @param q a queue of nd6_q_entry to free
+ */
+static void
+nd6_free_q(struct nd6_q_entry *q)
+{
+  struct nd6_q_entry *r;
+  LWIP_ASSERT("q != NULL", q != NULL);
+  LWIP_ASSERT("q->p != NULL", q->p != NULL);
+  while (q) {
+    r = q;
+    q = q->next;
+    LWIP_ASSERT("r->p != NULL", (r->p != NULL));
+    pbuf_free(r->p);
+    memp_free(MEMP_ND6_QUEUE, r);
+  }
+}
+#endif /* LWIP_ND6_QUEUEING */
+
+/**
+ * Send queued packets for a neighbor
+ *
+ * @param i the neighbor to send packets to
+ */
+static void
+nd6_send_q(s8_t i)
+{
+  struct ip6_hdr *ip6hdr;
+  ip6_addr_t dest;
+#if LWIP_ND6_QUEUEING
+  struct nd6_q_entry *q;
+#endif /* LWIP_ND6_QUEUEING */
+
+  if ((i < 0) || (i >= LWIP_ND6_NUM_NEIGHBORS)) {
+    return;
+  }
+
+#if LWIP_ND6_QUEUEING
+  while (neighbor_cache[i].q != NULL) {
+    /* remember first in queue */
+    q = neighbor_cache[i].q;
+    /* pop first item off the queue */
+    neighbor_cache[i].q = q->next;
+    /* Get ipv6 header. */
+    ip6hdr = (struct ip6_hdr *)(q->p->payload);
+    /* Create an aligned copy. */
+    ip6_addr_copy_from_packed(dest, ip6hdr->dest);
+    /* Restore the zone, if applicable. */
+    ip6_addr_assign_zone(&dest, IP6_UNKNOWN, neighbor_cache[i].netif);
+    /* send the queued IPv6 packet */
+    (neighbor_cache[i].netif)->output_ip6(neighbor_cache[i].netif, q->p, &dest);
+    /* free the queued IP packet */
+    pbuf_free(q->p);
+    /* now queue entry can be freed */
+    memp_free(MEMP_ND6_QUEUE, q);
+  }
+#else /* LWIP_ND6_QUEUEING */
+  if (neighbor_cache[i].q != NULL) {
+    /* Get ipv6 header. */
+    ip6hdr = (struct ip6_hdr *)(neighbor_cache[i].q->payload);
+    /* Create an aligned copy. */
+    ip6_addr_copy_from_packed(dest, ip6hdr->dest);
+    /* Restore the zone, if applicable. */
+    ip6_addr_assign_zone(&dest, IP6_UNKNOWN, neighbor_cache[i].netif);
+    /* send the queued IPv6 packet */
+    (neighbor_cache[i].netif)->output_ip6(neighbor_cache[i].netif, neighbor_cache[i].q, &dest);
+    /* free the queued IP packet */
+    pbuf_free(neighbor_cache[i].q);
+    neighbor_cache[i].q = NULL;
+  }
+#endif /* LWIP_ND6_QUEUEING */
+}
+
+/**
+ * A packet is to be transmitted to a specific IPv6 destination on a specific
+ * interface. Check if we can find the hardware address of the next hop to use
+ * for the packet. If so, give the hardware address to the caller, which should
+ * use it to send the packet right away. Otherwise, enqueue the packet for
+ * later transmission while looking up the hardware address, if possible.
+ *
+ * As such, this function returns one of three different possible results:
+ *
+ * - ERR_OK with a non-NULL 'hwaddrp': the caller should send the packet now.
+ * - ERR_OK with a NULL 'hwaddrp': the packet has been enqueued for later.
+ * - not ERR_OK: something went wrong; forward the error upward in the stack.
+ *
+ * @param netif The lwIP network interface on which the IP packet will be sent.
+ * @param q The pbuf(s) containing the IP packet to be sent.
+ * @param ip6addr The destination IPv6 address of the packet.
+ * @param hwaddrp On success, filled with a pointer to a HW address or NULL (meaning
+ *        the packet has been queued).
+ * @return
+ * - ERR_OK on success, ERR_RTE if no route was found for the packet,
+ * or ERR_MEM if low memory conditions prohibit sending the packet at all.
+ */
+err_t
+nd6_get_next_hop_addr_or_queue(struct netif *netif, struct pbuf *q, const ip6_addr_t *ip6addr, const u8_t **hwaddrp)
+{
+  s8_t i;
+
+  /* Get next hop record. */
+  i = nd6_get_next_hop_entry(ip6addr, netif);
+  if (i < 0) {
+    /* failed to get a next hop neighbor record. */
+    return i;
+  }
+
+  /* Now that we have a destination record, send or queue the packet. */
+  if (neighbor_cache[i].state == ND6_STALE) {
+    /* Switch to delay state. */
+    neighbor_cache[i].state = ND6_DELAY;
+    neighbor_cache[i].counter.delay_time = LWIP_ND6_DELAY_FIRST_PROBE_TIME / ND6_TMR_INTERVAL;
+  }
+  /* @todo should we send or queue if PROBE? send for now, to let unicast NS pass. */
+  if ((neighbor_cache[i].state == ND6_REACHABLE) ||
+      (neighbor_cache[i].state == ND6_DELAY) ||
+      (neighbor_cache[i].state == ND6_PROBE)) {
+
+    /* Tell the caller to send out the packet now. */
+    *hwaddrp = neighbor_cache[i].lladdr;
+    return ERR_OK;
+  }
+
+  /* We should queue packet on this interface. */
+  *hwaddrp = NULL;
+  return nd6_queue_packet(i, q);
+}
+
+
+/**
+ * Get the Path MTU for a destination.
+ *
+ * @param ip6addr the destination address
+ * @param netif the netif on which the packet will be sent
+ * @return the Path MTU, if known, or the netif default MTU
+ */
+u16_t
+nd6_get_destination_mtu(const ip6_addr_t *ip6addr, struct netif *netif)
+{
+  s16_t i;
+
+  i = nd6_find_destination_cache_entry(ip6addr);
+  if (i >= 0) {
+    if (destination_cache[i].pmtu > 0) {
+      return destination_cache[i].pmtu;
+    }
+  }
+
+  if (netif != NULL) {
+    return netif_mtu6(netif);
+  }
+
+  return 1280; /* Minimum MTU */
+}
+
+
+#if LWIP_ND6_TCP_REACHABILITY_HINTS
+/**
+ * Provide the Neighbor discovery process with a hint that a
+ * destination is reachable. Called by tcp_receive when ACKs are
+ * received or sent (as per RFC). This is useful to avoid sending
+ * NS messages every 30 seconds.
+ *
+ * @param ip6addr the destination address which is know to be reachable
+ *                by an upper layer protocol (TCP)
+ */
+void
+nd6_reachability_hint(const ip6_addr_t *ip6addr)
+{
+  s8_t i;
+  s16_t dst_idx;
+
+  /* Find destination in cache. */
+  if (ip6_addr_cmp(ip6addr, &(destination_cache[nd6_cached_destination_index].destination_addr))) {
+    dst_idx = nd6_cached_destination_index;
+    ND6_STATS_INC(nd6.cachehit);
+  } else {
+    dst_idx = nd6_find_destination_cache_entry(ip6addr);
+  }
+  if (dst_idx < 0) {
+    return;
+  }
+
+  /* Find next hop neighbor in cache. */
+  if (ip6_addr_cmp(&(destination_cache[dst_idx].next_hop_addr), &(neighbor_cache[nd6_cached_neighbor_index].next_hop_address))) {
+    i = nd6_cached_neighbor_index;
+    ND6_STATS_INC(nd6.cachehit);
+  } else {
+    i = nd6_find_neighbor_cache_entry(&(destination_cache[dst_idx].next_hop_addr));
+  }
+  if (i < 0) {
+    return;
+  }
+
+  /* For safety: don't set as reachable if we don't have a LL address yet. Misuse protection. */
+  if (neighbor_cache[i].state == ND6_INCOMPLETE || neighbor_cache[i].state == ND6_NO_ENTRY) {
+    return;
+  }
+
+  /* Set reachability state. */
+  neighbor_cache[i].state = ND6_REACHABLE;
+  neighbor_cache[i].counter.reachable_time = reachable_time;
+}
+#endif /* LWIP_ND6_TCP_REACHABILITY_HINTS */
+
+/**
+ * Remove all prefix, neighbor_cache and router entries of the specified netif.
+ *
+ * @param netif points to a network interface
+ */
+void
+nd6_cleanup_netif(struct netif *netif)
+{
+  u8_t i;
+  s8_t router_index;
+  for (i = 0; i < LWIP_ND6_NUM_PREFIXES; i++) {
+    if (prefix_list[i].netif == netif) {
+      prefix_list[i].netif = NULL;
+    }
+  }
+  for (i = 0; i < LWIP_ND6_NUM_NEIGHBORS; i++) {
+    if (neighbor_cache[i].netif == netif) {
+      for (router_index = 0; router_index < LWIP_ND6_NUM_ROUTERS; router_index++) {
+        if (default_router_list[router_index].neighbor_entry == &neighbor_cache[i]) {
+          default_router_list[router_index].neighbor_entry = NULL;
+          default_router_list[router_index].flags = 0;
+        }
+      }
+      neighbor_cache[i].isrouter = 0;
+      nd6_free_neighbor_cache_entry(i);
+    }
+  }
+  /* Clear the destination cache, since many entries may now have become
+   * invalid for one of several reasons. As destination cache entries have no
+   * netif association, use a sledgehammer approach (this can be improved). */
+  nd6_clear_destination_cache();
+}
+
+#if LWIP_IPV6_MLD
+/**
+ * The state of a local IPv6 address entry is about to change. If needed, join
+ * or leave the solicited-node multicast group for the address.
+ *
+ * @param netif The netif that owns the address.
+ * @param addr_idx The index of the address.
+ * @param new_state The new (IP6_ADDR_) state for the address.
+ */
+void
+nd6_adjust_mld_membership(struct netif *netif, s8_t addr_idx, u8_t new_state)
+{
+  u8_t old_state, old_member, new_member;
+
+  old_state = netif_ip6_addr_state(netif, addr_idx);
+
+  /* Determine whether we were, and should be, a member of the solicited-node
+   * multicast group for this address. For tentative addresses, the group is
+   * not joined until the address enters the TENTATIVE_1 (or VALID) state. */
+  old_member = (old_state != IP6_ADDR_INVALID && old_state != IP6_ADDR_DUPLICATED && old_state != IP6_ADDR_TENTATIVE);
+  new_member = (new_state != IP6_ADDR_INVALID && new_state != IP6_ADDR_DUPLICATED && new_state != IP6_ADDR_TENTATIVE);
+
+  if (old_member != new_member) {
+    ip6_addr_set_solicitednode(&multicast_address, netif_ip6_addr(netif, addr_idx)->addr[3]);
+    ip6_addr_assign_zone(&multicast_address, IP6_MULTICAST, netif);
+
+    if (new_member) {
+      mld6_joingroup_netif(netif, &multicast_address);
+    } else {
+      mld6_leavegroup_netif(netif, &multicast_address);
+    }
+  }
+}
+#endif /* LWIP_IPV6_MLD */
+
+/** Netif was added, set up, or reconnected (link up) */
+void
+nd6_restart_netif(struct netif *netif)
+{
+#if LWIP_IPV6_SEND_ROUTER_SOLICIT
+  /* Send Router Solicitation messages (see RFC 4861, ch. 6.3.7). */
+  netif->rs_count = LWIP_ND6_MAX_MULTICAST_SOLICIT;
+#endif /* LWIP_IPV6_SEND_ROUTER_SOLICIT */
+}
+
+#endif /* LWIP_IPV6 */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/core/mem.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/core/mem.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/core/mem.c	(revision 457)
@@ -0,0 +1,1017 @@
+/**
+ * @file
+ * Dynamic memory manager
+ *
+ * This is a lightweight replacement for the standard C library malloc().
+ *
+ * If you want to use the standard C library malloc() instead, define
+ * MEM_LIBC_MALLOC to 1 in your lwipopts.h
+ *
+ * To let mem_malloc() use pools (prevents fragmentation and is much faster than
+ * a heap but might waste some memory), define MEM_USE_POOLS to 1, define
+ * MEMP_USE_CUSTOM_POOLS to 1 and create a file "lwippools.h" that includes a list
+ * of pools like this (more pools can be added between _START and _END):
+ *
+ * Define three pools with sizes 256, 512, and 1512 bytes
+ * LWIP_MALLOC_MEMPOOL_START
+ * LWIP_MALLOC_MEMPOOL(20, 256)
+ * LWIP_MALLOC_MEMPOOL(10, 512)
+ * LWIP_MALLOC_MEMPOOL(5, 1512)
+ * LWIP_MALLOC_MEMPOOL_END
+ */
+
+/*
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Adam Dunkels <adam@sics.se>
+ *         Simon Goldschmidt
+ *
+ */
+
+#include "lwip/opt.h"
+#include "lwip/mem.h"
+#include "lwip/def.h"
+#include "lwip/sys.h"
+#include "lwip/stats.h"
+#include "lwip/err.h"
+
+#include <string.h>
+
+#if MEM_LIBC_MALLOC
+#include <stdlib.h> /* for malloc()/free() */
+#endif
+
+/* This is overridable for tests only... */
+#ifndef LWIP_MEM_ILLEGAL_FREE
+#define LWIP_MEM_ILLEGAL_FREE(msg)         LWIP_ASSERT(msg, 0)
+#endif
+
+#define MEM_STATS_INC_LOCKED(x)         SYS_ARCH_LOCKED(MEM_STATS_INC(x))
+#define MEM_STATS_INC_USED_LOCKED(x, y) SYS_ARCH_LOCKED(MEM_STATS_INC_USED(x, y))
+#define MEM_STATS_DEC_USED_LOCKED(x, y) SYS_ARCH_LOCKED(MEM_STATS_DEC_USED(x, y))
+
+#if MEM_OVERFLOW_CHECK
+#define MEM_SANITY_OFFSET   MEM_SANITY_REGION_BEFORE_ALIGNED
+#define MEM_SANITY_OVERHEAD (MEM_SANITY_REGION_BEFORE_ALIGNED + MEM_SANITY_REGION_AFTER_ALIGNED)
+#else
+#define MEM_SANITY_OFFSET   0
+#define MEM_SANITY_OVERHEAD 0
+#endif
+
+#if MEM_OVERFLOW_CHECK || MEMP_OVERFLOW_CHECK
+/**
+ * Check if a mep element was victim of an overflow or underflow
+ * (e.g. the restricted area after/before it has been altered)
+ *
+ * @param p the mem element to check
+ * @param size allocated size of the element
+ * @param descr1 description of the element source shown on error
+ * @param descr2 description of the element source shown on error
+ */
+void
+mem_overflow_check_raw(void *p, size_t size, const char *descr1, const char *descr2)
+{
+#if MEM_SANITY_REGION_AFTER_ALIGNED || MEM_SANITY_REGION_BEFORE_ALIGNED
+  u16_t k;
+  u8_t *m;
+
+#if MEM_SANITY_REGION_AFTER_ALIGNED > 0
+  m = (u8_t *)p + size;
+  for (k = 0; k < MEM_SANITY_REGION_AFTER_ALIGNED; k++) {
+    if (m[k] != 0xcd) {
+      char errstr[128];
+      snprintf(errstr, sizeof(errstr), "detected mem overflow in %s%s", descr1, descr2);
+      LWIP_ASSERT(errstr, 0);
+    }
+  }
+#endif /* MEM_SANITY_REGION_AFTER_ALIGNED > 0 */
+
+#if MEM_SANITY_REGION_BEFORE_ALIGNED > 0
+  m = (u8_t *)p - MEM_SANITY_REGION_BEFORE_ALIGNED;
+  for (k = 0; k < MEM_SANITY_REGION_BEFORE_ALIGNED; k++) {
+    if (m[k] != 0xcd) {
+      char errstr[128];
+      snprintf(errstr, sizeof(errstr), "detected mem underflow in %s%s", descr1, descr2);
+      LWIP_ASSERT(errstr, 0);
+    }
+  }
+#endif /* MEM_SANITY_REGION_BEFORE_ALIGNED > 0 */
+#else
+  LWIP_UNUSED_ARG(p);
+  LWIP_UNUSED_ARG(desc);
+  LWIP_UNUSED_ARG(descr);
+#endif
+}
+
+/**
+ * Initialize the restricted area of a mem element.
+ */
+void
+mem_overflow_init_raw(void *p, size_t size)
+{
+#if MEM_SANITY_REGION_BEFORE_ALIGNED > 0 || MEM_SANITY_REGION_AFTER_ALIGNED > 0
+  u8_t *m;
+#if MEM_SANITY_REGION_BEFORE_ALIGNED > 0
+  m = (u8_t *)p - MEM_SANITY_REGION_BEFORE_ALIGNED;
+  memset(m, 0xcd, MEM_SANITY_REGION_BEFORE_ALIGNED);
+#endif
+#if MEM_SANITY_REGION_AFTER_ALIGNED > 0
+  m = (u8_t *)p + size;
+  memset(m, 0xcd, MEM_SANITY_REGION_AFTER_ALIGNED);
+#endif
+#else /* MEM_SANITY_REGION_BEFORE_ALIGNED > 0 || MEM_SANITY_REGION_AFTER_ALIGNED > 0 */
+  LWIP_UNUSED_ARG(p);
+  LWIP_UNUSED_ARG(desc);
+#endif /* MEM_SANITY_REGION_BEFORE_ALIGNED > 0 || MEM_SANITY_REGION_AFTER_ALIGNED > 0 */
+}
+#endif /* MEM_OVERFLOW_CHECK || MEMP_OVERFLOW_CHECK */
+
+#if MEM_LIBC_MALLOC || MEM_USE_POOLS
+
+/** mem_init is not used when using pools instead of a heap or using
+ * C library malloc().
+ */
+void
+mem_init(void)
+{
+}
+
+/** mem_trim is not used when using pools instead of a heap or using
+ * C library malloc(): we can't free part of a pool element and the stack
+ * support mem_trim() to return a different pointer
+ */
+void *
+mem_trim(void *mem, mem_size_t size)
+{
+  LWIP_UNUSED_ARG(size);
+  return mem;
+}
+#endif /* MEM_LIBC_MALLOC || MEM_USE_POOLS */
+
+#if MEM_LIBC_MALLOC
+/* lwIP heap implemented using C library malloc() */
+
+/* in case C library malloc() needs extra protection,
+ * allow these defines to be overridden.
+ */
+#ifndef mem_clib_free
+#define mem_clib_free free
+#endif
+#ifndef mem_clib_malloc
+#define mem_clib_malloc malloc
+#endif
+#ifndef mem_clib_calloc
+#define mem_clib_calloc calloc
+#endif
+
+#if LWIP_STATS && MEM_STATS
+#define MEM_LIBC_STATSHELPER_SIZE LWIP_MEM_ALIGN_SIZE(sizeof(mem_size_t))
+#else
+#define MEM_LIBC_STATSHELPER_SIZE 0
+#endif
+
+/**
+ * Allocate a block of memory with a minimum of 'size' bytes.
+ *
+ * @param size is the minimum size of the requested block in bytes.
+ * @return pointer to allocated memory or NULL if no free memory was found.
+ *
+ * Note that the returned value must always be aligned (as defined by MEM_ALIGNMENT).
+ */
+void *
+mem_malloc(mem_size_t size)
+{
+  void *ret = mem_clib_malloc(size + MEM_LIBC_STATSHELPER_SIZE);
+  if (ret == NULL) {
+    MEM_STATS_INC_LOCKED(err);
+  } else {
+    LWIP_ASSERT("malloc() must return aligned memory", LWIP_MEM_ALIGN(ret) == ret);
+#if LWIP_STATS && MEM_STATS
+    *(mem_size_t *)ret = size;
+    ret = (u8_t *)ret + MEM_LIBC_STATSHELPER_SIZE;
+    MEM_STATS_INC_USED_LOCKED(used, size);
+#endif
+  }
+  return ret;
+}
+
+/** Put memory back on the heap
+ *
+ * @param rmem is the pointer as returned by a previous call to mem_malloc()
+ */
+void
+mem_free(void *rmem)
+{
+  LWIP_ASSERT("rmem != NULL", (rmem != NULL));
+  LWIP_ASSERT("rmem == MEM_ALIGN(rmem)", (rmem == LWIP_MEM_ALIGN(rmem)));
+#if LWIP_STATS && MEM_STATS
+  rmem = (u8_t *)rmem - MEM_LIBC_STATSHELPER_SIZE;
+  MEM_STATS_DEC_USED_LOCKED(used, *(mem_size_t *)rmem);
+#endif
+  mem_clib_free(rmem);
+}
+
+#elif MEM_USE_POOLS
+
+/* lwIP heap implemented with different sized pools */
+
+/**
+ * Allocate memory: determine the smallest pool that is big enough
+ * to contain an element of 'size' and get an element from that pool.
+ *
+ * @param size the size in bytes of the memory needed
+ * @return a pointer to the allocated memory or NULL if the pool is empty
+ */
+void *
+mem_malloc(mem_size_t size)
+{
+  void *ret;
+  struct memp_malloc_helper *element = NULL;
+  memp_t poolnr;
+  mem_size_t required_size = size + LWIP_MEM_ALIGN_SIZE(sizeof(struct memp_malloc_helper));
+
+  for (poolnr = MEMP_POOL_FIRST; poolnr <= MEMP_POOL_LAST; poolnr = (memp_t)(poolnr + 1)) {
+    /* is this pool big enough to hold an element of the required size
+       plus a struct memp_malloc_helper that saves the pool this element came from? */
+    if (required_size <= memp_pools[poolnr]->size) {
+      element = (struct memp_malloc_helper *)memp_malloc(poolnr);
+      if (element == NULL) {
+        /* No need to DEBUGF or ASSERT: This error is already taken care of in memp.c */
+#if MEM_USE_POOLS_TRY_BIGGER_POOL
+        /** Try a bigger pool if this one is empty! */
+        if (poolnr < MEMP_POOL_LAST) {
+          continue;
+        }
+#endif /* MEM_USE_POOLS_TRY_BIGGER_POOL */
+        MEM_STATS_INC_LOCKED(err);
+        return NULL;
+      }
+      break;
+    }
+  }
+  if (poolnr > MEMP_POOL_LAST) {
+    LWIP_ASSERT("mem_malloc(): no pool is that big!", 0);
+    MEM_STATS_INC_LOCKED(err);
+    return NULL;
+  }
+
+  /* save the pool number this element came from */
+  element->poolnr = poolnr;
+  /* and return a pointer to the memory directly after the struct memp_malloc_helper */
+  ret = (u8_t *)element + LWIP_MEM_ALIGN_SIZE(sizeof(struct memp_malloc_helper));
+
+#if MEMP_OVERFLOW_CHECK || (LWIP_STATS && MEM_STATS)
+  /* truncating to u16_t is safe because struct memp_desc::size is u16_t */
+  element->size = (u16_t)size;
+  MEM_STATS_INC_USED_LOCKED(used, element->size);
+#endif /* MEMP_OVERFLOW_CHECK || (LWIP_STATS && MEM_STATS) */
+#if MEMP_OVERFLOW_CHECK
+  /* initialize unused memory (diff between requested size and selected pool's size) */
+  memset((u8_t *)ret + size, 0xcd, memp_pools[poolnr]->size - size);
+#endif /* MEMP_OVERFLOW_CHECK */
+  return ret;
+}
+
+/**
+ * Free memory previously allocated by mem_malloc. Loads the pool number
+ * and calls memp_free with that pool number to put the element back into
+ * its pool
+ *
+ * @param rmem the memory element to free
+ */
+void
+mem_free(void *rmem)
+{
+  struct memp_malloc_helper *hmem;
+
+  LWIP_ASSERT("rmem != NULL", (rmem != NULL));
+  LWIP_ASSERT("rmem == MEM_ALIGN(rmem)", (rmem == LWIP_MEM_ALIGN(rmem)));
+
+  /* get the original struct memp_malloc_helper */
+  /* cast through void* to get rid of alignment warnings */
+  hmem = (struct memp_malloc_helper *)(void *)((u8_t *)rmem - LWIP_MEM_ALIGN_SIZE(sizeof(struct memp_malloc_helper)));
+
+  LWIP_ASSERT("hmem != NULL", (hmem != NULL));
+  LWIP_ASSERT("hmem == MEM_ALIGN(hmem)", (hmem == LWIP_MEM_ALIGN(hmem)));
+  LWIP_ASSERT("hmem->poolnr < MEMP_MAX", (hmem->poolnr < MEMP_MAX));
+
+  MEM_STATS_DEC_USED_LOCKED(used, hmem->size);
+#if MEMP_OVERFLOW_CHECK
+  {
+    u16_t i;
+    LWIP_ASSERT("MEM_USE_POOLS: invalid chunk size",
+                hmem->size <= memp_pools[hmem->poolnr]->size);
+    /* check that unused memory remained untouched (diff between requested size and selected pool's size) */
+    for (i = hmem->size; i < memp_pools[hmem->poolnr]->size; i++) {
+      u8_t data = *((u8_t *)rmem + i);
+      LWIP_ASSERT("MEM_USE_POOLS: mem overflow detected", data == 0xcd);
+    }
+  }
+#endif /* MEMP_OVERFLOW_CHECK */
+
+  /* and put it in the pool we saved earlier */
+  memp_free(hmem->poolnr, hmem);
+}
+
+#else /* MEM_USE_POOLS */
+/* lwIP replacement for your libc malloc() */
+
+/**
+ * The heap is made up as a list of structs of this type.
+ * This does not have to be aligned since for getting its size,
+ * we only use the macro SIZEOF_STRUCT_MEM, which automatically aligns.
+ */
+struct mem {
+  /** index (-> ram[next]) of the next struct */
+  mem_size_t next;
+  /** index (-> ram[prev]) of the previous struct */
+  mem_size_t prev;
+  /** 1: this area is used; 0: this area is unused */
+  u8_t used;
+#if MEM_OVERFLOW_CHECK
+  /** this keeps track of the user allocation size for guard checks */
+  mem_size_t user_size;
+#endif
+};
+
+/** All allocated blocks will be MIN_SIZE bytes big, at least!
+ * MIN_SIZE can be overridden to suit your needs. Smaller values save space,
+ * larger values could prevent too small blocks to fragment the RAM too much. */
+#ifndef MIN_SIZE
+#define MIN_SIZE             12
+#endif /* MIN_SIZE */
+/* some alignment macros: we define them here for better source code layout */
+#define MIN_SIZE_ALIGNED     LWIP_MEM_ALIGN_SIZE(MIN_SIZE)
+#define SIZEOF_STRUCT_MEM    LWIP_MEM_ALIGN_SIZE(sizeof(struct mem))
+#define MEM_SIZE_ALIGNED     LWIP_MEM_ALIGN_SIZE(MEM_SIZE)
+
+/** If you want to relocate the heap to external memory, simply define
+ * LWIP_RAM_HEAP_POINTER as a void-pointer to that location.
+ * If so, make sure the memory at that location is big enough (see below on
+ * how that space is calculated). */
+#ifndef LWIP_RAM_HEAP_POINTER
+/** the heap. we need one struct mem at the end and some room for alignment */
+LWIP_DECLARE_MEMORY_ALIGNED(ram_heap, MEM_SIZE_ALIGNED + (2U * SIZEOF_STRUCT_MEM));
+#define LWIP_RAM_HEAP_POINTER ram_heap
+#endif /* LWIP_RAM_HEAP_POINTER */
+
+/** pointer to the heap (ram_heap): for alignment, ram is now a pointer instead of an array */
+static u8_t *ram;
+/** the last entry, always unused! */
+static struct mem *ram_end;
+
+/** concurrent access protection */
+#if !NO_SYS
+static sys_mutex_t mem_mutex;
+#endif
+
+#if LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT
+
+static volatile u8_t mem_free_count;
+
+/* Allow mem_free from other (e.g. interrupt) context */
+#define LWIP_MEM_FREE_DECL_PROTECT()  SYS_ARCH_DECL_PROTECT(lev_free)
+#define LWIP_MEM_FREE_PROTECT()       SYS_ARCH_PROTECT(lev_free)
+#define LWIP_MEM_FREE_UNPROTECT()     SYS_ARCH_UNPROTECT(lev_free)
+#define LWIP_MEM_ALLOC_DECL_PROTECT() SYS_ARCH_DECL_PROTECT(lev_alloc)
+#define LWIP_MEM_ALLOC_PROTECT()      SYS_ARCH_PROTECT(lev_alloc)
+#define LWIP_MEM_ALLOC_UNPROTECT()    SYS_ARCH_UNPROTECT(lev_alloc)
+#define LWIP_MEM_LFREE_VOLATILE       volatile
+
+#else /* LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT */
+
+/* Protect the heap only by using a mutex */
+#define LWIP_MEM_FREE_DECL_PROTECT()
+#define LWIP_MEM_FREE_PROTECT()    sys_mutex_lock(&mem_mutex)
+#define LWIP_MEM_FREE_UNPROTECT()  sys_mutex_unlock(&mem_mutex)
+/* mem_malloc is protected using mutex AND LWIP_MEM_ALLOC_PROTECT */
+#define LWIP_MEM_ALLOC_DECL_PROTECT()
+#define LWIP_MEM_ALLOC_PROTECT()
+#define LWIP_MEM_ALLOC_UNPROTECT()
+#define LWIP_MEM_LFREE_VOLATILE
+
+#endif /* LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT */
+
+/** pointer to the lowest free block, this is used for faster search */
+static struct mem * LWIP_MEM_LFREE_VOLATILE lfree;
+
+#if MEM_SANITY_CHECK
+static void mem_sanity(void);
+#define MEM_SANITY() mem_sanity()
+#else
+#define MEM_SANITY()
+#endif
+
+#if MEM_OVERFLOW_CHECK
+static void
+mem_overflow_init_element(struct mem *mem, mem_size_t user_size)
+{
+  void *p = (u8_t *)mem + SIZEOF_STRUCT_MEM + MEM_SANITY_OFFSET;
+  mem->user_size = user_size;
+  mem_overflow_init_raw(p, user_size);
+}
+
+static void
+mem_overflow_check_element(struct mem *mem)
+{
+  void *p = (u8_t *)mem + SIZEOF_STRUCT_MEM + MEM_SANITY_OFFSET;
+  mem_overflow_check_raw(p, mem->user_size, "heap", "");
+}
+#else /* MEM_OVERFLOW_CHECK */
+#define mem_overflow_init_element(mem, size)
+#define mem_overflow_check_element(mem)
+#endif /* MEM_OVERFLOW_CHECK */
+
+static struct mem *
+ptr_to_mem(mem_size_t ptr)
+{
+  return (struct mem *)(void *)&ram[ptr];
+}
+
+static mem_size_t
+mem_to_ptr(void *mem)
+{
+  return (mem_size_t)((u8_t *)mem - ram);
+}
+
+/**
+ * "Plug holes" by combining adjacent empty struct mems.
+ * After this function is through, there should not exist
+ * one empty struct mem pointing to another empty struct mem.
+ *
+ * @param mem this points to a struct mem which just has been freed
+ * @internal this function is only called by mem_free() and mem_trim()
+ *
+ * This assumes access to the heap is protected by the calling function
+ * already.
+ */
+static void
+plug_holes(struct mem *mem)
+{
+  struct mem *nmem;
+  struct mem *pmem;
+
+  LWIP_ASSERT("plug_holes: mem >= ram", (u8_t *)mem >= ram);
+  LWIP_ASSERT("plug_holes: mem < ram_end", (u8_t *)mem < (u8_t *)ram_end);
+  LWIP_ASSERT("plug_holes: mem->used == 0", mem->used == 0);
+
+  /* plug hole forward */
+  LWIP_ASSERT("plug_holes: mem->next <= MEM_SIZE_ALIGNED", mem->next <= MEM_SIZE_ALIGNED);
+
+  nmem = ptr_to_mem(mem->next);
+  if (mem != nmem && nmem->used == 0 && (u8_t *)nmem != (u8_t *)ram_end) {
+    /* if mem->next is unused and not end of ram, combine mem and mem->next */
+    if (lfree == nmem) {
+      lfree = mem;
+    }
+    mem->next = nmem->next;
+    if (nmem->next != MEM_SIZE_ALIGNED) {
+      ptr_to_mem(nmem->next)->prev = mem_to_ptr(mem);
+    }
+  }
+
+  /* plug hole backward */
+  pmem = ptr_to_mem(mem->prev);
+  if (pmem != mem && pmem->used == 0) {
+    /* if mem->prev is unused, combine mem and mem->prev */
+    if (lfree == mem) {
+      lfree = pmem;
+    }
+    pmem->next = mem->next;
+    if (mem->next != MEM_SIZE_ALIGNED) {
+      ptr_to_mem(mem->next)->prev = mem_to_ptr(pmem);
+    }
+  }
+}
+
+/**
+ * Zero the heap and initialize start, end and lowest-free
+ */
+void
+mem_init(void)
+{
+  struct mem *mem;
+
+  LWIP_ASSERT("Sanity check alignment",
+              (SIZEOF_STRUCT_MEM & (MEM_ALIGNMENT - 1)) == 0);
+
+  /* align the heap */
+  ram = (u8_t *)LWIP_MEM_ALIGN(LWIP_RAM_HEAP_POINTER);
+  /* initialize the start of the heap */
+  mem = (struct mem *)(void *)ram;
+  mem->next = MEM_SIZE_ALIGNED;
+  mem->prev = 0;
+  mem->used = 0;
+  /* initialize the end of the heap */
+  ram_end = ptr_to_mem(MEM_SIZE_ALIGNED);
+  ram_end->used = 1;
+  ram_end->next = MEM_SIZE_ALIGNED;
+  ram_end->prev = MEM_SIZE_ALIGNED;
+  MEM_SANITY();
+
+  /* initialize the lowest-free pointer to the start of the heap */
+  lfree = (struct mem *)(void *)ram;
+
+  MEM_STATS_AVAIL(avail, MEM_SIZE_ALIGNED);
+
+  if (sys_mutex_new(&mem_mutex) != ERR_OK) {
+    LWIP_ASSERT("failed to create mem_mutex", 0);
+  }
+}
+
+/* Check if a struct mem is correctly linked.
+ * If not, double-free is a possible reason.
+ */
+static int
+mem_link_valid(struct mem *mem)
+{
+  struct mem *nmem, *pmem;
+  mem_size_t rmem_idx;
+  rmem_idx = mem_to_ptr(mem);
+  nmem = ptr_to_mem(mem->next);
+  pmem = ptr_to_mem(mem->prev);
+  if ((mem->next > MEM_SIZE_ALIGNED) || (mem->prev > MEM_SIZE_ALIGNED) ||
+      ((mem->prev != rmem_idx) && (pmem->next != rmem_idx)) ||
+      ((nmem != ram_end) && (nmem->prev != rmem_idx))) {
+    return 0;
+  }
+  return 1;
+}
+
+#if MEM_SANITY_CHECK
+static void
+mem_sanity(void)
+{
+  struct mem *mem;
+  u8_t last_used;
+
+  /* begin with first element here */
+  mem = (struct mem *)ram;
+  LWIP_ASSERT("heap element used valid", (mem->used == 0) || (mem->used == 1));
+  last_used = mem->used;
+  LWIP_ASSERT("heap element prev ptr valid", mem->prev == 0);
+  LWIP_ASSERT("heap element next ptr valid", mem->next <= MEM_SIZE_ALIGNED);
+  LWIP_ASSERT("heap element next ptr aligned", LWIP_MEM_ALIGN(ptr_to_mem(mem->next) == ptr_to_mem(mem->next)));
+
+  /* check all elements before the end of the heap */
+  for (mem = ptr_to_mem(mem->next);
+       ((u8_t *)mem > ram) && (mem < ram_end);
+       mem = ptr_to_mem(mem->next)) {
+    LWIP_ASSERT("heap element aligned", LWIP_MEM_ALIGN(mem) == mem);
+    LWIP_ASSERT("heap element prev ptr valid", mem->prev <= MEM_SIZE_ALIGNED);
+    LWIP_ASSERT("heap element next ptr valid", mem->next <= MEM_SIZE_ALIGNED);
+    LWIP_ASSERT("heap element prev ptr aligned", LWIP_MEM_ALIGN(ptr_to_mem(mem->prev) == ptr_to_mem(mem->prev)));
+    LWIP_ASSERT("heap element next ptr aligned", LWIP_MEM_ALIGN(ptr_to_mem(mem->next) == ptr_to_mem(mem->next)));
+
+    if (last_used == 0) {
+      /* 2 unused elements in a row? */
+      LWIP_ASSERT("heap element unused?", mem->used == 1);
+    } else {
+      LWIP_ASSERT("heap element unused member", (mem->used == 0) || (mem->used == 1));
+    }
+
+    LWIP_ASSERT("heap element link valid", mem_link_valid(mem));
+
+    /* used/unused altering */
+    last_used = mem->used;
+  }
+  LWIP_ASSERT("heap end ptr sanity", mem == ptr_to_mem(MEM_SIZE_ALIGNED));
+  LWIP_ASSERT("heap element used valid", mem->used == 1);
+  LWIP_ASSERT("heap element prev ptr valid", mem->prev == MEM_SIZE_ALIGNED);
+  LWIP_ASSERT("heap element next ptr valid", mem->next == MEM_SIZE_ALIGNED);
+}
+#endif /* MEM_SANITY_CHECK */
+
+/**
+ * Put a struct mem back on the heap
+ *
+ * @param rmem is the data portion of a struct mem as returned by a previous
+ *             call to mem_malloc()
+ */
+void
+mem_free(void *rmem)
+{
+  struct mem *mem;
+  LWIP_MEM_FREE_DECL_PROTECT();
+
+  if (rmem == NULL) {
+    LWIP_DEBUGF(MEM_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS, ("mem_free(p == NULL) was called.\n"));
+    return;
+  }
+  if ((((mem_ptr_t)rmem) & (MEM_ALIGNMENT - 1)) != 0) {
+    LWIP_MEM_ILLEGAL_FREE("mem_free: sanity check alignment");
+    LWIP_DEBUGF(MEM_DEBUG | LWIP_DBG_LEVEL_SEVERE, ("mem_free: sanity check alignment\n"));
+    /* protect mem stats from concurrent access */
+    MEM_STATS_INC_LOCKED(illegal);
+    return;
+  }
+
+  /* Get the corresponding struct mem: */
+  /* cast through void* to get rid of alignment warnings */
+  mem = (struct mem *)(void *)((u8_t *)rmem - (SIZEOF_STRUCT_MEM + MEM_SANITY_OFFSET));
+
+  if ((u8_t *)mem < ram || (u8_t *)rmem + MIN_SIZE_ALIGNED > (u8_t *)ram_end) {
+    LWIP_MEM_ILLEGAL_FREE("mem_free: illegal memory");
+    LWIP_DEBUGF(MEM_DEBUG | LWIP_DBG_LEVEL_SEVERE, ("mem_free: illegal memory\n"));
+    /* protect mem stats from concurrent access */
+    MEM_STATS_INC_LOCKED(illegal);
+    return;
+  }
+#if MEM_OVERFLOW_CHECK
+  mem_overflow_check_element(mem);
+#endif
+  /* protect the heap from concurrent access */
+  LWIP_MEM_FREE_PROTECT();
+  /* mem has to be in a used state */
+  if (!mem->used) {
+    LWIP_MEM_ILLEGAL_FREE("mem_free: illegal memory: double free");
+    LWIP_MEM_FREE_UNPROTECT();
+    LWIP_DEBUGF(MEM_DEBUG | LWIP_DBG_LEVEL_SEVERE, ("mem_free: illegal memory: double free?\n"));
+    /* protect mem stats from concurrent access */
+    MEM_STATS_INC_LOCKED(illegal);
+    return;
+  }
+
+  if (!mem_link_valid(mem)) {
+    LWIP_MEM_ILLEGAL_FREE("mem_free: illegal memory: non-linked: double free");
+    LWIP_MEM_FREE_UNPROTECT();
+    LWIP_DEBUGF(MEM_DEBUG | LWIP_DBG_LEVEL_SEVERE, ("mem_free: illegal memory: non-linked: double free?\n"));
+    /* protect mem stats from concurrent access */
+    MEM_STATS_INC_LOCKED(illegal);
+    return;
+  }
+
+  /* mem is now unused. */
+  mem->used = 0;
+
+  if (mem < lfree) {
+    /* the newly freed struct is now the lowest */
+    lfree = mem;
+  }
+
+  MEM_STATS_DEC_USED(used, mem->next - (mem_size_t)(((u8_t *)mem - ram)));
+
+  /* finally, see if prev or next are free also */
+  plug_holes(mem);
+  MEM_SANITY();
+#if LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT
+  mem_free_count = 1;
+#endif /* LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT */
+  LWIP_MEM_FREE_UNPROTECT();
+}
+
+/**
+ * Shrink memory returned by mem_malloc().
+ *
+ * @param rmem pointer to memory allocated by mem_malloc the is to be shrinked
+ * @param new_size required size after shrinking (needs to be smaller than or
+ *                equal to the previous size)
+ * @return for compatibility reasons: is always == rmem, at the moment
+ *         or NULL if newsize is > old size, in which case rmem is NOT touched
+ *         or freed!
+ */
+void *
+mem_trim(void *rmem, mem_size_t new_size)
+{
+  mem_size_t size, newsize;
+  mem_size_t ptr, ptr2;
+  struct mem *mem, *mem2;
+  /* use the FREE_PROTECT here: it protects with sem OR SYS_ARCH_PROTECT */
+  LWIP_MEM_FREE_DECL_PROTECT();
+
+  /* Expand the size of the allocated memory region so that we can
+     adjust for alignment. */
+  newsize = (mem_size_t)LWIP_MEM_ALIGN_SIZE(new_size);
+  if (newsize < MIN_SIZE_ALIGNED) {
+    /* every data block must be at least MIN_SIZE_ALIGNED long */
+    newsize = MIN_SIZE_ALIGNED;
+  }
+#if MEM_OVERFLOW_CHECK
+  newsize += MEM_SANITY_REGION_BEFORE_ALIGNED + MEM_SANITY_REGION_AFTER_ALIGNED;
+#endif
+  if ((newsize > MEM_SIZE_ALIGNED) || (newsize < new_size)) {
+    return NULL;
+  }
+
+  LWIP_ASSERT("mem_trim: legal memory", (u8_t *)rmem >= (u8_t *)ram &&
+              (u8_t *)rmem < (u8_t *)ram_end);
+
+  if ((u8_t *)rmem < (u8_t *)ram || (u8_t *)rmem >= (u8_t *)ram_end) {
+    LWIP_DEBUGF(MEM_DEBUG | LWIP_DBG_LEVEL_SEVERE, ("mem_trim: illegal memory\n"));
+    /* protect mem stats from concurrent access */
+    MEM_STATS_INC_LOCKED(illegal);
+    return rmem;
+  }
+  /* Get the corresponding struct mem ... */
+  /* cast through void* to get rid of alignment warnings */
+  mem = (struct mem *)(void *)((u8_t *)rmem - (SIZEOF_STRUCT_MEM + MEM_SANITY_OFFSET));
+#if MEM_OVERFLOW_CHECK
+  mem_overflow_check_element(mem);
+#endif
+  /* ... and its offset pointer */
+  ptr = mem_to_ptr(mem);
+
+  size = (mem_size_t)((mem_size_t)(mem->next - ptr) - (SIZEOF_STRUCT_MEM + MEM_SANITY_OVERHEAD));
+  LWIP_ASSERT("mem_trim can only shrink memory", newsize <= size);
+  if (newsize > size) {
+    /* not supported */
+    return NULL;
+  }
+  if (newsize == size) {
+    /* No change in size, simply return */
+    return rmem;
+  }
+
+  /* protect the heap from concurrent access */
+  LWIP_MEM_FREE_PROTECT();
+
+  mem2 = ptr_to_mem(mem->next);
+  if (mem2->used == 0) {
+    /* The next struct is unused, we can simply move it at little */
+    mem_size_t next;
+    LWIP_ASSERT("invalid next ptr", mem->next != MEM_SIZE_ALIGNED);
+    /* remember the old next pointer */
+    next = mem2->next;
+    /* create new struct mem which is moved directly after the shrinked mem */
+    ptr2 = (mem_size_t)(ptr + SIZEOF_STRUCT_MEM + newsize);
+    if (lfree == mem2) {
+      lfree = ptr_to_mem(ptr2);
+    }
+    mem2 = ptr_to_mem(ptr2);
+    mem2->used = 0;
+    /* restore the next pointer */
+    mem2->next = next;
+    /* link it back to mem */
+    mem2->prev = ptr;
+    /* link mem to it */
+    mem->next = ptr2;
+    /* last thing to restore linked list: as we have moved mem2,
+     * let 'mem2->next->prev' point to mem2 again. but only if mem2->next is not
+     * the end of the heap */
+    if (mem2->next != MEM_SIZE_ALIGNED) {
+      ptr_to_mem(mem2->next)->prev = ptr2;
+    }
+    MEM_STATS_DEC_USED(used, (size - newsize));
+    /* no need to plug holes, we've already done that */
+  } else if (newsize + SIZEOF_STRUCT_MEM + MIN_SIZE_ALIGNED <= size) {
+    /* Next struct is used but there's room for another struct mem with
+     * at least MIN_SIZE_ALIGNED of data.
+     * Old size ('size') must be big enough to contain at least 'newsize' plus a struct mem
+     * ('SIZEOF_STRUCT_MEM') with some data ('MIN_SIZE_ALIGNED').
+     * @todo we could leave out MIN_SIZE_ALIGNED. We would create an empty
+     *       region that couldn't hold data, but when mem->next gets freed,
+     *       the 2 regions would be combined, resulting in more free memory */
+    ptr2 = (mem_size_t)(ptr + SIZEOF_STRUCT_MEM + newsize);
+    LWIP_ASSERT("invalid next ptr", mem->next != MEM_SIZE_ALIGNED);
+    mem2 = ptr_to_mem(ptr2);
+    if (mem2 < lfree) {
+      lfree = mem2;
+    }
+    mem2->used = 0;
+    mem2->next = mem->next;
+    mem2->prev = ptr;
+    mem->next = ptr2;
+    if (mem2->next != MEM_SIZE_ALIGNED) {
+      ptr_to_mem(mem2->next)->prev = ptr2;
+    }
+    MEM_STATS_DEC_USED(used, (size - newsize));
+    /* the original mem->next is used, so no need to plug holes! */
+  }
+  /* else {
+    next struct mem is used but size between mem and mem2 is not big enough
+    to create another struct mem
+    -> don't do anyhting.
+    -> the remaining space stays unused since it is too small
+  } */
+#if MEM_OVERFLOW_CHECK
+  mem_overflow_init_element(mem, new_size);
+#endif
+  MEM_SANITY();
+#if LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT
+  mem_free_count = 1;
+#endif /* LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT */
+  LWIP_MEM_FREE_UNPROTECT();
+  return rmem;
+}
+
+/**
+ * Allocate a block of memory with a minimum of 'size' bytes.
+ *
+ * @param size_in is the minimum size of the requested block in bytes.
+ * @return pointer to allocated memory or NULL if no free memory was found.
+ *
+ * Note that the returned value will always be aligned (as defined by MEM_ALIGNMENT).
+ */
+void *
+mem_malloc(mem_size_t size_in)
+{
+  mem_size_t ptr, ptr2, size;
+  struct mem *mem, *mem2;
+#if LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT
+  u8_t local_mem_free_count = 0;
+#endif /* LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT */
+  LWIP_MEM_ALLOC_DECL_PROTECT();
+
+  if (size_in == 0) {
+    return NULL;
+  }
+
+  /* Expand the size of the allocated memory region so that we can
+     adjust for alignment. */
+  size = (mem_size_t)LWIP_MEM_ALIGN_SIZE(size_in);
+  if (size < MIN_SIZE_ALIGNED) {
+    /* every data block must be at least MIN_SIZE_ALIGNED long */
+    size = MIN_SIZE_ALIGNED;
+  }
+#if MEM_OVERFLOW_CHECK
+  size += MEM_SANITY_REGION_BEFORE_ALIGNED + MEM_SANITY_REGION_AFTER_ALIGNED;
+#endif
+  if ((size > MEM_SIZE_ALIGNED) || (size < size_in)) {
+    return NULL;
+  }
+
+  /* protect the heap from concurrent access */
+  sys_mutex_lock(&mem_mutex);
+  LWIP_MEM_ALLOC_PROTECT();
+#if LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT
+  /* run as long as a mem_free disturbed mem_malloc or mem_trim */
+  do {
+    local_mem_free_count = 0;
+#endif /* LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT */
+
+    /* Scan through the heap searching for a free block that is big enough,
+     * beginning with the lowest free block.
+     */
+    for (ptr = mem_to_ptr(lfree); ptr < MEM_SIZE_ALIGNED - size;
+         ptr = ptr_to_mem(ptr)->next) {
+      mem = ptr_to_mem(ptr);
+#if LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT
+      mem_free_count = 0;
+      LWIP_MEM_ALLOC_UNPROTECT();
+      /* allow mem_free or mem_trim to run */
+      LWIP_MEM_ALLOC_PROTECT();
+      if (mem_free_count != 0) {
+        /* If mem_free or mem_trim have run, we have to restart since they
+           could have altered our current struct mem. */
+        local_mem_free_count = 1;
+        break;
+      }
+#endif /* LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT */
+
+      if ((!mem->used) &&
+          (mem->next - (ptr + SIZEOF_STRUCT_MEM)) >= size) {
+        /* mem is not used and at least perfect fit is possible:
+         * mem->next - (ptr + SIZEOF_STRUCT_MEM) gives us the 'user data size' of mem */
+
+        if (mem->next - (ptr + SIZEOF_STRUCT_MEM) >= (size + SIZEOF_STRUCT_MEM + MIN_SIZE_ALIGNED)) {
+          /* (in addition to the above, we test if another struct mem (SIZEOF_STRUCT_MEM) containing
+           * at least MIN_SIZE_ALIGNED of data also fits in the 'user data space' of 'mem')
+           * -> split large block, create empty remainder,
+           * remainder must be large enough to contain MIN_SIZE_ALIGNED data: if
+           * mem->next - (ptr + (2*SIZEOF_STRUCT_MEM)) == size,
+           * struct mem would fit in but no data between mem2 and mem2->next
+           * @todo we could leave out MIN_SIZE_ALIGNED. We would create an empty
+           *       region that couldn't hold data, but when mem->next gets freed,
+           *       the 2 regions would be combined, resulting in more free memory
+           */
+          ptr2 = (mem_size_t)(ptr + SIZEOF_STRUCT_MEM + size);
+          LWIP_ASSERT("invalid next ptr",ptr2 != MEM_SIZE_ALIGNED);
+          /* create mem2 struct */
+          mem2 = ptr_to_mem(ptr2);
+          mem2->used = 0;
+          mem2->next = mem->next;
+          mem2->prev = ptr;
+          /* and insert it between mem and mem->next */
+          mem->next = ptr2;
+          mem->used = 1;
+
+          if (mem2->next != MEM_SIZE_ALIGNED) {
+            ptr_to_mem(mem2->next)->prev = ptr2;
+          }
+          MEM_STATS_INC_USED(used, (size + SIZEOF_STRUCT_MEM));
+        } else {
+          /* (a mem2 struct does no fit into the user data space of mem and mem->next will always
+           * be used at this point: if not we have 2 unused structs in a row, plug_holes should have
+           * take care of this).
+           * -> near fit or exact fit: do not split, no mem2 creation
+           * also can't move mem->next directly behind mem, since mem->next
+           * will always be used at this point!
+           */
+          mem->used = 1;
+          MEM_STATS_INC_USED(used, mem->next - mem_to_ptr(mem));
+        }
+#if LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT
+mem_malloc_adjust_lfree:
+#endif /* LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT */
+        if (mem == lfree) {
+          struct mem *cur = lfree;
+          /* Find next free block after mem and update lowest free pointer */
+          while (cur->used && cur != ram_end) {
+#if LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT
+            mem_free_count = 0;
+            LWIP_MEM_ALLOC_UNPROTECT();
+            /* prevent high interrupt latency... */
+            LWIP_MEM_ALLOC_PROTECT();
+            if (mem_free_count != 0) {
+              /* If mem_free or mem_trim have run, we have to restart since they
+                 could have altered our current struct mem or lfree. */
+              goto mem_malloc_adjust_lfree;
+            }
+#endif /* LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT */
+            cur = ptr_to_mem(cur->next);
+          }
+          lfree = cur;
+          LWIP_ASSERT("mem_malloc: !lfree->used", ((lfree == ram_end) || (!lfree->used)));
+        }
+        LWIP_MEM_ALLOC_UNPROTECT();
+        sys_mutex_unlock(&mem_mutex);
+        LWIP_ASSERT("mem_malloc: allocated memory not above ram_end.",
+                    (mem_ptr_t)mem + SIZEOF_STRUCT_MEM + size <= (mem_ptr_t)ram_end);
+        LWIP_ASSERT("mem_malloc: allocated memory properly aligned.",
+                    ((mem_ptr_t)mem + SIZEOF_STRUCT_MEM) % MEM_ALIGNMENT == 0);
+        LWIP_ASSERT("mem_malloc: sanity check alignment",
+                    (((mem_ptr_t)mem) & (MEM_ALIGNMENT - 1)) == 0);
+
+#if MEM_OVERFLOW_CHECK
+        mem_overflow_init_element(mem, size_in);
+#endif
+        MEM_SANITY();
+        return (u8_t *)mem + SIZEOF_STRUCT_MEM + MEM_SANITY_OFFSET;
+      }
+    }
+#if LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT
+    /* if we got interrupted by a mem_free, try again */
+  } while (local_mem_free_count != 0);
+#endif /* LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT */
+  MEM_STATS_INC(err);
+  LWIP_MEM_ALLOC_UNPROTECT();
+  sys_mutex_unlock(&mem_mutex);
+  LWIP_DEBUGF(MEM_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("mem_malloc: could not allocate %"S16_F" bytes\n", (s16_t)size));
+  return NULL;
+}
+
+#endif /* MEM_USE_POOLS */
+
+#if MEM_LIBC_MALLOC && (!LWIP_STATS || !MEM_STATS)
+void *
+mem_calloc(mem_size_t count, mem_size_t size)
+{
+  return mem_clib_calloc(count, size);
+}
+
+#else /* MEM_LIBC_MALLOC && (!LWIP_STATS || !MEM_STATS) */
+/**
+ * Contiguously allocates enough space for count objects that are size bytes
+ * of memory each and returns a pointer to the allocated memory.
+ *
+ * The allocated memory is filled with bytes of value zero.
+ *
+ * @param count number of objects to allocate
+ * @param size size of the objects to allocate
+ * @return pointer to allocated memory / NULL pointer if there is an error
+ */
+void *
+mem_calloc(mem_size_t count, mem_size_t size)
+{
+  void *p;
+  size_t alloc_size = (size_t)count * (size_t)size;
+
+  if ((size_t)(mem_size_t)alloc_size != alloc_size) {
+    LWIP_DEBUGF(MEM_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("mem_calloc: could not allocate %"SZT_F" bytes\n", alloc_size));
+    return NULL;
+  }
+
+  /* allocate 'count' objects of size 'size' */
+  p = mem_malloc((mem_size_t)alloc_size);
+  if (p) {
+    /* zero the memory */
+    memset(p, 0, alloc_size);
+  }
+  return p;
+}
+#endif /* MEM_LIBC_MALLOC && (!LWIP_STATS || !MEM_STATS) */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/core/memp.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/core/memp.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/core/memp.c	(revision 457)
@@ -0,0 +1,447 @@
+/**
+ * @file
+ * Dynamic pool memory manager
+ *
+ * lwIP has dedicated pools for many structures (netconn, protocol control blocks,
+ * packet buffers, ...). All these pools are managed here.
+ *
+ * @defgroup mempool Memory pools
+ * @ingroup infrastructure
+ * Custom memory pools
+
+ */
+
+/*
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Adam Dunkels <adam@sics.se>
+ *
+ */
+
+#include "lwip/opt.h"
+
+#include "lwip/memp.h"
+#include "lwip/sys.h"
+#include "lwip/stats.h"
+
+#include <string.h>
+
+/* Make sure we include everything we need for size calculation required by memp_std.h */
+#include "lwip/pbuf.h"
+#include "lwip/raw.h"
+#include "lwip/udp.h"
+#include "lwip/tcp.h"
+#include "lwip/priv/tcp_priv.h"
+#include "lwip/altcp.h"
+#include "lwip/ip4_frag.h"
+#include "lwip/netbuf.h"
+#include "lwip/api.h"
+#include "lwip/priv/tcpip_priv.h"
+#include "lwip/priv/api_msg.h"
+#include "lwip/priv/sockets_priv.h"
+#include "lwip/etharp.h"
+#include "lwip/igmp.h"
+#include "lwip/timeouts.h"
+/* needed by default MEMP_NUM_SYS_TIMEOUT */
+#include "netif/ppp/ppp_opts.h"
+#include "lwip/netdb.h"
+#include "lwip/dns.h"
+#include "lwip/priv/nd6_priv.h"
+#include "lwip/ip6_frag.h"
+#include "lwip/mld6.h"
+
+#define LWIP_MEMPOOL(name,num,size,desc) LWIP_MEMPOOL_DECLARE(name,num,size,desc)
+#include "lwip/priv/memp_std.h"
+
+const struct memp_desc *const memp_pools[MEMP_MAX] = {
+#define LWIP_MEMPOOL(name,num,size,desc) &memp_ ## name,
+#include "lwip/priv/memp_std.h"
+};
+
+#ifdef LWIP_HOOK_FILENAME
+#include LWIP_HOOK_FILENAME
+#endif
+
+#if MEMP_MEM_MALLOC && MEMP_OVERFLOW_CHECK >= 2
+#undef MEMP_OVERFLOW_CHECK
+/* MEMP_OVERFLOW_CHECK >= 2 does not work with MEMP_MEM_MALLOC, use 1 instead */
+#define MEMP_OVERFLOW_CHECK 1
+#endif
+
+#if MEMP_SANITY_CHECK && !MEMP_MEM_MALLOC
+/**
+ * Check that memp-lists don't form a circle, using "Floyd's cycle-finding algorithm".
+ */
+static int
+memp_sanity(const struct memp_desc *desc)
+{
+  struct memp *t, *h;
+
+  t = *desc->tab;
+  if (t != NULL) {
+    for (h = t->next; (t != NULL) && (h != NULL); t = t->next,
+         h = ((h->next != NULL) ? h->next->next : NULL)) {
+      if (t == h) {
+        return 0;
+      }
+    }
+  }
+
+  return 1;
+}
+#endif /* MEMP_SANITY_CHECK && !MEMP_MEM_MALLOC */
+
+#if MEMP_OVERFLOW_CHECK
+/**
+ * Check if a memp element was victim of an overflow or underflow
+ * (e.g. the restricted area after/before it has been altered)
+ *
+ * @param p the memp element to check
+ * @param desc the pool p comes from
+ */
+static void
+memp_overflow_check_element(struct memp *p, const struct memp_desc *desc)
+{
+  mem_overflow_check_raw((u8_t *)p + MEMP_SIZE, desc->size, "pool ", desc->desc);
+}
+
+/**
+ * Initialize the restricted area of on memp element.
+ */
+static void
+memp_overflow_init_element(struct memp *p, const struct memp_desc *desc)
+{
+  mem_overflow_init_raw((u8_t *)p + MEMP_SIZE, desc->size);
+}
+
+#if MEMP_OVERFLOW_CHECK >= 2
+/**
+ * Do an overflow check for all elements in every pool.
+ *
+ * @see memp_overflow_check_element for a description of the check
+ */
+static void
+memp_overflow_check_all(void)
+{
+  u16_t i, j;
+  struct memp *p;
+  SYS_ARCH_DECL_PROTECT(old_level);
+  SYS_ARCH_PROTECT(old_level);
+
+  for (i = 0; i < MEMP_MAX; ++i) {
+    p = (struct memp *)LWIP_MEM_ALIGN(memp_pools[i]->base);
+    for (j = 0; j < memp_pools[i]->num; ++j) {
+      memp_overflow_check_element(p, memp_pools[i]);
+      p = LWIP_ALIGNMENT_CAST(struct memp *, ((u8_t *)p + MEMP_SIZE + memp_pools[i]->size + MEM_SANITY_REGION_AFTER_ALIGNED));
+    }
+  }
+  SYS_ARCH_UNPROTECT(old_level);
+}
+#endif /* MEMP_OVERFLOW_CHECK >= 2 */
+#endif /* MEMP_OVERFLOW_CHECK */
+
+/**
+ * Initialize custom memory pool.
+ * Related functions: memp_malloc_pool, memp_free_pool
+ *
+ * @param desc pool to initialize
+ */
+void
+memp_init_pool(const struct memp_desc *desc)
+{
+#if MEMP_MEM_MALLOC
+  LWIP_UNUSED_ARG(desc);
+#else
+  int i;
+  struct memp *memp;
+
+  *desc->tab = NULL;
+  memp = (struct memp *)LWIP_MEM_ALIGN(desc->base);
+#if MEMP_MEM_INIT
+  /* force memset on pool memory */
+  memset(memp, 0, (size_t)desc->num * (MEMP_SIZE + desc->size
+#if MEMP_OVERFLOW_CHECK
+                                       + MEM_SANITY_REGION_AFTER_ALIGNED
+#endif
+                                      ));
+#endif
+  /* create a linked list of memp elements */
+  for (i = 0; i < desc->num; ++i) {
+    memp->next = *desc->tab;
+    *desc->tab = memp;
+#if MEMP_OVERFLOW_CHECK
+    memp_overflow_init_element(memp, desc);
+#endif /* MEMP_OVERFLOW_CHECK */
+    /* cast through void* to get rid of alignment warnings */
+    memp = (struct memp *)(void *)((u8_t *)memp + MEMP_SIZE + desc->size
+#if MEMP_OVERFLOW_CHECK
+                                   + MEM_SANITY_REGION_AFTER_ALIGNED
+#endif
+                                  );
+  }
+#if MEMP_STATS
+  desc->stats->avail = desc->num;
+#endif /* MEMP_STATS */
+#endif /* !MEMP_MEM_MALLOC */
+
+#if MEMP_STATS && (defined(LWIP_DEBUG) || LWIP_STATS_DISPLAY)
+  desc->stats->name  = desc->desc;
+#endif /* MEMP_STATS && (defined(LWIP_DEBUG) || LWIP_STATS_DISPLAY) */
+}
+
+/**
+ * Initializes lwIP built-in pools.
+ * Related functions: memp_malloc, memp_free
+ *
+ * Carves out memp_memory into linked lists for each pool-type.
+ */
+void
+memp_init(void)
+{
+  u16_t i;
+
+  /* for every pool: */
+  for (i = 0; i < LWIP_ARRAYSIZE(memp_pools); i++) {
+    memp_init_pool(memp_pools[i]);
+
+#if LWIP_STATS && MEMP_STATS
+    lwip_stats.memp[i] = memp_pools[i]->stats;
+#endif
+  }
+
+#if MEMP_OVERFLOW_CHECK >= 2
+  /* check everything a first time to see if it worked */
+  memp_overflow_check_all();
+#endif /* MEMP_OVERFLOW_CHECK >= 2 */
+}
+
+static void *
+#if !MEMP_OVERFLOW_CHECK
+do_memp_malloc_pool(const struct memp_desc *desc)
+#else
+do_memp_malloc_pool_fn(const struct memp_desc *desc, const char *file, const int line)
+#endif
+{
+  struct memp *memp;
+  SYS_ARCH_DECL_PROTECT(old_level);
+
+#if MEMP_MEM_MALLOC
+  memp = (struct memp *)mem_malloc(MEMP_SIZE + MEMP_ALIGN_SIZE(desc->size));
+  SYS_ARCH_PROTECT(old_level);
+#else /* MEMP_MEM_MALLOC */
+  SYS_ARCH_PROTECT(old_level);
+
+  memp = *desc->tab;
+#endif /* MEMP_MEM_MALLOC */
+
+  if (memp != NULL) {
+#if !MEMP_MEM_MALLOC
+#if MEMP_OVERFLOW_CHECK == 1
+    memp_overflow_check_element(memp, desc);
+#endif /* MEMP_OVERFLOW_CHECK */
+
+    *desc->tab = memp->next;
+#if MEMP_OVERFLOW_CHECK
+    memp->next = NULL;
+#endif /* MEMP_OVERFLOW_CHECK */
+#endif /* !MEMP_MEM_MALLOC */
+#if MEMP_OVERFLOW_CHECK
+    memp->file = file;
+    memp->line = line;
+#if MEMP_MEM_MALLOC
+    memp_overflow_init_element(memp, desc);
+#endif /* MEMP_MEM_MALLOC */
+#endif /* MEMP_OVERFLOW_CHECK */
+    LWIP_ASSERT("memp_malloc: memp properly aligned",
+                ((mem_ptr_t)memp % MEM_ALIGNMENT) == 0);
+#if MEMP_STATS
+    desc->stats->used++;
+    if (desc->stats->used > desc->stats->max) {
+      desc->stats->max = desc->stats->used;
+    }
+#endif
+    SYS_ARCH_UNPROTECT(old_level);
+    /* cast through u8_t* to get rid of alignment warnings */
+    return ((u8_t *)memp + MEMP_SIZE);
+  } else {
+#if MEMP_STATS
+    desc->stats->err++;
+#endif
+    SYS_ARCH_UNPROTECT(old_level);
+    LWIP_DEBUGF(MEMP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("memp_malloc: out of memory in pool %s\n", desc->desc));
+  }
+
+  return NULL;
+}
+
+/**
+ * Get an element from a custom pool.
+ *
+ * @param desc the pool to get an element from
+ *
+ * @return a pointer to the allocated memory or a NULL pointer on error
+ */
+void *
+#if !MEMP_OVERFLOW_CHECK
+memp_malloc_pool(const struct memp_desc *desc)
+#else
+memp_malloc_pool_fn(const struct memp_desc *desc, const char *file, const int line)
+#endif
+{
+  LWIP_ASSERT("invalid pool desc", desc != NULL);
+  if (desc == NULL) {
+    return NULL;
+  }
+
+#if !MEMP_OVERFLOW_CHECK
+  return do_memp_malloc_pool(desc);
+#else
+  return do_memp_malloc_pool_fn(desc, file, line);
+#endif
+}
+
+/**
+ * Get an element from a specific pool.
+ *
+ * @param type the pool to get an element from
+ *
+ * @return a pointer to the allocated memory or a NULL pointer on error
+ */
+void *
+#if !MEMP_OVERFLOW_CHECK
+memp_malloc(memp_t type)
+#else
+memp_malloc_fn(memp_t type, const char *file, const int line)
+#endif
+{
+  void *memp;
+  LWIP_ERROR("memp_malloc: type < MEMP_MAX", (type < MEMP_MAX), return NULL;);
+
+#if MEMP_OVERFLOW_CHECK >= 2
+  memp_overflow_check_all();
+#endif /* MEMP_OVERFLOW_CHECK >= 2 */
+
+#if !MEMP_OVERFLOW_CHECK
+  memp = do_memp_malloc_pool(memp_pools[type]);
+#else
+  memp = do_memp_malloc_pool_fn(memp_pools[type], file, line);
+#endif
+
+  return memp;
+}
+
+static void
+do_memp_free_pool(const struct memp_desc *desc, void *mem)
+{
+  struct memp *memp;
+  SYS_ARCH_DECL_PROTECT(old_level);
+
+  LWIP_ASSERT("memp_free: mem properly aligned",
+              ((mem_ptr_t)mem % MEM_ALIGNMENT) == 0);
+
+  /* cast through void* to get rid of alignment warnings */
+  memp = (struct memp *)(void *)((u8_t *)mem - MEMP_SIZE);
+
+  SYS_ARCH_PROTECT(old_level);
+
+#if MEMP_OVERFLOW_CHECK == 1
+  memp_overflow_check_element(memp, desc);
+#endif /* MEMP_OVERFLOW_CHECK */
+
+#if MEMP_STATS
+  desc->stats->used--;
+#endif
+
+#if MEMP_MEM_MALLOC
+  LWIP_UNUSED_ARG(desc);
+  SYS_ARCH_UNPROTECT(old_level);
+  mem_free(memp);
+#else /* MEMP_MEM_MALLOC */
+  memp->next = *desc->tab;
+  *desc->tab = memp;
+
+#if MEMP_SANITY_CHECK
+  LWIP_ASSERT("memp sanity", memp_sanity(desc));
+#endif /* MEMP_SANITY_CHECK */
+
+  SYS_ARCH_UNPROTECT(old_level);
+#endif /* !MEMP_MEM_MALLOC */
+}
+
+/**
+ * Put a custom pool element back into its pool.
+ *
+ * @param desc the pool where to put mem
+ * @param mem the memp element to free
+ */
+void
+memp_free_pool(const struct memp_desc *desc, void *mem)
+{
+  LWIP_ASSERT("invalid pool desc", desc != NULL);
+  if ((desc == NULL) || (mem == NULL)) {
+    return;
+  }
+
+  do_memp_free_pool(desc, mem);
+}
+
+/**
+ * Put an element back into its pool.
+ *
+ * @param type the pool where to put mem
+ * @param mem the memp element to free
+ */
+void
+memp_free(memp_t type, void *mem)
+{
+#ifdef LWIP_HOOK_MEMP_AVAILABLE
+  struct memp *old_first;
+#endif
+
+  LWIP_ERROR("memp_free: type < MEMP_MAX", (type < MEMP_MAX), return;);
+
+  if (mem == NULL) {
+    return;
+  }
+
+#if MEMP_OVERFLOW_CHECK >= 2
+  memp_overflow_check_all();
+#endif /* MEMP_OVERFLOW_CHECK >= 2 */
+
+#ifdef LWIP_HOOK_MEMP_AVAILABLE
+  old_first = *memp_pools[type]->tab;
+#endif
+
+  do_memp_free_pool(memp_pools[type], mem);
+
+#ifdef LWIP_HOOK_MEMP_AVAILABLE
+  if (old_first == NULL) {
+    LWIP_HOOK_MEMP_AVAILABLE(type);
+  }
+#endif
+}
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/core/netif.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/core/netif.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/core/netif.c	(revision 457)
@@ -0,0 +1,1795 @@
+/**
+ * @file
+ * lwIP network interface abstraction
+ *
+ * @defgroup netif Network interface (NETIF)
+ * @ingroup callbackstyle_api
+ *
+ * @defgroup netif_ip4 IPv4 address handling
+ * @ingroup netif
+ *
+ * @defgroup netif_ip6 IPv6 address handling
+ * @ingroup netif
+ *
+ * @defgroup netif_cd Client data handling
+ * Store data (void*) on a netif for application usage.
+ * @see @ref LWIP_NUM_NETIF_CLIENT_DATA
+ * @ingroup netif
+ */
+
+/*
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Adam Dunkels <adam@sics.se>
+ */
+
+#include "lwip/opt.h"
+
+#include <string.h> /* memset */
+#include <stdlib.h> /* atoi */
+
+#include "lwip/def.h"
+#include "lwip/ip_addr.h"
+#include "lwip/ip6_addr.h"
+#include "lwip/netif.h"
+#include "lwip/priv/tcp_priv.h"
+#include "lwip/udp.h"
+#include "lwip/priv/raw_priv.h"
+#include "lwip/snmp.h"
+#include "lwip/igmp.h"
+#include "lwip/etharp.h"
+#include "lwip/stats.h"
+#include "lwip/sys.h"
+#include "lwip/ip.h"
+#if ENABLE_LOOPBACK
+#if LWIP_NETIF_LOOPBACK_MULTITHREADING
+#include "lwip/tcpip.h"
+#endif /* LWIP_NETIF_LOOPBACK_MULTITHREADING */
+#endif /* ENABLE_LOOPBACK */
+
+#include "netif/ethernet.h"
+
+#if LWIP_AUTOIP
+#include "lwip/autoip.h"
+#endif /* LWIP_AUTOIP */
+#if LWIP_DHCP
+#include "lwip/dhcp.h"
+#endif /* LWIP_DHCP */
+#if LWIP_IPV6_DHCP6
+#include "lwip/dhcp6.h"
+#endif /* LWIP_IPV6_DHCP6 */
+#if LWIP_IPV6_MLD
+#include "lwip/mld6.h"
+#endif /* LWIP_IPV6_MLD */
+#if LWIP_IPV6
+#include "lwip/nd6.h"
+#endif
+
+#if LWIP_NETIF_STATUS_CALLBACK
+#define NETIF_STATUS_CALLBACK(n) do{ if (n->status_callback) { (n->status_callback)(n); }}while(0)
+#else
+#define NETIF_STATUS_CALLBACK(n)
+#endif /* LWIP_NETIF_STATUS_CALLBACK */
+
+#if LWIP_NETIF_LINK_CALLBACK
+#define NETIF_LINK_CALLBACK(n) do{ if (n->link_callback) { (n->link_callback)(n); }}while(0)
+#else
+#define NETIF_LINK_CALLBACK(n)
+#endif /* LWIP_NETIF_LINK_CALLBACK */
+
+#if LWIP_NETIF_EXT_STATUS_CALLBACK
+static netif_ext_callback_t *ext_callback;
+#endif
+
+#if !LWIP_SINGLE_NETIF
+struct netif *netif_list;
+#endif /* !LWIP_SINGLE_NETIF */
+struct netif *netif_default;
+
+#define netif_index_to_num(index)   ((index) - 1)
+static u8_t netif_num;
+
+#if LWIP_NUM_NETIF_CLIENT_DATA > 0
+static u8_t netif_client_id;
+#endif
+
+#define NETIF_REPORT_TYPE_IPV4  0x01
+#define NETIF_REPORT_TYPE_IPV6  0x02
+static void netif_issue_reports(struct netif *netif, u8_t report_type);
+
+#if LWIP_IPV6
+static err_t netif_null_output_ip6(struct netif *netif, struct pbuf *p, const ip6_addr_t *ipaddr);
+#endif /* LWIP_IPV6 */
+#if LWIP_IPV4
+static err_t netif_null_output_ip4(struct netif *netif, struct pbuf *p, const ip4_addr_t *ipaddr);
+#endif /* LWIP_IPV4 */
+
+#if LWIP_HAVE_LOOPIF
+#if LWIP_IPV4
+static err_t netif_loop_output_ipv4(struct netif *netif, struct pbuf *p, const ip4_addr_t *addr);
+#endif
+#if LWIP_IPV6
+static err_t netif_loop_output_ipv6(struct netif *netif, struct pbuf *p, const ip6_addr_t *addr);
+#endif
+
+
+static struct netif loop_netif;
+
+/**
+ * Initialize a lwip network interface structure for a loopback interface
+ *
+ * @param netif the lwip network interface structure for this loopif
+ * @return ERR_OK if the loopif is initialized
+ *         ERR_MEM if private data couldn't be allocated
+ */
+static err_t
+netif_loopif_init(struct netif *netif)
+{
+  LWIP_ASSERT("netif_loopif_init: invalid netif", netif != NULL);
+
+  /* initialize the snmp variables and counters inside the struct netif
+   * ifSpeed: no assumption can be made!
+   */
+  MIB2_INIT_NETIF(netif, snmp_ifType_softwareLoopback, 0);
+
+  netif->name[0] = 'l';
+  netif->name[1] = 'o';
+#if LWIP_IPV4
+  netif->output = netif_loop_output_ipv4;
+#endif
+#if LWIP_IPV6
+  netif->output_ip6 = netif_loop_output_ipv6;
+#endif
+#if LWIP_LOOPIF_MULTICAST
+  netif_set_flags(netif, NETIF_FLAG_IGMP);
+#endif
+  NETIF_SET_CHECKSUM_CTRL(netif, NETIF_CHECKSUM_DISABLE_ALL);
+  return ERR_OK;
+}
+#endif /* LWIP_HAVE_LOOPIF */
+
+void
+netif_init(void)
+{
+#if LWIP_HAVE_LOOPIF
+#if LWIP_IPV4
+#define LOOPIF_ADDRINIT &loop_ipaddr, &loop_netmask, &loop_gw,
+  ip4_addr_t loop_ipaddr, loop_netmask, loop_gw;
+  IP4_ADDR(&loop_gw, 127, 0, 0, 1);
+  IP4_ADDR(&loop_ipaddr, 127, 0, 0, 1);
+  IP4_ADDR(&loop_netmask, 255, 0, 0, 0);
+#else /* LWIP_IPV4 */
+#define LOOPIF_ADDRINIT
+#endif /* LWIP_IPV4 */
+
+#if NO_SYS
+  netif_add(&loop_netif, LOOPIF_ADDRINIT NULL, netif_loopif_init, ip_input);
+#else  /* NO_SYS */
+  netif_add(&loop_netif, LOOPIF_ADDRINIT NULL, netif_loopif_init, tcpip_input);
+#endif /* NO_SYS */
+
+#if LWIP_IPV6
+  IP_ADDR6_HOST(loop_netif.ip6_addr, 0, 0, 0, 0x00000001UL);
+  loop_netif.ip6_addr_state[0] = IP6_ADDR_VALID;
+#endif /* LWIP_IPV6 */
+
+  netif_set_link_up(&loop_netif);
+  netif_set_up(&loop_netif);
+
+#endif /* LWIP_HAVE_LOOPIF */
+}
+
+/**
+ * @ingroup lwip_nosys
+ * Forwards a received packet for input processing with
+ * ethernet_input() or ip_input() depending on netif flags.
+ * Don't call directly, pass to netif_add() and call
+ * netif->input().
+ * Only works if the netif driver correctly sets
+ * NETIF_FLAG_ETHARP and/or NETIF_FLAG_ETHERNET flag!
+ */
+err_t
+netif_input(struct pbuf *p, struct netif *inp)
+{
+  LWIP_ASSERT_CORE_LOCKED();
+
+  LWIP_ASSERT("netif_input: invalid pbuf", p != NULL);
+  LWIP_ASSERT("netif_input: invalid netif", inp != NULL);
+
+#if LWIP_ETHERNET
+  if (inp->flags & (NETIF_FLAG_ETHARP | NETIF_FLAG_ETHERNET)) {
+    return ethernet_input(p, inp);
+  } else
+#endif /* LWIP_ETHERNET */
+    return ip_input(p, inp);
+}
+
+/**
+ * @ingroup netif
+ * Add a network interface to the list of lwIP netifs.
+ *
+ * Same as @ref netif_add but without IPv4 addresses
+ */
+struct netif *
+netif_add_noaddr(struct netif *netif, void *state, netif_init_fn init, netif_input_fn input)
+{
+  return netif_add(netif,
+#if LWIP_IPV4
+                   NULL, NULL, NULL,
+#endif /* LWIP_IPV4*/
+                   state, init, input);
+}
+
+/**
+ * @ingroup netif
+ * Add a network interface to the list of lwIP netifs.
+ *
+ * @param netif a pre-allocated netif structure
+ * @param ipaddr IP address for the new netif
+ * @param netmask network mask for the new netif
+ * @param gw default gateway IP address for the new netif
+ * @param state opaque data passed to the new netif
+ * @param init callback function that initializes the interface
+ * @param input callback function that is called to pass
+ * ingress packets up in the protocol layer stack.\n
+ * It is recommended to use a function that passes the input directly
+ * to the stack (netif_input(), NO_SYS=1 mode) or via sending a
+ * message to TCPIP thread (tcpip_input(), NO_SYS=0 mode).\n
+ * These functions use netif flags NETIF_FLAG_ETHARP and NETIF_FLAG_ETHERNET
+ * to decide whether to forward to ethernet_input() or ip_input().
+ * In other words, the functions only work when the netif
+ * driver is implemented correctly!\n
+ * Most members of struct netif should be be initialized by the
+ * netif init function = netif driver (init parameter of this function).\n
+ * IPv6: Don't forget to call netif_create_ip6_linklocal_address() after
+ * setting the MAC address in struct netif.hwaddr
+ * (IPv6 requires a link-local address).
+ *
+ * @return netif, or NULL if failed.
+ */
+struct netif *
+netif_add(struct netif *netif,
+#if LWIP_IPV4
+          const ip4_addr_t *ipaddr, const ip4_addr_t *netmask, const ip4_addr_t *gw,
+#endif /* LWIP_IPV4 */
+          void *state, netif_init_fn init, netif_input_fn input)
+{
+#if LWIP_IPV6
+  s8_t i;
+#endif
+
+  LWIP_ASSERT_CORE_LOCKED();
+
+#if LWIP_SINGLE_NETIF
+  if (netif_default != NULL) {
+    LWIP_ASSERT("single netif already set", 0);
+    return NULL;
+  }
+#endif
+
+  LWIP_ERROR("netif_add: invalid netif", netif != NULL, return NULL);
+  LWIP_ERROR("netif_add: No init function given", init != NULL, return NULL);
+
+#if LWIP_IPV4
+  if (ipaddr == NULL) {
+    ipaddr = ip_2_ip4(IP4_ADDR_ANY);
+  }
+  if (netmask == NULL) {
+    netmask = ip_2_ip4(IP4_ADDR_ANY);
+  }
+  if (gw == NULL) {
+    gw = ip_2_ip4(IP4_ADDR_ANY);
+  }
+
+  /* reset new interface configuration state */
+  ip_addr_set_zero_ip4(&netif->ip_addr);
+  ip_addr_set_zero_ip4(&netif->netmask);
+  ip_addr_set_zero_ip4(&netif->gw);
+  netif->output = netif_null_output_ip4;
+#endif /* LWIP_IPV4 */
+#if LWIP_IPV6
+  for (i = 0; i < LWIP_IPV6_NUM_ADDRESSES; i++) {
+    ip_addr_set_zero_ip6(&netif->ip6_addr[i]);
+    netif->ip6_addr_state[i] = IP6_ADDR_INVALID;
+#if LWIP_IPV6_ADDRESS_LIFETIMES
+    netif->ip6_addr_valid_life[i] = IP6_ADDR_LIFE_STATIC;
+    netif->ip6_addr_pref_life[i] = IP6_ADDR_LIFE_STATIC;
+#endif /* LWIP_IPV6_ADDRESS_LIFETIMES */
+  }
+  netif->output_ip6 = netif_null_output_ip6;
+#endif /* LWIP_IPV6 */
+  NETIF_SET_CHECKSUM_CTRL(netif, NETIF_CHECKSUM_ENABLE_ALL);
+  netif->mtu = 0;
+  netif->flags = 0;
+#ifdef netif_get_client_data
+  memset(netif->client_data, 0, sizeof(netif->client_data));
+#endif /* LWIP_NUM_NETIF_CLIENT_DATA */
+#if LWIP_IPV6
+#if LWIP_IPV6_AUTOCONFIG
+  /* IPv6 address autoconfiguration not enabled by default */
+  netif->ip6_autoconfig_enabled = 0;
+#endif /* LWIP_IPV6_AUTOCONFIG */
+  nd6_restart_netif(netif);
+#endif /* LWIP_IPV6 */
+#if LWIP_NETIF_STATUS_CALLBACK
+  netif->status_callback = NULL;
+#endif /* LWIP_NETIF_STATUS_CALLBACK */
+#if LWIP_NETIF_LINK_CALLBACK
+  netif->link_callback = NULL;
+#endif /* LWIP_NETIF_LINK_CALLBACK */
+#if LWIP_IGMP
+  netif->igmp_mac_filter = NULL;
+#endif /* LWIP_IGMP */
+#if LWIP_IPV6 && LWIP_IPV6_MLD
+  netif->mld_mac_filter = NULL;
+#endif /* LWIP_IPV6 && LWIP_IPV6_MLD */
+#if ENABLE_LOOPBACK
+  netif->loop_first = NULL;
+  netif->loop_last = NULL;
+#endif /* ENABLE_LOOPBACK */
+
+  /* remember netif specific state information data */
+  netif->state = state;
+  netif->num = netif_num;
+  netif->input = input;
+
+  NETIF_RESET_HINTS(netif);
+#if ENABLE_LOOPBACK && LWIP_LOOPBACK_MAX_PBUFS
+  netif->loop_cnt_current = 0;
+#endif /* ENABLE_LOOPBACK && LWIP_LOOPBACK_MAX_PBUFS */
+
+#if LWIP_IPV4
+  netif_set_addr(netif, ipaddr, netmask, gw);
+#endif /* LWIP_IPV4 */
+
+  /* call user specified initialization function for netif */
+  if (init(netif) != ERR_OK) {
+    return NULL;
+  }
+#if LWIP_IPV6 && LWIP_ND6_ALLOW_RA_UPDATES
+  /* Initialize the MTU for IPv6 to the one set by the netif driver.
+     This can be updated later by RA. */
+  netif->mtu6 = netif->mtu;
+#endif /* LWIP_IPV6 && LWIP_ND6_ALLOW_RA_UPDATES */
+
+#if !LWIP_SINGLE_NETIF
+  /* Assign a unique netif number in the range [0..254], so that (num+1) can
+     serve as an interface index that fits in a u8_t.
+     We assume that the new netif has not yet been added to the list here.
+     This algorithm is O(n^2), but that should be OK for lwIP.
+     */
+  {
+    struct netif *netif2;
+    int num_netifs;
+    do {
+      if (netif->num == 255) {
+        netif->num = 0;
+      }
+      num_netifs = 0;
+      for (netif2 = netif_list; netif2 != NULL; netif2 = netif2->next) {
+        LWIP_ASSERT("netif already added", netif2 != netif);
+        num_netifs++;
+        LWIP_ASSERT("too many netifs, max. supported number is 255", num_netifs <= 255);
+        if (netif2->num == netif->num) {
+          netif->num++;
+          break;
+        }
+      }
+    } while (netif2 != NULL);
+  }
+  if (netif->num == 254) {
+    netif_num = 0;
+  } else {
+    netif_num = (u8_t)(netif->num + 1);
+  }
+
+  /* add this netif to the list */
+  netif->next = netif_list;
+  netif_list = netif;
+#endif /* "LWIP_SINGLE_NETIF */
+  mib2_netif_added(netif);
+
+#if LWIP_IGMP
+  /* start IGMP processing */
+  if (netif->flags & NETIF_FLAG_IGMP) {
+    igmp_start(netif);
+  }
+#endif /* LWIP_IGMP */
+
+  LWIP_DEBUGF(NETIF_DEBUG, ("netif: added interface %c%c IP",
+                            netif->name[0], netif->name[1]));
+#if LWIP_IPV4
+  LWIP_DEBUGF(NETIF_DEBUG, (" addr "));
+  ip4_addr_debug_print(NETIF_DEBUG, ipaddr);
+  LWIP_DEBUGF(NETIF_DEBUG, (" netmask "));
+  ip4_addr_debug_print(NETIF_DEBUG, netmask);
+  LWIP_DEBUGF(NETIF_DEBUG, (" gw "));
+  ip4_addr_debug_print(NETIF_DEBUG, gw);
+#endif /* LWIP_IPV4 */
+  LWIP_DEBUGF(NETIF_DEBUG, ("\n"));
+
+  netif_invoke_ext_callback(netif, LWIP_NSC_NETIF_ADDED, NULL);
+
+  return netif;
+}
+
+static void
+netif_do_ip_addr_changed(const ip_addr_t *old_addr, const ip_addr_t *new_addr)
+{
+#if LWIP_TCP
+  tcp_netif_ip_addr_changed(old_addr, new_addr);
+#endif /* LWIP_TCP */
+#if LWIP_UDP
+  udp_netif_ip_addr_changed(old_addr, new_addr);
+#endif /* LWIP_UDP */
+#if LWIP_RAW
+  raw_netif_ip_addr_changed(old_addr, new_addr);
+#endif /* LWIP_RAW */
+}
+
+#if LWIP_IPV4
+static int
+netif_do_set_ipaddr(struct netif *netif, const ip4_addr_t *ipaddr, ip_addr_t *old_addr)
+{
+  LWIP_ASSERT("invalid pointer", ipaddr != NULL);
+  LWIP_ASSERT("invalid pointer", old_addr != NULL);
+
+  /* address is actually being changed? */
+  if (ip4_addr_cmp(ipaddr, netif_ip4_addr(netif)) == 0) {
+    ip_addr_t new_addr;
+    *ip_2_ip4(&new_addr) = *ipaddr;
+    IP_SET_TYPE_VAL(new_addr, IPADDR_TYPE_V4);
+
+    ip_addr_copy(*old_addr, *netif_ip_addr4(netif));
+
+    LWIP_DEBUGF(NETIF_DEBUG | LWIP_DBG_STATE, ("netif_set_ipaddr: netif address being changed\n"));
+    netif_do_ip_addr_changed(old_addr, &new_addr);
+
+    mib2_remove_ip4(netif);
+    mib2_remove_route_ip4(0, netif);
+    /* set new IP address to netif */
+    ip4_addr_set(ip_2_ip4(&netif->ip_addr), ipaddr);
+    IP_SET_TYPE_VAL(netif->ip_addr, IPADDR_TYPE_V4);
+    mib2_add_ip4(netif);
+    mib2_add_route_ip4(0, netif);
+
+    netif_issue_reports(netif, NETIF_REPORT_TYPE_IPV4);
+
+    NETIF_STATUS_CALLBACK(netif);
+    return 1; /* address changed */
+  }
+  return 0; /* address unchanged */
+}
+
+/**
+ * @ingroup netif_ip4
+ * Change the IP address of a network interface
+ *
+ * @param netif the network interface to change
+ * @param ipaddr the new IP address
+ *
+ * @note call netif_set_addr() if you also want to change netmask and
+ * default gateway
+ */
+void
+netif_set_ipaddr(struct netif *netif, const ip4_addr_t *ipaddr)
+{
+  ip_addr_t old_addr;
+
+  LWIP_ERROR("netif_set_ipaddr: invalid netif", netif != NULL, return);
+
+  /* Don't propagate NULL pointer (IPv4 ANY) to subsequent functions */
+  if (ipaddr == NULL) {
+    ipaddr = IP4_ADDR_ANY4;
+  }
+
+  LWIP_ASSERT_CORE_LOCKED();
+
+  if (netif_do_set_ipaddr(netif, ipaddr, &old_addr)) {
+#if LWIP_NETIF_EXT_STATUS_CALLBACK
+    netif_ext_callback_args_t args;
+    args.ipv4_changed.old_address = &old_addr;
+    netif_invoke_ext_callback(netif, LWIP_NSC_IPV4_ADDRESS_CHANGED, &args);
+#endif
+  }
+}
+
+static int
+netif_do_set_netmask(struct netif *netif, const ip4_addr_t *netmask, ip_addr_t *old_nm)
+{
+  /* address is actually being changed? */
+  if (ip4_addr_cmp(netmask, netif_ip4_netmask(netif)) == 0) {
+#if LWIP_NETIF_EXT_STATUS_CALLBACK
+    LWIP_ASSERT("invalid pointer", old_nm != NULL);
+    ip_addr_copy(*old_nm, *netif_ip_netmask4(netif));
+#else
+    LWIP_UNUSED_ARG(old_nm);
+#endif
+    mib2_remove_route_ip4(0, netif);
+    /* set new netmask to netif */
+    ip4_addr_set(ip_2_ip4(&netif->netmask), netmask);
+    IP_SET_TYPE_VAL(netif->netmask, IPADDR_TYPE_V4);
+    mib2_add_route_ip4(0, netif);
+    LWIP_DEBUGF(NETIF_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("netif: netmask of interface %c%c set to %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n",
+                netif->name[0], netif->name[1],
+                ip4_addr1_16(netif_ip4_netmask(netif)),
+                ip4_addr2_16(netif_ip4_netmask(netif)),
+                ip4_addr3_16(netif_ip4_netmask(netif)),
+                ip4_addr4_16(netif_ip4_netmask(netif))));
+    return 1; /* netmask changed */
+  }
+  return 0; /* netmask unchanged */
+}
+
+/**
+ * @ingroup netif_ip4
+ * Change the netmask of a network interface
+ *
+ * @param netif the network interface to change
+ * @param netmask the new netmask
+ *
+ * @note call netif_set_addr() if you also want to change ip address and
+ * default gateway
+ */
+void
+netif_set_netmask(struct netif *netif, const ip4_addr_t *netmask)
+{
+#if LWIP_NETIF_EXT_STATUS_CALLBACK
+  ip_addr_t old_nm_val;
+  ip_addr_t *old_nm = &old_nm_val;
+#else
+  ip_addr_t *old_nm = NULL;
+#endif
+  LWIP_ASSERT_CORE_LOCKED();
+
+  LWIP_ERROR("netif_set_netmask: invalid netif", netif != NULL, return);
+
+  /* Don't propagate NULL pointer (IPv4 ANY) to subsequent functions */
+  if (netmask == NULL) {
+    netmask = IP4_ADDR_ANY4;
+  }
+
+  if (netif_do_set_netmask(netif, netmask, old_nm)) {
+#if LWIP_NETIF_EXT_STATUS_CALLBACK
+    netif_ext_callback_args_t args;
+    args.ipv4_changed.old_netmask = old_nm;
+    netif_invoke_ext_callback(netif, LWIP_NSC_IPV4_NETMASK_CHANGED, &args);
+#endif
+  }
+}
+
+static int
+netif_do_set_gw(struct netif *netif, const ip4_addr_t *gw, ip_addr_t *old_gw)
+{
+  /* address is actually being changed? */
+  if (ip4_addr_cmp(gw, netif_ip4_gw(netif)) == 0) {
+#if LWIP_NETIF_EXT_STATUS_CALLBACK
+    LWIP_ASSERT("invalid pointer", old_gw != NULL);
+    ip_addr_copy(*old_gw, *netif_ip_gw4(netif));
+#else
+    LWIP_UNUSED_ARG(old_gw);
+#endif
+
+    ip4_addr_set(ip_2_ip4(&netif->gw), gw);
+    IP_SET_TYPE_VAL(netif->gw, IPADDR_TYPE_V4);
+    LWIP_DEBUGF(NETIF_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("netif: GW address of interface %c%c set to %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n",
+                netif->name[0], netif->name[1],
+                ip4_addr1_16(netif_ip4_gw(netif)),
+                ip4_addr2_16(netif_ip4_gw(netif)),
+                ip4_addr3_16(netif_ip4_gw(netif)),
+                ip4_addr4_16(netif_ip4_gw(netif))));
+    return 1; /* gateway changed */
+  }
+  return 0; /* gateway unchanged */
+}
+
+/**
+ * @ingroup netif_ip4
+ * Change the default gateway for a network interface
+ *
+ * @param netif the network interface to change
+ * @param gw the new default gateway
+ *
+ * @note call netif_set_addr() if you also want to change ip address and netmask
+ */
+void
+netif_set_gw(struct netif *netif, const ip4_addr_t *gw)
+{
+#if LWIP_NETIF_EXT_STATUS_CALLBACK
+  ip_addr_t old_gw_val;
+  ip_addr_t *old_gw = &old_gw_val;
+#else
+  ip_addr_t *old_gw = NULL;
+#endif
+  LWIP_ASSERT_CORE_LOCKED();
+
+  LWIP_ERROR("netif_set_gw: invalid netif", netif != NULL, return);
+
+  /* Don't propagate NULL pointer (IPv4 ANY) to subsequent functions */
+  if (gw == NULL) {
+    gw = IP4_ADDR_ANY4;
+  }
+
+  if (netif_do_set_gw(netif, gw, old_gw)) {
+#if LWIP_NETIF_EXT_STATUS_CALLBACK
+    netif_ext_callback_args_t args;
+    args.ipv4_changed.old_gw = old_gw;
+    netif_invoke_ext_callback(netif, LWIP_NSC_IPV4_GATEWAY_CHANGED, &args);
+#endif
+  }
+}
+
+/**
+ * @ingroup netif_ip4
+ * Change IP address configuration for a network interface (including netmask
+ * and default gateway).
+ *
+ * @param netif the network interface to change
+ * @param ipaddr the new IP address
+ * @param netmask the new netmask
+ * @param gw the new default gateway
+ */
+void
+netif_set_addr(struct netif *netif, const ip4_addr_t *ipaddr, const ip4_addr_t *netmask,
+               const ip4_addr_t *gw)
+{
+#if LWIP_NETIF_EXT_STATUS_CALLBACK
+  netif_nsc_reason_t change_reason = LWIP_NSC_NONE;
+  netif_ext_callback_args_t cb_args;
+  ip_addr_t old_nm_val;
+  ip_addr_t old_gw_val;
+  ip_addr_t *old_nm = &old_nm_val;
+  ip_addr_t *old_gw = &old_gw_val;
+#else
+  ip_addr_t *old_nm = NULL;
+  ip_addr_t *old_gw = NULL;
+#endif
+  ip_addr_t old_addr;
+  int remove;
+
+  LWIP_ASSERT_CORE_LOCKED();
+
+  /* Don't propagate NULL pointer (IPv4 ANY) to subsequent functions */
+  if (ipaddr == NULL) {
+    ipaddr = IP4_ADDR_ANY4;
+  }
+  if (netmask == NULL) {
+    netmask = IP4_ADDR_ANY4;
+  }
+  if (gw == NULL) {
+    gw = IP4_ADDR_ANY4;
+  }
+
+  remove = ip4_addr_isany(ipaddr);
+  if (remove) {
+    /* when removing an address, we have to remove it *before* changing netmask/gw
+       to ensure that tcp RST segment can be sent correctly */
+    if (netif_do_set_ipaddr(netif, ipaddr, &old_addr)) {
+#if LWIP_NETIF_EXT_STATUS_CALLBACK
+      change_reason |= LWIP_NSC_IPV4_ADDRESS_CHANGED;
+      cb_args.ipv4_changed.old_address = &old_addr;
+#endif
+    }
+  }
+  if (netif_do_set_netmask(netif, netmask, old_nm)) {
+#if LWIP_NETIF_EXT_STATUS_CALLBACK
+    change_reason |= LWIP_NSC_IPV4_NETMASK_CHANGED;
+    cb_args.ipv4_changed.old_netmask = old_nm;
+#endif
+  }
+  if (netif_do_set_gw(netif, gw, old_gw)) {
+#if LWIP_NETIF_EXT_STATUS_CALLBACK
+    change_reason |= LWIP_NSC_IPV4_GATEWAY_CHANGED;
+    cb_args.ipv4_changed.old_gw = old_gw;
+#endif
+  }
+  if (!remove) {
+    /* set ipaddr last to ensure netmask/gw have been set when status callback is called */
+    if (netif_do_set_ipaddr(netif, ipaddr, &old_addr)) {
+#if LWIP_NETIF_EXT_STATUS_CALLBACK
+      change_reason |= LWIP_NSC_IPV4_ADDRESS_CHANGED;
+      cb_args.ipv4_changed.old_address = &old_addr;
+#endif
+    }
+  }
+
+#if LWIP_NETIF_EXT_STATUS_CALLBACK
+  if (change_reason != LWIP_NSC_NONE) {
+    change_reason |= LWIP_NSC_IPV4_SETTINGS_CHANGED;
+    netif_invoke_ext_callback(netif, change_reason, &cb_args);
+  }
+#endif
+}
+#endif /* LWIP_IPV4*/
+
+/**
+ * @ingroup netif
+ * Remove a network interface from the list of lwIP netifs.
+ *
+ * @param netif the network interface to remove
+ */
+void
+netif_remove(struct netif *netif)
+{
+#if LWIP_IPV6
+  int i;
+#endif
+
+  LWIP_ASSERT_CORE_LOCKED();
+
+  if (netif == NULL) {
+    return;
+  }
+
+  netif_invoke_ext_callback(netif, LWIP_NSC_NETIF_REMOVED, NULL);
+
+#if LWIP_IPV4
+  if (!ip4_addr_isany_val(*netif_ip4_addr(netif))) {
+    netif_do_ip_addr_changed(netif_ip_addr4(netif), NULL);
+  }
+
+#if LWIP_IGMP
+  /* stop IGMP processing */
+  if (netif->flags & NETIF_FLAG_IGMP) {
+    igmp_stop(netif);
+  }
+#endif /* LWIP_IGMP */
+#endif /* LWIP_IPV4*/
+
+#if LWIP_IPV6
+  for (i = 0; i < LWIP_IPV6_NUM_ADDRESSES; i++) {
+    if (ip6_addr_isvalid(netif_ip6_addr_state(netif, i))) {
+      netif_do_ip_addr_changed(netif_ip_addr6(netif, i), NULL);
+    }
+  }
+#if LWIP_IPV6_MLD
+  /* stop MLD processing */
+  mld6_stop(netif);
+#endif /* LWIP_IPV6_MLD */
+#endif /* LWIP_IPV6 */
+  if (netif_is_up(netif)) {
+    /* set netif down before removing (call callback function) */
+    netif_set_down(netif);
+  }
+
+  mib2_remove_ip4(netif);
+
+  /* this netif is default? */
+  if (netif_default == netif) {
+    /* reset default netif */
+    netif_set_default(NULL);
+  }
+#if !LWIP_SINGLE_NETIF
+  /*  is it the first netif? */
+  if (netif_list == netif) {
+    netif_list = netif->next;
+  } else {
+    /*  look for netif further down the list */
+    struct netif *tmp_netif;
+    NETIF_FOREACH(tmp_netif) {
+      if (tmp_netif->next == netif) {
+        tmp_netif->next = netif->next;
+        break;
+      }
+    }
+    if (tmp_netif == NULL) {
+      return; /* netif is not on the list */
+    }
+  }
+#endif /* !LWIP_SINGLE_NETIF */
+  mib2_netif_removed(netif);
+#if LWIP_NETIF_REMOVE_CALLBACK
+  if (netif->remove_callback) {
+    netif->remove_callback(netif);
+  }
+#endif /* LWIP_NETIF_REMOVE_CALLBACK */
+  LWIP_DEBUGF( NETIF_DEBUG, ("netif_remove: removed netif\n") );
+}
+
+/**
+ * @ingroup netif
+ * Set a network interface as the default network interface
+ * (used to output all packets for which no specific route is found)
+ *
+ * @param netif the default network interface
+ */
+void
+netif_set_default(struct netif *netif)
+{
+  LWIP_ASSERT_CORE_LOCKED();
+
+  if (netif == NULL) {
+    /* remove default route */
+    mib2_remove_route_ip4(1, netif);
+  } else {
+    /* install default route */
+    mib2_add_route_ip4(1, netif);
+  }
+  netif_default = netif;
+  LWIP_DEBUGF(NETIF_DEBUG, ("netif: setting default interface %c%c\n",
+                            netif ? netif->name[0] : '\'', netif ? netif->name[1] : '\''));
+}
+
+/**
+ * @ingroup netif
+ * Bring an interface up, available for processing
+ * traffic.
+ */
+void
+netif_set_up(struct netif *netif)
+{
+  LWIP_ASSERT_CORE_LOCKED();
+
+  LWIP_ERROR("netif_set_up: invalid netif", netif != NULL, return);
+
+  if (!(netif->flags & NETIF_FLAG_UP)) {
+    netif_set_flags(netif, NETIF_FLAG_UP);
+
+    MIB2_COPY_SYSUPTIME_TO(&netif->ts);
+
+    NETIF_STATUS_CALLBACK(netif);
+
+#if LWIP_NETIF_EXT_STATUS_CALLBACK
+    {
+      netif_ext_callback_args_t args;
+      args.status_changed.state = 1;
+      netif_invoke_ext_callback(netif, LWIP_NSC_STATUS_CHANGED, &args);
+    }
+#endif
+
+    netif_issue_reports(netif, NETIF_REPORT_TYPE_IPV4 | NETIF_REPORT_TYPE_IPV6);
+#if LWIP_IPV6
+    nd6_restart_netif(netif);
+#endif /* LWIP_IPV6 */
+  }
+}
+
+/** Send ARP/IGMP/MLD/RS events, e.g. on link-up/netif-up or addr-change
+ */
+static void
+netif_issue_reports(struct netif *netif, u8_t report_type)
+{
+  LWIP_ASSERT("netif_issue_reports: invalid netif", netif != NULL);
+
+  /* Only send reports when both link and admin states are up */
+  if (!(netif->flags & NETIF_FLAG_LINK_UP) ||
+      !(netif->flags & NETIF_FLAG_UP)) {
+    return;
+  }
+
+#if LWIP_IPV4
+  if ((report_type & NETIF_REPORT_TYPE_IPV4) &&
+      !ip4_addr_isany_val(*netif_ip4_addr(netif))) {
+#if LWIP_ARP
+    /* For Ethernet network interfaces, we would like to send a "gratuitous ARP" */
+    if (netif->flags & (NETIF_FLAG_ETHARP)) {
+      etharp_gratuitous(netif);
+    }
+#endif /* LWIP_ARP */
+
+#if LWIP_IGMP
+    /* resend IGMP memberships */
+    if (netif->flags & NETIF_FLAG_IGMP) {
+      igmp_report_groups(netif);
+    }
+#endif /* LWIP_IGMP */
+  }
+#endif /* LWIP_IPV4 */
+
+#if LWIP_IPV6
+  if (report_type & NETIF_REPORT_TYPE_IPV6) {
+#if LWIP_IPV6_MLD
+    /* send mld memberships */
+    mld6_report_groups(netif);
+#endif /* LWIP_IPV6_MLD */
+  }
+#endif /* LWIP_IPV6 */
+}
+
+/**
+ * @ingroup netif
+ * Bring an interface down, disabling any traffic processing.
+ */
+void
+netif_set_down(struct netif *netif)
+{
+  LWIP_ASSERT_CORE_LOCKED();
+
+  LWIP_ERROR("netif_set_down: invalid netif", netif != NULL, return);
+
+  if (netif->flags & NETIF_FLAG_UP) {
+#if LWIP_NETIF_EXT_STATUS_CALLBACK
+    {
+      netif_ext_callback_args_t args;
+      args.status_changed.state = 0;
+      netif_invoke_ext_callback(netif, LWIP_NSC_STATUS_CHANGED, &args);
+    }
+#endif
+
+    netif_clear_flags(netif, NETIF_FLAG_UP);
+    MIB2_COPY_SYSUPTIME_TO(&netif->ts);
+
+#if LWIP_IPV4 && LWIP_ARP
+    if (netif->flags & NETIF_FLAG_ETHARP) {
+      etharp_cleanup_netif(netif);
+    }
+#endif /* LWIP_IPV4 && LWIP_ARP */
+
+#if LWIP_IPV6
+    nd6_cleanup_netif(netif);
+#endif /* LWIP_IPV6 */
+
+    NETIF_STATUS_CALLBACK(netif);
+  }
+}
+
+#if LWIP_NETIF_STATUS_CALLBACK
+/**
+ * @ingroup netif
+ * Set callback to be called when interface is brought up/down or address is changed while up
+ */
+void
+netif_set_status_callback(struct netif *netif, netif_status_callback_fn status_callback)
+{
+  LWIP_ASSERT_CORE_LOCKED();
+
+  if (netif) {
+    netif->status_callback = status_callback;
+  }
+}
+#endif /* LWIP_NETIF_STATUS_CALLBACK */
+
+#if LWIP_NETIF_REMOVE_CALLBACK
+/**
+ * @ingroup netif
+ * Set callback to be called when the interface has been removed
+ */
+void
+netif_set_remove_callback(struct netif *netif, netif_status_callback_fn remove_callback)
+{
+  LWIP_ASSERT_CORE_LOCKED();
+
+  if (netif) {
+    netif->remove_callback = remove_callback;
+  }
+}
+#endif /* LWIP_NETIF_REMOVE_CALLBACK */
+
+/**
+ * @ingroup netif
+ * Called by a driver when its link goes up
+ */
+void
+netif_set_link_up(struct netif *netif)
+{
+  LWIP_ASSERT_CORE_LOCKED();
+
+  LWIP_ERROR("netif_set_link_up: invalid netif", netif != NULL, return);
+
+  if (!(netif->flags & NETIF_FLAG_LINK_UP)) {
+    netif_set_flags(netif, NETIF_FLAG_LINK_UP);
+
+#if LWIP_DHCP
+    dhcp_network_changed(netif);
+#endif /* LWIP_DHCP */
+
+#if LWIP_AUTOIP
+    autoip_network_changed(netif);
+#endif /* LWIP_AUTOIP */
+
+    netif_issue_reports(netif, NETIF_REPORT_TYPE_IPV4 | NETIF_REPORT_TYPE_IPV6);
+#if LWIP_IPV6
+    nd6_restart_netif(netif);
+#endif /* LWIP_IPV6 */
+
+    NETIF_LINK_CALLBACK(netif);
+#if LWIP_NETIF_EXT_STATUS_CALLBACK
+    {
+      netif_ext_callback_args_t args;
+      args.link_changed.state = 1;
+      netif_invoke_ext_callback(netif, LWIP_NSC_LINK_CHANGED, &args);
+    }
+#endif
+  }
+}
+
+/**
+ * @ingroup netif
+ * Called by a driver when its link goes down
+ */
+void
+netif_set_link_down(struct netif *netif)
+{
+  LWIP_ASSERT_CORE_LOCKED();
+
+  LWIP_ERROR("netif_set_link_down: invalid netif", netif != NULL, return);
+
+  if (netif->flags & NETIF_FLAG_LINK_UP) {
+    netif_clear_flags(netif, NETIF_FLAG_LINK_UP);
+    NETIF_LINK_CALLBACK(netif);
+#if LWIP_NETIF_EXT_STATUS_CALLBACK
+    {
+      netif_ext_callback_args_t args;
+      args.link_changed.state = 0;
+      netif_invoke_ext_callback(netif, LWIP_NSC_LINK_CHANGED, &args);
+    }
+#endif
+  }
+}
+
+#if LWIP_NETIF_LINK_CALLBACK
+/**
+ * @ingroup netif
+ * Set callback to be called when link is brought up/down
+ */
+void
+netif_set_link_callback(struct netif *netif, netif_status_callback_fn link_callback)
+{
+  LWIP_ASSERT_CORE_LOCKED();
+
+  if (netif) {
+    netif->link_callback = link_callback;
+  }
+}
+#endif /* LWIP_NETIF_LINK_CALLBACK */
+
+#if ENABLE_LOOPBACK
+/**
+ * @ingroup netif
+ * Send an IP packet to be received on the same netif (loopif-like).
+ * The pbuf is simply copied and handed back to netif->input.
+ * In multithreaded mode, this is done directly since netif->input must put
+ * the packet on a queue.
+ * In callback mode, the packet is put on an internal queue and is fed to
+ * netif->input by netif_poll().
+ *
+ * @param netif the lwip network interface structure
+ * @param p the (IP) packet to 'send'
+ * @return ERR_OK if the packet has been sent
+ *         ERR_MEM if the pbuf used to copy the packet couldn't be allocated
+ */
+err_t
+netif_loop_output(struct netif *netif, struct pbuf *p)
+{
+  struct pbuf *r;
+  err_t err;
+  struct pbuf *last;
+#if LWIP_LOOPBACK_MAX_PBUFS
+  u16_t clen = 0;
+#endif /* LWIP_LOOPBACK_MAX_PBUFS */
+  /* If we have a loopif, SNMP counters are adjusted for it,
+   * if not they are adjusted for 'netif'. */
+#if MIB2_STATS
+#if LWIP_HAVE_LOOPIF
+  struct netif *stats_if = &loop_netif;
+#else /* LWIP_HAVE_LOOPIF */
+  struct netif *stats_if = netif;
+#endif /* LWIP_HAVE_LOOPIF */
+#endif /* MIB2_STATS */
+#if LWIP_NETIF_LOOPBACK_MULTITHREADING
+  u8_t schedule_poll = 0;
+#endif /* LWIP_NETIF_LOOPBACK_MULTITHREADING */
+  SYS_ARCH_DECL_PROTECT(lev);
+
+  LWIP_ASSERT("netif_loop_output: invalid netif", netif != NULL);
+  LWIP_ASSERT("netif_loop_output: invalid pbuf", p != NULL);
+
+  /* Allocate a new pbuf */
+  r = pbuf_alloc(PBUF_LINK, p->tot_len, PBUF_RAM);
+  if (r == NULL) {
+    LINK_STATS_INC(link.memerr);
+    LINK_STATS_INC(link.drop);
+    MIB2_STATS_NETIF_INC(stats_if, ifoutdiscards);
+    return ERR_MEM;
+  }
+#if LWIP_LOOPBACK_MAX_PBUFS
+  clen = pbuf_clen(r);
+  /* check for overflow or too many pbuf on queue */
+  if (((netif->loop_cnt_current + clen) < netif->loop_cnt_current) ||
+      ((netif->loop_cnt_current + clen) > LWIP_MIN(LWIP_LOOPBACK_MAX_PBUFS, 0xFFFF))) {
+    pbuf_free(r);
+    LINK_STATS_INC(link.memerr);
+    LINK_STATS_INC(link.drop);
+    MIB2_STATS_NETIF_INC(stats_if, ifoutdiscards);
+    return ERR_MEM;
+  }
+  netif->loop_cnt_current = (u16_t)(netif->loop_cnt_current + clen);
+#endif /* LWIP_LOOPBACK_MAX_PBUFS */
+
+  /* Copy the whole pbuf queue p into the single pbuf r */
+  if ((err = pbuf_copy(r, p)) != ERR_OK) {
+    pbuf_free(r);
+    LINK_STATS_INC(link.memerr);
+    LINK_STATS_INC(link.drop);
+    MIB2_STATS_NETIF_INC(stats_if, ifoutdiscards);
+    return err;
+  }
+
+  /* Put the packet on a linked list which gets emptied through calling
+     netif_poll(). */
+
+  /* let last point to the last pbuf in chain r */
+  for (last = r; last->next != NULL; last = last->next) {
+    /* nothing to do here, just get to the last pbuf */
+  }
+
+  SYS_ARCH_PROTECT(lev);
+  if (netif->loop_first != NULL) {
+    LWIP_ASSERT("if first != NULL, last must also be != NULL", netif->loop_last != NULL);
+    netif->loop_last->next = r;
+    netif->loop_last = last;
+  } else {
+    netif->loop_first = r;
+    netif->loop_last = last;
+#if LWIP_NETIF_LOOPBACK_MULTITHREADING
+    /* No existing packets queued, schedule poll */
+    schedule_poll = 1;
+#endif /* LWIP_NETIF_LOOPBACK_MULTITHREADING */
+  }
+  SYS_ARCH_UNPROTECT(lev);
+
+  LINK_STATS_INC(link.xmit);
+  MIB2_STATS_NETIF_ADD(stats_if, ifoutoctets, p->tot_len);
+  MIB2_STATS_NETIF_INC(stats_if, ifoutucastpkts);
+
+#if LWIP_NETIF_LOOPBACK_MULTITHREADING
+  /* For multithreading environment, schedule a call to netif_poll */
+  if (schedule_poll) {
+    tcpip_try_callback((tcpip_callback_fn)netif_poll, netif);
+  }
+#endif /* LWIP_NETIF_LOOPBACK_MULTITHREADING */
+
+  return ERR_OK;
+}
+
+#if LWIP_HAVE_LOOPIF
+#if LWIP_IPV4
+static err_t
+netif_loop_output_ipv4(struct netif *netif, struct pbuf *p, const ip4_addr_t *addr)
+{
+  LWIP_UNUSED_ARG(addr);
+  return netif_loop_output(netif, p);
+}
+#endif /* LWIP_IPV4 */
+
+#if LWIP_IPV6
+static err_t
+netif_loop_output_ipv6(struct netif *netif, struct pbuf *p, const ip6_addr_t *addr)
+{
+  LWIP_UNUSED_ARG(addr);
+  return netif_loop_output(netif, p);
+}
+#endif /* LWIP_IPV6 */
+#endif /* LWIP_HAVE_LOOPIF */
+
+
+/**
+ * Call netif_poll() in the main loop of your application. This is to prevent
+ * reentering non-reentrant functions like tcp_input(). Packets passed to
+ * netif_loop_output() are put on a list that is passed to netif->input() by
+ * netif_poll().
+ */
+void
+netif_poll(struct netif *netif)
+{
+  /* If we have a loopif, SNMP counters are adjusted for it,
+   * if not they are adjusted for 'netif'. */
+#if MIB2_STATS
+#if LWIP_HAVE_LOOPIF
+  struct netif *stats_if = &loop_netif;
+#else /* LWIP_HAVE_LOOPIF */
+  struct netif *stats_if = netif;
+#endif /* LWIP_HAVE_LOOPIF */
+#endif /* MIB2_STATS */
+  SYS_ARCH_DECL_PROTECT(lev);
+
+  LWIP_ASSERT("netif_poll: invalid netif", netif != NULL);
+
+  /* Get a packet from the list. With SYS_LIGHTWEIGHT_PROT=1, this is protected */
+  SYS_ARCH_PROTECT(lev);
+  while (netif->loop_first != NULL) {
+    struct pbuf *in, *in_end;
+#if LWIP_LOOPBACK_MAX_PBUFS
+    u8_t clen = 1;
+#endif /* LWIP_LOOPBACK_MAX_PBUFS */
+
+    in = in_end = netif->loop_first;
+    while (in_end->len != in_end->tot_len) {
+      LWIP_ASSERT("bogus pbuf: len != tot_len but next == NULL!", in_end->next != NULL);
+      in_end = in_end->next;
+#if LWIP_LOOPBACK_MAX_PBUFS
+      clen++;
+#endif /* LWIP_LOOPBACK_MAX_PBUFS */
+    }
+#if LWIP_LOOPBACK_MAX_PBUFS
+    /* adjust the number of pbufs on queue */
+    LWIP_ASSERT("netif->loop_cnt_current underflow",
+                ((netif->loop_cnt_current - clen) < netif->loop_cnt_current));
+    netif->loop_cnt_current = (u16_t)(netif->loop_cnt_current - clen);
+#endif /* LWIP_LOOPBACK_MAX_PBUFS */
+
+    /* 'in_end' now points to the last pbuf from 'in' */
+    if (in_end == netif->loop_last) {
+      /* this was the last pbuf in the list */
+      netif->loop_first = netif->loop_last = NULL;
+    } else {
+      /* pop the pbuf off the list */
+      netif->loop_first = in_end->next;
+      LWIP_ASSERT("should not be null since first != last!", netif->loop_first != NULL);
+    }
+    /* De-queue the pbuf from its successors on the 'loop_' list. */
+    in_end->next = NULL;
+    SYS_ARCH_UNPROTECT(lev);
+
+    in->if_idx = netif_get_index(netif);
+
+    LINK_STATS_INC(link.recv);
+    MIB2_STATS_NETIF_ADD(stats_if, ifinoctets, in->tot_len);
+    MIB2_STATS_NETIF_INC(stats_if, ifinucastpkts);
+    /* loopback packets are always IP packets! */
+    if (ip_input(in, netif) != ERR_OK) {
+      pbuf_free(in);
+    }
+    SYS_ARCH_PROTECT(lev);
+  }
+  SYS_ARCH_UNPROTECT(lev);
+}
+
+#if !LWIP_NETIF_LOOPBACK_MULTITHREADING
+/**
+ * Calls netif_poll() for every netif on the netif_list.
+ */
+void
+netif_poll_all(void)
+{
+  struct netif *netif;
+  /* loop through netifs */
+  NETIF_FOREACH(netif) {
+    netif_poll(netif);
+  }
+}
+#endif /* !LWIP_NETIF_LOOPBACK_MULTITHREADING */
+#endif /* ENABLE_LOOPBACK */
+
+#if LWIP_NUM_NETIF_CLIENT_DATA > 0
+/**
+ * @ingroup netif_cd
+ * Allocate an index to store data in client_data member of struct netif.
+ * Returned value is an index in mentioned array.
+ * @see LWIP_NUM_NETIF_CLIENT_DATA
+ */
+u8_t
+netif_alloc_client_data_id(void)
+{
+  u8_t result = netif_client_id;
+  netif_client_id++;
+
+  LWIP_ASSERT_CORE_LOCKED();
+
+#if LWIP_NUM_NETIF_CLIENT_DATA > 256
+#error LWIP_NUM_NETIF_CLIENT_DATA must be <= 256
+#endif
+  LWIP_ASSERT("Increase LWIP_NUM_NETIF_CLIENT_DATA in lwipopts.h", result < LWIP_NUM_NETIF_CLIENT_DATA);
+  return (u8_t)(result + LWIP_NETIF_CLIENT_DATA_INDEX_MAX);
+}
+#endif
+
+#if LWIP_IPV6
+/**
+ * @ingroup netif_ip6
+ * Change an IPv6 address of a network interface
+ *
+ * @param netif the network interface to change
+ * @param addr_idx index of the IPv6 address
+ * @param addr6 the new IPv6 address
+ *
+ * @note call netif_ip6_addr_set_state() to set the address valid/temptative
+ */
+void
+netif_ip6_addr_set(struct netif *netif, s8_t addr_idx, const ip6_addr_t *addr6)
+{
+  LWIP_ASSERT_CORE_LOCKED();
+
+  LWIP_ASSERT("netif_ip6_addr_set: invalid netif", netif != NULL);
+  LWIP_ASSERT("netif_ip6_addr_set: invalid addr6", addr6 != NULL);
+
+  netif_ip6_addr_set_parts(netif, addr_idx, addr6->addr[0], addr6->addr[1],
+                           addr6->addr[2], addr6->addr[3]);
+}
+
+/*
+ * Change an IPv6 address of a network interface (internal version taking 4 * u32_t)
+ *
+ * @param netif the network interface to change
+ * @param addr_idx index of the IPv6 address
+ * @param i0 word0 of the new IPv6 address
+ * @param i1 word1 of the new IPv6 address
+ * @param i2 word2 of the new IPv6 address
+ * @param i3 word3 of the new IPv6 address
+ */
+void
+netif_ip6_addr_set_parts(struct netif *netif, s8_t addr_idx, u32_t i0, u32_t i1, u32_t i2, u32_t i3)
+{
+  ip_addr_t old_addr;
+  ip_addr_t new_ipaddr;
+  LWIP_ASSERT_CORE_LOCKED();
+  LWIP_ASSERT("netif != NULL", netif != NULL);
+  LWIP_ASSERT("invalid index", addr_idx < LWIP_IPV6_NUM_ADDRESSES);
+
+  ip6_addr_copy(*ip_2_ip6(&old_addr), *netif_ip6_addr(netif, addr_idx));
+  IP_SET_TYPE_VAL(old_addr, IPADDR_TYPE_V6);
+
+  /* address is actually being changed? */
+  if ((ip_2_ip6(&old_addr)->addr[0] != i0) || (ip_2_ip6(&old_addr)->addr[1] != i1) ||
+      (ip_2_ip6(&old_addr)->addr[2] != i2) || (ip_2_ip6(&old_addr)->addr[3] != i3)) {
+    LWIP_DEBUGF(NETIF_DEBUG | LWIP_DBG_STATE, ("netif_ip6_addr_set: netif address being changed\n"));
+
+    IP_ADDR6(&new_ipaddr, i0, i1, i2, i3);
+    ip6_addr_assign_zone(ip_2_ip6(&new_ipaddr), IP6_UNICAST, netif);
+
+    if (ip6_addr_isvalid(netif_ip6_addr_state(netif, addr_idx))) {
+      netif_do_ip_addr_changed(netif_ip_addr6(netif, addr_idx), &new_ipaddr);
+    }
+    /* @todo: remove/readd mib2 ip6 entries? */
+
+    ip_addr_copy(netif->ip6_addr[addr_idx], new_ipaddr);
+
+    if (ip6_addr_isvalid(netif_ip6_addr_state(netif, addr_idx))) {
+      netif_issue_reports(netif, NETIF_REPORT_TYPE_IPV6);
+      NETIF_STATUS_CALLBACK(netif);
+    }
+
+#if LWIP_NETIF_EXT_STATUS_CALLBACK
+    {
+      netif_ext_callback_args_t args;
+      args.ipv6_set.addr_index  = addr_idx;
+      args.ipv6_set.old_address = &old_addr;
+      netif_invoke_ext_callback(netif, LWIP_NSC_IPV6_SET, &args);
+    }
+#endif
+  }
+
+  LWIP_DEBUGF(NETIF_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("netif: IPv6 address %d of interface %c%c set to %s/0x%"X8_F"\n",
+              addr_idx, netif->name[0], netif->name[1], ip6addr_ntoa(netif_ip6_addr(netif, addr_idx)),
+              netif_ip6_addr_state(netif, addr_idx)));
+}
+
+/**
+ * @ingroup netif_ip6
+ * Change the state of an IPv6 address of a network interface
+ * (INVALID, TEMPTATIVE, PREFERRED, DEPRECATED, where TEMPTATIVE
+ * includes the number of checks done, see ip6_addr.h)
+ *
+ * @param netif the network interface to change
+ * @param addr_idx index of the IPv6 address
+ * @param state the new IPv6 address state
+ */
+void
+netif_ip6_addr_set_state(struct netif *netif, s8_t addr_idx, u8_t state)
+{
+  u8_t old_state;
+  LWIP_ASSERT_CORE_LOCKED();
+  LWIP_ASSERT("netif != NULL", netif != NULL);
+  LWIP_ASSERT("invalid index", addr_idx < LWIP_IPV6_NUM_ADDRESSES);
+
+  old_state = netif_ip6_addr_state(netif, addr_idx);
+  /* state is actually being changed? */
+  if (old_state != state) {
+    u8_t old_valid = old_state & IP6_ADDR_VALID;
+    u8_t new_valid = state & IP6_ADDR_VALID;
+    LWIP_DEBUGF(NETIF_DEBUG | LWIP_DBG_STATE, ("netif_ip6_addr_set_state: netif address state being changed\n"));
+
+#if LWIP_IPV6_MLD
+    /* Reevaluate solicited-node multicast group membership. */
+    if (netif->flags & NETIF_FLAG_MLD6) {
+      nd6_adjust_mld_membership(netif, addr_idx, state);
+    }
+#endif /* LWIP_IPV6_MLD */
+
+    if (old_valid && !new_valid) {
+      /* address about to be removed by setting invalid */
+      netif_do_ip_addr_changed(netif_ip_addr6(netif, addr_idx), NULL);
+      /* @todo: remove mib2 ip6 entries? */
+    }
+    netif->ip6_addr_state[addr_idx] = state;
+
+    if (!old_valid && new_valid) {
+      /* address added by setting valid */
+      /* This is a good moment to check that the address is properly zoned. */
+      IP6_ADDR_ZONECHECK_NETIF(netif_ip6_addr(netif, addr_idx), netif);
+      /* @todo: add mib2 ip6 entries? */
+      netif_issue_reports(netif, NETIF_REPORT_TYPE_IPV6);
+    }
+    if ((old_state & ~IP6_ADDR_TENTATIVE_COUNT_MASK) !=
+        (state     & ~IP6_ADDR_TENTATIVE_COUNT_MASK)) {
+      /* address state has changed -> call the callback function */
+      NETIF_STATUS_CALLBACK(netif);
+    }
+
+#if LWIP_NETIF_EXT_STATUS_CALLBACK
+    {
+      netif_ext_callback_args_t args;
+      args.ipv6_addr_state_changed.addr_index = addr_idx;
+      args.ipv6_addr_state_changed.old_state  = old_state;
+      args.ipv6_addr_state_changed.address    = netif_ip_addr6(netif, addr_idx);
+      netif_invoke_ext_callback(netif, LWIP_NSC_IPV6_ADDR_STATE_CHANGED, &args);
+    }
+#endif
+  }
+  LWIP_DEBUGF(NETIF_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("netif: IPv6 address %d of interface %c%c set to %s/0x%"X8_F"\n",
+              addr_idx, netif->name[0], netif->name[1], ip6addr_ntoa(netif_ip6_addr(netif, addr_idx)),
+              netif_ip6_addr_state(netif, addr_idx)));
+}
+
+/**
+ * Checks if a specific local address is present on the netif and returns its
+ * index. Depending on its state, it may or may not be assigned to the
+ * interface (as per RFC terminology).
+ *
+ * The given address may or may not be zoned (i.e., have a zone index other
+ * than IP6_NO_ZONE). If the address is zoned, it must have the correct zone
+ * for the given netif, or no match will be found.
+ *
+ * @param netif the netif to check
+ * @param ip6addr the IPv6 address to find
+ * @return >= 0: address found, this is its index
+ *         -1: address not found on this netif
+ */
+s8_t
+netif_get_ip6_addr_match(struct netif *netif, const ip6_addr_t *ip6addr)
+{
+  s8_t i;
+
+  LWIP_ASSERT_CORE_LOCKED();
+
+  LWIP_ASSERT("netif_get_ip6_addr_match: invalid netif", netif != NULL);
+  LWIP_ASSERT("netif_get_ip6_addr_match: invalid ip6addr", ip6addr != NULL);
+
+#if LWIP_IPV6_SCOPES
+  if (ip6_addr_has_zone(ip6addr) && !ip6_addr_test_zone(ip6addr, netif)) {
+    return -1; /* wrong zone, no match */
+  }
+#endif /* LWIP_IPV6_SCOPES */
+
+  for (i = 0; i < LWIP_IPV6_NUM_ADDRESSES; i++) {
+    if (!ip6_addr_isinvalid(netif_ip6_addr_state(netif, i)) &&
+        ip6_addr_cmp_zoneless(netif_ip6_addr(netif, i), ip6addr)) {
+      return i;
+    }
+  }
+  return -1;
+}
+
+/**
+ * @ingroup netif_ip6
+ * Create a link-local IPv6 address on a netif (stored in slot 0)
+ *
+ * @param netif the netif to create the address on
+ * @param from_mac_48bit if != 0, assume hwadr is a 48-bit MAC address (std conversion)
+ *                       if == 0, use hwaddr directly as interface ID
+ */
+void
+netif_create_ip6_linklocal_address(struct netif *netif, u8_t from_mac_48bit)
+{
+  u8_t i, addr_index;
+
+  LWIP_ASSERT_CORE_LOCKED();
+
+  LWIP_ASSERT("netif_create_ip6_linklocal_address: invalid netif", netif != NULL);
+
+  /* Link-local prefix. */
+  ip_2_ip6(&netif->ip6_addr[0])->addr[0] = PP_HTONL(0xfe800000ul);
+  ip_2_ip6(&netif->ip6_addr[0])->addr[1] = 0;
+
+  /* Generate interface ID. */
+  if (from_mac_48bit) {
+    /* Assume hwaddr is a 48-bit IEEE 802 MAC. Convert to EUI-64 address. Complement Group bit. */
+    ip_2_ip6(&netif->ip6_addr[0])->addr[2] = lwip_htonl((((u32_t)(netif->hwaddr[0] ^ 0x02)) << 24) |
+        ((u32_t)(netif->hwaddr[1]) << 16) |
+        ((u32_t)(netif->hwaddr[2]) << 8) |
+        (0xff));
+    ip_2_ip6(&netif->ip6_addr[0])->addr[3] = lwip_htonl((u32_t)(0xfeul << 24) |
+        ((u32_t)(netif->hwaddr[3]) << 16) |
+        ((u32_t)(netif->hwaddr[4]) << 8) |
+        (netif->hwaddr[5]));
+  } else {
+    /* Use hwaddr directly as interface ID. */
+    ip_2_ip6(&netif->ip6_addr[0])->addr[2] = 0;
+    ip_2_ip6(&netif->ip6_addr[0])->addr[3] = 0;
+
+    addr_index = 3;
+    for (i = 0; (i < 8) && (i < netif->hwaddr_len); i++) {
+      if (i == 4) {
+        addr_index--;
+      }
+      ip_2_ip6(&netif->ip6_addr[0])->addr[addr_index] |= lwip_htonl(((u32_t)(netif->hwaddr[netif->hwaddr_len - i - 1])) << (8 * (i & 0x03)));
+    }
+  }
+
+  /* Set a link-local zone. Even though the zone is implied by the owning
+   * netif, setting the zone anyway has two important conceptual advantages:
+   * 1) it avoids the need for a ton of exceptions in internal code, allowing
+   *    e.g. ip6_addr_cmp() to be used on local addresses;
+   * 2) the properly zoned address is visible externally, e.g. when any outside
+   *    code enumerates available addresses or uses one to bind a socket.
+   * Any external code unaware of address scoping is likely to just ignore the
+   * zone field, so this should not create any compatibility problems. */
+  ip6_addr_assign_zone(ip_2_ip6(&netif->ip6_addr[0]), IP6_UNICAST, netif);
+
+  /* Set address state. */
+#if LWIP_IPV6_DUP_DETECT_ATTEMPTS
+  /* Will perform duplicate address detection (DAD). */
+  netif_ip6_addr_set_state(netif, 0, IP6_ADDR_TENTATIVE);
+#else
+  /* Consider address valid. */
+  netif_ip6_addr_set_state(netif, 0, IP6_ADDR_PREFERRED);
+#endif /* LWIP_IPV6_AUTOCONFIG */
+}
+
+/**
+ * @ingroup netif_ip6
+ * This function allows for the easy addition of a new IPv6 address to an interface.
+ * It takes care of finding an empty slot and then sets the address tentative
+ * (to make sure that all the subsequent processing happens).
+ *
+ * @param netif netif to add the address on
+ * @param ip6addr address to add
+ * @param chosen_idx if != NULL, the chosen IPv6 address index will be stored here
+ */
+err_t
+netif_add_ip6_address(struct netif *netif, const ip6_addr_t *ip6addr, s8_t *chosen_idx)
+{
+  s8_t i;
+
+  LWIP_ASSERT_CORE_LOCKED();
+
+  LWIP_ASSERT("netif_add_ip6_address: invalid netif", netif != NULL);
+  LWIP_ASSERT("netif_add_ip6_address: invalid ip6addr", ip6addr != NULL);
+
+  i = netif_get_ip6_addr_match(netif, ip6addr);
+  if (i >= 0) {
+    /* Address already added */
+    if (chosen_idx != NULL) {
+      *chosen_idx = i;
+    }
+    return ERR_OK;
+  }
+
+  /* Find a free slot. The first one is reserved for link-local addresses. */
+  for (i = ip6_addr_islinklocal(ip6addr) ? 0 : 1; i < LWIP_IPV6_NUM_ADDRESSES; i++) {
+    if (ip6_addr_isinvalid(netif_ip6_addr_state(netif, i))) {
+      ip_addr_copy_from_ip6(netif->ip6_addr[i], *ip6addr);
+      ip6_addr_assign_zone(ip_2_ip6(&netif->ip6_addr[i]), IP6_UNICAST, netif);
+      netif_ip6_addr_set_state(netif, i, IP6_ADDR_TENTATIVE);
+      if (chosen_idx != NULL) {
+        *chosen_idx = i;
+      }
+      return ERR_OK;
+    }
+  }
+
+  if (chosen_idx != NULL) {
+    *chosen_idx = -1;
+  }
+  return ERR_VAL;
+}
+
+/** Dummy IPv6 output function for netifs not supporting IPv6
+ */
+static err_t
+netif_null_output_ip6(struct netif *netif, struct pbuf *p, const ip6_addr_t *ipaddr)
+{
+  LWIP_UNUSED_ARG(netif);
+  LWIP_UNUSED_ARG(p);
+  LWIP_UNUSED_ARG(ipaddr);
+
+  return ERR_IF;
+}
+#endif /* LWIP_IPV6 */
+
+#if LWIP_IPV4
+/** Dummy IPv4 output function for netifs not supporting IPv4
+ */
+static err_t
+netif_null_output_ip4(struct netif *netif, struct pbuf *p, const ip4_addr_t *ipaddr)
+{
+  LWIP_UNUSED_ARG(netif);
+  LWIP_UNUSED_ARG(p);
+  LWIP_UNUSED_ARG(ipaddr);
+
+  return ERR_IF;
+}
+#endif /* LWIP_IPV4 */
+
+/**
+* @ingroup netif
+* Return the interface index for the netif with name
+* or NETIF_NO_INDEX if not found/on error
+*
+* @param name the name of the netif
+*/
+u8_t
+netif_name_to_index(const char *name)
+{
+  struct netif *netif = netif_find(name);
+  if (netif != NULL) {
+    return netif_get_index(netif);
+  }
+  /* No name found, return invalid index */
+  return NETIF_NO_INDEX;
+}
+
+/**
+* @ingroup netif
+* Return the interface name for the netif matching index
+* or NULL if not found/on error
+*
+* @param idx the interface index of the netif
+* @param name char buffer of at least NETIF_NAMESIZE bytes
+*/
+char *
+netif_index_to_name(u8_t idx, char *name)
+{
+  struct netif *netif = netif_get_by_index(idx);
+
+  if (netif != NULL) {
+    name[0] = netif->name[0];
+    name[1] = netif->name[1];
+    lwip_itoa(&name[2], NETIF_NAMESIZE - 2, netif_index_to_num(idx));
+    return name;
+  }
+  return NULL;
+}
+
+/**
+* @ingroup netif
+* Return the interface for the netif index
+*
+* @param idx index of netif to find
+*/
+struct netif *
+netif_get_by_index(u8_t idx)
+{
+  struct netif *netif;
+
+  LWIP_ASSERT_CORE_LOCKED();
+
+  if (idx != NETIF_NO_INDEX) {
+    NETIF_FOREACH(netif) {
+      if (idx == netif_get_index(netif)) {
+        return netif; /* found! */
+      }
+    }
+  }
+
+  return NULL;
+}
+
+/**
+ * @ingroup netif
+ * Find a network interface by searching for its name
+ *
+ * @param name the name of the netif (like netif->name) plus concatenated number
+ * in ascii representation (e.g. 'en0')
+ */
+struct netif *
+netif_find(const char *name)
+{
+  struct netif *netif;
+  u8_t num;
+
+  LWIP_ASSERT_CORE_LOCKED();
+
+  if (name == NULL) {
+    return NULL;
+  }
+
+  num = (u8_t)atoi(&name[2]);
+
+  NETIF_FOREACH(netif) {
+    if (num == netif->num &&
+        name[0] == netif->name[0] &&
+        name[1] == netif->name[1]) {
+      LWIP_DEBUGF(NETIF_DEBUG, ("netif_find: found %c%c\n", name[0], name[1]));
+      return netif;
+    }
+  }
+  LWIP_DEBUGF(NETIF_DEBUG, ("netif_find: didn't find %c%c\n", name[0], name[1]));
+  return NULL;
+}
+
+#if LWIP_NETIF_EXT_STATUS_CALLBACK
+/**
+ * @ingroup netif
+ * Add extended netif events listener
+ * @param callback pointer to listener structure
+ * @param fn callback function
+ */
+void
+netif_add_ext_callback(netif_ext_callback_t *callback, netif_ext_callback_fn fn)
+{
+  LWIP_ASSERT_CORE_LOCKED();
+  LWIP_ASSERT("callback must be != NULL", callback != NULL);
+  LWIP_ASSERT("fn must be != NULL", fn != NULL);
+
+  callback->callback_fn = fn;
+  callback->next        = ext_callback;
+  ext_callback          = callback;
+}
+
+/**
+ * @ingroup netif
+ * Remove extended netif events listener
+ * @param callback pointer to listener structure
+ */
+void
+netif_remove_ext_callback(netif_ext_callback_t* callback)
+{
+  netif_ext_callback_t *last, *iter;
+
+  LWIP_ASSERT_CORE_LOCKED();
+  LWIP_ASSERT("callback must be != NULL", callback != NULL);
+
+  if (ext_callback == NULL) {
+    return;
+  }
+
+  if (callback == ext_callback) {
+    ext_callback = ext_callback->next;
+  } else {
+    last = ext_callback;
+    for (iter = ext_callback->next; iter != NULL; last = iter, iter = iter->next) {
+      if (iter == callback) {
+        LWIP_ASSERT("last != NULL", last != NULL);
+        last->next = callback->next;
+        callback->next = NULL;
+        return;
+      }
+    }
+  }
+}
+
+/**
+ * Invoke extended netif status event
+ * @param netif netif that is affected by change
+ * @param reason change reason
+ * @param args depends on reason, see reason description
+ */
+void
+netif_invoke_ext_callback(struct netif *netif, netif_nsc_reason_t reason, const netif_ext_callback_args_t *args)
+{
+  netif_ext_callback_t *callback = ext_callback;
+
+  LWIP_ASSERT("netif must be != NULL", netif != NULL);
+
+  while (callback != NULL) {
+    callback->callback_fn(netif, reason, args);
+    callback = callback->next;
+  }
+}
+#endif /* LWIP_NETIF_EXT_STATUS_CALLBACK */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/core/pbuf.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/core/pbuf.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/core/pbuf.c	(revision 457)
@@ -0,0 +1,1514 @@
+/**
+ * @file
+ * Packet buffer management
+ */
+
+/**
+ * @defgroup pbuf Packet buffers (PBUF)
+ * @ingroup infrastructure
+ *
+ * Packets are built from the pbuf data structure. It supports dynamic
+ * memory allocation for packet contents or can reference externally
+ * managed packet contents both in RAM and ROM. Quick allocation for
+ * incoming packets is provided through pools with fixed sized pbufs.
+ *
+ * A packet may span over multiple pbufs, chained as a singly linked
+ * list. This is called a "pbuf chain".
+ *
+ * Multiple packets may be queued, also using this singly linked list.
+ * This is called a "packet queue".
+ *
+ * So, a packet queue consists of one or more pbuf chains, each of
+ * which consist of one or more pbufs. CURRENTLY, PACKET QUEUES ARE
+ * NOT SUPPORTED!!! Use helper structs to queue multiple packets.
+ *
+ * The differences between a pbuf chain and a packet queue are very
+ * precise but subtle.
+ *
+ * The last pbuf of a packet has a ->tot_len field that equals the
+ * ->len field. It can be found by traversing the list. If the last
+ * pbuf of a packet has a ->next field other than NULL, more packets
+ * are on the queue.
+ *
+ * Therefore, looping through a pbuf of a single packet, has an
+ * loop end condition (tot_len == p->len), NOT (next == NULL).
+ *
+ * Example of custom pbuf usage: @ref zerocopyrx
+ */
+
+/*
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Adam Dunkels <adam@sics.se>
+ *
+ */
+
+#include "lwip/opt.h"
+
+#include "lwip/pbuf.h"
+#include "lwip/stats.h"
+#include "lwip/def.h"
+#include "lwip/mem.h"
+#include "lwip/memp.h"
+#include "lwip/sys.h"
+#include "lwip/netif.h"
+#if LWIP_TCP && TCP_QUEUE_OOSEQ
+#include "lwip/priv/tcp_priv.h"
+#endif
+#if LWIP_CHECKSUM_ON_COPY
+#include "lwip/inet_chksum.h"
+#endif
+
+#include <string.h>
+
+#define SIZEOF_STRUCT_PBUF        LWIP_MEM_ALIGN_SIZE(sizeof(struct pbuf))
+/* Since the pool is created in memp, PBUF_POOL_BUFSIZE will be automatically
+   aligned there. Therefore, PBUF_POOL_BUFSIZE_ALIGNED can be used here. */
+#define PBUF_POOL_BUFSIZE_ALIGNED LWIP_MEM_ALIGN_SIZE(PBUF_POOL_BUFSIZE)
+
+static const struct pbuf *
+pbuf_skip_const(const struct pbuf *in, u16_t in_offset, u16_t *out_offset);
+
+#if !LWIP_TCP || !TCP_QUEUE_OOSEQ || !PBUF_POOL_FREE_OOSEQ
+#define PBUF_POOL_IS_EMPTY()
+#else /* !LWIP_TCP || !TCP_QUEUE_OOSEQ || !PBUF_POOL_FREE_OOSEQ */
+
+#if !NO_SYS
+#ifndef PBUF_POOL_FREE_OOSEQ_QUEUE_CALL
+#include "lwip/tcpip.h"
+#define PBUF_POOL_FREE_OOSEQ_QUEUE_CALL()  do { \
+  if (tcpip_try_callback(pbuf_free_ooseq_callback, NULL) != ERR_OK) { \
+      SYS_ARCH_PROTECT(old_level); \
+      pbuf_free_ooseq_pending = 0; \
+      SYS_ARCH_UNPROTECT(old_level); \
+  } } while(0)
+#endif /* PBUF_POOL_FREE_OOSEQ_QUEUE_CALL */
+#endif /* !NO_SYS */
+
+volatile u8_t pbuf_free_ooseq_pending;
+#define PBUF_POOL_IS_EMPTY() pbuf_pool_is_empty()
+
+/**
+ * Attempt to reclaim some memory from queued out-of-sequence TCP segments
+ * if we run out of pool pbufs. It's better to give priority to new packets
+ * if we're running out.
+ *
+ * This must be done in the correct thread context therefore this function
+ * can only be used with NO_SYS=0 and through tcpip_callback.
+ */
+#if !NO_SYS
+static
+#endif /* !NO_SYS */
+void
+pbuf_free_ooseq(void)
+{
+  struct tcp_pcb *pcb;
+  SYS_ARCH_SET(pbuf_free_ooseq_pending, 0);
+
+  for (pcb = tcp_active_pcbs; NULL != pcb; pcb = pcb->next) {
+    if (pcb->ooseq != NULL) {
+      /** Free the ooseq pbufs of one PCB only */
+      LWIP_DEBUGF(PBUF_DEBUG | LWIP_DBG_TRACE, ("pbuf_free_ooseq: freeing out-of-sequence pbufs\n"));
+      tcp_free_ooseq(pcb);
+      return;
+    }
+  }
+}
+
+#if !NO_SYS
+/**
+ * Just a callback function for tcpip_callback() that calls pbuf_free_ooseq().
+ */
+static void
+pbuf_free_ooseq_callback(void *arg)
+{
+  LWIP_UNUSED_ARG(arg);
+  pbuf_free_ooseq();
+}
+#endif /* !NO_SYS */
+
+/** Queue a call to pbuf_free_ooseq if not already queued. */
+static void
+pbuf_pool_is_empty(void)
+{
+#ifndef PBUF_POOL_FREE_OOSEQ_QUEUE_CALL
+  SYS_ARCH_SET(pbuf_free_ooseq_pending, 1);
+#else /* PBUF_POOL_FREE_OOSEQ_QUEUE_CALL */
+  u8_t queued;
+  SYS_ARCH_DECL_PROTECT(old_level);
+  SYS_ARCH_PROTECT(old_level);
+  queued = pbuf_free_ooseq_pending;
+  pbuf_free_ooseq_pending = 1;
+  SYS_ARCH_UNPROTECT(old_level);
+
+  if (!queued) {
+    /* queue a call to pbuf_free_ooseq if not already queued */
+    PBUF_POOL_FREE_OOSEQ_QUEUE_CALL();
+  }
+#endif /* PBUF_POOL_FREE_OOSEQ_QUEUE_CALL */
+}
+#endif /* !LWIP_TCP || !TCP_QUEUE_OOSEQ || !PBUF_POOL_FREE_OOSEQ */
+
+/* Initialize members of struct pbuf after allocation */
+static void
+pbuf_init_alloced_pbuf(struct pbuf *p, void *payload, u16_t tot_len, u16_t len, pbuf_type type, u8_t flags)
+{
+  p->next = NULL;
+  p->payload = payload;
+  p->tot_len = tot_len;
+  p->len = len;
+  p->type_internal = (u8_t)type;
+  p->flags = flags;
+  p->ref = 1;
+  p->if_idx = NETIF_NO_INDEX;
+}
+
+/**
+ * @ingroup pbuf
+ * Allocates a pbuf of the given type (possibly a chain for PBUF_POOL type).
+ *
+ * The actual memory allocated for the pbuf is determined by the
+ * layer at which the pbuf is allocated and the requested size
+ * (from the size parameter).
+ *
+ * @param layer header size
+ * @param length size of the pbuf's payload
+ * @param type this parameter decides how and where the pbuf
+ * should be allocated as follows:
+ *
+ * - PBUF_RAM: buffer memory for pbuf is allocated as one large
+ *             chunk. This includes protocol headers as well.
+ * - PBUF_ROM: no buffer memory is allocated for the pbuf, even for
+ *             protocol headers. Additional headers must be prepended
+ *             by allocating another pbuf and chain in to the front of
+ *             the ROM pbuf. It is assumed that the memory used is really
+ *             similar to ROM in that it is immutable and will not be
+ *             changed. Memory which is dynamic should generally not
+ *             be attached to PBUF_ROM pbufs. Use PBUF_REF instead.
+ * - PBUF_REF: no buffer memory is allocated for the pbuf, even for
+ *             protocol headers. It is assumed that the pbuf is only
+ *             being used in a single thread. If the pbuf gets queued,
+ *             then pbuf_take should be called to copy the buffer.
+ * - PBUF_POOL: the pbuf is allocated as a pbuf chain, with pbufs from
+ *              the pbuf pool that is allocated during pbuf_init().
+ *
+ * @return the allocated pbuf. If multiple pbufs where allocated, this
+ * is the first pbuf of a pbuf chain.
+ */
+struct pbuf *
+pbuf_alloc(pbuf_layer layer, u16_t length, pbuf_type type)
+{
+  struct pbuf *p;
+  u16_t offset = (u16_t)layer;
+  LWIP_DEBUGF(PBUF_DEBUG | LWIP_DBG_TRACE, ("pbuf_alloc(length=%"U16_F")\n", length));
+
+  switch (type) {
+    case PBUF_REF: /* fall through */
+    case PBUF_ROM:
+      p = pbuf_alloc_reference(NULL, length, type);
+      break;
+    case PBUF_POOL: {
+      struct pbuf *q, *last;
+      u16_t rem_len; /* remaining length */
+      p = NULL;
+      last = NULL;
+      rem_len = length;
+      do {
+        u16_t qlen;
+        q = (struct pbuf *)memp_malloc(MEMP_PBUF_POOL);
+        if (q == NULL) {
+          PBUF_POOL_IS_EMPTY();
+          /* free chain so far allocated */
+          if (p) {
+            pbuf_free(p);
+          }
+          /* bail out unsuccessfully */
+          return NULL;
+        }
+        qlen = LWIP_MIN(rem_len, (u16_t)(PBUF_POOL_BUFSIZE_ALIGNED - LWIP_MEM_ALIGN_SIZE(offset)));
+        pbuf_init_alloced_pbuf(q, LWIP_MEM_ALIGN((void *)((u8_t *)q + SIZEOF_STRUCT_PBUF + offset)),
+                               rem_len, qlen, type, 0);
+        LWIP_ASSERT("pbuf_alloc: pbuf q->payload properly aligned",
+                    ((mem_ptr_t)q->payload % MEM_ALIGNMENT) == 0);
+        LWIP_ASSERT("PBUF_POOL_BUFSIZE must be bigger than MEM_ALIGNMENT",
+                    (PBUF_POOL_BUFSIZE_ALIGNED - LWIP_MEM_ALIGN_SIZE(offset)) > 0 );
+        if (p == NULL) {
+          /* allocated head of pbuf chain (into p) */
+          p = q;
+        } else {
+          /* make previous pbuf point to this pbuf */
+          last->next = q;
+        }
+        last = q;
+        rem_len = (u16_t)(rem_len - qlen);
+        offset = 0;
+      } while (rem_len > 0);
+      break;
+    }
+    case PBUF_RAM: {
+      u16_t payload_len = (u16_t)(LWIP_MEM_ALIGN_SIZE(offset) + LWIP_MEM_ALIGN_SIZE(length));
+      mem_size_t alloc_len = (mem_size_t)(LWIP_MEM_ALIGN_SIZE(SIZEOF_STRUCT_PBUF) + payload_len);
+
+      /* bug #50040: Check for integer overflow when calculating alloc_len */
+      if ((payload_len < LWIP_MEM_ALIGN_SIZE(length)) ||
+          (alloc_len < LWIP_MEM_ALIGN_SIZE(length))) {
+        return NULL;
+      }
+
+      /* If pbuf is to be allocated in RAM, allocate memory for it. */
+      p = (struct pbuf *)mem_malloc(alloc_len);
+      if (p == NULL) {
+        return NULL;
+      }
+      pbuf_init_alloced_pbuf(p, LWIP_MEM_ALIGN((void *)((u8_t *)p + SIZEOF_STRUCT_PBUF + offset)),
+                             length, length, type, 0);
+      LWIP_ASSERT("pbuf_alloc: pbuf->payload properly aligned",
+                  ((mem_ptr_t)p->payload % MEM_ALIGNMENT) == 0);
+      break;
+    }
+    default:
+      LWIP_ASSERT("pbuf_alloc: erroneous type", 0);
+      return NULL;
+  }
+  LWIP_DEBUGF(PBUF_DEBUG | LWIP_DBG_TRACE, ("pbuf_alloc(length=%"U16_F") == %p\n", length, (void *)p));
+  return p;
+}
+
+/**
+ * @ingroup pbuf
+ * Allocates a pbuf for referenced data.
+ * Referenced data can be volatile (PBUF_REF) or long-lived (PBUF_ROM).
+ *
+ * The actual memory allocated for the pbuf is determined by the
+ * layer at which the pbuf is allocated and the requested size
+ * (from the size parameter).
+ *
+ * @param payload referenced payload
+ * @param length size of the pbuf's payload
+ * @param type this parameter decides how and where the pbuf
+ * should be allocated as follows:
+ *
+ * - PBUF_ROM: It is assumed that the memory used is really
+ *             similar to ROM in that it is immutable and will not be
+ *             changed. Memory which is dynamic should generally not
+ *             be attached to PBUF_ROM pbufs. Use PBUF_REF instead.
+ * - PBUF_REF: It is assumed that the pbuf is only
+ *             being used in a single thread. If the pbuf gets queued,
+ *             then pbuf_take should be called to copy the buffer.
+ *
+ * @return the allocated pbuf.
+ */
+struct pbuf *
+pbuf_alloc_reference(void *payload, u16_t length, pbuf_type type)
+{
+  struct pbuf *p;
+  LWIP_ASSERT("invalid pbuf_type", (type == PBUF_REF) || (type == PBUF_ROM));
+  /* only allocate memory for the pbuf structure */
+  p = (struct pbuf *)memp_malloc(MEMP_PBUF);
+  if (p == NULL) {
+    LWIP_DEBUGF(PBUF_DEBUG | LWIP_DBG_LEVEL_SERIOUS,
+                ("pbuf_alloc_reference: Could not allocate MEMP_PBUF for PBUF_%s.\n",
+                 (type == PBUF_ROM) ? "ROM" : "REF"));
+    return NULL;
+  }
+  pbuf_init_alloced_pbuf(p, payload, length, length, type, 0);
+  return p;
+}
+
+
+#if LWIP_SUPPORT_CUSTOM_PBUF
+/**
+ * @ingroup pbuf
+ * Initialize a custom pbuf (already allocated).
+ * Example of custom pbuf usage: @ref zerocopyrx
+ *
+ * @param l header size
+ * @param length size of the pbuf's payload
+ * @param type type of the pbuf (only used to treat the pbuf accordingly, as
+ *        this function allocates no memory)
+ * @param p pointer to the custom pbuf to initialize (already allocated)
+ * @param payload_mem pointer to the buffer that is used for payload and headers,
+ *        must be at least big enough to hold 'length' plus the header size,
+ *        may be NULL if set later.
+ *        ATTENTION: The caller is responsible for correct alignment of this buffer!!
+ * @param payload_mem_len the size of the 'payload_mem' buffer, must be at least
+ *        big enough to hold 'length' plus the header size
+ */
+struct pbuf *
+pbuf_alloced_custom(pbuf_layer l, u16_t length, pbuf_type type, struct pbuf_custom *p,
+                    void *payload_mem, u16_t payload_mem_len)
+{
+  u16_t offset = (u16_t)l;
+  void *payload;
+  LWIP_DEBUGF(PBUF_DEBUG | LWIP_DBG_TRACE, ("pbuf_alloced_custom(length=%"U16_F")\n", length));
+
+  if (LWIP_MEM_ALIGN_SIZE(offset) + length > payload_mem_len) {
+    LWIP_DEBUGF(PBUF_DEBUG | LWIP_DBG_LEVEL_WARNING, ("pbuf_alloced_custom(length=%"U16_F") buffer too short\n", length));
+    return NULL;
+  }
+
+  if (payload_mem != NULL) {
+    payload = (u8_t *)payload_mem + LWIP_MEM_ALIGN_SIZE(offset);
+  } else {
+    payload = NULL;
+  }
+  pbuf_init_alloced_pbuf(&p->pbuf, payload, length, length, type, PBUF_FLAG_IS_CUSTOM);
+  return &p->pbuf;
+}
+#endif /* LWIP_SUPPORT_CUSTOM_PBUF */
+
+/**
+ * @ingroup pbuf
+ * Shrink a pbuf chain to a desired length.
+ *
+ * @param p pbuf to shrink.
+ * @param new_len desired new length of pbuf chain
+ *
+ * Depending on the desired length, the first few pbufs in a chain might
+ * be skipped and left unchanged. The new last pbuf in the chain will be
+ * resized, and any remaining pbufs will be freed.
+ *
+ * @note If the pbuf is ROM/REF, only the ->tot_len and ->len fields are adjusted.
+ * @note May not be called on a packet queue.
+ *
+ * @note Despite its name, pbuf_realloc cannot grow the size of a pbuf (chain).
+ */
+void
+pbuf_realloc(struct pbuf *p, u16_t new_len)
+{
+  struct pbuf *q;
+  u16_t rem_len; /* remaining length */
+  u16_t shrink;
+
+  LWIP_ASSERT("pbuf_realloc: p != NULL", p != NULL);
+
+  /* desired length larger than current length? */
+  if (new_len >= p->tot_len) {
+    /* enlarging not yet supported */
+    return;
+  }
+
+  /* the pbuf chain grows by (new_len - p->tot_len) bytes
+   * (which may be negative in case of shrinking) */
+  shrink = (u16_t)(p->tot_len - new_len);
+
+  /* first, step over any pbufs that should remain in the chain */
+  rem_len = new_len;
+  q = p;
+  /* should this pbuf be kept? */
+  while (rem_len > q->len) {
+    /* decrease remaining length by pbuf length */
+    rem_len = (u16_t)(rem_len - q->len);
+    /* decrease total length indicator */
+    q->tot_len = (u16_t)(q->tot_len - shrink);
+    /* proceed to next pbuf in chain */
+    q = q->next;
+    LWIP_ASSERT("pbuf_realloc: q != NULL", q != NULL);
+  }
+  /* we have now reached the new last pbuf (in q) */
+  /* rem_len == desired length for pbuf q */
+
+  /* shrink allocated memory for PBUF_RAM */
+  /* (other types merely adjust their length fields */
+  if (pbuf_match_allocsrc(q, PBUF_TYPE_ALLOC_SRC_MASK_STD_HEAP) && (rem_len != q->len)
+#if LWIP_SUPPORT_CUSTOM_PBUF
+      && ((q->flags & PBUF_FLAG_IS_CUSTOM) == 0)
+#endif /* LWIP_SUPPORT_CUSTOM_PBUF */
+     ) {
+    /* reallocate and adjust the length of the pbuf that will be split */
+    q = (struct pbuf *)mem_trim(q, (mem_size_t)(((u8_t *)q->payload - (u8_t *)q) + rem_len));
+    LWIP_ASSERT("mem_trim returned q == NULL", q != NULL);
+  }
+  /* adjust length fields for new last pbuf */
+  q->len = rem_len;
+  q->tot_len = q->len;
+
+  /* any remaining pbufs in chain? */
+  if (q->next != NULL) {
+    /* free remaining pbufs in chain */
+    pbuf_free(q->next);
+  }
+  /* q is last packet in chain */
+  q->next = NULL;
+
+}
+
+/**
+ * Adjusts the payload pointer to reveal headers in the payload.
+ * @see pbuf_add_header.
+ *
+ * @param p pbuf to change the header size.
+ * @param header_size_increment Number of bytes to increment header size.
+ * @param force Allow 'header_size_increment > 0' for PBUF_REF/PBUF_ROM types
+ *
+ * @return non-zero on failure, zero on success.
+ *
+ */
+static u8_t
+pbuf_add_header_impl(struct pbuf *p, size_t header_size_increment, u8_t force)
+{
+  u16_t type_internal;
+  void *payload;
+  u16_t increment_magnitude;
+
+  LWIP_ASSERT("p != NULL", p != NULL);
+  if ((p == NULL) || (header_size_increment > 0xFFFF)) {
+    return 1;
+  }
+  if (header_size_increment == 0) {
+    return 0;
+  }
+
+  increment_magnitude = (u16_t)header_size_increment;
+  /* Do not allow tot_len to wrap as a result. */
+  if ((u16_t)(increment_magnitude + p->tot_len) < increment_magnitude) {
+    return 1;
+  }
+
+  type_internal = p->type_internal;
+
+  /* pbuf types containing payloads? */
+  if (type_internal & PBUF_TYPE_FLAG_STRUCT_DATA_CONTIGUOUS) {
+    /* set new payload pointer */
+    payload = (u8_t *)p->payload - header_size_increment;
+    /* boundary check fails? */
+    if ((u8_t *)payload < (u8_t *)p + SIZEOF_STRUCT_PBUF) {
+      LWIP_DEBUGF( PBUF_DEBUG | LWIP_DBG_TRACE,
+                   ("pbuf_add_header: failed as %p < %p (not enough space for new header size)\n",
+                    (void *)payload, (void *)((u8_t *)p + SIZEOF_STRUCT_PBUF)));
+      /* bail out unsuccessfully */
+      return 1;
+    }
+    /* pbuf types referring to external payloads? */
+  } else {
+    /* hide a header in the payload? */
+    if (force) {
+      payload = (u8_t *)p->payload - header_size_increment;
+    } else {
+      /* cannot expand payload to front (yet!)
+       * bail out unsuccessfully */
+      return 1;
+    }
+  }
+  LWIP_DEBUGF(PBUF_DEBUG | LWIP_DBG_TRACE, ("pbuf_add_header: old %p new %p (%"U16_F")\n",
+              (void *)p->payload, (void *)payload, increment_magnitude));
+
+  /* modify pbuf fields */
+  p->payload = payload;
+  p->len = (u16_t)(p->len + increment_magnitude);
+  p->tot_len = (u16_t)(p->tot_len + increment_magnitude);
+
+
+  return 0;
+}
+
+/**
+ * Adjusts the payload pointer to reveal headers in the payload.
+ *
+ * Adjusts the ->payload pointer so that space for a header
+ * appears in the pbuf payload.
+ *
+ * The ->payload, ->tot_len and ->len fields are adjusted.
+ *
+ * @param p pbuf to change the header size.
+ * @param header_size_increment Number of bytes to increment header size which
+ *          increases the size of the pbuf. New space is on the front.
+ *          If header_size_increment is 0, this function does nothing and returns successful.
+ *
+ * PBUF_ROM and PBUF_REF type buffers cannot have their sizes increased, so
+ * the call will fail. A check is made that the increase in header size does
+ * not move the payload pointer in front of the start of the buffer.
+ *
+ * @return non-zero on failure, zero on success.
+ *
+ */
+u8_t
+pbuf_add_header(struct pbuf *p, size_t header_size_increment)
+{
+  return pbuf_add_header_impl(p, header_size_increment, 0);
+}
+
+/**
+ * Same as @ref pbuf_add_header but does not check if 'header_size > 0' is allowed.
+ * This is used internally only, to allow PBUF_REF for RX.
+ */
+u8_t
+pbuf_add_header_force(struct pbuf *p, size_t header_size_increment)
+{
+  return pbuf_add_header_impl(p, header_size_increment, 1);
+}
+
+/**
+ * Adjusts the payload pointer to hide headers in the payload.
+ *
+ * Adjusts the ->payload pointer so that space for a header
+ * disappears in the pbuf payload.
+ *
+ * The ->payload, ->tot_len and ->len fields are adjusted.
+ *
+ * @param p pbuf to change the header size.
+ * @param header_size_decrement Number of bytes to decrement header size which
+ *          decreases the size of the pbuf.
+ *          If header_size_decrement is 0, this function does nothing and returns successful.
+ * @return non-zero on failure, zero on success.
+ *
+ */
+u8_t
+pbuf_remove_header(struct pbuf *p, size_t header_size_decrement)
+{
+  void *payload;
+  u16_t increment_magnitude;
+
+  LWIP_ASSERT("p != NULL", p != NULL);
+  if ((p == NULL) || (header_size_decrement > 0xFFFF)) {
+    return 1;
+  }
+  if (header_size_decrement == 0) {
+    return 0;
+  }
+
+  increment_magnitude = (u16_t)header_size_decrement;
+  /* Check that we aren't going to move off the end of the pbuf */
+  LWIP_ERROR("increment_magnitude <= p->len", (increment_magnitude <= p->len), return 1;);
+
+  /* remember current payload pointer */
+  payload = p->payload;
+  LWIP_UNUSED_ARG(payload); /* only used in LWIP_DEBUGF below */
+
+  /* increase payload pointer (guarded by length check above) */
+  p->payload = (u8_t *)p->payload + header_size_decrement;
+  /* modify pbuf length fields */
+  p->len = (u16_t)(p->len - increment_magnitude);
+  p->tot_len = (u16_t)(p->tot_len - increment_magnitude);
+
+  LWIP_DEBUGF(PBUF_DEBUG | LWIP_DBG_TRACE, ("pbuf_remove_header: old %p new %p (%"U16_F")\n",
+              (void *)payload, (void *)p->payload, increment_magnitude));
+
+  return 0;
+}
+
+static u8_t
+pbuf_header_impl(struct pbuf *p, s16_t header_size_increment, u8_t force)
+{
+  if (header_size_increment < 0) {
+    return pbuf_remove_header(p, (size_t) - header_size_increment);
+  } else {
+    return pbuf_add_header_impl(p, (size_t)header_size_increment, force);
+  }
+}
+
+/**
+ * Adjusts the payload pointer to hide or reveal headers in the payload.
+ *
+ * Adjusts the ->payload pointer so that space for a header
+ * (dis)appears in the pbuf payload.
+ *
+ * The ->payload, ->tot_len and ->len fields are adjusted.
+ *
+ * @param p pbuf to change the header size.
+ * @param header_size_increment Number of bytes to increment header size which
+ * increases the size of the pbuf. New space is on the front.
+ * (Using a negative value decreases the header size.)
+ * If header_size_increment is 0, this function does nothing and returns successful.
+ *
+ * PBUF_ROM and PBUF_REF type buffers cannot have their sizes increased, so
+ * the call will fail. A check is made that the increase in header size does
+ * not move the payload pointer in front of the start of the buffer.
+ * @return non-zero on failure, zero on success.
+ *
+ */
+u8_t
+pbuf_header(struct pbuf *p, s16_t header_size_increment)
+{
+  return pbuf_header_impl(p, header_size_increment, 0);
+}
+
+/**
+ * Same as pbuf_header but does not check if 'header_size > 0' is allowed.
+ * This is used internally only, to allow PBUF_REF for RX.
+ */
+u8_t
+pbuf_header_force(struct pbuf *p, s16_t header_size_increment)
+{
+  return pbuf_header_impl(p, header_size_increment, 1);
+}
+
+/** Similar to pbuf_header(-size) but de-refs header pbufs for (size >= p->len)
+ *
+ * @param q pbufs to operate on
+ * @param size The number of bytes to remove from the beginning of the pbuf list.
+ *             While size >= p->len, pbufs are freed.
+ *        ATTENTION: this is the opposite direction as @ref pbuf_header, but
+ *                   takes an u16_t not s16_t!
+ * @return the new head pbuf
+ */
+struct pbuf *
+pbuf_free_header(struct pbuf *q, u16_t size)
+{
+  struct pbuf *p = q;
+  u16_t free_left = size;
+  while (free_left && p) {
+    if (free_left >= p->len) {
+      struct pbuf *f = p;
+      free_left = (u16_t)(free_left - p->len);
+      p = p->next;
+      f->next = 0;
+      pbuf_free(f);
+    } else {
+      pbuf_remove_header(p, free_left);
+      free_left = 0;
+    }
+  }
+  return p;
+}
+
+/**
+ * @ingroup pbuf
+ * Dereference a pbuf chain or queue and deallocate any no-longer-used
+ * pbufs at the head of this chain or queue.
+ *
+ * Decrements the pbuf reference count. If it reaches zero, the pbuf is
+ * deallocated.
+ *
+ * For a pbuf chain, this is repeated for each pbuf in the chain,
+ * up to the first pbuf which has a non-zero reference count after
+ * decrementing. So, when all reference counts are one, the whole
+ * chain is free'd.
+ *
+ * @param p The pbuf (chain) to be dereferenced.
+ *
+ * @return the number of pbufs that were de-allocated
+ * from the head of the chain.
+ *
+ * @note MUST NOT be called on a packet queue (Not verified to work yet).
+ * @note the reference counter of a pbuf equals the number of pointers
+ * that refer to the pbuf (or into the pbuf).
+ *
+ * @internal examples:
+ *
+ * Assuming existing chains a->b->c with the following reference
+ * counts, calling pbuf_free(a) results in:
+ *
+ * 1->2->3 becomes ...1->3
+ * 3->3->3 becomes 2->3->3
+ * 1->1->2 becomes ......1
+ * 2->1->1 becomes 1->1->1
+ * 1->1->1 becomes .......
+ *
+ */
+u8_t
+pbuf_free(struct pbuf *p)
+{
+  u8_t alloc_src;
+  struct pbuf *q;
+  u8_t count;
+
+  if (p == NULL) {
+    LWIP_ASSERT("p != NULL", p != NULL);
+    /* if assertions are disabled, proceed with debug output */
+    LWIP_DEBUGF(PBUF_DEBUG | LWIP_DBG_LEVEL_SERIOUS,
+                ("pbuf_free(p == NULL) was called.\n"));
+    return 0;
+  }
+  LWIP_DEBUGF(PBUF_DEBUG | LWIP_DBG_TRACE, ("pbuf_free(%p)\n", (void *)p));
+
+  PERF_START;
+
+  count = 0;
+  /* de-allocate all consecutive pbufs from the head of the chain that
+   * obtain a zero reference count after decrementing*/
+  while (p != NULL) {
+    LWIP_PBUF_REF_T ref;
+    SYS_ARCH_DECL_PROTECT(old_level);
+    /* Since decrementing ref cannot be guaranteed to be a single machine operation
+     * we must protect it. We put the new ref into a local variable to prevent
+     * further protection. */
+    SYS_ARCH_PROTECT(old_level);
+    /* all pbufs in a chain are referenced at least once */
+    LWIP_ASSERT("pbuf_free: p->ref > 0", p->ref > 0);
+    /* decrease reference count (number of pointers to pbuf) */
+    ref = --(p->ref);
+    SYS_ARCH_UNPROTECT(old_level);
+    /* this pbuf is no longer referenced to? */
+    if (ref == 0) {
+      /* remember next pbuf in chain for next iteration */
+      q = p->next;
+      LWIP_DEBUGF( PBUF_DEBUG | LWIP_DBG_TRACE, ("pbuf_free: deallocating %p\n", (void *)p));
+      alloc_src = pbuf_get_allocsrc(p);
+#if LWIP_SUPPORT_CUSTOM_PBUF
+      /* is this a custom pbuf? */
+      if ((p->flags & PBUF_FLAG_IS_CUSTOM) != 0) {
+        struct pbuf_custom *pc = (struct pbuf_custom *)p;
+        LWIP_ASSERT("pc->custom_free_function != NULL", pc->custom_free_function != NULL);
+        pc->custom_free_function(p);
+      } else
+#endif /* LWIP_SUPPORT_CUSTOM_PBUF */
+      {
+        /* is this a pbuf from the pool? */
+        if (alloc_src == PBUF_TYPE_ALLOC_SRC_MASK_STD_MEMP_PBUF_POOL) {
+          memp_free(MEMP_PBUF_POOL, p);
+          /* is this a ROM or RAM referencing pbuf? */
+        } else if (alloc_src == PBUF_TYPE_ALLOC_SRC_MASK_STD_MEMP_PBUF) {
+          memp_free(MEMP_PBUF, p);
+          /* type == PBUF_RAM */
+        } else if (alloc_src == PBUF_TYPE_ALLOC_SRC_MASK_STD_HEAP) {
+          mem_free(p);
+        } else {
+          /* @todo: support freeing other types */
+          LWIP_ASSERT("invalid pbuf type", 0);
+        }
+      }
+      count++;
+      /* proceed to next pbuf */
+      p = q;
+      /* p->ref > 0, this pbuf is still referenced to */
+      /* (and so the remaining pbufs in chain as well) */
+    } else {
+      LWIP_DEBUGF( PBUF_DEBUG | LWIP_DBG_TRACE, ("pbuf_free: %p has ref %"U16_F", ending here.\n", (void *)p, (u16_t)ref));
+      /* stop walking through the chain */
+      p = NULL;
+    }
+  }
+  PERF_STOP("pbuf_free");
+  /* return number of de-allocated pbufs */
+  return count;
+}
+
+/**
+ * Count number of pbufs in a chain
+ *
+ * @param p first pbuf of chain
+ * @return the number of pbufs in a chain
+ */
+u16_t
+pbuf_clen(const struct pbuf *p)
+{
+  u16_t len;
+
+  len = 0;
+  while (p != NULL) {
+    ++len;
+    p = p->next;
+  }
+  return len;
+}
+
+/**
+ * @ingroup pbuf
+ * Increment the reference count of the pbuf.
+ *
+ * @param p pbuf to increase reference counter of
+ *
+ */
+void
+pbuf_ref(struct pbuf *p)
+{
+  /* pbuf given? */
+  if (p != NULL) {
+    SYS_ARCH_SET(p->ref, (LWIP_PBUF_REF_T)(p->ref + 1));
+    LWIP_ASSERT("pbuf ref overflow", p->ref > 0);
+  }
+}
+
+/**
+ * @ingroup pbuf
+ * Concatenate two pbufs (each may be a pbuf chain) and take over
+ * the caller's reference of the tail pbuf.
+ *
+ * @note The caller MAY NOT reference the tail pbuf afterwards.
+ * Use pbuf_chain() for that purpose.
+ *
+ * This function explicitly does not check for tot_len overflow to prevent
+ * failing to queue too long pbufs. This can produce invalid pbufs, so
+ * handle with care!
+ *
+ * @see pbuf_chain()
+ */
+void
+pbuf_cat(struct pbuf *h, struct pbuf *t)
+{
+  struct pbuf *p;
+
+  LWIP_ERROR("(h != NULL) && (t != NULL) (programmer violates API)",
+             ((h != NULL) && (t != NULL)), return;);
+
+  /* proceed to last pbuf of chain */
+  for (p = h; p->next != NULL; p = p->next) {
+    /* add total length of second chain to all totals of first chain */
+    p->tot_len = (u16_t)(p->tot_len + t->tot_len);
+  }
+  /* { p is last pbuf of first h chain, p->next == NULL } */
+  LWIP_ASSERT("p->tot_len == p->len (of last pbuf in chain)", p->tot_len == p->len);
+  LWIP_ASSERT("p->next == NULL", p->next == NULL);
+  /* add total length of second chain to last pbuf total of first chain */
+  p->tot_len = (u16_t)(p->tot_len + t->tot_len);
+  /* chain last pbuf of head (p) with first of tail (t) */
+  p->next = t;
+  /* p->next now references t, but the caller will drop its reference to t,
+   * so netto there is no change to the reference count of t.
+   */
+}
+
+/**
+ * @ingroup pbuf
+ * Chain two pbufs (or pbuf chains) together.
+ *
+ * The caller MUST call pbuf_free(t) once it has stopped
+ * using it. Use pbuf_cat() instead if you no longer use t.
+ *
+ * @param h head pbuf (chain)
+ * @param t tail pbuf (chain)
+ * @note The pbufs MUST belong to the same packet.
+ * @note MAY NOT be called on a packet queue.
+ *
+ * The ->tot_len fields of all pbufs of the head chain are adjusted.
+ * The ->next field of the last pbuf of the head chain is adjusted.
+ * The ->ref field of the first pbuf of the tail chain is adjusted.
+ *
+ */
+void
+pbuf_chain(struct pbuf *h, struct pbuf *t)
+{
+  pbuf_cat(h, t);
+  /* t is now referenced by h */
+  pbuf_ref(t);
+  LWIP_DEBUGF(PBUF_DEBUG | LWIP_DBG_TRACE, ("pbuf_chain: %p references %p\n", (void *)h, (void *)t));
+}
+
+/**
+ * Dechains the first pbuf from its succeeding pbufs in the chain.
+ *
+ * Makes p->tot_len field equal to p->len.
+ * @param p pbuf to dechain
+ * @return remainder of the pbuf chain, or NULL if it was de-allocated.
+ * @note May not be called on a packet queue.
+ */
+struct pbuf *
+pbuf_dechain(struct pbuf *p)
+{
+  struct pbuf *q;
+  u8_t tail_gone = 1;
+  /* tail */
+  q = p->next;
+  /* pbuf has successor in chain? */
+  if (q != NULL) {
+    /* assert tot_len invariant: (p->tot_len == p->len + (p->next? p->next->tot_len: 0) */
+    LWIP_ASSERT("p->tot_len == p->len + q->tot_len", q->tot_len == p->tot_len - p->len);
+    /* enforce invariant if assertion is disabled */
+    q->tot_len = (u16_t)(p->tot_len - p->len);
+    /* decouple pbuf from remainder */
+    p->next = NULL;
+    /* total length of pbuf p is its own length only */
+    p->tot_len = p->len;
+    /* q is no longer referenced by p, free it */
+    LWIP_DEBUGF(PBUF_DEBUG | LWIP_DBG_TRACE, ("pbuf_dechain: unreferencing %p\n", (void *)q));
+    tail_gone = pbuf_free(q);
+    if (tail_gone > 0) {
+      LWIP_DEBUGF(PBUF_DEBUG | LWIP_DBG_TRACE,
+                  ("pbuf_dechain: deallocated %p (as it is no longer referenced)\n", (void *)q));
+    }
+    /* return remaining tail or NULL if deallocated */
+  }
+  /* assert tot_len invariant: (p->tot_len == p->len + (p->next? p->next->tot_len: 0) */
+  LWIP_ASSERT("p->tot_len == p->len", p->tot_len == p->len);
+  return ((tail_gone > 0) ? NULL : q);
+}
+
+/**
+ * @ingroup pbuf
+ * Create PBUF_RAM copies of pbufs.
+ *
+ * Used to queue packets on behalf of the lwIP stack, such as
+ * ARP based queueing.
+ *
+ * @note You MUST explicitly use p = pbuf_take(p);
+ *
+ * @note Only one packet is copied, no packet queue!
+ *
+ * @param p_to pbuf destination of the copy
+ * @param p_from pbuf source of the copy
+ *
+ * @return ERR_OK if pbuf was copied
+ *         ERR_ARG if one of the pbufs is NULL or p_to is not big
+ *                 enough to hold p_from
+ */
+err_t
+pbuf_copy(struct pbuf *p_to, const struct pbuf *p_from)
+{
+  size_t offset_to = 0, offset_from = 0, len;
+
+  LWIP_DEBUGF(PBUF_DEBUG | LWIP_DBG_TRACE, ("pbuf_copy(%p, %p)\n",
+              (const void *)p_to, (const void *)p_from));
+
+  /* is the target big enough to hold the source? */
+  LWIP_ERROR("pbuf_copy: target not big enough to hold source", ((p_to != NULL) &&
+             (p_from != NULL) && (p_to->tot_len >= p_from->tot_len)), return ERR_ARG;);
+
+  /* iterate through pbuf chain */
+  do {
+    /* copy one part of the original chain */
+    if ((p_to->len - offset_to) >= (p_from->len - offset_from)) {
+      /* complete current p_from fits into current p_to */
+      len = p_from->len - offset_from;
+    } else {
+      /* current p_from does not fit into current p_to */
+      len = p_to->len - offset_to;
+    }
+    MEMCPY((u8_t *)p_to->payload + offset_to, (u8_t *)p_from->payload + offset_from, len);
+    offset_to += len;
+    offset_from += len;
+    LWIP_ASSERT("offset_to <= p_to->len", offset_to <= p_to->len);
+    LWIP_ASSERT("offset_from <= p_from->len", offset_from <= p_from->len);
+    if (offset_from >= p_from->len) {
+      /* on to next p_from (if any) */
+      offset_from = 0;
+      p_from = p_from->next;
+    }
+    if (offset_to == p_to->len) {
+      /* on to next p_to (if any) */
+      offset_to = 0;
+      p_to = p_to->next;
+      LWIP_ERROR("p_to != NULL", (p_to != NULL) || (p_from == NULL), return ERR_ARG;);
+    }
+
+    if ((p_from != NULL) && (p_from->len == p_from->tot_len)) {
+      /* don't copy more than one packet! */
+      LWIP_ERROR("pbuf_copy() does not allow packet queues!",
+                 (p_from->next == NULL), return ERR_VAL;);
+    }
+    if ((p_to != NULL) && (p_to->len == p_to->tot_len)) {
+      /* don't copy more than one packet! */
+      LWIP_ERROR("pbuf_copy() does not allow packet queues!",
+                 (p_to->next == NULL), return ERR_VAL;);
+    }
+  } while (p_from);
+  LWIP_DEBUGF(PBUF_DEBUG | LWIP_DBG_TRACE, ("pbuf_copy: end of chain reached.\n"));
+  return ERR_OK;
+}
+
+/**
+ * @ingroup pbuf
+ * Copy (part of) the contents of a packet buffer
+ * to an application supplied buffer.
+ *
+ * @param buf the pbuf from which to copy data
+ * @param dataptr the application supplied buffer
+ * @param len length of data to copy (dataptr must be big enough). No more
+ * than buf->tot_len will be copied, irrespective of len
+ * @param offset offset into the packet buffer from where to begin copying len bytes
+ * @return the number of bytes copied, or 0 on failure
+ */
+u16_t
+pbuf_copy_partial(const struct pbuf *buf, void *dataptr, u16_t len, u16_t offset)
+{
+  const struct pbuf *p;
+  u16_t left = 0;
+  u16_t buf_copy_len;
+  u16_t copied_total = 0;
+
+  LWIP_ERROR("pbuf_copy_partial: invalid buf", (buf != NULL), return 0;);
+  LWIP_ERROR("pbuf_copy_partial: invalid dataptr", (dataptr != NULL), return 0;);
+
+  /* Note some systems use byte copy if dataptr or one of the pbuf payload pointers are unaligned. */
+  for (p = buf; len != 0 && p != NULL; p = p->next) {
+    if ((offset != 0) && (offset >= p->len)) {
+      /* don't copy from this buffer -> on to the next */
+      offset = (u16_t)(offset - p->len);
+    } else {
+      /* copy from this buffer. maybe only partially. */
+      buf_copy_len = (u16_t)(p->len - offset);
+      if (buf_copy_len > len) {
+        buf_copy_len = len;
+      }
+      /* copy the necessary parts of the buffer */
+      MEMCPY(&((char *)dataptr)[left], &((char *)p->payload)[offset], buf_copy_len);
+      copied_total = (u16_t)(copied_total + buf_copy_len);
+      left = (u16_t)(left + buf_copy_len);
+      len = (u16_t)(len - buf_copy_len);
+      offset = 0;
+    }
+  }
+  return copied_total;
+}
+
+/**
+ * @ingroup pbuf
+ * Get part of a pbuf's payload as contiguous memory. The returned memory is
+ * either a pointer into the pbuf's payload or, if split over multiple pbufs,
+ * a copy into the user-supplied buffer.
+ *
+ * @param p the pbuf from which to copy data
+ * @param buffer the application supplied buffer
+ * @param bufsize size of the application supplied buffer
+ * @param len length of data to copy (dataptr must be big enough). No more
+ * than buf->tot_len will be copied, irrespective of len
+ * @param offset offset into the packet buffer from where to begin copying len bytes
+ * @return the number of bytes copied, or 0 on failure
+ */
+void *
+pbuf_get_contiguous(const struct pbuf *p, void *buffer, size_t bufsize, u16_t len, u16_t offset)
+{
+  const struct pbuf *q;
+  u16_t out_offset;
+
+  LWIP_ERROR("pbuf_get_contiguous: invalid buf", (p != NULL), return NULL;);
+  LWIP_ERROR("pbuf_get_contiguous: invalid dataptr", (buffer != NULL), return NULL;);
+  LWIP_ERROR("pbuf_get_contiguous: invalid dataptr", (bufsize >= len), return NULL;);
+
+  q = pbuf_skip_const(p, offset, &out_offset);
+  if (q != NULL) {
+    if (q->len >= (out_offset + len)) {
+      /* all data in this pbuf, return zero-copy */
+      return (u8_t *)q->payload + out_offset;
+    }
+    /* need to copy */
+    if (pbuf_copy_partial(q, buffer, len, out_offset) != len) {
+      /* copying failed: pbuf is too short */
+      return NULL;
+    }
+    return buffer;
+  }
+  /* pbuf is too short (offset does not fit in) */
+  return NULL;
+}
+
+#if LWIP_TCP && TCP_QUEUE_OOSEQ && LWIP_WND_SCALE
+/**
+ * This method modifies a 'pbuf chain', so that its total length is
+ * smaller than 64K. The remainder of the original pbuf chain is stored
+ * in *rest.
+ * This function never creates new pbufs, but splits an existing chain
+ * in two parts. The tot_len of the modified packet queue will likely be
+ * smaller than 64K.
+ * 'packet queues' are not supported by this function.
+ *
+ * @param p the pbuf queue to be split
+ * @param rest pointer to store the remainder (after the first 64K)
+ */
+void pbuf_split_64k(struct pbuf *p, struct pbuf **rest)
+{
+  *rest = NULL;
+  if ((p != NULL) && (p->next != NULL)) {
+    u16_t tot_len_front = p->len;
+    struct pbuf *i = p;
+    struct pbuf *r = p->next;
+
+    /* continue until the total length (summed up as u16_t) overflows */
+    while ((r != NULL) && ((u16_t)(tot_len_front + r->len) >= tot_len_front)) {
+      tot_len_front = (u16_t)(tot_len_front + r->len);
+      i = r;
+      r = r->next;
+    }
+    /* i now points to last packet of the first segment. Set next
+       pointer to NULL */
+    i->next = NULL;
+
+    if (r != NULL) {
+      /* Update the tot_len field in the first part */
+      for (i = p; i != NULL; i = i->next) {
+        i->tot_len = (u16_t)(i->tot_len - r->tot_len);
+        LWIP_ASSERT("tot_len/len mismatch in last pbuf",
+                    (i->next != NULL) || (i->tot_len == i->len));
+      }
+      if (p->flags & PBUF_FLAG_TCP_FIN) {
+        r->flags |= PBUF_FLAG_TCP_FIN;
+      }
+
+      /* tot_len field in rest does not need modifications */
+      /* reference counters do not need modifications */
+      *rest = r;
+    }
+  }
+}
+#endif /* LWIP_TCP && TCP_QUEUE_OOSEQ && LWIP_WND_SCALE */
+
+/* Actual implementation of pbuf_skip() but returning const pointer... */
+static const struct pbuf *
+pbuf_skip_const(const struct pbuf *in, u16_t in_offset, u16_t *out_offset)
+{
+  u16_t offset_left = in_offset;
+  const struct pbuf *q = in;
+
+  /* get the correct pbuf */
+  while ((q != NULL) && (q->len <= offset_left)) {
+    offset_left = (u16_t)(offset_left - q->len);
+    q = q->next;
+  }
+  if (out_offset != NULL) {
+    *out_offset = offset_left;
+  }
+  return q;
+}
+
+/**
+ * @ingroup pbuf
+ * Skip a number of bytes at the start of a pbuf
+ *
+ * @param in input pbuf
+ * @param in_offset offset to skip
+ * @param out_offset resulting offset in the returned pbuf
+ * @return the pbuf in the queue where the offset is
+ */
+struct pbuf *
+pbuf_skip(struct pbuf *in, u16_t in_offset, u16_t *out_offset)
+{
+  const struct pbuf *out = pbuf_skip_const(in, in_offset, out_offset);
+  return LWIP_CONST_CAST(struct pbuf *, out);
+}
+
+/**
+ * @ingroup pbuf
+ * Copy application supplied data into a pbuf.
+ * This function can only be used to copy the equivalent of buf->tot_len data.
+ *
+ * @param buf pbuf to fill with data
+ * @param dataptr application supplied data buffer
+ * @param len length of the application supplied data buffer
+ *
+ * @return ERR_OK if successful, ERR_MEM if the pbuf is not big enough
+ */
+err_t
+pbuf_take(struct pbuf *buf, const void *dataptr, u16_t len)
+{
+  struct pbuf *p;
+  size_t buf_copy_len;
+  size_t total_copy_len = len;
+  size_t copied_total = 0;
+
+  LWIP_ERROR("pbuf_take: invalid buf", (buf != NULL), return ERR_ARG;);
+  LWIP_ERROR("pbuf_take: invalid dataptr", (dataptr != NULL), return ERR_ARG;);
+  LWIP_ERROR("pbuf_take: buf not large enough", (buf->tot_len >= len), return ERR_MEM;);
+
+  if ((buf == NULL) || (dataptr == NULL) || (buf->tot_len < len)) {
+    return ERR_ARG;
+  }
+
+  /* Note some systems use byte copy if dataptr or one of the pbuf payload pointers are unaligned. */
+  for (p = buf; total_copy_len != 0; p = p->next) {
+    LWIP_ASSERT("pbuf_take: invalid pbuf", p != NULL);
+    buf_copy_len = total_copy_len;
+    if (buf_copy_len > p->len) {
+      /* this pbuf cannot hold all remaining data */
+      buf_copy_len = p->len;
+    }
+    /* copy the necessary parts of the buffer */
+    MEMCPY(p->payload, &((const char *)dataptr)[copied_total], buf_copy_len);
+    total_copy_len -= buf_copy_len;
+    copied_total += buf_copy_len;
+  }
+  LWIP_ASSERT("did not copy all data", total_copy_len == 0 && copied_total == len);
+  return ERR_OK;
+}
+
+/**
+ * @ingroup pbuf
+ * Same as pbuf_take() but puts data at an offset
+ *
+ * @param buf pbuf to fill with data
+ * @param dataptr application supplied data buffer
+ * @param len length of the application supplied data buffer
+ * @param offset offset in pbuf where to copy dataptr to
+ *
+ * @return ERR_OK if successful, ERR_MEM if the pbuf is not big enough
+ */
+err_t
+pbuf_take_at(struct pbuf *buf, const void *dataptr, u16_t len, u16_t offset)
+{
+  u16_t target_offset;
+  struct pbuf *q = pbuf_skip(buf, offset, &target_offset);
+
+  /* return requested data if pbuf is OK */
+  if ((q != NULL) && (q->tot_len >= target_offset + len)) {
+    u16_t remaining_len = len;
+    const u8_t *src_ptr = (const u8_t *)dataptr;
+    /* copy the part that goes into the first pbuf */
+    u16_t first_copy_len;
+    LWIP_ASSERT("check pbuf_skip result", target_offset < q->len);
+    first_copy_len = (u16_t)LWIP_MIN(q->len - target_offset, len);
+    MEMCPY(((u8_t *)q->payload) + target_offset, dataptr, first_copy_len);
+    remaining_len = (u16_t)(remaining_len - first_copy_len);
+    src_ptr += first_copy_len;
+    if (remaining_len > 0) {
+      return pbuf_take(q->next, src_ptr, remaining_len);
+    }
+    return ERR_OK;
+  }
+  return ERR_MEM;
+}
+
+/**
+ * @ingroup pbuf
+ * Creates a single pbuf out of a queue of pbufs.
+ *
+ * @remark: Either the source pbuf 'p' is freed by this function or the original
+ *          pbuf 'p' is returned, therefore the caller has to check the result!
+ *
+ * @param p the source pbuf
+ * @param layer pbuf_layer of the new pbuf
+ *
+ * @return a new, single pbuf (p->next is NULL)
+ *         or the old pbuf if allocation fails
+ */
+struct pbuf *
+pbuf_coalesce(struct pbuf *p, pbuf_layer layer)
+{
+  struct pbuf *q;
+  if (p->next == NULL) {
+    return p;
+  }
+  q = pbuf_clone(layer, PBUF_RAM, p);
+  if (q == NULL) {
+    /* @todo: what do we do now? */
+    return p;
+  }
+  pbuf_free(p);
+  return q;
+}
+
+/**
+ * @ingroup pbuf
+ * Allocates a new pbuf of same length (via pbuf_alloc()) and copies the source
+ * pbuf into this new pbuf (using pbuf_copy()).
+ *
+ * @param layer pbuf_layer of the new pbuf
+ * @param type this parameter decides how and where the pbuf should be allocated
+ *             (@see pbuf_alloc())
+ * @param p the source pbuf
+ *
+ * @return a new pbuf or NULL if allocation fails
+ */
+struct pbuf *
+pbuf_clone(pbuf_layer layer, pbuf_type type, struct pbuf *p)
+{
+  struct pbuf *q;
+  err_t err;
+  q = pbuf_alloc(layer, p->tot_len, type);
+  if (q == NULL) {
+    return NULL;
+  }
+  err = pbuf_copy(q, p);
+  LWIP_UNUSED_ARG(err); /* in case of LWIP_NOASSERT */
+  LWIP_ASSERT("pbuf_copy failed", err == ERR_OK);
+  return q;
+}
+
+#if LWIP_CHECKSUM_ON_COPY
+/**
+ * Copies data into a single pbuf (*not* into a pbuf queue!) and updates
+ * the checksum while copying
+ *
+ * @param p the pbuf to copy data into
+ * @param start_offset offset of p->payload where to copy the data to
+ * @param dataptr data to copy into the pbuf
+ * @param len length of data to copy into the pbuf
+ * @param chksum pointer to the checksum which is updated
+ * @return ERR_OK if successful, another error if the data does not fit
+ *         within the (first) pbuf (no pbuf queues!)
+ */
+err_t
+pbuf_fill_chksum(struct pbuf *p, u16_t start_offset, const void *dataptr,
+                 u16_t len, u16_t *chksum)
+{
+  u32_t acc;
+  u16_t copy_chksum;
+  char *dst_ptr;
+  LWIP_ASSERT("p != NULL", p != NULL);
+  LWIP_ASSERT("dataptr != NULL", dataptr != NULL);
+  LWIP_ASSERT("chksum != NULL", chksum != NULL);
+  LWIP_ASSERT("len != 0", len != 0);
+
+  if ((start_offset >= p->len) || (start_offset + len > p->len)) {
+    return ERR_ARG;
+  }
+
+  dst_ptr = ((char *)p->payload) + start_offset;
+  copy_chksum = LWIP_CHKSUM_COPY(dst_ptr, dataptr, len);
+  if ((start_offset & 1) != 0) {
+    copy_chksum = SWAP_BYTES_IN_WORD(copy_chksum);
+  }
+  acc = *chksum;
+  acc += copy_chksum;
+  *chksum = FOLD_U32T(acc);
+  return ERR_OK;
+}
+#endif /* LWIP_CHECKSUM_ON_COPY */
+
+/**
+ * @ingroup pbuf
+ * Get one byte from the specified position in a pbuf
+ * WARNING: returns zero for offset >= p->tot_len
+ *
+ * @param p pbuf to parse
+ * @param offset offset into p of the byte to return
+ * @return byte at an offset into p OR ZERO IF 'offset' >= p->tot_len
+ */
+u8_t
+pbuf_get_at(const struct pbuf *p, u16_t offset)
+{
+  int ret = pbuf_try_get_at(p, offset);
+  if (ret >= 0) {
+    return (u8_t)ret;
+  }
+  return 0;
+}
+
+/**
+ * @ingroup pbuf
+ * Get one byte from the specified position in a pbuf
+ *
+ * @param p pbuf to parse
+ * @param offset offset into p of the byte to return
+ * @return byte at an offset into p [0..0xFF] OR negative if 'offset' >= p->tot_len
+ */
+int
+pbuf_try_get_at(const struct pbuf *p, u16_t offset)
+{
+  u16_t q_idx;
+  const struct pbuf *q = pbuf_skip_const(p, offset, &q_idx);
+
+  /* return requested data if pbuf is OK */
+  if ((q != NULL) && (q->len > q_idx)) {
+    return ((u8_t *)q->payload)[q_idx];
+  }
+  return -1;
+}
+
+/**
+ * @ingroup pbuf
+ * Put one byte to the specified position in a pbuf
+ * WARNING: silently ignores offset >= p->tot_len
+ *
+ * @param p pbuf to fill
+ * @param offset offset into p of the byte to write
+ * @param data byte to write at an offset into p
+ */
+void
+pbuf_put_at(struct pbuf *p, u16_t offset, u8_t data)
+{
+  u16_t q_idx;
+  struct pbuf *q = pbuf_skip(p, offset, &q_idx);
+
+  /* write requested data if pbuf is OK */
+  if ((q != NULL) && (q->len > q_idx)) {
+    ((u8_t *)q->payload)[q_idx] = data;
+  }
+}
+
+/**
+ * @ingroup pbuf
+ * Compare pbuf contents at specified offset with memory s2, both of length n
+ *
+ * @param p pbuf to compare
+ * @param offset offset into p at which to start comparing
+ * @param s2 buffer to compare
+ * @param n length of buffer to compare
+ * @return zero if equal, nonzero otherwise
+ *         (0xffff if p is too short, diffoffset+1 otherwise)
+ */
+u16_t
+pbuf_memcmp(const struct pbuf *p, u16_t offset, const void *s2, u16_t n)
+{
+  u16_t start = offset;
+  const struct pbuf *q = p;
+  u16_t i;
+
+  /* pbuf long enough to perform check? */
+  if (p->tot_len < (offset + n)) {
+    return 0xffff;
+  }
+
+  /* get the correct pbuf from chain. We know it succeeds because of p->tot_len check above. */
+  while ((q != NULL) && (q->len <= start)) {
+    start = (u16_t)(start - q->len);
+    q = q->next;
+  }
+
+  /* return requested data if pbuf is OK */
+  for (i = 0; i < n; i++) {
+    /* We know pbuf_get_at() succeeds because of p->tot_len check above. */
+    u8_t a = pbuf_get_at(q, (u16_t)(start + i));
+    u8_t b = ((const u8_t *)s2)[i];
+    if (a != b) {
+      return (u16_t)LWIP_MIN(i + 1, 0xFFFF);
+    }
+  }
+  return 0;
+}
+
+/**
+ * @ingroup pbuf
+ * Find occurrence of mem (with length mem_len) in pbuf p, starting at offset
+ * start_offset.
+ *
+ * @param p pbuf to search, maximum length is 0xFFFE since 0xFFFF is used as
+ *        return value 'not found'
+ * @param mem search for the contents of this buffer
+ * @param mem_len length of 'mem'
+ * @param start_offset offset into p at which to start searching
+ * @return 0xFFFF if substr was not found in p or the index where it was found
+ */
+u16_t
+pbuf_memfind(const struct pbuf *p, const void *mem, u16_t mem_len, u16_t start_offset)
+{
+  u16_t i;
+  u16_t max_cmp_start = (u16_t)(p->tot_len - mem_len);
+  if (p->tot_len >= mem_len + start_offset) {
+    for (i = start_offset; i <= max_cmp_start; i++) {
+      u16_t plus = pbuf_memcmp(p, i, mem, mem_len);
+      if (plus == 0) {
+        return i;
+      }
+    }
+  }
+  return 0xFFFF;
+}
+
+/**
+ * Find occurrence of substr with length substr_len in pbuf p, start at offset
+ * start_offset
+ * WARNING: in contrast to strstr(), this one does not stop at the first \0 in
+ * the pbuf/source string!
+ *
+ * @param p pbuf to search, maximum length is 0xFFFE since 0xFFFF is used as
+ *        return value 'not found'
+ * @param substr string to search for in p, maximum length is 0xFFFE
+ * @return 0xFFFF if substr was not found in p or the index where it was found
+ */
+u16_t
+pbuf_strstr(const struct pbuf *p, const char *substr)
+{
+  size_t substr_len;
+  if ((substr == NULL) || (substr[0] == 0) || (p->tot_len == 0xFFFF)) {
+    return 0xFFFF;
+  }
+  substr_len = strlen(substr);
+  if (substr_len >= 0xFFFF) {
+    return 0xFFFF;
+  }
+  return pbuf_memfind(p, substr, (u16_t)substr_len, 0);
+}
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/core/raw.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/core/raw.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/core/raw.c	(revision 457)
@@ -0,0 +1,671 @@
+/**
+ * @file
+ * Implementation of raw protocol PCBs for low-level handling of
+ * different types of protocols besides (or overriding) those
+ * already available in lwIP.\n
+ * See also @ref raw_raw
+ *
+ * @defgroup raw_raw RAW
+ * @ingroup callbackstyle_api
+ * Implementation of raw protocol PCBs for low-level handling of
+ * different types of protocols besides (or overriding) those
+ * already available in lwIP.\n
+ * @see @ref api
+ */
+
+/*
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Adam Dunkels <adam@sics.se>
+ *
+ */
+
+#include "lwip/opt.h"
+
+#if LWIP_RAW /* don't build if not configured for use in lwipopts.h */
+
+#include "lwip/def.h"
+#include "lwip/memp.h"
+#include "lwip/ip_addr.h"
+#include "lwip/netif.h"
+#include "lwip/raw.h"
+#include "lwip/priv/raw_priv.h"
+#include "lwip/stats.h"
+#include "lwip/ip6.h"
+#include "lwip/ip6_addr.h"
+#include "lwip/inet_chksum.h"
+
+#include <string.h>
+
+/** The list of RAW PCBs */
+static struct raw_pcb *raw_pcbs;
+
+static u8_t
+raw_input_local_match(struct raw_pcb *pcb, u8_t broadcast)
+{
+  LWIP_UNUSED_ARG(broadcast); /* in IPv6 only case */
+
+  /* check if PCB is bound to specific netif */
+  if ((pcb->netif_idx != NETIF_NO_INDEX) &&
+      (pcb->netif_idx != netif_get_index(ip_data.current_input_netif))) {
+    return 0;
+  }
+
+#if LWIP_IPV4 && LWIP_IPV6
+  /* Dual-stack: PCBs listening to any IP type also listen to any IP address */
+  if (IP_IS_ANY_TYPE_VAL(pcb->local_ip)) {
+#if IP_SOF_BROADCAST_RECV
+    if ((broadcast != 0) && !ip_get_option(pcb, SOF_BROADCAST)) {
+      return 0;
+    }
+#endif /* IP_SOF_BROADCAST_RECV */
+    return 1;
+  }
+#endif /* LWIP_IPV4 && LWIP_IPV6 */
+
+  /* Only need to check PCB if incoming IP version matches PCB IP version */
+  if (IP_ADDR_PCB_VERSION_MATCH_EXACT(pcb, ip_current_dest_addr())) {
+#if LWIP_IPV4
+    /* Special case: IPv4 broadcast: receive all broadcasts
+     * Note: broadcast variable can only be 1 if it is an IPv4 broadcast */
+    if (broadcast != 0) {
+#if IP_SOF_BROADCAST_RECV
+      if (ip_get_option(pcb, SOF_BROADCAST))
+#endif /* IP_SOF_BROADCAST_RECV */
+      {
+        if (ip4_addr_isany(ip_2_ip4(&pcb->local_ip))) {
+          return 1;
+        }
+      }
+    } else
+#endif /* LWIP_IPV4 */
+      /* Handle IPv4 and IPv6: catch all or exact match */
+      if (ip_addr_isany(&pcb->local_ip) ||
+          ip_addr_cmp(&pcb->local_ip, ip_current_dest_addr())) {
+        return 1;
+      }
+  }
+
+  return 0;
+}
+
+/**
+ * Determine if in incoming IP packet is covered by a RAW PCB
+ * and if so, pass it to a user-provided receive callback function.
+ *
+ * Given an incoming IP datagram (as a chain of pbufs) this function
+ * finds a corresponding RAW PCB and calls the corresponding receive
+ * callback function.
+ *
+ * @param p pbuf to be demultiplexed to a RAW PCB.
+ * @param inp network interface on which the datagram was received.
+ * @return - 1 if the packet has been eaten by a RAW PCB receive
+ *           callback function. The caller MAY NOT not reference the
+ *           packet any longer, and MAY NOT call pbuf_free().
+ * @return - 0 if packet is not eaten (pbuf is still referenced by the
+ *           caller).
+ *
+ */
+raw_input_state_t
+raw_input(struct pbuf *p, struct netif *inp)
+{
+  struct raw_pcb *pcb, *prev;
+  s16_t proto;
+  raw_input_state_t ret = RAW_INPUT_NONE;
+  u8_t broadcast = ip_addr_isbroadcast(ip_current_dest_addr(), ip_current_netif());
+
+  LWIP_UNUSED_ARG(inp);
+
+#if LWIP_IPV6
+#if LWIP_IPV4
+  if (IP_HDR_GET_VERSION(p->payload) == 6)
+#endif /* LWIP_IPV4 */
+  {
+    struct ip6_hdr *ip6hdr = (struct ip6_hdr *)p->payload;
+    proto = IP6H_NEXTH(ip6hdr);
+  }
+#if LWIP_IPV4
+  else
+#endif /* LWIP_IPV4 */
+#endif /* LWIP_IPV6 */
+#if LWIP_IPV4
+  {
+    proto = IPH_PROTO((struct ip_hdr *)p->payload);
+  }
+#endif /* LWIP_IPV4 */
+
+  prev = NULL;
+  pcb = raw_pcbs;
+  /* loop through all raw pcbs until the packet is eaten by one */
+  /* this allows multiple pcbs to match against the packet by design */
+  while (pcb != NULL) {
+    if ((pcb->protocol == proto) && raw_input_local_match(pcb, broadcast) &&
+        (((pcb->flags & RAW_FLAGS_CONNECTED) == 0) ||
+         ip_addr_cmp(&pcb->remote_ip, ip_current_src_addr()))) {
+      /* receive callback function available? */
+      if (pcb->recv != NULL) {
+        u8_t eaten;
+#ifndef LWIP_NOASSERT
+        void *old_payload = p->payload;
+#endif
+        ret = RAW_INPUT_DELIVERED;
+        /* the receive callback function did not eat the packet? */
+        eaten = pcb->recv(pcb->recv_arg, pcb, p, ip_current_src_addr());
+        if (eaten != 0) {
+          /* receive function ate the packet */
+          p = NULL;
+          if (prev != NULL) {
+            /* move the pcb to the front of raw_pcbs so that is
+               found faster next time */
+            prev->next = pcb->next;
+            pcb->next = raw_pcbs;
+            raw_pcbs = pcb;
+          }
+          return RAW_INPUT_EATEN;
+        } else {
+          /* sanity-check that the receive callback did not alter the pbuf */
+          LWIP_ASSERT("raw pcb recv callback altered pbuf payload pointer without eating packet",
+                      p->payload == old_payload);
+        }
+      }
+      /* no receive callback function was set for this raw PCB */
+    }
+    /* drop the packet */
+    prev = pcb;
+    pcb = pcb->next;
+  }
+  return ret;
+}
+
+/**
+ * @ingroup raw_raw
+ * Bind a RAW PCB.
+ *
+ * @param pcb RAW PCB to be bound with a local address ipaddr.
+ * @param ipaddr local IP address to bind with. Use IP4_ADDR_ANY to
+ * bind to all local interfaces.
+ *
+ * @return lwIP error code.
+ * - ERR_OK. Successful. No error occurred.
+ * - ERR_USE. The specified IP address is already bound to by
+ * another RAW PCB.
+ *
+ * @see raw_disconnect()
+ */
+err_t
+raw_bind(struct raw_pcb *pcb, const ip_addr_t *ipaddr)
+{
+  LWIP_ASSERT_CORE_LOCKED();
+  if ((pcb == NULL) || (ipaddr == NULL)) {
+    return ERR_VAL;
+  }
+  ip_addr_set_ipaddr(&pcb->local_ip, ipaddr);
+#if LWIP_IPV6 && LWIP_IPV6_SCOPES
+  /* If the given IP address should have a zone but doesn't, assign one now.
+   * This is legacy support: scope-aware callers should always provide properly
+   * zoned source addresses. */
+  if (IP_IS_V6(&pcb->local_ip) &&
+      ip6_addr_lacks_zone(ip_2_ip6(&pcb->local_ip), IP6_UNKNOWN)) {
+    ip6_addr_select_zone(ip_2_ip6(&pcb->local_ip), ip_2_ip6(&pcb->local_ip));
+  }
+#endif /* LWIP_IPV6 && LWIP_IPV6_SCOPES */
+  return ERR_OK;
+}
+
+/**
+ * @ingroup raw_raw
+ * Bind an RAW PCB to a specific netif.
+ * After calling this function, all packets received via this PCB
+ * are guaranteed to have come in via the specified netif, and all
+ * outgoing packets will go out via the specified netif.
+ *
+ * @param pcb RAW PCB to be bound with netif.
+ * @param netif netif to bind to. Can be NULL.
+ *
+ * @see raw_disconnect()
+ */
+void
+raw_bind_netif(struct raw_pcb *pcb, const struct netif *netif)
+{
+  LWIP_ASSERT_CORE_LOCKED();
+  if (netif != NULL) {
+    pcb->netif_idx = netif_get_index(netif);
+  } else {
+    pcb->netif_idx = NETIF_NO_INDEX;
+  }
+}
+
+/**
+ * @ingroup raw_raw
+ * Connect an RAW PCB. This function is required by upper layers
+ * of lwip. Using the raw api you could use raw_sendto() instead
+ *
+ * This will associate the RAW PCB with the remote address.
+ *
+ * @param pcb RAW PCB to be connected with remote address ipaddr and port.
+ * @param ipaddr remote IP address to connect with.
+ *
+ * @return lwIP error code
+ *
+ * @see raw_disconnect() and raw_sendto()
+ */
+err_t
+raw_connect(struct raw_pcb *pcb, const ip_addr_t *ipaddr)
+{
+  LWIP_ASSERT_CORE_LOCKED();
+  if ((pcb == NULL) || (ipaddr == NULL)) {
+    return ERR_VAL;
+  }
+  ip_addr_set_ipaddr(&pcb->remote_ip, ipaddr);
+#if LWIP_IPV6 && LWIP_IPV6_SCOPES
+  /* If the given IP address should have a zone but doesn't, assign one now,
+   * using the bound address to make a more informed decision when possible. */
+  if (IP_IS_V6(&pcb->remote_ip) &&
+      ip6_addr_lacks_zone(ip_2_ip6(&pcb->remote_ip), IP6_UNKNOWN)) {
+    ip6_addr_select_zone(ip_2_ip6(&pcb->remote_ip), ip_2_ip6(&pcb->local_ip));
+  }
+#endif /* LWIP_IPV6 && LWIP_IPV6_SCOPES */
+  raw_set_flags(pcb, RAW_FLAGS_CONNECTED);
+  return ERR_OK;
+}
+
+/**
+ * @ingroup raw_raw
+ * Disconnect a RAW PCB.
+ *
+ * @param pcb the raw pcb to disconnect.
+ */
+void
+raw_disconnect(struct raw_pcb *pcb)
+{
+  LWIP_ASSERT_CORE_LOCKED();
+  /* reset remote address association */
+#if LWIP_IPV4 && LWIP_IPV6
+  if (IP_IS_ANY_TYPE_VAL(pcb->local_ip)) {
+    ip_addr_copy(pcb->remote_ip, *IP_ANY_TYPE);
+  } else {
+#endif
+    ip_addr_set_any(IP_IS_V6_VAL(pcb->remote_ip), &pcb->remote_ip);
+#if LWIP_IPV4 && LWIP_IPV6
+  }
+#endif
+  pcb->netif_idx = NETIF_NO_INDEX;
+  /* mark PCB as unconnected */
+  raw_clear_flags(pcb, RAW_FLAGS_CONNECTED);
+}
+
+/**
+ * @ingroup raw_raw
+ * Set the callback function for received packets that match the
+ * raw PCB's protocol and binding.
+ *
+ * The callback function MUST either
+ * - eat the packet by calling pbuf_free() and returning non-zero. The
+ *   packet will not be passed to other raw PCBs or other protocol layers.
+ * - not free the packet, and return zero. The packet will be matched
+ *   against further PCBs and/or forwarded to another protocol layers.
+ */
+void
+raw_recv(struct raw_pcb *pcb, raw_recv_fn recv, void *recv_arg)
+{
+  LWIP_ASSERT_CORE_LOCKED();
+  /* remember recv() callback and user data */
+  pcb->recv = recv;
+  pcb->recv_arg = recv_arg;
+}
+
+/**
+ * @ingroup raw_raw
+ * Send the raw IP packet to the given address. An IP header will be prepended
+ * to the packet, unless the RAW_FLAGS_HDRINCL flag is set on the PCB. In that
+ * case, the packet must include an IP header, which will then be sent as is.
+ *
+ * @param pcb the raw pcb which to send
+ * @param p the IP payload to send
+ * @param ipaddr the destination address of the IP packet
+ *
+ */
+err_t
+raw_sendto(struct raw_pcb *pcb, struct pbuf *p, const ip_addr_t *ipaddr)
+{
+  struct netif *netif;
+  const ip_addr_t *src_ip;
+
+  if ((pcb == NULL) || (ipaddr == NULL) || !IP_ADDR_PCB_VERSION_MATCH(pcb, ipaddr)) {
+    return ERR_VAL;
+  }
+
+  LWIP_DEBUGF(RAW_DEBUG | LWIP_DBG_TRACE, ("raw_sendto\n"));
+
+  if (pcb->netif_idx != NETIF_NO_INDEX) {
+    netif = netif_get_by_index(pcb->netif_idx);
+  } else {
+#if LWIP_MULTICAST_TX_OPTIONS
+    netif = NULL;
+    if (ip_addr_ismulticast(ipaddr)) {
+      /* For multicast-destined packets, use the user-provided interface index to
+       * determine the outgoing interface, if an interface index is set and a
+       * matching netif can be found. Otherwise, fall back to regular routing. */
+      netif = netif_get_by_index(pcb->mcast_ifindex);
+    }
+
+    if (netif == NULL)
+#endif /* LWIP_MULTICAST_TX_OPTIONS */
+    {
+      netif = ip_route(&pcb->local_ip, ipaddr);
+    }
+  }
+
+  if (netif == NULL) {
+    LWIP_DEBUGF(RAW_DEBUG | LWIP_DBG_LEVEL_WARNING, ("raw_sendto: No route to "));
+    ip_addr_debug_print(RAW_DEBUG | LWIP_DBG_LEVEL_WARNING, ipaddr);
+    return ERR_RTE;
+  }
+
+  if (ip_addr_isany(&pcb->local_ip) || ip_addr_ismulticast(&pcb->local_ip)) {
+    /* use outgoing network interface IP address as source address */
+    src_ip = ip_netif_get_local_ip(netif, ipaddr);
+#if LWIP_IPV6
+    if (src_ip == NULL) {
+      return ERR_RTE;
+    }
+#endif /* LWIP_IPV6 */
+  } else {
+    /* use RAW PCB local IP address as source address */
+    src_ip = &pcb->local_ip;
+  }
+
+  return raw_sendto_if_src(pcb, p, ipaddr, netif, src_ip);
+}
+
+/**
+ * @ingroup raw_raw
+ * Send the raw IP packet to the given address, using a particular outgoing
+ * netif and source IP address. An IP header will be prepended to the packet,
+ * unless the RAW_FLAGS_HDRINCL flag is set on the PCB. In that case, the
+ * packet must include an IP header, which will then be sent as is.
+ *
+ * @param pcb RAW PCB used to send the data
+ * @param p chain of pbufs to be sent
+ * @param dst_ip destination IP address
+ * @param netif the netif used for sending
+ * @param src_ip source IP address
+ */
+err_t
+raw_sendto_if_src(struct raw_pcb *pcb, struct pbuf *p, const ip_addr_t *dst_ip,
+                  struct netif *netif, const ip_addr_t *src_ip)
+{
+  err_t err;
+  struct pbuf *q; /* q will be sent down the stack */
+  u16_t header_size;
+  u8_t ttl;
+
+  LWIP_ASSERT_CORE_LOCKED();
+
+  if ((pcb == NULL) || (dst_ip == NULL) || (netif == NULL) || (src_ip == NULL) ||
+      !IP_ADDR_PCB_VERSION_MATCH(pcb, src_ip) || !IP_ADDR_PCB_VERSION_MATCH(pcb, dst_ip)) {
+    return ERR_VAL;
+  }
+
+  header_size = (
+#if LWIP_IPV4 && LWIP_IPV6
+                  IP_IS_V6(dst_ip) ? IP6_HLEN : IP_HLEN);
+#elif LWIP_IPV4
+                  IP_HLEN);
+#else
+                  IP6_HLEN);
+#endif
+
+  /* Handle the HDRINCL option as an exception: none of the code below applies
+   * to this case, and sending the packet needs to be done differently too. */
+  if (pcb->flags & RAW_FLAGS_HDRINCL) {
+    /* A full header *must* be present in the first pbuf of the chain, as the
+     * output routines may access its fields directly. */
+    if (p->len < header_size) {
+      return ERR_VAL;
+    }
+    /* @todo multicast loop support, if at all desired for this scenario.. */
+    NETIF_SET_HINTS(netif, &pcb->netif_hints);
+    err = ip_output_if_hdrincl(p, src_ip, dst_ip, netif);
+    NETIF_RESET_HINTS(netif);
+    return err;
+  }
+
+  /* packet too large to add an IP header without causing an overflow? */
+  if ((u16_t)(p->tot_len + header_size) < p->tot_len) {
+    return ERR_MEM;
+  }
+  /* not enough space to add an IP header to first pbuf in given p chain? */
+  if (pbuf_add_header(p, header_size)) {
+    /* allocate header in new pbuf */
+    q = pbuf_alloc(PBUF_IP, 0, PBUF_RAM);
+    /* new header pbuf could not be allocated? */
+    if (q == NULL) {
+      LWIP_DEBUGF(RAW_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS, ("raw_sendto: could not allocate header\n"));
+      return ERR_MEM;
+    }
+    if (p->tot_len != 0) {
+      /* chain header q in front of given pbuf p */
+      pbuf_chain(q, p);
+    }
+    /* { first pbuf q points to header pbuf } */
+    LWIP_DEBUGF(RAW_DEBUG, ("raw_sendto: added header pbuf %p before given pbuf %p\n", (void *)q, (void *)p));
+  } else {
+    /* first pbuf q equals given pbuf */
+    q = p;
+    if (pbuf_remove_header(q, header_size)) {
+      LWIP_ASSERT("Can't restore header we just removed!", 0);
+      return ERR_MEM;
+    }
+  }
+
+#if IP_SOF_BROADCAST
+  if (IP_IS_V4(dst_ip)) {
+    /* broadcast filter? */
+    if (!ip_get_option(pcb, SOF_BROADCAST) && ip_addr_isbroadcast(dst_ip, netif)) {
+      LWIP_DEBUGF(RAW_DEBUG | LWIP_DBG_LEVEL_WARNING, ("raw_sendto: SOF_BROADCAST not enabled on pcb %p\n", (void *)pcb));
+      /* free any temporary header pbuf allocated by pbuf_header() */
+      if (q != p) {
+        pbuf_free(q);
+      }
+      return ERR_VAL;
+    }
+  }
+#endif /* IP_SOF_BROADCAST */
+
+  /* Multicast Loop? */
+#if LWIP_MULTICAST_TX_OPTIONS
+  if (((pcb->flags & RAW_FLAGS_MULTICAST_LOOP) != 0) && ip_addr_ismulticast(dst_ip)) {
+    q->flags |= PBUF_FLAG_MCASTLOOP;
+  }
+#endif /* LWIP_MULTICAST_TX_OPTIONS */
+
+#if LWIP_IPV6
+  /* If requested, based on the IPV6_CHECKSUM socket option per RFC3542,
+     compute the checksum and update the checksum in the payload. */
+  if (IP_IS_V6(dst_ip) && pcb->chksum_reqd) {
+    u16_t chksum = ip6_chksum_pseudo(p, pcb->protocol, p->tot_len, ip_2_ip6(src_ip), ip_2_ip6(dst_ip));
+    LWIP_ASSERT("Checksum must fit into first pbuf", p->len >= (pcb->chksum_offset + 2));
+    SMEMCPY(((u8_t *)p->payload) + pcb->chksum_offset, &chksum, sizeof(u16_t));
+  }
+#endif
+
+  /* Determine TTL to use */
+#if LWIP_MULTICAST_TX_OPTIONS
+  ttl = (ip_addr_ismulticast(dst_ip) ? raw_get_multicast_ttl(pcb) : pcb->ttl);
+#else /* LWIP_MULTICAST_TX_OPTIONS */
+  ttl = pcb->ttl;
+#endif /* LWIP_MULTICAST_TX_OPTIONS */
+
+  NETIF_SET_HINTS(netif, &pcb->netif_hints);
+  err = ip_output_if(q, src_ip, dst_ip, ttl, pcb->tos, pcb->protocol, netif);
+  NETIF_RESET_HINTS(netif);
+
+  /* did we chain a header earlier? */
+  if (q != p) {
+    /* free the header */
+    pbuf_free(q);
+  }
+  return err;
+}
+
+/**
+ * @ingroup raw_raw
+ * Send the raw IP packet to the address given by raw_connect()
+ *
+ * @param pcb the raw pcb which to send
+ * @param p the IP payload to send
+ *
+ */
+err_t
+raw_send(struct raw_pcb *pcb, struct pbuf *p)
+{
+  return raw_sendto(pcb, p, &pcb->remote_ip);
+}
+
+/**
+ * @ingroup raw_raw
+ * Remove an RAW PCB.
+ *
+ * @param pcb RAW PCB to be removed. The PCB is removed from the list of
+ * RAW PCB's and the data structure is freed from memory.
+ *
+ * @see raw_new()
+ */
+void
+raw_remove(struct raw_pcb *pcb)
+{
+  struct raw_pcb *pcb2;
+  LWIP_ASSERT_CORE_LOCKED();
+  /* pcb to be removed is first in list? */
+  if (raw_pcbs == pcb) {
+    /* make list start at 2nd pcb */
+    raw_pcbs = raw_pcbs->next;
+    /* pcb not 1st in list */
+  } else {
+    for (pcb2 = raw_pcbs; pcb2 != NULL; pcb2 = pcb2->next) {
+      /* find pcb in raw_pcbs list */
+      if (pcb2->next != NULL && pcb2->next == pcb) {
+        /* remove pcb from list */
+        pcb2->next = pcb->next;
+        break;
+      }
+    }
+  }
+  memp_free(MEMP_RAW_PCB, pcb);
+}
+
+/**
+ * @ingroup raw_raw
+ * Create a RAW PCB.
+ *
+ * @return The RAW PCB which was created. NULL if the PCB data structure
+ * could not be allocated.
+ *
+ * @param proto the protocol number of the IPs payload (e.g. IP_PROTO_ICMP)
+ *
+ * @see raw_remove()
+ */
+struct raw_pcb *
+raw_new(u8_t proto)
+{
+  struct raw_pcb *pcb;
+
+  LWIP_DEBUGF(RAW_DEBUG | LWIP_DBG_TRACE, ("raw_new\n"));
+  LWIP_ASSERT_CORE_LOCKED();
+
+  pcb = (struct raw_pcb *)memp_malloc(MEMP_RAW_PCB);
+  /* could allocate RAW PCB? */
+  if (pcb != NULL) {
+    /* initialize PCB to all zeroes */
+    memset(pcb, 0, sizeof(struct raw_pcb));
+    pcb->protocol = proto;
+    pcb->ttl = RAW_TTL;
+#if LWIP_MULTICAST_TX_OPTIONS
+    raw_set_multicast_ttl(pcb, RAW_TTL);
+#endif /* LWIP_MULTICAST_TX_OPTIONS */
+    pcb->next = raw_pcbs;
+    raw_pcbs = pcb;
+  }
+  return pcb;
+}
+
+/**
+ * @ingroup raw_raw
+ * Create a RAW PCB for specific IP type.
+ *
+ * @return The RAW PCB which was created. NULL if the PCB data structure
+ * could not be allocated.
+ *
+ * @param type IP address type, see @ref lwip_ip_addr_type definitions.
+ * If you want to listen to IPv4 and IPv6 (dual-stack) packets,
+ * supply @ref IPADDR_TYPE_ANY as argument and bind to @ref IP_ANY_TYPE.
+ * @param proto the protocol number (next header) of the IPv6 packet payload
+ *              (e.g. IP6_NEXTH_ICMP6)
+ *
+ * @see raw_remove()
+ */
+struct raw_pcb *
+raw_new_ip_type(u8_t type, u8_t proto)
+{
+  struct raw_pcb *pcb;
+  LWIP_ASSERT_CORE_LOCKED();
+  pcb = raw_new(proto);
+#if LWIP_IPV4 && LWIP_IPV6
+  if (pcb != NULL) {
+    IP_SET_TYPE_VAL(pcb->local_ip,  type);
+    IP_SET_TYPE_VAL(pcb->remote_ip, type);
+  }
+#else /* LWIP_IPV4 && LWIP_IPV6 */
+  LWIP_UNUSED_ARG(type);
+#endif /* LWIP_IPV4 && LWIP_IPV6 */
+  return pcb;
+}
+
+/** This function is called from netif.c when address is changed
+ *
+ * @param old_addr IP address of the netif before change
+ * @param new_addr IP address of the netif after change
+ */
+void raw_netif_ip_addr_changed(const ip_addr_t *old_addr, const ip_addr_t *new_addr)
+{
+  struct raw_pcb *rpcb;
+
+  if (!ip_addr_isany(old_addr) && !ip_addr_isany(new_addr)) {
+    for (rpcb = raw_pcbs; rpcb != NULL; rpcb = rpcb->next) {
+      /* PCB bound to current local interface address? */
+      if (ip_addr_cmp(&rpcb->local_ip, old_addr)) {
+        /* The PCB is bound to the old ipaddr and
+         * is set to bound to the new one instead */
+        ip_addr_copy(rpcb->local_ip, *new_addr);
+      }
+    }
+  }
+}
+
+#endif /* LWIP_RAW */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/core/stats.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/core/stats.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/core/stats.c	(revision 457)
@@ -0,0 +1,169 @@
+/**
+ * @file
+ * Statistics module
+ *
+ */
+
+/*
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Adam Dunkels <adam@sics.se>
+ *
+ */
+
+#include "lwip/opt.h"
+
+#if LWIP_STATS /* don't build if not configured for use in lwipopts.h */
+
+#include "lwip/def.h"
+#include "lwip/stats.h"
+#include "lwip/mem.h"
+#include "lwip/debug.h"
+
+#include <string.h>
+
+struct stats_ lwip_stats;
+
+void
+stats_init(void)
+{
+#ifdef LWIP_DEBUG
+#if MEM_STATS
+  lwip_stats.mem.name = "MEM";
+#endif /* MEM_STATS */
+#endif /* LWIP_DEBUG */
+}
+
+#if LWIP_STATS_DISPLAY
+void
+stats_display_proto(struct stats_proto *proto, const char *name)
+{
+  LWIP_PLATFORM_DIAG(("\n%s\n\t", name));
+  LWIP_PLATFORM_DIAG(("xmit: %"STAT_COUNTER_F"\n\t", proto->xmit));
+  LWIP_PLATFORM_DIAG(("recv: %"STAT_COUNTER_F"\n\t", proto->recv));
+  LWIP_PLATFORM_DIAG(("fw: %"STAT_COUNTER_F"\n\t", proto->fw));
+  LWIP_PLATFORM_DIAG(("drop: %"STAT_COUNTER_F"\n\t", proto->drop));
+  LWIP_PLATFORM_DIAG(("chkerr: %"STAT_COUNTER_F"\n\t", proto->chkerr));
+  LWIP_PLATFORM_DIAG(("lenerr: %"STAT_COUNTER_F"\n\t", proto->lenerr));
+  LWIP_PLATFORM_DIAG(("memerr: %"STAT_COUNTER_F"\n\t", proto->memerr));
+  LWIP_PLATFORM_DIAG(("rterr: %"STAT_COUNTER_F"\n\t", proto->rterr));
+  LWIP_PLATFORM_DIAG(("proterr: %"STAT_COUNTER_F"\n\t", proto->proterr));
+  LWIP_PLATFORM_DIAG(("opterr: %"STAT_COUNTER_F"\n\t", proto->opterr));
+  LWIP_PLATFORM_DIAG(("err: %"STAT_COUNTER_F"\n\t", proto->err));
+  LWIP_PLATFORM_DIAG(("cachehit: %"STAT_COUNTER_F"\n", proto->cachehit));
+}
+
+#if IGMP_STATS || MLD6_STATS
+void
+stats_display_igmp(struct stats_igmp *igmp, const char *name)
+{
+  LWIP_PLATFORM_DIAG(("\n%s\n\t", name));
+  LWIP_PLATFORM_DIAG(("xmit: %"STAT_COUNTER_F"\n\t", igmp->xmit));
+  LWIP_PLATFORM_DIAG(("recv: %"STAT_COUNTER_F"\n\t", igmp->recv));
+  LWIP_PLATFORM_DIAG(("drop: %"STAT_COUNTER_F"\n\t", igmp->drop));
+  LWIP_PLATFORM_DIAG(("chkerr: %"STAT_COUNTER_F"\n\t", igmp->chkerr));
+  LWIP_PLATFORM_DIAG(("lenerr: %"STAT_COUNTER_F"\n\t", igmp->lenerr));
+  LWIP_PLATFORM_DIAG(("memerr: %"STAT_COUNTER_F"\n\t", igmp->memerr));
+  LWIP_PLATFORM_DIAG(("proterr: %"STAT_COUNTER_F"\n\t", igmp->proterr));
+  LWIP_PLATFORM_DIAG(("rx_v1: %"STAT_COUNTER_F"\n\t", igmp->rx_v1));
+  LWIP_PLATFORM_DIAG(("rx_group: %"STAT_COUNTER_F"\n\t", igmp->rx_group));
+  LWIP_PLATFORM_DIAG(("rx_general: %"STAT_COUNTER_F"\n\t", igmp->rx_general));
+  LWIP_PLATFORM_DIAG(("rx_report: %"STAT_COUNTER_F"\n\t", igmp->rx_report));
+  LWIP_PLATFORM_DIAG(("tx_join: %"STAT_COUNTER_F"\n\t", igmp->tx_join));
+  LWIP_PLATFORM_DIAG(("tx_leave: %"STAT_COUNTER_F"\n\t", igmp->tx_leave));
+  LWIP_PLATFORM_DIAG(("tx_report: %"STAT_COUNTER_F"\n", igmp->tx_report));
+}
+#endif /* IGMP_STATS || MLD6_STATS */
+
+#if MEM_STATS || MEMP_STATS
+void
+stats_display_mem(struct stats_mem *mem, const char *name)
+{
+  LWIP_PLATFORM_DIAG(("\nMEM %s\n\t", name));
+  LWIP_PLATFORM_DIAG(("avail: %"MEM_SIZE_F"\n\t", mem->avail));
+  LWIP_PLATFORM_DIAG(("used: %"MEM_SIZE_F"\n\t", mem->used));
+  LWIP_PLATFORM_DIAG(("max: %"MEM_SIZE_F"\n\t", mem->max));
+  LWIP_PLATFORM_DIAG(("err: %"STAT_COUNTER_F"\n", mem->err));
+}
+
+#if MEMP_STATS
+void
+stats_display_memp(struct stats_mem *mem, int idx)
+{
+  if (idx < MEMP_MAX) {
+    stats_display_mem(mem, mem->name);
+  }
+}
+#endif /* MEMP_STATS */
+#endif /* MEM_STATS || MEMP_STATS */
+
+#if SYS_STATS
+void
+stats_display_sys(struct stats_sys *sys)
+{
+  LWIP_PLATFORM_DIAG(("\nSYS\n\t"));
+  LWIP_PLATFORM_DIAG(("sem.used:  %"STAT_COUNTER_F"\n\t", sys->sem.used));
+  LWIP_PLATFORM_DIAG(("sem.max:   %"STAT_COUNTER_F"\n\t", sys->sem.max));
+  LWIP_PLATFORM_DIAG(("sem.err:   %"STAT_COUNTER_F"\n\t", sys->sem.err));
+  LWIP_PLATFORM_DIAG(("mutex.used: %"STAT_COUNTER_F"\n\t", sys->mutex.used));
+  LWIP_PLATFORM_DIAG(("mutex.max:  %"STAT_COUNTER_F"\n\t", sys->mutex.max));
+  LWIP_PLATFORM_DIAG(("mutex.err:  %"STAT_COUNTER_F"\n\t", sys->mutex.err));
+  LWIP_PLATFORM_DIAG(("mbox.used:  %"STAT_COUNTER_F"\n\t", sys->mbox.used));
+  LWIP_PLATFORM_DIAG(("mbox.max:   %"STAT_COUNTER_F"\n\t", sys->mbox.max));
+  LWIP_PLATFORM_DIAG(("mbox.err:   %"STAT_COUNTER_F"\n", sys->mbox.err));
+}
+#endif /* SYS_STATS */
+
+void
+stats_display(void)
+{
+  s16_t i;
+
+  LINK_STATS_DISPLAY();
+  ETHARP_STATS_DISPLAY();
+  IPFRAG_STATS_DISPLAY();
+  IP6_FRAG_STATS_DISPLAY();
+  IP_STATS_DISPLAY();
+  ND6_STATS_DISPLAY();
+  IP6_STATS_DISPLAY();
+  IGMP_STATS_DISPLAY();
+  MLD6_STATS_DISPLAY();
+  ICMP_STATS_DISPLAY();
+  ICMP6_STATS_DISPLAY();
+  UDP_STATS_DISPLAY();
+  TCP_STATS_DISPLAY();
+  MEM_STATS_DISPLAY();
+  for (i = 0; i < MEMP_MAX; i++) {
+    MEMP_STATS_DISPLAY(i);
+  }
+  SYS_STATS_DISPLAY();
+}
+#endif /* LWIP_STATS_DISPLAY */
+
+#endif /* LWIP_STATS */
+
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/core/sys.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/core/sys.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/core/sys.c	(revision 457)
@@ -0,0 +1,148 @@
+/**
+ * @file
+ * lwIP Operating System abstraction
+ *
+ */
+
+/*
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Adam Dunkels <adam@sics.se>
+ *
+ */
+
+/**
+ * @defgroup sys_layer Porting (system abstraction layer)
+ * @ingroup lwip
+ *
+ * @defgroup sys_os OS abstraction layer
+ * @ingroup sys_layer
+ * No need to implement functions in this section in NO_SYS mode.
+ * The OS-specific code should be implemented in arch/sys_arch.h
+ * and sys_arch.c of your port.
+ * 
+ * The operating system emulation layer provides a common interface
+ * between the lwIP code and the underlying operating system kernel. The
+ * general idea is that porting lwIP to new architectures requires only
+ * small changes to a few header files and a new sys_arch
+ * implementation. It is also possible to do a sys_arch implementation
+ * that does not rely on any underlying operating system.
+ * 
+ * The sys_arch provides semaphores, mailboxes and mutexes to lwIP. For the full
+ * lwIP functionality, multiple threads support can be implemented in the
+ * sys_arch, but this is not required for the basic lwIP
+ * functionality. Timer scheduling is implemented in lwIP, but can be implemented
+ * by the sys_arch port (LWIP_TIMERS_CUSTOM==1).
+ * 
+ * In addition to the source file providing the functionality of sys_arch,
+ * the OS emulation layer must provide several header files defining
+ * macros used throughout lwip.  The files required and the macros they
+ * must define are listed below the sys_arch description.
+ * 
+ * Since lwIP 1.4.0, semaphore, mutexes and mailbox functions are prototyped in a way that
+ * allows both using pointers or actual OS structures to be used. This way, memory
+ * required for such types can be either allocated in place (globally or on the
+ * stack) or on the heap (allocated internally in the "*_new()" functions).
+ * 
+ * Note:
+ * -----
+ * Be careful with using mem_malloc() in sys_arch. When malloc() refers to
+ * mem_malloc() you can run into a circular function call problem. In mem.c
+ * mem_init() tries to allocate a semaphore using mem_malloc, which of course
+ * can't be performed when sys_arch uses mem_malloc.
+ *
+ * @defgroup sys_sem Semaphores
+ * @ingroup sys_os
+ * Semaphores can be either counting or binary - lwIP works with both
+ * kinds.
+ * Semaphores are represented by the type "sys_sem_t" which is typedef'd
+ * in the sys_arch.h file. Mailboxes are equivalently represented by the
+ * type "sys_mbox_t". Mutexes are represented by the type "sys_mutex_t".
+ * lwIP does not place any restrictions on how these types are represented
+ * internally.
+ *
+ * @defgroup sys_mutex Mutexes
+ * @ingroup sys_os
+ * Mutexes are recommended to correctly handle priority inversion,
+ * especially if you use LWIP_CORE_LOCKING .
+ *
+ * @defgroup sys_mbox Mailboxes
+ * @ingroup sys_os
+ * Mailboxes should be implemented as a queue which allows multiple messages
+ * to be posted (implementing as a rendez-vous point where only one message can be
+ * posted at a time can have a highly negative impact on performance). A message
+ * in a mailbox is just a pointer, nothing more. 
+ *
+ * @defgroup sys_time Time
+ * @ingroup sys_layer
+ *
+ * @defgroup sys_prot Critical sections
+ * @ingroup sys_layer
+ * Used to protect short regions of code against concurrent access.
+ * - Your system is a bare-metal system (probably with an RTOS)
+ *   and interrupts are under your control:
+ *   Implement this as LockInterrupts() / UnlockInterrupts()
+ * - Your system uses an RTOS with deferred interrupt handling from a
+ *   worker thread: Implement as a global mutex or lock/unlock scheduler
+ * - Your system uses a high-level OS with e.g. POSIX signals:
+ *   Implement as a global mutex
+ *
+ * @defgroup sys_misc Misc
+ * @ingroup sys_os
+ */
+
+#include "lwip/opt.h"
+
+#include "lwip/sys.h"
+
+/* Most of the functions defined in sys.h must be implemented in the
+ * architecture-dependent file sys_arch.c */
+
+#if !NO_SYS
+
+#ifndef sys_msleep
+/**
+ * Sleep for some ms. Timeouts are NOT processed while sleeping.
+ *
+ * @param ms number of milliseconds to sleep
+ */
+void
+sys_msleep(u32_t ms)
+{
+  if (ms > 0) {
+    sys_sem_t delaysem;
+    err_t err = sys_sem_new(&delaysem, 0);
+    if (err == ERR_OK) {
+      sys_arch_sem_wait(&delaysem, ms);
+      sys_sem_free(&delaysem);
+    }
+  }
+}
+#endif /* sys_msleep */
+
+#endif /* !NO_SYS */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/core/tcp.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/core/tcp.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/core/tcp.c	(revision 457)
@@ -0,0 +1,2686 @@
+/**
+ * @file
+ * Transmission Control Protocol for IP
+ * See also @ref tcp_raw
+ *
+ * @defgroup tcp_raw TCP
+ * @ingroup callbackstyle_api
+ * Transmission Control Protocol for IP\n
+ * @see @ref api
+ *
+ * Common functions for the TCP implementation, such as functions
+ * for manipulating the data structures and the TCP timer functions. TCP functions
+ * related to input and output is found in tcp_in.c and tcp_out.c respectively.\n
+ * 
+ * TCP connection setup
+ * --------------------
+ * The functions used for setting up connections is similar to that of
+ * the sequential API and of the BSD socket API. A new TCP connection
+ * identifier (i.e., a protocol control block - PCB) is created with the
+ * tcp_new() function. This PCB can then be either set to listen for new
+ * incoming connections or be explicitly connected to another host.
+ * - tcp_new()
+ * - tcp_bind()
+ * - tcp_listen() and tcp_listen_with_backlog()
+ * - tcp_accept()
+ * - tcp_connect()
+ * 
+ * Sending TCP data
+ * ----------------
+ * TCP data is sent by enqueueing the data with a call to tcp_write() and
+ * triggering to send by calling tcp_output(). When the data is successfully
+ * transmitted to the remote host, the application will be notified with a
+ * call to a specified callback function.
+ * - tcp_write()
+ * - tcp_output()
+ * - tcp_sent()
+ * 
+ * Receiving TCP data
+ * ------------------
+ * TCP data reception is callback based - an application specified
+ * callback function is called when new data arrives. When the
+ * application has taken the data, it has to call the tcp_recved()
+ * function to indicate that TCP can advertise increase the receive
+ * window.
+ * - tcp_recv()
+ * - tcp_recved()
+ * 
+ * Application polling
+ * -------------------
+ * When a connection is idle (i.e., no data is either transmitted or
+ * received), lwIP will repeatedly poll the application by calling a
+ * specified callback function. This can be used either as a watchdog
+ * timer for killing connections that have stayed idle for too long, or
+ * as a method of waiting for memory to become available. For instance,
+ * if a call to tcp_write() has failed because memory wasn't available,
+ * the application may use the polling functionality to call tcp_write()
+ * again when the connection has been idle for a while.
+ * - tcp_poll()
+ *
+ * Closing and aborting connections
+ * --------------------------------
+ * - tcp_close()
+ * - tcp_abort()
+ * - tcp_err()
+ * 
+ */
+
+/*
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Adam Dunkels <adam@sics.se>
+ *
+ */
+
+#include "lwip/opt.h"
+
+#if LWIP_TCP /* don't build if not configured for use in lwipopts.h */
+
+#include "lwip/def.h"
+#include "lwip/mem.h"
+#include "lwip/memp.h"
+#include "lwip/tcp.h"
+#include "lwip/priv/tcp_priv.h"
+#include "lwip/debug.h"
+#include "lwip/stats.h"
+#include "lwip/ip6.h"
+#include "lwip/ip6_addr.h"
+#include "lwip/nd6.h"
+
+#include <string.h>
+
+#ifdef LWIP_HOOK_FILENAME
+#include LWIP_HOOK_FILENAME
+#endif
+
+#ifndef TCP_LOCAL_PORT_RANGE_START
+/* From http://www.iana.org/assignments/port-numbers:
+   "The Dynamic and/or Private Ports are those from 49152 through 65535" */
+#define TCP_LOCAL_PORT_RANGE_START        0xc000
+#define TCP_LOCAL_PORT_RANGE_END          0xffff
+#define TCP_ENSURE_LOCAL_PORT_RANGE(port) ((u16_t)(((port) & (u16_t)~TCP_LOCAL_PORT_RANGE_START) + TCP_LOCAL_PORT_RANGE_START))
+#endif
+
+#if LWIP_TCP_KEEPALIVE
+#define TCP_KEEP_DUR(pcb)   ((pcb)->keep_cnt * (pcb)->keep_intvl)
+#define TCP_KEEP_INTVL(pcb) ((pcb)->keep_intvl)
+#else /* LWIP_TCP_KEEPALIVE */
+#define TCP_KEEP_DUR(pcb)   TCP_MAXIDLE
+#define TCP_KEEP_INTVL(pcb) TCP_KEEPINTVL_DEFAULT
+#endif /* LWIP_TCP_KEEPALIVE */
+
+/* As initial send MSS, we use TCP_MSS but limit it to 536. */
+#if TCP_MSS > 536
+#define INITIAL_MSS 536
+#else
+#define INITIAL_MSS TCP_MSS
+#endif
+
+static const char *const tcp_state_str[] = {
+  "CLOSED",
+  "LISTEN",
+  "SYN_SENT",
+  "SYN_RCVD",
+  "ESTABLISHED",
+  "FIN_WAIT_1",
+  "FIN_WAIT_2",
+  "CLOSE_WAIT",
+  "CLOSING",
+  "LAST_ACK",
+  "TIME_WAIT"
+};
+
+/* last local TCP port */
+static u16_t tcp_port = TCP_LOCAL_PORT_RANGE_START;
+
+/* Incremented every coarse grained timer shot (typically every 500 ms). */
+u32_t tcp_ticks;
+static const u8_t tcp_backoff[13] =
+{ 1, 2, 3, 4, 5, 6, 7, 7, 7, 7, 7, 7, 7};
+/* Times per slowtmr hits */
+static const u8_t tcp_persist_backoff[7] = { 3, 6, 12, 24, 48, 96, 120 };
+
+/* The TCP PCB lists. */
+
+/** List of all TCP PCBs bound but not yet (connected || listening) */
+struct tcp_pcb *tcp_bound_pcbs;
+/** List of all TCP PCBs in LISTEN state */
+union tcp_listen_pcbs_t tcp_listen_pcbs;
+/** List of all TCP PCBs that are in a state in which
+ * they accept or send data. */
+struct tcp_pcb *tcp_active_pcbs;
+/** List of all TCP PCBs in TIME-WAIT state */
+struct tcp_pcb *tcp_tw_pcbs;
+
+/** An array with all (non-temporary) PCB lists, mainly used for smaller code size */
+struct tcp_pcb **const tcp_pcb_lists[] = {&tcp_listen_pcbs.pcbs, &tcp_bound_pcbs,
+         &tcp_active_pcbs, &tcp_tw_pcbs
+};
+
+u8_t tcp_active_pcbs_changed;
+
+/** Timer counter to handle calling slow-timer from tcp_tmr() */
+static u8_t tcp_timer;
+static u8_t tcp_timer_ctr;
+static u16_t tcp_new_port(void);
+
+static err_t tcp_close_shutdown_fin(struct tcp_pcb *pcb);
+#if LWIP_TCP_PCB_NUM_EXT_ARGS
+static void tcp_ext_arg_invoke_callbacks_destroyed(struct tcp_pcb_ext_args *ext_args);
+#endif
+
+/**
+ * Initialize this module.
+ */
+void
+tcp_init(void)
+{
+#ifdef LWIP_RAND
+  tcp_port = TCP_ENSURE_LOCAL_PORT_RANGE(LWIP_RAND());
+#endif /* LWIP_RAND */
+}
+
+/** Free a tcp pcb */
+void
+tcp_free(struct tcp_pcb *pcb)
+{
+  LWIP_ASSERT("tcp_free: LISTEN", pcb->state != LISTEN);
+#if LWIP_TCP_PCB_NUM_EXT_ARGS
+  tcp_ext_arg_invoke_callbacks_destroyed(pcb->ext_args);
+#endif
+  memp_free(MEMP_TCP_PCB, pcb);
+}
+
+/** Free a tcp listen pcb */
+static void
+tcp_free_listen(struct tcp_pcb *pcb)
+{
+  LWIP_ASSERT("tcp_free_listen: !LISTEN", pcb->state != LISTEN);
+#if LWIP_TCP_PCB_NUM_EXT_ARGS
+  tcp_ext_arg_invoke_callbacks_destroyed(pcb->ext_args);
+#endif
+  memp_free(MEMP_TCP_PCB_LISTEN, pcb);
+}
+
+/**
+ * Called periodically to dispatch TCP timers.
+ */
+void
+tcp_tmr(void)
+{
+  /* Call tcp_fasttmr() every 250 ms */
+  tcp_fasttmr();
+
+  if (++tcp_timer & 1) {
+    /* Call tcp_slowtmr() every 500 ms, i.e., every other timer
+       tcp_tmr() is called. */
+    tcp_slowtmr();
+  }
+}
+
+#if LWIP_CALLBACK_API || TCP_LISTEN_BACKLOG
+/** Called when a listen pcb is closed. Iterates one pcb list and removes the
+ * closed listener pcb from pcb->listener if matching.
+ */
+static void
+tcp_remove_listener(struct tcp_pcb *list, struct tcp_pcb_listen *lpcb)
+{
+  struct tcp_pcb *pcb;
+
+  LWIP_ASSERT("tcp_remove_listener: invalid listener", lpcb != NULL);
+
+  for (pcb = list; pcb != NULL; pcb = pcb->next) {
+    if (pcb->listener == lpcb) {
+      pcb->listener = NULL;
+    }
+  }
+}
+#endif
+
+/** Called when a listen pcb is closed. Iterates all pcb lists and removes the
+ * closed listener pcb from pcb->listener if matching.
+ */
+static void
+tcp_listen_closed(struct tcp_pcb *pcb)
+{
+#if LWIP_CALLBACK_API || TCP_LISTEN_BACKLOG
+  size_t i;
+  LWIP_ASSERT("pcb != NULL", pcb != NULL);
+  LWIP_ASSERT("pcb->state == LISTEN", pcb->state == LISTEN);
+  for (i = 1; i < LWIP_ARRAYSIZE(tcp_pcb_lists); i++) {
+    tcp_remove_listener(*tcp_pcb_lists[i], (struct tcp_pcb_listen *)pcb);
+  }
+#endif
+  LWIP_UNUSED_ARG(pcb);
+}
+
+#if TCP_LISTEN_BACKLOG
+/** @ingroup tcp_raw
+ * Delay accepting a connection in respect to the listen backlog:
+ * the number of outstanding connections is increased until
+ * tcp_backlog_accepted() is called.
+ *
+ * ATTENTION: the caller is responsible for calling tcp_backlog_accepted()
+ * or else the backlog feature will get out of sync!
+ *
+ * @param pcb the connection pcb which is not fully accepted yet
+ */
+void
+tcp_backlog_delayed(struct tcp_pcb *pcb)
+{
+  LWIP_ASSERT("pcb != NULL", pcb != NULL);
+  LWIP_ASSERT_CORE_LOCKED();
+  if ((pcb->flags & TF_BACKLOGPEND) == 0) {
+    if (pcb->listener != NULL) {
+      pcb->listener->accepts_pending++;
+      LWIP_ASSERT("accepts_pending != 0", pcb->listener->accepts_pending != 0);
+      tcp_set_flags(pcb, TF_BACKLOGPEND);
+    }
+  }
+}
+
+/** @ingroup tcp_raw
+ * A delayed-accept a connection is accepted (or closed/aborted): decreases
+ * the number of outstanding connections after calling tcp_backlog_delayed().
+ *
+ * ATTENTION: the caller is responsible for calling tcp_backlog_accepted()
+ * or else the backlog feature will get out of sync!
+ *
+ * @param pcb the connection pcb which is now fully accepted (or closed/aborted)
+ */
+void
+tcp_backlog_accepted(struct tcp_pcb *pcb)
+{
+  LWIP_ASSERT("pcb != NULL", pcb != NULL);
+  LWIP_ASSERT_CORE_LOCKED();
+  if ((pcb->flags & TF_BACKLOGPEND) != 0) {
+    if (pcb->listener != NULL) {
+      LWIP_ASSERT("accepts_pending != 0", pcb->listener->accepts_pending != 0);
+      pcb->listener->accepts_pending--;
+      tcp_clear_flags(pcb, TF_BACKLOGPEND);
+    }
+  }
+}
+#endif /* TCP_LISTEN_BACKLOG */
+
+/**
+ * Closes the TX side of a connection held by the PCB.
+ * For tcp_close(), a RST is sent if the application didn't receive all data
+ * (tcp_recved() not called for all data passed to recv callback).
+ *
+ * Listening pcbs are freed and may not be referenced any more.
+ * Connection pcbs are freed if not yet connected and may not be referenced
+ * any more. If a connection is established (at least SYN received or in
+ * a closing state), the connection is closed, and put in a closing state.
+ * The pcb is then automatically freed in tcp_slowtmr(). It is therefore
+ * unsafe to reference it.
+ *
+ * @param pcb the tcp_pcb to close
+ * @return ERR_OK if connection has been closed
+ *         another err_t if closing failed and pcb is not freed
+ */
+static err_t
+tcp_close_shutdown(struct tcp_pcb *pcb, u8_t rst_on_unacked_data)
+{
+  LWIP_ASSERT("tcp_close_shutdown: invalid pcb", pcb != NULL);
+
+  if (rst_on_unacked_data && ((pcb->state == ESTABLISHED) || (pcb->state == CLOSE_WAIT))) {
+    if ((pcb->refused_data != NULL) || (pcb->rcv_wnd != TCP_WND_MAX(pcb))) {
+      /* Not all data received by application, send RST to tell the remote
+         side about this. */
+      LWIP_ASSERT("pcb->flags & TF_RXCLOSED", pcb->flags & TF_RXCLOSED);
+
+      /* don't call tcp_abort here: we must not deallocate the pcb since
+         that might not be expected when calling tcp_close */
+      tcp_rst(pcb, pcb->snd_nxt, pcb->rcv_nxt, &pcb->local_ip, &pcb->remote_ip,
+              pcb->local_port, pcb->remote_port);
+
+      tcp_pcb_purge(pcb);
+      TCP_RMV_ACTIVE(pcb);
+      /* Deallocate the pcb since we already sent a RST for it */
+      if (tcp_input_pcb == pcb) {
+        /* prevent using a deallocated pcb: free it from tcp_input later */
+        tcp_trigger_input_pcb_close();
+      } else {
+        tcp_free(pcb);
+      }
+      return ERR_OK;
+    }
+  }
+
+  /* - states which free the pcb are handled here,
+     - states which send FIN and change state are handled in tcp_close_shutdown_fin() */
+  switch (pcb->state) {
+    case CLOSED:
+      /* Closing a pcb in the CLOSED state might seem erroneous,
+       * however, it is in this state once allocated and as yet unused
+       * and the user needs some way to free it should the need arise.
+       * Calling tcp_close() with a pcb that has already been closed, (i.e. twice)
+       * or for a pcb that has been used and then entered the CLOSED state
+       * is erroneous, but this should never happen as the pcb has in those cases
+       * been freed, and so any remaining handles are bogus. */
+      if (pcb->local_port != 0) {
+        TCP_RMV(&tcp_bound_pcbs, pcb);
+      }
+      tcp_free(pcb);
+      break;
+    case LISTEN:
+      tcp_listen_closed(pcb);
+      tcp_pcb_remove(&tcp_listen_pcbs.pcbs, pcb);
+      tcp_free_listen(pcb);
+      break;
+    case SYN_SENT:
+      TCP_PCB_REMOVE_ACTIVE(pcb);
+      tcp_free(pcb);
+      MIB2_STATS_INC(mib2.tcpattemptfails);
+      break;
+    default:
+      return tcp_close_shutdown_fin(pcb);
+  }
+  return ERR_OK;
+}
+
+static err_t
+tcp_close_shutdown_fin(struct tcp_pcb *pcb)
+{
+  err_t err;
+  LWIP_ASSERT("pcb != NULL", pcb != NULL);
+
+  switch (pcb->state) {
+    case SYN_RCVD:
+      err = tcp_send_fin(pcb);
+      if (err == ERR_OK) {
+        tcp_backlog_accepted(pcb);
+        MIB2_STATS_INC(mib2.tcpattemptfails);
+        pcb->state = FIN_WAIT_1;
+      }
+      break;
+    case ESTABLISHED:
+      err = tcp_send_fin(pcb);
+      if (err == ERR_OK) {
+        MIB2_STATS_INC(mib2.tcpestabresets);
+        pcb->state = FIN_WAIT_1;
+      }
+      break;
+    case CLOSE_WAIT:
+      err = tcp_send_fin(pcb);
+      if (err == ERR_OK) {
+        MIB2_STATS_INC(mib2.tcpestabresets);
+        pcb->state = LAST_ACK;
+      }
+      break;
+    default:
+      /* Has already been closed, do nothing. */
+      return ERR_OK;
+  }
+
+  if (err == ERR_OK) {
+    /* To ensure all data has been sent when tcp_close returns, we have
+       to make sure tcp_output doesn't fail.
+       Since we don't really have to ensure all data has been sent when tcp_close
+       returns (unsent data is sent from tcp timer functions, also), we don't care
+       for the return value of tcp_output for now. */
+    tcp_output(pcb);
+  } else if (err == ERR_MEM) {
+    /* Mark this pcb for closing. Closing is retried from tcp_tmr. */
+    tcp_set_flags(pcb, TF_CLOSEPEND);
+    /* We have to return ERR_OK from here to indicate to the callers that this
+       pcb should not be used any more as it will be freed soon via tcp_tmr.
+       This is OK here since sending FIN does not guarantee a time frime for
+       actually freeing the pcb, either (it is left in closure states for
+       remote ACK or timeout) */
+    return ERR_OK;
+  }
+  return err;
+}
+
+/**
+ * @ingroup tcp_raw
+ * Closes the connection held by the PCB.
+ *
+ * Listening pcbs are freed and may not be referenced any more.
+ * Connection pcbs are freed if not yet connected and may not be referenced
+ * any more. If a connection is established (at least SYN received or in
+ * a closing state), the connection is closed, and put in a closing state.
+ * The pcb is then automatically freed in tcp_slowtmr(). It is therefore
+ * unsafe to reference it (unless an error is returned).
+ * 
+ * The function may return ERR_MEM if no memory
+ * was available for closing the connection. If so, the application
+ * should wait and try again either by using the acknowledgment
+ * callback or the polling functionality. If the close succeeds, the
+ * function returns ERR_OK.
+ *
+ * @param pcb the tcp_pcb to close
+ * @return ERR_OK if connection has been closed
+ *         another err_t if closing failed and pcb is not freed
+ */
+err_t
+tcp_close(struct tcp_pcb *pcb)
+{
+  LWIP_ASSERT_CORE_LOCKED();
+
+  LWIP_ERROR("tcp_close: invalid pcb", pcb != NULL, return ERR_ARG);
+  LWIP_DEBUGF(TCP_DEBUG, ("tcp_close: closing in "));
+
+  tcp_debug_print_state(pcb->state);
+
+  if (pcb->state != LISTEN) {
+    /* Set a flag not to receive any more data... */
+    tcp_set_flags(pcb, TF_RXCLOSED);
+  }
+  /* ... and close */
+  return tcp_close_shutdown(pcb, 1);
+}
+
+/**
+ * @ingroup tcp_raw
+ * Causes all or part of a full-duplex connection of this PCB to be shut down.
+ * This doesn't deallocate the PCB unless shutting down both sides!
+ * Shutting down both sides is the same as calling tcp_close, so if it succeds
+ * (i.e. returns ER_OK), the PCB must not be referenced any more!
+ *
+ * @param pcb PCB to shutdown
+ * @param shut_rx shut down receive side if this is != 0
+ * @param shut_tx shut down send side if this is != 0
+ * @return ERR_OK if shutdown succeeded (or the PCB has already been shut down)
+ *         another err_t on error.
+ */
+err_t
+tcp_shutdown(struct tcp_pcb *pcb, int shut_rx, int shut_tx)
+{
+  LWIP_ASSERT_CORE_LOCKED();
+
+  LWIP_ERROR("tcp_shutdown: invalid pcb", pcb != NULL, return ERR_ARG);
+
+  if (pcb->state == LISTEN) {
+    return ERR_CONN;
+  }
+  if (shut_rx) {
+    /* shut down the receive side: set a flag not to receive any more data... */
+    tcp_set_flags(pcb, TF_RXCLOSED);
+    if (shut_tx) {
+      /* shutting down the tx AND rx side is the same as closing for the raw API */
+      return tcp_close_shutdown(pcb, 1);
+    }
+    /* ... and free buffered data */
+    if (pcb->refused_data != NULL) {
+      pbuf_free(pcb->refused_data);
+      pcb->refused_data = NULL;
+    }
+  }
+  if (shut_tx) {
+    /* This can't happen twice since if it succeeds, the pcb's state is changed.
+       Only close in these states as the others directly deallocate the PCB */
+    switch (pcb->state) {
+      case SYN_RCVD:
+      case ESTABLISHED:
+      case CLOSE_WAIT:
+        return tcp_close_shutdown(pcb, (u8_t)shut_rx);
+      default:
+        /* Not (yet?) connected, cannot shutdown the TX side as that would bring us
+          into CLOSED state, where the PCB is deallocated. */
+        return ERR_CONN;
+    }
+  }
+  return ERR_OK;
+}
+
+/**
+ * Abandons a connection and optionally sends a RST to the remote
+ * host.  Deletes the local protocol control block. This is done when
+ * a connection is killed because of shortage of memory.
+ *
+ * @param pcb the tcp_pcb to abort
+ * @param reset boolean to indicate whether a reset should be sent
+ */
+void
+tcp_abandon(struct tcp_pcb *pcb, int reset)
+{
+  u32_t seqno, ackno;
+#if LWIP_CALLBACK_API
+  tcp_err_fn errf;
+#endif /* LWIP_CALLBACK_API */
+  void *errf_arg;
+
+  LWIP_ASSERT_CORE_LOCKED();
+
+  LWIP_ERROR("tcp_abandon: invalid pcb", pcb != NULL, return);
+
+  /* pcb->state LISTEN not allowed here */
+  LWIP_ASSERT("don't call tcp_abort/tcp_abandon for listen-pcbs",
+              pcb->state != LISTEN);
+  /* Figure out on which TCP PCB list we are, and remove us. If we
+     are in an active state, call the receive function associated with
+     the PCB with a NULL argument, and send an RST to the remote end. */
+  if (pcb->state == TIME_WAIT) {
+    tcp_pcb_remove(&tcp_tw_pcbs, pcb);
+    tcp_free(pcb);
+  } else {
+    int send_rst = 0;
+    u16_t local_port = 0;
+    enum tcp_state last_state;
+    seqno = pcb->snd_nxt;
+    ackno = pcb->rcv_nxt;
+#if LWIP_CALLBACK_API
+    errf = pcb->errf;
+#endif /* LWIP_CALLBACK_API */
+    errf_arg = pcb->callback_arg;
+    if (pcb->state == CLOSED) {
+      if (pcb->local_port != 0) {
+        /* bound, not yet opened */
+        TCP_RMV(&tcp_bound_pcbs, pcb);
+      }
+    } else {
+      send_rst = reset;
+      local_port = pcb->local_port;
+      TCP_PCB_REMOVE_ACTIVE(pcb);
+    }
+    if (pcb->unacked != NULL) {
+      tcp_segs_free(pcb->unacked);
+    }
+    if (pcb->unsent != NULL) {
+      tcp_segs_free(pcb->unsent);
+    }
+#if TCP_QUEUE_OOSEQ
+    if (pcb->ooseq != NULL) {
+      tcp_segs_free(pcb->ooseq);
+    }
+#endif /* TCP_QUEUE_OOSEQ */
+    tcp_backlog_accepted(pcb);
+    if (send_rst) {
+      LWIP_DEBUGF(TCP_RST_DEBUG, ("tcp_abandon: sending RST\n"));
+      tcp_rst(pcb, seqno, ackno, &pcb->local_ip, &pcb->remote_ip, local_port, pcb->remote_port);
+    }
+    last_state = pcb->state;
+    tcp_free(pcb);
+    TCP_EVENT_ERR(last_state, errf, errf_arg, ERR_ABRT);
+  }
+}
+
+/**
+ * @ingroup tcp_raw
+ * Aborts the connection by sending a RST (reset) segment to the remote
+ * host. The pcb is deallocated. This function never fails.
+ *
+ * ATTENTION: When calling this from one of the TCP callbacks, make
+ * sure you always return ERR_ABRT (and never return ERR_ABRT otherwise
+ * or you will risk accessing deallocated memory or memory leaks!
+ *
+ * @param pcb the tcp pcb to abort
+ */
+void
+tcp_abort(struct tcp_pcb *pcb)
+{
+  tcp_abandon(pcb, 1);
+}
+
+/**
+ * @ingroup tcp_raw
+ * Binds the connection to a local port number and IP address. If the
+ * IP address is not given (i.e., ipaddr == IP_ANY_TYPE), the connection is
+ * bound to all local IP addresses.
+ * If another connection is bound to the same port, the function will
+ * return ERR_USE, otherwise ERR_OK is returned.
+ *
+ * @param pcb the tcp_pcb to bind (no check is done whether this pcb is
+ *        already bound!)
+ * @param ipaddr the local ip address to bind to (use IPx_ADDR_ANY to bind
+ *        to any local address
+ * @param port the local port to bind to
+ * @return ERR_USE if the port is already in use
+ *         ERR_VAL if bind failed because the PCB is not in a valid state
+ *         ERR_OK if bound
+ */
+err_t
+tcp_bind(struct tcp_pcb *pcb, const ip_addr_t *ipaddr, u16_t port)
+{
+  int i;
+  int max_pcb_list = NUM_TCP_PCB_LISTS;
+  struct tcp_pcb *cpcb;
+#if LWIP_IPV6 && LWIP_IPV6_SCOPES
+  ip_addr_t zoned_ipaddr;
+#endif /* LWIP_IPV6 && LWIP_IPV6_SCOPES */
+
+  LWIP_ASSERT_CORE_LOCKED();
+
+#if LWIP_IPV4
+  /* Don't propagate NULL pointer (IPv4 ANY) to subsequent functions */
+  if (ipaddr == NULL) {
+    ipaddr = IP4_ADDR_ANY;
+  }
+#else /* LWIP_IPV4 */
+  LWIP_ERROR("tcp_bind: invalid ipaddr", ipaddr != NULL, return ERR_ARG);
+#endif /* LWIP_IPV4 */
+
+  LWIP_ERROR("tcp_bind: invalid pcb", pcb != NULL, return ERR_ARG);
+
+  LWIP_ERROR("tcp_bind: can only bind in state CLOSED", pcb->state == CLOSED, return ERR_VAL);
+
+#if SO_REUSE
+  /* Unless the REUSEADDR flag is set,
+     we have to check the pcbs in TIME-WAIT state, also.
+     We do not dump TIME_WAIT pcb's; they can still be matched by incoming
+     packets using both local and remote IP addresses and ports to distinguish.
+   */
+  if (ip_get_option(pcb, SOF_REUSEADDR)) {
+    max_pcb_list = NUM_TCP_PCB_LISTS_NO_TIME_WAIT;
+  }
+#endif /* SO_REUSE */
+
+#if LWIP_IPV6 && LWIP_IPV6_SCOPES
+  /* If the given IP address should have a zone but doesn't, assign one now.
+   * This is legacy support: scope-aware callers should always provide properly
+   * zoned source addresses. Do the zone selection before the address-in-use
+   * check below; as such we have to make a temporary copy of the address. */
+  if (IP_IS_V6(ipaddr) && ip6_addr_lacks_zone(ip_2_ip6(ipaddr), IP6_UNICAST)) {
+    ip_addr_copy(zoned_ipaddr, *ipaddr);
+    ip6_addr_select_zone(ip_2_ip6(&zoned_ipaddr), ip_2_ip6(&zoned_ipaddr));
+    ipaddr = &zoned_ipaddr;
+  }
+#endif /* LWIP_IPV6 && LWIP_IPV6_SCOPES */
+
+  if (port == 0) {
+    port = tcp_new_port();
+    if (port == 0) {
+      return ERR_BUF;
+    }
+  } else {
+    /* Check if the address already is in use (on all lists) */
+    for (i = 0; i < max_pcb_list; i++) {
+      for (cpcb = *tcp_pcb_lists[i]; cpcb != NULL; cpcb = cpcb->next) {
+        if (cpcb->local_port == port) {
+#if SO_REUSE
+          /* Omit checking for the same port if both pcbs have REUSEADDR set.
+             For SO_REUSEADDR, the duplicate-check for a 5-tuple is done in
+             tcp_connect. */
+          if (!ip_get_option(pcb, SOF_REUSEADDR) ||
+              !ip_get_option(cpcb, SOF_REUSEADDR))
+#endif /* SO_REUSE */
+          {
+            /* @todo: check accept_any_ip_version */
+            if ((IP_IS_V6(ipaddr) == IP_IS_V6_VAL(cpcb->local_ip)) &&
+                (ip_addr_isany(&cpcb->local_ip) ||
+                 ip_addr_isany(ipaddr) ||
+                 ip_addr_cmp(&cpcb->local_ip, ipaddr))) {
+              return ERR_USE;
+            }
+          }
+        }
+      }
+    }
+  }
+
+  if (!ip_addr_isany(ipaddr)
+#if LWIP_IPV4 && LWIP_IPV6
+      || (IP_GET_TYPE(ipaddr) != IP_GET_TYPE(&pcb->local_ip))
+#endif /* LWIP_IPV4 && LWIP_IPV6 */
+     ) {
+    ip_addr_set(&pcb->local_ip, ipaddr);
+  }
+  pcb->local_port = port;
+  TCP_REG(&tcp_bound_pcbs, pcb);
+  LWIP_DEBUGF(TCP_DEBUG, ("tcp_bind: bind to port %"U16_F"\n", port));
+  return ERR_OK;
+}
+
+/**
+ * @ingroup tcp_raw
+ * Binds the connection to a netif and IP address.
+ * After calling this function, all packets received via this PCB
+ * are guaranteed to have come in via the specified netif, and all
+ * outgoing packets will go out via the specified netif.
+ *
+ * @param pcb the tcp_pcb to bind.
+ * @param netif the netif to bind to. Can be NULL.
+ */
+void
+tcp_bind_netif(struct tcp_pcb *pcb, const struct netif *netif)
+{
+  LWIP_ASSERT_CORE_LOCKED();
+  if (netif != NULL) {
+    pcb->netif_idx = netif_get_index(netif);
+  } else {
+    pcb->netif_idx = NETIF_NO_INDEX;
+  }
+}
+
+#if LWIP_CALLBACK_API
+/**
+ * Default accept callback if no accept callback is specified by the user.
+ */
+static err_t
+tcp_accept_null(void *arg, struct tcp_pcb *pcb, err_t err)
+{
+  LWIP_UNUSED_ARG(arg);
+  LWIP_UNUSED_ARG(err);
+
+  LWIP_ASSERT("tcp_accept_null: invalid pcb", pcb != NULL);
+
+  tcp_abort(pcb);
+
+  return ERR_ABRT;
+}
+#endif /* LWIP_CALLBACK_API */
+
+/**
+ * @ingroup tcp_raw
+ * Set the state of the connection to be LISTEN, which means that it
+ * is able to accept incoming connections. The protocol control block
+ * is reallocated in order to consume less memory. Setting the
+ * connection to LISTEN is an irreversible process.
+ * When an incoming connection is accepted, the function specified with
+ * the tcp_accept() function will be called. The pcb has to be bound
+ * to a local port with the tcp_bind() function.
+ * 
+ * The tcp_listen() function returns a new connection identifier, and
+ * the one passed as an argument to the function will be
+ * deallocated. The reason for this behavior is that less memory is
+ * needed for a connection that is listening, so tcp_listen() will
+ * reclaim the memory needed for the original connection and allocate a
+ * new smaller memory block for the listening connection.
+ *
+ * tcp_listen() may return NULL if no memory was available for the
+ * listening connection. If so, the memory associated with the pcb
+ * passed as an argument to tcp_listen() will not be deallocated.
+ *
+ * The backlog limits the number of outstanding connections
+ * in the listen queue to the value specified by the backlog argument.
+ * To use it, your need to set TCP_LISTEN_BACKLOG=1 in your lwipopts.h.
+ * 
+ * @param pcb the original tcp_pcb
+ * @param backlog the incoming connections queue limit
+ * @return tcp_pcb used for listening, consumes less memory.
+ *
+ * @note The original tcp_pcb is freed. This function therefore has to be
+ *       called like this:
+ *             tpcb = tcp_listen_with_backlog(tpcb, backlog);
+ */
+struct tcp_pcb *
+tcp_listen_with_backlog(struct tcp_pcb *pcb, u8_t backlog)
+{
+  LWIP_ASSERT_CORE_LOCKED();
+  return tcp_listen_with_backlog_and_err(pcb, backlog, NULL);
+}
+
+/**
+ * @ingroup tcp_raw
+ * Set the state of the connection to be LISTEN, which means that it
+ * is able to accept incoming connections. The protocol control block
+ * is reallocated in order to consume less memory. Setting the
+ * connection to LISTEN is an irreversible process.
+ *
+ * @param pcb the original tcp_pcb
+ * @param backlog the incoming connections queue limit
+ * @param err when NULL is returned, this contains the error reason
+ * @return tcp_pcb used for listening, consumes less memory.
+ *
+ * @note The original tcp_pcb is freed. This function therefore has to be
+ *       called like this:
+ *             tpcb = tcp_listen_with_backlog_and_err(tpcb, backlog, &err);
+ */
+struct tcp_pcb *
+tcp_listen_with_backlog_and_err(struct tcp_pcb *pcb, u8_t backlog, err_t *err)
+{
+  struct tcp_pcb_listen *lpcb = NULL;
+  err_t res;
+
+  LWIP_UNUSED_ARG(backlog);
+
+  LWIP_ASSERT_CORE_LOCKED();
+
+  LWIP_ERROR("tcp_listen_with_backlog_and_err: invalid pcb", pcb != NULL, res = ERR_ARG; goto done);
+  LWIP_ERROR("tcp_listen_with_backlog_and_err: pcb already connected", pcb->state == CLOSED, res = ERR_CLSD; goto done);
+
+  /* already listening? */
+  if (pcb->state == LISTEN) {
+    lpcb = (struct tcp_pcb_listen *)pcb;
+    res = ERR_ALREADY;
+    goto done;
+  }
+#if SO_REUSE
+  if (ip_get_option(pcb, SOF_REUSEADDR)) {
+    /* Since SOF_REUSEADDR allows reusing a local address before the pcb's usage
+       is declared (listen-/connection-pcb), we have to make sure now that
+       this port is only used once for every local IP. */
+    for (lpcb = tcp_listen_pcbs.listen_pcbs; lpcb != NULL; lpcb = lpcb->next) {
+      if ((lpcb->local_port == pcb->local_port) &&
+          ip_addr_cmp(&lpcb->local_ip, &pcb->local_ip)) {
+        /* this address/port is already used */
+        lpcb = NULL;
+        res = ERR_USE;
+        goto done;
+      }
+    }
+  }
+#endif /* SO_REUSE */
+  lpcb = (struct tcp_pcb_listen *)memp_malloc(MEMP_TCP_PCB_LISTEN);
+  if (lpcb == NULL) {
+    res = ERR_MEM;
+    goto done;
+  }
+  lpcb->callback_arg = pcb->callback_arg;
+  lpcb->local_port = pcb->local_port;
+  lpcb->state = LISTEN;
+  lpcb->prio = pcb->prio;
+  lpcb->so_options = pcb->so_options;
+  lpcb->netif_idx = NETIF_NO_INDEX;
+  lpcb->ttl = pcb->ttl;
+  lpcb->tos = pcb->tos;
+#if LWIP_IPV4 && LWIP_IPV6
+  IP_SET_TYPE_VAL(lpcb->remote_ip, pcb->local_ip.type);
+#endif /* LWIP_IPV4 && LWIP_IPV6 */
+  ip_addr_copy(lpcb->local_ip, pcb->local_ip);
+  if (pcb->local_port != 0) {
+    TCP_RMV(&tcp_bound_pcbs, pcb);
+  }
+#if LWIP_TCP_PCB_NUM_EXT_ARGS
+  /* copy over ext_args to listening pcb  */
+  memcpy(&lpcb->ext_args, &pcb->ext_args, sizeof(pcb->ext_args));
+#endif
+  tcp_free(pcb);
+#if LWIP_CALLBACK_API
+  lpcb->accept = tcp_accept_null;
+#endif /* LWIP_CALLBACK_API */
+#if TCP_LISTEN_BACKLOG
+  lpcb->accepts_pending = 0;
+  tcp_backlog_set(lpcb, backlog);
+#endif /* TCP_LISTEN_BACKLOG */
+  TCP_REG(&tcp_listen_pcbs.pcbs, (struct tcp_pcb *)lpcb);
+  res = ERR_OK;
+done:
+  if (err != NULL) {
+    *err = res;
+  }
+  return (struct tcp_pcb *)lpcb;
+}
+
+/**
+ * Update the state that tracks the available window space to advertise.
+ *
+ * Returns how much extra window would be advertised if we sent an
+ * update now.
+ */
+u32_t
+tcp_update_rcv_ann_wnd(struct tcp_pcb *pcb)
+{
+  u32_t new_right_edge;
+
+  LWIP_ASSERT("tcp_update_rcv_ann_wnd: invalid pcb", pcb != NULL);
+  new_right_edge = pcb->rcv_nxt + pcb->rcv_wnd;
+
+  if (TCP_SEQ_GEQ(new_right_edge, pcb->rcv_ann_right_edge + LWIP_MIN((TCP_WND / 2), pcb->mss))) {
+    /* we can advertise more window */
+    pcb->rcv_ann_wnd = pcb->rcv_wnd;
+    return new_right_edge - pcb->rcv_ann_right_edge;
+  } else {
+    if (TCP_SEQ_GT(pcb->rcv_nxt, pcb->rcv_ann_right_edge)) {
+      /* Can happen due to other end sending out of advertised window,
+       * but within actual available (but not yet advertised) window */
+      pcb->rcv_ann_wnd = 0;
+    } else {
+      /* keep the right edge of window constant */
+      u32_t new_rcv_ann_wnd = pcb->rcv_ann_right_edge - pcb->rcv_nxt;
+#if !LWIP_WND_SCALE
+      LWIP_ASSERT("new_rcv_ann_wnd <= 0xffff", new_rcv_ann_wnd <= 0xffff);
+#endif
+      pcb->rcv_ann_wnd = (tcpwnd_size_t)new_rcv_ann_wnd;
+    }
+    return 0;
+  }
+}
+
+/**
+ * @ingroup tcp_raw
+ * This function should be called by the application when it has
+ * processed the data. The purpose is to advertise a larger window
+ * when the data has been processed.
+ *
+ * @param pcb the tcp_pcb for which data is read
+ * @param len the amount of bytes that have been read by the application
+ */
+void
+tcp_recved(struct tcp_pcb *pcb, u16_t len)
+{
+  u32_t wnd_inflation;
+  tcpwnd_size_t rcv_wnd;
+
+  LWIP_ASSERT_CORE_LOCKED();
+
+  LWIP_ERROR("tcp_recved: invalid pcb", pcb != NULL, return);
+
+  /* pcb->state LISTEN not allowed here */
+  LWIP_ASSERT("don't call tcp_recved for listen-pcbs",
+              pcb->state != LISTEN);
+
+  rcv_wnd = (tcpwnd_size_t)(pcb->rcv_wnd + len);
+  if ((rcv_wnd > TCP_WND_MAX(pcb)) || (rcv_wnd < pcb->rcv_wnd)) {
+    /* window got too big or tcpwnd_size_t overflow */
+    LWIP_DEBUGF(TCP_DEBUG, ("tcp_recved: window got too big or tcpwnd_size_t overflow\n"));
+    pcb->rcv_wnd = TCP_WND_MAX(pcb);
+  } else  {
+    pcb->rcv_wnd = rcv_wnd;
+  }
+
+  wnd_inflation = tcp_update_rcv_ann_wnd(pcb);
+
+  /* If the change in the right edge of window is significant (default
+   * watermark is TCP_WND/4), then send an explicit update now.
+   * Otherwise wait for a packet to be sent in the normal course of
+   * events (or more window to be available later) */
+  if (wnd_inflation >= TCP_WND_UPDATE_THRESHOLD) {
+    tcp_ack_now(pcb);
+    tcp_output(pcb);
+  }
+
+  LWIP_DEBUGF(TCP_DEBUG, ("tcp_recved: received %"U16_F" bytes, wnd %"TCPWNDSIZE_F" (%"TCPWNDSIZE_F").\n",
+                          len, pcb->rcv_wnd, (u16_t)(TCP_WND_MAX(pcb) - pcb->rcv_wnd)));
+}
+
+/**
+ * Allocate a new local TCP port.
+ *
+ * @return a new (free) local TCP port number
+ */
+static u16_t
+tcp_new_port(void)
+{
+  u8_t i;
+  u16_t n = 0;
+  struct tcp_pcb *pcb;
+
+again:
+  tcp_port++;
+  if (tcp_port == TCP_LOCAL_PORT_RANGE_END) {
+    tcp_port = TCP_LOCAL_PORT_RANGE_START;
+  }
+  /* Check all PCB lists. */
+  for (i = 0; i < NUM_TCP_PCB_LISTS; i++) {
+    for (pcb = *tcp_pcb_lists[i]; pcb != NULL; pcb = pcb->next) {
+      if (pcb->local_port == tcp_port) {
+        n++;
+        if (n > (TCP_LOCAL_PORT_RANGE_END - TCP_LOCAL_PORT_RANGE_START)) {
+          return 0;
+        }
+        goto again;
+      }
+    }
+  }
+  return tcp_port;
+}
+
+/**
+ * @ingroup tcp_raw
+ * Connects to another host. The function given as the "connected"
+ * argument will be called when the connection has been established.
+ *  Sets up the pcb to connect to the remote host and sends the
+ * initial SYN segment which opens the connection. 
+ *
+ * The tcp_connect() function returns immediately; it does not wait for
+ * the connection to be properly setup. Instead, it will call the
+ * function specified as the fourth argument (the "connected" argument)
+ * when the connection is established. If the connection could not be
+ * properly established, either because the other host refused the
+ * connection or because the other host didn't answer, the "err"
+ * callback function of this pcb (registered with tcp_err, see below)
+ * will be called.
+ *
+ * The tcp_connect() function can return ERR_MEM if no memory is
+ * available for enqueueing the SYN segment. If the SYN indeed was
+ * enqueued successfully, the tcp_connect() function returns ERR_OK.
+ *
+ * @param pcb the tcp_pcb used to establish the connection
+ * @param ipaddr the remote ip address to connect to
+ * @param port the remote tcp port to connect to
+ * @param connected callback function to call when connected (on error,
+                    the err calback will be called)
+ * @return ERR_VAL if invalid arguments are given
+ *         ERR_OK if connect request has been sent
+ *         other err_t values if connect request couldn't be sent
+ */
+err_t
+tcp_connect(struct tcp_pcb *pcb, const ip_addr_t *ipaddr, u16_t port,
+            tcp_connected_fn connected)
+{
+  struct netif *netif = NULL;
+  err_t ret;
+  u32_t iss;
+  u16_t old_local_port;
+
+  LWIP_ASSERT_CORE_LOCKED();
+
+  LWIP_ERROR("tcp_connect: invalid pcb", pcb != NULL, return ERR_ARG);
+  LWIP_ERROR("tcp_connect: invalid ipaddr", ipaddr != NULL, return ERR_ARG);
+
+  LWIP_ERROR("tcp_connect: can only connect from state CLOSED", pcb->state == CLOSED, return ERR_ISCONN);
+
+  LWIP_DEBUGF(TCP_DEBUG, ("tcp_connect to port %"U16_F"\n", port));
+  ip_addr_set(&pcb->remote_ip, ipaddr);
+  pcb->remote_port = port;
+
+  if (pcb->netif_idx != NETIF_NO_INDEX) {
+    netif = netif_get_by_index(pcb->netif_idx);
+  } else {
+    /* check if we have a route to the remote host */
+    netif = ip_route(&pcb->local_ip, &pcb->remote_ip);
+  }
+  if (netif == NULL) {
+    /* Don't even try to send a SYN packet if we have no route since that will fail. */
+    return ERR_RTE;
+  }
+
+  /* check if local IP has been assigned to pcb, if not, get one */
+  if (ip_addr_isany(&pcb->local_ip)) {
+    const ip_addr_t *local_ip = ip_netif_get_local_ip(netif, ipaddr);
+    if (local_ip == NULL) {
+      return ERR_RTE;
+    }
+    ip_addr_copy(pcb->local_ip, *local_ip);
+  }
+
+#if LWIP_IPV6 && LWIP_IPV6_SCOPES
+  /* If the given IP address should have a zone but doesn't, assign one now.
+   * Given that we already have the target netif, this is easy and cheap. */
+  if (IP_IS_V6(&pcb->remote_ip) &&
+      ip6_addr_lacks_zone(ip_2_ip6(&pcb->remote_ip), IP6_UNICAST)) {
+    ip6_addr_assign_zone(ip_2_ip6(&pcb->remote_ip), IP6_UNICAST, netif);
+  }
+#endif /* LWIP_IPV6 && LWIP_IPV6_SCOPES */
+
+  old_local_port = pcb->local_port;
+  if (pcb->local_port == 0) {
+    pcb->local_port = tcp_new_port();
+    if (pcb->local_port == 0) {
+      return ERR_BUF;
+    }
+  } else {
+#if SO_REUSE
+    if (ip_get_option(pcb, SOF_REUSEADDR)) {
+      /* Since SOF_REUSEADDR allows reusing a local address, we have to make sure
+         now that the 5-tuple is unique. */
+      struct tcp_pcb *cpcb;
+      int i;
+      /* Don't check listen- and bound-PCBs, check active- and TIME-WAIT PCBs. */
+      for (i = 2; i < NUM_TCP_PCB_LISTS; i++) {
+        for (cpcb = *tcp_pcb_lists[i]; cpcb != NULL; cpcb = cpcb->next) {
+          if ((cpcb->local_port == pcb->local_port) &&
+              (cpcb->remote_port == port) &&
+              ip_addr_cmp(&cpcb->local_ip, &pcb->local_ip) &&
+              ip_addr_cmp(&cpcb->remote_ip, ipaddr)) {
+            /* linux returns EISCONN here, but ERR_USE should be OK for us */
+            return ERR_USE;
+          }
+        }
+      }
+    }
+#endif /* SO_REUSE */
+  }
+
+  iss = tcp_next_iss(pcb);
+  pcb->rcv_nxt = 0;
+  pcb->snd_nxt = iss;
+  pcb->lastack = iss - 1;
+  pcb->snd_wl2 = iss - 1;
+  pcb->snd_lbb = iss - 1;
+  /* Start with a window that does not need scaling. When window scaling is
+     enabled and used, the window is enlarged when both sides agree on scaling. */
+  pcb->rcv_wnd = pcb->rcv_ann_wnd = TCPWND_MIN16(TCP_WND);
+  pcb->rcv_ann_right_edge = pcb->rcv_nxt;
+  pcb->snd_wnd = TCP_WND;
+  /* As initial send MSS, we use TCP_MSS but limit it to 536.
+     The send MSS is updated when an MSS option is received. */
+  pcb->mss = INITIAL_MSS;
+#if TCP_CALCULATE_EFF_SEND_MSS
+  pcb->mss = tcp_eff_send_mss_netif(pcb->mss, netif, &pcb->remote_ip);
+#endif /* TCP_CALCULATE_EFF_SEND_MSS */
+  pcb->cwnd = 1;
+#if LWIP_CALLBACK_API
+  pcb->connected = connected;
+#else /* LWIP_CALLBACK_API */
+  LWIP_UNUSED_ARG(connected);
+#endif /* LWIP_CALLBACK_API */
+
+  /* Send a SYN together with the MSS option. */
+  ret = tcp_enqueue_flags(pcb, TCP_SYN);
+  if (ret == ERR_OK) {
+    /* SYN segment was enqueued, changed the pcbs state now */
+    pcb->state = SYN_SENT;
+    if (old_local_port != 0) {
+      TCP_RMV(&tcp_bound_pcbs, pcb);
+    }
+    TCP_REG_ACTIVE(pcb);
+    MIB2_STATS_INC(mib2.tcpactiveopens);
+
+    tcp_output(pcb);
+  }
+  return ret;
+}
+
+/**
+ * Called every 500 ms and implements the retransmission timer and the timer that
+ * removes PCBs that have been in TIME-WAIT for enough time. It also increments
+ * various timers such as the inactivity timer in each PCB.
+ *
+ * Automatically called from tcp_tmr().
+ */
+void
+tcp_slowtmr(void)
+{
+  struct tcp_pcb *pcb, *prev;
+  tcpwnd_size_t eff_wnd;
+  u8_t pcb_remove;      /* flag if a PCB should be removed */
+  u8_t pcb_reset;       /* flag if a RST should be sent when removing */
+  err_t err;
+
+  err = ERR_OK;
+
+  ++tcp_ticks;
+  ++tcp_timer_ctr;
+
+tcp_slowtmr_start:
+  /* Steps through all of the active PCBs. */
+  prev = NULL;
+  pcb = tcp_active_pcbs;
+  if (pcb == NULL) {
+    LWIP_DEBUGF(TCP_DEBUG, ("tcp_slowtmr: no active pcbs\n"));
+  }
+  while (pcb != NULL) {
+    LWIP_DEBUGF(TCP_DEBUG, ("tcp_slowtmr: processing active pcb\n"));
+    LWIP_ASSERT("tcp_slowtmr: active pcb->state != CLOSED\n", pcb->state != CLOSED);
+    LWIP_ASSERT("tcp_slowtmr: active pcb->state != LISTEN\n", pcb->state != LISTEN);
+    LWIP_ASSERT("tcp_slowtmr: active pcb->state != TIME-WAIT\n", pcb->state != TIME_WAIT);
+    if (pcb->last_timer == tcp_timer_ctr) {
+      /* skip this pcb, we have already processed it */
+      prev = pcb;
+      pcb = pcb->next;
+      continue;
+    }
+    pcb->last_timer = tcp_timer_ctr;
+
+    pcb_remove = 0;
+    pcb_reset = 0;
+
+    if (pcb->state == SYN_SENT && pcb->nrtx >= TCP_SYNMAXRTX) {
+      ++pcb_remove;
+      LWIP_DEBUGF(TCP_DEBUG, ("tcp_slowtmr: max SYN retries reached\n"));
+    } else if (pcb->nrtx >= TCP_MAXRTX) {
+      ++pcb_remove;
+      LWIP_DEBUGF(TCP_DEBUG, ("tcp_slowtmr: max DATA retries reached\n"));
+    } else {
+      if (pcb->persist_backoff > 0) {
+        LWIP_ASSERT("tcp_slowtimr: persist ticking with in-flight data", pcb->unacked == NULL);
+        LWIP_ASSERT("tcp_slowtimr: persist ticking with empty send buffer", pcb->unsent != NULL);
+        if (pcb->persist_probe >= TCP_MAXRTX) {
+          ++pcb_remove; /* max probes reached */
+        } else {
+          u8_t backoff_cnt = tcp_persist_backoff[pcb->persist_backoff - 1];
+          if (pcb->persist_cnt < backoff_cnt) {
+            pcb->persist_cnt++;
+          }
+          if (pcb->persist_cnt >= backoff_cnt) {
+            int next_slot = 1; /* increment timer to next slot */
+            /* If snd_wnd is zero, send 1 byte probes */
+            if (pcb->snd_wnd == 0) {
+              if (tcp_zero_window_probe(pcb) != ERR_OK) {
+                next_slot = 0; /* try probe again with current slot */
+              }
+              /* snd_wnd not fully closed, split unsent head and fill window */
+            } else {
+              if (tcp_split_unsent_seg(pcb, (u16_t)pcb->snd_wnd) == ERR_OK) {
+                if (tcp_output(pcb) == ERR_OK) {
+                  /* sending will cancel persist timer, else retry with current slot */
+                  next_slot = 0;
+                }
+              }
+            }
+            if (next_slot) {
+              pcb->persist_cnt = 0;
+              if (pcb->persist_backoff < sizeof(tcp_persist_backoff)) {
+                pcb->persist_backoff++;
+              }
+            }
+          }
+        }
+      } else {
+        /* Increase the retransmission timer if it is running */
+        if ((pcb->rtime >= 0) && (pcb->rtime < 0x7FFF)) {
+          ++pcb->rtime;
+        }
+
+        if (pcb->rtime >= pcb->rto) {
+          /* Time for a retransmission. */
+          LWIP_DEBUGF(TCP_RTO_DEBUG, ("tcp_slowtmr: rtime %"S16_F
+                                      " pcb->rto %"S16_F"\n",
+                                      pcb->rtime, pcb->rto));
+          /* If prepare phase fails but we have unsent data but no unacked data,
+             still execute the backoff calculations below, as this means we somehow
+             failed to send segment. */
+          if ((tcp_rexmit_rto_prepare(pcb) == ERR_OK) || ((pcb->unacked == NULL) && (pcb->unsent != NULL))) {
+            /* Double retransmission time-out unless we are trying to
+             * connect to somebody (i.e., we are in SYN_SENT). */
+            if (pcb->state != SYN_SENT) {
+              u8_t backoff_idx = LWIP_MIN(pcb->nrtx, sizeof(tcp_backoff) - 1);
+              int calc_rto = ((pcb->sa >> 3) + pcb->sv) << tcp_backoff[backoff_idx];
+              pcb->rto = (s16_t)LWIP_MIN(calc_rto, 0x7FFF);
+            }
+
+            /* Reset the retransmission timer. */
+            pcb->rtime = 0;
+
+            /* Reduce congestion window and ssthresh. */
+            eff_wnd = LWIP_MIN(pcb->cwnd, pcb->snd_wnd);
+            pcb->ssthresh = eff_wnd >> 1;
+            if (pcb->ssthresh < (tcpwnd_size_t)(pcb->mss << 1)) {
+              pcb->ssthresh = (tcpwnd_size_t)(pcb->mss << 1);
+            }
+            pcb->cwnd = pcb->mss;
+            LWIP_DEBUGF(TCP_CWND_DEBUG, ("tcp_slowtmr: cwnd %"TCPWNDSIZE_F
+                                         " ssthresh %"TCPWNDSIZE_F"\n",
+                                         pcb->cwnd, pcb->ssthresh));
+            pcb->bytes_acked = 0;
+
+            /* The following needs to be called AFTER cwnd is set to one
+               mss - STJ */
+            tcp_rexmit_rto_commit(pcb);
+          }
+        }
+      }
+    }
+    /* Check if this PCB has stayed too long in FIN-WAIT-2 */
+    if (pcb->state == FIN_WAIT_2) {
+      /* If this PCB is in FIN_WAIT_2 because of SHUT_WR don't let it time out. */
+      if (pcb->flags & TF_RXCLOSED) {
+        /* PCB was fully closed (either through close() or SHUT_RDWR):
+           normal FIN-WAIT timeout handling. */
+        if ((u32_t)(tcp_ticks - pcb->tmr) >
+            TCP_FIN_WAIT_TIMEOUT / TCP_SLOW_INTERVAL) {
+          ++pcb_remove;
+          LWIP_DEBUGF(TCP_DEBUG, ("tcp_slowtmr: removing pcb stuck in FIN-WAIT-2\n"));
+        }
+      }
+    }
+
+    /* Check if KEEPALIVE should be sent */
+    if (ip_get_option(pcb, SOF_KEEPALIVE) &&
+        ((pcb->state == ESTABLISHED) ||
+         (pcb->state == CLOSE_WAIT))) {
+      if ((u32_t)(tcp_ticks - pcb->tmr) >
+          (pcb->keep_idle + TCP_KEEP_DUR(pcb)) / TCP_SLOW_INTERVAL) {
+        LWIP_DEBUGF(TCP_DEBUG, ("tcp_slowtmr: KEEPALIVE timeout. Aborting connection to "));
+        ip_addr_debug_print_val(TCP_DEBUG, pcb->remote_ip);
+        LWIP_DEBUGF(TCP_DEBUG, ("\n"));
+
+        ++pcb_remove;
+        ++pcb_reset;
+      } else if ((u32_t)(tcp_ticks - pcb->tmr) >
+                 (pcb->keep_idle + pcb->keep_cnt_sent * TCP_KEEP_INTVL(pcb))
+                 / TCP_SLOW_INTERVAL) {
+        err = tcp_keepalive(pcb);
+        if (err == ERR_OK) {
+          pcb->keep_cnt_sent++;
+        }
+      }
+    }
+
+    /* If this PCB has queued out of sequence data, but has been
+       inactive for too long, will drop the data (it will eventually
+       be retransmitted). */
+#if TCP_QUEUE_OOSEQ
+    if (pcb->ooseq != NULL &&
+        (tcp_ticks - pcb->tmr >= (u32_t)pcb->rto * TCP_OOSEQ_TIMEOUT)) {
+      LWIP_DEBUGF(TCP_CWND_DEBUG, ("tcp_slowtmr: dropping OOSEQ queued data\n"));
+      tcp_free_ooseq(pcb);
+    }
+#endif /* TCP_QUEUE_OOSEQ */
+
+    /* Check if this PCB has stayed too long in SYN-RCVD */
+    if (pcb->state == SYN_RCVD) {
+      if ((u32_t)(tcp_ticks - pcb->tmr) >
+          TCP_SYN_RCVD_TIMEOUT / TCP_SLOW_INTERVAL) {
+        ++pcb_remove;
+        LWIP_DEBUGF(TCP_DEBUG, ("tcp_slowtmr: removing pcb stuck in SYN-RCVD\n"));
+      }
+    }
+
+    /* Check if this PCB has stayed too long in LAST-ACK */
+    if (pcb->state == LAST_ACK) {
+      if ((u32_t)(tcp_ticks - pcb->tmr) > 2 * TCP_MSL / TCP_SLOW_INTERVAL) {
+        ++pcb_remove;
+        LWIP_DEBUGF(TCP_DEBUG, ("tcp_slowtmr: removing pcb stuck in LAST-ACK\n"));
+      }
+    }
+
+    /* If the PCB should be removed, do it. */
+    if (pcb_remove) {
+      struct tcp_pcb *pcb2;
+#if LWIP_CALLBACK_API
+      tcp_err_fn err_fn = pcb->errf;
+#endif /* LWIP_CALLBACK_API */
+      void *err_arg;
+      enum tcp_state last_state;
+      tcp_pcb_purge(pcb);
+      /* Remove PCB from tcp_active_pcbs list. */
+      if (prev != NULL) {
+        LWIP_ASSERT("tcp_slowtmr: middle tcp != tcp_active_pcbs", pcb != tcp_active_pcbs);
+        prev->next = pcb->next;
+      } else {
+        /* This PCB was the first. */
+        LWIP_ASSERT("tcp_slowtmr: first pcb == tcp_active_pcbs", tcp_active_pcbs == pcb);
+        tcp_active_pcbs = pcb->next;
+      }
+
+      if (pcb_reset) {
+        tcp_rst(pcb, pcb->snd_nxt, pcb->rcv_nxt, &pcb->local_ip, &pcb->remote_ip,
+                pcb->local_port, pcb->remote_port);
+      }
+
+      err_arg = pcb->callback_arg;
+      last_state = pcb->state;
+      pcb2 = pcb;
+      pcb = pcb->next;
+      tcp_free(pcb2);
+
+      tcp_active_pcbs_changed = 0;
+      TCP_EVENT_ERR(last_state, err_fn, err_arg, ERR_ABRT);
+      if (tcp_active_pcbs_changed) {
+        goto tcp_slowtmr_start;
+      }
+    } else {
+      /* get the 'next' element now and work with 'prev' below (in case of abort) */
+      prev = pcb;
+      pcb = pcb->next;
+
+      /* We check if we should poll the connection. */
+      ++prev->polltmr;
+      if (prev->polltmr >= prev->pollinterval) {
+        prev->polltmr = 0;
+        LWIP_DEBUGF(TCP_DEBUG, ("tcp_slowtmr: polling application\n"));
+        tcp_active_pcbs_changed = 0;
+        TCP_EVENT_POLL(prev, err);
+        if (tcp_active_pcbs_changed) {
+          goto tcp_slowtmr_start;
+        }
+        /* if err == ERR_ABRT, 'prev' is already deallocated */
+        if (err == ERR_OK) {
+          tcp_output(prev);
+        }
+      }
+    }
+  }
+
+
+  /* Steps through all of the TIME-WAIT PCBs. */
+  prev = NULL;
+  pcb = tcp_tw_pcbs;
+  while (pcb != NULL) {
+    LWIP_ASSERT("tcp_slowtmr: TIME-WAIT pcb->state == TIME-WAIT", pcb->state == TIME_WAIT);
+    pcb_remove = 0;
+
+    /* Check if this PCB has stayed long enough in TIME-WAIT */
+    if ((u32_t)(tcp_ticks - pcb->tmr) > 2 * TCP_MSL / TCP_SLOW_INTERVAL) {
+      ++pcb_remove;
+    }
+
+    /* If the PCB should be removed, do it. */
+    if (pcb_remove) {
+      struct tcp_pcb *pcb2;
+      tcp_pcb_purge(pcb);
+      /* Remove PCB from tcp_tw_pcbs list. */
+      if (prev != NULL) {
+        LWIP_ASSERT("tcp_slowtmr: middle tcp != tcp_tw_pcbs", pcb != tcp_tw_pcbs);
+        prev->next = pcb->next;
+      } else {
+        /* This PCB was the first. */
+        LWIP_ASSERT("tcp_slowtmr: first pcb == tcp_tw_pcbs", tcp_tw_pcbs == pcb);
+        tcp_tw_pcbs = pcb->next;
+      }
+      pcb2 = pcb;
+      pcb = pcb->next;
+      tcp_free(pcb2);
+    } else {
+      prev = pcb;
+      pcb = pcb->next;
+    }
+  }
+}
+
+/**
+ * Is called every TCP_FAST_INTERVAL (250 ms) and process data previously
+ * "refused" by upper layer (application) and sends delayed ACKs or pending FINs.
+ *
+ * Automatically called from tcp_tmr().
+ */
+void
+tcp_fasttmr(void)
+{
+  struct tcp_pcb *pcb;
+
+  ++tcp_timer_ctr;
+
+tcp_fasttmr_start:
+  pcb = tcp_active_pcbs;
+
+  while (pcb != NULL) {
+    if (pcb->last_timer != tcp_timer_ctr) {
+      struct tcp_pcb *next;
+      pcb->last_timer = tcp_timer_ctr;
+      /* send delayed ACKs */
+      if (pcb->flags & TF_ACK_DELAY) {
+        LWIP_DEBUGF(TCP_DEBUG, ("tcp_fasttmr: delayed ACK\n"));
+        tcp_ack_now(pcb);
+        tcp_output(pcb);
+        tcp_clear_flags(pcb, TF_ACK_DELAY | TF_ACK_NOW);
+      }
+      /* send pending FIN */
+      if (pcb->flags & TF_CLOSEPEND) {
+        LWIP_DEBUGF(TCP_DEBUG, ("tcp_fasttmr: pending FIN\n"));
+        tcp_clear_flags(pcb, TF_CLOSEPEND);
+        tcp_close_shutdown_fin(pcb);
+      }
+
+      next = pcb->next;
+
+      /* If there is data which was previously "refused" by upper layer */
+      if (pcb->refused_data != NULL) {
+        tcp_active_pcbs_changed = 0;
+        tcp_process_refused_data(pcb);
+        if (tcp_active_pcbs_changed) {
+          /* application callback has changed the pcb list: restart the loop */
+          goto tcp_fasttmr_start;
+        }
+      }
+      pcb = next;
+    } else {
+      pcb = pcb->next;
+    }
+  }
+}
+
+/** Call tcp_output for all active pcbs that have TF_NAGLEMEMERR set */
+void
+tcp_txnow(void)
+{
+  struct tcp_pcb *pcb;
+
+  for (pcb = tcp_active_pcbs; pcb != NULL; pcb = pcb->next) {
+    if (pcb->flags & TF_NAGLEMEMERR) {
+      tcp_output(pcb);
+    }
+  }
+}
+
+/** Pass pcb->refused_data to the recv callback */
+err_t
+tcp_process_refused_data(struct tcp_pcb *pcb)
+{
+#if TCP_QUEUE_OOSEQ && LWIP_WND_SCALE
+  struct pbuf *rest;
+#endif /* TCP_QUEUE_OOSEQ && LWIP_WND_SCALE */
+
+  LWIP_ERROR("tcp_process_refused_data: invalid pcb", pcb != NULL, return ERR_ARG);
+
+#if TCP_QUEUE_OOSEQ && LWIP_WND_SCALE
+  while (pcb->refused_data != NULL)
+#endif /* TCP_QUEUE_OOSEQ && LWIP_WND_SCALE */
+  {
+    err_t err;
+    u8_t refused_flags = pcb->refused_data->flags;
+    /* set pcb->refused_data to NULL in case the callback frees it and then
+       closes the pcb */
+    struct pbuf *refused_data = pcb->refused_data;
+#if TCP_QUEUE_OOSEQ && LWIP_WND_SCALE
+    pbuf_split_64k(refused_data, &rest);
+    pcb->refused_data = rest;
+#else /* TCP_QUEUE_OOSEQ && LWIP_WND_SCALE */
+    pcb->refused_data = NULL;
+#endif /* TCP_QUEUE_OOSEQ && LWIP_WND_SCALE */
+    /* Notify again application with data previously received. */
+    LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: notify kept packet\n"));
+    TCP_EVENT_RECV(pcb, refused_data, ERR_OK, err);
+    if (err == ERR_OK) {
+      /* did refused_data include a FIN? */
+      if ((refused_flags & PBUF_FLAG_TCP_FIN)
+#if TCP_QUEUE_OOSEQ && LWIP_WND_SCALE
+          && (rest == NULL)
+#endif /* TCP_QUEUE_OOSEQ && LWIP_WND_SCALE */
+         ) {
+        /* correct rcv_wnd as the application won't call tcp_recved()
+           for the FIN's seqno */
+        if (pcb->rcv_wnd != TCP_WND_MAX(pcb)) {
+          pcb->rcv_wnd++;
+        }
+        TCP_EVENT_CLOSED(pcb, err);
+        if (err == ERR_ABRT) {
+          return ERR_ABRT;
+        }
+      }
+    } else if (err == ERR_ABRT) {
+      /* if err == ERR_ABRT, 'pcb' is already deallocated */
+      /* Drop incoming packets because pcb is "full" (only if the incoming
+         segment contains data). */
+      LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: drop incoming packets, because pcb is \"full\"\n"));
+      return ERR_ABRT;
+    } else {
+      /* data is still refused, pbuf is still valid (go on for ACK-only packets) */
+#if TCP_QUEUE_OOSEQ && LWIP_WND_SCALE
+      if (rest != NULL) {
+        pbuf_cat(refused_data, rest);
+      }
+#endif /* TCP_QUEUE_OOSEQ && LWIP_WND_SCALE */
+      pcb->refused_data = refused_data;
+      return ERR_INPROGRESS;
+    }
+  }
+  return ERR_OK;
+}
+
+/**
+ * Deallocates a list of TCP segments (tcp_seg structures).
+ *
+ * @param seg tcp_seg list of TCP segments to free
+ */
+void
+tcp_segs_free(struct tcp_seg *seg)
+{
+  while (seg != NULL) {
+    struct tcp_seg *next = seg->next;
+    tcp_seg_free(seg);
+    seg = next;
+  }
+}
+
+/**
+ * Frees a TCP segment (tcp_seg structure).
+ *
+ * @param seg single tcp_seg to free
+ */
+void
+tcp_seg_free(struct tcp_seg *seg)
+{
+  if (seg != NULL) {
+    if (seg->p != NULL) {
+      pbuf_free(seg->p);
+#if TCP_DEBUG
+      seg->p = NULL;
+#endif /* TCP_DEBUG */
+    }
+    memp_free(MEMP_TCP_SEG, seg);
+  }
+}
+
+/**
+ * @ingroup tcp
+ * Sets the priority of a connection.
+ *
+ * @param pcb the tcp_pcb to manipulate
+ * @param prio new priority
+ */
+void
+tcp_setprio(struct tcp_pcb *pcb, u8_t prio)
+{
+  LWIP_ASSERT_CORE_LOCKED();
+
+  LWIP_ERROR("tcp_setprio: invalid pcb", pcb != NULL, return);
+
+  pcb->prio = prio;
+}
+
+#if TCP_QUEUE_OOSEQ
+/**
+ * Returns a copy of the given TCP segment.
+ * The pbuf and data are not copied, only the pointers
+ *
+ * @param seg the old tcp_seg
+ * @return a copy of seg
+ */
+struct tcp_seg *
+tcp_seg_copy(struct tcp_seg *seg)
+{
+  struct tcp_seg *cseg;
+
+  LWIP_ASSERT("tcp_seg_copy: invalid seg", seg != NULL);
+
+  cseg = (struct tcp_seg *)memp_malloc(MEMP_TCP_SEG);
+  if (cseg == NULL) {
+    return NULL;
+  }
+  SMEMCPY((u8_t *)cseg, (const u8_t *)seg, sizeof(struct tcp_seg));
+  pbuf_ref(cseg->p);
+  return cseg;
+}
+#endif /* TCP_QUEUE_OOSEQ */
+
+#if LWIP_CALLBACK_API
+/**
+ * Default receive callback that is called if the user didn't register
+ * a recv callback for the pcb.
+ */
+err_t
+tcp_recv_null(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err)
+{
+  LWIP_UNUSED_ARG(arg);
+
+  LWIP_ERROR("tcp_recv_null: invalid pcb", pcb != NULL, return ERR_ARG);
+
+  if (p != NULL) {
+    tcp_recved(pcb, p->tot_len);
+    pbuf_free(p);
+  } else if (err == ERR_OK) {
+    return tcp_close(pcb);
+  }
+  return ERR_OK;
+}
+#endif /* LWIP_CALLBACK_API */
+
+/**
+ * Kills the oldest active connection that has a lower priority than 'prio'.
+ *
+ * @param prio minimum priority
+ */
+static void
+tcp_kill_prio(u8_t prio)
+{
+  struct tcp_pcb *pcb, *inactive;
+  u32_t inactivity;
+  u8_t mprio;
+
+  mprio = LWIP_MIN(TCP_PRIO_MAX, prio);
+
+  /* We want to kill connections with a lower prio, so bail out if 
+   * supplied prio is 0 - there can never be a lower prio
+   */
+  if (mprio == 0) {
+    return;
+  }
+
+  /* We only want kill connections with a lower prio, so decrement prio by one 
+   * and start searching for oldest connection with same or lower priority than mprio.
+   * We want to find the connections with the lowest possible prio, and among
+   * these the one with the longest inactivity time.
+   */
+  mprio--;
+
+  inactivity = 0;
+  inactive = NULL;
+  for (pcb = tcp_active_pcbs; pcb != NULL; pcb = pcb->next) {
+        /* lower prio is always a kill candidate */
+    if ((pcb->prio < mprio) ||
+        /* longer inactivity is also a kill candidate */
+        ((pcb->prio == mprio) && ((u32_t)(tcp_ticks - pcb->tmr) >= inactivity))) {
+      inactivity = tcp_ticks - pcb->tmr;
+      inactive   = pcb;
+      mprio      = pcb->prio;
+    }
+  }
+  if (inactive != NULL) {
+    LWIP_DEBUGF(TCP_DEBUG, ("tcp_kill_prio: killing oldest PCB %p (%"S32_F")\n",
+                            (void *)inactive, inactivity));
+    tcp_abort(inactive);
+  }
+}
+
+/**
+ * Kills the oldest connection that is in specific state.
+ * Called from tcp_alloc() for LAST_ACK and CLOSING if no more connections are available.
+ */
+static void
+tcp_kill_state(enum tcp_state state)
+{
+  struct tcp_pcb *pcb, *inactive;
+  u32_t inactivity;
+
+  LWIP_ASSERT("invalid state", (state == CLOSING) || (state == LAST_ACK));
+
+  inactivity = 0;
+  inactive = NULL;
+  /* Go through the list of active pcbs and get the oldest pcb that is in state
+     CLOSING/LAST_ACK. */
+  for (pcb = tcp_active_pcbs; pcb != NULL; pcb = pcb->next) {
+    if (pcb->state == state) {
+      if ((u32_t)(tcp_ticks - pcb->tmr) >= inactivity) {
+        inactivity = tcp_ticks - pcb->tmr;
+        inactive = pcb;
+      }
+    }
+  }
+  if (inactive != NULL) {
+    LWIP_DEBUGF(TCP_DEBUG, ("tcp_kill_closing: killing oldest %s PCB %p (%"S32_F")\n",
+                            tcp_state_str[state], (void *)inactive, inactivity));
+    /* Don't send a RST, since no data is lost. */
+    tcp_abandon(inactive, 0);
+  }
+}
+
+/**
+ * Kills the oldest connection that is in TIME_WAIT state.
+ * Called from tcp_alloc() if no more connections are available.
+ */
+static void
+tcp_kill_timewait(void)
+{
+  struct tcp_pcb *pcb, *inactive;
+  u32_t inactivity;
+
+  inactivity = 0;
+  inactive = NULL;
+  /* Go through the list of TIME_WAIT pcbs and get the oldest pcb. */
+  for (pcb = tcp_tw_pcbs; pcb != NULL; pcb = pcb->next) {
+    if ((u32_t)(tcp_ticks - pcb->tmr) >= inactivity) {
+      inactivity = tcp_ticks - pcb->tmr;
+      inactive = pcb;
+    }
+  }
+  if (inactive != NULL) {
+    LWIP_DEBUGF(TCP_DEBUG, ("tcp_kill_timewait: killing oldest TIME-WAIT PCB %p (%"S32_F")\n",
+                            (void *)inactive, inactivity));
+    tcp_abort(inactive);
+  }
+}
+
+/* Called when allocating a pcb fails.
+ * In this case, we want to handle all pcbs that want to close first: if we can
+ * now send the FIN (which failed before), the pcb might be in a state that is
+ * OK for us to now free it.
+ */
+static void
+tcp_handle_closepend(void)
+{
+  struct tcp_pcb *pcb = tcp_active_pcbs;
+
+  while (pcb != NULL) {
+    struct tcp_pcb *next = pcb->next;
+    /* send pending FIN */
+    if (pcb->flags & TF_CLOSEPEND) {
+      LWIP_DEBUGF(TCP_DEBUG, ("tcp_handle_closepend: pending FIN\n"));
+      tcp_clear_flags(pcb, TF_CLOSEPEND);
+      tcp_close_shutdown_fin(pcb);
+    }
+    pcb = next;
+  }
+}
+
+/**
+ * Allocate a new tcp_pcb structure.
+ *
+ * @param prio priority for the new pcb
+ * @return a new tcp_pcb that initially is in state CLOSED
+ */
+struct tcp_pcb *
+tcp_alloc(u8_t prio)
+{
+  struct tcp_pcb *pcb;
+
+  LWIP_ASSERT_CORE_LOCKED();
+
+  pcb = (struct tcp_pcb *)memp_malloc(MEMP_TCP_PCB);
+  if (pcb == NULL) {
+    /* Try to send FIN for all pcbs stuck in TF_CLOSEPEND first */
+    tcp_handle_closepend();
+
+    /* Try killing oldest connection in TIME-WAIT. */
+    LWIP_DEBUGF(TCP_DEBUG, ("tcp_alloc: killing off oldest TIME-WAIT connection\n"));
+    tcp_kill_timewait();
+    /* Try to allocate a tcp_pcb again. */
+    pcb = (struct tcp_pcb *)memp_malloc(MEMP_TCP_PCB);
+    if (pcb == NULL) {
+      /* Try killing oldest connection in LAST-ACK (these wouldn't go to TIME-WAIT). */
+      LWIP_DEBUGF(TCP_DEBUG, ("tcp_alloc: killing off oldest LAST-ACK connection\n"));
+      tcp_kill_state(LAST_ACK);
+      /* Try to allocate a tcp_pcb again. */
+      pcb = (struct tcp_pcb *)memp_malloc(MEMP_TCP_PCB);
+      if (pcb == NULL) {
+        /* Try killing oldest connection in CLOSING. */
+        LWIP_DEBUGF(TCP_DEBUG, ("tcp_alloc: killing off oldest CLOSING connection\n"));
+        tcp_kill_state(CLOSING);
+        /* Try to allocate a tcp_pcb again. */
+        pcb = (struct tcp_pcb *)memp_malloc(MEMP_TCP_PCB);
+        if (pcb == NULL) {
+          /* Try killing oldest active connection with lower priority than the new one. */
+          LWIP_DEBUGF(TCP_DEBUG, ("tcp_alloc: killing oldest connection with prio lower than %d\n", prio));
+          tcp_kill_prio(prio);
+          /* Try to allocate a tcp_pcb again. */
+          pcb = (struct tcp_pcb *)memp_malloc(MEMP_TCP_PCB);
+          if (pcb != NULL) {
+            /* adjust err stats: memp_malloc failed multiple times before */
+            MEMP_STATS_DEC(err, MEMP_TCP_PCB);
+          }
+        }
+        if (pcb != NULL) {
+          /* adjust err stats: memp_malloc failed multiple times before */
+          MEMP_STATS_DEC(err, MEMP_TCP_PCB);
+        }
+      }
+      if (pcb != NULL) {
+        /* adjust err stats: memp_malloc failed multiple times before */
+        MEMP_STATS_DEC(err, MEMP_TCP_PCB);
+      }
+    }
+    if (pcb != NULL) {
+      /* adjust err stats: memp_malloc failed above */
+      MEMP_STATS_DEC(err, MEMP_TCP_PCB);
+    }
+  }
+  if (pcb != NULL) {
+    /* zero out the whole pcb, so there is no need to initialize members to zero */
+    memset(pcb, 0, sizeof(struct tcp_pcb));
+    pcb->prio = prio;
+    pcb->snd_buf = TCP_SND_BUF;
+    /* Start with a window that does not need scaling. When window scaling is
+       enabled and used, the window is enlarged when both sides agree on scaling. */
+    pcb->rcv_wnd = pcb->rcv_ann_wnd = TCPWND_MIN16(TCP_WND);
+    pcb->ttl = TCP_TTL;
+    /* As initial send MSS, we use TCP_MSS but limit it to 536.
+       The send MSS is updated when an MSS option is received. */
+    pcb->mss = INITIAL_MSS;
+    pcb->rto = 3000 / TCP_SLOW_INTERVAL;
+    pcb->sv = 3000 / TCP_SLOW_INTERVAL;
+    pcb->rtime = -1;
+    pcb->cwnd = 1;
+    pcb->tmr = tcp_ticks;
+    pcb->last_timer = tcp_timer_ctr;
+
+    /* RFC 5681 recommends setting ssthresh abritrarily high and gives an example
+    of using the largest advertised receive window.  We've seen complications with
+    receiving TCPs that use window scaling and/or window auto-tuning where the
+    initial advertised window is very small and then grows rapidly once the
+    connection is established. To avoid these complications, we set ssthresh to the
+    largest effective cwnd (amount of in-flight data) that the sender can have. */
+    pcb->ssthresh = TCP_SND_BUF;
+
+#if LWIP_CALLBACK_API
+    pcb->recv = tcp_recv_null;
+#endif /* LWIP_CALLBACK_API */
+
+    /* Init KEEPALIVE timer */
+    pcb->keep_idle  = TCP_KEEPIDLE_DEFAULT;
+
+#if LWIP_TCP_KEEPALIVE
+    pcb->keep_intvl = TCP_KEEPINTVL_DEFAULT;
+    pcb->keep_cnt   = TCP_KEEPCNT_DEFAULT;
+#endif /* LWIP_TCP_KEEPALIVE */
+  }
+  return pcb;
+}
+
+/**
+ * @ingroup tcp_raw
+ * Creates a new TCP protocol control block but doesn't place it on
+ * any of the TCP PCB lists.
+ * The pcb is not put on any list until binding using tcp_bind().
+ * If memory is not available for creating the new pcb, NULL is returned.
+ *
+ * @internal: Maybe there should be a idle TCP PCB list where these
+ * PCBs are put on. Port reservation using tcp_bind() is implemented but
+ * allocated pcbs that are not bound can't be killed automatically if wanting
+ * to allocate a pcb with higher prio (@see tcp_kill_prio())
+ *
+ * @return a new tcp_pcb that initially is in state CLOSED
+ */
+struct tcp_pcb *
+tcp_new(void)
+{
+  return tcp_alloc(TCP_PRIO_NORMAL);
+}
+
+/**
+ * @ingroup tcp_raw
+ * Creates a new TCP protocol control block but doesn't
+ * place it on any of the TCP PCB lists.
+ * The pcb is not put on any list until binding using tcp_bind().
+ *
+ * @param type IP address type, see @ref lwip_ip_addr_type definitions.
+ * If you want to listen to IPv4 and IPv6 (dual-stack) connections,
+ * supply @ref IPADDR_TYPE_ANY as argument and bind to @ref IP_ANY_TYPE.
+ * @return a new tcp_pcb that initially is in state CLOSED
+ */
+struct tcp_pcb *
+tcp_new_ip_type(u8_t type)
+{
+  struct tcp_pcb *pcb;
+  pcb = tcp_alloc(TCP_PRIO_NORMAL);
+#if LWIP_IPV4 && LWIP_IPV6
+  if (pcb != NULL) {
+    IP_SET_TYPE_VAL(pcb->local_ip, type);
+    IP_SET_TYPE_VAL(pcb->remote_ip, type);
+  }
+#else
+  LWIP_UNUSED_ARG(type);
+#endif /* LWIP_IPV4 && LWIP_IPV6 */
+  return pcb;
+}
+
+/**
+ * @ingroup tcp_raw
+ * Specifies the program specific state that should be passed to all
+ * other callback functions. The "pcb" argument is the current TCP
+ * connection control block, and the "arg" argument is the argument
+ * that will be passed to the callbacks.
+ *
+ * @param pcb tcp_pcb to set the callback argument
+ * @param arg void pointer argument to pass to callback functions
+ */
+void
+tcp_arg(struct tcp_pcb *pcb, void *arg)
+{
+  LWIP_ASSERT_CORE_LOCKED();
+  /* This function is allowed to be called for both listen pcbs and
+     connection pcbs. */
+  if (pcb != NULL) {
+    pcb->callback_arg = arg;
+  }
+}
+#if LWIP_CALLBACK_API
+
+/**
+ * @ingroup tcp_raw
+ * Sets the callback function that will be called when new data
+ * arrives. The callback function will be passed a NULL pbuf to
+ * indicate that the remote host has closed the connection. If the
+ * callback function returns ERR_OK or ERR_ABRT it must have
+ * freed the pbuf, otherwise it must not have freed it.
+ *
+ * @param pcb tcp_pcb to set the recv callback
+ * @param recv callback function to call for this pcb when data is received
+ */
+void
+tcp_recv(struct tcp_pcb *pcb, tcp_recv_fn recv)
+{
+  LWIP_ASSERT_CORE_LOCKED();
+  if (pcb != NULL) {
+    LWIP_ASSERT("invalid socket state for recv callback", pcb->state != LISTEN);
+    pcb->recv = recv;
+  }
+}
+
+/**
+ * @ingroup tcp_raw
+ * Specifies the callback function that should be called when data has
+ * successfully been received (i.e., acknowledged) by the remote
+ * host. The len argument passed to the callback function gives the
+ * amount bytes that was acknowledged by the last acknowledgment.
+ *
+ * @param pcb tcp_pcb to set the sent callback
+ * @param sent callback function to call for this pcb when data is successfully sent
+ */
+void
+tcp_sent(struct tcp_pcb *pcb, tcp_sent_fn sent)
+{
+  LWIP_ASSERT_CORE_LOCKED();
+  if (pcb != NULL) {
+    LWIP_ASSERT("invalid socket state for sent callback", pcb->state != LISTEN);
+    pcb->sent = sent;
+  }
+}
+
+/**
+ * @ingroup tcp_raw
+ * Used to specify the function that should be called when a fatal error
+ * has occurred on the connection.
+ * 
+ * If a connection is aborted because of an error, the application is
+ * alerted of this event by the err callback. Errors that might abort a
+ * connection are when there is a shortage of memory. The callback
+ * function to be called is set using the tcp_err() function.
+ *
+ * @note The corresponding pcb is already freed when this callback is called!
+ *
+ * @param pcb tcp_pcb to set the err callback
+ * @param err callback function to call for this pcb when a fatal error
+ *        has occurred on the connection
+ */
+void
+tcp_err(struct tcp_pcb *pcb, tcp_err_fn err)
+{
+  LWIP_ASSERT_CORE_LOCKED();
+  if (pcb != NULL) {
+    LWIP_ASSERT("invalid socket state for err callback", pcb->state != LISTEN);
+    pcb->errf = err;
+  }
+}
+
+/**
+ * @ingroup tcp_raw
+ * Used for specifying the function that should be called when a
+ * LISTENing connection has been connected to another host.
+ *
+ * @param pcb tcp_pcb to set the accept callback
+ * @param accept callback function to call for this pcb when LISTENing
+ *        connection has been connected to another host
+ */
+void
+tcp_accept(struct tcp_pcb *pcb, tcp_accept_fn accept)
+{
+  LWIP_ASSERT_CORE_LOCKED();
+  if ((pcb != NULL) && (pcb->state == LISTEN)) {
+    struct tcp_pcb_listen *lpcb = (struct tcp_pcb_listen *)pcb;
+    lpcb->accept = accept;
+  }
+}
+#endif /* LWIP_CALLBACK_API */
+
+
+/**
+ * @ingroup tcp_raw
+ * Specifies the polling interval and the callback function that should
+ * be called to poll the application. The interval is specified in
+ * number of TCP coarse grained timer shots, which typically occurs
+ * twice a second. An interval of 10 means that the application would
+ * be polled every 5 seconds.
+ * 
+ * When a connection is idle (i.e., no data is either transmitted or
+ * received), lwIP will repeatedly poll the application by calling a
+ * specified callback function. This can be used either as a watchdog
+ * timer for killing connections that have stayed idle for too long, or
+ * as a method of waiting for memory to become available. For instance,
+ * if a call to tcp_write() has failed because memory wasn't available,
+ * the application may use the polling functionality to call tcp_write()
+ * again when the connection has been idle for a while.
+ */
+void
+tcp_poll(struct tcp_pcb *pcb, tcp_poll_fn poll, u8_t interval)
+{
+  LWIP_ASSERT_CORE_LOCKED();
+
+  LWIP_ERROR("tcp_poll: invalid pcb", pcb != NULL, return);
+  LWIP_ASSERT("invalid socket state for poll", pcb->state != LISTEN);
+
+#if LWIP_CALLBACK_API
+  pcb->poll = poll;
+#else /* LWIP_CALLBACK_API */
+  LWIP_UNUSED_ARG(poll);
+#endif /* LWIP_CALLBACK_API */
+  pcb->pollinterval = interval;
+}
+
+/**
+ * Purges a TCP PCB. Removes any buffered data and frees the buffer memory
+ * (pcb->ooseq, pcb->unsent and pcb->unacked are freed).
+ *
+ * @param pcb tcp_pcb to purge. The pcb itself is not deallocated!
+ */
+void
+tcp_pcb_purge(struct tcp_pcb *pcb)
+{
+  LWIP_ERROR("tcp_pcb_purge: invalid pcb", pcb != NULL, return);
+
+  if (pcb->state != CLOSED &&
+      pcb->state != TIME_WAIT &&
+      pcb->state != LISTEN) {
+
+    LWIP_DEBUGF(TCP_DEBUG, ("tcp_pcb_purge\n"));
+
+    tcp_backlog_accepted(pcb);
+
+    if (pcb->refused_data != NULL) {
+      LWIP_DEBUGF(TCP_DEBUG, ("tcp_pcb_purge: data left on ->refused_data\n"));
+      pbuf_free(pcb->refused_data);
+      pcb->refused_data = NULL;
+    }
+    if (pcb->unsent != NULL) {
+      LWIP_DEBUGF(TCP_DEBUG, ("tcp_pcb_purge: not all data sent\n"));
+    }
+    if (pcb->unacked != NULL) {
+      LWIP_DEBUGF(TCP_DEBUG, ("tcp_pcb_purge: data left on ->unacked\n"));
+    }
+#if TCP_QUEUE_OOSEQ
+    if (pcb->ooseq != NULL) {
+      LWIP_DEBUGF(TCP_DEBUG, ("tcp_pcb_purge: data left on ->ooseq\n"));
+      tcp_free_ooseq(pcb);
+    }
+#endif /* TCP_QUEUE_OOSEQ */
+
+    /* Stop the retransmission timer as it will expect data on unacked
+       queue if it fires */
+    pcb->rtime = -1;
+
+    tcp_segs_free(pcb->unsent);
+    tcp_segs_free(pcb->unacked);
+    pcb->unacked = pcb->unsent = NULL;
+#if TCP_OVERSIZE
+    pcb->unsent_oversize = 0;
+#endif /* TCP_OVERSIZE */
+  }
+}
+
+/**
+ * Purges the PCB and removes it from a PCB list. Any delayed ACKs are sent first.
+ *
+ * @param pcblist PCB list to purge.
+ * @param pcb tcp_pcb to purge. The pcb itself is NOT deallocated!
+ */
+void
+tcp_pcb_remove(struct tcp_pcb **pcblist, struct tcp_pcb *pcb)
+{
+  LWIP_ASSERT("tcp_pcb_remove: invalid pcb", pcb != NULL);
+  LWIP_ASSERT("tcp_pcb_remove: invalid pcblist", pcblist != NULL);
+
+  TCP_RMV(pcblist, pcb);
+
+  tcp_pcb_purge(pcb);
+
+  /* if there is an outstanding delayed ACKs, send it */
+  if ((pcb->state != TIME_WAIT) &&
+      (pcb->state != LISTEN) &&
+      (pcb->flags & TF_ACK_DELAY)) {
+    tcp_ack_now(pcb);
+    tcp_output(pcb);
+  }
+
+  if (pcb->state != LISTEN) {
+    LWIP_ASSERT("unsent segments leaking", pcb->unsent == NULL);
+    LWIP_ASSERT("unacked segments leaking", pcb->unacked == NULL);
+#if TCP_QUEUE_OOSEQ
+    LWIP_ASSERT("ooseq segments leaking", pcb->ooseq == NULL);
+#endif /* TCP_QUEUE_OOSEQ */
+  }
+
+  pcb->state = CLOSED;
+  /* reset the local port to prevent the pcb from being 'bound' */
+  pcb->local_port = 0;
+
+  LWIP_ASSERT("tcp_pcb_remove: tcp_pcbs_sane()", tcp_pcbs_sane());
+}
+
+/**
+ * Calculates a new initial sequence number for new connections.
+ *
+ * @return u32_t pseudo random sequence number
+ */
+u32_t
+tcp_next_iss(struct tcp_pcb *pcb)
+{
+#ifdef LWIP_HOOK_TCP_ISN
+  LWIP_ASSERT("tcp_next_iss: invalid pcb", pcb != NULL);
+  return LWIP_HOOK_TCP_ISN(&pcb->local_ip, pcb->local_port, &pcb->remote_ip, pcb->remote_port);
+#else /* LWIP_HOOK_TCP_ISN */
+  static u32_t iss = 6510;
+
+  LWIP_ASSERT("tcp_next_iss: invalid pcb", pcb != NULL);
+  LWIP_UNUSED_ARG(pcb);
+
+  iss += tcp_ticks;       /* XXX */
+  return iss;
+#endif /* LWIP_HOOK_TCP_ISN */
+}
+
+#if TCP_CALCULATE_EFF_SEND_MSS
+/**
+ * Calculates the effective send mss that can be used for a specific IP address
+ * by calculating the minimum of TCP_MSS and the mtu (if set) of the target
+ * netif (if not NULL).
+ */
+u16_t
+tcp_eff_send_mss_netif(u16_t sendmss, struct netif *outif, const ip_addr_t *dest)
+{
+  u16_t mss_s;
+  u16_t mtu;
+
+  LWIP_UNUSED_ARG(dest); /* in case IPv6 is disabled */
+
+  LWIP_ASSERT("tcp_eff_send_mss_netif: invalid dst_ip", dest != NULL);
+
+#if LWIP_IPV6
+#if LWIP_IPV4
+  if (IP_IS_V6(dest))
+#endif /* LWIP_IPV4 */
+  {
+    /* First look in destination cache, to see if there is a Path MTU. */
+    mtu = nd6_get_destination_mtu(ip_2_ip6(dest), outif);
+  }
+#if LWIP_IPV4
+  else
+#endif /* LWIP_IPV4 */
+#endif /* LWIP_IPV6 */
+#if LWIP_IPV4
+  {
+    if (outif == NULL) {
+      return sendmss;
+    }
+    mtu = outif->mtu;
+  }
+#endif /* LWIP_IPV4 */
+
+  if (mtu != 0) {
+    u16_t offset;
+#if LWIP_IPV6
+#if LWIP_IPV4
+    if (IP_IS_V6(dest))
+#endif /* LWIP_IPV4 */
+    {
+      offset = IP6_HLEN + TCP_HLEN;
+    }
+#if LWIP_IPV4
+    else
+#endif /* LWIP_IPV4 */
+#endif /* LWIP_IPV6 */
+#if LWIP_IPV4
+    {
+      offset = IP_HLEN + TCP_HLEN;
+    }
+#endif /* LWIP_IPV4 */
+    mss_s = (mtu > offset) ? (u16_t)(mtu - offset) : 0;
+    /* RFC 1122, chap 4.2.2.6:
+     * Eff.snd.MSS = min(SendMSS+20, MMS_S) - TCPhdrsize - IPoptionsize
+     * We correct for TCP options in tcp_write(), and don't support IP options.
+     */
+    sendmss = LWIP_MIN(sendmss, mss_s);
+  }
+  return sendmss;
+}
+#endif /* TCP_CALCULATE_EFF_SEND_MSS */
+
+/** Helper function for tcp_netif_ip_addr_changed() that iterates a pcb list */
+static void
+tcp_netif_ip_addr_changed_pcblist(const ip_addr_t *old_addr, struct tcp_pcb *pcb_list)
+{
+  struct tcp_pcb *pcb;
+  pcb = pcb_list;
+
+  LWIP_ASSERT("tcp_netif_ip_addr_changed_pcblist: invalid old_addr", old_addr != NULL);
+
+  while (pcb != NULL) {
+    /* PCB bound to current local interface address? */
+    if (ip_addr_cmp(&pcb->local_ip, old_addr)
+#if LWIP_AUTOIP
+        /* connections to link-local addresses must persist (RFC3927 ch. 1.9) */
+        && (!IP_IS_V4_VAL(pcb->local_ip) || !ip4_addr_islinklocal(ip_2_ip4(&pcb->local_ip)))
+#endif /* LWIP_AUTOIP */
+       ) {
+      /* this connection must be aborted */
+      struct tcp_pcb *next = pcb->next;
+      LWIP_DEBUGF(NETIF_DEBUG | LWIP_DBG_STATE, ("netif_set_ipaddr: aborting TCP pcb %p\n", (void *)pcb));
+      tcp_abort(pcb);
+      pcb = next;
+    } else {
+      pcb = pcb->next;
+    }
+  }
+}
+
+/** This function is called from netif.c when address is changed or netif is removed
+ *
+ * @param old_addr IP address of the netif before change
+ * @param new_addr IP address of the netif after change or NULL if netif has been removed
+ */
+void
+tcp_netif_ip_addr_changed(const ip_addr_t *old_addr, const ip_addr_t *new_addr)
+{
+  struct tcp_pcb_listen *lpcb;
+
+  if (!ip_addr_isany(old_addr)) {
+    tcp_netif_ip_addr_changed_pcblist(old_addr, tcp_active_pcbs);
+    tcp_netif_ip_addr_changed_pcblist(old_addr, tcp_bound_pcbs);
+
+    if (!ip_addr_isany(new_addr)) {
+      /* PCB bound to current local interface address? */
+      for (lpcb = tcp_listen_pcbs.listen_pcbs; lpcb != NULL; lpcb = lpcb->next) {
+        /* PCB bound to current local interface address? */
+        if (ip_addr_cmp(&lpcb->local_ip, old_addr)) {
+          /* The PCB is listening to the old ipaddr and
+            * is set to listen to the new one instead */
+          ip_addr_copy(lpcb->local_ip, *new_addr);
+        }
+      }
+    }
+  }
+}
+
+const char *
+tcp_debug_state_str(enum tcp_state s)
+{
+  return tcp_state_str[s];
+}
+
+err_t
+tcp_tcp_get_tcp_addrinfo(struct tcp_pcb *pcb, int local, ip_addr_t *addr, u16_t *port)
+{
+  if (pcb) {
+    if (local) {
+      if (addr) {
+        *addr = pcb->local_ip;
+      }
+      if (port) {
+        *port = pcb->local_port;
+      }
+    } else {
+      if (addr) {
+        *addr = pcb->remote_ip;
+      }
+      if (port) {
+        *port = pcb->remote_port;
+      }
+    }
+    return ERR_OK;
+  }
+  return ERR_VAL;
+}
+
+#if TCP_QUEUE_OOSEQ
+/* Free all ooseq pbufs (and possibly reset SACK state) */
+void
+tcp_free_ooseq(struct tcp_pcb *pcb)
+{
+  if (pcb->ooseq) {
+    tcp_segs_free(pcb->ooseq);
+    pcb->ooseq = NULL;
+#if LWIP_TCP_SACK_OUT
+    memset(pcb->rcv_sacks, 0, sizeof(pcb->rcv_sacks));
+#endif /* LWIP_TCP_SACK_OUT */
+  }
+}
+#endif /* TCP_QUEUE_OOSEQ */
+
+#if TCP_DEBUG || TCP_INPUT_DEBUG || TCP_OUTPUT_DEBUG
+/**
+ * Print a tcp header for debugging purposes.
+ *
+ * @param tcphdr pointer to a struct tcp_hdr
+ */
+void
+tcp_debug_print(struct tcp_hdr *tcphdr)
+{
+  LWIP_DEBUGF(TCP_DEBUG, ("TCP header:\n"));
+  LWIP_DEBUGF(TCP_DEBUG, ("+-------------------------------+\n"));
+  LWIP_DEBUGF(TCP_DEBUG, ("|    %5"U16_F"      |    %5"U16_F"      | (src port, dest port)\n",
+                          lwip_ntohs(tcphdr->src), lwip_ntohs(tcphdr->dest)));
+  LWIP_DEBUGF(TCP_DEBUG, ("+-------------------------------+\n"));
+  LWIP_DEBUGF(TCP_DEBUG, ("|           %010"U32_F"          | (seq no)\n",
+                          lwip_ntohl(tcphdr->seqno)));
+  LWIP_DEBUGF(TCP_DEBUG, ("+-------------------------------+\n"));
+  LWIP_DEBUGF(TCP_DEBUG, ("|           %010"U32_F"          | (ack no)\n",
+                          lwip_ntohl(tcphdr->ackno)));
+  LWIP_DEBUGF(TCP_DEBUG, ("+-------------------------------+\n"));
+  LWIP_DEBUGF(TCP_DEBUG, ("| %2"U16_F" |   |%"U16_F"%"U16_F"%"U16_F"%"U16_F"%"U16_F"%"U16_F"|     %5"U16_F"     | (hdrlen, flags (",
+                          TCPH_HDRLEN(tcphdr),
+                          (u16_t)(TCPH_FLAGS(tcphdr) >> 5 & 1),
+                          (u16_t)(TCPH_FLAGS(tcphdr) >> 4 & 1),
+                          (u16_t)(TCPH_FLAGS(tcphdr) >> 3 & 1),
+                          (u16_t)(TCPH_FLAGS(tcphdr) >> 2 & 1),
+                          (u16_t)(TCPH_FLAGS(tcphdr) >> 1 & 1),
+                          (u16_t)(TCPH_FLAGS(tcphdr)      & 1),
+                          lwip_ntohs(tcphdr->wnd)));
+  tcp_debug_print_flags(TCPH_FLAGS(tcphdr));
+  LWIP_DEBUGF(TCP_DEBUG, ("), win)\n"));
+  LWIP_DEBUGF(TCP_DEBUG, ("+-------------------------------+\n"));
+  LWIP_DEBUGF(TCP_DEBUG, ("|    0x%04"X16_F"     |     %5"U16_F"     | (chksum, urgp)\n",
+                          lwip_ntohs(tcphdr->chksum), lwip_ntohs(tcphdr->urgp)));
+  LWIP_DEBUGF(TCP_DEBUG, ("+-------------------------------+\n"));
+}
+
+/**
+ * Print a tcp state for debugging purposes.
+ *
+ * @param s enum tcp_state to print
+ */
+void
+tcp_debug_print_state(enum tcp_state s)
+{
+  LWIP_DEBUGF(TCP_DEBUG, ("State: %s\n", tcp_state_str[s]));
+}
+
+/**
+ * Print tcp flags for debugging purposes.
+ *
+ * @param flags tcp flags, all active flags are printed
+ */
+void
+tcp_debug_print_flags(u8_t flags)
+{
+  if (flags & TCP_FIN) {
+    LWIP_DEBUGF(TCP_DEBUG, ("FIN "));
+  }
+  if (flags & TCP_SYN) {
+    LWIP_DEBUGF(TCP_DEBUG, ("SYN "));
+  }
+  if (flags & TCP_RST) {
+    LWIP_DEBUGF(TCP_DEBUG, ("RST "));
+  }
+  if (flags & TCP_PSH) {
+    LWIP_DEBUGF(TCP_DEBUG, ("PSH "));
+  }
+  if (flags & TCP_ACK) {
+    LWIP_DEBUGF(TCP_DEBUG, ("ACK "));
+  }
+  if (flags & TCP_URG) {
+    LWIP_DEBUGF(TCP_DEBUG, ("URG "));
+  }
+  if (flags & TCP_ECE) {
+    LWIP_DEBUGF(TCP_DEBUG, ("ECE "));
+  }
+  if (flags & TCP_CWR) {
+    LWIP_DEBUGF(TCP_DEBUG, ("CWR "));
+  }
+  LWIP_DEBUGF(TCP_DEBUG, ("\n"));
+}
+
+/**
+ * Print all tcp_pcbs in every list for debugging purposes.
+ */
+void
+tcp_debug_print_pcbs(void)
+{
+  struct tcp_pcb *pcb;
+  struct tcp_pcb_listen *pcbl;
+
+  LWIP_DEBUGF(TCP_DEBUG, ("Active PCB states:\n"));
+  for (pcb = tcp_active_pcbs; pcb != NULL; pcb = pcb->next) {
+    LWIP_DEBUGF(TCP_DEBUG, ("Local port %"U16_F", foreign port %"U16_F" snd_nxt %"U32_F" rcv_nxt %"U32_F" ",
+                            pcb->local_port, pcb->remote_port,
+                            pcb->snd_nxt, pcb->rcv_nxt));
+    tcp_debug_print_state(pcb->state);
+  }
+
+  LWIP_DEBUGF(TCP_DEBUG, ("Listen PCB states:\n"));
+  for (pcbl = tcp_listen_pcbs.listen_pcbs; pcbl != NULL; pcbl = pcbl->next) {
+    LWIP_DEBUGF(TCP_DEBUG, ("Local port %"U16_F" ", pcbl->local_port));
+    tcp_debug_print_state(pcbl->state);
+  }
+
+  LWIP_DEBUGF(TCP_DEBUG, ("TIME-WAIT PCB states:\n"));
+  for (pcb = tcp_tw_pcbs; pcb != NULL; pcb = pcb->next) {
+    LWIP_DEBUGF(TCP_DEBUG, ("Local port %"U16_F", foreign port %"U16_F" snd_nxt %"U32_F" rcv_nxt %"U32_F" ",
+                            pcb->local_port, pcb->remote_port,
+                            pcb->snd_nxt, pcb->rcv_nxt));
+    tcp_debug_print_state(pcb->state);
+  }
+}
+
+/**
+ * Check state consistency of the tcp_pcb lists.
+ */
+s16_t
+tcp_pcbs_sane(void)
+{
+  struct tcp_pcb *pcb;
+  for (pcb = tcp_active_pcbs; pcb != NULL; pcb = pcb->next) {
+    LWIP_ASSERT("tcp_pcbs_sane: active pcb->state != CLOSED", pcb->state != CLOSED);
+    LWIP_ASSERT("tcp_pcbs_sane: active pcb->state != LISTEN", pcb->state != LISTEN);
+    LWIP_ASSERT("tcp_pcbs_sane: active pcb->state != TIME-WAIT", pcb->state != TIME_WAIT);
+  }
+  for (pcb = tcp_tw_pcbs; pcb != NULL; pcb = pcb->next) {
+    LWIP_ASSERT("tcp_pcbs_sane: tw pcb->state == TIME-WAIT", pcb->state == TIME_WAIT);
+  }
+  return 1;
+}
+#endif /* TCP_DEBUG */
+
+#if LWIP_TCP_PCB_NUM_EXT_ARGS
+/**
+ * @defgroup tcp_raw_extargs ext arguments
+ * @ingroup tcp_raw
+ * Additional data storage per tcp pcb\n
+ * @see @ref tcp_raw
+ *
+ * When LWIP_TCP_PCB_NUM_EXT_ARGS is > 0, every tcp pcb (including listen pcb)
+ * includes a number of additional argument entries in an array.
+ *
+ * To support memory management, in addition to a 'void *', callbacks can be
+ * provided to manage transition from listening pcbs to connections and to
+ * deallocate memory when a pcb is deallocated (see struct @ref tcp_ext_arg_callbacks).
+ *
+ * After allocating this index, use @ref tcp_ext_arg_set and @ref tcp_ext_arg_get
+ * to store and load arguments from this index for a given pcb.
+ */
+
+static u8_t tcp_ext_arg_id;
+
+/**
+ * @ingroup tcp_raw_extargs
+ * Allocate an index to store data in ext_args member of struct tcp_pcb.
+ * Returned value is an index in mentioned array.
+ * The index is *global* over all pcbs!
+ *
+ * When @ref LWIP_TCP_PCB_NUM_EXT_ARGS is > 0, every tcp pcb (including listen pcb)
+ * includes a number of additional argument entries in an array.
+ *
+ * To support memory management, in addition to a 'void *', callbacks can be
+ * provided to manage transition from listening pcbs to connections and to
+ * deallocate memory when a pcb is deallocated (see struct @ref tcp_ext_arg_callbacks).
+ *
+ * After allocating this index, use @ref tcp_ext_arg_set and @ref tcp_ext_arg_get
+ * to store and load arguments from this index for a given pcb.
+ *
+ * @return a unique index into struct tcp_pcb.ext_args
+ */
+u8_t
+tcp_ext_arg_alloc_id(void)
+{
+  u8_t result = tcp_ext_arg_id;
+  tcp_ext_arg_id++;
+
+  LWIP_ASSERT_CORE_LOCKED();
+
+#if LWIP_TCP_PCB_NUM_EXT_ARGS >= 255
+#error LWIP_TCP_PCB_NUM_EXT_ARGS
+#endif
+  LWIP_ASSERT("Increase LWIP_TCP_PCB_NUM_EXT_ARGS in lwipopts.h", result < LWIP_TCP_PCB_NUM_EXT_ARGS);
+  return result;
+}
+
+/**
+ * @ingroup tcp_raw_extargs
+ * Set callbacks for a given index of ext_args on the specified pcb.
+ *
+ * @param pcb tcp_pcb for which to set the callback
+ * @param id ext_args index to set (allocated via @ref tcp_ext_arg_alloc_id)
+ * @param callbacks callback table (const since it is referenced, not copied!)
+ */
+void
+tcp_ext_arg_set_callbacks(struct tcp_pcb *pcb, uint8_t id, const struct tcp_ext_arg_callbacks * const callbacks)
+{
+  LWIP_ASSERT("pcb != NULL", pcb != NULL);
+  LWIP_ASSERT("id < LWIP_TCP_PCB_NUM_EXT_ARGS", id < LWIP_TCP_PCB_NUM_EXT_ARGS);
+  LWIP_ASSERT("callbacks != NULL", callbacks != NULL);
+
+  LWIP_ASSERT_CORE_LOCKED();
+
+  pcb->ext_args[id].callbacks = callbacks;
+}
+
+/**
+ * @ingroup tcp_raw_extargs
+ * Set data for a given index of ext_args on the specified pcb.
+ *
+ * @param pcb tcp_pcb for which to set the data
+ * @param id ext_args index to set (allocated via @ref tcp_ext_arg_alloc_id)
+ * @param arg data pointer to set
+ */
+void tcp_ext_arg_set(struct tcp_pcb *pcb, uint8_t id, void *arg)
+{
+  LWIP_ASSERT("pcb != NULL", pcb != NULL);
+  LWIP_ASSERT("id < LWIP_TCP_PCB_NUM_EXT_ARGS", id < LWIP_TCP_PCB_NUM_EXT_ARGS);
+
+  LWIP_ASSERT_CORE_LOCKED();
+
+  pcb->ext_args[id].data = arg;
+}
+
+/**
+ * @ingroup tcp_raw_extargs
+ * Set data for a given index of ext_args on the specified pcb.
+ *
+ * @param pcb tcp_pcb for which to set the data
+ * @param id ext_args index to set (allocated via @ref tcp_ext_arg_alloc_id)
+ * @return data pointer at the given index
+ */
+void *tcp_ext_arg_get(const struct tcp_pcb *pcb, uint8_t id)
+{
+  LWIP_ASSERT("pcb != NULL", pcb != NULL);
+  LWIP_ASSERT("id < LWIP_TCP_PCB_NUM_EXT_ARGS", id < LWIP_TCP_PCB_NUM_EXT_ARGS);
+
+  LWIP_ASSERT_CORE_LOCKED();
+
+  return pcb->ext_args[id].data;
+}
+
+/** This function calls the "destroy" callback for all ext_args once a pcb is
+ * freed.
+ */
+static void
+tcp_ext_arg_invoke_callbacks_destroyed(struct tcp_pcb_ext_args *ext_args)
+{
+  int i;
+  LWIP_ASSERT("ext_args != NULL", ext_args != NULL);
+
+  for (i = 0; i < LWIP_TCP_PCB_NUM_EXT_ARGS; i++) {
+    if (ext_args[i].callbacks != NULL) {
+      if (ext_args[i].callbacks->destroy != NULL) {
+        ext_args[i].callbacks->destroy((u8_t)i, ext_args[i].data);
+      }
+    }
+  }
+}
+
+/** This function calls the "passive_open" callback for all ext_args if a connection
+ * is in the process of being accepted. This is called just after the SYN is
+ * received and before a SYN/ACK is sent, to allow to modify the very first
+ * segment sent even on passive open. Naturally, the "accepted" callback of the
+ * pcb has not been called yet!
+ */
+err_t
+tcp_ext_arg_invoke_callbacks_passive_open(struct tcp_pcb_listen *lpcb, struct tcp_pcb *cpcb)
+{
+  int i;
+  LWIP_ASSERT("lpcb != NULL", lpcb != NULL);
+  LWIP_ASSERT("cpcb != NULL", cpcb != NULL);
+
+  for (i = 0; i < LWIP_TCP_PCB_NUM_EXT_ARGS; i++) {
+    if (lpcb->ext_args[i].callbacks != NULL) {
+      if (lpcb->ext_args[i].callbacks->passive_open != NULL) {
+        err_t err = lpcb->ext_args[i].callbacks->passive_open((u8_t)i, lpcb, cpcb);
+        if (err != ERR_OK) {
+          return err;
+        }
+      }
+    }
+  }
+  return ERR_OK;
+}
+#endif /* LWIP_TCP_PCB_NUM_EXT_ARGS */
+
+#endif /* LWIP_TCP */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/core/tcp_in.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/core/tcp_in.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/core/tcp_in.c	(revision 457)
@@ -0,0 +1,2178 @@
+/**
+ * @file
+ * Transmission Control Protocol, incoming traffic
+ *
+ * The input processing functions of the TCP layer.
+ *
+ * These functions are generally called in the order (ip_input() ->)
+ * tcp_input() -> * tcp_process() -> tcp_receive() (-> application).
+ *
+ */
+
+/*
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Adam Dunkels <adam@sics.se>
+ *
+ */
+
+#include "lwip/opt.h"
+
+#if LWIP_TCP /* don't build if not configured for use in lwipopts.h */
+
+#include "lwip/priv/tcp_priv.h"
+#include "lwip/def.h"
+#include "lwip/ip_addr.h"
+#include "lwip/netif.h"
+#include "lwip/mem.h"
+#include "lwip/memp.h"
+#include "lwip/inet_chksum.h"
+#include "lwip/stats.h"
+#include "lwip/ip6.h"
+#include "lwip/ip6_addr.h"
+#if LWIP_ND6_TCP_REACHABILITY_HINTS
+#include "lwip/nd6.h"
+#endif /* LWIP_ND6_TCP_REACHABILITY_HINTS */
+
+#include <string.h>
+
+#ifdef LWIP_HOOK_FILENAME
+#include LWIP_HOOK_FILENAME
+#endif
+
+/** Initial CWND calculation as defined RFC 2581 */
+#define LWIP_TCP_CALC_INITIAL_CWND(mss) ((tcpwnd_size_t)LWIP_MIN((4U * (mss)), LWIP_MAX((2U * (mss)), 4380U)))
+
+/* These variables are global to all functions involved in the input
+   processing of TCP segments. They are set by the tcp_input()
+   function. */
+static struct tcp_seg inseg;
+static struct tcp_hdr *tcphdr;
+static u16_t tcphdr_optlen;
+static u16_t tcphdr_opt1len;
+static u8_t *tcphdr_opt2;
+static u16_t tcp_optidx;
+static u32_t seqno, ackno;
+static tcpwnd_size_t recv_acked;
+static u16_t tcplen;
+static u8_t flags;
+
+static u8_t recv_flags;
+static struct pbuf *recv_data;
+
+struct tcp_pcb *tcp_input_pcb;
+
+/* Forward declarations. */
+static err_t tcp_process(struct tcp_pcb *pcb);
+static void tcp_receive(struct tcp_pcb *pcb);
+static void tcp_parseopt(struct tcp_pcb *pcb);
+
+static void tcp_listen_input(struct tcp_pcb_listen *pcb);
+static void tcp_timewait_input(struct tcp_pcb *pcb);
+
+static int tcp_input_delayed_close(struct tcp_pcb *pcb);
+
+#if LWIP_TCP_SACK_OUT
+static void tcp_add_sack(struct tcp_pcb *pcb, u32_t left, u32_t right);
+static void tcp_remove_sacks_lt(struct tcp_pcb *pcb, u32_t seq);
+#if defined(TCP_OOSEQ_BYTES_LIMIT) || defined(TCP_OOSEQ_PBUFS_LIMIT)
+static void tcp_remove_sacks_gt(struct tcp_pcb *pcb, u32_t seq);
+#endif /* TCP_OOSEQ_BYTES_LIMIT || TCP_OOSEQ_PBUFS_LIMIT */
+#endif /* LWIP_TCP_SACK_OUT */
+
+/**
+ * The initial input processing of TCP. It verifies the TCP header, demultiplexes
+ * the segment between the PCBs and passes it on to tcp_process(), which implements
+ * the TCP finite state machine. This function is called by the IP layer (in
+ * ip_input()).
+ *
+ * @param p received TCP segment to process (p->payload pointing to the TCP header)
+ * @param inp network interface on which this segment was received
+ */
+void
+tcp_input(struct pbuf *p, struct netif *inp)
+{
+  struct tcp_pcb *pcb, *prev;
+  struct tcp_pcb_listen *lpcb;
+#if SO_REUSE
+  struct tcp_pcb *lpcb_prev = NULL;
+  struct tcp_pcb_listen *lpcb_any = NULL;
+#endif /* SO_REUSE */
+  u8_t hdrlen_bytes;
+  err_t err;
+
+  LWIP_UNUSED_ARG(inp);
+  LWIP_ASSERT_CORE_LOCKED();
+  LWIP_ASSERT("tcp_input: invalid pbuf", p != NULL);
+
+  PERF_START;
+
+  TCP_STATS_INC(tcp.recv);
+  MIB2_STATS_INC(mib2.tcpinsegs);
+
+  tcphdr = (struct tcp_hdr *)p->payload;
+
+#if TCP_INPUT_DEBUG
+  tcp_debug_print(tcphdr);
+#endif
+
+  /* Check that TCP header fits in payload */
+  if (p->len < TCP_HLEN) {
+    /* drop short packets */
+    LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: short packet (%"U16_F" bytes) discarded\n", p->tot_len));
+    TCP_STATS_INC(tcp.lenerr);
+    goto dropped;
+  }
+
+  /* Don't even process incoming broadcasts/multicasts. */
+  if (ip_addr_isbroadcast(ip_current_dest_addr(), ip_current_netif()) ||
+      ip_addr_ismulticast(ip_current_dest_addr())) {
+    TCP_STATS_INC(tcp.proterr);
+    goto dropped;
+  }
+
+#if CHECKSUM_CHECK_TCP
+  IF__NETIF_CHECKSUM_ENABLED(inp, NETIF_CHECKSUM_CHECK_TCP) {
+    /* Verify TCP checksum. */
+    u16_t chksum = ip_chksum_pseudo(p, IP_PROTO_TCP, p->tot_len,
+                                    ip_current_src_addr(), ip_current_dest_addr());
+    if (chksum != 0) {
+      LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: packet discarded due to failing checksum 0x%04"X16_F"\n",
+                                    chksum));
+      tcp_debug_print(tcphdr);
+      TCP_STATS_INC(tcp.chkerr);
+      goto dropped;
+    }
+  }
+#endif /* CHECKSUM_CHECK_TCP */
+
+  /* sanity-check header length */
+  hdrlen_bytes = TCPH_HDRLEN_BYTES(tcphdr);
+  if ((hdrlen_bytes < TCP_HLEN) || (hdrlen_bytes > p->tot_len)) {
+    LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: invalid header length (%"U16_F")\n", (u16_t)hdrlen_bytes));
+    TCP_STATS_INC(tcp.lenerr);
+    goto dropped;
+  }
+
+  /* Move the payload pointer in the pbuf so that it points to the
+     TCP data instead of the TCP header. */
+  tcphdr_optlen = (u16_t)(hdrlen_bytes - TCP_HLEN);
+  tcphdr_opt2 = NULL;
+  if (p->len >= hdrlen_bytes) {
+    /* all options are in the first pbuf */
+    tcphdr_opt1len = tcphdr_optlen;
+    pbuf_remove_header(p, hdrlen_bytes); /* cannot fail */
+  } else {
+    u16_t opt2len;
+    /* TCP header fits into first pbuf, options don't - data is in the next pbuf */
+    /* there must be a next pbuf, due to hdrlen_bytes sanity check above */
+    LWIP_ASSERT("p->next != NULL", p->next != NULL);
+
+    /* advance over the TCP header (cannot fail) */
+    pbuf_remove_header(p, TCP_HLEN);
+
+    /* determine how long the first and second parts of the options are */
+    tcphdr_opt1len = p->len;
+    opt2len = (u16_t)(tcphdr_optlen - tcphdr_opt1len);
+
+    /* options continue in the next pbuf: set p to zero length and hide the
+        options in the next pbuf (adjusting p->tot_len) */
+    pbuf_remove_header(p, tcphdr_opt1len);
+
+    /* check that the options fit in the second pbuf */
+    if (opt2len > p->next->len) {
+      /* drop short packets */
+      LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: options overflow second pbuf (%"U16_F" bytes)\n", p->next->len));
+      TCP_STATS_INC(tcp.lenerr);
+      goto dropped;
+    }
+
+    /* remember the pointer to the second part of the options */
+    tcphdr_opt2 = (u8_t *)p->next->payload;
+
+    /* advance p->next to point after the options, and manually
+        adjust p->tot_len to keep it consistent with the changed p->next */
+    pbuf_remove_header(p->next, opt2len);
+    p->tot_len = (u16_t)(p->tot_len - opt2len);
+
+    LWIP_ASSERT("p->len == 0", p->len == 0);
+    LWIP_ASSERT("p->tot_len == p->next->tot_len", p->tot_len == p->next->tot_len);
+  }
+
+  /* Convert fields in TCP header to host byte order. */
+  tcphdr->src = lwip_ntohs(tcphdr->src);
+  tcphdr->dest = lwip_ntohs(tcphdr->dest);
+  seqno = tcphdr->seqno = lwip_ntohl(tcphdr->seqno);
+  ackno = tcphdr->ackno = lwip_ntohl(tcphdr->ackno);
+  tcphdr->wnd = lwip_ntohs(tcphdr->wnd);
+
+  flags = TCPH_FLAGS(tcphdr);
+  tcplen = p->tot_len;
+  if (flags & (TCP_FIN | TCP_SYN)) {
+    tcplen++;
+    if (tcplen < p->tot_len) {
+      /* u16_t overflow, cannot handle this */
+      LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: length u16_t overflow, cannot handle this\n"));
+      TCP_STATS_INC(tcp.lenerr);
+      goto dropped;
+    }
+  }
+
+  /* Demultiplex an incoming segment. First, we check if it is destined
+     for an active connection. */
+  prev = NULL;
+
+  for (pcb = tcp_active_pcbs; pcb != NULL; pcb = pcb->next) {
+    LWIP_ASSERT("tcp_input: active pcb->state != CLOSED", pcb->state != CLOSED);
+    LWIP_ASSERT("tcp_input: active pcb->state != TIME-WAIT", pcb->state != TIME_WAIT);
+    LWIP_ASSERT("tcp_input: active pcb->state != LISTEN", pcb->state != LISTEN);
+
+    /* check if PCB is bound to specific netif */
+    if ((pcb->netif_idx != NETIF_NO_INDEX) &&
+        (pcb->netif_idx != netif_get_index(ip_data.current_input_netif))) {
+      prev = pcb;
+      continue;
+    }
+
+    if (pcb->remote_port == tcphdr->src &&
+        pcb->local_port == tcphdr->dest &&
+        ip_addr_cmp(&pcb->remote_ip, ip_current_src_addr()) &&
+        ip_addr_cmp(&pcb->local_ip, ip_current_dest_addr())) {
+      /* Move this PCB to the front of the list so that subsequent
+         lookups will be faster (we exploit locality in TCP segment
+         arrivals). */
+      LWIP_ASSERT("tcp_input: pcb->next != pcb (before cache)", pcb->next != pcb);
+      if (prev != NULL) {
+        prev->next = pcb->next;
+        pcb->next = tcp_active_pcbs;
+        tcp_active_pcbs = pcb;
+      } else {
+        TCP_STATS_INC(tcp.cachehit);
+      }
+      LWIP_ASSERT("tcp_input: pcb->next != pcb (after cache)", pcb->next != pcb);
+      break;
+    }
+    prev = pcb;
+  }
+
+  if (pcb == NULL) {
+    /* If it did not go to an active connection, we check the connections
+       in the TIME-WAIT state. */
+    for (pcb = tcp_tw_pcbs; pcb != NULL; pcb = pcb->next) {
+      LWIP_ASSERT("tcp_input: TIME-WAIT pcb->state == TIME-WAIT", pcb->state == TIME_WAIT);
+
+      /* check if PCB is bound to specific netif */
+      if ((pcb->netif_idx != NETIF_NO_INDEX) &&
+          (pcb->netif_idx != netif_get_index(ip_data.current_input_netif))) {
+        continue;
+      }
+
+      if (pcb->remote_port == tcphdr->src &&
+          pcb->local_port == tcphdr->dest &&
+          ip_addr_cmp(&pcb->remote_ip, ip_current_src_addr()) &&
+          ip_addr_cmp(&pcb->local_ip, ip_current_dest_addr())) {
+        /* We don't really care enough to move this PCB to the front
+           of the list since we are not very likely to receive that
+           many segments for connections in TIME-WAIT. */
+        LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: packed for TIME_WAITing connection.\n"));
+#ifdef LWIP_HOOK_TCP_INPACKET_PCB
+        if (LWIP_HOOK_TCP_INPACKET_PCB(pcb, tcphdr, tcphdr_optlen, tcphdr_opt1len,
+                                       tcphdr_opt2, p) == ERR_OK)
+#endif
+        {
+          tcp_timewait_input(pcb);
+        }
+        pbuf_free(p);
+        return;
+      }
+    }
+
+    /* Finally, if we still did not get a match, we check all PCBs that
+       are LISTENing for incoming connections. */
+    prev = NULL;
+    for (lpcb = tcp_listen_pcbs.listen_pcbs; lpcb != NULL; lpcb = lpcb->next) {
+      /* check if PCB is bound to specific netif */
+      if ((lpcb->netif_idx != NETIF_NO_INDEX) &&
+          (lpcb->netif_idx != netif_get_index(ip_data.current_input_netif))) {
+        prev = (struct tcp_pcb *)lpcb;
+        continue;
+      }
+
+      if (lpcb->local_port == tcphdr->dest) {
+        if (IP_IS_ANY_TYPE_VAL(lpcb->local_ip)) {
+          /* found an ANY TYPE (IPv4/IPv6) match */
+#if SO_REUSE
+          lpcb_any = lpcb;
+          lpcb_prev = prev;
+#else /* SO_REUSE */
+          break;
+#endif /* SO_REUSE */
+        } else if (IP_ADDR_PCB_VERSION_MATCH_EXACT(lpcb, ip_current_dest_addr())) {
+          if (ip_addr_cmp(&lpcb->local_ip, ip_current_dest_addr())) {
+            /* found an exact match */
+            break;
+          } else if (ip_addr_isany(&lpcb->local_ip)) {
+            /* found an ANY-match */
+#if SO_REUSE
+            lpcb_any = lpcb;
+            lpcb_prev = prev;
+#else /* SO_REUSE */
+            break;
+#endif /* SO_REUSE */
+          }
+        }
+      }
+      prev = (struct tcp_pcb *)lpcb;
+    }
+#if SO_REUSE
+    /* first try specific local IP */
+    if (lpcb == NULL) {
+      /* only pass to ANY if no specific local IP has been found */
+      lpcb = lpcb_any;
+      prev = lpcb_prev;
+    }
+#endif /* SO_REUSE */
+    if (lpcb != NULL) {
+      /* Move this PCB to the front of the list so that subsequent
+         lookups will be faster (we exploit locality in TCP segment
+         arrivals). */
+      if (prev != NULL) {
+        ((struct tcp_pcb_listen *)prev)->next = lpcb->next;
+        /* our successor is the remainder of the listening list */
+        lpcb->next = tcp_listen_pcbs.listen_pcbs;
+        /* put this listening pcb at the head of the listening list */
+        tcp_listen_pcbs.listen_pcbs = lpcb;
+      } else {
+        TCP_STATS_INC(tcp.cachehit);
+      }
+
+      LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: packed for LISTENing connection.\n"));
+#ifdef LWIP_HOOK_TCP_INPACKET_PCB
+      if (LWIP_HOOK_TCP_INPACKET_PCB((struct tcp_pcb *)lpcb, tcphdr, tcphdr_optlen,
+                                     tcphdr_opt1len, tcphdr_opt2, p) == ERR_OK)
+#endif
+      {
+        tcp_listen_input(lpcb);
+      }
+      pbuf_free(p);
+      return;
+    }
+  }
+
+#if TCP_INPUT_DEBUG
+  LWIP_DEBUGF(TCP_INPUT_DEBUG, ("+-+-+-+-+-+-+-+-+-+-+-+-+-+- tcp_input: flags "));
+  tcp_debug_print_flags(TCPH_FLAGS(tcphdr));
+  LWIP_DEBUGF(TCP_INPUT_DEBUG, ("-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n"));
+#endif /* TCP_INPUT_DEBUG */
+
+
+#ifdef LWIP_HOOK_TCP_INPACKET_PCB
+  if ((pcb != NULL) && LWIP_HOOK_TCP_INPACKET_PCB(pcb, tcphdr, tcphdr_optlen,
+      tcphdr_opt1len, tcphdr_opt2, p) != ERR_OK) {
+    pbuf_free(p);
+    return;
+  }
+#endif
+  if (pcb != NULL) {
+    /* The incoming segment belongs to a connection. */
+#if TCP_INPUT_DEBUG
+    tcp_debug_print_state(pcb->state);
+#endif /* TCP_INPUT_DEBUG */
+
+    /* Set up a tcp_seg structure. */
+    inseg.next = NULL;
+    inseg.len = p->tot_len;
+    inseg.p = p;
+    inseg.tcphdr = tcphdr;
+
+    recv_data = NULL;
+    recv_flags = 0;
+    recv_acked = 0;
+
+    if (flags & TCP_PSH) {
+      p->flags |= PBUF_FLAG_PUSH;
+    }
+
+    /* If there is data which was previously "refused" by upper layer */
+    if (pcb->refused_data != NULL) {
+      if ((tcp_process_refused_data(pcb) == ERR_ABRT) ||
+          ((pcb->refused_data != NULL) && (tcplen > 0))) {
+        /* pcb has been aborted or refused data is still refused and the new
+           segment contains data */
+        if (pcb->rcv_ann_wnd == 0) {
+          /* this is a zero-window probe, we respond to it with current RCV.NXT
+          and drop the data segment */
+          tcp_send_empty_ack(pcb);
+        }
+        TCP_STATS_INC(tcp.drop);
+        MIB2_STATS_INC(mib2.tcpinerrs);
+        goto aborted;
+      }
+    }
+    tcp_input_pcb = pcb;
+    err = tcp_process(pcb);
+    /* A return value of ERR_ABRT means that tcp_abort() was called
+       and that the pcb has been freed. If so, we don't do anything. */
+    if (err != ERR_ABRT) {
+      if (recv_flags & TF_RESET) {
+        /* TF_RESET means that the connection was reset by the other
+           end. We then call the error callback to inform the
+           application that the connection is dead before we
+           deallocate the PCB. */
+        TCP_EVENT_ERR(pcb->state, pcb->errf, pcb->callback_arg, ERR_RST);
+        tcp_pcb_remove(&tcp_active_pcbs, pcb);
+        tcp_free(pcb);
+      } else {
+        err = ERR_OK;
+        /* If the application has registered a "sent" function to be
+           called when new send buffer space is available, we call it
+           now. */
+        if (recv_acked > 0) {
+          u16_t acked16;
+#if LWIP_WND_SCALE
+          /* recv_acked is u32_t but the sent callback only takes a u16_t,
+             so we might have to call it multiple times. */
+          u32_t acked = recv_acked;
+          while (acked > 0) {
+            acked16 = (u16_t)LWIP_MIN(acked, 0xffffu);
+            acked -= acked16;
+#else
+          {
+            acked16 = recv_acked;
+#endif
+            TCP_EVENT_SENT(pcb, (u16_t)acked16, err);
+            if (err == ERR_ABRT) {
+              goto aborted;
+            }
+          }
+          recv_acked = 0;
+        }
+        if (tcp_input_delayed_close(pcb)) {
+          goto aborted;
+        }
+#if TCP_QUEUE_OOSEQ && LWIP_WND_SCALE
+        while (recv_data != NULL) {
+          struct pbuf *rest = NULL;
+          pbuf_split_64k(recv_data, &rest);
+#else /* TCP_QUEUE_OOSEQ && LWIP_WND_SCALE */
+        if (recv_data != NULL) {
+#endif /* TCP_QUEUE_OOSEQ && LWIP_WND_SCALE */
+
+          LWIP_ASSERT("pcb->refused_data == NULL", pcb->refused_data == NULL);
+          if (pcb->flags & TF_RXCLOSED) {
+            /* received data although already closed -> abort (send RST) to
+               notify the remote host that not all data has been processed */
+            pbuf_free(recv_data);
+#if TCP_QUEUE_OOSEQ && LWIP_WND_SCALE
+            if (rest != NULL) {
+              pbuf_free(rest);
+            }
+#endif /* TCP_QUEUE_OOSEQ && LWIP_WND_SCALE */
+            tcp_abort(pcb);
+            goto aborted;
+          }
+
+          /* Notify application that data has been received. */
+          TCP_EVENT_RECV(pcb, recv_data, ERR_OK, err);
+          if (err == ERR_ABRT) {
+#if TCP_QUEUE_OOSEQ && LWIP_WND_SCALE
+            if (rest != NULL) {
+              pbuf_free(rest);
+            }
+#endif /* TCP_QUEUE_OOSEQ && LWIP_WND_SCALE */
+            goto aborted;
+          }
+
+          /* If the upper layer can't receive this data, store it */
+          if (err != ERR_OK) {
+#if TCP_QUEUE_OOSEQ && LWIP_WND_SCALE
+            if (rest != NULL) {
+              pbuf_cat(recv_data, rest);
+            }
+#endif /* TCP_QUEUE_OOSEQ && LWIP_WND_SCALE */
+            pcb->refused_data = recv_data;
+            LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: keep incoming packet, because pcb is \"full\"\n"));
+#if TCP_QUEUE_OOSEQ && LWIP_WND_SCALE
+            break;
+          } else {
+            /* Upper layer received the data, go on with the rest if > 64K */
+            recv_data = rest;
+#endif /* TCP_QUEUE_OOSEQ && LWIP_WND_SCALE */
+          }
+        }
+
+        /* If a FIN segment was received, we call the callback
+           function with a NULL buffer to indicate EOF. */
+        if (recv_flags & TF_GOT_FIN) {
+          if (pcb->refused_data != NULL) {
+            /* Delay this if we have refused data. */
+            pcb->refused_data->flags |= PBUF_FLAG_TCP_FIN;
+          } else {
+            /* correct rcv_wnd as the application won't call tcp_recved()
+               for the FIN's seqno */
+            if (pcb->rcv_wnd != TCP_WND_MAX(pcb)) {
+              pcb->rcv_wnd++;
+            }
+            TCP_EVENT_CLOSED(pcb, err);
+            if (err == ERR_ABRT) {
+              goto aborted;
+            }
+          }
+        }
+
+        tcp_input_pcb = NULL;
+        if (tcp_input_delayed_close(pcb)) {
+          goto aborted;
+        }
+        /* Try to send something out. */
+        tcp_output(pcb);
+#if TCP_INPUT_DEBUG
+#if TCP_DEBUG
+        tcp_debug_print_state(pcb->state);
+#endif /* TCP_DEBUG */
+#endif /* TCP_INPUT_DEBUG */
+      }
+    }
+    /* Jump target if pcb has been aborted in a callback (by calling tcp_abort()).
+       Below this line, 'pcb' may not be dereferenced! */
+aborted:
+    tcp_input_pcb = NULL;
+    recv_data = NULL;
+
+    /* give up our reference to inseg.p */
+    if (inseg.p != NULL) {
+      pbuf_free(inseg.p);
+      inseg.p = NULL;
+    }
+  } else {
+    /* If no matching PCB was found, send a TCP RST (reset) to the
+       sender. */
+    LWIP_DEBUGF(TCP_RST_DEBUG, ("tcp_input: no PCB match found, resetting.\n"));
+    if (!(TCPH_FLAGS(tcphdr) & TCP_RST)) {
+      TCP_STATS_INC(tcp.proterr);
+      TCP_STATS_INC(tcp.drop);
+      tcp_rst(NULL, ackno, seqno + tcplen, ip_current_dest_addr(),
+              ip_current_src_addr(), tcphdr->dest, tcphdr->src);
+    }
+    pbuf_free(p);
+  }
+
+  LWIP_ASSERT("tcp_input: tcp_pcbs_sane()", tcp_pcbs_sane());
+  PERF_STOP("tcp_input");
+  return;
+dropped:
+  TCP_STATS_INC(tcp.drop);
+  MIB2_STATS_INC(mib2.tcpinerrs);
+  pbuf_free(p);
+}
+
+/** Called from tcp_input to check for TF_CLOSED flag. This results in closing
+ * and deallocating a pcb at the correct place to ensure noone references it
+ * any more.
+ * @returns 1 if the pcb has been closed and deallocated, 0 otherwise
+ */
+static int
+tcp_input_delayed_close(struct tcp_pcb *pcb)
+{
+  LWIP_ASSERT("tcp_input_delayed_close: invalid pcb", pcb != NULL);
+
+  if (recv_flags & TF_CLOSED) {
+    /* The connection has been closed and we will deallocate the
+        PCB. */
+    if (!(pcb->flags & TF_RXCLOSED)) {
+      /* Connection closed although the application has only shut down the
+          tx side: call the PCB's err callback and indicate the closure to
+          ensure the application doesn't continue using the PCB. */
+      TCP_EVENT_ERR(pcb->state, pcb->errf, pcb->callback_arg, ERR_CLSD);
+    }
+    tcp_pcb_remove(&tcp_active_pcbs, pcb);
+    tcp_free(pcb);
+    return 1;
+  }
+  return 0;
+}
+
+/**
+ * Called by tcp_input() when a segment arrives for a listening
+ * connection (from tcp_input()).
+ *
+ * @param pcb the tcp_pcb_listen for which a segment arrived
+ *
+ * @note the segment which arrived is saved in global variables, therefore only the pcb
+ *       involved is passed as a parameter to this function
+ */
+static void
+tcp_listen_input(struct tcp_pcb_listen *pcb)
+{
+  struct tcp_pcb *npcb;
+  u32_t iss;
+  err_t rc;
+
+  if (flags & TCP_RST) {
+    /* An incoming RST should be ignored. Return. */
+    return;
+  }
+
+  LWIP_ASSERT("tcp_listen_input: invalid pcb", pcb != NULL);
+
+  /* In the LISTEN state, we check for incoming SYN segments,
+     creates a new PCB, and responds with a SYN|ACK. */
+  if (flags & TCP_ACK) {
+    /* For incoming segments with the ACK flag set, respond with a
+       RST. */
+    LWIP_DEBUGF(TCP_RST_DEBUG, ("tcp_listen_input: ACK in LISTEN, sending reset\n"));
+    tcp_rst((const struct tcp_pcb *)pcb, ackno, seqno + tcplen, ip_current_dest_addr(),
+            ip_current_src_addr(), tcphdr->dest, tcphdr->src);
+  } else if (flags & TCP_SYN) {
+    LWIP_DEBUGF(TCP_DEBUG, ("TCP connection request %"U16_F" -> %"U16_F".\n", tcphdr->src, tcphdr->dest));
+#if TCP_LISTEN_BACKLOG
+    if (pcb->accepts_pending >= pcb->backlog) {
+      LWIP_DEBUGF(TCP_DEBUG, ("tcp_listen_input: listen backlog exceeded for port %"U16_F"\n", tcphdr->dest));
+      return;
+    }
+#endif /* TCP_LISTEN_BACKLOG */
+    npcb = tcp_alloc(pcb->prio);
+    /* If a new PCB could not be created (probably due to lack of memory),
+       we don't do anything, but rely on the sender will retransmit the
+       SYN at a time when we have more memory available. */
+    if (npcb == NULL) {
+      err_t err;
+      LWIP_DEBUGF(TCP_DEBUG, ("tcp_listen_input: could not allocate PCB\n"));
+      TCP_STATS_INC(tcp.memerr);
+      TCP_EVENT_ACCEPT(pcb, NULL, pcb->callback_arg, ERR_MEM, err);
+      LWIP_UNUSED_ARG(err); /* err not useful here */
+      return;
+    }
+#if TCP_LISTEN_BACKLOG
+    pcb->accepts_pending++;
+    tcp_set_flags(npcb, TF_BACKLOGPEND);
+#endif /* TCP_LISTEN_BACKLOG */
+    /* Set up the new PCB. */
+    ip_addr_copy(npcb->local_ip, *ip_current_dest_addr());
+    ip_addr_copy(npcb->remote_ip, *ip_current_src_addr());
+    npcb->local_port = pcb->local_port;
+    npcb->remote_port = tcphdr->src;
+    npcb->state = SYN_RCVD;
+    npcb->rcv_nxt = seqno + 1;
+    npcb->rcv_ann_right_edge = npcb->rcv_nxt;
+    iss = tcp_next_iss(npcb);
+    npcb->snd_wl2 = iss;
+    npcb->snd_nxt = iss;
+    npcb->lastack = iss;
+    npcb->snd_lbb = iss;
+    npcb->snd_wl1 = seqno - 1;/* initialise to seqno-1 to force window update */
+    npcb->callback_arg = pcb->callback_arg;
+#if LWIP_CALLBACK_API || TCP_LISTEN_BACKLOG
+    npcb->listener = pcb;
+#endif /* LWIP_CALLBACK_API || TCP_LISTEN_BACKLOG */
+    /* inherit socket options */
+    npcb->so_options = pcb->so_options & SOF_INHERITED;
+    npcb->netif_idx = pcb->netif_idx;
+    /* Register the new PCB so that we can begin receiving segments
+       for it. */
+    TCP_REG_ACTIVE(npcb);
+
+    /* Parse any options in the SYN. */
+    tcp_parseopt(npcb);
+    npcb->snd_wnd = tcphdr->wnd;
+    npcb->snd_wnd_max = npcb->snd_wnd;
+
+#if TCP_CALCULATE_EFF_SEND_MSS
+    npcb->mss = tcp_eff_send_mss(npcb->mss, &npcb->local_ip, &npcb->remote_ip);
+#endif /* TCP_CALCULATE_EFF_SEND_MSS */
+
+    MIB2_STATS_INC(mib2.tcppassiveopens);
+
+#if LWIP_TCP_PCB_NUM_EXT_ARGS
+    if (tcp_ext_arg_invoke_callbacks_passive_open(pcb, npcb) != ERR_OK) {
+      tcp_abandon(npcb, 0);
+      return;
+    }
+#endif
+
+    /* Send a SYN|ACK together with the MSS option. */
+    rc = tcp_enqueue_flags(npcb, TCP_SYN | TCP_ACK);
+    if (rc != ERR_OK) {
+      tcp_abandon(npcb, 0);
+      return;
+    }
+    tcp_output(npcb);
+  }
+  return;
+}
+
+/**
+ * Called by tcp_input() when a segment arrives for a connection in
+ * TIME_WAIT.
+ *
+ * @param pcb the tcp_pcb for which a segment arrived
+ *
+ * @note the segment which arrived is saved in global variables, therefore only the pcb
+ *       involved is passed as a parameter to this function
+ */
+static void
+tcp_timewait_input(struct tcp_pcb *pcb)
+{
+  /* RFC 1337: in TIME_WAIT, ignore RST and ACK FINs + any 'acceptable' segments */
+  /* RFC 793 3.9 Event Processing - Segment Arrives:
+   * - first check sequence number - we skip that one in TIME_WAIT (always
+   *   acceptable since we only send ACKs)
+   * - second check the RST bit (... return) */
+  if (flags & TCP_RST) {
+    return;
+  }
+
+  LWIP_ASSERT("tcp_timewait_input: invalid pcb", pcb != NULL);
+
+  /* - fourth, check the SYN bit, */
+  if (flags & TCP_SYN) {
+    /* If an incoming segment is not acceptable, an acknowledgment
+       should be sent in reply */
+    if (TCP_SEQ_BETWEEN(seqno, pcb->rcv_nxt, pcb->rcv_nxt + pcb->rcv_wnd)) {
+      /* If the SYN is in the window it is an error, send a reset */
+      tcp_rst(pcb, ackno, seqno + tcplen, ip_current_dest_addr(),
+              ip_current_src_addr(), tcphdr->dest, tcphdr->src);
+      return;
+    }
+  } else if (flags & TCP_FIN) {
+    /* - eighth, check the FIN bit: Remain in the TIME-WAIT state.
+         Restart the 2 MSL time-wait timeout.*/
+    pcb->tmr = tcp_ticks;
+  }
+
+  if ((tcplen > 0)) {
+    /* Acknowledge data, FIN or out-of-window SYN */
+    tcp_ack_now(pcb);
+    tcp_output(pcb);
+  }
+  return;
+}
+
+/**
+ * Implements the TCP state machine. Called by tcp_input. In some
+ * states tcp_receive() is called to receive data. The tcp_seg
+ * argument will be freed by the caller (tcp_input()) unless the
+ * recv_data pointer in the pcb is set.
+ *
+ * @param pcb the tcp_pcb for which a segment arrived
+ *
+ * @note the segment which arrived is saved in global variables, therefore only the pcb
+ *       involved is passed as a parameter to this function
+ */
+static err_t
+tcp_process(struct tcp_pcb *pcb)
+{
+  struct tcp_seg *rseg;
+  u8_t acceptable = 0;
+  err_t err;
+
+  err = ERR_OK;
+
+  LWIP_ASSERT("tcp_process: invalid pcb", pcb != NULL);
+
+  /* Process incoming RST segments. */
+  if (flags & TCP_RST) {
+    /* First, determine if the reset is acceptable. */
+    if (pcb->state == SYN_SENT) {
+      /* "In the SYN-SENT state (a RST received in response to an initial SYN),
+          the RST is acceptable if the ACK field acknowledges the SYN." */
+      if (ackno == pcb->snd_nxt) {
+        acceptable = 1;
+      }
+    } else {
+      /* "In all states except SYN-SENT, all reset (RST) segments are validated
+          by checking their SEQ-fields." */
+      if (seqno == pcb->rcv_nxt) {
+        acceptable = 1;
+      } else  if (TCP_SEQ_BETWEEN(seqno, pcb->rcv_nxt,
+                                  pcb->rcv_nxt + pcb->rcv_wnd)) {
+        /* If the sequence number is inside the window, we send a challenge ACK
+           and wait for a re-send with matching sequence number.
+           This follows RFC 5961 section 3.2 and addresses CVE-2004-0230
+           (RST spoofing attack), which is present in RFC 793 RST handling. */
+        tcp_ack_now(pcb);
+      }
+    }
+
+    if (acceptable) {
+      LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_process: Connection RESET\n"));
+      LWIP_ASSERT("tcp_input: pcb->state != CLOSED", pcb->state != CLOSED);
+      recv_flags |= TF_RESET;
+      tcp_clear_flags(pcb, TF_ACK_DELAY);
+      return ERR_RST;
+    } else {
+      LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_process: unacceptable reset seqno %"U32_F" rcv_nxt %"U32_F"\n",
+                                    seqno, pcb->rcv_nxt));
+      LWIP_DEBUGF(TCP_DEBUG, ("tcp_process: unacceptable reset seqno %"U32_F" rcv_nxt %"U32_F"\n",
+                              seqno, pcb->rcv_nxt));
+      return ERR_OK;
+    }
+  }
+
+  if ((flags & TCP_SYN) && (pcb->state != SYN_SENT && pcb->state != SYN_RCVD)) {
+    /* Cope with new connection attempt after remote end crashed */
+    tcp_ack_now(pcb);
+    return ERR_OK;
+  }
+
+  if ((pcb->flags & TF_RXCLOSED) == 0) {
+    /* Update the PCB (in)activity timer unless rx is closed (see tcp_shutdown) */
+    pcb->tmr = tcp_ticks;
+  }
+  pcb->keep_cnt_sent = 0;
+  pcb->persist_probe = 0;
+
+  tcp_parseopt(pcb);
+
+  /* Do different things depending on the TCP state. */
+  switch (pcb->state) {
+    case SYN_SENT:
+      LWIP_DEBUGF(TCP_INPUT_DEBUG, ("SYN-SENT: ackno %"U32_F" pcb->snd_nxt %"U32_F" unacked %"U32_F"\n", ackno,
+                                    pcb->snd_nxt, lwip_ntohl(pcb->unacked->tcphdr->seqno)));
+      /* received SYN ACK with expected sequence number? */
+      if ((flags & TCP_ACK) && (flags & TCP_SYN)
+          && (ackno == pcb->lastack + 1)) {
+        pcb->rcv_nxt = seqno + 1;
+        pcb->rcv_ann_right_edge = pcb->rcv_nxt;
+        pcb->lastack = ackno;
+        pcb->snd_wnd = tcphdr->wnd;
+        pcb->snd_wnd_max = pcb->snd_wnd;
+        pcb->snd_wl1 = seqno - 1; /* initialise to seqno - 1 to force window update */
+        pcb->state = ESTABLISHED;
+
+#if TCP_CALCULATE_EFF_SEND_MSS
+        pcb->mss = tcp_eff_send_mss(pcb->mss, &pcb->local_ip, &pcb->remote_ip);
+#endif /* TCP_CALCULATE_EFF_SEND_MSS */
+
+        pcb->cwnd = LWIP_TCP_CALC_INITIAL_CWND(pcb->mss);
+        LWIP_DEBUGF(TCP_CWND_DEBUG, ("tcp_process (SENT): cwnd %"TCPWNDSIZE_F
+                                     " ssthresh %"TCPWNDSIZE_F"\n",
+                                     pcb->cwnd, pcb->ssthresh));
+        LWIP_ASSERT("pcb->snd_queuelen > 0", (pcb->snd_queuelen > 0));
+        --pcb->snd_queuelen;
+        LWIP_DEBUGF(TCP_QLEN_DEBUG, ("tcp_process: SYN-SENT --queuelen %"TCPWNDSIZE_F"\n", (tcpwnd_size_t)pcb->snd_queuelen));
+        rseg = pcb->unacked;
+        if (rseg == NULL) {
+          /* might happen if tcp_output fails in tcp_rexmit_rto()
+             in which case the segment is on the unsent list */
+          rseg = pcb->unsent;
+          LWIP_ASSERT("no segment to free", rseg != NULL);
+          pcb->unsent = rseg->next;
+        } else {
+          pcb->unacked = rseg->next;
+        }
+        tcp_seg_free(rseg);
+
+        /* If there's nothing left to acknowledge, stop the retransmit
+           timer, otherwise reset it to start again */
+        if (pcb->unacked == NULL) {
+          pcb->rtime = -1;
+        } else {
+          pcb->rtime = 0;
+          pcb->nrtx = 0;
+        }
+
+        /* Call the user specified function to call when successfully
+         * connected. */
+        TCP_EVENT_CONNECTED(pcb, ERR_OK, err);
+        if (err == ERR_ABRT) {
+          return ERR_ABRT;
+        }
+        tcp_ack_now(pcb);
+      }
+      /* received ACK? possibly a half-open connection */
+      else if (flags & TCP_ACK) {
+        /* send a RST to bring the other side in a non-synchronized state. */
+        tcp_rst(pcb, ackno, seqno + tcplen, ip_current_dest_addr(),
+                ip_current_src_addr(), tcphdr->dest, tcphdr->src);
+        /* Resend SYN immediately (don't wait for rto timeout) to establish
+          connection faster, but do not send more SYNs than we otherwise would
+          have, or we might get caught in a loop on loopback interfaces. */
+        if (pcb->nrtx < TCP_SYNMAXRTX) {
+          pcb->rtime = 0;
+          tcp_rexmit_rto(pcb);
+        }
+      }
+      break;
+    case SYN_RCVD:
+      if (flags & TCP_ACK) {
+        /* expected ACK number? */
+        if (TCP_SEQ_BETWEEN(ackno, pcb->lastack + 1, pcb->snd_nxt)) {
+          pcb->state = ESTABLISHED;
+          LWIP_DEBUGF(TCP_DEBUG, ("TCP connection established %"U16_F" -> %"U16_F".\n", inseg.tcphdr->src, inseg.tcphdr->dest));
+#if LWIP_CALLBACK_API || TCP_LISTEN_BACKLOG
+          if (pcb->listener == NULL) {
+            /* listen pcb might be closed by now */
+            err = ERR_VAL;
+          } else
+#endif /* LWIP_CALLBACK_API || TCP_LISTEN_BACKLOG */
+          {
+#if LWIP_CALLBACK_API
+            LWIP_ASSERT("pcb->listener->accept != NULL", pcb->listener->accept != NULL);
+#endif
+            tcp_backlog_accepted(pcb);
+            /* Call the accept function. */
+            TCP_EVENT_ACCEPT(pcb->listener, pcb, pcb->callback_arg, ERR_OK, err);
+          }
+          if (err != ERR_OK) {
+            /* If the accept function returns with an error, we abort
+             * the connection. */
+            /* Already aborted? */
+            if (err != ERR_ABRT) {
+              tcp_abort(pcb);
+            }
+            return ERR_ABRT;
+          }
+          /* If there was any data contained within this ACK,
+           * we'd better pass it on to the application as well. */
+          tcp_receive(pcb);
+
+          /* Prevent ACK for SYN to generate a sent event */
+          if (recv_acked != 0) {
+            recv_acked--;
+          }
+
+          pcb->cwnd = LWIP_TCP_CALC_INITIAL_CWND(pcb->mss);
+          LWIP_DEBUGF(TCP_CWND_DEBUG, ("tcp_process (SYN_RCVD): cwnd %"TCPWNDSIZE_F
+                                       " ssthresh %"TCPWNDSIZE_F"\n",
+                                       pcb->cwnd, pcb->ssthresh));
+
+          if (recv_flags & TF_GOT_FIN) {
+            tcp_ack_now(pcb);
+            pcb->state = CLOSE_WAIT;
+          }
+        } else {
+          /* incorrect ACK number, send RST */
+          tcp_rst(pcb, ackno, seqno + tcplen, ip_current_dest_addr(),
+                  ip_current_src_addr(), tcphdr->dest, tcphdr->src);
+        }
+      } else if ((flags & TCP_SYN) && (seqno == pcb->rcv_nxt - 1)) {
+        /* Looks like another copy of the SYN - retransmit our SYN-ACK */
+        tcp_rexmit(pcb);
+      }
+      break;
+    case CLOSE_WAIT:
+    /* FALLTHROUGH */
+    case ESTABLISHED:
+      tcp_receive(pcb);
+      if (recv_flags & TF_GOT_FIN) { /* passive close */
+        tcp_ack_now(pcb);
+        pcb->state = CLOSE_WAIT;
+      }
+      break;
+    case FIN_WAIT_1:
+      tcp_receive(pcb);
+      if (recv_flags & TF_GOT_FIN) {
+        if ((flags & TCP_ACK) && (ackno == pcb->snd_nxt) &&
+            pcb->unsent == NULL) {
+          LWIP_DEBUGF(TCP_DEBUG,
+                      ("TCP connection closed: FIN_WAIT_1 %"U16_F" -> %"U16_F".\n", inseg.tcphdr->src, inseg.tcphdr->dest));
+          tcp_ack_now(pcb);
+          tcp_pcb_purge(pcb);
+          TCP_RMV_ACTIVE(pcb);
+          pcb->state = TIME_WAIT;
+          TCP_REG(&tcp_tw_pcbs, pcb);
+        } else {
+          tcp_ack_now(pcb);
+          pcb->state = CLOSING;
+        }
+      } else if ((flags & TCP_ACK) && (ackno == pcb->snd_nxt) &&
+                 pcb->unsent == NULL) {
+        pcb->state = FIN_WAIT_2;
+      }
+      break;
+    case FIN_WAIT_2:
+      tcp_receive(pcb);
+      if (recv_flags & TF_GOT_FIN) {
+        LWIP_DEBUGF(TCP_DEBUG, ("TCP connection closed: FIN_WAIT_2 %"U16_F" -> %"U16_F".\n", inseg.tcphdr->src, inseg.tcphdr->dest));
+        tcp_ack_now(pcb);
+        tcp_pcb_purge(pcb);
+        TCP_RMV_ACTIVE(pcb);
+        pcb->state = TIME_WAIT;
+        TCP_REG(&tcp_tw_pcbs, pcb);
+      }
+      break;
+    case CLOSING:
+      tcp_receive(pcb);
+      if ((flags & TCP_ACK) && ackno == pcb->snd_nxt && pcb->unsent == NULL) {
+        LWIP_DEBUGF(TCP_DEBUG, ("TCP connection closed: CLOSING %"U16_F" -> %"U16_F".\n", inseg.tcphdr->src, inseg.tcphdr->dest));
+        tcp_pcb_purge(pcb);
+        TCP_RMV_ACTIVE(pcb);
+        pcb->state = TIME_WAIT;
+        TCP_REG(&tcp_tw_pcbs, pcb);
+      }
+      break;
+    case LAST_ACK:
+      tcp_receive(pcb);
+      if ((flags & TCP_ACK) && ackno == pcb->snd_nxt && pcb->unsent == NULL) {
+        LWIP_DEBUGF(TCP_DEBUG, ("TCP connection closed: LAST_ACK %"U16_F" -> %"U16_F".\n", inseg.tcphdr->src, inseg.tcphdr->dest));
+        /* bugfix #21699: don't set pcb->state to CLOSED here or we risk leaking segments */
+        recv_flags |= TF_CLOSED;
+      }
+      break;
+    default:
+      break;
+  }
+  return ERR_OK;
+}
+
+#if TCP_QUEUE_OOSEQ
+/**
+ * Insert segment into the list (segments covered with new one will be deleted)
+ *
+ * Called from tcp_receive()
+ */
+static void
+tcp_oos_insert_segment(struct tcp_seg *cseg, struct tcp_seg *next)
+{
+  struct tcp_seg *old_seg;
+
+  LWIP_ASSERT("tcp_oos_insert_segment: invalid cseg", cseg != NULL);
+
+  if (TCPH_FLAGS(cseg->tcphdr) & TCP_FIN) {
+    /* received segment overlaps all following segments */
+    tcp_segs_free(next);
+    next = NULL;
+  } else {
+    /* delete some following segments
+       oos queue may have segments with FIN flag */
+    while (next &&
+           TCP_SEQ_GEQ((seqno + cseg->len),
+                       (next->tcphdr->seqno + next->len))) {
+      /* cseg with FIN already processed */
+      if (TCPH_FLAGS(next->tcphdr) & TCP_FIN) {
+        TCPH_SET_FLAG(cseg->tcphdr, TCP_FIN);
+      }
+      old_seg = next;
+      next = next->next;
+      tcp_seg_free(old_seg);
+    }
+    if (next &&
+        TCP_SEQ_GT(seqno + cseg->len, next->tcphdr->seqno)) {
+      /* We need to trim the incoming segment. */
+      cseg->len = (u16_t)(next->tcphdr->seqno - seqno);
+      pbuf_realloc(cseg->p, cseg->len);
+    }
+  }
+  cseg->next = next;
+}
+#endif /* TCP_QUEUE_OOSEQ */
+
+/** Remove segments from a list if the incoming ACK acknowledges them */
+static struct tcp_seg *
+tcp_free_acked_segments(struct tcp_pcb *pcb, struct tcp_seg *seg_list, const char *dbg_list_name,
+                        struct tcp_seg *dbg_other_seg_list)
+{
+  struct tcp_seg *next;
+  u16_t clen;
+
+  LWIP_UNUSED_ARG(dbg_list_name);
+  LWIP_UNUSED_ARG(dbg_other_seg_list);
+
+  while (seg_list != NULL &&
+         TCP_SEQ_LEQ(lwip_ntohl(seg_list->tcphdr->seqno) +
+                     TCP_TCPLEN(seg_list), ackno)) {
+    LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_receive: removing %"U32_F":%"U32_F" from pcb->%s\n",
+                                  lwip_ntohl(seg_list->tcphdr->seqno),
+                                  lwip_ntohl(seg_list->tcphdr->seqno) + TCP_TCPLEN(seg_list),
+                                  dbg_list_name));
+
+    next = seg_list;
+    seg_list = seg_list->next;
+
+    clen = pbuf_clen(next->p);
+    LWIP_DEBUGF(TCP_QLEN_DEBUG, ("tcp_receive: queuelen %"TCPWNDSIZE_F" ... ",
+                                 (tcpwnd_size_t)pcb->snd_queuelen));
+    LWIP_ASSERT("pcb->snd_queuelen >= pbuf_clen(next->p)", (pcb->snd_queuelen >= clen));
+
+    pcb->snd_queuelen = (u16_t)(pcb->snd_queuelen - clen);
+    recv_acked = (tcpwnd_size_t)(recv_acked + next->len);
+    tcp_seg_free(next);
+
+    LWIP_DEBUGF(TCP_QLEN_DEBUG, ("%"TCPWNDSIZE_F" (after freeing %s)\n",
+                                 (tcpwnd_size_t)pcb->snd_queuelen,
+                                 dbg_list_name));
+    if (pcb->snd_queuelen != 0) {
+      LWIP_ASSERT("tcp_receive: valid queue length",
+                  seg_list != NULL || dbg_other_seg_list != NULL);
+    }
+  }
+  return seg_list;
+}
+
+/**
+ * Called by tcp_process. Checks if the given segment is an ACK for outstanding
+ * data, and if so frees the memory of the buffered data. Next, it places the
+ * segment on any of the receive queues (pcb->recved or pcb->ooseq). If the segment
+ * is buffered, the pbuf is referenced by pbuf_ref so that it will not be freed until
+ * it has been removed from the buffer.
+ *
+ * If the incoming segment constitutes an ACK for a segment that was used for RTT
+ * estimation, the RTT is estimated here as well.
+ *
+ * Called from tcp_process().
+ */
+static void
+tcp_receive(struct tcp_pcb *pcb)
+{
+  s16_t m;
+  u32_t right_wnd_edge;
+  int found_dupack = 0;
+
+  LWIP_ASSERT("tcp_receive: invalid pcb", pcb != NULL);
+  LWIP_ASSERT("tcp_receive: wrong state", pcb->state >= ESTABLISHED);
+
+  if (flags & TCP_ACK) {
+    right_wnd_edge = pcb->snd_wnd + pcb->snd_wl2;
+
+    /* Update window. */
+    if (TCP_SEQ_LT(pcb->snd_wl1, seqno) ||
+        (pcb->snd_wl1 == seqno && TCP_SEQ_LT(pcb->snd_wl2, ackno)) ||
+        (pcb->snd_wl2 == ackno && (u32_t)SND_WND_SCALE(pcb, tcphdr->wnd) > pcb->snd_wnd)) {
+      pcb->snd_wnd = SND_WND_SCALE(pcb, tcphdr->wnd);
+      /* keep track of the biggest window announced by the remote host to calculate
+         the maximum segment size */
+      if (pcb->snd_wnd_max < pcb->snd_wnd) {
+        pcb->snd_wnd_max = pcb->snd_wnd;
+      }
+      pcb->snd_wl1 = seqno;
+      pcb->snd_wl2 = ackno;
+      LWIP_DEBUGF(TCP_WND_DEBUG, ("tcp_receive: window update %"TCPWNDSIZE_F"\n", pcb->snd_wnd));
+#if TCP_WND_DEBUG
+    } else {
+      if (pcb->snd_wnd != (tcpwnd_size_t)SND_WND_SCALE(pcb, tcphdr->wnd)) {
+        LWIP_DEBUGF(TCP_WND_DEBUG,
+                    ("tcp_receive: no window update lastack %"U32_F" ackno %"
+                     U32_F" wl1 %"U32_F" seqno %"U32_F" wl2 %"U32_F"\n",
+                     pcb->lastack, ackno, pcb->snd_wl1, seqno, pcb->snd_wl2));
+      }
+#endif /* TCP_WND_DEBUG */
+    }
+
+    /* (From Stevens TCP/IP Illustrated Vol II, p970.) Its only a
+     * duplicate ack if:
+     * 1) It doesn't ACK new data
+     * 2) length of received packet is zero (i.e. no payload)
+     * 3) the advertised window hasn't changed
+     * 4) There is outstanding unacknowledged data (retransmission timer running)
+     * 5) The ACK is == biggest ACK sequence number so far seen (snd_una)
+     *
+     * If it passes all five, should process as a dupack:
+     * a) dupacks < 3: do nothing
+     * b) dupacks == 3: fast retransmit
+     * c) dupacks > 3: increase cwnd
+     *
+     * If it only passes 1-3, should reset dupack counter (and add to
+     * stats, which we don't do in lwIP)
+     *
+     * If it only passes 1, should reset dupack counter
+     *
+     */
+
+    /* Clause 1 */
+    if (TCP_SEQ_LEQ(ackno, pcb->lastack)) {
+      /* Clause 2 */
+      if (tcplen == 0) {
+        /* Clause 3 */
+        if (pcb->snd_wl2 + pcb->snd_wnd == right_wnd_edge) {
+          /* Clause 4 */
+          if (pcb->rtime >= 0) {
+            /* Clause 5 */
+            if (pcb->lastack == ackno) {
+              found_dupack = 1;
+              if ((u8_t)(pcb->dupacks + 1) > pcb->dupacks) {
+                ++pcb->dupacks;
+              }
+              if (pcb->dupacks > 3) {
+                /* Inflate the congestion window */
+                TCP_WND_INC(pcb->cwnd, pcb->mss);
+              }
+              if (pcb->dupacks >= 3) {
+                /* Do fast retransmit (checked via TF_INFR, not via dupacks count) */
+                tcp_rexmit_fast(pcb);
+              }
+            }
+          }
+        }
+      }
+      /* If Clause (1) or more is true, but not a duplicate ack, reset
+       * count of consecutive duplicate acks */
+      if (!found_dupack) {
+        pcb->dupacks = 0;
+      }
+    } else if (TCP_SEQ_BETWEEN(ackno, pcb->lastack + 1, pcb->snd_nxt)) {
+      /* We come here when the ACK acknowledges new data. */
+      tcpwnd_size_t acked;
+
+      /* Reset the "IN Fast Retransmit" flag, since we are no longer
+         in fast retransmit. Also reset the congestion window to the
+         slow start threshold. */
+      if (pcb->flags & TF_INFR) {
+        tcp_clear_flags(pcb, TF_INFR);
+        pcb->cwnd = pcb->ssthresh;
+        pcb->bytes_acked = 0;
+      }
+
+      /* Reset the number of retransmissions. */
+      pcb->nrtx = 0;
+
+      /* Reset the retransmission time-out. */
+      pcb->rto = (s16_t)((pcb->sa >> 3) + pcb->sv);
+
+      /* Record how much data this ACK acks */
+      acked = (tcpwnd_size_t)(ackno - pcb->lastack);
+
+      /* Reset the fast retransmit variables. */
+      pcb->dupacks = 0;
+      pcb->lastack = ackno;
+
+      /* Update the congestion control variables (cwnd and
+         ssthresh). */
+      if (pcb->state >= ESTABLISHED) {
+        if (pcb->cwnd < pcb->ssthresh) {
+          tcpwnd_size_t increase;
+          /* limit to 1 SMSS segment during period following RTO */
+          u8_t num_seg = (pcb->flags & TF_RTO) ? 1 : 2;
+          /* RFC 3465, section 2.2 Slow Start */
+          increase = LWIP_MIN(acked, (tcpwnd_size_t)(num_seg * pcb->mss));
+          TCP_WND_INC(pcb->cwnd, increase);
+          LWIP_DEBUGF(TCP_CWND_DEBUG, ("tcp_receive: slow start cwnd %"TCPWNDSIZE_F"\n", pcb->cwnd));
+        } else {
+          /* RFC 3465, section 2.1 Congestion Avoidance */
+          TCP_WND_INC(pcb->bytes_acked, acked);
+          if (pcb->bytes_acked >= pcb->cwnd) {
+            pcb->bytes_acked = (tcpwnd_size_t)(pcb->bytes_acked - pcb->cwnd);
+            TCP_WND_INC(pcb->cwnd, pcb->mss);
+          }
+          LWIP_DEBUGF(TCP_CWND_DEBUG, ("tcp_receive: congestion avoidance cwnd %"TCPWNDSIZE_F"\n", pcb->cwnd));
+        }
+      }
+      LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_receive: ACK for %"U32_F", unacked->seqno %"U32_F":%"U32_F"\n",
+                                    ackno,
+                                    pcb->unacked != NULL ?
+                                    lwip_ntohl(pcb->unacked->tcphdr->seqno) : 0,
+                                    pcb->unacked != NULL ?
+                                    lwip_ntohl(pcb->unacked->tcphdr->seqno) + TCP_TCPLEN(pcb->unacked) : 0));
+
+      /* Remove segment from the unacknowledged list if the incoming
+         ACK acknowledges them. */
+      pcb->unacked = tcp_free_acked_segments(pcb, pcb->unacked, "unacked", pcb->unsent);
+      /* We go through the ->unsent list to see if any of the segments
+         on the list are acknowledged by the ACK. This may seem
+         strange since an "unsent" segment shouldn't be acked. The
+         rationale is that lwIP puts all outstanding segments on the
+         ->unsent list after a retransmission, so these segments may
+         in fact have been sent once. */
+      pcb->unsent = tcp_free_acked_segments(pcb, pcb->unsent, "unsent", pcb->unacked);
+
+      /* If there's nothing left to acknowledge, stop the retransmit
+         timer, otherwise reset it to start again */
+      if (pcb->unacked == NULL) {
+        pcb->rtime = -1;
+      } else {
+        pcb->rtime = 0;
+      }
+
+      pcb->polltmr = 0;
+
+#if TCP_OVERSIZE
+      if (pcb->unsent == NULL) {
+        pcb->unsent_oversize = 0;
+      }
+#endif /* TCP_OVERSIZE */
+
+#if LWIP_IPV6 && LWIP_ND6_TCP_REACHABILITY_HINTS
+      if (ip_current_is_v6()) {
+        /* Inform neighbor reachability of forward progress. */
+        nd6_reachability_hint(ip6_current_src_addr());
+      }
+#endif /* LWIP_IPV6 && LWIP_ND6_TCP_REACHABILITY_HINTS*/
+
+      pcb->snd_buf = (tcpwnd_size_t)(pcb->snd_buf + recv_acked);
+      /* check if this ACK ends our retransmission of in-flight data */
+      if (pcb->flags & TF_RTO) {
+        /* RTO is done if
+            1) both queues are empty or
+            2) unacked is empty and unsent head contains data not part of RTO or
+            3) unacked head contains data not part of RTO */
+        if (pcb->unacked == NULL) {
+          if ((pcb->unsent == NULL) ||
+              (TCP_SEQ_LEQ(pcb->rto_end, lwip_ntohl(pcb->unsent->tcphdr->seqno)))) {
+            tcp_clear_flags(pcb, TF_RTO);
+          }
+        } else if (TCP_SEQ_LEQ(pcb->rto_end, lwip_ntohl(pcb->unacked->tcphdr->seqno))) {
+          tcp_clear_flags(pcb, TF_RTO);
+        }
+      }
+      /* End of ACK for new data processing. */
+    } else {
+      /* Out of sequence ACK, didn't really ack anything */
+      tcp_send_empty_ack(pcb);
+    }
+
+    LWIP_DEBUGF(TCP_RTO_DEBUG, ("tcp_receive: pcb->rttest %"U32_F" rtseq %"U32_F" ackno %"U32_F"\n",
+                                pcb->rttest, pcb->rtseq, ackno));
+
+    /* RTT estimation calculations. This is done by checking if the
+       incoming segment acknowledges the segment we use to take a
+       round-trip time measurement. */
+    if (pcb->rttest && TCP_SEQ_LT(pcb->rtseq, ackno)) {
+      /* diff between this shouldn't exceed 32K since this are tcp timer ticks
+         and a round-trip shouldn't be that long... */
+      m = (s16_t)(tcp_ticks - pcb->rttest);
+
+      LWIP_DEBUGF(TCP_RTO_DEBUG, ("tcp_receive: experienced rtt %"U16_F" ticks (%"U16_F" msec).\n",
+                                  m, (u16_t)(m * TCP_SLOW_INTERVAL)));
+
+      /* This is taken directly from VJs original code in his paper */
+      m = (s16_t)(m - (pcb->sa >> 3));
+      pcb->sa = (s16_t)(pcb->sa + m);
+      if (m < 0) {
+        m = (s16_t) - m;
+      }
+      m = (s16_t)(m - (pcb->sv >> 2));
+      pcb->sv = (s16_t)(pcb->sv + m);
+      pcb->rto = (s16_t)((pcb->sa >> 3) + pcb->sv);
+
+      LWIP_DEBUGF(TCP_RTO_DEBUG, ("tcp_receive: RTO %"U16_F" (%"U16_F" milliseconds)\n",
+                                  pcb->rto, (u16_t)(pcb->rto * TCP_SLOW_INTERVAL)));
+
+      pcb->rttest = 0;
+    }
+  }
+
+  /* If the incoming segment contains data, we must process it
+     further unless the pcb already received a FIN.
+     (RFC 793, chapter 3.9, "SEGMENT ARRIVES" in states CLOSE-WAIT, CLOSING,
+     LAST-ACK and TIME-WAIT: "Ignore the segment text.") */
+  if ((tcplen > 0) && (pcb->state < CLOSE_WAIT)) {
+    /* This code basically does three things:
+
+    +) If the incoming segment contains data that is the next
+    in-sequence data, this data is passed to the application. This
+    might involve trimming the first edge of the data. The rcv_nxt
+    variable and the advertised window are adjusted.
+
+    +) If the incoming segment has data that is above the next
+    sequence number expected (->rcv_nxt), the segment is placed on
+    the ->ooseq queue. This is done by finding the appropriate
+    place in the ->ooseq queue (which is ordered by sequence
+    number) and trim the segment in both ends if needed. An
+    immediate ACK is sent to indicate that we received an
+    out-of-sequence segment.
+
+    +) Finally, we check if the first segment on the ->ooseq queue
+    now is in sequence (i.e., if rcv_nxt >= ooseq->seqno). If
+    rcv_nxt > ooseq->seqno, we must trim the first edge of the
+    segment on ->ooseq before we adjust rcv_nxt. The data in the
+    segments that are now on sequence are chained onto the
+    incoming segment so that we only need to call the application
+    once.
+    */
+
+    /* First, we check if we must trim the first edge. We have to do
+       this if the sequence number of the incoming segment is less
+       than rcv_nxt, and the sequence number plus the length of the
+       segment is larger than rcv_nxt. */
+    /*    if (TCP_SEQ_LT(seqno, pcb->rcv_nxt)) {
+          if (TCP_SEQ_LT(pcb->rcv_nxt, seqno + tcplen)) {*/
+    if (TCP_SEQ_BETWEEN(pcb->rcv_nxt, seqno + 1, seqno + tcplen - 1)) {
+      /* Trimming the first edge is done by pushing the payload
+         pointer in the pbuf downwards. This is somewhat tricky since
+         we do not want to discard the full contents of the pbuf up to
+         the new starting point of the data since we have to keep the
+         TCP header which is present in the first pbuf in the chain.
+
+         What is done is really quite a nasty hack: the first pbuf in
+         the pbuf chain is pointed to by inseg.p. Since we need to be
+         able to deallocate the whole pbuf, we cannot change this
+         inseg.p pointer to point to any of the later pbufs in the
+         chain. Instead, we point the ->payload pointer in the first
+         pbuf to data in one of the later pbufs. We also set the
+         inseg.data pointer to point to the right place. This way, the
+         ->p pointer will still point to the first pbuf, but the
+         ->p->payload pointer will point to data in another pbuf.
+
+         After we are done with adjusting the pbuf pointers we must
+         adjust the ->data pointer in the seg and the segment
+         length.*/
+
+      struct pbuf *p = inseg.p;
+      u32_t off32 = pcb->rcv_nxt - seqno;
+      u16_t new_tot_len, off;
+      LWIP_ASSERT("inseg.p != NULL", inseg.p);
+      LWIP_ASSERT("insane offset!", (off32 < 0xffff));
+      off = (u16_t)off32;
+      LWIP_ASSERT("pbuf too short!", (((s32_t)inseg.p->tot_len) >= off));
+      inseg.len -= off;
+      new_tot_len = (u16_t)(inseg.p->tot_len - off);
+      while (p->len < off) {
+        off -= p->len;
+        /* all pbufs up to and including this one have len==0, so tot_len is equal */
+        p->tot_len = new_tot_len;
+        p->len = 0;
+        p = p->next;
+      }
+      /* cannot fail... */
+      pbuf_remove_header(p, off);
+      inseg.tcphdr->seqno = seqno = pcb->rcv_nxt;
+    } else {
+      if (TCP_SEQ_LT(seqno, pcb->rcv_nxt)) {
+        /* the whole segment is < rcv_nxt */
+        /* must be a duplicate of a packet that has already been correctly handled */
+
+        LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_receive: duplicate seqno %"U32_F"\n", seqno));
+        tcp_ack_now(pcb);
+      }
+    }
+
+    /* The sequence number must be within the window (above rcv_nxt
+       and below rcv_nxt + rcv_wnd) in order to be further
+       processed. */
+    if (TCP_SEQ_BETWEEN(seqno, pcb->rcv_nxt,
+                        pcb->rcv_nxt + pcb->rcv_wnd - 1)) {
+      if (pcb->rcv_nxt == seqno) {
+        /* The incoming segment is the next in sequence. We check if
+           we have to trim the end of the segment and update rcv_nxt
+           and pass the data to the application. */
+        tcplen = TCP_TCPLEN(&inseg);
+
+        if (tcplen > pcb->rcv_wnd) {
+          LWIP_DEBUGF(TCP_INPUT_DEBUG,
+                      ("tcp_receive: other end overran receive window"
+                       "seqno %"U32_F" len %"U16_F" right edge %"U32_F"\n",
+                       seqno, tcplen, pcb->rcv_nxt + pcb->rcv_wnd));
+          if (TCPH_FLAGS(inseg.tcphdr) & TCP_FIN) {
+            /* Must remove the FIN from the header as we're trimming
+             * that byte of sequence-space from the packet */
+            TCPH_FLAGS_SET(inseg.tcphdr, TCPH_FLAGS(inseg.tcphdr) & ~(unsigned int)TCP_FIN);
+          }
+          /* Adjust length of segment to fit in the window. */
+          TCPWND_CHECK16(pcb->rcv_wnd);
+          inseg.len = (u16_t)pcb->rcv_wnd;
+          if (TCPH_FLAGS(inseg.tcphdr) & TCP_SYN) {
+            inseg.len -= 1;
+          }
+          pbuf_realloc(inseg.p, inseg.len);
+          tcplen = TCP_TCPLEN(&inseg);
+          LWIP_ASSERT("tcp_receive: segment not trimmed correctly to rcv_wnd\n",
+                      (seqno + tcplen) == (pcb->rcv_nxt + pcb->rcv_wnd));
+        }
+#if TCP_QUEUE_OOSEQ
+        /* Received in-sequence data, adjust ooseq data if:
+           - FIN has been received or
+           - inseq overlaps with ooseq */
+        if (pcb->ooseq != NULL) {
+          if (TCPH_FLAGS(inseg.tcphdr) & TCP_FIN) {
+            LWIP_DEBUGF(TCP_INPUT_DEBUG,
+                        ("tcp_receive: received in-order FIN, binning ooseq queue\n"));
+            /* Received in-order FIN means anything that was received
+             * out of order must now have been received in-order, so
+             * bin the ooseq queue */
+            while (pcb->ooseq != NULL) {
+              struct tcp_seg *old_ooseq = pcb->ooseq;
+              pcb->ooseq = pcb->ooseq->next;
+              tcp_seg_free(old_ooseq);
+            }
+          } else {
+            struct tcp_seg *next = pcb->ooseq;
+            /* Remove all segments on ooseq that are covered by inseg already.
+             * FIN is copied from ooseq to inseg if present. */
+            while (next &&
+                   TCP_SEQ_GEQ(seqno + tcplen,
+                               next->tcphdr->seqno + next->len)) {
+              struct tcp_seg *tmp;
+              /* inseg cannot have FIN here (already processed above) */
+              if ((TCPH_FLAGS(next->tcphdr) & TCP_FIN) != 0 &&
+                  (TCPH_FLAGS(inseg.tcphdr) & TCP_SYN) == 0) {
+                TCPH_SET_FLAG(inseg.tcphdr, TCP_FIN);
+                tcplen = TCP_TCPLEN(&inseg);
+              }
+              tmp = next;
+              next = next->next;
+              tcp_seg_free(tmp);
+            }
+            /* Now trim right side of inseg if it overlaps with the first
+             * segment on ooseq */
+            if (next &&
+                TCP_SEQ_GT(seqno + tcplen,
+                           next->tcphdr->seqno)) {
+              /* inseg cannot have FIN here (already processed above) */
+              inseg.len = (u16_t)(next->tcphdr->seqno - seqno);
+              if (TCPH_FLAGS(inseg.tcphdr) & TCP_SYN) {
+                inseg.len -= 1;
+              }
+              pbuf_realloc(inseg.p, inseg.len);
+              tcplen = TCP_TCPLEN(&inseg);
+              LWIP_ASSERT("tcp_receive: segment not trimmed correctly to ooseq queue\n",
+                          (seqno + tcplen) == next->tcphdr->seqno);
+            }
+            pcb->ooseq = next;
+          }
+        }
+#endif /* TCP_QUEUE_OOSEQ */
+
+        pcb->rcv_nxt = seqno + tcplen;
+
+        /* Update the receiver's (our) window. */
+        LWIP_ASSERT("tcp_receive: tcplen > rcv_wnd\n", pcb->rcv_wnd >= tcplen);
+        pcb->rcv_wnd -= tcplen;
+
+        tcp_update_rcv_ann_wnd(pcb);
+
+        /* If there is data in the segment, we make preparations to
+           pass this up to the application. The ->recv_data variable
+           is used for holding the pbuf that goes to the
+           application. The code for reassembling out-of-sequence data
+           chains its data on this pbuf as well.
+
+           If the segment was a FIN, we set the TF_GOT_FIN flag that will
+           be used to indicate to the application that the remote side has
+           closed its end of the connection. */
+        if (inseg.p->tot_len > 0) {
+          recv_data = inseg.p;
+          /* Since this pbuf now is the responsibility of the
+             application, we delete our reference to it so that we won't
+             (mistakingly) deallocate it. */
+          inseg.p = NULL;
+        }
+        if (TCPH_FLAGS(inseg.tcphdr) & TCP_FIN) {
+          LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_receive: received FIN.\n"));
+          recv_flags |= TF_GOT_FIN;
+        }
+
+#if TCP_QUEUE_OOSEQ
+        /* We now check if we have segments on the ->ooseq queue that
+           are now in sequence. */
+        while (pcb->ooseq != NULL &&
+               pcb->ooseq->tcphdr->seqno == pcb->rcv_nxt) {
+
+          struct tcp_seg *cseg = pcb->ooseq;
+          seqno = pcb->ooseq->tcphdr->seqno;
+
+          pcb->rcv_nxt += TCP_TCPLEN(cseg);
+          LWIP_ASSERT("tcp_receive: ooseq tcplen > rcv_wnd\n",
+                      pcb->rcv_wnd >= TCP_TCPLEN(cseg));
+          pcb->rcv_wnd -= TCP_TCPLEN(cseg);
+
+          tcp_update_rcv_ann_wnd(pcb);
+
+          if (cseg->p->tot_len > 0) {
+            /* Chain this pbuf onto the pbuf that we will pass to
+               the application. */
+            /* With window scaling, this can overflow recv_data->tot_len, but
+               that's not a problem since we explicitly fix that before passing
+               recv_data to the application. */
+            if (recv_data) {
+              pbuf_cat(recv_data, cseg->p);
+            } else {
+              recv_data = cseg->p;
+            }
+            cseg->p = NULL;
+          }
+          if (TCPH_FLAGS(cseg->tcphdr) & TCP_FIN) {
+            LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_receive: dequeued FIN.\n"));
+            recv_flags |= TF_GOT_FIN;
+            if (pcb->state == ESTABLISHED) { /* force passive close or we can move to active close */
+              pcb->state = CLOSE_WAIT;
+            }
+          }
+
+          pcb->ooseq = cseg->next;
+          tcp_seg_free(cseg);
+        }
+#if LWIP_TCP_SACK_OUT
+        if (pcb->flags & TF_SACK) {
+          if (pcb->ooseq != NULL) {
+            /* Some segments may have been removed from ooseq, let's remove all SACKs that
+               describe anything before the new beginning of that list. */
+            tcp_remove_sacks_lt(pcb, pcb->ooseq->tcphdr->seqno);
+          } else if (LWIP_TCP_SACK_VALID(pcb, 0)) {
+            /* ooseq has been cleared. Nothing to SACK */
+            memset(pcb->rcv_sacks, 0, sizeof(pcb->rcv_sacks));
+          }
+        }
+#endif /* LWIP_TCP_SACK_OUT */
+#endif /* TCP_QUEUE_OOSEQ */
+
+
+        /* Acknowledge the segment(s). */
+        tcp_ack(pcb);
+
+#if LWIP_TCP_SACK_OUT
+        if (LWIP_TCP_SACK_VALID(pcb, 0)) {
+          /* Normally the ACK for the data received could be piggy-backed on a data packet,
+             but lwIP currently does not support including SACKs in data packets. So we force
+             it to respond with an empty ACK packet (only if there is at least one SACK to be sent).
+             NOTE: tcp_send_empty_ack() on success clears the ACK flags (set by tcp_ack()) */
+          tcp_send_empty_ack(pcb);
+        }
+#endif /* LWIP_TCP_SACK_OUT */
+
+#if LWIP_IPV6 && LWIP_ND6_TCP_REACHABILITY_HINTS
+        if (ip_current_is_v6()) {
+          /* Inform neighbor reachability of forward progress. */
+          nd6_reachability_hint(ip6_current_src_addr());
+        }
+#endif /* LWIP_IPV6 && LWIP_ND6_TCP_REACHABILITY_HINTS*/
+
+      } else {
+        /* We get here if the incoming segment is out-of-sequence. */
+
+#if TCP_QUEUE_OOSEQ
+        /* We queue the segment on the ->ooseq queue. */
+        if (pcb->ooseq == NULL) {
+          pcb->ooseq = tcp_seg_copy(&inseg);
+#if LWIP_TCP_SACK_OUT
+          if (pcb->flags & TF_SACK) {
+            /* All the SACKs should be invalid, so we can simply store the most recent one: */
+            pcb->rcv_sacks[0].left = seqno;
+            pcb->rcv_sacks[0].right = seqno + inseg.len;
+          }
+#endif /* LWIP_TCP_SACK_OUT */
+        } else {
+          /* If the queue is not empty, we walk through the queue and
+             try to find a place where the sequence number of the
+             incoming segment is between the sequence numbers of the
+             previous and the next segment on the ->ooseq queue. That is
+             the place where we put the incoming segment. If needed, we
+             trim the second edges of the previous and the incoming
+             segment so that it will fit into the sequence.
+
+             If the incoming segment has the same sequence number as a
+             segment on the ->ooseq queue, we discard the segment that
+             contains less data. */
+
+#if LWIP_TCP_SACK_OUT
+          /* This is the left edge of the lowest possible SACK range.
+             It may start before the newly received segment (possibly adjusted below). */
+          u32_t sackbeg = TCP_SEQ_LT(seqno, pcb->ooseq->tcphdr->seqno) ? seqno : pcb->ooseq->tcphdr->seqno;
+#endif /* LWIP_TCP_SACK_OUT */
+          struct tcp_seg *next, *prev = NULL;
+          for (next = pcb->ooseq; next != NULL; next = next->next) {
+            if (seqno == next->tcphdr->seqno) {
+              /* The sequence number of the incoming segment is the
+                 same as the sequence number of the segment on
+                 ->ooseq. We check the lengths to see which one to
+                 discard. */
+              if (inseg.len > next->len) {
+                /* The incoming segment is larger than the old
+                   segment. We replace some segments with the new
+                   one. */
+                struct tcp_seg *cseg = tcp_seg_copy(&inseg);
+                if (cseg != NULL) {
+                  if (prev != NULL) {
+                    prev->next = cseg;
+                  } else {
+                    pcb->ooseq = cseg;
+                  }
+                  tcp_oos_insert_segment(cseg, next);
+                }
+                break;
+              } else {
+                /* Either the lengths are the same or the incoming
+                   segment was smaller than the old one; in either
+                   case, we ditch the incoming segment. */
+                break;
+              }
+            } else {
+              if (prev == NULL) {
+                if (TCP_SEQ_LT(seqno, next->tcphdr->seqno)) {
+                  /* The sequence number of the incoming segment is lower
+                     than the sequence number of the first segment on the
+                     queue. We put the incoming segment first on the
+                     queue. */
+                  struct tcp_seg *cseg = tcp_seg_copy(&inseg);
+                  if (cseg != NULL) {
+                    pcb->ooseq = cseg;
+                    tcp_oos_insert_segment(cseg, next);
+                  }
+                  break;
+                }
+              } else {
+                /*if (TCP_SEQ_LT(prev->tcphdr->seqno, seqno) &&
+                  TCP_SEQ_LT(seqno, next->tcphdr->seqno)) {*/
+                if (TCP_SEQ_BETWEEN(seqno, prev->tcphdr->seqno + 1, next->tcphdr->seqno - 1)) {
+                  /* The sequence number of the incoming segment is in
+                     between the sequence numbers of the previous and
+                     the next segment on ->ooseq. We trim trim the previous
+                     segment, delete next segments that included in received segment
+                     and trim received, if needed. */
+                  struct tcp_seg *cseg = tcp_seg_copy(&inseg);
+                  if (cseg != NULL) {
+                    if (TCP_SEQ_GT(prev->tcphdr->seqno + prev->len, seqno)) {
+                      /* We need to trim the prev segment. */
+                      prev->len = (u16_t)(seqno - prev->tcphdr->seqno);
+                      pbuf_realloc(prev->p, prev->len);
+                    }
+                    prev->next = cseg;
+                    tcp_oos_insert_segment(cseg, next);
+                  }
+                  break;
+                }
+              }
+
+#if LWIP_TCP_SACK_OUT
+              /* The new segment goes after the 'next' one. If there is a "hole" in sequence numbers
+                 between 'prev' and the beginning of 'next', we want to move sackbeg. */
+              if (prev != NULL && prev->tcphdr->seqno + prev->len != next->tcphdr->seqno) {
+                sackbeg = next->tcphdr->seqno;
+              }
+#endif /* LWIP_TCP_SACK_OUT */
+
+              /* We don't use 'prev' below, so let's set it to current 'next'.
+                 This way even if we break the loop below, 'prev' will be pointing
+                 at the segment right in front of the newly added one. */
+              prev = next;
+
+              /* If the "next" segment is the last segment on the
+                 ooseq queue, we add the incoming segment to the end
+                 of the list. */
+              if (next->next == NULL &&
+                  TCP_SEQ_GT(seqno, next->tcphdr->seqno)) {
+                if (TCPH_FLAGS(next->tcphdr) & TCP_FIN) {
+                  /* segment "next" already contains all data */
+                  break;
+                }
+                next->next = tcp_seg_copy(&inseg);
+                if (next->next != NULL) {
+                  if (TCP_SEQ_GT(next->tcphdr->seqno + next->len, seqno)) {
+                    /* We need to trim the last segment. */
+                    next->len = (u16_t)(seqno - next->tcphdr->seqno);
+                    pbuf_realloc(next->p, next->len);
+                  }
+                  /* check if the remote side overruns our receive window */
+                  if (TCP_SEQ_GT((u32_t)tcplen + seqno, pcb->rcv_nxt + (u32_t)pcb->rcv_wnd)) {
+                    LWIP_DEBUGF(TCP_INPUT_DEBUG,
+                                ("tcp_receive: other end overran receive window"
+                                 "seqno %"U32_F" len %"U16_F" right edge %"U32_F"\n",
+                                 seqno, tcplen, pcb->rcv_nxt + pcb->rcv_wnd));
+                    if (TCPH_FLAGS(next->next->tcphdr) & TCP_FIN) {
+                      /* Must remove the FIN from the header as we're trimming
+                       * that byte of sequence-space from the packet */
+                      TCPH_FLAGS_SET(next->next->tcphdr, TCPH_FLAGS(next->next->tcphdr) & ~TCP_FIN);
+                    }
+                    /* Adjust length of segment to fit in the window. */
+                    next->next->len = (u16_t)(pcb->rcv_nxt + pcb->rcv_wnd - seqno);
+                    pbuf_realloc(next->next->p, next->next->len);
+                    tcplen = TCP_TCPLEN(next->next);
+                    LWIP_ASSERT("tcp_receive: segment not trimmed correctly to rcv_wnd\n",
+                                (seqno + tcplen) == (pcb->rcv_nxt + pcb->rcv_wnd));
+                  }
+                }
+                break;
+              }
+            }
+          }
+
+#if LWIP_TCP_SACK_OUT
+          if (pcb->flags & TF_SACK) {
+            if (prev == NULL) {
+              /* The new segment is at the beginning. sackbeg should already be set properly.
+                 We need to find the right edge. */
+              next = pcb->ooseq;
+            } else if (prev->next != NULL) {
+              /* The new segment was added after 'prev'. If there is a "hole" between 'prev' and 'prev->next',
+                 we need to move sackbeg. After that we should find the right edge. */
+              next = prev->next;
+              if (prev->tcphdr->seqno + prev->len != next->tcphdr->seqno) {
+                sackbeg = next->tcphdr->seqno;
+              }
+            } else {
+              next = NULL;
+            }
+            if (next != NULL) {
+              u32_t sackend = next->tcphdr->seqno;
+              for ( ; (next != NULL) && (sackend == next->tcphdr->seqno); next = next->next) {
+                sackend += next->len;
+              }
+              tcp_add_sack(pcb, sackbeg, sackend);
+            }
+          }
+#endif /* LWIP_TCP_SACK_OUT */
+        }
+#if defined(TCP_OOSEQ_BYTES_LIMIT) || defined(TCP_OOSEQ_PBUFS_LIMIT)
+        {
+          /* Check that the data on ooseq doesn't exceed one of the limits
+             and throw away everything above that limit. */
+#ifdef TCP_OOSEQ_BYTES_LIMIT
+          const u32_t ooseq_max_blen = TCP_OOSEQ_BYTES_LIMIT(pcb);
+          u32_t ooseq_blen = 0;
+#endif
+#ifdef TCP_OOSEQ_PBUFS_LIMIT
+          const u16_t ooseq_max_qlen = TCP_OOSEQ_PBUFS_LIMIT(pcb);
+          u16_t ooseq_qlen = 0;
+#endif
+          struct tcp_seg *next, *prev = NULL;
+          for (next = pcb->ooseq; next != NULL; prev = next, next = next->next) {
+            struct pbuf *p = next->p;
+            int stop_here = 0;
+#ifdef TCP_OOSEQ_BYTES_LIMIT
+            ooseq_blen += p->tot_len;
+            if (ooseq_blen > ooseq_max_blen) {
+              stop_here = 1;
+            }
+#endif
+#ifdef TCP_OOSEQ_PBUFS_LIMIT
+            ooseq_qlen += pbuf_clen(p);
+            if (ooseq_qlen > ooseq_max_qlen) {
+              stop_here = 1;
+            }
+#endif
+            if (stop_here) {
+#if LWIP_TCP_SACK_OUT
+              if (pcb->flags & TF_SACK) {
+                /* Let's remove all SACKs from next's seqno up. */
+                tcp_remove_sacks_gt(pcb, next->tcphdr->seqno);
+              }
+#endif /* LWIP_TCP_SACK_OUT */
+              /* too much ooseq data, dump this and everything after it */
+              tcp_segs_free(next);
+              if (prev == NULL) {
+                /* first ooseq segment is too much, dump the whole queue */
+                pcb->ooseq = NULL;
+              } else {
+                /* just dump 'next' and everything after it */
+                prev->next = NULL;
+              }
+              break;
+            }
+          }
+        }
+#endif /* TCP_OOSEQ_BYTES_LIMIT || TCP_OOSEQ_PBUFS_LIMIT */
+#endif /* TCP_QUEUE_OOSEQ */
+
+        /* We send the ACK packet after we've (potentially) dealt with SACKs,
+           so they can be included in the acknowledgment. */
+        tcp_send_empty_ack(pcb);
+      }
+    } else {
+      /* The incoming segment is not within the window. */
+      tcp_send_empty_ack(pcb);
+    }
+  } else {
+    /* Segments with length 0 is taken care of here. Segments that
+       fall out of the window are ACKed. */
+    if (!TCP_SEQ_BETWEEN(seqno, pcb->rcv_nxt, pcb->rcv_nxt + pcb->rcv_wnd - 1)) {
+      tcp_ack_now(pcb);
+    }
+  }
+}
+
+static u8_t
+tcp_get_next_optbyte(void)
+{
+  u16_t optidx = tcp_optidx++;
+  if ((tcphdr_opt2 == NULL) || (optidx < tcphdr_opt1len)) {
+    u8_t *opts = (u8_t *)tcphdr + TCP_HLEN;
+    return opts[optidx];
+  } else {
+    u8_t idx = (u8_t)(optidx - tcphdr_opt1len);
+    return tcphdr_opt2[idx];
+  }
+}
+
+/**
+ * Parses the options contained in the incoming segment.
+ *
+ * Called from tcp_listen_input() and tcp_process().
+ * Currently, only the MSS option is supported!
+ *
+ * @param pcb the tcp_pcb for which a segment arrived
+ */
+static void
+tcp_parseopt(struct tcp_pcb *pcb)
+{
+  u8_t data;
+  u16_t mss;
+#if LWIP_TCP_TIMESTAMPS
+  u32_t tsval;
+#endif
+
+  LWIP_ASSERT("tcp_parseopt: invalid pcb", pcb != NULL);
+
+  /* Parse the TCP MSS option, if present. */
+  if (tcphdr_optlen != 0) {
+    for (tcp_optidx = 0; tcp_optidx < tcphdr_optlen; ) {
+      u8_t opt = tcp_get_next_optbyte();
+      switch (opt) {
+        case LWIP_TCP_OPT_EOL:
+          /* End of options. */
+          LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_parseopt: EOL\n"));
+          return;
+        case LWIP_TCP_OPT_NOP:
+          /* NOP option. */
+          LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_parseopt: NOP\n"));
+          break;
+        case LWIP_TCP_OPT_MSS:
+          LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_parseopt: MSS\n"));
+          if (tcp_get_next_optbyte() != LWIP_TCP_OPT_LEN_MSS || (tcp_optidx - 2 + LWIP_TCP_OPT_LEN_MSS) > tcphdr_optlen) {
+            /* Bad length */
+            LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_parseopt: bad length\n"));
+            return;
+          }
+          /* An MSS option with the right option length. */
+          mss = (u16_t)(tcp_get_next_optbyte() << 8);
+          mss |= tcp_get_next_optbyte();
+          /* Limit the mss to the configured TCP_MSS and prevent division by zero */
+          pcb->mss = ((mss > TCP_MSS) || (mss == 0)) ? TCP_MSS : mss;
+          break;
+#if LWIP_WND_SCALE
+        case LWIP_TCP_OPT_WS:
+          LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_parseopt: WND_SCALE\n"));
+          if (tcp_get_next_optbyte() != LWIP_TCP_OPT_LEN_WS || (tcp_optidx - 2 + LWIP_TCP_OPT_LEN_WS) > tcphdr_optlen) {
+            /* Bad length */
+            LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_parseopt: bad length\n"));
+            return;
+          }
+          /* An WND_SCALE option with the right option length. */
+          data = tcp_get_next_optbyte();
+          /* If syn was received with wnd scale option,
+             activate wnd scale opt, but only if this is not a retransmission */
+          if ((flags & TCP_SYN) && !(pcb->flags & TF_WND_SCALE)) {
+            pcb->snd_scale = data;
+            if (pcb->snd_scale > 14U) {
+              pcb->snd_scale = 14U;
+            }
+            pcb->rcv_scale = TCP_RCV_SCALE;
+            tcp_set_flags(pcb, TF_WND_SCALE);
+            /* window scaling is enabled, we can use the full receive window */
+            LWIP_ASSERT("window not at default value", pcb->rcv_wnd == TCPWND_MIN16(TCP_WND));
+            LWIP_ASSERT("window not at default value", pcb->rcv_ann_wnd == TCPWND_MIN16(TCP_WND));
+            pcb->rcv_wnd = pcb->rcv_ann_wnd = TCP_WND;
+          }
+          break;
+#endif /* LWIP_WND_SCALE */
+#if LWIP_TCP_TIMESTAMPS
+        case LWIP_TCP_OPT_TS:
+          LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_parseopt: TS\n"));
+          if (tcp_get_next_optbyte() != LWIP_TCP_OPT_LEN_TS || (tcp_optidx - 2 + LWIP_TCP_OPT_LEN_TS) > tcphdr_optlen) {
+            /* Bad length */
+            LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_parseopt: bad length\n"));
+            return;
+          }
+          /* TCP timestamp option with valid length */
+          tsval = tcp_get_next_optbyte();
+          tsval |= (tcp_get_next_optbyte() << 8);
+          tsval |= (tcp_get_next_optbyte() << 16);
+          tsval |= (tcp_get_next_optbyte() << 24);
+          if (flags & TCP_SYN) {
+            pcb->ts_recent = lwip_ntohl(tsval);
+            /* Enable sending timestamps in every segment now that we know
+               the remote host supports it. */
+            tcp_set_flags(pcb, TF_TIMESTAMP);
+          } else if (TCP_SEQ_BETWEEN(pcb->ts_lastacksent, seqno, seqno + tcplen)) {
+            pcb->ts_recent = lwip_ntohl(tsval);
+          }
+          /* Advance to next option (6 bytes already read) */
+          tcp_optidx += LWIP_TCP_OPT_LEN_TS - 6;
+          break;
+#endif /* LWIP_TCP_TIMESTAMPS */
+#if LWIP_TCP_SACK_OUT
+        case LWIP_TCP_OPT_SACK_PERM:
+          LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_parseopt: SACK_PERM\n"));
+          if (tcp_get_next_optbyte() != LWIP_TCP_OPT_LEN_SACK_PERM || (tcp_optidx - 2 + LWIP_TCP_OPT_LEN_SACK_PERM) > tcphdr_optlen) {
+            /* Bad length */
+            LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_parseopt: bad length\n"));
+            return;
+          }
+          /* TCP SACK_PERM option with valid length */
+          if (flags & TCP_SYN) {
+            /* We only set it if we receive it in a SYN (or SYN+ACK) packet */
+            tcp_set_flags(pcb, TF_SACK);
+          }
+          break;
+#endif /* LWIP_TCP_SACK_OUT */
+        default:
+          LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_parseopt: other\n"));
+          data = tcp_get_next_optbyte();
+          if (data < 2) {
+            LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_parseopt: bad length\n"));
+            /* If the length field is zero, the options are malformed
+               and we don't process them further. */
+            return;
+          }
+          /* All other options have a length field, so that we easily
+             can skip past them. */
+          tcp_optidx += data - 2;
+      }
+    }
+  }
+}
+
+void
+tcp_trigger_input_pcb_close(void)
+{
+  recv_flags |= TF_CLOSED;
+}
+
+#if LWIP_TCP_SACK_OUT
+/**
+ * Called by tcp_receive() to add new SACK entry.
+ *
+ * The new SACK entry will be placed at the beginning of rcv_sacks[], as the newest one.
+ * Existing SACK entries will be "pushed back", to preserve their order.
+ * This is the behavior described in RFC 2018, section 4.
+ *
+ * @param pcb the tcp_pcb for which a segment arrived
+ * @param left the left side of the SACK (the first sequence number)
+ * @param right the right side of the SACK (the first sequence number past this SACK)
+ */
+static void
+tcp_add_sack(struct tcp_pcb *pcb, u32_t left, u32_t right)
+{
+  u8_t i;
+  u8_t unused_idx;
+
+  if ((pcb->flags & TF_SACK) == 0 || !TCP_SEQ_LT(left, right)) {
+    return;
+  }
+
+  /* First, let's remove all SACKs that are no longer needed (because they overlap with the newest one),
+     while moving all other SACKs forward.
+     We run this loop for all entries, until we find the first invalid one.
+     There is no point checking after that. */
+  for (i = unused_idx = 0; (i < LWIP_TCP_MAX_SACK_NUM) && LWIP_TCP_SACK_VALID(pcb, i); ++i) {
+    /* We only want to use SACK at [i] if it doesn't overlap with left:right range.
+       It does not overlap if its right side is before the newly added SACK,
+       or if its left side is after the newly added SACK.
+       NOTE: The equality should not really happen, but it doesn't hurt. */
+    if (TCP_SEQ_LEQ(pcb->rcv_sacks[i].right, left) || TCP_SEQ_LEQ(right, pcb->rcv_sacks[i].left)) {
+      if (unused_idx != i) {
+        /* We don't need to copy if it's already in the right spot */
+        pcb->rcv_sacks[unused_idx] = pcb->rcv_sacks[i];
+      }
+      ++unused_idx;
+    }
+  }
+
+  /* Now 'unused_idx' is the index of the first invalid SACK entry,
+     anywhere between 0 (no valid entries) and LWIP_TCP_MAX_SACK_NUM (all entries are valid).
+     We want to clear this and all following SACKs.
+     However, we will be adding another one in the front (and shifting everything else back).
+     So let's just iterate from the back, and set each entry to the one to the left if it's valid,
+     or to 0 if it is not. */
+  for (i = LWIP_TCP_MAX_SACK_NUM - 1; i > 0; --i) {
+    /* [i] is the index we are setting, and the value should be at index [i-1],
+       or 0 if that index is unused (>= unused_idx). */
+    if (i - 1 >= unused_idx) {
+      /* [i-1] is unused. Let's clear [i]. */
+      pcb->rcv_sacks[i].left = pcb->rcv_sacks[i].right = 0;
+    } else {
+      pcb->rcv_sacks[i] = pcb->rcv_sacks[i - 1];
+    }
+  }
+
+  /* And now we can store the newest SACK */
+  pcb->rcv_sacks[0].left = left;
+  pcb->rcv_sacks[0].right = right;
+}
+
+/**
+ * Called to remove a range of SACKs.
+ *
+ * SACK entries will be removed or adjusted to not acknowledge any sequence
+ * numbers that are less than 'seq' passed. It not only invalidates entries,
+ * but also moves all entries that are still valid to the beginning.
+ *
+ * @param pcb the tcp_pcb to modify
+ * @param seq the lowest sequence number to keep in SACK entries
+ */
+static void
+tcp_remove_sacks_lt(struct tcp_pcb *pcb, u32_t seq)
+{
+  u8_t i;
+  u8_t unused_idx;
+
+  /* We run this loop for all entries, until we find the first invalid one.
+     There is no point checking after that. */
+  for (i = unused_idx = 0; (i < LWIP_TCP_MAX_SACK_NUM) && LWIP_TCP_SACK_VALID(pcb, i); ++i) {
+    /* We only want to use SACK at index [i] if its right side is > 'seq'. */
+    if (TCP_SEQ_GT(pcb->rcv_sacks[i].right, seq)) {
+      if (unused_idx != i) {
+        /* We only copy it if it's not in the right spot already. */
+        pcb->rcv_sacks[unused_idx] = pcb->rcv_sacks[i];
+      }
+      /* NOTE: It is possible that its left side is < 'seq', in which case we should adjust it. */
+      if (TCP_SEQ_LT(pcb->rcv_sacks[unused_idx].left, seq)) {
+        pcb->rcv_sacks[unused_idx].left = seq;
+      }
+      ++unused_idx;
+    }
+  }
+
+  /* We also need to invalidate everything from 'unused_idx' till the end */
+  for (i = unused_idx; i < LWIP_TCP_MAX_SACK_NUM; ++i) {
+    pcb->rcv_sacks[i].left = pcb->rcv_sacks[i].right = 0;
+  }
+}
+
+#if defined(TCP_OOSEQ_BYTES_LIMIT) || defined(TCP_OOSEQ_PBUFS_LIMIT)
+/**
+ * Called to remove a range of SACKs.
+ *
+ * SACK entries will be removed or adjusted to not acknowledge any sequence
+ * numbers that are greater than (or equal to) 'seq' passed. It not only invalidates entries,
+ * but also moves all entries that are still valid to the beginning.
+ *
+ * @param pcb the tcp_pcb to modify
+ * @param seq the highest sequence number to keep in SACK entries
+ */
+static void
+tcp_remove_sacks_gt(struct tcp_pcb *pcb, u32_t seq)
+{
+  u8_t i;
+  u8_t unused_idx;
+
+  /* We run this loop for all entries, until we find the first invalid one.
+     There is no point checking after that. */
+  for (i = unused_idx = 0; (i < LWIP_TCP_MAX_SACK_NUM) && LWIP_TCP_SACK_VALID(pcb, i); ++i) {
+    /* We only want to use SACK at index [i] if its left side is < 'seq'. */
+    if (TCP_SEQ_LT(pcb->rcv_sacks[i].left, seq)) {
+      if (unused_idx != i) {
+        /* We only copy it if it's not in the right spot already. */
+        pcb->rcv_sacks[unused_idx] = pcb->rcv_sacks[i];
+      }
+      /* NOTE: It is possible that its right side is > 'seq', in which case we should adjust it. */
+      if (TCP_SEQ_GT(pcb->rcv_sacks[unused_idx].right, seq)) {
+        pcb->rcv_sacks[unused_idx].right = seq;
+      }
+      ++unused_idx;
+    }
+  }
+
+  /* We also need to invalidate everything from 'unused_idx' till the end */
+  for (i = unused_idx; i < LWIP_TCP_MAX_SACK_NUM; ++i) {
+    pcb->rcv_sacks[i].left = pcb->rcv_sacks[i].right = 0;
+  }
+}
+#endif /* TCP_OOSEQ_BYTES_LIMIT || TCP_OOSEQ_PBUFS_LIMIT */
+
+#endif /* LWIP_TCP_SACK_OUT */
+
+#endif /* LWIP_TCP */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/core/tcp_out.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/core/tcp_out.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/core/tcp_out.c	(revision 457)
@@ -0,0 +1,2190 @@
+/**
+ * @file
+ * Transmission Control Protocol, outgoing traffic
+ *
+ * The output functions of TCP.
+ *
+ * There are two distinct ways for TCP segments to get sent:
+ * - queued data: these are segments transferring data or segments containing
+ *   SYN or FIN (which both count as one sequence number). They are created as
+ *   struct @ref pbuf together with a struct tcp_seg and enqueue to the
+ *   unsent list of the pcb. They are sent by tcp_output:
+ *   - @ref tcp_write : creates data segments
+ *   - @ref tcp_split_unsent_seg : splits a data segment
+ *   - @ref tcp_enqueue_flags : creates SYN-only or FIN-only segments
+ *   - @ref tcp_output / tcp_output_segment : finalize the tcp header
+ *      (e.g. sequence numbers, options, checksum) and output to IP
+ *   - the various tcp_rexmit functions shuffle around segments between the
+ *     unsent an unacked lists to retransmit them
+ *   - tcp_create_segment and tcp_pbuf_prealloc allocate pbuf and
+ *     segment for these functions
+ * - direct send: these segments don't contain data but control the connection
+ *   behaviour. They are created as pbuf only and sent directly without
+ *   enqueueing them:
+ *   - @ref tcp_send_empty_ack sends an ACK-only segment
+ *   - @ref tcp_rst sends a RST segment
+ *   - @ref tcp_keepalive sends a keepalive segment
+ *   - @ref tcp_zero_window_probe sends a window probe segment
+ *   - tcp_output_alloc_header allocates a header-only pbuf for these functions
+ */
+
+/*
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Adam Dunkels <adam@sics.se>
+ *
+ */
+
+#include "lwip/opt.h"
+
+#if LWIP_TCP /* don't build if not configured for use in lwipopts.h */
+
+#include "lwip/priv/tcp_priv.h"
+#include "lwip/def.h"
+#include "lwip/mem.h"
+#include "lwip/memp.h"
+#include "lwip/ip_addr.h"
+#include "lwip/netif.h"
+#include "lwip/inet_chksum.h"
+#include "lwip/stats.h"
+#include "lwip/ip6.h"
+#include "lwip/ip6_addr.h"
+#if LWIP_TCP_TIMESTAMPS
+#include "lwip/sys.h"
+#endif
+
+#include <string.h>
+
+#ifdef LWIP_HOOK_FILENAME
+#include LWIP_HOOK_FILENAME
+#endif
+
+/* Allow to add custom TCP header options by defining this hook */
+#ifdef LWIP_HOOK_TCP_OUT_TCPOPT_LENGTH
+#define LWIP_TCP_OPT_LENGTH_SEGMENT(flags, pcb) LWIP_HOOK_TCP_OUT_TCPOPT_LENGTH(pcb, LWIP_TCP_OPT_LENGTH(flags))
+#else
+#define LWIP_TCP_OPT_LENGTH_SEGMENT(flags, pcb) LWIP_TCP_OPT_LENGTH(flags)
+#endif
+
+/* Define some copy-macros for checksum-on-copy so that the code looks
+   nicer by preventing too many ifdef's. */
+#if TCP_CHECKSUM_ON_COPY
+#define TCP_DATA_COPY(dst, src, len, seg) do { \
+  tcp_seg_add_chksum(LWIP_CHKSUM_COPY(dst, src, len), \
+                     len, &seg->chksum, &seg->chksum_swapped); \
+  seg->flags |= TF_SEG_DATA_CHECKSUMMED; } while(0)
+#define TCP_DATA_COPY2(dst, src, len, chksum, chksum_swapped)  \
+  tcp_seg_add_chksum(LWIP_CHKSUM_COPY(dst, src, len), len, chksum, chksum_swapped);
+#else /* TCP_CHECKSUM_ON_COPY*/
+#define TCP_DATA_COPY(dst, src, len, seg)                     MEMCPY(dst, src, len)
+#define TCP_DATA_COPY2(dst, src, len, chksum, chksum_swapped) MEMCPY(dst, src, len)
+#endif /* TCP_CHECKSUM_ON_COPY*/
+
+/** Define this to 1 for an extra check that the output checksum is valid
+ * (usefule when the checksum is generated by the application, not the stack) */
+#ifndef TCP_CHECKSUM_ON_COPY_SANITY_CHECK
+#define TCP_CHECKSUM_ON_COPY_SANITY_CHECK   0
+#endif
+/* Allow to override the failure of sanity check from warning to e.g. hard failure */
+#if TCP_CHECKSUM_ON_COPY_SANITY_CHECK
+#ifndef TCP_CHECKSUM_ON_COPY_SANITY_CHECK_FAIL
+#define TCP_CHECKSUM_ON_COPY_SANITY_CHECK_FAIL(msg) LWIP_DEBUGF(TCP_DEBUG | LWIP_DBG_LEVEL_WARNING, msg)
+#endif
+#endif
+
+#if TCP_OVERSIZE
+/** The size of segment pbufs created when TCP_OVERSIZE is enabled */
+#ifndef TCP_OVERSIZE_CALC_LENGTH
+#define TCP_OVERSIZE_CALC_LENGTH(length) ((length) + TCP_OVERSIZE)
+#endif
+#endif
+
+/* Forward declarations.*/
+static err_t tcp_output_segment(struct tcp_seg *seg, struct tcp_pcb *pcb, struct netif *netif);
+
+/* tcp_route: common code that returns a fixed bound netif or calls ip_route */
+static struct netif *
+tcp_route(const struct tcp_pcb *pcb, const ip_addr_t *src, const ip_addr_t *dst)
+{
+  LWIP_UNUSED_ARG(src); /* in case IPv4-only and source-based routing is disabled */
+
+  if ((pcb != NULL) && (pcb->netif_idx != NETIF_NO_INDEX)) {
+    return netif_get_by_index(pcb->netif_idx);
+  } else {
+    return ip_route(src, dst);
+  }
+}
+
+/**
+ * Create a TCP segment with prefilled header.
+ *
+ * Called by @ref tcp_write, @ref tcp_enqueue_flags and @ref tcp_split_unsent_seg
+ *
+ * @param pcb Protocol control block for the TCP connection.
+ * @param p pbuf that is used to hold the TCP header.
+ * @param hdrflags TCP flags for header.
+ * @param seqno TCP sequence number of this packet
+ * @param optflags options to include in TCP header
+ * @return a new tcp_seg pointing to p, or NULL.
+ * The TCP header is filled in except ackno and wnd.
+ * p is freed on failure.
+ */
+static struct tcp_seg *
+tcp_create_segment(const struct tcp_pcb *pcb, struct pbuf *p, u8_t hdrflags, u32_t seqno, u8_t optflags)
+{
+  struct tcp_seg *seg;
+  u8_t optlen;
+
+  LWIP_ASSERT("tcp_create_segment: invalid pcb", pcb != NULL);
+  LWIP_ASSERT("tcp_create_segment: invalid pbuf", p != NULL);
+
+  optlen = LWIP_TCP_OPT_LENGTH_SEGMENT(optflags, pcb);
+
+  if ((seg = (struct tcp_seg *)memp_malloc(MEMP_TCP_SEG)) == NULL) {
+    LWIP_DEBUGF(TCP_OUTPUT_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("tcp_create_segment: no memory.\n"));
+    pbuf_free(p);
+    return NULL;
+  }
+  seg->flags = optflags;
+  seg->next = NULL;
+  seg->p = p;
+  LWIP_ASSERT("p->tot_len >= optlen", p->tot_len >= optlen);
+  seg->len = p->tot_len - optlen;
+#if TCP_OVERSIZE_DBGCHECK
+  seg->oversize_left = 0;
+#endif /* TCP_OVERSIZE_DBGCHECK */
+#if TCP_CHECKSUM_ON_COPY
+  seg->chksum = 0;
+  seg->chksum_swapped = 0;
+  /* check optflags */
+  LWIP_ASSERT("invalid optflags passed: TF_SEG_DATA_CHECKSUMMED",
+              (optflags & TF_SEG_DATA_CHECKSUMMED) == 0);
+#endif /* TCP_CHECKSUM_ON_COPY */
+
+  /* build TCP header */
+  if (pbuf_add_header(p, TCP_HLEN)) {
+    LWIP_DEBUGF(TCP_OUTPUT_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("tcp_create_segment: no room for TCP header in pbuf.\n"));
+    TCP_STATS_INC(tcp.err);
+    tcp_seg_free(seg);
+    return NULL;
+  }
+  seg->tcphdr = (struct tcp_hdr *)seg->p->payload;
+  seg->tcphdr->src = lwip_htons(pcb->local_port);
+  seg->tcphdr->dest = lwip_htons(pcb->remote_port);
+  seg->tcphdr->seqno = lwip_htonl(seqno);
+  /* ackno is set in tcp_output */
+  TCPH_HDRLEN_FLAGS_SET(seg->tcphdr, (5 + optlen / 4), hdrflags);
+  /* wnd and chksum are set in tcp_output */
+  seg->tcphdr->urgp = 0;
+  return seg;
+}
+
+/**
+ * Allocate a PBUF_RAM pbuf, perhaps with extra space at the end.
+ *
+ * This function is like pbuf_alloc(layer, length, PBUF_RAM) except
+ * there may be extra bytes available at the end.
+ *
+ * Called by @ref tcp_write
+ *
+ * @param layer flag to define header size.
+ * @param length size of the pbuf's payload.
+ * @param max_length maximum usable size of payload+oversize.
+ * @param oversize pointer to a u16_t that will receive the number of usable tail bytes.
+ * @param pcb The TCP connection that will enqueue the pbuf.
+ * @param apiflags API flags given to tcp_write.
+ * @param first_seg true when this pbuf will be used in the first enqueued segment.
+ */
+#if TCP_OVERSIZE
+static struct pbuf *
+tcp_pbuf_prealloc(pbuf_layer layer, u16_t length, u16_t max_length,
+                  u16_t *oversize, const struct tcp_pcb *pcb, u8_t apiflags,
+                  u8_t first_seg)
+{
+  struct pbuf *p;
+  u16_t alloc = length;
+
+  LWIP_ASSERT("tcp_pbuf_prealloc: invalid oversize", oversize != NULL);
+  LWIP_ASSERT("tcp_pbuf_prealloc: invalid pcb", pcb != NULL);
+
+#if LWIP_NETIF_TX_SINGLE_PBUF
+  LWIP_UNUSED_ARG(max_length);
+  LWIP_UNUSED_ARG(pcb);
+  LWIP_UNUSED_ARG(apiflags);
+  LWIP_UNUSED_ARG(first_seg);
+  alloc = max_length;
+#else /* LWIP_NETIF_TX_SINGLE_PBUF */
+  if (length < max_length) {
+    /* Should we allocate an oversized pbuf, or just the minimum
+     * length required? If tcp_write is going to be called again
+     * before this segment is transmitted, we want the oversized
+     * buffer. If the segment will be transmitted immediately, we can
+     * save memory by allocating only length. We use a simple
+     * heuristic based on the following information:
+     *
+     * Did the user set TCP_WRITE_FLAG_MORE?
+     *
+     * Will the Nagle algorithm defer transmission of this segment?
+     */
+    if ((apiflags & TCP_WRITE_FLAG_MORE) ||
+        (!(pcb->flags & TF_NODELAY) &&
+         (!first_seg ||
+          pcb->unsent != NULL ||
+          pcb->unacked != NULL))) {
+      alloc = LWIP_MIN(max_length, LWIP_MEM_ALIGN_SIZE(TCP_OVERSIZE_CALC_LENGTH(length)));
+    }
+  }
+#endif /* LWIP_NETIF_TX_SINGLE_PBUF */
+  p = pbuf_alloc(layer, alloc, PBUF_RAM);
+  if (p == NULL) {
+    return NULL;
+  }
+  LWIP_ASSERT("need unchained pbuf", p->next == NULL);
+  *oversize = p->len - length;
+  /* trim p->len to the currently used size */
+  p->len = p->tot_len = length;
+  return p;
+}
+#else /* TCP_OVERSIZE */
+#define tcp_pbuf_prealloc(layer, length, mx, os, pcb, api, fst) pbuf_alloc((layer), (length), PBUF_RAM)
+#endif /* TCP_OVERSIZE */
+
+#if TCP_CHECKSUM_ON_COPY
+/** Add a checksum of newly added data to the segment.
+ *
+ * Called by tcp_write and tcp_split_unsent_seg.
+ */
+static void
+tcp_seg_add_chksum(u16_t chksum, u16_t len, u16_t *seg_chksum,
+                   u8_t *seg_chksum_swapped)
+{
+  u32_t helper;
+  /* add chksum to old chksum and fold to u16_t */
+  helper = chksum + *seg_chksum;
+  chksum = FOLD_U32T(helper);
+  if ((len & 1) != 0) {
+    *seg_chksum_swapped = 1 - *seg_chksum_swapped;
+    chksum = SWAP_BYTES_IN_WORD(chksum);
+  }
+  *seg_chksum = chksum;
+}
+#endif /* TCP_CHECKSUM_ON_COPY */
+
+/** Checks if tcp_write is allowed or not (checks state, snd_buf and snd_queuelen).
+ *
+ * @param pcb the tcp pcb to check for
+ * @param len length of data to send (checked agains snd_buf)
+ * @return ERR_OK if tcp_write is allowed to proceed, another err_t otherwise
+ */
+static err_t
+tcp_write_checks(struct tcp_pcb *pcb, u16_t len)
+{
+  LWIP_ASSERT("tcp_write_checks: invalid pcb", pcb != NULL);
+
+  /* connection is in invalid state for data transmission? */
+  if ((pcb->state != ESTABLISHED) &&
+      (pcb->state != CLOSE_WAIT) &&
+      (pcb->state != SYN_SENT) &&
+      (pcb->state != SYN_RCVD)) {
+    LWIP_DEBUGF(TCP_OUTPUT_DEBUG | LWIP_DBG_STATE | LWIP_DBG_LEVEL_SEVERE, ("tcp_write() called in invalid state\n"));
+    return ERR_CONN;
+  } else if (len == 0) {
+    return ERR_OK;
+  }
+
+  /* fail on too much data */
+  if (len > pcb->snd_buf) {
+    LWIP_DEBUGF(TCP_OUTPUT_DEBUG | LWIP_DBG_LEVEL_SEVERE, ("tcp_write: too much data (len=%"U16_F" > snd_buf=%"TCPWNDSIZE_F")\n",
+                len, pcb->snd_buf));
+    tcp_set_flags(pcb, TF_NAGLEMEMERR);
+    return ERR_MEM;
+  }
+
+  LWIP_DEBUGF(TCP_QLEN_DEBUG, ("tcp_write: queuelen: %"TCPWNDSIZE_F"\n", (tcpwnd_size_t)pcb->snd_queuelen));
+
+  /* If total number of pbufs on the unsent/unacked queues exceeds the
+   * configured maximum, return an error */
+  /* check for configured max queuelen and possible overflow */
+  if (pcb->snd_queuelen >= LWIP_MIN(TCP_SND_QUEUELEN, (TCP_SNDQUEUELEN_OVERFLOW + 1))) {
+    LWIP_DEBUGF(TCP_OUTPUT_DEBUG | LWIP_DBG_LEVEL_SEVERE, ("tcp_write: too long queue %"U16_F" (max %"U16_F")\n",
+                pcb->snd_queuelen, (u16_t)TCP_SND_QUEUELEN));
+    TCP_STATS_INC(tcp.memerr);
+    tcp_set_flags(pcb, TF_NAGLEMEMERR);
+    return ERR_MEM;
+  }
+  if (pcb->snd_queuelen != 0) {
+    LWIP_ASSERT("tcp_write: pbufs on queue => at least one queue non-empty",
+                pcb->unacked != NULL || pcb->unsent != NULL);
+  } else {
+    LWIP_ASSERT("tcp_write: no pbufs on queue => both queues empty",
+                pcb->unacked == NULL && pcb->unsent == NULL);
+  }
+  return ERR_OK;
+}
+
+/**
+ * @ingroup tcp_raw
+ * Write data for sending (but does not send it immediately).
+ *
+ * It waits in the expectation of more data being sent soon (as
+ * it can send them more efficiently by combining them together).
+ * To prompt the system to send data now, call tcp_output() after
+ * calling tcp_write().
+ * 
+ * This function enqueues the data pointed to by the argument dataptr. The length of
+ * the data is passed as the len parameter. The apiflags can be one or more of:
+ * - TCP_WRITE_FLAG_COPY: indicates whether the new memory should be allocated
+ *   for the data to be copied into. If this flag is not given, no new memory
+ *   should be allocated and the data should only be referenced by pointer. This
+ *   also means that the memory behind dataptr must not change until the data is
+ *   ACKed by the remote host
+ * - TCP_WRITE_FLAG_MORE: indicates that more data follows. If this is omitted,
+ *   the PSH flag is set in the last segment created by this call to tcp_write.
+ *   If this flag is given, the PSH flag is not set.
+ *
+ * The tcp_write() function will fail and return ERR_MEM if the length
+ * of the data exceeds the current send buffer size or if the length of
+ * the queue of outgoing segment is larger than the upper limit defined
+ * in lwipopts.h. The number of bytes available in the output queue can
+ * be retrieved with the tcp_sndbuf() function.
+ *
+ * The proper way to use this function is to call the function with at
+ * most tcp_sndbuf() bytes of data. If the function returns ERR_MEM,
+ * the application should wait until some of the currently enqueued
+ * data has been successfully received by the other host and try again.
+ *
+ * @param pcb Protocol control block for the TCP connection to enqueue data for.
+ * @param arg Pointer to the data to be enqueued for sending.
+ * @param len Data length in bytes
+ * @param apiflags combination of following flags :
+ * - TCP_WRITE_FLAG_COPY (0x01) data will be copied into memory belonging to the stack
+ * - TCP_WRITE_FLAG_MORE (0x02) for TCP connection, PSH flag will not be set on last segment sent,
+ * @return ERR_OK if enqueued, another err_t on error
+ */
+err_t
+tcp_write(struct tcp_pcb *pcb, const void *arg, u16_t len, u8_t apiflags)
+{
+  struct pbuf *concat_p = NULL;
+  struct tcp_seg *last_unsent = NULL, *seg = NULL, *prev_seg = NULL, *queue = NULL;
+  u16_t pos = 0; /* position in 'arg' data */
+  u16_t queuelen;
+  u8_t optlen;
+  u8_t optflags = 0;
+#if TCP_OVERSIZE
+  u16_t oversize = 0;
+  u16_t oversize_used = 0;
+#if TCP_OVERSIZE_DBGCHECK
+  u16_t oversize_add = 0;
+#endif /* TCP_OVERSIZE_DBGCHECK*/
+#endif /* TCP_OVERSIZE */
+  u16_t extendlen = 0;
+#if TCP_CHECKSUM_ON_COPY
+  u16_t concat_chksum = 0;
+  u8_t concat_chksum_swapped = 0;
+  u16_t concat_chksummed = 0;
+#endif /* TCP_CHECKSUM_ON_COPY */
+  err_t err;
+  u16_t mss_local;
+
+  LWIP_ERROR("tcp_write: invalid pcb", pcb != NULL, return ERR_ARG);
+
+  /* don't allocate segments bigger than half the maximum window we ever received */
+  mss_local = LWIP_MIN(pcb->mss, TCPWND_MIN16(pcb->snd_wnd_max / 2));
+  mss_local = mss_local ? mss_local : pcb->mss;
+
+  LWIP_ASSERT_CORE_LOCKED();
+
+#if LWIP_NETIF_TX_SINGLE_PBUF
+  /* Always copy to try to create single pbufs for TX */
+  apiflags |= TCP_WRITE_FLAG_COPY;
+#endif /* LWIP_NETIF_TX_SINGLE_PBUF */
+
+  LWIP_DEBUGF(TCP_OUTPUT_DEBUG, ("tcp_write(pcb=%p, data=%p, len=%"U16_F", apiflags=%"U16_F")\n",
+                                 (void *)pcb, arg, len, (u16_t)apiflags));
+  LWIP_ERROR("tcp_write: arg == NULL (programmer violates API)",
+             arg != NULL, return ERR_ARG;);
+
+  err = tcp_write_checks(pcb, len);
+  if (err != ERR_OK) {
+    return err;
+  }
+  queuelen = pcb->snd_queuelen;
+
+#if LWIP_TCP_TIMESTAMPS
+  if ((pcb->flags & TF_TIMESTAMP)) {
+    /* Make sure the timestamp option is only included in data segments if we
+       agreed about it with the remote host. */
+    optflags = TF_SEG_OPTS_TS;
+    optlen = LWIP_TCP_OPT_LENGTH_SEGMENT(TF_SEG_OPTS_TS, pcb);
+    /* ensure that segments can hold at least one data byte... */
+    mss_local = LWIP_MAX(mss_local, LWIP_TCP_OPT_LEN_TS + 1);
+  } else
+#endif /* LWIP_TCP_TIMESTAMPS */
+  {
+    optlen = LWIP_TCP_OPT_LENGTH_SEGMENT(0, pcb);
+  }
+
+
+  /*
+   * TCP segmentation is done in three phases with increasing complexity:
+   *
+   * 1. Copy data directly into an oversized pbuf.
+   * 2. Chain a new pbuf to the end of pcb->unsent.
+   * 3. Create new segments.
+   *
+   * We may run out of memory at any point. In that case we must
+   * return ERR_MEM and not change anything in pcb. Therefore, all
+   * changes are recorded in local variables and committed at the end
+   * of the function. Some pcb fields are maintained in local copies:
+   *
+   * queuelen = pcb->snd_queuelen
+   * oversize = pcb->unsent_oversize
+   *
+   * These variables are set consistently by the phases:
+   *
+   * seg points to the last segment tampered with.
+   *
+   * pos records progress as data is segmented.
+   */
+
+  /* Find the tail of the unsent queue. */
+  if (pcb->unsent != NULL) {
+    u16_t space;
+    u16_t unsent_optlen;
+
+    /* @todo: this could be sped up by keeping last_unsent in the pcb */
+    for (last_unsent = pcb->unsent; last_unsent->next != NULL;
+         last_unsent = last_unsent->next);
+
+    /* Usable space at the end of the last unsent segment */
+    unsent_optlen = LWIP_TCP_OPT_LENGTH_SEGMENT(last_unsent->flags, pcb);
+    LWIP_ASSERT("mss_local is too small", mss_local >= last_unsent->len + unsent_optlen);
+    space = mss_local - (last_unsent->len + unsent_optlen);
+
+    /*
+     * Phase 1: Copy data directly into an oversized pbuf.
+     *
+     * The number of bytes copied is recorded in the oversize_used
+     * variable. The actual copying is done at the bottom of the
+     * function.
+     */
+#if TCP_OVERSIZE
+#if TCP_OVERSIZE_DBGCHECK
+    /* check that pcb->unsent_oversize matches last_unsent->oversize_left */
+    LWIP_ASSERT("unsent_oversize mismatch (pcb vs. last_unsent)",
+                pcb->unsent_oversize == last_unsent->oversize_left);
+#endif /* TCP_OVERSIZE_DBGCHECK */
+    oversize = pcb->unsent_oversize;
+    if (oversize > 0) {
+      LWIP_ASSERT("inconsistent oversize vs. space", oversize <= space);
+      seg = last_unsent;
+      oversize_used = LWIP_MIN(space, LWIP_MIN(oversize, len));
+      pos += oversize_used;
+      oversize -= oversize_used;
+      space -= oversize_used;
+    }
+    /* now we are either finished or oversize is zero */
+    LWIP_ASSERT("inconsistent oversize vs. len", (oversize == 0) || (pos == len));
+#endif /* TCP_OVERSIZE */
+
+#if !LWIP_NETIF_TX_SINGLE_PBUF
+    /*
+     * Phase 2: Chain a new pbuf to the end of pcb->unsent.
+     *
+     * As an exception when NOT copying the data, if the given data buffer
+     * directly follows the last unsent data buffer in memory, extend the last
+     * ROM pbuf reference to the buffer, thus saving a ROM pbuf allocation.
+     *
+     * We don't extend segments containing SYN/FIN flags or options
+     * (len==0). The new pbuf is kept in concat_p and pbuf_cat'ed at
+     * the end.
+     *
+     * This phase is skipped for LWIP_NETIF_TX_SINGLE_PBUF as we could only execute
+     * it after rexmit puts a segment from unacked to unsent and at this point,
+     * oversize info is lost.
+     */
+    if ((pos < len) && (space > 0) && (last_unsent->len > 0)) {
+      u16_t seglen = LWIP_MIN(space, len - pos);
+      seg = last_unsent;
+
+      /* Create a pbuf with a copy or reference to seglen bytes. We
+       * can use PBUF_RAW here since the data appears in the middle of
+       * a segment. A header will never be prepended. */
+      if (apiflags & TCP_WRITE_FLAG_COPY) {
+        /* Data is copied */
+        if ((concat_p = tcp_pbuf_prealloc(PBUF_RAW, seglen, space, &oversize, pcb, apiflags, 1)) == NULL) {
+          LWIP_DEBUGF(TCP_OUTPUT_DEBUG | LWIP_DBG_LEVEL_SERIOUS,
+                      ("tcp_write : could not allocate memory for pbuf copy size %"U16_F"\n",
+                       seglen));
+          goto memerr;
+        }
+#if TCP_OVERSIZE_DBGCHECK
+        oversize_add = oversize;
+#endif /* TCP_OVERSIZE_DBGCHECK */
+        TCP_DATA_COPY2(concat_p->payload, (const u8_t *)arg + pos, seglen, &concat_chksum, &concat_chksum_swapped);
+#if TCP_CHECKSUM_ON_COPY
+        concat_chksummed += seglen;
+#endif /* TCP_CHECKSUM_ON_COPY */
+        queuelen += pbuf_clen(concat_p);
+      } else {
+        /* Data is not copied */
+        /* If the last unsent pbuf is of type PBUF_ROM, try to extend it. */
+        struct pbuf *p;
+        for (p = last_unsent->p; p->next != NULL; p = p->next);
+        if (((p->type_internal & (PBUF_TYPE_FLAG_STRUCT_DATA_CONTIGUOUS | PBUF_TYPE_FLAG_DATA_VOLATILE)) == 0) &&
+            (const u8_t *)p->payload + p->len == (const u8_t *)arg) {
+          LWIP_ASSERT("tcp_write: ROM pbufs cannot be oversized", pos == 0);
+          extendlen = seglen;
+        } else {
+          if ((concat_p = pbuf_alloc(PBUF_RAW, seglen, PBUF_ROM)) == NULL) {
+            LWIP_DEBUGF(TCP_OUTPUT_DEBUG | LWIP_DBG_LEVEL_SERIOUS,
+                        ("tcp_write: could not allocate memory for zero-copy pbuf\n"));
+            goto memerr;
+          }
+          /* reference the non-volatile payload data */
+          ((struct pbuf_rom *)concat_p)->payload = (const u8_t *)arg + pos;
+          queuelen += pbuf_clen(concat_p);
+        }
+#if TCP_CHECKSUM_ON_COPY
+        /* calculate the checksum of nocopy-data */
+        tcp_seg_add_chksum(~inet_chksum((const u8_t *)arg + pos, seglen), seglen,
+                           &concat_chksum, &concat_chksum_swapped);
+        concat_chksummed += seglen;
+#endif /* TCP_CHECKSUM_ON_COPY */
+      }
+
+      pos += seglen;
+    }
+#endif /* !LWIP_NETIF_TX_SINGLE_PBUF */
+  } else {
+#if TCP_OVERSIZE
+    LWIP_ASSERT("unsent_oversize mismatch (pcb->unsent is NULL)",
+                pcb->unsent_oversize == 0);
+#endif /* TCP_OVERSIZE */
+  }
+
+  /*
+   * Phase 3: Create new segments.
+   *
+   * The new segments are chained together in the local 'queue'
+   * variable, ready to be appended to pcb->unsent.
+   */
+  while (pos < len) {
+    struct pbuf *p;
+    u16_t left = len - pos;
+    u16_t max_len = mss_local - optlen;
+    u16_t seglen = LWIP_MIN(left, max_len);
+#if TCP_CHECKSUM_ON_COPY
+    u16_t chksum = 0;
+    u8_t chksum_swapped = 0;
+#endif /* TCP_CHECKSUM_ON_COPY */
+
+    if (apiflags & TCP_WRITE_FLAG_COPY) {
+      /* If copy is set, memory should be allocated and data copied
+       * into pbuf */
+      if ((p = tcp_pbuf_prealloc(PBUF_TRANSPORT, seglen + optlen, mss_local, &oversize, pcb, apiflags, queue == NULL)) == NULL) {
+        LWIP_DEBUGF(TCP_OUTPUT_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("tcp_write : could not allocate memory for pbuf copy size %"U16_F"\n", seglen));
+        goto memerr;
+      }
+      LWIP_ASSERT("tcp_write: check that first pbuf can hold the complete seglen",
+                  (p->len >= seglen));
+      TCP_DATA_COPY2((char *)p->payload + optlen, (const u8_t *)arg + pos, seglen, &chksum, &chksum_swapped);
+    } else {
+      /* Copy is not set: First allocate a pbuf for holding the data.
+       * Since the referenced data is available at least until it is
+       * sent out on the link (as it has to be ACKed by the remote
+       * party) we can safely use PBUF_ROM instead of PBUF_REF here.
+       */
+      struct pbuf *p2;
+#if TCP_OVERSIZE
+      LWIP_ASSERT("oversize == 0", oversize == 0);
+#endif /* TCP_OVERSIZE */
+      if ((p2 = pbuf_alloc(PBUF_TRANSPORT, seglen, PBUF_ROM)) == NULL) {
+        LWIP_DEBUGF(TCP_OUTPUT_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("tcp_write: could not allocate memory for zero-copy pbuf\n"));
+        goto memerr;
+      }
+#if TCP_CHECKSUM_ON_COPY
+      /* calculate the checksum of nocopy-data */
+      chksum = ~inet_chksum((const u8_t *)arg + pos, seglen);
+      if (seglen & 1) {
+        chksum_swapped = 1;
+        chksum = SWAP_BYTES_IN_WORD(chksum);
+      }
+#endif /* TCP_CHECKSUM_ON_COPY */
+      /* reference the non-volatile payload data */
+      ((struct pbuf_rom *)p2)->payload = (const u8_t *)arg + pos;
+
+      /* Second, allocate a pbuf for the headers. */
+      if ((p = pbuf_alloc(PBUF_TRANSPORT, optlen, PBUF_RAM)) == NULL) {
+        /* If allocation fails, we have to deallocate the data pbuf as
+         * well. */
+        pbuf_free(p2);
+        LWIP_DEBUGF(TCP_OUTPUT_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("tcp_write: could not allocate memory for header pbuf\n"));
+        goto memerr;
+      }
+      /* Concatenate the headers and data pbufs together. */
+      pbuf_cat(p/*header*/, p2/*data*/);
+    }
+
+    queuelen += pbuf_clen(p);
+
+    /* Now that there are more segments queued, we check again if the
+     * length of the queue exceeds the configured maximum or
+     * overflows. */
+    if (queuelen > LWIP_MIN(TCP_SND_QUEUELEN, TCP_SNDQUEUELEN_OVERFLOW)) {
+      LWIP_DEBUGF(TCP_OUTPUT_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("tcp_write: queue too long %"U16_F" (%d)\n",
+                  queuelen, (int)TCP_SND_QUEUELEN));
+      pbuf_free(p);
+      goto memerr;
+    }
+
+    if ((seg = tcp_create_segment(pcb, p, 0, pcb->snd_lbb + pos, optflags)) == NULL) {
+      goto memerr;
+    }
+#if TCP_OVERSIZE_DBGCHECK
+    seg->oversize_left = oversize;
+#endif /* TCP_OVERSIZE_DBGCHECK */
+#if TCP_CHECKSUM_ON_COPY
+    seg->chksum = chksum;
+    seg->chksum_swapped = chksum_swapped;
+    seg->flags |= TF_SEG_DATA_CHECKSUMMED;
+#endif /* TCP_CHECKSUM_ON_COPY */
+
+    /* first segment of to-be-queued data? */
+    if (queue == NULL) {
+      queue = seg;
+    } else {
+      /* Attach the segment to the end of the queued segments */
+      LWIP_ASSERT("prev_seg != NULL", prev_seg != NULL);
+      prev_seg->next = seg;
+    }
+    /* remember last segment of to-be-queued data for next iteration */
+    prev_seg = seg;
+
+    LWIP_DEBUGF(TCP_OUTPUT_DEBUG | LWIP_DBG_TRACE, ("tcp_write: queueing %"U32_F":%"U32_F"\n",
+                lwip_ntohl(seg->tcphdr->seqno),
+                lwip_ntohl(seg->tcphdr->seqno) + TCP_TCPLEN(seg)));
+
+    pos += seglen;
+  }
+
+  /*
+   * All three segmentation phases were successful. We can commit the
+   * transaction.
+   */
+#if TCP_OVERSIZE_DBGCHECK
+  if ((last_unsent != NULL) && (oversize_add != 0)) {
+    last_unsent->oversize_left += oversize_add;
+  }
+#endif /* TCP_OVERSIZE_DBGCHECK */
+
+  /*
+   * Phase 1: If data has been added to the preallocated tail of
+   * last_unsent, we update the length fields of the pbuf chain.
+   */
+#if TCP_OVERSIZE
+  if (oversize_used > 0) {
+    struct pbuf *p;
+    /* Bump tot_len of whole chain, len of tail */
+    for (p = last_unsent->p; p; p = p->next) {
+      p->tot_len += oversize_used;
+      if (p->next == NULL) {
+        TCP_DATA_COPY((char *)p->payload + p->len, arg, oversize_used, last_unsent);
+        p->len += oversize_used;
+      }
+    }
+    last_unsent->len += oversize_used;
+#if TCP_OVERSIZE_DBGCHECK
+    LWIP_ASSERT("last_unsent->oversize_left >= oversize_used",
+                last_unsent->oversize_left >= oversize_used);
+    last_unsent->oversize_left -= oversize_used;
+#endif /* TCP_OVERSIZE_DBGCHECK */
+  }
+  pcb->unsent_oversize = oversize;
+#endif /* TCP_OVERSIZE */
+
+  /*
+   * Phase 2: concat_p can be concatenated onto last_unsent->p, unless we
+   * determined that the last ROM pbuf can be extended to include the new data.
+   */
+  if (concat_p != NULL) {
+    LWIP_ASSERT("tcp_write: cannot concatenate when pcb->unsent is empty",
+                (last_unsent != NULL));
+    pbuf_cat(last_unsent->p, concat_p);
+    last_unsent->len += concat_p->tot_len;
+  } else if (extendlen > 0) {
+    struct pbuf *p;
+    LWIP_ASSERT("tcp_write: extension of reference requires reference",
+                last_unsent != NULL && last_unsent->p != NULL);
+    for (p = last_unsent->p; p->next != NULL; p = p->next) {
+      p->tot_len += extendlen;
+    }
+    p->tot_len += extendlen;
+    p->len += extendlen;
+    last_unsent->len += extendlen;
+  }
+
+#if TCP_CHECKSUM_ON_COPY
+  if (concat_chksummed) {
+    LWIP_ASSERT("tcp_write: concat checksum needs concatenated data",
+                concat_p != NULL || extendlen > 0);
+    /*if concat checksumm swapped - swap it back */
+    if (concat_chksum_swapped) {
+      concat_chksum = SWAP_BYTES_IN_WORD(concat_chksum);
+    }
+    tcp_seg_add_chksum(concat_chksum, concat_chksummed, &last_unsent->chksum,
+                       &last_unsent->chksum_swapped);
+    last_unsent->flags |= TF_SEG_DATA_CHECKSUMMED;
+  }
+#endif /* TCP_CHECKSUM_ON_COPY */
+
+  /*
+   * Phase 3: Append queue to pcb->unsent. Queue may be NULL, but that
+   * is harmless
+   */
+  if (last_unsent == NULL) {
+    pcb->unsent = queue;
+  } else {
+    last_unsent->next = queue;
+  }
+
+  /*
+   * Finally update the pcb state.
+   */
+  pcb->snd_lbb += len;
+  pcb->snd_buf -= len;
+  pcb->snd_queuelen = queuelen;
+
+  LWIP_DEBUGF(TCP_QLEN_DEBUG, ("tcp_write: %"S16_F" (after enqueued)\n",
+                               pcb->snd_queuelen));
+  if (pcb->snd_queuelen != 0) {
+    LWIP_ASSERT("tcp_write: valid queue length",
+                pcb->unacked != NULL || pcb->unsent != NULL);
+  }
+
+  /* Set the PSH flag in the last segment that we enqueued. */
+  if (seg != NULL && seg->tcphdr != NULL && ((apiflags & TCP_WRITE_FLAG_MORE) == 0)) {
+    TCPH_SET_FLAG(seg->tcphdr, TCP_PSH);
+  }
+
+  return ERR_OK;
+memerr:
+  tcp_set_flags(pcb, TF_NAGLEMEMERR);
+  TCP_STATS_INC(tcp.memerr);
+
+  if (concat_p != NULL) {
+    pbuf_free(concat_p);
+  }
+  if (queue != NULL) {
+    tcp_segs_free(queue);
+  }
+  if (pcb->snd_queuelen != 0) {
+    LWIP_ASSERT("tcp_write: valid queue length", pcb->unacked != NULL ||
+                pcb->unsent != NULL);
+  }
+  LWIP_DEBUGF(TCP_QLEN_DEBUG | LWIP_DBG_STATE, ("tcp_write: %"S16_F" (with mem err)\n", pcb->snd_queuelen));
+  return ERR_MEM;
+}
+
+/**
+ * Split segment on the head of the unsent queue.  If return is not
+ * ERR_OK, existing head remains intact
+ *
+ * The split is accomplished by creating a new TCP segment and pbuf
+ * which holds the remainder payload after the split.  The original
+ * pbuf is trimmed to new length.  This allows splitting of read-only
+ * pbufs
+ *
+ * @param pcb the tcp_pcb for which to split the unsent head
+ * @param split the amount of payload to remain in the head
+ */
+err_t
+tcp_split_unsent_seg(struct tcp_pcb *pcb, u16_t split)
+{
+  struct tcp_seg *seg = NULL, *useg = NULL;
+  struct pbuf *p = NULL;
+  u8_t optlen;
+  u8_t optflags;
+  u8_t split_flags;
+  u8_t remainder_flags;
+  u16_t remainder;
+  u16_t offset;
+#if TCP_CHECKSUM_ON_COPY
+  u16_t chksum = 0;
+  u8_t chksum_swapped = 0;
+  struct pbuf *q;
+#endif /* TCP_CHECKSUM_ON_COPY */
+
+  LWIP_ASSERT("tcp_split_unsent_seg: invalid pcb", pcb != NULL);
+
+  useg = pcb->unsent;
+  if (useg == NULL) {
+    return ERR_MEM;
+  }
+
+  if (split == 0) {
+    LWIP_ASSERT("Can't split segment into length 0", 0);
+    return ERR_VAL;
+  }
+
+  if (useg->len <= split) {
+    return ERR_OK;
+  }
+
+  LWIP_ASSERT("split <= mss", split <= pcb->mss);
+  LWIP_ASSERT("useg->len > 0", useg->len > 0);
+
+  /* We should check that we don't exceed TCP_SND_QUEUELEN but we need
+   * to split this packet so we may actually exceed the max value by
+   * one!
+   */
+  LWIP_DEBUGF(TCP_QLEN_DEBUG, ("tcp_enqueue: split_unsent_seg: %u\n", (unsigned int)pcb->snd_queuelen));
+
+  optflags = useg->flags;
+#if TCP_CHECKSUM_ON_COPY
+  /* Remove since checksum is not stored until after tcp_create_segment() */
+  optflags &= ~TF_SEG_DATA_CHECKSUMMED;
+#endif /* TCP_CHECKSUM_ON_COPY */
+  optlen = LWIP_TCP_OPT_LENGTH(optflags);
+  remainder = useg->len - split;
+
+  /* Create new pbuf for the remainder of the split */
+  p = pbuf_alloc(PBUF_TRANSPORT, remainder + optlen, PBUF_RAM);
+  if (p == NULL) {
+    LWIP_DEBUGF(TCP_OUTPUT_DEBUG | LWIP_DBG_LEVEL_SERIOUS,
+                ("tcp_split_unsent_seg: could not allocate memory for pbuf remainder %u\n", remainder));
+    goto memerr;
+  }
+
+  /* Offset into the original pbuf is past TCP/IP headers, options, and split amount */
+  offset = useg->p->tot_len - useg->len + split;
+  /* Copy remainder into new pbuf, headers and options will not be filled out */
+  if (pbuf_copy_partial(useg->p, (u8_t *)p->payload + optlen, remainder, offset ) != remainder) {
+    LWIP_DEBUGF(TCP_OUTPUT_DEBUG | LWIP_DBG_LEVEL_SERIOUS,
+                ("tcp_split_unsent_seg: could not copy pbuf remainder %u\n", remainder));
+    goto memerr;
+  }
+#if TCP_CHECKSUM_ON_COPY
+  /* calculate the checksum on remainder data */
+  tcp_seg_add_chksum(~inet_chksum((const u8_t *)p->payload + optlen, remainder), remainder,
+                     &chksum, &chksum_swapped);
+#endif /* TCP_CHECKSUM_ON_COPY */
+
+  /* Options are created when calling tcp_output() */
+
+  /* Migrate flags from original segment */
+  split_flags = TCPH_FLAGS(useg->tcphdr);
+  remainder_flags = 0; /* ACK added in tcp_output() */
+
+  if (split_flags & TCP_PSH) {
+    split_flags &= ~TCP_PSH;
+    remainder_flags |= TCP_PSH;
+  }
+  if (split_flags & TCP_FIN) {
+    split_flags &= ~TCP_FIN;
+    remainder_flags |= TCP_FIN;
+  }
+  /* SYN should be left on split, RST should not be present with data */
+
+  seg = tcp_create_segment(pcb, p, remainder_flags, lwip_ntohl(useg->tcphdr->seqno) + split, optflags);
+  if (seg == NULL) {
+    LWIP_DEBUGF(TCP_OUTPUT_DEBUG | LWIP_DBG_LEVEL_SERIOUS,
+                ("tcp_split_unsent_seg: could not create new TCP segment\n"));
+    goto memerr;
+  }
+
+#if TCP_CHECKSUM_ON_COPY
+  seg->chksum = chksum;
+  seg->chksum_swapped = chksum_swapped;
+  seg->flags |= TF_SEG_DATA_CHECKSUMMED;
+#endif /* TCP_CHECKSUM_ON_COPY */
+
+  /* Remove this segment from the queue since trimming it may free pbufs */
+  pcb->snd_queuelen -= pbuf_clen(useg->p);
+
+  /* Trim the original pbuf into our split size.  At this point our remainder segment must be setup
+  successfully because we are modifying the original segment */
+  pbuf_realloc(useg->p, useg->p->tot_len - remainder);
+  useg->len -= remainder;
+  TCPH_SET_FLAG(useg->tcphdr, split_flags);
+#if TCP_OVERSIZE_DBGCHECK
+  /* By trimming, realloc may have actually shrunk the pbuf, so clear oversize_left */
+  useg->oversize_left = 0;
+#endif /* TCP_OVERSIZE_DBGCHECK */
+
+  /* Add back to the queue with new trimmed pbuf */
+  pcb->snd_queuelen += pbuf_clen(useg->p);
+
+#if TCP_CHECKSUM_ON_COPY
+  /* The checksum on the split segment is now incorrect. We need to re-run it over the split */
+  useg->chksum = 0;
+  useg->chksum_swapped = 0;
+  q = useg->p;
+  offset = q->tot_len - useg->len; /* Offset due to exposed headers */
+
+  /* Advance to the pbuf where the offset ends */
+  while (q != NULL && offset > q->len) {
+    offset -= q->len;
+    q = q->next;
+  }
+  LWIP_ASSERT("Found start of payload pbuf", q != NULL);
+  /* Checksum the first payload pbuf accounting for offset, then other pbufs are all payload */
+  for (; q != NULL; offset = 0, q = q->next) {
+    tcp_seg_add_chksum(~inet_chksum((const u8_t *)q->payload + offset, q->len - offset), q->len - offset,
+                       &useg->chksum, &useg->chksum_swapped);
+  }
+#endif /* TCP_CHECKSUM_ON_COPY */
+
+  /* Update number of segments on the queues. Note that length now may
+   * exceed TCP_SND_QUEUELEN! We don't have to touch pcb->snd_buf
+   * because the total amount of data is constant when packet is split */
+  pcb->snd_queuelen += pbuf_clen(seg->p);
+
+  /* Finally insert remainder into queue after split (which stays head) */
+  seg->next = useg->next;
+  useg->next = seg;
+
+#if TCP_OVERSIZE
+  /* If remainder is last segment on the unsent, ensure we clear the oversize amount
+   * because the remainder is always sized to the exact remaining amount */
+  if (seg->next == NULL) {
+    pcb->unsent_oversize = 0;
+  }
+#endif /* TCP_OVERSIZE */
+
+  return ERR_OK;
+memerr:
+  TCP_STATS_INC(tcp.memerr);
+
+  LWIP_ASSERT("seg == NULL", seg == NULL);
+  if (p != NULL) {
+    pbuf_free(p);
+  }
+
+  return ERR_MEM;
+}
+
+/**
+ * Called by tcp_close() to send a segment including FIN flag but not data.
+ * This FIN may be added to an existing segment or a new, otherwise empty
+ * segment is enqueued.
+ *
+ * @param pcb the tcp_pcb over which to send a segment
+ * @return ERR_OK if sent, another err_t otherwise
+ */
+err_t
+tcp_send_fin(struct tcp_pcb *pcb)
+{
+  LWIP_ASSERT("tcp_send_fin: invalid pcb", pcb != NULL);
+
+  /* first, try to add the fin to the last unsent segment */
+  if (pcb->unsent != NULL) {
+    struct tcp_seg *last_unsent;
+    for (last_unsent = pcb->unsent; last_unsent->next != NULL;
+         last_unsent = last_unsent->next);
+
+    if ((TCPH_FLAGS(last_unsent->tcphdr) & (TCP_SYN | TCP_FIN | TCP_RST)) == 0) {
+      /* no SYN/FIN/RST flag in the header, we can add the FIN flag */
+      TCPH_SET_FLAG(last_unsent->tcphdr, TCP_FIN);
+      tcp_set_flags(pcb, TF_FIN);
+      return ERR_OK;
+    }
+  }
+  /* no data, no length, flags, copy=1, no optdata */
+  return tcp_enqueue_flags(pcb, TCP_FIN);
+}
+
+/**
+ * Enqueue SYN or FIN for transmission.
+ *
+ * Called by @ref tcp_connect, tcp_listen_input, and @ref tcp_close
+ * (via @ref tcp_send_fin)
+ *
+ * @param pcb Protocol control block for the TCP connection.
+ * @param flags TCP header flags to set in the outgoing segment.
+ */
+err_t
+tcp_enqueue_flags(struct tcp_pcb *pcb, u8_t flags)
+{
+  struct pbuf *p;
+  struct tcp_seg *seg;
+  u8_t optflags = 0;
+  u8_t optlen = 0;
+
+  LWIP_DEBUGF(TCP_QLEN_DEBUG, ("tcp_enqueue_flags: queuelen: %"U16_F"\n", (u16_t)pcb->snd_queuelen));
+
+  LWIP_ASSERT("tcp_enqueue_flags: need either TCP_SYN or TCP_FIN in flags (programmer violates API)",
+              (flags & (TCP_SYN | TCP_FIN)) != 0);
+  LWIP_ASSERT("tcp_enqueue_flags: invalid pcb", pcb != NULL);
+
+  /* No need to check pcb->snd_queuelen if only SYN or FIN are allowed! */
+
+  /* Get options for this segment. This is a special case since this is the
+     only place where a SYN can be sent. */
+  if (flags & TCP_SYN) {
+    optflags = TF_SEG_OPTS_MSS;
+#if LWIP_WND_SCALE
+    if ((pcb->state != SYN_RCVD) || (pcb->flags & TF_WND_SCALE)) {
+      /* In a <SYN,ACK> (sent in state SYN_RCVD), the window scale option may only
+         be sent if we received a window scale option from the remote host. */
+      optflags |= TF_SEG_OPTS_WND_SCALE;
+    }
+#endif /* LWIP_WND_SCALE */
+#if LWIP_TCP_SACK_OUT
+    if ((pcb->state != SYN_RCVD) || (pcb->flags & TF_SACK)) {
+      /* In a <SYN,ACK> (sent in state SYN_RCVD), the SACK_PERM option may only
+         be sent if we received a SACK_PERM option from the remote host. */
+      optflags |= TF_SEG_OPTS_SACK_PERM;
+    }
+#endif /* LWIP_TCP_SACK_OUT */
+  }
+#if LWIP_TCP_TIMESTAMPS
+  if ((pcb->flags & TF_TIMESTAMP) || ((flags & TCP_SYN) && (pcb->state != SYN_RCVD))) {
+    /* Make sure the timestamp option is only included in data segments if we
+       agreed about it with the remote host (and in active open SYN segments). */
+    optflags |= TF_SEG_OPTS_TS;
+  }
+#endif /* LWIP_TCP_TIMESTAMPS */
+  optlen = LWIP_TCP_OPT_LENGTH_SEGMENT(optflags, pcb);
+
+  /* Allocate pbuf with room for TCP header + options */
+  if ((p = pbuf_alloc(PBUF_TRANSPORT, optlen, PBUF_RAM)) == NULL) {
+    tcp_set_flags(pcb, TF_NAGLEMEMERR);
+    TCP_STATS_INC(tcp.memerr);
+    return ERR_MEM;
+  }
+  LWIP_ASSERT("tcp_enqueue_flags: check that first pbuf can hold optlen",
+              (p->len >= optlen));
+
+  /* Allocate memory for tcp_seg, and fill in fields. */
+  if ((seg = tcp_create_segment(pcb, p, flags, pcb->snd_lbb, optflags)) == NULL) {
+    tcp_set_flags(pcb, TF_NAGLEMEMERR);
+    TCP_STATS_INC(tcp.memerr);
+    return ERR_MEM;
+  }
+  LWIP_ASSERT("seg->tcphdr not aligned", ((mem_ptr_t)seg->tcphdr % LWIP_MIN(MEM_ALIGNMENT, 4)) == 0);
+  LWIP_ASSERT("tcp_enqueue_flags: invalid segment length", seg->len == 0);
+
+  LWIP_DEBUGF(TCP_OUTPUT_DEBUG | LWIP_DBG_TRACE,
+              ("tcp_enqueue_flags: queueing %"U32_F":%"U32_F" (0x%"X16_F")\n",
+               lwip_ntohl(seg->tcphdr->seqno),
+               lwip_ntohl(seg->tcphdr->seqno) + TCP_TCPLEN(seg),
+               (u16_t)flags));
+
+  /* Now append seg to pcb->unsent queue */
+  if (pcb->unsent == NULL) {
+    pcb->unsent = seg;
+  } else {
+    struct tcp_seg *useg;
+    for (useg = pcb->unsent; useg->next != NULL; useg = useg->next);
+    useg->next = seg;
+  }
+#if TCP_OVERSIZE
+  /* The new unsent tail has no space */
+  pcb->unsent_oversize = 0;
+#endif /* TCP_OVERSIZE */
+
+  /* SYN and FIN bump the sequence number */
+  if ((flags & TCP_SYN) || (flags & TCP_FIN)) {
+    pcb->snd_lbb++;
+    /* optlen does not influence snd_buf */
+  }
+  if (flags & TCP_FIN) {
+    tcp_set_flags(pcb, TF_FIN);
+  }
+
+  /* update number of segments on the queues */
+  pcb->snd_queuelen += pbuf_clen(seg->p);
+  LWIP_DEBUGF(TCP_QLEN_DEBUG, ("tcp_enqueue_flags: %"S16_F" (after enqueued)\n", pcb->snd_queuelen));
+  if (pcb->snd_queuelen != 0) {
+    LWIP_ASSERT("tcp_enqueue_flags: invalid queue length",
+                pcb->unacked != NULL || pcb->unsent != NULL);
+  }
+
+  return ERR_OK;
+}
+
+#if LWIP_TCP_TIMESTAMPS
+/* Build a timestamp option (12 bytes long) at the specified options pointer)
+ *
+ * @param pcb tcp_pcb
+ * @param opts option pointer where to store the timestamp option
+ */
+static void
+tcp_build_timestamp_option(const struct tcp_pcb *pcb, u32_t *opts)
+{
+  LWIP_ASSERT("tcp_build_timestamp_option: invalid pcb", pcb != NULL);
+
+  /* Pad with two NOP options to make everything nicely aligned */
+  opts[0] = PP_HTONL(0x0101080A);
+  opts[1] = lwip_htonl(sys_now());
+  opts[2] = lwip_htonl(pcb->ts_recent);
+}
+#endif
+
+#if LWIP_TCP_SACK_OUT
+/**
+ * Calculates the number of SACK entries that should be generated.
+ * It takes into account whether TF_SACK flag is set,
+ * the number of SACK entries in tcp_pcb that are valid,
+ * as well as the available options size.
+ *
+ * @param pcb tcp_pcb
+ * @param optlen the length of other TCP options (in bytes)
+ * @return the number of SACK ranges that can be used
+ */
+static u8_t
+tcp_get_num_sacks(const struct tcp_pcb *pcb, u8_t optlen)
+{
+  u8_t num_sacks = 0;
+
+  LWIP_ASSERT("tcp_get_num_sacks: invalid pcb", pcb != NULL);
+
+  if (pcb->flags & TF_SACK) {
+    u8_t i;
+
+    /* The first SACK takes up 12 bytes (it includes SACK header and two NOP options),
+       each additional one - 8 bytes. */
+    optlen += 12;
+
+    /* Max options size = 40, number of SACK array entries = LWIP_TCP_MAX_SACK_NUM */
+    for (i = 0; (i < LWIP_TCP_MAX_SACK_NUM) && (optlen <= TCP_MAX_OPTION_BYTES) &&
+         LWIP_TCP_SACK_VALID(pcb, i); ++i) {
+      ++num_sacks;
+      optlen += 8;
+    }
+  }
+
+  return num_sacks;
+}
+
+/** Build a SACK option (12 or more bytes long) at the specified options pointer)
+ *
+ * @param pcb tcp_pcb
+ * @param opts option pointer where to store the SACK option
+ * @param num_sacks the number of SACKs to store
+ */
+static void
+tcp_build_sack_option(const struct tcp_pcb *pcb, u32_t *opts, u8_t num_sacks)
+{
+  u8_t i;
+
+  LWIP_ASSERT("tcp_build_sack_option: invalid pcb", pcb != NULL);
+  LWIP_ASSERT("tcp_build_sack_option: invalid opts", opts != NULL);
+
+  /* Pad with two NOP options to make everything nicely aligned.
+     We add the length (of just the SACK option, not the NOPs in front of it),
+     which is 2B of header, plus 8B for each SACK. */
+  *(opts++) = PP_HTONL(0x01010500 + 2 + num_sacks * 8);
+
+  for (i = 0; i < num_sacks; ++i) {
+    *(opts++) = lwip_htonl(pcb->rcv_sacks[i].left);
+    *(opts++) = lwip_htonl(pcb->rcv_sacks[i].right);
+  }
+}
+
+#endif
+
+#if LWIP_WND_SCALE
+/** Build a window scale option (3 bytes long) at the specified options pointer)
+ *
+ * @param opts option pointer where to store the window scale option
+ */
+static void
+tcp_build_wnd_scale_option(u32_t *opts)
+{
+  LWIP_ASSERT("tcp_build_wnd_scale_option: invalid opts", opts != NULL);
+
+  /* Pad with one NOP option to make everything nicely aligned */
+  opts[0] = PP_HTONL(0x01030300 | TCP_RCV_SCALE);
+}
+#endif
+
+/**
+ * @ingroup tcp_raw
+ * Find out what we can send and send it
+ *
+ * @param pcb Protocol control block for the TCP connection to send data
+ * @return ERR_OK if data has been sent or nothing to send
+ *         another err_t on error
+ */
+err_t
+tcp_output(struct tcp_pcb *pcb)
+{
+  struct tcp_seg *seg, *useg;
+  u32_t wnd, snd_nxt;
+  err_t err;
+  struct netif *netif;
+#if TCP_CWND_DEBUG
+  s16_t i = 0;
+#endif /* TCP_CWND_DEBUG */
+
+  LWIP_ASSERT_CORE_LOCKED();
+
+  LWIP_ASSERT("tcp_output: invalid pcb", pcb != NULL);
+  /* pcb->state LISTEN not allowed here */
+  LWIP_ASSERT("don't call tcp_output for listen-pcbs",
+              pcb->state != LISTEN);
+
+  /* First, check if we are invoked by the TCP input processing
+     code. If so, we do not output anything. Instead, we rely on the
+     input processing code to call us when input processing is done
+     with. */
+  if (tcp_input_pcb == pcb) {
+    return ERR_OK;
+  }
+
+  wnd = LWIP_MIN(pcb->snd_wnd, pcb->cwnd);
+
+  seg = pcb->unsent;
+
+  if (seg == NULL) {
+    LWIP_DEBUGF(TCP_OUTPUT_DEBUG, ("tcp_output: nothing to send (%p)\n",
+                                   (void *)pcb->unsent));
+    LWIP_DEBUGF(TCP_CWND_DEBUG, ("tcp_output: snd_wnd %"TCPWNDSIZE_F
+                                 ", cwnd %"TCPWNDSIZE_F", wnd %"U32_F
+                                 ", seg == NULL, ack %"U32_F"\n",
+                                 pcb->snd_wnd, pcb->cwnd, wnd, pcb->lastack));
+
+    /* If the TF_ACK_NOW flag is set and the ->unsent queue is empty, construct
+     * an empty ACK segment and send it. */
+    if (pcb->flags & TF_ACK_NOW) {
+      return tcp_send_empty_ack(pcb);
+    }
+    /* nothing to send: shortcut out of here */
+    goto output_done;
+  } else {
+    LWIP_DEBUGF(TCP_CWND_DEBUG,
+                ("tcp_output: snd_wnd %"TCPWNDSIZE_F", cwnd %"TCPWNDSIZE_F", wnd %"U32_F
+                 ", effwnd %"U32_F", seq %"U32_F", ack %"U32_F"\n",
+                 pcb->snd_wnd, pcb->cwnd, wnd,
+                 lwip_ntohl(seg->tcphdr->seqno) - pcb->lastack + seg->len,
+                 lwip_ntohl(seg->tcphdr->seqno), pcb->lastack));
+  }
+
+  netif = tcp_route(pcb, &pcb->local_ip, &pcb->remote_ip);
+  if (netif == NULL) {
+    return ERR_RTE;
+  }
+
+  /* If we don't have a local IP address, we get one from netif */
+  if (ip_addr_isany(&pcb->local_ip)) {
+    const ip_addr_t *local_ip = ip_netif_get_local_ip(netif, &pcb->remote_ip);
+    if (local_ip == NULL) {
+      return ERR_RTE;
+    }
+    ip_addr_copy(pcb->local_ip, *local_ip);
+  }
+
+  /* Handle the current segment not fitting within the window */
+  if (lwip_ntohl(seg->tcphdr->seqno) - pcb->lastack + seg->len > wnd) {
+    /* We need to start the persistent timer when the next unsent segment does not fit
+     * within the remaining (could be 0) send window and RTO timer is not running (we
+     * have no in-flight data). If window is still too small after persist timer fires,
+     * then we split the segment. We don't consider the congestion window since a cwnd
+     * smaller than 1 SMSS implies in-flight data
+     */
+    if (wnd == pcb->snd_wnd && pcb->unacked == NULL && pcb->persist_backoff == 0) {
+      pcb->persist_cnt = 0;
+      pcb->persist_backoff = 1;
+      pcb->persist_probe = 0;
+    }
+    /* We need an ACK, but can't send data now, so send an empty ACK */
+    if (pcb->flags & TF_ACK_NOW) {
+      return tcp_send_empty_ack(pcb);
+    }
+    goto output_done;
+  }
+  /* Stop persist timer, above conditions are not active */
+  pcb->persist_backoff = 0;
+
+  /* useg should point to last segment on unacked queue */
+  useg = pcb->unacked;
+  if (useg != NULL) {
+    for (; useg->next != NULL; useg = useg->next);
+  }
+  /* data available and window allows it to be sent? */
+  while (seg != NULL &&
+         lwip_ntohl(seg->tcphdr->seqno) - pcb->lastack + seg->len <= wnd) {
+    LWIP_ASSERT("RST not expected here!",
+                (TCPH_FLAGS(seg->tcphdr) & TCP_RST) == 0);
+    /* Stop sending if the nagle algorithm would prevent it
+     * Don't stop:
+     * - if tcp_write had a memory error before (prevent delayed ACK timeout) or
+     * - if FIN was already enqueued for this PCB (SYN is always alone in a segment -
+     *   either seg->next != NULL or pcb->unacked == NULL;
+     *   RST is no sent using tcp_write/tcp_output.
+     */
+    if ((tcp_do_output_nagle(pcb) == 0) &&
+        ((pcb->flags & (TF_NAGLEMEMERR | TF_FIN)) == 0)) {
+      break;
+    }
+#if TCP_CWND_DEBUG
+    LWIP_DEBUGF(TCP_CWND_DEBUG, ("tcp_output: snd_wnd %"TCPWNDSIZE_F", cwnd %"TCPWNDSIZE_F", wnd %"U32_F", effwnd %"U32_F", seq %"U32_F", ack %"U32_F", i %"S16_F"\n",
+                                 pcb->snd_wnd, pcb->cwnd, wnd,
+                                 lwip_ntohl(seg->tcphdr->seqno) + seg->len -
+                                 pcb->lastack,
+                                 lwip_ntohl(seg->tcphdr->seqno), pcb->lastack, i));
+    ++i;
+#endif /* TCP_CWND_DEBUG */
+
+    if (pcb->state != SYN_SENT) {
+      TCPH_SET_FLAG(seg->tcphdr, TCP_ACK);
+    }
+
+    err = tcp_output_segment(seg, pcb, netif);
+    if (err != ERR_OK) {
+      /* segment could not be sent, for whatever reason */
+      tcp_set_flags(pcb, TF_NAGLEMEMERR);
+      return err;
+    }
+#if TCP_OVERSIZE_DBGCHECK
+    seg->oversize_left = 0;
+#endif /* TCP_OVERSIZE_DBGCHECK */
+    pcb->unsent = seg->next;
+    if (pcb->state != SYN_SENT) {
+      tcp_clear_flags(pcb, TF_ACK_DELAY | TF_ACK_NOW);
+    }
+    snd_nxt = lwip_ntohl(seg->tcphdr->seqno) + TCP_TCPLEN(seg);
+    if (TCP_SEQ_LT(pcb->snd_nxt, snd_nxt)) {
+      pcb->snd_nxt = snd_nxt;
+    }
+    /* put segment on unacknowledged list if length > 0 */
+    if (TCP_TCPLEN(seg) > 0) {
+      seg->next = NULL;
+      /* unacked list is empty? */
+      if (pcb->unacked == NULL) {
+        pcb->unacked = seg;
+        useg = seg;
+        /* unacked list is not empty? */
+      } else {
+        /* In the case of fast retransmit, the packet should not go to the tail
+         * of the unacked queue, but rather somewhere before it. We need to check for
+         * this case. -STJ Jul 27, 2004 */
+        if (TCP_SEQ_LT(lwip_ntohl(seg->tcphdr->seqno), lwip_ntohl(useg->tcphdr->seqno))) {
+          /* add segment to before tail of unacked list, keeping the list sorted */
+          struct tcp_seg **cur_seg = &(pcb->unacked);
+          while (*cur_seg &&
+                 TCP_SEQ_LT(lwip_ntohl((*cur_seg)->tcphdr->seqno), lwip_ntohl(seg->tcphdr->seqno))) {
+            cur_seg = &((*cur_seg)->next );
+          }
+          seg->next = (*cur_seg);
+          (*cur_seg) = seg;
+        } else {
+          /* add segment to tail of unacked list */
+          useg->next = seg;
+          useg = useg->next;
+        }
+      }
+      /* do not queue empty segments on the unacked list */
+    } else {
+      tcp_seg_free(seg);
+    }
+    seg = pcb->unsent;
+  }
+#if TCP_OVERSIZE
+  if (pcb->unsent == NULL) {
+    /* last unsent has been removed, reset unsent_oversize */
+    pcb->unsent_oversize = 0;
+  }
+#endif /* TCP_OVERSIZE */
+
+output_done:
+  tcp_clear_flags(pcb, TF_NAGLEMEMERR);
+  return ERR_OK;
+}
+
+/** Check if a segment's pbufs are used by someone else than TCP.
+ * This can happen on retransmission if the pbuf of this segment is still
+ * referenced by the netif driver due to deferred transmission.
+ * This is the case (only!) if someone down the TX call path called
+ * pbuf_ref() on one of the pbufs!
+ *
+ * @arg seg the tcp segment to check
+ * @return 1 if ref != 1, 0 if ref == 1
+ */
+static int
+tcp_output_segment_busy(const struct tcp_seg *seg)
+{
+  LWIP_ASSERT("tcp_output_segment_busy: invalid seg", seg != NULL);
+
+  /* We only need to check the first pbuf here:
+     If a pbuf is queued for transmission, a driver calls pbuf_ref(),
+     which only changes the ref count of the first pbuf */
+  if (seg->p->ref != 1) {
+    /* other reference found */
+    return 1;
+  }
+  /* no other references found */
+  return 0;
+}
+
+/**
+ * Called by tcp_output() to actually send a TCP segment over IP.
+ *
+ * @param seg the tcp_seg to send
+ * @param pcb the tcp_pcb for the TCP connection used to send the segment
+ * @param netif the netif used to send the segment
+ */
+static err_t
+tcp_output_segment(struct tcp_seg *seg, struct tcp_pcb *pcb, struct netif *netif)
+{
+  err_t err;
+  u16_t len;
+  u32_t *opts;
+#if TCP_CHECKSUM_ON_COPY
+  int seg_chksum_was_swapped = 0;
+#endif
+
+  LWIP_ASSERT("tcp_output_segment: invalid seg", seg != NULL);
+  LWIP_ASSERT("tcp_output_segment: invalid pcb", pcb != NULL);
+  LWIP_ASSERT("tcp_output_segment: invalid netif", netif != NULL);
+
+  if (tcp_output_segment_busy(seg)) {
+    /* This should not happen: rexmit functions should have checked this.
+       However, since this function modifies p->len, we must not continue in this case. */
+    LWIP_DEBUGF(TCP_RTO_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("tcp_output_segment: segment busy\n"));
+    return ERR_OK;
+  }
+
+  /* The TCP header has already been constructed, but the ackno and
+   wnd fields remain. */
+  seg->tcphdr->ackno = lwip_htonl(pcb->rcv_nxt);
+
+  /* advertise our receive window size in this TCP segment */
+#if LWIP_WND_SCALE
+  if (seg->flags & TF_SEG_OPTS_WND_SCALE) {
+    /* The Window field in a SYN segment itself (the only type where we send
+       the window scale option) is never scaled. */
+    seg->tcphdr->wnd = lwip_htons(TCPWND_MIN16(pcb->rcv_ann_wnd));
+  } else
+#endif /* LWIP_WND_SCALE */
+  {
+    seg->tcphdr->wnd = lwip_htons(TCPWND_MIN16(RCV_WND_SCALE(pcb, pcb->rcv_ann_wnd)));
+  }
+
+  pcb->rcv_ann_right_edge = pcb->rcv_nxt + pcb->rcv_ann_wnd;
+
+  /* Add any requested options.  NB MSS option is only set on SYN
+     packets, so ignore it here */
+  /* cast through void* to get rid of alignment warnings */
+  opts = (u32_t *)(void *)(seg->tcphdr + 1);
+  if (seg->flags & TF_SEG_OPTS_MSS) {
+    u16_t mss;
+#if TCP_CALCULATE_EFF_SEND_MSS
+    mss = tcp_eff_send_mss_netif(TCP_MSS, netif, &pcb->remote_ip);
+#else /* TCP_CALCULATE_EFF_SEND_MSS */
+    mss = TCP_MSS;
+#endif /* TCP_CALCULATE_EFF_SEND_MSS */
+    *opts = TCP_BUILD_MSS_OPTION(mss);
+    opts += 1;
+  }
+#if LWIP_TCP_TIMESTAMPS
+  pcb->ts_lastacksent = pcb->rcv_nxt;
+
+  if (seg->flags & TF_SEG_OPTS_TS) {
+    tcp_build_timestamp_option(pcb, opts);
+    opts += 3;
+  }
+#endif
+#if LWIP_WND_SCALE
+  if (seg->flags & TF_SEG_OPTS_WND_SCALE) {
+    tcp_build_wnd_scale_option(opts);
+    opts += 1;
+  }
+#endif
+#if LWIP_TCP_SACK_OUT
+  if (seg->flags & TF_SEG_OPTS_SACK_PERM) {
+    /* Pad with two NOP options to make everything nicely aligned
+     * NOTE: When we send both timestamp and SACK_PERM options,
+     * we could use the first two NOPs before the timestamp to store SACK_PERM option,
+     * but that would complicate the code.
+     */
+    *(opts++) = PP_HTONL(0x01010402);
+  }
+#endif
+
+  /* Set retransmission timer running if it is not currently enabled
+     This must be set before checking the route. */
+  if (pcb->rtime < 0) {
+    pcb->rtime = 0;
+  }
+
+  if (pcb->rttest == 0) {
+    pcb->rttest = tcp_ticks;
+    pcb->rtseq = lwip_ntohl(seg->tcphdr->seqno);
+
+    LWIP_DEBUGF(TCP_RTO_DEBUG, ("tcp_output_segment: rtseq %"U32_F"\n", pcb->rtseq));
+  }
+  LWIP_DEBUGF(TCP_OUTPUT_DEBUG, ("tcp_output_segment: %"U32_F":%"U32_F"\n",
+                                 lwip_htonl(seg->tcphdr->seqno), lwip_htonl(seg->tcphdr->seqno) +
+                                 seg->len));
+
+  len = (u16_t)((u8_t *)seg->tcphdr - (u8_t *)seg->p->payload);
+  if (len == 0) {
+    /** Exclude retransmitted segments from this count. */
+    MIB2_STATS_INC(mib2.tcpoutsegs);
+  }
+
+  seg->p->len -= len;
+  seg->p->tot_len -= len;
+
+  seg->p->payload = seg->tcphdr;
+
+  seg->tcphdr->chksum = 0;
+
+#ifdef LWIP_HOOK_TCP_OUT_ADD_TCPOPTS
+  opts = LWIP_HOOK_TCP_OUT_ADD_TCPOPTS(seg->p, seg->tcphdr, pcb, opts);
+#endif
+  LWIP_ASSERT("options not filled", (u8_t *)opts == ((u8_t *)(seg->tcphdr + 1)) + LWIP_TCP_OPT_LENGTH_SEGMENT(seg->flags, pcb));
+
+#if CHECKSUM_GEN_TCP
+  IF__NETIF_CHECKSUM_ENABLED(netif, NETIF_CHECKSUM_GEN_TCP) {
+#if TCP_CHECKSUM_ON_COPY
+    u32_t acc;
+#if TCP_CHECKSUM_ON_COPY_SANITY_CHECK
+    u16_t chksum_slow = ip_chksum_pseudo(seg->p, IP_PROTO_TCP,
+                                         seg->p->tot_len, &pcb->local_ip, &pcb->remote_ip);
+#endif /* TCP_CHECKSUM_ON_COPY_SANITY_CHECK */
+    if ((seg->flags & TF_SEG_DATA_CHECKSUMMED) == 0) {
+      LWIP_ASSERT("data included but not checksummed",
+                  seg->p->tot_len == TCPH_HDRLEN_BYTES(seg->tcphdr));
+    }
+
+    /* rebuild TCP header checksum (TCP header changes for retransmissions!) */
+    acc = ip_chksum_pseudo_partial(seg->p, IP_PROTO_TCP,
+                                   seg->p->tot_len, TCPH_HDRLEN_BYTES(seg->tcphdr), &pcb->local_ip, &pcb->remote_ip);
+    /* add payload checksum */
+    if (seg->chksum_swapped) {
+      seg_chksum_was_swapped = 1;
+      seg->chksum = SWAP_BYTES_IN_WORD(seg->chksum);
+      seg->chksum_swapped = 0;
+    }
+    acc = (u16_t)~acc + seg->chksum;
+    seg->tcphdr->chksum = (u16_t)~FOLD_U32T(acc);
+#if TCP_CHECKSUM_ON_COPY_SANITY_CHECK
+    if (chksum_slow != seg->tcphdr->chksum) {
+      TCP_CHECKSUM_ON_COPY_SANITY_CHECK_FAIL(
+        ("tcp_output_segment: calculated checksum is %"X16_F" instead of %"X16_F"\n",
+         seg->tcphdr->chksum, chksum_slow));
+      seg->tcphdr->chksum = chksum_slow;
+    }
+#endif /* TCP_CHECKSUM_ON_COPY_SANITY_CHECK */
+#else /* TCP_CHECKSUM_ON_COPY */
+    seg->tcphdr->chksum = ip_chksum_pseudo(seg->p, IP_PROTO_TCP,
+                                           seg->p->tot_len, &pcb->local_ip, &pcb->remote_ip);
+#endif /* TCP_CHECKSUM_ON_COPY */
+  }
+#endif /* CHECKSUM_GEN_TCP */
+  TCP_STATS_INC(tcp.xmit);
+
+  NETIF_SET_HINTS(netif, &(pcb->netif_hints));
+  err = ip_output_if(seg->p, &pcb->local_ip, &pcb->remote_ip, pcb->ttl,
+                     pcb->tos, IP_PROTO_TCP, netif);
+  NETIF_RESET_HINTS(netif);
+
+#if TCP_CHECKSUM_ON_COPY
+  if (seg_chksum_was_swapped) {
+    /* if data is added to this segment later, chksum needs to be swapped,
+       so restore this now */
+    seg->chksum = SWAP_BYTES_IN_WORD(seg->chksum);
+    seg->chksum_swapped = 1;
+  }
+#endif
+
+  return err;
+}
+
+/**
+ * Requeue all unacked segments for retransmission
+ *
+ * Called by tcp_slowtmr() for slow retransmission.
+ *
+ * @param pcb the tcp_pcb for which to re-enqueue all unacked segments
+ */
+err_t
+tcp_rexmit_rto_prepare(struct tcp_pcb *pcb)
+{
+  struct tcp_seg *seg;
+
+  LWIP_ASSERT("tcp_rexmit_rto_prepare: invalid pcb", pcb != NULL);
+
+  if (pcb->unacked == NULL) {
+    return ERR_VAL;
+  }
+
+  /* Move all unacked segments to the head of the unsent queue.
+     However, give up if any of the unsent pbufs are still referenced by the
+     netif driver due to deferred transmission. No point loading the link further
+     if it is struggling to flush its buffered writes. */
+  for (seg = pcb->unacked; seg->next != NULL; seg = seg->next) {
+    if (tcp_output_segment_busy(seg)) {
+      LWIP_DEBUGF(TCP_RTO_DEBUG, ("tcp_rexmit_rto: segment busy\n"));
+      return ERR_VAL;
+    }
+  }
+  if (tcp_output_segment_busy(seg)) {
+    LWIP_DEBUGF(TCP_RTO_DEBUG, ("tcp_rexmit_rto: segment busy\n"));
+    return ERR_VAL;
+  }
+  /* concatenate unsent queue after unacked queue */
+  seg->next = pcb->unsent;
+#if TCP_OVERSIZE_DBGCHECK
+  /* if last unsent changed, we need to update unsent_oversize */
+  if (pcb->unsent == NULL) {
+    pcb->unsent_oversize = seg->oversize_left;
+  }
+#endif /* TCP_OVERSIZE_DBGCHECK */
+  /* unsent queue is the concatenated queue (of unacked, unsent) */
+  pcb->unsent = pcb->unacked;
+  /* unacked queue is now empty */
+  pcb->unacked = NULL;
+
+  /* Mark RTO in-progress */
+  tcp_set_flags(pcb, TF_RTO);
+  /* Record the next byte following retransmit */
+  pcb->rto_end = lwip_ntohl(seg->tcphdr->seqno) + TCP_TCPLEN(seg);
+  /* Don't take any RTT measurements after retransmitting. */
+  pcb->rttest = 0;
+
+  return ERR_OK;
+}
+
+/**
+ * Requeue all unacked segments for retransmission
+ *
+ * Called by tcp_slowtmr() for slow retransmission.
+ *
+ * @param pcb the tcp_pcb for which to re-enqueue all unacked segments
+ */
+void
+tcp_rexmit_rto_commit(struct tcp_pcb *pcb)
+{
+  LWIP_ASSERT("tcp_rexmit_rto_commit: invalid pcb", pcb != NULL);
+
+  /* increment number of retransmissions */
+  if (pcb->nrtx < 0xFF) {
+    ++pcb->nrtx;
+  }
+  /* Do the actual retransmission */
+  tcp_output(pcb);
+}
+
+/**
+ * Requeue all unacked segments for retransmission
+ *
+ * Called by tcp_process() only, tcp_slowtmr() needs to do some things between
+ * "prepare" and "commit".
+ *
+ * @param pcb the tcp_pcb for which to re-enqueue all unacked segments
+ */
+void
+tcp_rexmit_rto(struct tcp_pcb *pcb)
+{
+  LWIP_ASSERT("tcp_rexmit_rto: invalid pcb", pcb != NULL);
+
+  if (tcp_rexmit_rto_prepare(pcb) == ERR_OK) {
+    tcp_rexmit_rto_commit(pcb);
+  }
+}
+
+/**
+ * Requeue the first unacked segment for retransmission
+ *
+ * Called by tcp_receive() for fast retransmit.
+ *
+ * @param pcb the tcp_pcb for which to retransmit the first unacked segment
+ */
+err_t
+tcp_rexmit(struct tcp_pcb *pcb)
+{
+  struct tcp_seg *seg;
+  struct tcp_seg **cur_seg;
+
+  LWIP_ASSERT("tcp_rexmit: invalid pcb", pcb != NULL);
+
+  if (pcb->unacked == NULL) {
+    return ERR_VAL;
+  }
+
+  seg = pcb->unacked;
+
+  /* Give up if the segment is still referenced by the netif driver
+     due to deferred transmission. */
+  if (tcp_output_segment_busy(seg)) {
+    LWIP_DEBUGF(TCP_RTO_DEBUG, ("tcp_rexmit busy\n"));
+    return ERR_VAL;
+  }
+
+  /* Move the first unacked segment to the unsent queue */
+  /* Keep the unsent queue sorted. */
+  pcb->unacked = seg->next;
+
+  cur_seg = &(pcb->unsent);
+  while (*cur_seg &&
+         TCP_SEQ_LT(lwip_ntohl((*cur_seg)->tcphdr->seqno), lwip_ntohl(seg->tcphdr->seqno))) {
+    cur_seg = &((*cur_seg)->next );
+  }
+  seg->next = *cur_seg;
+  *cur_seg = seg;
+#if TCP_OVERSIZE
+  if (seg->next == NULL) {
+    /* the retransmitted segment is last in unsent, so reset unsent_oversize */
+    pcb->unsent_oversize = 0;
+  }
+#endif /* TCP_OVERSIZE */
+
+  if (pcb->nrtx < 0xFF) {
+    ++pcb->nrtx;
+  }
+
+  /* Don't take any rtt measurements after retransmitting. */
+  pcb->rttest = 0;
+
+  /* Do the actual retransmission. */
+  MIB2_STATS_INC(mib2.tcpretranssegs);
+  /* No need to call tcp_output: we are always called from tcp_input()
+     and thus tcp_output directly returns. */
+  return ERR_OK;
+}
+
+
+/**
+ * Handle retransmission after three dupacks received
+ *
+ * @param pcb the tcp_pcb for which to retransmit the first unacked segment
+ */
+void
+tcp_rexmit_fast(struct tcp_pcb *pcb)
+{
+  LWIP_ASSERT("tcp_rexmit_fast: invalid pcb", pcb != NULL);
+
+  if (pcb->unacked != NULL && !(pcb->flags & TF_INFR)) {
+    /* This is fast retransmit. Retransmit the first unacked segment. */
+    LWIP_DEBUGF(TCP_FR_DEBUG,
+                ("tcp_receive: dupacks %"U16_F" (%"U32_F
+                 "), fast retransmit %"U32_F"\n",
+                 (u16_t)pcb->dupacks, pcb->lastack,
+                 lwip_ntohl(pcb->unacked->tcphdr->seqno)));
+    if (tcp_rexmit(pcb) == ERR_OK) {
+      /* Set ssthresh to half of the minimum of the current
+       * cwnd and the advertised window */
+      pcb->ssthresh = LWIP_MIN(pcb->cwnd, pcb->snd_wnd) / 2;
+
+      /* The minimum value for ssthresh should be 2 MSS */
+      if (pcb->ssthresh < (2U * pcb->mss)) {
+        LWIP_DEBUGF(TCP_FR_DEBUG,
+                    ("tcp_receive: The minimum value for ssthresh %"TCPWNDSIZE_F
+                     " should be min 2 mss %"U16_F"...\n",
+                     pcb->ssthresh, (u16_t)(2 * pcb->mss)));
+        pcb->ssthresh = 2 * pcb->mss;
+      }
+
+      pcb->cwnd = pcb->ssthresh + 3 * pcb->mss;
+      tcp_set_flags(pcb, TF_INFR);
+
+      /* Reset the retransmission timer to prevent immediate rto retransmissions */
+      pcb->rtime = 0;
+    }
+  }
+}
+
+static struct pbuf *
+tcp_output_alloc_header_common(u32_t ackno, u16_t optlen, u16_t datalen,
+                        u32_t seqno_be /* already in network byte order */,
+                        u16_t src_port, u16_t dst_port, u8_t flags, u16_t wnd)
+{
+  struct tcp_hdr *tcphdr;
+  struct pbuf *p;
+
+  p = pbuf_alloc(PBUF_IP, TCP_HLEN + optlen + datalen, PBUF_RAM);
+  if (p != NULL) {
+    LWIP_ASSERT("check that first pbuf can hold struct tcp_hdr",
+                (p->len >= TCP_HLEN + optlen));
+    tcphdr = (struct tcp_hdr *)p->payload;
+    tcphdr->src = lwip_htons(src_port);
+    tcphdr->dest = lwip_htons(dst_port);
+    tcphdr->seqno = seqno_be;
+    tcphdr->ackno = lwip_htonl(ackno);
+    TCPH_HDRLEN_FLAGS_SET(tcphdr, (5 + optlen / 4), flags);
+    tcphdr->wnd = lwip_htons(wnd);
+    tcphdr->chksum = 0;
+    tcphdr->urgp = 0;
+  }
+  return p;
+}
+
+/** Allocate a pbuf and create a tcphdr at p->payload, used for output
+ * functions other than the default tcp_output -> tcp_output_segment
+ * (e.g. tcp_send_empty_ack, etc.)
+ *
+ * @param pcb tcp pcb for which to send a packet (used to initialize tcp_hdr)
+ * @param optlen length of header-options
+ * @param datalen length of tcp data to reserve in pbuf
+ * @param seqno_be seqno in network byte order (big-endian)
+ * @return pbuf with p->payload being the tcp_hdr
+ */
+static struct pbuf *
+tcp_output_alloc_header(struct tcp_pcb *pcb, u16_t optlen, u16_t datalen,
+                        u32_t seqno_be /* already in network byte order */)
+{
+  struct pbuf *p;
+
+  LWIP_ASSERT("tcp_output_alloc_header: invalid pcb", pcb != NULL);
+
+  p = tcp_output_alloc_header_common(pcb->rcv_nxt, optlen, datalen,
+    seqno_be, pcb->local_port, pcb->remote_port, TCP_ACK,
+    TCPWND_MIN16(RCV_WND_SCALE(pcb, pcb->rcv_ann_wnd)));
+  if (p != NULL) {
+    /* If we're sending a packet, update the announced right window edge */
+    pcb->rcv_ann_right_edge = pcb->rcv_nxt + pcb->rcv_ann_wnd;
+  }
+  return p;
+}
+
+/* Fill in options for control segments */
+static void
+tcp_output_fill_options(const struct tcp_pcb *pcb, struct pbuf *p, u8_t optflags, u8_t num_sacks)
+{
+  struct tcp_hdr *tcphdr;
+  u32_t *opts;
+  u16_t sacks_len = 0;
+
+  LWIP_ASSERT("tcp_output_fill_options: invalid pbuf", p != NULL);
+
+  tcphdr = (struct tcp_hdr *)p->payload;
+  opts = (u32_t *)(void *)(tcphdr + 1);
+
+  /* NB. MSS and window scale options are only sent on SYNs, so ignore them here */
+
+#if LWIP_TCP_TIMESTAMPS
+  if (optflags & TF_SEG_OPTS_TS) {
+    tcp_build_timestamp_option(pcb, opts);
+    opts += 3;
+  }
+#endif
+
+#if LWIP_TCP_SACK_OUT
+  if (pcb && (num_sacks > 0)) {
+    tcp_build_sack_option(pcb, opts, num_sacks);
+    /* 1 word for SACKs header (including 2xNOP), and 2 words for each SACK */
+    sacks_len = 1 + num_sacks * 2;
+    opts += sacks_len;
+  }
+#else
+  LWIP_UNUSED_ARG(num_sacks);
+#endif
+
+#ifdef LWIP_HOOK_TCP_OUT_ADD_TCPOPTS
+  opts = LWIP_HOOK_TCP_OUT_ADD_TCPOPTS(p, tcphdr, pcb, opts);
+#endif
+
+  LWIP_UNUSED_ARG(pcb);
+  LWIP_UNUSED_ARG(sacks_len);
+  LWIP_ASSERT("options not filled", (u8_t *)opts == ((u8_t *)(tcphdr + 1)) + sacks_len * 4 + LWIP_TCP_OPT_LENGTH_SEGMENT(optflags, pcb));
+  LWIP_UNUSED_ARG(optflags); /* for LWIP_NOASSERT */
+  LWIP_UNUSED_ARG(opts); /* for LWIP_NOASSERT */
+}
+
+/** Output a control segment pbuf to IP.
+ *
+ * Called from tcp_rst, tcp_send_empty_ack, tcp_keepalive and tcp_zero_window_probe,
+ * this function combines selecting a netif for transmission, generating the tcp
+ * header checksum and calling ip_output_if while handling netif hints and stats.
+ */
+static err_t
+tcp_output_control_segment(const struct tcp_pcb *pcb, struct pbuf *p,
+                           const ip_addr_t *src, const ip_addr_t *dst)
+{
+  err_t err;
+  struct netif *netif;
+
+  LWIP_ASSERT("tcp_output_control_segment: invalid pbuf", p != NULL);
+
+  netif = tcp_route(pcb, src, dst);
+  if (netif == NULL) {
+    err = ERR_RTE;
+  } else {
+    u8_t ttl, tos;
+#if CHECKSUM_GEN_TCP
+    IF__NETIF_CHECKSUM_ENABLED(netif, NETIF_CHECKSUM_GEN_TCP) {
+      struct tcp_hdr *tcphdr = (struct tcp_hdr *)p->payload;
+      tcphdr->chksum = ip_chksum_pseudo(p, IP_PROTO_TCP, p->tot_len,
+                                        src, dst);
+    }
+#endif
+    if (pcb != NULL) {
+      NETIF_SET_HINTS(netif, LWIP_CONST_CAST(struct netif_hint*, &(pcb->netif_hints)));
+      ttl = pcb->ttl;
+      tos = pcb->tos;
+    } else {
+      /* Send output with hardcoded TTL/HL since we have no access to the pcb */
+      ttl = TCP_TTL;
+      tos = 0;
+    }
+    TCP_STATS_INC(tcp.xmit);
+    err = ip_output_if(p, src, dst, ttl, tos, IP_PROTO_TCP, netif);
+    NETIF_RESET_HINTS(netif);
+  }
+  pbuf_free(p);
+  return err;
+}
+
+/**
+ * Send a TCP RESET packet (empty segment with RST flag set) either to
+ * abort a connection or to show that there is no matching local connection
+ * for a received segment.
+ *
+ * Called by tcp_abort() (to abort a local connection), tcp_input() (if no
+ * matching local pcb was found), tcp_listen_input() (if incoming segment
+ * has ACK flag set) and tcp_process() (received segment in the wrong state)
+ *
+ * Since a RST segment is in most cases not sent for an active connection,
+ * tcp_rst() has a number of arguments that are taken from a tcp_pcb for
+ * most other segment output functions.
+ *
+ * @param pcb TCP pcb (may be NULL if no pcb is available)
+ * @param seqno the sequence number to use for the outgoing segment
+ * @param ackno the acknowledge number to use for the outgoing segment
+ * @param local_ip the local IP address to send the segment from
+ * @param remote_ip the remote IP address to send the segment to
+ * @param local_port the local TCP port to send the segment from
+ * @param remote_port the remote TCP port to send the segment to
+ */
+void
+tcp_rst(const struct tcp_pcb *pcb, u32_t seqno, u32_t ackno,
+        const ip_addr_t *local_ip, const ip_addr_t *remote_ip,
+        u16_t local_port, u16_t remote_port)
+{
+  struct pbuf *p;
+  u16_t wnd;
+  u8_t optlen;
+
+  LWIP_ASSERT("tcp_rst: invalid local_ip", local_ip != NULL);
+  LWIP_ASSERT("tcp_rst: invalid remote_ip", remote_ip != NULL);
+
+  optlen = LWIP_TCP_OPT_LENGTH_SEGMENT(0, pcb);
+
+#if LWIP_WND_SCALE
+  wnd = PP_HTONS(((TCP_WND >> TCP_RCV_SCALE) & 0xFFFF));
+#else
+  wnd = PP_HTONS(TCP_WND);
+#endif
+
+  p = tcp_output_alloc_header_common(ackno, optlen, 0, lwip_htonl(seqno), local_port,
+    remote_port, TCP_RST | TCP_ACK, wnd);
+  if (p == NULL) {
+    LWIP_DEBUGF(TCP_DEBUG, ("tcp_rst: could not allocate memory for pbuf\n"));
+    return;
+  }
+  tcp_output_fill_options(pcb, p, 0, optlen);
+
+  MIB2_STATS_INC(mib2.tcpoutrsts);
+
+  tcp_output_control_segment(pcb, p, local_ip, remote_ip);
+  LWIP_DEBUGF(TCP_RST_DEBUG, ("tcp_rst: seqno %"U32_F" ackno %"U32_F".\n", seqno, ackno));
+}
+
+/**
+ * Send an ACK without data.
+ *
+ * @param pcb Protocol control block for the TCP connection to send the ACK
+ */
+err_t
+tcp_send_empty_ack(struct tcp_pcb *pcb)
+{
+  err_t err;
+  struct pbuf *p;
+  u8_t optlen, optflags = 0;
+  u8_t num_sacks = 0;
+
+  LWIP_ASSERT("tcp_send_empty_ack: invalid pcb", pcb != NULL);
+
+#if LWIP_TCP_TIMESTAMPS
+  if (pcb->flags & TF_TIMESTAMP) {
+    optflags = TF_SEG_OPTS_TS;
+  }
+#endif
+  optlen = LWIP_TCP_OPT_LENGTH_SEGMENT(optflags, pcb);
+
+#if LWIP_TCP_SACK_OUT
+  /* For now, SACKs are only sent with empty ACKs */
+  if ((num_sacks = tcp_get_num_sacks(pcb, optlen)) > 0) {
+    optlen += 4 + num_sacks * 8; /* 4 bytes for header (including 2*NOP), plus 8B for each SACK */
+  }
+#endif
+
+  p = tcp_output_alloc_header(pcb, optlen, 0, lwip_htonl(pcb->snd_nxt));
+  if (p == NULL) {
+    /* let tcp_fasttmr retry sending this ACK */
+    tcp_set_flags(pcb, TF_ACK_DELAY | TF_ACK_NOW);
+    LWIP_DEBUGF(TCP_OUTPUT_DEBUG, ("tcp_output: (ACK) could not allocate pbuf\n"));
+    return ERR_BUF;
+  }
+  tcp_output_fill_options(pcb, p, optflags, num_sacks);
+
+#if LWIP_TCP_TIMESTAMPS
+  pcb->ts_lastacksent = pcb->rcv_nxt;
+#endif
+
+  LWIP_DEBUGF(TCP_OUTPUT_DEBUG,
+              ("tcp_output: sending ACK for %"U32_F"\n", pcb->rcv_nxt));
+  err = tcp_output_control_segment(pcb, p, &pcb->local_ip, &pcb->remote_ip);
+  if (err != ERR_OK) {
+    /* let tcp_fasttmr retry sending this ACK */
+    tcp_set_flags(pcb, TF_ACK_DELAY | TF_ACK_NOW);
+  } else {
+    /* remove ACK flags from the PCB, as we sent an empty ACK now */
+    tcp_clear_flags(pcb, TF_ACK_DELAY | TF_ACK_NOW);
+  }
+
+  return err;
+}
+
+/**
+ * Send keepalive packets to keep a connection active although
+ * no data is sent over it.
+ *
+ * Called by tcp_slowtmr()
+ *
+ * @param pcb the tcp_pcb for which to send a keepalive packet
+ */
+err_t
+tcp_keepalive(struct tcp_pcb *pcb)
+{
+  err_t err;
+  struct pbuf *p;
+  u8_t optlen = LWIP_TCP_OPT_LENGTH_SEGMENT(0, pcb);
+
+  LWIP_ASSERT("tcp_keepalive: invalid pcb", pcb != NULL);
+
+  LWIP_DEBUGF(TCP_DEBUG, ("tcp_keepalive: sending KEEPALIVE probe to "));
+  ip_addr_debug_print_val(TCP_DEBUG, pcb->remote_ip);
+  LWIP_DEBUGF(TCP_DEBUG, ("\n"));
+
+  LWIP_DEBUGF(TCP_DEBUG, ("tcp_keepalive: tcp_ticks %"U32_F"   pcb->tmr %"U32_F" pcb->keep_cnt_sent %"U16_F"\n",
+                          tcp_ticks, pcb->tmr, (u16_t)pcb->keep_cnt_sent));
+
+  p = tcp_output_alloc_header(pcb, optlen, 0, lwip_htonl(pcb->snd_nxt - 1));
+  if (p == NULL) {
+    LWIP_DEBUGF(TCP_DEBUG,
+                ("tcp_keepalive: could not allocate memory for pbuf\n"));
+    return ERR_MEM;
+  }
+  tcp_output_fill_options(pcb, p, 0, optlen);
+  err = tcp_output_control_segment(pcb, p, &pcb->local_ip, &pcb->remote_ip);
+
+  LWIP_DEBUGF(TCP_DEBUG, ("tcp_keepalive: seqno %"U32_F" ackno %"U32_F" err %d.\n",
+                          pcb->snd_nxt - 1, pcb->rcv_nxt, (int)err));
+  return err;
+}
+
+/**
+ * Send persist timer zero-window probes to keep a connection active
+ * when a window update is lost.
+ *
+ * Called by tcp_slowtmr()
+ *
+ * @param pcb the tcp_pcb for which to send a zero-window probe packet
+ */
+err_t
+tcp_zero_window_probe(struct tcp_pcb *pcb)
+{
+  err_t err;
+  struct pbuf *p;
+  struct tcp_hdr *tcphdr;
+  struct tcp_seg *seg;
+  u16_t len;
+  u8_t is_fin;
+  u32_t snd_nxt;
+  u8_t optlen = LWIP_TCP_OPT_LENGTH_SEGMENT(0, pcb);
+
+  LWIP_ASSERT("tcp_zero_window_probe: invalid pcb", pcb != NULL);
+
+  LWIP_DEBUGF(TCP_DEBUG, ("tcp_zero_window_probe: sending ZERO WINDOW probe to "));
+  ip_addr_debug_print_val(TCP_DEBUG, pcb->remote_ip);
+  LWIP_DEBUGF(TCP_DEBUG, ("\n"));
+
+  LWIP_DEBUGF(TCP_DEBUG,
+              ("tcp_zero_window_probe: tcp_ticks %"U32_F
+               "   pcb->tmr %"U32_F" pcb->keep_cnt_sent %"U16_F"\n",
+               tcp_ticks, pcb->tmr, (u16_t)pcb->keep_cnt_sent));
+
+  /* Only consider unsent, persist timer should be off when there is data in-flight */
+  seg = pcb->unsent;
+  if (seg == NULL) {
+    /* Not expected, persist timer should be off when the send buffer is empty */
+    return ERR_OK;
+  }
+
+  /* increment probe count. NOTE: we record probe even if it fails
+     to actually transmit due to an error. This ensures memory exhaustion/
+     routing problem doesn't leave a zero-window pcb as an indefinite zombie.
+     RTO mechanism has similar behavior, see pcb->nrtx */
+  if (pcb->persist_probe < 0xFF) {
+    ++pcb->persist_probe;
+  }
+
+  is_fin = ((TCPH_FLAGS(seg->tcphdr) & TCP_FIN) != 0) && (seg->len == 0);
+  /* we want to send one seqno: either FIN or data (no options) */
+  len = is_fin ? 0 : 1;
+
+  p = tcp_output_alloc_header(pcb, optlen, len, seg->tcphdr->seqno);
+  if (p == NULL) {
+    LWIP_DEBUGF(TCP_DEBUG, ("tcp_zero_window_probe: no memory for pbuf\n"));
+    return ERR_MEM;
+  }
+  tcphdr = (struct tcp_hdr *)p->payload;
+
+  if (is_fin) {
+    /* FIN segment, no data */
+    TCPH_FLAGS_SET(tcphdr, TCP_ACK | TCP_FIN);
+  } else {
+    /* Data segment, copy in one byte from the head of the unacked queue */
+    char *d = ((char *)p->payload + TCP_HLEN);
+    /* Depending on whether the segment has already been sent (unacked) or not
+       (unsent), seg->p->payload points to the IP header or TCP header.
+       Ensure we copy the first TCP data byte: */
+    pbuf_copy_partial(seg->p, d, 1, seg->p->tot_len - seg->len);
+  }
+
+  /* The byte may be acknowledged without the window being opened. */
+  snd_nxt = lwip_ntohl(seg->tcphdr->seqno) + 1;
+  if (TCP_SEQ_LT(pcb->snd_nxt, snd_nxt)) {
+    pcb->snd_nxt = snd_nxt;
+  }
+  tcp_output_fill_options(pcb, p, 0, optlen);
+
+  err = tcp_output_control_segment(pcb, p, &pcb->local_ip, &pcb->remote_ip);
+
+  LWIP_DEBUGF(TCP_DEBUG, ("tcp_zero_window_probe: seqno %"U32_F
+                          " ackno %"U32_F" err %d.\n",
+                          pcb->snd_nxt - 1, pcb->rcv_nxt, (int)err));
+  return err;
+}
+#endif /* LWIP_TCP */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/core/timeouts.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/core/timeouts.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/core/timeouts.c	(revision 457)
@@ -0,0 +1,451 @@
+/**
+ * @file
+ * Stack-internal timers implementation.
+ * This file includes timer callbacks for stack-internal timers as well as
+ * functions to set up or stop timers and check for expired timers.
+ *
+ */
+
+/*
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Adam Dunkels <adam@sics.se>
+ *         Simon Goldschmidt
+ *
+ */
+
+#include "lwip/opt.h"
+
+#include "lwip/timeouts.h"
+#include "lwip/priv/tcp_priv.h"
+
+#include "lwip/def.h"
+#include "lwip/memp.h"
+#include "lwip/priv/tcpip_priv.h"
+
+#include "lwip/ip4_frag.h"
+#include "lwip/etharp.h"
+#include "lwip/dhcp.h"
+#include "lwip/autoip.h"
+#include "lwip/igmp.h"
+#include "lwip/dns.h"
+#include "lwip/nd6.h"
+#include "lwip/ip6_frag.h"
+#include "lwip/mld6.h"
+#include "lwip/dhcp6.h"
+#include "lwip/sys.h"
+#include "lwip/pbuf.h"
+
+#if LWIP_DEBUG_TIMERNAMES
+#define HANDLER(x) x, #x
+#else /* LWIP_DEBUG_TIMERNAMES */
+#define HANDLER(x) x
+#endif /* LWIP_DEBUG_TIMERNAMES */
+
+#define LWIP_MAX_TIMEOUT  0x7fffffff
+
+/* Check if timer's expiry time is greater than time and care about u32_t wraparounds */
+#define TIME_LESS_THAN(t, compare_to) ( (((u32_t)((t)-(compare_to))) > LWIP_MAX_TIMEOUT) ? 1 : 0 )
+
+/** This array contains all stack-internal cyclic timers. To get the number of
+ * timers, use LWIP_ARRAYSIZE() */
+const struct lwip_cyclic_timer lwip_cyclic_timers[] = {
+#if LWIP_TCP
+  /* The TCP timer is a special case: it does not have to run always and
+     is triggered to start from TCP using tcp_timer_needed() */
+  {TCP_TMR_INTERVAL, HANDLER(tcp_tmr)},
+#endif /* LWIP_TCP */
+#if LWIP_IPV4
+#if IP_REASSEMBLY
+  {IP_TMR_INTERVAL, HANDLER(ip_reass_tmr)},
+#endif /* IP_REASSEMBLY */
+#if LWIP_ARP
+  {ARP_TMR_INTERVAL, HANDLER(etharp_tmr)},
+#endif /* LWIP_ARP */
+#if LWIP_DHCP
+  {DHCP_COARSE_TIMER_MSECS, HANDLER(dhcp_coarse_tmr)},
+  {DHCP_FINE_TIMER_MSECS, HANDLER(dhcp_fine_tmr)},
+#endif /* LWIP_DHCP */
+#if LWIP_AUTOIP
+  {AUTOIP_TMR_INTERVAL, HANDLER(autoip_tmr)},
+#endif /* LWIP_AUTOIP */
+#if LWIP_IGMP
+  {IGMP_TMR_INTERVAL, HANDLER(igmp_tmr)},
+#endif /* LWIP_IGMP */
+#endif /* LWIP_IPV4 */
+#if LWIP_DNS
+  {DNS_TMR_INTERVAL, HANDLER(dns_tmr)},
+#endif /* LWIP_DNS */
+#if LWIP_IPV6
+  {ND6_TMR_INTERVAL, HANDLER(nd6_tmr)},
+#if LWIP_IPV6_REASS
+  {IP6_REASS_TMR_INTERVAL, HANDLER(ip6_reass_tmr)},
+#endif /* LWIP_IPV6_REASS */
+#if LWIP_IPV6_MLD
+  {MLD6_TMR_INTERVAL, HANDLER(mld6_tmr)},
+#endif /* LWIP_IPV6_MLD */
+#if LWIP_IPV6_DHCP6
+  {DHCP6_TIMER_MSECS, HANDLER(dhcp6_tmr)},
+#endif /* LWIP_IPV6_DHCP6 */
+#endif /* LWIP_IPV6 */
+};
+const int lwip_num_cyclic_timers = LWIP_ARRAYSIZE(lwip_cyclic_timers);
+
+#if LWIP_TIMERS && !LWIP_TIMERS_CUSTOM
+
+/** The one and only timeout list */
+static struct sys_timeo *next_timeout;
+
+static u32_t current_timeout_due_time;
+
+#if LWIP_TESTMODE
+struct sys_timeo**
+sys_timeouts_get_next_timeout(void)
+{
+  return &next_timeout;
+}
+#endif
+
+#if LWIP_TCP
+/** global variable that shows if the tcp timer is currently scheduled or not */
+static int tcpip_tcp_timer_active;
+
+/**
+ * Timer callback function that calls tcp_tmr() and reschedules itself.
+ *
+ * @param arg unused argument
+ */
+static void
+tcpip_tcp_timer(void *arg)
+{
+  LWIP_UNUSED_ARG(arg);
+
+  /* call TCP timer handler */
+  tcp_tmr();
+  /* timer still needed? */
+  if (tcp_active_pcbs || tcp_tw_pcbs) {
+    /* restart timer */
+    sys_timeout(TCP_TMR_INTERVAL, tcpip_tcp_timer, NULL);
+  } else {
+    /* disable timer */
+    tcpip_tcp_timer_active = 0;
+  }
+}
+
+/**
+ * Called from TCP_REG when registering a new PCB:
+ * the reason is to have the TCP timer only running when
+ * there are active (or time-wait) PCBs.
+ */
+void
+tcp_timer_needed(void)
+{
+  LWIP_ASSERT_CORE_LOCKED();
+
+  /* timer is off but needed again? */
+  if (!tcpip_tcp_timer_active && (tcp_active_pcbs || tcp_tw_pcbs)) {
+    /* enable and start timer */
+    tcpip_tcp_timer_active = 1;
+    sys_timeout(TCP_TMR_INTERVAL, tcpip_tcp_timer, NULL);
+  }
+}
+#endif /* LWIP_TCP */
+
+static void
+#if LWIP_DEBUG_TIMERNAMES
+sys_timeout_abs(u32_t abs_time, sys_timeout_handler handler, void *arg, const char *handler_name)
+#else /* LWIP_DEBUG_TIMERNAMES */
+sys_timeout_abs(u32_t abs_time, sys_timeout_handler handler, void *arg)
+#endif
+{
+  struct sys_timeo *timeout, *t;
+
+  timeout = (struct sys_timeo *)memp_malloc(MEMP_SYS_TIMEOUT);
+  if (timeout == NULL) {
+    LWIP_ASSERT("sys_timeout: timeout != NULL, pool MEMP_SYS_TIMEOUT is empty", timeout != NULL);
+    return;
+  }
+
+  timeout->next = NULL;
+  timeout->h = handler;
+  timeout->arg = arg;
+  timeout->time = abs_time;
+
+#if LWIP_DEBUG_TIMERNAMES
+  timeout->handler_name = handler_name;
+  LWIP_DEBUGF(TIMERS_DEBUG, ("sys_timeout: %p abs_time=%"U32_F" handler=%s arg=%p\n",
+                             (void *)timeout, abs_time, handler_name, (void *)arg));
+#endif /* LWIP_DEBUG_TIMERNAMES */
+
+  if (next_timeout == NULL) {
+    next_timeout = timeout;
+    return;
+  }
+  if (TIME_LESS_THAN(timeout->time, next_timeout->time)) {
+    timeout->next = next_timeout;
+    next_timeout = timeout;
+  } else {
+    for (t = next_timeout; t != NULL; t = t->next) {
+      if ((t->next == NULL) || TIME_LESS_THAN(timeout->time, t->next->time)) {
+        timeout->next = t->next;
+        t->next = timeout;
+        break;
+      }
+    }
+  }
+}
+
+/**
+ * Timer callback function that calls cyclic->handler() and reschedules itself.
+ *
+ * @param arg unused argument
+ */
+#if !LWIP_TESTMODE
+static
+#endif
+void
+lwip_cyclic_timer(void *arg)
+{
+  u32_t now;
+  u32_t next_timeout_time;
+  const struct lwip_cyclic_timer *cyclic = (const struct lwip_cyclic_timer *)arg;
+
+#if LWIP_DEBUG_TIMERNAMES
+  LWIP_DEBUGF(TIMERS_DEBUG, ("tcpip: %s()\n", cyclic->handler_name));
+#endif
+  cyclic->handler();
+
+  now = sys_now();
+  next_timeout_time = (u32_t)(current_timeout_due_time + cyclic->interval_ms);  /* overflow handled by TIME_LESS_THAN macro */ 
+  if (TIME_LESS_THAN(next_timeout_time, now)) {
+    /* timer would immediately expire again -> "overload" -> restart without any correction */
+#if LWIP_DEBUG_TIMERNAMES
+    sys_timeout_abs((u32_t)(now + cyclic->interval_ms), lwip_cyclic_timer, arg, cyclic->handler_name);
+#else
+    sys_timeout_abs((u32_t)(now + cyclic->interval_ms), lwip_cyclic_timer, arg);
+#endif
+
+  } else {
+    /* correct cyclic interval with handler execution delay and sys_check_timeouts jitter */
+#if LWIP_DEBUG_TIMERNAMES
+    sys_timeout_abs(next_timeout_time, lwip_cyclic_timer, arg, cyclic->handler_name);
+#else
+    sys_timeout_abs(next_timeout_time, lwip_cyclic_timer, arg);
+#endif
+  }
+}
+
+/** Initialize this module */
+void sys_timeouts_init(void)
+{
+  size_t i;
+  /* tcp_tmr() at index 0 is started on demand */
+  for (i = (LWIP_TCP ? 1 : 0); i < LWIP_ARRAYSIZE(lwip_cyclic_timers); i++) {
+    /* we have to cast via size_t to get rid of const warning
+      (this is OK as cyclic_timer() casts back to const* */
+    sys_timeout(lwip_cyclic_timers[i].interval_ms, lwip_cyclic_timer, LWIP_CONST_CAST(void *, &lwip_cyclic_timers[i]));
+  }
+}
+
+/**
+ * Create a one-shot timer (aka timeout). Timeouts are processed in the
+ * following cases:
+ * - while waiting for a message using sys_timeouts_mbox_fetch()
+ * - by calling sys_check_timeouts() (NO_SYS==1 only)
+ *
+ * @param msecs time in milliseconds after that the timer should expire
+ * @param handler callback function to call when msecs have elapsed
+ * @param arg argument to pass to the callback function
+ */
+#if LWIP_DEBUG_TIMERNAMES
+void
+sys_timeout_debug(u32_t msecs, sys_timeout_handler handler, void *arg, const char *handler_name)
+#else /* LWIP_DEBUG_TIMERNAMES */
+void
+sys_timeout(u32_t msecs, sys_timeout_handler handler, void *arg)
+#endif /* LWIP_DEBUG_TIMERNAMES */
+{
+  u32_t next_timeout_time;
+
+  LWIP_ASSERT_CORE_LOCKED();
+
+  LWIP_ASSERT("Timeout time too long, max is LWIP_UINT32_MAX/4 msecs", msecs <= (LWIP_UINT32_MAX / 4));
+
+  next_timeout_time = (u32_t)(sys_now() + msecs); /* overflow handled by TIME_LESS_THAN macro */ 
+
+#if LWIP_DEBUG_TIMERNAMES
+  sys_timeout_abs(next_timeout_time, handler, arg, handler_name);
+#else
+  sys_timeout_abs(next_timeout_time, handler, arg);
+#endif
+}
+
+/**
+ * Go through timeout list (for this task only) and remove the first matching
+ * entry (subsequent entries remain untouched), even though the timeout has not
+ * triggered yet.
+ *
+ * @param handler callback function that would be called by the timeout
+ * @param arg callback argument that would be passed to handler
+*/
+void
+sys_untimeout(sys_timeout_handler handler, void *arg)
+{
+  struct sys_timeo *prev_t, *t;
+
+  LWIP_ASSERT_CORE_LOCKED();
+
+  if (next_timeout == NULL) {
+    return;
+  }
+
+  for (t = next_timeout, prev_t = NULL; t != NULL; prev_t = t, t = t->next) {
+    if ((t->h == handler) && (t->arg == arg)) {
+      /* We have a match */
+      /* Unlink from previous in list */
+      if (prev_t == NULL) {
+        next_timeout = t->next;
+      } else {
+        prev_t->next = t->next;
+      }
+      memp_free(MEMP_SYS_TIMEOUT, t);
+      return;
+    }
+  }
+  return;
+}
+
+/**
+ * @ingroup lwip_nosys
+ * Handle timeouts for NO_SYS==1 (i.e. without using
+ * tcpip_thread/sys_timeouts_mbox_fetch(). Uses sys_now() to call timeout
+ * handler functions when timeouts expire.
+ *
+ * Must be called periodically from your main loop.
+ */
+void
+sys_check_timeouts(void)
+{
+  u32_t now;
+
+  LWIP_ASSERT_CORE_LOCKED();
+
+  /* Process only timers expired at the start of the function. */
+  now = sys_now();
+
+  do {
+    struct sys_timeo *tmptimeout;
+    sys_timeout_handler handler;
+    void *arg;
+
+    PBUF_CHECK_FREE_OOSEQ();
+
+    tmptimeout = next_timeout;
+    if (tmptimeout == NULL) {
+      return;
+    }
+
+    if (TIME_LESS_THAN(now, tmptimeout->time)) {
+      return;
+    }
+
+    /* Timeout has expired */
+    next_timeout = tmptimeout->next;
+    handler = tmptimeout->h;
+    arg = tmptimeout->arg;
+    current_timeout_due_time = tmptimeout->time;
+#if LWIP_DEBUG_TIMERNAMES
+    if (handler != NULL) {
+      LWIP_DEBUGF(TIMERS_DEBUG, ("sct calling h=%s t=%"U32_F" arg=%p\n",
+                                 tmptimeout->handler_name, sys_now() - tmptimeout->time, arg));
+    }
+#endif /* LWIP_DEBUG_TIMERNAMES */
+    memp_free(MEMP_SYS_TIMEOUT, tmptimeout);
+    if (handler != NULL) {
+      handler(arg);
+    }
+    LWIP_TCPIP_THREAD_ALIVE();
+
+    /* Repeat until all expired timers have been called */
+  } while (1);
+}
+
+/** Rebase the timeout times to the current time.
+ * This is necessary if sys_check_timeouts() hasn't been called for a long
+ * time (e.g. while saving energy) to prevent all timer functions of that
+ * period being called.
+ */
+void
+sys_restart_timeouts(void)
+{
+  u32_t now;
+  u32_t base;
+  struct sys_timeo *t;
+
+  if (next_timeout == NULL) {
+    return;
+  }
+
+  now = sys_now();
+  base = next_timeout->time;
+
+  for (t = next_timeout; t != NULL; t = t->next) {
+    t->time = (t->time - base) + now;
+  }
+}
+
+/** Return the time left before the next timeout is due. If no timeouts are
+ * enqueued, returns 0xffffffff
+ */
+u32_t
+sys_timeouts_sleeptime(void)
+{
+  u32_t now;
+
+  LWIP_ASSERT_CORE_LOCKED();
+
+  if (next_timeout == NULL) {
+    return SYS_TIMEOUTS_SLEEPTIME_INFINITE;
+  }
+  now = sys_now();
+  if (TIME_LESS_THAN(next_timeout->time, now)) {
+    return 0;
+  } else {
+    u32_t ret = (u32_t)(next_timeout->time - now);
+    LWIP_ASSERT("invalid sleeptime", ret <= LWIP_MAX_TIMEOUT);
+    return ret;
+  }
+}
+
+#else /* LWIP_TIMERS && !LWIP_TIMERS_CUSTOM */
+/* Satisfy the TCP code which calls this function */
+void
+tcp_timer_needed(void)
+{
+}
+#endif /* LWIP_TIMERS && !LWIP_TIMERS_CUSTOM */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/core/udp.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/core/udp.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/core/udp.c	(revision 457)
@@ -0,0 +1,1314 @@
+/**
+ * @file
+ * User Datagram Protocol module\n
+ * The code for the User Datagram Protocol UDP & UDPLite (RFC 3828).\n
+ * See also @ref udp_raw
+ *
+ * @defgroup udp_raw UDP
+ * @ingroup callbackstyle_api
+ * User Datagram Protocol module\n
+ * @see @ref api
+ */
+
+/*
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Adam Dunkels <adam@sics.se>
+ *
+ */
+
+/* @todo Check the use of '(struct udp_pcb).chksum_len_rx'!
+ */
+
+#include "lwip/opt.h"
+
+#if LWIP_UDP /* don't build if not configured for use in lwipopts.h */
+
+#include "lwip/udp.h"
+#include "lwip/def.h"
+#include "lwip/memp.h"
+#include "lwip/inet_chksum.h"
+#include "lwip/ip_addr.h"
+#include "lwip/ip6.h"
+#include "lwip/ip6_addr.h"
+#include "lwip/netif.h"
+#include "lwip/icmp.h"
+#include "lwip/icmp6.h"
+#include "lwip/stats.h"
+#include "lwip/snmp.h"
+#include "lwip/dhcp.h"
+
+#include <string.h>
+
+#ifndef UDP_LOCAL_PORT_RANGE_START
+/* From http://www.iana.org/assignments/port-numbers:
+   "The Dynamic and/or Private Ports are those from 49152 through 65535" */
+#define UDP_LOCAL_PORT_RANGE_START  0xc000
+#define UDP_LOCAL_PORT_RANGE_END    0xffff
+#define UDP_ENSURE_LOCAL_PORT_RANGE(port) ((u16_t)(((port) & (u16_t)~UDP_LOCAL_PORT_RANGE_START) + UDP_LOCAL_PORT_RANGE_START))
+#endif
+
+/* last local UDP port */
+static u16_t udp_port = UDP_LOCAL_PORT_RANGE_START;
+
+/* The list of UDP PCBs */
+/* exported in udp.h (was static) */
+struct udp_pcb *udp_pcbs;
+
+/**
+ * Initialize this module.
+ */
+void
+udp_init(void)
+{
+#ifdef LWIP_RAND
+  udp_port = UDP_ENSURE_LOCAL_PORT_RANGE(LWIP_RAND());
+#endif /* LWIP_RAND */
+}
+
+/**
+ * Allocate a new local UDP port.
+ *
+ * @return a new (free) local UDP port number
+ */
+static u16_t
+udp_new_port(void)
+{
+  u16_t n = 0;
+  struct udp_pcb *pcb;
+
+again:
+  if (udp_port++ == UDP_LOCAL_PORT_RANGE_END) {
+    udp_port = UDP_LOCAL_PORT_RANGE_START;
+  }
+  /* Check all PCBs. */
+  for (pcb = udp_pcbs; pcb != NULL; pcb = pcb->next) {
+    if (pcb->local_port == udp_port) {
+      if (++n > (UDP_LOCAL_PORT_RANGE_END - UDP_LOCAL_PORT_RANGE_START)) {
+        return 0;
+      }
+      goto again;
+    }
+  }
+  return udp_port;
+}
+
+/** Common code to see if the current input packet matches the pcb
+ * (current input packet is accessed via ip(4/6)_current_* macros)
+ *
+ * @param pcb pcb to check
+ * @param inp network interface on which the datagram was received (only used for IPv4)
+ * @param broadcast 1 if his is an IPv4 broadcast (global or subnet-only), 0 otherwise (only used for IPv4)
+ * @return 1 on match, 0 otherwise
+ */
+static u8_t
+udp_input_local_match(struct udp_pcb *pcb, struct netif *inp, u8_t broadcast)
+{
+  LWIP_UNUSED_ARG(inp);       /* in IPv6 only case */
+  LWIP_UNUSED_ARG(broadcast); /* in IPv6 only case */
+
+  LWIP_ASSERT("udp_input_local_match: invalid pcb", pcb != NULL);
+  LWIP_ASSERT("udp_input_local_match: invalid netif", inp != NULL);
+
+  /* check if PCB is bound to specific netif */
+  if ((pcb->netif_idx != NETIF_NO_INDEX) &&
+      (pcb->netif_idx != netif_get_index(ip_data.current_input_netif))) {
+    return 0;
+  }
+
+  /* Dual-stack: PCBs listening to any IP type also listen to any IP address */
+  if (IP_IS_ANY_TYPE_VAL(pcb->local_ip)) {
+#if LWIP_IPV4 && IP_SOF_BROADCAST_RECV
+    if ((broadcast != 0) && !ip_get_option(pcb, SOF_BROADCAST)) {
+      return 0;
+    }
+#endif /* LWIP_IPV4 && IP_SOF_BROADCAST_RECV */
+    return 1;
+  }
+
+  /* Only need to check PCB if incoming IP version matches PCB IP version */
+  if (IP_ADDR_PCB_VERSION_MATCH_EXACT(pcb, ip_current_dest_addr())) {
+#if LWIP_IPV4
+    /* Special case: IPv4 broadcast: all or broadcasts in my subnet
+     * Note: broadcast variable can only be 1 if it is an IPv4 broadcast */
+    if (broadcast != 0) {
+#if IP_SOF_BROADCAST_RECV
+      if (ip_get_option(pcb, SOF_BROADCAST))
+#endif /* IP_SOF_BROADCAST_RECV */
+      {
+        if (ip4_addr_isany(ip_2_ip4(&pcb->local_ip)) ||
+            ((ip4_current_dest_addr()->addr == IPADDR_BROADCAST)) ||
+            ip4_addr_netcmp(ip_2_ip4(&pcb->local_ip), ip4_current_dest_addr(), netif_ip4_netmask(inp))) {
+          return 1;
+        }
+      }
+    } else
+#endif /* LWIP_IPV4 */
+      /* Handle IPv4 and IPv6: all or exact match */
+      if (ip_addr_isany(&pcb->local_ip) || ip_addr_cmp(&pcb->local_ip, ip_current_dest_addr())) {
+        return 1;
+      }
+  }
+
+  return 0;
+}
+
+/**
+ * Process an incoming UDP datagram.
+ *
+ * Given an incoming UDP datagram (as a chain of pbufs) this function
+ * finds a corresponding UDP PCB and hands over the pbuf to the pcbs
+ * recv function. If no pcb is found or the datagram is incorrect, the
+ * pbuf is freed.
+ *
+ * @param p pbuf to be demultiplexed to a UDP PCB (p->payload pointing to the UDP header)
+ * @param inp network interface on which the datagram was received.
+ *
+ */
+void
+udp_input(struct pbuf *p, struct netif *inp)
+{
+  struct udp_hdr *udphdr;
+  struct udp_pcb *pcb, *prev;
+  struct udp_pcb *uncon_pcb;
+  u16_t src, dest;
+  u8_t broadcast;
+  u8_t for_us = 0;
+
+  LWIP_UNUSED_ARG(inp);
+
+  LWIP_ASSERT_CORE_LOCKED();
+
+  LWIP_ASSERT("udp_input: invalid pbuf", p != NULL);
+  LWIP_ASSERT("udp_input: invalid netif", inp != NULL);
+
+  PERF_START;
+
+  UDP_STATS_INC(udp.recv);
+
+  /* Check minimum length (UDP header) */
+  if (p->len < UDP_HLEN) {
+    /* drop short packets */
+    LWIP_DEBUGF(UDP_DEBUG,
+                ("udp_input: short UDP datagram (%"U16_F" bytes) discarded\n", p->tot_len));
+    UDP_STATS_INC(udp.lenerr);
+    UDP_STATS_INC(udp.drop);
+    MIB2_STATS_INC(mib2.udpinerrors);
+    pbuf_free(p);
+    goto end;
+  }
+
+  udphdr = (struct udp_hdr *)p->payload;
+
+  /* is broadcast packet ? */
+  broadcast = ip_addr_isbroadcast(ip_current_dest_addr(), ip_current_netif());
+
+  LWIP_DEBUGF(UDP_DEBUG, ("udp_input: received datagram of length %"U16_F"\n", p->tot_len));
+
+  /* convert src and dest ports to host byte order */
+  src = lwip_ntohs(udphdr->src);
+  dest = lwip_ntohs(udphdr->dest);
+
+  udp_debug_print(udphdr);
+
+  /* print the UDP source and destination */
+  LWIP_DEBUGF(UDP_DEBUG, ("udp ("));
+  ip_addr_debug_print_val(UDP_DEBUG, *ip_current_dest_addr());
+  LWIP_DEBUGF(UDP_DEBUG, (", %"U16_F") <-- (", lwip_ntohs(udphdr->dest)));
+  ip_addr_debug_print_val(UDP_DEBUG, *ip_current_src_addr());
+  LWIP_DEBUGF(UDP_DEBUG, (", %"U16_F")\n", lwip_ntohs(udphdr->src)));
+
+  pcb = NULL;
+  prev = NULL;
+  uncon_pcb = NULL;
+  /* Iterate through the UDP pcb list for a matching pcb.
+   * 'Perfect match' pcbs (connected to the remote port & ip address) are
+   * preferred. If no perfect match is found, the first unconnected pcb that
+   * matches the local port and ip address gets the datagram. */
+  for (pcb = udp_pcbs; pcb != NULL; pcb = pcb->next) {
+    /* print the PCB local and remote address */
+    LWIP_DEBUGF(UDP_DEBUG, ("pcb ("));
+    ip_addr_debug_print_val(UDP_DEBUG, pcb->local_ip);
+    LWIP_DEBUGF(UDP_DEBUG, (", %"U16_F") <-- (", pcb->local_port));
+    ip_addr_debug_print_val(UDP_DEBUG, pcb->remote_ip);
+    LWIP_DEBUGF(UDP_DEBUG, (", %"U16_F")\n", pcb->remote_port));
+
+    /* compare PCB local addr+port to UDP destination addr+port */
+    if ((pcb->local_port == dest) &&
+        (udp_input_local_match(pcb, inp, broadcast) != 0)) {
+      if ((pcb->flags & UDP_FLAGS_CONNECTED) == 0) {
+        if (uncon_pcb == NULL) {
+          /* the first unconnected matching PCB */
+          uncon_pcb = pcb;
+#if LWIP_IPV4
+        } else if (broadcast && ip4_current_dest_addr()->addr == IPADDR_BROADCAST) {
+          /* global broadcast address (only valid for IPv4; match was checked before) */
+          if (!IP_IS_V4_VAL(uncon_pcb->local_ip) || !ip4_addr_cmp(ip_2_ip4(&uncon_pcb->local_ip), netif_ip4_addr(inp))) {
+            /* uncon_pcb does not match the input netif, check this pcb */
+            if (IP_IS_V4_VAL(pcb->local_ip) && ip4_addr_cmp(ip_2_ip4(&pcb->local_ip), netif_ip4_addr(inp))) {
+              /* better match */
+              uncon_pcb = pcb;
+            }
+          }
+#endif /* LWIP_IPV4 */
+        }
+#if SO_REUSE
+        else if (!ip_addr_isany(&pcb->local_ip)) {
+          /* prefer specific IPs over catch-all */
+          uncon_pcb = pcb;
+        }
+#endif /* SO_REUSE */
+      }
+
+      /* compare PCB remote addr+port to UDP source addr+port */
+      if ((pcb->remote_port == src) &&
+          (ip_addr_isany_val(pcb->remote_ip) ||
+           ip_addr_cmp(&pcb->remote_ip, ip_current_src_addr()))) {
+        /* the first fully matching PCB */
+        if (prev != NULL) {
+          /* move the pcb to the front of udp_pcbs so that is
+             found faster next time */
+          prev->next = pcb->next;
+          pcb->next = udp_pcbs;
+          udp_pcbs = pcb;
+        } else {
+          UDP_STATS_INC(udp.cachehit);
+        }
+        break;
+      }
+    }
+
+    prev = pcb;
+  }
+  /* no fully matching pcb found? then look for an unconnected pcb */
+  if (pcb == NULL) {
+    pcb = uncon_pcb;
+  }
+
+  /* Check checksum if this is a match or if it was directed at us. */
+  if (pcb != NULL) {
+    for_us = 1;
+  } else {
+#if LWIP_IPV6
+    if (ip_current_is_v6()) {
+      for_us = netif_get_ip6_addr_match(inp, ip6_current_dest_addr()) >= 0;
+    }
+#endif /* LWIP_IPV6 */
+#if LWIP_IPV4
+    if (!ip_current_is_v6()) {
+      for_us = ip4_addr_cmp(netif_ip4_addr(inp), ip4_current_dest_addr());
+    }
+#endif /* LWIP_IPV4 */
+  }
+
+  if (for_us) {
+    LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_TRACE, ("udp_input: calculating checksum\n"));
+#if CHECKSUM_CHECK_UDP
+    IF__NETIF_CHECKSUM_ENABLED(inp, NETIF_CHECKSUM_CHECK_UDP) {
+#if LWIP_UDPLITE
+      if (ip_current_header_proto() == IP_PROTO_UDPLITE) {
+        /* Do the UDP Lite checksum */
+        u16_t chklen = lwip_ntohs(udphdr->len);
+        if (chklen < sizeof(struct udp_hdr)) {
+          if (chklen == 0) {
+            /* For UDP-Lite, checksum length of 0 means checksum
+               over the complete packet (See RFC 3828 chap. 3.1) */
+            chklen = p->tot_len;
+          } else {
+            /* At least the UDP-Lite header must be covered by the
+               checksum! (Again, see RFC 3828 chap. 3.1) */
+            goto chkerr;
+          }
+        }
+        if (ip_chksum_pseudo_partial(p, IP_PROTO_UDPLITE,
+                                     p->tot_len, chklen,
+                                     ip_current_src_addr(), ip_current_dest_addr()) != 0) {
+          goto chkerr;
+        }
+      } else
+#endif /* LWIP_UDPLITE */
+      {
+        if (udphdr->chksum != 0) {
+          if (ip_chksum_pseudo(p, IP_PROTO_UDP, p->tot_len,
+                               ip_current_src_addr(),
+                               ip_current_dest_addr()) != 0) {
+            goto chkerr;
+          }
+        }
+      }
+    }
+#endif /* CHECKSUM_CHECK_UDP */
+    if (pbuf_remove_header(p, UDP_HLEN)) {
+      /* Can we cope with this failing? Just assert for now */
+      LWIP_ASSERT("pbuf_remove_header failed\n", 0);
+      UDP_STATS_INC(udp.drop);
+      MIB2_STATS_INC(mib2.udpinerrors);
+      pbuf_free(p);
+      goto end;
+    }
+
+    if (pcb != NULL) {
+      MIB2_STATS_INC(mib2.udpindatagrams);
+#if SO_REUSE && SO_REUSE_RXTOALL
+      if (ip_get_option(pcb, SOF_REUSEADDR) &&
+          (broadcast || ip_addr_ismulticast(ip_current_dest_addr()))) {
+        /* pass broadcast- or multicast packets to all multicast pcbs
+           if SOF_REUSEADDR is set on the first match */
+        struct udp_pcb *mpcb;
+        for (mpcb = udp_pcbs; mpcb != NULL; mpcb = mpcb->next) {
+          if (mpcb != pcb) {
+            /* compare PCB local addr+port to UDP destination addr+port */
+            if ((mpcb->local_port == dest) &&
+                (udp_input_local_match(mpcb, inp, broadcast) != 0)) {
+              /* pass a copy of the packet to all local matches */
+              if (mpcb->recv != NULL) {
+                struct pbuf *q;
+                q = pbuf_clone(PBUF_RAW, PBUF_POOL, p);
+                if (q != NULL) {
+                  mpcb->recv(mpcb->recv_arg, mpcb, q, ip_current_src_addr(), src);
+                }
+              }
+            }
+          }
+        }
+      }
+#endif /* SO_REUSE && SO_REUSE_RXTOALL */
+      /* callback */
+      if (pcb->recv != NULL) {
+        /* now the recv function is responsible for freeing p */
+        pcb->recv(pcb->recv_arg, pcb, p, ip_current_src_addr(), src);
+      } else {
+        /* no recv function registered? then we have to free the pbuf! */
+        pbuf_free(p);
+        goto end;
+      }
+    } else {
+      LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_TRACE, ("udp_input: not for us.\n"));
+
+#if LWIP_ICMP || LWIP_ICMP6
+      /* No match was found, send ICMP destination port unreachable unless
+         destination address was broadcast/multicast. */
+      if (!broadcast && !ip_addr_ismulticast(ip_current_dest_addr())) {
+        /* move payload pointer back to ip header */
+        pbuf_header_force(p, (s16_t)(ip_current_header_tot_len() + UDP_HLEN));
+        icmp_port_unreach(ip_current_is_v6(), p);
+      }
+#endif /* LWIP_ICMP || LWIP_ICMP6 */
+      UDP_STATS_INC(udp.proterr);
+      UDP_STATS_INC(udp.drop);
+      MIB2_STATS_INC(mib2.udpnoports);
+      pbuf_free(p);
+    }
+  } else {
+    pbuf_free(p);
+  }
+end:
+  PERF_STOP("udp_input");
+  return;
+#if CHECKSUM_CHECK_UDP
+chkerr:
+  LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_LEVEL_SERIOUS,
+              ("udp_input: UDP (or UDP Lite) datagram discarded due to failing checksum\n"));
+  UDP_STATS_INC(udp.chkerr);
+  UDP_STATS_INC(udp.drop);
+  MIB2_STATS_INC(mib2.udpinerrors);
+  pbuf_free(p);
+  PERF_STOP("udp_input");
+#endif /* CHECKSUM_CHECK_UDP */
+}
+
+/**
+ * @ingroup udp_raw
+ * Sends the pbuf p using UDP. The pbuf is not deallocated.
+ *
+ *
+ * @param pcb UDP PCB used to send the data.
+ * @param p chain of pbuf's to be sent.
+ *
+ * The datagram will be sent to the current remote_ip & remote_port
+ * stored in pcb. If the pcb is not bound to a port, it will
+ * automatically be bound to a random port.
+ *
+ * @return lwIP error code.
+ * - ERR_OK. Successful. No error occurred.
+ * - ERR_MEM. Out of memory.
+ * - ERR_RTE. Could not find route to destination address.
+ * - ERR_VAL. No PCB or PCB is dual-stack
+ * - More errors could be returned by lower protocol layers.
+ *
+ * @see udp_disconnect() udp_sendto()
+ */
+err_t
+udp_send(struct udp_pcb *pcb, struct pbuf *p)
+{
+  LWIP_ERROR("udp_send: invalid pcb", pcb != NULL, return ERR_ARG);
+  LWIP_ERROR("udp_send: invalid pbuf", p != NULL, return ERR_ARG);
+
+  if (IP_IS_ANY_TYPE_VAL(pcb->remote_ip)) {
+    return ERR_VAL;
+  }
+
+  /* send to the packet using remote ip and port stored in the pcb */
+  return udp_sendto(pcb, p, &pcb->remote_ip, pcb->remote_port);
+}
+
+#if LWIP_CHECKSUM_ON_COPY && CHECKSUM_GEN_UDP
+/** @ingroup udp_raw
+ * Same as udp_send() but with checksum
+ */
+err_t
+udp_send_chksum(struct udp_pcb *pcb, struct pbuf *p,
+                u8_t have_chksum, u16_t chksum)
+{
+  LWIP_ERROR("udp_send_chksum: invalid pcb", pcb != NULL, return ERR_ARG);
+  LWIP_ERROR("udp_send_chksum: invalid pbuf", p != NULL, return ERR_ARG);
+
+  if (IP_IS_ANY_TYPE_VAL(pcb->remote_ip)) {
+    return ERR_VAL;
+  }
+
+  /* send to the packet using remote ip and port stored in the pcb */
+  return udp_sendto_chksum(pcb, p, &pcb->remote_ip, pcb->remote_port,
+                           have_chksum, chksum);
+}
+#endif /* LWIP_CHECKSUM_ON_COPY && CHECKSUM_GEN_UDP */
+
+/**
+ * @ingroup udp_raw
+ * Send data to a specified address using UDP.
+ *
+ * @param pcb UDP PCB used to send the data.
+ * @param p chain of pbuf's to be sent.
+ * @param dst_ip Destination IP address.
+ * @param dst_port Destination UDP port.
+ *
+ * dst_ip & dst_port are expected to be in the same byte order as in the pcb.
+ *
+ * If the PCB already has a remote address association, it will
+ * be restored after the data is sent.
+ *
+ * @return lwIP error code (@see udp_send for possible error codes)
+ *
+ * @see udp_disconnect() udp_send()
+ */
+err_t
+udp_sendto(struct udp_pcb *pcb, struct pbuf *p,
+           const ip_addr_t *dst_ip, u16_t dst_port)
+{
+#if LWIP_CHECKSUM_ON_COPY && CHECKSUM_GEN_UDP
+  return udp_sendto_chksum(pcb, p, dst_ip, dst_port, 0, 0);
+}
+
+/** @ingroup udp_raw
+ * Same as udp_sendto(), but with checksum */
+err_t
+udp_sendto_chksum(struct udp_pcb *pcb, struct pbuf *p, const ip_addr_t *dst_ip,
+                  u16_t dst_port, u8_t have_chksum, u16_t chksum)
+{
+#endif /* LWIP_CHECKSUM_ON_COPY && CHECKSUM_GEN_UDP */
+  struct netif *netif;
+
+  LWIP_ERROR("udp_sendto: invalid pcb", pcb != NULL, return ERR_ARG);
+  LWIP_ERROR("udp_sendto: invalid pbuf", p != NULL, return ERR_ARG);
+  LWIP_ERROR("udp_sendto: invalid dst_ip", dst_ip != NULL, return ERR_ARG);
+
+  if (!IP_ADDR_PCB_VERSION_MATCH(pcb, dst_ip)) {
+    return ERR_VAL;
+  }
+
+  LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_TRACE, ("udp_send\n"));
+
+  if (pcb->netif_idx != NETIF_NO_INDEX) {
+    netif = netif_get_by_index(pcb->netif_idx);
+  } else {
+#if LWIP_MULTICAST_TX_OPTIONS
+    netif = NULL;
+    if (ip_addr_ismulticast(dst_ip)) {
+      /* For IPv6, the interface to use for packets with a multicast destination
+       * is specified using an interface index. The same approach may be used for
+       * IPv4 as well, in which case it overrides the IPv4 multicast override
+       * address below. Here we have to look up the netif by going through the
+       * list, but by doing so we skip a route lookup. If the interface index has
+       * gone stale, we fall through and do the regular route lookup after all. */
+      if (pcb->mcast_ifindex != NETIF_NO_INDEX) {
+        netif = netif_get_by_index(pcb->mcast_ifindex);
+      }
+#if LWIP_IPV4
+      else
+#if LWIP_IPV6
+        if (IP_IS_V4(dst_ip))
+#endif /* LWIP_IPV6 */
+        {
+          /* IPv4 does not use source-based routing by default, so we use an
+             administratively selected interface for multicast by default.
+             However, this can be overridden by setting an interface address
+             in pcb->mcast_ip4 that is used for routing. If this routing lookup
+             fails, we try regular routing as though no override was set. */
+          if (!ip4_addr_isany_val(pcb->mcast_ip4) &&
+              !ip4_addr_cmp(&pcb->mcast_ip4, IP4_ADDR_BROADCAST)) {
+            netif = ip4_route_src(ip_2_ip4(&pcb->local_ip), &pcb->mcast_ip4);
+          }
+        }
+#endif /* LWIP_IPV4 */
+    }
+
+    if (netif == NULL)
+#endif /* LWIP_MULTICAST_TX_OPTIONS */
+    {
+      /* find the outgoing network interface for this packet */
+      netif = ip_route(&pcb->local_ip, dst_ip);
+    }
+  }
+
+  /* no outgoing network interface could be found? */
+  if (netif == NULL) {
+    LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("udp_send: No route to "));
+    ip_addr_debug_print(UDP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, dst_ip);
+    LWIP_DEBUGF(UDP_DEBUG, ("\n"));
+    UDP_STATS_INC(udp.rterr);
+    return ERR_RTE;
+  }
+#if LWIP_CHECKSUM_ON_COPY && CHECKSUM_GEN_UDP
+  return udp_sendto_if_chksum(pcb, p, dst_ip, dst_port, netif, have_chksum, chksum);
+#else /* LWIP_CHECKSUM_ON_COPY && CHECKSUM_GEN_UDP */
+  return udp_sendto_if(pcb, p, dst_ip, dst_port, netif);
+#endif /* LWIP_CHECKSUM_ON_COPY && CHECKSUM_GEN_UDP */
+}
+
+/**
+ * @ingroup udp_raw
+ * Send data to a specified address using UDP.
+ * The netif used for sending can be specified.
+ *
+ * This function exists mainly for DHCP, to be able to send UDP packets
+ * on a netif that is still down.
+ *
+ * @param pcb UDP PCB used to send the data.
+ * @param p chain of pbuf's to be sent.
+ * @param dst_ip Destination IP address.
+ * @param dst_port Destination UDP port.
+ * @param netif the netif used for sending.
+ *
+ * dst_ip & dst_port are expected to be in the same byte order as in the pcb.
+ *
+ * @return lwIP error code (@see udp_send for possible error codes)
+ *
+ * @see udp_disconnect() udp_send()
+ */
+err_t
+udp_sendto_if(struct udp_pcb *pcb, struct pbuf *p,
+              const ip_addr_t *dst_ip, u16_t dst_port, struct netif *netif)
+{
+#if LWIP_CHECKSUM_ON_COPY && CHECKSUM_GEN_UDP
+  return udp_sendto_if_chksum(pcb, p, dst_ip, dst_port, netif, 0, 0);
+}
+
+/** Same as udp_sendto_if(), but with checksum */
+err_t
+udp_sendto_if_chksum(struct udp_pcb *pcb, struct pbuf *p, const ip_addr_t *dst_ip,
+                     u16_t dst_port, struct netif *netif, u8_t have_chksum,
+                     u16_t chksum)
+{
+#endif /* LWIP_CHECKSUM_ON_COPY && CHECKSUM_GEN_UDP */
+  const ip_addr_t *src_ip;
+
+  LWIP_ERROR("udp_sendto_if: invalid pcb", pcb != NULL, return ERR_ARG);
+  LWIP_ERROR("udp_sendto_if: invalid pbuf", p != NULL, return ERR_ARG);
+  LWIP_ERROR("udp_sendto_if: invalid dst_ip", dst_ip != NULL, return ERR_ARG);
+  LWIP_ERROR("udp_sendto_if: invalid netif", netif != NULL, return ERR_ARG);
+
+  if (!IP_ADDR_PCB_VERSION_MATCH(pcb, dst_ip)) {
+    return ERR_VAL;
+  }
+
+  /* PCB local address is IP_ANY_ADDR or multicast? */
+#if LWIP_IPV6
+  if (IP_IS_V6(dst_ip)) {
+    if (ip6_addr_isany(ip_2_ip6(&pcb->local_ip)) ||
+        ip6_addr_ismulticast(ip_2_ip6(&pcb->local_ip))) {
+      src_ip = ip6_select_source_address(netif, ip_2_ip6(dst_ip));
+      if (src_ip == NULL) {
+        /* No suitable source address was found. */
+        return ERR_RTE;
+      }
+    } else {
+      /* use UDP PCB local IPv6 address as source address, if still valid. */
+      if (netif_get_ip6_addr_match(netif, ip_2_ip6(&pcb->local_ip)) < 0) {
+        /* Address isn't valid anymore. */
+        return ERR_RTE;
+      }
+      src_ip = &pcb->local_ip;
+    }
+  }
+#endif /* LWIP_IPV6 */
+#if LWIP_IPV4 && LWIP_IPV6
+  else
+#endif /* LWIP_IPV4 && LWIP_IPV6 */
+#if LWIP_IPV4
+    if (ip4_addr_isany(ip_2_ip4(&pcb->local_ip)) ||
+        ip4_addr_ismulticast(ip_2_ip4(&pcb->local_ip))) {
+      /* if the local_ip is any or multicast
+       * use the outgoing network interface IP address as source address */
+      src_ip = netif_ip_addr4(netif);
+    } else {
+      /* check if UDP PCB local IP address is correct
+       * this could be an old address if netif->ip_addr has changed */
+      if (!ip4_addr_cmp(ip_2_ip4(&(pcb->local_ip)), netif_ip4_addr(netif))) {
+        /* local_ip doesn't match, drop the packet */
+        return ERR_RTE;
+      }
+      /* use UDP PCB local IP address as source address */
+      src_ip = &pcb->local_ip;
+    }
+#endif /* LWIP_IPV4 */
+#if LWIP_CHECKSUM_ON_COPY && CHECKSUM_GEN_UDP
+  return udp_sendto_if_src_chksum(pcb, p, dst_ip, dst_port, netif, have_chksum, chksum, src_ip);
+#else /* LWIP_CHECKSUM_ON_COPY && CHECKSUM_GEN_UDP */
+  return udp_sendto_if_src(pcb, p, dst_ip, dst_port, netif, src_ip);
+#endif /* LWIP_CHECKSUM_ON_COPY && CHECKSUM_GEN_UDP */
+}
+
+/** @ingroup udp_raw
+ * Same as @ref udp_sendto_if, but with source address */
+err_t
+udp_sendto_if_src(struct udp_pcb *pcb, struct pbuf *p,
+                  const ip_addr_t *dst_ip, u16_t dst_port, struct netif *netif, const ip_addr_t *src_ip)
+{
+#if LWIP_CHECKSUM_ON_COPY && CHECKSUM_GEN_UDP
+  return udp_sendto_if_src_chksum(pcb, p, dst_ip, dst_port, netif, 0, 0, src_ip);
+}
+
+/** Same as udp_sendto_if_src(), but with checksum */
+err_t
+udp_sendto_if_src_chksum(struct udp_pcb *pcb, struct pbuf *p, const ip_addr_t *dst_ip,
+                         u16_t dst_port, struct netif *netif, u8_t have_chksum,
+                         u16_t chksum, const ip_addr_t *src_ip)
+{
+#endif /* LWIP_CHECKSUM_ON_COPY && CHECKSUM_GEN_UDP */
+  struct udp_hdr *udphdr;
+  err_t err;
+  struct pbuf *q; /* q will be sent down the stack */
+  u8_t ip_proto;
+  u8_t ttl;
+
+  LWIP_ASSERT_CORE_LOCKED();
+
+  LWIP_ERROR("udp_sendto_if_src: invalid pcb", pcb != NULL, return ERR_ARG);
+  LWIP_ERROR("udp_sendto_if_src: invalid pbuf", p != NULL, return ERR_ARG);
+  LWIP_ERROR("udp_sendto_if_src: invalid dst_ip", dst_ip != NULL, return ERR_ARG);
+  LWIP_ERROR("udp_sendto_if_src: invalid src_ip", src_ip != NULL, return ERR_ARG);
+  LWIP_ERROR("udp_sendto_if_src: invalid netif", netif != NULL, return ERR_ARG);
+
+  if (!IP_ADDR_PCB_VERSION_MATCH(pcb, src_ip) ||
+      !IP_ADDR_PCB_VERSION_MATCH(pcb, dst_ip)) {
+    return ERR_VAL;
+  }
+
+#if LWIP_IPV4 && IP_SOF_BROADCAST
+  /* broadcast filter? */
+  if (!ip_get_option(pcb, SOF_BROADCAST) &&
+#if LWIP_IPV6
+      IP_IS_V4(dst_ip) &&
+#endif /* LWIP_IPV6 */
+      ip_addr_isbroadcast(dst_ip, netif)) {
+    LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_LEVEL_SERIOUS,
+                ("udp_sendto_if: SOF_BROADCAST not enabled on pcb %p\n", (void *)pcb));
+    return ERR_VAL;
+  }
+#endif /* LWIP_IPV4 && IP_SOF_BROADCAST */
+
+  /* if the PCB is not yet bound to a port, bind it here */
+  if (pcb->local_port == 0) {
+    LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_TRACE, ("udp_send: not yet bound to a port, binding now\n"));
+    err = udp_bind(pcb, &pcb->local_ip, pcb->local_port);
+    if (err != ERR_OK) {
+      LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS, ("udp_send: forced port bind failed\n"));
+      return err;
+    }
+  }
+
+  /* packet too large to add a UDP header without causing an overflow? */
+  if ((u16_t)(p->tot_len + UDP_HLEN) < p->tot_len) {
+    return ERR_MEM;
+  }
+  /* not enough space to add an UDP header to first pbuf in given p chain? */
+  if (pbuf_add_header(p, UDP_HLEN)) {
+    /* allocate header in a separate new pbuf */
+    q = pbuf_alloc(PBUF_IP, UDP_HLEN, PBUF_RAM);
+    /* new header pbuf could not be allocated? */
+    if (q == NULL) {
+      LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS, ("udp_send: could not allocate header\n"));
+      return ERR_MEM;
+    }
+    if (p->tot_len != 0) {
+      /* chain header q in front of given pbuf p (only if p contains data) */
+      pbuf_chain(q, p);
+    }
+    /* first pbuf q points to header pbuf */
+    LWIP_DEBUGF(UDP_DEBUG,
+                ("udp_send: added header pbuf %p before given pbuf %p\n", (void *)q, (void *)p));
+  } else {
+    /* adding space for header within p succeeded */
+    /* first pbuf q equals given pbuf */
+    q = p;
+    LWIP_DEBUGF(UDP_DEBUG, ("udp_send: added header in given pbuf %p\n", (void *)p));
+  }
+  LWIP_ASSERT("check that first pbuf can hold struct udp_hdr",
+              (q->len >= sizeof(struct udp_hdr)));
+  /* q now represents the packet to be sent */
+  udphdr = (struct udp_hdr *)q->payload;
+  udphdr->src = lwip_htons(pcb->local_port);
+  udphdr->dest = lwip_htons(dst_port);
+  /* in UDP, 0 checksum means 'no checksum' */
+  udphdr->chksum = 0x0000;
+
+  /* Multicast Loop? */
+#if LWIP_MULTICAST_TX_OPTIONS
+  if (((pcb->flags & UDP_FLAGS_MULTICAST_LOOP) != 0) && ip_addr_ismulticast(dst_ip)) {
+    q->flags |= PBUF_FLAG_MCASTLOOP;
+  }
+#endif /* LWIP_MULTICAST_TX_OPTIONS */
+
+  LWIP_DEBUGF(UDP_DEBUG, ("udp_send: sending datagram of length %"U16_F"\n", q->tot_len));
+
+#if LWIP_UDPLITE
+  /* UDP Lite protocol? */
+  if (pcb->flags & UDP_FLAGS_UDPLITE) {
+    u16_t chklen, chklen_hdr;
+    LWIP_DEBUGF(UDP_DEBUG, ("udp_send: UDP LITE packet length %"U16_F"\n", q->tot_len));
+    /* set UDP message length in UDP header */
+    chklen_hdr = chklen = pcb->chksum_len_tx;
+    if ((chklen < sizeof(struct udp_hdr)) || (chklen > q->tot_len)) {
+      if (chklen != 0) {
+        LWIP_DEBUGF(UDP_DEBUG, ("udp_send: UDP LITE pcb->chksum_len is illegal: %"U16_F"\n", chklen));
+      }
+      /* For UDP-Lite, checksum length of 0 means checksum
+         over the complete packet. (See RFC 3828 chap. 3.1)
+         At least the UDP-Lite header must be covered by the
+         checksum, therefore, if chksum_len has an illegal
+         value, we generate the checksum over the complete
+         packet to be safe. */
+      chklen_hdr = 0;
+      chklen = q->tot_len;
+    }
+    udphdr->len = lwip_htons(chklen_hdr);
+    /* calculate checksum */
+#if CHECKSUM_GEN_UDP
+    IF__NETIF_CHECKSUM_ENABLED(netif, NETIF_CHECKSUM_GEN_UDP) {
+#if LWIP_CHECKSUM_ON_COPY
+      if (have_chksum) {
+        chklen = UDP_HLEN;
+      }
+#endif /* LWIP_CHECKSUM_ON_COPY */
+      udphdr->chksum = ip_chksum_pseudo_partial(q, IP_PROTO_UDPLITE,
+                       q->tot_len, chklen, src_ip, dst_ip);
+#if LWIP_CHECKSUM_ON_COPY
+      if (have_chksum) {
+        u32_t acc;
+        acc = udphdr->chksum + (u16_t)~(chksum);
+        udphdr->chksum = FOLD_U32T(acc);
+      }
+#endif /* LWIP_CHECKSUM_ON_COPY */
+
+      /* chksum zero must become 0xffff, as zero means 'no checksum' */
+      if (udphdr->chksum == 0x0000) {
+        udphdr->chksum = 0xffff;
+      }
+    }
+#endif /* CHECKSUM_GEN_UDP */
+
+    ip_proto = IP_PROTO_UDPLITE;
+  } else
+#endif /* LWIP_UDPLITE */
+  {      /* UDP */
+    LWIP_DEBUGF(UDP_DEBUG, ("udp_send: UDP packet length %"U16_F"\n", q->tot_len));
+    udphdr->len = lwip_htons(q->tot_len);
+    /* calculate checksum */
+#if CHECKSUM_GEN_UDP
+    IF__NETIF_CHECKSUM_ENABLED(netif, NETIF_CHECKSUM_GEN_UDP) {
+      /* Checksum is mandatory over IPv6. */
+      if (IP_IS_V6(dst_ip) || (pcb->flags & UDP_FLAGS_NOCHKSUM) == 0) {
+        u16_t udpchksum;
+#if LWIP_CHECKSUM_ON_COPY
+        if (have_chksum) {
+          u32_t acc;
+          udpchksum = ip_chksum_pseudo_partial(q, IP_PROTO_UDP,
+                                               q->tot_len, UDP_HLEN, src_ip, dst_ip);
+          acc = udpchksum + (u16_t)~(chksum);
+          udpchksum = FOLD_U32T(acc);
+        } else
+#endif /* LWIP_CHECKSUM_ON_COPY */
+        {
+          udpchksum = ip_chksum_pseudo(q, IP_PROTO_UDP, q->tot_len,
+                                       src_ip, dst_ip);
+        }
+
+        /* chksum zero must become 0xffff, as zero means 'no checksum' */
+        if (udpchksum == 0x0000) {
+          udpchksum = 0xffff;
+        }
+        udphdr->chksum = udpchksum;
+      }
+    }
+#endif /* CHECKSUM_GEN_UDP */
+    ip_proto = IP_PROTO_UDP;
+  }
+
+  /* Determine TTL to use */
+#if LWIP_MULTICAST_TX_OPTIONS
+  ttl = (ip_addr_ismulticast(dst_ip) ? udp_get_multicast_ttl(pcb) : pcb->ttl);
+#else /* LWIP_MULTICAST_TX_OPTIONS */
+  ttl = pcb->ttl;
+#endif /* LWIP_MULTICAST_TX_OPTIONS */
+
+  LWIP_DEBUGF(UDP_DEBUG, ("udp_send: UDP checksum 0x%04"X16_F"\n", udphdr->chksum));
+  LWIP_DEBUGF(UDP_DEBUG, ("udp_send: ip_output_if (,,,,0x%02"X16_F",)\n", (u16_t)ip_proto));
+  /* output to IP */
+  NETIF_SET_HINTS(netif, &(pcb->netif_hints));
+  err = ip_output_if_src(q, src_ip, dst_ip, ttl, pcb->tos, ip_proto, netif);
+  NETIF_RESET_HINTS(netif);
+
+  /* @todo: must this be increased even if error occurred? */
+  MIB2_STATS_INC(mib2.udpoutdatagrams);
+
+  /* did we chain a separate header pbuf earlier? */
+  if (q != p) {
+    /* free the header pbuf */
+    pbuf_free(q);
+    q = NULL;
+    /* p is still referenced by the caller, and will live on */
+  }
+
+  UDP_STATS_INC(udp.xmit);
+  return err;
+}
+
+/**
+ * @ingroup udp_raw
+ * Bind an UDP PCB.
+ * 
+ * @param pcb UDP PCB to be bound with a local address ipaddr and port.
+ * @param ipaddr local IP address to bind with. Use IP_ANY_TYPE to
+ * bind to all local interfaces.
+ * @param port local UDP port to bind with. Use 0 to automatically bind
+ * to a random port between UDP_LOCAL_PORT_RANGE_START and
+ * UDP_LOCAL_PORT_RANGE_END.
+ *
+ * ipaddr & port are expected to be in the same byte order as in the pcb.
+ *
+ * @return lwIP error code.
+ * - ERR_OK. Successful. No error occurred.
+ * - ERR_USE. The specified ipaddr and port are already bound to by
+ * another UDP PCB.
+ *
+ * @see udp_disconnect()
+ */
+err_t
+udp_bind(struct udp_pcb *pcb, const ip_addr_t *ipaddr, u16_t port)
+{
+  struct udp_pcb *ipcb;
+  u8_t rebind;
+#if LWIP_IPV6 && LWIP_IPV6_SCOPES
+  ip_addr_t zoned_ipaddr;
+#endif /* LWIP_IPV6 && LWIP_IPV6_SCOPES */
+
+  LWIP_ASSERT_CORE_LOCKED();
+
+#if LWIP_IPV4
+  /* Don't propagate NULL pointer (IPv4 ANY) to subsequent functions */
+  if (ipaddr == NULL) {
+    ipaddr = IP4_ADDR_ANY;
+  }
+#else /* LWIP_IPV4 */
+  LWIP_ERROR("udp_bind: invalid ipaddr", ipaddr != NULL, return ERR_ARG);
+#endif /* LWIP_IPV4 */
+
+  LWIP_ERROR("udp_bind: invalid pcb", pcb != NULL, return ERR_ARG);
+
+  LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_TRACE, ("udp_bind(ipaddr = "));
+  ip_addr_debug_print(UDP_DEBUG | LWIP_DBG_TRACE, ipaddr);
+  LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_TRACE, (", port = %"U16_F")\n", port));
+
+  rebind = 0;
+  /* Check for double bind and rebind of the same pcb */
+  for (ipcb = udp_pcbs; ipcb != NULL; ipcb = ipcb->next) {
+    /* is this UDP PCB already on active list? */
+    if (pcb == ipcb) {
+      rebind = 1;
+      break;
+    }
+  }
+
+#if LWIP_IPV6 && LWIP_IPV6_SCOPES
+  /* If the given IP address should have a zone but doesn't, assign one now.
+   * This is legacy support: scope-aware callers should always provide properly
+   * zoned source addresses. Do the zone selection before the address-in-use
+   * check below; as such we have to make a temporary copy of the address. */
+  if (IP_IS_V6(ipaddr) && ip6_addr_lacks_zone(ip_2_ip6(ipaddr), IP6_UNKNOWN)) {
+    ip_addr_copy(zoned_ipaddr, *ipaddr);
+    ip6_addr_select_zone(ip_2_ip6(&zoned_ipaddr), ip_2_ip6(&zoned_ipaddr));
+    ipaddr = &zoned_ipaddr;
+  }
+#endif /* LWIP_IPV6 && LWIP_IPV6_SCOPES */
+
+  /* no port specified? */
+  if (port == 0) {
+    port = udp_new_port();
+    if (port == 0) {
+      /* no more ports available in local range */
+      LWIP_DEBUGF(UDP_DEBUG, ("udp_bind: out of free UDP ports\n"));
+      return ERR_USE;
+    }
+  } else {
+    for (ipcb = udp_pcbs; ipcb != NULL; ipcb = ipcb->next) {
+      if (pcb != ipcb) {
+        /* By default, we don't allow to bind to a port that any other udp
+           PCB is already bound to, unless *all* PCBs with that port have tha
+           REUSEADDR flag set. */
+#if SO_REUSE
+        if (!ip_get_option(pcb, SOF_REUSEADDR) ||
+            !ip_get_option(ipcb, SOF_REUSEADDR))
+#endif /* SO_REUSE */
+        {
+          /* port matches that of PCB in list and REUSEADDR not set -> reject */
+          if ((ipcb->local_port == port) &&
+              /* IP address matches or any IP used? */
+              (ip_addr_cmp(&ipcb->local_ip, ipaddr) || ip_addr_isany(ipaddr) ||
+              ip_addr_isany(&ipcb->local_ip))) {
+            /* other PCB already binds to this local IP and port */
+            LWIP_DEBUGF(UDP_DEBUG,
+                        ("udp_bind: local port %"U16_F" already bound by another pcb\n", port));
+            return ERR_USE;
+          }
+        }
+      }
+    }
+  }
+
+  ip_addr_set_ipaddr(&pcb->local_ip, ipaddr);
+
+  pcb->local_port = port;
+  mib2_udp_bind(pcb);
+  /* pcb not active yet? */
+  if (rebind == 0) {
+    /* place the PCB on the active list if not already there */
+    pcb->next = udp_pcbs;
+    udp_pcbs = pcb;
+  }
+  LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("udp_bind: bound to "));
+  ip_addr_debug_print_val(UDP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, pcb->local_ip);
+  LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, (", port %"U16_F")\n", pcb->local_port));
+  return ERR_OK;
+}
+
+/**
+ * @ingroup udp_raw
+ * Bind an UDP PCB to a specific netif.
+ * After calling this function, all packets received via this PCB
+ * are guaranteed to have come in via the specified netif, and all
+ * outgoing packets will go out via the specified netif.
+ *
+ * @param pcb UDP PCB to be bound.
+ * @param netif netif to bind udp pcb to. Can be NULL.
+ *
+ * @see udp_disconnect()
+ */
+void
+udp_bind_netif(struct udp_pcb *pcb, const struct netif *netif)
+{
+  LWIP_ASSERT_CORE_LOCKED();
+
+  if (netif != NULL) {
+    pcb->netif_idx = netif_get_index(netif);
+  } else {
+    pcb->netif_idx = NETIF_NO_INDEX;
+  }
+}
+
+/**
+ * @ingroup udp_raw
+ * Sets the remote end of the pcb. This function does not generate any
+ * network traffic, but only sets the remote address of the pcb.
+ *
+ * @param pcb UDP PCB to be connected with remote address ipaddr and port.
+ * @param ipaddr remote IP address to connect with.
+ * @param port remote UDP port to connect with.
+ *
+ * @return lwIP error code
+ *
+ * ipaddr & port are expected to be in the same byte order as in the pcb.
+ *
+ * The udp pcb is bound to a random local port if not already bound.
+ *
+ * @see udp_disconnect()
+ */
+err_t
+udp_connect(struct udp_pcb *pcb, const ip_addr_t *ipaddr, u16_t port)
+{
+  struct udp_pcb *ipcb;
+
+  LWIP_ASSERT_CORE_LOCKED();
+
+  LWIP_ERROR("udp_connect: invalid pcb", pcb != NULL, return ERR_ARG);
+  LWIP_ERROR("udp_connect: invalid ipaddr", ipaddr != NULL, return ERR_ARG);
+
+  if (pcb->local_port == 0) {
+    err_t err = udp_bind(pcb, &pcb->local_ip, pcb->local_port);
+    if (err != ERR_OK) {
+      return err;
+    }
+  }
+
+  ip_addr_set_ipaddr(&pcb->remote_ip, ipaddr);
+#if LWIP_IPV6 && LWIP_IPV6_SCOPES
+  /* If the given IP address should have a zone but doesn't, assign one now,
+   * using the bound address to make a more informed decision when possible. */
+  if (IP_IS_V6(&pcb->remote_ip) &&
+      ip6_addr_lacks_zone(ip_2_ip6(&pcb->remote_ip), IP6_UNKNOWN)) {
+    ip6_addr_select_zone(ip_2_ip6(&pcb->remote_ip), ip_2_ip6(&pcb->local_ip));
+  }
+#endif /* LWIP_IPV6 && LWIP_IPV6_SCOPES */
+
+  pcb->remote_port = port;
+  pcb->flags |= UDP_FLAGS_CONNECTED;
+
+  LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("udp_connect: connected to "));
+  ip_addr_debug_print_val(UDP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE,
+                          pcb->remote_ip);
+  LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, (", port %"U16_F")\n", pcb->remote_port));
+
+  /* Insert UDP PCB into the list of active UDP PCBs. */
+  for (ipcb = udp_pcbs; ipcb != NULL; ipcb = ipcb->next) {
+    if (pcb == ipcb) {
+      /* already on the list, just return */
+      return ERR_OK;
+    }
+  }
+  /* PCB not yet on the list, add PCB now */
+  pcb->next = udp_pcbs;
+  udp_pcbs = pcb;
+  return ERR_OK;
+}
+
+/**
+ * @ingroup udp_raw
+ * Remove the remote end of the pcb. This function does not generate
+ * any network traffic, but only removes the remote address of the pcb.
+ *
+ * @param pcb the udp pcb to disconnect.
+ */
+void
+udp_disconnect(struct udp_pcb *pcb)
+{
+  LWIP_ASSERT_CORE_LOCKED();
+
+  LWIP_ERROR("udp_disconnect: invalid pcb", pcb != NULL, return);
+
+  /* reset remote address association */
+#if LWIP_IPV4 && LWIP_IPV6
+  if (IP_IS_ANY_TYPE_VAL(pcb->local_ip)) {
+    ip_addr_copy(pcb->remote_ip, *IP_ANY_TYPE);
+  } else {
+#endif
+    ip_addr_set_any(IP_IS_V6_VAL(pcb->remote_ip), &pcb->remote_ip);
+#if LWIP_IPV4 && LWIP_IPV6
+  }
+#endif
+  pcb->remote_port = 0;
+  pcb->netif_idx = NETIF_NO_INDEX;
+  /* mark PCB as unconnected */
+  udp_clear_flags(pcb, UDP_FLAGS_CONNECTED);
+}
+
+/**
+ * @ingroup udp_raw
+ * Set a receive callback for a UDP PCB.
+ * This callback will be called when receiving a datagram for the pcb.
+ *
+ * @param pcb the pcb for which to set the recv callback
+ * @param recv function pointer of the callback function
+ * @param recv_arg additional argument to pass to the callback function
+ */
+void
+udp_recv(struct udp_pcb *pcb, udp_recv_fn recv, void *recv_arg)
+{
+  LWIP_ASSERT_CORE_LOCKED();
+
+  LWIP_ERROR("udp_recv: invalid pcb", pcb != NULL, return);
+
+  /* remember recv() callback and user data */
+  pcb->recv = recv;
+  pcb->recv_arg = recv_arg;
+}
+
+/**
+ * @ingroup udp_raw
+ * Removes and deallocates the pcb.  
+ * 
+ * @param pcb UDP PCB to be removed. The PCB is removed from the list of
+ * UDP PCB's and the data structure is freed from memory.
+ *
+ * @see udp_new()
+ */
+void
+udp_remove(struct udp_pcb *pcb)
+{
+  struct udp_pcb *pcb2;
+
+  LWIP_ASSERT_CORE_LOCKED();
+
+  LWIP_ERROR("udp_remove: invalid pcb", pcb != NULL, return);
+
+  mib2_udp_unbind(pcb);
+  /* pcb to be removed is first in list? */
+  if (udp_pcbs == pcb) {
+    /* make list start at 2nd pcb */
+    udp_pcbs = udp_pcbs->next;
+    /* pcb not 1st in list */
+  } else {
+    for (pcb2 = udp_pcbs; pcb2 != NULL; pcb2 = pcb2->next) {
+      /* find pcb in udp_pcbs list */
+      if (pcb2->next != NULL && pcb2->next == pcb) {
+        /* remove pcb from list */
+        pcb2->next = pcb->next;
+        break;
+      }
+    }
+  }
+  memp_free(MEMP_UDP_PCB, pcb);
+}
+
+/**
+ * @ingroup udp_raw
+ * Creates a new UDP pcb which can be used for UDP communication. The
+ * pcb is not active until it has either been bound to a local address
+ * or connected to a remote address.
+ *
+ * @return The UDP PCB which was created. NULL if the PCB data structure
+ * could not be allocated.
+ *
+ * @see udp_remove()
+ */
+struct udp_pcb *
+udp_new(void)
+{
+  struct udp_pcb *pcb;
+
+  LWIP_ASSERT_CORE_LOCKED();
+
+  pcb = (struct udp_pcb *)memp_malloc(MEMP_UDP_PCB);
+  /* could allocate UDP PCB? */
+  if (pcb != NULL) {
+    /* UDP Lite: by initializing to all zeroes, chksum_len is set to 0
+     * which means checksum is generated over the whole datagram per default
+     * (recommended as default by RFC 3828). */
+    /* initialize PCB to all zeroes */
+    memset(pcb, 0, sizeof(struct udp_pcb));
+    pcb->ttl = UDP_TTL;
+#if LWIP_MULTICAST_TX_OPTIONS
+    udp_set_multicast_ttl(pcb, UDP_TTL);
+#endif /* LWIP_MULTICAST_TX_OPTIONS */
+  }
+  return pcb;
+}
+
+/**
+ * @ingroup udp_raw
+ * Create a UDP PCB for specific IP type.
+ * The pcb is not active until it has either been bound to a local address
+ * or connected to a remote address.
+ * 
+ * @param type IP address type, see @ref lwip_ip_addr_type definitions.
+ * If you want to listen to IPv4 and IPv6 (dual-stack) packets,
+ * supply @ref IPADDR_TYPE_ANY as argument and bind to @ref IP_ANY_TYPE.
+ * @return The UDP PCB which was created. NULL if the PCB data structure
+ * could not be allocated.
+ *
+ * @see udp_remove()
+ */
+struct udp_pcb *
+udp_new_ip_type(u8_t type)
+{
+  struct udp_pcb *pcb;
+
+  LWIP_ASSERT_CORE_LOCKED();
+
+  pcb = udp_new();
+#if LWIP_IPV4 && LWIP_IPV6
+  if (pcb != NULL) {
+    IP_SET_TYPE_VAL(pcb->local_ip,  type);
+    IP_SET_TYPE_VAL(pcb->remote_ip, type);
+  }
+#else
+  LWIP_UNUSED_ARG(type);
+#endif /* LWIP_IPV4 && LWIP_IPV6 */
+  return pcb;
+}
+
+/** This function is called from netif.c when address is changed
+ *
+ * @param old_addr IP address of the netif before change
+ * @param new_addr IP address of the netif after change
+ */
+void udp_netif_ip_addr_changed(const ip_addr_t *old_addr, const ip_addr_t *new_addr)
+{
+  struct udp_pcb *upcb;
+
+  if (!ip_addr_isany(old_addr) && !ip_addr_isany(new_addr)) {
+    for (upcb = udp_pcbs; upcb != NULL; upcb = upcb->next) {
+      /* PCB bound to current local interface address? */
+      if (ip_addr_cmp(&upcb->local_ip, old_addr)) {
+        /* The PCB is bound to the old ipaddr and
+         * is set to bound to the new one instead */
+        ip_addr_copy(upcb->local_ip, *new_addr);
+      }
+    }
+  }
+}
+
+#if UDP_DEBUG
+/**
+ * Print UDP header information for debug purposes.
+ *
+ * @param udphdr pointer to the udp header in memory.
+ */
+void
+udp_debug_print(struct udp_hdr *udphdr)
+{
+  LWIP_DEBUGF(UDP_DEBUG, ("UDP header:\n"));
+  LWIP_DEBUGF(UDP_DEBUG, ("+-------------------------------+\n"));
+  LWIP_DEBUGF(UDP_DEBUG, ("|     %5"U16_F"     |     %5"U16_F"     | (src port, dest port)\n",
+                          lwip_ntohs(udphdr->src), lwip_ntohs(udphdr->dest)));
+  LWIP_DEBUGF(UDP_DEBUG, ("+-------------------------------+\n"));
+  LWIP_DEBUGF(UDP_DEBUG, ("|     %5"U16_F"     |     0x%04"X16_F"    | (len, chksum)\n",
+                          lwip_ntohs(udphdr->len), lwip_ntohs(udphdr->chksum)));
+  LWIP_DEBUGF(UDP_DEBUG, ("+-------------------------------+\n"));
+}
+#endif /* UDP_DEBUG */
+
+#endif /* LWIP_UDP */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/compat/posix/arpa/inet.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/compat/posix/arpa/inet.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/compat/posix/arpa/inet.h	(revision 457)
@@ -0,0 +1,33 @@
+/**
+ * @file
+ * This file is a posix wrapper for lwip/sockets.h.
+ */
+
+/*
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ */
+
+#include "lwip/sockets.h"
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/compat/posix/net/if.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/compat/posix/net/if.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/compat/posix/net/if.h	(revision 457)
@@ -0,0 +1,36 @@
+/**
+ * @file
+ * This file is a posix wrapper for lwip/if_api.h.
+ */
+
+/*
+ * Copyright (c) 2017 Joel Cunningham, Garmin International, Inc. <joel.cunningham@garmin.com>
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission. 
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ */
+
+#include "lwip/if_api.h"
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/compat/posix/netdb.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/compat/posix/netdb.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/compat/posix/netdb.h	(revision 457)
@@ -0,0 +1,33 @@
+/**
+ * @file
+ * This file is a posix wrapper for lwip/netdb.h.
+ */
+
+/*
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ */
+
+#include "lwip/netdb.h"
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/compat/posix/sys/socket.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/compat/posix/sys/socket.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/compat/posix/sys/socket.h	(revision 457)
@@ -0,0 +1,33 @@
+/**
+ * @file
+ * This file is a posix wrapper for lwip/sockets.h.
+ */
+
+/*
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ */
+
+#include "lwip/sockets.h"
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/compat/stdc/errno.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/compat/stdc/errno.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/compat/stdc/errno.h	(revision 457)
@@ -0,0 +1,33 @@
+/**
+ * @file
+ * This file is a posix/stdc wrapper for lwip/errno.h.
+ */
+
+/*
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ */
+
+#include "lwip/errno.h"
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/altcp.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/altcp.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/altcp.h	(revision 457)
@@ -0,0 +1,201 @@
+/**
+ * @file
+ * Application layered TCP connection API (to be used from TCPIP thread)\n
+ *
+ * This file contains the generic API.
+ * For more details see @ref altcp_api.
+ */
+
+/*
+ * Copyright (c) 2017 Simon Goldschmidt
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Simon Goldschmidt <goldsimon@gmx.de>
+ *
+ */
+#ifndef LWIP_HDR_ALTCP_H
+#define LWIP_HDR_ALTCP_H
+
+#include "lwip/opt.h"
+
+#if LWIP_ALTCP /* don't build if not configured for use in lwipopts.h */
+
+#include "lwip/tcpbase.h"
+#include "lwip/err.h"
+#include "lwip/pbuf.h"
+#include "lwip/ip_addr.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct altcp_pcb;
+struct altcp_functions;
+
+typedef err_t (*altcp_accept_fn)(void *arg, struct altcp_pcb *new_conn, err_t err);
+typedef err_t (*altcp_connected_fn)(void *arg, struct altcp_pcb *conn, err_t err);
+typedef err_t (*altcp_recv_fn)(void *arg, struct altcp_pcb *conn, struct pbuf *p, err_t err);
+typedef err_t (*altcp_sent_fn)(void *arg, struct altcp_pcb *conn, u16_t len);
+typedef err_t (*altcp_poll_fn)(void *arg, struct altcp_pcb *conn);
+typedef void  (*altcp_err_fn)(void *arg, err_t err);
+
+typedef struct altcp_pcb* (*altcp_new_fn)(void *arg, u8_t ip_type);
+
+struct altcp_pcb {
+  const struct altcp_functions *fns;
+  struct altcp_pcb *inner_conn;
+  void *arg;
+  void *state;
+  /* application callbacks */
+  altcp_accept_fn     accept;
+  altcp_connected_fn  connected;
+  altcp_recv_fn       recv;
+  altcp_sent_fn       sent;
+  altcp_poll_fn       poll;
+  altcp_err_fn        err;
+  u8_t pollinterval;
+};
+
+/** @ingroup altcp */
+typedef struct altcp_allocator_s {
+  /** Allocator function */
+  altcp_new_fn  alloc;
+  /** Argument to allocator function */
+  void         *arg;
+} altcp_allocator_t;
+
+struct altcp_pcb *altcp_new(altcp_allocator_t *allocator);
+struct altcp_pcb *altcp_new_ip6(altcp_allocator_t *allocator);
+struct altcp_pcb *altcp_new_ip_type(altcp_allocator_t *allocator, u8_t ip_type);
+
+void altcp_arg(struct altcp_pcb *conn, void *arg);
+void altcp_accept(struct altcp_pcb *conn, altcp_accept_fn accept);
+void altcp_recv(struct altcp_pcb *conn, altcp_recv_fn recv);
+void altcp_sent(struct altcp_pcb *conn, altcp_sent_fn sent);
+void altcp_poll(struct altcp_pcb *conn, altcp_poll_fn poll, u8_t interval);
+void altcp_err(struct altcp_pcb *conn, altcp_err_fn err);
+
+void  altcp_recved(struct altcp_pcb *conn, u16_t len);
+err_t altcp_bind(struct altcp_pcb *conn, const ip_addr_t *ipaddr, u16_t port);
+err_t altcp_connect(struct altcp_pcb *conn, const ip_addr_t *ipaddr, u16_t port, altcp_connected_fn connected);
+
+/* return conn for source code compatibility to tcp callback API only */
+struct altcp_pcb *altcp_listen_with_backlog_and_err(struct altcp_pcb *conn, u8_t backlog, err_t *err);
+#define altcp_listen_with_backlog(conn, backlog) altcp_listen_with_backlog_and_err(conn, backlog, NULL)
+/** @ingroup altcp */
+#define altcp_listen(conn) altcp_listen_with_backlog_and_err(conn, TCP_DEFAULT_LISTEN_BACKLOG, NULL)
+
+void altcp_abort(struct altcp_pcb *conn);
+err_t altcp_close(struct altcp_pcb *conn);
+err_t altcp_shutdown(struct altcp_pcb *conn, int shut_rx, int shut_tx);
+
+err_t altcp_write(struct altcp_pcb *conn, const void *dataptr, u16_t len, u8_t apiflags);
+err_t altcp_output(struct altcp_pcb *conn);
+
+u16_t altcp_mss(struct altcp_pcb *conn);
+u16_t altcp_sndbuf(struct altcp_pcb *conn);
+u16_t altcp_sndqueuelen(struct altcp_pcb *conn);
+void  altcp_nagle_disable(struct altcp_pcb *conn);
+void  altcp_nagle_enable(struct altcp_pcb *conn);
+int   altcp_nagle_disabled(struct altcp_pcb *conn);
+
+void  altcp_setprio(struct altcp_pcb *conn, u8_t prio);
+
+err_t altcp_get_tcp_addrinfo(struct altcp_pcb *conn, int local, ip_addr_t *addr, u16_t *port);
+ip_addr_t *altcp_get_ip(struct altcp_pcb *conn, int local);
+u16_t altcp_get_port(struct altcp_pcb *conn, int local);
+
+#ifdef LWIP_DEBUG
+enum tcp_state altcp_dbg_get_tcp_state(struct altcp_pcb *conn);
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#else /* LWIP_ALTCP */
+
+/* ALTCP disabled, define everything to link against tcp callback API (e.g. to get a small non-ssl httpd) */
+
+#include "lwip/tcp.h"
+
+#define altcp_accept_fn tcp_accept_fn
+#define altcp_connected_fn tcp_connected_fn
+#define altcp_recv_fn tcp_recv_fn
+#define altcp_sent_fn tcp_sent_fn
+#define altcp_poll_fn tcp_poll_fn
+#define altcp_err_fn tcp_err_fn
+
+#define altcp_pcb tcp_pcb
+#define altcp_tcp_new_ip_type tcp_new_ip_type
+#define altcp_tcp_new tcp_new
+#define altcp_tcp_new_ip6 tcp_new_ip6
+
+#define altcp_new(allocator) tcp_new()
+#define altcp_new_ip6(allocator) tcp_new_ip6()
+#define altcp_new_ip_type(allocator, ip_type) tcp_new_ip_type(ip_type)
+
+#define altcp_arg tcp_arg
+#define altcp_accept tcp_accept
+#define altcp_recv tcp_recv
+#define altcp_sent tcp_sent
+#define altcp_poll tcp_poll
+#define altcp_err tcp_err
+
+#define altcp_recved tcp_recved
+#define altcp_bind tcp_bind
+#define altcp_connect tcp_connect
+
+#define altcp_listen_with_backlog_and_err tcp_listen_with_backlog_and_err
+#define altcp_listen_with_backlog tcp_listen_with_backlog
+#define altcp_listen tcp_listen
+
+#define altcp_abort tcp_abort
+#define altcp_close tcp_close
+#define altcp_shutdown tcp_shutdown
+
+#define altcp_write tcp_write
+#define altcp_output tcp_output
+
+#define altcp_mss tcp_mss
+#define altcp_sndbuf tcp_sndbuf
+#define altcp_sndqueuelen tcp_sndqueuelen
+#define altcp_nagle_disable tcp_nagle_disable
+#define altcp_nagle_enable tcp_nagle_enable
+#define altcp_nagle_disabled tcp_nagle_disabled
+#define altcp_setprio tcp_setprio
+
+#define altcp_get_tcp_addrinfo tcp_get_tcp_addrinfo
+#define altcp_get_ip(pcb, local) ((local) ? (&(pcb)->local_ip) : (&(pcb)->remote_ip))
+
+#ifdef LWIP_DEBUG
+#define altcp_dbg_get_tcp_state tcp_dbg_get_tcp_state
+#endif
+
+#endif /* LWIP_ALTCP */
+
+#endif /* LWIP_HDR_ALTCP_H */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/altcp_tcp.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/altcp_tcp.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/altcp_tcp.h	(revision 457)
@@ -0,0 +1,72 @@
+/**
+ * @file
+ * Application layered TCP connection API (to be used from TCPIP thread)\n
+ * This interface mimics the tcp callback API to the application while preventing
+ * direct linking (much like virtual functions).
+ * This way, an application can make use of other application layer protocols
+ * on top of TCP without knowing the details (e.g. TLS, proxy connection).
+ *
+ * This file contains the base implementation calling into tcp.
+ */
+
+/*
+ * Copyright (c) 2017 Simon Goldschmidt
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Simon Goldschmidt <goldsimon@gmx.de>
+ *
+ */
+#ifndef LWIP_HDR_ALTCP_TCP_H
+#define LWIP_HDR_ALTCP_TCP_H
+
+#include "lwip/opt.h"
+
+#if LWIP_ALTCP /* don't build if not configured for use in lwipopts.h */
+
+#include "lwip/altcp.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct altcp_pcb *altcp_tcp_new_ip_type(u8_t ip_type);
+
+#define altcp_tcp_new() altcp_tcp_new_ip_type(IPADDR_TYPE_V4)
+#define altcp_tcp_new_ip6() altcp_tcp_new_ip_type(IPADDR_TYPE_V6)
+
+struct altcp_pcb *altcp_tcp_alloc(void *arg, u8_t ip_type);
+
+struct tcp_pcb;
+struct altcp_pcb *altcp_tcp_wrap(struct tcp_pcb *tpcb);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LWIP_ALTCP */
+
+#endif /* LWIP_HDR_ALTCP_TCP_H */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/altcp_tls.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/altcp_tls.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/altcp_tls.h	(revision 457)
@@ -0,0 +1,117 @@
+/**
+ * @file
+ * Application layered TCP/TLS connection API (to be used from TCPIP thread)
+ *
+ * @defgroup altcp_tls TLS layer
+ * @ingroup altcp
+ * This file contains function prototypes for a TLS layer.
+ * A port to ARM mbedtls is provided in the apps/ tree
+ * (LWIP_ALTCP_TLS_MBEDTLS option).
+ */
+
+/*
+ * Copyright (c) 2017 Simon Goldschmidt
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Simon Goldschmidt <goldsimon@gmx.de>
+ *
+ */
+#ifndef LWIP_HDR_ALTCP_TLS_H
+#define LWIP_HDR_ALTCP_TLS_H
+
+#include "lwip/opt.h"
+
+#if LWIP_ALTCP /* don't build if not configured for use in lwipopts.h */
+
+#if LWIP_ALTCP_TLS
+
+#include "lwip/altcp.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** @ingroup altcp_tls
+ * ALTCP_TLS configuration handle, content depends on port (e.g. mbedtls)
+ */
+struct altcp_tls_config;
+
+/** @ingroup altcp_tls
+ * Create an ALTCP_TLS server configuration handle
+ */
+struct altcp_tls_config *altcp_tls_create_config_server_privkey_cert(const u8_t *privkey, size_t privkey_len,
+                            const u8_t *privkey_pass, size_t privkey_pass_len,
+                            const u8_t *cert, size_t cert_len);
+
+/** @ingroup altcp_tls
+ * Create an ALTCP_TLS client configuration handle
+ */
+struct altcp_tls_config *altcp_tls_create_config_client(const u8_t *cert, size_t cert_len);
+
+/** @ingroup altcp_tls
+ * Create an ALTCP_TLS client configuration handle with two-way server/client authentication
+ */
+struct altcp_tls_config *altcp_tls_create_config_client_2wayauth(const u8_t *ca, size_t ca_len, const u8_t *privkey, size_t privkey_len,
+                            const u8_t *privkey_pass, size_t privkey_pass_len,
+                            const u8_t *cert, size_t cert_len);
+
+/** @ingroup altcp_tls
+ * Free an ALTCP_TLS configuration handle
+ */
+void altcp_tls_free_config(struct altcp_tls_config *conf);
+
+/** @ingroup altcp_tls
+ * Create new ALTCP_TLS layer wrapping an existing pcb as inner connection (e.g. TLS over TCP)
+ */
+struct altcp_pcb *altcp_tls_wrap(struct altcp_tls_config *config, struct altcp_pcb *inner_pcb);
+
+/** @ingroup altcp_tls
+ * Create new ALTCP_TLS pcb and its inner tcp pcb
+ */
+struct altcp_pcb *altcp_tls_new(struct altcp_tls_config *config, u8_t ip_type);
+
+/** @ingroup altcp_tls
+ * Create new ALTCP_TLS layer pcb and its inner tcp pcb.
+ * Same as @ref altcp_tls_new but this allocator function fits to
+ * @ref altcp_allocator_t / @ref altcp_new.\n
+ 'arg' must contain a struct altcp_tls_config *.
+ */
+struct altcp_pcb *altcp_tls_alloc(void *arg, u8_t ip_type);
+
+/** @ingroup altcp_tls
+ * Return pointer to internal TLS context so application can tweak it.
+ * Real type depends on port (e.g. mbedtls)
+ */
+void *altcp_tls_context(struct altcp_pcb *conn);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LWIP_ALTCP_TLS */
+#endif /* LWIP_ALTCP */
+#endif /* LWIP_HDR_ALTCP_TLS_H */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/api.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/api.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/api.h	(revision 457)
@@ -0,0 +1,431 @@
+/**
+ * @file
+ * netconn API (to be used from non-TCPIP threads)
+ */
+
+/*
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Adam Dunkels <adam@sics.se>
+ *
+ */
+#ifndef LWIP_HDR_API_H
+#define LWIP_HDR_API_H
+
+#include "lwip/opt.h"
+
+#if LWIP_NETCONN || LWIP_SOCKET /* don't build if not configured for use in lwipopts.h */
+/* Note: Netconn API is always available when sockets are enabled -
+ * sockets are implemented on top of them */
+
+#include "lwip/arch.h"
+#include "lwip/netbuf.h"
+#include "lwip/sys.h"
+#include "lwip/ip_addr.h"
+#include "lwip/err.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Throughout this file, IP addresses and port numbers are expected to be in
+ * the same byte order as in the corresponding pcb.
+ */
+
+/* Flags for netconn_write (u8_t) */
+#define NETCONN_NOFLAG      0x00
+#define NETCONN_NOCOPY      0x00 /* Only for source code compatibility */
+#define NETCONN_COPY        0x01
+#define NETCONN_MORE        0x02
+#define NETCONN_DONTBLOCK   0x04
+#define NETCONN_NOAUTORCVD  0x08 /* prevent netconn_recv_data_tcp() from updating the tcp window - must be done manually via netconn_tcp_recvd() */
+#define NETCONN_NOFIN       0x10 /* upper layer already received data, leave FIN in queue until called again */
+
+/* Flags for struct netconn.flags (u8_t) */
+/** This netconn had an error, don't block on recvmbox/acceptmbox any more */
+#define NETCONN_FLAG_MBOXCLOSED               0x01
+/** Should this netconn avoid blocking? */
+#define NETCONN_FLAG_NON_BLOCKING             0x02
+/** Was the last connect action a non-blocking one? */
+#define NETCONN_FLAG_IN_NONBLOCKING_CONNECT   0x04
+#if LWIP_NETCONN_FULLDUPLEX
+  /** The mbox of this netconn is being deallocated, don't use it anymore */
+#define NETCONN_FLAG_MBOXINVALID              0x08
+#endif /* LWIP_NETCONN_FULLDUPLEX */
+/** If a nonblocking write has been rejected before, poll_tcp needs to
+    check if the netconn is writable again */
+#define NETCONN_FLAG_CHECK_WRITESPACE         0x10
+#if LWIP_IPV6
+/** If this flag is set then only IPv6 communication is allowed on the
+    netconn. As per RFC#3493 this features defaults to OFF allowing
+    dual-stack usage by default. */
+#define NETCONN_FLAG_IPV6_V6ONLY              0x20
+#endif /* LWIP_IPV6 */
+#if LWIP_NETBUF_RECVINFO
+/** Received packet info will be recorded for this netconn */
+#define NETCONN_FLAG_PKTINFO                  0x40
+#endif /* LWIP_NETBUF_RECVINFO */
+/** A FIN has been received but not passed to the application yet */
+#define NETCONN_FIN_RX_PENDING                0x80
+
+/* Helpers to process several netconn_types by the same code */
+#define NETCONNTYPE_GROUP(t)         ((t)&0xF0)
+#define NETCONNTYPE_DATAGRAM(t)      ((t)&0xE0)
+#if LWIP_IPV6
+#define NETCONN_TYPE_IPV6            0x08
+#define NETCONNTYPE_ISIPV6(t)        (((t)&NETCONN_TYPE_IPV6) != 0)
+#define NETCONNTYPE_ISUDPLITE(t)     (((t)&0xF3) == NETCONN_UDPLITE)
+#define NETCONNTYPE_ISUDPNOCHKSUM(t) (((t)&0xF3) == NETCONN_UDPNOCHKSUM)
+#else /* LWIP_IPV6 */
+#define NETCONNTYPE_ISIPV6(t)        (0)
+#define NETCONNTYPE_ISUDPLITE(t)     ((t) == NETCONN_UDPLITE)
+#define NETCONNTYPE_ISUDPNOCHKSUM(t) ((t) == NETCONN_UDPNOCHKSUM)
+#endif /* LWIP_IPV6 */
+
+/** @ingroup netconn_common
+ * Protocol family and type of the netconn
+ */
+enum netconn_type {
+  NETCONN_INVALID     = 0,
+  /** TCP IPv4 */
+  NETCONN_TCP         = 0x10,
+#if LWIP_IPV6
+  /** TCP IPv6 */
+  NETCONN_TCP_IPV6    = NETCONN_TCP | NETCONN_TYPE_IPV6 /* 0x18 */,
+#endif /* LWIP_IPV6 */
+  /** UDP IPv4 */
+  NETCONN_UDP         = 0x20,
+  /** UDP IPv4 lite */
+  NETCONN_UDPLITE     = 0x21,
+  /** UDP IPv4 no checksum */
+  NETCONN_UDPNOCHKSUM = 0x22,
+
+#if LWIP_IPV6
+  /** UDP IPv6 (dual-stack by default, unless you call @ref netconn_set_ipv6only) */
+  NETCONN_UDP_IPV6         = NETCONN_UDP | NETCONN_TYPE_IPV6 /* 0x28 */,
+  /** UDP IPv6 lite (dual-stack by default, unless you call @ref netconn_set_ipv6only) */
+  NETCONN_UDPLITE_IPV6     = NETCONN_UDPLITE | NETCONN_TYPE_IPV6 /* 0x29 */,
+  /** UDP IPv6 no checksum (dual-stack by default, unless you call @ref netconn_set_ipv6only) */
+  NETCONN_UDPNOCHKSUM_IPV6 = NETCONN_UDPNOCHKSUM | NETCONN_TYPE_IPV6 /* 0x2a */,
+#endif /* LWIP_IPV6 */
+
+  /** Raw connection IPv4 */
+  NETCONN_RAW         = 0x40
+#if LWIP_IPV6
+  /** Raw connection IPv6 (dual-stack by default, unless you call @ref netconn_set_ipv6only) */
+  , NETCONN_RAW_IPV6    = NETCONN_RAW | NETCONN_TYPE_IPV6 /* 0x48 */
+#endif /* LWIP_IPV6 */
+};
+
+/** Current state of the netconn. Non-TCP netconns are always
+ * in state NETCONN_NONE! */
+enum netconn_state {
+  NETCONN_NONE,
+  NETCONN_WRITE,
+  NETCONN_LISTEN,
+  NETCONN_CONNECT,
+  NETCONN_CLOSE
+};
+
+/** Used to inform the callback function about changes
+ * 
+ * Event explanation:
+ * 
+ * In the netconn implementation, there are three ways to block a client:
+ * 
+ * - accept mbox (sys_arch_mbox_fetch(&conn->acceptmbox, &accept_ptr, 0); in netconn_accept())
+ * - receive mbox (sys_arch_mbox_fetch(&conn->recvmbox, &buf, 0); in netconn_recv_data())
+ * - send queue is full (sys_arch_sem_wait(LWIP_API_MSG_SEM(msg), 0); in lwip_netconn_do_write())
+ * 
+ * The events have to be seen as events signaling the state of these mboxes/semaphores. For non-blocking
+ * connections, you need to know in advance whether a call to a netconn function call would block or not,
+ * and these events tell you about that.
+ * 
+ * RCVPLUS events say: Safe to perform a potentially blocking call call once more. 
+ * They are counted in sockets - three RCVPLUS events for accept mbox means you are safe
+ * to call netconn_accept 3 times without being blocked.
+ * Same thing for receive mbox.
+ * 
+ * RCVMINUS events say: Your call to to a possibly blocking function is "acknowledged".
+ * Socket implementation decrements the counter.
+ * 
+ * For TX, there is no need to count, its merely a flag. SENDPLUS means you may send something.
+ * SENDPLUS occurs when enough data was delivered to peer so netconn_send() can be called again.
+ * A SENDMINUS event occurs when the next call to a netconn_send() would be blocking.
+ */
+enum netconn_evt {
+  NETCONN_EVT_RCVPLUS,
+  NETCONN_EVT_RCVMINUS,
+  NETCONN_EVT_SENDPLUS,
+  NETCONN_EVT_SENDMINUS,
+  NETCONN_EVT_ERROR
+};
+
+#if LWIP_IGMP || (LWIP_IPV6 && LWIP_IPV6_MLD)
+/** Used for netconn_join_leave_group() */
+enum netconn_igmp {
+  NETCONN_JOIN,
+  NETCONN_LEAVE
+};
+#endif /* LWIP_IGMP || (LWIP_IPV6 && LWIP_IPV6_MLD) */
+
+#if LWIP_DNS
+/* Used for netconn_gethostbyname_addrtype(), these should match the DNS_ADDRTYPE defines in dns.h */
+#define NETCONN_DNS_DEFAULT   NETCONN_DNS_IPV4_IPV6
+#define NETCONN_DNS_IPV4      0
+#define NETCONN_DNS_IPV6      1
+#define NETCONN_DNS_IPV4_IPV6 2 /* try to resolve IPv4 first, try IPv6 if IPv4 fails only */
+#define NETCONN_DNS_IPV6_IPV4 3 /* try to resolve IPv6 first, try IPv4 if IPv6 fails only */
+#endif /* LWIP_DNS */
+
+/* forward-declare some structs to avoid to include their headers */
+struct ip_pcb;
+struct tcp_pcb;
+struct udp_pcb;
+struct raw_pcb;
+struct netconn;
+struct api_msg;
+
+/** A callback prototype to inform about events for a netconn */
+typedef void (* netconn_callback)(struct netconn *, enum netconn_evt, u16_t len);
+
+/** A netconn descriptor */
+struct netconn {
+  /** type of the netconn (TCP, UDP or RAW) */
+  enum netconn_type type;
+  /** current state of the netconn */
+  enum netconn_state state;
+  /** the lwIP internal protocol control block */
+  union {
+    struct ip_pcb  *ip;
+    struct tcp_pcb *tcp;
+    struct udp_pcb *udp;
+    struct raw_pcb *raw;
+  } pcb;
+  /** the last asynchronous unreported error this netconn had */
+  err_t pending_err;
+#if !LWIP_NETCONN_SEM_PER_THREAD
+  /** sem that is used to synchronously execute functions in the core context */
+  sys_sem_t op_completed;
+#endif
+  /** mbox where received packets are stored until they are fetched
+      by the netconn application thread (can grow quite big) */
+  sys_mbox_t recvmbox;
+#if LWIP_TCP
+  /** mbox where new connections are stored until processed
+      by the application thread */
+  sys_mbox_t acceptmbox;
+#endif /* LWIP_TCP */
+#if LWIP_NETCONN_FULLDUPLEX
+  /** number of threads waiting on an mbox. This is required to unblock
+      all threads when closing while threads are waiting. */
+  int mbox_threads_waiting;
+#endif
+  /** only used for socket layer */
+#if LWIP_SOCKET
+  int socket;
+#endif /* LWIP_SOCKET */
+#if LWIP_SO_SNDTIMEO
+  /** timeout to wait for sending data (which means enqueueing data for sending
+      in internal buffers) in milliseconds */
+  s32_t send_timeout;
+#endif /* LWIP_SO_RCVTIMEO */
+#if LWIP_SO_RCVTIMEO
+  /** timeout in milliseconds to wait for new data to be received
+      (or connections to arrive for listening netconns) */
+  u32_t recv_timeout;
+#endif /* LWIP_SO_RCVTIMEO */
+#if LWIP_SO_RCVBUF
+  /** maximum amount of bytes queued in recvmbox
+      not used for TCP: adjust TCP_WND instead! */
+  int recv_bufsize;
+  /** number of bytes currently in recvmbox to be received,
+      tested against recv_bufsize to limit bytes on recvmbox
+      for UDP and RAW, used for FIONREAD */
+  int recv_avail;
+#endif /* LWIP_SO_RCVBUF */
+#if LWIP_SO_LINGER
+   /** values <0 mean linger is disabled, values > 0 are seconds to linger */
+  s16_t linger;
+#endif /* LWIP_SO_LINGER */
+  /** flags holding more netconn-internal state, see NETCONN_FLAG_* defines */
+  u8_t flags;
+#if LWIP_TCP
+  /** TCP: when data passed to netconn_write doesn't fit into the send buffer,
+      this temporarily stores the message.
+      Also used during connect and close. */
+  struct api_msg *current_msg;
+#endif /* LWIP_TCP */
+  /** A callback function that is informed about events for this netconn */
+  netconn_callback callback;
+};
+
+/** This vector type is passed to @ref netconn_write_vectors_partly to send
+ * multiple buffers at once.
+ * ATTENTION: This type has to directly map struct iovec since one is casted
+ *            into the other!
+ */
+struct netvector {
+  /** pointer to the application buffer that contains the data to send */
+  const void *ptr;
+  /** size of the application data to send */
+  size_t len;
+};
+
+/** Register an Network connection event */
+#define API_EVENT(c,e,l) if (c->callback) {         \
+                           (*c->callback)(c, e, l); \
+                         }
+
+/* Network connection functions: */
+
+/** @ingroup netconn_common
+ * Create new netconn connection
+ * @param t @ref netconn_type */
+#define netconn_new(t)                  netconn_new_with_proto_and_callback(t, 0, NULL)
+#define netconn_new_with_callback(t, c) netconn_new_with_proto_and_callback(t, 0, c)
+struct netconn *netconn_new_with_proto_and_callback(enum netconn_type t, u8_t proto,
+                                             netconn_callback callback);
+err_t   netconn_prepare_delete(struct netconn *conn);
+err_t   netconn_delete(struct netconn *conn);
+/** Get the type of a netconn (as enum netconn_type). */
+#define netconn_type(conn) (conn->type)
+
+err_t   netconn_getaddr(struct netconn *conn, ip_addr_t *addr,
+                        u16_t *port, u8_t local);
+/** @ingroup netconn_common */
+#define netconn_peer(c,i,p) netconn_getaddr(c,i,p,0)
+/** @ingroup netconn_common */
+#define netconn_addr(c,i,p) netconn_getaddr(c,i,p,1)
+
+err_t   netconn_bind(struct netconn *conn, const ip_addr_t *addr, u16_t port);
+err_t   netconn_bind_if(struct netconn *conn, u8_t if_idx);
+err_t   netconn_connect(struct netconn *conn, const ip_addr_t *addr, u16_t port);
+err_t   netconn_disconnect (struct netconn *conn);
+err_t   netconn_listen_with_backlog(struct netconn *conn, u8_t backlog);
+/** @ingroup netconn_tcp */
+#define netconn_listen(conn) netconn_listen_with_backlog(conn, TCP_DEFAULT_LISTEN_BACKLOG)
+err_t   netconn_accept(struct netconn *conn, struct netconn **new_conn);
+err_t   netconn_recv(struct netconn *conn, struct netbuf **new_buf);
+err_t   netconn_recv_udp_raw_netbuf(struct netconn *conn, struct netbuf **new_buf);
+err_t   netconn_recv_udp_raw_netbuf_flags(struct netconn *conn, struct netbuf **new_buf, u8_t apiflags);
+err_t   netconn_recv_tcp_pbuf(struct netconn *conn, struct pbuf **new_buf);
+err_t   netconn_recv_tcp_pbuf_flags(struct netconn *conn, struct pbuf **new_buf, u8_t apiflags);
+err_t   netconn_tcp_recvd(struct netconn *conn, size_t len);
+err_t   netconn_sendto(struct netconn *conn, struct netbuf *buf,
+                             const ip_addr_t *addr, u16_t port);
+err_t   netconn_send(struct netconn *conn, struct netbuf *buf);
+err_t   netconn_write_partly(struct netconn *conn, const void *dataptr, size_t size,
+                             u8_t apiflags, size_t *bytes_written);
+err_t   netconn_write_vectors_partly(struct netconn *conn, struct netvector *vectors, u16_t vectorcnt,
+                                     u8_t apiflags, size_t *bytes_written);
+/** @ingroup netconn_tcp */
+#define netconn_write(conn, dataptr, size, apiflags) \
+          netconn_write_partly(conn, dataptr, size, apiflags, NULL)
+err_t   netconn_close(struct netconn *conn);
+err_t   netconn_shutdown(struct netconn *conn, u8_t shut_rx, u8_t shut_tx);
+
+#if LWIP_IGMP || (LWIP_IPV6 && LWIP_IPV6_MLD)
+err_t   netconn_join_leave_group(struct netconn *conn, const ip_addr_t *multiaddr,
+                             const ip_addr_t *netif_addr, enum netconn_igmp join_or_leave);
+err_t   netconn_join_leave_group_netif(struct netconn *conn, const ip_addr_t *multiaddr,
+                             u8_t if_idx, enum netconn_igmp join_or_leave);
+#endif /* LWIP_IGMP || (LWIP_IPV6 && LWIP_IPV6_MLD) */
+#if LWIP_DNS
+#if LWIP_IPV4 && LWIP_IPV6
+err_t   netconn_gethostbyname_addrtype(const char *name, ip_addr_t *addr, u8_t dns_addrtype);
+#define netconn_gethostbyname(name, addr) netconn_gethostbyname_addrtype(name, addr, NETCONN_DNS_DEFAULT)
+#else /* LWIP_IPV4 && LWIP_IPV6 */
+err_t   netconn_gethostbyname(const char *name, ip_addr_t *addr);
+#define netconn_gethostbyname_addrtype(name, addr, dns_addrtype) netconn_gethostbyname(name, addr)
+#endif /* LWIP_IPV4 && LWIP_IPV6 */
+#endif /* LWIP_DNS */
+
+err_t   netconn_err(struct netconn *conn);
+#define netconn_recv_bufsize(conn)      ((conn)->recv_bufsize)
+
+#define netconn_set_flags(conn, set_flags)     do { (conn)->flags = (u8_t)((conn)->flags |  (set_flags)); } while(0)
+#define netconn_clear_flags(conn, clr_flags)   do { (conn)->flags = (u8_t)((conn)->flags & (u8_t)(~(clr_flags) & 0xff)); } while(0)
+#define netconn_is_flag_set(conn, flag)        (((conn)->flags & (flag)) != 0)
+
+/** Set the blocking status of netconn calls (@todo: write/send is missing) */
+#define netconn_set_nonblocking(conn, val)  do { if(val) { \
+  netconn_set_flags(conn, NETCONN_FLAG_NON_BLOCKING); \
+} else { \
+  netconn_clear_flags(conn, NETCONN_FLAG_NON_BLOCKING); }} while(0)
+/** Get the blocking status of netconn calls (@todo: write/send is missing) */
+#define netconn_is_nonblocking(conn)        (((conn)->flags & NETCONN_FLAG_NON_BLOCKING) != 0)
+
+#if LWIP_IPV6
+/** @ingroup netconn_common
+ * TCP: Set the IPv6 ONLY status of netconn calls (see NETCONN_FLAG_IPV6_V6ONLY)
+ */
+#define netconn_set_ipv6only(conn, val)  do { if(val) { \
+  netconn_set_flags(conn, NETCONN_FLAG_IPV6_V6ONLY); \
+} else { \
+  netconn_clear_flags(conn, NETCONN_FLAG_IPV6_V6ONLY); }} while(0)
+/** @ingroup netconn_common
+ * TCP: Get the IPv6 ONLY status of netconn calls (see NETCONN_FLAG_IPV6_V6ONLY)
+ */
+#define netconn_get_ipv6only(conn)        (((conn)->flags & NETCONN_FLAG_IPV6_V6ONLY) != 0)
+#endif /* LWIP_IPV6 */
+
+#if LWIP_SO_SNDTIMEO
+/** Set the send timeout in milliseconds */
+#define netconn_set_sendtimeout(conn, timeout)      ((conn)->send_timeout = (timeout))
+/** Get the send timeout in milliseconds */
+#define netconn_get_sendtimeout(conn)               ((conn)->send_timeout)
+#endif /* LWIP_SO_SNDTIMEO */
+#if LWIP_SO_RCVTIMEO
+/** Set the receive timeout in milliseconds */
+#define netconn_set_recvtimeout(conn, timeout)      ((conn)->recv_timeout = (timeout))
+/** Get the receive timeout in milliseconds */
+#define netconn_get_recvtimeout(conn)               ((conn)->recv_timeout)
+#endif /* LWIP_SO_RCVTIMEO */
+#if LWIP_SO_RCVBUF
+/** Set the receive buffer in bytes */
+#define netconn_set_recvbufsize(conn, recvbufsize)  ((conn)->recv_bufsize = (recvbufsize))
+/** Get the receive buffer in bytes */
+#define netconn_get_recvbufsize(conn)               ((conn)->recv_bufsize)
+#endif /* LWIP_SO_RCVBUF*/
+
+#if LWIP_NETCONN_SEM_PER_THREAD
+void netconn_thread_init(void);
+void netconn_thread_cleanup(void);
+#else /* LWIP_NETCONN_SEM_PER_THREAD */
+#define netconn_thread_init()
+#define netconn_thread_cleanup()
+#endif /* LWIP_NETCONN_SEM_PER_THREAD */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LWIP_NETCONN || LWIP_SOCKET */
+
+#endif /* LWIP_HDR_API_H */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/apps/FILES
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/apps/FILES	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/apps/FILES	(revision 457)
@@ -0,0 +1,2 @@
+This directory contains application headers.
+Every application shall provide one api file APP.h and optionally one options file APP_opts.h
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/apps/altcp_proxyconnect.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/apps/altcp_proxyconnect.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/apps/altcp_proxyconnect.h	(revision 457)
@@ -0,0 +1,79 @@
+/**
+ * @file
+ * Application layered TCP connection API that executes a proxy-connect.
+ *
+ * This file provides a starting layer that executes a proxy-connect e.g. to
+ * set up TLS connections through a http proxy.
+ */
+
+/*
+ * Copyright (c) 2018 Simon Goldschmidt
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Simon Goldschmidt <goldsimon@gmx.de>
+ *
+ */
+
+#ifndef LWIP_HDR_APPS_ALTCP_PROXYCONNECT_H
+#define LWIP_HDR_APPS_ALTCP_PROXYCONNECT_H
+
+#include "lwip/opt.h"
+
+#if LWIP_ALTCP /* don't build if not configured for use in lwipopts.h */
+
+#include "lwip/ip_addr.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct altcp_proxyconnect_config {
+  ip_addr_t proxy_addr;
+  u16_t proxy_port;
+};
+
+
+struct altcp_pcb *altcp_proxyconnect_new(struct altcp_proxyconnect_config *config, struct altcp_pcb *inner_pcb);
+struct altcp_pcb *altcp_proxyconnect_new_tcp(struct altcp_proxyconnect_config *config, u8_t ip_type);
+
+struct altcp_pcb *altcp_proxyconnect_alloc(void *arg, u8_t ip_type);
+
+#if LWIP_ALTCP_TLS
+struct altcp_proxyconnect_tls_config {
+  struct altcp_proxyconnect_config proxy;
+  struct altcp_tls_config *tls_config;
+};
+
+struct altcp_pcb *altcp_proxyconnect_tls_alloc(void *arg, u8_t ip_type);
+#endif /* LWIP_ALTCP_TLS */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LWIP_ALTCP */
+#endif /* LWIP_HDR_APPS_ALTCP_PROXYCONNECT_H */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/apps/altcp_tls_mbedtls_opts.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/apps/altcp_tls_mbedtls_opts.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/apps/altcp_tls_mbedtls_opts.h	(revision 457)
@@ -0,0 +1,67 @@
+/**
+ * @file
+ * Application layered TCP/TLS connection API (to be used from TCPIP thread)
+ *
+ * This file contains options for an mbedtls port of the TLS layer.
+ */
+
+/*
+ * Copyright (c) 2017 Simon Goldschmidt
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Simon Goldschmidt <goldsimon@gmx.de>
+ *
+ */
+#ifndef LWIP_HDR_ALTCP_TLS_OPTS_H
+#define LWIP_HDR_ALTCP_TLS_OPTS_H
+
+#include "lwip/opt.h"
+
+#if LWIP_ALTCP /* don't build if not configured for use in lwipopts.h */
+
+/** LWIP_ALTCP_TLS_MBEDTLS==1: use mbedTLS for TLS support for altcp API
+ * mbedtls include directory must be reachable via include search path
+ */
+#ifndef LWIP_ALTCP_TLS_MBEDTLS
+#define LWIP_ALTCP_TLS_MBEDTLS                        0
+#endif
+
+/** Configure debug level of this file */
+#ifndef ALTCP_MBEDTLS_DEBUG
+#define ALTCP_MBEDTLS_DEBUG                           LWIP_DBG_OFF
+#endif
+
+/** Set a session timeout in seconds for the basic session cache
+ * ATTENTION: Using a session cache can lower security by reusing keys!
+ */
+#ifndef ALTCP_MBEDTLS_SESSION_CACHE_TIMEOUT_SECONDS
+#define ALTCP_MBEDTLS_SESSION_CACHE_TIMEOUT_SECONDS   0
+#endif
+
+#endif /* LWIP_ALTCP */
+
+#endif /* LWIP_HDR_ALTCP_TLS_OPTS_H */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/apps/fs.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/apps/fs.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/apps/fs.h	(revision 457)
@@ -0,0 +1,126 @@
+/*
+ * Copyright (c) 2001-2003 Swedish Institute of Computer Science.
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission. 
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ * 
+ * Author: Adam Dunkels <adam@sics.se>
+ *
+ */
+#ifndef LWIP_HDR_APPS_FS_H
+#define LWIP_HDR_APPS_FS_H
+
+#include "httpd_opts.h"
+#include "lwip/err.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define FS_READ_EOF     -1
+#define FS_READ_DELAYED -2
+
+#if HTTPD_PRECALCULATED_CHECKSUM
+struct fsdata_chksum {
+  u32_t offset;
+  u16_t chksum;
+  u16_t len;
+};
+#endif /* HTTPD_PRECALCULATED_CHECKSUM */
+
+#define FS_FILE_FLAGS_HEADER_INCLUDED     0x01
+#define FS_FILE_FLAGS_HEADER_PERSISTENT   0x02
+#define FS_FILE_FLAGS_HEADER_HTTPVER_1_1  0x04
+#define FS_FILE_FLAGS_SSI                 0x08
+
+/** Define FS_FILE_EXTENSION_T_DEFINED if you have typedef'ed to your private
+ * pointer type (defaults to 'void' so the default usage is 'void*')
+ */
+#ifndef FS_FILE_EXTENSION_T_DEFINED
+typedef void fs_file_extension;
+#endif
+
+struct fs_file {
+  const char *data;
+  int len;
+  int index;
+  /* pextension is free for implementations to hold private (extensional)
+     arbitrary data, e.g. holding some file state or file system handle */
+  fs_file_extension *pextension;
+#if HTTPD_PRECALCULATED_CHECKSUM
+  const struct fsdata_chksum *chksum;
+  u16_t chksum_count;
+#endif /* HTTPD_PRECALCULATED_CHECKSUM */
+  u8_t flags;
+#if LWIP_HTTPD_CUSTOM_FILES
+  u8_t is_custom_file;
+#endif /* LWIP_HTTPD_CUSTOM_FILES */
+#if LWIP_HTTPD_FILE_STATE
+  void *state;
+#endif /* LWIP_HTTPD_FILE_STATE */
+};
+
+#if LWIP_HTTPD_FS_ASYNC_READ
+typedef void (*fs_wait_cb)(void *arg);
+#endif /* LWIP_HTTPD_FS_ASYNC_READ */
+
+err_t fs_open(struct fs_file *file, const char *name);
+void fs_close(struct fs_file *file);
+#if LWIP_HTTPD_DYNAMIC_FILE_READ
+#if LWIP_HTTPD_FS_ASYNC_READ
+int fs_read_async(struct fs_file *file, char *buffer, int count, fs_wait_cb callback_fn, void *callback_arg);
+#else /* LWIP_HTTPD_FS_ASYNC_READ */
+int fs_read(struct fs_file *file, char *buffer, int count);
+#endif /* LWIP_HTTPD_FS_ASYNC_READ */
+#endif /* LWIP_HTTPD_DYNAMIC_FILE_READ */
+#if LWIP_HTTPD_FS_ASYNC_READ
+int fs_is_file_ready(struct fs_file *file, fs_wait_cb callback_fn, void *callback_arg);
+#endif /* LWIP_HTTPD_FS_ASYNC_READ */
+int fs_bytes_left(struct fs_file *file);
+
+#if LWIP_HTTPD_FILE_STATE
+/** This user-defined function is called when a file is opened. */
+void *fs_state_init(struct fs_file *file, const char *name);
+/** This user-defined function is called when a file is closed. */
+void fs_state_free(struct fs_file *file, void *state);
+#endif /* #if LWIP_HTTPD_FILE_STATE */
+
+struct fsdata_file {
+  const struct fsdata_file *next;
+  const unsigned char *name;
+  const unsigned char *data;
+  int len;
+  u8_t flags;
+#if HTTPD_PRECALCULATED_CHECKSUM
+  u16_t chksum_count;
+  const struct fsdata_chksum *chksum;
+#endif /* HTTPD_PRECALCULATED_CHECKSUM */
+};
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LWIP_HDR_APPS_FS_H */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/apps/http_client.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/apps/http_client.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/apps/http_client.h	(revision 457)
@@ -0,0 +1,160 @@
+/**
+ * @file
+ * HTTP client
+ */
+
+/*
+ * Copyright (c) 2018 Simon Goldschmidt <goldsimon@gmx.de>
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Simon Goldschmidt <goldsimon@gmx.de>
+ *
+ */
+
+#ifndef LWIP_HDR_APPS_HTTP_CLIENT_H
+#define LWIP_HDR_APPS_HTTP_CLIENT_H
+
+#include "lwip/opt.h"
+#include "lwip/ip_addr.h"
+#include "lwip/err.h"
+#include "lwip/altcp.h"
+#include "lwip/prot/iana.h"
+#include "lwip/pbuf.h"
+
+#if LWIP_TCP && LWIP_CALLBACK_API
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @ingroup httpc 
+ * HTTPC_HAVE_FILE_IO: define this to 1 to have functions dowloading directly
+ * to disk via fopen/fwrite.
+ * These functions are example implementations of the interface only.
+ */
+#ifndef LWIP_HTTPC_HAVE_FILE_IO
+#define LWIP_HTTPC_HAVE_FILE_IO   0
+#endif
+
+/**
+ * @ingroup httpc 
+ * The default TCP port used for HTTP
+ */
+#define HTTP_DEFAULT_PORT         LWIP_IANA_PORT_HTTP
+
+/**
+ * @ingroup httpc 
+ * HTTP client result codes
+ */
+typedef enum ehttpc_result {
+  /** File successfully received */
+  HTTPC_RESULT_OK            = 0,
+  /** Unknown error */
+  HTTPC_RESULT_ERR_UNKNOWN   = 1,
+  /** Connection to server failed */
+  HTTPC_RESULT_ERR_CONNECT   = 2,
+  /** Failed to resolve server hostname */
+  HTTPC_RESULT_ERR_HOSTNAME  = 3,
+  /** Connection unexpectedly closed by remote server */
+  HTTPC_RESULT_ERR_CLOSED    = 4,
+  /** Connection timed out (server didn't respond in time) */
+  HTTPC_RESULT_ERR_TIMEOUT   = 5,
+  /** Server responded with an error code */
+  HTTPC_RESULT_ERR_SVR_RESP  = 6,
+  /** Local memory error */
+  HTTPC_RESULT_ERR_MEM       = 7,
+  /** Local abort */
+  HTTPC_RESULT_LOCAL_ABORT   = 8,
+  /** Content length mismatch */
+  HTTPC_RESULT_ERR_CONTENT_LEN = 9
+} httpc_result_t;
+
+typedef struct _httpc_state httpc_state_t;
+
+/**
+ * @ingroup httpc 
+ * Prototype of a http client callback function
+ *
+ * @param arg argument specified when initiating the request
+ * @param httpc_result result of the http transfer (see enum httpc_result_t)
+ * @param rx_content_len number of bytes received (without headers)
+ * @param srv_res this contains the http status code received (if any)
+ * @param err an error returned by internal lwip functions, can help to specify
+ *            the source of the error but must not necessarily be != ERR_OK
+ */
+typedef void (*httpc_result_fn)(void *arg, httpc_result_t httpc_result, u32_t rx_content_len, u32_t srv_res, err_t err);
+
+/**
+ * @ingroup httpc 
+ * Prototype of http client callback: called when the headers are received
+ *
+ * @param connection http client connection
+ * @param arg argument specified when initiating the request
+ * @param hdr header pbuf(s) (may contain data also)
+ * @param hdr_len length of the heders in 'hdr'
+ * @param content_len content length as received in the headers (-1 if not received)
+ * @return if != ERR_OK is returned, the connection is aborted
+ */
+typedef err_t (*httpc_headers_done_fn)(httpc_state_t *connection, void *arg, struct pbuf *hdr, u16_t hdr_len, u32_t content_len);
+
+typedef struct _httpc_connection {
+  ip_addr_t proxy_addr;
+  u16_t proxy_port;
+  u8_t use_proxy;
+  /* @todo: add username:pass? */
+
+#if LWIP_ALTCP
+  altcp_allocator_t *altcp_allocator;
+#endif
+
+  /* this callback is called when the transfer is finished (or aborted) */
+  httpc_result_fn result_fn;
+  /* this callback is called after receiving the http headers
+     It can abort the connection by returning != ERR_OK */
+  httpc_headers_done_fn headers_done_fn;
+} httpc_connection_t;
+
+err_t httpc_get_file(const ip_addr_t* server_addr, u16_t port, const char* uri, const httpc_connection_t *settings,
+                     altcp_recv_fn recv_fn, void* callback_arg, httpc_state_t **connection);
+err_t httpc_get_file_dns(const char* server_name, u16_t port, const char* uri, const httpc_connection_t *settings,
+                     altcp_recv_fn recv_fn, void* callback_arg, httpc_state_t **connection);
+
+#if LWIP_HTTPC_HAVE_FILE_IO
+err_t httpc_get_file_to_disk(const ip_addr_t* server_addr, u16_t port, const char* uri, const httpc_connection_t *settings,
+                     void* callback_arg, const char* local_file_name, httpc_state_t **connection);
+err_t httpc_get_file_dns_to_disk(const char* server_name, u16_t port, const char* uri, const httpc_connection_t *settings,
+                     void* callback_arg, const char* local_file_name, httpc_state_t **connection);
+#endif /* LWIP_HTTPC_HAVE_FILE_IO */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LWIP_TCP && LWIP_CALLBACK_API */
+
+#endif /* LWIP_HDR_APPS_HTTP_CLIENT_H */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/apps/httpd.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/apps/httpd.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/apps/httpd.h	(revision 457)
@@ -0,0 +1,255 @@
+/**
+ * @file
+ * HTTP server
+ */
+
+/*
+ * Copyright (c) 2001-2003 Swedish Institute of Computer Science.
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Adam Dunkels <adam@sics.se>
+ *
+ * This version of the file has been modified by Texas Instruments to offer
+ * simple server-side-include (SSI) and Common Gateway Interface (CGI)
+ * capability.
+ */
+
+#ifndef LWIP_HDR_APPS_HTTPD_H
+#define LWIP_HDR_APPS_HTTPD_H
+
+#include "httpd_opts.h"
+#include "lwip/err.h"
+#include "lwip/pbuf.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if LWIP_HTTPD_CGI
+
+/**
+ * @ingroup httpd
+ * Function pointer for a CGI script handler.
+ *
+ * This function is called each time the HTTPD server is asked for a file
+ * whose name was previously registered as a CGI function using a call to
+ * http_set_cgi_handlers. The iIndex parameter provides the index of the
+ * CGI within the cgis array passed to http_set_cgi_handlers. Parameters
+ * pcParam and pcValue provide access to the parameters provided along with
+ * the URI. iNumParams provides a count of the entries in the pcParam and
+ * pcValue arrays. Each entry in the pcParam array contains the name of a
+ * parameter with the corresponding entry in the pcValue array containing the
+ * value for that parameter. Note that pcParam may contain multiple elements
+ * with the same name if, for example, a multi-selection list control is used
+ * in the form generating the data.
+ *
+ * The function should return a pointer to a character string which is the
+ * path and filename of the response that is to be sent to the connected
+ * browser, for example "/thanks.htm" or "/response/error.ssi".
+ *
+ * The maximum number of parameters that will be passed to this function via
+ * iNumParams is defined by LWIP_HTTPD_MAX_CGI_PARAMETERS. Any parameters in
+ * the incoming HTTP request above this number will be discarded.
+ *
+ * Requests intended for use by this CGI mechanism must be sent using the GET
+ * method (which encodes all parameters within the URI rather than in a block
+ * later in the request). Attempts to use the POST method will result in the
+ * request being ignored.
+ *
+ */
+typedef const char *(*tCGIHandler)(int iIndex, int iNumParams, char *pcParam[],
+                             char *pcValue[]);
+
+/**
+ * @ingroup httpd
+ * Structure defining the base filename (URL) of a CGI and the associated
+ * function which is to be called when that URL is requested.
+ */
+typedef struct
+{
+    const char *pcCGIName;
+    tCGIHandler pfnCGIHandler;
+} tCGI;
+
+void http_set_cgi_handlers(const tCGI *pCGIs, int iNumHandlers);
+
+#endif /* LWIP_HTTPD_CGI */
+
+#if LWIP_HTTPD_CGI || LWIP_HTTPD_CGI_SSI
+
+#if LWIP_HTTPD_CGI_SSI
+/* we have to prototype this struct here to make it available for the handler */
+struct fs_file;
+
+/** Define this generic CGI handler in your application.
+ * It is called once for every URI with parameters.
+ * The parameters can be stored to the object passed as connection_state, which
+ * is allocated to file->state via fs_state_init() from fs_open() or fs_open_custom().
+ * Content creation via SSI or complete dynamic files can retrieve the CGI params from there.
+ */
+extern void httpd_cgi_handler(struct fs_file *file, const char* uri, int iNumParams,
+                              char **pcParam, char **pcValue
+#if defined(LWIP_HTTPD_FILE_STATE) && LWIP_HTTPD_FILE_STATE
+                                     , void *connection_state
+#endif /* LWIP_HTTPD_FILE_STATE */
+                                     );
+#endif /* LWIP_HTTPD_CGI_SSI */
+
+#endif /* LWIP_HTTPD_CGI || LWIP_HTTPD_CGI_SSI */
+
+#if LWIP_HTTPD_SSI
+
+/**
+ * @ingroup httpd
+ * Function pointer for the SSI tag handler callback.
+ *
+ * This function will be called each time the HTTPD server detects a tag of the
+ * form <!--#name--> in files with extensions mentioned in the g_pcSSIExtensions
+ * array (currently .shtml, .shtm, .ssi, .xml, .json) where "name" appears as
+ * one of the tags supplied to http_set_ssi_handler in the tags array.  The
+ * returned insert string, which will be appended after the the string
+ * "<!--#name-->" in file sent back to the client, should be written to pointer
+ * pcInsert. iInsertLen contains the size of the buffer pointed to by
+ * pcInsert. The iIndex parameter provides the zero-based index of the tag as
+ * found in the tags array and identifies the tag that is to be processed.
+ *
+ * The handler returns the number of characters written to pcInsert excluding
+ * any terminating NULL or HTTPD_SSI_TAG_UNKNOWN when tag is not recognized.
+ *
+ * Note that the behavior of this SSI mechanism is somewhat different from the
+ * "normal" SSI processing as found in, for example, the Apache web server.  In
+ * this case, the inserted text is appended following the SSI tag rather than
+ * replacing the tag entirely.  This allows for an implementation that does not
+ * require significant additional buffering of output data yet which will still
+ * offer usable SSI functionality. One downside to this approach is when
+ * attempting to use SSI within JavaScript.  The SSI tag is structured to
+ * resemble an HTML comment but this syntax does not constitute a comment
+ * within JavaScript and, hence, leaving the tag in place will result in
+ * problems in these cases. In order to avoid these problems, define
+ * LWIP_HTTPD_SSI_INCLUDE_TAG as zero in your lwip options file, or use JavaScript
+ * style block comments in the form / * # name * / (without the spaces).
+ */
+typedef u16_t (*tSSIHandler)(
+#if LWIP_HTTPD_SSI_RAW
+                             const char* ssi_tag_name,
+#else /* LWIP_HTTPD_SSI_RAW */
+                             int iIndex,
+#endif /* LWIP_HTTPD_SSI_RAW */
+                             char *pcInsert, int iInsertLen
+#if LWIP_HTTPD_SSI_MULTIPART
+                             , u16_t current_tag_part, u16_t *next_tag_part
+#endif /* LWIP_HTTPD_SSI_MULTIPART */
+#if defined(LWIP_HTTPD_FILE_STATE) && LWIP_HTTPD_FILE_STATE
+                             , void *connection_state
+#endif /* LWIP_HTTPD_FILE_STATE */
+                             );
+
+/** Set the SSI handler function
+ * (if LWIP_HTTPD_SSI_RAW==1, only the first argument is used)
+ */
+void http_set_ssi_handler(tSSIHandler pfnSSIHandler,
+                          const char **ppcTags, int iNumTags);
+
+/** For LWIP_HTTPD_SSI_RAW==1, return this to indicate the tag is unknown.
+ * In this case, the webserver writes a warning into the page.
+ * You can also just return 0 to write nothing for unknown tags.
+ */
+#define HTTPD_SSI_TAG_UNKNOWN 0xFFFF
+
+#endif /* LWIP_HTTPD_SSI */
+
+#if LWIP_HTTPD_SUPPORT_POST
+
+/* These functions must be implemented by the application */
+
+/**
+ * @ingroup httpd
+ * Called when a POST request has been received. The application can decide
+ * whether to accept it or not.
+ *
+ * @param connection Unique connection identifier, valid until httpd_post_end
+ *        is called.
+ * @param uri The HTTP header URI receiving the POST request.
+ * @param http_request The raw HTTP request (the first packet, normally).
+ * @param http_request_len Size of 'http_request'.
+ * @param content_len Content-Length from HTTP header.
+ * @param response_uri Filename of response file, to be filled when denying the
+ *        request
+ * @param response_uri_len Size of the 'response_uri' buffer.
+ * @param post_auto_wnd Set this to 0 to let the callback code handle window
+ *        updates by calling 'httpd_post_data_recved' (to throttle rx speed)
+ *        default is 1 (httpd handles window updates automatically)
+ * @return ERR_OK: Accept the POST request, data may be passed in
+ *         another err_t: Deny the POST request, send back 'bad request'.
+ */
+err_t httpd_post_begin(void *connection, const char *uri, const char *http_request,
+                       u16_t http_request_len, int content_len, char *response_uri,
+                       u16_t response_uri_len, u8_t *post_auto_wnd);
+
+/**
+ * @ingroup httpd
+ * Called for each pbuf of data that has been received for a POST.
+ * ATTENTION: The application is responsible for freeing the pbufs passed in!
+ *
+ * @param connection Unique connection identifier.
+ * @param p Received data.
+ * @return ERR_OK: Data accepted.
+ *         another err_t: Data denied, http_post_get_response_uri will be called.
+ */
+err_t httpd_post_receive_data(void *connection, struct pbuf *p);
+
+/**
+ * @ingroup httpd
+ * Called when all data is received or when the connection is closed.
+ * The application must return the filename/URI of a file to send in response
+ * to this POST request. If the response_uri buffer is untouched, a 404
+ * response is returned.
+ *
+ * @param connection Unique connection identifier.
+ * @param response_uri Filename of response file, to be filled when denying the request
+ * @param response_uri_len Size of the 'response_uri' buffer.
+ */
+void httpd_post_finished(void *connection, char *response_uri, u16_t response_uri_len);
+
+#if LWIP_HTTPD_POST_MANUAL_WND
+void httpd_post_data_recved(void *connection, u16_t recved_len);
+#endif /* LWIP_HTTPD_POST_MANUAL_WND */
+
+#endif /* LWIP_HTTPD_SUPPORT_POST */
+
+void httpd_init(void);
+
+#if HTTPD_ENABLE_HTTPS
+struct altcp_tls_config;
+void httpd_inits(struct altcp_tls_config *conf);
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LWIP_HDR_APPS_HTTPD_H */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/apps/httpd_opts.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/apps/httpd_opts.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/apps/httpd_opts.h	(revision 457)
@@ -0,0 +1,396 @@
+/**
+ * @file
+ * HTTP server options list
+ */
+
+/*
+ * Copyright (c) 2001-2003 Swedish Institute of Computer Science.
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Adam Dunkels <adam@sics.se>
+ *
+ * This version of the file has been modified by Texas Instruments to offer
+ * simple server-side-include (SSI) and Common Gateway Interface (CGI)
+ * capability.
+ */
+
+#ifndef LWIP_HDR_APPS_HTTPD_OPTS_H
+#define LWIP_HDR_APPS_HTTPD_OPTS_H
+
+#include "lwip/opt.h"
+#include "lwip/prot/iana.h"
+
+/**
+ * @defgroup httpd_opts Options
+ * @ingroup httpd
+ * @{
+ */
+
+/** Set this to 1 to support CGI (old style).
+ *
+ * This old style CGI support works by registering an array of URLs and
+ * associated CGI handler functions (@ref http_set_cgi_handlers).
+ * This list is scanned just before fs_open is called from request handling.
+ * The handler can return a new URL that is used internally by the httpd to
+ * load the returned page (passed to fs_open).
+ *
+ * Use this CGI type e.g. to execute specific actions and return a page that
+ * does not depend on the CGI parameters.
+ */
+#if !defined LWIP_HTTPD_CGI || defined __DOXYGEN__
+#define LWIP_HTTPD_CGI            0
+#endif
+
+/** Set this to 1 to support CGI (new style).
+ *
+ * This new style CGI support works by calling a global function
+ * (@ref tCGIHandler) for all URLs that are found. fs_open is called first
+ * and the URL can not be written by the CGI handler. Instead, this handler gets
+ * passed the http file state, an object where it can store information derived
+ * from the CGI URL or parameters. This file state is later passed to SSI, so
+ * the SSI code can return data depending on CGI input.
+ *
+ * Use this CGI handler if you want CGI information passed on to SSI.
+ */
+#if !defined LWIP_HTTPD_CGI_SSI || defined __DOXYGEN__
+#define LWIP_HTTPD_CGI_SSI        0
+#endif
+
+/** Set this to 1 to support SSI (Server-Side-Includes)
+ *
+ * In contrast to other http servers, this only calls a preregistered callback
+ * function (@see http_set_ssi_handler) for each tag (in the format of
+ * <!--#tag-->) encountered in SSI-enabled pages.
+ * SSI-enabled pages must have one of the predefined SSI-enabled file extensions.
+ * All files with one of these extensions are parsed when sent.
+ *
+ * A downside of the current SSI implementation is that persistent connections
+ * don't work, as the file length is not known in advance (and httpd currently
+ * relies on the Content-Length header for persistent connections).
+ *
+ * To save memory, the maximum tag length is limited (@see LWIP_HTTPD_MAX_TAG_NAME_LEN).
+ * To save memory, the maximum insertion string length is limited (@see
+ * LWIP_HTTPD_MAX_TAG_INSERT_LEN). If this is not enought, @ref LWIP_HTTPD_SSI_MULTIPART
+ * can be used.
+ */
+#if !defined LWIP_HTTPD_SSI || defined __DOXYGEN__
+#define LWIP_HTTPD_SSI            0
+#endif
+
+/** Set this to 1 to implement an SSI tag handler callback that gets a const char*
+ * to the tag (instead of an index into a pre-registered array of known tags)
+ * If this is 0, the SSI handler callback function is only called pre-registered tags.
+ */
+#if !defined LWIP_HTTPD_SSI_RAW || defined __DOXYGEN__
+#define LWIP_HTTPD_SSI_RAW        0
+#endif
+
+/** Set this to 0 to prevent parsing the file extension at runtime to decide
+ * if a file should be scanned for SSI tags or not.
+ * Default is 1 (file extensions are checked using the g_pcSSIExtensions array)
+ * Set to 2 to override this runtime test function.
+ *
+ * This is enabled by default, but if you only use a newer version of makefsdata
+ * supporting the "-ssi" option, this info is already present in
+ */
+#if !defined LWIP_HTTPD_SSI_BY_FILE_EXTENSION || defined __DOXYGEN__
+#define LWIP_HTTPD_SSI_BY_FILE_EXTENSION  1
+#endif
+
+/** Set this to 1 to support HTTP POST */
+#if !defined LWIP_HTTPD_SUPPORT_POST || defined __DOXYGEN__
+#define LWIP_HTTPD_SUPPORT_POST   0
+#endif
+
+/* The maximum number of parameters that the CGI handler can be sent. */
+#if !defined LWIP_HTTPD_MAX_CGI_PARAMETERS || defined __DOXYGEN__
+#define LWIP_HTTPD_MAX_CGI_PARAMETERS 16
+#endif
+
+/** LWIP_HTTPD_SSI_MULTIPART==1: SSI handler function is called with 2 more
+ * arguments indicating a counter for insert string that are too long to be
+ * inserted at once: the SSI handler function must then set 'next_tag_part'
+ * which will be passed back to it in the next call. */
+#if !defined LWIP_HTTPD_SSI_MULTIPART || defined __DOXYGEN__
+#define LWIP_HTTPD_SSI_MULTIPART    0
+#endif
+
+/* The maximum length of the string comprising the SSI tag name
+ * ATTENTION: tags longer than this are ignored, not truncated!
+ */
+#if !defined LWIP_HTTPD_MAX_TAG_NAME_LEN || defined __DOXYGEN__
+#define LWIP_HTTPD_MAX_TAG_NAME_LEN 8
+#endif
+
+/* The maximum length of string that can be returned to replace any given tag
+ * If this buffer is not long enough, use LWIP_HTTPD_SSI_MULTIPART.
+ */
+#if !defined LWIP_HTTPD_MAX_TAG_INSERT_LEN || defined __DOXYGEN__
+#define LWIP_HTTPD_MAX_TAG_INSERT_LEN 192
+#endif
+
+#if !defined LWIP_HTTPD_POST_MANUAL_WND || defined __DOXYGEN__
+#define LWIP_HTTPD_POST_MANUAL_WND  0
+#endif
+
+/** This string is passed in the HTTP header as "Server: " */
+#if !defined HTTPD_SERVER_AGENT || defined __DOXYGEN__
+#define HTTPD_SERVER_AGENT "lwIP/" LWIP_VERSION_STRING " (http://savannah.nongnu.org/projects/lwip)"
+#endif
+
+/** Set this to 1 if you want to include code that creates HTTP headers
+ * at runtime. Default is off: HTTP headers are then created statically
+ * by the makefsdata tool. Static headers mean smaller code size, but
+ * the (readonly) fsdata will grow a bit as every file includes the HTTP
+ * header. */
+#if !defined LWIP_HTTPD_DYNAMIC_HEADERS || defined __DOXYGEN__
+#define LWIP_HTTPD_DYNAMIC_HEADERS 0
+#endif
+
+#if !defined HTTPD_DEBUG || defined __DOXYGEN__
+#define HTTPD_DEBUG         LWIP_DBG_OFF
+#endif
+
+/** Set this to 1 to use a memp pool for allocating 
+ * struct http_state instead of the heap.
+ * If enabled, you'll need to define MEMP_NUM_PARALLEL_HTTPD_CONNS
+ * (and MEMP_NUM_PARALLEL_HTTPD_SSI_CONNS for SSI) to set the size of
+ * the pool(s).
+ */
+#if !defined HTTPD_USE_MEM_POOL || defined __DOXYGEN__
+#define HTTPD_USE_MEM_POOL  0
+#endif
+
+/** The server port for HTTPD to use */
+#if !defined HTTPD_SERVER_PORT || defined __DOXYGEN__
+#define HTTPD_SERVER_PORT                   LWIP_IANA_PORT_HTTP
+#endif
+
+/** The https server port for HTTPD to use */
+#if !defined HTTPD_SERVER_PORT_HTTPS || defined __DOXYGEN__
+#define HTTPD_SERVER_PORT_HTTPS             LWIP_IANA_PORT_HTTPS
+#endif
+
+/** Enable https support? */
+#if !defined HTTPD_ENABLE_HTTPS || defined __DOXYGEN__
+#define HTTPD_ENABLE_HTTPS                  0
+#endif
+
+/** Maximum retries before the connection is aborted/closed.
+ * - number of times pcb->poll is called -> default is 4*500ms = 2s;
+ * - reset when pcb->sent is called
+ */
+#if !defined HTTPD_MAX_RETRIES || defined __DOXYGEN__
+#define HTTPD_MAX_RETRIES                   4
+#endif
+
+/** The poll delay is X*500ms */
+#if !defined HTTPD_POLL_INTERVAL || defined __DOXYGEN__
+#define HTTPD_POLL_INTERVAL                 4
+#endif
+
+/** Priority for tcp pcbs created by HTTPD (very low by default).
+ *  Lower priorities get killed first when running out of memory.
+ */
+#if !defined HTTPD_TCP_PRIO || defined __DOXYGEN__
+#define HTTPD_TCP_PRIO                      TCP_PRIO_MIN
+#endif
+
+/** Set this to 1 to enable timing each file sent */
+#if !defined LWIP_HTTPD_TIMING || defined __DOXYGEN__
+#define LWIP_HTTPD_TIMING                   0
+#endif
+/** Set this to 1 to enable timing each file sent */
+#if !defined HTTPD_DEBUG_TIMING || defined __DOXYGEN__
+#define HTTPD_DEBUG_TIMING                  LWIP_DBG_OFF
+#endif
+
+/** Set this to one to show error pages when parsing a request fails instead
+    of simply closing the connection. */
+#if !defined LWIP_HTTPD_SUPPORT_EXTSTATUS || defined __DOXYGEN__
+#define LWIP_HTTPD_SUPPORT_EXTSTATUS        0
+#endif
+
+/** Set this to 0 to drop support for HTTP/0.9 clients (to save some bytes) */
+#if !defined LWIP_HTTPD_SUPPORT_V09 || defined __DOXYGEN__
+#define LWIP_HTTPD_SUPPORT_V09              1
+#endif
+
+/** Set this to 1 to enable HTTP/1.1 persistent connections.
+ * ATTENTION: If the generated file system includes HTTP headers, these must
+ * include the "Connection: keep-alive" header (pass argument "-11" to makefsdata).
+ */
+#if !defined LWIP_HTTPD_SUPPORT_11_KEEPALIVE || defined __DOXYGEN__
+#define LWIP_HTTPD_SUPPORT_11_KEEPALIVE     0
+#endif
+
+/** Set this to 1 to support HTTP request coming in in multiple packets/pbufs */
+#if !defined LWIP_HTTPD_SUPPORT_REQUESTLIST || defined __DOXYGEN__
+#define LWIP_HTTPD_SUPPORT_REQUESTLIST      1
+#endif
+
+#if LWIP_HTTPD_SUPPORT_REQUESTLIST
+/** Number of rx pbufs to enqueue to parse an incoming request (up to the first
+    newline) */
+#if !defined LWIP_HTTPD_REQ_QUEUELEN || defined __DOXYGEN__
+#define LWIP_HTTPD_REQ_QUEUELEN             5
+#endif
+
+/** Number of (TCP payload-) bytes (in pbufs) to enqueue to parse and incoming
+    request (up to the first double-newline) */
+#if !defined LWIP_HTTPD_REQ_BUFSIZE || defined __DOXYGEN__
+#define LWIP_HTTPD_REQ_BUFSIZE              LWIP_HTTPD_MAX_REQ_LENGTH
+#endif
+
+/** Defines the maximum length of a HTTP request line (up to the first CRLF,
+    copied from pbuf into this a global buffer when pbuf- or packet-queues
+    are received - otherwise the input pbuf is used directly) */
+#if !defined LWIP_HTTPD_MAX_REQ_LENGTH || defined __DOXYGEN__
+#define LWIP_HTTPD_MAX_REQ_LENGTH           LWIP_MIN(1023, (LWIP_HTTPD_REQ_QUEUELEN * PBUF_POOL_BUFSIZE))
+#endif
+#endif /* LWIP_HTTPD_SUPPORT_REQUESTLIST */
+
+/** This is the size of a static buffer used when URIs end with '/'.
+ * In this buffer, the directory requested is concatenated with all the
+ * configured default file names.
+ * Set to 0 to disable checking default filenames on non-root directories.
+ */
+#if !defined LWIP_HTTPD_MAX_REQUEST_URI_LEN || defined __DOXYGEN__
+#define LWIP_HTTPD_MAX_REQUEST_URI_LEN      63
+#endif
+
+/** Maximum length of the filename to send as response to a POST request,
+ * filled in by the application when a POST is finished.
+ */
+#if !defined LWIP_HTTPD_POST_MAX_RESPONSE_URI_LEN || defined __DOXYGEN__
+#define LWIP_HTTPD_POST_MAX_RESPONSE_URI_LEN 63
+#endif
+
+/** Set this to 0 to not send the SSI tag (default is on, so the tag will
+ * be sent in the HTML page */
+#if !defined LWIP_HTTPD_SSI_INCLUDE_TAG || defined __DOXYGEN__
+#define LWIP_HTTPD_SSI_INCLUDE_TAG           1
+#endif
+
+/** Set this to 1 to call tcp_abort when tcp_close fails with memory error.
+ * This can be used to prevent consuming all memory in situations where the
+ * HTTP server has low priority compared to other communication. */
+#if !defined LWIP_HTTPD_ABORT_ON_CLOSE_MEM_ERROR || defined __DOXYGEN__
+#define LWIP_HTTPD_ABORT_ON_CLOSE_MEM_ERROR  0
+#endif
+
+/** Set this to 1 to kill the oldest connection when running out of
+ * memory for 'struct http_state' or 'struct http_ssi_state'.
+ * ATTENTION: This puts all connections on a linked list, so may be kind of slow.
+ */
+#if !defined LWIP_HTTPD_KILL_OLD_ON_CONNECTIONS_EXCEEDED || defined __DOXYGEN__
+#define LWIP_HTTPD_KILL_OLD_ON_CONNECTIONS_EXCEEDED 0
+#endif
+
+/** Set this to 1 to send URIs without extension without headers
+ * (who uses this at all??) */
+#if !defined LWIP_HTTPD_OMIT_HEADER_FOR_EXTENSIONLESS_URI || defined __DOXYGEN__
+#define LWIP_HTTPD_OMIT_HEADER_FOR_EXTENSIONLESS_URI 0
+#endif
+
+/** Default: Tags are sent from struct http_state and are therefore volatile */
+#if !defined HTTP_IS_TAG_VOLATILE || defined __DOXYGEN__
+#define HTTP_IS_TAG_VOLATILE(ptr) TCP_WRITE_FLAG_COPY
+#endif
+
+/* By default, the httpd is limited to send 2*pcb->mss to keep resource usage low
+   when http is not an important protocol in the device. */
+#if !defined HTTPD_LIMIT_SENDING_TO_2MSS || defined __DOXYGEN__
+#define HTTPD_LIMIT_SENDING_TO_2MSS 1
+#endif
+
+/* Define this to a function that returns the maximum amount of data to enqueue.
+   The function have this signature: u16_t fn(struct altcp_pcb* pcb);
+   The best place to define this is the hooks file (@see LWIP_HOOK_FILENAME) */
+#if !defined HTTPD_MAX_WRITE_LEN || defined __DOXYGEN__
+#if HTTPD_LIMIT_SENDING_TO_2MSS
+#define HTTPD_MAX_WRITE_LEN(pcb)    ((u16_t)(2 * altcp_mss(pcb)))
+#endif
+#endif
+
+/*------------------- FS OPTIONS -------------------*/
+
+/** Set this to 1 and provide the functions:
+ * - "int fs_open_custom(struct fs_file *file, const char *name)"
+ *    Called first for every opened file to allow opening files
+ *    that are not included in fsdata(_custom).c
+ * - "void fs_close_custom(struct fs_file *file)"
+ *    Called to free resources allocated by fs_open_custom().
+ */
+#if !defined LWIP_HTTPD_CUSTOM_FILES || defined __DOXYGEN__
+#define LWIP_HTTPD_CUSTOM_FILES       0
+#endif
+
+/** Set this to 1 to support fs_read() to dynamically read file data.
+ * Without this (default=off), only one-block files are supported,
+ * and the contents must be ready after fs_open().
+ */
+#if !defined LWIP_HTTPD_DYNAMIC_FILE_READ || defined __DOXYGEN__
+#define LWIP_HTTPD_DYNAMIC_FILE_READ  0
+#endif
+
+/** Set this to 1 to include an application state argument per file
+ * that is opened. This allows to keep a state per connection/file.
+ */
+#if !defined LWIP_HTTPD_FILE_STATE || defined __DOXYGEN__
+#define LWIP_HTTPD_FILE_STATE         0
+#endif
+
+/** HTTPD_PRECALCULATED_CHECKSUM==1: include precompiled checksums for
+ * predefined (MSS-sized) chunks of the files to prevent having to calculate
+ * the checksums at runtime. */
+#if !defined HTTPD_PRECALCULATED_CHECKSUM || defined __DOXYGEN__
+#define HTTPD_PRECALCULATED_CHECKSUM  0
+#endif
+
+/** LWIP_HTTPD_FS_ASYNC_READ==1: support asynchronous read operations
+ * (fs_read_async returns FS_READ_DELAYED and calls a callback when finished).
+ */
+#if !defined LWIP_HTTPD_FS_ASYNC_READ || defined __DOXYGEN__
+#define LWIP_HTTPD_FS_ASYNC_READ      0
+#endif
+
+/** Filename (including path) to use as FS data file */
+#if !defined HTTPD_FSDATA_FILE || defined __DOXYGEN__
+/* HTTPD_USE_CUSTOM_FSDATA: Compatibility with deprecated lwIP option */
+#if defined(HTTPD_USE_CUSTOM_FSDATA) && (HTTPD_USE_CUSTOM_FSDATA != 0)
+#define HTTPD_FSDATA_FILE "fsdata_custom.c"
+#else
+#define HTTPD_FSDATA_FILE "fsdata.c"
+#endif
+#endif
+
+/**
+ * @}
+ */
+
+#endif /* LWIP_HDR_APPS_HTTPD_OPTS_H */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/apps/lwiperf.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/apps/lwiperf.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/apps/lwiperf.h	(revision 457)
@@ -0,0 +1,100 @@
+/**
+ * @file
+ * lwIP iPerf server implementation
+ */
+
+/*
+ * Copyright (c) 2014 Simon Goldschmidt
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Simon Goldschmidt
+ *
+ */
+#ifndef LWIP_HDR_APPS_LWIPERF_H
+#define LWIP_HDR_APPS_LWIPERF_H
+
+#include "lwip/opt.h"
+#include "lwip/ip_addr.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define LWIPERF_TCP_PORT_DEFAULT  5001
+
+/** lwIPerf test results */
+enum lwiperf_report_type
+{
+  /** The server side test is done */
+  LWIPERF_TCP_DONE_SERVER,
+  /** The client side test is done */
+  LWIPERF_TCP_DONE_CLIENT,
+  /** Local error lead to test abort */
+  LWIPERF_TCP_ABORTED_LOCAL,
+  /** Data check error lead to test abort */
+  LWIPERF_TCP_ABORTED_LOCAL_DATAERROR,
+  /** Transmit error lead to test abort */
+  LWIPERF_TCP_ABORTED_LOCAL_TXERROR,
+  /** Remote side aborted the test */
+  LWIPERF_TCP_ABORTED_REMOTE
+};
+
+/** Control */
+enum lwiperf_client_type
+{
+  /** Unidirectional tx only test */
+  LWIPERF_CLIENT,
+  /** Do a bidirectional test simultaneously */
+  LWIPERF_DUAL,
+  /** Do a bidirectional test individually */
+  LWIPERF_TRADEOFF
+};
+
+/** Prototype of a report function that is called when a session is finished.
+    This report function can show the test results.
+    @param report_type contains the test result */
+typedef void (*lwiperf_report_fn)(void *arg, enum lwiperf_report_type report_type,
+  const ip_addr_t* local_addr, u16_t local_port, const ip_addr_t* remote_addr, u16_t remote_port,
+  u32_t bytes_transferred, u32_t ms_duration, u32_t bandwidth_kbitpsec);
+
+void* lwiperf_start_tcp_server(const ip_addr_t* local_addr, u16_t local_port,
+                               lwiperf_report_fn report_fn, void* report_arg);
+void* lwiperf_start_tcp_server_default(lwiperf_report_fn report_fn, void* report_arg);
+void* lwiperf_start_tcp_client(const ip_addr_t* remote_addr, u16_t remote_port,
+                               enum lwiperf_client_type type,
+                               lwiperf_report_fn report_fn, void* report_arg);
+void* lwiperf_start_tcp_client_default(const ip_addr_t* remote_addr,
+                               lwiperf_report_fn report_fn, void* report_arg);
+
+void  lwiperf_abort(void* lwiperf_session);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LWIP_HDR_APPS_LWIPERF_H */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/apps/mdns.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/apps/mdns.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/apps/mdns.h	(revision 457)
@@ -0,0 +1,105 @@
+/**
+ * @file
+ * MDNS responder
+ */
+
+ /*
+ * Copyright (c) 2015 Verisure Innovation AB
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Erik Ekman <erik@kryo.se>
+ *
+ */
+
+#ifndef LWIP_HDR_APPS_MDNS_H
+#define LWIP_HDR_APPS_MDNS_H
+
+#include "lwip/apps/mdns_opts.h"
+#include "lwip/netif.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if LWIP_MDNS_RESPONDER
+
+enum mdns_sd_proto {
+  DNSSD_PROTO_UDP = 0,
+  DNSSD_PROTO_TCP = 1
+};
+
+#define MDNS_PROBING_CONFLICT   0
+#define MDNS_PROBING_SUCCESSFUL 1
+
+#define MDNS_LABEL_MAXLEN  63
+
+struct mdns_host;
+struct mdns_service;
+
+/** Callback function to add text to a reply, called when generating the reply */
+typedef void (*service_get_txt_fn_t)(struct mdns_service *service, void *txt_userdata);
+
+/** Callback function to let application know the result of probing network for name
+ * uniqueness, called with result MDNS_PROBING_SUCCESSFUL if no other node claimed
+ * use for the name for the netif or a service and is safe to use, or MDNS_PROBING_CONFLICT
+ * if another node is already using it and mdns is disabled on this interface */
+typedef void (*mdns_name_result_cb_t)(struct netif* netif, u8_t result);
+
+void mdns_resp_init(void);
+
+void mdns_resp_register_name_result_cb(mdns_name_result_cb_t cb);
+
+err_t mdns_resp_add_netif(struct netif *netif, const char *hostname, u32_t dns_ttl);
+err_t mdns_resp_remove_netif(struct netif *netif);
+err_t mdns_resp_rename_netif(struct netif *netif, const char *hostname);
+
+s8_t  mdns_resp_add_service(struct netif *netif, const char *name, const char *service, enum mdns_sd_proto proto, u16_t port, u32_t dns_ttl, service_get_txt_fn_t txt_fn, void *txt_userdata);
+err_t mdns_resp_del_service(struct netif *netif, s8_t slot);
+err_t mdns_resp_rename_service(struct netif *netif, s8_t slot, const char *name);
+
+err_t mdns_resp_add_service_txtitem(struct mdns_service *service, const char *txt, u8_t txt_len);
+
+void mdns_resp_restart(struct netif *netif);
+void mdns_resp_announce(struct netif *netif);
+
+/**
+ * @ingroup mdns
+ * Announce IP settings have changed on netif.
+ * Call this in your callback registered by netif_set_status_callback().
+ * No need to call this function when LWIP_NETIF_EXT_STATUS_CALLBACK==1,
+ * this handled automatically for you.
+ * @param netif The network interface where settings have changed.
+ */
+#define mdns_resp_netif_settings_changed(netif) mdns_resp_announce(netif)
+
+#endif /* LWIP_MDNS_RESPONDER */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LWIP_HDR_APPS_MDNS_H */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/apps/mdns_opts.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/apps/mdns_opts.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/apps/mdns_opts.h	(revision 457)
@@ -0,0 +1,81 @@
+/**
+ * @file
+ * MDNS responder
+ */
+
+ /*
+ * Copyright (c) 2015 Verisure Innovation AB
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Erik Ekman <erik@kryo.se>
+ *
+ */
+
+#ifndef LWIP_HDR_APPS_MDNS_OPTS_H
+#define LWIP_HDR_APPS_MDNS_OPTS_H
+
+#include "lwip/opt.h"
+
+/**
+ * @defgroup mdns_opts Options
+ * @ingroup mdns
+ * @{
+ */
+
+/**
+ * LWIP_MDNS_RESPONDER==1: Turn on multicast DNS module. UDP must be available for MDNS
+ * transport. IGMP is needed for IPv4 multicast.
+ */
+#ifndef LWIP_MDNS_RESPONDER
+#define LWIP_MDNS_RESPONDER             0
+#endif /* LWIP_MDNS_RESPONDER */
+
+/** The maximum number of services per netif */
+#ifndef MDNS_MAX_SERVICES
+#define MDNS_MAX_SERVICES               1
+#endif
+
+/** MDNS_RESP_USENETIF_EXTCALLBACK==1: register an ext_callback on the netif
+ * to automatically restart probing/announcing on status or address change.
+ */
+#ifndef MDNS_RESP_USENETIF_EXTCALLBACK
+#define MDNS_RESP_USENETIF_EXTCALLBACK  LWIP_NETIF_EXT_STATUS_CALLBACK
+#endif
+
+/**
+ * MDNS_DEBUG: Enable debugging for multicast DNS.
+ */
+#ifndef MDNS_DEBUG
+#define MDNS_DEBUG                       LWIP_DBG_OFF
+#endif
+
+/**
+ * @}
+ */
+
+#endif /* LWIP_HDR_APPS_MDNS_OPTS_H */
+
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/apps/mdns_priv.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/apps/mdns_priv.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/apps/mdns_priv.h	(revision 457)
@@ -0,0 +1,74 @@
+/**
+ * @file
+ * MDNS responder private definitions
+ */
+
+ /*
+ * Copyright (c) 2015 Verisure Innovation AB
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Erik Ekman <erik@kryo.se>
+ *
+ */
+#ifndef LWIP_HDR_MDNS_PRIV_H
+#define LWIP_HDR_MDNS_PRIV_H
+
+#include "lwip/apps/mdns_opts.h"
+#include "lwip/pbuf.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if LWIP_MDNS_RESPONDER
+
+/* Domain struct and methods - visible for unit tests */
+
+#define MDNS_DOMAIN_MAXLEN 256
+#define MDNS_READNAME_ERROR 0xFFFF
+
+struct mdns_domain {
+  /* Encoded domain name */
+  u8_t name[MDNS_DOMAIN_MAXLEN];
+  /* Total length of domain name, including zero */
+  u16_t length;
+  /* Set if compression of this domain is not allowed */
+  u8_t skip_compression;
+};
+
+err_t mdns_domain_add_label(struct mdns_domain *domain, const char *label, u8_t len);
+u16_t mdns_readname(struct pbuf *p, u16_t offset, struct mdns_domain *domain);
+int mdns_domain_eq(struct mdns_domain *a, struct mdns_domain *b);
+u16_t mdns_compress_domain(struct pbuf *pbuf, u16_t *offset, struct mdns_domain *domain);
+
+#endif /* LWIP_MDNS_RESPONDER */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LWIP_HDR_MDNS_PRIV_H */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/apps/mqtt.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/apps/mqtt.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/apps/mqtt.h	(revision 457)
@@ -0,0 +1,205 @@
+/**
+ * @file
+ * MQTT client
+ */
+
+/*
+ * Copyright (c) 2016 Erik Andersson
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Erik Andersson
+ *
+ */
+#ifndef LWIP_HDR_APPS_MQTT_CLIENT_H
+#define LWIP_HDR_APPS_MQTT_CLIENT_H
+
+#include "lwip/apps/mqtt_opts.h"
+#include "lwip/err.h"
+#include "lwip/ip_addr.h"
+#include "lwip/prot/iana.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct mqtt_client_s mqtt_client_t;
+
+#if LWIP_ALTCP && LWIP_ALTCP_TLS
+struct altcp_tls_config;
+#endif
+
+/** @ingroup mqtt
+ * Default MQTT port (non-TLS) */
+#define MQTT_PORT     LWIP_IANA_PORT_MQTT
+/** @ingroup mqtt
+ * Default MQTT TLS port */
+#define MQTT_TLS_PORT LWIP_IANA_PORT_SECURE_MQTT
+
+/*---------------------------------------------------------------------------------------------- */
+/* Connection with server */
+
+/**
+ * @ingroup mqtt
+ * Client information and connection parameters */
+struct mqtt_connect_client_info_t {
+  /** Client identifier, must be set by caller */
+  const char *client_id;
+  /** User name, set to NULL if not used */
+  const char* client_user;
+  /** Password, set to NULL if not used */
+  const char* client_pass;
+  /** keep alive time in seconds, 0 to disable keep alive functionality*/
+  u16_t keep_alive;
+  /** will topic, set to NULL if will is not to be used,
+      will_msg, will_qos and will retain are then ignored */
+  const char* will_topic;
+  /** will_msg, see will_topic */
+  const char* will_msg;
+  /** will_qos, see will_topic */
+  u8_t will_qos;
+  /** will_retain, see will_topic */
+  u8_t will_retain;
+#if LWIP_ALTCP && LWIP_ALTCP_TLS
+  /** TLS configuration for secure connections */
+  struct altcp_tls_config *tls_config;
+#endif
+};
+
+/**
+ * @ingroup mqtt
+ * Connection status codes */
+typedef enum
+{
+  /** Accepted */
+  MQTT_CONNECT_ACCEPTED                 = 0,
+  /** Refused protocol version */
+  MQTT_CONNECT_REFUSED_PROTOCOL_VERSION = 1,
+  /** Refused identifier */
+  MQTT_CONNECT_REFUSED_IDENTIFIER       = 2,
+  /** Refused server */
+  MQTT_CONNECT_REFUSED_SERVER           = 3,
+  /** Refused user credentials */
+  MQTT_CONNECT_REFUSED_USERNAME_PASS    = 4,
+  /** Refused not authorized */
+  MQTT_CONNECT_REFUSED_NOT_AUTHORIZED_  = 5,
+  /** Disconnected */
+  MQTT_CONNECT_DISCONNECTED             = 256,
+  /** Timeout */
+  MQTT_CONNECT_TIMEOUT                  = 257
+} mqtt_connection_status_t;
+
+/**
+ * @ingroup mqtt
+ * Function prototype for mqtt connection status callback. Called when
+ * client has connected to the server after initiating a mqtt connection attempt by
+ * calling mqtt_client_connect() or when connection is closed by server or an error
+ *
+ * @param client MQTT client itself
+ * @param arg Additional argument to pass to the callback function
+ * @param status Connect result code or disconnection notification @see mqtt_connection_status_t
+ *
+ */
+typedef void (*mqtt_connection_cb_t)(mqtt_client_t *client, void *arg, mqtt_connection_status_t status);
+
+
+/**
+ * @ingroup mqtt
+ * Data callback flags */
+enum {
+  /** Flag set when last fragment of data arrives in data callback */
+  MQTT_DATA_FLAG_LAST = 1
+};
+
+/** 
+ * @ingroup mqtt
+ * Function prototype for MQTT incoming publish data callback function. Called when data
+ * arrives to a subscribed topic @see mqtt_subscribe
+ *
+ * @param arg Additional argument to pass to the callback function
+ * @param data User data, pointed object, data may not be referenced after callback return,
+          NULL is passed when all publish data are delivered
+ * @param len Length of publish data fragment
+ * @param flags MQTT_DATA_FLAG_LAST set when this call contains the last part of data from publish message
+ *
+ */
+typedef void (*mqtt_incoming_data_cb_t)(void *arg, const u8_t *data, u16_t len, u8_t flags);
+
+
+/** 
+ * @ingroup mqtt
+ * Function prototype for MQTT incoming publish function. Called when an incoming publish
+ * arrives to a subscribed topic @see mqtt_subscribe
+ *
+ * @param arg Additional argument to pass to the callback function
+ * @param topic Zero terminated Topic text string, topic may not be referenced after callback return
+ * @param tot_len Total length of publish data, if set to 0 (no publish payload) data callback will not be invoked
+ */
+typedef void (*mqtt_incoming_publish_cb_t)(void *arg, const char *topic, u32_t tot_len);
+
+
+/**
+ * @ingroup mqtt
+ * Function prototype for mqtt request callback. Called when a subscribe, unsubscribe
+ * or publish request has completed
+ * @param arg Pointer to user data supplied when invoking request
+ * @param err ERR_OK on success
+ *            ERR_TIMEOUT if no response was received within timeout,
+ *            ERR_ABRT if (un)subscribe was denied
+ */
+typedef void (*mqtt_request_cb_t)(void *arg, err_t err);
+
+
+err_t mqtt_client_connect(mqtt_client_t *client, const ip_addr_t *ipaddr, u16_t port, mqtt_connection_cb_t cb, void *arg,
+                   const struct mqtt_connect_client_info_t *client_info);
+
+void mqtt_disconnect(mqtt_client_t *client);
+
+mqtt_client_t *mqtt_client_new(void);
+void mqtt_client_free(mqtt_client_t* client);
+
+u8_t mqtt_client_is_connected(mqtt_client_t *client);
+
+void mqtt_set_inpub_callback(mqtt_client_t *client, mqtt_incoming_publish_cb_t,
+                             mqtt_incoming_data_cb_t data_cb, void *arg);
+
+err_t mqtt_sub_unsub(mqtt_client_t *client, const char *topic, u8_t qos, mqtt_request_cb_t cb, void *arg, u8_t sub);
+
+/** @ingroup mqtt
+ *Subscribe to topic */
+#define mqtt_subscribe(client, topic, qos, cb, arg) mqtt_sub_unsub(client, topic, qos, cb, arg, 1)
+/** @ingroup mqtt
+ *  Unsubscribe to topic */
+#define mqtt_unsubscribe(client, topic, cb, arg) mqtt_sub_unsub(client, topic, 0, cb, arg, 0)
+
+err_t mqtt_publish(mqtt_client_t *client, const char *topic, const void *payload, u16_t payload_length, u8_t qos, u8_t retain,
+                                    mqtt_request_cb_t cb, void *arg);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LWIP_HDR_APPS_MQTT_CLIENT_H */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/apps/mqtt_opts.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/apps/mqtt_opts.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/apps/mqtt_opts.h	(revision 457)
@@ -0,0 +1,103 @@
+/**
+ * @file
+ * MQTT client options
+ */
+
+/*
+ * Copyright (c) 2016 Erik Andersson
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Erik Andersson
+ *
+ */
+#ifndef LWIP_HDR_APPS_MQTT_OPTS_H
+#define LWIP_HDR_APPS_MQTT_OPTS_H
+
+#include "lwip/opt.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @defgroup mqtt_opts Options
+ * @ingroup mqtt
+ * @{
+ */
+
+/**
+ * Output ring-buffer size, must be able to fit largest outgoing publish message topic+payloads
+ */
+#ifndef MQTT_OUTPUT_RINGBUF_SIZE
+#define MQTT_OUTPUT_RINGBUF_SIZE 256
+#endif
+
+/**
+ * Number of bytes in receive buffer, must be at least the size of the longest incoming topic + 8
+ * If one wants to avoid fragmented incoming publish, set length to max incoming topic length + max payload length + 8
+ */
+#ifndef MQTT_VAR_HEADER_BUFFER_LEN
+#define MQTT_VAR_HEADER_BUFFER_LEN 128
+#endif
+
+/**
+ * Maximum number of pending subscribe, unsubscribe and publish requests to server .
+ */
+#ifndef MQTT_REQ_MAX_IN_FLIGHT
+#define MQTT_REQ_MAX_IN_FLIGHT 4
+#endif
+
+/**
+ * Seconds between each cyclic timer call.
+ */
+#ifndef MQTT_CYCLIC_TIMER_INTERVAL
+#define MQTT_CYCLIC_TIMER_INTERVAL 5
+#endif
+
+/**
+ * Publish, subscribe and unsubscribe request timeout in seconds.
+ */
+#ifndef MQTT_REQ_TIMEOUT
+#define MQTT_REQ_TIMEOUT 30
+#endif
+
+/**
+ * Seconds for MQTT connect response timeout after sending connect request
+ */
+#ifndef MQTT_CONNECT_TIMOUT
+#define MQTT_CONNECT_TIMOUT 100
+#endif
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LWIP_HDR_APPS_MQTT_OPTS_H */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/apps/mqtt_priv.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/apps/mqtt_priv.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/apps/mqtt_priv.h	(revision 457)
@@ -0,0 +1,104 @@
+/**
+ * @file
+ * MQTT client (private interface)
+ */
+
+/*
+ * Copyright (c) 2016 Erik Andersson
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Erik Andersson
+ *
+ */
+#ifndef LWIP_HDR_APPS_MQTT_PRIV_H
+#define LWIP_HDR_APPS_MQTT_PRIV_H
+
+#include "lwip/apps/mqtt.h"
+#include "lwip/altcp.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Pending request item, binds application callback to pending server requests */
+struct mqtt_request_t
+{
+  /** Next item in list, NULL means this is the last in chain,
+      next pointing at itself means request is unallocated */
+  struct mqtt_request_t *next;
+  /** Callback to upper layer */
+  mqtt_request_cb_t cb;
+  void *arg;
+  /** MQTT packet identifier */
+  u16_t pkt_id;
+  /** Expire time relative to element before this  */
+  u16_t timeout_diff;
+};
+
+/** Ring buffer */
+struct mqtt_ringbuf_t {
+  u16_t put;
+  u16_t get;
+  u8_t buf[MQTT_OUTPUT_RINGBUF_SIZE];
+};
+
+/** MQTT client */
+struct mqtt_client_s
+{
+  /** Timers and timeouts */
+  u16_t cyclic_tick;
+  u16_t keep_alive;
+  u16_t server_watchdog;
+  /** Packet identifier generator*/
+  u16_t pkt_id_seq;
+  /** Packet identifier of pending incoming publish */
+  u16_t inpub_pkt_id;
+  /** Connection state */
+  u8_t conn_state;
+  struct altcp_pcb *conn;
+  /** Connection callback */
+  void *connect_arg;
+  mqtt_connection_cb_t connect_cb;
+  /** Pending requests to server */
+  struct mqtt_request_t *pend_req_queue;
+  struct mqtt_request_t req_list[MQTT_REQ_MAX_IN_FLIGHT];
+  void *inpub_arg;
+  /** Incoming data callback */
+  mqtt_incoming_data_cb_t data_cb;
+  mqtt_incoming_publish_cb_t pub_cb;
+  /** Input */
+  u32_t msg_idx;
+  u8_t rx_buffer[MQTT_VAR_HEADER_BUFFER_LEN];
+  /** Output ring-buffer */
+  struct mqtt_ringbuf_t output;
+};
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LWIP_HDR_APPS_MQTT_PRIV_H */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/apps/netbiosns.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/apps/netbiosns.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/apps/netbiosns.h	(revision 457)
@@ -0,0 +1,51 @@
+/**
+ * @file
+ * NETBIOS name service responder
+ */
+
+/*
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ */
+#ifndef LWIP_HDR_APPS_NETBIOS_H
+#define LWIP_HDR_APPS_NETBIOS_H
+
+#include "lwip/apps/netbiosns_opts.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void netbiosns_init(void);
+#ifndef NETBIOS_LWIP_NAME
+void netbiosns_set_name(const char* hostname);
+#endif
+void netbiosns_stop(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LWIP_HDR_APPS_NETBIOS_H */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/apps/netbiosns_opts.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/apps/netbiosns_opts.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/apps/netbiosns_opts.h	(revision 457)
@@ -0,0 +1,66 @@
+/**
+ * @file
+ * NETBIOS name service responder options
+ */
+
+/*
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ */
+#ifndef LWIP_HDR_APPS_NETBIOS_OPTS_H
+#define LWIP_HDR_APPS_NETBIOS_OPTS_H
+
+#include "lwip/opt.h"
+
+/**
+ * @defgroup netbiosns_opts Options
+ * @ingroup netbiosns
+ * @{
+ */
+
+/** NetBIOS name of lwip device
+ * This must be uppercase until NETBIOS_STRCMP() is defined to a string
+ * comparision function that is case insensitive.
+ * If you want to use the netif's hostname, use this (with LWIP_NETIF_HOSTNAME):
+ * (ip_current_netif() != NULL ? ip_current_netif()->hostname != NULL ? ip_current_netif()->hostname : "" : "")
+ *
+ * If this is not defined, netbiosns_set_name() can be called at runtime to change the name.
+ */
+#ifdef __DOXYGEN__
+#define NETBIOS_LWIP_NAME "NETBIOSLWIPDEV"
+#endif
+
+/** Respond to NetBIOS name queries
+ * Default is disabled
+ */
+#if !defined LWIP_NETBIOS_RESPOND_NAME_QUERY || defined __DOXYGEN__
+#define LWIP_NETBIOS_RESPOND_NAME_QUERY   0
+#endif
+
+/**
+ * @}
+ */
+
+#endif /* LWIP_HDR_APPS_NETBIOS_OPTS_H */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/apps/smtp.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/apps/smtp.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/apps/smtp.h	(revision 457)
@@ -0,0 +1,128 @@
+#ifndef LWIP_HDR_APPS_SMTP_H
+#define LWIP_HDR_APPS_SMTP_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "lwip/apps/smtp_opts.h"
+#include "lwip/err.h"
+#include "lwip/prot/iana.h"
+
+/** The default TCP port used for SMTP */
+#define SMTP_DEFAULT_PORT         LWIP_IANA_PORT_SMTP
+/** The default TCP port used for SMTPS */
+#define SMTPS_DEFAULT_PORT        LWIP_IANA_PORT_SMTPS
+
+/** Email successfully sent */
+#define SMTP_RESULT_OK            0
+/** Unknown error */
+#define SMTP_RESULT_ERR_UNKNOWN   1
+/** Connection to server failed */
+#define SMTP_RESULT_ERR_CONNECT   2
+/** Failed to resolve server hostname */
+#define SMTP_RESULT_ERR_HOSTNAME  3
+/** Connection unexpectedly closed by remote server */
+#define SMTP_RESULT_ERR_CLOSED    4
+/** Connection timed out (server didn't respond in time) */
+#define SMTP_RESULT_ERR_TIMEOUT   5
+/** Server responded with an unknown response code */
+#define SMTP_RESULT_ERR_SVR_RESP  6
+/** Out of resources locally */
+#define SMTP_RESULT_ERR_MEM       7
+
+/** Prototype of an smtp callback function
+ *
+ * @param arg argument specified when initiating the email
+ * @param smtp_result result of the mail transfer (see defines SMTP_RESULT_*)
+ * @param srv_err if aborted by the server, this contains the error code received
+ * @param err an error returned by internal lwip functions, can help to specify
+ *            the source of the error but must not necessarily be != ERR_OK
+ */
+typedef void (*smtp_result_fn)(void *arg, u8_t smtp_result, u16_t srv_err, err_t err);
+
+/** This structure is used as argument for smtp_send_mail_int(),
+ * which in turn can be used with tcpip_callback() to send mail
+ * from interrupt context, e.g. like this:
+ *    struct smtp_send_request *req; (to be filled)
+ *    tcpip_try_callback(smtp_send_mail_int, (void*)req);
+ *
+ * For member description, see parameter description of smtp_send_mail().
+ * When using with tcpip_callback, this structure has to stay allocated
+ * (e.g. using mem_malloc/mem_free) until its 'callback_fn' is called.
+ */
+struct smtp_send_request {
+  const char *from;
+  const char* to;
+  const char* subject;
+  const char* body;
+  smtp_result_fn callback_fn;
+  void* callback_arg;
+  /** If this is != 0, data is *not* copied into an extra buffer
+   * but used from the pointers supplied in this struct.
+   * This means less memory usage, but data must stay untouched until
+   * the callback function is called. */
+  u8_t static_data;
+};
+
+
+#if SMTP_BODYDH
+
+#ifndef SMTP_BODYDH_BUFFER_SIZE
+#define SMTP_BODYDH_BUFFER_SIZE 256
+#endif /* SMTP_BODYDH_BUFFER_SIZE */
+
+struct smtp_bodydh {
+  u16_t state;
+  u16_t length; /* Length of content in buffer */
+  char buffer[SMTP_BODYDH_BUFFER_SIZE]; /* buffer for generated content */
+#ifdef SMTP_BODYDH_USER_SIZE
+  u8_t user[SMTP_BODYDH_USER_SIZE];
+#endif /* SMTP_BODYDH_USER_SIZE */
+};
+
+enum bdh_retvals_e {
+  BDH_DONE = 0,
+  BDH_WORKING
+};
+
+/** Prototype of an smtp body callback function
+ * It receives a struct smtp_bodydh, and a buffer to write data,
+ * must return BDH_WORKING to be called again and BDH_DONE when
+ * it has finished processing. This one tries to fill one TCP buffer with
+ * data, your function will be repeatedly called until that happens; so if you
+ * know you'll be taking too long to serve your request, pause once in a while
+ * by writing length=0 to avoid hogging system resources
+ *
+ * @param arg argument specified when initiating the email
+ * @param smtp_bodydh state handling + buffer structure
+ */
+typedef int (*smtp_bodycback_fn)(void *arg, struct smtp_bodydh *bodydh);
+
+err_t smtp_send_mail_bodycback(const char *from, const char* to, const char* subject,
+                     smtp_bodycback_fn bodycback_fn, smtp_result_fn callback_fn, void* callback_arg);
+
+#endif /* SMTP_BODYDH */
+
+
+err_t smtp_set_server_addr(const char* server);
+void smtp_set_server_port(u16_t port);
+#if LWIP_ALTCP && LWIP_ALTCP_TLS
+struct altcp_tls_config;
+void smtp_set_tls_config(struct altcp_tls_config *tls_config);
+#endif
+err_t smtp_set_auth(const char* username, const char* pass);
+err_t smtp_send_mail(const char *from, const char* to, const char* subject, const char* body,
+                     smtp_result_fn callback_fn, void* callback_arg);
+err_t smtp_send_mail_static(const char *from, const char* to, const char* subject, const char* body,
+                     smtp_result_fn callback_fn, void* callback_arg);
+void smtp_send_mail_int(void *arg);
+#ifdef LWIP_DEBUG
+const char* smtp_result_str(u8_t smtp_result);
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LWIP_HDR_APPS_SMTP_H */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/apps/smtp_opts.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/apps/smtp_opts.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/apps/smtp_opts.h	(revision 457)
@@ -0,0 +1,81 @@
+#ifndef LWIP_HDR_APPS_SMTP_OPTS_H
+#define LWIP_HDR_APPS_SMTP_OPTS_H
+
+#include "lwip/opt.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+    
+/**
+ * @defgroup smtp_opts Options
+ * @ingroup smtp
+ * 
+ * @{
+ */
+    
+/** Set this to 1 to enable data handler callback on BODY */
+#ifndef SMTP_BODYDH
+#define SMTP_BODYDH             0
+#endif
+
+/** SMTP_DEBUG: Enable debugging for SNTP. */
+#ifndef SMTP_DEBUG
+#define SMTP_DEBUG              LWIP_DBG_OFF
+#endif
+
+/** Maximum length reserved for server name including terminating 0 byte */
+#ifndef SMTP_MAX_SERVERNAME_LEN
+#define SMTP_MAX_SERVERNAME_LEN 256
+#endif
+
+/** Maximum length reserved for username */
+#ifndef SMTP_MAX_USERNAME_LEN
+#define SMTP_MAX_USERNAME_LEN   32
+#endif
+
+/** Maximum length reserved for password */
+#ifndef SMTP_MAX_PASS_LEN
+#define SMTP_MAX_PASS_LEN       32
+#endif
+
+/** Set this to 0 if you know the authentication data will not change
+ * during the smtp session, which saves some heap space. */
+#ifndef SMTP_COPY_AUTHDATA
+#define SMTP_COPY_AUTHDATA      1
+#endif
+
+/** Set this to 0 to save some code space if you know for sure that all data
+ * passed to this module conforms to the requirements in the SMTP RFC.
+ * WARNING: use this with care!
+ */
+#ifndef SMTP_CHECK_DATA
+#define SMTP_CHECK_DATA         1
+#endif
+
+/** Set this to 1 to enable AUTH PLAIN support */
+#ifndef SMTP_SUPPORT_AUTH_PLAIN
+#define SMTP_SUPPORT_AUTH_PLAIN 1
+#endif
+
+/** Set this to 1 to enable AUTH LOGIN support */
+#ifndef SMTP_SUPPORT_AUTH_LOGIN
+#define SMTP_SUPPORT_AUTH_LOGIN 1
+#endif
+
+/* Memory allocation/deallocation can be overridden... */
+#ifndef SMTP_STATE_MALLOC
+#define SMTP_STATE_MALLOC(size)       mem_malloc(size)
+#define SMTP_STATE_FREE(ptr)          mem_free(ptr)
+#endif
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* SMTP_OPTS_H */
+
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/apps/snmp.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/apps/snmp.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/apps/snmp.h	(revision 457)
@@ -0,0 +1,135 @@
+/**
+ * @file
+ * SNMP server main API - start and basic configuration
+ */
+
+/*
+ * Copyright (c) 2001, 2002 Leon Woestenberg <leon.woestenberg@axon.tv>
+ * Copyright (c) 2001, 2002 Axon Digital Design B.V., The Netherlands.
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Leon Woestenberg <leon.woestenberg@axon.tv>
+ *         Martin Hentschel <info@cl-soft.de>
+ *
+ */
+#ifndef LWIP_HDR_APPS_SNMP_H
+#define LWIP_HDR_APPS_SNMP_H
+
+#include "lwip/apps/snmp_opts.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if LWIP_SNMP /* don't build if not configured for use in lwipopts.h */
+
+#include "lwip/err.h"
+#include "lwip/apps/snmp_core.h"
+
+/** SNMP variable binding descriptor (publically needed for traps) */
+struct snmp_varbind
+{
+  /** pointer to next varbind, NULL for last in list */
+  struct snmp_varbind *next;
+  /** pointer to previous varbind, NULL for first in list */
+  struct snmp_varbind *prev;
+
+  /** object identifier */
+  struct snmp_obj_id oid;
+
+  /** value ASN1 type */
+  u8_t type;
+  /** object value length */
+  u16_t value_len;
+  /** object value */
+  void *value;
+};
+
+/**
+ * @ingroup snmp_core
+ * Agent setup, start listening to port 161.
+ */
+void snmp_init(void);
+void snmp_set_mibs(const struct snmp_mib **mibs, u8_t num_mibs);
+
+void snmp_set_device_enterprise_oid(const struct snmp_obj_id* device_enterprise_oid);
+const struct snmp_obj_id* snmp_get_device_enterprise_oid(void);
+
+void snmp_trap_dst_enable(u8_t dst_idx, u8_t enable);
+void snmp_trap_dst_ip_set(u8_t dst_idx, const ip_addr_t *dst);
+
+/** Generic trap: cold start */
+#define SNMP_GENTRAP_COLDSTART 0
+/** Generic trap: warm start */
+#define SNMP_GENTRAP_WARMSTART 1
+/** Generic trap: link down */
+#define SNMP_GENTRAP_LINKDOWN 2
+/** Generic trap: link up */
+#define SNMP_GENTRAP_LINKUP 3
+/** Generic trap: authentication failure */
+#define SNMP_GENTRAP_AUTH_FAILURE 4
+/** Generic trap: EGP neighbor lost */
+#define SNMP_GENTRAP_EGP_NEIGHBOR_LOSS 5
+/** Generic trap: enterprise specific */
+#define SNMP_GENTRAP_ENTERPRISE_SPECIFIC 6
+
+err_t snmp_send_trap_generic(s32_t generic_trap);
+err_t snmp_send_trap_specific(s32_t specific_trap, struct snmp_varbind *varbinds);
+err_t snmp_send_trap(const struct snmp_obj_id* oid, s32_t generic_trap, s32_t specific_trap, struct snmp_varbind *varbinds);
+
+#define SNMP_AUTH_TRAPS_DISABLED 0
+#define SNMP_AUTH_TRAPS_ENABLED  1
+void snmp_set_auth_traps_enabled(u8_t enable);
+u8_t snmp_get_auth_traps_enabled(void);
+
+u8_t snmp_v1_enabled(void);
+u8_t snmp_v2c_enabled(void);
+u8_t snmp_v3_enabled(void);
+void snmp_v1_enable(u8_t enable);
+void snmp_v2c_enable(u8_t enable);
+void snmp_v3_enable(u8_t enable);
+
+const char * snmp_get_community(void);
+const char * snmp_get_community_write(void);
+const char * snmp_get_community_trap(void);
+void snmp_set_community(const char * const community);
+void snmp_set_community_write(const char * const community);
+void snmp_set_community_trap(const char * const community);
+
+void snmp_coldstart_trap(void);
+void snmp_authfail_trap(void);
+
+typedef void (*snmp_write_callback_fct)(const u32_t* oid, u8_t oid_len, void* callback_arg);
+void snmp_set_write_callback(snmp_write_callback_fct write_callback, void* callback_arg);
+
+#endif /* LWIP_SNMP */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LWIP_HDR_APPS_SNMP_H */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/apps/snmp_core.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/apps/snmp_core.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/apps/snmp_core.h	(revision 457)
@@ -0,0 +1,377 @@
+/**
+ * @file
+ * SNMP core API for implementing MIBs
+ */
+
+/*
+ * Copyright (c) 2006 Axon Digital Design B.V., The Netherlands.
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * Author: Christiaan Simons <christiaan.simons@axon.tv>
+ *         Martin Hentschel <info@cl-soft.de>
+ */
+
+#ifndef LWIP_HDR_APPS_SNMP_CORE_H
+#define LWIP_HDR_APPS_SNMP_CORE_H
+
+#include "lwip/apps/snmp_opts.h"
+
+#if LWIP_SNMP /* don't build if not configured for use in lwipopts.h */
+
+#include "lwip/ip_addr.h"
+#include "lwip/err.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* basic ASN1 defines */
+#define SNMP_ASN1_CLASS_UNIVERSAL   0x00
+#define SNMP_ASN1_CLASS_APPLICATION 0x40
+#define SNMP_ASN1_CLASS_CONTEXT     0x80
+#define SNMP_ASN1_CLASS_PRIVATE     0xC0
+
+#define SNMP_ASN1_CONTENTTYPE_PRIMITIVE   0x00
+#define SNMP_ASN1_CONTENTTYPE_CONSTRUCTED 0x20
+
+/* universal tags (from ASN.1 spec.) */
+#define SNMP_ASN1_UNIVERSAL_END_OF_CONTENT  0
+#define SNMP_ASN1_UNIVERSAL_INTEGER         2
+#define SNMP_ASN1_UNIVERSAL_OCTET_STRING    4
+#define SNMP_ASN1_UNIVERSAL_NULL            5
+#define SNMP_ASN1_UNIVERSAL_OBJECT_ID       6
+#define SNMP_ASN1_UNIVERSAL_SEQUENCE_OF    16
+
+/* application specific (SNMP) tags (from SNMPv2-SMI) */
+#define SNMP_ASN1_APPLICATION_IPADDR    0  /* [APPLICATION 0] IMPLICIT OCTET STRING (SIZE (4)) */
+#define SNMP_ASN1_APPLICATION_COUNTER   1  /* [APPLICATION 1] IMPLICIT INTEGER (0..4294967295) => u32_t */
+#define SNMP_ASN1_APPLICATION_GAUGE     2  /* [APPLICATION 2] IMPLICIT INTEGER (0..4294967295) => u32_t */
+#define SNMP_ASN1_APPLICATION_TIMETICKS 3  /* [APPLICATION 3] IMPLICIT INTEGER (0..4294967295) => u32_t */
+#define SNMP_ASN1_APPLICATION_OPAQUE    4  /* [APPLICATION 4] IMPLICIT OCTET STRING */
+#define SNMP_ASN1_APPLICATION_COUNTER64 6  /* [APPLICATION 6] IMPLICIT INTEGER (0..18446744073709551615) */
+
+/* context specific (SNMP) tags (from RFC 1905) */
+#define SNMP_ASN1_CONTEXT_VARBIND_NO_SUCH_INSTANCE 1
+
+/* full ASN1 type defines */
+#define SNMP_ASN1_TYPE_END_OF_CONTENT (SNMP_ASN1_CLASS_UNIVERSAL | SNMP_ASN1_CONTENTTYPE_PRIMITIVE | SNMP_ASN1_UNIVERSAL_END_OF_CONTENT)
+#define SNMP_ASN1_TYPE_INTEGER        (SNMP_ASN1_CLASS_UNIVERSAL | SNMP_ASN1_CONTENTTYPE_PRIMITIVE | SNMP_ASN1_UNIVERSAL_INTEGER)
+#define SNMP_ASN1_TYPE_OCTET_STRING   (SNMP_ASN1_CLASS_UNIVERSAL | SNMP_ASN1_CONTENTTYPE_PRIMITIVE | SNMP_ASN1_UNIVERSAL_OCTET_STRING)
+#define SNMP_ASN1_TYPE_NULL           (SNMP_ASN1_CLASS_UNIVERSAL | SNMP_ASN1_CONTENTTYPE_PRIMITIVE | SNMP_ASN1_UNIVERSAL_NULL)
+#define SNMP_ASN1_TYPE_OBJECT_ID      (SNMP_ASN1_CLASS_UNIVERSAL | SNMP_ASN1_CONTENTTYPE_PRIMITIVE | SNMP_ASN1_UNIVERSAL_OBJECT_ID)
+#define SNMP_ASN1_TYPE_SEQUENCE       (SNMP_ASN1_CLASS_UNIVERSAL | SNMP_ASN1_CONTENTTYPE_CONSTRUCTED | SNMP_ASN1_UNIVERSAL_SEQUENCE_OF)
+#define SNMP_ASN1_TYPE_IPADDR         (SNMP_ASN1_CLASS_APPLICATION | SNMP_ASN1_CONTENTTYPE_PRIMITIVE | SNMP_ASN1_APPLICATION_IPADDR)
+#define SNMP_ASN1_TYPE_IPADDRESS      SNMP_ASN1_TYPE_IPADDR
+#define SNMP_ASN1_TYPE_COUNTER        (SNMP_ASN1_CLASS_APPLICATION | SNMP_ASN1_CONTENTTYPE_PRIMITIVE | SNMP_ASN1_APPLICATION_COUNTER)
+#define SNMP_ASN1_TYPE_COUNTER32      SNMP_ASN1_TYPE_COUNTER
+#define SNMP_ASN1_TYPE_GAUGE          (SNMP_ASN1_CLASS_APPLICATION | SNMP_ASN1_CONTENTTYPE_PRIMITIVE | SNMP_ASN1_APPLICATION_GAUGE)
+#define SNMP_ASN1_TYPE_GAUGE32        SNMP_ASN1_TYPE_GAUGE
+#define SNMP_ASN1_TYPE_UNSIGNED32     SNMP_ASN1_TYPE_GAUGE
+#define SNMP_ASN1_TYPE_TIMETICKS      (SNMP_ASN1_CLASS_APPLICATION | SNMP_ASN1_CONTENTTYPE_PRIMITIVE | SNMP_ASN1_APPLICATION_TIMETICKS)
+#define SNMP_ASN1_TYPE_OPAQUE         (SNMP_ASN1_CLASS_APPLICATION | SNMP_ASN1_CONTENTTYPE_PRIMITIVE | SNMP_ASN1_APPLICATION_OPAQUE)
+#if LWIP_HAVE_INT64
+#define SNMP_ASN1_TYPE_COUNTER64      (SNMP_ASN1_CLASS_APPLICATION | SNMP_ASN1_CONTENTTYPE_PRIMITIVE | SNMP_ASN1_APPLICATION_COUNTER64)
+#endif
+
+#define SNMP_VARBIND_EXCEPTION_OFFSET 0xF0
+#define SNMP_VARBIND_EXCEPTION_MASK   0x0F
+
+/** error codes predefined by SNMP prot. */
+typedef enum {
+  SNMP_ERR_NOERROR             = 0,
+/* 
+outdated v1 error codes. do not use anmore!
+#define SNMP_ERR_NOSUCHNAME 2  use SNMP_ERR_NOSUCHINSTANCE instead
+#define SNMP_ERR_BADVALUE   3  use SNMP_ERR_WRONGTYPE,SNMP_ERR_WRONGLENGTH,SNMP_ERR_WRONGENCODING or SNMP_ERR_WRONGVALUE instead
+#define SNMP_ERR_READONLY   4  use SNMP_ERR_NOTWRITABLE instead
+*/
+  SNMP_ERR_GENERROR            = 5,
+  SNMP_ERR_NOACCESS            = 6,
+  SNMP_ERR_WRONGTYPE           = 7,
+  SNMP_ERR_WRONGLENGTH         = 8,
+  SNMP_ERR_WRONGENCODING       = 9,
+  SNMP_ERR_WRONGVALUE          = 10,
+  SNMP_ERR_NOCREATION          = 11,
+  SNMP_ERR_INCONSISTENTVALUE   = 12,
+  SNMP_ERR_RESOURCEUNAVAILABLE = 13,
+  SNMP_ERR_COMMITFAILED        = 14,
+  SNMP_ERR_UNDOFAILED          = 15,
+  SNMP_ERR_NOTWRITABLE         = 17,
+  SNMP_ERR_INCONSISTENTNAME    = 18,
+
+  SNMP_ERR_NOSUCHINSTANCE      = SNMP_VARBIND_EXCEPTION_OFFSET + SNMP_ASN1_CONTEXT_VARBIND_NO_SUCH_INSTANCE
+} snmp_err_t;
+
+/** internal object identifier representation */
+struct snmp_obj_id
+{
+  u8_t len;
+  u32_t id[SNMP_MAX_OBJ_ID_LEN];
+};
+
+struct snmp_obj_id_const_ref
+{
+  u8_t len;
+  const u32_t* id;
+};
+
+extern const struct snmp_obj_id_const_ref snmp_zero_dot_zero; /* administrative identifier from SNMPv2-SMI */
+
+/** SNMP variant value, used as reference in struct snmp_node_instance and table implementation */
+union snmp_variant_value
+{
+  void* ptr;
+  const void* const_ptr;
+  u32_t u32;
+  s32_t s32;
+#if LWIP_HAVE_INT64
+  u64_t u64;
+#endif
+};
+
+
+/**
+SNMP MIB node types
+ tree node is the only node the stack can process in order to walk the tree,
+ all other nodes are assumed to be leaf nodes.
+ This cannot be an enum because users may want to define their own node types.
+*/
+#define SNMP_NODE_TREE         0x00
+/* predefined leaf node types */
+#define SNMP_NODE_SCALAR       0x01
+#define SNMP_NODE_SCALAR_ARRAY 0x02
+#define SNMP_NODE_TABLE        0x03
+#define SNMP_NODE_THREADSYNC   0x04
+
+/** node "base class" layout, the mandatory fields for a node  */
+struct snmp_node
+{
+  /** one out of SNMP_NODE_TREE or any leaf node type (like SNMP_NODE_SCALAR) */
+  u8_t node_type;
+  /** the number assigned to this node which used as part of the full OID */
+  u32_t oid;
+};
+
+/** SNMP node instance access types */
+typedef enum {
+  SNMP_NODE_INSTANCE_ACCESS_READ    = 1,
+  SNMP_NODE_INSTANCE_ACCESS_WRITE   = 2,
+  SNMP_NODE_INSTANCE_READ_ONLY      = SNMP_NODE_INSTANCE_ACCESS_READ,
+  SNMP_NODE_INSTANCE_READ_WRITE     = (SNMP_NODE_INSTANCE_ACCESS_READ | SNMP_NODE_INSTANCE_ACCESS_WRITE),
+  SNMP_NODE_INSTANCE_WRITE_ONLY     = SNMP_NODE_INSTANCE_ACCESS_WRITE,
+  SNMP_NODE_INSTANCE_NOT_ACCESSIBLE = 0
+} snmp_access_t;
+
+struct snmp_node_instance;
+
+typedef s16_t (*node_instance_get_value_method)(struct snmp_node_instance*, void*);
+typedef snmp_err_t (*node_instance_set_test_method)(struct snmp_node_instance*, u16_t, void*);
+typedef snmp_err_t (*node_instance_set_value_method)(struct snmp_node_instance*, u16_t, void*);
+typedef void (*node_instance_release_method)(struct snmp_node_instance*);
+
+#define SNMP_GET_VALUE_RAW_DATA 0x4000  /* do not use 0x8000 because return value of node_instance_get_value_method is signed16 and 0x8000 would be the signed bit */
+
+/** SNMP node instance */
+struct snmp_node_instance
+{
+  /** prefilled with the node, get_instance() is called on; may be changed by user to any value to pass an arbitrary node between calls to get_instance() and get_value/test_value/set_value */
+  const struct snmp_node* node;
+  /** prefilled with the instance id requested; for get_instance() this is the exact oid requested; for get_next_instance() this is the relative starting point, stack expects relative oid of next node here */
+  struct snmp_obj_id instance_oid;
+
+  /** ASN type for this object (see snmp_asn1.h for definitions) */
+  u8_t asn1_type;
+  /** one out of instance access types defined above (SNMP_NODE_INSTANCE_READ_ONLY,...) */
+  snmp_access_t access;
+
+  /** returns object value for the given object identifier. Return values <0 to indicate an error */
+  node_instance_get_value_method get_value;
+  /** tests length and/or range BEFORE setting */
+  node_instance_set_test_method set_test;
+  /** sets object value, only called when set_test() was successful */
+  node_instance_set_value_method set_value;
+  /** called in any case when the instance is not required anymore by stack (useful for freeing memory allocated in get_instance/get_next_instance methods) */
+  node_instance_release_method release_instance;
+
+  /** reference to pass arbitrary value between calls to get_instance() and get_value/test_value/set_value */
+  union snmp_variant_value reference;
+  /** see reference (if reference is a pointer, the length of underlying data may be stored here or anything else) */
+  u32_t reference_len;
+};
+
+
+/** SNMP tree node */
+struct snmp_tree_node
+{
+  /** inherited "base class" members */
+  struct snmp_node node;
+  u16_t subnode_count;
+  const struct snmp_node* const *subnodes;
+};
+
+#define SNMP_CREATE_TREE_NODE(oid, subnodes) \
+  {{ SNMP_NODE_TREE, (oid) }, \
+  (u16_t)LWIP_ARRAYSIZE(subnodes), (subnodes) }
+
+#define SNMP_CREATE_EMPTY_TREE_NODE(oid) \
+  {{ SNMP_NODE_TREE, (oid) }, \
+  0, NULL }
+
+/** SNMP leaf node */
+struct snmp_leaf_node
+{
+  /** inherited "base class" members */
+  struct snmp_node node;
+  snmp_err_t (*get_instance)(const u32_t *root_oid, u8_t root_oid_len, struct snmp_node_instance* instance);
+  snmp_err_t (*get_next_instance)(const u32_t *root_oid, u8_t root_oid_len, struct snmp_node_instance* instance);
+};
+
+/** represents a single mib with its base oid and root node */
+struct snmp_mib
+{
+  const u32_t *base_oid;
+  u8_t base_oid_len;
+  const struct snmp_node *root_node;
+};
+
+#define SNMP_MIB_CREATE(oid_list, root_node) { (oid_list), (u8_t)LWIP_ARRAYSIZE(oid_list), root_node }
+
+/** OID range structure */
+struct snmp_oid_range
+{
+  u32_t min;
+  u32_t max;
+};
+
+/** checks if incoming OID length and values are in allowed ranges */
+u8_t snmp_oid_in_range(const u32_t *oid_in, u8_t oid_len, const struct snmp_oid_range *oid_ranges, u8_t oid_ranges_len);
+
+typedef enum {
+  SNMP_NEXT_OID_STATUS_SUCCESS,
+  SNMP_NEXT_OID_STATUS_NO_MATCH,
+  SNMP_NEXT_OID_STATUS_BUF_TO_SMALL
+} snmp_next_oid_status_t;
+
+/** state for next_oid_init / next_oid_check functions */
+struct snmp_next_oid_state
+{
+  const u32_t* start_oid;
+  u8_t start_oid_len;
+
+  u32_t* next_oid;
+  u8_t next_oid_len;
+  u8_t next_oid_max_len;
+
+  snmp_next_oid_status_t status;
+  void* reference;
+};
+
+void snmp_next_oid_init(struct snmp_next_oid_state *state,
+  const u32_t *start_oid, u8_t start_oid_len,
+  u32_t *next_oid_buf, u8_t next_oid_max_len);
+u8_t snmp_next_oid_precheck(struct snmp_next_oid_state *state, const u32_t *oid, u8_t oid_len);
+u8_t snmp_next_oid_check(struct snmp_next_oid_state *state, const u32_t *oid, u8_t oid_len, void* reference);
+
+void snmp_oid_assign(struct snmp_obj_id* target, const u32_t *oid, u8_t oid_len);
+void snmp_oid_combine(struct snmp_obj_id* target, const u32_t *oid1, u8_t oid1_len, const u32_t *oid2, u8_t oid2_len);
+void snmp_oid_prefix(struct snmp_obj_id* target, const u32_t *oid, u8_t oid_len);
+void snmp_oid_append(struct snmp_obj_id* target, const u32_t *oid, u8_t oid_len);
+u8_t snmp_oid_equal(const u32_t *oid1, u8_t oid1_len, const u32_t *oid2, u8_t oid2_len);
+s8_t snmp_oid_compare(const u32_t *oid1, u8_t oid1_len, const u32_t *oid2, u8_t oid2_len);
+
+#if LWIP_IPV4
+u8_t snmp_oid_to_ip4(const u32_t *oid, ip4_addr_t *ip);
+void snmp_ip4_to_oid(const ip4_addr_t *ip, u32_t *oid);
+#endif /* LWIP_IPV4 */
+#if LWIP_IPV6
+u8_t snmp_oid_to_ip6(const u32_t *oid, ip6_addr_t *ip);
+void snmp_ip6_to_oid(const ip6_addr_t *ip, u32_t *oid);
+#endif /* LWIP_IPV6 */
+#if LWIP_IPV4 || LWIP_IPV6
+u8_t snmp_ip_to_oid(const ip_addr_t *ip, u32_t *oid);
+u8_t snmp_ip_port_to_oid(const ip_addr_t *ip, u16_t port, u32_t *oid);
+
+u8_t snmp_oid_to_ip(const u32_t *oid, u8_t oid_len, ip_addr_t *ip);
+u8_t snmp_oid_to_ip_port(const u32_t *oid, u8_t oid_len, ip_addr_t *ip, u16_t *port);
+#endif /* LWIP_IPV4 || LWIP_IPV6 */
+
+struct netif;
+u8_t netif_to_num(const struct netif *netif);
+
+snmp_err_t snmp_set_test_ok(struct snmp_node_instance* instance, u16_t value_len, void* value); /* generic function which can be used if test is always successful */
+
+err_t snmp_decode_bits(const u8_t *buf, u32_t buf_len, u32_t *bit_value);
+err_t snmp_decode_truthvalue(const s32_t *asn1_value, u8_t *bool_value);
+u8_t  snmp_encode_bits(u8_t *buf, u32_t buf_len, u32_t bit_value, u8_t bit_count);
+u8_t  snmp_encode_truthvalue(s32_t *asn1_value, u32_t bool_value);
+
+struct snmp_statistics
+{
+  u32_t inpkts;
+  u32_t outpkts;
+  u32_t inbadversions;
+  u32_t inbadcommunitynames;
+  u32_t inbadcommunityuses;
+  u32_t inasnparseerrs;
+  u32_t intoobigs;
+  u32_t innosuchnames;
+  u32_t inbadvalues;
+  u32_t inreadonlys;
+  u32_t ingenerrs;
+  u32_t intotalreqvars;
+  u32_t intotalsetvars;
+  u32_t ingetrequests;
+  u32_t ingetnexts;
+  u32_t insetrequests;
+  u32_t ingetresponses;
+  u32_t intraps;
+  u32_t outtoobigs;
+  u32_t outnosuchnames;
+  u32_t outbadvalues;
+  u32_t outgenerrs;
+  u32_t outgetrequests;
+  u32_t outgetnexts;
+  u32_t outsetrequests;
+  u32_t outgetresponses;
+  u32_t outtraps;
+#if LWIP_SNMP_V3
+  u32_t unsupportedseclevels;
+  u32_t notintimewindows;
+  u32_t unknownusernames;
+  u32_t unknownengineids;
+  u32_t wrongdigests;
+  u32_t decryptionerrors;
+#endif
+};
+
+extern struct snmp_statistics snmp_stats;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LWIP_SNMP */
+
+#endif /* LWIP_HDR_APPS_SNMP_CORE_H */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/apps/snmp_mib2.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/apps/snmp_mib2.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/apps/snmp_mib2.h	(revision 457)
@@ -0,0 +1,78 @@
+/**
+ * @file
+ * SNMP MIB2 API
+ */
+
+/*
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Dirk Ziegelmeier <dziegel@gmx.de>
+ *
+ */
+#ifndef LWIP_HDR_APPS_SNMP_MIB2_H
+#define LWIP_HDR_APPS_SNMP_MIB2_H
+
+#include "lwip/apps/snmp_opts.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if LWIP_SNMP /* don't build if not configured for use in lwipopts.h */
+#if SNMP_LWIP_MIB2
+
+#include "lwip/apps/snmp_core.h"
+
+extern const struct snmp_mib mib2;
+
+#if SNMP_USE_NETCONN
+#include "lwip/apps/snmp_threadsync.h"
+void snmp_mib2_lwip_synchronizer(snmp_threadsync_called_fn fn, void* arg);
+extern struct snmp_threadsync_instance snmp_mib2_lwip_locks;
+#endif
+
+#ifndef SNMP_SYSSERVICES
+#define SNMP_SYSSERVICES ((1 << 6) | (1 << 3) | ((IP_FORWARD) << 2))
+#endif
+
+void snmp_mib2_set_sysdescr(const u8_t* str, const u16_t* len); /* read-only be defintion */
+void snmp_mib2_set_syscontact(u8_t *ocstr, u16_t *ocstrlen, u16_t bufsize);
+void snmp_mib2_set_syscontact_readonly(const u8_t *ocstr, const u16_t *ocstrlen);
+void snmp_mib2_set_sysname(u8_t *ocstr, u16_t *ocstrlen, u16_t bufsize);
+void snmp_mib2_set_sysname_readonly(const u8_t *ocstr, const u16_t *ocstrlen);
+void snmp_mib2_set_syslocation(u8_t *ocstr, u16_t *ocstrlen, u16_t bufsize);
+void snmp_mib2_set_syslocation_readonly(const u8_t *ocstr, const u16_t *ocstrlen);
+
+#endif /* SNMP_LWIP_MIB2 */
+#endif /* LWIP_SNMP */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LWIP_HDR_APPS_SNMP_MIB2_H */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/apps/snmp_opts.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/apps/snmp_opts.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/apps/snmp_opts.h	(revision 457)
@@ -0,0 +1,297 @@
+/**
+ * @file
+ * SNMP server options list
+ */
+
+/*
+ * Copyright (c) 2015 Dirk Ziegelmeier
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Dirk Ziegelmeier
+ *
+ */
+#ifndef LWIP_HDR_SNMP_OPTS_H
+#define LWIP_HDR_SNMP_OPTS_H
+
+#include "lwip/opt.h"
+
+/**
+ * @defgroup snmp_opts Options
+ * @ingroup snmp
+ * @{
+ */
+
+/**
+ * LWIP_SNMP==1: This enables the lwIP SNMP agent. UDP must be available
+ * for SNMP transport.
+ * If you want to use your own SNMP agent, leave this disabled.
+ * To integrate MIB2 of an external agent, you need to enable
+ * LWIP_MIB2_CALLBACKS and MIB2_STATS. This will give you the callbacks
+ * and statistics counters you need to get MIB2 working.
+ */
+#if !defined LWIP_SNMP || defined __DOXYGEN__
+#define LWIP_SNMP                       0
+#endif
+
+/**
+ * SNMP_USE_NETCONN: Use netconn API instead of raw API.
+ * Makes SNMP agent run in a worker thread, so blocking operations
+ * can be done in MIB calls.
+ */
+#if !defined SNMP_USE_NETCONN || defined __DOXYGEN__
+#define SNMP_USE_NETCONN           0
+#endif
+
+/**
+ * SNMP_USE_RAW: Use raw API.
+ * SNMP agent does not run in a worker thread, so blocking operations
+ * should not be done in MIB calls.
+ */
+#if !defined SNMP_USE_RAW || defined __DOXYGEN__
+#define SNMP_USE_RAW               1
+#endif
+
+#if SNMP_USE_NETCONN && SNMP_USE_RAW
+#error SNMP stack can use only one of the APIs {raw, netconn}
+#endif
+
+#if LWIP_SNMP && !SNMP_USE_NETCONN && !SNMP_USE_RAW
+#error SNMP stack needs a receive API and UDP {raw, netconn}
+#endif
+
+#if SNMP_USE_NETCONN
+/**
+ * SNMP_STACK_SIZE: Stack size of SNMP netconn worker thread
+ */
+#if !defined SNMP_STACK_SIZE || defined __DOXYGEN__
+#define SNMP_STACK_SIZE            DEFAULT_THREAD_STACKSIZE
+#endif
+
+/**
+ * SNMP_THREAD_PRIO: SNMP netconn worker thread priority
+ */
+#if !defined SNMP_THREAD_PRIO || defined __DOXYGEN__
+#define SNMP_THREAD_PRIO           DEFAULT_THREAD_PRIO
+#endif
+#endif /* SNMP_USE_NETCONN */
+
+/**
+ * SNMP_TRAP_DESTINATIONS: Number of trap destinations. At least one trap
+ * destination is required
+ */
+#if !defined SNMP_TRAP_DESTINATIONS || defined __DOXYGEN__
+#define SNMP_TRAP_DESTINATIONS          1
+#endif
+
+/**
+ * Only allow SNMP write actions that are 'safe' (e.g. disabling netifs is not
+ * a safe action and disabled when SNMP_SAFE_REQUESTS = 1).
+ * Unsafe requests are disabled by default!
+ */
+#if !defined SNMP_SAFE_REQUESTS || defined __DOXYGEN__
+#define SNMP_SAFE_REQUESTS              1
+#endif
+
+/**
+ * The maximum length of strings used.
+ */
+#if !defined SNMP_MAX_OCTET_STRING_LEN || defined __DOXYGEN__
+#define SNMP_MAX_OCTET_STRING_LEN       127
+#endif
+
+/**
+ * The maximum number of Sub ID's inside an object identifier.
+ * Indirectly this also limits the maximum depth of SNMP tree.
+ */
+#if !defined SNMP_MAX_OBJ_ID_LEN || defined __DOXYGEN__
+#define SNMP_MAX_OBJ_ID_LEN             50
+#endif
+
+#if !defined SNMP_MAX_VALUE_SIZE || defined __DOXYGEN__
+/**
+ * The minimum size of a value.
+ */
+#define SNMP_MIN_VALUE_SIZE             (2 * sizeof(u32_t*)) /* size required to store the basic types (8 bytes for counter64) */
+/**
+ * The maximum size of a value.
+ */
+#define SNMP_MAX_VALUE_SIZE             LWIP_MAX(LWIP_MAX((SNMP_MAX_OCTET_STRING_LEN), sizeof(u32_t)*(SNMP_MAX_OBJ_ID_LEN)), SNMP_MIN_VALUE_SIZE)
+#endif
+
+/**
+ * The snmp read-access community. Used for write-access and traps, too
+ * unless SNMP_COMMUNITY_WRITE or SNMP_COMMUNITY_TRAP are enabled, respectively.
+ */
+#if !defined SNMP_COMMUNITY || defined __DOXYGEN__
+#define SNMP_COMMUNITY                  "public"
+#endif
+
+/**
+ * The snmp write-access community.
+ * Set this community to "" in order to disallow any write access.
+ */
+#if !defined SNMP_COMMUNITY_WRITE || defined __DOXYGEN__
+#define SNMP_COMMUNITY_WRITE            "private"
+#endif
+
+/**
+ * The snmp community used for sending traps.
+ */
+#if !defined SNMP_COMMUNITY_TRAP || defined __DOXYGEN__
+#define SNMP_COMMUNITY_TRAP             "public"
+#endif
+
+/**
+ * The maximum length of community string.
+ * If community names shall be adjusted at runtime via snmp_set_community() calls,
+ * enter here the possible maximum length (+1 for terminating null character).
+ */
+#if !defined SNMP_MAX_COMMUNITY_STR_LEN || defined __DOXYGEN__
+#define SNMP_MAX_COMMUNITY_STR_LEN LWIP_MAX(LWIP_MAX(sizeof(SNMP_COMMUNITY), sizeof(SNMP_COMMUNITY_WRITE)), sizeof(SNMP_COMMUNITY_TRAP))
+#endif
+
+/**
+ * The OID identifiying the device. This may be the enterprise OID itself or any OID located below it in tree.
+ */
+#if !defined SNMP_DEVICE_ENTERPRISE_OID || defined __DOXYGEN__
+#define SNMP_LWIP_ENTERPRISE_OID 26381
+/**
+ * IANA assigned enterprise ID for lwIP is 26381
+ * @see http://www.iana.org/assignments/enterprise-numbers
+ *
+ * @note this enterprise ID is assigned to the lwIP project,
+ * all object identifiers living under this ID are assigned
+ * by the lwIP maintainers!
+ * @note don't change this define, use snmp_set_device_enterprise_oid()
+ *
+ * If you need to create your own private MIB you'll need
+ * to apply for your own enterprise ID with IANA:
+ * http://www.iana.org/numbers.html
+ */
+#define SNMP_DEVICE_ENTERPRISE_OID {1, 3, 6, 1, 4, 1, SNMP_LWIP_ENTERPRISE_OID}
+/**
+ * Length of SNMP_DEVICE_ENTERPRISE_OID
+ */
+#define SNMP_DEVICE_ENTERPRISE_OID_LEN 7
+#endif
+
+/**
+ * SNMP_DEBUG: Enable debugging for SNMP messages.
+ */
+#if !defined SNMP_DEBUG || defined __DOXYGEN__
+#define SNMP_DEBUG                      LWIP_DBG_OFF
+#endif
+
+/**
+ * SNMP_MIB_DEBUG: Enable debugging for SNMP MIBs.
+ */
+#if !defined SNMP_MIB_DEBUG || defined __DOXYGEN__
+#define SNMP_MIB_DEBUG                  LWIP_DBG_OFF
+#endif
+
+/**
+ * Indicates if the MIB2 implementation of LWIP SNMP stack is used.
+ */
+#if !defined SNMP_LWIP_MIB2 || defined __DOXYGEN__
+#define SNMP_LWIP_MIB2                      LWIP_SNMP
+#endif
+
+/**
+ * Value return for sysDesc field of MIB2.
+ */
+#if !defined SNMP_LWIP_MIB2_SYSDESC || defined __DOXYGEN__
+#define SNMP_LWIP_MIB2_SYSDESC              "lwIP"
+#endif
+
+/**
+ * Value return for sysName field of MIB2.
+ * To make sysName field settable, call snmp_mib2_set_sysname() to provide the necessary buffers.
+ */
+#if !defined SNMP_LWIP_MIB2_SYSNAME || defined __DOXYGEN__
+#define SNMP_LWIP_MIB2_SYSNAME              "FQDN-unk"
+#endif
+
+/**
+ * Value return for sysContact field of MIB2.
+ * To make sysContact field settable, call snmp_mib2_set_syscontact() to provide the necessary buffers.
+ */
+#if !defined SNMP_LWIP_MIB2_SYSCONTACT || defined __DOXYGEN__
+#define SNMP_LWIP_MIB2_SYSCONTACT           ""
+#endif
+
+/**
+ * Value return for sysLocation field of MIB2.
+ * To make sysLocation field settable, call snmp_mib2_set_syslocation() to provide the necessary buffers.
+ */
+#if !defined SNMP_LWIP_MIB2_SYSLOCATION || defined __DOXYGEN__
+#define SNMP_LWIP_MIB2_SYSLOCATION          ""
+#endif
+
+/**
+ * This value is used to limit the repetitions processed in GetBulk requests (value == 0 means no limitation).
+ * This may be useful to limit the load for a single request.
+ * According to SNMP RFC 1905 it is allowed to not return all requested variables from a GetBulk request if system load would be too high.
+ * so the effect is that the client will do more requests to gather all data.
+ * For the stack this could be useful in case that SNMP processing is done in TCP/IP thread. In this situation a request with many
+ * repetitions could block the thread for a longer time. Setting limit here will keep the stack more responsive.
+ */
+#if !defined SNMP_LWIP_GETBULK_MAX_REPETITIONS || defined __DOXYGEN__
+#define SNMP_LWIP_GETBULK_MAX_REPETITIONS 0
+#endif
+
+/**
+ * @}
+ */
+
+/*
+   ------------------------------------
+   ---------- SNMPv3 options ----------
+   ------------------------------------
+*/
+
+/**
+ * LWIP_SNMP_V3==1: This enables EXPERIMENTAL SNMPv3 support. LWIP_SNMP must
+ * also be enabled.
+ * THIS IS UNDER DEVELOPMENT AND SHOULD NOT BE ENABLED IN PRODUCTS.
+ */
+#ifndef LWIP_SNMP_V3
+#define LWIP_SNMP_V3               0
+#endif
+
+#ifndef LWIP_SNMP_V3_MBEDTLS
+#define LWIP_SNMP_V3_MBEDTLS       LWIP_SNMP_V3
+#endif
+
+#ifndef LWIP_SNMP_V3_CRYPTO
+#define LWIP_SNMP_V3_CRYPTO        LWIP_SNMP_V3_MBEDTLS
+#endif
+
+#ifndef LWIP_SNMP_CONFIGURE_VERSIONS
+#define LWIP_SNMP_CONFIGURE_VERSIONS 0
+#endif
+
+#endif /* LWIP_HDR_SNMP_OPTS_H */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/apps/snmp_scalar.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/apps/snmp_scalar.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/apps/snmp_scalar.h	(revision 457)
@@ -0,0 +1,113 @@
+/**
+ * @file
+ * SNMP server MIB API to implement scalar nodes
+ */
+
+/*
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Martin Hentschel <info@cl-soft.de>
+ *
+ */
+
+#ifndef LWIP_HDR_APPS_SNMP_SCALAR_H
+#define LWIP_HDR_APPS_SNMP_SCALAR_H
+
+#include "lwip/apps/snmp_opts.h"
+#include "lwip/apps/snmp_core.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if LWIP_SNMP /* don't build if not configured for use in lwipopts.h */
+
+/** basic scalar node */
+struct snmp_scalar_node
+{
+  /** inherited "base class" members */
+  struct snmp_leaf_node node;
+  u8_t asn1_type;
+  snmp_access_t access;
+  node_instance_get_value_method get_value;
+  node_instance_set_test_method set_test;
+  node_instance_set_value_method set_value;
+};
+
+
+snmp_err_t snmp_scalar_get_instance(const u32_t *root_oid, u8_t root_oid_len, struct snmp_node_instance* instance);
+snmp_err_t snmp_scalar_get_next_instance(const u32_t *root_oid, u8_t root_oid_len, struct snmp_node_instance* instance);
+
+#define SNMP_SCALAR_CREATE_NODE(oid, access, asn1_type, get_value_method, set_test_method, set_value_method) \
+  {{{ SNMP_NODE_SCALAR, (oid) }, \
+    snmp_scalar_get_instance, \
+    snmp_scalar_get_next_instance }, \
+    (asn1_type), (access), (get_value_method), (set_test_method), (set_value_method) }
+
+#define SNMP_SCALAR_CREATE_NODE_READONLY(oid, asn1_type, get_value_method) SNMP_SCALAR_CREATE_NODE(oid, SNMP_NODE_INSTANCE_READ_ONLY, asn1_type, get_value_method, NULL, NULL)
+
+/** scalar array node - a tree node which contains scalars only as children */
+struct snmp_scalar_array_node_def
+{
+  u32_t         oid;
+  u8_t          asn1_type;
+  snmp_access_t access;
+};
+
+typedef s16_t (*snmp_scalar_array_get_value_method)(const struct snmp_scalar_array_node_def*, void*);
+typedef snmp_err_t (*snmp_scalar_array_set_test_method)(const struct snmp_scalar_array_node_def*, u16_t, void*);
+typedef snmp_err_t (*snmp_scalar_array_set_value_method)(const struct snmp_scalar_array_node_def*, u16_t, void*);
+
+/** basic scalar array node */
+struct snmp_scalar_array_node
+{
+  /** inherited "base class" members */
+  struct snmp_leaf_node node;
+  u16_t array_node_count;
+  const struct snmp_scalar_array_node_def* array_nodes;
+  snmp_scalar_array_get_value_method get_value;
+  snmp_scalar_array_set_test_method set_test;
+  snmp_scalar_array_set_value_method set_value;
+};
+
+snmp_err_t snmp_scalar_array_get_instance(const u32_t *root_oid, u8_t root_oid_len, struct snmp_node_instance* instance);
+snmp_err_t snmp_scalar_array_get_next_instance(const u32_t *root_oid, u8_t root_oid_len, struct snmp_node_instance* instance);
+
+#define SNMP_SCALAR_CREATE_ARRAY_NODE(oid, array_nodes, get_value_method, set_test_method, set_value_method) \
+  {{{ SNMP_NODE_SCALAR_ARRAY, (oid) }, \
+    snmp_scalar_array_get_instance, \
+    snmp_scalar_array_get_next_instance }, \
+    (u16_t)LWIP_ARRAYSIZE(array_nodes), (array_nodes), (get_value_method), (set_test_method), (set_value_method) }
+
+#endif /* LWIP_SNMP */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LWIP_HDR_APPS_SNMP_SCALAR_H */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/apps/snmp_snmpv2_framework.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/apps/snmp_snmpv2_framework.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/apps/snmp_snmpv2_framework.h	(revision 457)
@@ -0,0 +1,32 @@
+/*
+Generated by LwipMibCompiler
+*/
+
+#ifndef LWIP_HDR_APPS_SNMP_FRAMEWORK_MIB_H
+#define LWIP_HDR_APPS_SNMP_FRAMEWORK_MIB_H
+
+#include "lwip/apps/snmp_opts.h"
+#if LWIP_SNMP
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+#include "lwip/apps/snmp_core.h"
+
+extern const struct snmp_obj_id usmNoAuthProtocol;
+extern const struct snmp_obj_id usmHMACMD5AuthProtocol;
+extern const struct snmp_obj_id usmHMACSHAAuthProtocol;
+
+extern const struct snmp_obj_id usmNoPrivProtocol;
+extern const struct snmp_obj_id usmDESPrivProtocol;
+extern const struct snmp_obj_id usmAESPrivProtocol;
+
+extern const struct snmp_mib snmpframeworkmib;
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* LWIP_SNMP */
+#endif /* LWIP_HDR_APPS_SNMP_FRAMEWORK_MIB_H */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/apps/snmp_snmpv2_usm.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/apps/snmp_snmpv2_usm.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/apps/snmp_snmpv2_usm.h	(revision 457)
@@ -0,0 +1,24 @@
+/*
+Generated by LwipMibCompiler
+*/
+
+#ifndef LWIP_HDR_APPS_SNMP_USER_BASED_SM_MIB_H
+#define LWIP_HDR_APPS_SNMP_USER_BASED_SM_MIB_H
+
+#include "lwip/apps/snmp_opts.h"
+#if LWIP_SNMP
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+#include "lwip/apps/snmp_core.h"
+
+extern const struct snmp_mib snmpusmmib;
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* LWIP_SNMP */
+#endif /* LWIP_HDR_APPS_SNMP_USER_BASED_SM_MIB_H */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/apps/snmp_table.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/apps/snmp_table.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/apps/snmp_table.h	(revision 457)
@@ -0,0 +1,134 @@
+/**
+ * @file
+ * SNMP server MIB API to implement table nodes
+ */
+
+/*
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Martin Hentschel <info@cl-soft.de>
+ *
+ */
+
+#ifndef LWIP_HDR_APPS_SNMP_TABLE_H
+#define LWIP_HDR_APPS_SNMP_TABLE_H
+
+#include "lwip/apps/snmp_opts.h"
+#include "lwip/apps/snmp_core.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if LWIP_SNMP /* don't build if not configured for use in lwipopts.h */
+
+/** default (customizable) read/write table */
+struct snmp_table_col_def
+{
+  u32_t index;
+  u8_t asn1_type;
+  snmp_access_t access;
+};
+
+/** table node */
+struct snmp_table_node
+{
+  /** inherited "base class" members */
+  struct snmp_leaf_node node;
+  u16_t column_count;
+  const struct snmp_table_col_def* columns;
+  snmp_err_t (*get_cell_instance)(const u32_t* column, const u32_t* row_oid, u8_t row_oid_len, struct snmp_node_instance* cell_instance);
+  snmp_err_t (*get_next_cell_instance)(const u32_t* column, struct snmp_obj_id* row_oid, struct snmp_node_instance* cell_instance);
+  /** returns object value for the given object identifier */
+  node_instance_get_value_method get_value;
+  /** tests length and/or range BEFORE setting */
+  node_instance_set_test_method set_test;
+  /** sets object value, only called when set_test() was successful */
+  node_instance_set_value_method set_value;
+};
+
+snmp_err_t snmp_table_get_instance(const u32_t *root_oid, u8_t root_oid_len, struct snmp_node_instance* instance);
+snmp_err_t snmp_table_get_next_instance(const u32_t *root_oid, u8_t root_oid_len, struct snmp_node_instance* instance);
+
+#define SNMP_TABLE_CREATE(oid, columns, get_cell_instance_method, get_next_cell_instance_method, get_value_method, set_test_method, set_value_method) \
+  {{{ SNMP_NODE_TABLE, (oid) }, \
+  snmp_table_get_instance, \
+  snmp_table_get_next_instance }, \
+  (u16_t)LWIP_ARRAYSIZE(columns), (columns), \
+  (get_cell_instance_method), (get_next_cell_instance_method), \
+  (get_value_method), (set_test_method), (set_value_method)}
+
+#define SNMP_TABLE_GET_COLUMN_FROM_OID(oid) ((oid)[1]) /* first array value is (fixed) row entry (fixed to 1) and 2nd value is column, follow3ed by instance */
+
+
+/** simple read-only table */
+typedef enum {
+  SNMP_VARIANT_VALUE_TYPE_U32,
+  SNMP_VARIANT_VALUE_TYPE_S32,
+  SNMP_VARIANT_VALUE_TYPE_PTR,
+  SNMP_VARIANT_VALUE_TYPE_CONST_PTR
+} snmp_table_column_data_type_t;
+
+struct snmp_table_simple_col_def
+{
+  u32_t index;
+  u8_t asn1_type;
+  snmp_table_column_data_type_t data_type; /* depending of what union member is used to store the value*/
+};
+
+/** simple read-only table node */
+struct snmp_table_simple_node
+{
+  /* inherited "base class" members */
+  struct snmp_leaf_node node;
+  u16_t column_count;
+  const struct snmp_table_simple_col_def* columns;
+  snmp_err_t (*get_cell_value)(const u32_t* column, const u32_t* row_oid, u8_t row_oid_len, union snmp_variant_value* value, u32_t* value_len);
+  snmp_err_t (*get_next_cell_instance_and_value)(const u32_t* column, struct snmp_obj_id* row_oid, union snmp_variant_value* value, u32_t* value_len);
+};
+
+snmp_err_t snmp_table_simple_get_instance(const u32_t *root_oid, u8_t root_oid_len, struct snmp_node_instance* instance);
+snmp_err_t snmp_table_simple_get_next_instance(const u32_t *root_oid, u8_t root_oid_len, struct snmp_node_instance* instance);
+
+#define SNMP_TABLE_CREATE_SIMPLE(oid, columns, get_cell_value_method, get_next_cell_instance_and_value_method) \
+  {{{ SNMP_NODE_TABLE, (oid) }, \
+  snmp_table_simple_get_instance, \
+  snmp_table_simple_get_next_instance }, \
+  (u16_t)LWIP_ARRAYSIZE(columns), (columns), (get_cell_value_method), (get_next_cell_instance_and_value_method) }
+
+s16_t snmp_table_extract_value_from_s32ref(struct snmp_node_instance* instance, void* value);
+s16_t snmp_table_extract_value_from_u32ref(struct snmp_node_instance* instance, void* value);
+s16_t snmp_table_extract_value_from_refconstptr(struct snmp_node_instance* instance, void* value);
+
+#endif /* LWIP_SNMP */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LWIP_HDR_APPS_SNMP_TABLE_H */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/apps/snmp_threadsync.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/apps/snmp_threadsync.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/apps/snmp_threadsync.h	(revision 457)
@@ -0,0 +1,114 @@
+/**
+ * @file
+ * SNMP server MIB API to implement thread synchronization
+ */
+
+/*
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Dirk Ziegelmeier <dziegel@gmx.de>
+ *
+ */
+
+#ifndef LWIP_HDR_APPS_SNMP_THREADSYNC_H
+#define LWIP_HDR_APPS_SNMP_THREADSYNC_H
+
+#include "lwip/apps/snmp_opts.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if LWIP_SNMP /* don't build if not configured for use in lwipopts.h */
+
+#include "lwip/apps/snmp_core.h"
+#include "lwip/sys.h"
+
+typedef void (*snmp_threadsync_called_fn)(void* arg);
+typedef void (*snmp_threadsync_synchronizer_fn)(snmp_threadsync_called_fn fn, void* arg);
+
+
+/** Thread sync runtime data. For internal usage only. */
+struct threadsync_data
+{
+  union {
+    snmp_err_t err;
+    s16_t s16;
+  } retval;
+  union {
+    const u32_t *root_oid;
+    void *value;
+  } arg1;
+  union {
+    u8_t root_oid_len;
+    u16_t len;
+  } arg2;
+  const struct snmp_threadsync_node *threadsync_node;
+  struct snmp_node_instance proxy_instance;
+};
+
+/** Thread sync instance. Needed EXCATLY once for every thread to be synced into. */
+struct snmp_threadsync_instance
+{
+  sys_sem_t                       sem;
+  sys_mutex_t                     sem_usage_mutex;
+  snmp_threadsync_synchronizer_fn sync_fn;
+  struct threadsync_data          data;
+};
+
+/** SNMP thread sync proxy leaf node */
+struct snmp_threadsync_node
+{
+  /* inherited "base class" members */
+  struct snmp_leaf_node           node;
+
+  const struct snmp_leaf_node     *target;
+  struct snmp_threadsync_instance *instance;
+};
+
+snmp_err_t snmp_threadsync_get_instance(const u32_t *root_oid, u8_t root_oid_len, struct snmp_node_instance* instance);
+snmp_err_t snmp_threadsync_get_next_instance(const u32_t *root_oid, u8_t root_oid_len, struct snmp_node_instance* instance);
+
+/** Create thread sync proxy node */
+#define SNMP_CREATE_THREAD_SYNC_NODE(oid, target_leaf_node, threadsync_instance) \
+  {{{ SNMP_NODE_THREADSYNC, (oid) }, \
+    snmp_threadsync_get_instance, \
+    snmp_threadsync_get_next_instance }, \
+    (target_leaf_node), \
+    (threadsync_instance) }
+
+/** Create thread sync instance data */
+void snmp_threadsync_init(struct snmp_threadsync_instance *instance, snmp_threadsync_synchronizer_fn sync_fn);
+
+#endif /* LWIP_SNMP */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LWIP_HDR_APPS_SNMP_THREADSYNC_H */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/apps/snmpv3.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/apps/snmpv3.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/apps/snmpv3.h	(revision 457)
@@ -0,0 +1,114 @@
+/**
+ * @file
+ * Additional SNMPv3 functionality RFC3414 and RFC3826.
+ */
+
+/*
+ * Copyright (c) 2016 Elias Oenal.
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * Author: Elias Oenal <lwip@eliasoenal.com>
+ */
+
+#ifndef LWIP_HDR_APPS_SNMP_V3_H
+#define LWIP_HDR_APPS_SNMP_V3_H
+
+#include "lwip/apps/snmp_opts.h"
+#include "lwip/err.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if LWIP_SNMP && LWIP_SNMP_V3
+
+typedef enum
+{
+  SNMP_V3_AUTH_ALGO_INVAL = 0,
+  SNMP_V3_AUTH_ALGO_MD5   = 1,
+  SNMP_V3_AUTH_ALGO_SHA   = 2
+} snmpv3_auth_algo_t;
+
+typedef enum
+{
+  SNMP_V3_PRIV_ALGO_INVAL = 0,
+  SNMP_V3_PRIV_ALGO_DES   = 1,
+  SNMP_V3_PRIV_ALGO_AES   = 2
+} snmpv3_priv_algo_t;
+
+typedef enum
+{
+  SNMP_V3_USER_STORAGETYPE_OTHER       = 1,
+  SNMP_V3_USER_STORAGETYPE_VOLATILE    = 2,
+  SNMP_V3_USER_STORAGETYPE_NONVOLATILE = 3,
+  SNMP_V3_USER_STORAGETYPE_PERMANENT   = 4,
+  SNMP_V3_USER_STORAGETYPE_READONLY    = 5
+} snmpv3_user_storagetype_t;
+
+/*
+ * The following callback functions must be implemented by the application.
+ * There is a dummy implementation in snmpv3_dummy.c.
+ */
+
+void snmpv3_get_engine_id(const char **id, u8_t *len);
+err_t snmpv3_set_engine_id(const char* id, u8_t len);
+
+u32_t snmpv3_get_engine_boots(void);
+void snmpv3_set_engine_boots(u32_t boots);
+
+u32_t snmpv3_get_engine_time(void);
+void snmpv3_reset_engine_time(void);
+
+err_t snmpv3_get_user(const char* username, snmpv3_auth_algo_t *auth_algo, u8_t *auth_key, snmpv3_priv_algo_t *priv_algo, u8_t *priv_key);
+u8_t snmpv3_get_amount_of_users(void);
+err_t snmpv3_get_user_storagetype(const char *username, snmpv3_user_storagetype_t *storagetype);
+err_t snmpv3_get_username(char *username, u8_t index);
+
+/* The following functions are provided by the SNMPv3 agent */
+
+void snmpv3_engine_id_changed(void);
+s32_t snmpv3_get_engine_time_internal(void);
+
+void snmpv3_password_to_key_md5(
+    const u8_t *password,     /* IN */
+    size_t      passwordlen,  /* IN */
+    const u8_t *engineID,     /* IN  - pointer to snmpEngineID  */
+    u8_t        engineLength, /* IN  - length of snmpEngineID */
+    u8_t       *key);         /* OUT - pointer to caller 16-octet buffer */
+
+void snmpv3_password_to_key_sha(
+    const u8_t *password,     /* IN */
+    size_t      passwordlen,  /* IN */
+    const u8_t *engineID,     /* IN  - pointer to snmpEngineID  */
+    u8_t        engineLength, /* IN  - length of snmpEngineID */
+    u8_t       *key);         /* OUT - pointer to caller 20-octet buffer */
+
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LWIP_HDR_APPS_SNMP_V3_H */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/apps/sntp.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/apps/sntp.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/apps/sntp.h	(revision 457)
@@ -0,0 +1,80 @@
+/**
+ * @file
+ * SNTP client API
+ */
+
+/*
+ * Copyright (c) 2007-2009 Fr辿d辿ric Bernon, Simon Goldschmidt
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Fr辿d辿ric Bernon, Simon Goldschmidt
+ *
+ */
+#ifndef LWIP_HDR_APPS_SNTP_H
+#define LWIP_HDR_APPS_SNTP_H
+
+#include "lwip/apps/sntp_opts.h"
+#include "lwip/ip_addr.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* SNTP operating modes: default is to poll using unicast.
+   The mode has to be set before calling sntp_init(). */
+#define SNTP_OPMODE_POLL            0
+#define SNTP_OPMODE_LISTENONLY      1
+void sntp_setoperatingmode(u8_t operating_mode);
+u8_t sntp_getoperatingmode(void);
+
+void sntp_init(void);
+void sntp_stop(void);
+u8_t sntp_enabled(void);
+
+void sntp_setserver(u8_t idx, const ip_addr_t *addr);
+const ip_addr_t* sntp_getserver(u8_t idx);
+
+#if SNTP_MONITOR_SERVER_REACHABILITY
+u8_t sntp_getreachability(u8_t idx);
+#endif /* SNTP_MONITOR_SERVER_REACHABILITY */
+
+#if SNTP_SERVER_DNS
+void sntp_setservername(u8_t idx, const char *server);
+const char *sntp_getservername(u8_t idx);
+#endif /* SNTP_SERVER_DNS */
+
+#if SNTP_GET_SERVERS_FROM_DHCP
+void sntp_servermode_dhcp(int set_servers_from_dhcp);
+#else /* SNTP_GET_SERVERS_FROM_DHCP */
+#define sntp_servermode_dhcp(x)
+#endif /* SNTP_GET_SERVERS_FROM_DHCP */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LWIP_HDR_APPS_SNTP_H */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/apps/sntp_opts.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/apps/sntp_opts.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/apps/sntp_opts.h	(revision 457)
@@ -0,0 +1,209 @@
+/**
+ * @file
+ * SNTP client options list
+ */
+
+/*
+ * Copyright (c) 2007-2009 Fr辿d辿ric Bernon, Simon Goldschmidt
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Fr辿d辿ric Bernon, Simon Goldschmidt
+ *
+ */
+#ifndef LWIP_HDR_APPS_SNTP_OPTS_H
+#define LWIP_HDR_APPS_SNTP_OPTS_H
+
+#include "lwip/opt.h"
+#include "lwip/prot/iana.h"
+
+/**
+ * @defgroup sntp_opts Options
+ * @ingroup sntp
+ * @{
+ */
+
+/** SNTP macro to change system time in seconds
+ * Define SNTP_SET_SYSTEM_TIME_US(sec, us) to set the time in microseconds
+ * instead of this one if you need the additional precision. Alternatively,
+ * define SNTP_SET_SYSTEM_TIME_NTP(sec, frac) in order to work with native
+ * NTP timestamps instead.
+ */
+#if !defined SNTP_SET_SYSTEM_TIME || defined __DOXYGEN__
+#define SNTP_SET_SYSTEM_TIME(sec)   LWIP_UNUSED_ARG(sec)
+#endif
+
+/** The maximum number of SNTP servers that can be set */
+#if !defined SNTP_MAX_SERVERS || defined __DOXYGEN__
+#define SNTP_MAX_SERVERS           LWIP_DHCP_MAX_NTP_SERVERS
+#endif
+
+/** Set this to 1 to implement the callback function called by dhcp when
+ * NTP servers are received. */
+#if !defined SNTP_GET_SERVERS_FROM_DHCP || defined __DOXYGEN__
+#define SNTP_GET_SERVERS_FROM_DHCP LWIP_DHCP_GET_NTP_SRV
+#endif
+
+/** Set this to 1 to support DNS names (or IP address strings) to set sntp servers
+ * One server address/name can be defined as default if SNTP_SERVER_DNS == 1:
+ * \#define SNTP_SERVER_ADDRESS "pool.ntp.org"
+ */
+#if !defined SNTP_SERVER_DNS || defined __DOXYGEN__
+#define SNTP_SERVER_DNS            0
+#endif
+
+/**
+ * SNTP_DEBUG: Enable debugging for SNTP.
+ */
+#if !defined SNTP_DEBUG || defined __DOXYGEN__
+#define SNTP_DEBUG                  LWIP_DBG_OFF
+#endif
+
+/** SNTP server port */
+#if !defined SNTP_PORT || defined __DOXYGEN__
+#define SNTP_PORT                   LWIP_IANA_PORT_SNTP
+#endif
+
+/** Sanity check:
+ * Define this to
+ * - 0 to turn off sanity checks (default; smaller code)
+ * - >= 1 to check address and port of the response packet to ensure the
+ *        response comes from the server we sent the request to.
+ * - >= 2 to check returned Originate Timestamp against Transmit Timestamp
+ *        sent to the server (to ensure response to older request).
+ * - >= 3 @todo: discard reply if any of the VN, Stratum, or Transmit Timestamp
+ *        fields is 0 or the Mode field is not 4 (unicast) or 5 (broadcast).
+ * - >= 4 @todo: to check that the Root Delay and Root Dispersion fields are each
+ *        greater than or equal to 0 and less than infinity, where infinity is
+ *        currently a cozy number like one second. This check avoids using a
+ *        server whose synchronization source has expired for a very long time.
+ */
+#if !defined SNTP_CHECK_RESPONSE || defined __DOXYGEN__
+#define SNTP_CHECK_RESPONSE         0
+#endif
+
+/** Enable round-trip delay compensation.
+ * Compensate for the round-trip delay by calculating the clock offset from
+ * the originate, receive, transmit and destination timestamps, as per RFC.
+ *
+ * The calculation requires compiler support for 64-bit integers. Also, either
+ * SNTP_SET_SYSTEM_TIME_US or SNTP_SET_SYSTEM_TIME_NTP has to be implemented
+ * for setting the system clock with sub-second precision. Likewise, either
+ * SNTP_GET_SYSTEM_TIME or SNTP_GET_SYSTEM_TIME_NTP needs to be implemented
+ * with sub-second precision.
+ *
+ * Although not strictly required, it makes sense to combine this option with
+ * SNTP_CHECK_RESPONSE >= 2 for sanity-checking of the received timestamps.
+ * Also, in order for the round-trip calculation to work, the difference
+ * between the local clock and the NTP server clock must not be larger than
+ * about 34 years. If that limit is exceeded, the implementation will fall back
+ * to setting the clock without compensation. In order to ensure that the local
+ * clock is always within the permitted range for compensation, even at first
+ * try, it may be necessary to store at least the current year in non-volatile
+ * memory.
+ */
+#if !defined SNTP_COMP_ROUNDTRIP || defined __DOXYGEN__
+#define SNTP_COMP_ROUNDTRIP         0
+#endif
+
+/** According to the RFC, this shall be a random delay
+ * between 1 and 5 minutes (in milliseconds) to prevent load peaks.
+ * This can be defined to a random generation function,
+ * which must return the delay in milliseconds as u32_t.
+ * Turned off by default.
+ */
+#if !defined SNTP_STARTUP_DELAY || defined __DOXYGEN__
+#ifdef LWIP_RAND
+#define SNTP_STARTUP_DELAY          1
+#else
+#define SNTP_STARTUP_DELAY          0
+#endif
+#endif
+
+/** If you want the startup delay to be a function, define this
+ * to a function (including the brackets) and define SNTP_STARTUP_DELAY to 1.
+ */
+#if !defined SNTP_STARTUP_DELAY_FUNC || defined __DOXYGEN__
+#define SNTP_STARTUP_DELAY_FUNC     (LWIP_RAND() % 5000)
+#endif
+
+/** SNTP receive timeout - in milliseconds
+ * Also used as retry timeout - this shouldn't be too low.
+ * Default is 15 seconds. Must not be beolw 15 seconds by specification (i.e. 15000)
+ */
+#if !defined SNTP_RECV_TIMEOUT || defined __DOXYGEN__
+#define SNTP_RECV_TIMEOUT           15000
+#endif
+
+/** SNTP update delay - in milliseconds
+ * Default is 1 hour. Must not be beolw 60 seconds by specification (i.e. 60000)
+ */
+#if !defined SNTP_UPDATE_DELAY || defined __DOXYGEN__
+#define SNTP_UPDATE_DELAY           3600000
+#endif
+
+/** SNTP macro to get system time, used with SNTP_CHECK_RESPONSE >= 2
+ * to send in request and compare in response. Also used for round-trip
+ * delay compensation if SNTP_COMP_ROUNDTRIP != 0.
+ * Alternatively, define SNTP_GET_SYSTEM_TIME_NTP(sec, frac) in order to
+ * work with native NTP timestamps instead.
+ */
+#if !defined SNTP_GET_SYSTEM_TIME || defined __DOXYGEN__
+#define SNTP_GET_SYSTEM_TIME(sec, us)     do { (sec) = 0; (us) = 0; } while(0)
+#endif
+
+/** Default retry timeout (in milliseconds) if the response
+ * received is invalid.
+ * This is doubled with each retry until SNTP_RETRY_TIMEOUT_MAX is reached.
+ */
+#if !defined SNTP_RETRY_TIMEOUT || defined __DOXYGEN__
+#define SNTP_RETRY_TIMEOUT          SNTP_RECV_TIMEOUT
+#endif
+
+/** Maximum retry timeout (in milliseconds). */
+#if !defined SNTP_RETRY_TIMEOUT_MAX || defined __DOXYGEN__
+#define SNTP_RETRY_TIMEOUT_MAX      (SNTP_RETRY_TIMEOUT * 10)
+#endif
+
+/** Increase retry timeout with every retry sent
+ * Default is on to conform to RFC.
+ */
+#if !defined SNTP_RETRY_TIMEOUT_EXP || defined __DOXYGEN__
+#define SNTP_RETRY_TIMEOUT_EXP      1
+#endif
+
+/** Keep a reachability shift register per server
+ * Default is on to conform to RFC.
+ */
+#if !defined SNTP_MONITOR_SERVER_REACHABILITY || defined __DOXYGEN__
+#define SNTP_MONITOR_SERVER_REACHABILITY 1
+#endif
+
+/**
+ * @}
+ */
+
+#endif /* LWIP_HDR_APPS_SNTP_OPTS_H */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/apps/tftp_opts.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/apps/tftp_opts.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/apps/tftp_opts.h	(revision 457)
@@ -0,0 +1,106 @@
+/**
+ *
+ * @file tftp_opts.h
+ *
+ * @author   Logan Gunthorpe <logang@deltatee.com>
+ *
+ * @brief    Trivial File Transfer Protocol (RFC 1350) implementation options
+ *
+ * Copyright (c) Deltatee Enterprises Ltd. 2013
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * Author: Logan Gunthorpe <logang@deltatee.com>
+ *
+ */
+
+#ifndef LWIP_HDR_APPS_TFTP_OPTS_H
+#define LWIP_HDR_APPS_TFTP_OPTS_H
+
+#include "lwip/opt.h"
+#include "lwip/prot/iana.h"
+
+/**
+ * @defgroup tftp_opts Options
+ * @ingroup tftp
+ * @{
+ */
+
+/**
+ * Enable TFTP debug messages
+ */
+#if !defined TFTP_DEBUG || defined __DOXYGEN__
+#define TFTP_DEBUG            LWIP_DBG_OFF
+#endif
+
+/**
+ * TFTP server port
+ */
+#if !defined TFTP_PORT || defined __DOXYGEN__
+#define TFTP_PORT             LWIP_IANA_PORT_TFTP
+#endif
+
+/**
+ * TFTP timeout
+ */
+#if !defined TFTP_TIMEOUT_MSECS || defined __DOXYGEN__
+#define TFTP_TIMEOUT_MSECS    10000
+#endif
+
+/**
+ * Max. number of retries when a file is read from server
+ */
+#if !defined TFTP_MAX_RETRIES || defined __DOXYGEN__
+#define TFTP_MAX_RETRIES      5
+#endif
+
+/**
+ * TFTP timer cyclic interval
+ */
+#if !defined TFTP_TIMER_MSECS || defined __DOXYGEN__
+#define TFTP_TIMER_MSECS      (TFTP_TIMEOUT_MSECS / 10)
+#endif
+
+/**
+ * Max. length of TFTP filename
+ */
+#if !defined TFTP_MAX_FILENAME_LEN || defined __DOXYGEN__
+#define TFTP_MAX_FILENAME_LEN 20
+#endif
+
+/**
+ * Max. length of TFTP mode
+ */
+#if !defined TFTP_MAX_MODE_LEN || defined __DOXYGEN__
+#define TFTP_MAX_MODE_LEN     7
+#endif
+
+/**
+ * @}
+ */
+
+#endif /* LWIP_HDR_APPS_TFTP_OPTS_H */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/apps/tftp_server.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/apps/tftp_server.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/apps/tftp_server.h	(revision 457)
@@ -0,0 +1,95 @@
+/**
+ *
+ * @file tftp_server.h
+ *
+ * @author   Logan Gunthorpe <logang@deltatee.com>
+ *
+ * @brief    Trivial File Transfer Protocol (RFC 1350)
+ *
+ * Copyright (c) Deltatee Enterprises Ltd. 2013
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * Author: Logan Gunthorpe <logang@deltatee.com>
+ *
+ */
+
+#ifndef LWIP_HDR_APPS_TFTP_SERVER_H
+#define LWIP_HDR_APPS_TFTP_SERVER_H
+
+#include "lwip/apps/tftp_opts.h"
+#include "lwip/err.h"
+#include "lwip/pbuf.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** @ingroup tftp
+ * TFTP context containing callback functions for TFTP transfers
+ */
+struct tftp_context {
+  /**
+   * Open file for read/write.
+   * @param fname Filename
+   * @param mode Mode string from TFTP RFC 1350 (netascii, octet, mail)
+   * @param write Flag indicating read (0) or write (!= 0) access
+   * @returns File handle supplied to other functions
+   */
+  void* (*open)(const char* fname, const char* mode, u8_t write);
+  /**
+   * Close file handle
+   * @param handle File handle returned by open()
+   */
+  void (*close)(void* handle);
+  /**
+   * Read from file 
+   * @param handle File handle returned by open()
+   * @param buf Target buffer to copy read data to
+   * @param bytes Number of bytes to copy to buf
+   * @returns &gt;= 0: Success; &lt; 0: Error
+   */
+  int (*read)(void* handle, void* buf, int bytes);
+  /**
+   * Write to file
+   * @param handle File handle returned by open()
+   * @param pbuf PBUF adjusted such that payload pointer points
+   *             to the beginning of write data. In other words,
+   *             TFTP headers are stripped off.
+   * @returns &gt;= 0: Success; &lt; 0: Error
+   */
+  int (*write)(void* handle, struct pbuf* p);
+};
+
+err_t tftp_init(const struct tftp_context* ctx);
+void tftp_cleanup(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LWIP_HDR_APPS_TFTP_SERVER_H */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/arch.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/arch.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/arch.h	(revision 457)
@@ -0,0 +1,393 @@
+/**
+ * @file
+ * Support for different processor and compiler architectures
+ */
+
+/*
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Adam Dunkels <adam@sics.se>
+ *
+ */
+#ifndef LWIP_HDR_ARCH_H
+#define LWIP_HDR_ARCH_H
+
+#ifndef LITTLE_ENDIAN
+#define LITTLE_ENDIAN 1234
+#endif
+
+#ifndef BIG_ENDIAN
+#define BIG_ENDIAN 4321
+#endif
+
+#include "arch/cc.h"
+
+/**
+ * @defgroup compiler_abstraction Compiler/platform abstraction
+ * @ingroup sys_layer
+ * All defines related to this section must not be placed in lwipopts.h,
+ * but in arch/cc.h!
+ * If the compiler does not provide memset() this file must include a
+ * definition of it, or include a file which defines it.
+ * These options cannot be \#defined in lwipopts.h since they are not options
+ * of lwIP itself, but options of the lwIP port to your system.
+ * @{
+ */
+
+/** Define the byte order of the system.
+ * Needed for conversion of network data to host byte order.
+ * Allowed values: LITTLE_ENDIAN and BIG_ENDIAN
+ */
+#ifndef BYTE_ORDER
+#define BYTE_ORDER LITTLE_ENDIAN
+#endif
+
+/** Define random number generator function of your system */
+#ifdef __DOXYGEN__
+#define LWIP_RAND() ((u32_t)rand())
+#endif
+
+/** Platform specific diagnostic output.\n
+ * Note the default implementation pulls in printf, which may
+ * in turn pull in a lot of standard libary code. In resource-constrained 
+ * systems, this should be defined to something less resource-consuming.
+ */
+#ifndef LWIP_PLATFORM_DIAG
+#define LWIP_PLATFORM_DIAG(x) do {printf x;} while(0)
+#include <stdio.h>
+#include <stdlib.h>
+#endif
+
+/** Platform specific assertion handling.\n
+ * Note the default implementation pulls in printf, fflush and abort, which may
+ * in turn pull in a lot of standard libary code. In resource-constrained 
+ * systems, this should be defined to something less resource-consuming.
+ */
+#ifndef LWIP_PLATFORM_ASSERT
+#define LWIP_PLATFORM_ASSERT(x) do {printf("Assertion \"%s\" failed at line %d in %s\n", \
+                                     x, __LINE__, __FILE__); fflush(NULL); abort();} while(0)
+#include <stdio.h>
+#include <stdlib.h>
+#endif
+
+/** Define this to 1 in arch/cc.h of your port if you do not want to
+ * include stddef.h header to get size_t. You need to typedef size_t
+ * by yourself in this case.
+ */
+#ifndef LWIP_NO_STDDEF_H
+#define LWIP_NO_STDDEF_H 0
+#endif
+
+#if !LWIP_NO_STDDEF_H
+#include <stddef.h> /* for size_t */
+#endif
+
+/** Define this to 1 in arch/cc.h of your port if your compiler does not provide
+ * the stdint.h header. You need to typedef the generic types listed in
+ * lwip/arch.h yourself in this case (u8_t, u16_t...).
+ */
+#ifndef LWIP_NO_STDINT_H
+#define LWIP_NO_STDINT_H 0
+#endif
+
+/* Define generic types used in lwIP */
+#if !LWIP_NO_STDINT_H
+#include <stdint.h>
+/* stdint.h is C99 which should also provide support for 64-bit integers */
+#if !defined(LWIP_HAVE_INT64) && defined(UINT64_MAX)
+#define LWIP_HAVE_INT64 1
+#endif
+typedef uint8_t   u8_t;
+typedef int8_t    s8_t;
+typedef uint16_t  u16_t;
+typedef int16_t   s16_t;
+typedef uint32_t  u32_t;
+typedef int32_t   s32_t;
+#if LWIP_HAVE_INT64
+typedef uint64_t  u64_t;
+typedef int64_t   s64_t;
+#endif
+typedef uintptr_t mem_ptr_t;
+#endif
+
+/** Define this to 1 in arch/cc.h of your port if your compiler does not provide
+ * the inttypes.h header. You need to define the format strings listed in
+ * lwip/arch.h yourself in this case (X8_F, U16_F...).
+ */
+#ifndef LWIP_NO_INTTYPES_H
+#define LWIP_NO_INTTYPES_H 0
+#endif
+
+/* Define (sn)printf formatters for these lwIP types */
+#if !LWIP_NO_INTTYPES_H
+#include <inttypes.h>
+#ifndef X8_F
+#define X8_F  "02" PRIx8
+#endif
+#ifndef U16_F
+#define U16_F PRIu16
+#endif
+#ifndef S16_F
+#define S16_F PRId16
+#endif
+#ifndef X16_F
+#define X16_F PRIx16
+#endif
+#ifndef U32_F
+#define U32_F PRIu32
+#endif
+#ifndef S32_F
+#define S32_F PRId32
+#endif
+#ifndef X32_F
+#define X32_F PRIx32
+#endif
+#ifndef SZT_F
+#define SZT_F PRIuPTR
+#endif
+#endif
+
+/** Define this to 1 in arch/cc.h of your port if your compiler does not provide
+ * the limits.h header. You need to define the type limits yourself in this case
+ * (e.g. INT_MAX, SSIZE_MAX).
+ */
+#ifndef LWIP_NO_LIMITS_H
+#define LWIP_NO_LIMITS_H 0
+#endif
+
+/* Include limits.h? */
+#if !LWIP_NO_LIMITS_H
+#include <limits.h>
+#endif
+
+/* Do we need to define ssize_t? This is a compatibility hack:
+ * Unfortunately, this type seems to be unavailable on some systems (even if
+ * sys/types or unistd.h are available).
+ * Being like that, we define it to 'int' if SSIZE_MAX is not defined.
+ */
+#ifdef SSIZE_MAX
+/* If SSIZE_MAX is defined, unistd.h should provide the type as well */
+#ifndef LWIP_NO_UNISTD_H
+#define LWIP_NO_UNISTD_H 0
+#endif
+#if !LWIP_NO_UNISTD_H
+#include <unistd.h>
+#endif
+#else /* SSIZE_MAX */
+typedef int ssize_t;
+#define SSIZE_MAX INT_MAX
+#endif /* SSIZE_MAX */
+
+/* some maximum values needed in lwip code */
+#define LWIP_UINT32_MAX 0xffffffff
+
+/** Define this to 1 in arch/cc.h of your port if your compiler does not provide
+ * the ctype.h header. If ctype.h is available, a few character functions
+ * are mapped to the appropriate functions (lwip_islower, lwip_isdigit...), if
+ * not, a private implementation is provided.
+ */
+#ifndef LWIP_NO_CTYPE_H
+#define LWIP_NO_CTYPE_H 0
+#endif
+
+#if LWIP_NO_CTYPE_H
+#define lwip_in_range(c, lo, up)  ((u8_t)(c) >= (lo) && (u8_t)(c) <= (up))
+#define lwip_isdigit(c)           lwip_in_range((c), '0', '9')
+#define lwip_isxdigit(c)          (lwip_isdigit(c) || lwip_in_range((c), 'a', 'f') || lwip_in_range((c), 'A', 'F'))
+#define lwip_islower(c)           lwip_in_range((c), 'a', 'z')
+#define lwip_isspace(c)           ((c) == ' ' || (c) == '\f' || (c) == '\n' || (c) == '\r' || (c) == '\t' || (c) == '\v')
+#define lwip_isupper(c)           lwip_in_range((c), 'A', 'Z')
+#define lwip_tolower(c)           (lwip_isupper(c) ? (c) - 'A' + 'a' : c)
+#define lwip_toupper(c)           (lwip_islower(c) ? (c) - 'a' + 'A' : c)
+#else
+#include <ctype.h>
+#define lwip_isdigit(c)           isdigit((unsigned char)(c))
+#define lwip_isxdigit(c)          isxdigit((unsigned char)(c))
+#define lwip_islower(c)           islower((unsigned char)(c))
+#define lwip_isspace(c)           isspace((unsigned char)(c))
+#define lwip_isupper(c)           isupper((unsigned char)(c))
+#define lwip_tolower(c)           tolower((unsigned char)(c))
+#define lwip_toupper(c)           toupper((unsigned char)(c))
+#endif
+
+/** C++ const_cast<target_type>(val) equivalent to remove constness from a value (GCC -Wcast-qual) */
+#ifndef LWIP_CONST_CAST
+#define LWIP_CONST_CAST(target_type, val) ((target_type)((ptrdiff_t)val))
+#endif
+
+/** Get rid of alignment cast warnings (GCC -Wcast-align) */
+#ifndef LWIP_ALIGNMENT_CAST
+#define LWIP_ALIGNMENT_CAST(target_type, val) LWIP_CONST_CAST(target_type, val)
+#endif
+
+/** Get rid of warnings related to pointer-to-numeric and vice-versa casts,
+ * e.g. "conversion from 'u8_t' to 'void *' of greater size"
+ */
+#ifndef LWIP_PTR_NUMERIC_CAST
+#define LWIP_PTR_NUMERIC_CAST(target_type, val) LWIP_CONST_CAST(target_type, val)
+#endif
+
+/** Avoid warnings/errors related to implicitly casting away packed attributes by doing a explicit cast */
+#ifndef LWIP_PACKED_CAST
+#define LWIP_PACKED_CAST(target_type, val) LWIP_CONST_CAST(target_type, val)
+#endif
+
+/** Allocates a memory buffer of specified size that is of sufficient size to align
+ * its start address using LWIP_MEM_ALIGN.
+ * You can declare your own version here e.g. to enforce alignment without adding
+ * trailing padding bytes (see LWIP_MEM_ALIGN_BUFFER) or your own section placement
+ * requirements.\n
+ * e.g. if you use gcc and need 32 bit alignment:\n
+ * \#define LWIP_DECLARE_MEMORY_ALIGNED(variable_name, size) u8_t variable_name[size] \_\_attribute\_\_((aligned(4)))\n
+ * or more portable:\n
+ * \#define LWIP_DECLARE_MEMORY_ALIGNED(variable_name, size) u32_t variable_name[(size + sizeof(u32_t) - 1) / sizeof(u32_t)]
+ */
+#ifndef LWIP_DECLARE_MEMORY_ALIGNED
+#define LWIP_DECLARE_MEMORY_ALIGNED(variable_name, size) u8_t variable_name[LWIP_MEM_ALIGN_BUFFER(size)]
+#endif
+
+/** Calculate memory size for an aligned buffer - returns the next highest
+ * multiple of MEM_ALIGNMENT (e.g. LWIP_MEM_ALIGN_SIZE(3) and
+ * LWIP_MEM_ALIGN_SIZE(4) will both yield 4 for MEM_ALIGNMENT == 4).
+ */
+#ifndef LWIP_MEM_ALIGN_SIZE
+#define LWIP_MEM_ALIGN_SIZE(size) (((size) + MEM_ALIGNMENT - 1U) & ~(MEM_ALIGNMENT-1U))
+#endif
+
+/** Calculate safe memory size for an aligned buffer when using an unaligned
+ * type as storage. This includes a safety-margin on (MEM_ALIGNMENT - 1) at the
+ * start (e.g. if buffer is u8_t[] and actual data will be u32_t*)
+ */
+#ifndef LWIP_MEM_ALIGN_BUFFER
+#define LWIP_MEM_ALIGN_BUFFER(size) (((size) + MEM_ALIGNMENT - 1U))
+#endif
+
+/** Align a memory pointer to the alignment defined by MEM_ALIGNMENT
+ * so that ADDR % MEM_ALIGNMENT == 0
+ */
+#ifndef LWIP_MEM_ALIGN
+#define LWIP_MEM_ALIGN(addr) ((void *)(((mem_ptr_t)(addr) + MEM_ALIGNMENT - 1) & ~(mem_ptr_t)(MEM_ALIGNMENT-1)))
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Packed structs support.
+  * Placed BEFORE declaration of a packed struct.\n
+  * For examples of packed struct declarations, see include/lwip/prot/ subfolder.\n
+  * A port to GCC/clang is included in lwIP, if you use these compilers there is nothing to do here.
+  */
+#ifndef PACK_STRUCT_BEGIN
+#define PACK_STRUCT_BEGIN
+#endif /* PACK_STRUCT_BEGIN */
+
+/** Packed structs support.
+  * Placed AFTER declaration of a packed struct.\n
+  * For examples of packed struct declarations, see include/lwip/prot/ subfolder.\n
+  * A port to GCC/clang is included in lwIP, if you use these compilers there is nothing to do here.
+  */
+#ifndef PACK_STRUCT_END
+#define PACK_STRUCT_END
+#endif /* PACK_STRUCT_END */
+
+/** Packed structs support.
+  * Placed between end of declaration of a packed struct and trailing semicolon.\n
+  * For examples of packed struct declarations, see include/lwip/prot/ subfolder.\n
+  * A port to GCC/clang is included in lwIP, if you use these compilers there is nothing to do here.
+  */
+#ifndef PACK_STRUCT_STRUCT
+#if defined(__GNUC__) || defined(__clang__)
+#define PACK_STRUCT_STRUCT __attribute__((packed))
+#else
+#define PACK_STRUCT_STRUCT
+#endif
+#endif /* PACK_STRUCT_STRUCT */
+
+/** Packed structs support.
+  * Wraps u32_t and u16_t members.\n
+  * For examples of packed struct declarations, see include/lwip/prot/ subfolder.\n
+  * A port to GCC/clang is included in lwIP, if you use these compilers there is nothing to do here.
+  */
+#ifndef PACK_STRUCT_FIELD
+#define PACK_STRUCT_FIELD(x) x
+#endif /* PACK_STRUCT_FIELD */
+
+/** Packed structs support.
+  * Wraps u8_t members, where some compilers warn that packing is not necessary.\n
+  * For examples of packed struct declarations, see include/lwip/prot/ subfolder.\n
+  * A port to GCC/clang is included in lwIP, if you use these compilers there is nothing to do here.
+  */
+#ifndef PACK_STRUCT_FLD_8
+#define PACK_STRUCT_FLD_8(x) PACK_STRUCT_FIELD(x)
+#endif /* PACK_STRUCT_FLD_8 */
+
+/** Packed structs support.
+  * Wraps members that are packed structs themselves, where some compilers warn that packing is not necessary.\n
+  * For examples of packed struct declarations, see include/lwip/prot/ subfolder.\n
+  * A port to GCC/clang is included in lwIP, if you use these compilers there is nothing to do here.
+  */
+#ifndef PACK_STRUCT_FLD_S
+#define PACK_STRUCT_FLD_S(x) PACK_STRUCT_FIELD(x)
+#endif /* PACK_STRUCT_FLD_S */
+
+/** PACK_STRUCT_USE_INCLUDES==1: Packed structs support using \#include files before and after struct to be packed.\n
+ * The file included BEFORE the struct is "arch/bpstruct.h".\n
+ * The file included AFTER the struct is "arch/epstruct.h".\n
+ * This can be used to implement struct packing on MS Visual C compilers, see
+ * the Win32 port in the lwIP contrib repository for reference.
+ * For examples of packed struct declarations, see include/lwip/prot/ subfolder.\n
+ * A port to GCC/clang is included in lwIP, if you use these compilers there is nothing to do here.
+ */
+#ifdef __DOXYGEN__
+#define PACK_STRUCT_USE_INCLUDES
+#endif
+
+/** Eliminates compiler warning about unused arguments (GCC -Wextra -Wunused). */
+#ifndef LWIP_UNUSED_ARG
+#define LWIP_UNUSED_ARG(x) (void)x
+#endif /* LWIP_UNUSED_ARG */
+
+/** LWIP_PROVIDE_ERRNO==1: Let lwIP provide ERRNO values and the 'errno' variable.
+ * If this is disabled, cc.h must either define 'errno', include <errno.h>,
+ * define LWIP_ERRNO_STDINCLUDE to get <errno.h> included or
+ * define LWIP_ERRNO_INCLUDE to <errno.h> or equivalent.
+ */
+#if defined __DOXYGEN__
+#define LWIP_PROVIDE_ERRNO
+#endif
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LWIP_HDR_ARCH_H */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/autoip.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/autoip.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/autoip.h	(revision 457)
@@ -0,0 +1,99 @@
+/**
+ * @file
+ *
+ * AutoIP Automatic LinkLocal IP Configuration
+ */
+
+/*
+ *
+ * Copyright (c) 2007 Dominik Spies <kontakt@dspies.de>
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * Author: Dominik Spies <kontakt@dspies.de>
+ *
+ * This is a AutoIP implementation for the lwIP TCP/IP stack. It aims to conform
+ * with RFC 3927.
+ *
+ */
+
+#ifndef LWIP_HDR_AUTOIP_H
+#define LWIP_HDR_AUTOIP_H
+
+#include "lwip/opt.h"
+
+#if LWIP_IPV4 && LWIP_AUTOIP /* don't build if not configured for use in lwipopts.h */
+
+#include "lwip/netif.h"
+/* #include "lwip/udp.h" */
+#include "lwip/etharp.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** AutoIP Timing */
+#define AUTOIP_TMR_INTERVAL      100
+#define AUTOIP_TICKS_PER_SECOND (1000 / AUTOIP_TMR_INTERVAL)
+
+/** AutoIP state information per netif */
+struct autoip
+{
+  /** the currently selected, probed, announced or used LL IP-Address */
+  ip4_addr_t llipaddr;
+  /** current AutoIP state machine state */
+  u8_t state;
+  /** sent number of probes or announces, dependent on state */
+  u8_t sent_num;
+  /** ticks to wait, tick is AUTOIP_TMR_INTERVAL long */
+  u16_t ttw;
+  /** ticks until a conflict can be solved by defending */
+  u8_t lastconflict;
+  /** total number of probed/used Link Local IP-Addresses */
+  u8_t tried_llipaddr;
+};
+
+
+void autoip_set_struct(struct netif *netif, struct autoip *autoip);
+/** Remove a struct autoip previously set to the netif using autoip_set_struct() */
+#define autoip_remove_struct(netif) do { (netif)->autoip = NULL; } while (0)
+err_t autoip_start(struct netif *netif);
+err_t autoip_stop(struct netif *netif);
+void autoip_arp_reply(struct netif *netif, struct etharp_hdr *hdr);
+void autoip_tmr(void);
+void autoip_network_changed(struct netif *netif);
+u8_t autoip_supplied_address(const struct netif *netif);
+
+/* for lwIP internal use by ip4.c */
+u8_t autoip_accept_packet(struct netif *netif, const ip4_addr_t *addr);
+
+#define netif_autoip_data(netif) ((struct autoip*)netif_get_client_data(netif, LWIP_NETIF_CLIENT_DATA_INDEX_AUTOIP))
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LWIP_IPV4 && LWIP_AUTOIP */
+
+#endif /* LWIP_HDR_AUTOIP_H */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/debug.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/debug.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/debug.h	(revision 457)
@@ -0,0 +1,161 @@
+/**
+ * @file
+ * Debug messages infrastructure
+ */
+
+/*
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Adam Dunkels <adam@sics.se>
+ *
+ */
+#ifndef LWIP_HDR_DEBUG_H
+#define LWIP_HDR_DEBUG_H
+
+#include "lwip/arch.h"
+#include "lwip/opt.h"
+
+/**
+ * @defgroup debugging_levels LWIP_DBG_MIN_LEVEL and LWIP_DBG_TYPES_ON values
+ * @ingroup lwip_opts_debugmsg
+ * @{
+ */
+
+/** @name Debug level (LWIP_DBG_MIN_LEVEL)
+ * @{
+ */
+/** Debug level: ALL messages*/
+#define LWIP_DBG_LEVEL_ALL     0x00
+/** Debug level: Warnings. bad checksums, dropped packets, ... */
+#define LWIP_DBG_LEVEL_WARNING 0x01
+/** Debug level: Serious. memory allocation failures, ... */
+#define LWIP_DBG_LEVEL_SERIOUS 0x02
+/** Debug level: Severe */
+#define LWIP_DBG_LEVEL_SEVERE  0x03
+/**
+ * @}
+ */
+
+#define LWIP_DBG_MASK_LEVEL    0x03
+/* compatibility define only */
+#define LWIP_DBG_LEVEL_OFF     LWIP_DBG_LEVEL_ALL
+
+/** @name Enable/disable debug messages completely (LWIP_DBG_TYPES_ON)
+ * @{
+ */
+/** flag for LWIP_DEBUGF to enable that debug message */
+#define LWIP_DBG_ON            0x80U
+/** flag for LWIP_DEBUGF to disable that debug message */
+#define LWIP_DBG_OFF           0x00U
+/**
+ * @}
+ */
+
+/** @name Debug message types (LWIP_DBG_TYPES_ON)
+ * @{
+ */
+/** flag for LWIP_DEBUGF indicating a tracing message (to follow program flow) */
+#define LWIP_DBG_TRACE         0x40U
+/** flag for LWIP_DEBUGF indicating a state debug message (to follow module states) */
+#define LWIP_DBG_STATE         0x20U
+/** flag for LWIP_DEBUGF indicating newly added code, not thoroughly tested yet */
+#define LWIP_DBG_FRESH         0x10U
+/** flag for LWIP_DEBUGF to halt after printing this debug message */
+#define LWIP_DBG_HALT          0x08U
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @defgroup lwip_assertions Assertion handling
+ * @ingroup lwip_opts_debug
+ * @{
+ */
+/**
+ * LWIP_NOASSERT: Disable LWIP_ASSERT checks:
+ * To disable assertions define LWIP_NOASSERT in arch/cc.h.
+ */
+#ifdef __DOXYGEN__
+#define LWIP_NOASSERT
+#undef LWIP_NOASSERT
+#endif
+/**
+ * @}
+ */
+
+#ifndef LWIP_NOASSERT
+#define LWIP_ASSERT(message, assertion) do { if (!(assertion)) { \
+  LWIP_PLATFORM_ASSERT(message); }} while(0)
+#else  /* LWIP_NOASSERT */
+#define LWIP_ASSERT(message, assertion)
+#endif /* LWIP_NOASSERT */
+
+#ifndef LWIP_ERROR
+#ifndef LWIP_NOASSERT
+#define LWIP_PLATFORM_ERROR(message) LWIP_PLATFORM_ASSERT(message)
+#elif defined LWIP_DEBUG
+#define LWIP_PLATFORM_ERROR(message) LWIP_PLATFORM_DIAG((message))
+#else
+#define LWIP_PLATFORM_ERROR(message)
+#endif
+
+/* if "expression" isn't true, then print "message" and execute "handler" expression */
+#define LWIP_ERROR(message, expression, handler) do { if (!(expression)) { \
+  LWIP_PLATFORM_ERROR(message); handler;}} while(0)
+#endif /* LWIP_ERROR */
+
+/** Enable debug message printing, but only if debug message type is enabled
+ *  AND is of correct type AND is at least LWIP_DBG_LEVEL.
+ */
+#ifdef __DOXYGEN__
+#define LWIP_DEBUG
+#undef LWIP_DEBUG
+#endif
+
+#ifdef LWIP_DEBUG
+#define LWIP_DEBUGF(debug, message) do { \
+                               if ( \
+                                   ((debug) & LWIP_DBG_ON) && \
+                                   ((debug) & LWIP_DBG_TYPES_ON) && \
+                                   ((s16_t)((debug) & LWIP_DBG_MASK_LEVEL) >= LWIP_DBG_MIN_LEVEL)) { \
+                                 LWIP_PLATFORM_DIAG(message); \
+                                 if ((debug) & LWIP_DBG_HALT) { \
+                                   while(1); \
+                                 } \
+                               } \
+                             } while(0)
+
+#else  /* LWIP_DEBUG */
+#define LWIP_DEBUGF(debug, message)
+#endif /* LWIP_DEBUG */
+
+#endif /* LWIP_HDR_DEBUG_H */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/def.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/def.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/def.h	(revision 457)
@@ -0,0 +1,152 @@
+/**
+ * @file
+ * various utility macros
+ */
+
+/*
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Adam Dunkels <adam@sics.se>
+ *
+ */
+
+/**
+ * @defgroup perf Performance measurement
+ * @ingroup sys_layer
+ * All defines related to this section must not be placed in lwipopts.h,
+ * but in arch/perf.h!
+ * Measurement calls made throughout lwip, these can be defined to nothing.
+ * - PERF_START: start measuring something.
+ * - PERF_STOP(x): stop measuring something, and record the result.
+ */
+
+#ifndef LWIP_HDR_DEF_H
+#define LWIP_HDR_DEF_H
+
+/* arch.h might define NULL already */
+#include "lwip/arch.h"
+#include "lwip/opt.h"
+#if LWIP_PERF
+#include "arch/perf.h"
+#else /* LWIP_PERF */
+#define PERF_START    /* null definition */
+#define PERF_STOP(x)  /* null definition */
+#endif /* LWIP_PERF */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define LWIP_MAX(x , y)  (((x) > (y)) ? (x) : (y))
+#define LWIP_MIN(x , y)  (((x) < (y)) ? (x) : (y))
+
+/* Get the number of entries in an array ('x' must NOT be a pointer!) */
+#define LWIP_ARRAYSIZE(x) (sizeof(x)/sizeof((x)[0]))
+
+/** Create u32_t value from bytes */
+#define LWIP_MAKEU32(a,b,c,d) (((u32_t)((a) & 0xff) << 24) | \
+                               ((u32_t)((b) & 0xff) << 16) | \
+                               ((u32_t)((c) & 0xff) << 8)  | \
+                                (u32_t)((d) & 0xff))
+
+#ifndef NULL
+#ifdef __cplusplus
+#define NULL 0
+#else
+#define NULL ((void *)0)
+#endif
+#endif
+
+#if BYTE_ORDER == BIG_ENDIAN
+#define lwip_htons(x) ((u16_t)(x))
+#define lwip_ntohs(x) ((u16_t)(x))
+#define lwip_htonl(x) ((u32_t)(x))
+#define lwip_ntohl(x) ((u32_t)(x))
+#define PP_HTONS(x)   ((u16_t)(x))
+#define PP_NTOHS(x)   ((u16_t)(x))
+#define PP_HTONL(x)   ((u32_t)(x))
+#define PP_NTOHL(x)   ((u32_t)(x))
+#else /* BYTE_ORDER != BIG_ENDIAN */
+#ifndef lwip_htons
+u16_t lwip_htons(u16_t x);
+#endif
+#define lwip_ntohs(x) lwip_htons(x)
+
+#ifndef lwip_htonl
+u32_t lwip_htonl(u32_t x);
+#endif
+#define lwip_ntohl(x) lwip_htonl(x)
+
+/* These macros should be calculated by the preprocessor and are used
+   with compile-time constants only (so that there is no little-endian
+   overhead at runtime). */
+#define PP_HTONS(x) ((u16_t)((((x) & (u16_t)0x00ffU) << 8) | (((x) & (u16_t)0xff00U) >> 8)))
+#define PP_NTOHS(x) PP_HTONS(x)
+#define PP_HTONL(x) ((((x) & (u32_t)0x000000ffUL) << 24) | \
+                     (((x) & (u32_t)0x0000ff00UL) <<  8) | \
+                     (((x) & (u32_t)0x00ff0000UL) >>  8) | \
+                     (((x) & (u32_t)0xff000000UL) >> 24))
+#define PP_NTOHL(x) PP_HTONL(x)
+#endif /* BYTE_ORDER == BIG_ENDIAN */
+
+/* Provide usual function names as macros for users, but this can be turned off */
+#ifndef LWIP_DONT_PROVIDE_BYTEORDER_FUNCTIONS
+#define htons(x) lwip_htons(x)
+#define ntohs(x) lwip_ntohs(x)
+#define htonl(x) lwip_htonl(x)
+#define ntohl(x) lwip_ntohl(x)
+#endif
+
+/* Functions that are not available as standard implementations.
+ * In cc.h, you can #define these to implementations available on
+ * your platform to save some code bytes if you use these functions
+ * in your application, too.
+ */
+
+#ifndef lwip_itoa
+/* This can be #defined to itoa() or snprintf(result, bufsize, "%d", number) depending on your platform */
+void  lwip_itoa(char* result, size_t bufsize, int number);
+#endif
+#ifndef lwip_strnicmp
+/* This can be #defined to strnicmp() or strncasecmp() depending on your platform */
+int   lwip_strnicmp(const char* str1, const char* str2, size_t len);
+#endif
+#ifndef lwip_stricmp
+/* This can be #defined to stricmp() or strcasecmp() depending on your platform */
+int   lwip_stricmp(const char* str1, const char* str2);
+#endif
+#ifndef lwip_strnstr
+/* This can be #defined to strnstr() depending on your platform */
+char* lwip_strnstr(const char* buffer, const char* token, size_t n);
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LWIP_HDR_DEF_H */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/dhcp.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/dhcp.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/dhcp.h	(revision 457)
@@ -0,0 +1,139 @@
+/**
+ * @file
+ * DHCP client API
+ */
+
+/*
+ * Copyright (c) 2001-2004 Leon Woestenberg <leon.woestenberg@gmx.net>
+ * Copyright (c) 2001-2004 Axon Digital Design B.V., The Netherlands.
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Leon Woestenberg <leon.woestenberg@gmx.net>
+ *
+ */
+#ifndef LWIP_HDR_DHCP_H
+#define LWIP_HDR_DHCP_H
+
+#include "lwip/opt.h"
+
+#if LWIP_DHCP /* don't build if not configured for use in lwipopts.h */
+
+#include "lwip/netif.h"
+#include "lwip/udp.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** period (in seconds) of the application calling dhcp_coarse_tmr() */
+#define DHCP_COARSE_TIMER_SECS  60
+/** period (in milliseconds) of the application calling dhcp_coarse_tmr() */
+#define DHCP_COARSE_TIMER_MSECS (DHCP_COARSE_TIMER_SECS * 1000UL)
+/** period (in milliseconds) of the application calling dhcp_fine_tmr() */
+#define DHCP_FINE_TIMER_MSECS   500
+
+#define DHCP_BOOT_FILE_LEN      128U
+
+/* AutoIP cooperation flags (struct dhcp.autoip_coop_state) */
+typedef enum {
+  DHCP_AUTOIP_COOP_STATE_OFF  = 0,
+  DHCP_AUTOIP_COOP_STATE_ON   = 1
+} dhcp_autoip_coop_state_enum_t;
+
+struct dhcp
+{
+  /** transaction identifier of last sent request */
+  u32_t xid;
+  /** track PCB allocation state */
+  u8_t pcb_allocated;
+  /** current DHCP state machine state */
+  u8_t state;
+  /** retries of current request */
+  u8_t tries;
+#if LWIP_DHCP_AUTOIP_COOP
+  u8_t autoip_coop_state;
+#endif
+  u8_t subnet_mask_given;
+
+  u16_t request_timeout; /* #ticks with period DHCP_FINE_TIMER_SECS for request timeout */
+  u16_t t1_timeout;  /* #ticks with period DHCP_COARSE_TIMER_SECS for renewal time */
+  u16_t t2_timeout;  /* #ticks with period DHCP_COARSE_TIMER_SECS for rebind time */
+  u16_t t1_renew_time;  /* #ticks with period DHCP_COARSE_TIMER_SECS until next renew try */
+  u16_t t2_rebind_time; /* #ticks with period DHCP_COARSE_TIMER_SECS until next rebind try */
+  u16_t lease_used; /* #ticks with period DHCP_COARSE_TIMER_SECS since last received DHCP ack */
+  u16_t t0_timeout; /* #ticks with period DHCP_COARSE_TIMER_SECS for lease time */
+  ip_addr_t server_ip_addr; /* dhcp server address that offered this lease (ip_addr_t because passed to UDP) */
+  ip4_addr_t offered_ip_addr;
+  ip4_addr_t offered_sn_mask;
+  ip4_addr_t offered_gw_addr;
+
+  u32_t offered_t0_lease; /* lease period (in seconds) */
+  u32_t offered_t1_renew; /* recommended renew time (usually 50% of lease period) */
+  u32_t offered_t2_rebind; /* recommended rebind time (usually 87.5 of lease period)  */
+#if LWIP_DHCP_BOOTP_FILE
+  ip4_addr_t offered_si_addr;
+  char boot_file_name[DHCP_BOOT_FILE_LEN];
+#endif /* LWIP_DHCP_BOOTPFILE */
+};
+
+
+void dhcp_set_struct(struct netif *netif, struct dhcp *dhcp);
+/** Remove a struct dhcp previously set to the netif using dhcp_set_struct() */
+#define dhcp_remove_struct(netif) netif_set_client_data(netif, LWIP_NETIF_CLIENT_DATA_INDEX_DHCP, NULL)
+void dhcp_cleanup(struct netif *netif);
+err_t dhcp_start(struct netif *netif);
+err_t dhcp_renew(struct netif *netif);
+err_t dhcp_release(struct netif *netif);
+void dhcp_stop(struct netif *netif);
+void dhcp_release_and_stop(struct netif *netif);
+void dhcp_inform(struct netif *netif);
+void dhcp_network_changed(struct netif *netif);
+#if DHCP_DOES_ARP_CHECK
+void dhcp_arp_reply(struct netif *netif, const ip4_addr_t *addr);
+#endif
+u8_t dhcp_supplied_address(const struct netif *netif);
+/* to be called every minute */
+void dhcp_coarse_tmr(void);
+/* to be called every half second */
+void dhcp_fine_tmr(void);
+
+#if LWIP_DHCP_GET_NTP_SRV
+/** This function must exist, in other to add offered NTP servers to
+ * the NTP (or SNTP) engine.
+ * See LWIP_DHCP_MAX_NTP_SERVERS */
+extern void dhcp_set_ntp_servers(u8_t num_ntp_servers, const ip4_addr_t* ntp_server_addrs);
+#endif /* LWIP_DHCP_GET_NTP_SRV */
+
+#define netif_dhcp_data(netif) ((struct dhcp*)netif_get_client_data(netif, LWIP_NETIF_CLIENT_DATA_INDEX_DHCP))
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LWIP_DHCP */
+
+#endif /*LWIP_HDR_DHCP_H*/
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/dhcp6.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/dhcp6.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/dhcp6.h	(revision 457)
@@ -0,0 +1,104 @@
+/**
+ * @file
+ *
+ * DHCPv6 client: IPv6 address autoconfiguration as per
+ * RFC 3315 (stateful DHCPv6) and
+ * RFC 3736 (stateless DHCPv6).
+ */
+
+/*
+ * Copyright (c) 2018 Simon Goldschmidt
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Simon Goldschmidt <goldsimon@gmx.de>
+ */
+
+#ifndef LWIP_HDR_IP6_DHCP6_H
+#define LWIP_HDR_IP6_DHCP6_H
+
+#include "lwip/opt.h"
+
+#if LWIP_IPV6_DHCP6  /* don't build if not configured for use in lwipopts.h */
+
+#include "lwip/err.h"
+#include "lwip/netif.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** period (in milliseconds) of the application calling dhcp6_tmr() */
+#define DHCP6_TIMER_MSECS   500
+
+struct dhcp6
+{
+  /** transaction identifier of last sent request */
+  u32_t xid;
+  /** track PCB allocation state */
+  u8_t pcb_allocated;
+  /** current DHCPv6 state machine state */
+  u8_t state;
+  /** retries of current request */
+  u8_t tries;
+  /** if request config is triggered while another action is active, this keeps track of it */
+  u8_t request_config_pending;
+  /** #ticks with period DHCP6_TIMER_MSECS for request timeout */
+  u16_t request_timeout;
+#if LWIP_IPV6_DHCP6_STATEFUL
+  /* @todo: add more members here to keep track of stateful DHCPv6 data, like lease times */
+#endif /* LWIP_IPV6_DHCP6_STATEFUL */
+};
+
+void dhcp6_set_struct(struct netif *netif, struct dhcp6 *dhcp6);
+/** Remove a struct dhcp6 previously set to the netif using dhcp6_set_struct() */
+#define dhcp6_remove_struct(netif) netif_set_client_data(netif, LWIP_NETIF_CLIENT_DATA_INDEX_DHCP6, NULL)
+void dhcp6_cleanup(struct netif *netif);
+
+err_t dhcp6_enable_stateful(struct netif *netif);
+err_t dhcp6_enable_stateless(struct netif *netif);
+void dhcp6_disable(struct netif *netif);
+
+void dhcp6_tmr(void);
+
+void dhcp6_nd6_ra_trigger(struct netif *netif, u8_t managed_addr_config, u8_t other_config);
+
+#if LWIP_DHCP6_GET_NTP_SRV
+/** This function must exist, in other to add offered NTP servers to
+ * the NTP (or SNTP) engine.
+ * See LWIP_DHCP6_MAX_NTP_SERVERS */
+extern void dhcp6_set_ntp_servers(u8_t num_ntp_servers, const ip_addr_t* ntp_server_addrs);
+#endif /* LWIP_DHCP6_GET_NTP_SRV */
+
+#define netif_dhcp6_data(netif) ((struct dhcp6*)netif_get_client_data(netif, LWIP_NETIF_CLIENT_DATA_INDEX_DHCP6))
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LWIP_IPV6_DHCP6 */
+
+#endif /* LWIP_HDR_IP6_DHCP6_H */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/dns.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/dns.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/dns.h	(revision 457)
@@ -0,0 +1,131 @@
+/**
+ * @file
+ * DNS API
+ */
+
+/**
+ * lwip DNS resolver header file.
+
+ * Author: Jim Pettinato
+ *   April 2007
+
+ * ported from uIP resolv.c Copyright (c) 2002-2003, Adam Dunkels.
+ *
+ * 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. The name of the author may not be used to endorse or promote
+ *    products derived from this software without specific prior
+ *    written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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 LWIP_HDR_DNS_H
+#define LWIP_HDR_DNS_H
+
+#include "lwip/opt.h"
+
+#if LWIP_DNS
+
+#include "lwip/ip_addr.h"
+#include "lwip/err.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** DNS timer period */
+#define DNS_TMR_INTERVAL          1000
+
+/* DNS resolve types: */
+#define LWIP_DNS_ADDRTYPE_IPV4      0
+#define LWIP_DNS_ADDRTYPE_IPV6      1
+#define LWIP_DNS_ADDRTYPE_IPV4_IPV6 2 /* try to resolve IPv4 first, try IPv6 if IPv4 fails only */
+#define LWIP_DNS_ADDRTYPE_IPV6_IPV4 3 /* try to resolve IPv6 first, try IPv4 if IPv6 fails only */
+#if LWIP_IPV4 && LWIP_IPV6
+#ifndef LWIP_DNS_ADDRTYPE_DEFAULT
+#define LWIP_DNS_ADDRTYPE_DEFAULT   LWIP_DNS_ADDRTYPE_IPV4_IPV6
+#endif
+#elif LWIP_IPV4
+#define LWIP_DNS_ADDRTYPE_DEFAULT   LWIP_DNS_ADDRTYPE_IPV4
+#else
+#define LWIP_DNS_ADDRTYPE_DEFAULT   LWIP_DNS_ADDRTYPE_IPV6
+#endif
+
+#if DNS_LOCAL_HOSTLIST
+/** struct used for local host-list */
+struct local_hostlist_entry {
+  /** static hostname */
+  const char *name;
+  /** static host address in network byteorder */
+  ip_addr_t addr;
+  struct local_hostlist_entry *next;
+};
+#define DNS_LOCAL_HOSTLIST_ELEM(name, addr_init) {name, addr_init, NULL}
+#if DNS_LOCAL_HOSTLIST_IS_DYNAMIC
+#ifndef DNS_LOCAL_HOSTLIST_MAX_NAMELEN
+#define DNS_LOCAL_HOSTLIST_MAX_NAMELEN  DNS_MAX_NAME_LENGTH
+#endif
+#define LOCALHOSTLIST_ELEM_SIZE ((sizeof(struct local_hostlist_entry) + DNS_LOCAL_HOSTLIST_MAX_NAMELEN + 1))
+#endif /* DNS_LOCAL_HOSTLIST_IS_DYNAMIC */
+#endif /* DNS_LOCAL_HOSTLIST */
+
+#if LWIP_IPV4
+extern const ip_addr_t dns_mquery_v4group;
+#endif /* LWIP_IPV4 */
+#if LWIP_IPV6
+extern const ip_addr_t dns_mquery_v6group;
+#endif /* LWIP_IPV6 */
+
+/** Callback which is invoked when a hostname is found.
+ * A function of this type must be implemented by the application using the DNS resolver.
+ * @param name pointer to the name that was looked up.
+ * @param ipaddr pointer to an ip_addr_t containing the IP address of the hostname,
+ *        or NULL if the name could not be found (or on any other error).
+ * @param callback_arg a user-specified callback argument passed to dns_gethostbyname
+*/
+typedef void (*dns_found_callback)(const char *name, const ip_addr_t *ipaddr, void *callback_arg);
+
+void             dns_init(void);
+void             dns_tmr(void);
+void             dns_setserver(u8_t numdns, const ip_addr_t *dnsserver);
+const ip_addr_t* dns_getserver(u8_t numdns);
+err_t            dns_gethostbyname(const char *hostname, ip_addr_t *addr,
+                                   dns_found_callback found, void *callback_arg);
+err_t            dns_gethostbyname_addrtype(const char *hostname, ip_addr_t *addr,
+                                   dns_found_callback found, void *callback_arg,
+                                   u8_t dns_addrtype);
+
+
+#if DNS_LOCAL_HOSTLIST
+size_t         dns_local_iterate(dns_found_callback iterator_fn, void *iterator_arg);
+err_t          dns_local_lookup(const char *hostname, ip_addr_t *addr, u8_t dns_addrtype);
+#if DNS_LOCAL_HOSTLIST_IS_DYNAMIC
+int            dns_local_removehost(const char *hostname, const ip_addr_t *addr);
+err_t          dns_local_addhost(const char *hostname, const ip_addr_t *addr);
+#endif /* DNS_LOCAL_HOSTLIST_IS_DYNAMIC */
+#endif /* DNS_LOCAL_HOSTLIST */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LWIP_DNS */
+
+#endif /* LWIP_HDR_DNS_H */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/err.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/err.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/err.h	(revision 457)
@@ -0,0 +1,117 @@
+/**
+ * @file
+ * lwIP Error codes
+ */
+/*
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Adam Dunkels <adam@sics.se>
+ *
+ */
+#ifndef LWIP_HDR_ERR_H
+#define LWIP_HDR_ERR_H
+
+#include "lwip/opt.h"
+#include "lwip/arch.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @defgroup infrastructure_errors Error codes
+ * @ingroup infrastructure
+ * @{
+ */
+
+/** Definitions for error constants. */
+typedef enum {
+/** No error, everything OK. */
+  ERR_OK         = 0,
+/** Out of memory error.     */
+  ERR_MEM        = -1,
+/** Buffer error.            */
+  ERR_BUF        = -2,
+/** Timeout.                 */
+  ERR_TIMEOUT    = -3,
+/** Routing problem.         */
+  ERR_RTE        = -4,
+/** Operation in progress    */
+  ERR_INPROGRESS = -5,
+/** Illegal value.           */
+  ERR_VAL        = -6,
+/** Operation would block.   */
+  ERR_WOULDBLOCK = -7,
+/** Address in use.          */
+  ERR_USE        = -8,
+/** Already connecting.      */
+  ERR_ALREADY    = -9,
+/** Conn already established.*/
+  ERR_ISCONN     = -10,
+/** Not connected.           */
+  ERR_CONN       = -11,
+/** Low-level netif error    */
+  ERR_IF         = -12,
+
+/** Connection aborted.      */
+  ERR_ABRT       = -13,
+/** Connection reset.        */
+  ERR_RST        = -14,
+/** Connection closed.       */
+  ERR_CLSD       = -15,
+/** Illegal argument.        */
+  ERR_ARG        = -16
+} err_enum_t;
+
+/** Define LWIP_ERR_T in cc.h if you want to use
+ *  a different type for your platform (must be signed). */
+#ifdef LWIP_ERR_T
+typedef LWIP_ERR_T err_t;
+#else /* LWIP_ERR_T */
+typedef s8_t err_t;
+#endif /* LWIP_ERR_T*/
+
+/**
+ * @}
+ */
+
+#ifdef LWIP_DEBUG
+extern const char *lwip_strerr(err_t err);
+#else
+#define lwip_strerr(x) ""
+#endif /* LWIP_DEBUG */
+
+#if !NO_SYS
+int err_to_errno(err_t err);
+#endif /* !NO_SYS */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LWIP_HDR_ERR_H */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/errno.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/errno.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/errno.h	(revision 457)
@@ -0,0 +1,198 @@
+/**
+ * @file
+ * Posix Errno defines
+ */
+
+/*
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Adam Dunkels <adam@sics.se>
+ *
+ */
+#ifndef LWIP_HDR_ERRNO_H
+#define LWIP_HDR_ERRNO_H
+
+#include "lwip/opt.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef LWIP_PROVIDE_ERRNO
+
+#define  EPERM            1  /* Operation not permitted */
+#define  ENOENT           2  /* No such file or directory */
+#define  ESRCH            3  /* No such process */
+#define  EINTR            4  /* Interrupted system call */
+#define  EIO              5  /* I/O error */
+#define  ENXIO            6  /* No such device or address */
+#define  E2BIG            7  /* Arg list too long */
+#define  ENOEXEC          8  /* Exec format error */
+#define  EBADF            9  /* Bad file number */
+#define  ECHILD          10  /* No child processes */
+#define  EAGAIN          11  /* Try again */
+#define  ENOMEM          12  /* Out of memory */
+#define  EACCES          13  /* Permission denied */
+#define  EFAULT          14  /* Bad address */
+#define  ENOTBLK         15  /* Block device required */
+#define  EBUSY           16  /* Device or resource busy */
+#define  EEXIST          17  /* File exists */
+#define  EXDEV           18  /* Cross-device link */
+#define  ENODEV          19  /* No such device */
+#define  ENOTDIR         20  /* Not a directory */
+#define  EISDIR          21  /* Is a directory */
+#define  EINVAL          22  /* Invalid argument */
+#define  ENFILE          23  /* File table overflow */
+#define  EMFILE          24  /* Too many open files */
+#define  ENOTTY          25  /* Not a typewriter */
+#define  ETXTBSY         26  /* Text file busy */
+#define  EFBIG           27  /* File too large */
+#define  ENOSPC          28  /* No space left on device */
+#define  ESPIPE          29  /* Illegal seek */
+#define  EROFS           30  /* Read-only file system */
+#define  EMLINK          31  /* Too many links */
+#define  EPIPE           32  /* Broken pipe */
+#define  EDOM            33  /* Math argument out of domain of func */
+#define  ERANGE          34  /* Math result not representable */
+#define  EDEADLK         35  /* Resource deadlock would occur */
+#define  ENAMETOOLONG    36  /* File name too long */
+#define  ENOLCK          37  /* No record locks available */
+#define  ENOSYS          38  /* Function not implemented */
+#define  ENOTEMPTY       39  /* Directory not empty */
+#define  ELOOP           40  /* Too many symbolic links encountered */
+#define  EWOULDBLOCK     EAGAIN  /* Operation would block */
+#define  ENOMSG          42  /* No message of desired type */
+#define  EIDRM           43  /* Identifier removed */
+#define  ECHRNG          44  /* Channel number out of range */
+#define  EL2NSYNC        45  /* Level 2 not synchronized */
+#define  EL3HLT          46  /* Level 3 halted */
+#define  EL3RST          47  /* Level 3 reset */
+#define  ELNRNG          48  /* Link number out of range */
+#define  EUNATCH         49  /* Protocol driver not attached */
+#define  ENOCSI          50  /* No CSI structure available */
+#define  EL2HLT          51  /* Level 2 halted */
+#define  EBADE           52  /* Invalid exchange */
+#define  EBADR           53  /* Invalid request descriptor */
+#define  EXFULL          54  /* Exchange full */
+#define  ENOANO          55  /* No anode */
+#define  EBADRQC         56  /* Invalid request code */
+#define  EBADSLT         57  /* Invalid slot */
+
+#define  EDEADLOCK       EDEADLK
+
+#define  EBFONT          59  /* Bad font file format */
+#define  ENOSTR          60  /* Device not a stream */
+#define  ENODATA         61  /* No data available */
+#define  ETIME           62  /* Timer expired */
+#define  ENOSR           63  /* Out of streams resources */
+#define  ENONET          64  /* Machine is not on the network */
+#define  ENOPKG          65  /* Package not installed */
+#define  EREMOTE         66  /* Object is remote */
+#define  ENOLINK         67  /* Link has been severed */
+#define  EADV            68  /* Advertise error */
+#define  ESRMNT          69  /* Srmount error */
+#define  ECOMM           70  /* Communication error on send */
+#define  EPROTO          71  /* Protocol error */
+#define  EMULTIHOP       72  /* Multihop attempted */
+#define  EDOTDOT         73  /* RFS specific error */
+#define  EBADMSG         74  /* Not a data message */
+#define  EOVERFLOW       75  /* Value too large for defined data type */
+#define  ENOTUNIQ        76  /* Name not unique on network */
+#define  EBADFD          77  /* File descriptor in bad state */
+#define  EREMCHG         78  /* Remote address changed */
+#define  ELIBACC         79  /* Can not access a needed shared library */
+#define  ELIBBAD         80  /* Accessing a corrupted shared library */
+#define  ELIBSCN         81  /* .lib section in a.out corrupted */
+#define  ELIBMAX         82  /* Attempting to link in too many shared libraries */
+#define  ELIBEXEC        83  /* Cannot exec a shared library directly */
+#define  EILSEQ          84  /* Illegal byte sequence */
+#define  ERESTART        85  /* Interrupted system call should be restarted */
+#define  ESTRPIPE        86  /* Streams pipe error */
+#define  EUSERS          87  /* Too many users */
+#define  ENOTSOCK        88  /* Socket operation on non-socket */
+#define  EDESTADDRREQ    89  /* Destination address required */
+#define  EMSGSIZE        90  /* Message too long */
+#define  EPROTOTYPE      91  /* Protocol wrong type for socket */
+#define  ENOPROTOOPT     92  /* Protocol not available */
+#define  EPROTONOSUPPORT 93  /* Protocol not supported */
+#define  ESOCKTNOSUPPORT 94  /* Socket type not supported */
+#define  EOPNOTSUPP      95  /* Operation not supported on transport endpoint */
+#define  EPFNOSUPPORT    96  /* Protocol family not supported */
+#define  EAFNOSUPPORT    97  /* Address family not supported by protocol */
+#define  EADDRINUSE      98  /* Address already in use */
+#define  EADDRNOTAVAIL   99  /* Cannot assign requested address */
+#define  ENETDOWN       100  /* Network is down */
+#define  ENETUNREACH    101  /* Network is unreachable */
+#define  ENETRESET      102  /* Network dropped connection because of reset */
+#define  ECONNABORTED   103  /* Software caused connection abort */
+#define  ECONNRESET     104  /* Connection reset by peer */
+#define  ENOBUFS        105  /* No buffer space available */
+#define  EISCONN        106  /* Transport endpoint is already connected */
+#define  ENOTCONN       107  /* Transport endpoint is not connected */
+#define  ESHUTDOWN      108  /* Cannot send after transport endpoint shutdown */
+#define  ETOOMANYREFS   109  /* Too many references: cannot splice */
+#define  ETIMEDOUT      110  /* Connection timed out */
+#define  ECONNREFUSED   111  /* Connection refused */
+#define  EHOSTDOWN      112  /* Host is down */
+#define  EHOSTUNREACH   113  /* No route to host */
+#define  EALREADY       114  /* Operation already in progress */
+#define  EINPROGRESS    115  /* Operation now in progress */
+#define  ESTALE         116  /* Stale NFS file handle */
+#define  EUCLEAN        117  /* Structure needs cleaning */
+#define  ENOTNAM        118  /* Not a XENIX named type file */
+#define  ENAVAIL        119  /* No XENIX semaphores available */
+#define  EISNAM         120  /* Is a named type file */
+#define  EREMOTEIO      121  /* Remote I/O error */
+#define  EDQUOT         122  /* Quota exceeded */
+
+#define  ENOMEDIUM      123  /* No medium found */
+#define  EMEDIUMTYPE    124  /* Wrong medium type */
+
+#ifndef errno
+extern int errno;
+#endif
+
+#else /* LWIP_PROVIDE_ERRNO */
+
+/* Define LWIP_ERRNO_STDINCLUDE if you want to include <errno.h> here */
+#ifdef LWIP_ERRNO_STDINCLUDE
+#include <errno.h>
+#else /* LWIP_ERRNO_STDINCLUDE */
+/* Define LWIP_ERRNO_INCLUDE to an equivalent of <errno.h> to include the error defines here */
+#ifdef LWIP_ERRNO_INCLUDE
+#include LWIP_ERRNO_INCLUDE
+#endif /* LWIP_ERRNO_INCLUDE */
+#endif /* LWIP_ERRNO_STDINCLUDE */
+
+#endif /* LWIP_PROVIDE_ERRNO */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LWIP_HDR_ERRNO_H */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/etharp.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/etharp.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/etharp.h	(revision 457)
@@ -0,0 +1,105 @@
+/**
+ * @file
+ * Ethernet output function - handles OUTGOING ethernet level traffic, implements
+ * ARP resolving.
+ * To be used in most low-level netif implementations
+ */
+
+/*
+ * Copyright (c) 2001-2003 Swedish Institute of Computer Science.
+ * Copyright (c) 2003-2004 Leon Woestenberg <leon.woestenberg@axon.tv>
+ * Copyright (c) 2003-2004 Axon Digital Design B.V., The Netherlands.
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Adam Dunkels <adam@sics.se>
+ *
+ */
+
+#ifndef LWIP_HDR_NETIF_ETHARP_H
+#define LWIP_HDR_NETIF_ETHARP_H
+
+#include "lwip/opt.h"
+
+#if LWIP_ARP || LWIP_ETHERNET /* don't build if not configured for use in lwipopts.h */
+
+#include "lwip/pbuf.h"
+#include "lwip/ip4_addr.h"
+#include "lwip/netif.h"
+#include "lwip/ip4.h"
+#include "lwip/prot/ethernet.h"
+
+#if LWIP_IPV4 && LWIP_ARP /* don't build if not configured for use in lwipopts.h */
+
+#include "lwip/prot/etharp.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** 1 seconds period */
+#define ARP_TMR_INTERVAL 1000
+
+#if ARP_QUEUEING
+/** struct for queueing outgoing packets for unknown address
+  * defined here to be accessed by memp.h
+  */
+struct etharp_q_entry {
+  struct etharp_q_entry *next;
+  struct pbuf *p;
+};
+#endif /* ARP_QUEUEING */
+
+#define etharp_init() /* Compatibility define, no init needed. */
+void etharp_tmr(void);
+ssize_t etharp_find_addr(struct netif *netif, const ip4_addr_t *ipaddr,
+         struct eth_addr **eth_ret, const ip4_addr_t **ip_ret);
+int etharp_get_entry(size_t i, ip4_addr_t **ipaddr, struct netif **netif, struct eth_addr **eth_ret);
+err_t etharp_output(struct netif *netif, struct pbuf *q, const ip4_addr_t *ipaddr);
+err_t etharp_query(struct netif *netif, const ip4_addr_t *ipaddr, struct pbuf *q);
+err_t etharp_request(struct netif *netif, const ip4_addr_t *ipaddr);
+/** For Ethernet network interfaces, we might want to send "gratuitous ARP";
+ *  this is an ARP packet sent by a node in order to spontaneously cause other
+ *  nodes to update an entry in their ARP cache.
+ *  From RFC 3220 "IP Mobility Support for IPv4" section 4.6. */
+#define etharp_gratuitous(netif) etharp_request((netif), netif_ip4_addr(netif))
+void etharp_cleanup_netif(struct netif *netif);
+
+#if ETHARP_SUPPORT_STATIC_ENTRIES
+err_t etharp_add_static_entry(const ip4_addr_t *ipaddr, struct eth_addr *ethaddr);
+err_t etharp_remove_static_entry(const ip4_addr_t *ipaddr);
+#endif /* ETHARP_SUPPORT_STATIC_ENTRIES */
+
+void etharp_input(struct pbuf *p, struct netif *netif);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LWIP_IPV4 && LWIP_ARP */
+#endif /* LWIP_ARP || LWIP_ETHERNET */
+
+#endif /* LWIP_HDR_NETIF_ETHARP_H */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/ethip6.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/ethip6.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/ethip6.h	(revision 457)
@@ -0,0 +1,68 @@
+/**
+ * @file
+ *
+ * Ethernet output for IPv6. Uses ND tables for link-layer addressing.
+ */
+
+/*
+ * Copyright (c) 2010 Inico Technologies Ltd.
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Ivan Delamer <delamer@inicotech.com>
+ *
+ *
+ * Please coordinate changes and requests with Ivan Delamer
+ * <delamer@inicotech.com>
+ */
+
+#ifndef LWIP_HDR_ETHIP6_H
+#define LWIP_HDR_ETHIP6_H
+
+#include "lwip/opt.h"
+
+#if LWIP_IPV6 && LWIP_ETHERNET /* don't build if not configured for use in lwipopts.h */
+
+#include "lwip/pbuf.h"
+#include "lwip/ip6.h"
+#include "lwip/ip6_addr.h"
+#include "lwip/netif.h"
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+err_t ethip6_output(struct netif *netif, struct pbuf *q, const ip6_addr_t *ip6addr);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LWIP_IPV6 && LWIP_ETHERNET */
+
+#endif /* LWIP_HDR_ETHIP6_H */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/icmp.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/icmp.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/icmp.h	(revision 457)
@@ -0,0 +1,110 @@
+/**
+ * @file
+ * ICMP API
+ */
+
+/*
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Adam Dunkels <adam@sics.se>
+ *
+ */
+#ifndef LWIP_HDR_ICMP_H
+#define LWIP_HDR_ICMP_H
+
+#include "lwip/opt.h"
+#include "lwip/pbuf.h"
+#include "lwip/ip_addr.h"
+#include "lwip/netif.h"
+#include "lwip/prot/icmp.h"
+
+#if LWIP_IPV6 && LWIP_ICMP6
+#include "lwip/icmp6.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** ICMP destination unreachable codes */
+enum icmp_dur_type {
+  /** net unreachable */
+  ICMP_DUR_NET   = 0,
+  /** host unreachable */
+  ICMP_DUR_HOST  = 1,
+  /** protocol unreachable */
+  ICMP_DUR_PROTO = 2,
+  /** port unreachable */
+  ICMP_DUR_PORT  = 3,
+  /** fragmentation needed and DF set */
+  ICMP_DUR_FRAG  = 4,
+  /** source route failed */
+  ICMP_DUR_SR    = 5
+};
+
+/** ICMP time exceeded codes */
+enum icmp_te_type {
+  /** time to live exceeded in transit */
+  ICMP_TE_TTL  = 0,
+  /** fragment reassembly time exceeded */
+  ICMP_TE_FRAG = 1
+};
+
+#if LWIP_IPV4 && LWIP_ICMP /* don't build if not configured for use in lwipopts.h */
+
+void icmp_input(struct pbuf *p, struct netif *inp);
+void icmp_dest_unreach(struct pbuf *p, enum icmp_dur_type t);
+void icmp_time_exceeded(struct pbuf *p, enum icmp_te_type t);
+
+#endif /* LWIP_IPV4 && LWIP_ICMP */
+
+#if LWIP_IPV4 && LWIP_IPV6
+#if LWIP_ICMP && LWIP_ICMP6
+#define icmp_port_unreach(isipv6, pbuf) ((isipv6) ? \
+                                         icmp6_dest_unreach(pbuf, ICMP6_DUR_PORT) : \
+                                         icmp_dest_unreach(pbuf, ICMP_DUR_PORT))
+#elif LWIP_ICMP
+#define icmp_port_unreach(isipv6, pbuf) do{ if(!(isipv6)) { icmp_dest_unreach(pbuf, ICMP_DUR_PORT);}}while(0)
+#elif LWIP_ICMP6
+#define icmp_port_unreach(isipv6, pbuf) do{ if(isipv6) { icmp6_dest_unreach(pbuf, ICMP6_DUR_PORT);}}while(0)
+#else
+#define icmp_port_unreach(isipv6, pbuf)
+#endif
+#elif LWIP_IPV6 && LWIP_ICMP6
+#define icmp_port_unreach(isipv6, pbuf) icmp6_dest_unreach(pbuf, ICMP6_DUR_PORT)
+#elif LWIP_IPV4 && LWIP_ICMP
+#define icmp_port_unreach(isipv6, pbuf) icmp_dest_unreach(pbuf, ICMP_DUR_PORT)
+#else /* (LWIP_IPV6 && LWIP_ICMP6) || (LWIP_IPV4 && LWIP_ICMP) */
+#define icmp_port_unreach(isipv6, pbuf)
+#endif /* (LWIP_IPV6 && LWIP_ICMP6) || (LWIP_IPV4 && LWIP_ICMP) LWIP_IPV4*/
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LWIP_HDR_ICMP_H */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/icmp6.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/icmp6.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/icmp6.h	(revision 457)
@@ -0,0 +1,72 @@
+/**
+ * @file
+ *
+ * IPv6 version of ICMP, as per RFC 4443.
+ */
+
+/*
+ * Copyright (c) 2010 Inico Technologies Ltd.
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Ivan Delamer <delamer@inicotech.com>
+ *
+ *
+ * Please coordinate changes and requests with Ivan Delamer
+ * <delamer@inicotech.com>
+ */
+#ifndef LWIP_HDR_ICMP6_H
+#define LWIP_HDR_ICMP6_H
+
+#include "lwip/opt.h"
+#include "lwip/pbuf.h"
+#include "lwip/ip6_addr.h"
+#include "lwip/netif.h"
+#include "lwip/prot/icmp6.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if LWIP_ICMP6 && LWIP_IPV6 /* don't build if not configured for use in lwipopts.h */
+
+void icmp6_input(struct pbuf *p, struct netif *inp);
+void icmp6_dest_unreach(struct pbuf *p, enum icmp6_dur_code c);
+void icmp6_packet_too_big(struct pbuf *p, u32_t mtu);
+void icmp6_time_exceeded(struct pbuf *p, enum icmp6_te_code c);
+void icmp6_time_exceeded_with_addrs(struct pbuf *p, enum icmp6_te_code c,
+    const ip6_addr_t *src_addr, const ip6_addr_t *dest_addr);
+void icmp6_param_problem(struct pbuf *p, enum icmp6_pp_code c, const void *pointer);
+
+#endif /* LWIP_ICMP6 && LWIP_IPV6 */
+
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif /* LWIP_HDR_ICMP6_H */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/if_api.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/if_api.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/if_api.h	(revision 457)
@@ -0,0 +1,68 @@
+/**
+ * @file
+ * Interface Identification APIs from:
+ *              RFC 3493: Basic Socket Interface Extensions for IPv6
+ *                  Section 4: Interface Identification
+ */
+
+/*
+ * Copyright (c) 2017 Joel Cunningham, Garmin International, Inc. <joel.cunningham@garmin.com>
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Joel Cunningham <joel.cunningham@me.com>
+ *
+ */
+#ifndef LWIP_HDR_IF_H
+#define LWIP_HDR_IF_H
+
+#include "lwip/opt.h"
+
+#if LWIP_SOCKET /* don't build if not configured for use in lwipopts.h */
+
+#include "lwip/netif.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define IF_NAMESIZE NETIF_NAMESIZE
+
+char * lwip_if_indextoname(unsigned int ifindex, char *ifname);
+unsigned int lwip_if_nametoindex(const char *ifname);
+
+#if LWIP_COMPAT_SOCKETS
+#define if_indextoname(ifindex, ifname)  lwip_if_indextoname(ifindex,ifname)
+#define if_nametoindex(ifname)           lwip_if_nametoindex(ifname)
+#endif /* LWIP_COMPAT_SOCKETS */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LWIP_SOCKET */
+
+#endif /* LWIP_HDR_IF_H */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/igmp.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/igmp.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/igmp.h	(revision 457)
@@ -0,0 +1,115 @@
+/**
+ * @file
+ * IGMP API
+ */
+
+/*
+ * Copyright (c) 2002 CITEL Technologies Ltd.
+ * 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 CITEL Technologies Ltd 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 CITEL TECHNOLOGIES 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 CITEL TECHNOLOGIES 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.
+ *
+ * This file is a contribution to the lwIP TCP/IP stack.
+ * The Swedish Institute of Computer Science and Adam Dunkels
+ * are specifically granted permission to redistribute this
+ * source code.
+*/
+
+#ifndef LWIP_HDR_IGMP_H
+#define LWIP_HDR_IGMP_H
+
+#include "lwip/opt.h"
+#include "lwip/ip_addr.h"
+#include "lwip/netif.h"
+#include "lwip/pbuf.h"
+
+#if LWIP_IPV4 && LWIP_IGMP /* don't build if not configured for use in lwipopts.h */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* IGMP timer */
+#define IGMP_TMR_INTERVAL              100 /* Milliseconds */
+#define IGMP_V1_DELAYING_MEMBER_TMR   (1000/IGMP_TMR_INTERVAL)
+#define IGMP_JOIN_DELAYING_MEMBER_TMR (500 /IGMP_TMR_INTERVAL)
+
+/* Compatibility defines (don't use for new code) */
+#define IGMP_DEL_MAC_FILTER            NETIF_DEL_MAC_FILTER
+#define IGMP_ADD_MAC_FILTER            NETIF_ADD_MAC_FILTER
+
+/**
+ * igmp group structure - there is
+ * a list of groups for each interface
+ * these should really be linked from the interface, but
+ * if we keep them separate we will not affect the lwip original code
+ * too much
+ *
+ * There will be a group for the all systems group address but this
+ * will not run the state machine as it is used to kick off reports
+ * from all the other groups
+ */
+struct igmp_group {
+  /** next link */
+  struct igmp_group *next;
+  /** multicast address */
+  ip4_addr_t         group_address;
+  /** signifies we were the last person to report */
+  u8_t               last_reporter_flag;
+  /** current state of the group */
+  u8_t               group_state;
+  /** timer for reporting, negative is OFF */
+  u16_t              timer;
+  /** counter of simultaneous uses */
+  u8_t               use;
+};
+
+/*  Prototypes */
+void   igmp_init(void);
+err_t  igmp_start(struct netif *netif);
+err_t  igmp_stop(struct netif *netif);
+void   igmp_report_groups(struct netif *netif);
+struct igmp_group *igmp_lookfor_group(struct netif *ifp, const ip4_addr_t *addr);
+void   igmp_input(struct pbuf *p, struct netif *inp, const ip4_addr_t *dest);
+err_t  igmp_joingroup(const ip4_addr_t *ifaddr, const ip4_addr_t *groupaddr);
+err_t  igmp_joingroup_netif(struct netif *netif, const ip4_addr_t *groupaddr);
+err_t  igmp_leavegroup(const ip4_addr_t *ifaddr, const ip4_addr_t *groupaddr);
+err_t  igmp_leavegroup_netif(struct netif *netif, const ip4_addr_t *groupaddr);
+void   igmp_tmr(void);
+
+/** @ingroup igmp 
+ * Get list head of IGMP groups for netif.
+ * Note: The allsystems group IP is contained in the list as first entry.
+ * @see @ref netif_set_igmp_mac_filter()
+ */
+#define netif_igmp_data(netif) ((struct igmp_group *)netif_get_client_data(netif, LWIP_NETIF_CLIENT_DATA_INDEX_IGMP))
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LWIP_IPV4 && LWIP_IGMP */
+
+#endif /* LWIP_HDR_IGMP_H */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/inet.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/inet.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/inet.h	(revision 457)
@@ -0,0 +1,169 @@
+/**
+ * @file
+ * This file (together with sockets.h) aims to provide structs and functions from
+ * - arpa/inet.h
+ * - netinet/in.h
+ *
+ */
+
+/*
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Adam Dunkels <adam@sics.se>
+ *
+ */
+#ifndef LWIP_HDR_INET_H
+#define LWIP_HDR_INET_H
+
+#include "lwip/opt.h"
+#include "lwip/def.h"
+#include "lwip/ip_addr.h"
+#include "lwip/ip6_addr.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* If your port already typedef's in_addr_t, define IN_ADDR_T_DEFINED
+   to prevent this code from redefining it. */
+#if !defined(in_addr_t) && !defined(IN_ADDR_T_DEFINED)
+typedef u32_t in_addr_t;
+#endif
+
+struct in_addr {
+  in_addr_t s_addr;
+};
+
+struct in6_addr {
+  union {
+    u32_t u32_addr[4];
+    u8_t  u8_addr[16];
+  } un;
+#define s6_addr  un.u8_addr
+};
+
+/** 255.255.255.255 */
+#define INADDR_NONE         IPADDR_NONE
+/** 127.0.0.1 */
+#define INADDR_LOOPBACK     IPADDR_LOOPBACK
+/** 0.0.0.0 */
+#define INADDR_ANY          IPADDR_ANY
+/** 255.255.255.255 */
+#define INADDR_BROADCAST    IPADDR_BROADCAST
+
+/** This macro can be used to initialize a variable of type struct in6_addr
+    to the IPv6 wildcard address. */
+#define IN6ADDR_ANY_INIT {{{0,0,0,0}}}
+/** This macro can be used to initialize a variable of type struct in6_addr
+    to the IPv6 loopback address. */
+#define IN6ADDR_LOOPBACK_INIT {{{0,0,0,PP_HTONL(1)}}}
+/** This variable is initialized by the system to contain the wildcard IPv6 address. */
+extern const struct in6_addr in6addr_any;
+
+/* Definitions of the bits in an (IPv4) Internet address integer.
+
+   On subnets, host and network parts are found according to
+   the subnet mask, not these masks.  */
+#define IN_CLASSA(a)        IP_CLASSA(a)
+#define IN_CLASSA_NET       IP_CLASSA_NET
+#define IN_CLASSA_NSHIFT    IP_CLASSA_NSHIFT
+#define IN_CLASSA_HOST      IP_CLASSA_HOST
+#define IN_CLASSA_MAX       IP_CLASSA_MAX
+
+#define IN_CLASSB(b)        IP_CLASSB(b)
+#define IN_CLASSB_NET       IP_CLASSB_NET
+#define IN_CLASSB_NSHIFT    IP_CLASSB_NSHIFT
+#define IN_CLASSB_HOST      IP_CLASSB_HOST
+#define IN_CLASSB_MAX       IP_CLASSB_MAX
+
+#define IN_CLASSC(c)        IP_CLASSC(c)
+#define IN_CLASSC_NET       IP_CLASSC_NET
+#define IN_CLASSC_NSHIFT    IP_CLASSC_NSHIFT
+#define IN_CLASSC_HOST      IP_CLASSC_HOST
+#define IN_CLASSC_MAX       IP_CLASSC_MAX
+
+#define IN_CLASSD(d)        IP_CLASSD(d)
+#define IN_CLASSD_NET       IP_CLASSD_NET     /* These ones aren't really */
+#define IN_CLASSD_NSHIFT    IP_CLASSD_NSHIFT  /*   net and host fields, but */
+#define IN_CLASSD_HOST      IP_CLASSD_HOST    /*   routing needn't know. */
+#define IN_CLASSD_MAX       IP_CLASSD_MAX
+
+#define IN_MULTICAST(a)     IP_MULTICAST(a)
+
+#define IN_EXPERIMENTAL(a)  IP_EXPERIMENTAL(a)
+#define IN_BADCLASS(a)      IP_BADCLASS(a)
+
+#define IN_LOOPBACKNET      IP_LOOPBACKNET
+
+
+#ifndef INET_ADDRSTRLEN
+#define INET_ADDRSTRLEN     IP4ADDR_STRLEN_MAX
+#endif
+#if LWIP_IPV6
+#ifndef INET6_ADDRSTRLEN
+#define INET6_ADDRSTRLEN    IP6ADDR_STRLEN_MAX
+#endif
+#endif
+
+#if LWIP_IPV4
+
+#define inet_addr_from_ip4addr(target_inaddr, source_ipaddr) ((target_inaddr)->s_addr = ip4_addr_get_u32(source_ipaddr))
+#define inet_addr_to_ip4addr(target_ipaddr, source_inaddr)   (ip4_addr_set_u32(target_ipaddr, (source_inaddr)->s_addr))
+
+/* directly map this to the lwip internal functions */
+#define inet_addr(cp)                   ipaddr_addr(cp)
+#define inet_aton(cp, addr)             ip4addr_aton(cp, (ip4_addr_t*)addr)
+#define inet_ntoa(addr)                 ip4addr_ntoa((const ip4_addr_t*)&(addr))
+#define inet_ntoa_r(addr, buf, buflen)  ip4addr_ntoa_r((const ip4_addr_t*)&(addr), buf, buflen)
+
+#endif /* LWIP_IPV4 */
+
+#if LWIP_IPV6
+#define inet6_addr_from_ip6addr(target_in6addr, source_ip6addr) {(target_in6addr)->un.u32_addr[0] = (source_ip6addr)->addr[0]; \
+                                                                 (target_in6addr)->un.u32_addr[1] = (source_ip6addr)->addr[1]; \
+                                                                 (target_in6addr)->un.u32_addr[2] = (source_ip6addr)->addr[2]; \
+                                                                 (target_in6addr)->un.u32_addr[3] = (source_ip6addr)->addr[3];}
+#define inet6_addr_to_ip6addr(target_ip6addr, source_in6addr)   {(target_ip6addr)->addr[0] = (source_in6addr)->un.u32_addr[0]; \
+                                                                 (target_ip6addr)->addr[1] = (source_in6addr)->un.u32_addr[1]; \
+                                                                 (target_ip6addr)->addr[2] = (source_in6addr)->un.u32_addr[2]; \
+                                                                 (target_ip6addr)->addr[3] = (source_in6addr)->un.u32_addr[3]; \
+                                                                 ip6_addr_clear_zone(target_ip6addr);}
+
+/* directly map this to the lwip internal functions */
+#define inet6_aton(cp, addr)            ip6addr_aton(cp, (ip6_addr_t*)addr)
+#define inet6_ntoa(addr)                ip6addr_ntoa((const ip6_addr_t*)&(addr))
+#define inet6_ntoa_r(addr, buf, buflen) ip6addr_ntoa_r((const ip6_addr_t*)&(addr), buf, buflen)
+
+#endif /* LWIP_IPV6 */
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LWIP_HDR_INET_H */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/inet_chksum.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/inet_chksum.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/inet_chksum.h	(revision 457)
@@ -0,0 +1,105 @@
+/**
+ * @file
+ * IP checksum calculation functions
+ */
+
+/*
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Adam Dunkels <adam@sics.se>
+ *
+ */
+#ifndef LWIP_HDR_INET_CHKSUM_H
+#define LWIP_HDR_INET_CHKSUM_H
+
+#include "lwip/opt.h"
+
+#include "lwip/pbuf.h"
+#include "lwip/ip_addr.h"
+
+/** Swap the bytes in an u16_t: much like lwip_htons() for little-endian */
+#ifndef SWAP_BYTES_IN_WORD
+#define SWAP_BYTES_IN_WORD(w) (((w) & 0xff) << 8) | (((w) & 0xff00) >> 8)
+#endif /* SWAP_BYTES_IN_WORD */
+
+/** Split an u32_t in two u16_ts and add them up */
+#ifndef FOLD_U32T
+#define FOLD_U32T(u)          ((u32_t)(((u) >> 16) + ((u) & 0x0000ffffUL)))
+#endif
+
+#if LWIP_CHECKSUM_ON_COPY
+/** Function-like macro: same as MEMCPY but returns the checksum of copied data
+    as u16_t */
+# ifndef LWIP_CHKSUM_COPY
+#  define LWIP_CHKSUM_COPY(dst, src, len) lwip_chksum_copy(dst, src, len)
+#  ifndef LWIP_CHKSUM_COPY_ALGORITHM
+#   define LWIP_CHKSUM_COPY_ALGORITHM 1
+#  endif /* LWIP_CHKSUM_COPY_ALGORITHM */
+# else /* LWIP_CHKSUM_COPY */
+#  define LWIP_CHKSUM_COPY_ALGORITHM 0
+# endif /* LWIP_CHKSUM_COPY */
+#else /* LWIP_CHECKSUM_ON_COPY */
+# define LWIP_CHKSUM_COPY_ALGORITHM 0
+#endif /* LWIP_CHECKSUM_ON_COPY */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+u16_t inet_chksum(const void *dataptr, u16_t len);
+u16_t inet_chksum_pbuf(struct pbuf *p);
+#if LWIP_CHKSUM_COPY_ALGORITHM
+u16_t lwip_chksum_copy(void *dst, const void *src, u16_t len);
+#endif /* LWIP_CHKSUM_COPY_ALGORITHM */
+
+#if LWIP_IPV4
+u16_t inet_chksum_pseudo(struct pbuf *p, u8_t proto, u16_t proto_len,
+       const ip4_addr_t *src, const ip4_addr_t *dest);
+u16_t inet_chksum_pseudo_partial(struct pbuf *p, u8_t proto,
+       u16_t proto_len, u16_t chksum_len, const ip4_addr_t *src, const ip4_addr_t *dest);
+#endif /* LWIP_IPV4 */
+
+#if LWIP_IPV6
+u16_t ip6_chksum_pseudo(struct pbuf *p, u8_t proto, u16_t proto_len,
+       const ip6_addr_t *src, const ip6_addr_t *dest);
+u16_t ip6_chksum_pseudo_partial(struct pbuf *p, u8_t proto, u16_t proto_len,
+       u16_t chksum_len, const ip6_addr_t *src, const ip6_addr_t *dest);
+#endif /* LWIP_IPV6 */
+
+
+u16_t ip_chksum_pseudo(struct pbuf *p, u8_t proto, u16_t proto_len,
+       const ip_addr_t *src, const ip_addr_t *dest);
+u16_t ip_chksum_pseudo_partial(struct pbuf *p, u8_t proto, u16_t proto_len,
+       u16_t chksum_len, const ip_addr_t *src, const ip_addr_t *dest);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LWIP_HDR_INET_H */
+
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/init.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/init.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/init.h	(revision 457)
@@ -0,0 +1,100 @@
+/**
+ * @file
+ * lwIP initialization API
+ */
+
+/*
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Adam Dunkels <adam@sics.se>
+ *
+ */
+#ifndef LWIP_HDR_INIT_H
+#define LWIP_HDR_INIT_H
+
+#include "lwip/opt.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @defgroup lwip_version Version
+ * @ingroup lwip
+ * @{
+ */
+
+/** X.x.x: Major version of the stack */
+#define LWIP_VERSION_MAJOR      2
+/** x.X.x: Minor version of the stack */
+#define LWIP_VERSION_MINOR      1
+/** x.x.X: Revision of the stack */
+#define LWIP_VERSION_REVISION   2
+/** For release candidates, this is set to 1..254
+  * For official releases, this is set to 255 (LWIP_RC_RELEASE)
+  * For development versions (Git), this is set to 0 (LWIP_RC_DEVELOPMENT) */
+#define LWIP_VERSION_RC         LWIP_RC_RELEASE
+
+/** LWIP_VERSION_RC is set to LWIP_RC_RELEASE for official releases */
+#define LWIP_RC_RELEASE         255
+/** LWIP_VERSION_RC is set to LWIP_RC_DEVELOPMENT for Git versions */
+#define LWIP_RC_DEVELOPMENT     0
+
+#define LWIP_VERSION_IS_RELEASE     (LWIP_VERSION_RC == LWIP_RC_RELEASE)
+#define LWIP_VERSION_IS_DEVELOPMENT (LWIP_VERSION_RC == LWIP_RC_DEVELOPMENT)
+#define LWIP_VERSION_IS_RC          ((LWIP_VERSION_RC != LWIP_RC_RELEASE) && (LWIP_VERSION_RC != LWIP_RC_DEVELOPMENT))
+
+/* Some helper defines to get a version string */
+#define LWIP_VERSTR2(x) #x
+#define LWIP_VERSTR(x) LWIP_VERSTR2(x)
+#if LWIP_VERSION_IS_RELEASE
+#define LWIP_VERSION_STRING_SUFFIX ""
+#elif LWIP_VERSION_IS_DEVELOPMENT
+#define LWIP_VERSION_STRING_SUFFIX "d"
+#else
+#define LWIP_VERSION_STRING_SUFFIX "rc" LWIP_VERSTR(LWIP_VERSION_RC)
+#endif
+
+/** Provides the version of the stack */
+#define LWIP_VERSION   ((LWIP_VERSION_MAJOR) << 24   | (LWIP_VERSION_MINOR) << 16 | \
+                        (LWIP_VERSION_REVISION) << 8 | (LWIP_VERSION_RC))
+/** Provides the version of the stack as string */
+#define LWIP_VERSION_STRING     LWIP_VERSTR(LWIP_VERSION_MAJOR) "." LWIP_VERSTR(LWIP_VERSION_MINOR) "." LWIP_VERSTR(LWIP_VERSION_REVISION) LWIP_VERSION_STRING_SUFFIX
+
+/**
+ * @}
+ */
+
+/* Modules initialization */
+void lwip_init(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LWIP_HDR_INIT_H */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/init.h.cmake.in
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/init.h.cmake.in	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/init.h.cmake.in	(revision 457)
@@ -0,0 +1,100 @@
+/**
+ * @file
+ * lwIP initialization API
+ */
+
+/*
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Adam Dunkels <adam@sics.se>
+ *
+ */
+#ifndef LWIP_HDR_INIT_H
+#define LWIP_HDR_INIT_H
+
+#include "lwip/opt.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @defgroup lwip_version Version
+ * @ingroup lwip
+ * @{
+ */
+
+/** X.x.x: Major version of the stack */
+#define LWIP_VERSION_MAJOR      ${LWIP_VERSION_MAJOR}
+/** x.X.x: Minor version of the stack */
+#define LWIP_VERSION_MINOR      ${LWIP_VERSION_MINOR}
+/** x.x.X: Revision of the stack */
+#define LWIP_VERSION_REVISION   ${LWIP_VERSION_REVISION}
+/** For release candidates, this is set to 1..254
+  * For official releases, this is set to 255 (LWIP_RC_RELEASE)
+  * For development versions (Git), this is set to 0 (LWIP_RC_DEVELOPMENT) */
+#define LWIP_VERSION_RC         ${LWIP_VERSION_RC}
+
+/** LWIP_VERSION_RC is set to LWIP_RC_RELEASE for official releases */
+#define LWIP_RC_RELEASE         255
+/** LWIP_VERSION_RC is set to LWIP_RC_DEVELOPMENT for Git versions */
+#define LWIP_RC_DEVELOPMENT     0
+
+#define LWIP_VERSION_IS_RELEASE     (LWIP_VERSION_RC == LWIP_RC_RELEASE)
+#define LWIP_VERSION_IS_DEVELOPMENT (LWIP_VERSION_RC == LWIP_RC_DEVELOPMENT)
+#define LWIP_VERSION_IS_RC          ((LWIP_VERSION_RC != LWIP_RC_RELEASE) && (LWIP_VERSION_RC != LWIP_RC_DEVELOPMENT))
+
+/* Some helper defines to get a version string */
+#define LWIP_VERSTR2(x) #x
+#define LWIP_VERSTR(x) LWIP_VERSTR2(x)
+#if LWIP_VERSION_IS_RELEASE
+#define LWIP_VERSION_STRING_SUFFIX ""
+#elif LWIP_VERSION_IS_DEVELOPMENT
+#define LWIP_VERSION_STRING_SUFFIX "d"
+#else
+#define LWIP_VERSION_STRING_SUFFIX "rc" LWIP_VERSTR(LWIP_VERSION_RC)
+#endif
+
+/** Provides the version of the stack */
+#define LWIP_VERSION   ((LWIP_VERSION_MAJOR) << 24   | (LWIP_VERSION_MINOR) << 16 | \
+                        (LWIP_VERSION_REVISION) << 8 | (LWIP_VERSION_RC))
+/** Provides the version of the stack as string */
+#define LWIP_VERSION_STRING     LWIP_VERSTR(LWIP_VERSION_MAJOR) "." LWIP_VERSTR(LWIP_VERSION_MINOR) "." LWIP_VERSTR(LWIP_VERSION_REVISION) LWIP_VERSION_STRING_SUFFIX
+
+/**
+ * @}
+ */
+
+/* Modules initialization */
+void lwip_init(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LWIP_HDR_INIT_H */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/ip.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/ip.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/ip.h	(revision 457)
@@ -0,0 +1,330 @@
+/**
+ * @file
+ * IP API
+ */
+
+/*
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Adam Dunkels <adam@sics.se>
+ *
+ */
+#ifndef LWIP_HDR_IP_H
+#define LWIP_HDR_IP_H
+
+#include "lwip/opt.h"
+
+#include "lwip/def.h"
+#include "lwip/pbuf.h"
+#include "lwip/ip_addr.h"
+#include "lwip/err.h"
+#include "lwip/netif.h"
+#include "lwip/ip4.h"
+#include "lwip/ip6.h"
+#include "lwip/prot/ip.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* This is passed as the destination address to ip_output_if (not
+   to ip_output), meaning that an IP header already is constructed
+   in the pbuf. This is used when TCP retransmits. */
+#define LWIP_IP_HDRINCL  NULL
+
+/** pbufs passed to IP must have a ref-count of 1 as their payload pointer
+    gets altered as the packet is passed down the stack */
+#ifndef LWIP_IP_CHECK_PBUF_REF_COUNT_FOR_TX
+#define LWIP_IP_CHECK_PBUF_REF_COUNT_FOR_TX(p) LWIP_ASSERT("p->ref == 1", (p)->ref == 1)
+#endif
+
+#if LWIP_NETIF_USE_HINTS
+#define IP_PCB_NETIFHINT ;struct netif_hint netif_hints
+#else /* LWIP_NETIF_USE_HINTS */
+#define IP_PCB_NETIFHINT
+#endif /* LWIP_NETIF_USE_HINTS */
+
+/** This is the common part of all PCB types. It needs to be at the
+   beginning of a PCB type definition. It is located here so that
+   changes to this common part are made in one location instead of
+   having to change all PCB structs. */
+#define IP_PCB                             \
+  /* ip addresses in network byte order */ \
+  ip_addr_t local_ip;                      \
+  ip_addr_t remote_ip;                     \
+  /* Bound netif index */                  \
+  u8_t netif_idx;                          \
+  /* Socket options */                     \
+  u8_t so_options;                         \
+  /* Type Of Service */                    \
+  u8_t tos;                                \
+  /* Time To Live */                       \
+  u8_t ttl                                 \
+  /* link layer address resolution hint */ \
+  IP_PCB_NETIFHINT
+
+struct ip_pcb {
+  /* Common members of all PCB types */
+  IP_PCB;
+};
+
+/*
+ * Option flags per-socket. These are the same like SO_XXX in sockets.h
+ */
+#define SOF_REUSEADDR     0x04U  /* allow local address reuse */
+#define SOF_KEEPALIVE     0x08U  /* keep connections alive */
+#define SOF_BROADCAST     0x20U  /* permit to send and to receive broadcast messages (see IP_SOF_BROADCAST option) */
+
+/* These flags are inherited (e.g. from a listen-pcb to a connection-pcb): */
+#define SOF_INHERITED   (SOF_REUSEADDR|SOF_KEEPALIVE)
+
+/** Global variables of this module, kept in a struct for efficient access using base+index. */
+struct ip_globals
+{
+  /** The interface that accepted the packet for the current callback invocation. */
+  struct netif *current_netif;
+  /** The interface that received the packet for the current callback invocation. */
+  struct netif *current_input_netif;
+#if LWIP_IPV4
+  /** Header of the input packet currently being processed. */
+  const struct ip_hdr *current_ip4_header;
+#endif /* LWIP_IPV4 */
+#if LWIP_IPV6
+  /** Header of the input IPv6 packet currently being processed. */
+  struct ip6_hdr *current_ip6_header;
+#endif /* LWIP_IPV6 */
+  /** Total header length of current_ip4/6_header (i.e. after this, the UDP/TCP header starts) */
+  u16_t current_ip_header_tot_len;
+  /** Source IP address of current_header */
+  ip_addr_t current_iphdr_src;
+  /** Destination IP address of current_header */
+  ip_addr_t current_iphdr_dest;
+};
+extern struct ip_globals ip_data;
+
+
+/** Get the interface that accepted the current packet.
+ * This may or may not be the receiving netif, depending on your netif/network setup.
+ * This function must only be called from a receive callback (udp_recv,
+ * raw_recv, tcp_accept). It will return NULL otherwise. */
+#define ip_current_netif()      (ip_data.current_netif)
+/** Get the interface that received the current packet.
+ * This function must only be called from a receive callback (udp_recv,
+ * raw_recv, tcp_accept). It will return NULL otherwise. */
+#define ip_current_input_netif() (ip_data.current_input_netif)
+/** Total header length of ip(6)_current_header() (i.e. after this, the UDP/TCP header starts) */
+#define ip_current_header_tot_len() (ip_data.current_ip_header_tot_len)
+/** Source IP address of current_header */
+#define ip_current_src_addr()   (&ip_data.current_iphdr_src)
+/** Destination IP address of current_header */
+#define ip_current_dest_addr()  (&ip_data.current_iphdr_dest)
+
+#if LWIP_IPV4 && LWIP_IPV6
+/** Get the IPv4 header of the current packet.
+ * This function must only be called from a receive callback (udp_recv,
+ * raw_recv, tcp_accept). It will return NULL otherwise. */
+#define ip4_current_header()     ip_data.current_ip4_header
+/** Get the IPv6 header of the current packet.
+ * This function must only be called from a receive callback (udp_recv,
+ * raw_recv, tcp_accept). It will return NULL otherwise. */
+#define ip6_current_header()      ((const struct ip6_hdr*)(ip_data.current_ip6_header))
+/** Returns TRUE if the current IP input packet is IPv6, FALSE if it is IPv4 */
+#define ip_current_is_v6()        (ip6_current_header() != NULL)
+/** Source IPv6 address of current_header */
+#define ip6_current_src_addr()    (ip_2_ip6(&ip_data.current_iphdr_src))
+/** Destination IPv6 address of current_header */
+#define ip6_current_dest_addr()   (ip_2_ip6(&ip_data.current_iphdr_dest))
+/** Get the transport layer protocol */
+#define ip_current_header_proto() (ip_current_is_v6() ? \
+                                   IP6H_NEXTH(ip6_current_header()) :\
+                                   IPH_PROTO(ip4_current_header()))
+/** Get the transport layer header */
+#define ip_next_header_ptr()     ((const void*)((ip_current_is_v6() ? \
+  (const u8_t*)ip6_current_header() : (const u8_t*)ip4_current_header())  + ip_current_header_tot_len()))
+
+/** Source IP4 address of current_header */
+#define ip4_current_src_addr()     (ip_2_ip4(&ip_data.current_iphdr_src))
+/** Destination IP4 address of current_header */
+#define ip4_current_dest_addr()    (ip_2_ip4(&ip_data.current_iphdr_dest))
+
+#elif LWIP_IPV4 /* LWIP_IPV4 && LWIP_IPV6 */
+
+/** Get the IPv4 header of the current packet.
+ * This function must only be called from a receive callback (udp_recv,
+ * raw_recv, tcp_accept). It will return NULL otherwise. */
+#define ip4_current_header()     ip_data.current_ip4_header
+/** Always returns FALSE when only supporting IPv4 only */
+#define ip_current_is_v6()        0
+/** Get the transport layer protocol */
+#define ip_current_header_proto() IPH_PROTO(ip4_current_header())
+/** Get the transport layer header */
+#define ip_next_header_ptr()     ((const void*)((const u8_t*)ip4_current_header() + ip_current_header_tot_len()))
+/** Source IP4 address of current_header */
+#define ip4_current_src_addr()     (&ip_data.current_iphdr_src)
+/** Destination IP4 address of current_header */
+#define ip4_current_dest_addr()    (&ip_data.current_iphdr_dest)
+
+#elif LWIP_IPV6 /* LWIP_IPV4 && LWIP_IPV6 */
+
+/** Get the IPv6 header of the current packet.
+ * This function must only be called from a receive callback (udp_recv,
+ * raw_recv, tcp_accept). It will return NULL otherwise. */
+#define ip6_current_header()      ((const struct ip6_hdr*)(ip_data.current_ip6_header))
+/** Always returns TRUE when only supporting IPv6 only */
+#define ip_current_is_v6()        1
+/** Get the transport layer protocol */
+#define ip_current_header_proto() IP6H_NEXTH(ip6_current_header())
+/** Get the transport layer header */
+#define ip_next_header_ptr()     ((const void*)(((const u8_t*)ip6_current_header()) + ip_current_header_tot_len()))
+/** Source IP6 address of current_header */
+#define ip6_current_src_addr()    (&ip_data.current_iphdr_src)
+/** Destination IP6 address of current_header */
+#define ip6_current_dest_addr()   (&ip_data.current_iphdr_dest)
+
+#endif /* LWIP_IPV6 */
+
+/** Union source address of current_header */
+#define ip_current_src_addr()    (&ip_data.current_iphdr_src)
+/** Union destination address of current_header */
+#define ip_current_dest_addr()   (&ip_data.current_iphdr_dest)
+
+/** Gets an IP pcb option (SOF_* flags) */
+#define ip_get_option(pcb, opt)   ((pcb)->so_options & (opt))
+/** Sets an IP pcb option (SOF_* flags) */
+#define ip_set_option(pcb, opt)   ((pcb)->so_options = (u8_t)((pcb)->so_options | (opt)))
+/** Resets an IP pcb option (SOF_* flags) */
+#define ip_reset_option(pcb, opt) ((pcb)->so_options = (u8_t)((pcb)->so_options & ~(opt)))
+
+#if LWIP_IPV4 && LWIP_IPV6
+/**
+ * @ingroup ip
+ * Output IP packet, netif is selected by source address
+ */
+#define ip_output(p, src, dest, ttl, tos, proto) \
+        (IP_IS_V6(dest) ? \
+        ip6_output(p, ip_2_ip6(src), ip_2_ip6(dest), ttl, tos, proto) : \
+        ip4_output(p, ip_2_ip4(src), ip_2_ip4(dest), ttl, tos, proto))
+/**
+ * @ingroup ip
+ * Output IP packet to specified interface
+ */
+#define ip_output_if(p, src, dest, ttl, tos, proto, netif) \
+        (IP_IS_V6(dest) ? \
+        ip6_output_if(p, ip_2_ip6(src), ip_2_ip6(dest), ttl, tos, proto, netif) : \
+        ip4_output_if(p, ip_2_ip4(src), ip_2_ip4(dest), ttl, tos, proto, netif))
+/**
+ * @ingroup ip
+ * Output IP packet to interface specifying source address
+ */
+#define ip_output_if_src(p, src, dest, ttl, tos, proto, netif) \
+        (IP_IS_V6(dest) ? \
+        ip6_output_if_src(p, ip_2_ip6(src), ip_2_ip6(dest), ttl, tos, proto, netif) : \
+        ip4_output_if_src(p, ip_2_ip4(src), ip_2_ip4(dest), ttl, tos, proto, netif))
+/** Output IP packet that already includes an IP header. */
+#define ip_output_if_hdrincl(p, src, dest, netif) \
+        (IP_IS_V6(dest) ? \
+        ip6_output_if(p, ip_2_ip6(src), LWIP_IP_HDRINCL, 0, 0, 0, netif) : \
+        ip4_output_if(p, ip_2_ip4(src), LWIP_IP_HDRINCL, 0, 0, 0, netif))
+/** Output IP packet with netif_hint */
+#define ip_output_hinted(p, src, dest, ttl, tos, proto, netif_hint) \
+        (IP_IS_V6(dest) ? \
+        ip6_output_hinted(p, ip_2_ip6(src), ip_2_ip6(dest), ttl, tos, proto, netif_hint) : \
+        ip4_output_hinted(p, ip_2_ip4(src), ip_2_ip4(dest), ttl, tos, proto, netif_hint))
+/**
+ * @ingroup ip
+ * Get netif for address combination. See \ref ip6_route and \ref ip4_route
+ */
+#define ip_route(src, dest) \
+        (IP_IS_V6(dest) ? \
+        ip6_route(ip_2_ip6(src), ip_2_ip6(dest)) : \
+        ip4_route_src(ip_2_ip4(src), ip_2_ip4(dest)))
+/**
+ * @ingroup ip
+ * Get netif for IP.
+ */
+#define ip_netif_get_local_ip(netif, dest) (IP_IS_V6(dest) ? \
+        ip6_netif_get_local_ip(netif, ip_2_ip6(dest)) : \
+        ip4_netif_get_local_ip(netif))
+#define ip_debug_print(is_ipv6, p) ((is_ipv6) ? ip6_debug_print(p) : ip4_debug_print(p))
+
+err_t ip_input(struct pbuf *p, struct netif *inp);
+
+#elif LWIP_IPV4 /* LWIP_IPV4 && LWIP_IPV6 */
+
+#define ip_output(p, src, dest, ttl, tos, proto) \
+        ip4_output(p, src, dest, ttl, tos, proto)
+#define ip_output_if(p, src, dest, ttl, tos, proto, netif) \
+        ip4_output_if(p, src, dest, ttl, tos, proto, netif)
+#define ip_output_if_src(p, src, dest, ttl, tos, proto, netif) \
+        ip4_output_if_src(p, src, dest, ttl, tos, proto, netif)
+#define ip_output_hinted(p, src, dest, ttl, tos, proto, netif_hint) \
+        ip4_output_hinted(p, src, dest, ttl, tos, proto, netif_hint)
+#define ip_output_if_hdrincl(p, src, dest, netif) \
+        ip4_output_if(p, src, LWIP_IP_HDRINCL, 0, 0, 0, netif)
+#define ip_route(src, dest) \
+        ip4_route_src(src, dest)
+#define ip_netif_get_local_ip(netif, dest) \
+        ip4_netif_get_local_ip(netif)
+#define ip_debug_print(is_ipv6, p) ip4_debug_print(p)
+
+#define ip_input ip4_input
+
+#elif LWIP_IPV6 /* LWIP_IPV4 && LWIP_IPV6 */
+
+#define ip_output(p, src, dest, ttl, tos, proto) \
+        ip6_output(p, src, dest, ttl, tos, proto)
+#define ip_output_if(p, src, dest, ttl, tos, proto, netif) \
+        ip6_output_if(p, src, dest, ttl, tos, proto, netif)
+#define ip_output_if_src(p, src, dest, ttl, tos, proto, netif) \
+        ip6_output_if_src(p, src, dest, ttl, tos, proto, netif)
+#define ip_output_hinted(p, src, dest, ttl, tos, proto, netif_hint) \
+        ip6_output_hinted(p, src, dest, ttl, tos, proto, netif_hint)
+#define ip_output_if_hdrincl(p, src, dest, netif) \
+        ip6_output_if(p, src, LWIP_IP_HDRINCL, 0, 0, 0, netif)
+#define ip_route(src, dest) \
+        ip6_route(src, dest)
+#define ip_netif_get_local_ip(netif, dest) \
+        ip6_netif_get_local_ip(netif, dest)
+#define ip_debug_print(is_ipv6, p) ip6_debug_print(p)
+
+#define ip_input ip6_input
+
+#endif /* LWIP_IPV6 */
+
+#define ip_route_get_local_ip(src, dest, netif, ipaddr) do { \
+  (netif) = ip_route(src, dest); \
+  (ipaddr) = ip_netif_get_local_ip(netif, dest); \
+}while(0)
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LWIP_HDR_IP_H */
+
+
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/ip4.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/ip4.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/ip4.h	(revision 457)
@@ -0,0 +1,111 @@
+/**
+ * @file
+ * IPv4 API
+ */
+
+/*
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Adam Dunkels <adam@sics.se>
+ *
+ */
+#ifndef LWIP_HDR_IP4_H
+#define LWIP_HDR_IP4_H
+
+#include "lwip/opt.h"
+
+#if LWIP_IPV4
+
+#include "lwip/def.h"
+#include "lwip/pbuf.h"
+#include "lwip/ip4_addr.h"
+#include "lwip/err.h"
+#include "lwip/netif.h"
+#include "lwip/prot/ip4.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef LWIP_HOOK_IP4_ROUTE_SRC
+#define LWIP_IPV4_SRC_ROUTING   1
+#else
+#define LWIP_IPV4_SRC_ROUTING   0
+#endif
+
+/** Currently, the function ip_output_if_opt() is only used with IGMP */
+#define IP_OPTIONS_SEND   (LWIP_IPV4 && LWIP_IGMP)
+
+#define ip_init() /* Compatibility define, no init needed. */
+struct netif *ip4_route(const ip4_addr_t *dest);
+#if LWIP_IPV4_SRC_ROUTING
+struct netif *ip4_route_src(const ip4_addr_t *src, const ip4_addr_t *dest);
+#else /* LWIP_IPV4_SRC_ROUTING */
+#define ip4_route_src(src, dest) ip4_route(dest)
+#endif /* LWIP_IPV4_SRC_ROUTING */
+err_t ip4_input(struct pbuf *p, struct netif *inp);
+err_t ip4_output(struct pbuf *p, const ip4_addr_t *src, const ip4_addr_t *dest,
+       u8_t ttl, u8_t tos, u8_t proto);
+err_t ip4_output_if(struct pbuf *p, const ip4_addr_t *src, const ip4_addr_t *dest,
+       u8_t ttl, u8_t tos, u8_t proto, struct netif *netif);
+err_t ip4_output_if_src(struct pbuf *p, const ip4_addr_t *src, const ip4_addr_t *dest,
+       u8_t ttl, u8_t tos, u8_t proto, struct netif *netif);
+#if LWIP_NETIF_USE_HINTS
+err_t ip4_output_hinted(struct pbuf *p, const ip4_addr_t *src, const ip4_addr_t *dest,
+       u8_t ttl, u8_t tos, u8_t proto, struct netif_hint *netif_hint);
+#endif /* LWIP_NETIF_USE_HINTS */
+#if IP_OPTIONS_SEND
+err_t ip4_output_if_opt(struct pbuf *p, const ip4_addr_t *src, const ip4_addr_t *dest,
+       u8_t ttl, u8_t tos, u8_t proto, struct netif *netif, void *ip_options,
+       u16_t optlen);
+err_t ip4_output_if_opt_src(struct pbuf *p, const ip4_addr_t *src, const ip4_addr_t *dest,
+       u8_t ttl, u8_t tos, u8_t proto, struct netif *netif, void *ip_options,
+       u16_t optlen);
+#endif /* IP_OPTIONS_SEND */
+
+#if LWIP_MULTICAST_TX_OPTIONS
+void  ip4_set_default_multicast_netif(struct netif* default_multicast_netif);
+#endif /* LWIP_MULTICAST_TX_OPTIONS */
+
+#define ip4_netif_get_local_ip(netif) (((netif) != NULL) ? netif_ip_addr4(netif) : NULL)
+
+#if IP_DEBUG
+void ip4_debug_print(struct pbuf *p);
+#else
+#define ip4_debug_print(p)
+#endif /* IP_DEBUG */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LWIP_IPV4 */
+
+#endif /* LWIP_HDR_IP_H */
+
+
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/ip4_addr.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/ip4_addr.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/ip4_addr.h	(revision 457)
@@ -0,0 +1,216 @@
+/**
+ * @file
+ * IPv4 address API
+ */
+
+/*
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Adam Dunkels <adam@sics.se>
+ *
+ */
+#ifndef LWIP_HDR_IP4_ADDR_H
+#define LWIP_HDR_IP4_ADDR_H
+
+#include "lwip/opt.h"
+#include "lwip/def.h"
+
+#if LWIP_IPV4
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** This is the aligned version of ip4_addr_t,
+   used as local variable, on the stack, etc. */
+struct ip4_addr {
+  u32_t addr;
+};
+
+/** ip4_addr_t uses a struct for convenience only, so that the same defines can
+ * operate both on ip4_addr_t as well as on ip4_addr_p_t. */
+typedef struct ip4_addr ip4_addr_t;
+
+/* Forward declaration to not include netif.h */
+struct netif;
+
+/** 255.255.255.255 */
+#define IPADDR_NONE         ((u32_t)0xffffffffUL)
+/** 127.0.0.1 */
+#define IPADDR_LOOPBACK     ((u32_t)0x7f000001UL)
+/** 0.0.0.0 */
+#define IPADDR_ANY          ((u32_t)0x00000000UL)
+/** 255.255.255.255 */
+#define IPADDR_BROADCAST    ((u32_t)0xffffffffUL)
+
+/* Definitions of the bits in an Internet address integer.
+
+   On subnets, host and network parts are found according to
+   the subnet mask, not these masks.  */
+#define IP_CLASSA(a)        ((((u32_t)(a)) & 0x80000000UL) == 0)
+#define IP_CLASSA_NET       0xff000000
+#define IP_CLASSA_NSHIFT    24
+#define IP_CLASSA_HOST      (0xffffffff & ~IP_CLASSA_NET)
+#define IP_CLASSA_MAX       128
+
+#define IP_CLASSB(a)        ((((u32_t)(a)) & 0xc0000000UL) == 0x80000000UL)
+#define IP_CLASSB_NET       0xffff0000
+#define IP_CLASSB_NSHIFT    16
+#define IP_CLASSB_HOST      (0xffffffff & ~IP_CLASSB_NET)
+#define IP_CLASSB_MAX       65536
+
+#define IP_CLASSC(a)        ((((u32_t)(a)) & 0xe0000000UL) == 0xc0000000UL)
+#define IP_CLASSC_NET       0xffffff00
+#define IP_CLASSC_NSHIFT    8
+#define IP_CLASSC_HOST      (0xffffffff & ~IP_CLASSC_NET)
+
+#define IP_CLASSD(a)        (((u32_t)(a) & 0xf0000000UL) == 0xe0000000UL)
+#define IP_CLASSD_NET       0xf0000000          /* These ones aren't really */
+#define IP_CLASSD_NSHIFT    28                  /*   net and host fields, but */
+#define IP_CLASSD_HOST      0x0fffffff          /*   routing needn't know. */
+#define IP_MULTICAST(a)     IP_CLASSD(a)
+
+#define IP_EXPERIMENTAL(a)  (((u32_t)(a) & 0xf0000000UL) == 0xf0000000UL)
+#define IP_BADCLASS(a)      (((u32_t)(a) & 0xf0000000UL) == 0xf0000000UL)
+
+#define IP_LOOPBACKNET      127                 /* official! */
+
+/** Set an IP address given by the four byte-parts */
+#define IP4_ADDR(ipaddr, a,b,c,d)  (ipaddr)->addr = PP_HTONL(LWIP_MAKEU32(a,b,c,d))
+
+/** Copy IP address - faster than ip4_addr_set: no NULL check */
+#define ip4_addr_copy(dest, src) MEMCPY(&((dest).addr), &((src).addr), 4)
+/** Safely copy one IP address to another (src may be NULL) */
+#define ip4_addr_set(dest, src) ((dest)->addr = \
+                                    ((src) == NULL ? 0 : \
+                                    (src)->addr))
+/** Set complete address to zero */
+#define ip4_addr_set_zero(ipaddr)     ((ipaddr)->addr = 0)
+/** Set address to IPADDR_ANY (no need for lwip_htonl()) */
+#define ip4_addr_set_any(ipaddr)      ((ipaddr)->addr = IPADDR_ANY)
+/** Set address to loopback address */
+#define ip4_addr_set_loopback(ipaddr) ((ipaddr)->addr = PP_HTONL(IPADDR_LOOPBACK))
+/** Check if an address is in the loopback region */
+#define ip4_addr_isloopback(ipaddr)    (((ipaddr)->addr & PP_HTONL(IP_CLASSA_NET)) == PP_HTONL(((u32_t)IP_LOOPBACKNET) << 24))
+/** Safely copy one IP address to another and change byte order
+ * from host- to network-order. */
+#define ip4_addr_set_hton(dest, src) ((dest)->addr = \
+                               ((src) == NULL ? 0:\
+                               lwip_htonl((src)->addr)))
+/** IPv4 only: set the IP address given as an u32_t */
+#define ip4_addr_set_u32(dest_ipaddr, src_u32) ((dest_ipaddr)->addr = (src_u32))
+/** IPv4 only: get the IP address as an u32_t */
+#define ip4_addr_get_u32(src_ipaddr) ((src_ipaddr)->addr)
+
+/** Get the network address by combining host address with netmask */
+#define ip4_addr_get_network(target, host, netmask) do { ((target)->addr = ((host)->addr) & ((netmask)->addr)); } while(0)
+
+/**
+ * Determine if two address are on the same network.
+ *
+ * @arg addr1 IP address 1
+ * @arg addr2 IP address 2
+ * @arg mask network identifier mask
+ * @return !0 if the network identifiers of both address match
+ */
+#define ip4_addr_netcmp(addr1, addr2, mask) (((addr1)->addr & \
+                                              (mask)->addr) == \
+                                             ((addr2)->addr & \
+                                              (mask)->addr))
+#define ip4_addr_cmp(addr1, addr2) ((addr1)->addr == (addr2)->addr)
+
+#define ip4_addr_isany_val(addr1)   ((addr1).addr == IPADDR_ANY)
+#define ip4_addr_isany(addr1) ((addr1) == NULL || ip4_addr_isany_val(*(addr1)))
+
+#define ip4_addr_isbroadcast(addr1, netif) ip4_addr_isbroadcast_u32((addr1)->addr, netif)
+u8_t ip4_addr_isbroadcast_u32(u32_t addr, const struct netif *netif);
+
+#define ip_addr_netmask_valid(netmask) ip4_addr_netmask_valid((netmask)->addr)
+u8_t ip4_addr_netmask_valid(u32_t netmask);
+
+#define ip4_addr_ismulticast(addr1) (((addr1)->addr & PP_HTONL(0xf0000000UL)) == PP_HTONL(0xe0000000UL))
+
+#define ip4_addr_islinklocal(addr1) (((addr1)->addr & PP_HTONL(0xffff0000UL)) == PP_HTONL(0xa9fe0000UL))
+
+#define ip4_addr_debug_print_parts(debug, a, b, c, d) \
+  LWIP_DEBUGF(debug, ("%" U16_F ".%" U16_F ".%" U16_F ".%" U16_F, a, b, c, d))
+#define ip4_addr_debug_print(debug, ipaddr) \
+  ip4_addr_debug_print_parts(debug, \
+                      (u16_t)((ipaddr) != NULL ? ip4_addr1_16(ipaddr) : 0),       \
+                      (u16_t)((ipaddr) != NULL ? ip4_addr2_16(ipaddr) : 0),       \
+                      (u16_t)((ipaddr) != NULL ? ip4_addr3_16(ipaddr) : 0),       \
+                      (u16_t)((ipaddr) != NULL ? ip4_addr4_16(ipaddr) : 0))
+#define ip4_addr_debug_print_val(debug, ipaddr) \
+  ip4_addr_debug_print_parts(debug, \
+                      ip4_addr1_16_val(ipaddr),       \
+                      ip4_addr2_16_val(ipaddr),       \
+                      ip4_addr3_16_val(ipaddr),       \
+                      ip4_addr4_16_val(ipaddr))
+
+/* Get one byte from the 4-byte address */
+#define ip4_addr_get_byte(ipaddr, idx) (((const u8_t*)(&(ipaddr)->addr))[idx])
+#define ip4_addr1(ipaddr) ip4_addr_get_byte(ipaddr, 0)
+#define ip4_addr2(ipaddr) ip4_addr_get_byte(ipaddr, 1)
+#define ip4_addr3(ipaddr) ip4_addr_get_byte(ipaddr, 2)
+#define ip4_addr4(ipaddr) ip4_addr_get_byte(ipaddr, 3)
+/* Get one byte from the 4-byte address, but argument is 'ip4_addr_t',
+ * not a pointer */
+#define ip4_addr_get_byte_val(ipaddr, idx) ((u8_t)(((ipaddr).addr >> (idx * 8)) & 0xff))
+#define ip4_addr1_val(ipaddr) ip4_addr_get_byte_val(ipaddr, 0)
+#define ip4_addr2_val(ipaddr) ip4_addr_get_byte_val(ipaddr, 1)
+#define ip4_addr3_val(ipaddr) ip4_addr_get_byte_val(ipaddr, 2)
+#define ip4_addr4_val(ipaddr) ip4_addr_get_byte_val(ipaddr, 3)
+/* These are cast to u16_t, with the intent that they are often arguments
+ * to printf using the U16_F format from cc.h. */
+#define ip4_addr1_16(ipaddr) ((u16_t)ip4_addr1(ipaddr))
+#define ip4_addr2_16(ipaddr) ((u16_t)ip4_addr2(ipaddr))
+#define ip4_addr3_16(ipaddr) ((u16_t)ip4_addr3(ipaddr))
+#define ip4_addr4_16(ipaddr) ((u16_t)ip4_addr4(ipaddr))
+#define ip4_addr1_16_val(ipaddr) ((u16_t)ip4_addr1_val(ipaddr))
+#define ip4_addr2_16_val(ipaddr) ((u16_t)ip4_addr2_val(ipaddr))
+#define ip4_addr3_16_val(ipaddr) ((u16_t)ip4_addr3_val(ipaddr))
+#define ip4_addr4_16_val(ipaddr) ((u16_t)ip4_addr4_val(ipaddr))
+
+#define IP4ADDR_STRLEN_MAX  16
+
+/** For backwards compatibility */
+#define ip_ntoa(ipaddr)  ipaddr_ntoa(ipaddr)
+
+u32_t ipaddr_addr(const char *cp);
+int ip4addr_aton(const char *cp, ip4_addr_t *addr);
+/** returns ptr to static buffer; not reentrant! */
+char *ip4addr_ntoa(const ip4_addr_t *addr);
+char *ip4addr_ntoa_r(const ip4_addr_t *addr, char *buf, int buflen);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LWIP_IPV4 */
+
+#endif /* LWIP_HDR_IP_ADDR_H */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/ip4_frag.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/ip4_frag.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/ip4_frag.h	(revision 457)
@@ -0,0 +1,100 @@
+/**
+ * @file
+ * IP fragmentation/reassembly
+ */
+
+/*
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Jani Monoses <jani@iv.ro>
+ *
+ */
+
+#ifndef LWIP_HDR_IP4_FRAG_H
+#define LWIP_HDR_IP4_FRAG_H
+
+#include "lwip/opt.h"
+#include "lwip/err.h"
+#include "lwip/pbuf.h"
+#include "lwip/netif.h"
+#include "lwip/ip_addr.h"
+#include "lwip/ip.h"
+
+#if LWIP_IPV4
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if IP_REASSEMBLY
+/* The IP reassembly timer interval in milliseconds. */
+#define IP_TMR_INTERVAL 1000
+
+/** IP reassembly helper struct.
+ * This is exported because memp needs to know the size.
+ */
+struct ip_reassdata {
+  struct ip_reassdata *next;
+  struct pbuf *p;
+  struct ip_hdr iphdr;
+  u16_t datagram_len;
+  u8_t flags;
+  u8_t timer;
+};
+
+void ip_reass_init(void);
+void ip_reass_tmr(void);
+struct pbuf * ip4_reass(struct pbuf *p);
+#endif /* IP_REASSEMBLY */
+
+#if IP_FRAG
+#if !LWIP_NETIF_TX_SINGLE_PBUF
+#ifndef LWIP_PBUF_CUSTOM_REF_DEFINED
+#define LWIP_PBUF_CUSTOM_REF_DEFINED
+/** A custom pbuf that holds a reference to another pbuf, which is freed
+ * when this custom pbuf is freed. This is used to create a custom PBUF_REF
+ * that points into the original pbuf. */
+struct pbuf_custom_ref {
+  /** 'base class' */
+  struct pbuf_custom pc;
+  /** pointer to the original pbuf that is referenced */
+  struct pbuf *original;
+};
+#endif /* LWIP_PBUF_CUSTOM_REF_DEFINED */
+#endif /* !LWIP_NETIF_TX_SINGLE_PBUF */
+
+err_t ip4_frag(struct pbuf *p, struct netif *netif, const ip4_addr_t *dest);
+#endif /* IP_FRAG */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LWIP_IPV4 */
+
+#endif /* LWIP_HDR_IP4_FRAG_H */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/ip6.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/ip6.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/ip6.h	(revision 457)
@@ -0,0 +1,93 @@
+/**
+ * @file
+ *
+ * IPv6 layer.
+ */
+
+/*
+ * Copyright (c) 2010 Inico Technologies Ltd.
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Ivan Delamer <delamer@inicotech.com>
+ *
+ *
+ * Please coordinate changes and requests with Ivan Delamer
+ * <delamer@inicotech.com>
+ */
+#ifndef LWIP_HDR_IP6_H
+#define LWIP_HDR_IP6_H
+
+#include "lwip/opt.h"
+
+#if LWIP_IPV6  /* don't build if not configured for use in lwipopts.h */
+
+#include "lwip/ip6_addr.h"
+#include "lwip/prot/ip6.h"
+#include "lwip/def.h"
+#include "lwip/pbuf.h"
+#include "lwip/netif.h"
+
+#include "lwip/err.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct netif *ip6_route(const ip6_addr_t *src, const ip6_addr_t *dest);
+const ip_addr_t *ip6_select_source_address(struct netif *netif, const ip6_addr_t * dest);
+err_t         ip6_input(struct pbuf *p, struct netif *inp);
+err_t         ip6_output(struct pbuf *p, const ip6_addr_t *src, const ip6_addr_t *dest,
+                         u8_t hl, u8_t tc, u8_t nexth);
+err_t         ip6_output_if(struct pbuf *p, const ip6_addr_t *src, const ip6_addr_t *dest,
+                            u8_t hl, u8_t tc, u8_t nexth, struct netif *netif);
+err_t         ip6_output_if_src(struct pbuf *p, const ip6_addr_t *src, const ip6_addr_t *dest,
+                            u8_t hl, u8_t tc, u8_t nexth, struct netif *netif);
+#if LWIP_NETIF_USE_HINTS
+err_t         ip6_output_hinted(struct pbuf *p, const ip6_addr_t *src, const ip6_addr_t *dest,
+                                u8_t hl, u8_t tc, u8_t nexth, struct netif_hint *netif_hint);
+#endif /* LWIP_NETIF_USE_HINTS */
+#if LWIP_IPV6_MLD
+err_t         ip6_options_add_hbh_ra(struct pbuf * p, u8_t nexth, u8_t value);
+#endif /* LWIP_IPV6_MLD */
+
+#define ip6_netif_get_local_ip(netif, dest) (((netif) != NULL) ? \
+  ip6_select_source_address(netif, dest) : NULL)
+
+#if IP6_DEBUG
+void ip6_debug_print(struct pbuf *p);
+#else
+#define ip6_debug_print(p)
+#endif /* IP6_DEBUG */
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LWIP_IPV6 */
+
+#endif /* LWIP_HDR_IP6_H */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/ip6_addr.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/ip6_addr.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/ip6_addr.h	(revision 457)
@@ -0,0 +1,352 @@
+/**
+ * @file
+ *
+ * IPv6 addresses.
+ */
+
+/*
+ * Copyright (c) 2010 Inico Technologies Ltd.
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Ivan Delamer <delamer@inicotech.com>
+ *
+ * Structs and macros for handling IPv6 addresses.
+ *
+ * Please coordinate changes and requests with Ivan Delamer
+ * <delamer@inicotech.com>
+ */
+#ifndef LWIP_HDR_IP6_ADDR_H
+#define LWIP_HDR_IP6_ADDR_H
+
+#include "lwip/opt.h"
+#include "def.h"
+
+#if LWIP_IPV6  /* don't build if not configured for use in lwipopts.h */
+
+#include "lwip/ip6_zone.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/** This is the aligned version of ip6_addr_t,
+    used as local variable, on the stack, etc. */
+struct ip6_addr {
+  u32_t addr[4];
+#if LWIP_IPV6_SCOPES
+  u8_t zone;
+#endif /* LWIP_IPV6_SCOPES */
+};
+
+/** IPv6 address */
+typedef struct ip6_addr ip6_addr_t;
+
+/** Set an IPv6 partial address given by byte-parts */
+#define IP6_ADDR_PART(ip6addr, index, a,b,c,d) \
+  (ip6addr)->addr[index] = PP_HTONL(LWIP_MAKEU32(a,b,c,d))
+
+/** Set a full IPv6 address by passing the 4 u32_t indices in network byte order
+    (use PP_HTONL() for constants) */
+#define IP6_ADDR(ip6addr, idx0, idx1, idx2, idx3) do { \
+  (ip6addr)->addr[0] = idx0; \
+  (ip6addr)->addr[1] = idx1; \
+  (ip6addr)->addr[2] = idx2; \
+  (ip6addr)->addr[3] = idx3; \
+  ip6_addr_clear_zone(ip6addr); } while(0)
+
+/** Access address in 16-bit block */
+#define IP6_ADDR_BLOCK1(ip6addr) ((u16_t)((lwip_htonl((ip6addr)->addr[0]) >> 16) & 0xffff))
+/** Access address in 16-bit block */
+#define IP6_ADDR_BLOCK2(ip6addr) ((u16_t)((lwip_htonl((ip6addr)->addr[0])) & 0xffff))
+/** Access address in 16-bit block */
+#define IP6_ADDR_BLOCK3(ip6addr) ((u16_t)((lwip_htonl((ip6addr)->addr[1]) >> 16) & 0xffff))
+/** Access address in 16-bit block */
+#define IP6_ADDR_BLOCK4(ip6addr) ((u16_t)((lwip_htonl((ip6addr)->addr[1])) & 0xffff))
+/** Access address in 16-bit block */
+#define IP6_ADDR_BLOCK5(ip6addr) ((u16_t)((lwip_htonl((ip6addr)->addr[2]) >> 16) & 0xffff))
+/** Access address in 16-bit block */
+#define IP6_ADDR_BLOCK6(ip6addr) ((u16_t)((lwip_htonl((ip6addr)->addr[2])) & 0xffff))
+/** Access address in 16-bit block */
+#define IP6_ADDR_BLOCK7(ip6addr) ((u16_t)((lwip_htonl((ip6addr)->addr[3]) >> 16) & 0xffff))
+/** Access address in 16-bit block */
+#define IP6_ADDR_BLOCK8(ip6addr) ((u16_t)((lwip_htonl((ip6addr)->addr[3])) & 0xffff))
+
+/** Copy IPv6 address - faster than ip6_addr_set: no NULL check */
+#define ip6_addr_copy(dest, src) do{(dest).addr[0] = (src).addr[0]; \
+                                    (dest).addr[1] = (src).addr[1]; \
+                                    (dest).addr[2] = (src).addr[2]; \
+                                    (dest).addr[3] = (src).addr[3]; \
+                                    ip6_addr_copy_zone((dest), (src)); }while(0)
+/** Safely copy one IPv6 address to another (src may be NULL) */
+#define ip6_addr_set(dest, src) do{(dest)->addr[0] = (src) == NULL ? 0 : (src)->addr[0]; \
+                                   (dest)->addr[1] = (src) == NULL ? 0 : (src)->addr[1]; \
+                                   (dest)->addr[2] = (src) == NULL ? 0 : (src)->addr[2]; \
+                                   (dest)->addr[3] = (src) == NULL ? 0 : (src)->addr[3]; \
+                                   ip6_addr_set_zone((dest), (src) == NULL ? IP6_NO_ZONE : ip6_addr_zone(src)); }while(0)
+
+/** Copy packed IPv6 address to unpacked IPv6 address; zone is not set */
+#define ip6_addr_copy_from_packed(dest, src) do{(dest).addr[0] = (src).addr[0]; \
+                                    (dest).addr[1] = (src).addr[1]; \
+                                    (dest).addr[2] = (src).addr[2]; \
+                                    (dest).addr[3] = (src).addr[3]; \
+                                    ip6_addr_clear_zone(&dest); }while(0)
+
+/** Copy unpacked IPv6 address to packed IPv6 address; zone is lost */
+#define ip6_addr_copy_to_packed(dest, src) do{(dest).addr[0] = (src).addr[0]; \
+                                    (dest).addr[1] = (src).addr[1]; \
+                                    (dest).addr[2] = (src).addr[2]; \
+                                    (dest).addr[3] = (src).addr[3]; }while(0)
+
+/** Set complete address to zero */
+#define ip6_addr_set_zero(ip6addr)    do{(ip6addr)->addr[0] = 0; \
+                                         (ip6addr)->addr[1] = 0; \
+                                         (ip6addr)->addr[2] = 0; \
+                                         (ip6addr)->addr[3] = 0; \
+                                         ip6_addr_clear_zone(ip6addr);}while(0)
+
+/** Set address to ipv6 'any' (no need for lwip_htonl()) */
+#define ip6_addr_set_any(ip6addr)       ip6_addr_set_zero(ip6addr)
+/** Set address to ipv6 loopback address */
+#define ip6_addr_set_loopback(ip6addr) do{(ip6addr)->addr[0] = 0; \
+                                          (ip6addr)->addr[1] = 0; \
+                                          (ip6addr)->addr[2] = 0; \
+                                          (ip6addr)->addr[3] = PP_HTONL(0x00000001UL); \
+                                          ip6_addr_clear_zone(ip6addr);}while(0)
+/** Safely copy one IPv6 address to another and change byte order
+ * from host- to network-order. */
+#define ip6_addr_set_hton(dest, src) do{(dest)->addr[0] = (src) == NULL ? 0 : lwip_htonl((src)->addr[0]); \
+                                        (dest)->addr[1] = (src) == NULL ? 0 : lwip_htonl((src)->addr[1]); \
+                                        (dest)->addr[2] = (src) == NULL ? 0 : lwip_htonl((src)->addr[2]); \
+                                        (dest)->addr[3] = (src) == NULL ? 0 : lwip_htonl((src)->addr[3]); \
+                                        ip6_addr_set_zone((dest), (src) == NULL ? IP6_NO_ZONE : ip6_addr_zone(src));}while(0)
+
+
+/** Compare IPv6 networks, ignoring zone information. To be used sparingly! */
+#define ip6_addr_netcmp_zoneless(addr1, addr2) (((addr1)->addr[0] == (addr2)->addr[0]) && \
+                                               ((addr1)->addr[1] == (addr2)->addr[1]))
+
+/**
+ * Determine if two IPv6 address are on the same network.
+ *
+ * @param addr1 IPv6 address 1
+ * @param addr2 IPv6 address 2
+ * @return 1 if the network identifiers of both address match, 0 if not
+ */
+#define ip6_addr_netcmp(addr1, addr2) (ip6_addr_netcmp_zoneless((addr1), (addr2)) && \
+                                       ip6_addr_cmp_zone((addr1), (addr2)))
+
+/* Exact-host comparison *after* ip6_addr_netcmp() succeeded, for efficiency. */
+#define ip6_addr_nethostcmp(addr1, addr2) (((addr1)->addr[2] == (addr2)->addr[2]) && \
+                                           ((addr1)->addr[3] == (addr2)->addr[3]))
+
+/** Compare IPv6 addresses, ignoring zone information. To be used sparingly! */
+#define ip6_addr_cmp_zoneless(addr1, addr2) (((addr1)->addr[0] == (addr2)->addr[0]) && \
+                                    ((addr1)->addr[1] == (addr2)->addr[1]) && \
+                                    ((addr1)->addr[2] == (addr2)->addr[2]) && \
+                                    ((addr1)->addr[3] == (addr2)->addr[3]))
+/**
+ * Determine if two IPv6 addresses are the same. In particular, the address
+ * part of both must be the same, and the zone must be compatible.
+ *
+ * @param addr1 IPv6 address 1
+ * @param addr2 IPv6 address 2
+ * @return 1 if the addresses are considered equal, 0 if not
+ */
+#define ip6_addr_cmp(addr1, addr2) (ip6_addr_cmp_zoneless((addr1), (addr2)) && \
+                                    ip6_addr_cmp_zone((addr1), (addr2)))
+
+/** Compare IPv6 address to packed address and zone */
+#define ip6_addr_cmp_packed(ip6addr, paddr, zone_idx) (((ip6addr)->addr[0] == (paddr)->addr[0]) && \
+                                    ((ip6addr)->addr[1] == (paddr)->addr[1]) && \
+                                    ((ip6addr)->addr[2] == (paddr)->addr[2]) && \
+                                    ((ip6addr)->addr[3] == (paddr)->addr[3]) && \
+                                    ip6_addr_equals_zone((ip6addr), (zone_idx)))
+
+#define ip6_get_subnet_id(ip6addr)   (lwip_htonl((ip6addr)->addr[2]) & 0x0000ffffUL)
+
+#define ip6_addr_isany_val(ip6addr) (((ip6addr).addr[0] == 0) && \
+                                     ((ip6addr).addr[1] == 0) && \
+                                     ((ip6addr).addr[2] == 0) && \
+                                     ((ip6addr).addr[3] == 0))
+#define ip6_addr_isany(ip6addr) (((ip6addr) == NULL) || ip6_addr_isany_val(*(ip6addr)))
+
+#define ip6_addr_isloopback(ip6addr) (((ip6addr)->addr[0] == 0UL) && \
+                                      ((ip6addr)->addr[1] == 0UL) && \
+                                      ((ip6addr)->addr[2] == 0UL) && \
+                                      ((ip6addr)->addr[3] == PP_HTONL(0x00000001UL)))
+
+#define ip6_addr_isglobal(ip6addr) (((ip6addr)->addr[0] & PP_HTONL(0xe0000000UL)) == PP_HTONL(0x20000000UL))
+
+#define ip6_addr_islinklocal(ip6addr) (((ip6addr)->addr[0] & PP_HTONL(0xffc00000UL)) == PP_HTONL(0xfe800000UL))
+
+#define ip6_addr_issitelocal(ip6addr) (((ip6addr)->addr[0] & PP_HTONL(0xffc00000UL)) == PP_HTONL(0xfec00000UL))
+
+#define ip6_addr_isuniquelocal(ip6addr) (((ip6addr)->addr[0] & PP_HTONL(0xfe000000UL)) == PP_HTONL(0xfc000000UL))
+
+#define ip6_addr_isipv4mappedipv6(ip6addr) (((ip6addr)->addr[0] == 0) && ((ip6addr)->addr[1] == 0) && (((ip6addr)->addr[2]) == PP_HTONL(0x0000FFFFUL)))
+
+#define ip6_addr_ismulticast(ip6addr) (((ip6addr)->addr[0] & PP_HTONL(0xff000000UL)) == PP_HTONL(0xff000000UL))
+#define ip6_addr_multicast_transient_flag(ip6addr)  ((ip6addr)->addr[0] & PP_HTONL(0x00100000UL))
+#define ip6_addr_multicast_prefix_flag(ip6addr)     ((ip6addr)->addr[0] & PP_HTONL(0x00200000UL))
+#define ip6_addr_multicast_rendezvous_flag(ip6addr) ((ip6addr)->addr[0] & PP_HTONL(0x00400000UL))
+#define ip6_addr_multicast_scope(ip6addr) ((lwip_htonl((ip6addr)->addr[0]) >> 16) & 0xf)
+#define IP6_MULTICAST_SCOPE_RESERVED            0x0
+#define IP6_MULTICAST_SCOPE_RESERVED0           0x0
+#define IP6_MULTICAST_SCOPE_INTERFACE_LOCAL     0x1
+#define IP6_MULTICAST_SCOPE_LINK_LOCAL          0x2
+#define IP6_MULTICAST_SCOPE_RESERVED3           0x3
+#define IP6_MULTICAST_SCOPE_ADMIN_LOCAL         0x4
+#define IP6_MULTICAST_SCOPE_SITE_LOCAL          0x5
+#define IP6_MULTICAST_SCOPE_ORGANIZATION_LOCAL  0x8
+#define IP6_MULTICAST_SCOPE_GLOBAL              0xe
+#define IP6_MULTICAST_SCOPE_RESERVEDF           0xf
+#define ip6_addr_ismulticast_iflocal(ip6addr) (((ip6addr)->addr[0] & PP_HTONL(0xff8f0000UL)) == PP_HTONL(0xff010000UL))
+#define ip6_addr_ismulticast_linklocal(ip6addr) (((ip6addr)->addr[0] & PP_HTONL(0xff8f0000UL)) == PP_HTONL(0xff020000UL))
+#define ip6_addr_ismulticast_adminlocal(ip6addr) (((ip6addr)->addr[0] & PP_HTONL(0xff8f0000UL)) == PP_HTONL(0xff040000UL))
+#define ip6_addr_ismulticast_sitelocal(ip6addr) (((ip6addr)->addr[0] & PP_HTONL(0xff8f0000UL)) == PP_HTONL(0xff050000UL))
+#define ip6_addr_ismulticast_orglocal(ip6addr) (((ip6addr)->addr[0] & PP_HTONL(0xff8f0000UL)) == PP_HTONL(0xff080000UL))
+#define ip6_addr_ismulticast_global(ip6addr) (((ip6addr)->addr[0] & PP_HTONL(0xff8f0000UL)) == PP_HTONL(0xff0e0000UL))
+
+/* Scoping note: while interface-local and link-local multicast addresses do
+ * have a scope (i.e., they are meaningful only in the context of a particular
+ * interface), the following functions are not assigning or comparing zone
+ * indices. The reason for this is backward compatibility. Any call site that
+ * produces a non-global multicast address must assign a multicast address as
+ * appropriate itself. */
+
+#define ip6_addr_isallnodes_iflocal(ip6addr) (((ip6addr)->addr[0] == PP_HTONL(0xff010000UL)) && \
+    ((ip6addr)->addr[1] == 0UL) && \
+    ((ip6addr)->addr[2] == 0UL) && \
+    ((ip6addr)->addr[3] == PP_HTONL(0x00000001UL)))
+
+#define ip6_addr_isallnodes_linklocal(ip6addr) (((ip6addr)->addr[0] == PP_HTONL(0xff020000UL)) && \
+    ((ip6addr)->addr[1] == 0UL) && \
+    ((ip6addr)->addr[2] == 0UL) && \
+    ((ip6addr)->addr[3] == PP_HTONL(0x00000001UL)))
+#define ip6_addr_set_allnodes_linklocal(ip6addr) do{(ip6addr)->addr[0] = PP_HTONL(0xff020000UL); \
+                (ip6addr)->addr[1] = 0; \
+                (ip6addr)->addr[2] = 0; \
+                (ip6addr)->addr[3] = PP_HTONL(0x00000001UL); \
+                ip6_addr_clear_zone(ip6addr); }while(0)
+
+#define ip6_addr_isallrouters_linklocal(ip6addr) (((ip6addr)->addr[0] == PP_HTONL(0xff020000UL)) && \
+    ((ip6addr)->addr[1] == 0UL) && \
+    ((ip6addr)->addr[2] == 0UL) && \
+    ((ip6addr)->addr[3] == PP_HTONL(0x00000002UL)))
+#define ip6_addr_set_allrouters_linklocal(ip6addr) do{(ip6addr)->addr[0] = PP_HTONL(0xff020000UL); \
+                (ip6addr)->addr[1] = 0; \
+                (ip6addr)->addr[2] = 0; \
+                (ip6addr)->addr[3] = PP_HTONL(0x00000002UL); \
+                ip6_addr_clear_zone(ip6addr); }while(0)
+
+#define ip6_addr_issolicitednode(ip6addr) ( ((ip6addr)->addr[0] == PP_HTONL(0xff020000UL)) && \
+        ((ip6addr)->addr[2] == PP_HTONL(0x00000001UL)) && \
+        (((ip6addr)->addr[3] & PP_HTONL(0xff000000UL)) == PP_HTONL(0xff000000UL)) )
+
+#define ip6_addr_set_solicitednode(ip6addr, if_id) do{(ip6addr)->addr[0] = PP_HTONL(0xff020000UL); \
+                (ip6addr)->addr[1] = 0; \
+                (ip6addr)->addr[2] = PP_HTONL(0x00000001UL); \
+                (ip6addr)->addr[3] = (PP_HTONL(0xff000000UL) | (if_id)); \
+                ip6_addr_clear_zone(ip6addr); }while(0)
+
+#define ip6_addr_cmp_solicitednode(ip6addr, sn_addr) (((ip6addr)->addr[0] == PP_HTONL(0xff020000UL)) && \
+                                    ((ip6addr)->addr[1] == 0) && \
+                                    ((ip6addr)->addr[2] == PP_HTONL(0x00000001UL)) && \
+                                    ((ip6addr)->addr[3] == (PP_HTONL(0xff000000UL) | (sn_addr)->addr[3])))
+
+/* IPv6 address states. */
+#define IP6_ADDR_INVALID      0x00
+#define IP6_ADDR_TENTATIVE    0x08
+#define IP6_ADDR_TENTATIVE_1  0x09 /* 1 probe sent */
+#define IP6_ADDR_TENTATIVE_2  0x0a /* 2 probes sent */
+#define IP6_ADDR_TENTATIVE_3  0x0b /* 3 probes sent */
+#define IP6_ADDR_TENTATIVE_4  0x0c /* 4 probes sent */
+#define IP6_ADDR_TENTATIVE_5  0x0d /* 5 probes sent */
+#define IP6_ADDR_TENTATIVE_6  0x0e /* 6 probes sent */
+#define IP6_ADDR_TENTATIVE_7  0x0f /* 7 probes sent */
+#define IP6_ADDR_VALID        0x10 /* This bit marks an address as valid (preferred or deprecated) */
+#define IP6_ADDR_PREFERRED    0x30
+#define IP6_ADDR_DEPRECATED   0x10 /* Same as VALID (valid but not preferred) */
+#define IP6_ADDR_DUPLICATED   0x40 /* Failed DAD test, not valid */
+
+#define IP6_ADDR_TENTATIVE_COUNT_MASK 0x07 /* 1-7 probes sent */
+
+#define ip6_addr_isinvalid(addr_state) (addr_state == IP6_ADDR_INVALID)
+#define ip6_addr_istentative(addr_state) (addr_state & IP6_ADDR_TENTATIVE)
+#define ip6_addr_isvalid(addr_state) (addr_state & IP6_ADDR_VALID) /* Include valid, preferred, and deprecated. */
+#define ip6_addr_ispreferred(addr_state) (addr_state == IP6_ADDR_PREFERRED)
+#define ip6_addr_isdeprecated(addr_state) (addr_state == IP6_ADDR_DEPRECATED)
+#define ip6_addr_isduplicated(addr_state) (addr_state == IP6_ADDR_DUPLICATED)
+
+#if LWIP_IPV6_ADDRESS_LIFETIMES
+#define IP6_ADDR_LIFE_STATIC   (0)
+#define IP6_ADDR_LIFE_INFINITE (0xffffffffUL)
+#define ip6_addr_life_isstatic(addr_life) ((addr_life) == IP6_ADDR_LIFE_STATIC)
+#define ip6_addr_life_isinfinite(addr_life) ((addr_life) == IP6_ADDR_LIFE_INFINITE)
+#endif /* LWIP_IPV6_ADDRESS_LIFETIMES */
+
+#define ip6_addr_debug_print_parts(debug, a, b, c, d, e, f, g, h) \
+  LWIP_DEBUGF(debug, ("%" X16_F ":%" X16_F ":%" X16_F ":%" X16_F ":%" X16_F ":%" X16_F ":%" X16_F ":%" X16_F, \
+                      a, b, c, d, e, f, g, h))
+#define ip6_addr_debug_print(debug, ipaddr) \
+  ip6_addr_debug_print_parts(debug, \
+                      (u16_t)((ipaddr) != NULL ? IP6_ADDR_BLOCK1(ipaddr) : 0),    \
+                      (u16_t)((ipaddr) != NULL ? IP6_ADDR_BLOCK2(ipaddr) : 0),    \
+                      (u16_t)((ipaddr) != NULL ? IP6_ADDR_BLOCK3(ipaddr) : 0),    \
+                      (u16_t)((ipaddr) != NULL ? IP6_ADDR_BLOCK4(ipaddr) : 0),    \
+                      (u16_t)((ipaddr) != NULL ? IP6_ADDR_BLOCK5(ipaddr) : 0),    \
+                      (u16_t)((ipaddr) != NULL ? IP6_ADDR_BLOCK6(ipaddr) : 0),    \
+                      (u16_t)((ipaddr) != NULL ? IP6_ADDR_BLOCK7(ipaddr) : 0),    \
+                      (u16_t)((ipaddr) != NULL ? IP6_ADDR_BLOCK8(ipaddr) : 0))
+#define ip6_addr_debug_print_val(debug, ipaddr) \
+  ip6_addr_debug_print_parts(debug, \
+                      IP6_ADDR_BLOCK1(&(ipaddr)),    \
+                      IP6_ADDR_BLOCK2(&(ipaddr)),    \
+                      IP6_ADDR_BLOCK3(&(ipaddr)),    \
+                      IP6_ADDR_BLOCK4(&(ipaddr)),    \
+                      IP6_ADDR_BLOCK5(&(ipaddr)),    \
+                      IP6_ADDR_BLOCK6(&(ipaddr)),    \
+                      IP6_ADDR_BLOCK7(&(ipaddr)),    \
+                      IP6_ADDR_BLOCK8(&(ipaddr)))
+
+#define IP6ADDR_STRLEN_MAX    46
+
+int ip6addr_aton(const char *cp, ip6_addr_t *addr);
+/** returns ptr to static buffer; not reentrant! */
+char *ip6addr_ntoa(const ip6_addr_t *addr);
+char *ip6addr_ntoa_r(const ip6_addr_t *addr, char *buf, int buflen);
+
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LWIP_IPV6 */
+
+#endif /* LWIP_HDR_IP6_ADDR_H */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/ip6_frag.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/ip6_frag.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/ip6_frag.h	(revision 457)
@@ -0,0 +1,144 @@
+/**
+ * @file
+ *
+ * IPv6 fragmentation and reassembly.
+ */
+
+/*
+ * Copyright (c) 2010 Inico Technologies Ltd.
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Ivan Delamer <delamer@inicotech.com>
+ *
+ *
+ * Please coordinate changes and requests with Ivan Delamer
+ * <delamer@inicotech.com>
+ */
+#ifndef LWIP_HDR_IP6_FRAG_H
+#define LWIP_HDR_IP6_FRAG_H
+
+#include "lwip/opt.h"
+#include "lwip/pbuf.h"
+#include "lwip/ip6_addr.h"
+#include "lwip/ip6.h"
+#include "lwip/netif.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+#if LWIP_IPV6 && LWIP_IPV6_REASS  /* don't build if not configured for use in lwipopts.h */
+
+/** The IPv6 reassembly timer interval in milliseconds. */
+#define IP6_REASS_TMR_INTERVAL 1000
+
+/** IP6_FRAG_COPYHEADER==1: for platforms where sizeof(void*) > 4, "struct
+ * ip6_reass_helper" is too large to be stored in the IPv6 fragment header, and
+ * will bleed into the header before it, which may be the IPv6 header or an
+ * extension header. This means that for each first fragment packet, we need to
+ * 1) make a copy of some IPv6 header fields (src+dest) that we need later on,
+ * just in case we do overwrite part of the IPv6 header, and 2) make a copy of
+ * the header data that we overwrote, so that we can restore it before either
+ * completing reassembly or sending an ICMPv6 reply. The last part is true even
+ * if this setting is disabled, but if it is enabled, we need to save a bit
+ * more data (up to the size of a pointer) because we overwrite more. */
+#ifndef IPV6_FRAG_COPYHEADER
+#define IPV6_FRAG_COPYHEADER   0
+#endif
+
+/* With IPV6_FRAG_COPYHEADER==1, a helper structure may (or, depending on the
+ * presence of extensions, may not) overwrite part of the IP header. Therefore,
+ * we copy the fields that we need from the IP header for as long as the helper
+ * structure may still be in place. This is easier than temporarily restoring
+ * those fields in the IP header each time we need to perform checks on them. */
+#if IPV6_FRAG_COPYHEADER
+#define IPV6_FRAG_SRC(ipr) ((ipr)->src)
+#define IPV6_FRAG_DEST(ipr) ((ipr)->dest)
+#else /* IPV6_FRAG_COPYHEADER */
+#define IPV6_FRAG_SRC(ipr) ((ipr)->iphdr->src)
+#define IPV6_FRAG_DEST(ipr) ((ipr)->iphdr->dest)
+#endif /* IPV6_FRAG_COPYHEADER */
+
+/** IPv6 reassembly helper struct.
+ * This is exported because memp needs to know the size.
+ */
+struct ip6_reassdata {
+  struct ip6_reassdata *next;
+  struct pbuf *p;
+  struct ip6_hdr *iphdr; /* pointer to the first (original) IPv6 header */
+#if IPV6_FRAG_COPYHEADER
+  ip6_addr_p_t src; /* copy of the source address in the IP header */
+  ip6_addr_p_t dest; /* copy of the destination address in the IP header */
+  /* This buffer (for the part of the original header that we overwrite) will
+   * be slightly oversized, but we cannot compute the exact size from here. */
+  u8_t orig_hdr[sizeof(struct ip6_frag_hdr) + sizeof(void*)];
+#else /* IPV6_FRAG_COPYHEADER */
+  /* In this case we still need the buffer, for sending ICMPv6 replies. */
+  u8_t orig_hdr[sizeof(struct ip6_frag_hdr)];
+#endif /* IPV6_FRAG_COPYHEADER */
+  u32_t identification;
+  u16_t datagram_len;
+  u8_t nexth;
+  u8_t timer;
+#if LWIP_IPV6_SCOPES
+  u8_t src_zone; /* zone of original packet's source address */
+  u8_t dest_zone; /* zone of original packet's destination address */
+#endif /* LWIP_IPV6_SCOPES */
+};
+
+#define ip6_reass_init() /* Compatibility define */
+void ip6_reass_tmr(void);
+struct pbuf *ip6_reass(struct pbuf *p);
+
+#endif /* LWIP_IPV6 && LWIP_IPV6_REASS */
+
+#if LWIP_IPV6 && LWIP_IPV6_FRAG  /* don't build if not configured for use in lwipopts.h */
+
+#ifndef LWIP_PBUF_CUSTOM_REF_DEFINED
+#define LWIP_PBUF_CUSTOM_REF_DEFINED
+/** A custom pbuf that holds a reference to another pbuf, which is freed
+ * when this custom pbuf is freed. This is used to create a custom PBUF_REF
+ * that points into the original pbuf. */
+struct pbuf_custom_ref {
+  /** 'base class' */
+  struct pbuf_custom pc;
+  /** pointer to the original pbuf that is referenced */
+  struct pbuf *original;
+};
+#endif /* LWIP_PBUF_CUSTOM_REF_DEFINED */
+
+err_t ip6_frag(struct pbuf *p, struct netif *netif, const ip6_addr_t *dest);
+
+#endif /* LWIP_IPV6 && LWIP_IPV6_FRAG */
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LWIP_HDR_IP6_FRAG_H */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/ip6_zone.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/ip6_zone.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/ip6_zone.h	(revision 457)
@@ -0,0 +1,304 @@
+/**
+ * @file
+ *
+ * IPv6 address scopes, zones, and scoping policy.
+ *
+ * This header provides the means to implement support for IPv6 address scopes,
+ * as per RFC 4007. An address scope can be either global or more constrained.
+ * In lwIP, we say that an address "has a scope" or "is scoped" when its scope
+ * is constrained, in which case the address is meaningful only in a specific
+ * "zone." For unicast addresses, only link-local addresses have a scope; in
+ * that case, the scope is the link. For multicast addresses, there are various
+ * scopes defined by RFC 4007 and others. For any constrained scope, a system
+ * must establish a (potentially one-to-many) mapping between zones and local
+ * interfaces. For example, a link-local address is valid on only one link (its
+ * zone). That link may be attached to one or more local interfaces. The
+ * decisions on which scopes are constrained and the mapping between zones and
+ * interfaces is together what we refer to as the "scoping policy" - more on
+ * this in a bit.
+ *
+ * In lwIP, each IPv6 address has an associated zone index. This zone index may
+ * be set to "no zone" (IP6_NO_ZONE, 0) or an actual zone. We say that an
+ * address "has a zone" or "is zoned" when its zone index is *not* set to "no
+ * zone." In lwIP, in principle, each address should be "properly zoned," which
+ * means that if the address has a zone if and only if has a scope. As such, it
+ * is a rule that an unscoped (e.g., global) address must never have a zone.
+ * Even though one could argue that there is always one zone even for global
+ * scopes, this rule exists for implementation simplicity. Violation of the
+ * rule will trigger assertions or otherwise result in undesired behavior.
+ *
+ * Backward compatibility prevents us from requiring that applications always
+ * provide properly zoned addresses. We do enforce the rule that the in the
+ * lwIP link layer (everything below netif->output_ip6() and in particular ND6)
+ * *all* addresses are properly zoned. Thus, on the output paths down the
+ * stack, various places deal with the case of addresses that lack a zone.
+ * Some of them are best-effort for efficiency (e.g. the PCB bind and connect
+ * API calls' attempts to add missing zones); ultimately the IPv6 output
+ * handler (@ref ip6_output_if_src) will set a zone if necessary.
+ *
+ * Aside from dealing with scoped addresses lacking a zone, a proper IPv6
+ * implementation must also ensure that a packet with a scoped source and/or
+ * destination address does not leave its zone. This is currently implemented
+ * in the input and forward functions. However, for output, these checks are
+ * deliberately omitted in order to keep the implementation lightweight. The
+ * routing algorithm in @ref ip6_route will take decisions such that it will
+ * not cause zone violations unless the application sets bad addresses, though.
+ *
+ * In terms of scoping policy, lwIP implements the default policy from RFC 4007
+ * using macros in this file. This policy considers link-local unicast
+ * addresses and (only) interface-local and link-local multicast addresses as
+ * having a scope. For all these addresses, the zone is equal to the interface.
+ * As shown below in this file, it is possible to implement a custom policy.
+ */
+
+/*
+ * Copyright (c) 2017 The MINIX 3 Project.
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: David van Moolenbroek <david@minix3.org>
+ *
+ */
+#ifndef LWIP_HDR_IP6_ZONE_H
+#define LWIP_HDR_IP6_ZONE_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @defgroup ip6_zones IPv6 Zones
+ * @ingroup ip6
+ * @{
+ */
+
+#if LWIP_IPV6  /* don't build if not configured for use in lwipopts.h */
+
+/** Identifier for "no zone". */
+#define IP6_NO_ZONE 0
+
+#if LWIP_IPV6_SCOPES
+
+/** Zone initializer for static IPv6 address initialization, including comma. */
+#define IPADDR6_ZONE_INIT , IP6_NO_ZONE
+
+/** Return the zone index of the given IPv6 address; possibly "no zone". */
+#define ip6_addr_zone(ip6addr) ((ip6addr)->zone)
+
+/** Does the given IPv6 address have a zone set? (0/1) */
+#define ip6_addr_has_zone(ip6addr) (ip6_addr_zone(ip6addr) != IP6_NO_ZONE)
+
+/** Set the zone field of an IPv6 address to a particular value. */
+#define ip6_addr_set_zone(ip6addr, zone_idx) ((ip6addr)->zone = (zone_idx))
+
+/** Clear the zone field of an IPv6 address, setting it to "no zone". */
+#define ip6_addr_clear_zone(ip6addr) ((ip6addr)->zone = IP6_NO_ZONE)
+
+/** Copy the zone field from the second IPv6 address to the first one. */
+#define ip6_addr_copy_zone(ip6addr1, ip6addr2) ((ip6addr1).zone = (ip6addr2).zone)
+
+/** Is the zone field of the given IPv6 address equal to the given zone index? (0/1) */
+#define ip6_addr_equals_zone(ip6addr, zone_idx) ((ip6addr)->zone == (zone_idx))
+
+/** Are the zone fields of the given IPv6 addresses equal? (0/1)
+ * This macro must only be used on IPv6 addresses of the same scope. */
+#define ip6_addr_cmp_zone(ip6addr1, ip6addr2) ((ip6addr1)->zone == (ip6addr2)->zone)
+
+/** Symbolic constants for the 'type' parameters in some of the macros.
+ * These exist for efficiency only, allowing the macros to avoid certain tests
+ * when the address is known not to be of a certain type. Dead code elimination
+ * will do the rest. IP6_MULTICAST is supported but currently not optimized.
+ * @see ip6_addr_has_scope, ip6_addr_assign_zone, ip6_addr_lacks_zone.
+ */
+enum lwip_ipv6_scope_type
+{
+  /** Unknown */
+  IP6_UNKNOWN   = 0,
+  /** Unicast */
+  IP6_UNICAST   = 1,
+  /** Multicast */
+  IP6_MULTICAST = 2
+};
+
+/** IPV6_CUSTOM_SCOPES: together, the following three macro definitions,
+ * @ref ip6_addr_has_scope, @ref ip6_addr_assign_zone, and
+ * @ref ip6_addr_test_zone, completely define the lwIP scoping policy.
+ * The definitions below implement the default policy from RFC 4007 Sec. 6.
+ * Should an implementation desire to implement a different policy, it can
+ * define IPV6_CUSTOM_SCOPES to 1 and supply its own definitions for the three
+ * macros instead.
+ */
+#ifndef IPV6_CUSTOM_SCOPES
+#define IPV6_CUSTOM_SCOPES 0
+#endif /* !IPV6_CUSTOM_SCOPES */
+
+#if !IPV6_CUSTOM_SCOPES
+
+/**
+ * Determine whether an IPv6 address has a constrained scope, and as such is
+ * meaningful only if accompanied by a zone index to identify the scope's zone.
+ * The given address type may be used to eliminate at compile time certain
+ * checks that will evaluate to false at run time anyway.
+ *
+ * This default implementation follows the default model of RFC 4007, where
+ * only interface-local and link-local scopes are defined.
+ *
+ * Even though the unicast loopback address does have an implied link-local
+ * scope, in this implementation it does not have an explicitly assigned zone
+ * index. As such it should not be tested for in this macro.
+ *
+ * @param ip6addr the IPv6 address (const); only its address part is examined.
+ * @param type address type; see @ref lwip_ipv6_scope_type.
+ * @return 1 if the address has a constrained scope, 0 if it does not.
+ */
+#define ip6_addr_has_scope(ip6addr, type) \
+  (ip6_addr_islinklocal(ip6addr) || (((type) != IP6_UNICAST) && \
+   (ip6_addr_ismulticast_iflocal(ip6addr) || \
+    ip6_addr_ismulticast_linklocal(ip6addr))))
+
+/**
+ * Assign a zone index to an IPv6 address, based on a network interface. If the
+ * given address has a scope, the assigned zone index is that scope's zone of
+ * the given netif; otherwise, the assigned zone index is "no zone".
+ *
+ * This default implementation follows the default model of RFC 4007, where
+ * only interface-local and link-local scopes are defined, and the zone index
+ * of both of those scopes always equals the index of the network interface.
+ * As such, this default implementation need not distinguish between different
+ * constrained scopes when assigning the zone.
+ *
+ * @param ip6addr the IPv6 address; its address part is examined, and its zone
+ *                index is assigned.
+ * @param type address type; see @ref lwip_ipv6_scope_type.
+ * @param netif the network interface (const).
+ */
+#define ip6_addr_assign_zone(ip6addr, type, netif) \
+    (ip6_addr_set_zone((ip6addr), \
+      ip6_addr_has_scope((ip6addr), (type)) ? netif_get_index(netif) : 0))
+
+/**
+ * Test whether an IPv6 address is "zone-compatible" with a network interface.
+ * That is, test whether the network interface is part of the zone associated
+ * with the address. For efficiency, this macro is only ever called if the
+ * given address is either scoped or zoned, and thus, it need not test this.
+ * If an address is scoped but not zoned, or zoned and not scoped, it is
+ * considered not zone-compatible with any netif.
+ *
+ * This default implementation follows the default model of RFC 4007, where
+ * only interface-local and link-local scopes are defined, and the zone index
+ * of both of those scopes always equals the index of the network interface.
+ * As such, there is always only one matching netif for a specific zone index,
+ * but all call sites of this macro currently support multiple matching netifs
+ * as well (at no additional expense in the common case).
+ *
+ * @param ip6addr the IPv6 address (const).
+ * @param netif the network interface (const).
+ * @return 1 if the address is scope-compatible with the netif, 0 if not.
+ */
+#define ip6_addr_test_zone(ip6addr, netif) \
+    (ip6_addr_equals_zone((ip6addr), netif_get_index(netif)))
+
+#endif /* !IPV6_CUSTOM_SCOPES */
+
+/** Does the given IPv6 address have a scope, and as such should also have a
+ * zone to be meaningful, but does not actually have a zone? (0/1) */
+#define ip6_addr_lacks_zone(ip6addr, type) \
+    (!ip6_addr_has_zone(ip6addr) && ip6_addr_has_scope((ip6addr), (type)))
+
+/**
+ * Try to select a zone for a scoped address that does not yet have a zone.
+ * Called from PCB bind and connect routines, for two reasons: 1) to save on
+ * this (relatively expensive) selection for every individual packet route
+ * operation and 2) to allow the application to obtain the selected zone from
+ * the PCB as is customary for e.g. getsockname/getpeername BSD socket calls.
+ *
+ * Ideally, callers would always supply a properly zoned address, in which case
+ * this function would not be needed. It exists both for compatibility with the
+ * BSD socket API (which accepts zoneless destination addresses) and for
+ * backward compatibility with pre-scoping lwIP code.
+ *
+ * It may be impossible to select a zone, e.g. if there are no netifs.  In that
+ * case, the address's zone field will be left as is.
+ *
+ * @param dest the IPv6 address for which to select and set a zone.
+ * @param src source IPv6 address (const); may be equal to dest.
+ */
+#define ip6_addr_select_zone(dest, src) do { struct netif *selected_netif; \
+  selected_netif = ip6_route((src), (dest)); \
+  if (selected_netif != NULL) { \
+    ip6_addr_assign_zone((dest), IP6_UNKNOWN, selected_netif); \
+  } } while (0)
+
+/**
+ * @}
+ */
+
+#else /* LWIP_IPV6_SCOPES */
+
+#define IPADDR6_ZONE_INIT
+#define ip6_addr_zone(ip6addr) (IP6_NO_ZONE)
+#define ip6_addr_has_zone(ip6addr) (0)
+#define ip6_addr_set_zone(ip6addr, zone_idx)
+#define ip6_addr_clear_zone(ip6addr)
+#define ip6_addr_copy_zone(ip6addr1, ip6addr2)
+#define ip6_addr_equals_zone(ip6addr, zone_idx) (1)
+#define ip6_addr_cmp_zone(ip6addr1, ip6addr2) (1)
+#define IPV6_CUSTOM_SCOPES 0
+#define ip6_addr_has_scope(ip6addr, type) (0)
+#define ip6_addr_assign_zone(ip6addr, type, netif)
+#define ip6_addr_test_zone(ip6addr, netif) (1)
+#define ip6_addr_lacks_zone(ip6addr, type) (0)
+#define ip6_addr_select_zone(ip6addr, src)
+
+#endif /* LWIP_IPV6_SCOPES */
+
+#if LWIP_IPV6_SCOPES && LWIP_IPV6_SCOPES_DEBUG
+
+/** Verify that the given IPv6 address is properly zoned. */
+#define IP6_ADDR_ZONECHECK(ip6addr) LWIP_ASSERT("IPv6 zone check failed", \
+    ip6_addr_has_scope(ip6addr, IP6_UNKNOWN) == ip6_addr_has_zone(ip6addr))
+
+/** Verify that the given IPv6 address is properly zoned for the given netif. */
+#define IP6_ADDR_ZONECHECK_NETIF(ip6addr, netif) LWIP_ASSERT("IPv6 netif zone check failed", \
+    ip6_addr_has_scope(ip6addr, IP6_UNKNOWN) ? \
+    (ip6_addr_has_zone(ip6addr) && \
+     (((netif) == NULL) || ip6_addr_test_zone((ip6addr), (netif)))) : \
+    !ip6_addr_has_zone(ip6addr))
+
+#else /* LWIP_IPV6_SCOPES && LWIP_IPV6_SCOPES_DEBUG */
+
+#define IP6_ADDR_ZONECHECK(ip6addr)
+#define IP6_ADDR_ZONECHECK_NETIF(ip6addr, netif)
+
+#endif /* LWIP_IPV6_SCOPES && LWIP_IPV6_SCOPES_DEBUG */
+
+#endif /* LWIP_IPV6 */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LWIP_HDR_IP6_ZONE_H */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/ip_addr.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/ip_addr.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/ip_addr.h	(revision 457)
@@ -0,0 +1,438 @@
+/**
+ * @file
+ * IP address API (common IPv4 and IPv6)
+ */
+
+/*
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Adam Dunkels <adam@sics.se>
+ *
+ */
+#ifndef LWIP_HDR_IP_ADDR_H
+#define LWIP_HDR_IP_ADDR_H
+
+#include "lwip/opt.h"
+#include "lwip/def.h"
+
+#include "lwip/ip4_addr.h"
+#include "lwip/ip6_addr.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** @ingroup ipaddr
+ * IP address types for use in ip_addr_t.type member.
+ * @see tcp_new_ip_type(), udp_new_ip_type(), raw_new_ip_type().
+ */
+enum lwip_ip_addr_type {
+  /** IPv4 */
+  IPADDR_TYPE_V4 =   0U,
+  /** IPv6 */
+  IPADDR_TYPE_V6 =   6U,
+  /** IPv4+IPv6 ("dual-stack") */
+  IPADDR_TYPE_ANY = 46U
+};
+
+#if LWIP_IPV4 && LWIP_IPV6
+/**
+ * @ingroup ipaddr
+ * A union struct for both IP version's addresses.
+ * ATTENTION: watch out for its size when adding IPv6 address scope!
+ */
+typedef struct ip_addr {
+  union {
+    ip6_addr_t ip6;
+    ip4_addr_t ip4;
+  } u_addr;
+  /** @ref lwip_ip_addr_type */
+  u8_t type;
+} ip_addr_t;
+
+extern const ip_addr_t ip_addr_any_type;
+
+/** @ingroup ip4addr */
+#define IPADDR4_INIT(u32val)          { { { { u32val, 0ul, 0ul, 0ul } IPADDR6_ZONE_INIT } }, IPADDR_TYPE_V4 }
+/** @ingroup ip4addr */
+#define IPADDR4_INIT_BYTES(a,b,c,d)   IPADDR4_INIT(PP_HTONL(LWIP_MAKEU32(a,b,c,d)))
+
+/** @ingroup ip6addr */
+#define IPADDR6_INIT(a, b, c, d)      { { { { a, b, c, d } IPADDR6_ZONE_INIT } }, IPADDR_TYPE_V6 }
+/** @ingroup ip6addr */
+#define IPADDR6_INIT_HOST(a, b, c, d) { { { { PP_HTONL(a), PP_HTONL(b), PP_HTONL(c), PP_HTONL(d) } IPADDR6_ZONE_INIT } }, IPADDR_TYPE_V6 }
+
+/** @ingroup ipaddr */
+#define IP_IS_ANY_TYPE_VAL(ipaddr)    (IP_GET_TYPE(&ipaddr) == IPADDR_TYPE_ANY)
+/** @ingroup ipaddr */
+#define IPADDR_ANY_TYPE_INIT          { { { { 0ul, 0ul, 0ul, 0ul } IPADDR6_ZONE_INIT } }, IPADDR_TYPE_ANY }
+
+/** @ingroup ip4addr */
+#define IP_IS_V4_VAL(ipaddr)          (IP_GET_TYPE(&ipaddr) == IPADDR_TYPE_V4)
+/** @ingroup ip6addr */
+#define IP_IS_V6_VAL(ipaddr)          (IP_GET_TYPE(&ipaddr) == IPADDR_TYPE_V6)
+/** @ingroup ip4addr */
+#define IP_IS_V4(ipaddr)              (((ipaddr) == NULL) || IP_IS_V4_VAL(*(ipaddr)))
+/** @ingroup ip6addr */
+#define IP_IS_V6(ipaddr)              (((ipaddr) != NULL) && IP_IS_V6_VAL(*(ipaddr)))
+
+#define IP_SET_TYPE_VAL(ipaddr, iptype) do { (ipaddr).type = (iptype); }while(0)
+#define IP_SET_TYPE(ipaddr, iptype)     do { if((ipaddr) != NULL) { IP_SET_TYPE_VAL(*(ipaddr), iptype); }}while(0)
+#define IP_GET_TYPE(ipaddr)           ((ipaddr)->type)
+
+#define IP_ADDR_RAW_SIZE(ipaddr)      (IP_GET_TYPE(&ipaddr) == IPADDR_TYPE_V4 ? sizeof(ip4_addr_t) : sizeof(ip6_addr_t))
+
+#define IP_ADDR_PCB_VERSION_MATCH_EXACT(pcb, ipaddr) (IP_GET_TYPE(&pcb->local_ip) == IP_GET_TYPE(ipaddr))
+#define IP_ADDR_PCB_VERSION_MATCH(pcb, ipaddr) (IP_IS_ANY_TYPE_VAL(pcb->local_ip) || IP_ADDR_PCB_VERSION_MATCH_EXACT(pcb, ipaddr))
+
+/** @ingroup ip6addr
+ * Convert generic ip address to specific protocol version
+ */
+#define ip_2_ip6(ipaddr)   (&((ipaddr)->u_addr.ip6))
+/** @ingroup ip4addr
+ * Convert generic ip address to specific protocol version
+ */
+#define ip_2_ip4(ipaddr)   (&((ipaddr)->u_addr.ip4))
+
+/** @ingroup ip4addr */
+#define IP_ADDR4(ipaddr,a,b,c,d)      do { IP4_ADDR(ip_2_ip4(ipaddr),a,b,c,d); \
+                                           IP_SET_TYPE_VAL(*(ipaddr), IPADDR_TYPE_V4); } while(0)
+/** @ingroup ip6addr */
+#define IP_ADDR6(ipaddr,i0,i1,i2,i3)  do { IP6_ADDR(ip_2_ip6(ipaddr),i0,i1,i2,i3); \
+                                           IP_SET_TYPE_VAL(*(ipaddr), IPADDR_TYPE_V6); } while(0)
+/** @ingroup ip6addr */
+#define IP_ADDR6_HOST(ipaddr,i0,i1,i2,i3)  IP_ADDR6(ipaddr,PP_HTONL(i0),PP_HTONL(i1),PP_HTONL(i2),PP_HTONL(i3))
+
+#define ip_clear_no4(ipaddr)  do { ip_2_ip6(ipaddr)->addr[1] = \
+                                   ip_2_ip6(ipaddr)->addr[2] = \
+                                   ip_2_ip6(ipaddr)->addr[3] = 0; \
+                                   ip6_addr_clear_zone(ip_2_ip6(ipaddr)); }while(0)
+
+/** @ingroup ipaddr */
+#define ip_addr_copy(dest, src)      do{ IP_SET_TYPE_VAL(dest, IP_GET_TYPE(&src)); if(IP_IS_V6_VAL(src)){ \
+  ip6_addr_copy(*ip_2_ip6(&(dest)), *ip_2_ip6(&(src))); }else{ \
+  ip4_addr_copy(*ip_2_ip4(&(dest)), *ip_2_ip4(&(src))); ip_clear_no4(&dest); }}while(0)
+/** @ingroup ip6addr */
+#define ip_addr_copy_from_ip6(dest, src)      do{ \
+  ip6_addr_copy(*ip_2_ip6(&(dest)), src); IP_SET_TYPE_VAL(dest, IPADDR_TYPE_V6); }while(0)
+/** @ingroup ip6addr */
+#define ip_addr_copy_from_ip6_packed(dest, src)      do{ \
+  ip6_addr_copy_from_packed(*ip_2_ip6(&(dest)), src); IP_SET_TYPE_VAL(dest, IPADDR_TYPE_V6); }while(0)
+/** @ingroup ip4addr */
+#define ip_addr_copy_from_ip4(dest, src)      do{ \
+  ip4_addr_copy(*ip_2_ip4(&(dest)), src); IP_SET_TYPE_VAL(dest, IPADDR_TYPE_V4); ip_clear_no4(&dest); }while(0)
+/** @ingroup ip4addr */
+#define ip_addr_set_ip4_u32(ipaddr, val)  do{if(ipaddr){ip4_addr_set_u32(ip_2_ip4(ipaddr), val); \
+  IP_SET_TYPE(ipaddr, IPADDR_TYPE_V4); ip_clear_no4(ipaddr); }}while(0)
+/** @ingroup ip4addr */
+#define ip_addr_set_ip4_u32_val(ipaddr, val)  do{ ip4_addr_set_u32(ip_2_ip4(&(ipaddr)), val); \
+  IP_SET_TYPE_VAL(ipaddr, IPADDR_TYPE_V4); ip_clear_no4(&ipaddr); }while(0)
+/** @ingroup ip4addr */
+#define ip_addr_get_ip4_u32(ipaddr)  (((ipaddr) && IP_IS_V4(ipaddr)) ? \
+  ip4_addr_get_u32(ip_2_ip4(ipaddr)) : 0)
+/** @ingroup ipaddr */
+#define ip_addr_set(dest, src) do{ IP_SET_TYPE(dest, IP_GET_TYPE(src)); if(IP_IS_V6(src)){ \
+  ip6_addr_set(ip_2_ip6(dest), ip_2_ip6(src)); }else{ \
+  ip4_addr_set(ip_2_ip4(dest), ip_2_ip4(src)); ip_clear_no4(dest); }}while(0)
+/** @ingroup ipaddr */
+#define ip_addr_set_ipaddr(dest, src) ip_addr_set(dest, src)
+/** @ingroup ipaddr */
+#define ip_addr_set_zero(ipaddr)     do{ \
+  ip6_addr_set_zero(ip_2_ip6(ipaddr)); IP_SET_TYPE(ipaddr, 0); }while(0)
+/** @ingroup ip5addr */
+#define ip_addr_set_zero_ip4(ipaddr)     do{ \
+  ip6_addr_set_zero(ip_2_ip6(ipaddr)); IP_SET_TYPE(ipaddr, IPADDR_TYPE_V4); }while(0)
+/** @ingroup ip6addr */
+#define ip_addr_set_zero_ip6(ipaddr)     do{ \
+  ip6_addr_set_zero(ip_2_ip6(ipaddr)); IP_SET_TYPE(ipaddr, IPADDR_TYPE_V6); }while(0)
+/** @ingroup ipaddr */
+#define ip_addr_set_any(is_ipv6, ipaddr)      do{if(is_ipv6){ \
+  ip6_addr_set_any(ip_2_ip6(ipaddr)); IP_SET_TYPE(ipaddr, IPADDR_TYPE_V6); }else{ \
+  ip4_addr_set_any(ip_2_ip4(ipaddr)); IP_SET_TYPE(ipaddr, IPADDR_TYPE_V4); ip_clear_no4(ipaddr); }}while(0)
+/** @ingroup ipaddr */
+#define ip_addr_set_any_val(is_ipv6, ipaddr)      do{if(is_ipv6){ \
+  ip6_addr_set_any(ip_2_ip6(&(ipaddr))); IP_SET_TYPE_VAL(ipaddr, IPADDR_TYPE_V6); }else{ \
+  ip4_addr_set_any(ip_2_ip4(&(ipaddr))); IP_SET_TYPE_VAL(ipaddr, IPADDR_TYPE_V4); ip_clear_no4(&ipaddr); }}while(0)
+/** @ingroup ipaddr */
+#define ip_addr_set_loopback(is_ipv6, ipaddr) do{if(is_ipv6){ \
+  ip6_addr_set_loopback(ip_2_ip6(ipaddr)); IP_SET_TYPE(ipaddr, IPADDR_TYPE_V6); }else{ \
+  ip4_addr_set_loopback(ip_2_ip4(ipaddr)); IP_SET_TYPE(ipaddr, IPADDR_TYPE_V4); ip_clear_no4(ipaddr); }}while(0)
+/** @ingroup ipaddr */
+#define ip_addr_set_loopback_val(is_ipv6, ipaddr) do{if(is_ipv6){ \
+  ip6_addr_set_loopback(ip_2_ip6(&(ipaddr))); IP_SET_TYPE_VAL(ipaddr, IPADDR_TYPE_V6); }else{ \
+  ip4_addr_set_loopback(ip_2_ip4(&(ipaddr))); IP_SET_TYPE_VAL(ipaddr, IPADDR_TYPE_V4); ip_clear_no4(&ipaddr); }}while(0)
+/** @ingroup ipaddr */
+#define ip_addr_set_hton(dest, src)  do{if(IP_IS_V6(src)){ \
+  ip6_addr_set_hton(ip_2_ip6(dest), ip_2_ip6(src)); IP_SET_TYPE(dest, IPADDR_TYPE_V6); }else{ \
+  ip4_addr_set_hton(ip_2_ip4(dest), ip_2_ip4(src)); IP_SET_TYPE(dest, IPADDR_TYPE_V4); ip_clear_no4(ipaddr); }}while(0)
+/** @ingroup ipaddr */
+#define ip_addr_get_network(target, host, netmask) do{if(IP_IS_V6(host)){ \
+  ip4_addr_set_zero(ip_2_ip4(target)); IP_SET_TYPE(target, IPADDR_TYPE_V6); } else { \
+  ip4_addr_get_network(ip_2_ip4(target), ip_2_ip4(host), ip_2_ip4(netmask)); IP_SET_TYPE(target, IPADDR_TYPE_V4); }}while(0)
+/** @ingroup ipaddr */
+#define ip_addr_netcmp(addr1, addr2, mask) ((IP_IS_V6(addr1) && IP_IS_V6(addr2)) ? \
+  0 : \
+  ip4_addr_netcmp(ip_2_ip4(addr1), ip_2_ip4(addr2), mask))
+/** @ingroup ipaddr */
+#define ip_addr_cmp(addr1, addr2)    ((IP_GET_TYPE(addr1) != IP_GET_TYPE(addr2)) ? 0 : (IP_IS_V6_VAL(*(addr1)) ? \
+  ip6_addr_cmp(ip_2_ip6(addr1), ip_2_ip6(addr2)) : \
+  ip4_addr_cmp(ip_2_ip4(addr1), ip_2_ip4(addr2))))
+/** @ingroup ipaddr */
+#define ip_addr_cmp_zoneless(addr1, addr2)    ((IP_GET_TYPE(addr1) != IP_GET_TYPE(addr2)) ? 0 : (IP_IS_V6_VAL(*(addr1)) ? \
+  ip6_addr_cmp_zoneless(ip_2_ip6(addr1), ip_2_ip6(addr2)) : \
+  ip4_addr_cmp(ip_2_ip4(addr1), ip_2_ip4(addr2))))
+/** @ingroup ipaddr */
+#define ip_addr_isany(ipaddr)        (((ipaddr) == NULL) ? 1 : ((IP_IS_V6(ipaddr)) ? \
+  ip6_addr_isany(ip_2_ip6(ipaddr)) : \
+  ip4_addr_isany(ip_2_ip4(ipaddr))))
+/** @ingroup ipaddr */
+#define ip_addr_isany_val(ipaddr)        ((IP_IS_V6_VAL(ipaddr)) ? \
+  ip6_addr_isany_val(*ip_2_ip6(&(ipaddr))) : \
+  ip4_addr_isany_val(*ip_2_ip4(&(ipaddr))))
+/** @ingroup ipaddr */
+#define ip_addr_isbroadcast(ipaddr, netif) ((IP_IS_V6(ipaddr)) ? \
+  0 : \
+  ip4_addr_isbroadcast(ip_2_ip4(ipaddr), netif))
+/** @ingroup ipaddr */
+#define ip_addr_ismulticast(ipaddr)  ((IP_IS_V6(ipaddr)) ? \
+  ip6_addr_ismulticast(ip_2_ip6(ipaddr)) : \
+  ip4_addr_ismulticast(ip_2_ip4(ipaddr)))
+/** @ingroup ipaddr */
+#define ip_addr_isloopback(ipaddr)  ((IP_IS_V6(ipaddr)) ? \
+  ip6_addr_isloopback(ip_2_ip6(ipaddr)) : \
+  ip4_addr_isloopback(ip_2_ip4(ipaddr)))
+/** @ingroup ipaddr */
+#define ip_addr_islinklocal(ipaddr)  ((IP_IS_V6(ipaddr)) ? \
+  ip6_addr_islinklocal(ip_2_ip6(ipaddr)) : \
+  ip4_addr_islinklocal(ip_2_ip4(ipaddr)))
+#define ip_addr_debug_print(debug, ipaddr) do { if(IP_IS_V6(ipaddr)) { \
+  ip6_addr_debug_print(debug, ip_2_ip6(ipaddr)); } else { \
+  ip4_addr_debug_print(debug, ip_2_ip4(ipaddr)); }}while(0)
+#define ip_addr_debug_print_val(debug, ipaddr) do { if(IP_IS_V6_VAL(ipaddr)) { \
+  ip6_addr_debug_print_val(debug, *ip_2_ip6(&(ipaddr))); } else { \
+  ip4_addr_debug_print_val(debug, *ip_2_ip4(&(ipaddr))); }}while(0)
+char *ipaddr_ntoa(const ip_addr_t *addr);
+char *ipaddr_ntoa_r(const ip_addr_t *addr, char *buf, int buflen);
+int ipaddr_aton(const char *cp, ip_addr_t *addr);
+
+/** @ingroup ipaddr */
+#define IPADDR_STRLEN_MAX   IP6ADDR_STRLEN_MAX
+
+/** @ingroup ipaddr */
+#define ip4_2_ipv4_mapped_ipv6(ip6addr, ip4addr) do { \
+  (ip6addr)->addr[3] = (ip4addr)->addr; \
+  (ip6addr)->addr[2] = PP_HTONL(0x0000FFFFUL); \
+  (ip6addr)->addr[1] = 0; \
+  (ip6addr)->addr[0] = 0; \
+  ip6_addr_clear_zone(ip6addr); } while(0);
+
+/** @ingroup ipaddr */
+#define unmap_ipv4_mapped_ipv6(ip4addr, ip6addr) \
+  (ip4addr)->addr = (ip6addr)->addr[3];
+
+#define IP46_ADDR_ANY(type) (((type) == IPADDR_TYPE_V6)? IP6_ADDR_ANY : IP4_ADDR_ANY)
+
+#else /* LWIP_IPV4 && LWIP_IPV6 */
+
+#define IP_ADDR_PCB_VERSION_MATCH(addr, pcb)          1
+#define IP_ADDR_PCB_VERSION_MATCH_EXACT(pcb, ipaddr)  1
+
+#define ip_addr_set_any_val(is_ipv6, ipaddr)          ip_addr_set_any(is_ipv6, &(ipaddr))
+#define ip_addr_set_loopback_val(is_ipv6, ipaddr)     ip_addr_set_loopback(is_ipv6, &(ipaddr))
+
+#if LWIP_IPV4
+
+typedef ip4_addr_t ip_addr_t;
+#define IPADDR4_INIT(u32val)                    { u32val }
+#define IPADDR4_INIT_BYTES(a,b,c,d)             IPADDR4_INIT(PP_HTONL(LWIP_MAKEU32(a,b,c,d)))
+#define IP_IS_V4_VAL(ipaddr)                    1
+#define IP_IS_V6_VAL(ipaddr)                    0
+#define IP_IS_V4(ipaddr)                        1
+#define IP_IS_V6(ipaddr)                        0
+#define IP_IS_ANY_TYPE_VAL(ipaddr)              0
+#define IP_SET_TYPE_VAL(ipaddr, iptype)
+#define IP_SET_TYPE(ipaddr, iptype)
+#define IP_GET_TYPE(ipaddr)                     IPADDR_TYPE_V4
+#define IP_ADDR_RAW_SIZE(ipaddr)                sizeof(ip4_addr_t)
+#define ip_2_ip4(ipaddr)                        (ipaddr)
+#define IP_ADDR4(ipaddr,a,b,c,d)                IP4_ADDR(ipaddr,a,b,c,d)
+
+#define ip_addr_copy(dest, src)                 ip4_addr_copy(dest, src)
+#define ip_addr_copy_from_ip4(dest, src)        ip4_addr_copy(dest, src)
+#define ip_addr_set_ip4_u32(ipaddr, val)        ip4_addr_set_u32(ip_2_ip4(ipaddr), val)
+#define ip_addr_set_ip4_u32_val(ipaddr, val)    ip_addr_set_ip4_u32(&(ipaddr), val)
+#define ip_addr_get_ip4_u32(ipaddr)             ip4_addr_get_u32(ip_2_ip4(ipaddr))
+#define ip_addr_set(dest, src)                  ip4_addr_set(dest, src)
+#define ip_addr_set_ipaddr(dest, src)           ip4_addr_set(dest, src)
+#define ip_addr_set_zero(ipaddr)                ip4_addr_set_zero(ipaddr)
+#define ip_addr_set_zero_ip4(ipaddr)            ip4_addr_set_zero(ipaddr)
+#define ip_addr_set_any(is_ipv6, ipaddr)        ip4_addr_set_any(ipaddr)
+#define ip_addr_set_loopback(is_ipv6, ipaddr)   ip4_addr_set_loopback(ipaddr)
+#define ip_addr_set_hton(dest, src)             ip4_addr_set_hton(dest, src)
+#define ip_addr_get_network(target, host, mask) ip4_addr_get_network(target, host, mask)
+#define ip_addr_netcmp(addr1, addr2, mask)      ip4_addr_netcmp(addr1, addr2, mask)
+#define ip_addr_cmp(addr1, addr2)               ip4_addr_cmp(addr1, addr2)
+#define ip_addr_isany(ipaddr)                   ip4_addr_isany(ipaddr)
+#define ip_addr_isany_val(ipaddr)               ip4_addr_isany_val(ipaddr)
+#define ip_addr_isloopback(ipaddr)              ip4_addr_isloopback(ipaddr)
+#define ip_addr_islinklocal(ipaddr)             ip4_addr_islinklocal(ipaddr)
+#define ip_addr_isbroadcast(addr, netif)        ip4_addr_isbroadcast(addr, netif)
+#define ip_addr_ismulticast(ipaddr)             ip4_addr_ismulticast(ipaddr)
+#define ip_addr_debug_print(debug, ipaddr)      ip4_addr_debug_print(debug, ipaddr)
+#define ip_addr_debug_print_val(debug, ipaddr)  ip4_addr_debug_print_val(debug, ipaddr)
+#define ipaddr_ntoa(ipaddr)                     ip4addr_ntoa(ipaddr)
+#define ipaddr_ntoa_r(ipaddr, buf, buflen)      ip4addr_ntoa_r(ipaddr, buf, buflen)
+#define ipaddr_aton(cp, addr)                   ip4addr_aton(cp, addr)
+
+#define IPADDR_STRLEN_MAX   IP4ADDR_STRLEN_MAX
+
+#define IP46_ADDR_ANY(type) (IP4_ADDR_ANY)
+
+#else /* LWIP_IPV4 */
+
+typedef ip6_addr_t ip_addr_t;
+#define IPADDR6_INIT(a, b, c, d)                { { a, b, c, d } IPADDR6_ZONE_INIT }
+#define IPADDR6_INIT_HOST(a, b, c, d)           { { PP_HTONL(a), PP_HTONL(b), PP_HTONL(c), PP_HTONL(d) } IPADDR6_ZONE_INIT }
+#define IP_IS_V4_VAL(ipaddr)                    0
+#define IP_IS_V6_VAL(ipaddr)                    1
+#define IP_IS_V4(ipaddr)                        0
+#define IP_IS_V6(ipaddr)                        1
+#define IP_IS_ANY_TYPE_VAL(ipaddr)              0
+#define IP_SET_TYPE_VAL(ipaddr, iptype)
+#define IP_SET_TYPE(ipaddr, iptype)
+#define IP_GET_TYPE(ipaddr)                     IPADDR_TYPE_V6
+#define IP_ADDR_RAW_SIZE(ipaddr)                sizeof(ip6_addr_t)
+#define ip_2_ip6(ipaddr)                        (ipaddr)
+#define IP_ADDR6(ipaddr,i0,i1,i2,i3)            IP6_ADDR(ipaddr,i0,i1,i2,i3)
+#define IP_ADDR6_HOST(ipaddr,i0,i1,i2,i3)       IP_ADDR6(ipaddr,PP_HTONL(i0),PP_HTONL(i1),PP_HTONL(i2),PP_HTONL(i3))
+
+#define ip_addr_copy(dest, src)                 ip6_addr_copy(dest, src)
+#define ip_addr_copy_from_ip6(dest, src)        ip6_addr_copy(dest, src)
+#define ip_addr_copy_from_ip6_packed(dest, src) ip6_addr_copy_from_packed(dest, src)
+#define ip_addr_set(dest, src)                  ip6_addr_set(dest, src)
+#define ip_addr_set_ipaddr(dest, src)           ip6_addr_set(dest, src)
+#define ip_addr_set_zero(ipaddr)                ip6_addr_set_zero(ipaddr)
+#define ip_addr_set_zero_ip6(ipaddr)            ip6_addr_set_zero(ipaddr)
+#define ip_addr_set_any(is_ipv6, ipaddr)        ip6_addr_set_any(ipaddr)
+#define ip_addr_set_loopback(is_ipv6, ipaddr)   ip6_addr_set_loopback(ipaddr)
+#define ip_addr_set_hton(dest, src)             ip6_addr_set_hton(dest, src)
+#define ip_addr_get_network(target, host, mask) ip6_addr_set_zero(target)
+#define ip_addr_netcmp(addr1, addr2, mask)      0
+#define ip_addr_cmp(addr1, addr2)               ip6_addr_cmp(addr1, addr2)
+#define ip_addr_cmp_zoneless(addr1, addr2)      ip6_addr_cmp_zoneless(addr1, addr2)
+#define ip_addr_isany(ipaddr)                   ip6_addr_isany(ipaddr)
+#define ip_addr_isany_val(ipaddr)               ip6_addr_isany_val(ipaddr)
+#define ip_addr_isloopback(ipaddr)              ip6_addr_isloopback(ipaddr)
+#define ip_addr_islinklocal(ipaddr)             ip6_addr_islinklocal(ipaddr)
+#define ip_addr_isbroadcast(addr, netif)        0
+#define ip_addr_ismulticast(ipaddr)             ip6_addr_ismulticast(ipaddr)
+#define ip_addr_debug_print(debug, ipaddr)      ip6_addr_debug_print(debug, ipaddr)
+#define ip_addr_debug_print_val(debug, ipaddr)  ip6_addr_debug_print_val(debug, ipaddr)
+#define ipaddr_ntoa(ipaddr)                     ip6addr_ntoa(ipaddr)
+#define ipaddr_ntoa_r(ipaddr, buf, buflen)      ip6addr_ntoa_r(ipaddr, buf, buflen)
+#define ipaddr_aton(cp, addr)                   ip6addr_aton(cp, addr)
+
+#define IPADDR_STRLEN_MAX   IP6ADDR_STRLEN_MAX
+
+#define IP46_ADDR_ANY(type) (IP6_ADDR_ANY)
+
+#endif /* LWIP_IPV4 */
+#endif /* LWIP_IPV4 && LWIP_IPV6 */
+
+#if LWIP_IPV4
+
+extern const ip_addr_t ip_addr_any;
+extern const ip_addr_t ip_addr_broadcast;
+
+/**
+ * @ingroup ip4addr
+ * Can be used as a fixed/const ip_addr_t
+ * for the IP wildcard.
+ * Defined to @ref IP4_ADDR_ANY when IPv4 is enabled.
+ * Defined to @ref IP6_ADDR_ANY in IPv6 only systems.
+ * Use this if you can handle IPv4 _AND_ IPv6 addresses.
+ * Use @ref IP4_ADDR_ANY or @ref IP6_ADDR_ANY when the IP
+ * type matters.
+ */
+#define IP_ADDR_ANY         IP4_ADDR_ANY
+/**
+ * @ingroup ip4addr
+ * Can be used as a fixed/const ip_addr_t
+ * for the IPv4 wildcard and the broadcast address
+ */
+#define IP4_ADDR_ANY        (&ip_addr_any)
+/**
+ * @ingroup ip4addr
+ * Can be used as a fixed/const ip4_addr_t
+ * for the wildcard and the broadcast address
+ */
+#define IP4_ADDR_ANY4       (ip_2_ip4(&ip_addr_any))
+
+/** @ingroup ip4addr */
+#define IP_ADDR_BROADCAST   (&ip_addr_broadcast)
+/** @ingroup ip4addr */
+#define IP4_ADDR_BROADCAST  (ip_2_ip4(&ip_addr_broadcast))
+
+#endif /* LWIP_IPV4*/
+
+#if LWIP_IPV6
+
+extern const ip_addr_t ip6_addr_any;
+
+/** 
+ * @ingroup ip6addr
+ * IP6_ADDR_ANY can be used as a fixed ip_addr_t
+ * for the IPv6 wildcard address
+ */
+#define IP6_ADDR_ANY   (&ip6_addr_any)
+/**
+ * @ingroup ip6addr
+ * IP6_ADDR_ANY6 can be used as a fixed ip6_addr_t
+ * for the IPv6 wildcard address
+ */
+#define IP6_ADDR_ANY6  (ip_2_ip6(&ip6_addr_any))
+
+#if !LWIP_IPV4
+/** IPv6-only configurations */
+#define IP_ADDR_ANY IP6_ADDR_ANY
+#endif /* !LWIP_IPV4 */
+
+#endif
+
+#if LWIP_IPV4 && LWIP_IPV6
+/** @ingroup ipaddr */
+#define IP_ANY_TYPE    (&ip_addr_any_type)
+#else
+#define IP_ANY_TYPE    IP_ADDR_ANY
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LWIP_HDR_IP_ADDR_H */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/mem.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/mem.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/mem.h	(revision 457)
@@ -0,0 +1,82 @@
+/**
+ * @file
+ * Heap API
+ */
+
+/*
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Adam Dunkels <adam@sics.se>
+ *
+ */
+#ifndef LWIP_HDR_MEM_H
+#define LWIP_HDR_MEM_H
+
+#include "lwip/opt.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if MEM_LIBC_MALLOC
+
+#include "lwip/arch.h"
+
+typedef size_t mem_size_t;
+#define MEM_SIZE_F SZT_F
+
+#elif MEM_USE_POOLS
+
+typedef u16_t mem_size_t;
+#define MEM_SIZE_F U16_F
+
+#else
+
+/* MEM_SIZE would have to be aligned, but using 64000 here instead of
+ * 65535 leaves some room for alignment...
+ */
+#if MEM_SIZE > 64000L
+typedef u32_t mem_size_t;
+#define MEM_SIZE_F U32_F
+#else
+typedef u16_t mem_size_t;
+#define MEM_SIZE_F U16_F
+#endif /* MEM_SIZE > 64000 */
+#endif
+
+void  mem_init(void);
+void *mem_trim(void *mem, mem_size_t size);
+void *mem_malloc(mem_size_t size);
+void *mem_calloc(mem_size_t count, mem_size_t size);
+void  mem_free(void *mem);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LWIP_HDR_MEM_H */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/memp.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/memp.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/memp.h	(revision 457)
@@ -0,0 +1,155 @@
+/**
+ * @file
+ * Memory pool API
+ */
+
+/*
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Adam Dunkels <adam@sics.se>
+ *
+ */
+
+#ifndef LWIP_HDR_MEMP_H
+#define LWIP_HDR_MEMP_H
+
+#include "lwip/opt.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* run once with empty definition to handle all custom includes in lwippools.h */
+#define LWIP_MEMPOOL(name,num,size,desc)
+#include "lwip/priv/memp_std.h"
+
+/** Create the list of all memory pools managed by memp. MEMP_MAX represents a NULL pool at the end */
+typedef enum {
+#define LWIP_MEMPOOL(name,num,size,desc)  MEMP_##name,
+#include "lwip/priv/memp_std.h"
+  MEMP_MAX
+} memp_t;
+
+#include "lwip/priv/memp_priv.h"
+#include "lwip/stats.h"
+
+extern const struct memp_desc* const memp_pools[MEMP_MAX];
+
+/**
+ * @ingroup mempool
+ * Declare prototype for private memory pool if it is used in multiple files
+ */
+#define LWIP_MEMPOOL_PROTOTYPE(name) extern const struct memp_desc memp_ ## name
+
+#if MEMP_MEM_MALLOC
+
+#define LWIP_MEMPOOL_DECLARE(name,num,size,desc) \
+  LWIP_MEMPOOL_DECLARE_STATS_INSTANCE(memp_stats_ ## name) \
+  const struct memp_desc memp_ ## name = { \
+    DECLARE_LWIP_MEMPOOL_DESC(desc) \
+    LWIP_MEMPOOL_DECLARE_STATS_REFERENCE(memp_stats_ ## name) \
+    LWIP_MEM_ALIGN_SIZE(size) \
+  };
+
+#else /* MEMP_MEM_MALLOC */
+
+/**
+ * @ingroup mempool
+ * Declare a private memory pool
+ * Private mempools example:
+ * .h: only when pool is used in multiple .c files: LWIP_MEMPOOL_PROTOTYPE(my_private_pool);
+ * .c:
+ *   - in global variables section: LWIP_MEMPOOL_DECLARE(my_private_pool, 10, sizeof(foo), "Some description")
+ *   - call ONCE before using pool (e.g. in some init() function): LWIP_MEMPOOL_INIT(my_private_pool);
+ *   - allocate: void* my_new_mem = LWIP_MEMPOOL_ALLOC(my_private_pool);
+ *   - free: LWIP_MEMPOOL_FREE(my_private_pool, my_new_mem);
+ *
+ * To relocate a pool, declare it as extern in cc.h. Example for GCC:
+ *   extern u8_t \_\_attribute\_\_((section(".onchip_mem"))) memp_memory_my_private_pool_base[];
+ */
+#define LWIP_MEMPOOL_DECLARE(name,num,size,desc) \
+  LWIP_DECLARE_MEMORY_ALIGNED(memp_memory_ ## name ## _base, ((num) * (MEMP_SIZE + MEMP_ALIGN_SIZE(size)))); \
+    \
+  LWIP_MEMPOOL_DECLARE_STATS_INSTANCE(memp_stats_ ## name) \
+    \
+  static struct memp *memp_tab_ ## name; \
+    \
+  const struct memp_desc memp_ ## name = { \
+    DECLARE_LWIP_MEMPOOL_DESC(desc) \
+    LWIP_MEMPOOL_DECLARE_STATS_REFERENCE(memp_stats_ ## name) \
+    LWIP_MEM_ALIGN_SIZE(size), \
+    (num), \
+    memp_memory_ ## name ## _base, \
+    &memp_tab_ ## name \
+  };
+
+#endif /* MEMP_MEM_MALLOC */
+
+/**
+ * @ingroup mempool
+ * Initialize a private memory pool
+ */
+#define LWIP_MEMPOOL_INIT(name)    memp_init_pool(&memp_ ## name)
+/**
+ * @ingroup mempool
+ * Allocate from a private memory pool
+ */
+#define LWIP_MEMPOOL_ALLOC(name)   memp_malloc_pool(&memp_ ## name)
+/**
+ * @ingroup mempool
+ * Free element from a private memory pool
+ */
+#define LWIP_MEMPOOL_FREE(name, x) memp_free_pool(&memp_ ## name, (x))
+
+#if MEM_USE_POOLS
+/** This structure is used to save the pool one element came from.
+ * This has to be defined here as it is required for pool size calculation. */
+struct memp_malloc_helper
+{
+   memp_t poolnr;
+#if MEMP_OVERFLOW_CHECK || (LWIP_STATS && MEM_STATS)
+   u16_t size;
+#endif /* MEMP_OVERFLOW_CHECK || (LWIP_STATS && MEM_STATS) */
+};
+#endif /* MEM_USE_POOLS */
+
+void  memp_init(void);
+
+#if MEMP_OVERFLOW_CHECK
+void *memp_malloc_fn(memp_t type, const char* file, const int line);
+#define memp_malloc(t) memp_malloc_fn((t), __FILE__, __LINE__)
+#else
+void *memp_malloc(memp_t type);
+#endif
+void  memp_free(memp_t type, void *mem);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LWIP_HDR_MEMP_H */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/mld6.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/mld6.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/mld6.h	(revision 457)
@@ -0,0 +1,99 @@
+/**
+ * @file
+ *
+ * Multicast listener discovery for IPv6. Aims to be compliant with RFC 2710.
+ * No support for MLDv2.
+ */
+
+/*
+ * Copyright (c) 2010 Inico Technologies Ltd.
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Ivan Delamer <delamer@inicotech.com>
+ *
+ *
+ * Please coordinate changes and requests with Ivan Delamer
+ * <delamer@inicotech.com>
+ */
+
+#ifndef LWIP_HDR_MLD6_H
+#define LWIP_HDR_MLD6_H
+
+#include "lwip/opt.h"
+
+#if LWIP_IPV6_MLD && LWIP_IPV6  /* don't build if not configured for use in lwipopts.h */
+
+#include "lwip/pbuf.h"
+#include "lwip/netif.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** MLD group */
+struct mld_group {
+  /** next link */
+  struct mld_group *next;
+  /** multicast address */
+  ip6_addr_t         group_address;
+  /** signifies we were the last person to report */
+  u8_t               last_reporter_flag;
+  /** current state of the group */
+  u8_t               group_state;
+  /** timer for reporting */
+  u16_t              timer;
+  /** counter of simultaneous uses */
+  u8_t               use;
+};
+
+#define MLD6_TMR_INTERVAL              100 /* Milliseconds */
+
+err_t  mld6_stop(struct netif *netif);
+void   mld6_report_groups(struct netif *netif);
+void   mld6_tmr(void);
+struct mld_group *mld6_lookfor_group(struct netif *ifp, const ip6_addr_t *addr);
+void   mld6_input(struct pbuf *p, struct netif *inp);
+err_t  mld6_joingroup(const ip6_addr_t *srcaddr, const ip6_addr_t *groupaddr);
+err_t  mld6_joingroup_netif(struct netif *netif, const ip6_addr_t *groupaddr);
+err_t  mld6_leavegroup(const ip6_addr_t *srcaddr, const ip6_addr_t *groupaddr);
+err_t  mld6_leavegroup_netif(struct netif *netif, const ip6_addr_t *groupaddr);
+
+/** @ingroup mld6
+ * Get list head of MLD6 groups for netif.
+ * Note: The allnodes group IP is NOT in the list, since it must always 
+ * be received for correct IPv6 operation.
+ * @see @ref netif_set_mld_mac_filter()
+ */
+#define netif_mld6_data(netif) ((struct mld_group *)netif_get_client_data(netif, LWIP_NETIF_CLIENT_DATA_INDEX_MLD6))
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LWIP_IPV6_MLD && LWIP_IPV6 */
+
+#endif /* LWIP_HDR_MLD6_H */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/nd6.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/nd6.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/nd6.h	(revision 457)
@@ -0,0 +1,90 @@
+/**
+ * @file
+ *
+ * Neighbor discovery and stateless address autoconfiguration for IPv6.
+ * Aims to be compliant with RFC 4861 (Neighbor discovery) and RFC 4862
+ * (Address autoconfiguration).
+ */
+
+/*
+ * Copyright (c) 2010 Inico Technologies Ltd.
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Ivan Delamer <delamer@inicotech.com>
+ *
+ *
+ * Please coordinate changes and requests with Ivan Delamer
+ * <delamer@inicotech.com>
+ */
+
+#ifndef LWIP_HDR_ND6_H
+#define LWIP_HDR_ND6_H
+
+#include "lwip/opt.h"
+
+#if LWIP_IPV6  /* don't build if not configured for use in lwipopts.h */
+
+#include "lwip/ip6_addr.h"
+#include "lwip/err.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** 1 second period */
+#define ND6_TMR_INTERVAL 1000
+
+/** Router solicitations are sent in 4 second intervals (see RFC 4861, ch. 6.3.7) */
+#ifndef ND6_RTR_SOLICITATION_INTERVAL
+#define ND6_RTR_SOLICITATION_INTERVAL  4000
+#endif
+
+struct pbuf;
+struct netif;
+
+void nd6_tmr(void);
+void nd6_input(struct pbuf *p, struct netif *inp);
+void nd6_clear_destination_cache(void);
+struct netif *nd6_find_route(const ip6_addr_t *ip6addr);
+err_t nd6_get_next_hop_addr_or_queue(struct netif *netif, struct pbuf *q, const ip6_addr_t *ip6addr, const u8_t **hwaddrp);
+u16_t nd6_get_destination_mtu(const ip6_addr_t *ip6addr, struct netif *netif);
+#if LWIP_ND6_TCP_REACHABILITY_HINTS
+void nd6_reachability_hint(const ip6_addr_t *ip6addr);
+#endif /* LWIP_ND6_TCP_REACHABILITY_HINTS */
+void nd6_cleanup_netif(struct netif *netif);
+#if LWIP_IPV6_MLD
+void nd6_adjust_mld_membership(struct netif *netif, s8_t addr_idx, u8_t new_state);
+#endif /* LWIP_IPV6_MLD */
+void nd6_restart_netif(struct netif *netif);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LWIP_IPV6 */
+
+#endif /* LWIP_HDR_ND6_H */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/netbuf.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/netbuf.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/netbuf.h	(revision 457)
@@ -0,0 +1,116 @@
+/**
+ * @file
+ * netbuf API (for netconn API)
+ */
+
+/*
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Adam Dunkels <adam@sics.se>
+ *
+ */
+#ifndef LWIP_HDR_NETBUF_H
+#define LWIP_HDR_NETBUF_H
+
+#include "lwip/opt.h"
+
+#if LWIP_NETCONN || LWIP_SOCKET /* don't build if not configured for use in lwipopts.h */
+/* Note: Netconn API is always available when sockets are enabled -
+ * sockets are implemented on top of them */
+
+#include "lwip/pbuf.h"
+#include "lwip/ip_addr.h"
+#include "lwip/ip6_addr.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** This netbuf has dest-addr/port set */
+#define NETBUF_FLAG_DESTADDR    0x01
+/** This netbuf includes a checksum */
+#define NETBUF_FLAG_CHKSUM      0x02
+
+/** "Network buffer" - contains data and addressing info */
+struct netbuf {
+  struct pbuf *p, *ptr;
+  ip_addr_t addr;
+  u16_t port;
+#if LWIP_NETBUF_RECVINFO || LWIP_CHECKSUM_ON_COPY
+  u8_t flags;
+  u16_t toport_chksum;
+#if LWIP_NETBUF_RECVINFO
+  ip_addr_t toaddr;
+#endif /* LWIP_NETBUF_RECVINFO */
+#endif /* LWIP_NETBUF_RECVINFO || LWIP_CHECKSUM_ON_COPY */
+};
+
+/* Network buffer functions: */
+struct netbuf *   netbuf_new      (void);
+void              netbuf_delete   (struct netbuf *buf);
+void *            netbuf_alloc    (struct netbuf *buf, u16_t size);
+void              netbuf_free     (struct netbuf *buf);
+err_t             netbuf_ref      (struct netbuf *buf,
+                                   const void *dataptr, u16_t size);
+void              netbuf_chain    (struct netbuf *head, struct netbuf *tail);
+
+err_t             netbuf_data     (struct netbuf *buf,
+                                   void **dataptr, u16_t *len);
+s8_t              netbuf_next     (struct netbuf *buf);
+void              netbuf_first    (struct netbuf *buf);
+
+
+#define netbuf_copy_partial(buf, dataptr, len, offset) \
+  pbuf_copy_partial((buf)->p, (dataptr), (len), (offset))
+#define netbuf_copy(buf,dataptr,len) netbuf_copy_partial(buf, dataptr, len, 0)
+#define netbuf_take(buf, dataptr, len) pbuf_take((buf)->p, dataptr, len)
+#define netbuf_len(buf)              ((buf)->p->tot_len)
+#define netbuf_fromaddr(buf)         (&((buf)->addr))
+#define netbuf_set_fromaddr(buf, fromaddr) ip_addr_set(&((buf)->addr), fromaddr)
+#define netbuf_fromport(buf)         ((buf)->port)
+#if LWIP_NETBUF_RECVINFO
+#define netbuf_destaddr(buf)         (&((buf)->toaddr))
+#define netbuf_set_destaddr(buf, destaddr) ip_addr_set(&((buf)->toaddr), destaddr)
+#if LWIP_CHECKSUM_ON_COPY
+#define netbuf_destport(buf)         (((buf)->flags & NETBUF_FLAG_DESTADDR) ? (buf)->toport_chksum : 0)
+#else /* LWIP_CHECKSUM_ON_COPY */
+#define netbuf_destport(buf)         ((buf)->toport_chksum)
+#endif /* LWIP_CHECKSUM_ON_COPY */
+#endif /* LWIP_NETBUF_RECVINFO */
+#if LWIP_CHECKSUM_ON_COPY
+#define netbuf_set_chksum(buf, chksum) do { (buf)->flags = NETBUF_FLAG_CHKSUM; \
+                                            (buf)->toport_chksum = chksum; } while(0)
+#endif /* LWIP_CHECKSUM_ON_COPY */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LWIP_NETCONN || LWIP_SOCKET */
+
+#endif /* LWIP_HDR_NETBUF_H */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/netdb.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/netdb.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/netdb.h	(revision 457)
@@ -0,0 +1,150 @@
+/**
+ * @file
+ * NETDB API (sockets)
+ */
+
+/*
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Simon Goldschmidt
+ *
+ */
+#ifndef LWIP_HDR_NETDB_H
+#define LWIP_HDR_NETDB_H
+
+#include "lwip/opt.h"
+
+#if LWIP_DNS && LWIP_SOCKET
+
+#include "lwip/arch.h"
+#include "lwip/inet.h"
+#include "lwip/sockets.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* some rarely used options */
+#ifndef LWIP_DNS_API_DECLARE_H_ERRNO
+#define LWIP_DNS_API_DECLARE_H_ERRNO  1
+#endif
+
+#ifndef LWIP_DNS_API_DEFINE_ERRORS
+#define LWIP_DNS_API_DEFINE_ERRORS    1
+#endif
+
+#ifndef LWIP_DNS_API_DEFINE_FLAGS
+#define LWIP_DNS_API_DEFINE_FLAGS     1
+#endif
+
+#ifndef LWIP_DNS_API_DECLARE_STRUCTS
+#define LWIP_DNS_API_DECLARE_STRUCTS  1
+#endif
+
+#if LWIP_DNS_API_DEFINE_ERRORS
+/** Errors used by the DNS API functions, h_errno can be one of them */
+#define EAI_NONAME      200
+#define EAI_SERVICE     201
+#define EAI_FAIL        202
+#define EAI_MEMORY      203
+#define EAI_FAMILY      204
+
+#define HOST_NOT_FOUND  210
+#define NO_DATA         211
+#define NO_RECOVERY     212
+#define TRY_AGAIN       213
+#endif /* LWIP_DNS_API_DEFINE_ERRORS */
+
+#if LWIP_DNS_API_DEFINE_FLAGS
+/* input flags for struct addrinfo */
+#define AI_PASSIVE      0x01
+#define AI_CANONNAME    0x02
+#define AI_NUMERICHOST  0x04
+#define AI_NUMERICSERV  0x08
+#define AI_V4MAPPED     0x10
+#define AI_ALL          0x20
+#define AI_ADDRCONFIG   0x40
+#endif /* LWIP_DNS_API_DEFINE_FLAGS */
+
+#if LWIP_DNS_API_DECLARE_STRUCTS
+struct hostent {
+    char  *h_name;      /* Official name of the host. */
+    char **h_aliases;   /* A pointer to an array of pointers to alternative host names,
+                           terminated by a null pointer. */
+    int    h_addrtype;  /* Address type. */
+    int    h_length;    /* The length, in bytes, of the address. */
+    char **h_addr_list; /* A pointer to an array of pointers to network addresses (in
+                           network byte order) for the host, terminated by a null pointer. */
+#define h_addr h_addr_list[0] /* for backward compatibility */
+};
+
+struct addrinfo {
+    int               ai_flags;      /* Input flags. */
+    int               ai_family;     /* Address family of socket. */
+    int               ai_socktype;   /* Socket type. */
+    int               ai_protocol;   /* Protocol of socket. */
+    socklen_t         ai_addrlen;    /* Length of socket address. */
+    struct sockaddr  *ai_addr;       /* Socket address of socket. */
+    char             *ai_canonname;  /* Canonical name of service location. */
+    struct addrinfo  *ai_next;       /* Pointer to next in list. */
+};
+#endif /* LWIP_DNS_API_DECLARE_STRUCTS */
+
+#define NETDB_ELEM_SIZE           (sizeof(struct addrinfo) + sizeof(struct sockaddr_storage) + DNS_MAX_NAME_LENGTH + 1)
+
+#if LWIP_DNS_API_DECLARE_H_ERRNO
+/* application accessible error code set by the DNS API functions */
+extern int h_errno;
+#endif /* LWIP_DNS_API_DECLARE_H_ERRNO*/
+
+struct hostent *lwip_gethostbyname(const char *name);
+int lwip_gethostbyname_r(const char *name, struct hostent *ret, char *buf,
+                size_t buflen, struct hostent **result, int *h_errnop);
+void lwip_freeaddrinfo(struct addrinfo *ai);
+int lwip_getaddrinfo(const char *nodename,
+       const char *servname,
+       const struct addrinfo *hints,
+       struct addrinfo **res);
+
+#if LWIP_COMPAT_SOCKETS
+/** @ingroup netdbapi */
+#define gethostbyname(name) lwip_gethostbyname(name)
+/** @ingroup netdbapi */
+#define gethostbyname_r(name, ret, buf, buflen, result, h_errnop) \
+       lwip_gethostbyname_r(name, ret, buf, buflen, result, h_errnop)
+/** @ingroup netdbapi */
+#define freeaddrinfo(addrinfo) lwip_freeaddrinfo(addrinfo)
+/** @ingroup netdbapi */
+#define getaddrinfo(nodname, servname, hints, res) \
+       lwip_getaddrinfo(nodname, servname, hints, res)
+#endif /* LWIP_COMPAT_SOCKETS */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LWIP_DNS && LWIP_SOCKET */
+
+#endif /* LWIP_HDR_NETDB_H */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/netif.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/netif.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/netif.h	(revision 457)
@@ -0,0 +1,669 @@
+/**
+ * @file
+ * netif API (to be used from TCPIP thread)
+ */
+
+/*
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Adam Dunkels <adam@sics.se>
+ *
+ */
+#ifndef LWIP_HDR_NETIF_H
+#define LWIP_HDR_NETIF_H
+
+#include "lwip/opt.h"
+
+#define ENABLE_LOOPBACK (LWIP_NETIF_LOOPBACK || LWIP_HAVE_LOOPIF)
+
+#include "lwip/err.h"
+
+#include "lwip/ip_addr.h"
+
+#include "lwip/def.h"
+#include "lwip/pbuf.h"
+#include "lwip/stats.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Throughout this file, IP addresses are expected to be in
+ * the same byte order as in IP_PCB. */
+
+/** Must be the maximum of all used hardware address lengths
+    across all types of interfaces in use.
+    This does not have to be changed, normally. */
+#ifndef NETIF_MAX_HWADDR_LEN
+#define NETIF_MAX_HWADDR_LEN 6U
+#endif
+
+/** The size of a fully constructed netif name which the
+ * netif can be identified by in APIs. Composed of
+ * 2 chars, 3 (max) digits, and 1 \0
+ */
+#define NETIF_NAMESIZE 6
+
+/**
+ * @defgroup netif_flags Flags
+ * @ingroup netif
+ * @{
+ */
+
+/** Whether the network interface is 'up'. This is
+ * a software flag used to control whether this network
+ * interface is enabled and processes traffic.
+ * It must be set by the startup code before this netif can be used
+ * (also for dhcp/autoip).
+ */
+#define NETIF_FLAG_UP           0x01U
+/** If set, the netif has broadcast capability.
+ * Set by the netif driver in its init function. */
+#define NETIF_FLAG_BROADCAST    0x02U
+/** If set, the interface has an active link
+ *  (set by the network interface driver).
+ * Either set by the netif driver in its init function (if the link
+ * is up at that time) or at a later point once the link comes up
+ * (if link detection is supported by the hardware). */
+#define NETIF_FLAG_LINK_UP      0x04U
+/** If set, the netif is an ethernet device using ARP.
+ * Set by the netif driver in its init function.
+ * Used to check input packet types and use of DHCP. */
+#define NETIF_FLAG_ETHARP       0x08U
+/** If set, the netif is an ethernet device. It might not use
+ * ARP or TCP/IP if it is used for PPPoE only.
+ */
+#define NETIF_FLAG_ETHERNET     0x10U
+/** If set, the netif has IGMP capability.
+ * Set by the netif driver in its init function. */
+#define NETIF_FLAG_IGMP         0x20U
+/** If set, the netif has MLD6 capability.
+ * Set by the netif driver in its init function. */
+#define NETIF_FLAG_MLD6         0x40U
+
+/**
+ * @}
+ */
+
+enum lwip_internal_netif_client_data_index
+{
+#if LWIP_IPV4
+#if LWIP_DHCP
+   LWIP_NETIF_CLIENT_DATA_INDEX_DHCP,
+#endif
+#if LWIP_AUTOIP
+   LWIP_NETIF_CLIENT_DATA_INDEX_AUTOIP,
+#endif
+#if LWIP_IGMP
+   LWIP_NETIF_CLIENT_DATA_INDEX_IGMP,
+#endif
+#endif /* LWIP_IPV4 */
+#if LWIP_IPV6
+#if LWIP_IPV6_DHCP6
+   LWIP_NETIF_CLIENT_DATA_INDEX_DHCP6,
+#endif
+#if LWIP_IPV6_MLD
+   LWIP_NETIF_CLIENT_DATA_INDEX_MLD6,
+#endif
+#endif /* LWIP_IPV6 */
+   LWIP_NETIF_CLIENT_DATA_INDEX_MAX
+};
+
+#if LWIP_CHECKSUM_CTRL_PER_NETIF
+#define NETIF_CHECKSUM_GEN_IP       0x0001
+#define NETIF_CHECKSUM_GEN_UDP      0x0002
+#define NETIF_CHECKSUM_GEN_TCP      0x0004
+#define NETIF_CHECKSUM_GEN_ICMP     0x0008
+#define NETIF_CHECKSUM_GEN_ICMP6    0x0010
+#define NETIF_CHECKSUM_CHECK_IP     0x0100
+#define NETIF_CHECKSUM_CHECK_UDP    0x0200
+#define NETIF_CHECKSUM_CHECK_TCP    0x0400
+#define NETIF_CHECKSUM_CHECK_ICMP   0x0800
+#define NETIF_CHECKSUM_CHECK_ICMP6  0x1000
+#define NETIF_CHECKSUM_ENABLE_ALL   0xFFFF
+#define NETIF_CHECKSUM_DISABLE_ALL  0x0000
+#endif /* LWIP_CHECKSUM_CTRL_PER_NETIF */
+
+struct netif;
+
+/** MAC Filter Actions, these are passed to a netif's igmp_mac_filter or
+ * mld_mac_filter callback function. */
+enum netif_mac_filter_action {
+  /** Delete a filter entry */
+  NETIF_DEL_MAC_FILTER = 0,
+  /** Add a filter entry */
+  NETIF_ADD_MAC_FILTER = 1
+};
+
+/** Function prototype for netif init functions. Set up flags and output/linkoutput
+ * callback functions in this function.
+ *
+ * @param netif The netif to initialize
+ */
+typedef err_t (*netif_init_fn)(struct netif *netif);
+/** Function prototype for netif->input functions. This function is saved as 'input'
+ * callback function in the netif struct. Call it when a packet has been received.
+ *
+ * @param p The received packet, copied into a pbuf
+ * @param inp The netif which received the packet
+ * @return ERR_OK if the packet was handled
+ *         != ERR_OK is the packet was NOT handled, in this case, the caller has
+ *                   to free the pbuf
+ */
+typedef err_t (*netif_input_fn)(struct pbuf *p, struct netif *inp);
+
+#if LWIP_IPV4
+/** Function prototype for netif->output functions. Called by lwIP when a packet
+ * shall be sent. For ethernet netif, set this to 'etharp_output' and set
+ * 'linkoutput'.
+ *
+ * @param netif The netif which shall send a packet
+ * @param p The packet to send (p->payload points to IP header)
+ * @param ipaddr The IP address to which the packet shall be sent
+ */
+typedef err_t (*netif_output_fn)(struct netif *netif, struct pbuf *p,
+       const ip4_addr_t *ipaddr);
+#endif /* LWIP_IPV4*/
+
+#if LWIP_IPV6
+/** Function prototype for netif->output_ip6 functions. Called by lwIP when a packet
+ * shall be sent. For ethernet netif, set this to 'ethip6_output' and set
+ * 'linkoutput'.
+ *
+ * @param netif The netif which shall send a packet
+ * @param p The packet to send (p->payload points to IP header)
+ * @param ipaddr The IPv6 address to which the packet shall be sent
+ */
+typedef err_t (*netif_output_ip6_fn)(struct netif *netif, struct pbuf *p,
+       const ip6_addr_t *ipaddr);
+#endif /* LWIP_IPV6 */
+
+/** Function prototype for netif->linkoutput functions. Only used for ethernet
+ * netifs. This function is called by ARP when a packet shall be sent.
+ *
+ * @param netif The netif which shall send a packet
+ * @param p The packet to send (raw ethernet packet)
+ */
+typedef err_t (*netif_linkoutput_fn)(struct netif *netif, struct pbuf *p);
+/** Function prototype for netif status- or link-callback functions. */
+typedef void (*netif_status_callback_fn)(struct netif *netif);
+#if LWIP_IPV4 && LWIP_IGMP
+/** Function prototype for netif igmp_mac_filter functions */
+typedef err_t (*netif_igmp_mac_filter_fn)(struct netif *netif,
+       const ip4_addr_t *group, enum netif_mac_filter_action action);
+#endif /* LWIP_IPV4 && LWIP_IGMP */
+#if LWIP_IPV6 && LWIP_IPV6_MLD
+/** Function prototype for netif mld_mac_filter functions */
+typedef err_t (*netif_mld_mac_filter_fn)(struct netif *netif,
+       const ip6_addr_t *group, enum netif_mac_filter_action action);
+#endif /* LWIP_IPV6 && LWIP_IPV6_MLD */
+
+#if LWIP_DHCP || LWIP_AUTOIP || LWIP_IGMP || LWIP_IPV6_MLD || LWIP_IPV6_DHCP6 || (LWIP_NUM_NETIF_CLIENT_DATA > 0)
+#if LWIP_NUM_NETIF_CLIENT_DATA > 0
+u8_t netif_alloc_client_data_id(void);
+#endif
+/** @ingroup netif_cd
+ * Set client data. Obtain ID from netif_alloc_client_data_id().
+ */
+#define netif_set_client_data(netif, id, data) netif_get_client_data(netif, id) = (data)
+/** @ingroup netif_cd
+ * Get client data. Obtain ID from netif_alloc_client_data_id().
+ */
+#define netif_get_client_data(netif, id)       (netif)->client_data[(id)]
+#endif
+
+#if (LWIP_IPV4 && LWIP_ARP && (ARP_TABLE_SIZE > 0x7f)) || (LWIP_IPV6 && (LWIP_ND6_NUM_DESTINATIONS > 0x7f))
+typedef u16_t netif_addr_idx_t;
+#define NETIF_ADDR_IDX_MAX 0x7FFF
+#else
+typedef u8_t netif_addr_idx_t;
+#define NETIF_ADDR_IDX_MAX 0x7F
+#endif
+
+#if LWIP_NETIF_HWADDRHINT
+#define LWIP_NETIF_USE_HINTS              1
+struct netif_hint {
+  netif_addr_idx_t addr_hint;
+};
+#else /* LWIP_NETIF_HWADDRHINT */
+#define LWIP_NETIF_USE_HINTS              0
+#endif /* LWIP_NETIF_HWADDRHINT */
+
+/** Generic data structure used for all lwIP network interfaces.
+ *  The following fields should be filled in by the initialization
+ *  function for the device driver: hwaddr_len, hwaddr[], mtu, flags */
+struct netif {
+#if !LWIP_SINGLE_NETIF
+  /** pointer to next in linked list */
+  struct netif *next;
+#endif
+
+#if LWIP_IPV4
+  /** IP address configuration in network byte order */
+  ip_addr_t ip_addr;
+  ip_addr_t netmask;
+  ip_addr_t gw;
+#endif /* LWIP_IPV4 */
+#if LWIP_IPV6
+  /** Array of IPv6 addresses for this netif. */
+  ip_addr_t ip6_addr[LWIP_IPV6_NUM_ADDRESSES];
+  /** The state of each IPv6 address (Tentative, Preferred, etc).
+   * @see ip6_addr.h */
+  u8_t ip6_addr_state[LWIP_IPV6_NUM_ADDRESSES];
+#if LWIP_IPV6_ADDRESS_LIFETIMES
+  /** Remaining valid and preferred lifetime of each IPv6 address, in seconds.
+   * For valid lifetimes, the special value of IP6_ADDR_LIFE_STATIC (0)
+   * indicates the address is static and has no lifetimes. */
+  u32_t ip6_addr_valid_life[LWIP_IPV6_NUM_ADDRESSES];
+  u32_t ip6_addr_pref_life[LWIP_IPV6_NUM_ADDRESSES];
+#endif /* LWIP_IPV6_ADDRESS_LIFETIMES */
+#endif /* LWIP_IPV6 */
+  /** This function is called by the network device driver
+   *  to pass a packet up the TCP/IP stack. */
+  netif_input_fn input;
+#if LWIP_IPV4
+  /** This function is called by the IP module when it wants
+   *  to send a packet on the interface. This function typically
+   *  first resolves the hardware address, then sends the packet.
+   *  For ethernet physical layer, this is usually etharp_output() */
+  netif_output_fn output;
+#endif /* LWIP_IPV4 */
+  /** This function is called by ethernet_output() when it wants
+   *  to send a packet on the interface. This function outputs
+   *  the pbuf as-is on the link medium. */
+  netif_linkoutput_fn linkoutput;
+#if LWIP_IPV6
+  /** This function is called by the IPv6 module when it wants
+   *  to send a packet on the interface. This function typically
+   *  first resolves the hardware address, then sends the packet.
+   *  For ethernet physical layer, this is usually ethip6_output() */
+  netif_output_ip6_fn output_ip6;
+#endif /* LWIP_IPV6 */
+#if LWIP_NETIF_STATUS_CALLBACK
+  /** This function is called when the netif state is set to up or down
+   */
+  netif_status_callback_fn status_callback;
+#endif /* LWIP_NETIF_STATUS_CALLBACK */
+#if LWIP_NETIF_LINK_CALLBACK
+  /** This function is called when the netif link is set to up or down
+   */
+  netif_status_callback_fn link_callback;
+#endif /* LWIP_NETIF_LINK_CALLBACK */
+#if LWIP_NETIF_REMOVE_CALLBACK
+  /** This function is called when the netif has been removed */
+  netif_status_callback_fn remove_callback;
+#endif /* LWIP_NETIF_REMOVE_CALLBACK */
+  /** This field can be set by the device driver and could point
+   *  to state information for the device. */
+  void *state;
+#ifdef netif_get_client_data
+  void* client_data[LWIP_NETIF_CLIENT_DATA_INDEX_MAX + LWIP_NUM_NETIF_CLIENT_DATA];
+#endif
+#if LWIP_NETIF_HOSTNAME
+  /* the hostname for this netif, NULL is a valid value */
+  const char*  hostname;
+#endif /* LWIP_NETIF_HOSTNAME */
+#if LWIP_CHECKSUM_CTRL_PER_NETIF
+  u16_t chksum_flags;
+#endif /* LWIP_CHECKSUM_CTRL_PER_NETIF*/
+  /** maximum transfer unit (in bytes) */
+  u16_t mtu;
+#if LWIP_IPV6 && LWIP_ND6_ALLOW_RA_UPDATES
+  /** maximum transfer unit (in bytes), updated by RA */
+  u16_t mtu6;
+#endif /* LWIP_IPV6 && LWIP_ND6_ALLOW_RA_UPDATES */
+  /** link level hardware address of this interface */
+  u8_t hwaddr[NETIF_MAX_HWADDR_LEN];
+  /** number of bytes used in hwaddr */
+  u8_t hwaddr_len;
+  /** flags (@see @ref netif_flags) */
+  u8_t flags;
+  /** descriptive abbreviation */
+  char name[2];
+  /** number of this interface. Used for @ref if_api and @ref netifapi_netif, 
+   * as well as for IPv6 zones */
+  u8_t num;
+#if LWIP_IPV6_AUTOCONFIG
+  /** is this netif enabled for IPv6 autoconfiguration */
+  u8_t ip6_autoconfig_enabled;
+#endif /* LWIP_IPV6_AUTOCONFIG */
+#if LWIP_IPV6_SEND_ROUTER_SOLICIT
+  /** Number of Router Solicitation messages that remain to be sent. */
+  u8_t rs_count;
+#endif /* LWIP_IPV6_SEND_ROUTER_SOLICIT */
+#if MIB2_STATS
+  /** link type (from "snmp_ifType" enum from snmp_mib2.h) */
+  u8_t link_type;
+  /** (estimate) link speed */
+  u32_t link_speed;
+  /** timestamp at last change made (up/down) */
+  u32_t ts;
+  /** counters */
+  struct stats_mib2_netif_ctrs mib2_counters;
+#endif /* MIB2_STATS */
+#if LWIP_IPV4 && LWIP_IGMP
+  /** This function could be called to add or delete an entry in the multicast
+      filter table of the ethernet MAC.*/
+  netif_igmp_mac_filter_fn igmp_mac_filter;
+#endif /* LWIP_IPV4 && LWIP_IGMP */
+#if LWIP_IPV6 && LWIP_IPV6_MLD
+  /** This function could be called to add or delete an entry in the IPv6 multicast
+      filter table of the ethernet MAC. */
+  netif_mld_mac_filter_fn mld_mac_filter;
+#endif /* LWIP_IPV6 && LWIP_IPV6_MLD */
+#if LWIP_NETIF_USE_HINTS
+  struct netif_hint *hints;
+#endif /* LWIP_NETIF_USE_HINTS */
+#if ENABLE_LOOPBACK
+  /* List of packets to be queued for ourselves. */
+  struct pbuf *loop_first;
+  struct pbuf *loop_last;
+#if LWIP_LOOPBACK_MAX_PBUFS
+  u16_t loop_cnt_current;
+#endif /* LWIP_LOOPBACK_MAX_PBUFS */
+#endif /* ENABLE_LOOPBACK */
+};
+
+#if LWIP_CHECKSUM_CTRL_PER_NETIF
+#define NETIF_SET_CHECKSUM_CTRL(netif, chksumflags) do { \
+  (netif)->chksum_flags = chksumflags; } while(0)
+#define IF__NETIF_CHECKSUM_ENABLED(netif, chksumflag) if (((netif) == NULL) || (((netif)->chksum_flags & (chksumflag)) != 0))
+#else /* LWIP_CHECKSUM_CTRL_PER_NETIF */
+#define NETIF_SET_CHECKSUM_CTRL(netif, chksumflags)
+#define IF__NETIF_CHECKSUM_ENABLED(netif, chksumflag)
+#endif /* LWIP_CHECKSUM_CTRL_PER_NETIF */
+
+#if LWIP_SINGLE_NETIF
+#define NETIF_FOREACH(netif) if (((netif) = netif_default) != NULL)
+#else /* LWIP_SINGLE_NETIF */
+/** The list of network interfaces. */
+extern struct netif *netif_list;
+#define NETIF_FOREACH(netif) for ((netif) = netif_list; (netif) != NULL; (netif) = (netif)->next)
+#endif /* LWIP_SINGLE_NETIF */
+/** The default network interface. */
+extern struct netif *netif_default;
+
+void netif_init(void);
+
+struct netif *netif_add_noaddr(struct netif *netif, void *state, netif_init_fn init, netif_input_fn input);
+
+#if LWIP_IPV4
+struct netif *netif_add(struct netif *netif,
+                            const ip4_addr_t *ipaddr, const ip4_addr_t *netmask, const ip4_addr_t *gw,
+                            void *state, netif_init_fn init, netif_input_fn input);
+void netif_set_addr(struct netif *netif, const ip4_addr_t *ipaddr, const ip4_addr_t *netmask,
+                    const ip4_addr_t *gw);
+#else /* LWIP_IPV4 */
+struct netif *netif_add(struct netif *netif, void *state, netif_init_fn init, netif_input_fn input);
+#endif /* LWIP_IPV4 */
+void netif_remove(struct netif * netif);
+
+/* Returns a network interface given its name. The name is of the form
+   "et0", where the first two letters are the "name" field in the
+   netif structure, and the digit is in the num field in the same
+   structure. */
+struct netif *netif_find(const char *name);
+
+void netif_set_default(struct netif *netif);
+
+#if LWIP_IPV4
+void netif_set_ipaddr(struct netif *netif, const ip4_addr_t *ipaddr);
+void netif_set_netmask(struct netif *netif, const ip4_addr_t *netmask);
+void netif_set_gw(struct netif *netif, const ip4_addr_t *gw);
+/** @ingroup netif_ip4 */
+#define netif_ip4_addr(netif)    ((const ip4_addr_t*)ip_2_ip4(&((netif)->ip_addr)))
+/** @ingroup netif_ip4 */
+#define netif_ip4_netmask(netif) ((const ip4_addr_t*)ip_2_ip4(&((netif)->netmask)))
+/** @ingroup netif_ip4 */
+#define netif_ip4_gw(netif)      ((const ip4_addr_t*)ip_2_ip4(&((netif)->gw)))
+/** @ingroup netif_ip4 */
+#define netif_ip_addr4(netif)    ((const ip_addr_t*)&((netif)->ip_addr))
+/** @ingroup netif_ip4 */
+#define netif_ip_netmask4(netif) ((const ip_addr_t*)&((netif)->netmask))
+/** @ingroup netif_ip4 */
+#define netif_ip_gw4(netif)      ((const ip_addr_t*)&((netif)->gw))
+#endif /* LWIP_IPV4 */
+
+#define netif_set_flags(netif, set_flags)     do { (netif)->flags = (u8_t)((netif)->flags |  (set_flags)); } while(0)
+#define netif_clear_flags(netif, clr_flags)   do { (netif)->flags = (u8_t)((netif)->flags & (u8_t)(~(clr_flags) & 0xff)); } while(0)
+#define netif_is_flag_set(nefif, flag)        (((netif)->flags & (flag)) != 0)
+
+void netif_set_up(struct netif *netif);
+void netif_set_down(struct netif *netif);
+/** @ingroup netif
+ * Ask if an interface is up
+ */
+#define netif_is_up(netif) (((netif)->flags & NETIF_FLAG_UP) ? (u8_t)1 : (u8_t)0)
+
+#if LWIP_NETIF_STATUS_CALLBACK
+void netif_set_status_callback(struct netif *netif, netif_status_callback_fn status_callback);
+#endif /* LWIP_NETIF_STATUS_CALLBACK */
+#if LWIP_NETIF_REMOVE_CALLBACK
+void netif_set_remove_callback(struct netif *netif, netif_status_callback_fn remove_callback);
+#endif /* LWIP_NETIF_REMOVE_CALLBACK */
+
+void netif_set_link_up(struct netif *netif);
+void netif_set_link_down(struct netif *netif);
+/** Ask if a link is up */
+#define netif_is_link_up(netif) (((netif)->flags & NETIF_FLAG_LINK_UP) ? (u8_t)1 : (u8_t)0)
+
+#if LWIP_NETIF_LINK_CALLBACK
+void netif_set_link_callback(struct netif *netif, netif_status_callback_fn link_callback);
+#endif /* LWIP_NETIF_LINK_CALLBACK */
+
+#if LWIP_NETIF_HOSTNAME
+/** @ingroup netif */
+#define netif_set_hostname(netif, name) do { if((netif) != NULL) { (netif)->hostname = name; }}while(0)
+/** @ingroup netif */
+#define netif_get_hostname(netif) (((netif) != NULL) ? ((netif)->hostname) : NULL)
+#endif /* LWIP_NETIF_HOSTNAME */
+
+#if LWIP_IGMP
+/** @ingroup netif */
+#define netif_set_igmp_mac_filter(netif, function) do { if((netif) != NULL) { (netif)->igmp_mac_filter = function; }}while(0)
+#define netif_get_igmp_mac_filter(netif) (((netif) != NULL) ? ((netif)->igmp_mac_filter) : NULL)
+#endif /* LWIP_IGMP */
+
+#if LWIP_IPV6 && LWIP_IPV6_MLD
+/** @ingroup netif */
+#define netif_set_mld_mac_filter(netif, function) do { if((netif) != NULL) { (netif)->mld_mac_filter = function; }}while(0)
+#define netif_get_mld_mac_filter(netif) (((netif) != NULL) ? ((netif)->mld_mac_filter) : NULL)
+#define netif_mld_mac_filter(netif, addr, action) do { if((netif) && (netif)->mld_mac_filter) { (netif)->mld_mac_filter((netif), (addr), (action)); }}while(0)
+#endif /* LWIP_IPV6 && LWIP_IPV6_MLD */
+
+#if ENABLE_LOOPBACK
+err_t netif_loop_output(struct netif *netif, struct pbuf *p);
+void netif_poll(struct netif *netif);
+#if !LWIP_NETIF_LOOPBACK_MULTITHREADING
+void netif_poll_all(void);
+#endif /* !LWIP_NETIF_LOOPBACK_MULTITHREADING */
+#endif /* ENABLE_LOOPBACK */
+
+err_t netif_input(struct pbuf *p, struct netif *inp);
+
+#if LWIP_IPV6
+/** @ingroup netif_ip6 */
+#define netif_ip_addr6(netif, i)  ((const ip_addr_t*)(&((netif)->ip6_addr[i])))
+/** @ingroup netif_ip6 */
+#define netif_ip6_addr(netif, i)  ((const ip6_addr_t*)ip_2_ip6(&((netif)->ip6_addr[i])))
+void netif_ip6_addr_set(struct netif *netif, s8_t addr_idx, const ip6_addr_t *addr6);
+void netif_ip6_addr_set_parts(struct netif *netif, s8_t addr_idx, u32_t i0, u32_t i1, u32_t i2, u32_t i3);
+#define netif_ip6_addr_state(netif, i)  ((netif)->ip6_addr_state[i])
+void netif_ip6_addr_set_state(struct netif* netif, s8_t addr_idx, u8_t state);
+s8_t netif_get_ip6_addr_match(struct netif *netif, const ip6_addr_t *ip6addr);
+void netif_create_ip6_linklocal_address(struct netif *netif, u8_t from_mac_48bit);
+err_t netif_add_ip6_address(struct netif *netif, const ip6_addr_t *ip6addr, s8_t *chosen_idx);
+#define netif_set_ip6_autoconfig_enabled(netif, action) do { if(netif) { (netif)->ip6_autoconfig_enabled = (action); }}while(0)
+#if LWIP_IPV6_ADDRESS_LIFETIMES
+#define netif_ip6_addr_valid_life(netif, i)  \
+    (((netif) != NULL) ? ((netif)->ip6_addr_valid_life[i]) : IP6_ADDR_LIFE_STATIC)
+#define netif_ip6_addr_set_valid_life(netif, i, secs) \
+    do { if (netif != NULL) { (netif)->ip6_addr_valid_life[i] = (secs); }} while (0)
+#define netif_ip6_addr_pref_life(netif, i)  \
+    (((netif) != NULL) ? ((netif)->ip6_addr_pref_life[i]) : IP6_ADDR_LIFE_STATIC)
+#define netif_ip6_addr_set_pref_life(netif, i, secs) \
+    do { if (netif != NULL) { (netif)->ip6_addr_pref_life[i] = (secs); }} while (0)
+#define netif_ip6_addr_isstatic(netif, i)  \
+    (netif_ip6_addr_valid_life((netif), (i)) == IP6_ADDR_LIFE_STATIC)
+#else /* !LWIP_IPV6_ADDRESS_LIFETIMES */
+#define netif_ip6_addr_isstatic(netif, i)  (1) /* all addresses are static */
+#endif /* !LWIP_IPV6_ADDRESS_LIFETIMES */
+#if LWIP_ND6_ALLOW_RA_UPDATES
+#define netif_mtu6(netif) ((netif)->mtu6)
+#else /* LWIP_ND6_ALLOW_RA_UPDATES */
+#define netif_mtu6(netif) ((netif)->mtu)
+#endif /* LWIP_ND6_ALLOW_RA_UPDATES */
+#endif /* LWIP_IPV6 */
+
+#if LWIP_NETIF_USE_HINTS
+#define NETIF_SET_HINTS(netif, netifhint)  (netif)->hints = (netifhint)
+#define NETIF_RESET_HINTS(netif)      (netif)->hints = NULL
+#else /* LWIP_NETIF_USE_HINTS */
+#define NETIF_SET_HINTS(netif, netifhint)
+#define NETIF_RESET_HINTS(netif)
+#endif /* LWIP_NETIF_USE_HINTS */
+
+u8_t netif_name_to_index(const char *name);
+char * netif_index_to_name(u8_t idx, char *name);
+struct netif* netif_get_by_index(u8_t idx);
+
+/* Interface indexes always start at 1 per RFC 3493, section 4, num starts at 0 (internal index is 0..254)*/
+#define netif_get_index(netif)      ((u8_t)((netif)->num + 1))
+#define NETIF_NO_INDEX              (0)
+
+/**
+ * @ingroup netif
+ * Extended netif status callback (NSC) reasons flags.
+ * May be extended in the future!
+ */
+typedef u16_t netif_nsc_reason_t;
+
+/* used for initialization only */
+#define LWIP_NSC_NONE                     0x0000
+/** netif was added. arg: NULL. Called AFTER netif was added. */
+#define LWIP_NSC_NETIF_ADDED              0x0001
+/** netif was removed. arg: NULL. Called BEFORE netif is removed. */
+#define LWIP_NSC_NETIF_REMOVED            0x0002
+/** link changed */
+#define LWIP_NSC_LINK_CHANGED             0x0004
+/** netif administrative status changed.\n
+  * up is called AFTER netif is set up.\n
+  * down is called BEFORE the netif is actually set down. */
+#define LWIP_NSC_STATUS_CHANGED           0x0008
+/** IPv4 address has changed */
+#define LWIP_NSC_IPV4_ADDRESS_CHANGED     0x0010
+/** IPv4 gateway has changed */
+#define LWIP_NSC_IPV4_GATEWAY_CHANGED     0x0020
+/** IPv4 netmask has changed */
+#define LWIP_NSC_IPV4_NETMASK_CHANGED     0x0040
+/** called AFTER IPv4 address/gateway/netmask changes have been applied */
+#define LWIP_NSC_IPV4_SETTINGS_CHANGED    0x0080
+/** IPv6 address was added */
+#define LWIP_NSC_IPV6_SET                 0x0100
+/** IPv6 address state has changed */
+#define LWIP_NSC_IPV6_ADDR_STATE_CHANGED  0x0200
+
+/** @ingroup netif
+ * Argument supplied to netif_ext_callback_fn.
+ */
+typedef union
+{
+  /** Args to LWIP_NSC_LINK_CHANGED callback */
+  struct link_changed_s
+  {
+    /** 1: up; 0: down */
+    u8_t state;
+  } link_changed;
+  /** Args to LWIP_NSC_STATUS_CHANGED callback */
+  struct status_changed_s
+  {
+    /** 1: up; 0: down */
+    u8_t state;
+  } status_changed;
+  /** Args to LWIP_NSC_IPV4_ADDRESS_CHANGED|LWIP_NSC_IPV4_GATEWAY_CHANGED|LWIP_NSC_IPV4_NETMASK_CHANGED|LWIP_NSC_IPV4_SETTINGS_CHANGED callback */
+  struct ipv4_changed_s
+  {
+    /** Old IPv4 address */
+    const ip_addr_t* old_address;
+    const ip_addr_t* old_netmask;
+    const ip_addr_t* old_gw;
+  } ipv4_changed;
+  /** Args to LWIP_NSC_IPV6_SET callback */
+  struct ipv6_set_s
+  {
+    /** Index of changed IPv6 address */
+    s8_t addr_index;
+    /** Old IPv6 address */
+    const ip_addr_t* old_address;
+  } ipv6_set;
+  /** Args to LWIP_NSC_IPV6_ADDR_STATE_CHANGED callback */
+  struct ipv6_addr_state_changed_s
+  {
+    /** Index of affected IPv6 address */
+    s8_t addr_index;
+    /** Old IPv6 address state */
+    u8_t old_state;
+    /** Affected IPv6 address */
+    const ip_addr_t* address;
+  } ipv6_addr_state_changed;
+} netif_ext_callback_args_t;
+
+/**
+ * @ingroup netif
+ * Function used for extended netif status callbacks
+ * Note: When parsing reason argument, keep in mind that more reasons may be added in the future!
+ * @param netif netif that is affected by change
+ * @param reason change reason
+ * @param args depends on reason, see reason description
+ */
+typedef void (*netif_ext_callback_fn)(struct netif* netif, netif_nsc_reason_t reason, const netif_ext_callback_args_t* args);
+
+#if LWIP_NETIF_EXT_STATUS_CALLBACK
+struct netif_ext_callback;
+typedef struct netif_ext_callback
+{
+  netif_ext_callback_fn callback_fn;
+  struct netif_ext_callback* next;
+} netif_ext_callback_t;
+
+#define NETIF_DECLARE_EXT_CALLBACK(name) static netif_ext_callback_t name;
+void netif_add_ext_callback(netif_ext_callback_t* callback, netif_ext_callback_fn fn);
+void netif_remove_ext_callback(netif_ext_callback_t* callback);
+void netif_invoke_ext_callback(struct netif* netif, netif_nsc_reason_t reason, const netif_ext_callback_args_t* args);
+#else
+#define NETIF_DECLARE_EXT_CALLBACK(name)
+#define netif_add_ext_callback(callback, fn)
+#define netif_remove_ext_callback(callback)
+#define netif_invoke_ext_callback(netif, reason, args)
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LWIP_HDR_NETIF_H */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/netifapi.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/netifapi.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/netifapi.h	(revision 457)
@@ -0,0 +1,161 @@
+/**
+ * @file
+ * netif API (to be used from non-TCPIP threads)
+ */
+
+/*
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ */
+#ifndef LWIP_HDR_NETIFAPI_H
+#define LWIP_HDR_NETIFAPI_H
+
+#include "lwip/opt.h"
+
+#if LWIP_NETIF_API /* don't build if not configured for use in lwipopts.h */
+
+#include "lwip/sys.h"
+#include "lwip/netif.h"
+#include "lwip/dhcp.h"
+#include "lwip/autoip.h"
+#include "lwip/priv/tcpip_priv.h"
+#include "lwip/priv/api_msg.h"
+#include "lwip/prot/ethernet.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* API for application */
+#if LWIP_ARP && LWIP_IPV4
+/* Used for netfiapi_arp_* APIs */
+enum netifapi_arp_entry {
+  NETIFAPI_ARP_PERM /* Permanent entry */
+  /* Other entry types can be added here */
+};
+
+/** @ingroup netifapi_arp */
+err_t netifapi_arp_add(const ip4_addr_t *ipaddr, struct eth_addr *ethaddr, enum netifapi_arp_entry type);
+/** @ingroup netifapi_arp */
+err_t netifapi_arp_remove(const ip4_addr_t *ipaddr, enum netifapi_arp_entry type);
+#endif /* LWIP_ARP && LWIP_IPV4 */
+
+err_t netifapi_netif_add(struct netif *netif,
+#if LWIP_IPV4
+                         const ip4_addr_t *ipaddr, const ip4_addr_t *netmask, const ip4_addr_t *gw,
+#endif /* LWIP_IPV4 */
+                         void *state, netif_init_fn init, netif_input_fn input);
+
+#if LWIP_IPV4
+err_t netifapi_netif_set_addr(struct netif *netif, const ip4_addr_t *ipaddr,
+                              const ip4_addr_t *netmask, const ip4_addr_t *gw);
+#endif /* LWIP_IPV4*/
+
+err_t netifapi_netif_common(struct netif *netif, netifapi_void_fn voidfunc,
+                            netifapi_errt_fn errtfunc);
+
+/** @ingroup netifapi_netif */
+err_t netifapi_netif_name_to_index(const char *name, u8_t *index);
+/** @ingroup netifapi_netif */
+err_t netifapi_netif_index_to_name(u8_t index, char *name);
+
+/** @ingroup netifapi_netif
+  * @see netif_remove()
+  */
+#define netifapi_netif_remove(n)        netifapi_netif_common(n, netif_remove, NULL)
+/** @ingroup netifapi_netif
+  * @see netif_set_up()
+  */
+#define netifapi_netif_set_up(n)        netifapi_netif_common(n, netif_set_up, NULL)
+/** @ingroup netifapi_netif
+  * @see netif_set_down()
+  */
+#define netifapi_netif_set_down(n)      netifapi_netif_common(n, netif_set_down, NULL)
+/** @ingroup netifapi_netif
+  * @see netif_set_default()
+  */
+#define netifapi_netif_set_default(n)   netifapi_netif_common(n, netif_set_default, NULL)
+/** @ingroup netifapi_netif
+  * @see netif_set_link_up()
+  */
+#define netifapi_netif_set_link_up(n)   netifapi_netif_common(n, netif_set_link_up, NULL)
+/** @ingroup netifapi_netif
+  * @see netif_set_link_down()
+  */
+#define netifapi_netif_set_link_down(n) netifapi_netif_common(n, netif_set_link_down, NULL)
+
+/**
+ * @defgroup netifapi_dhcp4 DHCPv4
+ * @ingroup netifapi
+ * To be called from non-TCPIP threads
+ */
+/** @ingroup netifapi_dhcp4
+  * @see dhcp_start()
+  */
+#define netifapi_dhcp_start(n)            netifapi_netif_common(n, NULL, dhcp_start)
+/**
+ * @ingroup netifapi_dhcp4
+ * @deprecated Use netifapi_dhcp_release_and_stop() instead.
+ */
+#define netifapi_dhcp_stop(n)             netifapi_netif_common(n, dhcp_stop, NULL)
+/** @ingroup netifapi_dhcp4
+  * @see dhcp_inform()
+  */
+#define netifapi_dhcp_inform(n)           netifapi_netif_common(n, dhcp_inform, NULL)
+/** @ingroup netifapi_dhcp4
+  * @see dhcp_renew()
+  */
+#define netifapi_dhcp_renew(n)            netifapi_netif_common(n, NULL, dhcp_renew)
+/**
+ * @ingroup netifapi_dhcp4
+ * @deprecated Use netifapi_dhcp_release_and_stop() instead.
+ */
+#define netifapi_dhcp_release(n)          netifapi_netif_common(n, NULL, dhcp_release)
+/** @ingroup netifapi_dhcp4
+  * @see dhcp_release_and_stop()
+  */
+#define netifapi_dhcp_release_and_stop(n) netifapi_netif_common(n, dhcp_release_and_stop, NULL)
+
+/**
+ * @defgroup netifapi_autoip AUTOIP
+ * @ingroup netifapi
+ * To be called from non-TCPIP threads
+ */
+/** @ingroup netifapi_autoip
+  * @see autoip_start()
+  */
+#define netifapi_autoip_start(n)      netifapi_netif_common(n, NULL, autoip_start)
+/** @ingroup netifapi_autoip
+  * @see autoip_stop()
+  */
+#define netifapi_autoip_stop(n)       netifapi_netif_common(n, NULL, autoip_stop)
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LWIP_NETIF_API */
+
+#endif /* LWIP_HDR_NETIFAPI_H */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/opt.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/opt.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/opt.h	(revision 457)
@@ -0,0 +1,3519 @@
+/**
+ * @file
+ *
+ * lwIP Options Configuration
+ */
+
+/*
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Adam Dunkels <adam@sics.se>
+ *
+ */
+
+/*
+ * NOTE: || defined __DOXYGEN__ is a workaround for doxygen bug -
+ * without this, doxygen does not see the actual #define
+ */
+
+#if !defined LWIP_HDR_OPT_H
+#define LWIP_HDR_OPT_H
+
+/*
+ * Include user defined options first. Anything not defined in these files
+ * will be set to standard values. Override anything you don't like!
+ */
+#include "lwipopts.h"
+#include "lwip/debug.h"
+
+/**
+ * @defgroup lwip_opts Options (lwipopts.h)
+ * @ingroup lwip
+ *
+ * @defgroup lwip_opts_debug Debugging
+ * @ingroup lwip_opts
+ *
+ * @defgroup lwip_opts_infrastructure Infrastructure
+ * @ingroup lwip_opts
+ *
+ * @defgroup lwip_opts_callback Callback-style APIs
+ * @ingroup lwip_opts
+ *
+ * @defgroup lwip_opts_threadsafe_apis Thread-safe APIs
+ * @ingroup lwip_opts
+ */
+
+ /*
+   ------------------------------------
+   -------------- NO SYS --------------
+   ------------------------------------
+*/
+/**
+ * @defgroup lwip_opts_nosys NO_SYS
+ * @ingroup lwip_opts_infrastructure
+ * @{
+ */
+/**
+ * NO_SYS==1: Use lwIP without OS-awareness (no thread, semaphores, mutexes or
+ * mboxes). This means threaded APIs cannot be used (socket, netconn,
+ * i.e. everything in the 'api' folder), only the callback-style raw API is
+ * available (and you have to watch out for yourself that you don't access
+ * lwIP functions/structures from more than one context at a time!)
+ */
+#if !defined NO_SYS || defined __DOXYGEN__
+#define NO_SYS                          0
+#endif
+/**
+ * @}
+ */
+
+/**
+ * @defgroup lwip_opts_timers Timers
+ * @ingroup lwip_opts_infrastructure
+ * @{
+ */
+/**
+ * LWIP_TIMERS==0: Drop support for sys_timeout and lwip-internal cyclic timers.
+ * (the array of lwip-internal cyclic timers is still provided)
+ * (check NO_SYS_NO_TIMERS for compatibility to old versions)
+ */
+#if !defined LWIP_TIMERS || defined __DOXYGEN__
+#ifdef NO_SYS_NO_TIMERS
+#define LWIP_TIMERS                     (!NO_SYS || (NO_SYS && !NO_SYS_NO_TIMERS))
+#else
+#define LWIP_TIMERS                     1
+#endif
+#endif
+
+/**
+ * LWIP_TIMERS_CUSTOM==1: Provide your own timer implementation.
+ * Function prototypes in timeouts.h and the array of lwip-internal cyclic timers
+ * are still included, but the implementation is not. The following functions
+ * will be required: sys_timeouts_init(), sys_timeout(), sys_untimeout(),
+ *                   sys_timeouts_mbox_fetch()
+ */
+#if !defined LWIP_TIMERS_CUSTOM || defined __DOXYGEN__
+#define LWIP_TIMERS_CUSTOM              0
+#endif
+/**
+ * @}
+ */
+
+/**
+ * @defgroup lwip_opts_memcpy memcpy
+ * @ingroup lwip_opts_infrastructure
+ * @{
+ */
+/**
+ * MEMCPY: override this if you have a faster implementation at hand than the
+ * one included in your C library
+ */
+#if !defined MEMCPY || defined __DOXYGEN__
+#define MEMCPY(dst,src,len)             memcpy(dst,src,len)
+#endif
+
+/**
+ * SMEMCPY: override this with care! Some compilers (e.g. gcc) can inline a
+ * call to memcpy() if the length is known at compile time and is small.
+ */
+#if !defined SMEMCPY || defined __DOXYGEN__
+#define SMEMCPY(dst,src,len)            memcpy(dst,src,len)
+#endif
+
+/**
+ * MEMMOVE: override this if you have a faster implementation at hand than the
+ * one included in your C library.  lwIP currently uses MEMMOVE only when IPv6
+ * fragmentation support is enabled.
+ */
+#if !defined MEMMOVE || defined __DOXYGEN__
+#define MEMMOVE(dst,src,len)            memmove(dst,src,len)
+#endif
+/**
+ * @}
+ */
+
+/*
+   ------------------------------------
+   ----------- Core locking -----------
+   ------------------------------------
+*/
+/**
+ * @defgroup lwip_opts_lock Core locking and MPU
+ * @ingroup lwip_opts_infrastructure
+ * @{
+ */
+/**
+ * LWIP_MPU_COMPATIBLE: enables special memory management mechanism
+ * which makes lwip able to work on MPU (Memory Protection Unit) system
+ * by not passing stack-pointers to other threads
+ * (this decreases performance as memory is allocated from pools instead
+ * of keeping it on the stack)
+ */
+#if !defined LWIP_MPU_COMPATIBLE || defined __DOXYGEN__
+#define LWIP_MPU_COMPATIBLE             0
+#endif
+
+/**
+ * LWIP_TCPIP_CORE_LOCKING
+ * Creates a global mutex that is held during TCPIP thread operations.
+ * Can be locked by client code to perform lwIP operations without changing
+ * into TCPIP thread using callbacks. See LOCK_TCPIP_CORE() and
+ * UNLOCK_TCPIP_CORE().
+ * Your system should provide mutexes supporting priority inversion to use this.
+ */
+#if !defined LWIP_TCPIP_CORE_LOCKING || defined __DOXYGEN__
+#define LWIP_TCPIP_CORE_LOCKING         1
+#endif
+
+/**
+ * LWIP_TCPIP_CORE_LOCKING_INPUT: when LWIP_TCPIP_CORE_LOCKING is enabled,
+ * this lets tcpip_input() grab the mutex for input packets as well,
+ * instead of allocating a message and passing it to tcpip_thread.
+ *
+ * ATTENTION: this does not work when tcpip_input() is called from
+ * interrupt context!
+ */
+#if !defined LWIP_TCPIP_CORE_LOCKING_INPUT || defined __DOXYGEN__
+#define LWIP_TCPIP_CORE_LOCKING_INPUT   0
+#endif
+
+/**
+ * SYS_LIGHTWEIGHT_PROT==1: enable inter-task protection (and task-vs-interrupt
+ * protection) for certain critical regions during buffer allocation, deallocation
+ * and memory allocation and deallocation.
+ * ATTENTION: This is required when using lwIP from more than one context! If
+ * you disable this, you must be sure what you are doing!
+ */
+#if !defined SYS_LIGHTWEIGHT_PROT || defined __DOXYGEN__
+#define SYS_LIGHTWEIGHT_PROT            1
+#endif
+
+/**
+ * Macro/function to check whether lwIP's threading/locking
+ * requirements are satisfied during current function call.
+ * This macro usually calls a function that is implemented in the OS-dependent
+ * sys layer and performs the following checks:
+ * - Not in ISR (this should be checked for NO_SYS==1, too!)
+ * - If @ref LWIP_TCPIP_CORE_LOCKING = 1: TCPIP core lock is held
+ * - If @ref LWIP_TCPIP_CORE_LOCKING = 0: function is called from TCPIP thread
+ * @see @ref multithreading
+ */
+#if !defined LWIP_ASSERT_CORE_LOCKED || defined __DOXYGEN__
+#define LWIP_ASSERT_CORE_LOCKED()
+#endif
+
+/**
+ * Called as first thing in the lwIP TCPIP thread. Can be used in conjunction
+ * with @ref LWIP_ASSERT_CORE_LOCKED to check core locking.
+ * @see @ref multithreading
+ */
+#if !defined LWIP_MARK_TCPIP_THREAD || defined __DOXYGEN__
+#define LWIP_MARK_TCPIP_THREAD()
+#endif
+/**
+ * @}
+ */
+
+/*
+   ------------------------------------
+   ---------- Memory options ----------
+   ------------------------------------
+*/
+/**
+ * @defgroup lwip_opts_mem Heap and memory pools
+ * @ingroup lwip_opts_infrastructure
+ * @{
+ */
+/**
+ * MEM_LIBC_MALLOC==1: Use malloc/free/realloc provided by your C-library
+ * instead of the lwip internal allocator. Can save code size if you
+ * already use it.
+ */
+#if !defined MEM_LIBC_MALLOC || defined __DOXYGEN__
+#define MEM_LIBC_MALLOC                 0
+#endif
+
+/**
+ * MEMP_MEM_MALLOC==1: Use mem_malloc/mem_free instead of the lwip pool allocator.
+ * Especially useful with MEM_LIBC_MALLOC but handle with care regarding execution
+ * speed (heap alloc can be much slower than pool alloc) and usage from interrupts
+ * (especially if your netif driver allocates PBUF_POOL pbufs for received frames
+ * from interrupt)!
+ * ATTENTION: Currently, this uses the heap for ALL pools (also for private pools,
+ * not only for internal pools defined in memp_std.h)!
+ */
+#if !defined MEMP_MEM_MALLOC || defined __DOXYGEN__
+#define MEMP_MEM_MALLOC                 0
+#endif
+
+/**
+ * MEMP_MEM_INIT==1: Force use of memset to initialize pool memory.
+ * Useful if pool are moved in uninitialized section of memory. This will ensure
+ * default values in pcbs struct are well initialized in all conditions.
+ */
+#if !defined MEMP_MEM_INIT || defined __DOXYGEN__
+#define MEMP_MEM_INIT                   0
+#endif
+
+/**
+ * MEM_ALIGNMENT: should be set to the alignment of the CPU
+ *    4 byte alignment -> \#define MEM_ALIGNMENT 4
+ *    2 byte alignment -> \#define MEM_ALIGNMENT 2
+ */
+#if !defined MEM_ALIGNMENT || defined __DOXYGEN__
+#define MEM_ALIGNMENT                   1
+#endif
+
+/**
+ * MEM_SIZE: the size of the heap memory. If the application will send
+ * a lot of data that needs to be copied, this should be set high.
+ */
+#if !defined MEM_SIZE || defined __DOXYGEN__
+#define MEM_SIZE                        1600
+#endif
+
+/**
+ * MEMP_OVERFLOW_CHECK: memp overflow protection reserves a configurable
+ * amount of bytes before and after each memp element in every pool and fills
+ * it with a prominent default value.
+ *    MEMP_OVERFLOW_CHECK == 0 no checking
+ *    MEMP_OVERFLOW_CHECK == 1 checks each element when it is freed
+ *    MEMP_OVERFLOW_CHECK >= 2 checks each element in every pool every time
+ *      memp_malloc() or memp_free() is called (useful but slow!)
+ */
+#if !defined MEMP_OVERFLOW_CHECK || defined __DOXYGEN__
+#define MEMP_OVERFLOW_CHECK             0
+#endif
+
+/**
+ * MEMP_SANITY_CHECK==1: run a sanity check after each memp_free() to make
+ * sure that there are no cycles in the linked lists.
+ */
+#if !defined MEMP_SANITY_CHECK || defined __DOXYGEN__
+#define MEMP_SANITY_CHECK               0
+#endif
+
+/**
+ * MEM_OVERFLOW_CHECK: mem overflow protection reserves a configurable
+ * amount of bytes before and after each heap allocation chunk and fills
+ * it with a prominent default value.
+ *    MEM_OVERFLOW_CHECK == 0 no checking
+ *    MEM_OVERFLOW_CHECK == 1 checks each element when it is freed
+ *    MEM_OVERFLOW_CHECK >= 2 checks all heap elements every time
+ *      mem_malloc() or mem_free() is called (useful but slow!)
+ */
+#if !defined MEM_OVERFLOW_CHECK || defined __DOXYGEN__
+#define MEM_OVERFLOW_CHECK              0
+#endif
+
+/**
+ * MEM_SANITY_CHECK==1: run a sanity check after each mem_free() to make
+ * sure that the linked list of heap elements is not corrupted.
+ */
+#if !defined MEM_SANITY_CHECK || defined __DOXYGEN__
+#define MEM_SANITY_CHECK                0
+#endif
+
+/**
+ * MEM_USE_POOLS==1: Use an alternative to malloc() by allocating from a set
+ * of memory pools of various sizes. When mem_malloc is called, an element of
+ * the smallest pool that can provide the length needed is returned.
+ * To use this, MEMP_USE_CUSTOM_POOLS also has to be enabled.
+ */
+#if !defined MEM_USE_POOLS || defined __DOXYGEN__
+#define MEM_USE_POOLS                   0
+#endif
+
+/**
+ * MEM_USE_POOLS_TRY_BIGGER_POOL==1: if one malloc-pool is empty, try the next
+ * bigger pool - WARNING: THIS MIGHT WASTE MEMORY but it can make a system more
+ * reliable. */
+#if !defined MEM_USE_POOLS_TRY_BIGGER_POOL || defined __DOXYGEN__
+#define MEM_USE_POOLS_TRY_BIGGER_POOL   0
+#endif
+
+/**
+ * MEMP_USE_CUSTOM_POOLS==1: whether to include a user file lwippools.h
+ * that defines additional pools beyond the "standard" ones required
+ * by lwIP. If you set this to 1, you must have lwippools.h in your
+ * include path somewhere.
+ */
+#if !defined MEMP_USE_CUSTOM_POOLS || defined __DOXYGEN__
+#define MEMP_USE_CUSTOM_POOLS           0
+#endif
+
+/**
+ * Set this to 1 if you want to free PBUF_RAM pbufs (or call mem_free()) from
+ * interrupt context (or another context that doesn't allow waiting for a
+ * semaphore).
+ * If set to 1, mem_malloc will be protected by a semaphore and SYS_ARCH_PROTECT,
+ * while mem_free will only use SYS_ARCH_PROTECT. mem_malloc SYS_ARCH_UNPROTECTs
+ * with each loop so that mem_free can run.
+ *
+ * ATTENTION: As you can see from the above description, this leads to dis-/
+ * enabling interrupts often, which can be slow! Also, on low memory, mem_malloc
+ * can need longer.
+ *
+ * If you don't want that, at least for NO_SYS=0, you can still use the following
+ * functions to enqueue a deallocation call which then runs in the tcpip_thread
+ * context:
+ * - pbuf_free_callback(p);
+ * - mem_free_callback(m);
+ */
+#if !defined LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT || defined __DOXYGEN__
+#define LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT 0
+#endif
+/**
+ * @}
+ */
+
+/*
+   ------------------------------------------------
+   ---------- Internal Memory Pool Sizes ----------
+   ------------------------------------------------
+*/
+/**
+ * @defgroup lwip_opts_memp Internal memory pools
+ * @ingroup lwip_opts_infrastructure
+ * @{
+ */
+/**
+ * MEMP_NUM_PBUF: the number of memp struct pbufs (used for PBUF_ROM and PBUF_REF).
+ * If the application sends a lot of data out of ROM (or other static memory),
+ * this should be set high.
+ */
+#if !defined MEMP_NUM_PBUF || defined __DOXYGEN__
+#define MEMP_NUM_PBUF                   16
+#endif
+
+/**
+ * MEMP_NUM_RAW_PCB: Number of raw connection PCBs
+ * (requires the LWIP_RAW option)
+ */
+#if !defined MEMP_NUM_RAW_PCB || defined __DOXYGEN__
+#define MEMP_NUM_RAW_PCB                4
+#endif
+
+/**
+ * MEMP_NUM_UDP_PCB: the number of UDP protocol control blocks. One
+ * per active UDP "connection".
+ * (requires the LWIP_UDP option)
+ */
+#if !defined MEMP_NUM_UDP_PCB || defined __DOXYGEN__
+#define MEMP_NUM_UDP_PCB                4
+#endif
+
+/**
+ * MEMP_NUM_TCP_PCB: the number of simultaneously active TCP connections.
+ * (requires the LWIP_TCP option)
+ */
+#if !defined MEMP_NUM_TCP_PCB || defined __DOXYGEN__
+#define MEMP_NUM_TCP_PCB                5
+#endif
+
+/**
+ * MEMP_NUM_TCP_PCB_LISTEN: the number of listening TCP connections.
+ * (requires the LWIP_TCP option)
+ */
+#if !defined MEMP_NUM_TCP_PCB_LISTEN || defined __DOXYGEN__
+#define MEMP_NUM_TCP_PCB_LISTEN         8
+#endif
+
+/**
+ * MEMP_NUM_TCP_SEG: the number of simultaneously queued TCP segments.
+ * (requires the LWIP_TCP option)
+ */
+#if !defined MEMP_NUM_TCP_SEG || defined __DOXYGEN__
+#define MEMP_NUM_TCP_SEG                16
+#endif
+
+/**
+ * MEMP_NUM_ALTCP_PCB: the number of simultaneously active altcp layer pcbs.
+ * (requires the LWIP_ALTCP option)
+ * Connections with multiple layers require more than one altcp_pcb (e.g. TLS
+ * over TCP requires 2 altcp_pcbs, one for TLS and one for TCP).
+ */
+#if !defined MEMP_NUM_ALTCP_PCB || defined __DOXYGEN__
+#define MEMP_NUM_ALTCP_PCB              MEMP_NUM_TCP_PCB
+#endif
+
+/**
+ * MEMP_NUM_REASSDATA: the number of IP packets simultaneously queued for
+ * reassembly (whole packets, not fragments!)
+ */
+#if !defined MEMP_NUM_REASSDATA || defined __DOXYGEN__
+#define MEMP_NUM_REASSDATA              5
+#endif
+
+/**
+ * MEMP_NUM_FRAG_PBUF: the number of IP fragments simultaneously sent
+ * (fragments, not whole packets!).
+ * This is only used with LWIP_NETIF_TX_SINGLE_PBUF==0 and only has to be > 1
+ * with DMA-enabled MACs where the packet is not yet sent when netif->output
+ * returns.
+ */
+#if !defined MEMP_NUM_FRAG_PBUF || defined __DOXYGEN__
+#define MEMP_NUM_FRAG_PBUF              15
+#endif
+
+/**
+ * MEMP_NUM_ARP_QUEUE: the number of simultaneously queued outgoing
+ * packets (pbufs) that are waiting for an ARP request (to resolve
+ * their destination address) to finish.
+ * (requires the ARP_QUEUEING option)
+ */
+#if !defined MEMP_NUM_ARP_QUEUE || defined __DOXYGEN__
+#define MEMP_NUM_ARP_QUEUE              30
+#endif
+
+/**
+ * MEMP_NUM_IGMP_GROUP: The number of multicast groups whose network interfaces
+ * can be members at the same time (one per netif - allsystems group -, plus one
+ * per netif membership).
+ * (requires the LWIP_IGMP option)
+ */
+#if !defined MEMP_NUM_IGMP_GROUP || defined __DOXYGEN__
+#define MEMP_NUM_IGMP_GROUP             8
+#endif
+
+/**
+ * The number of sys timeouts used by the core stack (not apps)
+ * The default number of timeouts is calculated here for all enabled modules.
+ */
+#define LWIP_NUM_SYS_TIMEOUT_INTERNAL   (LWIP_TCP + IP_REASSEMBLY + LWIP_ARP + (2*LWIP_DHCP) + LWIP_AUTOIP + LWIP_IGMP + LWIP_DNS + PPP_NUM_TIMEOUTS + (LWIP_IPV6 * (1 + LWIP_IPV6_REASS + LWIP_IPV6_MLD)))
+
+/**
+ * MEMP_NUM_SYS_TIMEOUT: the number of simultaneously active timeouts.
+ * The default number of timeouts is calculated here for all enabled modules.
+ * The formula expects settings to be either '0' or '1'.
+ */
+#if !defined MEMP_NUM_SYS_TIMEOUT || defined __DOXYGEN__
+#define MEMP_NUM_SYS_TIMEOUT            LWIP_NUM_SYS_TIMEOUT_INTERNAL
+#endif
+
+/**
+ * MEMP_NUM_NETBUF: the number of struct netbufs.
+ * (only needed if you use the sequential API, like api_lib.c)
+ */
+#if !defined MEMP_NUM_NETBUF || defined __DOXYGEN__
+#define MEMP_NUM_NETBUF                 2
+#endif
+
+/**
+ * MEMP_NUM_NETCONN: the number of struct netconns.
+ * (only needed if you use the sequential API, like api_lib.c)
+ */
+#if !defined MEMP_NUM_NETCONN || defined __DOXYGEN__
+#define MEMP_NUM_NETCONN                4
+#endif
+
+/**
+ * MEMP_NUM_SELECT_CB: the number of struct lwip_select_cb.
+ * (Only needed if you have LWIP_MPU_COMPATIBLE==1 and use the socket API.
+ * In that case, you need one per thread calling lwip_select.)
+ */
+#if !defined MEMP_NUM_SELECT_CB || defined __DOXYGEN__
+#define MEMP_NUM_SELECT_CB              4
+#endif
+
+/**
+ * MEMP_NUM_TCPIP_MSG_API: the number of struct tcpip_msg, which are used
+ * for callback/timeout API communication.
+ * (only needed if you use tcpip.c)
+ */
+#if !defined MEMP_NUM_TCPIP_MSG_API || defined __DOXYGEN__
+#define MEMP_NUM_TCPIP_MSG_API          8
+#endif
+
+/**
+ * MEMP_NUM_TCPIP_MSG_INPKT: the number of struct tcpip_msg, which are used
+ * for incoming packets.
+ * (only needed if you use tcpip.c)
+ */
+#if !defined MEMP_NUM_TCPIP_MSG_INPKT || defined __DOXYGEN__
+#define MEMP_NUM_TCPIP_MSG_INPKT        8
+#endif
+
+/**
+ * MEMP_NUM_NETDB: the number of concurrently running lwip_addrinfo() calls
+ * (before freeing the corresponding memory using lwip_freeaddrinfo()).
+ */
+#if !defined MEMP_NUM_NETDB || defined __DOXYGEN__
+#define MEMP_NUM_NETDB                  1
+#endif
+
+/**
+ * MEMP_NUM_LOCALHOSTLIST: the number of host entries in the local host list
+ * if DNS_LOCAL_HOSTLIST_IS_DYNAMIC==1.
+ */
+#if !defined MEMP_NUM_LOCALHOSTLIST || defined __DOXYGEN__
+#define MEMP_NUM_LOCALHOSTLIST          1
+#endif
+
+/**
+ * PBUF_POOL_SIZE: the number of buffers in the pbuf pool.
+ */
+#if !defined PBUF_POOL_SIZE || defined __DOXYGEN__
+#define PBUF_POOL_SIZE                  16
+#endif
+
+/** MEMP_NUM_API_MSG: the number of concurrently active calls to various
+ * socket, netconn, and tcpip functions
+ */
+#if !defined MEMP_NUM_API_MSG || defined __DOXYGEN__
+#define MEMP_NUM_API_MSG                MEMP_NUM_TCPIP_MSG_API
+#endif
+
+/** MEMP_NUM_DNS_API_MSG: the number of concurrently active calls to netconn_gethostbyname
+ */
+#if !defined MEMP_NUM_DNS_API_MSG || defined __DOXYGEN__
+#define MEMP_NUM_DNS_API_MSG            MEMP_NUM_TCPIP_MSG_API
+#endif
+
+/** MEMP_NUM_SOCKET_SETGETSOCKOPT_DATA: the number of concurrently active calls
+ * to getsockopt/setsockopt
+ */
+#if !defined MEMP_NUM_SOCKET_SETGETSOCKOPT_DATA || defined __DOXYGEN__
+#define MEMP_NUM_SOCKET_SETGETSOCKOPT_DATA MEMP_NUM_TCPIP_MSG_API
+#endif
+
+/** MEMP_NUM_NETIFAPI_MSG: the number of concurrently active calls to the
+ * netifapi functions
+ */
+#if !defined MEMP_NUM_NETIFAPI_MSG || defined __DOXYGEN__
+#define MEMP_NUM_NETIFAPI_MSG           MEMP_NUM_TCPIP_MSG_API
+#endif
+/**
+ * @}
+ */
+
+/*
+   ---------------------------------
+   ---------- ARP options ----------
+   ---------------------------------
+*/
+/**
+ * @defgroup lwip_opts_arp ARP
+ * @ingroup lwip_opts_ipv4
+ * @{
+ */
+/**
+ * LWIP_ARP==1: Enable ARP functionality.
+ */
+#if !defined LWIP_ARP || defined __DOXYGEN__
+#define LWIP_ARP                        1
+#endif
+
+/**
+ * ARP_TABLE_SIZE: Number of active MAC-IP address pairs cached.
+ */
+#if !defined ARP_TABLE_SIZE || defined __DOXYGEN__
+#define ARP_TABLE_SIZE                  10
+#endif
+
+/** the time an ARP entry stays valid after its last update,
+ *  for ARP_TMR_INTERVAL = 1000, this is
+ *  (60 * 5) seconds = 5 minutes.
+ */
+#if !defined ARP_MAXAGE || defined __DOXYGEN__
+#define ARP_MAXAGE                      300
+#endif
+
+/**
+ * ARP_QUEUEING==1: Multiple outgoing packets are queued during hardware address
+ * resolution. By default, only the most recent packet is queued per IP address.
+ * This is sufficient for most protocols and mainly reduces TCP connection
+ * startup time. Set this to 1 if you know your application sends more than one
+ * packet in a row to an IP address that is not in the ARP cache.
+ */
+#if !defined ARP_QUEUEING || defined __DOXYGEN__
+#define ARP_QUEUEING                    0
+#endif
+
+/** The maximum number of packets which may be queued for each
+ *  unresolved address by other network layers. Defaults to 3, 0 means disabled.
+ *  Old packets are dropped, new packets are queued.
+ */
+#if !defined ARP_QUEUE_LEN || defined __DOXYGEN__
+#define ARP_QUEUE_LEN                   3
+#endif
+
+/**
+ * ETHARP_SUPPORT_VLAN==1: support receiving and sending ethernet packets with
+ * VLAN header. See the description of LWIP_HOOK_VLAN_CHECK and
+ * LWIP_HOOK_VLAN_SET hooks to check/set VLAN headers.
+ * Additionally, you can define ETHARP_VLAN_CHECK to an u16_t VLAN ID to check.
+ * If ETHARP_VLAN_CHECK is defined, only VLAN-traffic for this VLAN is accepted.
+ * If ETHARP_VLAN_CHECK is not defined, all traffic is accepted.
+ * Alternatively, define a function/define ETHARP_VLAN_CHECK_FN(eth_hdr, vlan)
+ * that returns 1 to accept a packet or 0 to drop a packet.
+ */
+#if !defined ETHARP_SUPPORT_VLAN || defined __DOXYGEN__
+#define ETHARP_SUPPORT_VLAN             0
+#endif
+
+/** LWIP_ETHERNET==1: enable ethernet support even though ARP might be disabled
+ */
+#if !defined LWIP_ETHERNET || defined __DOXYGEN__
+#define LWIP_ETHERNET                   LWIP_ARP
+#endif
+
+/** ETH_PAD_SIZE: number of bytes added before the ethernet header to ensure
+ * alignment of payload after that header. Since the header is 14 bytes long,
+ * without this padding e.g. addresses in the IP header will not be aligned
+ * on a 32-bit boundary, so setting this to 2 can speed up 32-bit-platforms.
+ */
+#if !defined ETH_PAD_SIZE || defined __DOXYGEN__
+#define ETH_PAD_SIZE                    0
+#endif
+
+/** ETHARP_SUPPORT_STATIC_ENTRIES==1: enable code to support static ARP table
+ * entries (using etharp_add_static_entry/etharp_remove_static_entry).
+ */
+#if !defined ETHARP_SUPPORT_STATIC_ENTRIES || defined __DOXYGEN__
+#define ETHARP_SUPPORT_STATIC_ENTRIES   0
+#endif
+
+/** ETHARP_TABLE_MATCH_NETIF==1: Match netif for ARP table entries.
+ * If disabled, duplicate IP address on multiple netifs are not supported
+ * (but this should only occur for AutoIP).
+ */
+#if !defined ETHARP_TABLE_MATCH_NETIF || defined __DOXYGEN__
+#define ETHARP_TABLE_MATCH_NETIF        !LWIP_SINGLE_NETIF
+#endif
+/**
+ * @}
+ */
+
+/*
+   --------------------------------
+   ---------- IP options ----------
+   --------------------------------
+*/
+/**
+ * @defgroup lwip_opts_ipv4 IPv4
+ * @ingroup lwip_opts
+ * @{
+ */
+/**
+ * LWIP_IPV4==1: Enable IPv4
+ */
+#if !defined LWIP_IPV4 || defined __DOXYGEN__
+#define LWIP_IPV4                       1
+#endif
+
+/**
+ * IP_FORWARD==1: Enables the ability to forward IP packets across network
+ * interfaces. If you are going to run lwIP on a device with only one network
+ * interface, define this to 0.
+ */
+#if !defined IP_FORWARD || defined __DOXYGEN__
+#define IP_FORWARD                      0
+#endif
+
+/**
+ * IP_REASSEMBLY==1: Reassemble incoming fragmented IP packets. Note that
+ * this option does not affect outgoing packet sizes, which can be controlled
+ * via IP_FRAG.
+ */
+#if !defined IP_REASSEMBLY || defined __DOXYGEN__
+#define IP_REASSEMBLY                   1
+#endif
+
+/**
+ * IP_FRAG==1: Fragment outgoing IP packets if their size exceeds MTU. Note
+ * that this option does not affect incoming packet sizes, which can be
+ * controlled via IP_REASSEMBLY.
+ */
+#if !defined IP_FRAG || defined __DOXYGEN__
+#define IP_FRAG                         1
+#endif
+
+#if !LWIP_IPV4
+/* disable IPv4 extensions when IPv4 is disabled */
+#undef IP_FORWARD
+#define IP_FORWARD                      0
+#undef IP_REASSEMBLY
+#define IP_REASSEMBLY                   0
+#undef IP_FRAG
+#define IP_FRAG                         0
+#endif /* !LWIP_IPV4 */
+
+/**
+ * IP_OPTIONS_ALLOWED: Defines the behavior for IP options.
+ *      IP_OPTIONS_ALLOWED==0: All packets with IP options are dropped.
+ *      IP_OPTIONS_ALLOWED==1: IP options are allowed (but not parsed).
+ */
+#if !defined IP_OPTIONS_ALLOWED || defined __DOXYGEN__
+#define IP_OPTIONS_ALLOWED              1
+#endif
+
+/**
+ * IP_REASS_MAXAGE: Maximum time (in multiples of IP_TMR_INTERVAL - so seconds, normally)
+ * a fragmented IP packet waits for all fragments to arrive. If not all fragments arrived
+ * in this time, the whole packet is discarded.
+ */
+#if !defined IP_REASS_MAXAGE || defined __DOXYGEN__
+#define IP_REASS_MAXAGE                 15
+#endif
+
+/**
+ * IP_REASS_MAX_PBUFS: Total maximum amount of pbufs waiting to be reassembled.
+ * Since the received pbufs are enqueued, be sure to configure
+ * PBUF_POOL_SIZE > IP_REASS_MAX_PBUFS so that the stack is still able to receive
+ * packets even if the maximum amount of fragments is enqueued for reassembly!
+ * When IPv4 *and* IPv6 are enabled, this even changes to
+ * (PBUF_POOL_SIZE > 2 * IP_REASS_MAX_PBUFS)!
+ */
+#if !defined IP_REASS_MAX_PBUFS || defined __DOXYGEN__
+#define IP_REASS_MAX_PBUFS              10
+#endif
+
+/**
+ * IP_DEFAULT_TTL: Default value for Time-To-Live used by transport layers.
+ */
+#if !defined IP_DEFAULT_TTL || defined __DOXYGEN__
+#define IP_DEFAULT_TTL                  255
+#endif
+
+/**
+ * IP_SOF_BROADCAST=1: Use the SOF_BROADCAST field to enable broadcast
+ * filter per pcb on udp and raw send operations. To enable broadcast filter
+ * on recv operations, you also have to set IP_SOF_BROADCAST_RECV=1.
+ */
+#if !defined IP_SOF_BROADCAST || defined __DOXYGEN__
+#define IP_SOF_BROADCAST                0
+#endif
+
+/**
+ * IP_SOF_BROADCAST_RECV (requires IP_SOF_BROADCAST=1) enable the broadcast
+ * filter on recv operations.
+ */
+#if !defined IP_SOF_BROADCAST_RECV || defined __DOXYGEN__
+#define IP_SOF_BROADCAST_RECV           0
+#endif
+
+/**
+ * IP_FORWARD_ALLOW_TX_ON_RX_NETIF==1: allow ip_forward() to send packets back
+ * out on the netif where it was received. This should only be used for
+ * wireless networks.
+ * ATTENTION: When this is 1, make sure your netif driver correctly marks incoming
+ * link-layer-broadcast/multicast packets as such using the corresponding pbuf flags!
+ */
+#if !defined IP_FORWARD_ALLOW_TX_ON_RX_NETIF || defined __DOXYGEN__
+#define IP_FORWARD_ALLOW_TX_ON_RX_NETIF 0
+#endif
+/**
+ * @}
+ */
+
+/*
+   ----------------------------------
+   ---------- ICMP options ----------
+   ----------------------------------
+*/
+/**
+ * @defgroup lwip_opts_icmp ICMP
+ * @ingroup lwip_opts_ipv4
+ * @{
+ */
+/**
+ * LWIP_ICMP==1: Enable ICMP module inside the IP stack.
+ * Be careful, disable that make your product non-compliant to RFC1122
+ */
+#if !defined LWIP_ICMP || defined __DOXYGEN__
+#define LWIP_ICMP                       1
+#endif
+
+/**
+ * ICMP_TTL: Default value for Time-To-Live used by ICMP packets.
+ */
+#if !defined ICMP_TTL || defined __DOXYGEN__
+#define ICMP_TTL                        IP_DEFAULT_TTL
+#endif
+
+/**
+ * LWIP_BROADCAST_PING==1: respond to broadcast pings (default is unicast only)
+ */
+#if !defined LWIP_BROADCAST_PING || defined __DOXYGEN__
+#define LWIP_BROADCAST_PING             0
+#endif
+
+/**
+ * LWIP_MULTICAST_PING==1: respond to multicast pings (default is unicast only)
+ */
+#if !defined LWIP_MULTICAST_PING || defined __DOXYGEN__
+#define LWIP_MULTICAST_PING             0
+#endif
+/**
+ * @}
+ */
+
+/*
+   ---------------------------------
+   ---------- RAW options ----------
+   ---------------------------------
+*/
+/**
+ * @defgroup lwip_opts_raw RAW
+ * @ingroup lwip_opts_callback
+ * @{
+ */
+/**
+ * LWIP_RAW==1: Enable application layer to hook into the IP layer itself.
+ */
+#if !defined LWIP_RAW || defined __DOXYGEN__
+#define LWIP_RAW                        0
+#endif
+
+/**
+ * LWIP_RAW==1: Enable application layer to hook into the IP layer itself.
+ */
+#if !defined RAW_TTL || defined __DOXYGEN__
+#define RAW_TTL                         IP_DEFAULT_TTL
+#endif
+/**
+ * @}
+ */
+
+/*
+   ----------------------------------
+   ---------- DHCP options ----------
+   ----------------------------------
+*/
+/**
+ * @defgroup lwip_opts_dhcp DHCP
+ * @ingroup lwip_opts_ipv4
+ * @{
+ */
+/**
+ * LWIP_DHCP==1: Enable DHCP module.
+ */
+#if !defined LWIP_DHCP || defined __DOXYGEN__
+#define LWIP_DHCP                       0
+#endif
+#if !LWIP_IPV4
+/* disable DHCP when IPv4 is disabled */
+#undef LWIP_DHCP
+#define LWIP_DHCP                       0
+#endif /* !LWIP_IPV4 */
+
+/**
+ * DHCP_DOES_ARP_CHECK==1: Do an ARP check on the offered address.
+ */
+#if !defined DHCP_DOES_ARP_CHECK || defined __DOXYGEN__
+#define DHCP_DOES_ARP_CHECK             (LWIP_DHCP && LWIP_ARP)
+#endif
+
+/**
+ * LWIP_DHCP_BOOTP_FILE==1: Store offered_si_addr and boot_file_name.
+ */
+#if !defined LWIP_DHCP_BOOTP_FILE || defined __DOXYGEN__
+#define LWIP_DHCP_BOOTP_FILE            0
+#endif
+
+/**
+ * LWIP_DHCP_GETS_NTP==1: Request NTP servers with discover/select. For each
+ * response packet, an callback is called, which has to be provided by the port:
+ * void dhcp_set_ntp_servers(u8_t num_ntp_servers, ip_addr_t* ntp_server_addrs);
+*/
+#if !defined LWIP_DHCP_GET_NTP_SRV || defined __DOXYGEN__
+#define LWIP_DHCP_GET_NTP_SRV           0
+#endif
+
+/**
+ * The maximum of NTP servers requested
+ */
+#if !defined LWIP_DHCP_MAX_NTP_SERVERS || defined __DOXYGEN__
+#define LWIP_DHCP_MAX_NTP_SERVERS       1
+#endif
+
+/**
+ * LWIP_DHCP_MAX_DNS_SERVERS > 0: Request DNS servers with discover/select.
+ * DNS servers received in the response are passed to DNS via @ref dns_setserver()
+ * (up to the maximum limit defined here).
+ */
+#if !defined LWIP_DHCP_MAX_DNS_SERVERS || defined __DOXYGEN__
+#define LWIP_DHCP_MAX_DNS_SERVERS       DNS_MAX_SERVERS
+#endif
+/**
+ * @}
+ */
+
+/*
+   ------------------------------------
+   ---------- AUTOIP options ----------
+   ------------------------------------
+*/
+/**
+ * @defgroup lwip_opts_autoip AUTOIP
+ * @ingroup lwip_opts_ipv4
+ * @{
+ */
+/**
+ * LWIP_AUTOIP==1: Enable AUTOIP module.
+ */
+#if !defined LWIP_AUTOIP || defined __DOXYGEN__
+#define LWIP_AUTOIP                     0
+#endif
+#if !LWIP_IPV4
+/* disable AUTOIP when IPv4 is disabled */
+#undef LWIP_AUTOIP
+#define LWIP_AUTOIP                     0
+#endif /* !LWIP_IPV4 */
+
+/**
+ * LWIP_DHCP_AUTOIP_COOP==1: Allow DHCP and AUTOIP to be both enabled on
+ * the same interface at the same time.
+ */
+#if !defined LWIP_DHCP_AUTOIP_COOP || defined __DOXYGEN__
+#define LWIP_DHCP_AUTOIP_COOP           0
+#endif
+
+/**
+ * LWIP_DHCP_AUTOIP_COOP_TRIES: Set to the number of DHCP DISCOVER probes
+ * that should be sent before falling back on AUTOIP (the DHCP client keeps
+ * running in this case). This can be set as low as 1 to get an AutoIP address
+ * very  quickly, but you should be prepared to handle a changing IP address
+ * when DHCP overrides AutoIP.
+ */
+#if !defined LWIP_DHCP_AUTOIP_COOP_TRIES || defined __DOXYGEN__
+#define LWIP_DHCP_AUTOIP_COOP_TRIES     9
+#endif
+/**
+ * @}
+ */
+
+/*
+   ----------------------------------
+   ----- SNMP MIB2 support      -----
+   ----------------------------------
+*/
+/**
+ * @defgroup lwip_opts_mib2 SNMP MIB2 callbacks
+ * @ingroup lwip_opts_infrastructure
+ * @{
+ */
+/**
+ * LWIP_MIB2_CALLBACKS==1: Turn on SNMP MIB2 callbacks.
+ * Turn this on to get callbacks needed to implement MIB2.
+ * Usually MIB2_STATS should be enabled, too.
+ */
+#if !defined LWIP_MIB2_CALLBACKS || defined __DOXYGEN__
+#define LWIP_MIB2_CALLBACKS             0
+#endif
+/**
+ * @}
+ */
+
+/*
+   ----------------------------------
+   -------- Multicast options -------
+   ----------------------------------
+*/
+/**
+ * @defgroup lwip_opts_multicast Multicast
+ * @ingroup lwip_opts_infrastructure
+ * @{
+ */
+/**
+ * LWIP_MULTICAST_TX_OPTIONS==1: Enable multicast TX support like the socket options
+ * IP_MULTICAST_TTL/IP_MULTICAST_IF/IP_MULTICAST_LOOP, as well as (currently only)
+ * core support for the corresponding IPv6 options.
+ */
+#if !defined LWIP_MULTICAST_TX_OPTIONS || defined __DOXYGEN__
+#define LWIP_MULTICAST_TX_OPTIONS       ((LWIP_IGMP || LWIP_IPV6_MLD) && (LWIP_UDP || LWIP_RAW))
+#endif
+/**
+ * @}
+ */
+
+/*
+   ----------------------------------
+   ---------- IGMP options ----------
+   ----------------------------------
+*/
+/**
+ * @defgroup lwip_opts_igmp IGMP
+ * @ingroup lwip_opts_ipv4
+ * @{
+ */
+/**
+ * LWIP_IGMP==1: Turn on IGMP module.
+ */
+#if !defined LWIP_IGMP || defined __DOXYGEN__
+#define LWIP_IGMP                       0
+#endif
+#if !LWIP_IPV4
+#undef LWIP_IGMP
+#define LWIP_IGMP                       0
+#endif
+/**
+ * @}
+ */
+
+/*
+   ----------------------------------
+   ---------- DNS options -----------
+   ----------------------------------
+*/
+/**
+ * @defgroup lwip_opts_dns DNS
+ * @ingroup lwip_opts_callback
+ * @{
+ */
+/**
+ * LWIP_DNS==1: Turn on DNS module. UDP must be available for DNS
+ * transport.
+ */
+#if !defined LWIP_DNS || defined __DOXYGEN__
+#define LWIP_DNS                        0
+#endif
+
+/** DNS maximum number of entries to maintain locally. */
+#if !defined DNS_TABLE_SIZE || defined __DOXYGEN__
+#define DNS_TABLE_SIZE                  4
+#endif
+
+/** DNS maximum host name length supported in the name table. */
+#if !defined DNS_MAX_NAME_LENGTH || defined __DOXYGEN__
+#define DNS_MAX_NAME_LENGTH             256
+#endif
+
+/** The maximum of DNS servers
+ * The first server can be initialized automatically by defining
+ * DNS_SERVER_ADDRESS(ipaddr), where 'ipaddr' is an 'ip_addr_t*'
+ */
+#if !defined DNS_MAX_SERVERS || defined __DOXYGEN__
+#define DNS_MAX_SERVERS                 2
+#endif
+
+/** DNS maximum number of retries when asking for a name, before "timeout". */
+#if !defined DNS_MAX_RETRIES || defined __DOXYGEN__
+#define DNS_MAX_RETRIES                 4
+#endif
+
+/** DNS do a name checking between the query and the response. */
+#if !defined DNS_DOES_NAME_CHECK || defined __DOXYGEN__
+#define DNS_DOES_NAME_CHECK             1
+#endif
+
+/** LWIP_DNS_SECURE: controls the security level of the DNS implementation
+ * Use all DNS security features by default.
+ * This is overridable but should only be needed by very small targets
+ * or when using against non standard DNS servers. */
+#if !defined LWIP_DNS_SECURE || defined __DOXYGEN__
+#define LWIP_DNS_SECURE (LWIP_DNS_SECURE_RAND_XID | LWIP_DNS_SECURE_NO_MULTIPLE_OUTSTANDING | LWIP_DNS_SECURE_RAND_SRC_PORT)
+#endif
+
+/* A list of DNS security features follows */
+#define LWIP_DNS_SECURE_RAND_XID                1
+#define LWIP_DNS_SECURE_NO_MULTIPLE_OUTSTANDING 2
+#define LWIP_DNS_SECURE_RAND_SRC_PORT           4
+
+/** DNS_LOCAL_HOSTLIST: Implements a local host-to-address list. If enabled, you have to define an initializer:
+ *  \#define DNS_LOCAL_HOSTLIST_INIT {DNS_LOCAL_HOSTLIST_ELEM("host_ip4", IPADDR4_INIT_BYTES(1,2,3,4)), \
+ *                                    DNS_LOCAL_HOSTLIST_ELEM("host_ip6", IPADDR6_INIT_HOST(123, 234, 345, 456)}
+ *
+ *  Instead, you can also use an external function:
+ *  \#define DNS_LOOKUP_LOCAL_EXTERN(x) extern err_t my_lookup_function(const char *name, ip_addr_t *addr, u8_t dns_addrtype)
+ *  that looks up the IP address and returns ERR_OK if found (LWIP_DNS_ADDRTYPE_xxx is passed in dns_addrtype).
+ */
+#if !defined DNS_LOCAL_HOSTLIST || defined __DOXYGEN__
+#define DNS_LOCAL_HOSTLIST              0
+#endif /* DNS_LOCAL_HOSTLIST */
+
+/** If this is turned on, the local host-list can be dynamically changed
+ *  at runtime. */
+#if !defined DNS_LOCAL_HOSTLIST_IS_DYNAMIC || defined __DOXYGEN__
+#define DNS_LOCAL_HOSTLIST_IS_DYNAMIC   0
+#endif /* DNS_LOCAL_HOSTLIST_IS_DYNAMIC */
+
+/** Set this to 1 to enable querying ".local" names via mDNS
+ *  using a One-Shot Multicast DNS Query */
+#if !defined LWIP_DNS_SUPPORT_MDNS_QUERIES || defined __DOXYGEN__
+#define LWIP_DNS_SUPPORT_MDNS_QUERIES   0
+#endif
+/**
+ * @}
+ */
+
+/*
+   ---------------------------------
+   ---------- UDP options ----------
+   ---------------------------------
+*/
+/**
+ * @defgroup lwip_opts_udp UDP
+ * @ingroup lwip_opts_callback
+ * @{
+ */
+/**
+ * LWIP_UDP==1: Turn on UDP.
+ */
+#if !defined LWIP_UDP || defined __DOXYGEN__
+#define LWIP_UDP                        1
+#endif
+
+/**
+ * LWIP_UDPLITE==1: Turn on UDP-Lite. (Requires LWIP_UDP)
+ */
+#if !defined LWIP_UDPLITE || defined __DOXYGEN__
+#define LWIP_UDPLITE                    0
+#endif
+
+/**
+ * UDP_TTL: Default Time-To-Live value.
+ */
+#if !defined UDP_TTL || defined __DOXYGEN__
+#define UDP_TTL                         IP_DEFAULT_TTL
+#endif
+
+/**
+ * LWIP_NETBUF_RECVINFO==1: append destination addr and port to every netbuf.
+ */
+#if !defined LWIP_NETBUF_RECVINFO || defined __DOXYGEN__
+#define LWIP_NETBUF_RECVINFO            0
+#endif
+/**
+ * @}
+ */
+
+/*
+   ---------------------------------
+   ---------- TCP options ----------
+   ---------------------------------
+*/
+/**
+ * @defgroup lwip_opts_tcp TCP
+ * @ingroup lwip_opts_callback
+ * @{
+ */
+/**
+ * LWIP_TCP==1: Turn on TCP.
+ */
+#if !defined LWIP_TCP || defined __DOXYGEN__
+#define LWIP_TCP                        1
+#endif
+
+/**
+ * TCP_TTL: Default Time-To-Live value.
+ */
+#if !defined TCP_TTL || defined __DOXYGEN__
+#define TCP_TTL                         IP_DEFAULT_TTL
+#endif
+
+/**
+ * TCP_WND: The size of a TCP window.  This must be at least
+ * (2 * TCP_MSS) for things to work well.
+ * ATTENTION: when using TCP_RCV_SCALE, TCP_WND is the total size
+ * with scaling applied. Maximum window value in the TCP header
+ * will be TCP_WND >> TCP_RCV_SCALE
+ */
+#if !defined TCP_WND || defined __DOXYGEN__
+#define TCP_WND                         (4 * TCP_MSS)
+#endif
+
+/**
+ * TCP_MAXRTX: Maximum number of retransmissions of data segments.
+ */
+#if !defined TCP_MAXRTX || defined __DOXYGEN__
+#define TCP_MAXRTX                      12
+#endif
+
+/**
+ * TCP_SYNMAXRTX: Maximum number of retransmissions of SYN segments.
+ */
+#if !defined TCP_SYNMAXRTX || defined __DOXYGEN__
+#define TCP_SYNMAXRTX                   6
+#endif
+
+/**
+ * TCP_QUEUE_OOSEQ==1: TCP will queue segments that arrive out of order.
+ * Define to 0 if your device is low on memory.
+ */
+#if !defined TCP_QUEUE_OOSEQ || defined __DOXYGEN__
+#define TCP_QUEUE_OOSEQ                 LWIP_TCP
+#endif
+
+/**
+ * LWIP_TCP_SACK_OUT==1: TCP will support sending selective acknowledgements (SACKs).
+ */
+#if !defined LWIP_TCP_SACK_OUT || defined __DOXYGEN__
+#define LWIP_TCP_SACK_OUT               0
+#endif
+
+/**
+ * LWIP_TCP_MAX_SACK_NUM: The maximum number of SACK values to include in TCP segments.
+ * Must be at least 1, but is only used if LWIP_TCP_SACK_OUT is enabled.
+ * NOTE: Even though we never send more than 3 or 4 SACK ranges in a single segment
+ * (depending on other options), setting this option to values greater than 4 is not pointless.
+ * This is basically the max number of SACK ranges we want to keep track of.
+ * As new data is delivered, some of the SACK ranges may be removed or merged.
+ * In that case some of those older SACK ranges may be used again.
+ * The amount of memory used to store SACK ranges is LWIP_TCP_MAX_SACK_NUM * 8 bytes for each TCP PCB.
+ */
+#if !defined LWIP_TCP_MAX_SACK_NUM || defined __DOXYGEN__
+#define LWIP_TCP_MAX_SACK_NUM           4
+#endif
+
+/**
+ * TCP_MSS: TCP Maximum segment size. (default is 536, a conservative default,
+ * you might want to increase this.)
+ * For the receive side, this MSS is advertised to the remote side
+ * when opening a connection. For the transmit size, this MSS sets
+ * an upper limit on the MSS advertised by the remote host.
+ */
+#if !defined TCP_MSS || defined __DOXYGEN__
+#define TCP_MSS                         536
+#endif
+
+/**
+ * TCP_CALCULATE_EFF_SEND_MSS: "The maximum size of a segment that TCP really
+ * sends, the 'effective send MSS,' MUST be the smaller of the send MSS (which
+ * reflects the available reassembly buffer size at the remote host) and the
+ * largest size permitted by the IP layer" (RFC 1122)
+ * Setting this to 1 enables code that checks TCP_MSS against the MTU of the
+ * netif used for a connection and limits the MSS if it would be too big otherwise.
+ */
+#if !defined TCP_CALCULATE_EFF_SEND_MSS || defined __DOXYGEN__
+#define TCP_CALCULATE_EFF_SEND_MSS      1
+#endif
+
+
+/**
+ * TCP_SND_BUF: TCP sender buffer space (bytes).
+ * To achieve good performance, this should be at least 2 * TCP_MSS.
+ */
+#if !defined TCP_SND_BUF || defined __DOXYGEN__
+#define TCP_SND_BUF                     (2 * TCP_MSS)
+#endif
+
+/**
+ * TCP_SND_QUEUELEN: TCP sender buffer space (pbufs). This must be at least
+ * as much as (2 * TCP_SND_BUF/TCP_MSS) for things to work.
+ */
+#if !defined TCP_SND_QUEUELEN || defined __DOXYGEN__
+#define TCP_SND_QUEUELEN                ((4 * (TCP_SND_BUF) + (TCP_MSS - 1))/(TCP_MSS))
+#endif
+
+/**
+ * TCP_SNDLOWAT: TCP writable space (bytes). This must be less than
+ * TCP_SND_BUF. It is the amount of space which must be available in the
+ * TCP snd_buf for select to return writable (combined with TCP_SNDQUEUELOWAT).
+ */
+#if !defined TCP_SNDLOWAT || defined __DOXYGEN__
+#define TCP_SNDLOWAT                    LWIP_MIN(LWIP_MAX(((TCP_SND_BUF)/2), (2 * TCP_MSS) + 1), (TCP_SND_BUF) - 1)
+#endif
+
+/**
+ * TCP_SNDQUEUELOWAT: TCP writable bufs (pbuf count). This must be less
+ * than TCP_SND_QUEUELEN. If the number of pbufs queued on a pcb drops below
+ * this number, select returns writable (combined with TCP_SNDLOWAT).
+ */
+#if !defined TCP_SNDQUEUELOWAT || defined __DOXYGEN__
+#define TCP_SNDQUEUELOWAT               LWIP_MAX(((TCP_SND_QUEUELEN)/2), 5)
+#endif
+
+/**
+ * TCP_OOSEQ_MAX_BYTES: The default maximum number of bytes queued on ooseq per
+ * pcb if TCP_OOSEQ_BYTES_LIMIT is not defined. Default is 0 (no limit).
+ * Only valid for TCP_QUEUE_OOSEQ==1.
+ */
+#if !defined TCP_OOSEQ_MAX_BYTES || defined __DOXYGEN__
+#define TCP_OOSEQ_MAX_BYTES             0
+#endif
+
+/**
+ * TCP_OOSEQ_BYTES_LIMIT(pcb): Return the maximum number of bytes to be queued
+ * on ooseq per pcb, given the pcb. Only valid for TCP_QUEUE_OOSEQ==1 &&
+ * TCP_OOSEQ_MAX_BYTES==1.
+ * Use this to override TCP_OOSEQ_MAX_BYTES to a dynamic value per pcb.
+ */
+#if !defined TCP_OOSEQ_BYTES_LIMIT
+#if TCP_OOSEQ_MAX_BYTES
+#define TCP_OOSEQ_BYTES_LIMIT(pcb)      TCP_OOSEQ_MAX_BYTES
+#elif defined __DOXYGEN__
+#define TCP_OOSEQ_BYTES_LIMIT(pcb)
+#endif
+#endif
+
+/**
+ * TCP_OOSEQ_MAX_PBUFS: The default maximum number of pbufs queued on ooseq per
+ * pcb if TCP_OOSEQ_BYTES_LIMIT is not defined. Default is 0 (no limit).
+ * Only valid for TCP_QUEUE_OOSEQ==1.
+ */
+#if !defined TCP_OOSEQ_MAX_PBUFS || defined __DOXYGEN__
+#define TCP_OOSEQ_MAX_PBUFS             0
+#endif
+
+/**
+ * TCP_OOSEQ_PBUFS_LIMIT(pcb): Return the maximum number of pbufs to be queued
+ * on ooseq per pcb, given the pcb.  Only valid for TCP_QUEUE_OOSEQ==1 &&
+ * TCP_OOSEQ_MAX_PBUFS==1.
+ * Use this to override TCP_OOSEQ_MAX_PBUFS to a dynamic value per pcb.
+ */
+#if !defined TCP_OOSEQ_PBUFS_LIMIT
+#if TCP_OOSEQ_MAX_PBUFS
+#define TCP_OOSEQ_PBUFS_LIMIT(pcb)      TCP_OOSEQ_MAX_PBUFS
+#elif defined __DOXYGEN__
+#define TCP_OOSEQ_PBUFS_LIMIT(pcb)
+#endif
+#endif
+
+/**
+ * TCP_LISTEN_BACKLOG: Enable the backlog option for tcp listen pcb.
+ */
+#if !defined TCP_LISTEN_BACKLOG || defined __DOXYGEN__
+#define TCP_LISTEN_BACKLOG              0
+#endif
+
+/**
+ * The maximum allowed backlog for TCP listen netconns.
+ * This backlog is used unless another is explicitly specified.
+ * 0xff is the maximum (u8_t).
+ */
+#if !defined TCP_DEFAULT_LISTEN_BACKLOG || defined __DOXYGEN__
+#define TCP_DEFAULT_LISTEN_BACKLOG      0xff
+#endif
+
+/**
+ * TCP_OVERSIZE: The maximum number of bytes that tcp_write may
+ * allocate ahead of time in an attempt to create shorter pbuf chains
+ * for transmission. The meaningful range is 0 to TCP_MSS. Some
+ * suggested values are:
+ *
+ * 0:         Disable oversized allocation. Each tcp_write() allocates a new
+              pbuf (old behaviour).
+ * 1:         Allocate size-aligned pbufs with minimal excess. Use this if your
+ *            scatter-gather DMA requires aligned fragments.
+ * 128:       Limit the pbuf/memory overhead to 20%.
+ * TCP_MSS:   Try to create unfragmented TCP packets.
+ * TCP_MSS/4: Try to create 4 fragments or less per TCP packet.
+ */
+#if !defined TCP_OVERSIZE || defined __DOXYGEN__
+#define TCP_OVERSIZE                    TCP_MSS
+#endif
+
+/**
+ * LWIP_TCP_TIMESTAMPS==1: support the TCP timestamp option.
+ * The timestamp option is currently only used to help remote hosts, it is not
+ * really used locally. Therefore, it is only enabled when a TS option is
+ * received in the initial SYN packet from a remote host.
+ */
+#if !defined LWIP_TCP_TIMESTAMPS || defined __DOXYGEN__
+#define LWIP_TCP_TIMESTAMPS             0
+#endif
+
+/**
+ * TCP_WND_UPDATE_THRESHOLD: difference in window to trigger an
+ * explicit window update
+ */
+#if !defined TCP_WND_UPDATE_THRESHOLD || defined __DOXYGEN__
+#define TCP_WND_UPDATE_THRESHOLD        LWIP_MIN((TCP_WND / 4), (TCP_MSS * 4))
+#endif
+
+/**
+ * LWIP_EVENT_API and LWIP_CALLBACK_API: Only one of these should be set to 1.
+ *     LWIP_EVENT_API==1: The user defines lwip_tcp_event() to receive all
+ *         events (accept, sent, etc) that happen in the system.
+ *     LWIP_CALLBACK_API==1: The PCB callback function is called directly
+ *         for the event. This is the default.
+ */
+#if !defined(LWIP_EVENT_API) && !defined(LWIP_CALLBACK_API) || defined __DOXYGEN__
+#define LWIP_EVENT_API                  0
+#define LWIP_CALLBACK_API               1
+#else
+#ifndef LWIP_EVENT_API
+#define LWIP_EVENT_API                  0
+#endif
+#ifndef LWIP_CALLBACK_API
+#define LWIP_CALLBACK_API               0
+#endif
+#endif
+
+/**
+ * LWIP_WND_SCALE and TCP_RCV_SCALE:
+ * Set LWIP_WND_SCALE to 1 to enable window scaling.
+ * Set TCP_RCV_SCALE to the desired scaling factor (shift count in the
+ * range of [0..14]).
+ * When LWIP_WND_SCALE is enabled but TCP_RCV_SCALE is 0, we can use a large
+ * send window while having a small receive window only.
+ */
+#if !defined LWIP_WND_SCALE || defined __DOXYGEN__
+#define LWIP_WND_SCALE                  0
+#define TCP_RCV_SCALE                   0
+#endif
+
+/**
+ * LWIP_TCP_PCB_NUM_EXT_ARGS:
+ * When this is > 0, every tcp pcb (including listen pcb) includes a number of
+ * additional argument entries in an array (see tcp_ext_arg_alloc_id)
+ */
+#if !defined LWIP_TCP_PCB_NUM_EXT_ARGS || defined __DOXYGEN__
+#define LWIP_TCP_PCB_NUM_EXT_ARGS       0
+#endif
+
+/** LWIP_ALTCP==1: enable the altcp API.
+ * altcp is an abstraction layer that prevents applications linking against the
+ * tcp.h functions but provides the same functionality. It is used to e.g. add
+ * SSL/TLS or proxy-connect support to an application written for the tcp callback
+ * API without that application knowing the protocol details.
+ *
+ * With LWIP_ALTCP==0, applications written against the altcp API can still be
+ * compiled but are directly linked against the tcp.h callback API and then
+ * cannot use layered protocols.
+ *
+ * See @ref altcp_api
+ */
+#if !defined LWIP_ALTCP || defined __DOXYGEN__
+#define LWIP_ALTCP                      0
+#endif
+
+/** LWIP_ALTCP_TLS==1: enable TLS support for altcp API.
+ * This needs a port of the functions in altcp_tls.h to a TLS library.
+ * A port to ARM mbedtls is provided with lwIP, see apps/altcp_tls/ directory
+ * and LWIP_ALTCP_TLS_MBEDTLS option.
+ */
+#if !defined LWIP_ALTCP_TLS || defined __DOXYGEN__
+#define LWIP_ALTCP_TLS                  0
+#endif
+
+/**
+ * @}
+ */
+
+/*
+   ----------------------------------
+   ---------- Pbuf options ----------
+   ----------------------------------
+*/
+/**
+ * @defgroup lwip_opts_pbuf PBUF
+ * @ingroup lwip_opts
+ * @{
+ */
+/**
+ * PBUF_LINK_HLEN: the number of bytes that should be allocated for a
+ * link level header. The default is 14, the standard value for
+ * Ethernet.
+ */
+#if !defined PBUF_LINK_HLEN || defined __DOXYGEN__
+#if defined LWIP_HOOK_VLAN_SET && !defined __DOXYGEN__
+#define PBUF_LINK_HLEN                  (18 + ETH_PAD_SIZE)
+#else /* LWIP_HOOK_VLAN_SET */
+#define PBUF_LINK_HLEN                  (14 + ETH_PAD_SIZE)
+#endif /* LWIP_HOOK_VLAN_SET */
+#endif
+
+/**
+ * PBUF_LINK_ENCAPSULATION_HLEN: the number of bytes that should be allocated
+ * for an additional encapsulation header before ethernet headers (e.g. 802.11)
+ */
+#if !defined PBUF_LINK_ENCAPSULATION_HLEN || defined __DOXYGEN__
+#define PBUF_LINK_ENCAPSULATION_HLEN    0
+#endif
+
+/**
+ * PBUF_POOL_BUFSIZE: the size of each pbuf in the pbuf pool. The default is
+ * designed to accommodate single full size TCP frame in one pbuf, including
+ * TCP_MSS, IP header, and link header.
+ */
+#if !defined PBUF_POOL_BUFSIZE || defined __DOXYGEN__
+#define PBUF_POOL_BUFSIZE               LWIP_MEM_ALIGN_SIZE(TCP_MSS+40+PBUF_LINK_ENCAPSULATION_HLEN+PBUF_LINK_HLEN)
+#endif
+
+/**
+ * LWIP_PBUF_REF_T: Refcount type in pbuf.
+ * Default width of u8_t can be increased if 255 refs are not enough for you.
+ */
+#if !defined LWIP_PBUF_REF_T || defined __DOXYGEN__
+#define LWIP_PBUF_REF_T                 u8_t
+#endif
+/**
+ * @}
+ */
+
+/*
+   ------------------------------------------------
+   ---------- Network Interfaces options ----------
+   ------------------------------------------------
+*/
+/**
+ * @defgroup lwip_opts_netif NETIF
+ * @ingroup lwip_opts
+ * @{
+ */
+/**
+ * LWIP_SINGLE_NETIF==1: use a single netif only. This is the common case for
+ * small real-life targets. Some code like routing etc. can be left out.
+ */
+#if !defined LWIP_SINGLE_NETIF || defined __DOXYGEN__
+#define LWIP_SINGLE_NETIF               0
+#endif
+
+/**
+ * LWIP_NETIF_HOSTNAME==1: use DHCP_OPTION_HOSTNAME with netif's hostname
+ * field.
+ */
+#if !defined LWIP_NETIF_HOSTNAME || defined __DOXYGEN__
+#define LWIP_NETIF_HOSTNAME             0
+#endif
+
+/**
+ * LWIP_NETIF_API==1: Support netif api (in netifapi.c)
+ */
+#if !defined LWIP_NETIF_API || defined __DOXYGEN__
+#define LWIP_NETIF_API                  0
+#endif
+
+/**
+ * LWIP_NETIF_STATUS_CALLBACK==1: Support a callback function whenever an interface
+ * changes its up/down status (i.e., due to DHCP IP acquisition)
+ */
+#if !defined LWIP_NETIF_STATUS_CALLBACK || defined __DOXYGEN__
+#define LWIP_NETIF_STATUS_CALLBACK      0
+#endif
+
+/**
+ * LWIP_NETIF_EXT_STATUS_CALLBACK==1: Support an extended callback function 
+ * for several netif related event that supports multiple subscribers.
+ * @see netif_ext_status_callback
+ */
+#if !defined LWIP_NETIF_EXT_STATUS_CALLBACK || defined __DOXYGEN__
+#define LWIP_NETIF_EXT_STATUS_CALLBACK  0
+#endif
+
+/**
+ * LWIP_NETIF_LINK_CALLBACK==1: Support a callback function from an interface
+ * whenever the link changes (i.e., link down)
+ */
+#if !defined LWIP_NETIF_LINK_CALLBACK || defined __DOXYGEN__
+#define LWIP_NETIF_LINK_CALLBACK        0
+#endif
+
+/**
+ * LWIP_NETIF_REMOVE_CALLBACK==1: Support a callback function that is called
+ * when a netif has been removed
+ */
+#if !defined LWIP_NETIF_REMOVE_CALLBACK || defined __DOXYGEN__
+#define LWIP_NETIF_REMOVE_CALLBACK      0
+#endif
+
+/**
+ * LWIP_NETIF_HWADDRHINT==1: Cache link-layer-address hints (e.g. table
+ * indices) in struct netif. TCP and UDP can make use of this to prevent
+ * scanning the ARP table for every sent packet. While this is faster for big
+ * ARP tables or many concurrent connections, it might be counterproductive
+ * if you have a tiny ARP table or if there never are concurrent connections.
+ */
+#if !defined LWIP_NETIF_HWADDRHINT || defined __DOXYGEN__
+#define LWIP_NETIF_HWADDRHINT           0
+#endif
+
+/**
+ * LWIP_NETIF_TX_SINGLE_PBUF: if this is set to 1, lwIP *tries* to put all data
+ * to be sent into one single pbuf. This is for compatibility with DMA-enabled
+ * MACs that do not support scatter-gather.
+ * Beware that this might involve CPU-memcpy before transmitting that would not
+ * be needed without this flag! Use this only if you need to!
+ *
+ * ATTENTION: a driver should *NOT* rely on getting single pbufs but check TX
+ * pbufs for being in one piece. If not, @ref pbuf_clone can be used to get
+ * a single pbuf:
+ *   if (p->next != NULL) {
+ *     struct pbuf *q = pbuf_clone(PBUF_RAW, PBUF_RAM, p);
+ *     if (q == NULL) {
+ *       return ERR_MEM;
+ *     }
+ *     p = q; ATTENTION: do NOT free the old 'p' as the ref belongs to the caller!
+ *   }
+ */
+#if !defined LWIP_NETIF_TX_SINGLE_PBUF || defined __DOXYGEN__
+#define LWIP_NETIF_TX_SINGLE_PBUF       0
+#endif /* LWIP_NETIF_TX_SINGLE_PBUF */
+
+/**
+ * LWIP_NUM_NETIF_CLIENT_DATA: Number of clients that may store
+ * data in client_data member array of struct netif (max. 256).
+ */
+#if !defined LWIP_NUM_NETIF_CLIENT_DATA || defined __DOXYGEN__
+#define LWIP_NUM_NETIF_CLIENT_DATA      0
+#endif
+/**
+ * @}
+ */
+
+/*
+   ------------------------------------
+   ---------- LOOPIF options ----------
+   ------------------------------------
+*/
+/**
+ * @defgroup lwip_opts_loop Loopback interface
+ * @ingroup lwip_opts_netif
+ * @{
+ */
+/**
+ * LWIP_HAVE_LOOPIF==1: Support loop interface (127.0.0.1).
+ * This is only needed when no real netifs are available. If at least one other
+ * netif is available, loopback traffic uses this netif.
+ */
+#if !defined LWIP_HAVE_LOOPIF || defined __DOXYGEN__
+#define LWIP_HAVE_LOOPIF                (LWIP_NETIF_LOOPBACK && !LWIP_SINGLE_NETIF)
+#endif
+
+/**
+ * LWIP_LOOPIF_MULTICAST==1: Support multicast/IGMP on loop interface (127.0.0.1).
+ */
+#if !defined LWIP_LOOPIF_MULTICAST || defined __DOXYGEN__
+#define LWIP_LOOPIF_MULTICAST           0
+#endif
+
+/**
+ * LWIP_NETIF_LOOPBACK==1: Support sending packets with a destination IP
+ * address equal to the netif IP address, looping them back up the stack.
+ */
+#if !defined LWIP_NETIF_LOOPBACK || defined __DOXYGEN__
+#define LWIP_NETIF_LOOPBACK             0
+#endif
+
+/**
+ * LWIP_LOOPBACK_MAX_PBUFS: Maximum number of pbufs on queue for loopback
+ * sending for each netif (0 = disabled)
+ */
+#if !defined LWIP_LOOPBACK_MAX_PBUFS || defined __DOXYGEN__
+#define LWIP_LOOPBACK_MAX_PBUFS         0
+#endif
+
+/**
+ * LWIP_NETIF_LOOPBACK_MULTITHREADING: Indicates whether threading is enabled in
+ * the system, as netifs must change how they behave depending on this setting
+ * for the LWIP_NETIF_LOOPBACK option to work.
+ * Setting this is needed to avoid reentering non-reentrant functions like
+ * tcp_input().
+ *    LWIP_NETIF_LOOPBACK_MULTITHREADING==1: Indicates that the user is using a
+ *       multithreaded environment like tcpip.c. In this case, netif->input()
+ *       is called directly.
+ *    LWIP_NETIF_LOOPBACK_MULTITHREADING==0: Indicates a polling (or NO_SYS) setup.
+ *       The packets are put on a list and netif_poll() must be called in
+ *       the main application loop.
+ */
+#if !defined LWIP_NETIF_LOOPBACK_MULTITHREADING || defined __DOXYGEN__
+#define LWIP_NETIF_LOOPBACK_MULTITHREADING    (!NO_SYS)
+#endif
+/**
+ * @}
+ */
+
+/*
+   ------------------------------------
+   ---------- Thread options ----------
+   ------------------------------------
+*/
+/**
+ * @defgroup lwip_opts_thread Threading
+ * @ingroup lwip_opts_infrastructure
+ * @{
+ */
+/**
+ * TCPIP_THREAD_NAME: The name assigned to the main tcpip thread.
+ */
+#if !defined TCPIP_THREAD_NAME || defined __DOXYGEN__
+#define TCPIP_THREAD_NAME               "tcpip_thread"
+#endif
+
+/**
+ * TCPIP_THREAD_STACKSIZE: The stack size used by the main tcpip thread.
+ * The stack size value itself is platform-dependent, but is passed to
+ * sys_thread_new() when the thread is created.
+ */
+#if !defined TCPIP_THREAD_STACKSIZE || defined __DOXYGEN__
+#define TCPIP_THREAD_STACKSIZE          0
+#endif
+
+/**
+ * TCPIP_THREAD_PRIO: The priority assigned to the main tcpip thread.
+ * The priority value itself is platform-dependent, but is passed to
+ * sys_thread_new() when the thread is created.
+ */
+#if !defined TCPIP_THREAD_PRIO || defined __DOXYGEN__
+#define TCPIP_THREAD_PRIO               1
+#endif
+
+/**
+ * TCPIP_MBOX_SIZE: The mailbox size for the tcpip thread messages
+ * The queue size value itself is platform-dependent, but is passed to
+ * sys_mbox_new() when tcpip_init is called.
+ */
+#if !defined TCPIP_MBOX_SIZE || defined __DOXYGEN__
+#define TCPIP_MBOX_SIZE                 0
+#endif
+
+/**
+ * Define this to something that triggers a watchdog. This is called from
+ * tcpip_thread after processing a message.
+ */
+#if !defined LWIP_TCPIP_THREAD_ALIVE || defined __DOXYGEN__
+#define LWIP_TCPIP_THREAD_ALIVE()
+#endif
+
+/**
+ * SLIPIF_THREAD_NAME: The name assigned to the slipif_loop thread.
+ */
+#if !defined SLIPIF_THREAD_NAME || defined __DOXYGEN__
+#define SLIPIF_THREAD_NAME              "slipif_loop"
+#endif
+
+/**
+ * SLIP_THREAD_STACKSIZE: The stack size used by the slipif_loop thread.
+ * The stack size value itself is platform-dependent, but is passed to
+ * sys_thread_new() when the thread is created.
+ */
+#if !defined SLIPIF_THREAD_STACKSIZE || defined __DOXYGEN__
+#define SLIPIF_THREAD_STACKSIZE         0
+#endif
+
+/**
+ * SLIPIF_THREAD_PRIO: The priority assigned to the slipif_loop thread.
+ * The priority value itself is platform-dependent, but is passed to
+ * sys_thread_new() when the thread is created.
+ */
+#if !defined SLIPIF_THREAD_PRIO || defined __DOXYGEN__
+#define SLIPIF_THREAD_PRIO              1
+#endif
+
+/**
+ * DEFAULT_THREAD_NAME: The name assigned to any other lwIP thread.
+ */
+#if !defined DEFAULT_THREAD_NAME || defined __DOXYGEN__
+#define DEFAULT_THREAD_NAME             "lwIP"
+#endif
+
+/**
+ * DEFAULT_THREAD_STACKSIZE: The stack size used by any other lwIP thread.
+ * The stack size value itself is platform-dependent, but is passed to
+ * sys_thread_new() when the thread is created.
+ */
+#if !defined DEFAULT_THREAD_STACKSIZE || defined __DOXYGEN__
+#define DEFAULT_THREAD_STACKSIZE        0
+#endif
+
+/**
+ * DEFAULT_THREAD_PRIO: The priority assigned to any other lwIP thread.
+ * The priority value itself is platform-dependent, but is passed to
+ * sys_thread_new() when the thread is created.
+ */
+#if !defined DEFAULT_THREAD_PRIO || defined __DOXYGEN__
+#define DEFAULT_THREAD_PRIO             1
+#endif
+
+/**
+ * DEFAULT_RAW_RECVMBOX_SIZE: The mailbox size for the incoming packets on a
+ * NETCONN_RAW. The queue size value itself is platform-dependent, but is passed
+ * to sys_mbox_new() when the recvmbox is created.
+ */
+#if !defined DEFAULT_RAW_RECVMBOX_SIZE || defined __DOXYGEN__
+#define DEFAULT_RAW_RECVMBOX_SIZE       0
+#endif
+
+/**
+ * DEFAULT_UDP_RECVMBOX_SIZE: The mailbox size for the incoming packets on a
+ * NETCONN_UDP. The queue size value itself is platform-dependent, but is passed
+ * to sys_mbox_new() when the recvmbox is created.
+ */
+#if !defined DEFAULT_UDP_RECVMBOX_SIZE || defined __DOXYGEN__
+#define DEFAULT_UDP_RECVMBOX_SIZE       0
+#endif
+
+/**
+ * DEFAULT_TCP_RECVMBOX_SIZE: The mailbox size for the incoming packets on a
+ * NETCONN_TCP. The queue size value itself is platform-dependent, but is passed
+ * to sys_mbox_new() when the recvmbox is created.
+ */
+#if !defined DEFAULT_TCP_RECVMBOX_SIZE || defined __DOXYGEN__
+#define DEFAULT_TCP_RECVMBOX_SIZE       0
+#endif
+
+/**
+ * DEFAULT_ACCEPTMBOX_SIZE: The mailbox size for the incoming connections.
+ * The queue size value itself is platform-dependent, but is passed to
+ * sys_mbox_new() when the acceptmbox is created.
+ */
+#if !defined DEFAULT_ACCEPTMBOX_SIZE || defined __DOXYGEN__
+#define DEFAULT_ACCEPTMBOX_SIZE         0
+#endif
+/**
+ * @}
+ */
+
+/*
+   ----------------------------------------------
+   ---------- Sequential layer options ----------
+   ----------------------------------------------
+*/
+/**
+ * @defgroup lwip_opts_netconn Netconn
+ * @ingroup lwip_opts_threadsafe_apis
+ * @{
+ */
+/**
+ * LWIP_NETCONN==1: Enable Netconn API (require to use api_lib.c)
+ */
+#if !defined LWIP_NETCONN || defined __DOXYGEN__
+#define LWIP_NETCONN                    1
+#endif
+
+/** LWIP_TCPIP_TIMEOUT==1: Enable tcpip_timeout/tcpip_untimeout to create
+ * timers running in tcpip_thread from another thread.
+ */
+#if !defined LWIP_TCPIP_TIMEOUT || defined __DOXYGEN__
+#define LWIP_TCPIP_TIMEOUT              0
+#endif
+
+/** LWIP_NETCONN_SEM_PER_THREAD==1: Use one (thread-local) semaphore per
+ * thread calling socket/netconn functions instead of allocating one
+ * semaphore per netconn (and per select etc.)
+ * ATTENTION: a thread-local semaphore for API calls is needed:
+ * - LWIP_NETCONN_THREAD_SEM_GET() returning a sys_sem_t*
+ * - LWIP_NETCONN_THREAD_SEM_ALLOC() creating the semaphore
+ * - LWIP_NETCONN_THREAD_SEM_FREE() freeing the semaphore
+ * The latter 2 can be invoked up by calling netconn_thread_init()/netconn_thread_cleanup().
+ * Ports may call these for threads created with sys_thread_new().
+ */
+#if !defined LWIP_NETCONN_SEM_PER_THREAD || defined __DOXYGEN__
+#define LWIP_NETCONN_SEM_PER_THREAD     0
+#endif
+
+/** LWIP_NETCONN_FULLDUPLEX==1: Enable code that allows reading from one thread,
+ * writing from a 2nd thread and closing from a 3rd thread at the same time.
+ * ATTENTION: This is currently really alpha! Some requirements:
+ * - LWIP_NETCONN_SEM_PER_THREAD==1 is required to use one socket/netconn from
+ *   multiple threads at once
+ * - sys_mbox_free() has to unblock receive tasks waiting on recvmbox/acceptmbox
+ *   and prevent a task pending on this during/after deletion
+ */
+#if !defined LWIP_NETCONN_FULLDUPLEX || defined __DOXYGEN__
+#define LWIP_NETCONN_FULLDUPLEX         0
+#endif
+/**
+ * @}
+ */
+
+/*
+   ------------------------------------
+   ---------- Socket options ----------
+   ------------------------------------
+*/
+/**
+ * @defgroup lwip_opts_socket Sockets
+ * @ingroup lwip_opts_threadsafe_apis
+ * @{
+ */
+/**
+ * LWIP_SOCKET==1: Enable Socket API (require to use sockets.c)
+ */
+#if !defined LWIP_SOCKET || defined __DOXYGEN__
+#define LWIP_SOCKET                     1
+#endif
+
+/**
+ * LWIP_COMPAT_SOCKETS==1: Enable BSD-style sockets functions names through defines.
+ * LWIP_COMPAT_SOCKETS==2: Same as ==1 but correctly named functions are created.
+ * While this helps code completion, it might conflict with existing libraries.
+ * (only used if you use sockets.c)
+ */
+#if !defined LWIP_COMPAT_SOCKETS || defined __DOXYGEN__
+#define LWIP_COMPAT_SOCKETS             1
+#endif
+
+/**
+ * LWIP_POSIX_SOCKETS_IO_NAMES==1: Enable POSIX-style sockets functions names.
+ * Disable this option if you use a POSIX operating system that uses the same
+ * names (read, write & close). (only used if you use sockets.c)
+ */
+#if !defined LWIP_POSIX_SOCKETS_IO_NAMES || defined __DOXYGEN__
+#define LWIP_POSIX_SOCKETS_IO_NAMES     1
+#endif
+
+/**
+ * LWIP_SOCKET_OFFSET==n: Increases the file descriptor number created by LwIP with n.
+ * This can be useful when there are multiple APIs which create file descriptors.
+ * When they all start with a different offset and you won't make them overlap you can
+ * re implement read/write/close/ioctl/fnctl to send the requested action to the right
+ * library (sharing select will need more work though).
+ */
+#if !defined LWIP_SOCKET_OFFSET || defined __DOXYGEN__
+#define LWIP_SOCKET_OFFSET              0
+#endif
+
+/**
+ * LWIP_TCP_KEEPALIVE==1: Enable TCP_KEEPIDLE, TCP_KEEPINTVL and TCP_KEEPCNT
+ * options processing. Note that TCP_KEEPIDLE and TCP_KEEPINTVL have to be set
+ * in seconds. (does not require sockets.c, and will affect tcp.c)
+ */
+#if !defined LWIP_TCP_KEEPALIVE || defined __DOXYGEN__
+#define LWIP_TCP_KEEPALIVE              0
+#endif
+
+/**
+ * LWIP_SO_SNDTIMEO==1: Enable send timeout for sockets/netconns and
+ * SO_SNDTIMEO processing.
+ */
+#if !defined LWIP_SO_SNDTIMEO || defined __DOXYGEN__
+#define LWIP_SO_SNDTIMEO                0
+#endif
+
+/**
+ * LWIP_SO_RCVTIMEO==1: Enable receive timeout for sockets/netconns and
+ * SO_RCVTIMEO processing.
+ */
+#if !defined LWIP_SO_RCVTIMEO || defined __DOXYGEN__
+#define LWIP_SO_RCVTIMEO                0
+#endif
+
+/**
+ * LWIP_SO_SNDRCVTIMEO_NONSTANDARD==1: SO_RCVTIMEO/SO_SNDTIMEO take an int
+ * (milliseconds, much like winsock does) instead of a struct timeval (default).
+ */
+#if !defined LWIP_SO_SNDRCVTIMEO_NONSTANDARD || defined __DOXYGEN__
+#define LWIP_SO_SNDRCVTIMEO_NONSTANDARD 0
+#endif
+
+/**
+ * LWIP_SO_RCVBUF==1: Enable SO_RCVBUF processing.
+ */
+#if !defined LWIP_SO_RCVBUF || defined __DOXYGEN__
+#define LWIP_SO_RCVBUF                  0
+#endif
+
+/**
+ * LWIP_SO_LINGER==1: Enable SO_LINGER processing.
+ */
+#if !defined LWIP_SO_LINGER || defined __DOXYGEN__
+#define LWIP_SO_LINGER                  0
+#endif
+
+/**
+ * If LWIP_SO_RCVBUF is used, this is the default value for recv_bufsize.
+ */
+#if !defined RECV_BUFSIZE_DEFAULT || defined __DOXYGEN__
+#define RECV_BUFSIZE_DEFAULT            INT_MAX
+#endif
+
+/**
+ * By default, TCP socket/netconn close waits 20 seconds max to send the FIN
+ */
+#if !defined LWIP_TCP_CLOSE_TIMEOUT_MS_DEFAULT || defined __DOXYGEN__
+#define LWIP_TCP_CLOSE_TIMEOUT_MS_DEFAULT 20000
+#endif
+
+/**
+ * SO_REUSE==1: Enable SO_REUSEADDR option.
+ */
+#if !defined SO_REUSE || defined __DOXYGEN__
+#define SO_REUSE                        0
+#endif
+
+/**
+ * SO_REUSE_RXTOALL==1: Pass a copy of incoming broadcast/multicast packets
+ * to all local matches if SO_REUSEADDR is turned on.
+ * WARNING: Adds a memcpy for every packet if passing to more than one pcb!
+ */
+#if !defined SO_REUSE_RXTOALL || defined __DOXYGEN__
+#define SO_REUSE_RXTOALL                0
+#endif
+
+/**
+ * LWIP_FIONREAD_LINUXMODE==0 (default): ioctl/FIONREAD returns the amount of
+ * pending data in the network buffer. This is the way windows does it. It's
+ * the default for lwIP since it is smaller.
+ * LWIP_FIONREAD_LINUXMODE==1: ioctl/FIONREAD returns the size of the next
+ * pending datagram in bytes. This is the way linux does it. This code is only
+ * here for compatibility.
+ */
+#if !defined LWIP_FIONREAD_LINUXMODE || defined __DOXYGEN__
+#define LWIP_FIONREAD_LINUXMODE         0
+#endif
+
+/**
+ * LWIP_SOCKET_SELECT==1 (default): enable select() for sockets (uses a netconn
+ * callback to keep track of events).
+ * This saves RAM (counters per socket) and code (netconn event callback), which
+ * should improve performance a bit).
+ */
+#if !defined LWIP_SOCKET_SELECT || defined __DOXYGEN__
+#define LWIP_SOCKET_SELECT              1
+#endif
+
+/**
+ * LWIP_SOCKET_POLL==1 (default): enable poll() for sockets (including
+ * struct pollfd, nfds_t, and constants)
+ */
+#if !defined LWIP_SOCKET_POLL || defined __DOXYGEN__
+#define LWIP_SOCKET_POLL                1
+#endif
+/**
+ * @}
+ */
+
+/*
+   ----------------------------------------
+   ---------- Statistics options ----------
+   ----------------------------------------
+*/
+/**
+ * @defgroup lwip_opts_stats Statistics
+ * @ingroup lwip_opts_debug
+ * @{
+ */
+/**
+ * LWIP_STATS==1: Enable statistics collection in lwip_stats.
+ */
+#if !defined LWIP_STATS || defined __DOXYGEN__
+#define LWIP_STATS                      1
+#endif
+
+#if LWIP_STATS
+
+/**
+ * LWIP_STATS_DISPLAY==1: Compile in the statistics output functions.
+ */
+#if !defined LWIP_STATS_DISPLAY || defined __DOXYGEN__
+#define LWIP_STATS_DISPLAY              0
+#endif
+
+/**
+ * LINK_STATS==1: Enable link stats.
+ */
+#if !defined LINK_STATS || defined __DOXYGEN__
+#define LINK_STATS                      1
+#endif
+
+/**
+ * ETHARP_STATS==1: Enable etharp stats.
+ */
+#if !defined ETHARP_STATS || defined __DOXYGEN__
+#define ETHARP_STATS                    (LWIP_ARP)
+#endif
+
+/**
+ * IP_STATS==1: Enable IP stats.
+ */
+#if !defined IP_STATS || defined __DOXYGEN__
+#define IP_STATS                        1
+#endif
+
+/**
+ * IPFRAG_STATS==1: Enable IP fragmentation stats. Default is
+ * on if using either frag or reass.
+ */
+#if !defined IPFRAG_STATS || defined __DOXYGEN__
+#define IPFRAG_STATS                    (IP_REASSEMBLY || IP_FRAG)
+#endif
+
+/**
+ * ICMP_STATS==1: Enable ICMP stats.
+ */
+#if !defined ICMP_STATS || defined __DOXYGEN__
+#define ICMP_STATS                      1
+#endif
+
+/**
+ * IGMP_STATS==1: Enable IGMP stats.
+ */
+#if !defined IGMP_STATS || defined __DOXYGEN__
+#define IGMP_STATS                      (LWIP_IGMP)
+#endif
+
+/**
+ * UDP_STATS==1: Enable UDP stats. Default is on if
+ * UDP enabled, otherwise off.
+ */
+#if !defined UDP_STATS || defined __DOXYGEN__
+#define UDP_STATS                       (LWIP_UDP)
+#endif
+
+/**
+ * TCP_STATS==1: Enable TCP stats. Default is on if TCP
+ * enabled, otherwise off.
+ */
+#if !defined TCP_STATS || defined __DOXYGEN__
+#define TCP_STATS                       (LWIP_TCP)
+#endif
+
+/**
+ * MEM_STATS==1: Enable mem.c stats.
+ */
+#if !defined MEM_STATS || defined __DOXYGEN__
+#define MEM_STATS                       ((MEM_LIBC_MALLOC == 0) && (MEM_USE_POOLS == 0))
+#endif
+
+/**
+ * MEMP_STATS==1: Enable memp.c pool stats.
+ */
+#if !defined MEMP_STATS || defined __DOXYGEN__
+#define MEMP_STATS                      (MEMP_MEM_MALLOC == 0)
+#endif
+
+/**
+ * SYS_STATS==1: Enable system stats (sem and mbox counts, etc).
+ */
+#if !defined SYS_STATS || defined __DOXYGEN__
+#define SYS_STATS                       (NO_SYS == 0)
+#endif
+
+/**
+ * IP6_STATS==1: Enable IPv6 stats.
+ */
+#if !defined IP6_STATS || defined __DOXYGEN__
+#define IP6_STATS                       (LWIP_IPV6)
+#endif
+
+/**
+ * ICMP6_STATS==1: Enable ICMP for IPv6 stats.
+ */
+#if !defined ICMP6_STATS || defined __DOXYGEN__
+#define ICMP6_STATS                     (LWIP_IPV6 && LWIP_ICMP6)
+#endif
+
+/**
+ * IP6_FRAG_STATS==1: Enable IPv6 fragmentation stats.
+ */
+#if !defined IP6_FRAG_STATS || defined __DOXYGEN__
+#define IP6_FRAG_STATS                  (LWIP_IPV6 && (LWIP_IPV6_FRAG || LWIP_IPV6_REASS))
+#endif
+
+/**
+ * MLD6_STATS==1: Enable MLD for IPv6 stats.
+ */
+#if !defined MLD6_STATS || defined __DOXYGEN__
+#define MLD6_STATS                      (LWIP_IPV6 && LWIP_IPV6_MLD)
+#endif
+
+/**
+ * ND6_STATS==1: Enable Neighbor discovery for IPv6 stats.
+ */
+#if !defined ND6_STATS || defined __DOXYGEN__
+#define ND6_STATS                       (LWIP_IPV6)
+#endif
+
+/**
+ * MIB2_STATS==1: Stats for SNMP MIB2.
+ */
+#if !defined MIB2_STATS || defined __DOXYGEN__
+#define MIB2_STATS                      0
+#endif
+
+#else
+
+#define LINK_STATS                      0
+#define ETHARP_STATS                    0
+#define IP_STATS                        0
+#define IPFRAG_STATS                    0
+#define ICMP_STATS                      0
+#define IGMP_STATS                      0
+#define UDP_STATS                       0
+#define TCP_STATS                       0
+#define MEM_STATS                       0
+#define MEMP_STATS                      0
+#define SYS_STATS                       0
+#define LWIP_STATS_DISPLAY              0
+#define IP6_STATS                       0
+#define ICMP6_STATS                     0
+#define IP6_FRAG_STATS                  0
+#define MLD6_STATS                      0
+#define ND6_STATS                       0
+#define MIB2_STATS                      0
+
+#endif /* LWIP_STATS */
+/**
+ * @}
+ */
+
+/*
+   --------------------------------------
+   ---------- Checksum options ----------
+   --------------------------------------
+*/
+/**
+ * @defgroup lwip_opts_checksum Checksum
+ * @ingroup lwip_opts_infrastructure
+ * @{
+ */
+/**
+ * LWIP_CHECKSUM_CTRL_PER_NETIF==1: Checksum generation/check can be enabled/disabled
+ * per netif.
+ * ATTENTION: if enabled, the CHECKSUM_GEN_* and CHECKSUM_CHECK_* defines must be enabled!
+ */
+#if !defined LWIP_CHECKSUM_CTRL_PER_NETIF || defined __DOXYGEN__
+#define LWIP_CHECKSUM_CTRL_PER_NETIF    0
+#endif
+
+/**
+ * CHECKSUM_GEN_IP==1: Generate checksums in software for outgoing IP packets.
+ */
+#if !defined CHECKSUM_GEN_IP || defined __DOXYGEN__
+#define CHECKSUM_GEN_IP                 1
+#endif
+
+/**
+ * CHECKSUM_GEN_UDP==1: Generate checksums in software for outgoing UDP packets.
+ */
+#if !defined CHECKSUM_GEN_UDP || defined __DOXYGEN__
+#define CHECKSUM_GEN_UDP                1
+#endif
+
+/**
+ * CHECKSUM_GEN_TCP==1: Generate checksums in software for outgoing TCP packets.
+ */
+#if !defined CHECKSUM_GEN_TCP || defined __DOXYGEN__
+#define CHECKSUM_GEN_TCP                1
+#endif
+
+/**
+ * CHECKSUM_GEN_ICMP==1: Generate checksums in software for outgoing ICMP packets.
+ */
+#if !defined CHECKSUM_GEN_ICMP || defined __DOXYGEN__
+#define CHECKSUM_GEN_ICMP               1
+#endif
+
+/**
+ * CHECKSUM_GEN_ICMP6==1: Generate checksums in software for outgoing ICMP6 packets.
+ */
+#if !defined CHECKSUM_GEN_ICMP6 || defined __DOXYGEN__
+#define CHECKSUM_GEN_ICMP6              1
+#endif
+
+/**
+ * CHECKSUM_CHECK_IP==1: Check checksums in software for incoming IP packets.
+ */
+#if !defined CHECKSUM_CHECK_IP || defined __DOXYGEN__
+#define CHECKSUM_CHECK_IP               1
+#endif
+
+/**
+ * CHECKSUM_CHECK_UDP==1: Check checksums in software for incoming UDP packets.
+ */
+#if !defined CHECKSUM_CHECK_UDP || defined __DOXYGEN__
+#define CHECKSUM_CHECK_UDP              1
+#endif
+
+/**
+ * CHECKSUM_CHECK_TCP==1: Check checksums in software for incoming TCP packets.
+ */
+#if !defined CHECKSUM_CHECK_TCP || defined __DOXYGEN__
+#define CHECKSUM_CHECK_TCP              1
+#endif
+
+/**
+ * CHECKSUM_CHECK_ICMP==1: Check checksums in software for incoming ICMP packets.
+ */
+#if !defined CHECKSUM_CHECK_ICMP || defined __DOXYGEN__
+#define CHECKSUM_CHECK_ICMP             1
+#endif
+
+/**
+ * CHECKSUM_CHECK_ICMP6==1: Check checksums in software for incoming ICMPv6 packets
+ */
+#if !defined CHECKSUM_CHECK_ICMP6 || defined __DOXYGEN__
+#define CHECKSUM_CHECK_ICMP6            1
+#endif
+
+/**
+ * LWIP_CHECKSUM_ON_COPY==1: Calculate checksum when copying data from
+ * application buffers to pbufs.
+ */
+#if !defined LWIP_CHECKSUM_ON_COPY || defined __DOXYGEN__
+#define LWIP_CHECKSUM_ON_COPY           0
+#endif
+/**
+ * @}
+ */
+
+/*
+   ---------------------------------------
+   ---------- IPv6 options ---------------
+   ---------------------------------------
+*/
+/**
+ * @defgroup lwip_opts_ipv6 IPv6
+ * @ingroup lwip_opts
+ * @{
+ */
+/**
+ * LWIP_IPV6==1: Enable IPv6
+ */
+#if !defined LWIP_IPV6 || defined __DOXYGEN__
+#define LWIP_IPV6                       0
+#endif
+
+/**
+ * IPV6_REASS_MAXAGE: Maximum time (in multiples of IP6_REASS_TMR_INTERVAL - so seconds, normally)
+ * a fragmented IP packet waits for all fragments to arrive. If not all fragments arrived
+ * in this time, the whole packet is discarded.
+ */
+#if !defined IPV6_REASS_MAXAGE || defined __DOXYGEN__
+#define IPV6_REASS_MAXAGE               60
+#endif
+
+/**
+ * LWIP_IPV6_SCOPES==1: Enable support for IPv6 address scopes, ensuring that
+ * e.g. link-local addresses are really treated as link-local. Disable this
+ * setting only for single-interface configurations.
+ * All addresses that have a scope according to the default policy (link-local
+ * unicast addresses, interface-local and link-local multicast addresses) should
+ * now have a zone set on them before being passed to the core API, although
+ * lwIP will currently attempt to select a zone on the caller's behalf when 
+ * necessary. Applications that directly assign IPv6 addresses to interfaces
+ * (which is NOT recommended) must now ensure that link-local addresses carry
+ * the netif's zone. See the new ip6_zone.h header file for more information and
+ * relevant macros. For now it is still possible to turn off scopes support
+ * through the new LWIP_IPV6_SCOPES option. When upgrading an implementation that
+ * uses the core API directly, it is highly recommended to enable
+ * LWIP_IPV6_SCOPES_DEBUG at least for a while, to ensure e.g. proper address
+ * initialization.
+ */
+#if !defined LWIP_IPV6_SCOPES || defined __DOXYGEN__
+#define LWIP_IPV6_SCOPES                (LWIP_IPV6 && !LWIP_SINGLE_NETIF)
+#endif
+
+/**
+ * LWIP_IPV6_SCOPES_DEBUG==1: Perform run-time checks to verify that addresses
+ * are properly zoned (see ip6_zone.h on what that means) where it matters.
+ * Enabling this setting is highly recommended when upgrading from an existing
+ * installation that is not yet scope-aware; otherwise it may be too expensive.
+ */
+#if !defined LWIP_IPV6_SCOPES_DEBUG || defined __DOXYGEN__
+#define LWIP_IPV6_SCOPES_DEBUG          0
+#endif
+
+/**
+ * LWIP_IPV6_NUM_ADDRESSES: Number of IPv6 addresses per netif.
+ */
+#if !defined LWIP_IPV6_NUM_ADDRESSES || defined __DOXYGEN__
+#define LWIP_IPV6_NUM_ADDRESSES         3
+#endif
+
+/**
+ * LWIP_IPV6_FORWARD==1: Forward IPv6 packets across netifs
+ */
+#if !defined LWIP_IPV6_FORWARD || defined __DOXYGEN__
+#define LWIP_IPV6_FORWARD               0
+#endif
+
+/**
+ * LWIP_IPV6_FRAG==1: Fragment outgoing IPv6 packets that are too big.
+ */
+#if !defined LWIP_IPV6_FRAG || defined __DOXYGEN__
+#define LWIP_IPV6_FRAG                  1
+#endif
+
+/**
+ * LWIP_IPV6_REASS==1: reassemble incoming IPv6 packets that fragmented
+ */
+#if !defined LWIP_IPV6_REASS || defined __DOXYGEN__
+#define LWIP_IPV6_REASS                 LWIP_IPV6
+#endif
+
+/**
+ * LWIP_IPV6_SEND_ROUTER_SOLICIT==1: Send router solicitation messages during
+ * network startup.
+ */
+#if !defined LWIP_IPV6_SEND_ROUTER_SOLICIT || defined __DOXYGEN__
+#define LWIP_IPV6_SEND_ROUTER_SOLICIT   1
+#endif
+
+/**
+ * LWIP_IPV6_AUTOCONFIG==1: Enable stateless address autoconfiguration as per RFC 4862.
+ */
+#if !defined LWIP_IPV6_AUTOCONFIG || defined __DOXYGEN__
+#define LWIP_IPV6_AUTOCONFIG            LWIP_IPV6
+#endif
+
+/**
+ * LWIP_IPV6_ADDRESS_LIFETIMES==1: Keep valid and preferred lifetimes for each
+ * IPv6 address. Required for LWIP_IPV6_AUTOCONFIG. May still be enabled
+ * otherwise, in which case the application may assign address lifetimes with
+ * the appropriate macros. Addresses with no lifetime are assumed to be static.
+ * If this option is disabled, all addresses are assumed to be static.
+ */
+#if !defined LWIP_IPV6_ADDRESS_LIFETIMES || defined __DOXYGEN__
+#define LWIP_IPV6_ADDRESS_LIFETIMES     LWIP_IPV6_AUTOCONFIG
+#endif
+
+/**
+ * LWIP_IPV6_DUP_DETECT_ATTEMPTS=[0..7]: Number of duplicate address detection attempts.
+ */
+#if !defined LWIP_IPV6_DUP_DETECT_ATTEMPTS || defined __DOXYGEN__
+#define LWIP_IPV6_DUP_DETECT_ATTEMPTS   1
+#endif
+/**
+ * @}
+ */
+
+/**
+ * @defgroup lwip_opts_icmp6 ICMP6
+ * @ingroup lwip_opts_ipv6
+ * @{
+ */
+/**
+ * LWIP_ICMP6==1: Enable ICMPv6 (mandatory per RFC)
+ */
+#if !defined LWIP_ICMP6 || defined __DOXYGEN__
+#define LWIP_ICMP6                      LWIP_IPV6
+#endif
+
+/**
+ * LWIP_ICMP6_DATASIZE: bytes from original packet to send back in
+ * ICMPv6 error messages.
+ */
+#if !defined LWIP_ICMP6_DATASIZE || defined __DOXYGEN__
+#define LWIP_ICMP6_DATASIZE             8
+#endif
+
+/**
+ * LWIP_ICMP6_HL: default hop limit for ICMPv6 messages
+ */
+#if !defined LWIP_ICMP6_HL || defined __DOXYGEN__
+#define LWIP_ICMP6_HL                   255
+#endif
+/**
+ * @}
+ */
+
+/**
+ * @defgroup lwip_opts_mld6 Multicast listener discovery
+ * @ingroup lwip_opts_ipv6
+ * @{
+ */
+/**
+ * LWIP_IPV6_MLD==1: Enable multicast listener discovery protocol.
+ * If LWIP_IPV6 is enabled but this setting is disabled, the MAC layer must
+ * indiscriminately pass all inbound IPv6 multicast traffic to lwIP.
+ */
+#if !defined LWIP_IPV6_MLD || defined __DOXYGEN__
+#define LWIP_IPV6_MLD                   LWIP_IPV6
+#endif
+
+/**
+ * MEMP_NUM_MLD6_GROUP: Max number of IPv6 multicast groups that can be joined.
+ * There must be enough groups so that each netif can join the solicited-node
+ * multicast group for each of its local addresses, plus one for MDNS if
+ * applicable, plus any number of groups to be joined on UDP sockets.
+ */
+#if !defined MEMP_NUM_MLD6_GROUP || defined __DOXYGEN__
+#define MEMP_NUM_MLD6_GROUP             4
+#endif
+/**
+ * @}
+ */
+
+/**
+ * @defgroup lwip_opts_nd6 Neighbor discovery
+ * @ingroup lwip_opts_ipv6
+ * @{
+ */
+/**
+ * LWIP_ND6_QUEUEING==1: queue outgoing IPv6 packets while MAC address
+ * is being resolved.
+ */
+#if !defined LWIP_ND6_QUEUEING || defined __DOXYGEN__
+#define LWIP_ND6_QUEUEING               LWIP_IPV6
+#endif
+
+/**
+ * MEMP_NUM_ND6_QUEUE: Max number of IPv6 packets to queue during MAC resolution.
+ */
+#if !defined MEMP_NUM_ND6_QUEUE || defined __DOXYGEN__
+#define MEMP_NUM_ND6_QUEUE              20
+#endif
+
+/**
+ * LWIP_ND6_NUM_NEIGHBORS: Number of entries in IPv6 neighbor cache
+ */
+#if !defined LWIP_ND6_NUM_NEIGHBORS || defined __DOXYGEN__
+#define LWIP_ND6_NUM_NEIGHBORS          10
+#endif
+
+/**
+ * LWIP_ND6_NUM_DESTINATIONS: number of entries in IPv6 destination cache
+ */
+#if !defined LWIP_ND6_NUM_DESTINATIONS || defined __DOXYGEN__
+#define LWIP_ND6_NUM_DESTINATIONS       10
+#endif
+
+/**
+ * LWIP_ND6_NUM_PREFIXES: number of entries in IPv6 on-link prefixes cache
+ */
+#if !defined LWIP_ND6_NUM_PREFIXES || defined __DOXYGEN__
+#define LWIP_ND6_NUM_PREFIXES           5
+#endif
+
+/**
+ * LWIP_ND6_NUM_ROUTERS: number of entries in IPv6 default router cache
+ */
+#if !defined LWIP_ND6_NUM_ROUTERS || defined __DOXYGEN__
+#define LWIP_ND6_NUM_ROUTERS            3
+#endif
+
+/**
+ * LWIP_ND6_MAX_MULTICAST_SOLICIT: max number of multicast solicit messages to send
+ * (neighbor solicit and router solicit)
+ */
+#if !defined LWIP_ND6_MAX_MULTICAST_SOLICIT || defined __DOXYGEN__
+#define LWIP_ND6_MAX_MULTICAST_SOLICIT  3
+#endif
+
+/**
+ * LWIP_ND6_MAX_UNICAST_SOLICIT: max number of unicast neighbor solicitation messages
+ * to send during neighbor reachability detection.
+ */
+#if !defined LWIP_ND6_MAX_UNICAST_SOLICIT || defined __DOXYGEN__
+#define LWIP_ND6_MAX_UNICAST_SOLICIT    3
+#endif
+
+/**
+ * Unused: See ND RFC (time in milliseconds).
+ */
+#if !defined LWIP_ND6_MAX_ANYCAST_DELAY_TIME || defined __DOXYGEN__
+#define LWIP_ND6_MAX_ANYCAST_DELAY_TIME 1000
+#endif
+
+/**
+ * Unused: See ND RFC
+ */
+#if !defined LWIP_ND6_MAX_NEIGHBOR_ADVERTISEMENT || defined __DOXYGEN__
+#define LWIP_ND6_MAX_NEIGHBOR_ADVERTISEMENT  3
+#endif
+
+/**
+ * LWIP_ND6_REACHABLE_TIME: default neighbor reachable time (in milliseconds).
+ * May be updated by router advertisement messages.
+ */
+#if !defined LWIP_ND6_REACHABLE_TIME || defined __DOXYGEN__
+#define LWIP_ND6_REACHABLE_TIME         30000
+#endif
+
+/**
+ * LWIP_ND6_RETRANS_TIMER: default retransmission timer for solicitation messages
+ */
+#if !defined LWIP_ND6_RETRANS_TIMER || defined __DOXYGEN__
+#define LWIP_ND6_RETRANS_TIMER          1000
+#endif
+
+/**
+ * LWIP_ND6_DELAY_FIRST_PROBE_TIME: Delay before first unicast neighbor solicitation
+ * message is sent, during neighbor reachability detection.
+ */
+#if !defined LWIP_ND6_DELAY_FIRST_PROBE_TIME || defined __DOXYGEN__
+#define LWIP_ND6_DELAY_FIRST_PROBE_TIME 5000
+#endif
+
+/**
+ * LWIP_ND6_ALLOW_RA_UPDATES==1: Allow Router Advertisement messages to update
+ * Reachable time and retransmission timers, and netif MTU.
+ */
+#if !defined LWIP_ND6_ALLOW_RA_UPDATES || defined __DOXYGEN__
+#define LWIP_ND6_ALLOW_RA_UPDATES       1
+#endif
+
+/**
+ * LWIP_ND6_TCP_REACHABILITY_HINTS==1: Allow TCP to provide Neighbor Discovery
+ * with reachability hints for connected destinations. This helps avoid sending
+ * unicast neighbor solicitation messages.
+ */
+#if !defined LWIP_ND6_TCP_REACHABILITY_HINTS || defined __DOXYGEN__
+#define LWIP_ND6_TCP_REACHABILITY_HINTS 1
+#endif
+
+/**
+ * LWIP_ND6_RDNSS_MAX_DNS_SERVERS > 0: Use IPv6 Router Advertisement Recursive
+ * DNS Server Option (as per RFC 6106) to copy a defined maximum number of DNS
+ * servers to the DNS module.
+ */
+#if !defined LWIP_ND6_RDNSS_MAX_DNS_SERVERS || defined __DOXYGEN__
+#define LWIP_ND6_RDNSS_MAX_DNS_SERVERS  0
+#endif
+/**
+ * @}
+ */
+
+/**
+ * @defgroup lwip_opts_dhcpv6 DHCPv6
+ * @ingroup lwip_opts_ipv6
+ * @{
+ */
+/**
+ * LWIP_IPV6_DHCP6==1: enable DHCPv6 stateful/stateless address autoconfiguration.
+ */
+#if !defined LWIP_IPV6_DHCP6 || defined __DOXYGEN__
+#define LWIP_IPV6_DHCP6                 0
+#endif
+
+/**
+ * LWIP_IPV6_DHCP6_STATEFUL==1: enable DHCPv6 stateful address autoconfiguration.
+ * (not supported, yet!)
+ */
+#if !defined LWIP_IPV6_DHCP6_STATEFUL || defined __DOXYGEN__
+#define LWIP_IPV6_DHCP6_STATEFUL        0
+#endif
+
+/**
+ * LWIP_IPV6_DHCP6_STATELESS==1: enable DHCPv6 stateless address autoconfiguration.
+ */
+#if !defined LWIP_IPV6_DHCP6_STATELESS || defined __DOXYGEN__
+#define LWIP_IPV6_DHCP6_STATELESS       LWIP_IPV6_DHCP6
+#endif
+
+/**
+ * LWIP_DHCP6_GETS_NTP==1: Request NTP servers via DHCPv6. For each
+ * response packet, a callback is called, which has to be provided by the port:
+ * void dhcp6_set_ntp_servers(u8_t num_ntp_servers, ip_addr_t* ntp_server_addrs);
+*/
+#if !defined LWIP_DHCP6_GET_NTP_SRV || defined __DOXYGEN__
+#define LWIP_DHCP6_GET_NTP_SRV          0
+#endif
+
+/**
+ * The maximum of NTP servers requested
+ */
+#if !defined LWIP_DHCP6_MAX_NTP_SERVERS || defined __DOXYGEN__
+#define LWIP_DHCP6_MAX_NTP_SERVERS      1
+#endif
+
+/**
+ * LWIP_DHCP6_MAX_DNS_SERVERS > 0: Request DNS servers via DHCPv6.
+ * DNS servers received in the response are passed to DNS via @ref dns_setserver()
+ * (up to the maximum limit defined here).
+ */
+#if !defined LWIP_DHCP6_MAX_DNS_SERVERS || defined __DOXYGEN__
+#define LWIP_DHCP6_MAX_DNS_SERVERS      DNS_MAX_SERVERS
+#endif
+/**
+ * @}
+ */
+
+/*
+   ---------------------------------------
+   ---------- Hook options ---------------
+   ---------------------------------------
+*/
+
+/**
+ * @defgroup lwip_opts_hooks Hooks
+ * @ingroup lwip_opts_infrastructure
+ * Hooks are undefined by default, define them to a function if you need them.
+ * @{
+ */
+
+/**
+ * LWIP_HOOK_FILENAME: Custom filename to \#include in files that provide hooks.
+ * Declare your hook function prototypes in there, you may also \#include all headers
+ * providing data types that are need in this file.
+ */
+#ifdef __DOXYGEN__
+#define LWIP_HOOK_FILENAME "path/to/my/lwip_hooks.h"
+#endif
+
+/**
+ * LWIP_HOOK_TCP_ISN:
+ * Hook for generation of the Initial Sequence Number (ISN) for a new TCP
+ * connection. The default lwIP ISN generation algorithm is very basic and may
+ * allow for TCP spoofing attacks. This hook provides the means to implement
+ * the standardized ISN generation algorithm from RFC 6528 (see contrib/adons/tcp_isn),
+ * or any other desired algorithm as a replacement.
+ * Called from tcp_connect() and tcp_listen_input() when an ISN is needed for
+ * a new TCP connection, if TCP support (@ref LWIP_TCP) is enabled.\n
+ * Signature:\code{.c}
+ * u32_t my_hook_tcp_isn(const ip_addr_t* local_ip, u16_t local_port, const ip_addr_t* remote_ip, u16_t remote_port);
+ * \endcode
+ * - it may be necessary to use "struct ip_addr" (ip4_addr, ip6_addr) instead of "ip_addr_t" in function declarations\n
+ * Arguments:
+ * - local_ip: pointer to the local IP address of the connection
+ * - local_port: local port number of the connection (host-byte order)
+ * - remote_ip: pointer to the remote IP address of the connection
+ * - remote_port: remote port number of the connection (host-byte order)\n
+ * Return value:
+ * - the 32-bit Initial Sequence Number to use for the new TCP connection.
+ */
+#ifdef __DOXYGEN__
+#define LWIP_HOOK_TCP_ISN(local_ip, local_port, remote_ip, remote_port)
+#endif
+
+/**
+ * LWIP_HOOK_TCP_INPACKET_PCB:
+ * Hook for intercepting incoming packets before they are passed to a pcb. This
+ * allows updating some state or even dropping a packet.
+ * Signature:\code{.c}
+ * err_t my_hook_tcp_inpkt(struct tcp_pcb *pcb, struct tcp_hdr *hdr, u16_t optlen, u16_t opt1len, u8_t *opt2, struct pbuf *p);
+ * \endcode
+ * Arguments:
+ * - pcb: tcp_pcb selected for input of this packet (ATTENTION: this may be
+ *        struct tcp_pcb_listen if pcb->state == LISTEN)
+ * - hdr: pointer to tcp header (ATTENTION: tcp options may not be in one piece!)
+ * - optlen: tcp option length
+ * - opt1len: tcp option length 1st part
+ * - opt2: if this is != NULL, tcp options are split among 2 pbufs. In that case,
+ *         options start at right after the tcp header ('(u8_t*)(hdr + 1)') for
+ *         the first 'opt1len' bytes and the rest starts at 'opt2'. opt2len can
+ *         be simply calculated: 'opt2len = optlen - opt1len;'
+ * - p: input packet, p->payload points to application data (that's why tcp hdr
+ *      and options are passed in seperately)
+ * Return value:
+ * - ERR_OK: continue input of this packet as normal
+ * - != ERR_OK: drop this packet for input (don't continue input processing)
+ *
+ * ATTENTION: don't call any tcp api functions that might change tcp state (pcb
+ * state or any pcb lists) from this callback!
+ */
+#ifdef __DOXYGEN__
+#define LWIP_HOOK_TCP_INPACKET_PCB(pcb, hdr, optlen, opt1len, opt2, p)
+#endif
+
+/**
+ * LWIP_HOOK_TCP_OUT_TCPOPT_LENGTH:
+ * Hook for increasing the size of the options allocated with a tcp header.
+ * Together with LWIP_HOOK_TCP_OUT_ADD_TCPOPTS, this can be used to add custom
+ * options to outgoing tcp segments.
+ * Signature:\code{.c}
+ * u8_t my_hook_tcp_out_tcpopt_length(const struct tcp_pcb *pcb, u8_t internal_option_length);
+ * \endcode
+ * Arguments:
+ * - pcb: tcp_pcb that transmits (ATTENTION: this may be NULL or
+ *        struct tcp_pcb_listen if pcb->state == LISTEN)
+ * - internal_option_length: tcp option length used by the stack internally
+ * Return value:
+ * - a number of bytes to allocate for tcp options (internal_option_length <= ret <= 40)
+ *
+ * ATTENTION: don't call any tcp api functions that might change tcp state (pcb
+ * state or any pcb lists) from this callback!
+ */
+#ifdef __DOXYGEN__
+#define LWIP_HOOK_TCP_OUT_TCPOPT_LENGTH(pcb, internal_len)
+#endif
+
+/**
+ * LWIP_HOOK_TCP_OUT_ADD_TCPOPTS:
+ * Hook for adding custom options to outgoing tcp segments.
+ * Space for these custom options has to be reserved via LWIP_HOOK_TCP_OUT_TCPOPT_LENGTH.
+ * Signature:\code{.c}
+ * u32_t *my_hook_tcp_out_add_tcpopts(struct pbuf *p, struct tcp_hdr *hdr, const struct tcp_pcb *pcb, u32_t *opts);
+ * \endcode
+ * Arguments:
+ * - p: output packet, p->payload pointing to tcp header, data follows
+ * - hdr: tcp header
+ * - pcb: tcp_pcb that transmits (ATTENTION: this may be NULL or
+ *        struct tcp_pcb_listen if pcb->state == LISTEN)
+ * - opts: pointer where to add the custom options (there may already be options
+ *         between the header and these)
+ * Return value:
+ * - pointer pointing directly after the inserted options
+ *
+ * ATTENTION: don't call any tcp api functions that might change tcp state (pcb
+ * state or any pcb lists) from this callback!
+ */
+#ifdef __DOXYGEN__
+#define LWIP_HOOK_TCP_OUT_ADD_TCPOPTS(p, hdr, pcb, opts)
+#endif
+
+/**
+ * LWIP_HOOK_IP4_INPUT(pbuf, input_netif):
+ * Called from ip_input() (IPv4)
+ * Signature:\code{.c}
+ *   int my_hook(struct pbuf *pbuf, struct netif *input_netif);
+ * \endcode
+ * Arguments:
+ * - pbuf: received struct pbuf passed to ip_input()
+ * - input_netif: struct netif on which the packet has been received
+ * Return values:
+ * - 0: Hook has not consumed the packet, packet is processed as normal
+ * - != 0: Hook has consumed the packet.
+ * If the hook consumed the packet, 'pbuf' is in the responsibility of the hook
+ * (i.e. free it when done).
+ */
+#ifdef __DOXYGEN__
+#define LWIP_HOOK_IP4_INPUT(pbuf, input_netif)
+#endif
+
+/**
+ * LWIP_HOOK_IP4_ROUTE(dest):
+ * Called from ip_route() (IPv4)
+ * Signature:\code{.c}
+ *   struct netif *my_hook(const ip4_addr_t *dest);
+ * \endcode
+ * Arguments:
+ * - dest: destination IPv4 address
+ * Returns values:
+ * - the destination netif
+ * - NULL if no destination netif is found. In that case, ip_route() continues as normal.
+ */
+#ifdef __DOXYGEN__
+#define LWIP_HOOK_IP4_ROUTE()
+#endif
+
+/**
+ * LWIP_HOOK_IP4_ROUTE_SRC(src, dest):
+ * Source-based routing for IPv4 - called from ip_route() (IPv4)
+ * Signature:\code{.c}
+ *   struct netif *my_hook(const ip4_addr_t *src, const ip4_addr_t *dest);
+ * \endcode
+ * Arguments:
+ * - src: local/source IPv4 address
+ * - dest: destination IPv4 address
+ * Returns values:
+ * - the destination netif
+ * - NULL if no destination netif is found. In that case, ip_route() continues as normal.
+ */
+#ifdef __DOXYGEN__
+#define LWIP_HOOK_IP4_ROUTE_SRC(src, dest)
+#endif
+
+/**
+ * LWIP_HOOK_IP4_CANFORWARD(src, dest):
+ * Check if an IPv4 can be forwarded - called from:
+ * ip4_input() -> ip4_forward() -> ip4_canforward() (IPv4)
+ * - source address is available via ip4_current_src_addr()
+ * - calling an output function in this context (e.g. multicast router) is allowed
+ * Signature:\code{.c}
+ *   int my_hook(struct pbuf *p, u32_t dest_addr_hostorder);
+ * \endcode
+ * Arguments:
+ * - p: packet to forward
+ * - dest: destination IPv4 address
+ * Returns values:
+ * - 1: forward
+ * - 0: don't forward
+ * - -1: no decision. In that case, ip4_canforward() continues as normal.
+ */
+#ifdef __DOXYGEN__
+#define LWIP_HOOK_IP4_CANFORWARD(src, dest)
+#endif
+
+/**
+ * LWIP_HOOK_ETHARP_GET_GW(netif, dest):
+ * Called from etharp_output() (IPv4)
+ * Signature:\code{.c}
+ *   const ip4_addr_t *my_hook(struct netif *netif, const ip4_addr_t *dest);
+ * \endcode
+ * Arguments:
+ * - netif: the netif used for sending
+ * - dest: the destination IPv4 address
+ * Return values:
+ * - the IPv4 address of the gateway to handle the specified destination IPv4 address
+ * - NULL, in which case the netif's default gateway is used
+ *
+ * The returned address MUST be directly reachable on the specified netif!
+ * This function is meant to implement advanced IPv4 routing together with
+ * LWIP_HOOK_IP4_ROUTE(). The actual routing/gateway table implementation is
+ * not part of lwIP but can e.g. be hidden in the netif's state argument.
+*/
+#ifdef __DOXYGEN__
+#define LWIP_HOOK_ETHARP_GET_GW(netif, dest)
+#endif
+
+/**
+ * LWIP_HOOK_IP6_INPUT(pbuf, input_netif):
+ * Called from ip6_input() (IPv6)
+ * Signature:\code{.c}
+ *   int my_hook(struct pbuf *pbuf, struct netif *input_netif);
+ * \endcode
+ * Arguments:
+ * - pbuf: received struct pbuf passed to ip6_input()
+ * - input_netif: struct netif on which the packet has been received
+ * Return values:
+ * - 0: Hook has not consumed the packet, packet is processed as normal
+ * - != 0: Hook has consumed the packet.
+ * If the hook consumed the packet, 'pbuf' is in the responsibility of the hook
+ * (i.e. free it when done).
+ */
+#ifdef __DOXYGEN__
+#define LWIP_HOOK_IP6_INPUT(pbuf, input_netif)
+#endif
+
+/**
+ * LWIP_HOOK_IP6_ROUTE(src, dest):
+ * Called from ip_route() (IPv6)
+ * Signature:\code{.c}
+ *   struct netif *my_hook(const ip6_addr_t *dest, const ip6_addr_t *src);
+ * \endcode
+ * Arguments:
+ * - src: source IPv6 address
+ * - dest: destination IPv6 address
+ * Return values:
+ * - the destination netif
+ * - NULL if no destination netif is found. In that case, ip6_route() continues as normal.
+ */
+#ifdef __DOXYGEN__
+#define LWIP_HOOK_IP6_ROUTE(src, dest)
+#endif
+
+/**
+ * LWIP_HOOK_ND6_GET_GW(netif, dest):
+ * Called from nd6_get_next_hop_entry() (IPv6)
+ * Signature:\code{.c}
+ *   const ip6_addr_t *my_hook(struct netif *netif, const ip6_addr_t *dest);
+ * \endcode
+ * Arguments:
+ * - netif: the netif used for sending
+ * - dest: the destination IPv6 address
+ * Return values:
+ * - the IPv6 address of the next hop to handle the specified destination IPv6 address
+ * - NULL, in which case a NDP-discovered router is used instead
+ *
+ * The returned address MUST be directly reachable on the specified netif!
+ * This function is meant to implement advanced IPv6 routing together with
+ * LWIP_HOOK_IP6_ROUTE(). The actual routing/gateway table implementation is
+ * not part of lwIP but can e.g. be hidden in the netif's state argument.
+*/
+#ifdef __DOXYGEN__
+#define LWIP_HOOK_ND6_GET_GW(netif, dest)
+#endif
+
+/**
+ * LWIP_HOOK_VLAN_CHECK(netif, eth_hdr, vlan_hdr):
+ * Called from ethernet_input() if VLAN support is enabled
+ * Signature:\code{.c}
+ *   int my_hook(struct netif *netif, struct eth_hdr *eth_hdr, struct eth_vlan_hdr *vlan_hdr);
+ * \endcode
+ * Arguments:
+ * - netif: struct netif on which the packet has been received
+ * - eth_hdr: struct eth_hdr of the packet
+ * - vlan_hdr: struct eth_vlan_hdr of the packet
+ * Return values:
+ * - 0: Packet must be dropped.
+ * - != 0: Packet must be accepted.
+ */
+#ifdef __DOXYGEN__
+#define LWIP_HOOK_VLAN_CHECK(netif, eth_hdr, vlan_hdr)
+#endif
+
+/**
+ * LWIP_HOOK_VLAN_SET:
+ * Hook can be used to set prio_vid field of vlan_hdr. If you need to store data
+ * on per-netif basis to implement this callback, see @ref netif_cd.
+ * Called from ethernet_output() if VLAN support (@ref ETHARP_SUPPORT_VLAN) is enabled.\n
+ * Signature:\code{.c}
+ *   s32_t my_hook_vlan_set(struct netif* netif, struct pbuf* pbuf, const struct eth_addr* src, const struct eth_addr* dst, u16_t eth_type);\n
+ * \endcode
+ * Arguments:
+ * - netif: struct netif that the packet will be sent through
+ * - p: struct pbuf packet to be sent
+ * - src: source eth address
+ * - dst: destination eth address
+ * - eth_type: ethernet type to packet to be sent\n
+ * 
+ * 
+ * Return values:
+ * - &lt;0: Packet shall not contain VLAN header.
+ * - 0 &lt;= return value &lt;= 0xFFFF: Packet shall contain VLAN header. Return value is prio_vid in host byte order.
+ */
+#ifdef __DOXYGEN__
+#define LWIP_HOOK_VLAN_SET(netif, p, src, dst, eth_type)
+#endif
+
+/**
+ * LWIP_HOOK_MEMP_AVAILABLE(memp_t_type):
+ * Called from memp_free() when a memp pool was empty and an item is now available
+ * Signature:\code{.c}
+ *   void my_hook(memp_t type);
+ * \endcode
+ */
+#ifdef __DOXYGEN__
+#define LWIP_HOOK_MEMP_AVAILABLE(memp_t_type)
+#endif
+
+/**
+ * LWIP_HOOK_UNKNOWN_ETH_PROTOCOL(pbuf, netif):
+ * Called from ethernet_input() when an unknown eth type is encountered.
+ * Signature:\code{.c}
+ *   err_t my_hook(struct pbuf* pbuf, struct netif* netif);
+ * \endcode
+ * Arguments:
+ * - p: rx packet with unknown eth type
+ * - netif: netif on which the packet has been received
+ * Return values:
+ * - ERR_OK if packet is accepted (hook function now owns the pbuf)
+ * - any error code otherwise (pbuf is freed)
+ *
+ * Payload points to ethernet header!
+ */
+#ifdef __DOXYGEN__
+#define LWIP_HOOK_UNKNOWN_ETH_PROTOCOL(pbuf, netif)
+#endif
+
+/**
+ * LWIP_HOOK_DHCP_APPEND_OPTIONS(netif, dhcp, state, msg, msg_type, options_len_ptr):
+ * Called from various dhcp functions when sending a DHCP message.
+ * This hook is called just before the DHCP message trailer is added, so the
+ * options are at the end of a DHCP message.
+ * Signature:\code{.c}
+ *   void my_hook(struct netif *netif, struct dhcp *dhcp, u8_t state, struct dhcp_msg *msg,
+ *                u8_t msg_type, u16_t *options_len_ptr);
+ * \endcode
+ * Arguments:
+ * - netif: struct netif that the packet will be sent through
+ * - dhcp: struct dhcp on that netif
+ * - state: current dhcp state (dhcp_state_enum_t as an u8_t)
+ * - msg: struct dhcp_msg that will be sent
+ * - msg_type: dhcp message type to be sent (u8_t)
+ * - options_len_ptr: pointer to the current length of options in the dhcp_msg "msg"
+ *                    (must be increased when options are added!)
+ *
+ * Options need to appended like this:
+ *   LWIP_ASSERT("dhcp option overflow", *options_len_ptr + option_len + 2 <= DHCP_OPTIONS_LEN);
+ *   msg->options[(*options_len_ptr)++] = &lt;option_number&gt;;
+ *   msg->options[(*options_len_ptr)++] = &lt;option_len&gt;;
+ *   msg->options[(*options_len_ptr)++] = &lt;option_bytes&gt;;
+ *   [...]
+ */
+#ifdef __DOXYGEN__
+#define LWIP_HOOK_DHCP_APPEND_OPTIONS(netif, dhcp, state, msg, msg_type, options_len_ptr)
+#endif
+
+/**
+ * LWIP_HOOK_DHCP_PARSE_OPTION(netif, dhcp, state, msg, msg_type, option, len, pbuf, option_value_offset):
+ * Called from dhcp_parse_reply when receiving a DHCP message.
+ * This hook is called for every option in the received message that is not handled internally.
+ * Signature:\code{.c}
+ *   void my_hook(struct netif *netif, struct dhcp *dhcp, u8_t state, struct dhcp_msg *msg,
+ *                u8_t msg_type, u8_t option, u8_t option_len, struct pbuf *pbuf, u16_t option_value_offset);
+ * \endcode
+ * Arguments:
+ * - netif: struct netif that the packet will be sent through
+ * - dhcp: struct dhcp on that netif
+ * - state: current dhcp state (dhcp_state_enum_t as an u8_t)
+ * - msg: struct dhcp_msg that was received
+ * - msg_type: dhcp message type received (u8_t, ATTENTION: only valid after
+ *             the message type option has been parsed!)
+ * - option: option value (u8_t)
+ * - len: option data length (u8_t)
+ * - pbuf: pbuf where option data is contained
+ * - option_value_offset: offset in pbuf where option data begins
+ *
+ * A nice way to get the option contents is pbuf_get_contiguous():
+ *  u8_t buf[32];
+ *  u8_t *ptr = (u8_t*)pbuf_get_contiguous(p, buf, sizeof(buf), LWIP_MIN(option_len, sizeof(buf)), offset);
+ */
+#ifdef __DOXYGEN__
+#define LWIP_HOOK_DHCP_PARSE_OPTION(netif, dhcp, state, msg, msg_type, option, len, pbuf, offset)
+#endif
+
+/**
+ * LWIP_HOOK_DHCP6_APPEND_OPTIONS(netif, dhcp6, state, msg, msg_type, options_len_ptr, max_len):
+ * Called from various dhcp6 functions when sending a DHCP6 message.
+ * This hook is called just before the DHCP6 message is sent, so the
+ * options are at the end of a DHCP6 message.
+ * Signature:\code{.c}
+ *   void my_hook(struct netif *netif, struct dhcp6 *dhcp, u8_t state, struct dhcp6_msg *msg,
+ *                u8_t msg_type, u16_t *options_len_ptr);
+ * \endcode
+ * Arguments:
+ * - netif: struct netif that the packet will be sent through
+ * - dhcp6: struct dhcp6 on that netif
+ * - state: current dhcp6 state (dhcp6_state_enum_t as an u8_t)
+ * - msg: struct dhcp6_msg that will be sent
+ * - msg_type: dhcp6 message type to be sent (u8_t)
+ * - options_len_ptr: pointer to the current length of options in the dhcp6_msg "msg"
+ *                    (must be increased when options are added!)
+ *
+ * Options need to appended like this:
+ *   u8_t *options = (u8_t *)(msg + 1);
+ *   LWIP_ASSERT("dhcp option overflow", sizeof(struct dhcp6_msg) + *options_len_ptr + newoptlen <= max_len);
+ *   options[(*options_len_ptr)++] = &lt;option_data&gt;;
+ *   [...]
+ */
+#ifdef __DOXYGEN__
+#define LWIP_HOOK_DHCP6_APPEND_OPTIONS(netif, dhcp6, state, msg, msg_type, options_len_ptr, max_len)
+#endif
+
+/**
+ * LWIP_HOOK_SOCKETS_SETSOCKOPT(s, sock, level, optname, optval, optlen, err)
+ * Called from socket API to implement setsockopt() for options not provided by lwIP.
+ * Core lock is held when this hook is called.
+ * Signature:\code{.c}
+ *   int my_hook(int s, struct lwip_sock *sock, int level, int optname, const void *optval, socklen_t optlen, int *err)
+ * \endcode
+ * Arguments:
+ * - s: socket file descriptor
+ * - sock: internal socket descriptor (see lwip/priv/sockets_priv.h)
+ * - level: protocol level at which the option resides
+ * - optname: option to set
+ * - optval: value to set
+ * - optlen: size of optval
+ * - err: output error
+ * Return values:
+ * - 0: Hook has not consumed the option, code continues as normal (to internal options)
+ * - != 0: Hook has consumed the option, 'err' is returned
+ */
+#ifdef __DOXYGEN__
+#define LWIP_HOOK_SOCKETS_SETSOCKOPT(s, sock, level, optname, optval, optlen, err)
+#endif
+
+/**
+ * LWIP_HOOK_SOCKETS_GETSOCKOPT(s, sock, level, optname, optval, optlen, err)
+ * Called from socket API to implement getsockopt() for options not provided by lwIP.
+ * Core lock is held when this hook is called.
+ * Signature:\code{.c}
+ *   int my_hook(int s, struct lwip_sock *sock, int level, int optname, void *optval, socklen_t *optlen, int *err)
+ * \endcode
+ * Arguments:
+ * - s: socket file descriptor
+ * - sock: internal socket descriptor (see lwip/priv/sockets_priv.h)
+ * - level: protocol level at which the option resides
+ * - optname: option to get
+ * - optval: value to get
+ * - optlen: size of optval
+ * - err: output error
+ * Return values:
+ * - 0: Hook has not consumed the option, code continues as normal (to internal options)
+ * - != 0: Hook has consumed the option, 'err' is returned
+ */
+#ifdef __DOXYGEN__
+#define LWIP_HOOK_SOCKETS_GETSOCKOPT(s, sock, level, optname, optval, optlen, err)
+#endif
+
+/**
+ * LWIP_HOOK_NETCONN_EXTERNAL_RESOLVE(name, addr, addrtype, err)
+ * Called from netconn APIs (not usable with callback apps) allowing an
+ * external DNS resolver (which uses sequential API) to handle the query.
+ * Signature:\code{.c}
+ *   int my_hook(const char *name, ip_addr_t *addr, u8_t addrtype, err_t *err)
+ * \endcode
+ * Arguments:
+ * - name: hostname to resolve
+ * - addr: output host address
+ * - addrtype: type of address to query
+ * - err: output error
+ * Return values:
+ * - 0: Hook has not consumed hostname query, query continues into DNS module
+ * - != 0: Hook has consumed the query
+ *
+ * err must also be checked to determine if the hook consumed the query, but
+ * the query failed
+ */
+#ifdef __DOXYGEN__
+#define LWIP_HOOK_NETCONN_EXTERNAL_RESOLVE(name, addr, addrtype, err)
+#endif
+/**
+ * @}
+ */
+
+/*
+   ---------------------------------------
+   ---------- Debugging options ----------
+   ---------------------------------------
+*/
+/**
+ * @defgroup lwip_opts_debugmsg Debug messages
+ * @ingroup lwip_opts_debug
+ * @{
+ */
+/**
+ * LWIP_DBG_MIN_LEVEL: After masking, the value of the debug is
+ * compared against this value. If it is smaller, then debugging
+ * messages are written.
+ * @see debugging_levels
+ */
+#if !defined LWIP_DBG_MIN_LEVEL || defined __DOXYGEN__
+#define LWIP_DBG_MIN_LEVEL              LWIP_DBG_LEVEL_ALL
+#endif
+
+/**
+ * LWIP_DBG_TYPES_ON: A mask that can be used to globally enable/disable
+ * debug messages of certain types.
+ * @see debugging_levels
+ */
+#if !defined LWIP_DBG_TYPES_ON || defined __DOXYGEN__
+#define LWIP_DBG_TYPES_ON               LWIP_DBG_ON
+#endif
+
+/**
+ * ETHARP_DEBUG: Enable debugging in etharp.c.
+ */
+#if !defined ETHARP_DEBUG || defined __DOXYGEN__
+#define ETHARP_DEBUG                    LWIP_DBG_OFF
+#endif
+
+/**
+ * NETIF_DEBUG: Enable debugging in netif.c.
+ */
+#if !defined NETIF_DEBUG || defined __DOXYGEN__
+#define NETIF_DEBUG                     LWIP_DBG_OFF
+#endif
+
+/**
+ * PBUF_DEBUG: Enable debugging in pbuf.c.
+ */
+#if !defined PBUF_DEBUG || defined __DOXYGEN__
+#define PBUF_DEBUG                      LWIP_DBG_OFF
+#endif
+
+/**
+ * API_LIB_DEBUG: Enable debugging in api_lib.c.
+ */
+#if !defined API_LIB_DEBUG || defined __DOXYGEN__
+#define API_LIB_DEBUG                   LWIP_DBG_OFF
+#endif
+
+/**
+ * API_MSG_DEBUG: Enable debugging in api_msg.c.
+ */
+#if !defined API_MSG_DEBUG || defined __DOXYGEN__
+#define API_MSG_DEBUG                   LWIP_DBG_OFF
+#endif
+
+/**
+ * SOCKETS_DEBUG: Enable debugging in sockets.c.
+ */
+#if !defined SOCKETS_DEBUG || defined __DOXYGEN__
+#define SOCKETS_DEBUG                   LWIP_DBG_OFF
+#endif
+
+/**
+ * ICMP_DEBUG: Enable debugging in icmp.c.
+ */
+#if !defined ICMP_DEBUG || defined __DOXYGEN__
+#define ICMP_DEBUG                      LWIP_DBG_OFF
+#endif
+
+/**
+ * IGMP_DEBUG: Enable debugging in igmp.c.
+ */
+#if !defined IGMP_DEBUG || defined __DOXYGEN__
+#define IGMP_DEBUG                      LWIP_DBG_OFF
+#endif
+
+/**
+ * INET_DEBUG: Enable debugging in inet.c.
+ */
+#if !defined INET_DEBUG || defined __DOXYGEN__
+#define INET_DEBUG                      LWIP_DBG_OFF
+#endif
+
+/**
+ * IP_DEBUG: Enable debugging for IP.
+ */
+#if !defined IP_DEBUG || defined __DOXYGEN__
+#define IP_DEBUG                        LWIP_DBG_OFF
+#endif
+
+/**
+ * IP_REASS_DEBUG: Enable debugging in ip_frag.c for both frag & reass.
+ */
+#if !defined IP_REASS_DEBUG || defined __DOXYGEN__
+#define IP_REASS_DEBUG                  LWIP_DBG_OFF
+#endif
+
+/**
+ * RAW_DEBUG: Enable debugging in raw.c.
+ */
+#if !defined RAW_DEBUG || defined __DOXYGEN__
+#define RAW_DEBUG                       LWIP_DBG_OFF
+#endif
+
+/**
+ * MEM_DEBUG: Enable debugging in mem.c.
+ */
+#if !defined MEM_DEBUG || defined __DOXYGEN__
+#define MEM_DEBUG                       LWIP_DBG_OFF
+#endif
+
+/**
+ * MEMP_DEBUG: Enable debugging in memp.c.
+ */
+#if !defined MEMP_DEBUG || defined __DOXYGEN__
+#define MEMP_DEBUG                      LWIP_DBG_OFF
+#endif
+
+/**
+ * SYS_DEBUG: Enable debugging in sys.c.
+ */
+#if !defined SYS_DEBUG || defined __DOXYGEN__
+#define SYS_DEBUG                       LWIP_DBG_OFF
+#endif
+
+/**
+ * TIMERS_DEBUG: Enable debugging in timers.c.
+ */
+#if !defined TIMERS_DEBUG || defined __DOXYGEN__
+#define TIMERS_DEBUG                    LWIP_DBG_OFF
+#endif
+
+/**
+ * TCP_DEBUG: Enable debugging for TCP.
+ */
+#if !defined TCP_DEBUG || defined __DOXYGEN__
+#define TCP_DEBUG                       LWIP_DBG_OFF
+#endif
+
+/**
+ * TCP_INPUT_DEBUG: Enable debugging in tcp_in.c for incoming debug.
+ */
+#if !defined TCP_INPUT_DEBUG || defined __DOXYGEN__
+#define TCP_INPUT_DEBUG                 LWIP_DBG_OFF
+#endif
+
+/**
+ * TCP_FR_DEBUG: Enable debugging in tcp_in.c for fast retransmit.
+ */
+#if !defined TCP_FR_DEBUG || defined __DOXYGEN__
+#define TCP_FR_DEBUG                    LWIP_DBG_OFF
+#endif
+
+/**
+ * TCP_RTO_DEBUG: Enable debugging in TCP for retransmit
+ * timeout.
+ */
+#if !defined TCP_RTO_DEBUG || defined __DOXYGEN__
+#define TCP_RTO_DEBUG                   LWIP_DBG_OFF
+#endif
+
+/**
+ * TCP_CWND_DEBUG: Enable debugging for TCP congestion window.
+ */
+#if !defined TCP_CWND_DEBUG || defined __DOXYGEN__
+#define TCP_CWND_DEBUG                  LWIP_DBG_OFF
+#endif
+
+/**
+ * TCP_WND_DEBUG: Enable debugging in tcp_in.c for window updating.
+ */
+#if !defined TCP_WND_DEBUG || defined __DOXYGEN__
+#define TCP_WND_DEBUG                   LWIP_DBG_OFF
+#endif
+
+/**
+ * TCP_OUTPUT_DEBUG: Enable debugging in tcp_out.c output functions.
+ */
+#if !defined TCP_OUTPUT_DEBUG || defined __DOXYGEN__
+#define TCP_OUTPUT_DEBUG                LWIP_DBG_OFF
+#endif
+
+/**
+ * TCP_RST_DEBUG: Enable debugging for TCP with the RST message.
+ */
+#if !defined TCP_RST_DEBUG || defined __DOXYGEN__
+#define TCP_RST_DEBUG                   LWIP_DBG_OFF
+#endif
+
+/**
+ * TCP_QLEN_DEBUG: Enable debugging for TCP queue lengths.
+ */
+#if !defined TCP_QLEN_DEBUG || defined __DOXYGEN__
+#define TCP_QLEN_DEBUG                  LWIP_DBG_OFF
+#endif
+
+/**
+ * UDP_DEBUG: Enable debugging in UDP.
+ */
+#if !defined UDP_DEBUG || defined __DOXYGEN__
+#define UDP_DEBUG                       LWIP_DBG_OFF
+#endif
+
+/**
+ * TCPIP_DEBUG: Enable debugging in tcpip.c.
+ */
+#if !defined TCPIP_DEBUG || defined __DOXYGEN__
+#define TCPIP_DEBUG                     LWIP_DBG_OFF
+#endif
+
+/**
+ * SLIP_DEBUG: Enable debugging in slipif.c.
+ */
+#if !defined SLIP_DEBUG || defined __DOXYGEN__
+#define SLIP_DEBUG                      LWIP_DBG_OFF
+#endif
+
+/**
+ * DHCP_DEBUG: Enable debugging in dhcp.c.
+ */
+#if !defined DHCP_DEBUG || defined __DOXYGEN__
+#define DHCP_DEBUG                      LWIP_DBG_OFF
+#endif
+
+/**
+ * AUTOIP_DEBUG: Enable debugging in autoip.c.
+ */
+#if !defined AUTOIP_DEBUG || defined __DOXYGEN__
+#define AUTOIP_DEBUG                    LWIP_DBG_OFF
+#endif
+
+/**
+ * DNS_DEBUG: Enable debugging for DNS.
+ */
+#if !defined DNS_DEBUG || defined __DOXYGEN__
+#define DNS_DEBUG                       LWIP_DBG_OFF
+#endif
+
+/**
+ * IP6_DEBUG: Enable debugging for IPv6.
+ */
+#if !defined IP6_DEBUG || defined __DOXYGEN__
+#define IP6_DEBUG                       LWIP_DBG_OFF
+#endif
+
+/**
+ * DHCP6_DEBUG: Enable debugging in dhcp6.c.
+ */
+#if !defined DHCP6_DEBUG || defined __DOXYGEN__
+#define DHCP6_DEBUG                     LWIP_DBG_OFF
+#endif
+/**
+ * @}
+ */
+
+/**
+ * LWIP_TESTMODE: Changes to make unit test possible
+ */
+#if !defined LWIP_TESTMODE
+#define LWIP_TESTMODE                   0
+#endif
+
+/*
+   --------------------------------------------------
+   ---------- Performance tracking options ----------
+   --------------------------------------------------
+*/
+/**
+ * @defgroup lwip_opts_perf Performance
+ * @ingroup lwip_opts_debug
+ * @{
+ */
+/**
+ * LWIP_PERF: Enable performance testing for lwIP
+ * (if enabled, arch/perf.h is included)
+ */
+#if !defined LWIP_PERF || defined __DOXYGEN__
+#define LWIP_PERF                       0
+#endif
+/**
+ * @}
+ */
+
+#endif /* LWIP_HDR_OPT_H */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/pbuf.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/pbuf.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/pbuf.h	(revision 457)
@@ -0,0 +1,322 @@
+/**
+ * @file
+ * pbuf API
+ */
+
+/*
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Adam Dunkels <adam@sics.se>
+ *
+ */
+
+#ifndef LWIP_HDR_PBUF_H
+#define LWIP_HDR_PBUF_H
+
+#include "lwip/opt.h"
+#include "lwip/err.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** LWIP_SUPPORT_CUSTOM_PBUF==1: Custom pbufs behave much like their pbuf type
+ * but they are allocated by external code (initialised by calling
+ * pbuf_alloced_custom()) and when pbuf_free gives up their last reference, they
+ * are freed by calling pbuf_custom->custom_free_function().
+ * Currently, the pbuf_custom code is only needed for one specific configuration
+ * of IP_FRAG, unless required by external driver/application code. */
+#ifndef LWIP_SUPPORT_CUSTOM_PBUF
+#define LWIP_SUPPORT_CUSTOM_PBUF ((IP_FRAG && !LWIP_NETIF_TX_SINGLE_PBUF) || (LWIP_IPV6 && LWIP_IPV6_FRAG))
+#endif
+
+/** @ingroup pbuf 
+ * PBUF_NEEDS_COPY(p): return a boolean value indicating whether the given
+ * pbuf needs to be copied in order to be kept around beyond the current call
+ * stack without risking being corrupted. The default setting provides safety:
+ * it will make a copy iof any pbuf chain that does not consist entirely of
+ * PBUF_ROM type pbufs. For setups with zero-copy support, it may be redefined
+ * to evaluate to true in all cases, for example. However, doing so also has an
+ * effect on the application side: any buffers that are *not* copied must also
+ * *not* be reused by the application after passing them to lwIP. For example,
+ * when setting PBUF_NEEDS_COPY to (0), after using udp_send() with a PBUF_RAM
+ * pbuf, the application must free the pbuf immediately, rather than reusing it
+ * for other purposes. For more background information on this, see tasks #6735
+ * and #7896, and bugs #11400 and #49914. */
+#ifndef PBUF_NEEDS_COPY
+#define PBUF_NEEDS_COPY(p)  ((p)->type_internal & PBUF_TYPE_FLAG_DATA_VOLATILE)
+#endif /* PBUF_NEEDS_COPY */
+
+/* @todo: We need a mechanism to prevent wasting memory in every pbuf
+   (TCP vs. UDP, IPv4 vs. IPv6: UDP/IPv4 packets may waste up to 28 bytes) */
+
+#define PBUF_TRANSPORT_HLEN 20
+#if LWIP_IPV6
+#define PBUF_IP_HLEN        40
+#else
+#define PBUF_IP_HLEN        20
+#endif
+
+/**
+ * @ingroup pbuf
+ * Enumeration of pbuf layers
+ */
+typedef enum {
+  /** Includes spare room for transport layer header, e.g. UDP header.
+   * Use this if you intend to pass the pbuf to functions like udp_send().
+   */
+  PBUF_TRANSPORT = PBUF_LINK_ENCAPSULATION_HLEN + PBUF_LINK_HLEN + PBUF_IP_HLEN + PBUF_TRANSPORT_HLEN,
+  /** Includes spare room for IP header.
+   * Use this if you intend to pass the pbuf to functions like raw_send().
+   */
+  PBUF_IP = PBUF_LINK_ENCAPSULATION_HLEN + PBUF_LINK_HLEN + PBUF_IP_HLEN,
+  /** Includes spare room for link layer header (ethernet header).
+   * Use this if you intend to pass the pbuf to functions like ethernet_output().
+   * @see PBUF_LINK_HLEN
+   */
+  PBUF_LINK = PBUF_LINK_ENCAPSULATION_HLEN + PBUF_LINK_HLEN,
+  /** Includes spare room for additional encapsulation header before ethernet
+   * headers (e.g. 802.11).
+   * Use this if you intend to pass the pbuf to functions like netif->linkoutput().
+   * @see PBUF_LINK_ENCAPSULATION_HLEN
+   */
+  PBUF_RAW_TX = PBUF_LINK_ENCAPSULATION_HLEN,
+  /** Use this for input packets in a netif driver when calling netif->input()
+   * in the most common case - ethernet-layer netif driver. */
+  PBUF_RAW = 0
+} pbuf_layer;
+
+
+/* Base flags for pbuf_type definitions: */
+
+/** Indicates that the payload directly follows the struct pbuf.
+ *  This makes @ref pbuf_header work in both directions. */
+#define PBUF_TYPE_FLAG_STRUCT_DATA_CONTIGUOUS       0x80
+/** Indicates the data stored in this pbuf can change. If this pbuf needs
+ * to be queued, it must be copied/duplicated. */
+#define PBUF_TYPE_FLAG_DATA_VOLATILE                0x40
+/** 4 bits are reserved for 16 allocation sources (e.g. heap, pool1, pool2, etc)
+ * Internally, we use: 0=heap, 1=MEMP_PBUF, 2=MEMP_PBUF_POOL -> 13 types free*/
+#define PBUF_TYPE_ALLOC_SRC_MASK                    0x0F
+/** Indicates this pbuf is used for RX (if not set, indicates use for TX).
+ * This information can be used to keep some spare RX buffers e.g. for
+ * receiving TCP ACKs to unblock a connection) */
+#define PBUF_ALLOC_FLAG_RX                          0x0100
+/** Indicates the application needs the pbuf payload to be in one piece */
+#define PBUF_ALLOC_FLAG_DATA_CONTIGUOUS             0x0200
+
+#define PBUF_TYPE_ALLOC_SRC_MASK_STD_HEAP           0x00
+#define PBUF_TYPE_ALLOC_SRC_MASK_STD_MEMP_PBUF      0x01
+#define PBUF_TYPE_ALLOC_SRC_MASK_STD_MEMP_PBUF_POOL 0x02
+/** First pbuf allocation type for applications */
+#define PBUF_TYPE_ALLOC_SRC_MASK_APP_MIN            0x03
+/** Last pbuf allocation type for applications */
+#define PBUF_TYPE_ALLOC_SRC_MASK_APP_MAX            PBUF_TYPE_ALLOC_SRC_MASK
+
+/**
+ * @ingroup pbuf
+ * Enumeration of pbuf types
+ */
+typedef enum {
+  /** pbuf data is stored in RAM, used for TX mostly, struct pbuf and its payload
+      are allocated in one piece of contiguous memory (so the first payload byte
+      can be calculated from struct pbuf).
+      pbuf_alloc() allocates PBUF_RAM pbufs as unchained pbufs (although that might
+      change in future versions).
+      This should be used for all OUTGOING packets (TX).*/
+  PBUF_RAM = (PBUF_ALLOC_FLAG_DATA_CONTIGUOUS | PBUF_TYPE_FLAG_STRUCT_DATA_CONTIGUOUS | PBUF_TYPE_ALLOC_SRC_MASK_STD_HEAP),
+  /** pbuf data is stored in ROM, i.e. struct pbuf and its payload are located in
+      totally different memory areas. Since it points to ROM, payload does not
+      have to be copied when queued for transmission. */
+  PBUF_ROM = PBUF_TYPE_ALLOC_SRC_MASK_STD_MEMP_PBUF,
+  /** pbuf comes from the pbuf pool. Much like PBUF_ROM but payload might change
+      so it has to be duplicated when queued before transmitting, depending on
+      who has a 'ref' to it. */
+  PBUF_REF = (PBUF_TYPE_FLAG_DATA_VOLATILE | PBUF_TYPE_ALLOC_SRC_MASK_STD_MEMP_PBUF),
+  /** pbuf payload refers to RAM. This one comes from a pool and should be used
+      for RX. Payload can be chained (scatter-gather RX) but like PBUF_RAM, struct
+      pbuf and its payload are allocated in one piece of contiguous memory (so
+      the first payload byte can be calculated from struct pbuf).
+      Don't use this for TX, if the pool becomes empty e.g. because of TCP queuing,
+      you are unable to receive TCP acks! */
+  PBUF_POOL = (PBUF_ALLOC_FLAG_RX | PBUF_TYPE_FLAG_STRUCT_DATA_CONTIGUOUS | PBUF_TYPE_ALLOC_SRC_MASK_STD_MEMP_PBUF_POOL)
+} pbuf_type;
+
+
+/** indicates this packet's data should be immediately passed to the application */
+#define PBUF_FLAG_PUSH      0x01U
+/** indicates this is a custom pbuf: pbuf_free calls pbuf_custom->custom_free_function()
+    when the last reference is released (plus custom PBUF_RAM cannot be trimmed) */
+#define PBUF_FLAG_IS_CUSTOM 0x02U
+/** indicates this pbuf is UDP multicast to be looped back */
+#define PBUF_FLAG_MCASTLOOP 0x04U
+/** indicates this pbuf was received as link-level broadcast */
+#define PBUF_FLAG_LLBCAST   0x08U
+/** indicates this pbuf was received as link-level multicast */
+#define PBUF_FLAG_LLMCAST   0x10U
+/** indicates this pbuf includes a TCP FIN flag */
+#define PBUF_FLAG_TCP_FIN   0x20U
+
+/** Main packet buffer struct */
+struct pbuf {
+  /** next pbuf in singly linked pbuf chain */
+  struct pbuf *next;
+
+  /** pointer to the actual data in the buffer */
+  void *payload;
+
+  /**
+   * total length of this buffer and all next buffers in chain
+   * belonging to the same packet.
+   *
+   * For non-queue packet chains this is the invariant:
+   * p->tot_len == p->len + (p->next? p->next->tot_len: 0)
+   */
+  u16_t tot_len;
+
+  /** length of this buffer */
+  u16_t len;
+
+  /** a bit field indicating pbuf type and allocation sources
+      (see PBUF_TYPE_FLAG_*, PBUF_ALLOC_FLAG_* and PBUF_TYPE_ALLOC_SRC_MASK)
+    */
+  u8_t type_internal;
+
+  /** misc flags */
+  u8_t flags;
+
+  /**
+   * the reference count always equals the number of pointers
+   * that refer to this pbuf. This can be pointers from an application,
+   * the stack itself, or pbuf->next pointers from a chain.
+   */
+  LWIP_PBUF_REF_T ref;
+
+  /** For incoming packets, this contains the input netif's index */
+  u8_t if_idx;
+};
+
+
+/** Helper struct for const-correctness only.
+ * The only meaning of this one is to provide a const payload pointer
+ * for PBUF_ROM type.
+ */
+struct pbuf_rom {
+  /** next pbuf in singly linked pbuf chain */
+  struct pbuf *next;
+
+  /** pointer to the actual data in the buffer */
+  const void *payload;
+};
+
+#if LWIP_SUPPORT_CUSTOM_PBUF
+/** Prototype for a function to free a custom pbuf */
+typedef void (*pbuf_free_custom_fn)(struct pbuf *p);
+
+/** A custom pbuf: like a pbuf, but following a function pointer to free it. */
+struct pbuf_custom {
+  /** The actual pbuf */
+  struct pbuf pbuf;
+  /** This function is called when pbuf_free deallocates this pbuf(_custom) */
+  pbuf_free_custom_fn custom_free_function;
+};
+#endif /* LWIP_SUPPORT_CUSTOM_PBUF */
+
+/** Define this to 0 to prevent freeing ooseq pbufs when the PBUF_POOL is empty */
+#ifndef PBUF_POOL_FREE_OOSEQ
+#define PBUF_POOL_FREE_OOSEQ 1
+#endif /* PBUF_POOL_FREE_OOSEQ */
+#if LWIP_TCP && TCP_QUEUE_OOSEQ && NO_SYS && PBUF_POOL_FREE_OOSEQ
+extern volatile u8_t pbuf_free_ooseq_pending;
+void pbuf_free_ooseq(void);
+/** When not using sys_check_timeouts(), call PBUF_CHECK_FREE_OOSEQ()
+    at regular intervals from main level to check if ooseq pbufs need to be
+    freed! */
+#define PBUF_CHECK_FREE_OOSEQ() do { if(pbuf_free_ooseq_pending) { \
+  /* pbuf_alloc() reported PBUF_POOL to be empty -> try to free some \
+     ooseq queued pbufs now */ \
+  pbuf_free_ooseq(); }}while(0)
+#else /* LWIP_TCP && TCP_QUEUE_OOSEQ && NO_SYS && PBUF_POOL_FREE_OOSEQ */
+  /* Otherwise declare an empty PBUF_CHECK_FREE_OOSEQ */
+  #define PBUF_CHECK_FREE_OOSEQ()
+#endif /* LWIP_TCP && TCP_QUEUE_OOSEQ && NO_SYS && PBUF_POOL_FREE_OOSEQ*/
+
+/* Initializes the pbuf module. This call is empty for now, but may not be in future. */
+#define pbuf_init()
+
+struct pbuf *pbuf_alloc(pbuf_layer l, u16_t length, pbuf_type type);
+struct pbuf *pbuf_alloc_reference(void *payload, u16_t length, pbuf_type type);
+#if LWIP_SUPPORT_CUSTOM_PBUF
+struct pbuf *pbuf_alloced_custom(pbuf_layer l, u16_t length, pbuf_type type,
+                                 struct pbuf_custom *p, void *payload_mem,
+                                 u16_t payload_mem_len);
+#endif /* LWIP_SUPPORT_CUSTOM_PBUF */
+void pbuf_realloc(struct pbuf *p, u16_t size);
+#define pbuf_get_allocsrc(p)          ((p)->type_internal & PBUF_TYPE_ALLOC_SRC_MASK)
+#define pbuf_match_allocsrc(p, type)  (pbuf_get_allocsrc(p) == ((type) & PBUF_TYPE_ALLOC_SRC_MASK))
+#define pbuf_match_type(p, type)      pbuf_match_allocsrc(p, type)
+u8_t pbuf_header(struct pbuf *p, s16_t header_size);
+u8_t pbuf_header_force(struct pbuf *p, s16_t header_size);
+u8_t pbuf_add_header(struct pbuf *p, size_t header_size_increment);
+u8_t pbuf_add_header_force(struct pbuf *p, size_t header_size_increment);
+u8_t pbuf_remove_header(struct pbuf *p, size_t header_size);
+struct pbuf *pbuf_free_header(struct pbuf *q, u16_t size);
+void pbuf_ref(struct pbuf *p);
+u8_t pbuf_free(struct pbuf *p);
+u16_t pbuf_clen(const struct pbuf *p);
+void pbuf_cat(struct pbuf *head, struct pbuf *tail);
+void pbuf_chain(struct pbuf *head, struct pbuf *tail);
+struct pbuf *pbuf_dechain(struct pbuf *p);
+err_t pbuf_copy(struct pbuf *p_to, const struct pbuf *p_from);
+u16_t pbuf_copy_partial(const struct pbuf *p, void *dataptr, u16_t len, u16_t offset);
+void *pbuf_get_contiguous(const struct pbuf *p, void *buffer, size_t bufsize, u16_t len, u16_t offset);
+err_t pbuf_take(struct pbuf *buf, const void *dataptr, u16_t len);
+err_t pbuf_take_at(struct pbuf *buf, const void *dataptr, u16_t len, u16_t offset);
+struct pbuf *pbuf_skip(struct pbuf* in, u16_t in_offset, u16_t* out_offset);
+struct pbuf *pbuf_coalesce(struct pbuf *p, pbuf_layer layer);
+struct pbuf *pbuf_clone(pbuf_layer l, pbuf_type type, struct pbuf *p);
+#if LWIP_CHECKSUM_ON_COPY
+err_t pbuf_fill_chksum(struct pbuf *p, u16_t start_offset, const void *dataptr,
+                       u16_t len, u16_t *chksum);
+#endif /* LWIP_CHECKSUM_ON_COPY */
+#if LWIP_TCP && TCP_QUEUE_OOSEQ && LWIP_WND_SCALE
+void pbuf_split_64k(struct pbuf *p, struct pbuf **rest);
+#endif /* LWIP_TCP && TCP_QUEUE_OOSEQ && LWIP_WND_SCALE */
+
+u8_t pbuf_get_at(const struct pbuf* p, u16_t offset);
+int pbuf_try_get_at(const struct pbuf* p, u16_t offset);
+void pbuf_put_at(struct pbuf* p, u16_t offset, u8_t data);
+u16_t pbuf_memcmp(const struct pbuf* p, u16_t offset, const void* s2, u16_t n);
+u16_t pbuf_memfind(const struct pbuf* p, const void* mem, u16_t mem_len, u16_t start_offset);
+u16_t pbuf_strstr(const struct pbuf* p, const char* substr);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LWIP_HDR_PBUF_H */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/priv/altcp_priv.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/priv/altcp_priv.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/priv/altcp_priv.h	(revision 457)
@@ -0,0 +1,146 @@
+/**
+ * @file
+ * Application layered TCP connection API (to be used from TCPIP thread)\n
+ * This interface mimics the tcp callback API to the application while preventing
+ * direct linking (much like virtual functions).
+ * This way, an application can make use of other application layer protocols
+ * on top of TCP without knowing the details (e.g. TLS, proxy connection).
+ */
+
+/*
+ * Copyright (c) 2017 Simon Goldschmidt
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Simon Goldschmidt <goldsimon@gmx.de>
+ *
+ */
+#ifndef LWIP_HDR_ALTCP_PRIV_H
+#define LWIP_HDR_ALTCP_PRIV_H
+
+#include "lwip/opt.h"
+
+#if LWIP_ALTCP /* don't build if not configured for use in lwipopts.h */
+
+#include "lwip/altcp.h"
+#include "lwip/ip_addr.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct altcp_pcb *altcp_alloc(void);
+void altcp_free(struct altcp_pcb *conn);
+
+/* Function prototypes for application layers */
+typedef void (*altcp_set_poll_fn)(struct altcp_pcb *conn, u8_t interval);
+typedef void (*altcp_recved_fn)(struct altcp_pcb *conn, u16_t len);
+typedef err_t (*altcp_bind_fn)(struct altcp_pcb *conn, const ip_addr_t *ipaddr, u16_t port);
+typedef err_t (*altcp_connect_fn)(struct altcp_pcb *conn, const ip_addr_t *ipaddr, u16_t port, altcp_connected_fn connected);
+
+typedef struct altcp_pcb *(*altcp_listen_fn)(struct altcp_pcb *conn, u8_t backlog, err_t *err);
+
+typedef void  (*altcp_abort_fn)(struct altcp_pcb *conn);
+typedef err_t (*altcp_close_fn)(struct altcp_pcb *conn);
+typedef err_t (*altcp_shutdown_fn)(struct altcp_pcb *conn, int shut_rx, int shut_tx);
+
+typedef err_t (*altcp_write_fn)(struct altcp_pcb *conn, const void *dataptr, u16_t len, u8_t apiflags);
+typedef err_t (*altcp_output_fn)(struct altcp_pcb *conn);
+
+typedef u16_t (*altcp_mss_fn)(struct altcp_pcb *conn);
+typedef u16_t (*altcp_sndbuf_fn)(struct altcp_pcb *conn);
+typedef u16_t (*altcp_sndqueuelen_fn)(struct altcp_pcb *conn);
+typedef void  (*altcp_nagle_disable_fn)(struct altcp_pcb *conn);
+typedef void  (*altcp_nagle_enable_fn)(struct altcp_pcb *conn);
+typedef int   (*altcp_nagle_disabled_fn)(struct altcp_pcb *conn);
+
+typedef void  (*altcp_setprio_fn)(struct altcp_pcb *conn, u8_t prio);
+
+typedef void  (*altcp_dealloc_fn)(struct altcp_pcb *conn);
+
+typedef err_t (*altcp_get_tcp_addrinfo_fn)(struct altcp_pcb *conn, int local, ip_addr_t *addr, u16_t *port);
+typedef ip_addr_t *(*altcp_get_ip_fn)(struct altcp_pcb *conn, int local);
+typedef u16_t (*altcp_get_port_fn)(struct altcp_pcb *conn, int local);
+
+#ifdef LWIP_DEBUG
+typedef enum tcp_state (*altcp_dbg_get_tcp_state_fn)(struct altcp_pcb *conn);
+#endif
+
+struct altcp_functions {
+  altcp_set_poll_fn           set_poll;
+  altcp_recved_fn             recved;
+  altcp_bind_fn               bind;
+  altcp_connect_fn            connect;
+  altcp_listen_fn             listen;
+  altcp_abort_fn              abort;
+  altcp_close_fn              close;
+  altcp_shutdown_fn           shutdown;
+  altcp_write_fn              write;
+  altcp_output_fn             output;
+  altcp_mss_fn                mss;
+  altcp_sndbuf_fn             sndbuf;
+  altcp_sndqueuelen_fn        sndqueuelen;
+  altcp_nagle_disable_fn      nagle_disable;
+  altcp_nagle_enable_fn       nagle_enable;
+  altcp_nagle_disabled_fn     nagle_disabled;
+  altcp_setprio_fn            setprio;
+  altcp_dealloc_fn            dealloc;
+  altcp_get_tcp_addrinfo_fn   addrinfo;
+  altcp_get_ip_fn             getip;
+  altcp_get_port_fn           getport;
+#ifdef LWIP_DEBUG
+  altcp_dbg_get_tcp_state_fn  dbg_get_tcp_state;
+#endif
+};
+
+void  altcp_default_set_poll(struct altcp_pcb *conn, u8_t interval);
+void  altcp_default_recved(struct altcp_pcb *conn, u16_t len);
+err_t altcp_default_bind(struct altcp_pcb *conn, const ip_addr_t *ipaddr, u16_t port);
+err_t altcp_default_shutdown(struct altcp_pcb *conn, int shut_rx, int shut_tx);
+err_t altcp_default_write(struct altcp_pcb *conn, const void *dataptr, u16_t len, u8_t apiflags);
+err_t altcp_default_output(struct altcp_pcb *conn);
+u16_t altcp_default_mss(struct altcp_pcb *conn);
+u16_t altcp_default_sndbuf(struct altcp_pcb *conn);
+u16_t altcp_default_sndqueuelen(struct altcp_pcb *conn);
+void  altcp_default_nagle_disable(struct altcp_pcb *conn);
+void  altcp_default_nagle_enable(struct altcp_pcb *conn);
+int   altcp_default_nagle_disabled(struct altcp_pcb *conn);
+void  altcp_default_setprio(struct altcp_pcb *conn, u8_t prio);
+void  altcp_default_dealloc(struct altcp_pcb *conn);
+err_t altcp_default_get_tcp_addrinfo(struct altcp_pcb *conn, int local, ip_addr_t *addr, u16_t *port);
+ip_addr_t *altcp_default_get_ip(struct altcp_pcb *conn, int local);
+u16_t altcp_default_get_port(struct altcp_pcb *conn, int local);
+#ifdef LWIP_DEBUG
+enum tcp_state altcp_default_dbg_get_tcp_state(struct altcp_pcb *conn);
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LWIP_ALTCP */
+
+#endif /* LWIP_HDR_ALTCP_PRIV_H */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/priv/api_msg.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/priv/api_msg.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/priv/api_msg.h	(revision 457)
@@ -0,0 +1,272 @@
+/**
+ * @file
+ * netconn API lwIP internal implementations (do not use in application code)
+ */
+
+/*
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Adam Dunkels <adam@sics.se>
+ *
+ */
+#ifndef LWIP_HDR_API_MSG_H
+#define LWIP_HDR_API_MSG_H
+
+#include "lwip/opt.h"
+
+#include "lwip/arch.h"
+#include "lwip/ip_addr.h"
+#include "lwip/err.h"
+#include "lwip/sys.h"
+#include "lwip/igmp.h"
+#include "lwip/api.h"
+#include "lwip/priv/tcpip_priv.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if LWIP_NETCONN || LWIP_SOCKET /* don't build if not configured for use in lwipopts.h */
+/* Note: Netconn API is always available when sockets are enabled -
+ * sockets are implemented on top of them */
+
+#if LWIP_MPU_COMPATIBLE
+#if LWIP_NETCONN_SEM_PER_THREAD
+#define API_MSG_M_DEF_SEM(m)  *m
+#else
+#define API_MSG_M_DEF_SEM(m)  API_MSG_M_DEF(m)
+#endif
+#else /* LWIP_MPU_COMPATIBLE */
+#define API_MSG_M_DEF_SEM(m)  API_MSG_M_DEF(m)
+#endif /* LWIP_MPU_COMPATIBLE */
+
+/* For the netconn API, these values are use as a bitmask! */
+#define NETCONN_SHUT_RD   1
+#define NETCONN_SHUT_WR   2
+#define NETCONN_SHUT_RDWR (NETCONN_SHUT_RD | NETCONN_SHUT_WR)
+
+/* IP addresses and port numbers are expected to be in
+ * the same byte order as in the corresponding pcb.
+ */
+/** This struct includes everything that is necessary to execute a function
+    for a netconn in another thread context (mainly used to process netconns
+    in the tcpip_thread context to be thread safe). */
+struct api_msg {
+  /** The netconn which to process - always needed: it includes the semaphore
+      which is used to block the application thread until the function finished. */
+  struct netconn *conn;
+  /** The return value of the function executed in tcpip_thread. */
+  err_t err;
+  /** Depending on the executed function, one of these union members is used */
+  union {
+    /** used for lwip_netconn_do_send */
+    struct netbuf *b;
+    /** used for lwip_netconn_do_newconn */
+    struct {
+      u8_t proto;
+    } n;
+    /** used for lwip_netconn_do_bind and lwip_netconn_do_connect */
+    struct {
+      API_MSG_M_DEF_C(ip_addr_t, ipaddr);
+      u16_t port;
+      u8_t if_idx;
+    } bc;
+    /** used for lwip_netconn_do_getaddr */
+    struct {
+      ip_addr_t API_MSG_M_DEF(ipaddr);
+      u16_t API_MSG_M_DEF(port);
+      u8_t local;
+    } ad;
+    /** used for lwip_netconn_do_write */
+    struct {
+      /** current vector to write */
+      const struct netvector *vector;
+      /** number of unwritten vectors */
+      u16_t vector_cnt;
+      /** offset into current vector */
+      size_t vector_off;
+      /** total length across vectors */
+      size_t len;
+      /** offset into total length/output of bytes written when err == ERR_OK */
+      size_t offset;
+      u8_t apiflags;
+#if LWIP_SO_SNDTIMEO
+      u32_t time_started;
+#endif /* LWIP_SO_SNDTIMEO */
+    } w;
+    /** used for lwip_netconn_do_recv */
+    struct {
+      size_t len;
+    } r;
+#if LWIP_TCP
+    /** used for lwip_netconn_do_close (/shutdown) */
+    struct {
+      u8_t shut;
+#if LWIP_SO_SNDTIMEO || LWIP_SO_LINGER
+      u32_t time_started;
+#else /* LWIP_SO_SNDTIMEO || LWIP_SO_LINGER */
+      u8_t polls_left;
+#endif /* LWIP_SO_SNDTIMEO || LWIP_SO_LINGER */
+    } sd;
+#endif /* LWIP_TCP */
+#if LWIP_IGMP || (LWIP_IPV6 && LWIP_IPV6_MLD)
+    /** used for lwip_netconn_do_join_leave_group */
+    struct {
+      API_MSG_M_DEF_C(ip_addr_t, multiaddr);
+      API_MSG_M_DEF_C(ip_addr_t, netif_addr);
+      u8_t if_idx;
+      enum netconn_igmp join_or_leave;
+    } jl;
+#endif /* LWIP_IGMP || (LWIP_IPV6 && LWIP_IPV6_MLD) */
+#if TCP_LISTEN_BACKLOG
+    struct {
+      u8_t backlog;
+    } lb;
+#endif /* TCP_LISTEN_BACKLOG */
+  } msg;
+#if LWIP_NETCONN_SEM_PER_THREAD
+  sys_sem_t* op_completed_sem;
+#endif /* LWIP_NETCONN_SEM_PER_THREAD */
+};
+
+#if LWIP_NETCONN_SEM_PER_THREAD
+#define LWIP_API_MSG_SEM(msg)          ((msg)->op_completed_sem)
+#else /* LWIP_NETCONN_SEM_PER_THREAD */
+#define LWIP_API_MSG_SEM(msg)          (&(msg)->conn->op_completed)
+#endif /* LWIP_NETCONN_SEM_PER_THREAD */
+
+
+#if LWIP_DNS
+/** As lwip_netconn_do_gethostbyname requires more arguments but doesn't require a netconn,
+    it has its own struct (to avoid struct api_msg getting bigger than necessary).
+    lwip_netconn_do_gethostbyname must be called using tcpip_callback instead of tcpip_apimsg
+    (see netconn_gethostbyname). */
+struct dns_api_msg {
+  /** Hostname to query or dotted IP address string */
+#if LWIP_MPU_COMPATIBLE
+  char name[DNS_MAX_NAME_LENGTH];
+#else /* LWIP_MPU_COMPATIBLE */
+  const char *name;
+#endif /* LWIP_MPU_COMPATIBLE */
+  /** The resolved address is stored here */
+  ip_addr_t API_MSG_M_DEF(addr);
+#if LWIP_IPV4 && LWIP_IPV6
+  /** Type of resolve call */
+  u8_t dns_addrtype;
+#endif /* LWIP_IPV4 && LWIP_IPV6 */
+  /** This semaphore is posted when the name is resolved, the application thread
+      should wait on it. */
+  sys_sem_t API_MSG_M_DEF_SEM(sem);
+  /** Errors are given back here */
+  err_t API_MSG_M_DEF(err);
+};
+#endif /* LWIP_DNS */
+
+#if LWIP_NETCONN_FULLDUPLEX
+int lwip_netconn_is_deallocated_msg(void *msg);
+#endif
+int lwip_netconn_is_err_msg(void *msg, err_t *err);
+void lwip_netconn_do_newconn         (void *m);
+void lwip_netconn_do_delconn         (void *m);
+void lwip_netconn_do_bind            (void *m);
+void lwip_netconn_do_bind_if         (void *m);
+void lwip_netconn_do_connect         (void *m);
+void lwip_netconn_do_disconnect      (void *m);
+void lwip_netconn_do_listen          (void *m);
+void lwip_netconn_do_send            (void *m);
+void lwip_netconn_do_recv            (void *m);
+#if TCP_LISTEN_BACKLOG
+void lwip_netconn_do_accepted        (void *m);
+#endif /* TCP_LISTEN_BACKLOG */
+void lwip_netconn_do_write           (void *m);
+void lwip_netconn_do_getaddr         (void *m);
+void lwip_netconn_do_close           (void *m);
+void lwip_netconn_do_shutdown        (void *m);
+#if LWIP_IGMP || (LWIP_IPV6 && LWIP_IPV6_MLD)
+void lwip_netconn_do_join_leave_group(void *m);
+void lwip_netconn_do_join_leave_group_netif(void *m);
+#endif /* LWIP_IGMP || (LWIP_IPV6 && LWIP_IPV6_MLD) */
+
+#if LWIP_DNS
+void lwip_netconn_do_gethostbyname(void *arg);
+#endif /* LWIP_DNS */
+
+struct netconn* netconn_alloc(enum netconn_type t, netconn_callback callback);
+void netconn_free(struct netconn *conn);
+
+#endif /* LWIP_NETCONN || LWIP_SOCKET */
+
+#if LWIP_NETIF_API /* don't build if not configured for use in lwipopts.h */
+
+/* netifapi related lwIP internal definitions */
+
+#if LWIP_MPU_COMPATIBLE
+#define NETIFAPI_IPADDR_DEF(type, m)  type m
+#else /* LWIP_MPU_COMPATIBLE */
+#define NETIFAPI_IPADDR_DEF(type, m)  const type * m
+#endif /* LWIP_MPU_COMPATIBLE */
+
+typedef void (*netifapi_void_fn)(struct netif *netif);
+typedef err_t (*netifapi_errt_fn)(struct netif *netif);
+
+struct netifapi_msg {
+  struct tcpip_api_call_data call;
+  struct netif *netif;
+  union {
+    struct {
+#if LWIP_IPV4
+      NETIFAPI_IPADDR_DEF(ip4_addr_t, ipaddr);
+      NETIFAPI_IPADDR_DEF(ip4_addr_t, netmask);
+      NETIFAPI_IPADDR_DEF(ip4_addr_t, gw);
+#endif /* LWIP_IPV4 */
+      void *state;
+      netif_init_fn init;
+      netif_input_fn input;
+    } add;
+    struct {
+      netifapi_void_fn voidfunc;
+      netifapi_errt_fn errtfunc;
+    } common;
+    struct {
+#if LWIP_MPU_COMPATIBLE
+      char name[NETIF_NAMESIZE];
+#else /* LWIP_MPU_COMPATIBLE */
+      char *name;
+#endif /* LWIP_MPU_COMPATIBLE */
+      u8_t index;
+    } ifs;
+  } msg;
+};
+
+#endif /* LWIP_NETIF_API */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LWIP_HDR_API_MSG_H */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/priv/mem_priv.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/priv/mem_priv.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/priv/mem_priv.h	(revision 457)
@@ -0,0 +1,84 @@
+/**
+ * @file
+ * lwIP internal memory implementations (do not use in application code)
+ */
+
+/*
+ * Copyright (c) 2018 Swedish Institute of Computer Science.
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Simon Goldschmidt <goldsimon@gmx.de>
+ *
+ */
+
+#ifndef LWIP_HDR_MEM_PRIV_H
+#define LWIP_HDR_MEM_PRIV_H
+
+#include "lwip/opt.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "lwip/mem.h"
+
+#if MEM_OVERFLOW_CHECK || MEMP_OVERFLOW_CHECK
+/* if MEM_OVERFLOW_CHECK or MEMP_OVERFLOW_CHECK is turned on, we reserve some
+ * bytes at the beginning and at the end of each element, initialize them as
+ * 0xcd and check them later.
+ * If MEM(P)_OVERFLOW_CHECK is >= 2, on every call to mem(p)_malloc or mem(p)_free,
+ * every single element in each pool/heap is checked!
+ * This is VERY SLOW but also very helpful.
+ * MEM_SANITY_REGION_BEFORE and MEM_SANITY_REGION_AFTER can be overridden in
+ * lwipopts.h to change the amount reserved for checking. */
+#ifndef MEM_SANITY_REGION_BEFORE
+#define MEM_SANITY_REGION_BEFORE  16
+#endif /* MEM_SANITY_REGION_BEFORE*/
+#if MEM_SANITY_REGION_BEFORE > 0
+#define MEM_SANITY_REGION_BEFORE_ALIGNED    LWIP_MEM_ALIGN_SIZE(MEM_SANITY_REGION_BEFORE)
+#else
+#define MEM_SANITY_REGION_BEFORE_ALIGNED    0
+#endif /* MEM_SANITY_REGION_BEFORE*/
+#ifndef MEM_SANITY_REGION_AFTER
+#define MEM_SANITY_REGION_AFTER   16
+#endif /* MEM_SANITY_REGION_AFTER*/
+#if MEM_SANITY_REGION_AFTER > 0
+#define MEM_SANITY_REGION_AFTER_ALIGNED     LWIP_MEM_ALIGN_SIZE(MEM_SANITY_REGION_AFTER)
+#else
+#define MEM_SANITY_REGION_AFTER_ALIGNED     0
+#endif /* MEM_SANITY_REGION_AFTER*/
+
+void mem_overflow_init_raw(void *p, size_t size);
+void mem_overflow_check_raw(void *p, size_t size, const char *descr1, const char *descr2);
+
+#endif /* MEM_OVERFLOW_CHECK || MEMP_OVERFLOW_CHECK */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LWIP_HDR_MEMP_PRIV_H */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/priv/memp_priv.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/priv/memp_priv.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/priv/memp_priv.h	(revision 457)
@@ -0,0 +1,161 @@
+/**
+ * @file
+ * memory pools lwIP internal implementations (do not use in application code)
+ */
+
+/*
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Adam Dunkels <adam@sics.se>
+ *
+ */
+
+#ifndef LWIP_HDR_MEMP_PRIV_H
+#define LWIP_HDR_MEMP_PRIV_H
+
+#include "lwip/opt.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "lwip/mem.h"
+#include "lwip/priv/mem_priv.h"
+
+#if MEMP_OVERFLOW_CHECK
+
+
+/* MEMP_SIZE: save space for struct memp and for sanity check */
+#define MEMP_SIZE          (LWIP_MEM_ALIGN_SIZE(sizeof(struct memp)) + MEM_SANITY_REGION_BEFORE_ALIGNED)
+#define MEMP_ALIGN_SIZE(x) (LWIP_MEM_ALIGN_SIZE(x) + MEM_SANITY_REGION_AFTER_ALIGNED)
+
+#else /* MEMP_OVERFLOW_CHECK */
+
+/* No sanity checks
+ * We don't need to preserve the struct memp while not allocated, so we
+ * can save a little space and set MEMP_SIZE to 0.
+ */
+#define MEMP_SIZE           0
+#define MEMP_ALIGN_SIZE(x) (LWIP_MEM_ALIGN_SIZE(x))
+
+#endif /* MEMP_OVERFLOW_CHECK */
+
+#if !MEMP_MEM_MALLOC || MEMP_OVERFLOW_CHECK
+struct memp {
+  struct memp *next;
+#if MEMP_OVERFLOW_CHECK
+  const char *file;
+  int line;
+#endif /* MEMP_OVERFLOW_CHECK */
+};
+#endif /* !MEMP_MEM_MALLOC || MEMP_OVERFLOW_CHECK */
+
+#if MEM_USE_POOLS && MEMP_USE_CUSTOM_POOLS
+/* Use a helper type to get the start and end of the user "memory pools" for mem_malloc */
+typedef enum {
+    /* Get the first (via:
+       MEMP_POOL_HELPER_START = ((u8_t) 1*MEMP_POOL_A + 0*MEMP_POOL_B + 0*MEMP_POOL_C + 0)*/
+    MEMP_POOL_HELPER_FIRST = ((u8_t)
+#define LWIP_MEMPOOL(name,num,size,desc)
+#define LWIP_MALLOC_MEMPOOL_START 1
+#define LWIP_MALLOC_MEMPOOL(num, size) * MEMP_POOL_##size + 0
+#define LWIP_MALLOC_MEMPOOL_END
+#include "lwip/priv/memp_std.h"
+    ) ,
+    /* Get the last (via:
+       MEMP_POOL_HELPER_END = ((u8_t) 0 + MEMP_POOL_A*0 + MEMP_POOL_B*0 + MEMP_POOL_C*1) */
+    MEMP_POOL_HELPER_LAST = ((u8_t)
+#define LWIP_MEMPOOL(name,num,size,desc)
+#define LWIP_MALLOC_MEMPOOL_START
+#define LWIP_MALLOC_MEMPOOL(num, size) 0 + MEMP_POOL_##size *
+#define LWIP_MALLOC_MEMPOOL_END 1
+#include "lwip/priv/memp_std.h"
+    )
+} memp_pool_helper_t;
+
+/* The actual start and stop values are here (cast them over)
+   We use this helper type and these defines so we can avoid using const memp_t values */
+#define MEMP_POOL_FIRST ((memp_t) MEMP_POOL_HELPER_FIRST)
+#define MEMP_POOL_LAST   ((memp_t) MEMP_POOL_HELPER_LAST)
+#endif /* MEM_USE_POOLS && MEMP_USE_CUSTOM_POOLS */
+
+/** Memory pool descriptor */
+struct memp_desc {
+#if defined(LWIP_DEBUG) || MEMP_OVERFLOW_CHECK || LWIP_STATS_DISPLAY
+  /** Textual description */
+  const char *desc;
+#endif /* LWIP_DEBUG || MEMP_OVERFLOW_CHECK || LWIP_STATS_DISPLAY */
+#if MEMP_STATS
+  /** Statistics */
+  struct stats_mem *stats;
+#endif
+
+  /** Element size */
+  u16_t size;
+
+#if !MEMP_MEM_MALLOC
+  /** Number of elements */
+  u16_t num;
+
+  /** Base address */
+  u8_t *base;
+
+  /** First free element of each pool. Elements form a linked list. */
+  struct memp **tab;
+#endif /* MEMP_MEM_MALLOC */
+};
+
+#if defined(LWIP_DEBUG) || MEMP_OVERFLOW_CHECK || LWIP_STATS_DISPLAY
+#define DECLARE_LWIP_MEMPOOL_DESC(desc) (desc),
+#else
+#define DECLARE_LWIP_MEMPOOL_DESC(desc)
+#endif
+
+#if MEMP_STATS
+#define LWIP_MEMPOOL_DECLARE_STATS_INSTANCE(name) static struct stats_mem name;
+#define LWIP_MEMPOOL_DECLARE_STATS_REFERENCE(name) &name,
+#else
+#define LWIP_MEMPOOL_DECLARE_STATS_INSTANCE(name)
+#define LWIP_MEMPOOL_DECLARE_STATS_REFERENCE(name)
+#endif
+
+void memp_init_pool(const struct memp_desc *desc);
+
+#if MEMP_OVERFLOW_CHECK
+void *memp_malloc_pool_fn(const struct memp_desc* desc, const char* file, const int line);
+#define memp_malloc_pool(d) memp_malloc_pool_fn((d), __FILE__, __LINE__)
+#else
+void *memp_malloc_pool(const struct memp_desc *desc);
+#endif
+void  memp_free_pool(const struct memp_desc* desc, void *mem);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LWIP_HDR_MEMP_PRIV_H */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/priv/memp_std.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/priv/memp_std.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/priv/memp_std.h	(revision 457)
@@ -0,0 +1,153 @@
+/**
+ * @file
+ * lwIP internal memory pools (do not use in application code)
+ * This file is deliberately included multiple times: once with empty
+ * definition of LWIP_MEMPOOL() to handle all includes and multiple times
+ * to build up various lists of mem pools.
+ */
+
+/*
+ * SETUP: Make sure we define everything we will need.
+ *
+ * We have create three types of pools:
+ *   1) MEMPOOL - standard pools
+ *   2) MALLOC_MEMPOOL - to be used by mem_malloc in mem.c
+ *   3) PBUF_MEMPOOL - a mempool of pbuf's, so include space for the pbuf struct
+ *
+ * If the include'r doesn't require any special treatment of each of the types
+ * above, then will declare #2 & #3 to be just standard mempools.
+ */
+#ifndef LWIP_MALLOC_MEMPOOL
+/* This treats "malloc pools" just like any other pool.
+   The pools are a little bigger to provide 'size' as the amount of user data. */
+#define LWIP_MALLOC_MEMPOOL(num, size) LWIP_MEMPOOL(POOL_##size, num, (size + LWIP_MEM_ALIGN_SIZE(sizeof(struct memp_malloc_helper))), "MALLOC_"#size)
+#define LWIP_MALLOC_MEMPOOL_START
+#define LWIP_MALLOC_MEMPOOL_END
+#endif /* LWIP_MALLOC_MEMPOOL */
+
+#ifndef LWIP_PBUF_MEMPOOL
+/* This treats "pbuf pools" just like any other pool.
+ * Allocates buffers for a pbuf struct AND a payload size */
+#define LWIP_PBUF_MEMPOOL(name, num, payload, desc) LWIP_MEMPOOL(name, num, (LWIP_MEM_ALIGN_SIZE(sizeof(struct pbuf)) + LWIP_MEM_ALIGN_SIZE(payload)), desc)
+#endif /* LWIP_PBUF_MEMPOOL */
+
+
+/*
+ * A list of internal pools used by LWIP.
+ *
+ * LWIP_MEMPOOL(pool_name, number_elements, element_size, pool_description)
+ *     creates a pool name MEMP_pool_name. description is used in stats.c
+ */
+#if LWIP_RAW
+LWIP_MEMPOOL(RAW_PCB,        MEMP_NUM_RAW_PCB,         sizeof(struct raw_pcb),        "RAW_PCB")
+#endif /* LWIP_RAW */
+
+#if LWIP_UDP
+LWIP_MEMPOOL(UDP_PCB,        MEMP_NUM_UDP_PCB,         sizeof(struct udp_pcb),        "UDP_PCB")
+#endif /* LWIP_UDP */
+
+#if LWIP_TCP
+LWIP_MEMPOOL(TCP_PCB,        MEMP_NUM_TCP_PCB,         sizeof(struct tcp_pcb),        "TCP_PCB")
+LWIP_MEMPOOL(TCP_PCB_LISTEN, MEMP_NUM_TCP_PCB_LISTEN,  sizeof(struct tcp_pcb_listen), "TCP_PCB_LISTEN")
+LWIP_MEMPOOL(TCP_SEG,        MEMP_NUM_TCP_SEG,         sizeof(struct tcp_seg),        "TCP_SEG")
+#endif /* LWIP_TCP */
+
+#if LWIP_ALTCP && LWIP_TCP
+LWIP_MEMPOOL(ALTCP_PCB,      MEMP_NUM_ALTCP_PCB,       sizeof(struct altcp_pcb),      "ALTCP_PCB")
+#endif /* LWIP_ALTCP && LWIP_TCP */
+
+#if LWIP_IPV4 && IP_REASSEMBLY
+LWIP_MEMPOOL(REASSDATA,      MEMP_NUM_REASSDATA,       sizeof(struct ip_reassdata),   "REASSDATA")
+#endif /* LWIP_IPV4 && IP_REASSEMBLY */
+#if (IP_FRAG && !LWIP_NETIF_TX_SINGLE_PBUF) || (LWIP_IPV6 && LWIP_IPV6_FRAG)
+LWIP_MEMPOOL(FRAG_PBUF,      MEMP_NUM_FRAG_PBUF,       sizeof(struct pbuf_custom_ref),"FRAG_PBUF")
+#endif /* IP_FRAG && !LWIP_NETIF_TX_SINGLE_PBUF || (LWIP_IPV6 && LWIP_IPV6_FRAG) */
+
+#if LWIP_NETCONN || LWIP_SOCKET
+LWIP_MEMPOOL(NETBUF,         MEMP_NUM_NETBUF,          sizeof(struct netbuf),         "NETBUF")
+LWIP_MEMPOOL(NETCONN,        MEMP_NUM_NETCONN,         sizeof(struct netconn),        "NETCONN")
+#endif /* LWIP_NETCONN || LWIP_SOCKET */
+
+#if NO_SYS==0
+LWIP_MEMPOOL(TCPIP_MSG_API,  MEMP_NUM_TCPIP_MSG_API,   sizeof(struct tcpip_msg),      "TCPIP_MSG_API")
+#if LWIP_MPU_COMPATIBLE
+LWIP_MEMPOOL(API_MSG,        MEMP_NUM_API_MSG,         sizeof(struct api_msg),        "API_MSG")
+#if LWIP_DNS
+LWIP_MEMPOOL(DNS_API_MSG,    MEMP_NUM_DNS_API_MSG,     sizeof(struct dns_api_msg),    "DNS_API_MSG")
+#endif
+#if LWIP_SOCKET && !LWIP_TCPIP_CORE_LOCKING
+LWIP_MEMPOOL(SOCKET_SETGETSOCKOPT_DATA, MEMP_NUM_SOCKET_SETGETSOCKOPT_DATA, sizeof(struct lwip_setgetsockopt_data), "SOCKET_SETGETSOCKOPT_DATA")
+#endif
+#if LWIP_SOCKET && (LWIP_SOCKET_SELECT || LWIP_SOCKET_POLL)
+LWIP_MEMPOOL(SELECT_CB,      MEMP_NUM_SELECT_CB,       sizeof(struct lwip_select_cb), "SELECT_CB")
+#endif /* LWIP_SOCKET && (LWIP_SOCKET_SELECT || LWIP_SOCKET_POLL) */
+#if LWIP_NETIF_API
+LWIP_MEMPOOL(NETIFAPI_MSG,   MEMP_NUM_NETIFAPI_MSG,    sizeof(struct netifapi_msg),   "NETIFAPI_MSG")
+#endif
+#endif /* LWIP_MPU_COMPATIBLE */
+#if !LWIP_TCPIP_CORE_LOCKING_INPUT
+LWIP_MEMPOOL(TCPIP_MSG_INPKT,MEMP_NUM_TCPIP_MSG_INPKT, sizeof(struct tcpip_msg),      "TCPIP_MSG_INPKT")
+#endif /* !LWIP_TCPIP_CORE_LOCKING_INPUT */
+#endif /* NO_SYS==0 */
+
+#if LWIP_IPV4 && LWIP_ARP && ARP_QUEUEING
+LWIP_MEMPOOL(ARP_QUEUE,      MEMP_NUM_ARP_QUEUE,       sizeof(struct etharp_q_entry), "ARP_QUEUE")
+#endif /* LWIP_IPV4 && LWIP_ARP && ARP_QUEUEING */
+
+#if LWIP_IGMP
+LWIP_MEMPOOL(IGMP_GROUP,     MEMP_NUM_IGMP_GROUP,      sizeof(struct igmp_group),     "IGMP_GROUP")
+#endif /* LWIP_IGMP */
+
+#if LWIP_TIMERS && !LWIP_TIMERS_CUSTOM
+LWIP_MEMPOOL(SYS_TIMEOUT,    MEMP_NUM_SYS_TIMEOUT,     sizeof(struct sys_timeo),      "SYS_TIMEOUT")
+#endif /* LWIP_TIMERS && !LWIP_TIMERS_CUSTOM */
+
+#if LWIP_DNS && LWIP_SOCKET
+LWIP_MEMPOOL(NETDB,          MEMP_NUM_NETDB,           NETDB_ELEM_SIZE,               "NETDB")
+#endif /* LWIP_DNS && LWIP_SOCKET */
+#if LWIP_DNS && DNS_LOCAL_HOSTLIST && DNS_LOCAL_HOSTLIST_IS_DYNAMIC
+LWIP_MEMPOOL(LOCALHOSTLIST,  MEMP_NUM_LOCALHOSTLIST,   LOCALHOSTLIST_ELEM_SIZE,       "LOCALHOSTLIST")
+#endif /* LWIP_DNS && DNS_LOCAL_HOSTLIST && DNS_LOCAL_HOSTLIST_IS_DYNAMIC */
+
+#if LWIP_IPV6 && LWIP_ND6_QUEUEING
+LWIP_MEMPOOL(ND6_QUEUE,      MEMP_NUM_ND6_QUEUE,       sizeof(struct nd6_q_entry),    "ND6_QUEUE")
+#endif /* LWIP_IPV6 && LWIP_ND6_QUEUEING */
+
+#if LWIP_IPV6 && LWIP_IPV6_REASS
+LWIP_MEMPOOL(IP6_REASSDATA,  MEMP_NUM_REASSDATA,       sizeof(struct ip6_reassdata),  "IP6_REASSDATA")
+#endif /* LWIP_IPV6 && LWIP_IPV6_REASS */
+
+#if LWIP_IPV6 && LWIP_IPV6_MLD
+LWIP_MEMPOOL(MLD6_GROUP,     MEMP_NUM_MLD6_GROUP,      sizeof(struct mld_group),      "MLD6_GROUP")
+#endif /* LWIP_IPV6 && LWIP_IPV6_MLD */
+
+
+/*
+ * A list of pools of pbuf's used by LWIP.
+ *
+ * LWIP_PBUF_MEMPOOL(pool_name, number_elements, pbuf_payload_size, pool_description)
+ *     creates a pool name MEMP_pool_name. description is used in stats.c
+ *     This allocates enough space for the pbuf struct and a payload.
+ *     (Example: pbuf_payload_size=0 allocates only size for the struct)
+ */
+LWIP_MEMPOOL(PBUF,           MEMP_NUM_PBUF,            sizeof(struct pbuf),           "PBUF_REF/ROM")
+LWIP_PBUF_MEMPOOL(PBUF_POOL, PBUF_POOL_SIZE,           PBUF_POOL_BUFSIZE,             "PBUF_POOL")
+
+
+/*
+ * Allow for user-defined pools; this must be explicitly set in lwipopts.h
+ * since the default is to NOT look for lwippools.h
+ */
+#if MEMP_USE_CUSTOM_POOLS
+#include "lwippools.h"
+#endif /* MEMP_USE_CUSTOM_POOLS */
+
+/*
+ * REQUIRED CLEANUP: Clear up so we don't get "multiply defined" error later
+ * (#undef is ignored for something that is not defined)
+ */
+#undef LWIP_MEMPOOL
+#undef LWIP_MALLOC_MEMPOOL
+#undef LWIP_MALLOC_MEMPOOL_START
+#undef LWIP_MALLOC_MEMPOOL_END
+#undef LWIP_PBUF_MEMPOOL
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/priv/nd6_priv.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/priv/nd6_priv.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/priv/nd6_priv.h	(revision 457)
@@ -0,0 +1,142 @@
+/**
+ * @file
+ *
+ * Neighbor discovery and stateless address autoconfiguration for IPv6.
+ * Aims to be compliant with RFC 4861 (Neighbor discovery) and RFC 4862
+ * (Address autoconfiguration).
+ */
+
+/*
+ * Copyright (c) 2010 Inico Technologies Ltd.
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Ivan Delamer <delamer@inicotech.com>
+ *
+ *
+ * Please coordinate changes and requests with Ivan Delamer
+ * <delamer@inicotech.com>
+ */
+
+#ifndef LWIP_HDR_ND6_PRIV_H
+#define LWIP_HDR_ND6_PRIV_H
+
+#include "lwip/opt.h"
+
+#if LWIP_IPV6  /* don't build if not configured for use in lwipopts.h */
+
+#include "lwip/pbuf.h"
+#include "lwip/ip6_addr.h"
+#include "lwip/netif.h"
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if LWIP_ND6_QUEUEING
+/** struct for queueing outgoing packets for unknown address
+  * defined here to be accessed by memp.h
+  */
+struct nd6_q_entry {
+  struct nd6_q_entry *next;
+  struct pbuf *p;
+};
+#endif /* LWIP_ND6_QUEUEING */
+
+/** Struct for tables. */
+struct nd6_neighbor_cache_entry {
+  ip6_addr_t next_hop_address;
+  struct netif *netif;
+  u8_t lladdr[NETIF_MAX_HWADDR_LEN];
+  /*u32_t pmtu;*/
+#if LWIP_ND6_QUEUEING
+  /** Pointer to queue of pending outgoing packets on this entry. */
+  struct nd6_q_entry *q;
+#else /* LWIP_ND6_QUEUEING */
+  /** Pointer to a single pending outgoing packet on this entry. */
+  struct pbuf *q;
+#endif /* LWIP_ND6_QUEUEING */
+  u8_t state;
+  u8_t isrouter;
+  union {
+    u32_t reachable_time; /* in seconds */
+    u32_t delay_time;     /* ticks (ND6_TMR_INTERVAL) */
+    u32_t probes_sent;
+    u32_t stale_time;     /* ticks (ND6_TMR_INTERVAL) */
+  } counter;
+};
+
+struct nd6_destination_cache_entry {
+  ip6_addr_t destination_addr;
+  ip6_addr_t next_hop_addr;
+  u16_t pmtu;
+  u32_t age;
+};
+
+struct nd6_prefix_list_entry {
+  ip6_addr_t prefix;
+  struct netif *netif;
+  u32_t invalidation_timer; /* in seconds */
+};
+
+struct nd6_router_list_entry {
+  struct nd6_neighbor_cache_entry *neighbor_entry;
+  u32_t invalidation_timer; /* in seconds */
+  u8_t flags;
+};
+
+enum nd6_neighbor_cache_entry_state {
+  ND6_NO_ENTRY = 0,
+  ND6_INCOMPLETE,
+  ND6_REACHABLE,
+  ND6_STALE,
+  ND6_DELAY,
+  ND6_PROBE
+};
+
+#define ND6_HOPLIM 255 /* maximum hop limit, required in all ND packets */
+
+#define ND6_2HRS 7200 /* two hours, expressed in number of seconds */
+
+/* Router tables. */
+/* @todo make these static? and entries accessible through API? */
+extern struct nd6_neighbor_cache_entry neighbor_cache[];
+extern struct nd6_destination_cache_entry destination_cache[];
+extern struct nd6_prefix_list_entry prefix_list[];
+extern struct nd6_router_list_entry default_router_list[];
+
+/* Default values, can be updated by a RA message. */
+extern u32_t reachable_time;
+extern u32_t retrans_timer;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LWIP_IPV6 */
+
+#endif /* LWIP_HDR_ND6_PRIV_H */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/priv/raw_priv.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/priv/raw_priv.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/priv/raw_priv.h	(revision 457)
@@ -0,0 +1,69 @@
+/**
+ * @file
+ * raw API internal implementations (do not use in application code)
+ */
+
+/*
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Adam Dunkels <adam@sics.se>
+ *
+ */
+#ifndef LWIP_HDR_RAW_PRIV_H
+#define LWIP_HDR_RAW_PRIV_H
+
+#include "lwip/opt.h"
+
+#if LWIP_RAW /* don't build if not configured for use in lwipopts.h */
+
+#include "lwip/raw.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** return codes for raw_input */
+typedef enum raw_input_state
+{
+  RAW_INPUT_NONE = 0, /* pbuf did not match any pcbs */
+  RAW_INPUT_EATEN,    /* pbuf handed off and delivered to pcb */
+  RAW_INPUT_DELIVERED /* pbuf only delivered to pcb (pbuf can still be referenced) */
+} raw_input_state_t;
+
+/* The following functions are the lower layer interface to RAW. */
+raw_input_state_t raw_input(struct pbuf *p, struct netif *inp);
+
+void raw_netif_ip_addr_changed(const ip_addr_t* old_addr, const ip_addr_t* new_addr);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LWIP_RAW */
+
+#endif /* LWIP_HDR_RAW_PRIV_H */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/priv/sockets_priv.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/priv/sockets_priv.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/priv/sockets_priv.h	(revision 457)
@@ -0,0 +1,175 @@
+/**
+ * @file
+ * Sockets API internal implementations (do not use in application code)
+ */
+
+/*
+ * Copyright (c) 2017 Joel Cunningham, Garmin International, Inc. <joel.cunningham@garmin.com>
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Joel Cunningham <joel.cunningham@me.com>
+ *
+ */
+#ifndef LWIP_HDR_SOCKETS_PRIV_H
+#define LWIP_HDR_SOCKETS_PRIV_H
+
+#include "lwip/opt.h"
+
+#if LWIP_SOCKET /* don't build if not configured for use in lwipopts.h */
+
+#include "lwip/err.h"
+#include "lwip/sockets.h"
+#include "lwip/sys.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define NUM_SOCKETS MEMP_NUM_NETCONN
+
+/** This is overridable for the rare case where more than 255 threads
+ * select on the same socket...
+ */
+#ifndef SELWAIT_T
+#define SELWAIT_T u8_t
+#endif
+
+union lwip_sock_lastdata {
+  struct netbuf *netbuf;
+  struct pbuf *pbuf;
+};
+
+/** Contains all internal pointers and states used for a socket */
+struct lwip_sock {
+  /** sockets currently are built on netconns, each socket has one netconn */
+  struct netconn *conn;
+  /** data that was left from the previous read */
+  union lwip_sock_lastdata lastdata;
+#if LWIP_SOCKET_SELECT || LWIP_SOCKET_POLL
+  /** number of times data was received, set by event_callback(),
+      tested by the receive and select functions */
+  s16_t rcvevent;
+  /** number of times data was ACKed (free send buffer), set by event_callback(),
+      tested by select */
+  u16_t sendevent;
+  /** error happened for this socket, set by event_callback(), tested by select */
+  u16_t errevent;
+  /** counter of how many threads are waiting for this socket using select */
+  SELWAIT_T select_waiting;
+#endif /* LWIP_SOCKET_SELECT || LWIP_SOCKET_POLL */
+#if LWIP_NETCONN_FULLDUPLEX
+  /* counter of how many threads are using a struct lwip_sock (not the 'int') */
+  u8_t fd_used;
+  /* status of pending close/delete actions */
+  u8_t fd_free_pending;
+#define LWIP_SOCK_FD_FREE_TCP  1
+#define LWIP_SOCK_FD_FREE_FREE 2
+#endif
+};
+
+#ifndef set_errno
+#define set_errno(err) do { if (err) { errno = (err); } } while(0)
+#endif
+
+#if !LWIP_TCPIP_CORE_LOCKING
+/** Maximum optlen used by setsockopt/getsockopt */
+#define LWIP_SETGETSOCKOPT_MAXOPTLEN LWIP_MAX(16, sizeof(struct ifreq))
+
+/** This struct is used to pass data to the set/getsockopt_internal
+ * functions running in tcpip_thread context (only a void* is allowed) */
+struct lwip_setgetsockopt_data {
+  /** socket index for which to change options */
+  int s;
+  /** level of the option to process */
+  int level;
+  /** name of the option to process */
+  int optname;
+  /** set: value to set the option to
+    * get: value of the option is stored here */
+#if LWIP_MPU_COMPATIBLE
+  u8_t optval[LWIP_SETGETSOCKOPT_MAXOPTLEN];
+#else
+  union {
+    void *p;
+    const void *pc;
+  } optval;
+#endif
+  /** size of *optval */
+  socklen_t optlen;
+  /** if an error occurs, it is temporarily stored here */
+  int err;
+  /** semaphore to wake up the calling task */
+  void* completed_sem;
+};
+#endif /* !LWIP_TCPIP_CORE_LOCKING */
+
+#ifdef __cplusplus
+}
+#endif
+
+struct lwip_sock* lwip_socket_dbg_get_socket(int fd);
+
+#if LWIP_SOCKET_SELECT || LWIP_SOCKET_POLL
+
+#if LWIP_NETCONN_SEM_PER_THREAD
+#define SELECT_SEM_T        sys_sem_t*
+#define SELECT_SEM_PTR(sem) (sem)
+#else /* LWIP_NETCONN_SEM_PER_THREAD */
+#define SELECT_SEM_T        sys_sem_t
+#define SELECT_SEM_PTR(sem) (&(sem))
+#endif /* LWIP_NETCONN_SEM_PER_THREAD */
+
+/** Description for a task waiting in select */
+struct lwip_select_cb {
+  /** Pointer to the next waiting task */
+  struct lwip_select_cb *next;
+  /** Pointer to the previous waiting task */
+  struct lwip_select_cb *prev;
+#if LWIP_SOCKET_SELECT
+  /** readset passed to select */
+  fd_set *readset;
+  /** writeset passed to select */
+  fd_set *writeset;
+  /** unimplemented: exceptset passed to select */
+  fd_set *exceptset;
+#endif /* LWIP_SOCKET_SELECT */
+#if LWIP_SOCKET_POLL
+  /** fds passed to poll; NULL if select */
+  struct pollfd *poll_fds;
+  /** nfds passed to poll; 0 if select */
+  nfds_t poll_nfds;
+#endif /* LWIP_SOCKET_POLL */
+  /** don't signal the same semaphore twice: set to 1 when signalled */
+  int sem_signalled;
+  /** semaphore to wake up a task waiting for select */
+  SELECT_SEM_T sem;
+};
+#endif /* LWIP_SOCKET_SELECT || LWIP_SOCKET_POLL */
+
+#endif /* LWIP_SOCKET */
+
+#endif /* LWIP_HDR_SOCKETS_PRIV_H */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/priv/tcp_priv.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/priv/tcp_priv.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/priv/tcp_priv.h	(revision 457)
@@ -0,0 +1,523 @@
+/**
+ * @file
+ * TCP internal implementations (do not use in application code)
+ */
+
+/*
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Adam Dunkels <adam@sics.se>
+ *
+ */
+#ifndef LWIP_HDR_TCP_PRIV_H
+#define LWIP_HDR_TCP_PRIV_H
+
+#include "lwip/opt.h"
+
+#if LWIP_TCP /* don't build if not configured for use in lwipopts.h */
+
+#include "lwip/tcp.h"
+#include "lwip/mem.h"
+#include "lwip/pbuf.h"
+#include "lwip/ip.h"
+#include "lwip/icmp.h"
+#include "lwip/err.h"
+#include "lwip/ip6.h"
+#include "lwip/ip6_addr.h"
+#include "lwip/prot/tcp.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Functions for interfacing with TCP: */
+
+/* Lower layer interface to TCP: */
+void             tcp_init    (void);  /* Initialize this module. */
+void             tcp_tmr     (void);  /* Must be called every
+                                         TCP_TMR_INTERVAL
+                                         ms. (Typically 250 ms). */
+/* It is also possible to call these two functions at the right
+   intervals (instead of calling tcp_tmr()). */
+void             tcp_slowtmr (void);
+void             tcp_fasttmr (void);
+
+/* Call this from a netif driver (watch out for threading issues!) that has
+   returned a memory error on transmit and now has free buffers to send more.
+   This iterates all active pcbs that had an error and tries to call
+   tcp_output, so use this with care as it might slow down the system. */
+void             tcp_txnow   (void);
+
+/* Only used by IP to pass a TCP segment to TCP: */
+void             tcp_input   (struct pbuf *p, struct netif *inp);
+/* Used within the TCP code only: */
+struct tcp_pcb * tcp_alloc   (u8_t prio);
+void             tcp_free    (struct tcp_pcb *pcb);
+void             tcp_abandon (struct tcp_pcb *pcb, int reset);
+err_t            tcp_send_empty_ack(struct tcp_pcb *pcb);
+err_t            tcp_rexmit  (struct tcp_pcb *pcb);
+err_t            tcp_rexmit_rto_prepare(struct tcp_pcb *pcb);
+void             tcp_rexmit_rto_commit(struct tcp_pcb *pcb);
+void             tcp_rexmit_rto  (struct tcp_pcb *pcb);
+void             tcp_rexmit_fast (struct tcp_pcb *pcb);
+u32_t            tcp_update_rcv_ann_wnd(struct tcp_pcb *pcb);
+err_t            tcp_process_refused_data(struct tcp_pcb *pcb);
+
+/**
+ * This is the Nagle algorithm: try to combine user data to send as few TCP
+ * segments as possible. Only send if
+ * - no previously transmitted data on the connection remains unacknowledged or
+ * - the TF_NODELAY flag is set (nagle algorithm turned off for this pcb) or
+ * - the only unsent segment is at least pcb->mss bytes long (or there is more
+ *   than one unsent segment - with lwIP, this can happen although unsent->len < mss)
+ * - or if we are in fast-retransmit (TF_INFR)
+ */
+#define tcp_do_output_nagle(tpcb) ((((tpcb)->unacked == NULL) || \
+                            ((tpcb)->flags & (TF_NODELAY | TF_INFR)) || \
+                            (((tpcb)->unsent != NULL) && (((tpcb)->unsent->next != NULL) || \
+                              ((tpcb)->unsent->len >= (tpcb)->mss))) || \
+                            ((tcp_sndbuf(tpcb) == 0) || (tcp_sndqueuelen(tpcb) >= TCP_SND_QUEUELEN)) \
+                            ) ? 1 : 0)
+#define tcp_output_nagle(tpcb) (tcp_do_output_nagle(tpcb) ? tcp_output(tpcb) : ERR_OK)
+
+
+#define TCP_SEQ_LT(a,b)     ((s32_t)((u32_t)(a) - (u32_t)(b)) < 0)
+#define TCP_SEQ_LEQ(a,b)    ((s32_t)((u32_t)(a) - (u32_t)(b)) <= 0)
+#define TCP_SEQ_GT(a,b)     ((s32_t)((u32_t)(a) - (u32_t)(b)) > 0)
+#define TCP_SEQ_GEQ(a,b)    ((s32_t)((u32_t)(a) - (u32_t)(b)) >= 0)
+/* is b<=a<=c? */
+#if 0 /* see bug #10548 */
+#define TCP_SEQ_BETWEEN(a,b,c) ((c)-(b) >= (a)-(b))
+#endif
+#define TCP_SEQ_BETWEEN(a,b,c) (TCP_SEQ_GEQ(a,b) && TCP_SEQ_LEQ(a,c))
+
+#ifndef TCP_TMR_INTERVAL
+#define TCP_TMR_INTERVAL       250  /* The TCP timer interval in milliseconds. */
+#endif /* TCP_TMR_INTERVAL */
+
+#ifndef TCP_FAST_INTERVAL
+#define TCP_FAST_INTERVAL      TCP_TMR_INTERVAL /* the fine grained timeout in milliseconds */
+#endif /* TCP_FAST_INTERVAL */
+
+#ifndef TCP_SLOW_INTERVAL
+#define TCP_SLOW_INTERVAL      (2*TCP_TMR_INTERVAL)  /* the coarse grained timeout in milliseconds */
+#endif /* TCP_SLOW_INTERVAL */
+
+#define TCP_FIN_WAIT_TIMEOUT 20000 /* milliseconds */
+#define TCP_SYN_RCVD_TIMEOUT 20000 /* milliseconds */
+
+#define TCP_OOSEQ_TIMEOUT        6U /* x RTO */
+
+#ifndef TCP_MSL
+#define TCP_MSL 60000UL /* The maximum segment lifetime in milliseconds */
+#endif
+
+/* Keepalive values, compliant with RFC 1122. Don't change this unless you know what you're doing */
+#ifndef  TCP_KEEPIDLE_DEFAULT
+#define  TCP_KEEPIDLE_DEFAULT     7200000UL /* Default KEEPALIVE timer in milliseconds */
+#endif
+
+#ifndef  TCP_KEEPINTVL_DEFAULT
+#define  TCP_KEEPINTVL_DEFAULT    75000UL   /* Default Time between KEEPALIVE probes in milliseconds */
+#endif
+
+#ifndef  TCP_KEEPCNT_DEFAULT
+#define  TCP_KEEPCNT_DEFAULT      9U        /* Default Counter for KEEPALIVE probes */
+#endif
+
+#define  TCP_MAXIDLE              TCP_KEEPCNT_DEFAULT * TCP_KEEPINTVL_DEFAULT  /* Maximum KEEPALIVE probe time */
+
+#define TCP_TCPLEN(seg) ((seg)->len + (((TCPH_FLAGS((seg)->tcphdr) & (TCP_FIN | TCP_SYN)) != 0) ? 1U : 0U))
+
+/** Flags used on input processing, not on pcb->flags
+*/
+#define TF_RESET     (u8_t)0x08U   /* Connection was reset. */
+#define TF_CLOSED    (u8_t)0x10U   /* Connection was successfully closed. */
+#define TF_GOT_FIN   (u8_t)0x20U   /* Connection was closed by the remote end. */
+
+
+#if LWIP_EVENT_API
+
+#define TCP_EVENT_ACCEPT(lpcb,pcb,arg,err,ret) ret = lwip_tcp_event(arg, (pcb),\
+                LWIP_EVENT_ACCEPT, NULL, 0, err)
+#define TCP_EVENT_SENT(pcb,space,ret) ret = lwip_tcp_event((pcb)->callback_arg, (pcb),\
+                   LWIP_EVENT_SENT, NULL, space, ERR_OK)
+#define TCP_EVENT_RECV(pcb,p,err,ret) ret = lwip_tcp_event((pcb)->callback_arg, (pcb),\
+                LWIP_EVENT_RECV, (p), 0, (err))
+#define TCP_EVENT_CLOSED(pcb,ret) ret = lwip_tcp_event((pcb)->callback_arg, (pcb),\
+                LWIP_EVENT_RECV, NULL, 0, ERR_OK)
+#define TCP_EVENT_CONNECTED(pcb,err,ret) ret = lwip_tcp_event((pcb)->callback_arg, (pcb),\
+                LWIP_EVENT_CONNECTED, NULL, 0, (err))
+#define TCP_EVENT_POLL(pcb,ret)       do { if ((pcb)->state != SYN_RCVD) {                          \
+                ret = lwip_tcp_event((pcb)->callback_arg, (pcb), LWIP_EVENT_POLL, NULL, 0, ERR_OK); \
+                } else {                                                                            \
+                ret = ERR_ARG; } } while(0)
+/* For event API, last state SYN_RCVD must be excluded here: the application
+   has not seen this pcb, yet! */
+#define TCP_EVENT_ERR(last_state,errf,arg,err)  do { if (last_state != SYN_RCVD) {                \
+                lwip_tcp_event((arg), NULL, LWIP_EVENT_ERR, NULL, 0, (err)); } } while(0)
+
+#else /* LWIP_EVENT_API */
+
+#define TCP_EVENT_ACCEPT(lpcb,pcb,arg,err,ret)                 \
+  do {                                                         \
+    if((lpcb)->accept != NULL)                                 \
+      (ret) = (lpcb)->accept((arg),(pcb),(err));               \
+    else (ret) = ERR_ARG;                                      \
+  } while (0)
+
+#define TCP_EVENT_SENT(pcb,space,ret)                          \
+  do {                                                         \
+    if((pcb)->sent != NULL)                                    \
+      (ret) = (pcb)->sent((pcb)->callback_arg,(pcb),(space));  \
+    else (ret) = ERR_OK;                                       \
+  } while (0)
+
+#define TCP_EVENT_RECV(pcb,p,err,ret)                          \
+  do {                                                         \
+    if((pcb)->recv != NULL) {                                  \
+      (ret) = (pcb)->recv((pcb)->callback_arg,(pcb),(p),(err));\
+    } else {                                                   \
+      (ret) = tcp_recv_null(NULL, (pcb), (p), (err));          \
+    }                                                          \
+  } while (0)
+
+#define TCP_EVENT_CLOSED(pcb,ret)                                \
+  do {                                                           \
+    if(((pcb)->recv != NULL)) {                                  \
+      (ret) = (pcb)->recv((pcb)->callback_arg,(pcb),NULL,ERR_OK);\
+    } else {                                                     \
+      (ret) = ERR_OK;                                            \
+    }                                                            \
+  } while (0)
+
+#define TCP_EVENT_CONNECTED(pcb,err,ret)                         \
+  do {                                                           \
+    if((pcb)->connected != NULL)                                 \
+      (ret) = (pcb)->connected((pcb)->callback_arg,(pcb),(err)); \
+    else (ret) = ERR_OK;                                         \
+  } while (0)
+
+#define TCP_EVENT_POLL(pcb,ret)                                \
+  do {                                                         \
+    if((pcb)->poll != NULL)                                    \
+      (ret) = (pcb)->poll((pcb)->callback_arg,(pcb));          \
+    else (ret) = ERR_OK;                                       \
+  } while (0)
+
+#define TCP_EVENT_ERR(last_state,errf,arg,err)                 \
+  do {                                                         \
+    LWIP_UNUSED_ARG(last_state);                               \
+    if((errf) != NULL)                                         \
+      (errf)((arg),(err));                                     \
+  } while (0)
+
+#endif /* LWIP_EVENT_API */
+
+/** Enabled extra-check for TCP_OVERSIZE if LWIP_DEBUG is enabled */
+#if TCP_OVERSIZE && defined(LWIP_DEBUG)
+#define TCP_OVERSIZE_DBGCHECK 1
+#else
+#define TCP_OVERSIZE_DBGCHECK 0
+#endif
+
+/** Don't generate checksum on copy if CHECKSUM_GEN_TCP is disabled */
+#define TCP_CHECKSUM_ON_COPY  (LWIP_CHECKSUM_ON_COPY && CHECKSUM_GEN_TCP)
+
+/* This structure represents a TCP segment on the unsent, unacked and ooseq queues */
+struct tcp_seg {
+  struct tcp_seg *next;    /* used when putting segments on a queue */
+  struct pbuf *p;          /* buffer containing data + TCP header */
+  u16_t len;               /* the TCP length of this segment */
+#if TCP_OVERSIZE_DBGCHECK
+  u16_t oversize_left;     /* Extra bytes available at the end of the last
+                              pbuf in unsent (used for asserting vs.
+                              tcp_pcb.unsent_oversize only) */
+#endif /* TCP_OVERSIZE_DBGCHECK */
+#if TCP_CHECKSUM_ON_COPY
+  u16_t chksum;
+  u8_t  chksum_swapped;
+#endif /* TCP_CHECKSUM_ON_COPY */
+  u8_t  flags;
+#define TF_SEG_OPTS_MSS         (u8_t)0x01U /* Include MSS option (only used in SYN segments) */
+#define TF_SEG_OPTS_TS          (u8_t)0x02U /* Include timestamp option. */
+#define TF_SEG_DATA_CHECKSUMMED (u8_t)0x04U /* ALL data (not the header) is
+                                               checksummed into 'chksum' */
+#define TF_SEG_OPTS_WND_SCALE   (u8_t)0x08U /* Include WND SCALE option (only used in SYN segments) */
+#define TF_SEG_OPTS_SACK_PERM   (u8_t)0x10U /* Include SACK Permitted option (only used in SYN segments) */
+  struct tcp_hdr *tcphdr;  /* the TCP header */
+};
+
+#define LWIP_TCP_OPT_EOL        0
+#define LWIP_TCP_OPT_NOP        1
+#define LWIP_TCP_OPT_MSS        2
+#define LWIP_TCP_OPT_WS         3
+#define LWIP_TCP_OPT_SACK_PERM  4
+#define LWIP_TCP_OPT_TS         8
+
+#define LWIP_TCP_OPT_LEN_MSS    4
+#if LWIP_TCP_TIMESTAMPS
+#define LWIP_TCP_OPT_LEN_TS     10
+#define LWIP_TCP_OPT_LEN_TS_OUT 12 /* aligned for output (includes NOP padding) */
+#else
+#define LWIP_TCP_OPT_LEN_TS_OUT 0
+#endif
+#if LWIP_WND_SCALE
+#define LWIP_TCP_OPT_LEN_WS     3
+#define LWIP_TCP_OPT_LEN_WS_OUT 4 /* aligned for output (includes NOP padding) */
+#else
+#define LWIP_TCP_OPT_LEN_WS_OUT 0
+#endif
+
+#if LWIP_TCP_SACK_OUT
+#define LWIP_TCP_OPT_LEN_SACK_PERM     2
+#define LWIP_TCP_OPT_LEN_SACK_PERM_OUT 4 /* aligned for output (includes NOP padding) */
+#else
+#define LWIP_TCP_OPT_LEN_SACK_PERM_OUT 0
+#endif
+
+#define LWIP_TCP_OPT_LENGTH(flags) \
+  ((flags) & TF_SEG_OPTS_MSS       ? LWIP_TCP_OPT_LEN_MSS           : 0) + \
+  ((flags) & TF_SEG_OPTS_TS        ? LWIP_TCP_OPT_LEN_TS_OUT        : 0) + \
+  ((flags) & TF_SEG_OPTS_WND_SCALE ? LWIP_TCP_OPT_LEN_WS_OUT        : 0) + \
+  ((flags) & TF_SEG_OPTS_SACK_PERM ? LWIP_TCP_OPT_LEN_SACK_PERM_OUT : 0)
+
+/** This returns a TCP header option for MSS in an u32_t */
+#define TCP_BUILD_MSS_OPTION(mss) lwip_htonl(0x02040000 | ((mss) & 0xFFFF))
+
+#if LWIP_WND_SCALE
+#define TCPWNDSIZE_F       U32_F
+#define TCPWND_MAX         0xFFFFFFFFU
+#define TCPWND_CHECK16(x)  LWIP_ASSERT("window size > 0xFFFF", (x) <= 0xFFFF)
+#define TCPWND_MIN16(x)    ((u16_t)LWIP_MIN((x), 0xFFFF))
+#else /* LWIP_WND_SCALE */
+#define TCPWNDSIZE_F       U16_F
+#define TCPWND_MAX         0xFFFFU
+#define TCPWND_CHECK16(x)
+#define TCPWND_MIN16(x)    x
+#endif /* LWIP_WND_SCALE */
+
+/* Global variables: */
+extern struct tcp_pcb *tcp_input_pcb;
+extern u32_t tcp_ticks;
+extern u8_t tcp_active_pcbs_changed;
+
+/* The TCP PCB lists. */
+union tcp_listen_pcbs_t { /* List of all TCP PCBs in LISTEN state. */
+  struct tcp_pcb_listen *listen_pcbs;
+  struct tcp_pcb *pcbs;
+};
+extern struct tcp_pcb *tcp_bound_pcbs;
+extern union tcp_listen_pcbs_t tcp_listen_pcbs;
+extern struct tcp_pcb *tcp_active_pcbs;  /* List of all TCP PCBs that are in a
+              state in which they accept or send
+              data. */
+extern struct tcp_pcb *tcp_tw_pcbs;      /* List of all TCP PCBs in TIME-WAIT. */
+
+#define NUM_TCP_PCB_LISTS_NO_TIME_WAIT  3
+#define NUM_TCP_PCB_LISTS               4
+extern struct tcp_pcb ** const tcp_pcb_lists[NUM_TCP_PCB_LISTS];
+
+/* Axioms about the above lists:
+   1) Every TCP PCB that is not CLOSED is in one of the lists.
+   2) A PCB is only in one of the lists.
+   3) All PCBs in the tcp_listen_pcbs list is in LISTEN state.
+   4) All PCBs in the tcp_tw_pcbs list is in TIME-WAIT state.
+*/
+/* Define two macros, TCP_REG and TCP_RMV that registers a TCP PCB
+   with a PCB list or removes a PCB from a list, respectively. */
+#ifndef TCP_DEBUG_PCB_LISTS
+#define TCP_DEBUG_PCB_LISTS 0
+#endif
+#if TCP_DEBUG_PCB_LISTS
+#define TCP_REG(pcbs, npcb) do {\
+                            struct tcp_pcb *tcp_tmp_pcb; \
+                            LWIP_DEBUGF(TCP_DEBUG, ("TCP_REG %p local port %"U16_F"\n", (void *)(npcb), (npcb)->local_port)); \
+                            for (tcp_tmp_pcb = *(pcbs); \
+          tcp_tmp_pcb != NULL; \
+        tcp_tmp_pcb = tcp_tmp_pcb->next) { \
+                                LWIP_ASSERT("TCP_REG: already registered\n", tcp_tmp_pcb != (npcb)); \
+                            } \
+                            LWIP_ASSERT("TCP_REG: pcb->state != CLOSED", ((pcbs) == &tcp_bound_pcbs) || ((npcb)->state != CLOSED)); \
+                            (npcb)->next = *(pcbs); \
+                            LWIP_ASSERT("TCP_REG: npcb->next != npcb", (npcb)->next != (npcb)); \
+                            *(pcbs) = (npcb); \
+                            LWIP_ASSERT("TCP_REG: tcp_pcbs sane", tcp_pcbs_sane()); \
+              tcp_timer_needed(); \
+                            } while(0)
+#define TCP_RMV(pcbs, npcb) do { \
+                            struct tcp_pcb *tcp_tmp_pcb; \
+                            LWIP_ASSERT("TCP_RMV: pcbs != NULL", *(pcbs) != NULL); \
+                            LWIP_DEBUGF(TCP_DEBUG, ("TCP_RMV: removing %p from %p\n", (void *)(npcb), (void *)(*(pcbs)))); \
+                            if(*(pcbs) == (npcb)) { \
+                               *(pcbs) = (*pcbs)->next; \
+                            } else for (tcp_tmp_pcb = *(pcbs); tcp_tmp_pcb != NULL; tcp_tmp_pcb = tcp_tmp_pcb->next) { \
+                               if(tcp_tmp_pcb->next == (npcb)) { \
+                                  tcp_tmp_pcb->next = (npcb)->next; \
+                                  break; \
+                               } \
+                            } \
+                            (npcb)->next = NULL; \
+                            LWIP_ASSERT("TCP_RMV: tcp_pcbs sane", tcp_pcbs_sane()); \
+                            LWIP_DEBUGF(TCP_DEBUG, ("TCP_RMV: removed %p from %p\n", (void *)(npcb), (void *)(*(pcbs)))); \
+                            } while(0)
+
+#else /* LWIP_DEBUG */
+
+#define TCP_REG(pcbs, npcb)                        \
+  do {                                             \
+    (npcb)->next = *pcbs;                          \
+    *(pcbs) = (npcb);                              \
+    tcp_timer_needed();                            \
+  } while (0)
+
+#define TCP_RMV(pcbs, npcb)                        \
+  do {                                             \
+    if(*(pcbs) == (npcb)) {                        \
+      (*(pcbs)) = (*pcbs)->next;                   \
+    }                                              \
+    else {                                         \
+      struct tcp_pcb *tcp_tmp_pcb;                 \
+      for (tcp_tmp_pcb = *pcbs;                    \
+          tcp_tmp_pcb != NULL;                     \
+          tcp_tmp_pcb = tcp_tmp_pcb->next) {       \
+        if(tcp_tmp_pcb->next == (npcb)) {          \
+          tcp_tmp_pcb->next = (npcb)->next;        \
+          break;                                   \
+        }                                          \
+      }                                            \
+    }                                              \
+    (npcb)->next = NULL;                           \
+  } while(0)
+
+#endif /* LWIP_DEBUG */
+
+#define TCP_REG_ACTIVE(npcb)                       \
+  do {                                             \
+    TCP_REG(&tcp_active_pcbs, npcb);               \
+    tcp_active_pcbs_changed = 1;                   \
+  } while (0)
+
+#define TCP_RMV_ACTIVE(npcb)                       \
+  do {                                             \
+    TCP_RMV(&tcp_active_pcbs, npcb);               \
+    tcp_active_pcbs_changed = 1;                   \
+  } while (0)
+
+#define TCP_PCB_REMOVE_ACTIVE(pcb)                 \
+  do {                                             \
+    tcp_pcb_remove(&tcp_active_pcbs, pcb);         \
+    tcp_active_pcbs_changed = 1;                   \
+  } while (0)
+
+
+/* Internal functions: */
+struct tcp_pcb *tcp_pcb_copy(struct tcp_pcb *pcb);
+void tcp_pcb_purge(struct tcp_pcb *pcb);
+void tcp_pcb_remove(struct tcp_pcb **pcblist, struct tcp_pcb *pcb);
+
+void tcp_segs_free(struct tcp_seg *seg);
+void tcp_seg_free(struct tcp_seg *seg);
+struct tcp_seg *tcp_seg_copy(struct tcp_seg *seg);
+
+#define tcp_ack(pcb)                               \
+  do {                                             \
+    if((pcb)->flags & TF_ACK_DELAY) {              \
+      tcp_clear_flags(pcb, TF_ACK_DELAY);          \
+      tcp_ack_now(pcb);                            \
+    }                                              \
+    else {                                         \
+      tcp_set_flags(pcb, TF_ACK_DELAY);            \
+    }                                              \
+  } while (0)
+
+#define tcp_ack_now(pcb)                           \
+  tcp_set_flags(pcb, TF_ACK_NOW)
+
+err_t tcp_send_fin(struct tcp_pcb *pcb);
+err_t tcp_enqueue_flags(struct tcp_pcb *pcb, u8_t flags);
+
+void tcp_rexmit_seg(struct tcp_pcb *pcb, struct tcp_seg *seg);
+
+void tcp_rst(const struct tcp_pcb* pcb, u32_t seqno, u32_t ackno,
+       const ip_addr_t *local_ip, const ip_addr_t *remote_ip,
+       u16_t local_port, u16_t remote_port);
+
+u32_t tcp_next_iss(struct tcp_pcb *pcb);
+
+err_t tcp_keepalive(struct tcp_pcb *pcb);
+err_t tcp_split_unsent_seg(struct tcp_pcb *pcb, u16_t split);
+err_t tcp_zero_window_probe(struct tcp_pcb *pcb);
+void  tcp_trigger_input_pcb_close(void);
+
+#if TCP_CALCULATE_EFF_SEND_MSS
+u16_t tcp_eff_send_mss_netif(u16_t sendmss, struct netif *outif,
+                             const ip_addr_t *dest);
+#define tcp_eff_send_mss(sendmss, src, dest) \
+    tcp_eff_send_mss_netif(sendmss, ip_route(src, dest), dest)
+#endif /* TCP_CALCULATE_EFF_SEND_MSS */
+
+#if LWIP_CALLBACK_API
+err_t tcp_recv_null(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err);
+#endif /* LWIP_CALLBACK_API */
+
+#if TCP_DEBUG || TCP_INPUT_DEBUG || TCP_OUTPUT_DEBUG
+void tcp_debug_print(struct tcp_hdr *tcphdr);
+void tcp_debug_print_flags(u8_t flags);
+void tcp_debug_print_state(enum tcp_state s);
+void tcp_debug_print_pcbs(void);
+s16_t tcp_pcbs_sane(void);
+#else
+#  define tcp_debug_print(tcphdr)
+#  define tcp_debug_print_flags(flags)
+#  define tcp_debug_print_state(s)
+#  define tcp_debug_print_pcbs()
+#  define tcp_pcbs_sane() 1
+#endif /* TCP_DEBUG */
+
+/** External function (implemented in timers.c), called when TCP detects
+ * that a timer is needed (i.e. active- or time-wait-pcb found). */
+void tcp_timer_needed(void);
+
+void tcp_netif_ip_addr_changed(const ip_addr_t* old_addr, const ip_addr_t* new_addr);
+
+#if TCP_QUEUE_OOSEQ
+void tcp_free_ooseq(struct tcp_pcb *pcb);
+#endif
+
+#if LWIP_TCP_PCB_NUM_EXT_ARGS
+err_t tcp_ext_arg_invoke_callbacks_passive_open(struct tcp_pcb_listen *lpcb, struct tcp_pcb *cpcb);
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LWIP_TCP */
+
+#endif /* LWIP_HDR_TCP_PRIV_H */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/priv/tcpip_priv.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/priv/tcpip_priv.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/priv/tcpip_priv.h	(revision 457)
@@ -0,0 +1,170 @@
+/**
+ * @file
+ * TCPIP API internal implementations (do not use in application code)
+ */
+
+/*
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Adam Dunkels <adam@sics.se>
+ *
+ */
+#ifndef LWIP_HDR_TCPIP_PRIV_H
+#define LWIP_HDR_TCPIP_PRIV_H
+
+#include "lwip/opt.h"
+
+#if !NO_SYS /* don't build if not configured for use in lwipopts.h */
+
+#include "lwip/tcpip.h"
+#include "lwip/sys.h"
+#include "lwip/timeouts.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct pbuf;
+struct netif;
+
+#if LWIP_MPU_COMPATIBLE
+#define API_VAR_REF(name)               (*(name))
+#define API_VAR_DECLARE(type, name)     type * name
+#define API_VAR_ALLOC_EXT(type, pool, name, errorblock) do { \
+                                          name = (type *)memp_malloc(pool); \
+                                          if (name == NULL) { \
+                                            errorblock; \
+                                          } \
+                                        } while(0)
+#define API_VAR_ALLOC(type, pool, name, errorval) API_VAR_ALLOC_EXT(type, pool, name, return errorval)
+#define API_VAR_ALLOC_POOL(type, pool, name, errorval) do { \
+                                          name = (type *)LWIP_MEMPOOL_ALLOC(pool); \
+                                          if (name == NULL) { \
+                                            return errorval; \
+                                          } \
+                                        } while(0)
+#define API_VAR_FREE(pool, name)        memp_free(pool, name)
+#define API_VAR_FREE_POOL(pool, name)   LWIP_MEMPOOL_FREE(pool, name)
+#define API_EXPR_REF(expr)              (&(expr))
+#if LWIP_NETCONN_SEM_PER_THREAD
+#define API_EXPR_REF_SEM(expr)          (expr)
+#else
+#define API_EXPR_REF_SEM(expr)          API_EXPR_REF(expr)
+#endif
+#define API_EXPR_DEREF(expr)            expr
+#define API_MSG_M_DEF(m)                m
+#define API_MSG_M_DEF_C(t, m)           t m
+#else /* LWIP_MPU_COMPATIBLE */
+#define API_VAR_REF(name)               name
+#define API_VAR_DECLARE(type, name)     type name
+#define API_VAR_ALLOC_EXT(type, pool, name, errorblock)
+#define API_VAR_ALLOC(type, pool, name, errorval)
+#define API_VAR_ALLOC_POOL(type, pool, name, errorval)
+#define API_VAR_FREE(pool, name)
+#define API_VAR_FREE_POOL(pool, name)
+#define API_EXPR_REF(expr)              expr
+#define API_EXPR_REF_SEM(expr)          API_EXPR_REF(expr)
+#define API_EXPR_DEREF(expr)            (*(expr))
+#define API_MSG_M_DEF(m)                *m
+#define API_MSG_M_DEF_C(t, m)           const t * m
+#endif /* LWIP_MPU_COMPATIBLE */
+
+err_t tcpip_send_msg_wait_sem(tcpip_callback_fn fn, void *apimsg, sys_sem_t* sem);
+
+struct tcpip_api_call_data
+{
+#if !LWIP_TCPIP_CORE_LOCKING
+  err_t err;
+#if !LWIP_NETCONN_SEM_PER_THREAD
+  sys_sem_t sem;
+#endif /* LWIP_NETCONN_SEM_PER_THREAD */
+#else /* !LWIP_TCPIP_CORE_LOCKING */
+  u8_t dummy; /* avoid empty struct :-( */
+#endif /* !LWIP_TCPIP_CORE_LOCKING */
+};
+typedef err_t (*tcpip_api_call_fn)(struct tcpip_api_call_data* call);
+err_t tcpip_api_call(tcpip_api_call_fn fn, struct tcpip_api_call_data *call);
+
+enum tcpip_msg_type {
+#if !LWIP_TCPIP_CORE_LOCKING
+  TCPIP_MSG_API,
+  TCPIP_MSG_API_CALL,
+#endif /* !LWIP_TCPIP_CORE_LOCKING */
+#if !LWIP_TCPIP_CORE_LOCKING_INPUT
+  TCPIP_MSG_INPKT,
+#endif /* !LWIP_TCPIP_CORE_LOCKING_INPUT */
+#if LWIP_TCPIP_TIMEOUT && LWIP_TIMERS
+  TCPIP_MSG_TIMEOUT,
+  TCPIP_MSG_UNTIMEOUT,
+#endif /* LWIP_TCPIP_TIMEOUT && LWIP_TIMERS */
+  TCPIP_MSG_CALLBACK,
+  TCPIP_MSG_CALLBACK_STATIC
+};
+
+struct tcpip_msg {
+  enum tcpip_msg_type type;
+  union {
+#if !LWIP_TCPIP_CORE_LOCKING
+    struct {
+      tcpip_callback_fn function;
+      void* msg;
+    } api_msg;
+    struct {
+      tcpip_api_call_fn function;
+      struct tcpip_api_call_data *arg;
+      sys_sem_t *sem;
+    } api_call;
+#endif /* LWIP_TCPIP_CORE_LOCKING */
+#if !LWIP_TCPIP_CORE_LOCKING_INPUT
+    struct {
+      struct pbuf *p;
+      struct netif *netif;
+      netif_input_fn input_fn;
+    } inp;
+#endif /* !LWIP_TCPIP_CORE_LOCKING_INPUT */
+    struct {
+      tcpip_callback_fn function;
+      void *ctx;
+    } cb;
+#if LWIP_TCPIP_TIMEOUT && LWIP_TIMERS
+    struct {
+      u32_t msecs;
+      sys_timeout_handler h;
+      void *arg;
+    } tmo;
+#endif /* LWIP_TCPIP_TIMEOUT && LWIP_TIMERS */
+  } msg;
+};
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* !NO_SYS */
+
+#endif /* LWIP_HDR_TCPIP_PRIV_H */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/prot/autoip.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/prot/autoip.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/prot/autoip.h	(revision 457)
@@ -0,0 +1,78 @@
+/**
+ * @file
+ * AutoIP protocol definitions
+ */
+
+/*
+ *
+ * Copyright (c) 2007 Dominik Spies <kontakt@dspies.de>
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * Author: Dominik Spies <kontakt@dspies.de>
+ *
+ * This is a AutoIP implementation for the lwIP TCP/IP stack. It aims to conform
+ * with RFC 3927.
+ *
+ */
+
+#ifndef LWIP_HDR_PROT_AUTOIP_H
+#define LWIP_HDR_PROT_AUTOIP_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* 169.254.0.0 */
+#define AUTOIP_NET              0xA9FE0000
+/* 169.254.1.0 */
+#define AUTOIP_RANGE_START      (AUTOIP_NET | 0x0100)
+/* 169.254.254.255 */
+#define AUTOIP_RANGE_END        (AUTOIP_NET | 0xFEFF)
+
+/* RFC 3927 Constants */
+#define PROBE_WAIT              1   /* second   (initial random delay)                 */
+#define PROBE_MIN               1   /* second   (minimum delay till repeated probe)    */
+#define PROBE_MAX               2   /* seconds  (maximum delay till repeated probe)    */
+#define PROBE_NUM               3   /*          (number of probe packets)              */
+#define ANNOUNCE_NUM            2   /*          (number of announcement packets)       */
+#define ANNOUNCE_INTERVAL       2   /* seconds  (time between announcement packets)    */
+#define ANNOUNCE_WAIT           2   /* seconds  (delay before announcing)              */
+#define MAX_CONFLICTS           10  /*          (max conflicts before rate limiting)   */
+#define RATE_LIMIT_INTERVAL     60  /* seconds  (delay between successive attempts)    */
+#define DEFEND_INTERVAL         10  /* seconds  (min. wait between defensive ARPs)     */
+
+/* AutoIP client states */
+typedef enum {
+  AUTOIP_STATE_OFF        = 0,
+  AUTOIP_STATE_PROBING    = 1,
+  AUTOIP_STATE_ANNOUNCING = 2,
+  AUTOIP_STATE_BOUND      = 3
+} autoip_state_enum_t;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LWIP_HDR_PROT_AUTOIP_H */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/prot/dhcp.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/prot/dhcp.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/prot/dhcp.h	(revision 457)
@@ -0,0 +1,178 @@
+/**
+ * @file
+ * DHCP protocol definitions
+ */
+
+/*
+ * Copyright (c) 2001-2004 Leon Woestenberg <leon.woestenberg@gmx.net>
+ * Copyright (c) 2001-2004 Axon Digital Design B.V., The Netherlands.
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Leon Woestenberg <leon.woestenberg@gmx.net>
+ *
+ */
+#ifndef LWIP_HDR_PROT_DHCP_H
+#define LWIP_HDR_PROT_DHCP_H
+
+#include "lwip/opt.h"
+#include "lwip/arch.h"
+#include "lwip/prot/ip4.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+ /* DHCP message item offsets and length */
+#define DHCP_CHADDR_LEN   16U
+#define DHCP_SNAME_OFS    44U
+#define DHCP_SNAME_LEN    64U
+#define DHCP_FILE_OFS     108U
+#define DHCP_FILE_LEN     128U
+#define DHCP_MSG_LEN      236U
+#define DHCP_OPTIONS_OFS  (DHCP_MSG_LEN + 4U) /* 4 byte: cookie */
+
+#ifdef PACK_STRUCT_USE_INCLUDES
+#  include "arch/bpstruct.h"
+#endif
+PACK_STRUCT_BEGIN
+/** minimum set of fields of any DHCP message */
+struct dhcp_msg
+{
+  PACK_STRUCT_FLD_8(u8_t op);
+  PACK_STRUCT_FLD_8(u8_t htype);
+  PACK_STRUCT_FLD_8(u8_t hlen);
+  PACK_STRUCT_FLD_8(u8_t hops);
+  PACK_STRUCT_FIELD(u32_t xid);
+  PACK_STRUCT_FIELD(u16_t secs);
+  PACK_STRUCT_FIELD(u16_t flags);
+  PACK_STRUCT_FLD_S(ip4_addr_p_t ciaddr);
+  PACK_STRUCT_FLD_S(ip4_addr_p_t yiaddr);
+  PACK_STRUCT_FLD_S(ip4_addr_p_t siaddr);
+  PACK_STRUCT_FLD_S(ip4_addr_p_t giaddr);
+  PACK_STRUCT_FLD_8(u8_t chaddr[DHCP_CHADDR_LEN]);
+  PACK_STRUCT_FLD_8(u8_t sname[DHCP_SNAME_LEN]);
+  PACK_STRUCT_FLD_8(u8_t file[DHCP_FILE_LEN]);
+  PACK_STRUCT_FIELD(u32_t cookie);
+#define DHCP_MIN_OPTIONS_LEN 68U
+/** make sure user does not configure this too small */
+#if ((defined(DHCP_OPTIONS_LEN)) && (DHCP_OPTIONS_LEN < DHCP_MIN_OPTIONS_LEN))
+#  undef DHCP_OPTIONS_LEN
+#endif
+/** allow this to be configured in lwipopts.h, but not too small */
+#if (!defined(DHCP_OPTIONS_LEN))
+/** set this to be sufficient for your options in outgoing DHCP msgs */
+#  define DHCP_OPTIONS_LEN DHCP_MIN_OPTIONS_LEN
+#endif
+  PACK_STRUCT_FLD_8(u8_t options[DHCP_OPTIONS_LEN]);
+} PACK_STRUCT_STRUCT;
+PACK_STRUCT_END
+#ifdef PACK_STRUCT_USE_INCLUDES
+#  include "arch/epstruct.h"
+#endif
+
+
+/* DHCP client states */
+typedef enum {
+  DHCP_STATE_OFF             = 0,
+  DHCP_STATE_REQUESTING      = 1,
+  DHCP_STATE_INIT            = 2,
+  DHCP_STATE_REBOOTING       = 3,
+  DHCP_STATE_REBINDING       = 4,
+  DHCP_STATE_RENEWING        = 5,
+  DHCP_STATE_SELECTING       = 6,
+  DHCP_STATE_INFORMING       = 7,
+  DHCP_STATE_CHECKING        = 8,
+  DHCP_STATE_PERMANENT       = 9,  /* not yet implemented */
+  DHCP_STATE_BOUND           = 10,
+  DHCP_STATE_RELEASING       = 11, /* not yet implemented */
+  DHCP_STATE_BACKING_OFF     = 12
+} dhcp_state_enum_t;
+
+/* DHCP op codes */
+#define DHCP_BOOTREQUEST            1
+#define DHCP_BOOTREPLY              2
+
+/* DHCP message types */
+#define DHCP_DISCOVER               1
+#define DHCP_OFFER                  2
+#define DHCP_REQUEST                3
+#define DHCP_DECLINE                4
+#define DHCP_ACK                    5
+#define DHCP_NAK                    6
+#define DHCP_RELEASE                7
+#define DHCP_INFORM                 8
+
+#define DHCP_MAGIC_COOKIE           0x63825363UL
+
+/* This is a list of options for BOOTP and DHCP, see RFC 2132 for descriptions */
+
+/* BootP options */
+#define DHCP_OPTION_PAD             0
+#define DHCP_OPTION_SUBNET_MASK     1 /* RFC 2132 3.3 */
+#define DHCP_OPTION_ROUTER          3
+#define DHCP_OPTION_DNS_SERVER      6
+#define DHCP_OPTION_HOSTNAME        12
+#define DHCP_OPTION_IP_TTL          23
+#define DHCP_OPTION_MTU             26
+#define DHCP_OPTION_BROADCAST       28
+#define DHCP_OPTION_TCP_TTL         37
+#define DHCP_OPTION_NTP             42
+#define DHCP_OPTION_END             255
+
+/* DHCP options */
+#define DHCP_OPTION_REQUESTED_IP    50 /* RFC 2132 9.1, requested IP address */
+#define DHCP_OPTION_LEASE_TIME      51 /* RFC 2132 9.2, time in seconds, in 4 bytes */
+#define DHCP_OPTION_OVERLOAD        52 /* RFC2132 9.3, use file and/or sname field for options */
+
+#define DHCP_OPTION_MESSAGE_TYPE    53 /* RFC 2132 9.6, important for DHCP */
+#define DHCP_OPTION_MESSAGE_TYPE_LEN 1
+
+#define DHCP_OPTION_SERVER_ID       54 /* RFC 2132 9.7, server IP address */
+#define DHCP_OPTION_PARAMETER_REQUEST_LIST  55 /* RFC 2132 9.8, requested option types */
+
+#define DHCP_OPTION_MAX_MSG_SIZE    57 /* RFC 2132 9.10, message size accepted >= 576 */
+#define DHCP_OPTION_MAX_MSG_SIZE_LEN 2
+
+#define DHCP_OPTION_T1              58 /* T1 renewal time */
+#define DHCP_OPTION_T2              59 /* T2 rebinding time */
+#define DHCP_OPTION_US              60
+#define DHCP_OPTION_CLIENT_ID       61
+#define DHCP_OPTION_TFTP_SERVERNAME 66
+#define DHCP_OPTION_BOOTFILE        67
+
+/* possible combinations of overloading the file and sname fields with options */
+#define DHCP_OVERLOAD_NONE          0
+#define DHCP_OVERLOAD_FILE          1
+#define DHCP_OVERLOAD_SNAME         2
+#define DHCP_OVERLOAD_SNAME_FILE    3
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LWIP_HDR_PROT_DHCP_H */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/prot/dhcp6.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/prot/dhcp6.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/prot/dhcp6.h	(revision 457)
@@ -0,0 +1,138 @@
+/**
+ * @file
+ * DHCPv6 protocol definitions
+ */
+
+/*
+ * Copyright (c) 2017 Simon Goldschmidt <goldsimon@gmx.de>
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Simon Goldschmidt <goldsimon@gmx.de>
+ *
+ */
+#ifndef LWIP_HDR_PROT_DHCP6_H
+#define LWIP_HDR_PROT_DHCP6_H
+
+#include "lwip/opt.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define DHCP6_CLIENT_PORT  546
+#define DHCP6_SERVER_PORT  547
+
+
+ /* DHCPv6 message item offsets and length */
+#define DHCP6_TRANSACTION_ID_LEN   3
+
+#ifdef PACK_STRUCT_USE_INCLUDES
+#  include "arch/bpstruct.h"
+#endif
+PACK_STRUCT_BEGIN
+/** minimum set of fields of any DHCPv6 message */
+struct dhcp6_msg
+{
+  PACK_STRUCT_FLD_8(u8_t msgtype);
+  PACK_STRUCT_FLD_8(u8_t transaction_id[DHCP6_TRANSACTION_ID_LEN]);
+  /* options follow */
+} PACK_STRUCT_STRUCT;
+PACK_STRUCT_END
+#ifdef PACK_STRUCT_USE_INCLUDES
+#  include "arch/epstruct.h"
+#endif
+
+
+/* DHCP6 client states */
+typedef enum {
+  DHCP6_STATE_OFF               = 0,
+  DHCP6_STATE_STATELESS_IDLE    = 1,
+  DHCP6_STATE_REQUESTING_CONFIG = 2
+} dhcp6_state_enum_t;
+
+/* DHCPv6 message types */
+#define DHCP6_SOLICIT               1
+#define DHCP6_ADVERTISE             2
+#define DHCP6_REQUEST               3
+#define DHCP6_CONFIRM               4
+#define DHCP6_RENEW                 5
+#define DHCP6_REBIND                6
+#define DHCP6_REPLY                 7
+#define DHCP6_RELEASE               8
+#define DHCP6_DECLINE               9
+#define DHCP6_RECONFIGURE           10
+#define DHCP6_INFOREQUEST           11
+#define DHCP6_RELAYFORW             12
+#define DHCP6_RELAYREPL             13
+/* More message types see https://www.iana.org/assignments/dhcpv6-parameters/dhcpv6-parameters.xhtml */
+
+/** DHCPv6 status codes */
+#define DHCP6_STATUS_SUCCESS        0 /* Success. */
+#define DHCP6_STATUS_UNSPECFAIL     1 /* Failure, reason unspecified; this status code is sent by either a client or a server to indicate a failure not explicitly specified in this document. */
+#define DHCP6_STATUS_NOADDRSAVAIL   2 /* Server has no addresses available to assign to the IA(s). */
+#define DHCP6_STATUS_NOBINDING      3 /* Client record (binding) unavailable. */
+#define DHCP6_STATUS_NOTONLINK      4 /* The prefix for the address is not appropriate for the link to which the client is attached. */
+#define DHCP6_STATUS_USEMULTICAST   5 /* Sent by a server to a client to force the client to send messages to the server using the All_DHCP_Relay_Agents_and_Servers address. */
+/* More status codes see https://www.iana.org/assignments/dhcpv6-parameters/dhcpv6-parameters.xhtml */
+
+/** DHCPv6 DUID types */
+#define DHCP6_DUID_LLT              1 /* LLT: Link-layer Address Plus Time */
+#define DHCP6_DUID_EN               2 /* EN: Enterprise number */
+#define DHCP6_DUID_LL               3 /* LL: Link-layer Address */
+#define DHCP6_DUID_UUID             4 /* UUID (RFC 6355) */
+
+/* DHCPv6 options */
+#define DHCP6_OPTION_CLIENTID       1
+#define DHCP6_OPTION_SERVERID       2
+#define DHCP6_OPTION_IA_NA          3
+#define DHCP6_OPTION_IA_TA          4
+#define DHCP6_OPTION_IAADDR         5
+#define DHCP6_OPTION_ORO            6
+#define DHCP6_OPTION_PREFERENCE     7
+#define DHCP6_OPTION_ELAPSED_TIME   8
+#define DHCP6_OPTION_RELAY_MSG      9
+#define DHCP6_OPTION_AUTH           11
+#define DHCP6_OPTION_UNICAST        12
+#define DHCP6_OPTION_STATUS_CODE    13
+#define DHCP6_OPTION_RAPID_COMMIT   14
+#define DHCP6_OPTION_USER_CLASS     15
+#define DHCP6_OPTION_VENDOR_CLASS   16
+#define DHCP6_OPTION_VENDOR_OPTS    17
+#define DHCP6_OPTION_INTERFACE_ID   18
+#define DHCP6_OPTION_RECONF_MSG     19
+#define DHCP6_OPTION_RECONF_ACCEPT  20
+/* More options see https://www.iana.org/assignments/dhcpv6-parameters/dhcpv6-parameters.xhtml */
+#define DHCP6_OPTION_DNS_SERVERS    23 /* RFC 3646 */
+#define DHCP6_OPTION_DOMAIN_LIST    24 /* RFC 3646 */
+#define DHCP6_OPTION_SNTP_SERVERS   31 /* RFC 4075 */
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LWIP_HDR_PROT_DHCP6_H */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/prot/dns.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/prot/dns.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/prot/dns.h	(revision 457)
@@ -0,0 +1,140 @@
+/**
+ * @file
+ * DNS - host name to IP address resolver.
+ */
+
+/*
+ * Port to lwIP from uIP
+ * by Jim Pettinato April 2007
+ *
+ * security fixes and more by Simon Goldschmidt
+ *
+ * uIP version Copyright (c) 2002-2003, Adam Dunkels.
+ * 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. The name of the author may not be used to endorse or promote
+ *    products derived from this software without specific prior
+ *    written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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 LWIP_HDR_PROT_DNS_H
+#define LWIP_HDR_PROT_DNS_H
+
+#include "lwip/arch.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** DNS server port address */
+#ifndef DNS_SERVER_PORT
+#define DNS_SERVER_PORT           53
+#endif
+
+/* DNS field TYPE used for "Resource Records" */
+#define DNS_RRTYPE_A              1     /* a host address */
+#define DNS_RRTYPE_NS             2     /* an authoritative name server */
+#define DNS_RRTYPE_MD             3     /* a mail destination (Obsolete - use MX) */
+#define DNS_RRTYPE_MF             4     /* a mail forwarder (Obsolete - use MX) */
+#define DNS_RRTYPE_CNAME          5     /* the canonical name for an alias */
+#define DNS_RRTYPE_SOA            6     /* marks the start of a zone of authority */
+#define DNS_RRTYPE_MB             7     /* a mailbox domain name (EXPERIMENTAL) */
+#define DNS_RRTYPE_MG             8     /* a mail group member (EXPERIMENTAL) */
+#define DNS_RRTYPE_MR             9     /* a mail rename domain name (EXPERIMENTAL) */
+#define DNS_RRTYPE_NULL           10    /* a null RR (EXPERIMENTAL) */
+#define DNS_RRTYPE_WKS            11    /* a well known service description */
+#define DNS_RRTYPE_PTR            12    /* a domain name pointer */
+#define DNS_RRTYPE_HINFO          13    /* host information */
+#define DNS_RRTYPE_MINFO          14    /* mailbox or mail list information */
+#define DNS_RRTYPE_MX             15    /* mail exchange */
+#define DNS_RRTYPE_TXT            16    /* text strings */
+#define DNS_RRTYPE_AAAA           28    /* IPv6 address */
+#define DNS_RRTYPE_SRV            33    /* service location */
+#define DNS_RRTYPE_ANY            255   /* any type */
+
+/* DNS field CLASS used for "Resource Records" */
+#define DNS_RRCLASS_IN            1     /* the Internet */
+#define DNS_RRCLASS_CS            2     /* the CSNET class (Obsolete - used only for examples in some obsolete RFCs) */
+#define DNS_RRCLASS_CH            3     /* the CHAOS class */
+#define DNS_RRCLASS_HS            4     /* Hesiod [Dyer 87] */
+#define DNS_RRCLASS_ANY           255   /* any class */
+#define DNS_RRCLASS_FLUSH         0x800 /* Flush bit */
+
+/* DNS protocol flags */
+#define DNS_FLAG1_RESPONSE        0x80
+#define DNS_FLAG1_OPCODE_STATUS   0x10
+#define DNS_FLAG1_OPCODE_INVERSE  0x08
+#define DNS_FLAG1_OPCODE_STANDARD 0x00
+#define DNS_FLAG1_AUTHORATIVE     0x04
+#define DNS_FLAG1_TRUNC           0x02
+#define DNS_FLAG1_RD              0x01
+#define DNS_FLAG2_RA              0x80
+#define DNS_FLAG2_ERR_MASK        0x0f
+#define DNS_FLAG2_ERR_NONE        0x00
+#define DNS_FLAG2_ERR_NAME        0x03
+
+#define DNS_HDR_GET_OPCODE(hdr) ((((hdr)->flags1) >> 3) & 0xF)
+
+#ifdef PACK_STRUCT_USE_INCLUDES
+#  include "arch/bpstruct.h"
+#endif
+PACK_STRUCT_BEGIN
+/** DNS message header */
+struct dns_hdr {
+  PACK_STRUCT_FIELD(u16_t id);
+  PACK_STRUCT_FLD_8(u8_t flags1);
+  PACK_STRUCT_FLD_8(u8_t flags2);
+  PACK_STRUCT_FIELD(u16_t numquestions);
+  PACK_STRUCT_FIELD(u16_t numanswers);
+  PACK_STRUCT_FIELD(u16_t numauthrr);
+  PACK_STRUCT_FIELD(u16_t numextrarr);
+} PACK_STRUCT_STRUCT;
+PACK_STRUCT_END
+#ifdef PACK_STRUCT_USE_INCLUDES
+#  include "arch/epstruct.h"
+#endif
+#define SIZEOF_DNS_HDR 12
+
+
+/* Multicast DNS definitions */
+
+/** UDP port for multicast DNS queries */
+#ifndef DNS_MQUERY_PORT
+#define DNS_MQUERY_PORT             5353
+#endif
+
+/* IPv4 group for multicast DNS queries: 224.0.0.251 */
+#ifndef DNS_MQUERY_IPV4_GROUP_INIT
+#define DNS_MQUERY_IPV4_GROUP_INIT  IPADDR4_INIT_BYTES(224,0,0,251)
+#endif
+
+/* IPv6 group for multicast DNS queries: FF02::FB */
+#ifndef DNS_MQUERY_IPV6_GROUP_INIT
+#define DNS_MQUERY_IPV6_GROUP_INIT  IPADDR6_INIT_HOST(0xFF020000,0,0,0xFB)
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LWIP_HDR_PROT_DNS_H */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/prot/etharp.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/prot/etharp.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/prot/etharp.h	(revision 457)
@@ -0,0 +1,114 @@
+/**
+ * @file
+ * ARP protocol definitions
+ */
+
+/*
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Adam Dunkels <adam@sics.se>
+ *
+ */
+#ifndef LWIP_HDR_PROT_ETHARP_H
+#define LWIP_HDR_PROT_ETHARP_H
+
+#include "lwip/arch.h"
+#include "lwip/prot/ethernet.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef ETHARP_HWADDR_LEN
+#define ETHARP_HWADDR_LEN     ETH_HWADDR_LEN
+#endif
+
+/**
+ * struct ip4_addr_wordaligned is used in the definition of the ARP packet format in
+ * order to support compilers that don't have structure packing.
+ */
+#ifdef PACK_STRUCT_USE_INCLUDES
+#  include "arch/bpstruct.h"
+#endif
+PACK_STRUCT_BEGIN
+struct ip4_addr_wordaligned {
+  PACK_STRUCT_FIELD(u16_t addrw[2]);
+} PACK_STRUCT_STRUCT;
+PACK_STRUCT_END
+#ifdef PACK_STRUCT_USE_INCLUDES
+#  include "arch/epstruct.h"
+#endif
+
+/** MEMCPY-like copying of IP addresses where addresses are known to be
+ * 16-bit-aligned if the port is correctly configured (so a port could define
+ * this to copying 2 u16_t's) - no NULL-pointer-checking needed. */
+#ifndef IPADDR_WORDALIGNED_COPY_TO_IP4_ADDR_T
+#define IPADDR_WORDALIGNED_COPY_TO_IP4_ADDR_T(dest, src) SMEMCPY(dest, src, sizeof(ip4_addr_t))
+#endif
+
+ /** MEMCPY-like copying of IP addresses where addresses are known to be
+ * 16-bit-aligned if the port is correctly configured (so a port could define
+ * this to copying 2 u16_t's) - no NULL-pointer-checking needed. */
+#ifndef IPADDR_WORDALIGNED_COPY_FROM_IP4_ADDR_T
+#define IPADDR_WORDALIGNED_COPY_FROM_IP4_ADDR_T(dest, src) SMEMCPY(dest, src, sizeof(ip4_addr_t))
+#endif
+
+#ifdef PACK_STRUCT_USE_INCLUDES
+#  include "arch/bpstruct.h"
+#endif
+PACK_STRUCT_BEGIN
+/** the ARP message, see RFC 826 ("Packet format") */
+struct etharp_hdr {
+  PACK_STRUCT_FIELD(u16_t hwtype);
+  PACK_STRUCT_FIELD(u16_t proto);
+  PACK_STRUCT_FLD_8(u8_t  hwlen);
+  PACK_STRUCT_FLD_8(u8_t  protolen);
+  PACK_STRUCT_FIELD(u16_t opcode);
+  PACK_STRUCT_FLD_S(struct eth_addr shwaddr);
+  PACK_STRUCT_FLD_S(struct ip4_addr_wordaligned sipaddr);
+  PACK_STRUCT_FLD_S(struct eth_addr dhwaddr);
+  PACK_STRUCT_FLD_S(struct ip4_addr_wordaligned dipaddr);
+} PACK_STRUCT_STRUCT;
+PACK_STRUCT_END
+#ifdef PACK_STRUCT_USE_INCLUDES
+#  include "arch/epstruct.h"
+#endif
+
+#define SIZEOF_ETHARP_HDR 28
+
+/* ARP message types (opcodes) */
+enum etharp_opcode {
+  ARP_REQUEST = 1,
+  ARP_REPLY   = 2
+};
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LWIP_HDR_PROT_ETHARP_H */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/prot/ethernet.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/prot/ethernet.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/prot/ethernet.h	(revision 457)
@@ -0,0 +1,125 @@
+/**
+ * @file
+ * Ethernet protocol definitions
+ */
+
+/*
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Adam Dunkels <adam@sics.se>
+ *
+ */
+#ifndef LWIP_HDR_PROT_ETHERNET_H
+#define LWIP_HDR_PROT_ETHERNET_H
+
+#include "lwip/arch.h"
+#include "lwip/prot/ieee.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef ETH_HWADDR_LEN
+#ifdef ETHARP_HWADDR_LEN
+#define ETH_HWADDR_LEN    ETHARP_HWADDR_LEN /* compatibility mode */
+#else
+#define ETH_HWADDR_LEN    6
+#endif
+#endif
+
+#ifdef PACK_STRUCT_USE_INCLUDES
+#  include "arch/bpstruct.h"
+#endif
+PACK_STRUCT_BEGIN
+/** An Ethernet MAC address */
+struct eth_addr {
+  PACK_STRUCT_FLD_8(u8_t addr[ETH_HWADDR_LEN]);
+} PACK_STRUCT_STRUCT;
+PACK_STRUCT_END
+#ifdef PACK_STRUCT_USE_INCLUDES
+#  include "arch/epstruct.h"
+#endif
+
+/** Initialize a struct eth_addr with its 6 bytes (takes care of correct braces) */
+#define ETH_ADDR(b0, b1, b2, b3, b4, b5) {{b0, b1, b2, b3, b4, b5}}
+
+#ifdef PACK_STRUCT_USE_INCLUDES
+#  include "arch/bpstruct.h"
+#endif
+PACK_STRUCT_BEGIN
+/** Ethernet header */
+struct eth_hdr {
+#if ETH_PAD_SIZE
+  PACK_STRUCT_FLD_8(u8_t padding[ETH_PAD_SIZE]);
+#endif
+  PACK_STRUCT_FLD_S(struct eth_addr dest);
+  PACK_STRUCT_FLD_S(struct eth_addr src);
+  PACK_STRUCT_FIELD(u16_t type);
+} PACK_STRUCT_STRUCT;
+PACK_STRUCT_END
+#ifdef PACK_STRUCT_USE_INCLUDES
+#  include "arch/epstruct.h"
+#endif
+
+#define SIZEOF_ETH_HDR (14 + ETH_PAD_SIZE)
+
+#ifdef PACK_STRUCT_USE_INCLUDES
+#  include "arch/bpstruct.h"
+#endif
+PACK_STRUCT_BEGIN
+/** VLAN header inserted between ethernet header and payload
+ * if 'type' in ethernet header is ETHTYPE_VLAN.
+ * See IEEE802.Q */
+struct eth_vlan_hdr {
+  PACK_STRUCT_FIELD(u16_t prio_vid);
+  PACK_STRUCT_FIELD(u16_t tpid);
+} PACK_STRUCT_STRUCT;
+PACK_STRUCT_END
+#ifdef PACK_STRUCT_USE_INCLUDES
+#  include "arch/epstruct.h"
+#endif
+
+#define SIZEOF_VLAN_HDR 4
+#define VLAN_ID(vlan_hdr) (lwip_htons((vlan_hdr)->prio_vid) & 0xFFF)
+
+/** The 24-bit IANA IPv4-multicast OUI is 01-00-5e: */
+#define LL_IP4_MULTICAST_ADDR_0 0x01
+#define LL_IP4_MULTICAST_ADDR_1 0x00
+#define LL_IP4_MULTICAST_ADDR_2 0x5e
+
+/** IPv6 multicast uses this prefix */
+#define LL_IP6_MULTICAST_ADDR_0 0x33
+#define LL_IP6_MULTICAST_ADDR_1 0x33
+
+#define eth_addr_cmp(addr1, addr2) (memcmp((addr1)->addr, (addr2)->addr, ETH_HWADDR_LEN) == 0)
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LWIP_HDR_PROT_ETHERNET_H */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/prot/iana.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/prot/iana.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/prot/iana.h	(revision 457)
@@ -0,0 +1,97 @@
+/**
+ * @file
+ * IANA assigned numbers (RFC 1700 and successors)
+ *
+ * @defgroup iana IANA assigned numbers
+ * @ingroup infrastructure
+ */
+
+/*
+ * Copyright (c) 2017 Dirk Ziegelmeier.
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Dirk Ziegelmeier <dziegel@gmx.de>
+ *
+ */
+
+#ifndef LWIP_HDR_PROT_IANA_H
+#define LWIP_HDR_PROT_IANA_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @ingroup iana
+ * Hardware types
+ */
+enum lwip_iana_hwtype {
+  /** Ethernet */
+  LWIP_IANA_HWTYPE_ETHERNET = 1
+};
+
+/**
+ * @ingroup iana
+ * Port numbers
+ * https://www.iana.org/assignments/service-names-port-numbers/service-names-port-numbers.txt
+ */
+enum lwip_iana_port_number {
+  /** SMTP */
+  LWIP_IANA_PORT_SMTP        = 25,
+  /** DHCP server */
+  LWIP_IANA_PORT_DHCP_SERVER = 67,
+  /** DHCP client */
+  LWIP_IANA_PORT_DHCP_CLIENT = 68,
+  /** TFTP */
+  LWIP_IANA_PORT_TFTP        = 69,
+  /** HTTP */
+  LWIP_IANA_PORT_HTTP        = 80,
+  /** SNTP */
+  LWIP_IANA_PORT_SNTP        = 123,
+  /** NETBIOS */
+  LWIP_IANA_PORT_NETBIOS     = 137,
+  /** SNMP */
+  LWIP_IANA_PORT_SNMP        = 161,
+  /** SNMP traps */
+  LWIP_IANA_PORT_SNMP_TRAP   = 162,
+  /** HTTPS */
+  LWIP_IANA_PORT_HTTPS       = 443,
+  /** SMTPS */
+  LWIP_IANA_PORT_SMTPS       = 465,
+  /** MQTT */
+  LWIP_IANA_PORT_MQTT        = 1883,
+  /** MDNS */
+  LWIP_IANA_PORT_MDNS        = 5353,
+  /** Secure MQTT */
+  LWIP_IANA_PORT_SECURE_MQTT = 8883
+};
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LWIP_HDR_PROT_IANA_H */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/prot/icmp.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/prot/icmp.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/prot/icmp.h	(revision 457)
@@ -0,0 +1,91 @@
+/**
+ * @file
+ * ICMP protocol definitions
+ */
+
+/*
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Adam Dunkels <adam@sics.se>
+ *
+ */
+#ifndef LWIP_HDR_PROT_ICMP_H
+#define LWIP_HDR_PROT_ICMP_H
+
+#include "lwip/arch.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define ICMP_ER   0    /* echo reply */
+#define ICMP_DUR  3    /* destination unreachable */
+#define ICMP_SQ   4    /* source quench */
+#define ICMP_RD   5    /* redirect */
+#define ICMP_ECHO 8    /* echo */
+#define ICMP_TE  11    /* time exceeded */
+#define ICMP_PP  12    /* parameter problem */
+#define ICMP_TS  13    /* timestamp */
+#define ICMP_TSR 14    /* timestamp reply */
+#define ICMP_IRQ 15    /* information request */
+#define ICMP_IR  16    /* information reply */
+#define ICMP_AM  17    /* address mask request */
+#define ICMP_AMR 18    /* address mask reply */
+
+#ifdef PACK_STRUCT_USE_INCLUDES
+#  include "arch/bpstruct.h"
+#endif
+/** This is the standard ICMP header only that the u32_t data
+ *  is split to two u16_t like ICMP echo needs it.
+ *  This header is also used for other ICMP types that do not
+ *  use the data part.
+ */
+PACK_STRUCT_BEGIN
+struct icmp_echo_hdr {
+  PACK_STRUCT_FLD_8(u8_t type);
+  PACK_STRUCT_FLD_8(u8_t code);
+  PACK_STRUCT_FIELD(u16_t chksum);
+  PACK_STRUCT_FIELD(u16_t id);
+  PACK_STRUCT_FIELD(u16_t seqno);
+} PACK_STRUCT_STRUCT;
+PACK_STRUCT_END
+#ifdef PACK_STRUCT_USE_INCLUDES
+#  include "arch/epstruct.h"
+#endif
+
+/* Compatibility defines, old versions used to combine type and code to an u16_t */
+#define ICMPH_TYPE(hdr) ((hdr)->type)
+#define ICMPH_CODE(hdr) ((hdr)->code)
+#define ICMPH_TYPE_SET(hdr, t) ((hdr)->type = (t))
+#define ICMPH_CODE_SET(hdr, c) ((hdr)->code = (c))
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LWIP_HDR_PROT_ICMP_H */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/prot/icmp6.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/prot/icmp6.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/prot/icmp6.h	(revision 457)
@@ -0,0 +1,170 @@
+/**
+ * @file
+ * ICMP6 protocol definitions
+ */
+
+/*
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Adam Dunkels <adam@sics.se>
+ *
+ */
+#ifndef LWIP_HDR_PROT_ICMP6_H
+#define LWIP_HDR_PROT_ICMP6_H
+
+#include "lwip/arch.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** ICMP type */
+enum icmp6_type {
+  /** Destination unreachable */
+  ICMP6_TYPE_DUR = 1,
+  /** Packet too big */
+  ICMP6_TYPE_PTB = 2,
+  /** Time exceeded */
+  ICMP6_TYPE_TE = 3,
+  /** Parameter problem */
+  ICMP6_TYPE_PP = 4,
+  /** Private experimentation */
+  ICMP6_TYPE_PE1 = 100,
+  /** Private experimentation */
+  ICMP6_TYPE_PE2 = 101,
+  /** Reserved for expansion of error messages */
+  ICMP6_TYPE_RSV_ERR = 127,
+
+  /** Echo request */
+  ICMP6_TYPE_EREQ = 128,
+  /** Echo reply */
+  ICMP6_TYPE_EREP = 129,
+  /** Multicast listener query */
+  ICMP6_TYPE_MLQ = 130,
+  /** Multicast listener report */
+  ICMP6_TYPE_MLR = 131,
+  /** Multicast listener done */
+  ICMP6_TYPE_MLD = 132,
+  /** Router solicitation */
+  ICMP6_TYPE_RS = 133,
+  /** Router advertisement */
+  ICMP6_TYPE_RA = 134,
+  /** Neighbor solicitation */
+  ICMP6_TYPE_NS = 135,
+  /** Neighbor advertisement */
+  ICMP6_TYPE_NA = 136,
+  /** Redirect */
+  ICMP6_TYPE_RD = 137,
+  /** Multicast router advertisement */
+  ICMP6_TYPE_MRA = 151,
+  /** Multicast router solicitation */
+  ICMP6_TYPE_MRS = 152,
+  /** Multicast router termination */
+  ICMP6_TYPE_MRT = 153,
+  /** Private experimentation */
+  ICMP6_TYPE_PE3 = 200,
+  /** Private experimentation */
+  ICMP6_TYPE_PE4 = 201,
+  /** Reserved for expansion of informational messages */
+  ICMP6_TYPE_RSV_INF = 255
+};
+
+/** ICMP destination unreachable codes */
+enum icmp6_dur_code {
+  /** No route to destination */
+  ICMP6_DUR_NO_ROUTE = 0,
+  /** Communication with destination administratively prohibited */
+  ICMP6_DUR_PROHIBITED = 1,
+  /** Beyond scope of source address */
+  ICMP6_DUR_SCOPE = 2,
+  /** Address unreachable */
+  ICMP6_DUR_ADDRESS = 3,
+  /** Port unreachable */
+  ICMP6_DUR_PORT = 4,
+  /** Source address failed ingress/egress policy */
+  ICMP6_DUR_POLICY = 5,
+  /** Reject route to destination */
+  ICMP6_DUR_REJECT_ROUTE = 6
+};
+
+/** ICMP time exceeded codes */
+enum icmp6_te_code {
+  /** Hop limit exceeded in transit */
+  ICMP6_TE_HL = 0,
+  /** Fragment reassembly time exceeded */
+  ICMP6_TE_FRAG = 1
+};
+
+/** ICMP parameter code */
+enum icmp6_pp_code {
+  /** Erroneous header field encountered */
+  ICMP6_PP_FIELD = 0,
+  /** Unrecognized next header type encountered */
+  ICMP6_PP_HEADER = 1,
+  /** Unrecognized IPv6 option encountered */
+  ICMP6_PP_OPTION = 2
+};
+
+/** This is the standard ICMP6 header. */
+#ifdef PACK_STRUCT_USE_INCLUDES
+#  include "arch/bpstruct.h"
+#endif
+PACK_STRUCT_BEGIN
+struct icmp6_hdr {
+  PACK_STRUCT_FLD_8(u8_t type);
+  PACK_STRUCT_FLD_8(u8_t code);
+  PACK_STRUCT_FIELD(u16_t chksum);
+  PACK_STRUCT_FIELD(u32_t data);
+} PACK_STRUCT_STRUCT;
+PACK_STRUCT_END
+#ifdef PACK_STRUCT_USE_INCLUDES
+#  include "arch/epstruct.h"
+#endif
+
+/** This is the ICMP6 header adapted for echo req/resp. */
+#ifdef PACK_STRUCT_USE_INCLUDES
+#  include "arch/bpstruct.h"
+#endif
+PACK_STRUCT_BEGIN
+struct icmp6_echo_hdr {
+  PACK_STRUCT_FLD_8(u8_t type);
+  PACK_STRUCT_FLD_8(u8_t code);
+  PACK_STRUCT_FIELD(u16_t chksum);
+  PACK_STRUCT_FIELD(u16_t id);
+  PACK_STRUCT_FIELD(u16_t seqno);
+} PACK_STRUCT_STRUCT;
+PACK_STRUCT_END
+#ifdef PACK_STRUCT_USE_INCLUDES
+#  include "arch/epstruct.h"
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LWIP_HDR_PROT_ICMP6_H */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/prot/ieee.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/prot/ieee.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/prot/ieee.h	(revision 457)
@@ -0,0 +1,91 @@
+/**
+ * @file
+ * IEEE assigned numbers
+ *
+ * @defgroup ieee IEEE assigned numbers
+ * @ingroup infrastructure
+ */
+
+/*
+ * Copyright (c) 2017 Dirk Ziegelmeier.
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Dirk Ziegelmeier <dziegel@gmx.de>
+ *
+ */
+
+#ifndef LWIP_HDR_PROT_IEEE_H
+#define LWIP_HDR_PROT_IEEE_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @ingroup ieee
+ * A list of often ethtypes (although lwIP does not use all of them).
+ */
+enum lwip_ieee_eth_type {
+  /** Internet protocol v4 */
+  ETHTYPE_IP        = 0x0800U,
+  /** Address resolution protocol */
+  ETHTYPE_ARP       = 0x0806U, 
+  /** Wake on lan */
+  ETHTYPE_WOL       = 0x0842U,
+  /** RARP */
+  ETHTYPE_RARP      = 0x8035U,
+  /** Virtual local area network */
+  ETHTYPE_VLAN      = 0x8100U,
+  /** Internet protocol v6 */
+  ETHTYPE_IPV6      = 0x86DDU,
+  /** PPP Over Ethernet Discovery Stage */
+  ETHTYPE_PPPOEDISC = 0x8863U,
+  /** PPP Over Ethernet Session Stage */
+  ETHTYPE_PPPOE     = 0x8864U,
+  /** Jumbo Frames */
+  ETHTYPE_JUMBO     = 0x8870U,
+  /** Process field network */
+  ETHTYPE_PROFINET  = 0x8892U,
+  /** Ethernet for control automation technology */
+  ETHTYPE_ETHERCAT  = 0x88A4U,
+  /** Link layer discovery protocol */
+  ETHTYPE_LLDP      = 0x88CCU,
+  /** Serial real-time communication system */
+  ETHTYPE_SERCOS    = 0x88CDU,
+  /** Media redundancy protocol */
+  ETHTYPE_MRP       = 0x88E3U,
+  /** Precision time protocol */
+  ETHTYPE_PTP       = 0x88F7U,
+  /** Q-in-Q, 802.1ad */
+  ETHTYPE_QINQ      = 0x9100U
+};
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LWIP_HDR_PROT_IEEE_H */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/prot/igmp.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/prot/igmp.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/prot/igmp.h	(revision 457)
@@ -0,0 +1,90 @@
+/**
+ * @file
+ * IGMP protocol definitions
+ */
+
+/*
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Adam Dunkels <adam@sics.se>
+ *
+ */
+#ifndef LWIP_HDR_PROT_IGMP_H
+#define LWIP_HDR_PROT_IGMP_H
+
+#include "lwip/arch.h"
+#include "lwip/prot/ip4.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * IGMP constants
+ */
+#define IGMP_TTL                       1
+#define IGMP_MINLEN                    8
+#define ROUTER_ALERT                   0x9404U
+#define ROUTER_ALERTLEN                4
+
+/*
+ * IGMP message types, including version number.
+ */
+#define IGMP_MEMB_QUERY                0x11 /* Membership query         */
+#define IGMP_V1_MEMB_REPORT            0x12 /* Ver. 1 membership report */
+#define IGMP_V2_MEMB_REPORT            0x16 /* Ver. 2 membership report */
+#define IGMP_LEAVE_GROUP               0x17 /* Leave-group message      */
+
+/* Group  membership states */
+#define IGMP_GROUP_NON_MEMBER          0
+#define IGMP_GROUP_DELAYING_MEMBER     1
+#define IGMP_GROUP_IDLE_MEMBER         2
+
+/**
+ * IGMP packet format.
+ */
+#ifdef PACK_STRUCT_USE_INCLUDES
+#  include "arch/bpstruct.h"
+#endif
+PACK_STRUCT_BEGIN
+struct igmp_msg {
+  PACK_STRUCT_FLD_8(u8_t         igmp_msgtype);
+  PACK_STRUCT_FLD_8(u8_t         igmp_maxresp);
+  PACK_STRUCT_FIELD(u16_t        igmp_checksum);
+  PACK_STRUCT_FLD_S(ip4_addr_p_t igmp_group_address);
+} PACK_STRUCT_STRUCT;
+PACK_STRUCT_END
+#ifdef PACK_STRUCT_USE_INCLUDES
+#  include "arch/epstruct.h"
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LWIP_HDR_PROT_IGMP_H */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/prot/ip.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/prot/ip.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/prot/ip.h	(revision 457)
@@ -0,0 +1,59 @@
+/**
+ * @file
+ * IP protocol definitions
+ */
+
+/*
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Adam Dunkels <adam@sics.se>
+ *
+ */
+#ifndef LWIP_HDR_PROT_IP_H
+#define LWIP_HDR_PROT_IP_H
+
+#include "lwip/arch.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define IP_PROTO_ICMP    1
+#define IP_PROTO_IGMP    2
+#define IP_PROTO_UDP     17
+#define IP_PROTO_UDPLITE 136
+#define IP_PROTO_TCP     6
+
+/** This operates on a void* by loading the first byte */
+#define IP_HDR_GET_VERSION(ptr)   ((*(u8_t*)(ptr)) >> 4)
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LWIP_HDR_PROT_IP_H */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/prot/ip4.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/prot/ip4.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/prot/ip4.h	(revision 457)
@@ -0,0 +1,131 @@
+/**
+ * @file
+ * IPv4 protocol definitions
+ */
+
+/*
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Adam Dunkels <adam@sics.se>
+ *
+ */
+#ifndef LWIP_HDR_PROT_IP4_H
+#define LWIP_HDR_PROT_IP4_H
+
+#include "lwip/arch.h"
+#include "lwip/ip4_addr.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** This is the packed version of ip4_addr_t,
+    used in network headers that are itself packed */
+#ifdef PACK_STRUCT_USE_INCLUDES
+#  include "arch/bpstruct.h"
+#endif
+PACK_STRUCT_BEGIN
+struct ip4_addr_packed {
+  PACK_STRUCT_FIELD(u32_t addr);
+} PACK_STRUCT_STRUCT;
+PACK_STRUCT_END
+#ifdef PACK_STRUCT_USE_INCLUDES
+#  include "arch/epstruct.h"
+#endif
+
+typedef struct ip4_addr_packed ip4_addr_p_t;
+
+/* Size of the IPv4 header. Same as 'sizeof(struct ip_hdr)'. */
+#define IP_HLEN 20
+/* Maximum size of the IPv4 header with options. */
+#define IP_HLEN_MAX 60
+
+#ifdef PACK_STRUCT_USE_INCLUDES
+#  include "arch/bpstruct.h"
+#endif
+PACK_STRUCT_BEGIN
+/* The IPv4 header */
+struct ip_hdr {
+  /* version / header length */
+  PACK_STRUCT_FLD_8(u8_t _v_hl);
+  /* type of service */
+  PACK_STRUCT_FLD_8(u8_t _tos);
+  /* total length */
+  PACK_STRUCT_FIELD(u16_t _len);
+  /* identification */
+  PACK_STRUCT_FIELD(u16_t _id);
+  /* fragment offset field */
+  PACK_STRUCT_FIELD(u16_t _offset);
+#define IP_RF 0x8000U        /* reserved fragment flag */
+#define IP_DF 0x4000U        /* don't fragment flag */
+#define IP_MF 0x2000U        /* more fragments flag */
+#define IP_OFFMASK 0x1fffU   /* mask for fragmenting bits */
+  /* time to live */
+  PACK_STRUCT_FLD_8(u8_t _ttl);
+  /* protocol*/
+  PACK_STRUCT_FLD_8(u8_t _proto);
+  /* checksum */
+  PACK_STRUCT_FIELD(u16_t _chksum);
+  /* source and destination IP addresses */
+  PACK_STRUCT_FLD_S(ip4_addr_p_t src);
+  PACK_STRUCT_FLD_S(ip4_addr_p_t dest);
+} PACK_STRUCT_STRUCT;
+PACK_STRUCT_END
+#ifdef PACK_STRUCT_USE_INCLUDES
+#  include "arch/epstruct.h"
+#endif
+
+/* Macros to get struct ip_hdr fields: */
+#define IPH_V(hdr)  ((hdr)->_v_hl >> 4)
+#define IPH_HL(hdr) ((hdr)->_v_hl & 0x0f)
+#define IPH_HL_BYTES(hdr) ((u8_t)(IPH_HL(hdr) * 4))
+#define IPH_TOS(hdr) ((hdr)->_tos)
+#define IPH_LEN(hdr) ((hdr)->_len)
+#define IPH_ID(hdr) ((hdr)->_id)
+#define IPH_OFFSET(hdr) ((hdr)->_offset)
+#define IPH_OFFSET_BYTES(hdr) ((u16_t)((lwip_ntohs(IPH_OFFSET(hdr)) & IP_OFFMASK) * 8U))
+#define IPH_TTL(hdr) ((hdr)->_ttl)
+#define IPH_PROTO(hdr) ((hdr)->_proto)
+#define IPH_CHKSUM(hdr) ((hdr)->_chksum)
+
+/* Macros to set struct ip_hdr fields: */
+#define IPH_VHL_SET(hdr, v, hl) (hdr)->_v_hl = (u8_t)((((v) << 4) | (hl)))
+#define IPH_TOS_SET(hdr, tos) (hdr)->_tos = (tos)
+#define IPH_LEN_SET(hdr, len) (hdr)->_len = (len)
+#define IPH_ID_SET(hdr, id) (hdr)->_id = (id)
+#define IPH_OFFSET_SET(hdr, off) (hdr)->_offset = (off)
+#define IPH_TTL_SET(hdr, ttl) (hdr)->_ttl = (u8_t)(ttl)
+#define IPH_PROTO_SET(hdr, proto) (hdr)->_proto = (u8_t)(proto)
+#define IPH_CHKSUM_SET(hdr, chksum) (hdr)->_chksum = (chksum)
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LWIP_HDR_PROT_IP4_H */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/prot/ip6.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/prot/ip6.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/prot/ip6.h	(revision 457)
@@ -0,0 +1,233 @@
+/**
+ * @file
+ * IPv6 protocol definitions
+ */
+
+/*
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Adam Dunkels <adam@sics.se>
+ *
+ */
+#ifndef LWIP_HDR_PROT_IP6_H
+#define LWIP_HDR_PROT_IP6_H
+
+#include "lwip/arch.h"
+#include "lwip/ip6_addr.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** This is the packed version of ip6_addr_t,
+    used in network headers that are itself packed */
+#ifdef PACK_STRUCT_USE_INCLUDES
+#  include "arch/bpstruct.h"
+#endif
+PACK_STRUCT_BEGIN
+struct ip6_addr_packed {
+  PACK_STRUCT_FIELD(u32_t addr[4]);
+} PACK_STRUCT_STRUCT;
+PACK_STRUCT_END
+#ifdef PACK_STRUCT_USE_INCLUDES
+#  include "arch/epstruct.h"
+#endif
+typedef struct ip6_addr_packed ip6_addr_p_t;
+
+#define IP6_HLEN 40
+
+#define IP6_NEXTH_HOPBYHOP  0
+#define IP6_NEXTH_TCP       6
+#define IP6_NEXTH_UDP       17
+#define IP6_NEXTH_ENCAPS    41
+#define IP6_NEXTH_ROUTING   43
+#define IP6_NEXTH_FRAGMENT  44
+#define IP6_NEXTH_ICMP6     58
+#define IP6_NEXTH_NONE      59
+#define IP6_NEXTH_DESTOPTS  60
+#define IP6_NEXTH_UDPLITE   136
+
+/** The IPv6 header. */
+#ifdef PACK_STRUCT_USE_INCLUDES
+#  include "arch/bpstruct.h"
+#endif
+PACK_STRUCT_BEGIN
+struct ip6_hdr {
+  /** version / traffic class / flow label */
+  PACK_STRUCT_FIELD(u32_t _v_tc_fl);
+  /** payload length */
+  PACK_STRUCT_FIELD(u16_t _plen);
+  /** next header */
+  PACK_STRUCT_FLD_8(u8_t _nexth);
+  /** hop limit */
+  PACK_STRUCT_FLD_8(u8_t _hoplim);
+  /** source and destination IP addresses */
+  PACK_STRUCT_FLD_S(ip6_addr_p_t src);
+  PACK_STRUCT_FLD_S(ip6_addr_p_t dest);
+} PACK_STRUCT_STRUCT;
+PACK_STRUCT_END
+#ifdef PACK_STRUCT_USE_INCLUDES
+#  include "arch/epstruct.h"
+#endif
+#define IP6H_V(hdr)  ((lwip_ntohl((hdr)->_v_tc_fl) >> 28) & 0x0f)
+#define IP6H_TC(hdr) ((lwip_ntohl((hdr)->_v_tc_fl) >> 20) & 0xff)
+#define IP6H_FL(hdr) (lwip_ntohl((hdr)->_v_tc_fl) & 0x000fffff)
+#define IP6H_PLEN(hdr) (lwip_ntohs((hdr)->_plen))
+#define IP6H_NEXTH(hdr) ((hdr)->_nexth)
+#define IP6H_NEXTH_P(hdr) ((u8_t *)(hdr) + 6)
+#define IP6H_HOPLIM(hdr) ((hdr)->_hoplim)
+#define IP6H_VTCFL_SET(hdr, v, tc, fl) (hdr)->_v_tc_fl = (lwip_htonl((((u32_t)(v)) << 28) | (((u32_t)(tc)) << 20) | (fl)))
+#define IP6H_PLEN_SET(hdr, plen) (hdr)->_plen = lwip_htons(plen)
+#define IP6H_NEXTH_SET(hdr, nexth) (hdr)->_nexth = (nexth)
+#define IP6H_HOPLIM_SET(hdr, hl) (hdr)->_hoplim = (u8_t)(hl)
+
+/* ipv6 extended options header */
+#define IP6_PAD1_OPTION             0
+#define IP6_PADN_OPTION             1
+#define IP6_ROUTER_ALERT_OPTION     5
+#define IP6_JUMBO_OPTION            194
+#define IP6_HOME_ADDRESS_OPTION     201
+#define IP6_ROUTER_ALERT_DLEN       2
+#define IP6_ROUTER_ALERT_VALUE_MLD  0
+
+#ifdef PACK_STRUCT_USE_INCLUDES
+#  include "arch/bpstruct.h"
+#endif
+PACK_STRUCT_BEGIN
+struct ip6_opt_hdr {
+  /* router alert option type */
+  PACK_STRUCT_FLD_8(u8_t _opt_type);
+  /* router alert option data len */
+  PACK_STRUCT_FLD_8(u8_t _opt_dlen);
+} PACK_STRUCT_STRUCT;
+PACK_STRUCT_END
+#ifdef PACK_STRUCT_USE_INCLUDES
+#  include "arch/epstruct.h"
+#endif
+#define IP6_OPT_HLEN 2
+#define IP6_OPT_TYPE_ACTION(hdr) ((((hdr)->_opt_type) >> 6) & 0x3)
+#define IP6_OPT_TYPE_CHANGE(hdr) ((((hdr)->_opt_type) >> 5) & 0x1)
+#define IP6_OPT_TYPE(hdr) ((hdr)->_opt_type)
+#define IP6_OPT_DLEN(hdr) ((hdr)->_opt_dlen)
+
+/* Hop-by-Hop header. */
+#define IP6_HBH_HLEN    2
+
+#ifdef PACK_STRUCT_USE_INCLUDES
+#  include "arch/bpstruct.h"
+#endif
+PACK_STRUCT_BEGIN
+struct ip6_hbh_hdr {
+  /* next header */
+  PACK_STRUCT_FLD_8(u8_t _nexth);
+  /* header length in 8-octet units */
+  PACK_STRUCT_FLD_8(u8_t _hlen);
+} PACK_STRUCT_STRUCT;
+PACK_STRUCT_END
+#ifdef PACK_STRUCT_USE_INCLUDES
+#  include "arch/epstruct.h"
+#endif
+#define IP6_HBH_NEXTH(hdr) ((hdr)->_nexth)
+
+/* Destination header. */
+#define IP6_DEST_HLEN   2
+
+#ifdef PACK_STRUCT_USE_INCLUDES
+#  include "arch/bpstruct.h"
+#endif
+PACK_STRUCT_BEGIN
+struct ip6_dest_hdr {
+  /* next header */
+  PACK_STRUCT_FLD_8(u8_t _nexth);
+  /* header length in 8-octet units */
+  PACK_STRUCT_FLD_8(u8_t _hlen);
+} PACK_STRUCT_STRUCT;
+PACK_STRUCT_END
+#ifdef PACK_STRUCT_USE_INCLUDES
+#  include "arch/epstruct.h"
+#endif
+#define IP6_DEST_NEXTH(hdr) ((hdr)->_nexth)
+
+/* Routing header */
+#define IP6_ROUT_TYPE2  2
+#define IP6_ROUT_RPL    3
+
+#ifdef PACK_STRUCT_USE_INCLUDES
+#  include "arch/bpstruct.h"
+#endif
+PACK_STRUCT_BEGIN
+struct ip6_rout_hdr {
+  /* next header */
+  PACK_STRUCT_FLD_8(u8_t _nexth);
+  /* reserved */
+  PACK_STRUCT_FLD_8(u8_t _hlen);
+  /* fragment offset */
+  PACK_STRUCT_FIELD(u8_t _routing_type);
+  /* fragmented packet identification */
+  PACK_STRUCT_FIELD(u8_t _segments_left);
+} PACK_STRUCT_STRUCT;
+PACK_STRUCT_END
+#ifdef PACK_STRUCT_USE_INCLUDES
+#  include "arch/epstruct.h"
+#endif
+#define IP6_ROUT_NEXTH(hdr) ((hdr)->_nexth)
+#define IP6_ROUT_TYPE(hdr) ((hdr)->_routing_type)
+#define IP6_ROUT_SEG_LEFT(hdr) ((hdr)->_segments_left)
+
+/* Fragment header. */
+#define IP6_FRAG_HLEN    8
+#define IP6_FRAG_OFFSET_MASK    0xfff8
+#define IP6_FRAG_MORE_FLAG      0x0001
+
+#ifdef PACK_STRUCT_USE_INCLUDES
+#  include "arch/bpstruct.h"
+#endif
+PACK_STRUCT_BEGIN
+struct ip6_frag_hdr {
+  /* next header */
+  PACK_STRUCT_FLD_8(u8_t _nexth);
+  /* reserved */
+  PACK_STRUCT_FLD_8(u8_t reserved);
+  /* fragment offset */
+  PACK_STRUCT_FIELD(u16_t _fragment_offset);
+  /* fragmented packet identification */
+  PACK_STRUCT_FIELD(u32_t _identification);
+} PACK_STRUCT_STRUCT;
+PACK_STRUCT_END
+#ifdef PACK_STRUCT_USE_INCLUDES
+#  include "arch/epstruct.h"
+#endif
+#define IP6_FRAG_NEXTH(hdr) ((hdr)->_nexth)
+#define IP6_FRAG_MBIT(hdr) (lwip_ntohs((hdr)->_fragment_offset) & 0x1)
+#define IP6_FRAG_ID(hdr) (lwip_ntohl((hdr)->_identification))
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LWIP_HDR_PROT_IP6_H */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/prot/mld6.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/prot/mld6.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/prot/mld6.h	(revision 457)
@@ -0,0 +1,71 @@
+/**
+ * @file
+ * MLD6 protocol definitions
+ */
+
+/*
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Adam Dunkels <adam@sics.se>
+ *
+ */
+#ifndef LWIP_HDR_PROT_MLD6_H
+#define LWIP_HDR_PROT_MLD6_H
+
+#include "lwip/arch.h"
+#include "lwip/prot/ip6.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define MLD6_HBH_HLEN 8
+/** Multicast listener report/query/done message header. */
+#ifdef PACK_STRUCT_USE_INCLUDES
+#  include "arch/bpstruct.h"
+#endif
+PACK_STRUCT_BEGIN
+struct mld_header {
+  PACK_STRUCT_FLD_8(u8_t type);
+  PACK_STRUCT_FLD_8(u8_t code);
+  PACK_STRUCT_FIELD(u16_t chksum);
+  PACK_STRUCT_FIELD(u16_t max_resp_delay);
+  PACK_STRUCT_FIELD(u16_t reserved);
+  PACK_STRUCT_FLD_S(ip6_addr_p_t multicast_address);
+  /* Options follow. */
+} PACK_STRUCT_STRUCT;
+PACK_STRUCT_END
+#ifdef PACK_STRUCT_USE_INCLUDES
+#  include "arch/epstruct.h"
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LWIP_HDR_PROT_MLD6_H */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/prot/nd6.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/prot/nd6.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/prot/nd6.h	(revision 457)
@@ -0,0 +1,274 @@
+/**
+ * @file
+ * ND6 protocol definitions
+ */
+
+/*
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Adam Dunkels <adam@sics.se>
+ *
+ */
+#ifndef LWIP_HDR_PROT_ND6_H
+#define LWIP_HDR_PROT_ND6_H
+
+#include "lwip/arch.h"
+#include "lwip/ip6_addr.h"
+#include "lwip/prot/ip6.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Neighbor solicitation message header. */
+#ifdef PACK_STRUCT_USE_INCLUDES
+#  include "arch/bpstruct.h"
+#endif
+PACK_STRUCT_BEGIN
+struct ns_header {
+  PACK_STRUCT_FLD_8(u8_t type);
+  PACK_STRUCT_FLD_8(u8_t code);
+  PACK_STRUCT_FIELD(u16_t chksum);
+  PACK_STRUCT_FIELD(u32_t reserved);
+  PACK_STRUCT_FLD_S(ip6_addr_p_t target_address);
+  /* Options follow. */
+} PACK_STRUCT_STRUCT;
+PACK_STRUCT_END
+#ifdef PACK_STRUCT_USE_INCLUDES
+#  include "arch/epstruct.h"
+#endif
+
+/** Neighbor advertisement message header. */
+#ifdef PACK_STRUCT_USE_INCLUDES
+#  include "arch/bpstruct.h"
+#endif
+PACK_STRUCT_BEGIN
+struct na_header {
+  PACK_STRUCT_FLD_8(u8_t type);
+  PACK_STRUCT_FLD_8(u8_t code);
+  PACK_STRUCT_FIELD(u16_t chksum);
+  PACK_STRUCT_FLD_8(u8_t flags);
+  PACK_STRUCT_FLD_8(u8_t reserved[3]);
+  PACK_STRUCT_FLD_S(ip6_addr_p_t target_address);
+  /* Options follow. */
+} PACK_STRUCT_STRUCT;
+PACK_STRUCT_END
+#ifdef PACK_STRUCT_USE_INCLUDES
+#  include "arch/epstruct.h"
+#endif
+#define ND6_FLAG_ROUTER      (0x80)
+#define ND6_FLAG_SOLICITED   (0x40)
+#define ND6_FLAG_OVERRIDE    (0x20)
+
+/** Router solicitation message header. */
+#ifdef PACK_STRUCT_USE_INCLUDES
+#  include "arch/bpstruct.h"
+#endif
+PACK_STRUCT_BEGIN
+struct rs_header {
+  PACK_STRUCT_FLD_8(u8_t type);
+  PACK_STRUCT_FLD_8(u8_t code);
+  PACK_STRUCT_FIELD(u16_t chksum);
+  PACK_STRUCT_FIELD(u32_t reserved);
+  /* Options follow. */
+} PACK_STRUCT_STRUCT;
+PACK_STRUCT_END
+#ifdef PACK_STRUCT_USE_INCLUDES
+#  include "arch/epstruct.h"
+#endif
+
+/** Router advertisement message header. */
+#define ND6_RA_FLAG_MANAGED_ADDR_CONFIG (0x80)
+#define ND6_RA_FLAG_OTHER_CONFIG (0x40)
+#define ND6_RA_FLAG_HOME_AGENT (0x20)
+#define ND6_RA_PREFERENCE_MASK (0x18)
+#define ND6_RA_PREFERENCE_HIGH (0x08)
+#define ND6_RA_PREFERENCE_MEDIUM (0x00)
+#define ND6_RA_PREFERENCE_LOW (0x18)
+#define ND6_RA_PREFERENCE_DISABLED (0x10)
+#ifdef PACK_STRUCT_USE_INCLUDES
+#  include "arch/bpstruct.h"
+#endif
+PACK_STRUCT_BEGIN
+struct ra_header {
+  PACK_STRUCT_FLD_8(u8_t type);
+  PACK_STRUCT_FLD_8(u8_t code);
+  PACK_STRUCT_FIELD(u16_t chksum);
+  PACK_STRUCT_FLD_8(u8_t current_hop_limit);
+  PACK_STRUCT_FLD_8(u8_t flags);
+  PACK_STRUCT_FIELD(u16_t router_lifetime);
+  PACK_STRUCT_FIELD(u32_t reachable_time);
+  PACK_STRUCT_FIELD(u32_t retrans_timer);
+  /* Options follow. */
+} PACK_STRUCT_STRUCT;
+PACK_STRUCT_END
+#ifdef PACK_STRUCT_USE_INCLUDES
+#  include "arch/epstruct.h"
+#endif
+
+/** Redirect message header. */
+#ifdef PACK_STRUCT_USE_INCLUDES
+#  include "arch/bpstruct.h"
+#endif
+PACK_STRUCT_BEGIN
+struct redirect_header {
+  PACK_STRUCT_FLD_8(u8_t type);
+  PACK_STRUCT_FLD_8(u8_t code);
+  PACK_STRUCT_FIELD(u16_t chksum);
+  PACK_STRUCT_FIELD(u32_t reserved);
+  PACK_STRUCT_FLD_S(ip6_addr_p_t target_address);
+  PACK_STRUCT_FLD_S(ip6_addr_p_t destination_address);
+  /* Options follow. */
+} PACK_STRUCT_STRUCT;
+PACK_STRUCT_END
+#ifdef PACK_STRUCT_USE_INCLUDES
+#  include "arch/epstruct.h"
+#endif
+
+/** Link-layer address option. */
+#define ND6_OPTION_TYPE_SOURCE_LLADDR (0x01)
+#define ND6_OPTION_TYPE_TARGET_LLADDR (0x02)
+#ifdef PACK_STRUCT_USE_INCLUDES
+#  include "arch/bpstruct.h"
+#endif
+PACK_STRUCT_BEGIN
+struct lladdr_option {
+  PACK_STRUCT_FLD_8(u8_t type);
+  PACK_STRUCT_FLD_8(u8_t length);
+  PACK_STRUCT_FLD_8(u8_t addr[NETIF_MAX_HWADDR_LEN]);
+} PACK_STRUCT_STRUCT;
+PACK_STRUCT_END
+#ifdef PACK_STRUCT_USE_INCLUDES
+#  include "arch/epstruct.h"
+#endif
+
+/** Prefix information option. */
+#define ND6_OPTION_TYPE_PREFIX_INFO (0x03)
+#define ND6_PREFIX_FLAG_ON_LINK (0x80)
+#define ND6_PREFIX_FLAG_AUTONOMOUS (0x40)
+#define ND6_PREFIX_FLAG_ROUTER_ADDRESS (0x20)
+#define ND6_PREFIX_FLAG_SITE_PREFIX (0x10)
+#ifdef PACK_STRUCT_USE_INCLUDES
+#  include "arch/bpstruct.h"
+#endif
+PACK_STRUCT_BEGIN
+struct prefix_option {
+  PACK_STRUCT_FLD_8(u8_t type);
+  PACK_STRUCT_FLD_8(u8_t length);
+  PACK_STRUCT_FLD_8(u8_t prefix_length);
+  PACK_STRUCT_FLD_8(u8_t flags);
+  PACK_STRUCT_FIELD(u32_t valid_lifetime);
+  PACK_STRUCT_FIELD(u32_t preferred_lifetime);
+  PACK_STRUCT_FLD_8(u8_t reserved2[3]);
+  PACK_STRUCT_FLD_8(u8_t site_prefix_length);
+  PACK_STRUCT_FLD_S(ip6_addr_p_t prefix);
+} PACK_STRUCT_STRUCT;
+PACK_STRUCT_END
+#ifdef PACK_STRUCT_USE_INCLUDES
+#  include "arch/epstruct.h"
+#endif
+
+/** Redirected header option. */
+#define ND6_OPTION_TYPE_REDIR_HDR (0x04)
+#ifdef PACK_STRUCT_USE_INCLUDES
+#  include "arch/bpstruct.h"
+#endif
+PACK_STRUCT_BEGIN
+struct redirected_header_option {
+  PACK_STRUCT_FLD_8(u8_t type);
+  PACK_STRUCT_FLD_8(u8_t length);
+  PACK_STRUCT_FLD_8(u8_t reserved[6]);
+  /* Portion of redirected packet follows. */
+  /* PACK_STRUCT_FLD_8(u8_t redirected[8]); */
+} PACK_STRUCT_STRUCT;
+PACK_STRUCT_END
+#ifdef PACK_STRUCT_USE_INCLUDES
+#  include "arch/epstruct.h"
+#endif
+
+/** MTU option. */
+#define ND6_OPTION_TYPE_MTU (0x05)
+#ifdef PACK_STRUCT_USE_INCLUDES
+#  include "arch/bpstruct.h"
+#endif
+PACK_STRUCT_BEGIN
+struct mtu_option {
+  PACK_STRUCT_FLD_8(u8_t type);
+  PACK_STRUCT_FLD_8(u8_t length);
+  PACK_STRUCT_FIELD(u16_t reserved);
+  PACK_STRUCT_FIELD(u32_t mtu);
+} PACK_STRUCT_STRUCT;
+PACK_STRUCT_END
+#ifdef PACK_STRUCT_USE_INCLUDES
+#  include "arch/epstruct.h"
+#endif
+
+/** Route information option. */
+#define ND6_OPTION_TYPE_ROUTE_INFO (24)
+#ifdef PACK_STRUCT_USE_INCLUDES
+#  include "arch/bpstruct.h"
+#endif
+PACK_STRUCT_BEGIN
+struct route_option {
+  PACK_STRUCT_FLD_8(u8_t type);
+  PACK_STRUCT_FLD_8(u8_t length);
+  PACK_STRUCT_FLD_8(u8_t prefix_length);
+  PACK_STRUCT_FLD_8(u8_t preference);
+  PACK_STRUCT_FIELD(u32_t route_lifetime);
+  PACK_STRUCT_FLD_S(ip6_addr_p_t prefix);
+} PACK_STRUCT_STRUCT;
+PACK_STRUCT_END
+#ifdef PACK_STRUCT_USE_INCLUDES
+#  include "arch/epstruct.h"
+#endif
+
+/** Recursive DNS Server Option. */
+#define ND6_OPTION_TYPE_RDNSS (25)
+#ifdef PACK_STRUCT_USE_INCLUDES
+#  include "arch/bpstruct.h"
+#endif
+PACK_STRUCT_BEGIN
+struct rdnss_option {
+  PACK_STRUCT_FLD_8(u8_t type);
+  PACK_STRUCT_FLD_8(u8_t length);
+  PACK_STRUCT_FIELD(u16_t reserved);
+  PACK_STRUCT_FIELD(u32_t lifetime);
+  PACK_STRUCT_FLD_S(ip6_addr_p_t rdnss_address[1]);
+} PACK_STRUCT_STRUCT;
+PACK_STRUCT_END
+#ifdef PACK_STRUCT_USE_INCLUDES
+#  include "arch/epstruct.h"
+#endif
+
+#define SIZEOF_RDNSS_OPTION_BASE 8 /* size without addresses */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LWIP_HDR_PROT_ND6_H */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/prot/tcp.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/prot/tcp.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/prot/tcp.h	(revision 457)
@@ -0,0 +1,100 @@
+/**
+ * @file
+ * TCP protocol definitions
+ */
+
+/*
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Adam Dunkels <adam@sics.se>
+ *
+ */
+#ifndef LWIP_HDR_PROT_TCP_H
+#define LWIP_HDR_PROT_TCP_H
+
+#include "lwip/arch.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Length of the TCP header, excluding options. */
+#define TCP_HLEN 20
+
+/* Fields are (of course) in network byte order.
+ * Some fields are converted to host byte order in tcp_input().
+ */
+#ifdef PACK_STRUCT_USE_INCLUDES
+#  include "arch/bpstruct.h"
+#endif
+PACK_STRUCT_BEGIN
+struct tcp_hdr {
+  PACK_STRUCT_FIELD(u16_t src);
+  PACK_STRUCT_FIELD(u16_t dest);
+  PACK_STRUCT_FIELD(u32_t seqno);
+  PACK_STRUCT_FIELD(u32_t ackno);
+  PACK_STRUCT_FIELD(u16_t _hdrlen_rsvd_flags);
+  PACK_STRUCT_FIELD(u16_t wnd);
+  PACK_STRUCT_FIELD(u16_t chksum);
+  PACK_STRUCT_FIELD(u16_t urgp);
+} PACK_STRUCT_STRUCT;
+PACK_STRUCT_END
+#ifdef PACK_STRUCT_USE_INCLUDES
+#  include "arch/epstruct.h"
+#endif
+
+/* TCP header flags bits */
+#define TCP_FIN 0x01U
+#define TCP_SYN 0x02U
+#define TCP_RST 0x04U
+#define TCP_PSH 0x08U
+#define TCP_ACK 0x10U
+#define TCP_URG 0x20U
+#define TCP_ECE 0x40U
+#define TCP_CWR 0x80U
+/* Valid TCP header flags */
+#define TCP_FLAGS 0x3fU
+
+#define TCP_MAX_OPTION_BYTES 40
+
+#define TCPH_HDRLEN(phdr) ((u16_t)(lwip_ntohs((phdr)->_hdrlen_rsvd_flags) >> 12))
+#define TCPH_HDRLEN_BYTES(phdr) ((u8_t)(TCPH_HDRLEN(phdr) << 2))
+#define TCPH_FLAGS(phdr)  ((u8_t)((lwip_ntohs((phdr)->_hdrlen_rsvd_flags) & TCP_FLAGS)))
+
+#define TCPH_HDRLEN_SET(phdr, len) (phdr)->_hdrlen_rsvd_flags = lwip_htons(((len) << 12) | TCPH_FLAGS(phdr))
+#define TCPH_FLAGS_SET(phdr, flags) (phdr)->_hdrlen_rsvd_flags = (((phdr)->_hdrlen_rsvd_flags & PP_HTONS(~TCP_FLAGS)) | lwip_htons(flags))
+#define TCPH_HDRLEN_FLAGS_SET(phdr, len, flags) (phdr)->_hdrlen_rsvd_flags = (u16_t)(lwip_htons((u16_t)((len) << 12) | (flags)))
+
+#define TCPH_SET_FLAG(phdr, flags ) (phdr)->_hdrlen_rsvd_flags = ((phdr)->_hdrlen_rsvd_flags | lwip_htons(flags))
+#define TCPH_UNSET_FLAG(phdr, flags) (phdr)->_hdrlen_rsvd_flags = ((phdr)->_hdrlen_rsvd_flags & ~lwip_htons(flags))
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LWIP_HDR_PROT_TCP_H */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/prot/udp.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/prot/udp.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/prot/udp.h	(revision 457)
@@ -0,0 +1,68 @@
+/**
+ * @file
+ * UDP protocol definitions
+ */
+
+/*
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Adam Dunkels <adam@sics.se>
+ *
+ */
+#ifndef LWIP_HDR_PROT_UDP_H
+#define LWIP_HDR_PROT_UDP_H
+
+#include "lwip/arch.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define UDP_HLEN 8
+
+/* Fields are (of course) in network byte order. */
+#ifdef PACK_STRUCT_USE_INCLUDES
+#  include "arch/bpstruct.h"
+#endif
+PACK_STRUCT_BEGIN
+struct udp_hdr {
+  PACK_STRUCT_FIELD(u16_t src);
+  PACK_STRUCT_FIELD(u16_t dest);  /* src/dest UDP ports */
+  PACK_STRUCT_FIELD(u16_t len);
+  PACK_STRUCT_FIELD(u16_t chksum);
+} PACK_STRUCT_STRUCT;
+PACK_STRUCT_END
+#ifdef PACK_STRUCT_USE_INCLUDES
+#  include "arch/epstruct.h"
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LWIP_HDR_PROT_UDP_H */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/raw.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/raw.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/raw.h	(revision 457)
@@ -0,0 +1,143 @@
+/**
+ * @file
+ * raw API (to be used from TCPIP thread)\n
+ * See also @ref raw_raw
+ */
+
+/*
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Adam Dunkels <adam@sics.se>
+ *
+ */
+#ifndef LWIP_HDR_RAW_H
+#define LWIP_HDR_RAW_H
+
+#include "lwip/opt.h"
+
+#if LWIP_RAW /* don't build if not configured for use in lwipopts.h */
+
+#include "lwip/pbuf.h"
+#include "lwip/def.h"
+#include "lwip/ip.h"
+#include "lwip/ip_addr.h"
+#include "lwip/ip6_addr.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define RAW_FLAGS_CONNECTED      0x01U
+#define RAW_FLAGS_HDRINCL        0x02U
+#define RAW_FLAGS_MULTICAST_LOOP 0x04U
+
+struct raw_pcb;
+
+/** Function prototype for raw pcb receive callback functions.
+ * @param arg user supplied argument (raw_pcb.recv_arg)
+ * @param pcb the raw_pcb which received data
+ * @param p the packet buffer that was received
+ * @param addr the remote IP address from which the packet was received
+ * @return 1 if the packet was 'eaten' (aka. deleted),
+ *         0 if the packet lives on
+ * If returning 1, the callback is responsible for freeing the pbuf
+ * if it's not used any more.
+ */
+typedef u8_t (*raw_recv_fn)(void *arg, struct raw_pcb *pcb, struct pbuf *p,
+    const ip_addr_t *addr);
+
+/** the RAW protocol control block */
+struct raw_pcb {
+  /* Common members of all PCB types */
+  IP_PCB;
+
+  struct raw_pcb *next;
+
+  u8_t protocol;
+  u8_t flags;
+
+#if LWIP_MULTICAST_TX_OPTIONS
+  /** outgoing network interface for multicast packets, by interface index (if nonzero) */
+  u8_t mcast_ifindex;
+  /** TTL for outgoing multicast packets */
+  u8_t mcast_ttl;
+#endif /* LWIP_MULTICAST_TX_OPTIONS */
+
+  /** receive callback function */
+  raw_recv_fn recv;
+  /* user-supplied argument for the recv callback */
+  void *recv_arg;
+#if LWIP_IPV6
+  /* fields for handling checksum computations as per RFC3542. */
+  u16_t chksum_offset;
+  u8_t  chksum_reqd;
+#endif
+};
+
+/* The following functions is the application layer interface to the
+   RAW code. */
+struct raw_pcb * raw_new        (u8_t proto);
+struct raw_pcb * raw_new_ip_type(u8_t type, u8_t proto);
+void             raw_remove     (struct raw_pcb *pcb);
+err_t            raw_bind       (struct raw_pcb *pcb, const ip_addr_t *ipaddr);
+void             raw_bind_netif (struct raw_pcb *pcb, const struct netif *netif);
+err_t            raw_connect    (struct raw_pcb *pcb, const ip_addr_t *ipaddr);
+void             raw_disconnect (struct raw_pcb *pcb);
+
+err_t            raw_sendto     (struct raw_pcb *pcb, struct pbuf *p, const ip_addr_t *ipaddr);
+err_t            raw_sendto_if_src(struct raw_pcb *pcb, struct pbuf *p, const ip_addr_t *dst_ip, struct netif *netif, const ip_addr_t *src_ip);
+err_t            raw_send       (struct raw_pcb *pcb, struct pbuf *p);
+
+void             raw_recv       (struct raw_pcb *pcb, raw_recv_fn recv, void *recv_arg);
+
+#define          raw_flags(pcb) ((pcb)->flags)
+#define          raw_setflags(pcb,f)  ((pcb)->flags = (f))
+
+#define          raw_set_flags(pcb, set_flags)     do { (pcb)->flags = (u8_t)((pcb)->flags |  (set_flags)); } while(0)
+#define          raw_clear_flags(pcb, clr_flags)   do { (pcb)->flags = (u8_t)((pcb)->flags & (u8_t)(~(clr_flags) & 0xff)); } while(0)
+#define          raw_is_flag_set(pcb, flag)        (((pcb)->flags & (flag)) != 0)
+
+#define raw_init() /* Compatibility define, no init needed. */
+
+/* for compatibility with older implementation */
+#define raw_new_ip6(proto) raw_new_ip_type(IPADDR_TYPE_V6, proto)
+
+#if LWIP_MULTICAST_TX_OPTIONS
+#define raw_set_multicast_netif_index(pcb, idx) ((pcb)->mcast_ifindex = (idx))
+#define raw_get_multicast_netif_index(pcb)      ((pcb)->mcast_ifindex)
+#define raw_set_multicast_ttl(pcb, value)       ((pcb)->mcast_ttl = (value))
+#define raw_get_multicast_ttl(pcb)              ((pcb)->mcast_ttl)
+#endif /* LWIP_MULTICAST_TX_OPTIONS */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LWIP_RAW */
+
+#endif /* LWIP_HDR_RAW_H */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/sio.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/sio.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/sio.h	(revision 457)
@@ -0,0 +1,142 @@
+/*
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ */
+
+/*
+ * This is the interface to the platform specific serial IO module
+ * It needs to be implemented by those platforms which need SLIP or PPP
+ */
+
+#ifndef SIO_H
+#define SIO_H
+
+#include "lwip/arch.h"
+#include "lwip/opt.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* If you want to define sio_fd_t elsewhere or differently,
+   define this in your cc.h file. */
+#ifndef __sio_fd_t_defined
+typedef void * sio_fd_t;
+#endif
+
+/* The following functions can be defined to something else in your cc.h file
+   or be implemented in your custom sio.c file. */
+
+#ifndef sio_open
+/**
+ * Opens a serial device for communication.
+ *
+ * @param devnum device number
+ * @return handle to serial device if successful, NULL otherwise
+ */
+sio_fd_t sio_open(u8_t devnum);
+#endif
+
+#ifndef sio_send
+/**
+ * Sends a single character to the serial device.
+ *
+ * @param c character to send
+ * @param fd serial device handle
+ *
+ * @note This function will block until the character can be sent.
+ */
+void sio_send(u8_t c, sio_fd_t fd);
+#endif
+
+#ifndef sio_recv
+/**
+ * Receives a single character from the serial device.
+ *
+ * @param fd serial device handle
+ *
+ * @note This function will block until a character is received.
+ */
+u8_t sio_recv(sio_fd_t fd);
+#endif
+
+#ifndef sio_read
+/**
+ * Reads from the serial device.
+ *
+ * @param fd serial device handle
+ * @param data pointer to data buffer for receiving
+ * @param len maximum length (in bytes) of data to receive
+ * @return number of bytes actually received - may be 0 if aborted by sio_read_abort
+ *
+ * @note This function will block until data can be received. The blocking
+ * can be cancelled by calling sio_read_abort().
+ */
+u32_t sio_read(sio_fd_t fd, u8_t *data, u32_t len);
+#endif
+
+#ifndef sio_tryread
+/**
+ * Tries to read from the serial device. Same as sio_read but returns
+ * immediately if no data is available and never blocks.
+ *
+ * @param fd serial device handle
+ * @param data pointer to data buffer for receiving
+ * @param len maximum length (in bytes) of data to receive
+ * @return number of bytes actually received
+ */
+u32_t sio_tryread(sio_fd_t fd, u8_t *data, u32_t len);
+#endif
+
+#ifndef sio_write
+/**
+ * Writes to the serial device.
+ *
+ * @param fd serial device handle
+ * @param data pointer to data to send
+ * @param len length (in bytes) of data to send
+ * @return number of bytes actually sent
+ *
+ * @note This function will block until all data can be sent.
+ */
+u32_t sio_write(sio_fd_t fd, u8_t *data, u32_t len);
+#endif
+
+#ifndef sio_read_abort
+/**
+ * Aborts a blocking sio_read() call.
+ *
+ * @param fd serial device handle
+ */
+void sio_read_abort(sio_fd_t fd);
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* SIO_H */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/snmp.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/snmp.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/snmp.h	(revision 457)
@@ -0,0 +1,213 @@
+/**
+ * @file
+ * SNMP support API for implementing netifs and statitics for MIB2
+ */
+
+/*
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Dirk Ziegelmeier <dziegel@gmx.de>
+ *
+ */
+#ifndef LWIP_HDR_SNMP_H
+#define LWIP_HDR_SNMP_H
+
+#include "lwip/opt.h"
+#include "lwip/ip_addr.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct udp_pcb;
+struct netif;
+
+/**
+ * @defgroup netif_mib2 MIB2 statistics
+ * @ingroup netif
+ */
+
+/* MIB2 statistics functions */
+#if MIB2_STATS  /* don't build if not configured for use in lwipopts.h */
+/**
+ * @ingroup netif_mib2
+ * @see RFC1213, "MIB-II, 6. Definitions"
+ */
+enum snmp_ifType {
+  snmp_ifType_other=1,                /* none of the following */
+  snmp_ifType_regular1822,
+  snmp_ifType_hdh1822,
+  snmp_ifType_ddn_x25,
+  snmp_ifType_rfc877_x25,
+  snmp_ifType_ethernet_csmacd,
+  snmp_ifType_iso88023_csmacd,
+  snmp_ifType_iso88024_tokenBus,
+  snmp_ifType_iso88025_tokenRing,
+  snmp_ifType_iso88026_man,
+  snmp_ifType_starLan,
+  snmp_ifType_proteon_10Mbit,
+  snmp_ifType_proteon_80Mbit,
+  snmp_ifType_hyperchannel,
+  snmp_ifType_fddi,
+  snmp_ifType_lapb,
+  snmp_ifType_sdlc,
+  snmp_ifType_ds1,                    /* T-1 */
+  snmp_ifType_e1,                     /* european equiv. of T-1 */
+  snmp_ifType_basicISDN,
+  snmp_ifType_primaryISDN,            /* proprietary serial */
+  snmp_ifType_propPointToPointSerial,
+  snmp_ifType_ppp,
+  snmp_ifType_softwareLoopback,
+  snmp_ifType_eon,                    /* CLNP over IP [11] */
+  snmp_ifType_ethernet_3Mbit,
+  snmp_ifType_nsip,                   /* XNS over IP */
+  snmp_ifType_slip,                   /* generic SLIP */
+  snmp_ifType_ultra,                  /* ULTRA technologies */
+  snmp_ifType_ds3,                    /* T-3 */
+  snmp_ifType_sip,                    /* SMDS */
+  snmp_ifType_frame_relay
+};
+
+/** This macro has a precision of ~49 days because sys_now returns u32_t. \#define your own if you want ~490 days. */
+#ifndef MIB2_COPY_SYSUPTIME_TO
+#define MIB2_COPY_SYSUPTIME_TO(ptrToVal) (*(ptrToVal) = (sys_now() / 10))
+#endif
+
+/**
+ * @ingroup netif_mib2
+ * Increment stats member for SNMP MIB2 stats (struct stats_mib2_netif_ctrs)
+ */
+#define MIB2_STATS_NETIF_INC(n, x)      do { ++(n)->mib2_counters.x; } while(0)
+/**
+ * @ingroup netif_mib2
+ * Add value to stats member for SNMP MIB2 stats (struct stats_mib2_netif_ctrs)
+ */
+#define MIB2_STATS_NETIF_ADD(n, x, val) do { (n)->mib2_counters.x += (val); } while(0)
+
+/**
+ * @ingroup netif_mib2
+ * Init MIB2 statistic counters in netif
+ * @param netif Netif to init
+ * @param type one of enum @ref snmp_ifType
+ * @param speed your link speed here (units: bits per second)
+ */
+#define MIB2_INIT_NETIF(netif, type, speed) do { \
+  (netif)->link_type = (type);  \
+  (netif)->link_speed = (speed);\
+  (netif)->ts = 0;              \
+  (netif)->mib2_counters.ifinoctets = 0;      \
+  (netif)->mib2_counters.ifinucastpkts = 0;   \
+  (netif)->mib2_counters.ifinnucastpkts = 0;  \
+  (netif)->mib2_counters.ifindiscards = 0;    \
+  (netif)->mib2_counters.ifinerrors = 0;    \
+  (netif)->mib2_counters.ifinunknownprotos = 0;    \
+  (netif)->mib2_counters.ifoutoctets = 0;     \
+  (netif)->mib2_counters.ifoutucastpkts = 0;  \
+  (netif)->mib2_counters.ifoutnucastpkts = 0; \
+  (netif)->mib2_counters.ifoutdiscards = 0; \
+  (netif)->mib2_counters.ifouterrors = 0; } while(0)
+#else /* MIB2_STATS */
+#ifndef MIB2_COPY_SYSUPTIME_TO
+#define MIB2_COPY_SYSUPTIME_TO(ptrToVal)
+#endif
+#define MIB2_INIT_NETIF(netif, type, speed)
+#define MIB2_STATS_NETIF_INC(n, x)
+#define MIB2_STATS_NETIF_ADD(n, x, val)
+#endif /* MIB2_STATS */
+
+/* LWIP MIB2 callbacks */
+#if LWIP_MIB2_CALLBACKS /* don't build if not configured for use in lwipopts.h */
+/* network interface */
+void mib2_netif_added(struct netif *ni);
+void mib2_netif_removed(struct netif *ni);
+
+#if LWIP_IPV4 && LWIP_ARP
+/* ARP (for atTable and ipNetToMediaTable) */
+void mib2_add_arp_entry(struct netif *ni, ip4_addr_t *ip);
+void mib2_remove_arp_entry(struct netif *ni, ip4_addr_t *ip);
+#else /* LWIP_IPV4 && LWIP_ARP */
+#define mib2_add_arp_entry(ni,ip)
+#define mib2_remove_arp_entry(ni,ip)
+#endif /* LWIP_IPV4 && LWIP_ARP */
+
+/* IP */
+#if LWIP_IPV4
+void mib2_add_ip4(struct netif *ni);
+void mib2_remove_ip4(struct netif *ni);
+void mib2_add_route_ip4(u8_t dflt, struct netif *ni);
+void mib2_remove_route_ip4(u8_t dflt, struct netif *ni);
+#endif /* LWIP_IPV4 */
+
+/* UDP */
+#if LWIP_UDP
+void mib2_udp_bind(struct udp_pcb *pcb);
+void mib2_udp_unbind(struct udp_pcb *pcb);
+#endif /* LWIP_UDP */
+
+#else /* LWIP_MIB2_CALLBACKS */
+/* LWIP_MIB2_CALLBACKS support not available */
+/* define everything to be empty */
+
+/* network interface */
+#define mib2_netif_added(ni)
+#define mib2_netif_removed(ni)
+
+/* ARP */
+#define mib2_add_arp_entry(ni,ip)
+#define mib2_remove_arp_entry(ni,ip)
+
+/* IP */
+#define mib2_add_ip4(ni)
+#define mib2_remove_ip4(ni)
+#define mib2_add_route_ip4(dflt, ni)
+#define mib2_remove_route_ip4(dflt, ni)
+
+/* UDP */
+#define mib2_udp_bind(pcb)
+#define mib2_udp_unbind(pcb)
+#endif /* LWIP_MIB2_CALLBACKS */
+
+/* for source-code compatibility reasons only, can be removed (not used internally) */
+#define NETIF_INIT_SNMP                MIB2_INIT_NETIF
+#define snmp_add_ifinoctets(ni,value)  MIB2_STATS_NETIF_ADD(ni, ifinoctets, value)
+#define snmp_inc_ifinucastpkts(ni)     MIB2_STATS_NETIF_INC(ni, ifinucastpkts)
+#define snmp_inc_ifinnucastpkts(ni)    MIB2_STATS_NETIF_INC(ni, ifinnucastpkts)
+#define snmp_inc_ifindiscards(ni)      MIB2_STATS_NETIF_INC(ni, ifindiscards)
+#define snmp_inc_ifinerrors(ni)        MIB2_STATS_NETIF_INC(ni, ifinerrors)
+#define snmp_inc_ifinunknownprotos(ni) MIB2_STATS_NETIF_INC(ni, ifinunknownprotos)
+#define snmp_add_ifoutoctets(ni,value) MIB2_STATS_NETIF_ADD(ni, ifoutoctets, value)
+#define snmp_inc_ifoutucastpkts(ni)    MIB2_STATS_NETIF_INC(ni, ifoutucastpkts)
+#define snmp_inc_ifoutnucastpkts(ni)   MIB2_STATS_NETIF_INC(ni, ifoutnucastpkts)
+#define snmp_inc_ifoutdiscards(ni)     MIB2_STATS_NETIF_INC(ni, ifoutdiscards)
+#define snmp_inc_ifouterrors(ni)       MIB2_STATS_NETIF_INC(ni, ifouterrors)
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LWIP_HDR_SNMP_H */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/sockets.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/sockets.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/sockets.h	(revision 457)
@@ -0,0 +1,714 @@
+/**
+ * @file
+ * Socket API (to be used from non-TCPIP threads)
+ */
+
+/*
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Adam Dunkels <adam@sics.se>
+ *
+ */
+
+
+#ifndef LWIP_HDR_SOCKETS_H
+#define LWIP_HDR_SOCKETS_H
+
+#include "lwip/opt.h"
+
+#if LWIP_SOCKET /* don't build if not configured for use in lwipopts.h */
+
+#include "lwip/ip_addr.h"
+#include "lwip/netif.h"
+#include "lwip/err.h"
+#include "lwip/inet.h"
+#include "lwip/errno.h"
+
+#include <string.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* If your port already typedef's sa_family_t, define SA_FAMILY_T_DEFINED
+   to prevent this code from redefining it. */
+#if !defined(sa_family_t) && !defined(SA_FAMILY_T_DEFINED)
+typedef u8_t sa_family_t;
+#endif
+/* If your port already typedef's in_port_t, define IN_PORT_T_DEFINED
+   to prevent this code from redefining it. */
+#if !defined(in_port_t) && !defined(IN_PORT_T_DEFINED)
+typedef u16_t in_port_t;
+#endif
+
+#if LWIP_IPV4
+/* members are in network byte order */
+struct sockaddr_in {
+  u8_t            sin_len;
+  sa_family_t     sin_family;
+  in_port_t       sin_port;
+  struct in_addr  sin_addr;
+#define SIN_ZERO_LEN 8
+  char            sin_zero[SIN_ZERO_LEN];
+};
+#endif /* LWIP_IPV4 */
+
+#if LWIP_IPV6
+struct sockaddr_in6 {
+  u8_t            sin6_len;      /* length of this structure    */
+  sa_family_t     sin6_family;   /* AF_INET6                    */
+  in_port_t       sin6_port;     /* Transport layer port #      */
+  u32_t           sin6_flowinfo; /* IPv6 flow information       */
+  struct in6_addr sin6_addr;     /* IPv6 address                */
+  u32_t           sin6_scope_id; /* Set of interfaces for scope */
+};
+#endif /* LWIP_IPV6 */
+
+#define UNIX_PATH_MAX    108
+
+struct sockaddr_un {
+    sa_family_t sun_family;               /* AF_UNIX */
+    char        sun_path[UNIX_PATH_MAX];  /* pathname */
+};
+
+struct sockaddr {
+  u8_t        sa_len;
+  sa_family_t sa_family;
+  char        sa_data[14];
+};
+
+struct sockaddr_storage {
+  u8_t        s2_len;
+  sa_family_t ss_family;
+  char        s2_data1[2];
+  u32_t       s2_data2[3];
+#if LWIP_IPV6
+  u32_t       s2_data3[3];
+#endif /* LWIP_IPV6 */
+};
+
+/* If your port already typedef's socklen_t, define SOCKLEN_T_DEFINED
+   to prevent this code from redefining it. */
+#if !defined(socklen_t) && !defined(SOCKLEN_T_DEFINED)
+typedef u32_t socklen_t;
+#endif
+
+#if !defined IOV_MAX
+#define IOV_MAX 0xFFFF
+#elif IOV_MAX > 0xFFFF
+#error "IOV_MAX larger than supported by LwIP"
+#endif /* IOV_MAX */
+
+#if !defined(iovec)
+struct iovec {
+  void  *iov_base;
+  size_t iov_len;
+};
+#endif
+
+struct msghdr {
+  void         *msg_name;
+  socklen_t     msg_namelen;
+  struct iovec *msg_iov;
+  int           msg_iovlen;
+  void         *msg_control;
+  socklen_t     msg_controllen;
+  int           msg_flags;
+};
+
+/* struct msghdr->msg_flags bit field values */
+#define MSG_TRUNC   0x04
+#define MSG_CTRUNC  0x08
+
+/* RFC 3542, Section 20: Ancillary Data */
+struct cmsghdr {
+  socklen_t  cmsg_len;   /* number of bytes, including header */
+  int        cmsg_level; /* originating protocol */
+  int        cmsg_type;  /* protocol-specific type */
+};
+/* Data section follows header and possible padding, typically referred to as
+      unsigned char cmsg_data[]; */
+
+/* cmsg header/data alignment. NOTE: we align to native word size (double word
+size on 16-bit arch) so structures are not placed at an unaligned address.
+16-bit arch needs double word to ensure 32-bit alignment because socklen_t
+could be 32 bits. If we ever have cmsg data with a 64-bit variable, alignment
+will need to increase long long */
+#define ALIGN_H(size) (((size) + sizeof(long) - 1U) & ~(sizeof(long)-1U))
+#define ALIGN_D(size) ALIGN_H(size)
+
+#define CMSG_FIRSTHDR(mhdr) \
+          ((mhdr)->msg_controllen >= sizeof(struct cmsghdr) ? \
+           (struct cmsghdr *)(mhdr)->msg_control : \
+           (struct cmsghdr *)NULL)
+
+#define CMSG_NXTHDR(mhdr, cmsg) \
+        (((cmsg) == NULL) ? CMSG_FIRSTHDR(mhdr) : \
+         (((u8_t *)(cmsg) + ALIGN_H((cmsg)->cmsg_len) \
+                            + ALIGN_D(sizeof(struct cmsghdr)) > \
+           (u8_t *)((mhdr)->msg_control) + (mhdr)->msg_controllen) ? \
+          (struct cmsghdr *)NULL : \
+          (struct cmsghdr *)((void*)((u8_t *)(cmsg) + \
+                                      ALIGN_H((cmsg)->cmsg_len)))))
+
+#define CMSG_DATA(cmsg) ((void*)((u8_t *)(cmsg) + \
+                         ALIGN_D(sizeof(struct cmsghdr))))
+
+#define CMSG_SPACE(length) (ALIGN_D(sizeof(struct cmsghdr)) + \
+                            ALIGN_H(length))
+
+#define CMSG_LEN(length) (ALIGN_D(sizeof(struct cmsghdr)) + \
+                           length)
+
+/* Set socket options argument */
+#define IFNAMSIZ NETIF_NAMESIZE
+struct ifreq {
+  char ifr_name[IFNAMSIZ]; /* Interface name */
+  union {
+    struct sockaddr ifr_addr;
+    struct sockaddr ifr_hwaddr;
+  };
+};
+
+/* Socket protocol types (TCP/UDP/RAW) */
+#define SOCK_STREAM     1
+#define SOCK_DGRAM      2
+#define SOCK_RAW        3
+
+/*
+ * Option flags per-socket. These must match the SOF_ flags in ip.h (checked in init.c)
+ */
+#define SO_REUSEADDR   0x0004 /* Allow local address reuse */
+#define SO_KEEPALIVE   0x0008 /* keep connections alive */
+#define SO_BROADCAST   0x0020 /* permit to send and to receive broadcast messages (see IP_SOF_BROADCAST option) */
+
+
+/*
+ * Additional options, not kept in so_options.
+ */
+#define SO_DEBUG        0x0001 /* Unimplemented: turn on debugging info recording */
+#define SO_ACCEPTCONN   0x0002 /* socket has had listen() */
+#define SO_DONTROUTE    0x0010 /* Unimplemented: just use interface addresses */
+#define SO_USELOOPBACK  0x0040 /* Unimplemented: bypass hardware when possible */
+#define SO_LINGER       0x0080 /* linger on close if data present */
+#define SO_DONTLINGER   ((int)(~SO_LINGER))
+#define SO_OOBINLINE    0x0100 /* Unimplemented: leave received OOB data in line */
+#define SO_REUSEPORT    0x0200 /* Unimplemented: allow local address & port reuse */
+#define SO_SNDBUF       0x1001 /* Unimplemented: send buffer size */
+#define SO_RCVBUF       0x1002 /* receive buffer size */
+#define SO_SNDLOWAT     0x1003 /* Unimplemented: send low-water mark */
+#define SO_RCVLOWAT     0x1004 /* Unimplemented: receive low-water mark */
+#define SO_SNDTIMEO     0x1005 /* send timeout */
+#define SO_RCVTIMEO     0x1006 /* receive timeout */
+#define SO_ERROR        0x1007 /* get error status and clear */
+#define SO_TYPE         0x1008 /* get socket type */
+#define SO_CONTIMEO     0x1009 /* Unimplemented: connect timeout */
+#define SO_NO_CHECK     0x100a /* don't create UDP checksum */
+#define SO_BINDTODEVICE 0x100b /* bind to device */
+
+/*
+ * Structure used for manipulating linger option.
+ */
+struct linger {
+  int l_onoff;                /* option on/off */
+  int l_linger;               /* linger time in seconds */
+};
+
+/*
+ * Level number for (get/set)sockopt() to apply to socket itself.
+ */
+#define  SOL_SOCKET  0xfff    /* options for socket level */
+
+
+#define AF_UNSPEC       0
+#define AF_UNIX         1
+#define AF_INET         2
+#if LWIP_IPV6
+#define AF_INET6        10
+#else /* LWIP_IPV6 */
+#define AF_INET6        AF_UNSPEC
+#endif /* LWIP_IPV6 */
+#define PF_UNIX         AF_UNIX
+#define PF_INET         AF_INET
+#define PF_INET6        AF_INET6
+#define PF_UNSPEC       AF_UNSPEC
+
+#define IPPROTO_IP      0
+#define IPPROTO_ICMP    1
+#define IPPROTO_TCP     6
+#define IPPROTO_UDP     17
+#if LWIP_IPV6
+#define IPPROTO_IPV6    41
+#define IPPROTO_ICMPV6  58
+#endif /* LWIP_IPV6 */
+#define IPPROTO_UDPLITE 136
+#define IPPROTO_RAW     255
+
+/* Flags we can use with send and recv. */
+#define MSG_PEEK       0x01    /* Peeks at an incoming message */
+#define MSG_WAITALL    0x02    /* Unimplemented: Requests that the function block until the full amount of data requested can be returned */
+#define MSG_OOB        0x04    /* Unimplemented: Requests out-of-band data. The significance and semantics of out-of-band data are protocol-specific */
+#define MSG_DONTWAIT   0x08    /* Nonblocking i/o for this operation only */
+#define MSG_MORE       0x10    /* Sender will send more */
+#define MSG_NOSIGNAL   0x20    /* Uninmplemented: Requests not to send the SIGPIPE signal if an attempt to send is made on a stream-oriented socket that is no longer connected. */
+
+
+/*
+ * Options for level IPPROTO_IP
+ */
+#define IP_TOS             1
+#define IP_TTL             2
+#define IP_PKTINFO         8
+
+#if LWIP_TCP
+/*
+ * Options for level IPPROTO_TCP
+ */
+#define TCP_NODELAY    0x01    /* don't delay send to coalesce packets */
+#define TCP_KEEPALIVE  0x02    /* send KEEPALIVE probes when idle for pcb->keep_idle milliseconds */
+#define TCP_KEEPIDLE   0x03    /* set pcb->keep_idle  - Same as TCP_KEEPALIVE, but use seconds for get/setsockopt */
+#define TCP_KEEPINTVL  0x04    /* set pcb->keep_intvl - Use seconds for get/setsockopt */
+#define TCP_KEEPCNT    0x05    /* set pcb->keep_cnt   - Use number of probes sent for get/setsockopt */
+#endif /* LWIP_TCP */
+
+#if LWIP_IPV6
+/*
+ * Options for level IPPROTO_IPV6
+ */
+#define IPV6_CHECKSUM       7  /* RFC3542: calculate and insert the ICMPv6 checksum for raw sockets. */
+#define IPV6_V6ONLY         27 /* RFC3493: boolean control to restrict AF_INET6 sockets to IPv6 communications only. */
+#endif /* LWIP_IPV6 */
+
+#if LWIP_UDP && LWIP_UDPLITE
+/*
+ * Options for level IPPROTO_UDPLITE
+ */
+#define UDPLITE_SEND_CSCOV 0x01 /* sender checksum coverage */
+#define UDPLITE_RECV_CSCOV 0x02 /* minimal receiver checksum coverage */
+#endif /* LWIP_UDP && LWIP_UDPLITE*/
+
+
+#if LWIP_MULTICAST_TX_OPTIONS
+/*
+ * Options and types for UDP multicast traffic handling
+ */
+#define IP_MULTICAST_TTL   5
+#define IP_MULTICAST_IF    6
+#define IP_MULTICAST_LOOP  7
+#endif /* LWIP_MULTICAST_TX_OPTIONS */
+
+#if LWIP_IGMP
+/*
+ * Options and types related to multicast membership
+ */
+#define IP_ADD_MEMBERSHIP  3
+#define IP_DROP_MEMBERSHIP 4
+
+typedef struct ip_mreq {
+    struct in_addr imr_multiaddr; /* IP multicast address of group */
+    struct in_addr imr_interface; /* local IP address of interface */
+} ip_mreq;
+#endif /* LWIP_IGMP */
+
+#if LWIP_IPV4
+struct in_pktinfo {
+  unsigned int   ipi_ifindex;  /* Interface index */
+  struct in_addr ipi_addr;     /* Destination (from header) address */
+};
+#endif /* LWIP_IPV4 */
+
+#if LWIP_IPV6_MLD
+/*
+ * Options and types related to IPv6 multicast membership
+ */
+#define IPV6_JOIN_GROUP      12
+#define IPV6_ADD_MEMBERSHIP  IPV6_JOIN_GROUP
+#define IPV6_LEAVE_GROUP     13
+#define IPV6_DROP_MEMBERSHIP IPV6_LEAVE_GROUP
+
+typedef struct ipv6_mreq {
+  struct in6_addr ipv6mr_multiaddr; /*  IPv6 multicast addr */
+  unsigned int    ipv6mr_interface; /*  interface index, or 0 */
+} ipv6_mreq;
+#endif /* LWIP_IPV6_MLD */
+
+/*
+ * The Type of Service provides an indication of the abstract
+ * parameters of the quality of service desired.  These parameters are
+ * to be used to guide the selection of the actual service parameters
+ * when transmitting a datagram through a particular network.  Several
+ * networks offer service precedence, which somehow treats high
+ * precedence traffic as more important than other traffic (generally
+ * by accepting only traffic above a certain precedence at time of high
+ * load).  The major choice is a three way tradeoff between low-delay,
+ * high-reliability, and high-throughput.
+ * The use of the Delay, Throughput, and Reliability indications may
+ * increase the cost (in some sense) of the service.  In many networks
+ * better performance for one of these parameters is coupled with worse
+ * performance on another.  Except for very unusual cases at most two
+ * of these three indications should be set.
+ */
+#define IPTOS_TOS_MASK          0x1E
+#define IPTOS_TOS(tos)          ((tos) & IPTOS_TOS_MASK)
+#define IPTOS_LOWDELAY          0x10
+#define IPTOS_THROUGHPUT        0x08
+#define IPTOS_RELIABILITY       0x04
+#define IPTOS_LOWCOST           0x02
+#define IPTOS_MINCOST           IPTOS_LOWCOST
+
+/*
+ * The Network Control precedence designation is intended to be used
+ * within a network only.  The actual use and control of that
+ * designation is up to each network. The Internetwork Control
+ * designation is intended for use by gateway control originators only.
+ * If the actual use of these precedence designations is of concern to
+ * a particular network, it is the responsibility of that network to
+ * control the access to, and use of, those precedence designations.
+ */
+#define IPTOS_PREC_MASK                 0xe0
+#define IPTOS_PREC(tos)                ((tos) & IPTOS_PREC_MASK)
+#define IPTOS_PREC_NETCONTROL           0xe0
+#define IPTOS_PREC_INTERNETCONTROL      0xc0
+#define IPTOS_PREC_CRITIC_ECP           0xa0
+#define IPTOS_PREC_FLASHOVERRIDE        0x80
+#define IPTOS_PREC_FLASH                0x60
+#define IPTOS_PREC_IMMEDIATE            0x40
+#define IPTOS_PREC_PRIORITY             0x20
+#define IPTOS_PREC_ROUTINE              0x00
+
+
+/*
+ * Commands for ioctlsocket(),  taken from the BSD file fcntl.h.
+ * lwip_ioctl only supports FIONREAD and FIONBIO, for now
+ *
+ * Ioctl's have the command encoded in the lower word,
+ * and the size of any in or out parameters in the upper
+ * word.  The high 2 bits of the upper word are used
+ * to encode the in/out status of the parameter; for now
+ * we restrict parameters to at most 128 bytes.
+ */
+#if !defined(FIONREAD) || !defined(FIONBIO)
+#define IOCPARM_MASK    0x7fU           /* parameters must be < 128 bytes */
+#define IOC_VOID        0x20000000UL    /* no parameters */
+#define IOC_OUT         0x40000000UL    /* copy out parameters */
+#define IOC_IN          0x80000000UL    /* copy in parameters */
+#define IOC_INOUT       (IOC_IN|IOC_OUT)
+                                        /* 0x20000000 distinguishes new &
+                                           old ioctl's */
+#define _IO(x,y)        ((long)(IOC_VOID|((x)<<8)|(y)))
+
+#define _IOR(x,y,t)     ((long)(IOC_OUT|((sizeof(t)&IOCPARM_MASK)<<16)|((x)<<8)|(y)))
+
+#define _IOW(x,y,t)     ((long)(IOC_IN|((sizeof(t)&IOCPARM_MASK)<<16)|((x)<<8)|(y)))
+#endif /* !defined(FIONREAD) || !defined(FIONBIO) */
+
+#ifndef FIONREAD
+#define FIONREAD    _IOR('f', 127, unsigned long) /* get # bytes to read */
+#endif
+#ifndef FIONBIO
+#define FIONBIO     _IOW('f', 126, unsigned long) /* set/clear non-blocking i/o */
+#endif
+
+/* Socket I/O Controls: unimplemented */
+#ifndef SIOCSHIWAT
+#define SIOCSHIWAT  _IOW('s',  0, unsigned long)  /* set high watermark */
+#define SIOCGHIWAT  _IOR('s',  1, unsigned long)  /* get high watermark */
+#define SIOCSLOWAT  _IOW('s',  2, unsigned long)  /* set low watermark */
+#define SIOCGLOWAT  _IOR('s',  3, unsigned long)  /* get low watermark */
+#define SIOCATMARK  _IOR('s',  7, unsigned long)  /* at oob mark? */
+#endif
+
+#define SIOCGIFCONF     0x8912
+#define SIOCGIFFLAGS    0x8913
+#define SIOCGIFADDR     0x8915
+#define SIOCGIFHWADDR   0x8927
+
+struct ifconf {
+    int                 ifc_len;
+    union {
+        char           *ifc_buf;
+        struct ifreq   *ifc_req;
+    };
+};
+
+/* commands for fnctl */
+#ifndef F_GETFL
+#define F_GETFL 3
+#endif
+#ifndef F_SETFL
+#define F_SETFL 4
+#endif
+
+/* File status flags and file access modes for fnctl,
+   these are bits in an int. */
+#ifndef O_NONBLOCK
+#define O_NONBLOCK  1 /* nonblocking I/O */
+#endif
+#ifndef O_NDELAY
+#define O_NDELAY    O_NONBLOCK /* same as O_NONBLOCK, for compatibility */
+#endif
+#ifndef O_RDONLY
+#define O_RDONLY    2
+#endif
+#ifndef O_WRONLY
+#define O_WRONLY    4
+#endif
+#ifndef O_RDWR
+#define O_RDWR      (O_RDONLY|O_WRONLY)
+#endif
+
+#ifndef SHUT_RD
+  #define SHUT_RD   0
+  #define SHUT_WR   1
+  #define SHUT_RDWR 2
+#endif
+
+/* FD_SET used for lwip_select */
+#ifndef FD_SET
+#undef  FD_SETSIZE
+/* Make FD_SETSIZE match NUM_SOCKETS in socket.c */
+#define FD_SETSIZE    MEMP_NUM_NETCONN
+#define LWIP_SELECT_MAXNFDS (FD_SETSIZE + LWIP_SOCKET_OFFSET)
+#define FDSETSAFESET(n, code) do { \
+  if (((n) - LWIP_SOCKET_OFFSET < MEMP_NUM_NETCONN) && (((int)(n) - LWIP_SOCKET_OFFSET) >= 0)) { \
+  code; }} while(0)
+#define FDSETSAFEGET(n, code) (((n) - LWIP_SOCKET_OFFSET < MEMP_NUM_NETCONN) && (((int)(n) - LWIP_SOCKET_OFFSET) >= 0) ?\
+  (code) : 0)
+#define FD_SET(n, p)  FDSETSAFESET(n, (p)->fd_bits[((n)-LWIP_SOCKET_OFFSET)/8] = (u8_t)((p)->fd_bits[((n)-LWIP_SOCKET_OFFSET)/8] |  (1 << (((n)-LWIP_SOCKET_OFFSET) & 7))))
+#define FD_CLR(n, p)  FDSETSAFESET(n, (p)->fd_bits[((n)-LWIP_SOCKET_OFFSET)/8] = (u8_t)((p)->fd_bits[((n)-LWIP_SOCKET_OFFSET)/8] & ~(1 << (((n)-LWIP_SOCKET_OFFSET) & 7))))
+#define FD_ISSET(n,p) FDSETSAFEGET(n, (p)->fd_bits[((n)-LWIP_SOCKET_OFFSET)/8] &   (1 << (((n)-LWIP_SOCKET_OFFSET) & 7)))
+#define FD_ZERO(p)    memset((void*)(p), 0, sizeof(*(p)))
+
+typedef struct fd_set
+{
+  unsigned char fd_bits [(FD_SETSIZE+7)/8];
+} fd_set;
+
+#elif FD_SETSIZE < (LWIP_SOCKET_OFFSET + MEMP_NUM_NETCONN)
+#error "external FD_SETSIZE too small for number of sockets"
+#else
+#define LWIP_SELECT_MAXNFDS FD_SETSIZE
+#endif /* FD_SET */
+
+/* poll-related defines and types */
+/* @todo: find a better way to guard the definition of these defines and types if already defined */
+#if !defined(POLLIN) && !defined(POLLOUT)
+#define POLLIN     0x1
+#define POLLOUT    0x2
+#define POLLERR    0x4
+#define POLLNVAL   0x8
+/* Below values are unimplemented */
+#define POLLRDNORM 0x10
+#define POLLRDBAND 0x20
+#define POLLPRI    0x40
+#define POLLWRNORM 0x80
+#define POLLWRBAND 0x100
+#define POLLHUP    0x200
+typedef unsigned int nfds_t;
+struct pollfd
+{
+  int fd;
+  short events;
+  short revents;
+};
+#endif
+
+/** LWIP_TIMEVAL_PRIVATE: if you want to use the struct timeval provided
+ * by your system, set this to 0 and include <sys/time.h> in cc.h */
+#ifndef LWIP_TIMEVAL_PRIVATE
+#define LWIP_TIMEVAL_PRIVATE 1
+#endif
+
+#if LWIP_TIMEVAL_PRIVATE
+struct timeval {
+  long    tv_sec;         /* seconds */
+  long    tv_usec;        /* and microseconds */
+};
+#endif /* LWIP_TIMEVAL_PRIVATE */
+
+#define lwip_socket_init() /* Compatibility define, no init needed. */
+void lwip_socket_thread_init(void); /* LWIP_NETCONN_SEM_PER_THREAD==1: initialize thread-local semaphore */
+void lwip_socket_thread_cleanup(void); /* LWIP_NETCONN_SEM_PER_THREAD==1: destroy thread-local semaphore */
+
+#if LWIP_COMPAT_SOCKETS == 2
+/* This helps code parsers/code completion by not having the COMPAT functions as defines */
+#define lwip_accept       accept
+#define lwip_bind         bind
+#define lwip_shutdown     shutdown
+#define lwip_getpeername  getpeername
+#define lwip_getsockname  getsockname
+#define lwip_setsockopt   setsockopt
+#define lwip_getsockopt   getsockopt
+#define lwip_close        closesocket
+#define lwip_connect      connect
+#define lwip_listen       listen
+#define lwip_recv         recv
+#define lwip_recvmsg      recvmsg
+#define lwip_recvfrom     recvfrom
+#define lwip_send         send
+#define lwip_sendmsg      sendmsg
+#define lwip_sendto       sendto
+#define lwip_socket       socket
+#if LWIP_SOCKET_SELECT
+#define lwip_select       select
+#endif
+#if LWIP_SOCKET_POLL
+#define lwip_poll         poll
+#endif
+#define lwip_ioctl        ioctlsocket
+#define lwip_inet_ntop    inet_ntop
+#define lwip_inet_pton    inet_pton
+
+#if LWIP_POSIX_SOCKETS_IO_NAMES
+#define lwip_read         read
+#define lwip_readv        readv
+#define lwip_write        write
+#define lwip_writev       writev
+#undef lwip_close
+#define lwip_close        close
+#define closesocket(s)    close(s)
+int fcntl(int s, int cmd, int val);
+#undef lwip_ioctl
+#define lwip_ioctl        ioctl
+#define ioctlsocket       ioctl
+#endif /* LWIP_POSIX_SOCKETS_IO_NAMES */
+#endif /* LWIP_COMPAT_SOCKETS == 2 */
+
+int lwip_accept(int s, struct sockaddr *addr, socklen_t *addrlen);
+int lwip_bind(int s, const struct sockaddr *name, socklen_t namelen);
+int lwip_shutdown(int s, int how);
+int lwip_getpeername (int s, struct sockaddr *name, socklen_t *namelen);
+int lwip_getsockname (int s, struct sockaddr *name, socklen_t *namelen);
+int lwip_getsockopt (int s, int level, int optname, void *optval, socklen_t *optlen);
+int lwip_setsockopt (int s, int level, int optname, const void *optval, socklen_t optlen);
+ int lwip_close(int s);
+int lwip_connect(int s, const struct sockaddr *name, socklen_t namelen);
+int lwip_listen(int s, int backlog);
+ssize_t lwip_recv(int s, void *mem, size_t len, int flags);
+ssize_t lwip_read(int s, void *mem, size_t len);
+ssize_t lwip_readv(int s, const struct iovec *iov, int iovcnt);
+ssize_t lwip_recvfrom(int s, void *mem, size_t len, int flags,
+      struct sockaddr *from, socklen_t *fromlen);
+ssize_t lwip_recvmsg(int s, struct msghdr *message, int flags);
+ssize_t lwip_send(int s, const void *dataptr, size_t size, int flags);
+ssize_t lwip_sendmsg(int s, const struct msghdr *message, int flags);
+ssize_t lwip_sendto(int s, const void *dataptr, size_t size, int flags,
+    const struct sockaddr *to, socklen_t tolen);
+int lwip_socket(int domain, int type, int protocol);
+ssize_t lwip_write(int s, const void *dataptr, size_t size);
+ssize_t lwip_writev(int s, const struct iovec *iov, int iovcnt);
+#if LWIP_SOCKET_SELECT
+int lwip_select(int maxfdp1, fd_set *readset, fd_set *writeset, fd_set *exceptset,
+                struct timeval *timeout);
+#endif
+#if LWIP_SOCKET_POLL
+int lwip_poll(struct pollfd *fds, nfds_t nfds, int timeout);
+#endif
+int lwip_ioctl(int s, long cmd, void *argp);
+int lwip_fcntl(int s, int cmd, int val);
+const char *lwip_inet_ntop(int af, const void *src, char *dst, socklen_t size);
+int lwip_inet_pton(int af, const char *src, void *dst);
+
+#if LWIP_COMPAT_SOCKETS
+#if LWIP_COMPAT_SOCKETS != 2
+/** @ingroup socket */
+#define accept(s,addr,addrlen)                    lwip_accept(s,addr,addrlen)
+/** @ingroup socket */
+#define bind(s,name,namelen)                      lwip_bind(s,name,namelen)
+/** @ingroup socket */
+#define shutdown(s,how)                           lwip_shutdown(s,how)
+/** @ingroup socket */
+#define getpeername(s,name,namelen)               lwip_getpeername(s,name,namelen)
+/** @ingroup socket */
+#define getsockname(s,name,namelen)               lwip_getsockname(s,name,namelen)
+/** @ingroup socket */
+#define setsockopt(s,level,optname,opval,optlen)  lwip_setsockopt(s,level,optname,opval,optlen)
+/** @ingroup socket */
+#define getsockopt(s,level,optname,opval,optlen)  lwip_getsockopt(s,level,optname,opval,optlen)
+/** @ingroup socket */
+#define closesocket(s)                            lwip_close(s)
+/** @ingroup socket */
+#define connect(s,name,namelen)                   lwip_connect(s,name,namelen)
+/** @ingroup socket */
+#define listen(s,backlog)                         lwip_listen(s,backlog)
+/** @ingroup socket */
+#define recv(s,mem,len,flags)                     lwip_recv(s,mem,len,flags)
+/** @ingroup socket */
+#define recvmsg(s,message,flags)                  lwip_recvmsg(s,message,flags)
+/** @ingroup socket */
+#define recvfrom(s,mem,len,flags,from,fromlen)    lwip_recvfrom(s,mem,len,flags,from,fromlen)
+/** @ingroup socket */
+#define send(s,dataptr,size,flags)                lwip_send(s,dataptr,size,flags)
+/** @ingroup socket */
+#define sendmsg(s,message,flags)                  lwip_sendmsg(s,message,flags)
+/** @ingroup socket */
+#define sendto(s,dataptr,size,flags,to,tolen)     lwip_sendto(s,dataptr,size,flags,to,tolen)
+/** @ingroup socket */
+#define socket(domain,type,protocol)              lwip_socket(domain,type,protocol)
+#if LWIP_SOCKET_SELECT
+/** @ingroup socket */
+#define select(maxfdp1,readset,writeset,exceptset,timeout)     lwip_select(maxfdp1,readset,writeset,exceptset,timeout)
+#endif
+#if LWIP_SOCKET_POLL
+/** @ingroup socket */
+#define poll(fds,nfds,timeout)                    lwip_poll(fds,nfds,timeout)
+#endif
+/** @ingroup socket */
+#define ioctlsocket(s,cmd,argp)                   lwip_ioctl(s,cmd,argp)
+/** @ingroup socket */
+#define inet_ntop(af,src,dst,size)                lwip_inet_ntop(af,src,dst,size)
+/** @ingroup socket */
+#define inet_pton(af,src,dst)                     lwip_inet_pton(af,src,dst)
+
+#if LWIP_POSIX_SOCKETS_IO_NAMES
+/** @ingroup socket */
+#define read(s,mem,len)                           lwip_read(s,mem,len)
+/** @ingroup socket */
+#define readv(s,iov,iovcnt)                       lwip_readv(s,iov,iovcnt)
+/** @ingroup socket */
+#define write(s,dataptr,len)                      lwip_write(s,dataptr,len)
+/** @ingroup socket */
+#define writev(s,iov,iovcnt)                      lwip_writev(s,iov,iovcnt)
+/** @ingroup socket */
+#define close(s)                                  lwip_close(s)
+/** @ingroup socket */
+#define fcntl(s,cmd,val)                          lwip_fcntl(s,cmd,val)
+/** @ingroup socket */
+#define ioctl(s,cmd,argp)                         lwip_ioctl(s,cmd,argp)
+#endif /* LWIP_POSIX_SOCKETS_IO_NAMES */
+#endif /* LWIP_COMPAT_SOCKETS != 2 */
+
+#endif /* LWIP_COMPAT_SOCKETS */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LWIP_SOCKET */
+
+#endif /* LWIP_HDR_SOCKETS_H */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/stats.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/stats.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/stats.h	(revision 457)
@@ -0,0 +1,491 @@
+/**
+ * @file
+ * Statistics API (to be used from TCPIP thread)
+ */
+
+/*
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Adam Dunkels <adam@sics.se>
+ *
+ */
+#ifndef LWIP_HDR_STATS_H
+#define LWIP_HDR_STATS_H
+
+#include "lwip/opt.h"
+
+#include "lwip/mem.h"
+#include "lwip/memp.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if LWIP_STATS
+
+#ifndef LWIP_STATS_LARGE
+#define LWIP_STATS_LARGE 0
+#endif
+
+#if LWIP_STATS_LARGE
+#define STAT_COUNTER     u32_t
+#define STAT_COUNTER_F   U32_F
+#else
+#define STAT_COUNTER     u16_t
+#define STAT_COUNTER_F   U16_F
+#endif
+
+/** Protocol related stats */
+struct stats_proto {
+  STAT_COUNTER xmit;             /* Transmitted packets. */
+  STAT_COUNTER recv;             /* Received packets. */
+  STAT_COUNTER fw;               /* Forwarded packets. */
+  STAT_COUNTER drop;             /* Dropped packets. */
+  STAT_COUNTER chkerr;           /* Checksum error. */
+  STAT_COUNTER lenerr;           /* Invalid length error. */
+  STAT_COUNTER memerr;           /* Out of memory error. */
+  STAT_COUNTER rterr;            /* Routing error. */
+  STAT_COUNTER proterr;          /* Protocol error. */
+  STAT_COUNTER opterr;           /* Error in options. */
+  STAT_COUNTER err;              /* Misc error. */
+  STAT_COUNTER cachehit;
+};
+
+/** IGMP stats */
+struct stats_igmp {
+  STAT_COUNTER xmit;             /* Transmitted packets. */
+  STAT_COUNTER recv;             /* Received packets. */
+  STAT_COUNTER drop;             /* Dropped packets. */
+  STAT_COUNTER chkerr;           /* Checksum error. */
+  STAT_COUNTER lenerr;           /* Invalid length error. */
+  STAT_COUNTER memerr;           /* Out of memory error. */
+  STAT_COUNTER proterr;          /* Protocol error. */
+  STAT_COUNTER rx_v1;            /* Received v1 frames. */
+  STAT_COUNTER rx_group;         /* Received group-specific queries. */
+  STAT_COUNTER rx_general;       /* Received general queries. */
+  STAT_COUNTER rx_report;        /* Received reports. */
+  STAT_COUNTER tx_join;          /* Sent joins. */
+  STAT_COUNTER tx_leave;         /* Sent leaves. */
+  STAT_COUNTER tx_report;        /* Sent reports. */
+};
+
+/** Memory stats */
+struct stats_mem {
+#if defined(LWIP_DEBUG) || LWIP_STATS_DISPLAY
+  const char *name;
+#endif /* defined(LWIP_DEBUG) || LWIP_STATS_DISPLAY */
+  STAT_COUNTER err;
+  mem_size_t avail;
+  mem_size_t used;
+  mem_size_t max;
+  STAT_COUNTER illegal;
+};
+
+/** System element stats */
+struct stats_syselem {
+  STAT_COUNTER used;
+  STAT_COUNTER max;
+  STAT_COUNTER err;
+};
+
+/** System stats */
+struct stats_sys {
+  struct stats_syselem sem;
+  struct stats_syselem mutex;
+  struct stats_syselem mbox;
+};
+
+/** SNMP MIB2 stats */
+struct stats_mib2 {
+  /* IP */
+  u32_t ipinhdrerrors;
+  u32_t ipinaddrerrors;
+  u32_t ipinunknownprotos;
+  u32_t ipindiscards;
+  u32_t ipindelivers;
+  u32_t ipoutrequests;
+  u32_t ipoutdiscards;
+  u32_t ipoutnoroutes;
+  u32_t ipreasmoks;
+  u32_t ipreasmfails;
+  u32_t ipfragoks;
+  u32_t ipfragfails;
+  u32_t ipfragcreates;
+  u32_t ipreasmreqds;
+  u32_t ipforwdatagrams;
+  u32_t ipinreceives;
+
+  /* TCP */
+  u32_t tcpactiveopens;
+  u32_t tcppassiveopens;
+  u32_t tcpattemptfails;
+  u32_t tcpestabresets;
+  u32_t tcpoutsegs;
+  u32_t tcpretranssegs;
+  u32_t tcpinsegs;
+  u32_t tcpinerrs;
+  u32_t tcpoutrsts;
+
+  /* UDP */
+  u32_t udpindatagrams;
+  u32_t udpnoports;
+  u32_t udpinerrors;
+  u32_t udpoutdatagrams;
+
+  /* ICMP */
+  u32_t icmpinmsgs;
+  u32_t icmpinerrors;
+  u32_t icmpindestunreachs;
+  u32_t icmpintimeexcds;
+  u32_t icmpinparmprobs;
+  u32_t icmpinsrcquenchs;
+  u32_t icmpinredirects;
+  u32_t icmpinechos;
+  u32_t icmpinechoreps;
+  u32_t icmpintimestamps;
+  u32_t icmpintimestampreps;
+  u32_t icmpinaddrmasks;
+  u32_t icmpinaddrmaskreps;
+  u32_t icmpoutmsgs;
+  u32_t icmpouterrors;
+  u32_t icmpoutdestunreachs;
+  u32_t icmpouttimeexcds;
+  u32_t icmpoutechos; /* can be incremented by user application ('ping') */
+  u32_t icmpoutechoreps;
+};
+
+/**
+ * @ingroup netif_mib2
+ * SNMP MIB2 interface stats
+ */
+struct stats_mib2_netif_ctrs {
+  /** The total number of octets received on the interface, including framing characters */
+  u32_t ifinoctets;
+  /** The number of packets, delivered by this sub-layer to a higher (sub-)layer, which were
+   * not addressed to a multicast or broadcast address at this sub-layer */
+  u32_t ifinucastpkts;
+  /** The number of packets, delivered by this sub-layer to a higher (sub-)layer, which were
+   * addressed to a multicast or broadcast address at this sub-layer */
+  u32_t ifinnucastpkts;
+  /** The number of inbound packets which were chosen to be discarded even though no errors had
+   * been detected to prevent their being deliverable to a higher-layer protocol. One possible
+   * reason for discarding such a packet could be to free up buffer space */
+  u32_t ifindiscards;
+  /** For packet-oriented interfaces, the number of inbound packets that contained errors
+   * preventing them from being deliverable to a higher-layer protocol.  For character-
+   * oriented or fixed-length interfaces, the number of inbound transmission units that
+   * contained errors preventing them from being deliverable to a higher-layer protocol. */
+  u32_t ifinerrors;
+  /** For packet-oriented interfaces, the number of packets received via the interface which
+   * were discarded because of an unknown or unsupported protocol.  For character-oriented
+   * or fixed-length interfaces that support protocol multiplexing the number of transmission
+   * units received via the interface which were discarded because of an unknown or unsupported
+   * protocol. For any interface that does not support protocol multiplexing, this counter will
+   * always be 0 */
+  u32_t ifinunknownprotos;
+  /** The total number of octets transmitted out of the interface, including framing characters. */
+  u32_t ifoutoctets;
+  /** The total number of packets that higher-level protocols requested be transmitted, and
+   * which were not addressed to a multicast or broadcast address at this sub-layer, including
+   * those that were discarded or not sent. */
+  u32_t ifoutucastpkts;
+  /** The total number of packets that higher-level protocols requested be transmitted, and which
+   * were addressed to a multicast or broadcast address at this sub-layer, including
+   * those that were discarded or not sent. */
+  u32_t ifoutnucastpkts;
+  /** The number of outbound packets which were chosen to be discarded even though no errors had
+   * been detected to prevent their being transmitted.  One possible reason for discarding
+   * such a packet could be to free up buffer space. */
+  u32_t ifoutdiscards;
+  /** For packet-oriented interfaces, the number of outbound packets that could not be transmitted
+   * because of errors. For character-oriented or fixed-length interfaces, the number of outbound
+   * transmission units that could not be transmitted because of errors. */
+  u32_t ifouterrors;
+};
+
+/** lwIP stats container */
+struct stats_ {
+#if LINK_STATS
+  /** Link level */
+  struct stats_proto link;
+#endif
+#if ETHARP_STATS
+  /** ARP */
+  struct stats_proto etharp;
+#endif
+#if IPFRAG_STATS
+  /** Fragmentation */
+  struct stats_proto ip_frag;
+#endif
+#if IP_STATS
+  /** IP */
+  struct stats_proto ip;
+#endif
+#if ICMP_STATS
+  /** ICMP */
+  struct stats_proto icmp;
+#endif
+#if IGMP_STATS
+  /** IGMP */
+  struct stats_igmp igmp;
+#endif
+#if UDP_STATS
+  /** UDP */
+  struct stats_proto udp;
+#endif
+#if TCP_STATS
+  /** TCP */
+  struct stats_proto tcp;
+#endif
+#if MEM_STATS
+  /** Heap */
+  struct stats_mem mem;
+#endif
+#if MEMP_STATS
+  /** Internal memory pools */
+  struct stats_mem *memp[MEMP_MAX];
+#endif
+#if SYS_STATS
+  /** System */
+  struct stats_sys sys;
+#endif
+#if IP6_STATS
+  /** IPv6 */
+  struct stats_proto ip6;
+#endif
+#if ICMP6_STATS
+  /** ICMP6 */
+  struct stats_proto icmp6;
+#endif
+#if IP6_FRAG_STATS
+  /** IPv6 fragmentation */
+  struct stats_proto ip6_frag;
+#endif
+#if MLD6_STATS
+  /** Multicast listener discovery */
+  struct stats_igmp mld6;
+#endif
+#if ND6_STATS
+  /** Neighbor discovery */
+  struct stats_proto nd6;
+#endif
+#if MIB2_STATS
+  /** SNMP MIB2 */
+  struct stats_mib2 mib2;
+#endif
+};
+
+/** Global variable containing lwIP internal statistics. Add this to your debugger's watchlist. */
+extern struct stats_ lwip_stats;
+
+/** Init statistics */
+void stats_init(void);
+
+#define STATS_INC(x) ++lwip_stats.x
+#define STATS_DEC(x) --lwip_stats.x
+#define STATS_INC_USED(x, y, type) do { lwip_stats.x.used = (type)(lwip_stats.x.used + y); \
+                                if (lwip_stats.x.max < lwip_stats.x.used) { \
+                                    lwip_stats.x.max = lwip_stats.x.used; \
+                                } \
+                             } while(0)
+#define STATS_GET(x) lwip_stats.x
+#else /* LWIP_STATS */
+#define stats_init()
+#define STATS_INC(x)
+#define STATS_DEC(x)
+#define STATS_INC_USED(x, y, type)
+#endif /* LWIP_STATS */
+
+#if TCP_STATS
+#define TCP_STATS_INC(x) STATS_INC(x)
+#define TCP_STATS_DISPLAY() stats_display_proto(&lwip_stats.tcp, "TCP")
+#else
+#define TCP_STATS_INC(x)
+#define TCP_STATS_DISPLAY()
+#endif
+
+#if UDP_STATS
+#define UDP_STATS_INC(x) STATS_INC(x)
+#define UDP_STATS_DISPLAY() stats_display_proto(&lwip_stats.udp, "UDP")
+#else
+#define UDP_STATS_INC(x)
+#define UDP_STATS_DISPLAY()
+#endif
+
+#if ICMP_STATS
+#define ICMP_STATS_INC(x) STATS_INC(x)
+#define ICMP_STATS_DISPLAY() stats_display_proto(&lwip_stats.icmp, "ICMP")
+#else
+#define ICMP_STATS_INC(x)
+#define ICMP_STATS_DISPLAY()
+#endif
+
+#if IGMP_STATS
+#define IGMP_STATS_INC(x) STATS_INC(x)
+#define IGMP_STATS_DISPLAY() stats_display_igmp(&lwip_stats.igmp, "IGMP")
+#else
+#define IGMP_STATS_INC(x)
+#define IGMP_STATS_DISPLAY()
+#endif
+
+#if IP_STATS
+#define IP_STATS_INC(x) STATS_INC(x)
+#define IP_STATS_DISPLAY() stats_display_proto(&lwip_stats.ip, "IP")
+#else
+#define IP_STATS_INC(x)
+#define IP_STATS_DISPLAY()
+#endif
+
+#if IPFRAG_STATS
+#define IPFRAG_STATS_INC(x) STATS_INC(x)
+#define IPFRAG_STATS_DISPLAY() stats_display_proto(&lwip_stats.ip_frag, "IP_FRAG")
+#else
+#define IPFRAG_STATS_INC(x)
+#define IPFRAG_STATS_DISPLAY()
+#endif
+
+#if ETHARP_STATS
+#define ETHARP_STATS_INC(x) STATS_INC(x)
+#define ETHARP_STATS_DISPLAY() stats_display_proto(&lwip_stats.etharp, "ETHARP")
+#else
+#define ETHARP_STATS_INC(x)
+#define ETHARP_STATS_DISPLAY()
+#endif
+
+#if LINK_STATS
+#define LINK_STATS_INC(x) STATS_INC(x)
+#define LINK_STATS_DISPLAY() stats_display_proto(&lwip_stats.link, "LINK")
+#else
+#define LINK_STATS_INC(x)
+#define LINK_STATS_DISPLAY()
+#endif
+
+#if MEM_STATS
+#define MEM_STATS_AVAIL(x, y) lwip_stats.mem.x = y
+#define MEM_STATS_INC(x) STATS_INC(mem.x)
+#define MEM_STATS_INC_USED(x, y) STATS_INC_USED(mem, y, mem_size_t)
+#define MEM_STATS_DEC_USED(x, y) lwip_stats.mem.x = (mem_size_t)((lwip_stats.mem.x) - (y))
+#define MEM_STATS_DISPLAY() stats_display_mem(&lwip_stats.mem, "HEAP")
+#else
+#define MEM_STATS_AVAIL(x, y)
+#define MEM_STATS_INC(x)
+#define MEM_STATS_INC_USED(x, y)
+#define MEM_STATS_DEC_USED(x, y)
+#define MEM_STATS_DISPLAY()
+#endif
+
+ #if MEMP_STATS
+#define MEMP_STATS_DEC(x, i) STATS_DEC(memp[i]->x)
+#define MEMP_STATS_DISPLAY(i) stats_display_memp(lwip_stats.memp[i], i)
+#define MEMP_STATS_GET(x, i) STATS_GET(memp[i]->x)
+ #else
+#define MEMP_STATS_DEC(x, i)
+#define MEMP_STATS_DISPLAY(i)
+#define MEMP_STATS_GET(x, i) 0
+#endif
+
+#if SYS_STATS
+#define SYS_STATS_INC(x) STATS_INC(sys.x)
+#define SYS_STATS_DEC(x) STATS_DEC(sys.x)
+#define SYS_STATS_INC_USED(x) STATS_INC_USED(sys.x, 1, STAT_COUNTER)
+#define SYS_STATS_DISPLAY() stats_display_sys(&lwip_stats.sys)
+#else
+#define SYS_STATS_INC(x)
+#define SYS_STATS_DEC(x)
+#define SYS_STATS_INC_USED(x)
+#define SYS_STATS_DISPLAY()
+#endif
+
+#if IP6_STATS
+#define IP6_STATS_INC(x) STATS_INC(x)
+#define IP6_STATS_DISPLAY() stats_display_proto(&lwip_stats.ip6, "IPv6")
+#else
+#define IP6_STATS_INC(x)
+#define IP6_STATS_DISPLAY()
+#endif
+
+#if ICMP6_STATS
+#define ICMP6_STATS_INC(x) STATS_INC(x)
+#define ICMP6_STATS_DISPLAY() stats_display_proto(&lwip_stats.icmp6, "ICMPv6")
+#else
+#define ICMP6_STATS_INC(x)
+#define ICMP6_STATS_DISPLAY()
+#endif
+
+#if IP6_FRAG_STATS
+#define IP6_FRAG_STATS_INC(x) STATS_INC(x)
+#define IP6_FRAG_STATS_DISPLAY() stats_display_proto(&lwip_stats.ip6_frag, "IPv6 FRAG")
+#else
+#define IP6_FRAG_STATS_INC(x)
+#define IP6_FRAG_STATS_DISPLAY()
+#endif
+
+#if MLD6_STATS
+#define MLD6_STATS_INC(x) STATS_INC(x)
+#define MLD6_STATS_DISPLAY() stats_display_igmp(&lwip_stats.mld6, "MLDv1")
+#else
+#define MLD6_STATS_INC(x)
+#define MLD6_STATS_DISPLAY()
+#endif
+
+#if ND6_STATS
+#define ND6_STATS_INC(x) STATS_INC(x)
+#define ND6_STATS_DISPLAY() stats_display_proto(&lwip_stats.nd6, "ND")
+#else
+#define ND6_STATS_INC(x)
+#define ND6_STATS_DISPLAY()
+#endif
+
+#if MIB2_STATS
+#define MIB2_STATS_INC(x) STATS_INC(x)
+#else
+#define MIB2_STATS_INC(x)
+#endif
+
+/* Display of statistics */
+#if LWIP_STATS_DISPLAY
+void stats_display(void);
+void stats_display_proto(struct stats_proto *proto, const char *name);
+void stats_display_igmp(struct stats_igmp *igmp, const char *name);
+void stats_display_mem(struct stats_mem *mem, const char *name);
+void stats_display_memp(struct stats_mem *mem, int index);
+void stats_display_sys(struct stats_sys *sys);
+#else /* LWIP_STATS_DISPLAY */
+#define stats_display()
+#define stats_display_proto(proto, name)
+#define stats_display_igmp(igmp, name)
+#define stats_display_mem(mem, name)
+#define stats_display_memp(mem, index)
+#define stats_display_sys(sys)
+#endif /* LWIP_STATS_DISPLAY */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LWIP_HDR_STATS_H */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/sys.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/sys.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/sys.h	(revision 457)
@@ -0,0 +1,560 @@
+/**
+ * @file
+ * OS abstraction layer
+ */
+
+/*
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Adam Dunkels <adam@sics.se>
+ */
+
+#ifndef LWIP_HDR_SYS_H
+#define LWIP_HDR_SYS_H
+
+#include "lwip/opt.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if NO_SYS
+
+/* For a totally minimal and standalone system, we provide null
+   definitions of the sys_ functions. */
+typedef u8_t sys_sem_t;
+typedef u8_t sys_mutex_t;
+typedef u8_t sys_mbox_t;
+
+#define sys_sem_new(s, c) ERR_OK
+#define sys_sem_signal(s)
+#define sys_sem_wait(s)
+#define sys_arch_sem_wait(s,t)
+#define sys_sem_free(s)
+#define sys_sem_valid(s) 0
+#define sys_sem_valid_val(s) 0
+#define sys_sem_set_invalid(s)
+#define sys_sem_set_invalid_val(s)
+#define sys_mutex_new(mu) ERR_OK
+#define sys_mutex_lock(mu)
+#define sys_mutex_unlock(mu)
+#define sys_mutex_free(mu)
+#define sys_mutex_valid(mu) 0
+#define sys_mutex_set_invalid(mu)
+#define sys_mbox_new(m, s) ERR_OK
+#define sys_mbox_fetch(m,d)
+#define sys_mbox_tryfetch(m,d)
+#define sys_mbox_post(m,d)
+#define sys_mbox_trypost(m,d)
+#define sys_mbox_free(m)
+#define sys_mbox_valid(m)
+#define sys_mbox_valid_val(m)
+#define sys_mbox_set_invalid(m)
+#define sys_mbox_set_invalid_val(m)
+
+#define sys_thread_new(n,t,a,s,p)
+
+#define sys_msleep(t)
+
+#else /* NO_SYS */
+
+/** Return code for timeouts from sys_arch_mbox_fetch and sys_arch_sem_wait */
+#define SYS_ARCH_TIMEOUT 0xffffffffUL
+
+/** sys_mbox_tryfetch() returns SYS_MBOX_EMPTY if appropriate.
+ * For now we use the same magic value, but we allow this to change in future.
+ */
+#define SYS_MBOX_EMPTY SYS_ARCH_TIMEOUT
+
+#include "lwip/err.h"
+#include "arch/sys_arch.h"
+
+/** Function prototype for thread functions */
+typedef void (*lwip_thread_fn)(void *arg);
+
+/* Function prototypes for functions to be implemented by platform ports
+   (in sys_arch.c) */
+
+/* Mutex functions: */
+
+/** Define LWIP_COMPAT_MUTEX if the port has no mutexes and binary semaphores
+    should be used instead */
+#ifndef LWIP_COMPAT_MUTEX
+#define LWIP_COMPAT_MUTEX 0
+#endif
+
+#if LWIP_COMPAT_MUTEX
+/* for old ports that don't have mutexes: define them to binary semaphores */
+#define sys_mutex_t                   sys_sem_t
+#define sys_mutex_new(mutex)          sys_sem_new(mutex, 1)
+#define sys_mutex_lock(mutex)         sys_sem_wait(mutex)
+#define sys_mutex_unlock(mutex)       sys_sem_signal(mutex)
+#define sys_mutex_free(mutex)         sys_sem_free(mutex)
+#define sys_mutex_valid(mutex)        sys_sem_valid(mutex)
+#define sys_mutex_set_invalid(mutex)  sys_sem_set_invalid(mutex)
+
+#else /* LWIP_COMPAT_MUTEX */
+
+/**
+ * @ingroup sys_mutex
+ * Create a new mutex.
+ * Note that mutexes are expected to not be taken recursively by the lwIP code,
+ * so both implementation types (recursive or non-recursive) should work.
+ * The mutex is allocated to the memory that 'mutex'
+ * points to (which can be both a pointer or the actual OS structure).
+ * If the mutex has been created, ERR_OK should be returned. Returning any
+ * other error will provide a hint what went wrong, but except for assertions,
+ * no real error handling is implemented.
+ * 
+ * @param mutex pointer to the mutex to create
+ * @return ERR_OK if successful, another err_t otherwise
+ */
+err_t sys_mutex_new(sys_mutex_t *mutex);
+/**
+ * @ingroup sys_mutex
+ * Blocks the thread until the mutex can be grabbed.
+ * @param mutex the mutex to lock
+ */
+void sys_mutex_lock(sys_mutex_t *mutex);
+/**
+ * @ingroup sys_mutex
+ * Releases the mutex previously locked through 'sys_mutex_lock()'.
+ * @param mutex the mutex to unlock
+ */
+void sys_mutex_unlock(sys_mutex_t *mutex);
+/**
+ * @ingroup sys_mutex
+ * Deallocates a mutex.
+ * @param mutex the mutex to delete
+ */
+void sys_mutex_free(sys_mutex_t *mutex);
+#ifndef sys_mutex_valid
+/**
+ * @ingroup sys_mutex
+ * Returns 1 if the mutes is valid, 0 if it is not valid.
+ * When using pointers, a simple way is to check the pointer for != NULL.
+ * When directly using OS structures, implementing this may be more complex.
+ * This may also be a define, in which case the function is not prototyped.
+ */
+int sys_mutex_valid(sys_mutex_t *mutex);
+#endif
+#ifndef sys_mutex_set_invalid
+/**
+ * @ingroup sys_mutex
+ * Invalidate a mutex so that sys_mutex_valid() returns 0.
+ * ATTENTION: This does NOT mean that the mutex shall be deallocated:
+ * sys_mutex_free() is always called before calling this function!
+ * This may also be a define, in which case the function is not prototyped.
+ */
+void sys_mutex_set_invalid(sys_mutex_t *mutex);
+#endif
+#endif /* LWIP_COMPAT_MUTEX */
+
+/* Semaphore functions: */
+
+/**
+ * @ingroup sys_sem
+ * Create a new semaphore
+ * Creates a new semaphore. The semaphore is allocated to the memory that 'sem'
+ * points to (which can be both a pointer or the actual OS structure).
+ * The "count" argument specifies the initial state of the semaphore (which is
+ * either 0 or 1).
+ * If the semaphore has been created, ERR_OK should be returned. Returning any
+ * other error will provide a hint what went wrong, but except for assertions,
+ * no real error handling is implemented.
+ *
+ * @param sem pointer to the semaphore to create
+ * @param count initial count of the semaphore
+ * @return ERR_OK if successful, another err_t otherwise
+ */
+err_t sys_sem_new(sys_sem_t *sem, u8_t count);
+/**
+ * @ingroup sys_sem
+ * Signals a semaphore
+ * @param sem the semaphore to signal
+ */
+void sys_sem_signal(sys_sem_t *sem);
+/**
+ * @ingroup sys_sem
+ *  Blocks the thread while waiting for the semaphore to be signaled. If the
+ * "timeout" argument is non-zero, the thread should only be blocked for the
+ * specified time (measured in milliseconds). If the "timeout" argument is zero,
+ * the thread should be blocked until the semaphore is signalled.
+ * 
+ * The return value is SYS_ARCH_TIMEOUT if the semaphore wasn't signaled within
+ * the specified time or any other value if it was signaled (with or without
+ * waiting).
+ * Notice that lwIP implements a function with a similar name,
+ * sys_sem_wait(), that uses the sys_arch_sem_wait() function.
+ * 
+ * @param sem the semaphore to wait for
+ * @param timeout timeout in milliseconds to wait (0 = wait forever)
+ * @return SYS_ARCH_TIMEOUT on timeout, any other value on success
+ */
+u32_t sys_arch_sem_wait(sys_sem_t *sem, u32_t timeout);
+/**
+ * @ingroup sys_sem
+ * Deallocates a semaphore.
+ * @param sem semaphore to delete
+ */
+void sys_sem_free(sys_sem_t *sem);
+/** Wait for a semaphore - forever/no timeout */
+#define sys_sem_wait(sem)                  sys_arch_sem_wait(sem, 0)
+#ifndef sys_sem_valid
+/**
+ * @ingroup sys_sem
+ * Returns 1 if the semaphore is valid, 0 if it is not valid.
+ * When using pointers, a simple way is to check the pointer for != NULL.
+ * When directly using OS structures, implementing this may be more complex.
+ * This may also be a define, in which case the function is not prototyped.
+ */
+int sys_sem_valid(sys_sem_t *sem);
+#endif
+#ifndef sys_sem_set_invalid
+/**
+ * @ingroup sys_sem
+ * Invalidate a semaphore so that sys_sem_valid() returns 0.
+ * ATTENTION: This does NOT mean that the semaphore shall be deallocated:
+ * sys_sem_free() is always called before calling this function!
+ * This may also be a define, in which case the function is not prototyped.
+ */
+void sys_sem_set_invalid(sys_sem_t *sem);
+#endif
+#ifndef sys_sem_valid_val
+/**
+ * Same as sys_sem_valid() but taking a value, not a pointer
+ */
+#define sys_sem_valid_val(sem)       sys_sem_valid(&(sem))
+#endif
+#ifndef sys_sem_set_invalid_val
+/**
+ * Same as sys_sem_set_invalid() but taking a value, not a pointer
+ */
+#define sys_sem_set_invalid_val(sem) sys_sem_set_invalid(&(sem))
+#endif
+
+#ifndef sys_msleep
+/**
+ * @ingroup sys_misc
+ * Sleep for specified number of ms
+ */
+void sys_msleep(u32_t ms); /* only has a (close to) 1 ms resolution. */
+#endif
+
+/* Mailbox functions. */
+
+/**
+ * @ingroup sys_mbox
+ * Creates an empty mailbox for maximum "size" elements. Elements stored
+ * in mailboxes are pointers. You have to define macros "_MBOX_SIZE"
+ * in your lwipopts.h, or ignore this parameter in your implementation
+ * and use a default size.
+ * If the mailbox has been created, ERR_OK should be returned. Returning any
+ * other error will provide a hint what went wrong, but except for assertions,
+ * no real error handling is implemented.
+ * 
+ * @param mbox pointer to the mbox to create
+ * @param size (minimum) number of messages in this mbox
+ * @return ERR_OK if successful, another err_t otherwise
+ */
+err_t sys_mbox_new(sys_mbox_t *mbox, int size);
+/**
+ * @ingroup sys_mbox
+ * Post a message to an mbox - may not fail
+ * -> blocks if full, only to be used from tasks NOT from ISR!
+ * 
+ * @param mbox mbox to posts the message
+ * @param msg message to post (ATTENTION: can be NULL)
+ */
+void sys_mbox_post(sys_mbox_t *mbox, void *msg);
+/**
+ * @ingroup sys_mbox
+ * Try to post a message to an mbox - may fail if full.
+ * Can be used from ISR (if the sys arch layer allows this).
+ * Returns ERR_MEM if it is full, else, ERR_OK if the "msg" is posted.
+ * 
+ * @param mbox mbox to posts the message
+ * @param msg message to post (ATTENTION: can be NULL)
+ */
+err_t sys_mbox_trypost(sys_mbox_t *mbox, void *msg);
+/**
+ * @ingroup sys_mbox
+ * Try to post a message to an mbox - may fail if full.
+ * To be be used from ISR.
+ * Returns ERR_MEM if it is full, else, ERR_OK if the "msg" is posted.
+ * 
+ * @param mbox mbox to posts the message
+ * @param msg message to post (ATTENTION: can be NULL)
+ */
+err_t sys_mbox_trypost_fromisr(sys_mbox_t *mbox, void *msg);
+/**
+ * @ingroup sys_mbox
+ * Blocks the thread until a message arrives in the mailbox, but does
+ * not block the thread longer than "timeout" milliseconds (similar to
+ * the sys_arch_sem_wait() function). If "timeout" is 0, the thread should
+ * be blocked until a message arrives. The "msg" argument is a result
+ * parameter that is set by the function (i.e., by doing "*msg =
+ * ptr"). The "msg" parameter maybe NULL to indicate that the message
+ * should be dropped.
+ * The return values are the same as for the sys_arch_sem_wait() function:
+ * SYS_ARCH_TIMEOUT if there was a timeout, any other value if a messages
+ * is received.
+ * 
+ * Note that a function with a similar name, sys_mbox_fetch(), is
+ * implemented by lwIP. 
+ * 
+ * @param mbox mbox to get a message from
+ * @param msg pointer where the message is stored
+ * @param timeout maximum time (in milliseconds) to wait for a message (0 = wait forever)
+ * @return SYS_ARCH_TIMEOUT on timeout, any other value if a message has been received
+ */
+u32_t sys_arch_mbox_fetch(sys_mbox_t *mbox, void **msg, u32_t timeout);
+/* Allow port to override with a macro, e.g. special timeout for sys_arch_mbox_fetch() */
+#ifndef sys_arch_mbox_tryfetch
+/**
+ * @ingroup sys_mbox
+ * This is similar to sys_arch_mbox_fetch, however if a message is not
+ * present in the mailbox, it immediately returns with the code
+ * SYS_MBOX_EMPTY. On success 0 is returned.
+ * To allow for efficient implementations, this can be defined as a
+ * function-like macro in sys_arch.h instead of a normal function. For
+ * example, a naive implementation could be:
+ * \#define sys_arch_mbox_tryfetch(mbox,msg) sys_arch_mbox_fetch(mbox,msg,1)
+ * although this would introduce unnecessary delays.
+ * 
+ * @param mbox mbox to get a message from
+ * @param msg pointer where the message is stored
+ * @return 0 (milliseconds) if a message has been received
+ *         or SYS_MBOX_EMPTY if the mailbox is empty
+ */
+u32_t sys_arch_mbox_tryfetch(sys_mbox_t *mbox, void **msg);
+#endif
+/**
+ * For now, we map straight to sys_arch implementation.
+ */
+#define sys_mbox_tryfetch(mbox, msg) sys_arch_mbox_tryfetch(mbox, msg)
+/**
+ * @ingroup sys_mbox
+ * Deallocates a mailbox. If there are messages still present in the
+ * mailbox when the mailbox is deallocated, it is an indication of a
+ * programming error in lwIP and the developer should be notified.
+ * 
+ * @param mbox mbox to delete
+ */
+void sys_mbox_free(sys_mbox_t *mbox);
+#define sys_mbox_fetch(mbox, msg) sys_arch_mbox_fetch(mbox, msg, 0)
+#ifndef sys_mbox_valid
+/**
+ * @ingroup sys_mbox
+ * Returns 1 if the mailbox is valid, 0 if it is not valid.
+ * When using pointers, a simple way is to check the pointer for != NULL.
+ * When directly using OS structures, implementing this may be more complex.
+ * This may also be a define, in which case the function is not prototyped.
+ */
+int sys_mbox_valid(sys_mbox_t *mbox);
+#endif
+#ifndef sys_mbox_set_invalid
+/**
+ * @ingroup sys_mbox
+ * Invalidate a mailbox so that sys_mbox_valid() returns 0.
+ * ATTENTION: This does NOT mean that the mailbox shall be deallocated:
+ * sys_mbox_free() is always called before calling this function!
+ * This may also be a define, in which case the function is not prototyped.
+ */
+void sys_mbox_set_invalid(sys_mbox_t *mbox);
+#endif
+#ifndef sys_mbox_valid_val
+/**
+ * Same as sys_mbox_valid() but taking a value, not a pointer
+ */
+#define sys_mbox_valid_val(mbox)       sys_mbox_valid(&(mbox))
+#endif
+#ifndef sys_mbox_set_invalid_val
+/**
+ * Same as sys_mbox_set_invalid() but taking a value, not a pointer
+ */
+#define sys_mbox_set_invalid_val(mbox) sys_mbox_set_invalid(&(mbox))
+#endif
+
+
+/**
+ * @ingroup sys_misc
+ * The only thread function:
+ * Starts a new thread named "name" with priority "prio" that will begin its
+ * execution in the function "thread()". The "arg" argument will be passed as an
+ * argument to the thread() function. The stack size to used for this thread is
+ * the "stacksize" parameter. The id of the new thread is returned. Both the id
+ * and the priority are system dependent.
+ * ATTENTION: although this function returns a value, it MUST NOT FAIL (ports have to assert this!)
+ * 
+ * @param name human-readable name for the thread (used for debugging purposes)
+ * @param thread thread-function
+ * @param arg parameter passed to 'thread'
+ * @param stacksize stack size in bytes for the new thread (may be ignored by ports)
+ * @param prio priority of the new thread (may be ignored by ports) */
+sys_thread_t sys_thread_new(const char *name, lwip_thread_fn thread, void *arg, int stacksize, int prio);
+
+#endif /* NO_SYS */
+
+/**
+ * @ingroup sys_misc
+ * sys_init() must be called before anything else.
+ * Initialize the sys_arch layer.
+ */
+void sys_init(void);
+
+#ifndef sys_jiffies
+/**
+ * Ticks/jiffies since power up.
+ */
+u32_t sys_jiffies(void);
+#endif
+
+/**
+ * @ingroup sys_time
+ * Returns the current time in milliseconds,
+ * may be the same as sys_jiffies or at least based on it.
+ * Don't care for wraparound, this is only used for time diffs.
+ * Not implementing this function means you cannot use some modules (e.g. TCP
+ * timestamps, internal timeouts for NO_SYS==1).
+ */
+u32_t sys_now(void);
+
+/* Critical Region Protection */
+/* These functions must be implemented in the sys_arch.c file.
+   In some implementations they can provide a more light-weight protection
+   mechanism than using semaphores. Otherwise semaphores can be used for
+   implementation */
+#ifndef SYS_ARCH_PROTECT
+/** SYS_LIGHTWEIGHT_PROT
+ * define SYS_LIGHTWEIGHT_PROT in lwipopts.h if you want inter-task protection
+ * for certain critical regions during buffer allocation, deallocation and memory
+ * allocation and deallocation.
+ */
+#if SYS_LIGHTWEIGHT_PROT
+
+/**
+ * @ingroup sys_prot
+ * SYS_ARCH_DECL_PROTECT
+ * declare a protection variable. This macro will default to defining a variable of
+ * type sys_prot_t. If a particular port needs a different implementation, then
+ * this macro may be defined in sys_arch.h.
+ */
+#define SYS_ARCH_DECL_PROTECT(lev) sys_prot_t lev
+/**
+ * @ingroup sys_prot
+ * SYS_ARCH_PROTECT
+ * Perform a "fast" protect. This could be implemented by
+ * disabling interrupts for an embedded system or by using a semaphore or
+ * mutex. The implementation should allow calling SYS_ARCH_PROTECT when
+ * already protected. The old protection level is returned in the variable
+ * "lev". This macro will default to calling the sys_arch_protect() function
+ * which should be implemented in sys_arch.c. If a particular port needs a
+ * different implementation, then this macro may be defined in sys_arch.h
+ */
+#define SYS_ARCH_PROTECT(lev) lev = sys_arch_protect()
+/**
+ * @ingroup sys_prot
+ * SYS_ARCH_UNPROTECT
+ * Perform a "fast" set of the protection level to "lev". This could be
+ * implemented by setting the interrupt level to "lev" within the MACRO or by
+ * using a semaphore or mutex.  This macro will default to calling the
+ * sys_arch_unprotect() function which should be implemented in
+ * sys_arch.c. If a particular port needs a different implementation, then
+ * this macro may be defined in sys_arch.h
+ */
+#define SYS_ARCH_UNPROTECT(lev) sys_arch_unprotect(lev)
+sys_prot_t sys_arch_protect(void);
+void sys_arch_unprotect(sys_prot_t pval);
+
+#else
+
+#define SYS_ARCH_DECL_PROTECT(lev)
+#define SYS_ARCH_PROTECT(lev)
+#define SYS_ARCH_UNPROTECT(lev)
+
+#endif /* SYS_LIGHTWEIGHT_PROT */
+
+#endif /* SYS_ARCH_PROTECT */
+
+/*
+ * Macros to set/get and increase/decrease variables in a thread-safe way.
+ * Use these for accessing variable that are used from more than one thread.
+ */
+
+#ifndef SYS_ARCH_INC
+#define SYS_ARCH_INC(var, val) do { \
+                                SYS_ARCH_DECL_PROTECT(old_level); \
+                                SYS_ARCH_PROTECT(old_level); \
+                                var += val; \
+                                SYS_ARCH_UNPROTECT(old_level); \
+                              } while(0)
+#endif /* SYS_ARCH_INC */
+
+#ifndef SYS_ARCH_DEC
+#define SYS_ARCH_DEC(var, val) do { \
+                                SYS_ARCH_DECL_PROTECT(old_level); \
+                                SYS_ARCH_PROTECT(old_level); \
+                                var -= val; \
+                                SYS_ARCH_UNPROTECT(old_level); \
+                              } while(0)
+#endif /* SYS_ARCH_DEC */
+
+#ifndef SYS_ARCH_GET
+#define SYS_ARCH_GET(var, ret) do { \
+                                SYS_ARCH_DECL_PROTECT(old_level); \
+                                SYS_ARCH_PROTECT(old_level); \
+                                ret = var; \
+                                SYS_ARCH_UNPROTECT(old_level); \
+                              } while(0)
+#endif /* SYS_ARCH_GET */
+
+#ifndef SYS_ARCH_SET
+#define SYS_ARCH_SET(var, val) do { \
+                                SYS_ARCH_DECL_PROTECT(old_level); \
+                                SYS_ARCH_PROTECT(old_level); \
+                                var = val; \
+                                SYS_ARCH_UNPROTECT(old_level); \
+                              } while(0)
+#endif /* SYS_ARCH_SET */
+
+#ifndef SYS_ARCH_LOCKED
+#define SYS_ARCH_LOCKED(code) do { \
+                                SYS_ARCH_DECL_PROTECT(old_level); \
+                                SYS_ARCH_PROTECT(old_level); \
+                                code; \
+                                SYS_ARCH_UNPROTECT(old_level); \
+                              } while(0)
+#endif /* SYS_ARCH_LOCKED */
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LWIP_HDR_SYS_H */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/tcp.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/tcp.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/tcp.h	(revision 457)
@@ -0,0 +1,500 @@
+/**
+ * @file
+ * TCP API (to be used from TCPIP thread)\n
+ * See also @ref tcp_raw
+ */
+
+/*
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Adam Dunkels <adam@sics.se>
+ *
+ */
+#ifndef LWIP_HDR_TCP_H
+#define LWIP_HDR_TCP_H
+
+#include "lwip/opt.h"
+
+#if LWIP_TCP /* don't build if not configured for use in lwipopts.h */
+
+#include "lwip/tcpbase.h"
+#include "lwip/mem.h"
+#include "lwip/pbuf.h"
+#include "lwip/ip.h"
+#include "lwip/icmp.h"
+#include "lwip/err.h"
+#include "lwip/ip6.h"
+#include "lwip/ip6_addr.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct tcp_pcb;
+struct tcp_pcb_listen;
+
+/** Function prototype for tcp accept callback functions. Called when a new
+ * connection can be accepted on a listening pcb.
+ *
+ * @param arg Additional argument to pass to the callback function (@see tcp_arg())
+ * @param newpcb The new connection pcb
+ * @param err An error code if there has been an error accepting.
+ *            Only return ERR_ABRT if you have called tcp_abort from within the
+ *            callback function!
+ */
+typedef err_t (*tcp_accept_fn)(void *arg, struct tcp_pcb *newpcb, err_t err);
+
+/** Function prototype for tcp receive callback functions. Called when data has
+ * been received.
+ *
+ * @param arg Additional argument to pass to the callback function (@see tcp_arg())
+ * @param tpcb The connection pcb which received data
+ * @param p The received data (or NULL when the connection has been closed!)
+ * @param err An error code if there has been an error receiving
+ *            Only return ERR_ABRT if you have called tcp_abort from within the
+ *            callback function!
+ */
+typedef err_t (*tcp_recv_fn)(void *arg, struct tcp_pcb *tpcb,
+                             struct pbuf *p, err_t err);
+
+/** Function prototype for tcp sent callback functions. Called when sent data has
+ * been acknowledged by the remote side. Use it to free corresponding resources.
+ * This also means that the pcb has now space available to send new data.
+ *
+ * @param arg Additional argument to pass to the callback function (@see tcp_arg())
+ * @param tpcb The connection pcb for which data has been acknowledged
+ * @param len The amount of bytes acknowledged
+ * @return ERR_OK: try to send some data by calling tcp_output
+ *            Only return ERR_ABRT if you have called tcp_abort from within the
+ *            callback function!
+ */
+typedef err_t (*tcp_sent_fn)(void *arg, struct tcp_pcb *tpcb,
+                              u16_t len);
+
+/** Function prototype for tcp poll callback functions. Called periodically as
+ * specified by @see tcp_poll.
+ *
+ * @param arg Additional argument to pass to the callback function (@see tcp_arg())
+ * @param tpcb tcp pcb
+ * @return ERR_OK: try to send some data by calling tcp_output
+ *            Only return ERR_ABRT if you have called tcp_abort from within the
+ *            callback function!
+ */
+typedef err_t (*tcp_poll_fn)(void *arg, struct tcp_pcb *tpcb);
+
+/** Function prototype for tcp error callback functions. Called when the pcb
+ * receives a RST or is unexpectedly closed for any other reason.
+ *
+ * @note The corresponding pcb is already freed when this callback is called!
+ *
+ * @param arg Additional argument to pass to the callback function (@see tcp_arg())
+ * @param err Error code to indicate why the pcb has been closed
+ *            ERR_ABRT: aborted through tcp_abort or by a TCP timer
+ *            ERR_RST: the connection was reset by the remote host
+ */
+typedef void  (*tcp_err_fn)(void *arg, err_t err);
+
+/** Function prototype for tcp connected callback functions. Called when a pcb
+ * is connected to the remote side after initiating a connection attempt by
+ * calling tcp_connect().
+ *
+ * @param arg Additional argument to pass to the callback function (@see tcp_arg())
+ * @param tpcb The connection pcb which is connected
+ * @param err An unused error code, always ERR_OK currently ;-) @todo!
+ *            Only return ERR_ABRT if you have called tcp_abort from within the
+ *            callback function!
+ *
+ * @note When a connection attempt fails, the error callback is currently called!
+ */
+typedef err_t (*tcp_connected_fn)(void *arg, struct tcp_pcb *tpcb, err_t err);
+
+#if LWIP_WND_SCALE
+#define RCV_WND_SCALE(pcb, wnd) (((wnd) >> (pcb)->rcv_scale))
+#define SND_WND_SCALE(pcb, wnd) (((wnd) << (pcb)->snd_scale))
+#define TCPWND16(x)             ((u16_t)LWIP_MIN((x), 0xFFFF))
+#define TCP_WND_MAX(pcb)        ((tcpwnd_size_t)(((pcb)->flags & TF_WND_SCALE) ? TCP_WND : TCPWND16(TCP_WND)))
+#else
+#define RCV_WND_SCALE(pcb, wnd) (wnd)
+#define SND_WND_SCALE(pcb, wnd) (wnd)
+#define TCPWND16(x)             (x)
+#define TCP_WND_MAX(pcb)        TCP_WND
+#endif
+/* Increments a tcpwnd_size_t and holds at max value rather than rollover */
+#define TCP_WND_INC(wnd, inc)   do { \
+                                  if ((tcpwnd_size_t)(wnd + inc) >= wnd) { \
+                                    wnd = (tcpwnd_size_t)(wnd + inc); \
+                                  } else { \
+                                    wnd = (tcpwnd_size_t)-1; \
+                                  } \
+                                } while(0)
+
+#if LWIP_TCP_SACK_OUT
+/** SACK ranges to include in ACK packets.
+ * SACK entry is invalid if left==right. */
+struct tcp_sack_range {
+  /** Left edge of the SACK: the first acknowledged sequence number. */
+  u32_t left;
+  /** Right edge of the SACK: the last acknowledged sequence number +1 (so first NOT acknowledged). */
+  u32_t right;
+};
+#endif /* LWIP_TCP_SACK_OUT */
+
+/** Function prototype for deallocation of arguments. Called *just before* the
+ * pcb is freed, so don't expect to be able to do anything with this pcb!
+ *
+ * @param id ext arg id (allocated via @ref tcp_ext_arg_alloc_id)
+ * @param data pointer to the data (set via @ref tcp_ext_arg_set before)
+ */
+typedef void (*tcp_extarg_callback_pcb_destroyed_fn)(u8_t id, void *data);
+
+/** Function prototype to transition arguments from a listening pcb to an accepted pcb
+ *
+ * @param id ext arg id (allocated via @ref tcp_ext_arg_alloc_id)
+ * @param lpcb the listening pcb accepting a connection
+ * @param cpcb the newly allocated connection pcb
+ * @return ERR_OK if OK, any error if connection should be dropped
+ */
+typedef err_t (*tcp_extarg_callback_passive_open_fn)(u8_t id, struct tcp_pcb_listen *lpcb, struct tcp_pcb *cpcb);
+
+/** A table of callback functions that is invoked for ext arguments */
+struct tcp_ext_arg_callbacks {
+  /** @ref tcp_extarg_callback_pcb_destroyed_fn */
+  tcp_extarg_callback_pcb_destroyed_fn destroy;
+  /** @ref tcp_extarg_callback_passive_open_fn */
+  tcp_extarg_callback_passive_open_fn passive_open;
+};
+
+#define LWIP_TCP_PCB_NUM_EXT_ARG_ID_INVALID 0xFF
+
+#if LWIP_TCP_PCB_NUM_EXT_ARGS
+/* This is the structure for ext args in tcp pcbs (used as array) */
+struct tcp_pcb_ext_args {
+  const struct tcp_ext_arg_callbacks *callbacks;
+  void *data;
+};
+/* This is a helper define to prevent zero size arrays if disabled */
+#define TCP_PCB_EXTARGS struct tcp_pcb_ext_args ext_args[LWIP_TCP_PCB_NUM_EXT_ARGS];
+#else
+#define TCP_PCB_EXTARGS
+#endif
+
+typedef u16_t tcpflags_t;
+#define TCP_ALLFLAGS 0xffffU
+
+/**
+ * members common to struct tcp_pcb and struct tcp_listen_pcb
+ */
+#define TCP_PCB_COMMON(type) \
+  type *next; /* for the linked list */ \
+  void *callback_arg; \
+  TCP_PCB_EXTARGS \
+  enum tcp_state state; /* TCP state */ \
+  u8_t prio; \
+  /* ports are in host byte order */ \
+  u16_t local_port
+
+
+/** the TCP protocol control block for listening pcbs */
+struct tcp_pcb_listen {
+/** Common members of all PCB types */
+  IP_PCB;
+/** Protocol specific PCB members */
+  TCP_PCB_COMMON(struct tcp_pcb_listen);
+
+#if LWIP_CALLBACK_API
+  /* Function to call when a listener has been connected. */
+  tcp_accept_fn accept;
+#endif /* LWIP_CALLBACK_API */
+
+#if TCP_LISTEN_BACKLOG
+  u8_t backlog;
+  u8_t accepts_pending;
+#endif /* TCP_LISTEN_BACKLOG */
+};
+
+
+/** the TCP protocol control block */
+struct tcp_pcb {
+/** common PCB members */
+  IP_PCB;
+/** protocol specific PCB members */
+  TCP_PCB_COMMON(struct tcp_pcb);
+
+  /* ports are in host byte order */
+  u16_t remote_port;
+
+  tcpflags_t flags;
+#define TF_ACK_DELAY   0x01U   /* Delayed ACK. */
+#define TF_ACK_NOW     0x02U   /* Immediate ACK. */
+#define TF_INFR        0x04U   /* In fast recovery. */
+#define TF_CLOSEPEND   0x08U   /* If this is set, tcp_close failed to enqueue the FIN (retried in tcp_tmr) */
+#define TF_RXCLOSED    0x10U   /* rx closed by tcp_shutdown */
+#define TF_FIN         0x20U   /* Connection was closed locally (FIN segment enqueued). */
+#define TF_NODELAY     0x40U   /* Disable Nagle algorithm */
+#define TF_NAGLEMEMERR 0x80U   /* nagle enabled, memerr, try to output to prevent delayed ACK to happen */
+#if LWIP_WND_SCALE
+#define TF_WND_SCALE   0x0100U /* Window Scale option enabled */
+#endif
+#if TCP_LISTEN_BACKLOG
+#define TF_BACKLOGPEND 0x0200U /* If this is set, a connection pcb has increased the backlog on its listener */
+#endif
+#if LWIP_TCP_TIMESTAMPS
+#define TF_TIMESTAMP   0x0400U   /* Timestamp option enabled */
+#endif
+#define TF_RTO         0x0800U /* RTO timer has fired, in-flight data moved to unsent and being retransmitted */
+#if LWIP_TCP_SACK_OUT
+#define TF_SACK        0x1000U /* Selective ACKs enabled */
+#endif
+
+  /* the rest of the fields are in host byte order
+     as we have to do some math with them */
+
+  /* Timers */
+  u8_t polltmr, pollinterval;
+  u8_t last_timer;
+  u32_t tmr;
+
+  /* receiver variables */
+  u32_t rcv_nxt;   /* next seqno expected */
+  tcpwnd_size_t rcv_wnd;   /* receiver window available */
+  tcpwnd_size_t rcv_ann_wnd; /* receiver window to announce */
+  u32_t rcv_ann_right_edge; /* announced right edge of window */
+
+#if LWIP_TCP_SACK_OUT
+  /* SACK ranges to include in ACK packets (entry is invalid if left==right) */
+  struct tcp_sack_range rcv_sacks[LWIP_TCP_MAX_SACK_NUM];
+#define LWIP_TCP_SACK_VALID(pcb, idx) ((pcb)->rcv_sacks[idx].left != (pcb)->rcv_sacks[idx].right)
+#endif /* LWIP_TCP_SACK_OUT */
+
+  /* Retransmission timer. */
+  s16_t rtime;
+
+  u16_t mss;   /* maximum segment size */
+
+  /* RTT (round trip time) estimation variables */
+  u32_t rttest; /* RTT estimate in 500ms ticks */
+  u32_t rtseq;  /* sequence number being timed */
+  s16_t sa, sv; /* @see "Congestion Avoidance and Control" by Van Jacobson and Karels */
+
+  s16_t rto;    /* retransmission time-out (in ticks of TCP_SLOW_INTERVAL) */
+  u8_t nrtx;    /* number of retransmissions */
+
+  /* fast retransmit/recovery */
+  u8_t dupacks;
+  u32_t lastack; /* Highest acknowledged seqno. */
+
+  /* congestion avoidance/control variables */
+  tcpwnd_size_t cwnd;
+  tcpwnd_size_t ssthresh;
+
+  /* first byte following last rto byte */
+  u32_t rto_end;
+
+  /* sender variables */
+  u32_t snd_nxt;   /* next new seqno to be sent */
+  u32_t snd_wl1, snd_wl2; /* Sequence and acknowledgement numbers of last
+                             window update. */
+  u32_t snd_lbb;       /* Sequence number of next byte to be buffered. */
+  tcpwnd_size_t snd_wnd;   /* sender window */
+  tcpwnd_size_t snd_wnd_max; /* the maximum sender window announced by the remote host */
+
+  tcpwnd_size_t snd_buf;   /* Available buffer space for sending (in bytes). */
+#define TCP_SNDQUEUELEN_OVERFLOW (0xffffU-3)
+  u16_t snd_queuelen; /* Number of pbufs currently in the send buffer. */
+
+#if TCP_OVERSIZE
+  /* Extra bytes available at the end of the last pbuf in unsent. */
+  u16_t unsent_oversize;
+#endif /* TCP_OVERSIZE */
+
+  tcpwnd_size_t bytes_acked;
+
+  /* These are ordered by sequence number: */
+  struct tcp_seg *unsent;   /* Unsent (queued) segments. */
+  struct tcp_seg *unacked;  /* Sent but unacknowledged segments. */
+#if TCP_QUEUE_OOSEQ
+  struct tcp_seg *ooseq;    /* Received out of sequence segments. */
+#endif /* TCP_QUEUE_OOSEQ */
+
+  struct pbuf *refused_data; /* Data previously received but not yet taken by upper layer */
+
+#if LWIP_CALLBACK_API || TCP_LISTEN_BACKLOG
+  struct tcp_pcb_listen* listener;
+#endif /* LWIP_CALLBACK_API || TCP_LISTEN_BACKLOG */
+
+#if LWIP_CALLBACK_API
+  /* Function to be called when more send buffer space is available. */
+  tcp_sent_fn sent;
+  /* Function to be called when (in-sequence) data has arrived. */
+  tcp_recv_fn recv;
+  /* Function to be called when a connection has been set up. */
+  tcp_connected_fn connected;
+  /* Function which is called periodically. */
+  tcp_poll_fn poll;
+  /* Function to be called whenever a fatal error occurs. */
+  tcp_err_fn errf;
+#endif /* LWIP_CALLBACK_API */
+
+#if LWIP_TCP_TIMESTAMPS
+  u32_t ts_lastacksent;
+  u32_t ts_recent;
+#endif /* LWIP_TCP_TIMESTAMPS */
+
+  /* idle time before KEEPALIVE is sent */
+  u32_t keep_idle;
+#if LWIP_TCP_KEEPALIVE
+  u32_t keep_intvl;
+  u32_t keep_cnt;
+#endif /* LWIP_TCP_KEEPALIVE */
+
+  /* Persist timer counter */
+  u8_t persist_cnt;
+  /* Persist timer back-off */
+  u8_t persist_backoff;
+  /* Number of persist probes */
+  u8_t persist_probe;
+
+  /* KEEPALIVE counter */
+  u8_t keep_cnt_sent;
+
+#if LWIP_WND_SCALE
+  u8_t snd_scale;
+  u8_t rcv_scale;
+#endif
+};
+
+#if LWIP_EVENT_API
+
+enum lwip_event {
+  LWIP_EVENT_ACCEPT,
+  LWIP_EVENT_SENT,
+  LWIP_EVENT_RECV,
+  LWIP_EVENT_CONNECTED,
+  LWIP_EVENT_POLL,
+  LWIP_EVENT_ERR
+};
+
+err_t lwip_tcp_event(void *arg, struct tcp_pcb *pcb,
+         enum lwip_event,
+         struct pbuf *p,
+         u16_t size,
+         err_t err);
+
+#endif /* LWIP_EVENT_API */
+
+/* Application program's interface: */
+struct tcp_pcb * tcp_new     (void);
+struct tcp_pcb * tcp_new_ip_type (u8_t type);
+
+void             tcp_arg     (struct tcp_pcb *pcb, void *arg);
+#if LWIP_CALLBACK_API
+void             tcp_recv    (struct tcp_pcb *pcb, tcp_recv_fn recv);
+void             tcp_sent    (struct tcp_pcb *pcb, tcp_sent_fn sent);
+void             tcp_err     (struct tcp_pcb *pcb, tcp_err_fn err);
+void             tcp_accept  (struct tcp_pcb *pcb, tcp_accept_fn accept);
+#endif /* LWIP_CALLBACK_API */
+void             tcp_poll    (struct tcp_pcb *pcb, tcp_poll_fn poll, u8_t interval);
+
+#define          tcp_set_flags(pcb, set_flags)     do { (pcb)->flags = (tcpflags_t)((pcb)->flags |  (set_flags)); } while(0)
+#define          tcp_clear_flags(pcb, clr_flags)   do { (pcb)->flags = (tcpflags_t)((pcb)->flags & (tcpflags_t)(~(clr_flags) & TCP_ALLFLAGS)); } while(0)
+#define          tcp_is_flag_set(pcb, flag)        (((pcb)->flags & (flag)) != 0)
+
+#if LWIP_TCP_TIMESTAMPS
+#define          tcp_mss(pcb)             (((pcb)->flags & TF_TIMESTAMP) ? ((pcb)->mss - 12)  : (pcb)->mss)
+#else /* LWIP_TCP_TIMESTAMPS */
+/** @ingroup tcp_raw */
+#define          tcp_mss(pcb)             ((pcb)->mss)
+#endif /* LWIP_TCP_TIMESTAMPS */
+/** @ingroup tcp_raw */
+#define          tcp_sndbuf(pcb)          (TCPWND16((pcb)->snd_buf))
+/** @ingroup tcp_raw */
+#define          tcp_sndqueuelen(pcb)     ((pcb)->snd_queuelen)
+/** @ingroup tcp_raw */
+#define          tcp_nagle_disable(pcb)   tcp_set_flags(pcb, TF_NODELAY)
+/** @ingroup tcp_raw */
+#define          tcp_nagle_enable(pcb)    tcp_clear_flags(pcb, TF_NODELAY)
+/** @ingroup tcp_raw */
+#define          tcp_nagle_disabled(pcb)  tcp_is_flag_set(pcb, TF_NODELAY)
+
+#if TCP_LISTEN_BACKLOG
+#define          tcp_backlog_set(pcb, new_backlog) do { \
+  LWIP_ASSERT("pcb->state == LISTEN (called for wrong pcb?)", (pcb)->state == LISTEN); \
+  ((struct tcp_pcb_listen *)(pcb))->backlog = ((new_backlog) ? (new_backlog) : 1); } while(0)
+void             tcp_backlog_delayed(struct tcp_pcb* pcb);
+void             tcp_backlog_accepted(struct tcp_pcb* pcb);
+#else  /* TCP_LISTEN_BACKLOG */
+#define          tcp_backlog_set(pcb, new_backlog)
+#define          tcp_backlog_delayed(pcb)
+#define          tcp_backlog_accepted(pcb)
+#endif /* TCP_LISTEN_BACKLOG */
+#define          tcp_accepted(pcb) do { LWIP_UNUSED_ARG(pcb); } while(0) /* compatibility define, not needed any more */
+
+void             tcp_recved  (struct tcp_pcb *pcb, u16_t len);
+err_t            tcp_bind    (struct tcp_pcb *pcb, const ip_addr_t *ipaddr,
+                              u16_t port);
+void             tcp_bind_netif(struct tcp_pcb *pcb, const struct netif *netif);
+err_t            tcp_connect (struct tcp_pcb *pcb, const ip_addr_t *ipaddr,
+                              u16_t port, tcp_connected_fn connected);
+
+struct tcp_pcb * tcp_listen_with_backlog_and_err(struct tcp_pcb *pcb, u8_t backlog, err_t *err);
+struct tcp_pcb * tcp_listen_with_backlog(struct tcp_pcb *pcb, u8_t backlog);
+/** @ingroup tcp_raw */
+#define          tcp_listen(pcb) tcp_listen_with_backlog(pcb, TCP_DEFAULT_LISTEN_BACKLOG)
+
+void             tcp_abort (struct tcp_pcb *pcb);
+err_t            tcp_close   (struct tcp_pcb *pcb);
+err_t            tcp_shutdown(struct tcp_pcb *pcb, int shut_rx, int shut_tx);
+
+err_t            tcp_write   (struct tcp_pcb *pcb, const void *dataptr, u16_t len,
+                              u8_t apiflags);
+
+void             tcp_setprio (struct tcp_pcb *pcb, u8_t prio);
+
+err_t            tcp_output  (struct tcp_pcb *pcb);
+
+err_t            tcp_tcp_get_tcp_addrinfo(struct tcp_pcb *pcb, int local, ip_addr_t *addr, u16_t *port);
+
+#define tcp_dbg_get_tcp_state(pcb) ((pcb)->state)
+
+/* for compatibility with older implementation */
+#define tcp_new_ip6() tcp_new_ip_type(IPADDR_TYPE_V6)
+
+#if LWIP_TCP_PCB_NUM_EXT_ARGS
+u8_t tcp_ext_arg_alloc_id(void);
+void tcp_ext_arg_set_callbacks(struct tcp_pcb *pcb, uint8_t id, const struct tcp_ext_arg_callbacks * const callbacks);
+void tcp_ext_arg_set(struct tcp_pcb *pcb, uint8_t id, void *arg);
+void *tcp_ext_arg_get(const struct tcp_pcb *pcb, uint8_t id);
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LWIP_TCP */
+
+#endif /* LWIP_HDR_TCP_H */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/tcpbase.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/tcpbase.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/tcpbase.h	(revision 457)
@@ -0,0 +1,88 @@
+/**
+ * @file
+ * Base TCP API definitions shared by TCP and ALTCP\n
+ * See also @ref tcp_raw
+ */
+
+/*
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Adam Dunkels <adam@sics.se>
+ *
+ */
+#ifndef LWIP_HDR_TCPBASE_H
+#define LWIP_HDR_TCPBASE_H
+
+#include "lwip/opt.h"
+
+#if LWIP_TCP /* don't build if not configured for use in lwipopts.h */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+#if LWIP_WND_SCALE
+typedef u32_t tcpwnd_size_t;
+#else
+typedef u16_t tcpwnd_size_t;
+#endif
+
+enum tcp_state {
+  CLOSED      = 0,
+  LISTEN      = 1,
+  SYN_SENT    = 2,
+  SYN_RCVD    = 3,
+  ESTABLISHED = 4,
+  FIN_WAIT_1  = 5,
+  FIN_WAIT_2  = 6,
+  CLOSE_WAIT  = 7,
+  CLOSING     = 8,
+  LAST_ACK    = 9,
+  TIME_WAIT   = 10
+};
+/* ATTENTION: this depends on state number ordering! */
+#define TCP_STATE_IS_CLOSING(state) ((state) >= FIN_WAIT_1)
+
+/* Flags for "apiflags" parameter in tcp_write */
+#define TCP_WRITE_FLAG_COPY 0x01
+#define TCP_WRITE_FLAG_MORE 0x02
+
+#define TCP_PRIO_MIN    1
+#define TCP_PRIO_NORMAL 64
+#define TCP_PRIO_MAX    127
+
+const char* tcp_debug_state_str(enum tcp_state s);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LWIP_TCP */
+
+#endif /* LWIP_HDR_TCPBASE_H */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/tcpip.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/tcpip.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/tcpip.h	(revision 457)
@@ -0,0 +1,113 @@
+/**
+ * @file
+ * Functions to sync with TCPIP thread
+ */
+
+/*
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Adam Dunkels <adam@sics.se>
+ *
+ */
+#ifndef LWIP_HDR_TCPIP_H
+#define LWIP_HDR_TCPIP_H
+
+#include "lwip/opt.h"
+
+#if !NO_SYS /* don't build if not configured for use in lwipopts.h */
+
+#include "lwip/err.h"
+#include "lwip/timeouts.h"
+#include "lwip/netif.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if LWIP_TCPIP_CORE_LOCKING
+/** The global semaphore to lock the stack. */
+extern sys_mutex_t lock_tcpip_core;
+#if !defined LOCK_TCPIP_CORE || defined __DOXYGEN__
+/** Lock lwIP core mutex (needs @ref LWIP_TCPIP_CORE_LOCKING 1) */
+#define LOCK_TCPIP_CORE()     sys_mutex_lock(&lock_tcpip_core)
+/** Unlock lwIP core mutex (needs @ref LWIP_TCPIP_CORE_LOCKING 1) */
+#define UNLOCK_TCPIP_CORE()   sys_mutex_unlock(&lock_tcpip_core)
+#endif /* LOCK_TCPIP_CORE */
+#else /* LWIP_TCPIP_CORE_LOCKING */
+#define LOCK_TCPIP_CORE()
+#define UNLOCK_TCPIP_CORE()
+#endif /* LWIP_TCPIP_CORE_LOCKING */
+
+struct pbuf;
+struct netif;
+
+/** Function prototype for the init_done function passed to tcpip_init */
+typedef void (*tcpip_init_done_fn)(void *arg);
+/** Function prototype for functions passed to tcpip_callback() */
+typedef void (*tcpip_callback_fn)(void *ctx);
+
+/* Forward declarations */
+struct tcpip_callback_msg;
+
+void   tcpip_init(tcpip_init_done_fn tcpip_init_done, void *arg);
+
+err_t  tcpip_inpkt(struct pbuf *p, struct netif *inp, netif_input_fn input_fn);
+err_t  tcpip_input(struct pbuf *p, struct netif *inp);
+
+err_t  tcpip_try_callback(tcpip_callback_fn function, void *ctx);
+err_t  tcpip_callback(tcpip_callback_fn function, void *ctx);
+/**  @ingroup lwip_os
+ * @deprecated use tcpip_try_callback() or tcpip_callback() instead
+ */
+#define tcpip_callback_with_block(function, ctx, block) ((block != 0)? tcpip_callback(function, ctx) : tcpip_try_callback(function, ctx))
+
+struct tcpip_callback_msg* tcpip_callbackmsg_new(tcpip_callback_fn function, void *ctx);
+void   tcpip_callbackmsg_delete(struct tcpip_callback_msg* msg);
+err_t  tcpip_callbackmsg_trycallback(struct tcpip_callback_msg* msg);
+err_t  tcpip_callbackmsg_trycallback_fromisr(struct tcpip_callback_msg* msg);
+
+/* free pbufs or heap memory from another context without blocking */
+err_t  pbuf_free_callback(struct pbuf *p);
+err_t  mem_free_callback(void *m);
+
+#if LWIP_TCPIP_TIMEOUT && LWIP_TIMERS
+err_t  tcpip_timeout(u32_t msecs, sys_timeout_handler h, void *arg);
+err_t  tcpip_untimeout(sys_timeout_handler h, void *arg);
+#endif /* LWIP_TCPIP_TIMEOUT && LWIP_TIMERS */
+
+#ifdef TCPIP_THREAD_TEST
+int tcpip_thread_poll_one(void);
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* !NO_SYS */
+
+#endif /* LWIP_HDR_TCPIP_H */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/timeouts.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/timeouts.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/timeouts.h	(revision 457)
@@ -0,0 +1,128 @@
+/**
+ * @file
+ * Timer implementations
+ */
+
+/*
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Adam Dunkels <adam@sics.se>
+ *         Simon Goldschmidt
+ *
+ */
+#ifndef LWIP_HDR_TIMEOUTS_H
+#define LWIP_HDR_TIMEOUTS_H
+
+#include "lwip/opt.h"
+#include "lwip/err.h"
+#if !NO_SYS
+#include "lwip/sys.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef LWIP_DEBUG_TIMERNAMES
+#ifdef LWIP_DEBUG
+#define LWIP_DEBUG_TIMERNAMES SYS_DEBUG
+#else /* LWIP_DEBUG */
+#define LWIP_DEBUG_TIMERNAMES 0
+#endif /* LWIP_DEBUG*/
+#endif
+
+/** Returned by sys_timeouts_sleeptime() to indicate there is no timer, so we
+ * can sleep forever.
+ */
+#define SYS_TIMEOUTS_SLEEPTIME_INFINITE 0xFFFFFFFF
+
+/** Function prototype for a stack-internal timer function that has to be
+ * called at a defined interval */
+typedef void (* lwip_cyclic_timer_handler)(void);
+
+/** This struct contains information about a stack-internal timer function
+ that has to be called at a defined interval */
+struct lwip_cyclic_timer {
+  u32_t interval_ms;
+  lwip_cyclic_timer_handler handler;
+#if LWIP_DEBUG_TIMERNAMES
+  const char* handler_name;
+#endif /* LWIP_DEBUG_TIMERNAMES */
+};
+
+/** This array contains all stack-internal cyclic timers. To get the number of
+ * timers, use lwip_num_cyclic_timers */
+extern const struct lwip_cyclic_timer lwip_cyclic_timers[];
+/** Array size of lwip_cyclic_timers[] */
+extern const int lwip_num_cyclic_timers;
+
+#if LWIP_TIMERS
+
+/** Function prototype for a timeout callback function. Register such a function
+ * using sys_timeout().
+ *
+ * @param arg Additional argument to pass to the function - set up by sys_timeout()
+ */
+typedef void (* sys_timeout_handler)(void *arg);
+
+struct sys_timeo {
+  struct sys_timeo *next;
+  u32_t time;
+  sys_timeout_handler h;
+  void *arg;
+#if LWIP_DEBUG_TIMERNAMES
+  const char* handler_name;
+#endif /* LWIP_DEBUG_TIMERNAMES */
+};
+
+void sys_timeouts_init(void);
+
+#if LWIP_DEBUG_TIMERNAMES
+void sys_timeout_debug(u32_t msecs, sys_timeout_handler handler, void *arg, const char* handler_name);
+#define sys_timeout(msecs, handler, arg) sys_timeout_debug(msecs, handler, arg, #handler)
+#else /* LWIP_DEBUG_TIMERNAMES */
+void sys_timeout(u32_t msecs, sys_timeout_handler handler, void *arg);
+#endif /* LWIP_DEBUG_TIMERNAMES */
+
+void sys_untimeout(sys_timeout_handler handler, void *arg);
+void sys_restart_timeouts(void);
+void sys_check_timeouts(void);
+u32_t sys_timeouts_sleeptime(void);
+
+#if LWIP_TESTMODE
+struct sys_timeo** sys_timeouts_get_next_timeout(void);
+void lwip_cyclic_timer(void *arg);
+#endif
+
+#endif /* LWIP_TIMERS */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LWIP_HDR_TIMEOUTS_H */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/udp.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/udp.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/lwip/udp.h	(revision 457)
@@ -0,0 +1,195 @@
+/**
+ * @file
+ * UDP API (to be used from TCPIP thread)\n
+ * See also @ref udp_raw
+ */
+
+/*
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Adam Dunkels <adam@sics.se>
+ *
+ */
+#ifndef LWIP_HDR_UDP_H
+#define LWIP_HDR_UDP_H
+
+#include "lwip/opt.h"
+
+#if LWIP_UDP /* don't build if not configured for use in lwipopts.h */
+
+#include "lwip/pbuf.h"
+#include "lwip/netif.h"
+#include "lwip/ip_addr.h"
+#include "lwip/ip.h"
+#include "lwip/ip6_addr.h"
+#include "lwip/prot/udp.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define UDP_FLAGS_NOCHKSUM       0x01U
+#define UDP_FLAGS_UDPLITE        0x02U
+#define UDP_FLAGS_CONNECTED      0x04U
+#define UDP_FLAGS_MULTICAST_LOOP 0x08U
+
+struct udp_pcb;
+
+/** Function prototype for udp pcb receive callback functions
+ * addr and port are in same byte order as in the pcb
+ * The callback is responsible for freeing the pbuf
+ * if it's not used any more.
+ *
+ * ATTENTION: Be aware that 'addr' might point into the pbuf 'p' so freeing this pbuf
+ *            can make 'addr' invalid, too.
+ *
+ * @param arg user supplied argument (udp_pcb.recv_arg)
+ * @param pcb the udp_pcb which received data
+ * @param p the packet buffer that was received
+ * @param addr the remote IP address from which the packet was received
+ * @param port the remote port from which the packet was received
+ */
+typedef void (*udp_recv_fn)(void *arg, struct udp_pcb *pcb, struct pbuf *p,
+    const ip_addr_t *addr, u16_t port);
+
+/** the UDP protocol control block */
+struct udp_pcb {
+/** Common members of all PCB types */
+  IP_PCB;
+
+/* Protocol specific PCB members */
+
+  struct udp_pcb *next;
+
+  u8_t flags;
+  /** ports are in host byte order */
+  u16_t local_port, remote_port;
+
+#if LWIP_MULTICAST_TX_OPTIONS
+#if LWIP_IPV4
+  /** outgoing network interface for multicast packets, by IPv4 address (if not 'any') */
+  ip4_addr_t mcast_ip4;
+#endif /* LWIP_IPV4 */
+  /** outgoing network interface for multicast packets, by interface index (if nonzero) */
+  u8_t mcast_ifindex;
+  /** TTL for outgoing multicast packets */
+  u8_t mcast_ttl;
+#endif /* LWIP_MULTICAST_TX_OPTIONS */
+
+#if LWIP_UDPLITE
+  /** used for UDP_LITE only */
+  u16_t chksum_len_rx, chksum_len_tx;
+#endif /* LWIP_UDPLITE */
+
+  /** receive callback function */
+  udp_recv_fn recv;
+  /** user-supplied argument for the recv callback */
+  void *recv_arg;
+};
+/* udp_pcbs export for external reference (e.g. SNMP agent) */
+extern struct udp_pcb *udp_pcbs;
+
+/* The following functions is the application layer interface to the
+   UDP code. */
+struct udp_pcb * udp_new        (void);
+struct udp_pcb * udp_new_ip_type(u8_t type);
+void             udp_remove     (struct udp_pcb *pcb);
+err_t            udp_bind       (struct udp_pcb *pcb, const ip_addr_t *ipaddr,
+                                 u16_t port);
+void             udp_bind_netif (struct udp_pcb *pcb, const struct netif* netif);
+err_t            udp_connect    (struct udp_pcb *pcb, const ip_addr_t *ipaddr,
+                                 u16_t port);
+void             udp_disconnect (struct udp_pcb *pcb);
+void             udp_recv       (struct udp_pcb *pcb, udp_recv_fn recv,
+                                 void *recv_arg);
+err_t            udp_sendto_if  (struct udp_pcb *pcb, struct pbuf *p,
+                                 const ip_addr_t *dst_ip, u16_t dst_port,
+                                 struct netif *netif);
+err_t            udp_sendto_if_src(struct udp_pcb *pcb, struct pbuf *p,
+                                 const ip_addr_t *dst_ip, u16_t dst_port,
+                                 struct netif *netif, const ip_addr_t *src_ip);
+err_t            udp_sendto     (struct udp_pcb *pcb, struct pbuf *p,
+                                 const ip_addr_t *dst_ip, u16_t dst_port);
+err_t            udp_send       (struct udp_pcb *pcb, struct pbuf *p);
+
+#if LWIP_CHECKSUM_ON_COPY && CHECKSUM_GEN_UDP
+err_t            udp_sendto_if_chksum(struct udp_pcb *pcb, struct pbuf *p,
+                                 const ip_addr_t *dst_ip, u16_t dst_port,
+                                 struct netif *netif, u8_t have_chksum,
+                                 u16_t chksum);
+err_t            udp_sendto_chksum(struct udp_pcb *pcb, struct pbuf *p,
+                                 const ip_addr_t *dst_ip, u16_t dst_port,
+                                 u8_t have_chksum, u16_t chksum);
+err_t            udp_send_chksum(struct udp_pcb *pcb, struct pbuf *p,
+                                 u8_t have_chksum, u16_t chksum);
+err_t            udp_sendto_if_src_chksum(struct udp_pcb *pcb, struct pbuf *p,
+                                 const ip_addr_t *dst_ip, u16_t dst_port, struct netif *netif,
+                                 u8_t have_chksum, u16_t chksum, const ip_addr_t *src_ip);
+#endif /* LWIP_CHECKSUM_ON_COPY && CHECKSUM_GEN_UDP */
+
+#define          udp_flags(pcb) ((pcb)->flags)
+#define          udp_setflags(pcb, f)  ((pcb)->flags = (f))
+
+#define          udp_set_flags(pcb, set_flags)     do { (pcb)->flags = (u8_t)((pcb)->flags |  (set_flags)); } while(0)
+#define          udp_clear_flags(pcb, clr_flags)   do { (pcb)->flags = (u8_t)((pcb)->flags & (u8_t)(~(clr_flags) & 0xff)); } while(0)
+#define          udp_is_flag_set(pcb, flag)        (((pcb)->flags & (flag)) != 0)
+
+/* The following functions are the lower layer interface to UDP. */
+void             udp_input      (struct pbuf *p, struct netif *inp);
+
+void             udp_init       (void);
+
+/* for compatibility with older implementation */
+#define udp_new_ip6() udp_new_ip_type(IPADDR_TYPE_V6)
+
+#if LWIP_MULTICAST_TX_OPTIONS
+#if LWIP_IPV4
+#define udp_set_multicast_netif_addr(pcb, ip4addr) ip4_addr_copy((pcb)->mcast_ip4, *(ip4addr))
+#define udp_get_multicast_netif_addr(pcb)          (&(pcb)->mcast_ip4)
+#endif /* LWIP_IPV4 */
+#define udp_set_multicast_netif_index(pcb, idx)    ((pcb)->mcast_ifindex = (idx))
+#define udp_get_multicast_netif_index(pcb)         ((pcb)->mcast_ifindex)
+#define udp_set_multicast_ttl(pcb, value)          ((pcb)->mcast_ttl = (value))
+#define udp_get_multicast_ttl(pcb)                 ((pcb)->mcast_ttl)
+#endif /* LWIP_MULTICAST_TX_OPTIONS */
+
+#if UDP_DEBUG
+void udp_debug_print(struct udp_hdr *udphdr);
+#else
+#define udp_debug_print(udphdr)
+#endif
+
+void udp_netif_ip_addr_changed(const ip_addr_t* old_addr, const ip_addr_t* new_addr);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LWIP_UDP */
+
+#endif /* LWIP_HDR_UDP_H */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/netif/bridgeif.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/netif/bridgeif.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/netif/bridgeif.h	(revision 457)
@@ -0,0 +1,127 @@
+/**
+ * @file
+ * lwIP netif implementing an IEEE 802.1D MAC Bridge
+ */
+
+/*
+ * Copyright (c) 2017 Simon Goldschmidt.
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Simon Goldschmidt <goldsimon@gmx.de>
+ *
+ */
+#ifndef LWIP_HDR_NETIF_BRIDGEIF_H
+#define LWIP_HDR_NETIF_BRIDGEIF_H
+
+#include "netif/bridgeif_opts.h"
+
+#include "lwip/err.h"
+#include "lwip/prot/ethernet.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct netif;
+
+#if (BRIDGEIF_MAX_PORTS < 0) || (BRIDGEIF_MAX_PORTS >= 64)
+#error BRIDGEIF_MAX_PORTS must be [1..63]
+#elif BRIDGEIF_MAX_PORTS < 8
+typedef u8_t bridgeif_portmask_t;
+#elif BRIDGEIF_MAX_PORTS < 16
+typedef u16_t bridgeif_portmask_t;
+#elif BRIDGEIF_MAX_PORTS < 32
+typedef u32_t bridgeif_portmask_t;
+#elif BRIDGEIF_MAX_PORTS < 64
+typedef u64_t bridgeif_portmask_t;
+#endif
+
+#define BR_FLOOD ((bridgeif_portmask_t)-1)
+
+/** @ingroup bridgeif
+ * Initialisation data for @ref bridgeif_init.
+ * An instance of this type must be passed as parameter 'state' to @ref netif_add
+ * when the bridge is added.
+ */
+typedef struct bridgeif_initdata_s {
+  /** MAC address of the bridge (cannot use the netif's addresses) */
+  struct eth_addr ethaddr;
+  /** Maximum number of ports in the bridge (ports are stored in an array, this
+      influences memory allocated for netif->state of the bridge netif). */
+  u8_t            max_ports;
+  /** Maximum number of dynamic/learning entries in the bridge's forwarding database.
+      In the default implementation, this controls memory consumption only. */
+  u16_t           max_fdb_dynamic_entries;
+  /** Maximum number of static forwarding entries. Influences memory consumption! */
+  u16_t           max_fdb_static_entries;
+} bridgeif_initdata_t;
+
+/** @ingroup bridgeif
+ * Use this for constant initialization of a bridgeif_initdat_t
+ * (ethaddr must be passed as ETH_ADDR())
+ */
+#define BRIDGEIF_INITDATA1(max_ports, max_fdb_dynamic_entries, max_fdb_static_entries, ethaddr) {ethaddr, max_ports, max_fdb_dynamic_entries, max_fdb_static_entries}
+/** @ingroup bridgeif
+ * Use this for constant initialization of a bridgeif_initdat_t
+ * (each byte of ethaddr must be passed)
+ */
+#define BRIDGEIF_INITDATA2(max_ports, max_fdb_dynamic_entries, max_fdb_static_entries, e0, e1, e2, e3, e4, e5) {{e0, e1, e2, e3, e4, e5}, max_ports, max_fdb_dynamic_entries, max_fdb_static_entries}
+
+err_t bridgeif_init(struct netif *netif);
+err_t bridgeif_add_port(struct netif *bridgeif, struct netif *portif);
+err_t bridgeif_fdb_add(struct netif *bridgeif, const struct eth_addr *addr, bridgeif_portmask_t ports);
+err_t bridgeif_fdb_remove(struct netif *bridgeif, const struct eth_addr *addr);
+
+/* FDB interface, can be replaced by own implementation */
+void                bridgeif_fdb_update_src(void *fdb_ptr, struct eth_addr *src_addr, u8_t port_idx);
+bridgeif_portmask_t bridgeif_fdb_get_dst_ports(void *fdb_ptr, struct eth_addr *dst_addr);
+void*               bridgeif_fdb_init(u16_t max_fdb_entries);
+
+#if BRIDGEIF_PORT_NETIFS_OUTPUT_DIRECT
+#ifndef BRIDGEIF_DECL_PROTECT
+/* define bridgeif protection to sys_arch_protect... */
+#include "lwip/sys.h"
+#define BRIDGEIF_DECL_PROTECT(lev)    SYS_ARCH_DECL_PROTECT(lev)
+#define BRIDGEIF_READ_PROTECT(lev)    SYS_ARCH_PROTECT(lev)
+#define BRIDGEIF_READ_UNPROTECT(lev)  SYS_ARCH_UNPROTECT(lev)
+#define BRIDGEIF_WRITE_PROTECT(lev)
+#define BRIDGEIF_WRITE_UNPROTECT(lev)
+#endif
+#else /* BRIDGEIF_PORT_NETIFS_OUTPUT_DIRECT */
+#include "lwip/tcpip.h"
+#define BRIDGEIF_DECL_PROTECT(lev)
+#define BRIDGEIF_READ_PROTECT(lev)
+#define BRIDGEIF_READ_UNPROTECT(lev)
+#define BRIDGEIF_WRITE_PROTECT(lev)
+#define BRIDGEIF_WRITE_UNPROTECT(lev)
+#endif /* BRIDGEIF_PORT_NETIFS_OUTPUT_DIRECT */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LWIP_HDR_NETIF_BRIDGEIF_H */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/netif/bridgeif_opts.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/netif/bridgeif_opts.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/netif/bridgeif_opts.h	(revision 457)
@@ -0,0 +1,90 @@
+/**
+ * @file
+ * lwIP netif implementing an IEEE 802.1D MAC Bridge
+ */
+
+/*
+ * Copyright (c) 2017 Simon Goldschmidt.
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Simon Goldschmidt <goldsimon@gmx.de>
+ *
+ */
+
+#ifndef LWIP_HDR_NETIF_BRIDGEIF_OPTS_H
+#define LWIP_HDR_NETIF_BRIDGEIF_OPTS_H
+
+#include "lwip/opt.h"
+
+/**
+ * @defgroup bridgeif_opts Options
+ * @ingroup bridgeif
+ * @{
+ */
+
+/** BRIDGEIF_PORT_NETIFS_OUTPUT_DIRECT==1: set port netif's 'input' function
+ * to call directly into bridgeif code and on top of that, directly call into
+ * the selected forwarding port's 'linkoutput' function.
+ * This means that the bridgeif input/output path is protected from concurrent access
+ * but as well, *all* bridge port netif's drivers must correctly handle concurrent access!
+ * == 0: get into tcpip_thread for every input packet (no multithreading)
+ * ATTENTION: as ==0 relies on tcpip.h, the default depends on NO_SYS setting
+ */
+#ifndef BRIDGEIF_PORT_NETIFS_OUTPUT_DIRECT
+#define BRIDGEIF_PORT_NETIFS_OUTPUT_DIRECT  NO_SYS
+#endif
+
+/** BRIDGEIF_MAX_PORTS: this is used to create a typedef used for forwarding
+ * bit-fields: the number of bits required is this + 1 (for the internal/cpu port)
+ * (63 is the maximum, resulting in an u64_t for the bit mask)
+ * ATTENTION: this controls the maximum number of the implementation only!
+ * The max. number of ports per bridge must still be passed via netif_add parameter!
+ */
+#ifndef BRIDGEIF_MAX_PORTS
+#define BRIDGEIF_MAX_PORTS                  7
+#endif
+
+/** BRIDGEIF_DEBUG: Enable generic debugging in bridgeif.c. */
+#ifndef BRIDGEIF_DEBUG
+#define BRIDGEIF_DEBUG                      LWIP_DBG_OFF
+#endif
+
+/** BRIDGEIF_DEBUG: Enable FDB debugging in bridgeif.c. */
+#ifndef BRIDGEIF_FDB_DEBUG
+#define BRIDGEIF_FDB_DEBUG                  LWIP_DBG_OFF
+#endif
+
+/** BRIDGEIF_DEBUG: Enable forwarding debugging in bridgeif.c. */
+#ifndef BRIDGEIF_FW_DEBUG
+#define BRIDGEIF_FW_DEBUG                   LWIP_DBG_OFF
+#endif
+
+/**
+ * @}
+ */
+
+#endif /* LWIP_HDR_NETIF_BRIDGEIF_OPTS_H */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/netif/etharp.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/netif/etharp.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/netif/etharp.h	(revision 457)
@@ -0,0 +1,3 @@
+/* ARP has been moved to core/ipv4, provide this #include for compatibility only */
+#include "lwip/etharp.h"
+#include "netif/ethernet.h"
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/netif/ethernet.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/netif/ethernet.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/netif/ethernet.h	(revision 457)
@@ -0,0 +1,77 @@
+/**
+ * @file
+ * Ethernet input function - handles INCOMING ethernet level traffic
+ * To be used in most low-level netif implementations
+ */
+
+/*
+ * Copyright (c) 2001-2003 Swedish Institute of Computer Science.
+ * Copyright (c) 2003-2004 Leon Woestenberg <leon.woestenberg@axon.tv>
+ * Copyright (c) 2003-2004 Axon Digital Design B.V., The Netherlands.
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Adam Dunkels <adam@sics.se>
+ *
+ */
+
+#ifndef LWIP_HDR_NETIF_ETHERNET_H
+#define LWIP_HDR_NETIF_ETHERNET_H
+
+#include "lwip/opt.h"
+
+#include "lwip/pbuf.h"
+#include "lwip/netif.h"
+#include "lwip/prot/ethernet.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if LWIP_ARP || LWIP_ETHERNET
+
+/** Define this to 1 and define LWIP_ARP_FILTER_NETIF_FN(pbuf, netif, type)
+ * to a filter function that returns the correct netif when using multiple
+ * netifs on one hardware interface where the netif's low-level receive
+ * routine cannot decide for the correct netif (e.g. when mapping multiple
+ * IP addresses to one hardware interface).
+ */
+#ifndef LWIP_ARP_FILTER_NETIF
+#define LWIP_ARP_FILTER_NETIF 0
+#endif
+
+err_t ethernet_input(struct pbuf *p, struct netif *netif);
+err_t ethernet_output(struct netif* netif, struct pbuf* p, const struct eth_addr* src, const struct eth_addr* dst, u16_t eth_type);
+
+extern const struct eth_addr ethbroadcast, ethzero;
+
+#endif /* LWIP_ARP || LWIP_ETHERNET */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LWIP_HDR_NETIF_ETHERNET_H */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/netif/ieee802154.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/netif/ieee802154.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/netif/ieee802154.h	(revision 457)
@@ -0,0 +1,112 @@
+/**
+ * @file
+ * Definitions for IEEE 802.15.4 MAC frames
+ */
+
+/*
+ * Copyright (c) 2018 Simon Goldschmidt.
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Simon Goldschmidt <goldsimon@gmx.de>
+ *
+ */
+#ifndef LWIP_HDR_NETIF_IEEE802154_H
+#define LWIP_HDR_NETIF_IEEE802154_H
+
+#include "lwip/opt.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef PACK_STRUCT_USE_INCLUDES
+#  include "arch/bpstruct.h"
+#endif
+PACK_STRUCT_BEGIN
+/** General MAC frame format
+ * This shows the full featured header, mainly for documentation.
+ * Some fields are omitted or shortened to achieve frame compression.
+ */
+struct ieee_802154_hdr {
+  /** See IEEE_802154_FC_* defines */
+  PACK_STRUCT_FIELD(u16_t frame_control);
+  /** Sequence number is omitted if IEEE_802154_FC_SEQNO_SUPPR is set in frame_control */
+  PACK_STRUCT_FLD_8(u8_t  sequence_number);
+  /** Destination PAN ID is omitted if Destination Addressing Mode is 0 */
+  PACK_STRUCT_FIELD(u16_t destination_pan_id);
+  /** Destination Address is omitted if Destination Addressing Mode is 0 */
+  PACK_STRUCT_FLD_8(u8_t destination_address[8]);
+  /** Source PAN ID is omitted if Source Addressing Mode is 0
+      or if IEEE_802154_FC_PANID_COMPR is set in frame control*/
+  PACK_STRUCT_FIELD(u16_t source_pan_id);
+  /** Source Address is omitted if Source Addressing Mode is 0 */
+  PACK_STRUCT_FLD_8(u8_t source_address[8]);
+  /* The rest is variable */
+} PACK_STRUCT_STRUCT;
+PACK_STRUCT_END
+#ifdef PACK_STRUCT_USE_INCLUDES
+#  include "arch/epstruct.h"
+#endif
+
+/* Addressing modes (2 bits) */
+#define IEEE_802154_ADDR_MODE_NO_ADDR   0x00 /* PAN ID and address fields are not present */
+#define IEEE_802154_ADDR_MODE_RESERVED  0x01 /* Reserved */
+#define IEEE_802154_ADDR_MODE_SHORT     0x02 /* Address field contains a short address (16 bit) */
+#define IEEE_802154_ADDR_MODE_EXT       0x03 /* Address field contains an extended address (64 bit) */
+
+/* IEEE 802.15.4 Frame Control definitions (2 bytes; see IEEE 802.15.4-2015 ch. 7.2.1) */
+#define IEEE_802154_FC_FT_MASK             0x0007 /* bits 0..2: Frame Type */
+#define IEEE_802154_FC_FT_BEACON               0x00
+#define IEEE_802154_FC_FT_DATA                 0x01
+#define IEEE_802154_FC_FT_ACK                  0x02
+#define IEEE_802154_FC_FT_MAC_CMD              0x03
+#define IEEE_802154_FC_FT_RESERVED             0x04
+#define IEEE_802154_FC_FT_MULTIPURPOSE         0x05
+#define IEEE_802154_FC_FT_FRAG                 0x06
+#define IEEE_802154_FC_FT_EXT                  0x07
+#define IEEE_802154_FC_SEC_EN              0x0008 /* bit 3: Security Enabled */
+#define IEEE_802154_FC_FRAME_PEND          0x0010 /* bit 4: Frame Pending */
+#define IEEE_802154_FC_ACK_REQ             0x0020 /* bit 5: AR (ACK required) */
+#define IEEE_802154_FC_PANID_COMPR         0x0040 /* bit 6: PAN ID Compression (src and dst are equal, src PAN ID omitted) */
+#define IEEE_802154_FC_RESERVED            0x0080
+#define IEEE_802154_FC_SEQNO_SUPPR         0x0100 /* bit 8: Sequence Number Suppression */
+#define IEEE_802154_FC_IE_PRESENT          0x0200 /* bit 9: IE Present */
+#define IEEE_802154_FC_DST_ADDR_MODE_MASK  0x0c00 /* bits 10..11: Destination Addressing Mode */
+#define IEEE_802154_FC_DST_ADDR_MODE_NO_ADDR   (IEEE_802154_ADDR_MODE_NO_ADDR << 10)
+#define IEEE_802154_FC_DST_ADDR_MODE_SHORT     (IEEE_802154_ADDR_MODE_SHORT << 10)
+#define IEEE_802154_FC_DST_ADDR_MODE_EXT       (IEEE_802154_ADDR_MODE_EXT << 10)
+#define IEEE_802154_FC_FRAME_VERSION_MASK  0x3000 /* bits 12..13: Frame Version */
+#define IEEE_802154_FC_FRAME_VERSION_GET(x)    (((x) & IEEE_802154_FC_FRAME_VERSION_MASK) >> 12)
+#define IEEE_802154_FC_SRC_ADDR_MODE_MASK  0xc000 /* bits 14..15: Source Addressing Mode */
+#define IEEE_802154_FC_SRC_ADDR_MODE_SHORT     (IEEE_802154_ADDR_MODE_SHORT << 14)
+#define IEEE_802154_FC_SRC_ADDR_MODE_EXT       (IEEE_802154_ADDR_MODE_EXT << 14)
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LWIP_HDR_NETIF_IEEE802154_H */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/netif/lowpan6.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/netif/lowpan6.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/netif/lowpan6.h	(revision 457)
@@ -0,0 +1,89 @@
+/**
+ * @file
+ *
+ * 6LowPAN output for IPv6. Uses ND tables for link-layer addressing. Fragments packets to 6LowPAN units.
+ */
+
+/*
+ * Copyright (c) 2015 Inico Technologies Ltd.
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Ivan Delamer <delamer@inicotech.com>
+ *
+ *
+ * Please coordinate changes and requests with Ivan Delamer
+ * <delamer@inicotech.com>
+ */
+
+#ifndef LWIP_HDR_LOWPAN6_H
+#define LWIP_HDR_LOWPAN6_H
+
+#include "netif/lowpan6_opts.h"
+
+#if LWIP_IPV6
+
+#include "netif/lowpan6_common.h"
+#include "lwip/pbuf.h"
+#include "lwip/ip.h"
+#include "lwip/ip_addr.h"
+#include "lwip/netif.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** 1 second period for reassembly */
+#define LOWPAN6_TMR_INTERVAL 1000
+
+void lowpan6_tmr(void);
+
+err_t lowpan6_set_context(u8_t idx, const ip6_addr_t * context);
+err_t lowpan6_set_short_addr(u8_t addr_high, u8_t addr_low);
+
+#if LWIP_IPV4
+err_t lowpan4_output(struct netif *netif, struct pbuf *q, const ip4_addr_t *ipaddr);
+#endif /* LWIP_IPV4 */
+err_t lowpan6_output(struct netif *netif, struct pbuf *q, const ip6_addr_t *ip6addr);
+err_t lowpan6_input(struct pbuf * p, struct netif *netif);
+err_t lowpan6_if_init(struct netif *netif);
+
+/* pan_id in network byte order. */
+err_t lowpan6_set_pan_id(u16_t pan_id);
+
+u16_t lowpan6_calc_crc(const void *buf, u16_t len);
+
+#if !NO_SYS
+err_t tcpip_6lowpan_input(struct pbuf *p, struct netif *inp);
+#endif /* !NO_SYS */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LWIP_IPV6 */
+
+#endif /* LWIP_HDR_LOWPAN6_H */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/netif/lowpan6_ble.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/netif/lowpan6_ble.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/netif/lowpan6_ble.h	(revision 457)
@@ -0,0 +1,78 @@
+/**
+ * @file
+ * 6LowPAN over BLE for IPv6 (RFC7668).
+ */
+
+/*
+ * Copyright (c) 2017 Benjamin Aigner
+ * Copyright (c) 2015 Inico Technologies Ltd. , Author: Ivan Delamer <delamer@inicotech.com>
+ * 
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * Author: Benjamin Aigner <aignerb@technikum-wien.at>
+ * 
+ * Based on the original 6lowpan implementation of lwIP ( @see 6lowpan.c)
+ */
+ 
+#ifndef LWIP_HDR_LOWPAN6_BLE_H
+#define LWIP_HDR_LOWPAN6_BLE_H
+
+#include "netif/lowpan6_opts.h"
+
+#if LWIP_IPV6 /* don't build if not configured for use in lwipopts.h */
+
+#include "netif/lowpan6_common.h"
+#include "lwip/pbuf.h"
+#include "lwip/ip.h"
+#include "lwip/ip_addr.h"
+#include "lwip/netif.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+err_t rfc7668_output(struct netif *netif, struct pbuf *q, const ip6_addr_t *ip6addr);
+err_t rfc7668_input(struct pbuf * p, struct netif *netif);
+err_t rfc7668_set_local_addr_eui64(struct netif *netif, const u8_t *local_addr, size_t local_addr_len);
+err_t rfc7668_set_local_addr_mac48(struct netif *netif, const u8_t *local_addr, size_t local_addr_len, int is_public_addr);
+err_t rfc7668_set_peer_addr_eui64(struct netif *netif, const u8_t *peer_addr, size_t peer_addr_len);
+err_t rfc7668_set_peer_addr_mac48(struct netif *netif, const u8_t *peer_addr, size_t peer_addr_len, int is_public_addr);
+err_t rfc7668_set_context(u8_t index, const ip6_addr_t * context);
+err_t rfc7668_if_init(struct netif *netif);
+
+#if !NO_SYS
+err_t tcpip_rfc7668_input(struct pbuf *p, struct netif *inp);
+#endif
+
+void ble_addr_to_eui64(uint8_t *dst, const uint8_t *src, int public_addr);
+void eui64_to_ble_addr(uint8_t *dst, const uint8_t *src);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LWIP_IPV6 */
+
+#endif /* LWIP_HDR_LOWPAN6_BLE_H */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/netif/lowpan6_common.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/netif/lowpan6_common.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/netif/lowpan6_common.h	(revision 457)
@@ -0,0 +1,82 @@
+/**
+ * @file
+ *
+ * Common 6LowPAN routines for IPv6. Uses ND tables for link-layer addressing. Fragments packets to 6LowPAN units.
+ */
+
+/*
+ * Copyright (c) 2015 Inico Technologies Ltd.
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Ivan Delamer <delamer@inicotech.com>
+ *
+ *
+ * Please coordinate changes and requests with Ivan Delamer
+ * <delamer@inicotech.com>
+ */
+
+#ifndef LWIP_HDR_LOWPAN6_COMMON_H
+#define LWIP_HDR_LOWPAN6_COMMON_H
+
+#include "netif/lowpan6_opts.h"
+
+#if LWIP_IPV6 /* don't build if IPv6 is disabled in lwipopts.h */
+
+#include "lwip/pbuf.h"
+#include "lwip/ip.h"
+#include "lwip/ip6_addr.h"
+#include "lwip/netif.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Helper define for a link layer address, which can be encoded as 0, 2 or 8 bytes */
+struct lowpan6_link_addr {
+  /* encoded length of the address */
+  u8_t addr_len;
+  /* address bytes */
+  u8_t addr[8];
+};
+
+s8_t lowpan6_get_address_mode(const ip6_addr_t *ip6addr, const struct lowpan6_link_addr *mac_addr);
+
+#if LWIP_6LOWPAN_IPHC
+err_t lowpan6_compress_headers(struct netif *netif, u8_t *inbuf, size_t inbuf_size, u8_t *outbuf, size_t outbuf_size,
+                               u8_t *lowpan6_header_len_out, u8_t *hidden_header_len_out, ip6_addr_t *lowpan6_contexts,
+                               const struct lowpan6_link_addr *src, const struct lowpan6_link_addr *dst);
+struct pbuf *lowpan6_decompress(struct pbuf *p, u16_t datagram_size, ip6_addr_t *lowpan6_contexts,
+                                struct lowpan6_link_addr *src, struct lowpan6_link_addr *dest);
+#endif /* LWIP_6LOWPAN_IPHC */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LWIP_IPV6 */
+
+#endif /* LWIP_HDR_LOWPAN6_COMMON_H */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/netif/lowpan6_opts.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/netif/lowpan6_opts.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/netif/lowpan6_opts.h	(revision 457)
@@ -0,0 +1,122 @@
+/**
+ * @file
+ * 6LowPAN options list
+ */
+
+/*
+ * Copyright (c) 2015 Inico Technologies Ltd.
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Ivan Delamer <delamer@inicotech.com>
+ *
+ *
+ * Please coordinate changes and requests with Ivan Delamer
+ * <delamer@inicotech.com>
+ */
+
+#ifndef LWIP_HDR_LOWPAN6_OPTS_H
+#define LWIP_HDR_LOWPAN6_OPTS_H
+
+#include "lwip/opt.h"
+
+/** LWIP_6LOWPAN_NUM_CONTEXTS: define the number of compression
+ * contexts per netif type
+ */
+#ifndef LWIP_6LOWPAN_NUM_CONTEXTS
+#define LWIP_6LOWPAN_NUM_CONTEXTS        10
+#endif
+
+/** LWIP_6LOWPAN_INFER_SHORT_ADDRESS: set this to 0 to disable creating
+ * short addresses for matching addresses (debug only)
+ */
+#ifndef LWIP_6LOWPAN_INFER_SHORT_ADDRESS
+#define LWIP_6LOWPAN_INFER_SHORT_ADDRESS 1
+#endif
+
+/** LWIP_6LOWPAN_IPHC: set this to 0 to disable IP header compression as per
+ * RFC 6282 (which is mandatory for BLE)
+ */
+#ifndef LWIP_6LOWPAN_IPHC
+#define LWIP_6LOWPAN_IPHC                1
+#endif
+
+/** Set this to 1 if your IEEE 802.15.4 interface can calculate and check the
+ * CRC in hardware. This means TX packets get 2 zero bytes added on transmission
+ * which are to be filled with the CRC.
+ */
+#ifndef LWIP_6LOWPAN_802154_HW_CRC
+#define LWIP_6LOWPAN_802154_HW_CRC       0
+#endif
+
+/** If LWIP_6LOWPAN_802154_HW_CRC==0, this can override the default slow
+ * implementation of the CRC used for 6LoWPAN over IEEE 802.15.4 (which uses
+ * a shift register).
+ */
+#ifndef LWIP_6LOWPAN_CALC_CRC
+#define LWIP_6LOWPAN_CALC_CRC(buf, len)  lowpan6_calc_crc(buf, len)
+#endif
+
+/** Debug level for 6LoWPAN in general */
+#ifndef LWIP_LOWPAN6_DEBUG
+#define LWIP_LOWPAN6_DEBUG               LWIP_DBG_OFF
+#endif
+
+/** Debug level for 6LoWPAN over IEEE 802.15.4 */
+#ifndef LWIP_LOWPAN6_802154_DEBUG
+#define LWIP_LOWPAN6_802154_DEBUG        LWIP_DBG_OFF
+#endif
+
+/** LWIP_LOWPAN6_IP_COMPRESSED_DEBUG: enable compressed IP frame
+ * output debugging
+ */
+#ifndef LWIP_LOWPAN6_IP_COMPRESSED_DEBUG
+#define LWIP_LOWPAN6_IP_COMPRESSED_DEBUG      LWIP_DBG_OFF
+#endif
+
+/** LWIP_LOWPAN6_DECOMPRESSION_DEBUG: enable decompression debug output
+ */
+#ifndef LWIP_LOWPAN6_DECOMPRESSION_DEBUG
+#define LWIP_LOWPAN6_DECOMPRESSION_DEBUG      LWIP_DBG_OFF
+#endif
+
+/** LWIP_RFC7668_IP_UNCOMPRESSED_DEBUG: enable decompressed IP frame
+ * output debugging */
+#ifndef LWIP_RFC7668_IP_UNCOMPRESSED_DEBUG
+#define LWIP_RFC7668_IP_UNCOMPRESSED_DEBUG    LWIP_DBG_OFF
+#endif
+
+/** LWIP_RFC7668_LINUX_WORKAROUND_PUBLIC_ADDRESS: 
+ * Currently, the linux kernel driver for 6lowpan sets/clears a bit in
+ * the address, depending on the BD address (either public or not).
+ * Might not be RFC7668 conform, so you may select to do that (=1) or
+ * not (=0) */
+#ifndef LWIP_RFC7668_LINUX_WORKAROUND_PUBLIC_ADDRESS
+#define LWIP_RFC7668_LINUX_WORKAROUND_PUBLIC_ADDRESS 1
+#endif
+
+
+#endif /* LWIP_HDR_LOWPAN6_OPTS_H */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/netif/ppp/ccp.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/netif/ppp/ccp.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/netif/ppp/ccp.h	(revision 457)
@@ -0,0 +1,164 @@
+/*
+ * ccp.h - Definitions for PPP Compression Control Protocol.
+ *
+ * Copyright (c) 1994-2002 Paul Mackerras. 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. The name(s) of the authors of this software must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission.
+ *
+ * 3. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by Paul Mackerras
+ *     <paulus@samba.org>".
+ *
+ * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO
+ * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
+ * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
+ * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
+ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * $Id$
+ */
+
+#include "netif/ppp/ppp_opts.h"
+#if PPP_SUPPORT && CCP_SUPPORT  /* don't build if not configured for use in lwipopts.h */
+
+#ifndef CCP_H
+#define CCP_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * CCP codes.
+ */
+
+#define CCP_CONFREQ	1
+#define CCP_CONFACK	2
+#define CCP_TERMREQ	5
+#define CCP_TERMACK	6
+#define CCP_RESETREQ	14
+#define CCP_RESETACK	15
+
+/*
+ * Max # bytes for a CCP option
+ */
+
+#define CCP_MAX_OPTION_LENGTH	32
+
+/*
+ * Parts of a CCP packet.
+ */
+
+#define CCP_CODE(dp)		((dp)[0])
+#define CCP_ID(dp)		((dp)[1])
+#define CCP_LENGTH(dp)		(((dp)[2] << 8) + (dp)[3])
+#define CCP_HDRLEN		4
+
+#define CCP_OPT_CODE(dp)	((dp)[0])
+#define CCP_OPT_LENGTH(dp)	((dp)[1])
+#define CCP_OPT_MINLEN		2
+
+#if BSDCOMPRESS_SUPPORT
+/*
+ * Definitions for BSD-Compress.
+ */
+
+#define CI_BSD_COMPRESS		21	/* config. option for BSD-Compress */
+#define CILEN_BSD_COMPRESS	3	/* length of config. option */
+
+/* Macros for handling the 3rd byte of the BSD-Compress config option. */
+#define BSD_NBITS(x)		((x) & 0x1F)	/* number of bits requested */
+#define BSD_VERSION(x)		((x) >> 5)	/* version of option format */
+#define BSD_CURRENT_VERSION	1		/* current version number */
+#define BSD_MAKE_OPT(v, n)	(((v) << 5) | (n))
+
+#define BSD_MIN_BITS		9	/* smallest code size supported */
+#define BSD_MAX_BITS		15	/* largest code size supported */
+#endif /* BSDCOMPRESS_SUPPORT */
+
+#if DEFLATE_SUPPORT
+/*
+ * Definitions for Deflate.
+ */
+
+#define CI_DEFLATE		26	/* config option for Deflate */
+#define CI_DEFLATE_DRAFT	24	/* value used in original draft RFC */
+#define CILEN_DEFLATE		4	/* length of its config option */
+
+#define DEFLATE_MIN_SIZE	9
+#define DEFLATE_MAX_SIZE	15
+#define DEFLATE_METHOD_VAL	8
+#define DEFLATE_SIZE(x)		(((x) >> 4) + 8)
+#define DEFLATE_METHOD(x)	((x) & 0x0F)
+#define DEFLATE_MAKE_OPT(w)	((((w) - 8) << 4) + DEFLATE_METHOD_VAL)
+#define DEFLATE_CHK_SEQUENCE	0
+#endif /* DEFLATE_SUPPORT */
+
+#if MPPE_SUPPORT
+/*
+ * Definitions for MPPE.
+ */
+
+#define CI_MPPE                18      /* config option for MPPE */
+#define CILEN_MPPE              6      /* length of config option */
+#endif /* MPPE_SUPPORT */
+
+#if PREDICTOR_SUPPORT
+/*
+ * Definitions for other, as yet unsupported, compression methods.
+ */
+
+#define CI_PREDICTOR_1		1	/* config option for Predictor-1 */
+#define CILEN_PREDICTOR_1	2	/* length of its config option */
+#define CI_PREDICTOR_2		2	/* config option for Predictor-2 */
+#define CILEN_PREDICTOR_2	2	/* length of its config option */
+#endif /* PREDICTOR_SUPPORT */
+
+typedef struct ccp_options {
+#if DEFLATE_SUPPORT
+    unsigned int deflate          :1; /* do Deflate? */
+    unsigned int deflate_correct  :1; /* use correct code for deflate? */
+    unsigned int deflate_draft    :1; /* use draft RFC code for deflate? */
+#endif /* DEFLATE_SUPPORT */
+#if BSDCOMPRESS_SUPPORT
+    unsigned int bsd_compress     :1; /* do BSD Compress? */
+#endif /* BSDCOMPRESS_SUPPORT */
+#if PREDICTOR_SUPPORT
+    unsigned int predictor_1      :1; /* do Predictor-1? */
+    unsigned int predictor_2      :1; /* do Predictor-2? */
+#endif /* PREDICTOR_SUPPORT */
+
+#if MPPE_SUPPORT
+    u8_t mppe;			/* MPPE bitfield */
+#endif /* MPPE_SUPPORT */
+#if BSDCOMPRESS_SUPPORT
+    u_short bsd_bits;		/* # bits/code for BSD Compress */
+#endif /* BSDCOMPRESS_SUPPORT */
+#if DEFLATE_SUPPORT
+    u_short deflate_size;	/* lg(window size) for Deflate */
+#endif /* DEFLATE_SUPPORT */
+    u8_t method;		/* code for chosen compression method */
+} ccp_options;
+
+extern const struct protent ccp_protent;
+
+void ccp_resetrequest(ppp_pcb *pcb);  /* Issue a reset-request. */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* CCP_H */
+#endif /* PPP_SUPPORT && CCP_SUPPORT */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/netif/ppp/chap-md5.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/netif/ppp/chap-md5.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/netif/ppp/chap-md5.h	(revision 457)
@@ -0,0 +1,36 @@
+/*
+ * chap-md5.h - New CHAP/MD5 implementation.
+ *
+ * Copyright (c) 2003 Paul Mackerras. 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. The name(s) of the authors of this software must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission.
+ *
+ * 3. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by Paul Mackerras
+ *     <paulus@samba.org>".
+ *
+ * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO
+ * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
+ * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
+ * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
+ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include "netif/ppp/ppp_opts.h"
+#if PPP_SUPPORT && CHAP_SUPPORT  /* don't build if not configured for use in lwipopts.h */
+
+extern const struct chap_digest_type md5_digest;
+
+#endif /* PPP_SUPPORT && CHAP_SUPPORT */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/netif/ppp/chap-new.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/netif/ppp/chap-new.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/netif/ppp/chap-new.h	(revision 457)
@@ -0,0 +1,200 @@
+/*
+ * chap-new.c - New CHAP implementation.
+ *
+ * Copyright (c) 2003 Paul Mackerras. 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. The name(s) of the authors of this software must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission.
+ *
+ * 3. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by Paul Mackerras
+ *     <paulus@samba.org>".
+ *
+ * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO
+ * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
+ * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
+ * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
+ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include "netif/ppp/ppp_opts.h"
+#if PPP_SUPPORT && CHAP_SUPPORT  /* don't build if not configured for use in lwipopts.h */
+
+#ifndef CHAP_H
+#define CHAP_H
+
+#include "ppp.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * CHAP packets begin with a standard header with code, id, len (2 bytes).
+ */
+#define CHAP_HDRLEN	4
+
+/*
+ * Values for the code field.
+ */
+#define CHAP_CHALLENGE	1
+#define CHAP_RESPONSE	2
+#define CHAP_SUCCESS	3
+#define CHAP_FAILURE	4
+
+/*
+ * CHAP digest codes.
+ */
+#define CHAP_MD5		5
+#if MSCHAP_SUPPORT
+#define CHAP_MICROSOFT		0x80
+#define CHAP_MICROSOFT_V2	0x81
+#endif /* MSCHAP_SUPPORT */
+
+/*
+ * Semi-arbitrary limits on challenge and response fields.
+ */
+#define MAX_CHALLENGE_LEN	64
+#define MAX_RESPONSE_LEN	64
+
+/*
+ * These limits apply to challenge and response packets we send.
+ * The +4 is the +1 that we actually need rounded up.
+ */
+#define CHAL_MAX_PKTLEN	(PPP_HDRLEN + CHAP_HDRLEN + 4 + MAX_CHALLENGE_LEN + MAXNAMELEN)
+#define RESP_MAX_PKTLEN	(PPP_HDRLEN + CHAP_HDRLEN + 4 + MAX_RESPONSE_LEN + MAXNAMELEN)
+
+/* bitmask of supported algorithms */
+#if MSCHAP_SUPPORT
+#define MDTYPE_MICROSOFT_V2	0x1
+#define MDTYPE_MICROSOFT	0x2
+#endif /* MSCHAP_SUPPORT */
+#define MDTYPE_MD5		0x4
+#define MDTYPE_NONE		0
+
+#if MSCHAP_SUPPORT
+/* Return the digest alg. ID for the most preferred digest type. */
+#define CHAP_DIGEST(mdtype) \
+    ((mdtype) & MDTYPE_MD5)? CHAP_MD5: \
+    ((mdtype) & MDTYPE_MICROSOFT_V2)? CHAP_MICROSOFT_V2: \
+    ((mdtype) & MDTYPE_MICROSOFT)? CHAP_MICROSOFT: \
+    0
+#else /* !MSCHAP_SUPPORT */
+#define CHAP_DIGEST(mdtype) \
+    ((mdtype) & MDTYPE_MD5)? CHAP_MD5: \
+    0
+#endif /* MSCHAP_SUPPORT */
+
+/* Return the bit flag (lsb set) for our most preferred digest type. */
+#define CHAP_MDTYPE(mdtype) ((mdtype) ^ ((mdtype) - 1)) & (mdtype)
+
+/* Return the bit flag for a given digest algorithm ID. */
+#if MSCHAP_SUPPORT
+#define CHAP_MDTYPE_D(digest) \
+    ((digest) == CHAP_MICROSOFT_V2)? MDTYPE_MICROSOFT_V2: \
+    ((digest) == CHAP_MICROSOFT)? MDTYPE_MICROSOFT: \
+    ((digest) == CHAP_MD5)? MDTYPE_MD5: \
+    0
+#else /* !MSCHAP_SUPPORT */
+#define CHAP_MDTYPE_D(digest) \
+    ((digest) == CHAP_MD5)? MDTYPE_MD5: \
+    0
+#endif /* MSCHAP_SUPPORT */
+
+/* Can we do the requested digest? */
+#if MSCHAP_SUPPORT
+#define CHAP_CANDIGEST(mdtype, digest) \
+    ((digest) == CHAP_MICROSOFT_V2)? (mdtype) & MDTYPE_MICROSOFT_V2: \
+    ((digest) == CHAP_MICROSOFT)? (mdtype) & MDTYPE_MICROSOFT: \
+    ((digest) == CHAP_MD5)? (mdtype) & MDTYPE_MD5: \
+    0
+#else /* !MSCHAP_SUPPORT */
+#define CHAP_CANDIGEST(mdtype, digest) \
+    ((digest) == CHAP_MD5)? (mdtype) & MDTYPE_MD5: \
+    0
+#endif /* MSCHAP_SUPPORT */
+
+/*
+ * The code for each digest type has to supply one of these.
+ */
+struct chap_digest_type {
+	int code;
+
+#if PPP_SERVER
+	/*
+	 * Note: challenge and response arguments below are formatted as
+	 * a length byte followed by the actual challenge/response data.
+	 */
+	void (*generate_challenge)(ppp_pcb *pcb, unsigned char *challenge);
+	int (*verify_response)(ppp_pcb *pcb, int id, const char *name,
+		const unsigned char *secret, int secret_len,
+		const unsigned char *challenge, const unsigned char *response,
+		char *message, int message_space);
+#endif /* PPP_SERVER */
+	void (*make_response)(ppp_pcb *pcb, unsigned char *response, int id, const char *our_name,
+		const unsigned char *challenge, const char *secret, int secret_len,
+		unsigned char *priv);
+	int (*check_success)(ppp_pcb *pcb, unsigned char *pkt, int len, unsigned char *priv);
+	void (*handle_failure)(ppp_pcb *pcb, unsigned char *pkt, int len);
+};
+
+/*
+ * Each interface is described by chap structure.
+ */
+#if CHAP_SUPPORT
+typedef struct chap_client_state {
+	u8_t flags;
+	const char *name;
+	const struct chap_digest_type *digest;
+	unsigned char priv[64];		/* private area for digest's use */
+} chap_client_state;
+
+#if PPP_SERVER
+typedef struct chap_server_state {
+	u8_t flags;
+	u8_t id;
+	const char *name;
+	const struct chap_digest_type *digest;
+	int challenge_xmits;
+	int challenge_pktlen;
+	unsigned char challenge[CHAL_MAX_PKTLEN];
+} chap_server_state;
+#endif /* PPP_SERVER */
+#endif /* CHAP_SUPPORT */
+
+#if 0 /* UNUSED */
+/* Hook for a plugin to validate CHAP challenge */
+extern int (*chap_verify_hook)(char *name, char *ourname, int id,
+			const struct chap_digest_type *digest,
+			unsigned char *challenge, unsigned char *response,
+			char *message, int message_space);
+#endif /* UNUSED */
+
+#if PPP_SERVER
+/* Called by authentication code to start authenticating the peer. */
+extern void chap_auth_peer(ppp_pcb *pcb, const char *our_name, int digest_code);
+#endif /* PPP_SERVER */
+
+/* Called by auth. code to start authenticating us to the peer. */
+extern void chap_auth_with_peer(ppp_pcb *pcb, const char *our_name, int digest_code);
+
+/* Represents the CHAP protocol to the main pppd code */
+extern const struct protent chap_protent;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* CHAP_H */
+#endif /* PPP_SUPPORT && CHAP_SUPPORT */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/netif/ppp/chap_ms.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/netif/ppp/chap_ms.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/netif/ppp/chap_ms.h	(revision 457)
@@ -0,0 +1,44 @@
+/*
+ * chap_ms.h - Challenge Handshake Authentication Protocol definitions.
+ *
+ * Copyright (c) 1995 Eric Rosenquist.  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. The name(s) of the authors of this software must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission.
+ *
+ * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO
+ * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
+ * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
+ * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
+ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * $Id$
+ */
+
+#include "netif/ppp/ppp_opts.h"
+#if PPP_SUPPORT && MSCHAP_SUPPORT  /* don't build if not configured for use in lwipopts.h */
+
+#ifndef CHAPMS_INCLUDE
+#define CHAPMS_INCLUDE
+
+extern const struct chap_digest_type chapms_digest;
+extern const struct chap_digest_type chapms2_digest;
+
+#endif /* CHAPMS_INCLUDE */
+
+#endif /* PPP_SUPPORT && MSCHAP_SUPPORT */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/netif/ppp/eap.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/netif/ppp/eap.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/netif/ppp/eap.h	(revision 457)
@@ -0,0 +1,169 @@
+/*
+ * eap.h - Extensible Authentication Protocol for PPP (RFC 2284)
+ *
+ * Copyright (c) 2001 by Sun Microsystems, Inc.
+ * All rights reserved.
+ *
+ * Non-exclusive rights to redistribute, modify, translate, and use
+ * this software in source and binary forms, in whole or in part, is
+ * hereby granted, provided that the above copyright notice is
+ * duplicated in any source form, and that neither the name of the
+ * copyright holder nor the author is used to endorse or promote
+ * products derived from this software.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * Original version by James Carlson
+ *
+ * $Id$
+ */
+
+#include "netif/ppp/ppp_opts.h"
+#if PPP_SUPPORT && EAP_SUPPORT  /* don't build if not configured for use in lwipopts.h */
+
+#ifndef PPP_EAP_H
+#define	PPP_EAP_H
+
+#include "ppp.h"
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+
+/*
+ * Packet header = Code, id, length.
+ */
+#define	EAP_HEADERLEN	4
+
+
+/* EAP message codes. */
+#define	EAP_REQUEST	1
+#define	EAP_RESPONSE	2
+#define	EAP_SUCCESS	3
+#define	EAP_FAILURE	4
+
+/* EAP types */
+#define	EAPT_IDENTITY		1
+#define	EAPT_NOTIFICATION	2
+#define	EAPT_NAK		3	/* (response only) */
+#define	EAPT_MD5CHAP		4
+#define	EAPT_OTP		5	/* One-Time Password; RFC 1938 */
+#define	EAPT_TOKEN		6	/* Generic Token Card */
+/* 7 and 8 are unassigned. */
+#define	EAPT_RSA		9	/* RSA Public Key Authentication */
+#define	EAPT_DSS		10	/* DSS Unilateral */
+#define	EAPT_KEA		11	/* KEA */
+#define	EAPT_KEA_VALIDATE	12	/* KEA-VALIDATE	*/
+#define	EAPT_TLS		13	/* EAP-TLS */
+#define	EAPT_DEFENDER		14	/* Defender Token (AXENT) */
+#define	EAPT_W2K		15	/* Windows 2000 EAP */
+#define	EAPT_ARCOT		16	/* Arcot Systems */
+#define	EAPT_CISCOWIRELESS	17	/* Cisco Wireless */
+#define	EAPT_NOKIACARD		18	/* Nokia IP smart card */
+#define	EAPT_SRP		19	/* Secure Remote Password */
+/* 20 is deprecated */
+
+/* EAP SRP-SHA1 Subtypes */
+#define	EAPSRP_CHALLENGE	1	/* Request 1 - Challenge */
+#define	EAPSRP_CKEY		1	/* Response 1 - Client Key */
+#define	EAPSRP_SKEY		2	/* Request 2 - Server Key */
+#define	EAPSRP_CVALIDATOR	2	/* Response 2 - Client Validator */
+#define	EAPSRP_SVALIDATOR	3	/* Request 3 - Server Validator */
+#define	EAPSRP_ACK		3	/* Response 3 - final ack */
+#define	EAPSRP_LWRECHALLENGE	4	/* Req/resp 4 - Lightweight rechal */
+
+#define	SRPVAL_EBIT	0x00000001	/* Use shared key for ECP */
+
+#define	SRP_PSEUDO_ID	"pseudo_"
+#define	SRP_PSEUDO_LEN	7
+
+#define MD5_SIGNATURE_SIZE	16
+#define EAP_MIN_CHALLENGE_LENGTH	17
+#define EAP_MAX_CHALLENGE_LENGTH	24
+#define EAP_MIN_MAX_POWER_OF_TWO_CHALLENGE_LENGTH     3   /* 2^3-1 = 7, 17+7 = 24 */
+
+#define	EAP_STATES	\
+	"Initial", "Pending", "Closed", "Listen", "Identify", \
+	"SRP1", "SRP2", "SRP3", "MD5Chall", "Open", "SRP4", "BadAuth"
+
+#define	eap_client_active(pcb)	((pcb)->eap.es_client.ea_state == eapListen)
+#if PPP_SERVER
+#define	eap_server_active(pcb)	\
+	((pcb)->eap.es_server.ea_state >= eapIdentify && \
+	 (pcb)->eap.es_server.ea_state <= eapMD5Chall)
+#endif /* PPP_SERVER */
+
+/*
+ * Complete EAP state for one PPP session.
+ */
+enum eap_state_code {
+	eapInitial = 0,	/* No EAP authentication yet requested */
+	eapPending,	/* Waiting for LCP (no timer) */
+	eapClosed,	/* Authentication not in use */
+	eapListen,	/* Client ready (and timer running) */
+	eapIdentify,	/* EAP Identify sent */
+	eapSRP1,	/* Sent EAP SRP-SHA1 Subtype 1 */
+	eapSRP2,	/* Sent EAP SRP-SHA1 Subtype 2 */
+	eapSRP3,	/* Sent EAP SRP-SHA1 Subtype 3 */
+	eapMD5Chall,	/* Sent MD5-Challenge */
+	eapOpen,	/* Completed authentication */
+	eapSRP4,	/* Sent EAP SRP-SHA1 Subtype 4 */
+	eapBadAuth	/* Failed authentication */
+};
+
+struct eap_auth {
+	const char *ea_name;	/* Our name */
+	char ea_peer[MAXNAMELEN +1];	/* Peer's name */
+	void *ea_session;	/* Authentication library linkage */
+	u_char *ea_skey;	/* Shared encryption key */
+	u_short ea_namelen;	/* Length of our name */
+	u_short ea_peerlen;	/* Length of peer's name */
+	enum eap_state_code ea_state;
+	u_char ea_id;		/* Current id */
+	u_char ea_requests;	/* Number of Requests sent/received */
+	u_char ea_responses;	/* Number of Responses */
+	u_char ea_type;		/* One of EAPT_* */
+	u32_t ea_keyflags;	/* SRP shared key usage flags */
+};
+
+#ifndef EAP_MAX_CHALLENGE_LENGTH
+#define EAP_MAX_CHALLENGE_LENGTH	24
+#endif
+typedef struct eap_state {
+	struct eap_auth es_client;	/* Client (authenticatee) data */
+#if PPP_SERVER
+	struct eap_auth es_server;	/* Server (authenticator) data */
+#endif /* PPP_SERVER */
+	int es_savedtime;		/* Saved timeout */
+	int es_rechallenge;		/* EAP rechallenge interval */
+	int es_lwrechallenge;		/* SRP lightweight rechallenge inter */
+	u8_t es_usepseudo;		/* Use SRP Pseudonym if offered one */
+	int es_usedpseudo;		/* Set if we already sent PN */
+	int es_challen;			/* Length of challenge string */
+	u_char es_challenge[EAP_MAX_CHALLENGE_LENGTH];
+} eap_state;
+
+/*
+ * Timeouts.
+ */
+#if 0 /* moved to ppp_opts.h */
+#define	EAP_DEFTIMEOUT		3	/* Timeout (seconds) for rexmit */
+#define	EAP_DEFTRANSMITS	10	/* max # times to transmit */
+#define	EAP_DEFREQTIME		20	/* Time to wait for peer request */
+#define	EAP_DEFALLOWREQ		20	/* max # times to accept requests */
+#endif /* moved to ppp_opts.h */
+
+void eap_authwithpeer(ppp_pcb *pcb, const char *localname);
+void eap_authpeer(ppp_pcb *pcb, const char *localname);
+
+extern const struct protent eap_protent;
+
+#ifdef	__cplusplus
+}
+#endif
+
+#endif /* PPP_EAP_H */
+
+#endif /* PPP_SUPPORT && EAP_SUPPORT */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/netif/ppp/ecp.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/netif/ppp/ecp.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/netif/ppp/ecp.h	(revision 457)
@@ -0,0 +1,62 @@
+/*
+ * ecp.h - Definitions for PPP Encryption Control Protocol.
+ *
+ * Copyright (c) 2002 Google, Inc.
+ * 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. The name(s) of the authors of this software must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission.
+ *
+ * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO
+ * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
+ * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
+ * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
+ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * $Id$
+ */
+
+#include "netif/ppp/ppp_opts.h"
+#if PPP_SUPPORT && ECP_SUPPORT  /* don't build if not configured for use in lwipopts.h */
+
+#ifndef ECP_H
+#define ECP_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct ecp_options {
+    bool required;		/* Is ECP required? */
+    unsigned enctype;		/* Encryption type */
+} ecp_options;
+
+extern fsm ecp_fsm[];
+extern ecp_options ecp_wantoptions[];
+extern ecp_options ecp_gotoptions[];
+extern ecp_options ecp_allowoptions[];
+extern ecp_options ecp_hisoptions[];
+
+extern const struct protent ecp_protent;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* ECP_H */
+#endif /* PPP_SUPPORT && ECP_SUPPORT */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/netif/ppp/eui64.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/netif/ppp/eui64.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/netif/ppp/eui64.h	(revision 457)
@@ -0,0 +1,102 @@
+/*
+ * eui64.h - EUI64 routines for IPv6CP.
+ *
+ * Copyright (c) 1999 Tommi Komulainen.  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. The name(s) of the authors of this software must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission.
+ *
+ * 4. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by Tommi Komulainen
+ *     <Tommi.Komulainen@iki.fi>".
+ *
+ * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO
+ * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
+ * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
+ * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
+ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * $Id$
+*/
+
+#include "netif/ppp/ppp_opts.h"
+#if PPP_SUPPORT && PPP_IPV6_SUPPORT  /* don't build if not configured for use in lwipopts.h */
+
+#ifndef EUI64_H
+#define EUI64_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * @todo:
+ *
+ * Maybe this should be done by processing struct in6_addr directly...
+ */
+typedef union
+{
+    u8_t e8[8];
+    u16_t e16[4];
+    u32_t e32[2];
+} eui64_t;
+
+#define eui64_iszero(e)		(((e).e32[0] | (e).e32[1]) == 0)
+#define eui64_equals(e, o)	(((e).e32[0] == (o).e32[0]) && \
+				((e).e32[1] == (o).e32[1]))
+#define eui64_zero(e)		(e).e32[0] = (e).e32[1] = 0;
+
+#define eui64_copy(s, d)	memcpy(&(d), &(s), sizeof(eui64_t))
+
+#define eui64_magic(e)		do {			\
+				(e).e32[0] = magic();	\
+				(e).e32[1] = magic();	\
+				(e).e8[0] &= ~2;	\
+				} while (0)
+#define eui64_magic_nz(x)	do {				\
+				eui64_magic(x);			\
+				} while (eui64_iszero(x))
+#define eui64_magic_ne(x, y)	do {				\
+				eui64_magic(x);			\
+				} while (eui64_equals(x, y))
+
+#define eui64_get(ll, cp)	do {				\
+				eui64_copy((*cp), (ll));	\
+				(cp) += sizeof(eui64_t);	\
+				} while (0)
+
+#define eui64_put(ll, cp)	do {				\
+				eui64_copy((ll), (*cp));	\
+				(cp) += sizeof(eui64_t);	\
+				} while (0)
+
+#define eui64_set32(e, l)	do {			\
+				(e).e32[0] = 0;		\
+				(e).e32[1] = lwip_htonl(l);	\
+				} while (0)
+#define eui64_setlo32(e, l)	eui64_set32(e, l)
+
+char *eui64_ntoa(eui64_t);	/* Returns ascii representation of id */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* EUI64_H */
+#endif /* PPP_SUPPORT && PPP_IPV6_SUPPORT */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/netif/ppp/fsm.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/netif/ppp/fsm.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/netif/ppp/fsm.h	(revision 457)
@@ -0,0 +1,182 @@
+/*
+ * fsm.h - {Link, IP} Control Protocol Finite State Machine definitions.
+ *
+ * Copyright (c) 1984-2000 Carnegie Mellon University. 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. The name "Carnegie Mellon University" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For permission or any legal
+ *    details, please contact
+ *      Office of Technology Transfer
+ *      Carnegie Mellon University
+ *      5000 Forbes Avenue
+ *      Pittsburgh, PA  15213-3890
+ *      (412) 268-4387, fax: (412) 268-7395
+ *      tech-transfer@andrew.cmu.edu
+ *
+ * 4. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by Computing Services
+ *     at Carnegie Mellon University (http://www.cmu.edu/computing/)."
+ *
+ * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO
+ * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE
+ * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
+ * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
+ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * $Id$
+ */
+
+#include "netif/ppp/ppp_opts.h"
+#if PPP_SUPPORT /* don't build if not configured for use in lwipopts.h */
+
+#ifndef FSM_H
+#define	FSM_H
+
+#include "ppp.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * Packet header = Code, id, length.
+ */
+#define HEADERLEN	4
+
+
+/*
+ *  CP (LCP, IPCP, etc.) codes.
+ */
+#define CONFREQ		1	/* Configuration Request */
+#define CONFACK		2	/* Configuration Ack */
+#define CONFNAK		3	/* Configuration Nak */
+#define CONFREJ		4	/* Configuration Reject */
+#define TERMREQ		5	/* Termination Request */
+#define TERMACK		6	/* Termination Ack */
+#define CODEREJ		7	/* Code Reject */
+
+
+/*
+ * Each FSM is described by an fsm structure and fsm callbacks.
+ */
+typedef struct fsm {
+    ppp_pcb *pcb;		/* PPP Interface */
+    const struct fsm_callbacks *callbacks;	/* Callback routines */
+    const char *term_reason;	/* Reason for closing protocol */
+    u8_t seen_ack;		/* Have received valid Ack/Nak/Rej to Req */
+				  /* -- This is our only flag, we might use u_int :1 if we have more flags */
+    u16_t protocol;		/* Data Link Layer Protocol field value */
+    u8_t state;			/* State */
+    u8_t flags;			/* Contains option bits */
+    u8_t id;			/* Current id */
+    u8_t reqid;			/* Current request id */
+    u8_t retransmits;		/* Number of retransmissions left */
+    u8_t nakloops;		/* Number of nak loops since last ack */
+    u8_t rnakloops;		/* Number of naks received */
+    u8_t maxnakloops;		/* Maximum number of nak loops tolerated
+				   (necessary because IPCP require a custom large max nak loops value) */
+    u8_t term_reason_len;	/* Length of term_reason */
+} fsm;
+
+
+typedef struct fsm_callbacks {
+    void (*resetci)		/* Reset our Configuration Information */
+		(fsm *);
+    int  (*cilen)		/* Length of our Configuration Information */
+		(fsm *);
+    void (*addci) 		/* Add our Configuration Information */
+		(fsm *, u_char *, int *);
+    int  (*ackci)		/* ACK our Configuration Information */
+		(fsm *, u_char *, int);
+    int  (*nakci)		/* NAK our Configuration Information */
+		(fsm *, u_char *, int, int);
+    int  (*rejci)		/* Reject our Configuration Information */
+		(fsm *, u_char *, int);
+    int  (*reqci)		/* Request peer's Configuration Information */
+		(fsm *, u_char *, int *, int);
+    void (*up)			/* Called when fsm reaches PPP_FSM_OPENED state */
+		(fsm *);
+    void (*down)		/* Called when fsm leaves PPP_FSM_OPENED state */
+		(fsm *);
+    void (*starting)		/* Called when we want the lower layer */
+		(fsm *);
+    void (*finished)		/* Called when we don't want the lower layer */
+		(fsm *);
+    void (*protreject)		/* Called when Protocol-Reject received */
+		(int);
+    void (*retransmit)		/* Retransmission is necessary */
+		(fsm *);
+    int  (*extcode)		/* Called when unknown code received */
+		(fsm *, int, int, u_char *, int);
+    const char *proto_name;	/* String name for protocol (for messages) */
+} fsm_callbacks;
+
+
+/*
+ * Link states.
+ */
+#define PPP_FSM_INITIAL		0	/* Down, hasn't been opened */
+#define PPP_FSM_STARTING	1	/* Down, been opened */
+#define PPP_FSM_CLOSED		2	/* Up, hasn't been opened */
+#define PPP_FSM_STOPPED		3	/* Open, waiting for down event */
+#define PPP_FSM_CLOSING		4	/* Terminating the connection, not open */
+#define PPP_FSM_STOPPING	5	/* Terminating, but open */
+#define PPP_FSM_REQSENT		6	/* We've sent a Config Request */
+#define PPP_FSM_ACKRCVD		7	/* We've received a Config Ack */
+#define PPP_FSM_ACKSENT		8	/* We've sent a Config Ack */
+#define PPP_FSM_OPENED		9	/* Connection available */
+
+
+/*
+ * Flags - indicate options controlling FSM operation
+ */
+#define OPT_PASSIVE	1	/* Don't die if we don't get a response */
+#define OPT_RESTART	2	/* Treat 2nd OPEN as DOWN, UP */
+#define OPT_SILENT	4	/* Wait for peer to speak first */
+
+
+/*
+ * Timeouts.
+ */
+#if 0 /* moved to ppp_opts.h */
+#define DEFTIMEOUT	3	/* Timeout time in seconds */
+#define DEFMAXTERMREQS	2	/* Maximum Terminate-Request transmissions */
+#define DEFMAXCONFREQS	10	/* Maximum Configure-Request transmissions */
+#define DEFMAXNAKLOOPS	5	/* Maximum number of nak loops */
+#endif /* moved to ppp_opts.h */
+
+
+/*
+ * Prototypes
+ */
+void fsm_init(fsm *f);
+void fsm_lowerup(fsm *f);
+void fsm_lowerdown(fsm *f);
+void fsm_open(fsm *f);
+void fsm_close(fsm *f, const char *reason);
+void fsm_input(fsm *f, u_char *inpacket, int l);
+void fsm_protreject(fsm *f);
+void fsm_sdata(fsm *f, u_char code, u_char id, const u_char *data, int datalen);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* FSM_H */
+#endif /* PPP_SUPPORT */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/netif/ppp/ipcp.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/netif/ppp/ipcp.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/netif/ppp/ipcp.h	(revision 457)
@@ -0,0 +1,134 @@
+/*
+ * ipcp.h - IP Control Protocol definitions.
+ *
+ * Copyright (c) 1984-2000 Carnegie Mellon University. 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. The name "Carnegie Mellon University" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For permission or any legal
+ *    details, please contact
+ *      Office of Technology Transfer
+ *      Carnegie Mellon University
+ *      5000 Forbes Avenue
+ *      Pittsburgh, PA  15213-3890
+ *      (412) 268-4387, fax: (412) 268-7395
+ *      tech-transfer@andrew.cmu.edu
+ *
+ * 4. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by Computing Services
+ *     at Carnegie Mellon University (http://www.cmu.edu/computing/)."
+ *
+ * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO
+ * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE
+ * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
+ * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
+ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * $Id$
+ */
+
+#include "netif/ppp/ppp_opts.h"
+#if PPP_SUPPORT && PPP_IPV4_SUPPORT /* don't build if not configured for use in lwipopts.h */
+
+#ifndef IPCP_H
+#define	IPCP_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * Options.
+ */
+#define CI_ADDRS	1	/* IP Addresses */
+#if VJ_SUPPORT
+#define CI_COMPRESSTYPE	2	/* Compression Type */
+#endif /* VJ_SUPPORT */
+#define	CI_ADDR		3
+
+#if LWIP_DNS
+#define CI_MS_DNS1      129	/* Primary DNS value */
+#define CI_MS_DNS2      131     /* Secondary DNS value */
+#endif /* LWIP_DNS */
+#if 0 /* UNUSED - WINS */
+#define CI_MS_WINS1     130     /* Primary WINS value */
+#define CI_MS_WINS2     132	/* Secondary WINS value */
+#endif /* UNUSED - WINS */
+
+#if VJ_SUPPORT
+#define MAX_STATES 16		/* from slcompress.h */
+
+#define IPCP_VJMODE_OLD 1	/* "old" mode (option # = 0x0037) */
+#define IPCP_VJMODE_RFC1172 2	/* "old-rfc"mode (option # = 0x002d) */
+#define IPCP_VJMODE_RFC1332 3	/* "new-rfc"mode (option # = 0x002d, */
+                                /*  maxslot and slot number compression) */
+
+#define IPCP_VJ_COMP 0x002d	/* current value for VJ compression option*/
+#define IPCP_VJ_COMP_OLD 0x0037	/* "old" (i.e, broken) value for VJ */
+				/* compression option*/ 
+#endif /* VJ_SUPPORT */
+
+typedef struct ipcp_options {
+    unsigned int neg_addr               :1; /* Negotiate IP Address? */
+    unsigned int old_addrs              :1; /* Use old (IP-Addresses) option? */
+    unsigned int req_addr               :1; /* Ask peer to send IP address? */
+#if 0 /* UNUSED */
+    unsigned int default_route          :1; /* Assign default route through interface? */
+    unsigned int replace_default_route  :1; /* Replace default route through interface? */
+#endif /* UNUSED */
+#if 0 /* UNUSED - PROXY ARP */
+    unsigned int proxy_arp              :1; /* Make proxy ARP entry for peer? */
+#endif /* UNUSED - PROXY ARP */
+#if VJ_SUPPORT
+    unsigned int neg_vj                 :1; /* Van Jacobson Compression? */
+    unsigned int old_vj                 :1; /* use old (short) form of VJ option? */
+    unsigned int cflag                  :1;
+#endif /* VJ_SUPPORT */
+    unsigned int accept_local           :1; /* accept peer's value for ouraddr */
+    unsigned int accept_remote          :1; /* accept peer's value for hisaddr */
+#if LWIP_DNS
+    unsigned int req_dns1               :1; /* Ask peer to send primary DNS address? */
+    unsigned int req_dns2               :1; /* Ask peer to send secondary DNS address? */
+#endif /* LWIP_DNS */
+
+    u32_t ouraddr, hisaddr;	/* Addresses in NETWORK BYTE ORDER */
+#if LWIP_DNS
+    u32_t dnsaddr[2];	/* Primary and secondary MS DNS entries */
+#endif /* LWIP_DNS */
+#if 0 /* UNUSED - WINS */
+    u32_t winsaddr[2];	/* Primary and secondary MS WINS entries */
+#endif /* UNUSED - WINS */
+
+#if VJ_SUPPORT
+    u16_t vj_protocol;		/* protocol value to use in VJ option */
+    u8_t  maxslotindex;		/* values for RFC1332 VJ compression neg. */
+#endif /* VJ_SUPPORT */
+} ipcp_options;
+
+#if 0 /* UNUSED, already defined by lwIP */
+char *ip_ntoa (u32_t);
+#endif /* UNUSED, already defined by lwIP */
+
+extern const struct protent ipcp_protent;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* IPCP_H */
+#endif /* PPP_SUPPORT && PPP_IPV4_SUPPORT */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/netif/ppp/ipv6cp.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/netif/ppp/ipv6cp.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/netif/ppp/ipv6cp.h	(revision 457)
@@ -0,0 +1,191 @@
+/*
+ * ipv6cp.h - PPP IPV6 Control Protocol.
+ *
+ * Copyright (c) 1999 Tommi Komulainen.  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. The name(s) of the authors of this software must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission.
+ *
+ * 4. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by Tommi Komulainen
+ *     <Tommi.Komulainen@iki.fi>".
+ *
+ * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO
+ * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
+ * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
+ * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
+ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ */
+
+/*  Original version, based on RFC2023 :
+
+    Copyright (c) 1995, 1996, 1997 Francis.Dupont@inria.fr, INRIA Rocquencourt,
+    Alain.Durand@imag.fr, IMAG,
+    Jean-Luc.Richier@imag.fr, IMAG-LSR.
+
+    Copyright (c) 1998, 1999 Francis.Dupont@inria.fr, GIE DYADE,
+    Alain.Durand@imag.fr, IMAG,
+    Jean-Luc.Richier@imag.fr, IMAG-LSR.
+
+    Ce travail a ﾃｩtﾃｩ fait au sein du GIE DYADE (Groupement d'Intﾃｩrﾃｪt
+    ﾃ営onomique ayant pour membres BULL S.A. et l'INRIA).
+
+    Ce logiciel informatique est disponible aux conditions
+    usuelles dans la recherche, c'est-ﾃ-dire qu'il peut
+    ﾃｪtre utilisﾃｩ, copiﾃｩ, modifiﾃｩ, distribuﾃｩ ﾃ l'unique
+    condition que ce texte soit conservﾃｩ afin que
+    l'origine de ce logiciel soit reconnue.
+
+    Le nom de l'Institut National de Recherche en Informatique
+    et en Automatique (INRIA), de l'IMAG, ou d'une personne morale
+    ou physique ayant participﾃｩ ﾃ l'ﾃｩlaboration de ce logiciel ne peut
+    ﾃｪtre utilisﾃｩ sans son accord prﾃｩalable explicite.
+
+    Ce logiciel est fourni tel quel sans aucune garantie,
+    support ou responsabilitﾃｩ d'aucune sorte.
+    Ce logiciel est dﾃｩrivﾃｩ de sources d'origine
+    "University of California at Berkeley" et
+    "Digital Equipment Corporation" couvertes par des copyrights.
+
+    L'Institut d'Informatique et de Mathﾃｩmatiques Appliquﾃｩes de Grenoble (IMAG)
+    est une fﾃｩdﾃｩration d'unitﾃｩs mixtes de recherche du CNRS, de l'Institut National
+    Polytechnique de Grenoble et de l'Universitﾃｩ Joseph Fourier regroupant
+    sept laboratoires dont le laboratoire Logiciels, Systﾃｨmes, Rﾃｩseaux (LSR).
+
+    This work has been done in the context of GIE DYADE (joint R & D venture
+    between BULL S.A. and INRIA).
+
+    This software is available with usual "research" terms
+    with the aim of retain credits of the software. 
+    Permission to use, copy, modify and distribute this software for any
+    purpose and without fee is hereby granted, provided that the above
+    copyright notice and this permission notice appear in all copies,
+    and the name of INRIA, IMAG, or any contributor not be used in advertising
+    or publicity pertaining to this material without the prior explicit
+    permission. The software is provided "as is" without any
+    warranties, support or liabilities of any kind.
+    This software is derived from source code from
+    "University of California at Berkeley" and
+    "Digital Equipment Corporation" protected by copyrights.
+
+    Grenoble's Institute of Computer Science and Applied Mathematics (IMAG)
+    is a federation of seven research units funded by the CNRS, National
+    Polytechnic Institute of Grenoble and University Joseph Fourier.
+    The research unit in Software, Systems, Networks (LSR) is member of IMAG.
+*/
+
+/*
+ * Derived from :
+ *
+ *
+ * ipcp.h - IP Control Protocol definitions.
+ *
+ * Copyright (c) 1984-2000 Carnegie Mellon University. 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. The name "Carnegie Mellon University" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For permission or any legal
+ *    details, please contact
+ *      Office of Technology Transfer
+ *      Carnegie Mellon University
+ *      5000 Forbes Avenue
+ *      Pittsburgh, PA  15213-3890
+ *      (412) 268-4387, fax: (412) 268-7395
+ *      tech-transfer@andrew.cmu.edu
+ *
+ * 4. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by Computing Services
+ *     at Carnegie Mellon University (http://www.cmu.edu/computing/)."
+ *
+ * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO
+ * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE
+ * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
+ * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
+ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * $Id$
+ */
+
+#include "netif/ppp/ppp_opts.h"
+#if PPP_SUPPORT && PPP_IPV6_SUPPORT  /* don't build if not configured for use in lwipopts.h */
+
+#ifndef IPV6CP_H
+#define	IPV6CP_H
+
+#include "eui64.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * Options.
+ */
+#define CI_IFACEID	1	/* Interface Identifier */
+#ifdef IPV6CP_COMP
+#define CI_COMPRESSTYPE	2	/* Compression Type     */
+#endif /* IPV6CP_COMP */
+
+/* No compression types yet defined.
+ *#define IPV6CP_COMP	0x004f
+ */
+typedef struct ipv6cp_options {
+    unsigned int neg_ifaceid    :1;  /* Negotiate interface identifier? */
+    unsigned int req_ifaceid    :1;  /* Ask peer to send interface identifier? */
+    unsigned int accept_local   :1;  /* accept peer's value for iface id? */
+    unsigned int opt_local      :1;  /* ourtoken set by option */
+    unsigned int opt_remote     :1;  /* histoken set by option */
+    unsigned int use_ip         :1;  /* use IP as interface identifier */
+#if 0
+    unsigned int use_persistent :1;  /* use uniquely persistent value for address */
+#endif
+#ifdef IPV6CP_COMP
+    unsigned int neg_vj         :1;  /* Van Jacobson Compression? */
+#endif /* IPV6CP_COMP */
+
+#ifdef IPV6CP_COMP
+    u_short vj_protocol;        /* protocol value to use in VJ option */
+#endif /* IPV6CP_COMP */
+    eui64_t ourid, hisid;       /* Interface identifiers */
+} ipv6cp_options;
+
+extern const struct protent ipv6cp_protent;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* IPV6CP_H */
+#endif /* PPP_SUPPORT && PPP_IPV6_SUPPORT */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/netif/ppp/lcp.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/netif/ppp/lcp.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/netif/ppp/lcp.h	(revision 457)
@@ -0,0 +1,179 @@
+/*
+ * lcp.h - Link Control Protocol definitions.
+ *
+ * Copyright (c) 1984-2000 Carnegie Mellon University. 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. The name "Carnegie Mellon University" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For permission or any legal
+ *    details, please contact
+ *      Office of Technology Transfer
+ *      Carnegie Mellon University
+ *      5000 Forbes Avenue
+ *      Pittsburgh, PA  15213-3890
+ *      (412) 268-4387, fax: (412) 268-7395
+ *      tech-transfer@andrew.cmu.edu
+ *
+ * 4. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by Computing Services
+ *     at Carnegie Mellon University (http://www.cmu.edu/computing/)."
+ *
+ * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO
+ * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE
+ * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
+ * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
+ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * $Id$
+ */
+
+#include "netif/ppp/ppp_opts.h"
+#if PPP_SUPPORT /* don't build if not configured for use in lwipopts.h */
+
+#ifndef LCP_H
+#define	LCP_H
+
+#include "ppp.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * Options.
+ */
+#define CI_VENDOR	0	/* Vendor Specific */
+#define CI_MRU		1	/* Maximum Receive Unit */
+#define CI_ASYNCMAP	2	/* Async Control Character Map */
+#define CI_AUTHTYPE	3	/* Authentication Type */
+#define CI_QUALITY	4	/* Quality Protocol */
+#define CI_MAGICNUMBER	5	/* Magic Number */
+#define CI_PCOMPRESSION	7	/* Protocol Field Compression */
+#define CI_ACCOMPRESSION 8	/* Address/Control Field Compression */
+#define CI_FCSALTERN	9	/* FCS-Alternatives */
+#define CI_SDP		10	/* Self-Describing-Pad */
+#define CI_NUMBERED	11	/* Numbered-Mode */
+#define CI_CALLBACK	13	/* callback */
+#define CI_MRRU		17	/* max reconstructed receive unit; multilink */
+#define CI_SSNHF	18	/* short sequence numbers for multilink */
+#define CI_EPDISC	19	/* endpoint discriminator */
+#define CI_MPPLUS	22	/* Multi-Link-Plus-Procedure */
+#define CI_LDISC	23	/* Link-Discriminator */
+#define CI_LCPAUTH	24	/* LCP Authentication */
+#define CI_COBS		25	/* Consistent Overhead Byte Stuffing */
+#define CI_PREFELIS	26	/* Prefix Elision */
+#define CI_MPHDRFMT	27	/* MP Header Format */
+#define CI_I18N		28	/* Internationalization */
+#define CI_SDL		29	/* Simple Data Link */
+
+/*
+ * LCP-specific packet types (code numbers).
+ */
+#define PROTREJ		8	/* Protocol Reject */
+#define ECHOREQ		9	/* Echo Request */
+#define ECHOREP		10	/* Echo Reply */
+#define DISCREQ		11	/* Discard Request */
+#define IDENTIF		12	/* Identification */
+#define TIMEREM		13	/* Time Remaining */
+
+/* Value used as data for CI_CALLBACK option */
+#define CBCP_OPT	6	/* Use callback control protocol */
+
+#if 0 /* moved to ppp_opts.h */
+#define DEFMRU	1500		/* Try for this */
+#define MINMRU	128		/* No MRUs below this */
+#define MAXMRU	16384		/* Normally limit MRU to this */
+#endif /* moved to ppp_opts.h */
+
+/* An endpoint discriminator, used with multilink. */
+#define MAX_ENDP_LEN	20	/* maximum length of discriminator value */
+struct epdisc {
+    unsigned char	class_; /* -- The word "class" is reserved in C++. */
+    unsigned char	length;
+    unsigned char	value[MAX_ENDP_LEN];
+};
+
+/*
+ * The state of options is described by an lcp_options structure.
+ */
+typedef struct lcp_options {
+    unsigned int passive           :1; /* Don't die if we don't get a response */
+    unsigned int silent            :1; /* Wait for the other end to start first */
+#if 0 /* UNUSED */
+    unsigned int restart           :1; /* Restart vs. exit after close */
+#endif /* UNUSED */
+    unsigned int neg_mru           :1; /* Negotiate the MRU? */
+    unsigned int neg_asyncmap      :1; /* Negotiate the async map? */
+#if PAP_SUPPORT
+    unsigned int neg_upap          :1; /* Ask for UPAP authentication? */
+#endif /* PAP_SUPPORT */
+#if CHAP_SUPPORT
+    unsigned int neg_chap          :1; /* Ask for CHAP authentication? */
+#endif /* CHAP_SUPPORT */
+#if EAP_SUPPORT
+    unsigned int neg_eap           :1; /* Ask for EAP authentication? */
+#endif /* EAP_SUPPORT */
+    unsigned int neg_magicnumber   :1; /* Ask for magic number? */
+    unsigned int neg_pcompression  :1; /* HDLC Protocol Field Compression? */
+    unsigned int neg_accompression :1; /* HDLC Address/Control Field Compression? */
+#if LQR_SUPPORT
+    unsigned int neg_lqr           :1; /* Negotiate use of Link Quality Reports */
+#endif /* LQR_SUPPORT */
+    unsigned int neg_cbcp          :1; /* Negotiate use of CBCP */
+#ifdef HAVE_MULTILINK
+    unsigned int neg_mrru          :1; /* negotiate multilink MRRU */
+#endif /* HAVE_MULTILINK */
+    unsigned int neg_ssnhf         :1; /* negotiate short sequence numbers */
+    unsigned int neg_endpoint      :1; /* negotiate endpoint discriminator */
+
+    u16_t mru;			/* Value of MRU */
+#ifdef HAVE_MULTILINK
+    u16_t mrru;			/* Value of MRRU, and multilink enable */
+#endif /* MULTILINK */
+#if CHAP_SUPPORT
+    u8_t chap_mdtype;		/* which MD types (hashing algorithm) */
+#endif /* CHAP_SUPPORT */
+    u32_t asyncmap;		/* Value of async map */
+    u32_t magicnumber;
+    u8_t  numloops;		/* Number of loops during magic number neg. */
+#if LQR_SUPPORT
+    u32_t lqr_period;	/* Reporting period for LQR 1/100ths second */
+#endif /* LQR_SUPPORT */
+    struct epdisc endpoint;	/* endpoint discriminator */
+} lcp_options;
+
+void lcp_open(ppp_pcb *pcb);
+void lcp_close(ppp_pcb *pcb, const char *reason);
+void lcp_lowerup(ppp_pcb *pcb);
+void lcp_lowerdown(ppp_pcb *pcb);
+void lcp_sprotrej(ppp_pcb *pcb, u_char *p, int len);    /* send protocol reject */
+
+extern const struct protent lcp_protent;
+
+#if 0 /* moved to ppp_opts.h */
+/* Default number of times we receive our magic number from the peer
+   before deciding the link is looped-back. */
+#define DEFLOOPBACKFAIL	10
+#endif /* moved to ppp_opts.h */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LCP_H */
+#endif /* PPP_SUPPORT */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/netif/ppp/magic.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/netif/ppp/magic.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/netif/ppp/magic.h	(revision 457)
@@ -0,0 +1,130 @@
+/*
+ * magic.h - PPP Magic Number definitions.
+ *
+ * Copyright (c) 1984-2000 Carnegie Mellon University. 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. The name "Carnegie Mellon University" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For permission or any legal
+ *    details, please contact
+ *      Office of Technology Transfer
+ *      Carnegie Mellon University
+ *      5000 Forbes Avenue
+ *      Pittsburgh, PA  15213-3890
+ *      (412) 268-4387, fax: (412) 268-7395
+ *      tech-transfer@andrew.cmu.edu
+ *
+ * 4. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by Computing Services
+ *     at Carnegie Mellon University (http://www.cmu.edu/computing/)."
+ *
+ * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO
+ * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE
+ * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
+ * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
+ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * $Id$
+ */
+/*****************************************************************************
+* randm.h - Random number generator header file.
+*
+* Copyright (c) 2003 by Marc Boucher, Services Informatiques (MBSI) inc.
+* Copyright (c) 1998 Global Election Systems Inc.
+*
+* The authors hereby grant permission to use, copy, modify, distribute,
+* and license this software and its documentation for any purpose, provided
+* that existing copyright notices are retained in all copies and that this
+* notice and the following disclaimer are included verbatim in any
+* distributions. No written agreement, license, or royalty fee is required
+* for any of the authorized uses.
+*
+* THIS SOFTWARE IS PROVIDED BY THE 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 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.
+*
+******************************************************************************
+* REVISION HISTORY
+*
+* 03-01-01 Marc Boucher <marc@mbsi.ca>
+*   Ported to lwIP.
+* 98-05-29 Guy Lancaster <glanca@gesn.com>, Global Election Systems Inc.
+*   Extracted from avos.
+*****************************************************************************/
+
+#include "netif/ppp/ppp_opts.h"
+#if PPP_SUPPORT /* don't build if not configured for use in lwipopts.h */
+
+#ifndef MAGIC_H
+#define MAGIC_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/***********************
+*** PUBLIC FUNCTIONS ***
+***********************/
+
+/*
+ * Initialize the random number generator.
+ */
+void magic_init(void);
+
+/*
+ * Randomize our random seed value.  To be called for truely random events
+ * such as user operations and network traffic.
+ */
+void magic_randomize(void);
+
+/*
+ * Return a new random number.
+ */
+u32_t magic(void);	/* Returns the next magic number */
+
+/*
+ * Fill buffer with random bytes
+ *
+ * Use the random pool to generate random data.  This degrades to pseudo
+ * random when used faster than randomness is supplied using magic_churnrand().
+ * Thus it's important to make sure that the results of this are not
+ * published directly because one could predict the next result to at
+ * least some degree.  Also, it's important to get a good seed before
+ * the first use.
+ */
+void magic_random_bytes(unsigned char *buf, u32_t buf_len);
+
+/*
+ * Return a new random number between 0 and (2^pow)-1 included.
+ */
+u32_t magic_pow(u8_t pow);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* MAGIC_H */
+
+#endif /* PPP_SUPPORT */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/netif/ppp/mppe.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/netif/ppp/mppe.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/netif/ppp/mppe.h	(revision 457)
@@ -0,0 +1,181 @@
+/*
+ * mppe.h - Definitions for MPPE
+ *
+ * Copyright (c) 2008 Paul Mackerras. 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. The name(s) of the authors of this software must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission.
+ *
+ * 4. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by Paul Mackerras
+ *     <paulus@samba.org>".
+ *
+ * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO
+ * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
+ * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
+ * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
+ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include "netif/ppp/ppp_opts.h"
+#if PPP_SUPPORT && MPPE_SUPPORT  /* don't build if not configured for use in lwipopts.h */
+
+#ifndef MPPE_H
+#define MPPE_H
+
+#include "netif/ppp/pppcrypt.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define MPPE_PAD		4	/* MPPE growth per frame */
+#define MPPE_MAX_KEY_LEN	16	/* largest key length (128-bit) */
+
+/* option bits for ccp_options.mppe */
+#define MPPE_OPT_40		0x01	/* 40 bit */
+#define MPPE_OPT_128		0x02	/* 128 bit */
+#define MPPE_OPT_STATEFUL	0x04	/* stateful mode */
+/* unsupported opts */
+#define MPPE_OPT_56		0x08	/* 56 bit */
+#define MPPE_OPT_MPPC		0x10	/* MPPC compression */
+#define MPPE_OPT_D		0x20	/* Unknown */
+#define MPPE_OPT_UNSUPPORTED (MPPE_OPT_56|MPPE_OPT_MPPC|MPPE_OPT_D)
+#define MPPE_OPT_UNKNOWN	0x40	/* Bits !defined in RFC 3078 were set */
+
+/*
+ * This is not nice ... the alternative is a bitfield struct though.
+ * And unfortunately, we cannot share the same bits for the option
+ * names above since C and H are the same bit.  We could do a u_int32
+ * but then we have to do a lwip_htonl() all the time and/or we still need
+ * to know which octet is which.
+ */
+#define MPPE_C_BIT		0x01	/* MPPC */
+#define MPPE_D_BIT		0x10	/* Obsolete, usage unknown */
+#define MPPE_L_BIT		0x20	/* 40-bit */
+#define MPPE_S_BIT		0x40	/* 128-bit */
+#define MPPE_M_BIT		0x80	/* 56-bit, not supported */
+#define MPPE_H_BIT		0x01	/* Stateless (in a different byte) */
+
+/* Does not include H bit; used for least significant octet only. */
+#define MPPE_ALL_BITS (MPPE_D_BIT|MPPE_L_BIT|MPPE_S_BIT|MPPE_M_BIT|MPPE_H_BIT)
+
+/* Build a CI from mppe opts (see RFC 3078) */
+#define MPPE_OPTS_TO_CI(opts, ci)		\
+    do {					\
+	u_char *ptr = ci; /* u_char[4] */	\
+						\
+	/* H bit */				\
+	if (opts & MPPE_OPT_STATEFUL)		\
+	    *ptr++ = 0x0;			\
+	else					\
+	    *ptr++ = MPPE_H_BIT;		\
+	*ptr++ = 0;				\
+	*ptr++ = 0;				\
+						\
+	/* S,L bits */				\
+	*ptr = 0;				\
+	if (opts & MPPE_OPT_128)		\
+	    *ptr |= MPPE_S_BIT;			\
+	if (opts & MPPE_OPT_40)			\
+	    *ptr |= MPPE_L_BIT;			\
+	/* M,D,C bits not supported */		\
+    } while (/* CONSTCOND */ 0)
+
+/* The reverse of the above */
+#define MPPE_CI_TO_OPTS(ci, opts)		\
+    do {					\
+	const u_char *ptr = ci; /* u_char[4] */	\
+						\
+	opts = 0;				\
+						\
+	/* H bit */				\
+	if (!(ptr[0] & MPPE_H_BIT))		\
+	    opts |= MPPE_OPT_STATEFUL;		\
+						\
+	/* S,L bits */				\
+	if (ptr[3] & MPPE_S_BIT)		\
+	    opts |= MPPE_OPT_128;		\
+	if (ptr[3] & MPPE_L_BIT)		\
+	    opts |= MPPE_OPT_40;		\
+						\
+	/* M,D,C bits */			\
+	if (ptr[3] & MPPE_M_BIT)		\
+	    opts |= MPPE_OPT_56;		\
+	if (ptr[3] & MPPE_D_BIT)		\
+	    opts |= MPPE_OPT_D;			\
+	if (ptr[3] & MPPE_C_BIT)		\
+	    opts |= MPPE_OPT_MPPC;		\
+						\
+	/* Other bits */			\
+	if (ptr[0] & ~MPPE_H_BIT)		\
+	    opts |= MPPE_OPT_UNKNOWN;		\
+	if (ptr[1] || ptr[2])			\
+	    opts |= MPPE_OPT_UNKNOWN;		\
+	if (ptr[3] & ~MPPE_ALL_BITS)		\
+	    opts |= MPPE_OPT_UNKNOWN;		\
+    } while (/* CONSTCOND */ 0)
+
+/* Shared MPPE padding between MSCHAP and MPPE */
+#define SHA1_PAD_SIZE 40
+
+static const u8_t mppe_sha1_pad1[SHA1_PAD_SIZE] = {
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+};
+static const u8_t mppe_sha1_pad2[SHA1_PAD_SIZE] = {
+  0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2,
+  0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2,
+  0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2,
+  0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2
+};
+
+/*
+ * State for an MPPE (de)compressor.
+ */
+typedef struct ppp_mppe_state {
+	lwip_arc4_context arc4;
+	u8_t master_key[MPPE_MAX_KEY_LEN];
+	u8_t session_key[MPPE_MAX_KEY_LEN];
+	u8_t keylen;                /* key length in bytes */
+	/* NB: 128-bit == 16, 40-bit == 8!
+	 * If we want to support 56-bit, the unit has to change to bits
+	 */
+	u8_t bits;                  /* MPPE control bits */
+	u16_t ccount;               /* 12-bit coherency count (seqno)  */
+	u16_t sanity_errors;        /* take down LCP if too many */
+	unsigned int stateful  :1;  /* stateful mode flag */
+	unsigned int discard   :1;  /* stateful mode packet loss flag */
+} ppp_mppe_state;
+
+void mppe_set_key(ppp_pcb *pcb, ppp_mppe_state *state, u8_t *key);
+void mppe_init(ppp_pcb *pcb, ppp_mppe_state *state, u8_t options);
+void mppe_comp_reset(ppp_pcb *pcb, ppp_mppe_state *state);
+err_t mppe_compress(ppp_pcb *pcb, ppp_mppe_state *state, struct pbuf **pb, u16_t protocol);
+void mppe_decomp_reset(ppp_pcb *pcb, ppp_mppe_state *state);
+err_t mppe_decompress(ppp_pcb *pcb, ppp_mppe_state *state, struct pbuf **pb);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* MPPE_H */
+#endif /* PPP_SUPPORT && MPPE_SUPPORT */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/netif/ppp/polarssl/arc4.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/netif/ppp/polarssl/arc4.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/netif/ppp/polarssl/arc4.h	(revision 457)
@@ -0,0 +1,81 @@
+/**
+ * \file arc4.h
+ *
+ *  Based on XySSL: Copyright (C) 2006-2008  Christophe Devine
+ *
+ *  Copyright (C) 2009  Paul Bakker <polarssl_maintainer at polarssl dot org>
+ *
+ *  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.
+ *    * 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.
+ *    * Neither the names of PolarSSL or XySSL 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
+ *  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.
+ */
+
+#include "netif/ppp/ppp_opts.h"
+#if LWIP_INCLUDED_POLARSSL_ARC4
+
+#ifndef LWIP_INCLUDED_POLARSSL_ARC4_H
+#define LWIP_INCLUDED_POLARSSL_ARC4_H
+
+/**
+ * \brief          ARC4 context structure
+ */
+typedef struct
+{
+    int x;                      /*!< permutation index */
+    int y;                      /*!< permutation index */
+    unsigned char m[256];       /*!< permutation table */
+}
+arc4_context;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * \brief          ARC4 key schedule
+ *
+ * \param ctx      ARC4 context to be initialized
+ * \param key      the secret key
+ * \param keylen   length of the key
+ */
+void arc4_setup( arc4_context *ctx, unsigned char *key, int keylen );
+
+/**
+ * \brief          ARC4 cipher function
+ *
+ * \param ctx      ARC4 context
+ * \param buf      buffer to be processed
+ * \param buflen   amount of data in buf
+ */
+void arc4_crypt( arc4_context *ctx, unsigned char *buf, int buflen );
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LWIP_INCLUDED_POLARSSL_ARC4_H */
+
+#endif /* LWIP_INCLUDED_POLARSSL_ARC4 */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/netif/ppp/polarssl/des.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/netif/ppp/polarssl/des.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/netif/ppp/polarssl/des.h	(revision 457)
@@ -0,0 +1,92 @@
+/**
+ * \file des.h
+ *
+ *  Based on XySSL: Copyright (C) 2006-2008  Christophe Devine
+ *
+ *  Copyright (C) 2009  Paul Bakker <polarssl_maintainer at polarssl dot org>
+ *
+ *  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.
+ *    * 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.
+ *    * Neither the names of PolarSSL or XySSL 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
+ *  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.
+ */
+
+#include "netif/ppp/ppp_opts.h"
+#if LWIP_INCLUDED_POLARSSL_DES
+
+#ifndef LWIP_INCLUDED_POLARSSL_DES_H
+#define LWIP_INCLUDED_POLARSSL_DES_H
+
+#define DES_ENCRYPT     1
+#define DES_DECRYPT     0
+
+/**
+ * \brief          DES context structure
+ */
+typedef struct
+{
+    int mode;                   /*!<  encrypt/decrypt   */
+    unsigned long sk[32];       /*!<  DES subkeys       */
+}
+des_context;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * \brief          DES key schedule (56-bit, encryption)
+ *
+ * \param ctx      DES context to be initialized
+ * \param key      8-byte secret key
+ */
+void des_setkey_enc( des_context *ctx, unsigned char key[8] );
+
+/**
+ * \brief          DES key schedule (56-bit, decryption)
+ *
+ * \param ctx      DES context to be initialized
+ * \param key      8-byte secret key
+ */
+void des_setkey_dec( des_context *ctx, unsigned char key[8] );
+
+/**
+ * \brief          DES-ECB block encryption/decryption
+ *
+ * \param ctx      DES context
+ * \param input    64-bit input block
+ * \param output   64-bit output block
+ */
+void des_crypt_ecb( des_context *ctx,
+                    const unsigned char input[8],
+                    unsigned char output[8] );
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LWIP_INCLUDED_POLARSSL_DES_H */
+
+#endif /* LWIP_INCLUDED_POLARSSL_DES */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/netif/ppp/polarssl/md4.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/netif/ppp/polarssl/md4.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/netif/ppp/polarssl/md4.h	(revision 457)
@@ -0,0 +1,97 @@
+/**
+ * \file md4.h
+ *
+ *  Based on XySSL: Copyright (C) 2006-2008  Christophe Devine
+ *
+ *  Copyright (C) 2009  Paul Bakker <polarssl_maintainer at polarssl dot org>
+ *
+ *  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.
+ *    * 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.
+ *    * Neither the names of PolarSSL or XySSL 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
+ *  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.
+ */
+
+#include "netif/ppp/ppp_opts.h"
+#if LWIP_INCLUDED_POLARSSL_MD4
+
+#ifndef LWIP_INCLUDED_POLARSSL_MD4_H
+#define LWIP_INCLUDED_POLARSSL_MD4_H
+
+/**
+ * \brief          MD4 context structure
+ */
+typedef struct
+{
+    unsigned long total[2];     /*!< number of bytes processed  */
+    unsigned long state[4];     /*!< intermediate digest state  */
+    unsigned char buffer[64];   /*!< data block being processed */
+}
+md4_context;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * \brief          MD4 context setup
+ *
+ * \param ctx      context to be initialized
+ */
+void md4_starts( md4_context *ctx );
+
+/**
+ * \brief          MD4 process buffer
+ *
+ * \param ctx      MD4 context
+ * \param input    buffer holding the  data
+ * \param ilen     length of the input data
+ */
+void md4_update( md4_context *ctx, const unsigned char *input, int ilen );
+
+/**
+ * \brief          MD4 final digest
+ *
+ * \param ctx      MD4 context
+ * \param output   MD4 checksum result
+ */
+void md4_finish( md4_context *ctx, unsigned char output[16] );
+
+/**
+ * \brief          Output = MD4( input buffer )
+ *
+ * \param input    buffer holding the  data
+ * \param ilen     length of the input data
+ * \param output   MD4 checksum result
+ */
+void md4( unsigned char *input, int ilen, unsigned char output[16] );
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LWIP_INCLUDED_POLARSSL_MD4_H */
+
+#endif /* LWIP_INCLUDED_POLARSSL_MD4 */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/netif/ppp/polarssl/md5.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/netif/ppp/polarssl/md5.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/netif/ppp/polarssl/md5.h	(revision 457)
@@ -0,0 +1,96 @@
+/**
+ * \file md5.h
+ *
+ *  Based on XySSL: Copyright (C) 2006-2008  Christophe Devine
+ *
+ *  Copyright (C) 2009  Paul Bakker <polarssl_maintainer at polarssl dot org>
+ *
+ *  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.
+ *    * 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.
+ *    * Neither the names of PolarSSL or XySSL 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
+ *  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.
+ */
+
+#include "netif/ppp/ppp_opts.h"
+#if LWIP_INCLUDED_POLARSSL_MD5
+
+#ifndef LWIP_INCLUDED_POLARSSL_MD5_H
+#define LWIP_INCLUDED_POLARSSL_MD5_H
+
+/**
+ * \brief          MD5 context structure
+ */
+typedef struct
+{
+    unsigned long total[2];     /*!< number of bytes processed  */
+    unsigned long state[4];     /*!< intermediate digest state  */
+    unsigned char buffer[64];   /*!< data block being processed */
+}
+md5_context;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * \brief          MD5 context setup
+ *
+ * \param ctx      context to be initialized
+ */
+void md5_starts( md5_context *ctx );
+
+/**
+ * \brief          MD5 process buffer
+ *
+ * \param ctx      MD5 context
+ * \param input    buffer holding the  data
+ * \param ilen     length of the input data
+ */
+void md5_update( md5_context *ctx, const unsigned char *input, int ilen );
+
+/**
+ * \brief          MD5 final digest
+ *
+ * \param ctx      MD5 context
+ * \param output   MD5 checksum result
+ */
+void md5_finish( md5_context *ctx, unsigned char output[16] );
+
+/**
+ * \brief          Output = MD5( input buffer )
+ *
+ * \param input    buffer holding the  data
+ * \param ilen     length of the input data
+ * \param output   MD5 checksum result
+ */
+void md5( unsigned char *input, int ilen, unsigned char output[16] );
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LWIP_INCLUDED_POLARSSL_MD5_H */
+
+#endif /* LWIP_INCLUDED_POLARSSL_MD5 */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/netif/ppp/polarssl/sha1.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/netif/ppp/polarssl/sha1.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/netif/ppp/polarssl/sha1.h	(revision 457)
@@ -0,0 +1,96 @@
+/**
+ * \file sha1.h
+ *
+ *  Based on XySSL: Copyright (C) 2006-2008  Christophe Devine
+ *
+ *  Copyright (C) 2009  Paul Bakker <polarssl_maintainer at polarssl dot org>
+ *
+ *  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.
+ *    * 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.
+ *    * Neither the names of PolarSSL or XySSL 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
+ *  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.
+ */
+
+#include "netif/ppp/ppp_opts.h"
+#if LWIP_INCLUDED_POLARSSL_SHA1
+
+#ifndef LWIP_INCLUDED_POLARSSL_SHA1_H
+#define LWIP_INCLUDED_POLARSSL_SHA1_H
+
+/**
+ * \brief          SHA-1 context structure
+ */
+typedef struct
+{
+    unsigned long total[2];     /*!< number of bytes processed  */
+    unsigned long state[5];     /*!< intermediate digest state  */
+    unsigned char buffer[64];   /*!< data block being processed */
+}
+sha1_context;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * \brief          SHA-1 context setup
+ *
+ * \param ctx      context to be initialized
+ */
+void sha1_starts( sha1_context *ctx );
+
+/**
+ * \brief          SHA-1 process buffer
+ *
+ * \param ctx      SHA-1 context
+ * \param input    buffer holding the  data
+ * \param ilen     length of the input data
+ */
+void sha1_update( sha1_context *ctx, const unsigned char *input, int ilen );
+
+/**
+ * \brief          SHA-1 final digest
+ *
+ * \param ctx      SHA-1 context
+ * \param output   SHA-1 checksum result
+ */
+void sha1_finish( sha1_context *ctx, unsigned char output[20] );
+
+/**
+ * \brief          Output = SHA-1( input buffer )
+ *
+ * \param input    buffer holding the  data
+ * \param ilen     length of the input data
+ * \param output   SHA-1 checksum result
+ */
+void sha1( unsigned char *input, int ilen, unsigned char output[20] );
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LWIP_INCLUDED_POLARSSL_SHA1_H */
+
+#endif /* LWIP_INCLUDED_POLARSSL_SHA1 */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/netif/ppp/ppp.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/netif/ppp/ppp.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/netif/ppp/ppp.h	(revision 457)
@@ -0,0 +1,698 @@
+/*****************************************************************************
+* ppp.h - Network Point to Point Protocol header file.
+*
+* Copyright (c) 2003 by Marc Boucher, Services Informatiques (MBSI) inc.
+* portions Copyright (c) 1997 Global Election Systems Inc.
+*
+* The authors hereby grant permission to use, copy, modify, distribute,
+* and license this software and its documentation for any purpose, provided
+* that existing copyright notices are retained in all copies and that this
+* notice and the following disclaimer are included verbatim in any 
+* distributions. No written agreement, license, or royalty fee is required
+* for any of the authorized uses.
+*
+* THIS SOFTWARE IS PROVIDED BY THE 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 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.
+*
+******************************************************************************
+* REVISION HISTORY
+*
+* 03-01-01 Marc Boucher <marc@mbsi.ca>
+*   Ported to lwIP.
+* 97-11-05 Guy Lancaster <glanca@gesn.com>, Global Election Systems Inc.
+*   Original derived from BSD codes.
+*****************************************************************************/
+
+#include "netif/ppp/ppp_opts.h"
+#if PPP_SUPPORT /* don't build if not configured for use in lwipopts.h */
+
+#ifndef PPP_H
+#define PPP_H
+
+#include "lwip/def.h"
+#include "lwip/stats.h"
+#include "lwip/mem.h"
+#include "lwip/netif.h"
+#include "lwip/sys.h"
+#include "lwip/timeouts.h"
+#if PPP_IPV6_SUPPORT
+#include "lwip/ip6_addr.h"
+#endif /* PPP_IPV6_SUPPORT */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Disable non-working or rarely used PPP feature, so rarely that we don't want to bloat ppp_opts.h with them */
+#ifndef PPP_OPTIONS
+#define PPP_OPTIONS         0
+#endif
+
+#ifndef PPP_NOTIFY
+#define PPP_NOTIFY          0
+#endif
+
+#ifndef PPP_REMOTENAME
+#define PPP_REMOTENAME      0
+#endif
+
+#ifndef PPP_IDLETIMELIMIT
+#define PPP_IDLETIMELIMIT   0
+#endif
+
+#ifndef PPP_LCP_ADAPTIVE
+#define PPP_LCP_ADAPTIVE    0
+#endif
+
+#ifndef PPP_MAXCONNECT
+#define PPP_MAXCONNECT      0
+#endif
+
+#ifndef PPP_ALLOWED_ADDRS
+#define PPP_ALLOWED_ADDRS   0
+#endif
+
+#ifndef PPP_PROTOCOLNAME
+#define PPP_PROTOCOLNAME    0
+#endif
+
+#ifndef PPP_STATS_SUPPORT
+#define PPP_STATS_SUPPORT   0
+#endif
+
+#ifndef DEFLATE_SUPPORT
+#define DEFLATE_SUPPORT     0
+#endif
+
+#ifndef BSDCOMPRESS_SUPPORT
+#define BSDCOMPRESS_SUPPORT 0
+#endif
+
+#ifndef PREDICTOR_SUPPORT
+#define PREDICTOR_SUPPORT   0
+#endif
+
+/*************************
+*** PUBLIC DEFINITIONS ***
+*************************/
+
+/*
+ * The basic PPP frame.
+ */
+#define PPP_HDRLEN	4	/* octets for standard ppp header */
+#define PPP_FCSLEN	2	/* octets for FCS */
+
+/*
+ * Values for phase.
+ */
+#define PPP_PHASE_DEAD          0
+#define PPP_PHASE_MASTER        1
+#define PPP_PHASE_HOLDOFF       2
+#define PPP_PHASE_INITIALIZE    3
+#define PPP_PHASE_SERIALCONN    4
+#define PPP_PHASE_DORMANT       5
+#define PPP_PHASE_ESTABLISH     6
+#define PPP_PHASE_AUTHENTICATE  7
+#define PPP_PHASE_CALLBACK      8
+#define PPP_PHASE_NETWORK       9
+#define PPP_PHASE_RUNNING       10
+#define PPP_PHASE_TERMINATE     11
+#define PPP_PHASE_DISCONNECT    12
+
+/* Error codes. */
+#define PPPERR_NONE         0  /* No error. */
+#define PPPERR_PARAM        1  /* Invalid parameter. */
+#define PPPERR_OPEN         2  /* Unable to open PPP session. */
+#define PPPERR_DEVICE       3  /* Invalid I/O device for PPP. */
+#define PPPERR_ALLOC        4  /* Unable to allocate resources. */
+#define PPPERR_USER         5  /* User interrupt. */
+#define PPPERR_CONNECT      6  /* Connection lost. */
+#define PPPERR_AUTHFAIL     7  /* Failed authentication challenge. */
+#define PPPERR_PROTOCOL     8  /* Failed to meet protocol. */
+#define PPPERR_PEERDEAD     9  /* Connection timeout */
+#define PPPERR_IDLETIMEOUT  10 /* Idle Timeout */
+#define PPPERR_CONNECTTIME  11 /* Max connect time reached */
+#define PPPERR_LOOPBACK     12 /* Loopback detected */
+
+/* Whether auth support is enabled at all */
+#define PPP_AUTH_SUPPORT (PAP_SUPPORT || CHAP_SUPPORT || EAP_SUPPORT)
+
+/************************
+*** PUBLIC DATA TYPES ***
+************************/
+
+/*
+ * Other headers require ppp_pcb definition for prototypes, but ppp_pcb
+ * require some structure definition from other headers as well, we are
+ * fixing the dependency loop here by declaring the ppp_pcb type then
+ * by including headers containing necessary struct definition for ppp_pcb
+ */
+typedef struct ppp_pcb_s ppp_pcb;
+
+/* Type definitions for BSD code. */
+#ifndef __u_char_defined
+typedef unsigned long  u_long;
+typedef unsigned int   u_int;
+typedef unsigned short u_short;
+typedef unsigned char  u_char;
+#endif
+
+#include "fsm.h"
+#include "lcp.h"
+#if CCP_SUPPORT
+#include "ccp.h"
+#endif /* CCP_SUPPORT */
+#if MPPE_SUPPORT
+#include "mppe.h"
+#endif /* MPPE_SUPPORT */
+#if PPP_IPV4_SUPPORT
+#include "ipcp.h"
+#endif /* PPP_IPV4_SUPPORT */
+#if PPP_IPV6_SUPPORT
+#include "ipv6cp.h"
+#endif /* PPP_IPV6_SUPPORT */
+#if PAP_SUPPORT
+#include "upap.h"
+#endif /* PAP_SUPPORT */
+#if CHAP_SUPPORT
+#include "chap-new.h"
+#endif /* CHAP_SUPPORT */
+#if EAP_SUPPORT
+#include "eap.h"
+#endif /* EAP_SUPPORT */
+#if VJ_SUPPORT
+#include "vj.h"
+#endif /* VJ_SUPPORT */
+
+/* Link status callback function prototype */
+typedef void (*ppp_link_status_cb_fn)(ppp_pcb *pcb, int err_code, void *ctx);
+
+/*
+ * PPP configuration.
+ */
+typedef struct ppp_settings_s {
+
+#if PPP_SERVER && PPP_AUTH_SUPPORT
+  unsigned int  auth_required       :1;      /* Peer is required to authenticate */
+  unsigned int  null_login          :1;      /* Username of "" and a password of "" are acceptable */
+#endif /* PPP_SERVER && PPP_AUTH_SUPPORT */
+#if PPP_REMOTENAME
+  unsigned int  explicit_remote     :1;      /* remote_name specified with remotename opt */
+#endif /* PPP_REMOTENAME */
+#if PAP_SUPPORT
+  unsigned int  refuse_pap          :1;      /* Don't proceed auth. with PAP */
+#endif /* PAP_SUPPORT */
+#if CHAP_SUPPORT
+  unsigned int  refuse_chap         :1;      /* Don't proceed auth. with CHAP */
+#endif /* CHAP_SUPPORT */
+#if MSCHAP_SUPPORT
+  unsigned int  refuse_mschap       :1;      /* Don't proceed auth. with MS-CHAP */
+  unsigned int  refuse_mschap_v2    :1;      /* Don't proceed auth. with MS-CHAPv2 */
+#endif /* MSCHAP_SUPPORT */
+#if EAP_SUPPORT
+  unsigned int  refuse_eap          :1;      /* Don't proceed auth. with EAP */
+#endif /* EAP_SUPPORT */
+#if LWIP_DNS
+  unsigned int  usepeerdns          :1;      /* Ask peer for DNS adds */
+#endif /* LWIP_DNS */
+  unsigned int  persist             :1;      /* Persist mode, always try to open the connection */
+#if PRINTPKT_SUPPORT
+  unsigned int  hide_password       :1;      /* Hide password in dumped packets */
+#endif /* PRINTPKT_SUPPORT */
+  unsigned int  noremoteip          :1;      /* Let him have no IP address */
+  unsigned int  lax_recv            :1;      /* accept control chars in asyncmap */
+  unsigned int  noendpoint          :1;      /* don't send/accept endpoint discriminator */
+#if PPP_LCP_ADAPTIVE
+  unsigned int lcp_echo_adaptive    :1;      /* request echo only if the link was idle */
+#endif /* PPP_LCP_ADAPTIVE */
+#if MPPE_SUPPORT
+  unsigned int require_mppe         :1;      /* Require MPPE (Microsoft Point to Point Encryption) */
+  unsigned int refuse_mppe_40       :1;      /* Allow MPPE 40-bit mode? */
+  unsigned int refuse_mppe_128      :1;      /* Allow MPPE 128-bit mode? */
+  unsigned int refuse_mppe_stateful :1;      /* Allow MPPE stateful mode? */
+#endif /* MPPE_SUPPORT */
+
+  u16_t  listen_time;                 /* time to listen first (ms), waiting for peer to send LCP packet */
+
+#if PPP_IDLETIMELIMIT
+  u16_t  idle_time_limit;             /* Disconnect if idle for this many seconds */
+#endif /* PPP_IDLETIMELIMIT */
+#if PPP_MAXCONNECT
+  u32_t  maxconnect;                  /* Maximum connect time (seconds) */
+#endif /* PPP_MAXCONNECT */
+
+#if PPP_AUTH_SUPPORT
+  /* auth data */
+  const char  *user;                   /* Username for PAP */
+  const char  *passwd;                 /* Password for PAP, secret for CHAP */
+#if PPP_REMOTENAME
+  char  remote_name[MAXNAMELEN   + 1]; /* Peer's name for authentication */
+#endif /* PPP_REMOTENAME */
+
+#if PAP_SUPPORT
+  u8_t  pap_timeout_time;        /* Timeout (seconds) for auth-req retrans. */
+  u8_t  pap_max_transmits;       /* Number of auth-reqs sent */
+#if PPP_SERVER
+  u8_t  pap_req_timeout;         /* Time to wait for auth-req from peer */
+#endif /* PPP_SERVER */
+#endif /* PAP_SUPPPORT */
+
+#if CHAP_SUPPORT
+  u8_t  chap_timeout_time;       /* Timeout (seconds) for retransmitting req */
+  u8_t  chap_max_transmits;      /* max # times to send challenge */
+#if PPP_SERVER
+  u8_t  chap_rechallenge_time;   /* Time to wait for auth-req from peer */
+#endif /* PPP_SERVER */
+#endif /* CHAP_SUPPPORT */
+
+#if EAP_SUPPORT
+  u8_t  eap_req_time;            /* Time to wait (for retransmit/fail) */
+  u8_t  eap_allow_req;           /* Max Requests allowed */
+#if PPP_SERVER
+  u8_t  eap_timeout_time;        /* Time to wait (for retransmit/fail) */
+  u8_t  eap_max_transmits;       /* Max Requests allowed */
+#endif /* PPP_SERVER */
+#endif /* EAP_SUPPORT */
+
+#endif /* PPP_AUTH_SUPPORT */
+
+  u8_t  fsm_timeout_time;            /* Timeout time in seconds */
+  u8_t  fsm_max_conf_req_transmits;  /* Maximum Configure-Request transmissions */
+  u8_t  fsm_max_term_transmits;      /* Maximum Terminate-Request transmissions */
+  u8_t  fsm_max_nak_loops;           /* Maximum number of nak loops tolerated */
+
+  u8_t  lcp_loopbackfail;     /* Number of times we receive our magic number from the peer
+                                 before deciding the link is looped-back. */
+  u8_t  lcp_echo_interval;    /* Interval between LCP echo-requests */
+  u8_t  lcp_echo_fails;       /* Tolerance to unanswered echo-requests */
+
+} ppp_settings;
+
+#if PPP_SERVER
+struct ppp_addrs {
+#if PPP_IPV4_SUPPORT
+  ip4_addr_t our_ipaddr, his_ipaddr, netmask;
+#if LWIP_DNS
+  ip4_addr_t dns1, dns2;
+#endif /* LWIP_DNS */
+#endif /* PPP_IPV4_SUPPORT */
+#if PPP_IPV6_SUPPORT
+  ip6_addr_t our6_ipaddr, his6_ipaddr;
+#endif /* PPP_IPV6_SUPPORT */
+};
+#endif /* PPP_SERVER */
+
+/*
+ * PPP interface control block.
+ */
+struct ppp_pcb_s {
+  ppp_settings settings;
+  const struct link_callbacks *link_cb;
+  void *link_ctx_cb;
+  void (*link_status_cb)(ppp_pcb *pcb, int err_code, void *ctx);  /* Status change callback */
+#if PPP_NOTIFY_PHASE
+  void (*notify_phase_cb)(ppp_pcb *pcb, u8_t phase, void *ctx);   /* Notify phase callback */
+#endif /* PPP_NOTIFY_PHASE */
+  void *ctx_cb;                  /* Callbacks optional pointer */
+  struct netif *netif;           /* PPP interface */
+  u8_t phase;                    /* where the link is at */
+  u8_t err_code;                 /* Code indicating why interface is down. */
+
+  /* flags */
+#if PPP_IPV4_SUPPORT
+  unsigned int ask_for_local           :1; /* request our address from peer */
+  unsigned int ipcp_is_open            :1; /* haven't called np_finished() */
+  unsigned int ipcp_is_up              :1; /* have called ipcp_up() */
+  unsigned int if4_up                  :1; /* True when the IPv4 interface is up. */
+#if 0 /* UNUSED - PROXY ARP */
+  unsigned int proxy_arp_set           :1; /* Have created proxy arp entry */
+#endif /* UNUSED - PROXY ARP */
+#endif /* PPP_IPV4_SUPPORT */
+#if PPP_IPV6_SUPPORT
+  unsigned int ipv6cp_is_up            :1; /* have called ip6cp_up() */
+  unsigned int if6_up                  :1; /* True when the IPv6 interface is up. */
+#endif /* PPP_IPV6_SUPPORT */
+  unsigned int lcp_echo_timer_running  :1; /* set if a timer is running */
+#if VJ_SUPPORT
+  unsigned int vj_enabled              :1; /* Flag indicating VJ compression enabled. */
+#endif /* VJ_SUPPORT */
+#if CCP_SUPPORT
+  unsigned int ccp_all_rejected        :1; /* we rejected all peer's options */
+#endif /* CCP_SUPPORT */
+#if MPPE_SUPPORT
+  unsigned int mppe_keys_set           :1; /* Have the MPPE keys been set? */
+#endif /* MPPE_SUPPORT */
+
+#if PPP_AUTH_SUPPORT
+  /* auth data */
+#if PPP_SERVER && defined(HAVE_MULTILINK)
+  char peer_authname[MAXNAMELEN + 1]; /* The name by which the peer authenticated itself to us. */
+#endif /* PPP_SERVER && defined(HAVE_MULTILINK) */
+  u16_t auth_pending;        /* Records which authentication operations haven't completed yet. */
+  u16_t auth_done;           /* Records which authentication operations have been completed. */
+
+#if PAP_SUPPORT
+  upap_state upap;           /* PAP data */
+#endif /* PAP_SUPPORT */
+
+#if CHAP_SUPPORT
+  chap_client_state chap_client;  /* CHAP client data */
+#if PPP_SERVER
+  chap_server_state chap_server;  /* CHAP server data */
+#endif /* PPP_SERVER */
+#endif /* CHAP_SUPPORT */
+
+#if EAP_SUPPORT
+  eap_state eap;            /* EAP data */
+#endif /* EAP_SUPPORT */
+#endif /* PPP_AUTH_SUPPORT */
+
+  fsm lcp_fsm;                   /* LCP fsm structure */
+  lcp_options lcp_wantoptions;   /* Options that we want to request */
+  lcp_options lcp_gotoptions;    /* Options that peer ack'd */
+  lcp_options lcp_allowoptions;  /* Options we allow peer to request */
+  lcp_options lcp_hisoptions;    /* Options that we ack'd */
+  u16_t peer_mru;                /* currently negotiated peer MRU */
+  u8_t lcp_echos_pending;        /* Number of outstanding echo msgs */
+  u8_t lcp_echo_number;          /* ID number of next echo frame */
+
+  u8_t num_np_open;              /* Number of network protocols which we have opened. */
+  u8_t num_np_up;                /* Number of network protocols which have come up. */
+
+#if VJ_SUPPORT
+  struct vjcompress vj_comp;     /* Van Jacobson compression header. */
+#endif /* VJ_SUPPORT */
+
+#if CCP_SUPPORT
+  fsm ccp_fsm;                   /* CCP fsm structure */
+  ccp_options ccp_wantoptions;   /* what to request the peer to use */
+  ccp_options ccp_gotoptions;    /* what the peer agreed to do */
+  ccp_options ccp_allowoptions;  /* what we'll agree to do */
+  ccp_options ccp_hisoptions;    /* what we agreed to do */
+  u8_t ccp_localstate;           /* Local state (mainly for handling reset-reqs and reset-acks). */
+  u8_t ccp_receive_method;       /* Method chosen on receive path */
+  u8_t ccp_transmit_method;      /* Method chosen on transmit path */
+#if MPPE_SUPPORT
+  ppp_mppe_state mppe_comp;      /* MPPE "compressor" structure */
+  ppp_mppe_state mppe_decomp;    /* MPPE "decompressor" structure */
+#endif /* MPPE_SUPPORT */
+#endif /* CCP_SUPPORT */
+
+#if PPP_IPV4_SUPPORT
+  fsm ipcp_fsm;                   /* IPCP fsm structure */
+  ipcp_options ipcp_wantoptions;  /* Options that we want to request */
+  ipcp_options ipcp_gotoptions;   /* Options that peer ack'd */
+  ipcp_options ipcp_allowoptions; /* Options we allow peer to request */
+  ipcp_options ipcp_hisoptions;   /* Options that we ack'd */
+#endif /* PPP_IPV4_SUPPORT */
+
+#if PPP_IPV6_SUPPORT
+  fsm ipv6cp_fsm;                     /* IPV6CP fsm structure */
+  ipv6cp_options ipv6cp_wantoptions;  /* Options that we want to request */
+  ipv6cp_options ipv6cp_gotoptions;   /* Options that peer ack'd */
+  ipv6cp_options ipv6cp_allowoptions; /* Options we allow peer to request */
+  ipv6cp_options ipv6cp_hisoptions;   /* Options that we ack'd */
+#endif /* PPP_IPV6_SUPPORT */
+};
+
+/************************
+ *** PUBLIC FUNCTIONS ***
+ ************************/
+
+/*
+ * WARNING: For multi-threads environment, all ppp_set_* functions most
+ * only be called while the PPP is in the dead phase (i.e. disconnected).
+ */
+
+#if PPP_AUTH_SUPPORT
+/*
+ * Set PPP authentication.
+ *
+ * Warning: Using PPPAUTHTYPE_ANY might have security consequences.
+ * RFC 1994 says:
+ *
+ * In practice, within or associated with each PPP server, there is a
+ * database which associates "user" names with authentication
+ * information ("secrets").  It is not anticipated that a particular
+ * named user would be authenticated by multiple methods.  This would
+ * make the user vulnerable to attacks which negotiate the least secure
+ * method from among a set (such as PAP rather than CHAP).  If the same
+ * secret was used, PAP would reveal the secret to be used later with
+ * CHAP.
+ *
+ * Instead, for each user name there should be an indication of exactly
+ * one method used to authenticate that user name.  If a user needs to
+ * make use of different authentication methods under different
+ * circumstances, then distinct user names SHOULD be employed, each of
+ * which identifies exactly one authentication method.
+ *
+ * Default is none auth type, unset (NULL) user and passwd.
+ */
+#define PPPAUTHTYPE_NONE      0x00
+#define PPPAUTHTYPE_PAP       0x01
+#define PPPAUTHTYPE_CHAP      0x02
+#define PPPAUTHTYPE_MSCHAP    0x04
+#define PPPAUTHTYPE_MSCHAP_V2 0x08
+#define PPPAUTHTYPE_EAP       0x10
+#define PPPAUTHTYPE_ANY       0xff
+void ppp_set_auth(ppp_pcb *pcb, u8_t authtype, const char *user, const char *passwd);
+
+/*
+ * If set, peer is required to authenticate. This is mostly necessary for PPP server support.
+ *
+ * Default is false.
+ */
+#define ppp_set_auth_required(ppp, boolval) (ppp->settings.auth_required = boolval)
+#endif /* PPP_AUTH_SUPPORT */
+
+#if PPP_IPV4_SUPPORT
+/*
+ * Set PPP interface "our" and "his" IPv4 addresses. This is mostly necessary for PPP server
+ * support but it can also be used on a PPP link where each side choose its own IP address.
+ *
+ * Default is unset (0.0.0.0).
+ */
+#define ppp_set_ipcp_ouraddr(ppp, addr) do { ppp->ipcp_wantoptions.ouraddr = ip4_addr_get_u32(addr); \
+                                             ppp->ask_for_local = ppp->ipcp_wantoptions.ouraddr != 0; } while(0)
+#define ppp_set_ipcp_hisaddr(ppp, addr) (ppp->ipcp_wantoptions.hisaddr = ip4_addr_get_u32(addr))
+#if LWIP_DNS
+/*
+ * Set DNS server addresses that are sent if the peer asks for them. This is mostly necessary
+ * for PPP server support.
+ *
+ * Default is unset (0.0.0.0).
+ */
+#define ppp_set_ipcp_dnsaddr(ppp, index, addr) (ppp->ipcp_allowoptions.dnsaddr[index] = ip4_addr_get_u32(addr))
+
+/*
+ * If set, we ask the peer for up to 2 DNS server addresses. Received DNS server addresses are
+ * registered using the dns_setserver() function.
+ *
+ * Default is false.
+ */
+#define ppp_set_usepeerdns(ppp, boolval) (ppp->settings.usepeerdns = boolval)
+#endif /* LWIP_DNS */
+#endif /* PPP_IPV4_SUPPORT */
+
+#if MPPE_SUPPORT
+/* Disable MPPE (Microsoft Point to Point Encryption). This parameter is exclusive. */
+#define PPP_MPPE_DISABLE           0x00
+/* Require the use of MPPE (Microsoft Point to Point Encryption). */
+#define PPP_MPPE_ENABLE            0x01
+/* Allow MPPE to use stateful mode. Stateless mode is still attempted first. */
+#define PPP_MPPE_ALLOW_STATEFUL    0x02
+/* Refuse the use of MPPE with 40-bit encryption. Conflict with PPP_MPPE_REFUSE_128. */
+#define PPP_MPPE_REFUSE_40         0x04
+/* Refuse the use of MPPE with 128-bit encryption. Conflict with PPP_MPPE_REFUSE_40. */
+#define PPP_MPPE_REFUSE_128        0x08
+/*
+ * Set MPPE configuration
+ *
+ * Default is disabled.
+ */
+void ppp_set_mppe(ppp_pcb *pcb, u8_t flags);
+#endif /* MPPE_SUPPORT */
+
+/*
+ * Wait for up to intval milliseconds for a valid PPP packet from the peer.
+ * At the end of this  time, or when a valid PPP packet is received from the
+ * peer, we commence negotiation by sending our first LCP packet.
+ *
+ * Default is 0.
+ */
+#define ppp_set_listen_time(ppp, intval) (ppp->settings.listen_time = intval)
+
+/*
+ * If set, we will attempt to initiate a connection but if no reply is received from
+ * the peer, we will then just wait passively for a valid LCP packet from the peer.
+ *
+ * Default is false.
+ */
+#define ppp_set_passive(ppp, boolval) (ppp->lcp_wantoptions.passive = boolval)
+
+/*
+ * If set, we will not transmit LCP packets to initiate a connection until a valid
+ * LCP packet is received from the peer. This is what we usually call the server mode.
+ *
+ * Default is false.
+ */
+#define ppp_set_silent(ppp, boolval) (ppp->lcp_wantoptions.silent = boolval)
+
+/*
+ * If set, enable protocol field compression negotiation in both the receive and
+ * the transmit direction.
+ *
+ * Default is true.
+ */
+#define ppp_set_neg_pcomp(ppp, boolval) (ppp->lcp_wantoptions.neg_pcompression = \
+                                         ppp->lcp_allowoptions.neg_pcompression = boolval)
+
+/*
+ * If set, enable Address/Control compression in both the receive and the transmit
+ * direction.
+ *
+ * Default is true.
+ */
+#define ppp_set_neg_accomp(ppp, boolval) (ppp->lcp_wantoptions.neg_accompression = \
+                                          ppp->lcp_allowoptions.neg_accompression = boolval)
+
+/*
+ * If set, enable asyncmap negotiation. Otherwise forcing all control characters to
+ * be escaped for both the transmit and the receive direction.
+ *
+ * Default is true.
+ */
+#define ppp_set_neg_asyncmap(ppp, boolval) (ppp->lcp_wantoptions.neg_asyncmap = \
+                                            ppp->lcp_allowoptions.neg_asyncmap = boolval)
+
+/*
+ * This option sets the Async-Control-Character-Map (ACCM) for this end of the link.
+ * The ACCM is a set of 32 bits, one for each of the ASCII control characters with
+ * values from 0 to 31, where a 1 bit  indicates that the corresponding control
+ * character should not be used in PPP packets sent to this system. The map is
+ * an unsigned 32 bits integer where the least significant bit (00000001) represents
+ * character 0 and the most significant bit (80000000) represents character 31.
+ * We will then ask the peer to send these characters as a 2-byte escape sequence.
+ *
+ * Default is 0.
+ */
+#define ppp_set_asyncmap(ppp, intval) (ppp->lcp_wantoptions.asyncmap = intval)
+
+/*
+ * Set a PPP interface as the default network interface
+ * (used to output all packets for which no specific route is found).
+ */
+#define ppp_set_default(ppp)         netif_set_default(ppp->netif)
+
+#if PPP_NOTIFY_PHASE
+/*
+ * Set a PPP notify phase callback.
+ *
+ * This can be used for example to set a LED pattern depending on the
+ * current phase of the PPP session.
+ */
+typedef void (*ppp_notify_phase_cb_fn)(ppp_pcb *pcb, u8_t phase, void *ctx);
+void ppp_set_notify_phase_callback(ppp_pcb *pcb, ppp_notify_phase_cb_fn notify_phase_cb);
+#endif /* PPP_NOTIFY_PHASE */
+
+/*
+ * Initiate a PPP connection.
+ *
+ * This can only be called if PPP is in the dead phase.
+ *
+ * Holdoff is the time to wait (in seconds) before initiating
+ * the connection.
+ *
+ * If this port connects to a modem, the modem connection must be
+ * established before calling this.
+ */
+err_t ppp_connect(ppp_pcb *pcb, u16_t holdoff);
+
+#if PPP_SERVER
+/*
+ * Listen for an incoming PPP connection.
+ *
+ * This can only be called if PPP is in the dead phase.
+ *
+ * If this port connects to a modem, the modem connection must be
+ * established before calling this.
+ */
+err_t ppp_listen(ppp_pcb *pcb);
+#endif /* PPP_SERVER */
+
+/*
+ * Initiate the end of a PPP connection.
+ * Any outstanding packets in the queues are dropped.
+ *
+ * Setting nocarrier to 1 close the PPP connection without initiating the
+ * shutdown procedure. Always using nocarrier = 0 is still recommended,
+ * this is going to take a little longer time if your link is down, but
+ * is a safer choice for the PPP state machine.
+ *
+ * Return 0 on success, an error code on failure.
+ */
+err_t ppp_close(ppp_pcb *pcb, u8_t nocarrier);
+
+/*
+ * Release the control block.
+ *
+ * This can only be called if PPP is in the dead phase.
+ *
+ * You must use ppp_close() before if you wish to terminate
+ * an established PPP session.
+ *
+ * Return 0 on success, an error code on failure.
+ */
+err_t ppp_free(ppp_pcb *pcb);
+
+/*
+ * PPP IOCTL commands.
+ *
+ * Get the up status - 0 for down, non-zero for up.  The argument must
+ * point to an int.
+ */
+#define PPPCTLG_UPSTATUS 0
+
+/*
+ * Get the PPP error code.  The argument must point to an int.
+ * Returns a PPPERR_* value.
+ */
+#define PPPCTLG_ERRCODE  1
+
+/*
+ * Get the fd associated with a PPP over serial
+ */
+#define PPPCTLG_FD       2
+
+/*
+ * Get and set parameters for the given connection.
+ * Return 0 on success, an error code on failure.
+ */
+err_t ppp_ioctl(ppp_pcb *pcb, u8_t cmd, void *arg);
+
+/* Get the PPP netif interface */
+#define ppp_netif(ppp)               (ppp->netif)
+
+/* Set an lwIP-style status-callback for the selected PPP device */
+#define ppp_set_netif_statuscallback(ppp, status_cb)       \
+        netif_set_status_callback(ppp->netif, status_cb);
+
+/* Set an lwIP-style link-callback for the selected PPP device */
+#define ppp_set_netif_linkcallback(ppp, link_cb)           \
+        netif_set_link_callback(ppp->netif, link_cb);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* PPP_H */
+
+#endif /* PPP_SUPPORT */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/netif/ppp/ppp_impl.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/netif/ppp/ppp_impl.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/netif/ppp/ppp_impl.h	(revision 457)
@@ -0,0 +1,722 @@
+/*****************************************************************************
+* ppp.h - Network Point to Point Protocol header file.
+*
+* Copyright (c) 2003 by Marc Boucher, Services Informatiques (MBSI) inc.
+* portions Copyright (c) 1997 Global Election Systems Inc.
+*
+* The authors hereby grant permission to use, copy, modify, distribute,
+* and license this software and its documentation for any purpose, provided
+* that existing copyright notices are retained in all copies and that this
+* notice and the following disclaimer are included verbatim in any
+* distributions. No written agreement, license, or royalty fee is required
+* for any of the authorized uses.
+*
+* THIS SOFTWARE IS PROVIDED BY THE 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 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.
+*
+******************************************************************************
+* REVISION HISTORY
+*
+* 03-01-01 Marc Boucher <marc@mbsi.ca>
+*   Ported to lwIP.
+* 97-11-05 Guy Lancaster <glanca@gesn.com>, Global Election Systems Inc.
+*   Original derived from BSD codes.
+*****************************************************************************/
+#ifndef LWIP_HDR_PPP_IMPL_H
+#define LWIP_HDR_PPP_IMPL_H
+
+#include "netif/ppp/ppp_opts.h"
+
+#if PPP_SUPPORT /* don't build if not configured for use in lwipopts.h */
+
+#ifdef PPP_INCLUDE_SETTINGS_HEADER
+#include "ppp_settings.h"
+#endif
+
+#include <stdio.h> /* formats */
+#include <stdarg.h>
+#include <string.h>
+#include <stdlib.h> /* strtol() */
+
+#include "lwip/netif.h"
+#include "lwip/def.h"
+#include "lwip/timeouts.h"
+
+#include "ppp.h"
+#include "pppdebug.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * Memory used for control packets.
+ *
+ * PPP_CTRL_PBUF_MAX_SIZE is the amount of memory we allocate when we
+ * cannot figure out how much we are going to use before filling the buffer.
+ */
+#if PPP_USE_PBUF_RAM
+#define PPP_CTRL_PBUF_TYPE       PBUF_RAM
+#define PPP_CTRL_PBUF_MAX_SIZE   512
+#else /* PPP_USE_PBUF_RAM */
+#define PPP_CTRL_PBUF_TYPE       PBUF_POOL
+#define PPP_CTRL_PBUF_MAX_SIZE   PBUF_POOL_BUFSIZE
+#endif /* PPP_USE_PBUF_RAM */
+
+/*
+ * The basic PPP frame.
+ */
+#define PPP_ADDRESS(p)	(((u_char *)(p))[0])
+#define PPP_CONTROL(p)	(((u_char *)(p))[1])
+#define PPP_PROTOCOL(p)	((((u_char *)(p))[2] << 8) + ((u_char *)(p))[3])
+
+/*
+ * Significant octet values.
+ */
+#define	PPP_ALLSTATIONS	0xff	/* All-Stations broadcast address */
+#define	PPP_UI		0x03	/* Unnumbered Information */
+#define	PPP_FLAG	0x7e	/* Flag Sequence */
+#define	PPP_ESCAPE	0x7d	/* Asynchronous Control Escape */
+#define	PPP_TRANS	0x20	/* Asynchronous transparency modifier */
+
+/*
+ * Protocol field values.
+ */
+#define PPP_IP		0x21	/* Internet Protocol */
+#if 0 /* UNUSED */
+#define PPP_AT		0x29	/* AppleTalk Protocol */
+#define PPP_IPX		0x2b	/* IPX protocol */
+#endif /* UNUSED */
+#if VJ_SUPPORT
+#define	PPP_VJC_COMP	0x2d	/* VJ compressed TCP */
+#define	PPP_VJC_UNCOMP	0x2f	/* VJ uncompressed TCP */
+#endif /* VJ_SUPPORT */
+#if PPP_IPV6_SUPPORT
+#define PPP_IPV6	0x57	/* Internet Protocol Version 6 */
+#endif /* PPP_IPV6_SUPPORT */
+#if CCP_SUPPORT
+#define PPP_COMP	0xfd	/* compressed packet */
+#endif /* CCP_SUPPORT */
+#define PPP_IPCP	0x8021	/* IP Control Protocol */
+#if 0 /* UNUSED */
+#define PPP_ATCP	0x8029	/* AppleTalk Control Protocol */
+#define PPP_IPXCP	0x802b	/* IPX Control Protocol */
+#endif /* UNUSED */
+#if PPP_IPV6_SUPPORT
+#define PPP_IPV6CP	0x8057	/* IPv6 Control Protocol */
+#endif /* PPP_IPV6_SUPPORT */
+#if CCP_SUPPORT
+#define PPP_CCP		0x80fd	/* Compression Control Protocol */
+#endif /* CCP_SUPPORT */
+#if ECP_SUPPORT
+#define PPP_ECP		0x8053	/* Encryption Control Protocol */
+#endif /* ECP_SUPPORT */
+#define PPP_LCP		0xc021	/* Link Control Protocol */
+#if PAP_SUPPORT
+#define PPP_PAP		0xc023	/* Password Authentication Protocol */
+#endif /* PAP_SUPPORT */
+#if LQR_SUPPORT
+#define PPP_LQR		0xc025	/* Link Quality Report protocol */
+#endif /* LQR_SUPPORT */
+#if CHAP_SUPPORT
+#define PPP_CHAP	0xc223	/* Cryptographic Handshake Auth. Protocol */
+#endif /* CHAP_SUPPORT */
+#if CBCP_SUPPORT
+#define PPP_CBCP	0xc029	/* Callback Control Protocol */
+#endif /* CBCP_SUPPORT */
+#if EAP_SUPPORT
+#define PPP_EAP		0xc227	/* Extensible Authentication Protocol */
+#endif /* EAP_SUPPORT */
+
+/*
+ * The following struct gives the addresses of procedures to call
+ * for a particular lower link level protocol.
+ */
+struct link_callbacks {
+  /* Start a connection (e.g. Initiate discovery phase) */
+  void (*connect) (ppp_pcb *pcb, void *ctx);
+#if PPP_SERVER
+  /* Listen for an incoming connection (Passive mode) */
+  void (*listen) (ppp_pcb *pcb, void *ctx);
+#endif /* PPP_SERVER */
+  /* End a connection (i.e. initiate disconnect phase) */
+  void (*disconnect) (ppp_pcb *pcb, void *ctx);
+  /* Free lower protocol control block */
+  err_t (*free) (ppp_pcb *pcb, void *ctx);
+  /* Write a pbuf to a ppp link, only used from PPP functions to send PPP packets. */
+  err_t (*write)(ppp_pcb *pcb, void *ctx, struct pbuf *p);
+  /* Send a packet from lwIP core (IPv4 or IPv6) */
+  err_t (*netif_output)(ppp_pcb *pcb, void *ctx, struct pbuf *p, u_short protocol);
+  /* configure the transmit-side characteristics of the PPP interface */
+  void (*send_config)(ppp_pcb *pcb, void *ctx, u32_t accm, int pcomp, int accomp);
+  /* confire the receive-side characteristics of the PPP interface */
+  void (*recv_config)(ppp_pcb *pcb, void *ctx, u32_t accm, int pcomp, int accomp);
+};
+
+/*
+ * What to do with network protocol (NP) packets.
+ */
+enum NPmode {
+    NPMODE_PASS,		/* pass the packet through */
+    NPMODE_DROP,		/* silently drop the packet */
+    NPMODE_ERROR,		/* return an error */
+    NPMODE_QUEUE		/* save it up for later. */
+};
+
+/*
+ * Statistics.
+ */
+#if PPP_STATS_SUPPORT
+struct pppstat	{
+    unsigned int ppp_ibytes;	/* bytes received */
+    unsigned int ppp_ipackets;	/* packets received */
+    unsigned int ppp_ierrors;	/* receive errors */
+    unsigned int ppp_obytes;	/* bytes sent */
+    unsigned int ppp_opackets;	/* packets sent */
+    unsigned int ppp_oerrors;	/* transmit errors */
+};
+
+#if VJ_SUPPORT
+struct vjstat {
+    unsigned int vjs_packets;	/* outbound packets */
+    unsigned int vjs_compressed; /* outbound compressed packets */
+    unsigned int vjs_searches;	/* searches for connection state */
+    unsigned int vjs_misses;	/* times couldn't find conn. state */
+    unsigned int vjs_uncompressedin; /* inbound uncompressed packets */
+    unsigned int vjs_compressedin; /* inbound compressed packets */
+    unsigned int vjs_errorin;	/* inbound unknown type packets */
+    unsigned int vjs_tossed;	/* inbound packets tossed because of error */
+};
+#endif /* VJ_SUPPORT */
+
+struct ppp_stats {
+    struct pppstat p;		/* basic PPP statistics */
+#if VJ_SUPPORT
+    struct vjstat vj;		/* VJ header compression statistics */
+#endif /* VJ_SUPPORT */
+};
+
+#if CCP_SUPPORT
+struct compstat {
+    unsigned int unc_bytes;	/* total uncompressed bytes */
+    unsigned int unc_packets;	/* total uncompressed packets */
+    unsigned int comp_bytes;	/* compressed bytes */
+    unsigned int comp_packets;	/* compressed packets */
+    unsigned int inc_bytes;	/* incompressible bytes */
+    unsigned int inc_packets;	/* incompressible packets */
+    unsigned int ratio;		/* recent compression ratio << 8 */
+};
+
+struct ppp_comp_stats {
+    struct compstat c;		/* packet compression statistics */
+    struct compstat d;		/* packet decompression statistics */
+};
+#endif /* CCP_SUPPORT */
+
+#endif /* PPP_STATS_SUPPORT */
+
+#if PPP_IDLETIMELIMIT
+/*
+ * The following structure records the time in seconds since
+ * the last NP packet was sent or received.
+ */
+struct ppp_idle {
+    time_t xmit_idle;		/* time since last NP packet sent */
+    time_t recv_idle;		/* time since last NP packet received */
+};
+#endif /* PPP_IDLETIMELIMIT */
+
+/* values for epdisc.class */
+#define EPD_NULL	0	/* null discriminator, no data */
+#define EPD_LOCAL	1
+#define EPD_IP		2
+#define EPD_MAC		3
+#define EPD_MAGIC	4
+#define EPD_PHONENUM	5
+
+/*
+ * Global variables.
+ */
+#ifdef HAVE_MULTILINK
+extern u8_t	multilink;	/* enable multilink operation */
+extern u8_t	doing_multilink;
+extern u8_t	multilink_master;
+extern u8_t	bundle_eof;
+extern u8_t	bundle_terminating;
+#endif
+
+#ifdef MAXOCTETS
+extern unsigned int maxoctets;	     /* Maximum octetes per session (in bytes) */
+extern int       maxoctets_dir;      /* Direction :
+				      0 - in+out (default)
+				      1 - in
+				      2 - out
+				      3 - max(in,out) */
+extern int       maxoctets_timeout;  /* Timeout for check of octets limit */
+#define PPP_OCTETS_DIRECTION_SUM        0
+#define PPP_OCTETS_DIRECTION_IN         1
+#define PPP_OCTETS_DIRECTION_OUT        2
+#define PPP_OCTETS_DIRECTION_MAXOVERAL  3
+/* same as previos, but little different on RADIUS side */
+#define PPP_OCTETS_DIRECTION_MAXSESSION 4
+#endif
+
+/* Data input may be used by CCP and ECP, remove this entry
+ * from struct protent to save some flash
+ */
+#define PPP_DATAINPUT 0
+
+/*
+ * The following struct gives the addresses of procedures to call
+ * for a particular protocol.
+ */
+struct protent {
+    u_short protocol;		/* PPP protocol number */
+    /* Initialization procedure */
+    void (*init) (ppp_pcb *pcb);
+    /* Process a received packet */
+    void (*input) (ppp_pcb *pcb, u_char *pkt, int len);
+    /* Process a received protocol-reject */
+    void (*protrej) (ppp_pcb *pcb);
+    /* Lower layer has come up */
+    void (*lowerup) (ppp_pcb *pcb);
+    /* Lower layer has gone down */
+    void (*lowerdown) (ppp_pcb *pcb);
+    /* Open the protocol */
+    void (*open) (ppp_pcb *pcb);
+    /* Close the protocol */
+    void (*close) (ppp_pcb *pcb, const char *reason);
+#if PRINTPKT_SUPPORT
+    /* Print a packet in readable form */
+    int  (*printpkt) (const u_char *pkt, int len,
+			  void (*printer) (void *, const char *, ...),
+			  void *arg);
+#endif /* PRINTPKT_SUPPORT */
+#if PPP_DATAINPUT
+    /* Process a received data packet */
+    void (*datainput) (ppp_pcb *pcb, u_char *pkt, int len);
+#endif /* PPP_DATAINPUT */
+#if PRINTPKT_SUPPORT
+    const char *name;		/* Text name of protocol */
+    const char *data_name;	/* Text name of corresponding data protocol */
+#endif /* PRINTPKT_SUPPORT */
+#if PPP_OPTIONS
+    option_t *options;		/* List of command-line options */
+    /* Check requested options, assign defaults */
+    void (*check_options) (void);
+#endif /* PPP_OPTIONS */
+#if DEMAND_SUPPORT
+    /* Configure interface for demand-dial */
+    int  (*demand_conf) (int unit);
+    /* Say whether to bring up link for this pkt */
+    int  (*active_pkt) (u_char *pkt, int len);
+#endif /* DEMAND_SUPPORT */
+};
+
+/* Table of pointers to supported protocols */
+extern const struct protent* const protocols[];
+
+
+/* Values for auth_pending, auth_done */
+#if PAP_SUPPORT
+#define PAP_WITHPEER	0x1
+#define PAP_PEER	0x2
+#endif /* PAP_SUPPORT */
+#if CHAP_SUPPORT
+#define CHAP_WITHPEER	0x4
+#define CHAP_PEER	0x8
+#endif /* CHAP_SUPPORT */
+#if EAP_SUPPORT
+#define EAP_WITHPEER	0x10
+#define EAP_PEER	0x20
+#endif /* EAP_SUPPORT */
+
+/* Values for auth_done only */
+#if CHAP_SUPPORT
+#define CHAP_MD5_WITHPEER	0x40
+#define CHAP_MD5_PEER		0x80
+#if MSCHAP_SUPPORT
+#define CHAP_MS_SHIFT		8	/* LSB position for MS auths */
+#define CHAP_MS_WITHPEER	0x100
+#define CHAP_MS_PEER		0x200
+#define CHAP_MS2_WITHPEER	0x400
+#define CHAP_MS2_PEER		0x800
+#endif /* MSCHAP_SUPPORT */
+#endif /* CHAP_SUPPORT */
+
+/* Supported CHAP protocols */
+#if CHAP_SUPPORT
+
+#if MSCHAP_SUPPORT
+#define CHAP_MDTYPE_SUPPORTED (MDTYPE_MICROSOFT_V2 | MDTYPE_MICROSOFT | MDTYPE_MD5)
+#else /* MSCHAP_SUPPORT */
+#define CHAP_MDTYPE_SUPPORTED (MDTYPE_MD5)
+#endif /* MSCHAP_SUPPORT */
+
+#else /* CHAP_SUPPORT */
+#define CHAP_MDTYPE_SUPPORTED (MDTYPE_NONE)
+#endif /* CHAP_SUPPORT */
+
+#if PPP_STATS_SUPPORT
+/*
+ * PPP statistics structure
+ */
+struct pppd_stats {
+    unsigned int	bytes_in;
+    unsigned int	bytes_out;
+    unsigned int	pkts_in;
+    unsigned int	pkts_out;
+};
+#endif /* PPP_STATS_SUPPORT */
+
+
+/*
+ * PPP private functions
+ */
+
+ 
+/*
+ * Functions called from lwIP core.
+ */
+
+/* initialize the PPP subsystem */
+int ppp_init(void);
+
+/*
+ * Functions called from PPP link protocols.
+ */
+
+/* Create a new PPP control block */
+ppp_pcb *ppp_new(struct netif *pppif, const struct link_callbacks *callbacks, void *link_ctx_cb,
+                 ppp_link_status_cb_fn link_status_cb, void *ctx_cb);
+
+/* Initiate LCP open request */
+void ppp_start(ppp_pcb *pcb);
+
+/* Called when link failed to setup */
+void ppp_link_failed(ppp_pcb *pcb);
+
+/* Called when link is normally down (i.e. it was asked to end) */
+void ppp_link_end(ppp_pcb *pcb);
+
+/* function called to process input packet */
+void ppp_input(ppp_pcb *pcb, struct pbuf *pb);
+
+
+/*
+ * Functions called by PPP protocols.
+ */
+
+/* function called by all PPP subsystems to send packets */
+err_t ppp_write(ppp_pcb *pcb, struct pbuf *p);
+
+/* functions called by auth.c link_terminated() */
+void ppp_link_terminated(ppp_pcb *pcb);
+
+void new_phase(ppp_pcb *pcb, int p);
+
+int ppp_send_config(ppp_pcb *pcb, int mtu, u32_t accm, int pcomp, int accomp);
+int ppp_recv_config(ppp_pcb *pcb, int mru, u32_t accm, int pcomp, int accomp);
+
+#if PPP_IPV4_SUPPORT
+int sifaddr(ppp_pcb *pcb, u32_t our_adr, u32_t his_adr, u32_t netmask);
+int cifaddr(ppp_pcb *pcb, u32_t our_adr, u32_t his_adr);
+#if 0 /* UNUSED - PROXY ARP */
+int sifproxyarp(ppp_pcb *pcb, u32_t his_adr);
+int cifproxyarp(ppp_pcb *pcb, u32_t his_adr);
+#endif /* UNUSED - PROXY ARP */
+#if LWIP_DNS
+int sdns(ppp_pcb *pcb, u32_t ns1, u32_t ns2);
+int cdns(ppp_pcb *pcb, u32_t ns1, u32_t ns2);
+#endif /* LWIP_DNS */
+#if VJ_SUPPORT
+int sifvjcomp(ppp_pcb *pcb, int vjcomp, int cidcomp, int maxcid);
+#endif /* VJ_SUPPORT */
+int sifup(ppp_pcb *pcb);
+int sifdown (ppp_pcb *pcb);
+u32_t get_mask(u32_t addr);
+#endif /* PPP_IPV4_SUPPORT */
+
+#if PPP_IPV6_SUPPORT
+int sif6addr(ppp_pcb *pcb, eui64_t our_eui64, eui64_t his_eui64);
+int cif6addr(ppp_pcb *pcb, eui64_t our_eui64, eui64_t his_eui64);
+int sif6up(ppp_pcb *pcb);
+int sif6down (ppp_pcb *pcb);
+#endif /* PPP_IPV6_SUPPORT */
+
+#if DEMAND_SUPPORT
+int sifnpmode(ppp_pcb *pcb, int proto, enum NPmode mode);
+#endif /* DEMAND_SUPPORt */
+
+void netif_set_mtu(ppp_pcb *pcb, int mtu);
+int netif_get_mtu(ppp_pcb *pcb);
+
+#if CCP_SUPPORT
+#if 0 /* unused */
+int ccp_test(ppp_pcb *pcb, u_char *opt_ptr, int opt_len, int for_transmit);
+#endif /* unused */
+void ccp_set(ppp_pcb *pcb, u8_t isopen, u8_t isup, u8_t receive_method, u8_t transmit_method);
+void ccp_reset_comp(ppp_pcb *pcb);
+void ccp_reset_decomp(ppp_pcb *pcb);
+#if 0 /* unused */
+int ccp_fatal_error(ppp_pcb *pcb);
+#endif /* unused */
+#endif /* CCP_SUPPORT */
+
+#if PPP_IDLETIMELIMIT
+int get_idle_time(ppp_pcb *pcb, struct ppp_idle *ip);
+#endif /* PPP_IDLETIMELIMIT */
+
+#if DEMAND_SUPPORT
+int get_loop_output(void);
+#endif /* DEMAND_SUPPORT */
+
+/* Optional protocol names list, to make our messages a little more informative. */
+#if PPP_PROTOCOLNAME
+const char * protocol_name(int proto);
+#endif /* PPP_PROTOCOLNAME  */
+
+/* Optional stats support, to get some statistics on the PPP interface */
+#if PPP_STATS_SUPPORT
+void print_link_stats(void); /* Print stats, if available */
+void reset_link_stats(int u); /* Reset (init) stats when link goes up */
+void update_link_stats(int u); /* Get stats at link termination */
+#endif /* PPP_STATS_SUPPORT */
+
+
+
+/*
+ * Inline versions of get/put char/short/long.
+ * Pointer is advanced; we assume that both arguments
+ * are lvalues and will already be in registers.
+ * cp MUST be u_char *.
+ */
+#define GETCHAR(c, cp) { \
+	(c) = *(cp)++; \
+}
+#define PUTCHAR(c, cp) { \
+	*(cp)++ = (u_char) (c); \
+}
+#define GETSHORT(s, cp) { \
+	(s) = *(cp)++ << 8; \
+	(s) |= *(cp)++; \
+}
+#define PUTSHORT(s, cp) { \
+	*(cp)++ = (u_char) ((s) >> 8); \
+	*(cp)++ = (u_char) (s); \
+}
+#define GETLONG(l, cp) { \
+	(l) = *(cp)++ << 8; \
+	(l) |= *(cp)++; (l) <<= 8; \
+	(l) |= *(cp)++; (l) <<= 8; \
+	(l) |= *(cp)++; \
+}
+#define PUTLONG(l, cp) { \
+	*(cp)++ = (u_char) ((l) >> 24); \
+	*(cp)++ = (u_char) ((l) >> 16); \
+	*(cp)++ = (u_char) ((l) >> 8); \
+	*(cp)++ = (u_char) (l); \
+}
+
+#define INCPTR(n, cp)	((cp) += (n))
+#define DECPTR(n, cp)	((cp) -= (n))
+
+/*
+ * System dependent definitions for user-level 4.3BSD UNIX implementation.
+ */
+#define TIMEOUT(f, a, t)        do { sys_untimeout((f), (a)); sys_timeout((t)*1000, (f), (a)); } while(0)
+#define TIMEOUTMS(f, a, t)      do { sys_untimeout((f), (a)); sys_timeout((t), (f), (a)); } while(0)
+#define UNTIMEOUT(f, a)         sys_untimeout((f), (a))
+
+#define BZERO(s, n)		memset(s, 0, n)
+#define	BCMP(s1, s2, l)		memcmp(s1, s2, l)
+
+#define PRINTMSG(m, l)		{ ppp_info("Remote message: %0.*v", l, m); }
+
+/*
+ * MAKEHEADER - Add Header fields to a packet.
+ */
+#define MAKEHEADER(p, t) { \
+    PUTCHAR(PPP_ALLSTATIONS, p); \
+    PUTCHAR(PPP_UI, p); \
+    PUTSHORT(t, p); }
+
+/* Procedures exported from auth.c */
+void link_required(ppp_pcb *pcb);     /* we are starting to use the link */
+void link_terminated(ppp_pcb *pcb);   /* we are finished with the link */
+void link_down(ppp_pcb *pcb);	      /* the LCP layer has left the Opened state */
+void upper_layers_down(ppp_pcb *pcb); /* take all NCPs down */
+void link_established(ppp_pcb *pcb);  /* the link is up; authenticate now */
+void start_networks(ppp_pcb *pcb);    /* start all the network control protos */
+void continue_networks(ppp_pcb *pcb); /* start network [ip, etc] control protos */
+#if PPP_AUTH_SUPPORT
+#if PPP_SERVER
+int auth_check_passwd(ppp_pcb *pcb, char *auser, int userlen, char *apasswd, int passwdlen, const char **msg, int *msglen);
+                                /* check the user name and passwd against configuration */
+void auth_peer_fail(ppp_pcb *pcb, int protocol);
+				/* peer failed to authenticate itself */
+void auth_peer_success(ppp_pcb *pcb, int protocol, int prot_flavor, const char *name, int namelen);
+				/* peer successfully authenticated itself */
+#endif /* PPP_SERVER */
+void auth_withpeer_fail(ppp_pcb *pcb, int protocol);
+				/* we failed to authenticate ourselves */
+void auth_withpeer_success(ppp_pcb *pcb, int protocol, int prot_flavor);
+				/* we successfully authenticated ourselves */
+#endif /* PPP_AUTH_SUPPORT */
+void np_up(ppp_pcb *pcb, int proto);    /* a network protocol has come up */
+void np_down(ppp_pcb *pcb, int proto);  /* a network protocol has gone down */
+void np_finished(ppp_pcb *pcb, int proto); /* a network protocol no longer needs link */
+#if PPP_AUTH_SUPPORT
+int get_secret(ppp_pcb *pcb, const char *client, const char *server, char *secret, int *secret_len, int am_server);
+				/* get "secret" for chap */
+#endif /* PPP_AUTH_SUPPORT */
+
+/* Procedures exported from ipcp.c */
+/* int parse_dotted_ip (char *, u32_t *); */
+
+/* Procedures exported from demand.c */
+#if DEMAND_SUPPORT
+void demand_conf (void);	/* config interface(s) for demand-dial */
+void demand_block (void);	/* set all NPs to queue up packets */
+void demand_unblock (void); /* set all NPs to pass packets */
+void demand_discard (void); /* set all NPs to discard packets */
+void demand_rexmit (int, u32_t); /* retransmit saved frames for an NP*/
+int  loop_chars (unsigned char *, int); /* process chars from loopback */
+int  loop_frame (unsigned char *, int); /* should we bring link up? */
+#endif /* DEMAND_SUPPORT */
+
+/* Procedures exported from multilink.c */
+#ifdef HAVE_MULTILINK
+void mp_check_options (void); /* Check multilink-related options */
+int  mp_join_bundle (void);  /* join our link to an appropriate bundle */
+void mp_exit_bundle (void);  /* have disconnected our link from bundle */
+void mp_bundle_terminated (void);
+char *epdisc_to_str (struct epdisc *); /* string from endpoint discrim. */
+int  str_to_epdisc (struct epdisc *, char *); /* endpt disc. from str */
+#else
+#define mp_bundle_terminated()	/* nothing */
+#define mp_exit_bundle()	/* nothing */
+#define doing_multilink		0
+#define multilink_master	0
+#endif
+
+/* Procedures exported from utils.c. */
+void ppp_print_string(const u_char *p, int len, void (*printer) (void *, const char *, ...), void *arg);   /* Format a string for output */
+int ppp_slprintf(char *buf, int buflen, const char *fmt, ...);            /* sprintf++ */
+int ppp_vslprintf(char *buf, int buflen, const char *fmt, va_list args);  /* vsprintf++ */
+size_t ppp_strlcpy(char *dest, const char *src, size_t len);        /* safe strcpy */
+size_t ppp_strlcat(char *dest, const char *src, size_t len);        /* safe strncpy */
+void ppp_dbglog(const char *fmt, ...);    /* log a debug message */
+void ppp_info(const char *fmt, ...);      /* log an informational message */
+void ppp_notice(const char *fmt, ...);    /* log a notice-level message */
+void ppp_warn(const char *fmt, ...);      /* log a warning message */
+void ppp_error(const char *fmt, ...);     /* log an error message */
+void ppp_fatal(const char *fmt, ...);     /* log an error message and die(1) */
+#if PRINTPKT_SUPPORT
+void ppp_dump_packet(ppp_pcb *pcb, const char *tag, unsigned char *p, int len);
+                                /* dump packet to debug log if interesting */
+#endif /* PRINTPKT_SUPPORT */
+
+/*
+ * Number of necessary timers analysis.
+ *
+ * PPP use at least one timer per each of its protocol, but not all protocols are
+ * active at the same time, thus the number of necessary timeouts is actually
+ * lower than enabled protocols. Here is the actual necessary timeouts based
+ * on code analysis.
+ *
+ * Note that many features analysed here are not working at all and are only
+ * there for a comprehensive analysis of necessary timers in order to prevent
+ * having to redo that each time we add a feature.
+ *
+ * Timer list
+ *
+ * | holdoff timeout
+ *  | low level protocol timeout (PPPoE or PPPoL2P)
+ *   | LCP delayed UP
+ *    | LCP retransmit (FSM)
+ *     | LCP Echo timer
+ *     .| PAP or CHAP or EAP authentication
+ *     . | ECP retransmit (FSM)
+ *     .  | CCP retransmit (FSM) when MPPE is enabled
+ *     .   | CCP retransmit (FSM) when MPPE is NOT enabled
+ *     .    | IPCP retransmit (FSM)
+ *     .    .| IP6CP retransmit (FSM)
+ *     .    . | Idle time limit
+ *     .    .  | Max connect time
+ *     .    .   | Max octets
+ *     .    .    | CCP RACK timeout
+ *     .    .    .
+ * PPP_PHASE_DEAD
+ * PPP_PHASE_HOLDOFF
+ * |   .    .    .
+ * PPP_PHASE_INITIALIZE
+ *  |  .    .    .
+ * PPP_PHASE_ESTABLISH
+ *   | .    .    .
+ *    |.    .    .
+ *     |    .    .
+ * PPP_PHASE_AUTHENTICATE
+ *     |    .    .
+ *     ||   .    .
+ * PPP_PHASE_NETWORK
+ *     | || .    .
+ *     |   |||   .
+ * PPP_PHASE_RUNNING
+ *     |    .|||||
+ *     |    . ||||
+ * PPP_PHASE_TERMINATE
+ *     |    . ||||
+ * PPP_PHASE_NETWORK
+ *    |.         .
+ * PPP_PHASE_ESTABLISH
+ * PPP_PHASE_DISCONNECT
+ * PPP_PHASE_DEAD
+ *
+ * Alright, PPP basic retransmission and LCP Echo consume one timer.
+ *  1
+ *
+ * If authentication is enabled one timer is necessary during authentication.
+ *  1 + PPP_AUTH_SUPPORT
+ *
+ * If ECP is enabled one timer is necessary before IPCP and/or IP6CP, one more
+ * is necessary if CCP is enabled (only with MPPE support but we don't care much
+ * up to this detail level).
+ *  1 + ECP_SUPPORT + CCP_SUPPORT
+ *
+ * If CCP is enabled it might consume a timer during IPCP or IP6CP, thus
+ * we might use IPCP, IP6CP and CCP timers simultaneously.
+ *  1 + PPP_IPV4_SUPPORT + PPP_IPV6_SUPPORT + CCP_SUPPORT
+ *
+ * When entering running phase, IPCP or IP6CP is still running. If idle time limit
+ * is enabled one more timer is necessary. Same for max connect time and max
+ * octets features. Furthermore CCP RACK might be used past this point.
+ *  1 + PPP_IPV4_SUPPORT + PPP_IPV6_SUPPORT -1 + PPP_IDLETIMELIMIT + PPP_MAXCONNECT + MAXOCTETS + CCP_SUPPORT
+ *
+ * IPv4 or IPv6 must be enabled, therefore we don't need to take care the authentication
+ * and the CCP + ECP case, thus reducing overall complexity.
+ * 1 + LWIP_MAX(PPP_IPV4_SUPPORT + PPP_IPV6_SUPPORT + CCP_SUPPORT, PPP_IPV4_SUPPORT + PPP_IPV6_SUPPORT -1 + PPP_IDLETIMELIMIT + PPP_MAXCONNECT + MAXOCTETS + CCP_SUPPORT)
+ *
+ * We don't support PPP_IDLETIMELIMIT + PPP_MAXCONNECT + MAXOCTETS features
+ * and adding those defines to ppp_opts.h just for having the value always
+ * defined to 0 isn't worth it.
+ * 1 + LWIP_MAX(PPP_IPV4_SUPPORT + PPP_IPV6_SUPPORT + CCP_SUPPORT, PPP_IPV4_SUPPORT + PPP_IPV6_SUPPORT -1 + CCP_SUPPORT)
+ *
+ * Thus, the following is enough for now.
+ * 1 + PPP_IPV4_SUPPORT + PPP_IPV6_SUPPORT + CCP_SUPPORT
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* PPP_SUPPORT */
+#endif /* LWIP_HDR_PPP_IMPL_H */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/netif/ppp/ppp_opts.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/netif/ppp/ppp_opts.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/netif/ppp/ppp_opts.h	(revision 457)
@@ -0,0 +1,610 @@
+/*
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ */
+
+#ifndef LWIP_PPP_OPTS_H
+#define LWIP_PPP_OPTS_H
+
+#include "lwip/opt.h"
+
+/**
+ * PPP_SUPPORT==1: Enable PPP.
+ */
+#ifndef PPP_SUPPORT
+#define PPP_SUPPORT                     0
+#endif
+
+/**
+ * PPPOE_SUPPORT==1: Enable PPP Over Ethernet
+ */
+#ifndef PPPOE_SUPPORT
+#define PPPOE_SUPPORT                   0
+#endif
+
+/**
+ * PPPOL2TP_SUPPORT==1: Enable PPP Over L2TP
+ */
+#ifndef PPPOL2TP_SUPPORT
+#define PPPOL2TP_SUPPORT                0
+#endif
+
+/**
+ * PPPOL2TP_AUTH_SUPPORT==1: Enable PPP Over L2TP Auth (enable MD5 support)
+ */
+#ifndef PPPOL2TP_AUTH_SUPPORT
+#define PPPOL2TP_AUTH_SUPPORT           PPPOL2TP_SUPPORT
+#endif
+
+/**
+ * PPPOS_SUPPORT==1: Enable PPP Over Serial
+ */
+#ifndef PPPOS_SUPPORT
+#define PPPOS_SUPPORT                   PPP_SUPPORT
+#endif
+
+/**
+ * LWIP_PPP_API==1: Enable PPP API (in pppapi.c)
+ */
+#ifndef LWIP_PPP_API
+#define LWIP_PPP_API                    (PPP_SUPPORT && (NO_SYS == 0))
+#endif
+
+#if PPP_SUPPORT
+
+/**
+ * MEMP_NUM_PPP_PCB: the number of simultaneously active PPP
+ * connections (requires the PPP_SUPPORT option)
+ */
+#ifndef MEMP_NUM_PPP_PCB
+#define MEMP_NUM_PPP_PCB                1
+#endif
+
+/**
+ * PPP_NUM_TIMEOUTS_PER_PCB: the number of sys_timeouts running in parallel per
+ * ppp_pcb. See the detailed explanation at the end of ppp_impl.h about simultaneous
+ * timers analysis.
+ */
+#ifndef PPP_NUM_TIMEOUTS_PER_PCB
+#define PPP_NUM_TIMEOUTS_PER_PCB        (1 + PPP_IPV4_SUPPORT + PPP_IPV6_SUPPORT + CCP_SUPPORT)
+#endif
+
+/* The number of sys_timeouts required for the PPP module */
+#define PPP_NUM_TIMEOUTS                (PPP_SUPPORT * PPP_NUM_TIMEOUTS_PER_PCB * MEMP_NUM_PPP_PCB)
+
+/**
+ * MEMP_NUM_PPPOS_INTERFACES: the number of concurrently active PPPoS
+ * interfaces (only used with PPPOS_SUPPORT==1)
+ */
+#ifndef MEMP_NUM_PPPOS_INTERFACES
+#define MEMP_NUM_PPPOS_INTERFACES       MEMP_NUM_PPP_PCB
+#endif
+
+/**
+ * MEMP_NUM_PPPOE_INTERFACES: the number of concurrently active PPPoE
+ * interfaces (only used with PPPOE_SUPPORT==1)
+ */
+#ifndef MEMP_NUM_PPPOE_INTERFACES
+#define MEMP_NUM_PPPOE_INTERFACES       1
+#endif
+
+/**
+ * MEMP_NUM_PPPOL2TP_INTERFACES: the number of concurrently active PPPoL2TP
+ * interfaces (only used with PPPOL2TP_SUPPORT==1)
+ */
+#ifndef MEMP_NUM_PPPOL2TP_INTERFACES
+#define MEMP_NUM_PPPOL2TP_INTERFACES       1
+#endif
+
+/**
+ * MEMP_NUM_PPP_API_MSG: Number of concurrent PPP API messages (in pppapi.c)
+ */
+#ifndef MEMP_NUM_PPP_API_MSG
+#define MEMP_NUM_PPP_API_MSG 5
+#endif
+
+/**
+ * PPP_DEBUG: Enable debugging for PPP.
+ */
+#ifndef PPP_DEBUG
+#define PPP_DEBUG                       LWIP_DBG_OFF
+#endif
+
+/**
+ * PPP_INPROC_IRQ_SAFE==1 call pppos_input() using tcpip_callback().
+ *
+ * Please read the "PPPoS input path" chapter in the PPP documentation about this option.
+ */
+#ifndef PPP_INPROC_IRQ_SAFE
+#define PPP_INPROC_IRQ_SAFE             0
+#endif
+
+/**
+ * PRINTPKT_SUPPORT==1: Enable PPP print packet support
+ *
+ * Mandatory for debugging, it displays exchanged packet content in debug trace.
+ */
+#ifndef PRINTPKT_SUPPORT
+#define PRINTPKT_SUPPORT                0
+#endif
+
+/**
+ * PPP_IPV4_SUPPORT==1: Enable PPP IPv4 support
+ */
+#ifndef PPP_IPV4_SUPPORT
+#define PPP_IPV4_SUPPORT                (LWIP_IPV4)
+#endif
+
+/**
+ * PPP_IPV6_SUPPORT==1: Enable PPP IPv6 support
+ */
+#ifndef PPP_IPV6_SUPPORT
+#define PPP_IPV6_SUPPORT                (LWIP_IPV6)
+#endif
+
+/**
+ * PPP_NOTIFY_PHASE==1: Support PPP notify phase support
+ *
+ * PPP notify phase support allows you to set a callback which is
+ * called on change of the internal PPP state machine.
+ *
+ * This can be used for example to set a LED pattern depending on the
+ * current phase of the PPP session.
+ */
+#ifndef PPP_NOTIFY_PHASE
+#define PPP_NOTIFY_PHASE                0
+#endif
+
+/**
+ * pbuf_type PPP is using for LCP, PAP, CHAP, EAP, CCP, IPCP and IP6CP packets.
+ *
+ * Memory allocated must be single buffered for PPP to works, it requires pbuf
+ * that are not going to be chained when allocated. This requires setting
+ * PBUF_POOL_BUFSIZE to at least 512 bytes, which is quite huge for small systems.
+ *
+ * Setting PPP_USE_PBUF_RAM to 1 makes PPP use memory from heap where continuous
+ * buffers are required, allowing you to use a smaller PBUF_POOL_BUFSIZE.
+ */
+#ifndef PPP_USE_PBUF_RAM
+#define PPP_USE_PBUF_RAM                0
+#endif
+
+/**
+ * PPP_FCS_TABLE: Keep a 256*2 byte table to speed up FCS calculation for PPPoS
+ */
+#ifndef PPP_FCS_TABLE
+#define PPP_FCS_TABLE                   1
+#endif
+
+/**
+ * PAP_SUPPORT==1: Support PAP.
+ */
+#ifndef PAP_SUPPORT
+#define PAP_SUPPORT                     0
+#endif
+
+/**
+ * CHAP_SUPPORT==1: Support CHAP.
+ */
+#ifndef CHAP_SUPPORT
+#define CHAP_SUPPORT                    0
+#endif
+
+/**
+ * MSCHAP_SUPPORT==1: Support MSCHAP.
+ */
+#ifndef MSCHAP_SUPPORT
+#define MSCHAP_SUPPORT                  0
+#endif
+#if MSCHAP_SUPPORT
+/* MSCHAP requires CHAP support */
+#undef CHAP_SUPPORT
+#define CHAP_SUPPORT                    1
+#endif /* MSCHAP_SUPPORT */
+
+/**
+ * EAP_SUPPORT==1: Support EAP.
+ */
+#ifndef EAP_SUPPORT
+#define EAP_SUPPORT                     0
+#endif
+
+/**
+ * CCP_SUPPORT==1: Support CCP.
+ */
+#ifndef CCP_SUPPORT
+#define CCP_SUPPORT                     0
+#endif
+
+/**
+ * MPPE_SUPPORT==1: Support MPPE.
+ */
+#ifndef MPPE_SUPPORT
+#define MPPE_SUPPORT                    0
+#endif
+#if MPPE_SUPPORT
+/* MPPE requires CCP support */
+#undef CCP_SUPPORT
+#define CCP_SUPPORT                     1
+/* MPPE requires MSCHAP support */
+#undef MSCHAP_SUPPORT
+#define MSCHAP_SUPPORT                  1
+/* MSCHAP requires CHAP support */
+#undef CHAP_SUPPORT
+#define CHAP_SUPPORT                    1
+#endif /* MPPE_SUPPORT */
+
+/**
+ * CBCP_SUPPORT==1: Support CBCP. CURRENTLY NOT SUPPORTED! DO NOT SET!
+ */
+#ifndef CBCP_SUPPORT
+#define CBCP_SUPPORT                    0
+#endif
+
+/**
+ * ECP_SUPPORT==1: Support ECP. CURRENTLY NOT SUPPORTED! DO NOT SET!
+ */
+#ifndef ECP_SUPPORT
+#define ECP_SUPPORT                     0
+#endif
+
+/**
+ * DEMAND_SUPPORT==1: Support dial on demand. CURRENTLY NOT SUPPORTED! DO NOT SET!
+ */
+#ifndef DEMAND_SUPPORT
+#define DEMAND_SUPPORT                  0
+#endif
+
+/**
+ * LQR_SUPPORT==1: Support Link Quality Report. Do nothing except exchanging some LCP packets.
+ */
+#ifndef LQR_SUPPORT
+#define LQR_SUPPORT                     0
+#endif
+
+/**
+ * PPP_SERVER==1: Enable PPP server support (waiting for incoming PPP session).
+ *
+ * Currently only supported for PPPoS.
+ */
+#ifndef PPP_SERVER
+#define PPP_SERVER                      0
+#endif
+
+#if PPP_SERVER
+/*
+ * PPP_OUR_NAME: Our name for authentication purposes
+ */
+#ifndef PPP_OUR_NAME
+#define PPP_OUR_NAME                    "lwIP"
+#endif
+#endif /* PPP_SERVER */
+
+/**
+ * VJ_SUPPORT==1: Support VJ header compression.
+ */
+#ifndef VJ_SUPPORT
+#define VJ_SUPPORT                      1
+#endif
+/* VJ compression is only supported for TCP over IPv4 over PPPoS. */
+#if !PPPOS_SUPPORT || !PPP_IPV4_SUPPORT || !LWIP_TCP
+#undef VJ_SUPPORT
+#define VJ_SUPPORT                      0
+#endif /* !PPPOS_SUPPORT */
+
+/**
+ * PPP_MD5_RANDM==1: Use MD5 for better randomness.
+ * Enabled by default if CHAP, EAP, or L2TP AUTH support is enabled.
+ */
+#ifndef PPP_MD5_RANDM
+#define PPP_MD5_RANDM                   (CHAP_SUPPORT || EAP_SUPPORT || PPPOL2TP_AUTH_SUPPORT)
+#endif
+
+/**
+ * PolarSSL embedded library
+ *
+ *
+ * lwIP contains some files fetched from the latest BSD release of
+ * the PolarSSL project (PolarSSL 0.10.1-bsd) for ciphers and encryption
+ * methods we need for lwIP PPP support.
+ *
+ * The PolarSSL files were cleaned to contain only the necessary struct
+ * fields and functions needed for lwIP.
+ *
+ * The PolarSSL API was not changed at all, so if you are already using
+ * PolarSSL you can choose to skip the compilation of the included PolarSSL
+ * library into lwIP.
+ *
+ * If you are not using the embedded copy you must include external
+ * libraries into your arch/cc.h port file.
+ *
+ * Beware of the stack requirements which can be a lot larger if you are not
+ * using our cleaned PolarSSL library.
+ */
+
+/**
+ * LWIP_USE_EXTERNAL_POLARSSL: Use external PolarSSL library
+ */
+#ifndef LWIP_USE_EXTERNAL_POLARSSL
+#define LWIP_USE_EXTERNAL_POLARSSL      0
+#endif
+
+/**
+ * LWIP_USE_EXTERNAL_MBEDTLS: Use external mbed TLS library
+ */
+#ifndef LWIP_USE_EXTERNAL_MBEDTLS
+#define LWIP_USE_EXTERNAL_MBEDTLS       0
+#endif
+
+/*
+ * PPP Timeouts
+ */
+
+/**
+ * FSM_DEFTIMEOUT: Timeout time in seconds
+ */
+#ifndef FSM_DEFTIMEOUT
+#define FSM_DEFTIMEOUT                  6
+#endif
+
+/**
+ * FSM_DEFMAXTERMREQS: Maximum Terminate-Request transmissions
+ */
+#ifndef FSM_DEFMAXTERMREQS
+#define FSM_DEFMAXTERMREQS              2
+#endif
+
+/**
+ * FSM_DEFMAXCONFREQS: Maximum Configure-Request transmissions
+ */
+#ifndef FSM_DEFMAXCONFREQS
+#define FSM_DEFMAXCONFREQS              10
+#endif
+
+/**
+ * FSM_DEFMAXNAKLOOPS: Maximum number of nak loops
+ */
+#ifndef FSM_DEFMAXNAKLOOPS
+#define FSM_DEFMAXNAKLOOPS              5
+#endif
+
+/**
+ * UPAP_DEFTIMEOUT: Timeout (seconds) for retransmitting req
+ */
+#ifndef UPAP_DEFTIMEOUT
+#define UPAP_DEFTIMEOUT                 6
+#endif
+
+/**
+ * UPAP_DEFTRANSMITS: Maximum number of auth-reqs to send
+ */
+#ifndef UPAP_DEFTRANSMITS
+#define UPAP_DEFTRANSMITS               10
+#endif
+
+#if PPP_SERVER
+/**
+ * UPAP_DEFREQTIME: Time to wait for auth-req from peer
+ */
+#ifndef UPAP_DEFREQTIME
+#define UPAP_DEFREQTIME                 30
+#endif
+#endif /* PPP_SERVER */
+
+/**
+ * CHAP_DEFTIMEOUT: Timeout (seconds) for retransmitting req
+ */
+#ifndef CHAP_DEFTIMEOUT
+#define CHAP_DEFTIMEOUT                 6
+#endif
+
+/**
+ * CHAP_DEFTRANSMITS: max # times to send challenge
+ */
+#ifndef CHAP_DEFTRANSMITS
+#define CHAP_DEFTRANSMITS               10
+#endif
+
+#if PPP_SERVER
+/**
+ * CHAP_DEFRECHALLENGETIME: If this option is > 0, rechallenge the peer every n seconds
+ */
+#ifndef CHAP_DEFRECHALLENGETIME
+#define CHAP_DEFRECHALLENGETIME         0
+#endif
+#endif /* PPP_SERVER */
+
+/**
+ * EAP_DEFREQTIME: Time to wait for peer request
+ */
+#ifndef EAP_DEFREQTIME
+#define EAP_DEFREQTIME                  6
+#endif
+
+/**
+ * EAP_DEFALLOWREQ: max # times to accept requests
+ */
+#ifndef EAP_DEFALLOWREQ
+#define EAP_DEFALLOWREQ                 10
+#endif
+
+#if PPP_SERVER
+/**
+ * EAP_DEFTIMEOUT: Timeout (seconds) for rexmit
+ */
+#ifndef EAP_DEFTIMEOUT
+#define EAP_DEFTIMEOUT                  6
+#endif
+
+/**
+ * EAP_DEFTRANSMITS: max # times to transmit
+ */
+#ifndef EAP_DEFTRANSMITS
+#define EAP_DEFTRANSMITS                10
+#endif
+#endif /* PPP_SERVER */
+
+/**
+ * LCP_DEFLOOPBACKFAIL: Default number of times we receive our magic number from the peer
+ * before deciding the link is looped-back.
+ */
+#ifndef LCP_DEFLOOPBACKFAIL
+#define LCP_DEFLOOPBACKFAIL             10
+#endif
+
+/**
+ * LCP_ECHOINTERVAL: Interval in seconds between keepalive echo requests, 0 to disable.
+ */
+#ifndef LCP_ECHOINTERVAL
+#define LCP_ECHOINTERVAL                0
+#endif
+
+/**
+ * LCP_MAXECHOFAILS: Number of unanswered echo requests before failure.
+ */
+#ifndef LCP_MAXECHOFAILS
+#define LCP_MAXECHOFAILS                3
+#endif
+
+/**
+ * PPP_MAXIDLEFLAG: Max Xmit idle time (in ms) before resend flag char.
+ */
+#ifndef PPP_MAXIDLEFLAG
+#define PPP_MAXIDLEFLAG                 100
+#endif
+
+/**
+ * PPP Packet sizes
+ */
+
+/**
+ * PPP_MRU: Default MRU
+ */
+#ifndef PPP_MRU
+#define PPP_MRU                         1500
+#endif
+
+/**
+ * PPP_DEFMRU: Default MRU to try
+ */
+#ifndef PPP_DEFMRU
+#define PPP_DEFMRU                      1500
+#endif
+
+/**
+ * PPP_MAXMRU: Normally limit MRU to this (pppd default = 16384)
+ */
+#ifndef PPP_MAXMRU
+#define PPP_MAXMRU                      1500
+#endif
+
+/**
+ * PPP_MINMRU: No MRUs below this
+ */
+#ifndef PPP_MINMRU
+#define PPP_MINMRU                      128
+#endif
+
+/**
+ * PPPOL2TP_DEFMRU: Default MTU and MRU for L2TP
+ * Default = 1500 - PPPoE(6) - PPP Protocol(2) - IPv4 header(20) - UDP Header(8)
+ * - L2TP Header(6) - HDLC Header(2) - PPP Protocol(2) - MPPE Header(2) - PPP Protocol(2)
+ */
+#if PPPOL2TP_SUPPORT
+#ifndef PPPOL2TP_DEFMRU
+#define PPPOL2TP_DEFMRU                 1450
+#endif
+#endif /* PPPOL2TP_SUPPORT */
+
+/**
+ * MAXNAMELEN: max length of hostname or name for auth
+ */
+#ifndef MAXNAMELEN
+#define MAXNAMELEN                      256
+#endif
+
+/**
+ * MAXSECRETLEN: max length of password or secret
+ */
+#ifndef MAXSECRETLEN
+#define MAXSECRETLEN                    256
+#endif
+
+/* ------------------------------------------------------------------------- */
+
+/*
+ * Build triggers for embedded PolarSSL
+ */
+#if !LWIP_USE_EXTERNAL_POLARSSL && !LWIP_USE_EXTERNAL_MBEDTLS
+
+/* CHAP, EAP, L2TP AUTH and MD5 Random require MD5 support */
+#if CHAP_SUPPORT || EAP_SUPPORT || PPPOL2TP_AUTH_SUPPORT || PPP_MD5_RANDM
+#define LWIP_INCLUDED_POLARSSL_MD5      1
+#endif /* CHAP_SUPPORT || EAP_SUPPORT || PPPOL2TP_AUTH_SUPPORT || PPP_MD5_RANDM */
+
+#if MSCHAP_SUPPORT
+
+/* MSCHAP require MD4 support */
+#define LWIP_INCLUDED_POLARSSL_MD4      1
+/* MSCHAP require SHA1 support */
+#define LWIP_INCLUDED_POLARSSL_SHA1     1
+/* MSCHAP require DES support */
+#define LWIP_INCLUDED_POLARSSL_DES      1
+
+/* MS-CHAP support is required for MPPE */
+#if MPPE_SUPPORT
+/* MPPE require ARC4 support */
+#define LWIP_INCLUDED_POLARSSL_ARC4     1
+#endif /* MPPE_SUPPORT */
+
+#endif /* MSCHAP_SUPPORT */
+
+#endif /* !LWIP_USE_EXTERNAL_POLARSSL && !LWIP_USE_EXTERNAL_MBEDTLS */
+
+/* Default value if unset */
+#ifndef LWIP_INCLUDED_POLARSSL_MD4
+#define LWIP_INCLUDED_POLARSSL_MD4      0
+#endif /* LWIP_INCLUDED_POLARSSL_MD4 */
+#ifndef LWIP_INCLUDED_POLARSSL_MD5
+#define LWIP_INCLUDED_POLARSSL_MD5      0
+#endif /* LWIP_INCLUDED_POLARSSL_MD5 */
+#ifndef LWIP_INCLUDED_POLARSSL_SHA1
+#define LWIP_INCLUDED_POLARSSL_SHA1     0
+#endif /* LWIP_INCLUDED_POLARSSL_SHA1 */
+#ifndef LWIP_INCLUDED_POLARSSL_DES
+#define LWIP_INCLUDED_POLARSSL_DES      0
+#endif /* LWIP_INCLUDED_POLARSSL_DES */
+#ifndef LWIP_INCLUDED_POLARSSL_ARC4
+#define LWIP_INCLUDED_POLARSSL_ARC4     0
+#endif /* LWIP_INCLUDED_POLARSSL_ARC4 */
+
+#endif /* PPP_SUPPORT */
+
+/* Default value if unset */
+#ifndef PPP_NUM_TIMEOUTS
+#define PPP_NUM_TIMEOUTS                0
+#endif /* PPP_NUM_TIMEOUTS */
+
+#endif /* LWIP_PPP_OPTS_H */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/netif/ppp/pppapi.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/netif/ppp/pppapi.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/netif/ppp/pppapi.h	(revision 457)
@@ -0,0 +1,137 @@
+/*
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ */
+
+#ifndef LWIP_PPPAPI_H
+#define LWIP_PPPAPI_H
+
+#include "netif/ppp/ppp_opts.h"
+
+#if LWIP_PPP_API /* don't build if not configured for use in lwipopts.h */
+
+#include "lwip/sys.h"
+#include "lwip/netif.h"
+#include "lwip/priv/tcpip_priv.h"
+#include "netif/ppp/ppp.h"
+#if PPPOS_SUPPORT
+#include "netif/ppp/pppos.h"
+#endif /* PPPOS_SUPPORT */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct pppapi_msg_msg {
+  ppp_pcb *ppp;
+  union {
+#if PPP_NOTIFY_PHASE
+    struct {
+      ppp_notify_phase_cb_fn notify_phase_cb;
+    } setnotifyphasecb;
+#endif /* PPP_NOTIFY_PHASE */
+#if PPPOS_SUPPORT
+    struct {
+      struct netif *pppif;
+      pppos_output_cb_fn output_cb;
+      ppp_link_status_cb_fn link_status_cb;
+      void *ctx_cb;
+    } serialcreate;
+#endif /* PPPOS_SUPPORT */
+#if PPPOE_SUPPORT
+    struct {
+      struct netif *pppif;
+      struct netif *ethif;
+      const char *service_name;
+      const char *concentrator_name;
+      ppp_link_status_cb_fn link_status_cb;
+      void *ctx_cb;
+    } ethernetcreate;
+#endif /* PPPOE_SUPPORT */
+#if PPPOL2TP_SUPPORT
+    struct {
+      struct netif *pppif;
+      struct netif *netif;
+      API_MSG_M_DEF_C(ip_addr_t, ipaddr);
+      u16_t port;
+#if PPPOL2TP_AUTH_SUPPORT
+      const u8_t *secret;
+      u8_t secret_len;
+#endif /* PPPOL2TP_AUTH_SUPPORT */
+      ppp_link_status_cb_fn link_status_cb;
+      void *ctx_cb;
+    } l2tpcreate;
+#endif /* PPPOL2TP_SUPPORT */
+    struct {
+      u16_t holdoff;
+    } connect;
+    struct {
+      u8_t nocarrier;
+    } close;
+    struct {
+      u8_t cmd;
+      void *arg;
+    } ioctl;
+  } msg;
+};
+
+struct pppapi_msg {
+  struct tcpip_api_call_data call;
+  struct pppapi_msg_msg msg;
+};
+
+/* API for application */
+err_t pppapi_set_default(ppp_pcb *pcb);
+#if PPP_NOTIFY_PHASE
+err_t pppapi_set_notify_phase_callback(ppp_pcb *pcb, ppp_notify_phase_cb_fn notify_phase_cb);
+#endif /* PPP_NOTIFY_PHASE */
+#if PPPOS_SUPPORT
+ppp_pcb *pppapi_pppos_create(struct netif *pppif, pppos_output_cb_fn output_cb, ppp_link_status_cb_fn link_status_cb, void *ctx_cb);
+#endif /* PPPOS_SUPPORT */
+#if PPPOE_SUPPORT
+ppp_pcb *pppapi_pppoe_create(struct netif *pppif, struct netif *ethif, const char *service_name,
+                                const char *concentrator_name, ppp_link_status_cb_fn link_status_cb,
+                                void *ctx_cb);
+#endif /* PPPOE_SUPPORT */
+#if PPPOL2TP_SUPPORT
+ppp_pcb *pppapi_pppol2tp_create(struct netif *pppif, struct netif *netif, ip_addr_t *ipaddr, u16_t port,
+                            const u8_t *secret, u8_t secret_len,
+                            ppp_link_status_cb_fn link_status_cb, void *ctx_cb);
+#endif /* PPPOL2TP_SUPPORT */
+err_t pppapi_connect(ppp_pcb *pcb, u16_t holdoff);
+#if PPP_SERVER
+err_t pppapi_listen(ppp_pcb *pcb);
+#endif /* PPP_SERVER */
+err_t pppapi_close(ppp_pcb *pcb, u8_t nocarrier);
+err_t pppapi_free(ppp_pcb *pcb);
+err_t pppapi_ioctl(ppp_pcb *pcb, u8_t cmd, void *arg);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LWIP_PPP_API */
+
+#endif /* LWIP_PPPAPI_H */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/netif/ppp/pppcrypt.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/netif/ppp/pppcrypt.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/netif/ppp/pppcrypt.h	(revision 457)
@@ -0,0 +1,144 @@
+/*
+ * pppcrypt.c - PPP/DES linkage for MS-CHAP and EAP SRP-SHA1
+ *
+ * Extracted from chap_ms.c by James Carlson.
+ *
+ * Copyright (c) 1995 Eric Rosenquist.  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. The name(s) of the authors of this software must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission.
+ *
+ * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO
+ * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
+ * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
+ * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
+ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include "netif/ppp/ppp_opts.h"
+#if PPP_SUPPORT /* don't build if not configured for use in lwipopts.h */
+
+/* This header file is included in all PPP modules needing hashes and/or ciphers */
+
+#ifndef PPPCRYPT_H
+#define	PPPCRYPT_H
+
+/*
+ * If included PolarSSL copy is not used, user is expected to include
+ * external libraries in arch/cc.h (which is included by lwip/arch.h).
+ */
+#include "lwip/arch.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * Map hashes and ciphers functions to PolarSSL
+ */
+#if !LWIP_USE_EXTERNAL_MBEDTLS
+
+#include "netif/ppp/polarssl/md4.h"
+#define lwip_md4_context md4_context
+#define lwip_md4_init(context)
+#define lwip_md4_starts md4_starts
+#define lwip_md4_update md4_update
+#define lwip_md4_finish md4_finish
+#define lwip_md4_free(context)
+
+#include "netif/ppp/polarssl/md5.h"
+#define lwip_md5_context md5_context
+#define lwip_md5_init(context)
+#define lwip_md5_starts md5_starts
+#define lwip_md5_update md5_update
+#define lwip_md5_finish md5_finish
+#define lwip_md5_free(context)
+
+#include "netif/ppp/polarssl/sha1.h"
+#define lwip_sha1_context sha1_context
+#define lwip_sha1_init(context)
+#define lwip_sha1_starts sha1_starts
+#define lwip_sha1_update sha1_update
+#define lwip_sha1_finish sha1_finish
+#define lwip_sha1_free(context)
+
+#include "netif/ppp/polarssl/des.h"
+#define lwip_des_context des_context
+#define lwip_des_init(context)
+#define lwip_des_setkey_enc des_setkey_enc
+#define lwip_des_crypt_ecb des_crypt_ecb
+#define lwip_des_free(context)
+
+#include "netif/ppp/polarssl/arc4.h"
+#define lwip_arc4_context arc4_context
+#define lwip_arc4_init(context)
+#define lwip_arc4_setup arc4_setup
+#define lwip_arc4_crypt arc4_crypt
+#define lwip_arc4_free(context)
+
+#endif /* !LWIP_USE_EXTERNAL_MBEDTLS */
+
+/*
+ * Map hashes and ciphers functions to mbed TLS
+ */
+#if LWIP_USE_EXTERNAL_MBEDTLS
+
+#define lwip_md4_context mbedtls_md4_context
+#define lwip_md4_init mbedtls_md4_init
+#define lwip_md4_starts mbedtls_md4_starts
+#define lwip_md4_update mbedtls_md4_update
+#define lwip_md4_finish mbedtls_md4_finish
+#define lwip_md4_free mbedtls_md4_free
+
+#define lwip_md5_context mbedtls_md5_context
+#define lwip_md5_init mbedtls_md5_init
+#define lwip_md5_starts mbedtls_md5_starts
+#define lwip_md5_update mbedtls_md5_update
+#define lwip_md5_finish mbedtls_md5_finish
+#define lwip_md5_free mbedtls_md5_free
+
+#define lwip_sha1_context mbedtls_sha1_context
+#define lwip_sha1_init mbedtls_sha1_init
+#define lwip_sha1_starts mbedtls_sha1_starts
+#define lwip_sha1_update mbedtls_sha1_update
+#define lwip_sha1_finish mbedtls_sha1_finish
+#define lwip_sha1_free mbedtls_sha1_free
+
+#define lwip_des_context mbedtls_des_context
+#define lwip_des_init mbedtls_des_init
+#define lwip_des_setkey_enc mbedtls_des_setkey_enc
+#define lwip_des_crypt_ecb mbedtls_des_crypt_ecb
+#define lwip_des_free mbedtls_des_free
+
+#define lwip_arc4_context mbedtls_arc4_context
+#define lwip_arc4_init mbedtls_arc4_init
+#define lwip_arc4_setup mbedtls_arc4_setup
+#define lwip_arc4_crypt(context, buffer, length) mbedtls_arc4_crypt(context, length, buffer, buffer)
+#define lwip_arc4_free mbedtls_arc4_free
+
+#endif /* LWIP_USE_EXTERNAL_MBEDTLS */
+
+void pppcrypt_56_to_64_bit_key(u_char *key, u_char *des_key);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* PPPCRYPT_H */
+
+#endif /* PPP_SUPPORT */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/netif/ppp/pppdebug.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/netif/ppp/pppdebug.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/netif/ppp/pppdebug.h	(revision 457)
@@ -0,0 +1,88 @@
+/*****************************************************************************
+* pppdebug.h - System debugging utilities.
+*
+* Copyright (c) 2003 by Marc Boucher, Services Informatiques (MBSI) inc.
+* portions Copyright (c) 1998 Global Election Systems Inc.
+* portions Copyright (c) 2001 by Cognizant Pty Ltd.
+*
+* The authors hereby grant permission to use, copy, modify, distribute,
+* and license this software and its documentation for any purpose, provided
+* that existing copyright notices are retained in all copies and that this
+* notice and the following disclaimer are included verbatim in any 
+* distributions. No written agreement, license, or royalty fee is required
+* for any of the authorized uses.
+*
+* THIS SOFTWARE IS PROVIDED BY THE 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 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.
+*
+******************************************************************************
+* REVISION HISTORY (please don't use tabs!)
+*
+* 03-01-01 Marc Boucher <marc@mbsi.ca>
+*   Ported to lwIP.
+* 98-07-29 Guy Lancaster <lancasterg@acm.org>, Global Election Systems Inc.
+*   Original.
+*
+*****************************************************************************
+*/
+
+#include "netif/ppp/ppp_opts.h"
+#if PPP_SUPPORT /* don't build if not configured for use in lwipopts.h */
+
+#ifndef PPPDEBUG_H
+#define PPPDEBUG_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Trace levels. */
+#define LOG_CRITICAL  (PPP_DEBUG | LWIP_DBG_LEVEL_SEVERE)
+#define LOG_ERR       (PPP_DEBUG | LWIP_DBG_LEVEL_SEVERE)
+#define LOG_NOTICE    (PPP_DEBUG | LWIP_DBG_LEVEL_WARNING)
+#define LOG_WARNING   (PPP_DEBUG | LWIP_DBG_LEVEL_WARNING)
+#define LOG_INFO      (PPP_DEBUG)
+#define LOG_DETAIL    (PPP_DEBUG)
+#define LOG_DEBUG     (PPP_DEBUG)
+
+#if PPP_DEBUG
+
+#define MAINDEBUG(a)    LWIP_DEBUGF(LWIP_DBG_LEVEL_WARNING, a)
+#define SYSDEBUG(a)     LWIP_DEBUGF(LWIP_DBG_LEVEL_WARNING, a)
+#define FSMDEBUG(a)     LWIP_DEBUGF(LWIP_DBG_LEVEL_WARNING, a)
+#define LCPDEBUG(a)     LWIP_DEBUGF(LWIP_DBG_LEVEL_WARNING, a)
+#define IPCPDEBUG(a)    LWIP_DEBUGF(LWIP_DBG_LEVEL_WARNING, a)
+#define IPV6CPDEBUG(a)  LWIP_DEBUGF(LWIP_DBG_LEVEL_WARNING, a)
+#define UPAPDEBUG(a)    LWIP_DEBUGF(LWIP_DBG_LEVEL_WARNING, a)
+#define CHAPDEBUG(a)    LWIP_DEBUGF(LWIP_DBG_LEVEL_WARNING, a)
+#define PPPDEBUG(a, b)  LWIP_DEBUGF(a, b)
+
+#else /* PPP_DEBUG */
+
+#define MAINDEBUG(a)
+#define SYSDEBUG(a)
+#define FSMDEBUG(a)
+#define LCPDEBUG(a)
+#define IPCPDEBUG(a)
+#define IPV6CPDEBUG(a)
+#define UPAPDEBUG(a)
+#define CHAPDEBUG(a)
+#define PPPDEBUG(a, b)
+
+#endif /* PPP_DEBUG */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* PPPDEBUG_H */
+
+#endif /* PPP_SUPPORT */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/netif/ppp/pppoe.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/netif/ppp/pppoe.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/netif/ppp/pppoe.h	(revision 457)
@@ -0,0 +1,187 @@
+/*****************************************************************************
+* pppoe.h - PPP Over Ethernet implementation for lwIP.
+*
+* Copyright (c) 2006 by Marc Boucher, Services Informatiques (MBSI) inc.
+*
+* The authors hereby grant permission to use, copy, modify, distribute,
+* and license this software and its documentation for any purpose, provided
+* that existing copyright notices are retained in all copies and that this
+* notice and the following disclaimer are included verbatim in any 
+* distributions. No written agreement, license, or royalty fee is required
+* for any of the authorized uses.
+*
+* THIS SOFTWARE IS PROVIDED BY THE 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 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.
+*
+******************************************************************************
+* REVISION HISTORY
+*
+* 06-01-01 Marc Boucher <marc@mbsi.ca>
+*   Ported to lwIP.
+*****************************************************************************/
+
+
+
+/* based on NetBSD: if_pppoe.c,v 1.64 2006/01/31 23:50:15 martin Exp */
+
+/*-
+ * Copyright (c) 2002 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Martin Husemann <martin@NetBSD.org>.
+ *
+ * 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. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *        This product includes software developed by the NetBSD
+ *        Foundation, Inc. and its contributors.
+ * 4. Neither the name of The NetBSD Foundation 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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 "netif/ppp/ppp_opts.h"
+#if PPP_SUPPORT && PPPOE_SUPPORT /* don't build if not configured for use in lwipopts.h */
+
+#ifndef PPP_OE_H
+#define PPP_OE_H
+
+#include "ppp.h"
+#include "lwip/etharp.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef PACK_STRUCT_USE_INCLUDES
+#  include "arch/bpstruct.h"
+#endif
+PACK_STRUCT_BEGIN
+struct pppoehdr {
+  PACK_STRUCT_FLD_8(u8_t vertype);
+  PACK_STRUCT_FLD_8(u8_t code);
+  PACK_STRUCT_FIELD(u16_t session);
+  PACK_STRUCT_FIELD(u16_t plen);
+} PACK_STRUCT_STRUCT;
+PACK_STRUCT_END
+#ifdef PACK_STRUCT_USE_INCLUDES
+#  include "arch/epstruct.h"
+#endif
+
+#ifdef PACK_STRUCT_USE_INCLUDES
+#  include "arch/bpstruct.h"
+#endif
+PACK_STRUCT_BEGIN
+struct pppoetag {
+  PACK_STRUCT_FIELD(u16_t tag);
+  PACK_STRUCT_FIELD(u16_t len);
+} PACK_STRUCT_STRUCT;
+PACK_STRUCT_END
+#ifdef PACK_STRUCT_USE_INCLUDES
+#  include "arch/epstruct.h"
+#endif
+
+
+#define PPPOE_STATE_INITIAL   0
+#define PPPOE_STATE_PADI_SENT 1
+#define PPPOE_STATE_PADR_SENT 2
+#define PPPOE_STATE_SESSION   3
+/* passive */
+#define PPPOE_STATE_PADO_SENT 1
+
+#define PPPOE_HEADERLEN       sizeof(struct pppoehdr)
+#define PPPOE_VERTYPE         0x11    /* VER=1, TYPE = 1 */
+
+#define PPPOE_TAG_EOL         0x0000  /* end of list */
+#define PPPOE_TAG_SNAME       0x0101  /* service name */
+#define PPPOE_TAG_ACNAME      0x0102  /* access concentrator name */
+#define PPPOE_TAG_HUNIQUE     0x0103  /* host unique */
+#define PPPOE_TAG_ACCOOKIE    0x0104  /* AC cookie */
+#define PPPOE_TAG_VENDOR      0x0105  /* vendor specific */
+#define PPPOE_TAG_RELAYSID    0x0110  /* relay session id */
+#define PPPOE_TAG_SNAME_ERR   0x0201  /* service name error */
+#define PPPOE_TAG_ACSYS_ERR   0x0202  /* AC system error */
+#define PPPOE_TAG_GENERIC_ERR 0x0203  /* gerneric error */
+
+#define PPPOE_CODE_PADI       0x09    /* Active Discovery Initiation */
+#define PPPOE_CODE_PADO       0x07    /* Active Discovery Offer */
+#define PPPOE_CODE_PADR       0x19    /* Active Discovery Request */
+#define PPPOE_CODE_PADS       0x65    /* Active Discovery Session confirmation */
+#define PPPOE_CODE_PADT       0xA7    /* Active Discovery Terminate */
+
+#ifndef PPPOE_MAX_AC_COOKIE_LEN
+#define PPPOE_MAX_AC_COOKIE_LEN   64
+#endif
+
+struct pppoe_softc {
+  struct pppoe_softc *next;
+  struct netif *sc_ethif;      /* ethernet interface we are using */
+  ppp_pcb *pcb;                /* PPP PCB */
+
+  struct eth_addr sc_dest;     /* hardware address of concentrator */
+  u16_t sc_session;            /* PPPoE session id */
+  u8_t sc_state;               /* discovery phase or session connected */
+
+#ifdef PPPOE_TODO
+  u8_t *sc_service_name;       /* if != NULL: requested name of service */
+  u8_t *sc_concentrator_name;  /* if != NULL: requested concentrator id */
+#endif /* PPPOE_TODO */
+  u8_t sc_ac_cookie[PPPOE_MAX_AC_COOKIE_LEN]; /* content of AC cookie we must echo back */
+  u8_t sc_ac_cookie_len;       /* length of cookie data */
+#ifdef PPPOE_SERVER
+  u8_t *sc_hunique;            /* content of host unique we must echo back */
+  u8_t sc_hunique_len;         /* length of host unique */
+#endif
+  u8_t sc_padi_retried;        /* number of PADI retries already done */
+  u8_t sc_padr_retried;        /* number of PADR retries already done */
+};
+
+
+#define pppoe_init() /* compatibility define, no initialization needed */
+
+ppp_pcb *pppoe_create(struct netif *pppif,
+       struct netif *ethif,
+       const char *service_name, const char *concentrator_name,
+       ppp_link_status_cb_fn link_status_cb, void *ctx_cb);
+
+/*
+ * Functions called from lwIP
+ * DO NOT CALL FROM lwIP USER APPLICATION.
+ */
+void pppoe_disc_input(struct netif *netif, struct pbuf *p);
+void pppoe_data_input(struct netif *netif, struct pbuf *p);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* PPP_OE_H */
+
+#endif /* PPP_SUPPORT && PPPOE_SUPPORT */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/netif/ppp/pppol2tp.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/netif/ppp/pppol2tp.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/netif/ppp/pppol2tp.h	(revision 457)
@@ -0,0 +1,209 @@
+/**
+ * @file
+ * Network Point to Point Protocol over Layer 2 Tunneling Protocol header file.
+ *
+ */
+
+/*
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ */
+
+#include "netif/ppp/ppp_opts.h"
+#if PPP_SUPPORT && PPPOL2TP_SUPPORT /* don't build if not configured for use in lwipopts.h */
+
+#ifndef PPPOL2TP_H
+#define PPPOL2TP_H
+
+#include "ppp.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Timeout */
+#define PPPOL2TP_CONTROL_TIMEOUT         (5*1000)  /* base for quick timeout calculation */
+#define PPPOL2TP_SLOW_RETRY              (60*1000) /* persistent retry interval */
+
+#define PPPOL2TP_MAXSCCRQ                4         /* retry SCCRQ four times (quickly) */
+#define PPPOL2TP_MAXICRQ                 4         /* retry IRCQ four times */
+#define PPPOL2TP_MAXICCN                 4         /* retry ICCN four times */
+
+/* L2TP header flags */
+#define PPPOL2TP_HEADERFLAG_CONTROL      0x8000
+#define PPPOL2TP_HEADERFLAG_LENGTH       0x4000
+#define PPPOL2TP_HEADERFLAG_SEQUENCE     0x0800
+#define PPPOL2TP_HEADERFLAG_OFFSET       0x0200
+#define PPPOL2TP_HEADERFLAG_PRIORITY     0x0100
+#define PPPOL2TP_HEADERFLAG_VERSION      0x0002
+
+/* Mandatory bits for control: Control, Length, Sequence, Version 2 */
+#define PPPOL2TP_HEADERFLAG_CONTROL_MANDATORY     (PPPOL2TP_HEADERFLAG_CONTROL|PPPOL2TP_HEADERFLAG_LENGTH|PPPOL2TP_HEADERFLAG_SEQUENCE|PPPOL2TP_HEADERFLAG_VERSION)
+/* Forbidden bits for control: Offset, Priority */
+#define PPPOL2TP_HEADERFLAG_CONTROL_FORBIDDEN     (PPPOL2TP_HEADERFLAG_OFFSET|PPPOL2TP_HEADERFLAG_PRIORITY)
+
+/* Mandatory bits for data: Version 2 */
+#define PPPOL2TP_HEADERFLAG_DATA_MANDATORY        (PPPOL2TP_HEADERFLAG_VERSION)
+
+/* AVP (Attribute Value Pair) header */
+#define PPPOL2TP_AVPHEADERFLAG_MANDATORY  0x8000
+#define PPPOL2TP_AVPHEADERFLAG_HIDDEN     0x4000
+#define PPPOL2TP_AVPHEADERFLAG_LENGTHMASK 0x03ff
+
+/* -- AVP - Message type */
+#define PPPOL2TP_AVPTYPE_MESSAGE      0 /* Message type */
+
+/* Control Connection Management */
+#define PPPOL2TP_MESSAGETYPE_SCCRQ    1 /* Start Control Connection Request */
+#define PPPOL2TP_MESSAGETYPE_SCCRP    2 /* Start Control Connection Reply */
+#define PPPOL2TP_MESSAGETYPE_SCCCN    3 /* Start Control Connection Connected */
+#define PPPOL2TP_MESSAGETYPE_STOPCCN  4 /* Stop Control Connection Notification */
+#define PPPOL2TP_MESSAGETYPE_HELLO    6 /* Hello */
+/* Call Management */
+#define PPPOL2TP_MESSAGETYPE_OCRQ     7 /* Outgoing Call Request */
+#define PPPOL2TP_MESSAGETYPE_OCRP     8 /* Outgoing Call Reply */
+#define PPPOL2TP_MESSAGETYPE_OCCN     9 /* Outgoing Call Connected */
+#define PPPOL2TP_MESSAGETYPE_ICRQ    10 /* Incoming Call Request */
+#define PPPOL2TP_MESSAGETYPE_ICRP    11 /* Incoming Call Reply */
+#define PPPOL2TP_MESSAGETYPE_ICCN    12 /* Incoming Call Connected */
+#define PPPOL2TP_MESSAGETYPE_CDN     14 /* Call Disconnect Notify */
+/* Error reporting */
+#define PPPOL2TP_MESSAGETYPE_WEN     15 /* WAN Error Notify */
+/* PPP Session Control */
+#define PPPOL2TP_MESSAGETYPE_SLI     16 /* Set Link Info */
+
+/* -- AVP - Result code */
+#define PPPOL2TP_AVPTYPE_RESULTCODE   1 /* Result code */
+#define PPPOL2TP_RESULTCODE           1 /* General request to clear control connection */
+
+/* -- AVP - Protocol version (!= L2TP Header version) */
+#define PPPOL2TP_AVPTYPE_VERSION      2
+#define PPPOL2TP_VERSION         0x0100 /* L2TP Protocol version 1, revision 0 */
+
+/* -- AVP - Framing capabilities */
+#define PPPOL2TP_AVPTYPE_FRAMINGCAPABILITIES           3 /* Bearer capabilities */
+#define PPPOL2TP_FRAMINGCAPABILITIES          0x00000003 /* Async + Sync framing */
+
+/* -- AVP - Bearer capabilities */
+#define PPPOL2TP_AVPTYPE_BEARERCAPABILITIES           4 /* Bearer capabilities */
+#define PPPOL2TP_BEARERCAPABILITIES          0x00000003 /* Analog + Digital Access */
+
+/* -- AVP - Tie breaker */
+#define PPPOL2TP_AVPTYPE_TIEBREAKER   5
+
+/* -- AVP - Host name */
+#define PPPOL2TP_AVPTYPE_HOSTNAME     7 /* Host name */
+#define PPPOL2TP_HOSTNAME        "lwIP" /* FIXME: make it configurable */
+
+/* -- AVP - Vendor name */
+#define PPPOL2TP_AVPTYPE_VENDORNAME   8 /* Vendor name */
+#define PPPOL2TP_VENDORNAME      "lwIP" /* FIXME: make it configurable */
+
+/* -- AVP - Assign tunnel ID */
+#define PPPOL2TP_AVPTYPE_TUNNELID     9 /* Assign Tunnel ID */
+
+/* -- AVP - Receive window size */
+#define PPPOL2TP_AVPTYPE_RECEIVEWINDOWSIZE  10 /* Receive window size */
+#define PPPOL2TP_RECEIVEWINDOWSIZE           8 /* FIXME: make it configurable */
+
+/* -- AVP - Challenge */
+#define PPPOL2TP_AVPTYPE_CHALLENGE   11 /* Challenge */
+
+/* -- AVP - Cause code */
+#define PPPOL2TP_AVPTYPE_CAUSECODE   12 /* Cause code*/
+
+/* -- AVP - Challenge response */
+#define PPPOL2TP_AVPTYPE_CHALLENGERESPONSE   13 /* Challenge response */
+#define PPPOL2TP_AVPTYPE_CHALLENGERESPONSE_SIZE  16
+
+/* -- AVP - Assign session ID */
+#define PPPOL2TP_AVPTYPE_SESSIONID   14 /* Assign Session ID */
+
+/* -- AVP - Call serial number */
+#define PPPOL2TP_AVPTYPE_CALLSERIALNUMBER   15 /* Call Serial Number */
+
+/* -- AVP - Framing type */
+#define PPPOL2TP_AVPTYPE_FRAMINGTYPE         19 /* Framing Type */
+#define PPPOL2TP_FRAMINGTYPE         0x00000001 /* Sync framing */
+
+/* -- AVP - TX Connect Speed */
+#define PPPOL2TP_AVPTYPE_TXCONNECTSPEED      24 /* TX Connect Speed */
+#define PPPOL2TP_TXCONNECTSPEED       100000000 /* Connect speed: 100 Mbits/s */
+
+/* L2TP Session state */
+#define PPPOL2TP_STATE_INITIAL     0
+#define PPPOL2TP_STATE_SCCRQ_SENT  1
+#define PPPOL2TP_STATE_ICRQ_SENT   2
+#define PPPOL2TP_STATE_ICCN_SENT   3
+#define PPPOL2TP_STATE_DATA        4
+
+#define PPPOL2TP_OUTPUT_DATA_HEADER_LEN   6 /* Our data header len */
+
+/*
+ * PPPoL2TP interface control block.
+ */
+typedef struct pppol2tp_pcb_s pppol2tp_pcb;
+struct pppol2tp_pcb_s {
+  ppp_pcb *ppp;                /* PPP PCB */
+  u8_t phase;                  /* L2TP phase */
+  struct udp_pcb *udp;         /* UDP L2TP Socket */
+  struct netif *netif;         /* Output interface, used as a default route */
+  ip_addr_t remote_ip;         /* LNS IP Address */
+  u16_t remote_port;           /* LNS port */
+#if PPPOL2TP_AUTH_SUPPORT
+  const u8_t *secret;          /* Secret string */
+  u8_t secret_len;             /* Secret string length */
+  u8_t secret_rv[16];          /* Random vector */
+  u8_t challenge_hash[16];     /* Challenge response */
+  u8_t send_challenge;         /* Boolean whether the next sent packet should contains a challenge response */
+#endif /* PPPOL2TP_AUTH_SUPPORT */
+
+  u16_t tunnel_port;           /* Tunnel port */
+  u16_t our_ns;                /* NS to peer */
+  u16_t peer_nr;               /* NR from peer */
+  u16_t peer_ns;               /* Expected NS from peer */
+  u16_t source_tunnel_id;      /* Tunnel ID assigned by peer */
+  u16_t remote_tunnel_id;      /* Tunnel ID assigned to peer */
+  u16_t source_session_id;     /* Session ID assigned by peer */
+  u16_t remote_session_id;     /* Session ID assigned to peer */
+
+  u8_t sccrq_retried;          /* number of SCCRQ retries already done */
+  u8_t icrq_retried;           /* number of ICRQ retries already done */
+  u8_t iccn_retried;           /* number of ICCN retries already done */
+};
+
+
+/* Create a new L2TP session. */
+ppp_pcb *pppol2tp_create(struct netif *pppif,
+       struct netif *netif, const ip_addr_t *ipaddr, u16_t port,
+       const u8_t *secret, u8_t secret_len,
+       ppp_link_status_cb_fn link_status_cb, void *ctx_cb);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* PPPOL2TP_H */
+#endif /* PPP_SUPPORT && PPPOL2TP_SUPPORT */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/netif/ppp/pppos.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/netif/ppp/pppos.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/netif/ppp/pppos.h	(revision 457)
@@ -0,0 +1,126 @@
+/**
+ * @file
+ * Network Point to Point Protocol over Serial header file.
+ *
+ */
+
+/*
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ */
+
+#include "netif/ppp/ppp_opts.h"
+#if PPP_SUPPORT && PPPOS_SUPPORT /* don't build if not configured for use in lwipopts.h */
+
+#ifndef PPPOS_H
+#define PPPOS_H
+
+#include "lwip/sys.h"
+
+#include "ppp.h"
+#include "vj.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* PPP packet parser states.  Current state indicates operation yet to be
+ * completed. */
+enum {
+  PDIDLE = 0,  /* Idle state - waiting. */
+  PDSTART,     /* Process start flag. */
+  PDADDRESS,   /* Process address field. */
+  PDCONTROL,   /* Process control field. */
+  PDPROTOCOL1, /* Process protocol field 1. */
+  PDPROTOCOL2, /* Process protocol field 2. */
+  PDDATA       /* Process data byte. */
+};
+
+/* PPPoS serial output callback function prototype */
+typedef u32_t (*pppos_output_cb_fn)(ppp_pcb *pcb, u8_t *data, u32_t len, void *ctx);
+
+/*
+ * Extended asyncmap - allows any character to be escaped.
+ */
+typedef u8_t ext_accm[32];
+
+/*
+ * PPPoS interface control block.
+ */
+typedef struct pppos_pcb_s pppos_pcb;
+struct pppos_pcb_s {
+  /* -- below are data that will NOT be cleared between two sessions */
+  ppp_pcb *ppp;                    /* PPP PCB */
+  pppos_output_cb_fn output_cb;    /* PPP serial output callback */
+
+  /* -- below are data that will be cleared between two sessions
+   *
+   * last_xmit must be the first member of cleared members, because it is
+   * used to know which part must not be cleared.
+   */
+  u32_t last_xmit;                 /* Time of last transmission. */
+  ext_accm out_accm;               /* Async-Ctl-Char-Map for output. */
+
+  /* flags */
+  unsigned int open            :1; /* Set if PPPoS is open */
+  unsigned int pcomp           :1; /* Does peer accept protocol compression? */
+  unsigned int accomp          :1; /* Does peer accept addr/ctl compression? */
+
+  /* PPPoS rx */
+  ext_accm in_accm;                /* Async-Ctl-Char-Map for input. */
+  struct pbuf *in_head, *in_tail;  /* The input packet. */
+  u16_t in_protocol;               /* The input protocol code. */
+  u16_t in_fcs;                    /* Input Frame Check Sequence value. */
+  u8_t in_state;                   /* The input process state. */
+  u8_t in_escaped;                 /* Escape next character. */
+};
+
+/* Create a new PPPoS session. */
+ppp_pcb *pppos_create(struct netif *pppif, pppos_output_cb_fn output_cb,
+       ppp_link_status_cb_fn link_status_cb, void *ctx_cb);
+
+#if !NO_SYS && !PPP_INPROC_IRQ_SAFE
+/* Pass received raw characters to PPPoS to be decoded through lwIP TCPIP thread. */
+err_t pppos_input_tcpip(ppp_pcb *ppp, u8_t *s, int l);
+#endif /* !NO_SYS && !PPP_INPROC_IRQ_SAFE */
+
+/* PPP over Serial: this is the input function to be called for received data. */
+void pppos_input(ppp_pcb *ppp, u8_t* data, int len);
+
+
+/*
+ * Functions called from lwIP
+ * DO NOT CALL FROM lwIP USER APPLICATION.
+ */
+#if !NO_SYS && !PPP_INPROC_IRQ_SAFE
+err_t pppos_input_sys(struct pbuf *p, struct netif *inp);
+#endif /* !NO_SYS && !PPP_INPROC_IRQ_SAFE */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* PPPOS_H */
+#endif /* PPP_SUPPORT && PPPOL2TP_SUPPORT */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/netif/ppp/upap.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/netif/ppp/upap.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/netif/ppp/upap.h	(revision 457)
@@ -0,0 +1,131 @@
+/*
+ * upap.h - User/Password Authentication Protocol definitions.
+ *
+ * Copyright (c) 1984-2000 Carnegie Mellon University. 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. The name "Carnegie Mellon University" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For permission or any legal
+ *    details, please contact
+ *      Office of Technology Transfer
+ *      Carnegie Mellon University
+ *      5000 Forbes Avenue
+ *      Pittsburgh, PA  15213-3890
+ *      (412) 268-4387, fax: (412) 268-7395
+ *      tech-transfer@andrew.cmu.edu
+ *
+ * 4. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by Computing Services
+ *     at Carnegie Mellon University (http://www.cmu.edu/computing/)."
+ *
+ * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO
+ * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE
+ * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
+ * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
+ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * $Id$
+ */
+
+#include "netif/ppp/ppp_opts.h"
+#if PPP_SUPPORT && PAP_SUPPORT  /* don't build if not configured for use in lwipopts.h */
+
+#ifndef UPAP_H
+#define UPAP_H
+
+#include "ppp.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * Packet header = Code, id, length.
+ */
+#define UPAP_HEADERLEN	4
+
+
+/*
+ * UPAP codes.
+ */
+#define UPAP_AUTHREQ	1	/* Authenticate-Request */
+#define UPAP_AUTHACK	2	/* Authenticate-Ack */
+#define UPAP_AUTHNAK	3	/* Authenticate-Nak */
+
+
+/*
+ * Client states.
+ */
+#define UPAPCS_INITIAL	0	/* Connection down */
+#define UPAPCS_CLOSED	1	/* Connection up, haven't requested auth */
+#define UPAPCS_PENDING	2	/* Connection down, have requested auth */
+#define UPAPCS_AUTHREQ	3	/* We've sent an Authenticate-Request */
+#define UPAPCS_OPEN	4	/* We've received an Ack */
+#define UPAPCS_BADAUTH	5	/* We've received a Nak */
+
+/*
+ * Server states.
+ */
+#define UPAPSS_INITIAL	0	/* Connection down */
+#define UPAPSS_CLOSED	1	/* Connection up, haven't requested auth */
+#define UPAPSS_PENDING	2	/* Connection down, have requested auth */
+#define UPAPSS_LISTEN	3	/* Listening for an Authenticate */
+#define UPAPSS_OPEN	4	/* We've sent an Ack */
+#define UPAPSS_BADAUTH	5	/* We've sent a Nak */
+
+
+/*
+ * Timeouts.
+ */
+#if 0 /* moved to ppp_opts.h */
+#define UPAP_DEFTIMEOUT	3	/* Timeout (seconds) for retransmitting req */
+#define UPAP_DEFREQTIME	30	/* Time to wait for auth-req from peer */
+#endif /* moved to ppp_opts.h */
+
+/*
+ * Each interface is described by upap structure.
+ */
+#if PAP_SUPPORT
+typedef struct upap_state {
+    const char *us_user;	/* User */
+    u8_t us_userlen;		/* User length */
+    const char *us_passwd;	/* Password */
+    u8_t us_passwdlen;		/* Password length */
+    u8_t us_clientstate;	/* Client state */
+#if PPP_SERVER
+    u8_t us_serverstate;	/* Server state */
+#endif /* PPP_SERVER */
+    u8_t us_id;		        /* Current id */
+    u8_t us_transmits;		/* Number of auth-reqs sent */
+} upap_state;
+#endif /* PAP_SUPPORT */
+
+
+void upap_authwithpeer(ppp_pcb *pcb, const char *user, const char *password);
+#if PPP_SERVER
+void upap_authpeer(ppp_pcb *pcb);
+#endif /* PPP_SERVER */
+
+extern const struct protent pap_protent;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* UPAP_H */
+#endif /* PPP_SUPPORT && PAP_SUPPORT */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/netif/ppp/vj.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/netif/ppp/vj.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/netif/ppp/vj.h	(revision 457)
@@ -0,0 +1,169 @@
+/*
+ * Definitions for tcp compression routines.
+ *
+ * $Id$
+ *
+ * Copyright (c) 1989 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms are permitted
+ * provided that the above copyright notice and this paragraph are
+ * duplicated in all such forms and that any documentation,
+ * advertising materials, and other materials related to such
+ * distribution and use acknowledge that the software was developed
+ * by the University of California, Berkeley.  The name of the
+ * University may not be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * Van Jacobson (van@helios.ee.lbl.gov), Dec 31, 1989:
+ * - Initial distribution.
+ */
+
+#include "netif/ppp/ppp_opts.h"
+#if PPP_SUPPORT && VJ_SUPPORT /* don't build if not configured for use in lwipopts.h */
+
+#ifndef VJ_H
+#define VJ_H
+
+#include "lwip/ip.h"
+#include "lwip/priv/tcp_priv.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define MAX_SLOTS 16 /* must be > 2 and < 256 */
+#define MAX_HDR   128
+
+/*
+ * Compressed packet format:
+ *
+ * The first octet contains the packet type (top 3 bits), TCP
+ * 'push' bit, and flags that indicate which of the 4 TCP sequence
+ * numbers have changed (bottom 5 bits).  The next octet is a
+ * conversation number that associates a saved IP/TCP header with
+ * the compressed packet.  The next two octets are the TCP checksum
+ * from the original datagram.  The next 0 to 15 octets are
+ * sequence number changes, one change per bit set in the header
+ * (there may be no changes and there are two special cases where
+ * the receiver implicitly knows what changed -- see below).
+ *
+ * There are 5 numbers which can change (they are always inserted
+ * in the following order): TCP urgent pointer, window,
+ * acknowlegement, sequence number and IP ID.  (The urgent pointer
+ * is different from the others in that its value is sent, not the
+ * change in value.)  Since typical use of SLIP links is biased
+ * toward small packets (see comments on MTU/MSS below), changes
+ * use a variable length coding with one octet for numbers in the
+ * range 1 - 255 and 3 octets (0, MSB, LSB) for numbers in the
+ * range 256 - 65535 or 0.  (If the change in sequence number or
+ * ack is more than 65535, an uncompressed packet is sent.)
+ */
+
+/*
+ * Packet types (must not conflict with IP protocol version)
+ *
+ * The top nibble of the first octet is the packet type.  There are
+ * three possible types: IP (not proto TCP or tcp with one of the
+ * control flags set); uncompressed TCP (a normal IP/TCP packet but
+ * with the 8-bit protocol field replaced by an 8-bit connection id --
+ * this type of packet syncs the sender & receiver); and compressed
+ * TCP (described above).
+ *
+ * LSB of 4-bit field is TCP "PUSH" bit (a worthless anachronism) and
+ * is logically part of the 4-bit "changes" field that follows.  Top
+ * three bits are actual packet type.  For backward compatibility
+ * and in the interest of conserving bits, numbers are chosen so the
+ * IP protocol version number (4) which normally appears in this nibble
+ * means "IP packet".
+ */
+
+/* packet types */
+#define TYPE_IP               0x40
+#define TYPE_UNCOMPRESSED_TCP 0x70
+#define TYPE_COMPRESSED_TCP   0x80
+#define TYPE_ERROR            0x00
+
+/* Bits in first octet of compressed packet */
+#define NEW_C 0x40 /* flag bits for what changed in a packet */
+#define NEW_I 0x20
+#define NEW_S 0x08
+#define NEW_A 0x04
+#define NEW_W 0x02
+#define NEW_U 0x01
+
+/* reserved, special-case values of above */
+#define SPECIAL_I (NEW_S|NEW_W|NEW_U) /* echoed interactive traffic */
+#define SPECIAL_D (NEW_S|NEW_A|NEW_W|NEW_U) /* unidirectional data */
+#define SPECIALS_MASK (NEW_S|NEW_A|NEW_W|NEW_U)
+
+#define TCP_PUSH_BIT 0x10
+
+
+/*
+ * "state" data for each active tcp conversation on the wire.  This is
+ * basically a copy of the entire IP/TCP header from the last packet
+ * we saw from the conversation together with a small identifier
+ * the transmit & receive ends of the line use to locate saved header.
+ */
+struct cstate {
+  struct cstate *cs_next; /* next most recently used state (xmit only) */
+  u16_t cs_hlen;        /* size of hdr (receive only) */
+  u8_t cs_id;           /* connection # associated with this state */
+  u8_t cs_filler;
+  union {
+    char csu_hdr[MAX_HDR];
+    struct ip_hdr csu_ip;     /* ip/tcp hdr from most recent packet */
+  } vjcs_u;
+};
+#define cs_ip vjcs_u.csu_ip
+#define cs_hdr vjcs_u.csu_hdr
+
+
+struct vjstat {
+  u32_t vjs_packets;        /* outbound packets */
+  u32_t vjs_compressed;     /* outbound compressed packets */
+  u32_t vjs_searches;       /* searches for connection state */
+  u32_t vjs_misses;         /* times couldn't find conn. state */
+  u32_t vjs_uncompressedin; /* inbound uncompressed packets */
+  u32_t vjs_compressedin;   /* inbound compressed packets */
+  u32_t vjs_errorin;        /* inbound unknown type packets */
+  u32_t vjs_tossed;         /* inbound packets tossed because of error */
+};
+
+/*
+ * all the state data for one serial line (we need one of these per line).
+ */
+struct vjcompress {
+  struct cstate *last_cs;          /* most recently used tstate */
+  u8_t last_recv;                /* last rcvd conn. id */
+  u8_t last_xmit;                /* last sent conn. id */
+  u16_t flags;
+  u8_t maxSlotIndex;
+  u8_t compressSlot;             /* Flag indicating OK to compress slot ID. */
+#if LINK_STATS
+  struct vjstat stats;
+#endif
+  struct cstate tstate[MAX_SLOTS]; /* xmit connection states */
+  struct cstate rstate[MAX_SLOTS]; /* receive connection states */
+};
+
+/* flag values */
+#define VJF_TOSS 1U /* tossing rcvd frames because of input err */
+
+extern void  vj_compress_init    (struct vjcompress *comp);
+extern u8_t  vj_compress_tcp     (struct vjcompress *comp, struct pbuf **pb);
+extern void  vj_uncompress_err   (struct vjcompress *comp);
+extern int   vj_uncompress_uncomp(struct pbuf *nb, struct vjcompress *comp);
+extern int   vj_uncompress_tcp   (struct pbuf **nb, struct vjcompress *comp);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* VJ_H */
+
+#endif /* PPP_SUPPORT && VJ_SUPPORT */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/netif/slipif.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/netif/slipif.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/netif/slipif.h	(revision 457)
@@ -0,0 +1,87 @@
+/**
+ * @file
+ *
+ * SLIP netif API
+ */
+
+/*
+ * Copyright (c) 2001, Swedish Institute of Computer Science.
+ * 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 Institute 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 INSTITUTE 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 INSTITUTE 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Adam Dunkels <adam@sics.se>
+ *
+ */
+#ifndef LWIP_HDR_NETIF_SLIPIF_H
+#define LWIP_HDR_NETIF_SLIPIF_H
+
+#include "lwip/opt.h"
+#include "lwip/netif.h"
+
+/** Set this to 1 to start a thread that blocks reading on the serial line
+ * (using sio_read()).
+ */
+#ifndef SLIP_USE_RX_THREAD
+#define SLIP_USE_RX_THREAD !NO_SYS
+#endif
+
+/** Set this to 1 to enable functions to pass in RX bytes from ISR context.
+ * If enabled, slipif_received_byte[s]() process incoming bytes and put assembled
+ * packets on a queue, which is fed into lwIP from slipif_poll().
+ * If disabled, slipif_poll() polls the serial line (using sio_tryread()).
+ */
+#ifndef SLIP_RX_FROM_ISR
+#define SLIP_RX_FROM_ISR 0
+#endif
+
+/** Set this to 1 (default for SLIP_RX_FROM_ISR) to queue incoming packets
+ * received by slipif_received_byte[s]() as long as PBUF_POOL pbufs are available.
+ * If disabled, packets will be dropped if more than one packet is received.
+ */
+#ifndef SLIP_RX_QUEUE
+#define SLIP_RX_QUEUE SLIP_RX_FROM_ISR
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+err_t slipif_init(struct netif * netif);
+void slipif_poll(struct netif *netif);
+#if SLIP_RX_FROM_ISR
+void slipif_process_rxqueue(struct netif *netif);
+void slipif_received_byte(struct netif *netif, u8_t data);
+void slipif_received_bytes(struct netif *netif, u8_t *data, u8_t len);
+#endif /* SLIP_RX_FROM_ISR */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LWIP_HDR_NETIF_SLIPIF_H */
+
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/netif/zepif.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/netif/zepif.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/include/netif/zepif.h	(revision 457)
@@ -0,0 +1,81 @@
+/**
+ * @file
+ *
+ * A netif implementing the ZigBee Eencapsulation Protocol (ZEP).
+ * This is used to tunnel 6LowPAN over UDP.
+ */
+
+/*
+ * Copyright (c) 2018 Simon Goldschmidt
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Simon Goldschmidt <goldsimon@gmx.de>
+ *
+ */
+
+#ifndef LWIP_HDR_ZEPIF_H
+#define LWIP_HDR_ZEPIF_H
+
+#include "lwip/opt.h"
+#include "netif/lowpan6.h"
+
+#if LWIP_IPV6 && LWIP_UDP /* don't build if not configured for use in lwipopts.h */
+
+#include "lwip/netif.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define ZEPIF_DEFAULT_UDP_PORT  17754
+
+/** Pass this struct as 'state' to netif_add to control the behaviour
+ * of this netif. If NULL is passed, default behaviour is chosen */
+struct zepif_init {
+  /** The UDP port used to ZEP frames from (0 = default) */
+  u16_t               zep_src_udp_port;
+  /** The UDP port used to ZEP frames to (0 = default) */
+  u16_t               zep_dst_udp_port;
+  /** The IP address to sed ZEP frames from (NULL = ANY) */
+  const ip_addr_t    *zep_src_ip_addr;
+  /** The IP address to sed ZEP frames to (NULL = BROADCAST) */
+  const ip_addr_t    *zep_dst_ip_addr;
+  /** If != NULL, the udp pcb is bound to this netif */
+  const struct netif *zep_netif;
+  /** MAC address of the 6LowPAN device */
+  u8_t                addr[6];
+};
+
+err_t zepif_init(struct netif *netif);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LWIP_IPV6 && LWIP_UDP */
+
+#endif /* LWIP_HDR_ZEPIF_H */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/netif/FILES
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/netif/FILES	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/netif/FILES	(revision 457)
@@ -0,0 +1,23 @@
+This directory contains generic network interface device drivers that
+do not contain any hardware or architecture specific code. The files
+are:
+
+ethernet.c
+          Shared code for Ethernet based interfaces.
+
+lowpan6.c
+          A 6LoWPAN implementation as a netif.
+
+lowpan6_ble.c
+          A 6LoWPAN over Bluetooth Low Energy (BLE) implementation as netif,
+          according to RFC-7668.
+
+slipif.c
+          A generic implementation of the SLIP (Serial Line IP)
+          protocol. It requires a sio (serial I/O) module to work.
+
+ppp/      Point-to-Point Protocol stack
+          The lwIP PPP support is based from pppd (http://ppp.samba.org) with
+          huge changes to match code size and memory requirements for embedded
+          devices. Please read /doc/ppp.txt and ppp/PPPD_FOLLOWUP for a detailed
+          explanation.
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/netif/bridgeif.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/netif/bridgeif.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/netif/bridgeif.c	(revision 457)
@@ -0,0 +1,563 @@
+/**
+ * @file
+ * lwIP netif implementing an IEEE 802.1D MAC Bridge
+ */
+
+/*
+ * Copyright (c) 2017 Simon Goldschmidt.
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Simon Goldschmidt <goldsimon@gmx.de>
+ *
+ */
+
+/**
+ * @defgroup bridgeif IEEE 802.1D bridge
+ * @ingroup netifs
+ * This file implements an IEEE 802.1D bridge by using a multilayer netif approach
+ * (one hardware-independent netif for the bridge that uses hardware netifs for its ports).
+ * On transmit, the bridge selects the outgoing port(s).
+ * On receive, the port netif calls into the bridge (via its netif->input function) and
+ * the bridge selects the port(s) (and/or its netif->input function) to pass the received pbuf to.
+ *
+ * Usage:
+ * - add the port netifs just like you would when using them as dedicated netif without a bridge
+ *   - only NETIF_FLAG_ETHARP/NETIF_FLAG_ETHERNET netifs are supported as bridge ports
+ *   - add the bridge port netifs without IPv4 addresses (i.e. pass 'NULL, NULL, NULL')
+ *   - don't add IPv6 addresses to the port netifs!
+ * - set up the bridge configuration in a global variable of type 'bridgeif_initdata_t' that contains
+ *   - the MAC address of the bridge
+ *   - some configuration options controlling the memory consumption (maximum number of ports
+ *     and FDB entries)
+ *   - e.g. for a bridge MAC address 00-01-02-03-04-05, 2 bridge ports, 1024 FDB entries + 16 static MAC entries:
+ *     bridgeif_initdata_t mybridge_initdata = BRIDGEIF_INITDATA1(2, 1024, 16, ETH_ADDR(0, 1, 2, 3, 4, 5));
+ * - add the bridge netif (with IPv4 config):
+ *   struct netif bridge_netif;
+ *   netif_add(&bridge_netif, &my_ip, &my_netmask, &my_gw, &mybridge_initdata, bridgeif_init, tcpip_input);
+ *   NOTE: the passed 'input' function depends on BRIDGEIF_PORT_NETIFS_OUTPUT_DIRECT setting,
+ *         which controls where the forwarding is done (netif low level input context vs. tcpip_thread)
+ * - set up all ports netifs and the bridge netif
+ *
+ * - When adding a port netif, NETIF_FLAG_ETHARP flag will be removed from a port
+ *   to prevent ETHARP working on that port netif (we only want one IP per bridge not per port).
+ * - When adding a port netif, its input function is changed to call into the bridge.
+ *
+ *
+ * @todo:
+ * - compact static FDB entries (instead of walking the whole array)
+ * - add FDB query/read access
+ * - add FDB change callback (when learning or dropping auto-learned entries)
+ * - prefill FDB with MAC classes that should never be forwarded
+ * - multicast snooping? (and only forward group addresses to interested ports)
+ * - support removing ports
+ * - check SNMP integration
+ * - VLAN handling / trunk ports
+ * - priority handling? (although that largely depends on TX queue limitations and lwIP doesn't provide tx-done handling)
+ */
+
+#include "netif/bridgeif.h"
+#include "lwip/netif.h"
+#include "lwip/sys.h"
+#include "lwip/etharp.h"
+#include "lwip/ethip6.h"
+#include "lwip/snmp.h"
+#include "lwip/timeouts.h"
+#include <string.h>
+
+#if LWIP_NUM_NETIF_CLIENT_DATA
+
+/* Define those to better describe your network interface. */
+#define IFNAME0 'b'
+#define IFNAME1 'r'
+
+struct bridgeif_private_s;
+typedef struct bridgeif_port_private_s {
+  struct bridgeif_private_s *bridge;
+  struct netif *port_netif;
+  u8_t port_num;
+} bridgeif_port_t;
+
+typedef struct bridgeif_fdb_static_entry_s {
+  u8_t used;
+  bridgeif_portmask_t dst_ports;
+  struct eth_addr addr;
+} bridgeif_fdb_static_entry_t;
+
+typedef struct bridgeif_private_s {
+  struct netif     *netif;
+  struct eth_addr   ethaddr;
+  u8_t              max_ports;
+  u8_t              num_ports;
+  bridgeif_port_t  *ports;
+  u16_t             max_fdbs_entries;
+  bridgeif_fdb_static_entry_t *fdbs;
+  u16_t             max_fdbd_entries;
+  void             *fdbd;
+} bridgeif_private_t;
+
+/* netif data index to get the bridge on input */
+u8_t bridgeif_netif_client_id = 0xff;
+
+/**
+ * @ingroup bridgeif
+ * Add a static entry to the forwarding database.
+ * A static entry marks where frames to a specific eth address (unicast or group address) are
+ * forwarded.
+ * bits [0..(BRIDGEIF_MAX_PORTS-1)]: hw ports
+ * bit [BRIDGEIF_MAX_PORTS]: cpu port
+ * 0: drop
+ */
+err_t
+bridgeif_fdb_add(struct netif *bridgeif, const struct eth_addr *addr, bridgeif_portmask_t ports)
+{
+  int i;
+  bridgeif_private_t *br;
+  BRIDGEIF_DECL_PROTECT(lev);
+  LWIP_ASSERT("invalid netif", bridgeif != NULL);
+  br = (bridgeif_private_t *)bridgeif->state;
+  LWIP_ASSERT("invalid state", br != NULL);
+
+  BRIDGEIF_READ_PROTECT(lev);
+  for (i = 0; i < br->max_fdbs_entries; i++) {
+    if (!br->fdbs[i].used) {
+      BRIDGEIF_WRITE_PROTECT(lev);
+      if (!br->fdbs[i].used) {
+        br->fdbs[i].used = 1;
+        br->fdbs[i].dst_ports = ports;
+        memcpy(&br->fdbs[i].addr, addr, sizeof(struct eth_addr));
+        BRIDGEIF_WRITE_UNPROTECT(lev);
+        BRIDGEIF_READ_UNPROTECT(lev);
+        return ERR_OK;
+      }
+      BRIDGEIF_WRITE_UNPROTECT(lev);
+    }
+  }
+  BRIDGEIF_READ_UNPROTECT(lev);
+  return ERR_MEM;
+}
+
+/**
+ * @ingroup bridgeif
+ * Remove a static entry from the forwarding database
+ */
+err_t
+bridgeif_fdb_remove(struct netif *bridgeif, const struct eth_addr *addr)
+{
+  int i;
+  bridgeif_private_t *br;
+  BRIDGEIF_DECL_PROTECT(lev);
+  LWIP_ASSERT("invalid netif", bridgeif != NULL);
+  br = (bridgeif_private_t *)bridgeif->state;
+  LWIP_ASSERT("invalid state", br != NULL);
+
+  BRIDGEIF_READ_PROTECT(lev);
+  for (i = 0; i < br->max_fdbs_entries; i++) {
+    if (br->fdbs[i].used && !memcmp(&br->fdbs[i].addr, addr, sizeof(struct eth_addr))) {
+      BRIDGEIF_WRITE_PROTECT(lev);
+      if (br->fdbs[i].used && !memcmp(&br->fdbs[i].addr, addr, sizeof(struct eth_addr))) {
+        memset(&br->fdbs[i], 0, sizeof(bridgeif_fdb_static_entry_t));
+        BRIDGEIF_WRITE_UNPROTECT(lev);
+        BRIDGEIF_READ_UNPROTECT(lev);
+        return ERR_OK;
+      }
+      BRIDGEIF_WRITE_UNPROTECT(lev);
+    }
+  }
+  BRIDGEIF_READ_UNPROTECT(lev);
+  return ERR_VAL;
+}
+
+/** Get the forwarding port(s) (as bit mask) for the specified destination mac address */
+static bridgeif_portmask_t
+bridgeif_find_dst_ports(bridgeif_private_t *br, struct eth_addr *dst_addr)
+{
+  int i;
+  BRIDGEIF_DECL_PROTECT(lev);
+  BRIDGEIF_READ_PROTECT(lev);
+  /* first check for static entries */
+  for (i = 0; i < br->max_fdbs_entries; i++) {
+    if (br->fdbs[i].used) {
+      if (!memcmp(&br->fdbs[i].addr, dst_addr, sizeof(struct eth_addr))) {
+        bridgeif_portmask_t ret = br->fdbs[i].dst_ports;
+        BRIDGEIF_READ_UNPROTECT(lev);
+        return ret;
+      }
+    }
+  }
+  if (dst_addr->addr[0] & 1) {
+    /* no match found: flood remaining group address */
+    BRIDGEIF_READ_UNPROTECT(lev);
+    return BR_FLOOD;
+  }
+  BRIDGEIF_READ_UNPROTECT(lev);
+  /* no match found: check dynamic fdb for port or fall back to flooding */
+  return bridgeif_fdb_get_dst_ports(br->fdbd, dst_addr);
+}
+
+/** Helper function to see if a destination mac belongs to the bridge
+ * (bridge netif or one of the port netifs), in which case the frame
+ * is sent to the cpu only.
+ */
+static int
+bridgeif_is_local_mac(bridgeif_private_t *br, struct eth_addr *addr)
+{
+  int i;
+  BRIDGEIF_DECL_PROTECT(lev);
+  if (!memcmp(br->netif->hwaddr, addr, sizeof(struct eth_addr))) {
+    return 1;
+  }
+  BRIDGEIF_READ_PROTECT(lev);
+  for (i = 0; i < br->num_ports; i++) {
+    struct netif *portif = br->ports[i].port_netif;
+    if (portif != NULL) {
+      if (!memcmp(portif->hwaddr, addr, sizeof(struct eth_addr))) {
+        BRIDGEIF_READ_UNPROTECT(lev);
+        return 1;
+      }
+    }
+  }
+  BRIDGEIF_READ_UNPROTECT(lev);
+  return 0;
+}
+
+/* Output helper function */
+static err_t
+bridgeif_send_to_port(bridgeif_private_t *br, struct pbuf *p, u8_t dstport_idx)
+{
+  if (dstport_idx < BRIDGEIF_MAX_PORTS) {
+    /* possibly an external port */
+    if (dstport_idx < br->max_ports) {
+      struct netif *portif = br->ports[dstport_idx].port_netif;
+      if ((portif != NULL) && (portif->linkoutput != NULL)) {
+        /* prevent sending out to rx port */
+        if (netif_get_index(portif) != p->if_idx) {
+          if (netif_is_link_up(portif)) {
+            LWIP_DEBUGF(BRIDGEIF_FW_DEBUG, ("br -> flood(%p:%d) -> %d\n", (void *)p, p->if_idx, netif_get_index(portif)));
+            return portif->linkoutput(portif, p);
+          }
+        }
+      }
+    }
+  } else {
+    LWIP_ASSERT("invalid port index", dstport_idx == BRIDGEIF_MAX_PORTS);
+  }
+  return ERR_OK;
+}
+
+/** Helper function to pass a pbuf to all ports marked in 'dstports'
+ */
+static err_t
+bridgeif_send_to_ports(bridgeif_private_t *br, struct pbuf *p, bridgeif_portmask_t dstports)
+{
+  err_t err, ret_err = ERR_OK;
+  u8_t i;
+  bridgeif_portmask_t mask = 1;
+  BRIDGEIF_DECL_PROTECT(lev);
+  BRIDGEIF_READ_PROTECT(lev);
+  for (i = 0; i < BRIDGEIF_MAX_PORTS; i++, mask = (bridgeif_portmask_t)(mask << 1)) {
+    if (dstports & mask) {
+      err = bridgeif_send_to_port(br, p, i);
+      if (err != ERR_OK) {
+        ret_err = err;
+      }
+    }
+  }
+  BRIDGEIF_READ_UNPROTECT(lev);
+  return ret_err;
+}
+
+/** Output function of the application port of the bridge (the one with an ip address).
+ * The forwarding port(s) where this pbuf is sent on is/are automatically selected
+ * from the FDB.
+ */
+static err_t
+bridgeif_output(struct netif *netif, struct pbuf *p)
+{
+  err_t err;
+  bridgeif_private_t *br = (bridgeif_private_t *)netif->state;
+  struct eth_addr *dst = (struct eth_addr *)(p->payload);
+
+  bridgeif_portmask_t dstports = bridgeif_find_dst_ports(br, dst);
+  err = bridgeif_send_to_ports(br, p, dstports);
+
+  MIB2_STATS_NETIF_ADD(netif, ifoutoctets, p->tot_len);
+  if (((u8_t *)p->payload)[0] & 1) {
+    /* broadcast or multicast packet*/
+    MIB2_STATS_NETIF_INC(netif, ifoutnucastpkts);
+  } else {
+    /* unicast packet */
+    MIB2_STATS_NETIF_INC(netif, ifoutucastpkts);
+  }
+  /* increase ifoutdiscards or ifouterrors on error */
+
+  LINK_STATS_INC(link.xmit);
+
+  return err;
+}
+
+/** The actual bridge input function. Port netif's input is changed to call
+ * here. This function decides where the frame is forwarded.
+ */
+static err_t
+bridgeif_input(struct pbuf *p, struct netif *netif)
+{
+  u8_t rx_idx;
+  bridgeif_portmask_t dstports;
+  struct eth_addr *src, *dst;
+  bridgeif_private_t *br;
+  bridgeif_port_t *port;
+  if (p == NULL || netif == NULL) {
+    return ERR_VAL;
+  }
+  port = (bridgeif_port_t *)netif_get_client_data(netif, bridgeif_netif_client_id);
+  LWIP_ASSERT("port data not set", port != NULL);
+  if (port == NULL || port->bridge == NULL) {
+    return ERR_VAL;
+  }
+  br = (bridgeif_private_t *)port->bridge;
+  rx_idx = netif_get_index(netif);
+  /* store receive index in pbuf */
+  p->if_idx = rx_idx;
+
+  dst = (struct eth_addr *)p->payload;
+  src = (struct eth_addr *)(((u8_t *)p->payload) + sizeof(struct eth_addr));
+
+  if ((src->addr[0] & 1) == 0) {
+    /* update src for all non-group addresses */
+    bridgeif_fdb_update_src(br->fdbd, src, port->port_num);
+  }
+
+  if (dst->addr[0] & 1) {
+    /* group address -> flood + cpu? */
+    dstports = bridgeif_find_dst_ports(br, dst);
+    bridgeif_send_to_ports(br, p, dstports);
+    if (dstports & (1 << BRIDGEIF_MAX_PORTS)) {
+      /* we pass the reference to ->input or have to free it */
+      LWIP_DEBUGF(BRIDGEIF_FW_DEBUG, ("br -> input(%p)\n", (void *)p));
+      if (br->netif->input(p, br->netif) != ERR_OK) {
+        pbuf_free(p);
+      }
+    } else {
+      /* all references done */
+      pbuf_free(p);
+    }
+    /* always return ERR_OK here to prevent the caller freeing the pbuf */
+    return ERR_OK;
+  } else {
+    /* is this for one of the local ports? */
+    if (bridgeif_is_local_mac(br, dst)) {
+      /* yes, send to cpu port only */
+      LWIP_DEBUGF(BRIDGEIF_FW_DEBUG, ("br -> input(%p)\n", (void *)p));
+      return br->netif->input(p, br->netif);
+    }
+
+    /* get dst port */
+    dstports = bridgeif_find_dst_ports(br, dst);
+    bridgeif_send_to_ports(br, p, dstports);
+    /* no need to send to cpu, flooding is for external ports only */
+    /* by  this, we consumed the pbuf */
+    pbuf_free(p);
+    /* always return ERR_OK here to prevent the caller freeing the pbuf */
+    return ERR_OK;
+  }
+}
+
+#if !BRIDGEIF_PORT_NETIFS_OUTPUT_DIRECT
+/** Input function for port netifs used to synchronize into tcpip_thread.
+ */
+static err_t
+bridgeif_tcpip_input(struct pbuf *p, struct netif *netif)
+{
+  return tcpip_inpkt(p, netif, bridgeif_input);
+}
+#endif /* BRIDGEIF_PORT_NETIFS_OUTPUT_DIRECT */
+
+/**
+ * @ingroup bridgeif
+ * Initialization function passed to netif_add().
+ *
+ * ATTENTION: A pointer to a @ref bridgeif_initdata_t must be passed as 'state'
+ *            to @ref netif_add when adding the bridge. I supplies MAC address
+ *            and controls memory allocation (number of ports, FDB size).
+ *
+ * @param netif the lwip network interface structure for this ethernetif
+ * @return ERR_OK if the loopif is initialized
+ *         ERR_MEM if private data couldn't be allocated
+ *         any other err_t on error
+ */
+err_t
+bridgeif_init(struct netif *netif)
+{
+  bridgeif_initdata_t *init_data;
+  bridgeif_private_t *br;
+  size_t alloc_len_sizet;
+  mem_size_t alloc_len;
+
+  LWIP_ASSERT("netif != NULL", (netif != NULL));
+  LWIP_ASSERT("bridgeif needs an input callback", (netif->input != NULL));
+#if !BRIDGEIF_PORT_NETIFS_OUTPUT_DIRECT
+  if (netif->input == tcpip_input) {
+    LWIP_DEBUGF(BRIDGEIF_DEBUG | LWIP_DBG_ON, ("bridgeif does not need tcpip_input, use netif_input/ethernet_input instead"));
+  }
+#endif
+
+  if (bridgeif_netif_client_id == 0xFF) {
+    bridgeif_netif_client_id = netif_alloc_client_data_id();
+  }
+
+  init_data = (bridgeif_initdata_t *)netif->state;
+  LWIP_ASSERT("init_data != NULL", (init_data != NULL));
+  LWIP_ASSERT("init_data->max_ports <= BRIDGEIF_MAX_PORTS",
+              init_data->max_ports <= BRIDGEIF_MAX_PORTS);
+
+  alloc_len_sizet = sizeof(bridgeif_private_t) + (init_data->max_ports * sizeof(bridgeif_port_t) + (init_data->max_fdb_static_entries * sizeof(bridgeif_fdb_static_entry_t)));
+  alloc_len = (mem_size_t)alloc_len_sizet;
+  LWIP_ASSERT("alloc_len == alloc_len_sizet", alloc_len == alloc_len_sizet);
+  LWIP_DEBUGF(BRIDGEIF_DEBUG, ("bridgeif_init: allocating %d bytes for private data\n", (int)alloc_len));
+  br = (bridgeif_private_t *)mem_calloc(1, alloc_len);
+  if (br == NULL) {
+    LWIP_DEBUGF(NETIF_DEBUG, ("bridgeif_init: out of memory\n"));
+    return ERR_MEM;
+  }
+  memcpy(&br->ethaddr, &init_data->ethaddr, sizeof(br->ethaddr));
+  br->netif = netif;
+
+  br->max_ports = init_data->max_ports;
+  br->ports = (bridgeif_port_t *)(br + 1);
+
+  br->max_fdbs_entries = init_data->max_fdb_static_entries;
+  br->fdbs = (bridgeif_fdb_static_entry_t *)(((u8_t *)(br + 1)) + (init_data->max_ports * sizeof(bridgeif_port_t)));
+
+  br->max_fdbd_entries = init_data->max_fdb_dynamic_entries;
+  br->fdbd = bridgeif_fdb_init(init_data->max_fdb_dynamic_entries);
+  if (br->fdbd == NULL) {
+    LWIP_DEBUGF(NETIF_DEBUG, ("bridgeif_init: out of memory in fdb_init\n"));
+    mem_free(br);
+    return ERR_MEM;
+  }
+
+#if LWIP_NETIF_HOSTNAME
+  /* Initialize interface hostname */
+  netif->hostname = "lwip";
+#endif /* LWIP_NETIF_HOSTNAME */
+
+  /*
+   * Initialize the snmp variables and counters inside the struct netif.
+   * The last argument should be replaced with your link speed, in units
+   * of bits per second.
+   */
+  MIB2_INIT_NETIF(netif, snmp_ifType_ethernet_csmacd, 0);
+
+  netif->state = br;
+  netif->name[0] = IFNAME0;
+  netif->name[1] = IFNAME1;
+  /* We directly use etharp_output() here to save a function call.
+   * You can instead declare your own function an call etharp_output()
+   * from it if you have to do some checks before sending (e.g. if link
+   * is available...) */
+#if LWIP_IPV4
+  netif->output = etharp_output;
+#endif /* LWIP_IPV4 */
+#if LWIP_IPV6
+  netif->output_ip6 = ethip6_output;
+#endif /* LWIP_IPV6 */
+  netif->linkoutput = bridgeif_output;
+
+  /* set MAC hardware address length */
+  netif->hwaddr_len = ETH_HWADDR_LEN;
+
+  /* set MAC hardware address */
+  memcpy(netif->hwaddr, &br->ethaddr, ETH_HWADDR_LEN);
+
+  /* maximum transfer unit */
+  netif->mtu = 1500;
+
+  /* device capabilities */
+  /* don't set NETIF_FLAG_ETHARP if this device is not an ethernet one */
+  netif->flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP | NETIF_FLAG_ETHERNET | NETIF_FLAG_IGMP | NETIF_FLAG_MLD6 | NETIF_FLAG_LINK_UP;
+
+#if LWIP_IPV6 && LWIP_IPV6_MLD
+  /*
+   * For hardware/netifs that implement MAC filtering.
+   * All-nodes link-local is handled by default, so we must let the hardware know
+   * to allow multicast packets in.
+   * Should set mld_mac_filter previously. */
+  if (netif->mld_mac_filter != NULL) {
+    ip6_addr_t ip6_allnodes_ll;
+    ip6_addr_set_allnodes_linklocal(&ip6_allnodes_ll);
+    netif->mld_mac_filter(netif, &ip6_allnodes_ll, NETIF_ADD_MAC_FILTER);
+  }
+#endif /* LWIP_IPV6 && LWIP_IPV6_MLD */
+
+  return ERR_OK;
+}
+
+/**
+ * @ingroup bridgeif
+ * Add a port to the bridge
+ */
+err_t
+bridgeif_add_port(struct netif *bridgeif, struct netif *portif)
+{
+  bridgeif_private_t *br;
+  bridgeif_port_t *port;
+
+  LWIP_ASSERT("bridgeif != NULL", bridgeif != NULL);
+  LWIP_ASSERT("bridgeif->state != NULL", bridgeif->state != NULL);
+  LWIP_ASSERT("portif != NULL", portif != NULL);
+
+  if (!(portif->flags & NETIF_FLAG_ETHARP) || !(portif->flags & NETIF_FLAG_ETHERNET)) {
+    /* can only add ETHERNET/ETHARP interfaces */
+    return ERR_VAL;
+  }
+
+  br = (bridgeif_private_t *)bridgeif->state;
+
+  if (br->num_ports >= br->max_ports) {
+    return ERR_VAL;
+  }
+  port = &br->ports[br->num_ports];
+  port->port_netif = portif;
+  port->port_num = br->num_ports;
+  port->bridge = br;
+  br->num_ports++;
+
+  /* let the port call us on input */
+#if BRIDGEIF_PORT_NETIFS_OUTPUT_DIRECT
+  portif->input = bridgeif_input;
+#else
+  portif->input = bridgeif_tcpip_input;
+#endif
+  /* store pointer to bridge in netif */
+  netif_set_client_data(portif, bridgeif_netif_client_id, port);
+  /* remove ETHARP flag to prevent sending report events on netif-up */
+  netif_clear_flags(portif, NETIF_FLAG_ETHARP);
+
+  return ERR_OK;
+}
+
+#endif /* LWIP_NUM_NETIF_CLIENT_DATA */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/netif/bridgeif_fdb.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/netif/bridgeif_fdb.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/netif/bridgeif_fdb.c	(revision 457)
@@ -0,0 +1,212 @@
+/**
+ * @file
+ * lwIP netif implementing an FDB for IEEE 802.1D MAC Bridge
+ */
+
+/*
+ * Copyright (c) 2017 Simon Goldschmidt.
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Simon Goldschmidt <goldsimon@gmx.de>
+ *
+ */
+
+/**
+ * @defgroup bridgeif_fdb FDB example code
+ * @ingroup bridgeif
+ * This file implements an example for an FDB (Forwarding DataBase)
+ */
+
+#include "netif/bridgeif.h"
+#include "lwip/sys.h"
+#include "lwip/mem.h"
+#include "lwip/timeouts.h"
+#include <string.h>
+
+#define BRIDGEIF_AGE_TIMER_MS 1000
+
+#define BR_FDB_TIMEOUT_SEC  (60*5) /* 5 minutes FDB timeout */
+
+typedef struct bridgeif_dfdb_entry_s {
+  u8_t used;
+  u8_t port;
+  u32_t ts;
+  struct eth_addr addr;
+} bridgeif_dfdb_entry_t;
+
+typedef struct bridgeif_dfdb_s {
+  u16_t max_fdb_entries;
+  bridgeif_dfdb_entry_t *fdb;
+} bridgeif_dfdb_t;
+
+/**
+ * @ingroup bridgeif_fdb
+ * A real simple and slow implementation of an auto-learning forwarding database that
+ * remembers known src mac addresses to know which port to send frames destined for that
+ * mac address.
+ *
+ * ATTENTION: This is meant as an example only, in real-world use, you should 
+ * provide a better implementation :-)
+ */
+void
+bridgeif_fdb_update_src(void *fdb_ptr, struct eth_addr *src_addr, u8_t port_idx)
+{
+  int i;
+  bridgeif_dfdb_t *fdb = (bridgeif_dfdb_t *)fdb_ptr;
+  BRIDGEIF_DECL_PROTECT(lev);
+  BRIDGEIF_READ_PROTECT(lev);
+  for (i = 0; i < fdb->max_fdb_entries; i++) {
+    bridgeif_dfdb_entry_t *e = &fdb->fdb[i];
+    if (e->used && e->ts) {
+      if (!memcmp(&e->addr, src_addr, sizeof(struct eth_addr))) {
+        LWIP_DEBUGF(BRIDGEIF_FDB_DEBUG, ("br: update src %02x:%02x:%02x:%02x:%02x:%02x (from %d) @ idx %d\n",
+                                         src_addr->addr[0], src_addr->addr[1], src_addr->addr[2], src_addr->addr[3], src_addr->addr[4], src_addr->addr[5],
+                                         port_idx, i));
+        BRIDGEIF_WRITE_PROTECT(lev);
+        e->ts = BR_FDB_TIMEOUT_SEC;
+        e->port = port_idx;
+        BRIDGEIF_WRITE_UNPROTECT(lev);
+        BRIDGEIF_READ_UNPROTECT(lev);
+        return;
+      }
+    }
+  }
+  /* not found, allocate new entry from free */
+  for (i = 0; i < fdb->max_fdb_entries; i++) {
+    bridgeif_dfdb_entry_t *e = &fdb->fdb[i];
+    if (!e->used || !e->ts) {
+      BRIDGEIF_WRITE_PROTECT(lev);
+      /* check again when protected */
+      if (!e->used || !e->ts) {
+        LWIP_DEBUGF(BRIDGEIF_FDB_DEBUG, ("br: create src %02x:%02x:%02x:%02x:%02x:%02x (from %d) @ idx %d\n",
+                                         src_addr->addr[0], src_addr->addr[1], src_addr->addr[2], src_addr->addr[3], src_addr->addr[4], src_addr->addr[5],
+                                         port_idx, i));
+        memcpy(&e->addr, src_addr, sizeof(struct eth_addr));
+        e->ts = BR_FDB_TIMEOUT_SEC;
+        e->port = port_idx;
+        e->used = 1;
+        BRIDGEIF_WRITE_UNPROTECT(lev);
+        BRIDGEIF_READ_UNPROTECT(lev);
+        return;
+      }
+      BRIDGEIF_WRITE_UNPROTECT(lev);
+    }
+  }
+  BRIDGEIF_READ_UNPROTECT(lev);
+  /* not found, no free entry -> flood */
+}
+
+/** 
+ * @ingroup bridgeif_fdb
+ * Walk our list of auto-learnt fdb entries and return a port to forward or BR_FLOOD if unknown 
+ */
+bridgeif_portmask_t
+bridgeif_fdb_get_dst_ports(void *fdb_ptr, struct eth_addr *dst_addr)
+{
+  int i;
+  bridgeif_dfdb_t *fdb = (bridgeif_dfdb_t *)fdb_ptr;
+  BRIDGEIF_DECL_PROTECT(lev);
+  BRIDGEIF_READ_PROTECT(lev);
+  for (i = 0; i < fdb->max_fdb_entries; i++) {
+    bridgeif_dfdb_entry_t *e = &fdb->fdb[i];
+    if (e->used && e->ts) {
+      if (!memcmp(&e->addr, dst_addr, sizeof(struct eth_addr))) {
+        bridgeif_portmask_t ret = (bridgeif_portmask_t)(1 << e->port);
+        BRIDGEIF_READ_UNPROTECT(lev);
+        return ret;
+      }
+    }
+  }
+  BRIDGEIF_READ_UNPROTECT(lev);
+  return BR_FLOOD;
+}
+
+/**
+ * @ingroup bridgeif_fdb
+ * Aging implementation of our simple fdb
+ */
+static void
+bridgeif_fdb_age_one_second(void *fdb_ptr)
+{
+  int i;
+  bridgeif_dfdb_t *fdb;
+  BRIDGEIF_DECL_PROTECT(lev);
+
+  fdb = (bridgeif_dfdb_t *)fdb_ptr;
+  BRIDGEIF_READ_PROTECT(lev);
+
+  for (i = 0; i < fdb->max_fdb_entries; i++) {
+    bridgeif_dfdb_entry_t *e = &fdb->fdb[i];
+    if (e->used && e->ts) {
+      BRIDGEIF_WRITE_PROTECT(lev);
+      /* check again when protected */
+      if (e->used && e->ts) {
+        if (--e->ts == 0) {
+          e->used = 0;
+        }
+      }
+      BRIDGEIF_WRITE_UNPROTECT(lev);
+    }
+  }
+  BRIDGEIF_READ_UNPROTECT(lev);
+}
+
+/** Timer callback for fdb aging, called once per second */
+static void
+bridgeif_age_tmr(void *arg)
+{
+  bridgeif_dfdb_t *fdb = (bridgeif_dfdb_t *)arg;
+
+  LWIP_ASSERT("invalid arg", arg != NULL);
+
+  bridgeif_fdb_age_one_second(fdb);
+  sys_timeout(BRIDGEIF_AGE_TIMER_MS, bridgeif_age_tmr, arg);
+}
+
+/**
+ * @ingroup bridgeif_fdb
+ * Init our simple fdb list
+ */
+void *
+bridgeif_fdb_init(u16_t max_fdb_entries)
+{
+  bridgeif_dfdb_t *fdb;
+  size_t alloc_len_sizet = sizeof(bridgeif_dfdb_t) + (max_fdb_entries * sizeof(bridgeif_dfdb_entry_t));
+  mem_size_t alloc_len = (mem_size_t)alloc_len_sizet;
+  LWIP_ASSERT("alloc_len == alloc_len_sizet", alloc_len == alloc_len_sizet);
+  LWIP_DEBUGF(BRIDGEIF_DEBUG, ("bridgeif_fdb_init: allocating %d bytes for private FDB data\n", (int)alloc_len));
+  fdb = (bridgeif_dfdb_t *)mem_calloc(1, alloc_len);
+  if (fdb == NULL) {
+    return NULL;
+  }
+  fdb->max_fdb_entries = max_fdb_entries;
+  fdb->fdb = (bridgeif_dfdb_entry_t *)(fdb + 1);
+
+  sys_timeout(BRIDGEIF_AGE_TIMER_MS, bridgeif_age_tmr, fdb);
+
+  return fdb;
+}
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/netif/ethernet.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/netif/ethernet.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/netif/ethernet.c	(revision 457)
@@ -0,0 +1,321 @@
+/**
+ * @file
+ * Ethernet common functions
+ *
+ * @defgroup ethernet Ethernet
+ * @ingroup callbackstyle_api
+ */
+
+/*
+ * Copyright (c) 2001-2003 Swedish Institute of Computer Science.
+ * Copyright (c) 2003-2004 Leon Woestenberg <leon.woestenberg@axon.tv>
+ * Copyright (c) 2003-2004 Axon Digital Design B.V., The Netherlands.
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ */
+
+#include "lwip/opt.h"
+
+#if LWIP_ARP || LWIP_ETHERNET
+
+#include "netif/ethernet.h"
+#include "lwip/def.h"
+#include "lwip/stats.h"
+#include "lwip/etharp.h"
+#include "lwip/ip.h"
+#include "lwip/snmp.h"
+
+#include <string.h>
+
+#include "netif/ppp/ppp_opts.h"
+#if PPPOE_SUPPORT
+#include "netif/ppp/pppoe.h"
+#endif /* PPPOE_SUPPORT */
+
+#ifdef LWIP_HOOK_FILENAME
+#include LWIP_HOOK_FILENAME
+#endif
+
+const struct eth_addr ethbroadcast = {{0xff, 0xff, 0xff, 0xff, 0xff, 0xff}};
+const struct eth_addr ethzero = {{0, 0, 0, 0, 0, 0}};
+
+/**
+ * @ingroup lwip_nosys
+ * Process received ethernet frames. Using this function instead of directly
+ * calling ip_input and passing ARP frames through etharp in ethernetif_input,
+ * the ARP cache is protected from concurrent access.\n
+ * Don't call directly, pass to netif_add() and call netif->input().
+ *
+ * @param p the received packet, p->payload pointing to the ethernet header
+ * @param netif the network interface on which the packet was received
+ *
+ * @see LWIP_HOOK_UNKNOWN_ETH_PROTOCOL
+ * @see ETHARP_SUPPORT_VLAN
+ * @see LWIP_HOOK_VLAN_CHECK
+ */
+err_t
+ethernet_input(struct pbuf *p, struct netif *netif)
+{
+  struct eth_hdr *ethhdr;
+  u16_t type;
+#if LWIP_ARP || ETHARP_SUPPORT_VLAN || LWIP_IPV6
+  u16_t next_hdr_offset = SIZEOF_ETH_HDR;
+#endif /* LWIP_ARP || ETHARP_SUPPORT_VLAN */
+
+  LWIP_ASSERT_CORE_LOCKED();
+
+  if (p->len <= SIZEOF_ETH_HDR) {
+    /* a packet with only an ethernet header (or less) is not valid for us */
+    ETHARP_STATS_INC(etharp.proterr);
+    ETHARP_STATS_INC(etharp.drop);
+    MIB2_STATS_NETIF_INC(netif, ifinerrors);
+    goto free_and_return;
+  }
+
+  if (p->if_idx == NETIF_NO_INDEX) {
+    p->if_idx = netif_get_index(netif);
+  }
+
+  /* points to packet payload, which starts with an Ethernet header */
+  ethhdr = (struct eth_hdr *)p->payload;
+  LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE,
+              ("ethernet_input: dest:%"X8_F":%"X8_F":%"X8_F":%"X8_F":%"X8_F":%"X8_F", src:%"X8_F":%"X8_F":%"X8_F":%"X8_F":%"X8_F":%"X8_F", type:%"X16_F"\n",
+               (unsigned char)ethhdr->dest.addr[0], (unsigned char)ethhdr->dest.addr[1], (unsigned char)ethhdr->dest.addr[2],
+               (unsigned char)ethhdr->dest.addr[3], (unsigned char)ethhdr->dest.addr[4], (unsigned char)ethhdr->dest.addr[5],
+               (unsigned char)ethhdr->src.addr[0],  (unsigned char)ethhdr->src.addr[1],  (unsigned char)ethhdr->src.addr[2],
+               (unsigned char)ethhdr->src.addr[3],  (unsigned char)ethhdr->src.addr[4],  (unsigned char)ethhdr->src.addr[5],
+               lwip_htons(ethhdr->type)));
+
+  type = ethhdr->type;
+#if ETHARP_SUPPORT_VLAN
+  if (type == PP_HTONS(ETHTYPE_VLAN)) {
+    struct eth_vlan_hdr *vlan = (struct eth_vlan_hdr *)(((char *)ethhdr) + SIZEOF_ETH_HDR);
+    next_hdr_offset = SIZEOF_ETH_HDR + SIZEOF_VLAN_HDR;
+    if (p->len <= SIZEOF_ETH_HDR + SIZEOF_VLAN_HDR) {
+      /* a packet with only an ethernet/vlan header (or less) is not valid for us */
+      ETHARP_STATS_INC(etharp.proterr);
+      ETHARP_STATS_INC(etharp.drop);
+      MIB2_STATS_NETIF_INC(netif, ifinerrors);
+      goto free_and_return;
+    }
+#if defined(LWIP_HOOK_VLAN_CHECK) || defined(ETHARP_VLAN_CHECK) || defined(ETHARP_VLAN_CHECK_FN) /* if not, allow all VLANs */
+#ifdef LWIP_HOOK_VLAN_CHECK
+    if (!LWIP_HOOK_VLAN_CHECK(netif, ethhdr, vlan)) {
+#elif defined(ETHARP_VLAN_CHECK_FN)
+    if (!ETHARP_VLAN_CHECK_FN(ethhdr, vlan)) {
+#elif defined(ETHARP_VLAN_CHECK)
+    if (VLAN_ID(vlan) != ETHARP_VLAN_CHECK) {
+#endif
+      /* silently ignore this packet: not for our VLAN */
+      pbuf_free(p);
+      return ERR_OK;
+    }
+#endif /* defined(LWIP_HOOK_VLAN_CHECK) || defined(ETHARP_VLAN_CHECK) || defined(ETHARP_VLAN_CHECK_FN) */
+    type = vlan->tpid;
+  }
+#endif /* ETHARP_SUPPORT_VLAN */
+
+#if LWIP_ARP_FILTER_NETIF
+  netif = LWIP_ARP_FILTER_NETIF_FN(p, netif, lwip_htons(type));
+#endif /* LWIP_ARP_FILTER_NETIF*/
+
+  if (ethhdr->dest.addr[0] & 1) {
+    /* this might be a multicast or broadcast packet */
+    if (ethhdr->dest.addr[0] == LL_IP4_MULTICAST_ADDR_0) {
+#if LWIP_IPV4
+      if ((ethhdr->dest.addr[1] == LL_IP4_MULTICAST_ADDR_1) &&
+          (ethhdr->dest.addr[2] == LL_IP4_MULTICAST_ADDR_2)) {
+        /* mark the pbuf as link-layer multicast */
+        p->flags |= PBUF_FLAG_LLMCAST;
+      }
+#endif /* LWIP_IPV4 */
+    }
+#if LWIP_IPV6
+    else if ((ethhdr->dest.addr[0] == LL_IP6_MULTICAST_ADDR_0) &&
+             (ethhdr->dest.addr[1] == LL_IP6_MULTICAST_ADDR_1)) {
+      /* mark the pbuf as link-layer multicast */
+      p->flags |= PBUF_FLAG_LLMCAST;
+    }
+#endif /* LWIP_IPV6 */
+    else if (eth_addr_cmp(&ethhdr->dest, &ethbroadcast)) {
+      /* mark the pbuf as link-layer broadcast */
+      p->flags |= PBUF_FLAG_LLBCAST;
+    }
+  }
+
+  switch (type) {
+#if LWIP_IPV4 && LWIP_ARP
+    /* IP packet? */
+    case PP_HTONS(ETHTYPE_IP):
+      if (!(netif->flags & NETIF_FLAG_ETHARP)) {
+        goto free_and_return;
+      }
+      /* skip Ethernet header (min. size checked above) */
+      if (pbuf_remove_header(p, next_hdr_offset)) {
+        LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_WARNING,
+                    ("ethernet_input: IPv4 packet dropped, too short (%"U16_F"/%"U16_F")\n",
+                     p->tot_len, next_hdr_offset));
+        LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("Can't move over header in packet"));
+        goto free_and_return;
+      } else {
+        /* pass to IP layer */
+        ip4_input(p, netif);
+      }
+      break;
+
+    case PP_HTONS(ETHTYPE_ARP):
+      if (!(netif->flags & NETIF_FLAG_ETHARP)) {
+        goto free_and_return;
+      }
+      /* skip Ethernet header (min. size checked above) */
+      if (pbuf_remove_header(p, next_hdr_offset)) {
+        LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_WARNING,
+                    ("ethernet_input: ARP response packet dropped, too short (%"U16_F"/%"U16_F")\n",
+                     p->tot_len, next_hdr_offset));
+        LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("Can't move over header in packet"));
+        ETHARP_STATS_INC(etharp.lenerr);
+        ETHARP_STATS_INC(etharp.drop);
+        goto free_and_return;
+      } else {
+        /* pass p to ARP module */
+        etharp_input(p, netif);
+      }
+      break;
+#endif /* LWIP_IPV4 && LWIP_ARP */
+#if PPPOE_SUPPORT
+    case PP_HTONS(ETHTYPE_PPPOEDISC): /* PPP Over Ethernet Discovery Stage */
+      pppoe_disc_input(netif, p);
+      break;
+
+    case PP_HTONS(ETHTYPE_PPPOE): /* PPP Over Ethernet Session Stage */
+      pppoe_data_input(netif, p);
+      break;
+#endif /* PPPOE_SUPPORT */
+
+#if LWIP_IPV6
+    case PP_HTONS(ETHTYPE_IPV6): /* IPv6 */
+      /* skip Ethernet header */
+      if ((p->len < next_hdr_offset) || pbuf_remove_header(p, next_hdr_offset)) {
+        LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_WARNING,
+                    ("ethernet_input: IPv6 packet dropped, too short (%"U16_F"/%"U16_F")\n",
+                     p->tot_len, next_hdr_offset));
+        goto free_and_return;
+      } else {
+        /* pass to IPv6 layer */
+        ip6_input(p, netif);
+      }
+      break;
+#endif /* LWIP_IPV6 */
+
+    default:
+#ifdef LWIP_HOOK_UNKNOWN_ETH_PROTOCOL
+      if (LWIP_HOOK_UNKNOWN_ETH_PROTOCOL(p, netif) == ERR_OK) {
+        break;
+      }
+#endif
+      ETHARP_STATS_INC(etharp.proterr);
+      ETHARP_STATS_INC(etharp.drop);
+      MIB2_STATS_NETIF_INC(netif, ifinunknownprotos);
+      goto free_and_return;
+  }
+
+  /* This means the pbuf is freed or consumed,
+     so the caller doesn't have to free it again */
+  return ERR_OK;
+
+free_and_return:
+  pbuf_free(p);
+  return ERR_OK;
+}
+
+/**
+ * @ingroup ethernet
+ * Send an ethernet packet on the network using netif->linkoutput().
+ * The ethernet header is filled in before sending.
+ *
+ * @see LWIP_HOOK_VLAN_SET
+ *
+ * @param netif the lwIP network interface on which to send the packet
+ * @param p the packet to send. pbuf layer must be @ref PBUF_LINK.
+ * @param src the source MAC address to be copied into the ethernet header
+ * @param dst the destination MAC address to be copied into the ethernet header
+ * @param eth_type ethernet type (@ref lwip_ieee_eth_type)
+ * @return ERR_OK if the packet was sent, any other err_t on failure
+ */
+err_t
+ethernet_output(struct netif * netif, struct pbuf * p,
+                const struct eth_addr * src, const struct eth_addr * dst,
+                u16_t eth_type) {
+  struct eth_hdr *ethhdr;
+  u16_t eth_type_be = lwip_htons(eth_type);
+
+#if ETHARP_SUPPORT_VLAN && defined(LWIP_HOOK_VLAN_SET)
+  s32_t vlan_prio_vid = LWIP_HOOK_VLAN_SET(netif, p, src, dst, eth_type);
+  if (vlan_prio_vid >= 0) {
+    struct eth_vlan_hdr *vlanhdr;
+
+    LWIP_ASSERT("prio_vid must be <= 0xFFFF", vlan_prio_vid <= 0xFFFF);
+
+    if (pbuf_add_header(p, SIZEOF_ETH_HDR + SIZEOF_VLAN_HDR) != 0) {
+      goto pbuf_header_failed;
+    }
+    vlanhdr = (struct eth_vlan_hdr *)(((u8_t *)p->payload) + SIZEOF_ETH_HDR);
+    vlanhdr->tpid     = eth_type_be;
+    vlanhdr->prio_vid = lwip_htons((u16_t)vlan_prio_vid);
+
+    eth_type_be = PP_HTONS(ETHTYPE_VLAN);
+  } else
+#endif /* ETHARP_SUPPORT_VLAN && defined(LWIP_HOOK_VLAN_SET) */
+  {
+    if (pbuf_add_header(p, SIZEOF_ETH_HDR) != 0) {
+      goto pbuf_header_failed;
+    }
+  }
+
+  LWIP_ASSERT_CORE_LOCKED();
+
+  ethhdr = (struct eth_hdr *)p->payload;
+  ethhdr->type = eth_type_be;
+  SMEMCPY(&ethhdr->dest, dst, ETH_HWADDR_LEN);
+  SMEMCPY(&ethhdr->src,  src, ETH_HWADDR_LEN);
+
+  LWIP_ASSERT("netif->hwaddr_len must be 6 for ethernet_output!",
+              (netif->hwaddr_len == ETH_HWADDR_LEN));
+  LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE,
+              ("ethernet_output: sending packet %p\n", (void *)p));
+
+  /* send the packet */
+  return netif->linkoutput(netif, p);
+
+pbuf_header_failed:
+  LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS,
+              ("ethernet_output: could not allocate room for header.\n"));
+  LINK_STATS_INC(link.lenerr);
+  return ERR_BUF;
+}
+
+#endif /* LWIP_ARP || LWIP_ETHERNET */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/netif/lowpan6.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/netif/lowpan6.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/netif/lowpan6.c	(revision 457)
@@ -0,0 +1,920 @@
+/**
+ * @file
+ *
+ * 6LowPAN output for IPv6. Uses ND tables for link-layer addressing. Fragments packets to 6LowPAN units.
+ *
+ * This implementation aims to conform to IEEE 802.15.4(-2015), RFC 4944 and RFC 6282.
+ * @todo: RFC 6775.
+ */
+
+/*
+ * Copyright (c) 2015 Inico Technologies Ltd.
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Ivan Delamer <delamer@inicotech.com>
+ *
+ *
+ * Please coordinate changes and requests with Ivan Delamer
+ * <delamer@inicotech.com>
+ */
+
+/**
+ * @defgroup sixlowpan 6LoWPAN (RFC4944)
+ * @ingroup netifs
+ * 6LowPAN netif implementation
+ */
+
+#include "netif/lowpan6.h"
+
+#if LWIP_IPV6
+
+#include "lwip/ip.h"
+#include "lwip/pbuf.h"
+#include "lwip/ip_addr.h"
+#include "lwip/netif.h"
+#include "lwip/nd6.h"
+#include "lwip/mem.h"
+#include "lwip/udp.h"
+#include "lwip/tcpip.h"
+#include "lwip/snmp.h"
+#include "netif/ieee802154.h"
+
+#include <string.h>
+
+#if LWIP_6LOWPAN_802154_HW_CRC
+#define LWIP_6LOWPAN_DO_CALC_CRC(buf, len) 0
+#else
+#define LWIP_6LOWPAN_DO_CALC_CRC(buf, len) LWIP_6LOWPAN_CALC_CRC(buf, len)
+#endif
+
+/** This is a helper struct for reassembly of fragments
+ * (IEEE 802.15.4 limits to 127 bytes)
+ */
+struct lowpan6_reass_helper {
+  struct lowpan6_reass_helper *next_packet;
+  struct pbuf *reass;
+  struct pbuf *frags;
+  u8_t timer;
+  struct lowpan6_link_addr sender_addr;
+  u16_t datagram_size;
+  u16_t datagram_tag;
+};
+
+/** This struct keeps track of per-netif state */
+struct lowpan6_ieee802154_data {
+  /** fragment reassembly list */
+  struct lowpan6_reass_helper *reass_list;
+#if LWIP_6LOWPAN_NUM_CONTEXTS > 0
+  /** address context for compression */
+  ip6_addr_t lowpan6_context[LWIP_6LOWPAN_NUM_CONTEXTS];
+#endif
+  /** Datagram Tag for fragmentation */
+  u16_t tx_datagram_tag;
+  /** local PAN ID for IEEE 802.15.4 header */
+  u16_t ieee_802154_pan_id;
+  /** Sequence Number for IEEE 802.15.4 transmission */
+  u8_t tx_frame_seq_num;
+};
+
+/* Maximum frame size is 127 bytes minus CRC size */
+#define LOWPAN6_MAX_PAYLOAD (127 - 2)
+
+/** Currently, this state is global, since there's only one 6LoWPAN netif */
+static struct lowpan6_ieee802154_data lowpan6_data;
+
+#if LWIP_6LOWPAN_NUM_CONTEXTS > 0
+#define LWIP_6LOWPAN_CONTEXTS(netif) lowpan6_data.lowpan6_context
+#else
+#define LWIP_6LOWPAN_CONTEXTS(netif) NULL
+#endif
+
+static const struct lowpan6_link_addr ieee_802154_broadcast = {2, {0xff, 0xff}};
+
+#if LWIP_6LOWPAN_INFER_SHORT_ADDRESS
+static struct lowpan6_link_addr short_mac_addr = {2, {0, 0}};
+#endif /* LWIP_6LOWPAN_INFER_SHORT_ADDRESS */
+
+/* IEEE 802.15.4 specific functions: */
+
+/** Write the IEEE 802.15.4 header that encapsulates the 6LoWPAN frame.
+ * Src and dst PAN IDs are filled with the ID set by @ref lowpan6_set_pan_id.
+ *
+ * Since the length is variable:
+ * @returns the header length
+ */
+static u8_t
+lowpan6_write_iee802154_header(struct ieee_802154_hdr *hdr, const struct lowpan6_link_addr *src,
+                               const struct lowpan6_link_addr *dst)
+{
+  u8_t ieee_header_len;
+  u8_t *buffer;
+  u8_t i;
+  u16_t fc;
+
+  fc = IEEE_802154_FC_FT_DATA; /* send data packet (2003 frame version) */
+  fc |= IEEE_802154_FC_PANID_COMPR; /* set PAN ID compression, for now src and dst PANs are equal */
+  if (dst != &ieee_802154_broadcast) {
+    fc |= IEEE_802154_FC_ACK_REQ; /* data packet, no broadcast: ack required. */
+  }
+  if (dst->addr_len == 2) {
+    fc |= IEEE_802154_FC_DST_ADDR_MODE_SHORT;
+  } else {
+    LWIP_ASSERT("invalid dst address length", dst->addr_len == 8);
+    fc |= IEEE_802154_FC_DST_ADDR_MODE_EXT;
+  }
+  if (src->addr_len == 2) {
+    fc |= IEEE_802154_FC_SRC_ADDR_MODE_SHORT;
+  } else {
+    LWIP_ASSERT("invalid src address length", src->addr_len == 8);
+    fc |= IEEE_802154_FC_SRC_ADDR_MODE_EXT;
+  }
+  hdr->frame_control = fc;
+  hdr->sequence_number = lowpan6_data.tx_frame_seq_num++;
+  hdr->destination_pan_id = lowpan6_data.ieee_802154_pan_id; /* pan id */
+
+  buffer = (u8_t *)hdr;
+  ieee_header_len = 5;
+  i = dst->addr_len;
+  /* reverse memcpy of dst addr */
+  while (i-- > 0) {
+    buffer[ieee_header_len++] = dst->addr[i];
+  }
+  /* Source PAN ID skipped due to PAN ID Compression */
+  i = src->addr_len;
+  /* reverse memcpy of src addr */
+  while (i-- > 0) {
+    buffer[ieee_header_len++] = src->addr[i];
+  }
+  return ieee_header_len;
+}
+
+/** Parse the IEEE 802.15.4 header from a pbuf.
+ * If successful, the header is hidden from the pbuf.
+ *
+ * PAN IDs and seuqence number are not checked
+ *
+ * @param p input pbuf, p->payload pointing at the IEEE 802.15.4 header
+ * @param src pointer to source address filled from the header
+ * @param dest pointer to destination address filled from the header
+ * @returns ERR_OK if successful
+ */
+static err_t
+lowpan6_parse_iee802154_header(struct pbuf *p, struct lowpan6_link_addr *src,
+                               struct lowpan6_link_addr *dest)
+{
+  u8_t *puc;
+  s8_t i;
+  u16_t frame_control, addr_mode;
+  u16_t datagram_offset;
+
+  /* Parse IEEE 802.15.4 header */
+  puc = (u8_t *)p->payload;
+  frame_control = puc[0] | (puc[1] << 8);
+  datagram_offset = 2;
+  if (frame_control & IEEE_802154_FC_SEQNO_SUPPR) {
+    if (IEEE_802154_FC_FRAME_VERSION_GET(frame_control) <= 1) {
+      /* sequence number suppressed, this is not valid for versions 0/1 */
+      return ERR_VAL;
+    }
+  } else {
+    datagram_offset++;
+  }
+  datagram_offset += 2; /* Skip destination PAN ID */
+  addr_mode = frame_control & IEEE_802154_FC_DST_ADDR_MODE_MASK;
+  if (addr_mode == IEEE_802154_FC_DST_ADDR_MODE_EXT) {
+    /* extended address (64 bit) */
+    dest->addr_len = 8;
+    /* reverse memcpy: */
+    for (i = 0; i < 8; i++) {
+      dest->addr[i] = puc[datagram_offset + 7 - i];
+    }
+    datagram_offset += 8;
+  } else if (addr_mode == IEEE_802154_FC_DST_ADDR_MODE_SHORT) {
+    /* short address (16 bit) */
+    dest->addr_len = 2;
+    /* reverse memcpy: */
+    dest->addr[0] = puc[datagram_offset + 1];
+    dest->addr[1] = puc[datagram_offset];
+    datagram_offset += 2;
+  } else {
+    /* unsupported address mode (do we need "no address"?) */
+    return ERR_VAL;
+  }
+
+  if (!(frame_control & IEEE_802154_FC_PANID_COMPR)) {
+    /* No PAN ID compression, skip source PAN ID */
+    datagram_offset += 2;
+  }
+
+  addr_mode = frame_control & IEEE_802154_FC_SRC_ADDR_MODE_MASK;
+  if (addr_mode == IEEE_802154_FC_SRC_ADDR_MODE_EXT) {
+    /* extended address (64 bit) */
+    src->addr_len = 8;
+    /* reverse memcpy: */
+    for (i = 0; i < 8; i++) {
+      src->addr[i] = puc[datagram_offset + 7 - i];
+    }
+    datagram_offset += 8;
+  } else if (addr_mode == IEEE_802154_FC_DST_ADDR_MODE_SHORT) {
+    /* short address (16 bit) */
+    src->addr_len = 2;
+    src->addr[0] = puc[datagram_offset + 1];
+    src->addr[1] = puc[datagram_offset];
+    datagram_offset += 2;
+  } else {
+    /* unsupported address mode (do we need "no address"?) */
+    return ERR_VAL;
+  }
+
+  /* hide IEEE802.15.4 header. */
+  if (pbuf_remove_header(p, datagram_offset)) {
+    return ERR_VAL;
+  }
+  return ERR_OK;
+}
+
+/** Calculate the 16-bit CRC as required by IEEE 802.15.4 */
+u16_t
+lowpan6_calc_crc(const void* buf, u16_t len)
+{
+#define CCITT_POLY_16 0x8408U
+  u16_t i;
+  u8_t b;
+  u16_t crc = 0;
+  const u8_t* p = (const u8_t*)buf;
+
+  for (i = 0; i < len; i++) {
+    u8_t data = *p;
+    for (b = 0U; b < 8U; b++) {
+      if (((data ^ crc) & 1) != 0) {
+        crc = (u16_t)((crc >> 1) ^ CCITT_POLY_16);
+      } else {
+        crc = (u16_t)(crc >> 1);
+      }
+      data = (u8_t)(data >> 1);
+    }
+    p++;
+  }
+  return crc;
+}
+
+/* Fragmentation specific functions: */
+
+static void
+free_reass_datagram(struct lowpan6_reass_helper *lrh)
+{
+  if (lrh->reass) {
+    pbuf_free(lrh->reass);
+  }
+  if (lrh->frags) {
+    pbuf_free(lrh->frags);
+  }
+  mem_free(lrh);
+}
+
+/**
+ * Removes a datagram from the reassembly queue.
+ **/
+static void
+dequeue_datagram(struct lowpan6_reass_helper *lrh, struct lowpan6_reass_helper *prev)
+{
+  if (lowpan6_data.reass_list == lrh) {
+    lowpan6_data.reass_list = lowpan6_data.reass_list->next_packet;
+  } else {
+    /* it wasn't the first, so it must have a valid 'prev' */
+    LWIP_ASSERT("sanity check linked list", prev != NULL);
+    prev->next_packet = lrh->next_packet;
+  }
+}
+
+/**
+ * Periodic timer for 6LowPAN functions:
+ *
+ * - Remove incomplete/old packets
+ */
+void
+lowpan6_tmr(void)
+{
+  struct lowpan6_reass_helper *lrh, *lrh_next, *lrh_prev = NULL;
+
+  lrh = lowpan6_data.reass_list;
+  while (lrh != NULL) {
+    lrh_next = lrh->next_packet;
+    if ((--lrh->timer) == 0) {
+      dequeue_datagram(lrh, lrh_prev);
+      free_reass_datagram(lrh);
+    } else {
+      lrh_prev = lrh;
+    }
+    lrh = lrh_next;
+  }
+}
+
+/*
+ * Encapsulates data into IEEE 802.15.4 frames.
+ * Fragments an IPv6 datagram into 6LowPAN units, which fit into IEEE 802.15.4 frames.
+ * If configured, will compress IPv6 and or UDP headers.
+ * */
+static err_t
+lowpan6_frag(struct netif *netif, struct pbuf *p, const struct lowpan6_link_addr *src, const struct lowpan6_link_addr *dst)
+{
+  struct pbuf *p_frag;
+  u16_t frag_len, remaining_len, max_data_len;
+  u8_t *buffer;
+  u8_t ieee_header_len;
+  u8_t lowpan6_header_len;
+  u8_t hidden_header_len;
+  u16_t crc;
+  u16_t datagram_offset;
+  err_t err = ERR_IF;
+
+  LWIP_ASSERT("lowpan6_frag: netif->linkoutput not set", netif->linkoutput != NULL);
+
+  /* We'll use a dedicated pbuf for building 6LowPAN fragments. */
+  p_frag = pbuf_alloc(PBUF_RAW, 127, PBUF_RAM);
+  if (p_frag == NULL) {
+    MIB2_STATS_NETIF_INC(netif, ifoutdiscards);
+    return ERR_MEM;
+  }
+  LWIP_ASSERT("this needs a pbuf in one piece", p_frag->len == p_frag->tot_len);
+
+  /* Write IEEE 802.15.4 header. */
+  buffer = (u8_t *)p_frag->payload;
+  ieee_header_len = lowpan6_write_iee802154_header((struct ieee_802154_hdr *)buffer, src, dst);
+  LWIP_ASSERT("ieee_header_len < p_frag->len", ieee_header_len < p_frag->len);
+
+#if LWIP_6LOWPAN_IPHC
+  /* Perform 6LowPAN IPv6 header compression according to RFC 6282 */
+  /* do the header compression (this does NOT copy any non-compressed data) */
+  err = lowpan6_compress_headers(netif, (u8_t *)p->payload, p->len,
+    &buffer[ieee_header_len], p_frag->len - ieee_header_len, &lowpan6_header_len,
+    &hidden_header_len, LWIP_6LOWPAN_CONTEXTS(netif), src, dst);
+  if (err != ERR_OK) {
+    MIB2_STATS_NETIF_INC(netif, ifoutdiscards);
+    pbuf_free(p_frag);
+    return err;
+  }
+  pbuf_remove_header(p, hidden_header_len);
+
+#else /* LWIP_6LOWPAN_IPHC */
+  /* Send uncompressed IPv6 header with appropriate dispatch byte. */
+  lowpan6_header_len = 1;
+  buffer[ieee_header_len] = 0x41; /* IPv6 dispatch */
+#endif /* LWIP_6LOWPAN_IPHC */
+
+  /* Calculate remaining packet length */
+  remaining_len = p->tot_len;
+
+  if (remaining_len > 0x7FF) {
+    MIB2_STATS_NETIF_INC(netif, ifoutdiscards);
+    /* datagram_size must fit into 11 bit */
+    pbuf_free(p_frag);
+    return ERR_VAL;
+  }
+
+  /* Fragment, or 1 packet? */
+  max_data_len = LOWPAN6_MAX_PAYLOAD - ieee_header_len - lowpan6_header_len;
+  if (remaining_len > max_data_len) {
+    u16_t data_len;
+    /* We must move the 6LowPAN header to make room for the FRAG header. */
+    memmove(&buffer[ieee_header_len + 4], &buffer[ieee_header_len], lowpan6_header_len);
+
+    /* Now we need to fragment the packet. FRAG1 header first */
+    buffer[ieee_header_len] = 0xc0 | (((p->tot_len + hidden_header_len) >> 8) & 0x7);
+    buffer[ieee_header_len + 1] = (p->tot_len + hidden_header_len) & 0xff;
+
+    lowpan6_data.tx_datagram_tag++;
+    buffer[ieee_header_len + 2] = (lowpan6_data.tx_datagram_tag >> 8) & 0xff;
+    buffer[ieee_header_len + 3] = lowpan6_data.tx_datagram_tag & 0xff;
+
+    /* Fragment follows. */
+    data_len = (max_data_len - 4) & 0xf8;
+    frag_len = data_len + lowpan6_header_len;
+
+    pbuf_copy_partial(p, buffer + ieee_header_len + lowpan6_header_len + 4, frag_len - lowpan6_header_len, 0);
+    remaining_len -= frag_len - lowpan6_header_len;
+    /* datagram offset holds the offset before compression */
+    datagram_offset = frag_len - lowpan6_header_len + hidden_header_len;
+    LWIP_ASSERT("datagram offset must be a multiple of 8", (datagram_offset & 7) == 0);
+
+    /* Calculate frame length */
+    p_frag->len = p_frag->tot_len = ieee_header_len + 4 + frag_len + 2; /* add 2 bytes for crc*/
+
+    /* 2 bytes CRC */
+    crc = LWIP_6LOWPAN_DO_CALC_CRC(p_frag->payload, p_frag->len - 2);
+    pbuf_take_at(p_frag, &crc, 2, p_frag->len - 2);
+
+    /* send the packet */
+    MIB2_STATS_NETIF_ADD(netif, ifoutoctets, p_frag->tot_len);
+    LWIP_DEBUGF(LWIP_LOWPAN6_DEBUG | LWIP_DBG_TRACE, ("lowpan6_send: sending packet %p\n", (void *)p));
+    err = netif->linkoutput(netif, p_frag);
+
+    while ((remaining_len > 0) && (err == ERR_OK)) {
+      struct ieee_802154_hdr *hdr = (struct ieee_802154_hdr *)buffer;
+      /* new frame, new seq num for ACK */
+      hdr->sequence_number = lowpan6_data.tx_frame_seq_num++;
+
+      buffer[ieee_header_len] |= 0x20; /* Change FRAG1 to FRAGN */
+
+      LWIP_ASSERT("datagram offset must be a multiple of 8", (datagram_offset & 7) == 0);
+      buffer[ieee_header_len + 4] = (u8_t)(datagram_offset >> 3); /* datagram offset in FRAGN header (datagram_offset is max. 11 bit) */
+
+      frag_len = (127 - ieee_header_len - 5 - 2) & 0xf8;
+      if (frag_len > remaining_len) {
+        frag_len = remaining_len;
+      }
+
+      pbuf_copy_partial(p, buffer + ieee_header_len + 5, frag_len, p->tot_len - remaining_len);
+      remaining_len -= frag_len;
+      datagram_offset += frag_len;
+
+      /* Calculate frame length */
+      p_frag->len = p_frag->tot_len = frag_len + 5 + ieee_header_len + 2;
+
+      /* 2 bytes CRC */
+      crc = LWIP_6LOWPAN_DO_CALC_CRC(p_frag->payload, p_frag->len - 2);
+      pbuf_take_at(p_frag, &crc, 2, p_frag->len - 2);
+
+      /* send the packet */
+      MIB2_STATS_NETIF_ADD(netif, ifoutoctets, p_frag->tot_len);
+      LWIP_DEBUGF(LWIP_LOWPAN6_DEBUG | LWIP_DBG_TRACE, ("lowpan6_send: sending packet %p\n", (void *)p));
+      err = netif->linkoutput(netif, p_frag);
+    }
+  } else {
+    /* It fits in one frame. */
+    frag_len = remaining_len;
+
+    /* Copy IPv6 packet */
+    pbuf_copy_partial(p, buffer + ieee_header_len + lowpan6_header_len, frag_len, 0);
+    remaining_len = 0;
+
+    /* Calculate frame length */
+    p_frag->len = p_frag->tot_len = frag_len + lowpan6_header_len + ieee_header_len + 2;
+    LWIP_ASSERT("", p_frag->len <= 127);
+
+    /* 2 bytes CRC */
+    crc = LWIP_6LOWPAN_DO_CALC_CRC(p_frag->payload, p_frag->len - 2);
+    pbuf_take_at(p_frag, &crc, 2, p_frag->len - 2);
+
+    /* send the packet */
+    MIB2_STATS_NETIF_ADD(netif, ifoutoctets, p_frag->tot_len);
+    LWIP_DEBUGF(LWIP_LOWPAN6_DEBUG | LWIP_DBG_TRACE, ("lowpan6_send: sending packet %p\n", (void *)p));
+    err = netif->linkoutput(netif, p_frag);
+  }
+
+  pbuf_free(p_frag);
+
+  return err;
+}
+
+/**
+ * @ingroup sixlowpan
+ * Set context
+ */
+err_t
+lowpan6_set_context(u8_t idx, const ip6_addr_t *context)
+{
+#if LWIP_6LOWPAN_NUM_CONTEXTS > 0
+  if (idx >= LWIP_6LOWPAN_NUM_CONTEXTS) {
+    return ERR_ARG;
+  }
+
+  IP6_ADDR_ZONECHECK(context);
+
+  ip6_addr_set(&lowpan6_data.lowpan6_context[idx], context);
+
+  return ERR_OK;
+#else
+  LWIP_UNUSED_ARG(idx);
+  LWIP_UNUSED_ARG(context);
+  return ERR_ARG;
+#endif
+}
+
+#if LWIP_6LOWPAN_INFER_SHORT_ADDRESS
+/**
+ * @ingroup sixlowpan
+ * Set short address
+ */
+err_t
+lowpan6_set_short_addr(u8_t addr_high, u8_t addr_low)
+{
+  short_mac_addr.addr[0] = addr_high;
+  short_mac_addr.addr[1] = addr_low;
+
+  return ERR_OK;
+}
+#endif /* LWIP_6LOWPAN_INFER_SHORT_ADDRESS */
+
+/* Create IEEE 802.15.4 address from netif address */
+static err_t
+lowpan6_hwaddr_to_addr(struct netif *netif, struct lowpan6_link_addr *addr)
+{
+  addr->addr_len = 8;
+  if (netif->hwaddr_len == 8) {
+    LWIP_ERROR("NETIF_MAX_HWADDR_LEN >= 8 required", sizeof(netif->hwaddr) >= 8, return ERR_VAL;);
+    SMEMCPY(addr->addr, netif->hwaddr, 8);
+  } else if (netif->hwaddr_len == 6) {
+    /* Copy from MAC-48 */
+    SMEMCPY(addr->addr, netif->hwaddr, 3);
+    addr->addr[3] = addr->addr[4] = 0xff;
+    SMEMCPY(&addr->addr[5], &netif->hwaddr[3], 3);
+  } else {
+    /* Invalid address length, don't know how to convert this */
+    return ERR_VAL;
+  }
+  return ERR_OK;
+}
+
+/**
+ * @ingroup sixlowpan
+ * Resolve and fill-in IEEE 802.15.4 address header for outgoing IPv6 packet.
+ *
+ * Perform Header Compression and fragment if necessary.
+ *
+ * @param netif The lwIP network interface which the IP packet will be sent on.
+ * @param q The pbuf(s) containing the IP packet to be sent.
+ * @param ip6addr The IP address of the packet destination.
+ *
+ * @return err_t
+ */
+err_t
+lowpan6_output(struct netif *netif, struct pbuf *q, const ip6_addr_t *ip6addr)
+{
+  err_t result;
+  const u8_t *hwaddr;
+  struct lowpan6_link_addr src, dest;
+#if LWIP_6LOWPAN_INFER_SHORT_ADDRESS
+  ip6_addr_t ip6_src;
+  struct ip6_hdr *ip6_hdr;
+#endif /* LWIP_6LOWPAN_INFER_SHORT_ADDRESS */
+
+#if LWIP_6LOWPAN_INFER_SHORT_ADDRESS
+  /* Check if we can compress source address (use aligned copy) */
+  ip6_hdr = (struct ip6_hdr *)q->payload;
+  ip6_addr_copy_from_packed(ip6_src, ip6_hdr->src);
+  ip6_addr_assign_zone(&ip6_src, IP6_UNICAST, netif);
+  if (lowpan6_get_address_mode(&ip6_src, &short_mac_addr) == 3) {
+    src.addr_len = 2;
+    src.addr[0] = short_mac_addr.addr[0];
+    src.addr[1] = short_mac_addr.addr[1];
+  } else
+#endif /* LWIP_6LOWPAN_INFER_SHORT_ADDRESS */
+  {
+    result = lowpan6_hwaddr_to_addr(netif, &src);
+    if (result != ERR_OK) {
+      MIB2_STATS_NETIF_INC(netif, ifoutdiscards);
+      return result;
+    }
+  }
+
+  /* multicast destination IP address? */
+  if (ip6_addr_ismulticast(ip6addr)) {
+    MIB2_STATS_NETIF_INC(netif, ifoutnucastpkts);
+    /* We need to send to the broadcast address.*/
+    return lowpan6_frag(netif, q, &src, &ieee_802154_broadcast);
+  }
+
+  /* We have a unicast destination IP address */
+  /* @todo anycast? */
+
+#if LWIP_6LOWPAN_INFER_SHORT_ADDRESS
+  if (src.addr_len == 2) {
+    /* If source address was compressable to short_mac_addr, and dest has same subnet and
+     * is also compressable to 2-bytes, assume we can infer dest as a short address too. */
+    dest.addr_len = 2;
+    dest.addr[0] = ((u8_t *)q->payload)[38];
+    dest.addr[1] = ((u8_t *)q->payload)[39];
+    if ((src.addr_len == 2) && (ip6_addr_netcmp_zoneless(&ip6_hdr->src, &ip6_hdr->dest)) &&
+        (lowpan6_get_address_mode(ip6addr, &dest) == 3)) {
+      MIB2_STATS_NETIF_INC(netif, ifoutucastpkts);
+      return lowpan6_frag(netif, q, &src, &dest);
+    }
+  }
+#endif /* LWIP_6LOWPAN_INFER_SHORT_ADDRESS */
+
+  /* Ask ND6 what to do with the packet. */
+  result = nd6_get_next_hop_addr_or_queue(netif, q, ip6addr, &hwaddr);
+  if (result != ERR_OK) {
+    MIB2_STATS_NETIF_INC(netif, ifoutdiscards);
+    return result;
+  }
+
+  /* If no hardware address is returned, nd6 has queued the packet for later. */
+  if (hwaddr == NULL) {
+    return ERR_OK;
+  }
+
+  /* Send out the packet using the returned hardware address. */
+  dest.addr_len = netif->hwaddr_len;
+  /* XXX: Inferring the length of the source address from the destination address
+   * is not correct for IEEE 802.15.4, but currently we don't get this information
+   * from the neighbor cache */
+  SMEMCPY(dest.addr, hwaddr, netif->hwaddr_len);
+  MIB2_STATS_NETIF_INC(netif, ifoutucastpkts);
+  return lowpan6_frag(netif, q, &src, &dest);
+}
+/**
+ * @ingroup sixlowpan
+ * NETIF input function: don't free the input pbuf when returning != ERR_OK!
+ */
+err_t
+lowpan6_input(struct pbuf *p, struct netif *netif)
+{
+  u8_t *puc, b;
+  s8_t i;
+  struct lowpan6_link_addr src, dest;
+  u16_t datagram_size = 0;
+  u16_t datagram_offset, datagram_tag;
+  struct lowpan6_reass_helper *lrh, *lrh_next, *lrh_prev = NULL;
+
+  if (p == NULL) {
+    return ERR_OK;
+  }
+
+  MIB2_STATS_NETIF_ADD(netif, ifinoctets, p->tot_len);
+
+  if (p->len != p->tot_len) {
+    /* for now, this needs a pbuf in one piece */
+    goto lowpan6_input_discard;
+  }
+
+  if (lowpan6_parse_iee802154_header(p, &src, &dest) != ERR_OK) {
+    goto lowpan6_input_discard;
+  }
+
+  /* Check dispatch. */
+  puc = (u8_t *)p->payload;
+
+  b = *puc;
+  if ((b & 0xf8) == 0xc0) {
+    /* FRAG1 dispatch. add this packet to reassembly list. */
+    datagram_size = ((u16_t)(puc[0] & 0x07) << 8) | (u16_t)puc[1];
+    datagram_tag = ((u16_t)puc[2] << 8) | (u16_t)puc[3];
+
+    /* check for duplicate */
+    lrh = lowpan6_data.reass_list;
+    while (lrh != NULL) {
+      uint8_t discard = 0;
+      lrh_next = lrh->next_packet;
+      if ((lrh->sender_addr.addr_len == src.addr_len) &&
+          (memcmp(lrh->sender_addr.addr, src.addr, src.addr_len) == 0)) {
+        /* address match with packet in reassembly. */
+        if ((datagram_tag == lrh->datagram_tag) && (datagram_size == lrh->datagram_size)) {
+          /* duplicate fragment. */
+          goto lowpan6_input_discard;
+        } else {
+          /* We are receiving the start of a new datagram. Discard old one (incomplete). */
+          discard = 1;
+        }
+      }
+      if (discard) {
+        dequeue_datagram(lrh, lrh_prev);
+        free_reass_datagram(lrh);
+      } else {
+        lrh_prev = lrh;
+      }
+      /* Check next datagram in queue. */
+      lrh = lrh_next;
+    }
+
+    pbuf_remove_header(p, 4); /* hide frag1 dispatch */
+
+    lrh = (struct lowpan6_reass_helper *) mem_malloc(sizeof(struct lowpan6_reass_helper));
+    if (lrh == NULL) {
+      goto lowpan6_input_discard;
+    }
+
+    lrh->sender_addr.addr_len = src.addr_len;
+    for (i = 0; i < src.addr_len; i++) {
+      lrh->sender_addr.addr[i] = src.addr[i];
+    }
+    lrh->datagram_size = datagram_size;
+    lrh->datagram_tag = datagram_tag;
+    lrh->frags = NULL;
+    if (*(u8_t *)p->payload == 0x41) {
+      /* This is a complete IPv6 packet, just skip dispatch byte. */
+      pbuf_remove_header(p, 1); /* hide dispatch byte. */
+      lrh->reass = p;
+    } else if ((*(u8_t *)p->payload & 0xe0 ) == 0x60) {
+      lrh->reass = lowpan6_decompress(p, datagram_size, LWIP_6LOWPAN_CONTEXTS(netif), &src, &dest);
+      if (lrh->reass == NULL) {
+        /* decompression failed */
+        mem_free(lrh);
+        goto lowpan6_input_discard;
+      }
+    }
+    /* TODO: handle the case where we already have FRAGN received */
+    lrh->next_packet = lowpan6_data.reass_list;
+    lrh->timer = 2;
+    lowpan6_data.reass_list = lrh;
+
+    return ERR_OK;
+  } else if ((b & 0xf8) == 0xe0) {
+    /* FRAGN dispatch, find packet being reassembled. */
+    datagram_size = ((u16_t)(puc[0] & 0x07) << 8) | (u16_t)puc[1];
+    datagram_tag = ((u16_t)puc[2] << 8) | (u16_t)puc[3];
+    datagram_offset = (u16_t)puc[4] << 3;
+    pbuf_remove_header(p, 4); /* hide frag1 dispatch but keep datagram offset for reassembly */
+
+    for (lrh = lowpan6_data.reass_list; lrh != NULL; lrh_prev = lrh, lrh = lrh->next_packet) {
+      if ((lrh->sender_addr.addr_len == src.addr_len) &&
+          (memcmp(lrh->sender_addr.addr, src.addr, src.addr_len) == 0) &&
+          (datagram_tag == lrh->datagram_tag) &&
+          (datagram_size == lrh->datagram_size)) {
+        break;
+      }
+    }
+    if (lrh == NULL) {
+      /* rogue fragment */
+      goto lowpan6_input_discard;
+    }
+    /* Insert new pbuf into list of fragments. Each fragment is a pbuf,
+       this only works for unchained pbufs. */
+    LWIP_ASSERT("p->next == NULL", p->next == NULL);
+    if (lrh->reass != NULL) {
+      /* FRAG1 already received, check this offset against first len */
+      if (datagram_offset < lrh->reass->len) {
+        /* fragment overlap, discard old fragments */
+        dequeue_datagram(lrh, lrh_prev);
+        free_reass_datagram(lrh);
+        goto lowpan6_input_discard;
+      }
+    }
+    if (lrh->frags == NULL) {
+      /* first FRAGN */
+      lrh->frags = p;
+    } else {
+      /* find the correct place to insert */
+      struct pbuf *q, *last;
+      u16_t new_frag_len = p->len - 1; /* p->len includes datagram_offset byte */
+      for (q = lrh->frags, last = NULL; q != NULL; last = q, q = q->next) {
+        u16_t q_datagram_offset = ((u8_t *)q->payload)[0] << 3;
+        u16_t q_frag_len = q->len - 1;
+        if (datagram_offset < q_datagram_offset) {
+          if (datagram_offset + new_frag_len > q_datagram_offset) {
+            /* overlap, discard old fragments */
+            dequeue_datagram(lrh, lrh_prev);
+            free_reass_datagram(lrh);
+            goto lowpan6_input_discard;
+          }
+          /* insert here */
+          break;
+        } else if (datagram_offset == q_datagram_offset) {
+          if (q_frag_len != new_frag_len) {
+            /* fragment mismatch, discard old fragments */
+            dequeue_datagram(lrh, lrh_prev);
+            free_reass_datagram(lrh);
+            goto lowpan6_input_discard;
+          }
+          /* duplicate, ignore */
+          pbuf_free(p);
+          return ERR_OK;
+        }
+      }
+      /* insert fragment */
+      if (last == NULL) {
+        lrh->frags = p;
+      } else {
+        last->next = p;
+        p->next = q;
+      }
+    }
+    /* check if all fragments were received */
+    if (lrh->reass) {
+      u16_t offset = lrh->reass->len;
+      struct pbuf *q;
+      for (q = lrh->frags; q != NULL; q = q->next) {
+        u16_t q_datagram_offset = ((u8_t *)q->payload)[0] << 3;
+        if (q_datagram_offset != offset) {
+          /* not complete, wait for more fragments */
+          return ERR_OK;
+        }
+        offset += q->len - 1;
+      }
+      if (offset == datagram_size) {
+        /* all fragments received, combine pbufs */
+        u16_t datagram_left = datagram_size - lrh->reass->len;
+        for (q = lrh->frags; q != NULL; q = q->next) {
+          /* hide datagram_offset byte now */
+          pbuf_remove_header(q, 1);
+          q->tot_len = datagram_left;
+          datagram_left -= q->len;
+        }
+        LWIP_ASSERT("datagram_left == 0", datagram_left == 0);
+        q = lrh->reass;
+        q->tot_len = datagram_size;
+        q->next = lrh->frags;
+        lrh->frags = NULL;
+        lrh->reass = NULL;
+        dequeue_datagram(lrh, lrh_prev);
+        mem_free(lrh);
+
+        /* @todo: distinguish unicast/multicast */
+        MIB2_STATS_NETIF_INC(netif, ifinucastpkts);
+        return ip6_input(q, netif);
+      }
+    }
+    /* pbuf enqueued, waiting for more fragments */
+    return ERR_OK;
+  } else {
+    if (b == 0x41) {
+      /* This is a complete IPv6 packet, just skip dispatch byte. */
+      pbuf_remove_header(p, 1); /* hide dispatch byte. */
+    } else if ((b & 0xe0 ) == 0x60) {
+      /* IPv6 headers are compressed using IPHC. */
+      p = lowpan6_decompress(p, datagram_size, LWIP_6LOWPAN_CONTEXTS(netif), &src, &dest);
+      if (p == NULL) {
+        MIB2_STATS_NETIF_INC(netif, ifindiscards);
+        return ERR_OK;
+      }
+    } else {
+      goto lowpan6_input_discard;
+    }
+
+    /* @todo: distinguish unicast/multicast */
+    MIB2_STATS_NETIF_INC(netif, ifinucastpkts);
+
+    return ip6_input(p, netif);
+  }
+lowpan6_input_discard:
+  MIB2_STATS_NETIF_INC(netif, ifindiscards);
+  pbuf_free(p);
+  /* always return ERR_OK here to prevent the caller freeing the pbuf */
+  return ERR_OK;
+}
+
+/**
+ * @ingroup sixlowpan
+ */
+err_t
+lowpan6_if_init(struct netif *netif)
+{
+  netif->name[0] = 'L';
+  netif->name[1] = '6';
+  netif->output_ip6 = lowpan6_output;
+
+  MIB2_INIT_NETIF(netif, snmp_ifType_other, 0);
+
+  /* maximum transfer unit */
+  netif->mtu = 1280;
+
+  /* broadcast capability */
+  netif->flags = NETIF_FLAG_BROADCAST /* | NETIF_FLAG_LOWPAN6 */;
+
+  return ERR_OK;
+}
+
+/**
+ * @ingroup sixlowpan
+ * Set PAN ID
+ */
+err_t
+lowpan6_set_pan_id(u16_t pan_id)
+{
+  lowpan6_data.ieee_802154_pan_id = pan_id;
+
+  return ERR_OK;
+}
+
+#if !NO_SYS
+/**
+ * @ingroup sixlowpan
+ * Pass a received packet to tcpip_thread for input processing
+ *
+ * @param p the received packet, p->payload pointing to the
+ *          IEEE 802.15.4 header.
+ * @param inp the network interface on which the packet was received
+ */
+err_t
+tcpip_6lowpan_input(struct pbuf *p, struct netif *inp)
+{
+  return tcpip_inpkt(p, inp, lowpan6_input);
+}
+#endif /* !NO_SYS */
+
+#endif /* LWIP_IPV6 */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/netif/lowpan6_ble.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/netif/lowpan6_ble.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/netif/lowpan6_ble.c	(revision 457)
@@ -0,0 +1,447 @@
+/**
+ * @file
+ * 6LowPAN over BLE output for IPv6 (RFC7668).
+*/
+
+/*
+ * Copyright (c) 2017 Benjamin Aigner
+ * Copyright (c) 2015 Inico Technologies Ltd. , Author: Ivan Delamer <delamer@inicotech.com>
+ * 
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * Author: Benjamin Aigner <aignerb@technikum-wien.at>
+ * 
+ * Based on the original 6lowpan implementation of lwIP ( @see 6lowpan.c)
+ */
+
+
+/**
+ * @defgroup rfc7668if 6LoWPAN over BLE (RFC7668)
+ * @ingroup netifs
+ * This file implements a RFC7668 implementation for 6LoWPAN over
+ * Bluetooth Low Energy. The specification is very similar to 6LoWPAN,
+ * so most of the code is re-used.
+ * Compared to 6LoWPAN, much functionality is already implemented in
+ * lower BLE layers (fragmenting, session management,...).
+ *
+ * Usage:
+ * - add this netif
+ *   - don't add IPv4 addresses (no IPv4 support in RFC7668), pass 'NULL','NULL','NULL'
+ *   - use the BLE to EUI64 conversation util to create an IPv6 link-local address from the BLE MAC (@ref ble_addr_to_eui64)
+ *   - input function: @ref rfc7668_input
+ * - set the link output function, which transmits output data to an established L2CAP channel
+ * - If data arrives (HCI event "L2CAP_DATA_PACKET"):
+ *   - allocate a @ref PBUF_RAW buffer
+ *   - let the pbuf struct point to the incoming data or copy it to the buffer
+ *   - call netif->input
+ *
+ * @todo:
+ * - further testing
+ * - support compression contexts
+ * - support multiple addresses
+ * - support multicast
+ * - support neighbor discovery
+ */
+
+
+#include "netif/lowpan6_ble.h"
+
+#if LWIP_IPV6
+
+#include "lwip/ip.h"
+#include "lwip/pbuf.h"
+#include "lwip/ip_addr.h"
+#include "lwip/netif.h"
+#include "lwip/nd6.h"
+#include "lwip/mem.h"
+#include "lwip/udp.h"
+#include "lwip/tcpip.h"
+#include "lwip/snmp.h"
+
+#include <string.h>
+
+#if LWIP_6LOWPAN_NUM_CONTEXTS > 0
+/** context memory, containing IPv6 addresses */
+static ip6_addr_t rfc7668_context[LWIP_6LOWPAN_NUM_CONTEXTS];
+#else
+#define rfc7668_context NULL
+#endif
+
+static struct lowpan6_link_addr rfc7668_local_addr;
+static struct lowpan6_link_addr rfc7668_peer_addr;
+
+/**
+ * @ingroup rfc7668if
+ *  convert BT address to EUI64 addr
+ * 
+ * This method converts a Bluetooth MAC address to an EUI64 address,
+ * which is used within IPv6 communication
+ * 
+ * @param dst IPv6 destination space
+ * @param src BLE MAC address source
+ * @param public_addr If the LWIP_RFC7668_LINUX_WORKAROUND_PUBLIC_ADDRESS
+ * option is set, bit 0x02 will be set if param=0 (no public addr); cleared otherwise
+ * 
+ * @see LWIP_RFC7668_LINUX_WORKAROUND_PUBLIC_ADDRESS
+ */
+void
+ble_addr_to_eui64(uint8_t *dst, const uint8_t *src, int public_addr)
+{
+  /* according to RFC7668 ch 3.2.2. */
+  memcpy(dst, src, 3);
+  dst[3] = 0xFF;
+  dst[4] = 0xFE;
+  memcpy(&dst[5], &src[3], 3);
+#if LWIP_RFC7668_LINUX_WORKAROUND_PUBLIC_ADDRESS
+  if(public_addr) {
+    dst[0] &= ~0x02;
+  } else {
+    dst[0] |= 0x02;
+  }
+#else
+  LWIP_UNUSED_ARG(public_addr);
+#endif
+}
+
+/**
+ * @ingroup rfc7668if
+ *  convert EUI64 address to Bluetooth MAC addr
+ * 
+ * This method converts an EUI64 address to a Bluetooth MAC address,
+ * 
+ * @param dst BLE MAC address destination
+ * @param src IPv6 source
+ * 
+ */
+void
+eui64_to_ble_addr(uint8_t *dst, const uint8_t *src)
+{
+  /* according to RFC7668 ch 3.2.2. */
+  memcpy(dst,src,3);
+  memcpy(&dst[3],&src[5],3);
+}
+
+/** Set an address used for stateful compression.
+ * This expects an address of 6 or 8 bytes.
+ */
+static err_t
+rfc7668_set_addr(struct lowpan6_link_addr *addr, const u8_t *in_addr, size_t in_addr_len, int is_mac_48, int is_public_addr)
+{
+  if ((in_addr == NULL) || (addr == NULL)) {
+    return ERR_VAL;
+  }
+  if (is_mac_48) {
+    if (in_addr_len != 6) {
+      return ERR_VAL;
+    }
+    addr->addr_len = 8;
+    ble_addr_to_eui64(addr->addr, in_addr, is_public_addr);
+  } else {
+    if (in_addr_len != 8) {
+      return ERR_VAL;
+    }
+    addr->addr_len = 8;
+    memcpy(addr->addr, in_addr, 8);
+  }
+  return ERR_OK;
+}
+
+
+/** Set the local address used for stateful compression.
+ * This expects an address of 8 bytes.
+ */
+err_t
+rfc7668_set_local_addr_eui64(struct netif *netif, const u8_t *local_addr, size_t local_addr_len)
+{
+  /* netif not used for now, the address is stored globally... */
+  LWIP_UNUSED_ARG(netif);
+  return rfc7668_set_addr(&rfc7668_local_addr, local_addr, local_addr_len, 0, 0);
+}
+
+/** Set the local address used for stateful compression.
+ * This expects an address of 6 bytes.
+ */
+err_t
+rfc7668_set_local_addr_mac48(struct netif *netif, const u8_t *local_addr, size_t local_addr_len, int is_public_addr)
+{
+  /* netif not used for now, the address is stored globally... */
+  LWIP_UNUSED_ARG(netif);
+  return rfc7668_set_addr(&rfc7668_local_addr, local_addr, local_addr_len, 1, is_public_addr);
+}
+
+/** Set the peer address used for stateful compression.
+ * This expects an address of 8 bytes.
+ */
+err_t
+rfc7668_set_peer_addr_eui64(struct netif *netif, const u8_t *peer_addr, size_t peer_addr_len)
+{
+  /* netif not used for now, the address is stored globally... */
+  LWIP_UNUSED_ARG(netif);
+  return rfc7668_set_addr(&rfc7668_peer_addr, peer_addr, peer_addr_len, 0, 0);
+}
+
+/** Set the peer address used for stateful compression.
+ * This expects an address of 6 bytes.
+ */
+err_t
+rfc7668_set_peer_addr_mac48(struct netif *netif, const u8_t *peer_addr, size_t peer_addr_len, int is_public_addr)
+{
+  /* netif not used for now, the address is stored globally... */
+  LWIP_UNUSED_ARG(netif);
+  return rfc7668_set_addr(&rfc7668_peer_addr, peer_addr, peer_addr_len, 1, is_public_addr);
+}
+
+/** Encapsulate IPv6 frames for BLE transmission
+ * 
+ * This method implements the IPv6 header compression:
+ *  *) According to RFC6282
+ *  *) See Figure 2, contains base format of bit positions
+ *  *) Fragmentation not necessary (done at L2CAP layer of BLE)
+ * @note Currently the pbuf allocation uses 256 bytes. If longer packets are used (possible due to MTU=1480Bytes), increase it here!
+ * 
+ * @param p Pbuf struct, containing the payload data
+ * @param netif Output network interface. Should be of RFC7668 type
+ * 
+ * @return Same as netif->output.
+ */
+static err_t
+rfc7668_compress(struct netif *netif, struct pbuf *p)
+{
+  struct pbuf *p_frag;
+  u16_t remaining_len;
+  u8_t *buffer;
+  u8_t lowpan6_header_len;
+  u8_t hidden_header_len;
+  err_t err;
+
+  LWIP_ASSERT("lowpan6_frag: netif->linkoutput not set", netif->linkoutput != NULL);
+
+#if LWIP_6LOWPAN_IPHC
+
+  /* We'll use a dedicated pbuf for building BLE fragments.
+   * We'll over-allocate it by the bytes saved for header compression.
+   */
+  p_frag = pbuf_alloc(PBUF_RAW, p->tot_len, PBUF_RAM);
+  if (p_frag == NULL) {
+    MIB2_STATS_NETIF_INC(netif, ifoutdiscards);
+    return ERR_MEM;
+  }
+  LWIP_ASSERT("this needs a pbuf in one piece", p_frag->len == p_frag->tot_len);
+
+  /* Write IP6 header (with IPHC). */
+  buffer = (u8_t*)p_frag->payload;
+
+  err = lowpan6_compress_headers(netif, (u8_t *)p->payload, p->len, buffer, p_frag->len,
+    &lowpan6_header_len, &hidden_header_len, rfc7668_context, &rfc7668_local_addr, &rfc7668_peer_addr);
+  if (err != ERR_OK) {
+    MIB2_STATS_NETIF_INC(netif, ifoutdiscards);
+    pbuf_free(p_frag);
+    return err;
+  }
+  pbuf_remove_header(p, hidden_header_len);
+
+  /* Calculate remaining packet length */
+  remaining_len = p->tot_len;
+
+  /* Copy IPv6 packet */
+  pbuf_copy_partial(p, buffer + lowpan6_header_len, remaining_len, 0);
+
+  /* Calculate frame length */
+  p_frag->len = p_frag->tot_len = remaining_len + lowpan6_header_len;
+
+  /* send the packet */
+  MIB2_STATS_NETIF_ADD(netif, ifoutoctets, p_frag->tot_len);
+  LWIP_DEBUGF(LWIP_LOWPAN6_DEBUG|LWIP_DBG_TRACE, ("rfc7668_output: sending packet %p\n", (void *)p));
+  err = netif->linkoutput(netif, p_frag);
+
+  pbuf_free(p_frag);
+
+  return err;
+#else /* LWIP_6LOWPAN_IPHC */
+  /* 6LoWPAN over BLE requires IPHC! */
+  return ERR_IF;
+#endif/* LWIP_6LOWPAN_IPHC */
+}
+
+/**
+ * @ingroup rfc7668if
+ * Set context id IPv6 address
+ *
+ * Store one IPv6 address to a given context id.
+ *
+ * @param idx Context id
+ * @param context IPv6 addr for this context
+ *
+ * @return ERR_OK (if everything is fine), ERR_ARG (if the context id is out of range), ERR_VAL (if contexts disabled)
+ */
+err_t
+rfc7668_set_context(u8_t idx, const ip6_addr_t *context)
+{
+#if LWIP_6LOWPAN_NUM_CONTEXTS > 0
+  /* check if the ID is possible */
+  if (idx >= LWIP_6LOWPAN_NUM_CONTEXTS) {
+    return ERR_ARG;
+  }
+  /* copy IPv6 address to context storage */
+  ip6_addr_set(&rfc7668_context[idx], context);
+  return ERR_OK;
+#else
+  LWIP_UNUSED_ARG(idx);
+  LWIP_UNUSED_ARG(context);
+  return ERR_VAL;
+#endif
+}
+
+/**
+ * @ingroup rfc7668if
+ * Compress outgoing IPv6 packet and pass it on to netif->linkoutput
+ *
+ * @param netif The lwIP network interface which the IP packet will be sent on.
+ * @param q The pbuf(s) containing the IP packet to be sent.
+ * @param ip6addr The IP address of the packet destination.
+ *
+ * @return See rfc7668_compress
+ */
+err_t
+rfc7668_output(struct netif *netif, struct pbuf *q, const ip6_addr_t *ip6addr)
+{
+  /* dst ip6addr is not used here, we only have one peer */
+  LWIP_UNUSED_ARG(ip6addr);
+
+  return rfc7668_compress(netif, q);
+}
+
+/**
+ * @ingroup rfc7668if
+ * Process a received raw payload from an L2CAP channel
+ *
+ * @param p the received packet, p->payload pointing to the
+ *        IPv6 header (maybe compressed)
+ * @param netif the network interface on which the packet was received
+ * 
+ * @return ERR_OK if everything was fine
+ */
+err_t
+rfc7668_input(struct pbuf * p, struct netif *netif)
+{
+  u8_t * puc;
+
+  MIB2_STATS_NETIF_ADD(netif, ifinoctets, p->tot_len);
+
+  /* Load first header byte */
+  puc = (u8_t*)p->payload;
+  
+  /* no IP header compression */
+  if (*puc == 0x41) {
+    LWIP_DEBUGF(LWIP_LOWPAN6_DECOMPRESSION_DEBUG, ("Completed packet, removing dispatch: 0x%2x \n", *puc));
+    /* This is a complete IPv6 packet, just skip header byte. */
+    pbuf_remove_header(p, 1);
+  /* IPHC header compression */
+  } else if ((*puc & 0xe0 )== 0x60) {
+    LWIP_DEBUGF(LWIP_LOWPAN6_DECOMPRESSION_DEBUG, ("Completed packet, decompress dispatch: 0x%2x \n", *puc));
+    /* IPv6 headers are compressed using IPHC. */
+    p = lowpan6_decompress(p, 0, rfc7668_context, &rfc7668_peer_addr, &rfc7668_local_addr);
+    /* if no pbuf is returned, handle as discarded packet */
+    if (p == NULL) {
+      MIB2_STATS_NETIF_INC(netif, ifindiscards);
+      return ERR_OK;
+    }
+  /* invalid header byte, discard */
+  } else {
+    LWIP_DEBUGF(LWIP_LOWPAN6_DECOMPRESSION_DEBUG, ("Completed packet, discarding: 0x%2x \n", *puc));
+    MIB2_STATS_NETIF_INC(netif, ifindiscards);
+    pbuf_free(p);
+    return ERR_OK;
+  }
+  /* @todo: distinguish unicast/multicast */
+  MIB2_STATS_NETIF_INC(netif, ifinucastpkts);
+
+#if LWIP_RFC7668_IP_UNCOMPRESSED_DEBUG
+  {
+    u16_t i;
+    LWIP_DEBUGF(LWIP_RFC7668_IP_UNCOMPRESSED_DEBUG, ("IPv6 payload:\n"));
+    for (i = 0; i < p->len; i++) {
+      if ((i%4)==0) {
+        LWIP_DEBUGF(LWIP_RFC7668_IP_UNCOMPRESSED_DEBUG, ("\n"));
+      }
+      LWIP_DEBUGF(LWIP_RFC7668_IP_UNCOMPRESSED_DEBUG, ("%2X ", *((uint8_t *)p->payload+i)));
+    }
+    LWIP_DEBUGF(LWIP_RFC7668_IP_UNCOMPRESSED_DEBUG, ("\np->len: %d\n", p->len));
+  }
+#endif
+  /* pass data to ip6_input */
+  return ip6_input(p, netif);
+}
+
+/**
+ * @ingroup rfc7668if
+ * Initialize the netif
+ * 
+ * No flags are used (broadcast not possible, not ethernet, ...)
+ * The shortname for this netif is "BT"
+ *
+ * @param netif the network interface to be initialized as RFC7668 netif
+ * 
+ * @return ERR_OK if everything went fine
+ */
+err_t
+rfc7668_if_init(struct netif *netif)
+{
+  netif->name[0] = 'b';
+  netif->name[1] = 't';
+  /* local function as IPv6 output */
+  netif->output_ip6 = rfc7668_output;
+
+  MIB2_INIT_NETIF(netif, snmp_ifType_other, 0);
+
+  /* maximum transfer unit, set according to RFC7668 ch2.4 */
+  netif->mtu = 1280;
+
+  /* no flags set (no broadcast, ethernet,...)*/
+  netif->flags = 0;
+
+  /* everything fine */
+  return ERR_OK;
+}
+
+#if !NO_SYS
+/**
+ * Pass a received packet to tcpip_thread for input processing
+ *
+ * @param p the received packet, p->payload pointing to the
+ *          IEEE 802.15.4 header.
+ * @param inp the network interface on which the packet was received
+ * 
+ * @return see @ref tcpip_inpkt, same return values
+ */
+err_t
+tcpip_rfc7668_input(struct pbuf *p, struct netif *inp)
+{
+  /* send data to upper layer, return the result */
+  return tcpip_inpkt(p, inp, rfc7668_input);
+}
+#endif /* !NO_SYS */
+
+#endif /* LWIP_IPV6 */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/netif/lowpan6_common.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/netif/lowpan6_common.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/netif/lowpan6_common.c	(revision 457)
@@ -0,0 +1,841 @@
+/**
+ * @file
+ *
+ * Common 6LowPAN routines for IPv6. Uses ND tables for link-layer addressing. Fragments packets to 6LowPAN units.
+ *
+ * This implementation aims to conform to IEEE 802.15.4(-2015), RFC 4944 and RFC 6282.
+ * @todo: RFC 6775.
+ */
+
+/*
+ * Copyright (c) 2015 Inico Technologies Ltd.
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Ivan Delamer <delamer@inicotech.com>
+ *
+ *
+ * Please coordinate changes and requests with Ivan Delamer
+ * <delamer@inicotech.com>
+ */
+
+/**
+ * @defgroup sixlowpan 6LoWPAN (RFC4944)
+ * @ingroup netifs
+ * 6LowPAN netif implementation
+ */
+
+#include "netif/lowpan6_common.h"
+
+#if LWIP_IPV6
+
+#include "lwip/ip.h"
+#include "lwip/pbuf.h"
+#include "lwip/ip_addr.h"
+#include "lwip/netif.h"
+#include "lwip/udp.h"
+
+#include <string.h>
+
+/* Determine compression mode for unicast address. */
+s8_t
+lowpan6_get_address_mode(const ip6_addr_t *ip6addr, const struct lowpan6_link_addr *mac_addr)
+{
+  if (mac_addr->addr_len == 2) {
+    if ((ip6addr->addr[2] == (u32_t)PP_HTONL(0x000000ff)) &&
+        ((ip6addr->addr[3]  & PP_HTONL(0xffff0000)) == PP_NTOHL(0xfe000000))) {
+      if ((ip6addr->addr[3]  & PP_HTONL(0x0000ffff)) == lwip_ntohl((mac_addr->addr[0] << 8) | mac_addr->addr[1])) {
+        return 3;
+      }
+    }
+  } else if (mac_addr->addr_len == 8) {
+    if ((ip6addr->addr[2] == lwip_ntohl(((mac_addr->addr[0] ^ 2) << 24) | (mac_addr->addr[1] << 16) | mac_addr->addr[2] << 8 | mac_addr->addr[3])) &&
+        (ip6addr->addr[3] == lwip_ntohl((mac_addr->addr[4] << 24) | (mac_addr->addr[5] << 16) | mac_addr->addr[6] << 8 | mac_addr->addr[7]))) {
+      return 3;
+    }
+  }
+
+  if ((ip6addr->addr[2] == PP_HTONL(0x000000ffUL)) &&
+      ((ip6addr->addr[3]  & PP_HTONL(0xffff0000)) == PP_NTOHL(0xfe000000UL))) {
+    return 2;
+  }
+
+  return 1;
+}
+
+#if LWIP_6LOWPAN_IPHC
+
+/* Determine compression mode for multicast address. */
+static s8_t
+lowpan6_get_address_mode_mc(const ip6_addr_t *ip6addr)
+{
+  if ((ip6addr->addr[0] == PP_HTONL(0xff020000)) &&
+      (ip6addr->addr[1] == 0) &&
+      (ip6addr->addr[2] == 0) &&
+      ((ip6addr->addr[3]  & PP_HTONL(0xffffff00)) == 0)) {
+    return 3;
+  } else if (((ip6addr->addr[0] & PP_HTONL(0xff00ffff)) == PP_HTONL(0xff000000)) &&
+             (ip6addr->addr[1] == 0)) {
+    if ((ip6addr->addr[2] == 0) &&
+        ((ip6addr->addr[3]  & PP_HTONL(0xff000000)) == 0)) {
+      return 2;
+    } else if ((ip6addr->addr[2]  & PP_HTONL(0xffffff00)) == 0) {
+      return 1;
+    }
+  }
+
+  return 0;
+}
+
+#if LWIP_6LOWPAN_NUM_CONTEXTS > 0
+static s8_t
+lowpan6_context_lookup(const ip6_addr_t *lowpan6_contexts, const ip6_addr_t *ip6addr)
+{
+  s8_t i;
+
+  for (i = 0; i < LWIP_6LOWPAN_NUM_CONTEXTS; i++) {
+    if (ip6_addr_netcmp(&lowpan6_contexts[i], ip6addr)) {
+      return i;
+    }
+  }
+  return -1;
+}
+#endif /* LWIP_6LOWPAN_NUM_CONTEXTS > 0 */
+
+/*
+ * Compress IPv6 and/or UDP headers.
+ * */
+err_t
+lowpan6_compress_headers(struct netif *netif, u8_t *inbuf, size_t inbuf_size, u8_t *outbuf, size_t outbuf_size,
+                         u8_t *lowpan6_header_len_out, u8_t *hidden_header_len_out, ip6_addr_t *lowpan6_contexts,
+                         const struct lowpan6_link_addr *src, const struct lowpan6_link_addr *dst)
+{
+  u8_t *buffer, *inptr;
+  u8_t lowpan6_header_len;
+  u8_t hidden_header_len = 0;
+  s8_t i;
+  struct ip6_hdr *ip6hdr;
+  ip_addr_t ip6src, ip6dst;
+
+  LWIP_ASSERT("netif != NULL", netif != NULL);
+  LWIP_ASSERT("inbuf != NULL", inbuf != NULL);
+  LWIP_ASSERT("outbuf != NULL", outbuf != NULL);
+  LWIP_ASSERT("lowpan6_header_len_out != NULL", lowpan6_header_len_out != NULL);
+  LWIP_ASSERT("hidden_header_len_out != NULL", hidden_header_len_out != NULL);
+
+  /* Perform 6LowPAN IPv6 header compression according to RFC 6282 */
+  buffer = outbuf;
+  inptr = inbuf;
+
+  if (inbuf_size < IP6_HLEN) {
+    /* input buffer too short */
+    return ERR_VAL;
+  }
+  if (outbuf_size < IP6_HLEN) {
+    /* output buffer too short for worst case */
+    return ERR_MEM;
+  }
+
+  /* Point to ip6 header and align copies of src/dest addresses. */
+  ip6hdr = (struct ip6_hdr *)inptr;
+  ip_addr_copy_from_ip6_packed(ip6dst, ip6hdr->dest);
+  ip6_addr_assign_zone(ip_2_ip6(&ip6dst), IP6_UNKNOWN, netif);
+  ip_addr_copy_from_ip6_packed(ip6src, ip6hdr->src);
+  ip6_addr_assign_zone(ip_2_ip6(&ip6src), IP6_UNKNOWN, netif);
+
+  /* Basic length of 6LowPAN header, set dispatch and clear fields. */
+  lowpan6_header_len = 2;
+  buffer[0] = 0x60;
+  buffer[1] = 0;
+
+  /* Determine whether there will be a Context Identifier Extension byte or not.
+   * If so, set it already. */
+#if LWIP_6LOWPAN_NUM_CONTEXTS > 0
+  buffer[2] = 0;
+
+  i = lowpan6_context_lookup(lowpan6_contexts, ip_2_ip6(&ip6src));
+  if (i >= 0) {
+    /* Stateful source address compression. */
+    buffer[1] |= 0x40;
+    buffer[2] |= (i & 0x0f) << 4;
+  }
+
+  i = lowpan6_context_lookup(lowpan6_contexts, ip_2_ip6(&ip6dst));
+  if (i >= 0) {
+    /* Stateful destination address compression. */
+    buffer[1] |= 0x04;
+    buffer[2] |= i & 0x0f;
+  }
+
+  if (buffer[2] != 0x00) {
+    /* Context identifier extension byte is appended. */
+    buffer[1] |= 0x80;
+    lowpan6_header_len++;
+  }
+#else /* LWIP_6LOWPAN_NUM_CONTEXTS > 0 */
+  LWIP_UNUSED_ARG(lowpan6_contexts);
+#endif /* LWIP_6LOWPAN_NUM_CONTEXTS > 0 */
+
+  /* Determine TF field: Traffic Class, Flow Label */
+  if (IP6H_FL(ip6hdr) == 0) {
+    /* Flow label is elided. */
+    buffer[0] |= 0x10;
+    if (IP6H_TC(ip6hdr) == 0) {
+      /* Traffic class (ECN+DSCP) elided too. */
+      buffer[0] |= 0x08;
+    } else {
+      /* Traffic class (ECN+DSCP) appended. */
+      buffer[lowpan6_header_len++] = IP6H_TC(ip6hdr);
+    }
+  } else {
+    if (((IP6H_TC(ip6hdr) & 0x3f) == 0)) {
+      /* DSCP portion of Traffic Class is elided, ECN and FL are appended (3 bytes) */
+      buffer[0] |= 0x08;
+
+      buffer[lowpan6_header_len] = IP6H_TC(ip6hdr) & 0xc0;
+      buffer[lowpan6_header_len++] |= (IP6H_FL(ip6hdr) >> 16) & 0x0f;
+      buffer[lowpan6_header_len++] = (IP6H_FL(ip6hdr) >> 8) & 0xff;
+      buffer[lowpan6_header_len++] = IP6H_FL(ip6hdr) & 0xff;
+    } else {
+      /* Traffic class and flow label are appended (4 bytes) */
+      buffer[lowpan6_header_len++] = IP6H_TC(ip6hdr);
+      buffer[lowpan6_header_len++] = (IP6H_FL(ip6hdr) >> 16) & 0x0f;
+      buffer[lowpan6_header_len++] = (IP6H_FL(ip6hdr) >> 8) & 0xff;
+      buffer[lowpan6_header_len++] = IP6H_FL(ip6hdr) & 0xff;
+    }
+  }
+
+  /* Compress NH?
+  * Only if UDP for now. @todo support other NH compression. */
+  if (IP6H_NEXTH(ip6hdr) == IP6_NEXTH_UDP) {
+    buffer[0] |= 0x04;
+  } else {
+    /* append nexth. */
+    buffer[lowpan6_header_len++] = IP6H_NEXTH(ip6hdr);
+  }
+
+  /* Compress hop limit? */
+  if (IP6H_HOPLIM(ip6hdr) == 255) {
+    buffer[0] |= 0x03;
+  } else if (IP6H_HOPLIM(ip6hdr) == 64) {
+    buffer[0] |= 0x02;
+  } else if (IP6H_HOPLIM(ip6hdr) == 1) {
+    buffer[0] |= 0x01;
+  } else {
+    /* append hop limit */
+    buffer[lowpan6_header_len++] = IP6H_HOPLIM(ip6hdr);
+  }
+
+  /* Compress source address */
+  if (((buffer[1] & 0x40) != 0) ||
+      (ip6_addr_islinklocal(ip_2_ip6(&ip6src)))) {
+    /* Context-based or link-local source address compression. */
+    i = lowpan6_get_address_mode(ip_2_ip6(&ip6src), src);
+    buffer[1] |= (i & 0x03) << 4;
+    if (i == 1) {
+      MEMCPY(buffer + lowpan6_header_len, inptr + 16, 8);
+      lowpan6_header_len += 8;
+    } else if (i == 2) {
+      MEMCPY(buffer + lowpan6_header_len, inptr + 22, 2);
+      lowpan6_header_len += 2;
+    }
+  } else if (ip6_addr_isany(ip_2_ip6(&ip6src))) {
+    /* Special case: mark SAC and leave SAM=0 */
+    buffer[1] |= 0x40;
+  } else {
+    /* Append full address. */
+    MEMCPY(buffer + lowpan6_header_len, inptr + 8, 16);
+    lowpan6_header_len += 16;
+  }
+
+  /* Compress destination address */
+  if (ip6_addr_ismulticast(ip_2_ip6(&ip6dst))) {
+    /* @todo support stateful multicast address compression */
+
+    buffer[1] |= 0x08;
+
+    i = lowpan6_get_address_mode_mc(ip_2_ip6(&ip6dst));
+    buffer[1] |= i & 0x03;
+    if (i == 0) {
+      MEMCPY(buffer + lowpan6_header_len, inptr + 24, 16);
+      lowpan6_header_len += 16;
+    } else if (i == 1) {
+      buffer[lowpan6_header_len++] = inptr[25];
+      MEMCPY(buffer + lowpan6_header_len, inptr + 35, 5);
+      lowpan6_header_len += 5;
+    } else if (i == 2) {
+      buffer[lowpan6_header_len++] = inptr[25];
+      MEMCPY(buffer + lowpan6_header_len, inptr + 37, 3);
+      lowpan6_header_len += 3;
+    } else if (i == 3) {
+      buffer[lowpan6_header_len++] = (inptr)[39];
+    }
+  } else if (((buffer[1] & 0x04) != 0) ||
+              (ip6_addr_islinklocal(ip_2_ip6(&ip6dst)))) {
+    /* Context-based or link-local destination address compression. */
+    i = lowpan6_get_address_mode(ip_2_ip6(&ip6dst), dst);
+    buffer[1] |= i & 0x03;
+    if (i == 1) {
+      MEMCPY(buffer + lowpan6_header_len, inptr + 32, 8);
+      lowpan6_header_len += 8;
+    } else if (i == 2) {
+      MEMCPY(buffer + lowpan6_header_len, inptr + 38, 2);
+      lowpan6_header_len += 2;
+    }
+  } else {
+    /* Append full address. */
+    MEMCPY(buffer + lowpan6_header_len, inptr + 24, 16);
+    lowpan6_header_len += 16;
+  }
+
+  /* Move to payload. */
+  inptr += IP6_HLEN;
+  hidden_header_len += IP6_HLEN;
+
+#if LWIP_UDP
+  /* Compress UDP header? */
+  if (IP6H_NEXTH(ip6hdr) == IP6_NEXTH_UDP) {
+    /* @todo support optional checksum compression */
+
+    if (inbuf_size < IP6_HLEN + UDP_HLEN) {
+      /* input buffer too short */
+      return ERR_VAL;
+    }
+    if (outbuf_size < (size_t)(hidden_header_len + 7)) {
+      /* output buffer too short for worst case */
+      return ERR_MEM;
+    }
+
+    buffer[lowpan6_header_len] = 0xf0;
+
+    /* determine port compression mode. */
+    if ((inptr[0] == 0xf0) && ((inptr[1] & 0xf0) == 0xb0) &&
+        (inptr[2] == 0xf0) && ((inptr[3] & 0xf0) == 0xb0)) {
+      /* Compress source and dest ports. */
+      buffer[lowpan6_header_len++] |= 0x03;
+      buffer[lowpan6_header_len++] = ((inptr[1] & 0x0f) << 4) | (inptr[3] & 0x0f);
+    } else if (inptr[0] == 0xf0) {
+      /* Compress source port. */
+      buffer[lowpan6_header_len++] |= 0x02;
+      buffer[lowpan6_header_len++] = inptr[1];
+      buffer[lowpan6_header_len++] = inptr[2];
+      buffer[lowpan6_header_len++] = inptr[3];
+    } else if (inptr[2] == 0xf0) {
+      /* Compress dest port. */
+      buffer[lowpan6_header_len++] |= 0x01;
+      buffer[lowpan6_header_len++] = inptr[0];
+      buffer[lowpan6_header_len++] = inptr[1];
+      buffer[lowpan6_header_len++] = inptr[3];
+    } else {
+      /* append full ports. */
+      lowpan6_header_len++;
+      buffer[lowpan6_header_len++] = inptr[0];
+      buffer[lowpan6_header_len++] = inptr[1];
+      buffer[lowpan6_header_len++] = inptr[2];
+      buffer[lowpan6_header_len++] = inptr[3];
+    }
+
+    /* elide length and copy checksum */
+    buffer[lowpan6_header_len++] = inptr[6];
+    buffer[lowpan6_header_len++] = inptr[7];
+
+    hidden_header_len += UDP_HLEN;
+  }
+#endif /* LWIP_UDP */
+
+  *lowpan6_header_len_out = lowpan6_header_len;
+  *hidden_header_len_out = hidden_header_len;
+
+  return ERR_OK;
+}
+
+/** Decompress IPv6 and UDP headers compressed according to RFC 6282
+ *
+ * @param lowpan6_buffer compressed headers, first byte is the dispatch byte
+ * @param lowpan6_bufsize size of lowpan6_buffer (may include data after headers)
+ * @param decomp_buffer buffer where the decompressed headers are stored
+ * @param decomp_bufsize size of decomp_buffer
+ * @param hdr_size_comp returns the size of the compressed headers (skip to get to data)
+ * @param hdr_size_decomp returns the size of the decompressed headers (IPv6 + UDP)
+ * @param datagram_size datagram size from fragments or 0 if unfragmented
+ * @param compressed_size compressed datagram size (for unfragmented rx)
+ * @param lowpan6_contexts context addresses
+ * @param src source address of the outer layer, used for address compression
+ * @param dest destination address of the outer layer, used for address compression
+ * @return ERR_OK if decompression succeeded, an error otherwise
+ */
+static err_t
+lowpan6_decompress_hdr(u8_t *lowpan6_buffer, size_t lowpan6_bufsize,
+                       u8_t *decomp_buffer, size_t decomp_bufsize,
+                       u16_t *hdr_size_comp, u16_t *hdr_size_decomp,
+                       u16_t datagram_size, u16_t compressed_size,
+                       ip6_addr_t *lowpan6_contexts,
+                       struct lowpan6_link_addr *src, struct lowpan6_link_addr *dest)
+{
+  u16_t lowpan6_offset;
+  struct ip6_hdr *ip6hdr;
+  s8_t i;
+  u32_t header_temp;
+  u16_t ip6_offset = IP6_HLEN;
+
+  LWIP_ASSERT("lowpan6_buffer != NULL", lowpan6_buffer != NULL);
+  LWIP_ASSERT("decomp_buffer != NULL", decomp_buffer != NULL);
+  LWIP_ASSERT("src != NULL", src != NULL);
+  LWIP_ASSERT("dest != NULL", dest != NULL);
+  LWIP_ASSERT("hdr_size_comp != NULL", hdr_size_comp != NULL);
+  LWIP_ASSERT("dehdr_size_decompst != NULL", hdr_size_decomp != NULL);
+
+  ip6hdr = (struct ip6_hdr *)decomp_buffer;
+  if (decomp_bufsize < IP6_HLEN) {
+    return ERR_MEM;
+  }
+
+  /* output the full compressed packet, if set in @see lowpan6_opts.h */
+#if LWIP_LOWPAN6_IP_COMPRESSED_DEBUG
+  {
+    u16_t j;
+    LWIP_DEBUGF(LWIP_LOWPAN6_IP_COMPRESSED_DEBUG, ("lowpan6_decompress_hdr: IP6 payload (compressed): \n"));
+    for (j = 0; j < lowpan6_bufsize; j++) {
+      if ((j % 4) == 0) {
+        LWIP_DEBUGF(LWIP_LOWPAN6_IP_COMPRESSED_DEBUG, ("\n"));
+      }
+      LWIP_DEBUGF(LWIP_LOWPAN6_IP_COMPRESSED_DEBUG, ("%2X ", lowpan6_buffer[j]));
+    }
+    LWIP_DEBUGF(LWIP_LOWPAN6_IP_COMPRESSED_DEBUG, ("\np->len: %d", lowpan6_bufsize));
+  }
+#endif
+
+  /* offset for inline IP headers (RFC 6282 ch3)*/
+  lowpan6_offset = 2;
+  /* if CID is set (context identifier), the context byte 
+   * follows immediately after the header, so other IPHC fields are @+3 */
+  if (lowpan6_buffer[1] & 0x80) {
+    lowpan6_offset++;
+  }
+
+  /* Set IPv6 version, traffic class and flow label. (RFC6282, ch 3.1.1.)*/
+  if ((lowpan6_buffer[0] & 0x18) == 0x00) {
+    header_temp = ((lowpan6_buffer[lowpan6_offset+1] & 0x0f) << 16) | \
+      (lowpan6_buffer[lowpan6_offset + 2] << 8) | lowpan6_buffer[lowpan6_offset+3];
+    LWIP_DEBUGF(LWIP_LOWPAN6_DECOMPRESSION_DEBUG, ("TF: 00, ECN: 0x%2x, Flowlabel+DSCP: 0x%8X\n", \
+      lowpan6_buffer[lowpan6_offset],header_temp));
+    IP6H_VTCFL_SET(ip6hdr, 6, lowpan6_buffer[lowpan6_offset], header_temp);
+    /* increase offset, processed 4 bytes here:
+     * TF=00:  ECN + DSCP + 4-bit Pad + Flow Label (4 bytes)*/
+    lowpan6_offset += 4;
+  } else if ((lowpan6_buffer[0] & 0x18) == 0x08) {
+    header_temp = ((lowpan6_buffer[lowpan6_offset] & 0x0f) << 16) | (lowpan6_buffer[lowpan6_offset + 1] << 8) | lowpan6_buffer[lowpan6_offset+2];
+    LWIP_DEBUGF(LWIP_LOWPAN6_DECOMPRESSION_DEBUG, ("TF: 01, ECN: 0x%2x, Flowlabel: 0x%2X, DSCP ignored\n", \
+      lowpan6_buffer[lowpan6_offset] & 0xc0,header_temp));
+    IP6H_VTCFL_SET(ip6hdr, 6, lowpan6_buffer[lowpan6_offset] & 0xc0, header_temp);
+    /* increase offset, processed 3 bytes here:
+     * TF=01:  ECN + 2-bit Pad + Flow Label (3 bytes), DSCP is elided.*/
+    lowpan6_offset += 3;
+  } else if ((lowpan6_buffer[0] & 0x18) == 0x10) {
+    LWIP_DEBUGF(LWIP_LOWPAN6_DECOMPRESSION_DEBUG, ("TF: 10, DCSP+ECN: 0x%2x, Flowlabel ignored\n", lowpan6_buffer[lowpan6_offset]));
+    IP6H_VTCFL_SET(ip6hdr, 6, lowpan6_buffer[lowpan6_offset],0);
+    /* increase offset, processed 1 byte here:
+     * ECN + DSCP (1 byte), Flow Label is elided.*/
+    lowpan6_offset += 1;
+  } else if ((lowpan6_buffer[0] & 0x18) == 0x18) {
+    LWIP_DEBUGF(LWIP_LOWPAN6_DECOMPRESSION_DEBUG, ("TF: 11, DCSP/ECN & Flowlabel ignored\n"));
+    /* don't increase offset, no bytes processed here */
+    IP6H_VTCFL_SET(ip6hdr, 6, 0, 0);
+  }
+
+  /* Set Next Header (NH) */
+  if ((lowpan6_buffer[0] & 0x04) == 0x00) {
+    /* 0: full next header byte carried inline (increase offset)*/
+    LWIP_DEBUGF(LWIP_LOWPAN6_DECOMPRESSION_DEBUG, ("NH: 0x%2X\n", lowpan6_buffer[lowpan6_offset+1]));
+    IP6H_NEXTH_SET(ip6hdr, lowpan6_buffer[lowpan6_offset++]);
+  } else {
+    /* 1: NH compression, LOWPAN_NHC (RFC6282, ch 4.1) */
+    /* We should fill this later with NHC decoding */
+    LWIP_DEBUGF(LWIP_LOWPAN6_DECOMPRESSION_DEBUG, ("NH: skipped, later done with NHC\n"));
+    IP6H_NEXTH_SET(ip6hdr, 0);
+  }
+
+  /* Set Hop Limit, either carried inline or 3 different hops (1,64,255) */
+  if ((lowpan6_buffer[0] & 0x03) == 0x00) {
+    LWIP_DEBUGF(LWIP_LOWPAN6_DECOMPRESSION_DEBUG, ("Hops: full value: %d\n", lowpan6_buffer[lowpan6_offset+1]));
+    IP6H_HOPLIM_SET(ip6hdr, lowpan6_buffer[lowpan6_offset++]);
+  } else if ((lowpan6_buffer[0] & 0x03) == 0x01) {
+    LWIP_DEBUGF(LWIP_LOWPAN6_DECOMPRESSION_DEBUG, ("Hops: compressed: 1\n"));
+    IP6H_HOPLIM_SET(ip6hdr, 1);
+  } else if ((lowpan6_buffer[0] & 0x03) == 0x02) {
+    LWIP_DEBUGF(LWIP_LOWPAN6_DECOMPRESSION_DEBUG, ("Hops: compressed: 64\n"));
+    IP6H_HOPLIM_SET(ip6hdr, 64);
+  } else if ((lowpan6_buffer[0] & 0x03) == 0x03) {
+    LWIP_DEBUGF(LWIP_LOWPAN6_DECOMPRESSION_DEBUG, ("Hops: compressed: 255\n"));
+    IP6H_HOPLIM_SET(ip6hdr, 255);
+  }
+
+  /* Source address decoding. */
+  if ((lowpan6_buffer[1] & 0x40) == 0x00) {
+    /* Source address compression (SAC) = 0 -> stateless compression */
+    LWIP_DEBUGF(LWIP_LOWPAN6_DECOMPRESSION_DEBUG, ("SAC == 0, no context byte\n"));
+    /* Stateless compression */
+    if ((lowpan6_buffer[1] & 0x30) == 0x00) {
+      LWIP_DEBUGF(LWIP_LOWPAN6_DECOMPRESSION_DEBUG, ("SAM == 00, no src compression, fetching 128bits inline\n"));
+      /* copy full address, increase offset by 16 Bytes */
+      MEMCPY(&ip6hdr->src.addr[0], lowpan6_buffer + lowpan6_offset, 16);
+      lowpan6_offset += 16;
+    } else if ((lowpan6_buffer[1] & 0x30) == 0x10) {
+      LWIP_DEBUGF(LWIP_LOWPAN6_DECOMPRESSION_DEBUG, ("SAM == 01, src compression, 64bits inline\n"));
+      /* set 64 bits to link local */
+      ip6hdr->src.addr[0] = PP_HTONL(0xfe800000UL);
+      ip6hdr->src.addr[1] = 0;
+      /* copy 8 Bytes, increase offset */
+      MEMCPY(&ip6hdr->src.addr[2], lowpan6_buffer + lowpan6_offset, 8);
+      lowpan6_offset += 8;
+    } else if ((lowpan6_buffer[1] & 0x30) == 0x20) {
+      LWIP_DEBUGF(LWIP_LOWPAN6_DECOMPRESSION_DEBUG, ("SAM == 10, src compression, 16bits inline\n"));
+      /* set 96 bits to link local */
+      ip6hdr->src.addr[0] = PP_HTONL(0xfe800000UL);
+      ip6hdr->src.addr[1] = 0;
+      ip6hdr->src.addr[2] = PP_HTONL(0x000000ffUL);
+      /* extract remaining 16bits from inline bytes, increase offset */
+      ip6hdr->src.addr[3] = lwip_htonl(0xfe000000UL | (lowpan6_buffer[lowpan6_offset] << 8) |
+                                       lowpan6_buffer[lowpan6_offset + 1]);
+      lowpan6_offset += 2;
+    } else if ((lowpan6_buffer[1] & 0x30) == 0x30) {
+      LWIP_DEBUGF(LWIP_LOWPAN6_DECOMPRESSION_DEBUG, ("SAM == 11, src compression, 0bits inline, using other headers\n"));
+      /* no information avalaible, using other layers, see RFC6282 ch 3.2.2 */
+      ip6hdr->src.addr[0] = PP_HTONL(0xfe800000UL);
+      ip6hdr->src.addr[1] = 0;
+      if (src->addr_len == 2) {
+        ip6hdr->src.addr[2] = PP_HTONL(0x000000ffUL);
+        ip6hdr->src.addr[3] = lwip_htonl(0xfe000000UL | (src->addr[0] << 8) | src->addr[1]);
+      } else if (src->addr_len == 8) {
+        ip6hdr->src.addr[2] = lwip_htonl(((src->addr[0] ^ 2) << 24) | (src->addr[1] << 16) |
+                                         (src->addr[2] << 8) | src->addr[3]);
+        ip6hdr->src.addr[3] = lwip_htonl((src->addr[4] << 24) | (src->addr[5] << 16) |
+                                         (src->addr[6] << 8) | src->addr[7]);
+      } else {
+        /* invalid source address length */
+        LWIP_DEBUGF(LWIP_LOWPAN6_DECOMPRESSION_DEBUG, ("Invalid source address length\n"));
+        return ERR_VAL;
+      }
+    }
+  } else {
+    /* Source address compression (SAC) = 1 -> stateful/context-based compression */
+    LWIP_DEBUGF(LWIP_LOWPAN6_DECOMPRESSION_DEBUG, ("SAC == 1, additional context byte\n"));
+    if ((lowpan6_buffer[1] & 0x30) == 0x00) {
+      /* SAM=00, address=> :: (ANY) */
+      ip6hdr->src.addr[0] = 0;
+      ip6hdr->src.addr[1] = 0;
+      ip6hdr->src.addr[2] = 0;
+      ip6hdr->src.addr[3] = 0;
+      LWIP_DEBUGF(LWIP_LOWPAN6_DECOMPRESSION_DEBUG, ("SAM == 00, context compression, ANY (::)\n"));
+    } else {
+      /* Set prefix from context info */
+      if (lowpan6_buffer[1] & 0x80) {
+        i = (lowpan6_buffer[2] >> 4) & 0x0f;
+      } else {
+        i = 0;
+      }
+      if (i >= LWIP_6LOWPAN_NUM_CONTEXTS) {
+        /* Error */
+        return ERR_VAL;
+      }
+#if LWIP_6LOWPAN_NUM_CONTEXTS > 0
+      ip6hdr->src.addr[0] = lowpan6_contexts[i].addr[0];
+      ip6hdr->src.addr[1] = lowpan6_contexts[i].addr[1];
+      LWIP_DEBUGF(LWIP_LOWPAN6_DECOMPRESSION_DEBUG, ("SAM == xx, context compression found @%d: %8X, %8X\n", (int)i, ip6hdr->src.addr[0], ip6hdr->src.addr[1]));
+#else
+      LWIP_UNUSED_ARG(lowpan6_contexts);
+#endif
+    }
+
+    /* determine further address bits */
+    if ((lowpan6_buffer[1] & 0x30) == 0x10) {
+      /* SAM=01, load additional 64bits */
+      MEMCPY(&ip6hdr->src.addr[2], lowpan6_buffer + lowpan6_offset, 8);
+      LWIP_DEBUGF(LWIP_LOWPAN6_DECOMPRESSION_DEBUG, ("SAM == 01, context compression, 64bits inline\n"));
+      lowpan6_offset += 8;
+    } else if ((lowpan6_buffer[1] & 0x30) == 0x20) {
+      /* SAM=01, load additional 16bits */
+      ip6hdr->src.addr[2] = PP_HTONL(0x000000ffUL);
+      ip6hdr->src.addr[3] = lwip_htonl(0xfe000000UL | (lowpan6_buffer[lowpan6_offset] << 8) | lowpan6_buffer[lowpan6_offset + 1]);
+      LWIP_DEBUGF(LWIP_LOWPAN6_DECOMPRESSION_DEBUG, ("SAM == 10, context compression, 16bits inline\n"));
+      lowpan6_offset += 2;
+    } else if ((lowpan6_buffer[1] & 0x30) == 0x30) {
+      /* SAM=11, address is fully elided, load from other layers */
+      LWIP_DEBUGF(LWIP_LOWPAN6_DECOMPRESSION_DEBUG, ("SAM == 11, context compression, 0bits inline, using other headers\n"));
+      if (src->addr_len == 2) {
+        ip6hdr->src.addr[2] = PP_HTONL(0x000000ffUL);
+        ip6hdr->src.addr[3] = lwip_htonl(0xfe000000UL | (src->addr[0] << 8) | src->addr[1]);
+      } else if (src->addr_len == 8) {
+        ip6hdr->src.addr[2] = lwip_htonl(((src->addr[0] ^ 2) << 24) | (src->addr[1] << 16) | (src->addr[2] << 8) | src->addr[3]);
+        ip6hdr->src.addr[3] = lwip_htonl((src->addr[4] << 24) | (src->addr[5] << 16) | (src->addr[6] << 8) | src->addr[7]);
+      } else {
+        /* invalid source address length */
+        LWIP_DEBUGF(LWIP_LOWPAN6_DECOMPRESSION_DEBUG, ("Invalid source address length\n"));
+        return ERR_VAL;
+      }
+    }
+  }
+
+  /* Destination address decoding. */
+  if (lowpan6_buffer[1] & 0x08) {
+    LWIP_DEBUGF(LWIP_LOWPAN6_DECOMPRESSION_DEBUG, ("M=1: multicast\n"));
+    /* Multicast destination */
+    if (lowpan6_buffer[1] & 0x04) {
+      LWIP_DEBUGF(LWIP_DBG_ON,("DAC == 1, context multicast: unsupported!!!\n"));
+      /* @todo support stateful multicast addressing */
+      return ERR_VAL;
+    }
+
+    if ((lowpan6_buffer[1] & 0x03) == 0x00) {
+      /* DAM = 00, copy full address (128bits) */
+      LWIP_DEBUGF(LWIP_LOWPAN6_DECOMPRESSION_DEBUG, ("DAM == 00, no dst compression, fetching 128bits inline\n"));
+      MEMCPY(&ip6hdr->dest.addr[0], lowpan6_buffer + lowpan6_offset, 16);
+      lowpan6_offset += 16;
+    } else if ((lowpan6_buffer[1] & 0x03) == 0x01) {
+      /* DAM = 01, copy 4 bytes (32bits) */
+      LWIP_DEBUGF(LWIP_LOWPAN6_DECOMPRESSION_DEBUG, ("DAM == 01, dst address form (48bits): ffXX::00XX:XXXX:XXXX\n"));
+      ip6hdr->dest.addr[0] = lwip_htonl(0xff000000UL | (lowpan6_buffer[lowpan6_offset++] << 16));
+      ip6hdr->dest.addr[1] = 0;
+      ip6hdr->dest.addr[2] = lwip_htonl(lowpan6_buffer[lowpan6_offset++]);
+      ip6hdr->dest.addr[3] = lwip_htonl((lowpan6_buffer[lowpan6_offset] << 24) | (lowpan6_buffer[lowpan6_offset + 1] << 16) | (lowpan6_buffer[lowpan6_offset + 2] << 8) | lowpan6_buffer[lowpan6_offset + 3]);
+      lowpan6_offset += 4;
+    } else if ((lowpan6_buffer[1] & 0x03) == 0x02) {
+      /* DAM = 10, copy 3 bytes (24bits) */
+      LWIP_DEBUGF(LWIP_LOWPAN6_DECOMPRESSION_DEBUG, ("DAM == 10, dst address form (32bits): ffXX::00XX:XXXX\n"));
+      ip6hdr->dest.addr[0] = lwip_htonl(0xff000000UL | (lowpan6_buffer[lowpan6_offset++] << 16));
+      ip6hdr->dest.addr[1] = 0;
+      ip6hdr->dest.addr[2] = 0;
+      ip6hdr->dest.addr[3] = lwip_htonl((lowpan6_buffer[lowpan6_offset] << 16) | (lowpan6_buffer[lowpan6_offset + 1] << 8) | lowpan6_buffer[lowpan6_offset + 2]);
+      lowpan6_offset += 3;
+    } else if ((lowpan6_buffer[1] & 0x03) == 0x03) {
+      /* DAM = 11, copy 1 byte (8bits) */
+      LWIP_DEBUGF(LWIP_LOWPAN6_DECOMPRESSION_DEBUG, ("DAM == 11, dst address form (8bits): ff02::00XX\n"));
+      ip6hdr->dest.addr[0] = PP_HTONL(0xff020000UL);
+      ip6hdr->dest.addr[1] = 0;
+      ip6hdr->dest.addr[2] = 0;
+      ip6hdr->dest.addr[3] = lwip_htonl(lowpan6_buffer[lowpan6_offset++]);
+    }
+
+  } else {
+    /* no Multicast (M=0) */
+    if (lowpan6_buffer[1] & 0x04) {
+      LWIP_DEBUGF(LWIP_LOWPAN6_DECOMPRESSION_DEBUG, ("DAC == 1, stateful compression\n"));
+      /* Stateful destination compression */
+      /* Set prefix from context info */
+      if (lowpan6_buffer[1] & 0x80) {
+        i = lowpan6_buffer[2] & 0x0f;
+      } else {
+        i = 0;
+      }
+      if (i >= LWIP_6LOWPAN_NUM_CONTEXTS) {
+        /* Error */
+        return ERR_VAL;
+      }
+#if LWIP_6LOWPAN_NUM_CONTEXTS > 0
+      ip6hdr->dest.addr[0] = lowpan6_contexts[i].addr[0];
+      ip6hdr->dest.addr[1] = lowpan6_contexts[i].addr[1];
+#endif
+    } else {
+      LWIP_DEBUGF(LWIP_LOWPAN6_DECOMPRESSION_DEBUG, ("DAC == 0, stateless compression, setting link local prefix\n"));
+      /* Link local address compression */
+      ip6hdr->dest.addr[0] = PP_HTONL(0xfe800000UL);
+      ip6hdr->dest.addr[1] = 0;
+    }
+
+    /* M=0, DAC=0, determining destination address length via DAM=xx */
+    if ((lowpan6_buffer[1] & 0x03) == 0x00) {
+      LWIP_DEBUGF(LWIP_LOWPAN6_DECOMPRESSION_DEBUG, ("DAM == 00, no dst compression, fetching 128bits inline"));
+      /* DAM=00, copy full address */
+      MEMCPY(&ip6hdr->dest.addr[0], lowpan6_buffer + lowpan6_offset, 16);
+      lowpan6_offset += 16;
+    } else if ((lowpan6_buffer[1] & 0x03) == 0x01) {
+      LWIP_DEBUGF(LWIP_LOWPAN6_DECOMPRESSION_DEBUG, ("DAM == 01, dst compression, 64bits inline\n"));
+      /* DAM=01, copy 64 inline bits, increase offset */
+      MEMCPY(&ip6hdr->dest.addr[2], lowpan6_buffer + lowpan6_offset, 8);
+      lowpan6_offset += 8;
+    } else if ((lowpan6_buffer[1] & 0x03) == 0x02) {
+      LWIP_DEBUGF(LWIP_LOWPAN6_DECOMPRESSION_DEBUG, ("DAM == 01, dst compression, 16bits inline\n"));
+      /* DAM=10, copy 16 inline bits, increase offset */
+      ip6hdr->dest.addr[2] = PP_HTONL(0x000000ffUL);
+      ip6hdr->dest.addr[3] = lwip_htonl(0xfe000000UL | (lowpan6_buffer[lowpan6_offset] << 8) | lowpan6_buffer[lowpan6_offset + 1]);
+      lowpan6_offset += 2;
+    } else if ((lowpan6_buffer[1] & 0x03) == 0x03) {
+      /* DAM=11, no bits available, use other headers (not done here) */
+      LWIP_DEBUGF(LWIP_LOWPAN6_DECOMPRESSION_DEBUG,("DAM == 01, dst compression, 0bits inline, using other headers\n"));
+      if (dest->addr_len == 2) {
+        ip6hdr->dest.addr[2] = PP_HTONL(0x000000ffUL);
+        ip6hdr->dest.addr[3] = lwip_htonl(0xfe000000UL | (dest->addr[0] << 8) | dest->addr[1]);
+      } else if (dest->addr_len == 8) {
+        ip6hdr->dest.addr[2] = lwip_htonl(((dest->addr[0] ^ 2) << 24) | (dest->addr[1] << 16) | dest->addr[2] << 8 | dest->addr[3]);
+        ip6hdr->dest.addr[3] = lwip_htonl((dest->addr[4] << 24) | (dest->addr[5] << 16) | dest->addr[6] << 8 | dest->addr[7]);
+      } else {
+        /* invalid destination address length */
+        LWIP_DEBUGF(LWIP_LOWPAN6_DECOMPRESSION_DEBUG, ("Invalid destination address length\n"));
+        return ERR_VAL;
+      }
+    }
+  }
+
+
+  /* Next Header Compression (NHC) decoding? */
+  if (lowpan6_buffer[0] & 0x04) {
+    LWIP_DEBUGF(LWIP_LOWPAN6_DECOMPRESSION_DEBUG, ("NHC decoding\n"));
+#if LWIP_UDP
+    if ((lowpan6_buffer[lowpan6_offset] & 0xf8) == 0xf0) {
+      /* NHC: UDP */
+      struct udp_hdr *udphdr;
+      LWIP_DEBUGF(LWIP_LOWPAN6_DECOMPRESSION_DEBUG, ("NHC: UDP\n"));
+
+      /* UDP compression */
+      IP6H_NEXTH_SET(ip6hdr, IP6_NEXTH_UDP);
+      udphdr = (struct udp_hdr *)((u8_t *)decomp_buffer + ip6_offset);
+      if (decomp_bufsize < IP6_HLEN + UDP_HLEN) {
+        return ERR_MEM;
+      }
+
+      /* Checksum decompression */
+      if (lowpan6_buffer[lowpan6_offset] & 0x04) {
+        /* @todo support checksum decompress */
+        LWIP_DEBUGF(LWIP_DBG_ON, ("NHC: UDP chechsum decompression UNSUPPORTED\n"));
+        return ERR_VAL;
+      }
+
+      /* Decompress ports, according to RFC4944 */
+      i = lowpan6_buffer[lowpan6_offset++] & 0x03;
+      if (i == 0) {
+        udphdr->src = lwip_htons(lowpan6_buffer[lowpan6_offset] << 8 | lowpan6_buffer[lowpan6_offset + 1]);
+        udphdr->dest = lwip_htons(lowpan6_buffer[lowpan6_offset + 2] << 8 | lowpan6_buffer[lowpan6_offset + 3]);
+        lowpan6_offset += 4;
+      } else if (i == 0x01) {
+        udphdr->src = lwip_htons(lowpan6_buffer[lowpan6_offset] << 8 | lowpan6_buffer[lowpan6_offset + 1]);
+        udphdr->dest = lwip_htons(0xf000 | lowpan6_buffer[lowpan6_offset + 2]);
+        lowpan6_offset += 3;
+      } else if (i == 0x02) {
+        udphdr->src = lwip_htons(0xf000 | lowpan6_buffer[lowpan6_offset]);
+        udphdr->dest = lwip_htons(lowpan6_buffer[lowpan6_offset + 1] << 8 | lowpan6_buffer[lowpan6_offset + 2]);
+        lowpan6_offset += 3;
+      } else if (i == 0x03) {
+        udphdr->src = lwip_htons(0xf0b0 | ((lowpan6_buffer[lowpan6_offset] >> 4) & 0x0f));
+        udphdr->dest = lwip_htons(0xf0b0 | (lowpan6_buffer[lowpan6_offset] & 0x0f));
+        lowpan6_offset += 1;
+      }
+
+      udphdr->chksum = lwip_htons(lowpan6_buffer[lowpan6_offset] << 8 | lowpan6_buffer[lowpan6_offset + 1]);
+      lowpan6_offset += 2;
+      ip6_offset += UDP_HLEN;
+      if (datagram_size == 0) {
+        datagram_size = compressed_size - lowpan6_offset + ip6_offset;
+      }
+      udphdr->len = lwip_htons(datagram_size - IP6_HLEN);
+
+    } else
+#endif /* LWIP_UDP */
+    {
+      LWIP_DEBUGF(LWIP_DBG_ON,("NHC: unsupported protocol!\n"));
+      /* @todo support NHC other than UDP */
+      return ERR_VAL;
+    }
+  }
+  if (datagram_size == 0) {
+    datagram_size = compressed_size - lowpan6_offset + ip6_offset;
+  }
+  /* Infer IPv6 payload length for header */
+  IP6H_PLEN_SET(ip6hdr, datagram_size - IP6_HLEN);
+
+  if (lowpan6_offset > lowpan6_bufsize) {
+    /* input buffer overflow */
+    return ERR_VAL;
+  }
+  *hdr_size_comp = lowpan6_offset;
+  *hdr_size_decomp = ip6_offset;
+
+  return ERR_OK;
+}
+
+struct pbuf *
+lowpan6_decompress(struct pbuf *p, u16_t datagram_size, ip6_addr_t *lowpan6_contexts,
+                   struct lowpan6_link_addr *src, struct lowpan6_link_addr *dest)
+{
+  struct pbuf *q;
+  u16_t lowpan6_offset, ip6_offset;
+  err_t err;
+
+#if LWIP_UDP
+#define UDP_HLEN_ALLOC UDP_HLEN
+#else
+#define UDP_HLEN_ALLOC 0
+#endif
+
+  /* Allocate a buffer for decompression. This buffer will be too big and will be
+     trimmed once the final size is known. */
+  q = pbuf_alloc(PBUF_IP, p->len + IP6_HLEN + UDP_HLEN_ALLOC, PBUF_POOL);
+  if (q == NULL) {
+    pbuf_free(p);
+    return NULL;
+  }
+  if (q->len < IP6_HLEN + UDP_HLEN_ALLOC) {
+    /* The headers need to fit into the first pbuf */
+    pbuf_free(p);
+    pbuf_free(q);
+    return NULL;
+  }
+
+  /* Decompress the IPv6 (and possibly UDP) header(s) into the new pbuf */
+  err = lowpan6_decompress_hdr((u8_t *)p->payload, p->len, (u8_t *)q->payload, q->len,
+    &lowpan6_offset, &ip6_offset, datagram_size, p->tot_len, lowpan6_contexts, src, dest);
+  if (err != ERR_OK) {
+    pbuf_free(p);
+    pbuf_free(q);
+    return NULL;
+  }
+
+  /* Now we copy leftover contents from p to q, so we have all L2 and L3 headers
+     (and L4?) in a single pbuf: */
+
+  /* Hide the compressed headers in p */
+  pbuf_remove_header(p, lowpan6_offset);
+  /* Temporarily hide the headers in q... */
+  pbuf_remove_header(q, ip6_offset);
+  /* ... copy the rest of p into q... */
+  pbuf_copy(q, p);
+  /* ... and reveal the headers again... */
+  pbuf_add_header_force(q, ip6_offset);
+  /* ... trim the pbuf to its correct size... */
+  pbuf_realloc(q, ip6_offset + p->len);
+  /* ... and cat possibly remaining (data-only) pbufs */
+  if (p->next != NULL) {
+    pbuf_cat(q, p->next);
+  }
+  /* the original (first) pbuf can now be freed */
+  p->next = NULL;
+  pbuf_free(p);
+
+  /* all done */
+  return q;
+}
+
+#endif /* LWIP_6LOWPAN_IPHC */
+#endif /* LWIP_IPV6 */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/netif/ppp/PPPD_FOLLOWUP
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/netif/ppp/PPPD_FOLLOWUP	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/netif/ppp/PPPD_FOLLOWUP	(revision 457)
@@ -0,0 +1,473 @@
+The lwIP PPP support is based from pppd 2.4.5 (http://ppp.samba.org) with
+huge changes to match code size and memory requirements for embedded devices.
+
+Anyway, pppd has a mature codebase for years and the average commit count
+is getting low on their Git repository, meaning that we can follow what
+is happening on their side and merge what is relevant for lwIP.
+
+So, here is the pppd follow up, so that we don't get away too far from pppd.
+
+
+== Patch fetched from from pppd Debian packages ==
+
+This has nothing to do with pppd, but we merged some good patch from
+Debian and this is a good place to be.
+
+- LCP adaptive echo, so that we don't send LCP echo request if we
+  are receiving data from peer, can be enabled by setting PPP_LCP_ADAPTIVE
+  to true.
+ 
+- IPCP no/replace default route option, were added in the early stage of
+  the ppp port, but it wasn't really helpful and was disabled when adding
+  the new API ppp_set_default() call, which gives the lwIP user control over
+  which one is the default interface, it was actually a requirement if you
+  are doing PPP over PPP (i.e. PPPoL2TP, VPN link, over PPPoE, ADSL link).
+
+- using rp-pppoe pppd exits with EXIT_OK after receiving a timeout waiting
+  for PADO due to no modem attached, bug reported to pppd bug tracker, fixed
+  in Debian but not in the latest (at the time when the port were started)
+  pppd release.
+
+
+== Commits on pppd ==
+
+2010-03-06 - Document +ipv6 and ipv6cp-accept-local
+  e7537958aee79b3f653c601e903cb31d78fb7dcc
+
+Don't care.
+
+
+2010-03-06 - Install pppol2tp plugins with sane permissions
+  406215672cfadc03017341fe03802d1c7294b903
+
+Don't care.
+
+
+2010-03-07 - pppd: Terminate correctly if lcp_lowerup delayed calling
+             fsm_lowerup
+  3eb9e810cfa515543655659b72dde30c54fea0a5
+
+Merged 2012-05-17.
+
+
+2010-03-07 - rp_pppoe: Copy acName and pppd_pppoe_service after option parsing
+  cab58617fd9d328029fffabc788020264b4fa91f
+
+Don't care, is a patch for pppd/plugins/rp-pppoe/plugin.c which is not part
+of the port.
+
+
+2010-08-23 - set and reset options to control environment variables
+             for scripts.
+  2b6310fd24dba8e0fca8999916a162f0a1842a84
+
+We can't fork processes in embedded, therefore all the pppd process run
+feature is disabled in the port, so we don't care about the new
+"environment variables" pppd feature.
+
+
+2010-08-23 - Nit: use _exit when exec fails and restrict values to 0-255
+             per POSIX.
+  2b4ea140432eeba5a007c0d4e6236bd0e0c12ba4
+
+Again, we are not running as a heavy process, so all exit() or _exit() calls
+were removed.
+
+
+2010-08-23 - Fix quote handling in configuration files to be more like shell
+             quoting.
+  3089132cdf5b58dbdfc2daf08ec5c08eb47f8aca
+
+We are not parsing config file, all the filesystem I/O stuff were disabled
+in our port.
+
+
+2010-08-24 - rp-pppoe: allow MTU to be increased up to 1500
+  fd1dcdf758418f040da3ed801ab001b5e46854e7
+
+Only concern changes on RP-PPPoE plugin, which we don't use.
+
+
+2010-09-11 - chat: Allow TIMEOUT value to come from environment variable
+  ae80bf833e48a6202f44a935a68083ae52ad3824
+
+See 2b6310fd24dba8e0fca8999916a162f0a1842a84.
+
+
+2011-03-05 - pppdump: Fix printfs with insufficient arguments
+  7b8db569642c83ba3283745034f2e2c95e459423
+
+pppdump is a ppp tool outside pppd source tree.
+
+
+2012-05-06 - pppd: Don't unconditionally disable VJ compression under Linux
+  d8a66adf98a0e525cf38031b42098d539da6eeb6
+
+Patch for sys-linux.c, which we don't use.
+
+
+2012-05-20 - Remove old version of Linux if_pppol2tp.h
+  c41092dd4c49267f232f6cba3d31c6c68bfdf68d
+
+Not in the port.
+
+
+2012-05-20 - pppd: Make MSCHAP-v2 cope better with packet loss
+  08ef47ca532294eb428238c831616748940e24a2
+
+This is an interesting patch. However it consumes much more memory for
+MSCHAP and I am not sure if the benefit worth it. The PPP client can
+always start the authentication again if it failed for whatever reason.
+
+
+2012-05-20 - scripts: Make poff ignore extra arguments to pppd
+  18f515f32c9f5723a9c2c912601e04335106534b
+
+Again, we are not running scripts.
+
+
+2012-05-20 - rp-pppoe plugin: Print leading zeros in MAC address
+  f5dda0cfc220c4b52e26144096d729e27b30f0f7
+
+Again, we are not using the RP-PPPoE plugin.
+
+
+2012-05-20 - pppd: Notify IPv6 up/down as we do for IPv4
+  845cda8fa18939cf56e60b073f63a7efa65336fc
+
+This is just a patch that adds plugins hooks for IPv6, the plugin interface
+was disabled because we don't have .so plugins in embedded.
+
+
+2012-05-20 - pppd: Enable IPV6 by default and fix some warnings
+  0b6118239615e98959f7e0b4e746bdd197533248
+
+Change on Makefile for IPv6, warnings were already cleared during port.
+
+
+2012-05-20 - contrib: Fix pppgetpass.gtk compilation
+  80a8e2ce257ca12cce723519a0f20ea1d663b14a
+
+Change on Makefile, don't care.
+
+
+2012-05-20 - pppd: Don't crash if crypt() returns NULL
+  04c4348108d847e034dd91066cc6843f60d71731
+
+We are using the PolarSSL DES implementation that does not return NULL.
+
+
+2012-05-20 - pppd: Eliminate some warnings
+  c44ae5e6a7338c96eb463881fe709b2dfaffe568
+
+Again, we are handling compilation warnings on our own.
+
+
+2012-05-20 - rp-pppoe plugin: Import some fixes from rp-pppoe-3.10
+  1817d83e51a411044e730ba89ebdb0480e1c8cd4
+
+Once more, we are not using the RP-PPPoE plugin.
+
+
+2013-01-23 - pppd: Clarify circumstances where DNS1/DNS2 environment variables are set
+  cf2f5c9538b9400ade23446a194729b0a4113b3a
+
+Documentation only.
+
+
+2013-02-03 - ppp: ignore unrecognised radiusclient configuration directives
+  7f736dde0da3c19855997d9e67370e351e15e923
+
+Radius plugin, not in the port.
+
+
+2013-02-03 - pppd: Take out unused %r conversion completely
+  356d8d558d844412119aa18c8e5a113bc6459c7b
+
+Merged 2014-04-15.
+
+
+2013-02-03 - pppd: Arrange to use logwtmp from libutil on Linux
+  9617a7eb137f4fee62799a677a9ecf8d834db3f5
+
+Patch for sys-linux.c, which we don't use.
+
+
+2013-02-03 - pppdump: Eliminate some compiler warnings
+  3e3acf1ba2b3046c072a42c19164788a9e419bd1
+
+pppdump is a ppp tool outside pppd source tree.
+
+
+2013-02-03 - chat: Correct spelling errors in the man page
+  8dea1b969d266ccbf6f3a8c5474eb6dcd8838e3b
+
+Documentation only.
+
+
+2013-02-03 - pppd: Fix spelling errors in man page
+  9e05a25d76b3f83096c661678010320df673df6b
+
+Documentation only.
+
+
+2013-02-03 - plugins/passprompt: Fix potential out-of-bounds array reference
+  8edb889b753056a691a3e4b217a110a35f9fdedb
+
+Plugin patch, we do not have plugins.
+
+
+2013-02-03 - chat: Fix *roff errors in the man page
+  a7c3489eeaf44e83ce592143c7c8a5b5c29f4c48
+
+Documentation only.
+
+
+2013-03-02 - pppd: Fix man page description of case when remote IP address isn't known
+  224841f4799f4f1e2e71bc490c54448d66740f4f
+
+Documentation only.
+
+
+2013-03-02 - pppd: Add master_detach option
+  398ed2585640d198c53e736ee5bbd67f7ce8168e
+
+Option for multilink support, we do not support multilink and this option
+is about detaching from the terminal, which is out of the embedded scope.
+
+
+2013-03-11 - pppd: Default exit status to EXIT_CONNECT_FAILED during connection phase
+  225361d64ae737afdc8cb57579a2f33525461bc9
+
+Commented out in our port, and already fixed by a previously applied Debian patch.
+
+
+2013-03-11 - pppstats: Fix undefined macro in man page
+  d16a3985eade5280b8e171f5dd0670a91cba0d39
+
+Documentation only.
+
+
+2013-05-11 - plugins/radius: Handle bindaddr keyword in radiusclient.conf
+  d883b2dbafeed3ebd9d7a56ab1469373bd001a3b
+
+Radius plugin, not in the port.
+
+
+2013-06-09 - pppoatm: Remove explicit loading of pppoatm kernel module
+  52cd43a84bea524033b918b603698104f221bbb7
+
+PPPoATM plugin, not in the port.
+
+
+2013-06-09 - pppd: Fix segfault in update_db_entry()
+  37476164f15a45015310b9d4b197c2d7db1f7f8f
+
+We do not use the samba db.
+
+
+2013-06-09 - chat: Fix some text that was intended to be literal
+  cd9683676618adcee8add2c3cfa3382341b5a1f6
+
+Documentation only.
+
+
+2013-06-09 - README.pppoe: Minor semantic fix
+  b5b8898af6fd3d44e873cfc66810ace5f1f47e17
+
+Documentation only.
+
+
+2013-06-10 - radius: Handle additional attributes
+  2f581cd986a56f2ec4a95abad4f8297a1b10d7e2
+
+Radius plugin, not in the port.
+
+
+2013-06-10 - chat, pppd: Use \e instead of \\ in man pages
+  8d6942415d22f6ca4377340ca26e345c3f5fa5db
+
+Documentation only.
+
+
+2014-01-02 - pppd: Don't crash if NULL pointer passed to vslprintf for %q or %v
+  906814431bddeb2061825fa1ebad1a967b6d87a9
+
+Merged 2014-04-15.
+
+
+2014-01-02 - pppd: Accept IPCP ConfAck packets containing MS-WINS options
+  a243f217f1c6ac1aa7793806bc88590d077f490a
+
+Merged 2014-04-15.
+
+
+2014-01-02 - config: Update Solaris compiler options and enable CHAPMS and IPV6
+  99c46caaed01b7edba87962aa52b77fad61bfd7b
+
+Solaris port, don't care.
+
+
+2014-01-02 - Update README and patchlevel for 2.4.6 release
+  4043750fca36e7e0eb90d702e048ad1da4929418
+
+Just release stuff.
+
+
+2014-02-18 - pppd: Add option "stop-bits" to set number of serial port stop bits.
+  ad993a20ee485f0d0e2ac4105221641b200da6e2
+
+Low level serial port, not in the port.
+
+
+2014-03-09 - pppd: Separate IPv6 handling for sifup/sifdown
+  b04d2dc6df5c6b5650fea44250d58757ee3dac4a
+
+Reimplemented.
+
+
+2014-03-09 - pppol2tp: Connect up/down events to notifiers and add IPv6 ones
+  fafbe50251efc7d6b4a8be652d085316e112b34f
+
+Not in the port.
+
+
+2014-03-09 - pppd: Add declarations to eliminate compile warnings
+  50967962addebe15c7a7e63116ff46a0441dc464
+
+We are handling compilation warnings on our own
+
+
+2014-03-09 - pppd: Eliminate some unnecessary ifdefs
+  de8da14d845ee6db9236ccfddabf1d8ebf045ddb
+
+We mostly did that previously. Anyway, merged 2014-12-24.
+
+
+2014-08-01 - radius: Fix realms-config-file option
+  880a81be7c8e0fe8567227bc17a1bff3ea035943
+
+Radius plugin, not in the port.
+
+
+2014-08-01 - pppd: Eliminate potential integer overflow in option parsing
+  7658e8257183f062dc01f87969c140707c7e52cb
+
+pppd config file parser, not in the port.
+
+
+2014-08-01 - pppd: Eliminate memory leak with multiple instances of a string option
+  b94b7fbbaa0589aa6ec5fdc733aeb9ff294d2656
+
+pppd config file parser, not in the port.
+
+
+2014-08-01 - pppd: Fix a stack variable overflow in MSCHAP-v2
+  36733a891fb56594fcee580f667b33a64b990981
+
+This fixes a bug introduced in 08ef47ca ("pppd: Make MSCHAP-v2 cope better with packet loss").
+
+We didn't merge 08ef47ca ;-)
+
+
+2014-08-01 - winbind plugin: Add -DMPPE=1 to eliminate compiler warnings
+  2b05e22c62095e97dd0a97e4b5588402c2185071
+
+Linux plugin, not in the port.
+
+
+2014-08-09 - Update README and patchlevel for 2.4.7 release
+  6e8eaa7a78b31cdab2edf140a9c8afdb02ffaca5
+
+Just release stuff.
+
+
+2014-08-10 - abort on errors in subdir builds
+  5e90783d11a59268e05f4cfb29ce2343b13e8ab2
+
+Linux Makefile, not in the port.
+
+
+2014-06-03 - pppd: add support for defaultroute-metric option
+  35e5a569c988b1ff865b02a24d9a727a00db4da9
+
+Only necessary for Linux, lwIP does not support route metrics.
+
+
+2014-12-13 - scripts: Avoid killing wrong pppd
+  67811a647d399db5d188a242827760615a0f86b5
+
+pppd helper script, not in the port.
+
+
+2014-12-20 - pppd: Fix sign-extension when displaying bytes in octal
+  5e8c3cb256a7e86e3572a82a75d51c6850efdbdc
+
+Merged 2016-07-02.
+
+
+2015-03-01 - Suppress false error message on PPPoE disconnect
+  219aac3b53d0827549377f1bfe22853ee52d4405
+
+PPPoE plugin, not in the port.
+
+
+2015-03-01 - Send PADT on PPPoE disconnect
+  cd2c14f998c57bbe6a01dc5854f2763c0d7f31fb
+
+PPPoE plugin, not in the port. And our PPPoE implementation already does
+that: pppoe_disconnect() calls pppoe_send_padt().
+
+
+2015-08-14 - pppd: ipxcp: Prevent buffer overrun on remote router name
+  fe149de624f96629a7f46732055d8f718c74b856
+
+We never ported IPX support. lwIP does not support IPX.
+
+
+2015-03-25 - pppd: Fix ccp_options.mppe type
+  234edab99a6bb250cc9ecd384cca27b0c8b475ce
+
+We found that while working on MPPE support in lwIP, that's our patch ;-)
+
+
+2015-03-24 - pppd: Fix ccp_cilen calculated size if both deflate_correct and deflate_draft are enabled
+  094cb8ae4c61db225e67fedadb4964f846dd0c27
+
+We found that while working on MPPE support in lwIP, that's our patch ;-)
+
+
+2015-08-14 - Merge branch 'master' of https://github.com/ncopa/ppp
+  3a5c9a8fbc8970375cd881151d44e4b6fe249c6a
+
+Merge commit, we don't care.
+
+
+2015-08-14 - Merge branch 'master' of git://github.com/vapier/ppp
+  912e4fc6665aca188dced7ea7fdc663ce5a2dd24
+
+Merge commit, we don't care.
+
+
+2015-08-14 - Merge branch 'bug_fix' of git://github.com/radaiming/ppp
+  dfd33d7f526ecd7b39dd1bba8101260d02af5ebb
+
+Merge commit, we don't care.
+
+
+2015-08-14 - Merge branch 'master' of git://github.com/pprindeville/ppp
+  aa4a985f6114d08cf4e47634fb6325da71016473
+
+Merge commit, we don't care.
+
+
+2015-08-14 - Merge branch 'no-error-on-already-closed' of git://github.com/farnz/ppp
+  6edf252483b30dbcdcc5059f01831455365d5b6e
+
+Merge commit, we don't care.
+
+
+2015-08-14 - Merge branch 'send-padt-on-disconnect' of git://github.com/farnz/ppp
+  84684243d651f55f6df69d2a6707b52fbbe62bb9
+
+Merge commit, we don't care.
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/netif/ppp/auth.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/netif/ppp/auth.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/netif/ppp/auth.c	(revision 457)
@@ -0,0 +1,2510 @@
+/*
+ * auth.c - PPP authentication and phase control.
+ *
+ * Copyright (c) 1993-2002 Paul Mackerras. 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. The name(s) of the authors of this software must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission.
+ *
+ * 3. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by Paul Mackerras
+ *     <paulus@samba.org>".
+ *
+ * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO
+ * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
+ * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
+ * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
+ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Derived from main.c, which is:
+ *
+ * Copyright (c) 1984-2000 Carnegie Mellon University. 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. The name "Carnegie Mellon University" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For permission or any legal
+ *    details, please contact
+ *      Office of Technology Transfer
+ *      Carnegie Mellon University
+ *      5000 Forbes Avenue
+ *      Pittsburgh, PA  15213-3890
+ *      (412) 268-4387, fax: (412) 268-7395
+ *      tech-transfer@andrew.cmu.edu
+ *
+ * 4. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by Computing Services
+ *     at Carnegie Mellon University (http://www.cmu.edu/computing/)."
+ *
+ * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO
+ * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE
+ * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
+ * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
+ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include "netif/ppp/ppp_opts.h"
+#if PPP_SUPPORT /* don't build if not configured for use in lwipopts.h */
+
+#if 0 /* UNUSED */
+#include <stdio.h>
+#include <stddef.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <errno.h>
+#include <pwd.h>
+#include <grp.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/socket.h>
+#include <utmp.h>
+#include <fcntl.h>
+#if defined(_PATH_LASTLOG) && defined(__linux__)
+#include <lastlog.h>
+#endif
+
+#include <netdb.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+
+#ifdef HAS_SHADOW
+#include <shadow.h>
+#ifndef PW_PPP
+#define PW_PPP PW_LOGIN
+#endif
+#endif
+
+#include <time.h>
+#endif /* UNUSED */
+
+#include "netif/ppp/ppp_impl.h"
+
+#include "netif/ppp/fsm.h"
+#include "netif/ppp/lcp.h"
+#if CCP_SUPPORT
+#include "netif/ppp/ccp.h"
+#endif /* CCP_SUPPORT */
+#if ECP_SUPPORT
+#include "netif/ppp/ecp.h"
+#endif /* ECP_SUPPORT */
+#include "netif/ppp/ipcp.h"
+#if PAP_SUPPORT
+#include "netif/ppp/upap.h"
+#endif /* PAP_SUPPORT */
+#if CHAP_SUPPORT
+#include "netif/ppp/chap-new.h"
+#endif /* CHAP_SUPPORT */
+#if EAP_SUPPORT
+#include "netif/ppp/eap.h"
+#endif /* EAP_SUPPORT */
+#if CBCP_SUPPORT
+#include "netif/ppp/cbcp.h"
+#endif
+
+#if 0 /* UNUSED */
+#include "session.h"
+#endif /* UNUSED */
+
+#if 0 /* UNUSED */
+/* Bits in scan_authfile return value */
+#define NONWILD_SERVER	1
+#define NONWILD_CLIENT	2
+
+#define ISWILD(word)	(word[0] == '*' && word[1] == 0)
+#endif /* UNUSED */
+
+#if 0 /* UNUSED */
+/* List of addresses which the peer may use. */
+static struct permitted_ip *addresses[NUM_PPP];
+
+/* Wordlist giving addresses which the peer may use
+   without authenticating itself. */
+static struct wordlist *noauth_addrs;
+
+/* Remote telephone number, if available */
+char remote_number[MAXNAMELEN];
+
+/* Wordlist giving remote telephone numbers which may connect. */
+static struct wordlist *permitted_numbers;
+
+/* Extra options to apply, from the secrets file entry for the peer. */
+static struct wordlist *extra_options;
+#endif /* UNUSED */
+
+#if 0 /* UNUSED */
+/* Set if we require authentication only because we have a default route. */
+static bool default_auth;
+
+/* Hook to enable a plugin to control the idle time limit */
+int (*idle_time_hook) (struct ppp_idle *) = NULL;
+
+/* Hook for a plugin to say whether we can possibly authenticate any peer */
+int (*pap_check_hook) (void) = NULL;
+
+/* Hook for a plugin to check the PAP user and password */
+int (*pap_auth_hook) (char *user, char *passwd, char **msgp,
+			  struct wordlist **paddrs,
+			  struct wordlist **popts) = NULL;
+
+/* Hook for a plugin to know about the PAP user logout */
+void (*pap_logout_hook) (void) = NULL;
+
+/* Hook for a plugin to get the PAP password for authenticating us */
+int (*pap_passwd_hook) (char *user, char *passwd) = NULL;
+
+/* Hook for a plugin to say if we can possibly authenticate a peer using CHAP */
+int (*chap_check_hook) (void) = NULL;
+
+/* Hook for a plugin to get the CHAP password for authenticating us */
+int (*chap_passwd_hook) (char *user, char *passwd) = NULL;
+
+/* Hook for a plugin to say whether it is OK if the peer
+   refuses to authenticate. */
+int (*null_auth_hook) (struct wordlist **paddrs,
+			   struct wordlist **popts) = NULL;
+
+int (*allowed_address_hook) (u32_t addr) = NULL;
+#endif /* UNUSED */
+
+#ifdef HAVE_MULTILINK
+/* Hook for plugin to hear when an interface joins a multilink bundle */
+void (*multilink_join_hook) (void) = NULL;
+#endif
+
+#if PPP_NOTIFY
+/* A notifier for when the peer has authenticated itself,
+   and we are proceeding to the network phase. */
+struct notifier *auth_up_notifier = NULL;
+
+/* A notifier for when the link goes down. */
+struct notifier *link_down_notifier = NULL;
+#endif /* PPP_NOTIFY */
+
+/*
+ * Option variables.
+ */
+#if 0 /* MOVED TO ppp_settings */
+bool uselogin = 0;		/* Use /etc/passwd for checking PAP */
+bool session_mgmt = 0;		/* Do session management (login records) */
+bool cryptpap = 0;		/* Passwords in pap-secrets are encrypted */
+bool refuse_pap = 0;		/* Don't wanna auth. ourselves with PAP */
+bool refuse_chap = 0;		/* Don't wanna auth. ourselves with CHAP */
+bool refuse_eap = 0;		/* Don't wanna auth. ourselves with EAP */
+#if MSCHAP_SUPPORT
+bool refuse_mschap = 0;		/* Don't wanna auth. ourselves with MS-CHAP */
+bool refuse_mschap_v2 = 0;	/* Don't wanna auth. ourselves with MS-CHAPv2 */
+#else /* MSCHAP_SUPPORT */
+bool refuse_mschap = 1;		/* Don't wanna auth. ourselves with MS-CHAP */
+bool refuse_mschap_v2 = 1;	/* Don't wanna auth. ourselves with MS-CHAPv2 */
+#endif /* MSCHAP_SUPPORT */
+bool usehostname = 0;		/* Use hostname for our_name */
+bool auth_required = 0;		/* Always require authentication from peer */
+bool allow_any_ip = 0;		/* Allow peer to use any IP address */
+bool explicit_remote = 0;	/* User specified explicit remote name */
+bool explicit_user = 0;		/* Set if "user" option supplied */
+bool explicit_passwd = 0;	/* Set if "password" option supplied */
+char remote_name[MAXNAMELEN];	/* Peer's name for authentication */
+static char *uafname;		/* name of most recent +ua file */
+
+extern char *crypt (const char *, const char *);
+#endif /* UNUSED */
+/* Prototypes for procedures local to this file. */
+
+static void network_phase(ppp_pcb *pcb);
+#if PPP_IDLETIMELIMIT
+static void check_idle(void *arg);
+#endif /* PPP_IDLETIMELIMIT */
+#if PPP_MAXCONNECT
+static void connect_time_expired(void *arg);
+#endif /* PPP_MAXCONNECT */
+#if 0 /* UNUSED */
+static int  null_login (int);
+/* static int  get_pap_passwd (char *); */
+static int  have_pap_secret (int *);
+static int  have_chap_secret (char *, char *, int, int *);
+static int  have_srp_secret (char *client, char *server, int need_ip,
+    int *lacks_ipp);
+static int  ip_addr_check (u32_t, struct permitted_ip *);
+static int  scan_authfile (FILE *, char *, char *, char *,
+			       struct wordlist **, struct wordlist **,
+			       char *, int);
+static void free_wordlist (struct wordlist *);
+static void set_allowed_addrs (int, struct wordlist *, struct wordlist *);
+static int  some_ip_ok (struct wordlist *);
+static int  setupapfile (char **);
+static int  privgroup (char **);
+static int  set_noauth_addr (char **);
+static int  set_permitted_number (char **);
+static void check_access (FILE *, char *);
+static int  wordlist_count (struct wordlist *);
+#endif /* UNUSED */
+
+#ifdef MAXOCTETS
+static void check_maxoctets (void *);
+#endif
+
+#if PPP_OPTIONS
+/*
+ * Authentication-related options.
+ */
+option_t auth_options[] = {
+    { "auth", o_bool, &auth_required,
+      "Require authentication from peer", OPT_PRIO | 1 },
+    { "noauth", o_bool, &auth_required,
+      "Don't require peer to authenticate", OPT_PRIOSUB | OPT_PRIV,
+      &allow_any_ip },
+    { "require-pap", o_bool, &lcp_wantoptions[0].neg_upap,
+      "Require PAP authentication from peer",
+      OPT_PRIOSUB | 1, &auth_required },
+    { "+pap", o_bool, &lcp_wantoptions[0].neg_upap,
+      "Require PAP authentication from peer",
+      OPT_ALIAS | OPT_PRIOSUB | 1, &auth_required },
+    { "require-chap", o_bool, &auth_required,
+      "Require CHAP authentication from peer",
+      OPT_PRIOSUB | OPT_A2OR | MDTYPE_MD5,
+      &lcp_wantoptions[0].chap_mdtype },
+    { "+chap", o_bool, &auth_required,
+      "Require CHAP authentication from peer",
+      OPT_ALIAS | OPT_PRIOSUB | OPT_A2OR | MDTYPE_MD5,
+      &lcp_wantoptions[0].chap_mdtype },
+#if MSCHAP_SUPPORT
+    { "require-mschap", o_bool, &auth_required,
+      "Require MS-CHAP authentication from peer",
+      OPT_PRIOSUB | OPT_A2OR | MDTYPE_MICROSOFT,
+      &lcp_wantoptions[0].chap_mdtype },
+    { "+mschap", o_bool, &auth_required,
+      "Require MS-CHAP authentication from peer",
+      OPT_ALIAS | OPT_PRIOSUB | OPT_A2OR | MDTYPE_MICROSOFT,
+      &lcp_wantoptions[0].chap_mdtype },
+    { "require-mschap-v2", o_bool, &auth_required,
+      "Require MS-CHAPv2 authentication from peer",
+      OPT_PRIOSUB | OPT_A2OR | MDTYPE_MICROSOFT_V2,
+      &lcp_wantoptions[0].chap_mdtype },
+    { "+mschap-v2", o_bool, &auth_required,
+      "Require MS-CHAPv2 authentication from peer",
+      OPT_ALIAS | OPT_PRIOSUB | OPT_A2OR | MDTYPE_MICROSOFT_V2,
+      &lcp_wantoptions[0].chap_mdtype },
+#endif /* MSCHAP_SUPPORT */
+#if 0
+    { "refuse-pap", o_bool, &refuse_pap,
+      "Don't agree to auth to peer with PAP", 1 },
+    { "-pap", o_bool, &refuse_pap,
+      "Don't allow PAP authentication with peer", OPT_ALIAS | 1 },
+    { "refuse-chap", o_bool, &refuse_chap,
+      "Don't agree to auth to peer with CHAP",
+      OPT_A2CLRB | MDTYPE_MD5,
+      &lcp_allowoptions[0].chap_mdtype },
+    { "-chap", o_bool, &refuse_chap,
+      "Don't allow CHAP authentication with peer",
+      OPT_ALIAS | OPT_A2CLRB | MDTYPE_MD5,
+      &lcp_allowoptions[0].chap_mdtype },
+#endif
+#if MSCHAP_SUPPORT
+#if 0
+    { "refuse-mschap", o_bool, &refuse_mschap,
+      "Don't agree to auth to peer with MS-CHAP",
+      OPT_A2CLRB | MDTYPE_MICROSOFT,
+      &lcp_allowoptions[0].chap_mdtype },
+    { "-mschap", o_bool, &refuse_mschap,
+      "Don't allow MS-CHAP authentication with peer",
+      OPT_ALIAS | OPT_A2CLRB | MDTYPE_MICROSOFT,
+      &lcp_allowoptions[0].chap_mdtype },
+    { "refuse-mschap-v2", o_bool, &refuse_mschap_v2,
+      "Don't agree to auth to peer with MS-CHAPv2",
+      OPT_A2CLRB | MDTYPE_MICROSOFT_V2,
+      &lcp_allowoptions[0].chap_mdtype },
+    { "-mschap-v2", o_bool, &refuse_mschap_v2,
+      "Don't allow MS-CHAPv2 authentication with peer",
+      OPT_ALIAS | OPT_A2CLRB | MDTYPE_MICROSOFT_V2,
+      &lcp_allowoptions[0].chap_mdtype },
+#endif
+#endif /* MSCHAP_SUPPORT*/
+#if EAP_SUPPORT
+    { "require-eap", o_bool, &lcp_wantoptions[0].neg_eap,
+      "Require EAP authentication from peer", OPT_PRIOSUB | 1,
+      &auth_required },
+#if 0
+    { "refuse-eap", o_bool, &refuse_eap,
+      "Don't agree to authenticate to peer with EAP", 1 },
+#endif
+#endif /* EAP_SUPPORT */
+    { "name", o_string, our_name,
+      "Set local name for authentication",
+      OPT_PRIO | OPT_PRIV | OPT_STATIC, NULL, MAXNAMELEN },
+
+    { "+ua", o_special, (void *)setupapfile,
+      "Get PAP user and password from file",
+      OPT_PRIO | OPT_A2STRVAL, &uafname },
+
+#if 0
+    { "user", o_string, user,
+      "Set name for auth with peer", OPT_PRIO | OPT_STATIC,
+      &explicit_user, MAXNAMELEN },
+
+    { "password", o_string, passwd,
+      "Password for authenticating us to the peer",
+      OPT_PRIO | OPT_STATIC | OPT_HIDE,
+      &explicit_passwd, MAXSECRETLEN },
+#endif
+
+    { "usehostname", o_bool, &usehostname,
+      "Must use hostname for authentication", 1 },
+
+    { "remotename", o_string, remote_name,
+      "Set remote name for authentication", OPT_PRIO | OPT_STATIC,
+      &explicit_remote, MAXNAMELEN },
+
+    { "login", o_bool, &uselogin,
+      "Use system password database for PAP", OPT_A2COPY | 1 ,
+      &session_mgmt },
+    { "enable-session", o_bool, &session_mgmt,
+      "Enable session accounting for remote peers", OPT_PRIV | 1 },
+
+    { "papcrypt", o_bool, &cryptpap,
+      "PAP passwords are encrypted", 1 },
+
+    { "privgroup", o_special, (void *)privgroup,
+      "Allow group members to use privileged options", OPT_PRIV | OPT_A2LIST },
+
+    { "allow-ip", o_special, (void *)set_noauth_addr,
+      "Set IP address(es) which can be used without authentication",
+      OPT_PRIV | OPT_A2LIST },
+
+    { "remotenumber", o_string, remote_number,
+      "Set remote telephone number for authentication", OPT_PRIO | OPT_STATIC,
+      NULL, MAXNAMELEN },
+
+    { "allow-number", o_special, (void *)set_permitted_number,
+      "Set telephone number(s) which are allowed to connect",
+      OPT_PRIV | OPT_A2LIST },
+
+    { NULL }
+};
+#endif /* PPP_OPTIONS */
+
+#if 0 /* UNUSED */
+/*
+ * setupapfile - specifies UPAP info for authenticating with peer.
+ */
+static int
+setupapfile(argv)
+    char **argv;
+{
+    FILE *ufile;
+    int l;
+    uid_t euid;
+    char u[MAXNAMELEN], p[MAXSECRETLEN];
+    char *fname;
+
+    lcp_allowoptions[0].neg_upap = 1;
+
+    /* open user info file */
+    fname = strdup(*argv);
+    if (fname == NULL)
+	novm("+ua file name");
+    euid = geteuid();
+    if (seteuid(getuid()) == -1) {
+	option_error("unable to reset uid before opening %s: %m", fname);
+	return 0;
+    }
+    ufile = fopen(fname, "r");
+    if (seteuid(euid) == -1)
+	fatal("unable to regain privileges: %m");
+    if (ufile == NULL) {
+	option_error("unable to open user login data file %s", fname);
+	return 0;
+    }
+    check_access(ufile, fname);
+    uafname = fname;
+
+    /* get username */
+    if (fgets(u, MAXNAMELEN - 1, ufile) == NULL
+	|| fgets(p, MAXSECRETLEN - 1, ufile) == NULL) {
+	fclose(ufile);
+	option_error("unable to read user login data file %s", fname);
+	return 0;
+    }
+    fclose(ufile);
+
+    /* get rid of newlines */
+    l = strlen(u);
+    if (l > 0 && u[l-1] == '\n')
+	u[l-1] = 0;
+    l = strlen(p);
+    if (l > 0 && p[l-1] == '\n')
+	p[l-1] = 0;
+
+    if (override_value("user", option_priority, fname)) {
+	strlcpy(ppp_settings.user, u, sizeof(ppp_settings.user));
+	explicit_user = 1;
+    }
+    if (override_value("passwd", option_priority, fname)) {
+	strlcpy(ppp_settings.passwd, p, sizeof(ppp_settings.passwd));
+	explicit_passwd = 1;
+    }
+
+    return (1);
+}
+
+/*
+ * privgroup - allow members of the group to have privileged access.
+ */
+static int
+privgroup(argv)
+    char **argv;
+{
+    struct group *g;
+    int i;
+
+    g = getgrnam(*argv);
+    if (g == 0) {
+	option_error("group %s is unknown", *argv);
+	return 0;
+    }
+    for (i = 0; i < ngroups; ++i) {
+	if (groups[i] == g->gr_gid) {
+	    privileged = 1;
+	    break;
+	}
+    }
+    return 1;
+}
+
+
+/*
+ * set_noauth_addr - set address(es) that can be used without authentication.
+ * Equivalent to specifying an entry like `"" * "" addr' in pap-secrets.
+ */
+static int
+set_noauth_addr(argv)
+    char **argv;
+{
+    char *addr = *argv;
+    int l = strlen(addr) + 1;
+    struct wordlist *wp;
+
+    wp = (struct wordlist *) malloc(sizeof(struct wordlist) + l);
+    if (wp == NULL)
+	novm("allow-ip argument");
+    wp->word = (char *) (wp + 1);
+    wp->next = noauth_addrs;
+    MEMCPY(wp->word, addr, l);
+    noauth_addrs = wp;
+    return 1;
+}
+
+
+/*
+ * set_permitted_number - set remote telephone number(s) that may connect.
+ */
+static int
+set_permitted_number(argv)
+    char **argv;
+{
+    char *number = *argv;
+    int l = strlen(number) + 1;
+    struct wordlist *wp;
+
+    wp = (struct wordlist *) malloc(sizeof(struct wordlist) + l);
+    if (wp == NULL)
+	novm("allow-number argument");
+    wp->word = (char *) (wp + 1);
+    wp->next = permitted_numbers;
+    MEMCPY(wp->word, number, l);
+    permitted_numbers = wp;
+    return 1;
+}
+#endif
+
+/*
+ * An Open on LCP has requested a change from Dead to Establish phase.
+ */
+void link_required(ppp_pcb *pcb) {
+    LWIP_UNUSED_ARG(pcb);
+}
+
+#if 0
+/*
+ * Bring the link up to the point of being able to do ppp.
+ */
+void start_link(unit)
+    int unit;
+{
+    ppp_pcb *pcb = &ppp_pcb_list[unit];
+    char *msg;
+
+    status = EXIT_NEGOTIATION_FAILED;
+    new_phase(pcb, PPP_PHASE_SERIALCONN);
+
+    hungup = 0;
+    devfd = the_channel->connect();
+    msg = "Connect script failed";
+    if (devfd < 0)
+	goto fail;
+
+    /* set up the serial device as a ppp interface */
+    /*
+     * N.B. we used to do tdb_writelock/tdb_writeunlock around this
+     * (from establish_ppp to set_ifunit).  However, we won't be
+     * doing the set_ifunit in multilink mode, which is the only time
+     * we need the atomicity that the tdb_writelock/tdb_writeunlock
+     * gives us.  Thus we don't need the tdb_writelock/tdb_writeunlock.
+     */
+    fd_ppp = the_channel->establish_ppp(devfd);
+    msg = "ppp establishment failed";
+    if (fd_ppp < 0) {
+	status = EXIT_FATAL_ERROR;
+	goto disconnect;
+    }
+
+    if (!demand && ifunit >= 0)
+	set_ifunit(1);
+
+    /*
+     * Start opening the connection and wait for
+     * incoming events (reply, timeout, etc.).
+     */
+    if (ifunit >= 0)
+	ppp_notice("Connect: %s <--> %s", ifname, ppp_devnam);
+    else
+	ppp_notice("Starting negotiation on %s", ppp_devnam);
+    add_fd(fd_ppp);
+
+    new_phase(pcb, PPP_PHASE_ESTABLISH);
+
+    lcp_lowerup(pcb);
+    return;
+
+ disconnect:
+    new_phase(pcb, PPP_PHASE_DISCONNECT);
+    if (the_channel->disconnect)
+	the_channel->disconnect();
+
+ fail:
+    new_phase(pcb, PPP_PHASE_DEAD);
+    if (the_channel->cleanup)
+	(*the_channel->cleanup)();
+}
+#endif
+
+/*
+ * LCP has terminated the link; go to the Dead phase and take the
+ * physical layer down.
+ */
+void link_terminated(ppp_pcb *pcb) {
+    if (pcb->phase == PPP_PHASE_DEAD
+#ifdef HAVE_MULTILINK
+    || pcb->phase == PPP_PHASE_MASTER
+#endif /* HAVE_MULTILINK */
+    )
+	return;
+    new_phase(pcb, PPP_PHASE_DISCONNECT);
+
+#if 0 /* UNUSED */
+    if (pap_logout_hook) {
+	pap_logout_hook();
+    }
+    session_end(devnam);
+#endif /* UNUSED */
+
+    if (!doing_multilink) {
+	ppp_notice("Connection terminated.");
+#if PPP_STATS_SUPPORT
+	print_link_stats();
+#endif /* PPP_STATS_SUPPORT */
+    } else
+	ppp_notice("Link terminated.");
+
+    lcp_lowerdown(pcb);
+
+    ppp_link_terminated(pcb);
+#if 0
+    /*
+     * Delete pid files before disestablishing ppp.  Otherwise it
+     * can happen that another pppd gets the same unit and then
+     * we delete its pid file.
+     */
+    if (!doing_multilink && !demand)
+	remove_pidfiles();
+
+    /*
+     * If we may want to bring the link up again, transfer
+     * the ppp unit back to the loopback.  Set the
+     * real serial device back to its normal mode of operation.
+     */
+    if (fd_ppp >= 0) {
+	remove_fd(fd_ppp);
+	clean_check();
+	the_channel->disestablish_ppp(devfd);
+	if (doing_multilink)
+	    mp_exit_bundle();
+	fd_ppp = -1;
+    }
+    if (!hungup)
+	lcp_lowerdown(pcb);
+    if (!doing_multilink && !demand)
+	script_unsetenv("IFNAME");
+
+    /*
+     * Run disconnector script, if requested.
+     * XXX we may not be able to do this if the line has hung up!
+     */
+    if (devfd >= 0 && the_channel->disconnect) {
+	the_channel->disconnect();
+	devfd = -1;
+    }
+    if (the_channel->cleanup)
+	(*the_channel->cleanup)();
+
+    if (doing_multilink && multilink_master) {
+	if (!bundle_terminating)
+	    new_phase(pcb, PPP_PHASE_MASTER);
+	else
+	    mp_bundle_terminated();
+    } else
+	new_phase(pcb, PPP_PHASE_DEAD);
+#endif
+}
+
+/*
+ * LCP has gone down; it will either die or try to re-establish.
+ */
+void link_down(ppp_pcb *pcb) {
+#if PPP_NOTIFY
+    notify(link_down_notifier, 0);
+#endif /* PPP_NOTIFY */
+
+    if (!doing_multilink) {
+	upper_layers_down(pcb);
+	if (pcb->phase != PPP_PHASE_DEAD
+#ifdef HAVE_MULTILINK
+	&& pcb->phase != PPP_PHASE_MASTER
+#endif /* HAVE_MULTILINK */
+	)
+	    new_phase(pcb, PPP_PHASE_ESTABLISH);
+    }
+    /* XXX if doing_multilink, should do something to stop
+       network-layer traffic on the link */
+}
+
+void upper_layers_down(ppp_pcb *pcb) {
+    int i;
+    const struct protent *protp;
+
+    for (i = 0; (protp = protocols[i]) != NULL; ++i) {
+        if (protp->protocol != PPP_LCP && protp->lowerdown != NULL)
+	    (*protp->lowerdown)(pcb);
+        if (protp->protocol < 0xC000 && protp->close != NULL)
+	    (*protp->close)(pcb, "LCP down");
+    }
+    pcb->num_np_open = 0;
+    pcb->num_np_up = 0;
+}
+
+/*
+ * The link is established.
+ * Proceed to the Dead, Authenticate or Network phase as appropriate.
+ */
+void link_established(ppp_pcb *pcb) {
+#if PPP_AUTH_SUPPORT
+    int auth;
+#if PPP_SERVER
+#if PAP_SUPPORT
+    lcp_options *wo = &pcb->lcp_wantoptions;
+#endif /* PAP_SUPPORT */
+    lcp_options *go = &pcb->lcp_gotoptions;
+#endif /* PPP_SERVER */
+    lcp_options *ho = &pcb->lcp_hisoptions;
+#endif /* PPP_AUTH_SUPPORT */
+    int i;
+    const struct protent *protp;
+
+    /*
+     * Tell higher-level protocols that LCP is up.
+     */
+    if (!doing_multilink) {
+	for (i = 0; (protp = protocols[i]) != NULL; ++i)
+	    if (protp->protocol != PPP_LCP
+		&& protp->lowerup != NULL)
+		(*protp->lowerup)(pcb);
+    }
+
+#if PPP_AUTH_SUPPORT
+#if PPP_SERVER
+#if PPP_ALLOWED_ADDRS
+    if (!auth_required && noauth_addrs != NULL)
+	set_allowed_addrs(unit, NULL, NULL);
+#endif /* PPP_ALLOWED_ADDRS */
+
+    if (pcb->settings.auth_required && !(0
+#if PAP_SUPPORT
+	|| go->neg_upap
+#endif /* PAP_SUPPORT */
+#if CHAP_SUPPORT
+	|| go->neg_chap
+#endif /* CHAP_SUPPORT */
+#if EAP_SUPPORT
+	|| go->neg_eap
+#endif /* EAP_SUPPORT */
+	)) {
+
+#if PPP_ALLOWED_ADDRS
+	/*
+	 * We wanted the peer to authenticate itself, and it refused:
+	 * if we have some address(es) it can use without auth, fine,
+	 * otherwise treat it as though it authenticated with PAP using
+	 * a username of "" and a password of "".  If that's not OK,
+	 * boot it out.
+	 */
+	if (noauth_addrs != NULL) {
+	    set_allowed_addrs(unit, NULL, NULL);
+	} else
+#endif /* PPP_ALLOWED_ADDRS */
+	if (!pcb->settings.null_login
+#if PAP_SUPPORT
+	    || !wo->neg_upap
+#endif /* PAP_SUPPORT */
+	    ) {
+	    ppp_warn("peer refused to authenticate: terminating link");
+#if 0 /* UNUSED */
+	    status = EXIT_PEER_AUTH_FAILED;
+#endif /* UNUSED */
+	    pcb->err_code = PPPERR_AUTHFAIL;
+	    lcp_close(pcb, "peer refused to authenticate");
+	    return;
+	}
+    }
+#endif /* PPP_SERVER */
+
+    new_phase(pcb, PPP_PHASE_AUTHENTICATE);
+    auth = 0;
+#if PPP_SERVER
+#if EAP_SUPPORT
+    if (go->neg_eap) {
+	eap_authpeer(pcb, PPP_OUR_NAME);
+	auth |= EAP_PEER;
+    } else
+#endif /* EAP_SUPPORT */
+#if CHAP_SUPPORT
+    if (go->neg_chap) {
+	chap_auth_peer(pcb, PPP_OUR_NAME, CHAP_DIGEST(go->chap_mdtype));
+	auth |= CHAP_PEER;
+    } else
+#endif /* CHAP_SUPPORT */
+#if PAP_SUPPORT
+    if (go->neg_upap) {
+	upap_authpeer(pcb);
+	auth |= PAP_PEER;
+    } else
+#endif /* PAP_SUPPORT */
+    {}
+#endif /* PPP_SERVER */
+
+#if EAP_SUPPORT
+    if (ho->neg_eap) {
+	eap_authwithpeer(pcb, pcb->settings.user);
+	auth |= EAP_WITHPEER;
+    } else
+#endif /* EAP_SUPPORT */
+#if CHAP_SUPPORT
+    if (ho->neg_chap) {
+	chap_auth_with_peer(pcb, pcb->settings.user, CHAP_DIGEST(ho->chap_mdtype));
+	auth |= CHAP_WITHPEER;
+    } else
+#endif /* CHAP_SUPPORT */
+#if PAP_SUPPORT
+    if (ho->neg_upap) {
+	upap_authwithpeer(pcb, pcb->settings.user, pcb->settings.passwd);
+	auth |= PAP_WITHPEER;
+    } else
+#endif /* PAP_SUPPORT */
+    {}
+
+    pcb->auth_pending = auth;
+    pcb->auth_done = 0;
+
+    if (!auth)
+#endif /* PPP_AUTH_SUPPORT */
+	network_phase(pcb);
+}
+
+/*
+ * Proceed to the network phase.
+ */
+static void network_phase(ppp_pcb *pcb) {
+#if CBCP_SUPPORT
+    ppp_pcb *pcb = &ppp_pcb_list[unit];
+#endif
+#if 0 /* UNUSED */
+    lcp_options *go = &lcp_gotoptions[unit];
+#endif /* UNUSED */
+
+#if 0 /* UNUSED */
+    /* Log calling number. */
+    if (*remote_number)
+	ppp_notice("peer from calling number %q authorized", remote_number);
+#endif /* UNUSED */
+
+#if PPP_NOTIFY
+    /*
+     * If the peer had to authenticate, notify it now.
+     */
+    if (0
+#if CHAP_SUPPORT
+	|| go->neg_chap
+#endif /* CHAP_SUPPORT */
+#if PAP_SUPPORT
+	|| go->neg_upap
+#endif /* PAP_SUPPORT */
+#if EAP_SUPPORT
+	|| go->neg_eap
+#endif /* EAP_SUPPORT */
+	) {
+	notify(auth_up_notifier, 0);
+    }
+#endif /* PPP_NOTIFY */
+
+#if CBCP_SUPPORT
+    /*
+     * If we negotiated callback, do it now.
+     */
+    if (go->neg_cbcp) {
+	new_phase(pcb, PPP_PHASE_CALLBACK);
+	(*cbcp_protent.open)(pcb);
+	return;
+    }
+#endif
+
+#if PPP_OPTIONS
+    /*
+     * Process extra options from the secrets file
+     */
+    if (extra_options) {
+	options_from_list(extra_options, 1);
+	free_wordlist(extra_options);
+	extra_options = 0;
+    }
+#endif /* PPP_OPTIONS */
+    start_networks(pcb);
+}
+
+void start_networks(ppp_pcb *pcb) {
+#if CCP_SUPPORT || ECP_SUPPORT
+    int i;
+    const struct protent *protp;
+#endif /* CCP_SUPPORT || ECP_SUPPORT */
+
+    new_phase(pcb, PPP_PHASE_NETWORK);
+
+#ifdef HAVE_MULTILINK
+    if (multilink) {
+	if (mp_join_bundle()) {
+	    if (multilink_join_hook)
+		(*multilink_join_hook)();
+	    if (updetach && !nodetach)
+		detach();
+	    return;
+	}
+    }
+#endif /* HAVE_MULTILINK */
+
+#ifdef PPP_FILTER
+    if (!demand)
+	set_filters(&pass_filter, &active_filter);
+#endif
+#if CCP_SUPPORT || ECP_SUPPORT
+    /* Start CCP and ECP */
+    for (i = 0; (protp = protocols[i]) != NULL; ++i)
+	if (
+	    (0
+#if ECP_SUPPORT
+	    || protp->protocol == PPP_ECP
+#endif /* ECP_SUPPORT */
+#if CCP_SUPPORT
+	    || protp->protocol == PPP_CCP
+#endif /* CCP_SUPPORT */
+	    )
+	    && protp->open != NULL)
+	    (*protp->open)(pcb);
+#endif /* CCP_SUPPORT || ECP_SUPPORT */
+
+    /*
+     * Bring up other network protocols iff encryption is not required.
+     */
+    if (1
+#if ECP_SUPPORT
+        && !ecp_gotoptions[unit].required
+#endif /* ECP_SUPPORT */
+#if MPPE_SUPPORT
+        && !pcb->ccp_gotoptions.mppe
+#endif /* MPPE_SUPPORT */
+        )
+	continue_networks(pcb);
+}
+
+void continue_networks(ppp_pcb *pcb) {
+    int i;
+    const struct protent *protp;
+
+    /*
+     * Start the "real" network protocols.
+     */
+    for (i = 0; (protp = protocols[i]) != NULL; ++i)
+	if (protp->protocol < 0xC000
+#if CCP_SUPPORT
+	    && protp->protocol != PPP_CCP
+#endif /* CCP_SUPPORT */
+#if ECP_SUPPORT
+	    && protp->protocol != PPP_ECP
+#endif /* ECP_SUPPORT */
+	    && protp->open != NULL) {
+	    (*protp->open)(pcb);
+	    ++pcb->num_np_open;
+	}
+
+    if (pcb->num_np_open == 0)
+	/* nothing to do */
+	lcp_close(pcb, "No network protocols running");
+}
+
+#if PPP_AUTH_SUPPORT
+#if PPP_SERVER
+/*
+ * auth_check_passwd - Check the user name and passwd against configuration.
+ *
+ * returns:
+ *      0: Authentication failed.
+ *      1: Authentication succeeded.
+ * In either case, msg points to an appropriate message and msglen to the message len.
+ */
+int auth_check_passwd(ppp_pcb *pcb, char *auser, int userlen, char *apasswd, int passwdlen, const char **msg, int *msglen) {
+  int secretuserlen;
+  int secretpasswdlen;
+
+  if (pcb->settings.user && pcb->settings.passwd) {
+    secretuserlen = (int)strlen(pcb->settings.user);
+    secretpasswdlen = (int)strlen(pcb->settings.passwd);
+    if (secretuserlen == userlen
+        && secretpasswdlen == passwdlen
+        && !memcmp(auser, pcb->settings.user, userlen)
+        && !memcmp(apasswd, pcb->settings.passwd, passwdlen) ) {
+      *msg = "Login ok";
+      *msglen = sizeof("Login ok")-1;
+      return 1;
+    }
+  }
+
+  *msg = "Login incorrect";
+  *msglen = sizeof("Login incorrect")-1;
+  return 0;
+}
+
+/*
+ * The peer has failed to authenticate himself using `protocol'.
+ */
+void auth_peer_fail(ppp_pcb *pcb, int protocol) {
+    LWIP_UNUSED_ARG(protocol);
+    /*
+     * Authentication failure: take the link down
+     */
+#if 0 /* UNUSED */
+    status = EXIT_PEER_AUTH_FAILED;
+#endif /* UNUSED */
+    pcb->err_code = PPPERR_AUTHFAIL;
+    lcp_close(pcb, "Authentication failed");
+}
+
+/*
+ * The peer has been successfully authenticated using `protocol'.
+ */
+void auth_peer_success(ppp_pcb *pcb, int protocol, int prot_flavor, const char *name, int namelen) {
+    int bit;
+#ifndef HAVE_MULTILINK
+    LWIP_UNUSED_ARG(name);
+    LWIP_UNUSED_ARG(namelen);
+#endif /* HAVE_MULTILINK */
+
+    switch (protocol) {
+#if CHAP_SUPPORT
+    case PPP_CHAP:
+	bit = CHAP_PEER;
+	switch (prot_flavor) {
+	case CHAP_MD5:
+	    bit |= CHAP_MD5_PEER;
+	    break;
+#if MSCHAP_SUPPORT
+	case CHAP_MICROSOFT:
+	    bit |= CHAP_MS_PEER;
+	    break;
+	case CHAP_MICROSOFT_V2:
+	    bit |= CHAP_MS2_PEER;
+	    break;
+#endif /* MSCHAP_SUPPORT */
+	default:
+	    break;
+	}
+	break;
+#endif /* CHAP_SUPPORT */
+#if PAP_SUPPORT
+    case PPP_PAP:
+	bit = PAP_PEER;
+	break;
+#endif /* PAP_SUPPORT */
+#if EAP_SUPPORT
+    case PPP_EAP:
+	bit = EAP_PEER;
+	break;
+#endif /* EAP_SUPPORT */
+    default:
+	ppp_warn("auth_peer_success: unknown protocol %x", protocol);
+	return;
+    }
+
+#ifdef HAVE_MULTILINK
+    /*
+     * Save the authenticated name of the peer for later.
+     */
+    if (namelen > (int)sizeof(pcb->peer_authname) - 1)
+	namelen = (int)sizeof(pcb->peer_authname) - 1;
+    MEMCPY(pcb->peer_authname, name, namelen);
+    pcb->peer_authname[namelen] = 0;
+#endif /* HAVE_MULTILINK */
+#if 0 /* UNUSED */
+    script_setenv("PEERNAME", , 0);
+#endif /* UNUSED */
+
+    /* Save the authentication method for later. */
+    pcb->auth_done |= bit;
+
+    /*
+     * If there is no more authentication still to be done,
+     * proceed to the network (or callback) phase.
+     */
+    if ((pcb->auth_pending &= ~bit) == 0)
+        network_phase(pcb);
+}
+#endif /* PPP_SERVER */
+
+/*
+ * We have failed to authenticate ourselves to the peer using `protocol'.
+ */
+void auth_withpeer_fail(ppp_pcb *pcb, int protocol) {
+    LWIP_UNUSED_ARG(protocol);
+    /*
+     * We've failed to authenticate ourselves to our peer.
+     *
+     * Some servers keep sending CHAP challenges, but there
+     * is no point in persisting without any way to get updated
+     * authentication secrets.
+     *
+     * He'll probably take the link down, and there's not much
+     * we can do except wait for that.
+     */
+    pcb->err_code = PPPERR_AUTHFAIL;
+    lcp_close(pcb, "Failed to authenticate ourselves to peer");
+}
+
+/*
+ * We have successfully authenticated ourselves with the peer using `protocol'.
+ */
+void auth_withpeer_success(ppp_pcb *pcb, int protocol, int prot_flavor) {
+    int bit;
+    const char *prot = "";
+
+    switch (protocol) {
+#if CHAP_SUPPORT
+    case PPP_CHAP:
+	bit = CHAP_WITHPEER;
+	prot = "CHAP";
+	switch (prot_flavor) {
+	case CHAP_MD5:
+	    bit |= CHAP_MD5_WITHPEER;
+	    break;
+#if MSCHAP_SUPPORT
+	case CHAP_MICROSOFT:
+	    bit |= CHAP_MS_WITHPEER;
+	    break;
+	case CHAP_MICROSOFT_V2:
+	    bit |= CHAP_MS2_WITHPEER;
+	    break;
+#endif /* MSCHAP_SUPPORT */
+	default:
+	    break;
+	}
+	break;
+#endif /* CHAP_SUPPORT */
+#if PAP_SUPPORT
+    case PPP_PAP:
+	bit = PAP_WITHPEER;
+	prot = "PAP";
+	break;
+#endif /* PAP_SUPPORT */
+#if EAP_SUPPORT
+    case PPP_EAP:
+	bit = EAP_WITHPEER;
+	prot = "EAP";
+	break;
+#endif /* EAP_SUPPORT */
+    default:
+	ppp_warn("auth_withpeer_success: unknown protocol %x", protocol);
+	bit = 0;
+	/* no break */
+    }
+
+    ppp_notice("%s authentication succeeded", prot);
+
+    /* Save the authentication method for later. */
+    pcb->auth_done |= bit;
+
+    /*
+     * If there is no more authentication still being done,
+     * proceed to the network (or callback) phase.
+     */
+    if ((pcb->auth_pending &= ~bit) == 0)
+	network_phase(pcb);
+}
+#endif /* PPP_AUTH_SUPPORT */
+
+
+/*
+ * np_up - a network protocol has come up.
+ */
+void np_up(ppp_pcb *pcb, int proto) {
+#if PPP_IDLETIMELIMIT
+    int tlim;
+#endif /* PPP_IDLETIMELIMIT */
+    LWIP_UNUSED_ARG(proto);
+
+    if (pcb->num_np_up == 0) {
+	/*
+	 * At this point we consider that the link has come up successfully.
+	 */
+	new_phase(pcb, PPP_PHASE_RUNNING);
+
+#if PPP_IDLETIMELIMIT
+#if 0 /* UNUSED */
+	if (idle_time_hook != 0)
+	    tlim = (*idle_time_hook)(NULL);
+	else
+#endif /* UNUSED */
+	    tlim = pcb->settings.idle_time_limit;
+	if (tlim > 0)
+	    TIMEOUT(check_idle, (void*)pcb, tlim);
+#endif /* PPP_IDLETIMELIMIT */
+
+#if PPP_MAXCONNECT
+	/*
+	 * Set a timeout to close the connection once the maximum
+	 * connect time has expired.
+	 */
+	if (pcb->settings.maxconnect > 0)
+	    TIMEOUT(connect_time_expired, (void*)pcb, pcb->settings.maxconnect);
+#endif /* PPP_MAXCONNECT */
+
+#ifdef MAXOCTETS
+	if (maxoctets > 0)
+	    TIMEOUT(check_maxoctets, NULL, maxoctets_timeout);
+#endif
+
+#if 0 /* Unused */
+	/*
+	 * Detach now, if the updetach option was given.
+	 */
+	if (updetach && !nodetach)
+	    detach();
+#endif /* Unused */
+    }
+    ++pcb->num_np_up;
+}
+
+/*
+ * np_down - a network protocol has gone down.
+ */
+void np_down(ppp_pcb *pcb, int proto) {
+    LWIP_UNUSED_ARG(proto);
+    if (--pcb->num_np_up == 0) {
+#if PPP_IDLETIMELIMIT
+	UNTIMEOUT(check_idle, (void*)pcb);
+#endif /* PPP_IDLETIMELIMIT */
+#if PPP_MAXCONNECT
+	UNTIMEOUT(connect_time_expired, NULL);
+#endif /* PPP_MAXCONNECT */
+#ifdef MAXOCTETS
+	UNTIMEOUT(check_maxoctets, NULL);
+#endif
+	new_phase(pcb, PPP_PHASE_NETWORK);
+    }
+}
+
+/*
+ * np_finished - a network protocol has finished using the link.
+ */
+void np_finished(ppp_pcb *pcb, int proto) {
+    LWIP_UNUSED_ARG(proto);
+    if (--pcb->num_np_open <= 0) {
+	/* no further use for the link: shut up shop. */
+	lcp_close(pcb, "No network protocols running");
+    }
+}
+
+#ifdef MAXOCTETS
+static void
+check_maxoctets(arg)
+    void *arg;
+{
+#if PPP_STATS_SUPPORT
+    unsigned int used;
+
+    update_link_stats(ifunit);
+    link_stats_valid=0;
+
+    switch(maxoctets_dir) {
+	case PPP_OCTETS_DIRECTION_IN:
+	    used = link_stats.bytes_in;
+	    break;
+	case PPP_OCTETS_DIRECTION_OUT:
+	    used = link_stats.bytes_out;
+	    break;
+	case PPP_OCTETS_DIRECTION_MAXOVERAL:
+	case PPP_OCTETS_DIRECTION_MAXSESSION:
+	    used = (link_stats.bytes_in > link_stats.bytes_out) ? link_stats.bytes_in : link_stats.bytes_out;
+	    break;
+	default:
+	    used = link_stats.bytes_in+link_stats.bytes_out;
+	    break;
+    }
+    if (used > maxoctets) {
+	ppp_notice("Traffic limit reached. Limit: %u Used: %u", maxoctets, used);
+	status = EXIT_TRAFFIC_LIMIT;
+	lcp_close(pcb, "Traffic limit");
+#if 0 /* UNUSED */
+	need_holdoff = 0;
+#endif /* UNUSED */
+    } else {
+        TIMEOUT(check_maxoctets, NULL, maxoctets_timeout);
+    }
+#endif /* PPP_STATS_SUPPORT */
+}
+#endif /* MAXOCTETS */
+
+#if PPP_IDLETIMELIMIT
+/*
+ * check_idle - check whether the link has been idle for long
+ * enough that we can shut it down.
+ */
+static void check_idle(void *arg) {
+    ppp_pcb *pcb = (ppp_pcb*)arg;
+    struct ppp_idle idle;
+    time_t itime;
+    int tlim;
+
+    if (!get_idle_time(pcb, &idle))
+	return;
+#if 0 /* UNUSED */
+    if (idle_time_hook != 0) {
+	tlim = idle_time_hook(&idle);
+    } else {
+#endif /* UNUSED */
+	itime = LWIP_MIN(idle.xmit_idle, idle.recv_idle);
+	tlim = pcb->settings.idle_time_limit - itime;
+#if 0 /* UNUSED */
+    }
+#endif /* UNUSED */
+    if (tlim <= 0) {
+	/* link is idle: shut it down. */
+	ppp_notice("Terminating connection due to lack of activity.");
+	pcb->err_code = PPPERR_IDLETIMEOUT;
+	lcp_close(pcb, "Link inactive");
+#if 0 /* UNUSED */
+	need_holdoff = 0;
+#endif /* UNUSED */
+    } else {
+	TIMEOUT(check_idle, (void*)pcb, tlim);
+    }
+}
+#endif /* PPP_IDLETIMELIMIT */
+
+#if PPP_MAXCONNECT
+/*
+ * connect_time_expired - log a message and close the connection.
+ */
+static void connect_time_expired(void *arg) {
+    ppp_pcb *pcb = (ppp_pcb*)arg;
+    ppp_info("Connect time expired");
+    pcb->err_code = PPPERR_CONNECTTIME;
+    lcp_close(pcb, "Connect time expired");	/* Close connection */
+}
+#endif /* PPP_MAXCONNECT */
+
+#if PPP_OPTIONS
+/*
+ * auth_check_options - called to check authentication options.
+ */
+void
+auth_check_options()
+{
+    lcp_options *wo = &lcp_wantoptions[0];
+    int can_auth;
+    int lacks_ip;
+
+    /* Default our_name to hostname, and user to our_name */
+    if (our_name[0] == 0 || usehostname)
+	strlcpy(our_name, hostname, sizeof(our_name));
+    /* If a blank username was explicitly given as an option, trust
+       the user and don't use our_name */
+    if (ppp_settings.user[0] == 0 && !explicit_user)
+	strlcpy(ppp_settings.user, our_name, sizeof(ppp_settings.user));
+
+    /*
+     * If we have a default route, require the peer to authenticate
+     * unless the noauth option was given or the real user is root.
+     */
+    if (!auth_required && !allow_any_ip && have_route_to(0) && !privileged) {
+	auth_required = 1;
+	default_auth = 1;
+    }
+
+#if CHAP_SUPPORT
+    /* If we selected any CHAP flavors, we should probably negotiate it. :-) */
+    if (wo->chap_mdtype)
+	wo->neg_chap = 1;
+#endif /* CHAP_SUPPORT */
+
+    /* If authentication is required, ask peer for CHAP, PAP, or EAP. */
+    if (auth_required) {
+	allow_any_ip = 0;
+	if (1
+#if CHAP_SUPPORT
+	    && !wo->neg_chap
+#endif /* CHAP_SUPPORT */
+#if PAP_SUPPORT
+	    && !wo->neg_upap
+#endif /* PAP_SUPPORT */
+#if EAP_SUPPORT
+	    && !wo->neg_eap
+#endif /* EAP_SUPPORT */
+	    ) {
+#if CHAP_SUPPORT
+	    wo->neg_chap = CHAP_MDTYPE_SUPPORTED != MDTYPE_NONE;
+	    wo->chap_mdtype = CHAP_MDTYPE_SUPPORTED;
+#endif /* CHAP_SUPPORT */
+#if PAP_SUPPORT
+	    wo->neg_upap = 1;
+#endif /* PAP_SUPPORT */
+#if EAP_SUPPORT
+	    wo->neg_eap = 1;
+#endif /* EAP_SUPPORT */
+	}
+    } else {
+#if CHAP_SUPPORT
+	wo->neg_chap = 0;
+	wo->chap_mdtype = MDTYPE_NONE;
+#endif /* CHAP_SUPPORT */
+#if PAP_SUPPORT
+	wo->neg_upap = 0;
+#endif /* PAP_SUPPORT */
+#if EAP_SUPPORT
+	wo->neg_eap = 0;
+#endif /* EAP_SUPPORT */
+    }
+
+    /*
+     * Check whether we have appropriate secrets to use
+     * to authenticate the peer.  Note that EAP can authenticate by way
+     * of a CHAP-like exchanges as well as SRP.
+     */
+    lacks_ip = 0;
+#if PAP_SUPPORT
+    can_auth = wo->neg_upap && (uselogin || have_pap_secret(&lacks_ip));
+#else
+    can_auth = 0;
+#endif /* PAP_SUPPORT */
+    if (!can_auth && (0
+#if CHAP_SUPPORT
+	|| wo->neg_chap
+#endif /* CHAP_SUPPORT */
+#if EAP_SUPPORT
+	|| wo->neg_eap
+#endif /* EAP_SUPPORT */
+	)) {
+#if CHAP_SUPPORT
+	can_auth = have_chap_secret((explicit_remote? remote_name: NULL),
+				    our_name, 1, &lacks_ip);
+#else
+	can_auth = 0;
+#endif
+    }
+    if (!can_auth
+#if EAP_SUPPORT
+	&& wo->neg_eap
+#endif /* EAP_SUPPORT */
+	) {
+	can_auth = have_srp_secret((explicit_remote? remote_name: NULL),
+				    our_name, 1, &lacks_ip);
+    }
+
+    if (auth_required && !can_auth && noauth_addrs == NULL) {
+	if (default_auth) {
+	    option_error(
+"By default the remote system is required to authenticate itself");
+	    option_error(
+"(because this system has a default route to the internet)");
+	} else if (explicit_remote)
+	    option_error(
+"The remote system (%s) is required to authenticate itself",
+			 remote_name);
+	else
+	    option_error(
+"The remote system is required to authenticate itself");
+	option_error(
+"but I couldn't find any suitable secret (password) for it to use to do so.");
+	if (lacks_ip)
+	    option_error(
+"(None of the available passwords would let it use an IP address.)");
+
+	exit(1);
+    }
+
+    /*
+     * Early check for remote number authorization.
+     */
+    if (!auth_number()) {
+	ppp_warn("calling number %q is not authorized", remote_number);
+	exit(EXIT_CNID_AUTH_FAILED);
+    }
+}
+#endif /* PPP_OPTIONS */
+
+#if 0 /* UNUSED */
+/*
+ * auth_reset - called when LCP is starting negotiations to recheck
+ * authentication options, i.e. whether we have appropriate secrets
+ * to use for authenticating ourselves and/or the peer.
+ */
+void
+auth_reset(unit)
+    int unit;
+{
+    lcp_options *go = &lcp_gotoptions[unit];
+    lcp_options *ao = &lcp_allowoptions[unit];
+    int hadchap;
+
+    hadchap = -1;
+    ao->neg_upap = !refuse_pap && (passwd[0] != 0 || get_pap_passwd(NULL));
+    ao->neg_chap = (!refuse_chap || !refuse_mschap || !refuse_mschap_v2)
+	&& (passwd[0] != 0 ||
+	    (hadchap = have_chap_secret(user, (explicit_remote? remote_name:
+					       NULL), 0, NULL)));
+    ao->neg_eap = !refuse_eap && (
+	passwd[0] != 0 ||
+	(hadchap == 1 || (hadchap == -1 && have_chap_secret(user,
+	    (explicit_remote? remote_name: NULL), 0, NULL))) ||
+	have_srp_secret(user, (explicit_remote? remote_name: NULL), 0, NULL));
+
+    hadchap = -1;
+    if (go->neg_upap && !uselogin && !have_pap_secret(NULL))
+	go->neg_upap = 0;
+    if (go->neg_chap) {
+	if (!(hadchap = have_chap_secret((explicit_remote? remote_name: NULL),
+			      our_name, 1, NULL)))
+	    go->neg_chap = 0;
+    }
+    if (go->neg_eap &&
+	(hadchap == 0 || (hadchap == -1 &&
+	    !have_chap_secret((explicit_remote? remote_name: NULL), our_name,
+		1, NULL))) &&
+	!have_srp_secret((explicit_remote? remote_name: NULL), our_name, 1,
+	    NULL))
+	go->neg_eap = 0;
+}
+
+/*
+ * check_passwd - Check the user name and passwd against the PAP secrets
+ * file.  If requested, also check against the system password database,
+ * and login the user if OK.
+ *
+ * returns:
+ *	UPAP_AUTHNAK: Authentication failed.
+ *	UPAP_AUTHACK: Authentication succeeded.
+ * In either case, msg points to an appropriate message.
+ */
+int
+check_passwd(unit, auser, userlen, apasswd, passwdlen, msg)
+    int unit;
+    char *auser;
+    int userlen;
+    char *apasswd;
+    int passwdlen;
+    char **msg;
+{
+  return UPAP_AUTHNAK;
+    int ret;
+    char *filename;
+    FILE *f;
+    struct wordlist *addrs = NULL, *opts = NULL;
+    char passwd[256], user[256];
+    char secret[MAXWORDLEN];
+    static int attempts = 0;
+
+    /*
+     * Make copies of apasswd and auser, then null-terminate them.
+     * If there are unprintable characters in the password, make
+     * them visible.
+     */
+    slprintf(ppp_settings.passwd, sizeof(ppp_settings.passwd), "%.*v", passwdlen, apasswd);
+    slprintf(ppp_settings.user, sizeof(ppp_settings.user), "%.*v", userlen, auser);
+    *msg = "";
+
+    /*
+     * Check if a plugin wants to handle this.
+     */
+    if (pap_auth_hook) {
+	ret = (*pap_auth_hook)(ppp_settings.user, ppp_settings.passwd, msg, &addrs, &opts);
+	if (ret >= 0) {
+	    /* note: set_allowed_addrs() saves opts (but not addrs):
+	       don't free it! */
+	    if (ret)
+		set_allowed_addrs(unit, addrs, opts);
+	    else if (opts != 0)
+		free_wordlist(opts);
+	    if (addrs != 0)
+		free_wordlist(addrs);
+	    BZERO(ppp_settings.passwd, sizeof(ppp_settings.passwd));
+	    return ret? UPAP_AUTHACK: UPAP_AUTHNAK;
+	}
+    }
+
+    /*
+     * Open the file of pap secrets and scan for a suitable secret
+     * for authenticating this user.
+     */
+    filename = _PATH_UPAPFILE;
+    addrs = opts = NULL;
+    ret = UPAP_AUTHNAK;
+    f = fopen(filename, "r");
+    if (f == NULL) {
+	ppp_error("Can't open PAP password file %s: %m", filename);
+
+    } else {
+	check_access(f, filename);
+	if (scan_authfile(f, ppp_settings.user, our_name, secret, &addrs, &opts, filename, 0) < 0) {
+	    ppp_warn("no PAP secret found for %s", user);
+	} else {
+	    /*
+	     * If the secret is "@login", it means to check
+	     * the password against the login database.
+	     */
+	    int login_secret = strcmp(secret, "@login") == 0;
+	    ret = UPAP_AUTHACK;
+	    if (uselogin || login_secret) {
+		/* login option or secret is @login */
+		if (session_full(ppp_settings.user, ppp_settings.passwd, devnam, msg) == 0) {
+		    ret = UPAP_AUTHNAK;
+		}
+	    } else if (session_mgmt) {
+		if (session_check(ppp_settings.user, NULL, devnam, NULL) == 0) {
+		    ppp_warn("Peer %q failed PAP Session verification", user);
+		    ret = UPAP_AUTHNAK;
+		}
+	    }
+	    if (secret[0] != 0 && !login_secret) {
+		/* password given in pap-secrets - must match */
+		if ((cryptpap || strcmp(ppp_settings.passwd, secret) != 0)
+		    && strcmp(crypt(ppp_settings.passwd, secret), secret) != 0)
+		    ret = UPAP_AUTHNAK;
+	    }
+	}
+	fclose(f);
+    }
+
+    if (ret == UPAP_AUTHNAK) {
+        if (**msg == 0)
+	    *msg = "Login incorrect";
+	/*
+	 * XXX can we ever get here more than once??
+	 * Frustrate passwd stealer programs.
+	 * Allow 10 tries, but start backing off after 3 (stolen from login).
+	 * On 10'th, drop the connection.
+	 */
+	if (attempts++ >= 10) {
+	    ppp_warn("%d LOGIN FAILURES ON %s, %s", attempts, devnam, user);
+	    lcp_close(pcb, "login failed");
+	}
+	if (attempts > 3)
+	    sleep((u_int) (attempts - 3) * 5);
+	if (opts != NULL)
+	    free_wordlist(opts);
+
+    } else {
+	attempts = 0;			/* Reset count */
+	if (**msg == 0)
+	    *msg = "Login ok";
+	set_allowed_addrs(unit, addrs, opts);
+    }
+
+    if (addrs != NULL)
+	free_wordlist(addrs);
+    BZERO(ppp_settings.passwd, sizeof(ppp_settings.passwd));
+    BZERO(secret, sizeof(secret));
+
+    return ret;
+}
+
+/*
+ * null_login - Check if a username of "" and a password of "" are
+ * acceptable, and iff so, set the list of acceptable IP addresses
+ * and return 1.
+ */
+static int
+null_login(unit)
+    int unit;
+{
+    char *filename;
+    FILE *f;
+    int i, ret;
+    struct wordlist *addrs, *opts;
+    char secret[MAXWORDLEN];
+
+    /*
+     * Check if a plugin wants to handle this.
+     */
+    ret = -1;
+    if (null_auth_hook)
+	ret = (*null_auth_hook)(&addrs, &opts);
+
+    /*
+     * Open the file of pap secrets and scan for a suitable secret.
+     */
+    if (ret <= 0) {
+	filename = _PATH_UPAPFILE;
+	addrs = NULL;
+	f = fopen(filename, "r");
+	if (f == NULL)
+	    return 0;
+	check_access(f, filename);
+
+	i = scan_authfile(f, "", our_name, secret, &addrs, &opts, filename, 0);
+	ret = i >= 0 && secret[0] == 0;
+	BZERO(secret, sizeof(secret));
+	fclose(f);
+    }
+
+    if (ret)
+	set_allowed_addrs(unit, addrs, opts);
+    else if (opts != 0)
+	free_wordlist(opts);
+    if (addrs != 0)
+	free_wordlist(addrs);
+
+    return ret;
+}
+
+/*
+ * get_pap_passwd - get a password for authenticating ourselves with
+ * our peer using PAP.  Returns 1 on success, 0 if no suitable password
+ * could be found.
+ * Assumes passwd points to MAXSECRETLEN bytes of space (if non-null).
+ */
+static int
+get_pap_passwd(passwd)
+    char *passwd;
+{
+    char *filename;
+    FILE *f;
+    int ret;
+    char secret[MAXWORDLEN];
+
+    /*
+     * Check whether a plugin wants to supply this.
+     */
+    if (pap_passwd_hook) {
+	ret = (*pap_passwd_hook)(ppp_settings,user, ppp_settings.passwd);
+	if (ret >= 0)
+	    return ret;
+    }
+
+    filename = _PATH_UPAPFILE;
+    f = fopen(filename, "r");
+    if (f == NULL)
+	return 0;
+    check_access(f, filename);
+    ret = scan_authfile(f, user,
+			(remote_name[0]? remote_name: NULL),
+			secret, NULL, NULL, filename, 0);
+    fclose(f);
+    if (ret < 0)
+	return 0;
+    if (passwd != NULL)
+	strlcpy(passwd, secret, MAXSECRETLEN);
+    BZERO(secret, sizeof(secret));
+    return 1;
+}
+
+/*
+ * have_pap_secret - check whether we have a PAP file with any
+ * secrets that we could possibly use for authenticating the peer.
+ */
+static int
+have_pap_secret(lacks_ipp)
+    int *lacks_ipp;
+{
+    FILE *f;
+    int ret;
+    char *filename;
+    struct wordlist *addrs;
+
+    /* let the plugin decide, if there is one */
+    if (pap_check_hook) {
+	ret = (*pap_check_hook)();
+	if (ret >= 0)
+	    return ret;
+    }
+
+    filename = _PATH_UPAPFILE;
+    f = fopen(filename, "r");
+    if (f == NULL)
+	return 0;
+
+    ret = scan_authfile(f, (explicit_remote? remote_name: NULL), our_name,
+			NULL, &addrs, NULL, filename, 0);
+    fclose(f);
+    if (ret >= 0 && !some_ip_ok(addrs)) {
+	if (lacks_ipp != 0)
+	    *lacks_ipp = 1;
+	ret = -1;
+    }
+    if (addrs != 0)
+	free_wordlist(addrs);
+
+    return ret >= 0;
+}
+
+/*
+ * have_chap_secret - check whether we have a CHAP file with a
+ * secret that we could possibly use for authenticating `client'
+ * on `server'.  Either can be the null string, meaning we don't
+ * know the identity yet.
+ */
+static int
+have_chap_secret(client, server, need_ip, lacks_ipp)
+    char *client;
+    char *server;
+    int need_ip;
+    int *lacks_ipp;
+{
+    FILE *f;
+    int ret;
+    char *filename;
+    struct wordlist *addrs;
+
+    if (chap_check_hook) {
+	ret = (*chap_check_hook)();
+	if (ret >= 0) {
+	    return ret;
+	}
+    }
+
+    filename = _PATH_CHAPFILE;
+    f = fopen(filename, "r");
+    if (f == NULL)
+	return 0;
+
+    if (client != NULL && client[0] == 0)
+	client = NULL;
+    else if (server != NULL && server[0] == 0)
+	server = NULL;
+
+    ret = scan_authfile(f, client, server, NULL, &addrs, NULL, filename, 0);
+    fclose(f);
+    if (ret >= 0 && need_ip && !some_ip_ok(addrs)) {
+	if (lacks_ipp != 0)
+	    *lacks_ipp = 1;
+	ret = -1;
+    }
+    if (addrs != 0)
+	free_wordlist(addrs);
+
+    return ret >= 0;
+}
+
+/*
+ * have_srp_secret - check whether we have a SRP file with a
+ * secret that we could possibly use for authenticating `client'
+ * on `server'.  Either can be the null string, meaning we don't
+ * know the identity yet.
+ */
+static int
+have_srp_secret(client, server, need_ip, lacks_ipp)
+    char *client;
+    char *server;
+    int need_ip;
+    int *lacks_ipp;
+{
+    FILE *f;
+    int ret;
+    char *filename;
+    struct wordlist *addrs;
+
+    filename = _PATH_SRPFILE;
+    f = fopen(filename, "r");
+    if (f == NULL)
+	return 0;
+
+    if (client != NULL && client[0] == 0)
+	client = NULL;
+    else if (server != NULL && server[0] == 0)
+	server = NULL;
+
+    ret = scan_authfile(f, client, server, NULL, &addrs, NULL, filename, 0);
+    fclose(f);
+    if (ret >= 0 && need_ip && !some_ip_ok(addrs)) {
+	if (lacks_ipp != 0)
+	    *lacks_ipp = 1;
+	ret = -1;
+    }
+    if (addrs != 0)
+	free_wordlist(addrs);
+
+    return ret >= 0;
+}
+#endif /* UNUSED */
+
+#if PPP_AUTH_SUPPORT
+/*
+ * get_secret - open the CHAP secret file and return the secret
+ * for authenticating the given client on the given server.
+ * (We could be either client or server).
+ */
+int get_secret(ppp_pcb *pcb, const char *client, const char *server, char *secret, int *secret_len, int am_server) {
+  int len;
+  LWIP_UNUSED_ARG(server);
+  LWIP_UNUSED_ARG(am_server);
+
+  if (!client || !client[0] || !pcb->settings.user || !pcb->settings.passwd || strcmp(client, pcb->settings.user)) {
+    return 0;
+  }
+
+  len = (int)strlen(pcb->settings.passwd);
+  if (len > MAXSECRETLEN) {
+    ppp_error("Secret for %s on %s is too long", client, server);
+    len = MAXSECRETLEN;
+  }
+
+  MEMCPY(secret, pcb->settings.passwd, len);
+  *secret_len = len;
+  return 1;
+
+#if 0 /* UNUSED */
+    FILE *f;
+    int ret, len;
+    char *filename;
+    struct wordlist *addrs, *opts;
+    char secbuf[MAXWORDLEN];
+    struct wordlist *addrs;
+    addrs = NULL;
+
+    if (!am_server && ppp_settings.passwd[0] != 0) {
+	strlcpy(secbuf, ppp_settings.passwd, sizeof(secbuf));
+    } else if (!am_server && chap_passwd_hook) {
+	if ( (*chap_passwd_hook)(client, secbuf) < 0) {
+	    ppp_error("Unable to obtain CHAP password for %s on %s from plugin",
+		  client, server);
+	    return 0;
+	}
+    } else {
+	filename = _PATH_CHAPFILE;
+	addrs = NULL;
+	secbuf[0] = 0;
+
+	f = fopen(filename, "r");
+	if (f == NULL) {
+	    ppp_error("Can't open chap secret file %s: %m", filename);
+	    return 0;
+	}
+	check_access(f, filename);
+
+	ret = scan_authfile(f, client, server, secbuf, &addrs, &opts, filename, 0);
+	fclose(f);
+	if (ret < 0)
+	    return 0;
+
+	if (am_server)
+	    set_allowed_addrs(unit, addrs, opts);
+	else if (opts != 0)
+	    free_wordlist(opts);
+	if (addrs != 0)
+	    free_wordlist(addrs);
+    }
+
+    len = strlen(secbuf);
+    if (len > MAXSECRETLEN) {
+	ppp_error("Secret for %s on %s is too long", client, server);
+	len = MAXSECRETLEN;
+    }
+    MEMCPY(secret, secbuf, len);
+    BZERO(secbuf, sizeof(secbuf));
+    *secret_len = len;
+
+    return 1;
+#endif /* UNUSED */
+}
+#endif /* PPP_AUTH_SUPPORT */
+
+
+#if 0 /* UNUSED */
+/*
+ * get_srp_secret - open the SRP secret file and return the secret
+ * for authenticating the given client on the given server.
+ * (We could be either client or server).
+ */
+int
+get_srp_secret(unit, client, server, secret, am_server)
+    int unit;
+    char *client;
+    char *server;
+    char *secret;
+    int am_server;
+{
+    FILE *fp;
+    int ret;
+    char *filename;
+    struct wordlist *addrs, *opts;
+
+    if (!am_server && ppp_settings.passwd[0] != '\0') {
+	strlcpy(secret, ppp_settings.passwd, MAXWORDLEN);
+    } else {
+	filename = _PATH_SRPFILE;
+	addrs = NULL;
+
+	fp = fopen(filename, "r");
+	if (fp == NULL) {
+	    ppp_error("Can't open srp secret file %s: %m", filename);
+	    return 0;
+	}
+	check_access(fp, filename);
+
+	secret[0] = '\0';
+	ret = scan_authfile(fp, client, server, secret, &addrs, &opts,
+	    filename, am_server);
+	fclose(fp);
+	if (ret < 0)
+	    return 0;
+
+	if (am_server)
+	    set_allowed_addrs(unit, addrs, opts);
+	else if (opts != NULL)
+	    free_wordlist(opts);
+	if (addrs != NULL)
+	    free_wordlist(addrs);
+    }
+
+    return 1;
+}
+
+/*
+ * set_allowed_addrs() - set the list of allowed addresses.
+ * Also looks for `--' indicating options to apply for this peer
+ * and leaves the following words in extra_options.
+ */
+static void
+set_allowed_addrs(unit, addrs, opts)
+    int unit;
+    struct wordlist *addrs;
+    struct wordlist *opts;
+{
+    int n;
+    struct wordlist *ap, **plink;
+    struct permitted_ip *ip;
+    char *ptr_word, *ptr_mask;
+    struct hostent *hp;
+    struct netent *np;
+    u32_t a, mask, ah, offset;
+    struct ipcp_options *wo = &ipcp_wantoptions[unit];
+    u32_t suggested_ip = 0;
+
+    if (addresses[unit] != NULL)
+	free(addresses[unit]);
+    addresses[unit] = NULL;
+    if (extra_options != NULL)
+	free_wordlist(extra_options);
+    extra_options = opts;
+
+    /*
+     * Count the number of IP addresses given.
+     */
+    n = wordlist_count(addrs) + wordlist_count(noauth_addrs);
+    if (n == 0)
+	return;
+    ip = (struct permitted_ip *) malloc((n + 1) * sizeof(struct permitted_ip));
+    if (ip == 0)
+	return;
+
+    /* temporarily append the noauth_addrs list to addrs */
+    for (plink = &addrs; *plink != NULL; plink = &(*plink)->next)
+	;
+    *plink = noauth_addrs;
+
+    n = 0;
+    for (ap = addrs; ap != NULL; ap = ap->next) {
+	/* "-" means no addresses authorized, "*" means any address allowed */
+	ptr_word = ap->word;
+	if (strcmp(ptr_word, "-") == 0)
+	    break;
+	if (strcmp(ptr_word, "*") == 0) {
+	    ip[n].permit = 1;
+	    ip[n].base = ip[n].mask = 0;
+	    ++n;
+	    break;
+	}
+
+	ip[n].permit = 1;
+	if (*ptr_word == '!') {
+	    ip[n].permit = 0;
+	    ++ptr_word;
+	}
+
+	mask = ~ (u32_t) 0;
+	offset = 0;
+	ptr_mask = strchr (ptr_word, '/');
+	if (ptr_mask != NULL) {
+	    int bit_count;
+	    char *endp;
+
+	    bit_count = (int) strtol (ptr_mask+1, &endp, 10);
+	    if (bit_count <= 0 || bit_count > 32) {
+		ppp_warn("invalid address length %v in auth. address list",
+		     ptr_mask+1);
+		continue;
+	    }
+	    bit_count = 32 - bit_count;	/* # bits in host part */
+	    if (*endp == '+') {
+		offset = ifunit + 1;
+		++endp;
+	    }
+	    if (*endp != 0) {
+		ppp_warn("invalid address length syntax: %v", ptr_mask+1);
+		continue;
+	    }
+	    *ptr_mask = '\0';
+	    mask <<= bit_count;
+	}
+
+	hp = gethostbyname(ptr_word);
+	if (hp != NULL && hp->h_addrtype == AF_INET) {
+	    a = *(u32_t *)hp->h_addr;
+	} else {
+	    np = getnetbyname (ptr_word);
+	    if (np != NULL && np->n_addrtype == AF_INET) {
+		a = lwip_htonl ((u32_t)np->n_net);
+		if (ptr_mask == NULL) {
+		    /* calculate appropriate mask for net */
+		    ah = lwip_ntohl(a);
+		    if (IN_CLASSA(ah))
+			mask = IN_CLASSA_NET;
+		    else if (IN_CLASSB(ah))
+			mask = IN_CLASSB_NET;
+		    else if (IN_CLASSC(ah))
+			mask = IN_CLASSC_NET;
+		}
+	    } else {
+		a = inet_addr (ptr_word);
+	    }
+	}
+
+	if (ptr_mask != NULL)
+	    *ptr_mask = '/';
+
+	if (a == (u32_t)-1L) {
+	    ppp_warn("unknown host %s in auth. address list", ap->word);
+	    continue;
+	}
+	if (offset != 0) {
+	    if (offset >= ~mask) {
+		ppp_warn("interface unit %d too large for subnet %v",
+		     ifunit, ptr_word);
+		continue;
+	    }
+	    a = lwip_htonl((lwip_ntohl(a) & mask) + offset);
+	    mask = ~(u32_t)0;
+	}
+	ip[n].mask = lwip_htonl(mask);
+	ip[n].base = a & ip[n].mask;
+	++n;
+	if (~mask == 0 && suggested_ip == 0)
+	    suggested_ip = a;
+    }
+    *plink = NULL;
+
+    ip[n].permit = 0;		/* make the last entry forbid all addresses */
+    ip[n].base = 0;		/* to terminate the list */
+    ip[n].mask = 0;
+
+    addresses[unit] = ip;
+
+    /*
+     * If the address given for the peer isn't authorized, or if
+     * the user hasn't given one, AND there is an authorized address
+     * which is a single host, then use that if we find one.
+     */
+    if (suggested_ip != 0
+	&& (wo->hisaddr == 0 || !auth_ip_addr(unit, wo->hisaddr))) {
+	wo->hisaddr = suggested_ip;
+	/*
+	 * Do we insist on this address?  No, if there are other
+	 * addresses authorized than the suggested one.
+	 */
+	if (n > 1)
+	    wo->accept_remote = 1;
+    }
+}
+
+/*
+ * auth_ip_addr - check whether the peer is authorized to use
+ * a given IP address.  Returns 1 if authorized, 0 otherwise.
+ */
+int
+auth_ip_addr(unit, addr)
+    int unit;
+    u32_t addr;
+{
+    int ok;
+
+    /* don't allow loopback or multicast address */
+    if (bad_ip_adrs(addr))
+	return 0;
+
+    if (allowed_address_hook) {
+	ok = allowed_address_hook(addr);
+	if (ok >= 0) return ok;
+    }
+
+    if (addresses[unit] != NULL) {
+	ok = ip_addr_check(addr, addresses[unit]);
+	if (ok >= 0)
+	    return ok;
+    }
+
+    if (auth_required)
+	return 0;		/* no addresses authorized */
+    return allow_any_ip || privileged || !have_route_to(addr);
+}
+
+static int
+ip_addr_check(addr, addrs)
+    u32_t addr;
+    struct permitted_ip *addrs;
+{
+    for (; ; ++addrs)
+	if ((addr & addrs->mask) == addrs->base)
+	    return addrs->permit;
+}
+
+/*
+ * bad_ip_adrs - return 1 if the IP address is one we don't want
+ * to use, such as an address in the loopback net or a multicast address.
+ * addr is in network byte order.
+ */
+int
+bad_ip_adrs(addr)
+    u32_t addr;
+{
+    addr = lwip_ntohl(addr);
+    return (addr >> IN_CLASSA_NSHIFT) == IN_LOOPBACKNET
+	|| IN_MULTICAST(addr) || IN_BADCLASS(addr);
+}
+
+/*
+ * some_ip_ok - check a wordlist to see if it authorizes any
+ * IP address(es).
+ */
+static int
+some_ip_ok(addrs)
+    struct wordlist *addrs;
+{
+    for (; addrs != 0; addrs = addrs->next) {
+	if (addrs->word[0] == '-')
+	    break;
+	if (addrs->word[0] != '!')
+	    return 1;		/* some IP address is allowed */
+    }
+    return 0;
+}
+
+/*
+ * auth_number - check whether the remote number is allowed to connect.
+ * Returns 1 if authorized, 0 otherwise.
+ */
+int
+auth_number()
+{
+    struct wordlist *wp = permitted_numbers;
+    int l;
+
+    /* Allow all if no authorization list. */
+    if (!wp)
+	return 1;
+
+    /* Allow if we have a match in the authorization list. */
+    while (wp) {
+	/* trailing '*' wildcard */
+	l = strlen(wp->word);
+	if ((wp->word)[l - 1] == '*')
+	    l--;
+	if (!strncasecmp(wp->word, remote_number, l))
+	    return 1;
+	wp = wp->next;
+    }
+
+    return 0;
+}
+
+/*
+ * check_access - complain if a secret file has too-liberal permissions.
+ */
+static void
+check_access(f, filename)
+    FILE *f;
+    char *filename;
+{
+    struct stat sbuf;
+
+    if (fstat(fileno(f), &sbuf) < 0) {
+	ppp_warn("cannot stat secret file %s: %m", filename);
+    } else if ((sbuf.st_mode & (S_IRWXG | S_IRWXO)) != 0) {
+	ppp_warn("Warning - secret file %s has world and/or group access",
+	     filename);
+    }
+}
+
+/*
+ * scan_authfile - Scan an authorization file for a secret suitable
+ * for authenticating `client' on `server'.  The return value is -1
+ * if no secret is found, otherwise >= 0.  The return value has
+ * NONWILD_CLIENT set if the secret didn't have "*" for the client, and
+ * NONWILD_SERVER set if the secret didn't have "*" for the server.
+ * Any following words on the line up to a "--" (i.e. address authorization
+ * info) are placed in a wordlist and returned in *addrs.  Any
+ * following words (extra options) are placed in a wordlist and
+ * returned in *opts.
+ * We assume secret is NULL or points to MAXWORDLEN bytes of space.
+ * Flags are non-zero if we need two colons in the secret in order to
+ * match.
+ */
+static int
+scan_authfile(f, client, server, secret, addrs, opts, filename, flags)
+    FILE *f;
+    char *client;
+    char *server;
+    char *secret;
+    struct wordlist **addrs;
+    struct wordlist **opts;
+    char *filename;
+    int flags;
+{
+    int newline, xxx;
+    int got_flag, best_flag;
+    FILE *sf;
+    struct wordlist *ap, *addr_list, *alist, **app;
+    char word[MAXWORDLEN];
+    char atfile[MAXWORDLEN];
+    char lsecret[MAXWORDLEN];
+    char *cp;
+
+    if (addrs != NULL)
+	*addrs = NULL;
+    if (opts != NULL)
+	*opts = NULL;
+    addr_list = NULL;
+    if (!getword(f, word, &newline, filename))
+	return -1;		/* file is empty??? */
+    newline = 1;
+    best_flag = -1;
+    for (;;) {
+	/*
+	 * Skip until we find a word at the start of a line.
+	 */
+	while (!newline && getword(f, word, &newline, filename))
+	    ;
+	if (!newline)
+	    break;		/* got to end of file */
+
+	/*
+	 * Got a client - check if it's a match or a wildcard.
+	 */
+	got_flag = 0;
+	if (client != NULL && strcmp(word, client) != 0 && !ISWILD(word)) {
+	    newline = 0;
+	    continue;
+	}
+	if (!ISWILD(word))
+	    got_flag = NONWILD_CLIENT;
+
+	/*
+	 * Now get a server and check if it matches.
+	 */
+	if (!getword(f, word, &newline, filename))
+	    break;
+	if (newline)
+	    continue;
+	if (!ISWILD(word)) {
+	    if (server != NULL && strcmp(word, server) != 0)
+		continue;
+	    got_flag |= NONWILD_SERVER;
+	}
+
+	/*
+	 * Got some sort of a match - see if it's better than what
+	 * we have already.
+	 */
+	if (got_flag <= best_flag)
+	    continue;
+
+	/*
+	 * Get the secret.
+	 */
+	if (!getword(f, word, &newline, filename))
+	    break;
+	if (newline)
+	    continue;
+
+	/*
+	 * SRP-SHA1 authenticator should never be reading secrets from
+	 * a file.  (Authenticatee may, though.)
+	 */
+	if (flags && ((cp = strchr(word, ':')) == NULL ||
+	    strchr(cp + 1, ':') == NULL))
+	    continue;
+
+	if (secret != NULL) {
+	    /*
+	     * Special syntax: @/pathname means read secret from file.
+	     */
+	    if (word[0] == '@' && word[1] == '/') {
+		strlcpy(atfile, word+1, sizeof(atfile));
+		if ((sf = fopen(atfile, "r")) == NULL) {
+		    ppp_warn("can't open indirect secret file %s", atfile);
+		    continue;
+		}
+		check_access(sf, atfile);
+		if (!getword(sf, word, &xxx, atfile)) {
+		    ppp_warn("no secret in indirect secret file %s", atfile);
+		    fclose(sf);
+		    continue;
+		}
+		fclose(sf);
+	    }
+	    strlcpy(lsecret, word, sizeof(lsecret));
+	}
+
+	/*
+	 * Now read address authorization info and make a wordlist.
+	 */
+	app = &alist;
+	for (;;) {
+	    if (!getword(f, word, &newline, filename) || newline)
+		break;
+	    ap = (struct wordlist *)
+		    malloc(sizeof(struct wordlist) + strlen(word) + 1);
+	    if (ap == NULL)
+		novm("authorized addresses");
+	    ap->word = (char *) (ap + 1);
+	    strcpy(ap->word, word);
+	    *app = ap;
+	    app = &ap->next;
+	}
+	*app = NULL;
+
+	/*
+	 * This is the best so far; remember it.
+	 */
+	best_flag = got_flag;
+	if (addr_list)
+	    free_wordlist(addr_list);
+	addr_list = alist;
+	if (secret != NULL)
+	    strlcpy(secret, lsecret, MAXWORDLEN);
+
+	if (!newline)
+	    break;
+    }
+
+    /* scan for a -- word indicating the start of options */
+    for (app = &addr_list; (ap = *app) != NULL; app = &ap->next)
+	if (strcmp(ap->word, "--") == 0)
+	    break;
+    /* ap = start of options */
+    if (ap != NULL) {
+	ap = ap->next;		/* first option */
+	free(*app);			/* free the "--" word */
+	*app = NULL;		/* terminate addr list */
+    }
+    if (opts != NULL)
+	*opts = ap;
+    else if (ap != NULL)
+	free_wordlist(ap);
+    if (addrs != NULL)
+	*addrs = addr_list;
+    else if (addr_list != NULL)
+	free_wordlist(addr_list);
+
+    return best_flag;
+}
+
+/*
+ * wordlist_count - return the number of items in a wordlist
+ */
+static int
+wordlist_count(wp)
+    struct wordlist *wp;
+{
+    int n;
+
+    for (n = 0; wp != NULL; wp = wp->next)
+	++n;
+    return n;
+}
+
+/*
+ * free_wordlist - release memory allocated for a wordlist.
+ */
+static void
+free_wordlist(wp)
+    struct wordlist *wp;
+{
+    struct wordlist *next;
+
+    while (wp != NULL) {
+	next = wp->next;
+	free(wp);
+	wp = next;
+    }
+}
+#endif /* UNUSED */
+
+#endif /* PPP_SUPPORT */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/netif/ppp/ccp.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/netif/ppp/ccp.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/netif/ppp/ccp.c	(revision 457)
@@ -0,0 +1,1740 @@
+/*
+ * ccp.c - PPP Compression Control Protocol.
+ *
+ * Copyright (c) 1994-2002 Paul Mackerras. 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. The name(s) of the authors of this software must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission.
+ *
+ * 3. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by Paul Mackerras
+ *     <paulus@samba.org>".
+ *
+ * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO
+ * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
+ * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
+ * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
+ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include "netif/ppp/ppp_opts.h"
+#if PPP_SUPPORT && CCP_SUPPORT  /* don't build if not configured for use in lwipopts.h */
+
+#include <stdlib.h>
+#include <string.h>
+
+#include "netif/ppp/ppp_impl.h"
+
+#include "netif/ppp/fsm.h"
+#include "netif/ppp/ccp.h"
+
+#if MPPE_SUPPORT
+#include "netif/ppp/lcp.h"	/* lcp_close(), lcp_fsm */
+#include "netif/ppp/mppe.h"	/* mppe_init() */
+#endif /* MPPE_SUPPORT */
+
+/*
+ * Unfortunately there is a bug in zlib which means that using a
+ * size of 8 (window size = 256) for Deflate compression will cause
+ * buffer overruns and kernel crashes in the deflate module.
+ * Until this is fixed we only accept sizes in the range 9 .. 15.
+ * Thanks to James Carlson for pointing this out.
+ */
+#define DEFLATE_MIN_WORKS	9
+
+/*
+ * Command-line options.
+ */
+#if PPP_OPTIONS
+static int setbsdcomp (char **);
+static int setdeflate (char **);
+static char bsd_value[8];
+static char deflate_value[8];
+
+/*
+ * Option variables.
+ */
+#if MPPE_SUPPORT
+bool refuse_mppe_stateful = 1;		/* Allow stateful mode? */
+#endif /* MPPE_SUPPORT */
+
+static option_t ccp_option_list[] = {
+    { "noccp", o_bool, &ccp_protent.enabled_flag,
+      "Disable CCP negotiation" },
+    { "-ccp", o_bool, &ccp_protent.enabled_flag,
+      "Disable CCP negotiation", OPT_ALIAS },
+
+    { "bsdcomp", o_special, (void *)setbsdcomp,
+      "Request BSD-Compress packet compression",
+      OPT_PRIO | OPT_A2STRVAL | OPT_STATIC, bsd_value },
+    { "nobsdcomp", o_bool, &ccp_wantoptions[0].bsd_compress,
+      "don't allow BSD-Compress", OPT_PRIOSUB | OPT_A2CLR,
+      &ccp_allowoptions[0].bsd_compress },
+    { "-bsdcomp", o_bool, &ccp_wantoptions[0].bsd_compress,
+      "don't allow BSD-Compress", OPT_ALIAS | OPT_PRIOSUB | OPT_A2CLR,
+      &ccp_allowoptions[0].bsd_compress },
+
+    { "deflate", o_special, (void *)setdeflate,
+      "request Deflate compression",
+      OPT_PRIO | OPT_A2STRVAL | OPT_STATIC, deflate_value },
+    { "nodeflate", o_bool, &ccp_wantoptions[0].deflate,
+      "don't allow Deflate compression", OPT_PRIOSUB | OPT_A2CLR,
+      &ccp_allowoptions[0].deflate },
+    { "-deflate", o_bool, &ccp_wantoptions[0].deflate,
+      "don't allow Deflate compression", OPT_ALIAS | OPT_PRIOSUB | OPT_A2CLR,
+      &ccp_allowoptions[0].deflate },
+
+    { "nodeflatedraft", o_bool, &ccp_wantoptions[0].deflate_draft,
+      "don't use draft deflate #", OPT_A2COPY,
+      &ccp_allowoptions[0].deflate_draft },
+
+    { "predictor1", o_bool, &ccp_wantoptions[0].predictor_1,
+      "request Predictor-1", OPT_PRIO | 1 },
+    { "nopredictor1", o_bool, &ccp_wantoptions[0].predictor_1,
+      "don't allow Predictor-1", OPT_PRIOSUB | OPT_A2CLR,
+      &ccp_allowoptions[0].predictor_1 },
+    { "-predictor1", o_bool, &ccp_wantoptions[0].predictor_1,
+      "don't allow Predictor-1", OPT_ALIAS | OPT_PRIOSUB | OPT_A2CLR,
+      &ccp_allowoptions[0].predictor_1 },
+
+#if MPPE_SUPPORT
+    /* MPPE options are symmetrical ... we only set wantoptions here */
+    { "require-mppe", o_bool, &ccp_wantoptions[0].mppe,
+      "require MPPE encryption",
+      OPT_PRIO | MPPE_OPT_40 | MPPE_OPT_128 },
+    { "+mppe", o_bool, &ccp_wantoptions[0].mppe,
+      "require MPPE encryption",
+      OPT_ALIAS | OPT_PRIO | MPPE_OPT_40 | MPPE_OPT_128 },
+    { "nomppe", o_bool, &ccp_wantoptions[0].mppe,
+      "don't allow MPPE encryption", OPT_PRIO },
+    { "-mppe", o_bool, &ccp_wantoptions[0].mppe,
+      "don't allow MPPE encryption", OPT_ALIAS | OPT_PRIO },
+
+    /* We use ccp_allowoptions[0].mppe as a junk var ... it is reset later */
+    { "require-mppe-40", o_bool, &ccp_allowoptions[0].mppe,
+      "require MPPE 40-bit encryption", OPT_PRIO | OPT_A2OR | MPPE_OPT_40,
+      &ccp_wantoptions[0].mppe },
+    { "+mppe-40", o_bool, &ccp_allowoptions[0].mppe,
+      "require MPPE 40-bit encryption", OPT_PRIO | OPT_A2OR | MPPE_OPT_40,
+      &ccp_wantoptions[0].mppe },
+    { "nomppe-40", o_bool, &ccp_allowoptions[0].mppe,
+      "don't allow MPPE 40-bit encryption",
+      OPT_PRIOSUB | OPT_A2CLRB | MPPE_OPT_40, &ccp_wantoptions[0].mppe },
+    { "-mppe-40", o_bool, &ccp_allowoptions[0].mppe,
+      "don't allow MPPE 40-bit encryption",
+      OPT_ALIAS | OPT_PRIOSUB | OPT_A2CLRB | MPPE_OPT_40,
+      &ccp_wantoptions[0].mppe },
+
+    { "require-mppe-128", o_bool, &ccp_allowoptions[0].mppe,
+      "require MPPE 128-bit encryption", OPT_PRIO | OPT_A2OR | MPPE_OPT_128,
+      &ccp_wantoptions[0].mppe },
+    { "+mppe-128", o_bool, &ccp_allowoptions[0].mppe,
+      "require MPPE 128-bit encryption",
+      OPT_ALIAS | OPT_PRIO | OPT_A2OR | MPPE_OPT_128,
+      &ccp_wantoptions[0].mppe },
+    { "nomppe-128", o_bool, &ccp_allowoptions[0].mppe,
+      "don't allow MPPE 128-bit encryption",
+      OPT_PRIOSUB | OPT_A2CLRB | MPPE_OPT_128, &ccp_wantoptions[0].mppe },
+    { "-mppe-128", o_bool, &ccp_allowoptions[0].mppe,
+      "don't allow MPPE 128-bit encryption",
+      OPT_ALIAS | OPT_PRIOSUB | OPT_A2CLRB | MPPE_OPT_128,
+      &ccp_wantoptions[0].mppe },
+
+    /* strange one; we always request stateless, but will we allow stateful? */
+    { "mppe-stateful", o_bool, &refuse_mppe_stateful,
+      "allow MPPE stateful mode", OPT_PRIO },
+    { "nomppe-stateful", o_bool, &refuse_mppe_stateful,
+      "disallow MPPE stateful mode", OPT_PRIO | 1 },
+#endif /* MPPE_SUPPORT */
+
+    { NULL }
+};
+#endif /* PPP_OPTIONS */
+
+/*
+ * Protocol entry points from main code.
+ */
+static void ccp_init(ppp_pcb *pcb);
+static void ccp_open(ppp_pcb *pcb);
+static void ccp_close(ppp_pcb *pcb, const char *reason);
+static void ccp_lowerup(ppp_pcb *pcb);
+static void ccp_lowerdown(ppp_pcb *pcb);
+static void ccp_input(ppp_pcb *pcb, u_char *pkt, int len);
+static void ccp_protrej(ppp_pcb *pcb);
+#if PRINTPKT_SUPPORT
+static int ccp_printpkt(const u_char *p, int plen, void (*printer) (void *, const char *, ...), void *arg);
+#endif /* PRINTPKT_SUPPORT */
+#if PPP_DATAINPUT
+static void ccp_datainput(ppp_pcb *pcb, u_char *pkt, int len);
+#endif /* PPP_DATAINPUT */
+
+const struct protent ccp_protent = {
+    PPP_CCP,
+    ccp_init,
+    ccp_input,
+    ccp_protrej,
+    ccp_lowerup,
+    ccp_lowerdown,
+    ccp_open,
+    ccp_close,
+#if PRINTPKT_SUPPORT
+    ccp_printpkt,
+#endif /* PRINTPKT_SUPPORT */
+#if PPP_DATAINPUT
+    ccp_datainput,
+#endif /* PPP_DATAINPUT */
+#if PRINTPKT_SUPPORT
+    "CCP",
+    "Compressed",
+#endif /* PRINTPKT_SUPPORT */
+#if PPP_OPTIONS
+    ccp_option_list,
+    NULL,
+#endif /* PPP_OPTIONS */
+#if DEMAND_SUPPORT
+    NULL,
+    NULL
+#endif /* DEMAND_SUPPORT */
+};
+
+/*
+ * Callbacks for fsm code.
+ */
+static void ccp_resetci (fsm *);
+static int  ccp_cilen (fsm *);
+static void ccp_addci (fsm *, u_char *, int *);
+static int  ccp_ackci (fsm *, u_char *, int);
+static int  ccp_nakci (fsm *, u_char *, int, int);
+static int  ccp_rejci (fsm *, u_char *, int);
+static int  ccp_reqci (fsm *, u_char *, int *, int);
+static void ccp_up (fsm *);
+static void ccp_down (fsm *);
+static int  ccp_extcode (fsm *, int, int, u_char *, int);
+static void ccp_rack_timeout (void *);
+static const char *method_name (ccp_options *, ccp_options *);
+
+static const fsm_callbacks ccp_callbacks = {
+    ccp_resetci,
+    ccp_cilen,
+    ccp_addci,
+    ccp_ackci,
+    ccp_nakci,
+    ccp_rejci,
+    ccp_reqci,
+    ccp_up,
+    ccp_down,
+    NULL,
+    NULL,
+    NULL,
+    NULL,
+    ccp_extcode,
+    "CCP"
+};
+
+/*
+ * Do we want / did we get any compression?
+ */
+static int ccp_anycompress(ccp_options *opt) {
+    return (0
+#if DEFLATE_SUPPORT
+	|| (opt)->deflate
+#endif /* DEFLATE_SUPPORT */
+#if BSDCOMPRESS_SUPPORT
+	|| (opt)->bsd_compress
+#endif /* BSDCOMPRESS_SUPPORT */
+#if PREDICTOR_SUPPORT
+	|| (opt)->predictor_1 || (opt)->predictor_2
+#endif /* PREDICTOR_SUPPORT */
+#if MPPE_SUPPORT
+	|| (opt)->mppe
+#endif /* MPPE_SUPPORT */
+	);
+}
+
+/*
+ * Local state (mainly for handling reset-reqs and reset-acks).
+ */
+#define RACK_PENDING	1	/* waiting for reset-ack */
+#define RREQ_REPEAT	2	/* send another reset-req if no reset-ack */
+
+#define RACKTIMEOUT	1	/* second */
+
+#if PPP_OPTIONS
+/*
+ * Option parsing
+ */
+static int
+setbsdcomp(argv)
+    char **argv;
+{
+    int rbits, abits;
+    char *str, *endp;
+
+    str = *argv;
+    abits = rbits = strtol(str, &endp, 0);
+    if (endp != str && *endp == ',') {
+	str = endp + 1;
+	abits = strtol(str, &endp, 0);
+    }
+    if (*endp != 0 || endp == str) {
+	option_error("invalid parameter '%s' for bsdcomp option", *argv);
+	return 0;
+    }
+    if ((rbits != 0 && (rbits < BSD_MIN_BITS || rbits > BSD_MAX_BITS))
+	|| (abits != 0 && (abits < BSD_MIN_BITS || abits > BSD_MAX_BITS))) {
+	option_error("bsdcomp option values must be 0 or %d .. %d",
+		     BSD_MIN_BITS, BSD_MAX_BITS);
+	return 0;
+    }
+    if (rbits > 0) {
+	ccp_wantoptions[0].bsd_compress = 1;
+	ccp_wantoptions[0].bsd_bits = rbits;
+    } else
+	ccp_wantoptions[0].bsd_compress = 0;
+    if (abits > 0) {
+	ccp_allowoptions[0].bsd_compress = 1;
+	ccp_allowoptions[0].bsd_bits = abits;
+    } else
+	ccp_allowoptions[0].bsd_compress = 0;
+    ppp_slprintf(bsd_value, sizeof(bsd_value),
+	     rbits == abits? "%d": "%d,%d", rbits, abits);
+
+    return 1;
+}
+
+static int
+setdeflate(argv)
+    char **argv;
+{
+    int rbits, abits;
+    char *str, *endp;
+
+    str = *argv;
+    abits = rbits = strtol(str, &endp, 0);
+    if (endp != str && *endp == ',') {
+	str = endp + 1;
+	abits = strtol(str, &endp, 0);
+    }
+    if (*endp != 0 || endp == str) {
+	option_error("invalid parameter '%s' for deflate option", *argv);
+	return 0;
+    }
+    if ((rbits != 0 && (rbits < DEFLATE_MIN_SIZE || rbits > DEFLATE_MAX_SIZE))
+	|| (abits != 0 && (abits < DEFLATE_MIN_SIZE
+			  || abits > DEFLATE_MAX_SIZE))) {
+	option_error("deflate option values must be 0 or %d .. %d",
+		     DEFLATE_MIN_SIZE, DEFLATE_MAX_SIZE);
+	return 0;
+    }
+    if (rbits == DEFLATE_MIN_SIZE || abits == DEFLATE_MIN_SIZE) {
+	if (rbits == DEFLATE_MIN_SIZE)
+	    rbits = DEFLATE_MIN_WORKS;
+	if (abits == DEFLATE_MIN_SIZE)
+	    abits = DEFLATE_MIN_WORKS;
+	warn("deflate option value of %d changed to %d to avoid zlib bug",
+	     DEFLATE_MIN_SIZE, DEFLATE_MIN_WORKS);
+    }
+    if (rbits > 0) {
+	ccp_wantoptions[0].deflate = 1;
+	ccp_wantoptions[0].deflate_size = rbits;
+    } else
+	ccp_wantoptions[0].deflate = 0;
+    if (abits > 0) {
+	ccp_allowoptions[0].deflate = 1;
+	ccp_allowoptions[0].deflate_size = abits;
+    } else
+	ccp_allowoptions[0].deflate = 0;
+    ppp_slprintf(deflate_value, sizeof(deflate_value),
+	     rbits == abits? "%d": "%d,%d", rbits, abits);
+
+    return 1;
+}
+#endif /* PPP_OPTIONS */
+
+/*
+ * ccp_init - initialize CCP.
+ */
+static void ccp_init(ppp_pcb *pcb) {
+    fsm *f = &pcb->ccp_fsm;
+
+    f->pcb = pcb;
+    f->protocol = PPP_CCP;
+    f->callbacks = &ccp_callbacks;
+    fsm_init(f);
+
+#if 0 /* Not necessary, everything is cleared in ppp_new() */
+    memset(wo, 0, sizeof(*wo));
+    memset(go, 0, sizeof(*go));
+    memset(ao, 0, sizeof(*ao));
+    memset(ho, 0, sizeof(*ho));
+#endif /* 0 */
+
+#if DEFLATE_SUPPORT
+    wo->deflate = 1;
+    wo->deflate_size = DEFLATE_MAX_SIZE;
+    wo->deflate_correct = 1;
+    wo->deflate_draft = 1;
+    ao->deflate = 1;
+    ao->deflate_size = DEFLATE_MAX_SIZE;
+    ao->deflate_correct = 1;
+    ao->deflate_draft = 1;
+#endif /* DEFLATE_SUPPORT */
+
+#if BSDCOMPRESS_SUPPORT
+    wo->bsd_compress = 1;
+    wo->bsd_bits = BSD_MAX_BITS;
+    ao->bsd_compress = 1;
+    ao->bsd_bits = BSD_MAX_BITS;
+#endif /* BSDCOMPRESS_SUPPORT */
+
+#if PREDICTOR_SUPPORT
+    ao->predictor_1 = 1;
+#endif /* PREDICTOR_SUPPORT */
+}
+
+/*
+ * ccp_open - CCP is allowed to come up.
+ */
+static void ccp_open(ppp_pcb *pcb) {
+    fsm *f = &pcb->ccp_fsm;
+    ccp_options *go = &pcb->ccp_gotoptions;
+
+    if (f->state != PPP_FSM_OPENED)
+	ccp_set(pcb, 1, 0, 0, 0);
+
+    /*
+     * Find out which compressors the kernel supports before
+     * deciding whether to open in silent mode.
+     */
+    ccp_resetci(f);
+    if (!ccp_anycompress(go))
+	f->flags |= OPT_SILENT;
+
+    fsm_open(f);
+}
+
+/*
+ * ccp_close - Terminate CCP.
+ */
+static void ccp_close(ppp_pcb *pcb, const char *reason) {
+    fsm *f = &pcb->ccp_fsm;
+    ccp_set(pcb, 0, 0, 0, 0);
+    fsm_close(f, reason);
+}
+
+/*
+ * ccp_lowerup - we may now transmit CCP packets.
+ */
+static void ccp_lowerup(ppp_pcb *pcb) {
+    fsm *f = &pcb->ccp_fsm;
+    fsm_lowerup(f);
+}
+
+/*
+ * ccp_lowerdown - we may not transmit CCP packets.
+ */
+static void ccp_lowerdown(ppp_pcb *pcb) {
+    fsm *f = &pcb->ccp_fsm;
+    fsm_lowerdown(f);
+}
+
+/*
+ * ccp_input - process a received CCP packet.
+ */
+static void ccp_input(ppp_pcb *pcb, u_char *p, int len) {
+    fsm *f = &pcb->ccp_fsm;
+    ccp_options *go = &pcb->ccp_gotoptions;
+    int oldstate;
+
+    /*
+     * Check for a terminate-request so we can print a message.
+     */
+    oldstate = f->state;
+    fsm_input(f, p, len);
+    if (oldstate == PPP_FSM_OPENED && p[0] == TERMREQ && f->state != PPP_FSM_OPENED) {
+	ppp_notice("Compression disabled by peer.");
+#if MPPE_SUPPORT
+	if (go->mppe) {
+	    ppp_error("MPPE disabled, closing LCP");
+	    lcp_close(pcb, "MPPE disabled by peer");
+	}
+#endif /* MPPE_SUPPORT */
+    }
+
+    /*
+     * If we get a terminate-ack and we're not asking for compression,
+     * close CCP.
+     */
+    if (oldstate == PPP_FSM_REQSENT && p[0] == TERMACK
+	&& !ccp_anycompress(go))
+	ccp_close(pcb, "No compression negotiated");
+}
+
+/*
+ * Handle a CCP-specific code.
+ */
+static int ccp_extcode(fsm *f, int code, int id, u_char *p, int len) {
+    ppp_pcb *pcb = f->pcb;
+    LWIP_UNUSED_ARG(p);
+    LWIP_UNUSED_ARG(len);
+
+    switch (code) {
+    case CCP_RESETREQ:
+	if (f->state != PPP_FSM_OPENED)
+	    break;
+	ccp_reset_comp(pcb);
+	/* send a reset-ack, which the transmitter will see and
+	   reset its compression state. */
+	fsm_sdata(f, CCP_RESETACK, id, NULL, 0);
+	break;
+
+    case CCP_RESETACK:
+	if ((pcb->ccp_localstate & RACK_PENDING) && id == f->reqid) {
+	    pcb->ccp_localstate &= ~(RACK_PENDING | RREQ_REPEAT);
+	    UNTIMEOUT(ccp_rack_timeout, f);
+	    ccp_reset_decomp(pcb);
+	}
+	break;
+
+    default:
+	return 0;
+    }
+
+    return 1;
+}
+
+/*
+ * ccp_protrej - peer doesn't talk CCP.
+ */
+static void ccp_protrej(ppp_pcb *pcb) {
+    fsm *f = &pcb->ccp_fsm;
+#if MPPE_SUPPORT
+    ccp_options *go = &pcb->ccp_gotoptions;
+#endif /* MPPE_SUPPORT */
+
+    ccp_set(pcb, 0, 0, 0, 0);
+    fsm_lowerdown(f);
+
+#if MPPE_SUPPORT
+    if (go->mppe) {
+	ppp_error("MPPE required but peer negotiation failed");
+	lcp_close(pcb, "MPPE required but peer negotiation failed");
+    }
+#endif /* MPPE_SUPPORT */
+
+}
+
+/*
+ * ccp_resetci - initialize at start of negotiation.
+ */
+static void ccp_resetci(fsm *f) {
+    ppp_pcb *pcb = f->pcb;
+    ccp_options *go = &pcb->ccp_gotoptions;
+    ccp_options *wo = &pcb->ccp_wantoptions;
+#if MPPE_SUPPORT
+    ccp_options *ao = &pcb->ccp_allowoptions;
+#endif /* MPPE_SUPPORT */
+#if DEFLATE_SUPPORT || BSDCOMPRESS_SUPPORT || PREDICTOR_SUPPORT
+    u_char opt_buf[CCP_MAX_OPTION_LENGTH];
+#endif /* DEFLATE_SUPPORT || BSDCOMPRESS_SUPPORT || PREDICTOR_SUPPORT */
+#if DEFLATE_SUPPORT || BSDCOMPRESS_SUPPORT
+    int res;
+#endif /* DEFLATE_SUPPORT || BSDCOMPRESS_SUPPORT */
+
+#if MPPE_SUPPORT
+    if (pcb->settings.require_mppe) {
+	wo->mppe = ao->mppe =
+		    (pcb->settings.refuse_mppe_40 ? 0 : MPPE_OPT_40)
+		  | (pcb->settings.refuse_mppe_128 ? 0 : MPPE_OPT_128);
+    }
+#endif /* MPPE_SUPPORT */
+
+    *go = *wo;
+    pcb->ccp_all_rejected = 0;
+
+#if MPPE_SUPPORT
+    if (go->mppe) {
+	int auth_mschap_bits = pcb->auth_done;
+	int numbits;
+
+	/*
+	 * Start with a basic sanity check: mschap[v2] auth must be in
+	 * exactly one direction.  RFC 3079 says that the keys are
+	 * 'derived from the credentials of the peer that initiated the call',
+	 * however the PPP protocol doesn't have such a concept, and pppd
+	 * cannot get this info externally.  Instead we do the best we can.
+	 * NB: If MPPE is required, all other compression opts are invalid.
+	 *     So, we return right away if we can't do it.
+	 */
+
+	/* Leave only the mschap auth bits set */
+	auth_mschap_bits &= (CHAP_MS_WITHPEER  | CHAP_MS_PEER |
+			     CHAP_MS2_WITHPEER | CHAP_MS2_PEER);
+	/* Count the mschap auths */
+	auth_mschap_bits >>= CHAP_MS_SHIFT;
+	numbits = 0;
+	do {
+	    numbits += auth_mschap_bits & 1;
+	    auth_mschap_bits >>= 1;
+	} while (auth_mschap_bits);
+	if (numbits > 1) {
+	    ppp_error("MPPE required, but auth done in both directions.");
+	    lcp_close(pcb, "MPPE required but not available");
+	    return;
+	}
+	if (!numbits) {
+	    ppp_error("MPPE required, but MS-CHAP[v2] auth not performed.");
+	    lcp_close(pcb, "MPPE required but not available");
+	    return;
+	}
+
+	/* A plugin (eg radius) may not have obtained key material. */
+	if (!pcb->mppe_keys_set) {
+	    ppp_error("MPPE required, but keys are not available.  "
+		  "Possible plugin problem?");
+	    lcp_close(pcb, "MPPE required but not available");
+	    return;
+	}
+
+	/* LM auth not supported for MPPE */
+	if (pcb->auth_done & (CHAP_MS_WITHPEER | CHAP_MS_PEER)) {
+	    /* This might be noise */
+	    if (go->mppe & MPPE_OPT_40) {
+		ppp_notice("Disabling 40-bit MPPE; MS-CHAP LM not supported");
+		go->mppe &= ~MPPE_OPT_40;
+		wo->mppe &= ~MPPE_OPT_40;
+	    }
+	}
+
+	/* Last check: can we actually negotiate something? */
+	if (!(go->mppe & (MPPE_OPT_40 | MPPE_OPT_128))) {
+	    /* Could be misconfig, could be 40-bit disabled above. */
+	    ppp_error("MPPE required, but both 40-bit and 128-bit disabled.");
+	    lcp_close(pcb, "MPPE required but not available");
+	    return;
+	}
+
+	/* sync options */
+	ao->mppe = go->mppe;
+	/* MPPE is not compatible with other compression types */
+#if BSDCOMPRESS_SUPPORT
+	ao->bsd_compress = go->bsd_compress = 0;
+#endif /* BSDCOMPRESS_SUPPORT */
+#if PREDICTOR_SUPPORT
+	ao->predictor_1  = go->predictor_1  = 0;
+	ao->predictor_2  = go->predictor_2  = 0;
+#endif /* PREDICTOR_SUPPORT */
+#if DEFLATE_SUPPORT
+	ao->deflate      = go->deflate      = 0;
+#endif /* DEFLATE_SUPPORT */
+    }
+#endif /* MPPE_SUPPORT */
+
+    /*
+     * Check whether the kernel knows about the various
+     * compression methods we might request.
+     */
+#if BSDCOMPRESS_SUPPORT
+    /* FIXME: we don't need to test if BSD compress is available
+     * if BSDCOMPRESS_SUPPORT is set, it is.
+     */
+    if (go->bsd_compress) {
+	opt_buf[0] = CI_BSD_COMPRESS;
+	opt_buf[1] = CILEN_BSD_COMPRESS;
+	for (;;) {
+	    if (go->bsd_bits < BSD_MIN_BITS) {
+		go->bsd_compress = 0;
+		break;
+	    }
+	    opt_buf[2] = BSD_MAKE_OPT(BSD_CURRENT_VERSION, go->bsd_bits);
+	    res = ccp_test(pcb, opt_buf, CILEN_BSD_COMPRESS, 0);
+	    if (res > 0) {
+		break;
+	    } else if (res < 0) {
+		go->bsd_compress = 0;
+		break;
+	    }
+	    go->bsd_bits--;
+	}
+    }
+#endif /* BSDCOMPRESS_SUPPORT */
+#if DEFLATE_SUPPORT
+    /* FIXME: we don't need to test if deflate is available
+     * if DEFLATE_SUPPORT is set, it is.
+     */
+    if (go->deflate) {
+	if (go->deflate_correct) {
+	    opt_buf[0] = CI_DEFLATE;
+	    opt_buf[1] = CILEN_DEFLATE;
+	    opt_buf[3] = DEFLATE_CHK_SEQUENCE;
+	    for (;;) {
+		if (go->deflate_size < DEFLATE_MIN_WORKS) {
+		    go->deflate_correct = 0;
+		    break;
+		}
+		opt_buf[2] = DEFLATE_MAKE_OPT(go->deflate_size);
+		res = ccp_test(pcb, opt_buf, CILEN_DEFLATE, 0);
+		if (res > 0) {
+		    break;
+		} else if (res < 0) {
+		    go->deflate_correct = 0;
+		    break;
+		}
+		go->deflate_size--;
+	    }
+	}
+	if (go->deflate_draft) {
+	    opt_buf[0] = CI_DEFLATE_DRAFT;
+	    opt_buf[1] = CILEN_DEFLATE;
+	    opt_buf[3] = DEFLATE_CHK_SEQUENCE;
+	    for (;;) {
+		if (go->deflate_size < DEFLATE_MIN_WORKS) {
+		    go->deflate_draft = 0;
+		    break;
+		}
+		opt_buf[2] = DEFLATE_MAKE_OPT(go->deflate_size);
+		res = ccp_test(pcb, opt_buf, CILEN_DEFLATE, 0);
+		if (res > 0) {
+		    break;
+		} else if (res < 0) {
+		    go->deflate_draft = 0;
+		    break;
+		}
+		go->deflate_size--;
+	    }
+	}
+	if (!go->deflate_correct && !go->deflate_draft)
+	    go->deflate = 0;
+    }
+#endif /* DEFLATE_SUPPORT */
+#if PREDICTOR_SUPPORT
+    /* FIXME: we don't need to test if predictor is available,
+     * if PREDICTOR_SUPPORT is set, it is.
+     */
+    if (go->predictor_1) {
+	opt_buf[0] = CI_PREDICTOR_1;
+	opt_buf[1] = CILEN_PREDICTOR_1;
+	if (ccp_test(pcb, opt_buf, CILEN_PREDICTOR_1, 0) <= 0)
+	    go->predictor_1 = 0;
+    }
+    if (go->predictor_2) {
+	opt_buf[0] = CI_PREDICTOR_2;
+	opt_buf[1] = CILEN_PREDICTOR_2;
+	if (ccp_test(pcb, opt_buf, CILEN_PREDICTOR_2, 0) <= 0)
+	    go->predictor_2 = 0;
+    }
+#endif /* PREDICTOR_SUPPORT */
+}
+
+/*
+ * ccp_cilen - Return total length of our configuration info.
+ */
+static int ccp_cilen(fsm *f) {
+    ppp_pcb *pcb = f->pcb;
+    ccp_options *go = &pcb->ccp_gotoptions;
+
+    return 0
+#if BSDCOMPRESS_SUPPORT
+	+ (go->bsd_compress? CILEN_BSD_COMPRESS: 0)
+#endif /* BSDCOMPRESS_SUPPORT */
+#if DEFLATE_SUPPORT
+	+ (go->deflate && go->deflate_correct? CILEN_DEFLATE: 0)
+	+ (go->deflate && go->deflate_draft? CILEN_DEFLATE: 0)
+#endif /* DEFLATE_SUPPORT */
+#if PREDICTOR_SUPPORT
+	+ (go->predictor_1? CILEN_PREDICTOR_1: 0)
+	+ (go->predictor_2? CILEN_PREDICTOR_2: 0)
+#endif /* PREDICTOR_SUPPORT */
+#if MPPE_SUPPORT
+	+ (go->mppe? CILEN_MPPE: 0)
+#endif /* MPPE_SUPPORT */
+	;
+}
+
+/*
+ * ccp_addci - put our requests in a packet.
+ */
+static void ccp_addci(fsm *f, u_char *p, int *lenp) {
+    ppp_pcb *pcb = f->pcb;
+    ccp_options *go = &pcb->ccp_gotoptions;
+    u_char *p0 = p;
+
+    /*
+     * Add the compression types that we can receive, in decreasing
+     * preference order.
+     */
+#if MPPE_SUPPORT
+    if (go->mppe) {
+	p[0] = CI_MPPE;
+	p[1] = CILEN_MPPE;
+	MPPE_OPTS_TO_CI(go->mppe, &p[2]);
+	mppe_init(pcb, &pcb->mppe_decomp, go->mppe);
+	p += CILEN_MPPE;
+    }
+#endif /* MPPE_SUPPORT */
+#if DEFLATE_SUPPORT
+    if (go->deflate) {
+	if (go->deflate_correct) {
+	    p[0] = CI_DEFLATE;
+	    p[1] = CILEN_DEFLATE;
+	    p[2] = DEFLATE_MAKE_OPT(go->deflate_size);
+	    p[3] = DEFLATE_CHK_SEQUENCE;
+	    p += CILEN_DEFLATE;
+	}
+	if (go->deflate_draft) {
+	    p[0] = CI_DEFLATE_DRAFT;
+	    p[1] = CILEN_DEFLATE;
+	    p[2] = p[2 - CILEN_DEFLATE];
+	    p[3] = DEFLATE_CHK_SEQUENCE;
+	    p += CILEN_DEFLATE;
+	}
+    }
+#endif /* DEFLATE_SUPPORT */
+#if BSDCOMPRESS_SUPPORT
+    if (go->bsd_compress) {
+	p[0] = CI_BSD_COMPRESS;
+	p[1] = CILEN_BSD_COMPRESS;
+	p[2] = BSD_MAKE_OPT(BSD_CURRENT_VERSION, go->bsd_bits);
+	p += CILEN_BSD_COMPRESS;
+    }
+#endif /* BSDCOMPRESS_SUPPORT */
+#if PREDICTOR_SUPPORT
+    /* XXX Should Predictor 2 be preferable to Predictor 1? */
+    if (go->predictor_1) {
+	p[0] = CI_PREDICTOR_1;
+	p[1] = CILEN_PREDICTOR_1;
+	p += CILEN_PREDICTOR_1;
+    }
+    if (go->predictor_2) {
+	p[0] = CI_PREDICTOR_2;
+	p[1] = CILEN_PREDICTOR_2;
+	p += CILEN_PREDICTOR_2;
+    }
+#endif /* PREDICTOR_SUPPORT */
+
+    go->method = (p > p0)? p0[0]: 0;
+
+    *lenp = p - p0;
+}
+
+/*
+ * ccp_ackci - process a received configure-ack, and return
+ * 1 iff the packet was OK.
+ */
+static int ccp_ackci(fsm *f, u_char *p, int len) {
+    ppp_pcb *pcb = f->pcb;
+    ccp_options *go = &pcb->ccp_gotoptions;
+#if BSDCOMPRESS_SUPPORT || PREDICTOR_SUPPORT
+    u_char *p0 = p;
+#endif /* BSDCOMPRESS_SUPPORT || PREDICTOR_SUPPORT */
+
+#if MPPE_SUPPORT
+    if (go->mppe) {
+	u_char opt_buf[CILEN_MPPE];
+
+	opt_buf[0] = CI_MPPE;
+	opt_buf[1] = CILEN_MPPE;
+	MPPE_OPTS_TO_CI(go->mppe, &opt_buf[2]);
+	if (len < CILEN_MPPE || memcmp(opt_buf, p, CILEN_MPPE))
+	    return 0;
+	p += CILEN_MPPE;
+	len -= CILEN_MPPE;
+	/* XXX Cope with first/fast ack */
+	if (len == 0)
+	    return 1;
+    }
+#endif /* MPPE_SUPPORT */
+#if DEFLATE_SUPPORT
+    if (go->deflate) {
+	if (len < CILEN_DEFLATE
+	    || p[0] != (go->deflate_correct? CI_DEFLATE: CI_DEFLATE_DRAFT)
+	    || p[1] != CILEN_DEFLATE
+	    || p[2] != DEFLATE_MAKE_OPT(go->deflate_size)
+	    || p[3] != DEFLATE_CHK_SEQUENCE)
+	    return 0;
+	p += CILEN_DEFLATE;
+	len -= CILEN_DEFLATE;
+	/* XXX Cope with first/fast ack */
+	if (len == 0)
+	    return 1;
+	if (go->deflate_correct && go->deflate_draft) {
+	    if (len < CILEN_DEFLATE
+		|| p[0] != CI_DEFLATE_DRAFT
+		|| p[1] != CILEN_DEFLATE
+		|| p[2] != DEFLATE_MAKE_OPT(go->deflate_size)
+		|| p[3] != DEFLATE_CHK_SEQUENCE)
+		return 0;
+	    p += CILEN_DEFLATE;
+	    len -= CILEN_DEFLATE;
+	}
+    }
+#endif /* DEFLATE_SUPPORT */
+#if BSDCOMPRESS_SUPPORT
+    if (go->bsd_compress) {
+	if (len < CILEN_BSD_COMPRESS
+	    || p[0] != CI_BSD_COMPRESS || p[1] != CILEN_BSD_COMPRESS
+	    || p[2] != BSD_MAKE_OPT(BSD_CURRENT_VERSION, go->bsd_bits))
+	    return 0;
+	p += CILEN_BSD_COMPRESS;
+	len -= CILEN_BSD_COMPRESS;
+	/* XXX Cope with first/fast ack */
+	if (p == p0 && len == 0)
+	    return 1;
+    }
+#endif /* BSDCOMPRESS_SUPPORT */
+#if PREDICTOR_SUPPORT
+    if (go->predictor_1) {
+	if (len < CILEN_PREDICTOR_1
+	    || p[0] != CI_PREDICTOR_1 || p[1] != CILEN_PREDICTOR_1)
+	    return 0;
+	p += CILEN_PREDICTOR_1;
+	len -= CILEN_PREDICTOR_1;
+	/* XXX Cope with first/fast ack */
+	if (p == p0 && len == 0)
+	    return 1;
+    }
+    if (go->predictor_2) {
+	if (len < CILEN_PREDICTOR_2
+	    || p[0] != CI_PREDICTOR_2 || p[1] != CILEN_PREDICTOR_2)
+	    return 0;
+	p += CILEN_PREDICTOR_2;
+	len -= CILEN_PREDICTOR_2;
+	/* XXX Cope with first/fast ack */
+	if (p == p0 && len == 0)
+	    return 1;
+    }
+#endif /* PREDICTOR_SUPPORT */
+
+    if (len != 0)
+	return 0;
+    return 1;
+}
+
+/*
+ * ccp_nakci - process received configure-nak.
+ * Returns 1 iff the nak was OK.
+ */
+static int ccp_nakci(fsm *f, u_char *p, int len, int treat_as_reject) {
+    ppp_pcb *pcb = f->pcb;
+    ccp_options *go = &pcb->ccp_gotoptions;
+    ccp_options no;		/* options we've seen already */
+    ccp_options try_;		/* options to ask for next time */
+    LWIP_UNUSED_ARG(treat_as_reject);
+#if !MPPE_SUPPORT && !DEFLATE_SUPPORT && !BSDCOMPRESS_SUPPORT
+    LWIP_UNUSED_ARG(p);
+    LWIP_UNUSED_ARG(len);
+#endif /* !MPPE_SUPPORT && !DEFLATE_SUPPORT && !BSDCOMPRESS_SUPPORT */
+
+    memset(&no, 0, sizeof(no));
+    try_ = *go;
+
+#if MPPE_SUPPORT
+    if (go->mppe && len >= CILEN_MPPE
+	&& p[0] == CI_MPPE && p[1] == CILEN_MPPE) {
+	no.mppe = 1;
+	/*
+	 * Peer wants us to use a different strength or other setting.
+	 * Fail if we aren't willing to use his suggestion.
+	 */
+	MPPE_CI_TO_OPTS(&p[2], try_.mppe);
+	if ((try_.mppe & MPPE_OPT_STATEFUL) && pcb->settings.refuse_mppe_stateful) {
+	    ppp_error("Refusing MPPE stateful mode offered by peer");
+	    try_.mppe = 0;
+	} else if (((go->mppe | MPPE_OPT_STATEFUL) & try_.mppe) != try_.mppe) {
+	    /* Peer must have set options we didn't request (suggest) */
+	    try_.mppe = 0;
+	}
+
+	if (!try_.mppe) {
+	    ppp_error("MPPE required but peer negotiation failed");
+	    lcp_close(pcb, "MPPE required but peer negotiation failed");
+	}
+    }
+#endif /* MPPE_SUPPORT */
+#if DEFLATE_SUPPORT
+    if (go->deflate && len >= CILEN_DEFLATE
+	&& p[0] == (go->deflate_correct? CI_DEFLATE: CI_DEFLATE_DRAFT)
+	&& p[1] == CILEN_DEFLATE) {
+	no.deflate = 1;
+	/*
+	 * Peer wants us to use a different code size or something.
+	 * Stop asking for Deflate if we don't understand his suggestion.
+	 */
+	if (DEFLATE_METHOD(p[2]) != DEFLATE_METHOD_VAL
+	    || DEFLATE_SIZE(p[2]) < DEFLATE_MIN_WORKS
+	    || p[3] != DEFLATE_CHK_SEQUENCE)
+	    try_.deflate = 0;
+	else if (DEFLATE_SIZE(p[2]) < go->deflate_size)
+	    try_.deflate_size = DEFLATE_SIZE(p[2]);
+	p += CILEN_DEFLATE;
+	len -= CILEN_DEFLATE;
+	if (go->deflate_correct && go->deflate_draft
+	    && len >= CILEN_DEFLATE && p[0] == CI_DEFLATE_DRAFT
+	    && p[1] == CILEN_DEFLATE) {
+	    p += CILEN_DEFLATE;
+	    len -= CILEN_DEFLATE;
+	}
+    }
+#endif /* DEFLATE_SUPPORT */
+#if BSDCOMPRESS_SUPPORT
+    if (go->bsd_compress && len >= CILEN_BSD_COMPRESS
+	&& p[0] == CI_BSD_COMPRESS && p[1] == CILEN_BSD_COMPRESS) {
+	no.bsd_compress = 1;
+	/*
+	 * Peer wants us to use a different number of bits
+	 * or a different version.
+	 */
+	if (BSD_VERSION(p[2]) != BSD_CURRENT_VERSION)
+	    try_.bsd_compress = 0;
+	else if (BSD_NBITS(p[2]) < go->bsd_bits)
+	    try_.bsd_bits = BSD_NBITS(p[2]);
+	p += CILEN_BSD_COMPRESS;
+	len -= CILEN_BSD_COMPRESS;
+    }
+#endif /* BSDCOMPRESS_SUPPORT */
+
+    /*
+     * Predictor-1 and 2 have no options, so they can't be Naked.
+     *
+     * There may be remaining options but we ignore them.
+     */
+
+    if (f->state != PPP_FSM_OPENED)
+	*go = try_;
+    return 1;
+}
+
+/*
+ * ccp_rejci - reject some of our suggested compression methods.
+ */
+static int ccp_rejci(fsm *f, u_char *p, int len) {
+    ppp_pcb *pcb = f->pcb;
+    ccp_options *go = &pcb->ccp_gotoptions;
+    ccp_options try_;		/* options to request next time */
+
+    try_ = *go;
+
+    /*
+     * Cope with empty configure-rejects by ceasing to send
+     * configure-requests.
+     */
+    if (len == 0 && pcb->ccp_all_rejected)
+	return -1;
+
+#if MPPE_SUPPORT
+    if (go->mppe && len >= CILEN_MPPE
+	&& p[0] == CI_MPPE && p[1] == CILEN_MPPE) {
+	ppp_error("MPPE required but peer refused");
+	lcp_close(pcb, "MPPE required but peer refused");
+	p += CILEN_MPPE;
+	len -= CILEN_MPPE;
+    }
+#endif /* MPPE_SUPPORT */
+#if DEFLATE_SUPPORT
+    if (go->deflate_correct && len >= CILEN_DEFLATE
+	&& p[0] == CI_DEFLATE && p[1] == CILEN_DEFLATE) {
+	if (p[2] != DEFLATE_MAKE_OPT(go->deflate_size)
+	    || p[3] != DEFLATE_CHK_SEQUENCE)
+	    return 0;		/* Rej is bad */
+	try_.deflate_correct = 0;
+	p += CILEN_DEFLATE;
+	len -= CILEN_DEFLATE;
+    }
+    if (go->deflate_draft && len >= CILEN_DEFLATE
+	&& p[0] == CI_DEFLATE_DRAFT && p[1] == CILEN_DEFLATE) {
+	if (p[2] != DEFLATE_MAKE_OPT(go->deflate_size)
+	    || p[3] != DEFLATE_CHK_SEQUENCE)
+	    return 0;		/* Rej is bad */
+	try_.deflate_draft = 0;
+	p += CILEN_DEFLATE;
+	len -= CILEN_DEFLATE;
+    }
+    if (!try_.deflate_correct && !try_.deflate_draft)
+	try_.deflate = 0;
+#endif /* DEFLATE_SUPPORT */
+#if BSDCOMPRESS_SUPPORT
+    if (go->bsd_compress && len >= CILEN_BSD_COMPRESS
+	&& p[0] == CI_BSD_COMPRESS && p[1] == CILEN_BSD_COMPRESS) {
+	if (p[2] != BSD_MAKE_OPT(BSD_CURRENT_VERSION, go->bsd_bits))
+	    return 0;
+	try_.bsd_compress = 0;
+	p += CILEN_BSD_COMPRESS;
+	len -= CILEN_BSD_COMPRESS;
+    }
+#endif /* BSDCOMPRESS_SUPPORT */
+#if PREDICTOR_SUPPORT
+    if (go->predictor_1 && len >= CILEN_PREDICTOR_1
+	&& p[0] == CI_PREDICTOR_1 && p[1] == CILEN_PREDICTOR_1) {
+	try_.predictor_1 = 0;
+	p += CILEN_PREDICTOR_1;
+	len -= CILEN_PREDICTOR_1;
+    }
+    if (go->predictor_2 && len >= CILEN_PREDICTOR_2
+	&& p[0] == CI_PREDICTOR_2 && p[1] == CILEN_PREDICTOR_2) {
+	try_.predictor_2 = 0;
+	p += CILEN_PREDICTOR_2;
+	len -= CILEN_PREDICTOR_2;
+    }
+#endif /* PREDICTOR_SUPPORT */
+
+    if (len != 0)
+	return 0;
+
+    if (f->state != PPP_FSM_OPENED)
+	*go = try_;
+
+    return 1;
+}
+
+/*
+ * ccp_reqci - processed a received configure-request.
+ * Returns CONFACK, CONFNAK or CONFREJ and the packet modified
+ * appropriately.
+ */
+static int ccp_reqci(fsm *f, u_char *p, int *lenp, int dont_nak) {
+    ppp_pcb *pcb = f->pcb;
+    ccp_options *ho = &pcb->ccp_hisoptions;
+    ccp_options *ao = &pcb->ccp_allowoptions;
+    int ret, newret;
+#if DEFLATE_SUPPORT || BSDCOMPRESS_SUPPORT
+    int res;
+    int nb;
+#endif /* DEFLATE_SUPPORT || BSDCOMPRESS_SUPPORT */
+    u_char *p0, *retp;
+    int len, clen, type;
+#if MPPE_SUPPORT
+    u8_t rej_for_ci_mppe = 1;	/* Are we rejecting based on a bad/missing */
+				/* CI_MPPE, or due to other options?       */
+#endif /* MPPE_SUPPORT */
+
+    ret = CONFACK;
+    retp = p0 = p;
+    len = *lenp;
+
+    memset(ho, 0, sizeof(ccp_options));
+    ho->method = (len > 0)? p[0]: 0;
+
+    while (len > 0) {
+	newret = CONFACK;
+	if (len < 2 || p[1] < 2 || p[1] > len) {
+	    /* length is bad */
+	    clen = len;
+	    newret = CONFREJ;
+
+	} else {
+	    type = p[0];
+	    clen = p[1];
+
+	    switch (type) {
+#if MPPE_SUPPORT
+	    case CI_MPPE:
+		if (!ao->mppe || clen != CILEN_MPPE) {
+		    newret = CONFREJ;
+		    break;
+		}
+		MPPE_CI_TO_OPTS(&p[2], ho->mppe);
+
+		/* Nak if anything unsupported or unknown are set. */
+		if (ho->mppe & MPPE_OPT_UNSUPPORTED) {
+		    newret = CONFNAK;
+		    ho->mppe &= ~MPPE_OPT_UNSUPPORTED;
+		}
+		if (ho->mppe & MPPE_OPT_UNKNOWN) {
+		    newret = CONFNAK;
+		    ho->mppe &= ~MPPE_OPT_UNKNOWN;
+		}
+
+		/* Check state opt */
+		if (ho->mppe & MPPE_OPT_STATEFUL) {
+		    /*
+		     * We can Nak and request stateless, but it's a
+		     * lot easier to just assume the peer will request
+		     * it if he can do it; stateful mode is bad over
+		     * the Internet -- which is where we expect MPPE.
+		     */
+		   if (pcb->settings.refuse_mppe_stateful) {
+			ppp_error("Refusing MPPE stateful mode offered by peer");
+			newret = CONFREJ;
+			break;
+		    }
+		}
+
+		/* Find out which of {S,L} are set. */
+		if ((ho->mppe & MPPE_OPT_128)
+		     && (ho->mppe & MPPE_OPT_40)) {
+		    /* Both are set, negotiate the strongest. */
+		    newret = CONFNAK;
+		    if (ao->mppe & MPPE_OPT_128)
+			ho->mppe &= ~MPPE_OPT_40;
+		    else if (ao->mppe & MPPE_OPT_40)
+			ho->mppe &= ~MPPE_OPT_128;
+		    else {
+			newret = CONFREJ;
+			break;
+		    }
+		} else if (ho->mppe & MPPE_OPT_128) {
+		    if (!(ao->mppe & MPPE_OPT_128)) {
+			newret = CONFREJ;
+			break;
+		    }
+		} else if (ho->mppe & MPPE_OPT_40) {
+		    if (!(ao->mppe & MPPE_OPT_40)) {
+			newret = CONFREJ;
+			break;
+		    }
+		} else {
+		    /* Neither are set. */
+		    /* We cannot accept this.  */
+		    newret = CONFNAK;
+		    /* Give the peer our idea of what can be used,
+		       so it can choose and confirm */
+		    ho->mppe = ao->mppe;
+		}
+
+		/* rebuild the opts */
+		MPPE_OPTS_TO_CI(ho->mppe, &p[2]);
+		if (newret == CONFACK) {
+		    int mtu;
+
+		    mppe_init(pcb, &pcb->mppe_comp, ho->mppe);
+		    /*
+		     * We need to decrease the interface MTU by MPPE_PAD
+		     * because MPPE frames **grow**.  The kernel [must]
+		     * allocate MPPE_PAD extra bytes in xmit buffers.
+		     */
+		    mtu = netif_get_mtu(pcb);
+		    if (mtu)
+			netif_set_mtu(pcb, mtu - MPPE_PAD);
+		    else
+			newret = CONFREJ;
+		}
+
+		/*
+		 * We have accepted MPPE or are willing to negotiate
+		 * MPPE parameters.  A CONFREJ is due to subsequent
+		 * (non-MPPE) processing.
+		 */
+		rej_for_ci_mppe = 0;
+		break;
+#endif /* MPPE_SUPPORT */
+#if DEFLATE_SUPPORT
+	    case CI_DEFLATE:
+	    case CI_DEFLATE_DRAFT:
+		if (!ao->deflate || clen != CILEN_DEFLATE
+		    || (!ao->deflate_correct && type == CI_DEFLATE)
+		    || (!ao->deflate_draft && type == CI_DEFLATE_DRAFT)) {
+		    newret = CONFREJ;
+		    break;
+		}
+
+		ho->deflate = 1;
+		ho->deflate_size = nb = DEFLATE_SIZE(p[2]);
+		if (DEFLATE_METHOD(p[2]) != DEFLATE_METHOD_VAL
+		    || p[3] != DEFLATE_CHK_SEQUENCE
+		    || nb > ao->deflate_size || nb < DEFLATE_MIN_WORKS) {
+		    newret = CONFNAK;
+		    if (!dont_nak) {
+			p[2] = DEFLATE_MAKE_OPT(ao->deflate_size);
+			p[3] = DEFLATE_CHK_SEQUENCE;
+			/* fall through to test this #bits below */
+		    } else
+			break;
+		}
+
+		/*
+		 * Check whether we can do Deflate with the window
+		 * size they want.  If the window is too big, reduce
+		 * it until the kernel can cope and nak with that.
+		 * We only check this for the first option.
+		 */
+		if (p == p0) {
+		    for (;;) {
+			res = ccp_test(pcb, p, CILEN_DEFLATE, 1);
+			if (res > 0)
+			    break;		/* it's OK now */
+			if (res < 0 || nb == DEFLATE_MIN_WORKS || dont_nak) {
+			    newret = CONFREJ;
+			    p[2] = DEFLATE_MAKE_OPT(ho->deflate_size);
+			    break;
+			}
+			newret = CONFNAK;
+			--nb;
+			p[2] = DEFLATE_MAKE_OPT(nb);
+		    }
+		}
+		break;
+#endif /* DEFLATE_SUPPORT */
+#if BSDCOMPRESS_SUPPORT
+	    case CI_BSD_COMPRESS:
+		if (!ao->bsd_compress || clen != CILEN_BSD_COMPRESS) {
+		    newret = CONFREJ;
+		    break;
+		}
+
+		ho->bsd_compress = 1;
+		ho->bsd_bits = nb = BSD_NBITS(p[2]);
+		if (BSD_VERSION(p[2]) != BSD_CURRENT_VERSION
+		    || nb > ao->bsd_bits || nb < BSD_MIN_BITS) {
+		    newret = CONFNAK;
+		    if (!dont_nak) {
+			p[2] = BSD_MAKE_OPT(BSD_CURRENT_VERSION, ao->bsd_bits);
+			/* fall through to test this #bits below */
+		    } else
+			break;
+		}
+
+		/*
+		 * Check whether we can do BSD-Compress with the code
+		 * size they want.  If the code size is too big, reduce
+		 * it until the kernel can cope and nak with that.
+		 * We only check this for the first option.
+		 */
+		if (p == p0) {
+		    for (;;) {
+			res = ccp_test(pcb, p, CILEN_BSD_COMPRESS, 1);
+			if (res > 0)
+			    break;
+			if (res < 0 || nb == BSD_MIN_BITS || dont_nak) {
+			    newret = CONFREJ;
+			    p[2] = BSD_MAKE_OPT(BSD_CURRENT_VERSION,
+						ho->bsd_bits);
+			    break;
+			}
+			newret = CONFNAK;
+			--nb;
+			p[2] = BSD_MAKE_OPT(BSD_CURRENT_VERSION, nb);
+		    }
+		}
+		break;
+#endif /* BSDCOMPRESS_SUPPORT */
+#if PREDICTOR_SUPPORT
+	    case CI_PREDICTOR_1:
+		if (!ao->predictor_1 || clen != CILEN_PREDICTOR_1) {
+		    newret = CONFREJ;
+		    break;
+		}
+
+		ho->predictor_1 = 1;
+		if (p == p0
+		    && ccp_test(pcb, p, CILEN_PREDICTOR_1, 1) <= 0) {
+		    newret = CONFREJ;
+		}
+		break;
+
+	    case CI_PREDICTOR_2:
+		if (!ao->predictor_2 || clen != CILEN_PREDICTOR_2) {
+		    newret = CONFREJ;
+		    break;
+		}
+
+		ho->predictor_2 = 1;
+		if (p == p0
+		    && ccp_test(pcb, p, CILEN_PREDICTOR_2, 1) <= 0) {
+		    newret = CONFREJ;
+		}
+		break;
+#endif /* PREDICTOR_SUPPORT */
+
+	    default:
+		newret = CONFREJ;
+	    }
+	}
+
+	if (newret == CONFNAK && dont_nak)
+	    newret = CONFREJ;
+	if (!(newret == CONFACK || (newret == CONFNAK && ret == CONFREJ))) {
+	    /* we're returning this option */
+	    if (newret == CONFREJ && ret == CONFNAK)
+		retp = p0;
+	    ret = newret;
+	    if (p != retp)
+		MEMCPY(retp, p, clen);
+	    retp += clen;
+	}
+
+	p += clen;
+	len -= clen;
+    }
+
+    if (ret != CONFACK) {
+	if (ret == CONFREJ && *lenp == retp - p0)
+	    pcb->ccp_all_rejected = 1;
+	else
+	    *lenp = retp - p0;
+    }
+#if MPPE_SUPPORT
+    if (ret == CONFREJ && ao->mppe && rej_for_ci_mppe) {
+	ppp_error("MPPE required but peer negotiation failed");
+	lcp_close(pcb, "MPPE required but peer negotiation failed");
+    }
+#endif /* MPPE_SUPPORT */
+    return ret;
+}
+
+/*
+ * Make a string name for a compression method (or 2).
+ */
+static const char *method_name(ccp_options *opt, ccp_options *opt2) {
+    static char result[64];
+#if !DEFLATE_SUPPORT && !BSDCOMPRESS_SUPPORT
+    LWIP_UNUSED_ARG(opt2);
+#endif /* !DEFLATE_SUPPORT && !BSDCOMPRESS_SUPPORT */
+
+    if (!ccp_anycompress(opt))
+	return "(none)";
+    switch (opt->method) {
+#if MPPE_SUPPORT
+    case CI_MPPE:
+    {
+	char *p = result;
+	char *q = result + sizeof(result); /* 1 past result */
+
+	ppp_slprintf(p, q - p, "MPPE ");
+	p += 5;
+	if (opt->mppe & MPPE_OPT_128) {
+	    ppp_slprintf(p, q - p, "128-bit ");
+	    p += 8;
+	}
+	if (opt->mppe & MPPE_OPT_40) {
+	    ppp_slprintf(p, q - p, "40-bit ");
+	    p += 7;
+	}
+	if (opt->mppe & MPPE_OPT_STATEFUL)
+	    ppp_slprintf(p, q - p, "stateful");
+	else
+	    ppp_slprintf(p, q - p, "stateless");
+
+	break;
+    }
+#endif /* MPPE_SUPPORT */
+#if DEFLATE_SUPPORT
+    case CI_DEFLATE:
+    case CI_DEFLATE_DRAFT:
+	if (opt2 != NULL && opt2->deflate_size != opt->deflate_size)
+	    ppp_slprintf(result, sizeof(result), "Deflate%s (%d/%d)",
+		     (opt->method == CI_DEFLATE_DRAFT? "(old#)": ""),
+		     opt->deflate_size, opt2->deflate_size);
+	else
+	    ppp_slprintf(result, sizeof(result), "Deflate%s (%d)",
+		     (opt->method == CI_DEFLATE_DRAFT? "(old#)": ""),
+		     opt->deflate_size);
+	break;
+#endif /* DEFLATE_SUPPORT */
+#if BSDCOMPRESS_SUPPORT
+    case CI_BSD_COMPRESS:
+	if (opt2 != NULL && opt2->bsd_bits != opt->bsd_bits)
+	    ppp_slprintf(result, sizeof(result), "BSD-Compress (%d/%d)",
+		     opt->bsd_bits, opt2->bsd_bits);
+	else
+	    ppp_slprintf(result, sizeof(result), "BSD-Compress (%d)",
+		     opt->bsd_bits);
+	break;
+#endif /* BSDCOMPRESS_SUPPORT */
+#if PREDICTOR_SUPPORT
+    case CI_PREDICTOR_1:
+	return "Predictor 1";
+    case CI_PREDICTOR_2:
+	return "Predictor 2";
+#endif /* PREDICTOR_SUPPORT */
+    default:
+	ppp_slprintf(result, sizeof(result), "Method %d", opt->method);
+    }
+    return result;
+}
+
+/*
+ * CCP has come up - inform the kernel driver and log a message.
+ */
+static void ccp_up(fsm *f) {
+    ppp_pcb *pcb = f->pcb;
+    ccp_options *go = &pcb->ccp_gotoptions;
+    ccp_options *ho = &pcb->ccp_hisoptions;
+    char method1[64];
+
+    ccp_set(pcb, 1, 1, go->method, ho->method);
+    if (ccp_anycompress(go)) {
+	if (ccp_anycompress(ho)) {
+	    if (go->method == ho->method) {
+		ppp_notice("%s compression enabled", method_name(go, ho));
+	    } else {
+		ppp_strlcpy(method1, method_name(go, NULL), sizeof(method1));
+		ppp_notice("%s / %s compression enabled",
+		       method1, method_name(ho, NULL));
+	    }
+	} else
+	    ppp_notice("%s receive compression enabled", method_name(go, NULL));
+    } else if (ccp_anycompress(ho))
+	ppp_notice("%s transmit compression enabled", method_name(ho, NULL));
+#if MPPE_SUPPORT
+    if (go->mppe) {
+	continue_networks(pcb);		/* Bring up IP et al */
+    }
+#endif /* MPPE_SUPPORT */
+}
+
+/*
+ * CCP has gone down - inform the kernel driver.
+ */
+static void ccp_down(fsm *f) {
+    ppp_pcb *pcb = f->pcb;
+#if MPPE_SUPPORT
+    ccp_options *go = &pcb->ccp_gotoptions;
+#endif /* MPPE_SUPPORT */
+
+    if (pcb->ccp_localstate & RACK_PENDING)
+	UNTIMEOUT(ccp_rack_timeout, f);
+    pcb->ccp_localstate = 0;
+    ccp_set(pcb, 1, 0, 0, 0);
+#if MPPE_SUPPORT
+    if (go->mppe) {
+	go->mppe = 0;
+	if (pcb->lcp_fsm.state == PPP_FSM_OPENED) {
+	    /* If LCP is not already going down, make sure it does. */
+	    ppp_error("MPPE disabled");
+	    lcp_close(pcb, "MPPE disabled");
+	}
+    }
+#endif /* MPPE_SUPPORT */
+}
+
+#if PRINTPKT_SUPPORT
+/*
+ * Print the contents of a CCP packet.
+ */
+static const char* const ccp_codenames[] = {
+    "ConfReq", "ConfAck", "ConfNak", "ConfRej",
+    "TermReq", "TermAck", "CodeRej",
+    NULL, NULL, NULL, NULL, NULL, NULL,
+    "ResetReq", "ResetAck",
+};
+
+static int ccp_printpkt(const u_char *p, int plen, void (*printer) (void *, const char *, ...), void *arg) {
+    const u_char *p0, *optend;
+    int code, id, len;
+    int optlen;
+
+    p0 = p;
+    if (plen < HEADERLEN)
+	return 0;
+    code = p[0];
+    id = p[1];
+    len = (p[2] << 8) + p[3];
+    if (len < HEADERLEN || len > plen)
+	return 0;
+
+    if (code >= 1 && code <= (int)LWIP_ARRAYSIZE(ccp_codenames) && ccp_codenames[code-1] != NULL)
+	printer(arg, " %s", ccp_codenames[code-1]);
+    else
+	printer(arg, " code=0x%x", code);
+    printer(arg, " id=0x%x", id);
+    len -= HEADERLEN;
+    p += HEADERLEN;
+
+    switch (code) {
+    case CONFREQ:
+    case CONFACK:
+    case CONFNAK:
+    case CONFREJ:
+	/* print list of possible compression methods */
+	while (len >= 2) {
+	    code = p[0];
+	    optlen = p[1];
+	    if (optlen < 2 || optlen > len)
+		break;
+	    printer(arg, " <");
+	    len -= optlen;
+	    optend = p + optlen;
+	    switch (code) {
+#if MPPE_SUPPORT
+	    case CI_MPPE:
+		if (optlen >= CILEN_MPPE) {
+		    u_char mppe_opts;
+
+		    MPPE_CI_TO_OPTS(&p[2], mppe_opts);
+		    printer(arg, "mppe %s %s %s %s %s %s%s",
+			    (p[2] & MPPE_H_BIT)? "+H": "-H",
+			    (p[5] & MPPE_M_BIT)? "+M": "-M",
+			    (p[5] & MPPE_S_BIT)? "+S": "-S",
+			    (p[5] & MPPE_L_BIT)? "+L": "-L",
+			    (p[5] & MPPE_D_BIT)? "+D": "-D",
+			    (p[5] & MPPE_C_BIT)? "+C": "-C",
+			    (mppe_opts & MPPE_OPT_UNKNOWN)? " +U": "");
+		    if (mppe_opts & MPPE_OPT_UNKNOWN)
+			printer(arg, " (%.2x %.2x %.2x %.2x)",
+				p[2], p[3], p[4], p[5]);
+		    p += CILEN_MPPE;
+		}
+		break;
+#endif /* MPPE_SUPPORT */
+#if DEFLATE_SUPPORT
+	    case CI_DEFLATE:
+	    case CI_DEFLATE_DRAFT:
+		if (optlen >= CILEN_DEFLATE) {
+		    printer(arg, "deflate%s %d",
+			    (code == CI_DEFLATE_DRAFT? "(old#)": ""),
+			    DEFLATE_SIZE(p[2]));
+		    if (DEFLATE_METHOD(p[2]) != DEFLATE_METHOD_VAL)
+			printer(arg, " method %d", DEFLATE_METHOD(p[2]));
+		    if (p[3] != DEFLATE_CHK_SEQUENCE)
+			printer(arg, " check %d", p[3]);
+		    p += CILEN_DEFLATE;
+		}
+		break;
+#endif /* DEFLATE_SUPPORT */
+#if BSDCOMPRESS_SUPPORT
+	    case CI_BSD_COMPRESS:
+		if (optlen >= CILEN_BSD_COMPRESS) {
+		    printer(arg, "bsd v%d %d", BSD_VERSION(p[2]),
+			    BSD_NBITS(p[2]));
+		    p += CILEN_BSD_COMPRESS;
+		}
+		break;
+#endif /* BSDCOMPRESS_SUPPORT */
+#if PREDICTOR_SUPPORT
+	    case CI_PREDICTOR_1:
+		if (optlen >= CILEN_PREDICTOR_1) {
+		    printer(arg, "predictor 1");
+		    p += CILEN_PREDICTOR_1;
+		}
+		break;
+	    case CI_PREDICTOR_2:
+		if (optlen >= CILEN_PREDICTOR_2) {
+		    printer(arg, "predictor 2");
+		    p += CILEN_PREDICTOR_2;
+		}
+		break;
+#endif /* PREDICTOR_SUPPORT */
+	    default:
+                break;
+	    }
+	    while (p < optend)
+		printer(arg, " %.2x", *p++);
+	    printer(arg, ">");
+	}
+	break;
+
+    case TERMACK:
+    case TERMREQ:
+	if (len > 0 && *p >= ' ' && *p < 0x7f) {
+	    ppp_print_string(p, len, printer, arg);
+	    p += len;
+	    len = 0;
+	}
+	break;
+    default:
+        break;
+    }
+
+    /* dump out the rest of the packet in hex */
+    while (--len >= 0)
+	printer(arg, " %.2x", *p++);
+
+    return p - p0;
+}
+#endif /* PRINTPKT_SUPPORT */
+
+#if PPP_DATAINPUT
+/*
+ * We have received a packet that the decompressor failed to
+ * decompress.  Here we would expect to issue a reset-request, but
+ * Motorola has a patent on resetting the compressor as a result of
+ * detecting an error in the decompressed data after decompression.
+ * (See US patent 5,130,993; international patent publication number
+ * WO 91/10289; Australian patent 73296/91.)
+ *
+ * So we ask the kernel whether the error was detected after
+ * decompression; if it was, we take CCP down, thus disabling
+ * compression :-(, otherwise we issue the reset-request.
+ */
+static void ccp_datainput(ppp_pcb *pcb, u_char *pkt, int len) {
+    fsm *f;
+#if MPPE_SUPPORT
+    ccp_options *go = &pcb->ccp_gotoptions;
+#endif /* MPPE_SUPPORT */
+    LWIP_UNUSED_ARG(pkt);
+    LWIP_UNUSED_ARG(len);
+
+    f = &pcb->ccp_fsm;
+    if (f->state == PPP_FSM_OPENED) {
+	if (ccp_fatal_error(pcb)) {
+	    /*
+	     * Disable compression by taking CCP down.
+	     */
+	    ppp_error("Lost compression sync: disabling compression");
+	    ccp_close(pcb, "Lost compression sync");
+#if MPPE_SUPPORT
+	    /*
+	     * If we were doing MPPE, we must also take the link down.
+	     */
+	    if (go->mppe) {
+		ppp_error("Too many MPPE errors, closing LCP");
+		lcp_close(pcb, "Too many MPPE errors");
+	    }
+#endif /* MPPE_SUPPORT */
+	} else {
+	    /*
+	     * Send a reset-request to reset the peer's compressor.
+	     * We don't do that if we are still waiting for an
+	     * acknowledgement to a previous reset-request.
+	     */
+	    if (!(pcb->ccp_localstate & RACK_PENDING)) {
+		fsm_sdata(f, CCP_RESETREQ, f->reqid = ++f->id, NULL, 0);
+		TIMEOUT(ccp_rack_timeout, f, RACKTIMEOUT);
+		pcb->ccp_localstate |= RACK_PENDING;
+	    } else
+		pcb->ccp_localstate |= RREQ_REPEAT;
+	}
+    }
+}
+#endif /* PPP_DATAINPUT */
+
+/*
+ * We have received a packet that the decompressor failed to
+ * decompress. Issue a reset-request.
+ */
+void ccp_resetrequest(ppp_pcb *pcb) {
+    fsm *f = &pcb->ccp_fsm;
+
+    if (f->state != PPP_FSM_OPENED)
+	return;
+
+    /*
+     * Send a reset-request to reset the peer's compressor.
+     * We don't do that if we are still waiting for an
+     * acknowledgement to a previous reset-request.
+     */
+    if (!(pcb->ccp_localstate & RACK_PENDING)) {
+	fsm_sdata(f, CCP_RESETREQ, f->reqid = ++f->id, NULL, 0);
+	TIMEOUT(ccp_rack_timeout, f, RACKTIMEOUT);
+	pcb->ccp_localstate |= RACK_PENDING;
+    } else
+	pcb->ccp_localstate |= RREQ_REPEAT;
+}
+
+/*
+ * Timeout waiting for reset-ack.
+ */
+static void ccp_rack_timeout(void *arg) {
+    fsm *f = (fsm*)arg;
+    ppp_pcb *pcb = f->pcb;
+
+    if (f->state == PPP_FSM_OPENED && (pcb->ccp_localstate & RREQ_REPEAT)) {
+	fsm_sdata(f, CCP_RESETREQ, f->reqid, NULL, 0);
+	TIMEOUT(ccp_rack_timeout, f, RACKTIMEOUT);
+	pcb->ccp_localstate &= ~RREQ_REPEAT;
+    } else
+	pcb->ccp_localstate &= ~RACK_PENDING;
+}
+
+#endif /* PPP_SUPPORT && CCP_SUPPORT */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/netif/ppp/chap-md5.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/netif/ppp/chap-md5.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/netif/ppp/chap-md5.c	(revision 457)
@@ -0,0 +1,126 @@
+/*
+ * chap-md5.c - New CHAP/MD5 implementation.
+ *
+ * Copyright (c) 2003 Paul Mackerras. 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. The name(s) of the authors of this software must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission.
+ *
+ * 3. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by Paul Mackerras
+ *     <paulus@samba.org>".
+ *
+ * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO
+ * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
+ * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
+ * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
+ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include "netif/ppp/ppp_opts.h"
+#if PPP_SUPPORT && CHAP_SUPPORT  /* don't build if not configured for use in lwipopts.h */
+
+#if 0 /* UNUSED */
+#include <stdlib.h>
+#include <string.h>
+#endif /* UNUSED */
+
+#include "netif/ppp/ppp_impl.h"
+
+#include "netif/ppp/chap-new.h"
+#include "netif/ppp/chap-md5.h"
+#include "netif/ppp/magic.h"
+#include "netif/ppp/pppcrypt.h"
+
+#define MD5_HASH_SIZE		16
+#define MD5_MIN_CHALLENGE	17
+#define MD5_MAX_CHALLENGE	24
+#define MD5_MIN_MAX_POWER_OF_TWO_CHALLENGE     3   /* 2^3-1 = 7, 17+7 = 24 */
+
+#if PPP_SERVER
+static void chap_md5_generate_challenge(ppp_pcb *pcb, unsigned char *cp) {
+	int clen;
+	LWIP_UNUSED_ARG(pcb);
+
+	clen = MD5_MIN_CHALLENGE + magic_pow(MD5_MIN_MAX_POWER_OF_TWO_CHALLENGE);
+	*cp++ = clen;
+	magic_random_bytes(cp, clen);
+}
+
+static int chap_md5_verify_response(ppp_pcb *pcb, int id, const char *name,
+			 const unsigned char *secret, int secret_len,
+			 const unsigned char *challenge, const unsigned char *response,
+			 char *message, int message_space) {
+	lwip_md5_context ctx;
+	unsigned char idbyte = id;
+	unsigned char hash[MD5_HASH_SIZE];
+	int challenge_len, response_len;
+	LWIP_UNUSED_ARG(name);
+	LWIP_UNUSED_ARG(pcb);
+
+	challenge_len = *challenge++;
+	response_len = *response++;
+	if (response_len == MD5_HASH_SIZE) {
+		/* Generate hash of ID, secret, challenge */
+		lwip_md5_init(&ctx);
+		lwip_md5_starts(&ctx);
+		lwip_md5_update(&ctx, &idbyte, 1);
+		lwip_md5_update(&ctx, secret, secret_len);
+		lwip_md5_update(&ctx, challenge, challenge_len);
+		lwip_md5_finish(&ctx, hash);
+		lwip_md5_free(&ctx);
+
+		/* Test if our hash matches the peer's response */
+		if (memcmp(hash, response, MD5_HASH_SIZE) == 0) {
+			ppp_slprintf(message, message_space, "Access granted");
+			return 1;
+		}
+	}
+	ppp_slprintf(message, message_space, "Access denied");
+	return 0;
+}
+#endif /* PPP_SERVER */
+
+static void chap_md5_make_response(ppp_pcb *pcb, unsigned char *response, int id, const char *our_name,
+		       const unsigned char *challenge, const char *secret, int secret_len,
+		       unsigned char *private_) {
+	lwip_md5_context ctx;
+	unsigned char idbyte = id;
+	int challenge_len = *challenge++;
+	LWIP_UNUSED_ARG(our_name);
+	LWIP_UNUSED_ARG(private_);
+	LWIP_UNUSED_ARG(pcb);
+
+	lwip_md5_init(&ctx);
+	lwip_md5_starts(&ctx);
+	lwip_md5_update(&ctx, &idbyte, 1);
+	lwip_md5_update(&ctx, (const u_char *)secret, secret_len);
+	lwip_md5_update(&ctx, challenge, challenge_len);
+	lwip_md5_finish(&ctx, &response[1]);
+	lwip_md5_free(&ctx);
+	response[0] = MD5_HASH_SIZE;
+}
+
+const struct chap_digest_type md5_digest = {
+	CHAP_MD5,		/* code */
+#if PPP_SERVER
+	chap_md5_generate_challenge,
+	chap_md5_verify_response,
+#endif /* PPP_SERVER */
+	chap_md5_make_response,
+	NULL,			/* check_success */
+	NULL,			/* handle_failure */
+};
+
+#endif /* PPP_SUPPORT && CHAP_SUPPORT */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/netif/ppp/chap-new.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/netif/ppp/chap-new.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/netif/ppp/chap-new.c	(revision 457)
@@ -0,0 +1,677 @@
+/*
+ * chap-new.c - New CHAP implementation.
+ *
+ * Copyright (c) 2003 Paul Mackerras. 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. The name(s) of the authors of this software must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission.
+ *
+ * 3. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by Paul Mackerras
+ *     <paulus@samba.org>".
+ *
+ * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO
+ * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
+ * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
+ * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
+ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include "netif/ppp/ppp_opts.h"
+#if PPP_SUPPORT && CHAP_SUPPORT  /* don't build if not configured for use in lwipopts.h */
+
+#if 0 /* UNUSED */
+#include <stdlib.h>
+#include <string.h>
+#endif /* UNUSED */
+
+#include "netif/ppp/ppp_impl.h"
+
+#if 0 /* UNUSED */
+#include "session.h"
+#endif /* UNUSED */
+
+#include "netif/ppp/chap-new.h"
+#include "netif/ppp/chap-md5.h"
+#if MSCHAP_SUPPORT
+#include "netif/ppp/chap_ms.h"
+#endif
+#include "netif/ppp/magic.h"
+
+#if 0 /* UNUSED */
+/* Hook for a plugin to validate CHAP challenge */
+int (*chap_verify_hook)(const char *name, const char *ourname, int id,
+			const struct chap_digest_type *digest,
+			const unsigned char *challenge, const unsigned char *response,
+			char *message, int message_space) = NULL;
+#endif /* UNUSED */
+
+#if PPP_OPTIONS
+/*
+ * Command-line options.
+ */
+static option_t chap_option_list[] = {
+	{ "chap-restart", o_int, &chap_timeout_time,
+	  "Set timeout for CHAP", OPT_PRIO },
+	{ "chap-max-challenge", o_int, &pcb->settings.chap_max_transmits,
+	  "Set max #xmits for challenge", OPT_PRIO },
+	{ "chap-interval", o_int, &pcb->settings.chap_rechallenge_time,
+	  "Set interval for rechallenge", OPT_PRIO },
+	{ NULL }
+};
+#endif /* PPP_OPTIONS */
+
+
+/* Values for flags in chap_client_state and chap_server_state */
+#define LOWERUP			1
+#define AUTH_STARTED		2
+#define AUTH_DONE		4
+#define AUTH_FAILED		8
+#define TIMEOUT_PENDING		0x10
+#define CHALLENGE_VALID		0x20
+
+/*
+ * Prototypes.
+ */
+static void chap_init(ppp_pcb *pcb);
+static void chap_lowerup(ppp_pcb *pcb);
+static void chap_lowerdown(ppp_pcb *pcb);
+#if PPP_SERVER
+static void chap_timeout(void *arg);
+static void chap_generate_challenge(ppp_pcb *pcb);
+static void chap_handle_response(ppp_pcb *pcb, int code,
+		unsigned char *pkt, int len);
+static int chap_verify_response(ppp_pcb *pcb, const char *name, const char *ourname, int id,
+		const struct chap_digest_type *digest,
+		const unsigned char *challenge, const unsigned char *response,
+		char *message, int message_space);
+#endif /* PPP_SERVER */
+static void chap_respond(ppp_pcb *pcb, int id,
+		unsigned char *pkt, int len);
+static void chap_handle_status(ppp_pcb *pcb, int code, int id,
+		unsigned char *pkt, int len);
+static void chap_protrej(ppp_pcb *pcb);
+static void chap_input(ppp_pcb *pcb, unsigned char *pkt, int pktlen);
+#if PRINTPKT_SUPPORT
+static int chap_print_pkt(const unsigned char *p, int plen,
+		void (*printer) (void *, const char *, ...), void *arg);
+#endif /* PRINTPKT_SUPPORT */
+
+/* List of digest types that we know about */
+static const struct chap_digest_type* const chap_digests[] = {
+    &md5_digest,
+#if MSCHAP_SUPPORT
+    &chapms_digest,
+    &chapms2_digest,
+#endif /* MSCHAP_SUPPORT */
+    NULL
+};
+
+/*
+ * chap_init - reset to initial state.
+ */
+static void chap_init(ppp_pcb *pcb) {
+	LWIP_UNUSED_ARG(pcb);
+
+#if 0 /* Not necessary, everything is cleared in ppp_new() */
+	memset(&pcb->chap_client, 0, sizeof(chap_client_state));
+#if PPP_SERVER
+	memset(&pcb->chap_server, 0, sizeof(chap_server_state));
+#endif /* PPP_SERVER */
+#endif /* 0 */
+}
+
+/*
+ * chap_lowerup - we can start doing stuff now.
+ */
+static void chap_lowerup(ppp_pcb *pcb) {
+
+	pcb->chap_client.flags |= LOWERUP;
+#if PPP_SERVER
+	pcb->chap_server.flags |= LOWERUP;
+	if (pcb->chap_server.flags & AUTH_STARTED)
+		chap_timeout(pcb);
+#endif /* PPP_SERVER */
+}
+
+static void chap_lowerdown(ppp_pcb *pcb) {
+
+	pcb->chap_client.flags = 0;
+#if PPP_SERVER
+	if (pcb->chap_server.flags & TIMEOUT_PENDING)
+		UNTIMEOUT(chap_timeout, pcb);
+	pcb->chap_server.flags = 0;
+#endif /* PPP_SERVER */
+}
+
+#if PPP_SERVER
+/*
+ * chap_auth_peer - Start authenticating the peer.
+ * If the lower layer is already up, we start sending challenges,
+ * otherwise we wait for the lower layer to come up.
+ */
+void chap_auth_peer(ppp_pcb *pcb, const char *our_name, int digest_code) {
+	const struct chap_digest_type *dp;
+	int i;
+
+	if (pcb->chap_server.flags & AUTH_STARTED) {
+		ppp_error("CHAP: peer authentication already started!");
+		return;
+	}
+	for (i = 0; (dp = chap_digests[i]) != NULL; ++i)
+		if (dp->code == digest_code)
+			break;
+	if (dp == NULL)
+		ppp_fatal("CHAP digest 0x%x requested but not available",
+		      digest_code);
+
+	pcb->chap_server.digest = dp;
+	pcb->chap_server.name = our_name;
+	/* Start with a random ID value */
+	pcb->chap_server.id = magic();
+	pcb->chap_server.flags |= AUTH_STARTED;
+	if (pcb->chap_server.flags & LOWERUP)
+		chap_timeout(pcb);
+}
+#endif /* PPP_SERVER */
+
+/*
+ * chap_auth_with_peer - Prepare to authenticate ourselves to the peer.
+ * There isn't much to do until we receive a challenge.
+ */
+void chap_auth_with_peer(ppp_pcb *pcb, const char *our_name, int digest_code) {
+	const struct chap_digest_type *dp;
+	int i;
+
+	if(NULL == our_name)
+		return;
+
+	if (pcb->chap_client.flags & AUTH_STARTED) {
+		ppp_error("CHAP: authentication with peer already started!");
+		return;
+	}
+	for (i = 0; (dp = chap_digests[i]) != NULL; ++i)
+		if (dp->code == digest_code)
+			break;
+
+	if (dp == NULL)
+		ppp_fatal("CHAP digest 0x%x requested but not available",
+		      digest_code);
+
+	pcb->chap_client.digest = dp;
+	pcb->chap_client.name = our_name;
+	pcb->chap_client.flags |= AUTH_STARTED;
+}
+
+#if PPP_SERVER
+/*
+ * chap_timeout - It's time to send another challenge to the peer.
+ * This could be either a retransmission of a previous challenge,
+ * or a new challenge to start re-authentication.
+ */
+static void chap_timeout(void *arg) {
+	ppp_pcb *pcb = (ppp_pcb*)arg;
+	struct pbuf *p;
+
+	pcb->chap_server.flags &= ~TIMEOUT_PENDING;
+	if ((pcb->chap_server.flags & CHALLENGE_VALID) == 0) {
+		pcb->chap_server.challenge_xmits = 0;
+		chap_generate_challenge(pcb);
+		pcb->chap_server.flags |= CHALLENGE_VALID;
+	} else if (pcb->chap_server.challenge_xmits >= pcb->settings.chap_max_transmits) {
+		pcb->chap_server.flags &= ~CHALLENGE_VALID;
+		pcb->chap_server.flags |= AUTH_DONE | AUTH_FAILED;
+		auth_peer_fail(pcb, PPP_CHAP);
+		return;
+	}
+
+	p = pbuf_alloc(PBUF_RAW, (u16_t)(pcb->chap_server.challenge_pktlen), PPP_CTRL_PBUF_TYPE);
+	if(NULL == p)
+		return;
+	if(p->tot_len != p->len) {
+		pbuf_free(p);
+		return;
+	}
+	MEMCPY(p->payload, pcb->chap_server.challenge, pcb->chap_server.challenge_pktlen);
+	ppp_write(pcb, p);
+	++pcb->chap_server.challenge_xmits;
+	pcb->chap_server.flags |= TIMEOUT_PENDING;
+	TIMEOUT(chap_timeout, arg, pcb->settings.chap_timeout_time);
+}
+
+/*
+ * chap_generate_challenge - generate a challenge string and format
+ * the challenge packet in pcb->chap_server.challenge_pkt.
+ */
+static void chap_generate_challenge(ppp_pcb *pcb) {
+	int clen = 1, nlen, len;
+	unsigned char *p;
+
+	p = pcb->chap_server.challenge;
+	MAKEHEADER(p, PPP_CHAP);
+	p += CHAP_HDRLEN;
+	pcb->chap_server.digest->generate_challenge(pcb, p);
+	clen = *p;
+	nlen = strlen(pcb->chap_server.name);
+	memcpy(p + 1 + clen, pcb->chap_server.name, nlen);
+
+	len = CHAP_HDRLEN + 1 + clen + nlen;
+	pcb->chap_server.challenge_pktlen = PPP_HDRLEN + len;
+
+	p = pcb->chap_server.challenge + PPP_HDRLEN;
+	p[0] = CHAP_CHALLENGE;
+	p[1] = ++pcb->chap_server.id;
+	p[2] = len >> 8;
+	p[3] = len;
+}
+
+/*
+ * chap_handle_response - check the response to our challenge.
+ */
+static void  chap_handle_response(ppp_pcb *pcb, int id,
+		     unsigned char *pkt, int len) {
+	int response_len, ok, mlen;
+	const unsigned char *response;
+	unsigned char *outp;
+	struct pbuf *p;
+	const char *name = NULL;	/* initialized to shut gcc up */
+#if 0 /* UNUSED */
+	int (*verifier)(const char *, const char *, int, const struct chap_digest_type *,
+		const unsigned char *, const unsigned char *, char *, int);
+#endif /* UNUSED */
+	char rname[MAXNAMELEN+1];
+	char message[256];
+
+	if ((pcb->chap_server.flags & LOWERUP) == 0)
+		return;
+	if (id != pcb->chap_server.challenge[PPP_HDRLEN+1] || len < 2)
+		return;
+	if (pcb->chap_server.flags & CHALLENGE_VALID) {
+		response = pkt;
+		GETCHAR(response_len, pkt);
+		len -= response_len + 1;	/* length of name */
+		name = (char *)pkt + response_len;
+		if (len < 0)
+			return;
+
+		if (pcb->chap_server.flags & TIMEOUT_PENDING) {
+			pcb->chap_server.flags &= ~TIMEOUT_PENDING;
+			UNTIMEOUT(chap_timeout, pcb);
+		}
+#if PPP_REMOTENAME
+		if (pcb->settings.explicit_remote) {
+			name = pcb->remote_name;
+		} else
+#endif /* PPP_REMOTENAME */
+		{
+			/* Null terminate and clean remote name. */
+			ppp_slprintf(rname, sizeof(rname), "%.*v", len, name);
+			name = rname;
+		}
+
+#if 0 /* UNUSED */
+		if (chap_verify_hook)
+			verifier = chap_verify_hook;
+		else
+			verifier = chap_verify_response;
+		ok = (*verifier)(name, pcb->chap_server.name, id, pcb->chap_server.digest,
+				 pcb->chap_server.challenge + PPP_HDRLEN + CHAP_HDRLEN,
+				 response, pcb->chap_server.message, sizeof(pcb->chap_server.message));
+#endif /* UNUSED */
+		ok = chap_verify_response(pcb, name, pcb->chap_server.name, id, pcb->chap_server.digest,
+                    pcb->chap_server.challenge + PPP_HDRLEN + CHAP_HDRLEN,
+                    response, message, sizeof(message));
+#if 0 /* UNUSED */
+		if (!ok || !auth_number()) {
+#endif /* UNUSED */
+		if (!ok) {
+			pcb->chap_server.flags |= AUTH_FAILED;
+			ppp_warn("Peer %q failed CHAP authentication", name);
+		}
+	} else if ((pcb->chap_server.flags & AUTH_DONE) == 0)
+		return;
+
+	/* send the response */
+	mlen = strlen(message);
+	len = CHAP_HDRLEN + mlen;
+	p = pbuf_alloc(PBUF_RAW, (u16_t)(PPP_HDRLEN +len), PPP_CTRL_PBUF_TYPE);
+	if(NULL == p)
+		return;
+	if(p->tot_len != p->len) {
+		pbuf_free(p);
+		return;
+	}
+
+	outp = (unsigned char *)p->payload;
+	MAKEHEADER(outp, PPP_CHAP);
+
+	outp[0] = (pcb->chap_server.flags & AUTH_FAILED)? CHAP_FAILURE: CHAP_SUCCESS;
+	outp[1] = id;
+	outp[2] = len >> 8;
+	outp[3] = len;
+	if (mlen > 0)
+		memcpy(outp + CHAP_HDRLEN, message, mlen);
+	ppp_write(pcb, p);
+
+	if (pcb->chap_server.flags & CHALLENGE_VALID) {
+		pcb->chap_server.flags &= ~CHALLENGE_VALID;
+		if (!(pcb->chap_server.flags & AUTH_DONE) && !(pcb->chap_server.flags & AUTH_FAILED)) {
+
+#if 0 /* UNUSED */
+		    /*
+		     * Auth is OK, so now we need to check session restrictions
+		     * to ensure everything is OK, but only if we used a
+		     * plugin, and only if we're configured to check.  This
+		     * allows us to do PAM checks on PPP servers that
+		     * authenticate against ActiveDirectory, and use AD for
+		     * account info (like when using Winbind integrated with
+		     * PAM).
+		     */
+		    if (session_mgmt &&
+			session_check(name, NULL, devnam, NULL) == 0) {
+			pcb->chap_server.flags |= AUTH_FAILED;
+			ppp_warn("Peer %q failed CHAP Session verification", name);
+		    }
+#endif /* UNUSED */
+
+		}
+		if (pcb->chap_server.flags & AUTH_FAILED) {
+			auth_peer_fail(pcb, PPP_CHAP);
+		} else {
+			if ((pcb->chap_server.flags & AUTH_DONE) == 0)
+				auth_peer_success(pcb, PPP_CHAP,
+						  pcb->chap_server.digest->code,
+						  name, strlen(name));
+			if (pcb->settings.chap_rechallenge_time) {
+				pcb->chap_server.flags |= TIMEOUT_PENDING;
+				TIMEOUT(chap_timeout, pcb,
+					pcb->settings.chap_rechallenge_time);
+			}
+		}
+		pcb->chap_server.flags |= AUTH_DONE;
+	}
+}
+
+/*
+ * chap_verify_response - check whether the peer's response matches
+ * what we think it should be.  Returns 1 if it does (authentication
+ * succeeded), or 0 if it doesn't.
+ */
+static int chap_verify_response(ppp_pcb *pcb, const char *name, const char *ourname, int id,
+		     const struct chap_digest_type *digest,
+		     const unsigned char *challenge, const unsigned char *response,
+		     char *message, int message_space) {
+	int ok;
+	unsigned char secret[MAXSECRETLEN];
+	int secret_len;
+
+	/* Get the secret that the peer is supposed to know */
+	if (!get_secret(pcb, name, ourname, (char *)secret, &secret_len, 1)) {
+		ppp_error("No CHAP secret found for authenticating %q", name);
+		return 0;
+	}
+	ok = digest->verify_response(pcb, id, name, secret, secret_len, challenge,
+				     response, message, message_space);
+	memset(secret, 0, sizeof(secret));
+
+	return ok;
+}
+#endif /* PPP_SERVER */
+
+/*
+ * chap_respond - Generate and send a response to a challenge.
+ */
+static void chap_respond(ppp_pcb *pcb, int id,
+	     unsigned char *pkt, int len) {
+	int clen, nlen;
+	int secret_len;
+	struct pbuf *p;
+	u_char *outp;
+	char rname[MAXNAMELEN+1];
+	char secret[MAXSECRETLEN+1];
+
+	p = pbuf_alloc(PBUF_RAW, (u16_t)(RESP_MAX_PKTLEN), PPP_CTRL_PBUF_TYPE);
+	if(NULL == p)
+		return;
+	if(p->tot_len != p->len) {
+		pbuf_free(p);
+		return;
+	}
+
+	if ((pcb->chap_client.flags & (LOWERUP | AUTH_STARTED)) != (LOWERUP | AUTH_STARTED))
+		return;		/* not ready */
+	if (len < 2 || len < pkt[0] + 1)
+		return;		/* too short */
+	clen = pkt[0];
+	nlen = len - (clen + 1);
+
+	/* Null terminate and clean remote name. */
+	ppp_slprintf(rname, sizeof(rname), "%.*v", nlen, pkt + clen + 1);
+
+#if PPP_REMOTENAME
+	/* Microsoft doesn't send their name back in the PPP packet */
+	if (pcb->settings.explicit_remote || (pcb->settings.remote_name[0] != 0 && rname[0] == 0))
+		strlcpy(rname, pcb->settings.remote_name, sizeof(rname));
+#endif /* PPP_REMOTENAME */
+
+	/* get secret for authenticating ourselves with the specified host */
+	if (!get_secret(pcb, pcb->chap_client.name, rname, secret, &secret_len, 0)) {
+		secret_len = 0;	/* assume null secret if can't find one */
+		ppp_warn("No CHAP secret found for authenticating us to %q", rname);
+	}
+
+	outp = (u_char*)p->payload;
+	MAKEHEADER(outp, PPP_CHAP);
+	outp += CHAP_HDRLEN;
+
+	pcb->chap_client.digest->make_response(pcb, outp, id, pcb->chap_client.name, pkt,
+				  secret, secret_len, pcb->chap_client.priv);
+	memset(secret, 0, secret_len);
+
+	clen = *outp;
+	nlen = strlen(pcb->chap_client.name);
+	memcpy(outp + clen + 1, pcb->chap_client.name, nlen);
+
+	outp = (u_char*)p->payload + PPP_HDRLEN;
+	len = CHAP_HDRLEN + clen + 1 + nlen;
+	outp[0] = CHAP_RESPONSE;
+	outp[1] = id;
+	outp[2] = len >> 8;
+	outp[3] = len;
+
+	pbuf_realloc(p, PPP_HDRLEN + len);
+	ppp_write(pcb, p);
+}
+
+static void chap_handle_status(ppp_pcb *pcb, int code, int id,
+		   unsigned char *pkt, int len) {
+	const char *msg = NULL;
+	LWIP_UNUSED_ARG(id);
+
+	if ((pcb->chap_client.flags & (AUTH_DONE|AUTH_STARTED|LOWERUP))
+	    != (AUTH_STARTED|LOWERUP))
+		return;
+	pcb->chap_client.flags |= AUTH_DONE;
+
+	if (code == CHAP_SUCCESS) {
+		/* used for MS-CHAP v2 mutual auth, yuck */
+		if (pcb->chap_client.digest->check_success != NULL) {
+			if (!(*pcb->chap_client.digest->check_success)(pcb, pkt, len, pcb->chap_client.priv))
+				code = CHAP_FAILURE;
+		} else
+			msg = "CHAP authentication succeeded";
+	} else {
+		if (pcb->chap_client.digest->handle_failure != NULL)
+			(*pcb->chap_client.digest->handle_failure)(pcb, pkt, len);
+		else
+			msg = "CHAP authentication failed";
+	}
+	if (msg) {
+		if (len > 0)
+			ppp_info("%s: %.*v", msg, len, pkt);
+		else
+			ppp_info("%s", msg);
+	}
+	if (code == CHAP_SUCCESS)
+		auth_withpeer_success(pcb, PPP_CHAP, pcb->chap_client.digest->code);
+	else {
+		pcb->chap_client.flags |= AUTH_FAILED;
+		ppp_error("CHAP authentication failed");
+		auth_withpeer_fail(pcb, PPP_CHAP);
+	}
+}
+
+static void chap_input(ppp_pcb *pcb, unsigned char *pkt, int pktlen) {
+	unsigned char code, id;
+	int len;
+
+	if (pktlen < CHAP_HDRLEN)
+		return;
+	GETCHAR(code, pkt);
+	GETCHAR(id, pkt);
+	GETSHORT(len, pkt);
+	if (len < CHAP_HDRLEN || len > pktlen)
+		return;
+	len -= CHAP_HDRLEN;
+
+	switch (code) {
+	case CHAP_CHALLENGE:
+		chap_respond(pcb, id, pkt, len);
+		break;
+#if PPP_SERVER
+	case CHAP_RESPONSE:
+		chap_handle_response(pcb, id, pkt, len);
+		break;
+#endif /* PPP_SERVER */
+	case CHAP_FAILURE:
+	case CHAP_SUCCESS:
+		chap_handle_status(pcb, code, id, pkt, len);
+		break;
+	default:
+		break;
+	}
+}
+
+static void chap_protrej(ppp_pcb *pcb) {
+
+#if PPP_SERVER
+	if (pcb->chap_server.flags & TIMEOUT_PENDING) {
+		pcb->chap_server.flags &= ~TIMEOUT_PENDING;
+		UNTIMEOUT(chap_timeout, pcb);
+	}
+	if (pcb->chap_server.flags & AUTH_STARTED) {
+		pcb->chap_server.flags = 0;
+		auth_peer_fail(pcb, PPP_CHAP);
+	}
+#endif /* PPP_SERVER */
+	if ((pcb->chap_client.flags & (AUTH_STARTED|AUTH_DONE)) == AUTH_STARTED) {
+		pcb->chap_client.flags &= ~AUTH_STARTED;
+		ppp_error("CHAP authentication failed due to protocol-reject");
+		auth_withpeer_fail(pcb, PPP_CHAP);
+	}
+}
+
+#if PRINTPKT_SUPPORT
+/*
+ * chap_print_pkt - print the contents of a CHAP packet.
+ */
+static const char* const chap_code_names[] = {
+	"Challenge", "Response", "Success", "Failure"
+};
+
+static int chap_print_pkt(const unsigned char *p, int plen,
+	       void (*printer) (void *, const char *, ...), void *arg) {
+	int code, id, len;
+	int clen, nlen;
+	unsigned char x;
+
+	if (plen < CHAP_HDRLEN)
+		return 0;
+	GETCHAR(code, p);
+	GETCHAR(id, p);
+	GETSHORT(len, p);
+	if (len < CHAP_HDRLEN || len > plen)
+		return 0;
+
+	if (code >= 1 && code <= (int)LWIP_ARRAYSIZE(chap_code_names))
+		printer(arg, " %s", chap_code_names[code-1]);
+	else
+		printer(arg, " code=0x%x", code);
+	printer(arg, " id=0x%x", id);
+	len -= CHAP_HDRLEN;
+	switch (code) {
+	case CHAP_CHALLENGE:
+	case CHAP_RESPONSE:
+		if (len < 1)
+			break;
+		clen = p[0];
+		if (len < clen + 1)
+			break;
+		++p;
+		nlen = len - clen - 1;
+		printer(arg, " <");
+		for (; clen > 0; --clen) {
+			GETCHAR(x, p);
+			printer(arg, "%.2x", x);
+		}
+		printer(arg, ">, name = ");
+		ppp_print_string(p, nlen, printer, arg);
+		break;
+	case CHAP_FAILURE:
+	case CHAP_SUCCESS:
+		printer(arg, " ");
+		ppp_print_string(p, len, printer, arg);
+		break;
+	default:
+		for (clen = len; clen > 0; --clen) {
+			GETCHAR(x, p);
+			printer(arg, " %.2x", x);
+		}
+		/* no break */
+	}
+
+	return len + CHAP_HDRLEN;
+}
+#endif /* PRINTPKT_SUPPORT */
+
+const struct protent chap_protent = {
+	PPP_CHAP,
+	chap_init,
+	chap_input,
+	chap_protrej,
+	chap_lowerup,
+	chap_lowerdown,
+	NULL,		/* open */
+	NULL,		/* close */
+#if PRINTPKT_SUPPORT
+	chap_print_pkt,
+#endif /* PRINTPKT_SUPPORT */
+#if PPP_DATAINPUT
+	NULL,		/* datainput */
+#endif /* PPP_DATAINPUT */
+#if PRINTPKT_SUPPORT
+	"CHAP",		/* name */
+	NULL,		/* data_name */
+#endif /* PRINTPKT_SUPPORT */
+#if PPP_OPTIONS
+	chap_option_list,
+	NULL,		/* check_options */
+#endif /* PPP_OPTIONS */
+#if DEMAND_SUPPORT
+	NULL,
+	NULL
+#endif /* DEMAND_SUPPORT */
+};
+
+#endif /* PPP_SUPPORT && CHAP_SUPPORT */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/netif/ppp/chap_ms.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/netif/ppp/chap_ms.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/netif/ppp/chap_ms.c	(revision 457)
@@ -0,0 +1,962 @@
+/*
+ * chap_ms.c - Microsoft MS-CHAP compatible implementation.
+ *
+ * Copyright (c) 1995 Eric Rosenquist.  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. The name(s) of the authors of this software must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission.
+ *
+ * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO
+ * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
+ * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
+ * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
+ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * Modifications by Lauri Pesonen / lpesonen@clinet.fi, april 1997
+ *
+ *   Implemented LANManager type password response to MS-CHAP challenges.
+ *   Now pppd provides both NT style and LANMan style blocks, and the
+ *   prefered is set by option "ms-lanman". Default is to use NT.
+ *   The hash text (StdText) was taken from Win95 RASAPI32.DLL.
+ *
+ *   You should also use DOMAIN\\USERNAME as described in README.MSCHAP80
+ */
+
+/*
+ * Modifications by Frank Cusack, frank@google.com, March 2002.
+ *
+ *   Implemented MS-CHAPv2 functionality, heavily based on sample
+ *   implementation in RFC 2759.  Implemented MPPE functionality,
+ *   heavily based on sample implementation in RFC 3079.
+ *
+ * Copyright (c) 2002 Google, Inc.  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. The name(s) of the authors of this software must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission.
+ *
+ * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO
+ * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
+ * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
+ * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
+ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ */
+
+#include "netif/ppp/ppp_opts.h"
+#if PPP_SUPPORT && MSCHAP_SUPPORT  /* don't build if not configured for use in lwipopts.h */
+
+#if 0 /* UNUSED */
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <sys/types.h>
+#include <sys/time.h>
+#include <unistd.h>
+#endif /* UNUSED */
+
+#include "netif/ppp/ppp_impl.h"
+
+#include "netif/ppp/chap-new.h"
+#include "netif/ppp/chap_ms.h"
+#include "netif/ppp/pppcrypt.h"
+#include "netif/ppp/magic.h"
+#if MPPE_SUPPORT
+#include "netif/ppp/mppe.h" /* For mppe_sha1_pad*, mppe_set_key() */
+#endif /* MPPE_SUPPORT */
+
+#define SHA1_SIGNATURE_SIZE	20
+#define MD4_SIGNATURE_SIZE	16	/* 16 bytes in a MD4 message digest */
+#define MAX_NT_PASSWORD		256	/* Max (Unicode) chars in an NT pass */
+
+#define MS_CHAP_RESPONSE_LEN	49	/* Response length for MS-CHAP */
+#define MS_CHAP2_RESPONSE_LEN	49	/* Response length for MS-CHAPv2 */
+#define MS_AUTH_RESPONSE_LENGTH	40	/* MS-CHAPv2 authenticator response, */
+					/* as ASCII */
+
+/* Error codes for MS-CHAP failure messages. */
+#define MS_CHAP_ERROR_RESTRICTED_LOGON_HOURS	646
+#define MS_CHAP_ERROR_ACCT_DISABLED		647
+#define MS_CHAP_ERROR_PASSWD_EXPIRED		648
+#define MS_CHAP_ERROR_NO_DIALIN_PERMISSION	649
+#define MS_CHAP_ERROR_AUTHENTICATION_FAILURE	691
+#define MS_CHAP_ERROR_CHANGING_PASSWORD		709
+
+/*
+ * Offsets within the response field for MS-CHAP
+ */
+#define MS_CHAP_LANMANRESP	0
+#define MS_CHAP_LANMANRESP_LEN	24
+#define MS_CHAP_NTRESP		24
+#define MS_CHAP_NTRESP_LEN	24
+#define MS_CHAP_USENT		48
+
+/*
+ * Offsets within the response field for MS-CHAP2
+ */
+#define MS_CHAP2_PEER_CHALLENGE	0
+#define MS_CHAP2_PEER_CHAL_LEN	16
+#define MS_CHAP2_RESERVED_LEN	8
+#define MS_CHAP2_NTRESP		24
+#define MS_CHAP2_NTRESP_LEN	24
+#define MS_CHAP2_FLAGS		48
+
+#if MPPE_SUPPORT
+#if 0 /* UNUSED */
+/* These values are the RADIUS attribute values--see RFC 2548. */
+#define MPPE_ENC_POL_ENC_ALLOWED 1
+#define MPPE_ENC_POL_ENC_REQUIRED 2
+#define MPPE_ENC_TYPES_RC4_40 2
+#define MPPE_ENC_TYPES_RC4_128 4
+
+/* used by plugins (using above values) */
+extern void set_mppe_enc_types(int, int);
+#endif /* UNUSED */
+#endif /* MPPE_SUPPORT */
+
+/* Are we the authenticator or authenticatee?  For MS-CHAPv2 key derivation. */
+#define MS_CHAP2_AUTHENTICATEE 0
+#define MS_CHAP2_AUTHENTICATOR 1
+
+static void	ascii2unicode (const char[], int, u_char[]);
+static void	NTPasswordHash (u_char *, int, u_char[MD4_SIGNATURE_SIZE]);
+static void	ChallengeResponse (const u_char *, const u_char *, u_char[24]);
+static void	ChallengeHash (const u_char[16], const u_char *, const char *, u_char[8]);
+static void	ChapMS_NT (const u_char *, const char *, int, u_char[24]);
+static void	ChapMS2_NT (const u_char *, const u_char[16], const char *, const char *, int,
+				u_char[24]);
+static void	GenerateAuthenticatorResponsePlain
+			(const char*, int, u_char[24], const u_char[16], const u_char *,
+			     const char *, u_char[41]);
+#ifdef MSLANMAN
+static void	ChapMS_LANMan (u_char *, char *, int, u_char *);
+#endif
+
+static void GenerateAuthenticatorResponse(const u_char PasswordHashHash[MD4_SIGNATURE_SIZE],
+			u_char NTResponse[24], const u_char PeerChallenge[16],
+			const u_char *rchallenge, const char *username,
+			u_char authResponse[MS_AUTH_RESPONSE_LENGTH+1]);
+
+#if MPPE_SUPPORT
+static void	Set_Start_Key (ppp_pcb *pcb, const u_char *, const char *, int);
+static void	SetMasterKeys (ppp_pcb *pcb, const char *, int, u_char[24], int);
+#endif /* MPPE_SUPPORT */
+
+static void ChapMS (ppp_pcb *pcb, const u_char *, const char *, int, u_char *);
+static void ChapMS2 (ppp_pcb *pcb, const u_char *, const u_char *, const char *, const char *, int,
+		  u_char *, u_char[MS_AUTH_RESPONSE_LENGTH+1], int);
+
+#ifdef MSLANMAN
+bool	ms_lanman = 0;    	/* Use LanMan password instead of NT */
+			  	/* Has meaning only with MS-CHAP challenges */
+#endif
+
+#if MPPE_SUPPORT
+#ifdef DEBUGMPPEKEY
+/* For MPPE debug */
+/* Use "[]|}{?/><,`!2&&(" (sans quotes) for RFC 3079 MS-CHAPv2 test value */
+static char *mschap_challenge = NULL;
+/* Use "!@\#$%^&*()_+:3|~" (sans quotes, backslash is to escape #) for ... */
+static char *mschap2_peer_challenge = NULL;
+#endif
+
+#include "netif/ppp/fsm.h"		/* Need to poke MPPE options */
+#include "netif/ppp/ccp.h"
+#endif /* MPPE_SUPPORT */
+
+#if PPP_OPTIONS
+/*
+ * Command-line options.
+ */
+static option_t chapms_option_list[] = {
+#ifdef MSLANMAN
+	{ "ms-lanman", o_bool, &ms_lanman,
+	  "Use LanMan passwd when using MS-CHAP", 1 },
+#endif
+#ifdef DEBUGMPPEKEY
+	{ "mschap-challenge", o_string, &mschap_challenge,
+	  "specify CHAP challenge" },
+	{ "mschap2-peer-challenge", o_string, &mschap2_peer_challenge,
+	  "specify CHAP peer challenge" },
+#endif
+	{ NULL }
+};
+#endif /* PPP_OPTIONS */
+
+#if PPP_SERVER
+/*
+ * chapms_generate_challenge - generate a challenge for MS-CHAP.
+ * For MS-CHAP the challenge length is fixed at 8 bytes.
+ * The length goes in challenge[0] and the actual challenge starts
+ * at challenge[1].
+ */
+static void chapms_generate_challenge(ppp_pcb *pcb, unsigned char *challenge) {
+	LWIP_UNUSED_ARG(pcb);
+
+	*challenge++ = 8;
+#ifdef DEBUGMPPEKEY
+	if (mschap_challenge && strlen(mschap_challenge) == 8)
+		memcpy(challenge, mschap_challenge, 8);
+	else
+#endif
+		magic_random_bytes(challenge, 8);
+}
+
+static void chapms2_generate_challenge(ppp_pcb *pcb, unsigned char *challenge) {
+	LWIP_UNUSED_ARG(pcb);
+
+	*challenge++ = 16;
+#ifdef DEBUGMPPEKEY
+	if (mschap_challenge && strlen(mschap_challenge) == 16)
+		memcpy(challenge, mschap_challenge, 16);
+	else
+#endif
+		magic_random_bytes(challenge, 16);
+}
+
+static int chapms_verify_response(ppp_pcb *pcb, int id, const char *name,
+		       const unsigned char *secret, int secret_len,
+		       const unsigned char *challenge, const unsigned char *response,
+		       char *message, int message_space) {
+	unsigned char md[MS_CHAP_RESPONSE_LEN];
+	int diff;
+	int challenge_len, response_len;
+	LWIP_UNUSED_ARG(id);
+	LWIP_UNUSED_ARG(name);
+
+	challenge_len = *challenge++;	/* skip length, is 8 */
+	response_len = *response++;
+	if (response_len != MS_CHAP_RESPONSE_LEN)
+		goto bad;
+
+#ifndef MSLANMAN
+	if (!response[MS_CHAP_USENT]) {
+		/* Should really propagate this into the error packet. */
+		ppp_notice("Peer request for LANMAN auth not supported");
+		goto bad;
+	}
+#endif
+
+	/* Generate the expected response. */
+	ChapMS(pcb, (const u_char *)challenge, (const char *)secret, secret_len, md);
+
+#ifdef MSLANMAN
+	/* Determine which part of response to verify against */
+	if (!response[MS_CHAP_USENT])
+		diff = memcmp(&response[MS_CHAP_LANMANRESP],
+			      &md[MS_CHAP_LANMANRESP], MS_CHAP_LANMANRESP_LEN);
+	else
+#endif
+		diff = memcmp(&response[MS_CHAP_NTRESP], &md[MS_CHAP_NTRESP],
+			      MS_CHAP_NTRESP_LEN);
+
+	if (diff == 0) {
+		ppp_slprintf(message, message_space, "Access granted");
+		return 1;
+	}
+
+ bad:
+	/* See comments below for MS-CHAP V2 */
+	ppp_slprintf(message, message_space, "E=691 R=1 C=%0.*B V=0",
+		 challenge_len, challenge);
+	return 0;
+}
+
+static int chapms2_verify_response(ppp_pcb *pcb, int id, const char *name,
+			const unsigned char *secret, int secret_len,
+			const unsigned char *challenge, const unsigned char *response,
+			char *message, int message_space) {
+	unsigned char md[MS_CHAP2_RESPONSE_LEN];
+	char saresponse[MS_AUTH_RESPONSE_LENGTH+1];
+	int challenge_len, response_len;
+	LWIP_UNUSED_ARG(id);
+
+	challenge_len = *challenge++;	/* skip length, is 16 */
+	response_len = *response++;
+	if (response_len != MS_CHAP2_RESPONSE_LEN)
+		goto bad;	/* not even the right length */
+
+	/* Generate the expected response and our mutual auth. */
+	ChapMS2(pcb, (const u_char*)challenge, (const u_char*)&response[MS_CHAP2_PEER_CHALLENGE], name,
+		(const char *)secret, secret_len, md,
+		(unsigned char *)saresponse, MS_CHAP2_AUTHENTICATOR);
+
+	/* compare MDs and send the appropriate status */
+	/*
+	 * Per RFC 2759, success message must be formatted as
+	 *     "S=<auth_string> M=<message>"
+	 * where
+	 *     <auth_string> is the Authenticator Response (mutual auth)
+	 *     <message> is a text message
+	 *
+	 * However, some versions of Windows (win98 tested) do not know
+	 * about the M=<message> part (required per RFC 2759) and flag
+	 * it as an error (reported incorrectly as an encryption error
+	 * to the user).  Since the RFC requires it, and it can be
+	 * useful information, we supply it if the peer is a conforming
+	 * system.  Luckily (?), win98 sets the Flags field to 0x04
+	 * (contrary to RFC requirements) so we can use that to
+	 * distinguish between conforming and non-conforming systems.
+	 *
+	 * Special thanks to Alex Swiridov <say@real.kharkov.ua> for
+	 * help debugging this.
+	 */
+	if (memcmp(&md[MS_CHAP2_NTRESP], &response[MS_CHAP2_NTRESP],
+		   MS_CHAP2_NTRESP_LEN) == 0) {
+		if (response[MS_CHAP2_FLAGS])
+			ppp_slprintf(message, message_space, "S=%s", saresponse);
+		else
+			ppp_slprintf(message, message_space, "S=%s M=%s",
+				 saresponse, "Access granted");
+		return 1;
+	}
+
+ bad:
+	/*
+	 * Failure message must be formatted as
+	 *     "E=e R=r C=c V=v M=m"
+	 * where
+	 *     e = error code (we use 691, ERROR_AUTHENTICATION_FAILURE)
+	 *     r = retry (we use 1, ok to retry)
+	 *     c = challenge to use for next response, we reuse previous
+	 *     v = Change Password version supported, we use 0
+	 *     m = text message
+	 *
+	 * The M=m part is only for MS-CHAPv2.  Neither win2k nor
+	 * win98 (others untested) display the message to the user anyway.
+	 * They also both ignore the E=e code.
+	 *
+	 * Note that it's safe to reuse the same challenge as we don't
+	 * actually accept another response based on the error message
+	 * (and no clients try to resend a response anyway).
+	 *
+	 * Basically, this whole bit is useless code, even the small
+	 * implementation here is only because of overspecification.
+	 */
+	ppp_slprintf(message, message_space, "E=691 R=1 C=%0.*B V=0 M=%s",
+		 challenge_len, challenge, "Access denied");
+	return 0;
+}
+#endif /* PPP_SERVER */
+
+static void chapms_make_response(ppp_pcb *pcb, unsigned char *response, int id, const char *our_name,
+		     const unsigned char *challenge, const char *secret, int secret_len,
+		     unsigned char *private_) {
+	LWIP_UNUSED_ARG(id);
+	LWIP_UNUSED_ARG(our_name);
+	LWIP_UNUSED_ARG(private_);
+	challenge++;	/* skip length, should be 8 */
+	*response++ = MS_CHAP_RESPONSE_LEN;
+	ChapMS(pcb, challenge, secret, secret_len, response);
+}
+
+static void chapms2_make_response(ppp_pcb *pcb, unsigned char *response, int id, const char *our_name,
+		      const unsigned char *challenge, const char *secret, int secret_len,
+		      unsigned char *private_) {
+	LWIP_UNUSED_ARG(id);
+	challenge++;	/* skip length, should be 16 */
+	*response++ = MS_CHAP2_RESPONSE_LEN;
+	ChapMS2(pcb, challenge,
+#ifdef DEBUGMPPEKEY
+		mschap2_peer_challenge,
+#else
+		NULL,
+#endif
+		our_name, secret, secret_len, response, private_,
+		MS_CHAP2_AUTHENTICATEE);
+}
+
+static int chapms2_check_success(ppp_pcb *pcb, unsigned char *msg, int len, unsigned char *private_) {
+	LWIP_UNUSED_ARG(pcb);
+
+	if ((len < MS_AUTH_RESPONSE_LENGTH + 2) ||
+	    strncmp((char *)msg, "S=", 2) != 0) {
+		/* Packet does not start with "S=" */
+		ppp_error("MS-CHAPv2 Success packet is badly formed.");
+		return 0;
+	}
+	msg += 2;
+	len -= 2;
+	if (len < MS_AUTH_RESPONSE_LENGTH
+	    || memcmp(msg, private_, MS_AUTH_RESPONSE_LENGTH)) {
+		/* Authenticator Response did not match expected. */
+		ppp_error("MS-CHAPv2 mutual authentication failed.");
+		return 0;
+	}
+	/* Authenticator Response matches. */
+	msg += MS_AUTH_RESPONSE_LENGTH; /* Eat it */
+	len -= MS_AUTH_RESPONSE_LENGTH;
+	if ((len >= 3) && !strncmp((char *)msg, " M=", 3)) {
+		msg += 3; /* Eat the delimiter */
+	} else if (len) {
+		/* Packet has extra text which does not begin " M=" */
+		ppp_error("MS-CHAPv2 Success packet is badly formed.");
+		return 0;
+	}
+	return 1;
+}
+
+static void chapms_handle_failure(ppp_pcb *pcb, unsigned char *inp, int len) {
+	int err;
+	const char *p;
+	char msg[64];
+	LWIP_UNUSED_ARG(pcb);
+
+	/* We want a null-terminated string for strxxx(). */
+	len = LWIP_MIN(len, 63);
+	MEMCPY(msg, inp, len);
+	msg[len] = 0;
+	p = msg;
+
+	/*
+	 * Deal with MS-CHAP formatted failure messages; just print the
+	 * M=<message> part (if any).  For MS-CHAP we're not really supposed
+	 * to use M=<message>, but it shouldn't hurt.  See
+	 * chapms[2]_verify_response.
+	 */
+	if (!strncmp(p, "E=", 2))
+		err = strtol(p+2, NULL, 10); /* Remember the error code. */
+	else
+		goto print_msg; /* Message is badly formatted. */
+
+	if (len && ((p = strstr(p, " M=")) != NULL)) {
+		/* M=<message> field found. */
+		p += 3;
+	} else {
+		/* No M=<message>; use the error code. */
+		switch (err) {
+		case MS_CHAP_ERROR_RESTRICTED_LOGON_HOURS:
+			p = "E=646 Restricted logon hours";
+			break;
+
+		case MS_CHAP_ERROR_ACCT_DISABLED:
+			p = "E=647 Account disabled";
+			break;
+
+		case MS_CHAP_ERROR_PASSWD_EXPIRED:
+			p = "E=648 Password expired";
+			break;
+
+		case MS_CHAP_ERROR_NO_DIALIN_PERMISSION:
+			p = "E=649 No dialin permission";
+			break;
+
+		case MS_CHAP_ERROR_AUTHENTICATION_FAILURE:
+			p = "E=691 Authentication failure";
+			break;
+
+		case MS_CHAP_ERROR_CHANGING_PASSWORD:
+			/* Should never see this, we don't support Change Password. */
+			p = "E=709 Error changing password";
+			break;
+
+		default:
+			ppp_error("Unknown MS-CHAP authentication failure: %.*v",
+			      len, inp);
+			return;
+		}
+	}
+print_msg:
+	if (p != NULL)
+		ppp_error("MS-CHAP authentication failed: %v", p);
+}
+
+static void ChallengeResponse(const u_char *challenge,
+		  const u_char PasswordHash[MD4_SIGNATURE_SIZE],
+		  u_char response[24]) {
+    u_char    ZPasswordHash[21];
+    lwip_des_context des;
+    u_char des_key[8];
+
+    BZERO(ZPasswordHash, sizeof(ZPasswordHash));
+    MEMCPY(ZPasswordHash, PasswordHash, MD4_SIGNATURE_SIZE);
+
+#if 0
+    dbglog("ChallengeResponse - ZPasswordHash %.*B",
+	   sizeof(ZPasswordHash), ZPasswordHash);
+#endif
+
+    pppcrypt_56_to_64_bit_key(ZPasswordHash + 0, des_key);
+    lwip_des_init(&des);
+    lwip_des_setkey_enc(&des, des_key);
+    lwip_des_crypt_ecb(&des, challenge, response +0);
+    lwip_des_free(&des);
+
+    pppcrypt_56_to_64_bit_key(ZPasswordHash + 7, des_key);
+    lwip_des_init(&des);
+    lwip_des_setkey_enc(&des, des_key);
+    lwip_des_crypt_ecb(&des, challenge, response +8);
+    lwip_des_free(&des);
+
+    pppcrypt_56_to_64_bit_key(ZPasswordHash + 14, des_key);
+    lwip_des_init(&des);
+    lwip_des_setkey_enc(&des, des_key);
+    lwip_des_crypt_ecb(&des, challenge, response +16);
+    lwip_des_free(&des);
+
+#if 0
+    dbglog("ChallengeResponse - response %.24B", response);
+#endif
+}
+
+static void ChallengeHash(const u_char PeerChallenge[16], const u_char *rchallenge,
+	      const char *username, u_char Challenge[8]) {
+    lwip_sha1_context	sha1Context;
+    u_char	sha1Hash[SHA1_SIGNATURE_SIZE];
+    const char	*user;
+
+    /* remove domain from "domain\username" */
+    if ((user = strrchr(username, '\\')) != NULL)
+	++user;
+    else
+	user = username;
+
+    lwip_sha1_init(&sha1Context);
+    lwip_sha1_starts(&sha1Context);
+    lwip_sha1_update(&sha1Context, PeerChallenge, 16);
+    lwip_sha1_update(&sha1Context, rchallenge, 16);
+    lwip_sha1_update(&sha1Context, (const unsigned char*)user, strlen(user));
+    lwip_sha1_finish(&sha1Context, sha1Hash);
+    lwip_sha1_free(&sha1Context);
+
+    MEMCPY(Challenge, sha1Hash, 8);
+}
+
+/*
+ * Convert the ASCII version of the password to Unicode.
+ * This implicitly supports 8-bit ISO8859/1 characters.
+ * This gives us the little-endian representation, which
+ * is assumed by all M$ CHAP RFCs.  (Unicode byte ordering
+ * is machine-dependent.)
+ */
+static void ascii2unicode(const char ascii[], int ascii_len, u_char unicode[]) {
+    int i;
+
+    BZERO(unicode, ascii_len * 2);
+    for (i = 0; i < ascii_len; i++)
+	unicode[i * 2] = (u_char) ascii[i];
+}
+
+static void NTPasswordHash(u_char *secret, int secret_len, u_char hash[MD4_SIGNATURE_SIZE]) {
+    lwip_md4_context		md4Context;
+
+    lwip_md4_init(&md4Context);
+    lwip_md4_starts(&md4Context);
+    lwip_md4_update(&md4Context, secret, secret_len);
+    lwip_md4_finish(&md4Context, hash);
+    lwip_md4_free(&md4Context);
+}
+
+static void ChapMS_NT(const u_char *rchallenge, const char *secret, int secret_len,
+	  u_char NTResponse[24]) {
+    u_char	unicodePassword[MAX_NT_PASSWORD * 2];
+    u_char	PasswordHash[MD4_SIGNATURE_SIZE];
+
+    /* Hash the Unicode version of the secret (== password). */
+    ascii2unicode(secret, secret_len, unicodePassword);
+    NTPasswordHash(unicodePassword, secret_len * 2, PasswordHash);
+
+    ChallengeResponse(rchallenge, PasswordHash, NTResponse);
+}
+
+static void ChapMS2_NT(const u_char *rchallenge, const u_char PeerChallenge[16], const char *username,
+	   const char *secret, int secret_len, u_char NTResponse[24]) {
+    u_char	unicodePassword[MAX_NT_PASSWORD * 2];
+    u_char	PasswordHash[MD4_SIGNATURE_SIZE];
+    u_char	Challenge[8];
+
+    ChallengeHash(PeerChallenge, rchallenge, username, Challenge);
+
+    /* Hash the Unicode version of the secret (== password). */
+    ascii2unicode(secret, secret_len, unicodePassword);
+    NTPasswordHash(unicodePassword, secret_len * 2, PasswordHash);
+
+    ChallengeResponse(Challenge, PasswordHash, NTResponse);
+}
+
+#ifdef MSLANMAN
+static u_char *StdText = (u_char *)"KGS!@#$%"; /* key from rasapi32.dll */
+
+static void ChapMS_LANMan(u_char *rchallenge, char *secret, int secret_len,
+	      unsigned char *response) {
+    int			i;
+    u_char		UcasePassword[MAX_NT_PASSWORD]; /* max is actually 14 */
+    u_char		PasswordHash[MD4_SIGNATURE_SIZE];
+    lwip_des_context des;
+    u_char des_key[8];
+
+    /* LANMan password is case insensitive */
+    BZERO(UcasePassword, sizeof(UcasePassword));
+    for (i = 0; i < secret_len; i++)
+       UcasePassword[i] = (u_char)toupper(secret[i]);
+
+    pppcrypt_56_to_64_bit_key(UcasePassword +0, des_key);
+    lwip_des_init(&des);
+    lwip_des_setkey_enc(&des, des_key);
+    lwip_des_crypt_ecb(&des, StdText, PasswordHash +0);
+    lwip_des_free(&des);
+
+    pppcrypt_56_to_64_bit_key(UcasePassword +7, des_key);
+    lwip_des_init(&des);
+    lwip_des_setkey_enc(&des, des_key);
+    lwip_des_crypt_ecb(&des, StdText, PasswordHash +8);
+    lwip_des_free(&des);
+
+    ChallengeResponse(rchallenge, PasswordHash, &response[MS_CHAP_LANMANRESP]);
+}
+#endif
+
+
+static void GenerateAuthenticatorResponse(const u_char PasswordHashHash[MD4_SIGNATURE_SIZE],
+			      u_char NTResponse[24], const u_char PeerChallenge[16],
+			      const u_char *rchallenge, const char *username,
+			      u_char authResponse[MS_AUTH_RESPONSE_LENGTH+1]) {
+    /*
+     * "Magic" constants used in response generation, from RFC 2759.
+     */
+    static const u_char Magic1[39] = /* "Magic server to client signing constant" */
+	{ 0x4D, 0x61, 0x67, 0x69, 0x63, 0x20, 0x73, 0x65, 0x72, 0x76,
+	  0x65, 0x72, 0x20, 0x74, 0x6F, 0x20, 0x63, 0x6C, 0x69, 0x65,
+	  0x6E, 0x74, 0x20, 0x73, 0x69, 0x67, 0x6E, 0x69, 0x6E, 0x67,
+	  0x20, 0x63, 0x6F, 0x6E, 0x73, 0x74, 0x61, 0x6E, 0x74 };
+    static const u_char Magic2[41] = /* "Pad to make it do more than one iteration" */
+	{ 0x50, 0x61, 0x64, 0x20, 0x74, 0x6F, 0x20, 0x6D, 0x61, 0x6B,
+	  0x65, 0x20, 0x69, 0x74, 0x20, 0x64, 0x6F, 0x20, 0x6D, 0x6F,
+	  0x72, 0x65, 0x20, 0x74, 0x68, 0x61, 0x6E, 0x20, 0x6F, 0x6E,
+	  0x65, 0x20, 0x69, 0x74, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6F,
+	  0x6E };
+
+    int		i;
+    lwip_sha1_context	sha1Context;
+    u_char	Digest[SHA1_SIGNATURE_SIZE];
+    u_char	Challenge[8];
+
+    lwip_sha1_init(&sha1Context);
+    lwip_sha1_starts(&sha1Context);
+    lwip_sha1_update(&sha1Context, PasswordHashHash, MD4_SIGNATURE_SIZE);
+    lwip_sha1_update(&sha1Context, NTResponse, 24);
+    lwip_sha1_update(&sha1Context, Magic1, sizeof(Magic1));
+    lwip_sha1_finish(&sha1Context, Digest);
+    lwip_sha1_free(&sha1Context);
+
+    ChallengeHash(PeerChallenge, rchallenge, username, Challenge);
+
+    lwip_sha1_init(&sha1Context);
+    lwip_sha1_starts(&sha1Context);
+    lwip_sha1_update(&sha1Context, Digest, sizeof(Digest));
+    lwip_sha1_update(&sha1Context, Challenge, sizeof(Challenge));
+    lwip_sha1_update(&sha1Context, Magic2, sizeof(Magic2));
+    lwip_sha1_finish(&sha1Context, Digest);
+    lwip_sha1_free(&sha1Context);
+
+    /* Convert to ASCII hex string. */
+    for (i = 0; i < LWIP_MAX((MS_AUTH_RESPONSE_LENGTH / 2), (int)sizeof(Digest)); i++)
+	sprintf((char *)&authResponse[i * 2], "%02X", Digest[i]);
+}
+
+
+static void GenerateAuthenticatorResponsePlain(
+		 const char *secret, int secret_len,
+		 u_char NTResponse[24], const u_char PeerChallenge[16],
+		 const u_char *rchallenge, const char *username,
+		 u_char authResponse[MS_AUTH_RESPONSE_LENGTH+1]) {
+    u_char	unicodePassword[MAX_NT_PASSWORD * 2];
+    u_char	PasswordHash[MD4_SIGNATURE_SIZE];
+    u_char	PasswordHashHash[MD4_SIGNATURE_SIZE];
+
+    /* Hash (x2) the Unicode version of the secret (== password). */
+    ascii2unicode(secret, secret_len, unicodePassword);
+    NTPasswordHash(unicodePassword, secret_len * 2, PasswordHash);
+    NTPasswordHash(PasswordHash, sizeof(PasswordHash),
+		   PasswordHashHash);
+
+    GenerateAuthenticatorResponse(PasswordHashHash, NTResponse, PeerChallenge,
+				  rchallenge, username, authResponse);
+}
+
+
+#if MPPE_SUPPORT
+/*
+ * Set mppe_xxxx_key from MS-CHAP credentials. (see RFC 3079)
+ */
+static void Set_Start_Key(ppp_pcb *pcb, const u_char *rchallenge, const char *secret, int secret_len) {
+    u_char	unicodePassword[MAX_NT_PASSWORD * 2];
+    u_char	PasswordHash[MD4_SIGNATURE_SIZE];
+    u_char	PasswordHashHash[MD4_SIGNATURE_SIZE];
+    lwip_sha1_context	sha1Context;
+    u_char	Digest[SHA1_SIGNATURE_SIZE];	/* >= MPPE_MAX_KEY_LEN */
+
+    /* Hash (x2) the Unicode version of the secret (== password). */
+    ascii2unicode(secret, secret_len, unicodePassword);
+    NTPasswordHash(unicodePassword, secret_len * 2, PasswordHash);
+    NTPasswordHash(PasswordHash, sizeof(PasswordHash), PasswordHashHash);
+
+    lwip_sha1_init(&sha1Context);
+    lwip_sha1_starts(&sha1Context);
+    lwip_sha1_update(&sha1Context, PasswordHashHash, MD4_SIGNATURE_SIZE);
+    lwip_sha1_update(&sha1Context, PasswordHashHash, MD4_SIGNATURE_SIZE);
+    lwip_sha1_update(&sha1Context, rchallenge, 8);
+    lwip_sha1_finish(&sha1Context, Digest);
+    lwip_sha1_free(&sha1Context);
+
+    /* Same key in both directions. */
+    mppe_set_key(pcb, &pcb->mppe_comp, Digest);
+    mppe_set_key(pcb, &pcb->mppe_decomp, Digest);
+
+    pcb->mppe_keys_set = 1;
+}
+
+/*
+ * Set mppe_xxxx_key from MS-CHAPv2 credentials. (see RFC 3079)
+ */
+static void SetMasterKeys(ppp_pcb *pcb, const char *secret, int secret_len, u_char NTResponse[24], int IsServer) {
+    u_char	unicodePassword[MAX_NT_PASSWORD * 2];
+    u_char	PasswordHash[MD4_SIGNATURE_SIZE];
+    u_char	PasswordHashHash[MD4_SIGNATURE_SIZE];
+    lwip_sha1_context	sha1Context;
+    u_char	MasterKey[SHA1_SIGNATURE_SIZE];	/* >= MPPE_MAX_KEY_LEN */
+    u_char	Digest[SHA1_SIGNATURE_SIZE];	/* >= MPPE_MAX_KEY_LEN */
+    const u_char *s;
+
+    /* "This is the MPPE Master Key" */
+    static const u_char Magic1[27] =
+	{ 0x54, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, 0x20, 0x74,
+	  0x68, 0x65, 0x20, 0x4d, 0x50, 0x50, 0x45, 0x20, 0x4d,
+	  0x61, 0x73, 0x74, 0x65, 0x72, 0x20, 0x4b, 0x65, 0x79 };
+    /* "On the client side, this is the send key; "
+       "on the server side, it is the receive key." */
+    static const u_char Magic2[84] =
+	{ 0x4f, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x6c, 0x69,
+	  0x65, 0x6e, 0x74, 0x20, 0x73, 0x69, 0x64, 0x65, 0x2c, 0x20,
+	  0x74, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, 0x20, 0x74, 0x68,
+	  0x65, 0x20, 0x73, 0x65, 0x6e, 0x64, 0x20, 0x6b, 0x65, 0x79,
+	  0x3b, 0x20, 0x6f, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x73,
+	  0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x73, 0x69, 0x64, 0x65,
+	  0x2c, 0x20, 0x69, 0x74, 0x20, 0x69, 0x73, 0x20, 0x74, 0x68,
+	  0x65, 0x20, 0x72, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x20,
+	  0x6b, 0x65, 0x79, 0x2e };
+    /* "On the client side, this is the receive key; "
+       "on the server side, it is the send key." */
+    static const u_char Magic3[84] =
+	{ 0x4f, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x6c, 0x69,
+	  0x65, 0x6e, 0x74, 0x20, 0x73, 0x69, 0x64, 0x65, 0x2c, 0x20,
+	  0x74, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, 0x20, 0x74, 0x68,
+	  0x65, 0x20, 0x72, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x20,
+	  0x6b, 0x65, 0x79, 0x3b, 0x20, 0x6f, 0x6e, 0x20, 0x74, 0x68,
+	  0x65, 0x20, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x73,
+	  0x69, 0x64, 0x65, 0x2c, 0x20, 0x69, 0x74, 0x20, 0x69, 0x73,
+	  0x20, 0x74, 0x68, 0x65, 0x20, 0x73, 0x65, 0x6e, 0x64, 0x20,
+	  0x6b, 0x65, 0x79, 0x2e };
+
+    /* Hash (x2) the Unicode version of the secret (== password). */
+    ascii2unicode(secret, secret_len, unicodePassword);
+    NTPasswordHash(unicodePassword, secret_len * 2, PasswordHash);
+    NTPasswordHash(PasswordHash, sizeof(PasswordHash), PasswordHashHash);
+
+    lwip_sha1_init(&sha1Context);
+    lwip_sha1_starts(&sha1Context);
+    lwip_sha1_update(&sha1Context, PasswordHashHash, MD4_SIGNATURE_SIZE);
+    lwip_sha1_update(&sha1Context, NTResponse, 24);
+    lwip_sha1_update(&sha1Context, Magic1, sizeof(Magic1));
+    lwip_sha1_finish(&sha1Context, MasterKey);
+    lwip_sha1_free(&sha1Context);
+
+    /*
+     * generate send key
+     */
+    if (IsServer)
+	s = Magic3;
+    else
+	s = Magic2;
+    lwip_sha1_init(&sha1Context);
+    lwip_sha1_starts(&sha1Context);
+    lwip_sha1_update(&sha1Context, MasterKey, 16);
+    lwip_sha1_update(&sha1Context, mppe_sha1_pad1, SHA1_PAD_SIZE);
+    lwip_sha1_update(&sha1Context, s, 84);
+    lwip_sha1_update(&sha1Context, mppe_sha1_pad2, SHA1_PAD_SIZE);
+    lwip_sha1_finish(&sha1Context, Digest);
+    lwip_sha1_free(&sha1Context);
+
+    mppe_set_key(pcb, &pcb->mppe_comp, Digest);
+
+    /*
+     * generate recv key
+     */
+    if (IsServer)
+	s = Magic2;
+    else
+	s = Magic3;
+    lwip_sha1_init(&sha1Context);
+    lwip_sha1_starts(&sha1Context);
+    lwip_sha1_update(&sha1Context, MasterKey, 16);
+    lwip_sha1_update(&sha1Context, mppe_sha1_pad1, SHA1_PAD_SIZE);
+    lwip_sha1_update(&sha1Context, s, 84);
+    lwip_sha1_update(&sha1Context, mppe_sha1_pad2, SHA1_PAD_SIZE);
+    lwip_sha1_finish(&sha1Context, Digest);
+    lwip_sha1_free(&sha1Context);
+
+    mppe_set_key(pcb, &pcb->mppe_decomp, Digest);
+
+    pcb->mppe_keys_set = 1;
+}
+
+#endif /* MPPE_SUPPORT */
+
+
+static void ChapMS(ppp_pcb *pcb, const u_char *rchallenge, const char *secret, int secret_len,
+       unsigned char *response) {
+#if !MPPE_SUPPORT
+    LWIP_UNUSED_ARG(pcb);
+#endif /* !MPPE_SUPPORT */
+    BZERO(response, MS_CHAP_RESPONSE_LEN);
+
+    ChapMS_NT(rchallenge, secret, secret_len, &response[MS_CHAP_NTRESP]);
+
+#ifdef MSLANMAN
+    ChapMS_LANMan(rchallenge, secret, secret_len,
+		  &response[MS_CHAP_LANMANRESP]);
+
+    /* preferred method is set by option  */
+    response[MS_CHAP_USENT] = !ms_lanman;
+#else
+    response[MS_CHAP_USENT] = 1;
+#endif
+
+#if MPPE_SUPPORT
+    Set_Start_Key(pcb, rchallenge, secret, secret_len);
+#endif /* MPPE_SUPPORT */
+}
+
+
+/*
+ * If PeerChallenge is NULL, one is generated and the PeerChallenge
+ * field of response is filled in.  Call this way when generating a response.
+ * If PeerChallenge is supplied, it is copied into the PeerChallenge field.
+ * Call this way when verifying a response (or debugging).
+ * Do not call with PeerChallenge = response.
+ *
+ * The PeerChallenge field of response is then used for calculation of the
+ * Authenticator Response.
+ */
+static void ChapMS2(ppp_pcb *pcb, const u_char *rchallenge, const u_char *PeerChallenge,
+	const char *user, const char *secret, int secret_len, unsigned char *response,
+	u_char authResponse[], int authenticator) {
+    /* ARGSUSED */
+    LWIP_UNUSED_ARG(authenticator);
+#if !MPPE_SUPPORT
+    LWIP_UNUSED_ARG(pcb);
+#endif /* !MPPE_SUPPORT */
+
+    BZERO(response, MS_CHAP2_RESPONSE_LEN);
+
+    /* Generate the Peer-Challenge if requested, or copy it if supplied. */
+    if (!PeerChallenge)
+	magic_random_bytes(&response[MS_CHAP2_PEER_CHALLENGE], MS_CHAP2_PEER_CHAL_LEN);
+    else
+	MEMCPY(&response[MS_CHAP2_PEER_CHALLENGE], PeerChallenge,
+	      MS_CHAP2_PEER_CHAL_LEN);
+
+    /* Generate the NT-Response */
+    ChapMS2_NT(rchallenge, &response[MS_CHAP2_PEER_CHALLENGE], user,
+	       secret, secret_len, &response[MS_CHAP2_NTRESP]);
+
+    /* Generate the Authenticator Response. */
+    GenerateAuthenticatorResponsePlain(secret, secret_len,
+				       &response[MS_CHAP2_NTRESP],
+				       &response[MS_CHAP2_PEER_CHALLENGE],
+				       rchallenge, user, authResponse);
+
+#if MPPE_SUPPORT
+    SetMasterKeys(pcb, secret, secret_len,
+		  &response[MS_CHAP2_NTRESP], authenticator);
+#endif /* MPPE_SUPPORT */
+}
+
+#if 0 /* UNUSED */
+#if MPPE_SUPPORT
+/*
+ * Set MPPE options from plugins.
+ */
+void set_mppe_enc_types(int policy, int types) {
+    /* Early exit for unknown policies. */
+    if (policy != MPPE_ENC_POL_ENC_ALLOWED ||
+	policy != MPPE_ENC_POL_ENC_REQUIRED)
+	return;
+
+    /* Don't modify MPPE if it's optional and wasn't already configured. */
+    if (policy == MPPE_ENC_POL_ENC_ALLOWED && !ccp_wantoptions[0].mppe)
+	return;
+
+    /*
+     * Disable undesirable encryption types.  Note that we don't ENABLE
+     * any encryption types, to avoid overriding manual configuration.
+     */
+    switch(types) {
+	case MPPE_ENC_TYPES_RC4_40:
+	    ccp_wantoptions[0].mppe &= ~MPPE_OPT_128;	/* disable 128-bit */
+	    break;
+	case MPPE_ENC_TYPES_RC4_128:
+	    ccp_wantoptions[0].mppe &= ~MPPE_OPT_40;	/* disable 40-bit */
+	    break;
+	default:
+	    break;
+    }
+}
+#endif /* MPPE_SUPPORT */
+#endif /* UNUSED */
+
+const struct chap_digest_type chapms_digest = {
+	CHAP_MICROSOFT,		/* code */
+#if PPP_SERVER
+	chapms_generate_challenge,
+	chapms_verify_response,
+#endif /* PPP_SERVER */
+	chapms_make_response,
+	NULL,			/* check_success */
+	chapms_handle_failure,
+};
+
+const struct chap_digest_type chapms2_digest = {
+	CHAP_MICROSOFT_V2,	/* code */
+#if PPP_SERVER
+	chapms2_generate_challenge,
+	chapms2_verify_response,
+#endif /* PPP_SERVER */
+	chapms2_make_response,
+	chapms2_check_success,
+	chapms_handle_failure,
+};
+
+#endif /* PPP_SUPPORT && MSCHAP_SUPPORT */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/netif/ppp/demand.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/netif/ppp/demand.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/netif/ppp/demand.c	(revision 457)
@@ -0,0 +1,465 @@
+/*
+ * demand.c - Support routines for demand-dialling.
+ *
+ * Copyright (c) 1996-2002 Paul Mackerras. 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. The name(s) of the authors of this software must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission.
+ *
+ * 3. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by Paul Mackerras
+ *     <paulus@samba.org>".
+ *
+ * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO
+ * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
+ * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
+ * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
+ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include "netif/ppp/ppp_opts.h"
+#if PPP_SUPPORT && DEMAND_SUPPORT  /* don't build if not configured for use in lwipopts.h */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <netdb.h>
+#include <unistd.h>
+#include <syslog.h>
+#include <sys/param.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <sys/time.h>
+#include <sys/resource.h>
+#include <sys/stat.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#ifdef PPP_FILTER
+#include <pcap-bpf.h>
+#endif
+
+#include "netif/ppp/ppp_impl.h"
+
+#include "netif/ppp/fsm.h"
+#include "netif/ppp/ipcp.h"
+#include "netif/ppp/lcp.h"
+
+char *frame;
+int framelen;
+int framemax;
+int escape_flag;
+int flush_flag;
+int fcs;
+
+struct packet {
+    int length;
+    struct packet *next;
+    unsigned char data[1];
+};
+
+struct packet *pend_q;
+struct packet *pend_qtail;
+
+static int active_packet (unsigned char *, int);
+
+/*
+ * demand_conf - configure the interface for doing dial-on-demand.
+ */
+void
+demand_conf()
+{
+    int i;
+    const struct protent *protp;
+
+/*    framemax = lcp_allowoptions[0].mru;
+    if (framemax < PPP_MRU) */
+	framemax = PPP_MRU;
+    framemax += PPP_HDRLEN + PPP_FCSLEN;
+    frame = malloc(framemax);
+    if (frame == NULL)
+	novm("demand frame");
+    framelen = 0;
+    pend_q = NULL;
+    escape_flag = 0;
+    flush_flag = 0;
+    fcs = PPP_INITFCS;
+
+    netif_set_mtu(pcb, LWIP_MIN(lcp_allowoptions[0].mru, PPP_MRU));
+    if (ppp_send_config(pcb, PPP_MRU, (u32_t) 0, 0, 0) < 0
+	|| ppp_recv_config(pcb, PPP_MRU, (u32_t) 0, 0, 0) < 0)
+	    fatal("Couldn't set up demand-dialled PPP interface: %m");
+
+#ifdef PPP_FILTER
+    set_filters(&pass_filter, &active_filter);
+#endif
+
+    /*
+     * Call the demand_conf procedure for each protocol that's got one.
+     */
+    for (i = 0; (protp = protocols[i]) != NULL; ++i)
+	if (protp->demand_conf != NULL)
+	    ((*protp->demand_conf)(pcb));
+/* FIXME: find a way to die() here */
+#if 0
+	    if (!((*protp->demand_conf)(pcb)))
+		die(1);
+#endif
+}
+
+
+/*
+ * demand_block - set each network protocol to block further packets.
+ */
+void
+demand_block()
+{
+    int i;
+    const struct protent *protp;
+
+    for (i = 0; (protp = protocols[i]) != NULL; ++i)
+	if (protp->demand_conf != NULL)
+	    sifnpmode(pcb, protp->protocol & ~0x8000, NPMODE_QUEUE);
+    get_loop_output();
+}
+
+/*
+ * demand_discard - set each network protocol to discard packets
+ * with an error.
+ */
+void
+demand_discard()
+{
+    struct packet *pkt, *nextpkt;
+    int i;
+    const struct protent *protp;
+
+    for (i = 0; (protp = protocols[i]) != NULL; ++i)
+	if (protp->demand_conf != NULL)
+	    sifnpmode(pcb, protp->protocol & ~0x8000, NPMODE_ERROR);
+    get_loop_output();
+
+    /* discard all saved packets */
+    for (pkt = pend_q; pkt != NULL; pkt = nextpkt) {
+	nextpkt = pkt->next;
+	free(pkt);
+    }
+    pend_q = NULL;
+    framelen = 0;
+    flush_flag = 0;
+    escape_flag = 0;
+    fcs = PPP_INITFCS;
+}
+
+/*
+ * demand_unblock - set each enabled network protocol to pass packets.
+ */
+void
+demand_unblock()
+{
+    int i;
+    const struct protent *protp;
+
+    for (i = 0; (protp = protocols[i]) != NULL; ++i)
+	if (protp->demand_conf != NULL)
+	    sifnpmode(pcb, protp->protocol & ~0x8000, NPMODE_PASS);
+}
+
+/*
+ * FCS lookup table as calculated by genfcstab.
+ */
+static u_short fcstab[256] = {
+	0x0000,	0x1189,	0x2312,	0x329b,	0x4624,	0x57ad,	0x6536,	0x74bf,
+	0x8c48,	0x9dc1,	0xaf5a,	0xbed3,	0xca6c,	0xdbe5,	0xe97e,	0xf8f7,
+	0x1081,	0x0108,	0x3393,	0x221a,	0x56a5,	0x472c,	0x75b7,	0x643e,
+	0x9cc9,	0x8d40,	0xbfdb,	0xae52,	0xdaed,	0xcb64,	0xf9ff,	0xe876,
+	0x2102,	0x308b,	0x0210,	0x1399,	0x6726,	0x76af,	0x4434,	0x55bd,
+	0xad4a,	0xbcc3,	0x8e58,	0x9fd1,	0xeb6e,	0xfae7,	0xc87c,	0xd9f5,
+	0x3183,	0x200a,	0x1291,	0x0318,	0x77a7,	0x662e,	0x54b5,	0x453c,
+	0xbdcb,	0xac42,	0x9ed9,	0x8f50,	0xfbef,	0xea66,	0xd8fd,	0xc974,
+	0x4204,	0x538d,	0x6116,	0x709f,	0x0420,	0x15a9,	0x2732,	0x36bb,
+	0xce4c,	0xdfc5,	0xed5e,	0xfcd7,	0x8868,	0x99e1,	0xab7a,	0xbaf3,
+	0x5285,	0x430c,	0x7197,	0x601e,	0x14a1,	0x0528,	0x37b3,	0x263a,
+	0xdecd,	0xcf44,	0xfddf,	0xec56,	0x98e9,	0x8960,	0xbbfb,	0xaa72,
+	0x6306,	0x728f,	0x4014,	0x519d,	0x2522,	0x34ab,	0x0630,	0x17b9,
+	0xef4e,	0xfec7,	0xcc5c,	0xddd5,	0xa96a,	0xb8e3,	0x8a78,	0x9bf1,
+	0x7387,	0x620e,	0x5095,	0x411c,	0x35a3,	0x242a,	0x16b1,	0x0738,
+	0xffcf,	0xee46,	0xdcdd,	0xcd54,	0xb9eb,	0xa862,	0x9af9,	0x8b70,
+	0x8408,	0x9581,	0xa71a,	0xb693,	0xc22c,	0xd3a5,	0xe13e,	0xf0b7,
+	0x0840,	0x19c9,	0x2b52,	0x3adb,	0x4e64,	0x5fed,	0x6d76,	0x7cff,
+	0x9489,	0x8500,	0xb79b,	0xa612,	0xd2ad,	0xc324,	0xf1bf,	0xe036,
+	0x18c1,	0x0948,	0x3bd3,	0x2a5a,	0x5ee5,	0x4f6c,	0x7df7,	0x6c7e,
+	0xa50a,	0xb483,	0x8618,	0x9791,	0xe32e,	0xf2a7,	0xc03c,	0xd1b5,
+	0x2942,	0x38cb,	0x0a50,	0x1bd9,	0x6f66,	0x7eef,	0x4c74,	0x5dfd,
+	0xb58b,	0xa402,	0x9699,	0x8710,	0xf3af,	0xe226,	0xd0bd,	0xc134,
+	0x39c3,	0x284a,	0x1ad1,	0x0b58,	0x7fe7,	0x6e6e,	0x5cf5,	0x4d7c,
+	0xc60c,	0xd785,	0xe51e,	0xf497,	0x8028,	0x91a1,	0xa33a,	0xb2b3,
+	0x4a44,	0x5bcd,	0x6956,	0x78df,	0x0c60,	0x1de9,	0x2f72,	0x3efb,
+	0xd68d,	0xc704,	0xf59f,	0xe416,	0x90a9,	0x8120,	0xb3bb,	0xa232,
+	0x5ac5,	0x4b4c,	0x79d7,	0x685e,	0x1ce1,	0x0d68,	0x3ff3,	0x2e7a,
+	0xe70e,	0xf687,	0xc41c,	0xd595,	0xa12a,	0xb0a3,	0x8238,	0x93b1,
+	0x6b46,	0x7acf,	0x4854,	0x59dd,	0x2d62,	0x3ceb,	0x0e70,	0x1ff9,
+	0xf78f,	0xe606,	0xd49d,	0xc514,	0xb1ab,	0xa022,	0x92b9,	0x8330,
+	0x7bc7,	0x6a4e,	0x58d5,	0x495c,	0x3de3,	0x2c6a,	0x1ef1,	0x0f78
+};
+
+/*
+ * loop_chars - process characters received from the loopback.
+ * Calls loop_frame when a complete frame has been accumulated.
+ * Return value is 1 if we need to bring up the link, 0 otherwise.
+ */
+int
+loop_chars(p, n)
+    unsigned char *p;
+    int n;
+{
+    int c, rv;
+
+    rv = 0;
+
+/* check for synchronous connection... */
+
+    if ( (p[0] == 0xFF) && (p[1] == 0x03) ) {
+        rv = loop_frame(p,n);
+        return rv;
+    }
+
+    for (; n > 0; --n) {
+	c = *p++;
+	if (c == PPP_FLAG) {
+	    if (!escape_flag && !flush_flag
+		&& framelen > 2 && fcs == PPP_GOODFCS) {
+		framelen -= 2;
+		if (loop_frame((unsigned char *)frame, framelen))
+		    rv = 1;
+	    }
+	    framelen = 0;
+	    flush_flag = 0;
+	    escape_flag = 0;
+	    fcs = PPP_INITFCS;
+	    continue;
+	}
+	if (flush_flag)
+	    continue;
+	if (escape_flag) {
+	    c ^= PPP_TRANS;
+	    escape_flag = 0;
+	} else if (c == PPP_ESCAPE) {
+	    escape_flag = 1;
+	    continue;
+	}
+	if (framelen >= framemax) {
+	    flush_flag = 1;
+	    continue;
+	}
+	frame[framelen++] = c;
+	fcs = PPP_FCS(fcs, c);
+    }
+    return rv;
+}
+
+/*
+ * loop_frame - given a frame obtained from the loopback,
+ * decide whether to bring up the link or not, and, if we want
+ * to transmit this frame later, put it on the pending queue.
+ * Return value is 1 if we need to bring up the link, 0 otherwise.
+ * We assume that the kernel driver has already applied the
+ * pass_filter, so we won't get packets it rejected.
+ * We apply the active_filter to see if we want this packet to
+ * bring up the link.
+ */
+int
+loop_frame(frame, len)
+    unsigned char *frame;
+    int len;
+{
+    struct packet *pkt;
+
+    /* dbglog("from loop: %P", frame, len); */
+    if (len < PPP_HDRLEN)
+	return 0;
+    if ((PPP_PROTOCOL(frame) & 0x8000) != 0)
+	return 0;		/* shouldn't get any of these anyway */
+    if (!active_packet(frame, len))
+	return 0;
+
+    pkt = (struct packet *) malloc(sizeof(struct packet) + len);
+    if (pkt != NULL) {
+	pkt->length = len;
+	pkt->next = NULL;
+	memcpy(pkt->data, frame, len);
+	if (pend_q == NULL)
+	    pend_q = pkt;
+	else
+	    pend_qtail->next = pkt;
+	pend_qtail = pkt;
+    }
+    return 1;
+}
+
+/*
+ * demand_rexmit - Resend all those frames which we got via the
+ * loopback, now that the real serial link is up.
+ */
+void
+demand_rexmit(proto, newip)
+    int proto;
+    u32_t newip;
+{
+    struct packet *pkt, *prev, *nextpkt;
+    unsigned short checksum;
+    unsigned short pkt_checksum = 0;
+    unsigned iphdr;
+    struct timeval tv;
+    char cv = 0;
+    char ipstr[16];
+
+    prev = NULL;
+    pkt = pend_q;
+    pend_q = NULL;
+    tv.tv_sec = 1;
+    tv.tv_usec = 0;
+    select(0,NULL,NULL,NULL,&tv);	/* Sleep for 1 Seconds */
+    for (; pkt != NULL; pkt = nextpkt) {
+	nextpkt = pkt->next;
+	if (PPP_PROTOCOL(pkt->data) == proto) {
+            if ( (proto == PPP_IP) && newip ) {
+		/* Get old checksum */
+
+		iphdr = (pkt->data[4] & 15) << 2;
+		checksum = *((unsigned short *) (pkt->data+14));
+                if (checksum == 0xFFFF) {
+                    checksum = 0;
+                }
+
+ 
+                if (pkt->data[13] == 17) {
+                    pkt_checksum =  *((unsigned short *) (pkt->data+10+iphdr));
+		    if (pkt_checksum) {
+                        cv = 1;
+                        if (pkt_checksum == 0xFFFF) {
+                            pkt_checksum = 0;
+                        }
+                    }
+                    else {
+                       cv = 0;
+                    }
+                }
+
+		if (pkt->data[13] == 6) {
+		    pkt_checksum = *((unsigned short *) (pkt->data+20+iphdr));
+		    cv = 1;
+                    if (pkt_checksum == 0xFFFF) {
+                        pkt_checksum = 0;
+                    }
+		}
+
+		/* Delete old Source-IP-Address */
+                checksum -= *((unsigned short *) (pkt->data+16)) ^ 0xFFFF;
+                checksum -= *((unsigned short *) (pkt->data+18)) ^ 0xFFFF;
+
+		pkt_checksum -= *((unsigned short *) (pkt->data+16)) ^ 0xFFFF;
+		pkt_checksum -= *((unsigned short *) (pkt->data+18)) ^ 0xFFFF;
+
+		/* Change Source-IP-Address */
+                * ((u32_t *) (pkt->data + 16)) = newip;
+
+		/* Add new Source-IP-Address */
+                checksum += *((unsigned short *) (pkt->data+16)) ^ 0xFFFF;
+                checksum += *((unsigned short *) (pkt->data+18)) ^ 0xFFFF;
+
+                pkt_checksum += *((unsigned short *) (pkt->data+16)) ^ 0xFFFF;
+                pkt_checksum += *((unsigned short *) (pkt->data+18)) ^ 0xFFFF;
+
+		/* Write new checksum */
+                if (!checksum) {
+                    checksum = 0xFFFF;
+                }
+                *((unsigned short *) (pkt->data+14)) = checksum;
+		if (pkt->data[13] == 6) {
+		    *((unsigned short *) (pkt->data+20+iphdr)) = pkt_checksum;
+		}
+		if (cv && (pkt->data[13] == 17) ) {
+		    *((unsigned short *) (pkt->data+10+iphdr)) = pkt_checksum;
+		}
+
+		/* Log Packet */
+		strcpy(ipstr,inet_ntoa(*( (struct in_addr *) (pkt->data+16))));
+		if (pkt->data[13] == 1) {
+		    syslog(LOG_INFO,"Open ICMP %s -> %s\n",
+			ipstr,
+			inet_ntoa(*( (struct in_addr *) (pkt->data+20))));
+		} else {
+		    syslog(LOG_INFO,"Open %s %s:%d -> %s:%d\n",
+			pkt->data[13] == 6 ? "TCP" : "UDP",
+			ipstr,
+			ntohs(*( (short *) (pkt->data+iphdr+4))),
+			inet_ntoa(*( (struct in_addr *) (pkt->data+20))),
+			ntohs(*( (short *) (pkt->data+iphdr+6))));
+                }
+            }
+	    output(pcb, pkt->data, pkt->length);
+	    free(pkt);
+	} else {
+	    if (prev == NULL)
+		pend_q = pkt;
+	    else
+		prev->next = pkt;
+	    prev = pkt;
+	}
+    }
+    pend_qtail = prev;
+    if (prev != NULL)
+	prev->next = NULL;
+}
+
+/*
+ * Scan a packet to decide whether it is an "active" packet,
+ * that is, whether it is worth bringing up the link for.
+ */
+static int
+active_packet(p, len)
+    unsigned char *p;
+    int len;
+{
+    int proto, i;
+    const struct protent *protp;
+
+    if (len < PPP_HDRLEN)
+	return 0;
+    proto = PPP_PROTOCOL(p);
+#ifdef PPP_FILTER
+    p[0] = 1;		/* outbound packet indicator */
+    if ((pass_filter.bf_len != 0
+	 && bpf_filter(pass_filter.bf_insns, p, len, len) == 0)
+	|| (active_filter.bf_len != 0
+	    && bpf_filter(active_filter.bf_insns, p, len, len) == 0)) {
+	p[0] = 0xff;
+	return 0;
+    }
+    p[0] = 0xff;
+#endif
+    for (i = 0; (protp = protocols[i]) != NULL; ++i) {
+	if (protp->protocol < 0xC000 && (protp->protocol & ~0x8000) == proto) {
+	    if (protp->active_pkt == NULL)
+		return 1;
+	    return (*protp->active_pkt)(p, len);
+	}
+    }
+    return 0;			/* not a supported protocol !!?? */
+}
+
+#endif /* PPP_SUPPORT && DEMAND_SUPPORT */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/netif/ppp/eap.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/netif/ppp/eap.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/netif/ppp/eap.c	(revision 457)
@@ -0,0 +1,2423 @@
+/*
+ * eap.c - Extensible Authentication Protocol for PPP (RFC 2284)
+ *
+ * Copyright (c) 2001 by Sun Microsystems, Inc.
+ * All rights reserved.
+ *
+ * Non-exclusive rights to redistribute, modify, translate, and use
+ * this software in source and binary forms, in whole or in part, is
+ * hereby granted, provided that the above copyright notice is
+ * duplicated in any source form, and that neither the name of the
+ * copyright holder nor the author is used to endorse or promote
+ * products derived from this software.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * Original version by James Carlson
+ *
+ * This implementation of EAP supports MD5-Challenge and SRP-SHA1
+ * authentication styles.  Note that support of MD5-Challenge is a
+ * requirement of RFC 2284, and that it's essentially just a
+ * reimplementation of regular RFC 1994 CHAP using EAP messages.
+ *
+ * As an authenticator ("server"), there are multiple phases for each
+ * style.  In the first phase of each style, the unauthenticated peer
+ * name is queried using the EAP Identity request type.  If the
+ * "remotename" option is used, then this phase is skipped, because
+ * the peer's name is presumed to be known.
+ *
+ * For MD5-Challenge, there are two phases, and the second phase
+ * consists of sending the challenge itself and handling the
+ * associated response.
+ *
+ * For SRP-SHA1, there are four phases.  The second sends 's', 'N',
+ * and 'g'.  The reply contains 'A'.  The third sends 'B', and the
+ * reply contains 'M1'.  The forth sends the 'M2' value.
+ *
+ * As an authenticatee ("client"), there's just a single phase --
+ * responding to the queries generated by the peer.  EAP is an
+ * authenticator-driven protocol.
+ *
+ * Based on draft-ietf-pppext-eap-srp-03.txt.
+ */
+
+#include "netif/ppp/ppp_opts.h"
+#if PPP_SUPPORT && EAP_SUPPORT  /* don't build if not configured for use in lwipopts.h */
+
+#include "netif/ppp/ppp_impl.h"
+#include "netif/ppp/eap.h"
+#include "netif/ppp/magic.h"
+#include "netif/ppp/pppcrypt.h"
+
+#ifdef USE_SRP
+#include <t_pwd.h>
+#include <t_server.h>
+#include <t_client.h>
+#endif /* USE_SRP */
+
+#ifndef SHA_DIGESTSIZE
+#define	SHA_DIGESTSIZE 20
+#endif
+
+#ifdef USE_SRP
+static char *pn_secret = NULL;		/* Pseudonym generating secret */
+#endif
+
+#if PPP_OPTIONS
+/*
+ * Command-line options.
+ */
+static option_t eap_option_list[] = {
+    { "eap-restart", o_int, &eap_states[0].es_server.ea_timeout,
+      "Set retransmit timeout for EAP Requests (server)" },
+    { "eap-max-sreq", o_int, &eap_states[0].es_server.ea_maxrequests,
+      "Set max number of EAP Requests sent (server)" },
+    { "eap-timeout", o_int, &eap_states[0].es_client.ea_timeout,
+      "Set time limit for peer EAP authentication" },
+    { "eap-max-rreq", o_int, &eap_states[0].es_client.ea_maxrequests,
+      "Set max number of EAP Requests allows (client)" },
+    { "eap-interval", o_int, &eap_states[0].es_rechallenge,
+      "Set interval for EAP rechallenge" },
+#ifdef USE_SRP
+    { "srp-interval", o_int, &eap_states[0].es_lwrechallenge,
+      "Set interval for SRP lightweight rechallenge" },
+    { "srp-pn-secret", o_string, &pn_secret,
+      "Long term pseudonym generation secret" },
+    { "srp-use-pseudonym", o_bool, &eap_states[0].es_usepseudo,
+      "Use pseudonym if offered one by server", 1 },
+#endif
+    { NULL }
+};
+#endif /* PPP_OPTIONS */
+
+/*
+ * Protocol entry points.
+ */
+static void eap_init(ppp_pcb *pcb);
+static void eap_input(ppp_pcb *pcb, u_char *inp, int inlen);
+static void eap_protrej(ppp_pcb *pcb);
+static void eap_lowerup(ppp_pcb *pcb);
+static void eap_lowerdown(ppp_pcb *pcb);
+#if PRINTPKT_SUPPORT
+static int  eap_printpkt(const u_char *inp, int inlen,
+    void (*)(void *arg, const char *fmt, ...), void *arg);
+#endif /* PRINTPKT_SUPPORT */
+
+const struct protent eap_protent = {
+	PPP_EAP,		/* protocol number */
+	eap_init,		/* initialization procedure */
+	eap_input,		/* process a received packet */
+	eap_protrej,		/* process a received protocol-reject */
+	eap_lowerup,		/* lower layer has gone up */
+	eap_lowerdown,		/* lower layer has gone down */
+	NULL,			/* open the protocol */
+	NULL,			/* close the protocol */
+#if PRINTPKT_SUPPORT
+	eap_printpkt,		/* print a packet in readable form */
+#endif /* PRINTPKT_SUPPORT */
+#if PPP_DATAINPUT
+	NULL,			/* process a received data packet */
+#endif /* PPP_DATAINPUT */
+#if PRINTPKT_SUPPORT
+	"EAP",			/* text name of protocol */
+	NULL,			/* text name of corresponding data protocol */
+#endif /* PRINTPKT_SUPPORT */
+#if PPP_OPTIONS
+	eap_option_list,	/* list of command-line options */
+	NULL,			/* check requested options; assign defaults */
+#endif /* PPP_OPTIONS */
+#if DEMAND_SUPPORT
+	NULL,			/* configure interface for demand-dial */
+	NULL			/* say whether to bring up link for this pkt */
+#endif /* DEMAND_SUPPORT */
+};
+
+#ifdef USE_SRP
+/*
+ * A well-known 2048 bit modulus.
+ */
+static const u_char wkmodulus[] = {
+	0xAC, 0x6B, 0xDB, 0x41, 0x32, 0x4A, 0x9A, 0x9B,
+	0xF1, 0x66, 0xDE, 0x5E, 0x13, 0x89, 0x58, 0x2F,
+	0xAF, 0x72, 0xB6, 0x65, 0x19, 0x87, 0xEE, 0x07,
+	0xFC, 0x31, 0x92, 0x94, 0x3D, 0xB5, 0x60, 0x50,
+	0xA3, 0x73, 0x29, 0xCB, 0xB4, 0xA0, 0x99, 0xED,
+	0x81, 0x93, 0xE0, 0x75, 0x77, 0x67, 0xA1, 0x3D,
+	0xD5, 0x23, 0x12, 0xAB, 0x4B, 0x03, 0x31, 0x0D,
+	0xCD, 0x7F, 0x48, 0xA9, 0xDA, 0x04, 0xFD, 0x50,
+	0xE8, 0x08, 0x39, 0x69, 0xED, 0xB7, 0x67, 0xB0,
+	0xCF, 0x60, 0x95, 0x17, 0x9A, 0x16, 0x3A, 0xB3,
+	0x66, 0x1A, 0x05, 0xFB, 0xD5, 0xFA, 0xAA, 0xE8,
+	0x29, 0x18, 0xA9, 0x96, 0x2F, 0x0B, 0x93, 0xB8,
+	0x55, 0xF9, 0x79, 0x93, 0xEC, 0x97, 0x5E, 0xEA,
+	0xA8, 0x0D, 0x74, 0x0A, 0xDB, 0xF4, 0xFF, 0x74,
+	0x73, 0x59, 0xD0, 0x41, 0xD5, 0xC3, 0x3E, 0xA7,
+	0x1D, 0x28, 0x1E, 0x44, 0x6B, 0x14, 0x77, 0x3B,
+	0xCA, 0x97, 0xB4, 0x3A, 0x23, 0xFB, 0x80, 0x16,
+	0x76, 0xBD, 0x20, 0x7A, 0x43, 0x6C, 0x64, 0x81,
+	0xF1, 0xD2, 0xB9, 0x07, 0x87, 0x17, 0x46, 0x1A,
+	0x5B, 0x9D, 0x32, 0xE6, 0x88, 0xF8, 0x77, 0x48,
+	0x54, 0x45, 0x23, 0xB5, 0x24, 0xB0, 0xD5, 0x7D,
+	0x5E, 0xA7, 0x7A, 0x27, 0x75, 0xD2, 0xEC, 0xFA,
+	0x03, 0x2C, 0xFB, 0xDB, 0xF5, 0x2F, 0xB3, 0x78,
+	0x61, 0x60, 0x27, 0x90, 0x04, 0xE5, 0x7A, 0xE6,
+	0xAF, 0x87, 0x4E, 0x73, 0x03, 0xCE, 0x53, 0x29,
+	0x9C, 0xCC, 0x04, 0x1C, 0x7B, 0xC3, 0x08, 0xD8,
+	0x2A, 0x56, 0x98, 0xF3, 0xA8, 0xD0, 0xC3, 0x82,
+	0x71, 0xAE, 0x35, 0xF8, 0xE9, 0xDB, 0xFB, 0xB6,
+	0x94, 0xB5, 0xC8, 0x03, 0xD8, 0x9F, 0x7A, 0xE4,
+	0x35, 0xDE, 0x23, 0x6D, 0x52, 0x5F, 0x54, 0x75,
+	0x9B, 0x65, 0xE3, 0x72, 0xFC, 0xD6, 0x8E, 0xF2,
+	0x0F, 0xA7, 0x11, 0x1F, 0x9E, 0x4A, 0xFF, 0x73
+};
+#endif
+
+#if PPP_SERVER
+/* Local forward declarations. */
+static void eap_server_timeout(void *arg);
+#endif /* PPP_SERVER */
+
+/*
+ * Convert EAP state code to printable string for debug.
+ */
+static const char * eap_state_name(enum eap_state_code esc)
+{
+	static const char *state_names[] = { EAP_STATES };
+
+	return (state_names[(int)esc]);
+}
+
+/*
+ * eap_init - Initialize state for an EAP user.  This is currently
+ * called once by main() during start-up.
+ */
+static void eap_init(ppp_pcb *pcb) {
+
+	BZERO(&pcb->eap, sizeof(eap_state));
+#if PPP_SERVER
+	pcb->eap.es_server.ea_id = magic();
+#endif /* PPP_SERVER */
+}
+
+/*
+ * eap_client_timeout - Give up waiting for the peer to send any
+ * Request messages.
+ */
+static void eap_client_timeout(void *arg) {
+	ppp_pcb *pcb = (ppp_pcb*)arg;
+
+	if (!eap_client_active(pcb))
+		return;
+
+	ppp_error("EAP: timeout waiting for Request from peer");
+	auth_withpeer_fail(pcb, PPP_EAP);
+	pcb->eap.es_client.ea_state = eapBadAuth;
+}
+
+/*
+ * eap_authwithpeer - Authenticate to our peer (behave as client).
+ *
+ * Start client state and wait for requests.  This is called only
+ * after eap_lowerup.
+ */
+void eap_authwithpeer(ppp_pcb *pcb, const char *localname) {
+
+	if(NULL == localname)
+		return;
+
+	/* Save the peer name we're given */
+	pcb->eap.es_client.ea_name = localname;
+	pcb->eap.es_client.ea_namelen = strlen(localname);
+
+	pcb->eap.es_client.ea_state = eapListen;
+
+	/*
+	 * Start a timer so that if the other end just goes
+	 * silent, we don't sit here waiting forever.
+	 */
+	if (pcb->settings.eap_req_time > 0)
+		TIMEOUT(eap_client_timeout, pcb,
+		    pcb->settings.eap_req_time);
+}
+
+#if PPP_SERVER
+/*
+ * Format a standard EAP Failure message and send it to the peer.
+ * (Server operation)
+ */
+static void eap_send_failure(ppp_pcb *pcb) {
+	struct pbuf *p;
+	u_char *outp;
+
+	p = pbuf_alloc(PBUF_RAW, (u16_t)(PPP_HDRLEN + EAP_HEADERLEN), PPP_CTRL_PBUF_TYPE);
+	if(NULL == p)
+		return;
+	if(p->tot_len != p->len) {
+		pbuf_free(p);
+		return;
+	}
+
+	outp = (u_char*)p->payload;
+
+	MAKEHEADER(outp, PPP_EAP);
+
+	PUTCHAR(EAP_FAILURE, outp);
+	pcb->eap.es_server.ea_id++;
+	PUTCHAR(pcb->eap.es_server.ea_id, outp);
+	PUTSHORT(EAP_HEADERLEN, outp);
+
+	ppp_write(pcb, p);
+
+	pcb->eap.es_server.ea_state = eapBadAuth;
+	auth_peer_fail(pcb, PPP_EAP);
+}
+
+/*
+ * Format a standard EAP Success message and send it to the peer.
+ * (Server operation)
+ */
+static void eap_send_success(ppp_pcb *pcb) {
+	struct pbuf *p;
+	u_char *outp;
+
+	p = pbuf_alloc(PBUF_RAW, (u16_t)(PPP_HDRLEN + EAP_HEADERLEN), PPP_CTRL_PBUF_TYPE);
+	if(NULL == p)
+		return;
+	if(p->tot_len != p->len) {
+		pbuf_free(p);
+		return;
+	}
+
+	outp = (u_char*)p->payload;
+    
+	MAKEHEADER(outp, PPP_EAP);
+
+	PUTCHAR(EAP_SUCCESS, outp);
+	pcb->eap.es_server.ea_id++;
+	PUTCHAR(pcb->eap.es_server.ea_id, outp);
+	PUTSHORT(EAP_HEADERLEN, outp);
+
+	ppp_write(pcb, p);
+
+	auth_peer_success(pcb, PPP_EAP, 0,
+	    pcb->eap.es_server.ea_peer, pcb->eap.es_server.ea_peerlen);
+}
+#endif /* PPP_SERVER */
+
+#ifdef USE_SRP
+/*
+ * Set DES key according to pseudonym-generating secret and current
+ * date.
+ */
+static bool
+pncrypt_setkey(int timeoffs)
+{
+	struct tm *tp;
+	char tbuf[9];
+	SHA1_CTX ctxt;
+	u_char dig[SHA_DIGESTSIZE];
+	time_t reftime;
+
+	if (pn_secret == NULL)
+		return (0);
+	reftime = time(NULL) + timeoffs;
+	tp = localtime(&reftime);
+	SHA1Init(&ctxt);
+	SHA1Update(&ctxt, pn_secret, strlen(pn_secret));
+	strftime(tbuf, sizeof (tbuf), "%Y%m%d", tp);
+	SHA1Update(&ctxt, tbuf, strlen(tbuf));
+	SHA1Final(dig, &ctxt);
+	/* FIXME: if we want to do SRP, we need to find a way to pass the PolarSSL des_context instead of using static memory */
+	return (DesSetkey(dig));
+}
+
+static char base64[] =
+"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+
+struct b64state {
+	u32_t bs_bits;
+	int bs_offs;
+};
+
+static int
+b64enc(bs, inp, inlen, outp)
+struct b64state *bs;
+u_char *inp;
+int inlen;
+u_char *outp;
+{
+	int outlen = 0;
+
+	while (inlen > 0) {
+		bs->bs_bits = (bs->bs_bits << 8) | *inp++;
+		inlen--;
+		bs->bs_offs += 8;
+		if (bs->bs_offs >= 24) {
+			*outp++ = base64[(bs->bs_bits >> 18) & 0x3F];
+			*outp++ = base64[(bs->bs_bits >> 12) & 0x3F];
+			*outp++ = base64[(bs->bs_bits >> 6) & 0x3F];
+			*outp++ = base64[bs->bs_bits & 0x3F];
+			outlen += 4;
+			bs->bs_offs = 0;
+			bs->bs_bits = 0;
+		}
+	}
+	return (outlen);
+}
+
+static int
+b64flush(bs, outp)
+struct b64state *bs;
+u_char *outp;
+{
+	int outlen = 0;
+
+	if (bs->bs_offs == 8) {
+		*outp++ = base64[(bs->bs_bits >> 2) & 0x3F];
+		*outp++ = base64[(bs->bs_bits << 4) & 0x3F];
+		outlen = 2;
+	} else if (bs->bs_offs == 16) {
+		*outp++ = base64[(bs->bs_bits >> 10) & 0x3F];
+		*outp++ = base64[(bs->bs_bits >> 4) & 0x3F];
+		*outp++ = base64[(bs->bs_bits << 2) & 0x3F];
+		outlen = 3;
+	}
+	bs->bs_offs = 0;
+	bs->bs_bits = 0;
+	return (outlen);
+}
+
+static int
+b64dec(bs, inp, inlen, outp)
+struct b64state *bs;
+u_char *inp;
+int inlen;
+u_char *outp;
+{
+	int outlen = 0;
+	char *cp;
+
+	while (inlen > 0) {
+		if ((cp = strchr(base64, *inp++)) == NULL)
+			break;
+		bs->bs_bits = (bs->bs_bits << 6) | (cp - base64);
+		inlen--;
+		bs->bs_offs += 6;
+		if (bs->bs_offs >= 8) {
+			*outp++ = bs->bs_bits >> (bs->bs_offs - 8);
+			outlen++;
+			bs->bs_offs -= 8;
+		}
+	}
+	return (outlen);
+}
+#endif /* USE_SRP */
+
+#if PPP_SERVER
+/*
+ * Assume that current waiting server state is complete and figure
+ * next state to use based on available authentication data.  'status'
+ * indicates if there was an error in handling the last query.  It is
+ * 0 for success and non-zero for failure.
+ */
+static void eap_figure_next_state(ppp_pcb *pcb, int status) {
+#ifdef USE_SRP
+	unsigned char secbuf[MAXSECRETLEN], clear[8], *sp, *dp;
+	struct t_pw tpw;
+	struct t_confent *tce, mytce;
+	char *cp, *cp2;
+	struct t_server *ts;
+	int id, i, plen, toffs;
+	u_char vals[2];
+	struct b64state bs;
+#endif /* USE_SRP */
+
+	pcb->settings.eap_timeout_time = pcb->eap.es_savedtime;
+	switch (pcb->eap.es_server.ea_state) {
+	case eapBadAuth:
+		return;
+
+	case eapIdentify:
+#ifdef USE_SRP
+		/* Discard any previous session. */
+		ts = (struct t_server *)pcb->eap.es_server.ea_session;
+		if (ts != NULL) {
+			t_serverclose(ts);
+			pcb->eap.es_server.ea_session = NULL;
+			pcb->eap.es_server.ea_skey = NULL;
+		}
+#endif /* USE_SRP */
+		if (status != 0) {
+			pcb->eap.es_server.ea_state = eapBadAuth;
+			break;
+		}
+#ifdef USE_SRP
+		/* If we've got a pseudonym, try to decode to real name. */
+		if (pcb->eap.es_server.ea_peerlen > SRP_PSEUDO_LEN &&
+		    strncmp(pcb->eap.es_server.ea_peer, SRP_PSEUDO_ID,
+			SRP_PSEUDO_LEN) == 0 &&
+		    (pcb->eap.es_server.ea_peerlen - SRP_PSEUDO_LEN) * 3 / 4 <
+		    sizeof (secbuf)) {
+			BZERO(&bs, sizeof (bs));
+			plen = b64dec(&bs,
+			    pcb->eap.es_server.ea_peer + SRP_PSEUDO_LEN,
+			    pcb->eap.es_server.ea_peerlen - SRP_PSEUDO_LEN,
+			    secbuf);
+			toffs = 0;
+			for (i = 0; i < 5; i++) {
+				pncrypt_setkey(toffs);
+				toffs -= 86400;
+				/* FIXME: if we want to do SRP, we need to find a way to pass the PolarSSL des_context instead of using static memory */
+				if (!DesDecrypt(secbuf, clear)) {
+					ppp_dbglog("no DES here; cannot decode "
+					    "pseudonym");
+					return;
+				}
+				id = *(unsigned char *)clear;
+				if (id + 1 <= plen && id + 9 > plen)
+					break;
+			}
+			if (plen % 8 == 0 && i < 5) {
+				/*
+				 * Note that this is always shorter than the
+				 * original stored string, so there's no need
+				 * to realloc.
+				 */
+				if ((i = plen = *(unsigned char *)clear) > 7)
+					i = 7;
+				pcb->eap.es_server.ea_peerlen = plen;
+				dp = (unsigned char *)pcb->eap.es_server.ea_peer;
+				MEMCPY(dp, clear + 1, i);
+				plen -= i;
+				dp += i;
+				sp = secbuf + 8;
+				while (plen > 0) {
+					/* FIXME: if we want to do SRP, we need to find a way to pass the PolarSSL des_context instead of using static memory */
+					(void) DesDecrypt(sp, dp);
+					sp += 8;
+					dp += 8;
+					plen -= 8;
+				}
+				pcb->eap.es_server.ea_peer[
+					pcb->eap.es_server.ea_peerlen] = '\0';
+				ppp_dbglog("decoded pseudonym to \"%.*q\"",
+				    pcb->eap.es_server.ea_peerlen,
+				    pcb->eap.es_server.ea_peer);
+			} else {
+				ppp_dbglog("failed to decode real name");
+				/* Stay in eapIdentfy state; requery */
+				break;
+			}
+		}
+		/* Look up user in secrets database. */
+		if (get_srp_secret(pcb->eap.es_unit, pcb->eap.es_server.ea_peer,
+		    pcb->eap.es_server.ea_name, (char *)secbuf, 1) != 0) {
+			/* Set up default in case SRP entry is bad */
+			pcb->eap.es_server.ea_state = eapMD5Chall;
+			/* Get t_confent based on index in srp-secrets */
+			id = strtol((char *)secbuf, &cp, 10);
+			if (*cp++ != ':' || id < 0)
+				break;
+			if (id == 0) {
+				mytce.index = 0;
+				mytce.modulus.data = (u_char *)wkmodulus;
+				mytce.modulus.len = sizeof (wkmodulus);
+				mytce.generator.data = (u_char *)"\002";
+				mytce.generator.len = 1;
+				tce = &mytce;
+			} else if ((tce = gettcid(id)) != NULL) {
+				/*
+				 * Client will have to verify this modulus/
+				 * generator combination, and that will take
+				 * a while.  Lengthen the timeout here.
+				 */
+				if (pcb->settings.eap_timeout_time > 0 &&
+				    pcb->settings.eap_timeout_time < 30)
+					pcb->settings.eap_timeout_time = 30;
+			} else {
+				break;
+			}
+			if ((cp2 = strchr(cp, ':')) == NULL)
+				break;
+			*cp2++ = '\0';
+			tpw.pebuf.name = pcb->eap.es_server.ea_peer;
+			tpw.pebuf.password.len = t_fromb64((char *)tpw.pwbuf,
+			    cp);
+			tpw.pebuf.password.data = tpw.pwbuf;
+			tpw.pebuf.salt.len = t_fromb64((char *)tpw.saltbuf,
+			    cp2);
+			tpw.pebuf.salt.data = tpw.saltbuf;
+			if ((ts = t_serveropenraw(&tpw.pebuf, tce)) == NULL)
+				break;
+			pcb->eap.es_server.ea_session = (void *)ts;
+			pcb->eap.es_server.ea_state = eapSRP1;
+			vals[0] = pcb->eap.es_server.ea_id + 1;
+			vals[1] = EAPT_SRP;
+			t_serveraddexdata(ts, vals, 2);
+			/* Generate B; must call before t_servergetkey() */
+			t_servergenexp(ts);
+			break;
+		}
+#endif /* USE_SRP */
+		pcb->eap.es_server.ea_state = eapMD5Chall;
+		break;
+
+	case eapSRP1:
+#ifdef USE_SRP
+		ts = (struct t_server *)pcb->eap.es_server.ea_session;
+		if (ts != NULL && status != 0) {
+			t_serverclose(ts);
+			pcb->eap.es_server.ea_session = NULL;
+			pcb->eap.es_server.ea_skey = NULL;
+		}
+#endif /* USE_SRP */
+		if (status == 1) {
+			pcb->eap.es_server.ea_state = eapMD5Chall;
+		} else if (status != 0 || pcb->eap.es_server.ea_session == NULL) {
+			pcb->eap.es_server.ea_state = eapBadAuth;
+		} else {
+			pcb->eap.es_server.ea_state = eapSRP2;
+		}
+		break;
+
+	case eapSRP2:
+#ifdef USE_SRP
+		ts = (struct t_server *)pcb->eap.es_server.ea_session;
+		if (ts != NULL && status != 0) {
+			t_serverclose(ts);
+			pcb->eap.es_server.ea_session = NULL;
+			pcb->eap.es_server.ea_skey = NULL;
+		}
+#endif /* USE_SRP */
+		if (status != 0 || pcb->eap.es_server.ea_session == NULL) {
+			pcb->eap.es_server.ea_state = eapBadAuth;
+		} else {
+			pcb->eap.es_server.ea_state = eapSRP3;
+		}
+		break;
+
+	case eapSRP3:
+	case eapSRP4:
+#ifdef USE_SRP
+		ts = (struct t_server *)pcb->eap.es_server.ea_session;
+		if (ts != NULL && status != 0) {
+			t_serverclose(ts);
+			pcb->eap.es_server.ea_session = NULL;
+			pcb->eap.es_server.ea_skey = NULL;
+		}
+#endif /* USE_SRP */
+		if (status != 0 || pcb->eap.es_server.ea_session == NULL) {
+			pcb->eap.es_server.ea_state = eapBadAuth;
+		} else {
+			pcb->eap.es_server.ea_state = eapOpen;
+		}
+		break;
+
+	case eapMD5Chall:
+		if (status != 0) {
+			pcb->eap.es_server.ea_state = eapBadAuth;
+		} else {
+			pcb->eap.es_server.ea_state = eapOpen;
+		}
+		break;
+
+	default:
+		pcb->eap.es_server.ea_state = eapBadAuth;
+		break;
+	}
+	if (pcb->eap.es_server.ea_state == eapBadAuth)
+		eap_send_failure(pcb);
+}
+
+/*
+ * Format an EAP Request message and send it to the peer.  Message
+ * type depends on current state.  (Server operation)
+ */
+static void eap_send_request(ppp_pcb *pcb) {
+	struct pbuf *p;
+	u_char *outp;
+	u_char *lenloc;
+	int outlen;
+	int len;
+	const char *str;
+#ifdef USE_SRP
+	struct t_server *ts;
+	u_char clear[8], cipher[8], dig[SHA_DIGESTSIZE], *optr, *cp;
+	int i, j;
+	struct b64state b64;
+	SHA1_CTX ctxt;
+#endif /* USE_SRP */
+
+	/* Handle both initial auth and restart */
+	if (pcb->eap.es_server.ea_state < eapIdentify &&
+	    pcb->eap.es_server.ea_state != eapInitial) {
+		pcb->eap.es_server.ea_state = eapIdentify;
+#if PPP_REMOTENAME
+		if (pcb->settings.explicit_remote && pcb->remote_name) {
+			/*
+			 * If we already know the peer's
+			 * unauthenticated name, then there's no
+			 * reason to ask.  Go to next state instead.
+			 */
+			int len = (int)strlen(pcb->remote_name);
+			if (len > MAXNAMELEN) {
+				len = MAXNAMELEN;
+			}
+			MEMCPY(pcb->eap.es_server.ea_peer, pcb->remote_name, len);
+			pcb->eap.es_server.ea_peer[len] = '\0';
+			pcb->eap.es_server.ea_peerlen = len;
+			eap_figure_next_state(pcb, 0);
+		}
+#endif /* PPP_REMOTENAME */
+	}
+
+	if (pcb->settings.eap_max_transmits > 0 &&
+	    pcb->eap.es_server.ea_requests >= pcb->settings.eap_max_transmits) {
+		if (pcb->eap.es_server.ea_responses > 0)
+			ppp_error("EAP: too many Requests sent");
+		else
+			ppp_error("EAP: no response to Requests");
+		eap_send_failure(pcb);
+		return;
+	}
+
+	p = pbuf_alloc(PBUF_RAW, (u16_t)(PPP_CTRL_PBUF_MAX_SIZE), PPP_CTRL_PBUF_TYPE);
+	if(NULL == p)
+		return;
+	if(p->tot_len != p->len) {
+		pbuf_free(p);
+		return;
+	}
+
+	outp = (u_char*)p->payload;
+    
+	MAKEHEADER(outp, PPP_EAP);
+
+	PUTCHAR(EAP_REQUEST, outp);
+	PUTCHAR(pcb->eap.es_server.ea_id, outp);
+	lenloc = outp;
+	INCPTR(2, outp);
+
+	switch (pcb->eap.es_server.ea_state) {
+	case eapIdentify:
+		PUTCHAR(EAPT_IDENTITY, outp);
+		str = "Name";
+		len = strlen(str);
+		MEMCPY(outp, str, len);
+		INCPTR(len, outp);
+		break;
+
+	case eapMD5Chall:
+		PUTCHAR(EAPT_MD5CHAP, outp);
+		/*
+		 * pick a random challenge length between
+		 * EAP_MIN_CHALLENGE_LENGTH and EAP_MAX_CHALLENGE_LENGTH
+		 */
+		pcb->eap.es_challen = EAP_MIN_CHALLENGE_LENGTH +
+		    magic_pow(EAP_MIN_MAX_POWER_OF_TWO_CHALLENGE_LENGTH);
+		PUTCHAR(pcb->eap.es_challen, outp);
+		magic_random_bytes(pcb->eap.es_challenge, pcb->eap.es_challen);
+		MEMCPY(outp, pcb->eap.es_challenge, pcb->eap.es_challen);
+		INCPTR(pcb->eap.es_challen, outp);
+		MEMCPY(outp, pcb->eap.es_server.ea_name, pcb->eap.es_server.ea_namelen);
+		INCPTR(pcb->eap.es_server.ea_namelen, outp);
+		break;
+
+#ifdef USE_SRP
+	case eapSRP1:
+		PUTCHAR(EAPT_SRP, outp);
+		PUTCHAR(EAPSRP_CHALLENGE, outp);
+
+		PUTCHAR(pcb->eap.es_server.ea_namelen, outp);
+		MEMCPY(outp, pcb->eap.es_server.ea_name, pcb->eap.es_server.ea_namelen);
+		INCPTR(pcb->eap.es_server.ea_namelen, outp);
+
+		ts = (struct t_server *)pcb->eap.es_server.ea_session;
+		assert(ts != NULL);
+		PUTCHAR(ts->s.len, outp);
+		MEMCPY(outp, ts->s.data, ts->s.len);
+		INCPTR(ts->s.len, outp);
+
+		if (ts->g.len == 1 && ts->g.data[0] == 2) {
+			PUTCHAR(0, outp);
+		} else {
+			PUTCHAR(ts->g.len, outp);
+			MEMCPY(outp, ts->g.data, ts->g.len);
+			INCPTR(ts->g.len, outp);
+		}
+
+		if (ts->n.len != sizeof (wkmodulus) ||
+		    BCMP(ts->n.data, wkmodulus, sizeof (wkmodulus)) != 0) {
+			MEMCPY(outp, ts->n.data, ts->n.len);
+			INCPTR(ts->n.len, outp);
+		}
+		break;
+
+	case eapSRP2:
+		PUTCHAR(EAPT_SRP, outp);
+		PUTCHAR(EAPSRP_SKEY, outp);
+
+		ts = (struct t_server *)pcb->eap.es_server.ea_session;
+		assert(ts != NULL);
+		MEMCPY(outp, ts->B.data, ts->B.len);
+		INCPTR(ts->B.len, outp);
+		break;
+
+	case eapSRP3:
+		PUTCHAR(EAPT_SRP, outp);
+		PUTCHAR(EAPSRP_SVALIDATOR, outp);
+		PUTLONG(SRPVAL_EBIT, outp);
+		ts = (struct t_server *)pcb->eap.es_server.ea_session;
+		assert(ts != NULL);
+		MEMCPY(outp, t_serverresponse(ts), SHA_DIGESTSIZE);
+		INCPTR(SHA_DIGESTSIZE, outp);
+
+		if (pncrypt_setkey(0)) {
+			/* Generate pseudonym */
+			optr = outp;
+			cp = (unsigned char *)pcb->eap.es_server.ea_peer;
+			if ((j = i = pcb->eap.es_server.ea_peerlen) > 7)
+				j = 7;
+			clear[0] = i;
+			MEMCPY(clear + 1, cp, j);
+			i -= j;
+			cp += j;
+			/* FIXME: if we want to do SRP, we need to find a way to pass the PolarSSL des_context instead of using static memory */
+			if (!DesEncrypt(clear, cipher)) {
+				ppp_dbglog("no DES here; not generating pseudonym");
+				break;
+			}
+			BZERO(&b64, sizeof (b64));
+			outp++;		/* space for pseudonym length */
+			outp += b64enc(&b64, cipher, 8, outp);
+			while (i >= 8) {
+				/* FIXME: if we want to do SRP, we need to find a way to pass the PolarSSL des_context instead of using static memory */
+				(void) DesEncrypt(cp, cipher);
+				outp += b64enc(&b64, cipher, 8, outp);
+				cp += 8;
+				i -= 8;
+			}
+			if (i > 0) {
+				MEMCPY(clear, cp, i);
+				cp += i;
+				magic_random_bytes(cp, 8-i);
+				/* FIXME: if we want to do SRP, we need to find a way to pass the PolarSSL des_context instead of using static memory */
+				(void) DesEncrypt(clear, cipher);
+				outp += b64enc(&b64, cipher, 8, outp);
+			}
+			outp += b64flush(&b64, outp);
+
+			/* Set length and pad out to next 20 octet boundary */
+			i = outp - optr - 1;
+			*optr = i;
+			i %= SHA_DIGESTSIZE;
+			if (i != 0) {
+				magic_random_bytes(outp, SHA_DIGESTSIZE-i);
+				INCPTR(SHA_DIGESTSIZE-i, outp);
+			}
+
+			/* Obscure the pseudonym with SHA1 hash */
+			SHA1Init(&ctxt);
+			SHA1Update(&ctxt, &pcb->eap.es_server.ea_id, 1);
+			SHA1Update(&ctxt, pcb->eap.es_server.ea_skey,
+			    SESSION_KEY_LEN);
+			SHA1Update(&ctxt, pcb->eap.es_server.ea_peer,
+			    pcb->eap.es_server.ea_peerlen);
+			while (optr < outp) {
+				SHA1Final(dig, &ctxt);
+				cp = dig;
+				while (cp < dig + SHA_DIGESTSIZE)
+					*optr++ ^= *cp++;
+				SHA1Init(&ctxt);
+				SHA1Update(&ctxt, &pcb->eap.es_server.ea_id, 1);
+				SHA1Update(&ctxt, pcb->eap.es_server.ea_skey,
+				    SESSION_KEY_LEN);
+				SHA1Update(&ctxt, optr - SHA_DIGESTSIZE,
+				    SHA_DIGESTSIZE);
+			}
+		}
+		break;
+
+	case eapSRP4:
+		PUTCHAR(EAPT_SRP, outp);
+		PUTCHAR(EAPSRP_LWRECHALLENGE, outp);
+		pcb->eap.es_challen = EAP_MIN_CHALLENGE_LENGTH +
+		    magic_pow(EAP_MIN_MAX_POWER_OF_TWO_CHALLENGE_LENGTH);
+		magic_random_bytes(pcb->eap.es_challenge, pcb->eap.es_challen);
+		MEMCPY(outp, pcb->eap.es_challenge, pcb->eap.es_challen);
+		INCPTR(pcb->eap.es_challen, outp);
+		break;
+#endif /* USE_SRP */
+
+	default:
+		return;
+	}
+
+	outlen = (outp - (unsigned char*)p->payload) - PPP_HDRLEN;
+	PUTSHORT(outlen, lenloc);
+
+	pbuf_realloc(p, outlen + PPP_HDRLEN);
+	ppp_write(pcb, p);
+
+	pcb->eap.es_server.ea_requests++;
+
+	if (pcb->settings.eap_timeout_time > 0)
+		TIMEOUT(eap_server_timeout, pcb, pcb->settings.eap_timeout_time);
+}
+
+/*
+ * eap_authpeer - Authenticate our peer (behave as server).
+ *
+ * Start server state and send first request.  This is called only
+ * after eap_lowerup.
+ */
+void eap_authpeer(ppp_pcb *pcb, const char *localname) {
+
+	/* Save the name we're given. */
+	pcb->eap.es_server.ea_name = localname;
+	pcb->eap.es_server.ea_namelen = strlen(localname);
+
+	pcb->eap.es_savedtime = pcb->settings.eap_timeout_time;
+
+	/* Lower layer up yet? */
+	if (pcb->eap.es_server.ea_state == eapInitial ||
+	    pcb->eap.es_server.ea_state == eapPending) {
+		pcb->eap.es_server.ea_state = eapPending;
+		return;
+	}
+
+	pcb->eap.es_server.ea_state = eapPending;
+
+	/* ID number not updated here intentionally; hashed into M1 */
+	eap_send_request(pcb);
+}
+
+/*
+ * eap_server_timeout - Retransmission timer for sending Requests
+ * expired.
+ */
+static void eap_server_timeout(void *arg) {
+	ppp_pcb *pcb = (ppp_pcb*)arg;
+
+	if (!eap_server_active(pcb))
+		return;
+
+	/* EAP ID number must not change on timeout. */
+	eap_send_request(pcb);
+}
+
+/*
+ * When it's time to send rechallenge the peer, this timeout is
+ * called.  Once the rechallenge is successful, the response handler
+ * will restart the timer.  If it fails, then the link is dropped.
+ */
+static void eap_rechallenge(void *arg) {
+	ppp_pcb *pcb = (ppp_pcb*)arg;
+
+	if (pcb->eap.es_server.ea_state != eapOpen &&
+	    pcb->eap.es_server.ea_state != eapSRP4)
+		return;
+
+	pcb->eap.es_server.ea_requests = 0;
+	pcb->eap.es_server.ea_state = eapIdentify;
+	eap_figure_next_state(pcb, 0);
+	pcb->eap.es_server.ea_id++;
+	eap_send_request(pcb);
+}
+
+static void srp_lwrechallenge(void *arg) {
+	ppp_pcb *pcb = (ppp_pcb*)arg;
+
+	if (pcb->eap.es_server.ea_state != eapOpen ||
+	    pcb->eap.es_server.ea_type != EAPT_SRP)
+		return;
+
+	pcb->eap.es_server.ea_requests = 0;
+	pcb->eap.es_server.ea_state = eapSRP4;
+	pcb->eap.es_server.ea_id++;
+	eap_send_request(pcb);
+}
+#endif /* PPP_SERVER */
+
+/*
+ * eap_lowerup - The lower layer is now up.
+ *
+ * This is called before either eap_authpeer or eap_authwithpeer.  See
+ * link_established() in auth.c.  All that's necessary here is to
+ * return to closed state so that those two routines will do the right
+ * thing.
+ */
+static void eap_lowerup(ppp_pcb *pcb) {
+	pcb->eap.es_client.ea_state = eapClosed;
+#if PPP_SERVER
+	pcb->eap.es_server.ea_state = eapClosed;
+#endif /* PPP_SERVER */
+}
+
+/*
+ * eap_lowerdown - The lower layer is now down.
+ *
+ * Cancel all timeouts and return to initial state.
+ */
+static void eap_lowerdown(ppp_pcb *pcb) {
+
+	if (eap_client_active(pcb) && pcb->settings.eap_req_time > 0) {
+		UNTIMEOUT(eap_client_timeout, pcb);
+	}
+#if PPP_SERVER
+	if (eap_server_active(pcb)) {
+		if (pcb->settings.eap_timeout_time > 0) {
+			UNTIMEOUT(eap_server_timeout, pcb);
+		}
+	} else {
+		if ((pcb->eap.es_server.ea_state == eapOpen ||
+		    pcb->eap.es_server.ea_state == eapSRP4) &&
+		    pcb->eap.es_rechallenge > 0) {
+			UNTIMEOUT(eap_rechallenge, (void *)pcb);
+		}
+		if (pcb->eap.es_server.ea_state == eapOpen &&
+		    pcb->eap.es_lwrechallenge > 0) {
+			UNTIMEOUT(srp_lwrechallenge, (void *)pcb);
+		}
+	}
+
+	pcb->eap.es_client.ea_state = pcb->eap.es_server.ea_state = eapInitial;
+	pcb->eap.es_client.ea_requests = pcb->eap.es_server.ea_requests = 0;
+#endif /* PPP_SERVER */
+}
+
+/*
+ * eap_protrej - Peer doesn't speak this protocol.
+ *
+ * This shouldn't happen.  If it does, it represents authentication
+ * failure.
+ */
+static void eap_protrej(ppp_pcb *pcb) {
+
+	if (eap_client_active(pcb)) {
+		ppp_error("EAP authentication failed due to Protocol-Reject");
+		auth_withpeer_fail(pcb, PPP_EAP);
+	}
+#if PPP_SERVER
+	if (eap_server_active(pcb)) {
+		ppp_error("EAP authentication of peer failed on Protocol-Reject");
+		auth_peer_fail(pcb, PPP_EAP);
+	}
+#endif /* PPP_SERVER */
+	eap_lowerdown(pcb);
+}
+
+/*
+ * Format and send a regular EAP Response message.
+ */
+static void eap_send_response(ppp_pcb *pcb, u_char id, u_char typenum, const u_char *str, int lenstr) {
+	struct pbuf *p;
+	u_char *outp;
+	int msglen;
+
+	msglen = EAP_HEADERLEN + sizeof (u_char) + lenstr;
+	p = pbuf_alloc(PBUF_RAW, (u16_t)(PPP_HDRLEN + msglen), PPP_CTRL_PBUF_TYPE);
+	if(NULL == p)
+		return;
+	if(p->tot_len != p->len) {
+		pbuf_free(p);
+		return;
+	}
+
+	outp = (u_char*)p->payload;
+
+	MAKEHEADER(outp, PPP_EAP);
+
+	PUTCHAR(EAP_RESPONSE, outp);
+	PUTCHAR(id, outp);
+	pcb->eap.es_client.ea_id = id;
+	PUTSHORT(msglen, outp);
+	PUTCHAR(typenum, outp);
+	if (lenstr > 0) {
+		MEMCPY(outp, str, lenstr);
+	}
+
+	ppp_write(pcb, p);
+}
+
+/*
+ * Format and send an MD5-Challenge EAP Response message.
+ */
+static void eap_chap_response(ppp_pcb *pcb, u_char id, u_char *hash, const char *name, int namelen) {
+	struct pbuf *p;
+	u_char *outp;
+	int msglen;
+
+	msglen = EAP_HEADERLEN + 2 * sizeof (u_char) + MD5_SIGNATURE_SIZE +
+	    namelen;
+	p = pbuf_alloc(PBUF_RAW, (u16_t)(PPP_HDRLEN + msglen), PPP_CTRL_PBUF_TYPE);
+	if(NULL == p)
+		return;
+	if(p->tot_len != p->len) {
+		pbuf_free(p);
+		return;
+	}
+
+	outp = (u_char*)p->payload;
+    
+	MAKEHEADER(outp, PPP_EAP);
+
+	PUTCHAR(EAP_RESPONSE, outp);
+	PUTCHAR(id, outp);
+	pcb->eap.es_client.ea_id = id;
+	PUTSHORT(msglen, outp);
+	PUTCHAR(EAPT_MD5CHAP, outp);
+	PUTCHAR(MD5_SIGNATURE_SIZE, outp);
+	MEMCPY(outp, hash, MD5_SIGNATURE_SIZE);
+	INCPTR(MD5_SIGNATURE_SIZE, outp);
+	if (namelen > 0) {
+		MEMCPY(outp, name, namelen);
+	}
+
+	ppp_write(pcb, p);
+}
+
+#ifdef USE_SRP
+/*
+ * Format and send a SRP EAP Response message.
+ */
+static void
+eap_srp_response(esp, id, subtypenum, str, lenstr)
+eap_state *esp;
+u_char id;
+u_char subtypenum;
+u_char *str;
+int lenstr;
+{
+	ppp_pcb *pcb = &ppp_pcb_list[pcb->eap.es_unit];
+	struct pbuf *p;
+	u_char *outp;
+	int msglen;
+
+	msglen = EAP_HEADERLEN + 2 * sizeof (u_char) + lenstr;
+	p = pbuf_alloc(PBUF_RAW, (u16_t)(PPP_HDRLEN + msglen), PPP_CTRL_PBUF_TYPE);
+	if(NULL == p)
+		return;
+	if(p->tot_len != p->len) {
+		pbuf_free(p);
+		return;
+	}
+
+	outp = p->payload;
+
+	MAKEHEADER(outp, PPP_EAP);
+
+	PUTCHAR(EAP_RESPONSE, outp);
+	PUTCHAR(id, outp);
+	pcb->eap.es_client.ea_id = id;
+	PUTSHORT(msglen, outp);
+	PUTCHAR(EAPT_SRP, outp);
+	PUTCHAR(subtypenum, outp);
+	if (lenstr > 0) {
+		MEMCPY(outp, str, lenstr);
+	}
+
+	ppp_write(pcb, p);
+}
+
+/*
+ * Format and send a SRP EAP Client Validator Response message.
+ */
+static void
+eap_srpval_response(esp, id, flags, str)
+eap_state *esp;
+u_char id;
+u32_t flags;
+u_char *str;
+{
+	ppp_pcb *pcb = &ppp_pcb_list[pcb->eap.es_unit];
+	struct pbuf *p;
+	u_char *outp;
+	int msglen;
+
+	msglen = EAP_HEADERLEN + 2 * sizeof (u_char) + sizeof (u32_t) +
+	    SHA_DIGESTSIZE;
+	p = pbuf_alloc(PBUF_RAW, (u16_t)(PPP_HDRLEN + msglen), PPP_CTRL_PBUF_TYPE);
+	if(NULL == p)
+		return;
+	if(p->tot_len != p->len) {
+		pbuf_free(p);
+		return;
+	}
+
+	outp = p->payload;
+
+	MAKEHEADER(outp, PPP_EAP);
+
+	PUTCHAR(EAP_RESPONSE, outp);
+	PUTCHAR(id, outp);
+	pcb->eap.es_client.ea_id = id;
+	PUTSHORT(msglen, outp);
+	PUTCHAR(EAPT_SRP, outp);
+	PUTCHAR(EAPSRP_CVALIDATOR, outp);
+	PUTLONG(flags, outp);
+	MEMCPY(outp, str, SHA_DIGESTSIZE);
+
+	ppp_write(pcb, p);
+}
+#endif /* USE_SRP */
+
+static void eap_send_nak(ppp_pcb *pcb, u_char id, u_char type) {
+	struct pbuf *p;
+	u_char *outp;
+	int msglen;
+
+	msglen = EAP_HEADERLEN + 2 * sizeof (u_char);
+	p = pbuf_alloc(PBUF_RAW, (u16_t)(PPP_HDRLEN + msglen), PPP_CTRL_PBUF_TYPE);
+	if(NULL == p)
+		return;
+	if(p->tot_len != p->len) {
+		pbuf_free(p);
+		return;
+	}
+
+	outp = (u_char*)p->payload;
+
+	MAKEHEADER(outp, PPP_EAP);
+
+	PUTCHAR(EAP_RESPONSE, outp);
+	PUTCHAR(id, outp);
+	pcb->eap.es_client.ea_id = id;
+	PUTSHORT(msglen, outp);
+	PUTCHAR(EAPT_NAK, outp);
+	PUTCHAR(type, outp);
+
+	ppp_write(pcb, p);
+}
+
+#ifdef USE_SRP
+static char *
+name_of_pn_file()
+{
+	char *user, *path, *file;
+	struct passwd *pw;
+	size_t pl;
+	static bool pnlogged = 0;
+
+	pw = getpwuid(getuid());
+	if (pw == NULL || (user = pw->pw_dir) == NULL || user[0] == 0) {
+		errno = EINVAL;
+		return (NULL);
+	}
+	file = _PATH_PSEUDONYM;
+	pl = strlen(user) + strlen(file) + 2;
+	path = malloc(pl);
+	if (path == NULL)
+		return (NULL);
+	(void) slprintf(path, pl, "%s/%s", user, file);
+	if (!pnlogged) {
+		ppp_dbglog("pseudonym file: %s", path);
+		pnlogged = 1;
+	}
+	return (path);
+}
+
+static int
+open_pn_file(modebits)
+mode_t modebits;
+{
+	char *path;
+	int fd, err;
+
+	if ((path = name_of_pn_file()) == NULL)
+		return (-1);
+	fd = open(path, modebits, S_IRUSR | S_IWUSR);
+	err = errno;
+	free(path);
+	errno = err;
+	return (fd);
+}
+
+static void
+remove_pn_file()
+{
+	char *path;
+
+	if ((path = name_of_pn_file()) != NULL) {
+		(void) unlink(path);
+		(void) free(path);
+	}
+}
+
+static void
+write_pseudonym(esp, inp, len, id)
+eap_state *esp;
+u_char *inp;
+int len, id;
+{
+	u_char val;
+	u_char *datp, *digp;
+	SHA1_CTX ctxt;
+	u_char dig[SHA_DIGESTSIZE];
+	int dsize, fd, olen = len;
+
+	/*
+	 * Do the decoding by working backwards.  This eliminates the need
+	 * to save the decoded output in a separate buffer.
+	 */
+	val = id;
+	while (len > 0) {
+		if ((dsize = len % SHA_DIGESTSIZE) == 0)
+			dsize = SHA_DIGESTSIZE;
+		len -= dsize;
+		datp = inp + len;
+		SHA1Init(&ctxt);
+		SHA1Update(&ctxt, &val, 1);
+		SHA1Update(&ctxt, pcb->eap.es_client.ea_skey, SESSION_KEY_LEN);
+		if (len > 0) {
+			SHA1Update(&ctxt, datp, SHA_DIGESTSIZE);
+		} else {
+			SHA1Update(&ctxt, pcb->eap.es_client.ea_name,
+			    pcb->eap.es_client.ea_namelen);
+		}
+		SHA1Final(dig, &ctxt);
+		for (digp = dig; digp < dig + SHA_DIGESTSIZE; digp++)
+			*datp++ ^= *digp;
+	}
+
+	/* Now check that the result is sane */
+	if (olen <= 0 || *inp + 1 > olen) {
+		ppp_dbglog("EAP: decoded pseudonym is unusable <%.*B>", olen, inp);
+		return;
+	}
+
+	/* Save it away */
+	fd = open_pn_file(O_WRONLY | O_CREAT | O_TRUNC);
+	if (fd < 0) {
+		ppp_dbglog("EAP: error saving pseudonym: %m");
+		return;
+	}
+	len = write(fd, inp + 1, *inp);
+	if (close(fd) != -1 && len == *inp) {
+		ppp_dbglog("EAP: saved pseudonym");
+		pcb->eap.es_usedpseudo = 0;
+	} else {
+		ppp_dbglog("EAP: failed to save pseudonym");
+		remove_pn_file();
+	}
+}
+#endif /* USE_SRP */
+
+/*
+ * eap_request - Receive EAP Request message (client mode).
+ */
+static void eap_request(ppp_pcb *pcb, u_char *inp, int id, int len) {
+	u_char typenum;
+	u_char vallen;
+	int secret_len;
+	char secret[MAXSECRETLEN];
+	char rhostname[MAXNAMELEN];
+	lwip_md5_context mdContext;
+	u_char hash[MD5_SIGNATURE_SIZE];
+#ifdef USE_SRP
+	struct t_client *tc;
+	struct t_num sval, gval, Nval, *Ap, Bval;
+	u_char vals[2];
+	SHA1_CTX ctxt;
+	u_char dig[SHA_DIGESTSIZE];
+	int fd;
+#endif /* USE_SRP */
+
+	/*
+	 * Note: we update es_client.ea_id *only if* a Response
+	 * message is being generated.  Otherwise, we leave it the
+	 * same for duplicate detection purposes.
+	 */
+
+	pcb->eap.es_client.ea_requests++;
+	if (pcb->settings.eap_allow_req != 0 &&
+	    pcb->eap.es_client.ea_requests > pcb->settings.eap_allow_req) {
+		ppp_info("EAP: received too many Request messages");
+		if (pcb->settings.eap_req_time > 0) {
+			UNTIMEOUT(eap_client_timeout, pcb);
+		}
+		auth_withpeer_fail(pcb, PPP_EAP);
+		return;
+	}
+
+	if (len <= 0) {
+		ppp_error("EAP: empty Request message discarded");
+		return;
+	}
+
+	GETCHAR(typenum, inp);
+	len--;
+
+	switch (typenum) {
+	case EAPT_IDENTITY:
+		if (len > 0)
+			ppp_info("EAP: Identity prompt \"%.*q\"", len, inp);
+#ifdef USE_SRP
+		if (pcb->eap.es_usepseudo &&
+		    (pcb->eap.es_usedpseudo == 0 ||
+			(pcb->eap.es_usedpseudo == 1 &&
+			    id == pcb->eap.es_client.ea_id))) {
+			pcb->eap.es_usedpseudo = 1;
+			/* Try to get a pseudonym */
+			if ((fd = open_pn_file(O_RDONLY)) >= 0) {
+				strcpy(rhostname, SRP_PSEUDO_ID);
+				len = read(fd, rhostname + SRP_PSEUDO_LEN,
+				    sizeof (rhostname) - SRP_PSEUDO_LEN);
+				/* XXX NAI unsupported */
+				if (len > 0) {
+					eap_send_response(pcb, id, typenum,
+					    rhostname, len + SRP_PSEUDO_LEN);
+				}
+				(void) close(fd);
+				if (len > 0)
+					break;
+			}
+		}
+		/* Stop using pseudonym now. */
+		if (pcb->eap.es_usepseudo && pcb->eap.es_usedpseudo != 2) {
+			remove_pn_file();
+			pcb->eap.es_usedpseudo = 2;
+		}
+#endif /* USE_SRP */
+		eap_send_response(pcb, id, typenum, (const u_char*)pcb->eap.es_client.ea_name,
+		    pcb->eap.es_client.ea_namelen);
+		break;
+
+	case EAPT_NOTIFICATION:
+		if (len > 0)
+			ppp_info("EAP: Notification \"%.*q\"", len, inp);
+		eap_send_response(pcb, id, typenum, NULL, 0);
+		break;
+
+	case EAPT_NAK:
+		/*
+		 * Avoid the temptation to send Response Nak in reply
+		 * to Request Nak here.  It can only lead to trouble.
+		 */
+		ppp_warn("EAP: unexpected Nak in Request; ignored");
+		/* Return because we're waiting for something real. */
+		return;
+
+	case EAPT_MD5CHAP:
+		if (len < 1) {
+			ppp_error("EAP: received MD5-Challenge with no data");
+			/* Bogus request; wait for something real. */
+			return;
+		}
+		GETCHAR(vallen, inp);
+		len--;
+		if (vallen < 8 || vallen > len) {
+			ppp_error("EAP: MD5-Challenge with bad length %d (8..%d)",
+			    vallen, len);
+			/* Try something better. */
+			eap_send_nak(pcb, id, EAPT_SRP);
+			break;
+		}
+
+		/* Not so likely to happen. */
+		if (vallen >= len + sizeof (rhostname)) {
+			ppp_dbglog("EAP: trimming really long peer name down");
+			MEMCPY(rhostname, inp + vallen, sizeof (rhostname) - 1);
+			rhostname[sizeof (rhostname) - 1] = '\0';
+		} else {
+			MEMCPY(rhostname, inp + vallen, len - vallen);
+			rhostname[len - vallen] = '\0';
+		}
+
+#if PPP_REMOTENAME
+		/* In case the remote doesn't give us his name. */
+		if (pcb->settings.explicit_remote ||
+		    (pcb->settings.remote_name[0] != '\0' && vallen == len))
+			strlcpy(rhostname, pcb->settings.remote_name, sizeof (rhostname));
+#endif /* PPP_REMOTENAME */
+
+		/*
+		 * Get the secret for authenticating ourselves with
+		 * the specified host.
+		 */
+		if (!get_secret(pcb, pcb->eap.es_client.ea_name,
+		    rhostname, secret, &secret_len, 0)) {
+			ppp_dbglog("EAP: no MD5 secret for auth to %q", rhostname);
+			eap_send_nak(pcb, id, EAPT_SRP);
+			break;
+		}
+		lwip_md5_init(&mdContext);
+		lwip_md5_starts(&mdContext);
+		typenum = id;
+		lwip_md5_update(&mdContext, &typenum, 1);
+		lwip_md5_update(&mdContext, (u_char *)secret, secret_len);
+		BZERO(secret, sizeof (secret));
+		lwip_md5_update(&mdContext, inp, vallen);
+		lwip_md5_finish(&mdContext, hash);
+		lwip_md5_free(&mdContext);
+		eap_chap_response(pcb, id, hash, pcb->eap.es_client.ea_name,
+		    pcb->eap.es_client.ea_namelen);
+		break;
+
+#ifdef USE_SRP
+	case EAPT_SRP:
+		if (len < 1) {
+			ppp_error("EAP: received empty SRP Request");
+			/* Bogus request; wait for something real. */
+			return;
+		}
+
+		/* Get subtype */
+		GETCHAR(vallen, inp);
+		len--;
+		switch (vallen) {
+		case EAPSRP_CHALLENGE:
+			tc = NULL;
+			if (pcb->eap.es_client.ea_session != NULL) {
+				tc = (struct t_client *)pcb->eap.es_client.
+				    ea_session;
+				/*
+				 * If this is a new challenge, then start
+				 * over with a new client session context.
+				 * Otherwise, just resend last response.
+				 */
+				if (id != pcb->eap.es_client.ea_id) {
+					t_clientclose(tc);
+					pcb->eap.es_client.ea_session = NULL;
+					tc = NULL;
+				}
+			}
+			/* No session key just yet */
+			pcb->eap.es_client.ea_skey = NULL;
+			if (tc == NULL) {
+				int rhostnamelen;
+
+				GETCHAR(vallen, inp);
+				len--;
+				if (vallen >= len) {
+					ppp_error("EAP: badly-formed SRP Challenge"
+					    " (name)");
+					/* Ignore badly-formed messages */
+					return;
+				}
+				MEMCPY(rhostname, inp, vallen);
+				rhostname[vallen] = '\0';
+				INCPTR(vallen, inp);
+				len -= vallen;
+
+				/*
+				 * In case the remote doesn't give us his name,
+				 * use configured name.
+				 */
+				if (explicit_remote ||
+				    (remote_name[0] != '\0' && vallen == 0)) {
+					strlcpy(rhostname, remote_name,
+					    sizeof (rhostname));
+				}
+
+				rhostnamelen = (int)strlen(rhostname);
+				if (rhostnamelen > MAXNAMELEN) {
+					rhostnamelen = MAXNAMELEN;
+				}
+				MEMCPY(pcb->eap.es_client.ea_peer, rhostname, rhostnamelen);
+				pcb->eap.es_client.ea_peer[rhostnamelen] = '\0';
+				pcb->eap.es_client.ea_peerlen = rhostnamelen;
+
+				GETCHAR(vallen, inp);
+				len--;
+				if (vallen >= len) {
+					ppp_error("EAP: badly-formed SRP Challenge"
+					    " (s)");
+					/* Ignore badly-formed messages */
+					return;
+				}
+				sval.data = inp;
+				sval.len = vallen;
+				INCPTR(vallen, inp);
+				len -= vallen;
+
+				GETCHAR(vallen, inp);
+				len--;
+				if (vallen > len) {
+					ppp_error("EAP: badly-formed SRP Challenge"
+					    " (g)");
+					/* Ignore badly-formed messages */
+					return;
+				}
+				/* If no generator present, then use value 2 */
+				if (vallen == 0) {
+					gval.data = (u_char *)"\002";
+					gval.len = 1;
+				} else {
+					gval.data = inp;
+					gval.len = vallen;
+				}
+				INCPTR(vallen, inp);
+				len -= vallen;
+
+				/*
+				 * If no modulus present, then use well-known
+				 * value.
+				 */
+				if (len == 0) {
+					Nval.data = (u_char *)wkmodulus;
+					Nval.len = sizeof (wkmodulus);
+				} else {
+					Nval.data = inp;
+					Nval.len = len;
+				}
+				tc = t_clientopen(pcb->eap.es_client.ea_name,
+				    &Nval, &gval, &sval);
+				if (tc == NULL) {
+					eap_send_nak(pcb, id, EAPT_MD5CHAP);
+					break;
+				}
+				pcb->eap.es_client.ea_session = (void *)tc;
+
+				/* Add Challenge ID & type to verifier */
+				vals[0] = id;
+				vals[1] = EAPT_SRP;
+				t_clientaddexdata(tc, vals, 2);
+			}
+			Ap = t_clientgenexp(tc);
+			eap_srp_response(esp, id, EAPSRP_CKEY, Ap->data,
+			    Ap->len);
+			break;
+
+		case EAPSRP_SKEY:
+			tc = (struct t_client *)pcb->eap.es_client.ea_session;
+			if (tc == NULL) {
+				ppp_warn("EAP: peer sent Subtype 2 without 1");
+				eap_send_nak(pcb, id, EAPT_MD5CHAP);
+				break;
+			}
+			if (pcb->eap.es_client.ea_skey != NULL) {
+				/*
+				 * ID number should not change here.  Warn
+				 * if it does (but otherwise ignore).
+				 */
+				if (id != pcb->eap.es_client.ea_id) {
+					ppp_warn("EAP: ID changed from %d to %d "
+					    "in SRP Subtype 2 rexmit",
+					    pcb->eap.es_client.ea_id, id);
+				}
+			} else {
+				if (get_srp_secret(pcb->eap.es_unit,
+				    pcb->eap.es_client.ea_name,
+				    pcb->eap.es_client.ea_peer, secret, 0) == 0) {
+					/*
+					 * Can't work with this peer because
+					 * the secret is missing.  Just give
+					 * up.
+					 */
+					eap_send_nak(pcb, id, EAPT_MD5CHAP);
+					break;
+				}
+				Bval.data = inp;
+				Bval.len = len;
+				t_clientpasswd(tc, secret);
+				BZERO(secret, sizeof (secret));
+				pcb->eap.es_client.ea_skey =
+				    t_clientgetkey(tc, &Bval);
+				if (pcb->eap.es_client.ea_skey == NULL) {
+					/* Server is rogue; stop now */
+					ppp_error("EAP: SRP server is rogue");
+					goto client_failure;
+				}
+			}
+			eap_srpval_response(esp, id, SRPVAL_EBIT,
+			    t_clientresponse(tc));
+			break;
+
+		case EAPSRP_SVALIDATOR:
+			tc = (struct t_client *)pcb->eap.es_client.ea_session;
+			if (tc == NULL || pcb->eap.es_client.ea_skey == NULL) {
+				ppp_warn("EAP: peer sent Subtype 3 without 1/2");
+				eap_send_nak(pcb, id, EAPT_MD5CHAP);
+				break;
+			}
+			/*
+			 * If we're already open, then this ought to be a
+			 * duplicate.  Otherwise, check that the server is
+			 * who we think it is.
+			 */
+			if (pcb->eap.es_client.ea_state == eapOpen) {
+				if (id != pcb->eap.es_client.ea_id) {
+					ppp_warn("EAP: ID changed from %d to %d "
+					    "in SRP Subtype 3 rexmit",
+					    pcb->eap.es_client.ea_id, id);
+				}
+			} else {
+				len -= sizeof (u32_t) + SHA_DIGESTSIZE;
+				if (len < 0 || t_clientverify(tc, inp +
+					sizeof (u32_t)) != 0) {
+					ppp_error("EAP: SRP server verification "
+					    "failed");
+					goto client_failure;
+				}
+				GETLONG(pcb->eap.es_client.ea_keyflags, inp);
+				/* Save pseudonym if user wants it. */
+				if (len > 0 && pcb->eap.es_usepseudo) {
+					INCPTR(SHA_DIGESTSIZE, inp);
+					write_pseudonym(esp, inp, len, id);
+				}
+			}
+			/*
+			 * We've verified our peer.  We're now mostly done,
+			 * except for waiting on the regular EAP Success
+			 * message.
+			 */
+			eap_srp_response(esp, id, EAPSRP_ACK, NULL, 0);
+			break;
+
+		case EAPSRP_LWRECHALLENGE:
+			if (len < 4) {
+				ppp_warn("EAP: malformed Lightweight rechallenge");
+				return;
+			}
+			SHA1Init(&ctxt);
+			vals[0] = id;
+			SHA1Update(&ctxt, vals, 1);
+			SHA1Update(&ctxt, pcb->eap.es_client.ea_skey,
+			    SESSION_KEY_LEN);
+			SHA1Update(&ctxt, inp, len);
+			SHA1Update(&ctxt, pcb->eap.es_client.ea_name,
+			    pcb->eap.es_client.ea_namelen);
+			SHA1Final(dig, &ctxt);
+			eap_srp_response(esp, id, EAPSRP_LWRECHALLENGE, dig,
+			    SHA_DIGESTSIZE);
+			break;
+
+		default:
+			ppp_error("EAP: unknown SRP Subtype %d", vallen);
+			eap_send_nak(pcb, id, EAPT_MD5CHAP);
+			break;
+		}
+		break;
+#endif /* USE_SRP */
+
+	default:
+		ppp_info("EAP: unknown authentication type %d; Naking", typenum);
+		eap_send_nak(pcb, id, EAPT_SRP);
+		break;
+	}
+
+	if (pcb->settings.eap_req_time > 0) {
+		UNTIMEOUT(eap_client_timeout, pcb);
+		TIMEOUT(eap_client_timeout, pcb,
+		    pcb->settings.eap_req_time);
+	}
+	return;
+
+#ifdef USE_SRP
+client_failure:
+	pcb->eap.es_client.ea_state = eapBadAuth;
+	if (pcb->settings.eap_req_time > 0) {
+		UNTIMEOUT(eap_client_timeout, (void *)esp);
+	}
+	pcb->eap.es_client.ea_session = NULL;
+	t_clientclose(tc);
+	auth_withpeer_fail(pcb, PPP_EAP);
+#endif /* USE_SRP */
+}
+
+#if PPP_SERVER
+/*
+ * eap_response - Receive EAP Response message (server mode).
+ */
+static void eap_response(ppp_pcb *pcb, u_char *inp, int id, int len) {
+	u_char typenum;
+	u_char vallen;
+	int secret_len;
+	char secret[MAXSECRETLEN];
+	char rhostname[MAXNAMELEN];
+	lwip_md5_context mdContext;
+	u_char hash[MD5_SIGNATURE_SIZE];
+#ifdef USE_SRP
+	struct t_server *ts;
+	struct t_num A;
+	SHA1_CTX ctxt;
+	u_char dig[SHA_DIGESTSIZE];
+#endif /* USE_SRP */
+
+	if (pcb->eap.es_server.ea_id != id) {
+		ppp_dbglog("EAP: discarding Response %d; expected ID %d", id,
+		    pcb->eap.es_server.ea_id);
+		return;
+	}
+
+	pcb->eap.es_server.ea_responses++;
+
+	if (len <= 0) {
+		ppp_error("EAP: empty Response message discarded");
+		return;
+	}
+
+	GETCHAR(typenum, inp);
+	len--;
+
+	switch (typenum) {
+	case EAPT_IDENTITY:
+		if (pcb->eap.es_server.ea_state != eapIdentify) {
+			ppp_dbglog("EAP discarding unwanted Identify \"%.q\"", len,
+			    inp);
+			break;
+		}
+		ppp_info("EAP: unauthenticated peer name \"%.*q\"", len, inp);
+		if (len > MAXNAMELEN) {
+		  len = MAXNAMELEN;
+		}
+		MEMCPY(pcb->eap.es_server.ea_peer, inp, len);
+		pcb->eap.es_server.ea_peer[len] = '\0';
+		pcb->eap.es_server.ea_peerlen = len;
+		eap_figure_next_state(pcb, 0);
+		break;
+
+	case EAPT_NOTIFICATION:
+		ppp_dbglog("EAP unexpected Notification; response discarded");
+		break;
+
+	case EAPT_NAK:
+		if (len < 1) {
+			ppp_info("EAP: Nak Response with no suggested protocol");
+			eap_figure_next_state(pcb, 1);
+			break;
+		}
+
+		GETCHAR(vallen, inp);
+		len--;
+
+		if (
+#if PPP_REMOTENAME
+		!pcb->explicit_remote &&
+#endif /* PPP_REMOTENAME */
+		pcb->eap.es_server.ea_state == eapIdentify){
+			/* Peer cannot Nak Identify Request */
+			eap_figure_next_state(pcb, 1);
+			break;
+		}
+
+		switch (vallen) {
+		case EAPT_SRP:
+			/* Run through SRP validator selection again. */
+			pcb->eap.es_server.ea_state = eapIdentify;
+			eap_figure_next_state(pcb, 0);
+			break;
+
+		case EAPT_MD5CHAP:
+			pcb->eap.es_server.ea_state = eapMD5Chall;
+			break;
+
+		default:
+			ppp_dbglog("EAP: peer requesting unknown Type %d", vallen);
+			switch (pcb->eap.es_server.ea_state) {
+			case eapSRP1:
+			case eapSRP2:
+			case eapSRP3:
+				pcb->eap.es_server.ea_state = eapMD5Chall;
+				break;
+			case eapMD5Chall:
+			case eapSRP4:
+				pcb->eap.es_server.ea_state = eapIdentify;
+				eap_figure_next_state(pcb, 0);
+				break;
+			default:
+				break;
+			}
+			break;
+		}
+		break;
+
+	case EAPT_MD5CHAP:
+		if (pcb->eap.es_server.ea_state != eapMD5Chall) {
+			ppp_error("EAP: unexpected MD5-Response");
+			eap_figure_next_state(pcb, 1);
+			break;
+		}
+		if (len < 1) {
+			ppp_error("EAP: received MD5-Response with no data");
+			eap_figure_next_state(pcb, 1);
+			break;
+		}
+		GETCHAR(vallen, inp);
+		len--;
+		if (vallen != 16 || vallen > len) {
+			ppp_error("EAP: MD5-Response with bad length %d", vallen);
+			eap_figure_next_state(pcb, 1);
+			break;
+		}
+
+		/* Not so likely to happen. */
+		if (vallen >= len + sizeof (rhostname)) {
+			ppp_dbglog("EAP: trimming really long peer name down");
+			MEMCPY(rhostname, inp + vallen, sizeof (rhostname) - 1);
+			rhostname[sizeof (rhostname) - 1] = '\0';
+		} else {
+			MEMCPY(rhostname, inp + vallen, len - vallen);
+			rhostname[len - vallen] = '\0';
+		}
+
+#if PPP_REMOTENAME
+		/* In case the remote doesn't give us his name. */
+		if (explicit_remote ||
+		    (remote_name[0] != '\0' && vallen == len))
+			strlcpy(rhostname, remote_name, sizeof (rhostname));
+#endif /* PPP_REMOTENAME */
+
+		/*
+		 * Get the secret for authenticating the specified
+		 * host.
+		 */
+		if (!get_secret(pcb, rhostname,
+		    pcb->eap.es_server.ea_name, secret, &secret_len, 1)) {
+			ppp_dbglog("EAP: no MD5 secret for auth of %q", rhostname);
+			eap_send_failure(pcb);
+			break;
+		}
+		lwip_md5_init(&mdContext);
+		lwip_md5_starts(&mdContext);
+		lwip_md5_update(&mdContext, &pcb->eap.es_server.ea_id, 1);
+		lwip_md5_update(&mdContext, (u_char *)secret, secret_len);
+		BZERO(secret, sizeof (secret));
+		lwip_md5_update(&mdContext, pcb->eap.es_challenge, pcb->eap.es_challen);
+		lwip_md5_finish(&mdContext, hash);
+		lwip_md5_free(&mdContext);
+		if (BCMP(hash, inp, MD5_SIGNATURE_SIZE) != 0) {
+			eap_send_failure(pcb);
+			break;
+		}
+		pcb->eap.es_server.ea_type = EAPT_MD5CHAP;
+		eap_send_success(pcb);
+		eap_figure_next_state(pcb, 0);
+		if (pcb->eap.es_rechallenge != 0)
+			TIMEOUT(eap_rechallenge, pcb, pcb->eap.es_rechallenge);
+		break;
+
+#ifdef USE_SRP
+	case EAPT_SRP:
+		if (len < 1) {
+			ppp_error("EAP: empty SRP Response");
+			eap_figure_next_state(pcb, 1);
+			break;
+		}
+		GETCHAR(typenum, inp);
+		len--;
+		switch (typenum) {
+		case EAPSRP_CKEY:
+			if (pcb->eap.es_server.ea_state != eapSRP1) {
+				ppp_error("EAP: unexpected SRP Subtype 1 Response");
+				eap_figure_next_state(pcb, 1);
+				break;
+			}
+			A.data = inp;
+			A.len = len;
+			ts = (struct t_server *)pcb->eap.es_server.ea_session;
+			assert(ts != NULL);
+			pcb->eap.es_server.ea_skey = t_servergetkey(ts, &A);
+			if (pcb->eap.es_server.ea_skey == NULL) {
+				/* Client's A value is bogus; terminate now */
+				ppp_error("EAP: bogus A value from client");
+				eap_send_failure(pcb);
+			} else {
+				eap_figure_next_state(pcb, 0);
+			}
+			break;
+
+		case EAPSRP_CVALIDATOR:
+			if (pcb->eap.es_server.ea_state != eapSRP2) {
+				ppp_error("EAP: unexpected SRP Subtype 2 Response");
+				eap_figure_next_state(pcb, 1);
+				break;
+			}
+			if (len < sizeof (u32_t) + SHA_DIGESTSIZE) {
+				ppp_error("EAP: M1 length %d < %d", len,
+				    sizeof (u32_t) + SHA_DIGESTSIZE);
+				eap_figure_next_state(pcb, 1);
+				break;
+			}
+			GETLONG(pcb->eap.es_server.ea_keyflags, inp);
+			ts = (struct t_server *)pcb->eap.es_server.ea_session;
+			assert(ts != NULL);
+			if (t_serververify(ts, inp)) {
+				ppp_info("EAP: unable to validate client identity");
+				eap_send_failure(pcb);
+				break;
+			}
+			eap_figure_next_state(pcb, 0);
+			break;
+
+		case EAPSRP_ACK:
+			if (pcb->eap.es_server.ea_state != eapSRP3) {
+				ppp_error("EAP: unexpected SRP Subtype 3 Response");
+				eap_send_failure(esp);
+				break;
+			}
+			pcb->eap.es_server.ea_type = EAPT_SRP;
+			eap_send_success(pcb, esp);
+			eap_figure_next_state(pcb, 0);
+			if (pcb->eap.es_rechallenge != 0)
+				TIMEOUT(eap_rechallenge, pcb,
+				    pcb->eap.es_rechallenge);
+			if (pcb->eap.es_lwrechallenge != 0)
+				TIMEOUT(srp_lwrechallenge, pcb,
+				    pcb->eap.es_lwrechallenge);
+			break;
+
+		case EAPSRP_LWRECHALLENGE:
+			if (pcb->eap.es_server.ea_state != eapSRP4) {
+				ppp_info("EAP: unexpected SRP Subtype 4 Response");
+				return;
+			}
+			if (len != SHA_DIGESTSIZE) {
+				ppp_error("EAP: bad Lightweight rechallenge "
+				    "response");
+				return;
+			}
+			SHA1Init(&ctxt);
+			vallen = id;
+			SHA1Update(&ctxt, &vallen, 1);
+			SHA1Update(&ctxt, pcb->eap.es_server.ea_skey,
+			    SESSION_KEY_LEN);
+			SHA1Update(&ctxt, pcb->eap.es_challenge, pcb->eap.es_challen);
+			SHA1Update(&ctxt, pcb->eap.es_server.ea_peer,
+			    pcb->eap.es_server.ea_peerlen);
+			SHA1Final(dig, &ctxt);
+			if (BCMP(dig, inp, SHA_DIGESTSIZE) != 0) {
+				ppp_error("EAP: failed Lightweight rechallenge");
+				eap_send_failure(pcb);
+				break;
+			}
+			pcb->eap.es_server.ea_state = eapOpen;
+			if (pcb->eap.es_lwrechallenge != 0)
+				TIMEOUT(srp_lwrechallenge, esp,
+				    pcb->eap.es_lwrechallenge);
+			break;
+		}
+		break;
+#endif /* USE_SRP */
+
+	default:
+		/* This can't happen. */
+		ppp_error("EAP: unknown Response type %d; ignored", typenum);
+		return;
+	}
+
+	if (pcb->settings.eap_timeout_time > 0) {
+		UNTIMEOUT(eap_server_timeout, pcb);
+	}
+
+	if (pcb->eap.es_server.ea_state != eapBadAuth &&
+	    pcb->eap.es_server.ea_state != eapOpen) {
+		pcb->eap.es_server.ea_id++;
+		eap_send_request(pcb);
+	}
+}
+#endif /* PPP_SERVER */
+
+/*
+ * eap_success - Receive EAP Success message (client mode).
+ */
+static void eap_success(ppp_pcb *pcb, u_char *inp, int id, int len) {
+	LWIP_UNUSED_ARG(id);
+
+	if (pcb->eap.es_client.ea_state != eapOpen && !eap_client_active(pcb)) {
+		ppp_dbglog("EAP unexpected success message in state %s (%d)",
+		    eap_state_name(pcb->eap.es_client.ea_state),
+		    pcb->eap.es_client.ea_state);
+		return;
+	}
+
+	if (pcb->settings.eap_req_time > 0) {
+		UNTIMEOUT(eap_client_timeout, pcb);
+	}
+
+	if (len > 0) {
+		/* This is odd.  The spec doesn't allow for this. */
+		PRINTMSG(inp, len);
+	}
+
+	pcb->eap.es_client.ea_state = eapOpen;
+	auth_withpeer_success(pcb, PPP_EAP, 0);
+}
+
+/*
+ * eap_failure - Receive EAP Failure message (client mode).
+ */
+static void eap_failure(ppp_pcb *pcb, u_char *inp, int id, int len) {
+	LWIP_UNUSED_ARG(id);
+
+	if (!eap_client_active(pcb)) {
+		ppp_dbglog("EAP unexpected failure message in state %s (%d)",
+		    eap_state_name(pcb->eap.es_client.ea_state),
+		    pcb->eap.es_client.ea_state);
+	}
+
+	if (pcb->settings.eap_req_time > 0) {
+		UNTIMEOUT(eap_client_timeout, pcb);
+	}
+
+	if (len > 0) {
+		/* This is odd.  The spec doesn't allow for this. */
+		PRINTMSG(inp, len);
+	}
+
+	pcb->eap.es_client.ea_state = eapBadAuth;
+
+	ppp_error("EAP: peer reports authentication failure");
+	auth_withpeer_fail(pcb, PPP_EAP);
+}
+
+/*
+ * eap_input - Handle received EAP message.
+ */
+static void eap_input(ppp_pcb *pcb, u_char *inp, int inlen) {
+	u_char code, id;
+	int len;
+
+	/*
+	 * Parse header (code, id and length).  If packet too short,
+	 * drop it.
+	 */
+	if (inlen < EAP_HEADERLEN) {
+		ppp_error("EAP: packet too short: %d < %d", inlen, EAP_HEADERLEN);
+		return;
+	}
+	GETCHAR(code, inp);
+	GETCHAR(id, inp);
+	GETSHORT(len, inp);
+	if (len < EAP_HEADERLEN || len > inlen) {
+		ppp_error("EAP: packet has illegal length field %d (%d..%d)", len,
+		    EAP_HEADERLEN, inlen);
+		return;
+	}
+	len -= EAP_HEADERLEN;
+
+	/* Dispatch based on message code */
+	switch (code) {
+	case EAP_REQUEST:
+		eap_request(pcb, inp, id, len);
+		break;
+
+#if PPP_SERVER
+	case EAP_RESPONSE:
+		eap_response(pcb, inp, id, len);
+		break;
+#endif /* PPP_SERVER */
+
+	case EAP_SUCCESS:
+		eap_success(pcb, inp, id, len);
+		break;
+
+	case EAP_FAILURE:
+		eap_failure(pcb, inp, id, len);
+		break;
+
+	default:				/* XXX Need code reject */
+		/* Note: it's not legal to send EAP Nak here. */
+		ppp_warn("EAP: unknown code %d received", code);
+		break;
+	}
+}
+
+#if PRINTPKT_SUPPORT
+/*
+ * eap_printpkt - print the contents of an EAP packet.
+ */
+static const char* const eap_codenames[] = {
+	"Request", "Response", "Success", "Failure"
+};
+
+static const char* const eap_typenames[] = {
+	"Identity", "Notification", "Nak", "MD5-Challenge",
+	"OTP", "Generic-Token", NULL, NULL,
+	"RSA", "DSS", "KEA", "KEA-Validate",
+	"TLS", "Defender", "Windows 2000", "Arcot",
+	"Cisco", "Nokia", "SRP"
+};
+
+static int eap_printpkt(const u_char *inp, int inlen, void (*printer) (void *, const char *, ...), void *arg) {
+	int code, id, len, rtype, vallen;
+	const u_char *pstart;
+	u32_t uval;
+
+	if (inlen < EAP_HEADERLEN)
+		return (0);
+	pstart = inp;
+	GETCHAR(code, inp);
+	GETCHAR(id, inp);
+	GETSHORT(len, inp);
+	if (len < EAP_HEADERLEN || len > inlen)
+		return (0);
+
+	if (code >= 1 && code <= (int)LWIP_ARRAYSIZE(eap_codenames))
+		printer(arg, " %s", eap_codenames[code-1]);
+	else
+		printer(arg, " code=0x%x", code);
+	printer(arg, " id=0x%x", id);
+	len -= EAP_HEADERLEN;
+	switch (code) {
+	case EAP_REQUEST:
+		if (len < 1) {
+			printer(arg, " <missing type>");
+			break;
+		}
+		GETCHAR(rtype, inp);
+		len--;
+		if (rtype >= 1 && rtype <= (int)LWIP_ARRAYSIZE(eap_typenames))
+			printer(arg, " %s", eap_typenames[rtype-1]);
+		else
+			printer(arg, " type=0x%x", rtype);
+		switch (rtype) {
+		case EAPT_IDENTITY:
+		case EAPT_NOTIFICATION:
+			if (len > 0) {
+				printer(arg, " <Message ");
+				ppp_print_string(inp, len, printer, arg);
+				printer(arg, ">");
+				INCPTR(len, inp);
+				len = 0;
+			} else {
+				printer(arg, " <No message>");
+			}
+			break;
+
+		case EAPT_MD5CHAP:
+			if (len <= 0)
+				break;
+			GETCHAR(vallen, inp);
+			len--;
+			if (vallen > len)
+				goto truncated;
+			printer(arg, " <Value%.*B>", vallen, inp);
+			INCPTR(vallen, inp);
+			len -= vallen;
+			if (len > 0) {
+				printer(arg, " <Name ");
+				ppp_print_string(inp, len, printer, arg);
+				printer(arg, ">");
+				INCPTR(len, inp);
+				len = 0;
+			} else {
+				printer(arg, " <No name>");
+			}
+			break;
+
+		case EAPT_SRP:
+			if (len < 3)
+				goto truncated;
+			GETCHAR(vallen, inp);
+			len--;
+			printer(arg, "-%d", vallen);
+			switch (vallen) {
+			case EAPSRP_CHALLENGE:
+				GETCHAR(vallen, inp);
+				len--;
+				if (vallen >= len)
+					goto truncated;
+				if (vallen > 0) {
+					printer(arg, " <Name ");
+					ppp_print_string(inp, vallen, printer,
+					    arg);
+					printer(arg, ">");
+				} else {
+					printer(arg, " <No name>");
+				}
+				INCPTR(vallen, inp);
+				len -= vallen;
+				GETCHAR(vallen, inp);
+				len--;
+				if (vallen >= len)
+					goto truncated;
+				printer(arg, " <s%.*B>", vallen, inp);
+				INCPTR(vallen, inp);
+				len -= vallen;
+				GETCHAR(vallen, inp);
+				len--;
+				if (vallen > len)
+					goto truncated;
+				if (vallen == 0) {
+					printer(arg, " <Default g=2>");
+				} else {
+					printer(arg, " <g%.*B>", vallen, inp);
+				}
+				INCPTR(vallen, inp);
+				len -= vallen;
+				if (len == 0) {
+					printer(arg, " <Default N>");
+				} else {
+					printer(arg, " <N%.*B>", len, inp);
+					INCPTR(len, inp);
+					len = 0;
+				}
+				break;
+
+			case EAPSRP_SKEY:
+				printer(arg, " <B%.*B>", len, inp);
+				INCPTR(len, inp);
+				len = 0;
+				break;
+
+			case EAPSRP_SVALIDATOR:
+				if (len < (int)sizeof (u32_t))
+					break;
+				GETLONG(uval, inp);
+				len -= sizeof (u32_t);
+				if (uval & SRPVAL_EBIT) {
+					printer(arg, " E");
+					uval &= ~SRPVAL_EBIT;
+				}
+				if (uval != 0) {
+					printer(arg, " f<%X>", uval);
+				}
+				if ((vallen = len) > SHA_DIGESTSIZE)
+					vallen = SHA_DIGESTSIZE;
+				printer(arg, " <M2%.*B%s>", len, inp,
+				    len < SHA_DIGESTSIZE ? "?" : "");
+				INCPTR(vallen, inp);
+				len -= vallen;
+				if (len > 0) {
+					printer(arg, " <PN%.*B>", len, inp);
+					INCPTR(len, inp);
+					len = 0;
+				}
+				break;
+
+			case EAPSRP_LWRECHALLENGE:
+				printer(arg, " <Challenge%.*B>", len, inp);
+				INCPTR(len, inp);
+				len = 0;
+				break;
+			default:
+				break;
+			}
+			break;
+		default:
+			break;
+		}
+		break;
+
+	case EAP_RESPONSE:
+		if (len < 1)
+			break;
+		GETCHAR(rtype, inp);
+		len--;
+		if (rtype >= 1 && rtype <= (int)LWIP_ARRAYSIZE(eap_typenames))
+			printer(arg, " %s", eap_typenames[rtype-1]);
+		else
+			printer(arg, " type=0x%x", rtype);
+		switch (rtype) {
+		case EAPT_IDENTITY:
+			if (len > 0) {
+				printer(arg, " <Name ");
+				ppp_print_string(inp, len, printer, arg);
+				printer(arg, ">");
+				INCPTR(len, inp);
+				len = 0;
+			}
+			break;
+
+		case EAPT_NAK:
+			if (len <= 0) {
+				printer(arg, " <missing hint>");
+				break;
+			}
+			GETCHAR(rtype, inp);
+			len--;
+			printer(arg, " <Suggested-type %02X", rtype);
+			if (rtype >= 1 && rtype < (int)LWIP_ARRAYSIZE(eap_typenames))
+				printer(arg, " (%s)", eap_typenames[rtype-1]);
+			printer(arg, ">");
+			break;
+
+		case EAPT_MD5CHAP:
+			if (len <= 0) {
+				printer(arg, " <missing length>");
+				break;
+			}
+			GETCHAR(vallen, inp);
+			len--;
+			if (vallen > len)
+				goto truncated;
+			printer(arg, " <Value%.*B>", vallen, inp);
+			INCPTR(vallen, inp);
+			len -= vallen;
+			if (len > 0) {
+				printer(arg, " <Name ");
+				ppp_print_string(inp, len, printer, arg);
+				printer(arg, ">");
+				INCPTR(len, inp);
+				len = 0;
+			} else {
+				printer(arg, " <No name>");
+			}
+			break;
+
+		case EAPT_SRP:
+			if (len < 1)
+				goto truncated;
+			GETCHAR(vallen, inp);
+			len--;
+			printer(arg, "-%d", vallen);
+			switch (vallen) {
+			case EAPSRP_CKEY:
+				printer(arg, " <A%.*B>", len, inp);
+				INCPTR(len, inp);
+				len = 0;
+				break;
+
+			case EAPSRP_CVALIDATOR:
+				if (len < (int)sizeof (u32_t))
+					break;
+				GETLONG(uval, inp);
+				len -= sizeof (u32_t);
+				if (uval & SRPVAL_EBIT) {
+					printer(arg, " E");
+					uval &= ~SRPVAL_EBIT;
+				}
+				if (uval != 0) {
+					printer(arg, " f<%X>", uval);
+				}
+				printer(arg, " <M1%.*B%s>", len, inp,
+				    len == SHA_DIGESTSIZE ? "" : "?");
+				INCPTR(len, inp);
+				len = 0;
+				break;
+
+			case EAPSRP_ACK:
+				break;
+
+			case EAPSRP_LWRECHALLENGE:
+				printer(arg, " <Response%.*B%s>", len, inp,
+				    len == SHA_DIGESTSIZE ? "" : "?");
+				if ((vallen = len) > SHA_DIGESTSIZE)
+					vallen = SHA_DIGESTSIZE;
+				INCPTR(vallen, inp);
+				len -= vallen;
+				break;
+			default:
+				break;
+			}
+			break;
+		default:
+			break;
+		}
+		break;
+
+	case EAP_SUCCESS:	/* No payload expected for these! */
+	case EAP_FAILURE:
+	default:
+		break;
+
+	truncated:
+		printer(arg, " <truncated>");
+		break;
+	}
+
+	if (len > 8)
+		printer(arg, "%8B...", inp);
+	else if (len > 0)
+		printer(arg, "%.*B", len, inp);
+	INCPTR(len, inp);
+
+	return (inp - pstart);
+}
+#endif /* PRINTPKT_SUPPORT */
+
+#endif /* PPP_SUPPORT && EAP_SUPPORT */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/netif/ppp/ecp.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/netif/ppp/ecp.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/netif/ppp/ecp.c	(revision 457)
@@ -0,0 +1,191 @@
+/*
+ * ecp.c - PPP Encryption Control Protocol.
+ *
+ * Copyright (c) 2002 Google, Inc.
+ * 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. The name(s) of the authors of this software must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission.
+ *
+ * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO
+ * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
+ * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
+ * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
+ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Derived from ccp.c, which is:
+ *
+ * Copyright (c) 1994-2002 Paul Mackerras. 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. The name(s) of the authors of this software must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission.
+ *
+ * 3. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by Paul Mackerras
+ *     <paulus@samba.org>".
+ *
+ * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO
+ * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
+ * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
+ * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
+ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include "netif/ppp/ppp_opts.h"
+#if PPP_SUPPORT && ECP_SUPPORT  /* don't build if not configured for use in lwipopts.h */
+
+#include <string.h>
+
+#include "netif/ppp/ppp_impl.h"
+
+#include "netif/ppp/fsm.h"
+#include "netif/ppp/ecp.h"
+
+#if PPP_OPTIONS
+static option_t ecp_option_list[] = {
+    { "noecp", o_bool, &ecp_protent.enabled_flag,
+      "Disable ECP negotiation" },
+    { "-ecp", o_bool, &ecp_protent.enabled_flag,
+      "Disable ECP negotiation", OPT_ALIAS },
+
+    { NULL }
+};
+#endif /* PPP_OPTIONS */
+
+/*
+ * Protocol entry points from main code.
+ */
+static void ecp_init (int unit);
+/*
+static void ecp_open (int unit);
+static void ecp_close (int unit, char *);
+static void ecp_lowerup (int unit);
+static void ecp_lowerdown (int);
+static void ecp_input (int unit, u_char *pkt, int len);
+static void ecp_protrej (int unit);
+*/
+#if PRINTPKT_SUPPORT
+static int  ecp_printpkt (const u_char *pkt, int len,
+			      void (*printer) (void *, char *, ...),
+			      void *arg);
+#endif /* PRINTPKT_SUPPORT */
+/*
+static void ecp_datainput (int unit, u_char *pkt, int len);
+*/
+
+const struct protent ecp_protent = {
+    PPP_ECP,
+    ecp_init,
+    NULL, /* ecp_input, */
+    NULL, /* ecp_protrej, */
+    NULL, /* ecp_lowerup, */
+    NULL, /* ecp_lowerdown, */
+    NULL, /* ecp_open, */
+    NULL, /* ecp_close, */
+#if PRINTPKT_SUPPORT
+    ecp_printpkt,
+#endif /* PRINTPKT_SUPPORT */
+#if PPP_DATAINPUT
+    NULL, /* ecp_datainput, */
+#endif /* PPP_DATAINPUT */
+#if PRINTPKT_SUPPORT
+    "ECP",
+    "Encrypted",
+#endif /* PRINTPKT_SUPPORT */
+#if PPP_OPTIONS
+    ecp_option_list,
+    NULL,
+#endif /* PPP_OPTIONS */
+#if DEMAND_SUPPORT
+    NULL,
+    NULL
+#endif /* DEMAND_SUPPORT */
+};
+
+fsm ecp_fsm[NUM_PPP];
+ecp_options ecp_wantoptions[NUM_PPP];	/* what to request the peer to use */
+ecp_options ecp_gotoptions[NUM_PPP];	/* what the peer agreed to do */
+ecp_options ecp_allowoptions[NUM_PPP];	/* what we'll agree to do */
+ecp_options ecp_hisoptions[NUM_PPP];	/* what we agreed to do */
+
+static const fsm_callbacks ecp_callbacks = {
+    NULL, /* ecp_resetci, */
+    NULL, /* ecp_cilen, */
+    NULL, /* ecp_addci, */
+    NULL, /* ecp_ackci, */
+    NULL, /* ecp_nakci, */
+    NULL, /* ecp_rejci, */
+    NULL, /* ecp_reqci, */
+    NULL, /* ecp_up, */
+    NULL, /* ecp_down, */
+    NULL,
+    NULL,
+    NULL,
+    NULL,
+    NULL, /* ecp_extcode, */
+    "ECP"
+};
+
+/*
+ * ecp_init - initialize ECP.
+ */
+static void
+ecp_init(unit)
+    int unit;
+{
+    fsm *f = &ecp_fsm[unit];
+
+    f->unit = unit;
+    f->protocol = PPP_ECP;
+    f->callbacks = &ecp_callbacks;
+    fsm_init(f);
+
+#if 0 /* Not necessary, everything is cleared in ppp_new() */
+    memset(&ecp_wantoptions[unit],  0, sizeof(ecp_options));
+    memset(&ecp_gotoptions[unit],   0, sizeof(ecp_options));
+    memset(&ecp_allowoptions[unit], 0, sizeof(ecp_options));
+    memset(&ecp_hisoptions[unit],   0, sizeof(ecp_options));
+#endif /* 0 */
+
+}
+
+
+#if PRINTPKT_SUPPORT
+static int
+ecp_printpkt(p, plen, printer, arg)
+    const u_char *p;
+    int plen;
+    void (*printer) (void *, char *, ...);
+    void *arg;
+{
+    return 0;
+}
+#endif /* PRINTPKT_SUPPORT */
+
+#endif /* PPP_SUPPORT && ECP_SUPPORT */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/netif/ppp/eui64.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/netif/ppp/eui64.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/netif/ppp/eui64.c	(revision 457)
@@ -0,0 +1,56 @@
+/*
+ * eui64.c - EUI64 routines for IPv6CP.
+ *
+ * Copyright (c) 1999 Tommi Komulainen.  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. The name(s) of the authors of this software must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission.
+ *
+ * 4. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by Tommi Komulainen
+ *     <Tommi.Komulainen@iki.fi>".
+ *
+ * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO
+ * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
+ * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
+ * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
+ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * $Id$
+ */
+
+#include "netif/ppp/ppp_opts.h"
+#if PPP_SUPPORT && PPP_IPV6_SUPPORT  /* don't build if not configured for use in lwipopts.h */
+
+#include "netif/ppp/ppp_impl.h"
+#include "netif/ppp/eui64.h"
+
+/*
+ * eui64_ntoa - Make an ascii representation of an interface identifier
+ */
+char *eui64_ntoa(eui64_t e) {
+    static char buf[20];
+
+    sprintf(buf, "%02x%02x:%02x%02x:%02x%02x:%02x%02x",
+	     e.e8[0], e.e8[1], e.e8[2], e.e8[3], 
+	     e.e8[4], e.e8[5], e.e8[6], e.e8[7]);
+    return buf;
+}
+
+#endif /* PPP_SUPPORT && PPP_IPV6_SUPPORT */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/netif/ppp/fsm.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/netif/ppp/fsm.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/netif/ppp/fsm.c	(revision 457)
@@ -0,0 +1,799 @@
+/*
+ * fsm.c - {Link, IP} Control Protocol Finite State Machine.
+ *
+ * Copyright (c) 1984-2000 Carnegie Mellon University. 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. The name "Carnegie Mellon University" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For permission or any legal
+ *    details, please contact
+ *      Office of Technology Transfer
+ *      Carnegie Mellon University
+ *      5000 Forbes Avenue
+ *      Pittsburgh, PA  15213-3890
+ *      (412) 268-4387, fax: (412) 268-7395
+ *      tech-transfer@andrew.cmu.edu
+ *
+ * 4. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by Computing Services
+ *     at Carnegie Mellon University (http://www.cmu.edu/computing/)."
+ *
+ * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO
+ * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE
+ * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
+ * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
+ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include "netif/ppp/ppp_opts.h"
+#if PPP_SUPPORT /* don't build if not configured for use in lwipopts.h */
+
+/*
+ * @todo:
+ * Randomize fsm id on link/init.
+ * Deal with variable outgoing MTU.
+ */
+
+#if 0 /* UNUSED */
+#include <stdio.h>
+#include <string.h>
+#include <sys/types.h>
+#endif /* UNUSED */
+
+#include "netif/ppp/ppp_impl.h"
+
+#include "netif/ppp/fsm.h"
+
+static void fsm_timeout (void *);
+static void fsm_rconfreq(fsm *f, u_char id, u_char *inp, int len);
+static void fsm_rconfack(fsm *f, int id, u_char *inp, int len);
+static void fsm_rconfnakrej(fsm *f, int code, int id, u_char *inp, int len);
+static void fsm_rtermreq(fsm *f, int id, u_char *p, int len);
+static void fsm_rtermack(fsm *f);
+static void fsm_rcoderej(fsm *f, u_char *inp, int len);
+static void fsm_sconfreq(fsm *f, int retransmit);
+
+#define PROTO_NAME(f)	((f)->callbacks->proto_name)
+
+/*
+ * fsm_init - Initialize fsm.
+ *
+ * Initialize fsm state.
+ */
+void fsm_init(fsm *f) {
+    ppp_pcb *pcb = f->pcb;
+    f->state = PPP_FSM_INITIAL;
+    f->flags = 0;
+    f->id = 0;				/* XXX Start with random id? */
+    f->maxnakloops = pcb->settings.fsm_max_nak_loops;
+    f->term_reason_len = 0;
+}
+
+
+/*
+ * fsm_lowerup - The lower layer is up.
+ */
+void fsm_lowerup(fsm *f) {
+    switch( f->state ){
+    case PPP_FSM_INITIAL:
+	f->state = PPP_FSM_CLOSED;
+	break;
+
+    case PPP_FSM_STARTING:
+	if( f->flags & OPT_SILENT )
+	    f->state = PPP_FSM_STOPPED;
+	else {
+	    /* Send an initial configure-request */
+	    fsm_sconfreq(f, 0);
+	    f->state = PPP_FSM_REQSENT;
+	}
+	break;
+
+    default:
+	FSMDEBUG(("%s: Up event in state %d!", PROTO_NAME(f), f->state));
+	/* no break */
+    }
+}
+
+
+/*
+ * fsm_lowerdown - The lower layer is down.
+ *
+ * Cancel all timeouts and inform upper layers.
+ */
+void fsm_lowerdown(fsm *f) {
+    switch( f->state ){
+    case PPP_FSM_CLOSED:
+	f->state = PPP_FSM_INITIAL;
+	break;
+
+    case PPP_FSM_STOPPED:
+	f->state = PPP_FSM_STARTING;
+	if( f->callbacks->starting )
+	    (*f->callbacks->starting)(f);
+	break;
+
+    case PPP_FSM_CLOSING:
+	f->state = PPP_FSM_INITIAL;
+	UNTIMEOUT(fsm_timeout, f);	/* Cancel timeout */
+	break;
+
+    case PPP_FSM_STOPPING:
+    case PPP_FSM_REQSENT:
+    case PPP_FSM_ACKRCVD:
+    case PPP_FSM_ACKSENT:
+	f->state = PPP_FSM_STARTING;
+	UNTIMEOUT(fsm_timeout, f);	/* Cancel timeout */
+	break;
+
+    case PPP_FSM_OPENED:
+	if( f->callbacks->down )
+	    (*f->callbacks->down)(f);
+	f->state = PPP_FSM_STARTING;
+	break;
+
+    default:
+	FSMDEBUG(("%s: Down event in state %d!", PROTO_NAME(f), f->state));
+	/* no break */
+    }
+}
+
+
+/*
+ * fsm_open - Link is allowed to come up.
+ */
+void fsm_open(fsm *f) {
+    switch( f->state ){
+    case PPP_FSM_INITIAL:
+	f->state = PPP_FSM_STARTING;
+	if( f->callbacks->starting )
+	    (*f->callbacks->starting)(f);
+	break;
+
+    case PPP_FSM_CLOSED:
+	if( f->flags & OPT_SILENT )
+	    f->state = PPP_FSM_STOPPED;
+	else {
+	    /* Send an initial configure-request */
+	    fsm_sconfreq(f, 0);
+	    f->state = PPP_FSM_REQSENT;
+	}
+	break;
+
+    case PPP_FSM_CLOSING:
+	f->state = PPP_FSM_STOPPING;
+	/* fall through */
+	/* no break */
+    case PPP_FSM_STOPPED:
+    case PPP_FSM_OPENED:
+	if( f->flags & OPT_RESTART ){
+	    fsm_lowerdown(f);
+	    fsm_lowerup(f);
+	}
+	break;
+    default:
+	break;
+    }
+}
+
+/*
+ * terminate_layer - Start process of shutting down the FSM
+ *
+ * Cancel any timeout running, notify upper layers we're done, and
+ * send a terminate-request message as configured.
+ */
+static void terminate_layer(fsm *f, int nextstate) {
+    ppp_pcb *pcb = f->pcb;
+
+    if( f->state != PPP_FSM_OPENED )
+	UNTIMEOUT(fsm_timeout, f);	/* Cancel timeout */
+    else if( f->callbacks->down )
+	(*f->callbacks->down)(f);	/* Inform upper layers we're down */
+
+    /* Init restart counter and send Terminate-Request */
+    f->retransmits = pcb->settings.fsm_max_term_transmits;
+    fsm_sdata(f, TERMREQ, f->reqid = ++f->id,
+	      (const u_char *) f->term_reason, f->term_reason_len);
+
+    if (f->retransmits == 0) {
+	/*
+	 * User asked for no terminate requests at all; just close it.
+	 * We've already fired off one Terminate-Request just to be nice
+	 * to the peer, but we're not going to wait for a reply.
+	 */
+	f->state = nextstate == PPP_FSM_CLOSING ? PPP_FSM_CLOSED : PPP_FSM_STOPPED;
+	if( f->callbacks->finished )
+	    (*f->callbacks->finished)(f);
+	return;
+    }
+
+    TIMEOUT(fsm_timeout, f, pcb->settings.fsm_timeout_time);
+    --f->retransmits;
+
+    f->state = nextstate;
+}
+
+/*
+ * fsm_close - Start closing connection.
+ *
+ * Cancel timeouts and either initiate close or possibly go directly to
+ * the PPP_FSM_CLOSED state.
+ */
+void fsm_close(fsm *f, const char *reason) {
+    f->term_reason = reason;
+    f->term_reason_len = (reason == NULL? 0: (u8_t)LWIP_MIN(strlen(reason), 0xFF) );
+    switch( f->state ){
+    case PPP_FSM_STARTING:
+	f->state = PPP_FSM_INITIAL;
+	break;
+    case PPP_FSM_STOPPED:
+	f->state = PPP_FSM_CLOSED;
+	break;
+    case PPP_FSM_STOPPING:
+	f->state = PPP_FSM_CLOSING;
+	break;
+
+    case PPP_FSM_REQSENT:
+    case PPP_FSM_ACKRCVD:
+    case PPP_FSM_ACKSENT:
+    case PPP_FSM_OPENED:
+	terminate_layer(f, PPP_FSM_CLOSING);
+	break;
+    default:
+	break;
+    }
+}
+
+
+/*
+ * fsm_timeout - Timeout expired.
+ */
+static void fsm_timeout(void *arg) {
+    fsm *f = (fsm *) arg;
+    ppp_pcb *pcb = f->pcb;
+
+    switch (f->state) {
+    case PPP_FSM_CLOSING:
+    case PPP_FSM_STOPPING:
+	if( f->retransmits <= 0 ){
+	    /*
+	     * We've waited for an ack long enough.  Peer probably heard us.
+	     */
+	    f->state = (f->state == PPP_FSM_CLOSING)? PPP_FSM_CLOSED: PPP_FSM_STOPPED;
+	    if( f->callbacks->finished )
+		(*f->callbacks->finished)(f);
+	} else {
+	    /* Send Terminate-Request */
+	    fsm_sdata(f, TERMREQ, f->reqid = ++f->id,
+		      (const u_char *) f->term_reason, f->term_reason_len);
+	    TIMEOUT(fsm_timeout, f, pcb->settings.fsm_timeout_time);
+	    --f->retransmits;
+	}
+	break;
+
+    case PPP_FSM_REQSENT:
+    case PPP_FSM_ACKRCVD:
+    case PPP_FSM_ACKSENT:
+	if (f->retransmits <= 0) {
+	    ppp_warn("%s: timeout sending Config-Requests", PROTO_NAME(f));
+	    f->state = PPP_FSM_STOPPED;
+	    if( (f->flags & OPT_PASSIVE) == 0 && f->callbacks->finished )
+		(*f->callbacks->finished)(f);
+
+	} else {
+	    /* Retransmit the configure-request */
+	    if (f->callbacks->retransmit)
+		(*f->callbacks->retransmit)(f);
+	    fsm_sconfreq(f, 1);		/* Re-send Configure-Request */
+	    if( f->state == PPP_FSM_ACKRCVD )
+		f->state = PPP_FSM_REQSENT;
+	}
+	break;
+
+    default:
+	FSMDEBUG(("%s: Timeout event in state %d!", PROTO_NAME(f), f->state));
+	/* no break */
+    }
+}
+
+
+/*
+ * fsm_input - Input packet.
+ */
+void fsm_input(fsm *f, u_char *inpacket, int l) {
+    u_char *inp;
+    u_char code, id;
+    int len;
+
+    /*
+     * Parse header (code, id and length).
+     * If packet too short, drop it.
+     */
+    inp = inpacket;
+    if (l < HEADERLEN) {
+	FSMDEBUG(("fsm_input(%x): Rcvd short header.", f->protocol));
+	return;
+    }
+    GETCHAR(code, inp);
+    GETCHAR(id, inp);
+    GETSHORT(len, inp);
+    if (len < HEADERLEN) {
+	FSMDEBUG(("fsm_input(%x): Rcvd illegal length.", f->protocol));
+	return;
+    }
+    if (len > l) {
+	FSMDEBUG(("fsm_input(%x): Rcvd short packet.", f->protocol));
+	return;
+    }
+    len -= HEADERLEN;		/* subtract header length */
+
+    if( f->state == PPP_FSM_INITIAL || f->state == PPP_FSM_STARTING ){
+	FSMDEBUG(("fsm_input(%x): Rcvd packet in state %d.",
+		  f->protocol, f->state));
+	return;
+    }
+
+    /*
+     * Action depends on code.
+     */
+    switch (code) {
+    case CONFREQ:
+	fsm_rconfreq(f, id, inp, len);
+	break;
+    
+    case CONFACK:
+	fsm_rconfack(f, id, inp, len);
+	break;
+    
+    case CONFNAK:
+    case CONFREJ:
+	fsm_rconfnakrej(f, code, id, inp, len);
+	break;
+    
+    case TERMREQ:
+	fsm_rtermreq(f, id, inp, len);
+	break;
+    
+    case TERMACK:
+	fsm_rtermack(f);
+	break;
+    
+    case CODEREJ:
+	fsm_rcoderej(f, inp, len);
+	break;
+    
+    default:
+	if( !f->callbacks->extcode
+	   || !(*f->callbacks->extcode)(f, code, id, inp, len) )
+	    fsm_sdata(f, CODEREJ, ++f->id, inpacket, len + HEADERLEN);
+	break;
+    }
+}
+
+
+/*
+ * fsm_rconfreq - Receive Configure-Request.
+ */
+static void fsm_rconfreq(fsm *f, u_char id, u_char *inp, int len) {
+    int code, reject_if_disagree;
+
+    switch( f->state ){
+    case PPP_FSM_CLOSED:
+	/* Go away, we're closed */
+	fsm_sdata(f, TERMACK, id, NULL, 0);
+	return;
+    case PPP_FSM_CLOSING:
+    case PPP_FSM_STOPPING:
+	return;
+
+    case PPP_FSM_OPENED:
+	/* Go down and restart negotiation */
+	if( f->callbacks->down )
+	    (*f->callbacks->down)(f);	/* Inform upper layers */
+	fsm_sconfreq(f, 0);		/* Send initial Configure-Request */
+	f->state = PPP_FSM_REQSENT;
+	break;
+
+    case PPP_FSM_STOPPED:
+	/* Negotiation started by our peer */
+	fsm_sconfreq(f, 0);		/* Send initial Configure-Request */
+	f->state = PPP_FSM_REQSENT;
+	break;
+    default:
+	break;
+    }
+
+    /*
+     * Pass the requested configuration options
+     * to protocol-specific code for checking.
+     */
+    if (f->callbacks->reqci){		/* Check CI */
+	reject_if_disagree = (f->nakloops >= f->maxnakloops);
+	code = (*f->callbacks->reqci)(f, inp, &len, reject_if_disagree);
+    } else if (len)
+	code = CONFREJ;			/* Reject all CI */
+    else
+	code = CONFACK;
+
+    /* send the Ack, Nak or Rej to the peer */
+    fsm_sdata(f, code, id, inp, len);
+
+    if (code == CONFACK) {
+	if (f->state == PPP_FSM_ACKRCVD) {
+	    UNTIMEOUT(fsm_timeout, f);	/* Cancel timeout */
+	    f->state = PPP_FSM_OPENED;
+	    if (f->callbacks->up)
+		(*f->callbacks->up)(f);	/* Inform upper layers */
+	} else
+	    f->state = PPP_FSM_ACKSENT;
+	f->nakloops = 0;
+
+    } else {
+	/* we sent CONFACK or CONFREJ */
+	if (f->state != PPP_FSM_ACKRCVD)
+	    f->state = PPP_FSM_REQSENT;
+	if( code == CONFNAK )
+	    ++f->nakloops;
+    }
+}
+
+
+/*
+ * fsm_rconfack - Receive Configure-Ack.
+ */
+static void fsm_rconfack(fsm *f, int id, u_char *inp, int len) {
+    ppp_pcb *pcb = f->pcb;
+
+    if (id != f->reqid || f->seen_ack)		/* Expected id? */
+	return;					/* Nope, toss... */
+    if( !(f->callbacks->ackci? (*f->callbacks->ackci)(f, inp, len):
+	  (len == 0)) ){
+	/* Ack is bad - ignore it */
+	ppp_error("Received bad configure-ack: %P", inp, len);
+	return;
+    }
+    f->seen_ack = 1;
+    f->rnakloops = 0;
+
+    switch (f->state) {
+    case PPP_FSM_CLOSED:
+    case PPP_FSM_STOPPED:
+	fsm_sdata(f, TERMACK, id, NULL, 0);
+	break;
+
+    case PPP_FSM_REQSENT:
+	f->state = PPP_FSM_ACKRCVD;
+	f->retransmits = pcb->settings.fsm_max_conf_req_transmits;
+	break;
+
+    case PPP_FSM_ACKRCVD:
+	/* Huh? an extra valid Ack? oh well... */
+	UNTIMEOUT(fsm_timeout, f);	/* Cancel timeout */
+	fsm_sconfreq(f, 0);
+	f->state = PPP_FSM_REQSENT;
+	break;
+
+    case PPP_FSM_ACKSENT:
+	UNTIMEOUT(fsm_timeout, f);	/* Cancel timeout */
+	f->state = PPP_FSM_OPENED;
+	f->retransmits = pcb->settings.fsm_max_conf_req_transmits;
+	if (f->callbacks->up)
+	    (*f->callbacks->up)(f);	/* Inform upper layers */
+	break;
+
+    case PPP_FSM_OPENED:
+	/* Go down and restart negotiation */
+	if (f->callbacks->down)
+	    (*f->callbacks->down)(f);	/* Inform upper layers */
+	fsm_sconfreq(f, 0);		/* Send initial Configure-Request */
+	f->state = PPP_FSM_REQSENT;
+	break;
+    default:
+	break;
+    }
+}
+
+
+/*
+ * fsm_rconfnakrej - Receive Configure-Nak or Configure-Reject.
+ */
+static void fsm_rconfnakrej(fsm *f, int code, int id, u_char *inp, int len) {
+    int ret;
+    int treat_as_reject;
+
+    if (id != f->reqid || f->seen_ack)	/* Expected id? */
+	return;				/* Nope, toss... */
+
+    if (code == CONFNAK) {
+	++f->rnakloops;
+	treat_as_reject = (f->rnakloops >= f->maxnakloops);
+	if (f->callbacks->nakci == NULL
+	    || !(ret = f->callbacks->nakci(f, inp, len, treat_as_reject))) {
+	    ppp_error("Received bad configure-nak: %P", inp, len);
+	    return;
+	}
+    } else {
+	f->rnakloops = 0;
+	if (f->callbacks->rejci == NULL
+	    || !(ret = f->callbacks->rejci(f, inp, len))) {
+	    ppp_error("Received bad configure-rej: %P", inp, len);
+	    return;
+	}
+    }
+
+    f->seen_ack = 1;
+
+    switch (f->state) {
+    case PPP_FSM_CLOSED:
+    case PPP_FSM_STOPPED:
+	fsm_sdata(f, TERMACK, id, NULL, 0);
+	break;
+
+    case PPP_FSM_REQSENT:
+    case PPP_FSM_ACKSENT:
+	/* They didn't agree to what we wanted - try another request */
+	UNTIMEOUT(fsm_timeout, f);	/* Cancel timeout */
+	if (ret < 0)
+	    f->state = PPP_FSM_STOPPED;		/* kludge for stopping CCP */
+	else
+	    fsm_sconfreq(f, 0);		/* Send Configure-Request */
+	break;
+
+    case PPP_FSM_ACKRCVD:
+	/* Got a Nak/reject when we had already had an Ack?? oh well... */
+	UNTIMEOUT(fsm_timeout, f);	/* Cancel timeout */
+	fsm_sconfreq(f, 0);
+	f->state = PPP_FSM_REQSENT;
+	break;
+
+    case PPP_FSM_OPENED:
+	/* Go down and restart negotiation */
+	if (f->callbacks->down)
+	    (*f->callbacks->down)(f);	/* Inform upper layers */
+	fsm_sconfreq(f, 0);		/* Send initial Configure-Request */
+	f->state = PPP_FSM_REQSENT;
+	break;
+    default:
+	break;
+    }
+}
+
+
+/*
+ * fsm_rtermreq - Receive Terminate-Req.
+ */
+static void fsm_rtermreq(fsm *f, int id, u_char *p, int len) {
+    ppp_pcb *pcb = f->pcb;
+
+    switch (f->state) {
+    case PPP_FSM_ACKRCVD:
+    case PPP_FSM_ACKSENT:
+	f->state = PPP_FSM_REQSENT;		/* Start over but keep trying */
+	break;
+
+    case PPP_FSM_OPENED:
+	if (len > 0) {
+	    ppp_info("%s terminated by peer (%0.*v)", PROTO_NAME(f), len, p);
+	} else
+	    ppp_info("%s terminated by peer", PROTO_NAME(f));
+	f->retransmits = 0;
+	f->state = PPP_FSM_STOPPING;
+	if (f->callbacks->down)
+	    (*f->callbacks->down)(f);	/* Inform upper layers */
+	TIMEOUT(fsm_timeout, f, pcb->settings.fsm_timeout_time);
+	break;
+    default:
+	break;
+    }
+
+    fsm_sdata(f, TERMACK, id, NULL, 0);
+}
+
+
+/*
+ * fsm_rtermack - Receive Terminate-Ack.
+ */
+static void fsm_rtermack(fsm *f) {
+    switch (f->state) {
+    case PPP_FSM_CLOSING:
+	UNTIMEOUT(fsm_timeout, f);
+	f->state = PPP_FSM_CLOSED;
+	if( f->callbacks->finished )
+	    (*f->callbacks->finished)(f);
+	break;
+    case PPP_FSM_STOPPING:
+	UNTIMEOUT(fsm_timeout, f);
+	f->state = PPP_FSM_STOPPED;
+	if( f->callbacks->finished )
+	    (*f->callbacks->finished)(f);
+	break;
+
+    case PPP_FSM_ACKRCVD:
+	f->state = PPP_FSM_REQSENT;
+	break;
+
+    case PPP_FSM_OPENED:
+	if (f->callbacks->down)
+	    (*f->callbacks->down)(f);	/* Inform upper layers */
+	fsm_sconfreq(f, 0);
+	f->state = PPP_FSM_REQSENT;
+	break;
+    default:
+	break;
+    }
+}
+
+
+/*
+ * fsm_rcoderej - Receive an Code-Reject.
+ */
+static void fsm_rcoderej(fsm *f, u_char *inp, int len) {
+    u_char code, id;
+
+    if (len < HEADERLEN) {
+	FSMDEBUG(("fsm_rcoderej: Rcvd short Code-Reject packet!"));
+	return;
+    }
+    GETCHAR(code, inp);
+    GETCHAR(id, inp);
+    ppp_warn("%s: Rcvd Code-Reject for code %d, id %d", PROTO_NAME(f), code, id);
+
+    if( f->state == PPP_FSM_ACKRCVD )
+	f->state = PPP_FSM_REQSENT;
+}
+
+
+/*
+ * fsm_protreject - Peer doesn't speak this protocol.
+ *
+ * Treat this as a catastrophic error (RXJ-).
+ */
+void fsm_protreject(fsm *f) {
+    switch( f->state ){
+    case PPP_FSM_CLOSING:
+	UNTIMEOUT(fsm_timeout, f);	/* Cancel timeout */
+	/* fall through */
+	/* no break */
+    case PPP_FSM_CLOSED:
+	f->state = PPP_FSM_CLOSED;
+	if( f->callbacks->finished )
+	    (*f->callbacks->finished)(f);
+	break;
+
+    case PPP_FSM_STOPPING:
+    case PPP_FSM_REQSENT:
+    case PPP_FSM_ACKRCVD:
+    case PPP_FSM_ACKSENT:
+	UNTIMEOUT(fsm_timeout, f);	/* Cancel timeout */
+	/* fall through */
+	/* no break */
+    case PPP_FSM_STOPPED:
+	f->state = PPP_FSM_STOPPED;
+	if( f->callbacks->finished )
+	    (*f->callbacks->finished)(f);
+	break;
+
+    case PPP_FSM_OPENED:
+	terminate_layer(f, PPP_FSM_STOPPING);
+	break;
+
+    default:
+	FSMDEBUG(("%s: Protocol-reject event in state %d!",
+		  PROTO_NAME(f), f->state));
+	/* no break */
+    }
+}
+
+
+/*
+ * fsm_sconfreq - Send a Configure-Request.
+ */
+static void fsm_sconfreq(fsm *f, int retransmit) {
+    ppp_pcb *pcb = f->pcb;
+    struct pbuf *p;
+    u_char *outp;
+    int cilen;
+
+    if( f->state != PPP_FSM_REQSENT && f->state != PPP_FSM_ACKRCVD && f->state != PPP_FSM_ACKSENT ){
+	/* Not currently negotiating - reset options */
+	if( f->callbacks->resetci )
+	    (*f->callbacks->resetci)(f);
+	f->nakloops = 0;
+	f->rnakloops = 0;
+    }
+
+    if( !retransmit ){
+	/* New request - reset retransmission counter, use new ID */
+	f->retransmits = pcb->settings.fsm_max_conf_req_transmits;
+	f->reqid = ++f->id;
+    }
+
+    f->seen_ack = 0;
+
+    /*
+     * Make up the request packet
+     */
+    if( f->callbacks->cilen && f->callbacks->addci ){
+	cilen = (*f->callbacks->cilen)(f);
+	if( cilen > pcb->peer_mru - HEADERLEN )
+	    cilen = pcb->peer_mru - HEADERLEN;
+    } else
+	cilen = 0;
+
+    p = pbuf_alloc(PBUF_RAW, (u16_t)(cilen + HEADERLEN + PPP_HDRLEN), PPP_CTRL_PBUF_TYPE);
+    if(NULL == p)
+        return;
+    if(p->tot_len != p->len) {
+        pbuf_free(p);
+        return;
+    }
+
+    /* send the request to our peer */
+    outp = (u_char*)p->payload;
+    MAKEHEADER(outp, f->protocol);
+    PUTCHAR(CONFREQ, outp);
+    PUTCHAR(f->reqid, outp);
+    PUTSHORT(cilen + HEADERLEN, outp);
+    if (cilen != 0) {
+	(*f->callbacks->addci)(f, outp, &cilen);
+	LWIP_ASSERT("cilen == p->len - HEADERLEN - PPP_HDRLEN", cilen == p->len - HEADERLEN - PPP_HDRLEN);
+    }
+
+    ppp_write(pcb, p);
+
+    /* start the retransmit timer */
+    --f->retransmits;
+    TIMEOUT(fsm_timeout, f, pcb->settings.fsm_timeout_time);
+}
+
+
+/*
+ * fsm_sdata - Send some data.
+ *
+ * Used for all packets sent to our peer by this module.
+ */
+void fsm_sdata(fsm *f, u_char code, u_char id, const u_char *data, int datalen) {
+    ppp_pcb *pcb = f->pcb;
+    struct pbuf *p;
+    u_char *outp;
+    int outlen;
+
+    /* Adjust length to be smaller than MTU */
+    if (datalen > pcb->peer_mru - HEADERLEN)
+	datalen = pcb->peer_mru - HEADERLEN;
+    outlen = datalen + HEADERLEN;
+
+    p = pbuf_alloc(PBUF_RAW, (u16_t)(outlen + PPP_HDRLEN), PPP_CTRL_PBUF_TYPE);
+    if(NULL == p)
+        return;
+    if(p->tot_len != p->len) {
+        pbuf_free(p);
+        return;
+    }
+
+    outp = (u_char*)p->payload;
+    if (datalen) /* && data != outp + PPP_HDRLEN + HEADERLEN)  -- was only for fsm_sconfreq() */
+	MEMCPY(outp + PPP_HDRLEN + HEADERLEN, data, datalen);
+    MAKEHEADER(outp, f->protocol);
+    PUTCHAR(code, outp);
+    PUTCHAR(id, outp);
+    PUTSHORT(outlen, outp);
+    ppp_write(pcb, p);
+}
+
+#endif /* PPP_SUPPORT */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/netif/ppp/ipcp.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/netif/ppp/ipcp.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/netif/ppp/ipcp.c	(revision 457)
@@ -0,0 +1,2418 @@
+/*
+ * ipcp.c - PPP IP Control Protocol.
+ *
+ * Copyright (c) 1984-2000 Carnegie Mellon University. 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. The name "Carnegie Mellon University" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For permission or any legal
+ *    details, please contact
+ *      Office of Technology Transfer
+ *      Carnegie Mellon University
+ *      5000 Forbes Avenue
+ *      Pittsburgh, PA  15213-3890
+ *      (412) 268-4387, fax: (412) 268-7395
+ *      tech-transfer@andrew.cmu.edu
+ *
+ * 4. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by Computing Services
+ *     at Carnegie Mellon University (http://www.cmu.edu/computing/)."
+ *
+ * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO
+ * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE
+ * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
+ * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
+ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include "netif/ppp/ppp_opts.h"
+#if PPP_SUPPORT && PPP_IPV4_SUPPORT /* don't build if not configured for use in lwipopts.h */
+
+/*
+ * @todo:
+ */
+
+#if 0 /* UNUSED */
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <netdb.h>
+#include <sys/param.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#endif /* UNUSED */
+
+#include "netif/ppp/ppp_impl.h"
+
+#include "netif/ppp/fsm.h"
+#include "netif/ppp/ipcp.h"
+
+#if 0 /* UNUSED */
+/* global vars */
+u32_t netmask = 0;		/* IP netmask to set on interface */
+#endif /* UNUSED */
+
+#if 0 /* UNUSED */
+bool	disable_defaultip = 0;	/* Don't use hostname for default IP adrs */
+#endif /* UNUSED */
+
+#if 0 /* moved to ppp_settings */
+bool	noremoteip = 0;		/* Let him have no IP address */
+#endif /* moved to ppp_setting */
+
+#if 0 /* UNUSED */
+/* Hook for a plugin to know when IP protocol has come up */
+void (*ip_up_hook) (void) = NULL;
+
+/* Hook for a plugin to know when IP protocol has come down */
+void (*ip_down_hook) (void) = NULL;
+
+/* Hook for a plugin to choose the remote IP address */
+void (*ip_choose_hook) (u32_t *) = NULL;
+#endif /* UNUSED */
+
+#if PPP_NOTIFY
+/* Notifiers for when IPCP goes up and down */
+struct notifier *ip_up_notifier = NULL;
+struct notifier *ip_down_notifier = NULL;
+#endif /* PPP_NOTIFY */
+
+/* local vars */
+#if 0 /* moved to ppp_pcb */
+static int default_route_set[NUM_PPP];	/* Have set up a default route */
+static int proxy_arp_set[NUM_PPP];	/* Have created proxy arp entry */
+static int ipcp_is_up;			/* have called np_up() */
+static int ipcp_is_open;		/* haven't called np_finished() */
+static bool ask_for_local;		/* request our address from peer */
+#endif /* moved to ppp_pcb */
+#if 0 /* UNUSED */
+static char vj_value[8];		/* string form of vj option value */
+static char netmask_str[20];		/* string form of netmask value */
+#endif /* UNUSED */
+
+/*
+ * Callbacks for fsm code.  (CI = Configuration Information)
+ */
+static void ipcp_resetci(fsm *f);	/* Reset our CI */
+static int  ipcp_cilen(fsm *f);	        /* Return length of our CI */
+static void ipcp_addci(fsm *f, u_char *ucp, int *lenp); /* Add our CI */
+static int  ipcp_ackci(fsm *f, u_char *p, int len);	/* Peer ack'd our CI */
+static int  ipcp_nakci(fsm *f, u_char *p, int len, int treat_as_reject);/* Peer nak'd our CI */
+static int  ipcp_rejci(fsm *f, u_char *p, int len);	/* Peer rej'd our CI */
+static int  ipcp_reqci(fsm *f, u_char *inp, int *len, int reject_if_disagree); /* Rcv CI */
+static void ipcp_up(fsm *f);		/* We're UP */
+static void ipcp_down(fsm *f);		/* We're DOWN */
+static void ipcp_finished(fsm *f);	/* Don't need lower layer */
+
+static const fsm_callbacks ipcp_callbacks = { /* IPCP callback routines */
+    ipcp_resetci,		/* Reset our Configuration Information */
+    ipcp_cilen,			/* Length of our Configuration Information */
+    ipcp_addci,			/* Add our Configuration Information */
+    ipcp_ackci,			/* ACK our Configuration Information */
+    ipcp_nakci,			/* NAK our Configuration Information */
+    ipcp_rejci,			/* Reject our Configuration Information */
+    ipcp_reqci,			/* Request peer's Configuration Information */
+    ipcp_up,			/* Called when fsm reaches OPENED state */
+    ipcp_down,			/* Called when fsm leaves OPENED state */
+    NULL,			/* Called when we want the lower layer up */
+    ipcp_finished,		/* Called when we want the lower layer down */
+    NULL,			/* Called when Protocol-Reject received */
+    NULL,			/* Retransmission is necessary */
+    NULL,			/* Called to handle protocol-specific codes */
+    "IPCP"			/* String name of protocol */
+};
+
+/*
+ * Command-line options.
+ */
+#if PPP_OPTIONS
+static int setvjslots (char **);
+static int setdnsaddr (char **);
+static int setwinsaddr (char **);
+static int setnetmask (char **);
+int setipaddr (char *, char **, int);
+
+static void printipaddr (option_t *, void (*)(void *, char *,...),void *);
+
+static option_t ipcp_option_list[] = {
+    { "noip", o_bool, &ipcp_protent.enabled_flag,
+      "Disable IP and IPCP" },
+    { "-ip", o_bool, &ipcp_protent.enabled_flag,
+      "Disable IP and IPCP", OPT_ALIAS },
+
+    { "novj", o_bool, &ipcp_wantoptions[0].neg_vj,
+      "Disable VJ compression", OPT_A2CLR, &ipcp_allowoptions[0].neg_vj },
+    { "-vj", o_bool, &ipcp_wantoptions[0].neg_vj,
+      "Disable VJ compression", OPT_ALIAS | OPT_A2CLR,
+      &ipcp_allowoptions[0].neg_vj },
+
+    { "novjccomp", o_bool, &ipcp_wantoptions[0].cflag,
+      "Disable VJ connection-ID compression", OPT_A2CLR,
+      &ipcp_allowoptions[0].cflag },
+    { "-vjccomp", o_bool, &ipcp_wantoptions[0].cflag,
+      "Disable VJ connection-ID compression", OPT_ALIAS | OPT_A2CLR,
+      &ipcp_allowoptions[0].cflag },
+
+    { "vj-max-slots", o_special, (void *)setvjslots,
+      "Set maximum VJ header slots",
+      OPT_PRIO | OPT_A2STRVAL | OPT_STATIC, vj_value },
+
+    { "ipcp-accept-local", o_bool, &ipcp_wantoptions[0].accept_local,
+      "Accept peer's address for us", 1 },
+    { "ipcp-accept-remote", o_bool, &ipcp_wantoptions[0].accept_remote,
+      "Accept peer's address for it", 1 },
+
+    { "ipparam", o_string, &ipparam,
+      "Set ip script parameter", OPT_PRIO },
+
+    { "noipdefault", o_bool, &disable_defaultip,
+      "Don't use name for default IP adrs", 1 },
+
+    { "ms-dns", 1, (void *)setdnsaddr,
+      "DNS address for the peer's use" },
+    { "ms-wins", 1, (void *)setwinsaddr,
+      "Nameserver for SMB over TCP/IP for peer" },
+
+    { "ipcp-restart", o_int, &ipcp_fsm[0].timeouttime,
+      "Set timeout for IPCP", OPT_PRIO },
+    { "ipcp-max-terminate", o_int, &ipcp_fsm[0].maxtermtransmits,
+      "Set max #xmits for term-reqs", OPT_PRIO },
+    { "ipcp-max-configure", o_int, &ipcp_fsm[0].maxconfreqtransmits,
+      "Set max #xmits for conf-reqs", OPT_PRIO },
+    { "ipcp-max-failure", o_int, &ipcp_fsm[0].maxnakloops,
+      "Set max #conf-naks for IPCP", OPT_PRIO },
+
+    { "defaultroute", o_bool, &ipcp_wantoptions[0].default_route,
+      "Add default route", OPT_ENABLE|1, &ipcp_allowoptions[0].default_route },
+    { "nodefaultroute", o_bool, &ipcp_allowoptions[0].default_route,
+      "disable defaultroute option", OPT_A2CLR,
+      &ipcp_wantoptions[0].default_route },
+    { "-defaultroute", o_bool, &ipcp_allowoptions[0].default_route,
+      "disable defaultroute option", OPT_ALIAS | OPT_A2CLR,
+      &ipcp_wantoptions[0].default_route },
+
+    { "replacedefaultroute", o_bool,
+				&ipcp_wantoptions[0].replace_default_route,
+      "Replace default route", 1
+    },
+    { "noreplacedefaultroute", o_bool,
+				&ipcp_allowoptions[0].replace_default_route,
+      "Never replace default route", OPT_A2COPY,
+				&ipcp_wantoptions[0].replace_default_route },
+    { "proxyarp", o_bool, &ipcp_wantoptions[0].proxy_arp,
+      "Add proxy ARP entry", OPT_ENABLE|1, &ipcp_allowoptions[0].proxy_arp },
+    { "noproxyarp", o_bool, &ipcp_allowoptions[0].proxy_arp,
+      "disable proxyarp option", OPT_A2CLR,
+      &ipcp_wantoptions[0].proxy_arp },
+    { "-proxyarp", o_bool, &ipcp_allowoptions[0].proxy_arp,
+      "disable proxyarp option", OPT_ALIAS | OPT_A2CLR,
+      &ipcp_wantoptions[0].proxy_arp },
+
+    { "usepeerdns", o_bool, &usepeerdns,
+      "Ask peer for DNS address(es)", 1 },
+
+    { "netmask", o_special, (void *)setnetmask,
+      "set netmask", OPT_PRIO | OPT_A2STRVAL | OPT_STATIC, netmask_str },
+
+    { "ipcp-no-addresses", o_bool, &ipcp_wantoptions[0].old_addrs,
+      "Disable old-style IP-Addresses usage", OPT_A2CLR,
+      &ipcp_allowoptions[0].old_addrs },
+    { "ipcp-no-address", o_bool, &ipcp_wantoptions[0].neg_addr,
+      "Disable IP-Address usage", OPT_A2CLR,
+      &ipcp_allowoptions[0].neg_addr },
+
+    { "noremoteip", o_bool, &noremoteip,
+      "Allow peer to have no IP address", 1 },
+
+    { "nosendip", o_bool, &ipcp_wantoptions[0].neg_addr,
+      "Don't send our IP address to peer", OPT_A2CLR,
+      &ipcp_wantoptions[0].old_addrs},
+
+    { "IP addresses", o_wild, (void *) &setipaddr,
+      "set local and remote IP addresses",
+      OPT_NOARG | OPT_A2PRINTER, (void *) &printipaddr },
+
+    { NULL }
+};
+#endif /* PPP_OPTIONS */
+
+/*
+ * Protocol entry points from main code.
+ */
+static void ipcp_init(ppp_pcb *pcb);
+static void ipcp_open(ppp_pcb *pcb);
+static void ipcp_close(ppp_pcb *pcb, const char *reason);
+static void ipcp_lowerup(ppp_pcb *pcb);
+static void ipcp_lowerdown(ppp_pcb *pcb);
+static void ipcp_input(ppp_pcb *pcb, u_char *p, int len);
+static void ipcp_protrej(ppp_pcb *pcb);
+#if PRINTPKT_SUPPORT
+static int ipcp_printpkt(const u_char *p, int plen,
+		void (*printer) (void *, const char *, ...), void *arg);
+#endif /* PRINTPKT_SUPPORT */
+#if PPP_OPTIONS
+static void ip_check_options (void);
+#endif /* PPP_OPTIONS */
+#if DEMAND_SUPPORT
+static int  ip_demand_conf (int);
+static int  ip_active_pkt (u_char *, int);
+#endif /* DEMAND_SUPPORT */
+#if 0 /* UNUSED */
+static void create_resolv (u32_t, u32_t);
+#endif /* UNUSED */
+
+const struct protent ipcp_protent = {
+    PPP_IPCP,
+    ipcp_init,
+    ipcp_input,
+    ipcp_protrej,
+    ipcp_lowerup,
+    ipcp_lowerdown,
+    ipcp_open,
+    ipcp_close,
+#if PRINTPKT_SUPPORT
+    ipcp_printpkt,
+#endif /* PRINTPKT_SUPPORT */
+#if PPP_DATAINPUT
+    NULL,
+#endif /* PPP_DATAINPUT */
+#if PRINTPKT_SUPPORT
+    "IPCP",
+    "IP",
+#endif /* PRINTPKT_SUPPORT */
+#if PPP_OPTIONS
+    ipcp_option_list,
+    ip_check_options,
+#endif /* PPP_OPTIONS */
+#if DEMAND_SUPPORT
+    ip_demand_conf,
+    ip_active_pkt
+#endif /* DEMAND_SUPPORT */
+};
+
+static void ipcp_clear_addrs(ppp_pcb *pcb, u32_t ouraddr, u32_t hisaddr, u8_t replacedefaultroute);
+
+/*
+ * Lengths of configuration options.
+ */
+#define CILEN_VOID	2
+#define CILEN_COMPRESS	4	/* min length for compression protocol opt. */
+#define CILEN_VJ	6	/* length for RFC1332 Van-Jacobson opt. */
+#define CILEN_ADDR	6	/* new-style single address option */
+#define CILEN_ADDRS	10	/* old-style dual address option */
+
+
+#define CODENAME(x)	((x) == CONFACK ? "ACK" : \
+			 (x) == CONFNAK ? "NAK" : "REJ")
+
+#if 0 /* UNUSED, already defined by lwIP */
+/*
+ * Make a string representation of a network IP address.
+ */
+char *
+ip_ntoa(ipaddr)
+u32_t ipaddr;
+{
+    static char b[64];
+
+    slprintf(b, sizeof(b), "%I", ipaddr);
+    return b;
+}
+#endif /* UNUSED, already defined by lwIP */
+
+/*
+ * Option parsing.
+ */
+#if PPP_OPTIONS
+/*
+ * setvjslots - set maximum number of connection slots for VJ compression
+ */
+static int
+setvjslots(argv)
+    char **argv;
+{
+    int value;
+
+    if (!int_option(*argv, &value))
+	return 0;
+
+    if (value < 2 || value > 16) {
+	option_error("vj-max-slots value must be between 2 and 16");
+	return 0;
+    }
+    ipcp_wantoptions [0].maxslotindex =
+        ipcp_allowoptions[0].maxslotindex = value - 1;
+    slprintf(vj_value, sizeof(vj_value), "%d", value);
+    return 1;
+}
+
+/*
+ * setdnsaddr - set the dns address(es)
+ */
+static int
+setdnsaddr(argv)
+    char **argv;
+{
+    u32_t dns;
+    struct hostent *hp;
+
+    dns = inet_addr(*argv);
+    if (dns == (u32_t) -1) {
+	if ((hp = gethostbyname(*argv)) == NULL) {
+	    option_error("invalid address parameter '%s' for ms-dns option",
+			 *argv);
+	    return 0;
+	}
+	dns = *(u32_t *)hp->h_addr;
+    }
+
+    /* We take the last 2 values given, the 2nd-last as the primary
+       and the last as the secondary.  If only one is given it
+       becomes both primary and secondary. */
+    if (ipcp_allowoptions[0].dnsaddr[1] == 0)
+	ipcp_allowoptions[0].dnsaddr[0] = dns;
+    else
+	ipcp_allowoptions[0].dnsaddr[0] = ipcp_allowoptions[0].dnsaddr[1];
+
+    /* always set the secondary address value. */
+    ipcp_allowoptions[0].dnsaddr[1] = dns;
+
+    return (1);
+}
+
+/*
+ * setwinsaddr - set the wins address(es)
+ * This is primrarly used with the Samba package under UNIX or for pointing
+ * the caller to the existing WINS server on a Windows NT platform.
+ */
+static int
+setwinsaddr(argv)
+    char **argv;
+{
+    u32_t wins;
+    struct hostent *hp;
+
+    wins = inet_addr(*argv);
+    if (wins == (u32_t) -1) {
+	if ((hp = gethostbyname(*argv)) == NULL) {
+	    option_error("invalid address parameter '%s' for ms-wins option",
+			 *argv);
+	    return 0;
+	}
+	wins = *(u32_t *)hp->h_addr;
+    }
+
+    /* We take the last 2 values given, the 2nd-last as the primary
+       and the last as the secondary.  If only one is given it
+       becomes both primary and secondary. */
+    if (ipcp_allowoptions[0].winsaddr[1] == 0)
+	ipcp_allowoptions[0].winsaddr[0] = wins;
+    else
+	ipcp_allowoptions[0].winsaddr[0] = ipcp_allowoptions[0].winsaddr[1];
+
+    /* always set the secondary address value. */
+    ipcp_allowoptions[0].winsaddr[1] = wins;
+
+    return (1);
+}
+
+/*
+ * setipaddr - Set the IP address
+ * If doit is 0, the call is to check whether this option is
+ * potentially an IP address specification.
+ * Not static so that plugins can call it to set the addresses
+ */
+int
+setipaddr(arg, argv, doit)
+    char *arg;
+    char **argv;
+    int doit;
+{
+    struct hostent *hp;
+    char *colon;
+    u32_t local, remote;
+    ipcp_options *wo = &ipcp_wantoptions[0];
+    static int prio_local = 0, prio_remote = 0;
+
+    /*
+     * IP address pair separated by ":".
+     */
+    if ((colon = strchr(arg, ':')) == NULL)
+	return 0;
+    if (!doit)
+	return 1;
+  
+    /*
+     * If colon first character, then no local addr.
+     */
+    if (colon != arg && option_priority >= prio_local) {
+	*colon = '\0';
+	if ((local = inet_addr(arg)) == (u32_t) -1) {
+	    if ((hp = gethostbyname(arg)) == NULL) {
+		option_error("unknown host: %s", arg);
+		return 0;
+	    }
+	    local = *(u32_t *)hp->h_addr;
+	}
+	if (bad_ip_adrs(local)) {
+	    option_error("bad local IP address %s", ip_ntoa(local));
+	    return 0;
+	}
+	if (local != 0)
+	    wo->ouraddr = local;
+	*colon = ':';
+	prio_local = option_priority;
+    }
+  
+    /*
+     * If colon last character, then no remote addr.
+     */
+    if (*++colon != '\0' && option_priority >= prio_remote) {
+	if ((remote = inet_addr(colon)) == (u32_t) -1) {
+	    if ((hp = gethostbyname(colon)) == NULL) {
+		option_error("unknown host: %s", colon);
+		return 0;
+	    }
+	    remote = *(u32_t *)hp->h_addr;
+	    if (remote_name[0] == 0)
+		strlcpy(remote_name, colon, sizeof(remote_name));
+	}
+	if (bad_ip_adrs(remote)) {
+	    option_error("bad remote IP address %s", ip_ntoa(remote));
+	    return 0;
+	}
+	if (remote != 0)
+	    wo->hisaddr = remote;
+	prio_remote = option_priority;
+    }
+
+    return 1;
+}
+
+static void
+printipaddr(opt, printer, arg)
+    option_t *opt;
+    void (*printer) (void *, char *, ...);
+    void *arg;
+{
+	ipcp_options *wo = &ipcp_wantoptions[0];
+
+	if (wo->ouraddr != 0)
+		printer(arg, "%I", wo->ouraddr);
+	printer(arg, ":");
+	if (wo->hisaddr != 0)
+		printer(arg, "%I", wo->hisaddr);
+}
+
+/*
+ * setnetmask - set the netmask to be used on the interface.
+ */
+static int
+setnetmask(argv)
+    char **argv;
+{
+    u32_t mask;
+    int n;
+    char *p;
+
+    /*
+     * Unfortunately, if we use inet_addr, we can't tell whether
+     * a result of all 1s is an error or a valid 255.255.255.255.
+     */
+    p = *argv;
+    n = parse_dotted_ip(p, &mask);
+
+    mask = lwip_htonl(mask);
+
+    if (n == 0 || p[n] != 0 || (netmask & ~mask) != 0) {
+	option_error("invalid netmask value '%s'", *argv);
+	return 0;
+    }
+
+    netmask = mask;
+    slprintf(netmask_str, sizeof(netmask_str), "%I", mask);
+
+    return (1);
+}
+
+int
+parse_dotted_ip(p, vp)
+    char *p;
+    u32_t *vp;
+{
+    int n;
+    u32_t v, b;
+    char *endp, *p0 = p;
+
+    v = 0;
+    for (n = 3;; --n) {
+	b = strtoul(p, &endp, 0);
+	if (endp == p)
+	    return 0;
+	if (b > 255) {
+	    if (n < 3)
+		return 0;
+	    /* accept e.g. 0xffffff00 */
+	    *vp = b;
+	    return endp - p0;
+	}
+	v |= b << (n * 8);
+	p = endp;
+	if (n == 0)
+	    break;
+	if (*p != '.')
+	    return 0;
+	++p;
+    }
+    *vp = v;
+    return p - p0;
+}
+#endif /* PPP_OPTIONS */
+
+/*
+ * ipcp_init - Initialize IPCP.
+ */
+static void ipcp_init(ppp_pcb *pcb) {
+    fsm *f = &pcb->ipcp_fsm;
+
+    ipcp_options *wo = &pcb->ipcp_wantoptions;
+    ipcp_options *ao = &pcb->ipcp_allowoptions;
+
+    f->pcb = pcb;
+    f->protocol = PPP_IPCP;
+    f->callbacks = &ipcp_callbacks;
+    fsm_init(f);
+
+    /*
+     * Some 3G modems use repeated IPCP NAKs as a way of stalling
+     * until they can contact a server on the network, so we increase
+     * the default number of NAKs we accept before we start treating
+     * them as rejects.
+     */
+    f->maxnakloops = 100;
+
+#if 0 /* Not necessary, everything is cleared in ppp_new() */
+    memset(wo, 0, sizeof(*wo));
+    memset(ao, 0, sizeof(*ao));
+#endif /* 0 */
+
+    wo->neg_addr = wo->old_addrs = 1;
+#if VJ_SUPPORT
+    wo->neg_vj = 1;
+    wo->vj_protocol = IPCP_VJ_COMP;
+    wo->maxslotindex = MAX_STATES - 1; /* really max index */
+    wo->cflag = 1;
+#endif /* VJ_SUPPORT */
+
+#if 0 /* UNUSED */
+    /* wanting default route by default */
+    wo->default_route = 1;
+#endif /* UNUSED */
+
+    ao->neg_addr = ao->old_addrs = 1;
+#if VJ_SUPPORT
+    /* max slots and slot-id compression are currently hardwired in */
+    /* ppp_if.c to 16 and 1, this needs to be changed (among other */
+    /* things) gmc */
+
+    ao->neg_vj = 1;
+    ao->maxslotindex = MAX_STATES - 1;
+    ao->cflag = 1;
+#endif /* #if VJ_SUPPORT */
+
+#if 0 /* UNUSED */
+    /*
+     * XXX These control whether the user may use the proxyarp
+     * and defaultroute options.
+     */
+    ao->proxy_arp = 1;
+    ao->default_route = 1;
+#endif /* UNUSED */
+}
+
+
+/*
+ * ipcp_open - IPCP is allowed to come up.
+ */
+static void ipcp_open(ppp_pcb *pcb) {
+    fsm *f = &pcb->ipcp_fsm;
+    fsm_open(f);
+    pcb->ipcp_is_open = 1;
+}
+
+
+/*
+ * ipcp_close - Take IPCP down.
+ */
+static void ipcp_close(ppp_pcb *pcb, const char *reason) {
+    fsm *f = &pcb->ipcp_fsm;
+    fsm_close(f, reason);
+}
+
+
+/*
+ * ipcp_lowerup - The lower layer is up.
+ */
+static void ipcp_lowerup(ppp_pcb *pcb) {
+    fsm *f = &pcb->ipcp_fsm;
+    fsm_lowerup(f);
+}
+
+
+/*
+ * ipcp_lowerdown - The lower layer is down.
+ */
+static void ipcp_lowerdown(ppp_pcb *pcb) {
+    fsm *f = &pcb->ipcp_fsm;
+    fsm_lowerdown(f);
+}
+
+
+/*
+ * ipcp_input - Input IPCP packet.
+ */
+static void ipcp_input(ppp_pcb *pcb, u_char *p, int len) {
+    fsm *f = &pcb->ipcp_fsm;
+    fsm_input(f, p, len);
+}
+
+
+/*
+ * ipcp_protrej - A Protocol-Reject was received for IPCP.
+ *
+ * Pretend the lower layer went down, so we shut up.
+ */
+static void ipcp_protrej(ppp_pcb *pcb) {
+    fsm *f = &pcb->ipcp_fsm;
+    fsm_lowerdown(f);
+}
+
+
+/*
+ * ipcp_resetci - Reset our CI.
+ * Called by fsm_sconfreq, Send Configure Request.
+ */
+static void ipcp_resetci(fsm *f) {
+    ppp_pcb *pcb = f->pcb;
+    ipcp_options *wo = &pcb->ipcp_wantoptions;
+    ipcp_options *go = &pcb->ipcp_gotoptions;
+    ipcp_options *ao = &pcb->ipcp_allowoptions;
+
+    wo->req_addr = (wo->neg_addr || wo->old_addrs) &&
+	(ao->neg_addr || ao->old_addrs);
+    if (wo->ouraddr == 0)
+	wo->accept_local = 1;
+    if (wo->hisaddr == 0)
+	wo->accept_remote = 1;
+#if LWIP_DNS
+    wo->req_dns1 = wo->req_dns2 = pcb->settings.usepeerdns;	/* Request DNS addresses from the peer */
+#endif /* LWIP_DNS */
+    *go = *wo;
+    if (!pcb->ask_for_local)
+	go->ouraddr = 0;
+#if 0 /* UNUSED */
+    if (ip_choose_hook) {
+	ip_choose_hook(&wo->hisaddr);
+	if (wo->hisaddr) {
+	    wo->accept_remote = 0;
+	}
+    }
+#endif /* UNUSED */
+    BZERO(&pcb->ipcp_hisoptions, sizeof(ipcp_options));
+}
+
+
+/*
+ * ipcp_cilen - Return length of our CI.
+ * Called by fsm_sconfreq, Send Configure Request.
+ */
+static int ipcp_cilen(fsm *f) {
+    ppp_pcb *pcb = f->pcb;
+    ipcp_options *go = &pcb->ipcp_gotoptions;
+#if VJ_SUPPORT
+    ipcp_options *wo = &pcb->ipcp_wantoptions;
+#endif /* VJ_SUPPORT */
+    ipcp_options *ho = &pcb->ipcp_hisoptions;
+
+#define LENCIADDRS(neg)		(neg ? CILEN_ADDRS : 0)
+#if VJ_SUPPORT
+#define LENCIVJ(neg, old)	(neg ? (old? CILEN_COMPRESS : CILEN_VJ) : 0)
+#endif /* VJ_SUPPORT */
+#define LENCIADDR(neg)		(neg ? CILEN_ADDR : 0)
+#if LWIP_DNS
+#define LENCIDNS(neg)		LENCIADDR(neg)
+#endif /* LWIP_DNS */
+#if 0 /* UNUSED - WINS */
+#define LENCIWINS(neg)		LENCIADDR(neg)
+#endif /* UNUSED - WINS */
+
+    /*
+     * First see if we want to change our options to the old
+     * forms because we have received old forms from the peer.
+     */
+    if (go->neg_addr && go->old_addrs && !ho->neg_addr && ho->old_addrs)
+	go->neg_addr = 0;
+
+#if VJ_SUPPORT
+    if (wo->neg_vj && !go->neg_vj && !go->old_vj) {
+	/* try an older style of VJ negotiation */
+	/* use the old style only if the peer did */
+	if (ho->neg_vj && ho->old_vj) {
+	    go->neg_vj = 1;
+	    go->old_vj = 1;
+	    go->vj_protocol = ho->vj_protocol;
+	}
+    }
+#endif /* VJ_SUPPORT */
+
+    return (LENCIADDRS(!go->neg_addr && go->old_addrs) +
+#if VJ_SUPPORT
+	    LENCIVJ(go->neg_vj, go->old_vj) +
+#endif /* VJ_SUPPORT */
+	    LENCIADDR(go->neg_addr) +
+#if LWIP_DNS
+	    LENCIDNS(go->req_dns1) +
+	    LENCIDNS(go->req_dns2) +
+#endif /* LWIP_DNS */
+#if 0 /* UNUSED - WINS */
+	    LENCIWINS(go->winsaddr[0]) +
+	    LENCIWINS(go->winsaddr[1]) +
+#endif /* UNUSED - WINS */
+	    0);
+}
+
+
+/*
+ * ipcp_addci - Add our desired CIs to a packet.
+ * Called by fsm_sconfreq, Send Configure Request.
+ */
+static void ipcp_addci(fsm *f, u_char *ucp, int *lenp) {
+    ppp_pcb *pcb = f->pcb;
+    ipcp_options *go = &pcb->ipcp_gotoptions;
+    int len = *lenp;
+
+#define ADDCIADDRS(opt, neg, val1, val2) \
+    if (neg) { \
+	if (len >= CILEN_ADDRS) { \
+	    u32_t l; \
+	    PUTCHAR(opt, ucp); \
+	    PUTCHAR(CILEN_ADDRS, ucp); \
+	    l = lwip_ntohl(val1); \
+	    PUTLONG(l, ucp); \
+	    l = lwip_ntohl(val2); \
+	    PUTLONG(l, ucp); \
+	    len -= CILEN_ADDRS; \
+	} else \
+	    go->old_addrs = 0; \
+    }
+
+#if VJ_SUPPORT
+#define ADDCIVJ(opt, neg, val, old, maxslotindex, cflag) \
+    if (neg) { \
+	int vjlen = old? CILEN_COMPRESS : CILEN_VJ; \
+	if (len >= vjlen) { \
+	    PUTCHAR(opt, ucp); \
+	    PUTCHAR(vjlen, ucp); \
+	    PUTSHORT(val, ucp); \
+	    if (!old) { \
+		PUTCHAR(maxslotindex, ucp); \
+		PUTCHAR(cflag, ucp); \
+	    } \
+	    len -= vjlen; \
+	} else \
+	    neg = 0; \
+    }
+#endif /* VJ_SUPPORT */
+
+#define ADDCIADDR(opt, neg, val) \
+    if (neg) { \
+	if (len >= CILEN_ADDR) { \
+	    u32_t l; \
+	    PUTCHAR(opt, ucp); \
+	    PUTCHAR(CILEN_ADDR, ucp); \
+	    l = lwip_ntohl(val); \
+	    PUTLONG(l, ucp); \
+	    len -= CILEN_ADDR; \
+	} else \
+	    neg = 0; \
+    }
+
+#if LWIP_DNS
+#define ADDCIDNS(opt, neg, addr) \
+    if (neg) { \
+	if (len >= CILEN_ADDR) { \
+	    u32_t l; \
+	    PUTCHAR(opt, ucp); \
+	    PUTCHAR(CILEN_ADDR, ucp); \
+	    l = lwip_ntohl(addr); \
+	    PUTLONG(l, ucp); \
+	    len -= CILEN_ADDR; \
+	} else \
+	    neg = 0; \
+    }
+#endif /* LWIP_DNS */
+
+#if 0 /* UNUSED - WINS */
+#define ADDCIWINS(opt, addr) \
+    if (addr) { \
+	if (len >= CILEN_ADDR) { \
+	    u32_t l; \
+	    PUTCHAR(opt, ucp); \
+	    PUTCHAR(CILEN_ADDR, ucp); \
+	    l = lwip_ntohl(addr); \
+	    PUTLONG(l, ucp); \
+	    len -= CILEN_ADDR; \
+	} else \
+	    addr = 0; \
+    }
+#endif /* UNUSED - WINS */
+
+    ADDCIADDRS(CI_ADDRS, !go->neg_addr && go->old_addrs, go->ouraddr,
+	       go->hisaddr);
+
+#if VJ_SUPPORT
+    ADDCIVJ(CI_COMPRESSTYPE, go->neg_vj, go->vj_protocol, go->old_vj,
+	    go->maxslotindex, go->cflag);
+#endif /* VJ_SUPPORT */
+
+    ADDCIADDR(CI_ADDR, go->neg_addr, go->ouraddr);
+
+#if LWIP_DNS
+    ADDCIDNS(CI_MS_DNS1, go->req_dns1, go->dnsaddr[0]);
+
+    ADDCIDNS(CI_MS_DNS2, go->req_dns2, go->dnsaddr[1]);
+#endif /* LWIP_DNS */
+
+#if 0 /* UNUSED - WINS */
+    ADDCIWINS(CI_MS_WINS1, go->winsaddr[0]);
+
+    ADDCIWINS(CI_MS_WINS2, go->winsaddr[1]);
+#endif /* UNUSED - WINS */
+    
+    *lenp -= len;
+}
+
+
+/*
+ * ipcp_ackci - Ack our CIs.
+ * Called by fsm_rconfack, Receive Configure ACK.
+ *
+ * Returns:
+ *	0 - Ack was bad.
+ *	1 - Ack was good.
+ */
+static int ipcp_ackci(fsm *f, u_char *p, int len) {
+    ppp_pcb *pcb = f->pcb;
+    ipcp_options *go = &pcb->ipcp_gotoptions;
+    u_short cilen, citype;
+    u32_t cilong;
+#if VJ_SUPPORT
+    u_short cishort;
+    u_char cimaxslotindex, cicflag;
+#endif /* VJ_SUPPORT */
+
+    /*
+     * CIs must be in exactly the same order that we sent...
+     * Check packet length and CI length at each step.
+     * If we find any deviations, then this packet is bad.
+     */
+
+#define ACKCIADDRS(opt, neg, val1, val2) \
+    if (neg) { \
+	u32_t l; \
+	if ((len -= CILEN_ADDRS) < 0) \
+	    goto bad; \
+	GETCHAR(citype, p); \
+	GETCHAR(cilen, p); \
+	if (cilen != CILEN_ADDRS || \
+	    citype != opt) \
+	    goto bad; \
+	GETLONG(l, p); \
+	cilong = lwip_htonl(l); \
+	if (val1 != cilong) \
+	    goto bad; \
+	GETLONG(l, p); \
+	cilong = lwip_htonl(l); \
+	if (val2 != cilong) \
+	    goto bad; \
+    }
+
+#if VJ_SUPPORT
+#define ACKCIVJ(opt, neg, val, old, maxslotindex, cflag) \
+    if (neg) { \
+	int vjlen = old? CILEN_COMPRESS : CILEN_VJ; \
+	if ((len -= vjlen) < 0) \
+	    goto bad; \
+	GETCHAR(citype, p); \
+	GETCHAR(cilen, p); \
+	if (cilen != vjlen || \
+	    citype != opt)  \
+	    goto bad; \
+	GETSHORT(cishort, p); \
+	if (cishort != val) \
+	    goto bad; \
+	if (!old) { \
+	    GETCHAR(cimaxslotindex, p); \
+	    if (cimaxslotindex != maxslotindex) \
+		goto bad; \
+	    GETCHAR(cicflag, p); \
+	    if (cicflag != cflag) \
+		goto bad; \
+	} \
+    }
+#endif /* VJ_SUPPORT */
+
+#define ACKCIADDR(opt, neg, val) \
+    if (neg) { \
+	u32_t l; \
+	if ((len -= CILEN_ADDR) < 0) \
+	    goto bad; \
+	GETCHAR(citype, p); \
+	GETCHAR(cilen, p); \
+	if (cilen != CILEN_ADDR || \
+	    citype != opt) \
+	    goto bad; \
+	GETLONG(l, p); \
+	cilong = lwip_htonl(l); \
+	if (val != cilong) \
+	    goto bad; \
+    }
+
+#if LWIP_DNS
+#define ACKCIDNS(opt, neg, addr) \
+    if (neg) { \
+	u32_t l; \
+	if ((len -= CILEN_ADDR) < 0) \
+	    goto bad; \
+	GETCHAR(citype, p); \
+	GETCHAR(cilen, p); \
+	if (cilen != CILEN_ADDR || citype != opt) \
+	    goto bad; \
+	GETLONG(l, p); \
+	cilong = lwip_htonl(l); \
+	if (addr != cilong) \
+	    goto bad; \
+    }
+#endif /* LWIP_DNS */
+
+#if 0 /* UNUSED - WINS */
+#define ACKCIWINS(opt, addr) \
+    if (addr) { \
+	u32_t l; \
+	if ((len -= CILEN_ADDR) < 0) \
+	    goto bad; \
+	GETCHAR(citype, p); \
+	GETCHAR(cilen, p); \
+	if (cilen != CILEN_ADDR || citype != opt) \
+	    goto bad; \
+	GETLONG(l, p); \
+	cilong = lwip_htonl(l); \
+	if (addr != cilong) \
+	    goto bad; \
+    }
+#endif /* UNUSED - WINS */
+
+    ACKCIADDRS(CI_ADDRS, !go->neg_addr && go->old_addrs, go->ouraddr,
+	       go->hisaddr);
+
+#if VJ_SUPPORT
+    ACKCIVJ(CI_COMPRESSTYPE, go->neg_vj, go->vj_protocol, go->old_vj,
+	    go->maxslotindex, go->cflag);
+#endif /* VJ_SUPPORT */
+
+    ACKCIADDR(CI_ADDR, go->neg_addr, go->ouraddr);
+
+#if LWIP_DNS
+    ACKCIDNS(CI_MS_DNS1, go->req_dns1, go->dnsaddr[0]);
+
+    ACKCIDNS(CI_MS_DNS2, go->req_dns2, go->dnsaddr[1]);
+#endif /* LWIP_DNS */
+
+#if 0 /* UNUSED - WINS */
+    ACKCIWINS(CI_MS_WINS1, go->winsaddr[0]);
+
+    ACKCIWINS(CI_MS_WINS2, go->winsaddr[1]);
+#endif /* UNUSED - WINS */
+
+    /*
+     * If there are any remaining CIs, then this packet is bad.
+     */
+    if (len != 0)
+	goto bad;
+    return (1);
+
+bad:
+    IPCPDEBUG(("ipcp_ackci: received bad Ack!"));
+    return (0);
+}
+
+/*
+ * ipcp_nakci - Peer has sent a NAK for some of our CIs.
+ * This should not modify any state if the Nak is bad
+ * or if IPCP is in the OPENED state.
+ * Calback from fsm_rconfnakrej - Receive Configure-Nak or Configure-Reject.
+ *
+ * Returns:
+ *	0 - Nak was bad.
+ *	1 - Nak was good.
+ */
+static int ipcp_nakci(fsm *f, u_char *p, int len, int treat_as_reject) {
+    ppp_pcb *pcb = f->pcb;
+    ipcp_options *go = &pcb->ipcp_gotoptions;
+    u_char citype, cilen, *next;
+#if VJ_SUPPORT
+    u_char cimaxslotindex, cicflag;
+    u_short cishort;
+#endif /* VJ_SUPPORT */
+    u32_t ciaddr1, ciaddr2, l;
+#if LWIP_DNS
+    u32_t cidnsaddr;
+#endif /* LWIP_DNS */
+    ipcp_options no;		/* options we've seen Naks for */
+    ipcp_options try_;		/* options to request next time */
+
+    BZERO(&no, sizeof(no));
+    try_ = *go;
+
+    /*
+     * Any Nak'd CIs must be in exactly the same order that we sent.
+     * Check packet length and CI length at each step.
+     * If we find any deviations, then this packet is bad.
+     */
+#define NAKCIADDRS(opt, neg, code) \
+    if ((neg) && \
+	(cilen = p[1]) == CILEN_ADDRS && \
+	len >= cilen && \
+	p[0] == opt) { \
+	len -= cilen; \
+	INCPTR(2, p); \
+	GETLONG(l, p); \
+	ciaddr1 = lwip_htonl(l); \
+	GETLONG(l, p); \
+	ciaddr2 = lwip_htonl(l); \
+	no.old_addrs = 1; \
+	code \
+    }
+
+#if VJ_SUPPORT
+#define NAKCIVJ(opt, neg, code) \
+    if (go->neg && \
+	((cilen = p[1]) == CILEN_COMPRESS || cilen == CILEN_VJ) && \
+	len >= cilen && \
+	p[0] == opt) { \
+	len -= cilen; \
+	INCPTR(2, p); \
+	GETSHORT(cishort, p); \
+	no.neg = 1; \
+        code \
+    }
+#endif /* VJ_SUPPORT */
+
+#define NAKCIADDR(opt, neg, code) \
+    if (go->neg && \
+	(cilen = p[1]) == CILEN_ADDR && \
+	len >= cilen && \
+	p[0] == opt) { \
+	len -= cilen; \
+	INCPTR(2, p); \
+	GETLONG(l, p); \
+	ciaddr1 = lwip_htonl(l); \
+	no.neg = 1; \
+	code \
+    }
+
+#if LWIP_DNS
+#define NAKCIDNS(opt, neg, code) \
+    if (go->neg && \
+	((cilen = p[1]) == CILEN_ADDR) && \
+	len >= cilen && \
+	p[0] == opt) { \
+	len -= cilen; \
+	INCPTR(2, p); \
+	GETLONG(l, p); \
+	cidnsaddr = lwip_htonl(l); \
+	no.neg = 1; \
+	code \
+    }
+#endif /* LWIP_DNS */
+
+    /*
+     * Accept the peer's idea of {our,his} address, if different
+     * from our idea, only if the accept_{local,remote} flag is set.
+     */
+    NAKCIADDRS(CI_ADDRS, !go->neg_addr && go->old_addrs,
+	       if (treat_as_reject) {
+		   try_.old_addrs = 0;
+	       } else {
+		   if (go->accept_local && ciaddr1) {
+		       /* take his idea of our address */
+		       try_.ouraddr = ciaddr1;
+		   }
+		   if (go->accept_remote && ciaddr2) {
+		       /* take his idea of his address */
+		       try_.hisaddr = ciaddr2;
+		   }
+	       }
+	);
+
+#if VJ_SUPPORT
+    /*
+     * Accept the peer's value of maxslotindex provided that it
+     * is less than what we asked for.  Turn off slot-ID compression
+     * if the peer wants.  Send old-style compress-type option if
+     * the peer wants.
+     */
+    NAKCIVJ(CI_COMPRESSTYPE, neg_vj,
+	    if (treat_as_reject) {
+		try_.neg_vj = 0;
+	    } else if (cilen == CILEN_VJ) {
+		GETCHAR(cimaxslotindex, p);
+		GETCHAR(cicflag, p);
+		if (cishort == IPCP_VJ_COMP) {
+		    try_.old_vj = 0;
+		    if (cimaxslotindex < go->maxslotindex)
+			try_.maxslotindex = cimaxslotindex;
+		    if (!cicflag)
+			try_.cflag = 0;
+		} else {
+		    try_.neg_vj = 0;
+		}
+	    } else {
+		if (cishort == IPCP_VJ_COMP || cishort == IPCP_VJ_COMP_OLD) {
+		    try_.old_vj = 1;
+		    try_.vj_protocol = cishort;
+		} else {
+		    try_.neg_vj = 0;
+		}
+	    }
+	    );
+#endif /* VJ_SUPPORT */
+
+    NAKCIADDR(CI_ADDR, neg_addr,
+	      if (treat_as_reject) {
+		  try_.neg_addr = 0;
+		  try_.old_addrs = 0;
+	      } else if (go->accept_local && ciaddr1) {
+		  /* take his idea of our address */
+		  try_.ouraddr = ciaddr1;
+	      }
+	      );
+
+#if LWIP_DNS
+    NAKCIDNS(CI_MS_DNS1, req_dns1,
+	     if (treat_as_reject) {
+		 try_.req_dns1 = 0;
+	     } else {
+		 try_.dnsaddr[0] = cidnsaddr;
+	     }
+	     );
+
+    NAKCIDNS(CI_MS_DNS2, req_dns2,
+	     if (treat_as_reject) {
+		 try_.req_dns2 = 0;
+	     } else {
+		 try_.dnsaddr[1] = cidnsaddr;
+	     }
+	     );
+#endif /* #if LWIP_DNS */
+
+    /*
+     * There may be remaining CIs, if the peer is requesting negotiation
+     * on an option that we didn't include in our request packet.
+     * If they want to negotiate about IP addresses, we comply.
+     * If they want us to ask for compression, we refuse.
+     * If they want us to ask for ms-dns, we do that, since some
+     * peers get huffy if we don't.
+     */
+    while (len >= CILEN_VOID) {
+	GETCHAR(citype, p);
+	GETCHAR(cilen, p);
+	if ( cilen < CILEN_VOID || (len -= cilen) < 0 )
+	    goto bad;
+	next = p + cilen - 2;
+
+	switch (citype) {
+#if VJ_SUPPORT
+	case CI_COMPRESSTYPE:
+	    if (go->neg_vj || no.neg_vj ||
+		(cilen != CILEN_VJ && cilen != CILEN_COMPRESS))
+		goto bad;
+	    no.neg_vj = 1;
+	    break;
+#endif /* VJ_SUPPORT */
+	case CI_ADDRS:
+	    if ((!go->neg_addr && go->old_addrs) || no.old_addrs
+		|| cilen != CILEN_ADDRS)
+		goto bad;
+	    try_.neg_addr = 0;
+	    GETLONG(l, p);
+	    ciaddr1 = lwip_htonl(l);
+	    if (ciaddr1 && go->accept_local)
+		try_.ouraddr = ciaddr1;
+	    GETLONG(l, p);
+	    ciaddr2 = lwip_htonl(l);
+	    if (ciaddr2 && go->accept_remote)
+		try_.hisaddr = ciaddr2;
+	    no.old_addrs = 1;
+	    break;
+	case CI_ADDR:
+	    if (go->neg_addr || no.neg_addr || cilen != CILEN_ADDR)
+		goto bad;
+	    try_.old_addrs = 0;
+	    GETLONG(l, p);
+	    ciaddr1 = lwip_htonl(l);
+	    if (ciaddr1 && go->accept_local)
+		try_.ouraddr = ciaddr1;
+	    if (try_.ouraddr != 0)
+		try_.neg_addr = 1;
+	    no.neg_addr = 1;
+	    break;
+#if LWIP_DNS
+	case CI_MS_DNS1:
+	    if (go->req_dns1 || no.req_dns1 || cilen != CILEN_ADDR)
+		goto bad;
+	    GETLONG(l, p);
+	    try_.dnsaddr[0] = lwip_htonl(l);
+	    try_.req_dns1 = 1;
+	    no.req_dns1 = 1;
+	    break;
+	case CI_MS_DNS2:
+	    if (go->req_dns2 || no.req_dns2 || cilen != CILEN_ADDR)
+		goto bad;
+	    GETLONG(l, p);
+	    try_.dnsaddr[1] = lwip_htonl(l);
+	    try_.req_dns2 = 1;
+	    no.req_dns2 = 1;
+	    break;
+#endif /* LWIP_DNS */
+#if 0 /* UNUSED - WINS */
+	case CI_MS_WINS1:
+	case CI_MS_WINS2:
+	    if (cilen != CILEN_ADDR)
+		goto bad;
+	    GETLONG(l, p);
+	    ciaddr1 = lwip_htonl(l);
+	    if (ciaddr1)
+		try_.winsaddr[citype == CI_MS_WINS2] = ciaddr1;
+	    break;
+#endif /* UNUSED - WINS */
+	default:
+	    break;
+	}
+	p = next;
+    }
+
+    /*
+     * OK, the Nak is good.  Now we can update state.
+     * If there are any remaining options, we ignore them.
+     */
+    if (f->state != PPP_FSM_OPENED)
+	*go = try_;
+
+    return 1;
+
+bad:
+    IPCPDEBUG(("ipcp_nakci: received bad Nak!"));
+    return 0;
+}
+
+
+/*
+ * ipcp_rejci - Reject some of our CIs.
+ * Callback from fsm_rconfnakrej.
+ */
+static int ipcp_rejci(fsm *f, u_char *p, int len) {
+    ppp_pcb *pcb = f->pcb;
+    ipcp_options *go = &pcb->ipcp_gotoptions;
+    u_char cilen;
+#if VJ_SUPPORT
+    u_char cimaxslotindex, ciflag;
+    u_short cishort;
+#endif /* VJ_SUPPORT */
+    u32_t cilong;
+    ipcp_options try_;		/* options to request next time */
+
+    try_ = *go;
+    /*
+     * Any Rejected CIs must be in exactly the same order that we sent.
+     * Check packet length and CI length at each step.
+     * If we find any deviations, then this packet is bad.
+     */
+#define REJCIADDRS(opt, neg, val1, val2) \
+    if ((neg) && \
+	(cilen = p[1]) == CILEN_ADDRS && \
+	len >= cilen && \
+	p[0] == opt) { \
+	u32_t l; \
+	len -= cilen; \
+	INCPTR(2, p); \
+	GETLONG(l, p); \
+	cilong = lwip_htonl(l); \
+	/* Check rejected value. */ \
+	if (cilong != val1) \
+	    goto bad; \
+	GETLONG(l, p); \
+	cilong = lwip_htonl(l); \
+	/* Check rejected value. */ \
+	if (cilong != val2) \
+	    goto bad; \
+	try_.old_addrs = 0; \
+    }
+
+#if VJ_SUPPORT
+#define REJCIVJ(opt, neg, val, old, maxslot, cflag) \
+    if (go->neg && \
+	p[1] == (old? CILEN_COMPRESS : CILEN_VJ) && \
+	len >= p[1] && \
+	p[0] == opt) { \
+	len -= p[1]; \
+	INCPTR(2, p); \
+	GETSHORT(cishort, p); \
+	/* Check rejected value. */  \
+	if (cishort != val) \
+	    goto bad; \
+	if (!old) { \
+	   GETCHAR(cimaxslotindex, p); \
+	   if (cimaxslotindex != maxslot) \
+	     goto bad; \
+	   GETCHAR(ciflag, p); \
+	   if (ciflag != cflag) \
+	     goto bad; \
+        } \
+	try_.neg = 0; \
+     }
+#endif /* VJ_SUPPORT */
+
+#define REJCIADDR(opt, neg, val) \
+    if (go->neg && \
+	(cilen = p[1]) == CILEN_ADDR && \
+	len >= cilen && \
+	p[0] == opt) { \
+	u32_t l; \
+	len -= cilen; \
+	INCPTR(2, p); \
+	GETLONG(l, p); \
+	cilong = lwip_htonl(l); \
+	/* Check rejected value. */ \
+	if (cilong != val) \
+	    goto bad; \
+	try_.neg = 0; \
+    }
+
+#if LWIP_DNS
+#define REJCIDNS(opt, neg, dnsaddr) \
+    if (go->neg && \
+	((cilen = p[1]) == CILEN_ADDR) && \
+	len >= cilen && \
+	p[0] == opt) { \
+	u32_t l; \
+	len -= cilen; \
+	INCPTR(2, p); \
+	GETLONG(l, p); \
+	cilong = lwip_htonl(l); \
+	/* Check rejected value. */ \
+	if (cilong != dnsaddr) \
+	    goto bad; \
+	try_.neg = 0; \
+    }
+#endif /* LWIP_DNS */
+
+#if 0 /* UNUSED - WINS */
+#define REJCIWINS(opt, addr) \
+    if (addr && \
+	((cilen = p[1]) == CILEN_ADDR) && \
+	len >= cilen && \
+	p[0] == opt) { \
+	u32_t l; \
+	len -= cilen; \
+	INCPTR(2, p); \
+	GETLONG(l, p); \
+	cilong = lwip_htonl(l); \
+	/* Check rejected value. */ \
+	if (cilong != addr) \
+	    goto bad; \
+	try_.winsaddr[opt == CI_MS_WINS2] = 0; \
+    }
+#endif /* UNUSED - WINS */
+
+    REJCIADDRS(CI_ADDRS, !go->neg_addr && go->old_addrs,
+	       go->ouraddr, go->hisaddr);
+
+#if VJ_SUPPORT
+    REJCIVJ(CI_COMPRESSTYPE, neg_vj, go->vj_protocol, go->old_vj,
+	    go->maxslotindex, go->cflag);
+#endif /* VJ_SUPPORT */
+
+    REJCIADDR(CI_ADDR, neg_addr, go->ouraddr);
+
+#if LWIP_DNS
+    REJCIDNS(CI_MS_DNS1, req_dns1, go->dnsaddr[0]);
+
+    REJCIDNS(CI_MS_DNS2, req_dns2, go->dnsaddr[1]);
+#endif /* LWIP_DNS */
+
+#if 0 /* UNUSED - WINS */
+    REJCIWINS(CI_MS_WINS1, go->winsaddr[0]);
+
+    REJCIWINS(CI_MS_WINS2, go->winsaddr[1]);
+#endif /* UNUSED - WINS */
+
+    /*
+     * If there are any remaining CIs, then this packet is bad.
+     */
+    if (len != 0)
+	goto bad;
+    /*
+     * Now we can update state.
+     */
+    if (f->state != PPP_FSM_OPENED)
+	*go = try_;
+    return 1;
+
+bad:
+    IPCPDEBUG(("ipcp_rejci: received bad Reject!"));
+    return 0;
+}
+
+
+/*
+ * ipcp_reqci - Check the peer's requested CIs and send appropriate response.
+ * Callback from fsm_rconfreq, Receive Configure Request
+ *
+ * Returns: CONFACK, CONFNAK or CONFREJ and input packet modified
+ * appropriately.  If reject_if_disagree is non-zero, doesn't return
+ * CONFNAK; returns CONFREJ if it can't return CONFACK.
+ *
+ * inp = Requested CIs
+ * len = Length of requested CIs
+ */
+static int ipcp_reqci(fsm *f, u_char *inp, int *len, int reject_if_disagree) {
+    ppp_pcb *pcb = f->pcb;
+    ipcp_options *wo = &pcb->ipcp_wantoptions;
+    ipcp_options *ho = &pcb->ipcp_hisoptions;
+    ipcp_options *ao = &pcb->ipcp_allowoptions;
+    u_char *cip, *next;		/* Pointer to current and next CIs */
+    u_short cilen, citype;	/* Parsed len, type */
+#if VJ_SUPPORT
+    u_short cishort;		/* Parsed short value */
+#endif /* VJ_SUPPORT */
+    u32_t tl, ciaddr1, ciaddr2;/* Parsed address values */
+    int rc = CONFACK;		/* Final packet return code */
+    int orc;			/* Individual option return code */
+    u_char *p;			/* Pointer to next char to parse */
+    u_char *ucp = inp;		/* Pointer to current output char */
+    int l = *len;		/* Length left */
+#if VJ_SUPPORT
+    u_char maxslotindex, cflag;
+#endif /* VJ_SUPPORT */
+#if LWIP_DNS
+    int d;
+#endif /* LWIP_DNS */
+
+    /*
+     * Reset all his options.
+     */
+    BZERO(ho, sizeof(*ho));
+    
+    /*
+     * Process all his options.
+     */
+    next = inp;
+    while (l) {
+	orc = CONFACK;			/* Assume success */
+	cip = p = next;			/* Remember begining of CI */
+	if (l < 2 ||			/* Not enough data for CI header or */
+	    p[1] < 2 ||			/*  CI length too small or */
+	    p[1] > l) {			/*  CI length too big? */
+	    IPCPDEBUG(("ipcp_reqci: bad CI length!"));
+	    orc = CONFREJ;		/* Reject bad CI */
+	    cilen = l;			/* Reject till end of packet */
+	    l = 0;			/* Don't loop again */
+	    goto endswitch;
+	}
+	GETCHAR(citype, p);		/* Parse CI type */
+	GETCHAR(cilen, p);		/* Parse CI length */
+	l -= cilen;			/* Adjust remaining length */
+	next += cilen;			/* Step to next CI */
+
+	switch (citype) {		/* Check CI type */
+	case CI_ADDRS:
+	    if (!ao->old_addrs || ho->neg_addr ||
+		cilen != CILEN_ADDRS) {	/* Check CI length */
+		orc = CONFREJ;		/* Reject CI */
+		break;
+	    }
+
+	    /*
+	     * If he has no address, or if we both have his address but
+	     * disagree about it, then NAK it with our idea.
+	     * In particular, if we don't know his address, but he does,
+	     * then accept it.
+	     */
+	    GETLONG(tl, p);		/* Parse source address (his) */
+	    ciaddr1 = lwip_htonl(tl);
+	    if (ciaddr1 != wo->hisaddr
+		&& (ciaddr1 == 0 || !wo->accept_remote)) {
+		orc = CONFNAK;
+		if (!reject_if_disagree) {
+		    DECPTR(sizeof(u32_t), p);
+		    tl = lwip_ntohl(wo->hisaddr);
+		    PUTLONG(tl, p);
+		}
+	    } else if (ciaddr1 == 0 && wo->hisaddr == 0) {
+		/*
+		 * If neither we nor he knows his address, reject the option.
+		 */
+		orc = CONFREJ;
+		wo->req_addr = 0;	/* don't NAK with 0.0.0.0 later */
+		break;
+	    }
+
+	    /*
+	     * If he doesn't know our address, or if we both have our address
+	     * but disagree about it, then NAK it with our idea.
+	     */
+	    GETLONG(tl, p);		/* Parse desination address (ours) */
+	    ciaddr2 = lwip_htonl(tl);
+	    if (ciaddr2 != wo->ouraddr) {
+		if (ciaddr2 == 0 || !wo->accept_local) {
+		    orc = CONFNAK;
+		    if (!reject_if_disagree) {
+			DECPTR(sizeof(u32_t), p);
+			tl = lwip_ntohl(wo->ouraddr);
+			PUTLONG(tl, p);
+		    }
+		} else {
+		    wo->ouraddr = ciaddr2;	/* accept peer's idea */
+		}
+	    }
+
+	    ho->old_addrs = 1;
+	    ho->hisaddr = ciaddr1;
+	    ho->ouraddr = ciaddr2;
+	    break;
+
+	case CI_ADDR:
+	    if (!ao->neg_addr || ho->old_addrs ||
+		cilen != CILEN_ADDR) {	/* Check CI length */
+		orc = CONFREJ;		/* Reject CI */
+		break;
+	    }
+
+	    /*
+	     * If he has no address, or if we both have his address but
+	     * disagree about it, then NAK it with our idea.
+	     * In particular, if we don't know his address, but he does,
+	     * then accept it.
+	     */
+	    GETLONG(tl, p);	/* Parse source address (his) */
+	    ciaddr1 = lwip_htonl(tl);
+	    if (ciaddr1 != wo->hisaddr
+		&& (ciaddr1 == 0 || !wo->accept_remote)) {
+		orc = CONFNAK;
+		if (!reject_if_disagree) {
+		    DECPTR(sizeof(u32_t), p);
+		    tl = lwip_ntohl(wo->hisaddr);
+		    PUTLONG(tl, p);
+		}
+	    } else if (ciaddr1 == 0 && wo->hisaddr == 0) {
+		/*
+		 * Don't ACK an address of 0.0.0.0 - reject it instead.
+		 */
+		orc = CONFREJ;
+		wo->req_addr = 0;	/* don't NAK with 0.0.0.0 later */
+		break;
+	    }
+	
+	    ho->neg_addr = 1;
+	    ho->hisaddr = ciaddr1;
+	    break;
+
+#if LWIP_DNS
+	case CI_MS_DNS1:
+	case CI_MS_DNS2:
+	    /* Microsoft primary or secondary DNS request */
+	    d = citype == CI_MS_DNS2;
+
+	    /* If we do not have a DNS address then we cannot send it */
+	    if (ao->dnsaddr[d] == 0 ||
+		cilen != CILEN_ADDR) {	/* Check CI length */
+		orc = CONFREJ;		/* Reject CI */
+		break;
+	    }
+	    GETLONG(tl, p);
+	    if (lwip_htonl(tl) != ao->dnsaddr[d]) {
+                DECPTR(sizeof(u32_t), p);
+		tl = lwip_ntohl(ao->dnsaddr[d]);
+		PUTLONG(tl, p);
+		orc = CONFNAK;
+            }
+            break;
+#endif /* LWIP_DNS */
+
+#if 0 /* UNUSED - WINS */
+	case CI_MS_WINS1:
+	case CI_MS_WINS2:
+	    /* Microsoft primary or secondary WINS request */
+	    d = citype == CI_MS_WINS2;
+
+	    /* If we do not have a DNS address then we cannot send it */
+	    if (ao->winsaddr[d] == 0 ||
+		cilen != CILEN_ADDR) {	/* Check CI length */
+		orc = CONFREJ;		/* Reject CI */
+		break;
+	    }
+	    GETLONG(tl, p);
+	    if (lwip_htonl(tl) != ao->winsaddr[d]) {
+                DECPTR(sizeof(u32_t), p);
+		tl = lwip_ntohl(ao->winsaddr[d]);
+		PUTLONG(tl, p);
+		orc = CONFNAK;
+            }
+            break;
+#endif /* UNUSED - WINS */
+
+#if VJ_SUPPORT
+	case CI_COMPRESSTYPE:
+	    if (!ao->neg_vj ||
+		(cilen != CILEN_VJ && cilen != CILEN_COMPRESS)) {
+		orc = CONFREJ;
+		break;
+	    }
+	    GETSHORT(cishort, p);
+
+	    if (!(cishort == IPCP_VJ_COMP ||
+		  (cishort == IPCP_VJ_COMP_OLD && cilen == CILEN_COMPRESS))) {
+		orc = CONFREJ;
+		break;
+	    }
+
+	    ho->neg_vj = 1;
+	    ho->vj_protocol = cishort;
+	    if (cilen == CILEN_VJ) {
+		GETCHAR(maxslotindex, p);
+		if (maxslotindex > ao->maxslotindex) { 
+		    orc = CONFNAK;
+		    if (!reject_if_disagree){
+			DECPTR(1, p);
+			PUTCHAR(ao->maxslotindex, p);
+		    }
+		}
+		GETCHAR(cflag, p);
+		if (cflag && !ao->cflag) {
+		    orc = CONFNAK;
+		    if (!reject_if_disagree){
+			DECPTR(1, p);
+			PUTCHAR(wo->cflag, p);
+		    }
+		}
+		ho->maxslotindex = maxslotindex;
+		ho->cflag = cflag;
+	    } else {
+		ho->old_vj = 1;
+		ho->maxslotindex = MAX_STATES - 1;
+		ho->cflag = 1;
+	    }
+	    break;
+#endif /* VJ_SUPPORT */
+
+	default:
+	    orc = CONFREJ;
+	    break;
+	}
+endswitch:
+	if (orc == CONFACK &&		/* Good CI */
+	    rc != CONFACK)		/*  but prior CI wasnt? */
+	    continue;			/* Don't send this one */
+
+	if (orc == CONFNAK) {		/* Nak this CI? */
+	    if (reject_if_disagree)	/* Getting fed up with sending NAKs? */
+		orc = CONFREJ;		/* Get tough if so */
+	    else {
+		if (rc == CONFREJ)	/* Rejecting prior CI? */
+		    continue;		/* Don't send this one */
+		if (rc == CONFACK) {	/* Ack'd all prior CIs? */
+		    rc = CONFNAK;	/* Not anymore... */
+		    ucp = inp;		/* Backup */
+		}
+	    }
+	}
+
+	if (orc == CONFREJ &&		/* Reject this CI */
+	    rc != CONFREJ) {		/*  but no prior ones? */
+	    rc = CONFREJ;
+	    ucp = inp;			/* Backup */
+	}
+
+	/* Need to move CI? */
+	if (ucp != cip)
+	    MEMCPY(ucp, cip, cilen);	/* Move it */
+
+	/* Update output pointer */
+	INCPTR(cilen, ucp);
+    }
+
+    /*
+     * If we aren't rejecting this packet, and we want to negotiate
+     * their address, and they didn't send their address, then we
+     * send a NAK with a CI_ADDR option appended.  We assume the
+     * input buffer is long enough that we can append the extra
+     * option safely.
+     */
+    if (rc != CONFREJ && !ho->neg_addr && !ho->old_addrs &&
+	wo->req_addr && !reject_if_disagree && !pcb->settings.noremoteip) {
+	if (rc == CONFACK) {
+	    rc = CONFNAK;
+	    ucp = inp;			/* reset pointer */
+	    wo->req_addr = 0;		/* don't ask again */
+	}
+	PUTCHAR(CI_ADDR, ucp);
+	PUTCHAR(CILEN_ADDR, ucp);
+	tl = lwip_ntohl(wo->hisaddr);
+	PUTLONG(tl, ucp);
+    }
+
+    *len = ucp - inp;			/* Compute output length */
+    IPCPDEBUG(("ipcp: returning Configure-%s", CODENAME(rc)));
+    return (rc);			/* Return final code */
+}
+
+
+#if 0 /* UNUSED */
+/*
+ * ip_check_options - check that any IP-related options are OK,
+ * and assign appropriate defaults.
+ */
+static void
+ip_check_options()
+{
+    struct hostent *hp;
+    u32_t local;
+    ipcp_options *wo = &ipcp_wantoptions[0];
+
+    /*
+     * Default our local IP address based on our hostname.
+     * If local IP address already given, don't bother.
+     */
+    if (wo->ouraddr == 0 && !disable_defaultip) {
+	/*
+	 * Look up our hostname (possibly with domain name appended)
+	 * and take the first IP address as our local IP address.
+	 * If there isn't an IP address for our hostname, too bad.
+	 */
+	wo->accept_local = 1;	/* don't insist on this default value */
+	if ((hp = gethostbyname(hostname)) != NULL) {
+	    local = *(u32_t *)hp->h_addr;
+	    if (local != 0 && !bad_ip_adrs(local))
+		wo->ouraddr = local;
+	}
+    }
+    ask_for_local = wo->ouraddr != 0 || !disable_defaultip;
+}
+#endif /* UNUSED */
+
+#if DEMAND_SUPPORT
+/*
+ * ip_demand_conf - configure the interface as though
+ * IPCP were up, for use with dial-on-demand.
+ */
+static int
+ip_demand_conf(u)
+    int u;
+{
+    ppp_pcb *pcb = &ppp_pcb_list[u];
+    ipcp_options *wo = &ipcp_wantoptions[u];
+
+    if (wo->hisaddr == 0 && !pcb->settings.noremoteip) {
+	/* make up an arbitrary address for the peer */
+	wo->hisaddr = lwip_htonl(0x0a707070 + ifunit);
+	wo->accept_remote = 1;
+    }
+    if (wo->ouraddr == 0) {
+	/* make up an arbitrary address for us */
+	wo->ouraddr = lwip_htonl(0x0a404040 + ifunit);
+	wo->accept_local = 1;
+	ask_for_local = 0;	/* don't tell the peer this address */
+    }
+    if (!sifaddr(pcb, wo->ouraddr, wo->hisaddr, get_mask(wo->ouraddr)))
+	return 0;
+    if (!sifup(pcb))
+	return 0;
+    if (!sifnpmode(pcb, PPP_IP, NPMODE_QUEUE))
+	return 0;
+#if 0 /* UNUSED */
+    if (wo->default_route)
+	if (sifdefaultroute(pcb, wo->ouraddr, wo->hisaddr,
+		wo->replace_default_route))
+	    default_route_set[u] = 1;
+#endif /* UNUSED */
+#if 0 /* UNUSED - PROXY ARP */
+    if (wo->proxy_arp)
+	if (sifproxyarp(pcb, wo->hisaddr))
+	    proxy_arp_set[u] = 1;
+#endif /* UNUSED - PROXY ARP */
+
+    ppp_notice("local  IP address %I", wo->ouraddr);
+    if (wo->hisaddr)
+	ppp_notice("remote IP address %I", wo->hisaddr);
+
+    return 1;
+}
+#endif /* DEMAND_SUPPORT */
+
+/*
+ * ipcp_up - IPCP has come UP.
+ *
+ * Configure the IP network interface appropriately and bring it up.
+ */
+static void ipcp_up(fsm *f) {
+    ppp_pcb *pcb = f->pcb;
+    u32_t mask;
+    ipcp_options *ho = &pcb->ipcp_hisoptions;
+    ipcp_options *go = &pcb->ipcp_gotoptions;
+    ipcp_options *wo = &pcb->ipcp_wantoptions;
+
+    IPCPDEBUG(("ipcp: up"));
+
+    /*
+     * We must have a non-zero IP address for both ends of the link.
+     */
+    if (!ho->neg_addr && !ho->old_addrs)
+	ho->hisaddr = wo->hisaddr;
+
+    if (!(go->neg_addr || go->old_addrs) && (wo->neg_addr || wo->old_addrs)
+	&& wo->ouraddr != 0) {
+	ppp_error("Peer refused to agree to our IP address");
+	ipcp_close(f->pcb, "Refused our IP address");
+	return;
+    }
+    if (go->ouraddr == 0) {
+	ppp_error("Could not determine local IP address");
+	ipcp_close(f->pcb, "Could not determine local IP address");
+	return;
+    }
+    if (ho->hisaddr == 0 && !pcb->settings.noremoteip) {
+	ho->hisaddr = lwip_htonl(0x0a404040);
+	ppp_warn("Could not determine remote IP address: defaulting to %I",
+	     ho->hisaddr);
+    }
+#if 0 /* UNUSED */
+    script_setenv("IPLOCAL", ip_ntoa(go->ouraddr), 0);
+    if (ho->hisaddr != 0)
+	script_setenv("IPREMOTE", ip_ntoa(ho->hisaddr), 1);
+#endif /* UNUSED */
+
+#if LWIP_DNS
+    if (!go->req_dns1)
+	    go->dnsaddr[0] = 0;
+    if (!go->req_dns2)
+	    go->dnsaddr[1] = 0;
+#if 0 /* UNUSED */
+    if (go->dnsaddr[0])
+	script_setenv("DNS1", ip_ntoa(go->dnsaddr[0]), 0);
+    if (go->dnsaddr[1])
+	script_setenv("DNS2", ip_ntoa(go->dnsaddr[1]), 0);
+#endif /* UNUSED */
+    if (pcb->settings.usepeerdns && (go->dnsaddr[0] || go->dnsaddr[1])) {
+	sdns(pcb, go->dnsaddr[0], go->dnsaddr[1]);
+#if 0 /* UNUSED */
+	script_setenv("USEPEERDNS", "1", 0);
+	create_resolv(go->dnsaddr[0], go->dnsaddr[1]);
+#endif /* UNUSED */
+    }
+#endif /* LWIP_DNS */
+
+    /*
+     * Check that the peer is allowed to use the IP address it wants.
+     */
+    if (ho->hisaddr != 0) {
+	u32_t addr = lwip_ntohl(ho->hisaddr);
+	if ((addr >> IP_CLASSA_NSHIFT) == IP_LOOPBACKNET
+	    || IP_MULTICAST(addr) || IP_BADCLASS(addr)
+	    /*
+	     * For now, consider that PPP in server mode with peer required
+	     * to authenticate must provide the peer IP address, reject any
+	     * IP address wanted by peer different than the one we wanted.
+	     */
+#if PPP_SERVER && PPP_AUTH_SUPPORT
+	    || (pcb->settings.auth_required && wo->hisaddr != ho->hisaddr)
+#endif /* PPP_SERVER && PPP_AUTH_SUPPORT */
+	    ) {
+		ppp_error("Peer is not authorized to use remote address %I", ho->hisaddr);
+		ipcp_close(pcb, "Unauthorized remote IP address");
+		return;
+	}
+    }
+#if 0 /* Unused */
+    /* Upstream checking code */
+    if (ho->hisaddr != 0 && !auth_ip_addr(f->unit, ho->hisaddr)) {
+	ppp_error("Peer is not authorized to use remote address %I", ho->hisaddr);
+	ipcp_close(f->unit, "Unauthorized remote IP address");
+	return;
+    }
+#endif /* Unused */
+
+#if VJ_SUPPORT
+    /* set tcp compression */
+    sifvjcomp(pcb, ho->neg_vj, ho->cflag, ho->maxslotindex);
+#endif /* VJ_SUPPORT */
+
+#if DEMAND_SUPPORT
+    /*
+     * If we are doing dial-on-demand, the interface is already
+     * configured, so we put out any saved-up packets, then set the
+     * interface to pass IP packets.
+     */
+    if (demand) {
+	if (go->ouraddr != wo->ouraddr || ho->hisaddr != wo->hisaddr) {
+	    ipcp_clear_addrs(f->unit, wo->ouraddr, wo->hisaddr,
+				      wo->replace_default_route);
+	    if (go->ouraddr != wo->ouraddr) {
+		ppp_warn("Local IP address changed to %I", go->ouraddr);
+		script_setenv("OLDIPLOCAL", ip_ntoa(wo->ouraddr), 0);
+		wo->ouraddr = go->ouraddr;
+	    } else
+		script_unsetenv("OLDIPLOCAL");
+	    if (ho->hisaddr != wo->hisaddr && wo->hisaddr != 0) {
+		ppp_warn("Remote IP address changed to %I", ho->hisaddr);
+		script_setenv("OLDIPREMOTE", ip_ntoa(wo->hisaddr), 0);
+		wo->hisaddr = ho->hisaddr;
+	    } else
+		script_unsetenv("OLDIPREMOTE");
+
+	    /* Set the interface to the new addresses */
+	    mask = get_mask(go->ouraddr);
+	    if (!sifaddr(pcb, go->ouraddr, ho->hisaddr, mask)) {
+#if PPP_DEBUG
+		ppp_warn("Interface configuration failed");
+#endif /* PPP_DEBUG */
+		ipcp_close(f->unit, "Interface configuration failed");
+		return;
+	    }
+
+	    /* assign a default route through the interface if required */
+	    if (ipcp_wantoptions[f->unit].default_route) 
+		if (sifdefaultroute(pcb, go->ouraddr, ho->hisaddr,
+			wo->replace_default_route))
+		    default_route_set[f->unit] = 1;
+
+#if 0 /* UNUSED - PROXY ARP */
+	    /* Make a proxy ARP entry if requested. */
+	    if (ho->hisaddr != 0 && ipcp_wantoptions[f->unit].proxy_arp)
+		if (sifproxyarp(pcb, ho->hisaddr))
+		    proxy_arp_set[f->unit] = 1;
+#endif /* UNUSED - PROXY ARP */
+
+	}
+	demand_rexmit(PPP_IP,go->ouraddr);
+	sifnpmode(pcb, PPP_IP, NPMODE_PASS);
+
+    } else
+#endif /* DEMAND_SUPPORT */
+    {
+	/*
+	 * Set IP addresses and (if specified) netmask.
+	 */
+	mask = get_mask(go->ouraddr);
+
+#if !(defined(SVR4) && (defined(SNI) || defined(__USLC__)))
+	if (!sifaddr(pcb, go->ouraddr, ho->hisaddr, mask)) {
+#if PPP_DEBUG
+	    ppp_warn("Interface configuration failed");
+#endif /* PPP_DEBUG */
+	    ipcp_close(f->pcb, "Interface configuration failed");
+	    return;
+	}
+#endif
+
+	/* bring the interface up for IP */
+	if (!sifup(pcb)) {
+#if PPP_DEBUG
+	    ppp_warn("Interface failed to come up");
+#endif /* PPP_DEBUG */
+	    ipcp_close(f->pcb, "Interface configuration failed");
+	    return;
+	}
+
+#if (defined(SVR4) && (defined(SNI) || defined(__USLC__)))
+	if (!sifaddr(pcb, go->ouraddr, ho->hisaddr, mask)) {
+#if PPP_DEBUG
+	    ppp_warn("Interface configuration failed");
+#endif /* PPP_DEBUG */
+	    ipcp_close(f->unit, "Interface configuration failed");
+	    return;
+	}
+#endif
+#if DEMAND_SUPPORT
+	sifnpmode(pcb, PPP_IP, NPMODE_PASS);
+#endif /* DEMAND_SUPPORT */
+
+#if 0 /* UNUSED */
+	/* assign a default route through the interface if required */
+	if (wo->default_route)
+	    if (sifdefaultroute(pcb, go->ouraddr, ho->hisaddr,
+		    wo->replace_default_route))
+		    pcb->default_route_set = 1;
+#endif /* UNUSED */
+
+#if 0 /* UNUSED - PROXY ARP */
+	/* Make a proxy ARP entry if requested. */
+	if (ho->hisaddr != 0 && wo->proxy_arp)
+	    if (sifproxyarp(pcb, ho->hisaddr))
+		pcb->proxy_arp_set = 1;
+#endif /* UNUSED - PROXY ARP */
+
+	wo->ouraddr = go->ouraddr;
+
+	ppp_notice("local  IP address %I", go->ouraddr);
+	if (ho->hisaddr != 0)
+	    ppp_notice("remote IP address %I", ho->hisaddr);
+#if LWIP_DNS
+	if (go->dnsaddr[0])
+	    ppp_notice("primary   DNS address %I", go->dnsaddr[0]);
+	if (go->dnsaddr[1])
+	    ppp_notice("secondary DNS address %I", go->dnsaddr[1]);
+#endif /* LWIP_DNS */
+    }
+
+#if PPP_STATS_SUPPORT
+    reset_link_stats(f->unit);
+#endif /* PPP_STATS_SUPPORT */
+
+    np_up(pcb, PPP_IP);
+    pcb->ipcp_is_up = 1;
+
+#if PPP_NOTIFY
+    notify(ip_up_notifier, 0);
+#endif /* PPP_NOTIFY */
+#if 0 /* UNUSED */
+    if (ip_up_hook)
+	ip_up_hook();
+#endif /* UNUSED */
+}
+
+
+/*
+ * ipcp_down - IPCP has gone DOWN.
+ *
+ * Take the IP network interface down, clear its addresses
+ * and delete routes through it.
+ */
+static void ipcp_down(fsm *f) {
+    ppp_pcb *pcb = f->pcb;
+    ipcp_options *ho = &pcb->ipcp_hisoptions;
+    ipcp_options *go = &pcb->ipcp_gotoptions;
+
+    IPCPDEBUG(("ipcp: down"));
+#if PPP_STATS_SUPPORT
+    /* XXX a bit IPv4-centric here, we only need to get the stats
+     * before the interface is marked down. */
+    /* XXX more correct: we must get the stats before running the notifiers,
+     * at least for the radius plugin */
+    update_link_stats(f->unit);
+#endif /* PPP_STATS_SUPPORT */
+#if PPP_NOTIFY
+    notify(ip_down_notifier, 0);
+#endif /* PPP_NOTIFY */
+#if 0 /* UNUSED */
+    if (ip_down_hook)
+	ip_down_hook();
+#endif /* UNUSED */
+    if (pcb->ipcp_is_up) {
+	pcb->ipcp_is_up = 0;
+	np_down(pcb, PPP_IP);
+    }
+#if VJ_SUPPORT
+    sifvjcomp(pcb, 0, 0, 0);
+#endif /* VJ_SUPPORT */
+
+#if PPP_STATS_SUPPORT
+    print_link_stats(); /* _after_ running the notifiers and ip_down_hook(),
+			 * because print_link_stats() sets link_stats_valid
+			 * to 0 (zero) */
+#endif /* PPP_STATS_SUPPORT */
+
+#if DEMAND_SUPPORT
+    /*
+     * If we are doing dial-on-demand, set the interface
+     * to queue up outgoing packets (for now).
+     */
+    if (demand) {
+	sifnpmode(pcb, PPP_IP, NPMODE_QUEUE);
+    } else
+#endif /* DEMAND_SUPPORT */
+    {
+#if DEMAND_SUPPORT
+	sifnpmode(pcb, PPP_IP, NPMODE_DROP);
+#endif /* DEMAND_SUPPORT */
+	sifdown(pcb);
+	ipcp_clear_addrs(pcb, go->ouraddr,
+			 ho->hisaddr, 0);
+#if LWIP_DNS
+	cdns(pcb, go->dnsaddr[0], go->dnsaddr[1]);
+#endif /* LWIP_DNS */
+    }
+}
+
+
+/*
+ * ipcp_clear_addrs() - clear the interface addresses, routes,
+ * proxy arp entries, etc.
+ */
+static void ipcp_clear_addrs(ppp_pcb *pcb, u32_t ouraddr, u32_t hisaddr, u8_t replacedefaultroute) {
+    LWIP_UNUSED_ARG(replacedefaultroute);
+
+#if 0 /* UNUSED - PROXY ARP */
+    if (pcb->proxy_arp_set) {
+	cifproxyarp(pcb, hisaddr);
+	pcb->proxy_arp_set = 0;
+    }
+#endif /* UNUSED - PROXY ARP */
+#if 0 /* UNUSED */
+    /* If replacedefaultroute, sifdefaultroute will be called soon
+     * with replacedefaultroute set and that will overwrite the current
+     * default route. This is the case only when doing demand, otherwise
+     * during demand, this cifdefaultroute would restore the old default
+     * route which is not what we want in this case. In the non-demand
+     * case, we'll delete the default route and restore the old if there
+     * is one saved by an sifdefaultroute with replacedefaultroute.
+     */
+    if (!replacedefaultroute && pcb->default_route_set) {
+	cifdefaultroute(pcb, ouraddr, hisaddr);
+	pcb->default_route_set = 0;
+    }
+#endif /* UNUSED */
+    cifaddr(pcb, ouraddr, hisaddr);
+}
+
+
+/*
+ * ipcp_finished - possibly shut down the lower layers.
+ */
+static void ipcp_finished(fsm *f) {
+	ppp_pcb *pcb = f->pcb;
+	if (pcb->ipcp_is_open) {
+		pcb->ipcp_is_open = 0;
+		np_finished(pcb, PPP_IP);
+	}
+}
+
+
+#if 0 /* UNUSED */
+/*
+ * create_resolv - create the replacement resolv.conf file
+ */
+static void
+create_resolv(peerdns1, peerdns2)
+    u32_t peerdns1, peerdns2;
+{
+
+}
+#endif /* UNUSED */
+
+#if PRINTPKT_SUPPORT
+/*
+ * ipcp_printpkt - print the contents of an IPCP packet.
+ */
+static const char* const ipcp_codenames[] = {
+    "ConfReq", "ConfAck", "ConfNak", "ConfRej",
+    "TermReq", "TermAck", "CodeRej"
+};
+
+static int ipcp_printpkt(const u_char *p, int plen,
+		void (*printer) (void *, const char *, ...), void *arg) {
+    int code, id, len, olen;
+    const u_char *pstart, *optend;
+#if VJ_SUPPORT
+    u_short cishort;
+#endif /* VJ_SUPPORT */
+    u32_t cilong;
+
+    if (plen < HEADERLEN)
+	return 0;
+    pstart = p;
+    GETCHAR(code, p);
+    GETCHAR(id, p);
+    GETSHORT(len, p);
+    if (len < HEADERLEN || len > plen)
+	return 0;
+
+    if (code >= 1 && code <= (int)LWIP_ARRAYSIZE(ipcp_codenames))
+	printer(arg, " %s", ipcp_codenames[code-1]);
+    else
+	printer(arg, " code=0x%x", code);
+    printer(arg, " id=0x%x", id);
+    len -= HEADERLEN;
+    switch (code) {
+    case CONFREQ:
+    case CONFACK:
+    case CONFNAK:
+    case CONFREJ:
+	/* print option list */
+	while (len >= 2) {
+	    GETCHAR(code, p);
+	    GETCHAR(olen, p);
+	    p -= 2;
+	    if (olen < 2 || olen > len) {
+		break;
+	    }
+	    printer(arg, " <");
+	    len -= olen;
+	    optend = p + olen;
+	    switch (code) {
+	    case CI_ADDRS:
+		if (olen == CILEN_ADDRS) {
+		    p += 2;
+		    GETLONG(cilong, p);
+		    printer(arg, "addrs %I", lwip_htonl(cilong));
+		    GETLONG(cilong, p);
+		    printer(arg, " %I", lwip_htonl(cilong));
+		}
+		break;
+#if VJ_SUPPORT
+	    case CI_COMPRESSTYPE:
+		if (olen >= CILEN_COMPRESS) {
+		    p += 2;
+		    GETSHORT(cishort, p);
+		    printer(arg, "compress ");
+		    switch (cishort) {
+		    case IPCP_VJ_COMP:
+			printer(arg, "VJ");
+			break;
+		    case IPCP_VJ_COMP_OLD:
+			printer(arg, "old-VJ");
+			break;
+		    default:
+			printer(arg, "0x%x", cishort);
+		    }
+		}
+		break;
+#endif /* VJ_SUPPORT */
+	    case CI_ADDR:
+		if (olen == CILEN_ADDR) {
+		    p += 2;
+		    GETLONG(cilong, p);
+		    printer(arg, "addr %I", lwip_htonl(cilong));
+		}
+		break;
+#if LWIP_DNS
+	    case CI_MS_DNS1:
+	    case CI_MS_DNS2:
+	        p += 2;
+		GETLONG(cilong, p);
+		printer(arg, "ms-dns%d %I", (code == CI_MS_DNS1? 1: 2),
+			htonl(cilong));
+		break;
+#endif /* LWIP_DNS */
+#if 0 /* UNUSED - WINS */
+	    case CI_MS_WINS1:
+	    case CI_MS_WINS2:
+	        p += 2;
+		GETLONG(cilong, p);
+		printer(arg, "ms-wins %I", lwip_htonl(cilong));
+		break;
+#endif /* UNUSED - WINS */
+	    default:
+		break;
+	    }
+	    while (p < optend) {
+		GETCHAR(code, p);
+		printer(arg, " %.2x", code);
+	    }
+	    printer(arg, ">");
+	}
+	break;
+
+    case TERMACK:
+    case TERMREQ:
+	if (len > 0 && *p >= ' ' && *p < 0x7f) {
+	    printer(arg, " ");
+	    ppp_print_string(p, len, printer, arg);
+	    p += len;
+	    len = 0;
+	}
+	break;
+    default:
+	break;
+    }
+
+    /* print the rest of the bytes in the packet */
+    for (; len > 0; --len) {
+	GETCHAR(code, p);
+	printer(arg, " %.2x", code);
+    }
+
+    return p - pstart;
+}
+#endif /* PRINTPKT_SUPPORT */
+
+#if DEMAND_SUPPORT
+/*
+ * ip_active_pkt - see if this IP packet is worth bringing the link up for.
+ * We don't bring the link up for IP fragments or for TCP FIN packets
+ * with no data.
+ */
+#define IP_HDRLEN	20	/* bytes */
+#define IP_OFFMASK	0x1fff
+#ifndef IPPROTO_TCP
+#define IPPROTO_TCP	6
+#endif
+#define TCP_HDRLEN	20
+#define TH_FIN		0x01
+
+/*
+ * We use these macros because the IP header may be at an odd address,
+ * and some compilers might use word loads to get th_off or ip_hl.
+ */
+
+#define net_short(x)	(((x)[0] << 8) + (x)[1])
+#define get_iphl(x)	(((unsigned char *)(x))[0] & 0xF)
+#define get_ipoff(x)	net_short((unsigned char *)(x) + 6)
+#define get_ipproto(x)	(((unsigned char *)(x))[9])
+#define get_tcpoff(x)	(((unsigned char *)(x))[12] >> 4)
+#define get_tcpflags(x)	(((unsigned char *)(x))[13])
+
+static int
+ip_active_pkt(pkt, len)
+    u_char *pkt;
+    int len;
+{
+    u_char *tcp;
+    int hlen;
+
+    len -= PPP_HDRLEN;
+    pkt += PPP_HDRLEN;
+    if (len < IP_HDRLEN)
+	return 0;
+    if ((get_ipoff(pkt) & IP_OFFMASK) != 0)
+	return 0;
+    if (get_ipproto(pkt) != IPPROTO_TCP)
+	return 1;
+    hlen = get_iphl(pkt) * 4;
+    if (len < hlen + TCP_HDRLEN)
+	return 0;
+    tcp = pkt + hlen;
+    if ((get_tcpflags(tcp) & TH_FIN) != 0 && len == hlen + get_tcpoff(tcp) * 4)
+	return 0;
+    return 1;
+}
+#endif /* DEMAND_SUPPORT */
+
+#endif /* PPP_SUPPORT && PPP_IPV4_SUPPORT */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/netif/ppp/ipv6cp.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/netif/ppp/ipv6cp.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/netif/ppp/ipv6cp.c	(revision 457)
@@ -0,0 +1,1533 @@
+/*
+ * ipv6cp.c - PPP IPV6 Control Protocol.
+ *
+ * Copyright (c) 1999 Tommi Komulainen.  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. The name(s) of the authors of this software must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission.
+ *
+ * 4. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by Tommi Komulainen
+ *     <Tommi.Komulainen@iki.fi>".
+ *
+ * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO
+ * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
+ * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
+ * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
+ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ */
+
+/*  Original version, based on RFC2023 :
+
+    Copyright (c) 1995, 1996, 1997 Francis.Dupont@inria.fr, INRIA Rocquencourt,
+    Alain.Durand@imag.fr, IMAG,
+    Jean-Luc.Richier@imag.fr, IMAG-LSR.
+
+    Copyright (c) 1998, 1999 Francis.Dupont@inria.fr, GIE DYADE,
+    Alain.Durand@imag.fr, IMAG,
+    Jean-Luc.Richier@imag.fr, IMAG-LSR.
+
+    Ce travail a ﾃｩtﾃｩ fait au sein du GIE DYADE (Groupement d'Intﾃｩrﾃｪt
+    ﾃ営onomique ayant pour membres BULL S.A. et l'INRIA).
+
+    Ce logiciel informatique est disponible aux conditions
+    usuelles dans la recherche, c'est-ﾃ-dire qu'il peut
+    ﾃｪtre utilisﾃｩ, copiﾃｩ, modifiﾃｩ, distribuﾃｩ ﾃ l'unique
+    condition que ce texte soit conservﾃｩ afin que
+    l'origine de ce logiciel soit reconnue.
+
+    Le nom de l'Institut National de Recherche en Informatique
+    et en Automatique (INRIA), de l'IMAG, ou d'une personne morale
+    ou physique ayant participﾃｩ ﾃ l'ﾃｩlaboration de ce logiciel ne peut
+    ﾃｪtre utilisﾃｩ sans son accord prﾃｩalable explicite.
+
+    Ce logiciel est fourni tel quel sans aucune garantie,
+    support ou responsabilitﾃｩ d'aucune sorte.
+    Ce logiciel est dﾃｩrivﾃｩ de sources d'origine
+    "University of California at Berkeley" et
+    "Digital Equipment Corporation" couvertes par des copyrights.
+
+    L'Institut d'Informatique et de Mathﾃｩmatiques Appliquﾃｩes de Grenoble (IMAG)
+    est une fﾃｩdﾃｩration d'unitﾃｩs mixtes de recherche du CNRS, de l'Institut National
+    Polytechnique de Grenoble et de l'Universitﾃｩ Joseph Fourier regroupant
+    sept laboratoires dont le laboratoire Logiciels, Systﾃｨmes, Rﾃｩseaux (LSR).
+
+    This work has been done in the context of GIE DYADE (joint R & D venture
+    between BULL S.A. and INRIA).
+
+    This software is available with usual "research" terms
+    with the aim of retain credits of the software. 
+    Permission to use, copy, modify and distribute this software for any
+    purpose and without fee is hereby granted, provided that the above
+    copyright notice and this permission notice appear in all copies,
+    and the name of INRIA, IMAG, or any contributor not be used in advertising
+    or publicity pertaining to this material without the prior explicit
+    permission. The software is provided "as is" without any
+    warranties, support or liabilities of any kind.
+    This software is derived from source code from
+    "University of California at Berkeley" and
+    "Digital Equipment Corporation" protected by copyrights.
+
+    Grenoble's Institute of Computer Science and Applied Mathematics (IMAG)
+    is a federation of seven research units funded by the CNRS, National
+    Polytechnic Institute of Grenoble and University Joseph Fourier.
+    The research unit in Software, Systems, Networks (LSR) is member of IMAG.
+*/
+
+/*
+ * Derived from :
+ *
+ *
+ * ipcp.c - PPP IP Control Protocol.
+ *
+ * Copyright (c) 1984-2000 Carnegie Mellon University. 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. The name "Carnegie Mellon University" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For permission or any legal
+ *    details, please contact
+ *      Office of Technology Transfer
+ *      Carnegie Mellon University
+ *      5000 Forbes Avenue
+ *      Pittsburgh, PA  15213-3890
+ *      (412) 268-4387, fax: (412) 268-7395
+ *      tech-transfer@andrew.cmu.edu
+ *
+ * 4. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by Computing Services
+ *     at Carnegie Mellon University (http://www.cmu.edu/computing/)."
+ *
+ * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO
+ * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE
+ * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
+ * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
+ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * $Id$ 
+ */
+
+/*
+ * @todo: 
+ *
+ * Proxy Neighbour Discovery.
+ *
+ * Better defines for selecting the ordering of
+ *   interface up / set address.
+ */
+
+#include "netif/ppp/ppp_opts.h"
+#if PPP_SUPPORT && PPP_IPV6_SUPPORT  /* don't build if not configured for use in lwipopts.h */
+
+#if 0 /* UNUSED */
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#include <netdb.h>
+#include <sys/param.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#endif /* UNUSED */
+
+#include "netif/ppp/ppp_impl.h"
+#include "netif/ppp/fsm.h"
+#include "netif/ppp/ipcp.h"
+#include "netif/ppp/ipv6cp.h"
+#include "netif/ppp/magic.h"
+
+/* global vars */
+#if 0 /* UNUSED */
+int no_ifaceid_neg = 0;
+#endif /* UNUSED */
+
+/*
+ * Callbacks for fsm code.  (CI = Configuration Information)
+ */
+static void ipv6cp_resetci(fsm *f); /* Reset our CI */
+static int  ipv6cp_cilen(fsm *f); /* Return length of our CI */
+static void ipv6cp_addci(fsm *f, u_char *ucp, int *lenp); /* Add our CI */
+static int  ipv6cp_ackci(fsm *f, u_char *p, int len); /* Peer ack'd our CI */
+static int  ipv6cp_nakci(fsm *f, u_char *p, int len, int treat_as_reject); /* Peer nak'd our CI */
+static int  ipv6cp_rejci(fsm *f, u_char *p, int len); /* Peer rej'd our CI */
+static int  ipv6cp_reqci(fsm *f, u_char *inp, int *len, int reject_if_disagree); /* Rcv CI */
+static void ipv6cp_up(fsm *f); /* We're UP */
+static void ipv6cp_down(fsm *f); /* We're DOWN */
+static void ipv6cp_finished(fsm *f); /* Don't need lower layer */
+
+static const fsm_callbacks ipv6cp_callbacks = { /* IPV6CP callback routines */
+    ipv6cp_resetci,		/* Reset our Configuration Information */
+    ipv6cp_cilen,		/* Length of our Configuration Information */
+    ipv6cp_addci,		/* Add our Configuration Information */
+    ipv6cp_ackci,		/* ACK our Configuration Information */
+    ipv6cp_nakci,		/* NAK our Configuration Information */
+    ipv6cp_rejci,		/* Reject our Configuration Information */
+    ipv6cp_reqci,		/* Request peer's Configuration Information */
+    ipv6cp_up,			/* Called when fsm reaches OPENED state */
+    ipv6cp_down,		/* Called when fsm leaves OPENED state */
+    NULL,			/* Called when we want the lower layer up */
+    ipv6cp_finished,		/* Called when we want the lower layer down */
+    NULL,			/* Called when Protocol-Reject received */
+    NULL,			/* Retransmission is necessary */
+    NULL,			/* Called to handle protocol-specific codes */
+    "IPV6CP"			/* String name of protocol */
+};
+
+#if PPP_OPTIONS
+/*
+ * Command-line options.
+ */
+static int setifaceid(char **arg));
+static void printifaceid(option_t *,
+			      void (*)(void *, char *, ...), void *));
+
+static option_t ipv6cp_option_list[] = {
+    { "ipv6", o_special, (void *)setifaceid,
+      "Set interface identifiers for IPV6",
+      OPT_A2PRINTER, (void *)printifaceid },
+
+    { "+ipv6", o_bool, &ipv6cp_protent.enabled_flag,
+      "Enable IPv6 and IPv6CP", OPT_PRIO | 1 },
+    { "noipv6", o_bool, &ipv6cp_protent.enabled_flag,
+      "Disable IPv6 and IPv6CP", OPT_PRIOSUB },
+    { "-ipv6", o_bool, &ipv6cp_protent.enabled_flag,
+      "Disable IPv6 and IPv6CP", OPT_PRIOSUB | OPT_ALIAS },
+
+    { "ipv6cp-accept-local", o_bool, &ipv6cp_allowoptions[0].accept_local,
+      "Accept peer's interface identifier for us", 1 },
+
+    { "ipv6cp-use-ipaddr", o_bool, &ipv6cp_allowoptions[0].use_ip,
+      "Use (default) IPv4 address as interface identifier", 1 },
+
+    { "ipv6cp-use-persistent", o_bool, &ipv6cp_wantoptions[0].use_persistent,
+      "Use uniquely-available persistent value for link local address", 1 },
+
+    { "ipv6cp-restart", o_int, &ipv6cp_fsm[0].timeouttime,
+      "Set timeout for IPv6CP", OPT_PRIO },
+    { "ipv6cp-max-terminate", o_int, &ipv6cp_fsm[0].maxtermtransmits,
+      "Set max #xmits for term-reqs", OPT_PRIO },
+    { "ipv6cp-max-configure", o_int, &ipv6cp_fsm[0].maxconfreqtransmits,
+      "Set max #xmits for conf-reqs", OPT_PRIO },
+    { "ipv6cp-max-failure", o_int, &ipv6cp_fsm[0].maxnakloops,
+      "Set max #conf-naks for IPv6CP", OPT_PRIO },
+
+   { NULL }
+};
+#endif /* PPP_OPTIONS */
+
+/*
+ * Protocol entry points from main code.
+ */
+static void ipv6cp_init(ppp_pcb *pcb);
+static void ipv6cp_open(ppp_pcb *pcb);
+static void ipv6cp_close(ppp_pcb *pcb, const char *reason);
+static void ipv6cp_lowerup(ppp_pcb *pcb);
+static void ipv6cp_lowerdown(ppp_pcb *pcb);
+static void ipv6cp_input(ppp_pcb *pcb, u_char *p, int len);
+static void ipv6cp_protrej(ppp_pcb *pcb);
+#if PPP_OPTIONS
+static void ipv6_check_options(void);
+#endif /* PPP_OPTIONS */
+#if DEMAND_SUPPORT
+static int  ipv6_demand_conf(int u);
+#endif /* DEMAND_SUPPORT */
+#if PRINTPKT_SUPPORT
+static int ipv6cp_printpkt(const u_char *p, int plen,
+		void (*printer)(void *, const char *, ...), void *arg);
+#endif /* PRINTPKT_SUPPORT */
+#if DEMAND_SUPPORT
+static int ipv6_active_pkt(u_char *pkt, int len);
+#endif /* DEMAND_SUPPORT */
+
+const struct protent ipv6cp_protent = {
+    PPP_IPV6CP,
+    ipv6cp_init,
+    ipv6cp_input,
+    ipv6cp_protrej,
+    ipv6cp_lowerup,
+    ipv6cp_lowerdown,
+    ipv6cp_open,
+    ipv6cp_close,
+#if PRINTPKT_SUPPORT
+    ipv6cp_printpkt,
+#endif /* PRINTPKT_SUPPORT */
+#if PPP_DATAINPUT
+    NULL,
+#endif /* PPP_DATAINPUT */
+#if PRINTPKT_SUPPORT
+    "IPV6CP",
+    "IPV6",
+#endif /* PRINTPKT_SUPPORT */
+#if PPP_OPTIONS
+    ipv6cp_option_list,
+    ipv6_check_options,
+#endif /* PPP_OPTIONS */
+#if DEMAND_SUPPORT
+    ipv6_demand_conf,
+    ipv6_active_pkt
+#endif /* DEMAND_SUPPORT */
+};
+
+static void ipv6cp_clear_addrs(ppp_pcb *pcb, eui64_t ourid, eui64_t hisid);
+#if 0 /* UNUSED */
+static void ipv6cp_script(char *));
+static void ipv6cp_script_done(void *));
+#endif /* UNUSED */
+
+/*
+ * Lengths of configuration options.
+ */
+#define CILEN_VOID	2
+#define CILEN_COMPRESS	4	/* length for RFC2023 compress opt. */
+#define CILEN_IFACEID   10	/* RFC2472, interface identifier    */
+
+#define CODENAME(x)	((x) == CONFACK ? "ACK" : \
+			 (x) == CONFNAK ? "NAK" : "REJ")
+
+#if 0 /* UNUSED */
+/*
+ * This state variable is used to ensure that we don't
+ * run an ipcp-up/down script while one is already running.
+ */
+static enum script_state {
+    s_down,
+    s_up,
+} ipv6cp_script_state;
+static pid_t ipv6cp_script_pid;
+#endif /* UNUSED */
+
+static char *llv6_ntoa(eui64_t ifaceid);
+
+#if PPP_OPTIONS
+/*
+ * setifaceid - set the interface identifiers manually
+ */
+static int
+setifaceid(argv)
+    char **argv;
+{
+    char *comma, *arg, c;
+    ipv6cp_options *wo = &ipv6cp_wantoptions[0];
+    struct in6_addr addr;
+    static int prio_local, prio_remote;
+
+#define VALIDID(a) ( (((a).s6_addr32[0] == 0) && ((a).s6_addr32[1] == 0)) && \
+			(((a).s6_addr32[2] != 0) || ((a).s6_addr32[3] != 0)) )
+    
+    arg = *argv;
+    if ((comma = strchr(arg, ',')) == NULL)
+	comma = arg + strlen(arg);
+    
+    /* 
+     * If comma first character, then no local identifier
+     */
+    if (comma != arg) {
+	c = *comma;
+	*comma = '\0';
+
+	if (inet_pton(AF_INET6, arg, &addr) == 0 || !VALIDID(addr)) {
+	    option_error("Illegal interface identifier (local): %s", arg);
+	    return 0;
+	}
+
+	if (option_priority >= prio_local) {
+	    eui64_copy(addr.s6_addr32[2], wo->ourid);
+	    wo->opt_local = 1;
+	    prio_local = option_priority;
+	}
+	*comma = c;
+    }
+    
+    /*
+     * If comma last character, the no remote identifier
+     */
+    if (*comma != 0 && *++comma != '\0') {
+	if (inet_pton(AF_INET6, comma, &addr) == 0 || !VALIDID(addr)) {
+	    option_error("Illegal interface identifier (remote): %s", comma);
+	    return 0;
+	}
+	if (option_priority >= prio_remote) {
+	    eui64_copy(addr.s6_addr32[2], wo->hisid);
+	    wo->opt_remote = 1;
+	    prio_remote = option_priority;
+	}
+    }
+
+    if (override_value("+ipv6", option_priority, option_source))
+	ipv6cp_protent.enabled_flag = 1;
+    return 1;
+}
+
+static void
+printifaceid(opt, printer, arg)
+    option_t *opt;
+    void (*printer)(void *, char *, ...));
+    void *arg;
+{
+	ipv6cp_options *wo = &ipv6cp_wantoptions[0];
+
+	if (wo->opt_local)
+		printer(arg, "%s", llv6_ntoa(wo->ourid));
+	printer(arg, ",");
+	if (wo->opt_remote)
+		printer(arg, "%s", llv6_ntoa(wo->hisid));
+}
+#endif /* PPP_OPTIONS */
+
+/*
+ * Make a string representation of a network address.
+ */
+static char *
+llv6_ntoa(eui64_t ifaceid)
+{
+    static char b[26];
+
+    sprintf(b, "fe80::%02x%02x:%02x%02x:%02x%02x:%02x%02x",
+      ifaceid.e8[0], ifaceid.e8[1], ifaceid.e8[2], ifaceid.e8[3],
+      ifaceid.e8[4], ifaceid.e8[5], ifaceid.e8[6], ifaceid.e8[7]);
+
+    return b;
+}
+
+
+/*
+ * ipv6cp_init - Initialize IPV6CP.
+ */
+static void ipv6cp_init(ppp_pcb *pcb) {
+    fsm *f = &pcb->ipv6cp_fsm;
+    ipv6cp_options *wo = &pcb->ipv6cp_wantoptions;
+    ipv6cp_options *ao = &pcb->ipv6cp_allowoptions;
+
+    f->pcb = pcb;
+    f->protocol = PPP_IPV6CP;
+    f->callbacks = &ipv6cp_callbacks;
+    fsm_init(f);
+
+#if 0 /* Not necessary, everything is cleared in ppp_new() */
+    memset(wo, 0, sizeof(*wo));
+    memset(ao, 0, sizeof(*ao));
+#endif /* 0 */
+
+    wo->accept_local = 1;
+    wo->neg_ifaceid = 1;
+    ao->neg_ifaceid = 1;
+
+#ifdef IPV6CP_COMP
+    wo->neg_vj = 1;
+    ao->neg_vj = 1;
+    wo->vj_protocol = IPV6CP_COMP;
+#endif
+
+}
+
+
+/*
+ * ipv6cp_open - IPV6CP is allowed to come up.
+ */
+static void ipv6cp_open(ppp_pcb *pcb) {
+    fsm_open(&pcb->ipv6cp_fsm);
+}
+
+
+/*
+ * ipv6cp_close - Take IPV6CP down.
+ */
+static void ipv6cp_close(ppp_pcb *pcb, const char *reason) {
+    fsm_close(&pcb->ipv6cp_fsm, reason);
+}
+
+
+/*
+ * ipv6cp_lowerup - The lower layer is up.
+ */
+static void ipv6cp_lowerup(ppp_pcb *pcb) {
+    fsm_lowerup(&pcb->ipv6cp_fsm);
+}
+
+
+/*
+ * ipv6cp_lowerdown - The lower layer is down.
+ */
+static void ipv6cp_lowerdown(ppp_pcb *pcb) {
+    fsm_lowerdown(&pcb->ipv6cp_fsm);
+}
+
+
+/*
+ * ipv6cp_input - Input IPV6CP packet.
+ */
+static void ipv6cp_input(ppp_pcb *pcb, u_char *p, int len) {
+    fsm_input(&pcb->ipv6cp_fsm, p, len);
+}
+
+
+/*
+ * ipv6cp_protrej - A Protocol-Reject was received for IPV6CP.
+ *
+ * Pretend the lower layer went down, so we shut up.
+ */
+static void ipv6cp_protrej(ppp_pcb *pcb) {
+    fsm_lowerdown(&pcb->ipv6cp_fsm);
+}
+
+
+/*
+ * ipv6cp_resetci - Reset our CI.
+ */
+static void ipv6cp_resetci(fsm *f) {
+    ppp_pcb *pcb = f->pcb;
+    ipv6cp_options *wo = &pcb->ipv6cp_wantoptions;
+    ipv6cp_options *go = &pcb->ipv6cp_gotoptions;
+    ipv6cp_options *ao = &pcb->ipv6cp_allowoptions;
+
+    wo->req_ifaceid = wo->neg_ifaceid && ao->neg_ifaceid;
+    
+    if (!wo->opt_local) {
+	eui64_magic_nz(wo->ourid);
+    }
+    
+    *go = *wo;
+    eui64_zero(go->hisid);	/* last proposed interface identifier */
+}
+
+
+/*
+ * ipv6cp_cilen - Return length of our CI.
+ */
+static int ipv6cp_cilen(fsm *f) {
+    ppp_pcb *pcb = f->pcb;
+    ipv6cp_options *go = &pcb->ipv6cp_gotoptions;
+
+#ifdef IPV6CP_COMP
+#define LENCIVJ(neg)		(neg ? CILEN_COMPRESS : 0)
+#endif /* IPV6CP_COMP */
+#define LENCIIFACEID(neg)	(neg ? CILEN_IFACEID : 0)
+
+    return (LENCIIFACEID(go->neg_ifaceid) +
+#ifdef IPV6CP_COMP
+	    LENCIVJ(go->neg_vj) +
+#endif /* IPV6CP_COMP */
+	    0);
+}
+
+
+/*
+ * ipv6cp_addci - Add our desired CIs to a packet.
+ */
+static void ipv6cp_addci(fsm *f, u_char *ucp, int *lenp) {
+    ppp_pcb *pcb = f->pcb;
+    ipv6cp_options *go = &pcb->ipv6cp_gotoptions;
+    int len = *lenp;
+
+#ifdef IPV6CP_COMP
+#define ADDCIVJ(opt, neg, val) \
+    if (neg) { \
+	int vjlen = CILEN_COMPRESS; \
+	if (len >= vjlen) { \
+	    PUTCHAR(opt, ucp); \
+	    PUTCHAR(vjlen, ucp); \
+	    PUTSHORT(val, ucp); \
+	    len -= vjlen; \
+	} else \
+	    neg = 0; \
+    }
+#endif /* IPV6CP_COMP */
+
+#define ADDCIIFACEID(opt, neg, val1) \
+    if (neg) { \
+	int idlen = CILEN_IFACEID; \
+	if (len >= idlen) { \
+	    PUTCHAR(opt, ucp); \
+	    PUTCHAR(idlen, ucp); \
+	    eui64_put(val1, ucp); \
+	    len -= idlen; \
+	} else \
+	    neg = 0; \
+    }
+
+    ADDCIIFACEID(CI_IFACEID, go->neg_ifaceid, go->ourid);
+
+#ifdef IPV6CP_COMP
+    ADDCIVJ(CI_COMPRESSTYPE, go->neg_vj, go->vj_protocol);
+#endif /* IPV6CP_COMP */
+
+    *lenp -= len;
+}
+
+
+/*
+ * ipv6cp_ackci - Ack our CIs.
+ *
+ * Returns:
+ *	0 - Ack was bad.
+ *	1 - Ack was good.
+ */
+static int ipv6cp_ackci(fsm *f, u_char *p, int len) {
+    ppp_pcb *pcb = f->pcb;
+    ipv6cp_options *go = &pcb->ipv6cp_gotoptions;
+    u_short cilen, citype;
+#ifdef IPV6CP_COMP
+    u_short cishort;
+#endif /* IPV6CP_COMP */
+    eui64_t ifaceid;
+
+    /*
+     * CIs must be in exactly the same order that we sent...
+     * Check packet length and CI length at each step.
+     * If we find any deviations, then this packet is bad.
+     */
+
+#ifdef IPV6CP_COMP
+#define ACKCIVJ(opt, neg, val) \
+    if (neg) { \
+	int vjlen = CILEN_COMPRESS; \
+	if ((len -= vjlen) < 0) \
+	    goto bad; \
+	GETCHAR(citype, p); \
+	GETCHAR(cilen, p); \
+	if (cilen != vjlen || \
+	    citype != opt)  \
+	    goto bad; \
+	GETSHORT(cishort, p); \
+	if (cishort != val) \
+	    goto bad; \
+    }
+#endif /* IPV6CP_COMP */
+
+#define ACKCIIFACEID(opt, neg, val1) \
+    if (neg) { \
+	int idlen = CILEN_IFACEID; \
+	if ((len -= idlen) < 0) \
+	    goto bad; \
+	GETCHAR(citype, p); \
+	GETCHAR(cilen, p); \
+	if (cilen != idlen || \
+	    citype != opt) \
+	    goto bad; \
+	eui64_get(ifaceid, p); \
+	if (! eui64_equals(val1, ifaceid)) \
+	    goto bad; \
+    }
+
+    ACKCIIFACEID(CI_IFACEID, go->neg_ifaceid, go->ourid);
+
+#ifdef IPV6CP_COMP
+    ACKCIVJ(CI_COMPRESSTYPE, go->neg_vj, go->vj_protocol);
+#endif /* IPV6CP_COMP */
+
+    /*
+     * If there are any remaining CIs, then this packet is bad.
+     */
+    if (len != 0)
+	goto bad;
+    return (1);
+
+bad:
+    IPV6CPDEBUG(("ipv6cp_ackci: received bad Ack!"));
+    return (0);
+}
+
+/*
+ * ipv6cp_nakci - Peer has sent a NAK for some of our CIs.
+ * This should not modify any state if the Nak is bad
+ * or if IPV6CP is in the OPENED state.
+ *
+ * Returns:
+ *	0 - Nak was bad.
+ *	1 - Nak was good.
+ */
+static int ipv6cp_nakci(fsm *f, u_char *p, int len, int treat_as_reject) {
+    ppp_pcb *pcb = f->pcb;
+    ipv6cp_options *go = &pcb->ipv6cp_gotoptions;
+    u_char citype, cilen, *next;
+#ifdef IPV6CP_COMP
+    u_short cishort;
+#endif /* IPV6CP_COMP */
+    eui64_t ifaceid;
+    ipv6cp_options no;		/* options we've seen Naks for */
+    ipv6cp_options try_;	/* options to request next time */
+
+    BZERO(&no, sizeof(no));
+    try_ = *go;
+
+    /*
+     * Any Nak'd CIs must be in exactly the same order that we sent.
+     * Check packet length and CI length at each step.
+     * If we find any deviations, then this packet is bad.
+     */
+#define NAKCIIFACEID(opt, neg, code) \
+    if (go->neg && \
+	len >= (cilen = CILEN_IFACEID) && \
+	p[1] == cilen && \
+	p[0] == opt) { \
+	len -= cilen; \
+	INCPTR(2, p); \
+	eui64_get(ifaceid, p); \
+	no.neg = 1; \
+	code \
+    }
+
+#ifdef IPV6CP_COMP
+#define NAKCIVJ(opt, neg, code) \
+    if (go->neg && \
+	((cilen = p[1]) == CILEN_COMPRESS) && \
+	len >= cilen && \
+	p[0] == opt) { \
+	len -= cilen; \
+	INCPTR(2, p); \
+	GETSHORT(cishort, p); \
+	no.neg = 1; \
+        code \
+    }
+#endif /* IPV6CP_COMP */
+
+    /*
+     * Accept the peer's idea of {our,his} interface identifier, if different
+     * from our idea, only if the accept_{local,remote} flag is set.
+     */
+    NAKCIIFACEID(CI_IFACEID, neg_ifaceid,
+		 if (treat_as_reject) {
+		     try_.neg_ifaceid = 0;
+		 } else if (go->accept_local) {
+		     while (eui64_iszero(ifaceid) || 
+			    eui64_equals(ifaceid, go->hisid)) /* bad luck */
+			 eui64_magic(ifaceid);
+		     try_.ourid = ifaceid;
+		     IPV6CPDEBUG(("local LL address %s", llv6_ntoa(ifaceid)));
+		 }
+		 );
+
+#ifdef IPV6CP_COMP
+    NAKCIVJ(CI_COMPRESSTYPE, neg_vj,
+	    {
+		if (cishort == IPV6CP_COMP && !treat_as_reject) {
+		    try_.vj_protocol = cishort;
+		} else {
+		    try_.neg_vj = 0;
+		}
+	    }
+	    );
+#endif /* IPV6CP_COMP */
+
+    /*
+     * There may be remaining CIs, if the peer is requesting negotiation
+     * on an option that we didn't include in our request packet.
+     * If they want to negotiate about interface identifier, we comply.
+     * If they want us to ask for compression, we refuse.
+     */
+    while (len >= CILEN_VOID) {
+	GETCHAR(citype, p);
+	GETCHAR(cilen, p);
+	if ( cilen < CILEN_VOID || (len -= cilen) < 0 )
+	    goto bad;
+	next = p + cilen - 2;
+
+	switch (citype) {
+#ifdef IPV6CP_COMP
+	case CI_COMPRESSTYPE:
+	    if (go->neg_vj || no.neg_vj ||
+		(cilen != CILEN_COMPRESS))
+		goto bad;
+	    no.neg_vj = 1;
+	    break;
+#endif /* IPV6CP_COMP */
+	case CI_IFACEID:
+	    if (go->neg_ifaceid || no.neg_ifaceid || cilen != CILEN_IFACEID)
+		goto bad;
+	    try_.neg_ifaceid = 1;
+	    eui64_get(ifaceid, p);
+	    if (go->accept_local) {
+		while (eui64_iszero(ifaceid) || 
+		       eui64_equals(ifaceid, go->hisid)) /* bad luck */
+		    eui64_magic(ifaceid);
+		try_.ourid = ifaceid;
+	    }
+	    no.neg_ifaceid = 1;
+	    break;
+	default:
+	    break;
+	}
+	p = next;
+    }
+
+    /* If there is still anything left, this packet is bad. */
+    if (len != 0)
+	goto bad;
+
+    /*
+     * OK, the Nak is good.  Now we can update state.
+     */
+    if (f->state != PPP_FSM_OPENED)
+	*go = try_;
+
+    return 1;
+
+bad:
+    IPV6CPDEBUG(("ipv6cp_nakci: received bad Nak!"));
+    return 0;
+}
+
+
+/*
+ * ipv6cp_rejci - Reject some of our CIs.
+ */
+static int ipv6cp_rejci(fsm *f, u_char *p, int len) {
+    ppp_pcb *pcb = f->pcb;
+    ipv6cp_options *go = &pcb->ipv6cp_gotoptions;
+    u_char cilen;
+#ifdef IPV6CP_COMP
+    u_short cishort;
+#endif /* IPV6CP_COMP */
+    eui64_t ifaceid;
+    ipv6cp_options try_;		/* options to request next time */
+
+    try_ = *go;
+    /*
+     * Any Rejected CIs must be in exactly the same order that we sent.
+     * Check packet length and CI length at each step.
+     * If we find any deviations, then this packet is bad.
+     */
+#define REJCIIFACEID(opt, neg, val1) \
+    if (go->neg && \
+	len >= (cilen = CILEN_IFACEID) && \
+	p[1] == cilen && \
+	p[0] == opt) { \
+	len -= cilen; \
+	INCPTR(2, p); \
+	eui64_get(ifaceid, p); \
+	/* Check rejected value. */ \
+	if (! eui64_equals(ifaceid, val1)) \
+	    goto bad; \
+	try_.neg = 0; \
+    }
+
+#ifdef IPV6CP_COMP
+#define REJCIVJ(opt, neg, val) \
+    if (go->neg && \
+	p[1] == CILEN_COMPRESS && \
+	len >= p[1] && \
+	p[0] == opt) { \
+	len -= p[1]; \
+	INCPTR(2, p); \
+	GETSHORT(cishort, p); \
+	/* Check rejected value. */  \
+	if (cishort != val) \
+	    goto bad; \
+	try_.neg = 0; \
+     }
+#endif /* IPV6CP_COMP */
+
+    REJCIIFACEID(CI_IFACEID, neg_ifaceid, go->ourid);
+
+#ifdef IPV6CP_COMP
+    REJCIVJ(CI_COMPRESSTYPE, neg_vj, go->vj_protocol);
+#endif /* IPV6CP_COMP */
+
+    /*
+     * If there are any remaining CIs, then this packet is bad.
+     */
+    if (len != 0)
+	goto bad;
+    /*
+     * Now we can update state.
+     */
+    if (f->state != PPP_FSM_OPENED)
+	*go = try_;
+    return 1;
+
+bad:
+    IPV6CPDEBUG(("ipv6cp_rejci: received bad Reject!"));
+    return 0;
+}
+
+
+/*
+ * ipv6cp_reqci - Check the peer's requested CIs and send appropriate response.
+ *
+ * Returns: CONFACK, CONFNAK or CONFREJ and input packet modified
+ * appropriately.  If reject_if_disagree is non-zero, doesn't return
+ * CONFNAK; returns CONFREJ if it can't return CONFACK.
+ *
+ * inp = Requested CIs
+ * len = Length of requested CIs
+ *
+ */
+static int ipv6cp_reqci(fsm *f, u_char *inp, int *len, int reject_if_disagree) {
+    ppp_pcb *pcb = f->pcb;
+    ipv6cp_options *wo = &pcb->ipv6cp_wantoptions;
+    ipv6cp_options *ho = &pcb->ipv6cp_hisoptions;
+    ipv6cp_options *ao = &pcb->ipv6cp_allowoptions;
+    ipv6cp_options *go = &pcb->ipv6cp_gotoptions;
+    u_char *cip, *next;		/* Pointer to current and next CIs */
+    u_short cilen, citype;	/* Parsed len, type */
+#ifdef IPV6CP_COMP
+    u_short cishort;		/* Parsed short value */
+#endif /* IPV6CP_COMP */
+    eui64_t ifaceid;		/* Parsed interface identifier */
+    int rc = CONFACK;		/* Final packet return code */
+    int orc;			/* Individual option return code */
+    u_char *p;			/* Pointer to next char to parse */
+    u_char *ucp = inp;		/* Pointer to current output char */
+    int l = *len;		/* Length left */
+
+    /*
+     * Reset all his options.
+     */
+    BZERO(ho, sizeof(*ho));
+    
+    /*
+     * Process all his options.
+     */
+    next = inp;
+    while (l) {
+	orc = CONFACK;			/* Assume success */
+	cip = p = next;			/* Remember begining of CI */
+	if (l < 2 ||			/* Not enough data for CI header or */
+	    p[1] < 2 ||			/*  CI length too small or */
+	    p[1] > l) {			/*  CI length too big? */
+	    IPV6CPDEBUG(("ipv6cp_reqci: bad CI length!"));
+	    orc = CONFREJ;		/* Reject bad CI */
+	    cilen = l;			/* Reject till end of packet */
+	    l = 0;			/* Don't loop again */
+	    goto endswitch;
+	}
+	GETCHAR(citype, p);		/* Parse CI type */
+	GETCHAR(cilen, p);		/* Parse CI length */
+	l -= cilen;			/* Adjust remaining length */
+	next += cilen;			/* Step to next CI */
+
+	switch (citype) {		/* Check CI type */
+	case CI_IFACEID:
+	    IPV6CPDEBUG(("ipv6cp: received interface identifier "));
+
+	    if (!ao->neg_ifaceid ||
+		cilen != CILEN_IFACEID) {	/* Check CI length */
+		orc = CONFREJ;		/* Reject CI */
+		break;
+	    }
+
+	    /*
+	     * If he has no interface identifier, or if we both have same 
+	     * identifier then NAK it with new idea.
+	     * In particular, if we don't know his identifier, but he does,
+	     * then accept it.
+	     */
+	    eui64_get(ifaceid, p);
+	    IPV6CPDEBUG(("(%s)", llv6_ntoa(ifaceid)));
+	    if (eui64_iszero(ifaceid) && eui64_iszero(go->ourid)) {
+		orc = CONFREJ;		/* Reject CI */
+		break;
+	    }
+	    if (!eui64_iszero(wo->hisid) && 
+		!eui64_equals(ifaceid, wo->hisid) && 
+		eui64_iszero(go->hisid)) {
+		    
+		orc = CONFNAK;
+		ifaceid = wo->hisid;
+		go->hisid = ifaceid;
+		DECPTR(sizeof(ifaceid), p);
+		eui64_put(ifaceid, p);
+	    } else
+	    if (eui64_iszero(ifaceid) || eui64_equals(ifaceid, go->ourid)) {
+		orc = CONFNAK;
+		if (eui64_iszero(go->hisid))	/* first time, try option */
+		    ifaceid = wo->hisid;
+		while (eui64_iszero(ifaceid) || 
+		       eui64_equals(ifaceid, go->ourid)) /* bad luck */
+		    eui64_magic(ifaceid);
+		go->hisid = ifaceid;
+		DECPTR(sizeof(ifaceid), p);
+		eui64_put(ifaceid, p);
+	    }
+
+	    ho->neg_ifaceid = 1;
+	    ho->hisid = ifaceid;
+	    break;
+
+#ifdef IPV6CP_COMP
+	case CI_COMPRESSTYPE:
+	    IPV6CPDEBUG(("ipv6cp: received COMPRESSTYPE "));
+	    if (!ao->neg_vj ||
+		(cilen != CILEN_COMPRESS)) {
+		orc = CONFREJ;
+		break;
+	    }
+	    GETSHORT(cishort, p);
+	    IPV6CPDEBUG(("(%d)", cishort));
+
+	    if (!(cishort == IPV6CP_COMP)) {
+		orc = CONFREJ;
+		break;
+	    }
+
+	    ho->neg_vj = 1;
+	    ho->vj_protocol = cishort;
+	    break;
+#endif /* IPV6CP_COMP */
+
+	default:
+	    orc = CONFREJ;
+	    break;
+	}
+
+endswitch:
+	IPV6CPDEBUG((" (%s)\n", CODENAME(orc)));
+
+	if (orc == CONFACK &&		/* Good CI */
+	    rc != CONFACK)		/*  but prior CI wasnt? */
+	    continue;			/* Don't send this one */
+
+	if (orc == CONFNAK) {		/* Nak this CI? */
+	    if (reject_if_disagree)	/* Getting fed up with sending NAKs? */
+		orc = CONFREJ;		/* Get tough if so */
+	    else {
+		if (rc == CONFREJ)	/* Rejecting prior CI? */
+		    continue;		/* Don't send this one */
+		if (rc == CONFACK) {	/* Ack'd all prior CIs? */
+		    rc = CONFNAK;	/* Not anymore... */
+		    ucp = inp;		/* Backup */
+		}
+	    }
+	}
+
+	if (orc == CONFREJ &&		/* Reject this CI */
+	    rc != CONFREJ) {		/*  but no prior ones? */
+	    rc = CONFREJ;
+	    ucp = inp;			/* Backup */
+	}
+
+	/* Need to move CI? */
+	if (ucp != cip)
+	    MEMCPY(ucp, cip, cilen);	/* Move it */
+
+	/* Update output pointer */
+	INCPTR(cilen, ucp);
+    }
+
+    /*
+     * If we aren't rejecting this packet, and we want to negotiate
+     * their identifier and they didn't send their identifier, then we
+     * send a NAK with a CI_IFACEID option appended.  We assume the
+     * input buffer is long enough that we can append the extra
+     * option safely.
+     */
+    if (rc != CONFREJ && !ho->neg_ifaceid &&
+	wo->req_ifaceid && !reject_if_disagree) {
+	if (rc == CONFACK) {
+	    rc = CONFNAK;
+	    ucp = inp;				/* reset pointer */
+	    wo->req_ifaceid = 0;		/* don't ask again */
+	}
+	PUTCHAR(CI_IFACEID, ucp);
+	PUTCHAR(CILEN_IFACEID, ucp);
+	eui64_put(wo->hisid, ucp);
+    }
+
+    *len = ucp - inp;			/* Compute output length */
+    IPV6CPDEBUG(("ipv6cp: returning Configure-%s", CODENAME(rc)));
+    return (rc);			/* Return final code */
+}
+
+#if PPP_OPTIONS
+/*
+ * ipv6_check_options - check that any IP-related options are OK,
+ * and assign appropriate defaults.
+ */
+static void ipv6_check_options() {
+    ipv6cp_options *wo = &ipv6cp_wantoptions[0];
+
+    if (!ipv6cp_protent.enabled_flag)
+	return;
+
+    /*
+     * Persistent link-local id is only used when user has not explicitly
+     * configure/hard-code the id
+     */
+    if ((wo->use_persistent) && (!wo->opt_local) && (!wo->opt_remote)) {
+
+	/* 
+	 * On systems where there are no Ethernet interfaces used, there
+	 * may be other ways to obtain a persistent id. Right now, it
+	 * will fall back to using magic [see eui64_magic] below when
+	 * an EUI-48 from MAC address can't be obtained. Other possibilities
+	 * include obtaining EEPROM serial numbers, or some other unique
+	 * yet persistent number. On Sparc platforms, this is possible,
+	 * but too bad there's no standards yet for x86 machines.
+	 */
+	if (ether_to_eui64(&wo->ourid)) {
+	    wo->opt_local = 1;
+	}
+    }
+
+    if (!wo->opt_local) {	/* init interface identifier */
+	if (wo->use_ip && eui64_iszero(wo->ourid)) {
+	    eui64_setlo32(wo->ourid, lwip_ntohl(ipcp_wantoptions[0].ouraddr));
+	    if (!eui64_iszero(wo->ourid))
+		wo->opt_local = 1;
+	}
+	
+	while (eui64_iszero(wo->ourid))
+	    eui64_magic(wo->ourid);
+    }
+
+    if (!wo->opt_remote) {
+	if (wo->use_ip && eui64_iszero(wo->hisid)) {
+	    eui64_setlo32(wo->hisid, lwip_ntohl(ipcp_wantoptions[0].hisaddr));
+	    if (!eui64_iszero(wo->hisid))
+		wo->opt_remote = 1;
+	}
+    }
+
+    if (demand && (eui64_iszero(wo->ourid) || eui64_iszero(wo->hisid))) {
+	option_error("local/remote LL address required for demand-dialling\n");
+	exit(1);
+    }
+}
+#endif /* PPP_OPTIONS */
+
+#if DEMAND_SUPPORT
+/*
+ * ipv6_demand_conf - configure the interface as though
+ * IPV6CP were up, for use with dial-on-demand.
+ */
+static int ipv6_demand_conf(int u) {
+    ipv6cp_options *wo = &ipv6cp_wantoptions[u];
+
+    if (!sif6up(u))
+	return 0;
+
+    if (!sif6addr(u, wo->ourid, wo->hisid))
+	return 0;
+
+    if (!sifnpmode(u, PPP_IPV6, NPMODE_QUEUE))
+	return 0;
+
+    ppp_notice("ipv6_demand_conf");
+    ppp_notice("local  LL address %s", llv6_ntoa(wo->ourid));
+    ppp_notice("remote LL address %s", llv6_ntoa(wo->hisid));
+
+    return 1;
+}
+#endif /* DEMAND_SUPPORT */
+
+
+/*
+ * ipv6cp_up - IPV6CP has come UP.
+ *
+ * Configure the IPv6 network interface appropriately and bring it up.
+ */
+static void ipv6cp_up(fsm *f) {
+    ppp_pcb *pcb = f->pcb;
+    ipv6cp_options *wo = &pcb->ipv6cp_wantoptions;
+    ipv6cp_options *ho = &pcb->ipv6cp_hisoptions;
+    ipv6cp_options *go = &pcb->ipv6cp_gotoptions;
+
+    IPV6CPDEBUG(("ipv6cp: up"));
+
+    /*
+     * We must have a non-zero LL address for both ends of the link.
+     */
+    if (!ho->neg_ifaceid)
+	ho->hisid = wo->hisid;
+
+#if 0 /* UNUSED */
+    if(!no_ifaceid_neg) {
+#endif /* UNUSED */
+	if (eui64_iszero(ho->hisid)) {
+	    ppp_error("Could not determine remote LL address");
+	    ipv6cp_close(f->pcb, "Could not determine remote LL address");
+	    return;
+	}
+	if (eui64_iszero(go->ourid)) {
+	    ppp_error("Could not determine local LL address");
+	    ipv6cp_close(f->pcb, "Could not determine local LL address");
+	    return;
+	}
+	if (eui64_equals(go->ourid, ho->hisid)) {
+	    ppp_error("local and remote LL addresses are equal");
+	    ipv6cp_close(f->pcb, "local and remote LL addresses are equal");
+	    return;
+	}
+#if 0 /* UNUSED */
+    }
+#endif /* UNUSED */
+#if 0 /* UNUSED */
+    script_setenv("LLLOCAL", llv6_ntoa(go->ourid), 0);
+    script_setenv("LLREMOTE", llv6_ntoa(ho->hisid), 0);
+#endif /* UNUSED */
+
+#ifdef IPV6CP_COMP
+    /* set tcp compression */
+    sif6comp(f->unit, ho->neg_vj);
+#endif
+
+#if DEMAND_SUPPORT
+    /*
+     * If we are doing dial-on-demand, the interface is already
+     * configured, so we put out any saved-up packets, then set the
+     * interface to pass IPv6 packets.
+     */
+    if (demand) {
+	if (! eui64_equals(go->ourid, wo->ourid) || 
+	    ! eui64_equals(ho->hisid, wo->hisid)) {
+	    if (! eui64_equals(go->ourid, wo->ourid))
+		warn("Local LL address changed to %s", 
+		     llv6_ntoa(go->ourid));
+	    if (! eui64_equals(ho->hisid, wo->hisid))
+		warn("Remote LL address changed to %s", 
+		     llv6_ntoa(ho->hisid));
+	    ipv6cp_clear_addrs(f->pcb, go->ourid, ho->hisid);
+
+	    /* Set the interface to the new addresses */
+	    if (!sif6addr(f->pcb, go->ourid, ho->hisid)) {
+		if (debug)
+		    warn("sif6addr failed");
+		ipv6cp_close(f->unit, "Interface configuration failed");
+		return;
+	    }
+
+	}
+	demand_rexmit(PPP_IPV6);
+	sifnpmode(f->unit, PPP_IPV6, NPMODE_PASS);
+
+    } else
+#endif /* DEMAND_SUPPORT */
+    {
+	/*
+	 * Set LL addresses
+	 */
+	if (!sif6addr(f->pcb, go->ourid, ho->hisid)) {
+	    PPPDEBUG(LOG_DEBUG, ("sif6addr failed"));
+	    ipv6cp_close(f->pcb, "Interface configuration failed");
+	    return;
+	}
+
+	/* bring the interface up for IPv6 */
+	if (!sif6up(f->pcb)) {
+	    PPPDEBUG(LOG_DEBUG, ("sif6up failed (IPV6)"));
+	    ipv6cp_close(f->pcb, "Interface configuration failed");
+	    return;
+	}
+#if DEMAND_SUPPORT
+	sifnpmode(f->pcb, PPP_IPV6, NPMODE_PASS);
+#endif /* DEMAND_SUPPORT */
+
+	ppp_notice("local  LL address %s", llv6_ntoa(go->ourid));
+	ppp_notice("remote LL address %s", llv6_ntoa(ho->hisid));
+    }
+
+    np_up(f->pcb, PPP_IPV6);
+    pcb->ipv6cp_is_up = 1;
+
+#if 0 /* UNUSED */
+    /*
+     * Execute the ipv6-up script, like this:
+     *	/etc/ppp/ipv6-up interface tty speed local-LL remote-LL
+     */
+    if (ipv6cp_script_state == s_down && ipv6cp_script_pid == 0) {
+	ipv6cp_script_state = s_up;
+	ipv6cp_script(_PATH_IPV6UP);
+    }
+#endif /* UNUSED */
+}
+
+
+/*
+ * ipv6cp_down - IPV6CP has gone DOWN.
+ *
+ * Take the IPv6 network interface down, clear its addresses
+ * and delete routes through it.
+ */
+static void ipv6cp_down(fsm *f) {
+    ppp_pcb *pcb = f->pcb;
+    ipv6cp_options *go = &pcb->ipv6cp_gotoptions;
+    ipv6cp_options *ho = &pcb->ipv6cp_hisoptions;
+
+    IPV6CPDEBUG(("ipv6cp: down"));
+#if PPP_STATS_SUPPORT
+    update_link_stats(f->unit);
+#endif /* PPP_STATS_SUPPORT */
+    if (pcb->ipv6cp_is_up) {
+	pcb->ipv6cp_is_up = 0;
+	np_down(f->pcb, PPP_IPV6);
+    }
+#ifdef IPV6CP_COMP
+    sif6comp(f->unit, 0);
+#endif
+
+#if DEMAND_SUPPORT
+    /*
+     * If we are doing dial-on-demand, set the interface
+     * to queue up outgoing packets (for now).
+     */
+    if (demand) {
+	sifnpmode(f->pcb, PPP_IPV6, NPMODE_QUEUE);
+    } else
+#endif /* DEMAND_SUPPORT */
+    {
+#if DEMAND_SUPPORT
+	sifnpmode(f->pcb, PPP_IPV6, NPMODE_DROP);
+#endif /* DEMAND_SUPPORT */
+	ipv6cp_clear_addrs(f->pcb,
+			   go->ourid,
+			   ho->hisid);
+	sif6down(f->pcb);
+    }
+
+#if 0 /* UNUSED */
+    /* Execute the ipv6-down script */
+    if (ipv6cp_script_state == s_up && ipv6cp_script_pid == 0) {
+	ipv6cp_script_state = s_down;
+	ipv6cp_script(_PATH_IPV6DOWN);
+    }
+#endif /* UNUSED */
+}
+
+
+/*
+ * ipv6cp_clear_addrs() - clear the interface addresses, routes,
+ * proxy neighbour discovery entries, etc.
+ */
+static void ipv6cp_clear_addrs(ppp_pcb *pcb, eui64_t ourid, eui64_t hisid) {
+    cif6addr(pcb, ourid, hisid);
+}
+
+
+/*
+ * ipv6cp_finished - possibly shut down the lower layers.
+ */
+static void ipv6cp_finished(fsm *f) {
+    np_finished(f->pcb, PPP_IPV6);
+}
+
+
+#if 0 /* UNUSED */
+/*
+ * ipv6cp_script_done - called when the ipv6-up or ipv6-down script
+ * has finished.
+ */
+static void
+ipv6cp_script_done(arg)
+    void *arg;
+{
+    ipv6cp_script_pid = 0;
+    switch (ipv6cp_script_state) {
+    case s_up:
+	if (ipv6cp_fsm[0].state != PPP_FSM_OPENED) {
+	    ipv6cp_script_state = s_down;
+	    ipv6cp_script(_PATH_IPV6DOWN);
+	}
+	break;
+    case s_down:
+	if (ipv6cp_fsm[0].state == PPP_FSM_OPENED) {
+	    ipv6cp_script_state = s_up;
+	    ipv6cp_script(_PATH_IPV6UP);
+	}
+	break;
+    }
+}
+
+
+/*
+ * ipv6cp_script - Execute a script with arguments
+ * interface-name tty-name speed local-LL remote-LL.
+ */
+static void
+ipv6cp_script(script)
+    char *script;
+{
+    char strspeed[32], strlocal[32], strremote[32];
+    char *argv[8];
+
+    sprintf(strspeed, "%d", baud_rate);
+    strcpy(strlocal, llv6_ntoa(ipv6cp_gotoptions[0].ourid));
+    strcpy(strremote, llv6_ntoa(ipv6cp_hisoptions[0].hisid));
+
+    argv[0] = script;
+    argv[1] = ifname;
+    argv[2] = devnam;
+    argv[3] = strspeed;
+    argv[4] = strlocal;
+    argv[5] = strremote;
+    argv[6] = ipparam;
+    argv[7] = NULL;
+
+    ipv6cp_script_pid = run_program(script, argv, 0, ipv6cp_script_done,
+				    NULL, 0);
+}
+#endif /* UNUSED */
+
+#if PRINTPKT_SUPPORT
+/*
+ * ipv6cp_printpkt - print the contents of an IPV6CP packet.
+ */
+static const char* const ipv6cp_codenames[] = {
+    "ConfReq", "ConfAck", "ConfNak", "ConfRej",
+    "TermReq", "TermAck", "CodeRej"
+};
+
+static int ipv6cp_printpkt(const u_char *p, int plen,
+		void (*printer)(void *, const char *, ...), void *arg) {
+    int code, id, len, olen;
+    const u_char *pstart, *optend;
+#ifdef IPV6CP_COMP
+    u_short cishort;
+#endif /* IPV6CP_COMP */
+    eui64_t ifaceid;
+
+    if (plen < HEADERLEN)
+	return 0;
+    pstart = p;
+    GETCHAR(code, p);
+    GETCHAR(id, p);
+    GETSHORT(len, p);
+    if (len < HEADERLEN || len > plen)
+	return 0;
+
+    if (code >= 1 && code <= (int)LWIP_ARRAYSIZE(ipv6cp_codenames))
+	printer(arg, " %s", ipv6cp_codenames[code-1]);
+    else
+	printer(arg, " code=0x%x", code);
+    printer(arg, " id=0x%x", id);
+    len -= HEADERLEN;
+    switch (code) {
+    case CONFREQ:
+    case CONFACK:
+    case CONFNAK:
+    case CONFREJ:
+	/* print option list */
+	while (len >= 2) {
+	    GETCHAR(code, p);
+	    GETCHAR(olen, p);
+	    p -= 2;
+	    if (olen < 2 || olen > len) {
+		break;
+	    }
+	    printer(arg, " <");
+	    len -= olen;
+	    optend = p + olen;
+	    switch (code) {
+#ifdef IPV6CP_COMP
+	    case CI_COMPRESSTYPE:
+		if (olen >= CILEN_COMPRESS) {
+		    p += 2;
+		    GETSHORT(cishort, p);
+		    printer(arg, "compress ");
+		    printer(arg, "0x%x", cishort);
+		}
+		break;
+#endif /* IPV6CP_COMP */
+	    case CI_IFACEID:
+		if (olen == CILEN_IFACEID) {
+		    p += 2;
+		    eui64_get(ifaceid, p);
+		    printer(arg, "addr %s", llv6_ntoa(ifaceid));
+		}
+		break;
+	    default:
+		break;
+	    }
+	    while (p < optend) {
+		GETCHAR(code, p);
+		printer(arg, " %.2x", code);
+	    }
+	    printer(arg, ">");
+	}
+	break;
+
+    case TERMACK:
+    case TERMREQ:
+	if (len > 0 && *p >= ' ' && *p < 0x7f) {
+	    printer(arg, " ");
+	    ppp_print_string(p, len, printer, arg);
+	    p += len;
+	    len = 0;
+	}
+	break;
+    default:
+	break;
+    }
+
+    /* print the rest of the bytes in the packet */
+    for (; len > 0; --len) {
+	GETCHAR(code, p);
+	printer(arg, " %.2x", code);
+    }
+
+    return p - pstart;
+}
+#endif /* PRINTPKT_SUPPORT */
+
+#if DEMAND_SUPPORT
+/*
+ * ipv6_active_pkt - see if this IP packet is worth bringing the link up for.
+ * We don't bring the link up for IP fragments or for TCP FIN packets
+ * with no data.
+ */
+#define IP6_HDRLEN	40	/* bytes */
+#define IP6_NHDR_FRAG	44	/* fragment IPv6 header */
+#define TCP_HDRLEN	20
+#define TH_FIN		0x01
+
+/*
+ * We use these macros because the IP header may be at an odd address,
+ * and some compilers might use word loads to get th_off or ip_hl.
+ */
+
+#define get_ip6nh(x)	(((unsigned char *)(x))[6])
+#define get_tcpoff(x)	(((unsigned char *)(x))[12] >> 4)
+#define get_tcpflags(x)	(((unsigned char *)(x))[13])
+
+static int ipv6_active_pkt(u_char *pkt, int len) {
+    u_char *tcp;
+
+    len -= PPP_HDRLEN;
+    pkt += PPP_HDRLEN;
+    if (len < IP6_HDRLEN)
+	return 0;
+    if (get_ip6nh(pkt) == IP6_NHDR_FRAG)
+	return 0;
+    if (get_ip6nh(pkt) != IPPROTO_TCP)
+	return 1;
+    if (len < IP6_HDRLEN + TCP_HDRLEN)
+	return 0;
+    tcp = pkt + IP6_HDRLEN;
+    if ((get_tcpflags(tcp) & TH_FIN) != 0 && len == IP6_HDRLEN + get_tcpoff(tcp) * 4)
+	return 0;
+    return 1;
+}
+#endif /* DEMAND_SUPPORT */
+
+#endif /* PPP_SUPPORT && PPP_IPV6_SUPPORT */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/netif/ppp/lcp.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/netif/ppp/lcp.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/netif/ppp/lcp.c	(revision 457)
@@ -0,0 +1,2790 @@
+/*
+ * lcp.c - PPP Link Control Protocol.
+ *
+ * Copyright (c) 1984-2000 Carnegie Mellon University. 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. The name "Carnegie Mellon University" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For permission or any legal
+ *    details, please contact
+ *      Office of Technology Transfer
+ *      Carnegie Mellon University
+ *      5000 Forbes Avenue
+ *      Pittsburgh, PA  15213-3890
+ *      (412) 268-4387, fax: (412) 268-7395
+ *      tech-transfer@andrew.cmu.edu
+ *
+ * 4. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by Computing Services
+ *     at Carnegie Mellon University (http://www.cmu.edu/computing/)."
+ *
+ * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO
+ * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE
+ * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
+ * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
+ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include "netif/ppp/ppp_opts.h"
+#if PPP_SUPPORT /* don't build if not configured for use in lwipopts.h */
+
+/*
+ * @todo:
+ */
+
+#if 0 /* UNUSED */
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#endif /* UNUSED */
+
+#include "netif/ppp/ppp_impl.h"
+
+#include "netif/ppp/fsm.h"
+#include "netif/ppp/lcp.h"
+#if CHAP_SUPPORT
+#include "netif/ppp/chap-new.h"
+#endif /* CHAP_SUPPORT */
+#include "netif/ppp/magic.h"
+
+/*
+ * When the link comes up we want to be able to wait for a short while,
+ * or until seeing some input from the peer, before starting to send
+ * configure-requests.  We do this by delaying the fsm_lowerup call.
+ */
+/* steal a bit in fsm flags word */
+#define DELAYED_UP	0x80
+
+static void lcp_delayed_up(void *arg);
+
+/*
+ * LCP-related command-line options.
+ */
+#if 0 /* UNUSED */
+int	lcp_echo_interval = 0; 	/* Interval between LCP echo-requests */
+int	lcp_echo_fails = 0;	/* Tolerance to unanswered echo-requests */
+#endif /* UNUSED */
+
+#if 0 /* UNUSED */
+/* options */
+static u_int lcp_echo_interval      = LCP_ECHOINTERVAL; /* Interval between LCP echo-requests */
+static u_int lcp_echo_fails         = LCP_MAXECHOFAILS; /* Tolerance to unanswered echo-requests */
+#endif /* UNUSED */
+
+#if 0 /* UNUSED */
+#if PPP_LCP_ADAPTIVE
+bool	lcp_echo_adaptive = 0;	/* request echo only if the link was idle */
+#endif
+bool	lax_recv = 0;		/* accept control chars in asyncmap */
+bool	noendpoint = 0;		/* don't send/accept endpoint discriminator */
+#endif /* UNUSED */
+
+#if PPP_OPTIONS
+static int noopt (char **);
+#endif /* PPP_OPTIONS */
+
+#ifdef HAVE_MULTILINK
+static int setendpoint (char **);
+static void printendpoint (option_t *, void (*)(void *, char *, ...),
+			       void *);
+#endif /* HAVE_MULTILINK */
+
+#if PPP_OPTIONS
+static option_t lcp_option_list[] = {
+    /* LCP options */
+    { "-all", o_special_noarg, (void *)noopt,
+      "Don't request/allow any LCP options" },
+
+    { "noaccomp", o_bool, &lcp_wantoptions[0].neg_accompression,
+      "Disable address/control compression",
+      OPT_A2CLR, &lcp_allowoptions[0].neg_accompression },
+    { "-ac", o_bool, &lcp_wantoptions[0].neg_accompression,
+      "Disable address/control compression",
+      OPT_ALIAS | OPT_A2CLR, &lcp_allowoptions[0].neg_accompression },
+
+    { "asyncmap", o_uint32, &lcp_wantoptions[0].asyncmap,
+      "Set asyncmap (for received packets)",
+      OPT_OR, &lcp_wantoptions[0].neg_asyncmap },
+    { "-as", o_uint32, &lcp_wantoptions[0].asyncmap,
+      "Set asyncmap (for received packets)",
+      OPT_ALIAS | OPT_OR, &lcp_wantoptions[0].neg_asyncmap },
+    { "default-asyncmap", o_uint32, &lcp_wantoptions[0].asyncmap,
+      "Disable asyncmap negotiation",
+      OPT_OR | OPT_NOARG | OPT_VAL(~0U) | OPT_A2CLR,
+      &lcp_allowoptions[0].neg_asyncmap },
+    { "-am", o_uint32, &lcp_wantoptions[0].asyncmap,
+      "Disable asyncmap negotiation",
+      OPT_ALIAS | OPT_OR | OPT_NOARG | OPT_VAL(~0U) | OPT_A2CLR,
+      &lcp_allowoptions[0].neg_asyncmap },
+
+    { "nomagic", o_bool, &lcp_wantoptions[0].neg_magicnumber,
+      "Disable magic number negotiation (looped-back line detection)",
+      OPT_A2CLR, &lcp_allowoptions[0].neg_magicnumber },
+    { "-mn", o_bool, &lcp_wantoptions[0].neg_magicnumber,
+      "Disable magic number negotiation (looped-back line detection)",
+      OPT_ALIAS | OPT_A2CLR, &lcp_allowoptions[0].neg_magicnumber },
+
+    { "mru", o_int, &lcp_wantoptions[0].mru,
+      "Set MRU (maximum received packet size) for negotiation",
+      OPT_PRIO, &lcp_wantoptions[0].neg_mru },
+    { "default-mru", o_bool, &lcp_wantoptions[0].neg_mru,
+      "Disable MRU negotiation (use default 1500)",
+      OPT_PRIOSUB | OPT_A2CLR, &lcp_allowoptions[0].neg_mru },
+    { "-mru", o_bool, &lcp_wantoptions[0].neg_mru,
+      "Disable MRU negotiation (use default 1500)",
+      OPT_ALIAS | OPT_PRIOSUB | OPT_A2CLR, &lcp_allowoptions[0].neg_mru },
+
+    { "mtu", o_int, &lcp_allowoptions[0].mru,
+      "Set our MTU", OPT_LIMITS, NULL, MAXMRU, MINMRU },
+
+    { "nopcomp", o_bool, &lcp_wantoptions[0].neg_pcompression,
+      "Disable protocol field compression",
+      OPT_A2CLR, &lcp_allowoptions[0].neg_pcompression },
+    { "-pc", o_bool, &lcp_wantoptions[0].neg_pcompression,
+      "Disable protocol field compression",
+      OPT_ALIAS | OPT_A2CLR, &lcp_allowoptions[0].neg_pcompression },
+
+    { "passive", o_bool, &lcp_wantoptions[0].passive,
+      "Set passive mode", 1 },
+    { "-p", o_bool, &lcp_wantoptions[0].passive,
+      "Set passive mode", OPT_ALIAS | 1 },
+
+    { "silent", o_bool, &lcp_wantoptions[0].silent,
+      "Set silent mode", 1 },
+
+    { "lcp-echo-failure", o_int, &lcp_echo_fails,
+      "Set number of consecutive echo failures to indicate link failure",
+      OPT_PRIO },
+    { "lcp-echo-interval", o_int, &lcp_echo_interval,
+      "Set time in seconds between LCP echo requests", OPT_PRIO },
+#if PPP_LCP_ADAPTIVE
+    { "lcp-echo-adaptive", o_bool, &lcp_echo_adaptive,
+      "Suppress LCP echo requests if traffic was received", 1 },
+#endif
+    { "lcp-restart", o_int, &lcp_fsm[0].timeouttime,
+      "Set time in seconds between LCP retransmissions", OPT_PRIO },
+    { "lcp-max-terminate", o_int, &lcp_fsm[0].maxtermtransmits,
+      "Set maximum number of LCP terminate-request transmissions", OPT_PRIO },
+    { "lcp-max-configure", o_int, &lcp_fsm[0].maxconfreqtransmits,
+      "Set maximum number of LCP configure-request transmissions", OPT_PRIO },
+    { "lcp-max-failure", o_int, &lcp_fsm[0].maxnakloops,
+      "Set limit on number of LCP configure-naks", OPT_PRIO },
+
+    { "receive-all", o_bool, &lax_recv,
+      "Accept all received control characters", 1 },
+
+#ifdef HAVE_MULTILINK
+    { "mrru", o_int, &lcp_wantoptions[0].mrru,
+      "Maximum received packet size for multilink bundle",
+      OPT_PRIO, &lcp_wantoptions[0].neg_mrru },
+
+    { "mpshortseq", o_bool, &lcp_wantoptions[0].neg_ssnhf,
+      "Use short sequence numbers in multilink headers",
+      OPT_PRIO | 1, &lcp_allowoptions[0].neg_ssnhf },
+    { "nompshortseq", o_bool, &lcp_wantoptions[0].neg_ssnhf,
+      "Don't use short sequence numbers in multilink headers",
+      OPT_PRIOSUB | OPT_A2CLR, &lcp_allowoptions[0].neg_ssnhf },
+
+    { "endpoint", o_special, (void *) setendpoint,
+      "Endpoint discriminator for multilink",
+      OPT_PRIO | OPT_A2PRINTER, (void *) printendpoint },
+#endif /* HAVE_MULTILINK */
+
+    { "noendpoint", o_bool, &noendpoint,
+      "Don't send or accept multilink endpoint discriminator", 1 },
+
+    {NULL}
+};
+#endif /* PPP_OPTIONS */
+
+/*
+ * Callbacks for fsm code.  (CI = Configuration Information)
+ */
+static void lcp_resetci(fsm *f);	/* Reset our CI */
+static int  lcp_cilen(fsm *f);		/* Return length of our CI */
+static void lcp_addci(fsm *f, u_char *ucp, int *lenp); /* Add our CI to pkt */
+static int  lcp_ackci(fsm *f, u_char *p, int len); /* Peer ack'd our CI */
+static int  lcp_nakci(fsm *f, u_char *p, int len, int treat_as_reject); /* Peer nak'd our CI */
+static int  lcp_rejci(fsm *f, u_char *p, int len); /* Peer rej'd our CI */
+static int  lcp_reqci(fsm *f, u_char *inp, int *lenp, int reject_if_disagree); /* Rcv peer CI */
+static void lcp_up(fsm *f);		/* We're UP */
+static void lcp_down(fsm *f);		/* We're DOWN */
+static void lcp_starting (fsm *);	/* We need lower layer up */
+static void lcp_finished (fsm *);	/* We need lower layer down */
+static int  lcp_extcode(fsm *f, int code, int id, u_char *inp, int len);
+static void lcp_rprotrej(fsm *f, u_char *inp, int len);
+
+/*
+ * routines to send LCP echos to peer
+ */
+
+static void lcp_echo_lowerup(ppp_pcb *pcb);
+static void lcp_echo_lowerdown(ppp_pcb *pcb);
+static void LcpEchoTimeout(void *arg);
+static void lcp_received_echo_reply(fsm *f, int id, u_char *inp, int len);
+static void LcpSendEchoRequest(fsm *f);
+static void LcpLinkFailure(fsm *f);
+static void LcpEchoCheck(fsm *f);
+
+static const fsm_callbacks lcp_callbacks = {	/* LCP callback routines */
+    lcp_resetci,		/* Reset our Configuration Information */
+    lcp_cilen,			/* Length of our Configuration Information */
+    lcp_addci,			/* Add our Configuration Information */
+    lcp_ackci,			/* ACK our Configuration Information */
+    lcp_nakci,			/* NAK our Configuration Information */
+    lcp_rejci,			/* Reject our Configuration Information */
+    lcp_reqci,			/* Request peer's Configuration Information */
+    lcp_up,			/* Called when fsm reaches OPENED state */
+    lcp_down,			/* Called when fsm leaves OPENED state */
+    lcp_starting,		/* Called when we want the lower layer up */
+    lcp_finished,		/* Called when we want the lower layer down */
+    NULL,			/* Called when Protocol-Reject received */
+    NULL,			/* Retransmission is necessary */
+    lcp_extcode,		/* Called to handle LCP-specific codes */
+    "LCP"			/* String name of protocol */
+};
+
+/*
+ * Protocol entry points.
+ * Some of these are called directly.
+ */
+
+static void lcp_init(ppp_pcb *pcb);
+static void lcp_input(ppp_pcb *pcb, u_char *p, int len);
+static void lcp_protrej(ppp_pcb *pcb);
+#if PRINTPKT_SUPPORT
+static int lcp_printpkt(const u_char *p, int plen,
+		void (*printer) (void *, const char *, ...), void *arg);
+#endif /* PRINTPKT_SUPPORT */
+
+const struct protent lcp_protent = {
+    PPP_LCP,
+    lcp_init,
+    lcp_input,
+    lcp_protrej,
+    lcp_lowerup,
+    lcp_lowerdown,
+    lcp_open,
+    lcp_close,
+#if PRINTPKT_SUPPORT
+    lcp_printpkt,
+#endif /* PRINTPKT_SUPPORT */
+#if PPP_DATAINPUT
+    NULL,
+#endif /* PPP_DATAINPUT */
+#if PRINTPKT_SUPPORT
+    "LCP",
+    NULL,
+#endif /* PRINTPKT_SUPPORT */
+#if PPP_OPTIONS
+    lcp_option_list,
+    NULL,
+#endif /* PPP_OPTIONS */
+#if DEMAND_SUPPORT
+    NULL,
+    NULL
+#endif /* DEMAND_SUPPORT */
+};
+
+/*
+ * Length of each type of configuration option (in octets)
+ */
+#define CILEN_VOID	2
+#define CILEN_CHAR	3
+#define CILEN_SHORT	4	/* CILEN_VOID + 2 */
+#if CHAP_SUPPORT
+#define CILEN_CHAP	5	/* CILEN_VOID + 2 + 1 */
+#endif /* CHAP_SUPPORT */
+#define CILEN_LONG	6	/* CILEN_VOID + 4 */
+#if LQR_SUPPORT
+#define CILEN_LQR	8	/* CILEN_VOID + 2 + 4 */
+#endif /* LQR_SUPPORT */
+#define CILEN_CBCP	3
+
+#define CODENAME(x)	((x) == CONFACK ? "ACK" : \
+			 (x) == CONFNAK ? "NAK" : "REJ")
+
+#if PPP_OPTIONS
+/*
+ * noopt - Disable all options (why?).
+ */
+static int
+noopt(argv)
+    char **argv;
+{
+    BZERO((char *) &lcp_wantoptions[0], sizeof (struct lcp_options));
+    BZERO((char *) &lcp_allowoptions[0], sizeof (struct lcp_options));
+
+    return (1);
+}
+#endif /* PPP_OPTIONS */
+
+#ifdef HAVE_MULTILINK
+static int
+setendpoint(argv)
+    char **argv;
+{
+    if (str_to_epdisc(&lcp_wantoptions[0].endpoint, *argv)) {
+	lcp_wantoptions[0].neg_endpoint = 1;
+	return 1;
+    }
+    option_error("Can't parse '%s' as an endpoint discriminator", *argv);
+    return 0;
+}
+
+static void
+printendpoint(opt, printer, arg)
+    option_t *opt;
+    void (*printer) (void *, char *, ...);
+    void *arg;
+{
+	printer(arg, "%s", epdisc_to_str(&lcp_wantoptions[0].endpoint));
+}
+#endif /* HAVE_MULTILINK */
+
+/*
+ * lcp_init - Initialize LCP.
+ */
+static void lcp_init(ppp_pcb *pcb) {
+    fsm *f = &pcb->lcp_fsm;
+    lcp_options *wo = &pcb->lcp_wantoptions;
+    lcp_options *ao = &pcb->lcp_allowoptions;
+
+    f->pcb = pcb;
+    f->protocol = PPP_LCP;
+    f->callbacks = &lcp_callbacks;
+
+    fsm_init(f);
+
+    BZERO(wo, sizeof(*wo));
+    wo->neg_mru = 1;
+    wo->mru = PPP_DEFMRU;
+    wo->neg_asyncmap = 1;
+    wo->neg_magicnumber = 1;
+    wo->neg_pcompression = 1;
+    wo->neg_accompression = 1;
+
+    BZERO(ao, sizeof(*ao));
+    ao->neg_mru = 1;
+    ao->mru = PPP_MAXMRU;
+    ao->neg_asyncmap = 1;
+#if CHAP_SUPPORT
+    ao->neg_chap = 1;
+    ao->chap_mdtype = CHAP_MDTYPE_SUPPORTED;
+#endif /* CHAP_SUPPORT */
+#if PAP_SUPPORT
+    ao->neg_upap = 1;
+#endif /* PAP_SUPPORT */
+#if EAP_SUPPORT
+    ao->neg_eap = 1;
+#endif /* EAP_SUPPORT */
+    ao->neg_magicnumber = 1;
+    ao->neg_pcompression = 1;
+    ao->neg_accompression = 1;
+    ao->neg_endpoint = 1;
+}
+
+
+/*
+ * lcp_open - LCP is allowed to come up.
+ */
+void lcp_open(ppp_pcb *pcb) {
+    fsm *f = &pcb->lcp_fsm;
+    lcp_options *wo = &pcb->lcp_wantoptions;
+
+    f->flags &= ~(OPT_PASSIVE | OPT_SILENT);
+    if (wo->passive)
+	f->flags |= OPT_PASSIVE;
+    if (wo->silent)
+	f->flags |= OPT_SILENT;
+    fsm_open(f);
+}
+
+
+/*
+ * lcp_close - Take LCP down.
+ */
+void lcp_close(ppp_pcb *pcb, const char *reason) {
+    fsm *f = &pcb->lcp_fsm;
+    int oldstate;
+
+    if (pcb->phase != PPP_PHASE_DEAD
+#ifdef HAVE_MULTILINK
+    && pcb->phase != PPP_PHASE_MASTER
+#endif /* HAVE_MULTILINK */
+    )
+	new_phase(pcb, PPP_PHASE_TERMINATE);
+
+    if (f->flags & DELAYED_UP) {
+	UNTIMEOUT(lcp_delayed_up, f);
+	f->state = PPP_FSM_STOPPED;
+    }
+    oldstate = f->state;
+
+    fsm_close(f, reason);
+    if (oldstate == PPP_FSM_STOPPED && (f->flags & (OPT_PASSIVE|OPT_SILENT|DELAYED_UP))) {
+	/*
+	 * This action is not strictly according to the FSM in RFC1548,
+	 * but it does mean that the program terminates if you do a
+	 * lcp_close() when a connection hasn't been established
+	 * because we are in passive/silent mode or because we have
+	 * delayed the fsm_lowerup() call and it hasn't happened yet.
+	 */
+	f->flags &= ~DELAYED_UP;
+	lcp_finished(f);
+    }
+}
+
+
+/*
+ * lcp_lowerup - The lower layer is up.
+ */
+void lcp_lowerup(ppp_pcb *pcb) {
+    lcp_options *wo = &pcb->lcp_wantoptions;
+    fsm *f = &pcb->lcp_fsm;
+    /*
+     * Don't use A/C or protocol compression on transmission,
+     * but accept A/C and protocol compressed packets
+     * if we are going to ask for A/C and protocol compression.
+     */
+    if (ppp_send_config(pcb, PPP_MRU, 0xffffffff, 0, 0) < 0
+	|| ppp_recv_config(pcb, PPP_MRU, (pcb->settings.lax_recv? 0: 0xffffffff),
+			   wo->neg_pcompression, wo->neg_accompression) < 0)
+	    return;
+    pcb->peer_mru = PPP_MRU;
+
+    if (pcb->settings.listen_time != 0) {
+	f->flags |= DELAYED_UP;
+	TIMEOUTMS(lcp_delayed_up, f, pcb->settings.listen_time);
+    } else
+	fsm_lowerup(f);
+}
+
+
+/*
+ * lcp_lowerdown - The lower layer is down.
+ */
+void lcp_lowerdown(ppp_pcb *pcb) {
+    fsm *f = &pcb->lcp_fsm;
+
+    if (f->flags & DELAYED_UP) {
+	f->flags &= ~DELAYED_UP;
+	UNTIMEOUT(lcp_delayed_up, f);
+    } else
+	fsm_lowerdown(f);
+}
+
+
+/*
+ * lcp_delayed_up - Bring the lower layer up now.
+ */
+static void lcp_delayed_up(void *arg) {
+    fsm *f = (fsm*)arg;
+
+    if (f->flags & DELAYED_UP) {
+	f->flags &= ~DELAYED_UP;
+	fsm_lowerup(f);
+    }
+}
+
+
+/*
+ * lcp_input - Input LCP packet.
+ */
+static void lcp_input(ppp_pcb *pcb, u_char *p, int len) {
+    fsm *f = &pcb->lcp_fsm;
+
+    if (f->flags & DELAYED_UP) {
+	f->flags &= ~DELAYED_UP;
+	UNTIMEOUT(lcp_delayed_up, f);
+	fsm_lowerup(f);
+    }
+    fsm_input(f, p, len);
+}
+
+/*
+ * lcp_extcode - Handle a LCP-specific code.
+ */
+static int lcp_extcode(fsm *f, int code, int id, u_char *inp, int len) {
+    ppp_pcb *pcb = f->pcb;
+    lcp_options *go = &pcb->lcp_gotoptions;
+    u_char *magp;
+
+    switch( code ){
+    case PROTREJ:
+	lcp_rprotrej(f, inp, len);
+	break;
+    
+    case ECHOREQ:
+	if (f->state != PPP_FSM_OPENED)
+	    break;
+	magp = inp;
+	PUTLONG(go->magicnumber, magp);
+	fsm_sdata(f, ECHOREP, id, inp, len);
+	break;
+    
+    case ECHOREP:
+	lcp_received_echo_reply(f, id, inp, len);
+	break;
+
+    case DISCREQ:
+    case IDENTIF:
+    case TIMEREM:
+	break;
+
+    default:
+	return 0;
+    }
+    return 1;
+}
+
+    
+/*
+ * lcp_rprotrej - Receive an Protocol-Reject.
+ *
+ * Figure out which protocol is rejected and inform it.
+ */
+static void lcp_rprotrej(fsm *f, u_char *inp, int len) {
+    int i;
+    const struct protent *protp;
+    u_short prot;
+#if PPP_PROTOCOLNAME
+    const char *pname;
+#endif /* PPP_PROTOCOLNAME */
+
+    if (len < 2) {
+	LCPDEBUG(("lcp_rprotrej: Rcvd short Protocol-Reject packet!"));
+	return;
+    }
+
+    GETSHORT(prot, inp);
+
+    /*
+     * Protocol-Reject packets received in any state other than the LCP
+     * OPENED state SHOULD be silently discarded.
+     */
+    if( f->state != PPP_FSM_OPENED ){
+	LCPDEBUG(("Protocol-Reject discarded: LCP in state %d", f->state));
+	return;
+    }
+
+#if PPP_PROTOCOLNAME
+    pname = protocol_name(prot);
+#endif /* PPP_PROTOCOLNAME */
+
+    /*
+     * Upcall the proper Protocol-Reject routine.
+     */
+    for (i = 0; (protp = protocols[i]) != NULL; ++i)
+	if (protp->protocol == prot) {
+#if PPP_PROTOCOLNAME
+	    if (pname != NULL)
+		ppp_dbglog("Protocol-Reject for '%s' (0x%x) received", pname,
+		       prot);
+	    else
+#endif /* PPP_PROTOCOLNAME */
+		ppp_dbglog("Protocol-Reject for 0x%x received", prot);
+	    (*protp->protrej)(f->pcb);
+	    return;
+	}
+
+#if PPP_PROTOCOLNAME
+    if (pname != NULL)
+	ppp_warn("Protocol-Reject for unsupported protocol '%s' (0x%x)", pname,
+	     prot);
+    else
+#endif /* #if PPP_PROTOCOLNAME */
+	ppp_warn("Protocol-Reject for unsupported protocol 0x%x", prot);
+}
+
+
+/*
+ * lcp_protrej - A Protocol-Reject was received.
+ */
+/*ARGSUSED*/
+static void lcp_protrej(ppp_pcb *pcb) {
+    /*
+     * Can't reject LCP!
+     */
+    ppp_error("Received Protocol-Reject for LCP!");
+    fsm_protreject(&pcb->lcp_fsm);
+}
+
+
+/*
+ * lcp_sprotrej - Send a Protocol-Reject for some protocol.
+ */
+void lcp_sprotrej(ppp_pcb *pcb, u_char *p, int len) {
+    fsm *f = &pcb->lcp_fsm;
+    /*
+     * Send back the protocol and the information field of the
+     * rejected packet.  We only get here if LCP is in the OPENED state.
+     */
+#if 0
+    p += 2;
+    len -= 2;
+#endif
+
+    fsm_sdata(f, PROTREJ, ++f->id,
+	      p, len);
+}
+
+
+/*
+ * lcp_resetci - Reset our CI.
+ */
+static void lcp_resetci(fsm *f) {
+    ppp_pcb *pcb = f->pcb;
+    lcp_options *wo = &pcb->lcp_wantoptions;
+    lcp_options *go = &pcb->lcp_gotoptions;
+    lcp_options *ao = &pcb->lcp_allowoptions;
+
+#if PPP_AUTH_SUPPORT
+
+    /* note: default value is true for allow options */
+    if (pcb->settings.user && pcb->settings.passwd) {
+#if PAP_SUPPORT
+      if (pcb->settings.refuse_pap) {
+        ao->neg_upap = 0;
+      }
+#endif /* PAP_SUPPORT */
+#if CHAP_SUPPORT
+      if (pcb->settings.refuse_chap) {
+        ao->chap_mdtype &= ~MDTYPE_MD5;
+      }
+#if MSCHAP_SUPPORT
+      if (pcb->settings.refuse_mschap) {
+        ao->chap_mdtype &= ~MDTYPE_MICROSOFT;
+      }
+      if (pcb->settings.refuse_mschap_v2) {
+        ao->chap_mdtype &= ~MDTYPE_MICROSOFT_V2;
+      }
+#endif /* MSCHAP_SUPPORT */
+      ao->neg_chap = (ao->chap_mdtype != MDTYPE_NONE);
+#endif /* CHAP_SUPPORT */
+#if EAP_SUPPORT
+      if (pcb->settings.refuse_eap) {
+        ao->neg_eap = 0;
+      }
+#endif /* EAP_SUPPORT */
+
+#if PPP_SERVER
+      /* note: default value is false for wanted options */
+      if (pcb->settings.auth_required) {
+#if PAP_SUPPORT
+        if (!pcb->settings.refuse_pap) {
+          wo->neg_upap = 1;
+        }
+#endif /* PAP_SUPPORT */
+#if CHAP_SUPPORT
+        if (!pcb->settings.refuse_chap) {
+          wo->chap_mdtype |= MDTYPE_MD5;
+        }
+#if MSCHAP_SUPPORT
+        if (!pcb->settings.refuse_mschap) {
+          wo->chap_mdtype |= MDTYPE_MICROSOFT;
+        }
+        if (!pcb->settings.refuse_mschap_v2) {
+          wo->chap_mdtype |= MDTYPE_MICROSOFT_V2;
+        }
+#endif /* MSCHAP_SUPPORT */
+        wo->neg_chap = (wo->chap_mdtype != MDTYPE_NONE);
+#endif /* CHAP_SUPPORT */
+#if EAP_SUPPORT
+        if (!pcb->settings.refuse_eap) {
+          wo->neg_eap = 1;
+        }
+#endif /* EAP_SUPPORT */
+      }
+#endif /* PPP_SERVER */
+
+    } else {
+#if PAP_SUPPORT
+      ao->neg_upap = 0;
+#endif /* PAP_SUPPORT */
+#if CHAP_SUPPORT
+      ao->neg_chap = 0;
+      ao->chap_mdtype = MDTYPE_NONE;
+#endif /* CHAP_SUPPORT */
+#if EAP_SUPPORT
+      ao->neg_eap = 0;
+#endif /* EAP_SUPPORT */
+    }
+
+    PPPDEBUG(LOG_DEBUG, ("ppp: auth protocols:"));
+#if PAP_SUPPORT
+    PPPDEBUG(LOG_DEBUG, (" PAP=%d", ao->neg_upap));
+#endif /* PAP_SUPPORT */
+#if CHAP_SUPPORT
+    PPPDEBUG(LOG_DEBUG, (" CHAP=%d CHAP_MD5=%d", ao->neg_chap, !!(ao->chap_mdtype&MDTYPE_MD5)));
+#if MSCHAP_SUPPORT
+    PPPDEBUG(LOG_DEBUG, (" CHAP_MS=%d CHAP_MS2=%d", !!(ao->chap_mdtype&MDTYPE_MICROSOFT), !!(ao->chap_mdtype&MDTYPE_MICROSOFT_V2)));
+#endif /* MSCHAP_SUPPORT */
+#endif /* CHAP_SUPPORT */
+#if EAP_SUPPORT
+    PPPDEBUG(LOG_DEBUG, (" EAP=%d", ao->neg_eap));
+#endif /* EAP_SUPPORT */
+    PPPDEBUG(LOG_DEBUG, ("\n"));
+
+#endif /* PPP_AUTH_SUPPORT */
+
+    wo->magicnumber = magic();
+    wo->numloops = 0;
+    *go = *wo;
+#ifdef HAVE_MULTILINK
+    if (!multilink) {
+	go->neg_mrru = 0;
+#endif /* HAVE_MULTILINK */
+	go->neg_ssnhf = 0;
+	go->neg_endpoint = 0;
+#ifdef HAVE_MULTILINK
+    }
+#endif /* HAVE_MULTILINK */
+    if (pcb->settings.noendpoint)
+	ao->neg_endpoint = 0;
+    pcb->peer_mru = PPP_MRU;
+#if 0 /* UNUSED */
+    auth_reset(pcb);
+#endif /* UNUSED */
+}
+
+
+/*
+ * lcp_cilen - Return length of our CI.
+ */
+static int lcp_cilen(fsm *f) {
+    ppp_pcb *pcb = f->pcb;
+    lcp_options *go = &pcb->lcp_gotoptions;
+
+#define LENCIVOID(neg)	((neg) ? CILEN_VOID : 0)
+#if CHAP_SUPPORT
+#define LENCICHAP(neg)	((neg) ? CILEN_CHAP : 0)
+#endif /* CHAP_SUPPORT */
+#define LENCISHORT(neg)	((neg) ? CILEN_SHORT : 0)
+#define LENCILONG(neg)	((neg) ? CILEN_LONG : 0)
+#if LQR_SUPPORT
+#define LENCILQR(neg)	((neg) ? CILEN_LQR: 0)
+#endif /* LQR_SUPPORT */
+#define LENCICBCP(neg)	((neg) ? CILEN_CBCP: 0)
+    /*
+     * NB: we only ask for one of CHAP, UPAP, or EAP, even if we will
+     * accept more than one.  We prefer EAP first, then CHAP, then
+     * PAP.
+     */
+    return (LENCISHORT(go->neg_mru && go->mru != PPP_DEFMRU) +
+	    LENCILONG(go->neg_asyncmap && go->asyncmap != 0xFFFFFFFF) +
+#if EAP_SUPPORT
+	    LENCISHORT(go->neg_eap) +
+#endif /* EAP_SUPPORT */
+#if CHAP_SUPPORT /* cannot be improved, embedding a directive within macro arguments is not portable */
+#if EAP_SUPPORT
+	    LENCICHAP(!go->neg_eap && go->neg_chap) +
+#endif /* EAP_SUPPORT */
+#if !EAP_SUPPORT
+	    LENCICHAP(go->neg_chap) +
+#endif /* !EAP_SUPPORT */
+#endif /* CHAP_SUPPORT */
+#if PAP_SUPPORT /* cannot be improved, embedding a directive within macro arguments is not portable */
+#if EAP_SUPPORT && CHAP_SUPPORT
+	    LENCISHORT(!go->neg_eap && !go->neg_chap && go->neg_upap) +
+#endif /* EAP_SUPPORT && CHAP_SUPPORT */
+#if EAP_SUPPORT && !CHAP_SUPPORT
+	    LENCISHORT(!go->neg_eap && go->neg_upap) +
+#endif /* EAP_SUPPORT && !CHAP_SUPPORT */
+#if !EAP_SUPPORT && CHAP_SUPPORT
+	    LENCISHORT(!go->neg_chap && go->neg_upap) +
+#endif /* !EAP_SUPPORT && CHAP_SUPPORT */
+#if !EAP_SUPPORT && !CHAP_SUPPORT
+	    LENCISHORT(go->neg_upap) +
+#endif /* !EAP_SUPPORT && !CHAP_SUPPORT */
+#endif /* PAP_SUPPORT */
+#if LQR_SUPPORT
+	    LENCILQR(go->neg_lqr) +
+#endif /* LQR_SUPPORT */
+	    LENCICBCP(go->neg_cbcp) +
+	    LENCILONG(go->neg_magicnumber) +
+	    LENCIVOID(go->neg_pcompression) +
+	    LENCIVOID(go->neg_accompression) +
+#ifdef HAVE_MULTILINK
+	    LENCISHORT(go->neg_mrru) +
+#endif /* HAVE_MULTILINK */
+	    LENCIVOID(go->neg_ssnhf) +
+	    (go->neg_endpoint? CILEN_CHAR + go->endpoint.length: 0));
+}
+
+
+/*
+ * lcp_addci - Add our desired CIs to a packet.
+ */
+static void lcp_addci(fsm *f, u_char *ucp, int *lenp) {
+    ppp_pcb *pcb = f->pcb;
+    lcp_options *go = &pcb->lcp_gotoptions;
+    u_char *start_ucp = ucp;
+
+#define ADDCIVOID(opt, neg) \
+    if (neg) { \
+	PUTCHAR(opt, ucp); \
+	PUTCHAR(CILEN_VOID, ucp); \
+    }
+#define ADDCISHORT(opt, neg, val) \
+    if (neg) { \
+	PUTCHAR(opt, ucp); \
+	PUTCHAR(CILEN_SHORT, ucp); \
+	PUTSHORT(val, ucp); \
+    }
+#if CHAP_SUPPORT
+#define ADDCICHAP(opt, neg, val) \
+    if (neg) { \
+	PUTCHAR((opt), ucp); \
+	PUTCHAR(CILEN_CHAP, ucp); \
+	PUTSHORT(PPP_CHAP, ucp); \
+	PUTCHAR((CHAP_DIGEST(val)), ucp); \
+    }
+#endif /* CHAP_SUPPORT */
+#define ADDCILONG(opt, neg, val) \
+    if (neg) { \
+	PUTCHAR(opt, ucp); \
+	PUTCHAR(CILEN_LONG, ucp); \
+	PUTLONG(val, ucp); \
+    }
+#if LQR_SUPPORT
+#define ADDCILQR(opt, neg, val) \
+    if (neg) { \
+	PUTCHAR(opt, ucp); \
+	PUTCHAR(CILEN_LQR, ucp); \
+	PUTSHORT(PPP_LQR, ucp); \
+	PUTLONG(val, ucp); \
+    }
+#endif /* LQR_SUPPORT */
+#define ADDCICHAR(opt, neg, val) \
+    if (neg) { \
+	PUTCHAR(opt, ucp); \
+	PUTCHAR(CILEN_CHAR, ucp); \
+	PUTCHAR(val, ucp); \
+    }
+#define ADDCIENDP(opt, neg, class, val, len) \
+    if (neg) { \
+	int i; \
+	PUTCHAR(opt, ucp); \
+	PUTCHAR(CILEN_CHAR + len, ucp); \
+	PUTCHAR(class, ucp); \
+	for (i = 0; i < len; ++i) \
+	    PUTCHAR(val[i], ucp); \
+    }
+
+    ADDCISHORT(CI_MRU, go->neg_mru && go->mru != PPP_DEFMRU, go->mru);
+    ADDCILONG(CI_ASYNCMAP, go->neg_asyncmap && go->asyncmap != 0xFFFFFFFF,
+	      go->asyncmap);
+#if EAP_SUPPORT
+    ADDCISHORT(CI_AUTHTYPE, go->neg_eap, PPP_EAP);
+#endif /* EAP_SUPPORT */
+#if CHAP_SUPPORT /* cannot be improved, embedding a directive within macro arguments is not portable */
+#if EAP_SUPPORT
+    ADDCICHAP(CI_AUTHTYPE, !go->neg_eap && go->neg_chap, go->chap_mdtype);
+#endif /* EAP_SUPPORT */
+#if !EAP_SUPPORT
+    ADDCICHAP(CI_AUTHTYPE, go->neg_chap, go->chap_mdtype);
+#endif /* !EAP_SUPPORT */
+#endif /* CHAP_SUPPORT */
+#if PAP_SUPPORT /* cannot be improved, embedding a directive within macro arguments is not portable */
+#if EAP_SUPPORT && CHAP_SUPPORT
+    ADDCISHORT(CI_AUTHTYPE, !go->neg_eap && !go->neg_chap && go->neg_upap, PPP_PAP);
+#endif /* EAP_SUPPORT && CHAP_SUPPORT */
+#if EAP_SUPPORT && !CHAP_SUPPORT
+    ADDCISHORT(CI_AUTHTYPE, !go->neg_eap && go->neg_upap, PPP_PAP);
+#endif /* EAP_SUPPORT && !CHAP_SUPPORT */
+#if !EAP_SUPPORT && CHAP_SUPPORT
+    ADDCISHORT(CI_AUTHTYPE, !go->neg_chap && go->neg_upap, PPP_PAP);
+#endif /* !EAP_SUPPORT && CHAP_SUPPORT */
+#if !EAP_SUPPORT && !CHAP_SUPPORT
+    ADDCISHORT(CI_AUTHTYPE, go->neg_upap, PPP_PAP);
+#endif /* !EAP_SUPPORT && !CHAP_SUPPORT */
+#endif /* PAP_SUPPORT */
+#if LQR_SUPPORT
+    ADDCILQR(CI_QUALITY, go->neg_lqr, go->lqr_period);
+#endif /* LQR_SUPPORT */
+    ADDCICHAR(CI_CALLBACK, go->neg_cbcp, CBCP_OPT);
+    ADDCILONG(CI_MAGICNUMBER, go->neg_magicnumber, go->magicnumber);
+    ADDCIVOID(CI_PCOMPRESSION, go->neg_pcompression);
+    ADDCIVOID(CI_ACCOMPRESSION, go->neg_accompression);
+#ifdef HAVE_MULTILINK
+    ADDCISHORT(CI_MRRU, go->neg_mrru, go->mrru);
+#endif
+    ADDCIVOID(CI_SSNHF, go->neg_ssnhf);
+    ADDCIENDP(CI_EPDISC, go->neg_endpoint, go->endpoint.class_,
+	      go->endpoint.value, go->endpoint.length);
+
+    if (ucp - start_ucp != *lenp) {
+	/* this should never happen, because peer_mtu should be 1500 */
+	ppp_error("Bug in lcp_addci: wrong length");
+    }
+}
+
+
+/*
+ * lcp_ackci - Ack our CIs.
+ * This should not modify any state if the Ack is bad.
+ *
+ * Returns:
+ *	0 - Ack was bad.
+ *	1 - Ack was good.
+ */
+static int lcp_ackci(fsm *f, u_char *p, int len) {
+    ppp_pcb *pcb = f->pcb;
+    lcp_options *go = &pcb->lcp_gotoptions;
+    u_char cilen, citype, cichar;
+    u_short cishort;
+    u32_t cilong;
+
+    /*
+     * CIs must be in exactly the same order that we sent.
+     * Check packet length and CI length at each step.
+     * If we find any deviations, then this packet is bad.
+     */
+#define ACKCIVOID(opt, neg) \
+    if (neg) { \
+	if ((len -= CILEN_VOID) < 0) \
+	    goto bad; \
+	GETCHAR(citype, p); \
+	GETCHAR(cilen, p); \
+	if (cilen != CILEN_VOID || \
+	    citype != opt) \
+	    goto bad; \
+    }
+#define ACKCISHORT(opt, neg, val) \
+    if (neg) { \
+	if ((len -= CILEN_SHORT) < 0) \
+	    goto bad; \
+	GETCHAR(citype, p); \
+	GETCHAR(cilen, p); \
+	if (cilen != CILEN_SHORT || \
+	    citype != opt) \
+	    goto bad; \
+	GETSHORT(cishort, p); \
+	if (cishort != val) \
+	    goto bad; \
+    }
+#define ACKCICHAR(opt, neg, val) \
+    if (neg) { \
+	if ((len -= CILEN_CHAR) < 0) \
+	    goto bad; \
+	GETCHAR(citype, p); \
+	GETCHAR(cilen, p); \
+	if (cilen != CILEN_CHAR || \
+	    citype != opt) \
+	    goto bad; \
+	GETCHAR(cichar, p); \
+	if (cichar != val) \
+	    goto bad; \
+    }
+#if CHAP_SUPPORT
+#define ACKCICHAP(opt, neg, val) \
+    if (neg) { \
+	if ((len -= CILEN_CHAP) < 0) \
+	    goto bad; \
+	GETCHAR(citype, p); \
+	GETCHAR(cilen, p); \
+	if (cilen != CILEN_CHAP || \
+	    citype != (opt)) \
+	    goto bad; \
+	GETSHORT(cishort, p); \
+	if (cishort != PPP_CHAP) \
+	    goto bad; \
+	GETCHAR(cichar, p); \
+	if (cichar != (CHAP_DIGEST(val))) \
+	  goto bad; \
+    }
+#endif /* CHAP_SUPPORT */
+#define ACKCILONG(opt, neg, val) \
+    if (neg) { \
+	if ((len -= CILEN_LONG) < 0) \
+	    goto bad; \
+	GETCHAR(citype, p); \
+	GETCHAR(cilen, p); \
+	if (cilen != CILEN_LONG || \
+	    citype != opt) \
+	    goto bad; \
+	GETLONG(cilong, p); \
+	if (cilong != val) \
+	    goto bad; \
+    }
+#if LQR_SUPPORT
+#define ACKCILQR(opt, neg, val) \
+    if (neg) { \
+	if ((len -= CILEN_LQR) < 0) \
+	    goto bad; \
+	GETCHAR(citype, p); \
+	GETCHAR(cilen, p); \
+	if (cilen != CILEN_LQR || \
+	    citype != opt) \
+	    goto bad; \
+	GETSHORT(cishort, p); \
+	if (cishort != PPP_LQR) \
+	    goto bad; \
+	GETLONG(cilong, p); \
+	if (cilong != val) \
+	  goto bad; \
+    }
+#endif /* LQR_SUPPORT */
+#define ACKCIENDP(opt, neg, class, val, vlen) \
+    if (neg) { \
+	int i; \
+	if ((len -= CILEN_CHAR + vlen) < 0) \
+	    goto bad; \
+	GETCHAR(citype, p); \
+	GETCHAR(cilen, p); \
+	if (cilen != CILEN_CHAR + vlen || \
+	    citype != opt) \
+	    goto bad; \
+	GETCHAR(cichar, p); \
+	if (cichar != class) \
+	    goto bad; \
+	for (i = 0; i < vlen; ++i) { \
+	    GETCHAR(cichar, p); \
+	    if (cichar != val[i]) \
+		goto bad; \
+	} \
+    }
+
+    ACKCISHORT(CI_MRU, go->neg_mru && go->mru != PPP_DEFMRU, go->mru);
+    ACKCILONG(CI_ASYNCMAP, go->neg_asyncmap && go->asyncmap != 0xFFFFFFFF,
+	      go->asyncmap);
+#if EAP_SUPPORT
+    ACKCISHORT(CI_AUTHTYPE, go->neg_eap, PPP_EAP);
+#endif /* EAP_SUPPORT */
+#if CHAP_SUPPORT /* cannot be improved, embedding a directive within macro arguments is not portable */
+#if EAP_SUPPORT
+    ACKCICHAP(CI_AUTHTYPE, !go->neg_eap && go->neg_chap, go->chap_mdtype);
+#endif /* EAP_SUPPORT */
+#if !EAP_SUPPORT
+    ACKCICHAP(CI_AUTHTYPE, go->neg_chap, go->chap_mdtype);
+#endif /* !EAP_SUPPORT */
+#endif /* CHAP_SUPPORT */
+#if PAP_SUPPORT /* cannot be improved, embedding a directive within macro arguments is not portable */
+#if EAP_SUPPORT && CHAP_SUPPORT
+    ACKCISHORT(CI_AUTHTYPE, !go->neg_eap && !go->neg_chap && go->neg_upap, PPP_PAP);
+#endif /* EAP_SUPPORT && CHAP_SUPPORT */
+#if EAP_SUPPORT && !CHAP_SUPPORT
+    ACKCISHORT(CI_AUTHTYPE, !go->neg_eap && go->neg_upap, PPP_PAP);
+#endif /* EAP_SUPPORT && !CHAP_SUPPORT */
+#if !EAP_SUPPORT && CHAP_SUPPORT
+    ACKCISHORT(CI_AUTHTYPE, !go->neg_chap && go->neg_upap, PPP_PAP);
+#endif /* !EAP_SUPPORT && CHAP_SUPPORT */
+#if !EAP_SUPPORT && !CHAP_SUPPORT
+    ACKCISHORT(CI_AUTHTYPE, go->neg_upap, PPP_PAP);
+#endif /* !EAP_SUPPORT && !CHAP_SUPPORT */
+#endif /* PAP_SUPPORT */
+#if LQR_SUPPORT
+    ACKCILQR(CI_QUALITY, go->neg_lqr, go->lqr_period);
+#endif /* LQR_SUPPORT */
+    ACKCICHAR(CI_CALLBACK, go->neg_cbcp, CBCP_OPT);
+    ACKCILONG(CI_MAGICNUMBER, go->neg_magicnumber, go->magicnumber);
+    ACKCIVOID(CI_PCOMPRESSION, go->neg_pcompression);
+    ACKCIVOID(CI_ACCOMPRESSION, go->neg_accompression);
+#ifdef HAVE_MULTILINK
+    ACKCISHORT(CI_MRRU, go->neg_mrru, go->mrru);
+#endif /* HAVE_MULTILINK */
+    ACKCIVOID(CI_SSNHF, go->neg_ssnhf);
+    ACKCIENDP(CI_EPDISC, go->neg_endpoint, go->endpoint.class_,
+	      go->endpoint.value, go->endpoint.length);
+
+    /*
+     * If there are any remaining CIs, then this packet is bad.
+     */
+    if (len != 0)
+	goto bad;
+    return (1);
+bad:
+    LCPDEBUG(("lcp_acki: received bad Ack!"));
+    return (0);
+}
+
+
+/*
+ * lcp_nakci - Peer has sent a NAK for some of our CIs.
+ * This should not modify any state if the Nak is bad
+ * or if LCP is in the OPENED state.
+ *
+ * Returns:
+ *	0 - Nak was bad.
+ *	1 - Nak was good.
+ */
+static int lcp_nakci(fsm *f, u_char *p, int len, int treat_as_reject) {
+    ppp_pcb *pcb = f->pcb;
+    lcp_options *go = &pcb->lcp_gotoptions;
+    lcp_options *wo = &pcb->lcp_wantoptions;
+    u_char citype, cichar, *next;
+    u_short cishort;
+    u32_t cilong;
+    lcp_options no;		/* options we've seen Naks for */
+    lcp_options try_;		/* options to request next time */
+    int looped_back = 0;
+    int cilen;
+
+    BZERO(&no, sizeof(no));
+    try_ = *go;
+
+    /*
+     * Any Nak'd CIs must be in exactly the same order that we sent.
+     * Check packet length and CI length at each step.
+     * If we find any deviations, then this packet is bad.
+     */
+#define NAKCIVOID(opt, neg) \
+    if (go->neg && \
+	len >= CILEN_VOID && \
+	p[1] == CILEN_VOID && \
+	p[0] == opt) { \
+	len -= CILEN_VOID; \
+	INCPTR(CILEN_VOID, p); \
+	no.neg = 1; \
+	try_.neg = 0; \
+    }
+#if CHAP_SUPPORT
+#define NAKCICHAP(opt, neg, code) \
+    if (go->neg && \
+	len >= CILEN_CHAP && \
+	p[1] == CILEN_CHAP && \
+	p[0] == opt) { \
+	len -= CILEN_CHAP; \
+	INCPTR(2, p); \
+	GETSHORT(cishort, p); \
+	GETCHAR(cichar, p); \
+	no.neg = 1; \
+	code \
+    }
+#endif /* CHAP_SUPPORT */
+#define NAKCICHAR(opt, neg, code) \
+    if (go->neg && \
+	len >= CILEN_CHAR && \
+	p[1] == CILEN_CHAR && \
+	p[0] == opt) { \
+	len -= CILEN_CHAR; \
+	INCPTR(2, p); \
+	GETCHAR(cichar, p); \
+	no.neg = 1; \
+	code \
+    }
+#define NAKCISHORT(opt, neg, code) \
+    if (go->neg && \
+	len >= CILEN_SHORT && \
+	p[1] == CILEN_SHORT && \
+	p[0] == opt) { \
+	len -= CILEN_SHORT; \
+	INCPTR(2, p); \
+	GETSHORT(cishort, p); \
+	no.neg = 1; \
+	code \
+    }
+#define NAKCILONG(opt, neg, code) \
+    if (go->neg && \
+	len >= CILEN_LONG && \
+	p[1] == CILEN_LONG && \
+	p[0] == opt) { \
+	len -= CILEN_LONG; \
+	INCPTR(2, p); \
+	GETLONG(cilong, p); \
+	no.neg = 1; \
+	code \
+    }
+#if LQR_SUPPORT
+#define NAKCILQR(opt, neg, code) \
+    if (go->neg && \
+	len >= CILEN_LQR && \
+	p[1] == CILEN_LQR && \
+	p[0] == opt) { \
+	len -= CILEN_LQR; \
+	INCPTR(2, p); \
+	GETSHORT(cishort, p); \
+	GETLONG(cilong, p); \
+	no.neg = 1; \
+	code \
+    }
+#endif /* LQR_SUPPORT */
+#define NAKCIENDP(opt, neg) \
+    if (go->neg && \
+	len >= CILEN_CHAR && \
+	p[0] == opt && \
+	p[1] >= CILEN_CHAR && \
+	p[1] <= len) { \
+	len -= p[1]; \
+	INCPTR(p[1], p); \
+	no.neg = 1; \
+	try_.neg = 0; \
+    }
+
+    /*
+     * NOTE!  There must be no assignments to individual fields of *go in
+     * the code below.  Any such assignment is a BUG!
+     */
+    /*
+     * We don't care if they want to send us smaller packets than
+     * we want.  Therefore, accept any MRU less than what we asked for,
+     * but then ignore the new value when setting the MRU in the kernel.
+     * If they send us a bigger MRU than what we asked, accept it, up to
+     * the limit of the default MRU we'd get if we didn't negotiate.
+     */
+    if (go->neg_mru && go->mru != PPP_DEFMRU) {
+	NAKCISHORT(CI_MRU, neg_mru,
+		   if (cishort <= wo->mru || cishort <= PPP_DEFMRU)
+		       try_.mru = cishort;
+		   );
+    }
+
+    /*
+     * Add any characters they want to our (receive-side) asyncmap.
+     */
+    if (go->neg_asyncmap && go->asyncmap != 0xFFFFFFFF) {
+	NAKCILONG(CI_ASYNCMAP, neg_asyncmap,
+		  try_.asyncmap = go->asyncmap | cilong;
+		  );
+    }
+
+    /*
+     * If they've nak'd our authentication-protocol, check whether
+     * they are proposing a different protocol, or a different
+     * hash algorithm for CHAP.
+     */
+    if ((0
+#if CHAP_SUPPORT
+        || go->neg_chap
+#endif /* CHAP_SUPPORT */
+#if PAP_SUPPORT
+        || go->neg_upap
+#endif /* PAP_SUPPORT */
+#if EAP_SUPPORT
+        || go->neg_eap
+#endif /* EAP_SUPPORT */
+        )
+	&& len >= CILEN_SHORT
+	&& p[0] == CI_AUTHTYPE && p[1] >= CILEN_SHORT && p[1] <= len) {
+	cilen = p[1];
+	len -= cilen;
+#if CHAP_SUPPORT
+	no.neg_chap = go->neg_chap;
+#endif /* CHAP_SUPPORT */
+#if PAP_SUPPORT
+	no.neg_upap = go->neg_upap;
+#endif /* PAP_SUPPORT */
+#if EAP_SUPPORT
+	no.neg_eap = go->neg_eap;
+#endif /* EAP_SUPPORT */
+	INCPTR(2, p);
+	GETSHORT(cishort, p);
+
+#if PAP_SUPPORT
+	if (cishort == PPP_PAP && cilen == CILEN_SHORT) {
+#if EAP_SUPPORT
+	    /* If we were asking for EAP, then we need to stop that. */
+	    if (go->neg_eap)
+		try_.neg_eap = 0;
+	    else
+#endif /* EAP_SUPPORT */
+
+#if CHAP_SUPPORT
+	    /* If we were asking for CHAP, then we need to stop that. */
+	    if (go->neg_chap)
+		try_.neg_chap = 0;
+	    else
+#endif /* CHAP_SUPPORT */
+
+	    /*
+	     * If we weren't asking for CHAP or EAP, then we were asking for
+	     * PAP, in which case this Nak is bad.
+	     */
+		goto bad;
+	} else
+#endif /* PAP_SUPPORT */
+
+#if CHAP_SUPPORT
+	if (cishort == PPP_CHAP && cilen == CILEN_CHAP) {
+	    GETCHAR(cichar, p);
+#if EAP_SUPPORT
+	    /* Stop asking for EAP, if we were. */
+	    if (go->neg_eap) {
+		try_.neg_eap = 0;
+		/* Try to set up to use their suggestion, if possible */
+		if (CHAP_CANDIGEST(go->chap_mdtype, cichar))
+		    try_.chap_mdtype = CHAP_MDTYPE_D(cichar);
+	    } else
+#endif /* EAP_SUPPORT */
+	    if (go->neg_chap) {
+		/*
+		 * We were asking for our preferred algorithm, they must
+		 * want something different.
+		 */
+		if (cichar != CHAP_DIGEST(go->chap_mdtype)) {
+		    if (CHAP_CANDIGEST(go->chap_mdtype, cichar)) {
+			/* Use their suggestion if we support it ... */
+			try_.chap_mdtype = CHAP_MDTYPE_D(cichar);
+		    } else {
+			/* ... otherwise, try our next-preferred algorithm. */
+			try_.chap_mdtype &= ~(CHAP_MDTYPE(try_.chap_mdtype));
+			if (try_.chap_mdtype == MDTYPE_NONE) /* out of algos */
+			    try_.neg_chap = 0;
+		    }
+		} else {
+		    /*
+		     * Whoops, they Nak'd our algorithm of choice
+		     * but then suggested it back to us.
+		     */
+		    goto bad;
+		}
+	    } else {
+		/*
+		 * Stop asking for PAP if we were asking for it.
+		 */
+#if PAP_SUPPORT
+		try_.neg_upap = 0;
+#endif /* PAP_SUPPORT */
+	    }
+
+	} else
+#endif /* CHAP_SUPPORT */
+	{
+
+#if EAP_SUPPORT
+	    /*
+	     * If we were asking for EAP, and they're Conf-Naking EAP,
+	     * well, that's just strange.  Nobody should do that.
+	     */
+	    if (cishort == PPP_EAP && cilen == CILEN_SHORT && go->neg_eap)
+		ppp_dbglog("Unexpected Conf-Nak for EAP");
+
+	    /*
+	     * We don't recognize what they're suggesting.
+	     * Stop asking for what we were asking for.
+	     */
+	    if (go->neg_eap)
+		try_.neg_eap = 0;
+	    else
+#endif /* EAP_SUPPORT */
+
+#if CHAP_SUPPORT
+	    if (go->neg_chap)
+		try_.neg_chap = 0;
+	    else
+#endif /* CHAP_SUPPORT */
+
+#if PAP_SUPPORT
+	    if(1)
+		try_.neg_upap = 0;
+	    else
+#endif /* PAP_SUPPORT */
+	    {}
+
+	    p += cilen - CILEN_SHORT;
+	}
+    }
+
+#if LQR_SUPPORT
+    /*
+     * If they can't cope with our link quality protocol, we'll have
+     * to stop asking for LQR.  We haven't got any other protocol.
+     * If they Nak the reporting period, take their value XXX ?
+     */
+    NAKCILQR(CI_QUALITY, neg_lqr,
+	     if (cishort != PPP_LQR)
+		 try_.neg_lqr = 0;
+	     else
+		 try_.lqr_period = cilong;
+	     );
+#endif /* LQR_SUPPORT */
+
+    /*
+     * Only implementing CBCP...not the rest of the callback options
+     */
+    NAKCICHAR(CI_CALLBACK, neg_cbcp,
+              try_.neg_cbcp = 0;
+              (void)cichar; /* if CHAP support is not compiled, cichar is set but not used, which makes some compilers complaining */
+              );
+
+    /*
+     * Check for a looped-back line.
+     */
+    NAKCILONG(CI_MAGICNUMBER, neg_magicnumber,
+	      try_.magicnumber = magic();
+	      looped_back = 1;
+	      );
+
+    /*
+     * Peer shouldn't send Nak for protocol compression or
+     * address/control compression requests; they should send
+     * a Reject instead.  If they send a Nak, treat it as a Reject.
+     */
+    NAKCIVOID(CI_PCOMPRESSION, neg_pcompression);
+    NAKCIVOID(CI_ACCOMPRESSION, neg_accompression);
+
+#ifdef HAVE_MULTILINK
+    /*
+     * Nak for MRRU option - accept their value if it is smaller
+     * than the one we want.
+     */
+    if (go->neg_mrru) {
+	NAKCISHORT(CI_MRRU, neg_mrru,
+		   if (treat_as_reject)
+		       try_.neg_mrru = 0;
+		   else if (cishort <= wo->mrru)
+		       try_.mrru = cishort;
+		   );
+    }
+#else /* HAVE_MULTILINK */
+    LWIP_UNUSED_ARG(treat_as_reject);
+#endif /* HAVE_MULTILINK */
+
+    /*
+     * Nak for short sequence numbers shouldn't be sent, treat it
+     * like a reject.
+     */
+    NAKCIVOID(CI_SSNHF, neg_ssnhf);
+
+    /*
+     * Nak of the endpoint discriminator option is not permitted,
+     * treat it like a reject.
+     */
+    NAKCIENDP(CI_EPDISC, neg_endpoint);
+
+    /*
+     * There may be remaining CIs, if the peer is requesting negotiation
+     * on an option that we didn't include in our request packet.
+     * If we see an option that we requested, or one we've already seen
+     * in this packet, then this packet is bad.
+     * If we wanted to respond by starting to negotiate on the requested
+     * option(s), we could, but we don't, because except for the
+     * authentication type and quality protocol, if we are not negotiating
+     * an option, it is because we were told not to.
+     * For the authentication type, the Nak from the peer means
+     * `let me authenticate myself with you' which is a bit pointless.
+     * For the quality protocol, the Nak means `ask me to send you quality
+     * reports', but if we didn't ask for them, we don't want them.
+     * An option we don't recognize represents the peer asking to
+     * negotiate some option we don't support, so ignore it.
+     */
+    while (len >= CILEN_VOID) {
+	GETCHAR(citype, p);
+	GETCHAR(cilen, p);
+	if (cilen < CILEN_VOID || (len -= cilen) < 0)
+	    goto bad;
+	next = p + cilen - 2;
+
+	switch (citype) {
+	case CI_MRU:
+	    if ((go->neg_mru && go->mru != PPP_DEFMRU)
+		|| no.neg_mru || cilen != CILEN_SHORT)
+		goto bad;
+	    GETSHORT(cishort, p);
+	    if (cishort < PPP_DEFMRU) {
+		try_.neg_mru = 1;
+		try_.mru = cishort;
+	    }
+	    break;
+	case CI_ASYNCMAP:
+	    if ((go->neg_asyncmap && go->asyncmap != 0xFFFFFFFF)
+		|| no.neg_asyncmap || cilen != CILEN_LONG)
+		goto bad;
+	    break;
+	case CI_AUTHTYPE:
+	    if (0
+#if CHAP_SUPPORT
+                || go->neg_chap || no.neg_chap
+#endif /* CHAP_SUPPORT */
+#if PAP_SUPPORT
+                || go->neg_upap || no.neg_upap
+#endif /* PAP_SUPPORT */
+#if EAP_SUPPORT
+		|| go->neg_eap || no.neg_eap
+#endif /* EAP_SUPPORT */
+		)
+		goto bad;
+	    break;
+	case CI_MAGICNUMBER:
+	    if (go->neg_magicnumber || no.neg_magicnumber ||
+		cilen != CILEN_LONG)
+		goto bad;
+	    break;
+	case CI_PCOMPRESSION:
+	    if (go->neg_pcompression || no.neg_pcompression
+		|| cilen != CILEN_VOID)
+		goto bad;
+	    break;
+	case CI_ACCOMPRESSION:
+	    if (go->neg_accompression || no.neg_accompression
+		|| cilen != CILEN_VOID)
+		goto bad;
+	    break;
+#if LQR_SUPPORT
+	case CI_QUALITY:
+	    if (go->neg_lqr || no.neg_lqr || cilen != CILEN_LQR)
+		goto bad;
+	    break;
+#endif /* LQR_SUPPORT */
+#ifdef HAVE_MULTILINK
+	case CI_MRRU:
+	    if (go->neg_mrru || no.neg_mrru || cilen != CILEN_SHORT)
+		goto bad;
+	    break;
+#endif /* HAVE_MULTILINK */
+	case CI_SSNHF:
+	    if (go->neg_ssnhf || no.neg_ssnhf || cilen != CILEN_VOID)
+		goto bad;
+	    try_.neg_ssnhf = 1;
+	    break;
+	case CI_EPDISC:
+	    if (go->neg_endpoint || no.neg_endpoint || cilen < CILEN_CHAR)
+		goto bad;
+	    break;
+	default:
+	    break;
+	}
+	p = next;
+    }
+
+    /*
+     * OK, the Nak is good.  Now we can update state.
+     * If there are any options left we ignore them.
+     */
+    if (f->state != PPP_FSM_OPENED) {
+	if (looped_back) {
+	    if (++try_.numloops >= pcb->settings.lcp_loopbackfail) {
+		ppp_notice("Serial line is looped back.");
+		pcb->err_code = PPPERR_LOOPBACK;
+		lcp_close(f->pcb, "Loopback detected");
+	    }
+	} else
+	    try_.numloops = 0;
+	*go = try_;
+    }
+
+    return 1;
+
+bad:
+    LCPDEBUG(("lcp_nakci: received bad Nak!"));
+    return 0;
+}
+
+
+/*
+ * lcp_rejci - Peer has Rejected some of our CIs.
+ * This should not modify any state if the Reject is bad
+ * or if LCP is in the OPENED state.
+ *
+ * Returns:
+ *	0 - Reject was bad.
+ *	1 - Reject was good.
+ */
+static int lcp_rejci(fsm *f, u_char *p, int len) {
+    ppp_pcb *pcb = f->pcb;
+    lcp_options *go = &pcb->lcp_gotoptions;
+    u_char cichar;
+    u_short cishort;
+    u32_t cilong;
+    lcp_options try_;		/* options to request next time */
+
+    try_ = *go;
+
+    /*
+     * Any Rejected CIs must be in exactly the same order that we sent.
+     * Check packet length and CI length at each step.
+     * If we find any deviations, then this packet is bad.
+     */
+#define REJCIVOID(opt, neg) \
+    if (go->neg && \
+	len >= CILEN_VOID && \
+	p[1] == CILEN_VOID && \
+	p[0] == opt) { \
+	len -= CILEN_VOID; \
+	INCPTR(CILEN_VOID, p); \
+	try_.neg = 0; \
+    }
+#define REJCISHORT(opt, neg, val) \
+    if (go->neg && \
+	len >= CILEN_SHORT && \
+	p[1] == CILEN_SHORT && \
+	p[0] == opt) { \
+	len -= CILEN_SHORT; \
+	INCPTR(2, p); \
+	GETSHORT(cishort, p); \
+	/* Check rejected value. */ \
+	if (cishort != val) \
+	    goto bad; \
+	try_.neg = 0; \
+    }
+
+#if CHAP_SUPPORT && EAP_SUPPORT && PAP_SUPPORT
+#define REJCICHAP(opt, neg, val) \
+    if (go->neg && \
+	len >= CILEN_CHAP && \
+	p[1] == CILEN_CHAP && \
+	p[0] == opt) { \
+	len -= CILEN_CHAP; \
+	INCPTR(2, p); \
+	GETSHORT(cishort, p); \
+	GETCHAR(cichar, p); \
+	/* Check rejected value. */ \
+	if ((cishort != PPP_CHAP) || (cichar != (CHAP_DIGEST(val)))) \
+	    goto bad; \
+	try_.neg = 0; \
+	try_.neg_eap = try_.neg_upap = 0; \
+    }
+#endif /* CHAP_SUPPORT && EAP_SUPPORT && PAP_SUPPORT */
+
+#if CHAP_SUPPORT && !EAP_SUPPORT && PAP_SUPPORT
+#define REJCICHAP(opt, neg, val) \
+    if (go->neg && \
+	len >= CILEN_CHAP && \
+	p[1] == CILEN_CHAP && \
+	p[0] == opt) { \
+	len -= CILEN_CHAP; \
+	INCPTR(2, p); \
+	GETSHORT(cishort, p); \
+	GETCHAR(cichar, p); \
+	/* Check rejected value. */ \
+	if ((cishort != PPP_CHAP) || (cichar != (CHAP_DIGEST(val)))) \
+	    goto bad; \
+	try_.neg = 0; \
+	try_.neg_upap = 0; \
+    }
+#endif /* CHAP_SUPPORT && !EAP_SUPPORT && PAP_SUPPORT */
+
+#if CHAP_SUPPORT && EAP_SUPPORT && !PAP_SUPPORT
+#define REJCICHAP(opt, neg, val) \
+    if (go->neg && \
+	len >= CILEN_CHAP && \
+	p[1] == CILEN_CHAP && \
+	p[0] == opt) { \
+	len -= CILEN_CHAP; \
+	INCPTR(2, p); \
+	GETSHORT(cishort, p); \
+	GETCHAR(cichar, p); \
+	/* Check rejected value. */ \
+	if ((cishort != PPP_CHAP) || (cichar != (CHAP_DIGEST(val)))) \
+	    goto bad; \
+	try_.neg = 0; \
+	try_.neg_eap = 0; \
+    }
+#endif /* CHAP_SUPPORT && EAP_SUPPORT && !PAP_SUPPORT */
+
+#if CHAP_SUPPORT && !EAP_SUPPORT && !PAP_SUPPORT
+#define REJCICHAP(opt, neg, val) \
+    if (go->neg && \
+	len >= CILEN_CHAP && \
+	p[1] == CILEN_CHAP && \
+	p[0] == opt) { \
+	len -= CILEN_CHAP; \
+	INCPTR(2, p); \
+	GETSHORT(cishort, p); \
+	GETCHAR(cichar, p); \
+	/* Check rejected value. */ \
+	if ((cishort != PPP_CHAP) || (cichar != (CHAP_DIGEST(val)))) \
+	    goto bad; \
+	try_.neg = 0; \
+    }
+#endif /* CHAP_SUPPORT && !EAP_SUPPORT && !PAP_SUPPORT */
+
+#define REJCILONG(opt, neg, val) \
+    if (go->neg && \
+	len >= CILEN_LONG && \
+	p[1] == CILEN_LONG && \
+	p[0] == opt) { \
+	len -= CILEN_LONG; \
+	INCPTR(2, p); \
+	GETLONG(cilong, p); \
+	/* Check rejected value. */ \
+	if (cilong != val) \
+	    goto bad; \
+	try_.neg = 0; \
+    }
+#if LQR_SUPPORT
+#define REJCILQR(opt, neg, val) \
+    if (go->neg && \
+	len >= CILEN_LQR && \
+	p[1] == CILEN_LQR && \
+	p[0] == opt) { \
+	len -= CILEN_LQR; \
+	INCPTR(2, p); \
+	GETSHORT(cishort, p); \
+	GETLONG(cilong, p); \
+	/* Check rejected value. */ \
+	if (cishort != PPP_LQR || cilong != val) \
+	    goto bad; \
+	try_.neg = 0; \
+    }
+#endif /* LQR_SUPPORT */
+#define REJCICBCP(opt, neg, val) \
+    if (go->neg && \
+	len >= CILEN_CBCP && \
+	p[1] == CILEN_CBCP && \
+	p[0] == opt) { \
+	len -= CILEN_CBCP; \
+	INCPTR(2, p); \
+	GETCHAR(cichar, p); \
+	/* Check rejected value. */ \
+	if (cichar != val) \
+	    goto bad; \
+	try_.neg = 0; \
+    }
+#define REJCIENDP(opt, neg, class, val, vlen) \
+    if (go->neg && \
+	len >= CILEN_CHAR + vlen && \
+	p[0] == opt && \
+	p[1] == CILEN_CHAR + vlen) { \
+	int i; \
+	len -= CILEN_CHAR + vlen; \
+	INCPTR(2, p); \
+	GETCHAR(cichar, p); \
+	if (cichar != class) \
+	    goto bad; \
+	for (i = 0; i < vlen; ++i) { \
+	    GETCHAR(cichar, p); \
+	    if (cichar != val[i]) \
+		goto bad; \
+	} \
+	try_.neg = 0; \
+    }
+
+    REJCISHORT(CI_MRU, neg_mru, go->mru);
+    REJCILONG(CI_ASYNCMAP, neg_asyncmap, go->asyncmap);
+#if EAP_SUPPORT
+    REJCISHORT(CI_AUTHTYPE, neg_eap, PPP_EAP);
+    if (!go->neg_eap) {
+#endif /* EAP_SUPPORT */
+#if CHAP_SUPPORT
+	REJCICHAP(CI_AUTHTYPE, neg_chap, go->chap_mdtype);
+	if (!go->neg_chap) {
+#endif /* CHAP_SUPPORT */
+#if PAP_SUPPORT
+	    REJCISHORT(CI_AUTHTYPE, neg_upap, PPP_PAP);
+#endif /* PAP_SUPPORT */
+#if CHAP_SUPPORT
+	}
+#endif /* CHAP_SUPPORT */
+#if EAP_SUPPORT
+    }
+#endif /* EAP_SUPPORT */
+#if LQR_SUPPORT
+    REJCILQR(CI_QUALITY, neg_lqr, go->lqr_period);
+#endif /* LQR_SUPPORT */
+    REJCICBCP(CI_CALLBACK, neg_cbcp, CBCP_OPT);
+    REJCILONG(CI_MAGICNUMBER, neg_magicnumber, go->magicnumber);
+    REJCIVOID(CI_PCOMPRESSION, neg_pcompression);
+    REJCIVOID(CI_ACCOMPRESSION, neg_accompression);
+#ifdef HAVE_MULTILINK
+    REJCISHORT(CI_MRRU, neg_mrru, go->mrru);
+#endif /* HAVE_MULTILINK */
+    REJCIVOID(CI_SSNHF, neg_ssnhf);
+    REJCIENDP(CI_EPDISC, neg_endpoint, go->endpoint.class_,
+	      go->endpoint.value, go->endpoint.length);
+
+    /*
+     * If there are any remaining CIs, then this packet is bad.
+     */
+    if (len != 0)
+	goto bad;
+    /*
+     * Now we can update state.
+     */
+    if (f->state != PPP_FSM_OPENED)
+	*go = try_;
+    return 1;
+
+bad:
+    LCPDEBUG(("lcp_rejci: received bad Reject!"));
+    return 0;
+}
+
+
+/*
+ * lcp_reqci - Check the peer's requested CIs and send appropriate response.
+ *
+ * Returns: CONFACK, CONFNAK or CONFREJ and input packet modified
+ * appropriately.  If reject_if_disagree is non-zero, doesn't return
+ * CONFNAK; returns CONFREJ if it can't return CONFACK.
+ *
+ * inp = Requested CIs
+ * lenp = Length of requested CIs
+ */
+static int lcp_reqci(fsm *f, u_char *inp, int *lenp, int reject_if_disagree) {
+    ppp_pcb *pcb = f->pcb;
+    lcp_options *go = &pcb->lcp_gotoptions;
+    lcp_options *ho = &pcb->lcp_hisoptions;
+    lcp_options *ao = &pcb->lcp_allowoptions;
+    u_char *cip, *next;		/* Pointer to current and next CIs */
+    int cilen, citype, cichar;	/* Parsed len, type, char value */
+    u_short cishort;		/* Parsed short value */
+    u32_t cilong;		/* Parse long value */
+    int rc = CONFACK;		/* Final packet return code */
+    int orc;			/* Individual option return code */
+    u_char *p;			/* Pointer to next char to parse */
+    u_char *rejp;		/* Pointer to next char in reject frame */
+    struct pbuf *nakp;          /* Nak buffer */
+    u_char *nakoutp;		/* Pointer to next char in Nak frame */
+    int l = *lenp;		/* Length left */
+
+    /*
+     * Reset all his options.
+     */
+    BZERO(ho, sizeof(*ho));
+
+    /*
+     * Process all his options.
+     */
+    next = inp;
+    nakp = pbuf_alloc(PBUF_RAW, (u16_t)(PPP_CTRL_PBUF_MAX_SIZE), PPP_CTRL_PBUF_TYPE);
+    if(NULL == nakp)
+        return 0;
+    if(nakp->tot_len != nakp->len) {
+        pbuf_free(nakp);
+        return 0;
+    }
+
+    nakoutp = (u_char*)nakp->payload;
+    rejp = inp;
+    while (l) {
+	orc = CONFACK;			/* Assume success */
+	cip = p = next;			/* Remember begining of CI */
+	if (l < 2 ||			/* Not enough data for CI header or */
+	    p[1] < 2 ||			/*  CI length too small or */
+	    p[1] > l) {			/*  CI length too big? */
+	    LCPDEBUG(("lcp_reqci: bad CI length!"));
+	    orc = CONFREJ;		/* Reject bad CI */
+	    cilen = l;			/* Reject till end of packet */
+	    l = 0;			/* Don't loop again */
+	    citype = 0;
+	    goto endswitch;
+	}
+	GETCHAR(citype, p);		/* Parse CI type */
+	GETCHAR(cilen, p);		/* Parse CI length */
+	l -= cilen;			/* Adjust remaining length */
+	next += cilen;			/* Step to next CI */
+
+	switch (citype) {		/* Check CI type */
+	case CI_MRU:
+	    if (!ao->neg_mru ||		/* Allow option? */
+		cilen != CILEN_SHORT) {	/* Check CI length */
+		orc = CONFREJ;		/* Reject CI */
+		break;
+	    }
+	    GETSHORT(cishort, p);	/* Parse MRU */
+
+	    /*
+	     * He must be able to receive at least our minimum.
+	     * No need to check a maximum.  If he sends a large number,
+	     * we'll just ignore it.
+	     */
+	    if (cishort < PPP_MINMRU) {
+		orc = CONFNAK;		/* Nak CI */
+		PUTCHAR(CI_MRU, nakoutp);
+		PUTCHAR(CILEN_SHORT, nakoutp);
+		PUTSHORT(PPP_MINMRU, nakoutp);	/* Give him a hint */
+		break;
+	    }
+	    ho->neg_mru = 1;		/* Remember he sent MRU */
+	    ho->mru = cishort;		/* And remember value */
+	    break;
+
+	case CI_ASYNCMAP:
+	    if (!ao->neg_asyncmap ||
+		cilen != CILEN_LONG) {
+		orc = CONFREJ;
+		break;
+	    }
+	    GETLONG(cilong, p);
+
+	    /*
+	     * Asyncmap must have set at least the bits
+	     * which are set in lcp_allowoptions[unit].asyncmap.
+	     */
+	    if ((ao->asyncmap & ~cilong) != 0) {
+		orc = CONFNAK;
+		PUTCHAR(CI_ASYNCMAP, nakoutp);
+		PUTCHAR(CILEN_LONG, nakoutp);
+		PUTLONG(ao->asyncmap | cilong, nakoutp);
+		break;
+	    }
+	    ho->neg_asyncmap = 1;
+	    ho->asyncmap = cilong;
+	    break;
+
+	case CI_AUTHTYPE:
+	    if (cilen < CILEN_SHORT ||
+		!(0
+#if PAP_SUPPORT
+		|| ao->neg_upap
+#endif /* PAP_SUPPORT */
+#if CHAP_SUPPORT
+		|| ao->neg_chap
+#endif /* CHAP_SUPPORT */
+#if EAP_SUPPORT
+		|| ao->neg_eap
+#endif /* EAP_SUPPORT */
+		)) {
+		/*
+		 * Reject the option if we're not willing to authenticate.
+		 */
+		ppp_dbglog("No auth is possible");
+		orc = CONFREJ;
+		break;
+	    }
+	    GETSHORT(cishort, p);
+
+	    /*
+	     * Authtype must be PAP, CHAP, or EAP.
+	     *
+	     * Note: if more than one of ao->neg_upap, ao->neg_chap, and
+	     * ao->neg_eap are set, and the peer sends a Configure-Request
+	     * with two or more authenticate-protocol requests, then we will
+	     * reject the second request.
+	     * Whether we end up doing CHAP, UPAP, or EAP depends then on
+	     * the ordering of the CIs in the peer's Configure-Request.
+             */
+
+#if PAP_SUPPORT
+	    if (cishort == PPP_PAP) {
+		/* we've already accepted CHAP or EAP */
+		if (0
+#if CHAP_SUPPORT
+		    || ho->neg_chap
+#endif /* CHAP_SUPPORT */
+#if EAP_SUPPORT
+		    || ho->neg_eap
+#endif /* EAP_SUPPORT */
+		    || cilen != CILEN_SHORT) {
+		    LCPDEBUG(("lcp_reqci: rcvd AUTHTYPE PAP, rejecting..."));
+		    orc = CONFREJ;
+		    break;
+		}
+		if (!ao->neg_upap) {	/* we don't want to do PAP */
+		    orc = CONFNAK;	/* NAK it and suggest CHAP or EAP */
+		    PUTCHAR(CI_AUTHTYPE, nakoutp);
+#if EAP_SUPPORT
+		    if (ao->neg_eap) {
+			PUTCHAR(CILEN_SHORT, nakoutp);
+			PUTSHORT(PPP_EAP, nakoutp);
+		    } else {
+#endif /* EAP_SUPPORT */
+#if CHAP_SUPPORT
+			PUTCHAR(CILEN_CHAP, nakoutp);
+			PUTSHORT(PPP_CHAP, nakoutp);
+			PUTCHAR(CHAP_DIGEST(ao->chap_mdtype), nakoutp);
+#endif /* CHAP_SUPPORT */
+#if EAP_SUPPORT
+		    }
+#endif /* EAP_SUPPORT */
+		    break;
+		}
+		ho->neg_upap = 1;
+		break;
+	    }
+#endif /* PAP_SUPPORT */
+#if CHAP_SUPPORT
+	    if (cishort == PPP_CHAP) {
+		/* we've already accepted PAP or EAP */
+		if (
+#if PAP_SUPPORT
+		    ho->neg_upap ||
+#endif /* PAP_SUPPORT */
+#if EAP_SUPPORT
+		    ho->neg_eap ||
+#endif /* EAP_SUPPORT */
+		    cilen != CILEN_CHAP) {
+		    LCPDEBUG(("lcp_reqci: rcvd AUTHTYPE CHAP, rejecting..."));
+		    orc = CONFREJ;
+		    break;
+		}
+		if (!ao->neg_chap) {	/* we don't want to do CHAP */
+		    orc = CONFNAK;	/* NAK it and suggest EAP or PAP */
+		    PUTCHAR(CI_AUTHTYPE, nakoutp);
+		    PUTCHAR(CILEN_SHORT, nakoutp);
+#if EAP_SUPPORT
+		    if (ao->neg_eap) {
+			PUTSHORT(PPP_EAP, nakoutp);
+		    } else
+#endif /* EAP_SUPPORT */
+#if PAP_SUPPORT
+		    if(1) {
+			PUTSHORT(PPP_PAP, nakoutp);
+		    }
+		    else
+#endif /* PAP_SUPPORT */
+		    {}
+		    break;
+		}
+		GETCHAR(cichar, p);	/* get digest type */
+		if (!(CHAP_CANDIGEST(ao->chap_mdtype, cichar))) {
+		    /*
+		     * We can't/won't do the requested type,
+		     * suggest something else.
+		     */
+		    orc = CONFNAK;
+		    PUTCHAR(CI_AUTHTYPE, nakoutp);
+		    PUTCHAR(CILEN_CHAP, nakoutp);
+		    PUTSHORT(PPP_CHAP, nakoutp);
+		    PUTCHAR(CHAP_DIGEST(ao->chap_mdtype), nakoutp);
+		    break;
+		}
+		ho->chap_mdtype = CHAP_MDTYPE_D(cichar); /* save md type */
+		ho->neg_chap = 1;
+		break;
+	    }
+#endif /* CHAP_SUPPORT */
+#if EAP_SUPPORT
+	    if (cishort == PPP_EAP) {
+		/* we've already accepted CHAP or PAP */
+		if (
+#if CHAP_SUPPORT
+		    ho->neg_chap ||
+#endif /* CHAP_SUPPORT */
+#if PAP_SUPPORT
+		    ho->neg_upap ||
+#endif /* PAP_SUPPORT */
+		    cilen != CILEN_SHORT) {
+		    LCPDEBUG(("lcp_reqci: rcvd AUTHTYPE EAP, rejecting..."));
+		    orc = CONFREJ;
+		    break;
+		}
+		if (!ao->neg_eap) {	/* we don't want to do EAP */
+		    orc = CONFNAK;	/* NAK it and suggest CHAP or PAP */
+		    PUTCHAR(CI_AUTHTYPE, nakoutp);
+#if CHAP_SUPPORT
+		    if (ao->neg_chap) {
+			PUTCHAR(CILEN_CHAP, nakoutp);
+			PUTSHORT(PPP_CHAP, nakoutp);
+			PUTCHAR(CHAP_DIGEST(ao->chap_mdtype), nakoutp);
+		    } else
+#endif /* CHAP_SUPPORT */
+#if PAP_SUPPORT
+		    if(1) {
+			PUTCHAR(CILEN_SHORT, nakoutp);
+			PUTSHORT(PPP_PAP, nakoutp);
+		    } else
+#endif /* PAP_SUPPORT */
+		    {}
+		    break;
+		}
+		ho->neg_eap = 1;
+		break;
+	    }
+#endif /* EAP_SUPPORT */
+
+	    /*
+	     * We don't recognize the protocol they're asking for.
+	     * Nak it with something we're willing to do.
+	     * (At this point we know ao->neg_upap || ao->neg_chap ||
+	     * ao->neg_eap.)
+	     */
+	    orc = CONFNAK;
+	    PUTCHAR(CI_AUTHTYPE, nakoutp);
+
+#if EAP_SUPPORT
+	    if (ao->neg_eap) {
+		PUTCHAR(CILEN_SHORT, nakoutp);
+		PUTSHORT(PPP_EAP, nakoutp);
+	    } else
+#endif /* EAP_SUPPORT */
+#if CHAP_SUPPORT
+	    if (ao->neg_chap) {
+		PUTCHAR(CILEN_CHAP, nakoutp);
+		PUTSHORT(PPP_CHAP, nakoutp);
+		PUTCHAR(CHAP_DIGEST(ao->chap_mdtype), nakoutp);
+	    } else
+#endif /* CHAP_SUPPORT */
+#if PAP_SUPPORT
+	    if(1) {
+		PUTCHAR(CILEN_SHORT, nakoutp);
+		PUTSHORT(PPP_PAP, nakoutp);
+	    } else
+#endif /* PAP_SUPPORT */
+	    {}
+	    break;
+
+#if LQR_SUPPORT
+	case CI_QUALITY:
+	    if (!ao->neg_lqr ||
+		cilen != CILEN_LQR) {
+		orc = CONFREJ;
+		break;
+	    }
+
+	    GETSHORT(cishort, p);
+	    GETLONG(cilong, p);
+
+	    /*
+	     * Check the protocol and the reporting period.
+	     * XXX When should we Nak this, and what with?
+	     */
+	    if (cishort != PPP_LQR) {
+		orc = CONFNAK;
+		PUTCHAR(CI_QUALITY, nakoutp);
+		PUTCHAR(CILEN_LQR, nakoutp);
+		PUTSHORT(PPP_LQR, nakoutp);
+		PUTLONG(ao->lqr_period, nakoutp);
+		break;
+	    }
+	    break;
+#endif /* LQR_SUPPORT */
+
+	case CI_MAGICNUMBER:
+	    if (!(ao->neg_magicnumber || go->neg_magicnumber) ||
+		cilen != CILEN_LONG) {
+		orc = CONFREJ;
+		break;
+	    }
+	    GETLONG(cilong, p);
+
+	    /*
+	     * He must have a different magic number.
+	     */
+	    if (go->neg_magicnumber &&
+		cilong == go->magicnumber) {
+		cilong = magic();	/* Don't put magic() inside macro! */
+		orc = CONFNAK;
+		PUTCHAR(CI_MAGICNUMBER, nakoutp);
+		PUTCHAR(CILEN_LONG, nakoutp);
+		PUTLONG(cilong, nakoutp);
+		break;
+	    }
+	    ho->neg_magicnumber = 1;
+	    ho->magicnumber = cilong;
+	    break;
+
+
+	case CI_PCOMPRESSION:
+	    if (!ao->neg_pcompression ||
+		cilen != CILEN_VOID) {
+		orc = CONFREJ;
+		break;
+	    }
+	    ho->neg_pcompression = 1;
+	    break;
+
+	case CI_ACCOMPRESSION:
+	    if (!ao->neg_accompression ||
+		cilen != CILEN_VOID) {
+		orc = CONFREJ;
+		break;
+	    }
+	    ho->neg_accompression = 1;
+	    break;
+
+#ifdef HAVE_MULTILINK
+	case CI_MRRU:
+	    if (!ao->neg_mrru
+		|| !multilink
+		|| cilen != CILEN_SHORT) {
+		orc = CONFREJ;
+		break;
+	    }
+
+	    GETSHORT(cishort, p);
+	    /* possibly should insist on a minimum/maximum MRRU here */
+	    ho->neg_mrru = 1;
+	    ho->mrru = cishort;
+	    break;
+#endif /* HAVE_MULTILINK */
+
+	case CI_SSNHF:
+	    if (!ao->neg_ssnhf
+#ifdef HAVE_MULTILINK
+		|| !multilink
+#endif /* HAVE_MULTILINK */
+		|| cilen != CILEN_VOID) {
+		orc = CONFREJ;
+		break;
+	    }
+	    ho->neg_ssnhf = 1;
+	    break;
+
+	case CI_EPDISC:
+	    if (!ao->neg_endpoint ||
+		cilen < CILEN_CHAR ||
+		cilen > CILEN_CHAR + MAX_ENDP_LEN) {
+		orc = CONFREJ;
+		break;
+	    }
+	    GETCHAR(cichar, p);
+	    cilen -= CILEN_CHAR;
+	    ho->neg_endpoint = 1;
+	    ho->endpoint.class_ = cichar;
+	    ho->endpoint.length = cilen;
+	    MEMCPY(ho->endpoint.value, p, cilen);
+	    INCPTR(cilen, p);
+	    break;
+
+	default:
+	    LCPDEBUG(("lcp_reqci: rcvd unknown option %d", citype));
+	    orc = CONFREJ;
+	    break;
+	}
+
+endswitch:
+	if (orc == CONFACK &&		/* Good CI */
+	    rc != CONFACK)		/*  but prior CI wasnt? */
+	    continue;			/* Don't send this one */
+
+	if (orc == CONFNAK) {		/* Nak this CI? */
+	    if (reject_if_disagree	/* Getting fed up with sending NAKs? */
+		&& citype != CI_MAGICNUMBER) {
+		orc = CONFREJ;		/* Get tough if so */
+	    } else {
+		if (rc == CONFREJ)	/* Rejecting prior CI? */
+		    continue;		/* Don't send this one */
+		rc = CONFNAK;
+	    }
+	}
+	if (orc == CONFREJ) {		/* Reject this CI */
+	    rc = CONFREJ;
+	    if (cip != rejp)		/* Need to move rejected CI? */
+		MEMCPY(rejp, cip, cilen); /* Move it */
+	    INCPTR(cilen, rejp);	/* Update output pointer */
+	}
+    }
+
+    /*
+     * If we wanted to send additional NAKs (for unsent CIs), the
+     * code would go here.  The extra NAKs would go at *nakoutp.
+     * At present there are no cases where we want to ask the
+     * peer to negotiate an option.
+     */
+
+    switch (rc) {
+    case CONFACK:
+	*lenp = next - inp;
+	break;
+    case CONFNAK:
+	/*
+	 * Copy the Nak'd options from the nak buffer to the caller's buffer.
+	 */
+	*lenp = nakoutp - (u_char*)nakp->payload;
+	MEMCPY(inp, nakp->payload, *lenp);
+	break;
+    case CONFREJ:
+	*lenp = rejp - inp;
+	break;
+    default:
+	break;
+    }
+
+    pbuf_free(nakp);
+    LCPDEBUG(("lcp_reqci: returning CONF%s.", CODENAME(rc)));
+    return (rc);			/* Return final code */
+}
+
+
+/*
+ * lcp_up - LCP has come UP.
+ */
+static void lcp_up(fsm *f) {
+    ppp_pcb *pcb = f->pcb;
+    lcp_options *wo = &pcb->lcp_wantoptions;
+    lcp_options *ho = &pcb->lcp_hisoptions;
+    lcp_options *go = &pcb->lcp_gotoptions;
+    lcp_options *ao = &pcb->lcp_allowoptions;
+    int mtu, mru;
+
+    if (!go->neg_magicnumber)
+	go->magicnumber = 0;
+    if (!ho->neg_magicnumber)
+	ho->magicnumber = 0;
+
+    /*
+     * Set our MTU to the smaller of the MTU we wanted and
+     * the MRU our peer wanted.  If we negotiated an MRU,
+     * set our MRU to the larger of value we wanted and
+     * the value we got in the negotiation.
+     * Note on the MTU: the link MTU can be the MRU the peer wanted,
+     * the interface MTU is set to the lowest of that, the
+     * MTU we want to use, and our link MRU.
+     */
+    mtu = ho->neg_mru? ho->mru: PPP_MRU;
+    mru = go->neg_mru? LWIP_MAX(wo->mru, go->mru): PPP_MRU;
+#ifdef HAVE_MULTILINK
+    if (!(multilink && go->neg_mrru && ho->neg_mrru))
+#endif /* HAVE_MULTILINK */
+	netif_set_mtu(pcb, LWIP_MIN(LWIP_MIN(mtu, mru), ao->mru));
+    ppp_send_config(pcb, mtu,
+		    (ho->neg_asyncmap? ho->asyncmap: 0xffffffff),
+		    ho->neg_pcompression, ho->neg_accompression);
+    ppp_recv_config(pcb, mru,
+		    (pcb->settings.lax_recv? 0: go->neg_asyncmap? go->asyncmap: 0xffffffff),
+		    go->neg_pcompression, go->neg_accompression);
+
+    if (ho->neg_mru)
+	pcb->peer_mru = ho->mru;
+
+    lcp_echo_lowerup(f->pcb);  /* Enable echo messages */
+
+    link_established(pcb);
+}
+
+
+/*
+ * lcp_down - LCP has gone DOWN.
+ *
+ * Alert other protocols.
+ */
+static void lcp_down(fsm *f) {
+    ppp_pcb *pcb = f->pcb;
+    lcp_options *go = &pcb->lcp_gotoptions;
+
+    lcp_echo_lowerdown(f->pcb);
+
+    link_down(pcb);
+
+    ppp_send_config(pcb, PPP_MRU, 0xffffffff, 0, 0);
+    ppp_recv_config(pcb, PPP_MRU,
+		    (go->neg_asyncmap? go->asyncmap: 0xffffffff),
+		    go->neg_pcompression, go->neg_accompression);
+    pcb->peer_mru = PPP_MRU;
+}
+
+
+/*
+ * lcp_starting - LCP needs the lower layer up.
+ */
+static void lcp_starting(fsm *f) {
+    ppp_pcb *pcb = f->pcb;
+    link_required(pcb);
+}
+
+
+/*
+ * lcp_finished - LCP has finished with the lower layer.
+ */
+static void lcp_finished(fsm *f) {
+    ppp_pcb *pcb = f->pcb;
+    link_terminated(pcb);
+}
+
+
+#if PRINTPKT_SUPPORT
+/*
+ * lcp_printpkt - print the contents of an LCP packet.
+ */
+static const char* const lcp_codenames[] = {
+    "ConfReq", "ConfAck", "ConfNak", "ConfRej",
+    "TermReq", "TermAck", "CodeRej", "ProtRej",
+    "EchoReq", "EchoRep", "DiscReq", "Ident",
+    "TimeRem"
+};
+
+static int lcp_printpkt(const u_char *p, int plen,
+		void (*printer) (void *, const char *, ...), void *arg) {
+    int code, id, len, olen, i;
+    const u_char *pstart, *optend;
+    u_short cishort;
+    u32_t cilong;
+
+    if (plen < HEADERLEN)
+	return 0;
+    pstart = p;
+    GETCHAR(code, p);
+    GETCHAR(id, p);
+    GETSHORT(len, p);
+    if (len < HEADERLEN || len > plen)
+	return 0;
+
+   if (code >= 1 && code <= (int)LWIP_ARRAYSIZE(lcp_codenames))
+	printer(arg, " %s", lcp_codenames[code-1]);
+    else
+	printer(arg, " code=0x%x", code);
+    printer(arg, " id=0x%x", id);
+    len -= HEADERLEN;
+    switch (code) {
+    case CONFREQ:
+    case CONFACK:
+    case CONFNAK:
+    case CONFREJ:
+	/* print option list */
+	while (len >= 2) {
+	    GETCHAR(code, p);
+	    GETCHAR(olen, p);
+	    p -= 2;
+	    if (olen < 2 || olen > len) {
+		break;
+	    }
+	    printer(arg, " <");
+	    len -= olen;
+	    optend = p + olen;
+	    switch (code) {
+	    case CI_MRU:
+		if (olen == CILEN_SHORT) {
+		    p += 2;
+		    GETSHORT(cishort, p);
+		    printer(arg, "mru %d", cishort);
+		}
+		break;
+	    case CI_ASYNCMAP:
+		if (olen == CILEN_LONG) {
+		    p += 2;
+		    GETLONG(cilong, p);
+		    printer(arg, "asyncmap 0x%x", cilong);
+		}
+		break;
+	    case CI_AUTHTYPE:
+		if (olen >= CILEN_SHORT) {
+		    p += 2;
+		    printer(arg, "auth ");
+		    GETSHORT(cishort, p);
+		    switch (cishort) {
+#if PAP_SUPPORT
+		    case PPP_PAP:
+			printer(arg, "pap");
+			break;
+#endif /* PAP_SUPPORT */
+#if CHAP_SUPPORT
+		    case PPP_CHAP:
+			printer(arg, "chap");
+			if (p < optend) {
+			    switch (*p) {
+			    case CHAP_MD5:
+				printer(arg, " MD5");
+				++p;
+				break;
+#if MSCHAP_SUPPORT
+			    case CHAP_MICROSOFT:
+				printer(arg, " MS");
+				++p;
+				break;
+
+			    case CHAP_MICROSOFT_V2:
+				printer(arg, " MS-v2");
+				++p;
+				break;
+#endif /* MSCHAP_SUPPORT */
+			    default:
+				break;
+			    }
+			}
+			break;
+#endif /* CHAP_SUPPORT */
+#if EAP_SUPPORT
+		    case PPP_EAP:
+			printer(arg, "eap");
+			break;
+#endif /* EAP_SUPPORT */
+		    default:
+			printer(arg, "0x%x", cishort);
+		    }
+		}
+		break;
+#if LQR_SUPPORT
+	    case CI_QUALITY:
+		if (olen >= CILEN_SHORT) {
+		    p += 2;
+		    printer(arg, "quality ");
+		    GETSHORT(cishort, p);
+		    switch (cishort) {
+		    case PPP_LQR:
+			printer(arg, "lqr");
+			break;
+		    default:
+			printer(arg, "0x%x", cishort);
+		    }
+		}
+		break;
+#endif /* LQR_SUPPORT */
+	    case CI_CALLBACK:
+		if (olen >= CILEN_CHAR) {
+		    p += 2;
+		    printer(arg, "callback ");
+		    GETCHAR(cishort, p);
+		    switch (cishort) {
+		    case CBCP_OPT:
+			printer(arg, "CBCP");
+			break;
+		    default:
+			printer(arg, "0x%x", cishort);
+		    }
+		}
+		break;
+	    case CI_MAGICNUMBER:
+		if (olen == CILEN_LONG) {
+		    p += 2;
+		    GETLONG(cilong, p);
+		    printer(arg, "magic 0x%x", cilong);
+		}
+		break;
+	    case CI_PCOMPRESSION:
+		if (olen == CILEN_VOID) {
+		    p += 2;
+		    printer(arg, "pcomp");
+		}
+		break;
+	    case CI_ACCOMPRESSION:
+		if (olen == CILEN_VOID) {
+		    p += 2;
+		    printer(arg, "accomp");
+		}
+		break;
+	    case CI_MRRU:
+		if (olen == CILEN_SHORT) {
+		    p += 2;
+		    GETSHORT(cishort, p);
+		    printer(arg, "mrru %d", cishort);
+		}
+		break;
+	    case CI_SSNHF:
+		if (olen == CILEN_VOID) {
+		    p += 2;
+		    printer(arg, "ssnhf");
+		}
+		break;
+	    case CI_EPDISC:
+#ifdef HAVE_MULTILINK
+		if (olen >= CILEN_CHAR) {
+		    struct epdisc epd;
+		    p += 2;
+		    GETCHAR(epd.class, p);
+		    epd.length = olen - CILEN_CHAR;
+		    if (epd.length > MAX_ENDP_LEN)
+			epd.length = MAX_ENDP_LEN;
+		    if (epd.length > 0) {
+			MEMCPY(epd.value, p, epd.length);
+			p += epd.length;
+		    }
+		    printer(arg, "endpoint [%s]", epdisc_to_str(&epd));
+		}
+#else
+		printer(arg, "endpoint");
+#endif
+		break;
+	    default:
+		break;
+	    }
+	    while (p < optend) {
+		GETCHAR(code, p);
+		printer(arg, " %.2x", code);
+	    }
+	    printer(arg, ">");
+	}
+	break;
+
+    case TERMACK:
+    case TERMREQ:
+	if (len > 0 && *p >= ' ' && *p < 0x7f) {
+	    printer(arg, " ");
+	    ppp_print_string(p, len, printer, arg);
+	    p += len;
+	    len = 0;
+	}
+	break;
+
+    case ECHOREQ:
+    case ECHOREP:
+    case DISCREQ:
+	if (len >= 4) {
+	    GETLONG(cilong, p);
+	    printer(arg, " magic=0x%x", cilong);
+	    len -= 4;
+	}
+	break;
+
+    case IDENTIF:
+    case TIMEREM:
+	if (len >= 4) {
+	    GETLONG(cilong, p);
+	    printer(arg, " magic=0x%x", cilong);
+	    len -= 4;
+	}
+	if (code == TIMEREM) {
+	    if (len < 4)
+		break;
+	    GETLONG(cilong, p);
+	    printer(arg, " seconds=%u", cilong);
+	    len -= 4;
+	}
+	if (len > 0) {
+	    printer(arg, " ");
+	    ppp_print_string(p, len, printer, arg);
+	    p += len;
+	    len = 0;
+	}
+	break;
+    default:
+	break;
+    }
+
+    /* print the rest of the bytes in the packet */
+    for (i = 0; i < len && i < 32; ++i) {
+	GETCHAR(code, p);
+	printer(arg, " %.2x", code);
+    }
+    if (i < len) {
+	printer(arg, " ...");
+	p += len - i;
+    }
+
+    return p - pstart;
+}
+#endif /* PRINTPKT_SUPPORT */
+
+/*
+ * Time to shut down the link because there is nothing out there.
+ */
+
+static void LcpLinkFailure(fsm *f) {
+    ppp_pcb *pcb = f->pcb;
+    if (f->state == PPP_FSM_OPENED) {
+	ppp_info("No response to %d echo-requests", pcb->lcp_echos_pending);
+        ppp_notice("Serial link appears to be disconnected.");
+	pcb->err_code = PPPERR_PEERDEAD;
+	lcp_close(pcb, "Peer not responding");
+    }
+}
+
+/*
+ * Timer expired for the LCP echo requests from this process.
+ */
+
+static void LcpEchoCheck(fsm *f) {
+    ppp_pcb *pcb = f->pcb;
+
+    LcpSendEchoRequest (f);
+    if (f->state != PPP_FSM_OPENED)
+	return;
+
+    /*
+     * Start the timer for the next interval.
+     */
+    if (pcb->lcp_echo_timer_running)
+	ppp_warn("assertion lcp_echo_timer_running==0 failed");
+    TIMEOUT (LcpEchoTimeout, f, pcb->settings.lcp_echo_interval);
+    pcb->lcp_echo_timer_running = 1;
+}
+
+/*
+ * LcpEchoTimeout - Timer expired on the LCP echo
+ */
+
+static void LcpEchoTimeout(void *arg) {
+    fsm *f = (fsm*)arg;
+    ppp_pcb *pcb = f->pcb;
+    if (pcb->lcp_echo_timer_running != 0) {
+        pcb->lcp_echo_timer_running = 0;
+        LcpEchoCheck ((fsm *) arg);
+    }
+}
+
+/*
+ * LcpEchoReply - LCP has received a reply to the echo
+ */
+
+static void lcp_received_echo_reply(fsm *f, int id, u_char *inp, int len) {
+    ppp_pcb *pcb = f->pcb;
+    lcp_options *go = &pcb->lcp_gotoptions;
+    u32_t magic_val;
+    LWIP_UNUSED_ARG(id);
+
+    /* Check the magic number - don't count replies from ourselves. */
+    if (len < 4) {
+	ppp_dbglog("lcp: received short Echo-Reply, length %d", len);
+	return;
+    }
+    GETLONG(magic_val, inp);
+    if (go->neg_magicnumber
+	&& magic_val == go->magicnumber) {
+	ppp_warn("appear to have received our own echo-reply!");
+	return;
+    }
+
+    /* Reset the number of outstanding echo frames */
+    pcb->lcp_echos_pending = 0;
+}
+
+/*
+ * LcpSendEchoRequest - Send an echo request frame to the peer
+ */
+
+static void LcpSendEchoRequest(fsm *f) {
+    ppp_pcb *pcb = f->pcb;
+    lcp_options *go = &pcb->lcp_gotoptions;
+    u32_t lcp_magic;
+    u_char pkt[4], *pktp;
+
+    /*
+     * Detect the failure of the peer at this point.
+     */
+    if (pcb->settings.lcp_echo_fails != 0) {
+        if (pcb->lcp_echos_pending >= pcb->settings.lcp_echo_fails) {
+            LcpLinkFailure(f);
+            pcb->lcp_echos_pending = 0;
+	}
+    }
+
+#if PPP_LCP_ADAPTIVE
+    /*
+     * If adaptive echos have been enabled, only send the echo request if
+     * no traffic was received since the last one.
+     */
+    if (pcb->settings.lcp_echo_adaptive) {
+	static unsigned int last_pkts_in = 0;
+
+#if PPP_STATS_SUPPORT
+	update_link_stats(f->unit);
+	link_stats_valid = 0;
+#endif /* PPP_STATS_SUPPORT */
+
+	if (link_stats.pkts_in != last_pkts_in) {
+	    last_pkts_in = link_stats.pkts_in;
+	    return;
+	}
+    }
+#endif
+
+    /*
+     * Make and send the echo request frame.
+     */
+    if (f->state == PPP_FSM_OPENED) {
+        lcp_magic = go->magicnumber;
+	pktp = pkt;
+	PUTLONG(lcp_magic, pktp);
+        fsm_sdata(f, ECHOREQ, pcb->lcp_echo_number++, pkt, pktp - pkt);
+	++pcb->lcp_echos_pending;
+    }
+}
+
+/*
+ * lcp_echo_lowerup - Start the timer for the LCP frame
+ */
+
+static void lcp_echo_lowerup(ppp_pcb *pcb) {
+    fsm *f = &pcb->lcp_fsm;
+
+    /* Clear the parameters for generating echo frames */
+    pcb->lcp_echos_pending      = 0;
+    pcb->lcp_echo_number        = 0;
+    pcb->lcp_echo_timer_running = 0;
+  
+    /* If a timeout interval is specified then start the timer */
+    if (pcb->settings.lcp_echo_interval != 0)
+        LcpEchoCheck (f);
+}
+
+/*
+ * lcp_echo_lowerdown - Stop the timer for the LCP frame
+ */
+
+static void lcp_echo_lowerdown(ppp_pcb *pcb) {
+    fsm *f = &pcb->lcp_fsm;
+
+    if (pcb->lcp_echo_timer_running != 0) {
+        UNTIMEOUT (LcpEchoTimeout, f);
+        pcb->lcp_echo_timer_running = 0;
+    }
+}
+
+#endif /* PPP_SUPPORT */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/netif/ppp/magic.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/netif/ppp/magic.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/netif/ppp/magic.c	(revision 457)
@@ -0,0 +1,294 @@
+/*
+ * magic.c - PPP Magic Number routines.
+ *
+ * Copyright (c) 1984-2000 Carnegie Mellon University. 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. The name "Carnegie Mellon University" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For permission or any legal
+ *    details, please contact
+ *      Office of Technology Transfer
+ *      Carnegie Mellon University
+ *      5000 Forbes Avenue
+ *      Pittsburgh, PA  15213-3890
+ *      (412) 268-4387, fax: (412) 268-7395
+ *      tech-transfer@andrew.cmu.edu
+ *
+ * 4. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by Computing Services
+ *     at Carnegie Mellon University (http://www.cmu.edu/computing/)."
+ *
+ * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO
+ * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE
+ * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
+ * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
+ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+/*****************************************************************************
+* randm.c - Random number generator program file.
+*
+* Copyright (c) 2003 by Marc Boucher, Services Informatiques (MBSI) inc.
+* Copyright (c) 1998 by Global Election Systems Inc.
+*
+* The authors hereby grant permission to use, copy, modify, distribute,
+* and license this software and its documentation for any purpose, provided
+* that existing copyright notices are retained in all copies and that this
+* notice and the following disclaimer are included verbatim in any
+* distributions. No written agreement, license, or royalty fee is required
+* for any of the authorized uses.
+*
+* THIS SOFTWARE IS PROVIDED BY THE 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 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.
+*
+******************************************************************************
+* REVISION HISTORY
+*
+* 03-01-01 Marc Boucher <marc@mbsi.ca>
+*   Ported to lwIP.
+* 98-06-03 Guy Lancaster <lancasterg@acm.org>, Global Election Systems Inc.
+*   Extracted from avos.
+*****************************************************************************/
+
+#include "netif/ppp/ppp_opts.h"
+#if PPP_SUPPORT /* don't build if not configured for use in lwipopts.h */
+
+#include "netif/ppp/ppp_impl.h"
+#include "netif/ppp/magic.h"
+
+#if PPP_MD5_RANDM /* Using MD5 for better randomness if enabled */
+
+#include "netif/ppp/pppcrypt.h"
+
+#define MD5_HASH_SIZE 16
+static char magic_randpool[MD5_HASH_SIZE];   /* Pool of randomness. */
+static long magic_randcount;      /* Pseudo-random incrementer */
+static u32_t magic_randomseed;    /* Seed used for random number generation. */
+
+/*
+ * Churn the randomness pool on a random event.  Call this early and often
+ *  on random and semi-random system events to build randomness in time for
+ *  usage.  For randomly timed events, pass a null pointer and a zero length
+ *  and this will use the system timer and other sources to add randomness.
+ *  If new random data is available, pass a pointer to that and it will be
+ *  included.
+ *
+ * Ref: Applied Cryptography 2nd Ed. by Bruce Schneier p. 427
+ */
+static void magic_churnrand(char *rand_data, u32_t rand_len) {
+  lwip_md5_context md5_ctx;
+
+  /* LWIP_DEBUGF(LOG_INFO, ("magic_churnrand: %u@%P\n", rand_len, rand_data)); */
+  lwip_md5_init(&md5_ctx);
+  lwip_md5_starts(&md5_ctx);
+  lwip_md5_update(&md5_ctx, (u_char *)magic_randpool, sizeof(magic_randpool));
+  if (rand_data) {
+    lwip_md5_update(&md5_ctx, (u_char *)rand_data, rand_len);
+  } else {
+    struct {
+      /* INCLUDE fields for any system sources of randomness */
+      u32_t jiffies;
+#ifdef LWIP_RAND
+      u32_t rand;
+#endif /* LWIP_RAND */
+    } sys_data;
+    magic_randomseed += sys_jiffies();
+    sys_data.jiffies = magic_randomseed;
+#ifdef LWIP_RAND
+    sys_data.rand = LWIP_RAND();
+#endif /* LWIP_RAND */
+    /* Load sys_data fields here. */
+    lwip_md5_update(&md5_ctx, (u_char *)&sys_data, sizeof(sys_data));
+  }
+  lwip_md5_finish(&md5_ctx, (u_char *)magic_randpool);
+  lwip_md5_free(&md5_ctx);
+/*  LWIP_DEBUGF(LOG_INFO, ("magic_churnrand: -> 0\n")); */
+}
+
+/*
+ * Initialize the random number generator.
+ */
+void magic_init(void) {
+  magic_churnrand(NULL, 0);
+}
+
+/*
+ * Randomize our random seed value.
+ */
+void magic_randomize(void) {
+  magic_churnrand(NULL, 0);
+}
+
+/*
+ * magic_random_bytes - Fill a buffer with random bytes.
+ *
+ * Use the random pool to generate random data.  This degrades to pseudo
+ *  random when used faster than randomness is supplied using magic_churnrand().
+ * Note: It's important that there be sufficient randomness in magic_randpool
+ *  before this is called for otherwise the range of the result may be
+ *  narrow enough to make a search feasible.
+ *
+ * Ref: Applied Cryptography 2nd Ed. by Bruce Schneier p. 427
+ *
+ * XXX Why does he not just call magic_churnrand() for each block?  Probably
+ *  so that you don't ever publish the seed which could possibly help
+ *  predict future values.
+ * XXX Why don't we preserve md5 between blocks and just update it with
+ *  magic_randcount each time?  Probably there is a weakness but I wish that
+ *  it was documented.
+ */
+void magic_random_bytes(unsigned char *buf, u32_t buf_len) {
+  lwip_md5_context md5_ctx;
+  u_char tmp[MD5_HASH_SIZE];
+  u32_t n;
+
+  while (buf_len > 0) {
+    lwip_md5_init(&md5_ctx);
+    lwip_md5_starts(&md5_ctx);
+    lwip_md5_update(&md5_ctx, (u_char *)magic_randpool, sizeof(magic_randpool));
+    lwip_md5_update(&md5_ctx, (u_char *)&magic_randcount, sizeof(magic_randcount));
+    lwip_md5_finish(&md5_ctx, tmp);
+    lwip_md5_free(&md5_ctx);
+    magic_randcount++;
+    n = LWIP_MIN(buf_len, MD5_HASH_SIZE);
+    MEMCPY(buf, tmp, n);
+    buf += n;
+    buf_len -= n;
+  }
+}
+
+/*
+ * Return a new random number.
+ */
+u32_t magic(void) {
+  u32_t new_rand;
+
+  magic_random_bytes((unsigned char *)&new_rand, sizeof(new_rand));
+
+  return new_rand;
+}
+
+#else /* PPP_MD5_RANDM */
+
+/*****************************/
+/*** LOCAL DATA STRUCTURES ***/
+/*****************************/
+#ifndef LWIP_RAND
+static int  magic_randomized;       /* Set when truely randomized. */
+#endif /* LWIP_RAND */
+static u32_t magic_randomseed;      /* Seed used for random number generation. */
+
+
+/***********************************/
+/*** PUBLIC FUNCTION DEFINITIONS ***/
+/***********************************/
+
+/*
+ * Initialize the random number generator.
+ *
+ * Here we attempt to compute a random number seed but even if
+ * it isn't random, we'll randomize it later.
+ *
+ * The current method uses the fields from the real time clock,
+ * the idle process counter, the millisecond counter, and the
+ * hardware timer tick counter.  When this is invoked
+ * in startup(), then the idle counter and timer values may
+ * repeat after each boot and the real time clock may not be
+ * operational.  Thus we call it again on the first random
+ * event.
+ */
+void magic_init(void) {
+  magic_randomseed += sys_jiffies();
+#ifndef LWIP_RAND
+  /* Initialize the Borland random number generator. */
+  srand((unsigned)magic_randomseed);
+#endif /* LWIP_RAND */
+}
+
+/*
+ * magic_init - Initialize the magic number generator.
+ *
+ * Randomize our random seed value.  Here we use the fact that
+ * this function is called at *truely random* times by the polling
+ * and network functions.  Here we only get 16 bits of new random
+ * value but we use the previous value to randomize the other 16
+ * bits.
+ */
+void magic_randomize(void) {
+#ifndef LWIP_RAND
+  if (!magic_randomized) {
+    magic_randomized = !0;
+    magic_init();
+    /* The initialization function also updates the seed. */
+  } else {
+#endif /* LWIP_RAND */
+    magic_randomseed += sys_jiffies();
+#ifndef LWIP_RAND
+  }
+#endif /* LWIP_RAND */
+}
+
+/*
+ * Return a new random number.
+ *
+ * Here we use the Borland rand() function to supply a pseudo random
+ * number which we make truely random by combining it with our own
+ * seed which is randomized by truely random events.
+ * Thus the numbers will be truely random unless there have been no
+ * operator or network events in which case it will be pseudo random
+ * seeded by the real time clock.
+ */
+u32_t magic(void) {
+#ifdef LWIP_RAND
+  return LWIP_RAND() + magic_randomseed;
+#else /* LWIP_RAND */
+  return ((u32_t)rand() << 16) + (u32_t)rand() + magic_randomseed;
+#endif /* LWIP_RAND */
+}
+
+/*
+ * magic_random_bytes - Fill a buffer with random bytes.
+ */
+void magic_random_bytes(unsigned char *buf, u32_t buf_len) {
+  u32_t new_rand, n;
+
+  while (buf_len > 0) {
+    new_rand = magic();
+    n = LWIP_MIN(buf_len, sizeof(new_rand));
+    MEMCPY(buf, &new_rand, n);
+    buf += n;
+    buf_len -= n;
+  }
+}
+#endif /* PPP_MD5_RANDM */
+
+/*
+ * Return a new random number between 0 and (2^pow)-1 included.
+ */
+u32_t magic_pow(u8_t pow) {
+  return magic() & ~(~0UL<<pow);
+}
+
+#endif /* PPP_SUPPORT */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/netif/ppp/mppe.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/netif/ppp/mppe.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/netif/ppp/mppe.c	(revision 457)
@@ -0,0 +1,412 @@
+/*
+ * mppe.c - interface MPPE to the PPP code.
+ *
+ * By Frank Cusack <fcusack@fcusack.com>.
+ * Copyright (c) 2002,2003,2004 Google, Inc.
+ * All rights reserved.
+ *
+ * License:
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation is hereby granted, provided that the above copyright
+ * notice appears in all copies.  This software is provided without any
+ * warranty, express or implied.
+ *
+ * Changelog:
+ *      08/12/05 - Matt Domsch <Matt_Domsch@dell.com>
+ *                 Only need extra skb padding on transmit, not receive.
+ *      06/18/04 - Matt Domsch <Matt_Domsch@dell.com>, Oleg Makarenko <mole@quadra.ru>
+ *                 Use Linux kernel 2.6 arc4 and sha1 routines rather than
+ *                 providing our own.
+ *      2/15/04 - TS: added #include <version.h> and testing for Kernel
+ *                    version before using
+ *                    MOD_DEC_USAGE_COUNT/MOD_INC_USAGE_COUNT which are
+ *                    deprecated in 2.6
+ */
+
+#include "netif/ppp/ppp_opts.h"
+#if PPP_SUPPORT && MPPE_SUPPORT  /* don't build if not configured for use in lwipopts.h */
+
+#include <string.h>
+
+#include "lwip/err.h"
+
+#include "netif/ppp/ppp_impl.h"
+#include "netif/ppp/ccp.h"
+#include "netif/ppp/mppe.h"
+#include "netif/ppp/pppdebug.h"
+#include "netif/ppp/pppcrypt.h"
+
+#define SHA1_SIGNATURE_SIZE 20
+
+/* ppp_mppe_state.bits definitions */
+#define MPPE_BIT_A	0x80	/* Encryption table were (re)inititalized */
+#define MPPE_BIT_B	0x40	/* MPPC only (not implemented) */
+#define MPPE_BIT_C	0x20	/* MPPC only (not implemented) */
+#define MPPE_BIT_D	0x10	/* This is an encrypted frame */
+
+#define MPPE_BIT_FLUSHED	MPPE_BIT_A
+#define MPPE_BIT_ENCRYPTED	MPPE_BIT_D
+
+#define MPPE_BITS(p) ((p)[0] & 0xf0)
+#define MPPE_CCOUNT(p) ((((p)[0] & 0x0f) << 8) + (p)[1])
+#define MPPE_CCOUNT_SPACE 0x1000	/* The size of the ccount space */
+
+#define MPPE_OVHD	2	/* MPPE overhead/packet */
+#define SANITY_MAX	1600	/* Max bogon factor we will tolerate */
+
+/*
+ * Perform the MPPE rekey algorithm, from RFC 3078, sec. 7.3.
+ * Well, not what's written there, but rather what they meant.
+ */
+static void mppe_rekey(ppp_mppe_state * state, int initial_key)
+{
+	lwip_sha1_context sha1_ctx;
+	u8_t sha1_digest[SHA1_SIGNATURE_SIZE];
+
+	/*
+	 * Key Derivation, from RFC 3078, RFC 3079.
+	 * Equivalent to Get_Key() for MS-CHAP as described in RFC 3079.
+	 */
+	lwip_sha1_init(&sha1_ctx);
+	lwip_sha1_starts(&sha1_ctx);
+	lwip_sha1_update(&sha1_ctx, state->master_key, state->keylen);
+	lwip_sha1_update(&sha1_ctx, mppe_sha1_pad1, SHA1_PAD_SIZE);
+	lwip_sha1_update(&sha1_ctx, state->session_key, state->keylen);
+	lwip_sha1_update(&sha1_ctx, mppe_sha1_pad2, SHA1_PAD_SIZE);
+	lwip_sha1_finish(&sha1_ctx, sha1_digest);
+	lwip_sha1_free(&sha1_ctx);
+	MEMCPY(state->session_key, sha1_digest, state->keylen);
+
+	if (!initial_key) {
+		lwip_arc4_init(&state->arc4);
+		lwip_arc4_setup(&state->arc4, sha1_digest, state->keylen);
+		lwip_arc4_crypt(&state->arc4, state->session_key, state->keylen);
+		lwip_arc4_free(&state->arc4);
+	}
+	if (state->keylen == 8) {
+		/* See RFC 3078 */
+		state->session_key[0] = 0xd1;
+		state->session_key[1] = 0x26;
+		state->session_key[2] = 0x9e;
+	}
+	lwip_arc4_init(&state->arc4);
+	lwip_arc4_setup(&state->arc4, state->session_key, state->keylen);
+}
+
+/*
+ * Set key, used by MSCHAP before mppe_init() is actually called by CCP so we
+ * don't have to keep multiple copies of keys.
+ */
+void mppe_set_key(ppp_pcb *pcb, ppp_mppe_state *state, u8_t *key) {
+	LWIP_UNUSED_ARG(pcb);
+	MEMCPY(state->master_key, key, MPPE_MAX_KEY_LEN);
+}
+
+/*
+ * Initialize (de)compressor state.
+ */
+void
+mppe_init(ppp_pcb *pcb, ppp_mppe_state *state, u8_t options)
+{
+#if PPP_DEBUG
+	const u8_t *debugstr = (const u8_t*)"mppe_comp_init";
+	if (&pcb->mppe_decomp == state) {
+	    debugstr = (const u8_t*)"mppe_decomp_init";
+	}
+#endif /* PPP_DEBUG */
+
+	/* Save keys. */
+	MEMCPY(state->session_key, state->master_key, sizeof(state->master_key));
+
+	if (options & MPPE_OPT_128)
+		state->keylen = 16;
+	else if (options & MPPE_OPT_40)
+		state->keylen = 8;
+	else {
+		PPPDEBUG(LOG_DEBUG, ("%s[%d]: unknown key length\n", debugstr,
+			pcb->netif->num));
+		lcp_close(pcb, "MPPE required but peer negotiation failed");
+		return;
+	}
+	if (options & MPPE_OPT_STATEFUL)
+		state->stateful = 1;
+
+	/* Generate the initial session key. */
+	mppe_rekey(state, 1);
+
+#if PPP_DEBUG
+	{
+		int i;
+		char mkey[sizeof(state->master_key) * 2 + 1];
+		char skey[sizeof(state->session_key) * 2 + 1];
+
+		PPPDEBUG(LOG_DEBUG, ("%s[%d]: initialized with %d-bit %s mode\n",
+		       debugstr, pcb->netif->num, (state->keylen == 16) ? 128 : 40,
+		       (state->stateful) ? "stateful" : "stateless"));
+
+		for (i = 0; i < (int)sizeof(state->master_key); i++)
+			sprintf(mkey + i * 2, "%02x", state->master_key[i]);
+		for (i = 0; i < (int)sizeof(state->session_key); i++)
+			sprintf(skey + i * 2, "%02x", state->session_key[i]);
+		PPPDEBUG(LOG_DEBUG,
+		       ("%s[%d]: keys: master: %s initial session: %s\n",
+		       debugstr, pcb->netif->num, mkey, skey));
+	}
+#endif /* PPP_DEBUG */
+
+	/*
+	 * Initialize the coherency count.  The initial value is not specified
+	 * in RFC 3078, but we can make a reasonable assumption that it will
+	 * start at 0.  Setting it to the max here makes the comp/decomp code
+	 * do the right thing (determined through experiment).
+	 */
+	state->ccount = MPPE_CCOUNT_SPACE - 1;
+
+	/*
+	 * Note that even though we have initialized the key table, we don't
+	 * set the FLUSHED bit.  This is contrary to RFC 3078, sec. 3.1.
+	 */
+	state->bits = MPPE_BIT_ENCRYPTED;
+}
+
+/*
+ * We received a CCP Reset-Request (actually, we are sending a Reset-Ack),
+ * tell the compressor to rekey.  Note that we MUST NOT rekey for
+ * every CCP Reset-Request; we only rekey on the next xmit packet.
+ * We might get multiple CCP Reset-Requests if our CCP Reset-Ack is lost.
+ * So, rekeying for every CCP Reset-Request is broken as the peer will not
+ * know how many times we've rekeyed.  (If we rekey and THEN get another
+ * CCP Reset-Request, we must rekey again.)
+ */
+void mppe_comp_reset(ppp_pcb *pcb, ppp_mppe_state *state)
+{
+	LWIP_UNUSED_ARG(pcb);
+	state->bits |= MPPE_BIT_FLUSHED;
+}
+
+/*
+ * Compress (encrypt) a packet.
+ * It's strange to call this a compressor, since the output is always
+ * MPPE_OVHD + 2 bytes larger than the input.
+ */
+err_t
+mppe_compress(ppp_pcb *pcb, ppp_mppe_state *state, struct pbuf **pb, u16_t protocol)
+{
+	struct pbuf *n, *np;
+	u8_t *pl;
+	err_t err;
+
+	LWIP_UNUSED_ARG(pcb);
+
+	/* TCP stack requires that we don't change the packet payload, therefore we copy
+	 * the whole packet before encryption.
+	 */
+	np = pbuf_alloc(PBUF_RAW, MPPE_OVHD + sizeof(protocol) + (*pb)->tot_len, PBUF_RAM);
+	if (!np) {
+		return ERR_MEM;
+	}
+
+	/* Hide MPPE header + protocol */
+	pbuf_remove_header(np, MPPE_OVHD + sizeof(protocol));
+
+	if ((err = pbuf_copy(np, *pb)) != ERR_OK) {
+		pbuf_free(np);
+		return err;
+	}
+
+	/* Reveal MPPE header + protocol */
+	pbuf_add_header(np, MPPE_OVHD + sizeof(protocol));
+
+	*pb = np;
+	pl = (u8_t*)np->payload;
+
+	state->ccount = (state->ccount + 1) % MPPE_CCOUNT_SPACE;
+	PPPDEBUG(LOG_DEBUG, ("mppe_compress[%d]: ccount %d\n", pcb->netif->num, state->ccount));
+	/* FIXME: use PUT* macros */
+	pl[0] = state->ccount>>8;
+	pl[1] = state->ccount;
+
+	if (!state->stateful ||	/* stateless mode     */
+	    ((state->ccount & 0xff) == 0xff) ||	/* "flag" packet      */
+	    (state->bits & MPPE_BIT_FLUSHED)) {	/* CCP Reset-Request  */
+		/* We must rekey */
+		if (state->stateful) {
+			PPPDEBUG(LOG_DEBUG, ("mppe_compress[%d]: rekeying\n", pcb->netif->num));
+		}
+		mppe_rekey(state, 0);
+		state->bits |= MPPE_BIT_FLUSHED;
+	}
+	pl[0] |= state->bits;
+	state->bits &= ~MPPE_BIT_FLUSHED;	/* reset for next xmit */
+	pl += MPPE_OVHD;
+
+	/* Add protocol */
+	/* FIXME: add PFC support */
+	pl[0] = protocol >> 8;
+	pl[1] = protocol;
+
+	/* Hide MPPE header */
+	pbuf_remove_header(np, MPPE_OVHD);
+
+	/* Encrypt packet */
+	for (n = np; n != NULL; n = n->next) {
+		lwip_arc4_crypt(&state->arc4, (u8_t*)n->payload, n->len);
+		if (n->tot_len == n->len) {
+			break;
+		}
+	}
+
+	/* Reveal MPPE header */
+	pbuf_add_header(np, MPPE_OVHD);
+
+	return ERR_OK;
+}
+
+/*
+ * We received a CCP Reset-Ack.  Just ignore it.
+ */
+void mppe_decomp_reset(ppp_pcb *pcb, ppp_mppe_state *state)
+{
+	LWIP_UNUSED_ARG(pcb);
+	LWIP_UNUSED_ARG(state);
+	return;
+}
+
+/*
+ * Decompress (decrypt) an MPPE packet.
+ */
+err_t
+mppe_decompress(ppp_pcb *pcb, ppp_mppe_state *state, struct pbuf **pb)
+{
+	struct pbuf *n0 = *pb, *n;
+	u8_t *pl;
+	u16_t ccount;
+	u8_t flushed;
+
+	/* MPPE Header */
+	if (n0->len < MPPE_OVHD) {
+		PPPDEBUG(LOG_DEBUG,
+		       ("mppe_decompress[%d]: short pkt (%d)\n",
+		       pcb->netif->num, n0->len));
+		state->sanity_errors += 100;
+		goto sanity_error;
+	}
+
+	pl = (u8_t*)n0->payload;
+	flushed = MPPE_BITS(pl) & MPPE_BIT_FLUSHED;
+	ccount = MPPE_CCOUNT(pl);
+	PPPDEBUG(LOG_DEBUG, ("mppe_decompress[%d]: ccount %d\n",
+	       pcb->netif->num, ccount));
+
+	/* sanity checks -- terminate with extreme prejudice */
+	if (!(MPPE_BITS(pl) & MPPE_BIT_ENCRYPTED)) {
+		PPPDEBUG(LOG_DEBUG,
+		       ("mppe_decompress[%d]: ENCRYPTED bit not set!\n",
+		       pcb->netif->num));
+		state->sanity_errors += 100;
+		goto sanity_error;
+	}
+	if (!state->stateful && !flushed) {
+		PPPDEBUG(LOG_DEBUG, ("mppe_decompress[%d]: FLUSHED bit not set in "
+		       "stateless mode!\n", pcb->netif->num));
+		state->sanity_errors += 100;
+		goto sanity_error;
+	}
+	if (state->stateful && ((ccount & 0xff) == 0xff) && !flushed) {
+		PPPDEBUG(LOG_DEBUG, ("mppe_decompress[%d]: FLUSHED bit not set on "
+		       "flag packet!\n", pcb->netif->num));
+		state->sanity_errors += 100;
+		goto sanity_error;
+	}
+
+	/*
+	 * Check the coherency count.
+	 */
+
+	if (!state->stateful) {
+		/* Discard late packet */
+		if ((ccount - state->ccount) % MPPE_CCOUNT_SPACE > MPPE_CCOUNT_SPACE / 2) {
+			state->sanity_errors++;
+			goto sanity_error;
+		}
+
+		/* RFC 3078, sec 8.1.  Rekey for every packet. */
+		while (state->ccount != ccount) {
+			mppe_rekey(state, 0);
+			state->ccount = (state->ccount + 1) % MPPE_CCOUNT_SPACE;
+		}
+	} else {
+		/* RFC 3078, sec 8.2. */
+		if (!state->discard) {
+			/* normal state */
+			state->ccount = (state->ccount + 1) % MPPE_CCOUNT_SPACE;
+			if (ccount != state->ccount) {
+				/*
+				 * (ccount > state->ccount)
+				 * Packet loss detected, enter the discard state.
+				 * Signal the peer to rekey (by sending a CCP Reset-Request).
+				 */
+				state->discard = 1;
+				ccp_resetrequest(pcb);
+				return ERR_BUF;
+			}
+		} else {
+			/* discard state */
+			if (!flushed) {
+				/* ccp.c will be silent (no additional CCP Reset-Requests). */
+				return ERR_BUF;
+			} else {
+				/* Rekey for every missed "flag" packet. */
+				while ((ccount & ~0xff) !=
+				       (state->ccount & ~0xff)) {
+					mppe_rekey(state, 0);
+					state->ccount =
+					    (state->ccount +
+					     256) % MPPE_CCOUNT_SPACE;
+				}
+
+				/* reset */
+				state->discard = 0;
+				state->ccount = ccount;
+				/*
+				 * Another problem with RFC 3078 here.  It implies that the
+				 * peer need not send a Reset-Ack packet.  But RFC 1962
+				 * requires it.  Hopefully, M$ does send a Reset-Ack; even
+				 * though it isn't required for MPPE synchronization, it is
+				 * required to reset CCP state.
+				 */
+			}
+		}
+		if (flushed)
+			mppe_rekey(state, 0);
+	}
+
+	/* Hide MPPE header */
+	pbuf_remove_header(n0, MPPE_OVHD);
+
+	/* Decrypt the packet. */
+	for (n = n0; n != NULL; n = n->next) {
+		lwip_arc4_crypt(&state->arc4, (u8_t*)n->payload, n->len);
+		if (n->tot_len == n->len) {
+			break;
+		}
+	}
+
+	/* good packet credit */
+	state->sanity_errors >>= 1;
+
+	return ERR_OK;
+
+sanity_error:
+	if (state->sanity_errors >= SANITY_MAX) {
+		/*
+		 * Take LCP down if the peer is sending too many bogons.
+		 * We don't want to do this for a single or just a few
+		 * instances since it could just be due to packet corruption.
+		 */
+		lcp_close(pcb, "Too many MPPE errors");
+	}
+	return ERR_BUF;
+}
+
+#endif /* PPP_SUPPORT && MPPE_SUPPORT */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/netif/ppp/multilink.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/netif/ppp/multilink.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/netif/ppp/multilink.c	(revision 457)
@@ -0,0 +1,609 @@
+/*
+ * multilink.c - support routines for multilink.
+ *
+ * Copyright (c) 2000-2002 Paul Mackerras. 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. The name(s) of the authors of this software must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission.
+ *
+ * 3. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by Paul Mackerras
+ *     <paulus@samba.org>".
+ *
+ * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO
+ * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
+ * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
+ * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
+ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include "netif/ppp/ppp_opts.h"
+#if PPP_SUPPORT && defined(HAVE_MULTILINK) /* don't build if not configured for use in lwipopts.h */
+
+/* Multilink support
+ *
+ * Multilink uses Samba TDB (Trivial Database Library), which
+ * we cannot port, because it needs a filesystem.
+ *
+ * We have to choose between doing a memory-shared TDB-clone,
+ * or dropping multilink support at all.
+ */
+
+#include <string.h>
+#include <ctype.h>
+#include <stdlib.h>
+#include <netdb.h>
+#include <errno.h>
+#include <signal.h>
+#include <netinet/in.h>
+#include <unistd.h>
+
+#include "netif/ppp/ppp_impl.h"
+
+#include "netif/ppp/fsm.h"
+#include "netif/ppp/lcp.h"
+#include "netif/ppp/tdb.h"
+
+bool endpoint_specified;	/* user gave explicit endpoint discriminator */
+char *bundle_id;		/* identifier for our bundle */
+char *blinks_id;		/* key for the list of links */
+bool doing_multilink;		/* multilink was enabled and agreed to */
+bool multilink_master;		/* we own the multilink bundle */
+
+extern TDB_CONTEXT *pppdb;
+extern char db_key[];
+
+static void make_bundle_links (int append);
+static void remove_bundle_link (void);
+static void iterate_bundle_links (void (*func) (char *));
+
+static int get_default_epdisc (struct epdisc *);
+static int parse_num (char *str, const char *key, int *valp);
+static int owns_unit (TDB_DATA pid, int unit);
+
+#define set_ip_epdisc(ep, addr) do {	\
+	ep->length = 4;			\
+	ep->value[0] = addr >> 24;	\
+	ep->value[1] = addr >> 16;	\
+	ep->value[2] = addr >> 8;	\
+	ep->value[3] = addr;		\
+} while (0)
+
+#define LOCAL_IP_ADDR(addr)						  \
+	(((addr) & 0xff000000) == 0x0a000000		/* 10.x.x.x */	  \
+	 || ((addr) & 0xfff00000) == 0xac100000		/* 172.16.x.x */  \
+	 || ((addr) & 0xffff0000) == 0xc0a80000)	/* 192.168.x.x */
+
+#define process_exists(n)	(kill((n), 0) == 0 || errno != ESRCH)
+
+void
+mp_check_options()
+{
+	lcp_options *wo = &lcp_wantoptions[0];
+	lcp_options *ao = &lcp_allowoptions[0];
+
+	doing_multilink = 0;
+	if (!multilink)
+		return;
+	/* if we're doing multilink, we have to negotiate MRRU */
+	if (!wo->neg_mrru) {
+		/* mrru not specified, default to mru */
+		wo->mrru = wo->mru;
+		wo->neg_mrru = 1;
+	}
+	ao->mrru = ao->mru;
+	ao->neg_mrru = 1;
+
+	if (!wo->neg_endpoint && !noendpoint) {
+		/* get a default endpoint value */
+		wo->neg_endpoint = get_default_epdisc(&wo->endpoint);
+	}
+}
+
+/*
+ * Make a new bundle or join us to an existing bundle
+ * if we are doing multilink.
+ */
+int
+mp_join_bundle()
+{
+	lcp_options *go = &lcp_gotoptions[0];
+	lcp_options *ho = &lcp_hisoptions[0];
+	lcp_options *ao = &lcp_allowoptions[0];
+	int unit, pppd_pid;
+	int l, mtu;
+	char *p;
+	TDB_DATA key, pid, rec;
+
+	if (doing_multilink) {
+		/* have previously joined a bundle */
+		if (!go->neg_mrru || !ho->neg_mrru) {
+			notice("oops, didn't get multilink on renegotiation");
+			lcp_close(pcb, "multilink required");
+			return 0;
+		}
+		/* XXX should check the peer_authname and ho->endpoint
+		   are the same as previously */
+		return 0;
+	}
+
+	if (!go->neg_mrru || !ho->neg_mrru) {
+		/* not doing multilink */
+		if (go->neg_mrru)
+			notice("oops, multilink negotiated only for receive");
+		mtu = ho->neg_mru? ho->mru: PPP_MRU;
+		if (mtu > ao->mru)
+			mtu = ao->mru;
+		if (demand) {
+			/* already have a bundle */
+			cfg_bundle(0, 0, 0, 0);
+			netif_set_mtu(pcb, mtu);
+			return 0;
+		}
+		make_new_bundle(0, 0, 0, 0);
+		set_ifunit(1);
+		netif_set_mtu(pcb, mtu);
+		return 0;
+	}
+
+	doing_multilink = 1;
+
+	/*
+	 * Find the appropriate bundle or join a new one.
+	 * First we make up a name for the bundle.
+	 * The length estimate is worst-case assuming every
+	 * character has to be quoted.
+	 */
+	l = 4 * strlen(peer_authname) + 10;
+	if (ho->neg_endpoint)
+		l += 3 * ho->endpoint.length + 8;
+	if (bundle_name)
+		l += 3 * strlen(bundle_name) + 2;
+	bundle_id = malloc(l);
+	if (bundle_id == 0)
+		novm("bundle identifier");
+
+	p = bundle_id;
+	p += slprintf(p, l-1, "BUNDLE=\"%q\"", peer_authname);
+	if (ho->neg_endpoint || bundle_name)
+		*p++ = '/';
+	if (ho->neg_endpoint)
+		p += slprintf(p, bundle_id+l-p, "%s",
+			      epdisc_to_str(&ho->endpoint));
+	if (bundle_name)
+		p += slprintf(p, bundle_id+l-p, "/%v", bundle_name);
+
+	/* Make the key for the list of links belonging to the bundle */
+	l = p - bundle_id;
+	blinks_id = malloc(l + 7);
+	if (blinks_id == NULL)
+		novm("bundle links key");
+	slprintf(blinks_id, l + 7, "BUNDLE_LINKS=%s", bundle_id + 7);
+
+	/*
+	 * For demand mode, we only need to configure the bundle
+	 * and attach the link.
+	 */
+	mtu = LWIP_MIN(ho->mrru, ao->mru);
+	if (demand) {
+		cfg_bundle(go->mrru, ho->mrru, go->neg_ssnhf, ho->neg_ssnhf);
+		netif_set_mtu(pcb, mtu);
+		script_setenv("BUNDLE", bundle_id + 7, 1);
+		return 0;
+	}
+
+	/*
+	 * Check if the bundle ID is already in the database.
+	 */
+	unit = -1;
+	lock_db();
+	key.dptr = bundle_id;
+	key.dsize = p - bundle_id;
+	pid = tdb_fetch(pppdb, key);
+	if (pid.dptr != NULL) {
+		/* bundle ID exists, see if the pppd record exists */
+		rec = tdb_fetch(pppdb, pid);
+		if (rec.dptr != NULL && rec.dsize > 0) {
+			/* make sure the string is null-terminated */
+			rec.dptr[rec.dsize-1] = 0;
+			/* parse the interface number */
+			parse_num(rec.dptr, "IFNAME=ppp", &unit);
+			/* check the pid value */
+			if (!parse_num(rec.dptr, "PPPD_PID=", &pppd_pid)
+			    || !process_exists(pppd_pid)
+			    || !owns_unit(pid, unit))
+				unit = -1;
+			free(rec.dptr);
+		}
+		free(pid.dptr);
+	}
+
+	if (unit >= 0) {
+		/* attach to existing unit */
+		if (bundle_attach(unit)) {
+			set_ifunit(0);
+			script_setenv("BUNDLE", bundle_id + 7, 0);
+			make_bundle_links(1);
+			unlock_db();
+			info("Link attached to %s", ifname);
+			return 1;
+		}
+		/* attach failed because bundle doesn't exist */
+	}
+
+	/* we have to make a new bundle */
+	make_new_bundle(go->mrru, ho->mrru, go->neg_ssnhf, ho->neg_ssnhf);
+	set_ifunit(1);
+	netif_set_mtu(pcb, mtu);
+	script_setenv("BUNDLE", bundle_id + 7, 1);
+	make_bundle_links(pcb);
+	unlock_db();
+	info("New bundle %s created", ifname);
+	multilink_master = 1;
+	return 0;
+}
+
+void mp_exit_bundle()
+{
+	lock_db();
+	remove_bundle_link();
+	unlock_db();
+}
+
+static void sendhup(char *str)
+{
+	int pid;
+
+	if (parse_num(str, "PPPD_PID=", &pid) && pid != getpid()) {
+		if (debug)
+			dbglog("sending SIGHUP to process %d", pid);
+		kill(pid, SIGHUP);
+	}
+}
+
+void mp_bundle_terminated()
+{
+	TDB_DATA key;
+
+	bundle_terminating = 1;
+	upper_layers_down(pcb);
+	notice("Connection terminated.");
+#if PPP_STATS_SUPPORT
+	print_link_stats();
+#endif /* PPP_STATS_SUPPORT */
+	if (!demand) {
+		remove_pidfiles();
+		script_unsetenv("IFNAME");
+	}
+
+	lock_db();
+	destroy_bundle();
+	iterate_bundle_links(sendhup);
+	key.dptr = blinks_id;
+	key.dsize = strlen(blinks_id);
+	tdb_delete(pppdb, key);
+	unlock_db();
+
+	new_phase(PPP_PHASE_DEAD);
+
+	doing_multilink = 0;
+	multilink_master = 0;
+}
+
+static void make_bundle_links(int append)
+{
+	TDB_DATA key, rec;
+	char *p;
+	char entry[32];
+	int l;
+
+	key.dptr = blinks_id;
+	key.dsize = strlen(blinks_id);
+	slprintf(entry, sizeof(entry), "%s;", db_key);
+	p = entry;
+	if (append) {
+		rec = tdb_fetch(pppdb, key);
+		if (rec.dptr != NULL && rec.dsize > 0) {
+			rec.dptr[rec.dsize-1] = 0;
+			if (strstr(rec.dptr, db_key) != NULL) {
+				/* already in there? strange */
+				warn("link entry already exists in tdb");
+				return;
+			}
+			l = rec.dsize + strlen(entry);
+			p = malloc(l);
+			if (p == NULL)
+				novm("bundle link list");
+			slprintf(p, l, "%s%s", rec.dptr, entry);
+		} else {
+			warn("bundle link list not found");
+		}
+		if (rec.dptr != NULL)
+			free(rec.dptr);
+	}
+	rec.dptr = p;
+	rec.dsize = strlen(p) + 1;
+	if (tdb_store(pppdb, key, rec, TDB_REPLACE))
+		error("couldn't %s bundle link list",
+		      append? "update": "create");
+	if (p != entry)
+		free(p);
+}
+
+static void remove_bundle_link()
+{
+	TDB_DATA key, rec;
+	char entry[32];
+	char *p, *q;
+	int l;
+
+	key.dptr = blinks_id;
+	key.dsize = strlen(blinks_id);
+	slprintf(entry, sizeof(entry), "%s;", db_key);
+
+	rec = tdb_fetch(pppdb, key);
+	if (rec.dptr == NULL || rec.dsize <= 0) {
+		if (rec.dptr != NULL)
+			free(rec.dptr);
+		return;
+	}
+	rec.dptr[rec.dsize-1] = 0;
+	p = strstr(rec.dptr, entry);
+	if (p != NULL) {
+		q = p + strlen(entry);
+		l = strlen(q) + 1;
+		memmove(p, q, l);
+		rec.dsize = p - rec.dptr + l;
+		if (tdb_store(pppdb, key, rec, TDB_REPLACE))
+			error("couldn't update bundle link list (removal)");
+	}
+	free(rec.dptr);
+}
+
+static void iterate_bundle_links(void (*func)(char *))
+{
+	TDB_DATA key, rec, pp;
+	char *p, *q;
+
+	key.dptr = blinks_id;
+	key.dsize = strlen(blinks_id);
+	rec = tdb_fetch(pppdb, key);
+	if (rec.dptr == NULL || rec.dsize <= 0) {
+		error("bundle link list not found (iterating list)");
+		if (rec.dptr != NULL)
+			free(rec.dptr);
+		return;
+	}
+	p = rec.dptr;
+	p[rec.dsize-1] = 0;
+	while ((q = strchr(p, ';')) != NULL) {
+		*q = 0;
+		key.dptr = p;
+		key.dsize = q - p;
+		pp = tdb_fetch(pppdb, key);
+		if (pp.dptr != NULL && pp.dsize > 0) {
+			pp.dptr[pp.dsize-1] = 0;
+			func(pp.dptr);
+		}
+		if (pp.dptr != NULL)
+			free(pp.dptr);
+		p = q + 1;
+	}
+	free(rec.dptr);
+}
+
+static int
+parse_num(str, key, valp)
+     char *str;
+     const char *key;
+     int *valp;
+{
+	char *p, *endp;
+	int i;
+
+	p = strstr(str, key);
+	if (p != 0) {
+		p += strlen(key);
+		i = strtol(p, &endp, 10);
+		if (endp != p && (*endp == 0 || *endp == ';')) {
+			*valp = i;
+			return 1;
+		}
+	}
+	return 0;
+}
+
+/*
+ * Check whether the pppd identified by `key' still owns ppp unit `unit'.
+ */
+static int
+owns_unit(key, unit)
+     TDB_DATA key;
+     int unit;
+{
+	char ifkey[32];
+	TDB_DATA kd, vd;
+	int ret = 0;
+
+	slprintf(ifkey, sizeof(ifkey), "IFNAME=ppp%d", unit);
+	kd.dptr = ifkey;
+	kd.dsize = strlen(ifkey);
+	vd = tdb_fetch(pppdb, kd);
+	if (vd.dptr != NULL) {
+		ret = vd.dsize == key.dsize
+			&& memcmp(vd.dptr, key.dptr, vd.dsize) == 0;
+		free(vd.dptr);
+	}
+	return ret;
+}
+
+static int
+get_default_epdisc(ep)
+     struct epdisc *ep;
+{
+	char *p;
+	struct hostent *hp;
+	u32_t addr;
+
+	/* First try for an ethernet MAC address */
+	p = get_first_ethernet();
+	if (p != 0 && get_if_hwaddr(ep->value, p) >= 0) {
+		ep->class = EPD_MAC;
+		ep->length = 6;
+		return 1;
+	}
+
+	/* see if our hostname corresponds to a reasonable IP address */
+	hp = gethostbyname(hostname);
+	if (hp != NULL) {
+		addr = *(u32_t *)hp->h_addr;
+		if (!bad_ip_adrs(addr)) {
+			addr = lwip_ntohl(addr);
+			if (!LOCAL_IP_ADDR(addr)) {
+				ep->class = EPD_IP;
+				set_ip_epdisc(ep, addr);
+				return 1;
+			}
+		}
+	}
+
+	return 0;
+}
+
+/*
+ * epdisc_to_str - make a printable string from an endpoint discriminator.
+ */
+
+static char *endp_class_names[] = {
+    "null", "local", "IP", "MAC", "magic", "phone"
+};
+
+char *
+epdisc_to_str(ep)
+     struct epdisc *ep;
+{
+	static char str[MAX_ENDP_LEN*3+8];
+	u_char *p = ep->value;
+	int i, mask = 0;
+	char *q, c, c2;
+
+	if (ep->class == EPD_NULL && ep->length == 0)
+		return "null";
+	if (ep->class == EPD_IP && ep->length == 4) {
+		u32_t addr;
+
+		GETLONG(addr, p);
+		slprintf(str, sizeof(str), "IP:%I", lwip_htonl(addr));
+		return str;
+	}
+
+	c = ':';
+	c2 = '.';
+	if (ep->class == EPD_MAC && ep->length == 6)
+		c2 = ':';
+	else if (ep->class == EPD_MAGIC && (ep->length % 4) == 0)
+		mask = 3;
+	q = str;
+	if (ep->class <= EPD_PHONENUM)
+		q += slprintf(q, sizeof(str)-1, "%s",
+			      endp_class_names[ep->class]);
+	else
+		q += slprintf(q, sizeof(str)-1, "%d", ep->class);
+	c = ':';
+	for (i = 0; i < ep->length && i < MAX_ENDP_LEN; ++i) {
+		if ((i & mask) == 0) {
+			*q++ = c;
+			c = c2;
+		}
+		q += slprintf(q, str + sizeof(str) - q, "%.2x", ep->value[i]);
+	}
+	return str;
+}
+
+static int hexc_val(int c)
+{
+	if (c >= 'a')
+		return c - 'a' + 10;
+	if (c >= 'A')
+		return c - 'A' + 10;
+	return c - '0';
+}
+
+int
+str_to_epdisc(ep, str)
+     struct epdisc *ep;
+     char *str;
+{
+	int i, l;
+	char *p, *endp;
+
+	for (i = EPD_NULL; i <= EPD_PHONENUM; ++i) {
+		int sl = strlen(endp_class_names[i]);
+		if (strncasecmp(str, endp_class_names[i], sl) == 0) {
+			str += sl;
+			break;
+		}
+	}
+	if (i > EPD_PHONENUM) {
+		/* not a class name, try a decimal class number */
+		i = strtol(str, &endp, 10);
+		if (endp == str)
+			return 0;	/* can't parse class number */
+		str = endp;
+	}
+	ep->class = i;
+	if (*str == 0) {
+		ep->length = 0;
+		return 1;
+	}
+	if (*str != ':' && *str != '.')
+		return 0;
+	++str;
+
+	if (i == EPD_IP) {
+		u32_t addr;
+		i = parse_dotted_ip(str, &addr);
+		if (i == 0 || str[i] != 0)
+			return 0;
+		set_ip_epdisc(ep, addr);
+		return 1;
+	}
+	if (i == EPD_MAC && get_if_hwaddr(ep->value, str) >= 0) {
+		ep->length = 6;
+		return 1;
+	}
+
+	p = str;
+	for (l = 0; l < MAX_ENDP_LEN; ++l) {
+		if (*str == 0)
+			break;
+		if (p <= str)
+			for (p = str; isxdigit(*p); ++p)
+				;
+		i = p - str;
+		if (i == 0)
+			return 0;
+		ep->value[l] = hexc_val(*str++);
+		if ((i & 1) == 0)
+			ep->value[l] = (ep->value[l] << 4) + hexc_val(*str++);
+		if (*str == ':' || *str == '.')
+			++str;
+	}
+	if (*str != 0 || (ep->class == EPD_MAC && l != 6))
+		return 0;
+	ep->length = l;
+	return 1;
+}
+
+#endif /* PPP_SUPPORT && HAVE_MULTILINK */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/netif/ppp/polarssl/README
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/netif/ppp/polarssl/README	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/netif/ppp/polarssl/README	(revision 457)
@@ -0,0 +1,22 @@
+About PolarSSL files into lwIP PPP support
+------------------------------------------
+
+This folder contains some files fetched from the latest BSD release of
+the PolarSSL project (PolarSSL 0.10.1-bsd) for ciphers and encryption
+methods we need for lwIP PPP support.
+
+The PolarSSL files were cleaned to contain only the necessary struct
+fields and functions needed for lwIP.
+
+The PolarSSL API was not changed at all, so if you are already using
+PolarSSL you can choose to skip the compilation of the included PolarSSL
+library into lwIP.
+
+If you are not using the embedded copy you must include external
+libraries into your arch/cc.h port file.
+
+Beware of the stack requirements which can be a lot larger if you are not
+using our cleaned PolarSSL library.
+
+
+PolarSSL project website: http://polarssl.org/
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/netif/ppp/polarssl/arc4.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/netif/ppp/polarssl/arc4.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/netif/ppp/polarssl/arc4.c	(revision 457)
@@ -0,0 +1,101 @@
+/*
+ *  An implementation of the ARCFOUR algorithm
+ *
+ *  Based on XySSL: Copyright (C) 2006-2008  Christophe Devine
+ *
+ *  Copyright (C) 2009  Paul Bakker <polarssl_maintainer at polarssl dot org>
+ *
+ *  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.
+ *    * 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.
+ *    * Neither the names of PolarSSL or XySSL 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
+ *  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.
+ */
+/*
+ *  The ARCFOUR algorithm was publicly disclosed on 94/09.
+ *
+ *  http://groups.google.com/group/sci.crypt/msg/10a300c9d21afca0
+ */
+
+#include "netif/ppp/ppp_opts.h"
+#if PPP_SUPPORT && LWIP_INCLUDED_POLARSSL_ARC4
+
+#include "netif/ppp/polarssl/arc4.h"
+/*
+ * ARC4 key schedule
+ */
+void arc4_setup( arc4_context *ctx, unsigned char *key, int keylen )
+{
+    int i, j, k, a;
+    unsigned char *m;
+
+    ctx->x = 0;
+    ctx->y = 0;
+    m = ctx->m;
+
+    for( i = 0; i < 256; i++ )
+        m[i] = (unsigned char) i;
+
+    j = k = 0;
+
+    for( i = 0; i < 256; i++, k++ )
+    {
+        if( k >= keylen ) k = 0;
+
+        a = m[i];
+        j = ( j + a + key[k] ) & 0xFF;
+        m[i] = m[j];
+        m[j] = (unsigned char) a;
+    }
+}
+
+/*
+ * ARC4 cipher function
+ */
+void arc4_crypt( arc4_context *ctx, unsigned char *buf, int buflen )
+{
+    int i, x, y, a, b;
+    unsigned char *m;
+
+    x = ctx->x;
+    y = ctx->y;
+    m = ctx->m;
+
+    for( i = 0; i < buflen; i++ )
+    {
+        x = ( x + 1 ) & 0xFF; a = m[x];
+        y = ( y + a ) & 0xFF; b = m[y];
+
+        m[x] = (unsigned char) b;
+        m[y] = (unsigned char) a;
+
+        buf[i] = (unsigned char)
+            ( buf[i] ^ m[(unsigned char)( a + b )] );
+    }
+
+    ctx->x = x;
+    ctx->y = y;
+}
+
+#endif /* PPP_SUPPORT && LWIP_INCLUDED_POLARSSL_DES */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/netif/ppp/polarssl/des.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/netif/ppp/polarssl/des.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/netif/ppp/polarssl/des.c	(revision 457)
@@ -0,0 +1,422 @@
+/*
+ *  FIPS-46-3 compliant Triple-DES implementation
+ *
+ *  Based on XySSL: Copyright (C) 2006-2008  Christophe Devine
+ *
+ *  Copyright (C) 2009  Paul Bakker <polarssl_maintainer at polarssl dot org>
+ *
+ *  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.
+ *    * 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.
+ *    * Neither the names of PolarSSL or XySSL 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
+ *  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.
+ */
+/*
+ *  DES, on which TDES is based, was originally designed by Horst Feistel
+ *  at IBM in 1974, and was adopted as a standard by NIST (formerly NBS).
+ *
+ *  http://csrc.nist.gov/publications/fips/fips46-3/fips46-3.pdf
+ */
+
+#include "netif/ppp/ppp_opts.h"
+#if PPP_SUPPORT && LWIP_INCLUDED_POLARSSL_DES
+
+#include "netif/ppp/polarssl/des.h"
+
+/*
+ * 32-bit integer manipulation macros (big endian)
+ */
+#ifndef GET_ULONG_BE
+#define GET_ULONG_BE(n,b,i)                             \
+{                                                       \
+    (n) = ( (unsigned long) (b)[(i)    ] << 24 )        \
+        | ( (unsigned long) (b)[(i) + 1] << 16 )        \
+        | ( (unsigned long) (b)[(i) + 2] <<  8 )        \
+        | ( (unsigned long) (b)[(i) + 3]       );       \
+}
+#endif
+
+#ifndef PUT_ULONG_BE
+#define PUT_ULONG_BE(n,b,i)                             \
+{                                                       \
+    (b)[(i)    ] = (unsigned char) ( (n) >> 24 );       \
+    (b)[(i) + 1] = (unsigned char) ( (n) >> 16 );       \
+    (b)[(i) + 2] = (unsigned char) ( (n) >>  8 );       \
+    (b)[(i) + 3] = (unsigned char) ( (n)       );       \
+}
+#endif
+
+/*
+ * Expanded DES S-boxes
+ */
+static const unsigned long SB1[64] =
+{
+    0x01010400, 0x00000000, 0x00010000, 0x01010404,
+    0x01010004, 0x00010404, 0x00000004, 0x00010000,
+    0x00000400, 0x01010400, 0x01010404, 0x00000400,
+    0x01000404, 0x01010004, 0x01000000, 0x00000004,
+    0x00000404, 0x01000400, 0x01000400, 0x00010400,
+    0x00010400, 0x01010000, 0x01010000, 0x01000404,
+    0x00010004, 0x01000004, 0x01000004, 0x00010004,
+    0x00000000, 0x00000404, 0x00010404, 0x01000000,
+    0x00010000, 0x01010404, 0x00000004, 0x01010000,
+    0x01010400, 0x01000000, 0x01000000, 0x00000400,
+    0x01010004, 0x00010000, 0x00010400, 0x01000004,
+    0x00000400, 0x00000004, 0x01000404, 0x00010404,
+    0x01010404, 0x00010004, 0x01010000, 0x01000404,
+    0x01000004, 0x00000404, 0x00010404, 0x01010400,
+    0x00000404, 0x01000400, 0x01000400, 0x00000000,
+    0x00010004, 0x00010400, 0x00000000, 0x01010004
+};
+
+static const unsigned long SB2[64] =
+{
+    0x80108020, 0x80008000, 0x00008000, 0x00108020,
+    0x00100000, 0x00000020, 0x80100020, 0x80008020,
+    0x80000020, 0x80108020, 0x80108000, 0x80000000,
+    0x80008000, 0x00100000, 0x00000020, 0x80100020,
+    0x00108000, 0x00100020, 0x80008020, 0x00000000,
+    0x80000000, 0x00008000, 0x00108020, 0x80100000,
+    0x00100020, 0x80000020, 0x00000000, 0x00108000,
+    0x00008020, 0x80108000, 0x80100000, 0x00008020,
+    0x00000000, 0x00108020, 0x80100020, 0x00100000,
+    0x80008020, 0x80100000, 0x80108000, 0x00008000,
+    0x80100000, 0x80008000, 0x00000020, 0x80108020,
+    0x00108020, 0x00000020, 0x00008000, 0x80000000,
+    0x00008020, 0x80108000, 0x00100000, 0x80000020,
+    0x00100020, 0x80008020, 0x80000020, 0x00100020,
+    0x00108000, 0x00000000, 0x80008000, 0x00008020,
+    0x80000000, 0x80100020, 0x80108020, 0x00108000
+};
+
+static const unsigned long SB3[64] =
+{
+    0x00000208, 0x08020200, 0x00000000, 0x08020008,
+    0x08000200, 0x00000000, 0x00020208, 0x08000200,
+    0x00020008, 0x08000008, 0x08000008, 0x00020000,
+    0x08020208, 0x00020008, 0x08020000, 0x00000208,
+    0x08000000, 0x00000008, 0x08020200, 0x00000200,
+    0x00020200, 0x08020000, 0x08020008, 0x00020208,
+    0x08000208, 0x00020200, 0x00020000, 0x08000208,
+    0x00000008, 0x08020208, 0x00000200, 0x08000000,
+    0x08020200, 0x08000000, 0x00020008, 0x00000208,
+    0x00020000, 0x08020200, 0x08000200, 0x00000000,
+    0x00000200, 0x00020008, 0x08020208, 0x08000200,
+    0x08000008, 0x00000200, 0x00000000, 0x08020008,
+    0x08000208, 0x00020000, 0x08000000, 0x08020208,
+    0x00000008, 0x00020208, 0x00020200, 0x08000008,
+    0x08020000, 0x08000208, 0x00000208, 0x08020000,
+    0x00020208, 0x00000008, 0x08020008, 0x00020200
+};
+
+static const unsigned long SB4[64] =
+{
+    0x00802001, 0x00002081, 0x00002081, 0x00000080,
+    0x00802080, 0x00800081, 0x00800001, 0x00002001,
+    0x00000000, 0x00802000, 0x00802000, 0x00802081,
+    0x00000081, 0x00000000, 0x00800080, 0x00800001,
+    0x00000001, 0x00002000, 0x00800000, 0x00802001,
+    0x00000080, 0x00800000, 0x00002001, 0x00002080,
+    0x00800081, 0x00000001, 0x00002080, 0x00800080,
+    0x00002000, 0x00802080, 0x00802081, 0x00000081,
+    0x00800080, 0x00800001, 0x00802000, 0x00802081,
+    0x00000081, 0x00000000, 0x00000000, 0x00802000,
+    0x00002080, 0x00800080, 0x00800081, 0x00000001,
+    0x00802001, 0x00002081, 0x00002081, 0x00000080,
+    0x00802081, 0x00000081, 0x00000001, 0x00002000,
+    0x00800001, 0x00002001, 0x00802080, 0x00800081,
+    0x00002001, 0x00002080, 0x00800000, 0x00802001,
+    0x00000080, 0x00800000, 0x00002000, 0x00802080
+};
+
+static const unsigned long SB5[64] =
+{
+    0x00000100, 0x02080100, 0x02080000, 0x42000100,
+    0x00080000, 0x00000100, 0x40000000, 0x02080000,
+    0x40080100, 0x00080000, 0x02000100, 0x40080100,
+    0x42000100, 0x42080000, 0x00080100, 0x40000000,
+    0x02000000, 0x40080000, 0x40080000, 0x00000000,
+    0x40000100, 0x42080100, 0x42080100, 0x02000100,
+    0x42080000, 0x40000100, 0x00000000, 0x42000000,
+    0x02080100, 0x02000000, 0x42000000, 0x00080100,
+    0x00080000, 0x42000100, 0x00000100, 0x02000000,
+    0x40000000, 0x02080000, 0x42000100, 0x40080100,
+    0x02000100, 0x40000000, 0x42080000, 0x02080100,
+    0x40080100, 0x00000100, 0x02000000, 0x42080000,
+    0x42080100, 0x00080100, 0x42000000, 0x42080100,
+    0x02080000, 0x00000000, 0x40080000, 0x42000000,
+    0x00080100, 0x02000100, 0x40000100, 0x00080000,
+    0x00000000, 0x40080000, 0x02080100, 0x40000100
+};
+
+static const unsigned long SB6[64] =
+{
+    0x20000010, 0x20400000, 0x00004000, 0x20404010,
+    0x20400000, 0x00000010, 0x20404010, 0x00400000,
+    0x20004000, 0x00404010, 0x00400000, 0x20000010,
+    0x00400010, 0x20004000, 0x20000000, 0x00004010,
+    0x00000000, 0x00400010, 0x20004010, 0x00004000,
+    0x00404000, 0x20004010, 0x00000010, 0x20400010,
+    0x20400010, 0x00000000, 0x00404010, 0x20404000,
+    0x00004010, 0x00404000, 0x20404000, 0x20000000,
+    0x20004000, 0x00000010, 0x20400010, 0x00404000,
+    0x20404010, 0x00400000, 0x00004010, 0x20000010,
+    0x00400000, 0x20004000, 0x20000000, 0x00004010,
+    0x20000010, 0x20404010, 0x00404000, 0x20400000,
+    0x00404010, 0x20404000, 0x00000000, 0x20400010,
+    0x00000010, 0x00004000, 0x20400000, 0x00404010,
+    0x00004000, 0x00400010, 0x20004010, 0x00000000,
+    0x20404000, 0x20000000, 0x00400010, 0x20004010
+};
+
+static const unsigned long SB7[64] =
+{
+    0x00200000, 0x04200002, 0x04000802, 0x00000000,
+    0x00000800, 0x04000802, 0x00200802, 0x04200800,
+    0x04200802, 0x00200000, 0x00000000, 0x04000002,
+    0x00000002, 0x04000000, 0x04200002, 0x00000802,
+    0x04000800, 0x00200802, 0x00200002, 0x04000800,
+    0x04000002, 0x04200000, 0x04200800, 0x00200002,
+    0x04200000, 0x00000800, 0x00000802, 0x04200802,
+    0x00200800, 0x00000002, 0x04000000, 0x00200800,
+    0x04000000, 0x00200800, 0x00200000, 0x04000802,
+    0x04000802, 0x04200002, 0x04200002, 0x00000002,
+    0x00200002, 0x04000000, 0x04000800, 0x00200000,
+    0x04200800, 0x00000802, 0x00200802, 0x04200800,
+    0x00000802, 0x04000002, 0x04200802, 0x04200000,
+    0x00200800, 0x00000000, 0x00000002, 0x04200802,
+    0x00000000, 0x00200802, 0x04200000, 0x00000800,
+    0x04000002, 0x04000800, 0x00000800, 0x00200002
+};
+
+static const unsigned long SB8[64] =
+{
+    0x10001040, 0x00001000, 0x00040000, 0x10041040,
+    0x10000000, 0x10001040, 0x00000040, 0x10000000,
+    0x00040040, 0x10040000, 0x10041040, 0x00041000,
+    0x10041000, 0x00041040, 0x00001000, 0x00000040,
+    0x10040000, 0x10000040, 0x10001000, 0x00001040,
+    0x00041000, 0x00040040, 0x10040040, 0x10041000,
+    0x00001040, 0x00000000, 0x00000000, 0x10040040,
+    0x10000040, 0x10001000, 0x00041040, 0x00040000,
+    0x00041040, 0x00040000, 0x10041000, 0x00001000,
+    0x00000040, 0x10040040, 0x00001000, 0x00041040,
+    0x10001000, 0x00000040, 0x10000040, 0x10040000,
+    0x10040040, 0x10000000, 0x00040000, 0x10001040,
+    0x00000000, 0x10041040, 0x00040040, 0x10000040,
+    0x10040000, 0x10001000, 0x10001040, 0x00000000,
+    0x10041040, 0x00041000, 0x00041000, 0x00001040,
+    0x00001040, 0x00040040, 0x10000000, 0x10041000
+};
+
+/*
+ * PC1: left and right halves bit-swap
+ */
+static const unsigned long LHs[16] =
+{
+    0x00000000, 0x00000001, 0x00000100, 0x00000101,
+    0x00010000, 0x00010001, 0x00010100, 0x00010101,
+    0x01000000, 0x01000001, 0x01000100, 0x01000101,
+    0x01010000, 0x01010001, 0x01010100, 0x01010101
+};
+
+static const unsigned long RHs[16] =
+{
+    0x00000000, 0x01000000, 0x00010000, 0x01010000,
+    0x00000100, 0x01000100, 0x00010100, 0x01010100,
+    0x00000001, 0x01000001, 0x00010001, 0x01010001,
+    0x00000101, 0x01000101, 0x00010101, 0x01010101,
+};
+
+/*
+ * Initial Permutation macro
+ */
+#define DES_IP(X,Y)                                             \
+{                                                               \
+    T = ((X >>  4) ^ Y) & 0x0F0F0F0F; Y ^= T; X ^= (T <<  4);   \
+    T = ((X >> 16) ^ Y) & 0x0000FFFF; Y ^= T; X ^= (T << 16);   \
+    T = ((Y >>  2) ^ X) & 0x33333333; X ^= T; Y ^= (T <<  2);   \
+    T = ((Y >>  8) ^ X) & 0x00FF00FF; X ^= T; Y ^= (T <<  8);   \
+    Y = ((Y << 1) | (Y >> 31)) & 0xFFFFFFFF;                    \
+    T = (X ^ Y) & 0xAAAAAAAA; Y ^= T; X ^= T;                   \
+    X = ((X << 1) | (X >> 31)) & 0xFFFFFFFF;                    \
+}
+
+/*
+ * Final Permutation macro
+ */
+#define DES_FP(X,Y)                                             \
+{                                                               \
+    X = ((X << 31) | (X >> 1)) & 0xFFFFFFFF;                    \
+    T = (X ^ Y) & 0xAAAAAAAA; X ^= T; Y ^= T;                   \
+    Y = ((Y << 31) | (Y >> 1)) & 0xFFFFFFFF;                    \
+    T = ((Y >>  8) ^ X) & 0x00FF00FF; X ^= T; Y ^= (T <<  8);   \
+    T = ((Y >>  2) ^ X) & 0x33333333; X ^= T; Y ^= (T <<  2);   \
+    T = ((X >> 16) ^ Y) & 0x0000FFFF; Y ^= T; X ^= (T << 16);   \
+    T = ((X >>  4) ^ Y) & 0x0F0F0F0F; Y ^= T; X ^= (T <<  4);   \
+}
+
+/*
+ * DES round macro
+ */
+#define DES_ROUND(X,Y)                          \
+{                                               \
+    T = *SK++ ^ X;                              \
+    Y ^= SB8[ (T      ) & 0x3F ] ^              \
+         SB6[ (T >>  8) & 0x3F ] ^              \
+         SB4[ (T >> 16) & 0x3F ] ^              \
+         SB2[ (T >> 24) & 0x3F ];               \
+                                                \
+    T = *SK++ ^ ((X << 28) | (X >> 4));         \
+    Y ^= SB7[ (T      ) & 0x3F ] ^              \
+         SB5[ (T >>  8) & 0x3F ] ^              \
+         SB3[ (T >> 16) & 0x3F ] ^              \
+         SB1[ (T >> 24) & 0x3F ];               \
+}
+
+#define SWAP(a,b) { unsigned long t = a; a = b; b = t; t = 0; }
+
+static void des_setkey( unsigned long SK[32], unsigned char key[8] )
+{
+    int i;
+    unsigned long X, Y, T;
+
+    GET_ULONG_BE( X, key, 0 );
+    GET_ULONG_BE( Y, key, 4 );
+
+    /*
+     * Permuted Choice 1
+     */
+    T =  ((Y >>  4) ^ X) & 0x0F0F0F0F;  X ^= T; Y ^= (T <<  4);
+    T =  ((Y      ) ^ X) & 0x10101010;  X ^= T; Y ^= (T      );
+
+    X =   (LHs[ (X      ) & 0xF] << 3) | (LHs[ (X >>  8) & 0xF ] << 2)
+        | (LHs[ (X >> 16) & 0xF] << 1) | (LHs[ (X >> 24) & 0xF ]     )
+        | (LHs[ (X >>  5) & 0xF] << 7) | (LHs[ (X >> 13) & 0xF ] << 6)
+        | (LHs[ (X >> 21) & 0xF] << 5) | (LHs[ (X >> 29) & 0xF ] << 4);
+
+    Y =   (RHs[ (Y >>  1) & 0xF] << 3) | (RHs[ (Y >>  9) & 0xF ] << 2)
+        | (RHs[ (Y >> 17) & 0xF] << 1) | (RHs[ (Y >> 25) & 0xF ]     )
+        | (RHs[ (Y >>  4) & 0xF] << 7) | (RHs[ (Y >> 12) & 0xF ] << 6)
+        | (RHs[ (Y >> 20) & 0xF] << 5) | (RHs[ (Y >> 28) & 0xF ] << 4);
+
+    X &= 0x0FFFFFFF;
+    Y &= 0x0FFFFFFF;
+
+    /*
+     * calculate subkeys
+     */
+    for( i = 0; i < 16; i++ )
+    {
+        if( i < 2 || i == 8 || i == 15 )
+        {
+            X = ((X <<  1) | (X >> 27)) & 0x0FFFFFFF;
+            Y = ((Y <<  1) | (Y >> 27)) & 0x0FFFFFFF;
+        }
+        else
+        {
+            X = ((X <<  2) | (X >> 26)) & 0x0FFFFFFF;
+            Y = ((Y <<  2) | (Y >> 26)) & 0x0FFFFFFF;
+        }
+
+        *SK++ =   ((X <<  4) & 0x24000000) | ((X << 28) & 0x10000000)
+                | ((X << 14) & 0x08000000) | ((X << 18) & 0x02080000)
+                | ((X <<  6) & 0x01000000) | ((X <<  9) & 0x00200000)
+                | ((X >>  1) & 0x00100000) | ((X << 10) & 0x00040000)
+                | ((X <<  2) & 0x00020000) | ((X >> 10) & 0x00010000)
+                | ((Y >> 13) & 0x00002000) | ((Y >>  4) & 0x00001000)
+                | ((Y <<  6) & 0x00000800) | ((Y >>  1) & 0x00000400)
+                | ((Y >> 14) & 0x00000200) | ((Y      ) & 0x00000100)
+                | ((Y >>  5) & 0x00000020) | ((Y >> 10) & 0x00000010)
+                | ((Y >>  3) & 0x00000008) | ((Y >> 18) & 0x00000004)
+                | ((Y >> 26) & 0x00000002) | ((Y >> 24) & 0x00000001);
+
+        *SK++ =   ((X << 15) & 0x20000000) | ((X << 17) & 0x10000000)
+                | ((X << 10) & 0x08000000) | ((X << 22) & 0x04000000)
+                | ((X >>  2) & 0x02000000) | ((X <<  1) & 0x01000000)
+                | ((X << 16) & 0x00200000) | ((X << 11) & 0x00100000)
+                | ((X <<  3) & 0x00080000) | ((X >>  6) & 0x00040000)
+                | ((X << 15) & 0x00020000) | ((X >>  4) & 0x00010000)
+                | ((Y >>  2) & 0x00002000) | ((Y <<  8) & 0x00001000)
+                | ((Y >> 14) & 0x00000808) | ((Y >>  9) & 0x00000400)
+                | ((Y      ) & 0x00000200) | ((Y <<  7) & 0x00000100)
+                | ((Y >>  7) & 0x00000020) | ((Y >>  3) & 0x00000011)
+                | ((Y <<  2) & 0x00000004) | ((Y >> 21) & 0x00000002);
+    }
+}
+
+/*
+ * DES key schedule (56-bit, encryption)
+ */
+void des_setkey_enc( des_context *ctx, unsigned char key[8] )
+{
+    des_setkey( ctx->sk, key );
+}
+
+/*
+ * DES key schedule (56-bit, decryption)
+ */
+void des_setkey_dec( des_context *ctx, unsigned char key[8] )
+{
+    int i;
+
+    des_setkey( ctx->sk, key );
+
+    for( i = 0; i < 16; i += 2 )
+    {
+        SWAP( ctx->sk[i    ], ctx->sk[30 - i] );
+        SWAP( ctx->sk[i + 1], ctx->sk[31 - i] );
+    }
+}
+
+/*
+ * DES-ECB block encryption/decryption
+ */
+void des_crypt_ecb( des_context *ctx,
+                    const unsigned char input[8],
+                    unsigned char output[8] )
+{
+    int i;
+    unsigned long X, Y, T, *SK;
+
+    SK = ctx->sk;
+
+    GET_ULONG_BE( X, input, 0 );
+    GET_ULONG_BE( Y, input, 4 );
+
+    DES_IP( X, Y );
+
+    for( i = 0; i < 8; i++ )
+    {
+        DES_ROUND( Y, X );
+        DES_ROUND( X, Y );
+    }
+
+    DES_FP( Y, X );
+
+    PUT_ULONG_BE( Y, output, 0 );
+    PUT_ULONG_BE( X, output, 4 );
+}
+
+#endif /* PPP_SUPPORT && LWIP_INCLUDED_POLARSSL_DES */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/netif/ppp/polarssl/md4.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/netif/ppp/polarssl/md4.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/netif/ppp/polarssl/md4.c	(revision 457)
@@ -0,0 +1,281 @@
+/*
+ *  RFC 1186/1320 compliant MD4 implementation
+ *
+ *  Based on XySSL: Copyright (C) 2006-2008  Christophe Devine
+ *
+ *  Copyright (C) 2009  Paul Bakker <polarssl_maintainer at polarssl dot org>
+ *
+ *  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.
+ *    * 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.
+ *    * Neither the names of PolarSSL or XySSL 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
+ *  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.
+ */
+/*
+ *  The MD4 algorithm was designed by Ron Rivest in 1990.
+ *
+ *  http://www.ietf.org/rfc/rfc1186.txt
+ *  http://www.ietf.org/rfc/rfc1320.txt
+ */
+
+#include "netif/ppp/ppp_opts.h"
+#if PPP_SUPPORT && LWIP_INCLUDED_POLARSSL_MD4
+
+#include "netif/ppp/polarssl/md4.h"
+
+#include <string.h>
+
+/*
+ * 32-bit integer manipulation macros (little endian)
+ */
+#ifndef GET_ULONG_LE
+#define GET_ULONG_LE(n,b,i)                             \
+{                                                       \
+    (n) = ( (unsigned long) (b)[(i)    ]       )        \
+        | ( (unsigned long) (b)[(i) + 1] <<  8 )        \
+        | ( (unsigned long) (b)[(i) + 2] << 16 )        \
+        | ( (unsigned long) (b)[(i) + 3] << 24 );       \
+}
+#endif
+
+#ifndef PUT_ULONG_LE
+#define PUT_ULONG_LE(n,b,i)                             \
+{                                                       \
+    (b)[(i)    ] = (unsigned char) ( (n)       );       \
+    (b)[(i) + 1] = (unsigned char) ( (n) >>  8 );       \
+    (b)[(i) + 2] = (unsigned char) ( (n) >> 16 );       \
+    (b)[(i) + 3] = (unsigned char) ( (n) >> 24 );       \
+}
+#endif
+
+/*
+ * MD4 context setup
+ */
+void md4_starts( md4_context *ctx )
+{
+    ctx->total[0] = 0;
+    ctx->total[1] = 0;
+
+    ctx->state[0] = 0x67452301;
+    ctx->state[1] = 0xEFCDAB89;
+    ctx->state[2] = 0x98BADCFE;
+    ctx->state[3] = 0x10325476;
+}
+
+static void md4_process( md4_context *ctx, const unsigned char data[64] )
+{
+    unsigned long X[16], A, B, C, D;
+
+    GET_ULONG_LE( X[ 0], data,  0 );
+    GET_ULONG_LE( X[ 1], data,  4 );
+    GET_ULONG_LE( X[ 2], data,  8 );
+    GET_ULONG_LE( X[ 3], data, 12 );
+    GET_ULONG_LE( X[ 4], data, 16 );
+    GET_ULONG_LE( X[ 5], data, 20 );
+    GET_ULONG_LE( X[ 6], data, 24 );
+    GET_ULONG_LE( X[ 7], data, 28 );
+    GET_ULONG_LE( X[ 8], data, 32 );
+    GET_ULONG_LE( X[ 9], data, 36 );
+    GET_ULONG_LE( X[10], data, 40 );
+    GET_ULONG_LE( X[11], data, 44 );
+    GET_ULONG_LE( X[12], data, 48 );
+    GET_ULONG_LE( X[13], data, 52 );
+    GET_ULONG_LE( X[14], data, 56 );
+    GET_ULONG_LE( X[15], data, 60 );
+
+#define S(x,n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n)))
+
+    A = ctx->state[0];
+    B = ctx->state[1];
+    C = ctx->state[2];
+    D = ctx->state[3];
+
+#define F(x, y, z) ((x & y) | ((~x) & z))
+#define P(a,b,c,d,x,s) { a += F(b,c,d) + x; a = S(a,s); }
+
+    P( A, B, C, D, X[ 0],  3 );
+    P( D, A, B, C, X[ 1],  7 );
+    P( C, D, A, B, X[ 2], 11 );
+    P( B, C, D, A, X[ 3], 19 );
+    P( A, B, C, D, X[ 4],  3 );
+    P( D, A, B, C, X[ 5],  7 );
+    P( C, D, A, B, X[ 6], 11 );
+    P( B, C, D, A, X[ 7], 19 );
+    P( A, B, C, D, X[ 8],  3 );
+    P( D, A, B, C, X[ 9],  7 );
+    P( C, D, A, B, X[10], 11 );
+    P( B, C, D, A, X[11], 19 );
+    P( A, B, C, D, X[12],  3 );
+    P( D, A, B, C, X[13],  7 );
+    P( C, D, A, B, X[14], 11 );
+    P( B, C, D, A, X[15], 19 );
+
+#undef P
+#undef F
+
+#define F(x,y,z) ((x & y) | (x & z) | (y & z))
+#define P(a,b,c,d,x,s) { a += F(b,c,d) + x + 0x5A827999; a = S(a,s); }
+
+    P( A, B, C, D, X[ 0],  3 );
+    P( D, A, B, C, X[ 4],  5 );
+    P( C, D, A, B, X[ 8],  9 );
+    P( B, C, D, A, X[12], 13 );
+    P( A, B, C, D, X[ 1],  3 );
+    P( D, A, B, C, X[ 5],  5 );
+    P( C, D, A, B, X[ 9],  9 );
+    P( B, C, D, A, X[13], 13 );
+    P( A, B, C, D, X[ 2],  3 );
+    P( D, A, B, C, X[ 6],  5 );
+    P( C, D, A, B, X[10],  9 );
+    P( B, C, D, A, X[14], 13 );
+    P( A, B, C, D, X[ 3],  3 );
+    P( D, A, B, C, X[ 7],  5 );
+    P( C, D, A, B, X[11],  9 );
+    P( B, C, D, A, X[15], 13 );
+
+#undef P
+#undef F
+
+#define F(x,y,z) (x ^ y ^ z)
+#define P(a,b,c,d,x,s) { a += F(b,c,d) + x + 0x6ED9EBA1; a = S(a,s); }
+
+    P( A, B, C, D, X[ 0],  3 );
+    P( D, A, B, C, X[ 8],  9 );
+    P( C, D, A, B, X[ 4], 11 );
+    P( B, C, D, A, X[12], 15 );
+    P( A, B, C, D, X[ 2],  3 );
+    P( D, A, B, C, X[10],  9 );
+    P( C, D, A, B, X[ 6], 11 );
+    P( B, C, D, A, X[14], 15 );
+    P( A, B, C, D, X[ 1],  3 );
+    P( D, A, B, C, X[ 9],  9 );
+    P( C, D, A, B, X[ 5], 11 );
+    P( B, C, D, A, X[13], 15 );
+    P( A, B, C, D, X[ 3],  3 );
+    P( D, A, B, C, X[11],  9 );
+    P( C, D, A, B, X[ 7], 11 );
+    P( B, C, D, A, X[15], 15 );
+
+#undef F
+#undef P
+
+    ctx->state[0] += A;
+    ctx->state[1] += B;
+    ctx->state[2] += C;
+    ctx->state[3] += D;
+}
+
+/*
+ * MD4 process buffer
+ */
+void md4_update( md4_context *ctx, const unsigned char *input, int ilen )
+{
+    int fill;
+    unsigned long left;
+
+    if( ilen <= 0 )
+        return;
+
+    left = ctx->total[0] & 0x3F;
+    fill = 64 - left;
+
+    ctx->total[0] += ilen;
+    ctx->total[0] &= 0xFFFFFFFF;
+
+    if( ctx->total[0] < (unsigned long) ilen )
+        ctx->total[1]++;
+
+    if( left && ilen >= fill )
+    {
+        MEMCPY( (void *) (ctx->buffer + left),
+                input, fill );
+        md4_process( ctx, ctx->buffer );
+        input += fill;
+        ilen  -= fill;
+        left = 0;
+    }
+
+    while( ilen >= 64 )
+    {
+        md4_process( ctx, input );
+        input += 64;
+        ilen  -= 64;
+    }
+
+    if( ilen > 0 )
+    {
+        MEMCPY( (void *) (ctx->buffer + left),
+                input, ilen );
+    }
+}
+
+static const unsigned char md4_padding[64] =
+{
+ 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+/*
+ * MD4 final digest
+ */
+void md4_finish( md4_context *ctx, unsigned char output[16] )
+{
+    unsigned long last, padn;
+    unsigned long high, low;
+    unsigned char msglen[8];
+
+    high = ( ctx->total[0] >> 29 )
+         | ( ctx->total[1] <<  3 );
+    low  = ( ctx->total[0] <<  3 );
+
+    PUT_ULONG_LE( low,  msglen, 0 );
+    PUT_ULONG_LE( high, msglen, 4 );
+
+    last = ctx->total[0] & 0x3F;
+    padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last );
+
+    md4_update( ctx, md4_padding, padn );
+    md4_update( ctx, msglen, 8 );
+
+    PUT_ULONG_LE( ctx->state[0], output,  0 );
+    PUT_ULONG_LE( ctx->state[1], output,  4 );
+    PUT_ULONG_LE( ctx->state[2], output,  8 );
+    PUT_ULONG_LE( ctx->state[3], output, 12 );
+}
+
+/*
+ * output = MD4( input buffer )
+ */
+void md4( unsigned char *input, int ilen, unsigned char output[16] )
+{
+    md4_context ctx;
+
+    md4_starts( &ctx );
+    md4_update( &ctx, input, ilen );
+    md4_finish( &ctx, output );
+}
+
+#endif /* PPP_SUPPORT && LWIP_INCLUDED_POLARSSL_MD4 */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/netif/ppp/polarssl/md5.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/netif/ppp/polarssl/md5.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/netif/ppp/polarssl/md5.c	(revision 457)
@@ -0,0 +1,300 @@
+/*
+ *  RFC 1321 compliant MD5 implementation
+ *
+ *  Based on XySSL: Copyright (C) 2006-2008  Christophe Devine
+ *
+ *  Copyright (C) 2009  Paul Bakker <polarssl_maintainer at polarssl dot org>
+ *
+ *  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.
+ *    * 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.
+ *    * Neither the names of PolarSSL or XySSL 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
+ *  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.
+ */
+/*
+ *  The MD5 algorithm was designed by Ron Rivest in 1991.
+ *
+ *  http://www.ietf.org/rfc/rfc1321.txt
+ */
+
+#include "netif/ppp/ppp_opts.h"
+#if PPP_SUPPORT && LWIP_INCLUDED_POLARSSL_MD5
+
+#include "netif/ppp/polarssl/md5.h"
+
+#include <string.h>
+
+/*
+ * 32-bit integer manipulation macros (little endian)
+ */
+#ifndef GET_ULONG_LE
+#define GET_ULONG_LE(n,b,i)                             \
+{                                                       \
+    (n) = ( (unsigned long) (b)[(i)    ]       )        \
+        | ( (unsigned long) (b)[(i) + 1] <<  8 )        \
+        | ( (unsigned long) (b)[(i) + 2] << 16 )        \
+        | ( (unsigned long) (b)[(i) + 3] << 24 );       \
+}
+#endif
+
+#ifndef PUT_ULONG_LE
+#define PUT_ULONG_LE(n,b,i)                             \
+{                                                       \
+    (b)[(i)    ] = (unsigned char) ( (n)       );       \
+    (b)[(i) + 1] = (unsigned char) ( (n) >>  8 );       \
+    (b)[(i) + 2] = (unsigned char) ( (n) >> 16 );       \
+    (b)[(i) + 3] = (unsigned char) ( (n) >> 24 );       \
+}
+#endif
+
+/*
+ * MD5 context setup
+ */
+void md5_starts( md5_context *ctx )
+{
+    ctx->total[0] = 0;
+    ctx->total[1] = 0;
+
+    ctx->state[0] = 0x67452301;
+    ctx->state[1] = 0xEFCDAB89;
+    ctx->state[2] = 0x98BADCFE;
+    ctx->state[3] = 0x10325476;
+}
+
+static void md5_process( md5_context *ctx, const unsigned char data[64] )
+{
+    unsigned long X[16], A, B, C, D;
+
+    GET_ULONG_LE( X[ 0], data,  0 );
+    GET_ULONG_LE( X[ 1], data,  4 );
+    GET_ULONG_LE( X[ 2], data,  8 );
+    GET_ULONG_LE( X[ 3], data, 12 );
+    GET_ULONG_LE( X[ 4], data, 16 );
+    GET_ULONG_LE( X[ 5], data, 20 );
+    GET_ULONG_LE( X[ 6], data, 24 );
+    GET_ULONG_LE( X[ 7], data, 28 );
+    GET_ULONG_LE( X[ 8], data, 32 );
+    GET_ULONG_LE( X[ 9], data, 36 );
+    GET_ULONG_LE( X[10], data, 40 );
+    GET_ULONG_LE( X[11], data, 44 );
+    GET_ULONG_LE( X[12], data, 48 );
+    GET_ULONG_LE( X[13], data, 52 );
+    GET_ULONG_LE( X[14], data, 56 );
+    GET_ULONG_LE( X[15], data, 60 );
+
+#define S(x,n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n)))
+
+#define P(a,b,c,d,k,s,t)                                \
+{                                                       \
+    a += F(b,c,d) + X[k] + t; a = S(a,s) + b;           \
+}
+
+    A = ctx->state[0];
+    B = ctx->state[1];
+    C = ctx->state[2];
+    D = ctx->state[3];
+
+#define F(x,y,z) (z ^ (x & (y ^ z)))
+
+    P( A, B, C, D,  0,  7, 0xD76AA478 );
+    P( D, A, B, C,  1, 12, 0xE8C7B756 );
+    P( C, D, A, B,  2, 17, 0x242070DB );
+    P( B, C, D, A,  3, 22, 0xC1BDCEEE );
+    P( A, B, C, D,  4,  7, 0xF57C0FAF );
+    P( D, A, B, C,  5, 12, 0x4787C62A );
+    P( C, D, A, B,  6, 17, 0xA8304613 );
+    P( B, C, D, A,  7, 22, 0xFD469501 );
+    P( A, B, C, D,  8,  7, 0x698098D8 );
+    P( D, A, B, C,  9, 12, 0x8B44F7AF );
+    P( C, D, A, B, 10, 17, 0xFFFF5BB1 );
+    P( B, C, D, A, 11, 22, 0x895CD7BE );
+    P( A, B, C, D, 12,  7, 0x6B901122 );
+    P( D, A, B, C, 13, 12, 0xFD987193 );
+    P( C, D, A, B, 14, 17, 0xA679438E );
+    P( B, C, D, A, 15, 22, 0x49B40821 );
+
+#undef F
+
+#define F(x,y,z) (y ^ (z & (x ^ y)))
+
+    P( A, B, C, D,  1,  5, 0xF61E2562 );
+    P( D, A, B, C,  6,  9, 0xC040B340 );
+    P( C, D, A, B, 11, 14, 0x265E5A51 );
+    P( B, C, D, A,  0, 20, 0xE9B6C7AA );
+    P( A, B, C, D,  5,  5, 0xD62F105D );
+    P( D, A, B, C, 10,  9, 0x02441453 );
+    P( C, D, A, B, 15, 14, 0xD8A1E681 );
+    P( B, C, D, A,  4, 20, 0xE7D3FBC8 );
+    P( A, B, C, D,  9,  5, 0x21E1CDE6 );
+    P( D, A, B, C, 14,  9, 0xC33707D6 );
+    P( C, D, A, B,  3, 14, 0xF4D50D87 );
+    P( B, C, D, A,  8, 20, 0x455A14ED );
+    P( A, B, C, D, 13,  5, 0xA9E3E905 );
+    P( D, A, B, C,  2,  9, 0xFCEFA3F8 );
+    P( C, D, A, B,  7, 14, 0x676F02D9 );
+    P( B, C, D, A, 12, 20, 0x8D2A4C8A );
+
+#undef F
+    
+#define F(x,y,z) (x ^ y ^ z)
+
+    P( A, B, C, D,  5,  4, 0xFFFA3942 );
+    P( D, A, B, C,  8, 11, 0x8771F681 );
+    P( C, D, A, B, 11, 16, 0x6D9D6122 );
+    P( B, C, D, A, 14, 23, 0xFDE5380C );
+    P( A, B, C, D,  1,  4, 0xA4BEEA44 );
+    P( D, A, B, C,  4, 11, 0x4BDECFA9 );
+    P( C, D, A, B,  7, 16, 0xF6BB4B60 );
+    P( B, C, D, A, 10, 23, 0xBEBFBC70 );
+    P( A, B, C, D, 13,  4, 0x289B7EC6 );
+    P( D, A, B, C,  0, 11, 0xEAA127FA );
+    P( C, D, A, B,  3, 16, 0xD4EF3085 );
+    P( B, C, D, A,  6, 23, 0x04881D05 );
+    P( A, B, C, D,  9,  4, 0xD9D4D039 );
+    P( D, A, B, C, 12, 11, 0xE6DB99E5 );
+    P( C, D, A, B, 15, 16, 0x1FA27CF8 );
+    P( B, C, D, A,  2, 23, 0xC4AC5665 );
+
+#undef F
+
+#define F(x,y,z) (y ^ (x | ~z))
+
+    P( A, B, C, D,  0,  6, 0xF4292244 );
+    P( D, A, B, C,  7, 10, 0x432AFF97 );
+    P( C, D, A, B, 14, 15, 0xAB9423A7 );
+    P( B, C, D, A,  5, 21, 0xFC93A039 );
+    P( A, B, C, D, 12,  6, 0x655B59C3 );
+    P( D, A, B, C,  3, 10, 0x8F0CCC92 );
+    P( C, D, A, B, 10, 15, 0xFFEFF47D );
+    P( B, C, D, A,  1, 21, 0x85845DD1 );
+    P( A, B, C, D,  8,  6, 0x6FA87E4F );
+    P( D, A, B, C, 15, 10, 0xFE2CE6E0 );
+    P( C, D, A, B,  6, 15, 0xA3014314 );
+    P( B, C, D, A, 13, 21, 0x4E0811A1 );
+    P( A, B, C, D,  4,  6, 0xF7537E82 );
+    P( D, A, B, C, 11, 10, 0xBD3AF235 );
+    P( C, D, A, B,  2, 15, 0x2AD7D2BB );
+    P( B, C, D, A,  9, 21, 0xEB86D391 );
+
+#undef F
+
+    ctx->state[0] += A;
+    ctx->state[1] += B;
+    ctx->state[2] += C;
+    ctx->state[3] += D;
+}
+
+/*
+ * MD5 process buffer
+ */
+void md5_update( md5_context *ctx, const unsigned char *input, int ilen )
+{
+    int fill;
+    unsigned long left;
+
+    if( ilen <= 0 )
+        return;
+
+    left = ctx->total[0] & 0x3F;
+    fill = 64 - left;
+
+    ctx->total[0] += ilen;
+    ctx->total[0] &= 0xFFFFFFFF;
+
+    if( ctx->total[0] < (unsigned long) ilen )
+        ctx->total[1]++;
+
+    if( left && ilen >= fill )
+    {
+        MEMCPY( (void *) (ctx->buffer + left),
+                input, fill );
+        md5_process( ctx, ctx->buffer );
+        input += fill;
+        ilen  -= fill;
+        left = 0;
+    }
+
+    while( ilen >= 64 )
+    {
+        md5_process( ctx, input );
+        input += 64;
+        ilen  -= 64;
+    }
+
+    if( ilen > 0 )
+    {
+        MEMCPY( (void *) (ctx->buffer + left),
+                input, ilen );
+    }
+}
+
+static const unsigned char md5_padding[64] =
+{
+ 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+/*
+ * MD5 final digest
+ */
+void md5_finish( md5_context *ctx, unsigned char output[16] )
+{
+    unsigned long last, padn;
+    unsigned long high, low;
+    unsigned char msglen[8];
+
+    high = ( ctx->total[0] >> 29 )
+         | ( ctx->total[1] <<  3 );
+    low  = ( ctx->total[0] <<  3 );
+
+    PUT_ULONG_LE( low,  msglen, 0 );
+    PUT_ULONG_LE( high, msglen, 4 );
+
+    last = ctx->total[0] & 0x3F;
+    padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last );
+
+    md5_update( ctx, md5_padding, padn );
+    md5_update( ctx, msglen, 8 );
+
+    PUT_ULONG_LE( ctx->state[0], output,  0 );
+    PUT_ULONG_LE( ctx->state[1], output,  4 );
+    PUT_ULONG_LE( ctx->state[2], output,  8 );
+    PUT_ULONG_LE( ctx->state[3], output, 12 );
+}
+
+/*
+ * output = MD5( input buffer )
+ */
+void md5( unsigned char *input, int ilen, unsigned char output[16] )
+{
+    md5_context ctx;
+
+    md5_starts( &ctx );
+    md5_update( &ctx, input, ilen );
+    md5_finish( &ctx, output );
+}
+
+#endif /* PPP_SUPPORT && LWIP_INCLUDED_POLARSSL_MD5 */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/netif/ppp/polarssl/sha1.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/netif/ppp/polarssl/sha1.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/netif/ppp/polarssl/sha1.c	(revision 457)
@@ -0,0 +1,335 @@
+/*
+ *  FIPS-180-1 compliant SHA-1 implementation
+ *
+ *  Based on XySSL: Copyright (C) 2006-2008  Christophe Devine
+ *
+ *  Copyright (C) 2009  Paul Bakker <polarssl_maintainer at polarssl dot org>
+ *
+ *  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.
+ *    * 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.
+ *    * Neither the names of PolarSSL or XySSL 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
+ *  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.
+ */
+/*
+ *  The SHA-1 standard was published by NIST in 1993.
+ *
+ *  http://www.itl.nist.gov/fipspubs/fip180-1.htm
+ */
+
+#include "netif/ppp/ppp_opts.h"
+#if PPP_SUPPORT && LWIP_INCLUDED_POLARSSL_SHA1
+
+#include "netif/ppp/polarssl/sha1.h"
+
+#include <string.h>
+
+/*
+ * 32-bit integer manipulation macros (big endian)
+ */
+#ifndef GET_ULONG_BE
+#define GET_ULONG_BE(n,b,i)                             \
+{                                                       \
+    (n) = ( (unsigned long) (b)[(i)    ] << 24 )        \
+        | ( (unsigned long) (b)[(i) + 1] << 16 )        \
+        | ( (unsigned long) (b)[(i) + 2] <<  8 )        \
+        | ( (unsigned long) (b)[(i) + 3]       );       \
+}
+#endif
+
+#ifndef PUT_ULONG_BE
+#define PUT_ULONG_BE(n,b,i)                             \
+{                                                       \
+    (b)[(i)    ] = (unsigned char) ( (n) >> 24 );       \
+    (b)[(i) + 1] = (unsigned char) ( (n) >> 16 );       \
+    (b)[(i) + 2] = (unsigned char) ( (n) >>  8 );       \
+    (b)[(i) + 3] = (unsigned char) ( (n)       );       \
+}
+#endif
+
+/*
+ * SHA-1 context setup
+ */
+void sha1_starts( sha1_context *ctx )
+{
+    ctx->total[0] = 0;
+    ctx->total[1] = 0;
+
+    ctx->state[0] = 0x67452301;
+    ctx->state[1] = 0xEFCDAB89;
+    ctx->state[2] = 0x98BADCFE;
+    ctx->state[3] = 0x10325476;
+    ctx->state[4] = 0xC3D2E1F0;
+}
+
+static void sha1_process( sha1_context *ctx, const unsigned char data[64] )
+{
+    unsigned long temp, W[16], A, B, C, D, E;
+
+    GET_ULONG_BE( W[ 0], data,  0 );
+    GET_ULONG_BE( W[ 1], data,  4 );
+    GET_ULONG_BE( W[ 2], data,  8 );
+    GET_ULONG_BE( W[ 3], data, 12 );
+    GET_ULONG_BE( W[ 4], data, 16 );
+    GET_ULONG_BE( W[ 5], data, 20 );
+    GET_ULONG_BE( W[ 6], data, 24 );
+    GET_ULONG_BE( W[ 7], data, 28 );
+    GET_ULONG_BE( W[ 8], data, 32 );
+    GET_ULONG_BE( W[ 9], data, 36 );
+    GET_ULONG_BE( W[10], data, 40 );
+    GET_ULONG_BE( W[11], data, 44 );
+    GET_ULONG_BE( W[12], data, 48 );
+    GET_ULONG_BE( W[13], data, 52 );
+    GET_ULONG_BE( W[14], data, 56 );
+    GET_ULONG_BE( W[15], data, 60 );
+
+#define S(x,n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n)))
+
+#define R(t)                                            \
+(                                                       \
+    temp = W[(t -  3) & 0x0F] ^ W[(t - 8) & 0x0F] ^     \
+           W[(t - 14) & 0x0F] ^ W[ t      & 0x0F],      \
+    ( W[t & 0x0F] = S(temp,1) )                         \
+)
+
+#define P(a,b,c,d,e,x)                                  \
+{                                                       \
+    e += S(a,5) + F(b,c,d) + K + x; b = S(b,30);        \
+}
+
+    A = ctx->state[0];
+    B = ctx->state[1];
+    C = ctx->state[2];
+    D = ctx->state[3];
+    E = ctx->state[4];
+
+#define F(x,y,z) (z ^ (x & (y ^ z)))
+#define K 0x5A827999
+
+    P( A, B, C, D, E, W[0]  );
+    P( E, A, B, C, D, W[1]  );
+    P( D, E, A, B, C, W[2]  );
+    P( C, D, E, A, B, W[3]  );
+    P( B, C, D, E, A, W[4]  );
+    P( A, B, C, D, E, W[5]  );
+    P( E, A, B, C, D, W[6]  );
+    P( D, E, A, B, C, W[7]  );
+    P( C, D, E, A, B, W[8]  );
+    P( B, C, D, E, A, W[9]  );
+    P( A, B, C, D, E, W[10] );
+    P( E, A, B, C, D, W[11] );
+    P( D, E, A, B, C, W[12] );
+    P( C, D, E, A, B, W[13] );
+    P( B, C, D, E, A, W[14] );
+    P( A, B, C, D, E, W[15] );
+    P( E, A, B, C, D, R(16) );
+    P( D, E, A, B, C, R(17) );
+    P( C, D, E, A, B, R(18) );
+    P( B, C, D, E, A, R(19) );
+
+#undef K
+#undef F
+
+#define F(x,y,z) (x ^ y ^ z)
+#define K 0x6ED9EBA1
+
+    P( A, B, C, D, E, R(20) );
+    P( E, A, B, C, D, R(21) );
+    P( D, E, A, B, C, R(22) );
+    P( C, D, E, A, B, R(23) );
+    P( B, C, D, E, A, R(24) );
+    P( A, B, C, D, E, R(25) );
+    P( E, A, B, C, D, R(26) );
+    P( D, E, A, B, C, R(27) );
+    P( C, D, E, A, B, R(28) );
+    P( B, C, D, E, A, R(29) );
+    P( A, B, C, D, E, R(30) );
+    P( E, A, B, C, D, R(31) );
+    P( D, E, A, B, C, R(32) );
+    P( C, D, E, A, B, R(33) );
+    P( B, C, D, E, A, R(34) );
+    P( A, B, C, D, E, R(35) );
+    P( E, A, B, C, D, R(36) );
+    P( D, E, A, B, C, R(37) );
+    P( C, D, E, A, B, R(38) );
+    P( B, C, D, E, A, R(39) );
+
+#undef K
+#undef F
+
+#define F(x,y,z) ((x & y) | (z & (x | y)))
+#define K 0x8F1BBCDC
+
+    P( A, B, C, D, E, R(40) );
+    P( E, A, B, C, D, R(41) );
+    P( D, E, A, B, C, R(42) );
+    P( C, D, E, A, B, R(43) );
+    P( B, C, D, E, A, R(44) );
+    P( A, B, C, D, E, R(45) );
+    P( E, A, B, C, D, R(46) );
+    P( D, E, A, B, C, R(47) );
+    P( C, D, E, A, B, R(48) );
+    P( B, C, D, E, A, R(49) );
+    P( A, B, C, D, E, R(50) );
+    P( E, A, B, C, D, R(51) );
+    P( D, E, A, B, C, R(52) );
+    P( C, D, E, A, B, R(53) );
+    P( B, C, D, E, A, R(54) );
+    P( A, B, C, D, E, R(55) );
+    P( E, A, B, C, D, R(56) );
+    P( D, E, A, B, C, R(57) );
+    P( C, D, E, A, B, R(58) );
+    P( B, C, D, E, A, R(59) );
+
+#undef K
+#undef F
+
+#define F(x,y,z) (x ^ y ^ z)
+#define K 0xCA62C1D6
+
+    P( A, B, C, D, E, R(60) );
+    P( E, A, B, C, D, R(61) );
+    P( D, E, A, B, C, R(62) );
+    P( C, D, E, A, B, R(63) );
+    P( B, C, D, E, A, R(64) );
+    P( A, B, C, D, E, R(65) );
+    P( E, A, B, C, D, R(66) );
+    P( D, E, A, B, C, R(67) );
+    P( C, D, E, A, B, R(68) );
+    P( B, C, D, E, A, R(69) );
+    P( A, B, C, D, E, R(70) );
+    P( E, A, B, C, D, R(71) );
+    P( D, E, A, B, C, R(72) );
+    P( C, D, E, A, B, R(73) );
+    P( B, C, D, E, A, R(74) );
+    P( A, B, C, D, E, R(75) );
+    P( E, A, B, C, D, R(76) );
+    P( D, E, A, B, C, R(77) );
+    P( C, D, E, A, B, R(78) );
+    P( B, C, D, E, A, R(79) );
+
+#undef K
+#undef F
+
+    ctx->state[0] += A;
+    ctx->state[1] += B;
+    ctx->state[2] += C;
+    ctx->state[3] += D;
+    ctx->state[4] += E;
+}
+
+/*
+ * SHA-1 process buffer
+ */
+void sha1_update( sha1_context *ctx, const unsigned char *input, int ilen )
+{
+    int fill;
+    unsigned long left;
+
+    if( ilen <= 0 )
+        return;
+
+    left = ctx->total[0] & 0x3F;
+    fill = 64 - left;
+
+    ctx->total[0] += ilen;
+    ctx->total[0] &= 0xFFFFFFFF;
+
+    if( ctx->total[0] < (unsigned long) ilen )
+        ctx->total[1]++;
+
+    if( left && ilen >= fill )
+    {
+        MEMCPY( (void *) (ctx->buffer + left),
+                input, fill );
+        sha1_process( ctx, ctx->buffer );
+        input += fill;
+        ilen  -= fill;
+        left = 0;
+    }
+
+    while( ilen >= 64 )
+    {
+        sha1_process( ctx, input );
+        input += 64;
+        ilen  -= 64;
+    }
+
+    if( ilen > 0 )
+    {
+        MEMCPY( (void *) (ctx->buffer + left),
+                input, ilen );
+    }
+}
+
+static const unsigned char sha1_padding[64] =
+{
+ 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+/*
+ * SHA-1 final digest
+ */
+void sha1_finish( sha1_context *ctx, unsigned char output[20] )
+{
+    unsigned long last, padn;
+    unsigned long high, low;
+    unsigned char msglen[8];
+
+    high = ( ctx->total[0] >> 29 )
+         | ( ctx->total[1] <<  3 );
+    low  = ( ctx->total[0] <<  3 );
+
+    PUT_ULONG_BE( high, msglen, 0 );
+    PUT_ULONG_BE( low,  msglen, 4 );
+
+    last = ctx->total[0] & 0x3F;
+    padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last );
+
+    sha1_update( ctx, sha1_padding, padn );
+    sha1_update( ctx, msglen, 8 );
+
+    PUT_ULONG_BE( ctx->state[0], output,  0 );
+    PUT_ULONG_BE( ctx->state[1], output,  4 );
+    PUT_ULONG_BE( ctx->state[2], output,  8 );
+    PUT_ULONG_BE( ctx->state[3], output, 12 );
+    PUT_ULONG_BE( ctx->state[4], output, 16 );
+}
+
+/*
+ * output = SHA-1( input buffer )
+ */
+void sha1( unsigned char *input, int ilen, unsigned char output[20] )
+{
+    sha1_context ctx;
+
+    sha1_starts( &ctx );
+    sha1_update( &ctx, input, ilen );
+    sha1_finish( &ctx, output );
+}
+
+#endif /* PPP_SUPPORT && LWIP_INCLUDED_POLARSSL_SHA1 */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/netif/ppp/ppp.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/netif/ppp/ppp.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/netif/ppp/ppp.c	(revision 457)
@@ -0,0 +1,1628 @@
+/*****************************************************************************
+* ppp.c - Network Point to Point Protocol program file.
+*
+* Copyright (c) 2003 by Marc Boucher, Services Informatiques (MBSI) inc.
+* portions Copyright (c) 1997 by Global Election Systems Inc.
+*
+* The authors hereby grant permission to use, copy, modify, distribute,
+* and license this software and its documentation for any purpose, provided
+* that existing copyright notices are retained in all copies and that this
+* notice and the following disclaimer are included verbatim in any
+* distributions. No written agreement, license, or royalty fee is required
+* for any of the authorized uses.
+*
+* THIS SOFTWARE IS PROVIDED BY THE 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 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.
+*
+******************************************************************************
+* REVISION HISTORY
+*
+* 03-01-01 Marc Boucher <marc@mbsi.ca>
+*   Ported to lwIP.
+* 97-11-05 Guy Lancaster <lancasterg@acm.org>, Global Election Systems Inc.
+*   Original.
+*****************************************************************************/
+
+/*
+ * ppp_defs.h - PPP definitions.
+ *
+ * if_pppvar.h - private structures and declarations for PPP.
+ *
+ * Copyright (c) 1994 The Australian National University.
+ * All rights reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation is hereby granted, provided that the above copyright
+ * notice appears in all copies.  This software is provided without any
+ * warranty, express or implied. The Australian National University
+ * makes no representations about the suitability of this software for
+ * any purpose.
+ *
+ * IN NO EVENT SHALL THE AUSTRALIAN NATIONAL UNIVERSITY BE LIABLE TO ANY
+ * PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+ * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF
+ * THE AUSTRALIAN NATIONAL UNIVERSITY HAVE BEEN ADVISED OF THE POSSIBILITY
+ * OF SUCH DAMAGE.
+ *
+ * THE AUSTRALIAN NATIONAL UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE AUSTRALIAN NATIONAL UNIVERSITY HAS NO
+ * OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS,
+ * OR MODIFICATIONS.
+ */
+
+/*
+ * if_ppp.h - Point-to-Point Protocol definitions.
+ *
+ * Copyright (c) 1989 Carnegie Mellon University.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms are permitted
+ * provided that the above copyright notice and this paragraph are
+ * duplicated in all such forms and that any documentation,
+ * advertising materials, and other materials related to such
+ * distribution and use acknowledge that the software was developed
+ * by Carnegie Mellon University.  The name of the
+ * University may not be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+/**
+ * @defgroup ppp PPP
+ * @ingroup netifs
+ * @verbinclude "ppp.txt"
+ */
+
+#include "netif/ppp/ppp_opts.h"
+#if PPP_SUPPORT /* don't build if not configured for use in lwipopts.h */
+
+#include "lwip/pbuf.h"
+#include "lwip/stats.h"
+#include "lwip/sys.h"
+#include "lwip/tcpip.h"
+#include "lwip/api.h"
+#include "lwip/snmp.h"
+#include "lwip/ip4.h" /* for ip4_input() */
+#if PPP_IPV6_SUPPORT
+#include "lwip/ip6.h" /* for ip6_input() */
+#endif /* PPP_IPV6_SUPPORT */
+#include "lwip/dns.h"
+
+#include "netif/ppp/ppp_impl.h"
+#include "netif/ppp/pppos.h"
+
+#include "netif/ppp/fsm.h"
+#include "netif/ppp/lcp.h"
+#include "netif/ppp/magic.h"
+
+#if PAP_SUPPORT
+#include "netif/ppp/upap.h"
+#endif /* PAP_SUPPORT */
+#if CHAP_SUPPORT
+#include "netif/ppp/chap-new.h"
+#endif /* CHAP_SUPPORT */
+#if EAP_SUPPORT
+#include "netif/ppp/eap.h"
+#endif /* EAP_SUPPORT */
+#if CCP_SUPPORT
+#include "netif/ppp/ccp.h"
+#endif /* CCP_SUPPORT */
+#if MPPE_SUPPORT
+#include "netif/ppp/mppe.h"
+#endif /* MPPE_SUPPORT */
+#if ECP_SUPPORT
+#include "netif/ppp/ecp.h"
+#endif /* EAP_SUPPORT */
+#if VJ_SUPPORT
+#include "netif/ppp/vj.h"
+#endif /* VJ_SUPPORT */
+#if PPP_IPV4_SUPPORT
+#include "netif/ppp/ipcp.h"
+#endif /* PPP_IPV4_SUPPORT */
+#if PPP_IPV6_SUPPORT
+#include "netif/ppp/ipv6cp.h"
+#endif /* PPP_IPV6_SUPPORT */
+
+/*************************/
+/*** LOCAL DEFINITIONS ***/
+/*************************/
+
+/* Memory pools */
+#if PPPOS_SUPPORT
+LWIP_MEMPOOL_PROTOTYPE(PPPOS_PCB);
+#endif
+#if PPPOE_SUPPORT
+LWIP_MEMPOOL_PROTOTYPE(PPPOE_IF);
+#endif
+#if PPPOL2TP_SUPPORT
+LWIP_MEMPOOL_PROTOTYPE(PPPOL2TP_PCB);
+#endif
+#if LWIP_PPP_API && LWIP_MPU_COMPATIBLE
+LWIP_MEMPOOL_PROTOTYPE(PPPAPI_MSG);
+#endif
+LWIP_MEMPOOL_DECLARE(PPP_PCB, MEMP_NUM_PPP_PCB, sizeof(ppp_pcb), "PPP_PCB")
+
+/* FIXME: add stats per PPP session */
+#if PPP_STATS_SUPPORT
+static struct timeval start_time; /* Time when link was started. */
+static struct pppd_stats old_link_stats;
+struct pppd_stats link_stats;
+unsigned link_connect_time;
+int link_stats_valid;
+#endif /* PPP_STATS_SUPPORT */
+
+/*
+ * PPP Data Link Layer "protocol" table.
+ * One entry per supported protocol.
+ * The last entry must be NULL.
+ */
+const struct protent* const protocols[] = {
+    &lcp_protent,
+#if PAP_SUPPORT
+    &pap_protent,
+#endif /* PAP_SUPPORT */
+#if CHAP_SUPPORT
+    &chap_protent,
+#endif /* CHAP_SUPPORT */
+#if CBCP_SUPPORT
+    &cbcp_protent,
+#endif /* CBCP_SUPPORT */
+#if PPP_IPV4_SUPPORT
+    &ipcp_protent,
+#endif /* PPP_IPV4_SUPPORT */
+#if PPP_IPV6_SUPPORT
+    &ipv6cp_protent,
+#endif /* PPP_IPV6_SUPPORT */
+#if CCP_SUPPORT
+    &ccp_protent,
+#endif /* CCP_SUPPORT */
+#if ECP_SUPPORT
+    &ecp_protent,
+#endif /* ECP_SUPPORT */
+#ifdef AT_CHANGE
+    &atcp_protent,
+#endif /* AT_CHANGE */
+#if EAP_SUPPORT
+    &eap_protent,
+#endif /* EAP_SUPPORT */
+    NULL
+};
+
+/* Prototypes for procedures local to this file. */
+static void ppp_do_connect(void *arg);
+static err_t ppp_netif_init_cb(struct netif *netif);
+#if PPP_IPV4_SUPPORT
+static err_t ppp_netif_output_ip4(struct netif *netif, struct pbuf *pb, const ip4_addr_t *ipaddr);
+#endif /* PPP_IPV4_SUPPORT */
+#if PPP_IPV6_SUPPORT
+static err_t ppp_netif_output_ip6(struct netif *netif, struct pbuf *pb, const ip6_addr_t *ipaddr);
+#endif /* PPP_IPV6_SUPPORT */
+static err_t ppp_netif_output(struct netif *netif, struct pbuf *pb, u16_t protocol);
+
+/***********************************/
+/*** PUBLIC FUNCTION DEFINITIONS ***/
+/***********************************/
+#if PPP_AUTH_SUPPORT
+void ppp_set_auth(ppp_pcb *pcb, u8_t authtype, const char *user, const char *passwd) {
+  LWIP_ASSERT_CORE_LOCKED();
+#if PAP_SUPPORT
+  pcb->settings.refuse_pap = !(authtype & PPPAUTHTYPE_PAP);
+#endif /* PAP_SUPPORT */
+#if CHAP_SUPPORT
+  pcb->settings.refuse_chap = !(authtype & PPPAUTHTYPE_CHAP);
+#if MSCHAP_SUPPORT
+  pcb->settings.refuse_mschap = !(authtype & PPPAUTHTYPE_MSCHAP);
+  pcb->settings.refuse_mschap_v2 = !(authtype & PPPAUTHTYPE_MSCHAP_V2);
+#endif /* MSCHAP_SUPPORT */
+#endif /* CHAP_SUPPORT */
+#if EAP_SUPPORT
+  pcb->settings.refuse_eap = !(authtype & PPPAUTHTYPE_EAP);
+#endif /* EAP_SUPPORT */
+  pcb->settings.user = user;
+  pcb->settings.passwd = passwd;
+}
+#endif /* PPP_AUTH_SUPPORT */
+
+#if MPPE_SUPPORT
+/* Set MPPE configuration */
+void ppp_set_mppe(ppp_pcb *pcb, u8_t flags) {
+  if (flags == PPP_MPPE_DISABLE) {
+    pcb->settings.require_mppe = 0;
+    return;
+  }
+
+  pcb->settings.require_mppe = 1;
+  pcb->settings.refuse_mppe_stateful = !(flags & PPP_MPPE_ALLOW_STATEFUL);
+  pcb->settings.refuse_mppe_40 = !!(flags & PPP_MPPE_REFUSE_40);
+  pcb->settings.refuse_mppe_128 = !!(flags & PPP_MPPE_REFUSE_128);
+}
+#endif /* MPPE_SUPPORT */
+
+#if PPP_NOTIFY_PHASE
+void ppp_set_notify_phase_callback(ppp_pcb *pcb, ppp_notify_phase_cb_fn notify_phase_cb) {
+  pcb->notify_phase_cb = notify_phase_cb;
+  notify_phase_cb(pcb, pcb->phase, pcb->ctx_cb);
+}
+#endif /* PPP_NOTIFY_PHASE */
+
+/*
+ * Initiate a PPP connection.
+ *
+ * This can only be called if PPP is in the dead phase.
+ *
+ * Holdoff is the time to wait (in seconds) before initiating
+ * the connection.
+ *
+ * If this port connects to a modem, the modem connection must be
+ * established before calling this.
+ */
+err_t ppp_connect(ppp_pcb *pcb, u16_t holdoff) {
+  LWIP_ASSERT_CORE_LOCKED();
+  if (pcb->phase != PPP_PHASE_DEAD) {
+    return ERR_ALREADY;
+  }
+
+  PPPDEBUG(LOG_DEBUG, ("ppp_connect[%d]: holdoff=%d\n", pcb->netif->num, holdoff));
+
+  magic_randomize();
+
+  if (holdoff == 0) {
+    ppp_do_connect(pcb);
+    return ERR_OK;
+  }
+
+  new_phase(pcb, PPP_PHASE_HOLDOFF);
+  sys_timeout((u32_t)(holdoff*1000), ppp_do_connect, pcb);
+  return ERR_OK;
+}
+
+#if PPP_SERVER
+/*
+ * Listen for an incoming PPP connection.
+ *
+ * This can only be called if PPP is in the dead phase.
+ *
+ * If this port connects to a modem, the modem connection must be
+ * established before calling this.
+ */
+err_t ppp_listen(ppp_pcb *pcb) {
+  LWIP_ASSERT_CORE_LOCKED();
+  if (pcb->phase != PPP_PHASE_DEAD) {
+    return ERR_ALREADY;
+  }
+
+  PPPDEBUG(LOG_DEBUG, ("ppp_listen[%d]\n", pcb->netif->num));
+
+  magic_randomize();
+
+  if (pcb->link_cb->listen) {
+    new_phase(pcb, PPP_PHASE_INITIALIZE);
+    pcb->link_cb->listen(pcb, pcb->link_ctx_cb);
+    return ERR_OK;
+  }
+  return ERR_IF;
+}
+#endif /* PPP_SERVER */
+
+/*
+ * Initiate the end of a PPP connection.
+ * Any outstanding packets in the queues are dropped.
+ *
+ * Setting nocarrier to 1 close the PPP connection without initiating the
+ * shutdown procedure. Always using nocarrier = 0 is still recommended,
+ * this is going to take a little longer time if your link is down, but
+ * is a safer choice for the PPP state machine.
+ *
+ * Return 0 on success, an error code on failure.
+ */
+err_t
+ppp_close(ppp_pcb *pcb, u8_t nocarrier)
+{
+  LWIP_ASSERT_CORE_LOCKED();
+
+  pcb->err_code = PPPERR_USER;
+
+  /* holdoff phase, cancel the reconnection */
+  if (pcb->phase == PPP_PHASE_HOLDOFF) {
+    sys_untimeout(ppp_do_connect, pcb);
+    new_phase(pcb, PPP_PHASE_DEAD);
+  }
+
+  /* dead phase, nothing to do, call the status callback to be consistent */
+  if (pcb->phase == PPP_PHASE_DEAD) {
+    pcb->link_status_cb(pcb, pcb->err_code, pcb->ctx_cb);
+    return ERR_OK;
+  }
+
+  /* Already terminating, nothing to do */
+  if (pcb->phase >= PPP_PHASE_TERMINATE) {
+    return ERR_INPROGRESS;
+  }
+
+  /* LCP not open, close link protocol */
+  if (pcb->phase < PPP_PHASE_ESTABLISH) {
+    new_phase(pcb, PPP_PHASE_DISCONNECT);
+    ppp_link_terminated(pcb);
+    return ERR_OK;
+  }
+
+  /*
+   * Only accept carrier lost signal on the stable running phase in order
+   * to prevent changing the PPP phase FSM in transition phases.
+   *
+   * Always using nocarrier = 0 is still recommended, this is going to
+   * take a little longer time, but is a safer choice from FSM point of view.
+   */
+  if (nocarrier && pcb->phase == PPP_PHASE_RUNNING) {
+    PPPDEBUG(LOG_DEBUG, ("ppp_close[%d]: carrier lost -> lcp_lowerdown\n", pcb->netif->num));
+    lcp_lowerdown(pcb);
+    /* forced link termination, this will force link protocol to disconnect. */
+    link_terminated(pcb);
+    return ERR_OK;
+  }
+
+  /* Disconnect */
+  PPPDEBUG(LOG_DEBUG, ("ppp_close[%d]: kill_link -> lcp_close\n", pcb->netif->num));
+  /* LCP soft close request. */
+  lcp_close(pcb, "User request");
+  return ERR_OK;
+}
+
+/*
+ * Release the control block.
+ *
+ * This can only be called if PPP is in the dead phase.
+ *
+ * You must use ppp_close() before if you wish to terminate
+ * an established PPP session.
+ *
+ * Return 0 on success, an error code on failure.
+ */
+err_t ppp_free(ppp_pcb *pcb) {
+  err_t err;
+  LWIP_ASSERT_CORE_LOCKED();
+  if (pcb->phase != PPP_PHASE_DEAD) {
+    return ERR_CONN;
+  }
+
+  PPPDEBUG(LOG_DEBUG, ("ppp_free[%d]\n", pcb->netif->num));
+
+  netif_remove(pcb->netif);
+
+  err = pcb->link_cb->free(pcb, pcb->link_ctx_cb);
+
+  LWIP_MEMPOOL_FREE(PPP_PCB, pcb);
+  return err;
+}
+
+/* Get and set parameters for the given connection.
+ * Return 0 on success, an error code on failure. */
+err_t
+ppp_ioctl(ppp_pcb *pcb, u8_t cmd, void *arg)
+{
+  LWIP_ASSERT_CORE_LOCKED();
+  if (pcb == NULL) {
+    return ERR_VAL;
+  }
+
+  switch(cmd) {
+    case PPPCTLG_UPSTATUS:      /* Get the PPP up status. */
+      if (!arg) {
+        goto fail;
+      }
+      *(int *)arg = (int)(0
+#if PPP_IPV4_SUPPORT
+           || pcb->if4_up
+#endif /* PPP_IPV4_SUPPORT */
+#if PPP_IPV6_SUPPORT
+           || pcb->if6_up
+#endif /* PPP_IPV6_SUPPORT */
+           );
+      return ERR_OK;
+
+    case PPPCTLG_ERRCODE:       /* Get the PPP error code. */
+      if (!arg) {
+        goto fail;
+      }
+      *(int *)arg = (int)(pcb->err_code);
+      return ERR_OK;
+
+    default:
+      goto fail;
+  }
+
+fail:
+  return ERR_VAL;
+}
+
+
+/**********************************/
+/*** LOCAL FUNCTION DEFINITIONS ***/
+/**********************************/
+
+static void ppp_do_connect(void *arg) {
+  ppp_pcb *pcb = (ppp_pcb*)arg;
+
+  LWIP_ASSERT("pcb->phase == PPP_PHASE_DEAD || pcb->phase == PPP_PHASE_HOLDOFF", pcb->phase == PPP_PHASE_DEAD || pcb->phase == PPP_PHASE_HOLDOFF);
+
+  new_phase(pcb, PPP_PHASE_INITIALIZE);
+  pcb->link_cb->connect(pcb, pcb->link_ctx_cb);
+}
+
+/*
+ * ppp_netif_init_cb - netif init callback
+ */
+static err_t ppp_netif_init_cb(struct netif *netif) {
+  netif->name[0] = 'p';
+  netif->name[1] = 'p';
+#if PPP_IPV4_SUPPORT
+  netif->output = ppp_netif_output_ip4;
+#endif /* PPP_IPV4_SUPPORT */
+#if PPP_IPV6_SUPPORT
+  netif->output_ip6 = ppp_netif_output_ip6;
+#endif /* PPP_IPV6_SUPPORT */
+  netif->flags = NETIF_FLAG_UP;
+#if LWIP_NETIF_HOSTNAME
+  /* @todo: Initialize interface hostname */
+  /* netif_set_hostname(netif, "lwip"); */
+#endif /* LWIP_NETIF_HOSTNAME */
+  return ERR_OK;
+}
+
+#if PPP_IPV4_SUPPORT
+/*
+ * Send an IPv4 packet on the given connection.
+ */
+static err_t ppp_netif_output_ip4(struct netif *netif, struct pbuf *pb, const ip4_addr_t *ipaddr) {
+  LWIP_UNUSED_ARG(ipaddr);
+  return ppp_netif_output(netif, pb, PPP_IP);
+}
+#endif /* PPP_IPV4_SUPPORT */
+
+#if PPP_IPV6_SUPPORT
+/*
+ * Send an IPv6 packet on the given connection.
+ */
+static err_t ppp_netif_output_ip6(struct netif *netif, struct pbuf *pb, const ip6_addr_t *ipaddr) {
+  LWIP_UNUSED_ARG(ipaddr);
+  return ppp_netif_output(netif, pb, PPP_IPV6);
+}
+#endif /* PPP_IPV6_SUPPORT */
+
+static err_t ppp_netif_output(struct netif *netif, struct pbuf *pb, u16_t protocol) {
+  ppp_pcb *pcb = (ppp_pcb*)netif->state;
+  err_t err;
+  struct pbuf *fpb = NULL;
+
+  /* Check that the link is up. */
+  if (0
+#if PPP_IPV4_SUPPORT
+      || (protocol == PPP_IP && !pcb->if4_up)
+#endif /* PPP_IPV4_SUPPORT */
+#if PPP_IPV6_SUPPORT
+      || (protocol == PPP_IPV6 && !pcb->if6_up)
+#endif /* PPP_IPV6_SUPPORT */
+      ) {
+    PPPDEBUG(LOG_ERR, ("ppp_netif_output[%d]: link not up\n", pcb->netif->num));
+    goto err_rte_drop;
+  }
+
+#if MPPE_SUPPORT
+  /* If MPPE is required, refuse any IP packet until we are able to crypt them. */
+  if (pcb->settings.require_mppe && pcb->ccp_transmit_method != CI_MPPE) {
+    PPPDEBUG(LOG_ERR, ("ppp_netif_output[%d]: MPPE required, not up\n", pcb->netif->num));
+    goto err_rte_drop;
+  }
+#endif /* MPPE_SUPPORT */
+
+#if VJ_SUPPORT
+  /*
+   * Attempt Van Jacobson header compression if VJ is configured and
+   * this is an IP packet.
+   */
+  if (protocol == PPP_IP && pcb->vj_enabled) {
+    switch (vj_compress_tcp(&pcb->vj_comp, &pb)) {
+      case TYPE_IP:
+        /* No change...
+           protocol = PPP_IP; */
+        break;
+      case TYPE_COMPRESSED_TCP:
+        /* vj_compress_tcp() returns a new allocated pbuf, indicate we should free
+         * our duplicated pbuf later */
+        fpb = pb;
+        protocol = PPP_VJC_COMP;
+        break;
+      case TYPE_UNCOMPRESSED_TCP:
+        /* vj_compress_tcp() returns a new allocated pbuf, indicate we should free
+         * our duplicated pbuf later */
+        fpb = pb;
+        protocol = PPP_VJC_UNCOMP;
+        break;
+      default:
+        PPPDEBUG(LOG_WARNING, ("ppp_netif_output[%d]: bad IP packet\n", pcb->netif->num));
+        LINK_STATS_INC(link.proterr);
+        LINK_STATS_INC(link.drop);
+        MIB2_STATS_NETIF_INC(pcb->netif, ifoutdiscards);
+        return ERR_VAL;
+    }
+  }
+#endif /* VJ_SUPPORT */
+
+#if CCP_SUPPORT
+  switch (pcb->ccp_transmit_method) {
+  case 0:
+    break; /* Don't compress */
+#if MPPE_SUPPORT
+  case CI_MPPE:
+    if ((err = mppe_compress(pcb, &pcb->mppe_comp, &pb, protocol)) != ERR_OK) {
+      LINK_STATS_INC(link.memerr);
+      LINK_STATS_INC(link.drop);
+      MIB2_STATS_NETIF_INC(netif, ifoutdiscards);
+      goto err;
+    }
+    /* if VJ compressor returned a new allocated pbuf, free it */
+    if (fpb) {
+      pbuf_free(fpb);
+    }
+    /* mppe_compress() returns a new allocated pbuf, indicate we should free
+     * our duplicated pbuf later */
+    fpb = pb;
+    protocol = PPP_COMP;
+    break;
+#endif /* MPPE_SUPPORT */
+  default:
+    PPPDEBUG(LOG_ERR, ("ppp_netif_output[%d]: bad CCP transmit method\n", pcb->netif->num));
+    goto err_rte_drop; /* Cannot really happen, we only negotiate what we are able to do */
+  }
+#endif /* CCP_SUPPORT */
+
+  err = pcb->link_cb->netif_output(pcb, pcb->link_ctx_cb, pb, protocol);
+  goto err;
+
+err_rte_drop:
+  err = ERR_RTE;
+  LINK_STATS_INC(link.rterr);
+  LINK_STATS_INC(link.drop);
+  MIB2_STATS_NETIF_INC(netif, ifoutdiscards);
+err:
+  if (fpb) {
+    pbuf_free(fpb);
+  }
+  return err;
+}
+
+/************************************/
+/*** PRIVATE FUNCTION DEFINITIONS ***/
+/************************************/
+
+/* Initialize the PPP subsystem. */
+int ppp_init(void)
+{
+#if PPPOS_SUPPORT
+  LWIP_MEMPOOL_INIT(PPPOS_PCB);
+#endif
+#if PPPOE_SUPPORT
+  LWIP_MEMPOOL_INIT(PPPOE_IF);
+#endif
+#if PPPOL2TP_SUPPORT
+  LWIP_MEMPOOL_INIT(PPPOL2TP_PCB);
+#endif
+#if LWIP_PPP_API && LWIP_MPU_COMPATIBLE
+  LWIP_MEMPOOL_INIT(PPPAPI_MSG);
+#endif
+
+  LWIP_MEMPOOL_INIT(PPP_PCB);
+
+  /*
+   * Initialize magic number generator now so that protocols may
+   * use magic numbers in initialization.
+   */
+  magic_init();
+
+  return 0;
+}
+ 
+/*
+ * Create a new PPP control block.
+ *
+ * This initializes the PPP control block but does not
+ * attempt to negotiate the LCP session.
+ *
+ * Return a new PPP connection control block pointer
+ * on success or a null pointer on failure.
+ */
+ppp_pcb *ppp_new(struct netif *pppif, const struct link_callbacks *callbacks, void *link_ctx_cb, ppp_link_status_cb_fn link_status_cb, void *ctx_cb) {
+  ppp_pcb *pcb;
+  const struct protent *protp;
+  int i;
+
+  /* PPP is single-threaded: without a callback,
+   * there is no way to know when the link is up. */
+  if (link_status_cb == NULL) {
+    return NULL;
+  }
+
+  pcb = (ppp_pcb*)LWIP_MEMPOOL_ALLOC(PPP_PCB);
+  if (pcb == NULL) {
+    return NULL;
+  }
+
+  memset(pcb, 0, sizeof(ppp_pcb));
+
+  /* default configuration */
+#if PAP_SUPPORT
+  pcb->settings.pap_timeout_time = UPAP_DEFTIMEOUT;
+  pcb->settings.pap_max_transmits = UPAP_DEFTRANSMITS;
+#if PPP_SERVER
+  pcb->settings.pap_req_timeout = UPAP_DEFREQTIME;
+#endif /* PPP_SERVER */
+#endif /* PAP_SUPPORT */
+
+#if CHAP_SUPPORT
+  pcb->settings.chap_timeout_time = CHAP_DEFTIMEOUT;
+  pcb->settings.chap_max_transmits = CHAP_DEFTRANSMITS;
+#if PPP_SERVER
+  pcb->settings.chap_rechallenge_time = CHAP_DEFRECHALLENGETIME;
+#endif /* PPP_SERVER */
+#endif /* CHAP_SUPPPORT */
+
+#if EAP_SUPPORT
+  pcb->settings.eap_req_time = EAP_DEFREQTIME;
+  pcb->settings.eap_allow_req = EAP_DEFALLOWREQ;
+#if PPP_SERVER
+  pcb->settings.eap_timeout_time = EAP_DEFTIMEOUT;
+  pcb->settings.eap_max_transmits = EAP_DEFTRANSMITS;
+#endif /* PPP_SERVER */
+#endif /* EAP_SUPPORT */
+
+  pcb->settings.lcp_loopbackfail = LCP_DEFLOOPBACKFAIL;
+  pcb->settings.lcp_echo_interval = LCP_ECHOINTERVAL;
+  pcb->settings.lcp_echo_fails = LCP_MAXECHOFAILS;
+
+  pcb->settings.fsm_timeout_time = FSM_DEFTIMEOUT;
+  pcb->settings.fsm_max_conf_req_transmits = FSM_DEFMAXCONFREQS;
+  pcb->settings.fsm_max_term_transmits = FSM_DEFMAXTERMREQS;
+  pcb->settings.fsm_max_nak_loops = FSM_DEFMAXNAKLOOPS;
+
+  pcb->netif = pppif;
+  MIB2_INIT_NETIF(pppif, snmp_ifType_ppp, 0);
+  if (!netif_add(pcb->netif,
+#if LWIP_IPV4
+                 IP4_ADDR_ANY4, IP4_ADDR_BROADCAST, IP4_ADDR_ANY4,
+#endif /* LWIP_IPV4 */
+                 (void *)pcb, ppp_netif_init_cb, NULL)) {
+    LWIP_MEMPOOL_FREE(PPP_PCB, pcb);
+    PPPDEBUG(LOG_ERR, ("ppp_new: netif_add failed\n"));
+    return NULL;
+  }
+
+  pcb->link_cb = callbacks;
+  pcb->link_ctx_cb = link_ctx_cb;
+  pcb->link_status_cb = link_status_cb;
+  pcb->ctx_cb = ctx_cb;
+
+  /*
+   * Initialize each protocol.
+   */
+  for (i = 0; (protp = protocols[i]) != NULL; ++i) {
+      (*protp->init)(pcb);
+  }
+
+  new_phase(pcb, PPP_PHASE_DEAD);
+  return pcb;
+}
+
+/** Initiate LCP open request */
+void ppp_start(ppp_pcb *pcb) {
+  PPPDEBUG(LOG_DEBUG, ("ppp_start[%d]\n", pcb->netif->num));
+
+  /* Clean data not taken care by anything else, mostly shared data. */
+#if PPP_STATS_SUPPORT
+  link_stats_valid = 0;
+#endif /* PPP_STATS_SUPPORT */
+#if MPPE_SUPPORT
+  pcb->mppe_keys_set = 0;
+  memset(&pcb->mppe_comp, 0, sizeof(pcb->mppe_comp));
+  memset(&pcb->mppe_decomp, 0, sizeof(pcb->mppe_decomp));
+#endif /* MPPE_SUPPORT */
+#if VJ_SUPPORT
+  vj_compress_init(&pcb->vj_comp);
+#endif /* VJ_SUPPORT */
+
+  /* Start protocol */
+  new_phase(pcb, PPP_PHASE_ESTABLISH);
+  lcp_open(pcb);
+  lcp_lowerup(pcb);
+  PPPDEBUG(LOG_DEBUG, ("ppp_start[%d]: finished\n", pcb->netif->num));
+}
+
+/** Called when link failed to setup */
+void ppp_link_failed(ppp_pcb *pcb) {
+  PPPDEBUG(LOG_DEBUG, ("ppp_link_failed[%d]\n", pcb->netif->num));
+  new_phase(pcb, PPP_PHASE_DEAD);
+  pcb->err_code = PPPERR_OPEN;
+  pcb->link_status_cb(pcb, pcb->err_code, pcb->ctx_cb);
+}
+
+/** Called when link is normally down (i.e. it was asked to end) */
+void ppp_link_end(ppp_pcb *pcb) {
+  PPPDEBUG(LOG_DEBUG, ("ppp_link_end[%d]\n", pcb->netif->num));
+  new_phase(pcb, PPP_PHASE_DEAD);
+  if (pcb->err_code == PPPERR_NONE) {
+    pcb->err_code = PPPERR_CONNECT;
+  }
+  pcb->link_status_cb(pcb, pcb->err_code, pcb->ctx_cb);
+}
+
+/*
+ * Pass the processed input packet to the appropriate handler.
+ * This function and all handlers run in the context of the tcpip_thread
+ */
+void ppp_input(ppp_pcb *pcb, struct pbuf *pb) {
+  u16_t protocol;
+#if PPP_DEBUG && PPP_PROTOCOLNAME
+    const char *pname;
+#endif /* PPP_DEBUG && PPP_PROTOCOLNAME */
+
+  magic_randomize();
+
+  if (pb->len < 2) {
+    PPPDEBUG(LOG_ERR, ("ppp_input[%d]: packet too short\n", pcb->netif->num));
+    goto drop;
+  }
+  protocol = (((u8_t *)pb->payload)[0] << 8) | ((u8_t*)pb->payload)[1];
+
+#if PRINTPKT_SUPPORT
+  ppp_dump_packet(pcb, "rcvd", (unsigned char *)pb->payload, pb->len);
+#endif /* PRINTPKT_SUPPORT */
+
+  pbuf_remove_header(pb, sizeof(protocol));
+
+  LINK_STATS_INC(link.recv);
+  MIB2_STATS_NETIF_INC(pcb->netif, ifinucastpkts);
+  MIB2_STATS_NETIF_ADD(pcb->netif, ifinoctets, pb->tot_len);
+
+  /*
+   * Toss all non-LCP packets unless LCP is OPEN.
+   */
+  if (protocol != PPP_LCP && pcb->lcp_fsm.state != PPP_FSM_OPENED) {
+    ppp_dbglog("Discarded non-LCP packet when LCP not open");
+    goto drop;
+  }
+
+  /*
+   * Until we get past the authentication phase, toss all packets
+   * except LCP, LQR and authentication packets.
+   */
+  if (pcb->phase <= PPP_PHASE_AUTHENTICATE
+   && !(protocol == PPP_LCP
+#if LQR_SUPPORT
+   || protocol == PPP_LQR
+#endif /* LQR_SUPPORT */
+#if PAP_SUPPORT
+   || protocol == PPP_PAP
+#endif /* PAP_SUPPORT */
+#if CHAP_SUPPORT
+   || protocol == PPP_CHAP
+#endif /* CHAP_SUPPORT */
+#if EAP_SUPPORT
+   || protocol == PPP_EAP
+#endif /* EAP_SUPPORT */
+   )) {
+    ppp_dbglog("discarding proto 0x%x in phase %d", protocol, pcb->phase);
+    goto drop;
+  }
+
+#if CCP_SUPPORT
+#if MPPE_SUPPORT
+  /*
+   * MPPE is required and unencrypted data has arrived (this
+   * should never happen!). We should probably drop the link if
+   * the protocol is in the range of what should be encrypted.
+   * At the least, we drop this packet.
+   */
+  if (pcb->settings.require_mppe && protocol != PPP_COMP && protocol < 0x8000) {
+    PPPDEBUG(LOG_ERR, ("ppp_input[%d]: MPPE required, received unencrypted data!\n", pcb->netif->num));
+    goto drop;
+  }
+#endif /* MPPE_SUPPORT */
+
+  if (protocol == PPP_COMP) {
+    u8_t *pl;
+
+    switch (pcb->ccp_receive_method) {
+#if MPPE_SUPPORT
+    case CI_MPPE:
+      if (mppe_decompress(pcb, &pcb->mppe_decomp, &pb) != ERR_OK) {
+        goto drop;
+      }
+      break;
+#endif /* MPPE_SUPPORT */
+    default:
+      PPPDEBUG(LOG_ERR, ("ppp_input[%d]: bad CCP receive method\n", pcb->netif->num));
+      goto drop; /* Cannot really happen, we only negotiate what we are able to do */
+    }
+
+    /* Assume no PFC */
+    if (pb->len < 2) {
+      goto drop;
+    }
+
+    /* Extract and hide protocol (do PFC decompression if necessary) */
+    pl = (u8_t*)pb->payload;
+    if (pl[0] & 0x01) {
+      protocol = pl[0];
+      pbuf_remove_header(pb, 1);
+    } else {
+      protocol = (pl[0] << 8) | pl[1];
+      pbuf_remove_header(pb, 2);
+    }
+  }
+#endif /* CCP_SUPPORT */
+
+  switch(protocol) {
+
+#if PPP_IPV4_SUPPORT
+    case PPP_IP:            /* Internet Protocol */
+      PPPDEBUG(LOG_INFO, ("ppp_input[%d]: ip in pbuf len=%d\n", pcb->netif->num, pb->tot_len));
+      ip4_input(pb, pcb->netif);
+      return;
+#endif /* PPP_IPV4_SUPPORT */
+
+#if PPP_IPV6_SUPPORT
+    case PPP_IPV6:          /* Internet Protocol Version 6 */
+      PPPDEBUG(LOG_INFO, ("ppp_input[%d]: ip6 in pbuf len=%d\n", pcb->netif->num, pb->tot_len));
+      ip6_input(pb, pcb->netif);
+      return;
+#endif /* PPP_IPV6_SUPPORT */
+
+#if VJ_SUPPORT
+    case PPP_VJC_COMP:      /* VJ compressed TCP */
+      /*
+       * Clip off the VJ header and prepend the rebuilt TCP/IP header and
+       * pass the result to IP.
+       */
+      PPPDEBUG(LOG_INFO, ("ppp_input[%d]: vj_comp in pbuf len=%d\n", pcb->netif->num, pb->tot_len));
+      if (pcb->vj_enabled && vj_uncompress_tcp(&pb, &pcb->vj_comp) >= 0) {
+        ip4_input(pb, pcb->netif);
+        return;
+      }
+      /* Something's wrong so drop it. */
+      PPPDEBUG(LOG_WARNING, ("ppp_input[%d]: Dropping VJ compressed\n", pcb->netif->num));
+      break;
+
+    case PPP_VJC_UNCOMP:    /* VJ uncompressed TCP */
+      /*
+       * Process the TCP/IP header for VJ header compression and then pass
+       * the packet to IP.
+       */
+      PPPDEBUG(LOG_INFO, ("ppp_input[%d]: vj_un in pbuf len=%d\n", pcb->netif->num, pb->tot_len));
+      if (pcb->vj_enabled && vj_uncompress_uncomp(pb, &pcb->vj_comp) >= 0) {
+        ip4_input(pb, pcb->netif);
+        return;
+      }
+      /* Something's wrong so drop it. */
+      PPPDEBUG(LOG_WARNING, ("ppp_input[%d]: Dropping VJ uncompressed\n", pcb->netif->num));
+      break;
+#endif /* VJ_SUPPORT */
+
+    default: {
+      int i;
+      const struct protent *protp;
+
+      /*
+       * Upcall the proper protocol input routine.
+       */
+      for (i = 0; (protp = protocols[i]) != NULL; ++i) {
+        if (protp->protocol == protocol) {
+          pb = pbuf_coalesce(pb, PBUF_RAW);
+          (*protp->input)(pcb, (u8_t*)pb->payload, pb->len);
+          goto out;
+        }
+#if 0   /* UNUSED
+         *
+         * This is actually a (hacked?) way for the Linux kernel to pass a data
+         * packet to pppd. pppd in normal condition only do signaling
+         * (LCP, PAP, CHAP, IPCP, ...) and does not handle any data packet at all.
+         *
+         * We don't even need this interface, which is only there because of PPP
+         * interface limitation between Linux kernel and pppd. For MPPE, which uses
+         * CCP to negotiate although it is not really a (de)compressor, we added
+         * ccp_resetrequest() in CCP and MPPE input data flow is calling either
+         * ccp_resetrequest() or lcp_close() if the issue is, respectively, non-fatal
+         * or fatal, this is what ccp_datainput() really do.
+         */
+        if (protocol == (protp->protocol & ~0x8000)
+          && protp->datainput != NULL) {
+          (*protp->datainput)(pcb, pb->payload, pb->len);
+          goto out;
+        }
+#endif /* UNUSED */
+      }
+
+#if PPP_DEBUG
+#if PPP_PROTOCOLNAME
+      pname = protocol_name(protocol);
+      if (pname != NULL) {
+        ppp_warn("Unsupported protocol '%s' (0x%x) received", pname, protocol);
+      } else
+#endif /* PPP_PROTOCOLNAME */
+        ppp_warn("Unsupported protocol 0x%x received", protocol);
+#endif /* PPP_DEBUG */
+        if (pbuf_add_header(pb, sizeof(protocol))) {
+          PPPDEBUG(LOG_WARNING, ("ppp_input[%d]: Dropping (pbuf_add_header failed)\n", pcb->netif->num));
+          goto drop;
+        }
+        lcp_sprotrej(pcb, (u8_t*)pb->payload, pb->len);
+      }
+      break;
+  }
+
+drop:
+  LINK_STATS_INC(link.drop);
+  MIB2_STATS_NETIF_INC(pcb->netif, ifindiscards);
+
+out:
+  pbuf_free(pb);
+}
+
+/*
+ * Write a pbuf to a ppp link, only used from PPP functions
+ * to send PPP packets.
+ *
+ * IPv4 and IPv6 packets from lwIP are sent, respectively,
+ * with ppp_netif_output_ip4() and ppp_netif_output_ip6()
+ * functions (which are callbacks of the netif PPP interface).
+ */
+err_t ppp_write(ppp_pcb *pcb, struct pbuf *p) {
+#if PRINTPKT_SUPPORT
+  ppp_dump_packet(pcb, "sent", (unsigned char *)p->payload+2, p->len-2);
+#endif /* PRINTPKT_SUPPORT */
+  return pcb->link_cb->write(pcb, pcb->link_ctx_cb, p);
+}
+
+void ppp_link_terminated(ppp_pcb *pcb) {
+  PPPDEBUG(LOG_DEBUG, ("ppp_link_terminated[%d]\n", pcb->netif->num));
+  pcb->link_cb->disconnect(pcb, pcb->link_ctx_cb);
+  PPPDEBUG(LOG_DEBUG, ("ppp_link_terminated[%d]: finished.\n", pcb->netif->num));
+}
+
+
+/************************************************************************
+ * Functions called by various PPP subsystems to configure
+ * the PPP interface or change the PPP phase.
+ */
+
+/*
+ * new_phase - signal the start of a new phase of pppd's operation.
+ */
+void new_phase(ppp_pcb *pcb, int p) {
+  pcb->phase = p;
+  PPPDEBUG(LOG_DEBUG, ("ppp phase changed[%d]: phase=%d\n", pcb->netif->num, pcb->phase));
+#if PPP_NOTIFY_PHASE
+  if (pcb->notify_phase_cb != NULL) {
+    pcb->notify_phase_cb(pcb, p, pcb->ctx_cb);
+  }
+#endif /* PPP_NOTIFY_PHASE */
+}
+
+/*
+ * ppp_send_config - configure the transmit-side characteristics of
+ * the ppp interface.
+ */
+int ppp_send_config(ppp_pcb *pcb, int mtu, u32_t accm, int pcomp, int accomp) {
+  LWIP_UNUSED_ARG(mtu);
+  /* pcb->mtu = mtu; -- set correctly with netif_set_mtu */
+
+  if (pcb->link_cb->send_config) {
+    pcb->link_cb->send_config(pcb, pcb->link_ctx_cb, accm, pcomp, accomp);
+  }
+
+  PPPDEBUG(LOG_INFO, ("ppp_send_config[%d]\n", pcb->netif->num) );
+  return 0;
+}
+
+/*
+ * ppp_recv_config - configure the receive-side characteristics of
+ * the ppp interface.
+ */
+int ppp_recv_config(ppp_pcb *pcb, int mru, u32_t accm, int pcomp, int accomp) {
+  LWIP_UNUSED_ARG(mru);
+
+  if (pcb->link_cb->recv_config) {
+    pcb->link_cb->recv_config(pcb, pcb->link_ctx_cb, accm, pcomp, accomp);
+  }
+
+  PPPDEBUG(LOG_INFO, ("ppp_recv_config[%d]\n", pcb->netif->num));
+  return 0;
+}
+
+#if PPP_IPV4_SUPPORT
+/*
+ * sifaddr - Config the interface IP addresses and netmask.
+ */
+int sifaddr(ppp_pcb *pcb, u32_t our_adr, u32_t his_adr, u32_t netmask) {
+  ip4_addr_t ip, nm, gw;
+
+  ip4_addr_set_u32(&ip, our_adr);
+  ip4_addr_set_u32(&nm, netmask);
+  ip4_addr_set_u32(&gw, his_adr);
+  netif_set_addr(pcb->netif, &ip, &nm, &gw);
+  return 1;
+}
+
+/********************************************************************
+ *
+ * cifaddr - Clear the interface IP addresses, and delete routes
+ * through the interface if possible.
+ */
+int cifaddr(ppp_pcb *pcb, u32_t our_adr, u32_t his_adr) {
+  LWIP_UNUSED_ARG(our_adr);
+  LWIP_UNUSED_ARG(his_adr);
+
+  netif_set_addr(pcb->netif, IP4_ADDR_ANY4, IP4_ADDR_BROADCAST, IP4_ADDR_ANY4);
+  return 1;
+}
+
+#if 0 /* UNUSED - PROXY ARP */
+/********************************************************************
+ *
+ * sifproxyarp - Make a proxy ARP entry for the peer.
+ */
+
+int sifproxyarp(ppp_pcb *pcb, u32_t his_adr) {
+  LWIP_UNUSED_ARG(pcb);
+  LWIP_UNUSED_ARG(his_adr);
+  return 0;
+}
+
+/********************************************************************
+ *
+ * cifproxyarp - Delete the proxy ARP entry for the peer.
+ */
+
+int cifproxyarp(ppp_pcb *pcb, u32_t his_adr) {
+  LWIP_UNUSED_ARG(pcb);
+  LWIP_UNUSED_ARG(his_adr);
+  return 0;
+}
+#endif /* UNUSED - PROXY ARP */
+
+#if LWIP_DNS
+/*
+ * sdns - Config the DNS servers
+ */
+int sdns(ppp_pcb *pcb, u32_t ns1, u32_t ns2) {
+  ip_addr_t ns;
+  LWIP_UNUSED_ARG(pcb);
+
+  ip_addr_set_ip4_u32_val(ns, ns1);
+  dns_setserver(0, &ns);
+  ip_addr_set_ip4_u32_val(ns, ns2);
+  dns_setserver(1, &ns);
+  return 1;
+}
+
+/********************************************************************
+ *
+ * cdns - Clear the DNS servers
+ */
+int cdns(ppp_pcb *pcb, u32_t ns1, u32_t ns2) {
+  const ip_addr_t *nsa;
+  ip_addr_t nsb;
+  LWIP_UNUSED_ARG(pcb);
+
+  nsa = dns_getserver(0);
+  ip_addr_set_ip4_u32_val(nsb, ns1);
+  if (ip_addr_cmp(nsa, &nsb)) {
+    dns_setserver(0, IP_ADDR_ANY);
+  }
+  nsa = dns_getserver(1);
+  ip_addr_set_ip4_u32_val(nsb, ns2);
+  if (ip_addr_cmp(nsa, &nsb)) {
+    dns_setserver(1, IP_ADDR_ANY);
+  }
+  return 1;
+}
+#endif /* LWIP_DNS */
+
+#if VJ_SUPPORT
+/********************************************************************
+ *
+ * sifvjcomp - config tcp header compression
+ */
+int sifvjcomp(ppp_pcb *pcb, int vjcomp, int cidcomp, int maxcid) {
+  pcb->vj_enabled = vjcomp;
+  pcb->vj_comp.compressSlot = cidcomp;
+  pcb->vj_comp.maxSlotIndex = maxcid;
+  PPPDEBUG(LOG_INFO, ("sifvjcomp[%d]: VJ compress enable=%d slot=%d max slot=%d\n",
+            pcb->netif->num, vjcomp, cidcomp, maxcid));
+  return 0;
+}
+#endif /* VJ_SUPPORT */
+
+/*
+ * sifup - Config the interface up and enable IP packets to pass.
+ */
+int sifup(ppp_pcb *pcb) {
+  pcb->if4_up = 1;
+  pcb->err_code = PPPERR_NONE;
+  netif_set_link_up(pcb->netif);
+
+  PPPDEBUG(LOG_DEBUG, ("sifup[%d]: err_code=%d\n", pcb->netif->num, pcb->err_code));
+  pcb->link_status_cb(pcb, pcb->err_code, pcb->ctx_cb);
+  return 1;
+}
+
+/********************************************************************
+ *
+ * sifdown - Disable the indicated protocol and config the interface
+ *           down if there are no remaining protocols.
+ */
+int sifdown(ppp_pcb *pcb) {
+
+  pcb->if4_up = 0;
+
+  if (1
+#if PPP_IPV6_SUPPORT
+   /* set the interface down if IPv6 is down as well */
+   && !pcb->if6_up
+#endif /* PPP_IPV6_SUPPORT */
+  ) {
+    /* make sure the netif link callback is called */
+    netif_set_link_down(pcb->netif);
+  }
+  PPPDEBUG(LOG_DEBUG, ("sifdown[%d]: err_code=%d\n", pcb->netif->num, pcb->err_code));
+  return 1;
+}
+
+/********************************************************************
+ *
+ * Return user specified netmask, modified by any mask we might determine
+ * for address `addr' (in network byte order).
+ * Here we scan through the system's list of interfaces, looking for
+ * any non-point-to-point interfaces which might appear to be on the same
+ * network as `addr'.  If we find any, we OR in their netmask to the
+ * user-specified netmask.
+ */
+u32_t get_mask(u32_t addr) {
+#if 0
+  u32_t mask, nmask;
+
+  addr = lwip_htonl(addr);
+  if (IP_CLASSA(addr)) { /* determine network mask for address class */
+    nmask = IP_CLASSA_NET;
+  } else if (IP_CLASSB(addr)) {
+    nmask = IP_CLASSB_NET;
+  } else {
+    nmask = IP_CLASSC_NET;
+  }
+
+  /* class D nets are disallowed by bad_ip_adrs */
+  mask = PP_HTONL(0xffffff00UL) | lwip_htonl(nmask);
+
+  /* XXX
+   * Scan through the system's network interfaces.
+   * Get each netmask and OR them into our mask.
+   */
+  /* return mask; */
+  return mask;
+#endif /* 0 */
+  LWIP_UNUSED_ARG(addr);
+  return IPADDR_BROADCAST;
+}
+#endif /* PPP_IPV4_SUPPORT */
+
+#if PPP_IPV6_SUPPORT
+#define IN6_LLADDR_FROM_EUI64(ip6, eui64) do {    \
+  ip6.addr[0] = PP_HTONL(0xfe800000);             \
+  ip6.addr[1] = 0;                                \
+  eui64_copy(eui64, ip6.addr[2]);                 \
+  } while (0)
+
+/********************************************************************
+ *
+ * sif6addr - Config the interface with an IPv6 link-local address
+ */
+int sif6addr(ppp_pcb *pcb, eui64_t our_eui64, eui64_t his_eui64) {
+  ip6_addr_t ip6;
+  LWIP_UNUSED_ARG(his_eui64);
+
+  IN6_LLADDR_FROM_EUI64(ip6, our_eui64);
+  netif_ip6_addr_set(pcb->netif, 0, &ip6);
+  netif_ip6_addr_set_state(pcb->netif, 0, IP6_ADDR_PREFERRED);
+  /* FIXME: should we add an IPv6 static neighbor using his_eui64 ? */
+  return 1;
+}
+
+/********************************************************************
+ *
+ * cif6addr - Remove IPv6 address from interface
+ */
+int cif6addr(ppp_pcb *pcb, eui64_t our_eui64, eui64_t his_eui64) {
+  LWIP_UNUSED_ARG(our_eui64);
+  LWIP_UNUSED_ARG(his_eui64);
+
+  netif_ip6_addr_set_state(pcb->netif, 0, IP6_ADDR_INVALID);
+  netif_ip6_addr_set(pcb->netif, 0, IP6_ADDR_ANY6);
+  return 1;
+}
+
+/*
+ * sif6up - Config the interface up and enable IPv6 packets to pass.
+ */
+int sif6up(ppp_pcb *pcb) {
+
+  pcb->if6_up = 1;
+  pcb->err_code = PPPERR_NONE;
+  netif_set_link_up(pcb->netif);
+
+  PPPDEBUG(LOG_DEBUG, ("sif6up[%d]: err_code=%d\n", pcb->netif->num, pcb->err_code));
+  pcb->link_status_cb(pcb, pcb->err_code, pcb->ctx_cb);
+  return 1;
+}
+
+/********************************************************************
+ *
+ * sif6down - Disable the indicated protocol and config the interface
+ *            down if there are no remaining protocols.
+ */
+int sif6down(ppp_pcb *pcb) {
+
+  pcb->if6_up = 0;
+
+  if (1
+#if PPP_IPV4_SUPPORT
+   /* set the interface down if IPv4 is down as well */
+   && !pcb->if4_up
+#endif /* PPP_IPV4_SUPPORT */
+  ) {
+    /* make sure the netif link callback is called */
+    netif_set_link_down(pcb->netif);
+  }
+  PPPDEBUG(LOG_DEBUG, ("sif6down[%d]: err_code=%d\n", pcb->netif->num, pcb->err_code));
+  return 1;
+}
+#endif /* PPP_IPV6_SUPPORT */
+
+#if DEMAND_SUPPORT
+/*
+ * sifnpmode - Set the mode for handling packets for a given NP.
+ */
+int sifnpmode(ppp_pcb *pcb, int proto, enum NPmode mode) {
+  LWIP_UNUSED_ARG(pcb);
+  LWIP_UNUSED_ARG(proto);
+  LWIP_UNUSED_ARG(mode);
+  return 0;
+}
+#endif /* DEMAND_SUPPORT */
+
+/*
+ * netif_set_mtu - set the MTU on the PPP network interface.
+ */
+void netif_set_mtu(ppp_pcb *pcb, int mtu) {
+
+  pcb->netif->mtu = mtu;
+  PPPDEBUG(LOG_INFO, ("netif_set_mtu[%d]: mtu=%d\n", pcb->netif->num, mtu));
+}
+
+/*
+ * netif_get_mtu - get PPP interface MTU
+ */
+int netif_get_mtu(ppp_pcb *pcb) {
+
+  return pcb->netif->mtu;
+}
+
+#if CCP_SUPPORT
+#if 0 /* unused */
+/*
+ * ccp_test - whether a given compression method is acceptable for use.
+ */
+int
+ccp_test(ppp_pcb *pcb, u_char *opt_ptr, int opt_len, int for_transmit)
+{
+  LWIP_UNUSED_ARG(pcb);
+  LWIP_UNUSED_ARG(opt_ptr);
+  LWIP_UNUSED_ARG(opt_len);
+  LWIP_UNUSED_ARG(for_transmit);
+  return -1;
+}
+#endif /* unused */
+
+/*
+ * ccp_set - inform about the current state of CCP.
+ */
+void
+ccp_set(ppp_pcb *pcb, u8_t isopen, u8_t isup, u8_t receive_method, u8_t transmit_method)
+{
+  LWIP_UNUSED_ARG(isopen);
+  LWIP_UNUSED_ARG(isup);
+  pcb->ccp_receive_method = receive_method;
+  pcb->ccp_transmit_method = transmit_method;
+  PPPDEBUG(LOG_DEBUG, ("ccp_set[%d]: is_open=%d, is_up=%d, receive_method=%u, transmit_method=%u\n",
+           pcb->netif->num, isopen, isup, receive_method, transmit_method));
+}
+
+void
+ccp_reset_comp(ppp_pcb *pcb)
+{
+  switch (pcb->ccp_transmit_method) {
+#if MPPE_SUPPORT
+  case CI_MPPE:
+    mppe_comp_reset(pcb, &pcb->mppe_comp);
+    break;
+#endif /* MPPE_SUPPORT */
+  default:
+    break;
+  }
+}
+
+void
+ccp_reset_decomp(ppp_pcb *pcb)
+{
+  switch (pcb->ccp_receive_method) {
+#if MPPE_SUPPORT
+  case CI_MPPE:
+    mppe_decomp_reset(pcb, &pcb->mppe_decomp);
+    break;
+#endif /* MPPE_SUPPORT */
+  default:
+    break;
+  }
+}
+
+#if 0 /* unused */
+/*
+ * ccp_fatal_error - returns 1 if decompression was disabled as a
+ * result of an error detected after decompression of a packet,
+ * 0 otherwise.  This is necessary because of patent nonsense.
+ */
+int
+ccp_fatal_error(ppp_pcb *pcb)
+{
+  LWIP_UNUSED_ARG(pcb);
+  return 1;
+}
+#endif /* unused */
+#endif /* CCP_SUPPORT */
+
+#if PPP_IDLETIMELIMIT
+/********************************************************************
+ *
+ * get_idle_time - return how long the link has been idle.
+ */
+int get_idle_time(ppp_pcb *pcb, struct ppp_idle *ip) {
+  /* FIXME: add idle time support and make it optional */
+  LWIP_UNUSED_ARG(pcb);
+  LWIP_UNUSED_ARG(ip);
+  return 1;
+}
+#endif /* PPP_IDLETIMELIMIT */
+
+#if DEMAND_SUPPORT
+/********************************************************************
+ *
+ * get_loop_output - get outgoing packets from the ppp device,
+ * and detect when we want to bring the real link up.
+ * Return value is 1 if we need to bring up the link, 0 otherwise.
+ */
+int get_loop_output(void) {
+  return 0;
+}
+#endif /* DEMAND_SUPPORT */
+
+#if PPP_PROTOCOLNAME
+/* List of protocol names, to make our messages a little more informative. */
+struct protocol_list {
+  u_short proto;
+  const char *name;
+} const protocol_list[] = {
+  { 0x21, "IP" },
+  { 0x23, "OSI Network Layer" },
+  { 0x25, "Xerox NS IDP" },
+  { 0x27, "DECnet Phase IV" },
+  { 0x29, "Appletalk" },
+  { 0x2b, "Novell IPX" },
+  { 0x2d, "VJ compressed TCP/IP" },
+  { 0x2f, "VJ uncompressed TCP/IP" },
+  { 0x31, "Bridging PDU" },
+  { 0x33, "Stream Protocol ST-II" },
+  { 0x35, "Banyan Vines" },
+  { 0x39, "AppleTalk EDDP" },
+  { 0x3b, "AppleTalk SmartBuffered" },
+  { 0x3d, "Multi-Link" },
+  { 0x3f, "NETBIOS Framing" },
+  { 0x41, "Cisco Systems" },
+  { 0x43, "Ascom Timeplex" },
+  { 0x45, "Fujitsu Link Backup and Load Balancing (LBLB)" },
+  { 0x47, "DCA Remote Lan" },
+  { 0x49, "Serial Data Transport Protocol (PPP-SDTP)" },
+  { 0x4b, "SNA over 802.2" },
+  { 0x4d, "SNA" },
+  { 0x4f, "IP6 Header Compression" },
+  { 0x51, "KNX Bridging Data" },
+  { 0x53, "Encryption" },
+  { 0x55, "Individual Link Encryption" },
+  { 0x57, "IPv6" },
+  { 0x59, "PPP Muxing" },
+  { 0x5b, "Vendor-Specific Network Protocol" },
+  { 0x61, "RTP IPHC Full Header" },
+  { 0x63, "RTP IPHC Compressed TCP" },
+  { 0x65, "RTP IPHC Compressed non-TCP" },
+  { 0x67, "RTP IPHC Compressed UDP 8" },
+  { 0x69, "RTP IPHC Compressed RTP 8" },
+  { 0x6f, "Stampede Bridging" },
+  { 0x73, "MP+" },
+  { 0xc1, "NTCITS IPI" },
+  { 0xfb, "single-link compression" },
+  { 0xfd, "Compressed Datagram" },
+  { 0x0201, "802.1d Hello Packets" },
+  { 0x0203, "IBM Source Routing BPDU" },
+  { 0x0205, "DEC LANBridge100 Spanning Tree" },
+  { 0x0207, "Cisco Discovery Protocol" },
+  { 0x0209, "Netcs Twin Routing" },
+  { 0x020b, "STP - Scheduled Transfer Protocol" },
+  { 0x020d, "EDP - Extreme Discovery Protocol" },
+  { 0x0211, "Optical Supervisory Channel Protocol" },
+  { 0x0213, "Optical Supervisory Channel Protocol" },
+  { 0x0231, "Luxcom" },
+  { 0x0233, "Sigma Network Systems" },
+  { 0x0235, "Apple Client Server Protocol" },
+  { 0x0281, "MPLS Unicast" },
+  { 0x0283, "MPLS Multicast" },
+  { 0x0285, "IEEE p1284.4 standard - data packets" },
+  { 0x0287, "ETSI TETRA Network Protocol Type 1" },
+  { 0x0289, "Multichannel Flow Treatment Protocol" },
+  { 0x2063, "RTP IPHC Compressed TCP No Delta" },
+  { 0x2065, "RTP IPHC Context State" },
+  { 0x2067, "RTP IPHC Compressed UDP 16" },
+  { 0x2069, "RTP IPHC Compressed RTP 16" },
+  { 0x4001, "Cray Communications Control Protocol" },
+  { 0x4003, "CDPD Mobile Network Registration Protocol" },
+  { 0x4005, "Expand accelerator protocol" },
+  { 0x4007, "ODSICP NCP" },
+  { 0x4009, "DOCSIS DLL" },
+  { 0x400B, "Cetacean Network Detection Protocol" },
+  { 0x4021, "Stacker LZS" },
+  { 0x4023, "RefTek Protocol" },
+  { 0x4025, "Fibre Channel" },
+  { 0x4027, "EMIT Protocols" },
+  { 0x405b, "Vendor-Specific Protocol (VSP)" },
+  { 0x8021, "Internet Protocol Control Protocol" },
+  { 0x8023, "OSI Network Layer Control Protocol" },
+  { 0x8025, "Xerox NS IDP Control Protocol" },
+  { 0x8027, "DECnet Phase IV Control Protocol" },
+  { 0x8029, "Appletalk Control Protocol" },
+  { 0x802b, "Novell IPX Control Protocol" },
+  { 0x8031, "Bridging NCP" },
+  { 0x8033, "Stream Protocol Control Protocol" },
+  { 0x8035, "Banyan Vines Control Protocol" },
+  { 0x803d, "Multi-Link Control Protocol" },
+  { 0x803f, "NETBIOS Framing Control Protocol" },
+  { 0x8041, "Cisco Systems Control Protocol" },
+  { 0x8043, "Ascom Timeplex" },
+  { 0x8045, "Fujitsu LBLB Control Protocol" },
+  { 0x8047, "DCA Remote Lan Network Control Protocol (RLNCP)" },
+  { 0x8049, "Serial Data Control Protocol (PPP-SDCP)" },
+  { 0x804b, "SNA over 802.2 Control Protocol" },
+  { 0x804d, "SNA Control Protocol" },
+  { 0x804f, "IP6 Header Compression Control Protocol" },
+  { 0x8051, "KNX Bridging Control Protocol" },
+  { 0x8053, "Encryption Control Protocol" },
+  { 0x8055, "Individual Link Encryption Control Protocol" },
+  { 0x8057, "IPv6 Control Protocol" },
+  { 0x8059, "PPP Muxing Control Protocol" },
+  { 0x805b, "Vendor-Specific Network Control Protocol (VSNCP)" },
+  { 0x806f, "Stampede Bridging Control Protocol" },
+  { 0x8073, "MP+ Control Protocol" },
+  { 0x80c1, "NTCITS IPI Control Protocol" },
+  { 0x80fb, "Single Link Compression Control Protocol" },
+  { 0x80fd, "Compression Control Protocol" },
+  { 0x8207, "Cisco Discovery Protocol Control" },
+  { 0x8209, "Netcs Twin Routing" },
+  { 0x820b, "STP - Control Protocol" },
+  { 0x820d, "EDPCP - Extreme Discovery Protocol Ctrl Prtcl" },
+  { 0x8235, "Apple Client Server Protocol Control" },
+  { 0x8281, "MPLSCP" },
+  { 0x8285, "IEEE p1284.4 standard - Protocol Control" },
+  { 0x8287, "ETSI TETRA TNP1 Control Protocol" },
+  { 0x8289, "Multichannel Flow Treatment Protocol" },
+  { 0xc021, "Link Control Protocol" },
+  { 0xc023, "Password Authentication Protocol" },
+  { 0xc025, "Link Quality Report" },
+  { 0xc027, "Shiva Password Authentication Protocol" },
+  { 0xc029, "CallBack Control Protocol (CBCP)" },
+  { 0xc02b, "BACP Bandwidth Allocation Control Protocol" },
+  { 0xc02d, "BAP" },
+  { 0xc05b, "Vendor-Specific Authentication Protocol (VSAP)" },
+  { 0xc081, "Container Control Protocol" },
+  { 0xc223, "Challenge Handshake Authentication Protocol" },
+  { 0xc225, "RSA Authentication Protocol" },
+  { 0xc227, "Extensible Authentication Protocol" },
+  { 0xc229, "Mitsubishi Security Info Exch Ptcl (SIEP)" },
+  { 0xc26f, "Stampede Bridging Authorization Protocol" },
+  { 0xc281, "Proprietary Authentication Protocol" },
+  { 0xc283, "Proprietary Authentication Protocol" },
+  { 0xc481, "Proprietary Node ID Authentication Protocol" },
+  { 0, NULL },
+};
+
+/*
+ * protocol_name - find a name for a PPP protocol.
+ */
+const char * protocol_name(int proto) {
+  const struct protocol_list *lp;
+
+  for (lp = protocol_list; lp->proto != 0; ++lp) {
+    if (proto == lp->proto) {
+      return lp->name;
+    }
+  }
+  return NULL;
+}
+#endif /* PPP_PROTOCOLNAME */
+
+#if PPP_STATS_SUPPORT
+
+/* ---- Note on PPP Stats support ----
+ *
+ * The one willing link stats support should add the get_ppp_stats()
+ * to fetch statistics from lwIP.
+ */
+
+/*
+ * reset_link_stats - "reset" stats when link goes up.
+ */
+void reset_link_stats(int u) {
+  if (!get_ppp_stats(u, &old_link_stats)) {
+    return;
+  }
+  gettimeofday(&start_time, NULL);
+}
+
+/*
+ * update_link_stats - get stats at link termination.
+ */
+void update_link_stats(int u) {
+  struct timeval now;
+  char numbuf[32];
+
+  if (!get_ppp_stats(u, &link_stats) || gettimeofday(&now, NULL) < 0) {
+    return;
+  }
+  link_connect_time = now.tv_sec - start_time.tv_sec;
+  link_stats_valid = 1;
+
+  link_stats.bytes_in  -= old_link_stats.bytes_in;
+  link_stats.bytes_out -= old_link_stats.bytes_out;
+  link_stats.pkts_in   -= old_link_stats.pkts_in;
+  link_stats.pkts_out  -= old_link_stats.pkts_out;
+}
+
+void print_link_stats() {
+  /*
+   * Print connect time and statistics.
+   */
+  if (link_stats_valid) {
+    int t = (link_connect_time + 5) / 6;    /* 1/10ths of minutes */
+    info("Connect time %d.%d minutes.", t/10, t%10);
+    info("Sent %u bytes, received %u bytes.", link_stats.bytes_out, link_stats.bytes_in);
+    link_stats_valid = 0;
+  }
+}
+#endif /* PPP_STATS_SUPPORT */
+
+#endif /* PPP_SUPPORT */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/netif/ppp/pppapi.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/netif/ppp/pppapi.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/netif/ppp/pppapi.c	(revision 457)
@@ -0,0 +1,427 @@
+/**
+ * @file
+ * Point To Point Protocol Sequential API module
+ *
+ */
+
+/*
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ */
+
+#include "netif/ppp/ppp_opts.h"
+
+#if LWIP_PPP_API /* don't build if not configured for use in lwipopts.h */
+
+#include "netif/ppp/pppapi.h"
+#include "lwip/priv/tcpip_priv.h"
+#include "netif/ppp/pppoe.h"
+#include "netif/ppp/pppol2tp.h"
+#include "netif/ppp/pppos.h"
+
+#if LWIP_MPU_COMPATIBLE
+LWIP_MEMPOOL_DECLARE(PPPAPI_MSG, MEMP_NUM_PPP_API_MSG, sizeof(struct pppapi_msg), "PPPAPI_MSG")
+#endif
+
+#define PPPAPI_VAR_REF(name)               API_VAR_REF(name)
+#define PPPAPI_VAR_DECLARE(name)           API_VAR_DECLARE(struct pppapi_msg, name)
+#define PPPAPI_VAR_ALLOC(name)             API_VAR_ALLOC_POOL(struct pppapi_msg, PPPAPI_MSG, name, ERR_MEM)
+#define PPPAPI_VAR_ALLOC_RETURN_NULL(name) API_VAR_ALLOC_POOL(struct pppapi_msg, PPPAPI_MSG, name, NULL)
+#define PPPAPI_VAR_FREE(name)              API_VAR_FREE_POOL(PPPAPI_MSG, name)
+
+/**
+ * Call ppp_set_default() inside the tcpip_thread context.
+ */
+static err_t
+pppapi_do_ppp_set_default(struct tcpip_api_call_data *m)
+{
+  /* cast through void* to silence alignment warnings. 
+   * We know it works because the structs have been instantiated as struct pppapi_msg */
+  struct pppapi_msg *msg = (struct pppapi_msg *)(void*)m;
+  
+  ppp_set_default(msg->msg.ppp);
+  return ERR_OK;
+}
+
+/**
+ * Call ppp_set_default() in a thread-safe way by running that function inside the
+ * tcpip_thread context.
+ */
+err_t
+pppapi_set_default(ppp_pcb *pcb)
+{
+  err_t err;
+  PPPAPI_VAR_DECLARE(msg);
+  PPPAPI_VAR_ALLOC(msg);
+
+  PPPAPI_VAR_REF(msg).msg.ppp = pcb;
+  err = tcpip_api_call(pppapi_do_ppp_set_default, &PPPAPI_VAR_REF(msg).call);
+  PPPAPI_VAR_FREE(msg);
+  return err;
+}
+
+
+#if PPP_NOTIFY_PHASE
+/**
+ * Call ppp_set_notify_phase_callback() inside the tcpip_thread context.
+ */
+static err_t
+pppapi_do_ppp_set_notify_phase_callback(struct tcpip_api_call_data *m)
+{
+  /* cast through void* to silence alignment warnings. 
+   * We know it works because the structs have been instantiated as struct pppapi_msg */
+   struct pppapi_msg *msg = (struct pppapi_msg *)(void*)m;
+
+  ppp_set_notify_phase_callback(msg->msg.ppp, msg->msg.msg.setnotifyphasecb.notify_phase_cb);
+  return ERR_OK;
+}
+
+/**
+ * Call ppp_set_notify_phase_callback() in a thread-safe way by running that function inside the
+ * tcpip_thread context.
+ */
+err_t
+pppapi_set_notify_phase_callback(ppp_pcb *pcb, ppp_notify_phase_cb_fn notify_phase_cb)
+{
+  err_t err;
+  PPPAPI_VAR_DECLARE(msg);
+  PPPAPI_VAR_ALLOC(msg);
+
+  PPPAPI_VAR_REF(msg).msg.ppp = pcb;
+  PPPAPI_VAR_REF(msg).msg.msg.setnotifyphasecb.notify_phase_cb = notify_phase_cb;
+  err = tcpip_api_call(pppapi_do_ppp_set_notify_phase_callback, &PPPAPI_VAR_REF(msg).call);
+  PPPAPI_VAR_FREE(msg);
+  return err;
+}
+#endif /* PPP_NOTIFY_PHASE */
+
+
+#if PPPOS_SUPPORT
+/**
+ * Call pppos_create() inside the tcpip_thread context.
+ */
+static err_t
+pppapi_do_pppos_create(struct tcpip_api_call_data *m)
+{
+  /* cast through void* to silence alignment warnings. 
+   * We know it works because the structs have been instantiated as struct pppapi_msg */
+  struct pppapi_msg *msg = (struct pppapi_msg *)(void*)m;
+
+  msg->msg.ppp = pppos_create(msg->msg.msg.serialcreate.pppif, msg->msg.msg.serialcreate.output_cb,
+    msg->msg.msg.serialcreate.link_status_cb, msg->msg.msg.serialcreate.ctx_cb);
+  return ERR_OK;
+}
+
+/**
+ * Call pppos_create() in a thread-safe way by running that function inside the
+ * tcpip_thread context.
+ */
+ppp_pcb*
+pppapi_pppos_create(struct netif *pppif, pppos_output_cb_fn output_cb,
+               ppp_link_status_cb_fn link_status_cb, void *ctx_cb)
+{
+  ppp_pcb* result;
+  PPPAPI_VAR_DECLARE(msg);
+  PPPAPI_VAR_ALLOC_RETURN_NULL(msg);
+
+  PPPAPI_VAR_REF(msg).msg.ppp = NULL;
+  PPPAPI_VAR_REF(msg).msg.msg.serialcreate.pppif = pppif;
+  PPPAPI_VAR_REF(msg).msg.msg.serialcreate.output_cb = output_cb;
+  PPPAPI_VAR_REF(msg).msg.msg.serialcreate.link_status_cb = link_status_cb;
+  PPPAPI_VAR_REF(msg).msg.msg.serialcreate.ctx_cb = ctx_cb;
+  tcpip_api_call(pppapi_do_pppos_create, &PPPAPI_VAR_REF(msg).call);
+  result = PPPAPI_VAR_REF(msg).msg.ppp;
+  PPPAPI_VAR_FREE(msg);
+  return result;
+}
+#endif /* PPPOS_SUPPORT */
+
+
+#if PPPOE_SUPPORT
+/**
+ * Call pppoe_create() inside the tcpip_thread context.
+ */
+static err_t
+pppapi_do_pppoe_create(struct tcpip_api_call_data *m)
+{
+  /* cast through void* to silence alignment warnings. 
+   * We know it works because the structs have been instantiated as struct pppapi_msg */
+  struct pppapi_msg *msg = (struct pppapi_msg *)(void*)m;
+
+  msg->msg.ppp = pppoe_create(msg->msg.msg.ethernetcreate.pppif, msg->msg.msg.ethernetcreate.ethif,
+    msg->msg.msg.ethernetcreate.service_name, msg->msg.msg.ethernetcreate.concentrator_name,
+    msg->msg.msg.ethernetcreate.link_status_cb, msg->msg.msg.ethernetcreate.ctx_cb);
+  return ERR_OK;
+}
+
+/**
+ * Call pppoe_create() in a thread-safe way by running that function inside the
+ * tcpip_thread context.
+ */
+ppp_pcb*
+pppapi_pppoe_create(struct netif *pppif, struct netif *ethif, const char *service_name,
+                            const char *concentrator_name, ppp_link_status_cb_fn link_status_cb,
+                            void *ctx_cb)
+{
+  ppp_pcb* result;
+  PPPAPI_VAR_DECLARE(msg);
+  PPPAPI_VAR_ALLOC_RETURN_NULL(msg);
+
+  PPPAPI_VAR_REF(msg).msg.ppp = NULL;
+  PPPAPI_VAR_REF(msg).msg.msg.ethernetcreate.pppif = pppif;
+  PPPAPI_VAR_REF(msg).msg.msg.ethernetcreate.ethif = ethif;
+  PPPAPI_VAR_REF(msg).msg.msg.ethernetcreate.service_name = service_name;
+  PPPAPI_VAR_REF(msg).msg.msg.ethernetcreate.concentrator_name = concentrator_name;
+  PPPAPI_VAR_REF(msg).msg.msg.ethernetcreate.link_status_cb = link_status_cb;
+  PPPAPI_VAR_REF(msg).msg.msg.ethernetcreate.ctx_cb = ctx_cb;
+  tcpip_api_call(pppapi_do_pppoe_create, &PPPAPI_VAR_REF(msg).call);
+  result = PPPAPI_VAR_REF(msg).msg.ppp;
+  PPPAPI_VAR_FREE(msg);
+  return result;
+}
+#endif /* PPPOE_SUPPORT */
+
+
+#if PPPOL2TP_SUPPORT
+/**
+ * Call pppol2tp_create() inside the tcpip_thread context.
+ */
+static err_t
+pppapi_do_pppol2tp_create(struct tcpip_api_call_data *m)
+{
+  /* cast through void* to silence alignment warnings. 
+   * We know it works because the structs have been instantiated as struct pppapi_msg */
+  struct pppapi_msg *msg = (struct pppapi_msg *)(void*)m;
+
+  msg->msg.ppp = pppol2tp_create(msg->msg.msg.l2tpcreate.pppif,
+    msg->msg.msg.l2tpcreate.netif, API_EXPR_REF(msg->msg.msg.l2tpcreate.ipaddr), msg->msg.msg.l2tpcreate.port,
+#if PPPOL2TP_AUTH_SUPPORT
+    msg->msg.msg.l2tpcreate.secret,
+    msg->msg.msg.l2tpcreate.secret_len,
+#else /* PPPOL2TP_AUTH_SUPPORT */
+    NULL,
+    0,
+#endif /* PPPOL2TP_AUTH_SUPPORT */
+    msg->msg.msg.l2tpcreate.link_status_cb, msg->msg.msg.l2tpcreate.ctx_cb);
+  return ERR_OK;
+}
+
+/**
+ * Call pppol2tp_create() in a thread-safe way by running that function inside the
+ * tcpip_thread context.
+ */
+ppp_pcb*
+pppapi_pppol2tp_create(struct netif *pppif, struct netif *netif, ip_addr_t *ipaddr, u16_t port,
+                        const u8_t *secret, u8_t secret_len,
+                        ppp_link_status_cb_fn link_status_cb, void *ctx_cb)
+{
+  ppp_pcb* result;
+  PPPAPI_VAR_DECLARE(msg);
+  PPPAPI_VAR_ALLOC_RETURN_NULL(msg);
+#if !PPPOL2TP_AUTH_SUPPORT
+  LWIP_UNUSED_ARG(secret);
+  LWIP_UNUSED_ARG(secret_len);
+#endif /* !PPPOL2TP_AUTH_SUPPORT */
+
+  PPPAPI_VAR_REF(msg).msg.ppp = NULL;
+  PPPAPI_VAR_REF(msg).msg.msg.l2tpcreate.pppif = pppif;
+  PPPAPI_VAR_REF(msg).msg.msg.l2tpcreate.netif = netif;
+  PPPAPI_VAR_REF(msg).msg.msg.l2tpcreate.ipaddr = PPPAPI_VAR_REF(ipaddr);
+  PPPAPI_VAR_REF(msg).msg.msg.l2tpcreate.port = port;
+#if PPPOL2TP_AUTH_SUPPORT
+  PPPAPI_VAR_REF(msg).msg.msg.l2tpcreate.secret = secret;
+  PPPAPI_VAR_REF(msg).msg.msg.l2tpcreate.secret_len = secret_len;
+#endif /* PPPOL2TP_AUTH_SUPPORT */
+  PPPAPI_VAR_REF(msg).msg.msg.l2tpcreate.link_status_cb = link_status_cb;
+  PPPAPI_VAR_REF(msg).msg.msg.l2tpcreate.ctx_cb = ctx_cb;
+  tcpip_api_call(pppapi_do_pppol2tp_create, &PPPAPI_VAR_REF(msg).call);
+  result = PPPAPI_VAR_REF(msg).msg.ppp;
+  PPPAPI_VAR_FREE(msg);
+  return result;
+}
+#endif /* PPPOL2TP_SUPPORT */
+
+
+/**
+ * Call ppp_connect() inside the tcpip_thread context.
+ */
+static err_t
+pppapi_do_ppp_connect(struct tcpip_api_call_data *m)
+{
+  /* cast through void* to silence alignment warnings. 
+   * We know it works because the structs have been instantiated as struct pppapi_msg */
+  struct pppapi_msg *msg = (struct pppapi_msg *)(void*)m;
+
+  return ppp_connect(msg->msg.ppp, msg->msg.msg.connect.holdoff);
+}
+
+/**
+ * Call ppp_connect() in a thread-safe way by running that function inside the
+ * tcpip_thread context.
+ */
+err_t
+pppapi_connect(ppp_pcb *pcb, u16_t holdoff)
+{
+  err_t err;
+  PPPAPI_VAR_DECLARE(msg);
+  PPPAPI_VAR_ALLOC(msg);
+
+  PPPAPI_VAR_REF(msg).msg.ppp = pcb;
+  PPPAPI_VAR_REF(msg).msg.msg.connect.holdoff = holdoff;
+  err = tcpip_api_call(pppapi_do_ppp_connect, &PPPAPI_VAR_REF(msg).call);
+  PPPAPI_VAR_FREE(msg);
+  return err;
+}
+
+
+#if PPP_SERVER
+/**
+ * Call ppp_listen() inside the tcpip_thread context.
+ */
+static err_t
+pppapi_do_ppp_listen(struct tcpip_api_call_data *m)
+{
+  /* cast through void* to silence alignment warnings. 
+   * We know it works because the structs have been instantiated as struct pppapi_msg */
+  struct pppapi_msg *msg = (struct pppapi_msg *)(void*)m;
+
+  return ppp_listen(msg->msg.ppp);
+}
+
+/**
+ * Call ppp_listen() in a thread-safe way by running that function inside the
+ * tcpip_thread context.
+ */
+err_t
+pppapi_listen(ppp_pcb *pcb)
+{
+  err_t err;
+  PPPAPI_VAR_DECLARE(msg);
+  PPPAPI_VAR_ALLOC(msg);
+
+  PPPAPI_VAR_REF(msg).msg.ppp = pcb;
+  err = tcpip_api_call(pppapi_do_ppp_listen, &PPPAPI_VAR_REF(msg).call);
+  PPPAPI_VAR_FREE(msg);
+  return err;
+}
+#endif /* PPP_SERVER */
+
+
+/**
+ * Call ppp_close() inside the tcpip_thread context.
+ */
+static err_t
+pppapi_do_ppp_close(struct tcpip_api_call_data *m)
+{
+  /* cast through void* to silence alignment warnings. 
+   * We know it works because the structs have been instantiated as struct pppapi_msg */
+  struct pppapi_msg *msg = (struct pppapi_msg *)(void*)m;
+
+  return ppp_close(msg->msg.ppp, msg->msg.msg.close.nocarrier);
+}
+
+/**
+ * Call ppp_close() in a thread-safe way by running that function inside the
+ * tcpip_thread context.
+ */
+err_t
+pppapi_close(ppp_pcb *pcb, u8_t nocarrier)
+{
+  err_t err;
+  PPPAPI_VAR_DECLARE(msg);
+  PPPAPI_VAR_ALLOC(msg);
+
+  PPPAPI_VAR_REF(msg).msg.ppp = pcb;
+  PPPAPI_VAR_REF(msg).msg.msg.close.nocarrier = nocarrier;
+  err = tcpip_api_call(pppapi_do_ppp_close, &PPPAPI_VAR_REF(msg).call);
+  PPPAPI_VAR_FREE(msg);
+  return err;
+}
+
+
+/**
+ * Call ppp_free() inside the tcpip_thread context.
+ */
+static err_t
+pppapi_do_ppp_free(struct tcpip_api_call_data *m)
+{
+  /* cast through void* to silence alignment warnings. 
+   * We know it works because the structs have been instantiated as struct pppapi_msg */
+  struct pppapi_msg *msg = (struct pppapi_msg *)(void*)m;
+
+  return ppp_free(msg->msg.ppp);
+}
+
+/**
+ * Call ppp_free() in a thread-safe way by running that function inside the
+ * tcpip_thread context.
+ */
+err_t
+pppapi_free(ppp_pcb *pcb)
+{
+  err_t err;
+  PPPAPI_VAR_DECLARE(msg);
+  PPPAPI_VAR_ALLOC(msg);
+
+  PPPAPI_VAR_REF(msg).msg.ppp = pcb;
+  err = tcpip_api_call(pppapi_do_ppp_free, &PPPAPI_VAR_REF(msg).call);
+  PPPAPI_VAR_FREE(msg);
+  return err;
+}
+
+
+/**
+ * Call ppp_ioctl() inside the tcpip_thread context.
+ */
+static err_t
+pppapi_do_ppp_ioctl(struct tcpip_api_call_data *m)
+{
+  /* cast through void* to silence alignment warnings. 
+   * We know it works because the structs have been instantiated as struct pppapi_msg */
+  struct pppapi_msg *msg = (struct pppapi_msg *)(void*)m;
+
+  return ppp_ioctl(msg->msg.ppp, msg->msg.msg.ioctl.cmd, msg->msg.msg.ioctl.arg);
+}
+
+/**
+ * Call ppp_ioctl() in a thread-safe way by running that function inside the
+ * tcpip_thread context.
+ */
+err_t
+pppapi_ioctl(ppp_pcb *pcb, u8_t cmd, void *arg)
+{
+  err_t err;
+  PPPAPI_VAR_DECLARE(msg);
+  PPPAPI_VAR_ALLOC(msg);
+
+  PPPAPI_VAR_REF(msg).msg.ppp = pcb;
+  PPPAPI_VAR_REF(msg).msg.msg.ioctl.cmd = cmd;
+  PPPAPI_VAR_REF(msg).msg.msg.ioctl.arg = arg;
+  err = tcpip_api_call(pppapi_do_ppp_ioctl, &PPPAPI_VAR_REF(msg).call);
+  PPPAPI_VAR_FREE(msg);
+  return err;
+}
+
+#endif /* LWIP_PPP_API */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/netif/ppp/pppcrypt.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/netif/ppp/pppcrypt.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/netif/ppp/pppcrypt.c	(revision 457)
@@ -0,0 +1,66 @@
+/*
+ * pppcrypt.c - PPP/DES linkage for MS-CHAP and EAP SRP-SHA1
+ *
+ * Extracted from chap_ms.c by James Carlson.
+ *
+ * Copyright (c) 1995 Eric Rosenquist.  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. The name(s) of the authors of this software must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission.
+ *
+ * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO
+ * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
+ * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
+ * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
+ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include "netif/ppp/ppp_opts.h"
+#if PPP_SUPPORT && MSCHAP_SUPPORT /* don't build if not necessary */
+
+#include "netif/ppp/ppp_impl.h"
+
+#include "netif/ppp/pppcrypt.h"
+
+
+static u_char pppcrypt_get_7bits(u_char *input, int startBit) {
+	unsigned int word;
+
+	word  = (unsigned)input[startBit / 8] << 8;
+	word |= (unsigned)input[startBit / 8 + 1];
+
+	word >>= 15 - (startBit % 8 + 7);
+
+	return word & 0xFE;
+}
+
+/* IN  56 bit DES key missing parity bits
+ * OUT 64 bit DES key with parity bits added
+ */
+void pppcrypt_56_to_64_bit_key(u_char *key, u_char * des_key) {
+	des_key[0] = pppcrypt_get_7bits(key,  0);
+	des_key[1] = pppcrypt_get_7bits(key,  7);
+	des_key[2] = pppcrypt_get_7bits(key, 14);
+	des_key[3] = pppcrypt_get_7bits(key, 21);
+	des_key[4] = pppcrypt_get_7bits(key, 28);
+	des_key[5] = pppcrypt_get_7bits(key, 35);
+	des_key[6] = pppcrypt_get_7bits(key, 42);
+	des_key[7] = pppcrypt_get_7bits(key, 49);
+}
+
+#endif /* PPP_SUPPORT && MSCHAP_SUPPORT */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/netif/ppp/pppoe.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/netif/ppp/pppoe.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/netif/ppp/pppoe.c	(revision 457)
@@ -0,0 +1,1201 @@
+/*****************************************************************************
+* pppoe.c - PPP Over Ethernet implementation for lwIP.
+*
+* Copyright (c) 2006 by Marc Boucher, Services Informatiques (MBSI) inc.
+*
+* The authors hereby grant permission to use, copy, modify, distribute,
+* and license this software and its documentation for any purpose, provided
+* that existing copyright notices are retained in all copies and that this
+* notice and the following disclaimer are included verbatim in any 
+* distributions. No written agreement, license, or royalty fee is required
+* for any of the authorized uses.
+*
+* THIS SOFTWARE IS PROVIDED BY THE 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 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.
+*
+******************************************************************************
+* REVISION HISTORY
+*
+* 06-01-01 Marc Boucher <marc@mbsi.ca>
+*   Ported to lwIP.
+*****************************************************************************/
+
+
+
+/* based on NetBSD: if_pppoe.c,v 1.64 2006/01/31 23:50:15 martin Exp */
+
+/*-
+ * Copyright (c) 2002 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Martin Husemann <martin@NetBSD.org>.
+ *
+ * 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. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *        This product includes software developed by the NetBSD
+ *        Foundation, Inc. and its contributors.
+ * 4. Neither the name of The NetBSD Foundation 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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 "netif/ppp/ppp_opts.h"
+#if PPP_SUPPORT && PPPOE_SUPPORT /* don't build if not configured for use in lwipopts.h */
+
+#if 0 /* UNUSED */
+#include <string.h>
+#include <stdio.h>
+#endif /* UNUSED */
+
+#include "lwip/timeouts.h"
+#include "lwip/memp.h"
+#include "lwip/stats.h"
+#include "lwip/snmp.h"
+
+#include "netif/ethernet.h"
+#include "netif/ppp/ppp_impl.h"
+#include "netif/ppp/lcp.h"
+#include "netif/ppp/ipcp.h"
+#include "netif/ppp/pppoe.h"
+
+/* Memory pool */
+LWIP_MEMPOOL_DECLARE(PPPOE_IF, MEMP_NUM_PPPOE_INTERFACES, sizeof(struct pppoe_softc), "PPPOE_IF")
+
+/* Add a 16 bit unsigned value to a buffer pointed to by PTR */
+#define PPPOE_ADD_16(PTR, VAL) \
+    *(PTR)++ = (u8_t)((VAL) / 256);    \
+    *(PTR)++ = (u8_t)((VAL) % 256)
+
+/* Add a complete PPPoE header to the buffer pointed to by PTR */
+#define PPPOE_ADD_HEADER(PTR, CODE, SESS, LEN)  \
+    *(PTR)++ = PPPOE_VERTYPE;  \
+    *(PTR)++ = (CODE);         \
+    PPPOE_ADD_16(PTR, SESS);   \
+    PPPOE_ADD_16(PTR, LEN)
+
+#define PPPOE_DISC_TIMEOUT (5*1000)  /* base for quick timeout calculation */
+#define PPPOE_SLOW_RETRY   (60*1000) /* persistent retry interval */
+#define PPPOE_DISC_MAXPADI  4        /* retry PADI four times (quickly) */
+#define PPPOE_DISC_MAXPADR  2        /* retry PADR twice */
+
+#ifdef PPPOE_SERVER
+#error "PPPOE_SERVER is not yet supported under lwIP!"
+/* from if_spppsubr.c */
+#define IFF_PASSIVE IFF_LINK0 /* wait passively for connection */
+#endif
+
+#define PPPOE_ERRORSTRING_LEN     64
+
+
+/* callbacks called from PPP core */
+static err_t pppoe_write(ppp_pcb *ppp, void *ctx, struct pbuf *p);
+static err_t pppoe_netif_output(ppp_pcb *ppp, void *ctx, struct pbuf *p, u_short protocol);
+static void pppoe_connect(ppp_pcb *ppp, void *ctx);
+static void pppoe_disconnect(ppp_pcb *ppp, void *ctx);
+static err_t pppoe_destroy(ppp_pcb *ppp, void *ctx);
+
+/* management routines */
+static void pppoe_abort_connect(struct pppoe_softc *);
+#if 0 /* UNUSED */
+static void pppoe_clear_softc(struct pppoe_softc *, const char *);
+#endif /* UNUSED */
+
+/* internal timeout handling */
+static void pppoe_timeout(void *);
+
+/* sending actual protocol controll packets */
+static err_t pppoe_send_padi(struct pppoe_softc *);
+static err_t pppoe_send_padr(struct pppoe_softc *);
+#ifdef PPPOE_SERVER
+static err_t pppoe_send_pado(struct pppoe_softc *);
+static err_t pppoe_send_pads(struct pppoe_softc *);
+#endif
+static err_t pppoe_send_padt(struct netif *, u_int, const u8_t *);
+
+/* internal helper functions */
+static err_t pppoe_xmit(struct pppoe_softc *sc, struct pbuf *pb);
+static struct pppoe_softc* pppoe_find_softc_by_session(u_int session, struct netif *rcvif);
+static struct pppoe_softc* pppoe_find_softc_by_hunique(u8_t *token, size_t len, struct netif *rcvif);
+
+/** linked list of created pppoe interfaces */
+static struct pppoe_softc *pppoe_softc_list;
+
+/* Callbacks structure for PPP core */
+static const struct link_callbacks pppoe_callbacks = {
+  pppoe_connect,
+#if PPP_SERVER
+  NULL,
+#endif /* PPP_SERVER */
+  pppoe_disconnect,
+  pppoe_destroy,
+  pppoe_write,
+  pppoe_netif_output,
+  NULL,
+  NULL
+};
+
+/*
+ * Create a new PPP Over Ethernet (PPPoE) connection.
+ *
+ * Return 0 on success, an error code on failure.
+ */
+ppp_pcb *pppoe_create(struct netif *pppif,
+       struct netif *ethif,
+       const char *service_name, const char *concentrator_name,
+       ppp_link_status_cb_fn link_status_cb, void *ctx_cb)
+{
+  ppp_pcb *ppp;
+  struct pppoe_softc *sc;
+  LWIP_UNUSED_ARG(service_name);
+  LWIP_UNUSED_ARG(concentrator_name);
+  LWIP_ASSERT_CORE_LOCKED();
+
+  sc = (struct pppoe_softc *)LWIP_MEMPOOL_ALLOC(PPPOE_IF);
+  if (sc == NULL) {
+    return NULL;
+  }
+
+  ppp = ppp_new(pppif, &pppoe_callbacks, sc, link_status_cb, ctx_cb);
+  if (ppp == NULL) {
+    LWIP_MEMPOOL_FREE(PPPOE_IF, sc);
+    return NULL;
+  }
+
+  memset(sc, 0, sizeof(struct pppoe_softc));
+  sc->pcb = ppp;
+  sc->sc_ethif = ethif;
+  /* put the new interface at the head of the list */
+  sc->next = pppoe_softc_list;
+  pppoe_softc_list = sc;
+  return ppp;
+}
+
+/* Called by PPP core */
+static err_t pppoe_write(ppp_pcb *ppp, void *ctx, struct pbuf *p) {
+  struct pppoe_softc *sc = (struct pppoe_softc *)ctx;
+  struct pbuf *ph; /* Ethernet + PPPoE header */
+  err_t ret;
+#if MIB2_STATS
+  u16_t tot_len;
+#else /* MIB2_STATS */
+  LWIP_UNUSED_ARG(ppp);
+#endif /* MIB2_STATS */
+
+  /* skip address & flags */
+  pbuf_remove_header(p, 2);
+
+  ph = pbuf_alloc(PBUF_LINK, (u16_t)(PPPOE_HEADERLEN), PBUF_RAM);
+  if(!ph) {
+    LINK_STATS_INC(link.memerr);
+    LINK_STATS_INC(link.proterr);
+    MIB2_STATS_NETIF_INC(ppp->netif, ifoutdiscards);
+    pbuf_free(p);
+    return ERR_MEM;
+  }
+
+  pbuf_remove_header(ph, PPPOE_HEADERLEN); /* hide PPPoE header */
+  pbuf_cat(ph, p);
+#if MIB2_STATS
+  tot_len = ph->tot_len;
+#endif /* MIB2_STATS */
+
+  ret = pppoe_xmit(sc, ph);
+  if (ret != ERR_OK) {
+    LINK_STATS_INC(link.err);
+    MIB2_STATS_NETIF_INC(ppp->netif, ifoutdiscards);
+    return ret;
+  }
+
+  MIB2_STATS_NETIF_ADD(ppp->netif, ifoutoctets, (u16_t)tot_len);
+  MIB2_STATS_NETIF_INC(ppp->netif, ifoutucastpkts);
+  LINK_STATS_INC(link.xmit);
+  return ERR_OK;
+}
+
+/* Called by PPP core */
+static err_t pppoe_netif_output(ppp_pcb *ppp, void *ctx, struct pbuf *p, u_short protocol) {
+  struct pppoe_softc *sc = (struct pppoe_softc *)ctx;
+  struct pbuf *pb;
+  u8_t *pl;
+  err_t err;
+#if MIB2_STATS
+  u16_t tot_len;
+#else /* MIB2_STATS */
+  LWIP_UNUSED_ARG(ppp);
+#endif /* MIB2_STATS */
+
+  /* @todo: try to use pbuf_header() here! */
+  pb = pbuf_alloc(PBUF_LINK, PPPOE_HEADERLEN + sizeof(protocol), PBUF_RAM);
+  if(!pb) {
+    LINK_STATS_INC(link.memerr);
+    LINK_STATS_INC(link.proterr);
+    MIB2_STATS_NETIF_INC(ppp->netif, ifoutdiscards);
+    return ERR_MEM;
+  }
+
+  pbuf_remove_header(pb, PPPOE_HEADERLEN);
+
+  pl = (u8_t*)pb->payload;
+  PUTSHORT(protocol, pl);
+
+  pbuf_chain(pb, p);
+#if MIB2_STATS
+  tot_len = pb->tot_len;
+#endif /* MIB2_STATS */
+
+  if( (err = pppoe_xmit(sc, pb)) != ERR_OK) {
+    LINK_STATS_INC(link.err);
+    MIB2_STATS_NETIF_INC(ppp->netif, ifoutdiscards);
+    return err;
+  }
+
+  MIB2_STATS_NETIF_ADD(ppp->netif, ifoutoctets, tot_len);
+  MIB2_STATS_NETIF_INC(ppp->netif, ifoutucastpkts);
+  LINK_STATS_INC(link.xmit);
+  return ERR_OK;
+}
+
+static err_t
+pppoe_destroy(ppp_pcb *ppp, void *ctx)
+{
+  struct pppoe_softc *sc = (struct pppoe_softc *)ctx;
+  struct pppoe_softc **copp, *freep;
+  LWIP_UNUSED_ARG(ppp);
+
+  sys_untimeout(pppoe_timeout, sc);
+
+  /* remove interface from list */
+  for (copp = &pppoe_softc_list; (freep = *copp); copp = &freep->next) {
+    if (freep == sc) {
+       *copp = freep->next;
+       break;
+    }
+  }
+
+#ifdef PPPOE_TODO
+  if (sc->sc_concentrator_name) {
+    mem_free(sc->sc_concentrator_name);
+  }
+  if (sc->sc_service_name) {
+    mem_free(sc->sc_service_name);
+  }
+#endif /* PPPOE_TODO */
+  LWIP_MEMPOOL_FREE(PPPOE_IF, sc);
+
+  return ERR_OK;
+}
+
+/*
+ * Find the interface handling the specified session.
+ * Note: O(number of sessions open), this is a client-side only, mean
+ * and lean implementation, so number of open sessions typically should
+ * be 1.
+ */
+static struct pppoe_softc* pppoe_find_softc_by_session(u_int session, struct netif *rcvif) {
+  struct pppoe_softc *sc;
+
+  for (sc = pppoe_softc_list; sc != NULL; sc = sc->next) {
+    if (sc->sc_state == PPPOE_STATE_SESSION
+        && sc->sc_session == session
+         && sc->sc_ethif == rcvif) {
+           return sc;
+      }
+  }
+  return NULL;
+}
+
+/* Check host unique token passed and return appropriate softc pointer,
+ * or NULL if token is bogus. */
+static struct pppoe_softc* pppoe_find_softc_by_hunique(u8_t *token, size_t len, struct netif *rcvif) {
+  struct pppoe_softc *sc, *t;
+
+  if (len != sizeof sc) {
+    return NULL;
+  }
+  MEMCPY(&t, token, len);
+
+  for (sc = pppoe_softc_list; sc != NULL; sc = sc->next) {
+    if (sc == t) {
+      break;
+    }
+  }
+
+  if (sc == NULL) {
+    PPPDEBUG(LOG_DEBUG, ("pppoe: alien host unique tag, no session found\n"));
+    return NULL;
+  }
+
+  /* should be safe to access *sc now */
+  if (sc->sc_state < PPPOE_STATE_PADI_SENT || sc->sc_state >= PPPOE_STATE_SESSION) {
+    PPPDEBUG(LOG_DEBUG, ("%c%c%"U16_F": host unique tag found, but it belongs to a connection in state %d\n",
+      sc->sc_ethif->name[0], sc->sc_ethif->name[1], sc->sc_ethif->num, sc->sc_state));
+    return NULL;
+  }
+  if (sc->sc_ethif != rcvif) {
+    PPPDEBUG(LOG_DEBUG, ("%c%c%"U16_F": wrong interface, not accepting host unique\n",
+      sc->sc_ethif->name[0], sc->sc_ethif->name[1], sc->sc_ethif->num));
+    return NULL;
+  }
+  return sc;
+}
+
+/* analyze and handle a single received packet while not in session state */
+void
+pppoe_disc_input(struct netif *netif, struct pbuf *pb)
+{
+  u16_t tag, len, off;
+  u16_t session, plen;
+  struct pppoe_softc *sc;
+#if PPP_DEBUG
+  const char *err_msg = NULL;
+#endif /* PPP_DEBUG */
+  u8_t *ac_cookie;
+  u16_t ac_cookie_len;
+#ifdef PPPOE_SERVER
+  u8_t *hunique;
+  size_t hunique_len;
+#endif
+  struct pppoehdr *ph;
+  struct pppoetag pt;
+  int err;
+  struct eth_hdr *ethhdr;
+
+  /* don't do anything if there is not a single PPPoE instance */
+  if (pppoe_softc_list == NULL) {
+    pbuf_free(pb);
+    return;
+  }
+
+  pb = pbuf_coalesce(pb, PBUF_RAW);
+
+  ethhdr = (struct eth_hdr *)pb->payload;
+
+  ac_cookie = NULL;
+  ac_cookie_len = 0;
+#ifdef PPPOE_SERVER
+  hunique = NULL;
+  hunique_len = 0;
+#endif
+  session = 0;
+  off = sizeof(struct eth_hdr) + sizeof(struct pppoehdr);
+  if (pb->len < off) {
+    PPPDEBUG(LOG_DEBUG, ("pppoe: packet too short: %d\n", pb->len));
+    goto done;
+  }
+
+  ph = (struct pppoehdr *) (ethhdr + 1);
+  if (ph->vertype != PPPOE_VERTYPE) {
+    PPPDEBUG(LOG_DEBUG, ("pppoe: unknown version/type packet: 0x%x\n", ph->vertype));
+    goto done;
+  }
+  session = lwip_ntohs(ph->session);
+  plen = lwip_ntohs(ph->plen);
+
+  if (plen > (pb->len - off)) {
+    PPPDEBUG(LOG_DEBUG, ("pppoe: packet content does not fit: data available = %d, packet size = %u\n",
+        pb->len - off, plen));
+    goto done;
+  }
+  if(pb->tot_len == pb->len) {
+    u16_t framelen = off + plen;
+    if (framelen < pb->len) {
+      /* ignore trailing garbage */
+      pb->tot_len = pb->len = framelen;
+    }
+  }
+  tag = 0;
+  len = 0;
+  sc = NULL;
+  while (off + sizeof(pt) <= pb->len) {
+    MEMCPY(&pt, (u8_t*)pb->payload + off, sizeof(pt));
+    tag = lwip_ntohs(pt.tag);
+    len = lwip_ntohs(pt.len);
+    if (off + sizeof(pt) + len > pb->len) {
+      PPPDEBUG(LOG_DEBUG, ("pppoe: tag 0x%x len 0x%x is too long\n", tag, len));
+      goto done;
+    }
+    switch (tag) {
+      case PPPOE_TAG_EOL:
+        goto breakbreak;
+      case PPPOE_TAG_SNAME:
+        break;  /* ignored */
+      case PPPOE_TAG_ACNAME:
+        break;  /* ignored */
+      case PPPOE_TAG_HUNIQUE:
+        if (sc != NULL) {
+          break;
+        }
+#ifdef PPPOE_SERVER
+        hunique = (u8_t*)pb->payload + off + sizeof(pt);
+        hunique_len = len;
+#endif
+        sc = pppoe_find_softc_by_hunique((u8_t*)pb->payload + off + sizeof(pt), len, netif);
+        break;
+      case PPPOE_TAG_ACCOOKIE:
+        if (ac_cookie == NULL) {
+          if (len > PPPOE_MAX_AC_COOKIE_LEN) {
+            PPPDEBUG(LOG_DEBUG, ("pppoe: AC cookie is too long: len = %d, max = %d\n", len, PPPOE_MAX_AC_COOKIE_LEN));
+            goto done;
+          }
+          ac_cookie = (u8_t*)pb->payload + off + sizeof(pt);
+          ac_cookie_len = len;
+        }
+        break;
+#if PPP_DEBUG
+      case PPPOE_TAG_SNAME_ERR:
+        err_msg = "SERVICE NAME ERROR";
+        break;
+      case PPPOE_TAG_ACSYS_ERR:
+        err_msg = "AC SYSTEM ERROR";
+        break;
+      case PPPOE_TAG_GENERIC_ERR:
+        err_msg = "GENERIC ERROR";
+        break;
+#endif /* PPP_DEBUG */
+      default:
+        break;
+    }
+#if PPP_DEBUG
+    if (err_msg != NULL) {
+      char error_tmp[PPPOE_ERRORSTRING_LEN];
+      u16_t error_len = LWIP_MIN(len, sizeof(error_tmp)-1);
+      strncpy(error_tmp, (char*)pb->payload + off + sizeof(pt), error_len);
+      error_tmp[error_len] = '\0';
+      if (sc) {
+        PPPDEBUG(LOG_DEBUG, ("pppoe: %c%c%"U16_F": %s: %s\n", sc->sc_ethif->name[0], sc->sc_ethif->name[1], sc->sc_ethif->num, err_msg, error_tmp));
+      } else {
+        PPPDEBUG(LOG_DEBUG, ("pppoe: %s: %s\n", err_msg, error_tmp));
+      }
+    }
+#endif /* PPP_DEBUG */
+    off += sizeof(pt) + len;
+  }
+
+breakbreak:;
+  switch (ph->code) {
+    case PPPOE_CODE_PADI:
+#ifdef PPPOE_SERVER
+      /*
+       * got service name, concentrator name, and/or host unique.
+       * ignore if we have no interfaces with IFF_PASSIVE|IFF_UP.
+       */
+      if (LIST_EMPTY(&pppoe_softc_list)) {
+        goto done;
+      }
+      LIST_FOREACH(sc, &pppoe_softc_list, sc_list) {
+        if (!(sc->sc_sppp.pp_if.if_flags & IFF_UP)) {
+          continue;
+        }
+        if (!(sc->sc_sppp.pp_if.if_flags & IFF_PASSIVE)) {
+          continue;
+        }
+        if (sc->sc_state == PPPOE_STATE_INITIAL) {
+          break;
+        }
+      }
+      if (sc == NULL) {
+        /* PPPDEBUG(LOG_DEBUG, ("pppoe: free passive interface is not found\n")); */
+        goto done;
+      }
+      if (hunique) {
+        if (sc->sc_hunique) {
+          mem_free(sc->sc_hunique);
+        }
+        sc->sc_hunique = mem_malloc(hunique_len);
+        if (sc->sc_hunique == NULL) {
+          goto done;
+        }
+        sc->sc_hunique_len = hunique_len;
+        MEMCPY(sc->sc_hunique, hunique, hunique_len);
+      }
+      MEMCPY(&sc->sc_dest, eh->ether_shost, sizeof sc->sc_dest);
+      sc->sc_state = PPPOE_STATE_PADO_SENT;
+      pppoe_send_pado(sc);
+      break;
+#endif /* PPPOE_SERVER */
+    case PPPOE_CODE_PADR:
+#ifdef PPPOE_SERVER
+      /*
+       * get sc from ac_cookie if IFF_PASSIVE
+       */
+      if (ac_cookie == NULL) {
+        /* be quiet if there is not a single pppoe instance */
+        PPPDEBUG(LOG_DEBUG, ("pppoe: received PADR but not includes ac_cookie\n"));
+        goto done;
+      }
+      sc = pppoe_find_softc_by_hunique(ac_cookie, ac_cookie_len, netif);
+      if (sc == NULL) {
+        /* be quiet if there is not a single pppoe instance */
+        if (!LIST_EMPTY(&pppoe_softc_list)) {
+          PPPDEBUG(LOG_DEBUG, ("pppoe: received PADR but could not find request for it\n"));
+        }
+        goto done;
+      }
+      if (sc->sc_state != PPPOE_STATE_PADO_SENT) {
+        PPPDEBUG(LOG_DEBUG, ("%c%c%"U16_F": received unexpected PADR\n", sc->sc_ethif->name[0], sc->sc_ethif->name[1], sc->sc_ethif->num));
+        goto done;
+      }
+      if (hunique) {
+        if (sc->sc_hunique) {
+          mem_free(sc->sc_hunique);
+        }
+        sc->sc_hunique = mem_malloc(hunique_len);
+        if (sc->sc_hunique == NULL) {
+          goto done;
+        }
+        sc->sc_hunique_len = hunique_len;
+        MEMCPY(sc->sc_hunique, hunique, hunique_len);
+      }
+      pppoe_send_pads(sc);
+      sc->sc_state = PPPOE_STATE_SESSION;
+      ppp_start(sc->pcb); /* notify upper layers */
+      break;
+#else
+      /* ignore, we are no access concentrator */
+      goto done;
+#endif /* PPPOE_SERVER */
+    case PPPOE_CODE_PADO:
+      if (sc == NULL) {
+        /* be quiet if there is not a single pppoe instance */
+        if (pppoe_softc_list != NULL) {
+          PPPDEBUG(LOG_DEBUG, ("pppoe: received PADO but could not find request for it\n"));
+        }
+        goto done;
+      }
+      if (sc->sc_state != PPPOE_STATE_PADI_SENT) {
+        PPPDEBUG(LOG_DEBUG, ("%c%c%"U16_F": received unexpected PADO\n", sc->sc_ethif->name[0], sc->sc_ethif->name[1], sc->sc_ethif->num));
+        goto done;
+      }
+      if (ac_cookie) {
+        sc->sc_ac_cookie_len = ac_cookie_len;
+        MEMCPY(sc->sc_ac_cookie, ac_cookie, ac_cookie_len);
+      }
+      MEMCPY(&sc->sc_dest, ethhdr->src.addr, sizeof(sc->sc_dest.addr));
+      sys_untimeout(pppoe_timeout, sc);
+      sc->sc_padr_retried = 0;
+      sc->sc_state = PPPOE_STATE_PADR_SENT;
+      if ((err = pppoe_send_padr(sc)) != 0) {
+        PPPDEBUG(LOG_DEBUG, ("pppoe: %c%c%"U16_F": failed to send PADR, error=%d\n", sc->sc_ethif->name[0], sc->sc_ethif->name[1], sc->sc_ethif->num, err));
+        LWIP_UNUSED_ARG(err); /* if PPPDEBUG is disabled */
+      }
+      sys_timeout(PPPOE_DISC_TIMEOUT * (1 + sc->sc_padr_retried), pppoe_timeout, sc);
+      break;
+    case PPPOE_CODE_PADS:
+      if (sc == NULL) {
+        goto done;
+      }
+      sc->sc_session = session;
+      sys_untimeout(pppoe_timeout, sc);
+      PPPDEBUG(LOG_DEBUG, ("pppoe: %c%c%"U16_F": session 0x%x connected\n", sc->sc_ethif->name[0], sc->sc_ethif->name[1], sc->sc_ethif->num, session));
+      sc->sc_state = PPPOE_STATE_SESSION;
+      ppp_start(sc->pcb); /* notify upper layers */
+      break;
+    case PPPOE_CODE_PADT:
+      /* Don't disconnect here, we let the LCP Echo/Reply find the fact
+       * that PPP session is down. Asking the PPP stack to end the session
+       * require strict checking about the PPP phase to prevent endless
+       * disconnection loops.
+       */
+#if 0 /* UNUSED */
+      if (sc == NULL) { /* PADT frames are rarely sent with a hunique tag, this is actually almost always true */
+        goto done;
+      }
+      pppoe_clear_softc(sc, "received PADT");
+#endif /* UNUSED */
+      break;
+    default:
+      if(sc) {
+        PPPDEBUG(LOG_DEBUG, ("%c%c%"U16_F": unknown code (0x%"X16_F") session = 0x%"X16_F"\n",
+            sc->sc_ethif->name[0], sc->sc_ethif->name[1], sc->sc_ethif->num,
+            (u16_t)ph->code, session));
+      } else {
+        PPPDEBUG(LOG_DEBUG, ("pppoe: unknown code (0x%"X16_F") session = 0x%"X16_F"\n", (u16_t)ph->code, session));
+      }
+      break;
+  }
+
+done:
+  pbuf_free(pb);
+  return;
+}
+
+void
+pppoe_data_input(struct netif *netif, struct pbuf *pb)
+{
+  u16_t session, plen;
+  struct pppoe_softc *sc;
+  struct pppoehdr *ph;
+#ifdef PPPOE_TERM_UNKNOWN_SESSIONS
+  u8_t shost[ETHER_ADDR_LEN];
+#endif
+
+#ifdef PPPOE_TERM_UNKNOWN_SESSIONS
+  MEMCPY(shost, ((struct eth_hdr *)pb->payload)->src.addr, sizeof(shost));
+#endif
+  if (pbuf_remove_header(pb, sizeof(struct eth_hdr)) != 0) {
+    /* bail out */
+    PPPDEBUG(LOG_ERR, ("pppoe_data_input: pbuf_remove_header failed\n"));
+    LINK_STATS_INC(link.lenerr);
+    goto drop;
+  } 
+
+  if (pb->len < sizeof(*ph)) {
+    PPPDEBUG(LOG_DEBUG, ("pppoe_data_input: could not get PPPoE header\n"));
+    goto drop;
+  }
+  ph = (struct pppoehdr *)pb->payload;
+
+  if (ph->vertype != PPPOE_VERTYPE) {
+    PPPDEBUG(LOG_DEBUG, ("pppoe (data): unknown version/type packet: 0x%x\n", ph->vertype));
+    goto drop;
+  }
+  if (ph->code != 0) {
+    goto drop;
+  }
+
+  session = lwip_ntohs(ph->session);
+  sc = pppoe_find_softc_by_session(session, netif);
+  if (sc == NULL) {
+#ifdef PPPOE_TERM_UNKNOWN_SESSIONS
+    PPPDEBUG(LOG_DEBUG, ("pppoe: input for unknown session 0x%x, sending PADT\n", session));
+    pppoe_send_padt(netif, session, shost);
+#endif
+    goto drop;
+  }
+
+  plen = lwip_ntohs(ph->plen);
+
+  if (pbuf_remove_header(pb, PPPOE_HEADERLEN) != 0) {
+    /* bail out */
+    PPPDEBUG(LOG_ERR, ("pppoe_data_input: pbuf_remove_header PPPOE_HEADERLEN failed\n"));
+    LINK_STATS_INC(link.lenerr);
+    goto drop;
+  } 
+
+  PPPDEBUG(LOG_DEBUG, ("pppoe_data_input: %c%c%"U16_F": pkthdr.len=%d, pppoe.len=%d\n",
+        sc->sc_ethif->name[0], sc->sc_ethif->name[1], sc->sc_ethif->num,
+        pb->len, plen));
+
+  if (pb->tot_len < plen) {
+    goto drop;
+  }
+
+  /* Dispatch the packet thereby consuming it. */
+  ppp_input(sc->pcb, pb);
+  return;
+
+drop:
+  pbuf_free(pb);
+}
+
+static err_t
+pppoe_output(struct pppoe_softc *sc, struct pbuf *pb)
+{
+  struct eth_hdr *ethhdr;
+  u16_t etype;
+  err_t res;
+
+  /* make room for Ethernet header - should not fail */
+  if (pbuf_add_header(pb, sizeof(struct eth_hdr)) != 0) {
+    /* bail out */
+    PPPDEBUG(LOG_ERR, ("pppoe: %c%c%"U16_F": pppoe_output: could not allocate room for Ethernet header\n", sc->sc_ethif->name[0], sc->sc_ethif->name[1], sc->sc_ethif->num));
+    LINK_STATS_INC(link.lenerr);
+    pbuf_free(pb);
+    return ERR_BUF;
+  }
+  ethhdr = (struct eth_hdr *)pb->payload;
+  etype = sc->sc_state == PPPOE_STATE_SESSION ? ETHTYPE_PPPOE : ETHTYPE_PPPOEDISC;
+  ethhdr->type = lwip_htons(etype);
+  MEMCPY(&ethhdr->dest.addr, &sc->sc_dest.addr, sizeof(ethhdr->dest.addr));
+  MEMCPY(&ethhdr->src.addr, &sc->sc_ethif->hwaddr, sizeof(ethhdr->src.addr));
+
+  PPPDEBUG(LOG_DEBUG, ("pppoe: %c%c%"U16_F" (%x) state=%d, session=0x%x output -> %02"X16_F":%02"X16_F":%02"X16_F":%02"X16_F":%02"X16_F":%02"X16_F", len=%d\n",
+      sc->sc_ethif->name[0], sc->sc_ethif->name[1], sc->sc_ethif->num, etype,
+      sc->sc_state, sc->sc_session,
+      sc->sc_dest.addr[0], sc->sc_dest.addr[1], sc->sc_dest.addr[2], sc->sc_dest.addr[3], sc->sc_dest.addr[4], sc->sc_dest.addr[5],
+      pb->tot_len));
+
+  res = sc->sc_ethif->linkoutput(sc->sc_ethif, pb);
+
+  pbuf_free(pb);
+
+  return res;
+}
+
+static err_t
+pppoe_send_padi(struct pppoe_softc *sc)
+{
+  struct pbuf *pb;
+  u8_t *p;
+  int len;
+#ifdef PPPOE_TODO
+  int l1 = 0, l2 = 0; /* XXX: gcc */
+#endif /* PPPOE_TODO */
+
+  /* calculate length of frame (excluding ethernet header + pppoe header) */
+  len = 2 + 2 + 2 + 2 + sizeof sc;  /* service name tag is required, host unique is send too */
+#ifdef PPPOE_TODO
+  if (sc->sc_service_name != NULL) {
+    l1 = (int)strlen(sc->sc_service_name);
+    len += l1;
+  }
+  if (sc->sc_concentrator_name != NULL) {
+    l2 = (int)strlen(sc->sc_concentrator_name);
+    len += 2 + 2 + l2;
+  }
+#endif /* PPPOE_TODO */
+  LWIP_ASSERT("sizeof(struct eth_hdr) + PPPOE_HEADERLEN + len <= 0xffff",
+    sizeof(struct eth_hdr) + PPPOE_HEADERLEN + len <= 0xffff);
+
+  /* allocate a buffer */
+  pb = pbuf_alloc(PBUF_LINK, (u16_t)(PPPOE_HEADERLEN + len), PBUF_RAM);
+  if (!pb) {
+    return ERR_MEM;
+  }
+  LWIP_ASSERT("pb->tot_len == pb->len", pb->tot_len == pb->len);
+
+  p = (u8_t*)pb->payload;
+  /* fill in pkt */
+  PPPOE_ADD_HEADER(p, PPPOE_CODE_PADI, 0, (u16_t)len);
+  PPPOE_ADD_16(p, PPPOE_TAG_SNAME);
+#ifdef PPPOE_TODO
+  if (sc->sc_service_name != NULL) {
+    PPPOE_ADD_16(p, l1);
+    MEMCPY(p, sc->sc_service_name, l1);
+    p += l1;
+  } else
+#endif /* PPPOE_TODO */
+  {
+    PPPOE_ADD_16(p, 0);
+  }
+#ifdef PPPOE_TODO
+  if (sc->sc_concentrator_name != NULL) {
+    PPPOE_ADD_16(p, PPPOE_TAG_ACNAME);
+    PPPOE_ADD_16(p, l2);
+    MEMCPY(p, sc->sc_concentrator_name, l2);
+    p += l2;
+  }
+#endif /* PPPOE_TODO */
+  PPPOE_ADD_16(p, PPPOE_TAG_HUNIQUE);
+  PPPOE_ADD_16(p, sizeof(sc));
+  MEMCPY(p, &sc, sizeof sc);
+
+  /* send pkt */
+  return pppoe_output(sc, pb);
+}
+
+static void
+pppoe_timeout(void *arg)
+{
+  u32_t retry_wait;
+  int err;
+  struct pppoe_softc *sc = (struct pppoe_softc*)arg;
+
+  PPPDEBUG(LOG_DEBUG, ("pppoe: %c%c%"U16_F": timeout\n", sc->sc_ethif->name[0], sc->sc_ethif->name[1], sc->sc_ethif->num));
+
+  switch (sc->sc_state) {
+    case PPPOE_STATE_PADI_SENT:
+      /*
+       * We have two basic ways of retrying:
+       *  - Quick retry mode: try a few times in short sequence
+       *  - Slow retry mode: we already had a connection successfully
+       *    established and will try infinitely (without user
+       *    intervention)
+       * We only enter slow retry mode if IFF_LINK1 (aka autodial)
+       * is not set.
+       */
+      if (sc->sc_padi_retried < 0xff) {
+        sc->sc_padi_retried++;
+      }
+      if (!sc->pcb->settings.persist && sc->sc_padi_retried >= PPPOE_DISC_MAXPADI) {
+#if 0
+        if ((sc->sc_sppp.pp_if.if_flags & IFF_LINK1) == 0) {
+          /* slow retry mode */
+          retry_wait = PPPOE_SLOW_RETRY;
+        } else
+#endif
+        {
+          pppoe_abort_connect(sc);
+          return;
+        }
+      }
+      /* initialize for quick retry mode */
+      retry_wait = LWIP_MIN(PPPOE_DISC_TIMEOUT * sc->sc_padi_retried, PPPOE_SLOW_RETRY);
+      if ((err = pppoe_send_padi(sc)) != 0) {
+        sc->sc_padi_retried--;
+        PPPDEBUG(LOG_DEBUG, ("pppoe: %c%c%"U16_F": failed to transmit PADI, error=%d\n", sc->sc_ethif->name[0], sc->sc_ethif->name[1], sc->sc_ethif->num, err));
+        LWIP_UNUSED_ARG(err); /* if PPPDEBUG is disabled */
+      }
+      sys_timeout(retry_wait, pppoe_timeout, sc);
+      break;
+
+    case PPPOE_STATE_PADR_SENT:
+      sc->sc_padr_retried++;
+      if (sc->sc_padr_retried >= PPPOE_DISC_MAXPADR) {
+        MEMCPY(&sc->sc_dest, ethbroadcast.addr, sizeof(sc->sc_dest));
+        sc->sc_state = PPPOE_STATE_PADI_SENT;
+        sc->sc_padr_retried = 0;
+        if ((err = pppoe_send_padi(sc)) != 0) {
+          PPPDEBUG(LOG_DEBUG, ("pppoe: %c%c%"U16_F": failed to send PADI, error=%d\n", sc->sc_ethif->name[0], sc->sc_ethif->name[1], sc->sc_ethif->num, err));
+          LWIP_UNUSED_ARG(err); /* if PPPDEBUG is disabled */
+        }
+        sys_timeout(PPPOE_DISC_TIMEOUT * (1 + sc->sc_padi_retried), pppoe_timeout, sc);
+        return;
+      }
+      if ((err = pppoe_send_padr(sc)) != 0) {
+        sc->sc_padr_retried--;
+        PPPDEBUG(LOG_DEBUG, ("pppoe: %c%c%"U16_F": failed to send PADR, error=%d\n", sc->sc_ethif->name[0], sc->sc_ethif->name[1], sc->sc_ethif->num, err));
+        LWIP_UNUSED_ARG(err); /* if PPPDEBUG is disabled */
+      }
+      sys_timeout(PPPOE_DISC_TIMEOUT * (1 + sc->sc_padr_retried), pppoe_timeout, sc);
+      break;
+    default:
+      return;  /* all done, work in peace */
+  }
+}
+
+/* Start a connection (i.e. initiate discovery phase) */
+static void
+pppoe_connect(ppp_pcb *ppp, void *ctx)
+{
+  err_t err;
+  struct pppoe_softc *sc = (struct pppoe_softc *)ctx;
+  lcp_options *lcp_wo;
+  lcp_options *lcp_ao;
+#if PPP_IPV4_SUPPORT && VJ_SUPPORT
+  ipcp_options *ipcp_wo;
+  ipcp_options *ipcp_ao;
+#endif /* PPP_IPV4_SUPPORT && VJ_SUPPORT */
+
+  sc->sc_session = 0;
+  sc->sc_ac_cookie_len = 0;
+  sc->sc_padi_retried = 0;
+  sc->sc_padr_retried = 0;
+  /* changed to real address later */
+  MEMCPY(&sc->sc_dest, ethbroadcast.addr, sizeof(sc->sc_dest));
+#ifdef PPPOE_SERVER
+  /* wait PADI if IFF_PASSIVE */
+  if ((sc->sc_sppp.pp_if.if_flags & IFF_PASSIVE)) {
+    return 0;
+  }
+#endif
+
+  lcp_wo = &ppp->lcp_wantoptions;
+  lcp_wo->mru = sc->sc_ethif->mtu-PPPOE_HEADERLEN-2; /* two byte PPP protocol discriminator, then IP data */
+  lcp_wo->neg_asyncmap = 0;
+  lcp_wo->neg_pcompression = 0;
+  lcp_wo->neg_accompression = 0;
+  lcp_wo->passive = 0;
+  lcp_wo->silent = 0;
+
+  lcp_ao = &ppp->lcp_allowoptions;
+  lcp_ao->mru = sc->sc_ethif->mtu-PPPOE_HEADERLEN-2; /* two byte PPP protocol discriminator, then IP data */
+  lcp_ao->neg_asyncmap = 0;
+  lcp_ao->neg_pcompression = 0;
+  lcp_ao->neg_accompression = 0;
+
+#if PPP_IPV4_SUPPORT && VJ_SUPPORT
+  ipcp_wo = &ppp->ipcp_wantoptions;
+  ipcp_wo->neg_vj = 0;
+  ipcp_wo->old_vj = 0;
+
+  ipcp_ao = &ppp->ipcp_allowoptions;
+  ipcp_ao->neg_vj = 0;
+  ipcp_ao->old_vj = 0;
+#endif /* PPP_IPV4_SUPPORT && VJ_SUPPORT */
+
+  /* save state, in case we fail to send PADI */
+  sc->sc_state = PPPOE_STATE_PADI_SENT;
+  if ((err = pppoe_send_padi(sc)) != 0) {
+    PPPDEBUG(LOG_DEBUG, ("pppoe: %c%c%"U16_F": failed to send PADI, error=%d\n", sc->sc_ethif->name[0], sc->sc_ethif->name[1], sc->sc_ethif->num, err));
+  }
+  sys_timeout(PPPOE_DISC_TIMEOUT, pppoe_timeout, sc);
+}
+
+/* disconnect */
+static void
+pppoe_disconnect(ppp_pcb *ppp, void *ctx)
+{
+  struct pppoe_softc *sc = (struct pppoe_softc *)ctx;
+
+  PPPDEBUG(LOG_DEBUG, ("pppoe: %c%c%"U16_F": disconnecting\n", sc->sc_ethif->name[0], sc->sc_ethif->name[1], sc->sc_ethif->num));
+  if (sc->sc_state == PPPOE_STATE_SESSION) {
+    pppoe_send_padt(sc->sc_ethif, sc->sc_session, (const u8_t *)&sc->sc_dest);
+  }
+
+  /* stop any timer, disconnect can be called while initiating is in progress */
+  sys_untimeout(pppoe_timeout, sc);
+  sc->sc_state = PPPOE_STATE_INITIAL;
+#ifdef PPPOE_SERVER
+  if (sc->sc_hunique) {
+    mem_free(sc->sc_hunique);
+    sc->sc_hunique = NULL; /* probably not necessary, if state is initial we shouldn't have to access hunique anyway  */
+  }
+  sc->sc_hunique_len = 0; /* probably not necessary, if state is initial we shouldn't have to access hunique anyway  */
+#endif
+  ppp_link_end(ppp); /* notify upper layers */
+  return;
+}
+
+/* Connection attempt aborted */
+static void
+pppoe_abort_connect(struct pppoe_softc *sc)
+{
+  PPPDEBUG(LOG_DEBUG, ("%c%c%"U16_F": could not establish connection\n", sc->sc_ethif->name[0], sc->sc_ethif->name[1], sc->sc_ethif->num));
+  sc->sc_state = PPPOE_STATE_INITIAL;
+  ppp_link_failed(sc->pcb); /* notify upper layers */
+}
+
+/* Send a PADR packet */
+static err_t
+pppoe_send_padr(struct pppoe_softc *sc)
+{
+  struct pbuf *pb;
+  u8_t *p;
+  size_t len;
+#ifdef PPPOE_TODO
+  size_t l1 = 0; /* XXX: gcc */
+#endif /* PPPOE_TODO */
+
+  len = 2 + 2 + 2 + 2 + sizeof(sc);    /* service name, host unique */
+#ifdef PPPOE_TODO
+  if (sc->sc_service_name != NULL) {    /* service name tag maybe empty */
+    l1 = strlen(sc->sc_service_name);
+    len += l1;
+  }
+#endif /* PPPOE_TODO */
+  if (sc->sc_ac_cookie_len > 0) {
+    len += 2 + 2 + sc->sc_ac_cookie_len;  /* AC cookie */
+  }
+  LWIP_ASSERT("sizeof(struct eth_hdr) + PPPOE_HEADERLEN + len <= 0xffff",
+    sizeof(struct eth_hdr) + PPPOE_HEADERLEN + len <= 0xffff);
+  pb = pbuf_alloc(PBUF_LINK, (u16_t)(PPPOE_HEADERLEN + len), PBUF_RAM);
+  if (!pb) {
+    return ERR_MEM;
+  }
+  LWIP_ASSERT("pb->tot_len == pb->len", pb->tot_len == pb->len);
+  p = (u8_t*)pb->payload;
+  PPPOE_ADD_HEADER(p, PPPOE_CODE_PADR, 0, len);
+  PPPOE_ADD_16(p, PPPOE_TAG_SNAME);
+#ifdef PPPOE_TODO
+  if (sc->sc_service_name != NULL) {
+    PPPOE_ADD_16(p, l1);
+    MEMCPY(p, sc->sc_service_name, l1);
+    p += l1;
+  } else
+#endif /* PPPOE_TODO */
+  {
+    PPPOE_ADD_16(p, 0);
+  }
+  if (sc->sc_ac_cookie_len > 0) {
+    PPPOE_ADD_16(p, PPPOE_TAG_ACCOOKIE);
+    PPPOE_ADD_16(p, sc->sc_ac_cookie_len);
+    MEMCPY(p, sc->sc_ac_cookie, sc->sc_ac_cookie_len);
+    p += sc->sc_ac_cookie_len;
+  }
+  PPPOE_ADD_16(p, PPPOE_TAG_HUNIQUE);
+  PPPOE_ADD_16(p, sizeof(sc));
+  MEMCPY(p, &sc, sizeof sc);
+
+  return pppoe_output(sc, pb);
+}
+
+/* send a PADT packet */
+static err_t
+pppoe_send_padt(struct netif *outgoing_if, u_int session, const u8_t *dest)
+{
+  struct pbuf *pb;
+  struct eth_hdr *ethhdr;
+  err_t res;
+  u8_t *p;
+
+  pb = pbuf_alloc(PBUF_LINK, (u16_t)(PPPOE_HEADERLEN), PBUF_RAM);
+  if (!pb) {
+    return ERR_MEM;
+  }
+  LWIP_ASSERT("pb->tot_len == pb->len", pb->tot_len == pb->len);
+
+  if (pbuf_add_header(pb, sizeof(struct eth_hdr))) {
+    PPPDEBUG(LOG_ERR, ("pppoe: pppoe_send_padt: could not allocate room for PPPoE header\n"));
+    LINK_STATS_INC(link.lenerr);
+    pbuf_free(pb);
+    return ERR_BUF;
+  }
+  ethhdr = (struct eth_hdr *)pb->payload;
+  ethhdr->type = PP_HTONS(ETHTYPE_PPPOEDISC);
+  MEMCPY(&ethhdr->dest.addr, dest, sizeof(ethhdr->dest.addr));
+  MEMCPY(&ethhdr->src.addr, &outgoing_if->hwaddr, sizeof(ethhdr->src.addr));
+
+  p = (u8_t*)(ethhdr + 1);
+  PPPOE_ADD_HEADER(p, PPPOE_CODE_PADT, session, 0);
+
+  res = outgoing_if->linkoutput(outgoing_if, pb);
+
+  pbuf_free(pb);
+
+  return res;
+}
+
+#ifdef PPPOE_SERVER
+static err_t
+pppoe_send_pado(struct pppoe_softc *sc)
+{
+  struct pbuf *pb;
+  u8_t *p;
+  size_t len;
+
+  /* calc length */
+  len = 0;
+  /* include ac_cookie */
+  len += 2 + 2 + sizeof(sc);
+  /* include hunique */
+  len += 2 + 2 + sc->sc_hunique_len;
+  pb = pbuf_alloc(PBUF_LINK, (u16_t)(PPPOE_HEADERLEN + len), PBUF_RAM);
+  if (!pb) {
+    return ERR_MEM;
+  }
+  LWIP_ASSERT("pb->tot_len == pb->len", pb->tot_len == pb->len);
+  p = (u8_t*)pb->payload;
+  PPPOE_ADD_HEADER(p, PPPOE_CODE_PADO, 0, len);
+  PPPOE_ADD_16(p, PPPOE_TAG_ACCOOKIE);
+  PPPOE_ADD_16(p, sizeof(sc));
+  MEMCPY(p, &sc, sizeof(sc));
+  p += sizeof(sc);
+  PPPOE_ADD_16(p, PPPOE_TAG_HUNIQUE);
+  PPPOE_ADD_16(p, sc->sc_hunique_len);
+  MEMCPY(p, sc->sc_hunique, sc->sc_hunique_len);
+  return pppoe_output(sc, pb);
+}
+
+static err_t
+pppoe_send_pads(struct pppoe_softc *sc)
+{
+  struct pbuf *pb;
+  u8_t *p;
+  size_t len, l1 = 0;  /* XXX: gcc */
+
+  sc->sc_session = mono_time.tv_sec % 0xff + 1;
+  /* calc length */
+  len = 0;
+  /* include hunique */
+  len += 2 + 2 + 2 + 2 + sc->sc_hunique_len;  /* service name, host unique*/
+  if (sc->sc_service_name != NULL) {    /* service name tag maybe empty */
+    l1 = strlen(sc->sc_service_name);
+    len += l1;
+  }
+  pb = pbuf_alloc(PBUF_LINK, (u16_t)(PPPOE_HEADERLEN + len), PBUF_RAM);
+  if (!pb) {
+    return ERR_MEM;
+  }
+  LWIP_ASSERT("pb->tot_len == pb->len", pb->tot_len == pb->len);
+  p = (u8_t*)pb->payload;
+  PPPOE_ADD_HEADER(p, PPPOE_CODE_PADS, sc->sc_session, len);
+  PPPOE_ADD_16(p, PPPOE_TAG_SNAME);
+  if (sc->sc_service_name != NULL) {
+    PPPOE_ADD_16(p, l1);
+    MEMCPY(p, sc->sc_service_name, l1);
+    p += l1;
+  } else {
+    PPPOE_ADD_16(p, 0);
+  }
+  PPPOE_ADD_16(p, PPPOE_TAG_HUNIQUE);
+  PPPOE_ADD_16(p, sc->sc_hunique_len);
+  MEMCPY(p, sc->sc_hunique, sc->sc_hunique_len);
+  return pppoe_output(sc, pb);
+}
+#endif
+
+static err_t
+pppoe_xmit(struct pppoe_softc *sc, struct pbuf *pb)
+{
+  u8_t *p;
+  size_t len;
+
+  len = pb->tot_len;
+
+  /* make room for PPPoE header - should not fail */
+  if (pbuf_add_header(pb, PPPOE_HEADERLEN) != 0) {
+    /* bail out */
+    PPPDEBUG(LOG_ERR, ("pppoe: %c%c%"U16_F": pppoe_xmit: could not allocate room for PPPoE header\n", sc->sc_ethif->name[0], sc->sc_ethif->name[1], sc->sc_ethif->num));
+    LINK_STATS_INC(link.lenerr);
+    pbuf_free(pb);
+    return ERR_BUF;
+  }
+
+  p = (u8_t*)pb->payload;
+  PPPOE_ADD_HEADER(p, 0, sc->sc_session, len);
+
+  return pppoe_output(sc, pb);
+}
+
+#if 0 /*def PFIL_HOOKS*/
+static int
+pppoe_ifattach_hook(void *arg, struct pbuf **mp, struct netif *ifp, int dir)
+{
+  struct pppoe_softc *sc;
+  int s;
+
+  if (mp != (struct pbuf **)PFIL_IFNET_DETACH) {
+    return 0;
+  }
+
+  LIST_FOREACH(sc, &pppoe_softc_list, sc_list) {
+    if (sc->sc_ethif != ifp) {
+      continue;
+    }
+    if (sc->sc_sppp.pp_if.if_flags & IFF_UP) {
+      sc->sc_sppp.pp_if.if_flags &= ~(IFF_UP|IFF_RUNNING);
+      PPPDEBUG(LOG_DEBUG, ("%c%c%"U16_F": ethernet interface detached, going down\n",
+          sc->sc_ethif->name[0], sc->sc_ethif->name[1], sc->sc_ethif->num));
+    }
+    sc->sc_ethif = NULL;
+    pppoe_clear_softc(sc, "ethernet interface detached");
+  }
+
+  return 0;
+}
+#endif
+
+#if 0 /* UNUSED */
+static void
+pppoe_clear_softc(struct pppoe_softc *sc, const char *message)
+{
+  LWIP_UNUSED_ARG(message);
+
+  /* stop timer */
+  sys_untimeout(pppoe_timeout, sc);
+  PPPDEBUG(LOG_DEBUG, ("pppoe: %c%c%"U16_F": session 0x%x terminated, %s\n", sc->sc_ethif->name[0], sc->sc_ethif->name[1], sc->sc_ethif->num, sc->sc_session, message));
+  sc->sc_state = PPPOE_STATE_INITIAL;
+  ppp_link_end(sc->pcb);  /* notify upper layers - /!\ dangerous /!\ - see pppoe_disc_input() */
+}
+#endif /* UNUSED */
+#endif /* PPP_SUPPORT && PPPOE_SUPPORT */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/netif/ppp/pppol2tp.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/netif/ppp/pppol2tp.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/netif/ppp/pppol2tp.c	(revision 457)
@@ -0,0 +1,1159 @@
+/**
+ * @file
+ * Network Point to Point Protocol over Layer 2 Tunneling Protocol program file.
+ *
+ */
+
+/*
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ */
+
+/*
+ * L2TP Support status:
+ *
+ * Supported:
+ * - L2TPv2 (PPP over L2TP, a.k.a. UDP tunnels)
+ * - LAC
+ *
+ * Not supported:
+ * - LNS (require PPP server support)
+ * - L2TPv3 ethernet pseudowires
+ * - L2TPv3 VLAN pseudowire
+ * - L2TPv3 PPP pseudowires
+ * - L2TPv3 IP encapsulation
+ * - L2TPv3 IP pseudowire
+ * - L2TP tunnel switching - http://tools.ietf.org/html/draft-ietf-l2tpext-tunnel-switching-08
+ * - Multiple tunnels per UDP socket, as well as multiple sessions per tunnel
+ * - Hidden AVPs
+ */
+
+#include "netif/ppp/ppp_opts.h"
+#if PPP_SUPPORT && PPPOL2TP_SUPPORT /* don't build if not configured for use in lwipopts.h */
+
+#include "lwip/err.h"
+#include "lwip/memp.h"
+#include "lwip/netif.h"
+#include "lwip/udp.h"
+#include "lwip/snmp.h"
+
+#include "netif/ppp/ppp_impl.h"
+#include "netif/ppp/lcp.h"
+#include "netif/ppp/ipcp.h"
+#include "netif/ppp/pppol2tp.h"
+#include "netif/ppp/pppcrypt.h"
+#include "netif/ppp/magic.h"
+
+/* Memory pool */
+LWIP_MEMPOOL_DECLARE(PPPOL2TP_PCB, MEMP_NUM_PPPOL2TP_INTERFACES, sizeof(pppol2tp_pcb), "PPPOL2TP_PCB")
+
+/* callbacks called from PPP core */
+static err_t pppol2tp_write(ppp_pcb *ppp, void *ctx, struct pbuf *p);
+static err_t pppol2tp_netif_output(ppp_pcb *ppp, void *ctx, struct pbuf *p, u_short protocol);
+static err_t pppol2tp_destroy(ppp_pcb *ppp, void *ctx);    /* Destroy a L2TP control block */
+static void pppol2tp_connect(ppp_pcb *ppp, void *ctx);    /* Be a LAC, connect to a LNS. */
+static void pppol2tp_disconnect(ppp_pcb *ppp, void *ctx);  /* Disconnect */
+
+ /* Prototypes for procedures local to this file. */
+static void pppol2tp_input(void *arg, struct udp_pcb *pcb, struct pbuf *p, const ip_addr_t *addr, u16_t port);
+static void pppol2tp_dispatch_control_packet(pppol2tp_pcb *l2tp, u16_t port, struct pbuf *p, u16_t ns, u16_t nr);
+static void pppol2tp_timeout(void *arg);
+static void pppol2tp_abort_connect(pppol2tp_pcb *l2tp);
+static err_t pppol2tp_send_sccrq(pppol2tp_pcb *l2tp);
+static err_t pppol2tp_send_scccn(pppol2tp_pcb *l2tp, u16_t ns);
+static err_t pppol2tp_send_icrq(pppol2tp_pcb *l2tp, u16_t ns);
+static err_t pppol2tp_send_iccn(pppol2tp_pcb *l2tp, u16_t ns);
+static err_t pppol2tp_send_zlb(pppol2tp_pcb *l2tp, u16_t ns, u16_t nr);
+static err_t pppol2tp_send_stopccn(pppol2tp_pcb *l2tp, u16_t ns);
+static err_t pppol2tp_xmit(pppol2tp_pcb *l2tp, struct pbuf *pb);
+static err_t pppol2tp_udp_send(pppol2tp_pcb *l2tp, struct pbuf *pb);
+
+/* Callbacks structure for PPP core */
+static const struct link_callbacks pppol2tp_callbacks = {
+  pppol2tp_connect,
+#if PPP_SERVER
+  NULL,
+#endif /* PPP_SERVER */
+  pppol2tp_disconnect,
+  pppol2tp_destroy,
+  pppol2tp_write,
+  pppol2tp_netif_output,
+  NULL,
+  NULL
+};
+
+
+/* Create a new L2TP session. */
+ppp_pcb *pppol2tp_create(struct netif *pppif,
+       struct netif *netif, const ip_addr_t *ipaddr, u16_t port,
+       const u8_t *secret, u8_t secret_len,
+       ppp_link_status_cb_fn link_status_cb, void *ctx_cb) {
+  ppp_pcb *ppp;
+  pppol2tp_pcb *l2tp;
+  struct udp_pcb *udp;
+#if !PPPOL2TP_AUTH_SUPPORT
+  LWIP_UNUSED_ARG(secret);
+  LWIP_UNUSED_ARG(secret_len);
+#endif /* !PPPOL2TP_AUTH_SUPPORT */
+
+  if (ipaddr == NULL) {
+    goto ipaddr_check_failed;
+  }
+
+  l2tp = (pppol2tp_pcb *)LWIP_MEMPOOL_ALLOC(PPPOL2TP_PCB);
+  if (l2tp == NULL) {
+    goto memp_malloc_l2tp_failed;
+  }
+
+  udp = udp_new_ip_type(IP_GET_TYPE(ipaddr));
+  if (udp == NULL) {
+    goto udp_new_failed;
+  }
+  udp_recv(udp, pppol2tp_input, l2tp);
+
+  ppp = ppp_new(pppif, &pppol2tp_callbacks, l2tp, link_status_cb, ctx_cb);
+  if (ppp == NULL) {
+    goto ppp_new_failed;
+  }
+
+  memset(l2tp, 0, sizeof(pppol2tp_pcb));
+  l2tp->phase = PPPOL2TP_STATE_INITIAL;
+  l2tp->ppp = ppp;
+  l2tp->udp = udp;
+  l2tp->netif = netif;
+  ip_addr_copy(l2tp->remote_ip, *ipaddr);
+  l2tp->remote_port = port;
+#if PPPOL2TP_AUTH_SUPPORT
+  l2tp->secret = secret;
+  l2tp->secret_len = secret_len;
+#endif /* PPPOL2TP_AUTH_SUPPORT */
+
+  return ppp;
+
+ppp_new_failed:
+  udp_remove(udp);
+udp_new_failed:
+  LWIP_MEMPOOL_FREE(PPPOL2TP_PCB, l2tp);
+memp_malloc_l2tp_failed:
+ipaddr_check_failed:
+  return NULL;
+}
+
+/* Called by PPP core */
+static err_t pppol2tp_write(ppp_pcb *ppp, void *ctx, struct pbuf *p) {
+  pppol2tp_pcb *l2tp = (pppol2tp_pcb *)ctx;
+  struct pbuf *ph; /* UDP + L2TP header */
+  err_t ret;
+#if MIB2_STATS
+  u16_t tot_len;
+#else /* MIB2_STATS */
+  LWIP_UNUSED_ARG(ppp);
+#endif /* MIB2_STATS */
+
+  ph = pbuf_alloc(PBUF_TRANSPORT, (u16_t)(PPPOL2TP_OUTPUT_DATA_HEADER_LEN), PBUF_RAM);
+  if(!ph) {
+    LINK_STATS_INC(link.memerr);
+    LINK_STATS_INC(link.proterr);
+    MIB2_STATS_NETIF_INC(ppp->netif, ifoutdiscards);
+    pbuf_free(p);
+    return ERR_MEM;
+  }
+
+  pbuf_remove_header(ph, PPPOL2TP_OUTPUT_DATA_HEADER_LEN); /* hide L2TP header */
+  pbuf_cat(ph, p);
+#if MIB2_STATS
+  tot_len = ph->tot_len;
+#endif /* MIB2_STATS */
+
+  ret = pppol2tp_xmit(l2tp, ph);
+  if (ret != ERR_OK) {
+    LINK_STATS_INC(link.err);
+    MIB2_STATS_NETIF_INC(ppp->netif, ifoutdiscards);
+    return ret;
+  }
+
+  MIB2_STATS_NETIF_ADD(ppp->netif, ifoutoctets, (u16_t)tot_len);
+  MIB2_STATS_NETIF_INC(ppp->netif, ifoutucastpkts);
+  LINK_STATS_INC(link.xmit);
+  return ERR_OK;
+}
+
+/* Called by PPP core */
+static err_t pppol2tp_netif_output(ppp_pcb *ppp, void *ctx, struct pbuf *p, u_short protocol) {
+  pppol2tp_pcb *l2tp = (pppol2tp_pcb *)ctx;
+  struct pbuf *pb;
+  u8_t *pl;
+  err_t err;
+#if MIB2_STATS
+  u16_t tot_len;
+#else /* MIB2_STATS */
+  LWIP_UNUSED_ARG(ppp);
+#endif /* MIB2_STATS */
+
+  /* @todo: try to use pbuf_header() here! */
+  pb = pbuf_alloc(PBUF_TRANSPORT, PPPOL2TP_OUTPUT_DATA_HEADER_LEN + sizeof(protocol), PBUF_RAM);
+  if(!pb) {
+    LINK_STATS_INC(link.memerr);
+    LINK_STATS_INC(link.proterr);
+    MIB2_STATS_NETIF_INC(ppp->netif, ifoutdiscards);
+    return ERR_MEM;
+  }
+
+  pbuf_remove_header(pb, PPPOL2TP_OUTPUT_DATA_HEADER_LEN);
+
+  pl = (u8_t*)pb->payload;
+  PUTSHORT(protocol, pl);
+
+  pbuf_chain(pb, p);
+#if MIB2_STATS
+  tot_len = pb->tot_len;
+#endif /* MIB2_STATS */
+
+  if( (err = pppol2tp_xmit(l2tp, pb)) != ERR_OK) {
+    LINK_STATS_INC(link.err);
+    MIB2_STATS_NETIF_INC(ppp->netif, ifoutdiscards);
+    return err;
+  }
+
+  MIB2_STATS_NETIF_ADD(ppp->netif, ifoutoctets, tot_len);
+  MIB2_STATS_NETIF_INC(ppp->netif, ifoutucastpkts);
+  LINK_STATS_INC(link.xmit);
+  return ERR_OK;
+}
+
+/* Destroy a L2TP control block */
+static err_t pppol2tp_destroy(ppp_pcb *ppp, void *ctx) {
+  pppol2tp_pcb *l2tp = (pppol2tp_pcb *)ctx;
+  LWIP_UNUSED_ARG(ppp);
+
+  sys_untimeout(pppol2tp_timeout, l2tp);
+  udp_remove(l2tp->udp);
+  LWIP_MEMPOOL_FREE(PPPOL2TP_PCB, l2tp);
+  return ERR_OK;
+}
+
+/* Be a LAC, connect to a LNS. */
+static void pppol2tp_connect(ppp_pcb *ppp, void *ctx) {
+  err_t err;
+  pppol2tp_pcb *l2tp = (pppol2tp_pcb *)ctx;
+  lcp_options *lcp_wo;
+  lcp_options *lcp_ao;
+#if PPP_IPV4_SUPPORT && VJ_SUPPORT
+  ipcp_options *ipcp_wo;
+  ipcp_options *ipcp_ao;
+#endif /* PPP_IPV4_SUPPORT && VJ_SUPPORT */
+
+  l2tp->tunnel_port = l2tp->remote_port;
+  l2tp->our_ns = 0;
+  l2tp->peer_nr = 0;
+  l2tp->peer_ns = 0;
+  l2tp->source_tunnel_id = 0;
+  l2tp->remote_tunnel_id = 0;
+  l2tp->source_session_id = 0;
+  l2tp->remote_session_id = 0;
+  /* l2tp->*_retried are cleared when used */
+
+  lcp_wo = &ppp->lcp_wantoptions;
+  lcp_wo->mru = PPPOL2TP_DEFMRU;
+  lcp_wo->neg_asyncmap = 0;
+  lcp_wo->neg_pcompression = 0;
+  lcp_wo->neg_accompression = 0;
+  lcp_wo->passive = 0;
+  lcp_wo->silent = 0;
+
+  lcp_ao = &ppp->lcp_allowoptions;
+  lcp_ao->mru = PPPOL2TP_DEFMRU;
+  lcp_ao->neg_asyncmap = 0;
+  lcp_ao->neg_pcompression = 0;
+  lcp_ao->neg_accompression = 0;
+
+#if PPP_IPV4_SUPPORT && VJ_SUPPORT
+  ipcp_wo = &ppp->ipcp_wantoptions;
+  ipcp_wo->neg_vj = 0;
+  ipcp_wo->old_vj = 0;
+
+  ipcp_ao = &ppp->ipcp_allowoptions;
+  ipcp_ao->neg_vj = 0;
+  ipcp_ao->old_vj = 0;
+#endif /* PPP_IPV4_SUPPORT && VJ_SUPPORT */
+
+  /* Listen to a random source port, we need to do that instead of using udp_connect()
+   * because the L2TP LNS might answer with its own random source port (!= 1701)
+   */
+#if LWIP_IPV6
+  if (IP_IS_V6_VAL(l2tp->udp->local_ip)) {
+    udp_bind(l2tp->udp, IP6_ADDR_ANY, 0);
+  } else
+#endif /* LWIP_IPV6 */
+  udp_bind(l2tp->udp, IP_ADDR_ANY, 0);
+
+#if PPPOL2TP_AUTH_SUPPORT
+  /* Generate random vector */
+  if (l2tp->secret != NULL) {
+    magic_random_bytes(l2tp->secret_rv, sizeof(l2tp->secret_rv));
+  }
+#endif /* PPPOL2TP_AUTH_SUPPORT */
+
+  do {
+    l2tp->remote_tunnel_id = magic();
+  } while(l2tp->remote_tunnel_id == 0);
+  /* save state, in case we fail to send SCCRQ */
+  l2tp->sccrq_retried = 0;
+  l2tp->phase = PPPOL2TP_STATE_SCCRQ_SENT;
+  if ((err = pppol2tp_send_sccrq(l2tp)) != 0) {
+    PPPDEBUG(LOG_DEBUG, ("pppol2tp: failed to send SCCRQ, error=%d\n", err));
+  }
+  sys_timeout(PPPOL2TP_CONTROL_TIMEOUT, pppol2tp_timeout, l2tp);
+}
+
+/* Disconnect */
+static void pppol2tp_disconnect(ppp_pcb *ppp, void *ctx) {
+  pppol2tp_pcb *l2tp = (pppol2tp_pcb *)ctx;
+
+  l2tp->our_ns++;
+  pppol2tp_send_stopccn(l2tp, l2tp->our_ns);
+
+  /* stop any timer, disconnect can be called while initiating is in progress */
+  sys_untimeout(pppol2tp_timeout, l2tp);
+  l2tp->phase = PPPOL2TP_STATE_INITIAL;
+  ppp_link_end(ppp); /* notify upper layers */
+}
+
+/* UDP Callback for incoming IPv4 L2TP frames */
+static void pppol2tp_input(void *arg, struct udp_pcb *pcb, struct pbuf *p, const ip_addr_t *addr, u16_t port) {
+  pppol2tp_pcb *l2tp = (pppol2tp_pcb*)arg;
+  u16_t hflags, hlen, len=0, tunnel_id=0, session_id=0, ns=0, nr=0, offset=0;
+  u8_t *inp;
+  LWIP_UNUSED_ARG(pcb);
+
+  /* we can't unbound a UDP pcb, thus we can still receive UDP frames after the link is closed */
+  if (l2tp->phase < PPPOL2TP_STATE_SCCRQ_SENT) {
+    goto free_and_return;
+  }
+
+  if (!ip_addr_cmp(&l2tp->remote_ip, addr)) {
+    goto free_and_return;
+  }
+
+  /* discard packet if port mismatch, but only if we received a SCCRP */
+  if (l2tp->phase > PPPOL2TP_STATE_SCCRQ_SENT && l2tp->tunnel_port != port) {
+    goto free_and_return;
+  }
+
+  /* printf("-----------\nL2TP INPUT, %d\n", p->len); */
+
+  /* L2TP header */
+  if (p->len < sizeof(hflags) + sizeof(tunnel_id) + sizeof(session_id) ) {
+    goto packet_too_short;
+  }
+
+  inp = (u8_t*)p->payload;
+  GETSHORT(hflags, inp);
+
+  if (hflags & PPPOL2TP_HEADERFLAG_CONTROL) {
+    /* check mandatory flags for a control packet */
+    if ( (hflags & PPPOL2TP_HEADERFLAG_CONTROL_MANDATORY) != PPPOL2TP_HEADERFLAG_CONTROL_MANDATORY ) {
+      PPPDEBUG(LOG_DEBUG, ("pppol2tp: mandatory header flags for control packet not set\n"));
+      goto free_and_return;
+    }
+    /* check forbidden flags for a control packet */
+    if (hflags & PPPOL2TP_HEADERFLAG_CONTROL_FORBIDDEN) {
+      PPPDEBUG(LOG_DEBUG, ("pppol2tp: forbidden header flags for control packet found\n"));
+      goto free_and_return;
+    }
+  } else {
+    /* check mandatory flags for a data packet */
+    if ( (hflags & PPPOL2TP_HEADERFLAG_DATA_MANDATORY) != PPPOL2TP_HEADERFLAG_DATA_MANDATORY) {
+      PPPDEBUG(LOG_DEBUG, ("pppol2tp: mandatory header flags for data packet not set\n"));
+      goto free_and_return;
+    }
+  }
+
+  /* Expected header size  */
+  hlen = sizeof(hflags) + sizeof(tunnel_id) + sizeof(session_id);
+  if (hflags & PPPOL2TP_HEADERFLAG_LENGTH) {
+    hlen += sizeof(len);
+  }
+  if (hflags & PPPOL2TP_HEADERFLAG_SEQUENCE) {
+    hlen += sizeof(ns) + sizeof(nr);
+  }
+  if (hflags & PPPOL2TP_HEADERFLAG_OFFSET) {
+    hlen += sizeof(offset);
+  }
+  if (p->len < hlen) {
+    goto packet_too_short;
+  }
+
+  if (hflags & PPPOL2TP_HEADERFLAG_LENGTH) {
+    GETSHORT(len, inp);
+    if (p->len < len || len < hlen) {
+      goto packet_too_short;
+    }
+  }
+  GETSHORT(tunnel_id, inp);
+  GETSHORT(session_id, inp);
+  if (hflags & PPPOL2TP_HEADERFLAG_SEQUENCE) {
+    GETSHORT(ns, inp);
+    GETSHORT(nr, inp);
+  }
+  if (hflags & PPPOL2TP_HEADERFLAG_OFFSET) {
+    GETSHORT(offset, inp)
+    if (offset > 4096) { /* don't be fooled with large offset which might overflow hlen */
+      PPPDEBUG(LOG_DEBUG, ("pppol2tp: strange packet received, offset=%d\n", offset));
+      goto free_and_return;
+    }
+    hlen += offset;
+    if (p->len < hlen) {
+      goto packet_too_short;
+    }
+    INCPTR(offset, inp);
+  }
+
+  /* printf("HLEN = %d\n", hlen); */
+
+  /* skip L2TP header */
+  if (pbuf_remove_header(p, hlen) != 0) {
+    goto free_and_return;
+  }
+
+  /* printf("LEN=%d, TUNNEL_ID=%d, SESSION_ID=%d, NS=%d, NR=%d, OFFSET=%d\n", len, tunnel_id, session_id, ns, nr, offset); */
+  PPPDEBUG(LOG_DEBUG, ("pppol2tp: input packet, len=%"U16_F", tunnel=%"U16_F", session=%"U16_F", ns=%"U16_F", nr=%"U16_F"\n",
+    len, tunnel_id, session_id, ns, nr));
+
+  /* Control packet */
+  if (hflags & PPPOL2TP_HEADERFLAG_CONTROL) {
+    pppol2tp_dispatch_control_packet(l2tp, port, p, ns, nr);
+    goto free_and_return;
+  }
+
+  /* Data packet */
+  if(l2tp->phase != PPPOL2TP_STATE_DATA) {
+    goto free_and_return;
+  }
+  if(tunnel_id != l2tp->remote_tunnel_id) {
+     PPPDEBUG(LOG_DEBUG, ("pppol2tp: tunnel ID mismatch, assigned=%d, received=%d\n", l2tp->remote_tunnel_id, tunnel_id));
+     goto free_and_return;
+  }
+  if(session_id != l2tp->remote_session_id) {
+     PPPDEBUG(LOG_DEBUG, ("pppol2tp: session ID mismatch, assigned=%d, received=%d\n", l2tp->remote_session_id, session_id));
+     goto free_and_return;
+  }
+  /*
+   * skip address & flags if necessary
+   *
+   * RFC 2661 does not specify whether the PPP frame in the L2TP payload should
+   * have a HDLC header or not. We handle both cases for compatibility.
+   */
+  if (p->len >= 2) {
+    GETSHORT(hflags, inp);
+    if (hflags == 0xff03) {
+      pbuf_remove_header(p, 2);
+    }
+  }
+  /* Dispatch the packet thereby consuming it. */
+  ppp_input(l2tp->ppp, p);
+  return;
+
+packet_too_short:
+  PPPDEBUG(LOG_DEBUG, ("pppol2tp: packet too short: %d\n", p->len));
+free_and_return:
+  pbuf_free(p);
+}
+
+/* L2TP Control packet entry point */
+static void pppol2tp_dispatch_control_packet(pppol2tp_pcb *l2tp, u16_t port, struct pbuf *p, u16_t ns, u16_t nr) {
+  u8_t *inp;
+  u16_t avplen, avpflags, vendorid, attributetype, messagetype=0;
+  err_t err;
+#if PPPOL2TP_AUTH_SUPPORT
+  lwip_md5_context md5_ctx;
+  u8_t md5_hash[16];
+  u8_t challenge_id = 0;
+#endif /* PPPOL2TP_AUTH_SUPPORT */
+
+  /* printf("L2TP CTRL INPUT, ns=%d, nr=%d, len=%d\n", ns, nr, p->len); */
+
+  /* Drop unexpected packet */
+  if (ns != l2tp->peer_ns) {
+    PPPDEBUG(LOG_DEBUG, ("pppol2tp: drop unexpected packet: received NS=%d, expected NS=%d\n", ns, l2tp->peer_ns));
+    /*
+     * In order to ensure that all messages are acknowledged properly
+     * (particularly in the case of a lost ZLB ACK message), receipt
+     * of duplicate messages MUST be acknowledged.
+     *
+     * In this very special case we Ack a packet we previously received.
+     * Therefore our NS is the NR we just received. And our NR is the
+     * NS we just received plus one.
+     */
+    if ((s16_t)(ns - l2tp->peer_ns) < 0) {
+      pppol2tp_send_zlb(l2tp, nr, ns+1);
+    }
+    return;
+  }
+
+  l2tp->peer_nr = nr;
+
+  /* Handle the special case of the ICCN acknowledge */
+  if (l2tp->phase == PPPOL2TP_STATE_ICCN_SENT && (s16_t)(l2tp->peer_nr - l2tp->our_ns) > 0) {
+    l2tp->phase = PPPOL2TP_STATE_DATA;
+    sys_untimeout(pppol2tp_timeout, l2tp);
+    ppp_start(l2tp->ppp); /* notify upper layers */
+  }
+
+  /* ZLB packets */
+  if (p->tot_len == 0) {
+    return;
+  }
+  /* A ZLB packet does not consume a NS slot thus we don't record the NS value for ZLB packets */
+  l2tp->peer_ns = ns+1;
+
+  p = pbuf_coalesce(p, PBUF_RAW);
+  inp = (u8_t*)p->payload;
+  /* Decode AVPs */
+  while (p->len > 0) {
+    if (p->len < sizeof(avpflags) + sizeof(vendorid) + sizeof(attributetype) ) {
+      goto packet_too_short;
+    }
+    GETSHORT(avpflags, inp);
+    avplen = avpflags & PPPOL2TP_AVPHEADERFLAG_LENGTHMASK;
+    /* printf("AVPLEN = %d\n", avplen); */
+    if (p->len < avplen || avplen < sizeof(avpflags) + sizeof(vendorid) + sizeof(attributetype)) {
+      goto packet_too_short;
+    }
+    GETSHORT(vendorid, inp);
+    GETSHORT(attributetype, inp);
+    avplen -= sizeof(avpflags) + sizeof(vendorid) + sizeof(attributetype);
+
+    /* Message type must be the first AVP */
+    if (messagetype == 0) {
+      if (attributetype != 0 || vendorid != 0 || avplen != sizeof(messagetype) ) {
+        PPPDEBUG(LOG_DEBUG, ("pppol2tp: message type must be the first AVP\n"));
+        return;
+      }
+      GETSHORT(messagetype, inp);
+      /* printf("Message type = %d\n", messagetype); */
+      switch(messagetype) {
+        /* Start Control Connection Reply */
+        case PPPOL2TP_MESSAGETYPE_SCCRP:
+          /* Only accept SCCRP packet if we sent a SCCRQ */
+          if (l2tp->phase != PPPOL2TP_STATE_SCCRQ_SENT) {
+            goto send_zlb;
+          }
+          break;
+        /* Incoming Call Reply */
+        case PPPOL2TP_MESSAGETYPE_ICRP:
+          /* Only accept ICRP packet if we sent a IRCQ */
+          if (l2tp->phase != PPPOL2TP_STATE_ICRQ_SENT) {
+            goto send_zlb;
+          }
+          break;
+        /* Stop Control Connection Notification */
+        case PPPOL2TP_MESSAGETYPE_STOPCCN:
+          pppol2tp_send_zlb(l2tp, l2tp->our_ns+1, l2tp->peer_ns); /* Ack the StopCCN before we switch to down state */
+          if (l2tp->phase < PPPOL2TP_STATE_DATA) {
+            pppol2tp_abort_connect(l2tp);
+          } else if (l2tp->phase == PPPOL2TP_STATE_DATA) {
+            /* Don't disconnect here, we let the LCP Echo/Reply find the fact
+             * that PPP session is down. Asking the PPP stack to end the session
+             * require strict checking about the PPP phase to prevent endless
+             * disconnection loops.
+             */
+          }
+          return;
+        default:
+          break;
+      }
+      goto nextavp;
+    }
+
+    /* Skip proprietary L2TP extensions */
+    if (vendorid != 0) {
+      goto skipavp;
+    }
+
+    switch (messagetype) {
+      /* Start Control Connection Reply */
+      case PPPOL2TP_MESSAGETYPE_SCCRP:
+       switch (attributetype) {
+          case PPPOL2TP_AVPTYPE_TUNNELID:
+            if (avplen != sizeof(l2tp->source_tunnel_id) ) {
+               PPPDEBUG(LOG_DEBUG, ("pppol2tp: AVP Assign tunnel ID length check failed\n"));
+               return;
+            }
+            GETSHORT(l2tp->source_tunnel_id, inp);
+            PPPDEBUG(LOG_DEBUG, ("pppol2tp: Assigned tunnel ID %"U16_F"\n", l2tp->source_tunnel_id));
+            goto nextavp;
+#if PPPOL2TP_AUTH_SUPPORT
+          case PPPOL2TP_AVPTYPE_CHALLENGE:
+            if (avplen == 0) {
+               PPPDEBUG(LOG_DEBUG, ("pppol2tp: Challenge length check failed\n"));
+               return;
+            }
+            if (l2tp->secret == NULL) {
+              PPPDEBUG(LOG_DEBUG, ("pppol2tp: Received challenge from peer and no secret key available\n"));
+              pppol2tp_abort_connect(l2tp);
+              return;
+            }
+            /* Generate hash of ID, secret, challenge */
+            lwip_md5_init(&md5_ctx);
+            lwip_md5_starts(&md5_ctx);
+            challenge_id = PPPOL2TP_MESSAGETYPE_SCCCN;
+            lwip_md5_update(&md5_ctx, &challenge_id, 1);
+            lwip_md5_update(&md5_ctx, l2tp->secret, l2tp->secret_len);
+            lwip_md5_update(&md5_ctx, inp, avplen);
+            lwip_md5_finish(&md5_ctx, l2tp->challenge_hash);
+            lwip_md5_free(&md5_ctx);
+            l2tp->send_challenge = 1;
+            goto skipavp;
+          case PPPOL2TP_AVPTYPE_CHALLENGERESPONSE:
+            if (avplen != PPPOL2TP_AVPTYPE_CHALLENGERESPONSE_SIZE) {
+               PPPDEBUG(LOG_DEBUG, ("pppol2tp: AVP Challenge Response length check failed\n"));
+               return;
+            }
+            /* Generate hash of ID, secret, challenge */
+            lwip_md5_init(&md5_ctx);
+            lwip_md5_starts(&md5_ctx);
+            challenge_id = PPPOL2TP_MESSAGETYPE_SCCRP;
+            lwip_md5_update(&md5_ctx, &challenge_id, 1);
+            lwip_md5_update(&md5_ctx, l2tp->secret, l2tp->secret_len);
+            lwip_md5_update(&md5_ctx, l2tp->secret_rv, sizeof(l2tp->secret_rv));
+            lwip_md5_finish(&md5_ctx, md5_hash);
+            lwip_md5_free(&md5_ctx);
+            if ( memcmp(inp, md5_hash, sizeof(md5_hash)) ) {
+              PPPDEBUG(LOG_DEBUG, ("pppol2tp: Received challenge response from peer and secret key do not match\n"));
+              pppol2tp_abort_connect(l2tp);
+              return;
+            }
+            goto skipavp;
+#endif /* PPPOL2TP_AUTH_SUPPORT */
+          default:
+            break;
+        }
+        break;
+      /* Incoming Call Reply */
+      case PPPOL2TP_MESSAGETYPE_ICRP:
+        switch (attributetype) {
+         case PPPOL2TP_AVPTYPE_SESSIONID:
+            if (avplen != sizeof(l2tp->source_session_id) ) {
+               PPPDEBUG(LOG_DEBUG, ("pppol2tp: AVP Assign session ID length check failed\n"));
+               return;
+            }
+            GETSHORT(l2tp->source_session_id, inp);
+            PPPDEBUG(LOG_DEBUG, ("pppol2tp: Assigned session ID %"U16_F"\n", l2tp->source_session_id));
+            goto nextavp;
+          default:
+            break;
+        }
+        break;
+      default:
+        break;
+    }
+
+skipavp:
+    INCPTR(avplen, inp);
+nextavp:
+    /* printf("AVP Found, vendor=%d, attribute=%d, len=%d\n", vendorid, attributetype, avplen); */
+    /* next AVP */
+    if (pbuf_remove_header(p, avplen + sizeof(avpflags) + sizeof(vendorid) + sizeof(attributetype)) != 0) {
+      return;
+    }
+  }
+
+  switch(messagetype) {
+    /* Start Control Connection Reply */
+    case PPPOL2TP_MESSAGETYPE_SCCRP:
+      do {
+        l2tp->remote_session_id = magic();
+      } while(l2tp->remote_session_id == 0);
+      l2tp->tunnel_port = port; /* LNS server might have chosen its own local port */
+      l2tp->icrq_retried = 0;
+      l2tp->phase = PPPOL2TP_STATE_ICRQ_SENT;
+      l2tp->our_ns++;
+      if ((err = pppol2tp_send_scccn(l2tp, l2tp->our_ns)) != 0) {
+        PPPDEBUG(LOG_DEBUG, ("pppol2tp: failed to send SCCCN, error=%d\n", err));
+        LWIP_UNUSED_ARG(err); /* if PPPDEBUG is disabled */
+      }
+      l2tp->our_ns++;
+      if ((err = pppol2tp_send_icrq(l2tp, l2tp->our_ns)) != 0) {
+        PPPDEBUG(LOG_DEBUG, ("pppol2tp: failed to send ICRQ, error=%d\n", err));
+        LWIP_UNUSED_ARG(err); /* if PPPDEBUG is disabled */
+      }
+      sys_untimeout(pppol2tp_timeout, l2tp);
+      sys_timeout(PPPOL2TP_CONTROL_TIMEOUT, pppol2tp_timeout, l2tp);
+      break;
+    /* Incoming Call Reply */
+    case PPPOL2TP_MESSAGETYPE_ICRP:
+      l2tp->iccn_retried = 0;
+      l2tp->phase = PPPOL2TP_STATE_ICCN_SENT;
+      l2tp->our_ns++;
+      if ((err = pppol2tp_send_iccn(l2tp, l2tp->our_ns)) != 0) {
+        PPPDEBUG(LOG_DEBUG, ("pppol2tp: failed to send ICCN, error=%d\n", err));
+        LWIP_UNUSED_ARG(err); /* if PPPDEBUG is disabled */
+      }
+      sys_untimeout(pppol2tp_timeout, l2tp);
+      sys_timeout(PPPOL2TP_CONTROL_TIMEOUT, pppol2tp_timeout, l2tp);
+      break;
+    /* Unhandled packet, send ZLB ACK */
+    default:
+      goto send_zlb;
+  }
+  return;
+
+send_zlb:
+  pppol2tp_send_zlb(l2tp, l2tp->our_ns+1, l2tp->peer_ns);
+  return;
+packet_too_short:
+  PPPDEBUG(LOG_DEBUG, ("pppol2tp: packet too short: %d\n", p->len));
+}
+
+/* L2TP Timeout handler */
+static void pppol2tp_timeout(void *arg) {
+  pppol2tp_pcb *l2tp = (pppol2tp_pcb*)arg;
+  err_t err;
+  u32_t retry_wait;
+
+  PPPDEBUG(LOG_DEBUG, ("pppol2tp: timeout\n"));
+
+  switch (l2tp->phase) {
+    case PPPOL2TP_STATE_SCCRQ_SENT:
+      /* backoff wait */
+      if (l2tp->sccrq_retried < 0xff) {
+        l2tp->sccrq_retried++;
+      }
+      if (!l2tp->ppp->settings.persist && l2tp->sccrq_retried >= PPPOL2TP_MAXSCCRQ) {
+        pppol2tp_abort_connect(l2tp);
+        return;
+      }
+      retry_wait = LWIP_MIN(PPPOL2TP_CONTROL_TIMEOUT * l2tp->sccrq_retried, PPPOL2TP_SLOW_RETRY);
+      PPPDEBUG(LOG_DEBUG, ("pppol2tp: sccrq_retried=%d\n", l2tp->sccrq_retried));
+      if ((err = pppol2tp_send_sccrq(l2tp)) != 0) {
+        l2tp->sccrq_retried--;
+        PPPDEBUG(LOG_DEBUG, ("pppol2tp: failed to send SCCRQ, error=%d\n", err));
+        LWIP_UNUSED_ARG(err); /* if PPPDEBUG is disabled */
+      }
+      sys_timeout(retry_wait, pppol2tp_timeout, l2tp);
+      break;
+
+    case PPPOL2TP_STATE_ICRQ_SENT:
+      l2tp->icrq_retried++;
+      if (l2tp->icrq_retried >= PPPOL2TP_MAXICRQ) {
+        pppol2tp_abort_connect(l2tp);
+        return;
+      }
+      PPPDEBUG(LOG_DEBUG, ("pppol2tp: icrq_retried=%d\n", l2tp->icrq_retried));
+      if ((s16_t)(l2tp->peer_nr - l2tp->our_ns) < 0) { /* the SCCCN was not acknowledged */
+        if ((err = pppol2tp_send_scccn(l2tp, l2tp->our_ns -1)) != 0) {
+          l2tp->icrq_retried--;
+          PPPDEBUG(LOG_DEBUG, ("pppol2tp: failed to send SCCCN, error=%d\n", err));
+          LWIP_UNUSED_ARG(err); /* if PPPDEBUG is disabled */
+          sys_timeout(PPPOL2TP_CONTROL_TIMEOUT, pppol2tp_timeout, l2tp);
+          break;
+        }
+      }
+      if ((err = pppol2tp_send_icrq(l2tp, l2tp->our_ns)) != 0) {
+        l2tp->icrq_retried--;
+        PPPDEBUG(LOG_DEBUG, ("pppol2tp: failed to send ICRQ, error=%d\n", err));
+        LWIP_UNUSED_ARG(err); /* if PPPDEBUG is disabled */
+      }
+      sys_timeout(PPPOL2TP_CONTROL_TIMEOUT, pppol2tp_timeout, l2tp);
+      break;
+
+    case PPPOL2TP_STATE_ICCN_SENT:
+      l2tp->iccn_retried++;
+      if (l2tp->iccn_retried >= PPPOL2TP_MAXICCN) {
+        pppol2tp_abort_connect(l2tp);
+        return;
+      }
+      PPPDEBUG(LOG_DEBUG, ("pppol2tp: iccn_retried=%d\n", l2tp->iccn_retried));
+      if ((err = pppol2tp_send_iccn(l2tp, l2tp->our_ns)) != 0) {
+        l2tp->iccn_retried--;
+        PPPDEBUG(LOG_DEBUG, ("pppol2tp: failed to send ICCN, error=%d\n", err));
+        LWIP_UNUSED_ARG(err); /* if PPPDEBUG is disabled */
+      }
+      sys_timeout(PPPOL2TP_CONTROL_TIMEOUT, pppol2tp_timeout, l2tp);
+      break;
+
+    default:
+      return;  /* all done, work in peace */
+  }
+}
+
+/* Connection attempt aborted */
+static void pppol2tp_abort_connect(pppol2tp_pcb *l2tp) {
+  PPPDEBUG(LOG_DEBUG, ("pppol2tp: could not establish connection\n"));
+  l2tp->phase = PPPOL2TP_STATE_INITIAL;
+  ppp_link_failed(l2tp->ppp); /* notify upper layers */
+}
+
+/* Initiate a new tunnel */
+static err_t pppol2tp_send_sccrq(pppol2tp_pcb *l2tp) {
+  struct pbuf *pb;
+  u8_t *p;
+  u16_t len;
+
+  /* calculate UDP packet length */
+  len = 12 +8 +8 +10 +10 +6+sizeof(PPPOL2TP_HOSTNAME)-1 +6+sizeof(PPPOL2TP_VENDORNAME)-1 +8 +8;
+#if PPPOL2TP_AUTH_SUPPORT
+  if (l2tp->secret != NULL) {
+    len += 6 + sizeof(l2tp->secret_rv);
+  }
+#endif /* PPPOL2TP_AUTH_SUPPORT */
+
+  /* allocate a buffer */
+  pb = pbuf_alloc(PBUF_TRANSPORT, len, PBUF_RAM);
+  if (pb == NULL) {
+    return ERR_MEM;
+  }
+  LWIP_ASSERT("pb->tot_len == pb->len", pb->tot_len == pb->len);
+
+  p = (u8_t*)pb->payload;
+  /* fill in pkt */
+  /* L2TP control header */
+  PUTSHORT(PPPOL2TP_HEADERFLAG_CONTROL_MANDATORY, p);
+  PUTSHORT(len, p); /* Length */
+  PUTSHORT(0, p); /* Tunnel Id */
+  PUTSHORT(0, p); /* Session Id */
+  PUTSHORT(0, p); /* NS Sequence number - to peer */
+  PUTSHORT(0, p); /* NR Sequence number - expected for peer */
+
+  /* AVP - Message type */
+  PUTSHORT(PPPOL2TP_AVPHEADERFLAG_MANDATORY + 8, p); /* Mandatory flag + len field */
+  PUTSHORT(0, p); /* Vendor ID */
+  PUTSHORT(PPPOL2TP_AVPTYPE_MESSAGE, p); /* Attribute type: Message Type */
+  PUTSHORT(PPPOL2TP_MESSAGETYPE_SCCRQ, p); /* Attribute value: Message type: SCCRQ */
+
+  /* AVP - L2TP Version */
+  PUTSHORT(PPPOL2TP_AVPHEADERFLAG_MANDATORY + 8, p); /* Mandatory flag + len field */
+  PUTSHORT(0, p); /* Vendor ID */
+  PUTSHORT(PPPOL2TP_AVPTYPE_VERSION, p); /* Attribute type: Version */
+  PUTSHORT(PPPOL2TP_VERSION, p); /* Attribute value: L2TP Version */
+
+  /* AVP - Framing capabilities */
+  PUTSHORT(PPPOL2TP_AVPHEADERFLAG_MANDATORY + 10, p); /* Mandatory flag + len field */
+  PUTSHORT(0, p); /* Vendor ID */
+  PUTSHORT(PPPOL2TP_AVPTYPE_FRAMINGCAPABILITIES, p); /* Attribute type: Framing capabilities */
+  PUTLONG(PPPOL2TP_FRAMINGCAPABILITIES, p); /* Attribute value: Framing capabilities */
+
+  /* AVP - Bearer capabilities */
+  PUTSHORT(PPPOL2TP_AVPHEADERFLAG_MANDATORY + 10, p); /* Mandatory flag + len field */
+  PUTSHORT(0, p); /* Vendor ID */
+  PUTSHORT(PPPOL2TP_AVPTYPE_BEARERCAPABILITIES, p); /* Attribute type: Bearer capabilities */
+  PUTLONG(PPPOL2TP_BEARERCAPABILITIES, p); /* Attribute value: Bearer capabilities */
+
+  /* AVP - Host name */
+  PUTSHORT(PPPOL2TP_AVPHEADERFLAG_MANDATORY + 6+sizeof(PPPOL2TP_HOSTNAME)-1, p); /* Mandatory flag + len field */
+  PUTSHORT(0, p); /* Vendor ID */
+  PUTSHORT(PPPOL2TP_AVPTYPE_HOSTNAME, p); /* Attribute type: Hostname */
+  MEMCPY(p, PPPOL2TP_HOSTNAME, sizeof(PPPOL2TP_HOSTNAME)-1); /* Attribute value: Hostname */
+  INCPTR(sizeof(PPPOL2TP_HOSTNAME)-1, p);
+
+  /* AVP - Vendor name */
+  PUTSHORT(6+sizeof(PPPOL2TP_VENDORNAME)-1, p); /* len field */
+  PUTSHORT(0, p); /* Vendor ID */
+  PUTSHORT(PPPOL2TP_AVPTYPE_VENDORNAME, p); /* Attribute type: Vendor name */
+  MEMCPY(p, PPPOL2TP_VENDORNAME, sizeof(PPPOL2TP_VENDORNAME)-1); /* Attribute value: Vendor name */
+  INCPTR(sizeof(PPPOL2TP_VENDORNAME)-1, p);
+
+  /* AVP - Assign tunnel ID */
+  PUTSHORT(PPPOL2TP_AVPHEADERFLAG_MANDATORY + 8, p); /* Mandatory flag + len field */
+  PUTSHORT(0, p); /* Vendor ID */
+  PUTSHORT(PPPOL2TP_AVPTYPE_TUNNELID, p); /* Attribute type: Tunnel ID */
+  PUTSHORT(l2tp->remote_tunnel_id, p); /* Attribute value: Tunnel ID */
+
+  /* AVP - Receive window size */
+  PUTSHORT(PPPOL2TP_AVPHEADERFLAG_MANDATORY + 8, p); /* Mandatory flag + len field */
+  PUTSHORT(0, p); /* Vendor ID */
+  PUTSHORT(PPPOL2TP_AVPTYPE_RECEIVEWINDOWSIZE, p); /* Attribute type: Receive window size */
+  PUTSHORT(PPPOL2TP_RECEIVEWINDOWSIZE, p); /* Attribute value: Receive window size */
+
+#if PPPOL2TP_AUTH_SUPPORT
+  /* AVP - Challenge */
+  if (l2tp->secret != NULL) {
+    PUTSHORT(PPPOL2TP_AVPHEADERFLAG_MANDATORY + 6 + sizeof(l2tp->secret_rv), p); /* Mandatory flag + len field */
+    PUTSHORT(0, p); /* Vendor ID */
+    PUTSHORT(PPPOL2TP_AVPTYPE_CHALLENGE, p); /* Attribute type: Challenge */
+    MEMCPY(p, l2tp->secret_rv, sizeof(l2tp->secret_rv)); /* Attribute value: Random vector */
+    INCPTR(sizeof(l2tp->secret_rv), p);
+  }
+#endif /* PPPOL2TP_AUTH_SUPPORT */
+
+  return pppol2tp_udp_send(l2tp, pb);
+}
+
+/* Complete tunnel establishment */
+static err_t pppol2tp_send_scccn(pppol2tp_pcb *l2tp, u16_t ns) {
+  struct pbuf *pb;
+  u8_t *p;
+  u16_t len;
+
+  /* calculate UDP packet length */
+  len = 12 +8;
+#if PPPOL2TP_AUTH_SUPPORT
+  if (l2tp->send_challenge) {
+    len += 6 + sizeof(l2tp->challenge_hash);
+  }
+#endif /* PPPOL2TP_AUTH_SUPPORT */
+
+  /* allocate a buffer */
+  pb = pbuf_alloc(PBUF_TRANSPORT, len, PBUF_RAM);
+  if (pb == NULL) {
+    return ERR_MEM;
+  }
+  LWIP_ASSERT("pb->tot_len == pb->len", pb->tot_len == pb->len);
+
+  p = (u8_t*)pb->payload;
+  /* fill in pkt */
+  /* L2TP control header */
+  PUTSHORT(PPPOL2TP_HEADERFLAG_CONTROL_MANDATORY, p);
+  PUTSHORT(len, p); /* Length */
+  PUTSHORT(l2tp->source_tunnel_id, p); /* Tunnel Id */
+  PUTSHORT(0, p); /* Session Id */
+  PUTSHORT(ns, p); /* NS Sequence number - to peer */
+  PUTSHORT(l2tp->peer_ns, p); /* NR Sequence number - expected for peer */
+
+  /* AVP - Message type */
+  PUTSHORT(PPPOL2TP_AVPHEADERFLAG_MANDATORY + 8, p); /* Mandatory flag + len field */
+  PUTSHORT(0, p); /* Vendor ID */
+  PUTSHORT(PPPOL2TP_AVPTYPE_MESSAGE, p); /* Attribute type: Message Type */
+  PUTSHORT(PPPOL2TP_MESSAGETYPE_SCCCN, p); /* Attribute value: Message type: SCCCN */
+
+#if PPPOL2TP_AUTH_SUPPORT
+  /* AVP - Challenge response */
+  if (l2tp->send_challenge) {
+    PUTSHORT(PPPOL2TP_AVPHEADERFLAG_MANDATORY + 6 + sizeof(l2tp->challenge_hash), p); /* Mandatory flag + len field */
+    PUTSHORT(0, p); /* Vendor ID */
+    PUTSHORT(PPPOL2TP_AVPTYPE_CHALLENGERESPONSE, p); /* Attribute type: Challenge response */
+    MEMCPY(p, l2tp->challenge_hash, sizeof(l2tp->challenge_hash)); /* Attribute value: Computed challenge */
+    INCPTR(sizeof(l2tp->challenge_hash), p);
+  }
+#endif /* PPPOL2TP_AUTH_SUPPORT */
+
+  return pppol2tp_udp_send(l2tp, pb);
+}
+
+/* Initiate a new session */
+static err_t pppol2tp_send_icrq(pppol2tp_pcb *l2tp, u16_t ns) {
+  struct pbuf *pb;
+  u8_t *p;
+  u16_t len;
+  u32_t serialnumber;
+
+  /* calculate UDP packet length */
+  len = 12 +8 +8 +10;
+
+  /* allocate a buffer */
+  pb = pbuf_alloc(PBUF_TRANSPORT, len, PBUF_RAM);
+  if (pb == NULL) {
+    return ERR_MEM;
+  }
+  LWIP_ASSERT("pb->tot_len == pb->len", pb->tot_len == pb->len);
+
+  p = (u8_t*)pb->payload;
+  /* fill in pkt */
+  /* L2TP control header */
+  PUTSHORT(PPPOL2TP_HEADERFLAG_CONTROL_MANDATORY, p);
+  PUTSHORT(len, p); /* Length */
+  PUTSHORT(l2tp->source_tunnel_id, p); /* Tunnel Id */
+  PUTSHORT(0, p); /* Session Id */
+  PUTSHORT(ns, p); /* NS Sequence number - to peer */
+  PUTSHORT(l2tp->peer_ns, p); /* NR Sequence number - expected for peer */
+
+  /* AVP - Message type */
+  PUTSHORT(PPPOL2TP_AVPHEADERFLAG_MANDATORY + 8, p); /* Mandatory flag + len field */
+  PUTSHORT(0, p); /* Vendor ID */
+  PUTSHORT(PPPOL2TP_AVPTYPE_MESSAGE, p); /* Attribute type: Message Type */
+  PUTSHORT(PPPOL2TP_MESSAGETYPE_ICRQ, p); /* Attribute value: Message type: ICRQ */
+
+  /* AVP - Assign session ID */
+  PUTSHORT(PPPOL2TP_AVPHEADERFLAG_MANDATORY + 8, p); /* Mandatory flag + len field */
+  PUTSHORT(0, p); /* Vendor ID */
+  PUTSHORT(PPPOL2TP_AVPTYPE_SESSIONID, p); /* Attribute type: Session ID */
+  PUTSHORT(l2tp->remote_session_id, p); /* Attribute value: Session ID */
+
+  /* AVP - Call Serial Number */
+  PUTSHORT(PPPOL2TP_AVPHEADERFLAG_MANDATORY + 10, p); /* Mandatory flag + len field */
+  PUTSHORT(0, p); /* Vendor ID */
+  PUTSHORT(PPPOL2TP_AVPTYPE_CALLSERIALNUMBER, p); /* Attribute type: Serial number */
+  serialnumber = magic();
+  PUTLONG(serialnumber, p); /* Attribute value: Serial number */
+
+  return pppol2tp_udp_send(l2tp, pb);
+}
+
+/* Complete tunnel establishment */
+static err_t pppol2tp_send_iccn(pppol2tp_pcb *l2tp, u16_t ns) {
+  struct pbuf *pb;
+  u8_t *p;
+  u16_t len;
+
+  /* calculate UDP packet length */
+  len = 12 +8 +10 +10;
+
+  /* allocate a buffer */
+  pb = pbuf_alloc(PBUF_TRANSPORT, len, PBUF_RAM);
+  if (pb == NULL) {
+    return ERR_MEM;
+  }
+  LWIP_ASSERT("pb->tot_len == pb->len", pb->tot_len == pb->len);
+
+  p = (u8_t*)pb->payload;
+  /* fill in pkt */
+  /* L2TP control header */
+  PUTSHORT(PPPOL2TP_HEADERFLAG_CONTROL_MANDATORY, p);
+  PUTSHORT(len, p); /* Length */
+  PUTSHORT(l2tp->source_tunnel_id, p); /* Tunnel Id */
+  PUTSHORT(l2tp->source_session_id, p); /* Session Id */
+  PUTSHORT(ns, p); /* NS Sequence number - to peer */
+  PUTSHORT(l2tp->peer_ns, p); /* NR Sequence number - expected for peer */
+
+  /* AVP - Message type */
+  PUTSHORT(PPPOL2TP_AVPHEADERFLAG_MANDATORY + 8, p); /* Mandatory flag + len field */
+  PUTSHORT(0, p); /* Vendor ID */
+  PUTSHORT(PPPOL2TP_AVPTYPE_MESSAGE, p); /* Attribute type: Message Type */
+  PUTSHORT(PPPOL2TP_MESSAGETYPE_ICCN, p); /* Attribute value: Message type: ICCN */
+
+  /* AVP - Framing type */
+  PUTSHORT(PPPOL2TP_AVPHEADERFLAG_MANDATORY + 10, p); /* Mandatory flag + len field */
+  PUTSHORT(0, p); /* Vendor ID */
+  PUTSHORT(PPPOL2TP_AVPTYPE_FRAMINGTYPE, p); /* Attribute type: Framing type */
+  PUTLONG(PPPOL2TP_FRAMINGTYPE, p); /* Attribute value: Framing type */
+
+  /* AVP - TX Connect speed */
+  PUTSHORT(PPPOL2TP_AVPHEADERFLAG_MANDATORY + 10, p); /* Mandatory flag + len field */
+  PUTSHORT(0, p); /* Vendor ID */
+  PUTSHORT(PPPOL2TP_AVPTYPE_TXCONNECTSPEED, p); /* Attribute type: TX Connect speed */
+  PUTLONG(PPPOL2TP_TXCONNECTSPEED, p); /* Attribute value: TX Connect speed */
+
+  return pppol2tp_udp_send(l2tp, pb);
+}
+
+/* Send a ZLB ACK packet */
+static err_t pppol2tp_send_zlb(pppol2tp_pcb *l2tp, u16_t ns, u16_t nr) {
+  struct pbuf *pb;
+  u8_t *p;
+  u16_t len;
+
+  /* calculate UDP packet length */
+  len = 12;
+
+  /* allocate a buffer */
+  pb = pbuf_alloc(PBUF_TRANSPORT, len, PBUF_RAM);
+  if (pb == NULL) {
+    return ERR_MEM;
+  }
+  LWIP_ASSERT("pb->tot_len == pb->len", pb->tot_len == pb->len);
+
+  p = (u8_t*)pb->payload;
+  /* fill in pkt */
+  /* L2TP control header */
+  PUTSHORT(PPPOL2TP_HEADERFLAG_CONTROL_MANDATORY, p);
+  PUTSHORT(len, p); /* Length */
+  PUTSHORT(l2tp->source_tunnel_id, p); /* Tunnel Id */
+  PUTSHORT(0, p); /* Session Id */
+  PUTSHORT(ns, p); /* NS Sequence number - to peer */
+  PUTSHORT(nr, p); /* NR Sequence number - expected for peer */
+
+  return pppol2tp_udp_send(l2tp, pb);
+}
+
+/* Send a StopCCN packet */
+static err_t pppol2tp_send_stopccn(pppol2tp_pcb *l2tp, u16_t ns) {
+  struct pbuf *pb;
+  u8_t *p;
+  u16_t len;
+
+  /* calculate UDP packet length */
+  len = 12 +8 +8 +8;
+
+  /* allocate a buffer */
+  pb = pbuf_alloc(PBUF_TRANSPORT, len, PBUF_RAM);
+  if (pb == NULL) {
+    return ERR_MEM;
+  }
+  LWIP_ASSERT("pb->tot_len == pb->len", pb->tot_len == pb->len);
+
+  p = (u8_t*)pb->payload;
+  /* fill in pkt */
+  /* L2TP control header */
+  PUTSHORT(PPPOL2TP_HEADERFLAG_CONTROL_MANDATORY, p);
+  PUTSHORT(len, p); /* Length */
+  PUTSHORT(l2tp->source_tunnel_id, p); /* Tunnel Id */
+  PUTSHORT(0, p); /* Session Id */
+  PUTSHORT(ns, p); /* NS Sequence number - to peer */
+  PUTSHORT(l2tp->peer_ns, p); /* NR Sequence number - expected for peer */
+
+  /* AVP - Message type */
+  PUTSHORT(PPPOL2TP_AVPHEADERFLAG_MANDATORY + 8, p); /* Mandatory flag + len field */
+  PUTSHORT(0, p); /* Vendor ID */
+  PUTSHORT(PPPOL2TP_AVPTYPE_MESSAGE, p); /* Attribute type: Message Type */
+  PUTSHORT(PPPOL2TP_MESSAGETYPE_STOPCCN, p); /* Attribute value: Message type: StopCCN */
+
+  /* AVP - Assign tunnel ID */
+  PUTSHORT(PPPOL2TP_AVPHEADERFLAG_MANDATORY + 8, p); /* Mandatory flag + len field */
+  PUTSHORT(0, p); /* Vendor ID */
+  PUTSHORT(PPPOL2TP_AVPTYPE_TUNNELID, p); /* Attribute type: Tunnel ID */
+  PUTSHORT(l2tp->remote_tunnel_id, p); /* Attribute value: Tunnel ID */
+
+  /* AVP - Result code */
+  PUTSHORT(PPPOL2TP_AVPHEADERFLAG_MANDATORY + 8, p); /* Mandatory flag + len field */
+  PUTSHORT(0, p); /* Vendor ID */
+  PUTSHORT(PPPOL2TP_AVPTYPE_RESULTCODE, p); /* Attribute type: Result code */
+  PUTSHORT(PPPOL2TP_RESULTCODE, p); /* Attribute value: Result code */
+
+  return pppol2tp_udp_send(l2tp, pb);
+}
+
+static err_t pppol2tp_xmit(pppol2tp_pcb *l2tp, struct pbuf *pb) {
+  u8_t *p;
+
+  /* make room for L2TP header - should not fail */
+  if (pbuf_add_header(pb, PPPOL2TP_OUTPUT_DATA_HEADER_LEN) != 0) {
+    /* bail out */
+    PPPDEBUG(LOG_ERR, ("pppol2tp: pppol2tp_pcb: could not allocate room for L2TP header\n"));
+    LINK_STATS_INC(link.lenerr);
+    pbuf_free(pb);
+    return ERR_BUF;
+  }
+
+  p = (u8_t*)pb->payload;
+  PUTSHORT(PPPOL2TP_HEADERFLAG_DATA_MANDATORY, p);
+  PUTSHORT(l2tp->source_tunnel_id, p); /* Tunnel Id */
+  PUTSHORT(l2tp->source_session_id, p); /* Session Id */
+
+  return pppol2tp_udp_send(l2tp, pb);
+}
+
+static err_t pppol2tp_udp_send(pppol2tp_pcb *l2tp, struct pbuf *pb) {
+  err_t err;
+  if (l2tp->netif) {
+    err = udp_sendto_if(l2tp->udp, pb, &l2tp->remote_ip, l2tp->tunnel_port, l2tp->netif);
+  } else {
+    err = udp_sendto(l2tp->udp, pb, &l2tp->remote_ip, l2tp->tunnel_port);
+  }
+  pbuf_free(pb);
+  return err;
+}
+
+#endif /* PPP_SUPPORT && PPPOL2TP_SUPPORT */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/netif/ppp/pppos.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/netif/ppp/pppos.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/netif/ppp/pppos.c	(revision 457)
@@ -0,0 +1,895 @@
+/**
+ * @file
+ * Network Point to Point Protocol over Serial file.
+ *
+ */
+
+/*
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ */
+
+#include "netif/ppp/ppp_opts.h"
+#if PPP_SUPPORT && PPPOS_SUPPORT /* don't build if not configured for use in lwipopts.h */
+
+#include <string.h>
+
+#include "lwip/arch.h"
+#include "lwip/err.h"
+#include "lwip/pbuf.h"
+#include "lwip/sys.h"
+#include "lwip/memp.h"
+#include "lwip/netif.h"
+#include "lwip/snmp.h"
+#include "lwip/priv/tcpip_priv.h"
+#include "lwip/api.h"
+#include "lwip/ip4.h" /* for ip4_input() */
+
+#include "netif/ppp/ppp_impl.h"
+#include "netif/ppp/pppos.h"
+#include "netif/ppp/vj.h"
+
+/* Memory pool */
+LWIP_MEMPOOL_DECLARE(PPPOS_PCB, MEMP_NUM_PPPOS_INTERFACES, sizeof(pppos_pcb), "PPPOS_PCB")
+
+/* callbacks called from PPP core */
+static err_t pppos_write(ppp_pcb *ppp, void *ctx, struct pbuf *p);
+static err_t pppos_netif_output(ppp_pcb *ppp, void *ctx, struct pbuf *pb, u16_t protocol);
+static void pppos_connect(ppp_pcb *ppp, void *ctx);
+#if PPP_SERVER
+static void pppos_listen(ppp_pcb *ppp, void *ctx);
+#endif /* PPP_SERVER */
+static void pppos_disconnect(ppp_pcb *ppp, void *ctx);
+static err_t pppos_destroy(ppp_pcb *ppp, void *ctx);
+static void pppos_send_config(ppp_pcb *ppp, void *ctx, u32_t accm, int pcomp, int accomp);
+static void pppos_recv_config(ppp_pcb *ppp, void *ctx, u32_t accm, int pcomp, int accomp);
+
+/* Prototypes for procedures local to this file. */
+#if PPP_INPROC_IRQ_SAFE
+static void pppos_input_callback(void *arg);
+#endif /* PPP_INPROC_IRQ_SAFE */
+static void pppos_input_free_current_packet(pppos_pcb *pppos);
+static void pppos_input_drop(pppos_pcb *pppos);
+static err_t pppos_output_append(pppos_pcb *pppos, err_t err, struct pbuf *nb, u8_t c, u8_t accm, u16_t *fcs);
+static err_t pppos_output_last(pppos_pcb *pppos, err_t err, struct pbuf *nb, u16_t *fcs);
+
+/* Callbacks structure for PPP core */
+static const struct link_callbacks pppos_callbacks = {
+  pppos_connect,
+#if PPP_SERVER
+  pppos_listen,
+#endif /* PPP_SERVER */
+  pppos_disconnect,
+  pppos_destroy,
+  pppos_write,
+  pppos_netif_output,
+  pppos_send_config,
+  pppos_recv_config
+};
+
+/* PPP's Asynchronous-Control-Character-Map.  The mask array is used
+ * to select the specific bit for a character. */
+#define ESCAPE_P(accm, c) ((accm)[(c) >> 3] & 1 << (c & 0x07))
+
+#if PPP_FCS_TABLE
+/*
+ * FCS lookup table as calculated by genfcstab.
+ */
+static const u16_t fcstab[256] = {
+  0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf,
+  0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7,
+  0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e,
+  0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876,
+  0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd,
+  0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5,
+  0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c,
+  0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974,
+  0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb,
+  0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3,
+  0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a,
+  0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72,
+  0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9,
+  0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1,
+  0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738,
+  0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70,
+  0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7,
+  0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff,
+  0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036,
+  0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e,
+  0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5,
+  0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd,
+  0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134,
+  0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c,
+  0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3,
+  0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb,
+  0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232,
+  0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a,
+  0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1,
+  0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9,
+  0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330,
+  0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78
+};
+#define PPP_FCS(fcs, c) (((fcs) >> 8) ^ fcstab[((fcs) ^ (c)) & 0xff])
+#else /* PPP_FCS_TABLE */
+/* The HDLC polynomial: X**0 + X**5 + X**12 + X**16 (0x8408) */
+#define PPP_FCS_POLYNOMIAL 0x8408
+static u16_t
+ppp_get_fcs(u8_t byte)
+{
+  unsigned int octet;
+  int bit;
+  octet = byte;
+  for (bit = 8; bit-- > 0; ) {
+    octet = (octet & 0x01) ? ((octet >> 1) ^ PPP_FCS_POLYNOMIAL) : (octet >> 1);
+  }
+  return octet & 0xffff;
+}
+#define PPP_FCS(fcs, c) (((fcs) >> 8) ^ ppp_get_fcs(((fcs) ^ (c)) & 0xff))
+#endif /* PPP_FCS_TABLE */
+
+/*
+ * Values for FCS calculations.
+ */
+#define PPP_INITFCS     0xffff  /* Initial FCS value */
+#define PPP_GOODFCS     0xf0b8  /* Good final FCS value */
+
+#if PPP_INPROC_IRQ_SAFE
+#define PPPOS_DECL_PROTECT(lev) SYS_ARCH_DECL_PROTECT(lev)
+#define PPPOS_PROTECT(lev) SYS_ARCH_PROTECT(lev)
+#define PPPOS_UNPROTECT(lev) SYS_ARCH_UNPROTECT(lev)
+#else
+#define PPPOS_DECL_PROTECT(lev)
+#define PPPOS_PROTECT(lev)
+#define PPPOS_UNPROTECT(lev)
+#endif /* PPP_INPROC_IRQ_SAFE */
+
+
+/*
+ * Create a new PPP connection using the given serial I/O device.
+ *
+ * Return 0 on success, an error code on failure.
+ */
+ppp_pcb *pppos_create(struct netif *pppif, pppos_output_cb_fn output_cb,
+       ppp_link_status_cb_fn link_status_cb, void *ctx_cb)
+{
+  pppos_pcb *pppos;
+  ppp_pcb *ppp;
+  LWIP_ASSERT_CORE_LOCKED();
+
+  pppos = (pppos_pcb *)LWIP_MEMPOOL_ALLOC(PPPOS_PCB);
+  if (pppos == NULL) {
+    return NULL;
+  }
+
+  ppp = ppp_new(pppif, &pppos_callbacks, pppos, link_status_cb, ctx_cb);
+  if (ppp == NULL) {
+    LWIP_MEMPOOL_FREE(PPPOS_PCB, pppos);
+    return NULL;
+  }
+
+  memset(pppos, 0, sizeof(pppos_pcb));
+  pppos->ppp = ppp;
+  pppos->output_cb = output_cb;
+  return ppp;
+}
+
+/* Called by PPP core */
+static err_t
+pppos_write(ppp_pcb *ppp, void *ctx, struct pbuf *p)
+{
+  pppos_pcb *pppos = (pppos_pcb *)ctx;
+  u8_t *s;
+  struct pbuf *nb;
+  u16_t n;
+  u16_t fcs_out;
+  err_t err;
+  LWIP_UNUSED_ARG(ppp);
+
+  /* Grab an output buffer. Using PBUF_POOL here for tx is ok since the pbuf
+     gets freed by 'pppos_output_last' before this function returns and thus
+     cannot starve rx. */
+  nb = pbuf_alloc(PBUF_RAW, 0, PBUF_POOL);
+  if (nb == NULL) {
+    PPPDEBUG(LOG_WARNING, ("pppos_write[%d]: alloc fail\n", ppp->netif->num));
+    LINK_STATS_INC(link.memerr);
+    LINK_STATS_INC(link.drop);
+    MIB2_STATS_NETIF_INC(ppp->netif, ifoutdiscards);
+    pbuf_free(p);
+    return ERR_MEM;
+  }
+
+  /* Set nb->tot_len to actual payload length */
+  nb->tot_len = p->len;
+
+  /* If the link has been idle, we'll send a fresh flag character to
+   * flush any noise. */
+  err = ERR_OK;
+  if ((sys_now() - pppos->last_xmit) >= PPP_MAXIDLEFLAG) {
+    err = pppos_output_append(pppos, err,  nb, PPP_FLAG, 0, NULL);
+  }
+
+  /* Load output buffer. */
+  fcs_out = PPP_INITFCS;
+  s = (u8_t*)p->payload;
+  n = p->len;
+  while (n-- > 0) {
+    err = pppos_output_append(pppos, err,  nb, *s++, 1, &fcs_out);
+  }
+
+  err = pppos_output_last(pppos, err, nb, &fcs_out);
+  if (err == ERR_OK) {
+    PPPDEBUG(LOG_INFO, ("pppos_write[%d]: len=%d\n", ppp->netif->num, p->len));
+  } else {
+    PPPDEBUG(LOG_WARNING, ("pppos_write[%d]: output failed len=%d\n", ppp->netif->num, p->len));
+  }
+  pbuf_free(p);
+  return err;
+}
+
+/* Called by PPP core */
+static err_t
+pppos_netif_output(ppp_pcb *ppp, void *ctx, struct pbuf *pb, u16_t protocol)
+{
+  pppos_pcb *pppos = (pppos_pcb *)ctx;
+  struct pbuf *nb, *p;
+  u16_t fcs_out;
+  err_t err;
+  LWIP_UNUSED_ARG(ppp);
+
+  /* Grab an output buffer. Using PBUF_POOL here for tx is ok since the pbuf
+     gets freed by 'pppos_output_last' before this function returns and thus
+     cannot starve rx. */
+  nb = pbuf_alloc(PBUF_RAW, 0, PBUF_POOL);
+  if (nb == NULL) {
+    PPPDEBUG(LOG_WARNING, ("pppos_netif_output[%d]: alloc fail\n", ppp->netif->num));
+    LINK_STATS_INC(link.memerr);
+    LINK_STATS_INC(link.drop);
+    MIB2_STATS_NETIF_INC(ppp->netif, ifoutdiscards);
+    return ERR_MEM;
+  }
+
+  /* Set nb->tot_len to actual payload length */
+  nb->tot_len = pb->tot_len;
+
+  /* If the link has been idle, we'll send a fresh flag character to
+   * flush any noise. */
+  err = ERR_OK;
+  if ((sys_now() - pppos->last_xmit) >= PPP_MAXIDLEFLAG) {
+    err = pppos_output_append(pppos, err,  nb, PPP_FLAG, 0, NULL);
+  }
+
+  fcs_out = PPP_INITFCS;
+  if (!pppos->accomp) {
+    err = pppos_output_append(pppos, err,  nb, PPP_ALLSTATIONS, 1, &fcs_out);
+    err = pppos_output_append(pppos, err,  nb, PPP_UI, 1, &fcs_out);
+  }
+  if (!pppos->pcomp || protocol > 0xFF) {
+    err = pppos_output_append(pppos, err,  nb, (protocol >> 8) & 0xFF, 1, &fcs_out);
+  }
+  err = pppos_output_append(pppos, err,  nb, protocol & 0xFF, 1, &fcs_out);
+
+  /* Load packet. */
+  for(p = pb; p; p = p->next) {
+    u16_t n = p->len;
+    u8_t *s = (u8_t*)p->payload;
+
+    while (n-- > 0) {
+      err = pppos_output_append(pppos, err,  nb, *s++, 1, &fcs_out);
+    }
+  }
+
+  err = pppos_output_last(pppos, err, nb, &fcs_out);
+  if (err == ERR_OK) {
+    PPPDEBUG(LOG_INFO, ("pppos_netif_output[%d]: proto=0x%"X16_F", len = %d\n", ppp->netif->num, protocol, pb->tot_len));
+  } else {
+    PPPDEBUG(LOG_WARNING, ("pppos_netif_output[%d]: output failed proto=0x%"X16_F", len = %d\n", ppp->netif->num, protocol, pb->tot_len));
+  }
+  return err;
+}
+
+static void
+pppos_connect(ppp_pcb *ppp, void *ctx)
+{
+  pppos_pcb *pppos = (pppos_pcb *)ctx;
+  PPPOS_DECL_PROTECT(lev);
+
+#if PPP_INPROC_IRQ_SAFE
+  /* input pbuf left over from last session? */
+  pppos_input_free_current_packet(pppos);
+#endif /* PPP_INPROC_IRQ_SAFE */
+
+  /* reset PPPoS control block to its initial state */
+  memset(&pppos->last_xmit, 0, sizeof(pppos_pcb) - offsetof(pppos_pcb, last_xmit));
+
+  /*
+   * Default the in and out accm so that escape and flag characters
+   * are always escaped.
+   */
+  pppos->in_accm[15] = 0x60; /* no need to protect since RX is not running */
+  pppos->out_accm[15] = 0x60;
+  PPPOS_PROTECT(lev);
+  pppos->open = 1;
+  PPPOS_UNPROTECT(lev);
+
+  /*
+   * Start the connection and handle incoming events (packet or timeout).
+   */
+  PPPDEBUG(LOG_INFO, ("pppos_connect: unit %d: connecting\n", ppp->netif->num));
+  ppp_start(ppp); /* notify upper layers */
+}
+
+#if PPP_SERVER
+static void
+pppos_listen(ppp_pcb *ppp, void *ctx)
+{
+  pppos_pcb *pppos = (pppos_pcb *)ctx;
+  PPPOS_DECL_PROTECT(lev);
+
+#if PPP_INPROC_IRQ_SAFE
+  /* input pbuf left over from last session? */
+  pppos_input_free_current_packet(pppos);
+#endif /* PPP_INPROC_IRQ_SAFE */
+
+  /* reset PPPoS control block to its initial state */
+  memset(&pppos->last_xmit, 0, sizeof(pppos_pcb) - offsetof(pppos_pcb, last_xmit));
+
+  /*
+   * Default the in and out accm so that escape and flag characters
+   * are always escaped.
+   */
+  pppos->in_accm[15] = 0x60; /* no need to protect since RX is not running */
+  pppos->out_accm[15] = 0x60;
+  PPPOS_PROTECT(lev);
+  pppos->open = 1;
+  PPPOS_UNPROTECT(lev);
+
+  /*
+   * Wait for something to happen.
+   */
+  PPPDEBUG(LOG_INFO, ("pppos_listen: unit %d: listening\n", ppp->netif->num));
+  ppp_start(ppp); /* notify upper layers */
+}
+#endif /* PPP_SERVER */
+
+static void
+pppos_disconnect(ppp_pcb *ppp, void *ctx)
+{
+  pppos_pcb *pppos = (pppos_pcb *)ctx;
+  PPPOS_DECL_PROTECT(lev);
+
+  PPPOS_PROTECT(lev);
+  pppos->open = 0;
+  PPPOS_UNPROTECT(lev);
+
+  /* If PPP_INPROC_IRQ_SAFE is used we cannot call
+   * pppos_input_free_current_packet() here because
+   * rx IRQ might still call pppos_input().
+   */
+#if !PPP_INPROC_IRQ_SAFE
+  /* input pbuf left ? */
+  pppos_input_free_current_packet(pppos);
+#endif /* !PPP_INPROC_IRQ_SAFE */
+
+  ppp_link_end(ppp); /* notify upper layers */
+}
+
+static err_t
+pppos_destroy(ppp_pcb *ppp, void *ctx)
+{
+  pppos_pcb *pppos = (pppos_pcb *)ctx;
+  LWIP_UNUSED_ARG(ppp);
+
+#if PPP_INPROC_IRQ_SAFE
+  /* input pbuf left ? */
+  pppos_input_free_current_packet(pppos);
+#endif /* PPP_INPROC_IRQ_SAFE */
+
+  LWIP_MEMPOOL_FREE(PPPOS_PCB, pppos);
+  return ERR_OK;
+}
+
+#if !NO_SYS && !PPP_INPROC_IRQ_SAFE
+/** Pass received raw characters to PPPoS to be decoded through lwIP TCPIP thread.
+ *
+ * This is one of the only functions that may be called outside of the TCPIP thread!
+ *
+ * @param ppp PPP descriptor index, returned by pppos_create()
+ * @param s received data
+ * @param l length of received data
+ */
+err_t
+pppos_input_tcpip(ppp_pcb *ppp, u8_t *s, int l)
+{
+  struct pbuf *p;
+  err_t err;
+
+  p = pbuf_alloc(PBUF_RAW, l, PBUF_POOL);
+  if (!p) {
+    return ERR_MEM;
+  }
+  pbuf_take(p, s, l);
+
+  err = tcpip_inpkt(p, ppp_netif(ppp), pppos_input_sys);
+  if (err != ERR_OK) {
+     pbuf_free(p);
+  }
+  return err;
+}
+
+/* called from TCPIP thread */
+err_t pppos_input_sys(struct pbuf *p, struct netif *inp) {
+  ppp_pcb *ppp = (ppp_pcb*)inp->state;
+  struct pbuf *n;
+  LWIP_ASSERT_CORE_LOCKED();
+
+  for (n = p; n; n = n->next) {
+    pppos_input(ppp, (u8_t*)n->payload, n->len);
+  }
+  pbuf_free(p);
+  return ERR_OK;
+}
+#endif /* !NO_SYS && !PPP_INPROC_IRQ_SAFE */
+
+/** PPPoS input helper struct, must be packed since it is stored
+ * to pbuf->payload, which might be unaligned. */
+#if PPP_INPROC_IRQ_SAFE
+#ifdef PACK_STRUCT_USE_INCLUDES
+#  include "arch/bpstruct.h"
+#endif
+PACK_STRUCT_BEGIN
+struct pppos_input_header {
+  PACK_STRUCT_FIELD(ppp_pcb *ppp);
+} PACK_STRUCT_STRUCT;
+PACK_STRUCT_END
+#ifdef PACK_STRUCT_USE_INCLUDES
+#  include "arch/epstruct.h"
+#endif
+#endif /* PPP_INPROC_IRQ_SAFE */
+
+/** Pass received raw characters to PPPoS to be decoded.
+ *
+ * @param ppp PPP descriptor index, returned by pppos_create()
+ * @param s received data
+ * @param l length of received data
+ */
+void
+pppos_input(ppp_pcb *ppp, u8_t *s, int l)
+{
+  pppos_pcb *pppos = (pppos_pcb *)ppp->link_ctx_cb;
+  struct pbuf *next_pbuf;
+  u8_t cur_char;
+  u8_t escaped;
+  PPPOS_DECL_PROTECT(lev);
+#if !PPP_INPROC_IRQ_SAFE
+  LWIP_ASSERT_CORE_LOCKED();
+#endif
+
+  PPPDEBUG(LOG_DEBUG, ("pppos_input[%d]: got %d bytes\n", ppp->netif->num, l));
+  while (l-- > 0) {
+    cur_char = *s++;
+
+    PPPOS_PROTECT(lev);
+    /* ppp_input can disconnect the interface, we need to abort to prevent a memory
+     * leak if there are remaining bytes because pppos_connect and pppos_listen
+     * functions expect input buffer to be free. Furthermore there are no real
+     * reason to continue reading bytes if we are disconnected.
+     */
+    if (!pppos->open) {
+      PPPOS_UNPROTECT(lev);
+      return;
+    }
+    escaped = ESCAPE_P(pppos->in_accm, cur_char);
+    PPPOS_UNPROTECT(lev);
+    /* Handle special characters. */
+    if (escaped) {
+      /* Check for escape sequences. */
+      /* XXX Note that this does not handle an escaped 0x5d character which
+       * would appear as an escape character.  Since this is an ASCII ']'
+       * and there is no reason that I know of to escape it, I won't complicate
+       * the code to handle this case. GLL */
+      if (cur_char == PPP_ESCAPE) {
+        pppos->in_escaped = 1;
+      /* Check for the flag character. */
+      } else if (cur_char == PPP_FLAG) {
+        /* If this is just an extra flag character, ignore it. */
+        if (pppos->in_state <= PDADDRESS) {
+          /* ignore it */;
+        /* If we haven't received the packet header, drop what has come in. */
+        } else if (pppos->in_state < PDDATA) {
+          PPPDEBUG(LOG_WARNING,
+                   ("pppos_input[%d]: Dropping incomplete packet %d\n",
+                    ppp->netif->num, pppos->in_state));
+          LINK_STATS_INC(link.lenerr);
+          pppos_input_drop(pppos);
+        /* If the fcs is invalid, drop the packet. */
+        } else if (pppos->in_fcs != PPP_GOODFCS) {
+          PPPDEBUG(LOG_INFO,
+                   ("pppos_input[%d]: Dropping bad fcs 0x%"X16_F" proto=0x%"X16_F"\n",
+                    ppp->netif->num, pppos->in_fcs, pppos->in_protocol));
+          /* Note: If you get lots of these, check for UART frame errors or try different baud rate */
+          LINK_STATS_INC(link.chkerr);
+          pppos_input_drop(pppos);
+        /* Otherwise it's a good packet so pass it on. */
+        } else {
+          struct pbuf *inp;
+          /* Trim off the checksum. */
+          if(pppos->in_tail->len > 2) {
+            pppos->in_tail->len -= 2;
+
+            pppos->in_tail->tot_len = pppos->in_tail->len;
+            if (pppos->in_tail != pppos->in_head) {
+              pbuf_cat(pppos->in_head, pppos->in_tail);
+            }
+          } else {
+            pppos->in_tail->tot_len = pppos->in_tail->len;
+            if (pppos->in_tail != pppos->in_head) {
+              pbuf_cat(pppos->in_head, pppos->in_tail);
+            }
+
+            pbuf_realloc(pppos->in_head, pppos->in_head->tot_len - 2);
+          }
+
+          /* Dispatch the packet thereby consuming it. */
+          inp = pppos->in_head;
+          /* Packet consumed, release our references. */
+          pppos->in_head = NULL;
+          pppos->in_tail = NULL;
+#if IP_FORWARD || LWIP_IPV6_FORWARD
+          /* hide the room for Ethernet forwarding header */
+          pbuf_remove_header(inp, PBUF_LINK_ENCAPSULATION_HLEN + PBUF_LINK_HLEN);
+#endif /* IP_FORWARD || LWIP_IPV6_FORWARD */
+#if PPP_INPROC_IRQ_SAFE
+          if(tcpip_try_callback(pppos_input_callback, inp) != ERR_OK) {
+            PPPDEBUG(LOG_ERR, ("pppos_input[%d]: tcpip_callback() failed, dropping packet\n", ppp->netif->num));
+            pbuf_free(inp);
+            LINK_STATS_INC(link.drop);
+            MIB2_STATS_NETIF_INC(ppp->netif, ifindiscards);
+          }
+#else /* PPP_INPROC_IRQ_SAFE */
+          ppp_input(ppp, inp);
+#endif /* PPP_INPROC_IRQ_SAFE */
+        }
+
+        /* Prepare for a new packet. */
+        pppos->in_fcs = PPP_INITFCS;
+        pppos->in_state = PDADDRESS;
+        pppos->in_escaped = 0;
+      /* Other characters are usually control characters that may have
+       * been inserted by the physical layer so here we just drop them. */
+      } else {
+        PPPDEBUG(LOG_WARNING,
+                 ("pppos_input[%d]: Dropping ACCM char <%d>\n", ppp->netif->num, cur_char));
+      }
+    /* Process other characters. */
+    } else {
+      /* Unencode escaped characters. */
+      if (pppos->in_escaped) {
+        pppos->in_escaped = 0;
+        cur_char ^= PPP_TRANS;
+      }
+
+      /* Process character relative to current state. */
+      switch(pppos->in_state) {
+        case PDIDLE:                    /* Idle state - waiting. */
+          /* Drop the character if it's not 0xff
+           * we would have processed a flag character above. */
+          if (cur_char != PPP_ALLSTATIONS) {
+            break;
+          }
+          /* no break */
+          /* Fall through */
+
+        case PDSTART:                   /* Process start flag. */
+          /* Prepare for a new packet. */
+          pppos->in_fcs = PPP_INITFCS;
+          /* no break */
+          /* Fall through */
+
+        case PDADDRESS:                 /* Process address field. */
+          if (cur_char == PPP_ALLSTATIONS) {
+            pppos->in_state = PDCONTROL;
+            break;
+          }
+          /* no break */
+
+          /* Else assume compressed address and control fields so
+           * fall through to get the protocol... */
+          /* Fall through */
+        case PDCONTROL:                 /* Process control field. */
+          /* If we don't get a valid control code, restart. */
+          if (cur_char == PPP_UI) {
+            pppos->in_state = PDPROTOCOL1;
+            break;
+          }
+          /* no break */
+
+#if 0
+          else {
+            PPPDEBUG(LOG_WARNING,
+                     ("pppos_input[%d]: Invalid control <%d>\n", ppp->netif->num, cur_char));
+            pppos->in_state = PDSTART;
+          }
+#endif
+          /* Fall through */
+
+      case PDPROTOCOL1:               /* Process protocol field 1. */
+          /* If the lower bit is set, this is the end of the protocol
+           * field. */
+          if (cur_char & 1) {
+            pppos->in_protocol = cur_char;
+            pppos->in_state = PDDATA;
+          } else {
+            pppos->in_protocol = (u16_t)cur_char << 8;
+            pppos->in_state = PDPROTOCOL2;
+          }
+          break;
+        case PDPROTOCOL2:               /* Process protocol field 2. */
+          pppos->in_protocol |= cur_char;
+          pppos->in_state = PDDATA;
+          break;
+        case PDDATA:                    /* Process data byte. */
+          /* Make space to receive processed data. */
+          if (pppos->in_tail == NULL || pppos->in_tail->len == PBUF_POOL_BUFSIZE) {
+            u16_t pbuf_alloc_len;
+            if (pppos->in_tail != NULL) {
+              pppos->in_tail->tot_len = pppos->in_tail->len;
+              if (pppos->in_tail != pppos->in_head) {
+                pbuf_cat(pppos->in_head, pppos->in_tail);
+                /* give up the in_tail reference now */
+                pppos->in_tail = NULL;
+              }
+            }
+            /* If we haven't started a packet, we need a packet header. */
+            pbuf_alloc_len = 0;
+#if IP_FORWARD || LWIP_IPV6_FORWARD
+            /* If IP forwarding is enabled we are reserving PBUF_LINK_ENCAPSULATION_HLEN
+             * + PBUF_LINK_HLEN bytes so the packet is being allocated with enough header
+             * space to be forwarded (to Ethernet for example).
+             */
+            if (pppos->in_head == NULL) {
+              pbuf_alloc_len = PBUF_LINK_ENCAPSULATION_HLEN + PBUF_LINK_HLEN;
+            }
+#endif /* IP_FORWARD || LWIP_IPV6_FORWARD */
+            next_pbuf = pbuf_alloc(PBUF_RAW, pbuf_alloc_len, PBUF_POOL);
+            if (next_pbuf == NULL) {
+              /* No free buffers.  Drop the input packet and let the
+               * higher layers deal with it.  Continue processing
+               * the received pbuf chain in case a new packet starts. */
+              PPPDEBUG(LOG_ERR, ("pppos_input[%d]: NO FREE PBUFS!\n", ppp->netif->num));
+              LINK_STATS_INC(link.memerr);
+              pppos_input_drop(pppos);
+              pppos->in_state = PDSTART;  /* Wait for flag sequence. */
+              break;
+            }
+            if (pppos->in_head == NULL) {
+              u8_t *payload = ((u8_t*)next_pbuf->payload) + pbuf_alloc_len;
+#if PPP_INPROC_IRQ_SAFE
+              ((struct pppos_input_header*)payload)->ppp = ppp;
+              payload += sizeof(struct pppos_input_header);
+              next_pbuf->len += sizeof(struct pppos_input_header);
+#endif /* PPP_INPROC_IRQ_SAFE */
+              next_pbuf->len += sizeof(pppos->in_protocol);
+              *(payload++) = pppos->in_protocol >> 8;
+              *(payload) = pppos->in_protocol & 0xFF;
+              pppos->in_head = next_pbuf;
+            }
+            pppos->in_tail = next_pbuf;
+          }
+          /* Load character into buffer. */
+          ((u8_t*)pppos->in_tail->payload)[pppos->in_tail->len++] = cur_char;
+          break;
+        default:
+          break;
+      }
+
+      /* update the frame check sequence number. */
+      pppos->in_fcs = PPP_FCS(pppos->in_fcs, cur_char);
+    }
+  } /* while (l-- > 0), all bytes processed */
+}
+
+#if PPP_INPROC_IRQ_SAFE
+/* PPPoS input callback using one input pointer
+ */
+static void pppos_input_callback(void *arg) {
+  struct pbuf *pb = (struct pbuf*)arg;
+  ppp_pcb *ppp;
+
+  ppp = ((struct pppos_input_header*)pb->payload)->ppp;
+  if(pbuf_remove_header(pb, sizeof(struct pppos_input_header))) {
+    LWIP_ASSERT("pbuf_remove_header failed\n", 0);
+    goto drop;
+  }
+
+  /* Dispatch the packet thereby consuming it. */
+  ppp_input(ppp, pb);
+  return;
+
+drop:
+  LINK_STATS_INC(link.drop);
+  MIB2_STATS_NETIF_INC(ppp->netif, ifindiscards);
+  pbuf_free(pb);
+}
+#endif /* PPP_INPROC_IRQ_SAFE */
+
+static void
+pppos_send_config(ppp_pcb *ppp, void *ctx, u32_t accm, int pcomp, int accomp)
+{
+  int i;
+  pppos_pcb *pppos = (pppos_pcb *)ctx;
+  LWIP_UNUSED_ARG(ppp);
+
+  pppos->pcomp = pcomp;
+  pppos->accomp = accomp;
+
+  /* Load the ACCM bits for the 32 control codes. */
+  for (i = 0; i < 32/8; i++) {
+    pppos->out_accm[i] = (u8_t)((accm >> (8 * i)) & 0xFF);
+  }
+
+  PPPDEBUG(LOG_INFO, ("pppos_send_config[%d]: out_accm=%X %X %X %X\n",
+            pppos->ppp->netif->num,
+            pppos->out_accm[0], pppos->out_accm[1], pppos->out_accm[2], pppos->out_accm[3]));
+}
+
+static void
+pppos_recv_config(ppp_pcb *ppp, void *ctx, u32_t accm, int pcomp, int accomp)
+{
+  int i;
+  pppos_pcb *pppos = (pppos_pcb *)ctx;
+  PPPOS_DECL_PROTECT(lev);
+  LWIP_UNUSED_ARG(ppp);
+  LWIP_UNUSED_ARG(pcomp);
+  LWIP_UNUSED_ARG(accomp);
+
+  /* Load the ACCM bits for the 32 control codes. */
+  PPPOS_PROTECT(lev);
+  for (i = 0; i < 32 / 8; i++) {
+    pppos->in_accm[i] = (u8_t)(accm >> (i * 8));
+  }
+  PPPOS_UNPROTECT(lev);
+
+  PPPDEBUG(LOG_INFO, ("pppos_recv_config[%d]: in_accm=%X %X %X %X\n",
+            pppos->ppp->netif->num,
+            pppos->in_accm[0], pppos->in_accm[1], pppos->in_accm[2], pppos->in_accm[3]));
+}
+
+/*
+ * Drop the input packet.
+ */
+static void
+pppos_input_free_current_packet(pppos_pcb *pppos)
+{
+  if (pppos->in_head != NULL) {
+    if (pppos->in_tail && (pppos->in_tail != pppos->in_head)) {
+      pbuf_free(pppos->in_tail);
+    }
+    pbuf_free(pppos->in_head);
+    pppos->in_head = NULL;
+  }
+  pppos->in_tail = NULL;
+}
+
+/*
+ * Drop the input packet and increase error counters.
+ */
+static void
+pppos_input_drop(pppos_pcb *pppos)
+{
+  if (pppos->in_head != NULL) {
+#if 0
+    PPPDEBUG(LOG_INFO, ("pppos_input_drop: %d:%.*H\n", pppos->in_head->len, min(60, pppos->in_head->len * 2), pppos->in_head->payload));
+#endif
+    PPPDEBUG(LOG_INFO, ("pppos_input_drop: pbuf len=%d, addr %p\n", pppos->in_head->len, (void*)pppos->in_head));
+  }
+  pppos_input_free_current_packet(pppos);
+#if VJ_SUPPORT
+  vj_uncompress_err(&pppos->ppp->vj_comp);
+#endif /* VJ_SUPPORT */
+
+  LINK_STATS_INC(link.drop);
+  MIB2_STATS_NETIF_INC(pppos->ppp->netif, ifindiscards);
+}
+
+/*
+ * pppos_output_append - append given character to end of given pbuf.
+ * If out_accm is not 0 and the character needs to be escaped, do so.
+ * If pbuf is full, send the pbuf and reuse it.
+ * Return the current pbuf.
+ */
+static err_t
+pppos_output_append(pppos_pcb *pppos, err_t err, struct pbuf *nb, u8_t c, u8_t accm, u16_t *fcs)
+{
+  if (err != ERR_OK) {
+    return err;
+  }
+
+  /* Make sure there is room for the character and an escape code.
+   * Sure we don't quite fill the buffer if the character doesn't
+   * get escaped but is one character worth complicating this? */
+  if ((PBUF_POOL_BUFSIZE - nb->len) < 2) {
+    u32_t l = pppos->output_cb(pppos->ppp, (u8_t*)nb->payload, nb->len, pppos->ppp->ctx_cb);
+    if (l != nb->len) {
+      return ERR_IF;
+    }
+    nb->len = 0;
+  }
+
+  /* Update FCS before checking for special characters. */
+  if (fcs) {
+    *fcs = PPP_FCS(*fcs, c);
+  }
+
+  /* Copy to output buffer escaping special characters. */
+  if (accm && ESCAPE_P(pppos->out_accm, c)) {
+    *((u8_t*)nb->payload + nb->len++) = PPP_ESCAPE;
+    *((u8_t*)nb->payload + nb->len++) = c ^ PPP_TRANS;
+  } else {
+    *((u8_t*)nb->payload + nb->len++) = c;
+  }
+
+  return ERR_OK;
+}
+
+static err_t
+pppos_output_last(pppos_pcb *pppos, err_t err, struct pbuf *nb, u16_t *fcs)
+{
+  ppp_pcb *ppp = pppos->ppp;
+
+  /* Add FCS and trailing flag. */
+  err = pppos_output_append(pppos, err,  nb, ~(*fcs) & 0xFF, 1, NULL);
+  err = pppos_output_append(pppos, err,  nb, (~(*fcs) >> 8) & 0xFF, 1, NULL);
+  err = pppos_output_append(pppos, err,  nb, PPP_FLAG, 0, NULL);
+
+  if (err != ERR_OK) {
+    goto failed;
+  }
+
+  /* Send remaining buffer if not empty */
+  if (nb->len > 0) {
+    u32_t l = pppos->output_cb(ppp, (u8_t*)nb->payload, nb->len, ppp->ctx_cb);
+    if (l != nb->len) {
+      err = ERR_IF;
+      goto failed;
+    }
+  }
+
+  pppos->last_xmit = sys_now();
+  MIB2_STATS_NETIF_ADD(ppp->netif, ifoutoctets, nb->tot_len);
+  MIB2_STATS_NETIF_INC(ppp->netif, ifoutucastpkts);
+  LINK_STATS_INC(link.xmit);
+  pbuf_free(nb);
+  return ERR_OK;
+
+failed:
+  pppos->last_xmit = 0; /* prepend PPP_FLAG to next packet */
+  LINK_STATS_INC(link.err);
+  LINK_STATS_INC(link.drop);
+  MIB2_STATS_NETIF_INC(ppp->netif, ifoutdiscards);
+  pbuf_free(nb);
+  return err;
+}
+
+#endif /* PPP_SUPPORT && PPPOS_SUPPORT */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/netif/ppp/upap.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/netif/ppp/upap.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/netif/ppp/upap.c	(revision 457)
@@ -0,0 +1,677 @@
+/*
+ * upap.c - User/Password Authentication Protocol.
+ *
+ * Copyright (c) 1984-2000 Carnegie Mellon University. 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. The name "Carnegie Mellon University" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For permission or any legal
+ *    details, please contact
+ *      Office of Technology Transfer
+ *      Carnegie Mellon University
+ *      5000 Forbes Avenue
+ *      Pittsburgh, PA  15213-3890
+ *      (412) 268-4387, fax: (412) 268-7395
+ *      tech-transfer@andrew.cmu.edu
+ *
+ * 4. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by Computing Services
+ *     at Carnegie Mellon University (http://www.cmu.edu/computing/)."
+ *
+ * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO
+ * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE
+ * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
+ * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
+ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include "netif/ppp/ppp_opts.h"
+#if PPP_SUPPORT && PAP_SUPPORT  /* don't build if not configured for use in lwipopts.h */
+
+/*
+ * @todo:
+ */
+
+#if 0 /* UNUSED */
+#include <stdio.h>
+#include <string.h>
+#endif /* UNUSED */
+
+#include "netif/ppp/ppp_impl.h"
+
+#include "netif/ppp/upap.h"
+
+#if PPP_OPTIONS
+/*
+ * Command-line options.
+ */
+static option_t pap_option_list[] = {
+    { "hide-password", o_bool, &hide_password,
+      "Don't output passwords to log", OPT_PRIO | 1 },
+    { "show-password", o_bool, &hide_password,
+      "Show password string in debug log messages", OPT_PRIOSUB | 0 },
+
+    { "pap-restart", o_int, &upap[0].us_timeouttime,
+      "Set retransmit timeout for PAP", OPT_PRIO },
+    { "pap-max-authreq", o_int, &upap[0].us_maxtransmits,
+      "Set max number of transmissions for auth-reqs", OPT_PRIO },
+    { "pap-timeout", o_int, &upap[0].us_reqtimeout,
+      "Set time limit for peer PAP authentication", OPT_PRIO },
+
+    { NULL }
+};
+#endif /* PPP_OPTIONS */
+
+/*
+ * Protocol entry points.
+ */
+static void upap_init(ppp_pcb *pcb);
+static void upap_lowerup(ppp_pcb *pcb);
+static void upap_lowerdown(ppp_pcb *pcb);
+static void upap_input(ppp_pcb *pcb, u_char *inpacket, int l);
+static void upap_protrej(ppp_pcb *pcb);
+#if PRINTPKT_SUPPORT
+static int upap_printpkt(const u_char *p, int plen, void (*printer) (void *, const char *, ...), void *arg);
+#endif /* PRINTPKT_SUPPORT */
+
+const struct protent pap_protent = {
+    PPP_PAP,
+    upap_init,
+    upap_input,
+    upap_protrej,
+    upap_lowerup,
+    upap_lowerdown,
+    NULL,
+    NULL,
+#if PRINTPKT_SUPPORT
+    upap_printpkt,
+#endif /* PRINTPKT_SUPPORT */
+#if PPP_DATAINPUT
+    NULL,
+#endif /* PPP_DATAINPUT */
+#if PRINTPKT_SUPPORT
+    "PAP",
+    NULL,
+#endif /* PRINTPKT_SUPPORT */
+#if PPP_OPTIONS
+    pap_option_list,
+    NULL,
+#endif /* PPP_OPTIONS */
+#if DEMAND_SUPPORT
+    NULL,
+    NULL
+#endif /* DEMAND_SUPPORT */
+};
+
+static void upap_timeout(void *arg);
+#if PPP_SERVER
+static void upap_reqtimeout(void *arg);
+static void upap_rauthreq(ppp_pcb *pcb, u_char *inp, int id, int len);
+#endif /* PPP_SERVER */
+static void upap_rauthack(ppp_pcb *pcb, u_char *inp, int id, int len);
+static void upap_rauthnak(ppp_pcb *pcb, u_char *inp, int id, int len);
+static void upap_sauthreq(ppp_pcb *pcb);
+#if PPP_SERVER
+static void upap_sresp(ppp_pcb *pcb, u_char code, u_char id, const char *msg, int msglen);
+#endif /* PPP_SERVER */
+
+
+/*
+ * upap_init - Initialize a UPAP unit.
+ */
+static void upap_init(ppp_pcb *pcb) {
+    pcb->upap.us_user = NULL;
+    pcb->upap.us_userlen = 0;
+    pcb->upap.us_passwd = NULL;
+    pcb->upap.us_passwdlen = 0;
+    pcb->upap.us_clientstate = UPAPCS_INITIAL;
+#if PPP_SERVER
+    pcb->upap.us_serverstate = UPAPSS_INITIAL;
+#endif /* PPP_SERVER */
+    pcb->upap.us_id = 0;
+}
+
+
+/*
+ * upap_authwithpeer - Authenticate us with our peer (start client).
+ *
+ * Set new state and send authenticate's.
+ */
+void upap_authwithpeer(ppp_pcb *pcb, const char *user, const char *password) {
+
+    if(!user || !password)
+        return;
+
+    /* Save the username and password we're given */
+    pcb->upap.us_user = user;
+    pcb->upap.us_userlen = (u8_t)LWIP_MIN(strlen(user), 0xff);
+    pcb->upap.us_passwd = password;
+    pcb->upap.us_passwdlen = (u8_t)LWIP_MIN(strlen(password), 0xff);
+    pcb->upap.us_transmits = 0;
+
+    /* Lower layer up yet? */
+    if (pcb->upap.us_clientstate == UPAPCS_INITIAL ||
+	pcb->upap.us_clientstate == UPAPCS_PENDING) {
+	pcb->upap.us_clientstate = UPAPCS_PENDING;
+	return;
+    }
+
+    upap_sauthreq(pcb);		/* Start protocol */
+}
+
+#if PPP_SERVER
+/*
+ * upap_authpeer - Authenticate our peer (start server).
+ *
+ * Set new state.
+ */
+void upap_authpeer(ppp_pcb *pcb) {
+
+    /* Lower layer up yet? */
+    if (pcb->upap.us_serverstate == UPAPSS_INITIAL ||
+	pcb->upap.us_serverstate == UPAPSS_PENDING) {
+	pcb->upap.us_serverstate = UPAPSS_PENDING;
+	return;
+    }
+
+    pcb->upap.us_serverstate = UPAPSS_LISTEN;
+    if (pcb->settings.pap_req_timeout > 0)
+	TIMEOUT(upap_reqtimeout, pcb, pcb->settings.pap_req_timeout);
+}
+#endif /* PPP_SERVER */
+
+/*
+ * upap_timeout - Retransmission timer for sending auth-reqs expired.
+ */
+static void upap_timeout(void *arg) {
+    ppp_pcb *pcb = (ppp_pcb*)arg;
+
+    if (pcb->upap.us_clientstate != UPAPCS_AUTHREQ)
+	return;
+
+    if (pcb->upap.us_transmits >= pcb->settings.pap_max_transmits) {
+	/* give up in disgust */
+	ppp_error("No response to PAP authenticate-requests");
+	pcb->upap.us_clientstate = UPAPCS_BADAUTH;
+	auth_withpeer_fail(pcb, PPP_PAP);
+	return;
+    }
+
+    upap_sauthreq(pcb);		/* Send Authenticate-Request */
+}
+
+
+#if PPP_SERVER
+/*
+ * upap_reqtimeout - Give up waiting for the peer to send an auth-req.
+ */
+static void upap_reqtimeout(void *arg) {
+    ppp_pcb *pcb = (ppp_pcb*)arg;
+
+    if (pcb->upap.us_serverstate != UPAPSS_LISTEN)
+	return;			/* huh?? */
+
+    auth_peer_fail(pcb, PPP_PAP);
+    pcb->upap.us_serverstate = UPAPSS_BADAUTH;
+}
+#endif /* PPP_SERVER */
+
+
+/*
+ * upap_lowerup - The lower layer is up.
+ *
+ * Start authenticating if pending.
+ */
+static void upap_lowerup(ppp_pcb *pcb) {
+
+    if (pcb->upap.us_clientstate == UPAPCS_INITIAL)
+	pcb->upap.us_clientstate = UPAPCS_CLOSED;
+    else if (pcb->upap.us_clientstate == UPAPCS_PENDING) {
+	upap_sauthreq(pcb);	/* send an auth-request */
+    }
+
+#if PPP_SERVER
+    if (pcb->upap.us_serverstate == UPAPSS_INITIAL)
+	pcb->upap.us_serverstate = UPAPSS_CLOSED;
+    else if (pcb->upap.us_serverstate == UPAPSS_PENDING) {
+	pcb->upap.us_serverstate = UPAPSS_LISTEN;
+	if (pcb->settings.pap_req_timeout > 0)
+	    TIMEOUT(upap_reqtimeout, pcb, pcb->settings.pap_req_timeout);
+    }
+#endif /* PPP_SERVER */
+}
+
+
+/*
+ * upap_lowerdown - The lower layer is down.
+ *
+ * Cancel all timeouts.
+ */
+static void upap_lowerdown(ppp_pcb *pcb) {
+
+    if (pcb->upap.us_clientstate == UPAPCS_AUTHREQ)	/* Timeout pending? */
+	UNTIMEOUT(upap_timeout, pcb);		/* Cancel timeout */
+#if PPP_SERVER
+    if (pcb->upap.us_serverstate == UPAPSS_LISTEN && pcb->settings.pap_req_timeout > 0)
+	UNTIMEOUT(upap_reqtimeout, pcb);
+#endif /* PPP_SERVER */
+
+    pcb->upap.us_clientstate = UPAPCS_INITIAL;
+#if PPP_SERVER
+    pcb->upap.us_serverstate = UPAPSS_INITIAL;
+#endif /* PPP_SERVER */
+}
+
+
+/*
+ * upap_protrej - Peer doesn't speak this protocol.
+ *
+ * This shouldn't happen.  In any case, pretend lower layer went down.
+ */
+static void upap_protrej(ppp_pcb *pcb) {
+
+    if (pcb->upap.us_clientstate == UPAPCS_AUTHREQ) {
+	ppp_error("PAP authentication failed due to protocol-reject");
+	auth_withpeer_fail(pcb, PPP_PAP);
+    }
+#if PPP_SERVER
+    if (pcb->upap.us_serverstate == UPAPSS_LISTEN) {
+	ppp_error("PAP authentication of peer failed (protocol-reject)");
+	auth_peer_fail(pcb, PPP_PAP);
+    }
+#endif /* PPP_SERVER */
+    upap_lowerdown(pcb);
+}
+
+
+/*
+ * upap_input - Input UPAP packet.
+ */
+static void upap_input(ppp_pcb *pcb, u_char *inpacket, int l) {
+    u_char *inp;
+    u_char code, id;
+    int len;
+
+    /*
+     * Parse header (code, id and length).
+     * If packet too short, drop it.
+     */
+    inp = inpacket;
+    if (l < UPAP_HEADERLEN) {
+	UPAPDEBUG(("pap_input: rcvd short header."));
+	return;
+    }
+    GETCHAR(code, inp);
+    GETCHAR(id, inp);
+    GETSHORT(len, inp);
+    if (len < UPAP_HEADERLEN) {
+	UPAPDEBUG(("pap_input: rcvd illegal length."));
+	return;
+    }
+    if (len > l) {
+	UPAPDEBUG(("pap_input: rcvd short packet."));
+	return;
+    }
+    len -= UPAP_HEADERLEN;
+
+    /*
+     * Action depends on code.
+     */
+    switch (code) {
+    case UPAP_AUTHREQ:
+#if PPP_SERVER
+	upap_rauthreq(pcb, inp, id, len);
+#endif /* PPP_SERVER */
+	break;
+
+    case UPAP_AUTHACK:
+	upap_rauthack(pcb, inp, id, len);
+	break;
+
+    case UPAP_AUTHNAK:
+	upap_rauthnak(pcb, inp, id, len);
+	break;
+
+    default:				/* XXX Need code reject */
+	break;
+    }
+}
+
+#if PPP_SERVER
+/*
+ * upap_rauth - Receive Authenticate.
+ */
+static void upap_rauthreq(ppp_pcb *pcb, u_char *inp, int id, int len) {
+    u_char ruserlen, rpasswdlen;
+    char *ruser;
+    char *rpasswd;
+    char rhostname[256];
+    int retcode;
+    const char *msg;
+    int msglen;
+
+    if (pcb->upap.us_serverstate < UPAPSS_LISTEN)
+	return;
+
+    /*
+     * If we receive a duplicate authenticate-request, we are
+     * supposed to return the same status as for the first request.
+     */
+    if (pcb->upap.us_serverstate == UPAPSS_OPEN) {
+	upap_sresp(pcb, UPAP_AUTHACK, id, "", 0);	/* return auth-ack */
+	return;
+    }
+    if (pcb->upap.us_serverstate == UPAPSS_BADAUTH) {
+	upap_sresp(pcb, UPAP_AUTHNAK, id, "", 0);	/* return auth-nak */
+	return;
+    }
+
+    /*
+     * Parse user/passwd.
+     */
+    if (len < 1) {
+	UPAPDEBUG(("pap_rauth: rcvd short packet."));
+	return;
+    }
+    GETCHAR(ruserlen, inp);
+    len -= sizeof (u_char) + ruserlen + sizeof (u_char);
+    if (len < 0) {
+	UPAPDEBUG(("pap_rauth: rcvd short packet."));
+	return;
+    }
+    ruser = (char *) inp;
+    INCPTR(ruserlen, inp);
+    GETCHAR(rpasswdlen, inp);
+    if (len < rpasswdlen) {
+	UPAPDEBUG(("pap_rauth: rcvd short packet."));
+	return;
+    }
+
+    rpasswd = (char *) inp;
+
+    /*
+     * Check the username and password given.
+     */
+    retcode = UPAP_AUTHNAK;
+    if (auth_check_passwd(pcb, ruser, ruserlen, rpasswd, rpasswdlen, &msg, &msglen)) {
+      retcode = UPAP_AUTHACK;
+    }
+    BZERO(rpasswd, rpasswdlen);
+
+#if 0 /* UNUSED */
+    /*
+     * Check remote number authorization.  A plugin may have filled in
+     * the remote number or added an allowed number, and rather than
+     * return an authenticate failure, is leaving it for us to verify.
+     */
+    if (retcode == UPAP_AUTHACK) {
+	if (!auth_number()) {
+	    /* We do not want to leak info about the pap result. */
+	    retcode = UPAP_AUTHNAK; /* XXX exit value will be "wrong" */
+	    warn("calling number %q is not authorized", remote_number);
+	}
+    }
+
+    msglen = strlen(msg);
+    if (msglen > 255)
+	msglen = 255;
+#endif /* UNUSED */
+
+    upap_sresp(pcb, retcode, id, msg, msglen);
+
+    /* Null terminate and clean remote name. */
+    ppp_slprintf(rhostname, sizeof(rhostname), "%.*v", ruserlen, ruser);
+
+    if (retcode == UPAP_AUTHACK) {
+	pcb->upap.us_serverstate = UPAPSS_OPEN;
+	ppp_notice("PAP peer authentication succeeded for %q", rhostname);
+	auth_peer_success(pcb, PPP_PAP, 0, ruser, ruserlen);
+    } else {
+	pcb->upap.us_serverstate = UPAPSS_BADAUTH;
+	ppp_warn("PAP peer authentication failed for %q", rhostname);
+	auth_peer_fail(pcb, PPP_PAP);
+    }
+
+    if (pcb->settings.pap_req_timeout > 0)
+	UNTIMEOUT(upap_reqtimeout, pcb);
+}
+#endif /* PPP_SERVER */
+
+/*
+ * upap_rauthack - Receive Authenticate-Ack.
+ */
+static void upap_rauthack(ppp_pcb *pcb, u_char *inp, int id, int len) {
+    u_char msglen;
+    char *msg;
+    LWIP_UNUSED_ARG(id);
+
+    if (pcb->upap.us_clientstate != UPAPCS_AUTHREQ) /* XXX */
+	return;
+
+    /*
+     * Parse message.
+     */
+    if (len < 1) {
+	UPAPDEBUG(("pap_rauthack: ignoring missing msg-length."));
+    } else {
+	GETCHAR(msglen, inp);
+	if (msglen > 0) {
+	    len -= sizeof (u_char);
+	    if (len < msglen) {
+		UPAPDEBUG(("pap_rauthack: rcvd short packet."));
+		return;
+	    }
+	    msg = (char *) inp;
+	    PRINTMSG(msg, msglen);
+	}
+    }
+
+    pcb->upap.us_clientstate = UPAPCS_OPEN;
+
+    auth_withpeer_success(pcb, PPP_PAP, 0);
+}
+
+
+/*
+ * upap_rauthnak - Receive Authenticate-Nak.
+ */
+static void upap_rauthnak(ppp_pcb *pcb, u_char *inp, int id, int len) {
+    u_char msglen;
+    char *msg;
+    LWIP_UNUSED_ARG(id);
+
+    if (pcb->upap.us_clientstate != UPAPCS_AUTHREQ) /* XXX */
+	return;
+
+    /*
+     * Parse message.
+     */
+    if (len < 1) {
+	UPAPDEBUG(("pap_rauthnak: ignoring missing msg-length."));
+    } else {
+	GETCHAR(msglen, inp);
+	if (msglen > 0) {
+	    len -= sizeof (u_char);
+	    if (len < msglen) {
+		UPAPDEBUG(("pap_rauthnak: rcvd short packet."));
+		return;
+	    }
+	    msg = (char *) inp;
+	    PRINTMSG(msg, msglen);
+	}
+    }
+
+    pcb->upap.us_clientstate = UPAPCS_BADAUTH;
+
+    ppp_error("PAP authentication failed");
+    auth_withpeer_fail(pcb, PPP_PAP);
+}
+
+
+/*
+ * upap_sauthreq - Send an Authenticate-Request.
+ */
+static void upap_sauthreq(ppp_pcb *pcb) {
+    struct pbuf *p;
+    u_char *outp;
+    int outlen;
+
+    outlen = UPAP_HEADERLEN + 2 * sizeof (u_char) +
+	pcb->upap.us_userlen + pcb->upap.us_passwdlen;
+    p = pbuf_alloc(PBUF_RAW, (u16_t)(PPP_HDRLEN +outlen), PPP_CTRL_PBUF_TYPE);
+    if(NULL == p)
+        return;
+    if(p->tot_len != p->len) {
+        pbuf_free(p);
+        return;
+    }
+
+    outp = (u_char*)p->payload;
+    MAKEHEADER(outp, PPP_PAP);
+
+    PUTCHAR(UPAP_AUTHREQ, outp);
+    PUTCHAR(++pcb->upap.us_id, outp);
+    PUTSHORT(outlen, outp);
+    PUTCHAR(pcb->upap.us_userlen, outp);
+    MEMCPY(outp, pcb->upap.us_user, pcb->upap.us_userlen);
+    INCPTR(pcb->upap.us_userlen, outp);
+    PUTCHAR(pcb->upap.us_passwdlen, outp);
+    MEMCPY(outp, pcb->upap.us_passwd, pcb->upap.us_passwdlen);
+
+    ppp_write(pcb, p);
+
+    TIMEOUT(upap_timeout, pcb, pcb->settings.pap_timeout_time);
+    ++pcb->upap.us_transmits;
+    pcb->upap.us_clientstate = UPAPCS_AUTHREQ;
+}
+
+#if PPP_SERVER
+/*
+ * upap_sresp - Send a response (ack or nak).
+ */
+static void upap_sresp(ppp_pcb *pcb, u_char code, u_char id, const char *msg, int msglen) {
+    struct pbuf *p;
+    u_char *outp;
+    int outlen;
+
+    outlen = UPAP_HEADERLEN + sizeof (u_char) + msglen;
+    p = pbuf_alloc(PBUF_RAW, (u16_t)(PPP_HDRLEN +outlen), PPP_CTRL_PBUF_TYPE);
+    if(NULL == p)
+        return;
+    if(p->tot_len != p->len) {
+        pbuf_free(p);
+        return;
+    }
+
+    outp = (u_char*)p->payload;
+    MAKEHEADER(outp, PPP_PAP);
+
+    PUTCHAR(code, outp);
+    PUTCHAR(id, outp);
+    PUTSHORT(outlen, outp);
+    PUTCHAR(msglen, outp);
+    MEMCPY(outp, msg, msglen);
+
+    ppp_write(pcb, p);
+}
+#endif /* PPP_SERVER */
+
+#if PRINTPKT_SUPPORT
+/*
+ * upap_printpkt - print the contents of a PAP packet.
+ */
+static const char* const upap_codenames[] = {
+    "AuthReq", "AuthAck", "AuthNak"
+};
+
+static int upap_printpkt(const u_char *p, int plen, void (*printer) (void *, const char *, ...), void *arg) {
+    int code, id, len;
+    int mlen, ulen, wlen;
+    const u_char *user, *pwd, *msg;
+    const u_char *pstart;
+
+    if (plen < UPAP_HEADERLEN)
+	return 0;
+    pstart = p;
+    GETCHAR(code, p);
+    GETCHAR(id, p);
+    GETSHORT(len, p);
+    if (len < UPAP_HEADERLEN || len > plen)
+	return 0;
+
+    if (code >= 1 && code <= (int)LWIP_ARRAYSIZE(upap_codenames))
+	printer(arg, " %s", upap_codenames[code-1]);
+    else
+	printer(arg, " code=0x%x", code);
+    printer(arg, " id=0x%x", id);
+    len -= UPAP_HEADERLEN;
+    switch (code) {
+    case UPAP_AUTHREQ:
+	if (len < 1)
+	    break;
+	ulen = p[0];
+	if (len < ulen + 2)
+	    break;
+	wlen = p[ulen + 1];
+	if (len < ulen + wlen + 2)
+	    break;
+	user = (const u_char *) (p + 1);
+	pwd = (const u_char *) (p + ulen + 2);
+	p += ulen + wlen + 2;
+	len -= ulen + wlen + 2;
+	printer(arg, " user=");
+	ppp_print_string(user, ulen, printer, arg);
+	printer(arg, " password=");
+/* FIXME: require ppp_pcb struct as printpkt() argument */
+#if 0
+	if (!pcb->settings.hide_password)
+#endif
+	    ppp_print_string(pwd, wlen, printer, arg);
+#if 0
+	else
+	    printer(arg, "<hidden>");
+#endif
+	break;
+    case UPAP_AUTHACK:
+    case UPAP_AUTHNAK:
+	if (len < 1)
+	    break;
+	mlen = p[0];
+	if (len < mlen + 1)
+	    break;
+	msg = (const u_char *) (p + 1);
+	p += mlen + 1;
+	len -= mlen + 1;
+	printer(arg, " ");
+	ppp_print_string(msg, mlen, printer, arg);
+	break;
+    default:
+	break;
+    }
+
+    /* print the rest of the bytes in the packet */
+    for (; len > 0; --len) {
+	GETCHAR(code, p);
+	printer(arg, " %.2x", code);
+    }
+
+    return p - pstart;
+}
+#endif /* PRINTPKT_SUPPORT */
+
+#endif /* PPP_SUPPORT && PAP_SUPPORT */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/netif/ppp/utils.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/netif/ppp/utils.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/netif/ppp/utils.c	(revision 457)
@@ -0,0 +1,957 @@
+/*
+ * utils.c - various utility functions used in pppd.
+ *
+ * Copyright (c) 1999-2002 Paul Mackerras. 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. The name(s) of the authors of this software must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission.
+ *
+ * 3. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by Paul Mackerras
+ *     <paulus@samba.org>".
+ *
+ * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO
+ * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
+ * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
+ * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
+ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include "netif/ppp/ppp_opts.h"
+#if PPP_SUPPORT /* don't build if not configured for use in lwipopts.h */
+
+#if 0 /* UNUSED */
+#include <stdio.h>
+#include <ctype.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <signal.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <syslog.h>
+#include <netdb.h>
+#include <time.h>
+#include <utmp.h>
+#include <pwd.h>
+#include <sys/param.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <sys/time.h>
+#include <sys/resource.h>
+#include <sys/stat.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#ifdef SVR4
+#include <sys/mkdev.h>
+#endif
+#endif /* UNUSED */
+
+#include "netif/ppp/ppp_impl.h"
+
+#include "netif/ppp/fsm.h"
+#include "netif/ppp/lcp.h"
+
+#if defined(SUNOS4)
+extern char *strerror();
+#endif
+
+static void ppp_logit(int level, const char *fmt, va_list args);
+static void ppp_log_write(int level, char *buf);
+#if PRINTPKT_SUPPORT
+static void ppp_vslp_printer(void *arg, const char *fmt, ...);
+static void ppp_format_packet(const u_char *p, int len,
+		void (*printer) (void *, const char *, ...), void *arg);
+
+struct buffer_info {
+    char *ptr;
+    int len;
+};
+#endif /* PRINTPKT_SUPPORT */
+
+/*
+ * ppp_strlcpy - like strcpy/strncpy, doesn't overflow destination buffer,
+ * always leaves destination null-terminated (for len > 0).
+ */
+size_t ppp_strlcpy(char *dest, const char *src, size_t len) {
+    size_t ret = strlen(src);
+
+    if (len != 0) {
+	if (ret < len)
+	    strcpy(dest, src);
+	else {
+	    strncpy(dest, src, len - 1);
+	    dest[len-1] = 0;
+	}
+    }
+    return ret;
+}
+
+/*
+ * ppp_strlcat - like strcat/strncat, doesn't overflow destination buffer,
+ * always leaves destination null-terminated (for len > 0).
+ */
+size_t ppp_strlcat(char *dest, const char *src, size_t len) {
+    size_t dlen = strlen(dest);
+
+    return dlen + ppp_strlcpy(dest + dlen, src, (len > dlen? len - dlen: 0));
+}
+
+
+/*
+ * ppp_slprintf - format a message into a buffer.  Like sprintf except we
+ * also specify the length of the output buffer, and we handle
+ * %m (error message), %v (visible string),
+ * %q (quoted string), %t (current time) and %I (IP address) formats.
+ * Doesn't do floating-point formats.
+ * Returns the number of chars put into buf.
+ */
+int ppp_slprintf(char *buf, int buflen, const char *fmt, ...) {
+    va_list args;
+    int n;
+
+    va_start(args, fmt);
+    n = ppp_vslprintf(buf, buflen, fmt, args);
+    va_end(args);
+    return n;
+}
+
+/*
+ * ppp_vslprintf - like ppp_slprintf, takes a va_list instead of a list of args.
+ */
+#define OUTCHAR(c)	(buflen > 0? (--buflen, *buf++ = (c)): 0)
+
+int ppp_vslprintf(char *buf, int buflen, const char *fmt, va_list args) {
+    int c, i, n;
+    int width, prec, fillch;
+    int base, len, neg, quoted;
+    unsigned long val = 0;
+    const char *f;
+    char *str, *buf0;
+    const unsigned char *p;
+    char num[32];
+#if 0 /* need port */
+    time_t t;
+#endif /* need port */
+    u32_t ip;
+    static char hexchars[] = "0123456789abcdef";
+#if PRINTPKT_SUPPORT
+    struct buffer_info bufinfo;
+#endif /* PRINTPKT_SUPPORT */
+
+    buf0 = buf;
+    --buflen;
+    while (buflen > 0) {
+	for (f = fmt; *f != '%' && *f != 0; ++f)
+	    ;
+	if (f > fmt) {
+	    len = f - fmt;
+	    if (len > buflen)
+		len = buflen;
+	    memcpy(buf, fmt, len);
+	    buf += len;
+	    buflen -= len;
+	    fmt = f;
+	}
+	if (*fmt == 0)
+	    break;
+	c = *++fmt;
+	width = 0;
+	prec = -1;
+	fillch = ' ';
+	if (c == '0') {
+	    fillch = '0';
+	    c = *++fmt;
+	}
+	if (c == '*') {
+	    width = va_arg(args, int);
+	    c = *++fmt;
+	} else {
+	    while (lwip_isdigit(c)) {
+		width = width * 10 + c - '0';
+		c = *++fmt;
+	    }
+	}
+	if (c == '.') {
+	    c = *++fmt;
+	    if (c == '*') {
+		prec = va_arg(args, int);
+		c = *++fmt;
+	    } else {
+		prec = 0;
+		while (lwip_isdigit(c)) {
+		    prec = prec * 10 + c - '0';
+		    c = *++fmt;
+		}
+	    }
+	}
+	str = 0;
+	base = 0;
+	neg = 0;
+	++fmt;
+	switch (c) {
+	case 'l':
+	    c = *fmt++;
+	    switch (c) {
+	    case 'd':
+		val = va_arg(args, long);
+		if ((long)val < 0) {
+		    neg = 1;
+		    val = (unsigned long)-(long)val;
+		}
+		base = 10;
+		break;
+	    case 'u':
+		val = va_arg(args, unsigned long);
+		base = 10;
+		break;
+	    default:
+		OUTCHAR('%');
+		OUTCHAR('l');
+		--fmt;		/* so %lz outputs %lz etc. */
+		continue;
+	    }
+	    break;
+	case 'd':
+	    i = va_arg(args, int);
+	    if (i < 0) {
+		neg = 1;
+		val = -i;
+	    } else
+		val = i;
+	    base = 10;
+	    break;
+	case 'u':
+	    val = va_arg(args, unsigned int);
+	    base = 10;
+	    break;
+	case 'o':
+	    val = va_arg(args, unsigned int);
+	    base = 8;
+	    break;
+	case 'x':
+	case 'X':
+	    val = va_arg(args, unsigned int);
+	    base = 16;
+	    break;
+#if 0 /* unused (and wrong on LLP64 systems) */
+	case 'p':
+	    val = (unsigned long) va_arg(args, void *);
+	    base = 16;
+	    neg = 2;
+	    break;
+#endif /* unused (and wrong on LLP64 systems) */
+	case 's':
+	    str = va_arg(args, char *);
+	    break;
+	case 'c':
+	    num[0] = va_arg(args, int);
+	    num[1] = 0;
+	    str = num;
+	    break;
+#if 0 /* do we always have strerror() in embedded ? */
+	case 'm':
+	    str = strerror(errno);
+	    break;
+#endif /* do we always have strerror() in embedded ? */
+	case 'I':
+	    ip = va_arg(args, u32_t);
+	    ip = lwip_ntohl(ip);
+	    ppp_slprintf(num, sizeof(num), "%d.%d.%d.%d", (ip >> 24) & 0xff,
+		     (ip >> 16) & 0xff, (ip >> 8) & 0xff, ip & 0xff);
+	    str = num;
+	    break;
+#if 0 /* need port */
+	case 't':
+	    time(&t);
+	    str = ctime(&t);
+	    str += 4;		/* chop off the day name */
+	    str[15] = 0;	/* chop off year and newline */
+	    break;
+#endif /* need port */
+	case 'v':		/* "visible" string */
+	case 'q':		/* quoted string */
+	    quoted = c == 'q';
+	    p = va_arg(args, unsigned char *);
+	    if (p == NULL)
+		p = (const unsigned char *)"<NULL>";
+	    if (fillch == '0' && prec >= 0) {
+		n = prec;
+	    } else {
+		n = strlen((const char *)p);
+		if (prec >= 0 && n > prec)
+		    n = prec;
+	    }
+	    while (n > 0 && buflen > 0) {
+		c = *p++;
+		--n;
+		if (!quoted && c >= 0x80) {
+		    OUTCHAR('M');
+		    OUTCHAR('-');
+		    c -= 0x80;
+		}
+		if (quoted && (c == '"' || c == '\\'))
+		    OUTCHAR('\\');
+		if (c < 0x20 || (0x7f <= c && c < 0xa0)) {
+		    if (quoted) {
+			OUTCHAR('\\');
+			switch (c) {
+			case '\t':	OUTCHAR('t');	break;
+			case '\n':	OUTCHAR('n');	break;
+			case '\b':	OUTCHAR('b');	break;
+			case '\f':	OUTCHAR('f');	break;
+			default:
+			    OUTCHAR('x');
+			    OUTCHAR(hexchars[c >> 4]);
+			    OUTCHAR(hexchars[c & 0xf]);
+			}
+		    } else {
+			if (c == '\t')
+			    OUTCHAR(c);
+			else {
+			    OUTCHAR('^');
+			    OUTCHAR(c ^ 0x40);
+			}
+		    }
+		} else
+		    OUTCHAR(c);
+	    }
+	    continue;
+#if PRINTPKT_SUPPORT
+	case 'P':		/* print PPP packet */
+	    bufinfo.ptr = buf;
+	    bufinfo.len = buflen + 1;
+	    p = va_arg(args, unsigned char *);
+	    n = va_arg(args, int);
+	    ppp_format_packet(p, n, ppp_vslp_printer, &bufinfo);
+	    buf = bufinfo.ptr;
+	    buflen = bufinfo.len - 1;
+	    continue;
+#endif /* PRINTPKT_SUPPORT */
+	case 'B':
+	    p = va_arg(args, unsigned char *);
+	    for (n = prec; n > 0; --n) {
+		c = *p++;
+		if (fillch == ' ')
+		    OUTCHAR(' ');
+		OUTCHAR(hexchars[(c >> 4) & 0xf]);
+		OUTCHAR(hexchars[c & 0xf]);
+	    }
+	    continue;
+	default:
+	    *buf++ = '%';
+	    if (c != '%')
+		--fmt;		/* so %z outputs %z etc. */
+	    --buflen;
+	    continue;
+	}
+	if (base != 0) {
+	    str = num + sizeof(num);
+	    *--str = 0;
+	    while (str > num + neg) {
+		*--str = hexchars[val % base];
+		val = val / base;
+		if (--prec <= 0 && val == 0)
+		    break;
+	    }
+	    switch (neg) {
+	    case 1:
+		*--str = '-';
+		break;
+	    case 2:
+		*--str = 'x';
+		*--str = '0';
+		break;
+	    default:
+		break;
+	    }
+	    len = num + sizeof(num) - 1 - str;
+	} else {
+	    len = strlen(str);
+	    if (prec >= 0 && len > prec)
+		len = prec;
+	}
+	if (width > 0) {
+	    if (width > buflen)
+		width = buflen;
+	    if ((n = width - len) > 0) {
+		buflen -= n;
+		for (; n > 0; --n)
+		    *buf++ = fillch;
+	    }
+	}
+	if (len > buflen)
+	    len = buflen;
+	memcpy(buf, str, len);
+	buf += len;
+	buflen -= len;
+    }
+    *buf = 0;
+    return buf - buf0;
+}
+
+#if PRINTPKT_SUPPORT
+/*
+ * vslp_printer - used in processing a %P format
+ */
+static void ppp_vslp_printer(void *arg, const char *fmt, ...) {
+    int n;
+    va_list pvar;
+    struct buffer_info *bi;
+
+    va_start(pvar, fmt);
+    bi = (struct buffer_info *) arg;
+    n = ppp_vslprintf(bi->ptr, bi->len, fmt, pvar);
+    va_end(pvar);
+
+    bi->ptr += n;
+    bi->len -= n;
+}
+#endif /* PRINTPKT_SUPPORT */
+
+#if 0 /* UNUSED */
+/*
+ * log_packet - format a packet and log it.
+ */
+
+void
+log_packet(p, len, prefix, level)
+    u_char *p;
+    int len;
+    char *prefix;
+    int level;
+{
+	init_pr_log(prefix, level);
+	ppp_format_packet(p, len, pr_log, &level);
+	end_pr_log();
+}
+#endif /* UNUSED */
+
+#if PRINTPKT_SUPPORT
+/*
+ * ppp_format_packet - make a readable representation of a packet,
+ * calling `printer(arg, format, ...)' to output it.
+ */
+static void ppp_format_packet(const u_char *p, int len,
+		void (*printer) (void *, const char *, ...), void *arg) {
+    int i, n;
+    u_short proto;
+    const struct protent *protp;
+
+    if (len >= 2) {
+	GETSHORT(proto, p);
+	len -= 2;
+	for (i = 0; (protp = protocols[i]) != NULL; ++i)
+	    if (proto == protp->protocol)
+		break;
+	if (protp != NULL) {
+	    printer(arg, "[%s", protp->name);
+	    n = (*protp->printpkt)(p, len, printer, arg);
+	    printer(arg, "]");
+	    p += n;
+	    len -= n;
+	} else {
+	    for (i = 0; (protp = protocols[i]) != NULL; ++i)
+		if (proto == (protp->protocol & ~0x8000))
+		    break;
+	    if (protp != 0 && protp->data_name != 0) {
+		printer(arg, "[%s data]", protp->data_name);
+		if (len > 8)
+		    printer(arg, "%.8B ...", p);
+		else
+		    printer(arg, "%.*B", len, p);
+		len = 0;
+	    } else
+		printer(arg, "[proto=0x%x]", proto);
+	}
+    }
+
+    if (len > 32)
+	printer(arg, "%.32B ...", p);
+    else
+	printer(arg, "%.*B", len, p);
+}
+#endif /* PRINTPKT_SUPPORT */
+
+#if 0 /* UNUSED */
+/*
+ * init_pr_log, end_pr_log - initialize and finish use of pr_log.
+ */
+
+static char line[256];		/* line to be logged accumulated here */
+static char *linep;		/* current pointer within line */
+static int llevel;		/* level for logging */
+
+void
+init_pr_log(prefix, level)
+     const char *prefix;
+     int level;
+{
+	linep = line;
+	if (prefix != NULL) {
+		ppp_strlcpy(line, prefix, sizeof(line));
+		linep = line + strlen(line);
+	}
+	llevel = level;
+}
+
+void
+end_pr_log()
+{
+	if (linep != line) {
+		*linep = 0;
+		ppp_log_write(llevel, line);
+	}
+}
+
+/*
+ * pr_log - printer routine for outputting to log
+ */
+void
+pr_log (void *arg, const char *fmt, ...)
+{
+	int l, n;
+	va_list pvar;
+	char *p, *eol;
+	char buf[256];
+
+	va_start(pvar, fmt);
+	n = ppp_vslprintf(buf, sizeof(buf), fmt, pvar);
+	va_end(pvar);
+
+	p = buf;
+	eol = strchr(buf, '\n');
+	if (linep != line) {
+		l = (eol == NULL)? n: eol - buf;
+		if (linep + l < line + sizeof(line)) {
+			if (l > 0) {
+				memcpy(linep, buf, l);
+				linep += l;
+			}
+			if (eol == NULL)
+				return;
+			p = eol + 1;
+			eol = strchr(p, '\n');
+		}
+		*linep = 0;
+		ppp_log_write(llevel, line);
+		linep = line;
+	}
+
+	while (eol != NULL) {
+		*eol = 0;
+		ppp_log_write(llevel, p);
+		p = eol + 1;
+		eol = strchr(p, '\n');
+	}
+
+	/* assumes sizeof(buf) <= sizeof(line) */
+	l = buf + n - p;
+	if (l > 0) {
+		memcpy(line, p, n);
+		linep = line + l;
+	}
+}
+#endif /* UNUSED */
+
+/*
+ * ppp_print_string - print a readable representation of a string using
+ * printer.
+ */
+void ppp_print_string(const u_char *p, int len, void (*printer) (void *, const char *, ...), void *arg) {
+    int c;
+
+    printer(arg, "\"");
+    for (; len > 0; --len) {
+	c = *p++;
+	if (' ' <= c && c <= '~') {
+	    if (c == '\\' || c == '"')
+		printer(arg, "\\");
+	    printer(arg, "%c", c);
+	} else {
+	    switch (c) {
+	    case '\n':
+		printer(arg, "\\n");
+		break;
+	    case '\r':
+		printer(arg, "\\r");
+		break;
+	    case '\t':
+		printer(arg, "\\t");
+		break;
+	    default:
+		printer(arg, "\\%.3o", (u8_t)c);
+		/* no break */
+	    }
+	}
+    }
+    printer(arg, "\"");
+}
+
+/*
+ * ppp_logit - does the hard work for fatal et al.
+ */
+static void ppp_logit(int level, const char *fmt, va_list args) {
+    char buf[1024];
+
+    ppp_vslprintf(buf, sizeof(buf), fmt, args);
+    ppp_log_write(level, buf);
+}
+
+static void ppp_log_write(int level, char *buf) {
+    LWIP_UNUSED_ARG(level); /* necessary if PPPDEBUG is defined to an empty function */
+    LWIP_UNUSED_ARG(buf);
+    PPPDEBUG(level, ("%s\n", buf) );
+#if 0
+    if (log_to_fd >= 0 && (level != LOG_DEBUG || debug)) {
+	int n = strlen(buf);
+
+	if (n > 0 && buf[n-1] == '\n')
+	    --n;
+	if (write(log_to_fd, buf, n) != n
+	    || write(log_to_fd, "\n", 1) != 1)
+	    log_to_fd = -1;
+    }
+#endif
+}
+
+/*
+ * ppp_fatal - log an error message and die horribly.
+ */
+void ppp_fatal(const char *fmt, ...) {
+    va_list pvar;
+
+    va_start(pvar, fmt);
+    ppp_logit(LOG_ERR, fmt, pvar);
+    va_end(pvar);
+
+    LWIP_ASSERT("ppp_fatal", 0);   /* as promised */
+}
+
+/*
+ * ppp_error - log an error message.
+ */
+void ppp_error(const char *fmt, ...) {
+    va_list pvar;
+
+    va_start(pvar, fmt);
+    ppp_logit(LOG_ERR, fmt, pvar);
+    va_end(pvar);
+#if 0 /* UNUSED */
+    ++error_count;
+#endif /* UNUSED */
+}
+
+/*
+ * ppp_warn - log a warning message.
+ */
+void ppp_warn(const char *fmt, ...) {
+    va_list pvar;
+
+    va_start(pvar, fmt);
+    ppp_logit(LOG_WARNING, fmt, pvar);
+    va_end(pvar);
+}
+
+/*
+ * ppp_notice - log a notice-level message.
+ */
+void ppp_notice(const char *fmt, ...) {
+    va_list pvar;
+
+    va_start(pvar, fmt);
+    ppp_logit(LOG_NOTICE, fmt, pvar);
+    va_end(pvar);
+}
+
+/*
+ * ppp_info - log an informational message.
+ */
+void ppp_info(const char *fmt, ...) {
+    va_list pvar;
+
+    va_start(pvar, fmt);
+    ppp_logit(LOG_INFO, fmt, pvar);
+    va_end(pvar);
+}
+
+/*
+ * ppp_dbglog - log a debug message.
+ */
+void ppp_dbglog(const char *fmt, ...) {
+    va_list pvar;
+
+    va_start(pvar, fmt);
+    ppp_logit(LOG_DEBUG, fmt, pvar);
+    va_end(pvar);
+}
+
+#if PRINTPKT_SUPPORT
+/*
+ * ppp_dump_packet - print out a packet in readable form if it is interesting.
+ * Assumes len >= PPP_HDRLEN.
+ */
+void ppp_dump_packet(ppp_pcb *pcb, const char *tag, unsigned char *p, int len) {
+    int proto;
+
+    /*
+     * don't print data packets, i.e. IPv4, IPv6, VJ, and compressed packets.
+     */
+    proto = (p[0] << 8) + p[1];
+    if (proto < 0xC000 && (proto & ~0x8000) == proto)
+	return;
+
+    /*
+     * don't print valid LCP echo request/reply packets if the link is up.
+     */
+    if (proto == PPP_LCP && pcb->phase == PPP_PHASE_RUNNING && len >= 2 + HEADERLEN) {
+	unsigned char *lcp = p + 2;
+	int l = (lcp[2] << 8) + lcp[3];
+
+	if ((lcp[0] == ECHOREQ || lcp[0] == ECHOREP)
+	    && l >= HEADERLEN && l <= len - 2)
+	    return;
+    }
+
+    ppp_dbglog("%s %P", tag, p, len);
+}
+#endif /* PRINTPKT_SUPPORT */
+
+#if 0 /* Unused */
+
+/*
+ * complete_read - read a full `count' bytes from fd,
+ * unless end-of-file or an error other than EINTR is encountered.
+ */
+ssize_t
+complete_read(int fd, void *buf, size_t count)
+{
+	size_t done;
+	ssize_t nb;
+	char *ptr = buf;
+
+	for (done = 0; done < count; ) {
+		nb = read(fd, ptr, count - done);
+		if (nb < 0) {
+			if (errno == EINTR)
+				continue;
+			return -1;
+		}
+		if (nb == 0)
+			break;
+		done += nb;
+		ptr += nb;
+	}
+	return done;
+}
+
+/* Procedures for locking the serial device using a lock file. */
+#ifndef LOCK_DIR
+#ifdef __linux__
+#define LOCK_DIR	"/var/lock"
+#else
+#ifdef SVR4
+#define LOCK_DIR	"/var/spool/locks"
+#else
+#define LOCK_DIR	"/var/spool/lock"
+#endif
+#endif
+#endif /* LOCK_DIR */
+
+static char lock_file[MAXPATHLEN];
+
+/*
+ * lock - create a lock file for the named device
+ */
+int
+lock(dev)
+    char *dev;
+{
+#ifdef LOCKLIB
+    int result;
+
+    result = mklock (dev, (void *) 0);
+    if (result == 0) {
+	ppp_strlcpy(lock_file, dev, sizeof(lock_file));
+	return 0;
+    }
+
+    if (result > 0)
+        ppp_notice("Device %s is locked by pid %d", dev, result);
+    else
+	ppp_error("Can't create lock file %s", lock_file);
+    return -1;
+
+#else /* LOCKLIB */
+
+    char lock_buffer[12];
+    int fd, pid, n;
+
+#ifdef SVR4
+    struct stat sbuf;
+
+    if (stat(dev, &sbuf) < 0) {
+	ppp_error("Can't get device number for %s: %m", dev);
+	return -1;
+    }
+    if ((sbuf.st_mode & S_IFMT) != S_IFCHR) {
+	ppp_error("Can't lock %s: not a character device", dev);
+	return -1;
+    }
+    ppp_slprintf(lock_file, sizeof(lock_file), "%s/LK.%03d.%03d.%03d",
+	     LOCK_DIR, major(sbuf.st_dev),
+	     major(sbuf.st_rdev), minor(sbuf.st_rdev));
+#else
+    char *p;
+    char lockdev[MAXPATHLEN];
+
+    if ((p = strstr(dev, "dev/")) != NULL) {
+	dev = p + 4;
+	strncpy(lockdev, dev, MAXPATHLEN-1);
+	lockdev[MAXPATHLEN-1] = 0;
+	while ((p = strrchr(lockdev, '/')) != NULL) {
+	    *p = '_';
+	}
+	dev = lockdev;
+    } else
+	if ((p = strrchr(dev, '/')) != NULL)
+	    dev = p + 1;
+
+    ppp_slprintf(lock_file, sizeof(lock_file), "%s/LCK..%s", LOCK_DIR, dev);
+#endif
+
+    while ((fd = open(lock_file, O_EXCL | O_CREAT | O_RDWR, 0644)) < 0) {
+	if (errno != EEXIST) {
+	    ppp_error("Can't create lock file %s: %m", lock_file);
+	    break;
+	}
+
+	/* Read the lock file to find out who has the device locked. */
+	fd = open(lock_file, O_RDONLY, 0);
+	if (fd < 0) {
+	    if (errno == ENOENT) /* This is just a timing problem. */
+		continue;
+	    ppp_error("Can't open existing lock file %s: %m", lock_file);
+	    break;
+	}
+#ifndef LOCK_BINARY
+	n = read(fd, lock_buffer, 11);
+#else
+	n = read(fd, &pid, sizeof(pid));
+#endif /* LOCK_BINARY */
+	close(fd);
+	fd = -1;
+	if (n <= 0) {
+	    ppp_error("Can't read pid from lock file %s", lock_file);
+	    break;
+	}
+
+	/* See if the process still exists. */
+#ifndef LOCK_BINARY
+	lock_buffer[n] = 0;
+	pid = atoi(lock_buffer);
+#endif /* LOCK_BINARY */
+	if (pid == getpid())
+	    return 1;		/* somebody else locked it for us */
+	if (pid == 0
+	    || (kill(pid, 0) == -1 && errno == ESRCH)) {
+	    if (unlink (lock_file) == 0) {
+		ppp_notice("Removed stale lock on %s (pid %d)", dev, pid);
+		continue;
+	    }
+	    ppp_warn("Couldn't remove stale lock on %s", dev);
+	} else
+	    ppp_notice("Device %s is locked by pid %d", dev, pid);
+	break;
+    }
+
+    if (fd < 0) {
+	lock_file[0] = 0;
+	return -1;
+    }
+
+    pid = getpid();
+#ifndef LOCK_BINARY
+    ppp_slprintf(lock_buffer, sizeof(lock_buffer), "%10d\n", pid);
+    write (fd, lock_buffer, 11);
+#else
+    write(fd, &pid, sizeof (pid));
+#endif
+    close(fd);
+    return 0;
+
+#endif
+}
+
+/*
+ * relock - called to update our lockfile when we are about to detach,
+ * thus changing our pid (we fork, the child carries on, and the parent dies).
+ * Note that this is called by the parent, with pid equal to the pid
+ * of the child.  This avoids a potential race which would exist if
+ * we had the child rewrite the lockfile (the parent might die first,
+ * and another process could think the lock was stale if it checked
+ * between when the parent died and the child rewrote the lockfile).
+ */
+int
+relock(pid)
+    int pid;
+{
+#ifdef LOCKLIB
+    /* XXX is there a way to do this? */
+    return -1;
+#else /* LOCKLIB */
+
+    int fd;
+    char lock_buffer[12];
+
+    if (lock_file[0] == 0)
+	return -1;
+    fd = open(lock_file, O_WRONLY, 0);
+    if (fd < 0) {
+	ppp_error("Couldn't reopen lock file %s: %m", lock_file);
+	lock_file[0] = 0;
+	return -1;
+    }
+
+#ifndef LOCK_BINARY
+    ppp_slprintf(lock_buffer, sizeof(lock_buffer), "%10d\n", pid);
+    write (fd, lock_buffer, 11);
+#else
+    write(fd, &pid, sizeof(pid));
+#endif /* LOCK_BINARY */
+    close(fd);
+    return 0;
+
+#endif /* LOCKLIB */
+}
+
+/*
+ * unlock - remove our lockfile
+ */
+void
+unlock()
+{
+    if (lock_file[0]) {
+#ifdef LOCKLIB
+	(void) rmlock(lock_file, (void *) 0);
+#else
+	unlink(lock_file);
+#endif
+	lock_file[0] = 0;
+    }
+}
+
+#endif /* Unused */
+
+#endif /* PPP_SUPPORT */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/netif/ppp/vj.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/netif/ppp/vj.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/netif/ppp/vj.c	(revision 457)
@@ -0,0 +1,685 @@
+/*
+ * Routines to compress and uncompess tcp packets (for transmission
+ * over low speed serial lines.
+ *
+ * Copyright (c) 1989 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms are permitted
+ * provided that the above copyright notice and this paragraph are
+ * duplicated in all such forms and that any documentation,
+ * advertising materials, and other materials related to such
+ * distribution and use acknowledge that the software was developed
+ * by the University of California, Berkeley.  The name of the
+ * University may not be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * Van Jacobson (van@helios.ee.lbl.gov), Dec 31, 1989:
+ *   Initial distribution.
+ *
+ * Modified June 1993 by Paul Mackerras, paulus@cs.anu.edu.au,
+ * so that the entire packet being decompressed doesn't have
+ * to be in contiguous memory (just the compressed header).
+ *
+ * Modified March 1998 by Guy Lancaster, glanca@gesn.com,
+ * for a 16 bit processor.
+ */
+
+#include "netif/ppp/ppp_opts.h"
+#if PPP_SUPPORT && VJ_SUPPORT /* don't build if not configured for use in lwipopts.h */
+
+#include "netif/ppp/ppp_impl.h"
+#include "netif/ppp/pppdebug.h"
+
+#include "netif/ppp/vj.h"
+
+#include <string.h>
+
+#if LINK_STATS
+#define INCR(counter) ++comp->stats.counter
+#else
+#define INCR(counter)
+#endif
+
+void
+vj_compress_init(struct vjcompress *comp)
+{
+  u8_t i;
+  struct cstate *tstate = comp->tstate;
+
+#if MAX_SLOTS == 0
+  memset((char *)comp, 0, sizeof(*comp));
+#endif
+  comp->maxSlotIndex = MAX_SLOTS - 1;
+  comp->compressSlot = 0;    /* Disable slot ID compression by default. */
+  for (i = MAX_SLOTS - 1; i > 0; --i) {
+    tstate[i].cs_id = i;
+    tstate[i].cs_next = &tstate[i - 1];
+  }
+  tstate[0].cs_next = &tstate[MAX_SLOTS - 1];
+  tstate[0].cs_id = 0;
+  comp->last_cs = &tstate[0];
+  comp->last_recv = 255;
+  comp->last_xmit = 255;
+  comp->flags = VJF_TOSS;
+}
+
+
+/* ENCODE encodes a number that is known to be non-zero.  ENCODEZ
+ * checks for zero (since zero has to be encoded in the long, 3 byte
+ * form).
+ */
+#define ENCODE(n) { \
+  if ((u16_t)(n) >= 256) { \
+    *cp++ = 0; \
+    cp[1] = (u8_t)(n); \
+    cp[0] = (u8_t)((n) >> 8); \
+    cp += 2; \
+  } else { \
+    *cp++ = (u8_t)(n); \
+  } \
+}
+#define ENCODEZ(n) { \
+  if ((u16_t)(n) >= 256 || (u16_t)(n) == 0) { \
+    *cp++ = 0; \
+    cp[1] = (u8_t)(n); \
+    cp[0] = (u8_t)((n) >> 8); \
+    cp += 2; \
+  } else { \
+    *cp++ = (u8_t)(n); \
+  } \
+}
+
+#define DECODEL(f) { \
+  if (*cp == 0) {\
+    u32_t tmp_ = lwip_ntohl(f) + ((cp[1] << 8) | cp[2]); \
+    (f) = lwip_htonl(tmp_); \
+    cp += 3; \
+  } else { \
+    u32_t tmp_ = lwip_ntohl(f) + (u32_t)*cp++; \
+    (f) = lwip_htonl(tmp_); \
+  } \
+}
+
+#define DECODES(f) { \
+  if (*cp == 0) {\
+    u16_t tmp_ = lwip_ntohs(f) + (((u16_t)cp[1] << 8) | cp[2]); \
+    (f) = lwip_htons(tmp_); \
+    cp += 3; \
+  } else { \
+    u16_t tmp_ = lwip_ntohs(f) + (u16_t)*cp++; \
+    (f) = lwip_htons(tmp_); \
+  } \
+}
+
+#define DECODEU(f) { \
+  if (*cp == 0) {\
+    (f) = lwip_htons(((u16_t)cp[1] << 8) | cp[2]); \
+    cp += 3; \
+  } else { \
+    (f) = lwip_htons((u16_t)*cp++); \
+  } \
+}
+
+/* Helper structures for unaligned *u32_t and *u16_t accesses */
+#ifdef PACK_STRUCT_USE_INCLUDES
+#  include "arch/bpstruct.h"
+#endif
+PACK_STRUCT_BEGIN
+struct vj_u32_t {
+  PACK_STRUCT_FIELD(u32_t v);
+} PACK_STRUCT_STRUCT;
+PACK_STRUCT_END
+#ifdef PACK_STRUCT_USE_INCLUDES
+#  include "arch/epstruct.h"
+#endif
+
+#ifdef PACK_STRUCT_USE_INCLUDES
+#  include "arch/bpstruct.h"
+#endif
+PACK_STRUCT_BEGIN
+struct vj_u16_t {
+  PACK_STRUCT_FIELD(u16_t v);
+} PACK_STRUCT_STRUCT;
+PACK_STRUCT_END
+#ifdef PACK_STRUCT_USE_INCLUDES
+#  include "arch/epstruct.h"
+#endif
+
+/*
+ * vj_compress_tcp - Attempt to do Van Jacobson header compression on a
+ * packet.  This assumes that nb and comp are not null and that the first
+ * buffer of the chain contains a valid IP header.
+ * Return the VJ type code indicating whether or not the packet was
+ * compressed.
+ */
+u8_t
+vj_compress_tcp(struct vjcompress *comp, struct pbuf **pb)
+{
+  struct pbuf *np = *pb;
+  struct ip_hdr *ip = (struct ip_hdr *)np->payload;
+  struct cstate *cs = comp->last_cs->cs_next;
+  u16_t ilen = IPH_HL(ip);
+  u16_t hlen;
+  struct tcp_hdr *oth;
+  struct tcp_hdr *th;
+  u16_t deltaS, deltaA = 0;
+  u32_t deltaL;
+  u32_t changes = 0;
+  u8_t new_seq[16];
+  u8_t *cp = new_seq;
+
+  /*
+   * Check that the packet is IP proto TCP.
+   */
+  if (IPH_PROTO(ip) != IP_PROTO_TCP) {
+    return (TYPE_IP);
+  }
+
+  /*
+   * Bail if this is an IP fragment or if the TCP packet isn't
+   * `compressible' (i.e., ACK isn't set or some other control bit is
+   * set).
+   */
+  if ((IPH_OFFSET(ip) & PP_HTONS(0x3fff)) || np->tot_len < 40) {
+    return (TYPE_IP);
+  }
+  th = (struct tcp_hdr *)&((struct vj_u32_t*)ip)[ilen];
+  if ((TCPH_FLAGS(th) & (TCP_SYN|TCP_FIN|TCP_RST|TCP_ACK)) != TCP_ACK) {
+    return (TYPE_IP);
+  }
+
+  /* Check that the TCP/IP headers are contained in the first buffer. */
+  hlen = ilen + TCPH_HDRLEN(th);
+  hlen <<= 2;
+  if (np->len < hlen) {
+    PPPDEBUG(LOG_INFO, ("vj_compress_tcp: header len %d spans buffers\n", hlen));
+    return (TYPE_IP);
+  }
+
+  /* TCP stack requires that we don't change the packet payload, therefore we copy
+   * the whole packet before compression. */
+  np = pbuf_clone(PBUF_RAW, PBUF_RAM, *pb);
+  if (!np) {
+    return (TYPE_IP);
+  }
+
+  *pb = np;
+  ip = (struct ip_hdr *)np->payload;
+
+  /*
+   * Packet is compressible -- we're going to send either a
+   * COMPRESSED_TCP or UNCOMPRESSED_TCP packet.  Either way we need
+   * to locate (or create) the connection state.  Special case the
+   * most recently used connection since it's most likely to be used
+   * again & we don't have to do any reordering if it's used.
+   */
+  INCR(vjs_packets);
+  if (!ip4_addr_cmp(&ip->src, &cs->cs_ip.src)
+      || !ip4_addr_cmp(&ip->dest, &cs->cs_ip.dest)
+      || (*(struct vj_u32_t*)th).v != (((struct vj_u32_t*)&cs->cs_ip)[IPH_HL(&cs->cs_ip)]).v) {
+    /*
+     * Wasn't the first -- search for it.
+     *
+     * States are kept in a circularly linked list with
+     * last_cs pointing to the end of the list.  The
+     * list is kept in lru order by moving a state to the
+     * head of the list whenever it is referenced.  Since
+     * the list is short and, empirically, the connection
+     * we want is almost always near the front, we locate
+     * states via linear search.  If we don't find a state
+     * for the datagram, the oldest state is (re-)used.
+     */
+    struct cstate *lcs;
+    struct cstate *lastcs = comp->last_cs;
+
+    do {
+      lcs = cs; cs = cs->cs_next;
+      INCR(vjs_searches);
+      if (ip4_addr_cmp(&ip->src, &cs->cs_ip.src)
+          && ip4_addr_cmp(&ip->dest, &cs->cs_ip.dest)
+          && (*(struct vj_u32_t*)th).v == (((struct vj_u32_t*)&cs->cs_ip)[IPH_HL(&cs->cs_ip)]).v) {
+        goto found;
+      }
+    } while (cs != lastcs);
+
+    /*
+     * Didn't find it -- re-use oldest cstate.  Send an
+     * uncompressed packet that tells the other side what
+     * connection number we're using for this conversation.
+     * Note that since the state list is circular, the oldest
+     * state points to the newest and we only need to set
+     * last_cs to update the lru linkage.
+     */
+    INCR(vjs_misses);
+    comp->last_cs = lcs;
+    goto uncompressed;
+
+    found:
+    /*
+     * Found it -- move to the front on the connection list.
+     */
+    if (cs == lastcs) {
+      comp->last_cs = lcs;
+    } else {
+      lcs->cs_next = cs->cs_next;
+      cs->cs_next = lastcs->cs_next;
+      lastcs->cs_next = cs;
+    }
+  }
+
+  oth = (struct tcp_hdr *)&((struct vj_u32_t*)&cs->cs_ip)[ilen];
+  deltaS = ilen;
+
+  /*
+   * Make sure that only what we expect to change changed. The first
+   * line of the `if' checks the IP protocol version, header length &
+   * type of service.  The 2nd line checks the "Don't fragment" bit.
+   * The 3rd line checks the time-to-live and protocol (the protocol
+   * check is unnecessary but costless).  The 4th line checks the TCP
+   * header length.  The 5th line checks IP options, if any.  The 6th
+   * line checks TCP options, if any.  If any of these things are
+   * different between the previous & current datagram, we send the
+   * current datagram `uncompressed'.
+   */
+  if ((((struct vj_u16_t*)ip)[0]).v != (((struct vj_u16_t*)&cs->cs_ip)[0]).v
+      || (((struct vj_u16_t*)ip)[3]).v != (((struct vj_u16_t*)&cs->cs_ip)[3]).v
+      || (((struct vj_u16_t*)ip)[4]).v != (((struct vj_u16_t*)&cs->cs_ip)[4]).v
+      || TCPH_HDRLEN(th) != TCPH_HDRLEN(oth)
+      || (deltaS > 5 && BCMP(ip + 1, &cs->cs_ip + 1, (deltaS - 5) << 2))
+      || (TCPH_HDRLEN(th) > 5 && BCMP(th + 1, oth + 1, (TCPH_HDRLEN(th) - 5) << 2))) {
+    goto uncompressed;
+  }
+
+  /*
+   * Figure out which of the changing fields changed.  The
+   * receiver expects changes in the order: urgent, window,
+   * ack, seq (the order minimizes the number of temporaries
+   * needed in this section of code).
+   */
+  if (TCPH_FLAGS(th) & TCP_URG) {
+    deltaS = lwip_ntohs(th->urgp);
+    ENCODEZ(deltaS);
+    changes |= NEW_U;
+  } else if (th->urgp != oth->urgp) {
+    /* argh! URG not set but urp changed -- a sensible
+     * implementation should never do this but RFC793
+     * doesn't prohibit the change so we have to deal
+     * with it. */
+    goto uncompressed;
+  }
+
+  if ((deltaS = (u16_t)(lwip_ntohs(th->wnd) - lwip_ntohs(oth->wnd))) != 0) {
+    ENCODE(deltaS);
+    changes |= NEW_W;
+  }
+
+  if ((deltaL = lwip_ntohl(th->ackno) - lwip_ntohl(oth->ackno)) != 0) {
+    if (deltaL > 0xffff) {
+      goto uncompressed;
+    }
+    deltaA = (u16_t)deltaL;
+    ENCODE(deltaA);
+    changes |= NEW_A;
+  }
+
+  if ((deltaL = lwip_ntohl(th->seqno) - lwip_ntohl(oth->seqno)) != 0) {
+    if (deltaL > 0xffff) {
+      goto uncompressed;
+    }
+    deltaS = (u16_t)deltaL;
+    ENCODE(deltaS);
+    changes |= NEW_S;
+  }
+
+  switch(changes) {
+  case 0:
+    /*
+     * Nothing changed. If this packet contains data and the
+     * last one didn't, this is probably a data packet following
+     * an ack (normal on an interactive connection) and we send
+     * it compressed.  Otherwise it's probably a retransmit,
+     * retransmitted ack or window probe.  Send it uncompressed
+     * in case the other side missed the compressed version.
+     */
+    if (IPH_LEN(ip) != IPH_LEN(&cs->cs_ip) &&
+      lwip_ntohs(IPH_LEN(&cs->cs_ip)) == hlen) {
+      break;
+    }
+    /* no break */
+    /* fall through */
+
+  case SPECIAL_I:
+  case SPECIAL_D:
+    /*
+     * actual changes match one of our special case encodings --
+     * send packet uncompressed.
+     */
+    goto uncompressed;
+
+  case NEW_S|NEW_A:
+    if (deltaS == deltaA && deltaS == lwip_ntohs(IPH_LEN(&cs->cs_ip)) - hlen) {
+      /* special case for echoed terminal traffic */
+      changes = SPECIAL_I;
+      cp = new_seq;
+    }
+    break;
+
+  case NEW_S:
+    if (deltaS == lwip_ntohs(IPH_LEN(&cs->cs_ip)) - hlen) {
+      /* special case for data xfer */
+      changes = SPECIAL_D;
+      cp = new_seq;
+    }
+    break;
+  default:
+     break;
+  }
+
+  deltaS = (u16_t)(lwip_ntohs(IPH_ID(ip)) - lwip_ntohs(IPH_ID(&cs->cs_ip)));
+  if (deltaS != 1) {
+    ENCODEZ(deltaS);
+    changes |= NEW_I;
+  }
+  if (TCPH_FLAGS(th) & TCP_PSH) {
+    changes |= TCP_PUSH_BIT;
+  }
+  /*
+   * Grab the cksum before we overwrite it below.  Then update our
+   * state with this packet's header.
+   */
+  deltaA = lwip_ntohs(th->chksum);
+  MEMCPY(&cs->cs_ip, ip, hlen);
+
+  /*
+   * We want to use the original packet as our compressed packet.
+   * (cp - new_seq) is the number of bytes we need for compressed
+   * sequence numbers.  In addition we need one byte for the change
+   * mask, one for the connection id and two for the tcp checksum.
+   * So, (cp - new_seq) + 4 bytes of header are needed.  hlen is how
+   * many bytes of the original packet to toss so subtract the two to
+   * get the new packet size.
+   */
+  deltaS = (u16_t)(cp - new_seq);
+  if (!comp->compressSlot || comp->last_xmit != cs->cs_id) {
+    comp->last_xmit = cs->cs_id;
+    hlen -= deltaS + 4;
+    if (pbuf_remove_header(np, hlen)){
+      /* Can we cope with this failing?  Just assert for now */
+      LWIP_ASSERT("pbuf_remove_header failed\n", 0);
+    }
+    cp = (u8_t*)np->payload;
+    *cp++ = (u8_t)(changes | NEW_C);
+    *cp++ = cs->cs_id;
+  } else {
+    hlen -= deltaS + 3;
+    if (pbuf_remove_header(np, hlen)) {
+      /* Can we cope with this failing?  Just assert for now */
+      LWIP_ASSERT("pbuf_remove_header failed\n", 0);
+    }
+    cp = (u8_t*)np->payload;
+    *cp++ = (u8_t)changes;
+  }
+  *cp++ = (u8_t)(deltaA >> 8);
+  *cp++ = (u8_t)deltaA;
+  MEMCPY(cp, new_seq, deltaS);
+  INCR(vjs_compressed);
+  return (TYPE_COMPRESSED_TCP);
+
+  /*
+   * Update connection state cs & send uncompressed packet (that is,
+   * a regular ip/tcp packet but with the 'conversation id' we hope
+   * to use on future compressed packets in the protocol field).
+   */
+uncompressed:
+  MEMCPY(&cs->cs_ip, ip, hlen);
+  IPH_PROTO_SET(ip, cs->cs_id);
+  comp->last_xmit = cs->cs_id;
+  return (TYPE_UNCOMPRESSED_TCP);
+}
+
+/*
+ * Called when we may have missed a packet.
+ */
+void
+vj_uncompress_err(struct vjcompress *comp)
+{
+  comp->flags |= VJF_TOSS;
+  INCR(vjs_errorin);
+}
+
+/*
+ * "Uncompress" a packet of type TYPE_UNCOMPRESSED_TCP.
+ * Return 0 on success, -1 on failure.
+ */
+int
+vj_uncompress_uncomp(struct pbuf *nb, struct vjcompress *comp)
+{
+  u32_t hlen;
+  struct cstate *cs;
+  struct ip_hdr *ip;
+
+  ip = (struct ip_hdr *)nb->payload;
+  hlen = IPH_HL(ip) << 2;
+  if (IPH_PROTO(ip) >= MAX_SLOTS
+      || hlen + sizeof(struct tcp_hdr) > nb->len
+      || (hlen += TCPH_HDRLEN_BYTES((struct tcp_hdr *)&((char *)ip)[hlen]))
+          > nb->len
+      || hlen > MAX_HDR) {
+    PPPDEBUG(LOG_INFO, ("vj_uncompress_uncomp: bad cid=%d, hlen=%d buflen=%d\n",
+      IPH_PROTO(ip), hlen, nb->len));
+    vj_uncompress_err(comp);
+    return -1;
+  }
+  cs = &comp->rstate[comp->last_recv = IPH_PROTO(ip)];
+  comp->flags &=~ VJF_TOSS;
+  IPH_PROTO_SET(ip, IP_PROTO_TCP);
+  /* copy from/to bigger buffers checked above instead of cs->cs_ip and ip
+     just to help static code analysis to see this is correct ;-) */
+  MEMCPY(&cs->cs_hdr, nb->payload, hlen);
+  cs->cs_hlen = (u16_t)hlen;
+  INCR(vjs_uncompressedin);
+  return 0;
+}
+
+/*
+ * Uncompress a packet of type TYPE_COMPRESSED_TCP.
+ * The packet is composed of a buffer chain and the first buffer
+ * must contain an accurate chain length.
+ * The first buffer must include the entire compressed TCP/IP header.
+ * This procedure replaces the compressed header with the uncompressed
+ * header and returns the length of the VJ header.
+ */
+int
+vj_uncompress_tcp(struct pbuf **nb, struct vjcompress *comp)
+{
+  u8_t *cp;
+  struct tcp_hdr *th;
+  struct cstate *cs;
+  struct vj_u16_t *bp;
+  struct pbuf *n0 = *nb;
+  u32_t tmp;
+  u32_t vjlen, hlen, changes;
+
+  INCR(vjs_compressedin);
+  cp = (u8_t*)n0->payload;
+  changes = *cp++;
+  if (changes & NEW_C) {
+    /*
+     * Make sure the state index is in range, then grab the state.
+     * If we have a good state index, clear the 'discard' flag.
+     */
+    if (*cp >= MAX_SLOTS) {
+      PPPDEBUG(LOG_INFO, ("vj_uncompress_tcp: bad cid=%d\n", *cp));
+      goto bad;
+    }
+
+    comp->flags &=~ VJF_TOSS;
+    comp->last_recv = *cp++;
+  } else {
+    /*
+     * this packet has an implicit state index.  If we've
+     * had a line error since the last time we got an
+     * explicit state index, we have to toss the packet.
+     */
+    if (comp->flags & VJF_TOSS) {
+      PPPDEBUG(LOG_INFO, ("vj_uncompress_tcp: tossing\n"));
+      INCR(vjs_tossed);
+      return (-1);
+    }
+  }
+  cs = &comp->rstate[comp->last_recv];
+  hlen = IPH_HL(&cs->cs_ip) << 2;
+  th = (struct tcp_hdr *)&((u8_t*)&cs->cs_ip)[hlen];
+  th->chksum = lwip_htons((*cp << 8) | cp[1]);
+  cp += 2;
+  if (changes & TCP_PUSH_BIT) {
+    TCPH_SET_FLAG(th, TCP_PSH);
+  } else {
+    TCPH_UNSET_FLAG(th, TCP_PSH);
+  }
+
+  switch (changes & SPECIALS_MASK) {
+  case SPECIAL_I:
+    {
+      u32_t i = lwip_ntohs(IPH_LEN(&cs->cs_ip)) - cs->cs_hlen;
+      /* some compilers can't nest inline assembler.. */
+      tmp = lwip_ntohl(th->ackno) + i;
+      th->ackno = lwip_htonl(tmp);
+      tmp = lwip_ntohl(th->seqno) + i;
+      th->seqno = lwip_htonl(tmp);
+    }
+    break;
+
+  case SPECIAL_D:
+    /* some compilers can't nest inline assembler.. */
+    tmp = lwip_ntohl(th->seqno) + lwip_ntohs(IPH_LEN(&cs->cs_ip)) - cs->cs_hlen;
+    th->seqno = lwip_htonl(tmp);
+    break;
+
+  default:
+    if (changes & NEW_U) {
+      TCPH_SET_FLAG(th, TCP_URG);
+      DECODEU(th->urgp);
+    } else {
+      TCPH_UNSET_FLAG(th, TCP_URG);
+    }
+    if (changes & NEW_W) {
+      DECODES(th->wnd);
+    }
+    if (changes & NEW_A) {
+      DECODEL(th->ackno);
+    }
+    if (changes & NEW_S) {
+      DECODEL(th->seqno);
+    }
+    break;
+  }
+  if (changes & NEW_I) {
+    DECODES(cs->cs_ip._id);
+  } else {
+    IPH_ID_SET(&cs->cs_ip, lwip_ntohs(IPH_ID(&cs->cs_ip)) + 1);
+    IPH_ID_SET(&cs->cs_ip, lwip_htons(IPH_ID(&cs->cs_ip)));
+  }
+
+  /*
+   * At this point, cp points to the first byte of data in the
+   * packet.  Fill in the IP total length and update the IP
+   * header checksum.
+   */
+  vjlen = (u16_t)(cp - (u8_t*)n0->payload);
+  if (n0->len < vjlen) {
+    /*
+     * We must have dropped some characters (crc should detect
+     * this but the old slip framing won't)
+     */
+    PPPDEBUG(LOG_INFO, ("vj_uncompress_tcp: head buffer %d too short %d\n",
+          n0->len, vjlen));
+    goto bad;
+  }
+
+#if BYTE_ORDER == LITTLE_ENDIAN
+  tmp = n0->tot_len - vjlen + cs->cs_hlen;
+  IPH_LEN_SET(&cs->cs_ip, lwip_htons((u16_t)tmp));
+#else
+  IPH_LEN_SET(&cs->cs_ip, lwip_htons(n0->tot_len - vjlen + cs->cs_hlen));
+#endif
+
+  /* recompute the ip header checksum */
+  bp = (struct vj_u16_t*) &cs->cs_ip;
+  IPH_CHKSUM_SET(&cs->cs_ip, 0);
+  for (tmp = 0; hlen > 0; hlen -= 2) {
+    tmp += (*bp++).v;
+  }
+  tmp = (tmp & 0xffff) + (tmp >> 16);
+  tmp = (tmp & 0xffff) + (tmp >> 16);
+  IPH_CHKSUM_SET(&cs->cs_ip,  (u16_t)(~tmp));
+
+  /* Remove the compressed header and prepend the uncompressed header. */
+  if (pbuf_remove_header(n0, vjlen)) {
+    /* Can we cope with this failing?  Just assert for now */
+    LWIP_ASSERT("pbuf_remove_header failed\n", 0);
+    goto bad;
+  }
+
+  if(LWIP_MEM_ALIGN(n0->payload) != n0->payload) {
+    struct pbuf *np;
+
+#if IP_FORWARD
+    /* If IP forwarding is enabled we are using a PBUF_LINK packet type so
+     * the packet is being allocated with enough header space to be
+     * forwarded (to Ethernet for example).
+     */
+    np = pbuf_alloc(PBUF_LINK, n0->len + cs->cs_hlen, PBUF_POOL);
+#else /* IP_FORWARD */
+    np = pbuf_alloc(PBUF_RAW, n0->len + cs->cs_hlen, PBUF_POOL);
+#endif /* IP_FORWARD */
+    if(!np) {
+      PPPDEBUG(LOG_WARNING, ("vj_uncompress_tcp: realign failed\n"));
+      goto bad;
+    }
+
+    if (pbuf_remove_header(np, cs->cs_hlen)) {
+      /* Can we cope with this failing?  Just assert for now */
+      LWIP_ASSERT("pbuf_remove_header failed\n", 0);
+      goto bad;
+    }
+
+    pbuf_take(np, n0->payload, n0->len);
+
+    if(n0->next) {
+      pbuf_chain(np, n0->next);
+      pbuf_dechain(n0);
+    }
+    pbuf_free(n0);
+    n0 = np;
+  }
+
+  if (pbuf_add_header(n0, cs->cs_hlen)) {
+    struct pbuf *np;
+
+    LWIP_ASSERT("vj_uncompress_tcp: cs->cs_hlen <= PBUF_POOL_BUFSIZE", cs->cs_hlen <= PBUF_POOL_BUFSIZE);
+    np = pbuf_alloc(PBUF_RAW, cs->cs_hlen, PBUF_POOL);
+    if(!np) {
+      PPPDEBUG(LOG_WARNING, ("vj_uncompress_tcp: prepend failed\n"));
+      goto bad;
+    }
+    pbuf_cat(np, n0);
+    n0 = np;
+  }
+  LWIP_ASSERT("n0->len >= cs->cs_hlen", n0->len >= cs->cs_hlen);
+  MEMCPY(n0->payload, &cs->cs_ip, cs->cs_hlen);
+
+  *nb = n0;
+
+  return vjlen;
+
+bad:
+  vj_uncompress_err(comp);
+  return (-1);
+}
+
+#endif /* PPP_SUPPORT && VJ_SUPPORT */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/netif/slipif.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/netif/slipif.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/netif/slipif.c	(revision 457)
@@ -0,0 +1,558 @@
+/**
+ * @file
+ * SLIP Interface
+ *
+ */
+
+/*
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
+ * 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 Institute 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 INSTITUTE 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 INSTITUTE 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.
+ *
+ * This file is built upon the file: src/arch/rtxc/netif/sioslip.c
+ *
+ * Author: Magnus Ivarsson <magnus.ivarsson(at)volvo.com>
+ *         Simon Goldschmidt
+ */
+
+
+/**
+ * @defgroup slipif SLIP
+ * @ingroup netifs
+ *
+ * This is an arch independent SLIP netif. The specific serial hooks must be
+ * provided by another file. They are sio_open, sio_read/sio_tryread and sio_send
+ *
+ * Usage: This netif can be used in three ways:\n
+ *        1) For NO_SYS==0, an RX thread can be used which blocks on sio_read()
+ *           until data is received.\n
+ *        2) In your main loop, call slipif_poll() to check for new RX bytes,
+ *           completed packets are fed into netif->input().\n
+ *        3) Call slipif_received_byte[s]() from your serial RX ISR and
+ *           slipif_process_rxqueue() from your main loop. ISR level decodes
+ *           packets and puts completed packets on a queue which is fed into
+ *           the stack from the main loop (needs SYS_LIGHTWEIGHT_PROT for
+ *           pbuf_alloc to work on ISR level!).
+ *
+ */
+
+#include "netif/slipif.h"
+#include "lwip/opt.h"
+
+#include "lwip/def.h"
+#include "lwip/pbuf.h"
+#include "lwip/stats.h"
+#include "lwip/snmp.h"
+#include "lwip/sys.h"
+#include "lwip/sio.h"
+
+#define SLIP_END     0xC0 /* 0300: start and end of every packet */
+#define SLIP_ESC     0xDB /* 0333: escape start (one byte escaped data follows) */
+#define SLIP_ESC_END 0xDC /* 0334: following escape: original byte is 0xC0 (END) */
+#define SLIP_ESC_ESC 0xDD /* 0335: following escape: original byte is 0xDB (ESC) */
+
+/** Maximum packet size that is received by this netif */
+#ifndef SLIP_MAX_SIZE
+#define SLIP_MAX_SIZE 1500
+#endif
+
+/** Define this to the interface speed for SNMP
+ * (sio_fd is the sio_fd_t returned by sio_open).
+ * The default value of zero means 'unknown'.
+ */
+#ifndef SLIP_SIO_SPEED
+#define SLIP_SIO_SPEED(sio_fd) 0
+#endif
+
+enum slipif_recv_state {
+  SLIP_RECV_NORMAL,
+  SLIP_RECV_ESCAPE
+};
+
+struct slipif_priv {
+  sio_fd_t sd;
+  /* q is the whole pbuf chain for a packet, p is the current pbuf in the chain */
+  struct pbuf *p, *q;
+  u8_t state;
+  u16_t i, recved;
+#if SLIP_RX_FROM_ISR
+  struct pbuf *rxpackets;
+#endif
+};
+
+/**
+ * Send a pbuf doing the necessary SLIP encapsulation
+ *
+ * Uses the serial layer's sio_send()
+ *
+ * @param netif the lwip network interface structure for this slipif
+ * @param p the pbuf chain packet to send
+ * @return always returns ERR_OK since the serial layer does not provide return values
+ */
+static err_t
+slipif_output(struct netif *netif, struct pbuf *p)
+{
+  struct slipif_priv *priv;
+  struct pbuf *q;
+  u16_t i;
+  u8_t c;
+
+  LWIP_ASSERT("netif != NULL", (netif != NULL));
+  LWIP_ASSERT("netif->state != NULL", (netif->state != NULL));
+  LWIP_ASSERT("p != NULL", (p != NULL));
+
+  LWIP_DEBUGF(SLIP_DEBUG, ("slipif_output: sending %"U16_F" bytes\n", p->tot_len));
+  priv = (struct slipif_priv *)netif->state;
+
+  /* Send pbuf out on the serial I/O device. */
+  /* Start with packet delimiter. */
+  sio_send(SLIP_END, priv->sd);
+
+  for (q = p; q != NULL; q = q->next) {
+    for (i = 0; i < q->len; i++) {
+      c = ((u8_t *)q->payload)[i];
+      switch (c) {
+        case SLIP_END:
+          /* need to escape this byte (0xC0 -> 0xDB, 0xDC) */
+          sio_send(SLIP_ESC, priv->sd);
+          sio_send(SLIP_ESC_END, priv->sd);
+          break;
+        case SLIP_ESC:
+          /* need to escape this byte (0xDB -> 0xDB, 0xDD) */
+          sio_send(SLIP_ESC, priv->sd);
+          sio_send(SLIP_ESC_ESC, priv->sd);
+          break;
+        default:
+          /* normal byte - no need for escaping */
+          sio_send(c, priv->sd);
+          break;
+      }
+    }
+  }
+  /* End with packet delimiter. */
+  sio_send(SLIP_END, priv->sd);
+  return ERR_OK;
+}
+
+#if LWIP_IPV4
+/**
+ * Send a pbuf doing the necessary SLIP encapsulation
+ *
+ * Uses the serial layer's sio_send()
+ *
+ * @param netif the lwip network interface structure for this slipif
+ * @param p the pbuf chain packet to send
+ * @param ipaddr the ip address to send the packet to (not used for slipif)
+ * @return always returns ERR_OK since the serial layer does not provide return values
+ */
+static err_t
+slipif_output_v4(struct netif *netif, struct pbuf *p, const ip4_addr_t *ipaddr)
+{
+  LWIP_UNUSED_ARG(ipaddr);
+  return slipif_output(netif, p);
+}
+#endif /* LWIP_IPV4 */
+
+#if LWIP_IPV6
+/**
+ * Send a pbuf doing the necessary SLIP encapsulation
+ *
+ * Uses the serial layer's sio_send()
+ *
+ * @param netif the lwip network interface structure for this slipif
+ * @param p the pbuf chain packet to send
+ * @param ipaddr the ip address to send the packet to (not used for slipif)
+ * @return always returns ERR_OK since the serial layer does not provide return values
+ */
+static err_t
+slipif_output_v6(struct netif *netif, struct pbuf *p, const ip6_addr_t *ipaddr)
+{
+  LWIP_UNUSED_ARG(ipaddr);
+  return slipif_output(netif, p);
+}
+#endif /* LWIP_IPV6 */
+
+/**
+ * Handle the incoming SLIP stream character by character
+ *
+ * @param netif the lwip network interface structure for this slipif
+ * @param c received character (multiple calls to this function will
+ *        return a complete packet, NULL is returned before - used for polling)
+ * @return The IP packet when SLIP_END is received
+ */
+static struct pbuf *
+slipif_rxbyte(struct netif *netif, u8_t c)
+{
+  struct slipif_priv *priv;
+  struct pbuf *t;
+
+  LWIP_ASSERT("netif != NULL", (netif != NULL));
+  LWIP_ASSERT("netif->state != NULL", (netif->state != NULL));
+
+  priv = (struct slipif_priv *)netif->state;
+
+  switch (priv->state) {
+    case SLIP_RECV_NORMAL:
+      switch (c) {
+        case SLIP_END:
+          if (priv->recved > 0) {
+            /* Received whole packet. */
+            /* Trim the pbuf to the size of the received packet. */
+            pbuf_realloc(priv->q, priv->recved);
+
+            LINK_STATS_INC(link.recv);
+
+            LWIP_DEBUGF(SLIP_DEBUG, ("slipif: Got packet (%"U16_F" bytes)\n", priv->recved));
+            t = priv->q;
+            priv->p = priv->q = NULL;
+            priv->i = priv->recved = 0;
+            return t;
+          }
+          return NULL;
+        case SLIP_ESC:
+          priv->state = SLIP_RECV_ESCAPE;
+          return NULL;
+        default:
+          break;
+      } /* end switch (c) */
+      break;
+    case SLIP_RECV_ESCAPE:
+      /* un-escape END or ESC bytes, leave other bytes
+         (although that would be a protocol error) */
+      switch (c) {
+        case SLIP_ESC_END:
+          c = SLIP_END;
+          break;
+        case SLIP_ESC_ESC:
+          c = SLIP_ESC;
+          break;
+        default:
+          break;
+      }
+      priv->state = SLIP_RECV_NORMAL;
+      break;
+    default:
+      break;
+  } /* end switch (priv->state) */
+
+  /* byte received, packet not yet completely received */
+  if (priv->p == NULL) {
+    /* allocate a new pbuf */
+    LWIP_DEBUGF(SLIP_DEBUG, ("slipif_input: alloc\n"));
+    priv->p = pbuf_alloc(PBUF_LINK, (PBUF_POOL_BUFSIZE - PBUF_LINK_HLEN - PBUF_LINK_ENCAPSULATION_HLEN), PBUF_POOL);
+
+    if (priv->p == NULL) {
+      LINK_STATS_INC(link.drop);
+      LWIP_DEBUGF(SLIP_DEBUG, ("slipif_input: no new pbuf! (DROP)\n"));
+      /* don't process any further since we got no pbuf to receive to */
+      return NULL;
+    }
+
+    if (priv->q != NULL) {
+      /* 'chain' the pbuf to the existing chain */
+      pbuf_cat(priv->q, priv->p);
+    } else {
+      /* p is the first pbuf in the chain */
+      priv->q = priv->p;
+    }
+  }
+
+  /* this automatically drops bytes if > SLIP_MAX_SIZE */
+  if ((priv->p != NULL) && (priv->recved <= SLIP_MAX_SIZE)) {
+    ((u8_t *)priv->p->payload)[priv->i] = c;
+    priv->recved++;
+    priv->i++;
+    if (priv->i >= priv->p->len) {
+      /* on to the next pbuf */
+      priv->i = 0;
+      if (priv->p->next != NULL && priv->p->next->len > 0) {
+        /* p is a chain, on to the next in the chain */
+        priv->p = priv->p->next;
+      } else {
+        /* p is a single pbuf, set it to NULL so next time a new
+         * pbuf is allocated */
+        priv->p = NULL;
+      }
+    }
+  }
+  return NULL;
+}
+
+/** Like slipif_rxbyte, but passes completed packets to netif->input
+ *
+ * @param netif The lwip network interface structure for this slipif
+ * @param c received character
+ */
+static void
+slipif_rxbyte_input(struct netif *netif, u8_t c)
+{
+  struct pbuf *p;
+  p = slipif_rxbyte(netif, c);
+  if (p != NULL) {
+    if (netif->input(p, netif) != ERR_OK) {
+      pbuf_free(p);
+    }
+  }
+}
+
+#if SLIP_USE_RX_THREAD
+/**
+ * The SLIP input thread.
+ *
+ * Feed the IP layer with incoming packets
+ *
+ * @param nf the lwip network interface structure for this slipif
+ */
+static void
+slipif_loop_thread(void *nf)
+{
+  u8_t c;
+  struct netif *netif = (struct netif *)nf;
+  struct slipif_priv *priv = (struct slipif_priv *)netif->state;
+
+  while (1) {
+    if (sio_read(priv->sd, &c, 1) > 0) {
+      slipif_rxbyte_input(netif, c);
+    }
+  }
+}
+#endif /* SLIP_USE_RX_THREAD */
+
+/**
+ * @ingroup slipif
+ * SLIP netif initialization
+ *
+ * Call the arch specific sio_open and remember
+ * the opened device in the state field of the netif.
+ *
+ * @param netif the lwip network interface structure for this slipif
+ * @return ERR_OK if serial line could be opened,
+ *         ERR_MEM if no memory could be allocated,
+ *         ERR_IF is serial line couldn't be opened
+ *
+ * @note If netif->state is interpreted as an u8_t serial port number.
+ *
+ */
+err_t
+slipif_init(struct netif *netif)
+{
+  struct slipif_priv *priv;
+  u8_t sio_num;
+
+  LWIP_ASSERT("slipif needs an input callback", netif->input != NULL);
+
+  /* netif->state contains serial port number */
+  sio_num = LWIP_PTR_NUMERIC_CAST(u8_t, netif->state);
+
+  LWIP_DEBUGF(SLIP_DEBUG, ("slipif_init: netif->num=%"U16_F"\n", (u16_t)sio_num));
+
+  /* Allocate private data */
+  priv = (struct slipif_priv *)mem_malloc(sizeof(struct slipif_priv));
+  if (!priv) {
+    return ERR_MEM;
+  }
+
+  netif->name[0] = 's';
+  netif->name[1] = 'l';
+#if LWIP_IPV4
+  netif->output = slipif_output_v4;
+#endif /* LWIP_IPV4 */
+#if LWIP_IPV6
+  netif->output_ip6 = slipif_output_v6;
+#endif /* LWIP_IPV6 */
+  netif->mtu = SLIP_MAX_SIZE;
+
+  /* Try to open the serial port. */
+  priv->sd = sio_open(sio_num);
+  if (!priv->sd) {
+    /* Opening the serial port failed. */
+    mem_free(priv);
+    return ERR_IF;
+  }
+
+  /* Initialize private data */
+  priv->p = NULL;
+  priv->q = NULL;
+  priv->state = SLIP_RECV_NORMAL;
+  priv->i = 0;
+  priv->recved = 0;
+#if SLIP_RX_FROM_ISR
+  priv->rxpackets = NULL;
+#endif
+
+  netif->state = priv;
+
+  /* initialize the snmp variables and counters inside the struct netif */
+  MIB2_INIT_NETIF(netif, snmp_ifType_slip, SLIP_SIO_SPEED(priv->sd));
+
+#if SLIP_USE_RX_THREAD
+  /* Create a thread to poll the serial line. */
+  sys_thread_new(SLIPIF_THREAD_NAME, slipif_loop_thread, netif,
+                 SLIPIF_THREAD_STACKSIZE, SLIPIF_THREAD_PRIO);
+#endif /* SLIP_USE_RX_THREAD */
+  return ERR_OK;
+}
+
+/**
+ * @ingroup slipif
+ * Polls the serial device and feeds the IP layer with incoming packets.
+ *
+ * @param netif The lwip network interface structure for this slipif
+ */
+void
+slipif_poll(struct netif *netif)
+{
+  u8_t c;
+  struct slipif_priv *priv;
+
+  LWIP_ASSERT("netif != NULL", (netif != NULL));
+  LWIP_ASSERT("netif->state != NULL", (netif->state != NULL));
+
+  priv = (struct slipif_priv *)netif->state;
+
+  while (sio_tryread(priv->sd, &c, 1) > 0) {
+    slipif_rxbyte_input(netif, c);
+  }
+}
+
+#if SLIP_RX_FROM_ISR
+/**
+ * @ingroup slipif
+ * Feeds the IP layer with incoming packets that were receive
+ *
+ * @param netif The lwip network interface structure for this slipif
+ */
+void
+slipif_process_rxqueue(struct netif *netif)
+{
+  struct slipif_priv *priv;
+  SYS_ARCH_DECL_PROTECT(old_level);
+
+  LWIP_ASSERT("netif != NULL", (netif != NULL));
+  LWIP_ASSERT("netif->state != NULL", (netif->state != NULL));
+
+  priv = (struct slipif_priv *)netif->state;
+
+  SYS_ARCH_PROTECT(old_level);
+  while (priv->rxpackets != NULL) {
+    struct pbuf *p = priv->rxpackets;
+#if SLIP_RX_QUEUE
+    /* dequeue packet */
+    struct pbuf *q = p;
+    while ((q->len != q->tot_len) && (q->next != NULL)) {
+      q = q->next;
+    }
+    priv->rxpackets = q->next;
+    q->next = NULL;
+#else /* SLIP_RX_QUEUE */
+    priv->rxpackets = NULL;
+#endif /* SLIP_RX_QUEUE */
+    SYS_ARCH_UNPROTECT(old_level);
+    if (netif->input(p, netif) != ERR_OK) {
+      pbuf_free(p);
+    }
+    SYS_ARCH_PROTECT(old_level);
+  }
+  SYS_ARCH_UNPROTECT(old_level);
+}
+
+/** Like slipif_rxbyte, but queues completed packets.
+ *
+ * @param netif The lwip network interface structure for this slipif
+ * @param data Received serial byte
+ */
+static void
+slipif_rxbyte_enqueue(struct netif *netif, u8_t data)
+{
+  struct pbuf *p;
+  struct slipif_priv *priv = (struct slipif_priv *)netif->state;
+  SYS_ARCH_DECL_PROTECT(old_level);
+
+  p = slipif_rxbyte(netif, data);
+  if (p != NULL) {
+    SYS_ARCH_PROTECT(old_level);
+    if (priv->rxpackets != NULL) {
+#if SLIP_RX_QUEUE
+      /* queue multiple pbufs */
+      struct pbuf *q = p;
+      while (q->next != NULL) {
+        q = q->next;
+      }
+      q->next = p;
+    } else {
+#else /* SLIP_RX_QUEUE */
+      pbuf_free(priv->rxpackets);
+    }
+    {
+#endif /* SLIP_RX_QUEUE */
+      priv->rxpackets = p;
+    }
+    SYS_ARCH_UNPROTECT(old_level);
+  }
+}
+
+/**
+ * @ingroup slipif
+ * Process a received byte, completed packets are put on a queue that is
+ * fed into IP through slipif_process_rxqueue().
+ *
+ * This function can be called from ISR if SYS_LIGHTWEIGHT_PROT is enabled.
+ *
+ * @param netif The lwip network interface structure for this slipif
+ * @param data received character
+ */
+void
+slipif_received_byte(struct netif *netif, u8_t data)
+{
+  LWIP_ASSERT("netif != NULL", (netif != NULL));
+  LWIP_ASSERT("netif->state != NULL", (netif->state != NULL));
+  slipif_rxbyte_enqueue(netif, data);
+}
+
+/**
+ * @ingroup slipif
+ * Process multiple received byte, completed packets are put on a queue that is
+ * fed into IP through slipif_process_rxqueue().
+ *
+ * This function can be called from ISR if SYS_LIGHTWEIGHT_PROT is enabled.
+ *
+ * @param netif The lwip network interface structure for this slipif
+ * @param data received character
+ * @param len Number of received characters
+ */
+void
+slipif_received_bytes(struct netif *netif, u8_t *data, u8_t len)
+{
+  u8_t i;
+  u8_t *rxdata = data;
+  LWIP_ASSERT("netif != NULL", (netif != NULL));
+  LWIP_ASSERT("netif->state != NULL", (netif->state != NULL));
+
+  for (i = 0; i < len; i++, rxdata++) {
+    slipif_rxbyte_enqueue(netif, *rxdata);
+  }
+}
+#endif /* SLIP_RX_FROM_ISR */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/netif/zepif.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/netif/zepif.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/netif/zepif.c	(revision 457)
@@ -0,0 +1,300 @@
+/**
+ * @file
+ *
+ * @defgroup zepif ZEP - ZigBee Encapsulation Protocol
+ * @ingroup netifs
+ * A netif implementing the ZigBee Encapsulation Protocol (ZEP).
+ * This is used to tunnel 6LowPAN over UDP.
+ *
+ * Usage (there must be a default netif before!):
+ * @code{.c}
+ *   netif_add(&zep_netif, NULL, NULL, NULL, NULL, zepif_init, tcpip_6lowpan_input);
+ *   netif_create_ip6_linklocal_address(&zep_netif, 1);
+ *   netif_set_up(&zep_netif);
+ *   netif_set_link_up(&zep_netif);
+ * @endcode
+ */
+
+/*
+ * Copyright (c) 2018 Simon Goldschmidt
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Simon Goldschmidt <goldsimon@gmx.de>
+ *
+ */
+
+#include "netif/zepif.h"
+
+#if LWIP_IPV6 && LWIP_UDP
+
+#include "netif/lowpan6.h"
+#include "lwip/udp.h"
+#include "lwip/timeouts.h"
+#include <string.h>
+
+/** Define this to 1 to loop back TX packets for testing */
+#ifndef ZEPIF_LOOPBACK
+#define ZEPIF_LOOPBACK    0
+#endif
+
+#define ZEP_MAX_DATA_LEN  127
+
+#ifdef PACK_STRUCT_USE_INCLUDES
+#  include "arch/bpstruct.h"
+#endif
+PACK_STRUCT_BEGIN
+struct zep_hdr {
+  PACK_STRUCT_FLD_8(u8_t prot_id[2]);
+  PACK_STRUCT_FLD_8(u8_t prot_version);
+  PACK_STRUCT_FLD_8(u8_t type);
+  PACK_STRUCT_FLD_8(u8_t channel_id);
+  PACK_STRUCT_FIELD(u16_t device_id);
+  PACK_STRUCT_FLD_8(u8_t crc_mode);
+  PACK_STRUCT_FLD_8(u8_t unknown_1);
+  PACK_STRUCT_FIELD(u32_t timestamp[2]);
+  PACK_STRUCT_FIELD(u32_t seq_num);
+  PACK_STRUCT_FLD_8(u8_t unknown_2[10]);
+  PACK_STRUCT_FLD_8(u8_t len);
+} PACK_STRUCT_STRUCT;
+PACK_STRUCT_END
+#ifdef PACK_STRUCT_USE_INCLUDES
+#  include "arch/epstruct.h"
+#endif
+
+struct zepif_state {
+  struct zepif_init init;
+  struct udp_pcb *pcb;
+  u32_t seqno;
+};
+
+static u8_t zep_lowpan_timer_running;
+
+/* Helper function that calls the 6LoWPAN timer and reschedules itself */
+static void
+zep_lowpan_timer(void *arg)
+{
+  lowpan6_tmr();
+  if (zep_lowpan_timer_running) {
+    sys_timeout(LOWPAN6_TMR_INTERVAL, zep_lowpan_timer, arg);
+  }
+}
+
+/* Pass received pbufs into 6LowPAN netif */
+static void
+zepif_udp_recv(void *arg, struct udp_pcb *pcb, struct pbuf *p,
+               const ip_addr_t *addr, u16_t port)
+{
+  err_t err;
+  struct netif *netif_lowpan6 = (struct netif *)arg;
+  struct zep_hdr *zep;
+
+  LWIP_ASSERT("arg != NULL", arg != NULL);
+  LWIP_ASSERT("pcb != NULL", pcb != NULL);
+  LWIP_UNUSED_ARG(pcb); /* for LWIP_NOASSERT */
+  LWIP_UNUSED_ARG(addr);
+  LWIP_UNUSED_ARG(port);
+  if (p == NULL) {
+    return;
+  }
+
+  /* Parse and hide the ZEP header */
+  if (p->len < sizeof(struct zep_hdr)) {
+    /* need the zep_hdr in one piece */
+    goto err_return;
+  }
+  zep = (struct zep_hdr *)p->payload;
+  if (zep->prot_id[0] != 'E') {
+    goto err_return;
+  }
+  if (zep->prot_id[1] != 'X') {
+    goto err_return;
+  }
+  if (zep->prot_version != 2) {
+    /* we only support this version for now */
+    goto err_return;
+  }
+  if (zep->type != 1) {
+    goto err_return;
+  }
+  if (zep->crc_mode != 1) {
+    goto err_return;
+  }
+  if (zep->len != p->tot_len - sizeof(struct zep_hdr)) {
+    goto err_return;
+  }
+  /* everything seems to be OK, hide the ZEP header */
+  if (pbuf_remove_header(p, sizeof(struct zep_hdr))) {
+    goto err_return;
+  }
+  /* TODO Check CRC? */
+  /* remove CRC trailer */
+  pbuf_realloc(p, p->tot_len - 2);
+
+  /* Call into 6LoWPAN code. */
+  err = netif_lowpan6->input(p, netif_lowpan6);
+  if (err == ERR_OK) {
+    return;
+  }
+err_return:
+  pbuf_free(p);
+}
+
+/* Send 6LoWPAN TX packets as UDP broadcast */
+static err_t
+zepif_linkoutput(struct netif *netif, struct pbuf *p)
+{
+  err_t err;
+  struct pbuf *q;
+  struct zep_hdr *zep;
+  struct zepif_state *state;
+
+  LWIP_ASSERT("invalid netif", netif != NULL);
+  LWIP_ASSERT("invalid pbuf", p != NULL);
+
+  if (p->tot_len > ZEP_MAX_DATA_LEN) {
+    return ERR_VAL;
+  }
+  LWIP_ASSERT("TODO: support chained pbufs", p->next == NULL);
+
+  state = (struct zepif_state *)netif->state;
+  LWIP_ASSERT("state->pcb != NULL", state->pcb != NULL);
+
+  q = pbuf_alloc(PBUF_TRANSPORT, sizeof(struct zep_hdr) + p->tot_len, PBUF_RAM);
+  if (q == NULL) {
+    return ERR_MEM;
+  }
+  zep = (struct zep_hdr *)q->payload;
+  memset(zep, 0, sizeof(struct zep_hdr));
+  zep->prot_id[0] = 'E';
+  zep->prot_id[1] = 'X';
+  zep->prot_version = 2;
+  zep->type = 1; /* Data */
+  zep->channel_id = 0; /* whatever */
+  zep->device_id = lwip_htons(1); /* whatever */
+  zep->crc_mode = 1;
+  zep->unknown_1 = 0xff;
+  zep->seq_num = lwip_htonl(state->seqno);
+  state->seqno++;
+  zep->len = (u8_t)p->tot_len;
+
+  err = pbuf_take_at(q, p->payload, p->tot_len, sizeof(struct zep_hdr));
+  if (err == ERR_OK) {
+#if ZEPIF_LOOPBACK
+    zepif_udp_recv(netif, state->pcb, pbuf_clone(PBUF_RAW, PBUF_RAM, q), NULL, 0);
+#endif
+    err = udp_sendto(state->pcb, q, state->init.zep_dst_ip_addr, state->init.zep_dst_udp_port);
+  }
+  pbuf_free(q);
+
+  return err;
+}
+
+/**
+ * @ingroup zepif
+ * Set up a raw 6LowPAN netif and surround it with input- and output
+ * functions for ZEP
+ */
+err_t
+zepif_init(struct netif *netif)
+{
+  err_t err;
+  struct zepif_init *init_state = (struct zepif_init *)netif->state;
+  struct zepif_state *state = (struct zepif_state *)mem_malloc(sizeof(struct zepif_state));
+
+  LWIP_ASSERT("zepif needs an input callback", netif->input != NULL);
+
+  if (state == NULL) {
+    return ERR_MEM;
+  }
+  memset(state, 0, sizeof(struct zepif_state));
+  if (init_state != NULL) {
+    memcpy(&state->init, init_state, sizeof(struct zepif_init));
+  }
+  if (state->init.zep_src_udp_port == 0) {
+    state->init.zep_src_udp_port = ZEPIF_DEFAULT_UDP_PORT;
+  }
+  if (state->init.zep_dst_udp_port == 0) {
+    state->init.zep_dst_udp_port = ZEPIF_DEFAULT_UDP_PORT;
+  }
+#if LWIP_IPV4
+  if (state->init.zep_dst_ip_addr == NULL) {
+    /* With IPv4 enabled, default to broadcasting packets if no address is set */
+    state->init.zep_dst_ip_addr = IP_ADDR_BROADCAST;
+  }
+#endif /* LWIP_IPV4 */
+
+  netif->state = NULL;
+
+  state->pcb = udp_new_ip_type(IPADDR_TYPE_ANY);
+  if (state->pcb == NULL) {
+    err = ERR_MEM;
+    goto err_ret;
+  }
+  err = udp_bind(state->pcb, state->init.zep_src_ip_addr, state->init.zep_src_udp_port);
+  if (err != ERR_OK) {
+    goto err_ret;
+  }
+  if (state->init.zep_netif != NULL) {
+    udp_bind_netif(state->pcb, state->init.zep_netif);
+  }
+  LWIP_ASSERT("udp_bind(lowpan6_broadcast_pcb) failed", err == ERR_OK);
+  ip_set_option(state->pcb, SOF_BROADCAST);
+  udp_recv(state->pcb, zepif_udp_recv, netif);
+
+  err = lowpan6_if_init(netif);
+  LWIP_ASSERT("lowpan6_if_init set a state", netif->state == NULL);
+  if (err == ERR_OK) {
+    netif->state = state;
+    netif->hwaddr_len = 6;
+    if (init_state != NULL) {
+      memcpy(netif->hwaddr, init_state->addr, 6);
+    } else {
+      u8_t i;
+      for (i = 0; i < 6; i++) {
+        netif->hwaddr[i] = i;
+      }
+      netif->hwaddr[0] &= 0xfc;
+    }
+    netif->linkoutput = zepif_linkoutput;
+
+    if (!zep_lowpan_timer_running) {
+      sys_timeout(LOWPAN6_TMR_INTERVAL, zep_lowpan_timer, NULL);
+      zep_lowpan_timer_running = 1;
+    }
+
+    return ERR_OK;
+  }
+
+err_ret:
+  if (state->pcb != NULL) {
+    udp_remove(state->pcb);
+  }
+  mem_free(state);
+  return err;
+}
+
+#endif /* LWIP_IPV6 && LWIP_UDP */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/test/fuzz/Makefile
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/test/fuzz/Makefile	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/test/fuzz/Makefile	(revision 457)
@@ -0,0 +1,54 @@
+#
+# Copyright (c) 2001, 2002 Swedish Institute of Computer Science.
+# 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. The name of the author may not be used to endorse or promote products
+#    derived from this software without specific prior written permission. 
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+#
+# This file is part of the lwIP TCP/IP stack.
+# 
+# Author: Adam Dunkels <adam@sics.se>
+#
+
+all compile: lwip_fuzz
+.PHONY: all clean
+
+CC=afl-gcc
+LDFLAGS=-lm
+# use 'make D=-DUSER_DEFINE' to pass a user define to gcc
+CFLAGS=-O0 $(D)
+
+CONTRIBDIR=../../../lwip-contrib
+include $(CONTRIBDIR)/ports/unix/Common.mk
+
+clean:
+	rm -f *.o $(LWIPLIBCOMMON) $(APPLIB) lwip_fuzz *.s .depend* *.core core
+
+depend dep: .depend
+
+include .depend
+
+.depend: fuzz.c $(LWIPFILES) $(APPFILES)
+	$(CCDEP) $(CFLAGS) -MM $^ > .depend || rm -f .depend
+
+lwip_fuzz: .depend $(LWIPLIBCOMMON) $(APPLIB) fuzz.o
+	$(CC) $(CFLAGS) -o lwip_fuzz fuzz.o $(APPLIB) $(LWIPLIBCOMMON) $(LDFLAGS)
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/test/fuzz/README
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/test/fuzz/README	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/test/fuzz/README	(revision 457)
@@ -0,0 +1,37 @@
+
+Fuzzing the lwIP stack (afl-fuzz requires linux/unix or similar)
+
+This directory contains a small app that reads Ethernet frames from stdin and
+processes them. It is used together with the 'american fuzzy lop' tool (found
+at http://lcamtuf.coredump.cx/afl/) and the sample inputs to test how
+unexpected inputs are handled. The afl tool will read the known inputs, and
+try to modify them to exercise as many code paths as possible, by instrumenting
+the code and keeping track of which code is executed.
+
+Just running make will produce the test program.
+
+Running make with parameter 'D=-DLWIP_FUZZ_MULTI_PACKET' will produce a binary
+that parses the input data as multiple packets (experimental!).
+
+Then run afl with:
+
+afl-fuzz -i inputs/<INPUT> -o output ./lwip_fuzz
+
+and it should start working. It will probably complain about CPU scheduler,
+set AFL_SKIP_CPUFREQ=1 to ignore it.
+If it complains about invalid "/proc/sys/kernel/core_pattern" setting, try
+executing "sudo bash -c 'echo core > /proc/sys/kernel/core_pattern'".
+
+The input is split into different subdirectories since they test different
+parts of the code, and since you want to run one instance of afl-fuzz on each
+core.
+
+When afl finds a crash or a hang, the input that caused it will be placed in
+the output directory. If you have hexdump and text2pcap tools installed,
+running output_to_pcap.sh <outputdir> will create pcap files for each input
+file to simplify viewing in wireshark.
+
+The lwipopts.h file needs to have checksum checking off, otherwise almost every
+packet will be discarded because of that. The other options can be tuned to
+expose different parts of the code.
+
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/test/fuzz/fuzz.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/test/fuzz/fuzz.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/test/fuzz/fuzz.c	(revision 457)
@@ -0,0 +1,189 @@
+/*
+ * Copyright (c) 2001-2003 Swedish Institute of Computer Science.
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission. 
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ * 
+ * Author: Erik Ekman <erik@kryo.se>
+ *
+ */
+
+#include "lwip/init.h"
+#include "lwip/netif.h"
+#include "lwip/dns.h"
+#include "netif/etharp.h"
+#if LWIP_IPV6
+#include "lwip/ethip6.h"
+#include "lwip/nd6.h"
+#endif
+
+#include "lwip/apps/httpd.h"
+#include "lwip/apps/snmp.h"
+#include "lwip/apps/lwiperf.h"
+#include "lwip/apps/mdns.h"
+
+#include <string.h>
+#include <stdio.h>
+
+/* This define enables multi packet processing.
+ * For this, the input is interpreted as 2 byte length + data + 2 byte length + data...
+ * #define LWIP_FUZZ_MULTI_PACKET
+*/
+#ifdef LWIP_FUZZ_MULTI_PACKET
+u8_t pktbuf[20000];
+#else
+u8_t pktbuf[2000];
+#endif
+
+/* no-op send function */
+static err_t lwip_tx_func(struct netif *netif, struct pbuf *p)
+{
+  LWIP_UNUSED_ARG(netif);
+  LWIP_UNUSED_ARG(p);
+  return ERR_OK;
+}
+
+static err_t testif_init(struct netif *netif)
+{
+  netif->name[0] = 'f';
+  netif->name[1] = 'z';
+  netif->output = etharp_output;
+  netif->linkoutput = lwip_tx_func;
+  netif->mtu = 1500;
+  netif->hwaddr_len = 6;
+  netif->flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP | NETIF_FLAG_IGMP;
+
+  netif->hwaddr[0] = 0x00;
+  netif->hwaddr[1] = 0x23;
+  netif->hwaddr[2] = 0xC1;
+  netif->hwaddr[3] = 0xDE;
+  netif->hwaddr[4] = 0xD0;
+  netif->hwaddr[5] = 0x0D;
+
+#if LWIP_IPV6
+  netif->output_ip6 = ethip6_output;
+  netif->ip6_autoconfig_enabled = 1;
+  netif_create_ip6_linklocal_address(netif, 1);
+  netif->flags |= NETIF_FLAG_MLD6;
+#endif
+
+  return ERR_OK;
+}
+
+static void input_pkt(struct netif *netif, const u8_t *data, size_t len)
+{
+  struct pbuf *p, *q;
+  err_t err;
+
+  LWIP_ASSERT("pkt too big", len <= 0xFFFF);
+  p = pbuf_alloc(PBUF_RAW, (u16_t)len, PBUF_POOL);
+  LWIP_ASSERT("alloc failed", p);
+  for(q = p; q != NULL; q = q->next) {
+    MEMCPY(q->payload, data, q->len);
+    data += q->len;
+  }
+  err = netif->input(p, netif);
+  if (err != ERR_OK) {
+    pbuf_free(p);
+  }
+}
+
+static void input_pkts(struct netif *netif, const u8_t *data, size_t len)
+{
+#ifdef LWIP_FUZZ_MULTI_PACKET
+  const u16_t max_packet_size = 1514;
+  const u8_t *ptr = data;
+  size_t rem_len = len;
+
+  while (rem_len > sizeof(u16_t)) {
+    u16_t frame_len;
+    memcpy(&frame_len, ptr, sizeof(u16_t));
+    ptr += sizeof(u16_t);
+    rem_len -= sizeof(u16_t);
+    frame_len = htons(frame_len) & 0x7FF;
+    frame_len = LWIP_MIN(frame_len, max_packet_size);
+    if (frame_len > rem_len) {
+      frame_len = (u16_t)rem_len;
+    }
+    if (frame_len != 0) {
+      input_pkt(netif, ptr, frame_len);
+    }
+    ptr += frame_len;
+    rem_len -= frame_len;
+  }
+#else /* LWIP_FUZZ_MULTI_PACKET */
+  input_pkt(netif, data, len);
+#endif /* LWIP_FUZZ_MULTI_PACKET */
+}
+
+int main(int argc, char** argv)
+{
+  struct netif net_test;
+  ip4_addr_t addr;
+  ip4_addr_t netmask;
+  ip4_addr_t gw;
+  size_t len;
+
+  lwip_init();
+
+  IP4_ADDR(&addr, 172, 30, 115, 84);
+  IP4_ADDR(&netmask, 255, 255, 255, 0);
+  IP4_ADDR(&gw, 172, 30, 115, 1);
+
+  netif_add(&net_test, &addr, &netmask, &gw, &net_test, testif_init, ethernet_input);
+  netif_set_up(&net_test);
+  netif_set_link_up(&net_test);
+
+#if LWIP_IPV6
+  nd6_tmr(); /* tick nd to join multicast groups */
+#endif
+  dns_setserver(0, &net_test.gw);
+
+  /* initialize apps */
+  httpd_init();
+  lwiperf_start_tcp_server_default(NULL, NULL);
+  mdns_resp_init();
+  mdns_resp_add_netif(&net_test, "hostname", 255);
+  snmp_init();
+
+  if(argc > 1) {
+    FILE* f;
+    const char* filename;
+    printf("reading input from file... ");
+    fflush(stdout);
+    filename = argv[1];
+    LWIP_ASSERT("invalid filename", filename != NULL);
+    f = fopen(filename, "rb");
+    LWIP_ASSERT("open failed", f != NULL);
+    len = fread(pktbuf, 1, sizeof(pktbuf), f);
+    fclose(f);
+    printf("testing file: \"%s\"...\r\n", filename);
+  } else {
+    len = fread(pktbuf, 1, sizeof(pktbuf), stdin);
+  }
+  input_pkts(&net_test, pktbuf, len);
+
+  return 0;
+}
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/test/fuzz/lwipopts.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/test/fuzz/lwipopts.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/test/fuzz/lwipopts.h	(revision 457)
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 2001-2003 Swedish Institute of Computer Science.
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission. 
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ * 
+ * Author: Simon Goldschmidt
+ *
+ */
+#ifndef LWIP_HDR_LWIPOPTS_H__
+#define LWIP_HDR_LWIPOPTS_H__
+
+/* Prevent having to link sys_arch.c (we don't test the API layers in unit tests) */
+#define NO_SYS                          1
+#define LWIP_NETCONN                    0
+#define LWIP_SOCKET                     0
+#define SYS_LIGHTWEIGHT_PROT            0
+
+#define LWIP_IPV6                       1
+#define IPV6_FRAG_COPYHEADER            1
+#define LWIP_IPV6_DUP_DETECT_ATTEMPTS   0
+
+/* Enable some protocols to test them */
+#define LWIP_DHCP                       1
+#define LWIP_AUTOIP                     1
+
+#define LWIP_IGMP                       1
+#define LWIP_DNS                        1
+
+#define LWIP_ALTCP                      1
+
+/* Turn off checksum verification of fuzzed data */
+#define CHECKSUM_CHECK_IP               0
+#define CHECKSUM_CHECK_UDP              0
+#define CHECKSUM_CHECK_TCP              0
+#define CHECKSUM_CHECK_ICMP             0
+#define CHECKSUM_CHECK_ICMP6            0
+
+/* Minimal changes to opt.h required for tcp unit tests: */
+#define MEM_SIZE                        16000
+#define TCP_SND_QUEUELEN                40
+#define MEMP_NUM_TCP_SEG                TCP_SND_QUEUELEN
+#define TCP_OVERSIZE                    1
+#define TCP_SND_BUF                     (12 * TCP_MSS)
+#define TCP_WND                         (10 * TCP_MSS)
+#define LWIP_WND_SCALE                  1
+#define TCP_RCV_SCALE                   2
+#define PBUF_POOL_SIZE                  400 /* pbuf tests need ~200KByte */
+
+/* Minimal changes to opt.h required for etharp unit tests: */
+#define ETHARP_SUPPORT_STATIC_ENTRIES   1
+
+#define LWIP_NUM_NETIF_CLIENT_DATA      1
+#define LWIP_SNMP                       1
+#define MIB2_STATS                      1
+#define LWIP_MDNS_RESPONDER             1
+
+#endif /* LWIP_HDR_LWIPOPTS_H__ */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/test/fuzz/output_to_pcap.sh
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/test/fuzz/output_to_pcap.sh	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/test/fuzz/output_to_pcap.sh	(revision 457)
@@ -0,0 +1,31 @@
+#!/bin/bash
+
+if [ -z "$1" ]
+then
+	echo "This script will make pcap files from the afl-fuzz crash/hang files"
+	echo "It needs hexdump and text2pcap"
+	echo "Please give output directory as argument"
+	exit 2
+fi
+
+for i in `ls $1/crashes/id*`
+do
+	PCAPNAME=`echo $i | grep pcap`
+	if [ -z "$PCAPNAME" ]; then
+		hexdump -C $i > $1/$$.tmp
+		text2pcap $1/$$.tmp ${i}.pcap
+	fi
+done
+for i in `ls $1/hangs/id*`
+do
+	PCAPNAME=`echo $i | grep pcap`
+	if [ -z "$PCAPNAME" ]; then
+		hexdump -C $i > $1/$$.tmp
+		text2pcap $1/$$.tmp ${i}.pcap
+	fi
+done
+rm -f $1/$$.tmp
+
+echo
+echo "Created pcap files:"
+ls $1/*/*.pcap
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/test/sockets/sockets_stresstest.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/test/sockets/sockets_stresstest.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/test/sockets/sockets_stresstest.c	(revision 457)
@@ -0,0 +1,726 @@
+/**
+ * @file
+ * Sockets stresstest
+ *
+ * This file uses the lwIP socket API to do stress tests that should test the
+ * stability when used in many different situations, with many concurrent
+ * sockets making concurrent transfers in different manners.
+ *
+ * - test rely on loopback sockets for now, so netif drivers are not tested
+ * - all enabled functions shall be used
+ * - parallelism of the tests depend on enough resources being available
+ *   (configure your lwipopts.h settings high enough)
+ * - test should also be able to run in a real target
+ *
+ * TODO:
+ * - full duplex
+ * - add asserts about internal socket/netconn/pcb state?
+ */
+ 
+ /*
+ * Copyright (c) 2017 Simon Goldschmidt
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission. 
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ * 
+ * Author: Simon Goldschmidt <goldsimon@gmx.de>
+ *
+ */
+
+#include "lwip/opt.h"
+#include "sockets_stresstest.h"
+
+#include "lwip/sockets.h"
+#include "lwip/sys.h"
+
+#include "lwip/mem.h"
+
+#include <stdio.h>
+#include <string.h>
+
+#if LWIP_SOCKET && LWIP_IPV4 /* this uses IPv4 loopback sockets, currently */
+
+#ifndef TEST_SOCKETS_STRESS
+#define TEST_SOCKETS_STRESS   LWIP_DBG_OFF
+#endif
+
+#define TEST_TIME_SECONDS     10
+#define TEST_TXRX_BUFSIZE     (TCP_MSS * 2)
+#define TEST_MAX_RXWAIT_MS    50
+#define TEST_MAX_CONNECTIONS  50
+
+#define TEST_SOCK_READABLE    0x01
+#define TEST_SOCK_WRITABLE    0x02
+#define TEST_SOCK_ERR         0x04
+
+#define TEST_MODE_SELECT      0x01
+#define TEST_MODE_POLL        0x02
+#define TEST_MODE_NONBLOCKING 0x04
+#define TEST_MODE_WAIT        0x08
+#define TEST_MODE_RECVTIMEO   0x10
+#define TEST_MODE_SLEEP       0x20
+
+static int sockets_stresstest_numthreads;
+
+struct test_settings {
+  struct sockaddr_storage addr;
+  int start_client;
+  int loop_cnt;
+};
+
+struct sockets_stresstest_fullduplex {
+  int s;
+  volatile int closed;
+};
+
+static void
+fill_test_data(void *buf, size_t buf_len_bytes)
+{
+  u8_t *p = (u8_t*)buf;
+  u16_t i, chk;
+
+  LWIP_ASSERT("buffer too short", buf_len_bytes >= 4);
+  LWIP_ASSERT("buffer too big", buf_len_bytes <= 0xFFFF);
+  /* store the total number of bytes */
+  p[0] = (u8_t)(buf_len_bytes >> 8);
+  p[1] = (u8_t)buf_len_bytes;
+
+  /* fill buffer with random */
+  chk = 0;
+  for (i = 4; i < buf_len_bytes; i++) {
+    u8_t rnd = (u8_t)LWIP_RAND();
+    p[i] = rnd;
+    chk += rnd;
+  }
+  /* store checksum */
+  p[2] = (u8_t)(chk >> 8);
+  p[3] = (u8_t)chk;
+}
+
+static size_t
+check_test_data(const void *buf, size_t buf_len_bytes)
+{
+  u8_t *p = (u8_t*)buf;
+  u16_t i, chk, chk_rx, len_rx;
+
+  LWIP_ASSERT("buffer too short", buf_len_bytes >= 4);
+  len_rx = (((u16_t)p[0]) << 8) | p[1];
+  LWIP_ASSERT("len too short", len_rx >= 4);
+  if (len_rx > buf_len_bytes) {
+    /* not all data received in this segment */
+    LWIP_DEBUGF(TEST_SOCKETS_STRESS | LWIP_DBG_TRACE, ("check-\n"));
+    return buf_len_bytes;
+  }
+  chk_rx = (((u16_t)p[2]) << 8) | p[3];
+  /* calculate received checksum */
+  chk = 0;
+  for (i = 4; i < len_rx; i++) {
+    chk += p[i];
+  }
+  LWIP_ASSERT("invalid checksum", chk == chk_rx);
+  if (len_rx < buf_len_bytes) {
+    size_t data_left = buf_len_bytes - len_rx;
+    memmove(p, &p[len_rx], data_left);
+    return data_left;
+  }
+  /* if we come here, we received exactly one chunk
+     -> next offset is 0 */
+  return 0;
+}
+
+static size_t
+recv_and_check_data_return_offset(int s, char *rxbuf, size_t rxbufsize, size_t rxoff, int *closed, const char *dbg)
+{
+  ssize_t ret;
+
+  ret = lwip_read(s, &rxbuf[rxoff], rxbufsize - rxoff);
+  if (ret == 0) {
+    *closed = 1;
+    return rxoff;
+  }
+  *closed = 0;
+  LWIP_DEBUGF(TEST_SOCKETS_STRESS | LWIP_DBG_TRACE, ("%s %d rx %d\n", dbg, s, (int)ret));
+  if (ret == -1) {
+    /* TODO: for this to work, 'errno' has to support multithreading... */
+    int err = errno;
+    if (err == ENOTCONN) {
+      *closed = 1;
+      return 0;
+    }
+    LWIP_ASSERT("err == 0", err == 0);
+  }
+  LWIP_ASSERT("ret > 0", ret > 0);
+  return check_test_data(rxbuf, rxoff + ret);
+}
+
+#if LWIP_SOCKET_SELECT
+static int
+sockets_stresstest_wait_readable_select(int s, int timeout_ms)
+{
+  int ret;
+  struct timeval tv;
+  fd_set fs_r;
+  fd_set fs_w;
+  fd_set fs_e;
+
+  FD_ZERO(&fs_r);
+  FD_ZERO(&fs_w);
+  FD_ZERO(&fs_e);
+
+  FD_SET(s, &fs_r);
+  FD_SET(s, &fs_e);
+
+  tv.tv_sec = timeout_ms / 1000;
+  tv.tv_usec = (timeout_ms - (tv.tv_sec * 1000)) * 1000;
+  ret = lwip_select(s + 1, &fs_r, &fs_w, &fs_e, &tv);
+  LWIP_ASSERT("select error", ret >= 0);
+  if (ret) {
+    /* convert poll flags to our flags */
+    ret = 0;
+    if (FD_ISSET(s, &fs_r)) {
+      ret |= TEST_SOCK_READABLE;
+    }
+    if (FD_ISSET(s, &fs_w)) {
+      ret |= TEST_SOCK_WRITABLE;
+    }
+    if (FD_ISSET(s, &fs_e)) {
+      ret |= TEST_SOCK_ERR;
+    }
+    return ret;
+  }
+  return 0;
+}
+#endif
+
+#if LWIP_SOCKET_POLL
+static int
+sockets_stresstest_wait_readable_poll(int s, int timeout_ms)
+{
+  int ret;
+  struct pollfd pfd;
+
+  pfd.fd = s;
+  pfd.revents = 0;
+  pfd.events = POLLIN | POLLERR;
+
+  ret = lwip_poll(&pfd, 1, timeout_ms);
+  if (ret) {
+    /* convert poll flags to our flags */
+    ret = 0;
+    if (pfd.revents & POLLIN) {
+      ret |= TEST_SOCK_READABLE;
+    }
+    if (pfd.revents & POLLOUT) {
+      ret |= TEST_SOCK_WRITABLE;
+    }
+    if (pfd.revents & POLLERR) {
+      ret |= TEST_SOCK_ERR;
+    }
+    return ret;
+  }
+  return 0;
+}
+#endif
+
+#if LWIP_SO_RCVTIMEO
+static int
+sockets_stresstest_wait_readable_recvtimeo(int s, int timeout_ms)
+{
+  int ret;
+  char buf;
+#if LWIP_SO_SNDRCVTIMEO_NONSTANDARD
+  int opt_on = timeout_ms;
+  int opt_off = 0;
+#else
+  struct timeval opt_on, opt_off;
+  opt_on.tv_sec = timeout_ms / 1000;
+  opt_on.tv_usec = (timeout_ms - (opt_on.tv_sec * 1000)) * 1000;
+  opt_off.tv_sec = 0;
+  opt_off.tv_usec = 0;
+#endif
+
+  /* enable receive timeout */
+  ret = lwip_setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, &opt_on, sizeof(opt_on));
+  LWIP_ASSERT("setsockopt error", ret == 0);
+
+  /* peek for one byte with timeout */
+  ret = lwip_recv(s, &buf, 1, MSG_PEEK);
+
+  /* disable receive timeout */
+  ret = lwip_setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, &opt_off, sizeof(opt_off));
+  LWIP_ASSERT("setsockopt error", ret == 0);
+
+  if (ret == 1) {
+    return TEST_SOCK_READABLE;
+  }
+  if (ret == 0) {
+    return 0;
+  }
+  if (ret == -1) {
+    return TEST_SOCK_ERR;
+  }
+  LWIP_ASSERT("invalid return value", 0);
+  return TEST_SOCK_ERR;
+}
+#endif
+
+static int
+sockets_stresstest_wait_readable_wait_peek(int s, int timeout_ms)
+{
+  int ret;
+  char buf;
+
+  LWIP_UNUSED_ARG(timeout_ms); /* cannot time out here */
+
+  /* peek for one byte */
+  ret = lwip_recv(s, &buf, 1, MSG_PEEK);
+
+  if (ret == 1) {
+    return TEST_SOCK_READABLE;
+  }
+  if (ret == 0) {
+    return 0;
+  }
+  if (ret == -1) {
+    return TEST_SOCK_ERR;
+  }
+  LWIP_ASSERT("invalid return value", 0);
+  return TEST_SOCK_ERR;
+}
+
+static int
+sockets_stresstest_wait_readable_nonblock(int s, int timeout_ms)
+{
+  int ret;
+  char buf;
+  u32_t wait_until = sys_now() + timeout_ms;
+
+  while(sys_now() < wait_until) {
+    /* peek for one byte */
+    ret = lwip_recv(s, &buf, 1, MSG_PEEK | MSG_DONTWAIT);
+
+    if (ret == 1) {
+      return TEST_SOCK_READABLE;
+    }
+    if (ret == -1) {
+      /* TODO: for this to work, 'errno' has to support multithreading... */
+      int err = errno;
+      if (err != EWOULDBLOCK) {
+        return TEST_SOCK_ERR;
+      }
+    }
+    /* TODO: sleep? */
+  }
+  return 0;
+}
+
+static int sockets_stresstest_rand_mode(int allow_wait, int allow_rx)
+{
+  u32_t random_value = LWIP_RAND();
+#if LWIP_SOCKET_SELECT
+  if (random_value & TEST_MODE_SELECT) {
+    return TEST_MODE_SELECT;
+  }
+#endif
+#if LWIP_SOCKET_POLL
+  if (random_value & TEST_MODE_POLL) {
+    return TEST_MODE_POLL;
+  }
+#endif
+  if (!allow_rx) {
+    return TEST_MODE_SLEEP;
+  }
+#if LWIP_SO_RCVTIMEO
+  if (random_value & TEST_MODE_RECVTIMEO) {
+    return TEST_MODE_RECVTIMEO;
+  }
+#endif
+  if (allow_wait) {
+    if (random_value & TEST_MODE_RECVTIMEO) {
+      return TEST_MODE_RECVTIMEO;
+    }
+  }
+  return TEST_MODE_NONBLOCKING;
+}
+
+static int
+sockets_stresstest_wait_readable(int mode, int s, int timeout_ms)
+{
+  switch(mode)
+  {
+#if LWIP_SOCKET_SELECT
+  case TEST_MODE_SELECT:
+    return sockets_stresstest_wait_readable_select(s, timeout_ms);
+#endif
+#if LWIP_SOCKET_POLL
+  case TEST_MODE_POLL:
+    return sockets_stresstest_wait_readable_poll(s, timeout_ms);
+#endif
+#if LWIP_SO_RCVTIMEO
+  case TEST_MODE_RECVTIMEO:
+    return sockets_stresstest_wait_readable_recvtimeo(s, timeout_ms);
+#endif
+  case TEST_MODE_WAIT:
+    return sockets_stresstest_wait_readable_wait_peek(s, timeout_ms);
+  case TEST_MODE_NONBLOCKING:
+    return sockets_stresstest_wait_readable_nonblock(s, timeout_ms);
+  case TEST_MODE_SLEEP:
+    {
+      sys_msleep(timeout_ms);
+      return 1;
+    }
+  default:
+    LWIP_ASSERT("invalid mode", 0);
+    break;
+  }
+  return 0;
+}
+
+#if LWIP_NETCONN_FULLDUPLEX
+static void
+sockets_stresstest_conn_client_r(void *arg)
+{
+  struct sockets_stresstest_fullduplex *fd = (struct sockets_stresstest_fullduplex *)arg;
+  int s = fd->s;
+  size_t rxoff = 0;
+  char rxbuf[TEST_TXRX_BUFSIZE];
+
+  while (1) {
+    int closed;
+    if (fd->closed) {
+      break;
+    }
+    rxoff = recv_and_check_data_return_offset(s, rxbuf, sizeof(rxbuf), rxoff, &closed, "cli");
+    if (fd->closed) {
+      break;
+    }
+    if (closed) {
+      lwip_close(s);
+      break;
+    }
+  }
+
+  SYS_ARCH_DEC(sockets_stresstest_numthreads, 1);
+  LWIP_ASSERT("", sockets_stresstest_numthreads >= 0);
+}
+#endif
+
+static void
+sockets_stresstest_conn_client(void *arg)
+{
+  struct sockaddr_storage addr;
+  struct sockaddr_in *addr_in;
+  int s, ret;
+  char txbuf[TEST_TXRX_BUFSIZE];
+  char rxbuf[TEST_TXRX_BUFSIZE];
+  size_t rxoff = 0;
+  u32_t max_time = sys_now() + (TEST_TIME_SECONDS * 1000);
+  int do_rx = 1;
+  struct sockets_stresstest_fullduplex *data = NULL;
+
+  memcpy(&addr, arg, sizeof(addr));
+  LWIP_ASSERT("", addr.ss_family == AF_INET);
+  addr_in = (struct sockaddr_in *)&addr;
+  addr_in->sin_addr.s_addr = inet_addr("127.0.0.1");
+
+  /* sleep a random time between 1 and 2 seconds */
+  sys_msleep(1000 + (LWIP_RAND() % 1000));
+
+  /* connect to the server */
+  s = lwip_socket(addr.ss_family, SOCK_STREAM, 0);
+  LWIP_ASSERT("s >= 0", s >= 0);
+
+#if LWIP_NETCONN_FULLDUPLEX
+  if (LWIP_RAND() & 1) {
+    sys_thread_t t;
+    data = (struct sockets_stresstest_fullduplex*)mem_malloc(sizeof(struct sockets_stresstest_fullduplex));
+    LWIP_ASSERT("data != NULL", data != 0);
+    SYS_ARCH_INC(sockets_stresstest_numthreads, 1);
+    data->s = s;
+    data->closed = 0;
+    t = sys_thread_new("sockets_stresstest_conn_client_r", sockets_stresstest_conn_client_r, data, 0, 0);
+    LWIP_ASSERT("thread != NULL", t != 0);
+    do_rx = 0;
+  }
+#endif
+
+  /* @todo: nonblocking connect? */
+  ret = lwip_connect(s, (struct sockaddr *)&addr, sizeof(struct sockaddr_storage));
+  LWIP_ASSERT("ret == 0", ret == 0);
+
+  while (sys_now() < max_time) {
+    int closed;
+    int mode = sockets_stresstest_rand_mode(0, do_rx);
+    int timeout_ms = LWIP_RAND() % TEST_MAX_RXWAIT_MS;
+    ret = sockets_stresstest_wait_readable(mode, s, timeout_ms);
+    if (ret) {
+      if (do_rx) {
+        /* read some */
+        LWIP_ASSERT("readable", ret == TEST_SOCK_READABLE);
+        rxoff = recv_and_check_data_return_offset(s, rxbuf, sizeof(rxbuf), rxoff, &closed, "cli");
+        LWIP_ASSERT("client got closed", !closed);
+      }
+    } else {
+      /* timeout, send some */
+      size_t send_len = (LWIP_RAND() % (sizeof(txbuf) - 4)) + 4;
+      fill_test_data(txbuf, send_len);
+      LWIP_DEBUGF(TEST_SOCKETS_STRESS | LWIP_DBG_TRACE, ("cli %d tx %d\n", s, (int)send_len));
+      ret = lwip_write(s, txbuf, send_len);
+      if (ret == -1) {
+        /* TODO: for this to work, 'errno' has to support multithreading... */
+        int err = errno;
+        LWIP_ASSERT("err == 0", err == 0);
+      }
+      LWIP_ASSERT("ret == send_len", ret == (int)send_len);
+    }
+  }
+  if (data) {
+    data->closed = 1;
+  }
+  ret = lwip_close(s);
+  LWIP_ASSERT("ret == 0", ret == 0);
+
+  SYS_ARCH_DEC(sockets_stresstest_numthreads, 1);
+  LWIP_ASSERT("", sockets_stresstest_numthreads >= 0);
+}
+
+static void
+sockets_stresstest_conn_server(void *arg)
+{
+  int s, ret;
+  char txbuf[TEST_TXRX_BUFSIZE];
+  char rxbuf[TEST_TXRX_BUFSIZE];
+  size_t rxoff = 0;
+
+  s = (int)arg;
+
+  while (1) {
+    int closed;
+    int mode = sockets_stresstest_rand_mode(1, 1);
+    int timeout_ms = LWIP_RAND() % TEST_MAX_RXWAIT_MS;
+    ret = sockets_stresstest_wait_readable(mode, s, timeout_ms);
+    if (ret) {
+      if (ret & TEST_SOCK_ERR) {
+        /* closed? */
+        break;
+      }
+      /* read some */
+      LWIP_ASSERT("readable", ret == TEST_SOCK_READABLE);
+      rxoff = recv_and_check_data_return_offset(s, rxbuf, sizeof(rxbuf), rxoff, &closed, "srv");
+      if (closed) {
+        break;
+      }
+    } else {
+      /* timeout, send some */
+      size_t send_len = (LWIP_RAND() % (sizeof(txbuf) - 4)) + 4;
+      fill_test_data(txbuf, send_len);
+      LWIP_DEBUGF(TEST_SOCKETS_STRESS | LWIP_DBG_TRACE, ("srv %d tx %d\n", s, (int)send_len));
+      ret = lwip_write(s, txbuf, send_len);
+      if (ret == -1) {
+        /* TODO: for this to work, 'errno' has to support multithreading... */
+        int err = errno;
+        if (err == ECONNRESET) {
+          break;
+        }
+        if (err == ENOTCONN) {
+          break;
+        }
+        LWIP_ASSERT("unknown error", 0);
+      }
+      LWIP_ASSERT("ret == send_len", ret == (int)send_len);
+    }
+  }
+  ret = lwip_close(s);
+  LWIP_ASSERT("ret == 0", ret == 0);
+
+  SYS_ARCH_DEC(sockets_stresstest_numthreads, 1);
+  LWIP_ASSERT("", sockets_stresstest_numthreads >= 0);
+}
+
+static int
+sockets_stresstest_start_clients(const struct sockaddr_storage *remote_addr)
+{
+  /* limit the number of connections */
+  const int max_connections = LWIP_MIN(TEST_MAX_CONNECTIONS, MEMP_NUM_TCP_PCB/3);
+  int i;
+
+  for (i = 0; i < max_connections; i++) {
+    sys_thread_t t;
+    SYS_ARCH_INC(sockets_stresstest_numthreads, 1);
+    t = sys_thread_new("sockets_stresstest_conn_client", sockets_stresstest_conn_client, (void*)remote_addr, 0, 0);
+    LWIP_ASSERT("thread != NULL", t != 0);
+  }
+  return max_connections;
+}
+
+static void
+sockets_stresstest_listener(void *arg)
+{
+  int slisten;
+  int ret;
+  struct sockaddr_storage addr;
+  socklen_t addr_len;
+  struct test_settings *settings = (struct test_settings *)arg;
+  int num_clients, num_servers = 0;
+
+  slisten = lwip_socket(AF_INET, SOCK_STREAM, 0);
+  LWIP_ASSERT("slisten >= 0", slisten >= 0);
+
+  memcpy(&addr, &settings->addr, sizeof(struct sockaddr_storage));
+  ret = lwip_bind(slisten, (struct sockaddr *)&addr, sizeof(addr));
+  LWIP_ASSERT("ret == 0", ret == 0);
+
+  ret = lwip_listen(slisten, 0);
+  LWIP_ASSERT("ret == 0", ret == 0);
+
+  addr_len = sizeof(addr);
+  ret = lwip_getsockname(slisten, (struct sockaddr *)&addr, &addr_len);
+  LWIP_ASSERT("ret == 0", ret == 0);
+
+  num_clients = sockets_stresstest_start_clients(&addr);
+
+  while (num_servers < num_clients) {
+    struct sockaddr_storage aclient;
+    socklen_t aclient_len = sizeof(aclient);
+    int sclient = lwip_accept(slisten, (struct sockaddr *)&aclient, &aclient_len);
+#if 1
+    /* using server threads */
+    {
+      sys_thread_t t;
+      SYS_ARCH_INC(sockets_stresstest_numthreads, 1);
+      num_servers++;
+      t = sys_thread_new("sockets_stresstest_conn_server", sockets_stresstest_conn_server, (void*)sclient, 0, 0);
+      LWIP_ASSERT("thread != NULL", t != 0);
+    }
+#else
+    /* using server select */
+#endif
+  }
+  LWIP_DEBUGF(TEST_SOCKETS_STRESS | LWIP_DBG_STATE, ("sockets_stresstest_listener: all %d connections established\n", num_clients));
+
+  /* accepted all clients */
+  while (sockets_stresstest_numthreads > 0) {
+    sys_msleep(1);
+  }
+
+  ret = lwip_close(slisten);
+  LWIP_ASSERT("ret == 0", ret == 0);
+
+  LWIP_DEBUGF(TEST_SOCKETS_STRESS |LWIP_DBG_STATE, ("sockets_stresstest_listener: done\n"));
+}
+
+static void
+sockets_stresstest_listener_loop(void *arg)
+{
+  int i;
+  struct test_settings *settings = (struct test_settings *)arg;
+
+  if (settings->loop_cnt) {
+    for (i = 0; i < settings->loop_cnt; i++) {
+      LWIP_DEBUGF(TEST_SOCKETS_STRESS |LWIP_DBG_STATE, ("sockets_stresstest_listener_loop: iteration %d\n", i));
+      sockets_stresstest_listener(arg);
+      sys_msleep(2);
+    }
+    LWIP_DEBUGF(TEST_SOCKETS_STRESS |LWIP_DBG_STATE, ("sockets_stresstest_listener_loop: done\n"));
+  } else {
+    for (i = 0; ; i++) {
+      LWIP_DEBUGF(TEST_SOCKETS_STRESS |LWIP_DBG_STATE, ("sockets_stresstest_listener_loop: iteration %d\n", i));
+      sockets_stresstest_listener(arg);
+      sys_msleep(2);
+    }
+  }
+}
+
+void
+sockets_stresstest_init_loopback(int addr_family)
+{
+  sys_thread_t t;
+  struct test_settings *settings = (struct test_settings *)mem_malloc(sizeof(struct test_settings));
+
+  LWIP_ASSERT("OOM", settings != NULL);
+  memset(settings, 0, sizeof(struct test_settings));
+#if LWIP_IPV4 && LWIP_IPV6
+  LWIP_ASSERT("invalid addr_family", (addr_family == AF_INET) || (addr_family == AF_INET6));
+#endif
+  settings->addr.ss_family = (sa_family_t)addr_family;
+  LWIP_UNUSED_ARG(addr_family);
+  settings->start_client = 1;
+
+  t = sys_thread_new("sockets_stresstest_listener_loop", sockets_stresstest_listener_loop, settings, 0, 0);
+  LWIP_ASSERT("thread != NULL", t != 0);
+}
+
+void
+sockets_stresstest_init_server(int addr_family, u16_t server_port)
+{
+  sys_thread_t t;
+  struct test_settings *settings = (struct test_settings *)mem_malloc(sizeof(struct test_settings));
+
+  LWIP_ASSERT("OOM", settings != NULL);
+  memset(settings, 0, sizeof(struct test_settings));
+#if LWIP_IPV4 && LWIP_IPV6
+  LWIP_ASSERT("invalid addr_family", (addr_family == AF_INET) || (addr_family == AF_INET6));
+  settings->addr.ss_family = (sa_family_t)addr_family;
+#endif
+  LWIP_UNUSED_ARG(addr_family);
+  ((struct sockaddr_in *)(&settings->addr))->sin_port = server_port;
+
+  t = sys_thread_new("sockets_stresstest_listener", sockets_stresstest_listener, settings, 0, 0);
+  LWIP_ASSERT("thread != NULL", t != 0);
+}
+
+void
+sockets_stresstest_init_client(const char *remote_ip, u16_t remote_port)
+{
+#if LWIP_IPV4
+  ip4_addr_t ip4;
+#endif
+#if LWIP_IPV6
+  ip6_addr_t ip6;
+#endif
+  struct sockaddr_storage *addr = (struct sockaddr_storage *)mem_malloc(sizeof(struct sockaddr_storage));
+
+  LWIP_ASSERT("OOM", addr != NULL);
+  memset(addr, 0, sizeof(struct test_settings));
+#if LWIP_IPV4
+  if (ip4addr_aton(remote_ip, &ip4)) {
+    addr->ss_family = AF_INET;
+    ((struct sockaddr_in *)addr)->sin_addr.s_addr = ip4_addr_get_u32(&ip4);
+  }
+#endif
+#if LWIP_IPV4 && LWIP_IPV6
+  else
+#endif
+#if LWIP_IPV6
+  if (ip6addr_aton(remote_ip, &ip6)) {
+    addr->ss_family = AF_INET6;
+    /* todo: copy ipv6 address */
+  }
+#endif
+  ((struct sockaddr_in *)addr)->sin_port = remote_port;
+  sockets_stresstest_start_clients(addr);
+}
+
+#endif /* LWIP_SOCKET && LWIP_IPV4 */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/test/sockets/sockets_stresstest.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/test/sockets/sockets_stresstest.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/test/sockets/sockets_stresstest.h	(revision 457)
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2017 Simon Goldschmidt
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission. 
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ * 
+ * Author: Simon Goldschmidt <goldsimon@gmx.de>
+ *
+ */
+
+#ifndef LWIP_HDR_TEST_SOCKETS_STRESSTEST
+#define LWIP_HDR_TEST_SOCKETS_STRESSTEST
+
+void sockets_stresstest_init_loopback(int addr_family);
+void sockets_stresstest_init_server(int addr_family, u16_t server_port);
+void sockets_stresstest_init_client(const char *remote_ip, u16_t remote_port);
+
+#endif /* LWIP_HDR_TEST_SOCKETS_STRESSTEST */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/test/unit/Filelists.cmake
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/test/unit/Filelists.cmake	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/test/unit/Filelists.cmake	(revision 457)
@@ -0,0 +1,31 @@
+# This file is indended to be included in end-user CMakeLists.txt
+# include(/path/to/Filelists.cmake)
+# It assumes the variable LWIP_DIR is defined pointing to the
+# root path of lwIP sources.
+#
+# This file is NOT designed (on purpose) to be used as cmake
+# subdir via add_subdirectory()
+# The intention is to provide greater flexibility to users to 
+# create their own targets using the *_SRCS variables.
+
+set(LWIP_TESTDIR ${LWIP_DIR}/test/unit)
+set(LWIP_TESTFILES
+	${LWIP_TESTDIR}/lwip_unittests.c
+	${LWIP_TESTDIR}/api/test_sockets.c
+	${LWIP_TESTDIR}/arch/sys_arch.c
+	${LWIP_TESTDIR}/core/test_def.c
+	${LWIP_TESTDIR}/core/test_mem.c
+	${LWIP_TESTDIR}/core/test_netif.c
+	${LWIP_TESTDIR}/core/test_pbuf.c
+	${LWIP_TESTDIR}/core/test_timers.c
+	${LWIP_TESTDIR}/dhcp/test_dhcp.c
+	${LWIP_TESTDIR}/etharp/test_etharp.c
+	${LWIP_TESTDIR}/ip4/test_ip4.c
+	${LWIP_TESTDIR}/ip6/test_ip6.c
+	${LWIP_TESTDIR}/mdns/test_mdns.c
+	${LWIP_TESTDIR}/mqtt/test_mqtt.c
+	${LWIP_TESTDIR}/tcp/tcp_helper.c
+	${LWIP_TESTDIR}/tcp/test_tcp_oos.c
+	${LWIP_TESTDIR}/tcp/test_tcp.c
+	${LWIP_TESTDIR}/udp/test_udp.c
+)
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/test/unit/Filelists.mk
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/test/unit/Filelists.mk	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/test/unit/Filelists.mk	(revision 457)
@@ -0,0 +1,51 @@
+#
+# Copyright (c) 2001, 2002 Swedish Institute of Computer Science.
+# 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. The name of the author may not be used to endorse or promote products
+#    derived from this software without specific prior written permission. 
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+#
+# This file is part of the lwIP TCP/IP stack.
+# 
+# Author: Adam Dunkels <adam@sics.se>
+#
+
+TESTDIR=$(LWIPDIR)/../test/unit
+TESTFILES=$(TESTDIR)/lwip_unittests.c \
+	$(TESTDIR)/api/test_sockets.c \
+	$(TESTDIR)/arch/sys_arch.c \
+	$(TESTDIR)/core/test_def.c \
+	$(TESTDIR)/core/test_mem.c \
+	$(TESTDIR)/core/test_netif.c \
+	$(TESTDIR)/core/test_pbuf.c \
+	$(TESTDIR)/core/test_timers.c \
+	$(TESTDIR)/dhcp/test_dhcp.c \
+	$(TESTDIR)/etharp/test_etharp.c \
+	$(TESTDIR)/ip4/test_ip4.c \
+	$(TESTDIR)/ip6/test_ip6.c \
+	$(TESTDIR)/mdns/test_mdns.c \
+	$(TESTDIR)/mqtt/test_mqtt.c \
+	$(TESTDIR)/tcp/tcp_helper.c \
+	$(TESTDIR)/tcp/test_tcp_oos.c \
+	$(TESTDIR)/tcp/test_tcp.c \
+	$(TESTDIR)/udp/test_udp.c
+
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/test/unit/api/test_sockets.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/test/unit/api/test_sockets.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/test/unit/api/test_sockets.c	(revision 457)
@@ -0,0 +1,852 @@
+#include "test_sockets.h"
+
+#include "lwip/mem.h"
+#include "lwip/opt.h"
+#include "lwip/sockets.h"
+#include "lwip/priv/sockets_priv.h"
+#include "lwip/stats.h"
+
+#include "lwip/tcpip.h"
+#include "lwip/priv/tcp_priv.h"
+#include "lwip/api.h"
+
+
+static int
+test_sockets_get_used_count(void)
+{
+  int used = 0;
+  int i;
+
+  for (i = 0; i < NUM_SOCKETS; i++) {
+    struct lwip_sock* s = lwip_socket_dbg_get_socket(i);
+    if (s != NULL) {
+      if (s->fd_used) {
+        used++;
+      }
+    }
+  }
+  return used;
+}
+
+
+/* Setups/teardown functions */
+
+static void
+sockets_setup(void)
+{
+  /* expect full free heap */
+  lwip_check_ensure_no_alloc(SKIP_POOL(MEMP_SYS_TIMEOUT));
+}
+
+static void
+sockets_teardown(void)
+{
+  fail_unless(test_sockets_get_used_count() == 0);
+  /* poll until all memory is released... */
+  tcpip_thread_poll_one();
+  while (tcp_tw_pcbs) {
+    tcp_abort(tcp_tw_pcbs);
+    tcpip_thread_poll_one();
+  }
+  tcpip_thread_poll_one();
+  /* ensure full free heap */
+  lwip_check_ensure_no_alloc(SKIP_POOL(MEMP_SYS_TIMEOUT));
+}
+
+#ifndef NUM_SOCKETS
+#define NUM_SOCKETS MEMP_NUM_NETCONN
+#endif
+
+#if LWIP_SOCKET
+static int
+test_sockets_alloc_socket_nonblocking(int domain, int type)
+{
+  int s = lwip_socket(domain, type, 0);
+  if (s >= 0) {
+    int ret = lwip_fcntl(s, F_SETFL, O_NONBLOCK);
+    fail_unless(ret == 0);
+  }
+  return s;
+}
+
+/* Verify basic sockets functionality
+ */
+START_TEST(test_sockets_basics)
+{
+  int s, i, ret;
+  int s2[NUM_SOCKETS];
+  LWIP_UNUSED_ARG(_i);
+
+  s = lwip_socket(AF_INET, SOCK_STREAM, 0);
+  fail_unless(s >= 0);
+  lwip_close(s);
+
+  for (i = 0; i < NUM_SOCKETS; i++) {
+    s2[i] = lwip_socket(AF_INET, SOCK_STREAM, 0);
+    fail_unless(s2[i] >= 0);
+  }
+
+  /* all sockets used, now it should fail */
+  s = lwip_socket(AF_INET, SOCK_STREAM, 0);
+  fail_unless(s == -1);
+  /* close one socket */
+  ret = lwip_close(s2[0]);
+  fail_unless(ret == 0);
+  /* now it should succeed */
+  s2[0] = lwip_socket(AF_INET, SOCK_STREAM, 0);
+  fail_unless(s2[0] >= 0);
+
+  /* close all sockets */
+  for (i = 0; i < NUM_SOCKETS; i++) {
+    ret = lwip_close(s2[i]);
+    fail_unless(ret == 0);
+  }
+}
+END_TEST
+
+static void test_sockets_allfunctions_basic_domain(int domain)
+{
+  int s, s2, s3, ret;
+  struct sockaddr_storage addr, addr2;
+  socklen_t addrlen, addr2len;
+  char buf[4];
+  /* listen socket */
+  s = lwip_socket(domain, SOCK_STREAM, 0);
+  fail_unless(s >= 0);
+
+  ret = lwip_listen(s, 0);
+  fail_unless(ret == 0);
+
+  addrlen = sizeof(addr);
+  ret = lwip_getsockname(s, (struct sockaddr*)&addr, &addrlen);
+  fail_unless(ret == 0);
+
+  s2 = test_sockets_alloc_socket_nonblocking(domain, SOCK_STREAM);
+  fail_unless(s2 >= 0);
+  /* nonblocking connect s2 to s (but use loopback address) */
+  if (domain == AF_INET) {
+#if LWIP_IPV4
+    struct sockaddr_in *addr4 = (struct sockaddr_in *)&addr;
+    addr4->sin_addr.s_addr = PP_HTONL(INADDR_LOOPBACK);
+#endif
+  } else {
+#if LWIP_IPV6
+    struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *)&addr;
+    struct in6_addr lo6 = IN6ADDR_LOOPBACK_INIT;
+    addr6->sin6_addr = lo6;
+#endif
+  }
+  ret = lwip_connect(s2, (struct sockaddr*)&addr, addrlen);
+  fail_unless(ret == -1);
+  fail_unless(errno == EINPROGRESS);
+  ret = lwip_connect(s2, (struct sockaddr*)&addr, addrlen);
+  fail_unless(ret == -1);
+  fail_unless(errno == EALREADY);
+
+  while(tcpip_thread_poll_one());
+
+  s3 = lwip_accept(s, (struct sockaddr*)&addr2, &addr2len);
+  fail_unless(s3 >= 0);
+
+  ret = lwip_connect(s2, (struct sockaddr*)&addr, addrlen);
+  fail_unless(ret == -1);
+  fail_unless(errno == EISCONN);
+
+  /* write from server to client */
+  ret = write(s3, "test", 4);
+  fail_unless(ret == 4);
+
+  ret = lwip_shutdown(s3, SHUT_WR);
+  fail_unless(ret == 0);
+
+  while(tcpip_thread_poll_one());
+
+  ret = lwip_recv(s2, buf, 3, MSG_PEEK);
+  fail_unless(ret == 3);
+
+  ret = lwip_recv(s2, buf, 3, MSG_PEEK);
+  fail_unless(ret == 3);
+
+  ret = lwip_read(s2, buf, 4);
+  fail_unless(ret == 4);
+
+  ret = lwip_read(s2, buf, 1);
+  fail_unless(ret == 0);
+
+  ret = lwip_read(s2, buf, 1);
+  fail_unless(ret == -1);
+
+  ret = lwip_write(s2, "foo", 3);
+  fail_unless(ret == 3);
+
+  ret = lwip_close(s2);
+  fail_unless(ret == 0);
+
+  while(tcpip_thread_poll_one());
+
+  /* read one byte more than available to check handling FIN */
+  ret = lwip_read(s3, buf, 4);
+  fail_unless(ret == 3);
+
+  ret = lwip_read(s3, buf, 1);
+  fail_unless(ret == 0);
+
+  ret = lwip_read(s3, buf, 1);
+  fail_unless(ret == -1);
+
+  while(tcpip_thread_poll_one());
+
+  ret = lwip_close(s);
+  fail_unless(ret == 0);
+  ret = lwip_close(s3);
+  fail_unless(ret == 0);
+}
+
+/* Try to step through all sockets functions once...
+ */
+START_TEST(test_sockets_allfunctions_basic)
+{
+  LWIP_UNUSED_ARG(_i);
+#if LWIP_IPV4
+  test_sockets_allfunctions_basic_domain(AF_INET);
+#endif
+#if LWIP_IPV6
+  test_sockets_allfunctions_basic_domain(AF_INET6);
+#endif
+}
+END_TEST
+
+static void test_sockets_init_loopback_addr(int domain, struct sockaddr_storage *addr_st, socklen_t *sz)
+{
+  memset(addr_st, 0, sizeof(*addr_st));
+  switch(domain) {
+#if LWIP_IPV6
+    case AF_INET6: {
+      struct sockaddr_in6 *addr = (struct sockaddr_in6*)addr_st;
+      struct in6_addr lo6 = IN6ADDR_LOOPBACK_INIT;
+      addr->sin6_family = AF_INET6;
+      addr->sin6_port = 0; /* use ephemeral port */
+      addr->sin6_addr = lo6;
+      *sz = sizeof(*addr);
+   }
+      break;
+#endif /* LWIP_IPV6 */
+#if LWIP_IPV4
+    case AF_INET: {
+      struct sockaddr_in *addr = (struct sockaddr_in*)addr_st;
+      addr->sin_family = AF_INET;
+      addr->sin_port = 0; /* use ephemeral port */
+      addr->sin_addr.s_addr = PP_HTONL(INADDR_LOOPBACK);
+      *sz = sizeof(*addr);
+    }
+      break;
+#endif /* LWIP_IPV4 */
+    default:
+      *sz = 0;
+      fail();
+      break;
+  }
+}
+
+static void test_sockets_msgapi_update_iovs(struct msghdr *msg, size_t bytes)
+{
+  int i;
+
+  /* note: this modifies the underyling iov_base and iov_len for a partial
+     read for an individual vector. This updates the msg->msg_iov pointer
+     to skip fully consumed vecotrs */
+  
+  /* process fully consumed vectors */
+  for (i = 0; i < msg->msg_iovlen; i++) {
+    if (msg->msg_iov[i].iov_len <= bytes) {
+      /* reduce bytes by amount of this vector */
+      bytes -= msg->msg_iov[i].iov_len;
+    } else {
+      break; /* iov not fully consumed */
+    }
+  }
+
+  /* slide down over fully consumed vectors */
+  msg->msg_iov = &msg->msg_iov[i];
+  msg->msg_iovlen -= i;
+
+  /* update new first vector with any remaining amount */
+  msg->msg_iov[0].iov_base = ((u8_t *)msg->msg_iov[0].iov_base + bytes);
+  msg->msg_iov[0].iov_len -= bytes;
+}
+
+static void test_sockets_msgapi_tcp(int domain)
+{
+  #define BUF_SZ          (TCP_SND_BUF/4)
+  #define TOTAL_DATA_SZ   (BUF_SZ*8) /* ~(TCP_SND_BUF*2) that accounts for integer rounding */
+  #define NEED_TRAILER    (BUF_SZ % 4 != 0)
+  int listnr, s1, s2, i, ret, opt;
+  int bytes_written, bytes_read;
+  struct sockaddr_storage addr_storage;
+  socklen_t addr_size;
+  struct iovec siovs[8];
+  struct msghdr smsg;
+  u8_t * snd_buf;
+  struct iovec riovs[5];
+  struct iovec riovs_tmp[5];
+  struct msghdr rmsg;
+  u8_t * rcv_buf;
+  int    rcv_off;
+  int    rcv_trailer = 0;
+  u8_t val;
+
+  test_sockets_init_loopback_addr(domain, &addr_storage, &addr_size);
+
+  listnr = test_sockets_alloc_socket_nonblocking(domain, SOCK_STREAM);
+  fail_unless(listnr >= 0);
+  s1 = test_sockets_alloc_socket_nonblocking(domain, SOCK_STREAM);
+  fail_unless(s1 >= 0);
+
+  /* setup a listener socket on loopback with ephemeral port */
+  ret = lwip_bind(listnr, (struct sockaddr*)&addr_storage, addr_size);
+  fail_unless(ret == 0);
+  ret = lwip_listen(listnr, 0);
+  fail_unless(ret == 0);
+
+  /* update address with ephemeral port */
+  ret = lwip_getsockname(listnr, (struct sockaddr*)&addr_storage, &addr_size);
+  fail_unless(ret == 0);
+
+  /* connect, won't complete until we accept it */
+  ret = lwip_connect(s1, (struct sockaddr*)&addr_storage, addr_size);
+  fail_unless(ret == -1);
+  fail_unless(errno == EINPROGRESS);
+
+  while (tcpip_thread_poll_one());
+
+  /* accept, creating the other side of the connection */
+  s2 = lwip_accept(listnr, NULL, NULL);
+  fail_unless(s2 >= 0);
+
+  /* double check s1 is connected */
+  ret = lwip_connect(s1, (struct sockaddr*)&addr_storage, addr_size);
+  fail_unless(ret == -1);
+  fail_unless(errno == EISCONN);
+
+  /* set s2 to non-blocking, not inherited from listener */
+  opt = lwip_fcntl(s2, F_GETFL, 0);
+  fail_unless(opt == 6);
+  opt = O_NONBLOCK;
+  ret = lwip_fcntl(s2, F_SETFL, opt);
+  fail_unless(ret == 0);
+
+  /* we are done with listener, close it */
+  ret = lwip_close(listnr);
+  fail_unless(ret == 0);
+
+  /* allocate a buffer for a stream of incrementing hex (0x00..0xFF) which we will use
+     to create an input vector set that is larger than the TCP's send buffer. This will
+     force execution of the partial IO vector send case */
+  snd_buf = (u8_t*)mem_malloc(BUF_SZ);
+  val = 0x00;
+  fail_unless(snd_buf != NULL);
+  for (i = 0; i < BUF_SZ; i++,val++) {
+    snd_buf[i] = val;
+  }
+
+  /* send the buffer 8 times in one message, equating to TOTAL_DATA_SZ */
+  for (i = 0; i < 8; i++) {
+    siovs[i].iov_base = snd_buf;
+    siovs[i].iov_len = BUF_SZ;
+  }
+
+  /* allocate a receive buffer, same size as snd_buf for easy verification */
+  rcv_buf = (u8_t*)mem_calloc(1, BUF_SZ);
+  fail_unless(rcv_buf != NULL);
+  /* split across iovs */
+  for (i = 0; i < 4; i++) {
+    riovs[i].iov_base = &rcv_buf[i*(BUF_SZ/4)];
+    riovs[i].iov_len = BUF_SZ/4;
+  }
+  /* handling trailing bytes if buffer doesn't evenly divide by 4 */
+#if NEED_TRAILER
+  if ((BUF_SZ % 4) != 0) {
+    riovs[5].iov_base = &rcv_buf[4*(BUF_SZ/4)];
+    riovs[5].iov_len = BUF_SZ - (4*(BUF_SZ/4));
+    rcv_trailer = 1;
+  }
+#endif /* NEED_TRAILER */
+
+  /* we use a copy of riovs since we'll be modifying base and len during
+     receiving. This gives us an easy way to reset the iovs for next recvmsg */
+  memcpy(riovs_tmp, riovs, sizeof(riovs));
+
+  memset(&smsg, 0, sizeof(smsg));
+  smsg.msg_iov = siovs;
+  smsg.msg_iovlen = 8;
+
+  memset(&rmsg, 0, sizeof(rmsg));
+  rmsg.msg_iov = riovs_tmp;
+  rmsg.msg_iovlen = (rcv_trailer ? 5 : 4);
+
+  bytes_written = 0;
+  bytes_read = 0;
+  rcv_off = 0;
+
+  while (bytes_written < TOTAL_DATA_SZ && (bytes_read < TOTAL_DATA_SZ)) {
+    /* send data */
+    if (bytes_written < TOTAL_DATA_SZ) {
+      ret = lwip_sendmsg(s1, &smsg, 0);
+      /* note: since we always receive after sending, there will be open
+         space in the send buffer */
+      fail_unless(ret > 0);
+    
+      bytes_written += ret;
+      if (bytes_written < TOTAL_DATA_SZ) {
+        test_sockets_msgapi_update_iovs(&smsg, (size_t)ret);
+      }
+    }
+
+    while (tcpip_thread_poll_one());
+
+    /* receive and verify data */
+    do {
+      if (bytes_read < TOTAL_DATA_SZ) {
+        ret = lwip_recvmsg(s2, &rmsg, 0);
+        fail_unless(ret > 0 || (ret == -1 && errno == EWOULDBLOCK));
+
+        if (ret > 0) {
+          rcv_off += ret;
+          /* we have received a full buffer */
+          if (rcv_off == BUF_SZ) {
+            /* note: since iovs are just pointers, compare underlying buf */
+            fail_unless(!memcmp(snd_buf, rcv_buf, BUF_SZ));
+            bytes_read += BUF_SZ;
+            /* reset receive state for next buffer */
+            rcv_off = 0;
+            memset(rcv_buf, 0, BUF_SZ);
+            memcpy(riovs_tmp, riovs, sizeof(riovs));
+            rmsg.msg_iov = riovs_tmp;
+            rmsg.msg_iovlen = (rcv_trailer ? 5 : 4);
+          } else { /* partial read */
+            test_sockets_msgapi_update_iovs(&rmsg, (size_t)ret);
+          }
+        }
+      } else {
+        break;
+      }
+    } while(ret > 0);
+  }
+  
+  ret = lwip_close(s1);
+  fail_unless(ret == 0);
+  ret = lwip_close(s2);
+  fail_unless(ret == 0);
+  mem_free(snd_buf);
+  mem_free(rcv_buf);
+}
+
+static void test_sockets_msgapi_udp_send_recv_loop(int s, struct msghdr *smsg, struct msghdr *rmsg)
+{
+  int i, ret;
+
+  /* send/receive our datagram of IO vectors 10 times */
+  for (i = 0; i < 10; i++) {
+    ret = lwip_sendmsg(s, smsg, 0);
+    fail_unless(ret == 4);
+
+    while (tcpip_thread_poll_one());
+
+    /* receive the datagram split across 4 buffers */
+    ret = lwip_recvmsg(s, rmsg, 0);
+    fail_unless(ret == 4);
+
+    /* verify data */
+    fail_unless(*((u8_t*)rmsg->msg_iov[0].iov_base) == 0xDE);
+    fail_unless(*((u8_t*)rmsg->msg_iov[1].iov_base) == 0xAD);
+    fail_unless(*((u8_t*)rmsg->msg_iov[2].iov_base) == 0xBE);
+    fail_unless(*((u8_t*)rmsg->msg_iov[3].iov_base) == 0xEF);
+
+    /* clear rcv_buf to ensure no data is being skipped */
+    *((u8_t*)rmsg->msg_iov[0].iov_base) = 0x00;
+    *((u8_t*)rmsg->msg_iov[1].iov_base) = 0x00;
+    *((u8_t*)rmsg->msg_iov[2].iov_base) = 0x00;
+    *((u8_t*)rmsg->msg_iov[3].iov_base) = 0x00;
+  }
+}
+
+static void test_sockets_msgapi_udp(int domain)
+{
+  int s, i, ret;
+  struct sockaddr_storage addr_storage;
+  socklen_t addr_size;
+  struct iovec riovs[4];
+  struct msghdr rmsg;
+  u8_t rcv_buf[4];
+  struct iovec siovs[4];
+  struct msghdr smsg;
+  u8_t snd_buf[4] = {0xDE, 0xAD, 0xBE, 0xEF};
+
+  /* initialize IO vectors with data */
+  for (i = 0; i < 4; i++) {
+    siovs[i].iov_base = &snd_buf[i];
+    siovs[i].iov_len = sizeof(u8_t);
+    riovs[i].iov_base = &rcv_buf[i];
+    riovs[i].iov_len = sizeof(u8_t);
+  }
+
+  test_sockets_init_loopback_addr(domain, &addr_storage, &addr_size);
+
+  s = test_sockets_alloc_socket_nonblocking(domain, SOCK_DGRAM);
+  fail_unless(s >= 0);
+
+  ret = lwip_bind(s, (struct sockaddr*)&addr_storage, addr_size);
+  fail_unless(ret == 0);
+
+  /* Update addr with epehermal port */
+  ret = lwip_getsockname(s, (struct sockaddr*)&addr_storage, &addr_size);
+  fail_unless(ret == 0);
+  switch(domain) {
+#if LWIP_IPV6
+    case AF_INET6:
+      fail_unless(addr_size == sizeof(struct sockaddr_in6));
+      break;
+#endif /* LWIP_IPV6 */
+#if LWIP_IPV4
+    case AF_INET:
+        fail_unless(addr_size == sizeof(struct sockaddr_in));
+        break;
+#endif /* LWIP_IPV6 */
+    default:
+      fail();
+      break;
+  }
+
+  /* send and receive the datagram in 4 pieces */
+  memset(&smsg, 0, sizeof(smsg));
+  smsg.msg_iov = siovs;
+  smsg.msg_iovlen = 4;
+  memset(&rmsg, 0, sizeof(rmsg));
+  rmsg.msg_iov = riovs;
+  rmsg.msg_iovlen = 4;
+
+  /* perform a sendmsg with remote host (self) */
+  smsg.msg_name = &addr_storage;
+  smsg.msg_namelen = addr_size;
+
+  test_sockets_msgapi_udp_send_recv_loop(s, &smsg, &rmsg);
+
+  /* Connect to self, allowing us to not pass message name */
+  ret = lwip_connect(s, (struct sockaddr*)&addr_storage, addr_size);
+  fail_unless(ret == 0);
+
+  smsg.msg_name = NULL;
+  smsg.msg_namelen = 0;
+
+  test_sockets_msgapi_udp_send_recv_loop(s, &smsg, &rmsg);
+
+  ret = lwip_close(s);
+  fail_unless(ret == 0);
+}
+
+#if LWIP_IPV4
+static void test_sockets_msgapi_cmsg(int domain)
+{
+  int s, ret, enable;
+  struct sockaddr_storage addr_storage;
+  socklen_t addr_size;
+  struct iovec iov;
+  struct msghdr msg;
+  struct cmsghdr *cmsg;
+  struct in_pktinfo *pktinfo;
+  u8_t rcv_buf[4];
+  u8_t snd_buf[4] = {0xDE, 0xAD, 0xBE, 0xEF};
+  u8_t cmsg_buf[CMSG_SPACE(sizeof(struct in_pktinfo))];
+
+  test_sockets_init_loopback_addr(domain, &addr_storage, &addr_size);
+
+  s = test_sockets_alloc_socket_nonblocking(domain, SOCK_DGRAM);
+  fail_unless(s >= 0);
+
+  ret = lwip_bind(s, (struct sockaddr*)&addr_storage, addr_size);
+  fail_unless(ret == 0);
+
+  /* Update addr with epehermal port */
+  ret = lwip_getsockname(s, (struct sockaddr*)&addr_storage, &addr_size);
+  fail_unless(ret == 0);
+
+  enable = 1;
+  ret = lwip_setsockopt(s, IPPROTO_IP, IP_PKTINFO, &enable, sizeof(enable));
+  fail_unless(ret == 0);
+
+  /* Receive full message, including control message */
+  iov.iov_base = rcv_buf;
+  iov.iov_len = sizeof(rcv_buf);
+  msg.msg_control = cmsg_buf;
+  msg.msg_controllen = sizeof(cmsg_buf);
+  msg.msg_flags = 0;
+  msg.msg_iov = &iov;
+  msg.msg_iovlen = 1;
+  msg.msg_name = NULL;
+  msg.msg_namelen = 0;
+
+  memset(rcv_buf, 0, sizeof(rcv_buf));
+  ret = lwip_sendto(s, snd_buf, sizeof(snd_buf), 0, (struct sockaddr*)&addr_storage, addr_size);
+  fail_unless(ret == sizeof(snd_buf));
+  
+  tcpip_thread_poll_one();
+
+  ret = lwip_recvmsg(s, &msg, 0);
+  fail_unless(ret == sizeof(rcv_buf));
+  fail_unless(!memcmp(rcv_buf, snd_buf, sizeof(rcv_buf)));
+  
+  /* Verify message header */
+  cmsg = CMSG_FIRSTHDR(&msg);
+  fail_unless(cmsg != NULL);
+  fail_unless(cmsg->cmsg_len > 0);
+  fail_unless(cmsg->cmsg_level == IPPROTO_IP);
+  fail_unless(cmsg->cmsg_type == IP_PKTINFO);
+
+  /* Verify message data */
+  pktinfo = (struct in_pktinfo*)CMSG_DATA(cmsg);
+  /* We only have loopback interface enabled */
+  fail_unless(pktinfo->ipi_ifindex == 1);
+  fail_unless(pktinfo->ipi_addr.s_addr == PP_HTONL(INADDR_LOOPBACK));
+
+  /* Verify there are no additional messages */
+  cmsg = CMSG_NXTHDR(&msg, cmsg);
+  fail_unless(cmsg == NULL);
+
+  /* Send datagram again, testing truncation */
+  memset(rcv_buf, 0, sizeof(rcv_buf));
+  ret = lwip_sendto(s, snd_buf, sizeof(snd_buf), 0, (struct sockaddr*)&addr_storage, addr_size);
+  fail_unless(ret == sizeof(snd_buf));
+
+  tcpip_thread_poll_one();
+
+  msg.msg_controllen = 1;
+  msg.msg_flags = 0;
+  ret = lwip_recvmsg(s, &msg, 0);
+  fail_unless(ret == sizeof(rcv_buf));
+  fail_unless(!memcmp(rcv_buf, snd_buf, sizeof(rcv_buf)));
+  /* Ensure truncation was returned */
+  fail_unless(msg.msg_flags & MSG_CTRUNC);
+  /* Ensure no control messages were returned */
+  fail_unless(msg.msg_controllen == 0);
+
+  ret = lwip_close(s);
+  fail_unless(ret == 0);
+}
+#endif /* LWIP_IPV4 */
+
+START_TEST(test_sockets_msgapis)
+{
+  LWIP_UNUSED_ARG(_i);
+#if LWIP_IPV4
+  test_sockets_msgapi_udp(AF_INET);
+  test_sockets_msgapi_tcp(AF_INET);
+  test_sockets_msgapi_cmsg(AF_INET);
+#endif
+#if LWIP_IPV6
+  test_sockets_msgapi_udp(AF_INET6);
+  test_sockets_msgapi_tcp(AF_INET6);
+#endif
+}
+END_TEST
+
+START_TEST(test_sockets_select)
+{
+#if LWIP_SOCKET_SELECT
+  int s;
+  int ret;
+  fd_set readset;
+  fd_set writeset;
+  fd_set errset;
+  struct timeval tv;
+
+  fail_unless(test_sockets_get_used_count() == 0);
+
+  s = lwip_socket(AF_INET, SOCK_STREAM, 0);
+  fail_unless(s >= 0);
+  fail_unless(test_sockets_get_used_count() == 0);
+
+  FD_ZERO(&readset);
+  FD_SET(s, &readset);
+  FD_ZERO(&writeset);
+  FD_SET(s, &writeset);
+  FD_ZERO(&errset);
+  FD_SET(s, &errset);
+
+  tv.tv_sec = tv.tv_usec = 0;
+  ret = lwip_select(s + 1, &readset, &writeset, &errset, &tv);
+  fail_unless(ret == 0);
+  fail_unless(test_sockets_get_used_count() == 0);
+
+  ret = lwip_close(s);
+  fail_unless(ret == 0);
+
+#endif
+  LWIP_UNUSED_ARG(_i);
+}
+END_TEST
+
+START_TEST(test_sockets_recv_after_rst)
+{
+  int sl, sact;
+  int spass = -1;
+  int ret;
+  struct sockaddr_in sa_listen;
+  const u16_t port = 1234;
+  int arg;
+  const char txbuf[] = "something";
+  char rxbuf[16];
+  struct lwip_sock *sact_sock;
+  int err;
+  LWIP_UNUSED_ARG(_i);
+
+  fail_unless(test_sockets_get_used_count() == 0);
+
+  memset(&sa_listen, 0, sizeof(sa_listen));
+  sa_listen.sin_family = AF_INET;
+  sa_listen.sin_port = PP_HTONS(port);
+  sa_listen.sin_addr.s_addr = PP_HTONL(INADDR_LOOPBACK);
+
+  /* set up the listener */
+  sl = lwip_socket(AF_INET, SOCK_STREAM, 0);
+  fail_unless(sl >= 0);
+  fail_unless(test_sockets_get_used_count() == 0);
+
+  ret = lwip_bind(sl, (struct sockaddr *)&sa_listen, sizeof(sa_listen));
+  fail_unless(ret == 0);
+  ret = lwip_listen(sl, 0);
+  fail_unless(ret == 0);
+
+  /* set up the client */
+  sact = lwip_socket(AF_INET, SOCK_STREAM, 0);
+  fail_unless(sact >= 0);
+  fail_unless(test_sockets_get_used_count() == 0);
+  /* set the client to nonblocking to simplify this test */
+  arg = 1;
+  ret = lwip_ioctl(sact, FIONBIO, &arg);
+  fail_unless(ret == 0);
+  /* connect */
+  do {
+    ret = lwip_connect(sact, (struct sockaddr *)&sa_listen, sizeof(sa_listen));
+    err = errno;
+    fail_unless((ret == 0) || (ret == -1));
+    if (ret != 0) {
+      if (err == EISCONN) {
+        /* Although this is not valid, use EISCONN as an indicator for successful connection.
+           This marks us as "connect phase is done". On error, we would either have a different
+           errno code or "send" fails later... -> good enough for this test. */
+        ret = 0;
+      } else {
+        fail_unless(err == EINPROGRESS);
+        if (err != EINPROGRESS) {
+          goto cleanup;
+        }
+        /* we're in progress: little side check: test for EALREADY */
+        ret = lwip_connect(sact, (struct sockaddr *)&sa_listen, sizeof(sa_listen));
+        err = errno;
+        fail_unless(ret == -1);
+        fail_unless(err == EALREADY);
+        if ((ret != -1) || (err != EALREADY)) {
+          goto cleanup;
+        }
+      }
+      tcpip_thread_poll_one();
+      tcpip_thread_poll_one();
+      tcpip_thread_poll_one();
+      tcpip_thread_poll_one();
+    }
+  } while (ret != 0);
+  fail_unless(ret == 0);
+
+  /* accept the server connection part */
+  spass = lwip_accept(sl, NULL, NULL);
+  fail_unless(spass >= 0);
+
+  /* write data from client */
+  ret = lwip_send(sact, txbuf, sizeof(txbuf), 0);
+  fail_unless(ret == sizeof(txbuf));
+
+  tcpip_thread_poll_one();
+  tcpip_thread_poll_one();
+
+  /* issue RST (This is a HACK, don't try this in your own app!) */
+  sact_sock = lwip_socket_dbg_get_socket(sact);
+  fail_unless(sact_sock != NULL);
+  if (sact_sock != NULL) {
+    struct netconn *sact_conn = sact_sock->conn;
+    fail_unless(sact_conn != NULL);
+    if (sact_conn != NULL) {
+      struct tcp_pcb *pcb = sact_conn->pcb.tcp;
+      fail_unless(pcb != NULL);
+      if (pcb != NULL) {
+        tcp_rst(pcb, pcb->snd_nxt, pcb->rcv_nxt, &pcb->local_ip, &pcb->remote_ip,
+                     pcb->local_port, pcb->remote_port);
+      }
+    }
+  }
+  tcpip_thread_poll_one();
+  tcpip_thread_poll_one();
+
+  /* expect to receive data first */
+  ret = lwip_recv(spass, rxbuf, sizeof(rxbuf), 0);
+  fail_unless(ret > 0);
+  tcpip_thread_poll_one();
+  tcpip_thread_poll_one();
+
+  /* expect to receive RST indication */
+  ret = lwip_recv(spass, rxbuf, sizeof(rxbuf), 0);
+  fail_unless(ret == -1);
+  err = errno;
+  fail_unless(err == ECONNRESET);
+  tcpip_thread_poll_one();
+  tcpip_thread_poll_one();
+
+  /* expect to receive ENOTCONN indication */
+  ret = lwip_recv(spass, rxbuf, sizeof(rxbuf), 0);
+  fail_unless(ret == -1);
+  err = errno;
+  fail_unless(err == ENOTCONN);
+  tcpip_thread_poll_one();
+  tcpip_thread_poll_one();
+
+  /* expect to receive ENOTCONN indication */
+  ret = lwip_recv(spass, rxbuf, sizeof(rxbuf), 0);
+  fail_unless(ret == -1);
+  err = errno;
+  fail_unless(err == ENOTCONN);
+  tcpip_thread_poll_one();
+  tcpip_thread_poll_one();
+
+cleanup:
+  ret = lwip_close(sl);
+  fail_unless(ret == 0);
+  ret = lwip_close(sact);
+  fail_unless(ret == 0);
+  if (spass >= 0) {
+    ret = lwip_close(spass);
+    fail_unless(ret == 0);
+  }
+}
+END_TEST
+
+/** Create the suite including all tests for this module */
+Suite *
+sockets_suite(void)
+{
+  testfunc tests[] = {
+    TESTFUNC(test_sockets_basics),
+    TESTFUNC(test_sockets_allfunctions_basic),
+    TESTFUNC(test_sockets_msgapis),
+    TESTFUNC(test_sockets_select),
+    TESTFUNC(test_sockets_recv_after_rst),
+  };
+  return create_suite("SOCKETS", tests, sizeof(tests)/sizeof(testfunc), sockets_setup, sockets_teardown);
+}
+
+#else /* LWIP_SOCKET */
+
+Suite *
+sockets_suite(void)
+{
+  return create_suite("SOCKETS", NULL, 0, NULL, NULL);
+}
+#endif /* LWIP_SOCKET */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/test/unit/api/test_sockets.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/test/unit/api/test_sockets.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/test/unit/api/test_sockets.h	(revision 457)
@@ -0,0 +1,8 @@
+#ifndef LWIP_HDR_TEST_SOCKETS_H
+#define LWIP_HDR_TEST_SOCKETS_H
+
+#include "../lwip_check.h"
+
+Suite *sockets_suite(void);
+
+#endif
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/test/unit/arch/sys_arch.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/test/unit/arch/sys_arch.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/test/unit/arch/sys_arch.c	(revision 457)
@@ -0,0 +1,371 @@
+/*
+ * Copyright (c) 2017 Simon Goldschmidt
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission. 
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ * 
+ * Author: Simon Goldschmidt
+ *
+ */
+
+
+#include <lwip/opt.h>
+#include <lwip/arch.h>
+#if !NO_SYS
+#include "sys_arch.h"
+#endif
+#include <lwip/stats.h>
+#include <lwip/debug.h>
+#include <lwip/sys.h>
+
+#include <string.h>
+
+u32_t lwip_sys_now;
+
+u32_t
+sys_jiffies(void)
+{
+  return lwip_sys_now;
+}
+
+u32_t
+sys_now(void)
+{
+  return lwip_sys_now;
+}
+
+void
+sys_init(void)
+{
+}
+
+#if !NO_SYS
+
+test_sys_arch_waiting_fn the_waiting_fn;
+
+void
+test_sys_arch_wait_callback(test_sys_arch_waiting_fn waiting_fn)
+{
+  the_waiting_fn = waiting_fn;
+}
+
+err_t
+sys_sem_new(sys_sem_t *sem, u8_t count)
+{
+  LWIP_ASSERT("sem != NULL", sem != NULL);
+  *sem = count + 1;
+  return ERR_OK;
+}
+
+void
+sys_sem_free(sys_sem_t *sem)
+{
+  LWIP_ASSERT("sem != NULL", sem != NULL);
+  *sem = 0;
+}
+
+void
+sys_sem_set_invalid(sys_sem_t *sem)
+{
+  LWIP_ASSERT("sem != NULL", sem != NULL);
+  *sem = 0;
+}
+
+/* semaphores are 1-based because RAM is initialized as 0, which would be valid */
+u32_t
+sys_arch_sem_wait(sys_sem_t *sem, u32_t timeout)
+{
+  u32_t ret = 0;
+  LWIP_ASSERT("sem != NULL", sem != NULL);
+  LWIP_ASSERT("*sem > 0", *sem > 0);
+  if (*sem == 1) {
+    /* need to wait */
+    if(!timeout)
+    {
+      /* wait infinite */
+      LWIP_ASSERT("cannot wait without waiting callback", the_waiting_fn != NULL);
+      do {
+        int expectSomething = the_waiting_fn(sem, NULL);
+        LWIP_ASSERT("*sem > 0", *sem > 0);
+        LWIP_ASSERT("expecting a semaphore count but it's 0", !expectSomething || (*sem > 1));
+        ret++;
+        if (ret == SYS_ARCH_TIMEOUT) {
+          ret--;
+        }
+      } while(*sem == 1);
+    }
+    else
+    {
+      if (the_waiting_fn) {
+        int expectSomething = the_waiting_fn(sem, NULL);
+        LWIP_ASSERT("expecting a semaphore count but it's 0", !expectSomething || (*sem > 1));
+      }
+      LWIP_ASSERT("*sem > 0", *sem > 0);
+      if (*sem == 1) {
+        return SYS_ARCH_TIMEOUT;
+      }
+      ret = 1;
+    }
+  }
+  LWIP_ASSERT("*sem > 0", *sem > 0);
+  (*sem)--;
+  LWIP_ASSERT("*sem > 0", *sem > 0);
+  /* return the time we waited for the sem */
+  return ret;
+}
+
+void
+sys_sem_signal(sys_sem_t *sem)
+{
+  LWIP_ASSERT("sem != NULL", sem != NULL);
+  LWIP_ASSERT("*sem > 0", *sem > 0);
+  (*sem)++;
+  LWIP_ASSERT("*sem > 0", *sem > 0);
+}
+
+err_t
+sys_mutex_new(sys_mutex_t *mutex)
+{
+  LWIP_ASSERT("mutex != NULL", mutex != NULL);
+  *mutex = 1; /* 1 allocated */
+  return ERR_OK;
+}
+
+void
+sys_mutex_free(sys_mutex_t *mutex)
+{
+  /* parameter check */
+  LWIP_ASSERT("mutex != NULL", mutex != NULL);
+  LWIP_ASSERT("*mutex >= 1", *mutex >= 1);
+  *mutex = 0;
+}
+
+void
+sys_mutex_set_invalid(sys_mutex_t *mutex)
+{
+  LWIP_ASSERT("mutex != NULL", mutex != NULL);
+  *mutex = 0;
+}
+
+void
+sys_mutex_lock(sys_mutex_t *mutex)
+{
+  /* nothing to do, no multithreading supported */
+  LWIP_ASSERT("mutex != NULL", mutex != NULL);
+  /* check that the mutext is valid and unlocked (no nested locking) */
+  LWIP_ASSERT("*mutex >= 1", *mutex == 1);
+  /* we count up just to check the correct pairing of lock/unlock */
+  (*mutex)++;
+  LWIP_ASSERT("*mutex >= 1", *mutex >= 1);
+}
+
+void
+sys_mutex_unlock(sys_mutex_t *mutex)
+{
+  /* nothing to do, no multithreading supported */
+  LWIP_ASSERT("mutex != NULL", mutex != NULL);
+  LWIP_ASSERT("*mutex >= 1", *mutex >= 1);
+  /* we count down just to check the correct pairing of lock/unlock */
+  (*mutex)--;
+  LWIP_ASSERT("*mutex >= 1", *mutex >= 1);
+}
+
+
+sys_thread_t
+sys_thread_new(const char *name, lwip_thread_fn function, void *arg, int stacksize, int prio)
+{
+  LWIP_UNUSED_ARG(name);
+  LWIP_UNUSED_ARG(function);
+  LWIP_UNUSED_ARG(arg);
+  LWIP_UNUSED_ARG(stacksize);
+  LWIP_UNUSED_ARG(prio);
+  /* threads not supported */
+  return 0;
+}
+
+err_t
+sys_mbox_new(sys_mbox_t *mbox, int size)
+{
+  int mboxsize = size;
+  LWIP_ASSERT("mbox != NULL", mbox != NULL);
+  LWIP_ASSERT("size >= 0", size >= 0);
+  if (size == 0) {
+    mboxsize = 1024;
+  }
+  mbox->head = mbox->tail = 0;
+  mbox->sem = mbox; /* just point to something for sys_mbox_valid() */
+  mbox->q_mem = (void**)malloc(sizeof(void*)*mboxsize);
+  mbox->size = mboxsize;
+  mbox->used = 0;
+
+  memset(mbox->q_mem, 0, sizeof(void*)*mboxsize);
+  return ERR_OK;
+}
+
+void
+sys_mbox_free(sys_mbox_t *mbox)
+{
+  /* parameter check */
+  LWIP_ASSERT("mbox != NULL", mbox != NULL);
+  LWIP_ASSERT("mbox->sem != NULL", mbox->sem != NULL);
+  LWIP_ASSERT("mbox->sem == mbox", mbox->sem == mbox);
+  LWIP_ASSERT("mbox->q_mem != NULL", mbox->q_mem != NULL);
+  mbox->sem = NULL;
+  free(mbox->q_mem);
+  mbox->q_mem = NULL;
+}
+
+void
+sys_mbox_set_invalid(sys_mbox_t *mbox)
+{
+  LWIP_ASSERT("mbox != NULL", mbox != NULL);
+  LWIP_ASSERT("mbox->q_mem == NULL", mbox->q_mem == NULL);
+  mbox->sem = NULL;
+  mbox->q_mem = NULL;
+}
+
+void
+sys_mbox_post(sys_mbox_t *q, void *msg)
+{
+  LWIP_ASSERT("q != SYS_MBOX_NULL", q != SYS_MBOX_NULL);
+  LWIP_ASSERT("q->sem == q", q->sem == q);
+  LWIP_ASSERT("q->q_mem != NULL", q->q_mem != NULL);
+  LWIP_ASSERT("q->used >= 0", q->used >= 0);
+  LWIP_ASSERT("q->size > 0", q->size > 0);
+
+  LWIP_ASSERT("mbox already full", q->used < q->size);
+
+  q->q_mem[q->head] = msg;
+  q->head++;
+  if (q->head >= (unsigned int)q->size) {
+    q->head = 0;
+  }
+  LWIP_ASSERT("mbox is full!", q->head != q->tail);
+  q->used++;
+}
+
+err_t
+sys_mbox_trypost(sys_mbox_t *q, void *msg)
+{
+  LWIP_ASSERT("q != SYS_MBOX_NULL", q != SYS_MBOX_NULL);
+  LWIP_ASSERT("q->sem == q", q->sem == q);
+  LWIP_ASSERT("q->q_mem != NULL", q->q_mem != NULL);
+  LWIP_ASSERT("q->used >= 0", q->used >= 0);
+  LWIP_ASSERT("q->size > 0", q->size > 0);
+  LWIP_ASSERT("q->used <= q->size", q->used <= q->size);
+
+  if (q->used == q->size) {
+    return ERR_MEM;
+  }
+  sys_mbox_post(q, msg);
+  return ERR_OK;
+}
+
+err_t
+sys_mbox_trypost_fromisr(sys_mbox_t *q, void *msg)
+{
+  return sys_mbox_trypost(q, msg);
+}
+
+u32_t
+sys_arch_mbox_fetch(sys_mbox_t *q, void **msg, u32_t timeout)
+{
+  u32_t ret = 0;
+  u32_t ret2;
+  LWIP_ASSERT("q != SYS_MBOX_NULL", q != SYS_MBOX_NULL);
+  LWIP_ASSERT("q->sem == q", q->sem == q);
+  LWIP_ASSERT("q->q_mem != NULL", q->q_mem != NULL);
+  LWIP_ASSERT("q->used >= 0", q->used >= 0);
+  LWIP_ASSERT("q->size > 0", q->size > 0);
+
+  if (q->used == 0) {
+    /* need to wait */
+    /* need to wait */
+    if(!timeout)
+    {
+      /* wait infinite */
+      LWIP_ASSERT("cannot wait without waiting callback", the_waiting_fn != NULL);
+      do {
+        int expectSomething = the_waiting_fn(NULL, q);
+        LWIP_ASSERT("q->used >= 0", q->used >= 0);
+        LWIP_ASSERT("expecting item available but it's 0", !expectSomething || (q->used > 0));
+        ret++;
+        if (ret == SYS_ARCH_TIMEOUT) {
+          ret--;
+        }
+      } while(q->used == 0);
+    }
+    else
+    {
+      if (the_waiting_fn) {
+        int expectSomething = the_waiting_fn(NULL, q);
+        LWIP_ASSERT("expecting item available count but it's 0", !expectSomething || (q->used > 0));
+      }
+      LWIP_ASSERT("q->used >= 0", q->used >= 0);
+      if (q->used == 0) {
+        if(msg) {
+          *msg = NULL;
+        }
+        return SYS_ARCH_TIMEOUT;
+      }
+      ret = 1;
+    }
+  }
+  LWIP_ASSERT("q->used > 0", q->used > 0);
+  ret2 = sys_arch_mbox_tryfetch(q, msg);
+  LWIP_ASSERT("got no message", ret2 == 0);
+  return ret;
+}
+
+u32_t
+sys_arch_mbox_tryfetch(sys_mbox_t *q, void **msg)
+{
+  LWIP_ASSERT("q != SYS_MBOX_NULL", q != SYS_MBOX_NULL);
+  LWIP_ASSERT("q->sem == q", q->sem == q);
+  LWIP_ASSERT("q->q_mem != NULL", q->q_mem != NULL);
+  LWIP_ASSERT("q->used >= 0", q->used >= 0);
+  LWIP_ASSERT("q->size > 0", q->size > 0);
+
+  if (!q->used) {
+    return SYS_ARCH_TIMEOUT;
+  }
+  if(msg) {
+    *msg = q->q_mem[q->tail];
+  }
+
+  q->tail++;
+  if (q->tail >= (unsigned int)q->size) {
+    q->tail = 0;
+  }
+  q->used--;
+  LWIP_ASSERT("q->used >= 0", q->used >= 0);
+  return 0;
+}
+
+#if LWIP_NETCONN_SEM_PER_THREAD
+#error LWIP_NETCONN_SEM_PER_THREAD==1 not supported
+#endif /* LWIP_NETCONN_SEM_PER_THREAD */
+
+#endif /* !NO_SYS */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/test/unit/arch/sys_arch.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/test/unit/arch/sys_arch.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/test/unit/arch/sys_arch.h	(revision 457)
@@ -0,0 +1,72 @@
+/*
+ * Copyright (c) 2017 Simon Goldschmidt
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission. 
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ * 
+ * Author: Simon Goldschmidt
+ *
+ */
+#ifndef LWIP_HDR_TEST_SYS_ARCH_H
+#define LWIP_HDR_TEST_SYS_ARCH_H
+
+typedef int sys_sem_t;
+#define sys_sem_valid(sema) ((sema) != NULL)
+
+typedef int sys_mutex_t;
+#define sys_mutex_valid(mutex) (((mutex) != NULL)
+
+struct lwip_mbox {
+  void* sem;
+  void** q_mem;
+  unsigned int head, tail;
+  int size;
+  int used;
+};
+typedef struct lwip_mbox sys_mbox_t;
+#define SYS_MBOX_NULL NULL
+#define sys_mbox_valid(mbox) ((mbox != NULL) && ((mbox)->sem != NULL)  && ((mbox)->sem != (void*)-1))
+#define sys_mbox_valid_val(mbox) (((mbox).sem != NULL)  && ((mbox).sem != (void*)-1))
+
+/* DWORD (thread id) is used for sys_thread_t but we won't include windows.h */
+typedef u32_t sys_thread_t;
+
+#define SYS_ARCH_DECL_PROTECT(lev)
+#define SYS_ARCH_PROTECT(lev)
+#define SYS_ARCH_UNPROTECT(lev)
+
+/* to implement doing something while blocking on an mbox or semaphore:
+ * pass a function to test_sys_arch_wait_callback() that returns
+ * '0' if waiting again and
+ * '1' if now there should be something to do (used for asserting)
+ */
+typedef int (*test_sys_arch_waiting_fn)(sys_sem_t* wait_sem, sys_mbox_t* wait_mbox);
+void test_sys_arch_wait_callback(test_sys_arch_waiting_fn waiting_fn);
+
+/* current time */
+extern u32_t lwip_sys_now;
+
+#endif /* LWIP_HDR_TEST_SYS_ARCH_H */
+
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/test/unit/core/test_def.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/test/unit/core/test_def.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/test/unit/core/test_def.c	(revision 457)
@@ -0,0 +1,84 @@
+#include "test_def.h"
+
+#include "lwip/def.h"
+
+#define MAGIC_UNTOUCHED_BYTE  0x7a
+#define TEST_BUFSIZE          32
+#define GUARD_SIZE            4
+
+/* Setups/teardown functions */
+
+static void
+def_setup(void)
+{
+}
+
+static void
+def_teardown(void)
+{
+}
+
+static void
+def_check_range_untouched(const char *buf, size_t len)
+{
+  size_t i;
+
+  for (i = 0; i < len; i++) {
+    fail_unless(buf[i] == (char)MAGIC_UNTOUCHED_BYTE);
+  }
+}
+
+static void test_def_itoa(int number, const char *expected)
+{
+  char buf[TEST_BUFSIZE];
+  char *test_buf = &buf[GUARD_SIZE];
+
+  size_t exp_len = strlen(expected);
+  fail_unless(exp_len + 4 < (TEST_BUFSIZE - (2 * GUARD_SIZE)));
+
+  memset(buf, MAGIC_UNTOUCHED_BYTE, sizeof(buf));
+  lwip_itoa(test_buf, exp_len + 1, number);
+  def_check_range_untouched(buf, GUARD_SIZE);
+  fail_unless(test_buf[exp_len] == 0);
+  fail_unless(!memcmp(test_buf, expected, exp_len));
+  def_check_range_untouched(&test_buf[exp_len + 1], TEST_BUFSIZE - GUARD_SIZE - exp_len - 1);
+
+  /* check with too small buffer */
+  memset(buf, MAGIC_UNTOUCHED_BYTE, sizeof(buf));
+  lwip_itoa(test_buf, exp_len, number);
+  def_check_range_untouched(buf, GUARD_SIZE);
+  def_check_range_untouched(&test_buf[exp_len + 1], TEST_BUFSIZE - GUARD_SIZE - exp_len - 1);
+
+  /* check with too large buffer */
+  memset(buf, MAGIC_UNTOUCHED_BYTE, sizeof(buf));
+  lwip_itoa(test_buf, exp_len + 4, number);
+  def_check_range_untouched(buf, GUARD_SIZE);
+  fail_unless(test_buf[exp_len] == 0);
+  fail_unless(!memcmp(test_buf, expected, exp_len));
+  def_check_range_untouched(&test_buf[exp_len + 4], TEST_BUFSIZE - GUARD_SIZE - exp_len - 4);
+}
+
+START_TEST(test_def_lwip_itoa)
+{
+  LWIP_UNUSED_ARG(_i);
+
+  test_def_itoa(0, "0");
+  test_def_itoa(1, "1");
+  test_def_itoa(-1, "-1");
+  test_def_itoa(15, "15");
+  test_def_itoa(-15, "-15");
+  test_def_itoa(156, "156");
+  test_def_itoa(1192, "1192");
+  test_def_itoa(-156, "-156");
+}
+END_TEST
+
+/** Create the suite including all tests for this module */
+Suite *
+def_suite(void)
+{
+  testfunc tests[] = {
+    TESTFUNC(test_def_lwip_itoa)
+  };
+  return create_suite("DEF", tests, sizeof(tests)/sizeof(testfunc), def_setup, def_teardown);
+}
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/test/unit/core/test_def.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/test/unit/core/test_def.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/test/unit/core/test_def.h	(revision 457)
@@ -0,0 +1,8 @@
+#ifndef LWIP_HDR_TEST_DEF_H
+#define LWIP_HDR_TEST_DEF_H
+
+#include "../lwip_check.h"
+
+Suite *def_suite(void);
+
+#endif
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/test/unit/core/test_mem.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/test/unit/core/test_mem.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/test/unit/core/test_mem.c	(revision 457)
@@ -0,0 +1,224 @@
+#include "test_mem.h"
+
+#include "lwip/mem.h"
+#include "lwip/stats.h"
+
+#if !LWIP_STATS || !MEM_STATS
+#error "This tests needs MEM-statistics enabled"
+#endif
+#if LWIP_DNS
+#error "This test needs DNS turned off (as it mallocs on init)"
+#endif
+
+/* Setups/teardown functions */
+
+static void
+mem_setup(void)
+{
+  lwip_check_ensure_no_alloc(SKIP_POOL(MEMP_SYS_TIMEOUT));
+}
+
+static void
+mem_teardown(void)
+{
+  lwip_check_ensure_no_alloc(SKIP_POOL(MEMP_SYS_TIMEOUT));
+}
+
+
+/* Test functions */
+
+/** Call mem_malloc, mem_free and mem_trim and check stats */
+START_TEST(test_mem_one)
+{
+#define SIZE1   16
+#define SIZE1_2 12
+#define SIZE2   16
+  void *p1, *p2;
+  mem_size_t s1, s2;
+  LWIP_UNUSED_ARG(_i);
+
+  fail_unless(lwip_stats.mem.used == 0);
+
+  p1 = mem_malloc(SIZE1);
+  fail_unless(p1 != NULL);
+  fail_unless(lwip_stats.mem.used >= SIZE1);
+  s1 = lwip_stats.mem.used;
+
+  p2 = mem_malloc(SIZE2);
+  fail_unless(p2 != NULL);
+  fail_unless(lwip_stats.mem.used >= SIZE2 + s1);
+  s2 = lwip_stats.mem.used;
+
+  mem_trim(p1, SIZE1_2);
+
+  mem_free(p2);
+  fail_unless(lwip_stats.mem.used <= s2 - SIZE2);
+
+  mem_free(p1);
+  fail_unless(lwip_stats.mem.used == 0);
+}
+END_TEST
+
+static void malloc_keep_x(int x, int num, int size, int freestep)
+{
+   int i;
+   void* p[16];
+   LWIP_ASSERT("invalid size", size >= 0 && size < (mem_size_t)-1);
+   memset(p, 0, sizeof(p));
+   for(i = 0; i < num && i < 16; i++) {
+      p[i] = mem_malloc((mem_size_t)size);
+      fail_unless(p[i] != NULL);
+   }
+   for(i = 0; i < num && i < 16; i += freestep) {
+      if (i == x) {
+         continue;
+      }
+      mem_free(p[i]);
+      p[i] = NULL;
+   }
+   for(i = 0; i < num && i < 16; i++) {
+      if (i == x) {
+         continue;
+      }
+      if (p[i] != NULL) {
+         mem_free(p[i]);
+         p[i] = NULL;
+      }
+   }
+   fail_unless(p[x] != NULL);
+   mem_free(p[x]);
+}
+
+START_TEST(test_mem_random)
+{
+  const int num = 16;
+  int x;
+  int size;
+  int freestep;
+  LWIP_UNUSED_ARG(_i);
+
+  fail_unless(lwip_stats.mem.used == 0);
+
+  for (x = 0; x < num; x++) {
+     for (size = 1; size < 32; size++) {
+        for (freestep = 1; freestep <= 3; freestep++) {
+          fail_unless(lwip_stats.mem.used == 0);
+          malloc_keep_x(x, num, size, freestep);
+          fail_unless(lwip_stats.mem.used == 0);
+        }
+     }
+  }
+}
+END_TEST
+
+START_TEST(test_mem_invalid_free)
+{
+  u8_t *ptr, *ptr_low, *ptr_high;
+  LWIP_UNUSED_ARG(_i);
+
+  fail_unless(lwip_stats.mem.used == 0);
+  fail_unless(lwip_stats.mem.illegal == 0);
+
+  ptr = (u8_t *)mem_malloc(1);
+  fail_unless(ptr != NULL);
+  fail_unless(lwip_stats.mem.used != 0);
+
+  ptr_low = ptr - 0x10;
+  mem_free(ptr_low);
+  fail_unless(lwip_stats.mem.illegal == 1);
+  lwip_stats.mem.illegal = 0;
+
+  ptr_high = ptr + (MEM_SIZE * 2);
+  mem_free(ptr_high);
+  fail_unless(lwip_stats.mem.illegal == 1);
+  lwip_stats.mem.illegal = 0;
+
+  mem_free(ptr);
+  fail_unless(lwip_stats.mem.illegal == 0);
+  fail_unless(lwip_stats.mem.used == 0);
+}
+END_TEST
+
+START_TEST(test_mem_double_free)
+{
+  u8_t *ptr1b, *ptr1, *ptr2, *ptr3;
+  LWIP_UNUSED_ARG(_i);
+
+  fail_unless(lwip_stats.mem.used == 0);
+  fail_unless(lwip_stats.mem.illegal == 0);
+
+  ptr1 = (u8_t *)mem_malloc(1);
+  fail_unless(ptr1 != NULL);
+  fail_unless(lwip_stats.mem.used != 0);
+
+  ptr2 = (u8_t *)mem_malloc(1);
+  fail_unless(ptr2 != NULL);
+  fail_unless(lwip_stats.mem.used != 0);
+
+  ptr3 = (u8_t *)mem_malloc(1);
+  fail_unless(ptr3 != NULL);
+  fail_unless(lwip_stats.mem.used != 0);
+
+  /* free the middle mem */
+  mem_free(ptr2);
+  fail_unless(lwip_stats.mem.illegal == 0);
+
+  /* double-free of middle mem: should fail */
+  mem_free(ptr2);
+  fail_unless(lwip_stats.mem.illegal == 1);
+  lwip_stats.mem.illegal = 0;
+
+  /* free upper memory and try again */
+  mem_free(ptr3);
+  fail_unless(lwip_stats.mem.illegal == 0);
+
+  mem_free(ptr2);
+  fail_unless(lwip_stats.mem.illegal == 1);
+  lwip_stats.mem.illegal = 0;
+
+  /* free lower memory and try again */
+  mem_free(ptr1);
+  fail_unless(lwip_stats.mem.illegal == 0);
+  fail_unless(lwip_stats.mem.used == 0);
+
+  mem_free(ptr2);
+  fail_unless(lwip_stats.mem.illegal == 1);
+  fail_unless(lwip_stats.mem.used == 0);
+  lwip_stats.mem.illegal = 0;
+
+  /* reallocate lowest memory, now overlapping already freed ptr2 */
+#ifndef MIN_SIZE
+#define MIN_SIZE 12
+#endif
+  ptr1b = (u8_t *)mem_malloc(MIN_SIZE * 2);
+  fail_unless(ptr1b != NULL);
+  fail_unless(lwip_stats.mem.used != 0);
+
+  mem_free(ptr2);
+  fail_unless(lwip_stats.mem.illegal == 1);
+  lwip_stats.mem.illegal = 0;
+
+  memset(ptr1b, 1, MIN_SIZE * 2);
+
+  mem_free(ptr2);
+  fail_unless(lwip_stats.mem.illegal == 1);
+  lwip_stats.mem.illegal = 0;
+
+  mem_free(ptr1b);
+  fail_unless(lwip_stats.mem.illegal == 0);
+  fail_unless(lwip_stats.mem.used == 0);
+}
+END_TEST
+
+/** Create the suite including all tests for this module */
+Suite *
+mem_suite(void)
+{
+  testfunc tests[] = {
+    TESTFUNC(test_mem_one),
+    TESTFUNC(test_mem_random),
+    TESTFUNC(test_mem_invalid_free),
+    TESTFUNC(test_mem_double_free)
+  };
+  return create_suite("MEM", tests, sizeof(tests)/sizeof(testfunc), mem_setup, mem_teardown);
+}
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/test/unit/core/test_mem.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/test/unit/core/test_mem.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/test/unit/core/test_mem.h	(revision 457)
@@ -0,0 +1,8 @@
+#ifndef LWIP_HDR_TEST_MEM_H
+#define LWIP_HDR_TEST_MEM_H
+
+#include "../lwip_check.h"
+
+Suite *mem_suite(void);
+
+#endif
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/test/unit/core/test_netif.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/test/unit/core/test_netif.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/test/unit/core/test_netif.c	(revision 457)
@@ -0,0 +1,227 @@
+#include "test_netif.h"
+
+#include "lwip/netif.h"
+#include "lwip/stats.h"
+#include "lwip/etharp.h"
+#include "netif/ethernet.h"
+
+#if !LWIP_NETIF_EXT_STATUS_CALLBACK
+#error "This tests needs LWIP_NETIF_EXT_STATUS_CALLBACK enabled"
+#endif
+
+struct netif net_test;
+
+
+/* Setups/teardown functions */
+
+static void
+netif_setup(void)
+{
+  lwip_check_ensure_no_alloc(SKIP_POOL(MEMP_SYS_TIMEOUT));
+}
+
+static void
+netif_teardown(void)
+{
+  lwip_check_ensure_no_alloc(SKIP_POOL(MEMP_SYS_TIMEOUT));
+}
+
+/* test helper functions */
+
+static err_t
+testif_tx_func(struct netif *netif, struct pbuf *p)
+{
+  LWIP_UNUSED_ARG(netif);
+  LWIP_UNUSED_ARG(p);
+  return ERR_OK;
+}
+
+static err_t
+testif_init(struct netif *netif)
+{
+  netif->name[0] = 'c';
+  netif->name[1] = 'h';
+  netif->output = etharp_output;
+  netif->linkoutput = testif_tx_func;
+  netif->mtu = 1500;
+  netif->hwaddr_len = 6;
+  netif->flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP | NETIF_FLAG_ETHERNET | NETIF_FLAG_IGMP | NETIF_FLAG_MLD6;
+
+  netif->hwaddr[0] = 0x02;
+  netif->hwaddr[1] = 0x03;
+  netif->hwaddr[2] = 0x04;
+  netif->hwaddr[3] = 0x05;
+  netif->hwaddr[4] = 0x06;
+  netif->hwaddr[5] = 0x07;
+
+  return ERR_OK;
+}
+
+#define MAX_NSC_REASON_IDX 10
+static netif_nsc_reason_t expected_reasons;
+static int callback_ctr;
+
+static int dummy_active;
+
+static void
+test_netif_ext_callback_dummy(struct netif* netif, netif_nsc_reason_t reason, const netif_ext_callback_args_t* args)
+{
+  LWIP_UNUSED_ARG(netif);
+  LWIP_UNUSED_ARG(reason);
+  LWIP_UNUSED_ARG(args);
+
+  fail_unless(dummy_active);
+}
+
+static void
+test_netif_ext_callback(struct netif* netif, netif_nsc_reason_t reason, const netif_ext_callback_args_t* args)
+{
+  LWIP_UNUSED_ARG(args); /* @todo */
+  callback_ctr++;
+
+  fail_unless(netif == &net_test);
+
+  fail_unless(expected_reasons == reason);
+}
+
+/* Test functions */
+
+NETIF_DECLARE_EXT_CALLBACK(netif_callback_1)
+NETIF_DECLARE_EXT_CALLBACK(netif_callback_2)
+NETIF_DECLARE_EXT_CALLBACK(netif_callback_3)
+
+START_TEST(test_netif_extcallbacks)
+{
+  ip4_addr_t addr;
+  ip4_addr_t netmask;
+  ip4_addr_t gw;
+  LWIP_UNUSED_ARG(_i);
+
+  IP4_ADDR(&addr, 0, 0, 0, 0);
+  IP4_ADDR(&netmask, 0, 0, 0, 0);
+  IP4_ADDR(&gw, 0, 0, 0, 0);
+
+  netif_add_ext_callback(&netif_callback_3, test_netif_ext_callback_dummy);
+  netif_add_ext_callback(&netif_callback_2, test_netif_ext_callback);
+  netif_add_ext_callback(&netif_callback_1, test_netif_ext_callback_dummy);
+
+  dummy_active = 1;
+
+  /* positive tests: check that single events come as expected */
+
+  expected_reasons = LWIP_NSC_NETIF_ADDED;
+  callback_ctr = 0;
+  netif_add(&net_test, &addr, &netmask, &gw, &net_test, testif_init, ethernet_input);
+  fail_unless(callback_ctr == 1);
+
+  expected_reasons = LWIP_NSC_LINK_CHANGED;
+  callback_ctr = 0;
+  netif_set_link_up(&net_test);
+  fail_unless(callback_ctr == 1);
+
+  expected_reasons = LWIP_NSC_STATUS_CHANGED;
+  callback_ctr = 0;
+  netif_set_up(&net_test);
+  fail_unless(callback_ctr == 1);
+
+  IP4_ADDR(&addr, 1, 2, 3, 4);
+  expected_reasons = LWIP_NSC_IPV4_ADDRESS_CHANGED;
+  callback_ctr = 0;
+  netif_set_ipaddr(&net_test, &addr);
+  fail_unless(callback_ctr == 1);
+
+  IP4_ADDR(&netmask, 255, 255, 255, 0);
+  expected_reasons = LWIP_NSC_IPV4_NETMASK_CHANGED;
+  callback_ctr = 0;
+  netif_set_netmask(&net_test, &netmask);
+  fail_unless(callback_ctr == 1);
+
+  IP4_ADDR(&gw, 1, 2, 3, 254);
+  expected_reasons = LWIP_NSC_IPV4_GATEWAY_CHANGED;
+  callback_ctr = 0;
+  netif_set_gw(&net_test, &gw);
+  fail_unless(callback_ctr == 1);
+
+  IP4_ADDR(&addr, 0, 0, 0, 0);
+  expected_reasons = LWIP_NSC_IPV4_ADDRESS_CHANGED;
+  callback_ctr = 0;
+  netif_set_ipaddr(&net_test, &addr);
+  fail_unless(callback_ctr == 1);
+
+  IP4_ADDR(&netmask, 0, 0, 0, 0);
+  expected_reasons = LWIP_NSC_IPV4_NETMASK_CHANGED;
+  callback_ctr = 0;
+  netif_set_netmask(&net_test, &netmask);
+  fail_unless(callback_ctr == 1);
+
+  IP4_ADDR(&gw, 0, 0, 0, 0);
+  expected_reasons = LWIP_NSC_IPV4_GATEWAY_CHANGED;
+  callback_ctr = 0;
+  netif_set_gw(&net_test, &gw);
+  fail_unless(callback_ctr == 1);
+
+  /* check for multi-events (only one combined callback expected) */
+
+  IP4_ADDR(&addr, 1, 2, 3, 4);
+  IP4_ADDR(&netmask, 255, 255, 255, 0);
+  IP4_ADDR(&gw, 1, 2, 3, 254);
+  expected_reasons = (netif_nsc_reason_t)(LWIP_NSC_IPV4_ADDRESS_CHANGED | LWIP_NSC_IPV4_NETMASK_CHANGED |
+                                          LWIP_NSC_IPV4_GATEWAY_CHANGED | LWIP_NSC_IPV4_SETTINGS_CHANGED);
+  callback_ctr = 0;
+  netif_set_addr(&net_test, &addr, &netmask, &gw);
+  fail_unless(callback_ctr == 1);
+
+  /* check that for no-change, no callback is expected */
+  expected_reasons = LWIP_NSC_NONE;
+  callback_ctr = 0;
+  netif_set_ipaddr(&net_test, &addr);
+  fail_unless(callback_ctr == 0);
+
+  netif_set_netmask(&net_test, &netmask);
+  callback_ctr = 0;
+  fail_unless(callback_ctr == 0);
+
+  callback_ctr = 0;
+  netif_set_gw(&net_test, &gw);
+  fail_unless(callback_ctr == 0);
+
+  callback_ctr = 0;
+  netif_set_addr(&net_test, &addr, &netmask, &gw);
+  fail_unless(callback_ctr == 0);
+
+  /* check for single-events */
+  IP4_ADDR(&addr, 1, 2, 3, 5);
+  expected_reasons = (netif_nsc_reason_t)(LWIP_NSC_IPV4_ADDRESS_CHANGED | LWIP_NSC_IPV4_SETTINGS_CHANGED);
+  callback_ctr = 0;
+  netif_set_addr(&net_test, &addr, &netmask, &gw);
+  fail_unless(callback_ctr == 1);
+
+  expected_reasons = LWIP_NSC_STATUS_CHANGED;
+  callback_ctr = 0;
+  netif_set_down(&net_test);
+  fail_unless(callback_ctr == 1);
+
+  expected_reasons = LWIP_NSC_NETIF_REMOVED;
+  callback_ctr = 0;
+  netif_remove(&net_test);
+  fail_unless(callback_ctr == 1);
+
+  expected_reasons = LWIP_NSC_NONE;
+
+  netif_remove_ext_callback(&netif_callback_2);
+  netif_remove_ext_callback(&netif_callback_3);
+  netif_remove_ext_callback(&netif_callback_1);
+  dummy_active = 0;
+}
+END_TEST
+
+
+/** Create the suite including all tests for this module */
+Suite *
+netif_suite(void)
+{
+  testfunc tests[] = {
+    TESTFUNC(test_netif_extcallbacks)
+  };
+  return create_suite("NETIF", tests, sizeof(tests)/sizeof(testfunc), netif_setup, netif_teardown);
+}
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/test/unit/core/test_netif.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/test/unit/core/test_netif.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/test/unit/core/test_netif.h	(revision 457)
@@ -0,0 +1,8 @@
+#ifndef LWIP_HDR_TEST_NETIF_H
+#define LWIP_HDR_TEST_NETIF_H
+
+#include "../lwip_check.h"
+
+Suite *netif_suite(void);
+
+#endif
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/test/unit/core/test_pbuf.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/test/unit/core/test_pbuf.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/test/unit/core/test_pbuf.c	(revision 457)
@@ -0,0 +1,271 @@
+#include "test_pbuf.h"
+
+#include "lwip/pbuf.h"
+#include "lwip/stats.h"
+
+#if !LWIP_STATS || !MEM_STATS ||!MEMP_STATS
+#error "This tests needs MEM- and MEMP-statistics enabled"
+#endif
+#if LWIP_DNS
+#error "This test needs DNS turned off (as it mallocs on init)"
+#endif
+#if !LWIP_TCP || !TCP_QUEUE_OOSEQ || !LWIP_WND_SCALE
+#error "This test needs TCP OOSEQ queueing and window scaling enabled"
+#endif
+
+/* Setups/teardown functions */
+
+static void
+pbuf_setup(void)
+{
+  lwip_check_ensure_no_alloc(SKIP_POOL(MEMP_SYS_TIMEOUT));
+}
+
+static void
+pbuf_teardown(void)
+{
+  lwip_check_ensure_no_alloc(SKIP_POOL(MEMP_SYS_TIMEOUT));
+}
+
+
+#define TESTBUFSIZE_1 65535
+#define TESTBUFSIZE_2 65530
+#define TESTBUFSIZE_3 50050
+static u8_t testbuf_1[TESTBUFSIZE_1];
+static u8_t testbuf_1a[TESTBUFSIZE_1];
+static u8_t testbuf_2[TESTBUFSIZE_2];
+static u8_t testbuf_2a[TESTBUFSIZE_2];
+static u8_t testbuf_3[TESTBUFSIZE_3];
+static u8_t testbuf_3a[TESTBUFSIZE_3];
+
+/* Test functions */
+START_TEST(test_pbuf_alloc_zero_pbufs)
+{
+  struct pbuf *p;
+  LWIP_UNUSED_ARG(_i);
+
+  p = pbuf_alloc(PBUF_RAW, 0, PBUF_ROM);
+  fail_unless(p != NULL);
+  if (p != NULL) {
+    pbuf_free(p);
+  }
+
+  p = pbuf_alloc(PBUF_RAW, 0, PBUF_RAM);
+  fail_unless(p != NULL);
+  if (p != NULL) {
+    pbuf_free(p);
+  }
+
+  p = pbuf_alloc(PBUF_RAW, 0, PBUF_REF);
+  fail_unless(p != NULL);
+  if (p != NULL) {
+    pbuf_free(p);
+  }
+
+  p = pbuf_alloc(PBUF_RAW, 0, PBUF_POOL);
+  fail_unless(p != NULL);
+  if (p != NULL) {
+    pbuf_free(p);
+  }
+}
+END_TEST
+
+/** Call pbuf_copy on a pbuf with zero length */
+START_TEST(test_pbuf_copy_zero_pbuf)
+{
+  struct pbuf *p1, *p2, *p3;
+  err_t err;
+  LWIP_UNUSED_ARG(_i);
+
+  fail_unless(lwip_stats.mem.used == 0);
+  fail_unless(MEMP_STATS_GET(used, MEMP_PBUF_POOL) == 0);
+
+  p1 = pbuf_alloc(PBUF_RAW, 1024, PBUF_RAM);
+  fail_unless(p1 != NULL);
+  fail_unless(p1->ref == 1);
+
+  p2 = pbuf_alloc(PBUF_RAW, 2, PBUF_POOL);
+  fail_unless(p2 != NULL);
+  fail_unless(p2->ref == 1);
+  p2->len = p2->tot_len = 0;
+
+  pbuf_cat(p1, p2);
+  fail_unless(p1->ref == 1);
+  fail_unless(p2->ref == 1);
+
+  p3 = pbuf_alloc(PBUF_RAW, p1->tot_len, PBUF_POOL);
+  err = pbuf_copy(p3, p1);
+  fail_unless(err == ERR_VAL);
+
+  pbuf_free(p1);
+  pbuf_free(p3);
+  fail_unless(lwip_stats.mem.used == 0);
+
+  fail_unless(lwip_stats.mem.used == 0);
+  fail_unless(MEMP_STATS_GET(used, MEMP_PBUF_POOL) == 0);
+}
+END_TEST
+
+START_TEST(test_pbuf_split_64k_on_small_pbufs)
+{
+  struct pbuf *p, *rest=NULL;
+  LWIP_UNUSED_ARG(_i);
+
+  p = pbuf_alloc(PBUF_RAW, 1, PBUF_POOL);
+  pbuf_split_64k(p, &rest);
+  fail_unless(p->tot_len == 1);
+  pbuf_free(p);
+}
+END_TEST
+
+START_TEST(test_pbuf_queueing_bigger_than_64k)
+{
+  int i;
+  err_t err;
+  struct pbuf *p1, *p2, *p3, *rest2=NULL, *rest3=NULL;
+  LWIP_UNUSED_ARG(_i);
+
+  for(i = 0; i < TESTBUFSIZE_1; i++) {
+    testbuf_1[i] = (u8_t)rand();
+  }
+  for(i = 0; i < TESTBUFSIZE_2; i++) {
+    testbuf_2[i] = (u8_t)rand();
+  }
+  for(i = 0; i < TESTBUFSIZE_3; i++) {
+    testbuf_3[i] = (u8_t)rand();
+  }
+
+  p1 = pbuf_alloc(PBUF_RAW, TESTBUFSIZE_1, PBUF_POOL);
+  fail_unless(p1 != NULL);
+  p2 = pbuf_alloc(PBUF_RAW, TESTBUFSIZE_2, PBUF_POOL);
+  fail_unless(p2 != NULL);
+  p3 = pbuf_alloc(PBUF_RAW, TESTBUFSIZE_3, PBUF_POOL);
+  fail_unless(p3 != NULL);
+  err = pbuf_take(p1, testbuf_1, TESTBUFSIZE_1);
+  fail_unless(err == ERR_OK);
+  err = pbuf_take(p2, testbuf_2, TESTBUFSIZE_2);
+  fail_unless(err == ERR_OK);
+  err = pbuf_take(p3, testbuf_3, TESTBUFSIZE_3);
+  fail_unless(err == ERR_OK);
+
+  pbuf_cat(p1, p2);
+  pbuf_cat(p1, p3);
+
+  pbuf_split_64k(p1, &rest2);
+  fail_unless(p1->tot_len == TESTBUFSIZE_1);
+  fail_unless(rest2->tot_len == (u16_t)((TESTBUFSIZE_2+TESTBUFSIZE_3) & 0xFFFF));
+  pbuf_split_64k(rest2, &rest3);
+  fail_unless(rest2->tot_len == TESTBUFSIZE_2);
+  fail_unless(rest3->tot_len == TESTBUFSIZE_3);
+
+  pbuf_copy_partial(p1, testbuf_1a, TESTBUFSIZE_1, 0);
+  pbuf_copy_partial(rest2, testbuf_2a, TESTBUFSIZE_2, 0);
+  pbuf_copy_partial(rest3, testbuf_3a, TESTBUFSIZE_3, 0);
+  fail_if(memcmp(testbuf_1, testbuf_1a, TESTBUFSIZE_1));
+  fail_if(memcmp(testbuf_2, testbuf_2a, TESTBUFSIZE_2));
+  fail_if(memcmp(testbuf_3, testbuf_3a, TESTBUFSIZE_3));
+
+  pbuf_free(p1);
+  pbuf_free(rest2);
+  pbuf_free(rest3);
+}
+END_TEST
+
+/* Test for bug that writing with pbuf_take_at() did nothing
+ * and returned ERR_OK when writing at beginning of a pbuf
+ * in the chain.
+ */
+START_TEST(test_pbuf_take_at_edge)
+{
+  err_t res;
+  u8_t *out;
+  int i;
+  u8_t testdata[] = { 0x01, 0x08, 0x82, 0x02 };
+  struct pbuf *p = pbuf_alloc(PBUF_RAW, 1024, PBUF_POOL);
+  struct pbuf *q = p->next;
+  LWIP_UNUSED_ARG(_i);
+  /* alloc big enough to get a chain of pbufs */
+  fail_if(p->tot_len == p->len);
+  memset(p->payload, 0, p->len);
+  memset(q->payload, 0, q->len);
+
+  /* copy data to the beginning of first pbuf */
+  res = pbuf_take_at(p, &testdata, sizeof(testdata), 0);
+  fail_unless(res == ERR_OK);
+
+  out = (u8_t*)p->payload;
+  for (i = 0; i < (int)sizeof(testdata); i++) {
+    fail_unless(out[i] == testdata[i],
+      "Bad data at pos %d, was %02X, expected %02X", i, out[i], testdata[i]);
+  }
+
+  /* copy data to the just before end of first pbuf */
+  res = pbuf_take_at(p, &testdata, sizeof(testdata), p->len - 1);
+  fail_unless(res == ERR_OK);
+
+  out = (u8_t*)p->payload;
+  fail_unless(out[p->len - 1] == testdata[0],
+    "Bad data at pos %d, was %02X, expected %02X", p->len - 1, out[p->len - 1], testdata[0]);
+  out = (u8_t*)q->payload;
+  for (i = 1; i < (int)sizeof(testdata); i++) {
+    fail_unless(out[i-1] == testdata[i],
+      "Bad data at pos %d, was %02X, expected %02X", p->len - 1 + i, out[i-1], testdata[i]);
+  }
+
+  /* copy data to the beginning of second pbuf */
+  res = pbuf_take_at(p, &testdata, sizeof(testdata), p->len);
+  fail_unless(res == ERR_OK);
+
+  out = (u8_t*)p->payload;
+  for (i = 0; i < (int)sizeof(testdata); i++) {
+    fail_unless(out[i] == testdata[i],
+      "Bad data at pos %d, was %02X, expected %02X", p->len+i, out[i], testdata[i]);
+  }
+  pbuf_free(p);
+}
+END_TEST
+
+/* Verify pbuf_put_at()/pbuf_get_at() when using
+ * offsets equal to beginning of new pbuf in chain
+ */
+START_TEST(test_pbuf_get_put_at_edge)
+{
+  u8_t *out;
+  u8_t testdata = 0x01;
+  u8_t getdata;
+  struct pbuf *p = pbuf_alloc(PBUF_RAW, 1024, PBUF_POOL);
+  struct pbuf *q = p->next;
+  LWIP_UNUSED_ARG(_i);
+  /* alloc big enough to get a chain of pbufs */
+  fail_if(p->tot_len == p->len);
+  memset(p->payload, 0, p->len);
+  memset(q->payload, 0, q->len);
+
+  /* put byte at the beginning of second pbuf */
+  pbuf_put_at(p, p->len, testdata);
+
+  out = (u8_t*)q->payload;
+  fail_unless(*out == testdata,
+    "Bad data at pos %d, was %02X, expected %02X", p->len, *out, testdata);
+
+  getdata = pbuf_get_at(p, p->len);
+  fail_unless(*out == getdata,
+    "pbuf_get_at() returned bad data at pos %d, was %02X, expected %02X", p->len, getdata, *out);
+  pbuf_free(p);
+}
+END_TEST
+
+/** Create the suite including all tests for this module */
+Suite *
+pbuf_suite(void)
+{
+  testfunc tests[] = {
+    TESTFUNC(test_pbuf_alloc_zero_pbufs),
+    TESTFUNC(test_pbuf_copy_zero_pbuf),
+    TESTFUNC(test_pbuf_split_64k_on_small_pbufs),
+    TESTFUNC(test_pbuf_queueing_bigger_than_64k),
+    TESTFUNC(test_pbuf_take_at_edge),
+    TESTFUNC(test_pbuf_get_put_at_edge)
+  };
+  return create_suite("PBUF", tests, sizeof(tests)/sizeof(testfunc), pbuf_setup, pbuf_teardown);
+}
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/test/unit/core/test_pbuf.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/test/unit/core/test_pbuf.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/test/unit/core/test_pbuf.h	(revision 457)
@@ -0,0 +1,8 @@
+#ifndef LWIP_HDR_TEST_PBUF_H
+#define LWIP_HDR_TEST_PBUF_H
+
+#include "../lwip_check.h"
+
+Suite *pbuf_suite(void);
+
+#endif
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/test/unit/core/test_timers.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/test/unit/core/test_timers.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/test/unit/core/test_timers.c	(revision 457)
@@ -0,0 +1,233 @@
+#include "test_timers.h"
+
+#include "lwip/def.h"
+#include "lwip/timeouts.h"
+#include "arch/sys_arch.h"
+
+/* Setups/teardown functions */
+
+static struct sys_timeo* old_list_head;
+
+static void
+timers_setup(void)
+{
+  struct sys_timeo** list_head = sys_timeouts_get_next_timeout();
+  old_list_head = *list_head;
+  *list_head = NULL;
+}
+
+static void
+timers_teardown(void)
+{
+  struct sys_timeo** list_head = sys_timeouts_get_next_timeout();
+  *list_head = old_list_head;
+  lwip_sys_now = 0;
+}
+
+static int fired[3];
+static void
+dummy_handler(void* arg)
+{
+  int index = LWIP_PTR_NUMERIC_CAST(int, arg);
+  fired[index] = 1;
+}
+
+#define HANDLER_EXECUTION_TIME 5
+static int cyclic_fired;
+static void
+dummy_cyclic_handler(void)
+{
+   cyclic_fired = 1;
+   lwip_sys_now += HANDLER_EXECUTION_TIME;
+}
+
+struct lwip_cyclic_timer test_cyclic = {10, dummy_cyclic_handler};
+
+static void
+do_test_cyclic_timers(u32_t offset)
+{
+  struct sys_timeo** list_head = sys_timeouts_get_next_timeout();
+
+  /* verify normal timer expiration */
+  lwip_sys_now = offset + 0;
+  sys_timeout(test_cyclic.interval_ms, lwip_cyclic_timer, &test_cyclic);
+
+  cyclic_fired = 0;
+  sys_check_timeouts();
+  fail_unless(cyclic_fired == 0);
+
+  lwip_sys_now = offset + test_cyclic.interval_ms;
+  sys_check_timeouts();
+  fail_unless(cyclic_fired == 1);
+
+  fail_unless((*list_head)->time == (u32_t)(lwip_sys_now + test_cyclic.interval_ms - HANDLER_EXECUTION_TIME));
+  
+  sys_untimeout(lwip_cyclic_timer, &test_cyclic);
+
+
+  /* verify "overload" - next cyclic timer execution is already overdue twice */
+  lwip_sys_now = offset + 0;
+  sys_timeout(test_cyclic.interval_ms, lwip_cyclic_timer, &test_cyclic);
+
+  cyclic_fired = 0;
+  sys_check_timeouts();
+  fail_unless(cyclic_fired == 0);
+
+  lwip_sys_now = offset + 2*test_cyclic.interval_ms;
+  sys_check_timeouts();
+  fail_unless(cyclic_fired == 1);
+
+  fail_unless((*list_head)->time == (u32_t)(lwip_sys_now + test_cyclic.interval_ms));
+}
+
+START_TEST(test_cyclic_timers)
+{
+  LWIP_UNUSED_ARG(_i);
+
+  /* check without u32_t wraparound */
+  do_test_cyclic_timers(0);
+
+  /* check with u32_t wraparound */
+  do_test_cyclic_timers(0xfffffff0);
+}
+END_TEST
+
+/* reproduce bug #52748: the bug in timeouts.c */
+START_TEST(test_bug52748)
+{
+  LWIP_UNUSED_ARG(_i);
+
+  memset(&fired, 0, sizeof(fired));
+
+  lwip_sys_now = 50;
+  sys_timeout(20, dummy_handler, LWIP_PTR_NUMERIC_CAST(void*, 0));
+  sys_timeout( 5, dummy_handler, LWIP_PTR_NUMERIC_CAST(void*, 2));
+
+  lwip_sys_now = 55;
+  sys_check_timeouts();
+  fail_unless(fired[0] == 0);
+  fail_unless(fired[1] == 0);
+  fail_unless(fired[2] == 1);
+
+  lwip_sys_now = 60;
+  sys_timeout(10, dummy_handler, LWIP_PTR_NUMERIC_CAST(void*, 1));
+  sys_check_timeouts();
+  fail_unless(fired[0] == 0);
+  fail_unless(fired[1] == 0);
+  fail_unless(fired[2] == 1);
+
+  lwip_sys_now = 70;
+  sys_check_timeouts();
+  fail_unless(fired[0] == 1);
+  fail_unless(fired[1] == 1);
+  fail_unless(fired[2] == 1);
+}
+END_TEST
+
+static void
+do_test_timers(u32_t offset)
+{
+  struct sys_timeo** list_head = sys_timeouts_get_next_timeout();
+  
+  lwip_sys_now = offset + 0;
+
+  sys_timeout(10, dummy_handler, LWIP_PTR_NUMERIC_CAST(void*, 0));
+  fail_unless(sys_timeouts_sleeptime() == 10);
+  sys_timeout(20, dummy_handler, LWIP_PTR_NUMERIC_CAST(void*, 1));
+  fail_unless(sys_timeouts_sleeptime() == 10);
+  sys_timeout( 5, dummy_handler, LWIP_PTR_NUMERIC_CAST(void*, 2));
+  fail_unless(sys_timeouts_sleeptime() == 5);
+
+  /* linked list correctly sorted? */
+  fail_unless((*list_head)->time             == (u32_t)(lwip_sys_now + 5));
+  fail_unless((*list_head)->next->time       == (u32_t)(lwip_sys_now + 10));
+  fail_unless((*list_head)->next->next->time == (u32_t)(lwip_sys_now + 20));
+  
+  /* check timers expire in correct order */
+  memset(&fired, 0, sizeof(fired));
+
+  lwip_sys_now += 4;
+  sys_check_timeouts();
+  fail_unless(fired[2] == 0);
+
+  lwip_sys_now += 1;
+  sys_check_timeouts();
+  fail_unless(fired[2] == 1);
+
+  lwip_sys_now += 4;
+  sys_check_timeouts();
+  fail_unless(fired[0] == 0);
+
+  lwip_sys_now += 1;
+  sys_check_timeouts();
+  fail_unless(fired[0] == 1);
+
+  lwip_sys_now += 9;
+  sys_check_timeouts();
+  fail_unless(fired[1] == 0);
+
+  lwip_sys_now += 1;
+  sys_check_timeouts();
+  fail_unless(fired[1] == 1);
+
+  sys_untimeout(dummy_handler, LWIP_PTR_NUMERIC_CAST(void*, 0));
+  sys_untimeout(dummy_handler, LWIP_PTR_NUMERIC_CAST(void*, 1));
+  sys_untimeout(dummy_handler, LWIP_PTR_NUMERIC_CAST(void*, 2));
+}
+
+START_TEST(test_timers)
+{
+  LWIP_UNUSED_ARG(_i);
+
+  /* check without u32_t wraparound */
+  do_test_timers(0);
+
+  /* check with u32_t wraparound */
+  do_test_timers(0xfffffff0);
+}
+END_TEST
+
+START_TEST(test_long_timer)
+{
+  LWIP_UNUSED_ARG(_i);
+
+  memset(&fired, 0, sizeof(fired));
+  lwip_sys_now = 0;
+
+  sys_timeout(LWIP_UINT32_MAX / 4, dummy_handler, LWIP_PTR_NUMERIC_CAST(void*, 0));
+  fail_unless(sys_timeouts_sleeptime() == LWIP_UINT32_MAX / 4);
+
+  sys_check_timeouts();
+  fail_unless(fired[0] == 0);
+
+  lwip_sys_now += LWIP_UINT32_MAX / 8;
+
+  sys_check_timeouts();
+  fail_unless(fired[0] == 0);
+
+  lwip_sys_now += LWIP_UINT32_MAX / 8;
+
+  sys_check_timeouts();
+  fail_unless(fired[0] == 0);
+
+  lwip_sys_now += 1;
+
+  sys_check_timeouts();
+  fail_unless(fired[0] == 1);
+
+  sys_untimeout(dummy_handler, LWIP_PTR_NUMERIC_CAST(void*, 0));
+}
+END_TEST
+
+/** Create the suite including all tests for this module */
+Suite *
+timers_suite(void)
+{
+  testfunc tests[] = {
+    TESTFUNC(test_bug52748),
+    TESTFUNC(test_cyclic_timers),
+    TESTFUNC(test_timers),
+    TESTFUNC(test_long_timer),
+  };
+  return create_suite("TIMERS", tests, LWIP_ARRAYSIZE(tests), timers_setup, timers_teardown);
+}
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/test/unit/core/test_timers.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/test/unit/core/test_timers.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/test/unit/core/test_timers.h	(revision 457)
@@ -0,0 +1,8 @@
+#ifndef LWIP_HDR_TEST_TIMERS_H
+#define LWIP_HDR_TEST_TIMERS_H
+
+#include "../lwip_check.h"
+
+Suite *timers_suite(void);
+
+#endif
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/test/unit/dhcp/test_dhcp.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/test/unit/dhcp/test_dhcp.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/test/unit/dhcp/test_dhcp.c	(revision 457)
@@ -0,0 +1,1057 @@
+#include "test_dhcp.h"
+
+#include "lwip/netif.h"
+#include "lwip/dhcp.h"
+#include "lwip/prot/dhcp.h"
+#include "lwip/etharp.h"
+#include "netif/ethernet.h"
+
+struct netif net_test;
+
+static const u8_t broadcast[6] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
+
+static const u8_t magic_cookie[] = { 0x63, 0x82, 0x53, 0x63 };
+
+static u8_t dhcp_offer[] = {
+    0x00, 0x23, 0xc1, 0xde, 0xd0, 0x0d, /* To unit */
+    0x00, 0x0F, 0xEE, 0x30, 0xAB, 0x22, /* From Remote host */
+    0x08, 0x00, /* Protocol: IP */
+    0x45, 0x10, 0x01, 0x48, 0x00, 0x00, 0x00, 0x00, 0x80, 0x11, 0x36, 0xcc, 0xc3, 0xaa, 0xbd, 0xab, 0xc3, 0xaa, 0xbd, 0xc8, /* IP header */
+    0x00, 0x43, 0x00, 0x44, 0x01, 0x34, 0x00, 0x00, /* UDP header */
+
+    0x02, /* Type == Boot reply */
+    0x01, 0x06, /* Hw Ethernet, 6 bytes addrlen */
+    0x00, /* 0 hops */
+    0xAA, 0xAA, 0xAA, 0xAA, /* Transaction id, will be overwritten */
+    0x00, 0x00, /* 0 seconds elapsed */
+    0x00, 0x00, /* Flags (unicast) */
+    0x00, 0x00, 0x00, 0x00, /* Client ip */
+    0xc3, 0xaa, 0xbd, 0xc8, /* Your IP */
+    0xc3, 0xaa, 0xbd, 0xab, /* DHCP server ip */
+    0x00, 0x00, 0x00, 0x00, /* relay agent */
+    0x00, 0x23, 0xc1, 0xde, 0xd0, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* MAC addr + padding */
+
+    /* Empty server name and boot file name */
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00,
+
+    0x63, 0x82, 0x53, 0x63, /* Magic cookie */
+    0x35, 0x01, 0x02, /* Message type: Offer */
+    0x36, 0x04, 0xc3, 0xaa, 0xbd, 0xab, /* Server identifier (IP) */
+    0x33, 0x04, 0x00, 0x00, 0x00, 0x78, /* Lease time 2 minutes */
+    0x03, 0x04, 0xc3, 0xaa, 0xbd, 0xab, /* Router IP */
+    0x01, 0x04, 0xff, 0xff, 0xff, 0x00, /* Subnet mask */
+    0xff, /* End option */
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Padding */
+};
+
+static u8_t dhcp_ack[] = {
+    0x00, 0x23, 0xc1, 0xde, 0xd0, 0x0d, /* To unit */
+    0x00, 0x0f, 0xEE, 0x30, 0xAB, 0x22, /* From remote host */
+    0x08, 0x00, /* Proto IP */
+    0x45, 0x10, 0x01, 0x48, 0x00, 0x00, 0x00, 0x00, 0x80, 0x11, 0x36, 0xcc, 0xc3, 0xaa, 0xbd, 0xab, 0xc3, 0xaa, 0xbd, 0xc8, /* IP header */
+    0x00, 0x43, 0x00, 0x44, 0x01, 0x34, 0x00, 0x00, /* UDP header */
+    0x02, /* Bootp reply */
+    0x01, 0x06, /* Hw type Eth, len 6 */
+    0x00, /* 0 hops */
+    0xAA, 0xAA, 0xAA, 0xAA,
+    0x00, 0x00, /* 0 seconds elapsed */
+    0x00, 0x00, /* Flags (unicast) */
+    0x00, 0x00, 0x00, 0x00, /* Client IP */
+    0xc3, 0xaa, 0xbd, 0xc8, /* Your IP */
+    0xc3, 0xaa, 0xbd, 0xab, /* DHCP server IP */
+    0x00, 0x00, 0x00, 0x00, /* Relay agent */
+    0x00, 0x23, 0xc1, 0xde, 0xd0, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Macaddr + padding */
+
+    /* Empty server name and boot file name */
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00,
+
+    0x63, 0x82, 0x53, 0x63, /* Magic cookie */
+    0x35, 0x01, 0x05, /* Dhcp message type ack */
+    0x36, 0x04, 0xc3, 0xaa, 0xbd, 0xab, /* DHCP server identifier */
+    0x33, 0x04, 0x00, 0x00, 0x00, 0x78, /* Lease time 2 minutes */
+    0x03, 0x04, 0xc3, 0xaa, 0xbd, 0xab, /* Router IP */
+    0x01, 0x04, 0xff, 0xff, 0xff, 0x00, /* Netmask */
+    0xff, /* End marker */
+
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Padding */
+};
+
+static const u8_t arpreply[] = {
+    0x00, 0x23, 0xC1, 0xDE, 0xD0, 0x0D, /* dst mac */
+    0x00, 0x32, 0x44, 0x20, 0x01, 0x02, /* src mac */
+    0x08, 0x06, /* proto arp */
+    0x00, 0x01, /* hw eth */
+    0x08, 0x00, /* proto ip */
+    0x06, /* hw addr len 6 */
+    0x04, /* proto addr len 4 */
+    0x00, 0x02, /* arp reply */
+    0x00, 0x32, 0x44, 0x20, 0x01, 0x02, /* sender mac */
+    0xc3, 0xaa, 0xbd, 0xc8, /* sender ip */
+    0x00, 0x23, 0xC1, 0xDE, 0xD0, 0x0D, /* target mac */
+    0x00, 0x00, 0x00, 0x00, /* target ip */
+};
+
+static int txpacket;
+static enum tcase {
+  TEST_LWIP_DHCP,
+  TEST_LWIP_DHCP_NAK,
+  TEST_LWIP_DHCP_RELAY,
+  TEST_LWIP_DHCP_NAK_NO_ENDMARKER,
+  TEST_LWIP_DHCP_INVALID_OVERLOAD,
+  TEST_NONE
+} tcase;
+
+static int debug = 0;
+static void setdebug(int a) {debug = a;}
+
+static int tick = 0;
+static void tick_lwip(void)
+{
+  tick++;
+  if (tick % 5 == 0) {
+    dhcp_fine_tmr();
+  }
+  if (tick % 600 == 0) {
+    dhcp_coarse_tmr();
+  }
+}
+
+static void send_pkt(struct netif *netif, const u8_t *data, size_t len)
+{
+  struct pbuf *p, *q;
+  LWIP_ASSERT("pkt too big", len <= 0xFFFF);
+  p = pbuf_alloc(PBUF_RAW, (u16_t)len, PBUF_POOL);
+
+  if (debug) {
+    /* Dump data */
+    u32_t i;
+    printf("RX data (len %d)", p->tot_len);
+    for (i = 0; i < len; i++) {
+      printf(" %02X", data[i]);
+    }
+    printf("\n");
+  }
+
+  fail_unless(p != NULL);
+  for(q = p; q != NULL; q = q->next) {
+    memcpy(q->payload, data, q->len);
+    data += q->len;
+  }
+  netif->input(p, netif);
+}
+
+static err_t lwip_tx_func(struct netif *netif, struct pbuf *p);
+
+static err_t testif_init(struct netif *netif)
+{
+  netif->name[0] = 'c';
+  netif->name[1] = 'h';
+  netif->output = etharp_output;
+  netif->linkoutput = lwip_tx_func;
+  netif->mtu = 1500;
+  netif->hwaddr_len = 6;
+  netif->flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP;
+
+  netif->hwaddr[0] = 0x00;
+  netif->hwaddr[1] = 0x23;
+  netif->hwaddr[2] = 0xC1;
+  netif->hwaddr[3] = 0xDE;
+  netif->hwaddr[4] = 0xD0;
+  netif->hwaddr[5] = 0x0D;
+
+  return ERR_OK;
+}
+
+static void dhcp_setup(void)
+{
+  txpacket = 0;
+  lwip_check_ensure_no_alloc(SKIP_POOL(MEMP_SYS_TIMEOUT));
+}
+
+static void dhcp_teardown(void)
+{
+  lwip_check_ensure_no_alloc(SKIP_POOL(MEMP_SYS_TIMEOUT));
+}
+
+static void check_pkt(struct pbuf *p, u32_t pos, const u8_t *mem, u32_t len)
+{
+  u8_t *data;
+
+  fail_if((pos + len) > p->tot_len);
+  while (pos > p->len && p->next) {
+    pos -= p->len;
+    p = p->next;
+  }
+  fail_if(p == NULL);
+  fail_unless(pos + len <= p->len); /* All data we seek within same pbuf */
+
+  data = (u8_t*)p->payload;
+  fail_if(memcmp(&data[pos], mem, len), "data at pos %d, len %d in packet %d did not match", pos, len, txpacket);
+}
+
+static void check_pkt_fuzzy(struct pbuf *p, u32_t startpos, const u8_t *mem, u32_t len)
+{
+  int found;
+  u32_t i;
+  u8_t *data;
+
+  fail_if((startpos + len) > p->tot_len);
+  while (startpos > p->len && p->next) {
+    startpos -= p->len;
+    p = p->next;
+  }
+  fail_if(p == NULL);
+  fail_unless(startpos + len <= p->len); /* All data we seek within same pbuf */
+
+  found = 0;
+  data = (u8_t*)p->payload;
+  for (i = startpos; i <= (p->len - len); i++) {
+    if (memcmp(&data[i], mem, len) == 0) {
+      found = 1;
+      break;
+    }
+  }
+  fail_unless(found);
+}
+
+static err_t lwip_tx_func(struct netif *netif, struct pbuf *p)
+{
+  fail_unless(netif == &net_test);
+  txpacket++;
+
+  if (debug) {
+    struct pbuf *pp = p;
+    /* Dump data */
+    printf("TX data (pkt %d, len %d, tick %d)", txpacket, p->tot_len, tick);
+    do {
+      int i;
+      for (i = 0; i < pp->len; i++) {
+        printf(" %02X", ((u8_t *) pp->payload)[i]);
+      }
+      if (pp->next) {
+        pp = pp->next;
+      }
+    } while (pp->next);
+    printf("\n");
+  }
+
+  switch (tcase) {
+  case TEST_LWIP_DHCP:
+    switch (txpacket) {
+    case 1:
+    case 2:
+      {
+        const u8_t ipproto[] = { 0x08, 0x00 };
+        const u8_t bootp_start[] = { 0x01, 0x01, 0x06, 0x00}; /* bootp request, eth, hwaddr len 6, 0 hops */
+        const u8_t ipaddrs[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
+
+        check_pkt(p, 0, broadcast, 6); /* eth level dest: broadcast */
+        check_pkt(p, 6, netif->hwaddr, 6); /* eth level src: unit mac */
+
+        check_pkt(p, 12, ipproto, sizeof(ipproto)); /* eth level proto: ip */
+
+        check_pkt(p, 42, bootp_start, sizeof(bootp_start));
+
+        check_pkt(p, 53, ipaddrs, sizeof(ipaddrs));
+
+        check_pkt(p, 70, netif->hwaddr, 6); /* mac addr inside bootp */
+
+        check_pkt(p, 278, magic_cookie, sizeof(magic_cookie));
+
+        /* Check dchp message type, can be at different positions */
+        if (txpacket == 1) {
+          u8_t dhcp_discover_opt[] = { 0x35, 0x01, 0x01 };
+          check_pkt_fuzzy(p, 282, dhcp_discover_opt, sizeof(dhcp_discover_opt));
+        } else if (txpacket == 2) {
+          u8_t dhcp_request_opt[] = { 0x35, 0x01, 0x03 };
+          u8_t requested_ipaddr[] = { 0x32, 0x04, 0xc3, 0xaa, 0xbd, 0xc8 }; /* Ask for offered IP */
+
+          check_pkt_fuzzy(p, 282, dhcp_request_opt, sizeof(dhcp_request_opt));
+          check_pkt_fuzzy(p, 282, requested_ipaddr, sizeof(requested_ipaddr));
+        }
+        break;
+      }
+    case 3:
+    case 4:
+    case 5:
+      {
+        const u8_t arpproto[] = { 0x08, 0x06 };
+
+        check_pkt(p, 0, broadcast, 6); /* eth level dest: broadcast */
+        check_pkt(p, 6, netif->hwaddr, 6); /* eth level src: unit mac */
+
+        check_pkt(p, 12, arpproto, sizeof(arpproto)); /* eth level proto: ip */
+        break;
+      }
+      default:
+        fail();
+        break;
+    }
+    break;
+
+  case TEST_LWIP_DHCP_NAK:
+    {
+      const u8_t ipproto[] = { 0x08, 0x00 };
+      const u8_t bootp_start[] = { 0x01, 0x01, 0x06, 0x00}; /* bootp request, eth, hwaddr len 6, 0 hops */
+      const u8_t ipaddrs[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
+      const u8_t dhcp_nak_opt[] = { 0x35, 0x01, 0x04 };
+      const u8_t requested_ipaddr[] = { 0x32, 0x04, 0xc3, 0xaa, 0xbd, 0xc8 }; /* offered IP */
+
+      fail_unless(txpacket == 4);
+      check_pkt(p, 0, broadcast, 6); /* eth level dest: broadcast */
+      check_pkt(p, 6, netif->hwaddr, 6); /* eth level src: unit mac */
+
+      check_pkt(p, 12, ipproto, sizeof(ipproto)); /* eth level proto: ip */
+
+      check_pkt(p, 42, bootp_start, sizeof(bootp_start));
+
+      check_pkt(p, 53, ipaddrs, sizeof(ipaddrs));
+
+      check_pkt(p, 70, netif->hwaddr, 6); /* mac addr inside bootp */
+
+      check_pkt(p, 278, magic_cookie, sizeof(magic_cookie));
+
+      check_pkt_fuzzy(p, 282, dhcp_nak_opt, sizeof(dhcp_nak_opt)); /* NAK the ack */
+
+      check_pkt_fuzzy(p, 282, requested_ipaddr, sizeof(requested_ipaddr));
+      break;
+    }
+
+  case TEST_LWIP_DHCP_RELAY:
+    switch (txpacket) {
+    case 1:
+    case 2:
+      {
+        const u8_t ipproto[] = { 0x08, 0x00 };
+        const u8_t bootp_start[] = { 0x01, 0x01, 0x06, 0x00}; /* bootp request, eth, hwaddr len 6, 0 hops */
+        const u8_t ipaddrs[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
+
+        check_pkt(p, 0, broadcast, 6); /* eth level dest: broadcast */
+        check_pkt(p, 6, netif->hwaddr, 6); /* eth level src: unit mac */
+
+        check_pkt(p, 12, ipproto, sizeof(ipproto)); /* eth level proto: ip */
+
+        check_pkt(p, 42, bootp_start, sizeof(bootp_start));
+
+        check_pkt(p, 53, ipaddrs, sizeof(ipaddrs));
+
+        check_pkt(p, 70, netif->hwaddr, 6); /* mac addr inside bootp */
+
+        check_pkt(p, 278, magic_cookie, sizeof(magic_cookie));
+
+        /* Check dchp message type, can be at different positions */
+        if (txpacket == 1) {
+          u8_t dhcp_discover_opt[] = { 0x35, 0x01, 0x01 };
+          check_pkt_fuzzy(p, 282, dhcp_discover_opt, sizeof(dhcp_discover_opt));
+        } else if (txpacket == 2) {
+          u8_t dhcp_request_opt[] = { 0x35, 0x01, 0x03 };
+          u8_t requested_ipaddr[] = { 0x32, 0x04, 0x4f, 0x8a, 0x33, 0x05 }; /* Ask for offered IP */
+
+          check_pkt_fuzzy(p, 282, dhcp_request_opt, sizeof(dhcp_request_opt));
+          check_pkt_fuzzy(p, 282, requested_ipaddr, sizeof(requested_ipaddr));
+        }
+        break;
+      }
+    case 3:
+    case 4:
+    case 5:
+    case 6:
+      {
+        const u8_t arpproto[] = { 0x08, 0x06 };
+
+        check_pkt(p, 0, broadcast, 6); /* eth level dest: broadcast */
+        check_pkt(p, 6, netif->hwaddr, 6); /* eth level src: unit mac */
+
+        check_pkt(p, 12, arpproto, sizeof(arpproto)); /* eth level proto: ip */
+        break;
+      }
+    case 7:
+      {
+        const u8_t fake_arp[6] = { 0x12, 0x34, 0x56, 0x78, 0x9a, 0xab };
+        const u8_t ipproto[] = { 0x08, 0x00 };
+        const u8_t bootp_start[] = { 0x01, 0x01, 0x06, 0x00}; /* bootp request, eth, hwaddr len 6, 0 hops */
+        const u8_t ipaddrs[] = { 0x00, 0x4f, 0x8a, 0x33, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
+        const u8_t dhcp_request_opt[] = { 0x35, 0x01, 0x03 };
+
+        check_pkt(p, 0, fake_arp, 6); /* eth level dest: broadcast */
+        check_pkt(p, 6, netif->hwaddr, 6); /* eth level src: unit mac */
+
+        check_pkt(p, 12, ipproto, sizeof(ipproto)); /* eth level proto: ip */
+
+        check_pkt(p, 42, bootp_start, sizeof(bootp_start));
+
+        check_pkt(p, 53, ipaddrs, sizeof(ipaddrs));
+
+        check_pkt(p, 70, netif->hwaddr, 6); /* mac addr inside bootp */
+
+        check_pkt(p, 278, magic_cookie, sizeof(magic_cookie));
+
+        /* Check dchp message type, can be at different positions */
+        check_pkt_fuzzy(p, 282, dhcp_request_opt, sizeof(dhcp_request_opt));
+        break;
+      }
+    default:
+      fail();
+      break;
+    }
+    break;
+
+  default:
+    break;
+  }
+
+  return ERR_OK;
+}
+
+/*
+ * Test basic happy flow DHCP session.
+ * Validate that xid is checked.
+ */
+START_TEST(test_dhcp)
+{
+  ip4_addr_t addr;
+  ip4_addr_t netmask;
+  ip4_addr_t gw;
+  int i;
+  u32_t xid;
+  LWIP_UNUSED_ARG(_i);
+
+  tcase = TEST_LWIP_DHCP;
+  setdebug(0);
+
+  IP4_ADDR(&addr, 0, 0, 0, 0);
+  IP4_ADDR(&netmask, 0, 0, 0, 0);
+  IP4_ADDR(&gw, 0, 0, 0, 0);
+
+  netif_add(&net_test, &addr, &netmask, &gw, &net_test, testif_init, ethernet_input);
+  netif_set_link_up(&net_test);
+  netif_set_up(&net_test);
+
+  dhcp_start(&net_test);
+
+  fail_unless(txpacket == 1); /* DHCP discover sent */
+  xid = netif_dhcp_data(&net_test)->xid; /* Write bad xid, not using htonl! */
+  memcpy(&dhcp_offer[46], &xid, 4);
+  send_pkt(&net_test, dhcp_offer, sizeof(dhcp_offer));
+
+  /* IP addresses should be zero */
+  fail_if(memcmp(&addr, &net_test.ip_addr, sizeof(ip4_addr_t)));
+  fail_if(memcmp(&netmask, &net_test.netmask, sizeof(ip4_addr_t)));
+  fail_if(memcmp(&gw, &net_test.gw, sizeof(ip4_addr_t)));
+
+  fail_unless(txpacket == 1, "TX %d packets, expected 1", txpacket); /* Nothing more sent */
+  xid = htonl(netif_dhcp_data(&net_test)->xid);
+  memcpy(&dhcp_offer[46], &xid, 4); /* insert correct transaction id */
+  send_pkt(&net_test, dhcp_offer, sizeof(dhcp_offer));
+
+  fail_unless(txpacket == 2, "TX %d packets, expected 2", txpacket); /* DHCP request sent */
+  xid = netif_dhcp_data(&net_test)->xid; /* Write bad xid, not using htonl! */
+  memcpy(&dhcp_ack[46], &xid, 4);
+  send_pkt(&net_test, dhcp_ack, sizeof(dhcp_ack));
+
+  fail_unless(txpacket == 2, "TX %d packets, still expected 2", txpacket); /* No more sent */
+  xid = htonl(netif_dhcp_data(&net_test)->xid); /* xid updated */
+  memcpy(&dhcp_ack[46], &xid, 4); /* insert transaction id */
+  send_pkt(&net_test, dhcp_ack, sizeof(dhcp_ack));
+
+  for (i = 0; i < 20; i++) {
+    tick_lwip();
+  }
+  fail_unless(txpacket == 5, "TX %d packets, expected 5", txpacket); /* ARP requests sent */
+
+  /* Interface up */
+  fail_unless(netif_is_up(&net_test));
+
+  /* Now it should have taken the IP */
+  IP4_ADDR(&addr, 195, 170, 189, 200);
+  IP4_ADDR(&netmask, 255, 255, 255, 0);
+  IP4_ADDR(&gw, 195, 170, 189, 171);
+  fail_if(memcmp(&addr, &net_test.ip_addr, sizeof(ip4_addr_t)));
+  fail_if(memcmp(&netmask, &net_test.netmask, sizeof(ip4_addr_t)));
+  fail_if(memcmp(&gw, &net_test.gw, sizeof(ip4_addr_t)));
+
+  tcase = TEST_NONE;
+  dhcp_stop(&net_test);
+  dhcp_cleanup(&net_test);
+  netif_remove(&net_test);
+}
+END_TEST
+
+/*
+ * Test that IP address is not taken and NAK is sent if someone
+ * replies to ARP requests for the offered address.
+ */
+START_TEST(test_dhcp_nak)
+{
+  ip4_addr_t addr;
+  ip4_addr_t netmask;
+  ip4_addr_t gw;
+  u32_t xid;
+  LWIP_UNUSED_ARG(_i);
+
+  tcase = TEST_LWIP_DHCP;
+  setdebug(0);
+
+  IP4_ADDR(&addr, 0, 0, 0, 0);
+  IP4_ADDR(&netmask, 0, 0, 0, 0);
+  IP4_ADDR(&gw, 0, 0, 0, 0);
+
+  netif_add(&net_test, &addr, &netmask, &gw, &net_test, testif_init, ethernet_input);
+  netif_set_link_up(&net_test);
+  netif_set_up(&net_test);
+
+  dhcp_start(&net_test);
+
+  fail_unless(txpacket == 1); /* DHCP discover sent */
+  xid = netif_dhcp_data(&net_test)->xid; /* Write bad xid, not using htonl! */
+  memcpy(&dhcp_offer[46], &xid, 4);
+  send_pkt(&net_test, dhcp_offer, sizeof(dhcp_offer));
+
+  /* IP addresses should be zero */
+  fail_if(memcmp(&addr, &net_test.ip_addr, sizeof(ip4_addr_t)));
+  fail_if(memcmp(&netmask, &net_test.netmask, sizeof(ip4_addr_t)));
+  fail_if(memcmp(&gw, &net_test.gw, sizeof(ip4_addr_t)));
+
+  fail_unless(txpacket == 1); /* Nothing more sent */
+  xid = htonl(netif_dhcp_data(&net_test)->xid);
+  memcpy(&dhcp_offer[46], &xid, 4); /* insert correct transaction id */
+  send_pkt(&net_test, dhcp_offer, sizeof(dhcp_offer));
+
+  fail_unless(txpacket == 2); /* DHCP request sent */
+  xid = netif_dhcp_data(&net_test)->xid; /* Write bad xid, not using htonl! */
+  memcpy(&dhcp_ack[46], &xid, 4);
+  send_pkt(&net_test, dhcp_ack, sizeof(dhcp_ack));
+
+  fail_unless(txpacket == 2); /* No more sent */
+  xid = htonl(netif_dhcp_data(&net_test)->xid); /* xid updated */
+  memcpy(&dhcp_ack[46], &xid, 4); /* insert transaction id */
+  send_pkt(&net_test, dhcp_ack, sizeof(dhcp_ack));
+
+  fail_unless(txpacket == 3); /* ARP request sent */
+
+  tcase = TEST_LWIP_DHCP_NAK; /* Switch testcase */
+
+  /* Send arp reply, mark offered IP as taken */
+  send_pkt(&net_test, arpreply, sizeof(arpreply));
+
+  fail_unless(txpacket == 4); /* DHCP nak sent */
+
+  tcase = TEST_NONE;
+  dhcp_stop(&net_test);
+  dhcp_cleanup(&net_test);
+  netif_remove(&net_test);
+}
+END_TEST
+
+/*
+ * Test case based on captured data where
+ * replies are sent from a different IP than the
+ * one the client unicasted to.
+ */
+START_TEST(test_dhcp_relayed)
+{
+  u8_t relay_offer[] = {
+  0x00, 0x23, 0xc1, 0xde, 0xd0, 0x0d,
+  0x00, 0x22, 0x93, 0x5a, 0xf7, 0x60,
+  0x08, 0x00, 0x45, 0x00,
+  0x01, 0x38, 0xfd, 0x53, 0x00, 0x00, 0x40, 0x11,
+  0x78, 0x46, 0x4f, 0x8a, 0x32, 0x02, 0x4f, 0x8a,
+  0x33, 0x05, 0x00, 0x43, 0x00, 0x44, 0x01, 0x24,
+  0x00, 0x00, 0x02, 0x01, 0x06, 0x00, 0x51, 0x35,
+  0xb6, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x4f, 0x8a, 0x33, 0x05, 0x00, 0x00,
+  0x00, 0x00, 0x0a, 0xb5, 0x04, 0x01, 0x00, 0x23,
+  0xc1, 0xde, 0xd0, 0x0d, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x63, 0x82,
+  0x53, 0x63, 0x01, 0x04, 0xff, 0xff, 0xfe, 0x00,
+  0x03, 0x04, 0x4f, 0x8a, 0x32, 0x01, 0x06, 0x08,
+  0x4f, 0x8a, 0x00, 0xb4, 0x55, 0x08, 0x1f, 0xd1,
+  0x1c, 0x04, 0x4f, 0x8a, 0x33, 0xff, 0x33, 0x04,
+  0x00, 0x00, 0x54, 0x49, 0x35, 0x01, 0x02, 0x36,
+  0x04, 0x0a, 0xb5, 0x04, 0x01, 0xff
+  };
+
+  u8_t relay_ack1[] = {
+  0x00, 0x23, 0xc1, 0xde, 0xd0, 0x0d, 0x00, 0x22,
+  0x93, 0x5a, 0xf7, 0x60, 0x08, 0x00, 0x45, 0x00,
+  0x01, 0x38, 0xfd, 0x55, 0x00, 0x00, 0x40, 0x11,
+  0x78, 0x44, 0x4f, 0x8a, 0x32, 0x02, 0x4f, 0x8a,
+  0x33, 0x05, 0x00, 0x43, 0x00, 0x44, 0x01, 0x24,
+  0x00, 0x00, 0x02, 0x01, 0x06, 0x00, 0x51, 0x35,
+  0xb6, 0xa1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x4f, 0x8a, 0x33, 0x05, 0x00, 0x00,
+  0x00, 0x00, 0x0a, 0xb5, 0x04, 0x01, 0x00, 0x23,
+  0xc1, 0xde, 0xd0, 0x0d, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x63, 0x82,
+  0x53, 0x63, 0x01, 0x04, 0xff, 0xff, 0xfe, 0x00,
+  0x03, 0x04, 0x4f, 0x8a, 0x32, 0x01, 0x06, 0x08,
+  0x4f, 0x8a, 0x00, 0xb4, 0x55, 0x08, 0x1f, 0xd1,
+  0x1c, 0x04, 0x4f, 0x8a, 0x33, 0xff, 0x33, 0x04,
+  0x00, 0x00, 0x54, 0x49, 0x35, 0x01, 0x05, 0x36,
+  0x04, 0x0a, 0xb5, 0x04, 0x01, 0xff
+  };
+
+  u8_t relay_ack2[] = {
+  0x00, 0x23, 0xc1, 0xde, 0xd0, 0x0d,
+  0x00, 0x22, 0x93, 0x5a, 0xf7, 0x60,
+  0x08, 0x00, 0x45, 0x00,
+  0x01, 0x38, 0xfa, 0x18, 0x00, 0x00, 0x40, 0x11,
+  0x7b, 0x81, 0x4f, 0x8a, 0x32, 0x02, 0x4f, 0x8a,
+  0x33, 0x05, 0x00, 0x43, 0x00, 0x44, 0x01, 0x24,
+  0x00, 0x00, 0x02, 0x01, 0x06, 0x00, 0x49, 0x8b,
+  0x6e, 0xab, 0x00, 0x00, 0x00, 0x00, 0x4f, 0x8a,
+  0x33, 0x05, 0x4f, 0x8a, 0x33, 0x05, 0x00, 0x00,
+  0x00, 0x00, 0x0a, 0xb5, 0x04, 0x01, 0x00, 0x23,
+  0xc1, 0xde, 0xd0, 0x0d, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x63, 0x82,
+  0x53, 0x63, 0x01, 0x04, 0xff, 0xff, 0xfe, 0x00,
+  0x03, 0x04, 0x4f, 0x8a, 0x32, 0x01, 0x06, 0x08,
+  0x4f, 0x8a, 0x00, 0xb4, 0x55, 0x08, 0x1f, 0xd1,
+  0x1c, 0x04, 0x4f, 0x8a, 0x33, 0xff, 0x33, 0x04,
+  0x00, 0x00, 0x54, 0x60, 0x35, 0x01, 0x05, 0x36,
+  0x04, 0x0a, 0xb5, 0x04, 0x01, 0xff };
+
+  const u8_t arp_resp[] = {
+  0x00, 0x23, 0xc1, 0xde, 0xd0, 0x0d, /* DEST */
+  0x00, 0x22, 0x93, 0x5a, 0xf7, 0x60, /* SRC */
+  0x08, 0x06, /* Type: ARP */
+  0x00, 0x01, /* HW: Ethernet */
+  0x08, 0x00, /* PROTO: IP */
+  0x06, /* HW size */
+  0x04, /* PROTO size */
+  0x00, 0x02, /* OPCODE: Reply */
+
+  0x12, 0x34, 0x56, 0x78, 0x9a, 0xab, /* Target MAC */
+  0x4f, 0x8a, 0x32, 0x01, /* Target IP */
+
+  0x00, 0x23, 0xc1, 0x00, 0x06, 0x50, /* src mac */
+  0x4f, 0x8a, 0x33, 0x05, /* src ip */
+
+  /* Padding follows.. */
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00 };
+
+  ip4_addr_t addr;
+  ip4_addr_t netmask;
+  ip4_addr_t gw;
+  int i;
+  u32_t xid;
+  LWIP_UNUSED_ARG(_i);
+
+  tcase = TEST_LWIP_DHCP_RELAY;
+  setdebug(0);
+
+  IP4_ADDR(&addr, 0, 0, 0, 0);
+  IP4_ADDR(&netmask, 0, 0, 0, 0);
+  IP4_ADDR(&gw, 0, 0, 0, 0);
+
+  netif_add(&net_test, &addr, &netmask, &gw, &net_test, testif_init, ethernet_input);
+  netif_set_link_up(&net_test);
+  netif_set_up(&net_test);
+
+  dhcp_start(&net_test);
+
+  fail_unless(txpacket == 1); /* DHCP discover sent */
+
+  /* IP addresses should be zero */
+  fail_if(memcmp(&addr, &net_test.ip_addr, sizeof(ip4_addr_t)));
+  fail_if(memcmp(&netmask, &net_test.netmask, sizeof(ip4_addr_t)));
+  fail_if(memcmp(&gw, &net_test.gw, sizeof(ip4_addr_t)));
+
+  fail_unless(txpacket == 1); /* Nothing more sent */
+  xid = htonl(netif_dhcp_data(&net_test)->xid);
+  memcpy(&relay_offer[46], &xid, 4); /* insert correct transaction id */
+  send_pkt(&net_test, relay_offer, sizeof(relay_offer));
+
+  /* request sent? */
+  fail_unless(txpacket == 2, "txpkt = %d, should be 2", txpacket);
+  xid = htonl(netif_dhcp_data(&net_test)->xid); /* xid updated */
+  memcpy(&relay_ack1[46], &xid, 4); /* insert transaction id */
+  send_pkt(&net_test, relay_ack1, sizeof(relay_ack1));
+
+  for (i = 0; i < 25; i++) {
+    tick_lwip();
+  }
+  fail_unless(txpacket == 5, "txpkt should be 5, is %d", txpacket); /* ARP requests sent */
+
+  /* Interface up */
+  fail_unless(netif_is_up(&net_test));
+
+  /* Now it should have taken the IP */
+  IP4_ADDR(&addr, 79, 138, 51, 5);
+  IP4_ADDR(&netmask, 255, 255, 254, 0);
+  IP4_ADDR(&gw, 79, 138, 50, 1);
+  fail_if(memcmp(&addr, &net_test.ip_addr, sizeof(ip4_addr_t)));
+  fail_if(memcmp(&netmask, &net_test.netmask, sizeof(ip4_addr_t)));
+  fail_if(memcmp(&gw, &net_test.gw, sizeof(ip4_addr_t)));
+
+  fail_unless(txpacket == 5, "txpacket = %d", txpacket);
+
+  for (i = 0; i < 108000 - 25; i++) {
+    tick_lwip();
+  }
+
+  fail_unless(netif_is_up(&net_test));
+  fail_unless(txpacket == 6, "txpacket = %d", txpacket);
+
+  /* We need to send arp response here.. */
+
+  send_pkt(&net_test, arp_resp, sizeof(arp_resp));
+
+  fail_unless(txpacket == 7, "txpacket = %d", txpacket);
+  fail_unless(netif_is_up(&net_test));
+
+  xid = htonl(netif_dhcp_data(&net_test)->xid); /* xid updated */
+  memcpy(&relay_ack2[46], &xid, 4); /* insert transaction id */
+  send_pkt(&net_test, relay_ack2, sizeof(relay_ack2));
+
+  for (i = 0; i < 100000; i++) {
+    tick_lwip();
+  }
+
+  fail_unless(txpacket == 7, "txpacket = %d", txpacket);
+
+  tcase = TEST_NONE;
+  dhcp_stop(&net_test);
+  dhcp_cleanup(&net_test);
+  netif_remove(&net_test);
+
+}
+END_TEST
+
+START_TEST(test_dhcp_nak_no_endmarker)
+{
+  ip4_addr_t addr;
+  ip4_addr_t netmask;
+  ip4_addr_t gw;
+
+  u8_t dhcp_nack_no_endmarker[] = {
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x54, 0x75,
+    0xd0, 0x26, 0xd0, 0x0d, 0x08, 0x00, 0x45, 0x00,
+    0x01, 0x15, 0x38, 0x86, 0x00, 0x00, 0xff, 0x11,
+    0xc0, 0xa8, 0xc0, 0xa8, 0x01, 0x01, 0xff, 0xff,
+    0xff, 0xff, 0x00, 0x43, 0x00, 0x44, 0x01, 0x01,
+    0x00, 0x00, 0x02, 0x01, 0x06, 0x00, 0x7a, 0xcb,
+    0xba, 0xf2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x23,
+    0xc1, 0xde, 0xd0, 0x0d, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x63, 0x82,
+    0x53, 0x63, 0x35, 0x01, 0x06, 0x36, 0x04, 0xc0,
+    0xa8, 0x01, 0x01, 0x31, 0xef, 0xad, 0x72, 0x31,
+    0x43, 0x4e, 0x44, 0x30, 0x32, 0x35, 0x30, 0x43,
+    0x52, 0x47, 0x44, 0x38, 0x35, 0x36, 0x3c, 0x08,
+    0x4d, 0x53, 0x46, 0x54, 0x20, 0x35, 0x2e, 0x30,
+    0x37, 0x0d, 0x01, 0x0f, 0x03, 0x06, 0x2c, 0x2e,
+    0x2f, 0x1f, 0x21, 0x79, 0xf9, 0x2b, 0xfc, 0xff,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe2, 0x71,
+    0xf3, 0x5b, 0xe2, 0x71, 0x2e, 0x01, 0x08, 0x03,
+    0x04, 0xc0, 0xa8, 0x01, 0x01, 0xff, 0xeb, 0x1e,
+    0x44, 0xec, 0xeb, 0x1e, 0x30, 0x37, 0x0c, 0x01,
+    0x0f, 0x03, 0x06, 0x2c, 0x2e, 0x2f, 0x1f, 0x21,
+    0x79, 0xf9, 0x2b, 0xff, 0x25, 0xc0, 0x09, 0xd6,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+  };
+  u32_t xid;
+  struct dhcp* dhcp;
+  u8_t tries;
+  u16_t request_timeout;
+  LWIP_UNUSED_ARG(_i);
+
+  tcase = TEST_LWIP_DHCP_NAK_NO_ENDMARKER;
+  setdebug(0);
+
+  IP4_ADDR(&addr, 0, 0, 0, 0);
+  IP4_ADDR(&netmask, 0, 0, 0, 0);
+  IP4_ADDR(&gw, 0, 0, 0, 0);
+
+  netif_add(&net_test, &addr, &netmask, &gw, &net_test, testif_init, ethernet_input);
+  netif_set_link_up(&net_test);
+  netif_set_up(&net_test);
+
+  dhcp_start(&net_test);
+  dhcp = netif_dhcp_data(&net_test);
+
+  fail_unless(txpacket == 1); /* DHCP discover sent */
+  xid = dhcp->xid; /* Write bad xid, not using htonl! */
+  memcpy(&dhcp_offer[46], &xid, 4);
+  send_pkt(&net_test, dhcp_offer, sizeof(dhcp_offer));
+
+  /* IP addresses should be zero */
+  fail_if(memcmp(&addr, &net_test.ip_addr, sizeof(ip4_addr_t)));
+  fail_if(memcmp(&netmask, &net_test.netmask, sizeof(ip4_addr_t)));
+  fail_if(memcmp(&gw, &net_test.gw, sizeof(ip4_addr_t)));
+
+  fail_unless(txpacket == 1); /* Nothing more sent */
+  xid = htonl(dhcp->xid);
+  memcpy(&dhcp_offer[46], &xid, 4); /* insert correct transaction id */
+  send_pkt(&net_test, dhcp_offer, sizeof(dhcp_offer));
+
+  fail_unless(dhcp->state == DHCP_STATE_REQUESTING);
+
+  fail_unless(txpacket == 2); /* No more sent */
+  xid = htonl(dhcp->xid); /* xid updated */
+  memcpy(&dhcp_nack_no_endmarker[46], &xid, 4); /* insert transaction id */
+  tries = dhcp->tries;
+  request_timeout = dhcp->request_timeout;
+  send_pkt(&net_test, dhcp_nack_no_endmarker, sizeof(dhcp_nack_no_endmarker));
+
+  /* NAK should be ignored */
+  fail_unless(dhcp->state == DHCP_STATE_REQUESTING);
+  fail_unless(txpacket == 2); /* No more sent */
+  fail_unless(xid == htonl(dhcp->xid));
+  fail_unless(tries == dhcp->tries);
+  fail_unless(request_timeout == dhcp->request_timeout);
+
+  tcase = TEST_NONE;
+  dhcp_stop(&net_test);
+  dhcp_cleanup(&net_test);
+  netif_remove(&net_test);
+}
+END_TEST
+
+START_TEST(test_dhcp_invalid_overload)
+{
+  u8_t dhcp_offer_invalid_overload[] = {
+      0x00, 0x23, 0xc1, 0xde, 0xd0, 0x0d, /* To unit */
+      0x00, 0x0F, 0xEE, 0x30, 0xAB, 0x22, /* From Remote host */
+      0x08, 0x00, /* Protocol: IP */
+      0x45, 0x10, 0x01, 0x48, 0x00, 0x00, 0x00, 0x00, 0x80, 0x11, 0x36, 0xcc, 0xc3, 0xaa, 0xbd, 0xab, 0xc3, 0xaa, 0xbd, 0xc8, /* IP header */
+      0x00, 0x43, 0x00, 0x44, 0x01, 0x34, 0x00, 0x00, /* UDP header */
+
+      0x02, /* Type == Boot reply */
+      0x01, 0x06, /* Hw Ethernet, 6 bytes addrlen */
+      0x00, /* 0 hops */
+      0xAA, 0xAA, 0xAA, 0xAA, /* Transaction id, will be overwritten */
+      0x00, 0x00, /* 0 seconds elapsed */
+      0x00, 0x00, /* Flags (unicast) */
+      0x00, 0x00, 0x00, 0x00, /* Client ip */
+      0xc3, 0xaa, 0xbd, 0xc8, /* Your IP */
+      0xc3, 0xaa, 0xbd, 0xab, /* DHCP server ip */
+      0x00, 0x00, 0x00, 0x00, /* relay agent */
+      0x00, 0x23, 0xc1, 0xde, 0xd0, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* MAC addr + padding */
+
+      /* Empty server name */
+      0x34, 0x01, 0x02, 0xff, /* Overload: SNAME + END */
+      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+      /* Empty boot file name */
+      0x34, 0x01, 0x01, 0xff, /* Overload FILE + END */
+      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+
+      0x63, 0x82, 0x53, 0x63, /* Magic cookie */
+      0x35, 0x01, 0x02, /* Message type: Offer */
+      0x36, 0x04, 0xc3, 0xaa, 0xbd, 0xab, /* Server identifier (IP) */
+      0x33, 0x04, 0x00, 0x00, 0x00, 0x78, /* Lease time 2 minutes */
+      0x03, 0x04, 0xc3, 0xaa, 0xbd, 0xab, /* Router IP */
+      0x01, 0x04, 0xff, 0xff, 0xff, 0x00, /* Subnet mask */
+      0x34, 0x01, 0x03, /* Overload: FILE + SNAME */
+      0xff, /* End option */
+      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Padding */
+  };
+  ip4_addr_t addr;
+  ip4_addr_t netmask;
+  ip4_addr_t gw;
+  u32_t xid;
+  LWIP_UNUSED_ARG(_i);
+
+  tcase = TEST_LWIP_DHCP_INVALID_OVERLOAD;
+  setdebug(0);
+
+  IP4_ADDR(&addr, 0, 0, 0, 0);
+  IP4_ADDR(&netmask, 0, 0, 0, 0);
+  IP4_ADDR(&gw, 0, 0, 0, 0);
+
+  netif_add(&net_test, &addr, &netmask, &gw, &net_test, testif_init, ethernet_input);
+  netif_set_link_up(&net_test);
+  netif_set_up(&net_test);
+
+  dhcp_start(&net_test);
+
+  fail_unless(txpacket == 1); /* DHCP discover sent */
+  xid = htonl(netif_dhcp_data(&net_test)->xid);
+  memcpy(&dhcp_offer_invalid_overload[46], &xid, 4); /* insert correct transaction id */
+  dhcp_offer_invalid_overload[311] = 3;
+  send_pkt(&net_test, dhcp_offer_invalid_overload, sizeof(dhcp_offer_invalid_overload));
+  /* IP addresses should be zero */
+  fail_if(memcmp(&addr, &net_test.ip_addr, sizeof(ip4_addr_t)));
+  fail_if(memcmp(&netmask, &net_test.netmask, sizeof(ip4_addr_t)));
+  fail_if(memcmp(&gw, &net_test.gw, sizeof(ip4_addr_t)));
+  fail_unless(txpacket == 1); /* Nothing more sent */
+
+  dhcp_offer_invalid_overload[311] = 2;
+  send_pkt(&net_test, dhcp_offer_invalid_overload, sizeof(dhcp_offer_invalid_overload));
+  /* IP addresses should be zero */
+  fail_if(memcmp(&addr, &net_test.ip_addr, sizeof(ip4_addr_t)));
+  fail_if(memcmp(&netmask, &net_test.netmask, sizeof(ip4_addr_t)));
+  fail_if(memcmp(&gw, &net_test.gw, sizeof(ip4_addr_t)));
+  fail_unless(txpacket == 1); /* Nothing more sent */
+
+  dhcp_offer_invalid_overload[311] = 1;
+  send_pkt(&net_test, dhcp_offer_invalid_overload, sizeof(dhcp_offer_invalid_overload));
+  /* IP addresses should be zero */
+  fail_if(memcmp(&addr, &net_test.ip_addr, sizeof(ip4_addr_t)));
+  fail_if(memcmp(&netmask, &net_test.netmask, sizeof(ip4_addr_t)));
+  fail_if(memcmp(&gw, &net_test.gw, sizeof(ip4_addr_t)));
+  fail_unless(txpacket == 1); /* Nothing more sent */
+
+  dhcp_offer_invalid_overload[311] = 0;
+  send_pkt(&net_test, dhcp_offer_invalid_overload, sizeof(dhcp_offer));
+
+  fail_unless(netif_dhcp_data(&net_test)->state == DHCP_STATE_REQUESTING);
+
+  fail_unless(txpacket == 2); /* No more sent */
+  xid = htonl(netif_dhcp_data(&net_test)->xid); /* xid updated */
+
+  tcase = TEST_NONE;
+  dhcp_stop(&net_test);
+  dhcp_cleanup(&net_test);
+  netif_remove(&net_test);
+}
+END_TEST
+
+/** Create the suite including all tests for this module */
+Suite *
+dhcp_suite(void)
+{
+  testfunc tests[] = {
+    TESTFUNC(test_dhcp),
+    TESTFUNC(test_dhcp_nak),
+    TESTFUNC(test_dhcp_relayed),
+    TESTFUNC(test_dhcp_nak_no_endmarker),
+    TESTFUNC(test_dhcp_invalid_overload)
+  };
+  return create_suite("DHCP", tests, sizeof(tests)/sizeof(testfunc), dhcp_setup, dhcp_teardown);
+}
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/test/unit/dhcp/test_dhcp.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/test/unit/dhcp/test_dhcp.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/test/unit/dhcp/test_dhcp.h	(revision 457)
@@ -0,0 +1,8 @@
+#ifndef LWIP_HDR_TEST_DHCP_H
+#define LWIP_HDR_TEST_DHCP_H
+
+#include "../lwip_check.h"
+
+Suite* dhcp_suite(void);
+
+#endif
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/test/unit/etharp/test_etharp.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/test/unit/etharp/test_etharp.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/test/unit/etharp/test_etharp.c	(revision 457)
@@ -0,0 +1,272 @@
+#include "test_etharp.h"
+
+#include "lwip/udp.h"
+#include "lwip/etharp.h"
+#include "netif/ethernet.h"
+#include "lwip/stats.h"
+#include "lwip/prot/iana.h"
+
+#if !LWIP_STATS || !UDP_STATS || !MEMP_STATS || !ETHARP_STATS
+#error "This tests needs UDP-, MEMP- and ETHARP-statistics enabled"
+#endif
+#if !ETHARP_SUPPORT_STATIC_ENTRIES
+#error "This test needs ETHARP_SUPPORT_STATIC_ENTRIES enabled"
+#endif
+
+static struct netif test_netif;
+static ip4_addr_t test_ipaddr, test_netmask, test_gw;
+struct eth_addr test_ethaddr =  {{1,1,1,1,1,1}};
+struct eth_addr test_ethaddr2 = {{1,1,1,1,1,2}};
+struct eth_addr test_ethaddr3 = {{1,1,1,1,1,3}};
+struct eth_addr test_ethaddr4 = {{1,1,1,1,1,4}};
+static int linkoutput_ctr;
+
+/* Helper functions */
+static void
+etharp_remove_all(void)
+{
+  int i;
+  /* call etharp_tmr often enough to have all entries cleaned */
+  for(i = 0; i < 0xff; i++) {
+    etharp_tmr();
+  }
+}
+
+static err_t
+default_netif_linkoutput(struct netif *netif, struct pbuf *p)
+{
+  fail_unless(netif == &test_netif);
+  fail_unless(p != NULL);
+  linkoutput_ctr++;
+  return ERR_OK;
+}
+
+static err_t
+default_netif_init(struct netif *netif)
+{
+  fail_unless(netif != NULL);
+  netif->linkoutput = default_netif_linkoutput;
+  netif->output = etharp_output;
+  netif->mtu = 1500;
+  netif->flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP | NETIF_FLAG_LINK_UP;
+  netif->hwaddr_len = ETHARP_HWADDR_LEN;
+  return ERR_OK;
+}
+
+static void
+default_netif_add(void)
+{
+  IP4_ADDR(&test_gw, 192,168,0,1);
+  IP4_ADDR(&test_ipaddr, 192,168,0,1);
+  IP4_ADDR(&test_netmask, 255,255,0,0);
+
+  fail_unless(netif_default == NULL);
+  netif_set_default(netif_add(&test_netif, &test_ipaddr, &test_netmask,
+                              &test_gw, NULL, default_netif_init, NULL));
+  netif_set_up(&test_netif);
+}
+
+static void
+default_netif_remove(void)
+{
+  fail_unless(netif_default == &test_netif);
+  netif_remove(&test_netif);
+}
+
+static void
+create_arp_response(ip4_addr_t *adr)
+{
+  int k;
+  struct eth_hdr *ethhdr;
+  struct etharp_hdr *etharphdr;
+  struct pbuf *p = pbuf_alloc(PBUF_RAW, sizeof(struct eth_hdr) + sizeof(struct etharp_hdr), PBUF_RAM);
+  if(p == NULL) {
+    FAIL_RET();
+  }
+  ethhdr = (struct eth_hdr*)p->payload;
+  etharphdr = (struct etharp_hdr*)(ethhdr + 1);
+
+  ethhdr->dest = test_ethaddr;
+  ethhdr->src = test_ethaddr2;
+  ethhdr->type = htons(ETHTYPE_ARP);
+
+  etharphdr->hwtype = htons(LWIP_IANA_HWTYPE_ETHERNET);
+  etharphdr->proto = htons(ETHTYPE_IP);
+  etharphdr->hwlen = ETHARP_HWADDR_LEN;
+  etharphdr->protolen = sizeof(ip4_addr_t);
+  etharphdr->opcode = htons(ARP_REPLY);
+
+  SMEMCPY(&etharphdr->sipaddr, adr, sizeof(ip4_addr_t));
+  SMEMCPY(&etharphdr->dipaddr, &test_ipaddr, sizeof(ip4_addr_t));
+
+  k = 6;
+  while(k > 0) {
+    k--;
+    /* Write the ARP MAC-Addresses */
+    etharphdr->shwaddr.addr[k] = test_ethaddr2.addr[k];
+    etharphdr->dhwaddr.addr[k] = test_ethaddr.addr[k];
+    /* Write the Ethernet MAC-Addresses */
+    ethhdr->dest.addr[k] = test_ethaddr.addr[k];
+    ethhdr->src.addr[k]  = test_ethaddr2.addr[k];
+  }
+
+  ethernet_input(p, &test_netif);
+}
+
+/* Setups/teardown functions */
+
+static void
+etharp_setup(void)
+{
+  etharp_remove_all();
+  default_netif_add();
+  lwip_check_ensure_no_alloc(SKIP_POOL(MEMP_SYS_TIMEOUT));
+}
+
+static void
+etharp_teardown(void)
+{
+  etharp_remove_all();
+  default_netif_remove();
+  lwip_check_ensure_no_alloc(SKIP_POOL(MEMP_SYS_TIMEOUT));
+}
+
+
+/* Test functions */
+
+START_TEST(test_etharp_table)
+{
+#if ETHARP_SUPPORT_STATIC_ENTRIES
+  err_t err;
+#endif /* ETHARP_SUPPORT_STATIC_ENTRIES */
+  ssize_t idx;
+  const ip4_addr_t *unused_ipaddr;
+  struct eth_addr *unused_ethaddr;
+  struct udp_pcb* pcb;
+  LWIP_UNUSED_ARG(_i);
+
+  if (netif_default != &test_netif) {
+    fail("This test needs a default netif");
+  }
+
+  linkoutput_ctr = 0;
+
+  pcb = udp_new();
+  fail_unless(pcb != NULL);
+  if (pcb != NULL) {
+    ip4_addr_t adrs[ARP_TABLE_SIZE + 2];
+    int i;
+    for(i = 0; i < ARP_TABLE_SIZE + 2; i++) {
+      IP4_ADDR(&adrs[i], 192,168,0,i+2);
+    }
+    /* fill ARP-table with dynamic entries */
+    for(i = 0; i < ARP_TABLE_SIZE; i++) {
+      struct pbuf *p = pbuf_alloc(PBUF_TRANSPORT, 10, PBUF_RAM);
+      fail_unless(p != NULL);
+      if (p != NULL) {
+        err_t err2;
+        ip_addr_t dst;
+        ip_addr_copy_from_ip4(dst, adrs[i]);
+        err2 = udp_sendto(pcb, p, &dst, 123);
+        fail_unless(err2 == ERR_OK);
+        /* etharp request sent? */
+        fail_unless(linkoutput_ctr == (2*i) + 1);
+        pbuf_free(p);
+
+        /* create an ARP response */
+        create_arp_response(&adrs[i]);
+        /* queued UDP packet sent? */
+        fail_unless(linkoutput_ctr == (2*i) + 2);
+
+        idx = etharp_find_addr(NULL, &adrs[i], &unused_ethaddr, &unused_ipaddr);
+        fail_unless(idx == i);
+        etharp_tmr();
+      }
+    }
+    linkoutput_ctr = 0;
+#if ETHARP_SUPPORT_STATIC_ENTRIES
+    /* create one static entry */
+    err = etharp_add_static_entry(&adrs[ARP_TABLE_SIZE], &test_ethaddr3);
+    fail_unless(err == ERR_OK);
+    idx = etharp_find_addr(NULL, &adrs[ARP_TABLE_SIZE], &unused_ethaddr, &unused_ipaddr);
+    fail_unless(idx == 0);
+    fail_unless(linkoutput_ctr == 0);
+#endif /* ETHARP_SUPPORT_STATIC_ENTRIES */
+
+    linkoutput_ctr = 0;
+    /* fill ARP-table with dynamic entries */
+    for(i = 0; i < ARP_TABLE_SIZE; i++) {
+      struct pbuf *p = pbuf_alloc(PBUF_TRANSPORT, 10, PBUF_RAM);
+      fail_unless(p != NULL);
+      if (p != NULL) {
+        err_t err2;
+        ip_addr_t dst;
+        ip_addr_copy_from_ip4(dst, adrs[i]);
+        err2 = udp_sendto(pcb, p, &dst, 123);
+        fail_unless(err2 == ERR_OK);
+        /* etharp request sent? */
+        fail_unless(linkoutput_ctr == (2*i) + 1);
+        pbuf_free(p);
+
+        /* create an ARP response */
+        create_arp_response(&adrs[i]);
+        /* queued UDP packet sent? */
+        fail_unless(linkoutput_ctr == (2*i) + 2);
+
+        idx = etharp_find_addr(NULL, &adrs[i], &unused_ethaddr, &unused_ipaddr);
+        if (i < ARP_TABLE_SIZE - 1) {
+          fail_unless(idx == i+1);
+        } else {
+          /* the last entry must not overwrite the static entry! */
+          fail_unless(idx == 1);
+        }
+        etharp_tmr();
+      }
+    }
+#if ETHARP_SUPPORT_STATIC_ENTRIES
+    /* create a second static entry */
+    err = etharp_add_static_entry(&adrs[ARP_TABLE_SIZE+1], &test_ethaddr4);
+    fail_unless(err == ERR_OK);
+    idx = etharp_find_addr(NULL, &adrs[ARP_TABLE_SIZE], &unused_ethaddr, &unused_ipaddr);
+    fail_unless(idx == 0);
+    idx = etharp_find_addr(NULL, &adrs[ARP_TABLE_SIZE+1], &unused_ethaddr, &unused_ipaddr);
+    fail_unless(idx == 2);
+    /* and remove it again */
+    err = etharp_remove_static_entry(&adrs[ARP_TABLE_SIZE+1]);
+    fail_unless(err == ERR_OK);
+    idx = etharp_find_addr(NULL, &adrs[ARP_TABLE_SIZE], &unused_ethaddr, &unused_ipaddr);
+    fail_unless(idx == 0);
+    idx = etharp_find_addr(NULL, &adrs[ARP_TABLE_SIZE+1], &unused_ethaddr, &unused_ipaddr);
+    fail_unless(idx == -1);
+#endif /* ETHARP_SUPPORT_STATIC_ENTRIES */
+
+    /* check that static entries don't time out */
+    etharp_remove_all();
+    idx = etharp_find_addr(NULL, &adrs[ARP_TABLE_SIZE], &unused_ethaddr, &unused_ipaddr);
+    fail_unless(idx == 0);
+
+#if ETHARP_SUPPORT_STATIC_ENTRIES
+    /* remove the first static entry */
+    err = etharp_remove_static_entry(&adrs[ARP_TABLE_SIZE]);
+    fail_unless(err == ERR_OK);
+    idx = etharp_find_addr(NULL, &adrs[ARP_TABLE_SIZE], &unused_ethaddr, &unused_ipaddr);
+    fail_unless(idx == -1);
+    idx = etharp_find_addr(NULL, &adrs[ARP_TABLE_SIZE+1], &unused_ethaddr, &unused_ipaddr);
+    fail_unless(idx == -1);
+#endif /* ETHARP_SUPPORT_STATIC_ENTRIES */
+
+    udp_remove(pcb);
+  }
+}
+END_TEST
+
+
+/** Create the suite including all tests for this module */
+Suite *
+etharp_suite(void)
+{
+  testfunc tests[] = {
+    TESTFUNC(test_etharp_table)
+  };
+  return create_suite("ETHARP", tests, sizeof(tests)/sizeof(testfunc), etharp_setup, etharp_teardown);
+}
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/test/unit/etharp/test_etharp.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/test/unit/etharp/test_etharp.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/test/unit/etharp/test_etharp.h	(revision 457)
@@ -0,0 +1,8 @@
+#ifndef LWIP_HDR_TEST_ETHARP_H
+#define LWIP_HDR_TEST_ETHARP_H
+
+#include "../lwip_check.h"
+
+Suite* etharp_suite(void);
+
+#endif
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/test/unit/ip4/test_ip4.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/test/unit/ip4/test_ip4.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/test/unit/ip4/test_ip4.c	(revision 457)
@@ -0,0 +1,160 @@
+#include "test_ip4.h"
+
+#include "lwip/ip4.h"
+#include "lwip/inet_chksum.h"
+#include "lwip/stats.h"
+#include "lwip/prot/ip.h"
+#include "lwip/prot/ip4.h"
+
+#include "lwip/tcpip.h"
+
+#if !LWIP_IPV4 || !IP_REASSEMBLY || !MIB2_STATS || !IPFRAG_STATS
+#error "This tests needs LWIP_IPV4, IP_REASSEMBLY; MIB2- and IPFRAG-statistics enabled"
+#endif
+
+/* Helper functions */
+static void
+create_ip4_input_fragment(u16_t ip_id, u16_t start, u16_t len, int last)
+{
+  struct pbuf *p;
+  struct netif *input_netif = netif_list; /* just use any netif */
+  fail_unless((start & 7) == 0);
+  fail_unless(((len & 7) == 0) || last);
+  fail_unless(input_netif != NULL);
+
+  p = pbuf_alloc(PBUF_RAW, len + sizeof(struct ip_hdr), PBUF_RAM);
+  fail_unless(p != NULL);
+  if (p != NULL) {
+    err_t err;
+    struct ip_hdr *iphdr = (struct ip_hdr *)p->payload;
+    IPH_VHL_SET(iphdr, 4, sizeof(struct ip_hdr) / 4);
+    IPH_TOS_SET(iphdr, 0);
+    IPH_LEN_SET(iphdr, lwip_htons(p->tot_len));
+    IPH_ID_SET(iphdr, lwip_htons(ip_id));
+    if (last) {
+      IPH_OFFSET_SET(iphdr, lwip_htons(start / 8));
+    } else {
+      IPH_OFFSET_SET(iphdr, lwip_htons((start / 8) | IP_MF));
+    }
+    IPH_TTL_SET(iphdr, 5);
+    IPH_PROTO_SET(iphdr, IP_PROTO_UDP);
+    IPH_CHKSUM_SET(iphdr, 0);
+    ip4_addr_copy(iphdr->src, *netif_ip4_addr(input_netif));
+    iphdr->src.addr = lwip_htonl(lwip_htonl(iphdr->src.addr) + 1);
+    ip4_addr_copy(iphdr->dest, *netif_ip4_addr(input_netif));
+    IPH_CHKSUM_SET(iphdr, inet_chksum(iphdr, sizeof(struct ip_hdr)));
+
+    err = ip4_input(p, input_netif);
+    if (err != ERR_OK) {
+      pbuf_free(p);
+    }
+    fail_unless(err == ERR_OK);
+  }
+}
+
+/* Setups/teardown functions */
+
+static void
+ip4_setup(void)
+{
+  lwip_check_ensure_no_alloc(SKIP_POOL(MEMP_SYS_TIMEOUT));
+}
+
+static void
+ip4_teardown(void)
+{
+  if (netif_list->loop_first != NULL) {
+    pbuf_free(netif_list->loop_first);
+    netif_list->loop_first = NULL;
+  }
+  netif_list->loop_last = NULL;
+  /* poll until all memory is released... */
+  tcpip_thread_poll_one();
+  lwip_check_ensure_no_alloc(SKIP_POOL(MEMP_SYS_TIMEOUT));
+}
+
+
+/* Test functions */
+
+START_TEST(test_ip4_reass)
+{
+  const u16_t ip_id = 128;
+  LWIP_UNUSED_ARG(_i);
+
+  memset(&lwip_stats.mib2, 0, sizeof(lwip_stats.mib2));
+
+  create_ip4_input_fragment(ip_id, 8*200, 200, 1);
+  fail_unless(lwip_stats.ip_frag.recv == 1);
+  fail_unless(lwip_stats.ip_frag.err == 0);
+  fail_unless(lwip_stats.ip_frag.memerr == 0);
+  fail_unless(lwip_stats.ip_frag.drop == 0);
+  fail_unless(lwip_stats.mib2.ipreasmoks == 0);
+
+  create_ip4_input_fragment(ip_id, 0*200, 200, 0);
+  fail_unless(lwip_stats.ip_frag.recv == 2);
+  fail_unless(lwip_stats.ip_frag.err == 0);
+  fail_unless(lwip_stats.ip_frag.memerr == 0);
+  fail_unless(lwip_stats.ip_frag.drop == 0);
+  fail_unless(lwip_stats.mib2.ipreasmoks == 0);
+
+  create_ip4_input_fragment(ip_id, 1*200, 200, 0);
+  fail_unless(lwip_stats.ip_frag.recv == 3);
+  fail_unless(lwip_stats.ip_frag.err == 0);
+  fail_unless(lwip_stats.ip_frag.memerr == 0);
+  fail_unless(lwip_stats.ip_frag.drop == 0);
+  fail_unless(lwip_stats.mib2.ipreasmoks == 0);
+
+  create_ip4_input_fragment(ip_id, 2*200, 200, 0);
+  fail_unless(lwip_stats.ip_frag.recv == 4);
+  fail_unless(lwip_stats.ip_frag.err == 0);
+  fail_unless(lwip_stats.ip_frag.memerr == 0);
+  fail_unless(lwip_stats.ip_frag.drop == 0);
+  fail_unless(lwip_stats.mib2.ipreasmoks == 0);
+
+  create_ip4_input_fragment(ip_id, 3*200, 200, 0);
+  fail_unless(lwip_stats.ip_frag.recv == 5);
+  fail_unless(lwip_stats.ip_frag.err == 0);
+  fail_unless(lwip_stats.ip_frag.memerr == 0);
+  fail_unless(lwip_stats.ip_frag.drop == 0);
+  fail_unless(lwip_stats.mib2.ipreasmoks == 0);
+
+  create_ip4_input_fragment(ip_id, 4*200, 200, 0);
+  fail_unless(lwip_stats.ip_frag.recv == 6);
+  fail_unless(lwip_stats.ip_frag.err == 0);
+  fail_unless(lwip_stats.ip_frag.memerr == 0);
+  fail_unless(lwip_stats.ip_frag.drop == 0);
+  fail_unless(lwip_stats.mib2.ipreasmoks == 0);
+
+  create_ip4_input_fragment(ip_id, 7*200, 200, 0);
+  fail_unless(lwip_stats.ip_frag.recv == 7);
+  fail_unless(lwip_stats.ip_frag.err == 0);
+  fail_unless(lwip_stats.ip_frag.memerr == 0);
+  fail_unless(lwip_stats.ip_frag.drop == 0);
+  fail_unless(lwip_stats.mib2.ipreasmoks == 0);
+
+  create_ip4_input_fragment(ip_id, 6*200, 200, 0);
+  fail_unless(lwip_stats.ip_frag.recv == 8);
+  fail_unless(lwip_stats.ip_frag.err == 0);
+  fail_unless(lwip_stats.ip_frag.memerr == 0);
+  fail_unless(lwip_stats.ip_frag.drop == 0);
+  fail_unless(lwip_stats.mib2.ipreasmoks == 0);
+
+  create_ip4_input_fragment(ip_id, 5*200, 200, 0);
+  fail_unless(lwip_stats.ip_frag.recv == 9);
+  fail_unless(lwip_stats.ip_frag.err == 0);
+  fail_unless(lwip_stats.ip_frag.memerr == 0);
+  fail_unless(lwip_stats.ip_frag.drop == 0);
+  fail_unless(lwip_stats.mib2.ipreasmoks == 1);
+}
+END_TEST
+
+
+/** Create the suite including all tests for this module */
+Suite *
+ip4_suite(void)
+{
+  testfunc tests[] = {
+    TESTFUNC(test_ip4_reass),
+  };
+  return create_suite("IPv4", tests, sizeof(tests)/sizeof(testfunc), ip4_setup, ip4_teardown);
+}
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/test/unit/ip4/test_ip4.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/test/unit/ip4/test_ip4.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/test/unit/ip4/test_ip4.h	(revision 457)
@@ -0,0 +1,8 @@
+#ifndef LWIP_HDR_TEST_IP4_H
+#define LWIP_HDR_TEST_IP4_H
+
+#include "../lwip_check.h"
+
+Suite* ip4_suite(void);
+
+#endif
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/test/unit/ip6/test_ip6.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/test/unit/ip6/test_ip6.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/test/unit/ip6/test_ip6.c	(revision 457)
@@ -0,0 +1,321 @@
+#include "test_ip6.h"
+
+#include "lwip/ethip6.h"
+#include "lwip/ip6.h"
+#include "lwip/inet_chksum.h"
+#include "lwip/nd6.h"
+#include "lwip/stats.h"
+#include "lwip/prot/ethernet.h"
+#include "lwip/prot/ip.h"
+#include "lwip/prot/ip6.h"
+
+#include "lwip/tcpip.h"
+
+#if LWIP_IPV6 /* allow to build the unit tests without IPv6 support */
+
+static struct netif test_netif6;
+static int linkoutput_ctr;
+
+static err_t
+default_netif_linkoutput(struct netif *netif, struct pbuf *p)
+{
+  fail_unless(netif == &test_netif6);
+  fail_unless(p != NULL);
+  linkoutput_ctr++;
+  return ERR_OK;
+}
+
+static err_t
+default_netif_init(struct netif *netif)
+{
+  fail_unless(netif != NULL);
+  netif->linkoutput = default_netif_linkoutput;
+  netif->output_ip6 = ethip6_output;
+  netif->mtu = 1500;
+  netif->flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHERNET | NETIF_FLAG_MLD6;
+  netif->hwaddr_len = ETH_HWADDR_LEN;
+  return ERR_OK;
+}
+
+static void
+default_netif_add(void)
+{
+  struct netif *n;
+  fail_unless(netif_default == NULL);
+  n = netif_add_noaddr(&test_netif6, NULL, default_netif_init, NULL);
+  fail_unless(n == &test_netif6);
+  netif_set_default(&test_netif6);
+}
+
+static void
+default_netif_remove(void)
+{
+  fail_unless(netif_default == &test_netif6);
+  netif_remove(&test_netif6);
+}
+
+static void
+ip6_test_handle_timers(int count)
+{
+  int i;
+  for (i = 0; i < count; i++) {
+    nd6_tmr();
+  }
+}
+
+/* Setups/teardown functions */
+
+static void
+ip6_setup(void)
+{
+  default_netif_add();
+  lwip_check_ensure_no_alloc(SKIP_POOL(MEMP_SYS_TIMEOUT));
+}
+
+static void
+ip6_teardown(void)
+{
+  if (netif_list->loop_first != NULL) {
+    pbuf_free(netif_list->loop_first);
+    netif_list->loop_first = NULL;
+  }
+  netif_list->loop_last = NULL;
+  /* poll until all memory is released... */
+  tcpip_thread_poll_one();
+  default_netif_remove();
+  lwip_check_ensure_no_alloc(SKIP_POOL(MEMP_SYS_TIMEOUT));
+}
+
+
+/* Test functions */
+
+static void
+test_ip6_ll_addr_iter(int expected_ctr1, int expected_ctr2)
+{
+  fail_unless(linkoutput_ctr == 0);
+
+  /* test that nothing is sent with link uo but netif down */
+  netif_set_link_up(&test_netif6);
+  ip6_test_handle_timers(500);
+  fail_unless(linkoutput_ctr == 0);
+  netif_set_link_down(&test_netif6);
+  fail_unless(linkoutput_ctr == 0);
+
+  /* test that nothing is sent with link down but netif up */
+  netif_set_up(&test_netif6);
+  ip6_test_handle_timers(500);
+  fail_unless(linkoutput_ctr == 0);
+  netif_set_down(&test_netif6);
+  fail_unless(linkoutput_ctr == 0);
+
+  /* test what is sent with link up + netif up */
+  netif_set_link_up(&test_netif6);
+  netif_set_up(&test_netif6);
+  ip6_test_handle_timers(500);
+  fail_unless(linkoutput_ctr == expected_ctr1);
+  netif_set_down(&test_netif6);
+  netif_set_link_down(&test_netif6);
+  fail_unless(linkoutput_ctr == expected_ctr1);
+  linkoutput_ctr = 0;
+
+  netif_set_up(&test_netif6);
+  netif_set_link_up(&test_netif6);
+  ip6_test_handle_timers(500);
+  fail_unless(linkoutput_ctr == expected_ctr2);
+  netif_set_link_down(&test_netif6);
+  netif_set_down(&test_netif6);
+  fail_unless(linkoutput_ctr == expected_ctr2);
+  linkoutput_ctr = 0;
+}
+
+START_TEST(test_ip6_ll_addr)
+{
+  LWIP_UNUSED_ARG(_i);
+
+  /* test without link-local address */
+  test_ip6_ll_addr_iter(0, 0);
+
+  /* test with link-local address */
+  netif_create_ip6_linklocal_address(&test_netif6, 1);
+  test_ip6_ll_addr_iter(3 + LWIP_IPV6_DUP_DETECT_ATTEMPTS + LWIP_IPV6_MLD, 3);
+}
+END_TEST
+
+START_TEST(test_ip6_aton_ipv4mapped)
+{
+  int ret;
+  ip_addr_t addr;
+  ip6_addr_t addr6;
+  const ip_addr_t addr_expected = IPADDR6_INIT_HOST(0, 0, 0xFFFF, 0xD4CC65D2);
+  const char *full_ipv6_addr = "0:0:0:0:0:FFFF:D4CC:65D2";
+  const char *shortened_ipv6_addr = "::FFFF:D4CC:65D2";
+  const char *full_ipv4_mapped_addr = "0:0:0:0:0:FFFF:212.204.101.210";
+  const char *shortened_ipv4_mapped_addr = "::FFFF:212.204.101.210";
+  const char *bogus_ipv4_mapped_addr = "::FFFF:212.204.101.2101";
+  LWIP_UNUSED_ARG(_i);
+
+  /* check IPv6 representation */
+  memset(&addr6, 0, sizeof(addr6));
+  ret = ip6addr_aton(full_ipv6_addr, &addr6);
+  fail_unless(ret == 1);
+  fail_unless(memcmp(&addr6, &addr_expected, 16) == 0);
+  memset(&addr, 0, sizeof(addr));
+  ret = ipaddr_aton(full_ipv6_addr, &addr);
+  fail_unless(ret == 1);
+  fail_unless(memcmp(&addr, &addr_expected, 16) == 0);
+
+  /* check shortened IPv6 representation */
+  memset(&addr6, 0, sizeof(addr6));
+  ret = ip6addr_aton(shortened_ipv6_addr, &addr6);
+  fail_unless(ret == 1);
+  fail_unless(memcmp(&addr6, &addr_expected, 16) == 0);
+  memset(&addr, 0, sizeof(addr));
+  ret = ipaddr_aton(shortened_ipv6_addr, &addr);
+  fail_unless(ret == 1);
+  fail_unless(memcmp(&addr, &addr_expected, 16) == 0);
+
+  /* checked shortened mixed representation */
+  memset(&addr6, 0, sizeof(addr6));
+  ret = ip6addr_aton(shortened_ipv4_mapped_addr, &addr6);
+  fail_unless(ret == 1);
+  fail_unless(memcmp(&addr6, &addr_expected, 16) == 0);
+  memset(&addr, 0, sizeof(addr));
+  ret = ipaddr_aton(shortened_ipv4_mapped_addr, &addr);
+  fail_unless(ret == 1);
+  fail_unless(memcmp(&addr, &addr_expected, 16) == 0);
+
+  /* checked mixed representation */
+  memset(&addr6, 0, sizeof(addr6));
+  ret = ip6addr_aton(full_ipv4_mapped_addr, &addr6);
+  fail_unless(ret == 1);
+  fail_unless(memcmp(&addr6, &addr_expected, 16) == 0);
+  memset(&addr, 0, sizeof(addr));
+  ret = ipaddr_aton(full_ipv4_mapped_addr, &addr);
+  fail_unless(ret == 1);
+  fail_unless(memcmp(&addr, &addr_expected, 16) == 0);
+
+  /* checked bogus mixed representation */
+  memset(&addr6, 0, sizeof(addr6));
+  ret = ip6addr_aton(bogus_ipv4_mapped_addr, &addr6);
+  fail_unless(ret == 0);
+  memset(&addr, 0, sizeof(addr));
+  ret = ipaddr_aton(bogus_ipv4_mapped_addr, &addr);
+  fail_unless(ret == 0);
+}
+END_TEST
+
+START_TEST(test_ip6_ntoa_ipv4mapped)
+{
+  const ip_addr_t addr = IPADDR6_INIT_HOST(0, 0, 0xFFFF, 0xD4CC65D2);
+  char buf[128];
+  char *str;
+  LWIP_UNUSED_ARG(_i);
+
+  str = ip6addr_ntoa_r(ip_2_ip6(&addr), buf, sizeof(buf));
+  fail_unless(str == buf);
+  fail_unless(!strcmp(str, "::FFFF:212.204.101.210"));
+}
+END_TEST
+
+struct test_addr_and_str {
+  ip_addr_t addr;
+  const char *str;
+};
+
+START_TEST(test_ip6_ntoa)
+{
+  struct test_addr_and_str tests[] = {
+    {IPADDR6_INIT_HOST(0xfe800000, 0x00000000, 0xb2a1a2ff, 0xfea3a4a5), "FE80::B2A1:A2FF:FEA3:A4A5"}, /* test shortened zeros */
+    {IPADDR6_INIT_HOST(0xfe800000, 0xff000000, 0xb2a1a2ff, 0xfea3a4a5), "FE80:0:FF00:0:B2A1:A2FF:FEA3:A4A5"}, /* don't omit single zero blocks */
+    {IPADDR6_INIT_HOST(0xfe800000, 0xff000000, 0xb2000000, 0x0000a4a5), "FE80:0:FF00:0:B200::A4A5"}, /* omit longest zero block */
+  };
+  char buf[128];
+  char *str;
+  size_t i;
+  LWIP_UNUSED_ARG(_i);
+
+  for (i = 0; i < LWIP_ARRAYSIZE(tests); i++) {
+    str = ip6addr_ntoa_r(ip_2_ip6(&tests[i].addr), buf, sizeof(buf));
+    fail_unless(str == buf);
+    fail_unless(!strcmp(str, tests[i].str));
+  }
+}
+END_TEST
+
+START_TEST(test_ip6_lladdr)
+{
+  u8_t zeros[128];
+  const u8_t test_mac_addr[6] = {0xb0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5};
+  const u32_t expected_ip6_addr_1[4] = {PP_HTONL(0xfe800000), 0, PP_HTONL(0xb2a1a2ff), PP_HTONL(0xfea3a4a5)};
+  const u32_t expected_ip6_addr_2[4] = {PP_HTONL(0xfe800000), 0, PP_HTONL(0x0000b0a1), PP_HTONL(0xa2a3a4a5)};
+  LWIP_UNUSED_ARG(_i);
+  memset(zeros, 0, sizeof(zeros));
+
+  fail_unless(test_netif6.hwaddr_len == 6);
+  fail_unless(!memcmp(test_netif6.hwaddr, zeros, 6));
+
+  fail_unless(test_netif6.ip6_addr_state[0] == 0);
+  fail_unless(!memcmp(netif_ip6_addr(&test_netif6, 0), zeros, sizeof(ip6_addr_t)));
+
+  /* set specific mac addr */
+  memcpy(test_netif6.hwaddr, test_mac_addr, 6);
+
+  /* create link-local addr based on mac (EUI-48) */
+  netif_create_ip6_linklocal_address(&test_netif6, 1);
+  fail_unless(IP_IS_V6(&test_netif6.ip6_addr[0]));
+  fail_unless(!memcmp(&netif_ip6_addr(&test_netif6, 0)->addr, expected_ip6_addr_1, 16));
+#if LWIP_IPV6_SCOPES
+  fail_unless(netif_ip6_addr(&test_netif6, 0)->zone == (test_netif6.num + 1));
+#endif
+  /* reset address */
+  memset(&test_netif6.ip6_addr[0], 0, sizeof(ip6_addr_t));
+  test_netif6.ip6_addr_state[0] = 0;
+
+  /* create link-local addr based interface ID */
+  netif_create_ip6_linklocal_address(&test_netif6, 0);
+  fail_unless(IP_IS_V6(&test_netif6.ip6_addr[0]));
+  fail_unless(!memcmp(&netif_ip6_addr(&test_netif6, 0)->addr, expected_ip6_addr_2, 16));
+#if LWIP_IPV6_SCOPES
+  fail_unless(netif_ip6_addr(&test_netif6, 0)->zone == (test_netif6.num + 1));
+#endif
+  /* reset address */
+  memset(&test_netif6.ip6_addr[0], 0, sizeof(ip6_addr_t));
+  test_netif6.ip6_addr_state[0] = 0;
+
+  /* reset mac address */
+  memset(&test_netif6.hwaddr, 0, sizeof(test_netif6.hwaddr));
+}
+END_TEST
+
+/** Create the suite including all tests for this module */
+Suite *
+ip6_suite(void)
+{
+  testfunc tests[] = {
+    TESTFUNC(test_ip6_ll_addr),
+    TESTFUNC(test_ip6_aton_ipv4mapped),
+    TESTFUNC(test_ip6_ntoa_ipv4mapped),
+    TESTFUNC(test_ip6_ntoa),
+    TESTFUNC(test_ip6_lladdr)
+  };
+  return create_suite("IPv6", tests, sizeof(tests)/sizeof(testfunc), ip6_setup, ip6_teardown);
+}
+
+#else /* LWIP_IPV6 */
+
+/* allow to build the unit tests without IPv6 support */
+START_TEST(test_ip6_dummy)
+{
+  LWIP_UNUSED_ARG(_i);
+}
+END_TEST
+
+Suite *
+ip6_suite(void)
+{
+  testfunc tests[] = {
+    TESTFUNC(test_ip6_dummy),
+  };
+  return create_suite("IPv6", tests, sizeof(tests)/sizeof(testfunc), NULL, NULL);
+}
+#endif /* LWIP_IPV6 */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/test/unit/ip6/test_ip6.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/test/unit/ip6/test_ip6.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/test/unit/ip6/test_ip6.h	(revision 457)
@@ -0,0 +1,8 @@
+#ifndef LWIP_HDR_TEST_IP6_H
+#define LWIP_HDR_TEST_IP6_H
+
+#include "../lwip_check.h"
+
+Suite* ip6_suite(void);
+
+#endif
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/test/unit/lwip_check.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/test/unit/lwip_check.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/test/unit/lwip_check.h	(revision 457)
@@ -0,0 +1,42 @@
+#ifndef LWIP_HDR_LWIP_CHECK_H
+#define LWIP_HDR_LWIP_CHECK_H
+
+/* Common header file for lwIP unit tests using the check framework */
+
+#include <config.h>
+#include <check.h>
+#include <stdlib.h>
+
+#define FAIL_RET() do { fail(); return; } while(0)
+#define EXPECT(x) fail_unless(x)
+#define EXPECT_RET(x) do { fail_unless(x); if(!(x)) { return; }} while(0)
+#define EXPECT_RETX(x, y) do { fail_unless(x); if(!(x)) { return y; }} while(0)
+#define EXPECT_RETNULL(x) EXPECT_RETX(x, NULL)
+
+typedef struct {
+  TFun func;
+  const char *name;
+} testfunc;
+
+#define TESTFUNC(x) {(x), "" # x "" }
+
+/* Modified function from check.h, supplying function name */
+#define tcase_add_named_test(tc,tf) \
+   _tcase_add_test((tc),(tf).func,(tf).name,0, 0, 0, 1)
+
+/** typedef for a function returning a test suite */
+typedef Suite* (suite_getter_fn)(void);
+
+/** Create a test suite */
+Suite* create_suite(const char* name, testfunc *tests, size_t num_tests, SFun setup, SFun teardown);
+
+#ifdef LWIP_UNITTESTS_LIB
+int lwip_unittests_run(void)
+#endif
+
+/* helper functions */
+#define SKIP_POOL(x) (1 << x)
+#define SKIP_HEAP    (1 << MEMP_MAX)
+void lwip_check_ensure_no_alloc(unsigned int skip);
+
+#endif /* LWIP_HDR_LWIP_CHECK_H */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/test/unit/lwip_unittests.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/test/unit/lwip_unittests.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/test/unit/lwip_unittests.c	(revision 457)
@@ -0,0 +1,107 @@
+#include "lwip_check.h"
+
+#include "ip4/test_ip4.h"
+#include "ip6/test_ip6.h"
+#include "udp/test_udp.h"
+#include "tcp/test_tcp.h"
+#include "tcp/test_tcp_oos.h"
+#include "core/test_def.h"
+#include "core/test_mem.h"
+#include "core/test_netif.h"
+#include "core/test_pbuf.h"
+#include "core/test_timers.h"
+#include "etharp/test_etharp.h"
+#include "dhcp/test_dhcp.h"
+#include "mdns/test_mdns.h"
+#include "mqtt/test_mqtt.h"
+#include "api/test_sockets.h"
+
+#include "lwip/init.h"
+#if !NO_SYS
+#include "lwip/tcpip.h"
+#endif
+
+Suite* create_suite(const char* name, testfunc *tests, size_t num_tests, SFun setup, SFun teardown)
+{
+  size_t i;
+  Suite *s = suite_create(name);
+
+  for(i = 0; i < num_tests; i++) {
+    TCase *tc_core = tcase_create(name);
+    if ((setup != NULL) || (teardown != NULL)) {
+      tcase_add_checked_fixture(tc_core, setup, teardown);
+    }
+    tcase_add_named_test(tc_core, tests[i]);
+    suite_add_tcase(s, tc_core);
+  }
+  return s;
+}
+
+void lwip_check_ensure_no_alloc(unsigned int skip)
+{
+  int i;
+  unsigned int mask;
+
+  if (!(skip & SKIP_HEAP)) {
+    fail_unless(lwip_stats.mem.used == 0);
+  }
+  for (i = 0, mask = 1; i < MEMP_MAX; i++, mask <<= 1) {
+    if (!(skip & mask)) {
+      fail_unless(lwip_stats.memp[i]->used == 0);
+    }
+  }
+}
+
+#ifdef LWIP_UNITTESTS_LIB
+int lwip_unittests_run(void)
+#else
+int main(void)
+#endif
+{
+  int number_failed;
+  SRunner *sr;
+  size_t i;
+  suite_getter_fn* suites[] = {
+    ip4_suite,
+    ip6_suite,
+    udp_suite,
+    tcp_suite,
+    tcp_oos_suite,
+    def_suite,
+    mem_suite,
+    netif_suite,
+    pbuf_suite,
+    timers_suite,
+    etharp_suite,
+    dhcp_suite,
+    mdns_suite,
+    mqtt_suite,
+    sockets_suite
+  };
+  size_t num = sizeof(suites)/sizeof(void*);
+  LWIP_ASSERT("No suites defined", num > 0);
+
+#if NO_SYS
+  lwip_init();
+#else
+  tcpip_init(NULL, NULL);
+#endif
+
+  sr = srunner_create((suites[0])());
+  srunner_set_xml(sr, "lwip_unittests.xml");
+  for(i = 1; i < num; i++) {
+    srunner_add_suite(sr, ((suite_getter_fn*)suites[i])());
+  }
+
+#ifdef LWIP_UNITTESTS_NOFORK
+  srunner_set_fork_status(sr, CK_NOFORK);
+#endif
+#ifdef LWIP_UNITTESTS_FORK
+  srunner_set_fork_status(sr, CK_FORK);
+#endif
+
+  srunner_run_all(sr, CK_NORMAL);
+  number_failed = srunner_ntests_failed(sr);
+  srunner_free(sr);
+  return (number_failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE;
+}
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/test/unit/lwipopts.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/test/unit/lwipopts.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/test/unit/lwipopts.h	(revision 457)
@@ -0,0 +1,85 @@
+/*
+ * Copyright (c) 2001-2003 Swedish Institute of Computer Science.
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission. 
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ * 
+ * Author: Simon Goldschmidt
+ *
+ */
+#ifndef LWIP_HDR_LWIPOPTS_H
+#define LWIP_HDR_LWIPOPTS_H
+
+#define LWIP_TESTMODE                   1
+
+#define LWIP_IPV6                       1
+
+#define LWIP_CHECKSUM_ON_COPY           1
+#define TCP_CHECKSUM_ON_COPY_SANITY_CHECK 1
+#define TCP_CHECKSUM_ON_COPY_SANITY_CHECK_FAIL(printfmsg) LWIP_ASSERT("TCP_CHECKSUM_ON_COPY_SANITY_CHECK_FAIL", 0)
+
+/* We link to special sys_arch.c (for basic non-waiting API layers unit tests) */
+#define NO_SYS                          0
+#define SYS_LIGHTWEIGHT_PROT            0
+#define LWIP_NETCONN                    !NO_SYS
+#define LWIP_SOCKET                     !NO_SYS
+#define LWIP_NETCONN_FULLDUPLEX         LWIP_SOCKET
+#define LWIP_NETBUF_RECVINFO            1
+#define LWIP_HAVE_LOOPIF                1
+#define TCPIP_THREAD_TEST
+
+/* Enable DHCP to test it, disable UDP checksum to easier inject packets */
+#define LWIP_DHCP                       1
+
+/* Minimal changes to opt.h required for tcp unit tests: */
+#define MEM_SIZE                        16000
+#define TCP_SND_QUEUELEN                40
+#define MEMP_NUM_TCP_SEG                TCP_SND_QUEUELEN
+#define TCP_SND_BUF                     (12 * TCP_MSS)
+#define TCP_WND                         (10 * TCP_MSS)
+#define LWIP_WND_SCALE                  1
+#define TCP_RCV_SCALE                   0
+#define PBUF_POOL_SIZE                  400 /* pbuf tests need ~200KByte */
+
+/* Enable IGMP and MDNS for MDNS tests */
+#define LWIP_IGMP                       1
+#define LWIP_MDNS_RESPONDER             1
+#define LWIP_NUM_NETIF_CLIENT_DATA      (LWIP_MDNS_RESPONDER)
+
+/* Minimal changes to opt.h required for etharp unit tests: */
+#define ETHARP_SUPPORT_STATIC_ENTRIES   1
+
+#define MEMP_NUM_SYS_TIMEOUT            (LWIP_NUM_SYS_TIMEOUT_INTERNAL + 8)
+
+/* MIB2 stats are required to check IPv4 reassembly results */
+#define MIB2_STATS                      1
+
+/* netif tests want to test this, so enable: */
+#define LWIP_NETIF_EXT_STATUS_CALLBACK  1
+
+/* Check lwip_stats.mem.illegal instead of asserting */
+#define LWIP_MEM_ILLEGAL_FREE(msg)      /* to nothing */
+
+#endif /* LWIP_HDR_LWIPOPTS_H */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/test/unit/mdns/test_mdns.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/test/unit/mdns/test_mdns.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/test/unit/mdns/test_mdns.c	(revision 457)
@@ -0,0 +1,915 @@
+/*
+ * Copyright (c) 2015 Verisure Innovation AB
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Erik Ekman <erik@kryo.se>
+ *
+ */
+
+#include "test_mdns.h"
+
+#include "lwip/pbuf.h"
+#include "lwip/apps/mdns.h"
+#include "lwip/apps/mdns_priv.h"
+
+START_TEST(readname_basic)
+{
+  static const u8_t data[] = { 0x05, 'm', 'u', 'l', 't', 'i', 0x04, 'c', 'a', 's', 't', 0x00 };
+  struct pbuf *p;
+  struct mdns_domain domain;
+  u16_t offset;
+  LWIP_UNUSED_ARG(_i);
+
+  p = pbuf_alloc(PBUF_RAW, sizeof(data), PBUF_ROM);
+  fail_if(p == NULL);
+  p->payload = (void *)(size_t)data;
+  offset = mdns_readname(p, 0, &domain);
+  pbuf_free(p);
+  fail_unless(offset == sizeof(data));
+  fail_unless(domain.length == sizeof(data));
+  fail_if(memcmp(&domain.name, data, sizeof(data)));
+}
+END_TEST
+
+START_TEST(readname_anydata)
+{
+  static const u8_t data[] = { 0x05, 0x00, 0xFF, 0x08, 0xc0, 0x0f, 0x04, 0x7f, 0x80, 0x82, 0x88, 0x00 };
+  struct pbuf *p;
+  struct mdns_domain domain;
+  u16_t offset;
+  LWIP_UNUSED_ARG(_i);
+
+  p = pbuf_alloc(PBUF_RAW, sizeof(data), PBUF_ROM);
+  fail_if(p == NULL);
+  p->payload = (void *)(size_t)data;
+  offset = mdns_readname(p, 0, &domain);
+  pbuf_free(p);
+  fail_unless(offset == sizeof(data));
+  fail_unless(domain.length == sizeof(data));
+  fail_if(memcmp(&domain.name, data, sizeof(data)));
+}
+END_TEST
+
+START_TEST(readname_short_buf)
+{
+  static const u8_t data[] = { 0x05, 'm', 'u', 'l', 't', 'i', 0x04, 'c', 'a' };
+  struct pbuf *p;
+  struct mdns_domain domain;
+  u16_t offset;
+  LWIP_UNUSED_ARG(_i);
+
+  p = pbuf_alloc(PBUF_RAW, sizeof(data), PBUF_ROM);
+  fail_if(p == NULL);
+  p->payload = (void *)(size_t)data;
+  offset = mdns_readname(p, 0, &domain);
+  pbuf_free(p);
+  fail_unless(offset == MDNS_READNAME_ERROR);
+}
+END_TEST
+
+START_TEST(readname_long_label)
+{
+  static const u8_t data[] = {
+      0x05, 'm', 'u', 'l', 't', 'i',
+      0x52, 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a',
+      'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a',
+      'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a',
+      'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a',
+      'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a',
+      'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 0x00
+  };
+  struct pbuf *p;
+  struct mdns_domain domain;
+  u16_t offset;
+  LWIP_UNUSED_ARG(_i);
+
+  p = pbuf_alloc(PBUF_RAW, sizeof(data), PBUF_ROM);
+  fail_if(p == NULL);
+  p->payload = (void *)(size_t)data;
+  offset = mdns_readname(p, 0, &domain);
+  pbuf_free(p);
+  fail_unless(offset == MDNS_READNAME_ERROR);
+}
+END_TEST
+
+START_TEST(readname_overflow)
+{
+  static const u8_t data[] = {
+      0x05, 'm', 'u', 'l', 't', 'i', 0x04, 'c', 'a', 's', 't',
+      0x05, 'm', 'u', 'l', 't', 'i', 0x04, 'c', 'a', 's', 't',
+      0x05, 'm', 'u', 'l', 't', 'i', 0x04, 'c', 'a', 's', 't',
+      0x05, 'm', 'u', 'l', 't', 'i', 0x04, 'c', 'a', 's', 't',
+      0x05, 'm', 'u', 'l', 't', 'i', 0x04, 'c', 'a', 's', 't',
+      0x05, 'm', 'u', 'l', 't', 'i', 0x04, 'c', 'a', 's', 't',
+      0x05, 'm', 'u', 'l', 't', 'i', 0x04, 'c', 'a', 's', 't',
+      0x05, 'm', 'u', 'l', 't', 'i', 0x04, 'c', 'a', 's', 't',
+      0x05, 'm', 'u', 'l', 't', 'i', 0x04, 'c', 'a', 's', 't',
+      0x05, 'm', 'u', 'l', 't', 'i', 0x04, 'c', 'a', 's', 't',
+      0x05, 'm', 'u', 'l', 't', 'i', 0x04, 'c', 'a', 's', 't',
+      0x05, 'm', 'u', 'l', 't', 'i', 0x04, 'c', 'a', 's', 't',
+      0x05, 'm', 'u', 'l', 't', 'i', 0x04, 'c', 'a', 's', 't',
+      0x05, 'm', 'u', 'l', 't', 'i', 0x04, 'c', 'a', 's', 't',
+      0x05, 'm', 'u', 'l', 't', 'i', 0x04, 'c', 'a', 's', 't',
+      0x05, 'm', 'u', 'l', 't', 'i', 0x04, 'c', 'a', 's', 't',
+      0x05, 'm', 'u', 'l', 't', 'i', 0x04, 'c', 'a', 's', 't',
+      0x05, 'm', 'u', 'l', 't', 'i', 0x04, 'c', 'a', 's', 't',
+      0x05, 'm', 'u', 'l', 't', 'i', 0x04, 'c', 'a', 's', 't',
+      0x05, 'm', 'u', 'l', 't', 'i', 0x04, 'c', 'a', 's', 't',
+      0x05, 'm', 'u', 'l', 't', 'i', 0x04, 'c', 'a', 's', 't',
+      0x05, 'm', 'u', 'l', 't', 'i', 0x04, 'c', 'a', 's', 't',
+      0x05, 'm', 'u', 'l', 't', 'i', 0x04, 'c', 'a', 's', 't',
+      0x05, 'm', 'u', 'l', 't', 'i', 0x04, 'c', 'a', 's', 't',
+      0x05, 'm', 'u', 'l', 't', 'i', 0x04, 'c', 'a', 's', 't',
+      0x05, 'm', 'u', 'l', 't', 'i', 0x04, 'c', 'a', 's', 't',
+      0x05, 'm', 'u', 'l', 't', 'i', 0x04, 'c', 'a', 's', 't',
+      0x05, 'm', 'u', 'l', 't', 'i', 0x04, 'c', 'a', 's', 't',
+      0x05, 'm', 'u', 'l', 't', 'i', 0x04, 'c', 'a', 's', 't',
+      0x05, 'm', 'u', 'l', 't', 'i', 0x04, 'c', 'a', 's', 't',
+      0x05, 'm', 'u', 'l', 't', 'i', 0x04, 'c', 'a', 's', 't',
+      0x05, 'm', 'u', 'l', 't', 'i', 0x04, 'c', 'a', 's', 't',
+      0x05, 'm', 'u', 'l', 't', 'i', 0x04, 'c', 'a', 's', 't',
+      0x05, 'm', 'u', 'l', 't', 'i', 0x04, 'c', 'a', 's', 't',
+      0x05, 'm', 'u', 'l', 't', 'i', 0x04, 'c', 'a', 's', 't',
+      0x05, 'm', 'u', 'l', 't', 'i', 0x04, 'c', 'a', 's', 't',
+      0x05, 'm', 'u', 'l', 't', 'i', 0x04, 'c', 'a', 's', 't',
+      0x00
+  };
+  struct pbuf *p;
+  struct mdns_domain domain;
+  u16_t offset;
+  LWIP_UNUSED_ARG(_i);
+
+  p = pbuf_alloc(PBUF_RAW, sizeof(data), PBUF_ROM);
+  fail_if(p == NULL);
+  p->payload = (void *)(size_t)data;
+  offset = mdns_readname(p, 0, &domain);
+  pbuf_free(p);
+  fail_unless(offset == MDNS_READNAME_ERROR);
+}
+END_TEST
+
+START_TEST(readname_jump_earlier)
+{
+  static const u8_t data[] = {
+      /* Some padding needed, not supported to jump to bytes containing dns header */
+      /*  0 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+      /* 10 */ 0x0f, 0x0e, 0x05, 'l', 'o', 'c', 'a', 'l', 0x00, 0xab,
+      /* 20 */ 0x05, 'm', 'u', 'l', 't', 'i', 0x04, 'c', 'a', 's', 't', 0xc0, 0x0c
+  };
+  static const u8_t fullname[] = {
+      0x05, 'm', 'u', 'l', 't', 'i', 0x04, 'c', 'a', 's', 't', 0x05, 'l', 'o', 'c', 'a', 'l', 0x00
+  };
+  struct pbuf *p;
+  struct mdns_domain domain;
+  u16_t offset;
+  LWIP_UNUSED_ARG(_i);
+
+  p = pbuf_alloc(PBUF_RAW, sizeof(data), PBUF_ROM);
+  fail_if(p == NULL);
+  p->payload = (void *)(size_t)data;
+  offset = mdns_readname(p, 20, &domain);
+  pbuf_free(p);
+  fail_unless(offset == sizeof(data));
+  fail_unless(domain.length == sizeof(fullname));
+
+  fail_if(memcmp(&domain.name, fullname, sizeof(fullname)));
+}
+END_TEST
+
+START_TEST(readname_jump_earlier_jump)
+{
+  static const u8_t data[] = {
+      /* Some padding needed, not supported to jump to bytes containing dns header */
+      /* 0x00 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+      /* 0x08 */ 0x00, 0x00, 0x00, 0x00, 0x03, 0x0b, 0x0a, 0xf2,
+      /* 0x10 */ 0x04, 'c', 'a', 's', 't', 0x00, 0xc0, 0x10,
+      /* 0x18 */ 0x05, 'm', 'u', 'l', 't', 'i', 0xc0, 0x16
+  };
+  static const u8_t fullname[] = {
+      0x05, 'm', 'u', 'l', 't', 'i', 0x04, 'c', 'a', 's', 't', 0x00
+  };
+  struct pbuf *p;
+  struct mdns_domain domain;
+  u16_t offset;
+  LWIP_UNUSED_ARG(_i);
+
+  p = pbuf_alloc(PBUF_RAW, sizeof(data), PBUF_ROM);
+  fail_if(p == NULL);
+  p->payload = (void *)(size_t)data;
+  offset = mdns_readname(p, 0x18, &domain);
+  pbuf_free(p);
+  fail_unless(offset == sizeof(data));
+  fail_unless(domain.length == sizeof(fullname));
+
+  fail_if(memcmp(&domain.name, fullname, sizeof(fullname)));
+}
+END_TEST
+
+START_TEST(readname_jump_maxdepth)
+{
+  static const u8_t data[] = {
+      /* Some padding needed, not supported to jump to bytes containing dns header */
+      /* 0x00 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+      /* 0x08 */ 0x00, 0x00, 0x00, 0x00, 0x03, 0x0b, 0x0a, 0xf2,
+      /* 0x10 */ 0x04, 'n', 'a', 'm', 'e', 0xc0, 0x27, 0x03,
+      /* 0x18 */ 0x03, 'd', 'n', 's', 0xc0, 0x10, 0xc0, 0x10,
+      /* 0x20 */ 0x04, 'd', 'e', 'e', 'p', 0xc0, 0x18, 0x00,
+      /* 0x28 */ 0x04, 'c', 'a', 's', 't', 0xc0, 0x20, 0xb0,
+      /* 0x30 */ 0x05, 'm', 'u', 'l', 't', 'i', 0xc0, 0x28
+  };
+  static const u8_t fullname[] = {
+      0x05, 'm', 'u', 'l', 't', 'i', 0x04, 'c', 'a', 's', 't',
+      0x04, 'd', 'e', 'e', 'p', 0x03, 'd', 'n', 's',
+      0x04, 'n', 'a', 'm', 'e', 0x00
+  };
+  struct pbuf *p;
+  struct mdns_domain domain;
+  u16_t offset;
+  LWIP_UNUSED_ARG(_i);
+
+  p = pbuf_alloc(PBUF_RAW, sizeof(data), PBUF_ROM);
+  fail_if(p == NULL);
+  p->payload = (void *)(size_t)data;
+  offset = mdns_readname(p, 0x30, &domain);
+  pbuf_free(p);
+  fail_unless(offset == sizeof(data));
+  fail_unless(domain.length == sizeof(fullname));
+
+  fail_if(memcmp(&domain.name, fullname, sizeof(fullname)));
+}
+END_TEST
+
+START_TEST(readname_jump_later)
+{
+  static const u8_t data[] = {
+      /* 0x00 */ 0x05, 'm', 'u', 'l', 't', 'i', 0x04, 'c', 'a', 's', 't', 0xc0, 0x10, 0x00, 0x01, 0x40,
+      /* 0x10 */ 0x05, 'l', 'o', 'c', 'a', 'l', 0x00, 0xab
+  };
+  static const u8_t fullname[] = {
+      0x05, 'm', 'u', 'l', 't', 'i', 0x04, 'c', 'a', 's', 't', 0x05, 'l', 'o', 'c', 'a', 'l', 0x00
+  };
+  struct pbuf *p;
+  struct mdns_domain domain;
+  u16_t offset;
+  LWIP_UNUSED_ARG(_i);
+
+  p = pbuf_alloc(PBUF_RAW, sizeof(data), PBUF_ROM);
+  fail_if(p == NULL);
+  p->payload = (void *)(size_t)data;
+  offset = mdns_readname(p, 0, &domain);
+  pbuf_free(p);
+  fail_unless(offset == 13);
+  fail_unless(domain.length == sizeof(fullname));
+
+  fail_if(memcmp(&domain.name, fullname, sizeof(fullname)));
+}
+END_TEST
+
+START_TEST(readname_half_jump)
+{
+  static const u8_t data[] = {
+      0x05, 'm', 'u', 'l', 't', 'i', 0x04, 'c', 'a', 's', 't', 0xc0
+  };
+  struct pbuf *p;
+  struct mdns_domain domain;
+  u16_t offset;
+  LWIP_UNUSED_ARG(_i);
+
+  p = pbuf_alloc(PBUF_RAW, sizeof(data), PBUF_ROM);
+  fail_if(p == NULL);
+  p->payload = (void *)(size_t)data;
+  offset = mdns_readname(p, 0, &domain);
+  pbuf_free(p);
+  fail_unless(offset == MDNS_READNAME_ERROR);
+}
+END_TEST
+
+START_TEST(readname_jump_toolong)
+{
+  static const u8_t data[] = {
+      0x05, 'm', 'u', 'l', 't', 'i', 0x04, 'c', 'a', 's', 't', 0xc2, 0x10, 0x00, 0x01, 0x40
+  };
+  struct pbuf *p;
+  struct mdns_domain domain;
+  u16_t offset;
+  LWIP_UNUSED_ARG(_i);
+
+  p = pbuf_alloc(PBUF_RAW, sizeof(data), PBUF_ROM);
+  fail_if(p == NULL);
+  p->payload = (void *)(size_t)data;
+  offset = mdns_readname(p, 0, &domain);
+  pbuf_free(p);
+  fail_unless(offset == MDNS_READNAME_ERROR);
+}
+END_TEST
+
+START_TEST(readname_jump_loop_label)
+{
+  static const u8_t data[] = {
+      /*  0 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+      /* 10 */ 0x05, 'm', 'u', 'l', 't', 'i', 0x04, 'c', 'a', 's', 't', 0xc0, 0x10
+  };
+  struct pbuf *p;
+  struct mdns_domain domain;
+  u16_t offset;
+  LWIP_UNUSED_ARG(_i);
+
+  p = pbuf_alloc(PBUF_RAW, sizeof(data), PBUF_ROM);
+  fail_if(p == NULL);
+  p->payload = (void *)(size_t)data;
+  offset = mdns_readname(p, 10, &domain);
+  pbuf_free(p);
+  fail_unless(offset == MDNS_READNAME_ERROR);
+}
+END_TEST
+
+START_TEST(readname_jump_loop_jump)
+{
+  static const u8_t data[] = {
+      /*  0 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+      /* 10 */ 0x05, 'm', 'u', 'l', 't', 'i', 0x04, 'c', 'a', 's', 't', 0xc0, 0x15
+  };
+  struct pbuf *p;
+  struct mdns_domain domain;
+  u16_t offset;
+  LWIP_UNUSED_ARG(_i);
+
+  p = pbuf_alloc(PBUF_RAW, sizeof(data), PBUF_ROM);
+  fail_if(p == NULL);
+  p->payload = (void *)(size_t)data;
+  offset = mdns_readname(p, 10, &domain);
+  pbuf_free(p);
+  fail_unless(offset == MDNS_READNAME_ERROR);
+}
+END_TEST
+
+START_TEST(add_label_basic)
+{
+  static const u8_t data[] = { 0x05, 'm', 'u', 'l', 't', 'i', 0x04, 'c', 'a', 's', 't', 0x00 };
+  struct mdns_domain domain;
+  err_t res;
+  LWIP_UNUSED_ARG(_i);
+
+  memset(&domain, 0, sizeof(domain));
+  res = mdns_domain_add_label(&domain, "multi", 5);
+  fail_unless(res == ERR_OK);
+  res = mdns_domain_add_label(&domain, "cast", 4);
+  fail_unless(res == ERR_OK);
+  res = mdns_domain_add_label(&domain, NULL, 0);
+  fail_unless(res == ERR_OK);
+  fail_unless(domain.length == sizeof(data));
+  fail_if(memcmp(&domain.name, data, sizeof(data)));
+}
+END_TEST
+
+START_TEST(add_label_long_label)
+{
+  static const char *toolong = "abcdefghijklmnopqrstuvwxyz0123456789-abcdefghijklmnopqrstuvwxyz0123456789-abcdefghijklmnopqrstuvwxyz0123456789-";
+  struct mdns_domain domain;
+  err_t res;
+  LWIP_UNUSED_ARG(_i);
+
+  memset(&domain, 0, sizeof(domain));
+  res = mdns_domain_add_label(&domain, "multi", 5);
+  fail_unless(res == ERR_OK);
+  res = mdns_domain_add_label(&domain, toolong, (u8_t)strlen(toolong));
+  fail_unless(res == ERR_VAL);
+}
+END_TEST
+
+START_TEST(add_label_full)
+{
+  static const char *label = "0123456789abcdef0123456789abcdef";
+  struct mdns_domain domain;
+  err_t res;
+  LWIP_UNUSED_ARG(_i);
+
+  memset(&domain, 0, sizeof(domain));
+  res = mdns_domain_add_label(&domain, label, (u8_t)strlen(label));
+  fail_unless(res == ERR_OK);
+  fail_unless(domain.length == 33);
+  res = mdns_domain_add_label(&domain, label, (u8_t)strlen(label));
+  fail_unless(res == ERR_OK);
+  fail_unless(domain.length == 66);
+  res = mdns_domain_add_label(&domain, label, (u8_t)strlen(label));
+  fail_unless(res == ERR_OK);
+  fail_unless(domain.length == 99);
+  res = mdns_domain_add_label(&domain, label, (u8_t)strlen(label));
+  fail_unless(res == ERR_OK);
+  fail_unless(domain.length == 132);
+  res = mdns_domain_add_label(&domain, label, (u8_t)strlen(label));
+  fail_unless(res == ERR_OK);
+  fail_unless(domain.length == 165);
+  res = mdns_domain_add_label(&domain, label, (u8_t)strlen(label));
+  fail_unless(res == ERR_OK);
+  fail_unless(domain.length == 198);
+  res = mdns_domain_add_label(&domain, label, (u8_t)strlen(label));
+  fail_unless(res == ERR_OK);
+  fail_unless(domain.length == 231);
+  res = mdns_domain_add_label(&domain, label, (u8_t)strlen(label));
+  fail_unless(res == ERR_VAL);
+  fail_unless(domain.length == 231);
+  res = mdns_domain_add_label(&domain, label, 25);
+  fail_unless(res == ERR_VAL);
+  fail_unless(domain.length == 231);
+  res = mdns_domain_add_label(&domain, label, 24);
+  fail_unless(res == ERR_VAL);
+  fail_unless(domain.length == 231);
+  res = mdns_domain_add_label(&domain, label, 23);
+  fail_unless(res == ERR_OK);
+  fail_unless(domain.length == 255);
+  res = mdns_domain_add_label(&domain, NULL, 0);
+  fail_unless(res == ERR_OK);
+  fail_unless(domain.length == 256);
+  res = mdns_domain_add_label(&domain, NULL, 0);
+  fail_unless(res == ERR_VAL);
+  fail_unless(domain.length == 256);
+}
+END_TEST
+
+START_TEST(domain_eq_basic)
+{
+  static const u8_t data[] = {
+      0x05, 'm', 'u', 'l', 't', 'i', 0x04, 'c', 'a', 's', 't', 0x00
+  };
+  struct mdns_domain domain1, domain2;
+  err_t res;
+  LWIP_UNUSED_ARG(_i);
+
+  memset(&domain1, 0, sizeof(domain1));
+  res = mdns_domain_add_label(&domain1, "multi", 5);
+  fail_unless(res == ERR_OK);
+  res = mdns_domain_add_label(&domain1, "cast", 4);
+  fail_unless(res == ERR_OK);
+  res = mdns_domain_add_label(&domain1, NULL, 0);
+  fail_unless(res == ERR_OK);
+  fail_unless(domain1.length == sizeof(data));
+
+  memset(&domain2, 0, sizeof(domain2));
+  res = mdns_domain_add_label(&domain2, "multi", 5);
+  fail_unless(res == ERR_OK);
+  res = mdns_domain_add_label(&domain2, "cast", 4);
+  fail_unless(res == ERR_OK);
+  res = mdns_domain_add_label(&domain2, NULL, 0);
+  fail_unless(res == ERR_OK);
+
+  fail_unless(mdns_domain_eq(&domain1, &domain2));
+}
+END_TEST
+
+START_TEST(domain_eq_diff)
+{
+  struct mdns_domain domain1, domain2;
+  err_t res;
+  LWIP_UNUSED_ARG(_i);
+
+  memset(&domain1, 0, sizeof(domain1));
+  res = mdns_domain_add_label(&domain1, "multi", 5);
+  fail_unless(res == ERR_OK);
+  res = mdns_domain_add_label(&domain1, "base", 4);
+  fail_unless(res == ERR_OK);
+  res = mdns_domain_add_label(&domain1, NULL, 0);
+  fail_unless(res == ERR_OK);
+
+  memset(&domain2, 0, sizeof(domain2));
+  res = mdns_domain_add_label(&domain2, "multi", 5);
+  fail_unless(res == ERR_OK);
+  res = mdns_domain_add_label(&domain2, "cast", 4);
+  fail_unless(res == ERR_OK);
+  res = mdns_domain_add_label(&domain2, NULL, 0);
+  fail_unless(res == ERR_OK);
+
+  fail_if(mdns_domain_eq(&domain1, &domain2));
+}
+END_TEST
+
+START_TEST(domain_eq_case)
+{
+  struct mdns_domain domain1, domain2;
+  err_t res;
+  LWIP_UNUSED_ARG(_i);
+
+  memset(&domain1, 0, sizeof(domain1));
+  res = mdns_domain_add_label(&domain1, "multi", 5);
+  fail_unless(res == ERR_OK);
+  res = mdns_domain_add_label(&domain1, "cast", 4);
+  fail_unless(res == ERR_OK);
+  res = mdns_domain_add_label(&domain1, NULL, 0);
+  fail_unless(res == ERR_OK);
+
+  memset(&domain2, 0, sizeof(domain2));
+  res = mdns_domain_add_label(&domain2, "MulTI", 5);
+  fail_unless(res == ERR_OK);
+  res = mdns_domain_add_label(&domain2, "casT", 4);
+  fail_unless(res == ERR_OK);
+  res = mdns_domain_add_label(&domain2, NULL, 0);
+  fail_unless(res == ERR_OK);
+
+  fail_unless(mdns_domain_eq(&domain1, &domain2));
+}
+END_TEST
+
+START_TEST(domain_eq_anydata)
+{
+  static const u8_t data1[] = { 0x05, 0xcc, 0xdc, 0x00, 0xa0 };
+  static const u8_t data2[] = { 0x7f, 0x8c, 0x01, 0xff, 0xcf };
+  struct mdns_domain domain1, domain2;
+  err_t res;
+  LWIP_UNUSED_ARG(_i);
+
+  memset(&domain1, 0, sizeof(domain1));
+  res = mdns_domain_add_label(&domain1, (const char*)data1, sizeof(data1));
+  fail_unless(res == ERR_OK);
+  res = mdns_domain_add_label(&domain1, "cast", 4);
+  fail_unless(res == ERR_OK);
+  res = mdns_domain_add_label(&domain1, (const char*)data2, sizeof(data2));
+  fail_unless(res == ERR_OK);
+  res = mdns_domain_add_label(&domain1, NULL, 0);
+  fail_unless(res == ERR_OK);
+
+  memset(&domain2, 0, sizeof(domain2));
+  res = mdns_domain_add_label(&domain2, (const char*)data1, sizeof(data1));
+  fail_unless(res == ERR_OK);
+  res = mdns_domain_add_label(&domain2, "casT", 4);
+  fail_unless(res == ERR_OK);
+  res = mdns_domain_add_label(&domain2, (const char*)data2, sizeof(data2));
+  fail_unless(res == ERR_OK);
+  res = mdns_domain_add_label(&domain2, NULL, 0);
+  fail_unless(res == ERR_OK);
+
+  fail_unless(mdns_domain_eq(&domain1, &domain2));
+}
+END_TEST
+
+START_TEST(domain_eq_length)
+{
+  struct mdns_domain domain1, domain2;
+  err_t res;
+  LWIP_UNUSED_ARG(_i);
+
+  memset(&domain1, 0, sizeof(domain1));
+  memset(domain1.name, 0xAA, sizeof(MDNS_DOMAIN_MAXLEN));
+  res = mdns_domain_add_label(&domain1, "multi", 5);
+  fail_unless(res == ERR_OK);
+  res = mdns_domain_add_label(&domain1, "cast", 4);
+  fail_unless(res == ERR_OK);
+
+  memset(&domain2, 0, sizeof(domain2));
+  memset(domain2.name, 0xBB, sizeof(MDNS_DOMAIN_MAXLEN));
+  res = mdns_domain_add_label(&domain2, "multi", 5);
+  fail_unless(res == ERR_OK);
+  res = mdns_domain_add_label(&domain2, "cast", 4);
+  fail_unless(res == ERR_OK);
+
+  fail_unless(mdns_domain_eq(&domain1, &domain2));
+}
+END_TEST
+
+START_TEST(compress_full_match)
+{
+  static const u8_t data[] = {
+      0x00, 0x00,
+      0x06, 'f', 'o', 'o', 'b', 'a', 'r', 0x05, 'l', 'o', 'c', 'a', 'l', 0x00
+  };
+  struct pbuf *p;
+  struct mdns_domain domain;
+  u16_t offset;
+  u16_t length;
+  err_t res;
+  LWIP_UNUSED_ARG(_i);
+
+  p = pbuf_alloc(PBUF_RAW, sizeof(data), PBUF_ROM);
+  fail_if(p == NULL);
+  p->payload = (void *)(size_t)data;
+
+  memset(&domain, 0, sizeof(domain));
+  res = mdns_domain_add_label(&domain, "foobar", 6);
+  fail_unless(res == ERR_OK);
+  res = mdns_domain_add_label(&domain, "local", 5);
+  fail_unless(res == ERR_OK);
+  res = mdns_domain_add_label(&domain, NULL, 0);
+  fail_unless(res == ERR_OK);
+
+  offset = 2;
+  length = mdns_compress_domain(p, &offset, &domain);
+  /* Write 0 bytes, then a jump to addr 2 */
+  fail_unless(length == 0);
+  fail_unless(offset == 2);
+
+  pbuf_free(p);
+}
+END_TEST
+
+START_TEST(compress_full_match_subset)
+{
+  static const u8_t data[] = {
+      0x00, 0x00,
+      0x02, 'g', 'o', 0x06, 'f', 'o', 'o', 'b', 'a', 'r', 0x05, 'l', 'o', 'c', 'a', 'l', 0x00
+  };
+  struct pbuf *p;
+  struct mdns_domain domain;
+  u16_t offset;
+  u16_t length;
+  err_t res;
+  LWIP_UNUSED_ARG(_i);
+
+  p = pbuf_alloc(PBUF_RAW, sizeof(data), PBUF_ROM);
+  fail_if(p == NULL);
+  p->payload = (void *)(size_t)data;
+
+  memset(&domain, 0, sizeof(domain));
+  res = mdns_domain_add_label(&domain, "foobar", 6);
+  fail_unless(res == ERR_OK);
+  res = mdns_domain_add_label(&domain, "local", 5);
+  fail_unless(res == ERR_OK);
+  res = mdns_domain_add_label(&domain, NULL, 0);
+  fail_unless(res == ERR_OK);
+
+  offset = 2;
+  length = mdns_compress_domain(p, &offset, &domain);
+  /* Write 0 bytes, then a jump to addr 5 */
+  fail_unless(length == 0);
+  fail_unless(offset == 5);
+
+  pbuf_free(p);
+}
+END_TEST
+
+START_TEST(compress_full_match_jump)
+{
+  static const u8_t data[] = {
+    /* 0x00 */ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+               0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
+    /* 0x10 */ 0x04, 'l', 'w', 'i', 'p', 0x05, 'l', 'o', 'c', 'a', 'l', 0x00, 0xc0, 0x00, 0x02, 0x00,
+    /* 0x20 */ 0x06, 'f', 'o', 'o', 'b', 'a', 'r', 0xc0, 0x15
+  };
+  struct pbuf *p;
+  struct mdns_domain domain;
+  u16_t offset;
+  u16_t length;
+  err_t res;
+  LWIP_UNUSED_ARG(_i);
+
+  p = pbuf_alloc(PBUF_RAW, sizeof(data), PBUF_ROM);
+  fail_if(p == NULL);
+  p->payload = (void *)(size_t)data;
+
+  memset(&domain, 0, sizeof(domain));
+  res = mdns_domain_add_label(&domain, "foobar", 6);
+  fail_unless(res == ERR_OK);
+  res = mdns_domain_add_label(&domain, "local", 5);
+  fail_unless(res == ERR_OK);
+  res = mdns_domain_add_label(&domain, NULL, 0);
+  fail_unless(res == ERR_OK);
+
+  offset = 0x20;
+  length = mdns_compress_domain(p, &offset, &domain);
+  /* Write 0 bytes, then a jump to addr 0x20 */
+  fail_unless(length == 0);
+  fail_unless(offset == 0x20);
+
+  pbuf_free(p);
+}
+END_TEST
+
+START_TEST(compress_no_match)
+{
+  static const u8_t data[] = {
+      0x00, 0x00,
+      0x04, 'l', 'w', 'i', 'p', 0x05, 'w', 'i', 'k', 'i', 'a', 0x03, 'c', 'o', 'm', 0x00
+  };
+  struct pbuf *p;
+  struct mdns_domain domain;
+  u16_t offset;
+  u16_t length;
+  err_t res;
+  LWIP_UNUSED_ARG(_i);
+
+  p = pbuf_alloc(PBUF_RAW, sizeof(data), PBUF_ROM);
+  fail_if(p == NULL);
+  p->payload = (void *)(size_t)data;
+
+  memset(&domain, 0, sizeof(domain));
+  res = mdns_domain_add_label(&domain, "foobar", 6);
+  fail_unless(res == ERR_OK);
+  res = mdns_domain_add_label(&domain, "local", 5);
+  fail_unless(res == ERR_OK);
+  res = mdns_domain_add_label(&domain, NULL, 0);
+  fail_unless(res == ERR_OK);
+
+  offset = 2;
+  length = mdns_compress_domain(p, &offset, &domain);
+  /* Write all bytes, no jump */
+  fail_unless(length == domain.length);
+
+  pbuf_free(p);
+}
+END_TEST
+
+START_TEST(compress_2nd_label)
+{
+  static const u8_t data[] = {
+      0x00, 0x00,
+      0x06, 'f', 'o', 'o', 'b', 'a', 'r', 0x05, 'l', 'o', 'c', 'a', 'l', 0x00
+  };
+  struct pbuf *p;
+  struct mdns_domain domain;
+  u16_t offset;
+  u16_t length;
+  err_t res;
+  LWIP_UNUSED_ARG(_i);
+
+  p = pbuf_alloc(PBUF_RAW, sizeof(data), PBUF_ROM);
+  fail_if(p == NULL);
+  p->payload = (void *)(size_t)data;
+
+  memset(&domain, 0, sizeof(domain));
+  res = mdns_domain_add_label(&domain, "lwip", 4);
+  fail_unless(res == ERR_OK);
+  res = mdns_domain_add_label(&domain, "local", 5);
+  fail_unless(res == ERR_OK);
+  res = mdns_domain_add_label(&domain, NULL, 0);
+  fail_unless(res == ERR_OK);
+
+  offset = 2;
+  length = mdns_compress_domain(p, &offset, &domain);
+  /* Write 5 bytes, then a jump to addr 9 */
+  fail_unless(length == 5);
+  fail_unless(offset == 9);
+
+  pbuf_free(p);
+}
+END_TEST
+
+START_TEST(compress_2nd_label_short)
+{
+  static const u8_t data[] = {
+      0x00, 0x00,
+      0x04, 'l', 'w', 'i', 'p', 0x05, 'l', 'o', 'c', 'a', 'l', 0x00
+  };
+  struct pbuf *p;
+  struct mdns_domain domain;
+  u16_t offset;
+  u16_t length;
+  err_t res;
+  LWIP_UNUSED_ARG(_i);
+
+  p = pbuf_alloc(PBUF_RAW, sizeof(data), PBUF_ROM);
+  fail_if(p == NULL);
+  p->payload = (void *)(size_t)data;
+
+  memset(&domain, 0, sizeof(domain));
+  res = mdns_domain_add_label(&domain, "foobar", 6);
+  fail_unless(res == ERR_OK);
+  res = mdns_domain_add_label(&domain, "local", 5);
+  fail_unless(res == ERR_OK);
+  res = mdns_domain_add_label(&domain, NULL, 0);
+  fail_unless(res == ERR_OK);
+
+  offset = 2;
+  length = mdns_compress_domain(p, &offset, &domain);
+  /* Write 5 bytes, then a jump to addr 7 */
+  fail_unless(length == 7);
+  fail_unless(offset == 7);
+
+  pbuf_free(p);
+}
+END_TEST
+
+START_TEST(compress_jump_to_jump)
+{
+  static const u8_t data[] = {
+      /* 0x00 */ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+                 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
+      /* 0x10 */ 0x04, 'l', 'w', 'i', 'p', 0x05, 'l', 'o', 'c', 'a', 'l', 0x00, 0xc0, 0x00, 0x02, 0x00,
+      /* 0x20 */ 0x07, 'b', 'a', 'n', 'a', 'n', 'a', 's', 0xc0, 0x15
+  };
+  struct pbuf *p;
+  struct mdns_domain domain;
+  u16_t offset;
+  u16_t length;
+  err_t res;
+  LWIP_UNUSED_ARG(_i);
+
+  p = pbuf_alloc(PBUF_RAW, sizeof(data), PBUF_ROM);
+  fail_if(p == NULL);
+  p->payload = (void *)(size_t)data;
+
+  memset(&domain, 0, sizeof(domain));
+  res = mdns_domain_add_label(&domain, "foobar", 6);
+  fail_unless(res == ERR_OK);
+  res = mdns_domain_add_label(&domain, "local", 5);
+  fail_unless(res == ERR_OK);
+  res = mdns_domain_add_label(&domain, NULL, 0);
+  fail_unless(res == ERR_OK);
+
+  offset = 0x20;
+  length = mdns_compress_domain(p, &offset, &domain);
+  /* Dont compress if jump would be to a jump */
+  fail_unless(length == domain.length);
+
+  offset = 0x10;
+  length = mdns_compress_domain(p, &offset, &domain);
+  /* Write 7 bytes, then a jump to addr 0x15 */
+  fail_unless(length == 7);
+  fail_unless(offset == 0x15);
+
+  pbuf_free(p);
+}
+END_TEST
+
+START_TEST(compress_long_match)
+{
+  static const u8_t data[] = {
+      0x00, 0x00,
+      0x06, 'f', 'o', 'o', 'b', 'a', 'r', 0x05, 'l', 'o', 'c', 'a', 'l', 0x03, 'c', 'o', 'm', 0x00
+  };
+  struct pbuf *p;
+  struct mdns_domain domain;
+  u16_t offset;
+  u16_t length;
+  err_t res;
+  LWIP_UNUSED_ARG(_i);
+
+  p = pbuf_alloc(PBUF_RAW, sizeof(data), PBUF_ROM);
+  fail_if(p == NULL);
+  p->payload = (void *)(size_t)data;
+
+  memset(&domain, 0, sizeof(domain));
+  res = mdns_domain_add_label(&domain, "foobar", 6);
+  fail_unless(res == ERR_OK);
+  res = mdns_domain_add_label(&domain, "local", 5);
+  fail_unless(res == ERR_OK);
+  res = mdns_domain_add_label(&domain, NULL, 0);
+  fail_unless(res == ERR_OK);
+
+  offset = 2;
+  length = mdns_compress_domain(p, &offset, &domain);
+  fail_unless(length == domain.length);
+
+  pbuf_free(p);
+}
+END_TEST
+
+Suite* mdns_suite(void)
+{
+  testfunc tests[] = {
+    TESTFUNC(readname_basic),
+    TESTFUNC(readname_anydata),
+    TESTFUNC(readname_short_buf),
+    TESTFUNC(readname_long_label),
+    TESTFUNC(readname_overflow),
+    TESTFUNC(readname_jump_earlier),
+    TESTFUNC(readname_jump_earlier_jump),
+    TESTFUNC(readname_jump_maxdepth),
+    TESTFUNC(readname_jump_later),
+    TESTFUNC(readname_half_jump),
+    TESTFUNC(readname_jump_toolong),
+    TESTFUNC(readname_jump_loop_label),
+    TESTFUNC(readname_jump_loop_jump),
+
+    TESTFUNC(add_label_basic),
+    TESTFUNC(add_label_long_label),
+    TESTFUNC(add_label_full),
+
+    TESTFUNC(domain_eq_basic),
+    TESTFUNC(domain_eq_diff),
+    TESTFUNC(domain_eq_case),
+    TESTFUNC(domain_eq_anydata),
+    TESTFUNC(domain_eq_length),
+
+    TESTFUNC(compress_full_match),
+    TESTFUNC(compress_full_match_subset),
+    TESTFUNC(compress_full_match_jump),
+    TESTFUNC(compress_no_match),
+    TESTFUNC(compress_2nd_label),
+    TESTFUNC(compress_2nd_label_short),
+    TESTFUNC(compress_jump_to_jump),
+    TESTFUNC(compress_long_match),
+  };
+  return create_suite("MDNS", tests, sizeof(tests)/sizeof(testfunc), NULL, NULL);
+}
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/test/unit/mdns/test_mdns.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/test/unit/mdns/test_mdns.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/test/unit/mdns/test_mdns.h	(revision 457)
@@ -0,0 +1,8 @@
+#ifndef LWIP_HDR_TEST_MDNS_H__
+#define LWIP_HDR_TEST_MDNS_H__
+
+#include "../lwip_check.h"
+
+Suite* mdns_suite(void);
+
+#endif
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/test/unit/mqtt/test_mqtt.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/test/unit/mqtt/test_mqtt.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/test/unit/mqtt/test_mqtt.c	(revision 457)
@@ -0,0 +1,115 @@
+#include "test_mqtt.h"
+
+#include "lwip/pbuf.h"
+#include "lwip/apps/mqtt.h"
+#include "lwip/apps/mqtt_priv.h"
+#include "lwip/netif.h"
+
+const ip_addr_t test_mqtt_local_ip = IPADDR4_INIT_BYTES(192, 168, 1, 1);
+const ip_addr_t test_mqtt_remote_ip = IPADDR4_INIT_BYTES(192, 168, 1, 2);
+const ip_addr_t test_mqtt_netmask = IPADDR4_INIT_BYTES(255, 255, 255, 0);
+
+static err_t test_mqtt_netif_output(struct netif *netif, struct pbuf *p,
+       const ip4_addr_t *ipaddr)
+{
+  LWIP_UNUSED_ARG(netif);
+  LWIP_UNUSED_ARG(ipaddr);
+  LWIP_UNUSED_ARG(p);
+  return ERR_OK;
+}
+
+static void
+test_mqtt_init_netif(struct netif *netif, const ip_addr_t *ip_addr, const ip_addr_t *netmask)
+{
+  struct netif *n;
+  memset(netif, 0, sizeof(struct netif));
+  netif->output = test_mqtt_netif_output;
+  netif->flags |= NETIF_FLAG_UP | NETIF_FLAG_LINK_UP;
+  ip_addr_copy_from_ip4(netif->netmask, *ip_2_ip4(netmask));
+  ip_addr_copy_from_ip4(netif->ip_addr, *ip_2_ip4(ip_addr));
+  for (n = netif_list; n != NULL; n = n->next) {
+    if (n == netif) {
+      return;
+    }
+  }
+  netif->next = NULL;
+  netif_list = netif;
+}
+
+/* Setups/teardown functions */
+static struct netif *old_netif_list;
+static struct netif *old_netif_default;
+
+static void
+mqtt_setup(void)
+{
+  old_netif_list = netif_list;
+  old_netif_default = netif_default;
+  netif_list = NULL;
+  netif_default = NULL;
+  lwip_check_ensure_no_alloc(SKIP_POOL(MEMP_SYS_TIMEOUT));
+}
+
+static void
+mqtt_teardown(void)
+{
+  netif_list = NULL;
+  netif_default = NULL;
+  /* restore netif_list for next tests (e.g. loopif) */
+  netif_list = old_netif_list;
+  netif_default = old_netif_default;
+  lwip_check_ensure_no_alloc(SKIP_POOL(MEMP_SYS_TIMEOUT));
+}
+
+static void test_mqtt_connection_cb(mqtt_client_t *client, void *arg, mqtt_connection_status_t status)
+{
+  LWIP_UNUSED_ARG(client);
+  LWIP_UNUSED_ARG(arg);
+  LWIP_UNUSED_ARG(status);
+}
+
+START_TEST(basic_connect)
+{
+  mqtt_client_t* client;
+  struct netif netif;
+  err_t err;
+  struct mqtt_connect_client_info_t client_info = {
+    "dumm",
+    NULL, NULL,
+    10,
+    NULL, NULL, 0, 0
+  };
+  struct pbuf *p;
+  unsigned char rxbuf[] = {0x20, 0x02, 0x00, 0x00};
+  LWIP_UNUSED_ARG(_i);
+
+  test_mqtt_init_netif(&netif, &test_mqtt_local_ip, &test_mqtt_netmask);
+
+  client = mqtt_client_new();
+  fail_unless(client != NULL);
+  err = mqtt_client_connect(client, &test_mqtt_remote_ip, 1234, test_mqtt_connection_cb, NULL, &client_info);
+  fail_unless(err == ERR_OK);
+
+  client->conn->connected(client->conn->callback_arg, client->conn, ERR_OK);
+  p = pbuf_alloc(PBUF_RAW, sizeof(rxbuf), PBUF_REF);
+  fail_unless(p != NULL);
+  p->payload = rxbuf;
+  /* since we hack the rx path, we have to hack the rx window, too: */
+  client->conn->rcv_wnd -= p->tot_len;
+  if (client->conn->recv(client->conn->callback_arg, client->conn, p, ERR_OK) != ERR_OK) {
+    pbuf_free(p);
+  }
+
+  mqtt_disconnect(client);
+  /* fixme: mqtt_client_fre() is missing... */
+  mem_free(client);
+}
+END_TEST
+
+Suite* mqtt_suite(void)
+{
+  testfunc tests[] = {
+    TESTFUNC(basic_connect),
+  };
+  return create_suite("MQTT", tests, sizeof(tests)/sizeof(testfunc), mqtt_setup, mqtt_teardown);
+}
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/test/unit/mqtt/test_mqtt.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/test/unit/mqtt/test_mqtt.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/test/unit/mqtt/test_mqtt.h	(revision 457)
@@ -0,0 +1,8 @@
+#ifndef LWIP_HDR_TEST_MQTT_H__
+#define LWIP_HDR_TEST_MQTT_H__
+
+#include "../lwip_check.h"
+
+Suite* mqtt_suite(void);
+
+#endif
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/test/unit/tcp/tcp_helper.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/test/unit/tcp/tcp_helper.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/test/unit/tcp/tcp_helper.c	(revision 457)
@@ -0,0 +1,319 @@
+#include "tcp_helper.h"
+
+#include "lwip/priv/tcp_priv.h"
+#include "lwip/stats.h"
+#include "lwip/pbuf.h"
+#include "lwip/inet_chksum.h"
+#include "lwip/ip_addr.h"
+
+#if !LWIP_STATS || !TCP_STATS || !MEMP_STATS
+#error "This tests needs TCP- and MEMP-statistics enabled"
+#endif
+
+const ip_addr_t test_local_ip = IPADDR4_INIT_BYTES(192, 168, 1, 1);
+const ip_addr_t test_remote_ip = IPADDR4_INIT_BYTES(192, 168, 1, 2);
+const ip_addr_t test_netmask = IPADDR4_INIT_BYTES(255, 255, 255, 0);
+
+/** Remove all pcbs on the given list. */
+static void
+tcp_remove(struct tcp_pcb* pcb_list)
+{
+  struct tcp_pcb *pcb = pcb_list;
+  struct tcp_pcb *pcb2;
+
+  while(pcb != NULL) {
+    pcb2 = pcb;
+    pcb = pcb->next;
+    tcp_abort(pcb2);
+  }
+}
+
+/** Remove all pcbs on listen-, active- and time-wait-list (bound- isn't exported). */
+void
+tcp_remove_all(void)
+{
+  tcp_remove(tcp_listen_pcbs.pcbs);
+  tcp_remove(tcp_bound_pcbs);
+  tcp_remove(tcp_active_pcbs);
+  tcp_remove(tcp_tw_pcbs);
+  fail_unless(MEMP_STATS_GET(used, MEMP_TCP_PCB) == 0);
+  fail_unless(MEMP_STATS_GET(used, MEMP_TCP_PCB_LISTEN) == 0);
+  fail_unless(MEMP_STATS_GET(used, MEMP_TCP_SEG) == 0);
+  fail_unless(MEMP_STATS_GET(used, MEMP_PBUF_POOL) == 0);
+}
+
+/** Create a TCP segment usable for passing to tcp_input */
+static struct pbuf*
+tcp_create_segment_wnd(ip_addr_t* src_ip, ip_addr_t* dst_ip,
+                   u16_t src_port, u16_t dst_port, void* data, size_t data_len,
+                   u32_t seqno, u32_t ackno, u8_t headerflags, u16_t wnd)
+{
+  struct pbuf *p, *q;
+  struct ip_hdr* iphdr;
+  struct tcp_hdr* tcphdr;
+  u16_t pbuf_len = (u16_t)(sizeof(struct ip_hdr) + sizeof(struct tcp_hdr) + data_len);
+  LWIP_ASSERT("data_len too big", data_len <= 0xFFFF);
+
+  p = pbuf_alloc(PBUF_RAW, pbuf_len, PBUF_POOL);
+  EXPECT_RETNULL(p != NULL);
+  /* first pbuf must be big enough to hold the headers */
+  EXPECT_RETNULL(p->len >= (sizeof(struct ip_hdr) + sizeof(struct tcp_hdr)));
+  if (data_len > 0) {
+    /* first pbuf must be big enough to hold at least 1 data byte, too */
+    EXPECT_RETNULL(p->len > (sizeof(struct ip_hdr) + sizeof(struct tcp_hdr)));
+  }
+
+  for(q = p; q != NULL; q = q->next) {
+    memset(q->payload, 0, q->len);
+  }
+
+  iphdr = (struct ip_hdr*)p->payload;
+  /* fill IP header */
+  iphdr->dest.addr = ip_2_ip4(dst_ip)->addr;
+  iphdr->src.addr = ip_2_ip4(src_ip)->addr;
+  IPH_VHL_SET(iphdr, 4, IP_HLEN / 4);
+  IPH_TOS_SET(iphdr, 0);
+  IPH_LEN_SET(iphdr, htons(p->tot_len));
+  IPH_CHKSUM_SET(iphdr, inet_chksum(iphdr, IP_HLEN));
+
+  /* let p point to TCP header */
+  pbuf_header(p, -(s16_t)sizeof(struct ip_hdr));
+
+  tcphdr = (struct tcp_hdr*)p->payload;
+  tcphdr->src   = htons(src_port);
+  tcphdr->dest  = htons(dst_port);
+  tcphdr->seqno = htonl(seqno);
+  tcphdr->ackno = htonl(ackno);
+  TCPH_HDRLEN_SET(tcphdr, sizeof(struct tcp_hdr)/4);
+  TCPH_FLAGS_SET(tcphdr, headerflags);
+  tcphdr->wnd   = htons(wnd);
+
+  if (data_len > 0) {
+    /* let p point to TCP data */
+    pbuf_header(p, -(s16_t)sizeof(struct tcp_hdr));
+    /* copy data */
+    pbuf_take(p, data, (u16_t)data_len);
+    /* let p point to TCP header again */
+    pbuf_header(p, sizeof(struct tcp_hdr));
+  }
+
+  /* calculate checksum */
+
+  tcphdr->chksum = ip_chksum_pseudo(p,
+          IP_PROTO_TCP, p->tot_len, src_ip, dst_ip);
+
+  pbuf_header(p, sizeof(struct ip_hdr));
+
+  return p;
+}
+
+/** Create a TCP segment usable for passing to tcp_input */
+struct pbuf*
+tcp_create_segment(ip_addr_t* src_ip, ip_addr_t* dst_ip,
+                   u16_t src_port, u16_t dst_port, void* data, size_t data_len,
+                   u32_t seqno, u32_t ackno, u8_t headerflags)
+{
+  return tcp_create_segment_wnd(src_ip, dst_ip, src_port, dst_port, data,
+    data_len, seqno, ackno, headerflags, TCP_WND);
+}
+
+/** Create a TCP segment usable for passing to tcp_input
+ * - IP-addresses, ports, seqno and ackno are taken from pcb
+ * - seqno and ackno can be altered with an offset
+ */
+struct pbuf*
+tcp_create_rx_segment(struct tcp_pcb* pcb, void* data, size_t data_len, u32_t seqno_offset,
+                      u32_t ackno_offset, u8_t headerflags)
+{
+  return tcp_create_segment(&pcb->remote_ip, &pcb->local_ip, pcb->remote_port, pcb->local_port,
+    data, data_len, pcb->rcv_nxt + seqno_offset, pcb->lastack + ackno_offset, headerflags);
+}
+
+/** Create a TCP segment usable for passing to tcp_input
+ * - IP-addresses, ports, seqno and ackno are taken from pcb
+ * - seqno and ackno can be altered with an offset
+ * - TCP window can be adjusted
+ */
+struct pbuf* tcp_create_rx_segment_wnd(struct tcp_pcb* pcb, void* data, size_t data_len,
+                   u32_t seqno_offset, u32_t ackno_offset, u8_t headerflags, u16_t wnd)
+{
+  return tcp_create_segment_wnd(&pcb->remote_ip, &pcb->local_ip, pcb->remote_port, pcb->local_port,
+    data, data_len, pcb->rcv_nxt + seqno_offset, pcb->lastack + ackno_offset, headerflags, wnd);
+}
+
+/** Safely bring a tcp_pcb into the requested state */
+void
+tcp_set_state(struct tcp_pcb* pcb, enum tcp_state state, const ip_addr_t* local_ip,
+                   const ip_addr_t* remote_ip, u16_t local_port, u16_t remote_port)
+{
+  u32_t iss;
+
+  /* @todo: are these all states? */
+  /* @todo: remove from previous list */
+  pcb->state = state;
+  
+  iss = tcp_next_iss(pcb);
+  pcb->snd_wl2 = iss;
+  pcb->snd_nxt = iss;
+  pcb->lastack = iss;
+  pcb->snd_lbb = iss;
+  
+  if (state == ESTABLISHED) {
+    TCP_REG(&tcp_active_pcbs, pcb);
+    ip_addr_copy(pcb->local_ip, *local_ip);
+    pcb->local_port = local_port;
+    ip_addr_copy(pcb->remote_ip, *remote_ip);
+    pcb->remote_port = remote_port;
+  } else if(state == LISTEN) {
+    TCP_REG(&tcp_listen_pcbs.pcbs, pcb);
+    ip_addr_copy(pcb->local_ip, *local_ip);
+    pcb->local_port = local_port;
+  } else if(state == TIME_WAIT) {
+    TCP_REG(&tcp_tw_pcbs, pcb);
+    ip_addr_copy(pcb->local_ip, *local_ip);
+    pcb->local_port = local_port;
+    ip_addr_copy(pcb->remote_ip, *remote_ip);
+    pcb->remote_port = remote_port;
+  } else {
+    fail();
+  }
+}
+
+void
+test_tcp_counters_err(void* arg, err_t err)
+{
+  struct test_tcp_counters* counters = (struct test_tcp_counters*)arg;
+  EXPECT_RET(arg != NULL);
+  counters->err_calls++;
+  counters->last_err = err;
+}
+
+static void
+test_tcp_counters_check_rxdata(struct test_tcp_counters* counters, struct pbuf* p)
+{
+  struct pbuf* q;
+  u32_t i, received;
+  if(counters->expected_data == NULL) {
+    /* no data to compare */
+    return;
+  }
+  EXPECT_RET(counters->recved_bytes + p->tot_len <= counters->expected_data_len);
+  received = counters->recved_bytes;
+  for(q = p; q != NULL; q = q->next) {
+    char *data = (char*)q->payload;
+    for(i = 0; i < q->len; i++) {
+      EXPECT_RET(data[i] == counters->expected_data[received]);
+      received++;
+    }
+  }
+  EXPECT(received == counters->recved_bytes + p->tot_len);
+}
+
+err_t
+test_tcp_counters_recv(void* arg, struct tcp_pcb* pcb, struct pbuf* p, err_t err)
+{
+  struct test_tcp_counters* counters = (struct test_tcp_counters*)arg;
+  EXPECT_RETX(arg != NULL, ERR_OK);
+  EXPECT_RETX(pcb != NULL, ERR_OK);
+  EXPECT_RETX(err == ERR_OK, ERR_OK);
+
+  if (p != NULL) {
+    if (counters->close_calls == 0) {
+      counters->recv_calls++;
+      test_tcp_counters_check_rxdata(counters, p);
+      counters->recved_bytes += p->tot_len;
+    } else {
+      counters->recv_calls_after_close++;
+      counters->recved_bytes_after_close += p->tot_len;
+    }
+    pbuf_free(p);
+  } else {
+    counters->close_calls++;
+  }
+  EXPECT(counters->recv_calls_after_close == 0 && counters->recved_bytes_after_close == 0);
+  return ERR_OK;
+}
+
+/** Allocate a pcb and set up the test_tcp_counters_* callbacks */
+struct tcp_pcb*
+test_tcp_new_counters_pcb(struct test_tcp_counters* counters)
+{
+  struct tcp_pcb* pcb = tcp_new();
+  if (pcb != NULL) {
+    /* set up args and callbacks */
+    tcp_arg(pcb, counters);
+    tcp_recv(pcb, test_tcp_counters_recv);
+    tcp_err(pcb, test_tcp_counters_err);
+    pcb->snd_wnd = TCP_WND;
+    pcb->snd_wnd_max = TCP_WND;
+  }
+  return pcb;
+}
+
+/** Calls tcp_input() after adjusting current_iphdr_dest */
+void test_tcp_input(struct pbuf *p, struct netif *inp)
+{
+  struct ip_hdr *iphdr = (struct ip_hdr*)p->payload;
+  /* these lines are a hack, don't use them as an example :-) */
+  ip_addr_copy_from_ip4(*ip_current_dest_addr(), iphdr->dest);
+  ip_addr_copy_from_ip4(*ip_current_src_addr(), iphdr->src);
+  ip_current_netif() = inp;
+  ip_data.current_ip4_header = iphdr;
+
+  /* since adding IPv6, p->payload must point to tcp header, not ip header */
+  pbuf_header(p, -(s16_t)sizeof(struct ip_hdr));
+
+  tcp_input(p, inp);
+
+  ip_addr_set_zero(ip_current_dest_addr());
+  ip_addr_set_zero(ip_current_src_addr());
+  ip_current_netif() = NULL;
+  ip_data.current_ip4_header = NULL;
+}
+
+static err_t test_tcp_netif_output(struct netif *netif, struct pbuf *p,
+       const ip4_addr_t *ipaddr)
+{
+  struct test_tcp_txcounters *txcounters = (struct test_tcp_txcounters*)netif->state;
+  LWIP_UNUSED_ARG(ipaddr);
+  if (txcounters != NULL)
+  {
+    txcounters->num_tx_calls++;
+    txcounters->num_tx_bytes += p->tot_len;
+    if (txcounters->copy_tx_packets) {
+      struct pbuf *p_copy = pbuf_alloc(PBUF_LINK, p->tot_len, PBUF_RAM);
+      err_t err;
+      EXPECT(p_copy != NULL);
+      err = pbuf_copy(p_copy, p);
+      EXPECT(err == ERR_OK);
+      if (txcounters->tx_packets == NULL) {
+        txcounters->tx_packets = p_copy;
+      } else {
+        pbuf_cat(txcounters->tx_packets, p_copy);
+      }
+    }
+  }
+  return ERR_OK;
+}
+
+void test_tcp_init_netif(struct netif *netif, struct test_tcp_txcounters *txcounters,
+                         const ip_addr_t *ip_addr, const ip_addr_t *netmask)
+{
+  struct netif *n;
+  memset(netif, 0, sizeof(struct netif));
+  if (txcounters != NULL) {
+    memset(txcounters, 0, sizeof(struct test_tcp_txcounters));
+    netif->state = txcounters;
+  }
+  netif->output = test_tcp_netif_output;
+  netif->flags |= NETIF_FLAG_UP | NETIF_FLAG_LINK_UP;
+  ip_addr_copy_from_ip4(netif->netmask, *ip_2_ip4(netmask));
+  ip_addr_copy_from_ip4(netif->ip_addr, *ip_2_ip4(ip_addr));
+  for (n = netif_list; n != NULL; n = n->next) {
+    if (n == netif) {
+      return;
+    }
+  }
+  netif->next = NULL;
+  netif_list = netif;
+}
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/test/unit/tcp/tcp_helper.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/test/unit/tcp/tcp_helper.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/test/unit/tcp/tcp_helper.h	(revision 457)
@@ -0,0 +1,58 @@
+#ifndef LWIP_HDR_TCP_HELPER_H
+#define LWIP_HDR_TCP_HELPER_H
+
+#include "../lwip_check.h"
+#include "lwip/arch.h"
+#include "lwip/tcp.h"
+#include "lwip/netif.h"
+
+/* counters used for test_tcp_counters_* callback functions */
+struct test_tcp_counters {
+  u32_t recv_calls;
+  u32_t recved_bytes;
+  u32_t recv_calls_after_close;
+  u32_t recved_bytes_after_close;
+  u32_t close_calls;
+  u32_t err_calls;
+  err_t last_err;
+  char* expected_data;
+  u32_t expected_data_len;
+};
+
+struct test_tcp_txcounters {
+  u32_t num_tx_calls;
+  u32_t num_tx_bytes;
+  u8_t  copy_tx_packets;
+  struct pbuf *tx_packets;
+};
+
+extern const ip_addr_t test_local_ip;
+extern const ip_addr_t test_remote_ip;
+extern const ip_addr_t test_netmask;
+#define TEST_REMOTE_PORT    0x100
+#define TEST_LOCAL_PORT     0x101
+
+/* Helper functions */
+void tcp_remove_all(void);
+
+struct pbuf* tcp_create_segment(ip_addr_t* src_ip, ip_addr_t* dst_ip,
+                   u16_t src_port, u16_t dst_port, void* data, size_t data_len,
+                   u32_t seqno, u32_t ackno, u8_t headerflags);
+struct pbuf* tcp_create_rx_segment(struct tcp_pcb* pcb, void* data, size_t data_len,
+                   u32_t seqno_offset, u32_t ackno_offset, u8_t headerflags);
+struct pbuf* tcp_create_rx_segment_wnd(struct tcp_pcb* pcb, void* data, size_t data_len,
+                   u32_t seqno_offset, u32_t ackno_offset, u8_t headerflags, u16_t wnd);
+void tcp_set_state(struct tcp_pcb* pcb, enum tcp_state state, const ip_addr_t* local_ip,
+                   const ip_addr_t* remote_ip, u16_t local_port, u16_t remote_port);
+void test_tcp_counters_err(void* arg, err_t err);
+err_t test_tcp_counters_recv(void* arg, struct tcp_pcb* pcb, struct pbuf* p, err_t err);
+
+struct tcp_pcb* test_tcp_new_counters_pcb(struct test_tcp_counters* counters);
+
+void test_tcp_input(struct pbuf *p, struct netif *inp);
+
+void test_tcp_init_netif(struct netif *netif, struct test_tcp_txcounters *txcounters,
+                         const ip_addr_t *ip_addr, const ip_addr_t *netmask);
+
+
+#endif
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/test/unit/tcp/test_tcp.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/test/unit/tcp/test_tcp.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/test/unit/tcp/test_tcp.c	(revision 457)
@@ -0,0 +1,1695 @@
+#include "test_tcp.h"
+
+#include "lwip/priv/tcp_priv.h"
+#include "lwip/stats.h"
+#include "tcp_helper.h"
+#include "lwip/inet_chksum.h"
+
+#ifdef _MSC_VER
+#pragma warning(disable: 4307) /* we explicitly wrap around TCP seqnos */
+#endif
+
+#if !LWIP_STATS || !TCP_STATS || !MEMP_STATS
+#error "This tests needs TCP- and MEMP-statistics enabled"
+#endif
+#if TCP_SND_BUF <= TCP_WND
+#error "This tests needs TCP_SND_BUF to be > TCP_WND"
+#endif
+
+/* used with check_seqnos() */
+#define SEQNO1 (0xFFFFFF00 - TCP_MSS)
+#define ISS    6510
+static u32_t seqnos[] = {
+    SEQNO1,
+    SEQNO1 + (1 * TCP_MSS),
+    SEQNO1 + (2 * TCP_MSS),
+    SEQNO1 + (3 * TCP_MSS),
+    SEQNO1 + (4 * TCP_MSS),
+    SEQNO1 + (5 * TCP_MSS) };
+
+static u8_t test_tcp_timer;
+
+/* our own version of tcp_tmr so we can reset fast/slow timer state */
+static void
+test_tcp_tmr(void)
+{
+  tcp_fasttmr();
+  if (++test_tcp_timer & 1) {
+    tcp_slowtmr();
+  }
+}
+
+/* Setups/teardown functions */
+static struct netif *old_netif_list;
+static struct netif *old_netif_default;
+
+static void
+tcp_setup(void)
+{
+  struct tcp_pcb dummy_pcb; /* we need this for tcp_next_iss() only */
+
+  old_netif_list = netif_list;
+  old_netif_default = netif_default;
+  netif_list = NULL;
+  netif_default = NULL;
+  /* reset iss to default (6510) */
+  tcp_ticks = 0;
+  tcp_ticks = 0 - (tcp_next_iss(&dummy_pcb) - 6510);
+  tcp_next_iss(&dummy_pcb);
+  tcp_ticks = 0;
+
+  test_tcp_timer = 0;
+  tcp_remove_all();
+  lwip_check_ensure_no_alloc(SKIP_POOL(MEMP_SYS_TIMEOUT));
+}
+
+static void
+tcp_teardown(void)
+{
+  netif_list = NULL;
+  netif_default = NULL;
+  tcp_remove_all();
+  /* restore netif_list for next tests (e.g. loopif) */
+  netif_list = old_netif_list;
+  netif_default = old_netif_default;
+  lwip_check_ensure_no_alloc(SKIP_POOL(MEMP_SYS_TIMEOUT));
+}
+
+
+/* Test functions */
+
+/** Call tcp_new() and tcp_abort() and test memp stats */
+START_TEST(test_tcp_new_abort)
+{
+  struct tcp_pcb* pcb;
+  LWIP_UNUSED_ARG(_i);
+
+  fail_unless(MEMP_STATS_GET(used, MEMP_TCP_PCB) == 0);
+
+  pcb = tcp_new();
+  fail_unless(pcb != NULL);
+  if (pcb != NULL) {
+    fail_unless(MEMP_STATS_GET(used, MEMP_TCP_PCB) == 1);
+    tcp_abort(pcb);
+    fail_unless(MEMP_STATS_GET(used, MEMP_TCP_PCB) == 0);
+  }
+}
+END_TEST
+
+/** Call tcp_new() and tcp_abort() and test memp stats */
+START_TEST(test_tcp_listen_passive_open)
+{
+  struct tcp_pcb *pcb, *pcbl;
+  struct tcp_pcb_listen *lpcb;
+  struct netif netif;
+  struct test_tcp_txcounters txcounters;
+  struct test_tcp_counters counters;
+  struct pbuf *p;
+  ip_addr_t src_addr;
+  err_t err;
+  LWIP_UNUSED_ARG(_i);
+
+  fail_unless(MEMP_STATS_GET(used, MEMP_TCP_PCB) == 0);
+
+  test_tcp_init_netif(&netif, &txcounters, &test_local_ip, &test_netmask);
+  /* initialize counter struct */
+  memset(&counters, 0, sizeof(counters));
+
+  pcb = tcp_new();
+  EXPECT_RET(pcb != NULL);
+  err = tcp_bind(pcb, &netif.ip_addr, 1234);
+  EXPECT(err == ERR_OK);
+  pcbl = tcp_listen(pcb);
+  EXPECT_RET(pcbl != NULL);
+  EXPECT_RET(pcbl != pcb);
+  lpcb = (struct tcp_pcb_listen *)pcbl;
+
+  ip_addr_set_ip4_u32_val(src_addr, lwip_htonl(lwip_ntohl(ip_addr_get_ip4_u32(&lpcb->local_ip)) + 1));
+
+  /* check correct syn packet */
+  p = tcp_create_segment(&src_addr, &lpcb->local_ip, 12345,
+    lpcb->local_port, NULL, 0, 12345, 54321, TCP_SYN);
+  EXPECT(p != NULL);
+  if (p != NULL) {
+    /* pass the segment to tcp_input */
+    test_tcp_input(p, &netif);
+    /* check if counters are as expected */
+    EXPECT(txcounters.num_tx_calls == 1);
+  }
+
+  /* check syn packet with short length */
+  p = tcp_create_segment(&src_addr, &lpcb->local_ip, 12345,
+    lpcb->local_port, NULL, 0, 12345, 54321, TCP_SYN);
+  EXPECT(p != NULL);
+  EXPECT(p->next == NULL);
+  if ((p != NULL) && (p->next == NULL)) {
+    p->len -= 2;
+    p->tot_len -= 2;
+    /* pass the segment to tcp_input */
+    test_tcp_input(p, &netif);
+    /* check if counters are as expected */
+    EXPECT(txcounters.num_tx_calls == 1);
+  }
+
+  tcp_close(pcbl);
+}
+END_TEST
+
+/** Create an ESTABLISHED pcb and check if receive callback is called */
+START_TEST(test_tcp_recv_inseq)
+{
+  struct test_tcp_counters counters;
+  struct tcp_pcb* pcb;
+  struct pbuf* p;
+  char data[] = {1, 2, 3, 4};
+  u16_t data_len;
+  struct netif netif;
+  struct test_tcp_txcounters txcounters;
+  LWIP_UNUSED_ARG(_i);
+
+  /* initialize local vars */
+  test_tcp_init_netif(&netif, &txcounters, &test_local_ip, &test_netmask);
+  data_len = sizeof(data);
+  /* initialize counter struct */
+  memset(&counters, 0, sizeof(counters));
+  counters.expected_data_len = data_len;
+  counters.expected_data = data;
+
+  /* create and initialize the pcb */
+  pcb = test_tcp_new_counters_pcb(&counters);
+  EXPECT_RET(pcb != NULL);
+  tcp_set_state(pcb, ESTABLISHED, &test_local_ip, &test_remote_ip, TEST_LOCAL_PORT, TEST_REMOTE_PORT);
+
+  /* create a segment */
+  p = tcp_create_rx_segment(pcb, counters.expected_data, data_len, 0, 0, 0);
+  EXPECT(p != NULL);
+  if (p != NULL) {
+    /* pass the segment to tcp_input */
+    test_tcp_input(p, &netif);
+    /* check if counters are as expected */
+    EXPECT(counters.close_calls == 0);
+    EXPECT(counters.recv_calls == 1);
+    EXPECT(counters.recved_bytes == data_len);
+    EXPECT(counters.err_calls == 0);
+  }
+
+  /* make sure the pcb is freed */
+  EXPECT(MEMP_STATS_GET(used, MEMP_TCP_PCB) == 1);
+  tcp_abort(pcb);
+  EXPECT(MEMP_STATS_GET(used, MEMP_TCP_PCB) == 0);
+}
+END_TEST
+
+/** Create an ESTABLISHED pcb and check if receive callback is called if a segment
+ * overlapping rcv_nxt is received */
+START_TEST(test_tcp_recv_inseq_trim)
+{
+  struct test_tcp_counters counters;
+  struct tcp_pcb* pcb;
+  struct pbuf* p;
+  char data[PBUF_POOL_BUFSIZE*2];
+  u16_t data_len;
+  struct netif netif;
+  struct test_tcp_txcounters txcounters;
+  const u32_t new_data_len = 40;
+  LWIP_UNUSED_ARG(_i);
+
+  /* initialize local vars */
+  test_tcp_init_netif(&netif, &txcounters, &test_local_ip, &test_netmask);
+  data_len = sizeof(data);
+  memset(data, 0, sizeof(data));
+  /* initialize counter struct */
+  memset(&counters, 0, sizeof(counters));
+  counters.expected_data_len = data_len;
+  counters.expected_data = data;
+
+  /* create and initialize the pcb */
+  pcb = test_tcp_new_counters_pcb(&counters);
+  EXPECT_RET(pcb != NULL);
+  tcp_set_state(pcb, ESTABLISHED, &test_local_ip, &test_remote_ip, TEST_LOCAL_PORT, TEST_REMOTE_PORT);
+
+  /* create a segment (with an overlapping/old seqno so that the new data begins in the 2nd pbuf) */
+  p = tcp_create_rx_segment(pcb, counters.expected_data, data_len, (u32_t)(0-(data_len-new_data_len)), 0, 0);
+  EXPECT(p != NULL);
+  if (p != NULL) {
+    EXPECT(p->next != NULL);
+    if (p->next != NULL) {
+      EXPECT(p->next->next != NULL);
+    }
+  }
+  if ((p != NULL) && (p->next != NULL) && (p->next->next != NULL)) {
+    /* pass the segment to tcp_input */
+    test_tcp_input(p, &netif);
+    /* check if counters are as expected */
+    EXPECT(counters.close_calls == 0);
+    EXPECT(counters.recv_calls == 1);
+    EXPECT(counters.recved_bytes == new_data_len);
+    EXPECT(counters.err_calls == 0);
+  }
+
+  /* make sure the pcb is freed */
+  EXPECT(MEMP_STATS_GET(used, MEMP_TCP_PCB) == 1);
+  tcp_abort(pcb);
+  EXPECT(MEMP_STATS_GET(used, MEMP_TCP_PCB) == 0);
+}
+END_TEST
+
+static err_t test_tcp_recv_expect1byte(void* arg, struct tcp_pcb* pcb, struct pbuf* p, err_t err);
+
+static err_t
+test_tcp_recv_expectclose(void* arg, struct tcp_pcb* pcb, struct pbuf* p, err_t err)
+{
+  EXPECT_RETX(pcb != NULL, ERR_OK);
+  EXPECT_RETX(err == ERR_OK, ERR_OK);
+  LWIP_UNUSED_ARG(arg);
+
+  if (p != NULL) {
+    fail();
+  } else {
+    /* correct: FIN received; close our end, too */
+    err_t err2 = tcp_close(pcb);
+    fail_unless(err2 == ERR_OK);
+    /* set back to some other rx function, just to not get here again */
+    tcp_recv(pcb, test_tcp_recv_expect1byte);
+  }
+  return ERR_OK;
+}
+
+static err_t
+test_tcp_recv_expect1byte(void* arg, struct tcp_pcb* pcb, struct pbuf* p, err_t err)
+{
+  EXPECT_RETX(pcb != NULL, ERR_OK);
+  EXPECT_RETX(err == ERR_OK, ERR_OK);
+  LWIP_UNUSED_ARG(arg);
+
+  if (p != NULL) {
+    if ((p->len == 1) && (p->tot_len == 1)) {
+      tcp_recv(pcb, test_tcp_recv_expectclose);
+    } else {
+      fail();
+    }
+    pbuf_free(p);
+  } else {
+    fail();
+  }
+  return ERR_OK;
+}
+
+START_TEST(test_tcp_passive_close)
+{
+  struct test_tcp_counters counters;
+  struct tcp_pcb* pcb;
+  struct pbuf* p;
+  char data = 0x0f;
+  struct netif netif;
+  struct test_tcp_txcounters txcounters;
+  LWIP_UNUSED_ARG(_i);
+
+  /* initialize local vars */
+  test_tcp_init_netif(&netif, &txcounters, &test_local_ip, &test_netmask);
+
+  /* initialize counter struct */
+  memset(&counters, 0, sizeof(counters));
+  counters.expected_data_len = 1;
+  counters.expected_data = &data;
+
+  /* create and initialize the pcb */
+  pcb = test_tcp_new_counters_pcb(&counters);
+  EXPECT_RET(pcb != NULL);
+  tcp_set_state(pcb, ESTABLISHED, &test_local_ip, &test_remote_ip, TEST_LOCAL_PORT, TEST_REMOTE_PORT);
+
+  /* create a segment without data */
+  p = tcp_create_rx_segment(pcb, &data, 1, 0, 0, TCP_FIN);
+  EXPECT(p != NULL);
+  if (p != NULL) {
+    tcp_recv(pcb, test_tcp_recv_expect1byte);
+    /* pass the segment to tcp_input */
+    test_tcp_input(p, &netif);
+  }
+  /* don't free the pcb here (part of the test!) */
+}
+END_TEST
+
+START_TEST(test_tcp_active_abort)
+{
+  struct test_tcp_counters counters;
+  struct tcp_pcb* pcb;
+  char data = 0x0f;
+  struct netif netif;
+  struct test_tcp_txcounters txcounters;
+  LWIP_UNUSED_ARG(_i);
+
+  memset(&txcounters, 0, sizeof(txcounters));
+
+  /* initialize local vars */
+  test_tcp_init_netif(&netif, &txcounters, &test_local_ip, &test_netmask);
+
+  /* initialize counter struct */
+  memset(&counters, 0, sizeof(counters));
+  counters.expected_data_len = 1;
+  counters.expected_data = &data;
+
+  /* create and initialize the pcb */
+  pcb = test_tcp_new_counters_pcb(&counters);
+  EXPECT_RET(pcb != NULL);
+  tcp_set_state(pcb, ESTABLISHED, &test_local_ip, &test_remote_ip, TEST_LOCAL_PORT, TEST_REMOTE_PORT);
+
+  /* abort the pcb */
+  EXPECT_RET(txcounters.num_tx_calls == 0);
+  txcounters.copy_tx_packets = 1;
+  tcp_abort(pcb);
+  txcounters.copy_tx_packets = 0;
+  EXPECT(txcounters.num_tx_calls == 1);
+  EXPECT(txcounters.num_tx_bytes == 40U);
+  EXPECT(txcounters.tx_packets != NULL);
+  if (txcounters.tx_packets != NULL) {
+    u16_t ret;
+    struct tcp_hdr tcphdr;
+    ret = pbuf_copy_partial(txcounters.tx_packets, &tcphdr, 20, 20);
+    EXPECT(ret == 20);
+    EXPECT(tcphdr.dest == PP_HTONS(TEST_REMOTE_PORT));
+    EXPECT(tcphdr.src == PP_HTONS(TEST_LOCAL_PORT));
+    pbuf_free(txcounters.tx_packets);
+    txcounters.tx_packets = NULL;
+  }
+
+  /* don't free the pcb here (part of the test!) */
+}
+END_TEST
+
+/** Check that we handle malformed tcp headers, and discard the pbuf(s) */
+START_TEST(test_tcp_malformed_header)
+{
+  struct test_tcp_counters counters;
+  struct tcp_pcb* pcb;
+  struct pbuf* p;
+  char data[] = {1, 2, 3, 4};
+  u16_t data_len, chksum;
+  struct netif netif;
+  struct test_tcp_txcounters txcounters;
+  struct tcp_hdr *hdr;
+  LWIP_UNUSED_ARG(_i);
+
+  /* initialize local vars */
+  test_tcp_init_netif(&netif, &txcounters, &test_local_ip, &test_netmask);
+  data_len = sizeof(data);
+  /* initialize counter struct */
+  memset(&counters, 0, sizeof(counters));
+  counters.expected_data_len = data_len;
+  counters.expected_data = data;
+
+  /* create and initialize the pcb */
+  pcb = test_tcp_new_counters_pcb(&counters);
+  EXPECT_RET(pcb != NULL);
+  tcp_set_state(pcb, ESTABLISHED, &test_local_ip, &test_remote_ip, TEST_LOCAL_PORT, TEST_REMOTE_PORT);
+
+  /* create a segment */
+  p = tcp_create_rx_segment(pcb, counters.expected_data, data_len, 0, 0, 0);
+
+  pbuf_header(p, -(s16_t)sizeof(struct ip_hdr));
+
+  hdr = (struct tcp_hdr *)p->payload;
+  TCPH_HDRLEN_FLAGS_SET(hdr, 15, 0x3d1);
+
+  hdr->chksum = 0;
+
+  chksum = ip_chksum_pseudo(p, IP_PROTO_TCP, p->tot_len,
+                             &test_remote_ip, &test_local_ip);
+
+  hdr->chksum = chksum;
+
+  pbuf_header(p, sizeof(struct ip_hdr));
+
+  EXPECT(p != NULL);
+  EXPECT(p->next == NULL);
+  if (p != NULL) {
+    /* pass the segment to tcp_input */
+    test_tcp_input(p, &netif);
+    /* check if counters are as expected */
+    EXPECT(counters.close_calls == 0);
+    EXPECT(counters.recv_calls == 0);
+    EXPECT(counters.recved_bytes == 0);
+    EXPECT(counters.err_calls == 0);
+  }
+
+  /* make sure the pcb is freed */
+  EXPECT(MEMP_STATS_GET(used, MEMP_TCP_PCB) == 1);
+  tcp_abort(pcb);
+  EXPECT(MEMP_STATS_GET(used, MEMP_TCP_PCB) == 0);
+}
+END_TEST
+
+
+/** Provoke fast retransmission by duplicate ACKs and then recover by ACKing all sent data.
+ * At the end, send more data. */
+START_TEST(test_tcp_fast_retx_recover)
+{
+  struct netif netif;
+  struct test_tcp_txcounters txcounters;
+  struct test_tcp_counters counters;
+  struct tcp_pcb* pcb;
+  struct pbuf* p;
+  char data1[] = { 1,  2,  3,  4};
+  char data2[] = { 5,  6,  7,  8};
+  char data3[] = { 9, 10, 11, 12};
+  char data4[] = {13, 14, 15, 16};
+  char data5[] = {17, 18, 19, 20};
+  char data6[TCP_MSS] = {21, 22, 23, 24};
+  err_t err;
+  LWIP_UNUSED_ARG(_i);
+
+  /* initialize local vars */
+  test_tcp_init_netif(&netif, &txcounters, &test_local_ip, &test_netmask);
+  memset(&counters, 0, sizeof(counters));
+
+  /* create and initialize the pcb */
+  pcb = test_tcp_new_counters_pcb(&counters);
+  EXPECT_RET(pcb != NULL);
+  tcp_set_state(pcb, ESTABLISHED, &test_local_ip, &test_remote_ip, TEST_LOCAL_PORT, TEST_REMOTE_PORT);
+  pcb->mss = TCP_MSS;
+  /* disable initial congestion window (we don't send a SYN here...) */
+  pcb->cwnd = pcb->snd_wnd;
+
+  /* send data1 */
+  err = tcp_write(pcb, data1, sizeof(data1), TCP_WRITE_FLAG_COPY);
+  EXPECT_RET(err == ERR_OK);
+  err = tcp_output(pcb);
+  EXPECT_RET(err == ERR_OK);
+  EXPECT_RET(txcounters.num_tx_calls == 1);
+  EXPECT_RET(txcounters.num_tx_bytes == sizeof(data1) + sizeof(struct tcp_hdr) + sizeof(struct ip_hdr));
+  memset(&txcounters, 0, sizeof(txcounters));
+ /* "recv" ACK for data1 */
+  p = tcp_create_rx_segment(pcb, NULL, 0, 0, 4, TCP_ACK);
+  EXPECT_RET(p != NULL);
+  test_tcp_input(p, &netif);
+  EXPECT_RET(txcounters.num_tx_calls == 0);
+  EXPECT_RET(pcb->unacked == NULL);
+  /* send data2 */
+  err = tcp_write(pcb, data2, sizeof(data2), TCP_WRITE_FLAG_COPY);
+  EXPECT_RET(err == ERR_OK);
+  err = tcp_output(pcb);
+  EXPECT_RET(err == ERR_OK);
+  EXPECT_RET(txcounters.num_tx_calls == 1);
+  EXPECT_RET(txcounters.num_tx_bytes == sizeof(data2) + sizeof(struct tcp_hdr) + sizeof(struct ip_hdr));
+  memset(&txcounters, 0, sizeof(txcounters));
+  /* duplicate ACK for data1 (data2 is lost) */
+  p = tcp_create_rx_segment(pcb, NULL, 0, 0, 0, TCP_ACK);
+  EXPECT_RET(p != NULL);
+  test_tcp_input(p, &netif);
+  EXPECT_RET(txcounters.num_tx_calls == 0);
+  EXPECT_RET(pcb->dupacks == 1);
+  /* send data3 */
+  err = tcp_write(pcb, data3, sizeof(data3), TCP_WRITE_FLAG_COPY);
+  EXPECT_RET(err == ERR_OK);
+  err = tcp_output(pcb);
+  EXPECT_RET(err == ERR_OK);
+  /* nagle enabled, no tx calls */
+  EXPECT_RET(txcounters.num_tx_calls == 0);
+  EXPECT_RET(txcounters.num_tx_bytes == 0);
+  memset(&txcounters, 0, sizeof(txcounters));
+  /* 2nd duplicate ACK for data1 (data2 and data3 are lost) */
+  p = tcp_create_rx_segment(pcb, NULL, 0, 0, 0, TCP_ACK);
+  EXPECT_RET(p != NULL);
+  test_tcp_input(p, &netif);
+  EXPECT_RET(txcounters.num_tx_calls == 0);
+  EXPECT_RET(pcb->dupacks == 2);
+  /* queue data4, don't send it (unsent-oversize is != 0) */
+  err = tcp_write(pcb, data4, sizeof(data4), TCP_WRITE_FLAG_COPY);
+  EXPECT_RET(err == ERR_OK);
+  /* 3nd duplicate ACK for data1 (data2 and data3 are lost) -> fast retransmission */
+  p = tcp_create_rx_segment(pcb, NULL, 0, 0, 0, TCP_ACK);
+  EXPECT_RET(p != NULL);
+  test_tcp_input(p, &netif);
+  /*EXPECT_RET(txcounters.num_tx_calls == 1);*/
+  EXPECT_RET(pcb->dupacks == 3);
+  memset(&txcounters, 0, sizeof(txcounters));
+  /* @todo: check expected data?*/
+  
+  /* send data5, not output yet */
+  err = tcp_write(pcb, data5, sizeof(data5), TCP_WRITE_FLAG_COPY);
+  EXPECT_RET(err == ERR_OK);
+  /*err = tcp_output(pcb);
+  EXPECT_RET(err == ERR_OK);*/
+  EXPECT_RET(txcounters.num_tx_calls == 0);
+  EXPECT_RET(txcounters.num_tx_bytes == 0);
+  memset(&txcounters, 0, sizeof(txcounters));
+  {
+    int i = 0;
+    do
+    {
+      err = tcp_write(pcb, data6, TCP_MSS, TCP_WRITE_FLAG_COPY);
+      i++;
+    }while(err == ERR_OK);
+    EXPECT_RET(err != ERR_OK);
+  }
+  err = tcp_output(pcb);
+  EXPECT_RET(err == ERR_OK);
+  /*EXPECT_RET(txcounters.num_tx_calls == 0);
+  EXPECT_RET(txcounters.num_tx_bytes == 0);*/
+  memset(&txcounters, 0, sizeof(txcounters));
+
+  /* send even more data */
+  err = tcp_write(pcb, data5, sizeof(data5), TCP_WRITE_FLAG_COPY);
+  EXPECT_RET(err == ERR_OK);
+  err = tcp_output(pcb);
+  EXPECT_RET(err == ERR_OK);
+  /* ...and even more data */
+  err = tcp_write(pcb, data5, sizeof(data5), TCP_WRITE_FLAG_COPY);
+  EXPECT_RET(err == ERR_OK);
+  err = tcp_output(pcb);
+  EXPECT_RET(err == ERR_OK);
+  /* ...and even more data */
+  err = tcp_write(pcb, data5, sizeof(data5), TCP_WRITE_FLAG_COPY);
+  EXPECT_RET(err == ERR_OK);
+  err = tcp_output(pcb);
+  EXPECT_RET(err == ERR_OK);
+  /* ...and even more data */
+  err = tcp_write(pcb, data5, sizeof(data5), TCP_WRITE_FLAG_COPY);
+  EXPECT_RET(err == ERR_OK);
+  err = tcp_output(pcb);
+  EXPECT_RET(err == ERR_OK);
+
+  /* send ACKs for data2 and data3 */
+  p = tcp_create_rx_segment(pcb, NULL, 0, 0, 12, TCP_ACK);
+  EXPECT_RET(p != NULL);
+  test_tcp_input(p, &netif);
+  /*EXPECT_RET(txcounters.num_tx_calls == 0);*/
+
+  /* ...and even more data */
+  err = tcp_write(pcb, data5, sizeof(data5), TCP_WRITE_FLAG_COPY);
+  EXPECT_RET(err == ERR_OK);
+  err = tcp_output(pcb);
+  EXPECT_RET(err == ERR_OK);
+  /* ...and even more data */
+  err = tcp_write(pcb, data5, sizeof(data5), TCP_WRITE_FLAG_COPY);
+  EXPECT_RET(err == ERR_OK);
+  err = tcp_output(pcb);
+  EXPECT_RET(err == ERR_OK);
+
+#if 0
+  /* create expected segment */
+  p1 = tcp_create_rx_segment(pcb, counters.expected_data, data_len, 0, 0, 0);
+  EXPECT_RET(p != NULL);
+  if (p != NULL) {
+    /* pass the segment to tcp_input */
+    test_tcp_input(p, &netif);
+    /* check if counters are as expected */
+    EXPECT_RET(counters.close_calls == 0);
+    EXPECT_RET(counters.recv_calls == 1);
+    EXPECT_RET(counters.recved_bytes == data_len);
+    EXPECT_RET(counters.err_calls == 0);
+  }
+#endif
+  /* make sure the pcb is freed */
+  EXPECT_RET(MEMP_STATS_GET(used, MEMP_TCP_PCB) == 1);
+  tcp_abort(pcb);
+  EXPECT_RET(MEMP_STATS_GET(used, MEMP_TCP_PCB) == 0);
+}
+END_TEST
+
+static u8_t tx_data[TCP_WND*2];
+
+static void
+check_seqnos(struct tcp_seg *segs, int num_expected, u32_t *seqnos_expected)
+{
+  struct tcp_seg *s = segs;
+  int i;
+  for (i = 0; i < num_expected; i++, s = s->next) {
+    EXPECT_RET(s != NULL);
+    EXPECT(s->tcphdr->seqno == htonl(seqnos_expected[i]));
+  }
+  EXPECT(s == NULL);
+}
+
+/** Send data with sequence numbers that wrap around the u32_t range.
+ * Then, provoke fast retransmission by duplicate ACKs and check that all
+ * segment lists are still properly sorted. */
+START_TEST(test_tcp_fast_rexmit_wraparound)
+{
+  struct netif netif;
+  struct test_tcp_txcounters txcounters;
+  struct test_tcp_counters counters;
+  struct tcp_pcb* pcb;
+  struct pbuf* p;
+  err_t err;
+  size_t i;
+  u16_t sent_total = 0;
+  LWIP_UNUSED_ARG(_i);
+
+  for (i = 0; i < sizeof(tx_data); i++) {
+    tx_data[i] = (u8_t)i;
+  }
+
+  /* initialize local vars */
+  test_tcp_init_netif(&netif, &txcounters, &test_local_ip, &test_netmask);
+  memset(&counters, 0, sizeof(counters));
+
+  /* create and initialize the pcb */
+  tcp_ticks = SEQNO1 - ISS;
+  pcb = test_tcp_new_counters_pcb(&counters);
+  EXPECT_RET(pcb != NULL);
+  tcp_set_state(pcb, ESTABLISHED, &test_local_ip, &test_remote_ip, TEST_LOCAL_PORT, TEST_REMOTE_PORT);
+  pcb->mss = TCP_MSS;
+  /* disable initial congestion window (we don't send a SYN here...) */
+  pcb->cwnd = 2*TCP_MSS;
+  /* start in congestion advoidance */
+  pcb->ssthresh = pcb->cwnd;
+
+  /* send 6 mss-sized segments */
+  for (i = 0; i < 6; i++) {
+    err = tcp_write(pcb, &tx_data[sent_total], TCP_MSS, TCP_WRITE_FLAG_COPY);
+    EXPECT_RET(err == ERR_OK);
+    sent_total += TCP_MSS;
+  }
+  check_seqnos(pcb->unsent, 6, seqnos);
+  EXPECT(pcb->unacked == NULL);
+  err = tcp_output(pcb);
+  EXPECT(txcounters.num_tx_calls == 2);
+  EXPECT(txcounters.num_tx_bytes == 2 * (TCP_MSS + 40U));
+  memset(&txcounters, 0, sizeof(txcounters));
+
+  check_seqnos(pcb->unacked, 2, seqnos);
+  check_seqnos(pcb->unsent, 4, &seqnos[2]);
+
+  /* ACK the first segment */
+  p = tcp_create_rx_segment(pcb, NULL, 0, 0, TCP_MSS, TCP_ACK);
+  test_tcp_input(p, &netif);
+  /* ensure this didn't trigger a retransmission. Only one
+  segment should be transmitted because cwnd opened up by
+  TCP_MSS and a fraction since we are in congestion avoidance */
+  EXPECT(txcounters.num_tx_calls == 1);
+  EXPECT(txcounters.num_tx_bytes == TCP_MSS + 40U);
+  memset(&txcounters, 0, sizeof(txcounters));
+  check_seqnos(pcb->unacked, 2, &seqnos[1]);
+  check_seqnos(pcb->unsent, 3, &seqnos[3]);
+
+  /* 3 dupacks */
+  EXPECT(pcb->dupacks == 0);
+  p = tcp_create_rx_segment(pcb, NULL, 0, 0, 0, TCP_ACK);
+  test_tcp_input(p, &netif);
+  EXPECT(txcounters.num_tx_calls == 0);
+  EXPECT(pcb->dupacks == 1);
+  p = tcp_create_rx_segment(pcb, NULL, 0, 0, 0, TCP_ACK);
+  test_tcp_input(p, &netif);
+  EXPECT(txcounters.num_tx_calls == 0);
+  EXPECT(pcb->dupacks == 2);
+  /* 3rd dupack -> fast rexmit */
+  p = tcp_create_rx_segment(pcb, NULL, 0, 0, 0, TCP_ACK);
+  test_tcp_input(p, &netif);
+  EXPECT(pcb->dupacks == 3);
+  EXPECT(txcounters.num_tx_calls == 4);
+  memset(&txcounters, 0, sizeof(txcounters));
+  EXPECT(pcb->unsent == NULL);
+  check_seqnos(pcb->unacked, 5, &seqnos[1]);
+
+  /* make sure the pcb is freed */
+  EXPECT_RET(MEMP_STATS_GET(used, MEMP_TCP_PCB) == 1);
+  tcp_abort(pcb);
+  EXPECT_RET(MEMP_STATS_GET(used, MEMP_TCP_PCB) == 0);
+}
+END_TEST
+
+/** Send data with sequence numbers that wrap around the u32_t range.
+ * Then, provoke RTO retransmission and check that all
+ * segment lists are still properly sorted. */
+START_TEST(test_tcp_rto_rexmit_wraparound)
+{
+  struct netif netif;
+  struct test_tcp_txcounters txcounters;
+  struct test_tcp_counters counters;
+  struct tcp_pcb* pcb;
+  struct tcp_pcb dummy_pcb_for_iss; /* we need this for tcp_next_iss() only */
+  err_t err;
+  size_t i;
+  u16_t sent_total = 0;
+  LWIP_UNUSED_ARG(_i);
+
+  for (i = 0; i < sizeof(tx_data); i++) {
+    tx_data[i] = (u8_t)i;
+  }
+
+  /* initialize local vars */
+  test_tcp_init_netif(&netif, &txcounters, &test_local_ip, &test_netmask);
+  memset(&counters, 0, sizeof(counters));
+
+  /* create and initialize the pcb */
+  tcp_ticks = 0;
+  tcp_ticks = 0 - tcp_next_iss(&dummy_pcb_for_iss);
+  tcp_ticks = SEQNO1 - tcp_next_iss(&dummy_pcb_for_iss);
+  pcb = test_tcp_new_counters_pcb(&counters);
+  EXPECT_RET(pcb != NULL);
+  tcp_set_state(pcb, ESTABLISHED, &test_local_ip, &test_remote_ip, TEST_LOCAL_PORT, TEST_REMOTE_PORT);
+  pcb->mss = TCP_MSS;
+  /* disable initial congestion window (we don't send a SYN here...) */
+  pcb->cwnd = 2*TCP_MSS;
+
+  /* send 6 mss-sized segments */
+  for (i = 0; i < 6; i++) {
+    err = tcp_write(pcb, &tx_data[sent_total], TCP_MSS, TCP_WRITE_FLAG_COPY);
+    EXPECT_RET(err == ERR_OK);
+    sent_total += TCP_MSS;
+  }
+  check_seqnos(pcb->unsent, 6, seqnos);
+  EXPECT(pcb->unacked == NULL);
+  err = tcp_output(pcb);
+  EXPECT(txcounters.num_tx_calls == 2);
+  EXPECT(txcounters.num_tx_bytes == 2 * (TCP_MSS + 40U));
+  memset(&txcounters, 0, sizeof(txcounters));
+
+  check_seqnos(pcb->unacked, 2, seqnos);
+  check_seqnos(pcb->unsent, 4, &seqnos[2]);
+
+  /* call the tcp timer some times */
+  for (i = 0; i < 10; i++) {
+    test_tcp_tmr();
+    EXPECT(txcounters.num_tx_calls == 0);
+  }
+  /* 11th call to tcp_tmr: RTO rexmit fires */
+  test_tcp_tmr();
+  EXPECT(txcounters.num_tx_calls == 1);
+  check_seqnos(pcb->unacked, 1, seqnos);
+  check_seqnos(pcb->unsent, 5, &seqnos[1]);
+
+  /* fake greater cwnd */
+  pcb->cwnd = pcb->snd_wnd;
+  /* send more data */
+  err = tcp_output(pcb);
+  EXPECT(err == ERR_OK);
+  /* check queues are sorted */
+  EXPECT(pcb->unsent == NULL);
+  check_seqnos(pcb->unacked, 6, seqnos);
+
+  /* make sure the pcb is freed */
+  EXPECT_RET(MEMP_STATS_GET(used, MEMP_TCP_PCB) == 1);
+  tcp_abort(pcb);
+  EXPECT_RET(MEMP_STATS_GET(used, MEMP_TCP_PCB) == 0);
+}
+END_TEST
+
+/** Provoke fast retransmission by duplicate ACKs and then recover by ACKing all sent data.
+ * At the end, send more data. */
+static void test_tcp_tx_full_window_lost(u8_t zero_window_probe_from_unsent)
+{
+  struct netif netif;
+  struct test_tcp_txcounters txcounters;
+  struct test_tcp_counters counters;
+  struct tcp_pcb* pcb;
+  struct pbuf *p;
+  err_t err;
+  size_t i;
+  u16_t sent_total;
+  u8_t expected = 0xFE;
+
+  for (i = 0; i < sizeof(tx_data); i++) {
+    u8_t d = (u8_t)i;
+    if (d == 0xFE) {
+      d = 0xF0;
+    }
+    tx_data[i] = d;
+  }
+  if (zero_window_probe_from_unsent) {
+    tx_data[TCP_WND] = expected;
+  } else {
+    tx_data[0] = expected;
+  }
+
+  /* initialize local vars */
+  test_tcp_init_netif(&netif, &txcounters, &test_local_ip, &test_netmask);
+  memset(&counters, 0, sizeof(counters));
+
+  /* create and initialize the pcb */
+  pcb = test_tcp_new_counters_pcb(&counters);
+  EXPECT_RET(pcb != NULL);
+  tcp_set_state(pcb, ESTABLISHED, &test_local_ip, &test_remote_ip, TEST_LOCAL_PORT, TEST_REMOTE_PORT);
+  pcb->mss = TCP_MSS;
+  /* disable initial congestion window (we don't send a SYN here...) */
+  pcb->cwnd = pcb->snd_wnd;
+
+  /* send a full window (minus 1 packets) of TCP data in MSS-sized chunks */
+  sent_total = 0;
+  if ((TCP_WND - TCP_MSS) % TCP_MSS != 0) {
+    u16_t initial_data_len = (TCP_WND - TCP_MSS) % TCP_MSS;
+    err = tcp_write(pcb, &tx_data[sent_total], initial_data_len, TCP_WRITE_FLAG_COPY);
+    EXPECT_RET(err == ERR_OK);
+    err = tcp_output(pcb);
+    EXPECT_RET(err == ERR_OK);
+    EXPECT(txcounters.num_tx_calls == 1);
+    EXPECT(txcounters.num_tx_bytes == initial_data_len + 40U);
+    memset(&txcounters, 0, sizeof(txcounters));
+    sent_total += initial_data_len;
+  }
+  for (; sent_total < (TCP_WND - TCP_MSS); sent_total += TCP_MSS) {
+    err = tcp_write(pcb, &tx_data[sent_total], TCP_MSS, TCP_WRITE_FLAG_COPY);
+    EXPECT_RET(err == ERR_OK);
+    err = tcp_output(pcb);
+    EXPECT_RET(err == ERR_OK);
+    EXPECT(txcounters.num_tx_calls == 1);
+    EXPECT(txcounters.num_tx_bytes == TCP_MSS + 40U);
+    memset(&txcounters, 0, sizeof(txcounters));
+  }
+  EXPECT(sent_total == (TCP_WND - TCP_MSS));
+
+  /* now ACK the packet before the first */
+  p = tcp_create_rx_segment(pcb, NULL, 0, 0, 0, TCP_ACK);
+  test_tcp_input(p, &netif);
+  /* ensure this didn't trigger a retransmission */
+  EXPECT(txcounters.num_tx_calls == 0);
+  EXPECT(txcounters.num_tx_bytes == 0);
+
+  EXPECT(pcb->persist_backoff == 0);
+  /* send the last packet, now a complete window has been sent */
+  err = tcp_write(pcb, &tx_data[sent_total], TCP_MSS, TCP_WRITE_FLAG_COPY);
+  sent_total += TCP_MSS;
+  EXPECT_RET(err == ERR_OK);
+  err = tcp_output(pcb);
+  EXPECT_RET(err == ERR_OK);
+  EXPECT(txcounters.num_tx_calls == 1);
+  EXPECT(txcounters.num_tx_bytes == TCP_MSS + 40U);
+  memset(&txcounters, 0, sizeof(txcounters));
+  EXPECT(pcb->persist_backoff == 0);
+
+  if (zero_window_probe_from_unsent) {
+    /* ACK all data but close the TX window */
+    p = tcp_create_rx_segment_wnd(pcb, NULL, 0, 0, TCP_WND, TCP_ACK, 0);
+    test_tcp_input(p, &netif);
+    /* ensure this didn't trigger any transmission */
+    EXPECT(txcounters.num_tx_calls == 0);
+    EXPECT(txcounters.num_tx_bytes == 0);
+    /* window is completely full, but persist timer is off since send buffer is empty */
+    EXPECT(pcb->snd_wnd == 0);
+    EXPECT(pcb->persist_backoff == 0);
+  }
+
+  /* send one byte more (out of window) -> persist timer starts */
+  err = tcp_write(pcb, &tx_data[sent_total], 1, TCP_WRITE_FLAG_COPY);
+  EXPECT_RET(err == ERR_OK);
+  err = tcp_output(pcb);
+  EXPECT_RET(err == ERR_OK);
+  EXPECT(txcounters.num_tx_calls == 0);
+  EXPECT(txcounters.num_tx_bytes == 0);
+  memset(&txcounters, 0, sizeof(txcounters));
+  if (!zero_window_probe_from_unsent) {
+    /* no persist timer unless a zero window announcement has been received */
+    EXPECT(pcb->persist_backoff == 0);
+  } else {
+    EXPECT(pcb->persist_backoff == 1);
+
+    /* call tcp_timer some more times to let persist timer count up */
+    for (i = 0; i < 4; i++) {
+      test_tcp_tmr();
+      EXPECT(txcounters.num_tx_calls == 0);
+      EXPECT(txcounters.num_tx_bytes == 0);
+    }
+
+    /* this should trigger the zero-window-probe */
+    txcounters.copy_tx_packets = 1;
+    test_tcp_tmr();
+    txcounters.copy_tx_packets = 0;
+    EXPECT(txcounters.num_tx_calls == 1);
+    EXPECT(txcounters.num_tx_bytes == 1 + 40U);
+    EXPECT(txcounters.tx_packets != NULL);
+    if (txcounters.tx_packets != NULL) {
+      u8_t sent;
+      u16_t ret;
+      ret = pbuf_copy_partial(txcounters.tx_packets, &sent, 1, 40U);
+      EXPECT(ret == 1);
+      EXPECT(sent == expected);
+    }
+    if (txcounters.tx_packets != NULL) {
+      pbuf_free(txcounters.tx_packets);
+      txcounters.tx_packets = NULL;
+    }
+  }
+
+  /* make sure the pcb is freed */
+  EXPECT_RET(MEMP_STATS_GET(used, MEMP_TCP_PCB) == 1);
+  tcp_abort(pcb);
+  EXPECT_RET(MEMP_STATS_GET(used, MEMP_TCP_PCB) == 0);
+}
+
+START_TEST(test_tcp_tx_full_window_lost_from_unsent)
+{
+  LWIP_UNUSED_ARG(_i);
+  test_tcp_tx_full_window_lost(1);
+}
+END_TEST
+
+START_TEST(test_tcp_tx_full_window_lost_from_unacked)
+{
+  LWIP_UNUSED_ARG(_i);
+  test_tcp_tx_full_window_lost(0);
+}
+END_TEST
+
+/** Send data, provoke retransmission and then add data to a segment
+ * that already has been sent before. */
+START_TEST(test_tcp_retx_add_to_sent)
+{
+  struct netif netif;
+  struct test_tcp_txcounters txcounters;
+  struct test_tcp_counters counters;
+  struct tcp_pcb* pcb;
+  struct pbuf* p;
+  char data1a[] = {  1,  2,  3};
+  char data1b[] = {  4};
+  char data2a[] = {  5,  6,  7,  8};
+  char data2b[] = {  5,  6,  7};
+  char data3[] = {  9, 10, 11, 12, 12};
+  char data4[] = { 13, 14, 15, 16,17};
+  err_t err;
+  int i;
+  LWIP_UNUSED_ARG(_i);
+
+  /* initialize local vars */
+  test_tcp_init_netif(&netif, &txcounters, &test_local_ip, &test_netmask);
+  memset(&counters, 0, sizeof(counters));
+
+  /* create and initialize the pcb */
+  pcb = test_tcp_new_counters_pcb(&counters);
+  EXPECT_RET(pcb != NULL);
+  tcp_set_state(pcb, ESTABLISHED, &test_local_ip, &test_remote_ip, TEST_LOCAL_PORT, TEST_REMOTE_PORT);
+  pcb->mss = TCP_MSS;
+  /* disable initial congestion window (we don't send a SYN here...) */
+  pcb->cwnd = pcb->snd_wnd;
+
+  /* send data1 */
+  err = tcp_write(pcb, data1a, sizeof(data1a), TCP_WRITE_FLAG_COPY);
+  EXPECT_RET(err == ERR_OK);
+  err = tcp_write(pcb, data1b, sizeof(data1b), TCP_WRITE_FLAG_COPY);
+  EXPECT_RET(err == ERR_OK);
+  err = tcp_output(pcb);
+  EXPECT_RET(err == ERR_OK);
+  EXPECT_RET(txcounters.num_tx_calls == 1);
+  EXPECT_RET(txcounters.num_tx_bytes == sizeof(data1a) + sizeof(data1b) + sizeof(struct tcp_hdr) + sizeof(struct ip_hdr));
+  memset(&txcounters, 0, sizeof(txcounters));
+ /* "recv" ACK for data1 */
+  p = tcp_create_rx_segment(pcb, NULL, 0, 0, 4, TCP_ACK);
+  EXPECT_RET(p != NULL);
+  test_tcp_input(p, &netif);
+  EXPECT_RET(txcounters.num_tx_calls == 0);
+  EXPECT_RET(pcb->unacked == NULL);
+  /* send data2 */
+  err = tcp_write(pcb, data2a, sizeof(data2a), TCP_WRITE_FLAG_COPY);
+  EXPECT_RET(err == ERR_OK);
+  err = tcp_write(pcb, data2b, sizeof(data2b), TCP_WRITE_FLAG_COPY);
+  EXPECT_RET(err == ERR_OK);
+  err = tcp_output(pcb);
+  EXPECT_RET(err == ERR_OK);
+  EXPECT_RET(txcounters.num_tx_calls == 1);
+  EXPECT_RET(txcounters.num_tx_bytes == sizeof(data2a) + sizeof(data2b) + sizeof(struct tcp_hdr) + sizeof(struct ip_hdr));
+  memset(&txcounters, 0, sizeof(txcounters));
+  /* send data3 */
+  err = tcp_write(pcb, data3, sizeof(data3), TCP_WRITE_FLAG_COPY);
+  EXPECT_RET(err == ERR_OK);
+  err = tcp_output(pcb);
+  EXPECT_RET(err == ERR_OK);
+  EXPECT_RET(txcounters.num_tx_calls == 0);
+  EXPECT_RET(txcounters.num_tx_bytes == 0);
+  memset(&txcounters, 0, sizeof(txcounters));
+
+  /* data3 not sent yet (nagle) */
+  EXPECT_RET(pcb->unacked != NULL);
+  EXPECT_RET(pcb->unsent != NULL);
+
+  /* disable nagle for this test so data to sent segment can be added below... */
+  tcp_nagle_disable(pcb);
+
+  /* call the tcp timer some times */
+  for (i = 0; i < 20; i++) {
+    test_tcp_tmr();
+    if (txcounters.num_tx_calls != 0) {
+      break;
+    }
+  }
+  /* data3 sent */
+  EXPECT_RET(txcounters.num_tx_calls == 1);
+  EXPECT_RET(txcounters.num_tx_bytes == sizeof(data3) + sizeof(struct tcp_hdr) + sizeof(struct ip_hdr));
+  EXPECT_RET(pcb->unacked != NULL);
+  EXPECT_RET(pcb->unsent == NULL);
+  memset(&txcounters, 0, sizeof(txcounters));
+
+  tcp_nagle_enable(pcb);
+
+  /* call the tcp timer some times */
+  for (i = 0; i < 20; i++) {
+    test_tcp_tmr();
+    if (txcounters.num_tx_calls != 0) {
+      break;
+    }
+  }
+  /* RTO: rexmit of data2 */
+  EXPECT_RET(txcounters.num_tx_calls == 1);
+  EXPECT_RET(txcounters.num_tx_bytes == sizeof(data2a) + sizeof(data2b) + sizeof(struct tcp_hdr) + sizeof(struct ip_hdr));
+  EXPECT_RET(pcb->unacked != NULL);
+  EXPECT_RET(pcb->unsent != NULL);
+  memset(&txcounters, 0, sizeof(txcounters));
+
+  /* send data4 */
+  err = tcp_write(pcb, data4, sizeof(data4), TCP_WRITE_FLAG_COPY);
+  EXPECT_RET(err == ERR_OK);
+  /* disable nagle for this test so data to transmit without further ACKs... */
+  tcp_nagle_disable(pcb);
+  err = tcp_output(pcb);
+  EXPECT_RET(err == ERR_OK);
+  /* nagle enabled, no tx calls */
+  EXPECT_RET(txcounters.num_tx_calls == 1);
+  EXPECT_RET(txcounters.num_tx_bytes == sizeof(data3) + sizeof(data4) + sizeof(struct tcp_hdr) + sizeof(struct ip_hdr));
+  memset(&txcounters, 0, sizeof(txcounters));
+  /* make sure the pcb is freed */
+  EXPECT_RET(MEMP_STATS_GET(used, MEMP_TCP_PCB) == 1);
+  tcp_abort(pcb);
+  EXPECT_RET(MEMP_STATS_GET(used, MEMP_TCP_PCB) == 0);
+}
+END_TEST
+
+START_TEST(test_tcp_rto_tracking)
+{
+  struct netif netif;
+  struct test_tcp_txcounters txcounters;
+  struct test_tcp_counters counters;
+  struct tcp_pcb* pcb;
+  struct pbuf* p;
+  err_t err;
+  size_t i;
+  u16_t sent_total = 0;
+  LWIP_UNUSED_ARG(_i);
+
+  for (i = 0; i < sizeof(tx_data); i++) {
+    tx_data[i] = (u8_t)i;
+  }
+
+  /* initialize local vars */
+  test_tcp_init_netif(&netif, &txcounters, &test_local_ip, &test_netmask);
+  memset(&counters, 0, sizeof(counters));
+
+  /* create and initialize the pcb */
+  tcp_ticks = SEQNO1 - ISS;
+  pcb = test_tcp_new_counters_pcb(&counters);
+  EXPECT_RET(pcb != NULL);
+  tcp_set_state(pcb, ESTABLISHED, &test_local_ip, &test_remote_ip, TEST_LOCAL_PORT, TEST_REMOTE_PORT);
+  pcb->mss = TCP_MSS;
+  /* Set congestion window large enough to send all our segments */
+  pcb->cwnd = 5*TCP_MSS;
+
+  /* send 5 mss-sized segments */
+  for (i = 0; i < 5; i++) {
+    err = tcp_write(pcb, &tx_data[sent_total], TCP_MSS, TCP_WRITE_FLAG_COPY);
+    EXPECT_RET(err == ERR_OK);
+    sent_total += TCP_MSS;
+  }
+  check_seqnos(pcb->unsent, 5, seqnos);
+  EXPECT(pcb->unacked == NULL);
+  err = tcp_output(pcb);
+  EXPECT(txcounters.num_tx_calls == 5);
+  EXPECT(txcounters.num_tx_bytes == 5 * (TCP_MSS + 40U));
+  memset(&txcounters, 0, sizeof(txcounters));
+  /* Check all 5 are in-flight */
+  EXPECT(pcb->unsent == NULL);
+  check_seqnos(pcb->unacked, 5, seqnos);
+
+  /* Force us into retransmisson timeout */
+  while (!(pcb->flags & TF_RTO)) {
+    test_tcp_tmr();
+  }
+  /* Ensure 4 remaining segments are back on unsent, ready for retransmission */
+  check_seqnos(pcb->unsent, 4, &seqnos[1]);
+  /* Ensure 1st segment is on unacked (already retransmitted) */
+  check_seqnos(pcb->unacked, 1, seqnos);
+  EXPECT(txcounters.num_tx_calls == 1);
+  EXPECT(txcounters.num_tx_bytes == TCP_MSS + 40U);
+  memset(&txcounters, 0, sizeof(txcounters));
+  /* Ensure rto_end points to next byte */
+  EXPECT(pcb->rto_end == seqnos[5]);
+  EXPECT(pcb->rto_end == pcb->snd_nxt);
+  /* Check cwnd was reset */
+  EXPECT(pcb->cwnd == pcb->mss);
+
+  /* Add another segment to send buffer which is outside of RTO */
+  err = tcp_write(pcb, &tx_data[sent_total], TCP_MSS, TCP_WRITE_FLAG_COPY);
+  EXPECT_RET(err == ERR_OK);
+  sent_total += TCP_MSS;
+  check_seqnos(pcb->unsent, 5, &seqnos[1]);
+  /* Ensure no new data was sent */
+  EXPECT(txcounters.num_tx_calls == 0);
+  EXPECT(txcounters.num_tx_bytes == 0);
+  EXPECT(pcb->rto_end == pcb->snd_nxt);
+
+  /* ACK first segment */
+  p = tcp_create_rx_segment(pcb, NULL, 0, 0, TCP_MSS, TCP_ACK);
+  test_tcp_input(p, &netif);
+  /* Next two retranmissions should go out, due to cwnd in slow start */
+  EXPECT(txcounters.num_tx_calls == 2);
+  EXPECT(txcounters.num_tx_bytes == 2 * (TCP_MSS + 40U));
+  memset(&txcounters, 0, sizeof(txcounters));
+  check_seqnos(pcb->unacked, 2, &seqnos[1]);
+  check_seqnos(pcb->unsent, 3, &seqnos[3]);
+  /* RTO should still be marked */
+  EXPECT(pcb->flags & TF_RTO);
+  /* cwnd should have only grown by 1 MSS */
+  EXPECT(pcb->cwnd == (tcpwnd_size_t)(2 * pcb->mss));
+  /* Ensure no new data was sent */
+  EXPECT(pcb->rto_end == pcb->snd_nxt);
+
+  /* ACK the next two segments */
+  p = tcp_create_rx_segment(pcb, NULL, 0, 0, 2*TCP_MSS, TCP_ACK);
+  test_tcp_input(p, &netif);
+  /* Final 2 retransmissions and 1 new data should go out */
+  EXPECT(txcounters.num_tx_calls == 3);
+  EXPECT(txcounters.num_tx_bytes == 3 * (TCP_MSS + 40U));
+  memset(&txcounters, 0, sizeof(txcounters));
+  check_seqnos(pcb->unacked, 3, &seqnos[3]);
+  EXPECT(pcb->unsent == NULL);
+  /* RTO should still be marked */
+  EXPECT(pcb->flags & TF_RTO);
+  /* cwnd should have only grown by 1 MSS */
+  EXPECT(pcb->cwnd == (tcpwnd_size_t)(3 * pcb->mss));
+  /* snd_nxt should have been advanced past rto_end */
+  EXPECT(TCP_SEQ_GT(pcb->snd_nxt, pcb->rto_end));
+
+  /* ACK the next two segments, finishing our RTO, leaving new segment unacked */
+  p = tcp_create_rx_segment(pcb, NULL, 0, 0, 2*TCP_MSS, TCP_ACK);
+  test_tcp_input(p, &netif);
+  EXPECT(!(pcb->flags & TF_RTO));
+  check_seqnos(pcb->unacked, 1, &seqnos[5]);
+  /* We should be in ABC congestion avoidance, so no change in cwnd */
+  EXPECT(pcb->cwnd == (tcpwnd_size_t)(3 * pcb->mss));
+  EXPECT(pcb->cwnd >= pcb->ssthresh);
+  /* Ensure ABC congestion avoidance is tracking bytes acked */
+  EXPECT(pcb->bytes_acked == (tcpwnd_size_t)(2 * pcb->mss));
+
+  /* make sure the pcb is freed */
+  EXPECT_RET(MEMP_STATS_GET(used, MEMP_TCP_PCB) == 1);
+  tcp_abort(pcb);
+  EXPECT_RET(MEMP_STATS_GET(used, MEMP_TCP_PCB) == 0);
+}
+END_TEST
+
+static void test_tcp_rto_timeout_impl(int link_down)
+{
+  struct netif netif;
+  struct test_tcp_txcounters txcounters;
+  struct test_tcp_counters counters;
+  struct tcp_pcb *pcb, *cur;
+  err_t err;
+  size_t i;
+  const size_t max_wait_ctr = 1024 * 1024;
+
+  /* Setup data for a single segment */
+  for (i = 0; i < TCP_MSS; i++) {
+    tx_data[i] = (u8_t)i;
+  }
+
+  /* initialize local vars */
+  test_tcp_init_netif(&netif, &txcounters, &test_local_ip, &test_netmask);
+  memset(&counters, 0, sizeof(counters));
+
+  /* create and initialize the pcb */
+  tcp_ticks = SEQNO1 - ISS;
+  pcb = test_tcp_new_counters_pcb(&counters);
+  EXPECT_RET(pcb != NULL);
+  tcp_set_state(pcb, ESTABLISHED, &test_local_ip, &test_remote_ip, TEST_LOCAL_PORT, TEST_REMOTE_PORT);
+  pcb->mss = TCP_MSS;
+  pcb->cwnd = TCP_MSS;
+
+  /* send our segment */
+  err = tcp_write(pcb, &tx_data[0], TCP_MSS, TCP_WRITE_FLAG_COPY);
+  EXPECT_RET(err == ERR_OK);
+  err = tcp_output(pcb);
+  EXPECT(txcounters.num_tx_calls == 1);
+  EXPECT(txcounters.num_tx_bytes == 1 * (TCP_MSS + 40U));
+  memset(&txcounters, 0, sizeof(txcounters));
+
+  /* ensure no errors have been recorded */
+  EXPECT(counters.err_calls == 0);
+  EXPECT(counters.last_err == ERR_OK);
+
+  /* Force us into retransmisson timeout */
+   for (i = 0; !(pcb->flags & TF_RTO) && i < max_wait_ctr; i++) {
+    test_tcp_tmr();
+  }
+   EXPECT(i < max_wait_ctr);
+
+  /* check first rexmit */
+  EXPECT(pcb->nrtx == 1);
+  EXPECT(txcounters.num_tx_calls == 1);
+  EXPECT(txcounters.num_tx_bytes == 1 * (TCP_MSS + 40U));
+
+  /* still no error expected */
+  EXPECT(counters.err_calls == 0);
+  EXPECT(counters.last_err == ERR_OK);
+
+  if (link_down) {
+    netif_set_link_down(&netif);
+  }
+
+  /* keep running the timer till we hit our maximum RTO */
+  for (i = 0;  counters.last_err == ERR_OK && i < max_wait_ctr; i++) {
+    test_tcp_tmr();
+  }
+  EXPECT(i < max_wait_ctr);
+
+  /* check number of retransmissions */
+  if (link_down) {
+    EXPECT(txcounters.num_tx_calls == 1);
+    EXPECT(txcounters.num_tx_bytes == 1 * (TCP_MSS + 40U));
+  } else {
+    EXPECT(txcounters.num_tx_calls == TCP_MAXRTX);
+    EXPECT(txcounters.num_tx_bytes == TCP_MAXRTX * (TCP_MSS + 40U));
+  }
+
+  /* check the connection (pcb) has been aborted */
+  EXPECT(counters.err_calls == 1);
+  EXPECT(counters.last_err == ERR_ABRT);
+  /* check our pcb is no longer active */
+  for (cur = tcp_active_pcbs; cur != NULL; cur = cur->next) {
+    EXPECT(cur != pcb);
+  }  
+  EXPECT_RET(MEMP_STATS_GET(used, MEMP_TCP_PCB) == 0);
+}
+
+START_TEST(test_tcp_rto_timeout)
+{
+  LWIP_UNUSED_ARG(_i);
+  test_tcp_rto_timeout_impl(0);
+}
+END_TEST
+
+START_TEST(test_tcp_rto_timeout_link_down)
+{
+  LWIP_UNUSED_ARG(_i);
+  test_tcp_rto_timeout_impl(1);
+}
+END_TEST
+
+static void test_tcp_rto_timeout_syn_sent_impl(int link_down)
+{
+  struct netif netif;
+  struct test_tcp_txcounters txcounters;
+  struct test_tcp_counters counters;
+  struct tcp_pcb *pcb, *cur;
+  err_t err;
+  size_t i;
+  const size_t max_wait_ctr = 1024 * 1024;
+  const u16_t tcp_syn_opts_len = LWIP_TCP_OPT_LENGTH(TF_SEG_OPTS_MSS|TF_SEG_OPTS_WND_SCALE|TF_SEG_OPTS_SACK_PERM|TF_SEG_OPTS_TS);
+
+  /* Setup data for a single segment */
+  for (i = 0; i < TCP_MSS; i++) {
+    tx_data[i] = (u8_t)i;
+  }
+
+  /* initialize local vars */
+  test_tcp_init_netif(&netif, &txcounters, &test_local_ip, &test_netmask);
+  memset(&counters, 0, sizeof(counters));
+
+  /* create and initialize the pcb */
+  tcp_ticks = SEQNO1 - ISS;
+  pcb = test_tcp_new_counters_pcb(&counters);
+  EXPECT_RET(pcb != NULL);
+  err = tcp_connect(pcb, &netif.gw, 123, NULL);
+  EXPECT_RET(err == ERR_OK);
+  EXPECT_RET(pcb->state == SYN_SENT);
+  EXPECT(txcounters.num_tx_calls == 1);
+  EXPECT(txcounters.num_tx_bytes == 40U + tcp_syn_opts_len);
+
+  /* ensure no errors have been recorded */
+  EXPECT(counters.err_calls == 0);
+  EXPECT(counters.last_err == ERR_OK);
+
+  txcounters.num_tx_calls = 0;
+  txcounters.num_tx_bytes = 0;
+
+  /* Force us into retransmisson timeout */
+  for (i = 0; !(pcb->flags & TF_RTO) && i < max_wait_ctr; i++) {
+    test_tcp_tmr();
+  }
+  EXPECT(i < max_wait_ctr);
+
+  /* check first rexmit */
+  EXPECT(pcb->nrtx == 1);
+  EXPECT(txcounters.num_tx_calls == 1);
+  EXPECT(txcounters.num_tx_bytes == 40U + tcp_syn_opts_len); /* 40: headers; >=: options */
+
+  /* still no error expected */
+  EXPECT(counters.err_calls == 0);
+  EXPECT(counters.last_err == ERR_OK);
+
+  if (link_down) {
+    /* set link down and check what happens to the RTO counter */
+    netif_set_link_down(&netif);
+  }
+
+  /* keep running the timer till we hit our maximum RTO */
+  for (i = 0;  counters.last_err == ERR_OK && i < max_wait_ctr; i++) {
+    test_tcp_tmr();
+  }
+  EXPECT(i < max_wait_ctr);
+
+  /* check number of retransmissions */
+  if (link_down) {
+    EXPECT(txcounters.num_tx_calls == 1);
+    EXPECT(txcounters.num_tx_bytes == 40U + tcp_syn_opts_len);
+  } else {
+    EXPECT(txcounters.num_tx_calls == TCP_SYNMAXRTX);
+    EXPECT(txcounters.num_tx_bytes == TCP_SYNMAXRTX * (tcp_syn_opts_len + 40U));
+  }
+
+  /* check the connection (pcb) has been aborted */
+  EXPECT(counters.err_calls == 1);
+  EXPECT(counters.last_err == ERR_ABRT);
+  /* check our pcb is no longer active */
+  for (cur = tcp_active_pcbs; cur != NULL; cur = cur->next) {
+    EXPECT(cur != pcb);
+  }  
+  EXPECT_RET(MEMP_STATS_GET(used, MEMP_TCP_PCB) == 0);
+}
+
+START_TEST(test_tcp_rto_timeout_syn_sent)
+{
+  LWIP_UNUSED_ARG(_i);
+  test_tcp_rto_timeout_syn_sent_impl(0);
+}
+END_TEST
+
+START_TEST(test_tcp_rto_timeout_syn_sent_link_down)
+{
+  LWIP_UNUSED_ARG(_i);
+  test_tcp_rto_timeout_syn_sent_impl(1);
+}
+END_TEST
+
+static void test_tcp_zwp_timeout_impl(int link_down)
+{
+  struct netif netif;
+  struct test_tcp_txcounters txcounters;
+  struct test_tcp_counters counters;
+  struct tcp_pcb *pcb, *cur;
+  struct pbuf* p;
+  err_t err;
+  size_t i;
+
+  /* Setup data for two segments */
+  for (i = 0; i < 2*TCP_MSS; i++) {
+    tx_data[i] = (u8_t)i;
+  }
+
+  /* initialize local vars */
+  test_tcp_init_netif(&netif, &txcounters, &test_local_ip, &test_netmask);
+  memset(&counters, 0, sizeof(counters));
+
+  /* create and initialize the pcb */
+  tcp_ticks = SEQNO1 - ISS;
+  pcb = test_tcp_new_counters_pcb(&counters);
+  EXPECT_RET(pcb != NULL);
+  tcp_set_state(pcb, ESTABLISHED, &test_local_ip, &test_remote_ip, TEST_LOCAL_PORT, TEST_REMOTE_PORT);
+  pcb->mss = TCP_MSS;
+  pcb->cwnd = TCP_MSS;
+
+  /* send first segment */
+  err = tcp_write(pcb, &tx_data[0], TCP_MSS, TCP_WRITE_FLAG_COPY);
+  EXPECT(err == ERR_OK);
+  err = tcp_output(pcb);
+  EXPECT(err == ERR_OK);
+  
+  /* verify segment is in-flight */
+  EXPECT(pcb->unsent == NULL);
+  check_seqnos(pcb->unacked, 1, seqnos);
+  EXPECT(txcounters.num_tx_calls == 1);
+  EXPECT(txcounters.num_tx_bytes == 1 * (TCP_MSS + 40U));
+  memset(&txcounters, 0, sizeof(txcounters));
+
+  /* ACK the segment and close the TX window */
+  p = tcp_create_rx_segment_wnd(pcb, NULL, 0, 0, TCP_MSS, TCP_ACK, 0);
+  test_tcp_input(p, &netif);
+  EXPECT(pcb->unacked == NULL);
+  EXPECT(pcb->unsent == NULL);
+  /* send buffer empty, persist should be off */
+  EXPECT(pcb->persist_backoff == 0);
+  EXPECT(pcb->snd_wnd == 0);
+
+  /* send second segment, should be buffered */
+  err = tcp_write(pcb, &tx_data[TCP_MSS], TCP_MSS, TCP_WRITE_FLAG_COPY);
+  EXPECT(err == ERR_OK);
+  err = tcp_output(pcb);
+  EXPECT(err == ERR_OK);
+
+  /* ensure it is buffered and persist timer started */
+  EXPECT(pcb->unacked == NULL);
+  check_seqnos(pcb->unsent, 1, &seqnos[1]);
+  EXPECT(txcounters.num_tx_calls == 0);
+  EXPECT(txcounters.num_tx_bytes == 0);
+  EXPECT(pcb->persist_backoff == 1);
+
+  /* ensure no errors have been recorded */
+  EXPECT(counters.err_calls == 0);
+  EXPECT(counters.last_err == ERR_OK);
+
+  /* run timer till first probe */
+  EXPECT(pcb->persist_probe == 0);
+  while (pcb->persist_probe == 0) {
+    test_tcp_tmr();
+  }
+  EXPECT(txcounters.num_tx_calls == 1);
+  EXPECT(txcounters.num_tx_bytes == (1 + 40U));
+  memset(&txcounters, 0, sizeof(txcounters));
+
+  /* respond to probe with remote's current SEQ, ACK, and zero-window */
+  p = tcp_create_rx_segment_wnd(pcb, NULL, 0, 0, 0, TCP_ACK, 0);
+  test_tcp_input(p, &netif);
+  /* ensure zero-window is still active, but probe count reset */
+  EXPECT(pcb->persist_backoff > 1);
+  EXPECT(pcb->persist_probe == 0);
+  EXPECT(pcb->snd_wnd == 0);
+
+  /* ensure no errors have been recorded */
+  EXPECT(counters.err_calls == 0);
+  EXPECT(counters.last_err == ERR_OK);
+
+  if (link_down) {
+    netif_set_link_down(&netif);
+  }
+
+  /* now run the timer till we hit our maximum probe count */
+  while (counters.last_err == ERR_OK) {
+    test_tcp_tmr();
+  }
+
+  if (link_down) {
+    EXPECT(txcounters.num_tx_calls == 0);
+    EXPECT(txcounters.num_tx_bytes == 0);
+  } else {
+    /* check maximum number of 1 byte probes were sent */
+    EXPECT(txcounters.num_tx_calls == TCP_MAXRTX);
+    EXPECT(txcounters.num_tx_bytes == TCP_MAXRTX * (1 + 40U));
+  }
+
+  /* check the connection (pcb) has been aborted */
+  EXPECT(counters.err_calls == 1);
+  EXPECT(counters.last_err == ERR_ABRT);
+  /* check our pcb is no longer active */
+  for (cur = tcp_active_pcbs; cur != NULL; cur = cur->next) {
+    EXPECT(cur != pcb);
+  }  
+  EXPECT_RET(MEMP_STATS_GET(used, MEMP_TCP_PCB) == 0);
+}
+
+START_TEST(test_tcp_zwp_timeout)
+{
+  LWIP_UNUSED_ARG(_i);
+  test_tcp_zwp_timeout_impl(0);
+}
+END_TEST
+
+START_TEST(test_tcp_zwp_timeout_link_down)
+{
+  LWIP_UNUSED_ARG(_i);
+  test_tcp_zwp_timeout_impl(1);
+}
+END_TEST
+
+START_TEST(test_tcp_persist_split)
+{
+  struct netif netif;
+  struct test_tcp_txcounters txcounters;
+  struct test_tcp_counters counters;
+  struct tcp_pcb *pcb;
+  struct pbuf* p;
+  err_t err;
+  size_t i;
+  LWIP_UNUSED_ARG(_i);
+
+  /* Setup data for four segments */
+  for (i = 0; i < 4 * TCP_MSS; i++) {
+    tx_data[i] = (u8_t)i;
+  }
+
+  /* initialize local vars */
+  test_tcp_init_netif(&netif, &txcounters, &test_local_ip, &test_netmask);
+  memset(&counters, 0, sizeof(counters));
+
+  /* create and initialize the pcb */
+  tcp_ticks = SEQNO1 - ISS;
+  pcb = test_tcp_new_counters_pcb(&counters);
+  EXPECT_RET(pcb != NULL);
+  tcp_set_state(pcb, ESTABLISHED, &test_local_ip, &test_remote_ip, TEST_LOCAL_PORT, TEST_REMOTE_PORT);
+  pcb->mss = TCP_MSS;
+  /* set window to three segments */
+  pcb->cwnd = 3 * TCP_MSS;
+  pcb->snd_wnd = 3 * TCP_MSS;
+  pcb->snd_wnd_max = 3 * TCP_MSS;
+
+  /* send four segments. Fourth should stay buffered and is a 3/4 MSS segment to
+     get coverage on the oversized segment case */
+  err = tcp_write(pcb, &tx_data[0], (3 * TCP_MSS) + (TCP_MSS - (TCP_MSS / 4)), TCP_WRITE_FLAG_COPY);
+  EXPECT(err == ERR_OK);
+  err = tcp_output(pcb);
+  EXPECT(err == ERR_OK);
+
+  /* verify 3 segments are in-flight */
+  EXPECT(pcb->unacked != NULL);
+  check_seqnos(pcb->unacked, 3, seqnos);
+  EXPECT(txcounters.num_tx_calls == 3);
+  EXPECT(txcounters.num_tx_bytes == 3 * (TCP_MSS + 40U));
+  memset(&txcounters, 0, sizeof(txcounters));
+  /* verify 4th segment is on unsent */
+  EXPECT(pcb->unsent != NULL);
+  EXPECT(pcb->unsent->len == TCP_MSS - (TCP_MSS / 4));
+  check_seqnos(pcb->unsent, 1, &seqnos[3]);
+#if TCP_OVERSIZE
+  EXPECT(pcb->unsent_oversize == TCP_MSS / 4);
+#if TCP_OVERSIZE_DBGCHECK
+  EXPECT(pcb->unsent->oversize_left == pcb->unsent_oversize);
+#endif /* TCP_OVERSIZE_DBGCHECK */
+#endif /* TCP_OVERSIZE */
+
+  /* ACK the 3 segments and update the window to only 1/2 TCP_MSS.
+     4th segment should stay on unsent because it's bigger than 1/2 MSS */
+  p = tcp_create_rx_segment_wnd(pcb, NULL, 0, 0, 3 * TCP_MSS, TCP_ACK, TCP_MSS / 2);
+  test_tcp_input(p, &netif);
+  EXPECT(pcb->unacked == NULL);
+  EXPECT(pcb->snd_wnd == TCP_MSS / 2);
+  EXPECT(pcb->unsent != NULL);
+  check_seqnos(pcb->unsent, 1, &seqnos[3]);
+  EXPECT(txcounters.num_tx_calls == 0);
+  EXPECT(txcounters.num_tx_bytes == 0);
+  /* persist timer should be started since 4th segment is stuck waiting on snd_wnd */
+  EXPECT(pcb->persist_backoff == 1);
+
+  /* ensure no errors have been recorded */
+  EXPECT(counters.err_calls == 0);
+  EXPECT(counters.last_err == ERR_OK);
+
+  /* call tcp_timer some more times to let persist timer count up */
+    for (i = 0; i < 4; i++) {
+      test_tcp_tmr();
+      EXPECT(txcounters.num_tx_calls == 0);
+      EXPECT(txcounters.num_tx_bytes == 0);
+    }
+
+  /* this should be the first timer shot, which should split the
+   * segment and send a runt (of the remaining window size) */
+  txcounters.copy_tx_packets = 1;
+  test_tcp_tmr();
+  txcounters.copy_tx_packets = 0;
+  /* persist will be disabled as RTO timer takes over */
+  EXPECT(pcb->persist_backoff == 0);
+  EXPECT(txcounters.num_tx_calls == 1);
+  EXPECT(txcounters.num_tx_bytes == ((TCP_MSS /2) + 40U));
+  /* verify 1/2 MSS segment sent, 1/4 MSS still buffered */
+  EXPECT(pcb->unsent != NULL);
+  EXPECT(pcb->unsent->len == TCP_MSS / 4);
+  EXPECT(pcb->unacked != NULL);
+  EXPECT(pcb->unacked->len == TCP_MSS / 2);
+#if TCP_OVERSIZE
+  /* verify there is no oversized remaining since during the
+     segment split, the remainder pbuf is always the exact length */
+  EXPECT(pcb->unsent_oversize == 0);
+#if TCP_OVERSIZE_DBGCHECK
+  /* Split segment already transmitted, should be at 0 */
+  EXPECT(pcb->unacked->oversize_left == 0);
+  /* Remainder segement should match pcb value (which is 0) */
+  EXPECT(pcb->unsent->oversize_left == pcb->unsent_oversize);
+#endif /* TCP_OVERSIZE_DBGCHECK */
+#endif /* TCP_OVERSIZE */
+
+  /* verify first half segment */
+  EXPECT(txcounters.tx_packets != NULL);
+  if (txcounters.tx_packets != NULL) {
+    u8_t sent[TCP_MSS / 2];
+    u16_t ret;
+    ret = pbuf_copy_partial(txcounters.tx_packets, &sent, TCP_MSS / 2, 40U);
+    EXPECT(ret == TCP_MSS / 2);
+    EXPECT(memcmp(sent, &tx_data[3 * TCP_MSS], TCP_MSS / 2) == 0);
+  }
+  if (txcounters.tx_packets != NULL) {
+    pbuf_free(txcounters.tx_packets);
+    txcounters.tx_packets = NULL;
+  }
+  memset(&txcounters, 0, sizeof(txcounters));
+
+  /* ACK the half segment, leave window at half segment */
+  p = tcp_create_rx_segment_wnd(pcb, NULL, 0, 0, TCP_MSS / 2, TCP_ACK, TCP_MSS / 2);
+  txcounters.copy_tx_packets = 1;
+  test_tcp_input(p, &netif);
+  txcounters.copy_tx_packets = 0;
+  /* ensure remaining segment was sent */
+  EXPECT(txcounters.num_tx_calls == 1);
+  EXPECT(txcounters.num_tx_bytes == ((TCP_MSS / 4) + 40U));
+  EXPECT(pcb->unsent == NULL);
+  EXPECT(pcb->unacked != NULL);
+  EXPECT(pcb->unacked->len == TCP_MSS / 4);
+  EXPECT(pcb->snd_wnd == TCP_MSS / 2);
+
+  /* verify remainder segment */
+  EXPECT(txcounters.tx_packets != NULL);
+  if (txcounters.tx_packets != NULL) {
+    u8_t sent[TCP_MSS / 4];
+    u16_t ret;
+    ret = pbuf_copy_partial(txcounters.tx_packets, &sent, TCP_MSS / 4, 40U);
+    EXPECT(ret == TCP_MSS / 4);
+    EXPECT(memcmp(sent, &tx_data[(3 * TCP_MSS) + TCP_MSS / 2], TCP_MSS / 4) == 0);
+  }
+  if (txcounters.tx_packets != NULL) {
+    pbuf_free(txcounters.tx_packets);
+    txcounters.tx_packets = NULL;
+  }
+
+  /* ensure no errors have been recorded */
+  EXPECT(counters.err_calls == 0);
+  EXPECT(counters.last_err == ERR_OK);
+
+  /* make sure the pcb is freed */
+  EXPECT_RET(MEMP_STATS_GET(used, MEMP_TCP_PCB) == 1);
+  tcp_abort(pcb);
+  EXPECT_RET(MEMP_STATS_GET(used, MEMP_TCP_PCB) == 0);
+}
+END_TEST
+
+/** Create the suite including all tests for this module */
+Suite *
+tcp_suite(void)
+{
+  testfunc tests[] = {
+    TESTFUNC(test_tcp_new_abort),
+    TESTFUNC(test_tcp_listen_passive_open),
+    TESTFUNC(test_tcp_recv_inseq),
+    TESTFUNC(test_tcp_recv_inseq_trim),
+    TESTFUNC(test_tcp_passive_close),
+    TESTFUNC(test_tcp_active_abort),
+    TESTFUNC(test_tcp_malformed_header),
+    TESTFUNC(test_tcp_fast_retx_recover),
+    TESTFUNC(test_tcp_fast_rexmit_wraparound),
+    TESTFUNC(test_tcp_rto_rexmit_wraparound),
+    TESTFUNC(test_tcp_tx_full_window_lost_from_unacked),
+    TESTFUNC(test_tcp_tx_full_window_lost_from_unsent),
+    TESTFUNC(test_tcp_retx_add_to_sent),
+    TESTFUNC(test_tcp_rto_tracking),
+    TESTFUNC(test_tcp_rto_timeout),
+    TESTFUNC(test_tcp_rto_timeout_link_down),
+    TESTFUNC(test_tcp_rto_timeout_syn_sent),
+    TESTFUNC(test_tcp_rto_timeout_syn_sent_link_down),
+    TESTFUNC(test_tcp_zwp_timeout),
+    TESTFUNC(test_tcp_zwp_timeout_link_down),
+    TESTFUNC(test_tcp_persist_split)
+  };
+  return create_suite("TCP", tests, sizeof(tests)/sizeof(testfunc), tcp_setup, tcp_teardown);
+}
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/test/unit/tcp/test_tcp.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/test/unit/tcp/test_tcp.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/test/unit/tcp/test_tcp.h	(revision 457)
@@ -0,0 +1,8 @@
+#ifndef LWIP_HDR_TEST_TCP_H
+#define LWIP_HDR_TEST_TCP_H
+
+#include "../lwip_check.h"
+
+Suite *tcp_suite(void);
+
+#endif
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/test/unit/tcp/test_tcp_oos.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/test/unit/tcp/test_tcp_oos.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/test/unit/tcp/test_tcp_oos.c	(revision 457)
@@ -0,0 +1,1018 @@
+#include "test_tcp_oos.h"
+
+#include "lwip/priv/tcp_priv.h"
+#include "lwip/stats.h"
+#include "tcp_helper.h"
+
+#if !LWIP_STATS || !TCP_STATS || !MEMP_STATS
+#error "This tests needs TCP- and MEMP-statistics enabled"
+#endif
+#if !TCP_QUEUE_OOSEQ
+#error "This tests needs TCP_QUEUE_OOSEQ enabled"
+#endif
+
+/** CHECK_SEGMENTS_ON_OOSEQ:
+ * 1: check count, seqno and len of segments on pcb->ooseq (strict)
+ * 0: only check that bytes are received in correct order (less strict) */
+#define CHECK_SEGMENTS_ON_OOSEQ 1
+
+#if CHECK_SEGMENTS_ON_OOSEQ
+#define EXPECT_OOSEQ(x) EXPECT(x)
+#else
+#define EXPECT_OOSEQ(x)
+#endif
+
+/* helper functions */
+
+/** Get the numbers of segments on the ooseq list */
+static int tcp_oos_count(struct tcp_pcb* pcb)
+{
+  int num = 0;
+  struct tcp_seg* seg = pcb->ooseq;
+  while(seg != NULL) {
+    num++;
+    seg = seg->next;
+  }
+  return num;
+}
+
+#if TCP_OOSEQ_MAX_PBUFS && (TCP_OOSEQ_MAX_PBUFS < ((TCP_WND / TCP_MSS) + 1)) && (PBUF_POOL_BUFSIZE >= (TCP_MSS + PBUF_LINK_ENCAPSULATION_HLEN + PBUF_LINK_HLEN + PBUF_IP_HLEN + PBUF_TRANSPORT_HLEN))
+/** Get the numbers of pbufs on the ooseq list */
+static int tcp_oos_pbuf_count(struct tcp_pcb* pcb)
+{
+  int num = 0;
+  struct tcp_seg* seg = pcb->ooseq;
+  while(seg != NULL) {
+    num += pbuf_clen(seg->p);
+    seg = seg->next;
+  }
+  return num;
+}
+#endif
+
+/** Get the seqno of a segment (by index) on the ooseq list
+ *
+ * @param pcb the pcb to check for ooseq segments
+ * @param seg_index index of the segment on the ooseq list
+ * @return seqno of the segment
+ */
+static u32_t
+tcp_oos_seg_seqno(struct tcp_pcb* pcb, int seg_index)
+{
+  int num = 0;
+  struct tcp_seg* seg = pcb->ooseq;
+
+  /* then check the actual segment */
+  while(seg != NULL) {
+    if(num == seg_index) {
+      return seg->tcphdr->seqno;
+    }
+    num++;
+    seg = seg->next;
+  }
+  fail();
+  return 0;
+}
+
+/** Get the tcplen (datalen + SYN/FIN) of a segment (by index) on the ooseq list
+ *
+ * @param pcb the pcb to check for ooseq segments
+ * @param seg_index index of the segment on the ooseq list
+ * @return tcplen of the segment
+ */
+static int
+tcp_oos_seg_tcplen(struct tcp_pcb* pcb, int seg_index)
+{
+  int num = 0;
+  struct tcp_seg* seg = pcb->ooseq;
+
+  /* then check the actual segment */
+  while(seg != NULL) {
+    if(num == seg_index) {
+      return TCP_TCPLEN(seg);
+    }
+    num++;
+    seg = seg->next;
+  }
+  fail();
+  return -1;
+}
+
+/** Get the tcplen (datalen + SYN/FIN) of all segments on the ooseq list
+ *
+ * @param pcb the pcb to check for ooseq segments
+ * @return tcplen of all segment
+ */
+static int
+tcp_oos_tcplen(struct tcp_pcb* pcb)
+{
+  int len = 0;
+  struct tcp_seg* seg = pcb->ooseq;
+
+  /* then check the actual segment */
+  while(seg != NULL) {
+    len += TCP_TCPLEN(seg);
+    seg = seg->next;
+  }
+  return len;
+}
+
+/* Setup/teardown functions */
+static struct netif *old_netif_list;
+static struct netif *old_netif_default;
+
+static void
+tcp_oos_setup(void)
+{
+  old_netif_list = netif_list;
+  old_netif_default = netif_default;
+  netif_list = NULL;
+  netif_default = NULL;
+  tcp_remove_all();
+  lwip_check_ensure_no_alloc(SKIP_POOL(MEMP_SYS_TIMEOUT));
+}
+
+static void
+tcp_oos_teardown(void)
+{
+  netif_list = NULL;
+  netif_default = NULL;
+  tcp_remove_all();
+  /* restore netif_list for next tests (e.g. loopif) */
+  netif_list = old_netif_list;
+  netif_default = old_netif_default;
+  lwip_check_ensure_no_alloc(SKIP_POOL(MEMP_SYS_TIMEOUT));
+}
+
+
+
+/* Test functions */
+
+/** create multiple segments and pass them to tcp_input in a wrong
+ * order to see if ooseq-caching works correctly
+ * FIN is received in out-of-sequence segments only */
+START_TEST(test_tcp_recv_ooseq_FIN_OOSEQ)
+{
+  struct test_tcp_counters counters;
+  struct tcp_pcb* pcb;
+  struct pbuf *p_8_9, *p_4_8, *p_4_10, *p_2_14, *p_fin, *pinseq;
+  char data[] = {
+     1,  2,  3,  4,
+     5,  6,  7,  8,
+     9, 10, 11, 12,
+    13, 14, 15, 16};
+  u16_t data_len;
+  struct netif netif;
+  LWIP_UNUSED_ARG(_i);
+
+  /* initialize local vars */
+  test_tcp_init_netif(&netif, NULL, &test_local_ip, &test_netmask);
+  data_len = sizeof(data);
+  /* initialize counter struct */
+  memset(&counters, 0, sizeof(counters));
+  counters.expected_data_len = data_len;
+  counters.expected_data = data;
+
+  /* create and initialize the pcb */
+  pcb = test_tcp_new_counters_pcb(&counters);
+  EXPECT_RET(pcb != NULL);
+  tcp_set_state(pcb, ESTABLISHED, &test_local_ip, &test_remote_ip, TEST_LOCAL_PORT, TEST_REMOTE_PORT);
+
+  /* create segments */
+  /* pinseq is sent as last segment! */
+  pinseq = tcp_create_rx_segment(pcb, &data[0],  4, 0, 0, TCP_ACK);
+  /* p1: 8 bytes before FIN */
+  /*     seqno: 8..16 */
+  p_8_9  = tcp_create_rx_segment(pcb, &data[8],  8, 8, 0, TCP_ACK|TCP_FIN);
+  /* p2: 4 bytes before p1, including the first 4 bytes of p1 (partly duplicate) */
+  /*     seqno: 4..11 */
+  p_4_8  = tcp_create_rx_segment(pcb, &data[4],  8, 4, 0, TCP_ACK);
+  /* p3: same as p2 but 2 bytes longer */
+  /*     seqno: 4..13 */
+  p_4_10 = tcp_create_rx_segment(pcb, &data[4], 10, 4, 0, TCP_ACK);
+  /* p4: 14 bytes before FIN, includes data from p1 and p2, plus partly from pinseq */
+  /*     seqno: 2..15 */
+  p_2_14 = tcp_create_rx_segment(pcb, &data[2], 14, 2, 0, TCP_ACK);
+  /* FIN, seqno 16 */
+  p_fin  = tcp_create_rx_segment(pcb,     NULL,  0,16, 0, TCP_ACK|TCP_FIN);
+  EXPECT(pinseq != NULL);
+  EXPECT(p_8_9 != NULL);
+  EXPECT(p_4_8 != NULL);
+  EXPECT(p_4_10 != NULL);
+  EXPECT(p_2_14 != NULL);
+  EXPECT(p_fin != NULL);
+  if ((pinseq != NULL) && (p_8_9 != NULL) && (p_4_8 != NULL) && (p_4_10 != NULL) && (p_2_14 != NULL) && (p_fin != NULL)) {
+    /* pass the segment to tcp_input */
+    test_tcp_input(p_8_9, &netif);
+    /* check if counters are as expected */
+    EXPECT(counters.close_calls == 0);
+    EXPECT(counters.recv_calls == 0);
+    EXPECT(counters.recved_bytes == 0);
+    EXPECT(counters.err_calls == 0);
+    /* check ooseq queue */
+    EXPECT_OOSEQ(tcp_oos_count(pcb) == 1);
+    EXPECT_OOSEQ(tcp_oos_seg_seqno(pcb, 0) == 8);
+    EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb, 0) == 9); /* includes FIN */
+
+    /* pass the segment to tcp_input */
+    test_tcp_input(p_4_8, &netif);
+    /* check if counters are as expected */
+    EXPECT(counters.close_calls == 0);
+    EXPECT(counters.recv_calls == 0);
+    EXPECT(counters.recved_bytes == 0);
+    EXPECT(counters.err_calls == 0);
+    /* check ooseq queue */
+    EXPECT_OOSEQ(tcp_oos_count(pcb) == 2);
+    EXPECT_OOSEQ(tcp_oos_seg_seqno(pcb, 0) == 4);
+    EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb, 0) == 4);
+    EXPECT_OOSEQ(tcp_oos_seg_seqno(pcb, 1) == 8);
+    EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb, 1) == 9); /* includes FIN */
+
+    /* pass the segment to tcp_input */
+    test_tcp_input(p_4_10, &netif);
+    /* check if counters are as expected */
+    EXPECT(counters.close_calls == 0);
+    EXPECT(counters.recv_calls == 0);
+    EXPECT(counters.recved_bytes == 0);
+    EXPECT(counters.err_calls == 0);
+    /* ooseq queue: unchanged */
+    EXPECT_OOSEQ(tcp_oos_count(pcb) == 2);
+    EXPECT_OOSEQ(tcp_oos_seg_seqno(pcb, 0) == 4);
+    EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb, 0) == 4);
+    EXPECT_OOSEQ(tcp_oos_seg_seqno(pcb, 1) == 8);
+    EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb, 1) == 9); /* includes FIN */
+
+    /* pass the segment to tcp_input */
+    test_tcp_input(p_2_14, &netif);
+    /* check if counters are as expected */
+    EXPECT(counters.close_calls == 0);
+    EXPECT(counters.recv_calls == 0);
+    EXPECT(counters.recved_bytes == 0);
+    EXPECT(counters.err_calls == 0);
+    /* check ooseq queue */
+    EXPECT_OOSEQ(tcp_oos_count(pcb) == 1);
+    EXPECT_OOSEQ(tcp_oos_seg_seqno(pcb, 0) == 2);
+    EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb, 0) == 15); /* includes FIN */
+
+    /* pass the segment to tcp_input */
+    test_tcp_input(p_fin, &netif);
+    /* check if counters are as expected */
+    EXPECT(counters.close_calls == 0);
+    EXPECT(counters.recv_calls == 0);
+    EXPECT(counters.recved_bytes == 0);
+    EXPECT(counters.err_calls == 0);
+    /* ooseq queue: unchanged */
+    EXPECT_OOSEQ(tcp_oos_count(pcb) == 1);
+    EXPECT_OOSEQ(tcp_oos_seg_seqno(pcb, 0) == 2);
+    EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb, 0) == 15); /* includes FIN */
+
+    /* pass the segment to tcp_input */
+    test_tcp_input(pinseq, &netif);
+    /* check if counters are as expected */
+    EXPECT(counters.close_calls == 1);
+    EXPECT(counters.recv_calls == 1);
+    EXPECT(counters.recved_bytes == data_len);
+    EXPECT(counters.err_calls == 0);
+    EXPECT(pcb->ooseq == NULL);
+  }
+
+  /* make sure the pcb is freed */
+  EXPECT(MEMP_STATS_GET(used, MEMP_TCP_PCB) == 1);
+  tcp_abort(pcb);
+  EXPECT(MEMP_STATS_GET(used, MEMP_TCP_PCB) == 0);
+}
+END_TEST
+
+
+/** create multiple segments and pass them to tcp_input in a wrong
+ * order to see if ooseq-caching works correctly
+ * FIN is received IN-SEQUENCE at the end */
+START_TEST(test_tcp_recv_ooseq_FIN_INSEQ)
+{
+  struct test_tcp_counters counters;
+  struct tcp_pcb* pcb;
+  struct pbuf *p_1_2, *p_4_8, *p_3_11, *p_2_12, *p_15_1, *p_15_1a, *pinseq, *pinseqFIN;
+  char data[] = {
+     1,  2,  3,  4,
+     5,  6,  7,  8,
+     9, 10, 11, 12,
+    13, 14, 15, 16};
+  u16_t data_len;
+  struct netif netif;
+  LWIP_UNUSED_ARG(_i);
+
+  /* initialize local vars */
+  test_tcp_init_netif(&netif, NULL, &test_local_ip, &test_netmask);
+  data_len = sizeof(data);
+  /* initialize counter struct */
+  memset(&counters, 0, sizeof(counters));
+  counters.expected_data_len = data_len;
+  counters.expected_data = data;
+
+  /* create and initialize the pcb */
+  pcb = test_tcp_new_counters_pcb(&counters);
+  EXPECT_RET(pcb != NULL);
+  tcp_set_state(pcb, ESTABLISHED, &test_local_ip, &test_remote_ip, TEST_LOCAL_PORT, TEST_REMOTE_PORT);
+
+  /* create segments */
+  /* p1: 7 bytes - 2 before FIN */
+  /*     seqno: 1..2 */
+  p_1_2  = tcp_create_rx_segment(pcb, &data[1],  2, 1, 0, TCP_ACK);
+  /* p2: 4 bytes before p1, including the first 4 bytes of p1 (partly duplicate) */
+  /*     seqno: 4..11 */
+  p_4_8  = tcp_create_rx_segment(pcb, &data[4],  8, 4, 0, TCP_ACK);
+  /* p3: same as p2 but 2 bytes longer and one byte more at the front */
+  /*     seqno: 3..13 */
+  p_3_11 = tcp_create_rx_segment(pcb, &data[3], 11, 3, 0, TCP_ACK);
+  /* p4: 13 bytes - 2 before FIN - should be ignored as contained in p1 and p3 */
+  /*     seqno: 2..13 */
+  p_2_12 = tcp_create_rx_segment(pcb, &data[2], 12, 2, 0, TCP_ACK);
+  /* pinseq is the first segment that is held back to create ooseq! */
+  /*     seqno: 0..3 */
+  pinseq = tcp_create_rx_segment(pcb, &data[0],  4, 0, 0, TCP_ACK);
+  /* p5: last byte before FIN */
+  /*     seqno: 15 */
+  p_15_1 = tcp_create_rx_segment(pcb, &data[15], 1, 15, 0, TCP_ACK);
+  /* p6: same as p5, should be ignored */
+  p_15_1a= tcp_create_rx_segment(pcb, &data[15], 1, 15, 0, TCP_ACK);
+  /* pinseqFIN: last 2 bytes plus FIN */
+  /*     only segment containing seqno 14 and FIN */
+  pinseqFIN = tcp_create_rx_segment(pcb,  &data[14], 2, 14, 0, TCP_ACK|TCP_FIN);
+  EXPECT(pinseq != NULL);
+  EXPECT(p_1_2 != NULL);
+  EXPECT(p_4_8 != NULL);
+  EXPECT(p_3_11 != NULL);
+  EXPECT(p_2_12 != NULL);
+  EXPECT(p_15_1 != NULL);
+  EXPECT(p_15_1a != NULL);
+  EXPECT(pinseqFIN != NULL);
+  if ((pinseq != NULL) && (p_1_2 != NULL) && (p_4_8 != NULL) && (p_3_11 != NULL) && (p_2_12 != NULL)
+    && (p_15_1 != NULL) && (p_15_1a != NULL) && (pinseqFIN != NULL)) {
+    /* pass the segment to tcp_input */
+    test_tcp_input(p_1_2, &netif);
+    /* check if counters are as expected */
+    EXPECT(counters.close_calls == 0);
+    EXPECT(counters.recv_calls == 0);
+    EXPECT(counters.recved_bytes == 0);
+    EXPECT(counters.err_calls == 0);
+    /* check ooseq queue */
+    EXPECT_OOSEQ(tcp_oos_count(pcb) == 1);
+    EXPECT_OOSEQ(tcp_oos_seg_seqno(pcb, 0) == 1);
+    EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb, 0) == 2);
+
+    /* pass the segment to tcp_input */
+    test_tcp_input(p_4_8, &netif);
+    /* check if counters are as expected */
+    EXPECT(counters.close_calls == 0);
+    EXPECT(counters.recv_calls == 0);
+    EXPECT(counters.recved_bytes == 0);
+    EXPECT(counters.err_calls == 0);
+    /* check ooseq queue */
+    EXPECT_OOSEQ(tcp_oos_count(pcb) == 2);
+    EXPECT_OOSEQ(tcp_oos_seg_seqno(pcb, 0) == 1);
+    EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb, 0) == 2);
+    EXPECT_OOSEQ(tcp_oos_seg_seqno(pcb, 1) == 4);
+    EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb, 1) == 8);
+
+    /* pass the segment to tcp_input */
+    test_tcp_input(p_3_11, &netif);
+    /* check if counters are as expected */
+    EXPECT(counters.close_calls == 0);
+    EXPECT(counters.recv_calls == 0);
+    EXPECT(counters.recved_bytes == 0);
+    EXPECT(counters.err_calls == 0);
+    /* check ooseq queue */
+    EXPECT_OOSEQ(tcp_oos_count(pcb) == 2);
+    EXPECT_OOSEQ(tcp_oos_seg_seqno(pcb, 0) == 1);
+    EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb, 0) == 2);
+    /* p_3_11 has removed p_4_8 from ooseq */
+    EXPECT_OOSEQ(tcp_oos_seg_seqno(pcb, 1) == 3);
+    EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb, 1) == 11);
+
+    /* pass the segment to tcp_input */
+    test_tcp_input(p_2_12, &netif);
+    /* check if counters are as expected */
+    EXPECT(counters.close_calls == 0);
+    EXPECT(counters.recv_calls == 0);
+    EXPECT(counters.recved_bytes == 0);
+    EXPECT(counters.err_calls == 0);
+    /* check ooseq queue */
+    EXPECT_OOSEQ(tcp_oos_count(pcb) == 2);
+    EXPECT_OOSEQ(tcp_oos_seg_seqno(pcb, 0) == 1);
+    EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb, 0) == 1);
+    EXPECT_OOSEQ(tcp_oos_seg_seqno(pcb, 1) == 2);
+    EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb, 1) == 12);
+
+    /* pass the segment to tcp_input */
+    test_tcp_input(pinseq, &netif);
+    /* check if counters are as expected */
+    EXPECT(counters.close_calls == 0);
+    EXPECT(counters.recv_calls == 1);
+    EXPECT(counters.recved_bytes == 14);
+    EXPECT(counters.err_calls == 0);
+    EXPECT(pcb->ooseq == NULL);
+
+    /* pass the segment to tcp_input */
+    test_tcp_input(p_15_1, &netif);
+    /* check if counters are as expected */
+    EXPECT(counters.close_calls == 0);
+    EXPECT(counters.recv_calls == 1);
+    EXPECT(counters.recved_bytes == 14);
+    EXPECT(counters.err_calls == 0);
+    /* check ooseq queue */
+    EXPECT_OOSEQ(tcp_oos_count(pcb) == 1);
+    EXPECT_OOSEQ(tcp_oos_seg_seqno(pcb, 0) == 15);
+    EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb, 0) == 1);
+
+    /* pass the segment to tcp_input */
+    test_tcp_input(p_15_1a, &netif);
+    /* check if counters are as expected */
+    EXPECT(counters.close_calls == 0);
+    EXPECT(counters.recv_calls == 1);
+    EXPECT(counters.recved_bytes == 14);
+    EXPECT(counters.err_calls == 0);
+    /* check ooseq queue: unchanged */
+    EXPECT_OOSEQ(tcp_oos_count(pcb) == 1);
+    EXPECT_OOSEQ(tcp_oos_seg_seqno(pcb, 0) == 15);
+    EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb, 0) == 1);
+
+    /* pass the segment to tcp_input */
+    test_tcp_input(pinseqFIN, &netif);
+    /* check if counters are as expected */
+    EXPECT(counters.close_calls == 1);
+    EXPECT(counters.recv_calls == 2);
+    EXPECT(counters.recved_bytes == data_len);
+    EXPECT(counters.err_calls == 0);
+    EXPECT(pcb->ooseq == NULL);
+  }
+
+  /* make sure the pcb is freed */
+  EXPECT(MEMP_STATS_GET(used, MEMP_TCP_PCB) == 1);
+  tcp_abort(pcb);
+  EXPECT(MEMP_STATS_GET(used, MEMP_TCP_PCB) == 0);
+}
+END_TEST
+
+static char data_full_wnd[TCP_WND + TCP_MSS];
+
+/** create multiple segments and pass them to tcp_input with the first segment missing
+ * to simulate overruning the rxwin with ooseq queueing enabled */
+START_TEST(test_tcp_recv_ooseq_overrun_rxwin)
+{
+#if !TCP_OOSEQ_MAX_BYTES && !TCP_OOSEQ_MAX_PBUFS
+  int i, k;
+  struct test_tcp_counters counters;
+  struct tcp_pcb* pcb;
+  struct pbuf *pinseq, *p_ovr;
+  struct netif netif;
+  int datalen = 0;
+  int datalen2;
+
+  for(i = 0; i < (int)sizeof(data_full_wnd); i++) {
+    data_full_wnd[i] = (char)i;
+  }
+
+  /* initialize local vars */
+  test_tcp_init_netif(&netif, NULL, &test_local_ip, &test_netmask);
+  /* initialize counter struct */
+  memset(&counters, 0, sizeof(counters));
+  counters.expected_data_len = TCP_WND;
+  counters.expected_data = data_full_wnd;
+
+  /* create and initialize the pcb */
+  pcb = test_tcp_new_counters_pcb(&counters);
+  EXPECT_RET(pcb != NULL);
+  tcp_set_state(pcb, ESTABLISHED, &test_local_ip, &test_remote_ip, TEST_LOCAL_PORT, TEST_REMOTE_PORT);
+  pcb->rcv_nxt = 0x8000;
+
+  /* create segments */
+  /* pinseq is sent as last segment! */
+  pinseq = tcp_create_rx_segment(pcb, &data_full_wnd[0],  TCP_MSS, 0, 0, TCP_ACK);
+
+  for(i = TCP_MSS, k = 0; i < TCP_WND; i += TCP_MSS, k++) {
+    int count, expected_datalen;
+    struct pbuf *p = tcp_create_rx_segment(pcb, &data_full_wnd[TCP_MSS*(k+1)],
+                                           TCP_MSS, TCP_MSS*(k+1), 0, TCP_ACK);
+    EXPECT_RET(p != NULL);
+    /* pass the segment to tcp_input */
+    test_tcp_input(p, &netif);
+    /* check if counters are as expected */
+    EXPECT(counters.close_calls == 0);
+    EXPECT(counters.recv_calls == 0);
+    EXPECT(counters.recved_bytes == 0);
+    EXPECT(counters.err_calls == 0);
+    /* check ooseq queue */
+    count = tcp_oos_count(pcb);
+    EXPECT_OOSEQ(count == k+1);
+    datalen = tcp_oos_tcplen(pcb);
+    if (i + TCP_MSS < TCP_WND) {
+      expected_datalen = (k+1)*TCP_MSS;
+    } else {
+      expected_datalen = TCP_WND - TCP_MSS;
+    }
+    if (datalen != expected_datalen) {
+      EXPECT_OOSEQ(datalen == expected_datalen);
+    }
+  }
+
+  /* pass in one more segment, cleary overrunning the rxwin */
+  p_ovr = tcp_create_rx_segment(pcb, &data_full_wnd[TCP_MSS*(k+1)], TCP_MSS, TCP_MSS*(k+1), 0, TCP_ACK);
+  EXPECT_RET(p_ovr != NULL);
+  /* pass the segment to tcp_input */
+  test_tcp_input(p_ovr, &netif);
+  /* check if counters are as expected */
+  EXPECT(counters.close_calls == 0);
+  EXPECT(counters.recv_calls == 0);
+  EXPECT(counters.recved_bytes == 0);
+  EXPECT(counters.err_calls == 0);
+  /* check ooseq queue */
+  EXPECT_OOSEQ(tcp_oos_count(pcb) == k);
+  datalen2 = tcp_oos_tcplen(pcb);
+  EXPECT_OOSEQ(datalen == datalen2);
+
+  /* now pass inseq */
+  test_tcp_input(pinseq, &netif);
+  EXPECT(pcb->ooseq == NULL);
+
+  /* make sure the pcb is freed */
+  EXPECT(MEMP_STATS_GET(used, MEMP_TCP_PCB) == 1);
+  tcp_abort(pcb);
+  EXPECT(MEMP_STATS_GET(used, MEMP_TCP_PCB) == 0);
+#endif /* !TCP_OOSEQ_MAX_BYTES && !TCP_OOSEQ_MAX_PBUFS */
+  LWIP_UNUSED_ARG(_i);
+}
+END_TEST
+
+/** similar to above test, except seqno starts near the max rxwin */
+START_TEST(test_tcp_recv_ooseq_overrun_rxwin_edge)
+{
+#if !TCP_OOSEQ_MAX_BYTES && !TCP_OOSEQ_MAX_PBUFS
+  int i, k;
+  struct test_tcp_counters counters;
+  struct tcp_pcb* pcb;
+  struct pbuf *pinseq, *p_ovr;
+  struct netif netif;
+  int datalen = 0;
+  int datalen2;
+
+  for(i = 0; i < (int)sizeof(data_full_wnd); i++) {
+    data_full_wnd[i] = (char)i;
+  }
+
+  /* initialize local vars */
+  test_tcp_init_netif(&netif, NULL, &test_local_ip, &test_netmask);
+  /* initialize counter struct */
+  memset(&counters, 0, sizeof(counters));
+  counters.expected_data_len = TCP_WND;
+  counters.expected_data = data_full_wnd;
+
+  /* create and initialize the pcb */
+  pcb = test_tcp_new_counters_pcb(&counters);
+  EXPECT_RET(pcb != NULL);
+  tcp_set_state(pcb, ESTABLISHED, &test_local_ip, &test_remote_ip, TEST_LOCAL_PORT, TEST_REMOTE_PORT);
+  pcb->rcv_nxt = 0xffffffff - (TCP_WND / 2);
+
+  /* create segments */
+  /* pinseq is sent as last segment! */
+  pinseq = tcp_create_rx_segment(pcb, &data_full_wnd[0],  TCP_MSS, 0, 0, TCP_ACK);
+
+  for(i = TCP_MSS, k = 0; i < TCP_WND; i += TCP_MSS, k++) {
+    int count, expected_datalen;
+    struct pbuf *p = tcp_create_rx_segment(pcb, &data_full_wnd[TCP_MSS*(k+1)],
+                                           TCP_MSS, TCP_MSS*(k+1), 0, TCP_ACK);
+    EXPECT_RET(p != NULL);
+    /* pass the segment to tcp_input */
+    test_tcp_input(p, &netif);
+    /* check if counters are as expected */
+    EXPECT(counters.close_calls == 0);
+    EXPECT(counters.recv_calls == 0);
+    EXPECT(counters.recved_bytes == 0);
+    EXPECT(counters.err_calls == 0);
+    /* check ooseq queue */
+    count = tcp_oos_count(pcb);
+    EXPECT_OOSEQ(count == k+1);
+    datalen = tcp_oos_tcplen(pcb);
+    if (i + TCP_MSS < TCP_WND) {
+      expected_datalen = (k+1)*TCP_MSS;
+    } else {
+      expected_datalen = TCP_WND - TCP_MSS;
+    }
+    if (datalen != expected_datalen) {
+      EXPECT_OOSEQ(datalen == expected_datalen);
+    }
+  }
+
+  /* pass in one more segment, cleary overrunning the rxwin */
+  p_ovr = tcp_create_rx_segment(pcb, &data_full_wnd[TCP_MSS*(k+1)], TCP_MSS, TCP_MSS*(k+1), 0, TCP_ACK);
+  EXPECT_RET(p_ovr != NULL);
+  /* pass the segment to tcp_input */
+  test_tcp_input(p_ovr, &netif);
+  /* check if counters are as expected */
+  EXPECT(counters.close_calls == 0);
+  EXPECT(counters.recv_calls == 0);
+  EXPECT(counters.recved_bytes == 0);
+  EXPECT(counters.err_calls == 0);
+  /* check ooseq queue */
+  EXPECT_OOSEQ(tcp_oos_count(pcb) == k);
+  datalen2 = tcp_oos_tcplen(pcb);
+  EXPECT_OOSEQ(datalen == datalen2);
+
+  /* now pass inseq */
+  test_tcp_input(pinseq, &netif);
+  EXPECT(pcb->ooseq == NULL);
+
+  /* make sure the pcb is freed */
+  EXPECT(MEMP_STATS_GET(used, MEMP_TCP_PCB) == 1);
+  tcp_abort(pcb);
+  EXPECT(MEMP_STATS_GET(used, MEMP_TCP_PCB) == 0);
+#endif /* !TCP_OOSEQ_MAX_BYTES && !TCP_OOSEQ_MAX_PBUFS */
+  LWIP_UNUSED_ARG(_i);
+}
+END_TEST
+
+START_TEST(test_tcp_recv_ooseq_max_bytes)
+{
+#if TCP_OOSEQ_MAX_BYTES && (TCP_OOSEQ_MAX_BYTES < (TCP_WND + 1)) && (PBUF_POOL_BUFSIZE >= (TCP_MSS + PBUF_LINK_ENCAPSULATION_HLEN + PBUF_LINK_HLEN + PBUF_IP_HLEN + PBUF_TRANSPORT_HLEN))
+  int i, k;
+  struct test_tcp_counters counters;
+  struct tcp_pcb* pcb;
+  struct pbuf *p_ovr;
+  struct netif netif;
+  int datalen = 0;
+  int datalen2;
+
+  for(i = 0; i < sizeof(data_full_wnd); i++) {
+    data_full_wnd[i] = (char)i;
+  }
+
+  /* initialize local vars */
+  test_tcp_init_netif(&netif, NULL, &test_local_ip, &test_netmask);
+  /* initialize counter struct */
+  memset(&counters, 0, sizeof(counters));
+  counters.expected_data_len = TCP_WND;
+  counters.expected_data = data_full_wnd;
+
+  /* create and initialize the pcb */
+  pcb = test_tcp_new_counters_pcb(&counters);
+  EXPECT_RET(pcb != NULL);
+  tcp_set_state(pcb, ESTABLISHED, &test_local_ip, &test_remote_ip, TEST_LOCAL_PORT, TEST_REMOTE_PORT);
+  pcb->rcv_nxt = 0x8000;
+
+  /* don't 'recv' the first segment (1 byte) so that all other segments will be ooseq */
+
+  /* create segments and 'recv' them */
+  for(k = 1, i = 1; k < TCP_OOSEQ_MAX_BYTES; k += TCP_MSS, i++) {
+    int count;
+    struct pbuf *p = tcp_create_rx_segment(pcb, &data_full_wnd[k],
+                                           TCP_MSS, k, 0, TCP_ACK);
+    EXPECT_RET(p != NULL);
+    EXPECT_RET(p->next == NULL);
+    /* pass the segment to tcp_input */
+    test_tcp_input(p, &netif);
+    /* check if counters are as expected */
+    EXPECT(counters.close_calls == 0);
+    EXPECT(counters.recv_calls == 0);
+    EXPECT(counters.recved_bytes == 0);
+    EXPECT(counters.err_calls == 0);
+    /* check ooseq queue */
+    count = tcp_oos_pbuf_count(pcb);
+    EXPECT_OOSEQ(count == i);
+    datalen = tcp_oos_tcplen(pcb);
+    EXPECT_OOSEQ(datalen == (i * TCP_MSS));
+  }
+
+  /* pass in one more segment, overrunning the limit */
+  p_ovr = tcp_create_rx_segment(pcb, &data_full_wnd[k+1], 1, k+1, 0, TCP_ACK);
+  EXPECT_RET(p_ovr != NULL);
+  /* pass the segment to tcp_input */
+  test_tcp_input(p_ovr, &netif);
+  /* check if counters are as expected */
+  EXPECT(counters.close_calls == 0);
+  EXPECT(counters.recv_calls == 0);
+  EXPECT(counters.recved_bytes == 0);
+  EXPECT(counters.err_calls == 0);
+  /* check ooseq queue (ensure the new segment was not accepted) */
+  EXPECT_OOSEQ(tcp_oos_count(pcb) == (i-1));
+  datalen2 = tcp_oos_tcplen(pcb);
+  EXPECT_OOSEQ(datalen2 == ((i-1) * TCP_MSS));
+
+  /* make sure the pcb is freed */
+  EXPECT(MEMP_STATS_GET(used, MEMP_TCP_PCB) == 1);
+  tcp_abort(pcb);
+  EXPECT(MEMP_STATS_GET(used, MEMP_TCP_PCB) == 0);
+#endif /* TCP_OOSEQ_MAX_BYTES && (TCP_OOSEQ_MAX_BYTES < (TCP_WND + 1)) && (PBUF_POOL_BUFSIZE >= (TCP_MSS + PBUF_LINK_ENCAPSULATION_HLEN + PBUF_LINK_HLEN + PBUF_IP_HLEN + PBUF_TRANSPORT_HLEN)) */
+  LWIP_UNUSED_ARG(_i);
+}
+END_TEST
+
+START_TEST(test_tcp_recv_ooseq_max_pbufs)
+{
+#if TCP_OOSEQ_MAX_PBUFS && (TCP_OOSEQ_MAX_PBUFS < ((TCP_WND / TCP_MSS) + 1)) && (PBUF_POOL_BUFSIZE >= (TCP_MSS + PBUF_LINK_ENCAPSULATION_HLEN + PBUF_LINK_HLEN + PBUF_IP_HLEN + PBUF_TRANSPORT_HLEN))
+  int i;
+  struct test_tcp_counters counters;
+  struct tcp_pcb* pcb;
+  struct pbuf *p_ovr;
+  struct netif netif;
+  int datalen = 0;
+  int datalen2;
+
+  for(i = 0; i < sizeof(data_full_wnd); i++) {
+    data_full_wnd[i] = (char)i;
+  }
+
+  /* initialize local vars */
+  test_tcp_init_netif(&netif, NULL, &test_local_ip, &test_netmask);
+  /* initialize counter struct */
+  memset(&counters, 0, sizeof(counters));
+  counters.expected_data_len = TCP_WND;
+  counters.expected_data = data_full_wnd;
+
+  /* create and initialize the pcb */
+  pcb = test_tcp_new_counters_pcb(&counters);
+  EXPECT_RET(pcb != NULL);
+  tcp_set_state(pcb, ESTABLISHED, &local_ip, &remote_ip, TEST_LOCAL_PORT, TEST_REMOTE_PORT);
+  pcb->rcv_nxt = 0x8000;
+
+  /* don't 'recv' the first segment (1 byte) so that all other segments will be ooseq */
+
+  /* create segments and 'recv' them */
+  for(i = 1; i <= TCP_OOSEQ_MAX_PBUFS; i++) {
+    int count;
+    struct pbuf *p = tcp_create_rx_segment(pcb, &data_full_wnd[i],
+                                           1, i, 0, TCP_ACK);
+    EXPECT_RET(p != NULL);
+    EXPECT_RET(p->next == NULL);
+    /* pass the segment to tcp_input */
+    test_tcp_input(p, &netif);
+    /* check if counters are as expected */
+    EXPECT(counters.close_calls == 0);
+    EXPECT(counters.recv_calls == 0);
+    EXPECT(counters.recved_bytes == 0);
+    EXPECT(counters.err_calls == 0);
+    /* check ooseq queue */
+    count = tcp_oos_pbuf_count(pcb);
+    EXPECT_OOSEQ(count == i);
+    datalen = tcp_oos_tcplen(pcb);
+    EXPECT_OOSEQ(datalen == i);
+  }
+
+  /* pass in one more segment, overrunning the limit */
+  p_ovr = tcp_create_rx_segment(pcb, &data_full_wnd[i+1], 1, i+1, 0, TCP_ACK);
+  EXPECT_RET(p_ovr != NULL);
+  /* pass the segment to tcp_input */
+  test_tcp_input(p_ovr, &netif);
+  /* check if counters are as expected */
+  EXPECT(counters.close_calls == 0);
+  EXPECT(counters.recv_calls == 0);
+  EXPECT(counters.recved_bytes == 0);
+  EXPECT(counters.err_calls == 0);
+  /* check ooseq queue (ensure the new segment was not accepted) */
+  EXPECT_OOSEQ(tcp_oos_count(pcb) == (i-1));
+  datalen2 = tcp_oos_tcplen(pcb);
+  EXPECT_OOSEQ(datalen2 == (i-1));
+
+  /* make sure the pcb is freed */
+  EXPECT(MEMP_STATS_GET(used, MEMP_TCP_PCB) == 1);
+  tcp_abort(pcb);
+  EXPECT(MEMP_STATS_GET(used, MEMP_TCP_PCB) == 0);
+#endif /* TCP_OOSEQ_MAX_PBUFS && (TCP_OOSEQ_MAX_BYTES < (TCP_WND + 1)) && (PBUF_POOL_BUFSIZE >= (TCP_MSS + PBUF_LINK_ENCAPSULATION_HLEN + PBUF_LINK_HLEN + PBUF_IP_HLEN + PBUF_TRANSPORT_HLEN)) */
+  LWIP_UNUSED_ARG(_i);
+}
+END_TEST
+
+static void
+check_rx_counters(struct tcp_pcb *pcb, struct test_tcp_counters *counters, u32_t exp_close_calls, u32_t exp_rx_calls,
+                  u32_t exp_rx_bytes, u32_t exp_err_calls, int exp_oos_count, int exp_oos_len)
+{
+  int oos_len;
+  EXPECT(counters->close_calls == exp_close_calls);
+  EXPECT(counters->recv_calls == exp_rx_calls);
+  EXPECT(counters->recved_bytes == exp_rx_bytes);
+  EXPECT(counters->err_calls == exp_err_calls);
+  /* check that pbuf is queued in ooseq */
+  EXPECT_OOSEQ(tcp_oos_count(pcb) == exp_oos_count);
+  oos_len = tcp_oos_tcplen(pcb);
+  EXPECT_OOSEQ(exp_oos_len == oos_len);
+}
+
+/* this test uses 4 packets:
+ * - data (len=TCP_MSS)
+ * - FIN
+ * - data after FIN (len=1) (invalid)
+ * - 2nd FIN (invalid)
+ *
+ * the parameter 'delay_packet' is a bitmask that choses which on these packets is ooseq
+ */
+static void test_tcp_recv_ooseq_double_FINs(int delay_packet)
+{
+  int i, k;
+  struct test_tcp_counters counters;
+  struct tcp_pcb* pcb;
+  struct pbuf *p_normal_fin, *p_data_after_fin, *p, *p_2nd_fin_ooseq;
+  struct netif netif;
+  u32_t exp_rx_calls = 0, exp_rx_bytes = 0, exp_close_calls = 0, exp_oos_pbufs = 0, exp_oos_tcplen = 0;
+  int first_dropped = 0xff;
+
+  for(i = 0; i < (int)sizeof(data_full_wnd); i++) {
+    data_full_wnd[i] = (char)i;
+  }
+
+  /* initialize local vars */
+  test_tcp_init_netif(&netif, NULL, &test_local_ip, &test_netmask);
+  /* initialize counter struct */
+  memset(&counters, 0, sizeof(counters));
+  counters.expected_data_len = TCP_WND;
+  counters.expected_data = data_full_wnd;
+
+  /* create and initialize the pcb */
+  pcb = test_tcp_new_counters_pcb(&counters);
+  EXPECT_RET(pcb != NULL);
+  tcp_set_state(pcb, ESTABLISHED, &test_local_ip, &test_remote_ip, TEST_LOCAL_PORT, TEST_REMOTE_PORT);
+  pcb->rcv_nxt = 0x8000;
+
+  /* create segments */
+  p = tcp_create_rx_segment(pcb, &data_full_wnd[0], TCP_MSS, 0, 0, TCP_ACK);
+  p_normal_fin = tcp_create_rx_segment(pcb, NULL, 0, TCP_MSS, 0, TCP_ACK|TCP_FIN);
+  k = 1;
+  p_data_after_fin = tcp_create_rx_segment(pcb, &data_full_wnd[TCP_MSS+1], k, TCP_MSS+1, 0, TCP_ACK);
+  p_2nd_fin_ooseq = tcp_create_rx_segment(pcb, NULL, 0, TCP_MSS+1+k, 0, TCP_ACK|TCP_FIN);
+
+  if(delay_packet & 1) {
+    /* drop normal data */
+    first_dropped = 1;
+  } else {
+    /* send normal data */
+    test_tcp_input(p, &netif);
+    exp_rx_calls++;
+    exp_rx_bytes += TCP_MSS;
+  }
+  /* check if counters are as expected */
+  check_rx_counters(pcb, &counters, exp_close_calls, exp_rx_calls, exp_rx_bytes, 0, exp_oos_pbufs, exp_oos_tcplen);
+
+  if(delay_packet & 2) {
+    /* drop FIN */
+    if(first_dropped > 2) {
+      first_dropped = 2;
+    }
+  } else {
+    /* send FIN */
+    test_tcp_input(p_normal_fin, &netif);
+    if (first_dropped < 2) {
+      /* already dropped packets, this one is ooseq */
+      exp_oos_pbufs++;
+      exp_oos_tcplen++;
+    } else {
+      /* inseq */
+      exp_close_calls++;
+    }
+  }
+  /* check if counters are as expected */
+  check_rx_counters(pcb, &counters, exp_close_calls, exp_rx_calls, exp_rx_bytes, 0, exp_oos_pbufs, exp_oos_tcplen);
+
+  if(delay_packet & 4) {
+    /* drop data-after-FIN */
+    if(first_dropped > 3) {
+      first_dropped = 3;
+    }
+  } else {
+    /* send data-after-FIN */
+    test_tcp_input(p_data_after_fin, &netif);
+    if (first_dropped < 3) {
+      /* already dropped packets, this one is ooseq */
+      if (delay_packet & 2) {
+        /* correct FIN was ooseq */
+        exp_oos_pbufs++;
+        exp_oos_tcplen += k;
+      }
+    } else {
+      /* inseq: no change */
+    }
+  }
+  /* check if counters are as expected */
+  check_rx_counters(pcb, &counters, exp_close_calls, exp_rx_calls, exp_rx_bytes, 0, exp_oos_pbufs, exp_oos_tcplen);
+
+  if(delay_packet & 8) {
+    /* drop 2nd-FIN */
+    if(first_dropped > 4) {
+      first_dropped = 4;
+    }
+  } else {
+    /* send 2nd-FIN */
+    test_tcp_input(p_2nd_fin_ooseq, &netif);
+    if (first_dropped < 3) {
+      /* already dropped packets, this one is ooseq */
+      if (delay_packet & 2) {
+        /* correct FIN was ooseq */
+        exp_oos_pbufs++;
+        exp_oos_tcplen++;
+      }
+    } else {
+      /* inseq: no change */
+    }
+  }
+  /* check if counters are as expected */
+  check_rx_counters(pcb, &counters, exp_close_calls, exp_rx_calls, exp_rx_bytes, 0, exp_oos_pbufs, exp_oos_tcplen);
+
+  if(delay_packet & 1) {
+    /* dropped normal data before */
+    test_tcp_input(p, &netif);
+    exp_rx_calls++;
+    exp_rx_bytes += TCP_MSS;
+    if((delay_packet & 2) == 0) {
+      /* normal FIN was NOT delayed */
+      exp_close_calls++;
+      exp_oos_pbufs = exp_oos_tcplen = 0;
+    }
+  }
+  /* check if counters are as expected */
+  check_rx_counters(pcb, &counters, exp_close_calls, exp_rx_calls, exp_rx_bytes, 0, exp_oos_pbufs, exp_oos_tcplen);
+
+  if(delay_packet & 2) {
+    /* dropped normal FIN before */
+    test_tcp_input(p_normal_fin, &netif);
+    exp_close_calls++;
+    exp_oos_pbufs = exp_oos_tcplen = 0;
+  }
+  /* check if counters are as expected */
+  check_rx_counters(pcb, &counters, exp_close_calls, exp_rx_calls, exp_rx_bytes, 0, exp_oos_pbufs, exp_oos_tcplen);
+
+  if(delay_packet & 4) {
+    /* dropped data-after-FIN before */
+    test_tcp_input(p_data_after_fin, &netif);
+  }
+  /* check if counters are as expected */
+  check_rx_counters(pcb, &counters, exp_close_calls, exp_rx_calls, exp_rx_bytes, 0, exp_oos_pbufs, exp_oos_tcplen);
+
+  if(delay_packet & 8) {
+    /* dropped 2nd-FIN before */
+    test_tcp_input(p_2nd_fin_ooseq, &netif);
+  }
+  /* check if counters are as expected */
+  check_rx_counters(pcb, &counters, exp_close_calls, exp_rx_calls, exp_rx_bytes, 0, exp_oos_pbufs, exp_oos_tcplen);
+
+  /* check that ooseq data has been dumped */
+  EXPECT(pcb->ooseq == NULL);
+
+  /* make sure the pcb is freed */
+  EXPECT(MEMP_STATS_GET(used, MEMP_TCP_PCB) == 1);
+  tcp_abort(pcb);
+  EXPECT(MEMP_STATS_GET(used, MEMP_TCP_PCB) == 0);
+}
+
+/** create multiple segments and pass them to tcp_input with the first segment missing
+ * to simulate overruning the rxwin with ooseq queueing enabled */
+#define FIN_TEST(name, num) \
+  START_TEST(name) \
+  { \
+    LWIP_UNUSED_ARG(_i); \
+    test_tcp_recv_ooseq_double_FINs(num); \
+  } \
+  END_TEST
+FIN_TEST(test_tcp_recv_ooseq_double_FIN_0, 0)
+FIN_TEST(test_tcp_recv_ooseq_double_FIN_1, 1)
+FIN_TEST(test_tcp_recv_ooseq_double_FIN_2, 2)
+FIN_TEST(test_tcp_recv_ooseq_double_FIN_3, 3)
+FIN_TEST(test_tcp_recv_ooseq_double_FIN_4, 4)
+FIN_TEST(test_tcp_recv_ooseq_double_FIN_5, 5)
+FIN_TEST(test_tcp_recv_ooseq_double_FIN_6, 6)
+FIN_TEST(test_tcp_recv_ooseq_double_FIN_7, 7)
+FIN_TEST(test_tcp_recv_ooseq_double_FIN_8, 8)
+FIN_TEST(test_tcp_recv_ooseq_double_FIN_9, 9)
+FIN_TEST(test_tcp_recv_ooseq_double_FIN_10, 10)
+FIN_TEST(test_tcp_recv_ooseq_double_FIN_11, 11)
+FIN_TEST(test_tcp_recv_ooseq_double_FIN_12, 12)
+FIN_TEST(test_tcp_recv_ooseq_double_FIN_13, 13)
+FIN_TEST(test_tcp_recv_ooseq_double_FIN_14, 14)
+FIN_TEST(test_tcp_recv_ooseq_double_FIN_15, 15)
+
+
+/** Create the suite including all tests for this module */
+Suite *
+tcp_oos_suite(void)
+{
+  testfunc tests[] = {
+    TESTFUNC(test_tcp_recv_ooseq_FIN_OOSEQ),
+    TESTFUNC(test_tcp_recv_ooseq_FIN_INSEQ),
+    TESTFUNC(test_tcp_recv_ooseq_overrun_rxwin),
+    TESTFUNC(test_tcp_recv_ooseq_overrun_rxwin_edge),
+    TESTFUNC(test_tcp_recv_ooseq_max_bytes),
+    TESTFUNC(test_tcp_recv_ooseq_max_pbufs),
+    TESTFUNC(test_tcp_recv_ooseq_double_FIN_0),
+    TESTFUNC(test_tcp_recv_ooseq_double_FIN_1),
+    TESTFUNC(test_tcp_recv_ooseq_double_FIN_2),
+    TESTFUNC(test_tcp_recv_ooseq_double_FIN_3),
+    TESTFUNC(test_tcp_recv_ooseq_double_FIN_4),
+    TESTFUNC(test_tcp_recv_ooseq_double_FIN_5),
+    TESTFUNC(test_tcp_recv_ooseq_double_FIN_6),
+    TESTFUNC(test_tcp_recv_ooseq_double_FIN_7),
+    TESTFUNC(test_tcp_recv_ooseq_double_FIN_8),
+    TESTFUNC(test_tcp_recv_ooseq_double_FIN_9),
+    TESTFUNC(test_tcp_recv_ooseq_double_FIN_10),
+    TESTFUNC(test_tcp_recv_ooseq_double_FIN_11),
+    TESTFUNC(test_tcp_recv_ooseq_double_FIN_12),
+    TESTFUNC(test_tcp_recv_ooseq_double_FIN_13),
+    TESTFUNC(test_tcp_recv_ooseq_double_FIN_14),
+    TESTFUNC(test_tcp_recv_ooseq_double_FIN_15)
+  };
+  return create_suite("TCP_OOS", tests, sizeof(tests)/sizeof(testfunc), tcp_oos_setup, tcp_oos_teardown);
+}
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/test/unit/tcp/test_tcp_oos.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/test/unit/tcp/test_tcp_oos.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/test/unit/tcp/test_tcp_oos.h	(revision 457)
@@ -0,0 +1,8 @@
+#ifndef LWIP_HDR_TEST_TCP_OOS_H
+#define LWIP_HDR_TEST_TCP_OOS_H
+
+#include "../lwip_check.h"
+
+Suite *tcp_oos_suite(void);
+
+#endif
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/test/unit/udp/test_udp.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/test/unit/udp/test_udp.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/test/unit/udp/test_udp.c	(revision 457)
@@ -0,0 +1,347 @@
+#include "test_udp.h"
+
+#include "lwip/udp.h"
+#include "lwip/stats.h"
+#include "lwip/inet_chksum.h"
+
+#if !LWIP_STATS || !UDP_STATS || !MEMP_STATS
+#error "This tests needs UDP- and MEMP-statistics enabled"
+#endif
+
+struct test_udp_rxdata {
+  u32_t rx_cnt;
+  u32_t rx_bytes;
+  struct udp_pcb *pcb;
+};
+
+static struct netif test_netif1, test_netif2;
+static ip4_addr_t test_gw1, test_ipaddr1, test_netmask1;
+static ip4_addr_t test_gw2, test_ipaddr2, test_netmask2;
+static int output_ctr, linkoutput_ctr;
+
+/* Helper functions */
+static void
+udp_remove_all(void)
+{
+  struct udp_pcb *pcb = udp_pcbs;
+  struct udp_pcb *pcb2;
+
+  while(pcb != NULL) {
+    pcb2 = pcb;
+    pcb = pcb->next;
+    udp_remove(pcb2);
+  }
+  fail_unless(MEMP_STATS_GET(used, MEMP_UDP_PCB) == 0);
+}
+
+static err_t
+default_netif_output(struct netif *netif, struct pbuf *p, const ip4_addr_t *ipaddr)
+{
+  fail_unless((netif == &test_netif1) || (netif == &test_netif2));
+  fail_unless(p != NULL);
+  fail_unless(ipaddr != NULL);
+  output_ctr++;
+  return ERR_OK;
+}
+
+static err_t
+default_netif_linkoutput(struct netif *netif, struct pbuf *p)
+{
+  fail_unless((netif == &test_netif1) || (netif == &test_netif2));
+  fail_unless(p != NULL);
+  linkoutput_ctr++;
+  return ERR_OK;
+}
+
+static err_t
+default_netif_init(struct netif *netif)
+{
+  fail_unless(netif != NULL);
+  netif->output = default_netif_output;
+  netif->linkoutput = default_netif_linkoutput;
+  netif->mtu = 1500;
+  netif->flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP | NETIF_FLAG_LINK_UP;
+  netif->hwaddr_len = 6;
+  return ERR_OK;
+}
+
+static void
+default_netif_add(void)
+{
+  struct netif *n;
+
+#if LWIP_HAVE_LOOPIF
+  fail_unless(netif_list != NULL); /* the loopif */
+  fail_unless(netif_list->next == NULL);
+#else
+  fail_unless(netif_list == NULL);
+#endif
+  fail_unless(netif_default == NULL);
+
+  IP4_ADDR(&test_ipaddr1, 192,168,0,1);
+  IP4_ADDR(&test_netmask1, 255,255,255,0);
+  IP4_ADDR(&test_gw1, 192,168,0,254);
+  n = netif_add(&test_netif1, &test_ipaddr1, &test_netmask1,
+                &test_gw1, NULL, default_netif_init, NULL);
+  fail_unless(n == &test_netif1);
+
+  IP4_ADDR(&test_ipaddr2, 192,168,1,1);
+  IP4_ADDR(&test_netmask2, 255,255,255,0);
+  IP4_ADDR(&test_gw2, 192,168,1,254);
+  n = netif_add(&test_netif2, &test_ipaddr2, &test_netmask2,
+                &test_gw2, NULL, default_netif_init, NULL);
+  fail_unless(n == &test_netif2);
+
+  netif_set_default(&test_netif1);
+  netif_set_up(&test_netif1);
+  netif_set_up(&test_netif2);
+}
+
+static void
+default_netif_remove(void)
+{
+  fail_unless(netif_default == &test_netif1);
+  netif_remove(&test_netif1);
+  netif_remove(&test_netif2);
+  fail_unless(netif_default == NULL);
+#if LWIP_HAVE_LOOPIF
+  fail_unless(netif_list != NULL); /* the loopif */
+  fail_unless(netif_list->next == NULL);
+#else
+  fail_unless(netif_list == NULL);
+#endif
+}
+/* Setups/teardown functions */
+
+static void
+udp_setup(void)
+{
+  udp_remove_all();
+  default_netif_add();
+  lwip_check_ensure_no_alloc(SKIP_POOL(MEMP_SYS_TIMEOUT));
+}
+
+static void
+udp_teardown(void)
+{
+  udp_remove_all();
+  default_netif_remove();
+  lwip_check_ensure_no_alloc(SKIP_POOL(MEMP_SYS_TIMEOUT));
+}
+
+
+/* Test functions */
+
+START_TEST(test_udp_new_remove)
+{
+  struct udp_pcb* pcb;
+  LWIP_UNUSED_ARG(_i);
+
+  fail_unless(MEMP_STATS_GET(used, MEMP_UDP_PCB) == 0);
+
+  pcb = udp_new();
+  fail_unless(pcb != NULL);
+  if (pcb != NULL) {
+    fail_unless(MEMP_STATS_GET(used, MEMP_UDP_PCB) == 1);
+    udp_remove(pcb);
+    fail_unless(MEMP_STATS_GET(used, MEMP_UDP_PCB) == 0);
+  }
+}
+END_TEST
+
+static void test_recv(void *arg, struct udp_pcb *pcb, struct pbuf *p,
+    const ip_addr_t *addr, u16_t port)
+{
+  struct test_udp_rxdata *ctr = (struct test_udp_rxdata *)arg;
+
+  LWIP_UNUSED_ARG(addr);
+  LWIP_UNUSED_ARG(port);
+
+  fail_unless(arg != NULL);
+  fail_unless(ctr->pcb == pcb);
+
+  ctr->rx_cnt++;
+  ctr->rx_bytes += p->tot_len;
+
+  if (p != NULL) {
+    pbuf_free(p);
+  }
+}
+
+static struct pbuf *
+test_udp_create_test_packet(u16_t length, u16_t port, u32_t dst_addr)
+{
+  err_t err;
+  u8_t ret;
+  struct udp_hdr *uh;
+  struct ip_hdr *ih;
+  struct pbuf *p;
+  const u8_t test_data[16] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf};
+
+  p = pbuf_alloc(PBUF_TRANSPORT, length, PBUF_POOL);
+  fail_unless(p != NULL);
+  if (p == NULL) {
+    return NULL;
+  }
+  fail_unless(p->next == NULL);
+  err = pbuf_take(p, test_data, length);
+  fail_unless(err == ERR_OK);
+
+  /* add UDP header */
+  ret = pbuf_add_header(p, sizeof(struct udp_hdr));
+  fail_unless(!ret);
+  uh = (struct udp_hdr *)p->payload;
+  uh->chksum = 0;
+  uh->dest = uh->src = lwip_htons(port);
+  uh->len = lwip_htons(p->tot_len);
+  /* add IPv4 header */
+  ret = pbuf_add_header(p, sizeof(struct ip_hdr));
+  fail_unless(!ret);
+  ih = (struct ip_hdr *)p->payload;
+  memset(ih, 0, sizeof(*ih));
+  ih->dest.addr = dst_addr;
+  ih->_len = lwip_htons(p->tot_len);
+  ih->_ttl = 32;
+  ih->_proto = IP_PROTO_UDP;
+  IPH_VHL_SET(ih, 4, sizeof(struct ip_hdr) / 4);
+  IPH_CHKSUM_SET(ih, inet_chksum(ih, sizeof(struct ip_hdr)));
+  return p;
+}
+
+/* bind 2 pcbs to specific netif IP and test which one gets broadcasts */
+START_TEST(test_udp_broadcast_rx_with_2_netifs)
+{
+  err_t err;
+  struct udp_pcb *pcb1, *pcb2;
+  const u16_t port = 12345;
+  struct test_udp_rxdata ctr1, ctr2;
+  struct pbuf *p;
+#if SO_REUSE
+  struct udp_pcb *pcb_any;
+  struct test_udp_rxdata ctr_any;
+#endif
+  LWIP_UNUSED_ARG(_i);
+
+  pcb1 = udp_new();
+  fail_unless(pcb1 != NULL);
+  pcb2 = udp_new();
+  fail_unless(pcb2 != NULL);
+
+#if SO_REUSE
+  pcb_any = udp_new();
+  fail_unless(pcb_any != NULL);
+
+  ip_set_option(pcb1, SOF_REUSEADDR);
+  ip_set_option(pcb2, SOF_REUSEADDR);
+  ip_set_option(pcb_any, SOF_REUSEADDR);
+
+  err = udp_bind(pcb_any, NULL, port);
+  fail_unless(err == ERR_OK);
+  memset(&ctr_any, 0, sizeof(ctr_any));
+  ctr_any.pcb = pcb_any;
+  udp_recv(pcb_any, test_recv, &ctr_any);
+#endif
+
+  err = udp_bind(pcb1, &test_netif1.ip_addr, port);
+  fail_unless(err == ERR_OK);
+  err = udp_bind(pcb2, &test_netif2.ip_addr, port);
+  fail_unless(err == ERR_OK);
+
+  memset(&ctr1, 0, sizeof(ctr1));
+  ctr1.pcb = pcb1;
+  memset(&ctr2, 0, sizeof(ctr2));
+  ctr2.pcb = pcb2;
+
+  udp_recv(pcb1, test_recv, &ctr1);
+  udp_recv(pcb2, test_recv, &ctr2);
+
+  /* unicast to netif1 */
+  p = test_udp_create_test_packet(16, port, test_ipaddr1.addr);
+  EXPECT_RET(p != NULL);
+  err = ip4_input(p, &test_netif1);
+  fail_unless(err == ERR_OK);
+  fail_unless(ctr1.rx_cnt == 1);
+  fail_unless(ctr1.rx_bytes == 16);
+  fail_unless(ctr2.rx_cnt == 0);
+#if SO_REUSE
+  fail_unless(ctr_any.rx_cnt == 0);
+#endif
+  ctr1.rx_cnt = ctr1.rx_bytes = 0;
+
+  /* unicast to netif2 */
+  p = test_udp_create_test_packet(16, port, test_ipaddr2.addr);
+  EXPECT_RET(p != NULL);
+  err = ip4_input(p, &test_netif2);
+  fail_unless(err == ERR_OK);
+  fail_unless(ctr2.rx_cnt == 1);
+  fail_unless(ctr2.rx_bytes == 16);
+  fail_unless(ctr1.rx_cnt == 0);
+#if SO_REUSE
+  fail_unless(ctr_any.rx_cnt == 0);
+#endif
+  ctr2.rx_cnt = ctr2.rx_bytes = 0;
+
+  /* broadcast to netif1-broadcast, input to netif2 */
+  p = test_udp_create_test_packet(16, port, test_ipaddr1.addr | ~test_netmask1.addr);
+  EXPECT_RET(p != NULL);
+  err = ip4_input(p, &test_netif2);
+  fail_unless(err == ERR_OK);
+  fail_unless(ctr1.rx_cnt == 1);
+  fail_unless(ctr1.rx_bytes == 16);
+  fail_unless(ctr2.rx_cnt == 0);
+#if SO_REUSE
+  fail_unless(ctr_any.rx_cnt == 0);
+#endif
+  ctr1.rx_cnt = ctr1.rx_bytes = 0;
+
+  /* broadcast to netif2-broadcast, input to netif1 */
+  p = test_udp_create_test_packet(16, port, test_ipaddr2.addr | ~test_netmask2.addr);
+  EXPECT_RET(p != NULL);
+  err = ip4_input(p, &test_netif1);
+  fail_unless(err == ERR_OK);
+  fail_unless(ctr2.rx_cnt == 1);
+  fail_unless(ctr2.rx_bytes == 16);
+  fail_unless(ctr1.rx_cnt == 0);
+#if SO_REUSE
+  fail_unless(ctr_any.rx_cnt == 0);
+#endif
+  ctr2.rx_cnt = ctr2.rx_bytes = 0;
+
+  /* broadcast to global-broadcast, input to netif1 */
+  p = test_udp_create_test_packet(16, port, 0xffffffff);
+  EXPECT_RET(p != NULL);
+  err = ip4_input(p, &test_netif1);
+  fail_unless(err == ERR_OK);
+  fail_unless(ctr1.rx_cnt == 1);
+  fail_unless(ctr1.rx_bytes == 16);
+  fail_unless(ctr2.rx_cnt == 0);
+#if SO_REUSE
+  fail_unless(ctr_any.rx_cnt == 0);
+#endif
+  ctr1.rx_cnt = ctr1.rx_bytes = 0;
+
+  /* broadcast to global-broadcast, input to netif2 */
+  p = test_udp_create_test_packet(16, port, 0xffffffff);
+  EXPECT_RET(p != NULL);
+  err = ip4_input(p, &test_netif2);
+  fail_unless(err == ERR_OK);
+  fail_unless(ctr2.rx_cnt == 1);
+  fail_unless(ctr2.rx_bytes == 16);
+  fail_unless(ctr1.rx_cnt == 0);
+#if SO_REUSE
+  fail_unless(ctr_any.rx_cnt == 0);
+#endif
+  ctr2.rx_cnt = ctr2.rx_bytes = 0;
+}
+END_TEST
+
+/** Create the suite including all tests for this module */
+Suite *
+udp_suite(void)
+{
+  testfunc tests[] = {
+    TESTFUNC(test_udp_new_remove),
+    TESTFUNC(test_udp_broadcast_rx_with_2_netifs)
+  };
+  return create_suite("UDP", tests, sizeof(tests)/sizeof(testfunc), udp_setup, udp_teardown);
+}
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/test/unit/udp/test_udp.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/test/unit/udp/test_udp.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/test/unit/udp/test_udp.h	(revision 457)
@@ -0,0 +1,8 @@
+#ifndef LWIP_HDR_TEST_UDP_H
+#define LWIP_HDR_TEST_UDP_H
+
+#include "../lwip_check.h"
+
+Suite* udp_suite(void);
+
+#endif
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip.cfg
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip.cfg	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip.cfg	(revision 457)
@@ -0,0 +1,68 @@
+/*
+ *  @(#) $Id$
+ */
+
+/*
+ *  LWIPミドルウェアのコンフィギュレーションファイル
+ */
+
+#include "lwip.h"
+
+
+CRE_TSK(LWIP_TASK_1, { TA_NULL, 0, lwip_task, LWIP_DEFAULT_PRIORITY, LWIP_STACK_SIZE, NULL });
+CRE_TSK(LWIP_TASK_2, { TA_NULL, 1, lwip_task, LWIP_DEFAULT_PRIORITY, LWIP_STACK_SIZE, NULL });
+CRE_TSK(LWIP_TASK_3, { TA_NULL, 2, lwip_task, LWIP_DEFAULT_PRIORITY, LWIP_STACK_SIZE, NULL });
+CRE_TSK(LWIP_TASK_4, { TA_NULL, 3, lwip_task, LWIP_DEFAULT_PRIORITY, LWIP_STACK_SIZE, NULL });
+CRE_TSK(LWIP_TASK_5, { TA_NULL, 4, lwip_task, LWIP_DEFAULT_PRIORITY, LWIP_STACK_SIZE, NULL });
+CRE_TSK(LWIP_TASK_6, { TA_NULL, 5, lwip_task, LWIP_DEFAULT_PRIORITY, LWIP_STACK_SIZE, NULL });
+CRE_TSK(LWIP_TASK_7, { TA_NULL, 6, lwip_task, LWIP_DEFAULT_PRIORITY, LWIP_STACK_SIZE, NULL });
+CRE_TSK(LWIP_TASK_8, { TA_NULL, 7, lwip_task, LWIP_DEFAULT_PRIORITY, LWIP_STACK_SIZE, NULL });
+CRE_TSK(LWIP_TASK_N, { TA_NULL, 8, lwip_task, LWIP_DEFAULT_PRIORITY, LWIP_STACK_SIZE, NULL });
+
+CRE_SEM(LWIP_PROTECT,  { TA_TPRI, 1, 1 });
+CRE_SEM(LWIP_THREAD,   { TA_TPRI, 1, 1 });
+CRE_SEM(LWIP_SNPRINTF, { TA_TPRI, 1, 1 });
+CRE_SEM(LWIP_LOCK_1, { TA_TPRI, 1, 1 });
+CRE_SEM(LWIP_LOCK_2, { TA_TPRI, 1, 1 });
+CRE_SEM(LWIP_LOCK_3, { TA_TPRI, 1, 1 });
+CRE_SEM(LWIP_LOCK_4, { TA_TPRI, 1, 1 });
+CRE_SEM(LWIP_LOCK_5, { TA_TPRI, 1, 1 });
+CRE_SEM(LWIP_LOCK_6, { TA_TPRI, 1, 1 });
+CRE_SEM(LWIP_LOCK_7, { TA_TPRI, 1, 1 });
+CRE_SEM(LWIP_LOCK_8, { TA_TPRI, 1, 1 });
+CRE_SEM(LWIP_LOCK_9, { TA_TPRI, 1, 1 });
+CRE_SEM(LWIP_LOCK_10, { TA_TPRI, 1, 1 });
+CRE_SEM(LWIP_LOCK_11, { TA_TPRI, 1, 1 });
+CRE_SEM(LWIP_LOCK_12, { TA_TPRI, 1, 1 });
+CRE_SEM(LWIP_LOCK_13, { TA_TPRI, 1, 1 });
+CRE_SEM(LWIP_LOCK_N, { TA_TPRI, 1, 1 });
+
+CRE_SEM(LWIP0_SEM_1, { TA_TPRI, 0, 1 });
+CRE_SEM(LWIP0_SEM_2, { TA_TPRI, 0, 1 });
+CRE_SEM(LWIP0_SEM_3, { TA_TPRI, 0, 1 });
+CRE_SEM(LWIP0_SEM_4, { TA_TPRI, 0, 1 });
+CRE_SEM(LWIP0_SEM_5, { TA_TPRI, 0, 1 });
+CRE_SEM(LWIP0_SEM_6, { TA_TPRI, 0, 1 });
+CRE_SEM(LWIP0_SEM_7, { TA_TPRI, 0, 1 });
+CRE_SEM(LWIP0_SEM_8, { TA_TPRI, 0, 1 });
+CRE_SEM(LWIP0_SEM_9, { TA_TPRI, 0, 1 });
+CRE_SEM(LWIP0_SEM_10, { TA_TPRI, 0, 1 });
+CRE_SEM(LWIP0_SEM_11, { TA_TPRI, 0, 1 });
+CRE_SEM(LWIP0_SEM_12, { TA_TPRI, 0, 1 });
+CRE_SEM(LWIP0_SEM_13, { TA_TPRI, 0, 1 });
+CRE_SEM(LWIP0_SEM_14, { TA_TPRI, 0, 1 });
+CRE_SEM(LWIP0_SEM_15, { TA_TPRI, 0, 1 });
+CRE_SEM(LWIP0_SEM_16, { TA_TPRI, 0, 1 });
+CRE_SEM(LWIP0_SEM_17, { TA_TPRI, 0, 1 });
+CRE_SEM(LWIP0_SEM_18, { TA_TPRI, 0, 1 });
+CRE_SEM(LWIP0_SEM_19, { TA_TPRI, 0, 1 });
+CRE_SEM(LWIP0_SEM_20, { TA_TPRI, 0, 1 });
+CRE_SEM(LWIP0_SEM_21, { TA_TPRI, 0, 1 });
+CRE_SEM(LWIP0_SEM_22, { TA_TPRI, 0, 1 });
+CRE_SEM(LWIP0_SEM_23, { TA_TPRI, 0, 1 });
+CRE_SEM(LWIP0_SEM_24, { TA_TPRI, 0, 1 });
+CRE_SEM(LWIP0_SEM_25, { TA_TPRI, 0, 1 });
+CRE_SEM(LWIP0_SEM_26, { TA_TPRI, 0, 1 });
+CRE_SEM(LWIP0_SEM_27, { TA_TPRI, 0, 1 });
+CRE_SEM(LWIP0_SEM_N, { TA_TPRI, 0, 1 });
+
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip.h	(revision 457)
@@ -0,0 +1,59 @@
+/*
+ *  TOPPERS/ASP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Advanced Standard Profile Kernel
+ * 
+ *  Copyright (C) 2003-2015 by Ryosuke Takeuchi
+ *                     GJ Business Division RICOH COMPANY,LTD. JAPAN
+ *  Copyright (C) 2017-2019 by TOPPERS PROJECT Educational Working Group.
+ * 
+ *  上記著作権者は，Free Software Foundation によって公表されている 
+ *  GNU General Public License の Version 2 に記述されている条件か，以
+ *  下の(1)～(4)の条件を満たす場合に限り，本ソフトウェア（本ソフトウェ
+ *  アを改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを再利用可能なバイナリコード（リロケータブルオブ
+ *      ジェクトファイルやライブラリなど）の形で利用する場合には，利用
+ *      に伴うドキュメント（利用者マニュアルなど）に，上記の著作権表示，
+ *      この利用条件および下記の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを再利用不可能なバイナリコードの形または機器に組
+ *      み込んだ形で利用する場合には，次のいずれかの条件を満たすこと．
+ *    (a) 利用に伴うドキュメント（利用者マニュアルなど）に，上記の著作
+ *        権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 利用の形態を，別に定める方法によって，上記著作権者に報告する
+ *        こと．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者を免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者は，
+ *  本ソフトウェアに関して，その適用可能性も含めて，いかなる保証も行わ
+ *  ない．また，本ソフトウェアの利用により直接的または間接的に生じたい
+ *  かなる損害に関しても，その責任を負わない．
+ * 
+ *  $Id$
+ */
+
+/*
+ *	LWIP設定のヘッダファイル
+ */
+
+#ifndef _LWIP_H_
+
+#define LWIP_DEFAULT_PRIORITY   8
+#define LWIP_STACK_SIZE         4096
+
+#ifndef TOPPERS_MACRO_ONLY
+
+/*
+ *  関数のプロトタイプ宣言
+ */
+extern void lwip_task(intptr_t exinf);
+#endif
+
+#define _LWIP_H_
+
+#endif	/* _LWIP_H_ */
+
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/monitor/Makefile
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/monitor/Makefile	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/monitor/Makefile	(revision 457)
@@ -0,0 +1,593 @@
+#
+#  TOPPERS/ASP Kernel
+#      Toyohashi Open Platform for Embedded Real-Time Systems/
+#      Advanced Standard Profile Kernel
+# 
+#  Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
+#                              Toyohashi Univ. of Technology, JAPAN
+#  Copyright (C) 2006-2014 by Embedded and Real-Time Systems Laboratory
+#              Graduate School of Information Science, Nagoya Univ., JAPAN
+# 
+#  ä¸è¨èä½æ¨©è
+ã¯ï¼ä»¥ä¸ã®(1)ï½(4)ã®æ¡ä»¶ãæºããå ´åã«éãï¼æ¬ã½ããã¦ã§
+#  ã¢ï¼æ¬ã½ããã¦ã§ã¢ãæ¹å¤ãããã®ãå«ãï¼ä»¥ä¸åãï¼ãä½¿ç¨ã»è¤è£½ã»æ¹
+#  å¤ã»åé
+å¸ï¼ä»¥ä¸ï¼å©ç¨ã¨å¼ã¶ï¼ãããã¨ãç¡åã§è¨±è«¾ããï¼
+#  (1) æ¬ã½ããã¦ã§ã¢ãã½ã¼ã¹ã³ã¼ãã®å½¢ã§å©ç¨ããå ´åã«ã¯ï¼ä¸è¨ã®èä½
+#      æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨ã®ç¡ä¿è¨¼è¦å®ãï¼ãã®ã¾ã¾ã®å½¢ã§ã½ã¼
+#      ã¹ã³ã¼ãä¸­ã«å«ã¾ãã¦ãããã¨ï¼
+#  (2) æ¬ã½ããã¦ã§ã¢ãï¼ã©ã¤ãã©ãªå½¢å¼ãªã©ï¼ä»ã®ã½ããã¦ã§ã¢éçºã«ä½¿
+#      ç¨ã§ããå½¢ã§åé
+å¸ããå ´åã«ã¯ï¼åé
+å¸ã«ä¼´ããã­ã¥ã¡ã³ãï¼å©ç¨
+#      è
+ããã¥ã¢ã«ãªã©ï¼ã«ï¼ä¸è¨ã®èä½æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨
+#      ã®ç¡ä¿è¨¼è¦å®ãæ²è¼ãããã¨ï¼
+#  (3) æ¬ã½ããã¦ã§ã¢ãï¼æ©å¨ã«çµã¿è¾¼ããªã©ï¼ä»ã®ã½ããã¦ã§ã¢éçºã«ä½¿
+#      ç¨ã§ããªãå½¢ã§åé
+å¸ããå ´åã«ã¯ï¼æ¬¡ã®ããããã®æ¡ä»¶ãæºããã
+#      ã¨ï¼
+#    (a) åé
+å¸ã«ä¼´ããã­ã¥ã¡ã³ãï¼å©ç¨è
+ããã¥ã¢ã«ãªã©ï¼ã«ï¼ä¸è¨ã®è
+#        ä½æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨ã®ç¡ä¿è¨¼è¦å®ãæ²è¼ãããã¨ï¼
+#    (b) åé
+å¸ã®å½¢æ
+ãï¼å¥ã«å®ããæ¹æ³ã«ãã£ã¦ï¼TOPPERSãã­ã¸ã§ã¯ãã«
+#        å ±åãããã¨ï¼
+#  (4) æ¬ã½ããã¦ã§ã¢ã®å©ç¨ã«ããç´æ¥çã¾ãã¯éæ¥çã«çãããããªãæ
+#      å®³ãããï¼ä¸è¨èä½æ¨©è
+ããã³TOPPERSãã­ã¸ã§ã¯ããå
+è²¬ãããã¨ï¼
+#      ã¾ãï¼æ¬ã½ããã¦ã§ã¢ã®ã¦ã¼ã¶ã¾ãã¯ã¨ã³ãã¦ã¼ã¶ããã®ãããªãç
+#      ç±ã«åºã¥ãè«æ±ãããï¼ä¸è¨èä½æ¨©è
+ããã³TOPPERSãã­ã¸ã§ã¯ãã
+#      å
+è²¬ãããã¨ï¼
+# 
+#  æ¬ã½ããã¦ã§ã¢ã¯ï¼ç¡ä¿è¨¼ã§æä¾ããã¦ãããã®ã§ããï¼ä¸è¨èä½æ¨©è
+ã
+#  ãã³TOPPERSãã­ã¸ã§ã¯ãã¯ï¼æ¬ã½ããã¦ã§ã¢ã«é¢ãã¦ï¼ç¹å®ã®ä½¿ç¨ç®ç
+#  ã«å¯¾ããé©åæ§ãå«ãã¦ï¼ãããªãä¿è¨¼ãè¡ããªãï¼ã¾ãï¼æ¬ã½ããã¦ã§
+#  ã¢ã®å©ç¨ã«ããç´æ¥çã¾ãã¯éæ¥çã«çãããããªãæå®³ã«é¢ãã¦ãï¼ã
+#  ã®è²¬ä»»ãè² ããªãï¼
+# 
+#  $Id$
+# 
+
+#
+#  ã¿ã¼ã²ããã®æå®ï¼Makefile.targetã§ä¸æ¸ããããã®ãé²ãããï¼
+#
+all:
+
+#
+#  ã¿ã¼ã²ããç¥ç§°ã®å®ç¾©
+#
+TARGET = @(TARGET)
+
+#
+#  ãã­ã°ã©ãã³ã°è¨èªã®å®ç¾©
+#
+SRCLANG = @(SRCLANG)
+ifeq ($(SRCLANG),c)
+  LIBS = -lc
+endif
+ifeq ($(SRCLANG),c++)
+  USE_CXX = true
+  CXXLIBS = -lstdc++ -lm -lc
+  CXXRTS = cxxrt.o newlibrt.o
+endif
+
+#
+#  ã½ã¼ã¹ãã¡ã¤ã«ã®ãã£ã¬ã¯ããªã®å®ç¾©
+#
+SRCDIR = @(SRCDIR)
+
+#
+#  ãªãã¸ã§ã¯ããã¡ã¤ã«åã®æ¡å¼µå­ã®è¨­å®
+#
+OBJEXT = @(OBJEXT)
+
+#
+#  å®è¡ç°å¢ã®å®ç¾©ï¼ã¿ã¼ã²ããä¾å­ã«ä¸æ¸ããããå ´åãããï¼
+#
+DBGENV := @(DBGENV)
+
+#
+#  ã«ã¼ãã«ã©ã¤ãã©ãªï¼libkernel.aï¼ã®ãã£ã¬ã¯ããªå
+#  ï¼ã«ã¼ãã«ã©ã¤ãã©ãªãmakeå¯¾è±¡ã«ããæã¯ï¼ç©ºã«å®ç¾©ããï¼
+#
+KERNEL_LIB = @(KERNEL_LIB)
+
+#
+#  ã«ã¼ãã«ãé¢æ°åä½ã§ã³ã³ãã¤ã«ãããã©ããã®å®ç¾©
+#
+KERNEL_FUNCOBJS = @(KERNEL_FUNCOBJS)
+
+#
+#  ãã¬ã¼ã¹ã­ã°ãåå¾ãããã©ããã®å®ç¾©
+#
+ENABLE_TRACE = @(ENABLE_TRACE)
+
+#
+#  ã¦ã¼ãã£ãªãã£ãã­ã°ã©ã ã®åç§°
+#
+PERL = @(PERL)
+CFG = @(CFG)
+
+#
+#  ãªãã¸ã§ã¯ããã¡ã¤ã«åã®å®ç¾©
+#
+OBJNAME = asp
+ifdef OBJEXT
+  OBJFILE = $(OBJNAME).$(OBJEXT)
+  CFG1_OUT = cfg1_out.$(OBJEXT)
+else
+  OBJFILE = $(OBJNAME)
+  CFG1_OUT = cfg1_out
+endif
+
+#
+#  ã¿ã¼ã²ããä¾å­é¨ã®ãã£ã¬ã¯ããªã®å®ç¾©
+#
+TARGETDIR = $(SRCDIR)/target/$(TARGET)
+
+#
+#  ã¿ã¼ã²ããä¾å­ã®å®ç¾©ã®ã¤ã³ã¯ã«ã¼ã
+#
+include $(TARGETDIR)/Makefile.target
+
+#
+#  ã³ã³ãã£ã®ã¥ã¬ã¼ã¿é¢ä¿ã®å¤æ°ã®å®ç¾©
+#
+CFG_TABS := --api-table $(SRCDIR)/kernel/kernel_api.csv \
+			--cfg1-def-table $(SRCDIR)/kernel/kernel_def.csv $(CFG_TABS)
+
+CFG_ASMOBJS := $(CFG_ASMOBJS)
+CFG_COBJS := kernel_cfg.o $(CFG_COBJS)
+CFG_OBJS := $(CFG_ASMOBJS) $(CFG_COBJS)
+CFG2_OUT_SRCS := kernel_cfg.h kernel_cfg.c $(CFG2_OUT_SRCS)
+
+#
+#  å
+±éã³ã³ãã¤ã«ãªãã·ã§ã³ã®å®ç¾©
+#
+COPTS := $(COPTS) -g @(COPTS)
+ifndef OMIT_WARNING_ALL
+  COPTS := $(COPTS) -Wall
+endif
+ifndef OMIT_OPTIMIZATION
+  COPTS := $(COPTS) -O2
+endif
+CDEFS := $(CDEFS) @(CDEFS)
+INCLUDES := -I. -I$(SRCDIR)/include -I$(SRCDIR)/arch -I$(SRCDIR) $(INCLUDES)
+LDFLAGS := $(LDFLAGS) @(LDFLAGS)
+CFG1_OUT_LDFLAGS := $(CFG1_OUT_LDFLAGS) @(LDFLAGS)
+LIBS := $(LIBS) $(CXXLIBS)
+CFLAGS = $(COPTS) $(CDEFS) $(INCLUDES)
+
+#
+#  ã¢ããªã±ã¼ã·ã§ã³ãã­ã°ã©ã ã«é¢ããå®ç¾©
+#
+APPLNAME = @(APPLNAME)
+APPLDIR = @(APPLDIR)
+APPL_CFG = $(APPLNAME).cfg
+
+APPL_DIR = $(APPLDIR) $(SRCDIR)/library
+APPL_ASMOBJS =
+ifdef USE_CXX
+  APPL_CXXOBJS = $(APPLNAME).o @(APPLOBJS)
+  APPL_COBJS =
+else
+  APPL_COBJS = $(APPLNAME).o @(APPLOBJS)
+endif
+APPL_COBJS := $(APPL_COBJS) log_output.o vasyslog.o t_perror.o strerror.o
+APPL_CFLAGS =
+APPL_LIBS =
+ifdef APPLDIR
+  INCLUDES := $(INCLUDES) $(foreach dir,$(APPLDIR),-I$(dir))
+endif
+
+#  ããã«ã¦ã§ã¢ã® Makefile ã®ã¤ã³ã¯ã«ã¼ã
+#
+include @(SRCDIR)/monitor/Makefile.config
+
+#
+#  ã·ã¹ãã ãµã¼ãã¹ã«é¢ããå®ç¾©
+#
+SYSSVC_DIR := $(SYSSVC_DIR) $(SRCDIR)/syssvc $(SRCDIR)/library
+SYSSVC_ASMOBJS := $(SYSSVC_ASMOBJS)
+SYSSVC_COBJS := $(SYSSVC_COBJS) banner.o syslog.o serial.o logtask.o armv7m.o \
+				@(SYSSVCOBJS) $(CXXRTS)
+SYSSVC_CFLAGS := $(SYSSVC_CFLAGS)
+SYSSVC_LIBS := $(SYSSVC_LIBS)
+INCLUDES := $(INCLUDES)
+
+#
+#  ã«ã¼ãã«ã«é¢ããå®ç¾©
+#
+#  KERNEL_ASMOBJS: ã«ã¼ãã«ã©ã¤ãã©ãªã«å«ããï¼ã½ã¼ã¹ãã¢ã»ã³ããªè¨èªã®
+#				   ãªãã¸ã§ã¯ããã¡ã¤ã«ï¼
+#  KERNEL_COBJS: ã«ã¼ãã«ã®ã©ã¤ãã©ãªã«å«ããï¼ã½ã¼ã¹ãCè¨èªã§ï¼ã½ã¼ã¹
+#				 ãã¡ã¤ã«ã¨1å¯¾1ã«å¯¾å¿ãããªãã¸ã§ã¯ããã¡ã¤ã«ï¼
+#  KERNEL_LCSRCS: ã«ã¼ãã«ã®ã©ã¤ãã©ãªã«å«ããCè¨èªã®ã½ã¼ã¹ãã¡ã¤ã«ã§ï¼
+#				  1ã¤ã®ã½ã¼ã¹ãã¡ã¤ã«ããè¤æ°ã®ãªãã¸ã§ã¯ããã¡ã¤ã«ãç
+#				  æãããã®ï¼
+#  KERNEL_LCOBJS: ä¸ã®ã½ã¼ã¹ãã¡ã¤ã«ããçæããããªãã¸ã§ã¯ããã¡ã¤ã«ï¼
+#  KERNEL_AUX_COBJS: ã­ã¼ãã¢ã¸ã¥ã¼ã«ã«å«ããªããï¼ã«ã¼ãã«ã®ã½ã¼ã¹ãã¡
+#					 ã¤ã«ã¨åããªãã·ã§ã³ãé©ç¨ãã¦ã³ã³ãã¤ã«ãã¹ãï¼ã½ã¼
+#					 ã¹ãCè¨èªã®ãªãã¸ã§ã¯ããã¡ã¤ã«ï¼
+#
+KERNEL_DIR := $(KERNEL_DIR) $(SRCDIR)/kernel
+KERNEL_ASMOBJS := $(KERNEL_ASMOBJS)
+KERNEL_COBJS := $(KERNEL_COBJS)
+KERNEL_CFLAGS := $(KERNEL_CFLAGS) -I$(SRCDIR)/kernel
+ifdef OMIT_MAKEOFFSET
+  OFFSET_H =
+else
+  OFFSET_H = offset.h
+ifndef OFFSET_TF
+  KERNEL_AUX_COBJS := $(KERNEL_AUX_COBJS) makeoffset.o
+endif
+endif
+
+#
+#  ã¿ã¼ã²ãããã¡ã¤ã«ï¼è¤æ°ãåæã«é¸æãã¦ã¯ãªããªãï¼
+#
+all: $(OBJFILE)
+#all: $(OBJNAME).bin
+#all: $(OBJNAME).srec
+
+##### ä»¥ä¸ã¯ç·¨éããªããã¨ #####
+
+#
+#  ç°å¢ã«ä¾å­ããã³ã³ãã¤ã«ãªãã·ã§ã³ã®å®ç¾©
+#
+ifdef DBGENV
+  CDEFS := $(CDEFS) -D$(DBGENV)
+endif
+
+#
+#  ã«ã¼ãã«ã®ãã¡ã¤ã«æ§æã®å®ç¾©
+#
+include $(SRCDIR)/kernel/Makefile.kernel
+ifdef KERNEL_FUNCOBJS
+  KERNEL_LCSRCS := $(KERNEL_FCSRCS)
+  KERNEL_LCOBJS := $(foreach file,$(KERNEL_FCSRCS),$($(file:.c=)))
+else
+  KERNEL_CFLAGS := -DALLFUNC $(KERNEL_CFLAGS)
+  KERNEL_COBJS := $(KERNEL_COBJS) \
+					$(foreach file,$(KERNEL_FCSRCS),$(file:.c=.o))
+endif
+
+#
+#  ã½ã¼ã¹ãã¡ã¤ã«ã®ãããã£ã¬ã¯ããªã«é¢ããå®ç¾©
+#
+vpath %.c $(KERNEL_DIR) $(SYSSVC_DIR) $(APPL_DIR)
+vpath %.S $(KERNEL_DIR) $(SYSSVC_DIR) $(APPL_DIR)
+vpath %.cfg $(APPL_DIR)
+
+#
+#  ã³ã³ãã¤ã«ã®ããã®å¤æ°ã®å®ç¾©
+#
+KERNEL_LIB_OBJS = $(KERNEL_ASMOBJS) $(KERNEL_COBJS) $(KERNEL_LCOBJS)
+SYSSVC_OBJS = $(SYSSVC_ASMOBJS) $(SYSSVC_COBJS)
+APPL_OBJS = $(APPL_ASMOBJS) $(APPL_COBJS) $(APPL_CXXOBJS)
+ALL_OBJS = $(START_OBJS) $(APPL_OBJS) $(SYSSVC_OBJS) $(CFG_OBJS) \
+											$(END_OBJS) $(HIDDEN_OBJS)
+ifdef KERNEL_LIB
+  ALL_LIBS = $(APPL_LIBS) $(SYSSVC_LIBS) -lkernel $(LIBS)
+  LIBS_DEP = $(filter %.a,$(ALL_LIBS)) $(KERNEL_LIB)/libkernel.a
+  LDFLAGS := $(LDFLAGS) -L$(KERNEL_LIB)
+  REALCLEAN_FILES := libkernel.a $(REALCLEAN_FILES)
+else
+  ALL_LIBS = $(APPL_LIBS) $(SYSSVC_LIBS) libkernel.a $(LIBS)
+  LIBS_DEP = $(filter %.a,$(ALL_LIBS))
+endif
+
+ifdef TEXT_START_ADDRESS
+  LDFLAGS := $(LDFLAGS) -Wl,-Ttext,$(TEXT_START_ADDRESS)
+  CFG1_OUT_LDFLAGS := $(CFG1_OUT_LDFLAGS) -Wl,-Ttext,$(TEXT_START_ADDRESS)
+endif
+ifdef DATA_START_ADDRESS
+  LDFLAGS := $(LDFLAGS) -Wl,-Tdata,$(DATA_START_ADDRESS)
+  CFG1_OUT_LDFLAGS := $(CFG1_OUT_LDFLAGS) -Wl,-Tdata,$(DATA_START_ADDRESS)
+endif
+ifdef LDSCRIPT
+  LDFLAGS := $(LDFLAGS) -Wl,-T,$(LDSCRIPT)
+  CFG1_OUT_LDFLAGS := $(CFG1_OUT_LDFLAGS) -Wl,-T,$(LDSCRIPT)
+endif
+
+#
+#  ãªãã»ãããã¡ã¤ã«ï¼offset.hï¼ã®çæè¦å
+#
+ifdef OFFSET_TF
+offset.h: $(APPL_CFG) kernel_cfg.timestamp
+	$(CFG) --pass 3 --kernel asp $(INCLUDES) \
+				--rom-image cfg1_out.srec --symbol-table cfg1_out.syms \
+				-T $(OFFSET_TF) $(CFG_TABS) $<
+else
+offset.h: makeoffset.s $(SRCDIR)/utils/genoffset
+	$(PERL) $(SRCDIR)/utils/genoffset makeoffset.s > offset.h
+endif
+
+#
+#  ã«ã¼ãã«ã®ã³ã³ãã£ã®ã¥ã¬ã¼ã·ã§ã³ãã¡ã¤ã«ã®çæ
+#
+cfg1_out.c: $(APPL_CFG)
+	$(CFG) --pass 1 --kernel asp $(INCLUDES) $(CFG_TABS) $<
+
+$(CFG2_OUT_SRCS): kernel_cfg.timestamp
+kernel_cfg.timestamp: $(APPL_CFG) \
+						$(START_OBJS) cfg1_out.o $(END_OBJS) $(HIDDEN_OBJS)
+	$(LINK) $(CFLAGS) $(CFG1_OUT_LDFLAGS) -o $(CFG1_OUT) \
+						$(START_OBJS) cfg1_out.o $(END_OBJS)
+	$(NM) -n $(CFG1_OUT) > cfg1_out.syms
+	$(OBJCOPY) -O srec -S $(CFG1_OUT) cfg1_out.srec
+	$(CFG) --pass 2 --kernel asp $(INCLUDES) \
+				-T $(TARGETDIR)/target.tf $(CFG_TABS) $<
+	touch -r kernel_cfg.c kernel_cfg.timestamp
+
+#
+#  ã«ã¼ãã«ã©ã¤ãã©ãªãã¡ã¤ã«ã®çæ
+#
+libkernel.a: $(OFFSET_H) $(KERNEL_LIB_OBJS)
+	rm -f libkernel.a
+	$(AR) -rcs libkernel.a $(KERNEL_LIB_OBJS)
+	$(RANLIB) libkernel.a
+
+#
+#  ç¹å¥ãªä¾å­é¢ä¿ã®å®ç¾©
+#
+banner.o: kernel_cfg.timestamp $(filter-out banner.o,$(ALL_OBJS)) $(LIBS_DEP)
+
+#
+#  å
+¨ä½ã®ãªã³ã¯
+#
+$(OBJFILE): $(APPL_CFG) kernel_cfg.timestamp $(ALL_OBJS) $(LIBS_DEP)
+	$(LINK) $(CFLAGS) $(LDFLAGS) -o $(OBJFILE) $(START_OBJS) \
+			$(APPL_OBJS) $(SYSSVC_OBJS) $(CFG_OBJS) $(ALL_LIBS) $(END_OBJS)
+	$(NM) -n $(OBJFILE) > $(OBJNAME).syms
+	$(OBJCOPY) -O srec -S $(OBJFILE) $(OBJNAME).srec
+	$(CFG) --pass 3 --kernel asp $(INCLUDES) \
+				--rom-image $(OBJNAME).srec --symbol-table $(OBJNAME).syms \
+				-T $(TARGETDIR)/target_check.tf $(CFG_TABS) $<
+
+#
+#  ãã¤ããªãã¡ã¤ã«ã®çæ
+#
+$(OBJNAME).bin: $(OBJFILE)
+	$(OBJCOPY) -O binary -S $(OBJFILE) $(OBJNAME).bin
+
+#
+#  Sã¬ã³ã¼ããã¡ã¤ã«ã®çæ
+#
+$(OBJNAME).srec: $(OBJFILE)
+	$(OBJCOPY) -O srec -S $(OBJFILE) $(OBJNAME).srec
+
+#
+#  ã³ã³ãã¤ã«çµæã®æ¶å»
+#
+.PHONY: clean
+clean:
+	rm -f \#* *~ *.o $(CLEAN_FILES)
+	rm -f $(OBJFILE) $(OBJNAME).syms $(OBJNAME).srec $(OBJNAME).bin
+	rm -f kernel_cfg.timestamp $(CFG2_OUT_SRCS)
+	rm -f cfg1_out.c $(CFG1_OUT) cfg1_out.syms cfg1_out.srec
+ifndef KERNEL_LIB
+	rm -f libkernel.a
+endif
+	rm -f makeoffset.s offset.h
+
+.PHONY: cleankernel
+cleankernel:
+	rm -rf $(KERNEL_LIB_OBJS)
+	rm -f makeoffset.s offset.h
+
+.PHONY: cleandep
+cleandep:
+	if ! [ -f Makefile.depend ]; then \
+		rm -f kernel_cfg.timestamp $(CFG2_OUT_SRCS); \
+		rm -f cfg1_out.c cfg1_out.o $(CFG1_OUT) cfg1_out.syms cfg1_out.srec; \
+		rm -f makeoffset.s offset.h; \
+	fi
+	rm -f Makefile.depend
+
+.PHONY: realclean
+realclean: cleandep clean
+	rm -f $(REALCLEAN_FILES)
+
+#
+#  ã³ã³ãã£ã®ã¥ã¬ã¼ã¿ãçæãããã¡ã¤ã«ã®ã³ã³ãã¤ã«ã«ã¼ã«ã¨ä¾å­é¢ä¿ä½æ
+#  ã«ã¼ã«ã®å®ç¾©
+#
+#  ã³ã³ãã£ã®ã¥ã¬ã¼ã¿ãçæãããã¡ã¤ã«ã¯ï¼ã¢ããªã±ã¼ã·ã§ã³ãã­ã°ã©ã ç¨ï¼
+#  ã·ã¹ãã ãµã¼ãã¹ç¨ï¼ã«ã¼ãã«ç¨ã®ãã¹ã¦ã®ãªãã·ã§ã³ãä»ãã¦ã³ã³ãã¤ã«
+#  ããï¼
+#
+ALL_CFG_COBJS = $(CFG_COBJS) cfg1_out.o
+ALL_CFG_ASMOBJS = $(CFG_ASMOBJS)
+CFG_CFLAGS = $(APPL_CFLAGS) $(SYSSVC_CFLAGS) $(KERNEL_CFLAGS)
+
+$(ALL_CFG_COBJS): %.o: %.c
+	$(CC) -c $(CFLAGS) $(CFG_CFLAGS) $<
+
+$(ALL_CFG_COBJS:.o=.s): %.s: %.c
+	$(CC) -S $(CFLAGS) $(CFG_CFLAGS) $<
+
+$(ALL_CFG_COBJS:.o=.d): %.d: %.c
+	@$(PERL) $(SRCDIR)/utils/makedep -C $(CC) $(MAKEDEP_OPTS) \
+		-O "$(CFLAGS) $(CFG_CFLAGS)" $< >> Makefile.depend
+
+$(ALL_CFG_ASMOBJS): %.o: %.S
+	$(CC) -c $(CFLAGS) $(CFG_CFLAGS) $<
+
+$(ALL_CFG_ASMOBJS:.o=.d): %.d: %.S
+	@$(PERL) $(SRCDIR)/utils/makedep -C $(CC) $(MAKEDEP_OPTS) \
+		-O "$(CFLAGS) $(CFG_CFLAGS)" $< >> Makefile.depend
+
+#
+#  ç¹æ®ãªä¾å­é¢ä¿ä½æã«ã¼ã«ã®å®ç¾©
+#
+cfg1_out.depend: $(APPL_CFG)
+	@$(CFG) -M cfg1_out.c $(INCLUDES) $< >> Makefile.depend
+
+makeoffset.d: makeoffset.c
+	@$(PERL) $(SRCDIR)/utils/makedep -C $(CC) $(MAKEDEP_OPTS) \
+		-T "makeoffset.s" -O "$(CFLAGS) $(KERNEL_CFLAGS)" $< >> Makefile.depend
+
+#
+#  ä¾å­é¢ä¿ãã¡ã¤ã«ã®çæ
+#
+.PHONY: gendepend
+gendepend:
+	@echo "Generating Makefile.depend."
+
+.PHONY: depend
+ifdef KERNEL_LIB
+depend: cleandep kernel_cfg.timestamp gendepend \
+		cfg1_out.depend cfg1_out.d \
+		$(ALL_OBJS:.o=.d)
+else
+depend: cleandep $(OFFSET_H) kernel_cfg.timestamp gendepend \
+		cfg1_out.depend cfg1_out.d \
+		$(KERNEL_AUX_COBJS:.o=.d) $(KERNEL_ASMOBJS:.o=.d) \
+		$(KERNEL_COBJS:.o=.d) $(KERNEL_LCSRCS:.c=.d) $(ALL_OBJS:.o=.d)
+endif
+
+#
+#  ä¾å­é¢ä¿ãã¡ã¤ã«ãã¤ã³ã¯ã«ã¼ã
+#
+-include Makefile.depend
+
+#
+#  éçºãã¼ã«ã®ã³ãã³ãåã®å®ç¾©
+#
+ifeq ($(TOOL),gcc)
+  #
+  #  GNUéçºç°å¢ç¨
+  #
+  ifdef GCC_TARGET
+    GCC_TARGET_PREFIX = $(GCC_TARGET)-
+  else
+    GCC_TARGET_PREFIX =
+  endif
+  CC = $(GCC_TARGET_PREFIX)gcc
+  CXX = $(GCC_TARGET_PREFIX)g++
+  AS = $(GCC_TARGET_PREFIX)as
+  LD = $(GCC_TARGET_PREFIX)ld
+  AR = $(GCC_TARGET_PREFIX)ar
+  NM = $(GCC_TARGET_PREFIX)nm
+  RANLIB = $(GCC_TARGET_PREFIX)ranlib
+  OBJCOPY = $(GCC_TARGET_PREFIX)objcopy
+  OBJDUMP = $(GCC_TARGET_PREFIX)objdump
+endif
+
+ifdef USE_CXX
+  LINK = $(CXX)
+else
+  LINK = $(CC)
+endif
+
+#
+#  ã³ã³ãã¤ã«ã«ã¼ã«ã®å®ç¾©
+#
+KERNEL_ALL_COBJS = $(KERNEL_COBJS) $(KERNEL_AUX_COBJS)
+
+$(KERNEL_ALL_COBJS): %.o: %.c
+	$(CC) -c $(CFLAGS) $(KERNEL_CFLAGS) $<
+
+$(KERNEL_ALL_COBJS:.o=.s): %.s: %.c
+	$(CC) -S $(CFLAGS) $(KERNEL_CFLAGS) $<
+
+$(KERNEL_LCOBJS): %.o:
+	$(CC) -DTOPPERS_$(*F) -o $@ -c $(CFLAGS) $(KERNEL_CFLAGS) $<
+
+$(KERNEL_LCOBJS:.o=.s): %.s:
+	$(CC) -DTOPPERS_$(*F) -o $@ -S $(CFLAGS) $(KERNEL_CFLAGS) $<
+
+$(KERNEL_ASMOBJS): %.o: %.S
+	$(CC) -c $(CFLAGS) $(KERNEL_CFLAGS) $<
+
+$(SYSSVC_COBJS): %.o: %.c
+	$(CC) -c $(CFLAGS) $(SYSSVC_CFLAGS) $<
+
+$(SYSSVC_COBJS:.o=.s): %.s: %.c
+	$(CC) -S $(CFLAGS) $(SYSSVC_CFLAGS) $<
+
+$(SYSSVC_ASMOBJS): %.o: %.S
+	$(CC) -c $(CFLAGS) $(SYSSVC_CFLAGS) $<
+
+$(APPL_COBJS): %.o: %.c
+	$(CC) -c $(CFLAGS) $(APPL_CFLAGS) $<
+
+$(APPL_COBJS:.o=.s): %.s: %.c
+	$(CC) -S $(CFLAGS) $(APPL_CFLAGS) $<
+
+$(APPL_CXXOBJS): %.o: %.cpp
+	$(CXX) -c $(CFLAGS) $(APPL_CFLAGS) $<
+
+$(APPL_CXXOBJS:.o=.s): %.s: %.cpp
+	$(CXX) -S $(CFLAGS) $(APPL_CFLAGS) $<
+
+$(APPL_ASMOBJS): %.o: %.S
+	$(CC) -c $(CFLAGS) $(APPL_CFLAGS) $<
+
+#
+#  ä¾å­é¢ä¿ä½æã«ã¼ã«ã®å®ç¾©
+#
+$(KERNEL_COBJS:.o=.d): %.d: %.c
+	@$(PERL) $(SRCDIR)/utils/makedep -C $(CC) $(MAKEDEP_OPTS) \
+		-O "$(CFLAGS) $(KERNEL_CFLAGS)" $< >> Makefile.depend
+
+$(KERNEL_LCSRCS:.c=.d): %.d: %.c
+	@$(PERL) $(SRCDIR)/utils/makedep -C $(CC) $(MAKEDEP_OPTS) -T "$($*)" \
+		-O "-DALLFUNC $(CFLAGS) $(KERNEL_CFLAGS)" $< >> Makefile.depend
+
+$(KERNEL_ASMOBJS:.o=.d): %.d: %.S
+	@$(PERL) $(SRCDIR)/utils/makedep -C $(CC) $(MAKEDEP_OPTS) \
+		-O "$(CFLAGS) $(KERNEL_CFLAGS)" $< >> Makefile.depend
+
+$(SYSSVC_COBJS:.o=.d): %.d: %.c
+	@$(PERL) $(SRCDIR)/utils/makedep -C $(CC) $(MAKEDEP_OPTS) \
+		-O "$(CFLAGS) $(SYSSVC_CFLAGS)" $< >> Makefile.depend
+
+$(SYSSVC_ASMOBJS:.o=.d): %.d: %.S
+	@$(PERL) $(SRCDIR)/utils/makedep -C $(CC) $(MAKEDEP_OPTS) \
+		-O "$(CFLAGS) $(SYSSVC_CFLAGS)" $< >> Makefile.depend
+
+$(APPL_COBJS:.o=.d): %.d: %.c
+	@$(PERL) $(SRCDIR)/utils/makedep -C $(CC) $(MAKEDEP_OPTS) \
+		-O "$(CFLAGS) $(APPL_CFLAGS)" $< >> Makefile.depend
+
+$(APPL_CXXOBJS:.o=.d): %.d: %.cpp
+	@$(PERL) $(SRCDIR)/utils/makedep -C $(CXX) $(MAKEDEP_OPTS) \
+		-O "$(CFLAGS) $(APPL_CFLAGS)" $< >> Makefile.depend
+
+$(APPL_ASMOBJS:.o=.d): %.d: %.S
+	@$(PERL) $(SRCDIR)/utils/makedep -C $(CC) $(MAKEDEP_OPTS) \
+		-O "$(CFLAGS) $(APPL_CFLAGS)" $< >> Makefile.depend
+
+#
+#  ããã©ã«ãã³ã³ãã¤ã«ã«ã¼ã«ãä¸æ¸ã
+#
+%.o: %.c
+	@echo "*** Default compile rules should not be used."
+	$(CC) -c $(CFLAGS) $<
+
+%.s: %.c
+	@echo "*** Default compile rules should not be used."
+	$(CC) -S $(CFLAGS) $<
+
+%.o: %.cpp
+	@echo "*** Default compile rules should not be used."
+	$(CXX) -c $(CFLAGS) $<
+
+%.s: %.cpp
+	@echo "*** Default compile rules should not be used."
+	$(CXX) -S $(CFLAGS) $<
+
+%.o: %.S
+	@echo "*** Default compile rules should not be used."
+	$(CC) -c $(CFLAGS) $<
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/monitor/Makefile.config
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/monitor/Makefile.config	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/monitor/Makefile.config	(revision 457)
@@ -0,0 +1,57 @@
+#
+#   TOPPERS/ASP Kernel
+#       Toyohashi Open Platform for Embedded Real-Time Systems/
+#       Advanced Standard Profile Kernel
+#
+#   Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
+#                               Toyohashi Univ. of Technology, JAPAN
+#   Copyright (C) 2003-2008 by Ryosuke Takeuchi
+#                Platform Development Center RICOH COMPANY,LTD. JAPAN
+#
+#   上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+#   によって公表されている GNU General Public License の Version 2 に記
+#   述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+#   を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+#   利用と呼ぶ）することを無償で許諾する．
+#   (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+#       権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+#       スコード中に含まれていること．
+#   (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+#       用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+#       者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+#       の無保証規定を掲載すること．
+#   (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+#       用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+#       と．
+#     (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+#         作権表示，この利用条件および下記の無保証規定を掲載すること．
+#     (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+#         報告すること．
+#   (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+#       害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+#
+#   本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+#   よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+#   含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+#   接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+#
+#  @(#) $Id$
+#
+ 
+#
+#  Makefile のプロセッサ依存 (monitor用)
+#
+
+#
+#  コンパイルオプション
+#
+INCLUDES	:= $(INCLUDES) -I$(SRCDIR)/monitor -I$(SRCDIR)/kernel
+LDFLAGS := $(LDFLAGS) -Wl,--wrap=fflush
+
+#
+#  モニターに関する定義
+#
+SYSSVC_DIR := $(SYSSVC_DIR):$(SRCDIR)/monitor:$(SRCDIR)/monitor/arch:$(SRCDIR)/monitor/stdio
+SYSSVC_COBJS := $(SYSSVC_COBJS) task_expansion.o monitor.o stddev.o \
+	      printf.o sprintf.o fprintf.o scanf.o sscanf.o
+
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/monitor/README.txt
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/monitor/README.txt	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/monitor/README.txt	(revision 457)
@@ -0,0 +1,374 @@
+
+        ＝ TOPPERS/JSPカーネル ユーザズマニュアル ＝
+      （monitor、netDeviceの説明、newlib標準入出力の対応）
+
+        （Release 1.4.3 対応，最終更新: 11-27-2010）
+
+------------------------------------------------------------------------
+ TOPPERS/JSP Kernel
+     Toyohashi Open Platform for Embedded Real-Time Systems/
+     Just Standard Profile Kernel
+
+ Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
+                             Toyohashi Univ. of Technology, JAPAN
+ Copyright (C) 2003-2004 by Takagi Nobuhisa
+ Copyright (C) 2003-2010 by Ryosuke Takeuchi
+                     GJ Business Division RICOH COMPANY,LTD. JAPAN
+
+ 上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ によって公表されている GNU General Public License の Version 2 に記
+ 述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ 利用と呼ぶ）することを無償で許諾する．
+ (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+     権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+     スコード中に含まれていること．
+ (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+     用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+     者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+     の無保証規定を掲載すること．
+ (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+     用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+     と．
+   (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+       作権表示，この利用条件および下記の無保証規定を掲載すること．
+   (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+       報告すること．
+ (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+     害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+
+ 本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ 含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ 接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+------------------------------------------------------------------------
+/*
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms are permitted
+ * provided that the above copyright notice and this paragraph are
+ * duplicated in all such forms and that any documentation,
+ * advertising materials, and other materials related to such
+ * distribution and use acknowledge that the software was developed
+ * by the University of California, Berkeley.  The name of the
+ * University may not be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+１．monitorについて
+
+１－１．解説
+本モニタは、TOPPERSプロジェクト教育ＷＧの実装教育用に作成されたプログラム
+です。TOPPERS/JSP1.4.1上でタスクとして実行します。実行確認は以下の４つの
+環境環境で実行確認を行っています。
+１）m16c(OAKS16-miniとOAKS16)   ルネサステクノロジ製TM
+２）h8(AKIH8-3048,AKIH8-3069F)  PizzaFactory2+GNU(h8300-hms)
+                                cygwin+GNU(h8300-hms)
+３）sh2(hsb7616it)              cygwin+GNU(sh-hitachi-elf)
+
+１－２．コンソールの指定
+タスクモニタのコンソールは通常はシリアルデバイスを対象としています。
+MONTSK(タスクモニタのタスク)の起動の引数で渡されるexinfの値をモニタの
+通信出力デバイスとしています。但し、netDeviceのサーバとして起動する場合
+コンソールはWindows上のnetTermとなります。
+
+１－３．コンパイルスイッチ
+タスクモニタのビルドで実行機能を指定するコンパイルスイッチについて説明します。
+
+１）MONITOR_PORTID
+モニタのデフォルトポートはシリアルコンソール（CONSOLE_PORTID）ですが、
+モニタの起動コンソールを変更したい場合、コンパイルスイッチに
+-DMONITOR_PORTID=nを指定すると変更が可能です。このとき、指定ポートのオープンは
+モニタの起動時に行います。(Ver1.1.0のNEED_OPENのスイッチは削除します)
+
+２）SUPPORT_PIPE
+このスイッチを定義すると、外付けのコマンドを拡張します。
+外付けコマンドは第1コマンド"PIPE"で起動します。
+外付けコマンドの連絡関数はpipe_command(B *command);で設定してください。
+
+３）SUPPORT_ETHER
+TINETのコマンドサービス及びnetDeviceのコマンド拡張を行います。
+このコマンドは第1コマンド"NET"で起動します。
+
+４）START_TASKID
+netDEviceの接続時、自動実行するタスク番号を指定します。
+-DSTART_TASKID=1
+のように指定すると、netDeviceの接続後、教材のプログラムが自動的に実行します。
+
+５）NEED_MONITOR
+このコンパイルスイッチを指定すると、モニタの起動時にneed_monitor()関数を呼び
+出します。この関数の戻り値がFALSEの場合、モニタタスクを終了します。
+
+６）MONITOR_DELAY
+このコンパイルスイッチが指定された場合、モニタの起動時、コンソールの出力を
+MONITOR_DELAY(ms)待ちを行った後で行います。
+
+１－４．TOPPERS/JSPの実装拡張について
+タスクモニタの以下の機能を実現するためにTOPPERS/JSPの実装依存configに
+いくつかの改造が必要です。
+
+１）_kernel_break_waitの定義の追加(必須)
+JSPカーネルのサービスコールでの待ち状態の判定のために、_kernel_break_wait
+ラベルをサービスコールの待ちプログラム位置に定義する必要があります。
+サービスコールの待ちプログラム位置は通常各ＣＰＵのcpu_support.Sの何れかの
+位置にあります。
+
+２）iana_tskのリンクポイントの設定（必須ではない）
+タスクモニタでは各タスクの実行履歴をdispatchのタスク切り替え時にiana_tsk
+関数を呼び出すことで情報収集を行っています。そのためiana_tskの呼び出しに
+より、スイッチング時間が大きく低下します。しかし、"log task"コマンドによる
+タスク情報はリアルタイムシステムの検証には有用な手段です。
+通常はコンパイルスイッチMONにより、取り外し可能とし、必要のない場合は
+取り外して、使用してください。
+dispatch関数は通常各ＣＰＵのcpu_support.S中にあります。
+
+１－５．タスクモニタのマニュアル
+１）displayコマンド
+display byte [<start address> [<end address>]]
+        <start address>から<end address>までのメモリまたはポート領域を
+        １バイト単位に表示する。<end address>を省略した場合は128バイトの
+        表示を行う。<start adress>を省略した場合は、前回表示を行った次の
+        アドレスから表示を行う。
+
+display half [<start address> [<end address>]]
+        <start address>から<end address>までのメモリまたはポート領域を
+        ２バイト単位に表示する。<end address>を省略した場合は128バイトの
+        表示を行う。<start adress>を省略した場合は、前回表示を行った次の
+        アドレスから表示を行う。
+
+display word [<start address> [<end address>]]
+        <start address>から<end address>までのメモリまたはポート領域を
+        ４バイト単位に表示する。<end address>を省略した場合は128バイトの
+        表示を行う。<start adress>を省略した場合は、前回表示を行った次の
+        アドレスから表示を行う。
+
+display task
+        登録されたタスクの内容を表示する。表示内容は以下の通り。
+        cur     	カレントタスクに*、モニタタスクはmonを表示する。
+        id          タスクIDを表示する。
+        pri         初期値のタスク優先度
+        state       タスクの状態
+        pc          RUN状態以外なら、現在のプログラムカウンタ値
+        stack       現在のスタックアドレス
+        inistack    初期値スタックの先頭アドレス
+        inisize     初期値スタックのバイトサイズ
+
+diaplay register
+        カレントタスクが待ち状態となった場合、待ち状態のレジスタの内容を
+        表示する。サービスコール中の待ちではレジスタの保存を行わない為、
+        レジスタの表示は行わない。レジスタの内容はCPUによって異なる。
+
+２）setコマンド
+set byte [<start address>]
+        <start address>の内容を１バイト表示し入力待ちとなる。１６進数入力後
+        <RETURN>にてバイト値を入力すると<start address>に値を書込み後、
+        <start address>の内容を再表示し<start address>+1の内容の入力待ちとなる
+        .<RETURN>にてsetコマンドを終了しプロンプト表示に戻る。<start address>
+        を省略した場合、最後に書込んだ次のアドレスの書込みを行う。
+
+set half [<start address>]
+        <start address>の内容を２バイト表示し入力待ちとなる。１６進数入力後
+        <RETURN>にてバイト値を入力すると<start address>に値を書込み後、
+        <start address>の内容を再表示し<start address>+2の内容の入力待ちとなる
+        .<RETURN>にてsetコマンドを終了しプロンプト表示に戻る。<start address>
+        を省略した場合、最後に書込んだ次のアドレスの書込みを行う。
+
+set ward [<start address>]
+        <start address>の内容を２バイト表示し入力待ちとなる。１６進数入力後
+        <RETURN>にてバイト値を入力すると<start address>に値を書込み後、
+        <start address>の内容を再表示し<start address>+2の内容の入力待ちとなる
+        .<RETURN>にてsetコマンドを終了しプロンプト表示に戻る。<start address>
+        を省略した場合、最後に書込んだ次のアドレスの書込みを行う。
+
+set command [<mode>]
+        コマンドモードを設定する。モードは１(1コマンド)、２(2コマンド)モードで
+        デフォルトは２コマンドモード(例：displayとbyteの２つのコマンドで
+        コマンド設定を行う)である。１コマンドは２コマンドの先頭の1文字を組み合
+        わせた１つのコマンドでコマンド設定を行う。(例：display byteではdb)
+        <mode>を省略すると現在のコマンドモードの表示を行う。
+        ２コマンドモードでも、コマンドの最初の1文字の入力で実行可能である。
+        (例：display byteでは d b)
+
+set serial [<portid>]
+        タスクモニタの入出力対応のシリアルのポート番号を<porid>で変更する
+        <portid>を省略すると現在のポート番号を表示する。
+
+set task [<task id>]
+        <task id>で指定したタスクにカレントタスクを変更する。
+        <task id>を省略するとモニタタスクをカレントタスクに設定する。
+
+３）taskコマンド
+task activate
+        カレントタスクにact_tsk(<カレントタスクID>)サービスコールを発行する。
+
+task terminate
+        カレントタスクにter_tsk(<カレントタスクID>)サービスコールを発行する。
+
+task suspend
+        カレントタスクにsus_tsk(<カレントタスクID>)サービスコールを発行する。
+
+task resume
+        カレントタスクにrsm_tsk(<カレントタスクID>)サービスコールを発行する。
+
+task priority [pir]
+        カレントタスクにchg_tsk(<カレントタスクID>, <pri>)サービスコールを
+        発行する。
+
+４）logコマンド
+log mode [<logmask> [<lowmask>]]
+        syslogの表示モードを変更する。<logmask>と<lowmask>を省略した場合
+        現在の<logmask>と<lowmask>を表示する。設定値のマスクの対応は
+        以下の通りである。
+        <マスク>   <設定値>
+        LOG_EMERG     0     シャットダウンに値するエラー:lowmask default
+        LOG_ALERT     1
+        LOG_CRIT      2
+        LOG_ERROR     3     システムエラー
+        LOG_WARNING   4     警告メッセージ
+        LOG_NOTICE    5                                 :logmask default
+        LOG_INFO      6
+        LOG_DEBUG     7     デバッグ用メッセージ
+        logmask defaultとlowmask defaultは電源RTOS起動後のデフォルト値
+
+log task [<cycle time>]
+        <cycle time>ms周期に各タスクの前周期からのタスクの実行時間を表示する。
+        <cycle time>を省略した場合、前回のlog task表示からの各タスクの
+        実行時間を表示する。
+
+log port [<no> <logno> [<portaddress>]]
+        ポートモニタ機能の設定。<portaddress>を設定した場合<portaddress>が
+        アクセスされるたびに<logno>にてアクセスデータをsyslogにてログ表示
+        する。
+         <no> <logno> <portaddress>の設定にて<portaddress>を<no>にlogmaskを
+         <logno>にてポートモニタの設定を行う。但し、<logno>は1以上7までの値。
+         <no> <0>の設定にてポートモニタの解除を行う。
+         引数を省略すると、ポートモニタの登録状態の表示を行う。
+
+５）volumeコマンド
+TINETが有効であり、SUPPORT_VOLUMEコンパイルスイッチが有効の場合のみ使用可能な
+コマンドである。
+volume format <drive>
+         <drive>に対してフォーマットを行う。
+
+volume dir  [<path>]
+         <path>のディレクトリを表示する。<path>を省略した場合、デフォルト
+         deriveのディレクトリを表示する。
+
+volume mkdir <path>
+         <path>で指定したディレクトリを作成する。
+
+volume rmdir <path>
+         <path>で指定したディレクトリを削除する。
+
+volume erase <path>
+         <path>で指定したファイルを削除する。
+
+６）pipeコマンド
+SUPPORT_PIPEコンパイルスイッチが有効で、拡張コマンドが用意されている場合のみ
+有効なコマンドであり、コマンド仕様は拡張されたユーザ設定コマンドの仕様に
+従う、セカンドコマンドがユーザ設定コマンドとなる。
+
+７）helpコマンド
+モニタコマンドのヘルプ情報を表示する。
+
+２．モニタの入出力に関して
+モニタのデータ取り込みは、(FILE*)mon_infileに対するデータ取り込みを行う
+モニタのデータ送信は、標準入出力の出力ファイル(stdout)に対して行う。
+
+
+３．標準入出力の対応
+
+３－１．解説
+標準入出力はnewlib版と簡易版を選択できます。
+newlib版は簡易版に比べ、H8のサイズで32KBほど大きくなります。
+状況に応じて、選択してください。
+newlib版はh8の環境のみ実行確認を行っています。他の環境では
+実行確認を行っていません。
+
+
+３－２．簡易版標準入出力
+monitorデレクトリィ中の以下のファイルを使用します
+　stdio.h　　（newlib中のstdio.hに優先して参照する）
+  printf.c　　(printf文)
+  sprintf.c   (sprintf文)
+サポートしている標準入出力関数はstdio.hを参照してください
+また、printf関数やsprintf関数がlibc.aに優先してリンクされるように
+ライブラリィより前に、printf.oとsprintf.oを取り込むようにしてください。
+また、OAKS16用の開発環境TMで使用する場合はstdio.hを削除しMTOOLの
+stdio.hを使用するようにしてください。
+
+３－３．newlib版標準入出力
+monitorデレクトリィ中のstdio.h、stddev.c、printf.c、sprintf.cを参照しない
+ように、これらのファイルを削除してください。
+また、monitor/Makefile.config中からstddev.o、printf.o、sprintf.oをビルド時
+にリンクしないように削除してください。
+newlib中の標準入出力は、putcharやputcのような一文字出力関数は\n(改行)コードが
+ないと表示を行いません。また、printfやputsのような文字列出力関数は\nコードが
+付けられて出力されます。
+putcharやputcの対応を行うには、初期化としてバッファのない指定を行えば
+解決できます。この教材ではnewlibrc.cを改造し、タスクモニタの初期化時、
+setbuf(stdio, 0);関数にて、出力バッファなしの指定を行っています。
+タスクモニタを使用しない場合は、setbufの設定を自分で行ってください。
+printfやputsのような文字列の出力関数に関しては、newlib中のputs.cを
+修正することにより、これを回避することが出来ます。
+詳細は３．newlibの改造を参照してください。
+
+ライブラリィのビルド手順は以下の通りです。
+/home/roi/gnuにnewlibの凍結ファイルをコピーし
+gnu>tar zxvf newlib-1.11.0.tar.gz
+gnu>mkdir /usr/local/h8300-hms
+gnu>mkdir newlib-objdir
+gnu>cd newlib-objdir
+gnu>export TARGET_CFLAGS=-DREENTRANT_SYSCALLS_PROVIDED
+gnu>/home/roi/gnu/newlib-1.11.0/configure --target=h8300-hms --prefix=/usr/local/h8300-hms
+gnu>make
+gnu>make install
+
+アプリケーションのビルド時、標準入出力用の実装部として改造した
+systask/newlibrt.cをリンクする必要があります。
+
+
+３－４．newlibの改造(newlib-1.11.0/newlib/libc/stdio/)
+puts.cの修正部
+/*
+ * Write the given string to stdout, appending a newline.
+ */
+
+int
+_DEFUN (_puts_r, (ptr, s),
+	struct _reent *ptr _AND
+	_CONST char * s)
+{
+  size_t c = strlen (s);
+  struct __suio uio;
+  struct __siov iov[2];
+
+  iov[0].iov_base = s;
+  iov[0].iov_len = c;
+#if 0	/* TOPPERS.JSP */
+  iov[1].iov_base = "\n";
+#else	/* TOPPERS.JSP */
+  iov[1].iov_base = "\0";
+#endif	/* TOPPERS.JSP */
+  iov[1].iov_len = 1;
+  uio.uio_resid = c + 1;
+  uio.uio_iov = &iov[0];
+  uio.uio_iovcnt = 2;
+
+  _REENT_SMALL_CHECK_INIT(_stdout_r (ptr));
+  return (__sfvwrite (_stdout_r (ptr), &uio) ? EOF : '\n');
+}
+
+
+また、標準入出力用のローレベル関数はsystask/newlibrt.cに記載してあります。
+既存のnewlibrt.cはnewlib用のC言語ライブラリィとC++言語ライブラリィと
+初期化プログラムがいっしょに記述してありましたので以下の２つのソースに
+分けました。newlibの標準入出力を使用する場合は新しいnewlibrt.cを
+プログラムのビルド時にリンクするようにしてください。
+・新しいnewlibrt.c：C言語用のnewlibライブラリィのTOPPERSとのI/F部
+・cpplibrt.c：C++言語用の関数と初期化プログラム
+
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/monitor/arch/armv4.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/monitor/arch/armv4.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/monitor/arch/armv4.c	(revision 457)
@@ -0,0 +1,311 @@
+/*
+ *  TOPPERS/ASP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Advanced Standard Profile Kernel
+ * 
+ *  Copyright (C) 2003-2008 by Ryosuke Takeuchi
+ *                     GJ Business Division RICOH COMPANY,LTD. JAPAN
+ * 
+ *  上記著作権者は，Free Software Foundation によって公表されている 
+ *  GNU General Public License の Version 2 に記述されている条件か，以
+ *  下の(1)～(4)の条件を満たす場合に限り，本ソフトウェア（本ソフトウェ
+ *  アを改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを再利用可能なバイナリコード（リロケータブルオブ
+ *      ジェクトファイルやライブラリなど）の形で利用する場合には，利用
+ *      に伴うドキュメント（利用者マニュアルなど）に，上記の著作権表示，
+ *      この利用条件および下記の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを再利用不可能なバイナリコードの形または機器に組
+ *      み込んだ形で利用する場合には，次のいずれかの条件を満たすこと．
+ *    (a) 利用に伴うドキュメント（利用者マニュアルなど）に，上記の著作
+ *        権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 利用の形態を，別に定める方法によって，上記著作権者に報告する
+ *        こと．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者を免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者は，
+ *  本ソフトウェアに関して，その適用可能性も含めて，いかなる保証も行わ
+ *  ない．また，本ソフトウェアの利用により直接的または間接的に生じたい
+ *  かなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/* 
+ *  TOPPERS/ASP用タスクモニタCPU依存プログラム．
+ *
+ */
+
+#include <itron.h>
+#include <sil.h>
+#include <stdio.h>
+#include "kernel_impl.h"
+#include "task.h"
+#include "task_expansion.h"
+#include "monitor.h"
+
+extern void _kernel_break_wait();
+
+#define set_align(a, b)	((ulong_t)a & ~(b-1))
+
+/*
+ * レジスタの構造体
+ */
+typedef struct t_reg{
+	uint32_t r4;
+	uint32_t r5;
+	uint32_t r6;
+	uint32_t r7;
+	uint32_t r8;
+	uint32_t r9;
+	uint32_t r10;
+	uint32_t r11;
+	uint32_t spsr;
+	uint32_t r0;
+	uint32_t r1;
+	uint32_t r2;
+	uint32_t r3;
+	uint32_t ip;
+	uint32_t lr;
+	uint32_t pc;
+}T_REG;
+
+/*
+ * メモリのマッピング定義構造体
+ */
+
+typedef struct t_memdef{
+	uint32_t mstart;
+	uint32_t mend;
+	uint8_t  mtype;
+	uint8_t  mstate;
+}T_MEMDEF;
+
+/*
+ * ARM4のメモリマッピング
+ */
+
+static T_MEMDEF const memdefine[] = {
+#if defined(__AT91SAM7S128__)
+	{0x00000000, 0x0001FFFF,           MEMORY_AREA, MREAD_ONLY },
+	{RAM_START,  RAM_START+RAM_SIZE-1, MEMORY_AREA, MREAD_WRITE},
+	{0xFFFF0000, 0xFFFFFFFF,           PORT_AREA,   MREAD_WRITE}
+#elif defined(MINDSTORMSNXT)
+	{0x00000000, RAM_SIZE-1,           MEMORY_AREA, MREAD_ONLY },
+	{0x001C0000, 0x001FFFFF,           MEMORY_AREA, MREAD_ONLY },
+	{RAM_START,  RAM_START+RAM_SIZE-1, MEMORY_AREA, MREAD_WRITE},
+	{0xFFFF0000, 0xFFFFFFFF,           PORT_AREA,   MREAD_WRITE}
+#elif defined(__LPC2388__)
+	{0x00000000, 0x0007FFFF,           MEMORY_AREA, MREAD_ONLY },
+	{0x3FFFC000, 0x3FFFFFFF,           PORT_AREA,   MREAD_WRITE},
+	{RAM_START,  RAM_START+RAM_SIZE-1, MEMORY_AREA, MREAD_WRITE},
+	{0x80000000, 0x8000FFFF,           MEMORY_AREA, MREAD_ONLY },
+	{0x81000000, 0x8100FFFF,           MEMORY_AREA, MREAD_ONLY },
+	{0xE0000000, 0xE008FFFF,           PORT_AREA,   MREAD_WRITE},
+	{0xE01FC000, 0xE01FFFFF,           PORT_AREA,   MREAD_WRITE},
+	{0xFFEF0000, 0xFFFFFFFF,           PORT_AREA,   MREAD_WRITE}
+#elif (__TARGET_ARCH_ARM == 5)
+	{0x01BC0000, 0x01BC0FFF,           MEMORY_AREA, MREAD_WRITE},
+	{0x01BC1000, 0x01BC17FF,           PORT_AREA,   MREAD_WRITE},
+	{0x01C00000, 0x01C07FFF,           PORT_AREA,   MREAD_WRITE},
+	{0x01C08000, 0x01C087FF,           PORT_AREA,   MREAD_WRITE},
+	{0x01C10000, 0x01C11FFF,           PORT_AREA,   MREAD_WRITE},
+	{0x01C14000, 0x01C14FFF,           PORT_AREA,   MREAD_WRITE},
+	{0x01C20000, 0x01C23FFF,           PORT_AREA,   MREAD_WRITE},
+	{0x01C40000, 0x01C42FFF,           PORT_AREA,   MREAD_WRITE},
+	{0x01D00000, 0x01D02FFF,           PORT_AREA,   MREAD_WRITE},
+	{0x01D0C000, 0x01D0DFFF,           PORT_AREA,   MREAD_WRITE},
+	{0x01D10000, 0x01D11FFF,           PORT_AREA,   MREAD_WRITE},
+	{0x01E00000, 0x01E0FFFF,           PORT_AREA,   MREAD_WRITE},
+	{0x01E10000, 0x01E10FFF,           PORT_AREA,   MREAD_WRITE},
+	{0x01E13000, 0x01E1BFFF,           PORT_AREA,   MREAD_WRITE},
+	{0x01E20000, 0x01E28FFF,           PORT_AREA,   MREAD_WRITE},
+	{0x01E2C000, 0x01E2CFFF,           PORT_AREA,   MREAD_WRITE},
+	{0x01E30000, 0x01E383FF,           PORT_AREA,   MREAD_WRITE},
+	{0x01F00000, 0x01F03FFF,           PORT_AREA,   MREAD_WRITE},
+	{0x01F06000, 0x01F08FFF,           PORT_AREA,   MREAD_WRITE},
+	{0x01F0C000, 0x01F0EFFF,           PORT_AREA,   MREAD_WRITE},
+	{0x01F10000, 0x01F11FFF,           PORT_AREA,   MREAD_WRITE},
+	{0x01C40000, 0x01C42FFF,           PORT_AREA,   MREAD_WRITE},
+	{0xC0000000, 0xC3FFFFFF,           MEMORY_AREA, MREAD_WRITE},
+	{0xFFFD0000, 0xFFFDFFFF,           MEMORY_AREA, MREAD_ONLY },
+	{0xFFFEE000, 0xFFFEFFFF,           PORT_AREA,   MREAD_WRITE},
+	{0xFFFF0000, 0xFFFF1FFF,           MEMORY_AREA, MREAD_WRITE}
+#else
+#error "No board type in ARMV4 groups."
+#endif
+};
+
+static T_REG  sreg;
+
+/******************************************************************************
+ * ハードウェアポート属性参照関数
+ ******************************************************************************/
+/*
+ *  アドレスからメモリ領域属性を取り出す
+ *  mode=0:領域の型
+ *  mode=1:読み取り書き込み属性
+ */
+
+char
+getMemoryType(ulong_t address, int_t mode)
+{
+	int_t count = sizeof(memdefine) / sizeof(T_MEMDEF);
+	int_t i;
+
+	for(i = 0 ; i < count ; i++){
+		if(address >= memdefine[i].mstart && address <= memdefine[i].mend){
+			if(mode == 0)
+				return memdefine[i].mtype;
+			else
+				return memdefine[i].mstate;
+		}
+	}
+	return NONE_AREA;
+}
+
+/*
+ *  アドレスからアライン後のアドレスを取り出す
+ */
+
+ulong_t
+MonAlignAddress(ulong_t address)
+{
+	return address;
+}
+
+/******************************************************************************
+ * メモリアクセス用関数
+ ******************************************************************************/
+/*
+ *  メモリ領域に対する読み出し関数
+ *  領域のチェックを行い、エラーならゼロを返す
+ */
+int_t
+MemoryRead(ulong_t address, intptr_t p, int_t type)
+{
+	int_t len;
+
+	switch(getMemoryType(address, 0)){
+	case PORT_AREA:
+		if(type == 2){
+			len = 2;
+			*((UH *)p) = sil_reh_mem((VP)address);
+		}
+		else if(type == 4){
+			len = 4;
+			*((UW *)p) = sil_rew_mem((VP)address);
+		}
+		else{
+			len = 1;
+			*((UB *)p) = sil_reb_mem((VP)address);
+		}
+		break;
+	case MEMORY_AREA:
+		if(type == 2){
+			len = 2;
+			*((UH *)p) = *((UH *)set_align(address, len));
+		}
+		else if(type == 4){
+			len = 4;
+			*((UW *)p) = *((UW *)set_align(address, len));
+		}
+		else{
+			len = 1;
+			*((UB *)p) = *((UB *)address);
+		}
+		break;
+	default:
+		len = 0;
+		break;
+	}
+	return len;
+}
+
+/*
+ *  メモリ領域に対する書き込み関数
+ *  領域のチェックを行い、エラーならゼロを返す
+ */
+int_t
+MemoryWrite(ulong_t address, intptr_t p, int_t type)
+{
+	int_t len;
+
+	switch(getMemoryType(address, 0)){
+	case PORT_AREA:
+		if(type == 2){
+			len = 2;
+			address = set_align(address, len);
+			sil_wrh_mem((VP)address, *((UH *)p));
+		}
+		else if(type == 4){
+			len = 4;
+			address = set_align(address, len);
+			sil_wrw_mem((VP)address, *((UW *)p));
+		}
+		else{
+			len = 1;
+			sil_wrb_mem((VP)address, *((UB *)p));
+		}
+		break;
+	case MEMORY_AREA:
+		if(getMemoryType(address, 1) == MREAD_ONLY){
+			len = 0;
+		}
+		else if(type == 2){
+			len = 2;
+			*((UH *)address) = *((UH *)set_align(p, len));
+		}
+		else if(type == 4){
+			len = 4;
+			*((UW *)address) = *((UW *)set_align(p, len));
+		}
+		else{
+			len = 1;
+			*((UB *)address) = *((UB *)p);
+		}
+		break;
+	default:
+		len = 0;
+		break;
+	}
+	return len;
+}
+
+/******************************************************************************
+ * モニタ用関数
+ ******************************************************************************/
+/*
+ *  レジスタ内容の表示
+ */
+void
+display_registers(ID tskid)
+{
+	ER     ercd;
+	T_RTST rtst;
+
+	ercd = ref_tst(tskid, &rtst);
+	if(ercd == E_OK){
+		if(rtst.tskpc == (FP)_kernel_break_wait){
+			sreg = *((T_REG *)rtst.tsksp);
+			printf(" PC =%08lx SP =%08x IR =%08x", (long)sreg.pc, (UW)((long)rtst.tsksp+sizeof(T_REG)), sreg.lr);
+			printf(" IP =%08x SR=%08x\n", sreg.ip, sreg.spsr);
+			printf(" R0 =%08x R1 =%08x R2 =%08x", sreg.r0, sreg.r1, sreg.r2);
+			printf(" R3 =%08x R4 =%08x R5 =%08x\n", sreg.r3, sreg.r4, sreg.r5);
+			printf(" R6 =%08x R7 =%08x R8 =%08x", sreg.r6, sreg.r7, sreg.r8);
+			printf(" R9 =%08x R10=%08x R11=%08x\n", sreg.r9, sreg.r10, sreg.r11);
+			printf("     %08lx    %08x\n", (long)sreg.pc, *((UW*)((sreg.pc+3) & ~3)));
+			return;
+		}
+		else if(rtst.tskstat == TTS_DMT){
+			printf("  wait in activate_r() !!\n");
+			return;
+		}
+	}
+	printf("  wait in dispatch() !!\n");
+}
+
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/monitor/arch/armv7m.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/monitor/arch/armv7m.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/monitor/arch/armv7m.c	(revision 457)
@@ -0,0 +1,365 @@
+/*
+ *  TOPPERS/ASP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Advanced Standard Profile Kernel
+ * 
+ *  Copyright (C) 2003-2016 by Ryosuke Takeuchi
+ *                     GJ Business Division RICOH COMPANY,LTD. JAPAN
+ *  Copyright (C) 2017-2019 by TOPPERS PROJECT Educational Working Group.
+ * 
+ *  上記著作権者は，Free Software Foundation によって公表されている 
+ *  GNU General Public License の Version 2 に記述されている条件か，以
+ *  下の(1)～(4)の条件を満たす場合に限り，本ソフトウェア（本ソフトウェ
+ *  アを改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを再利用可能なバイナリコード（リロケータブルオブ
+ *      ジェクトファイルやライブラリなど）の形で利用する場合には，利用
+ *      に伴うドキュメント（利用者マニュアルなど）に，上記の著作権表示，
+ *      この利用条件および下記の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを再利用不可能なバイナリコードの形または機器に組
+ *      み込んだ形で利用する場合には，次のいずれかの条件を満たすこと．
+ *    (a) 利用に伴うドキュメント（利用者マニュアルなど）に，上記の著作
+ *        権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 利用の形態を，別に定める方法によって，上記著作権者に報告する
+ *        こと．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者を免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者は，
+ *  本ソフトウェアに関して，その適用可能性も含めて，いかなる保証も行わ
+ *  ない．また，本ソフトウェアの利用により直接的または間接的に生じたい
+ *  かなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/* 
+ *  TOPPERS/ASP用タスクモニタCPU依存プログラム．
+ *
+ */
+
+#include <itron.h>
+#include <sil.h>
+#include <stdio.h>
+#include "kernel_impl.h"
+#include "task.h"
+#include "task_expansion.h"
+#include "monitor.h"
+
+extern void dispatch_r(void);
+
+#define set_align(a, b)	((ulong_t)a & ~(b-1))
+
+/*
+ * レジスタの構造体
+ */
+typedef struct t_reg{
+	uint32_t r4;
+	uint32_t r5;
+	uint32_t r6;
+	uint32_t r7;
+	uint32_t r8;
+	uint32_t r9;
+	uint32_t r10;
+	uint32_t r11;
+	uint32_t pc;
+}T_REG;
+
+/*
+ * メモリのマッピング定義構造体
+ */
+
+typedef struct t_memdef{
+	uint32_t mstart;
+	uint32_t mend;
+	uint8_t  mtype;
+	uint8_t  mstate;
+}T_MEMDEF;
+
+/*
+ * ARMv7のメモリマッピング
+ */
+
+static T_MEMDEF const memdefine[] = {
+#if defined(TOPPERS_CQ_FRK_FM3)
+	{0x00000000, 0x000FFFFF,           MEMORY_AREA, MREAD_ONLY },
+	{0x1FFF0000, 0x201EFFFF,           MEMORY_AREA, MREAD_WRITE},
+	{0x40000000, 0x400FFFFF,           PORT_AREA,   MREAD_WRITE},
+#elif defined(TOPPERS_STM32F091_NUCLEO64)	/* ARMV6m */
+	{0x08000000, 0x0803FFFF,           MEMORY_AREA, MREAD_ONLY },
+	{0x20000000, 0x20007FFF,           MEMORY_AREA, MREAD_WRITE},
+	{0x40000000, 0x50060FFF,           PORT_AREA,   MREAD_WRITE},
+	{0xA0000000, 0xBFFFFFFF,           PORT_AREA,   MREAD_WRITE},
+#elif defined(TOPPERS_STM32L073_NUCLEO64) || defined(TOPPERS_STM32LORA_DISCOVERY)	/* ARMV6m */
+	{0x08000000, 0x0802FFFF,           MEMORY_AREA, MREAD_ONLY },
+	{0x20000000, 0x20004FFF,           MEMORY_AREA, MREAD_WRITE},
+	{0x40000000, 0x50060FFF,           PORT_AREA,   MREAD_WRITE},
+	{0xA0000000, 0xBFFFFFFF,           PORT_AREA,   MREAD_WRITE},
+#elif defined(TOPPERS_STM32G071_NUCLEO64)	/* ARMV6m */
+	{0x08000000, 0x0801FFFF,           MEMORY_AREA, MREAD_ONLY },
+	{0x20000000, 0x20008FFF,           MEMORY_AREA, MREAD_WRITE},
+	{0x40000000, 0x50060FFF,           PORT_AREA,   MREAD_WRITE},
+	{0xA0000000, 0xBFFFFFFF,           PORT_AREA,   MREAD_WRITE},
+#elif defined(TOPPERS_STM32L476_NUCLEO64) || defined(TOPPERS_STM32L476_DISCOVERY)
+	{0x08000000, 0x080FFFFF,           MEMORY_AREA, MREAD_ONLY },
+	{0x10000000, 0x10007FFF,           MEMORY_AREA, MREAD_WRITE},
+	{0x20000000, 0x20017FFF,           MEMORY_AREA, MREAD_WRITE},
+	{0x40000000, 0x50060FFF,           PORT_AREA,   MREAD_WRITE},
+	{0x90000000, 0xBFFFFFFF,           PORT_AREA,   MREAD_WRITE},
+#elif defined(TOPPERS_STM32L4R5_NUCLEO144)
+	{0x08000000, 0x080FFFFF,           MEMORY_AREA, MREAD_ONLY },
+	{0x10000000, 0x10007FFF,           MEMORY_AREA, MREAD_WRITE},
+	{0x20000000, 0x2009FFFF,           MEMORY_AREA, MREAD_WRITE},
+	{0x40000000, 0x6FFFFFFF,           PORT_AREA,   MREAD_WRITE},
+	{0x80000000, 0xBFFFFFFF,           PORT_AREA,   MREAD_WRITE},
+#elif defined(TOPPERS_STM32WB55_NUCLEO)
+	{0x08000000, 0x080CBFFF,           MEMORY_AREA, MREAD_ONLY },
+	{0x20000000, 0x2003FFFF,           MEMORY_AREA, MREAD_WRITE},
+	{0x40000000, 0x6FFFFFFF,           PORT_AREA,   MREAD_WRITE},
+	{0x80000000, 0xBFFFFFFF,           PORT_AREA,   MREAD_WRITE},
+#elif defined(TOPPERS_STM32F4_DISCOVERY) || defined(TOPPERS_STM32_E407)
+	{0x08000000, 0x080FFFFF,           MEMORY_AREA, MREAD_ONLY },
+	{0x20000000, 0x2001FFFF,           MEMORY_AREA, MREAD_WRITE},
+	{0x40000000, 0x50060FFF,           PORT_AREA,   MREAD_WRITE},
+	{0xA0000000, 0xBFFFFFFF,           PORT_AREA,   MREAD_WRITE},
+#elif defined(TOPPERS_STM32F401_NUCLEO)
+	{0x08000000, 0x0807FFFF,           MEMORY_AREA, MREAD_ONLY },
+	{0x20000000, 0x20017FFF,           MEMORY_AREA, MREAD_WRITE},
+	{0x40000000, 0x50060FFF,           PORT_AREA,   MREAD_WRITE},
+	{0xA0000000, 0xBFFFFFFF,           PORT_AREA,   MREAD_WRITE},
+#elif defined(TOPPERS_STM32F446_NUCLEO64) || defined(TOPPERS_STM32F446_NUCLEO144)
+	{0x08000000, 0x0807FFFF,           MEMORY_AREA, MREAD_ONLY },
+	{0x20000000, 0x2001FFFF,           MEMORY_AREA, MREAD_WRITE},
+	{0x40000000, 0x50060FFF,           PORT_AREA,   MREAD_WRITE},
+	{0xA0000000, 0xBFFFFFFF,           PORT_AREA,   MREAD_WRITE},
+#elif defined(TOPPERS_STM32F429_BOARD)
+	{0x08000000, 0x080FFFFF,           MEMORY_AREA, MREAD_ONLY },
+	{0x20000000, 0x2002FFFF,           MEMORY_AREA, MREAD_WRITE},
+	{0x40000000, 0x50060FFF,           PORT_AREA,   MREAD_WRITE},
+	{0xA0000000, 0xBFFFFFFF,           PORT_AREA,   MREAD_WRITE},
+#elif defined(TOPPERS_STM32G474_NUCLEO64)
+	{0x08000000, 0x0807FFFF,           MEMORY_AREA, MREAD_ONLY },
+	{0x10000000, 0x10007FFF,           MEMORY_AREA, MREAD_WRITE},
+	{0x20000000, 0x20017FFF,           MEMORY_AREA, MREAD_WRITE},
+	{0x40000000, 0xAFFFFFFF,           PORT_AREA,   MREAD_WRITE},
+#elif defined(TOPPERS_STM32G431_NUCLEO64)
+	{0x08000000, 0x0801FFFF,           MEMORY_AREA, MREAD_ONLY },
+	{0x10000000, 0x10002FFF,           MEMORY_AREA, MREAD_WRITE},
+	{0x20000000, 0x200057FF,           MEMORY_AREA, MREAD_WRITE},
+	{0x40000000, 0xAFFFFFFF,           PORT_AREA,   MREAD_WRITE},
+#elif defined(TOPPERS_STM32F723_DISCOVERY)
+	{0x00000000, 0x0003FFFF,           MEMORY_AREA, MREAD_WRITE},
+	{0x08000000, 0x0807FFFF,           MEMORY_AREA, MREAD_ONLY },
+	{0x20000000, 0x2003FFFF,           MEMORY_AREA, MREAD_WRITE},
+	{0x40000000, 0x50060FFF,           PORT_AREA,   MREAD_WRITE},
+	{0x90000000, 0xBFFFFFFF,           PORT_AREA,   MREAD_WRITE},
+	{0xC0000000, 0xC07FFFFF,           MEMORY_AREA, MREAD_WRITE},
+#elif defined(TOPPERS_STM32F7_DISCOVERY) ||defined(TOPPERS_STM32F746_NUCLEO144)
+	{0x00000000, 0x0003FFFF,           MEMORY_AREA, MREAD_WRITE},
+	{0x08000000, 0x080FFFFF,           MEMORY_AREA, MREAD_ONLY },
+	{0x20000000, 0x2004FFFF,           MEMORY_AREA, MREAD_WRITE},
+	{0x40000000, 0x50060FFF,           PORT_AREA,   MREAD_WRITE},
+	{0x90000000, 0xBFFFFFFF,           PORT_AREA,   MREAD_WRITE},
+	{0xC0000000, 0xC07FFFFF,           MEMORY_AREA, MREAD_WRITE},
+#elif defined(TOPPERS_STM32F769_DISCOVERY) || defined(TOPPERS_STM32F767_NUCLEO144)
+	{0x00000000, 0x0003FFFF,           MEMORY_AREA, MREAD_WRITE},
+	{0x08000000, 0x081FFFFF,           MEMORY_AREA, MREAD_ONLY },
+	{0x20000000, 0x2007FFFF,           MEMORY_AREA, MREAD_WRITE},
+	{0x40000000, 0x50060FFF,           PORT_AREA,   MREAD_WRITE},
+	{0x90000000, 0xBFFFFFFF,           PORT_AREA,   MREAD_WRITE},
+	{0xC0000000, 0xC07FFFFF,           MEMORY_AREA, MREAD_WRITE},
+#elif defined(TOPPERS_STM32H743_NUCLEO144)
+	{0x08000000, 0x081FFFFF,           MEMORY_AREA, MREAD_ONLY },
+	{0x20000000, 0x0001FFFF,           MEMORY_AREA, MREAD_WRITE},
+	{0x24000000, 0x2407FFFF,           MEMORY_AREA, MREAD_WRITE},
+	{0x30000000, 0x30047FFF,           MEMORY_AREA, MREAD_WRITE},
+	{0x38000000, 0x3800FFFF,           MEMORY_AREA, MREAD_WRITE},
+	{0x40000000, 0x5802FFFF,           PORT_AREA,   MREAD_WRITE},
+	{0x90000000, 0xBFFFFFFF,           PORT_AREA,   MREAD_WRITE},
+#elif defined(NRF52832)
+	{0x00000000, 0x0007FFFF,           MEMORY_AREA, MREAD_ONLY },
+	{0x10000000, 0x1FFFFFFF,           PORT_AREA,   MREAD_WRITE},
+	{0x20000000, 0x2000FFFF,           MEMORY_AREA, MREAD_WRITE},
+	{0x40000000, 0x5007FFFF,           PORT_AREA,   MREAD_WRITE},
+	{0xF0000000, 0xF1FFFFFF,           PORT_AREA,   MREAD_WRITE},
+#elif defined(NRF52810)
+	{0x00000000, 0x0002FFFF,           MEMORY_AREA, MREAD_ONLY },
+	{0x10000000, 0x1FFFFFFF,           PORT_AREA,   MREAD_WRITE},
+	{0x20000000, 0x20005FFF,           MEMORY_AREA, MREAD_WRITE},
+	{0x40000000, 0x5007FFFF,           PORT_AREA,   MREAD_WRITE},
+	{0xF0000000, 0xF1FFFFFF,           PORT_AREA,   MREAD_WRITE},
+#else
+#error "No support board type in ARMV7-M groups."
+#endif
+	{0xE0000000, 0xFFFFFFFF,           PORT_AREA,   MREAD_WRITE}
+};
+
+static T_REG  sreg;
+
+/******************************************************************************
+ * ハードウェアポート属性参照関数
+ ******************************************************************************/
+/*
+ *  アドレスからメモリ領域属性を取り出す
+ *  mode=0:領域の型
+ *  mode=1:読み取り書き込み属性
+ */
+
+char
+getMemoryType(ulong_t address, int_t mode)
+{
+	int_t count = sizeof(memdefine) / sizeof(T_MEMDEF);
+	int_t i;
+
+	for(i = 0 ; i < count ; i++){
+		if(address >= memdefine[i].mstart && address <= memdefine[i].mend){
+			if(mode == 0)
+				return memdefine[i].mtype;
+			else
+				return memdefine[i].mstate;
+		}
+	}
+	return NONE_AREA;
+}
+
+/*
+ *  アドレスからアライン後のアドレスを取り出す
+ */
+
+ulong_t
+MonAlignAddress(ulong_t address)
+{
+	return address;
+}
+
+/******************************************************************************
+ * メモリアクセス用関数
+ ******************************************************************************/
+/*
+ *  メモリ領域に対する読み出し関数
+ *  領域のチェックを行い、エラーならゼロを返す
+ */
+int_t
+MemoryRead(ulong_t address, intptr_t p, int_t type)
+{
+	int_t len;
+
+	switch(getMemoryType(address, 0)){
+	case PORT_AREA:
+		if(type == 2){
+			len = 2;
+			*((UH *)p) = sil_reh_mem((VP)address);
+		}
+		else if(type == 4){
+			len = 4;
+			*((UW *)p) = sil_rew_mem((VP)address);
+		}
+		else{
+			len = 1;
+			*((UB *)p) = sil_reb_mem((VP)address);
+		}
+		break;
+	case MEMORY_AREA:
+		if(type == 2){
+			len = 2;
+			*((UH *)p) = *((UH *)set_align(address, len));
+		}
+		else if(type == 4){
+			len = 4;
+			*((UW *)p) = *((UW *)set_align(address, len));
+		}
+		else{
+			len = 1;
+			*((UB *)p) = *((UB *)address);
+		}
+		break;
+	default:
+		len = 0;
+		break;
+	}
+	return len;
+}
+
+/*
+ *  メモリ領域に対する書き込み関数
+ *  領域のチェックを行い、エラーならゼロを返す
+ */
+int_t
+MemoryWrite(ulong_t address, intptr_t p, int_t type)
+{
+	int_t len;
+
+	switch(getMemoryType(address, 0)){
+	case PORT_AREA:
+		if(type == 2){
+			len = 2;
+			address = set_align(address, len);
+			sil_wrh_mem((VP)address, *((UH *)p));
+		}
+		else if(type == 4){
+			len = 4;
+			address = set_align(address, len);
+			sil_wrw_mem((VP)address, *((UW *)p));
+		}
+		else{
+			len = 1;
+			sil_wrb_mem((VP)address, *((UB *)p));
+		}
+		break;
+	case MEMORY_AREA:
+		if(getMemoryType(address, 1) == MREAD_ONLY){
+			len = 0;
+		}
+		else if(type == 2){
+			len = 2;
+			*((UH *)address) = *((UH *)set_align(p, len));
+		}
+		else if(type == 4){
+			len = 4;
+			*((UW *)address) = *((UW *)set_align(p, len));
+		}
+		else{
+			len = 1;
+			*((UB *)address) = *((UB *)p);
+		}
+		break;
+	default:
+		len = 0;
+		break;
+	}
+	return len;
+}
+
+/******************************************************************************
+ * モニタ用関数
+ ******************************************************************************/
+/*
+ *  レジスタ内容の表示
+ */
+void
+display_registers(ID tskid)
+{
+	ER     ercd;
+	T_RTST rtst;
+
+	ercd = ref_tst(tskid, &rtst);
+	if(ercd == E_OK){
+		if(rtst.tskpc == (FP)dispatch_r){
+			sreg = *((T_REG *)rtst.tsksp);
+			printf(" PC  =%08lx SP =%08x\n", (long)sreg.pc, (UW)((long)rtst.tsksp+sizeof(T_REG)));
+			printf(" R4  =%08x R5 =%08x R6  =%08x R7  =%08x\n", sreg.r4, sreg.r5, sreg.r6, sreg.r7);
+			printf(" R8  =%08x R9 =%08x R10 =%08x R11 =%08x\n", sreg.r8, sreg.r9, sreg.r10, sreg.r11);
+			printf("     %08lx    %04x\n", (long)sreg.pc, *((UH*)(sreg.pc & ~1)));
+			return;
+		}
+		else if(rtst.tskstat == TTS_DMT){
+			printf("  wait in activate_r() !!\n");
+			return;
+		}
+	}
+	printf("  wait in dispatch() !!\n");
+}
+
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/monitor/arch/h8300h.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/monitor/arch/h8300h.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/monitor/arch/h8300h.c	(revision 457)
@@ -0,0 +1,357 @@
+/*
+ *  TOPPERS/ASP Educative Program
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Just Standard Profile Kernel
+ * 
+ *  Copyright (C) 2003-2008 by Ryosuke Takeuchi
+ *               Platform Development Center RICOH COMPANY,LTD. JAPAN
+ * 
+ *  上記著作権者は，Free Software Foundation によって公表されている 
+ *  GNU General Public License の Version 2 に記述されている条件か，以
+ *  下の(1)～(4)の条件を満たす場合に限り，本ソフトウェア（本ソフトウェ
+ *  アを改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを再利用可能なバイナリコード（リロケータブルオブ
+ *      ジェクトファイルやライブラリなど）の形で利用する場合には，利用
+ *      に伴うドキュメント（利用者マニュアルなど）に，上記の著作権表示，
+ *      この利用条件および下記の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを再利用不可能なバイナリコードの形または機器に組
+ *      み込んだ形で利用する場合には，次のいずれかの条件を満たすこと．
+ *    (a) 利用に伴うドキュメント（利用者マニュアルなど）に，上記の著作
+ *        権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 利用の形態を，別に定める方法によって，上記著作権者に報告する
+ *        こと．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者を免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者は，
+ *  本ソフトウェアに関して，その適用可能性も含めて，いかなる保証も行わ
+ *  ない．また，本ソフトウェアの利用により直接的または間接的に生じたい
+ *  かなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/* 
+ *  TOPPERS/ASP用タスクモニタCPU依存プログラム．
+ *
+ */
+
+#include <itron.h>
+#include <sil.h>
+#include <stdio.h>
+#include "kernel_impl.h"
+#include "task.h"
+#include "task_expansion.h"
+#ifdef SUPPORT_NETDEV
+#include "netdevice.h"
+#endif
+#include "monitor.h"
+
+extern void _kernel_break_wait();
+#ifdef SUPPORT_NETDEV
+static UB save_ier;
+extern unsigned long vector[];
+#endif
+
+/*
+ * レジスタの構造体
+ */
+typedef struct t_reg{
+	uint32_t er6;
+	uint32_t er5;
+	uint32_t er4;
+	uint32_t er3;
+	uint32_t er2;
+	uint32_t er1;
+	uint32_t er0;
+	uint32_t pc;
+}T_REG;
+
+/*
+ * メモリのマッピング定義構造体
+ */
+
+typedef struct t_memdef{
+	uint32_t mstart;
+	uint32_t mend;
+	uint8_t  mtype;
+	uint8_t  mstate;
+}T_MEMDEF;
+
+/*
+ * AKIH8のメモリマッピング
+ */
+
+static T_MEMDEF const memdefine[] = {
+	0x00000000, 0x000000FF, MEMORY_AREA, MREAD_ONLY,
+#if defined(__H8_3048F__)
+	0x00000100,	0x0001FFFF, MEMORY_AREA, MREAD_ONLY,
+	0x000FEF10, 0x000FFF0F, MEMORY_AREA, MREAD_WRITE,
+	0x00FFFF1C, 0x00FFFFFF, PORT_AREA,   MREAD_WRITE
+#elif defined(__H8_3069F__)
+	0x00000100,	0x0007FFFF, MEMORY_AREA, MREAD_ONLY,
+	0x00400000, 0x005FFFFF, MEMORY_AREA, MREAD_WRITE,
+	0x00FEE000, 0x00FEEFFF, PORT_AREA,   MREAD_WRITE,
+	0x00FFBF20, 0x00FFFF1F, MEMORY_AREA, MREAD_WRITE,
+	0x00FFFF20, 0x00FFFFFF, PORT_AREA,   MREAD_WRITE
+#else
+#error "No board type in H8300H groups."
+#endif
+};
+
+/******************************************************************************
+ * ハードウェアポート属性参照関数
+ ******************************************************************************/
+/*
+ *  アドレスからメモリ領域属性を取り出す
+ *  mode=0:領域の型
+ *  mode=1:読み取り書き込み属性
+ */
+
+char
+getMemoryType(ulong_t address, int_t mode)
+{
+	int_t count = sizeof(memdefine) / sizeof(T_MEMDEF);
+	int_t i;
+
+	for(i = 0 ; i < count ; i++){
+		if(address >= memdefine[i].mstart && address <= memdefine[i].mend){
+			if(mode == 0)
+				return memdefine[i].mtype;
+			else
+				return memdefine[i].mstate;
+		}
+	}
+	return NONE_AREA;
+}
+
+/*
+ *  アドレスからアライン後のアドレスを取り出す
+ */
+
+ulong_t
+MonAlignAddress(ulong_t address)
+{
+	return address;
+}
+
+/******************************************************************************
+ * メモリアクセス用関数
+ ******************************************************************************/
+/*
+ *  メモリ領域に対する読み出し関数
+ *  領域のチェックを行い、エラーならゼロを返す
+ */
+int_t
+MemoryRead(ulong_t address, intptr_t p, int_t type)
+{
+	int_t len;
+
+	switch(getMemoryType(address, 0)){
+	case PORT_AREA:
+		if(type == 2){
+			len = 2;
+#ifdef SUPPORT_NETDEV
+            if(!NetDeviceRead((unsigned long)address, len, (void *)p))
+#endif
+			*((UH *)p) = sil_reh_mem((VP)address);
+		}
+		else if(type == 4){
+			len = 4;
+#ifdef SUPPORT_NETDEV
+            if(!NetDeviceRead((unsigned long)address, len, (void *)p))
+#endif
+			*((UW *)p) = sil_rew_mem((VP)address);
+		}
+		else{
+#ifdef SUPPORT_NETDEV
+			len = 1;
+			if(NetDeviceActive() && address == H8IER)
+				*((UB *)p) = save_ier;
+			else if(address == H8IPRA || address == H8IPRB)
+				*((UB *)p) = sil_reb_mem((VP)address);
+            else if(!NetDeviceRead((unsigned long)address, len, (void *)p))
+				*((UB *)p) = sil_reb_mem((VP)address);
+#else
+			len = 1;
+			*((UB *)p) = sil_reb_mem((VP)address);
+#endif
+		}
+		break;
+	case MEMORY_AREA:
+		if(type == 2){
+			len = 2;
+			*((UH *)p) = *((UH *)address);
+		}
+		else if(type == 4){
+			len = 4;
+			*((UW *)p) = *((UW *)address);
+		}
+		else{
+			len = 1;
+			*((UB *)p) = *((UB *)address);
+		}
+		break;
+	default:
+		len = 0;
+		break;
+	}
+	return len;
+}
+
+/*
+ *  メモリ領域に対する書き込み関数
+ *  領域のチェックを行い、エラーならゼロを返す
+ */
+int_t
+MemoryWrite(ulong_t address, intptr_t p, int_t type)
+{
+	int_t len;
+
+	switch(getMemoryType(address, 0)){
+	case PORT_AREA:
+		if(type == 2){
+			len = 2;
+#ifdef SUPPORT_NETDEV
+            if(!NetDeviceWrite((unsigned long)address, len, (void *)p))
+#endif
+			sil_wrh_mem((VP)address, *((UH *)p));
+		}
+		else if(type == 4){
+			len = 4;
+#ifdef SUPPORT_NETDEV
+            if(!NetDeviceWrite((unsigned long)address, len, (void *)p))
+#endif
+			sil_wrw_mem((VP)address, *((UW *)p));
+		}
+		else{
+#ifdef SUPPORT_NETDEV
+			len = 1;
+			if(NetDeviceActive() && address == H8IER){
+				save_ier = *((UB *)p);
+				if(save_ier & (1<<H8IER_IRQ1E_BIT))
+					NetDeviceSetInt(IRQ_EXT1, (void (*)(VP))vector[IRQ_EXT1]);
+				else
+					NetDeviceSetInt(IRQ_EXT1, 0);
+				if(save_ier & (1<<H8IER_IRQ2E_BIT))
+					NetDeviceSetInt(IRQ_EXT2, (void (*)(VP))vector[IRQ_EXT2]);
+				else
+					NetDeviceSetInt(IRQ_EXT2, 0);
+			}
+			else if(address == H8IPRA || address == H8IPRB)
+				sil_wrb_mem((VP)address, *((UB *)p));
+            else if(!NetDeviceWrite((unsigned long)address, len, (void *)p))
+				sil_wrb_mem((VP)address, *((UB *)p));
+#else
+			len = 1;
+			sil_wrb_mem((VP)address, *((UB *)p));
+#endif
+		}
+		break;
+	case MEMORY_AREA:
+		if(getMemoryType(address, 1) == MREAD_ONLY){
+			len = 0;
+		}
+		else if(type == 2){
+			len = 2;
+			*((UH *)address) = *((UH *)p);
+		}
+		else if(type == 4){
+			len = 4;
+			*((UW *)address) = *((UW *)p);
+		}
+		else{
+			len = 1;
+			*((UB *)address) = *((UB *)p);
+		}
+		break;
+	default:
+		len = 0;
+		break;
+	}
+	return len;
+}
+
+/******************************************************************************
+ * モニタ用関数
+ ******************************************************************************/
+/*
+ *  エクセプションの引数よりpcを取り出す関数
+ */
+ulong_t
+get_exception_pc(void * p_excinf)
+{
+	ulong_t pc;
+
+	pc = *(ulong_t*)((char*)p_excinf+16) & 0xffffff;
+	return pc;
+}
+
+/*
+ *  レジスタ内容の表示
+ */
+void
+display_registers(ID tskid)
+{
+	ER       ercd;
+	T_RTST   rtst;
+	T_REG    reg;
+	uint32_t pc;
+	uint8_t  ccr;
+
+	ercd = ref_tst(tskid, &rtst);
+	printf("tskid=%d ercd=%d rtst.tskpc=0x%x rtst.tsksp=0x%x\n", tskid, ercd, (int)rtst.tskpc, (int)rtst.tsksp);
+
+	if(ercd == E_OK){
+		if(rtst.tskpc == (FP)_kernel_break_wait){
+			reg = *((T_REG *)rtst.tsksp);
+			pc  = reg.pc & 0xffffff;
+			ccr = reg.pc >> 24;
+			printf("  PC=%08lx SP=%08lx", (unsigned long)pc, (unsigned long)rtst.tsksp+sizeof(T_REG));
+			printf(" I=%1x UI=%1x H=%1x", (ccr>>7) & 1, (ccr>>6) & 1, (ccr>>5) & 1);
+			printf(" U=%1x N=%1x Z=%1x", (ccr>>4) & 1, (ccr>>3) & 1, (ccr>>2) & 1);
+			printf(" V=%1x C=%1x    R6=%08x\n", (ccr>>1) & 1, ccr & 1, reg.er6);
+			printf("  R0=%08x R1=%08x R2=%08x", reg.er0, reg.er1, reg.er2);
+			printf(" R3=%08x R4=%08x R5=%08x\n", reg.er3, reg.er4, reg.er5);
+			printf("     %08lx    %02x %02x\n", (unsigned long)pc, *((UB*)pc), *((UB*)(pc+1)));
+			return;
+		}
+		else if(rtst.tskstat == TTS_DMT){
+			printf("  wait in activate_r() !!\n");
+			return;
+		}
+	}
+	printf("  wait in dispatch() !!\n");
+}
+
+/******************************************************************************
+ * エラー通知用関数
+ ******************************************************************************/
+/*
+ * イレギュラーエクセプション
+ */
+void
+irregular_ext_handler(void * p_excinf)
+{
+	uint32_t pc = get_exception_pc(p_excinf);
+
+	if(p_runtsk){
+		if(_kernel_intnest > 1){
+			syslog_2(LOG_EMERG, "Irregular Exception occured in not task Context pc=0x%x p_excinf=0x%x !", pc, p_excinf);
+			target_exit();
+		}
+		else{
+			syslog_3(LOG_ERROR, "Irregular Exception occured in tskid=%d pc=0x%x p_excinf=0x%x !", TSKID(p_runtsk), pc, p_excinf);
+			isus_tsk(TSKID(p_runtsk));
+		}
+	}
+	else{
+		syslog_2(LOG_EMERG, "Irregular Exception occured in Idle pc=0x%x p_excinf=0x%x !", pc, p_excinf);
+		target_exit();
+	}
+}
+
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/monitor/arch/m16c.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/monitor/arch/m16c.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/monitor/arch/m16c.c	(revision 457)
@@ -0,0 +1,330 @@
+/*
+ *  TOPPERS/ASP Educative Program
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Just Standard Profile Kernel
+ * 
+ *  Copyright (C) 2003-2009 by Ryosuke Takeuchi
+ *               Platform Development Center RICOH COMPANY,LTD. JAPAN
+ * 
+ *  上記著作権者は，Free Software Foundation によって公表されている 
+ *  GNU General Public License の Version 2 に記述されている条件か，以
+ *  下の(1)～(4)の条件を満たす場合に限り，本ソフトウェア（本ソフトウェ
+ *  アを改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを再利用可能なバイナリコード（リロケータブルオブ
+ *      ジェクトファイルやライブラリなど）の形で利用する場合には，利用
+ *      に伴うドキュメント（利用者マニュアルなど）に，上記の著作権表示，
+ *      この利用条件および下記の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを再利用不可能なバイナリコードの形または機器に組
+ *      み込んだ形で利用する場合には，次のいずれかの条件を満たすこと．
+ *    (a) 利用に伴うドキュメント（利用者マニュアルなど）に，上記の著作
+ *        権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 利用の形態を，別に定める方法によって，上記著作権者に報告する
+ *        こと．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者を免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者は，
+ *  本ソフトウェアに関して，その適用可能性も含めて，いかなる保証も行わ
+ *  ない．また，本ソフトウェアの利用により直接的または間接的に生じたい
+ *  かなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/* 
+ *  TOPPERS/ASP用タスクモニタCPU依存プログラム．
+ *
+ */
+
+#include <itron.h>
+#include <sil.h>
+#include <stdio.h>
+#include "kernel_impl.h"
+#include "task.h"
+#include "task_expansion.h"
+#include "monitor.h"
+
+extern void _kernel_break_wait();
+
+/*
+ * レジスタの構造体
+ */
+typedef struct t_reg{
+	uint16_t r0;
+	uint16_t r1;
+	uint16_t r2;
+	uint16_t r3;
+	uint16_t a0;
+	uint16_t a1;
+	uint16_t sb;
+	uint16_t fb;
+	uint16_t lpc;
+	uint8_t  lflg;
+	uint8_t  hpc;
+}T_REG;
+
+/*
+ * メモリのマッピング定義構造体
+ */
+
+typedef struct t_memdef{
+	uint32_t mstart;
+	uint32_t mend;
+	uint8_t  mtype;
+	uint8_t  mstate;
+}T_MEMDEF;
+
+/*
+ * M16Cのメモリマッピング
+ */
+
+static T_MEMDEF const memdefine[] = {
+	0x00000000,	0x000003FF, PORT_AREA,   MREAD_WRITE,
+#if defined(OAKS16)
+	0x00000400, 0x00002BFF, MEMORY_AREA, MREAD_WRITE,
+	0x000E0000, 0x000FFFFF, MEMORY_AREA, MREAD_ONLY
+#elif defined(OAKS16_MINI)
+	0x00000400, 0x00000BFF, MEMORY_AREA, MREAD_WRITE,
+	0x000F0000, 0x000FFFFF, MEMORY_AREA, MREAD_ONLY
+#else
+	0x00000400, 0x000033FF, MEMORY_AREA, MREAD_WRITE,
+	0x000E0000, 0x000FFFFF, MEMORY_AREA, MREAD_ONLY
+#endif
+};
+
+/******************************************************************************
+ * ハードウェアポート属性参照関数
+ ******************************************************************************/
+/*
+ *  アドレスからメモリ領域属性を取り出す
+ *  mode=0:領域の型
+ *  mode=1:読み取り書き込み属性
+ */
+
+char
+getMemoryType(ulong_t address, int_t mode)
+{
+	int_t count = sizeof(memdefine) / sizeof(T_MEMDEF);
+	int_t i;
+
+	for(i = 0 ; i < count ; i++){
+		if(address >= memdefine[i].mstart && address <= memdefine[i].mend){
+			if(mode == 0)
+				return memdefine[i].mtype;
+			else
+				return memdefine[i].mstate;
+		}
+	}
+	return NONE_AREA;
+}
+
+/*
+ *  アドレスからアライン後のアドレスを取り出す
+ */
+
+ulong_t
+MonAlignAddress(ulong_t address)
+{
+	return address;
+}
+
+/******************************************************************************
+ * メモリアクセス用関数
+ ******************************************************************************/
+/*
+ *  メモリ領域に対する読み出し関数
+ *  領域のチェックを行い、エラーならゼロを返す
+ */
+int_t
+MemoryRead(ulong_t address, intptr_t p, int_t type)
+{
+	int_t len;
+
+	switch(getMemoryType(address, 0)){
+	case PORT_AREA:
+		if(type == 2){
+			len = 2;
+			*((UH _far *)p) = sil_reh_mem((VP)address);
+		}
+		else if(type == 4){
+			len = 4;
+			*((UW _far *)p) = sil_rew_mem((VP)address);
+		}
+		else{
+			len = 1;
+			*((UB _far *)p) = sil_reb_mem((VP)address);
+		}
+		break;
+	case MEMORY_AREA:
+		if(type == 2){
+			len = 2;
+			*((UH _far *)p) = *((UH _far *)address);
+		}
+		else if(type == 4){
+			len = 4;
+			*((UW _far *)p) = *((UW _far *)address);
+		}
+		else{
+			len = 1;
+			*((UB _far *)p) = *((UB _far *)address);
+		}
+		break;
+	default:
+		len = 0;
+		break;
+	}
+	return len;
+}
+
+/*
+ *  メモリ領域に対する書き込み関数
+ *  領域のチェックを行い、エラーならゼロを返す
+ */
+int_t
+MemoryWrite(ulong_t address, intptr_t p, int_t type)
+{
+	int_t len;
+
+	switch(getMemoryType(address, 0)){
+	case PORT_AREA:
+		if(type == 2){
+			len = 2;
+			sil_wrh_mem((VP)address, *((UH _far *)p));
+		}
+		else if(type == 4){
+			len = 4;
+			sil_wrw_mem((VP)address, *((UW _far *)p));
+		}
+		else{
+			len = 1;
+			sil_wrb_mem((VP)address, *((UB _far *)p));
+		}
+		break;
+	case MEMORY_AREA:
+		if(getMemoryType(address, 1) == MREAD_ONLY){
+			len = 0;
+		}
+		else if(type == 2){
+			len = 2;
+			*((UH _far *)address) = *((UH _far *)p);
+		}
+		else if(type == 4){
+			len = 4;
+			*((UW _far *)address) = *((UW _far *)p);
+		}
+		else{
+			len = 1;
+			*((UB _far *)address) = *((UB _far *)p);
+		}
+		break;
+	default:
+		len = 0;
+		break;
+	}
+	return len;
+}
+
+/******************************************************************************
+ * モニタ用関数
+ ******************************************************************************/
+/*
+ *  エクセプションの引数よりpcを取り出す関数
+ */
+ulong_t
+get_exception_pc(void * p_excinf)
+{
+	ulong_t pc;
+
+	pc = *(uint16_t*)((char*)p_excinf+16) | ((ulong_t)(*((char*)p_excinf+19) & 0xf) << 16);
+	return pc;
+}
+
+/*
+ *  レジスタ内容の表示
+ */
+void
+display_registers(ID tskid)
+{
+	ER       ercd;
+	T_RTST   rtst;
+	T_REG    reg;
+	uint32_t pc;
+
+	ercd = ref_tst(tskid, &rtst);
+	if(ercd == E_OK){
+		if(rtst.tskpc == (FP)_kernel_break_wait){
+			reg = *((T_REG *)rtst.tsksp);
+			pc = reg.lpc | (((UW)reg.hpc & 0xf)<<16);
+			printf("  PC=%06lx SP=%04x", (unsigned long)pc, (UW)rtst.tsksp+sizeof(T_REG));
+			printf("       IPL=%1x U=%1x I=%1x", (reg.hpc>>4) & 0x7, (reg.lflg>>7) & 1, (reg.lflg>>6) & 1);
+			printf(" O=%1x B=%1x S=%1x", (reg.lflg>>5) & 1, (reg.lflg>>4) & 1, (reg.lflg>>3) & 1);
+			printf(" Z=%1x D=%1x C=%1x\n", (reg.lflg>>2) & 1, (reg.lflg>>1) & 1, reg.lflg & 1);
+			printf("  R0=%04x R1=%04x R2=%04x", reg.r0, reg.r1, reg.r2);
+			printf(" R3=%04x A0=%04x A1=%04x", reg.r3, reg.a0, reg.a1);
+			printf(" SB=%04x FB=%04x\n", reg.sb, reg.fb);
+			printf("     %06lx    %02x %02x\n", (unsigned long)pc, *((UB*)pc), *((UB*)(pc+1)));
+			return;
+		}
+		else if(rtst.tskstat == TTS_DMT){
+			printf("  wait in activate_r() !!\n");
+			return;
+		}
+	}
+	printf("  wait in dispatch() !!\n");
+}
+
+#if 0
+/******************************************************************************
+ * エラー通知用関数
+ ******************************************************************************/
+/*
+ * イレギュラー割込みハンドラー
+ */
+void
+irregular_int_handler(void)
+{
+	if(runtsk){
+		if(intnest > 1){
+			syslog_1(LOG_EMERG, "Irregular Interrupt occured in tskid=%d !", TSKID(runtsk));
+			kernel_exit();
+		}
+		else{
+			syslog_1(LOG_ERROR, "Irregular Interrupt occured in tskid=%d  !", TSKID(runtsk));
+			isus_tsk(TSKID(runtsk));
+		}
+	}
+	else{
+		syslog_0(LOG_EMERG, "Irregular Interrupt occured in Idle!");
+		kernel_exit();
+	}
+}
+
+/*
+ * イレギュラーエクセプション
+ */
+void
+irregular_ext_handler(VP p_excinf)
+{
+	UW pc = get_exception_pc(p_excinf);
+
+	if(runtsk){
+		if(exc_sense_context(p_excinf)){
+			syslog_1(LOG_EMERG, "Irregular Exception occured in not task Context pc=0x%x !", pc);
+			kernel_exit();
+		}
+		else{
+			syslog_2(LOG_ERROR, "Irregular Exception occured in tskid=%d pc=0x%x !", TSKID(runtsk), pc);
+			isus_tsk(TSKID(runtsk));
+		}
+	}
+	else{
+		syslog_1(LOG_EMERG, "Irregular Exception occured in Idle pc=0x%x !", pc);
+		kernel_exit();
+	}
+}
+#endif
+
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/monitor/arch/powerpc32.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/monitor/arch/powerpc32.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/monitor/arch/powerpc32.c	(revision 457)
@@ -0,0 +1,351 @@
+/*
+ *  TOPPERS/ASP Educative Program
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Just Standard Profile Kernel
+ * 
+ *  Copyright (C) 2003-2009 by Ryosuke Takeuchi
+ *                     GJ Business Division RICOH COMPANY,LTD. JAPAN
+ * 
+ *  上記著作権者は，Free Software Foundation によって公表されている 
+ *  GNU General Public License の Version 2 に記述されている条件か，以
+ *  下の(1)～(4)の条件を満たす場合に限り，本ソフトウェア（本ソフトウェ
+ *  アを改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを再利用可能なバイナリコード（リロケータブルオブ
+ *      ジェクトファイルやライブラリなど）の形で利用する場合には，利用
+ *      に伴うドキュメント（利用者マニュアルなど）に，上記の著作権表示，
+ *      この利用条件および下記の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを再利用不可能なバイナリコードの形または機器に組
+ *      み込んだ形で利用する場合には，次のいずれかの条件を満たすこと．
+ *    (a) 利用に伴うドキュメント（利用者マニュアルなど）に，上記の著作
+ *        権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 利用の形態を，別に定める方法によって，上記著作権者に報告する
+ *        こと．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者を免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者は，
+ *  本ソフトウェアに関して，その適用可能性も含めて，いかなる保証も行わ
+ *  ない．また，本ソフトウェアの利用により直接的または間接的に生じたい
+ *  かなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/* 
+ *  TOPPERS/JSP用タスクモニタCPU依存プログラム．
+ *
+ */
+
+#include <itron.h>
+#include <sil.h>
+#include <stdio.h>
+#include "kernel_impl.h"
+#include "task.h"
+#include "task_expansion.h"
+#ifdef SUPPORT_ETHER
+#include "netdevice.h"
+#endif
+#include "monitor.h"
+
+extern void _kernel_break_wait();
+
+#define set_align(a, b)	((UW)a & ~(b-1))
+
+/*
+ * レジスタの構造体
+ */
+typedef struct t_reg{
+#ifdef SUPPORT_FLOATING_POINT_REG
+	UW  memo_msr;
+	UW  memo_off;
+	UW  fps[33*2+1];
+#endif	/* SUPPORT_FLOATING_POINT_REG */
+	UW  r13;
+	UW  r14;
+	UW  r15;
+	UW  r16;
+	UW  r17;
+	UW  r18;
+	UW  r19;
+	UW  r20;
+	UW  r21;
+	UW  r22;
+	UW  r23;
+	UW  r24;
+	UW  r25;
+	UW  r26;
+	UW  r27;
+	UW  r28;
+	UW  r29;
+	UW  r30;
+	UW  r31;
+	UW  lr2;
+
+	UW	r0;
+	UW	r3;
+	UW	r4;
+	UW	r5;
+	UW	r6;
+	UW	r7;
+	UW	r8;
+	UW	r9;
+	UW	r10;
+	UW	r11;
+	UW	r12;
+	UW	srr0;
+	UW	srr1;
+	UW  lr;
+	UW	ctr;
+	UW	cr;
+	UW	xer;
+	UW  dummy;
+}T_REG;
+
+/*
+ * メモリのマッピング定義構造体
+ */
+
+typedef struct t_memdef{
+	UW	mstart;
+	UW	mend;
+	UB	mtype;
+	UB	mstate;
+}T_MEMDEF;
+
+/*
+ * POWERPC32のメモリマッピング
+ */
+
+static T_MEMDEF const memdefine[] = {
+	{0x00000000, 0x0FFFFFFF, MEMORY_AREA, MREAD_WRITE},
+#ifdef SUPPORT_MIRROR_MEMORY
+	{0x20000000, 0x2FFFFFFF, MEMORY_AREA, MREAD_WRITE},
+#endif
+#if defined(SANTAMARIA)
+	{0xEC000000, 0xEC7FFFFF, MEMORY_AREA, MREAD_ONLY },
+	{0xFF400000, 0xFF4FFFFF, PORT_AREA,   MREAD_WRITE},
+	{0xFFF00000, 0xFFFFFFFF, MEMORY_AREA, MREAD_ONLY }
+#elif defined(EP440XC)
+	{0xE0000000, 0xE00004FF, PORT_AREA,   MREAD_ONLY },
+	{0xE0010000, 0xE0013FFF, MEMORY_AREA, MREAD_WRITE},
+	{0xEF600000, 0xEF6011FF, PORT_AREA,   MREAD_WRITE},
+	{0xFFF00000, 0xFFFFFFFF, MEMORY_AREA, MREAD_ONLY }
+#elif defined(EP460XC)
+	{0xD8000000, 0xD8FFFFFF, PORT_AREA,   MREAD_WRITE},
+	{0xE2000000, 0xE20FFFFF, PORT_AREA,   MREAD_WRITE},
+	{0xEF600000, 0xEF6011FF, PORT_AREA,   MREAD_WRITE},
+	{0xFFF00000, 0xFFFFFFFF, MEMORY_AREA, MREAD_ONLY }
+#else
+#error "No board type in POWERPC32 groups."
+#endif
+};
+
+static T_REG  sreg;
+
+/******************************************************************************
+ * ハードウェアポート属性参照関数
+ ******************************************************************************/
+/*
+ *  アドレスからメモリ領域属性を取り出す
+ *  mode=0:領域の型
+ *  mode=1:読み取り書き込み属性
+ */
+
+UB
+getMemoryType(UW address, INT mode)
+{
+	INT count = sizeof(memdefine) / sizeof(T_MEMDEF);
+	INT i;
+
+	for(i = 0 ; i < count ; i++){
+		if(address >= memdefine[i].mstart && address <= memdefine[i].mend){
+			if(mode == 0)
+				return memdefine[i].mtype;
+			else
+				return memdefine[i].mstate;
+		}
+	}
+	return NONE_AREA;
+}
+
+/*
+ *  アドレスからアライン後のアドレスを取り出す
+ */
+
+UW
+MonAlignAddress(UW address)
+{
+	return address;
+}
+
+/******************************************************************************
+ * メモリアクセス用関数
+ ******************************************************************************/
+/*
+ *  メモリ領域に対する読み出し関数
+ *  領域のチェックを行い、エラーならゼロを返す
+ */
+INT
+MemoryRead(UW address, VP_INT p, INT type)
+{
+	INT  len;
+
+	switch(getMemoryType(address, 0)){
+	case PORT_AREA:
+		if(type == 2){
+			len = 2;
+#ifdef PANEL_SIMULATION
+            if(!NetDeviceRead((unsigned long)address, len, (void *)p))
+#endif
+			asm("eieio");
+			*((UH *)p) = sil_reh_mem((VP)address);
+		}
+		else if(type == 4){
+			len = 4;
+#ifdef PANEL_SIMULATION
+            if(!NetDeviceRead((unsigned long)address, len, (void *)p))
+#endif
+			*((UW *)p) = sil_rew_mem_ppc((VP)address);
+		}
+		else{
+#ifdef PANEL_SIMULATION
+			len = 1;
+            if(!NetDeviceRead((unsigned long)address, len, (void *)p))
+				*((UB *)p) = sil_reb_mem_ppc((VP)address);
+#else
+			len = 1;
+			*((UB *)p) = sil_reb_mem_ppc((VP)address);
+#endif
+		}
+		break;
+	case MEMORY_AREA:
+		if(type == 2){
+			len = 2;
+			*((UH *)p) = *((UH *)set_align(address, len));
+		}
+		else if(type == 4){
+			len = 4;
+			*((UW *)p) = *((UW *)set_align(address, len));
+		}
+		else{
+			len = 1;
+			*((UB *)p) = *((UB *)address);
+		}
+		break;
+	default:
+		len = 0;
+		break;
+	}
+	return len;
+}
+
+/*
+ *  メモリ領域に対する書き込み関数
+ *  領域のチェックを行い、エラーならゼロを返す
+ */
+INT
+MemoryWrite(UW address, VP_INT p, INT type)
+{
+	INT  len;
+
+	switch(getMemoryType(address, 0)){
+	case PORT_AREA:
+		if(type == 2){
+			len = 2;
+			address = set_align(address, len);
+#ifdef PANEL_SIMULATION
+            if(!NetDeviceWrite((unsigned long)address, len, (void *)p))
+#endif
+			sil_wrh_mem((VP)address, *((UH *)p));
+		}
+		else if(type == 4){
+			len = 4;
+			address = set_align(address, len);
+#ifdef PANEL_SIMULATION
+            if(!NetDeviceWrite((unsigned long)address, len, (void *)p))
+#endif
+			sil_wrw_mem((VP)address, *((UW *)p));
+		}
+		else{
+#ifdef PANEL_SIMULATION
+			len = 1;
+            if(!NetDeviceWrite((unsigned long)address, len, (void *)p))
+				sil_wrb_mem((VP)address, *((UB *)p));
+#else
+			len = 1;
+			sil_wrb_mem((VP)address, *((UB *)p));
+#endif
+		}
+		break;
+	case MEMORY_AREA:
+		if(getMemoryType(address, 1) == MREAD_ONLY){
+			len = 0;
+		}
+		else if(type == 2){
+			len = 2;
+			*((UH *)address) = *((UH *)set_align(p, len));
+		}
+		else if(type == 4){
+			len = 4;
+			*((UW *)address) = *((UW *)set_align(p, len));
+		}
+		else{
+			len = 1;
+			*((UB *)address) = *((UB *)p);
+		}
+		break;
+	default:
+		len = 0;
+		break;
+	}
+	return len;
+}
+
+/******************************************************************************
+ * モニタ用関数
+ ******************************************************************************/
+/*
+ *  レジスタ内容の表示
+ */
+void
+display_registers(ID tskid)
+{
+	ER     ercd;
+	T_RTST rtst;
+
+	ercd = ref_tst(tskid, &rtst);
+	if(ercd == E_OK){
+		if(rtst.tskpc == (FP)_kernel_break_wait){
+			sreg = *((T_REG *)(rtst.tsksp-4));
+			printf(" PC =%08lx SP =%08x MSR =%08x", (long)sreg.srr0, (UW)((long)rtst.tsksp+sizeof(T_REG)), sreg.srr1);
+			printf(" LR =%08x CTR=%08x CR=%08x\n", sreg.lr, sreg.ctr, sreg.cr);
+			printf(" R0 =%08x R3 =%08x R4 =%08x", sreg.r0, sreg.r3, sreg.r4);
+			printf(" R5 =%08x R6 =%08x R7 =%08x\n", sreg.r5, sreg.r6, sreg.r7);
+			printf(" R8 =%08x R9 =%08x R10=%08x", sreg.r8, sreg.r9, sreg.r10);
+			printf(" R11=%08x R12=%08x R13=%08x\n", sreg.r11, sreg.r12, sreg.r13);
+			printf(" R14=%08x R15=%08x R16=%08x\n", sreg.r14, sreg.r15, sreg.r16);
+			printf(" R17=%08x R18=%08x R19=%08x\n", sreg.r17, sreg.r18, sreg.r19);
+			printf(" R20=%08x R21=%08x R22=%08x\n", sreg.r20, sreg.r21, sreg.r22);
+			printf(" R23=%08x R24=%08x R25=%08x\n", sreg.r23, sreg.r24, sreg.r25);
+			printf(" R26=%08x R27=%08x R28=%08x\n", sreg.r26, sreg.r27, sreg.r28);
+			printf(" R29=%08x R30=%08x R31=%08x\n", sreg.r29, sreg.r30, sreg.r31);
+			printf(" XER=%08x\n", sreg.xer);
+			printf("     %08lx    %08x\n", (long)sreg.srr0, *((UW*)sreg.srr0));
+			return;
+		}
+		else if(rtst.tskstat == TTS_DMT){
+			printf("  wait in activate_r() !!\n");
+			return;
+		}
+	}
+	printf("  wait in dispatch() !!\n");
+}
+
+
+void __va_arg_type_violation(void)
+{}
+
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/monitor/arch/riscv32.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/monitor/arch/riscv32.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/monitor/arch/riscv32.c	(revision 457)
@@ -0,0 +1,261 @@
+/*
+ *  TOPPERS/ASP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Advanced Standard Profile Kernel
+ * 
+ *  Copyright (C) 2003-2016 by Ryosuke Takeuchi
+ *                     GJ Business Division RICOH COMPANY,LTD. JAPAN
+ *  Copyright (C) 2017-2019 by TOPPERS PROJECT Educational Working Group.
+ * 
+ *  上記著作権者は，Free Software Foundation によって公表されている 
+ *  GNU General Public License の Version 2 に記述されている条件か，以
+ *  下の(1)～(4)の条件を満たす場合に限り，本ソフトウェア（本ソフトウェ
+ *  アを改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを再利用可能なバイナリコード（リロケータブルオブ
+ *      ジェクトファイルやライブラリなど）の形で利用する場合には，利用
+ *      に伴うドキュメント（利用者マニュアルなど）に，上記の著作権表示，
+ *      この利用条件および下記の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを再利用不可能なバイナリコードの形または機器に組
+ *      み込んだ形で利用する場合には，次のいずれかの条件を満たすこと．
+ *    (a) 利用に伴うドキュメント（利用者マニュアルなど）に，上記の著作
+ *        権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 利用の形態を，別に定める方法によって，上記著作権者に報告する
+ *        こと．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者を免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者は，
+ *  本ソフトウェアに関して，その適用可能性も含めて，いかなる保証も行わ
+ *  ない．また，本ソフトウェアの利用により直接的または間接的に生じたい
+ *  かなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/* 
+ *  TOPPERS/ASP用タスクモニタCPU依存プログラム．
+ *
+ */
+
+#include <itron.h>
+#include <sil.h>
+#include <stdio.h>
+#include "kernel_impl.h"
+#include "task.h"
+#include "task_expansion.h"
+#include "monitor.h"
+
+extern void dispatch_r(void);
+
+#define set_align(a, b)	((ulong_t)a & ~(b-1))
+
+/*
+ * レジスタの構造体
+ */
+typedef struct t_reg{
+	uint32_t ra;
+	uint32_t gp;
+	uint32_t tp;
+	uint32_t s0;
+	uint32_t s1;
+	uint32_t s2;
+	uint32_t s3;
+	uint32_t s4;
+	uint32_t s5;
+}T_REG;
+
+/*
+ * メモリのマッピング定義構造体
+ */
+
+typedef struct t_memdef{
+	uint32_t mstart;
+	uint32_t mend;
+	uint8_t  mtype;
+	uint8_t  mstate;
+}T_MEMDEF;
+
+/*
+ * RISC-V/32のメモリマッピング
+ */
+
+static T_MEMDEF const memdefine[] = {
+	{0x00000000, 0x1FFFFFFF,           PORT_AREA,   MREAD_WRITE},
+#if defined(TOPPERS_HIFIVE1)
+	{0x20000000, 0x3FFFFFFF,           MEMORY_AREA, MREAD_ONLY },
+	{0x80000000, 0x80003FFF,           MEMORY_AREA, MREAD_WRITE},
+#else
+#error "No support board type in RISC-V/32 groups."
+#endif
+};
+
+static T_REG  sreg;
+
+/******************************************************************************
+ * ハードウェアポート属性参照関数
+ ******************************************************************************/
+/*
+ *  アドレスからメモリ領域属性を取り出す
+ *  mode=0:領域の型
+ *  mode=1:読み取り書き込み属性
+ */
+
+char
+getMemoryType(ulong_t address, int_t mode)
+{
+	int_t count = sizeof(memdefine) / sizeof(T_MEMDEF);
+	int_t i;
+
+	for(i = 0 ; i < count ; i++){
+		if(address >= memdefine[i].mstart && address <= memdefine[i].mend){
+			if(mode == 0)
+				return memdefine[i].mtype;
+			else
+				return memdefine[i].mstate;
+		}
+	}
+	return NONE_AREA;
+}
+
+/*
+ *  アドレスからアライン後のアドレスを取り出す
+ */
+
+ulong_t
+MonAlignAddress(ulong_t address)
+{
+	return address;
+}
+
+/******************************************************************************
+ * メモリアクセス用関数
+ ******************************************************************************/
+/*
+ *  メモリ領域に対する読み出し関数
+ *  領域のチェックを行い、エラーならゼロを返す
+ */
+int_t
+MemoryRead(ulong_t address, intptr_t p, int_t type)
+{
+	int_t len;
+
+	switch(getMemoryType(address, 0)){
+	case PORT_AREA:
+		if(type == 2){
+			len = 2;
+			*((UH *)p) = sil_reh_mem((VP)address);
+		}
+		else if(type == 4){
+			len = 4;
+			*((UW *)p) = sil_rew_mem((VP)address);
+		}
+		else{
+			len = 1;
+			*((UB *)p) = sil_reb_mem((VP)address);
+		}
+		break;
+	case MEMORY_AREA:
+		if(type == 2){
+			len = 2;
+			*((UH *)p) = *((UH *)set_align(address, len));
+		}
+		else if(type == 4){
+			len = 4;
+			*((UW *)p) = *((UW *)set_align(address, len));
+		}
+		else{
+			len = 1;
+			*((UB *)p) = *((UB *)address);
+		}
+		break;
+	default:
+		len = 0;
+		break;
+	}
+	return len;
+}
+
+/*
+ *  メモリ領域に対する書き込み関数
+ *  領域のチェックを行い、エラーならゼロを返す
+ */
+int_t
+MemoryWrite(ulong_t address, intptr_t p, int_t type)
+{
+	int_t len;
+
+	switch(getMemoryType(address, 0)){
+	case PORT_AREA:
+		if(type == 2){
+			len = 2;
+			address = set_align(address, len);
+			sil_wrh_mem((VP)address, *((UH *)p));
+		}
+		else if(type == 4){
+			len = 4;
+			address = set_align(address, len);
+			sil_wrw_mem((VP)address, *((UW *)p));
+		}
+		else{
+			len = 1;
+			sil_wrb_mem((VP)address, *((UB *)p));
+		}
+		break;
+	case MEMORY_AREA:
+		if(getMemoryType(address, 1) == MREAD_ONLY){
+			len = 0;
+		}
+		else if(type == 2){
+			len = 2;
+			*((UH *)address) = *((UH *)set_align(p, len));
+		}
+		else if(type == 4){
+			len = 4;
+			*((UW *)address) = *((UW *)set_align(p, len));
+		}
+		else{
+			len = 1;
+			*((UB *)address) = *((UB *)p);
+		}
+		break;
+	default:
+		len = 0;
+		break;
+	}
+	return len;
+}
+
+/******************************************************************************
+ * モニタ用関数
+ ******************************************************************************/
+/*
+ *  レジスタ内容の表示
+ */
+void
+display_registers(ID tskid)
+{
+	ER     ercd;
+	T_RTST rtst;
+
+	ercd = ref_tst(tskid, &rtst);
+	if(ercd == E_OK){
+		if(rtst.tskpc == (FP)dispatch_r){
+			sreg = *((T_REG *)rtst.tsksp);
+			printf(" RA  =%08lx SP =%08x\n", (long)sreg.ra, (UW)((long)rtst.tsksp+sizeof(T_REG)));
+			printf(" GP  =%08x TP =%08x S0 =%08x S1 =%08x\n", sreg.gp, sreg.tp, sreg.s0, sreg.s1);
+			printf(" S2  =%08x S3 =%08x S4 =%08x S5 =%08x\n", sreg.s2, sreg.s3, sreg.s4, sreg.s5);
+			printf("     %08lx    %04x\n", (long)sreg.ra, *((UH*)(sreg.ra & ~1)));
+			return;
+		}
+		else if(rtst.tskstat == TTS_DMT){
+			printf("  wait in activate_r() !!\n");
+			return;
+		}
+	}
+	printf("  wait in dispatch() !!\n");
+}
+
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/monitor/arch/riscv64.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/monitor/arch/riscv64.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/monitor/arch/riscv64.c	(revision 457)
@@ -0,0 +1,265 @@
+/*
+ *  TOPPERS/ASP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Advanced Standard Profile Kernel
+ * 
+ *  Copyright (C) 2003-2016 by Ryosuke Takeuchi
+ *                     GJ Business Division RICOH COMPANY,LTD. JAPAN
+ *  Copyright (C) 2017-2019 by TOPPERS PROJECT Educational Working Group.
+ * 
+ *  上記著作権者は，Free Software Foundation によって公表されている 
+ *  GNU General Public License の Version 2 に記述されている条件か，以
+ *  下の(1)～(4)の条件を満たす場合に限り，本ソフトウェア（本ソフトウェ
+ *  アを改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを再利用可能なバイナリコード（リロケータブルオブ
+ *      ジェクトファイルやライブラリなど）の形で利用する場合には，利用
+ *      に伴うドキュメント（利用者マニュアルなど）に，上記の著作権表示，
+ *      この利用条件および下記の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを再利用不可能なバイナリコードの形または機器に組
+ *      み込んだ形で利用する場合には，次のいずれかの条件を満たすこと．
+ *    (a) 利用に伴うドキュメント（利用者マニュアルなど）に，上記の著作
+ *        権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 利用の形態を，別に定める方法によって，上記著作権者に報告する
+ *        こと．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者を免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者は，
+ *  本ソフトウェアに関して，その適用可能性も含めて，いかなる保証も行わ
+ *  ない．また，本ソフトウェアの利用により直接的または間接的に生じたい
+ *  かなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/* 
+ *  TOPPERS/ASP用タスクモニタCPU依存プログラム．
+ *
+ */
+
+#include <itron.h>
+#include <sil.h>
+#include <stdio.h>
+#include "kernel_impl.h"
+#include "task.h"
+#include "task_expansion.h"
+#include "monitor.h"
+
+extern void dispatch_r(void);
+
+#define set_align(a, b)	((ulong_t)a & ~(b-1))
+
+/*
+ * レジスタの構造体
+ */
+typedef struct t_reg{
+	unsigned long ra;
+	unsigned long gp;
+	unsigned long tp;
+	unsigned long s0;
+	unsigned long s1;
+	unsigned long s2;
+	unsigned long s3;
+	unsigned long s4;
+	unsigned long s5;
+}T_REG;
+
+/*
+ * メモリのマッピング定義構造体
+ */
+
+typedef struct t_memdef{
+	uintptr_t mstart;
+	uint32_t  mend;
+	uint8_t   mtype;
+	uint8_t   mstate;
+}T_MEMDEF;
+
+/*
+ * RISC-V/64のメモリマッピング
+ */
+
+static T_MEMDEF const memdefine[] = {
+	{0x02000000L, 0x02FFFFFFL,         PORT_AREA,   MREAD_WRITE},
+	{0x0C000000L, 0x0CFFFFFFL,         PORT_AREA,   MREAD_WRITE},
+	{0x38000000L, 0x3807FFFFL,         PORT_AREA,   MREAD_WRITE},
+	{0x40000000L, 0x413FFFFFL,         PORT_AREA,   MREAD_WRITE},
+	{0x50000000L, 0x543FFFFFL,         PORT_AREA,   MREAD_WRITE},
+#if defined(TOPPERS_K210)
+	{0x80000000L, 0x807FFFFFL,         MEMORY_AREA, MREAD_WRITE},
+	{0x88000000L, 0x881FFFFFL,         MEMORY_AREA, MREAD_ONLY },
+#else
+#error "No support board type in RISC-V/64 groups."
+#endif
+};
+
+static T_REG  sreg;
+
+/******************************************************************************
+ * ハードウェアポート属性参照関数
+ ******************************************************************************/
+/*
+ *  アドレスからメモリ領域属性を取り出す
+ *  mode=0:領域の型
+ *  mode=1:読み取り書き込み属性
+ */
+
+char
+getMemoryType(ulong_t address, int_t mode)
+{
+	int_t count = sizeof(memdefine) / sizeof(T_MEMDEF);
+	int_t i;
+
+	for(i = 0 ; i < count ; i++){
+		if(address >= memdefine[i].mstart && address <= memdefine[i].mend){
+			if(mode == 0)
+				return memdefine[i].mtype;
+			else
+				return memdefine[i].mstate;
+		}
+	}
+	return NONE_AREA;
+}
+
+/*
+ *  アドレスからアライン後のアドレスを取り出す
+ */
+
+ulong_t
+MonAlignAddress(ulong_t address)
+{
+	return address;
+}
+
+/******************************************************************************
+ * メモリアクセス用関数
+ ******************************************************************************/
+/*
+ *  メモリ領域に対する読み出し関数
+ *  領域のチェックを行い、エラーならゼロを返す
+ */
+int_t
+MemoryRead(ulong_t address, intptr_t p, int_t type)
+{
+	int_t len;
+
+	switch(getMemoryType(address, 0)){
+	case PORT_AREA:
+		if(type == 2){
+			len = 2;
+			*((UH *)p) = sil_reh_mem((VP)address);
+		}
+		else if(type == 4){
+			len = 4;
+			*((UW *)p) = sil_rew_mem((VP)address);
+		}
+		else{
+			len = 1;
+			*((UB *)p) = sil_reb_mem((VP)address);
+		}
+		break;
+	case MEMORY_AREA:
+		if(type == 2){
+			len = 2;
+			*((UH *)p) = *((UH *)set_align(address, len));
+		}
+		else if(type == 4){
+			len = 4;
+			*((UW *)p) = *((UW *)set_align(address, len));
+		}
+		else{
+			len = 1;
+			*((UB *)p) = *((UB *)address);
+		}
+		break;
+	default:
+		len = 0;
+		break;
+	}
+	return len;
+}
+
+/*
+ *  メモリ領域に対する書き込み関数
+ *  領域のチェックを行い、エラーならゼロを返す
+ */
+int_t
+MemoryWrite(ulong_t address, intptr_t p, int_t type)
+{
+	int_t len;
+
+	switch(getMemoryType(address, 0)){
+	case PORT_AREA:
+		if(type == 2){
+			len = 2;
+			address = set_align(address, len);
+			sil_wrh_mem((VP)address, *((UH *)p));
+		}
+		else if(type == 4){
+			len = 4;
+			address = set_align(address, len);
+			sil_wrw_mem((VP)address, *((UW *)p));
+		}
+		else{
+			len = 1;
+			sil_wrb_mem((VP)address, *((UB *)p));
+		}
+		break;
+	case MEMORY_AREA:
+		if(getMemoryType(address, 1) == MREAD_ONLY){
+			len = 0;
+		}
+		else if(type == 2){
+			len = 2;
+			*((UH *)address) = *((UH *)set_align(p, len));
+		}
+		else if(type == 4){
+			len = 4;
+			*((UW *)address) = *((UW *)set_align(p, len));
+		}
+		else{
+			len = 1;
+			*((UB *)address) = *((UB *)p);
+		}
+		break;
+	default:
+		len = 0;
+		break;
+	}
+	return len;
+}
+
+/******************************************************************************
+ * モニタ用関数
+ ******************************************************************************/
+/*
+ *  レジスタ内容の表示
+ */
+void
+display_registers(ID tskid)
+{
+	ER     ercd;
+	T_RTST rtst;
+
+	ercd = ref_tst(tskid, &rtst);
+	if(ercd == E_OK){
+		if(rtst.tskpc == (FP)dispatch_r){
+			sreg = *((T_REG *)rtst.tsksp);
+			printf(" RA  =%lx SP =%lx\n", (long)sreg.ra, (long)((long)rtst.tsksp+sizeof(T_REG)));
+			printf(" GP  =%lx TP =%lx S0 =%lx S1 =%lx\n", sreg.gp, sreg.tp, sreg.s0, sreg.s1);
+			printf(" S2  =%lx S3 =%lx S4 =%lx S5 =%lx\n", sreg.s2, sreg.s3, sreg.s4, sreg.s5);
+			printf("     %lx    %04x\n", (long)sreg.ra, *((UH*)(sreg.ra & ~1)));
+			return;
+		}
+		else if(rtst.tskstat == TTS_DMT){
+			printf("  wait in activate_r() !!\n");
+			return;
+		}
+	}
+	printf("  wait in dispatch() !!\n");
+}
+
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/monitor/arch/sh2.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/monitor/arch/sh2.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/monitor/arch/sh2.c	(revision 457)
@@ -0,0 +1,396 @@
+/*
+ *  TOPPERS/ASP Educative Program
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Just Standard Profile Kernel
+ * 
+ *  Copyright (C) 2003-2008 by Ryosuke Takeuchi
+ *                     GJ Business Division RICOH COMPANY,LTD. JAPAN
+ * 
+ *  上記著作権者は，Free Software Foundation によって公表されている 
+ *  GNU General Public License の Version 2 に記述されている条件か，以
+ *  下の(1)～(4)の条件を満たす場合に限り，本ソフトウェア（本ソフトウェ
+ *  アを改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを再利用可能なバイナリコード（リロケータブルオブ
+ *      ジェクトファイルやライブラリなど）の形で利用する場合には，利用
+ *      に伴うドキュメント（利用者マニュアルなど）に，上記の著作権表示，
+ *      この利用条件および下記の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを再利用不可能なバイナリコードの形または機器に組
+ *      み込んだ形で利用する場合には，次のいずれかの条件を満たすこと．
+ *    (a) 利用に伴うドキュメント（利用者マニュアルなど）に，上記の著作
+ *        権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 利用の形態を，別に定める方法によって，上記著作権者に報告する
+ *        こと．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者を免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者は，
+ *  本ソフトウェアに関して，その適用可能性も含めて，いかなる保証も行わ
+ *  ない．また，本ソフトウェアの利用により直接的または間接的に生じたい
+ *  かなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/* 
+ *  TOPPERS/ASP用タスクモニタCPU依存プログラム．
+ *
+ */
+
+#include <itron.h>
+#include <sil.h>
+#include <stdio.h>
+#include "kernel_impl.h"
+#include "task.h"
+#include "task_expansion.h"
+#ifdef SUPPORT_ETHER
+#include "netdevice.h"
+#endif
+#include "monitor.h"
+
+extern void _kernel_break_wait();
+#ifdef SUPPORT_ETHER
+extern unsigned long vectors[];
+#endif
+
+#define set_align(a, b)	((UW)a & ~(b-1))
+
+/*
+ * レジスタの構造体
+ */
+typedef struct t_reg{
+	uint32_t gbr;
+	uint32_t macl;
+	uint32_t mach;
+	uint32_t r14;
+	uint32_t r13;
+	uint32_t r12;
+	uint32_t r11;
+	uint32_t r10;
+	uint32_t r9;
+	uint32_t r8;
+	uint32_t pr;
+	uint32_t r7;
+	uint32_t r6;
+	uint32_t r5;
+	uint32_t r4;
+	uint32_t r3;
+	uint32_t r2;
+	uint32_t r1;
+	uint32_t r0;
+	uint32_t pc;
+	uint32_t sr;
+}T_REG;
+
+/*
+ * メモリのマッピング定義構造体
+ */
+
+typedef struct t_memdef{
+	uint32_t mstart;
+	uint32_t mend;
+	uint8_t  mtype;
+	uint8_t  mstate;
+}T_MEMDEF;
+
+/*
+ * SH2のメモリマッピング
+ */
+
+static T_MEMDEF const memdefine[] = {
+#if defined(HSB7616IT)
+	{0x00000000, 0x0001FFFF, MEMORY_AREA, MREAD_ONLY },
+	{0x02000000, 0x021FFFFF, MEMORY_AREA, MREAD_ONLY },
+	{0x04000000, 0x040FFFFF, MEMORY_AREA, MREAD_WRITE},
+	{0xFFFFE000, 0xFFFFFFFF, PORT_AREA,   MREAD_WRITE}
+#elif defined(MS72060SEP01)
+	{0x00000000, 0x001FFFFF, MEMORY_AREA, MREAD_ONLY },
+	{0x01000000, 0x01FFFFFF, MEMORY_AREA, MREAD_ONLY },
+	{0x0C000000, 0x0FFFFFFF, MEMORY_AREA, MREAD_WRITE},
+	{0x10000000, 0xFFF7FFFF, PORT_AREA,   MREAD_WRITE},
+	{0xFFF80000, 0xFFF9FFFF, MEMORY_AREA, MREAD_WRITE},
+	{0xFFFA0000, 0xFFFFFFFF, PORT_AREA,   MREAD_WRITE}
+#elif defined(CRB_H3)
+	{0x00000000, 0x0003FFFF, MEMORY_AREA, MREAD_ONLY },
+	{0x00200000, 0x0021FFFF, MEMORY_AREA, MREAD_WRITE},
+	{0x00220000, 0x0022FFFF, MEMORY_AREA, MREAD_ONLY },
+	{0x00230000, 0x0023FFFF, PORT_AREA,   MREAD_WRITE},
+	{0xFFF00000, 0xFFFCFFFF, PORT_AREA,   MREAD_WRITE},
+	{0xFFFD0000, 0xFFFFFFFF, MEMORY_AREA, MREAD_WRITE}
+#else
+#error "No board type in SH2 groups."
+#endif
+};
+
+static T_REG  sreg;
+
+/******************************************************************************
+ * ハードウェアポート属性参照関数
+ ******************************************************************************/
+/*
+ *  アドレスからメモリ領域属性を取り出す
+ *  mode=0:領域の型
+ *  mode=1:読み取り書き込み属性
+ */
+
+char
+getMemoryType(ulong_t address, int_t mode)
+{
+	int_t count = sizeof(memdefine) / sizeof(T_MEMDEF);
+	int_t i;
+
+	for(i = 0 ; i < count ; i++){
+		if(address >= memdefine[i].mstart && address <= memdefine[i].mend){
+			if(mode == 0)
+				return memdefine[i].mtype;
+			else
+				return memdefine[i].mstate;
+		}
+	}
+	return NONE_AREA;
+}
+
+/*
+ *  アドレスからアライン後のアドレスを取り出す
+ */
+
+ulong_t
+MonAlignAddress(ulong_t address)
+{
+	return address;
+}
+
+/******************************************************************************
+ * メモリアクセス用関数
+ ******************************************************************************/
+/*
+ *  メモリ領域に対する読み出し関数
+ *  領域のチェックを行い、エラーならゼロを返す
+ */
+int_t
+MemoryRead(ulong_t address, intptr_t p, int_t type)
+{
+	int_t len;
+
+	switch(getMemoryType(address, 0)){
+	case PORT_AREA:
+		if(type == 2){
+			len = 2;
+#ifdef SUPPORT_ETHER
+            if(!NetDeviceRead((unsigned long)address, len, (void *)p))
+#endif
+			*((UH *)p) = sil_reh_mem((VP)address);
+		}
+		else if(type == 4){
+			len = 4;
+#ifdef SUPPORT_ETHER
+            if(!NetDeviceRead((unsigned long)address, len, (void *)p))
+#endif
+			*((UW *)p) = sil_rew_mem((VP)address);
+		}
+		else{
+#ifdef SUPPORT_ETHER
+			len = 1;
+            if(!NetDeviceRead((unsigned long)address, len, (void *)p))
+				*((UB *)p) = sil_reb_mem((VP)address);
+#else
+			len = 1;
+			*((UB *)p) = sil_reb_mem((VP)address);
+#endif
+		}
+		break;
+	case MEMORY_AREA:
+		if(type == 2){
+			len = 2;
+			*((UH *)p) = *((UH *)set_align(address, len));
+		}
+		else if(type == 4){
+			len = 4;
+			*((UW *)p) = *((UW *)set_align(address, len));
+		}
+		else{
+			len = 1;
+			*((UB *)p) = *((UB *)address);
+		}
+		break;
+	default:
+		len = 0;
+		break;
+	}
+	return len;
+}
+
+/*
+ *  メモリ領域に対する書き込み関数
+ *  領域のチェックを行い、エラーならゼロを返す
+ */
+int_t
+MemoryWrite(ulong_t address, intptr_t p, int_t type)
+{
+	int_t len;
+
+	switch(getMemoryType(address, 0)){
+	case PORT_AREA:
+		if(type == 2){
+			len = 2;
+			address = set_align(address, len);
+#ifdef SUPPORT_ETHER
+            if(!NetDeviceWrite((unsigned long)address, len, (void *)p))
+#endif
+			sil_wrh_mem((VP)address, *((UH *)p));
+		}
+		else if(type == 4){
+			len = 4;
+			address = set_align(address, len);
+#ifdef SUPPORT_ETHER
+            if(!NetDeviceWrite((unsigned long)address, len, (void *)p))
+#endif
+			sil_wrw_mem((VP)address, *((UW *)p));
+		}
+		else{
+#ifdef SUPPORT_ETHER
+			len = 1;
+            if(!NetDeviceWrite((unsigned long)address, len, (void *)p))
+				sil_wrb_mem((VP)address, *((UB *)p));
+#else
+			len = 1;
+			sil_wrb_mem((VP)address, *((UB *)p));
+#endif
+		}
+		break;
+	case MEMORY_AREA:
+		if(getMemoryType(address, 1) == MREAD_ONLY){
+			len = 0;
+		}
+		else if(type == 2){
+			len = 2;
+			*((UH *)address) = *((UH *)set_align(p, len));
+		}
+		else if(type == 4){
+			len = 4;
+			*((UW *)address) = *((UW *)set_align(p, len));
+		}
+		else{
+			len = 1;
+			*((UB *)address) = *((UB *)p);
+		}
+		break;
+	default:
+		len = 0;
+		break;
+	}
+	return len;
+}
+
+/******************************************************************************
+ * モニタ用関数
+ ******************************************************************************/
+/*
+ *  エクセプションの引数よりpcを取り出す関数
+ */
+ulong_t
+get_exception_pc(void * p_excinf)
+{
+	ulong_t pc;
+
+	pc = *(ulong_t*)((char*)p_excinf-4);
+	return pc;
+}
+
+/*
+ *  レジスタ内容の表示
+ */
+void
+display_registers(ID tskid)
+{
+	ER     ercd;
+	T_RTST rtst;
+
+	ercd = ref_tst(tskid, &rtst);
+	if(ercd == E_OK){
+		if(rtst.tskpc == (FP)_kernel_break_wait){
+			sreg = *((T_REG *)rtst.tsksp);
+			printf(" PC =%08lx SP =%08x PR =%08x", (long)sreg.pc, (UW)((long)rtst.tsksp+sizeof(T_REG)), sreg.pr);
+			printf(" SR =%08x MBH=%08x MBL=%08x\n", sreg.sr, sreg.mach, sreg.macl);
+			printf(" R0 =%08x R1 =%08x R2 =%08x", sreg.r0, sreg.r1, sreg.r2);
+			printf(" R3 =%08x R4 =%08x R5 =%08x\n", sreg.r3, sreg.r4, sreg.r5);
+			printf(" R6 =%08x R7 =%08x R8 =%08x", sreg.r6, sreg.r7, sreg.r8);
+			printf(" R9 =%08x R10=%08x R11=%08x\n", sreg.r9, sreg.r10, sreg.r11);
+			printf(" R12=%08x R13=%08x R14=%08x\n", sreg.r12, sreg.r13, sreg.r14);
+			printf("     %08lx    %02x %02x\n", (long)sreg.pc, *((UB*)sreg.pc), *((UB*)(sreg.pc+1)));
+			return;
+		}
+		else if(rtst.tskstat == TTS_DMT){
+			printf("  wait in activate_r() !!\n");
+			return;
+		}
+	}
+	printf("  wait in dispatch() !!\n");
+}
+
+/******************************************************************************
+ * エラー通知用関数
+ ******************************************************************************/
+/*
+ * イレギュラーエクセプション
+ */
+static void
+irregular_ext_handler(void *p_excinf, const char *s)
+{
+	uint32_t pc = get_exception_pc(p_excinf);
+
+	if(runtsk){
+		if(exc_sense_context(p_excinf)){
+			syslog_3(LOG_EMERG, "Irregular Exception(%s) occured in not task Context pc=0x%x p_excinf=0x%x !", s, pc, p_excinf);
+			kernel_exit();
+		}
+		else{
+			syslog_4(LOG_ERROR, "Irregular Exception(%s) occured in tskid=%d pc=0x%x p_excinf=0x%x !", s, TSKID(runtsk), pc, p_excinf);
+			isus_tsk(TSKID(runtsk));
+		}
+	}
+	else{
+		syslog_3(LOG_EMERG, "Irregular Exception(%s) occured in Idle pc=0x%x p_excinf=0x%x !", s, pc, p_excinf);
+		kernel_exit();
+	}
+}
+
+/*
+ *  一般不当命令:General Illegal Instruction
+ */
+void
+irregular_extgii_handler(void * p_excinf)
+{
+	irregular_ext_handler(p_excinf, "GII");
+}
+
+/*
+ *  スロット不当命令:Slot Illegal Instruction
+ */
+void
+irregular_extsii_handler(void * p_excinf)
+{
+	irregular_ext_handler(p_excinf, "SII");
+}
+
+/*
+ *  CPUアドレスエラー:CPU Address Error
+ */
+void
+irregular_extcae_handler(void * p_excinf)
+{
+	irregular_ext_handler(p_excinf, "CAE");
+}
+
+/*
+ *  DMAアドレスエラー:DMA Address Error
+ */
+void
+irregular_extdae_handler(void * p_excinf)
+{
+	irregular_ext_handler(p_excinf, "DAE");
+}
+
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/monitor/monitor.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/monitor/monitor.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/monitor/monitor.c	(revision 457)
@@ -0,0 +1,1091 @@
+/*
+ *  TOPPERS/ASP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Advanced Standard Profile Kernel
+ * 
+ *  Copyright (C) 2003-2015 by Ryosuke Takeuchi
+ *                     GJ Business Division RICOH COMPANY,LTD. JAPAN
+ *  Copyright (C) 2017-2019 by TOPPERS PROJECT Educational Working Group.
+ * 
+ *  上記著作権者は，Free Software Foundation によって公表されている 
+ *  GNU General Public License の Version 2 に記述されている条件か，以
+ *  下の(1)～(4)の条件を満たす場合に限り，本ソフトウェア（本ソフトウェ
+ *  アを改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを再利用可能なバイナリコード（リロケータブルオブ
+ *      ジェクトファイルやライブラリなど）の形で利用する場合には，利用
+ *      に伴うドキュメント（利用者マニュアルなど）に，上記の著作権表示，
+ *      この利用条件および下記の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを再利用不可能なバイナリコードの形または機器に組
+ *      み込んだ形で利用する場合には，次のいずれかの条件を満たすこと．
+ *    (a) 利用に伴うドキュメント（利用者マニュアルなど）に，上記の著作
+ *        権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 利用の形態を，別に定める方法によって，上記著作権者に報告する
+ *        こと．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者を免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者は，
+ *  本ソフトウェアに関して，その適用可能性も含めて，いかなる保証も行わ
+ *  ない．また，本ソフトウェアの利用により直接的または間接的に生じたい
+ *  かなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/* 
+ *  TOPPERS/ASP用タスクモニタプログラム．
+ *
+ */
+
+#include <kernel.h>
+#include <stdio.h>
+#include <t_syslog.h>
+#include <t_stdlib.h>
+#include <string.h>
+#include "syssvc/serial.h"
+#include "syssvc/syslog.h"
+#include "task_expansion.h"
+#include "task.h"
+#include "kernel_cfg.h"
+#include "monitor.h"
+
+#ifndef NUM_ARGC
+#define NUM_ARGC    16
+#endif
+
+/*
+ *  サービスコールのエラーのログ出力
+ */
+Inline void
+svc_perror(const char *file, int_t line, const char *expr, ER ercd)
+{
+	if (ercd < 0) {
+		t_perror(LOG_ERROR, file, line, expr, ercd);
+	}
+}
+
+#define	SVC_PERROR(expr)	svc_perror(__FILE__, __LINE__, #expr, (expr))
+
+/*
+ *  モニタ内定義
+ */
+#define	HEX_VALUE			16			/* 16進指定 */
+#define	DEC_VALUE			10			/* 10進指定 */
+
+#define	MONDISPLAY_BYTE	DATA_BYTE	/* バイト単位メモリ表示 */
+#define	MONDISPLAY_HALF	DATA_HALF	/* ハーフ単位メモリ表示 */
+#define	MONDISPLAY_WORD	DATA_WORD	/* ワード単位メモリ表示 */
+#define	MONDISPLAY_TASK	3			/* タスク状態表示 */
+#define	MONDISPLAY_REG	5			/* レジスタの表示 */
+#define	MONDISPLAY_ASM	6
+
+#define	MONSET_BYTE		DATA_BYTE	/* バイト単位メモリ設定 */
+#define	MONSET_HALF		DATA_HALF	/* ハーフ単位メモリ設定 */
+#define	MONSET_WORD		DATA_WORD	/* ワード単位メモリ設定 */
+#define	MONSET_COMMAND	3			/* コマンドモード設定 */
+#define	MONSET_SERIAL	5			/* シリアル設定 */
+#define	MONSET_TASK		6			/* タスク設定 */
+#define MONSET_IN       7			/* 入力設定 */
+
+struct SUBCOMMAND_TABLE {
+	const char *subcommand;			/* サブコマンド文 */
+	const char type;				/* 実行タイプ */
+};
+
+/*
+ *  プロトタイプ宣言
+ *
+ *  このモジュール内で使用している関数
+ */
+static void    prompt(ID tskid);
+static int_t   dispatch_command(int argc, char **argv);
+static int_t   display_command(int argc, char **argv);
+static int_t   set_command(int argc, char **argv);
+static int_t   help_command(int argc, char **argv);
+static int_t   task_activate(int argc, char **argv);
+static int_t   task_terminate(int argc, char **argv);
+static int_t   task_suspend(int argc, char **argv);
+static int_t   task_resume(int argc, char **argv);
+static int_t   task_release(int argc, char **argv);
+static int_t   task_wakeup(int argc, char **argv);
+static int_t   task_priority(int argc, char **argv);
+static int_t   log_mode(int argc, char **argv);
+static int_t   log_task(int argc, char **argv);
+static int_t   log_port(int argc, char **argv);
+static uint_t  get_taskstate(STAT tskstat);
+static char    monitor_getstring(char *s, int *len);
+
+extern const char	*itron_strerror(ER ercd);
+
+/*
+ *  モニタバナー表示
+ */
+static char const banner[] = "\n"
+"ASP TASK Monitor Release %d.%d.%d for " TARGET_NAME
+" (" __DATE__ ", " __TIME__ ")\n"
+"Copyright (C) 2016-2019 by TOPPERS PROJECT Educational Working Group\n";
+
+/*
+ *  ヘルプメッセージ
+ */
+static char const display_help[] =
+"  Display BYTE     [start address] [end address]\n"
+"          HALF     [start address] [end address]\n"
+"          WORD     [start address] [end address]\n"
+"          TASK\n"
+"          REGISTER\n";
+
+static char const set_help[] =
+"  Set     BYTE     [start address]\n"
+"          HALF     [start address]\n"
+"          WORD     [start address]\n"
+"          COMMAND  [mode]  mode=1 or (2)\n"
+"          SERIAL   [port id]\n"
+"          TASK     [task id]\n";
+
+static char const task_help[] =
+"  Task    ACTIVATE          (act_tsk)\n"
+"          TERMINATE         (ter_tsk)\n"
+"          SUSPEND           (sus_tsk)\n"
+"          RESUME            (rsm_tsk)\n"
+"          RELEASE           (rel_tsk)\n"
+"          WAKEUP            (wup_tsk)\n"
+"          PRIORITY [pri]    (chg_pri)\n";
+
+static char const log_help[] =
+"  Log     MODE     [logmask] [lowmask]\n"
+"          TASK     [cycle time(ms)] [count]\n"
+"          PORT     [no] [logno] [portaddress]\n";
+
+static char const help_help[] =
+"  Help    [arg1]\n";
+
+/*
+ *  タスクコマンドサブテーブル
+ */
+static const COMMAND_INFO task_command_info[] = {
+	{"ACTIVATE",	task_activate},
+	{"TERMINATE",	task_terminate},
+	{"SUSPEND",		task_suspend},
+	{"RESUME",		task_resume},
+	{"RELEASE",		task_release},
+	{"WAKEUP",		task_wakeup},
+	{"PRIORITY",	task_priority}
+};
+
+/*
+ *  ログコマンドサブテーブル
+ */
+static const COMMAND_INFO log_command_info[] = {
+	{"MODE",		log_mode},
+	{"TASK",		log_task},
+	{"PORT",		log_port}
+};
+
+/*
+ *  メインコマンドテーブル
+ */
+static COMMAND_LINK const standard_command[] = {
+	{NULL,	0,	"DISPLAY",	display_command,	display_help,	NULL },
+	{NULL,	0,	"SET",		set_command,		set_help,		NULL },
+	{NULL,	7,	"TASK",		NULL,				task_help,		task_command_info },
+	{NULL,	3,	"LOG",		NULL,				log_help,		log_command_info },
+	{NULL,	0,	"HELP",		help_command,		help_help,		NULL }
+};
+
+/*
+ *  表示コマンドテーブル
+ */
+static struct SUBCOMMAND_TABLE const mon_display[] = {
+	{"BYTE",		MONDISPLAY_BYTE },	/* バイト単位メモリ表示 */
+	{"HALF",		MONDISPLAY_HALF },	/* ハーフ単位メモリ表示 */
+	{"WORD",		MONDISPLAY_WORD },	/* ワード単位メモリ表示 */
+	{"TASK",		MONDISPLAY_TASK },	/* タスク状態表示 */
+	{"REGISTER",	MONDISPLAY_REG  },	/* タスクレジスター表示 */
+	{"ASSEMBLER",	MONDISPLAY_ASM  }	/* アセンブラー表示 */
+};
+
+/*
+ *  設定コマンドテーブル
+ */
+static struct SUBCOMMAND_TABLE const mon_set[] = {
+	{"BYTE",		MONSET_BYTE     },	/* バイト単位メモリ設定 */
+	{"HALF",		MONSET_HALF     },	/* ハーフ単位メモリ設定 */
+	{"WORD",		MONSET_WORD     },	/* ワード単位メモリ設定 */
+	{"COMMAND",		MONSET_COMMAND  },	/* コマンドモード設定 */
+	{"SERIAL",		MONSET_SERIAL   },	/* シリアル設定 */
+	{"TASK",		MONSET_TASK     },	/* タスク選択 */
+	{"IN",			MONSET_IN       }	/* 入力設定 */
+};
+
+/*
+ *  バックスペース
+ */
+static const char backspace[] = "\b \b";
+
+/*
+ *  タスクモード表示テーブル
+ */
+#define	TSTATE_LEN		11
+
+static char const task_state[6][TSTATE_LEN] = {
+	"RUNNING",						/* 実行中 */
+	"RUNNABLE",						/* 実行できる状態 */
+	"WAITING",						/* 待ち状態 */
+	"SUSPENDED",					/* 強制待ち状態 */
+	"WSUSPENDED",					/* 二重待ち状態 */
+	"DORMANT"						/* 休止状態 */
+};
+
+/*
+ *  ロギングモード表示テーブル
+ */
+static char const log_mode_name[8][12] = {
+	"LOG_EMERG",					/* シャットダウンに値するエラー */
+	"LOG_ALERT",
+	"LOG_CRIT",
+	"LOG_ERROR",					/* システムエラー */
+	"LOG_WARNING",					/* 警告メッセージ */
+	"LOG_NOTICE",
+	"LOG_INFO",
+	"LOG_DEBUG"						/* デバッグ用メッセージ */
+};
+
+/*
+ * モニタで使用されるデータ領域
+ */
+static ID      current_tskid;			/* モニタが対象とするタスク */
+static char    mon_command[MAX_COMMAND_LENGTH+1];
+static char    mon_datatype;			/* モニタが指定するデータタイプのデフォルト値 */
+static ulong_t mon_address;				/* モニタが指定するアドレスのデフォルト値 */
+static int_t   mon_mode;				/* モニタが指定するコマンドモード */
+static uint_t  mon_logmask;				/* モニタが指定する記録／出力すべき重要度 */
+static uint_t  mon_lowmask;				/* モニタが指定する低レベル出力すべき重要度 */
+static ID      mon_default_portid;		/* モニタのデフォルトポートID */
+static FILE    *mon_infile;				/* モニタの入力ファイル */
+static COMMAND_LINK *pheadcmd;
+
+ID             mon_portid;				/* モニタのデバイスポートID */
+
+/*
+ *  モニタタスク
+ */
+void monitor(intptr_t exinf)
+{
+	int    no, argc, cno, len;
+	char   *argv[NUM_ARGC], c;
+
+	/* モニタで使用するデータの初期化 */
+
+	mon_portid   = mon_default_portid = (ID)exinf;
+	mon_datatype = DATA_BYTE;
+	mon_logmask  = LOG_NOTICE;
+	mon_lowmask  = LOG_EMERG;
+	current_tskid = MONTASK;
+	mon_infile   = stdin;
+
+	if(mon_portid != CONSOLE_PORTID)
+		SVC_PERROR(serial_opn_por(mon_portid));
+#ifdef NEED_MONITOR
+	if(!need_monitor())
+		ext_tsk();
+#endif	/* NEED_MONITOR */
+#ifndef NOINIT_STDIO_MONITOR
+	_setup_stdio(&mon_portid);
+#endif	/* NOTSET_STDIO_MONITOR */
+#ifdef MONITOR_DELAY
+	dly_tsk(MONITOR_DELAY);
+#endif	/* MONITOR_DELAY */
+	printf(banner,
+		(TMONITOR_PRVER >> 12) & 0x0f,
+		(TMONITOR_PRVER >> 4) & 0xff,
+		TMONITOR_PRVER & 0x0f);
+	SVC_PERROR(syslog_msk_log(LOG_UPTO(mon_logmask), LOG_UPTO(mon_lowmask)));
+	SVC_PERROR(serial_ctl_por(mon_portid, (IOCTL_CRLF | IOCTL_FCSND | IOCTL_FCRCV)));
+
+	/* モニタのメインのデスパッチ */
+
+	do{
+		prompt(current_tskid);
+		c = monitor_getstring(mon_command, &len);
+		/*
+		 *  引数の設定
+		 */
+		for(no = argc = cno = 0 ; argc < 16 && no < len ; no++){
+			if(test_next_char(mon_command[no])){
+				mon_command[no] = 0;
+				cno = 0;
+			}
+			else if(no < len){
+				if(cno == 0)
+					argv[argc++] = &mon_command[no];
+				cno++;
+			}
+		}
+		mon_command[no] = 0;
+
+		putecho('\n');
+		no = dispatch_command(argc, argv);
+		fflush(NULL);
+	}while(c != KEY_EXT);
+	printf("exit monitor !!\n");
+}
+
+/*
+ *  モニタのプロンプトの表示
+ *
+ *  指定のタスクIDがモニタ以外の場合は
+ *  タスクの状態によってプロンプトの表示内容を変更する．
+ */
+static void
+prompt(ID tskid)
+{
+	T_RTSK rtsk;
+
+	if(tskid == MONTASK)
+		printf("mon");
+	else{
+		ref_tsk(tskid, &rtsk);
+		printf("%03d(%s)", tskid, task_state[get_taskstate(rtsk.tskstat)]);
+	}
+	putchar('>');
+	fflush(NULL);
+}
+
+/*
+ *  コマンドのデスパッチ
+ */
+static int_t
+dispatch_command(int argc, char **argv)
+{
+	COMMAND_LINK *pcmd = (COMMAND_LINK *)standard_command;
+	const COMMAND_INFO *pscmd;
+	int no, sno, count;
+
+	if(argc > 0){
+		count = sizeof(standard_command) / sizeof(COMMAND_LINK);
+		for(no = 0 ; no < count ; no++, pcmd++){
+			if(compare_word(pcmd->command, argv[0], mon_mode)){
+				if(pcmd->num_command == 0){
+					if(pcmd->func != NULL){
+						pcmd->func(argc-1, &argv[1]);
+						return no;
+					}
+					else
+						return -1;
+				}
+				for(sno = 0, pscmd = pcmd->pcinfo ; sno < pcmd->num_command; sno++, pscmd++){
+					if(compare_word(pscmd->command, argv[1], mon_mode)){
+						pscmd->func(argc-1, &argv[1]);
+						return sno;
+					}
+				}
+			}
+		}
+		pcmd = pheadcmd;
+		while(pcmd){
+			if(compare_word(pcmd->command, argv[0], mon_mode)){
+				for(sno = 0, pscmd = pcmd->pcinfo ; sno < pcmd->num_command; sno++, pscmd++){
+					if(compare_word(pscmd->command, argv[1], mon_mode)){
+						pscmd->func(argc-1, &argv[1]);
+						return sno;
+					}
+				}
+			}
+			pcmd = pcmd->pcnext;
+		}
+	}
+	return -1;
+}
+
+/*
+ *  コマンドセットアップ
+ */
+int
+setup_command(COMMAND_LINK *pcmd)
+{
+	COMMAND_LINK *pbcmd = pheadcmd;
+
+	if(pcmd == NULL)
+		return -1;
+	pcmd->pcnext = NULL;
+	if(pbcmd == NULL){
+		pheadcmd = pcmd;
+		return 0;
+	}
+	while(pbcmd != NULL){
+		if(pbcmd == pcmd)
+			return -1;
+		else if(pbcmd->pcnext == NULL)
+			break;
+		pbcmd = pbcmd->pcnext;
+	}
+	pbcmd->pcnext = pcmd;
+	return 0;
+}
+
+/*
+ *  表示コマンド
+ */
+static int_t
+display_command(int argc, char **argv)
+{
+	char     cmd=0;
+	T_RTST   rtst;
+	char     b;
+	uint16_t h;
+	ulong_t  w, value1, value2;
+	int      no, count;
+
+	count = sizeof(mon_display) / sizeof(struct SUBCOMMAND_TABLE);
+	if(argc > 0){
+		for(no = 0 ; no < count ; no++){
+			if(compare_word(mon_display[no].subcommand, argv[0], 0)){
+				cmd = mon_display[no].type;
+				break;
+			}
+		}
+	}
+	switch(cmd){
+	default:						/* デフォルト */
+		cmd = mon_datatype;
+	case MONDISPLAY_BYTE:			/* バイト単位メモリ表示 */
+	case MONDISPLAY_HALF:			/* ハーフ単位メモリ表示 */
+	case MONDISPLAY_WORD:			/* ワード単位メモリ表示 */
+		value2 = 128;
+		if(argc < 2 || !get_value(argv[1], &value1, HEX_VALUE))
+			value1 = mon_address;
+		value1 = MonAlignAddress(value1);
+		if(argc > 2){
+			if(*argv[2] == '+'){
+				if(!get_value(argv[2]+1, &value2, HEX_VALUE))
+					value2 = 128;
+			}
+			else{
+				if(!get_value(argv[2], &value2, HEX_VALUE))
+					value2 = value1 + 128;
+				value2 -= value1;
+			}
+		}
+		mon_datatype = cmd;
+		while((W)value2 > 0){
+			printf("%08lx  ", (long)value1);
+			for(no = 0 ; no < 16 ; no += mon_datatype){
+				if(no == 8)
+					putchar(' ');
+				switch(mon_datatype){
+				case DATA_HALF:
+					if(MemoryRead(value1+no, (intptr_t)&h, 2) == 0)
+						h = -1;
+					printf("%04x  ", h);
+					break;
+				case DATA_WORD:
+					if(MemoryRead(value1+no, (intptr_t)&w, 4) == 0)
+						w = -1;
+					printf("%08lx    ", (long)w);
+					break;
+				default:
+					if(MemoryRead(value1+no, (intptr_t)&b, 1) == 0)
+						b = -1;
+					printf("%02x ", b);
+					break;
+				}
+			}
+			if(getMemoryType(value1+no, 0) == MEMORY_AREA){
+				for(no = 0 ; no < 16 ; no++){
+					if(MemoryRead(value1+no, (intptr_t)&b, 1)){
+						if(b < ' ' || b >= 0xE0)
+							b = '.';
+						else if(b >= 127 && b < 0xA0)
+							b = '.';
+					}
+					else
+						b = '.';
+					putchar(b);
+				}
+			}
+			putchar('\n');
+			value1 += 16;
+			value2 -= 16;
+			tslp_tsk(50);
+			if(monitor_break())
+				value2 = 0;
+		}
+		mon_address = value1;
+		break;
+	case MONDISPLAY_TASK:			/* タスク状態表示 */
+		printf("cur id  pri state      pc       stack    inistack inisize\n");
+		for(no = 0 ; no < tmax_tskid ; no++){
+			ref_tst(no+TMIN_TSKID, &rtst);
+			if(current_tskid == (no+TMIN_TSKID))
+				printf(" * ");
+			else
+				printf("   ");
+			if(MONTASK == (no+TMIN_TSKID))
+				printf(" mon");
+			else
+				printf(" %03d", no+TMIN_TSKID);
+			printf(" %3d ", rtst.tskpri);
+			value1 = get_taskstate(rtst.tskstat);
+			for(count = 0 ; count < TSTATE_LEN-1 ; count++){
+				if(task_state[value1][count] == 0)
+					putchar(' ');
+				else
+					putchar(task_state[value1][count]);
+			}
+			if(rtst.tskstat == TTS_RUN)
+				printf("         ");
+			else
+				printf(" %08lx", (unsigned long)rtst.tskpc);
+			printf(" %08lx %08lx %5ld\n", (unsigned long)rtst.tsksp, (unsigned long)rtst.inistk, (unsigned long)rtst.inistksz);
+		}
+		putchar('\n');
+		break;
+	case MONDISPLAY_REG:			/* レジスタの表示 */
+		if(current_tskid != MONTASK)
+			display_registers(current_tskid);
+		break;
+	}
+	return 0;
+}
+
+/*
+ *  設定コマンド
+ */
+static int_t
+set_command(int argc, char **argv)
+{
+	char     cmd=0;
+	char     b;
+	uint16_t h;
+	ulong_t  w, value1, value2;
+	int      no, count;
+	bool_t   cont;
+
+	count = sizeof(mon_set) / sizeof(struct SUBCOMMAND_TABLE);
+	if(argc > 0){
+		for(no = 0 ; no < count ; no++){
+			if(compare_word(mon_set[no].subcommand, argv[0], 0)){
+				cmd = mon_set[no].type;
+				break;
+			}
+		}
+	}
+	switch(cmd){
+	default:						/* デフォルト */
+		cmd = mon_datatype;
+	case MONSET_BYTE:				/* バイト単位メモリ設定 */
+	case MONSET_HALF:				/* ハーフ単位メモリ設定 */
+	case MONSET_WORD:				/* ワード単位メモリ設定 */
+		if(argc < 2 || !get_value(argv[1], &value1, HEX_VALUE))
+			value1 = mon_address;
+		value1 = MonAlignAddress(value1);
+		mon_datatype = cmd;
+		do{
+			printf("  %08lx", (unsigned long)value1);
+			switch(mon_datatype){
+			case DATA_HALF:
+				if(MemoryRead(value1, (intptr_t)&h, 2) == 0)
+					h = -1;
+				printf(" %04x =", h);
+				break;
+			case DATA_WORD:
+				if(MemoryRead(value1, (intptr_t)&w, 4) == 0)
+					w = -1;
+				printf(" %08lx =", (unsigned long)w);
+				break;
+			default:
+				if(MemoryRead(value1, (intptr_t)&b, 1) == 0)
+					b = -1;
+				printf(" %02x =", b);
+				break;
+			}
+			monitor_getstring(mon_command, &count);
+			if(get_value(mon_command, &value2, HEX_VALUE)){
+				switch(mon_datatype){
+				case DATA_HALF:
+					h = value2;
+					MemoryWrite(value1, (intptr_t)&h, 2);
+					if(MemoryRead(value1, (intptr_t)&h, 2) == 0)
+						h = -1;
+					printf(" %04x\n", h);
+					break;
+				case DATA_WORD:
+					w = value2;
+					MemoryWrite(value1, (intptr_t)&w, 4);
+					if(MemoryRead(value1, (intptr_t)&w, 4) == 0)
+						w = -1;
+					printf(" %08lx\n", (unsigned long)w);
+					break;
+				default:
+					b = value2;
+					MemoryWrite(value1, (intptr_t)&b, 1);
+					if(MemoryRead(value1, (intptr_t)&b, 1) == 0)
+						b = -1;
+					printf(" %02x\n", b);
+					break;
+				}
+				value1 += mon_datatype;
+				cont = true;
+			}
+			else
+				cont = false;
+		}while(cont);
+		putchar('\n');
+		mon_address = value1;
+		break;
+	case MONSET_COMMAND:			/* コマンドモード設定 */
+		if(argc > 1 && get_value(argv[1], &value1, DEC_VALUE)){
+			if(value1 == 1 || value1 == 2){
+				printf("  set %d command(s) mode !\n", (int)value1);
+				mon_mode = value1;
+			}
+		}
+		printf("  set command mode=%d word(s) !\n", mon_mode);
+		break;
+	case MONSET_SERIAL:				/* シリアル設定 */
+		if(argc > 1 && get_value(argv[1], &value1, DEC_VALUE)){
+			if(value1 > 0 && mon_portid != value1){
+				if(mon_portid != mon_default_portid && mon_portid != CONSOLE_PORTID)
+					SVC_PERROR(serial_cls_por(mon_portid));
+				mon_portid = value1;
+				if(mon_portid != mon_default_portid && mon_portid != CONSOLE_PORTID)
+					SVC_PERROR(serial_opn_por(mon_portid));
+				SVC_PERROR(serial_ctl_por(mon_portid, (IOCTL_CRLF | IOCTL_FCSND | IOCTL_FCRCV)));
+				printf(banner,
+					(TMONITOR_PRVER >> 12) & 0x0f,
+					(TMONITOR_PRVER >> 4) & 0xff,
+					TMONITOR_PRVER & 0x0f);
+			}
+		}
+		printf("  set serial port id=%d !\n", mon_portid);
+		break;
+	case MONSET_TASK:				/* タスク選択 */
+		if(argc > 1 && get_value(argv[1], &value1, DEC_VALUE)){
+			if(value1 >= TMIN_TSKID && value1 < (TMIN_TSKID+tmax_tskid))
+				current_tskid = value1;
+			else
+				current_tskid = MONTASK;
+		}
+		else
+			current_tskid = MONTASK;
+		break;
+	case MONSET_IN:					/* 入力設定 */
+		value1 = 0;
+		if(argc > 1)
+			get_value(argv[1], &value1, DEC_VALUE);
+		if(value1 == 1)
+			mon_infile = stdout;
+		else if(value1 == 2)
+			mon_infile = stderr;
+		else
+			mon_infile = stdin;
+		break;
+	}
+	return 0;
+}
+
+/*
+ *  ヘルプコマンド
+ */
+static int_t
+help_command(int argc, char **argv)
+{
+	COMMAND_LINK *pcmd = (COMMAND_LINK *)standard_command;
+	int no, count;
+
+	count = sizeof(standard_command) / sizeof(COMMAND_LINK);
+	for(no = 0 ; no < count ; no++, pcmd++){
+		if(argc > 0){
+			if(compare_word(pcmd->command, argv[0], 0)){
+				printf(pcmd->help);
+				return no;
+			}
+		}
+		else
+			printf(pcmd->help);
+	}
+	pcmd = pheadcmd;
+	while(pcmd){
+		if(argc > 0){
+			if(compare_word(pcmd->command, argv[0], 0)){
+				printf(pcmd->help);
+				return no;
+			}
+		}
+		else
+			printf(pcmd->help);
+		pcmd = pcmd->pcnext;
+	}
+	return 0;
+}
+
+/*
+ *  タスクコマンド、起動要求(act_tsk)
+ */
+static int_t
+task_activate(int argc, char **argv)
+{
+	ER      ercd = E_OK;
+
+	if(current_tskid == MONTASK){	/* モニタ自体の制御はできない */
+		printf(" Can't control the monitor!!\n");
+		return 0;
+	}
+	ercd = act_tsk(current_tskid);
+	printf("  execute act_tsk(%d) :: result = %s !\n", current_tskid, itron_strerror(ercd));
+	tslp_tsk(100);				/* スイッチング */
+	return 0;
+}
+
+/*
+ *  タスクコマンド、強制終了(ter_tsk)
+ */
+static int_t
+task_terminate(int argc, char **argv)
+{
+	ER      ercd = E_OK;
+
+	if(current_tskid == MONTASK){	/* モニタ自体の制御はできない */
+		printf(" Can't control the monitor!!\n");
+		return 0;
+	}
+	ercd = ter_tsk(current_tskid);
+	printf("  execute ter_tsk(%d) :: result = %s !\n", current_tskid, itron_strerror(ercd));
+	tslp_tsk(100);				/* スイッチング */
+	return 0;
+}
+
+/*
+ *  タスクコマンド、待ち要求(sus_tsk)
+ */
+static int_t
+task_suspend(int argc, char **argv)
+{
+	ER      ercd = E_OK;
+
+	if(current_tskid == MONTASK){	/* モニタ自体の制御はできない */
+		printf(" Can't control the monitor!!\n");
+		return 0;
+	}
+	ercd = sus_tsk(current_tskid);
+	printf("  execute sus_tsk(%d) :: result = %s !\n", current_tskid, itron_strerror(ercd));
+	tslp_tsk(100);				/* スイッチング */
+	return 0;
+}
+
+/*
+ *  タスクコマンド、待ち再開(rsm_tsk)
+ */
+static int_t
+task_resume(int argc, char **argv)
+{
+	ER      ercd = E_OK;
+
+	if(current_tskid == MONTASK){	/* モニタ自体の制御はできない */
+		printf(" Can't control the monitor!!\n");
+		return 0;
+	}
+	ercd = rsm_tsk(current_tskid);
+	printf("  execute rsm_tsk(%d) :: result = %s !\n", current_tskid, itron_strerror(ercd));
+	tslp_tsk(100);				/* スイッチング */
+	return 0;
+}
+
+/*
+ *  タスクコマンド、待ち解除(rel_wai)
+ */
+static int_t
+task_release(int argc, char **argv)
+{
+	ER      ercd = E_OK;
+
+	if(current_tskid == MONTASK){	/* モニタ自体の制御はできない */
+		printf(" Can't control the monitor!!\n");
+		return 0;
+	}
+	ercd = rel_wai(current_tskid);
+	printf("  execute rel_wai(%d) :: result = %s !\n", current_tskid, itron_strerror(ercd));
+	tslp_tsk(100);				/* スイッチング */
+	return 0;
+}
+
+/*
+ *  タスクコマンド、タスク起床(wup_tsk)
+ */
+static int_t
+task_wakeup(int argc, char **argv)
+{
+	ER      ercd = E_OK;
+
+	if(current_tskid == MONTASK){	/* モニタ自体の制御はできない */
+		printf(" Can't control the monitor!!\n");
+		return 0;
+	}
+	ercd = wup_tsk(current_tskid);
+	printf("  execute wup_tsk(%d) :: result = %s !\n", current_tskid, itron_strerror(ercd));
+	tslp_tsk(100);				/* スイッチング */
+	return 0;
+}
+
+/*
+ *  タスクコマンド、優先度変更(chg_pri)
+ */
+static int_t
+task_priority(int argc, char **argv)
+{
+	ER      ercd = E_OK;
+	ulong_t w;
+
+	if(current_tskid == MONTASK){	/* モニタ自体の制御はできない */
+		printf(" Can't control the monitor!!\n");
+		return 0;
+	}
+	if(argc > 1 && get_value(argv[1], &w, DEC_VALUE)){
+		ercd = chg_pri(current_tskid, w);
+		printf("  execute chg_pri(%d, %d) :: result = %s !\n", current_tskid, (int)w, itron_strerror(ercd));
+		tslp_tsk(100);				/* スイッチング */
+		return 0;
+	}
+	return -1;
+}
+
+/*
+ * ログコマンド、ロギングモード設定
+ */
+static int_t
+log_mode(int argc, char **argv)
+{
+	ulong_t	value1, value2;
+
+	if(argc < 2 || !get_value(argv[1], &value1, DEC_VALUE))
+		value1 = mon_logmask;
+	if(argc < 3 || !get_value(argv[2], &value2, DEC_VALUE))
+		value2 = mon_lowmask;
+	if(value1 <= LOG_DEBUG)
+		mon_logmask = value1;
+	if(value2 <= LOG_DEBUG)
+		mon_lowmask = value2;
+	syslog_msk_log(LOG_UPTO(mon_logmask), LOG_UPTO(mon_lowmask));
+	printf("  set logmask=%s lowmask=%s !\n", log_mode_name[mon_logmask], log_mode_name[mon_lowmask]);
+	return 0;
+}
+
+/*
+ * ログコマンド、タスクモニタ設定
+ */
+static int_t
+log_task(int argc, char **argv)
+{
+	T_TPRM  loglist;
+	ulong_t value1, value2, value3 = 0;
+	ulong_t tcount, ttime;
+	ulong_t sno = MONTASK;
+	ulong_t xno = MONTASK+NUM_LOG_DISP;
+	int     no, count;
+
+	if(argc < 2 || !get_value(argv[1], &value1, DEC_VALUE))
+		value1 = 0;
+	else if(argc < 3 || !get_value(argv[2], &value3, DEC_VALUE))
+		value3 = 0;
+	if(value1 < 100)
+		value1 = 0;
+	value2 = 0;
+	do{
+		count = get_tsklog(&loglist);
+		if(value2 == 0){		/* はじめの１回 */
+			value2 =loglist.currtime;
+			if(xno > count){
+				int i = xno - count;
+				if(i > MONTASK)
+					i = MONTASK;
+				sno -= xno - count;
+				xno -= xno - count;
+			}
+			printf("-- time --");
+			for(no = 1 ; no <= xno ; no++){
+				if(no > sno)
+					printf(" --id=%04u --", no);
+			}
+			printf(" -- others --  -vacancy-\n");
+		}
+		value2 += value1;
+		if(value1 == 0)
+			printf("%010lu\n", (unsigned long)loglist.pervtime);
+		printf("%010lu", (unsigned long)loglist.currtime);
+		tcount = ttime = 0;
+		for(no = 1 ; no <= count ; no++){
+			if(no > sno && no <= xno){
+				printf(" %04u %05lu.%01u", loglist.tlog[no].runcount, (unsigned long)(loglist.tlog[no].runtimes/10),
+						(int)(loglist.tlog[no].runtimes%10));
+			}
+			else{
+				tcount += loglist.tlog[no].runcount;
+				ttime += loglist.tlog[no].runtimes;
+			}
+		}
+		printf(" %04u %05lu.%01u", (int)tcount, (unsigned long)(ttime/10), (int)(ttime%10));
+		printf("  %07lu.%01u\n", (unsigned long)(loglist.tlog[0].runtimes/10), (int)(loglist.tlog[0].runtimes%10));
+		if(value1){
+			tslp_tsk(value2 - loglist.currtime);
+			if(monitor_break())
+				value1 = 0;
+		}
+		value3--;
+	}while(value1 && value3 != 0);
+	return 0;
+}
+
+/*
+ * ログコマンド、ポートモニタ設定
+ */
+static int_t
+log_port(int argc, char **argv)
+{
+	T_PCHK  *p;
+	ulong_t type, address;
+	ulong_t value1, value2;
+
+	value2 = NUM_PCHK-1;
+	if(argc > 1 && get_value(argv[1], &value1, DEC_VALUE)){
+		if((p = get_device_log(value1)) != 0){
+			value2 = value1;
+			if(argc < 3 || !get_value(argv[2], &type, DEC_VALUE)){
+				type = p->logtype;
+			}
+			if(type >= LOG_DEBUG)
+				type = 0;
+			p->logtype = type;
+			if(argc < 4 || !get_value(argv[4], &address, HEX_VALUE)){
+				address = p->portaddress;
+			}
+			p->portaddress = address;
+		}
+	}
+	else
+		value1 = 0;
+	while(value1 <= value2){
+		if((p = get_device_log(value1)) != 0){
+			if(p->logtype > 0)
+				printf("  %02d   %s port=%08lx\n", (int)value1, log_mode_name[p->logtype], (unsigned long)p->portaddress);
+			else
+				printf("  %02d   OFF      port=%08lx\n", (int)value1, (unsigned long)p->portaddress);
+		}
+		else
+			break;
+		value1++;
+	}
+	return 0;
+}
+
+
+/*
+ *  キャラクタの比較
+ */
+bool_t
+compare_word(const char *s, char *d, int_t mode)
+{
+	char c1, c2;
+
+	if(*d == 0)
+		return false;
+	while(*s != 0 && *d != 0 && *d != ' ' && *d != ','){
+		c2 = *d++;
+		if(c2 >= 'a' && c2 <= 'z')
+			c2 -= 0x20;
+		c1 = *s++;
+		if(c1 >= 'a' && c1 <= 'z')
+			c1 -= 0x20;
+		if(c1 != c2)
+			return false;
+		if(mode == 1)
+			break;
+	}
+	return true;
+}
+
+/*
+ *  タスク状態番号を取り出す
+ */
+static uint_t
+get_taskstate(STAT tskstat)
+{
+	uint_t no;
+
+	if(tskstat == TTS_RUN)
+		no = 0;
+	else if(tskstat == TTS_RDY)
+		no = 1;
+	else if(tskstat == TTS_WAI)
+		no = 2;
+	else if(tskstat == TTS_SUS)
+		no = 3;
+	else if(tskstat == TTS_DMT)
+		no = 5;
+	else
+		no = 4;
+	return no;
+}
+
+/*
+ *  モニタのコマンド読み込み文
+ */
+char
+monitor_getstring(char *s, int *len)
+{
+	char c;
+	int  no = 0;
+
+	*len = 0;
+	do{
+		c = getc(mon_infile);
+		if(c >= ' ' && no < MAX_COMMAND_LENGTH){
+			putecho((int)c);
+			s[no++] = c;
+		}
+		else if((c == KEY_BS || c == KEY_DEL) && no > 0){
+			printecho(backspace);
+			no--;
+		}
+	}while(c != KEY_NL && c != KEY_CR && c != KEY_EXT);
+	s[no] = 0;
+	*len = no;
+	return c;
+}
+
+/*
+ *  モニタコマンドブレークの判定
+ */
+bool_t
+monitor_break(void)
+{
+	T_SERIAL_RPOR k_rpor;
+
+	if(mon_infile != stdin)
+		return false;
+	serial_ref_por(mon_portid, &k_rpor);
+	if(k_rpor.reacnt > 0){
+		getc(mon_infile);
+		return true;
+	}
+	else
+		return false;
+}
+
+/*
+ *  モニタ入力ファイルの切り替え
+ */
+void *
+monitor_infile(void *file)
+{
+	void *ofile = mon_infile;
+
+	if(file != NULL)
+		mon_infile = file;
+	return ofile;
+}
+
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/monitor/monitor.cfg
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/monitor/monitor.cfg	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/monitor/monitor.cfg	(revision 457)
@@ -0,0 +1,11 @@
+/*
+ *  @(#) $Id$
+ */
+
+/*
+ *  モニタタスクのコンフィギュレーション
+ */
+
+#include "monitor.h"
+CRE_TSK(MONTASK, { TA_ACT, MONITOR_PORTID, monitor,
+			MONITOR_PRIORITY, MONITOR_STACK_SIZE, NULL });
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/monitor/monitor.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/monitor/monitor.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/monitor/monitor.h	(revision 457)
@@ -0,0 +1,215 @@
+/*
+ *  TOPPERS/ASP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Advanced Standard Profile Kernel
+ * 
+ *  Copyright (C) 2003-2015 by Ryosuke Takeuchi
+ *                     GJ Business Division RICOH COMPANY,LTD. JAPAN
+ *  Copyright (C) 2017-2019 by TOPPERS PROJECT Educational Working Group.
+ * 
+ *  上記著作権者は，Free Software Foundation によって公表されている 
+ *  GNU General Public License の Version 2 に記述されている条件か，以
+ *  下の(1)～(4)の条件を満たす場合に限り，本ソフトウェア（本ソフトウェ
+ *  アを改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを再利用可能なバイナリコード（リロケータブルオブ
+ *      ジェクトファイルやライブラリなど）の形で利用する場合には，利用
+ *      に伴うドキュメント（利用者マニュアルなど）に，上記の著作権表示，
+ *      この利用条件および下記の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを再利用不可能なバイナリコードの形または機器に組
+ *      み込んだ形で利用する場合には，次のいずれかの条件を満たすこと．
+ *    (a) 利用に伴うドキュメント（利用者マニュアルなど）に，上記の著作
+ *        権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 利用の形態を，別に定める方法によって，上記著作権者に報告する
+ *        こと．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者を免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者は，
+ *  本ソフトウェアに関して，その適用可能性も含めて，いかなる保証も行わ
+ *  ない．また，本ソフトウェアの利用により直接的または間接的に生じたい
+ *  かなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+#ifndef _MONITOR_H_
+#define	_MONITOR_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* 
+ *  モニタ・サンプルプログラムのヘッダファイル
+ */
+#include <kernel.h>
+#include "syssvc/logtask.h"
+
+/*
+ *  タスク優先度の設定
+ */
+#define MONITOR_PRIORITY	4
+
+/*
+ *  ターゲットに依存する可能性のある定数の定義
+ */
+
+#ifndef CONSOLE_PORTID
+#if defined(LOGTASK_PORTID) && defined(SIO_PORTID)
+#define	CONSOLE_PORTID		LOGTASK_PORTID	/* 文字入力するシリアルポートID */
+#else  /* LOGTASK_PORTID */
+#define	CONSOLE_PORTID		1				/* 文字入力するシリアルポートID */
+#endif /* LOGTASK_PORTID */
+#endif /* TASK_PORTID */
+
+/*
+ *  モニタのサイズの設定
+ */
+#if defined(TOPPERS_CORTEX_M0PLUS) || defined(TOPPERS_HIFIVE1)
+#define	MONITOR_STACK_SIZE	1536	/* タスクのスタックサイズ */
+#else
+#define	MONITOR_STACK_SIZE	2046	/* タスクのスタックサイズ */
+#endif
+#define	MAX_COMMAND_LENGTH	200		/* モニタの最大コマンド長 */
+#define	NUM_LOG_DISP		3		/* 最大表示アイテム数 */
+#ifndef MONITOR_PORTID
+#define MONITOR_PORTID      CONSOLE_PORTID
+#endif
+
+/*
+ *  バージョン情報
+ */
+#define	TMONITOR_PRVER	0x1020		/* カーネルのバージョン番号 */
+
+/*
+ *  キー割り当ての定義
+ */
+#define	KEY_BS			(8)			/* バックスペース */
+#define	KEY_DEL			(127)		/* 削除 */
+#define KEY_NL			(10)		/* 改行1 */
+#define	KEY_CR			(13)		/* 改行2 */
+#define	KEY_EXT			(1)			/* 終了 */
+
+/*
+ *  データタイプ定義
+ */
+#define	DATA_BYTE		1			/* バイトデータ（１バイト）*/
+#define	DATA_HALF		2			/* ハーフデータ（２バイト）*/
+#define	DATA_WORD		4			/* ワードデータ（４バイト）*/
+
+/*
+ *  領域属性の定義
+ */
+#define	NONE_AREA		0			/* 領域の割り当てのない領域 */
+#define	PORT_AREA		1			/* ハードウェアのポート領域 */
+#define	MEMORY_AREA		2			/* メモリ領域　*/
+
+#define	MREAD_ONLY		1			/* 読み込み専用 */
+#define	MWRITE_ONLY		2			/* 書き込み専用 */
+#define	MREAD_WRITE		(MREAD_ONLY+MWRITE_ONLY)
+
+#ifndef TOPPERS_MACRO_ONLY
+
+/*
+ *  コマンドデスパッチ用の構造体定義
+ */
+typedef struct _COMMAND_INFO {
+	const char   *command;			/* コマンド文 */
+	int_t        (*func)(int argc, char **argv);	/* 実行関数 */
+} COMMAND_INFO;
+
+typedef struct _COMMAND_LINK COMMAND_LINK;
+struct _COMMAND_LINK {
+	COMMAND_LINK *pcnext;
+	int          num_command;
+	const char   *command;			/* 主コマンド文 */
+	int_t        (*func)(int argc, char **argv);	/* 実行関数 */
+	const char   *help;				/* ヘルプ文 */
+    const COMMAND_INFO *pcinfo;
+};
+
+/*
+ *  エコーの設定
+ */
+#define putecho(a)      putchar(a)
+#define printecho(a)    printf(a)
+
+/*
+ *  関数のプロトタイプ宣言
+ */
+
+extern bool_t  need_monitor(void);
+extern void	   monitor(intptr_t exinf);
+extern int     setup_command(COMMAND_LINK *pcmd);
+extern bool_t  monitor_break(void);
+extern bool_t  compare_word(const char *s, char *d, int_t mode);
+extern char    getMemoryType(ulong_t address, int_t mode);
+extern int_t   MemoryRead(ulong_t address, intptr_t p, int_t type);
+extern int_t   MemoryWrite(ulong_t address, intptr_t p, int_t type);
+extern ulong_t MonAlignAddress(ulong_t address);
+extern int_t   MemoryRead(ulong_t address, intptr_t p, int_t type);
+extern int_t   MemoryWrite(ulong_t address, intptr_t p, int_t type);
+extern ulong_t get_exception_pc(void * p_excinf);
+extern void    display_registers(ID tskid);
+extern ulong_t display_assembler(ulong_t pc);
+
+/*
+ *  次のキャラクタの判定
+ */
+Inline bool_t
+test_next_char(char c)
+{
+	if(c == ' ' || c == '\t')
+		return true;
+	else
+		return false;
+}
+
+/*
+ *  文字列から数字を取り出す
+ *  戻り値がFALSEなら値が未設定であることを示す
+ */
+Inline bool_t
+get_value(char *s, ulong_t *v, int_t card)
+{
+	char c;
+	int  no = 0;
+
+	*v = 0;
+	if(s[no] == 0)
+		return false;
+	else if(s[no] == ' ' || s[no] == '\t'
+               || s[no] == ',' || s[no] == '.'){
+		no++;
+		return false;
+	}
+	else{
+		while(s[no]){
+			c = s[no];
+			no++;
+			if(c >= '0' && c <= '9')
+				c -= '0';
+			else if(c >= 'A' && c <= 'Z')
+				c -= 'A' - 10;
+			else if(c >= 'a' && c <= 'z')
+				c -= 'a' - 10;
+			else
+				break;
+			*v = *v * card + c;
+		}
+		return true;
+	}
+}
+
+#endif /* TOPPERS_MACRO_ONLY */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _MONITOR_H_ */
+
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/monitor/monsil.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/monitor/monsil.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/monitor/monsil.h	(revision 457)
@@ -0,0 +1,329 @@
+/*
+ *  TOPPERS/JSP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Just Standard Profile Kernel
+ * 
+ *  Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
+ *                              Toyohashi Univ. of Technology, JAPAN
+ *  Copyright (C) 2003-2004 by Ryosuke Takeuchi
+ *               Platform Development Center RICOH COMPANY,LTD. JAPAN
+ * 
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *	システムインタフェースレイヤ（ターゲット共通部）
+ *
+ *  アセンブリ言語のソースファイルやシステムコンフィギュレーションファ
+ *  イルからこのファイルをインクルードする時は，_MACRO_ONLY を定義して
+ *  おくことで，マクロ定義以外の記述を除くことができる．
+ *
+ *  このインクルードファイルは，標準インクルードファイル（s_services.h）
+ *  でインクルードされる．また，カーネルから呼ばれるデバイスドライバの
+ *  インクルードファイルで，インライン関数などでシステムインタフェース
+ *  レイヤを用いている場合にも，このファイルがインクルードされる．この
+ *  例外を除いて，他のファイルから直接インクルードされることはない．
+ *
+ *  この中でインクルードしているファイルを除いて，他のインクルードファ
+ *  イルに依存していない．
+ */
+
+#ifndef _MONSIL_H_
+#define _MONSIL_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ *  カーネル・アプリケーション 共通インクルードファイル
+ */
+#include <t_stddef.h>
+
+/*
+ *  ITRON仕様共通規定のデータ型・定数・マクロ
+ */
+#include <itron.h>
+
+/*
+ *  システムやプロセッサに依存する定義
+ */
+#include <sys_defs.h>
+#include <cpu_defs.h>
+
+/*
+ *  システムログサービスのための定義
+ */
+#include <t_syslog.h>
+
+/*
+ *  ポートログ設定の定義
+ */
+#include <task_expansion.h>
+
+/*
+ *  エンディアン定数の定義
+ */
+#define	SIL_ENDIAN_LITTLE	0	/* リトルエンディアン */
+#define	SIL_ENDIAN_BIG		1	/* ビッグエンディアン */
+
+#ifndef _MACRO_ONLY
+
+/*
+ *  割込みロック状態の制御
+ */
+#ifndef SIL_PRE_LOC
+#define	SIL_PRE_LOC	BOOL _sil_loc_ = sns_loc()
+#define	SIL_LOC_INT()	((void)(!(_sil_loc_) \
+				&& (sns_ctx() ? iloc_cpu() : loc_cpu())))
+#define	SIL_UNL_INT()	((void)(!(_sil_loc_) \
+				&& (sns_ctx() ? iunl_cpu() : unl_cpu())))
+#endif /* SIL_PRE_LOC */
+
+/*
+ *  微少時間待ち
+ */
+extern void	sil_dly_nse(UINT dlytim) throw();
+
+/*
+ *  エンディアンの反転
+ */
+#ifndef SIL_REV_ENDIAN_H
+#define	SIL_REV_ENDIAN_H(data) \
+	((VH)((((UH)(data) & 0xff) << 8) | (((UH)(data) >> 8) & 0xff)))
+#endif /* SIL_REV_ENDIAN_H */
+
+#ifndef SIL_REV_ENDIAN_W
+#define	SIL_REV_ENDIAN_W(data) \
+	((VW)((((UW)(data) & 0xff) << 24) | (((UW)(data) & 0xff00) << 8) \
+		| (((UW)(data)>> 8) & 0xff00) | (((UW)(data) >> 24) & 0xff)))
+#endif /* SIL_REV_ENDIAN_H */
+
+/*
+ *  メモリ空間アクセス関数
+ */
+#ifndef OMIT_SIL_ACCESS
+
+/*
+ *  8ビット単位の読出し／書込み
+ */
+#ifdef _int8_
+
+Inline VB
+sil_reb_mem(VP mem)
+{
+	VB data;
+
+    MemoryRead((unsigned long)mem, (void *)&data, sizeof(VB));
+	ana_rdv((UW)mem, (UW)data, 1);
+	return(data);
+}
+
+Inline void
+sil_wrb_mem(VP mem, VB data)
+{
+	ana_wdv((UW)mem, (UW)data, 1);
+    MemoryWrite((unsigned long)mem, (void *)&data, sizeof(VB));
+}
+
+#endif /* _int8_ */
+
+/*
+ *  16ビット単位の読出し／書込み
+ */
+#ifdef _int16_
+
+Inline VH
+sil_reh_mem(VP mem)
+{
+	VH data;
+
+    MemoryRead((unsigned long)mem,  (void *)&data, sizeof(VH));
+	ana_rdv((UW)mem, (UW)data, 2);
+	return(data);
+}
+
+Inline void
+sil_wrh_mem(VP mem, VH data)
+{
+	ana_wdv((UW)mem, (UW)data, 2);
+    MemoryWrite((unsigned long)mem, (void *)&data, sizeof(VH));
+}
+
+#if SIL_ENDIAN == SIL_ENDIAN_BIG	/* ビッグエンディアンプロセッサ */
+
+#define	sil_reh_bem(mem)	sil_reh_mem(mem)
+#define	sil_wrh_bem(mem, data)	sil_wrh_mem(mem, data)
+
+#ifndef OMIT_SIL_REH_LEM
+
+Inline VH
+sil_reh_lem(VP mem)
+{
+	VH	data;
+
+	data = *((volatile VH *) mem);
+	data = (SIL_REV_ENDIAN_H(data));
+	ana_rdv((UW)mem, (UW)data, 2);
+	return(data);
+}
+
+#endif /* OMIT_SIL_REH_LEM */
+#ifndef OMIT_SIL_WRH_LEM
+
+Inline void
+sil_wrh_lem(VP mem, VH data)
+{
+	ana_wdv((UW)mem, (UW)data, 2);
+	*((volatile VH *) mem) = SIL_REV_ENDIAN_H(data);
+}
+
+#endif /* OMIT_SIL_WRH_LEM */
+#else /* SIL_ENDIAN == SIL_ENDIAN_BIG *//* リトルエンディアンプロセッサ */
+
+#define	sil_reh_lem(mem)	sil_reh_mem(mem)
+#define	sil_wrh_lem(mem, data)	sil_wrh_mem(mem, data)
+
+#ifndef OMIT_SIL_REH_BEM
+
+Inline VH
+sil_reh_bem(VP mem)
+{
+	VH	data;
+
+	data = *((volatile VH *) mem);
+	data = (SIL_REV_ENDIAN_H(data));
+	ana_rdv((UW)mem, (UW)data, 2);
+	return(data);
+}
+
+#endif /* OMIT_SIL_REH_BEM */
+#ifndef OMIT_SIL_WRH_BEM
+
+Inline void
+sil_wrh_bem(VP mem, VH data)
+{
+	ana_wdv((UW)mem, (UW)data, 2);
+	*((volatile VH *) mem) = SIL_REV_ENDIAN_H(data);
+}
+
+#endif /* OMIT_SIL_WRH_BEM */
+#endif /* SIL_ENDIAN == SIL_ENDIAN_BIG */
+#endif /* _int16_ */
+
+/*
+ *  32ビット単位の読出し／書込み
+ */
+
+Inline VW
+sil_rew_mem(VP mem)
+{
+	VW data;
+
+    MemoryRead((unsigned long)mem, (void *)&data,  sizeof(VW));
+	ana_rdv((UW)mem, (UW)data, 4);
+	return(data);
+}
+
+Inline void
+sil_wrw_mem(VP mem, VW data)
+{
+	ana_wdv((UW)mem, (UW)data, 4);
+    MemoryWrite((unsigned long)mem, (void *)&data, sizeof(VW));
+}
+
+#if SIL_ENDIAN == SIL_ENDIAN_BIG	/* ビッグエンディアンプロセッサ */
+
+#define	sil_rew_bem(mem)	sil_rew_mem(mem)
+#define	sil_wrw_bem(mem, data)	sil_wrw_mem(mem, data)
+
+#ifndef OMIT_SIL_REW_LEM
+
+Inline VW
+sil_rew_lem(VP mem)
+{
+	VW	data;
+
+	data = *((volatile VW *) mem);
+	data = (SIL_REV_ENDIAN_W(data));
+	ana_rdv((UW)mem, (UW)data, 4);
+	return(data);
+}
+
+#endif /* OMIT_SIL_REW_LEM */
+#ifndef OMIT_SIL_WRW_LEM
+
+Inline void
+sil_wrw_lem(VP mem, VW data)
+{
+	ana_wdv((UW)mem, (UW)data, 4);
+	*((volatile VW *) mem) = SIL_REV_ENDIAN_W(data);
+}
+
+#endif /* OMIT_SIL_WRW_LEM */
+#else /* SIL_ENDIAN == SIL_ENDIAN_BIG *//* リトルエンディアンプロセッサ */
+
+#define	sil_rew_lem(mem)	sil_rew_mem(mem)
+#define	sil_wrw_lem(mem, data)	sil_wrw_mem(mem, data)
+
+#ifndef OMIT_SIL_REW_BEM
+
+Inline VW
+sil_rew_bem(VP mem)
+{
+	VW	data;
+
+	data = *((volatile VW *) mem);
+	data = (SIL_REV_ENDIAN_W(data));
+	ana_rdv((UW)mem, (UW)data, 4);
+	return(data);
+}
+
+#endif /* OMIT_SIL_REW_BEM */
+#ifndef OMIT_SIL_WRW_BEM
+
+Inline void
+sil_wrw_bem(VP mem, VW data)
+{
+	ana_wdv((UW)mem, (UW)data, 4);
+	*((volatile VW *) mem) = SIL_REV_ENDIAN_W(data);
+}
+
+#endif /* OMIT_SIL_WRW_BEM */
+#endif /* SIL_ENDIAN == SIL_ENDIAN_BIG */
+#endif /* OMIT_SIL_ACCESS */
+
+#endif /* _MACRO_ONLY */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _MONSIL_H_ */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/monitor/sample1.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/monitor/sample1.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/monitor/sample1.c	(revision 457)
@@ -0,0 +1,541 @@
+/*
+ *  TOPPERS/ASP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Advanced Standard Profile Kernel
+ * 
+ *  Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
+ *                              Toyohashi Univ. of Technology, JAPAN
+ *  Copyright (C) 2004-2012 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  $Id$
+ */
+
+/* 
+ *  サンプルプログラム(1)の本体
+ *
+ *  ASPカーネルの基本的な動作を確認するためのサンプルプログラム．
+ *
+ *  プログラムの概要:
+ *
+ *  ユーザインタフェースを受け持つメインタスク（タスクID: MAIN_TASK，優
+ *  先度: MAIN_PRIORITY）と，3つの並行実行されるタスク（タスクID:
+ *  TASK1～TASK3，初期優先度: MID_PRIORITY）で構成される．また，起動周
+ *  期が2秒の周期ハンドラ（周期ハンドラID: CYCHDR1）を用いる．
+ *
+ *  並行実行されるタスクは，task_loop回空ループを実行する度に，タスクが
+ *  実行中であることをあらわすメッセージを表示する．空ループを実行する
+ *  のは，空ループなしでメッセージを出力すると，多量のメッセージが出力
+ *  され，プログラムの動作が確認しずらくなるためである．また，低速なシ
+ *  リアルポートを用いてメッセージを出力する場合に，すべてのメッセージ
+ *  が出力できるように，メッセージの量を制限するという理由もある．
+ *
+ *  周期ハンドラは，三つの優先度（HIGH_PRIORITY，MID_PRIORITY，
+ *  LOW_PRIORITY）のレディキューを回転させる．プログラムの起動直後は，
+ *  周期ハンドラは停止状態になっている．
+ *
+ *  メインタスクは，シリアルI/Oポートからの文字入力を行い（文字入力を
+ *  待っている間は，並行実行されるタスクが実行されている），入力された
+ *  文字に対応した処理を実行する．入力された文字と処理の関係は次の通り．
+ *  Control-Cまたは'Q'が入力されると，プログラムを終了する．
+ *
+ *  '1' : 対象タスクをTASK1に切り換える（初期設定）．
+ *  '2' : 対象タスクをTASK2に切り換える．
+ *  '3' : 対象タスクをTASK3に切り換える．
+ *  'a' : 対象タスクをact_tskにより起動する．
+ *  'A' : 対象タスクに対する起動要求をcan_actによりキャンセルする．
+ *  'e' : 対象タスクにext_tskを呼び出させ，終了させる．
+ *  't' : 対象タスクをter_tskにより強制終了する．
+ *  '>' : 対象タスクの優先度をHIGH_PRIORITYにする．
+ *  '=' : 対象タスクの優先度をMID_PRIORITYにする．
+ *  '<' : 対象タスクの優先度をLOW_PRIORITYにする．
+ *  'G' : 対象タスクの優先度をget_priで読み出す．
+ *  's' : 対象タスクにslp_tskを呼び出させ，起床待ちにさせる．
+ *  'S' : 対象タスクにtslp_tsk(10秒)を呼び出させ，起床待ちにさせる．
+ *  'w' : 対象タスクをwup_tskにより起床する．
+ *  'W' : 対象タスクに対する起床要求をcan_wupによりキャンセルする．
+ *  'l' : 対象タスクをrel_waiにより強制的に待ち解除にする．
+ *  'u' : 対象タスクをsus_tskにより強制待ち状態にする．
+ *  'm' : 対象タスクの強制待ち状態をrsm_tskにより解除する．
+ *  'd' : 対象タスクにdly_tsk(10秒)を呼び出させ，時間経過待ちにさせる．
+ *  'x' : 対象タスクに例外パターン0x0001の例外処理を要求する．
+ *  'X' : 対象タスクに例外パターン0x0002の例外処理を要求する．
+ *  'y' : 対象タスクにdis_texを呼び出させ，タスク例外を禁止する．
+ *  'Y' : 対象タスクにena_texを呼び出させ，タスク例外を許可する．
+ *  'r' : 3つの優先度（HIGH_PRIORITY，MID_PRIORITY，LOW_PRIORITY）のレ
+ *        ディキューを回転させる．
+ *  'c' : 周期ハンドラを動作開始させる．
+ *  'C' : 周期ハンドラを動作停止させる．
+ *  'b' : アラームハンドラを5秒後に起動するよう動作開始させる．
+ *  'B' : アラームハンドラを動作停止させる．
+ *  'z' : 対象タスクにCPU例外を発生させる（タスクを終了させる）．
+ *  'Z' : 対象タスクにCPUロック状態でCPU例外を発生させる（プログラムを
+ *        終了する）．
+ *  'V' : get_utmで性能評価用システム時刻を2回読む．
+ *  'v' : 発行したシステムコールを表示する（デフォルト）．
+ *  'q' : 発行したシステムコールを表示しない．
+ */
+
+#include <kernel.h>
+#include <t_syslog.h>
+#include <t_stdlib.h>
+#include "syssvc/serial.h"
+#include "syssvc/syslog.h"
+#include "kernel_cfg.h"
+#include "sample1.h"
+
+/*
+ *  サービスコールのエラーのログ出力
+ */
+Inline void
+svc_perror(const char *file, int_t line, const char *expr, ER ercd)
+{
+	if (ercd < 0) {
+		t_perror(LOG_ERROR, file, line, expr, ercd);
+	}
+}
+
+#define	SVC_PERROR(expr)	svc_perror(__FILE__, __LINE__, #expr, (expr))
+
+/*
+ *  並行実行されるタスクへのメッセージ領域
+ */
+char	message[3];
+
+/*
+ *  ループ回数
+ */
+ulong_t	task_loop;		/* タスク内でのループ回数 */
+ulong_t	tex_loop;		/* 例外処理ルーチン内でのループ回数 */
+
+/*
+ *  並行実行されるタスク
+ */
+void task(intptr_t exinf)
+{
+	volatile ulong_t	i;
+	int_t		n = 0;
+	int_t		tskno = (int_t) exinf;
+	const char	*graph[] = { "|", "  +", "    *" };
+	char		c;
+
+	SVC_PERROR(ena_tex());
+	while (true) {
+		syslog(LOG_NOTICE, "task%d is running (%03d).   %s",
+										tskno, ++n, graph[tskno-1]);
+		for (i = 0; i < task_loop; i++);
+		c = message[tskno-1];
+		message[tskno-1] = 0;
+		switch (c) {
+		case 'e':
+			syslog(LOG_INFO, "#%d#ext_tsk()", tskno);
+			SVC_PERROR(ext_tsk());
+			assert(0);
+		case 's':
+			syslog(LOG_INFO, "#%d#slp_tsk()", tskno);
+			SVC_PERROR(slp_tsk());
+			break;
+		case 'S':
+			syslog(LOG_INFO, "#%d#tslp_tsk(10000)", tskno);
+			SVC_PERROR(tslp_tsk(10000));
+			break;
+		case 'd':
+			syslog(LOG_INFO, "#%d#dly_tsk(10000)", tskno);
+			SVC_PERROR(dly_tsk(10000));
+			break;
+		case 'y':
+			syslog(LOG_INFO, "#%d#dis_tex()", tskno);
+			SVC_PERROR(dis_tex());
+			break;
+		case 'Y':
+			syslog(LOG_INFO, "#%d#ena_tex()", tskno);
+			SVC_PERROR(ena_tex());
+			break;
+#ifdef CPUEXC1
+		case 'z':
+			syslog(LOG_NOTICE, "#%d#raise CPU exception", tskno);
+			RAISE_CPU_EXCEPTION;
+			break;
+		case 'Z':
+			SVC_PERROR(loc_cpu());
+			syslog(LOG_NOTICE, "#%d#raise CPU exception", tskno);
+			RAISE_CPU_EXCEPTION;
+			SVC_PERROR(unl_cpu());
+			break;
+#endif /* CPUEXC1 */
+		default:
+			break;
+		}
+	}
+}
+
+/*
+ *  並行して実行されるタスク用のタスク例外処理ルーチン
+ */
+void tex_routine(TEXPTN texptn, intptr_t exinf)
+{
+	volatile ulong_t	i;
+	int_t	tskno = (int_t) exinf;
+
+	syslog(LOG_NOTICE, "task%d receives exception 0x%04x.", tskno, texptn);
+	for (i = 0; i < tex_loop; i++);
+
+	if ((texptn & 0x8000U) != 0U) {
+		syslog(LOG_INFO, "#%d#ext_tsk()", tskno);
+		SVC_PERROR(ext_tsk());
+		assert(0);
+	}
+}
+
+/*
+ *  CPU例外ハンドラ
+ */
+#ifdef CPUEXC1
+
+void
+cpuexc_handler(void *p_excinf)
+{
+	ID		tskid;
+
+	syslog(LOG_NOTICE, "CPU exception handler (p_excinf = %08p).", p_excinf);
+	if (sns_ctx() != true) {
+		syslog(LOG_WARNING,
+					"sns_ctx() is not true in CPU exception handler.");
+	}
+	if (sns_dpn() != true) {
+		syslog(LOG_WARNING,
+					"sns_dpn() is not true in CPU exception handler.");
+	}
+	syslog(LOG_INFO, "sns_loc = %d sns_dsp = %d sns_tex = %d",
+									sns_loc(), sns_dsp(), sns_tex());
+	syslog(LOG_INFO, "xsns_dpn = %d xsns_xpn = %d",
+									xsns_dpn(p_excinf), xsns_xpn(p_excinf));
+
+	if (xsns_xpn(p_excinf)) {
+		syslog(LOG_NOTICE, "Sample program ends with exception.");
+		SVC_PERROR(ext_ker());
+		assert(0);
+	}
+
+	SVC_PERROR(iget_tid(&tskid));
+	SVC_PERROR(iras_tex(tskid, 0x8000U));
+}
+
+#endif /* CPUEXC1 */
+
+/*
+ *  周期ハンドラ
+ *
+ *  HIGH_PRIORITY，MID_PRIORITY，LOW_PRIORITY の各優先度のレディキュー
+ *  を回転させる．
+ */
+void cyclic_handler(intptr_t exinf)
+{
+	SVC_PERROR(irot_rdq(HIGH_PRIORITY));
+	SVC_PERROR(irot_rdq(MID_PRIORITY));
+	SVC_PERROR(irot_rdq(LOW_PRIORITY));
+}
+
+/*
+ *  アラームハンドラ
+ *
+ *  HIGH_PRIORITY，MID_PRIORITY，LOW_PRIORITY の各優先度のレディキュー
+ *  を回転させる．
+ */
+void alarm_handler(intptr_t exinf)
+{
+	SVC_PERROR(irot_rdq(HIGH_PRIORITY));
+	SVC_PERROR(irot_rdq(MID_PRIORITY));
+	SVC_PERROR(irot_rdq(LOW_PRIORITY));
+}
+
+/*
+ *  メインタスク
+ */
+void main_task(intptr_t exinf)
+{
+	char	c;
+	ID		tskid = TASK1;
+	int_t	tskno = 1;
+	ER_UINT	ercd;
+	PRI		tskpri;
+#ifndef TASK_LOOP
+	volatile ulong_t	i;
+	SYSTIM	stime1, stime2;
+#endif /* TASK_LOOP */
+#ifdef TOPPERS_SUPPORT_GET_UTM
+	SYSUTM	utime1, utime2;
+#endif /* TOPPERS_SUPPORT_GET_UTM */
+
+	SVC_PERROR(syslog_msk_log(LOG_UPTO(LOG_INFO), LOG_UPTO(LOG_EMERG)));
+	syslog(LOG_NOTICE, "Sample program starts (exinf = %d).", (int_t) exinf);
+
+	/*
+	 *  シリアルポートの初期化
+	 *
+	 *  システムログタスクと同じシリアルポートを使う場合など，シリアル
+	 *  ポートがオープン済みの場合にはここでE_OBJエラーになるが，支障は
+	 *  ない．
+	 */
+	ercd = serial_opn_por(TASK_PORTID);
+	if (ercd < 0 && MERCD(ercd) != E_OBJ) {
+		syslog(LOG_ERROR, "%s (%d) reported by `serial_opn_por'.",
+									itron_strerror(ercd), SERCD(ercd));
+	}
+	SVC_PERROR(serial_ctl_por(TASK_PORTID,
+							(IOCTL_CRLF | IOCTL_FCSND | IOCTL_FCRCV)));
+
+	/*
+ 	 *  ループ回数の設定
+	 *
+	 *  並行実行されるタスク内での空ループの回数（task_loop）は，空ルー
+	 *  プの実行時間が約0.4秒になるように設定する．この設定のために，
+	 *  LOOP_REF回の空ループの実行時間を，その前後でget_timを呼ぶことで
+	 *  測定し，その測定結果から空ループの実行時間が0.4秒になるループ回
+	 *  数を求め，task_loopに設定する．
+	 *
+	 *  LOOP_REFは，デフォルトでは1,000,000に設定しているが，想定したよ
+	 *  り遅いプロセッサでは，サンプルプログラムの実行開始に時間がかか
+	 *  りすぎるという問題を生じる．逆に想定したより速いプロセッサでは，
+	 *  LOOP_REF回の空ループの実行時間が短くなり，task_loopに設定する値
+	 *  の誤差が大きくなるという問題がある．
+	 *
+	 *  そこで，そのようなターゲットでは，target_test.hで，LOOP_REFを適
+	 *  切な値に定義するのが望ましい．
+	 *
+	 *  また，task_loopの値を固定したい場合には，その値をTASK_LOOPにマ
+	 *  クロ定義する．TASK_LOOPがマクロ定義されている場合，上記の測定を
+	 *  行わずに，TASK_LOOPに定義された値を空ループの回数とする．
+	 *
+	 * ターゲットによっては，空ループの実行時間の1回目の測定で，本来よ
+	 * りも長めになるものがある．このようなターゲットでは，MEASURE_TWICE
+	 * をマクロ定義することで，1回目の測定結果を捨てて，2回目の測定結果
+	 * を使う．
+	 *
+	 *  タスク例外処理ルーチン内での空ループの回数（tex_loop）は，
+	 *  task_loopの4分の1の値（空ループの実行時間が0.1秒になるループ回
+	 *  数）に設定する．
+	 */
+#ifdef TASK_LOOP
+	task_loop = TASK_LOOP;
+#else /* TASK_LOOP */
+
+#ifdef MEASURE_TWICE
+	task_loop = LOOP_REF;
+	SVC_PERROR(get_tim(&stime1));
+	for (i = 0; i < task_loop; i++);
+	SVC_PERROR(get_tim(&stime2));
+#endif /* MEASURE_TWICE */
+
+	task_loop = LOOP_REF;
+	SVC_PERROR(get_tim(&stime1));
+	for (i = 0; i < task_loop; i++);
+	SVC_PERROR(get_tim(&stime2));
+	task_loop = LOOP_REF * 400UL / (stime2 - stime1);
+
+#endif /* TASK_LOOP */
+	tex_loop = task_loop / 4;
+
+	/*
+ 	 *  タスクの起動
+	 */
+	SVC_PERROR(act_tsk(TASK1));
+	SVC_PERROR(act_tsk(TASK2));
+	SVC_PERROR(act_tsk(TASK3));
+
+	/*
+ 	 *  メインループ
+	 */
+	do {
+#ifndef USE_CUPCOMMAND
+		SVC_PERROR(serial_rea_dat(TASK_PORTID, &c, 1));
+#else
+		do{
+			c = get_cup_command();
+			dly_tsk(10);
+		}while(c == 0);
+#endif
+		switch (c) {
+		case 'e':
+		case 's':
+		case 'S':
+		case 'd':
+		case 'y':
+		case 'Y':
+		case 'z':
+		case 'Z':
+			message[tskno-1] = c;
+			break;
+		case '1':
+			tskno = 1;
+			tskid = TASK1;
+			break;
+		case '2':
+			tskno = 2;
+			tskid = TASK2;
+			break;
+		case '3':
+			tskno = 3;
+			tskid = TASK3;
+			break;
+		case 'a':
+			syslog(LOG_INFO, "#act_tsk(%d)", tskno);
+			SVC_PERROR(act_tsk(tskid));
+			break;
+		case 'A':
+			syslog(LOG_INFO, "#can_act(%d)", tskno);
+			SVC_PERROR(ercd = can_act(tskid));
+			if (ercd >= 0) {
+				syslog(LOG_NOTICE, "can_act(%d) returns %d", tskno, ercd);
+			}
+			break;
+		case 't':
+			syslog(LOG_INFO, "#ter_tsk(%d)", tskno);
+			SVC_PERROR(ter_tsk(tskid));
+			break;
+		case '>':
+			syslog(LOG_INFO, "#chg_pri(%d, HIGH_PRIORITY)", tskno);
+			SVC_PERROR(chg_pri(tskid, HIGH_PRIORITY));
+			break;
+		case '=':
+			syslog(LOG_INFO, "#chg_pri(%d, MID_PRIORITY)", tskno);
+			SVC_PERROR(chg_pri(tskid, MID_PRIORITY));
+			break;
+		case '<':
+			syslog(LOG_INFO, "#chg_pri(%d, LOW_PRIORITY)", tskno);
+			SVC_PERROR(chg_pri(tskid, LOW_PRIORITY));
+			break;
+		case 'G':
+			syslog(LOG_INFO, "#get_pri(%d, &tskpri)", tskno);
+			SVC_PERROR(ercd = get_pri(tskid, &tskpri));
+			if (ercd >= 0) {
+				syslog(LOG_NOTICE, "priority of task %d is %d", tskno, tskpri);
+			}
+			break;
+		case 'w':
+			syslog(LOG_INFO, "#wup_tsk(%d)", tskno);
+			SVC_PERROR(wup_tsk(tskid));
+			break;
+		case 'W':
+			syslog(LOG_INFO, "#can_wup(%d)", tskno);
+			SVC_PERROR(ercd = can_wup(tskid));
+			if (ercd >= 0) {
+				syslog(LOG_NOTICE, "can_wup(%d) returns %d", tskno, ercd);
+			}
+			break;
+		case 'l':
+			syslog(LOG_INFO, "#rel_wai(%d)", tskno);
+			SVC_PERROR(rel_wai(tskid));
+			break;
+		case 'u':
+			syslog(LOG_INFO, "#sus_tsk(%d)", tskno);
+			SVC_PERROR(sus_tsk(tskid));
+			break;
+		case 'm':
+			syslog(LOG_INFO, "#rsm_tsk(%d)", tskno);
+			SVC_PERROR(rsm_tsk(tskid));
+			break;
+		case 'x':
+			syslog(LOG_INFO, "#ras_tex(%d, 0x0001U)", tskno);
+			SVC_PERROR(ras_tex(tskid, 0x0001U));
+			break;
+		case 'X':
+			syslog(LOG_INFO, "#ras_tex(%d, 0x0002U)", tskno);
+			SVC_PERROR(ras_tex(tskid, 0x0002U));
+			break;
+		case 'r':
+			syslog(LOG_INFO, "#rot_rdq(three priorities)");
+			SVC_PERROR(rot_rdq(HIGH_PRIORITY));
+			SVC_PERROR(rot_rdq(MID_PRIORITY));
+			SVC_PERROR(rot_rdq(LOW_PRIORITY));
+			break;
+		case 'c':
+			syslog(LOG_INFO, "#sta_cyc(1)");
+			SVC_PERROR(sta_cyc(CYCHDR1));
+			break;
+		case 'C':
+			syslog(LOG_INFO, "#stp_cyc(1)");
+			SVC_PERROR(stp_cyc(CYCHDR1));
+			break;
+		case 'b':
+			syslog(LOG_INFO, "#sta_alm(1, 5000)");
+			SVC_PERROR(sta_alm(ALMHDR1, 5000));
+			break;
+		case 'B':
+			syslog(LOG_INFO, "#stp_alm(1)");
+			SVC_PERROR(stp_alm(ALMHDR1));
+			break;
+
+		case 'V':
+#ifdef TOPPERS_SUPPORT_GET_UTM
+			SVC_PERROR(get_utm(&utime1));
+			SVC_PERROR(get_utm(&utime2));
+			syslog(LOG_NOTICE, "utime1 = %ld, utime2 = %ld",
+										(ulong_t) utime1, (ulong_t) utime2);
+#else /* TOPPERS_SUPPORT_GET_UTM */
+			syslog(LOG_NOTICE, "get_utm is not supported.");
+#endif /* TOPPERS_SUPPORT_GET_UTM */
+			break;
+
+		case 'v':
+			SVC_PERROR(syslog_msk_log(LOG_UPTO(LOG_INFO),
+										LOG_UPTO(LOG_EMERG)));
+			break;
+		case 'q':
+			SVC_PERROR(syslog_msk_log(LOG_UPTO(LOG_NOTICE),
+										LOG_UPTO(LOG_EMERG)));
+			break;
+
+#ifdef BIT_KERNEL
+		case ' ':
+			SVC_PERROR(loc_cpu());
+			{
+				extern ER	bit_kernel(void);
+
+				SVC_PERROR(ercd = bit_kernel());
+				if (ercd >= 0) {
+					syslog(LOG_NOTICE, "bit_kernel passed.");
+				}
+			}
+			SVC_PERROR(unl_cpu());
+			break;
+#endif /* BIT_KERNEL */
+
+		default:
+			break;
+		}
+	} while (c != '\003' && c != 'Q');
+
+	syslog(LOG_NOTICE, "Sample program ends.");
+	SVC_PERROR(ext_ker());
+	assert(0);
+}
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/monitor/sample1.cfg
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/monitor/sample1.cfg	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/monitor/sample1.cfg	(revision 457)
@@ -0,0 +1,27 @@
+/*
+ *  $Id$
+ */
+
+/*
+ *  サンプルプログラム(1)のシステムコンフィギュレーションファイル
+ */
+INCLUDE("target_timer.cfg");
+INCLUDE("syssvc/syslog.cfg");
+INCLUDE("syssvc/banner.cfg");
+INCLUDE("syssvc/serial.cfg");
+INCLUDE("syssvc/logtask.cfg");
+INCLUDE("monitor/monitor.cfg");
+
+#include "sample1.h"
+CRE_TSK(TASK1, { TA_NULL, 1, task, MID_PRIORITY, STACK_SIZE, NULL });
+CRE_TSK(TASK2, { TA_NULL, 2, task, MID_PRIORITY, STACK_SIZE, NULL });
+CRE_TSK(TASK3, { TA_NULL, 3, task, MID_PRIORITY, STACK_SIZE, NULL });
+CRE_TSK(MAIN_TASK, { TA_NULL, 0, main_task, MAIN_PRIORITY, STACK_SIZE, NULL });
+DEF_TEX(TASK1, { TA_NULL, tex_routine });
+DEF_TEX(TASK2, { TA_NULL, tex_routine });
+DEF_TEX(TASK3, { TA_NULL, tex_routine });
+CRE_CYC(CYCHDR1, { TA_NULL, 0, cyclic_handler, 2000, 0 });
+CRE_ALM(ALMHDR1, { TA_NULL, 0, alarm_handler });
+#ifdef CPUEXC1
+DEF_EXC(CPUEXC1, { TA_NULL, cpuexc_handler });
+#endif /* CPUEXC1 */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/monitor/sample1.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/monitor/sample1.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/monitor/sample1.h	(revision 457)
@@ -0,0 +1,94 @@
+/*
+ *  TOPPERS/ASP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Advanced Standard Profile Kernel
+ *
+ *  Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
+ *                              Toyohashi Univ. of Technology, JAPAN
+ *  Copyright (C) 2004-2010 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ *
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ *
+ *  $Id$
+ */
+
+/*
+ *		サンプルプログラム(1)のヘッダファイル
+ */
+
+/*
+ *  ターゲット依存の定義
+ */
+#include "target_test.h"
+
+/*
+ *  各タスクの優先度の定義
+ */
+
+#define MAIN_PRIORITY	5		/* メインタスクの優先度 */
+								/* HIGH_PRIORITYより高くすること */
+
+#define HIGH_PRIORITY	9		/* 並行実行されるタスクの優先度 */
+#define MID_PRIORITY	10
+#define LOW_PRIORITY	11
+
+/*
+ *  ターゲットに依存する可能性のある定数の定義
+ */
+
+#ifndef TASK_PORTID
+#define	TASK_PORTID		1			/* 文字入力するシリアルポートID */
+#endif /* TASK_PORTID */
+
+#ifndef STACK_SIZE
+#define	STACK_SIZE		4096		/* タスクのスタックサイズ */
+#endif /* STACK_SIZE */
+
+#ifndef LOOP_REF
+#define LOOP_REF		ULONG_C(1000000)	/* 速度計測用のループ回数 */
+#endif /* LOOP_REF */
+
+/*
+ *  関数のプロトタイプ宣言
+ */
+#ifndef TOPPERS_MACRO_ONLY
+
+extern void	task(intptr_t exinf);
+extern void	main_task(intptr_t exinf);
+extern void	tex_routine(TEXPTN texptn, intptr_t exinf);
+#ifdef CPUEXC1
+extern void	cpuexc_handler(void *p_excinf);
+#endif /* CPUEXC1 */
+extern void	cyclic_handler(intptr_t exinf);
+extern void	alarm_handler(intptr_t exinf);
+extern int8_t get_cup_command(void);
+
+#endif /* TOPPERS_MACRO_ONLY */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/monitor/stdio.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/monitor/stdio.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/monitor/stdio.h	(revision 457)
@@ -0,0 +1,186 @@
+/*
+ *  TOPPERS/ASP/FMP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Advanced Standard Profile/Flexible MultiProcessor Kernel
+ * 
+ *  Copyright (C) 2003-2005 by 
+ *                     GJ Business Division RICOH COMPANY,LTD. JAPAN
+ *  Copyright (C) 2015-2017 by TOPPERS PROJECT Educational Working Group.
+ * 
+ *  上記著作権者は，Free Software Foundation によって公表されている 
+ *  GNU General Public License の Version 2 に記述されている条件か，以
+ *  下の(1)～(4)の条件を満たす場合に限り，本ソフトウェア（本ソフトウェ
+ *  アを改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを再利用可能なバイナリコード（リロケータブルオブ
+ *      ジェクトファイルやライブラリなど）の形で利用する場合には，利用
+ *      に伴うドキュメント（利用者マニュアルなど）に，上記の著作権表示，
+ *      この利用条件および下記の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを再利用不可能なバイナリコードの形または機器に組
+ *      み込んだ形で利用する場合には，次のいずれかの条件を満たすこと．
+ *    (a) 利用に伴うドキュメント（利用者マニュアルなど）に，上記の著作
+ *        権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 利用の形態を，別に定める方法によって，上記著作権者に報告する
+ *        こと．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者を免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者は，
+ *  本ソフトウェアに関して，その適用可能性も含めて，いかなる保証も行わ
+ *  ない．また，本ソフトウェアの利用により直接的または間接的に生じたい
+ *  かなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+/*
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms are permitted
+ * provided that the above copyright notice and this paragraph are
+ * duplicated in all such forms and that any documentation,
+ * advertising materials, and other materials related to such
+ * distribution and use acknowledge that the software was developed
+ * by the University of California, Berkeley.  The name of the
+ * University may not be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ *	@(#)stdio.h	5.3 (Berkeley) 3/15/86
+ */
+
+/*
+ * NB: to fit things in six character monocase externals, the
+ * stdio code uses the prefix `__ms' for embedded stdio objects, typically
+ * followed by a three-character attempt at a mnemonic.
+ */
+#ifndef _STDIO_H_
+#define	_STDIO_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+//#define __need___va_list
+#include <stdarg.h>
+
+#define	_SMALL_STDIO_
+
+#include <target_stddef.h>
+
+typedef struct __msFILE {
+  int	_flags;				/* flags, below; this FILE is free if 0 */
+  int	_file;				/* fileno, if Unix descriptor, else -1 */
+  int  (* _func_in)(void*);	/* pointer to a character input function */
+							/* pointer to a character input string function */
+  int  (* _func_ins)(void*, unsigned int, char *);
+  void (* _func_out)(void*, int);	/* pointer to a character output function */
+							/* pointer to a character output string function */
+  int  (* _func_outs)(void*, unsigned int, char *);
+							/* pointer to a character output flush function */
+  int  (* _func_flush)(struct __msFILE *);
+  void * _dev;				/* pointer to local device structure */
+} FILE;
+
+#define	__SLBF	0x0001		/* line buffered */
+#define	__SNBF	0x0002		/* unbuffered */
+#define	__SRD	0x0004		/* OK to read */
+#define	__SWR	0x0008		/* OK to write */
+	/* RD and WR are never simultaneously asserted */
+#define	__SRW	0x0010		/* open for reading & writing */
+#define	__SEOF	0x0020		/* found EOF */
+#define	__SERR	0x0040		/* found error */
+#define	__SMBF	0x0080		/* _buf is from malloc */
+#define	__SAPP	0x0100		/* fdopen()ed in append mode - so must  write to end */
+#define	__SSTR	0x0200		/* this is an sprintf/snprintf string */
+#define	__SOPT	0x0400		/* do fseek() optimisation */
+#define	__SNPT	0x0800		/* do not do fseek() optimisation */
+#define	__SOFF	0x1000		/* set iff _offset is in fact correct */
+#define	__SMOD	0x2000		/* true => fgetline modified _p text */
+
+/*
+ * The following three definitions are for ANSI C, which took them
+ * from System V, which stupidly took internal interface macros and
+ * made them official arguments to setvbuf(), without renaming them.
+ * Hence, these ugly _IOxxx names are *supposed* to appear in user code.
+ *
+ * Although these happen to match their counterparts above, the
+ * implementation does not rely on that (so these could be renumbered).
+ */
+#define	_IOFBF	0		/* setvbuf should set fully buffered */
+#define	_IOLBF	1		/* setvbuf should set line buffered */
+#define	_IONBF	2		/* setvbuf should set unbuffered */
+
+#ifndef NULL
+#define	NULL	0
+#endif
+
+#define	BUFSIZ	1024
+#define	EOF	(-1)
+
+extern FILE _iob[];
+#define  stdin   (&_iob[0])	/* FILE input */
+#define  stdout  (&_iob[1])	/* FILE output */
+#define  stderr  (&_iob[2])	/* FILE error input output */
+
+/*
+ * Functions defined in ANSI C standard.
+ */
+
+#ifdef __GNUC__
+#define __VALIST __gnuc_va_list
+#else
+#define __VALIST char*
+#endif
+
+int fgetc(FILE *);
+int fgets(char *, int, FILE *);
+int fputc(int, FILE *);
+int fputs(const char *, FILE *);
+int putchar(int);
+int puts(const char *);
+int printf(const char *, ...);
+int vprintf(const char *, va_list args);
+int sprintf(char *, const char *, ...);
+int vsprintf(char *, const char *, va_list args);
+int snprintf(char *, size_t, const char *, ...);
+int scanf(const char *, ...);
+int sscanf(char *, const char *, ...);
+int fflush(FILE *);
+FILE *fopen(const char *, const char *);
+int fclose(FILE *);
+size_t fread(void *, size_t, size_t, FILE *);
+size_t fwrite(const void *, size_t, size_t, FILE *);
+int fseek(FILE *, long, int);
+long ftell(FILE *);
+int fprintf(FILE *, const char *, ...);
+int vfprintf(FILE *, const char *, va_list args);
+
+#define	feof(p)     (((p)->_flags & __SEOF) != 0)
+#define	ferror(p)   (((p)->_flags & __SERR) != 0)
+#define	clearerr(p) ((void)((p)->_flags &= ~(__SERR|__SEOF)))
+#define putc(c,fp)  fputc(c,fp)
+#define getchar()   fgetc(stdin)
+#define getc(fp)    fgetc(fp)
+
+/*
+ * NOT SUPPORT stdio functions
+ */
+#define gets(s)                         puts("NOT SUPPORT gets !\n")
+#define ungetc(c, st)                   puts("NOT SUPPORT ungetc !\n")
+#if !defined(__cplusplus) && defined(__GNUC__)
+#define fscanf(st, format, ...)         puts("NOT SUPPORT fscanf !\n")
+#endif
+
+extern void _setup_stdio(signed int *pport);
+extern FILE *_get_stdio(int no);
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* _STDIO_H_ */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/monitor/stdio/fprintf.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/monitor/stdio/fprintf.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/monitor/stdio/fprintf.c	(revision 457)
@@ -0,0 +1,66 @@
+/*
+ *  TOPPERS/ASP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Advanced Standard Profile Kernel
+ * 
+ *  Copyright (C) 2008-2011 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ *  Copyright (C) 2015-2016 by TOPPERS PROJECT Educational Working Group.
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+/*
+ * 
+ *	fprintf代用プログラム
+ *
+ */
+#include <stdio.h>
+#include <string.h>
+#include <stdarg.h>
+
+extern int _setformat(int (*)(int, FILE *), FILE *st, const char *, va_list);
+
+int
+fprintf(FILE *st, const char *format, ...)
+{
+    va_list args;
+    va_start(args, format);
+
+    return _setformat(fputc, st, format, args);
+}
+
+int
+vfprintf(FILE *st, const char *format, va_list args)
+{
+    return _setformat(fputc, st, format, args);
+}
+
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/monitor/stdio/printf.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/monitor/stdio/printf.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/monitor/stdio/printf.c	(revision 457)
@@ -0,0 +1,280 @@
+/*
+ *  TOPPERS/JSP/ASP/FMP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Just Standard Profile Kernel
+ * 
+ *  Copyright (C) 2008-2011 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ *  Copyright (C) 2015-2019 by TOPPERS PROJECT Educational Working Group.
+ * 
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *	printf代用プログラム
+ */
+
+#include <itron.h>
+#include <stdarg.h>
+#include <stdio.h>
+
+/*
+ *  long型から変換される文字列の最大サイズを計算
+ */
+#define CONVERT_BUFLEN	((sizeof(unsigned long) * CHAR_BIT + 4) / 3)
+
+/*
+ *  数値を文字列に変換
+ */
+static int
+convert(unsigned long val, int radix, const char *radchar, int width, int minus, int padzero,
+        void (*putsub)(char c, char **p), char ** putbuf)
+{
+	char	buf[CONVERT_BUFLEN];
+	int	i, j;
+	int count = 0;
+
+	i = 0;
+	do {
+		buf[i++] = radchar[val % radix];
+		val /= radix;
+	} while (i < CONVERT_BUFLEN && val != 0);
+
+	width -= minus;
+	if (minus > 0 && padzero > 0) {
+		putsub('-', putbuf);
+		count++;
+	}
+	for (j = i; j < width; j++) {
+		putsub((char)(padzero > 0 ? '0' : ' '), putbuf);
+		count++;
+	}
+	if (minus > 0 && padzero <= 0) {
+		putsub('-', putbuf);
+		count++;
+	}
+	while (i > 0) {
+		putsub(buf[--i], putbuf);
+		count++;
+	}
+	return count;
+}
+
+/*
+ *  ログ情報フォーマット用ライブラリ関数
+ */
+static char const raddec[] = "0123456789";
+static char const radhex[] = "0123456789abcdef";
+static char const radHEX[] = "0123456789ABCDEF";
+
+int _setformat (void (*putsub)(char c, char **p), char ** putbuf, const char * format, va_list ap)
+{
+	int	c;
+	int count = 0;
+	int	width;
+	int	padzero;
+	int precision;
+	long	val;
+	char const	*str;
+
+	while ((c = *format++) != '\0') {
+		if (c != '%') {
+			putsub((char) c, putbuf);
+			count++;
+			continue;
+		}
+
+		width = padzero = precision = 0;
+		if ((c = *format++) == '0') {
+			padzero = 1;
+			c = *format++;
+		}
+		else if (c == '.') {
+			precision = 1;
+			c = *format++;
+		}
+		while ('0' <= c && c <= '9') {
+			width = width*10 + c - '0';
+			c = *format++;
+		}
+		switch (c) {
+		case 'l':						/* long */
+			c = *format++;
+			switch (c) {
+			case 'd':					/* long 10進整数 */
+			case 'i':					/* long 8,10,16進整数 */
+				val = (long) va_arg(ap, long);
+				if (val >= 0)
+					count += convert(val, 10, raddec, width, 0, padzero, putsub, putbuf);
+				else
+					count += convert(-val, 10, raddec, width, 1, padzero, putsub, putbuf);
+				break;
+			case 'u':					/* unsigned long 10進整数 */
+				val = (long) va_arg(ap, unsigned long);
+				count += convert(val, 10, raddec, width, 0, padzero, putsub, putbuf);
+				break;
+			case 'o':					/* unsigned long 8進整数 */
+				val = (long) va_arg(ap, unsigned long);
+				count += convert(val, 8, raddec, width, 0, padzero, putsub, putbuf);
+				break;
+			case 'x':					/* unsigned long 16進整数 */
+				val = (long) va_arg(ap, unsigned long);
+				count += convert(val, 16, radhex, width, 0, padzero, putsub, putbuf);
+				break;
+			case 'X':					/* unsigned long 大文字16進整数 */
+				val = (long) va_arg(ap, unsigned long);
+				count += convert(val, 16, radHEX, width, 0, padzero, putsub, putbuf);
+				break;
+			case '\0':
+				format--;
+				break;
+			}
+			break;
+
+		case 'h':						/* short */
+			c = *format++;
+			switch (c) {
+			case 'd':					/* short 8進整数 */
+			case 'i':					/* short 8,10,16進整数 */
+				val = (long) ((short)va_arg(ap, int));
+				if (val >= 0)
+					count += convert(val, 10, raddec, width, 0, padzero, putsub, putbuf);
+				else
+					count += convert(-val, 10, raddec, width, 1, padzero, putsub, putbuf);
+				break;
+			case 'u':					/* unsigned short 10進整数 */
+				val = (long) ((unsigned short)va_arg(ap, unsigned int));
+				count += convert(val, 10, raddec, width, 0, padzero, putsub, putbuf);
+				break;
+			case 'o':					/* unsigned short 8進整数 */
+				val = (long) ((unsigned short)va_arg(ap, unsigned int));
+				count += convert(val, 8, raddec, width, 0, padzero, putsub, putbuf);
+				break;
+			case 'x':					/* unsigned short 16進整数 */
+				val = (long) ((unsigned short)va_arg(ap, unsigned int));
+				count += convert(val, 16, radhex, width, 0, padzero, putsub, putbuf);
+				break;
+			case 'X':					/* unsigned short 大文字16進整数 */
+				val = (long) ((unsigned short)va_arg(ap, unsigned int));
+				count += convert(val, 16, radHEX, width, 0, padzero, putsub, putbuf);
+				break;
+			case '\0':
+				format--;
+				break;
+			}
+			break;
+		case 'd':						/* int 10進整数 */
+		case 'i':						/* int 8,10,16進整数 */
+			val = (long) va_arg(ap, int);
+			if (val >= 0)
+				count += convert(val, 10, raddec, width, 0, padzero, putsub, putbuf);
+			else
+				count += convert(-val, 10, raddec, width, 1, padzero, putsub, putbuf);
+			break;
+		case 'u':						/* unsigned int 10進整数 */
+			val = (long) va_arg(ap, unsigned int);
+			count += convert(val, 10, raddec, width, 0, padzero, putsub, putbuf);
+			break;
+		case 'o':						/* unsigned int 8進整数 */
+			val = (long) va_arg(ap, unsigned int);
+			count += convert(val, 8, raddec, width, 0, padzero, putsub, putbuf);
+			break;
+		case 'p':
+		case 'x':						/* unsigned int 16進整数 */
+			val = (long) va_arg(ap, unsigned int);
+			count += convert(val, 16, radhex, width, 0, padzero, putsub, putbuf);
+			break;
+		case 'X':						/* unsigned int 大文字16進整数 */
+			val = (long) va_arg(ap, unsigned int);
+			count += convert(val, 16, radHEX, width, 0, padzero, putsub, putbuf);
+			break;
+
+		case 'c':						/* 1バイト文字 */
+			c = (int) va_arg(ap, unsigned int);
+			putsub((char)(int)c, putbuf);
+			count++;
+			break;
+		case 's':						/* 文字列 */
+			str = (char const *) va_arg(ap, VP_INT);
+			if (width > 0) {
+				while (((c = *str++) != '\0') && (width > 0)) {
+					putsub((char) c, putbuf);
+					count++;
+					width--;
+				}
+				while (width > 0) {
+					putsub(' ', putbuf);
+					count++;
+					width--;
+				}
+			}
+			else {
+				while ((c = *str++) != '\0') {
+					putsub((char) c, putbuf);
+					count++;
+				}
+			}
+			break;
+		case '%':
+			putsub('%', putbuf);
+			count++;
+			break;
+		case '\0':
+			format--;
+			break;
+		}
+	}
+	return count;
+}
+
+static void putzi (char c, char ** p)
+{
+    putchar(c);
+}
+
+int printf (const char * format, ...)
+{
+	va_list args;
+	va_start(args, format);
+	int ret = (_setformat(putzi, NULL, format, args));
+	va_end(args);
+	return ret;
+}
+
+
+int vprintf (const char * format, va_list args)
+{
+	return (_setformat(putzi, NULL, format, args));
+}
+
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/monitor/stdio/scanf.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/monitor/stdio/scanf.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/monitor/stdio/scanf.c	(revision 457)
@@ -0,0 +1,297 @@
+/*
+ *  TOPPERS/JSP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Just Standard Profile Kernel
+ * 
+ *  Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
+ *                              Toyohashi Univ. of Technology, JAPAN
+ *  Copyright (C) 2003-2006 by Ryosuke Takeuchi
+  *                     GJ Business Division RICOH COMPANY,LTD. JAPAN
+ * 
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *	scanf代用プログラム
+ */
+
+#include <stdarg.h>
+#include <stdio.h>
+
+typedef	void		*VP;		/* 型が定まらないものへのポインタ */
+typedef	VP		VP_INT;		/* VP または INT */
+
+#define	BOOL	int
+#define TRUE	1
+#define FALSE	0
+#define FHALF   0
+#define FINT    1
+#define FLONG   2
+
+static BOOL is_terminator(char c)
+{
+	if(c == '\0')
+		return TRUE;
+	else if(c == '\r' || c == '\n' || c == 0xc)
+		return TRUE;
+	else
+		return FALSE;
+}
+
+/*
+ *  文字列を数値に変換
+ */
+static int
+convert(VP_INT p, int radix, int padzero, int width, int minus, int (*getsub)(char **p), char ** getbuf, int type)
+{
+	char	c;
+	int		i;
+	unsigned long val = 0;
+	int count = 0;
+	int csign = 0;
+
+	if(width <= 0)
+		width = 64;
+	c = getsub(getbuf);				/* get first character */
+	if(is_terminator((char)c))
+		return count;
+	if(c < '0' || (c > '9' && c < 'A')
+			   || (c > 'Z' && c < 'a') || c > 'z'){
+		c = getsub(getbuf);
+		if(is_terminator((char)c))
+			return count;
+	}
+
+	while(c == ' ' || c == '\t'){	/* skip white space */
+		c = getsub(getbuf);
+		if(is_terminator((char)c))
+			return count;
+	}
+
+	if(padzero && c == '0'){		/* skip pad zero */
+		do{
+			c = getsub(getbuf);
+			if(is_terminator((char)c))
+				return count;
+		}while(c == '0');
+	}
+	for( ; !is_terminator((char)c) ; c = getsub(getbuf), width--){
+		if(c == '\t' || c == ' ' || c == ',')
+			break;
+		i = 0;
+		if(c == '-' && minus){
+			csign = 1;
+			width++;
+		}
+		else if(c >= '0' && c <= '9')
+			i = c - '0';
+		else if(c >= 'A' && c <= 'Z')
+			i = c - 'A' + 10;
+		else if(c >= 'a' && c <= 'z')
+			i = c - 'a' + 10;
+		else
+			continue;
+
+		if(i >= radix)
+			i = radix - 1;
+		val = val * radix + i;
+		count = 1;
+		if(width <= 1)
+			break;
+	}
+	if(csign)
+		val = (unsigned long)((long)val * -1);
+
+	switch(type){
+	case FHALF:
+		*((unsigned short *)p) = (unsigned short)val;
+		break;
+	case FLONG:
+		*((unsigned long *)p) = (unsigned long)val;
+		break;
+	default:
+		*((unsigned int *)p) = (unsigned int)val;
+		break;
+	}
+	return count;
+}
+
+
+/*
+ *  データ取り込みライブラリ関数
+ */
+
+int _getformat (int (*getsub)(char **p), char ** getbuf, const char * format, va_list ap)
+{
+	int c;
+	int count = 0;
+	int	width;
+	int	padzero;
+	VP_INT	val;
+	char *str;
+
+	while ((c = *format++) != '\0') {
+		if (c != '%') {
+			continue;
+		}
+
+		width = padzero = 0;
+		c = *format++;
+		if (c >= '1' && c <= '9') {
+			padzero = 1;
+		}
+		while (c >= '0' && c <= '9') {
+			width = width*10 + c - '0';
+			c = *format++;
+		}
+		switch (c) {
+		case 'l':						/* long */
+			c = *format++;
+			switch (c) {
+			case 'd':					/* long 10進整数 */
+			case 'i':					/* long 8,10,16進整数 */
+				val = (VP_INT) va_arg(ap, VP_INT);
+				count += convert(val, 10, padzero, width, 1, getsub, getbuf, FLONG);
+				break;
+			case 'u':					/* unsigned long 10進整数 */
+				val = (VP_INT) va_arg(ap, VP_INT);
+				count += convert(val, 10, padzero, width, 0, getsub, getbuf, FLONG);
+				break;
+			case 'o':					/* unsigned long 8進整数 */
+				val = (VP_INT) va_arg(ap, VP_INT);
+				count += convert(val, 8, padzero, width, 0, getsub, getbuf, FLONG);
+				break;
+			case 'x':					/* unsigned long 16進整数 */
+				val = (VP_INT) va_arg(ap, VP_INT);
+				count += convert(val, 16, padzero, width, 0, getsub, getbuf, FLONG);
+				break;
+			case 'X':					/* unsigned long 大文字16進整数 */
+				val = (VP_INT) va_arg(ap, VP_INT);
+				count += convert(val, 16, padzero, width, 0, getsub, getbuf, FLONG);
+				break;
+			case '\0':
+				format--;
+				break;
+			}
+			break;
+		case 'h':						/* short */
+			c = *format++;
+			switch (c) {
+			case 'd':					/* short 8進整数 */
+			case 'i':					/* short 8,10,16進整数 */
+				val = (VP_INT) va_arg(ap, VP_INT);
+				count += convert(val, 10, padzero, width, 1, getsub, getbuf, FHALF);
+				break;
+			case 'u':					/* unsigned short 10進整数 */
+				val = (VP_INT) va_arg(ap, VP_INT);
+				count += convert(val, 10, padzero, width, 0, getsub, getbuf, FHALF);
+				break;
+			case 'o':					/* unsigned short 8進整数 */
+				val = (VP_INT) va_arg(ap, VP_INT);
+				count += convert(val, 8, padzero, width, 0, getsub, getbuf, FHALF);
+				break;
+			case 'x':					/* unsigned short 16進整数 */
+				val = (VP_INT) va_arg(ap, VP_INT);
+				count += convert(val, 16, padzero, width, 0, getsub, getbuf, FHALF);
+				break;
+			case 'X':					/* unsigned short 大文字16進整数 */
+				val = (VP_INT) va_arg(ap, VP_INT);
+				count += convert(val, 16, padzero, width, 0, getsub, getbuf, FHALF);
+				break;
+			case '\0':
+				format--;
+				break;
+			}
+			break;
+		case 'd':						/* int 10進整数 */
+		case 'i':						/* int 8,10,16進整数 */
+			val = (VP_INT) va_arg(ap, VP_INT);
+			count += convert(val, 10, padzero, width, 1, getsub, getbuf, FINT);
+			break;
+		case 'u':						/* unsigned int 10進整数 */
+			val = (VP_INT) va_arg(ap, VP_INT);
+			count += convert(val, 10, padzero, width, 0, getsub, getbuf, FINT);
+			break;
+		case 'o':						/* unsigned int 8進整数 */
+			val = (VP_INT) va_arg(ap, VP_INT);
+			count += convert(val, 8, padzero, width, 0, getsub, getbuf, FINT);
+			break;
+		case 'x':						/* unsigned int 16進整数 */
+			val = (VP_INT) va_arg(ap, VP_INT);
+			count += convert(val, 16, padzero, width, 0, getsub, getbuf, FINT);
+			break;
+		case 'X':						/* unsigned int 大文字16進整数 */
+			val = (VP_INT) va_arg(ap, VP_INT);
+			count += convert(val, 16, padzero, width, 0, getsub, getbuf, FINT);
+			break;
+
+		case 'c':						/* 1バイト文字 */
+			str = (char *) va_arg(ap, VP_INT);
+			*str = getsub(getbuf);
+			count++;
+			break;
+		case 's':						/* 文字列 */
+			str = (char *) va_arg(ap, VP_INT);
+			do{
+				c = getsub(getbuf);
+				if(c == ' ' || c == '\t')
+					break;
+				if(is_terminator((char)c))
+					break;
+				if(width > 0)
+					*str++ = c;
+				width--;
+			}while(c != '\0');
+			*str = '\0';
+			count++;
+			break;
+		case '\0':
+			format--;
+			break;
+		default:
+			break;
+		}
+	}
+	return count;
+}
+
+static int getzi (char ** p)
+{
+	return getchar();
+}
+
+int scanf (const char * format, ...)
+{
+    va_list args;
+    va_start(args, format);
+    return (_getformat(getzi, NULL, format, args));
+}
+
+
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/monitor/stdio/sprintf.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/monitor/stdio/sprintf.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/monitor/stdio/sprintf.c	(revision 457)
@@ -0,0 +1,81 @@
+/*
+ *  TOPPERS/JSP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Just Standard Profile Kernel
+ * 
+ *  Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
+ *                              Toyohashi Univ. of Technology, JAPAN
+ *  Copyright (C) 2003-2004 by Ryosuke Takeuchi
+ *               GW Development Center RICOH COMPANY,LTD. JAPAN
+ * 
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *	sprintf代用プログラム
+ */
+
+#include <stdarg.h>
+
+extern int _setformat(void (*)(char c, char **p), char **, const char *, va_list);
+
+static void putz (char c, char ** p)
+{
+    *(*p)++ = c;
+}
+
+/*  sprintf() takes an unlimited number of arguments,
+ *  which the caller has thoughtfully pushed onto the stack.
+ *  It returns a count of bytes moved to the output buffer.
+ */
+int
+sprintf(char * buffer, const char * format, ...)
+{
+    int count;
+    char * pbuffer = buffer;
+    va_list args;
+    va_start(args, format);
+
+    count = _setformat(putz, &pbuffer, format, args);
+    *pbuffer = 0;
+    return count;
+}
+
+int
+vsprintf(char * buffer, const char * format, va_list args)
+{
+    int count;
+    char * pbuffer = buffer;
+
+    count = _setformat(putz, &pbuffer, format, args);
+    *pbuffer = 0;
+    return count;
+}
+
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/monitor/stdio/sscanf.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/monitor/stdio/sscanf.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/monitor/stdio/sscanf.c	(revision 457)
@@ -0,0 +1,66 @@
+/*
+ *  TOPPERS/JSP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Just Standard Profile Kernel
+ * 
+ *  Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
+ *                              Toyohashi Univ. of Technology, JAPAN
+ *  Copyright (C) 2003-2006 by Ryosuke Takeuchi
+  *                     GJ Business Division RICOH COMPANY,LTD. JAPAN
+ * 
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *	sprintf代用プログラム
+ */
+
+#include <stdarg.h>
+
+extern int _getformat(int (*)(char **p), char **, const char *, va_list);
+
+static int getz (char ** p)
+{
+	int c;
+
+	c = *(*p)++;
+	return c;
+}
+
+
+int sscanf(char * buffer, const char * format, ...)
+{
+    char * gbuffer = buffer;
+    va_list args;
+    va_start(args, format);
+
+    return _getformat(getz, &gbuffer, format, args);
+}
+
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/monitor/stdio/stddev.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/monitor/stdio/stddev.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/monitor/stdio/stddev.c	(revision 457)
@@ -0,0 +1,271 @@
+/*
+ *  TOPPERS/JSP/ASP/FMP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Just Standard Profile Kernel
+ * 
+ *  Copyright (C) 2008-2011 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ *  Copyright (C) 2015-2017 by TOPPERS PROJECT Educational Working Group.
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/* 
+ *  TOPPERS用タスクモニタCPU依存プログラム．
+ *
+ */
+
+#include <itron.h> 
+#include <stdio.h>
+#include <string.h>
+#include "syssvc/serial.h"
+#include "monitor.h"
+
+
+#ifdef _SMALL_STDIO_
+/******************************************************************************
+ * 縮小版標準入出力の設定
+ ******************************************************************************/
+
+FILE _iob[4];
+static ID   dummyid = CONSOLE_PORTID;
+static ID * stdport = &dummyid;
+
+/*
+ *  モニタの１文字入力文
+ */
+static int
+local_getc(FILE *st)
+{
+	char buf[2];
+
+	serial_rea_dat(*stdport, buf, 1);
+	return (int)buf[0];
+}
+
+/*
+ *  モニタの文字列入力文
+ */
+static int
+local_gets(FILE *st, unsigned int len, char *s)
+{
+	return serial_rea_dat(*stdport, s, len);
+}
+
+/*
+ *  モニタの１文字出力文
+ */
+static void
+local_putc(FILE *st, int c)
+{
+	char buf[2];
+
+	buf[0] = c;
+	serial_wri_dat(*stdport, buf, 1);
+	if(c == '\n'){
+		buf[0] = '\r';
+		serial_wri_dat(*stdport, buf, 1);
+	}
+}
+
+/*
+ *  モニタの文字列出力文
+ */
+static int
+local_puts(FILE *st, unsigned int len, char *s)
+{
+	return serial_wri_dat(*stdport, s, len);
+}
+
+/*
+ *  モニタのデータフラッシュ文
+ */
+static int
+local_flush(FILE *st)
+{
+	return 0;
+}
+
+/*
+ *  ローカルなstrlen
+ */
+static int
+local_datacount(const char *s)
+{
+	int i;
+
+	for(i = 0 ; *s != 0 ; i++)
+		s++;
+	return i;
+}
+
+/*
+ *  標準出力関数
+ */
+int fputc(int c, FILE *st)
+{
+	if(st == NULL)
+		st = stdout;
+	st->_func_out(st, c);
+	return 1;
+}
+
+/*
+ *  標準文字列出力関数
+ */
+int fputs(const char *s, FILE *st)
+{
+	int status;
+
+	if(st == NULL)
+		st = stdout;
+	status = st->_func_outs(st, local_datacount(s), (char *)s);
+	st->_func_out(st, '\n');
+	return status;
+}
+
+/*
+ *  標準入力関数
+ */
+int fgetc(FILE *st)
+{
+	if(st == NULL)
+		st = stdin;
+	return st->_func_in(st);
+}
+
+/*
+ *  標準文字列入力関数
+ */
+int fgets(char *buf, int size, FILE *st)
+{
+	if(st == NULL)
+		st = stdin;
+	return st->_func_ins(st, size, buf);
+}
+
+/*
+ *  標準データ読み出し関数
+ */
+size_t fread(void *buf, size_t size, size_t count, FILE *st)
+{
+	int result;
+	if(st == NULL)
+		st = stdin;
+	result = st->_func_ins(st, size*count, buf);
+	return result / size;
+}
+
+/*
+ *  標準データ書き込み関数
+ */
+size_t fwrite(const void *buf, size_t size, size_t count, FILE *st)
+{
+	int result;
+	if(st == NULL)
+		st = stdout;
+	result = st->_func_outs(st, size*count, (char *)buf);
+	return result / size;
+}
+
+/*
+ *  標準文字列出力関数
+ */
+int puts(const char *s)
+{
+	int status;
+
+	status = stdout->_func_outs(stdout, local_datacount(s), (char *)s);
+	stdout->_func_out(stdout, '\n');
+	return status;
+}
+
+/*
+ *  一文字出力プログラム
+ */
+int putchar(int c)
+{
+	return fputc(c,stdout);
+}
+
+/*
+ *  バッファのフラッシュ関数
+ */
+int __wrap_fflush(FILE *st)
+{
+	if(st == NULL)
+		st = stdout;
+	return st->_func_flush(st);
+}
+
+/*
+ *  標準入出力用ストリーム取り出し関数
+ */
+FILE *_get_stdio(int no)
+{
+	return &_iob[no];
+}
+
+/*
+ *  標準入出力ストリーム初期化関数
+ */
+int _set_stdio(int no)
+{
+	if(no >= 0 && no < 3){
+		_iob[no]._file       = -1;
+		_iob[no]._func_in    = (int (*)(void*))local_getc;
+		_iob[no]._func_ins   = (int (*)(void*, unsigned int, char *))local_gets;
+		_iob[no]._func_out   = (void (*)(void*, int))local_putc;
+		_iob[no]._func_outs  = (int  (*)(void*, unsigned int, char *))local_puts;
+		_iob[no]._func_flush = local_flush;
+		_iob[no]._dev        = 0;
+		return no;
+	}
+	else
+		return -1;
+}
+
+/*
+ *  標準入出力初期化関数
+ */
+void _setup_stdio(signed int *pport)
+{
+	int i;
+
+	stdport = pport;
+	for(i = 0 ; i < 3 ; i++){
+		_set_stdio(i);
+	}
+}
+
+#endif /* _SMALL_STDIO_ */
+
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/monitor/task_expansion.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/monitor/task_expansion.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/monitor/task_expansion.c	(revision 457)
@@ -0,0 +1,393 @@
+/*
+ *  TOPPERS/ASP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Advanced Standard Profile Kernel
+ * 
+ *  Copyright (C) 2003-2012 by Ryosuke Takeuchi
+ *                     GJ Business Division RICOH COMPANY,LTD. JAPAN
+ * 
+ *  上記著作権者は，Free Software Foundation によって公表されている 
+ *  GNU General Public License の Version 2 に記述されている条件か，以
+ *  下の(1)～(4)の条件を満たす場合に限り，本ソフトウェア（本ソフトウェ
+ *  アを改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを再利用可能なバイナリコード（リロケータブルオブ
+ *      ジェクトファイルやライブラリなど）の形で利用する場合には，利用
+ *      に伴うドキュメント（利用者マニュアルなど）に，上記の著作権表示，
+ *      この利用条件および下記の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを再利用不可能なバイナリコードの形または機器に組
+ *      み込んだ形で利用する場合には，次のいずれかの条件を満たすこと．
+ *    (a) 利用に伴うドキュメント（利用者マニュアルなど）に，上記の著作
+ *        権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 利用の形態を，別に定める方法によって，上記著作権者に報告する
+ *        こと．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者を免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者は，
+ *  本ソフトウェアに関して，その適用可能性も含めて，いかなる保証も行わ
+ *  ない．また，本ソフトウェアの利用により直接的または間接的に生じたい
+ *  かなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *	TOPPERS/ASP用タスク管理拡張機能
+ */
+
+#include "kernel_impl.h"
+#include "check.h"
+#include "task.h"
+#include "task_expansion.h"
+#include "kernel_cfg.h"
+#include "target_timer.h"
+
+/*
+ *  コンテクスト中からの強制待ち状態への移行
+ */
+ER
+isus_tsk(ID tskid)
+{
+	TCB	*tcb;
+	UINT	tstat;
+	ER	ercd;
+
+	CHECK_INTCTX_UNL();
+	CHECK_TSKID(tskid);
+	tcb = get_tcb(tskid);
+
+	i_lock_cpu();
+	if (TSTAT_DORMANT(tstat = tcb->tstat)) {
+		ercd = E_OBJ;
+	}
+	else if (TSTAT_RUNNABLE(tstat)) {
+		/*
+		 *  実行できる状態から強制待ち状態への遷移
+		 */
+		tcb->tstat = TS_SUSPENDED;
+		if (make_non_runnable(tcb)) {
+			reqflg = TRUE;
+		}
+		ercd = E_OK;
+	}
+	else if (TSTAT_SUSPENDED(tstat)) {
+		ercd = E_QOVR;
+	}
+	else {
+		/*
+		 *  待ち状態から二重待ち状態への遷移
+		 */
+		tcb->tstat |= TS_SUSPENDED;
+		ercd = E_OK;
+	}
+	i_unlock_cpu();
+
+    error_exit:
+	return(ercd);
+}
+
+/*
+ *  タスク状態参照（簡易版）
+ */
+ER
+ref_tst(ID tskid, T_RTST *pk_rtst)
+{
+	TCB	*tcb;
+	UB	tstat;
+	ER	ercd;
+
+	CHECK_TSKCTX_UNL();
+	CHECK_TSKID_SELF(tskid);
+	tcb = get_tcb_self(tskid);
+
+	t_lock_cpu();
+	pk_rtst->tskwait  = 0;
+	pk_rtst->tskpri   = EXT_TSKPRI(tcb->priority);
+#ifdef USE_TSKINICTXB
+	pk_rtst->inistk   = (VP)tcb->p_tinib->tskinictxb.stk_bottom;
+	pk_rtst->inistksz = tcb->p_tinib->tskinictxb.stksz;
+#else
+	pk_rtst->inistk   = (VP)tcb->p_tinib->stk;
+	pk_rtst->inistksz = tcb->p_tinib->stksz;
+#endif
+
+	tstat = tcb->tstat;
+	if (TSTAT_RUNNABLE(tstat)) {
+		if (tcb == p_runtsk) {
+			pk_rtst->tskstat = TTS_RUN;
+		}
+		else {
+			pk_rtst->tskstat = TTS_RDY;
+		}
+	}
+	else if (TSTAT_WAITING(tstat)) {
+		if (TSTAT_SUSPENDED(tstat)) {
+			pk_rtst->tskstat = TTS_WAS;
+		}
+		else {
+			pk_rtst->tskstat = TTS_WAI;
+		}
+		if ((tstat & TS_WAIT_MASK) == TS_WAIT_DLY) {
+			pk_rtst->tskwait = TTW_DLY;
+		}
+		else if ((tstat & TS_WAIT_MASK) == TS_WAIT_SLP) {
+			pk_rtst->tskwait = TTW_SLP;
+		}
+		else if ((tstat & TS_WAIT_MASK) == TS_WAIT_RDTQ) {
+			pk_rtst->tskwait = TTW_RDTQ;
+		}
+		else {
+			pk_rtst->tskwait = TTW_OTHR;
+		}
+	}
+	else if (TSTAT_SUSPENDED(tstat)) {
+		pk_rtst->tskstat = TTS_SUS;
+	}
+	else {
+		pk_rtst->tskstat = TTS_DMT;
+	}
+	if (pk_rtst->tskstat == TTS_DMT)
+		pk_rtst->tskpc = (FP)tcb->p_tinib->task;
+	else
+		pk_rtst->tskpc = (FP)tcb->tskctxb.pc;
+	pk_rtst->tsksp   = (VP)tcb->tskctxb.sp;
+	ercd = E_OK;
+	t_unlock_cpu();
+
+    error_exit:
+	return(ercd);
+}
+
+/*
+ *  タスク状態のロギング格納領域
+ */
+static T_TLOG   tsk_log[MAX_TASK_LOG+1];
+static uint32_t check_tskid;
+static SYSTIM   check_time;
+static SYSTIM   pervious_time;
+
+/*
+ *  システム時間取り出し関数
+ *  割込み中でも使用でき、共通化できるように
+ *  インライン関数とする．
+ */
+Inline SYSTIM get_systime(void)
+{
+	return next_time;
+}
+
+/*
+ *  タスクの実測時間測定用の時間
+ *  取り出し関数、CPUロック状態で呼び出す．
+ */
+Inline SYSTIM get_anatime(void)
+{
+	SYSTIM  time;
+#if TIC_DENO != 1
+	INT     subtime;
+#endif /* TIC_DENO != 1 */
+	CLOCK   clock1, clock2;
+	BOOL    ireq;
+
+	/*
+	 * 時間の取り出しはコンテキスト中でも行われるので
+	 * get_utmと同等の記述をここにおく。
+	 */
+#if TIC_DENO != 1
+	subtime = (INT) next_subtime;
+#endif /* TIC_DENO != 1 */
+	clock1 = target_timer_get_current();
+	ireq = target_timer_probe_int();
+	clock2 = target_timer_get_current();
+
+	time = get_systime() * ANA_STIC;
+#if TIC_DENO != 1
+	time += subtime * ANA_STIC / TIC_DENO;
+#endif /* TIC_DENO != 1 */
+	if (!(ireq) || clock1 > clock2) {
+		time -= TIC_NUME * ANA_STIC / TIC_DENO;
+	}
+	time += clock1 * ANA_STIC / TIMER_CLOCK;
+	return time;
+}
+
+/*
+ *  タスク実行領域設定関数
+ *  この関数はdispatchの開始時、CPUロック状態で呼び出す．
+ *  STM32F746はこの関数を複雑にするとハングアップ時間の方はあきらめる．
+ */
+void log_dsp_enter(TCB *runtsk)
+{
+#if !defined(TOPPERS_ARM_M) || defined(TOPPERS_STM32F4_DISCOVERY)
+	SYSTIM time = get_systime();
+#endif	/* ROI DEBUG */
+	T_TLOG  *t;
+
+	if(check_tskid < MAX_TASK_LOG)
+		t = &tsk_log[check_tskid];
+	else
+		t = &tsk_log[MAX_TASK_LOG];
+#if !defined(TOPPERS_ARM_M) || defined(TOPPERS_STM32F4_DISCOVERY)
+	t->runtimes += time - check_time;
+	check_time = time;
+#endif
+	if(p_schedtsk == 0){
+		check_tskid = 0;
+#if defined(TOPPERS_ARM_M) && !defined(TOPPERS_STM32F4_DISCOVERY)
+		t->runtimes += 2;
+//		check_time  += 2;
+#endif
+	}
+}
+
+/*
+ *  タスク実行領域設定関数
+ *  この関数はdispatchの終了時時、CPUロック状態で呼び出す．
+ */
+void log_dsp_leave(TCB *runtsk)
+{
+	SYSTIM time = get_anatime();
+	T_TLOG  *t;
+
+	if(check_tskid < MAX_TASK_LOG)
+		t = &tsk_log[check_tskid];
+	else
+		t = &tsk_log[MAX_TASK_LOG];
+	t->runtimes += time - check_time;
+
+	if(runtsk){
+		check_tskid = TSKID(runtsk);
+		t = &tsk_log[check_tskid];
+		t->runcount++;
+	}
+	else
+		check_tskid = 0;
+	check_time = time;
+}
+
+/*
+ *  タスクログ状態取り出し関数
+ */
+int_t get_tsklog(T_TPRM * pprm)
+{
+	INT no;
+	INT num_item=0;
+
+	get_tim(&pprm->currtime);
+	t_lock_cpu();
+	pprm->pervtime = pervious_time;
+	pervious_time  = pprm->currtime;
+	for(no = 0 ; no <= tmax_tskid && no <= MAX_TASK_LOG ; no++){
+		if(no < NUM_LDSP){
+			pprm->tlog[no] = tsk_log[no];
+			num_item = no;
+		}
+		else{
+			pprm->tlog[1].runcount += tsk_log[no].runcount;
+			pprm->tlog[1].runtimes += tsk_log[no].runtimes;
+			num_item = NUM_LDSP-1;
+		}
+		tsk_log[no].runcount = 0;
+		tsk_log[no].runtimes = 0;
+	}
+	t_unlock_cpu();
+	return num_item;
+}
+
+
+/*
+ *  デバイス・ポートのログアウト要求判定用データ領域
+ */
+
+static T_PCHK port_log[NUM_PCHK];
+
+/*
+ *  デバイスログを行うかどうかの判定
+ */
+static uint_t check_device_log(ulong_t address, ulong_t size)
+{
+	int    i;
+	T_PCHK *p;
+
+	for(i = 0 ; i < NUM_PCHK ; i++){
+		p = &port_log[i];
+		if(p->portaddress >= address && p->portaddress < (address+size) && p->logtype)
+			return (UINT)p->logtype;
+	}
+	return 0;
+}
+
+/*
+ *  デバイス・ポートのログ判定データの取り出し
+ */
+T_PCHK *get_device_log(ulong_t no){
+	if(no < NUM_PCHK)
+		return &port_log[no];
+	else
+		return 0;
+}
+
+/*
+ *  デバイス読み出し表示判定とログアウト関数
+ */
+void
+ana_rdv(ulong_t address, ulong_t data, int_t size)
+{
+	SYSTIM time = get_systime();
+	ID     id;
+	uint_t logtype = check_device_log(address, size);
+
+	if(logtype == 0)
+		return;
+	if(sense_context() || !p_runtsk)
+		syslog_3(logtype, "Device Read  time=%09d interrupt port=%08x data=0x%x", time, address, data);
+	else{
+		id = TSKID(p_runtsk);
+		switch(size){
+		case 4:
+			syslog_4(logtype, "Device Read  time=%09d task=%04d port=%08x data=%08x", time, id, address, data);
+			break;
+		case 2:
+			syslog_4(logtype, "Device Read  time=%09d task=%04d port=%08x data=%04x", time, id, address, data);
+			break;
+		default:
+			syslog_4(logtype, "Device Read  time=%09d task=%04d port=%08x data=%02x", time, id, address, data);
+			break;
+		}
+	}
+}
+
+/*
+ *  デバイス書き込み表示判定とログアウト関数
+ */
+void
+ana_wdv(ulong_t address, ulong_t data, int_t size)
+{
+	SYSTIM time = get_systime();
+	ID     id;
+	uint_t logtype = check_device_log(address, size);
+
+	if(logtype == 0)
+		return;
+	if(sense_context() || !p_runtsk)
+		syslog_3(logtype, "Device Write  time=%09d interrupt port=%08x data=0x%x", time, address, data);
+	else{
+		id = TSKID(p_runtsk);
+		switch(size){
+		case 4:
+			syslog_4(logtype, "Device Write time=%09d task=%04d port=%08x data=%08x", time, id, address, data);
+			break;
+		case 2:
+			syslog_4(logtype, "Device Write time=%09d task=%04d port=%08x data=%04x", time, id, address, data);
+			break;
+		default:
+			syslog_4(logtype, "Device Write time=%09d task=%04d port=%08x data=%02x", time, id, address, data);
+			break;
+		}
+	}
+}
+
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/monitor/task_expansion.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/monitor/task_expansion.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/monitor/task_expansion.h	(revision 457)
@@ -0,0 +1,123 @@
+/*
+ *  TOPPERS/ASP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Advanced Standard Profile Kernel
+ * 
+ *  Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
+ *                              Toyohashi Univ. of Technology, JAPAN
+ *  Copyright (C) 2003-2008 by Ryosuke Takeuchi
+ *                     GJ Business Division RICOH COMPANY,LTD. JAPAN
+ * 
+ *  上記著作権者は，Free Software Foundation によって公表されている 
+ *  GNU General Public License の Version 2 に記述されている条件か，以
+ *  下の(1)～(4)の条件を満たす場合に限り，本ソフトウェア（本ソフトウェ
+ *  アを改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを再利用可能なバイナリコード（リロケータブルオブ
+ *      ジェクトファイルやライブラリなど）の形で利用する場合には，利用
+ *      に伴うドキュメント（利用者マニュアルなど）に，上記の著作権表示，
+ *      この利用条件および下記の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを再利用不可能なバイナリコードの形または機器に組
+ *      み込んだ形で利用する場合には，次のいずれかの条件を満たすこと．
+ *    (a) 利用に伴うドキュメント（利用者マニュアルなど）に，上記の著作
+ *        権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 利用の形態を，別に定める方法によって，上記著作権者に報告する
+ *        こと．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者を免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者は，
+ *  本ソフトウェアに関して，その適用可能性も含めて，いかなる保証も行わ
+ *  ない．また，本ソフトウェアの利用により直接的または間接的に生じたい
+ *  かなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *	TOPPERS/ASPモニタ用タスク用拡張定義
+ */
+
+#ifndef _TASK_EXPANSION_H_
+#define _TASK_EXPANSION_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "itron.h"
+#include "kernel_impl.h"
+
+/*
+ *  タスク状態（簡易版）のパケット形式
+ */
+
+typedef struct t_rtst{
+	STAT    tskstat;			/* タスク状態 */
+	STAT    tskwait;			/* 待ち要因 */
+	PRI     tskpri;				/* タスクの現在の優先度 */
+	FP      tskpc;				/* タスクの現在のプログラムカウンタ */
+	VP      tsksp;				/* タスクの現在のスタックポインタ */
+	VP      inistk;				/* 初期設定のスタックアドレス */
+	SIZE    inistksz;			/* 初期設定のスタックサイズ */
+}T_RTST;
+
+#define	TTW_OTHR	0x0040		/* その他の待ち状態 */
+					/* TOPPERS待ち状態TTW_SEM,TTW_FLG, TTW_SDTQ */
+					/* TTW_MBX, TTW_MPFの待ち状態区別ではない */
+
+/*
+ *  タスクの実行状態構造体定義
+ */
+#define	MAX_TASK_LOG	8		/* タスクログテーブルの数 */
+#define	ANA_STIC		10		/* サブチック値 */
+
+typedef struct t_tlog{
+	int_t   runcount;			/* タスクの実行回数 */
+	SYSTIM	runtimes;			/* タスクの実行時間(MS) */
+}T_TLOG;
+
+/*
+ *  タスクのログ情報取り出し構造体定義
+ */
+
+#define	NUM_LDSP		6		/* 表示用のログ情報取り出し領域の最大数 */
+
+typedef struct t_tprm{
+	SYSTIM  pervtime;			/* 過去の参照時間 */
+	SYSTIM  currtime;			/* 今回の参照時間 */
+	T_TLOG	tlog[NUM_LDSP];		/* 取り出したログ情報 */
+}T_TPRM;
+
+/*
+ *  デバイスポート判定テーブルの構造体定義
+ */
+
+#define	NUM_PCHK		4		/* デバイスポート判定テーブルのアイテム数 */
+
+typedef struct t_pchk{
+	char    logtype;			/* ログ表示判定情報 */
+	ulong_t portaddress;		/* ポートアドレス */
+}T_PCHK;
+
+/*
+ *  プロトタイプ宣言
+ */
+
+extern ER isus_tsk(ID tskid);
+extern ER ref_tst(ID tskid, T_RTST *pk_rtst);
+extern void iana_tsk(void);
+extern void ana_rdv(ulong_t address, ulong_t data, int_t size);
+extern void ana_wdv(ulong_t address, ulong_t data, int_t size);
+extern int_t get_tsklog(T_TPRM *pprm);
+extern T_PCHK *get_device_log(ulong_t no);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _TASK_EXPANSION_H_ */
+
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/pdic/stm32f7xx/adc.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/pdic/stm32f7xx/adc.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/pdic/stm32f7xx/adc.c	(revision 457)
@@ -0,0 +1,730 @@
+/*
+ *  TOPPERS/ASP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Advanced Standard Profile Kernel
+ * 
+ *  Copyright (C) 2008-2011 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ *  Copyright (C) 2015-2016 by TOPPERS PROJECT Educational Working Group.
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+/*
+ * 
+ *  ADCドライバ関数群
+ *
+ */
+#include <kernel.h>
+#include <t_syslog.h>
+#include <t_stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include "syssvc/serial.h"
+#include "syssvc/syslog.h"
+#include <target_syssvc.h>
+#include "device.h"
+#include "adc.h"
+
+/*
+ *  SIL関数のマクロ定義
+ */
+#define sil_orw_mem(a, b)		sil_wrw_mem((a), sil_rew_mem(a) | (b))
+#define sil_andw_mem(a, b)		sil_wrw_mem((a), sil_rew_mem(a) & ~(b))
+#define sil_modw_mem(a, b, c)	sil_wrw_mem((a), (sil_rew_mem(a) & (~b)) | (c))
+
+/*
+ *  I2CポートIDから管理ブロックを取り出すためのマクロ
+ */
+#define INDEX_ADC(adcid)        ((uint_t)((adcid) - 1))
+
+#define ADC_CHANNEL_TEMPSENSOR  ((uint32_t)ADC_CHANNEL_16)
+
+/*
+ *  ADC実行待ち時間(μsec)
+ */
+#define ADC_STAB_DELAY_US              3
+/*
+ *  ADC温度センサー実行待ち時間(μsec)
+ */
+#define ADC_TEMPSENSOR_DELAY_US        10
+
+/*
+ *  ADCポート設定テーブル
+ */
+static const ADC_PortControlBlock adc_pcb[NUM_ADCPORT] = {
+  {	TADR_ADC1_BASE,
+	(TADR_RCC_BASE+TOFF_RCC_APB2ENR),  RCC_APB2ENR_ADC1EN,
+	(TADR_RCC_BASE+TOFF_RCC_AHB1ENR),  RCC_AHB1ENR_DMA2EN,
+	TADR_DMA2_STM0_BASE, DMA_CHANNEL_0 },
+  {	TADR_ADC2_BASE,
+	(TADR_RCC_BASE+TOFF_RCC_APB2ENR),  RCC_APB2ENR_ADC2EN,
+	(TADR_RCC_BASE+TOFF_RCC_AHB1ENR),  RCC_AHB1ENR_DMA2EN,
+	TADR_DMA2_STM2_BASE, DMA_CHANNEL_1 },
+  {	TADR_ADC3_BASE,
+	(TADR_RCC_BASE+TOFF_RCC_APB2ENR),  RCC_APB2ENR_ADC3EN,
+	(TADR_RCC_BASE+TOFF_RCC_AHB1ENR),  RCC_AHB1ENR_DMA2EN,
+	TADR_DMA2_STM0_BASE, DMA_CHANNEL_2 }
+};
+
+static ADC_Handle_t  AdcHandle[NUM_ADCPORT];
+
+/*
+ *  ADC DMA転送終了コールバック関数
+ */
+static void
+adc_dmatrans_func(DMA_Handle_t *hdma)
+{
+	ADC_Handle_t* hadc = ( ADC_Handle_t* )((DMA_Handle_t* )hdma)->localdata;
+
+	if(hadc->Init.ContinuousConvMode == ADC_CONTINUOUS_DISABLE)
+		hadc->status = ADC_STATUS_EOC;
+	else
+		hadc->status = ADC_STATUS_BUSY_EOC;
+	if(hadc->xfercallback != NULL)
+		hadc->xfercallback(hadc);
+}
+
+/*
+ *  ADC DMAハーフ転送コールバック関数
+ */
+static void
+adc_dmahalftrans_func(DMA_Handle_t *hdma)
+{
+	ADC_Handle_t* hadc = ( ADC_Handle_t* )((DMA_Handle_t* )hdma)->localdata;
+
+	if(hadc->xferhalfcallback != NULL)
+		hadc->xferhalfcallback(hadc);
+}
+
+/*
+ *  ADC DMAエラーコールバック関数
+ */
+static void
+adc_dmaerror_func(DMA_Handle_t *hdma)
+{
+	ADC_Handle_t* hadc = ( ADC_Handle_t* )((DMA_Handle_t* )hdma)->localdata;
+
+	hadc->status = ADC_STATUS_READY;
+	hadc->ErrorCode |= ADC_ERROR_DMA;
+	if(hadc->errorcallback != NULL)
+		hadc->errorcallback(hadc);
+}
+
+/*
+ *  ADC初期設定
+ *  parameter1  port: ADCポート番号
+ *  parameter2  pini: ADC初期設定構造体へのポインタ
+ *  return ADCハンドラへのポインタ、NULLでエラー
+ */
+ADC_Handle_t *
+adc_init(ID portid, ADC_Init_t* pini)
+{
+	static DMA_Handle_t  hdma_adc;
+	ADC_Handle_t *hadc;
+	const ADC_PortControlBlock *apcb;
+
+	/*
+	 *  設定パラメータチェック
+	 */
+	if(portid < 1 || portid > NUM_ADCPORT)
+		return NULL;
+
+	hadc = &AdcHandle[INDEX_ADC(portid)];
+	memcpy(&hadc->Init, pini, sizeof(ADC_Init_t));
+
+	apcb = &adc_pcb[INDEX_ADC(portid)];
+	hadc->base = apcb->base;
+
+	/*
+	 *  ADCクロック設定
+	 */
+	sil_orw_mem((uint32_t *)(apcb->adcclockbase), apcb->adcclockbit);
+	sil_rew_mem((uint32_t *)(apcb->adcclockbase));
+
+	/*
+	 *  DMA対応があれば、DMA設定を行う
+	 */
+	if(apcb->dmaclockbase != 0 && pini->DMAContinuousRequests != ADC_DMACONTINUOUS_DISABLE){
+		sil_orw_mem((uint32_t *)(apcb->dmaclockbase), apcb->dmaclockbit);
+		sil_rew_mem((uint32_t *)(apcb->dmaclockbase));
+
+		hdma_adc.base = apcb->dmarxbase;
+		hdma_adc.Init.Channel  = apcb->dmarxchannel;
+		hdma_adc.Init.Direction = DMA_PERIPH_TO_MEMORY;
+		hdma_adc.Init.PeriphInc = DMA_PINC_DISABLE;
+		hdma_adc.Init.MemInc = DMA_MINC_ENABLE;
+		hdma_adc.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD;
+		hdma_adc.Init.MemDataAlignment = DMA_MDATAALIGN_WORD;
+		if((pini->DMAContinuousRequests & ADC_DMANONECIRCULAR) != 0)
+			hdma_adc.Init.Mode = DMA_NORMAL;
+		else
+			hdma_adc.Init.Mode = DMA_CIRCULAR;
+		hdma_adc.Init.Priority = DMA_PRIORITY_HIGH;
+		hdma_adc.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
+		hdma_adc.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_HALFFULL;
+		hdma_adc.Init.MemBurst = DMA_MBURST_SINGLE;
+		hdma_adc.Init.PeriphBurst = DMA_PBURST_SINGLE;
+
+		dma_init(&hdma_adc);
+
+		hadc->hdmarx = &hdma_adc;
+		hdma_adc.localdata = hadc;
+	}
+	else{
+		hadc->hdmarx = NULL;
+	}
+
+	/*
+	 *  ADCのプリスケーラ設定(コモン設定)
+	 */
+	sil_modw_mem((uint32_t *)(TADR_ADC_BASE+TOFF_ADC_CCR), ADC_CCR_ADCPRE, hadc->Init.ClockPrescaler);
+
+	/*
+	 *  ADC初期設定
+	 */
+	sil_modw_mem((uint32_t *)(hadc->base+TOFF_ADC_CR1), ADC_CR1_SCAN, hadc->Init.ScanConvMode);
+	sil_modw_mem((uint32_t *)(hadc->base+TOFF_ADC_CR1), ADC_CR1_RES, hadc->Init.Resolution);
+	sil_modw_mem((uint32_t *)(hadc->base+TOFF_ADC_CR2), ADC_CR2_ALIGN, hadc->Init.DataAlign);
+
+	/*
+	 *  ADC外部トリガ設定
+	 */
+	if(hadc->Init.ExternalTrigConv != ADC_SOFTWARE_START){
+		sil_modw_mem((uint32_t *)(hadc->base+TOFF_ADC_CR2), ADC_CR2_EXTSEL, hadc->Init.ExternalTrigConv);
+		sil_modw_mem((uint32_t *)(hadc->base+TOFF_ADC_CR2), ADC_CR2_EXTEN, hadc->Init.ExternalTrigConvEdge);
+	}
+	else{
+		sil_andw_mem((uint32_t *)(hadc->base+TOFF_ADC_CR2), (ADC_CR2_EXTSEL | ADC_CR2_EXTEN));
+	}
+
+	/*
+	 *  ADC継続モード設定
+	 */
+	sil_modw_mem((uint32_t *)(hadc->base+TOFF_ADC_CR2), ADC_CR2_CONT, hadc->Init.ContinuousConvMode);
+	sil_modw_mem((uint32_t *)(hadc->base+TOFF_ADC_CR1), ADC_CR1_DISCEN, hadc->Init.DiscontinuousConvMode);
+	sil_modw_mem((uint32_t *)(hadc->base+TOFF_ADC_CR1), ADC_CR1_DISCNUM, hadc->Init.NumDiscConversion << 13);
+
+	/*
+	 *  コンバージョン数設定
+	 */
+	sil_modw_mem((uint32_t *)(hadc->base+TOFF_ADC_SQR1), ADC_SQR1_L, (hadc->Init.NumConversion - 1) << 20);
+
+	/*
+	 *  ADC-DMAモード設定
+	 */
+	sil_modw_mem((uint32_t *)(hadc->base+TOFF_ADC_CR2), ADC_CR2_DDS, hadc->Init.DMAContinuousRequests);
+
+	/*
+	 *  ADC EOC設定
+	 */
+	sil_modw_mem((uint32_t *)(hadc->base+TOFF_ADC_CR2), ADC_CR2_EOCS, hadc->Init.EOCSelection);
+
+	/*
+	 *  ADCを初期状態に
+	 */
+	hadc->ErrorCode = ADC_ERROR_NONE;
+	hadc->status = ADC_STATUS_READY;
+	return hadc;
+}
+
+/*
+ *  ADC終了設定
+ *  parameter1  hadc: ADCハンドラへのポインタ
+ *  return ERコード
+ */
+ER
+adc_deinit(ADC_Handle_t* hadc)
+{
+	if(hadc == NULL)
+		return E_PAR;
+
+	/*
+	 *  ADCリセット(コモン設定)
+	 */
+	sil_orw_mem((uint32_t *)(TADR_RCC_BASE+TOFF_RCC_APB2RSTR), RCC_APB2RSTR_ADCRST);
+	sil_andw_mem((uint32_t *)(TADR_RCC_BASE+TOFF_RCC_APB2RSTR), RCC_APB2RSTR_ADCRST);
+
+	/*
+	 *  DMA停止
+	 */
+	if(hadc->hdmarx != NULL)
+		dma_deinit(hadc->hdmarx);
+
+	/*
+	 *  ADCの状態初期化
+	 */
+	hadc->ErrorCode = ADC_ERROR_NONE;
+	hadc->status = ADC_STATUS_RESET;
+	return E_OK;
+}
+
+/*
+ *  ADC-割込みモード開始処理
+ *  parameter1  hadc: ADCハンドラへのポインタ
+ *  return ERコード
+ */
+ER
+adc_start_int(ADC_Handle_t* hadc)
+{
+	if(hadc == NULL)
+		return E_PAR;
+
+	/*
+	 *  実行状態に移行
+	 */
+	hadc->status = ADC_STATUS_BUSY;
+	hadc->ErrorCode = ADC_ERROR_NONE;
+
+	/*
+	 *  ADCが有効でなければ、ADCを設定し実行待ちを行う
+	 */
+	if((sil_rew_mem((uint32_t *)(hadc->base+TOFF_ADC_CR2)) & ADC_CR2_ADON) == 0){
+		sil_orw_mem((uint32_t *)(hadc->base+TOFF_ADC_CR2), ADC_CR2_ADON);
+		sil_dly_nse(ADC_STAB_DELAY_US*1000);
+	}
+
+	/*
+	 *  エラー転送割込み設定
+	 */
+	sil_orw_mem((uint32_t *)(hadc->base+TOFF_ADC_CR1), (ADC_CR1_OVRIE | ADC_CR1_EOCIE));
+
+	/*
+	 *  マルチモード判定
+	 */
+	if((sil_rew_mem((uint32_t *)(TADR_ADC_BASE+TOFF_ADC_CCR)) & ADC_CCR_MULTI) == 0){
+		/*
+		 *  非マルチモード：外部トリガでなければソフトスタート
+		 */
+		if((sil_rew_mem((uint32_t *)(hadc->base+TOFF_ADC_CR2)) & ADC_CR2_EXTEN) == 0){
+			sil_orw_mem((uint32_t *)(hadc->base+TOFF_ADC_CR2), ADC_CR2_SWSTART);
+		}
+	}
+	else{
+		/*
+		 *  マルチモード：ADC1で外部トリガでなければソフトスタート
+		 */
+		if((hadc->base == TADR_ADC1_BASE) && ((sil_rew_mem((uint32_t *)(hadc->base+TOFF_ADC_CR2)) & ADC_CR2_EXTEN) == 0)){
+			sil_orw_mem((uint32_t *)(hadc->base+TOFF_ADC_CR2), ADC_CR2_SWSTART);
+		}
+	}
+	return E_OK;
+}
+
+/*
+ *  ADC-割込みモード停止処理
+ *  parameter1  hadc: ADCハンドラへのポインタ
+ *  return ERコード
+ */
+ER
+adc_end_int(ADC_Handle_t* hadc)
+{
+	if(hadc == NULL)
+		return E_PAR;
+
+	/*
+	 *  転送、エラー割込み停止
+	 */
+	sil_andw_mem((uint32_t *)(hadc->base+TOFF_ADC_CR1), (ADC_CR1_EOCIE | ADC_CR1_JEOCIE | ADC_CR1_OVRIE));
+
+	/*
+	 *  ADCモジュール停止
+	 */
+	sil_andw_mem((uint32_t *)(hadc->base+TOFF_ADC_CR2), ADC_CR2_ADON);
+
+	hadc->status = ADC_STATUS_READY;
+	return E_OK;
+}
+
+/*
+ *  ADC-DMAモード開始処理
+ *  parameter1  hadc: ADCハンドラへのポインタ
+ *  parameter2  pdata: 受信領域のポインタ
+ *  parameter3  length: 受信データ長
+ *  return ERコード
+ */
+ER
+adc_start_dma(ADC_Handle_t* hadc, uint32_t* pdata, uint32_t length)
+{
+	if(hadc == NULL)
+		return E_PAR;
+
+	/*
+	 *  ADC DMA設定
+	 */
+	sil_orw_mem((uint32_t *)(hadc->base+TOFF_ADC_CR2), ADC_CR2_DMA);
+
+	/*
+	 *  ADCオーバーラン割込み設定
+	 */
+	sil_orw_mem((uint32_t *)(hadc->base+TOFF_ADC_CR1), ADC_CR1_OVRIE);
+
+	/*
+	 *  DMAコールバック関数設定
+	 */
+	hadc->hdmarx->xfercallback = adc_dmatrans_func;
+	hadc->hdmarx->xferhalfcallback = adc_dmahalftrans_func;
+	hadc->hdmarx->errorcallback = adc_dmaerror_func;
+
+	/*
+	 *  実行状態に移行
+	 */
+	hadc->status = ADC_STATUS_BUSY;
+	hadc->ErrorCode = ADC_ERROR_NONE;
+	hadc->NumCurrentConversionRank = hadc->Init.NumConversion;
+
+	/*
+	 *  DMAスタート
+	 */
+	dma_start(hadc->hdmarx, hadc->base+TOFF_ADC_DR, (uint32_t)pdata, length);
+
+	/*
+	 *  ADCが有効でなければ、ADCを設定し実行待ちを行う
+	 */
+	if((sil_rew_mem((uint32_t *)(hadc->base+TOFF_ADC_CR2)) & ADC_CR2_ADON) == 0){
+		sil_orw_mem((uint32_t *)(hadc->base+TOFF_ADC_CR2), ADC_CR2_ADON);
+		sil_dly_nse(ADC_STAB_DELAY_US*1000);
+	}
+
+	/*
+	 *  外部トリガ設定がなければ、ソフトウェアコンバージョンスタート設定を行う
+	 */
+	if((sil_rew_mem((uint32_t *)(hadc->base+TOFF_ADC_CR2)) & ADC_CR2_EXTEN) == 0){
+		sil_orw_mem((uint32_t *)(hadc->base+TOFF_ADC_CR2), ADC_CR2_SWSTART);
+	}
+	return E_OK;
+}
+
+/*
+ *  ADC-DMAモード停止処理
+ *  parameter1  hadc: ADCハンドラへのポインタ
+ *  return ERコード
+ */
+ER
+adc_end_dma(ADC_Handle_t* hadc)
+{
+	if(hadc == NULL)
+		return E_PAR;
+
+	/*
+	 *  ADCモジュール停止
+	 */
+	sil_andw_mem((uint32_t *)(hadc->base+TOFF_ADC_CR2), ADC_CR2_ADON);
+
+	/*
+	 *  オーバーラン割込みを停止
+	 */
+	sil_andw_mem((uint32_t *)(hadc->base+TOFF_ADC_CR1), ADC_CR1_OVRIE);
+
+	/*
+	 *  ADCのDMAモードをオフ
+	 */
+	sil_andw_mem((uint32_t *)(hadc->base+TOFF_ADC_CR2), ADC_CR2_DMA);
+
+	/*
+	 *  DMAを停止
+	 */
+	if(hadc->hdmarx != NULL)
+		dma_end(hadc->hdmarx);
+
+	hadc->status = ADC_STATUS_READY;
+	return E_OK;
+}
+
+/*
+ *  ADC 割込みハンドラ実行関数
+ */
+void
+adc_handler(ADC_Handle_t* hadc)
+{
+	uint32_t sr  = sil_rew_mem((uint32_t *)(hadc->base+TOFF_ADC_SR));
+	uint32_t cr1 = sil_rew_mem((uint32_t *)(hadc->base+TOFF_ADC_CR1));
+	uint32_t cr2 = sil_rew_mem((uint32_t *)(hadc->base+TOFF_ADC_CR2));
+
+	/*
+	 *  レギュラーレジスタの終了判定
+	 */
+	if((sr & ADC_SR_EOC) != 0 && (cr1 & ADC_CR1_EOCIE) != 0){
+		if((cr2 & ADC_CR2_CONT) == 0)		/* ステータスの変更 */
+			hadc->status = ADC_STATUS_EOC;
+		else
+			hadc->status = ADC_STATUS_BUSY_EOC;
+
+		if((hadc->Init.ContinuousConvMode == ADC_CONTINUOUS_DISABLE) && ((cr2 & ADC_CR2_EXTEN) == 0)){
+			if(hadc->Init.EOCSelection == ADC_EOC_SEQ_DISABLE){
+				/*
+				 *  転送とエラー割込みを停止
+				 */
+				sil_andw_mem((uint32_t *)(hadc->base+TOFF_ADC_CR1), ADC_CR1_EOCIE);
+				sil_andw_mem((uint32_t *)(hadc->base+TOFF_ADC_CR1), ADC_CR1_OVRIE);
+			}
+			else{
+				if (hadc->NumCurrentConversionRank != 0){
+					hadc->NumCurrentConversionRank--;
+				}
+
+				/*
+				 *  RANK終了判定
+				 */
+				if(hadc->NumCurrentConversionRank == 0){
+					/*
+					 *  転送とエラー割込みを停止
+					 */
+					sil_andw_mem((uint32_t *)(hadc->base+TOFF_ADC_CR1), ADC_CR1_EOCIE);
+					sil_andw_mem((uint32_t *)(hadc->base+TOFF_ADC_CR1), ADC_CR1_OVRIE);
+				}
+			}
+		}
+
+		/*
+		 *  終了コールバック関数の読み出し
+		 */
+		if(hadc->xfercallback != NULL)
+			hadc->xfercallback(hadc);
+
+		/*
+		 * レギュラー転送の割込みクリア
+		 */
+		sil_wrw_mem((uint32_t *)(hadc->base+TOFF_ADC_SR), ~ADC_SR_EOC);
+	}
+
+	/*
+	 *  インジェクテェットチャネルの終了判定
+	 */
+	sr = sil_rew_mem((uint32_t *)(hadc->base+TOFF_ADC_SR));
+	if((sr & ADC_SR_JEOC) != 0 && (cr1 & ADC_CR1_JEOCIE) != 0){
+		if((cr2 & ADC_CR2_CONT) == 0)		/* ステータスの変更 */
+			hadc->status = ADC_STATUS_EOC;
+		else
+			hadc->status = ADC_STATUS_BUSY_EOC;
+
+		if(((hadc->Init.ContinuousConvMode == ADC_CONTINUOUS_DISABLE) || (cr1 & ADC_CR1_JAUTO) == 0) && (cr2 & ADC_CR2_JEXTEN) == 0){
+			/*
+			 *  インジェクテェットチャネル転送を停止
+			 */
+			sil_andw_mem((uint32_t *)(hadc->base+TOFF_ADC_CR1), ADC_CR1_JEOCIE);
+		}
+
+		/*
+		 *  インジェクテェットチャネル割込みクリア
+		 */
+		sil_wrw_mem((uint32_t *)(hadc->base+TOFF_ADC_SR), ~ADC_SR_JEOC);
+	}
+
+	/*
+	 *  アナログウォッチドック判定
+	 */
+	sr = sil_rew_mem((uint32_t *)(hadc->base+TOFF_ADC_SR));
+	if((sr & ADC_SR_AWD) != 0 && (cr1 & ADC_CR1_AWDIE) != 0){
+		/*
+		 *  ウォッチドック発生状態に変更
+		 */
+		hadc->status = ADC_STATUS_AWD;
+
+		/*
+		 *  ウォッチドック割込みクリア
+		 */
+		sil_wrw_mem((uint32_t *)(hadc->base+TOFF_ADC_SR), ~ADC_SR_AWD);
+
+		/*
+		 *  ウィンドウ領域アウトのコールバック関数読み出し
+		 */
+		if(hadc->outofwincallback != NULL)
+			hadc->outofwincallback(hadc);
+	}
+
+	/*
+	 *  オーバーランエラー判定
+	 */
+	sr = sil_rew_mem((uint32_t *)(hadc->base+TOFF_ADC_SR));
+	if((sr & ADC_SR_OVR) != 0 && (cr1 & ADC_CR1_OVRIE) != 0){
+		/*
+		 *  オーバーラン発生状態に変更
+		 */
+		hadc->status = ADC_STATUS_READY;
+		hadc->ErrorCode |= ADC_ERROR_OVR;
+
+		/*
+		 *  オーバーラン割込みクリア
+		 */
+		sil_wrw_mem((uint32_t *)(hadc->base+TOFF_ADC_SR), ~ADC_SR_OVR);
+
+		/*
+		 *  エラーコールバック関数を読み出し
+		 */
+		if(hadc->errorcallback != NULL)
+			hadc->errorcallback(hadc);
+	}
+}
+
+/*
+ *  ADC割込みハンドラ
+ */
+void
+adc_int_handler(void)
+{
+	uint32_t i;
+	ADC_Handle_t* hadc = &AdcHandle[0];
+
+	for(i = 0 ; i < NUM_ADCPORT ; i++, hadc++){
+		if(hadc->status > ADC_STATUS_READY)
+			adc_handler(hadc);
+	}
+}
+
+
+/*
+ *  レギュラーレジスタの取り出し
+ *  parameter1  hadc: ADCハンドラへのポインタ
+ *  return レギュラーレジスタ値
+ */
+uint32_t
+adc_getvalue(ADC_Handle_t* hadc)
+{
+	return sil_rew_mem((uint32_t *)(hadc->base+TOFF_ADC_DR));
+}
+
+/*
+ *  ADCチャネル設定
+ *  parameter1  hadc: ADCハンドラへのポインタ
+ *  parameter2  sConfig: チャネル設定構造体へのポインタ
+ *  return ERコード
+ */
+ER
+adc_setupchannel(ADC_Handle_t* hadc, ADC_ChannelConf_t* sConfig)
+{
+	GPIO_Init_t GPIO_InitStruct;
+	uint32_t shift, clkpin;
+
+	if(hadc == NULL || sConfig == NULL)
+		return E_PAR;
+
+	clkpin = (sConfig->GpioBase - TADR_GPIOA_BASE) / 0x400;
+	if(clkpin >= 12 || sConfig->GpioPin >= 16)
+		return E_PAR;
+
+	/*
+	 *  チャネル有効設定
+	 */
+	sil_orw_mem((uint32_t *)(TADR_RCC_BASE+TOFF_RCC_AHB1ENR), 1<<clkpin);
+	sil_rew_mem((uint32_t *)(TADR_RCC_BASE+TOFF_RCC_AHB1ENR));
+
+	GPIO_InitStruct.mode = GPIO_MODE_ANALOG;
+	GPIO_InitStruct.pull = GPIO_NOPULL;
+	gpio_setup(sConfig->GpioBase, &GPIO_InitStruct, sConfig->GpioPin);
+
+	/*
+	 *  サンプリング時間設定
+	 */
+	if (sConfig->Channel > ADC_CHANNEL_9){	/* チャネル10から18 */
+		shift = 3 * (sConfig->Channel - 10);
+		sil_modw_mem((uint32_t *)(hadc->base+TOFF_ADC_SMPR1), (ADC_SMPR1_SMP10 << shift), (sConfig->SamplingTime << shift));
+	}
+	else{ 	/* チャネル0から9 */
+		shift = 3 * sConfig->Channel;
+		sil_modw_mem((uint32_t *)(hadc->base+TOFF_ADC_SMPR2), (ADC_SMPR2_SMP0 << shift), (sConfig->SamplingTime << shift));
+	}
+
+	/*
+	 *  ランク設定
+	 */
+	if (sConfig->Rank < 7){	/* ランク1から6 */
+		shift = 5 * (sConfig->Rank - 1);
+		sil_modw_mem((uint32_t *)(hadc->base+TOFF_ADC_SQR3), (ADC_SQR3_SQ1 << shift), (sConfig->Channel << shift));
+	}
+	else if (sConfig->Rank < 13){	/* ランク7から12 */
+		shift = 5 * (sConfig->Rank - 7);
+		sil_modw_mem((uint32_t *)(hadc->base+TOFF_ADC_SQR2), (ADC_SQR2_SQ7 << shift), (sConfig->Channel << shift));
+	}
+	else{	/* ランク13から16 */
+		shift = 5 * (sConfig->Rank - 13);
+		sil_modw_mem((uint32_t *)(hadc->base+TOFF_ADC_SQR1), (ADC_SQR1_SQ13 << shift), (sConfig->Channel << shift));
+	}
+
+	/*
+	 *  電圧管理用チャネル設定
+	 */
+	if ((hadc->base == TADR_ADC1_BASE) && (sConfig->Channel == ADC_CHANNEL_VBAT)){
+		sil_orw_mem((uint32_t *)(TADR_ADC_BASE+TOFF_ADC_CCR), ADC_CCR_VBATE);
+	}
+
+	/*
+	 *  温度センサー専用チャネル設定
+	 */
+	if ((hadc->base == TADR_ADC1_BASE) && ((sConfig->Channel == ADC_CHANNEL_TEMPSENSOR) || (sConfig->Channel == ADC_CHANNEL_VREFINT))){
+		sil_orw_mem((uint32_t *)(TADR_ADC_BASE+TOFF_ADC_CCR), ADC_CCR_TSVREFE);
+		if((sConfig->Channel == ADC_CHANNEL_TEMPSENSOR)){
+			sil_dly_nse(ADC_TEMPSENSOR_DELAY_US*1000);
+		}
+	}
+	return E_OK;
+}
+
+/*
+ *  ADCアナログウォッチドック設定
+ *  parameter1  hadc: ADCハンドラへのポインタ
+ *  parameter2  AnalogWDGConfig: アナログウォッチドック設定構造体へのポインタ
+ *  return ERコード
+ */
+ER
+adc_setupwatchdog(ADC_Handle_t* hadc, ADC_AnalogWDGConf_t* AnalogWDGConfig)
+{
+	if(hadc == NULL || AnalogWDGConfig == NULL)
+		return E_PAR;
+
+	/*
+	 *  割込み設定
+	 */
+	sil_modw_mem((uint32_t *)(hadc->base+TOFF_ADC_CR1), ADC_CR1_AWDIE, AnalogWDGConfig->ITMode);
+
+	/*
+	 *  モード設定
+	 */
+	sil_andw_mem((uint32_t *)(hadc->base+TOFF_ADC_CR1), (ADC_CR1_AWDSGL | ADC_CR1_JAWDEN | ADC_CR1_AWDEN));
+
+	/* Set the analog watchdog enable mode */
+	sil_orw_mem((uint32_t *)(hadc->base+TOFF_ADC_CR1), AnalogWDGConfig->WatchdogMode);
+	sil_wrw_mem((uint32_t *)(hadc->base+TOFF_ADC_HTR), AnalogWDGConfig->HighThreshold);
+  
+	/*
+	 *  HIGH/LOWのスレッシュホールド設定
+	 */
+	sil_wrw_mem((uint32_t *)(hadc->base+TOFF_ADC_LTR), AnalogWDGConfig->LowThreshold);
+	sil_andw_mem((uint32_t *)(hadc->base+TOFF_ADC_CR1), ADC_CR1_AWDCH);
+
+	/*
+	 *  対応チャネル設定
+	 */
+    sil_orw_mem((uint32_t *)(hadc->base+TOFF_ADC_CR1), AnalogWDGConfig->Channel);
+	return E_OK;
+}
+
+
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/pdic/stm32f7xx/adc.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/pdic/stm32f7xx/adc.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/pdic/stm32f7xx/adc.h	(revision 457)
@@ -0,0 +1,313 @@
+/*
+ *  TOPPERS/ASP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Advanced Standard Profile Kernel
+ * 
+ *  Copyright (C) 2008-2011 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ *  Copyright (C) 2015-2016 by TOPPERS PROJECT Educational Working Group.
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+/*
+ * 
+ *  STM32F4xx ADCデバイスドライバの外部宣言
+ *
+ */
+
+#ifndef _ADC_H_
+#define _ADC_H_
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/*
+ *  ADCポート定義
+ */
+#define ADC1_PORTID             1
+#define ADC2_PORTID             2
+#define ADC3_PORTID             3
+#define NUM_ADCPORT             3
+
+/*
+ *  ADCクロックプリスケーラ定義(ClockPrescaler)
+ */ 
+#define ADC_CLOCK_SYNC_PCLK_DIV2        0x00000000
+#define ADC_CLOCK_SYNC_PCLK_DIV4        ADC_CCR_ADCPRE_0
+#define ADC_CLOCK_SYNC_PCLK_DIV6        ADC_CCR_ADCPRE_1
+#define ADC_CLOCK_SYNC_PCLK_DIV8        ADC_CCR_ADCPRE
+
+/*
+ *  ADCリゾリューション定義(Resolution)
+ */
+#define ADC_RESOLUTION_12B              0x00000000
+#define ADC_RESOLUTION_10B              ADC_CR1_RES_0
+#define ADC_RESOLUTION_8B               ADC_CR1_RES_1
+#define ADC_RESOLUTION_6B               ADC_CR1_RES
+
+/*
+ *  ADCデータアライン定義(DataAlign)
+ */ 
+#define ADC_DATAALIGN_RIGHT             0x00000000
+#define ADC_DATAALIGN_LEFT              ADC_CR2_ALIGN
+
+
+/*
+ *  ADCスキャンコンバージョンモード(ScanConvMode)
+ */
+#define ADC_SCANMODE_DISABLE            0x00000000
+#define ADC_SCANMODE_ENABLE             ADC_CR1_SCAN
+
+/*
+ *  ADC EOCシーケンス設定(EOCSelection)
+ */
+#define ADC_EOC_SEQ_DISABLE             0x00000000
+#define ADC_EOC_SEQ_ENABLE              ADC_CR2_EOCS
+
+/*
+ *  ADC継続モード設定(ContinuousConvMode)
+ */
+#define ADC_CONTINUOUS_DISABLE          0x00000000
+#define ADC_CONTINUOUS_ENABLE           ADC_CR2_CONT
+
+/*
+ *  ADC DMA設定定義(DMAContinuousRequests)
+ */
+#define ADC_DMACONTINUOUS_DISABLE       0x00000000
+#define ADC_DMANONECIRCULAR             0x80000000
+#define ADC_DMACONTINUOUS_ENABLE        ADC_CR2_DDS
+#define ADC_DMACONTINUOUS_ENABLE2       (ADC_CR2_DDS | ADC_DMANONECIRCULAR)
+
+/*
+ *  ADC 非継続モード設定(DiscontinuousConvMode)
+ */
+#define ADC_DISCONTINUOUS_DISABLE       0x00000000
+#define ADC_DISCONTINUOUS_ENABLE        ADC_CR1_DISCEN
+
+/*
+ *  ADC外部トリガソース設定(ExternalTrigConv)
+ */
+#define ADC_EXTERNALTRIGCONV_T1_CC1     0x00000000
+#define ADC_EXTERNALTRIGCONV_T1_CC2     ADC_CR2_EXTSEL_0
+#define ADC_EXTERNALTRIGCONV_T1_CC3     ADC_CR2_EXTSEL_1
+#define ADC_EXTERNALTRIGCONV_T2_CC2     (ADC_CR2_EXTSEL_1 | ADC_CR2_EXTSEL_0)
+#define ADC_EXTERNALTRIGCONV_T2_CC3     ADC_CR2_EXTSEL_2
+#define ADC_EXTERNALTRIGCONV_T2_CC4     (ADC_CR2_EXTSEL_2 | ADC_CR2_EXTSEL_0)
+#define ADC_EXTERNALTRIGCONV_T2_TRGO    (ADC_CR2_EXTSEL_2 | ADC_CR2_EXTSEL_1)
+#define ADC_EXTERNALTRIGCONV_T3_CC1     (ADC_CR2_EXTSEL_2 | ADC_CR2_EXTSEL_1 | ADC_CR2_EXTSEL_0)
+#define ADC_EXTERNALTRIGCONV_T3_TRGO    ADC_CR2_EXTSEL_3
+#define ADC_EXTERNALTRIGCONV_T4_CC4     (ADC_CR2_EXTSEL_3 | ADC_CR2_EXTSEL_0)
+#define ADC_EXTERNALTRIGCONV_T5_CC1     (ADC_CR2_EXTSEL_3 | ADC_CR2_EXTSEL_1)
+#define ADC_EXTERNALTRIGCONV_T5_CC2     (ADC_CR2_EXTSEL_3 | ADC_CR2_EXTSEL_1 | ADC_CR2_EXTSEL_0)
+#define ADC_EXTERNALTRIGCONV_T5_CC3     (ADC_CR2_EXTSEL_3 | ADC_CR2_EXTSEL_2)
+#define ADC_EXTERNALTRIGCONV_T8_CC1     (ADC_CR2_EXTSEL_3 | ADC_CR2_EXTSEL_2 | ADC_CR2_EXTSEL_0)
+#define ADC_EXTERNALTRIGCONV_T8_TRGO    (ADC_CR2_EXTSEL_3 | ADC_CR2_EXTSEL_2 | ADC_CR2_EXTSEL_1)
+#define ADC_EXTERNALTRIGCONV_Ext_IT11   ADC_CR2_EXTSEL
+#define ADC_SOFTWARE_START              (ADC_CR2_EXTSEL + 1)
+
+/*
+ *  ADC外部トリガエッジ設定()
+ */
+#define ADC_EXTERNALTRIGCONVEDGE_NONE           0x00000000
+#define ADC_EXTERNALTRIGCONVEDGE_RISING         ADC_CR2_EXTEN_0
+#define ADC_EXTERNALTRIGCONVEDGE_FALLING        ADC_CR2_EXTEN_1
+#define ADC_EXTERNALTRIGCONVEDGE_RISINGFALLING  ADC_CR2_EXTEN
+
+
+/*
+ *  ADCチャネル定義
+ */
+#define ADC_CHANNEL_0                   0x00000000
+#define ADC_CHANNEL_1                   ADC_CR1_AWDCH_0
+#define ADC_CHANNEL_2                   ADC_CR1_AWDCH_1
+#define ADC_CHANNEL_3                   (ADC_CR1_AWDCH_1 | ADC_CR1_AWDCH_0)
+#define ADC_CHANNEL_4                   ADC_CR1_AWDCH_2
+#define ADC_CHANNEL_5                   (ADC_CR1_AWDCH_2 | ADC_CR1_AWDCH_0)
+#define ADC_CHANNEL_6                   (ADC_CR1_AWDCH_2 | ADC_CR1_AWDCH_1)
+#define ADC_CHANNEL_7                   (ADC_CR1_AWDCH_2 | ADC_CR1_AWDCH_1 | ADC_CR1_AWDCH_0)
+#define ADC_CHANNEL_8                   ADC_CR1_AWDCH_3
+#define ADC_CHANNEL_9                   (ADC_CR1_AWDCH_3 | ADC_CR1_AWDCH_0)
+#define ADC_CHANNEL_10                  (ADC_CR1_AWDCH_3 | ADC_CR1_AWDCH_1)
+#define ADC_CHANNEL_11                  (ADC_CR1_AWDCH_3 | ADC_CR1_AWDCH_1 | ADC_CR1_AWDCH_0)
+#define ADC_CHANNEL_12                  (ADC_CR1_AWDCH_3 | ADC_CR1_AWDCH_2)
+#define ADC_CHANNEL_13                  (ADC_CR1_AWDCH_3 | ADC_CR1_AWDCH_2 | ADC_CR1_AWDCH_0)
+#define ADC_CHANNEL_14                  (ADC_CR1_AWDCH_3 | ADC_CR1_AWDCH_2 | ADC_CR1_AWDCH_1)
+#define ADC_CHANNEL_15                  (ADC_CR1_AWDCH_3 | ADC_CR1_AWDCH_2 | ADC_CR1_AWDCH_1 | ADC_CR1_AWDCH_0)
+#define ADC_CHANNEL_16                  ADC_CR1_AWDCH_4
+#define ADC_CHANNEL_17                  (ADC_CR1_AWDCH_4 | ADC_CR1_AWDCH_0)
+#define ADC_CHANNEL_18                  (ADC_CR1_AWDCH_4 | ADC_CR1_AWDCH_1)
+
+#define ADC_CHANNEL_VREFINT             ADC_CHANNEL_17
+#define ADC_CHANNEL_VBAT                ADC_CHANNEL_18
+
+/*
+ *  ADCサンプリング時間設定
+ */
+#define ADC_SAMPLETIME_3CYCLES          0x00000000
+#define ADC_SAMPLETIME_15CYCLES         ADC_SMPR1_SMP10_0
+#define ADC_SAMPLETIME_28CYCLES         ADC_SMPR1_SMP10_1
+#define ADC_SAMPLETIME_56CYCLES         (ADC_SMPR1_SMP10_1 | ADC_SMPR1_SMP10_0)
+#define ADC_SAMPLETIME_84CYCLES         ADC_SMPR1_SMP10_2
+#define ADC_SAMPLETIME_112CYCLES        (ADC_SMPR1_SMP10_2 | ADC_SMPR1_SMP10_0)
+#define ADC_SAMPLETIME_144CYCLES        (ADC_SMPR1_SMP10_2 | ADC_SMPR1_SMP10_1)
+#define ADC_SAMPLETIME_480CYCLES        ADC_SMPR1_SMP10
+
+
+/*
+ *  ADCアナログウォッチドックモード設定
+ */
+#define ADC_ANALOGWATCHDOG_NONE               0x00000000
+#define ADC_ANALOGWATCHDOG_SINGLE_REG         (ADC_CR1_AWDSGL | ADC_CR1_AWDEN)
+#define ADC_ANALOGWATCHDOG_SINGLE_INJEC       (ADC_CR1_AWDSGL | ADC_CR1_JAWDEN)
+#define ADC_ANALOGWATCHDOG_SINGLE_REGINJEC    (ADC_CR1_AWDSGL | ADC_CR1_AWDEN | ADC_CR1_JAWDEN)
+#define ADC_ANALOGWATCHDOG_ALL_REG            ADC_CR1_AWDEN
+#define ADC_ANALOGWATCHDOG_ALL_INJEC          ADC_CR1_JAWDEN
+#define ADC_ANALOGWATCHDOG_ALL_REGINJEC       (ADC_CR1_AWDEN | ADC_CR1_JAWDEN)
+
+/*
+ *  ADCアナログウォッチドック割込みモード設定
+ */
+#define ADC_ANALOGWATCHDOG_ITMODE_DISABLE     0x00000000
+#define ADC_ANALOGWATCHDOG_ITMODE_ENABLE      ADC_CR1_AWDIE
+
+/*
+ *  ADCハードウェア設定構造体
+ */
+typedef struct _ADC_PortControlBlock{
+	uint32_t              base;
+	uint32_t              adcclockbase;
+	uint32_t              adcclockbit;
+	uint32_t              dmaclockbase;
+	uint32_t              dmaclockbit;
+	uint32_t              dmarxbase;
+	uint32_t              dmarxchannel;
+} ADC_PortControlBlock;
+
+/*
+ *  ADCの初期化構造体
+ */
+typedef struct
+{
+	uint32_t              ClockPrescaler;				/* ADCクロックプリスケーラ値(各ADCにて共通値) */
+	uint32_t              Resolution;					/* ADCのリゾリューション */
+	uint32_t              DataAlign;					/* ADC結果データアライン設定 */
+	uint32_t              ScanConvMode;					/* ADCスキャンコンバージョンモード */
+	uint32_t              EOCSelection;					/* ADC EOC設定 */
+	uint32_t              ContinuousConvMode;			/* ADC継続モード */
+	uint32_t              DMAContinuousRequests;		/* ADC-DMAモード */
+	uint32_t              NumConversion;				/* ADCコンバージョン数 */
+	uint32_t              DiscontinuousConvMode;		/* ADC非継続モード */
+	uint32_t              NumDiscConversion;			/* ADC非継続変換数 */
+	uint32_t              ExternalTrigConv;				/* ADC外部トリガ設定 */
+	uint32_t              ExternalTrigConvEdge;			/* ADC外部トリガエッジ設定 */
+}ADC_Init_t;
+
+/*
+ *  ADCハンドラ構造体
+ */ 
+typedef struct __ADC_Handle_t ADC_Handle_t;
+struct __ADC_Handle_t
+{
+	uint32_t              base;							/* ADCベースアドレス */
+	ADC_Init_t            Init;							/* ADC初期化データ */
+	volatile uint32_t     NumCurrentConversionRank;		/* ADC現在のコンバージョンランク値 */
+	DMA_Handle_t          *hdmarx;						/* ADC用DMAハンドラへのポインタ */
+	void                  (*xfercallback)(ADC_Handle_t * hadc);		/* ADC 転送完了コールバック */
+	void                  (*xferhalfcallback)(ADC_Handle_t * hadc);	/* ADC 半分転送コールバック */
+	void                  (*outofwincallback)(ADC_Handle_t * hadc);	/* ADC アナログウォッチドックコールバック */
+	void                  (*errorcallback)(ADC_Handle_t * hadc);	/* ADC エラーコールバック */
+	volatile uint32_t     status;						/* ADCステータス */
+	volatile uint32_t     ErrorCode;					/* ADCエラー値 */
+};
+
+/*
+ *  チャンネル設定構造体
+ */
+typedef struct
+{
+	uint32_t              Channel;						/* ADCチャンネル番号 */
+	uint32_t              Rank;							/* ADCランク番号(1-16) */
+	uint32_t              SamplingTime;					/* ADCサンプリング時間 */
+	uint32_t              GpioBase;						/* ADC-GPIOベースアドレス */
+	uint32_t              GpioPin;						/* ADC-GPIOピン番号 */
+}ADC_ChannelConf_t;
+
+/*
+ *  ADCアナログウォッチドック設定構造体
+ */
+typedef struct
+{
+	uint32_t              WatchdogMode;					/* ADCアナログウォッチドッグモード */
+	uint32_t              HighThreshold;				/* ADCスレッシュホールド上限値 */
+	uint32_t              LowThreshold;					/* ADCスレッシュホールド下限値 */
+	uint32_t              Channel;						/* ADC対応チャネル番号 */
+	uint32_t              ITMode;						/* ADCアナログウォッチドック割込み設定 */
+}ADC_AnalogWDGConf_t;
+
+/*
+ *  ADCのステータス定義
+ */
+#define ADC_STATUS_RESET        0x00    /* ADC 未使用状態 */
+#define ADC_STATUS_READY        0x01    /* ADC レディ状態 */
+#define ADC_STATUS_BUSY         0x02    /* ADC ビジィ状態 */
+#define ADC_STATUS_EOC          0x10    /* ADC 終了状態 */
+#define ADC_STATUS_BUSY_EOC     0x12    /* ADC ビジィ終了発生状態 */ 
+#define ADC_STATUS_AWD          0x20    /* ADC アナログウォッチドック発生状態 */
+
+/*
+ *  ADCエラー定義
+ */
+#define ADC_ERROR_NONE          0x00	/* No error             */
+#define ADC_ERROR_OVR           0x01	/* OVR error            */
+#define ADC_ERROR_DMA           0x02	/* DMA transfer error   */
+
+
+extern ADC_Handle_t *adc_init(ID portid, ADC_Init_t *pini);
+extern ER adc_deinit(ADC_Handle_t *hadc);
+extern ER adc_start_int(ADC_Handle_t* hadc);
+extern ER adc_end_int(ADC_Handle_t* hadc);
+extern ER adc_start_dma(ADC_Handle_t* hadc, uint32_t* pdata, uint32_t length);
+extern ER adc_end_dma(ADC_Handle_t* hadc);
+extern ER adc_setupchannel(ADC_Handle_t* hadc, ADC_ChannelConf_t* sConfig);
+extern ER adc_setupwatchdog(ADC_Handle_t* hadc, ADC_AnalogWDGConf_t* AnalogWDGConfig);
+extern uint32_t adc_getvalue(ADC_Handle_t* hadc);
+
+extern void adc_handler(ADC_Handle_t* hadc);
+extern void adc_int_handler(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif	/* _ADC_H_ */
+
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/pdic/stm32f7xx/clock.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/pdic/stm32f7xx/clock.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/pdic/stm32f7xx/clock.c	(revision 457)
@@ -0,0 +1,297 @@
+/*
+ *  TOPPERS/ASP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Advanced Standard Profile Kernel
+ *
+ *  Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
+ *                              Toyohashi Univ. of Technology, JAPAN
+ *  Copyright (C) 2004-2010 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ *  Copyright (C) 2012-2015 by GT Development Center RICOH COMPANY,LTD. JAPAN
+ *  Copyright (C) 2015-2019 by TOPPERS PROJECT Educational Working Group.
+ * 
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+#include <kernel.h>
+#include <t_syslog.h>
+#include <t_stdlib.h>
+#include <stdio.h>
+#define _SYS__STDINT_H
+#include <time.h>
+#include "kernel_cfg.h"
+#include "device.h"
+#include "monitor.h"
+
+#define RTC_CLOCK   32768	/* LSE_VALUE */
+
+static int_t date_func(int argc, char **argv);
+static int_t time_func(int argc, char **argv);
+static int_t wakeup_func(int argc, char **argv);
+static int_t clock_func(int argc, char **argv);
+
+/*
+ *  ＲＴＣコマンドテーブル
+ */
+static const COMMAND_INFO rtc_command_info[] = {
+	{"DATE",	date_func    },	/* 日にち設定 */
+	{"TIME",	time_func    },	/* 時間設定 */
+	{"WAKEUP",	wakeup_func  },	/* WAKEUP設定 */
+	{"CLOCK",	clock_func   }	/* 時計 */
+};
+
+#define NUM_RTC_CMD     (sizeof(rtc_command_info)/sizeof(COMMAND_INFO))
+
+static const char rtc_name[] = "RTC";
+static const char rtc_help[] =
+"  Rtc     DATE  (year #) (month #) (day #)\n"
+"          TIME  (hour #) (min   #) (sec #)\n"
+#ifdef USE_RTC_WAKEUP_CMD
+"          WAKEUP time(ms)\n"
+#endif
+"          CLOCK DATE:TIME\n";
+
+static const char monthday[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
+
+static COMMAND_LINK rtc_command_link = {
+	NULL,
+	NUM_RTC_CMD,
+	rtc_name,
+	NULL,
+	rtc_help,
+	&rtc_command_info[0]
+};
+
+static RTC_Wakeup_t rtc_wup;
+
+/*
+ *  ローカルatox
+ */
+static int atoix(char *s)
+{
+	int c, val = 0;
+
+	while((c = *s++) != 0){
+		if(c >= '0' && c <= '9')
+			val = val * 10 + (c - '0');
+	}
+	return val;
+}
+
+#ifdef USE_RTC_WAKEUP_CMD
+/*
+ *  WAKUP EVENT
+ */
+static void wakeup_event(void)
+{
+	syslog_0(LOG_NOTICE, "rtc wakeup event !");
+}
+#endif
+#ifndef NOT_USE_TBP_MKTIME_GMTIME
+/*
+ *  mktime関数
+ */
+time_t mktime(struct tm *ptm)
+{
+	int day = ptm->tm_year *365;
+	int yday, i; 
+
+	day += (ptm->tm_year+2) / 4;
+	for(i = 1, yday = 0 ; i < ptm->tm_mon ; i++)
+		yday += monthday[i-1];
+	if(ptm->tm_mon > 2 && ((ptm->tm_year+2) % 4) == 0)
+		yday++;
+	yday += ptm->tm_mday - 1;
+	day  += yday;
+	ptm->tm_wday = (day+4) % 7;
+	ptm->tm_yday = yday+1;
+	syslog_3(LOG_INFO, "yday[%d] wday[%d] day[%d]", yday+1, ptm->tm_wday, ptm->tm_yday);
+	return day * (24*60*60) + ptm->tm_hour * 60*60 + ptm->tm_min * 60 + ptm->tm_sec;
+}
+
+/*
+ * gmtime_r関数
+ */
+struct tm *gmtime_r(const time_t *pt, struct tm *ptm)
+{
+	int day = *pt / (24*60*60);
+	int time, i, yday, mday;
+
+	time = *pt - day * 24 * 60 * 60;
+	ptm->tm_wday = (day+4) % 7;
+	for(i = 365, ptm->tm_year = 0 ; i < day ; i += 365){
+		if(((ptm->tm_year+2) % 4) == 0)
+			i++;
+		ptm->tm_year++;
+	}
+
+	ptm->tm_yday = yday = day - i + 365 + 1;
+	for(ptm->tm_mon = 1 ; ptm->tm_mon <= 12 && yday > 0 ; ptm->tm_mon++){
+		mday = monthday[ptm->tm_mon-1];
+		if(ptm->tm_mon == 2 && ((ptm->tm_year+2) % 4) == 0)
+			mday++;
+		if(yday < mday){
+			ptm->tm_mday = yday;
+			break;
+		}
+		yday -= mday;
+	}
+	ptm->tm_hour = time / (60*60);
+	time -= ptm->tm_hour * 60 * 60;
+	ptm->tm_min  = time / 60;
+	ptm->tm_sec = time % 60;
+	return ptm;
+}
+#endif
+int
+_gettimeofday (struct timeval * tp, void * tzvp)
+{
+	struct tm timedate;
+	if (!tp) return 0;
+	rtc_get_time((struct tm2 *)&timedate);
+	uint64_t time = (uint64_t)mktime(&timedate) * (uint64_t)1000000;
+	tp->tv_sec = time / 1000000;
+	tp->tv_usec = time - (tp->tv_sec * 1000000);
+	return 0;
+}
+
+/*
+ *  RTCコマンド設定関数
+ */
+void rtc_info_init(intptr_t exinf)
+{
+#ifdef USE_RTC_WAKEUP_CMD
+	rtc_wakeup_init(&rtc_wup, wakeup_event);
+#endif
+	setup_command(&rtc_command_link);
+}
+
+/*
+ *  日付設定コマンド関数
+ */
+static int_t date_func(int argc, char **argv)
+{
+	struct tm timedate;
+	int arg1 = 2016;
+
+	ER ret = rtc_get_time((struct tm2 *)&timedate);
+	if (ret != E_OK){
+		printf("rtc_get_time %s\n", itron_strerror(ret));
+	}
+	if(argc > 1)
+		arg1 = atoix(argv[1]);
+	if(argc > 2)
+		timedate.tm_mon = atoix(argv[2]) - 1;
+	else
+		timedate.tm_mon = 0;
+	if(argc > 3)
+		timedate.tm_mday = atoix(argv[3]);
+	else
+		timedate.tm_mday = 1;
+	printf("%04d/%02d/%02d\n", arg1, timedate.tm_mon + 1, timedate.tm_mday);
+	timedate.tm_year = arg1 - 1900;
+	timedate.tm_isdst = 0;
+	mktime((struct tm *)&timedate);
+	ret = rtc_set_time((struct tm2 *)&timedate);
+	if (ret != E_OK){
+		printf("rtc_set_time %s\n", itron_strerror(ret));
+	}
+	return 0;
+}
+
+/*
+ *  時間設定コマンド関数
+ */
+static int_t time_func(int argc, char **argv)
+{
+	struct tm2 timedate;
+
+	ER ret = rtc_get_time(&timedate);
+	if (ret != E_OK){
+		printf("rtc_get_time %s\n", itron_strerror(ret));
+	}
+	if(argc > 1)
+		timedate.tm_hour = atoix(argv[1]);
+	else
+		timedate.tm_hour = 0;
+	if(argc > 2)
+		timedate.tm_min = atoix(argv[2]);
+	else
+		timedate.tm_min = 0;
+	if(argc > 3)
+		timedate.tm_sec = atoix(argv[3]);
+	else
+		timedate.tm_sec = 0;
+	printf("%02d:%02d:%02d\n", timedate.tm_hour, timedate.tm_min, timedate.tm_sec);
+	timedate.tm_isdst = 0;
+	mktime((struct tm *)&timedate);
+	ret = rtc_set_time(&timedate);
+	if (ret != E_OK){
+		printf("rtc_set_time %s\n", itron_strerror(ret));
+	}
+	return 0;
+}
+
+/*
+ *  WAKEUPイベント設定関数
+ */
+static int_t wakeup_func(int argc, char **argv)
+{
+	uint32_t count = 0;
+	if(argc > 1){
+		count = atoix(argv[1]);
+		count = (count * (RTC_CLOCK >> rtc_wup.wakeuptimerPrescaler)) / 1000;
+		if(count <= 0xFFFF)
+			rtc_setup_wakeuptime(count);
+		else
+			printf("wakeup renge error(%d) !", count);
+		return 0;
+	}
+	else
+		return 1;
+}
+
+/*
+ *  時刻取出しコマンド関数
+ */
+static int_t clock_func(int argc, char **argv)
+{
+	struct tm2 timedate;
+
+	ER ret = rtc_get_time(&timedate);
+	if (ret != E_OK){
+		printf("rtc_get_time %s\n", itron_strerror(ret));
+	}
+	mktime(&timedate);
+	printf("  %04d/%02d/%02d yday[%d]\n", timedate.tm_year+1900, timedate.tm_mon+1, timedate.tm_mday, timedate.tm_yday);
+	printf("    %02d:%02d:%02d wday[%d]\n", timedate.tm_hour, timedate.tm_min, timedate.tm_sec, timedate.tm_wday);
+	return 0;
+}
+
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/pdic/stm32f7xx/device.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/pdic/stm32f7xx/device.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/pdic/stm32f7xx/device.c	(revision 457)
@@ -0,0 +1,1965 @@
+/*
+ *  TOPPERS/ASP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Advanced Standard Profile Kernel
+ * 
+ *  Copyright (C) 2008-2011 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ *  Copyright (C) 2015-2018 by TOPPERS PROJECT Educational Working Group.
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+/*
+ * STM32F7xx用デバイスドライバ
+ */
+#include "kernel_impl.h"
+#include <t_syslog.h>
+#include <t_stdlib.h>
+#include <sil.h>
+#include <target_syssvc.h>
+#include "kernel_cfg.h"
+#include "device.h"
+
+
+/*
+ *  SIL関数のマクロ定義
+ */
+#define sil_orw_mem(a, b)		sil_wrw_mem((a), sil_rew_mem(a) | (b))
+#define sil_andw_mem(a, b)		sil_wrw_mem((a), sil_rew_mem(a) & ~(b))
+#define sil_modw_mem(a, b, c)	sil_wrw_mem((a), (sil_rew_mem(a) & (~b)) | (c))
+
+#define byte2bcd(value) ((((value)/10)<<4) | ((value) % 10))
+#define bcd2byte(value) ((((value)>>4) * 10) + ((value) & 0xF))
+
+/*
+ *  サービスコールのエラーのログ出力
+ */
+Inline void
+svc_perror(const char *file, int_t line, const char *expr, ER ercd)
+{
+	if (ercd < 0) {
+		t_perror(LOG_ERROR, file, line, expr, ercd);
+	}
+}
+
+#define	SVC_PERROR(expr)	svc_perror(__FILE__, __LINE__, #expr, (expr))
+
+uint_t dipsw_value;
+void (*exti_func[16])(void) = { 0 };
+
+
+/*
+ *  GPIOモードの内部定義
+ */
+#define GPIO_MODE               0x00000003
+#define EXTI_MODE               0x10000000
+#define GPIO_MODE_IT            0x00010000
+#define GPIO_MODE_EVT           0x00020000
+#define RISING_EDGE             0x00100000
+#define FALLING_EDGE            0x00200000
+#define GPIO_OUTPUT_TYPE        0x00000010
+
+static const uint32_t gpio_index[] = {
+	TADR_GPIOA_BASE,			/* index 0 */
+	TADR_GPIOB_BASE,			/* index 1 */
+	TADR_GPIOC_BASE,			/* index 2 */
+	TADR_GPIOD_BASE,			/* index 3 */
+	TADR_GPIOE_BASE,			/* index 4 */
+	TADR_GPIOF_BASE,			/* index 5 */
+	TADR_GPIOG_BASE,			/* index 6 */
+	TADR_GPIOH_BASE,			/* index 7 */
+	TADR_GPIOI_BASE,			/* index 8 */
+	TADR_GPIOJ_BASE,			/* index 9 */
+	TADR_GPIOK_BASE				/* index 10 */
+};
+
+#define NUM_OF_GPIOPORT (sizeof(gpio_index)/sizeof(uint32_t))
+
+/*
+ *  GPIOの初期設定関数
+ */
+void
+gpio_setup(uint32_t base, GPIO_Init_t *init, uint32_t pin)
+{
+	uint32_t iocurrent = 1<<pin;
+	uint32_t temp = 0x00;
+	uint32_t index;
+
+	for(index = 0 ; index < NUM_OF_GPIOPORT ; index++){
+		if(gpio_index[index] == base)
+			break;
+	}
+	if(index == NUM_OF_GPIOPORT)
+		return;
+
+	/*
+	 *  GPIOモード設定
+	 */
+	/* アルタネート・ファンクション・モード設定 */
+	temp = sil_rew_mem((uint32_t *)(base+TOFF_GPIO_AFR0+(pin>>3)*4));
+	temp &= ~((uint32_t)0xF << ((uint32_t)(pin & (uint32_t)0x07) * 4)) ;
+	if(init->mode == GPIO_MODE_AF)
+		temp |= ((uint32_t)(init->alternate) << (((uint32_t)pin & (uint32_t)0x07) * 4));
+	sil_wrw_mem((uint32_t *)(base+TOFF_GPIO_AFR0+(pin>>3)*4), temp);
+
+	/*  入出力モード設定 */
+	sil_modw_mem((uint32_t *)(base+TOFF_GPIO_MODER), (GPIO_MODER_MODER0 << (pin * 2)), ((init->mode & GPIO_MODE) << (pin * 2)));
+
+	/*  出力モード設定 */
+	if(init->mode == GPIO_MODE_OUTPUT || init->mode == GPIO_MODE_AF){
+		sil_modw_mem((uint32_t *)(base+TOFF_GPIO_OSPEEDR), (GPIO_OSPEEDER_OSPEEDR0 << (pin * 2)), (init->speed << (pin * 2)));
+		sil_modw_mem((uint32_t *)(base+TOFF_GPIO_OTYPER), (GPIO_OTYPER_OT_0 << pin), (init->otype << pin));
+	}
+
+	/*  プルアップ、プルダウン設定 */
+	sil_modw_mem((uint32_t *)(base+TOFF_GPIO_PUPDR), (GPIO_PUPDR_PUPDR0 << (pin * 2)), (init->pull << (pin * 2)));
+
+	/*
+	 *  EXTIモード設定
+	 */
+	if((init->mode & EXTI_MODE) == EXTI_MODE){
+		/*  SYSCFGクロック設定 */
+		sil_orw_mem((uint32_t *)(TADR_RCC_BASE+TOFF_RCC_APB2ENR), RCC_APB2ENR_SYSCFGEN);
+		temp = sil_rew_mem((uint32_t *)(TADR_RCC_BASE+TOFF_RCC_APB2ENR));
+
+		temp = sil_rew_mem((uint32_t *)(TADR_SYSCFG_BASE+TOFF_SYSCFG_EXTICR0+(pin & 0x0C)));
+		temp &= ~(0x0F << (4 * (pin & 0x03)));
+		temp |= (index << (4 * (pin & 0x03)));
+		sil_wrw_mem((uint32_t *)(TADR_SYSCFG_BASE+TOFF_SYSCFG_EXTICR0+(pin & 0x0C)), temp);
+
+		if((init->mode & GPIO_MODE_IT) == GPIO_MODE_IT)
+			sil_orw_mem((uint32_t *)(TADR_EXTI_BASE+TOFF_EXTI_IMR), iocurrent);
+		else
+			sil_andw_mem((uint32_t *)(TADR_EXTI_BASE+TOFF_EXTI_IMR), iocurrent);
+
+		if((init->mode & GPIO_MODE_EVT) == GPIO_MODE_EVT)
+			sil_orw_mem((uint32_t *)(TADR_EXTI_BASE+TOFF_EXTI_EMR), iocurrent);
+		else
+			sil_andw_mem((uint32_t *)(TADR_EXTI_BASE+TOFF_EXTI_EMR), iocurrent);
+
+		if((init->mode & RISING_EDGE) == RISING_EDGE)
+			sil_orw_mem((uint32_t *)(TADR_EXTI_BASE+TOFF_EXTI_RTSR), iocurrent);
+		else
+			sil_andw_mem((uint32_t *)(TADR_EXTI_BASE+TOFF_EXTI_RTSR), iocurrent);
+
+		if((init->mode & FALLING_EDGE) == FALLING_EDGE)
+			sil_orw_mem((uint32_t *)(TADR_EXTI_BASE+TOFF_EXTI_FTSR), iocurrent);
+		else
+			sil_andw_mem((uint32_t *)(TADR_EXTI_BASE+TOFF_EXTI_FTSR), iocurrent);
+	}
+}
+
+
+/*
+ *  アドレス指定Dキャッシュインバリデート関数
+ *  parameter1  addr    address (aligned to CACHE_LINE_SIZE(32)-byte boundary)
+ *  parameter2  dsize   size of memory block (in number of bytes)
+ */
+void
+invalidatedcache_by_addr(uint8_t *addr, int32_t dsize)
+{
+	int32_t  op_size = dsize + (CACHE_LINE_SIZE-1);
+	uint32_t op_addr = (((uint32_t)addr) & ~(CACHE_LINE_SIZE-1));
+
+	asm("dsb 0xF":::"memory");
+	while (op_size > 0) {
+		sil_wrw_mem((uint32_t *)(TADR_SCB_BASE+TOFF_SCB_DCIMVAC), op_addr);
+		op_addr += CACHE_LINE_SIZE;
+		op_size -= CACHE_LINE_SIZE;
+	}
+	asm("dsb 0xF":::"memory");
+	asm("isb 0xF":::"memory");
+}
+
+/*
+ *  アドレス指定Dキャッシュフラッシュ関数
+ *  parameter1  addr    address (aligned to CACHE_LINE_SIZE(32)-byte boundary)
+ *  parameter2  dsize   size of memory block (in number of bytes)
+ */
+void flushdcache_by_addr(uint8_t *addr, int32_t dsize)
+{
+	int32_t  op_size = dsize + (CACHE_LINE_SIZE-1);
+	uint32_t op_addr = (((uint32_t)addr) & ~(CACHE_LINE_SIZE-1));
+
+	asm("dsb 0xF":::"memory");
+	while (op_size > 0) {
+		sil_wrw_mem((uint32_t *)(TADR_SCB_BASE+TOFF_SCB_DCCMVAC), op_addr);
+		op_addr += CACHE_LINE_SIZE;
+		op_size -= CACHE_LINE_SIZE;
+	}
+	asm("dsb 0xF":::"memory");
+	asm("isb 0xF":::"memory");
+}
+
+/*
+ *  アドレス指定Dキャッシュフラッシュ&インバリデート関数
+ *  parameter1  addr    address (aligned to CACHE_LINE_SIZE(32)-byte boundary)
+ *  parameter2  dsize   size of memory block (in number of bytes)
+ */
+void flushinvalidatedcache_by_addr(uint8_t *addr, int32_t dsize)
+{
+	int32_t  op_size = dsize + (CACHE_LINE_SIZE-1);
+	uint32_t op_addr = (((uint32_t)addr) & ~(CACHE_LINE_SIZE-1));
+
+	asm("dsb 0xF":::"memory");
+	while (op_size > 0) {
+		sil_wrw_mem((uint32_t *)(TADR_SCB_BASE+TOFF_SCB_DCCIMVAC), op_addr);
+		op_addr += CACHE_LINE_SIZE;
+		op_size -= CACHE_LINE_SIZE;
+	}
+	asm("dsb 0xF":::"memory");
+	asm("isb 0xF":::"memory");
+}
+
+
+/*
+ *  DMACの設定関数
+ */
+
+#define NUM_STMDMA      16
+#define NUM_DMAINDEX    5
+#define INDEX_TC        0
+#define INDEX_HT        1
+#define INDEX_TE        2
+#define INDEX_FE        3
+#define INDEX_DME       4
+
+#define DMA_TRS_TIMEOUT 2000	/* 2秒 */
+
+static const uint32_t dma_base[NUM_STMDMA] = {
+	TADR_DMA1_STM0_BASE,
+	TADR_DMA1_STM1_BASE,
+	TADR_DMA1_STM2_BASE,
+	TADR_DMA1_STM3_BASE,
+	TADR_DMA1_STM4_BASE,
+	TADR_DMA1_STM5_BASE,
+	TADR_DMA1_STM6_BASE,
+	TADR_DMA1_STM7_BASE,
+	TADR_DMA2_STM0_BASE,
+	TADR_DMA2_STM1_BASE,
+	TADR_DMA2_STM2_BASE,
+	TADR_DMA2_STM3_BASE,
+	TADR_DMA2_STM4_BASE,
+	TADR_DMA2_STM5_BASE,
+	TADR_DMA2_STM6_BASE,
+	TADR_DMA2_STM7_BASE
+};
+
+static const uint32_t dma_flag[NUM_STMDMA][NUM_DMAINDEX] = {
+	{	0x00000020, 0x00000010, 0x00000008, 0x00800001, 0x00800004 },
+	{	0x00000800, 0x00000400, 0x00000200, 0x00000040, 0x00000100 },
+	{	0x00200000, 0x00100000, 0x00080000, 0x00010000, 0x00040000 },
+	{	0x08000000, 0x04000000, 0x02000000, 0x00400000, 0x01000000 },
+	{	0x00000020, 0x00000010, 0x00000008, 0x00800001, 0x00800004 },
+	{	0x00000800, 0x00000400, 0x00000200, 0x00000040, 0x00000100 },
+	{	0x00200000, 0x00100000, 0x00080000, 0x00010000, 0x00040000 },
+	{	0x08000000, 0x04000000, 0x02000000, 0x00400000, 0x01000000 },
+	{	0x00000020, 0x00000010, 0x00000008, 0x00800001, 0x00800004 },
+	{	0x00000800, 0x00000400, 0x00000200, 0x00000040, 0x00000100 },
+	{	0x00200000, 0x00100000, 0x00080000, 0x00010000, 0x00040000 },
+	{	0x08000000, 0x04000000, 0x02000000, 0x00400000, 0x01000000 },
+	{	0x00000020, 0x00000010, 0x00000008, 0x00800001, 0x00800004 },
+	{	0x00000800, 0x00000400, 0x00000200, 0x00000040, 0x00000100 },
+	{	0x00200000, 0x00100000, 0x00080000, 0x00010000, 0x00040000 },
+	{	0x08000000, 0x04000000, 0x02000000, 0x00400000, 0x01000000 }
+};
+
+static const uint32_t dma_faddr[NUM_STMDMA/4] = {
+	(TADR_DMA1_BASE+TOFF_DMAI_LISR),
+	(TADR_DMA1_BASE+TOFF_DMAI_HISR),
+	(TADR_DMA2_BASE+TOFF_DMAI_LISR),
+	(TADR_DMA2_BASE+TOFF_DMAI_HISR)
+};
+
+static DMA_Handle_t *pDmaHandler[NUM_STMDMA];
+
+
+/*
+ *  STREAM DMA初期化関数
+ *  parameter1  hdma: DMAハンドラへのポインタ
+ *  return ER値
+ */
+ER
+dma_init(DMA_Handle_t *hdma)
+{
+	uint32_t tmp = 0;
+	uint32_t i;
+
+	/* パラメータチェック */
+	if(hdma == NULL)
+		return E_PAR;
+
+	for(i = 0 ; i < NUM_STMDMA ; i++){
+		if(dma_base[i] == hdma->base)
+			break;
+	}
+	if(i == NUM_STMDMA)
+		return E_PAR;
+	hdma->sdid = i;
+	pDmaHandler[i] = hdma;
+
+	/* DMA-CRレジスタ取得 */
+	tmp = sil_rew_mem((uint32_t *)(hdma->base+TOFF_DMAS_CR));
+
+	/* DMAモードビットをテンポラリィにクリア */
+	tmp &= ((uint32_t)~(DMA_SxCR_CHSEL | DMA_SxCR_MBURST | DMA_SxCR_PBURST | \
+                      DMA_SxCR_PL    | DMA_SxCR_MSIZE  | DMA_SxCR_PSIZE  | \
+                      DMA_SxCR_MINC  | DMA_SxCR_PINC   | DMA_SxCR_CIRC   | \
+                      DMA_SxCR_DIR   | DMA_SxCR_CT     | DMA_SxCR_DBM));
+
+	/* DMAモードをテンポラリィに設定 */
+	tmp |=  hdma->Init.Channel           | hdma->Init.Direction        |
+          hdma->Init.PeriphInc           | hdma->Init.MemInc           |
+          hdma->Init.PeriphDataAlignment | hdma->Init.MemDataAlignment |
+          hdma->Init.Mode                | hdma->Init.Priority;
+
+	/* FIFOモードならバースト設定 */
+	if(hdma->Init.FIFOMode == DMA_FIFOMODE_ENABLE){
+		tmp |=  hdma->Init.MemBurst | hdma->Init.PeriphBurst;
+	}
+
+	/* DMAモード設定 */
+	sil_wrw_mem((uint32_t *)(hdma->base+TOFF_DMAS_CR), tmp);
+
+	/* DMA-FCRレジスタを取得 */
+	tmp = sil_rew_mem((uint32_t *)(hdma->base+TOFF_DMAS_FCR));
+
+	/* FIFOモードをテンポラリィにクリア */
+	tmp &= (uint32_t)~(DMA_SxFCR_DMDIS | DMA_SxFCR_FTH);
+
+	/* FIFOモードをテンポラリィに設定 */
+	tmp |= hdma->Init.FIFOMode;
+
+	/* FIFOモードならスレッシュホールドを設定 */
+	if(hdma->Init.FIFOMode == DMA_FIFOMODE_ENABLE){
+		tmp |= hdma->Init.FIFOThreshold;
+	}
+
+	/* DMA-FCRレジスタに設定 */
+	sil_wrw_mem((uint32_t *)(hdma->base+TOFF_DMAS_FCR), tmp);
+
+	/* エラー状態をクリア */
+	hdma->ErrorCode = DMA_ERROR_NONE;
+	return E_OK;
+}
+
+/*
+ *  STREAM DMA終了関数
+ *  parameter1  hdma: DMAハンドラへのポインタ
+ *  return ER値
+ */
+ER
+dma_deinit(DMA_Handle_t *hdma)
+{
+	int i;
+
+	/* パラメータチェック */
+	if(hdma == NULL)
+		return E_PAR;
+
+	for(i = 0 ; i < NUM_STMDMA ; i++){
+		if(dma_base[i] == hdma->base)
+			break;
+	}
+	if(i == NUM_STMDMA)
+		return E_PAR;
+	hdma->sdid = i;
+
+	/* DMAイネーブル */
+	sil_andw_mem((uint32_t *)(hdma->base+TOFF_DMAS_CR), DMA_SxCR_EN);
+	sil_wrw_mem((uint32_t *)(hdma->base+TOFF_DMAS_CR), 0);
+	sil_wrw_mem((uint32_t *)(hdma->base+TOFF_DMAS_NDTR), 0);
+	sil_wrw_mem((uint32_t *)(hdma->base+TOFF_DMAS_PAR), 0);
+	sil_wrw_mem((uint32_t *)(hdma->base+TOFF_DMAS_M0AR), 0);
+	sil_wrw_mem((uint32_t *)(hdma->base+TOFF_DMAS_M1AR), 0);
+	sil_wrw_mem((uint32_t *)(hdma->base+TOFF_DMAS_FCR), 0x00000021);
+
+	/* 各フラグをクリア */
+	for(i = 0 ; i < NUM_DMAINDEX ; i++){
+		sil_wrw_mem((uint32_t *)(dma_faddr[hdma->sdid/4]+8), dma_flag[hdma->sdid][i]);
+	}
+
+	/* エラー状態をクリア */
+	hdma->ErrorCode = DMA_ERROR_NONE;
+	return E_OK;
+}
+
+/*
+ *  STREAM DMA開始関数
+ *  parameter1  hdma:       DMAハンドラへのポインタ
+ *  parameter2  SrcAddress: ソースアドレス
+ *  parameter3  DstAddress: デスティネーションアドレス
+ *  parameter4  DataLength: 転送長
+ *  return ER値
+ */
+ER
+dma_start(DMA_Handle_t *hdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t DataLength)
+{
+	/* パラメータチェック */
+	if(hdma == NULL)
+		return E_PAR;
+
+	/* DMA停止 */
+	sil_andw_mem((uint32_t *)(hdma->base+TOFF_DMAS_CR), DMA_SxCR_EN);
+	sil_andw_mem((uint32_t *)(hdma->base+TOFF_DMAS_CR), DMA_SxCR_TCIE | DMA_SxCR_HTIE | DMA_SxCR_TEIE | DMA_SxCR_DMEIE);
+	sil_andw_mem((uint32_t *)(hdma->base+TOFF_DMAS_FCR), DMA_SxFCR_FEIE);
+	hdma->status = DMA_STATUS_BUSY;
+
+	/* DBMビットクリア */
+	sil_andw_mem((uint32_t *)(hdma->base+TOFF_DMAS_CR), DMA_SxCR_DBM);
+	/* データ長設定 */
+	sil_wrw_mem((uint32_t *)(hdma->base+TOFF_DMAS_NDTR), DataLength);
+
+	if((hdma->Init.Direction) == DMA_MEMORY_TO_PERIPH){
+		/* メモリからデバイス */
+		flushdcache_by_addr((uint8_t *)SrcAddress, DataLength*4);
+		sil_wrw_mem((uint32_t *)(hdma->base+TOFF_DMAS_PAR), DstAddress);
+		sil_wrw_mem((uint32_t *)(hdma->base+TOFF_DMAS_M0AR), SrcAddress);
+	}
+	else{	/* デバイスからメモリ */
+		flushinvalidatedcache_by_addr((uint8_t *)DstAddress, DataLength*4);
+		sil_wrw_mem((uint32_t *)(hdma->base+TOFF_DMAS_PAR), SrcAddress);
+		sil_wrw_mem((uint32_t *)(hdma->base+TOFF_DMAS_M0AR), DstAddress);
+	}
+
+	/* 割込みイネーブル */
+	sil_orw_mem((uint32_t *)(hdma->base+TOFF_DMAS_CR), DMA_SxCR_TCIE | DMA_SxCR_HTIE | DMA_SxCR_TEIE | DMA_SxCR_DMEIE);
+	sil_orw_mem((uint32_t *)(hdma->base+TOFF_DMAS_FCR), DMA_SxFCR_FEIE);
+	/* DMA開始 */
+	sil_orw_mem((uint32_t *)(hdma->base+TOFF_DMAS_CR), DMA_SxCR_EN);
+
+	return E_OK;
+}
+
+/*
+ *  STREAM DMA停止関数
+ *  parameter1  hdma  : DMAハンドラへのポインタ
+ *  return ER値
+ */
+ER
+dma_end(DMA_Handle_t *hdma)
+{
+	uint32_t tick = 0;
+
+	/* DMA停止 */
+	sil_andw_mem((uint32_t *)(hdma->base+TOFF_DMAS_CR), DMA_SxCR_EN);
+
+	/* DMA停止待ち */
+	while((sil_rew_mem((uint32_t *)(hdma->base+TOFF_DMAS_CR)) & DMA_SxCR_EN) != 0){
+	    /* Check for the Timeout */
+		if(tick > DMA_TRS_TIMEOUT){
+			/* タイムアウトエラー設定 */
+			hdma->ErrorCode |= DMA_ERROR_TIMEOUT;
+			return E_TMOUT;
+		}
+    	dly_tsk(1);
+	}
+	hdma->status = 0;
+	return E_OK;
+}
+
+/*
+ *  STREAM DMA割込み処理関数
+ *  parameter1  hdma: DMAハンドラへのポインタ
+ */
+void
+dma_inthandler(DMA_Handle_t *hdma)
+{
+	/*
+	 *  転送エラー処理
+	 */
+	if((sil_rew_mem((uint32_t *)(dma_faddr[hdma->sdid/4])) & dma_flag[hdma->sdid][INDEX_TE]) != 0){
+		if((sil_rew_mem((uint32_t *)(hdma->base+TOFF_DMAS_CR)) & DMA_SxCR_TEIE) != 0){
+			/* 転送エラー割込みクリア */
+			sil_andw_mem((uint32_t *)(hdma->base+TOFF_DMAS_CR), DMA_SxCR_TEIE);
+			/* 転送エラーフラグをクリア */
+			sil_wrw_mem((uint32_t *)(dma_faddr[hdma->sdid/4]+8), dma_flag[hdma->sdid][INDEX_TE]);
+			/* 転送エラー状態を設定 */
+			hdma->ErrorCode |= DMA_ERROR_TE;
+			hdma->status = DMA_STATUS_READY_ERROR;
+			/* エラーコールバック */
+			if(hdma->errorcallback != NULL)
+				hdma->errorcallback(hdma);
+		}
+	}
+	/*
+	 *  FIFOエラー処理
+	 */
+	if((sil_rew_mem((uint32_t *)(dma_faddr[hdma->sdid/4])) & dma_flag[hdma->sdid][INDEX_FE]) != 0){
+	    if((sil_rew_mem((uint32_t *)(hdma->base+TOFF_DMAS_FCR)) & DMA_SxFCR_FEIE) != 0){
+			/* FIFOエラー割込みをクリア */
+			sil_andw_mem((uint32_t *)(hdma->base+TOFF_DMAS_FCR), DMA_SxFCR_FEIE);
+			/* FIFOエラーフラグをクリア */
+			sil_wrw_mem((uint32_t *)(dma_faddr[hdma->sdid/4]+8), dma_flag[hdma->sdid][INDEX_FE]);
+			/* FIFOエラーを設定 */
+			hdma->ErrorCode |= DMA_ERROR_FE;
+			hdma->status = DMA_STATUS_READY_ERROR;
+			/* エラーコールバック */
+			if(hdma->errorcallback != NULL){
+				hdma->errorcallback(hdma);
+			}
+		}
+	}
+	/*
+	 *  ダイレクト・メモリ・エラー処理
+	 */
+	if((sil_rew_mem((uint32_t *)(dma_faddr[hdma->sdid/4])) & dma_flag[hdma->sdid][INDEX_DME]) != 0){
+		if((sil_rew_mem((uint32_t *)(hdma->base+TOFF_DMAS_CR)) & DMA_SxCR_DMEIE) != 0){
+			/* DMEエラー割込みをクリア */
+			sil_andw_mem((uint32_t *)(hdma->base+TOFF_DMAS_CR), DMA_SxCR_DMEIE);
+			/* DMEエラーフラグをクリア */
+			sil_wrw_mem((uint32_t *)(dma_faddr[hdma->sdid/4]+8), dma_flag[hdma->sdid][INDEX_DME]);
+			/* DMEエラーを設定 */
+			hdma->ErrorCode |= DMA_ERROR_DME;
+			hdma->status = DMA_STATUS_READY_ERROR;
+			/* エラーコールバック */
+			if(hdma->errorcallback != NULL)
+				hdma->errorcallback(hdma);
+		}
+	}
+	/*
+	 *  ハーフ転送終了処理
+	 */
+	if((sil_rew_mem((uint32_t *)(dma_faddr[hdma->sdid/4])) & dma_flag[hdma->sdid][INDEX_HT]) != 0){
+		if((sil_rew_mem((uint32_t *)(hdma->base+TOFF_DMAS_CR)) & DMA_SxCR_HTIE) != 0){
+			/* マルチバッファモード */
+			if((sil_rew_mem((uint32_t *)(hdma->base+TOFF_DMAS_CR)) & DMA_SxCR_DBM) != 0){
+				/* ハーフ転送フラグをクリア */
+				sil_wrw_mem((uint32_t *)(dma_faddr[hdma->sdid/4]+8), dma_flag[hdma->sdid][INDEX_HT]);
+
+				/* メモリ０使用 */
+				if((sil_rew_mem((uint32_t *)(hdma->base+TOFF_DMAS_CR)) & DMA_SxCR_CT) == 0){
+					/* ハーフメモリ０の状態設定 */
+					hdma->status = DMA_STATUS_READY_HMEM0;
+				}
+				/* メモリ１使用 */
+				else if((sil_rew_mem((uint32_t *)(hdma->base+TOFF_DMAS_CR)) & DMA_SxCR_CT) != 0){
+					/* ハーフメモリ１の状態設定 */
+					hdma->status = DMA_STATUS_READY_HMEM1;
+				}
+			}
+			else{
+				if((sil_rew_mem((uint32_t *)(hdma->base+TOFF_DMAS_CR)) & DMA_SxCR_CIRC) == 0){
+					/* ハーフ転送割込みをクリア */
+					sil_andw_mem((uint32_t *)(hdma->base+TOFF_DMAS_CR), DMA_SxCR_HTIE);
+				}
+				/* ハーフ転送完了フラグをクリア */
+				sil_wrw_mem((uint32_t *)(dma_faddr[hdma->sdid/4]+8), dma_flag[hdma->sdid][INDEX_HT]);
+				/* ハーフ転送ステータスに変更 */
+				hdma->status = DMA_STATUS_READY_HMEM0;
+			}
+			/* ハーフ転送終了コールバック */
+			if(hdma->xferhalfcallback != NULL)
+				hdma->xferhalfcallback(hdma);
+		}
+	}
+	/*
+	 *  転送終了処理
+	 */
+	if((sil_rew_mem((uint32_t *)(dma_faddr[hdma->sdid/4])) & dma_flag[hdma->sdid][INDEX_TC]) != 0){
+		if((sil_rew_mem((uint32_t *)(hdma->base+TOFF_DMAS_CR)) & DMA_SxCR_TCIE) != 0){
+			if((sil_rew_mem((uint32_t *)(hdma->base+TOFF_DMAS_CR)) & DMA_SxCR_DBM) != 0){
+				/* 転送完了フラグをクリア */
+				sil_wrw_mem((uint32_t *)(dma_faddr[hdma->sdid/4]+8), dma_flag[hdma->sdid][INDEX_TC]);
+				/* メモリ１使用 */
+				if((sil_rew_mem((uint32_t *)(hdma->base+TOFF_DMAS_CR)) & DMA_SxCR_CT) == 0){
+					/* メモリ1転送終了コールバック */
+					if(hdma->xferm1callback != NULL)
+						hdma->xferm1callback(hdma);
+				}
+				/* メモリ０使用 */
+				else if((sil_rew_mem((uint32_t *)(hdma->base+TOFF_DMAS_CR)) & DMA_SxCR_CT) != 0){
+					/* 転送終了コールバック */
+					if(hdma->xfercallback != NULL)
+						hdma->xfercallback(hdma);
+				}
+			}
+			else{
+				if((sil_rew_mem((uint32_t *)(hdma->base+TOFF_DMAS_CR)) & DMA_SxCR_CIRC) == 0){
+					/* 転送割込みをクリア */
+					sil_andw_mem((uint32_t *)(hdma->base+TOFF_DMAS_CR), DMA_SxCR_TCIE);
+				}
+				/* 転送完了フラグをクリア */
+				sil_wrw_mem((uint32_t *)(dma_faddr[hdma->sdid/4]+8), dma_flag[hdma->sdid][INDEX_TC]);
+				/* ステータスを終了へ */
+				hdma->ErrorCode = DMA_ERROR_NONE;
+				hdma->status = DMA_STATUS_READY_MEM0;
+				/* 転送終了コールバック */
+				if(hdma->xfercallback != NULL)
+					hdma->xfercallback(hdma);
+			}
+		}
+	}
+}
+
+/*
+ *  STREAM DMA 割込みサービスルーチン
+ */
+void
+stream_dma_isr(intptr_t exinf)
+{
+	dma_inthandler(pDmaHandler[(uint32_t)exinf]);
+}
+
+
+static DMA2D_Handle_t *pDma2dHandler;
+
+/*
+ *  DMA2D割込み関数
+ */
+void dma2d_inthandler(DMA2D_Handle_t *hdma2d)
+{
+	uint32_t isr = sil_rew_mem((uint32_t *)(hdma2d->base+TOFF_DMA2D_ISR));
+	/*
+	 *  転送エラー判定
+	 */
+	if((isr & DMA2D_ISR_TEIF) != 0){
+		if((sil_rew_mem((uint32_t *)(hdma2d->base+TOFF_DMA2D_CR)) & DMA2D_CR_TEIE) != 0){
+			/* 転送エラー割込みDisable */
+			sil_andw_mem((uint32_t *)(hdma2d->base+TOFF_DMA2D_CR), DMA2D_CR_TEIE);
+			hdma2d->ErrorCode |= DMA2D_ERROR_TE;	/* 転送エラー設定 */
+			hdma2d->status = DMA2D_STATUS_ERROR;
+			/* 転送エラー割込みクリア */
+			sil_wrw_mem((uint32_t *)(hdma2d->base+TOFF_DMA2D_IFCR), DMA2D_IFSR_CTEIF);
+			/* 転送エラーコールバック */
+			if(hdma2d->errorcallback != NULL)
+				hdma2d->errorcallback(hdma2d);
+			isig_sem(DMA2DTRNSEM);
+		}
+	}
+	/*
+	 *  コンフィギュレーションエラー判定
+	 */
+	if((isr & DMA2D_ISR_CEIF) != 0){
+		if((sil_rew_mem((uint32_t *)(hdma2d->base+TOFF_DMA2D_CR)) & DMA2D_CR_CEIE) != 0){
+			/* コンフィギュレーションエラーDisable */
+			sil_andw_mem((uint32_t *)(hdma2d->base+TOFF_DMA2D_CR), DMA2D_CR_CEIE);
+			/* コンフィギュレーションエラー割込みクリア */
+			sil_wrw_mem((uint32_t *)(hdma2d->base+TOFF_DMA2D_IFCR), DMA2D_IFSR_CCEIF);
+			hdma2d->ErrorCode |= DMA2D_ERROR_CE;	/* コンフィギュレーションエラー設定 */
+			hdma2d->status = DMA2D_STATUS_ERROR;
+			/* コンフィギュレーションエラーコールバック */
+			if(hdma2d->errorcallback != NULL)
+				hdma2d->errorcallback(hdma2d);
+			isig_sem(DMA2DTRNSEM);
+		}
+	}
+	/*
+	 *  転送終了割込み判定
+	 */
+	if((isr & DMA2D_ISR_TCIF) != 0){
+		if((sil_rew_mem((uint32_t *)(hdma2d->base+TOFF_DMA2D_CR)) & DMA2D_CR_TCIE) != 0){ 
+			/* 転送終了割込みDisable */
+			sil_andw_mem((uint32_t *)(hdma2d->base+TOFF_DMA2D_CR), DMA2D_CR_TCIE);
+			/* 転送終了割込みクリア */  
+			sil_wrw_mem((uint32_t *)(hdma2d->base+TOFF_DMA2D_IFCR), DMA2D_IFSR_CTCIF);
+			hdma2d->ErrorCode = DMA2D_ERROR_NONE;	/* エラー情報リセット */
+			hdma2d->status = DMA2D_STATUS_TCOMP;
+			/* 転送終了コールバック */
+			if(hdma2d->xfercallback != NULL)
+				hdma2d->xfercallback(hdma2d);
+			isig_sem(DMA2DTRNSEM);
+		}
+	}
+	/*
+	 *  CLUTローディング転送割込み判定
+	 */
+	if((isr & DMA2D_ISR_CTCIF) != 0){
+		if((sil_rew_mem((uint32_t *)(hdma2d->base+TOFF_DMA2D_CR)) & DMA2D_CR_CTCIE) != 0){ 
+			/* CLUT転送終了割込みDisable */
+			sil_andw_mem((uint32_t *)(hdma2d->base+TOFF_DMA2D_CR), DMA2D_CR_CTCIE);
+			/* 転送終了割込みクリア */
+			sil_wrw_mem((uint32_t *)(hdma2d->base+TOFF_DMA2D_IFCR), DMA2D_IFSR_CCTCIF);
+			hdma2d->ErrorCode = DMA2D_ERROR_NONE;	/* エラー情報リセット */
+			hdma2d->status = DMA2D_STATUS_CCOMP;
+			/* 転送終了コールバック */
+			if(hdma2d->xfercallback != NULL)
+				hdma2d->xfercallback(hdma2d);
+			isig_sem(DMA2DTRNSEM);
+		}
+	}
+}
+
+/*
+ *  DMA2Dの初期設定
+ *  parameter1 hdma2d    DMA2Dハンドラへのポインタ
+ *  return               正常終了ならばE_OK
+ */
+ER
+dma2d_init(DMA2D_Handle_t *hdma2d)
+{
+	volatile uint32_t tmp = 0;
+	static bool_t init = false;
+
+	if(hdma2d == NULL)
+		return E_PAR;
+
+	wai_sem(DMA2DSEM);	/* セマフォロック */
+	pDma2dHandler = hdma2d;
+	if(!init){
+		/* クロック設定 */
+		sil_orw_mem((uint32_t *)(TADR_RCC_BASE+TOFF_RCC_AHB1ENR), RCC_AHB1ENR_DMA2DEN);
+		tmp = sil_rew_mem((uint32_t *)(TADR_RCC_BASE+TOFF_RCC_AHB1ENR));
+		(void)(tmp);
+		init = true;
+	}
+
+	/* DMA2D CRレジスタ設定 */
+	sil_modw_mem((uint32_t *)(hdma2d->base+TOFF_DMA2D_CR), DMA2D_CR_MODE, hdma2d->Init.Mode);
+	/* DMA2D OPFCCレジスタ設定 */
+	sil_modw_mem((uint32_t *)(hdma2d->base+TOFF_DMA2D_OPFCCR), DMA2D_OPFCCR_CM, hdma2d->Init.ColorMode);
+	/* DMA2D OORレジスタ設定 */
+	sil_modw_mem((uint32_t *)(hdma2d->base+TOFF_DMA2D_OOR), DMA2D_OOR_LO, hdma2d->Init.OutputOffset);
+
+#if defined(TOPPERS_STM32F767_NUCLEO144) || defined(TOPPERS_STM32F769_DISCOVERY)
+	/* DMA2D OPFCCRレジスタ AI/RBSWAP設定 */
+	sil_modw_mem((uint32_t *)(hdma2d->base+TOFF_DMA2D_OPFCCR), DMA2D_OPFCCR_AI, hdma2d->Init.AlphaInverted);
+	sil_modw_mem((uint32_t *)(hdma2d->base+TOFF_DMA2D_OPFCCR), DMA2D_OPFCCR_RBS, hdma2d->Init.RedBlueSwap);
+#endif
+
+	/* エラー情報リセット */
+	hdma2d->ErrorCode = DMA2D_ERROR_NONE;
+	return E_OK;
+}
+
+/*
+ *  DMA2Dレイヤー設定
+ *  parameter1 hdma2d    DMA2Dハンドラへのポインタ
+ *  parameter2 LayerIdx  DMA2Dレイヤーインデックス
+ *  return               正常終了ならばE_OK
+ */
+ER
+dma2d_configlayer(DMA2D_Handle_t *hdma2d, uint32_t LayerIdx)
+{
+	DMA2D_LayerCfg_t *pLayerCfg = &hdma2d->LayerCfg[LayerIdx];
+	uint32_t tmp = 0;
+
+	if(hdma2d->Init.Mode != DMA2D_R2M && hdma2d->Init.Mode != DMA2D_M2M){
+		if(pLayerCfg->AlphaMode != DMA2D_NO_MODIF_ALPHA
+			&& pLayerCfg->AlphaMode != DMA2D_REPLACE_ALPHA && pLayerCfg->AlphaMode != DMA2D_COMBINE_ALPHA){
+			sig_sem(DMA2DSEM);
+			return E_PAR;
+		}
+	}
+
+	/* レイヤー0(background)DMA2D設定 */
+	if(LayerIdx == 0){
+		/* DMA2D BGPFCCRレジスタ設定 */
+		tmp = sil_rew_mem((uint32_t *)(hdma2d->base+TOFF_DMA2D_BGPFCCR));
+		tmp &= (uint32_t)~(DMA2D_BGPFCCR_CM | DMA2D_BGPFCCR_AM | DMA2D_BGPFCCR_ALPHA); 
+		if (pLayerCfg->InputColorMode == CM_A4 || pLayerCfg->InputColorMode == CM_A8)
+			tmp |= (pLayerCfg->InputColorMode | (pLayerCfg->AlphaMode << 16) | ((pLayerCfg->InputAlpha) & 0xFF000000));
+		else
+			tmp |= (pLayerCfg->InputColorMode | (pLayerCfg->AlphaMode << 16) | (pLayerCfg->InputAlpha << 24));
+		sil_wrw_mem((uint32_t *)(hdma2d->base+TOFF_DMA2D_BGPFCCR), tmp);
+
+		/* DMA2D BGORレジスタ設定 */
+		sil_modw_mem((uint32_t *)(hdma2d->base+TOFF_DMA2D_BGOR), DMA2D_BGOR_LO, pLayerCfg->InputOffset);
+		/* DMA2D BGCOLRレジスタ設定 */
+		if ((pLayerCfg->InputColorMode == CM_A4) || (pLayerCfg->InputColorMode == CM_A8)){
+			sil_wrw_mem((uint32_t *)(hdma2d->base+TOFF_DMA2D_BGCOLR), (pLayerCfg->InputAlpha & 0x00FFFFFF));
+		}
+	}
+	/* レイヤー1(foreground)DMA2D設定 */
+	else{
+		/* DMA2D FGPFCCRレジスタ設定 */
+		tmp = sil_rew_mem((uint32_t *)(hdma2d->base+TOFF_DMA2D_FGPFCCR));
+		tmp &= (uint32_t)~(DMA2D_FGPFCCR_CM | DMA2D_FGPFCCR_AM | DMA2D_FGPFCCR_ALPHA); 
+		if (pLayerCfg->InputColorMode == CM_A4 || pLayerCfg->InputColorMode == CM_A8)
+			tmp |= (pLayerCfg->InputColorMode | (pLayerCfg->AlphaMode << 16) | ((pLayerCfg->InputAlpha) & 0xFF000000));
+		else
+			tmp |= (pLayerCfg->InputColorMode | (pLayerCfg->AlphaMode << 16) | (pLayerCfg->InputAlpha << 24));
+		sil_wrw_mem((uint32_t *)(hdma2d->base+TOFF_DMA2D_FGPFCCR), tmp);
+
+		/* DMA2D FGORレジスタ設定 */
+		sil_modw_mem((uint32_t *)(hdma2d->base+TOFF_DMA2D_FGOR), DMA2D_FGOR_LO, pLayerCfg->InputOffset);
+		/* DMA2D FGCOLRレジスタ設定 */
+		if ((pLayerCfg->InputColorMode == CM_A4) || (pLayerCfg->InputColorMode == CM_A8)){
+			sil_wrw_mem((uint32_t *)(hdma2d->base+TOFF_DMA2D_FGCOLR), (pLayerCfg->InputAlpha & 0x00FFFFFF));
+		}
+	}
+	return E_OK;
+}
+
+/*
+ *  DMA2D転送スタート
+ *  parameter1 hdma2d    DMA2Dハンドラへのポインタ
+ *  parameter2 pdata     ソースメモリバッファアドレス
+ *  parameter3 DstAddr   デスティネーションメモリバッファアドレス
+ *  parameter4 Width     転送データ幅
+ *  parameter5 Height    転送データ高さ
+ *  return               正常終了ならばE_OK
+ */
+ER
+dma2d_start(DMA2D_Handle_t *hdma2d, uint32_t pdata, uint32_t DstAddress, uint32_t Width,  uint32_t Height)
+{
+	if(hdma2d == NULL)
+		return E_PAR;
+	/* DMA2D Disable */
+	sil_andw_mem((uint32_t *)(hdma2d->base+TOFF_DMA2D_CR), DMA2D_CR_START);
+
+	/* DMA2Dデータサイズ設定 */
+	sil_wrw_mem((uint32_t *)(hdma2d->base+TOFF_DMA2D_NLR), (Width << 16) | Height);
+
+	/* DMA2Dのデスティネーションアドレス設定 */
+	sil_wrw_mem((uint32_t *)(hdma2d->base+TOFF_DMA2D_OMAR), DstAddress);
+
+	/* DMA2Dメモリモード選択 */
+	if (hdma2d->Init.Mode == DMA2D_R2M){
+		uint32_t tmp = 0;
+		uint32_t tmp1 = 0;
+		uint32_t tmp2 = 0;
+		uint32_t tmp3 = 0;
+		uint32_t tmp4 = 0;
+
+		tmp1 = pdata & DMA2D_OCOLR_ALPHA_1;
+		tmp2 = pdata & DMA2D_OCOLR_RED_1;
+		tmp3 = pdata & DMA2D_OCOLR_GREEN_1;
+		tmp4 = pdata & DMA2D_OCOLR_BLUE_1;
+
+		/* Prepare the value to be wrote to the OCOLR register according to the color mode */
+		if (hdma2d->Init.ColorMode == DMA2D_ARGB8888){
+			tmp = (tmp3 | tmp2 | tmp1| tmp4);
+		}
+		else if (hdma2d->Init.ColorMode == DMA2D_RGB888){
+			tmp = (tmp3 | tmp2 | tmp4);  
+		}
+		else if (hdma2d->Init.ColorMode == DMA2D_RGB565){
+			tmp2 = (tmp2 >> 19);
+			tmp3 = (tmp3 >> 10);
+			tmp4 = (tmp4 >> 3 );
+			tmp  = ((tmp3 << 5) | (tmp2 << 11) | tmp4); 
+		}
+ 		else if (hdma2d->Init.ColorMode == DMA2D_ARGB1555){
+			tmp1 = (tmp1 >> 31);
+			tmp2 = (tmp2 >> 19);
+			tmp3 = (tmp3 >> 11);
+			tmp4 = (tmp4 >> 3 );
+			tmp  = ((tmp3 << 5) | (tmp2 << 10) | (tmp1 << 15) | tmp4);
+		}
+		else{ /* DMA2D_CMode = DMA2D_ARGB4444 */
+			tmp1 = (tmp1 >> 28);
+			tmp2 = (tmp2 >> 20);
+			tmp3 = (tmp3 >> 12);
+			tmp4 = (tmp4 >> 4 );
+			tmp  = ((tmp3 << 4) | (tmp2 << 8) | (tmp1 << 12) | tmp4);
+		}
+		/* Write to DMA2D OCOLR register */
+		sil_wrw_mem((uint32_t *)(hdma2d->base+TOFF_DMA2D_OCOLR), tmp);
+	}
+	else{ /* M2M, M2M_PFC or M2M_Blending DMA2D Mode */
+		/* DMA2Dソースアドレス設定 */
+		sil_wrw_mem((uint32_t *)(hdma2d->base+TOFF_DMA2D_FGMAR), pdata);
+	}
+	/*
+	 *  転送割込みを許可
+	 */
+	sil_orw_mem((uint32_t *)(hdma2d->base+TOFF_DMA2D_CR), (DMA2D_CR_TEIE | DMA2D_CR_CEIE | DMA2D_CR_TCIE));
+
+	/* DMA2D Enable */
+	sil_orw_mem((uint32_t *)(hdma2d->base+TOFF_DMA2D_CR), DMA2D_CR_START);
+	hdma2d->status = DMA2D_STATUS_BUSY;
+	return E_OK;
+}
+
+/*
+ *  DMA2D転送待ち
+ *  parameter1 hdma2d    DMA2Dハンドラへのポインタ
+ *  parameter2 Timeout   待ち時間(MS)
+ *  return               正常終了ならばE_OK
+ */
+ER
+dma2d_waittransfar(DMA2D_Handle_t *hdma2d, uint32_t Timeout)
+{
+	ER       ercd = E_OK;
+	uint32_t time = 0;
+
+	/*
+	 *  転送設定がある場合のポーリング待ち
+	 */
+	if((sil_rew_mem((uint32_t *)(hdma2d->base+TOFF_DMA2D_CR)) & DMA2D_CR_START) != 0){
+		while(hdma2d->status == DMA2D_STATUS_BUSY){
+			if(time > Timeout){	/* タイムアウト時間をチェック */
+				hdma2d->ErrorCode |= DMA2D_ERROR_TIMEOUT;	/* タイムアウトエラー設定 */
+				sig_sem(DMA2DSEM);
+				return E_TMOUT;
+			}
+			twai_sem(DMA2DTRNSEM, 1);
+			time++;
+		}
+		if(hdma2d->status == DMA2D_STATUS_ERROR)
+			ercd = E_OBJ;
+	}
+	/*
+	 *  CLUTローディングの処理待ち
+	 */
+	time = 0;
+	if((sil_rew_mem((uint32_t *)(hdma2d->base+TOFF_DMA2D_FGPFCCR)) & DMA2D_FGPFCCR_START) != 0){
+		while(hdma2d->status == DMA2D_STATUS_BUSY){
+			if(time > Timeout){	/* タイムアウト時間をチェック */
+				hdma2d->ErrorCode |= DMA2D_ERROR_TIMEOUT;	/* タイムアウトエラー設定 */
+				sig_sem(DMA2DSEM);
+				return E_TMOUT;
+			}
+			twai_sem(DMA2DTRNSEM, 1);
+			time++;
+		}
+		if(hdma2d->status == DMA2D_STATUS_ERROR)
+			ercd = E_OBJ;
+	}
+	sig_sem(DMA2DSEM);	/* セマフォアンロック */
+	return ercd;
+}
+
+/*
+ *  DMA2D割込みハンドラ
+ */
+void dma2d_handler(void)
+{
+	dma2d_inthandler(pDma2dHandler);
+}
+
+
+#define RTC_ASYNCH_PREDIV       0x7F		/* LSE用 RTCクロック */
+#define RTC_SYNCH_PREDIV        0x00FF
+
+#define RTC_TR_RESERVED_MASK    (RTC_TR_SU | RTC_TR_ST | RTC_TR_MNU | RTC_TR_MNT | \
+								 RTC_TR_HU | RTC_TR_HT | RTC_TR_PM)
+#define RTC_DR_RESERVED_MASK    (RTC_DR_DU | RTC_DR_DT  | RTC_DR_MU | RTC_DR_MT | \
+								 RTC_DR_WDU | RTC_DR_YU | RTC_DR_YT)
+#define RTC_INIT_MASK           ((uint32_t)0xFFFFFFFF)  
+#define RTC_RSF_MASK            ((uint32_t)0xFFFFFF5F)
+
+#define RTC_TIMEOUT_VALUE       (1000*1000)
+#define LSI_TIMEOUT_VALUE       (100*1000)
+#define RCC_DBP_TIMEOUT_VALUE   (100*1000)
+#define RCC_LSE_TIMEOUT_VALUE   (5000*1000)
+
+#define RTC_EXTI_LINE_WUPTIMER  ((uint32_t)EXTI_IMR_MR22)	/* External interrupt line 22 Connected to the RTC Wake-up event */
+
+uint32_t rtcerrorcode;
+
+static void (*rtcalarmA_callback)(void);	/* DMA transfer complete Memory1 callback */
+static void (*rtcalarmB_callback)(void);	/* DMA transfer error callback */
+static void (*rtcwakeup_callback)(void);	/* rtc wakeup callback */
+
+/*
+ *  RTCエントリモード設定
+ */
+static ER
+rtc_requestInitMode(void)
+{
+	uint32_t tick = 0;
+
+	/*
+	 * イニシャルモード判定
+	 */
+	if((sil_rew_mem((uint32_t *)(TADR_RTC_BASE+TOFF_RTC_ISR)) & RTC_ISR_INITF) == 0){
+	    /*
+		 *  イニシャルモード設定
+		 */
+		sil_wrw_mem((uint32_t *)(TADR_RTC_BASE+TOFF_RTC_ISR), RTC_INIT_MASK);
+	    while((sil_rew_mem((uint32_t *)(TADR_RTC_BASE+TOFF_RTC_ISR)) & RTC_ISR_INITF) == 0){
+			if(tick > RTC_TIMEOUT_VALUE){
+				return E_TMOUT;
+			}
+		}
+		sil_dly_nse(1000);
+		tick++;
+	}
+	return E_OK;
+}
+
+/*
+ *  RTC用初期化
+ */
+void
+rtc_init(intptr_t exinf)
+{
+	uint32_t tick = 0;
+	volatile uint32_t tmpreg;
+
+	rtcerrorcode = 0;
+	/*
+	 *  LSIをオフする
+	 */
+	sil_andw_mem((uint32_t *)(TADR_RCC_BASE+TOFF_RCC_CSR), RCC_CSR_LSION);
+	while((sil_rew_mem((uint32_t *)(TADR_RCC_BASE+TOFF_RCC_CSR)) & RCC_CSR_LSIRDY) != 0){
+		if( tick > LSI_TIMEOUT_VALUE){
+			rtcerrorcode |= RTC_ERROR_LSI;
+			return;
+		}
+		sil_dly_nse(1000);
+		tick++;
+	}
+
+	/*
+	 *  LSEをオンする
+	 */
+    /* Enable Power Clock*/
+	sil_orw_mem((uint32_t *)(TADR_RCC_BASE+TOFF_RCC_APB1ENR), RCC_APB1ENR_PWREN);
+	tmpreg = sil_rew_mem((uint32_t *)(TADR_RCC_BASE+TOFF_RCC_APB1ENR));
+
+	/* Enable write access to Backup domain */
+	sil_orw_mem((uint32_t *)(TADR_PWR_BASE+TOFF_PWR_CR1), PWR_CR1_DBP);
+
+	/* Wait for Backup domain Write protection disable */
+	tick = 0;
+	while((sil_rew_mem((uint32_t *)(TADR_PWR_BASE+TOFF_PWR_CR1)) & PWR_CR1_DBP) == 0){
+		if(tick > RCC_DBP_TIMEOUT_VALUE){
+			rtcerrorcode |= RTC_ERROR_LSE;
+			return;
+		}
+		sil_dly_nse(1000);
+		tick++;
+	}
+    
+    /*
+	 *  LSEON / LSEBYPリセット
+	 */
+	sil_andw_mem((uint32_t *)(TADR_RCC_BASE+TOFF_RCC_BDCR), RCC_BDCR_LSEBYP);
+	sil_andw_mem((uint32_t *)(TADR_RCC_BASE+TOFF_RCC_BDCR), RCC_BDCR_LSEON);
+
+	tick = 0;
+	while((sil_rew_mem((uint32_t *)(TADR_RCC_BASE+TOFF_RCC_BDCR)) & RCC_BDCR_LSERDY) != 0){
+		if(tick > RCC_LSE_TIMEOUT_VALUE){
+			rtcerrorcode |= RTC_ERROR_LSE;
+			return;
+		}
+		sil_dly_nse(1000);
+		tick++;
+	}
+    
+    /*
+	 *  LSE初期設定
+	 */
+	sil_andw_mem((uint32_t *)(TADR_RCC_BASE+TOFF_RCC_BDCR), RCC_BDCR_LSEBYP);
+	sil_orw_mem((uint32_t *)(TADR_RCC_BASE+TOFF_RCC_BDCR), RCC_BDCR_LSEON);
+
+	tick = 0;
+	while((sil_rew_mem((uint32_t *)(TADR_RCC_BASE+TOFF_RCC_BDCR)) & RCC_BDCR_LSERDY) == 0){
+		if(tick > RCC_LSE_TIMEOUT_VALUE){
+			rtcerrorcode |= RTC_ERROR_LSE;
+			return;
+		}
+		sil_dly_nse(1000);
+		tick++;
+	}
+
+    /*
+	 *  RTCクロック設定
+	 */
+	if((sil_rew_mem((uint32_t *)(TADR_RCC_BASE+TOFF_RCC_BDCR)) & RCC_BDCR_RTCSEL) != RCC_BDCR_RTCSEL_0){
+		/*
+		 *  クロック電源設定
+		 */
+		tmpreg = (sil_rew_mem((uint32_t *)(TADR_RCC_BASE+TOFF_RCC_BDCR)) & ~(RCC_BDCR_RTCSEL));
+
+		sil_orw_mem((uint32_t *)(TADR_RCC_BASE+TOFF_RCC_BDCR), RCC_BDCR_BDRST);
+		sil_andw_mem((uint32_t *)(TADR_RCC_BASE+TOFF_RCC_BDCR), RCC_BDCR_BDRST);
+
+		sil_wrw_mem((uint32_t *)(TADR_RCC_BASE+TOFF_RCC_BDCR), tmpreg);
+
+		if((tmpreg & RCC_BDCR_LSERDY) != 0){
+			tick = 0;
+			/* Wait till LSE is ready */  
+			while((sil_rew_mem((uint32_t *)(TADR_RCC_BASE+TOFF_RCC_BDCR)) & RCC_BDCR_LSERDY) == 0){
+				if(tick > RCC_LSE_TIMEOUT_VALUE){
+					rtcerrorcode |= RTC_ERROR_RTC;
+					return;
+				}
+				sil_dly_nse(1000);
+				tick++;
+			}
+		}
+		sil_andw_mem((uint32_t *)(TADR_RCC_BASE+TOFF_RCC_CFGR), RCC_CFGR_RTCPRE);
+		sil_orw_mem((uint32_t *)(TADR_RCC_BASE+TOFF_RCC_BDCR), RCC_BDCR_RTCSEL_0);
+	}
+
+	/*
+	 *  RTCのクロック設定
+	 */
+	sil_orw_mem((uint32_t *)(TADR_RCC_BASE+TOFF_RCC_BDCR), RCC_BDCR_RTCEN);
+
+	/* プロテクション解除 */
+	sil_wrw_mem((uint32_t *)(TADR_RTC_BASE+TOFF_RTC_WPR), 0xCA);
+	sil_wrw_mem((uint32_t *)(TADR_RTC_BASE+TOFF_RTC_WPR), 0x53);
+
+	/*
+	 *  RTC初期設定
+	 */
+	if(rtc_requestInitMode() != E_OK){
+		rtcerrorcode |= RTC_ERROR_RTC;
+	    /* プロテクション設定 */
+		sil_wrw_mem((uint32_t *)(TADR_RTC_BASE+TOFF_RTC_WPR), 0xFF);
+		return;
+	}
+	else{ 
+		sil_andw_mem((uint32_t *)(TADR_RTC_BASE+TOFF_RTC_CR), (RTC_CR_FMT | RTC_CR_OSEL | RTC_CR_POL));
+
+		sil_wrw_mem((uint32_t *)(TADR_RTC_BASE+TOFF_RTC_PRER), RTC_SYNCH_PREDIV);
+		sil_orw_mem((uint32_t *)(TADR_RTC_BASE+TOFF_RTC_PRER), (RTC_ASYNCH_PREDIV << 16));
+
+		sil_andw_mem((uint32_t *)(TADR_RTC_BASE+TOFF_RTC_ISR), RTC_ISR_INIT);
+		sil_andw_mem((uint32_t *)(TADR_RTC_BASE+TOFF_RTC_OR), RTC_OR_ALARMTYPE);
+
+	    /* プロテクション設定 */
+		sil_wrw_mem((uint32_t *)(TADR_RTC_BASE+TOFF_RTC_WPR), 0xFF);
+		return;
+	}
+}
+
+/*
+ *  RTCの時刻設定関数
+ *
+ *  時刻の設定はPONIXのtm構造体を使用する
+ *  PONIXのインクルードがない場合を考慮し、同一項目のtm2をドライバとして定義する。
+ */
+ER
+rtc_set_time(struct tm2 *pt)
+{
+	uint32_t timetmp = 0;
+	uint32_t datetmp = 0;
+
+	if(pt == NULL)
+		return E_PAR;
+	if(rtcerrorcode != 0)
+		return E_SYS;
+
+	SVC_PERROR(wai_sem(RTCSEM));
+
+	datetmp = (((uint32_t)byte2bcd(pt->tm_year - 30) << 16) |
+				((uint32_t)byte2bcd(pt->tm_mon) << 8) |
+				((uint32_t)byte2bcd(pt->tm_mday)) |
+				((uint32_t)pt->tm_wday << 13));
+    timetmp = (uint32_t)(((uint32_t)byte2bcd(pt->tm_hour) << 16) |
+				((uint32_t)byte2bcd(pt->tm_min) << 8) |
+				((uint32_t)byte2bcd(pt->tm_sec)));
+
+	/* プロテクション解除 */
+	sil_wrw_mem((uint32_t *)(TADR_RTC_BASE+TOFF_RTC_WPR), 0xCA);
+	sil_wrw_mem((uint32_t *)(TADR_RTC_BASE+TOFF_RTC_WPR), 0x53);
+
+	/*
+	 *  初期化モード設定
+	 */
+	if(rtc_requestInitMode() != E_OK){
+		/* プロテクション設定 */
+		sil_wrw_mem((uint32_t *)(TADR_RTC_BASE+TOFF_RTC_WPR), 0xFF);
+		SVC_PERROR(sig_sem(RTCSEM));
+		return E_TMOUT;
+	}
+	else{
+		/*
+		 *  日付、時刻設定
+		 */
+		sil_wrw_mem((uint32_t *)(TADR_RTC_BASE+TOFF_RTC_DR), (datetmp & RTC_DR_RESERVED_MASK));
+		sil_wrw_mem((uint32_t *)(TADR_RTC_BASE+TOFF_RTC_TR), (timetmp & RTC_TR_RESERVED_MASK));
+
+		/*  初期化モード終了 */
+		sil_andw_mem((uint32_t *)(TADR_RTC_BASE+TOFF_RTC_CR), RTC_CR_BCK);
+		sil_andw_mem((uint32_t *)(TADR_RTC_BASE+TOFF_RTC_ISR), RTC_ISR_INIT);
+
+		/*
+		 *  同期設定
+		 */
+		if((sil_rew_mem((uint32_t *)(TADR_RTC_BASE+TOFF_RTC_CR)) & RTC_CR_BYPSHAD) == 0){
+			uint32_t tick = 0;
+
+			sil_andw_mem((uint32_t *)(TADR_RTC_BASE+TOFF_RTC_ISR), RTC_RSF_MASK);
+    		while((sil_rew_mem((uint32_t *)(TADR_RTC_BASE+TOFF_RTC_ISR)) & RTC_ISR_RSF) == 0){
+				if(tick > (RTC_TIMEOUT_VALUE/1000)){
+					SVC_PERROR(sig_sem(RTCSEM));
+					return E_TMOUT;
+				}
+				dly_tsk(1);
+				tick++;
+			}
+		}
+
+		/* プロテクション設定 */
+		sil_wrw_mem((uint32_t *)(TADR_RTC_BASE+TOFF_RTC_WPR), 0xFF);
+	}
+	SVC_PERROR(sig_sem(RTCSEM));
+	return E_OK;
+}
+
+/*
+ *  RTCの時刻取り出し関数
+ *
+ *  時刻の設定はPONIXのtm構造体を使用する
+ *  PONIXのインクルードがない場合を考慮し、同一項目のtm2をドライバとして定義する。
+ */
+ER
+rtc_get_time(struct tm2 *pt)
+{
+	uint32_t timetmp = 0;
+	uint32_t datetmp = 0;
+
+	if(pt == NULL)
+		return E_PAR;
+	if(rtcerrorcode != 0)
+		return E_SYS;
+
+	SVC_PERROR(wai_sem(RTCSEM));
+	/*
+	 *  時刻取得
+	 */
+	timetmp = sil_rew_mem((uint32_t *)(TADR_RTC_BASE+TOFF_RTC_TR)) & RTC_TR_RESERVED_MASK;
+	pt->tm_hour = (uint8_t)bcd2byte((uint8_t)((timetmp & (RTC_TR_HT | RTC_TR_HU)) >> 16));
+	pt->tm_min = (uint8_t)bcd2byte((uint8_t)((timetmp & (RTC_TR_MNT | RTC_TR_MNU)) >>8));
+	pt->tm_sec = (uint8_t)bcd2byte((uint8_t)(timetmp & (RTC_TR_ST | RTC_TR_SU)));
+  
+	/*
+	 *  日付取得
+	 */
+	datetmp = sil_rew_mem((uint32_t *)(TADR_RTC_BASE+TOFF_RTC_DR)) & RTC_DR_RESERVED_MASK;
+	pt->tm_year = (uint8_t)bcd2byte((uint8_t)((datetmp & (RTC_DR_YT | RTC_DR_YU)) >> 16)) + 30;
+	pt->tm_mon = (uint8_t)bcd2byte((uint8_t)((datetmp & (RTC_DR_MT | RTC_DR_MU)) >> 8));
+	pt->tm_mday = (uint8_t)bcd2byte((uint8_t)(datetmp & (RTC_DR_DT | RTC_DR_DU)));
+	pt->tm_wday = (uint8_t)((datetmp & (RTC_DR_WDU)) >> 13); 
+
+	SVC_PERROR(sig_sem(RTCSEM));
+	return E_OK;
+}
+
+/*
+ *  RTCアラーム設定
+ *  parameter1 : parm: Pointer to Alarm structure
+ *  parameter2 : ptm: Pointer to struct tm2
+ *  return ERコード
+ */
+ER
+rtc_setalarm(RTC_Alarm_t *parm, struct tm2 *ptm)
+{
+	uint32_t tick = 0;
+	uint32_t tmparm = 0, subsecond = 0;
+	uint32_t tmp, day;
+
+	if(parm == NULL || ptm == NULL)
+		return E_PAR;
+	if(rtcerrorcode != 0)
+		return E_SYS;
+
+	if(parm->dayselect == ALARMDAYSEL_DATE)
+		day = ptm->tm_mday;
+	else
+		day = ptm->tm_wday;
+
+	/*
+	 *  ALARM-AB設定レジスタ値を取得
+	 */
+	SVC_PERROR(wai_sem(RTCSEM));
+    tmparm = ((byte2bcd(ptm->tm_hour) << 16) | (byte2bcd(ptm->tm_min) << 8) |
+              (byte2bcd(ptm->tm_sec)) | (byte2bcd(day) << 24) |
+              ((uint32_t)parm->dayselect) | (parm->alarmmask)); 
+	subsecond = (uint32_t)(parm->subsecond | parm->subsecondmask);
+
+	/* プロテクション解除 */
+	sil_wrw_mem((uint32_t *)(TADR_RTC_BASE+TOFF_RTC_WPR), 0xCA);
+	sil_wrw_mem((uint32_t *)(TADR_RTC_BASE+TOFF_RTC_WPR), 0x53);
+
+	if(parm->alarm == RTC_ALARM_A){
+		/*
+		 *  ALARM-A設定、レジスタ初期化
+		 */
+		sil_andw_mem((uint32_t *)(TADR_RTC_BASE+TOFF_RTC_CR), RTC_CR_ALRAE);
+		tmp = sil_rew_mem((uint32_t *)(TADR_RTC_BASE+TOFF_RTC_ISR));
+		sil_wrw_mem((uint32_t *)(TADR_RTC_BASE+TOFF_RTC_ISR), (~(RTC_ISR_ALRAF | RTC_ISR_INIT) | tmp));
+		while((sil_rew_mem((uint32_t *)(TADR_RTC_BASE+TOFF_RTC_ISR)) & RTC_ISR_ALRAWF) == 0){
+			if(tick > (RTC_TIMEOUT_VALUE/1000)){
+			    /* プロテクション設定 */
+				sil_wrw_mem((uint32_t *)(TADR_RTC_BASE+TOFF_RTC_WPR), 0xFF);
+				SVC_PERROR(sig_sem(RTCSEM));
+				return E_TMOUT;
+			}
+			dly_tsk(1);
+			tick++;
+		}
+
+		/*
+		 *  ALARM-A設定
+		 */
+		sil_wrw_mem((uint32_t *)(TADR_RTC_BASE+TOFF_RTC_ALRMAR), tmparm);
+		sil_wrw_mem((uint32_t *)(TADR_RTC_BASE+TOFF_RTC_ALRMASSR), subsecond);
+		sil_orw_mem((uint32_t *)(TADR_RTC_BASE+TOFF_RTC_CR), RTC_CR_ALRAE);
+		sil_orw_mem((uint32_t *)(TADR_RTC_BASE+TOFF_RTC_CR), RTC_CR_ALRAIE);
+		rtcalarmA_callback = parm->callback;
+	}
+	else{
+		/*
+		 *  ALARM-B設定、レジスタ初期化
+		 */
+		sil_andw_mem((uint32_t *)(TADR_RTC_BASE+TOFF_RTC_CR), RTC_CR_ALRBE);
+		tmp = sil_rew_mem((uint32_t *)(TADR_RTC_BASE+TOFF_RTC_ISR));
+		sil_wrw_mem((uint32_t *)(TADR_RTC_BASE+TOFF_RTC_ISR), (~(RTC_ISR_ALRBF | RTC_ISR_INIT) | tmp));
+		while((sil_rew_mem((uint32_t *)(TADR_RTC_BASE+TOFF_RTC_ISR)) & RTC_ISR_ALRBWF) == 0){
+			if(tick > (RTC_TIMEOUT_VALUE/1000)){
+			    /* プロテクション設定 */
+				sil_wrw_mem((uint32_t *)(TADR_RTC_BASE+TOFF_RTC_WPR), 0xFF);
+				SVC_PERROR(sig_sem(RTCSEM));
+				return E_TMOUT;
+			}
+			dly_tsk(1);
+			tick++;
+		}
+
+		/*
+		 *  ALARM-B設定
+		 */
+		sil_wrw_mem((uint32_t *)(TADR_RTC_BASE+TOFF_RTC_ALRMBR), tmparm);
+		sil_wrw_mem((uint32_t *)(TADR_RTC_BASE+TOFF_RTC_ALRMBSSR), subsecond);
+		sil_orw_mem((uint32_t *)(TADR_RTC_BASE+TOFF_RTC_CR), RTC_CR_ALRBE);
+		sil_orw_mem((uint32_t *)(TADR_RTC_BASE+TOFF_RTC_CR), RTC_CR_ALRBIE);
+		rtcalarmB_callback = parm->callback;
+	}
+
+	/*
+	 * RTC ALARM用EXTI設定
+	 */
+	sil_orw_mem((uint32_t *)(TADR_EXTI_BASE+TOFF_EXTI_IMR), EXTI_IMR_MR17);
+	sil_orw_mem((uint32_t *)(TADR_EXTI_BASE+TOFF_EXTI_RTSR), EXTI_RTSR_TR17);
+
+    /* プロテクション設定 */
+	sil_wrw_mem((uint32_t *)(TADR_RTC_BASE+TOFF_RTC_WPR), 0xFF);
+	SVC_PERROR(sig_sem(RTCSEM));
+	return E_OK;
+}
+
+/*
+ *  RTCアラーム停止
+ *  parameter1 : Alarm: アラーム設定
+ *  return ERコード
+ */
+ER
+rtc_stopalarm(uint32_t Alarm)
+{
+	uint32_t tick = 0;
+
+	if(rtcerrorcode != 0)
+		return E_SYS;
+	SVC_PERROR(wai_sem(RTCSEM));
+	/* プロテクション解除 */
+	sil_wrw_mem((uint32_t *)(TADR_RTC_BASE+TOFF_RTC_WPR), 0xCA);
+	sil_wrw_mem((uint32_t *)(TADR_RTC_BASE+TOFF_RTC_WPR), 0x53);
+
+	if(Alarm == RTC_ALARM_A){
+		/*
+		 *  ALARM-A割込みイネーブル解除
+		 */
+		sil_andw_mem((uint32_t *)(TADR_RTC_BASE+TOFF_RTC_CR), RTC_CR_ALRAE);
+		sil_andw_mem((uint32_t *)(TADR_RTC_BASE+TOFF_RTC_CR), RTC_CR_ALRAIE);
+		while((sil_rew_mem((uint32_t *)(TADR_RTC_BASE+TOFF_RTC_ISR)) & RTC_ISR_ALRAWF) == 0){
+			if(tick > (RTC_TIMEOUT_VALUE/1000)){
+			    /* プロテクション設定 */
+				sil_wrw_mem((uint32_t *)(TADR_RTC_BASE+TOFF_RTC_WPR), 0xFF);
+				SVC_PERROR(sig_sem(RTCSEM));
+				return E_TMOUT;
+			}
+			dly_tsk(1);
+			tick++;
+		}
+		rtcalarmA_callback = NULL;
+	}
+	else{
+		/*
+		 *  ALARM-B割込みイネーブル解除
+		 */
+		sil_andw_mem((uint32_t *)(TADR_RTC_BASE+TOFF_RTC_CR), RTC_CR_ALRBE);
+		sil_andw_mem((uint32_t *)(TADR_RTC_BASE+TOFF_RTC_CR), RTC_CR_ALRBIE);
+		while((sil_rew_mem((uint32_t *)(TADR_RTC_BASE+TOFF_RTC_ISR)) & RTC_ISR_ALRBWF) == 0){
+			if( tick > RTC_TIMEOUT_VALUE){
+			    /* プロテクション設定 */
+				sil_wrw_mem((uint32_t *)(TADR_RTC_BASE+TOFF_RTC_WPR), 0xFF);
+				SVC_PERROR(sig_sem(RTCSEM));
+				return E_TMOUT;
+			}
+			dly_tsk(1);
+			tick++;
+		}
+		rtcalarmB_callback = NULL;
+	}
+    /* プロテクション設定 */
+	sil_wrw_mem((uint32_t *)(TADR_RTC_BASE+TOFF_RTC_WPR), 0xFF);
+	SVC_PERROR(sig_sem(RTCSEM));
+	return E_OK; 
+}
+
+/*
+ *  RTCアラーム設定値取得
+ *  parameter1 : parm: Pointer to Alarm structure
+ *  parameter2 : ptm: Pointer to struct tm2
+ *  return ERコード
+ */
+ER
+rtc_getalarm(RTC_Alarm_t *parm, struct tm2 *ptm, uint32_t Alarm)
+{
+	uint32_t tmparm = 0;
+	uint32_t subsecond = 0;
+
+	if(parm == NULL || ptm == NULL)
+		return E_PAR;
+	if(rtcerrorcode != 0)
+		return E_SYS;
+
+	SVC_PERROR(wai_sem(RTCSEM));
+	if(Alarm == RTC_ALARM_A){
+		/*
+		  ALARM-A レジスタ取得
+		 */
+		parm->alarm = RTC_ALARM_A;
+		tmparm = sil_rew_mem((uint32_t *)(TADR_RTC_BASE+TOFF_RTC_ALRMAR));
+		subsecond = sil_rew_mem((uint32_t *)(TADR_RTC_BASE+TOFF_RTC_ALRMASSR)) & RTC_ALRMASSR_SS;
+	}
+	else{
+		/*
+		  ALARM-B レジスタ取得
+		 */
+		parm->alarm = RTC_ALARM_B;
+		tmparm = sil_rew_mem((uint32_t *)(TADR_RTC_BASE+TOFF_RTC_ALRMBR));
+		subsecond = sil_rew_mem((uint32_t *)(TADR_RTC_BASE+TOFF_RTC_ALRMBSSR)) & RTC_ALRMBSSR_SS;
+	}
+
+	/*
+	 *  レジスタからパラメータに変換
+	 */
+	ptm->tm_hour = bcd2byte((uint8_t)((tmparm & (RTC_ALRMAR_HT | RTC_ALRMAR_HU)) >> 16));
+	ptm->tm_min  = bcd2byte((uint8_t)((tmparm & (RTC_ALRMAR_MNT | RTC_ALRMAR_MNU)) >> 8));
+	ptm->tm_sec = bcd2byte((uint8_t)(tmparm & (RTC_ALRMAR_ST | RTC_ALRMAR_SU)));
+	parm->subsecond = (uint32_t) subsecond;
+	parm->dayselect = (uint32_t)(tmparm & RTC_ALRMAR_WDSEL);
+	if(parm->dayselect == ALARMDAYSEL_DATE)
+		ptm->tm_mday = bcd2byte((uint8_t)((tmparm & (RTC_ALRMAR_DT | RTC_ALRMAR_DU)) >> 24));
+	else
+		ptm->tm_wday = bcd2byte((uint8_t)((tmparm & (RTC_ALRMAR_DT | RTC_ALRMAR_DU)) >> 24));
+
+	parm->alarmmask = (uint32_t)(tmparm & ALARMMASK_ALL);
+	SVC_PERROR(sig_sem(RTCSEM));
+	return E_OK;
+}
+
+/*
+ *  RTC WAKEUPタイマ初期化
+ *  parameter1 : parm: Pointer to wakeup structure
+ *  parameter2 : func: callback function
+ *  return ERコード
+ */
+ER
+rtc_wakeup_init(RTC_Wakeup_t *parm, void (*func)(void))
+{
+	uint32_t prer, isr;
+
+	if(parm == NULL)
+		return E_PAR;
+	parm->wakeuptimerPrescaler = (4 - (sil_rew_mem((uint32_t *)(TADR_RTC_BASE+TOFF_RTC_CR)) & RTC_CR_WUCKSEL));
+	prer = sil_rew_mem((uint32_t *)(TADR_RTC_BASE+TOFF_RTC_PRER));
+	parm->asynchPrescaler = ((prer >> 16) & 0x7f) + 1;
+	parm->synchPrescaler  = prer & 0xffff;
+
+	/* プロテクション解除 */
+	sil_wrw_mem((uint32_t *)(TADR_RTC_BASE+TOFF_RTC_WPR), 0xCA);
+	sil_wrw_mem((uint32_t *)(TADR_RTC_BASE+TOFF_RTC_WPR), 0x53);
+
+	sil_andw_mem((uint32_t *)(TADR_RTC_BASE+TOFF_RTC_CR), RTC_CR_WUTE);
+	isr  = sil_rew_mem((uint32_t *)(TADR_RTC_BASE+TOFF_RTC_ISR)) & RTC_ISR_INIT;
+	isr |= ~(RTC_ISR_WUTF | RTC_ISR_INIT);
+	sil_wrw_mem((uint32_t *)(TADR_RTC_BASE+TOFF_RTC_ISR), isr);
+	sil_wrw_mem((uint32_t *)(TADR_EXTI_BASE+TOFF_EXTI_PR), RTC_EXTI_LINE_WUPTIMER);
+	sil_orw_mem((uint32_t *)(TADR_RTC_BASE+TOFF_RTC_CR), RTC_CR_WUTIE);
+	/*
+	 *  EXTI WAKEUPLINE設定
+	 */
+	sil_orw_mem((uint32_t *)(TADR_EXTI_BASE+TOFF_EXTI_RTSR), RTC_EXTI_LINE_WUPTIMER);
+	sil_orw_mem((uint32_t *)(TADR_EXTI_BASE+TOFF_EXTI_IMR), RTC_EXTI_LINE_WUPTIMER);
+
+    /* プロテクション設定 */
+	sil_wrw_mem((uint32_t *)(TADR_RTC_BASE+TOFF_RTC_WPR), 0xFF);
+
+	rtcwakeup_callback = func;
+	return E_OK;
+}
+
+/*
+ *  RTC WAKEUP時間設定
+ *  parameter1 : parm: WAKEUP時間
+ *  return ERコード
+ */
+ER
+rtc_setup_wakeuptime(uint32_t time)
+{
+	uint32_t timeout = LSI_TIMEOUT_VALUE;
+	/*
+	 *  WAUPTIMER設定停止
+	 */
+	if((sil_rew_mem((uint32_t *)(TADR_RTC_BASE+TOFF_RTC_CR)) & RTC_CR_WUTE) != 0){
+		while((sil_rew_mem((uint32_t *)(TADR_RTC_BASE+TOFF_RTC_ISR)) & RTC_ISR_WUTWF) == 0){
+			timeout--;
+			if(timeout == 0)
+				return E_TMOUT;
+			sil_dly_nse(1000);
+		}
+	}
+	/* プロテクション解除 */
+	sil_wrw_mem((uint32_t *)(TADR_RTC_BASE+TOFF_RTC_WPR), 0xCA);
+	sil_wrw_mem((uint32_t *)(TADR_RTC_BASE+TOFF_RTC_WPR), 0x53);
+
+	sil_andw_mem((uint32_t *)(TADR_RTC_BASE+TOFF_RTC_CR), RTC_CR_WUTE);
+
+	if(time != 0 && time < 0xFFFF){
+		sil_wrw_mem((uint32_t *)(TADR_EXTI_BASE+TOFF_EXTI_PR), RTC_EXTI_LINE_WUPTIMER);
+		sil_wrw_mem((uint32_t *)(TADR_RTC_BASE+TOFF_RTC_WUTR), time);
+		sil_orw_mem((uint32_t *)(TADR_RTC_BASE+TOFF_RTC_CR), RTC_CR_WUTE);
+	}
+    /* プロテクション設定 */
+	sil_wrw_mem((uint32_t *)(TADR_RTC_BASE+TOFF_RTC_WPR), 0xFF);
+	return E_OK;
+}
+
+/*
+ *  SSRの取り出し
+ */
+uint32_t
+rtc_get_ssr(void)
+{
+	return sil_rew_mem((uint32_t *)(TADR_RTC_BASE+TOFF_RTC_SSR));
+}
+
+/*
+ *  RTC割込みハンドラ
+ */
+void rtc_handler(void)
+{
+	uint32_t tmp;
+
+	if((sil_rew_mem((uint32_t *)(TADR_RTC_BASE+TOFF_RTC_ISR)) & RTC_CR_ALRAE) != 0){
+		/*
+		 * ALARM-A割込み確認
+		 */
+		if((sil_rew_mem((uint32_t *)(TADR_RTC_BASE+TOFF_RTC_CR)) & RTC_CR_ALRAIE) != 0){
+			/*
+			 *  ALARM-Aコールバック
+			 */
+			if(rtcalarmA_callback != NULL)
+				rtcalarmA_callback();
+
+			/* プロテクション解除 */
+			sil_wrw_mem((uint32_t *)(TADR_RTC_BASE+TOFF_RTC_WPR), 0xCA);
+			sil_wrw_mem((uint32_t *)(TADR_RTC_BASE+TOFF_RTC_WPR), 0x53);
+			/*
+			 *  ALARM-A割込みクリア
+			 */
+			tmp = sil_rew_mem((uint32_t *)(TADR_RTC_BASE+TOFF_RTC_ISR)) & RTC_ISR_INIT;
+			sil_wrw_mem((uint32_t *)(TADR_RTC_BASE+TOFF_RTC_ISR), (~(RTC_ISR_ALRAF | RTC_ISR_INIT) | tmp));
+		    /* プロテクション設定 */
+			sil_wrw_mem((uint32_t *)(TADR_RTC_BASE+TOFF_RTC_WPR), 0xFF);
+		}
+	}
+	if((sil_rew_mem((uint32_t *)(TADR_RTC_BASE+TOFF_RTC_ISR)) & RTC_CR_ALRBE) != 0){
+		/*
+		 * ALARM-B割込み確認
+		 */
+		if((sil_rew_mem((uint32_t *)(TADR_RTC_BASE+TOFF_RTC_CR)) & RTC_CR_ALRBIE) != 0){
+			/*
+			 *  ALARM-Bコールバック
+			 */
+			if(rtcalarmB_callback != NULL)
+				rtcalarmB_callback();
+
+			/* プロテクション解除 */
+			sil_wrw_mem((uint32_t *)(TADR_RTC_BASE+TOFF_RTC_WPR), 0xCA);
+			sil_wrw_mem((uint32_t *)(TADR_RTC_BASE+TOFF_RTC_WPR), 0x53);
+			/*
+			 *  ALARM-B割込みクリア
+			 */
+			tmp = sil_rew_mem((uint32_t *)(TADR_RTC_BASE+TOFF_RTC_ISR)) & RTC_ISR_INIT;
+			sil_wrw_mem((uint32_t *)(TADR_RTC_BASE+TOFF_RTC_ISR), (~(RTC_ISR_ALRBF | RTC_ISR_INIT) | tmp));
+		    /* プロテクション設定 */
+			sil_wrw_mem((uint32_t *)(TADR_RTC_BASE+TOFF_RTC_WPR), 0xFF);
+		}
+	}
+	/*
+	 *  EXTI RTCペンディングクリア
+	 */
+	sil_wrw_mem((uint32_t *)(TADR_EXTI_BASE+TOFF_EXTI_PR), EXTI_PR_PR17);
+}
+
+/*
+ *  WAKEUP割込みハンドラ
+ */
+void wakeup_handler(void)
+{
+	uint32_t isr;
+
+	/* プロテクション解除 */
+	sil_wrw_mem((uint32_t *)(TADR_RTC_BASE+TOFF_RTC_WPR), 0xCA);
+	sil_wrw_mem((uint32_t *)(TADR_RTC_BASE+TOFF_RTC_WPR), 0x53);
+	/*
+	 *  WAKEUP TIMER停止
+	 */
+	sil_andw_mem((uint32_t *)(TADR_RTC_BASE+TOFF_RTC_CR), RTC_CR_WUTE);
+
+	/*
+ 	 *  WUTF flagクリア
+	 */
+	isr  = sil_rew_mem((uint32_t *)(TADR_RTC_BASE+TOFF_RTC_ISR)) & RTC_ISR_INIT;
+	isr |= ~(RTC_ISR_WUTF | RTC_ISR_INIT);
+	sil_wrw_mem((uint32_t *)(TADR_RTC_BASE+TOFF_RTC_ISR), isr);
+
+    /* プロテクション設定 */
+	sil_wrw_mem((uint32_t *)(TADR_RTC_BASE+TOFF_RTC_WPR), 0xFF);
+
+	/*
+	 *  EXTIの割込みクリア
+	 */
+	sil_wrw_mem((uint32_t *)(TADR_EXTI_BASE+TOFF_EXTI_PR), RTC_EXTI_LINE_WUPTIMER);
+
+	/*
+	 *  コールバック関数実行
+	 */
+	if(rtcwakeup_callback != NULL)
+		rtcwakeup_callback();
+}
+
+
+/*
+ *  WINDOW WATCH-DOGデータ保存領域
+ */
+static uint32_t mcount, mcounter, wdogcount;
+
+/*
+ *  WINDOW WATCH-DOG初期化
+ *  parameter1  port: WDOGポート番号
+ *  parameter2  hini: WDOGハンドラのポインタ
+ *  return 正常終了時 E_OK
+ */
+ER
+wdog_init(ID portid, WDOG_Init_t *hini)
+{
+	if(hini == NULL || portid != WDOG1_PORTID)
+		return E_PAR;
+	if(hini->Window > 127 || hini->Window < 64)
+		return E_PAR;
+	if(hini->Counter > 127 || hini->Counter < 64)
+		return E_PAR;
+
+	mcount    = hini->MCounter;
+	mcounter  = 0;
+	wdogcount = hini->Counter;
+	sil_orw_mem((uint32_t *)(TADR_RCC_BASE+TOFF_RCC_APB1ENR), RCC_APB1ENR_WWDGEN);
+	sil_wrw_mem((uint32_t *)(TADR_WWDG_BASE+TOFF_WWDG_CR), wdogcount);
+	if(mcount == 0)
+		sil_wrw_mem((uint32_t *)(TADR_WWDG_BASE+TOFF_WWDG_CFR), (WWDG_CFR_WDGTB | hini->Window));
+	else
+		sil_wrw_mem((uint32_t *)(TADR_WWDG_BASE+TOFF_WWDG_CFR), (WWDG_CFR_EWI | WWDG_CFR_WDGTB | hini->Window));
+	sil_wrw_mem((uint32_t *)(TADR_WWDG_BASE+TOFF_WWDG_CR), (WWDG_CR_WDGA | wdogcount));
+	return E_OK;
+}
+
+/*
+ *  WINDOW WATCH-DOG終了設定
+ *  parameter1  port: WDOGポート番号
+ *  return ERコード
+ */
+ER
+wdog_deinit(ID portid)
+{
+	if(portid != WDOG1_PORTID || wdogcount == 0)
+		return E_PAR;
+	sil_wrw_mem((uint32_t *)(TADR_WWDG_BASE+TOFF_WWDG_CR), wdogcount);
+	sil_andw_mem((uint32_t *)(TADR_RCC_BASE+TOFF_RCC_APB1ENR), RCC_APB1ENR_WWDGEN);
+	wdogcount = 0;
+	return E_OK;
+}
+
+/*
+ *  WINDOW WATCH-DOGリセット
+ *  parameter1  port: WDOGポート番号
+ *  return ERコード
+ */
+ER
+wdog_reset(ID portid)
+{
+	if(portid != WDOG1_PORTID || wdogcount == 0)
+		return E_PAR;
+	sil_wrw_mem((uint32_t *)(TADR_WWDG_BASE+TOFF_WWDG_CR), wdogcount);
+	mcounter = 0;
+	return E_OK;
+}
+
+/*
+ *  WINDOW WATCH-DOG割込みハンドラ
+ */
+void
+wdog_handler(void)
+{
+	uint32_t base = TADR_WWDG_BASE;
+
+	if((sil_rew_mem((uint32_t *)(base+TOFF_WWDG_CFR)) & WWDG_CFR_EWI) != 0
+			&& (sil_rew_mem((uint32_t *)(base+TOFF_WWDG_SR)) & WWDG_SR_EWIF) != 0){
+		sil_andw_mem((uint32_t *)(base+TOFF_WWDG_SR), WWDG_SR_EWIF);
+		if(mcounter++ < mcount)
+			sil_wrw_mem((uint32_t *)(base+TOFF_WWDG_CR), wdogcount);
+	}
+}
+
+
+/*
+ *  LED接続ポート
+ *
+ *  拡張I/OボードのLED1-3はプログラマブル入出力ポート0に
+ *  にインバータを介して接続されている．
+ */
+
+typedef struct gio_confstruct
+{
+	uint32_t    clkbit;
+	uint32_t    giobase;
+	uint32_t    pinpos;
+	uint32_t    pinpp;
+} gio_conftype;
+
+#if defined(TOPPERS_STM32F7_DISCOVERY)
+static const gio_conftype led_confdata[] = {
+	{ RCC_AHB1ENR_GPIOIEN, TADR_GPIOI_BASE, PINPOSITION1, GPIO_PULLUP}
+};
+#elif defined(TOPPERS_STM32F769_DISCOVERY)
+static const gio_conftype led_confdata[] = {
+	{ RCC_AHB1ENR_GPIOJEN, TADR_GPIOJ_BASE, PINPOSITION13, GPIO_PULLUP},
+	{ RCC_AHB1ENR_GPIOJEN, TADR_GPIOJ_BASE, PINPOSITION5, GPIO_PULLUP}
+};
+#elif defined(TOPPERS_STM32F723_DISCOVERY)
+static const gio_conftype led_confdata[] = {
+	{ RCC_AHB1ENR_GPIOAEN, TADR_GPIOA_BASE, PINPOSITION7, GPIO_PULLUP},
+	{ RCC_AHB1ENR_GPIOBEN, TADR_GPIOB_BASE, PINPOSITION1, GPIO_PULLUP}
+};
+#else
+static const gio_conftype led_confdata[] = {
+	{ RCC_AHB1ENR_GPIOBEN, TADR_GPIOB_BASE, PINPOSITION0, GPIO_PULLUP},
+	{ RCC_AHB1ENR_GPIOBEN, TADR_GPIOB_BASE, PINPOSITION7, GPIO_PULLUP},
+	{ RCC_AHB1ENR_GPIOBEN, TADR_GPIOB_BASE, PINPOSITION14, GPIO_PULLUP}
+};
+#endif
+#define NUM_LED   (sizeof(led_confdata)/sizeof(gio_conftype))
+
+/*
+ *  LED接続ポート初期化
+ */ 
+void
+led_init(intptr_t exinf)
+{
+	const gio_conftype *pled = &led_confdata[0];
+	GPIO_Init_t GPIO_Init_Data;
+	uint32_t i;
+
+	for(i = 0 ; i < NUM_LED ; pled++, i++){
+		sil_orw_mem((uint32_t *)(TADR_RCC_BASE+TOFF_RCC_AHB1ENR), pled->clkbit);
+		/* モード設定 */
+		GPIO_Init_Data.mode      = GPIO_MODE_OUTPUT;
+		/* プルアップ プロダウン設定 */
+		GPIO_Init_Data.pull      = pled->pinpp;
+		/* 出力モード設定 */
+		GPIO_Init_Data.otype     = GPIO_OTYPE_PP;
+        /* スピード設定 */
+		GPIO_Init_Data.speed     = GPIO_SPEED_HIGH;
+		gpio_setup(pled->giobase, &GPIO_Init_Data, pled->pinpos);
+
+		/* 消灯 */
+		sil_wrw_mem((uint32_t *)(pled->giobase+TOFF_GPIO_BSRR), (1 << pled->pinpos)<<16);
+	}
+}
+
+/*
+ *  LED接続ポート読み出し
+ */
+uint_t
+led_in(void)
+{
+	const gio_conftype *pled = &led_confdata[0];
+	uint32_t data, i;
+
+	for(i = 0, data = 0 ; i < NUM_LED ; pled++, i++){
+		if((sil_rew_mem((uint32_t *)(pled->giobase+TOFF_GPIO_IDR)) & (1<<(pled->pinpos))) != 0)
+			data |= (1<<i);
+	}
+	return data;
+}
+
+/*
+ *  LED接続ポート書き込み
+ */ 
+void
+led_out(unsigned int led_data)
+{
+	const gio_conftype *pled = &led_confdata[0];
+	uint32_t reg1, reg2, i;
+
+	/* 設定値はLED接続ビット以外は変更しない */
+	for(i = 0 ; i < NUM_LED ; pled++, i++){
+		reg1 = reg2 = 0;
+		if((led_data & (1<<i)) != 0)
+			reg2 = 1 << pled->pinpos;
+		else
+			reg1 = 1 << pled->pinpos;
+
+		/* 書き込みデータを生成して書き込み */
+		sil_wrw_mem((uint32_t *)(pled->giobase+TOFF_GPIO_BSRR), (reg1<<16) | reg2);
+	}
+}
+
+/*
+ * LEDとスイッチの個別設定・読み込み関数群
+ */
+
+/*
+ *  LEDの状態保存用変数
+ */	
+unsigned int LedState;
+
+
+/*
+ *  LED点灯制御
+ */
+void 
+set_led_state(unsigned int led, unsigned char state){
+	if (state == ON) {
+		LedState = LedState | led;
+	} else {
+		LedState = LedState & ~led;
+	}
+	led_out(LedState);
+}
+
+
+#if defined(TOPPERS_STM32F7_DISCOVERY)
+#define TADR_PSW_BASE   TADR_GPIOI_BASE
+#define PSWGIOPEN       RCC_AHB1ENR_GPIOIEN
+#define	PSW_PIN         PINPOSITION11
+#elif defined(TOPPERS_STM32F769_DISCOVERY) || defined(TOPPERS_STM32F723_DISCOVERY)
+#define TADR_PSW_BASE   TADR_GPIOA_BASE
+#define PSWGIOPEN       RCC_AHB1ENR_GPIOAEN
+#define	PSW_PIN         PINPOSITION0
+#else
+#define TADR_PSW_BASE   TADR_GPIOC_BASE
+#define PSWGIOPEN       RCC_AHB1ENR_GPIOCEN
+#define	PSW_PIN         PINPOSITION13
+#endif
+
+/*
+ * PUSHスイッチ接続ポート初期化
+ */
+void
+switch_push_init(intptr_t exinf)
+{
+	GPIO_Init_t GPIO_Init_Data;
+	volatile uint32_t temp;
+
+	/* 入力ポートに設定 */
+	/* Enable the BUTTON Clock */
+	sil_orw_mem((uint32_t *)(TADR_RCC_BASE+TOFF_RCC_AHB1ENR), PSWGIOPEN);
+	temp = sil_rew_mem((uint32_t *)(TADR_RCC_BASE+TOFF_RCC_AHB1ENR));
+	(void)(temp);
+	/* モード設定 */
+	GPIO_Init_Data.mode      = GPIO_MODE_IT_FALLING;
+	/* プルアップ プロダウン設定 */
+	GPIO_Init_Data.pull      = GPIO_NOPULL;
+	gpio_setup(TADR_PSW_BASE, &GPIO_Init_Data, PSW_PIN);
+}
+
+/*
+ * PUSHスイッチコールバック関数設定
+ */
+void setup_sw_func(intptr_t exinf)
+{
+	exti_func[PSW_PIN] = (void (*)(void))exinf;
+}
+
+/*
+ * EXTI0割込みハンドラ
+ */
+void
+exti0_handler(void)
+{
+	uint32_t istatus = sil_rew_mem((uint32_t *)(TADR_EXTI_BASE+TOFF_EXTI_PR));
+
+	if((istatus & (1<<0)) != 0){
+		if(exti_func[0] != NULL)
+			(exti_func[0])();
+	}
+    sil_wrw_mem((uint32_t *)(TADR_EXTI_BASE+TOFF_EXTI_PR), istatus);
+}
+
+/*
+ * EXTI9-5割込みハンドラ
+ */
+void
+exti9_handler(void)
+{
+	/* EXTI line interrupt detected */
+	uint32_t istatus = sil_rew_mem((uint32_t *)(TADR_EXTI_BASE+TOFF_EXTI_PR));
+	uint32_t i;
+	for(i = 0 ; i < NUM_EXTI9_FUNC ; i++){
+		if((istatus & (1<<(i+EXTI9_BASENO))) != 0){
+			if(exti_func[i+EXTI9_BASENO] != NULL)
+				(exti_func[i+EXTI9_BASENO])();
+		}
+	}
+    sil_wrw_mem((uint32_t *)(TADR_EXTI_BASE+TOFF_EXTI_PR), istatus);
+}
+
+/*
+ * EXTI15-10割込みハンドラ
+ */
+void
+exti15_handler(void)
+{
+	/* EXTI line interrupt detected */
+	uint32_t istatus = sil_rew_mem((uint32_t *)(TADR_EXTI_BASE+TOFF_EXTI_PR));
+	uint32_t i;
+	for(i = 0 ; i < NUM_EXTI15_FUNC ; i++){
+		if((istatus & (1<<(i+EXTI15_BASENO))) != 0){
+			if(exti_func[i+EXTI15_BASENO] != NULL)
+				(exti_func[i+EXTI15_BASENO])();
+		}
+	}
+    sil_wrw_mem((uint32_t *)(TADR_EXTI_BASE+TOFF_EXTI_PR), istatus);
+}
+
+
+/*
+ * DIPSWの取出し
+ */
+uint_t
+switch_dip_sense(void)
+{
+	return dipsw_value;
+}
+
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/pdic/stm32f7xx/device.cfg
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/pdic/stm32f7xx/device.cfg	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/pdic/stm32f7xx/device.cfg	(revision 457)
@@ -0,0 +1,42 @@
+/*
+ *  @(#) $Id$
+ */
+
+/*
+ *  STM32F7-Discovery Deviceのシステムコンフィギュレーションファイル
+ */
+
+#include "device.h"
+
+ATT_INI({ TA_NULL, 0, led_init });
+ATT_INI({ TA_NULL, 0, switch_push_init });
+#if defined(TOPPERS_STM32F7_DISCOVERY) || defined(TOPPERS_STM32F769_DISCOVERY)
+ATT_INI({ TA_NULL, FMC_SDRAM_BANK1, sdram_init });
+#endif
+ATT_INI({ TA_NULL, 0, rtc_init });
+ATT_INI({ TA_NULL, 0, rtc_info_init });
+
+CRE_SEM(DMA2DSEM, {TA_TPRI, 1, 1 });
+CRE_SEM(DMA2DTRNSEM, {TA_TPRI, 0, 1 });
+CRE_SEM(RTCSEM, {TA_TPRI, 1, 1 });
+
+DEF_INH(INHNO_DMA2D, { TA_NULL, dma2d_handler });
+CFG_INT(INTNO_DMA2D, { TA_ENAINT | INTATR_DMA2D, INTPRI_DMA2D });
+
+DEF_INH(INHNO_ALARM, { TA_NULL, rtc_handler });
+CFG_INT(INTNO_ALARM, { TA_ENAINT | INTATR_ALARM, INTPRI_ALARM });
+
+DEF_INH(INHNO_RTCWUP, { TA_NULL, wakeup_handler });
+CFG_INT(INTNO_RTCWUP, { TA_ENAINT | INTATR_RTCWUP,  INTPRI_RTCWUP });
+
+DEF_INH(INHNO_EXTI9, { TA_NULL, exti9_handler });
+CFG_INT(INTNO_EXTI9, { TA_ENAINT | INTATR_EXTI9, INTPRI_EXTI9 });
+
+DEF_INH(INHNO_EXTI15, { TA_NULL, exti15_handler });
+CFG_INT(INTNO_EXTI15, { TA_ENAINT | INTATR_EXTI15, INTPRI_EXTI15 });
+
+#ifdef INHNO_SW1
+DEF_INH(INHNO_SW1, { TA_NULL, exti_handler });
+CFG_INT(INTNO_SW1, { TA_ENAINT | INTATR_SW1, INTPRI_SW1 });
+#endif
+
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/pdic/stm32f7xx/device.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/pdic/stm32f7xx/device.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/pdic/stm32f7xx/device.h	(revision 457)
@@ -0,0 +1,825 @@
+/*
+ *  TOPPERS/ASP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Advanced Standard Profile Kernel
+ * 
+ *  Copyright (C) 2008-2011 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ *  Copyright (C) 2015-2019 by TOPPERS PROJECT Educational Working Group.
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+/*
+ * STM32F7XX用デバイスドライバの外部宣言
+ */
+
+#ifndef _DEVICE_H_
+#define _DEVICE_H_
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/*
+ *  TOPPERS BASE PLATFORM情報
+ */
+#define TOPPERS_BASE_PLATFORM_STF7
+
+/*
+ *  バージョン情報
+ */
+#define	TPLATFORM_PRVER 0x1041		/* プラットフォームのバージョン番号 */
+
+/*
+ * ピン設定
+ */
+
+#define PINPOSITION0    0
+#define PINPOSITION1    1
+#define PINPOSITION2    2
+#define PINPOSITION3    3
+#define PINPOSITION4    4
+#define PINPOSITION5    5
+#define PINPOSITION6    6
+#define PINPOSITION7    7
+#define PINPOSITION8    8
+#define PINPOSITION9    9
+#define PINPOSITION10   10
+#define PINPOSITION11   11
+#define PINPOSITION12   12
+#define PINPOSITION13	13
+#define PINPOSITION14	14
+#define PINPOSITION15	15
+
+#define GPIO_PIN_0      (1<<PINPOSITION0)
+#define GPIO_PIN_1      (1<<PINPOSITION1)
+#define GPIO_PIN_2      (1<<PINPOSITION2)
+#define GPIO_PIN_3      (1<<PINPOSITION3)
+#define GPIO_PIN_4      (1<<PINPOSITION4)
+#define GPIO_PIN_5      (1<<PINPOSITION5)
+#define GPIO_PIN_6      (1<<PINPOSITION6)
+#define GPIO_PIN_7      (1<<PINPOSITION7)
+#define GPIO_PIN_8      (1<<PINPOSITION8)
+#define GPIO_PIN_9      (1<<PINPOSITION9)
+#define GPIO_PIN_10     (1<<PINPOSITION10)
+#define GPIO_PIN_11     (1<<PINPOSITION11)
+#define GPIO_PIN_12     (1<<PINPOSITION12)
+#define GPIO_PIN_13     (1<<PINPOSITION13)
+#define GPIO_PIN_14     (1<<PINPOSITION14)
+#define GPIO_PIN_15     (1<<PINPOSITION15)
+
+/*
+ *  GPIOモードパラメータ
+ */
+#define GPIO_MODE_INPUT     0x00000000	/* Input Floating Mode */
+#define GPIO_MODE_OUTPUT    0x00000001	/* Output Mode */
+#define GPIO_MODE_AF        0x00000002	/* Alternate Function Mode */
+#define GPIO_MODE_ANALOG    0x00000003	/* Analog Mode  */
+
+/*
+ *  GPIO-EXTIモードパラメータ
+ */
+#define GPIO_MODE_IT_RISING             0x10110000	/* External Interrupt Mode with Rising edge trigger detection */
+#define GPIO_MODE_IT_FALLING            0x10210000	/* External Interrupt Mode with Falling edge trigger detection */
+#define GPIO_MODE_IT_RISING_FALLING     0x10310000	/* External Interrupt Mode with Rising/Falling edge trigger detection */
+#define GPIO_MODE_EVT_RISING            0x10120000	/* External Event Mode with Rising edge trigger detection */
+#define GPIO_MODE_EVT_FALLING           0x10220000	/* External Event Mode with Falling edge trigger detection */
+#define GPIO_MODE_EVT_RISING_FALLING    0x10320000	/* External Event Mode with Rising/Falling edge trigger detection */
+
+/*
+ *  GPIOアウトプット設定パラメータ
+ */
+#define GPIO_OTYPE_PP       0x0
+#define GPIO_OTYPE_OD       0x1
+
+/*
+ *  GPIOアウトプット最大周波数パラメータ
+ */
+#define GPIO_SPEED_LOW      0x00000000	/* Low speed     */
+#define GPIO_SPEED_MEDIUM   0x00000001	/* Medium speed  */
+#define GPIO_SPEED_FAST     0x00000002	/* Fast speed    */
+#define GPIO_SPEED_HIGH     0x00000003	/* High speed    */
+
+/*
+ *  GPIOプルアップダウンパラメータ
+ */
+#define GPIO_NOPULL         0x00000000	/* No Pull-up or Pull-down activation  */
+#define GPIO_PULLUP         0x00000001	/* Pull-up activation                  */
+#define GPIO_PULLDOWN       0x00000002	/* Pull-down activation                */
+
+/*
+ *  GPIO初期化設定
+ */
+typedef struct
+{
+    uint32_t    mode;		/* specifies the operating mode for the selected pins. */
+	uint32_t    pull;		/* specifies the Pull-up or Pull-Down */
+	uint32_t    otype;		/* output type */
+	uint32_t    speed;		/* speed for the selected pins. */
+	uint32_t    alternate;	/* alternate for the selected pins. */
+}GPIO_Init_t;
+
+typedef struct {
+	uint32_t    base;
+	uint32_t    pinmap;
+} GPIO_Init_Table;
+
+
+extern void gpio_setup(uint32_t base, GPIO_Init_t *init, uint32_t pin);
+
+/*
+ *  SDRAMアドレス
+ */
+#define SDRAM_ADDRESS   0xC0000000
+
+/*
+ *  FMC SDRAM Bank
+ */
+#define FMC_SDRAM_BANK1 0
+#define FMC_SDRAM_BANK2 1
+
+extern void sdram_init(intptr_t exinf);
+
+
+/*
+ *  キャッシュ制御関数
+ */
+#define CACHE_LINE_SIZE	    32	/* cortex-m7 cacle line size */
+
+extern void invalidatedcache_by_addr(uint8_t *addr, int32_t dsize);
+extern void flushdcache_by_addr(uint8_t *addr, int32_t dsize);
+extern void flushinvalidatedcache_by_addr(uint8_t *addr, int32_t dsize);
+
+
+/*
+ *  DMAステータス定義
+ */
+#define DMA_STATUS_BUSY         0x00000001	/* BUSY */
+#define DMA_STATUS_READY_HMEM0  0x00000002	/* DMA Mem0 Half process success */
+#define DMA_STATUS_READY_HMEM1  0x00000004	/* DMA Mem1 Half process success */
+#define DMA_STATUS_READY_MEM0   0x00000008	/* DMA Mem0 process success      */
+#define DMA_STATUS_READY_ERROR  0x00000100	/* DMA Error end */
+
+/*
+ *  DMAストリームID定義
+ */
+#define DMA1STM0_SID            (0)
+#define DMA1STM1_SID            (1)
+#define DMA1STM2_SID            (2)
+#define DMA1STM3_SID            (3)
+#define DMA1STM4_SID            (4)
+#define DMA1STM5_SID            (5)
+#define DMA1STM6_SID            (6)
+#define DMA1STM7_SID            (7)
+#define DMA2STM0_SID            (8+0)
+#define DMA2STM1_SID            (8+1)
+#define DMA2STM2_SID            (8+2)
+#define DMA2STM3_SID            (8+3)
+#define DMA2STM4_SID            (8+4)
+#define DMA2STM5_SID            (8+5)
+#define DMA2STM6_SID            (8+6)
+#define DMA2STM7_SID            (8+7)
+
+/*
+ *  DMAエラー定義
+ */ 
+#define DMA_ERROR_NONE          0x00000000	/* No error */
+#define DMA_ERROR_TE            0x00000001	/* Transfer error */
+#define DMA_ERROR_FE            0x00000002	/* FIFO error */
+#define DMA_ERROR_DME           0x00000004	/* Direct Mode error */
+#define DMA_ERROR_TIMEOUT       0x00000020	/* Timeout error */
+
+/*
+ *  DMAチャネル定義
+ */
+#define DMA_CHANNEL_0           0x00000000	/* DMA Channel 0 */
+#define DMA_CHANNEL_1           0x02000000	/* DMA Channel 1 */
+#define DMA_CHANNEL_2           0x04000000	/* DMA Channel 2 */
+#define DMA_CHANNEL_3           0x06000000	/* DMA Channel 3 */
+#define DMA_CHANNEL_4           0x08000000	/* DMA Channel 4 */
+#define DMA_CHANNEL_5           0x0A000000	/* DMA Channel 5 */
+#define DMA_CHANNEL_6           0x0C000000	/* DMA Channel 6 */
+#define DMA_CHANNEL_7           0x0E000000	/* DMA Channel 7 */
+#if defined(TOPPERS_STM32F767_NUCLEO144) || defined(TOPPERS_STM32F769_DISCOVERY)
+#define DMA_CHANNEL_8           0x10000000	/* DMA Channel 8 */
+#define DMA_CHANNEL_9           0x12000000	/* DMA Channel 9 */
+#define DMA_CHANNEL_10          0x14000000	/* DMA Channel 10*/
+#define DMA_CHANNEL_11          0x16000000	/* DMA Channel 11*/
+#define DMA_CHANNEL_12          0x18000000	/* DMA Channel 12*/
+#define DMA_CHANNEL_13          0x1A000000	/* DMA Channel 13*/
+#define DMA_CHANNEL_14          0x1C000000	/* DMA Channel 14*/
+#define DMA_CHANNEL_15          0x1E000000	/* DMA Channel 15*/
+#endif
+
+/*
+ *  DMA転送方向定義
+ */
+#define DMA_PERIPH_TO_MEMORY    0x00000000		/* Peripheral to memory direction */
+#define DMA_MEMORY_TO_PERIPH    DMA_SxCR_DIR_0	/* Memory to peripheral direction */
+#define DMA_MEMORY_TO_MEMORY    DMA_SxCR_DIR_1	/* Memory to memory direction     */
+
+/*
+ *  DMAペリフェラル増加モード定義
+ */
+#define DMA_PINC_ENABLE         DMA_SxCR_PINC	/* Peripheral increment mode enable  */
+#define DMA_PINC_DISABLE        0x00000000		/* Peripheral increment mode disable */
+
+/*
+ *  DMAメモリ増加モード定義
+ */ 
+#define DMA_MINC_ENABLE         DMA_SxCR_MINC	/* Memory increment mode enable  */
+#define DMA_MINC_DISABLE        0x00000000		/* Memory increment mode disable */
+
+/*
+ *  DMAペリフェラル・データ・サイズ定義
+ */
+#define DMA_PDATAALIGN_BYTE     0x00000000		/* Peripheral data alignment: Byte     */
+#define DMA_PDATAALIGN_HALFWORD DMA_SxCR_PSIZE_0	/* Peripheral data alignment: HalfWord */
+#define DMA_PDATAALIGN_WORD     DMA_SxCR_PSIZE_1	/* Peripheral data alignment: Word     */
+
+/*
+ *  DMAメモリ・データ・サイズ定義
+ */
+#define DMA_MDATAALIGN_BYTE     0x00000000		/* Memory data alignment: Byte     */
+#define DMA_MDATAALIGN_HALFWORD DMA_SxCR_MSIZE_0	/* Memory data alignment: HalfWord */
+#define DMA_MDATAALIGN_WORD     DMA_SxCR_MSIZE_1	/* Memory data alignment: Word     */
+
+/*
+ *  DMAモード定義
+ */
+#define DMA_NORMAL              0x00000000		/* Normal mode                  */
+#define DMA_CIRCULAR            DMA_SxCR_CIRC	/* Circular mode                */
+#define DMA_PFCTRL              DMA_SxCR_PFCTRL	/* Peripheral flow control mode */
+
+/*
+ *  DMA優先度レベル定義
+ */
+#define DMA_PRIORITY_LOW        0x00000000		/* Priority level: Low       */
+#define DMA_PRIORITY_MEDIUM     DMA_SxCR_PL_0	/* Priority level: Medium    */
+#define DMA_PRIORITY_HIGH       DMA_SxCR_PL_1	/* Priority level: High      */
+#define DMA_PRIORITY_VERY_HIGH  DMA_SxCR_PL		/* Priority level: Very High */
+
+/*
+ *  DMA FIFOモード定義
+ */
+#define DMA_FIFOMODE_DISABLE    0x00000000		/* FIFO mode disable */
+#define DMA_FIFOMODE_ENABLE     DMA_SxFCR_DMDIS	/* FIFO mode enable  */
+
+/*
+ *  DMA FIFOスレッシュホールドレベル定義
+ */
+#define DMA_FIFO_THRESHOLD_1QUARTERFULL  0x00000000			/* FIFO threshold 1 quart full configuration  */
+#define DMA_FIFO_THRESHOLD_HALFFULL      DMA_SxFCR_FTH_0	/* FIFO threshold half full configuration     */
+#define DMA_FIFO_THRESHOLD_3QUARTERSFULL DMA_SxFCR_FTH_1	/* FIFO threshold 3 quarts full configuration */
+#define DMA_FIFO_THRESHOLD_FULL          DMA_SxFCR_FTH		/* FIFO threshold full configuration          */
+
+/*
+ *  DMAメモリバースト定義
+ */
+#define DMA_MBURST_SINGLE       0x00000000
+#define DMA_MBURST_INC4         DMA_SxCR_MBURST_0
+#define DMA_MBURST_INC8         DMA_SxCR_MBURST_1
+#define DMA_MBURST_INC16        DMA_SxCR_MBURST
+
+/*
+ *  DMAペリフェラルバースト定義
+ */
+#define DMA_PBURST_SINGLE       0x00000000
+#define DMA_PBURST_INC4         DMA_SxCR_PBURST_0
+#define DMA_PBURST_INC8         DMA_SxCR_PBURST_1
+#define DMA_PBURST_INC16        DMA_SxCR_PBURST
+
+/*
+ *  DMA初期化構造体定義
+ */
+typedef struct
+{
+	uint32_t              Channel;		/* Specifies the channel used for the specified stream. */
+	uint32_t              Direction;	/* Specifies if the data will be transferred from memory to peripheral */
+	uint32_t              PeriphInc;	/* Specifies whether the Peripheral address register should be incremented or not. */
+	uint32_t              MemInc;		/* Specifies whether the memory address register should be incremented or not. */
+	uint32_t              PeriphDataAlignment;	/* Specifies the Peripheral data width. */
+	uint32_t              MemDataAlignment;		/* Specifies the Memory data width. */
+	uint32_t              Mode;			/* Specifies the operation mode of the DMAy Streamx. */
+	uint32_t              Priority;		/* Specifies the software priority for the DMAy Streamx. */
+	uint32_t              FIFOMode;		/* Specifies if the FIFO mode or Direct mode will be used for the specified stream. */
+	uint32_t              FIFOThreshold;		/* Specifies the FIFO threshold level. */
+	uint32_t              MemBurst;		/* Specifies the Burst transfer configuration for the memory transfers. */
+	uint32_t              PeriphBurst;	/* Specifies the Burst transfer configuration for the peripheral transfers. */
+}DMA_Init_t;
+
+/*
+ *  DMAハンドラ構造体定義
+ */
+typedef struct __DMA_Handle_t DMA_Handle_t;
+struct __DMA_Handle_t
+{
+	uint32_t              base;
+	DMA_Init_t            Init;			/* DMA communication parameters */
+	uint32_t              sdid;			/* stream dma id */
+	volatile uint32_t     status;		/* DMA status */
+	void                  (*xfercallback)(DMA_Handle_t * hdma);		/* DMA transfer complete callback */
+	void                  (*xferhalfcallback)(DMA_Handle_t * hdma);	/* DMA Half transfer complete callback */
+	void                  (*xferm1callback)(DMA_Handle_t * hdma);	/* DMA transfer complete Memory1 callback */
+	void                  (*errorcallback)(DMA_Handle_t * hdma);	/* DMA transfer error callback */
+	volatile uint32_t     ErrorCode;	/* DMA Error code */
+	void                  *localdata;	/* DMA local data */
+};
+
+extern ER dma_init(DMA_Handle_t *hdma);
+extern ER dma_deinit(DMA_Handle_t *hdma);
+extern ER dma_start(DMA_Handle_t *hdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t DataLength);
+extern ER dma_end(DMA_Handle_t *hdma);
+extern void dma_inthandler(DMA_Handle_t *hdma);
+extern void stream_dma_isr(intptr_t exinf);
+
+
+/*
+ *  DMAステータス定義
+ */
+#define DMA2D_STATUS_BUSY       0x00000001	/* BUSY */
+#define DMA2D_STATUS_TCOMP      0x00000002	/* DMA2D transfar process success */
+#define DMA2D_STATUS_CCOMP      0x00000004	/* DMA2D CLUT Transfer process success */
+#define DMA2D_STATUS_ERROR      0x00000100	/* DMA2D Error end */
+
+/*
+ *  DMA2Dエラーコード定義
+ */
+#define DMA2D_ERROR_NONE        0x00000000	/* No error             */
+#define DMA2D_ERROR_TE          0x00000001	/* Transfer error       */
+#define DMA2D_ERROR_CE          0x00000002	/* Configuration error  */
+#define DMA2D_ERROR_TIMEOUT     0x00000020	/* Timeout error        */
+
+/*
+ *  DMA2Dモード定義
+ */
+#define DMA2D_M2M               0x00000000	/* DMA2D memory to memory transfer mode */
+#define DMA2D_M2M_PFC           0x00010000	/* DMA2D memory to memory with pixel format conversion transfer mode */
+#define DMA2D_M2M_BLEND         0x00020000	/* DMA2D memory to memory with blending transfer mode */
+#define DMA2D_R2M               0x00030000	/* DMA2D register to memory transfer mode */
+
+/*
+ *  DMA2Dカラーモード定義
+ */
+#define DMA2D_ARGB8888          0x00000000	/* ARGB8888 DMA2D color mode */
+#define DMA2D_RGB888            0x00000001	/* RGB888 DMA2D color mode   */
+#define DMA2D_RGB565            0x00000002	/* RGB565 DMA2D color mode   */
+#define DMA2D_ARGB1555          0x00000003	/* ARGB1555 DMA2D color mode */
+#define DMA2D_ARGB4444          0x00000004	/* ARGB4444 DMA2D color mode */
+
+/*
+ *  DMA2D入力カラー定義
+ */
+#define CM_ARGB8888             0x00000000	/* ARGB8888 color mode */
+#define CM_RGB888               0x00000001	/* RGB888 color mode */
+#define CM_RGB565               0x00000002	/* RGB565 color mode */
+#define CM_ARGB1555             0x00000003	/* ARGB1555 color mode */
+#define CM_ARGB4444             0x00000004	/* ARGB4444 color mode */
+#define CM_L8                   0x00000005	/* L8 color mode */
+#define CM_AL44                 0x00000006	/* AL44 color mode */
+#define CM_AL88                 0x00000007	/* AL88 color mode */
+#define CM_L4                   0x00000008	/* L4 color mode */
+#define CM_A8                   0x00000009	/* A8 color mode */
+#define CM_A4                   0x0000000A	/* A4 color mode */
+
+/*
+ *  DMA2Dアルファモード定義
+ */
+#define DMA2D_NO_MODIF_ALPHA    0x00000000	/* No modification of the alpha channel value */
+#define DMA2D_REPLACE_ALPHA     0x00000001	/* Replace original alpha channel value by programmed alpha value */
+#define DMA2D_COMBINE_ALPHA     0x00000002	/* Replace original alpha channel value by programmed alpha value
+                                                                with original alpha channel value */
+/*
+ *  DMA2D CLUT CM定義
+ */
+#define DMA2D_CCM_ARGB8888      0x00000000	/* ARGB8888 DMA2D C-LUT color mode */
+#define DMA2D_CCM_RGB888        0x00000001	/* RGB888 DMA2D C-LUT color mode   */
+
+#if defined(TOPPERS_STM32F767_NUCLEO144) || defined(TOPPERS_STM32F769_DISCOVERY)
+/*
+ *  DMA2Dアルファインバート定義
+ */
+#define DMA2D_REGULAR_ALPHA     0x00000000		/* No modification of the alpha channel value */
+#define DMA2D_INVERTED_ALPHA    DMA2D_OPFCCR_AI	/* Invert the alpha channel value */                                  
+
+/*
+ *  DMA2D RBスワップ定義
+ */
+#define DMA2D_RB_REGULAR        0x00000000		/* Select regular mode (RGB or ARGB) */
+#define DMA2D_RB_SWAP           DMA2D_OPFCCR_RBS/* Select swap mode (BGR or ABGR) */
+#endif
+
+/*
+ *  DMA2Dレイヤーの数
+ */
+#define MAX_DMA2D_LAYER  2
+
+/*
+ *  DMA2Dステート定義
+ */
+#define DMA2D_STATE_RESET       0	/* DMA2D not yet initialized or disabled       */
+#define DMA2D_STATE_READY       1	/* Peripheral Initialized and ready for use    */
+#define DMA2D_STATE_BUSY        2	/* an internal process is ongoing              */
+#define DMA2D_STATE_TIMEOUT     3	/* Timeout state                               */
+#define DMA2D_STATE_ERROR       4	/* DMA2D state error                           */
+#define DMA2D_STATE_SUSPEND     5	/* DMA2D process is suspended                  */
+
+/*
+ *  DMA2D入力構造体定義
+ */
+typedef struct
+{
+	uint32_t              Mode;				/* configures the DMA2D transfer mode. */
+	uint32_t              ColorMode;		/* configures the color format of the output image. */
+	uint32_t              OutputOffset;		/* Specifies the Offset value. */
+#if defined(TOPPERS_STM32F767_NUCLEO144) || defined(TOPPERS_STM32F769_DISCOVERY)
+    uint32_t              AlphaInverted;	/* Select regular or inverted alpha value for the output pixel format converter. */
+    uint32_t              RedBlueSwap;		/* Select regular mode (RGB or ARGB) or swap mode (BGR or ABGR) */
+#endif /* DMA2D_OPFCCR_RBS */
+} DMA2D_Init_t;
+
+/*
+ *  DMA2Dレイヤー構造体定義
+ */
+typedef struct
+{
+	uint32_t               InputOffset;		/* configures the DMA2D foreground offset. */
+	uint32_t               InputColorMode;	/* configures the DMA2D foreground color mode . */
+	uint32_t               AlphaMode;		/* configures the DMA2D foreground alpha mode. */
+	uint32_t               InputAlpha;		/* Specifies the DMA2D foreground alpha value and color value in case of A8 or A4 color mode. */
+} DMA2D_LayerCfg_t;
+
+/*
+ *  DMA2Dハンドラ構造体定義
+ */
+typedef struct __DMA2D_Handle_t DMA2D_Handle_t;
+struct __DMA2D_Handle_t
+{
+	uint32_t               base;
+	DMA2D_Init_t           Init;										/* DMA2D communication parameters */
+	volatile uint32_t      status;										/* DMA2D status */
+	void                   (* xfercallback)(DMA2D_Handle_t * hdma2d);	/* DMA2D transfer complete callback */
+	void                   (* errorcallback)(DMA2D_Handle_t * hdma2d);	/* DMA2D transfer error callback */
+	DMA2D_LayerCfg_t       LayerCfg[MAX_DMA2D_LAYER];					/* DMA2D Layers parameters */
+	uint32_t               ErrorCode;									/* DMA2D Error code */
+};
+
+
+#define INHNO_DMA2D     IRQ_VECTOR_DMA2D
+#define INTNO_DMA2D     IRQ_VECTOR_DMA2D
+
+#define INTPRI_DMA2D     -7        /* 割込み優先度 */
+#define INTATR_DMA2D     0         /* 割込み属性 */
+
+extern ER dma2d_init(DMA2D_Handle_t *hdma2d);
+extern ER dma2d_start(DMA2D_Handle_t *hdma2d, uint32_t pdata, uint32_t DstAddress, uint32_t Width, uint32_t Height);
+extern ER dma2d_waittransfar(DMA2D_Handle_t *hdma2d, uint32_t Timeout);
+extern ER dma2d_configlayer(DMA2D_Handle_t *hdma2d, uint32_t LayerIdx);
+extern void dma2d_inthandler(DMA2D_Handle_t *hdma);
+extern void dma2d_handler(void);
+
+
+/*
+ *  RTCアラーム定義
+ */
+#define RTC_ALARM_A     RTC_CR_ALRAE
+#define RTC_ALARM_B     RTC_CR_ALRBE
+
+/*
+ *  RTC日付、ウィークディ定義
+ */ 
+#define ALARMDAYSEL_DATE    0x00000000
+#define ALARMDAYSEL_WEEKDAY 0x40000000
+
+/*
+ *  RTCマスク定義
+ */ 
+#define ALARMMASK_NONE      0x00000000
+#define ALARMMASK_DATESEL   RTC_ALRMAR_MSK4
+#define ALARMMASK_HOURS     RTC_ALRMAR_MSK3
+#define ALARMMASK_MINUTES   RTC_ALRMAR_MSK2
+#define ALARMMASK_SECONDS   RTC_ALRMAR_MSK1
+#define ALARMMASK_ALL       (RTC_ALRMAR_MSK1 | RTC_ALRMAR_MSK2 | RTC_ALRMAR_MSK3 | RTC_ALRMAR_MSK4)
+
+/*
+ *  RTCサブセカンドアラームマッチ定義
+ */
+#define ALARMSSMASK_ALL     0x00000000	/* All Alarm SS fields are masked. */
+#define ALARMSSMASK_SS14_1  0x01000000	/* SS[0]がマッチでアラーム */
+#define ALARMSSMASK_SS14_2  0x02000000	/* SS[1:0]がマッチでアラーム */
+#define ALARMSSMASK_SS14_3  0x03000000	/* SS[2-0]がマッチでアラーム */
+#define ALARMSSMASK_SS14_4  0x04000000	/* SS[3-0]がマッチでアラーム */
+#define ALARMSSMASK_SS14_5  0x05000000	/* SS[4-0]がマッチでアラーム */
+#define ALARMSSMASK_SS14_6  0x06000000	/* SS[5-0]がマッチでアラーム */
+#define ALARMSSMASK_SS14_7  0x07000000	/* SS[6-0]がマッチでアラーム */
+#define ALARMSSMASK_SS14_8  0x08000000	/* SS[7-0]がマッチでアラーム */
+#define ALARMSSMASK_SS14_9  0x09000000	/* SS[8-0]がマッチでアラーム */
+#define ALARMSSMASK_SS14_10 0x0A000000	/* SS[9-0]がマッチでアラーム */
+#define ALARMSSMASK_SS14_11 0x0B000000	/* SS[10-0]がマッチでアラーム */
+#define ALARMSSMASK_SS14_12 0x0C000000	/* SS[11-0]がマッチでアラーム */
+#define ALARMSSMASK_SS14_13 0x0D000000	/* SS[12-0]がマッチでアラーム */
+#define ALARMSSMASK_SS14    0x0E000000	/* SS[13-0]がマッチでアラーム */
+#define ALARMSSMASK_NONE    0x0F000000	/* SS[14-0]がマッチでアラーム */
+
+#define RTC_ERROR_LSI   0x00000001
+#define RTC_ERROR_LSE   0x00000002
+#define RTC_ERROR_RTC   0x00000004
+
+#define INHNO_ALARM     IRQ_VECTOR_RTC_ALARM
+#define INTNO_ALARM     IRQ_VECTOR_RTC_ALARM
+
+#define INTPRI_ALARM     -11       /* 割込み優先度 */
+#define INTATR_ALARM     0         /* 割込み属性 */
+
+#define INHNO_RTCWUP    IRQ_VECTOR_RTC_WKUP	/* 割込みハンドラ番号 */
+#define INTNO_RTCWUP    IRQ_VECTOR_RTC_WKUP	/* 割込み番号 */
+#define INTPRI_RTCWUP   -8          /* 割込み優先度 */
+#define INTATR_RTCWUP   TA_EDGE     /* 割込み属性 */
+
+/*
+ *  日時設定用の構造体を定義
+ */
+struct tm2 {
+  int	tm_sec;			/* 秒 */
+  int	tm_min;			/* 分 */
+  int	tm_hour;		/* 時 */
+  int	tm_mday;		/* 月中の日 */
+  int	tm_mon;			/* 月 */
+  int	tm_year;		/* 年 */
+  int	tm_wday;		/* 曜日 */
+  int	tm_yday;		/* 年中の日 */
+  int	tm_isdst;
+};
+
+/*
+ *  RTCアラーム構造体
+ */
+typedef struct
+{
+	uint32_t            alarm;				/* アラーム選択 */
+	uint32_t            alarmmask;			/* アラームマスク設定 */
+	uint32_t            subsecondmask;		/* アラームサブセカンドマスク */
+	uint32_t            dayselect;			/* アラーム日付設定 */
+	uint32_t            subsecond;			/* アラームサブセカンド */
+	void                (*callback)(void);	/* アラームコールバック */
+}RTC_Alarm_t;
+
+/*
+ *  RTC-WAKEUP構造体
+ */
+typedef struct
+{
+	uint8_t	            wakeuptimerPrescaler;	/* WAKEUP TIMERプリスケーラ */
+	uint8_t             asynchPrescaler;	/* 非同期プリスケーラ */
+	uint16_t            synchPrescaler;		/* 非同期プリスケーラ */
+}RTC_Wakeup_t;
+
+
+extern uint32_t rtcerrorcode;
+
+extern void rtc_init(intptr_t exinf);
+extern ER rtc_set_time(struct tm2 *pt);
+extern ER rtc_get_time(struct tm2 *pt);
+extern ER rtc_setalarm(RTC_Alarm_t *parm, struct tm2 *ptm);
+extern ER rtc_stopalarm(uint32_t Alarm);
+extern ER rtc_getalarm(RTC_Alarm_t *parm, struct tm2 *ptm, uint32_t Alarm);
+extern ER rtc_wakeup_init(RTC_Wakeup_t *parm, void (*func)(void));
+extern ER rtc_setup_wakeuptime(uint32_t time);
+extern uint32_t rtc_get_ssr(void);
+extern void rtc_handler(void);
+extern void wakeup_handler(void);
+extern void rtc_info_init(intptr_t exinf);
+
+
+/*
+ *  WINDOW-WDOGドライバ
+ */
+#define WDOG1_PORTID        1
+#define NUM_WDOGPORT        1
+
+typedef struct __WDOG_Init_t
+{
+	uint32_t              Window;			/* WDOG Window設定 0x40-0x7F */
+	uint32_t              Counter;			/* WDOG ダウンカウンタ設定 0x40-0x7F 0x7F */
+	uint32_t              MCounter;			/* WDOG More Counter */
+} WDOG_Init_t;
+
+extern ER wdog_init(ID portid, WDOG_Init_t *hwini);
+extern ER wdog_deinit(ID portid);
+extern ER wdog_reset(ID portod);
+extern void wdog_handler(void);
+
+
+/*
+ *  USBのローカル設定
+ */
+#define ENABLE_FS_BASE1 (TADR_RCC_BASE+TOFF_RCC_AHB1ENR)
+#define ENABLE_FS_VAL1  RCC_AHB1ENR_GPIOAEN
+#define TADR_FS_G1_BASE TADR_GPIOA_BASE
+#define FS_DM_PINNO     11
+#define FS_DP_PINNO     12
+#if defined(TOPPERS_STM32F7_DISCOVERY)
+#define ENABLE_FS_BASE2 (TADR_RCC_BASE+TOFF_RCC_AHB1ENR)
+#define ENABLE_FS_VAL2  RCC_AHB1ENR_GPIODEN
+#define TADR_FS_G2_BASE TADR_GPIOD_BASE
+#define FS_ID_PINNO     10
+#define FS_POWERSW_PINO 5
+#define FS_EVBUS_PINNO  FS_POWERSW_PINO
+#elif defined(TOPPERS_STM32F723_DISCOVERY)
+#define ENABLE_FS_BASE2 (TADR_RCC_BASE+TOFF_RCC_AHB1ENR)
+#define ENABLE_FS_VAL2  RCC_AHB1ENR_GPIOGEN
+#define TADR_FS_G2_BASE TADR_GPIOG_BASE
+#define FS_G2_PORT_TYPE GPIO_OTYPE_OD
+#define FS_POWERSW_PINO 8
+#else
+#define ENABLE_FS_BASE2 (TADR_RCC_BASE+TOFF_RCC_AHB1ENR)
+#define ENABLE_FS_VAL2  RCC_AHB1ENR_GPIOGEN
+#define TADR_FS_G2_BASE TADR_GPIOG_BASE
+#define FS_ID_PINNO     10
+#define FS_VBUS_PINNO   9
+#define FS_POWERSW_PINO 6
+#if !defined(TOPPERS_STM32F769_DISCOVERY)
+#define FS_EVBUS_PINNO  FS_POWERSW_PINO
+#endif
+#endif
+
+#if defined(TOPPERS_STM32F769_DISCOVERY)
+#define ENABLE_HS_VAL1  RCC_AHB1ENR_GPIOIEN
+#define TADR_HS_G1_BASE TADR_GPIOI_BASE
+#define HS_DIR_PINNNO   11
+#else
+#define ENABLE_HS_VAL1  RCC_AHB1ENR_GPIOCEN
+#define TADR_HS_G1_BASE TADR_GPIOC_BASE
+#define HS_DIR_PINNNO   2
+#endif
+
+#define ENABLE_HS_BASE  (TADR_RCC_BASE+TOFF_RCC_AHB1ENR)
+#define ENABLE_HS_VAL2  RCC_AHB1ENR_GPIOBEN
+#define ENABLE_HS_VAL3  RCC_AHB1ENR_GPIOHEN
+#define ENABLE_HS_VAL4  RCC_AHB1ENR_GPIOAEN
+#define ENABLE_HS_VAL5  RCC_AHB1ENR_GPIOCEN
+
+#define TOFF_RCC_USBFS  TOFF_RCC_AHB2ENR
+#define RCC_USBFSEN     RCC_AHB2ENR_OTGFSEN
+#define TOFF_RCC_USBHS  TOFF_RCC_AHB1ENR
+#define RCC_USBHSEN     RCC_AHB1ENR_OTGHSEN
+#define RCC_USBHSUPEN   RCC_AHB1ENR_OTGHSULPIEN
+#define TOFF_RCC_SYSFG  TOFF_RCC_APB2ENR
+#define RCC_SYSGFGEN    RCC_APB2ENR_SYSCFGEN
+
+#define EXTI_IMR_BASE   (TADR_EXTI_BASE+TOFF_EXTI_IMR)
+#define EXTI_PR_BASE    (TADR_EXTI_BASE+TOFF_EXTI_PR)
+
+/*
+ *  EMACのローカル設定
+ */
+#if defined(TOPPERS_STM32F7_DISCOVERY)
+#define RMII_MII_TXD1_PORT       TADR_GPIOG_BASE
+#define RMII_MII_TXD1_PIN        14
+#else
+#define RMII_MII_TXD1_CLOCK      RCC_AHB1ENR_GPIOBEN
+#endif
+
+/*
+ *  ポートのLED接続ビット
+ */
+#define LED01           (1<<0)
+#define LED02           (1<<1)
+#define LED03           (1<<2)
+#define LED04           (1<<3)
+
+#define LED_MASK        (LED01 | LED02 | LED03 | LED04)
+
+/*
+ *  LEDとスイッチの状態マクロ
+ */
+#define ON              1     /* LEDやスイッチON状態             */
+#define OFF             0     /* LEDやスイッチOFF状態            */
+
+/*
+ *  DIPSW設定
+ */
+#define DSW1             0x01
+#define DSW2             0x02
+#define DSW3             0x04
+#define DSW4             0x08
+
+/*
+ *  LED接続ポート初期化
+ */ 
+extern void led_init(intptr_t exinf);
+
+/*
+ *  LED接続ポート読み出し
+ */
+uint_t led_in(void);
+
+/*
+ *  LED接続ポート書き込み
+ */ 
+void led_out(unsigned int led_data);
+
+/*
+ *  LEDとスイッチの個別設定・読み込み関数群
+ */
+extern void set_led_state(unsigned int led, unsigned char state);
+
+#define NUM_EXTI9_FUNC   5
+#define EXTI9_BASENO     5
+#define INHNO_EXTI9 IRQ_VECTOR_EXTI9_5	/* 割込みハンドラ番号 */
+#define INTNO_EXTI9 IRQ_VECTOR_EXTI9_5	/* 割込み番号 */
+#define INTPRI_EXTI9    -4			/* 割込み優先度 */
+#define INTATR_EXTI9     0			/* 割込み属性 */
+
+#define NUM_EXTI15_FUNC  6
+#define EXTI15_BASENO    10
+#define INHNO_EXTI15 IRQ_VECTOR_EXTI15_10	/* 割込みハンドラ番号 */
+#define INTNO_EXTI15 IRQ_VECTOR_EXTI15_10	/* 割込み番号 */
+#define INTPRI_EXTI15    -4			/* 割込み優先度 */
+#define INTATR_EXTI15    0			/* 割込み属性 */
+
+#if defined(TOPPERS_STM32F769_DISCOVERY) || defined(TOPPERS_STM32F723_DISCOVERY)
+#define INHNO_SW1   IRQ_VECTOR_EXTI0	/* 割込みハンドラ番号 */
+#define INTNO_SW1   IRQ_VECTOR_EXTI0	/* 割込み番号 */
+#define INTPRI_SW1  -4          /* 割込み優先度 */
+#define INTATR_SW1  TA_EDGE     /* 割込み属性 */
+#define NUM_EXTI_FUNC  1
+#define EXTI_BASENO    0
+#define exti_handler   exti0_handler
+#else
+#define NUM_EXTI_FUNC  6
+#define EXTI_BASENO    10
+#endif
+
+extern void (*exti_func[16])(void);
+
+/*
+ *  PSW接続ビット
+ */
+#define PSW1             0x00000001
+#define PSW_MASK         (PSW1)
+#define PSW_CHK_INTERVAL 10
+
+
+/*
+ *  PUSHスイッチ接続ポート初期化
+ */
+extern void switch_push_init(intptr_t exinf);
+
+/*
+ *  PUSHスイッチコールバック関数設定
+ */
+extern void setup_sw_func(intptr_t exinf);
+
+/*
+ *  EXTI割込みハンドラ
+ */
+extern void exti0_handler(void);
+extern void exti9_handler(void);
+extern void exti15_handler(void);
+
+/*
+ *  DIPSWの取出し
+ */
+uint_t switch_dip_sense(void);
+
+
+extern void device_info_init(intptr_t exinf);
+
+extern uint_t dipsw_value;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/pdic/stm32f7xx/dfsdm.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/pdic/stm32f7xx/dfsdm.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/pdic/stm32f7xx/dfsdm.c	(revision 457)
@@ -0,0 +1,1708 @@
+/*
+ *  TOPPERS/ASP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Advanced Standard Profile Kernel
+ * 
+ *  Copyright (C) 2008-2011 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ *  Copyright (C) 2015-2018 by TOPPERS PROJECT Educational Working Group.
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+/*
+ * 
+ *  DFSDMドライバ関数群
+ *
+ */
+#include <kernel.h>
+#include <t_syslog.h>
+#include <t_stdlib.h>
+#include "syssvc/serial.h"
+#include "syssvc/syslog.h"
+#include <target_syssvc.h>
+
+#include "device.h"
+#include "dfsdm.h"
+
+#define sil_orw_mem(a, b)		sil_wrw_mem((a), sil_rew_mem(a) | (b))
+#define sil_andw_mem(a, b)		sil_wrw_mem((a), sil_rew_mem(a) & ~(b))
+#define sil_modw_mem(a, b, c)	sil_wrw_mem((a), (sil_rew_mem(a) & (~b)) | (c))
+#define get_channelno(b)        (((b)-TADR_DFSDM1_BASE) / 0x20)
+
+/*
+ *  SAIポート定義
+ */
+#define SAI1_PORTID           1
+#define SAI2_PORTID           2
+
+/*
+ *  タイムアウト時間定義
+ */ 
+#define HAL_MAX_DELAY           0xFFFFFFFFU
+#define PLLI2S_TIMEOUT_VALUE    100			/* Timeout value fixed to 100 ms  */
+#define DFSDM_CKAB_TIMEOUT      5000
+
+/*
+ *  チャネル設定定義
+ */
+#define DFSDM_LSB_MASK          0x0000FFFF
+#define DFSDM1_CHANNEL_NUMBER   8
+
+/*
+ *  オーディオ周波数の定義
+ */
+#define AUDIO_FREQUENCY_44K     ((uint32_t)44100)
+#define AUDIO_FREQUENCY_22K     ((uint32_t)22050)
+#define AUDIO_FREQUENCY_11K     ((uint32_t)11025)
+
+/*
+ *  チャネル情報
+ */
+static volatile uint32_t       Dfsdm1ChannelCounter = 0;
+static DFSDM_Channel_Handle_t* Dfsdm1ChannelHandle[DFSDM1_CHANNEL_NUMBER] = {NULL};
+
+
+/*
+ *  DFSDMクロックコンフィグレーション
+ *  parameter1  port:SAI PORTID
+ *  parameter2  AudioFreq: Audio周波数
+ *  parameter3  Params: 補助パラメータポインタ
+ */
+void
+dfsdm_clockconfig(ID port, uint32_t AudioFreq)
+{
+	uint32_t PLLI2SN, PLLI2SQ, PLLI2SDivQ;
+	uint32_t tick = 0;
+
+	/*
+	 *  AUDIO周波数からPLL設定値の取得
+	 */
+	if((AudioFreq == AUDIO_FREQUENCY_11K) || (AudioFreq == AUDIO_FREQUENCY_22K) || (AudioFreq == AUDIO_FREQUENCY_44K)){
+		/* Configure PLLI2S prescalers */
+		/* PLLI2S_VCO: VCO_429M
+		I2S_CLK(first level) = PLLI2S_VCO/PLLI2SQ = 429/2 = 214.5 Mhz
+		I2S_CLK_x = I2S_CLK(first level)/PLLI2SDIVQ = 214.5/19 = 11.289 Mhz */
+		PLLI2SN = 429;
+		PLLI2SQ = 2;
+		PLLI2SDivQ = 19;
+	}
+	else /* AUDIO_FREQUENCY_8K, AUDIO_FREQUENCY_16K, AUDIO_FREQUENCY_48K, AUDIO_FREQUENCY_96K */{
+		/* I2S clock config
+		PLLI2S_VCO: VCO_344M
+		I2S_CLK(first level) = PLLI2S_VCO/PLLI2SQ = 344/7 = 49.142 Mhz
+		I2S_CLK_x = I2S_CLK(first level)/PLLI2SDIVQ = 49.142/1 = 49.142 Mhz */
+		PLLI2SN = 344;
+		PLLI2SQ = 7;
+		PLLI2SDivQ = 1;
+	}
+
+	/*
+	 *  SAI1/2クロック設定
+	 */
+	if(port == SAI1_PORTID){
+		sil_modw_mem((uint32_t *)(TADR_RCC_BASE+TOFF_RCC_DCKCFGR1), RCC_DCKCFGR1_SAI1SEL, RCC_DCKCFGR1_SAI1SEL_0);
+	}
+	else{
+		sil_modw_mem((uint32_t *)(TADR_RCC_BASE+TOFF_RCC_DCKCFGR1), RCC_DCKCFGR1_SAI2SEL, RCC_DCKCFGR1_SAI2SEL_0);
+	}
+
+	/*
+	 *  PLLI2Sデゼーブル
+	 */
+	sil_andw_mem((uint32_t *)(TADR_RCC_BASE+TOFF_RCC_CR), RCC_CR_PLLI2SON);
+
+    /*
+	 *  PLLI2S停止待ち
+	 */
+	tick = 0;
+	while((sil_rew_mem((uint32_t *)(TADR_RCC_BASE+TOFF_RCC_CR)) & RCC_CR_PLLI2SRDY) != 0){
+		if(tick > PLLI2S_TIMEOUT_VALUE){
+			return;		/* タイムアウトエラー */
+		}
+		dly_tsk(1);
+		tick++;
+	}
+
+    /*
+	 *  PLLI2SSN/PLLI2SN値設定
+	 */
+	sil_modw_mem((uint32_t *)(TADR_RCC_BASE+TOFF_RCC_PLLI2SCFGR), (RCC_PLLI2SCFGR_PLLI2SN | RCC_PLLI2SCFGR_PLLI2SQ), ((PLLI2SN << 6) | (PLLI2SQ << 24)));
+
+	/*
+	 *  PLLI2SDIVQ設定
+	 */
+	sil_modw_mem((uint32_t *)(TADR_RCC_BASE+TOFF_RCC_DCKCFGR1), RCC_DCKCFGR1_PLLI2SDIVQ, (PLLI2SDivQ-1));
+
+	/*
+	 *  PLLI2Sイネーブル
+	 */
+	sil_orw_mem((uint32_t *)(TADR_RCC_BASE+TOFF_RCC_CR), RCC_CR_PLLI2SON);
+
+    /*
+	 *  PLLI2S再開待ち
+	 */
+	tick = 0;
+	while((sil_rew_mem((uint32_t *)(TADR_RCC_BASE+TOFF_RCC_CR)) & RCC_CR_PLLI2SRDY) == 0){
+		if(tick > PLLI2S_TIMEOUT_VALUE){
+			return;		/* タイムアウトエラー */
+		}
+		dly_tsk(1);
+		tick++;
+	}
+}
+
+/*
+ *  DFSDMチャネル初期化
+ *  parameter1 hdfsc  DFSDMチャネルハンドラへのポインタ
+ *  return            正常終了時、E_OK
+ */
+ER dfsdm_channel_init(DFSDM_Channel_Handle_t *hdfsc)
+{
+	/*
+	 *  パラメータチェック
+	 */
+	if(hdfsc == NULL)
+		return E_PAR;
+	if((hdfsc->Init.OutClockActivation & DFSDM_MASK) != 0)
+		return E_PAR;
+	if(hdfsc->Init.InputMultiplexer != DFSDM_CHANNEL_EXTERNAL_INPUTS &&
+		hdfsc->Init.InputMultiplexer != DFSDM_CHANNEL_INTERNAL_REGISTER)
+		return E_PAR;
+	if(hdfsc->Init.InputDataPacking != DFSDM_CHANNEL_STANDARD_MODE &&
+		hdfsc->Init.InputDataPacking != DFSDM_CHANNEL_INTERLEAVED_MODE &&
+			hdfsc->Init.InputDataPacking != DFSDM_CHANNEL_DUAL_MODE)
+		return E_PAR;
+	if(hdfsc->Init.InputPins != DFSDM_CHANNEL_SAME_CHANNEL_PINS && 
+		hdfsc->Init.InputPins != DFSDM_CHANNEL_FOLLOWING_CHANNEL_PINS)
+		return E_PAR;
+	if(hdfsc->Init.SerialType != DFSDM_CHANNEL_SPI_RISING &&
+		hdfsc->Init.SerialType != DFSDM_CHANNEL_SPI_FALLING &&
+			hdfsc->Init.SerialType != DFSDM_CHANNEL_MANCHESTER_RISING &&
+				hdfsc->Init.SerialType != DFSDM_CHANNEL_MANCHESTER_FALLING)
+		return E_PAR;
+	if(hdfsc->Init.SerialSpiClock != DFSDM_CHANNEL_SPI_CLOCK_EXTERNAL &&
+		hdfsc->Init.SerialSpiClock != DFSDM_CHANNEL_SPI_CLOCK_INTERNAL &&
+			hdfsc->Init.SerialSpiClock != DFSDM_CHANNEL_SPI_CLOCK_INTERNAL_DIV2_FALLING &&
+				hdfsc->Init.SerialSpiClock != DFSDM_CHANNEL_SPI_CLOCK_INTERNAL_DIV2_RISING)
+		return E_PAR;
+	if(hdfsc->Init.AwdFilterOrder != DFSDM_CHANNEL_FASTSINC_ORDER &&
+		hdfsc->Init.AwdFilterOrder != DFSDM_CHANNEL_SINC1_ORDER &&
+			hdfsc->Init.AwdFilterOrder != DFSDM_CHANNEL_SINC2_ORDER &&
+				hdfsc->Init.AwdFilterOrder != DFSDM_CHANNEL_SINC3_ORDER)
+		return E_PAR;
+	if(hdfsc->Init.AwdOversampling < 1 || hdfsc->Init.AwdOversampling > 32)
+		return E_PAR;
+	if(hdfsc->Init.Offset < -8388608 || hdfsc->Init.Offset > 8388607)
+		return E_PAR;
+	if(hdfsc->Init.RightBitShift > 0x1F)
+		return E_PAR;
+
+	/*
+	 *  チャネル設定テーブルのチェック
+	 */
+	if(Dfsdm1ChannelHandle[get_channelno(hdfsc->base)] != NULL)
+		return E_OBJ;
+
+	/*
+	 *  グローバルDFSDM設定
+	 */
+	if(++Dfsdm1ChannelCounter == 1){
+		/*
+		 *  アウトプット・シリアルクロックソース設定
+		 */
+		sil_andw_mem((uint32_t *)(TADR_DFSDM1_CHANNEL0_BASE+TOFF_DFSDM_CHCFGR1), DFSDM_CHCFGR1_CKOUTSRC);
+		sil_orw_mem((uint32_t *)(TADR_DFSDM1_CHANNEL0_BASE+TOFF_DFSDM_CHCFGR1), hdfsc->Init.OutClockSelection);
+
+		/*
+		 *  クロック分周設定
+		 */
+		sil_andw_mem((uint32_t *)(TADR_DFSDM1_CHANNEL0_BASE+TOFF_DFSDM_CHCFGR1), DFSDM_CHCFGR1_CKOUTDIV);
+		if(hdfsc->Init.OutClockActivation == DFSDM_ENABLE)
+			sil_orw_mem((uint32_t *)(TADR_DFSDM1_CHANNEL0_BASE+TOFF_DFSDM_CHCFGR1), ((hdfsc->Init.OutClockDivider - 1) << 16));
+
+		/*
+		 *  DFSDMグローバルインターフェイス設定
+		 */
+		sil_orw_mem((uint32_t *)(TADR_DFSDM1_CHANNEL0_BASE+TOFF_DFSDM_CHCFGR1), DFSDM_CHCFGR1_DFSDMEN);
+	}
+
+	/*
+	 *  チャネル入力設定
+	 */
+	sil_andw_mem((uint32_t *)(hdfsc->base+TOFF_DFSDM_CHCFGR1), (DFSDM_CHCFGR1_DATPACK | DFSDM_CHCFGR1_DATMPX | DFSDM_CHCFGR1_CHINSEL));
+	sil_orw_mem((uint32_t *)(hdfsc->base+TOFF_DFSDM_CHCFGR1), (hdfsc->Init.InputMultiplexer | hdfsc->Init.InputDataPacking | hdfsc->Init.InputPins));
+
+	/*
+	 *  シリアルインターフェース設定
+	 */
+	sil_andw_mem((uint32_t *)(hdfsc->base+TOFF_DFSDM_CHCFGR1), (DFSDM_CHCFGR1_SITP | DFSDM_CHCFGR1_SPICKSEL));
+	sil_orw_mem((uint32_t *)(hdfsc->base+TOFF_DFSDM_CHCFGR1), (hdfsc->Init.SerialType | hdfsc->Init.SerialSpiClock));
+
+	/*
+	 *  アナログウォッチドッグ設定
+	 */
+	sil_andw_mem((uint32_t *)(hdfsc->base+TOFF_DFSDM_CHAWSCDR), (DFSDM_CHAWSCDR_AWFORD | DFSDM_CHAWSCDR_AWFOSR));
+	sil_orw_mem((uint32_t *)(hdfsc->base+TOFF_DFSDM_CHAWSCDR), (hdfsc->Init.AwdFilterOrder | ((hdfsc->Init.AwdOversampling - 1) << 16)));
+
+	/*
+	 *  チャネルオフセット、ライトビットシフト設定
+	 */
+	sil_andw_mem((uint32_t *)(hdfsc->base+TOFF_DFSDM_CHCFGR2), (DFSDM_CHCFGR2_OFFSET | DFSDM_CHCFGR2_DTRBS));
+	sil_orw_mem((uint32_t *)(hdfsc->base+TOFF_DFSDM_CHCFGR2), ((hdfsc->Init.Offset << 8) | (hdfsc->Init.RightBitShift << 3)));
+
+	/*
+	 *  DFSDMチャネル有効化
+	 */
+	sil_orw_mem((uint32_t *)(hdfsc->base+TOFF_DFSDM_CHCFGR1), DFSDM_CHCFGR1_CHEN);
+	hdfsc->state = DFSDM_CHANNEL_STATE_READY;
+
+	/*
+	 *  DFSDMチャネルテーブル設定
+	 */
+	Dfsdm1ChannelHandle[get_channelno(hdfsc->base)] = hdfsc;
+	return E_OK;
+}
+
+/*
+ *  DFSDMチャネル無効化
+ *  parameter1 hdfsc  DFSDMチャネルハンドラへのポインタ
+ *  return            正常終了時、E_OK
+ */
+ER
+dfsdm_channel_deinit(DFSDM_Channel_Handle_t *hdfsc)
+{
+	if(hdfsc == NULL)
+		return E_PAR;
+
+	/*
+	 *  DFSDMチャネルテーブルチェック
+	 */
+	if(Dfsdm1ChannelHandle[get_channelno(hdfsc->base)] == NULL){
+		return E_OBJ;
+	}
+
+	/*
+	 *  DFSDMチャネル無効化
+	 */
+	sil_andw_mem((uint32_t *)(hdfsc->base+TOFF_DFSDM_CHCFGR1), DFSDM_CHCFGR1_CHEN);
+
+	/*
+	 *  グローバルDFSDM無効化
+	 */
+	if(--Dfsdm1ChannelCounter == 0){
+		sil_andw_mem((uint32_t *)(TADR_DFSDM1_CHANNEL0_BASE+TOFF_DFSDM_CHCFGR1), DFSDM_CHCFGR1_DFSDMEN);
+	}
+
+	/*
+	 *  DFSDMチャネルテーブルリセット
+	 */
+	hdfsc->state = DFSDM_CHANNEL_STATE_RESET;
+	Dfsdm1ChannelHandle[get_channelno(hdfsc->base)] = (DFSDM_Channel_Handle_t *)NULL;
+	return E_OK;
+}
+
+
+/*
+ *  クロック・アブセンススタート
+ *  parameter1 hdfsc  DFSDMチャネルハンドラへのポインタ
+ *  return            正常終了時、E_OK
+ */
+ER
+dfsdm_channelCkabStart(DFSDM_Channel_Handle_t *hdfsc)
+{
+	uint32_t channel;
+	uint32_t tick = 0;
+
+	if(hdfsc == NULL)
+		return E_PAR;
+
+	if(hdfsc->state != DFSDM_CHANNEL_STATE_READY)	/* 状態判定 */
+		return E_OBJ;
+
+    /*
+	 *  チャネル番号取得
+	 */
+    channel = get_channelno(hdfsc->base);
+
+    /*
+	 *  クロックアブセンス・フラグクリア
+	 */
+    while((((sil_rew_mem((uint32_t *)(TADR_DFSDM1_FILTER0_BASE+TOFF_DFSDM_FLTISR)) & DFSDM_FLTISR_CKABF) >> (16 + channel)) & 1) != 0){
+		sil_wrw_mem((uint32_t *)(TADR_DFSDM1_FILTER0_BASE+TOFF_DFSDM_FLTICR), (1 << (16 + channel)));
+		if(tick++ > DFSDM_CKAB_TIMEOUT)
+			return E_TMOUT;	/* タイムアウト */
+		dly_tsk(1);
+    }
+
+	/*
+	 *  クロックアブセンス割込み設定
+	 */
+	sil_orw_mem((uint32_t *)(TADR_DFSDM1_FILTER0_BASE+TOFF_DFSDM_FLTCR2), DFSDM_FLTCR2_CKABIE);
+
+	/*
+	 *  クロックアブセンス・スタート
+	 */
+	sil_orw_mem((uint32_t *)(hdfsc->base+TOFF_DFSDM_CHCFGR1), DFSDM_CHCFGR1_CKABEN);
+	return E_OK;
+}
+
+/*
+ *  クロック・アブセンスストップ
+ *  parameter1 hdfsc  DFSDMチャネルハンドラへのポインタ
+ *  return            正常終了時、E_OK
+ */
+ER
+dfsdm_channelCkabStop(DFSDM_Channel_Handle_t *hdfsc)
+{
+	uint32_t channel;
+
+	if(hdfsc == NULL)
+		return E_PAR;
+
+	if(hdfsc->state != DFSDM_CHANNEL_STATE_READY)	/* 状態判定 */
+		return E_OBJ;
+
+	/*
+	 *  クロックアブセンス・停止
+	 */
+	sil_andw_mem((uint32_t *)(hdfsc->base+TOFF_DFSDM_CHCFGR1), DFSDM_CHCFGR1_CKABEN);
+
+	/*
+	 *  クロックアブセンス・フラグクリア
+	 */
+    channel = get_channelno(hdfsc->base);
+	sil_wrw_mem((uint32_t *)(TADR_DFSDM1_FILTER0_BASE+TOFF_DFSDM_FLTICR), (1 << (16 + channel)));
+
+	/*
+	 *  クロックアブセンス割込み停止
+	 */
+	sil_andw_mem((uint32_t *)(TADR_DFSDM1_FILTER0_BASE+TOFF_DFSDM_FLTCR2), DFSDM_FLTCR2_CKABIE);
+	return E_OK;
+}
+
+/*
+ *  ショート・サーキットスタート
+ *  parameter1 hdfsc       DFSDMチャネルハンドラへのポインタ
+ *  parameter2 Threshold   ショート・サーキット・スレッシュホールド(0-255)
+ *  parameter3 BreakSignal ブレークシグナル
+ *  return            正常終了時、E_OK
+ */
+ER
+dfsdm_channelScdStart(DFSDM_Channel_Handle_t *hdfsc, uint32_t Threshold, uint32_t BreakSignal)
+{
+	if(hdfsc == NULL)
+		return E_PAR;
+	if(Threshold > 255)
+		return E_PAR;
+	if(BreakSignal > 15)
+		return E_PAR;
+
+	if(hdfsc->state != DFSDM_CHANNEL_STATE_READY)	/* 状態判定 */
+		return E_OBJ;
+
+	/*
+	 *  ショート・サーキット割込み設定
+	 */
+	sil_orw_mem((uint32_t *)(TADR_DFSDM1_FILTER0_BASE+TOFF_DFSDM_FLTCR2), DFSDM_FLTCR2_SCDIE);
+
+	/*
+	 *  スレッシュホールド、ブレークシグナル設定
+	 */
+	sil_andw_mem((uint32_t *)(hdfsc->base+TOFF_DFSDM_CHAWSCDR), (DFSDM_CHAWSCDR_BKSCD | DFSDM_CHAWSCDR_SCDT));
+	sil_orw_mem((uint32_t *)(hdfsc->base+TOFF_DFSDM_CHAWSCDR), ((BreakSignal << 12) | Threshold));
+
+	/*
+	 *  ショート・サーキットスタート
+	 */
+	sil_orw_mem((uint32_t *)(hdfsc->base+TOFF_DFSDM_CHCFGR1), DFSDM_CHCFGR1_SCDEN);
+	return E_OK;
+}
+
+/*
+ *  ショート・サーキットストップ
+ *  parameter1 hdfsc  DFSDMチャネルハンドラへのポインタ
+ *  return            正常終了時、E_OK
+ */
+ER
+dfsdm_channelScdStop(DFSDM_Channel_Handle_t *hdfsc)
+{
+	uint32_t channel;
+
+	if(hdfsc == NULL)
+		return E_PAR;
+
+	if(hdfsc->state != DFSDM_CHANNEL_STATE_READY)	/* 状態判定 */
+		return E_OBJ;
+
+	/*
+	 *  ショート・サーキット停止
+	 */
+	sil_andw_mem((uint32_t *)(hdfsc->base+TOFF_DFSDM_CHCFGR1), DFSDM_CHCFGR1_SCDEN);
+
+    /*
+	 *  ショート・サーキットフラグクリア
+	 */
+	channel = get_channelno(hdfsc->base);
+	sil_wrw_mem((uint32_t *)(TADR_DFSDM1_FILTER0_BASE+TOFF_DFSDM_FLTICR), (1 << (24 + channel)));
+
+	/*
+	 *  ショート・サーキット割込み停止
+	 */
+	sil_andw_mem((uint32_t *)(TADR_DFSDM1_FILTER0_BASE+TOFF_DFSDM_FLTCR2), DFSDM_FLTCR2_SCDIE);
+	return E_OK;
+}
+
+/*
+ *  アナログ・ウォッチドッグ値取得
+ *  parameter1 hdfsc  DFSDMチャネルハンドラへのポインタ
+ *  return            アナログ・ウォッチドッグ値
+ */
+int16_t
+dfsdm_channelGetAwdValue(DFSDM_Channel_Handle_t *hdfsc)
+{
+	return (int16_t)sil_rew_mem((uint32_t *)(hdfsc->base+TOFF_DFSDM_CHWDATAR));
+}
+
+/*
+ *  チャネルオフセット値変更
+ *  parameter1 hdfsc  DFSDMチャネルハンドラへのポインタ
+ *  parameter2 Offset チャネルオフセット値(-8388608 - 8388607)
+ *  return            正常終了時、E_OK
+ */
+ER
+dfsdm_channelModifyOffset(DFSDM_Channel_Handle_t *hdfsc, int32_t Offset)
+{
+	if(hdfsc == NULL)
+		return E_PAR;
+	if(Offset < -8388608 || Offset > 8388607)
+		return E_PAR;
+
+	if(hdfsc->state != DFSDM_CHANNEL_STATE_READY)
+		return E_OBJ;
+
+	/*
+	 *  チャネルオフセット値設定
+	 */
+	sil_andw_mem((uint32_t *)(hdfsc->base+TOFF_DFSDM_CHCFGR2), DFSDM_CHCFGR2_OFFSET);
+	sil_orw_mem((uint32_t *)(hdfsc->base+TOFF_DFSDM_CHCFGR2), ((uint32_t) Offset << 8));
+	return E_OK;
+}
+
+
+/*
+ *  インジェクトチャネル数取得
+ */
+static uint32_t
+DFSDM_GetInjChannelsNbr(uint32_t Channels)
+{
+	uint32_t nbChannels = 0;
+	uint32_t tmp = (Channels & DFSDM_LSB_MASK);
+
+	/*
+	 *  チャネルビットフィールドから数を取得
+	 */
+	while(tmp != 0){
+		if((tmp & 1) != 0)
+			nbChannels++;
+		tmp >>= 1;
+	}
+	return nbChannels;
+}
+
+/*
+ *  レギュラー変換設定
+ */
+static void
+DFSDM_RegConvStart(DFSDM_Filter_Handle_t* hdfsf)
+{
+	/*
+	 *  レギュラートリガなら即スタート
+	 */
+	if(hdfsf->Init.RegTrigger == DFSDM_FILTER_SW_TRIGGER)
+		sil_orw_mem((uint32_t *)(hdfsf->base+TOFF_DFSDM_FLTCR1), DFSDM_FLTCR1_RSWSTART);
+	else{	/* シンクロナストリガの場合 */
+		/*
+		 *  DFSDMフィルターディゼーブル
+		 */
+		sil_andw_mem((uint32_t *)(hdfsf->base+TOFF_DFSDM_FLTCR1), DFSDM_FLTCR1_DFEN);
+
+		/*
+		 * RSYNCビットセット
+		 */
+		sil_orw_mem((uint32_t *)(hdfsf->base+TOFF_DFSDM_FLTCR1), DFSDM_FLTCR1_RSYNC);
+
+		/*
+		 *  DFSDMフィルターイネーブル
+		 */
+		sil_orw_mem((uint32_t *)(hdfsf->base+TOFF_DFSDM_FLTCR1), DFSDM_FLTCR1_DFEN);
+
+		/*
+		 *  インジェクト変換中なら再スタート
+		 */
+		if(hdfsf->state == DFSDM_FILTER_STATE_INJ){
+			if(hdfsf->Init.InjTrigger == DFSDM_FILTER_SW_TRIGGER)
+				sil_orw_mem((uint32_t *)(hdfsf->base+TOFF_DFSDM_FLTCR1), DFSDM_FLTCR1_JSWSTART);
+			hdfsf->InjConvRemaining = (hdfsf->Init.InjScanMode == DFSDM_ENABLE) ? hdfsf->InjectedChannelsNbr : 1;
+		}
+	}
+	/*
+	 *  DFSDMフィルター状態更新
+	 */
+	hdfsf->state = (hdfsf->state == DFSDM_FILTER_STATE_READY) ? DFSDM_FILTER_STATE_REG : DFSDM_FILTER_STATE_REG_INJ;
+}
+
+/*
+ *  レギュラー変換停止
+ */
+static void
+DFSDM_RegConvStop(DFSDM_Filter_Handle_t* hdfsf)
+{
+	/*
+	 *  DFSDMフィルターディゼーブル
+	 */
+	sil_andw_mem((uint32_t *)(hdfsf->base+TOFF_DFSDM_FLTCR1), DFSDM_FLTCR1_DFEN);
+
+	/*
+	 *  シンクロナストリガなら RSYNCビットリセット
+	 */
+	if(hdfsf->Init.RegTrigger == DFSDM_FILTER_SYNC_TRIGGER)
+		sil_andw_mem((uint32_t *)(hdfsf->base+TOFF_DFSDM_FLTCR1), DFSDM_FLTCR1_RSYNC);
+
+	/*
+	 *  DFSDMフィルターイネーブル
+	 */
+	sil_orw_mem((uint32_t *)(hdfsf->base+TOFF_DFSDM_FLTCR1), DFSDM_FLTCR1_DFEN);
+  
+	/*
+	 *  インジェクト変換中ならリスタート
+	 */
+	if(hdfsf->state == DFSDM_FILTER_STATE_REG_INJ){
+		if(hdfsf->Init.InjTrigger == DFSDM_FILTER_SW_TRIGGER)
+			sil_orw_mem((uint32_t *)(hdfsf->base+TOFF_DFSDM_FLTCR1), DFSDM_FLTCR1_JSWSTART);
+		hdfsf->InjConvRemaining = (hdfsf->Init.InjScanMode == DFSDM_ENABLE) ? hdfsf->InjectedChannelsNbr : 1;
+	}
+
+	/*
+	 *  DFSDMフィルター状態更新
+	 */
+	hdfsf->state = (hdfsf->state == DFSDM_FILTER_STATE_REG) ? DFSDM_FILTER_STATE_READY : DFSDM_FILTER_STATE_INJ;
+}
+
+/*
+ *  インジェクト変換設定
+ */
+static void
+DFSDM_InjConvStart(DFSDM_Filter_Handle_t* hdfsf)
+{
+	/*
+	 *  インジェクトトリガなら即スタート
+	 */
+	if(hdfsf->Init.InjTrigger == DFSDM_FILTER_SW_TRIGGER)
+		sil_orw_mem((uint32_t *)(hdfsf->base+TOFF_DFSDM_FLTCR1), DFSDM_FLTCR1_JSWSTART);
+	else{	/* 外部またはシンクロナストリガの場合 */
+		/*
+		 *  DFSDMフィルターディゼーブル
+		 */
+		sil_andw_mem((uint32_t *)(hdfsf->base+TOFF_DFSDM_FLTCR1), DFSDM_FLTCR1_DFEN);
+
+		/*
+		 *  シンクロナストリガならJSYNCビットセット
+		 *  外部トリガならJEXTENビットセット
+		 */
+		if(hdfsf->Init.InjTrigger == DFSDM_FILTER_SYNC_TRIGGER)
+			sil_orw_mem((uint32_t *)(hdfsf->base+TOFF_DFSDM_FLTCR1), DFSDM_FLTCR1_JSYNC);
+		else
+			sil_orw_mem((uint32_t *)(hdfsf->base+TOFF_DFSDM_FLTCR1), hdfsf->Init.InjExtTriggerEdge);
+
+		/*
+		 *  DFSDMフィルターイネーブル
+		 */
+		sil_orw_mem((uint32_t *)(hdfsf->base+TOFF_DFSDM_FLTCR1), DFSDM_FLTCR1_DFEN);
+
+		/* If regular conversion was in progress, restart it */
+		if(hdfsf->state == DFSDM_FILTER_STATE_REG && hdfsf->Init.RegTrigger == DFSDM_FILTER_SW_TRIGGER)
+			sil_orw_mem((uint32_t *)(hdfsf->base+TOFF_DFSDM_FLTCR1), DFSDM_FLTCR1_RSWSTART);
+	}
+
+	/*
+	 *  DFSDMフィルター状態更新
+	 */
+	hdfsf->state = (hdfsf->state == DFSDM_FILTER_STATE_READY) ? DFSDM_FILTER_STATE_INJ : DFSDM_FILTER_STATE_REG_INJ;
+}
+
+/*
+ *  インジェクト変換停止
+ */
+static void
+DFSDM_InjConvStop(DFSDM_Filter_Handle_t* hdfsf)
+{
+	/*
+	 *  DFSDMフィルターディゼーブル
+	 */
+	sil_andw_mem((uint32_t *)(hdfsf->base+TOFF_DFSDM_FLTCR1), DFSDM_FLTCR1_DFEN);
+
+	/*
+	 *  シンクロナストリガならJSYNCビットリセット
+	 *  外部トリガならJEXTENビットリセット
+	 */
+	if(hdfsf->Init.InjTrigger == DFSDM_FILTER_SYNC_TRIGGER)
+		sil_andw_mem((uint32_t *)(hdfsf->base+TOFF_DFSDM_FLTCR1), DFSDM_FLTCR1_JSYNC);
+	else if(hdfsf->Init.InjTrigger == DFSDM_FILTER_EXT_TRIGGER)
+		sil_andw_mem((uint32_t *)(hdfsf->base+TOFF_DFSDM_FLTCR1), DFSDM_FLTCR1_JEXTEN);
+
+	/*
+	 *  DFSDMフィルターイネーブル
+	 */
+	sil_orw_mem((uint32_t *)(hdfsf->base+TOFF_DFSDM_FLTCR1), DFSDM_FLTCR1_DFEN);
+
+	/*
+	 *  レギュラー変換中なら、リスタート
+	 */
+	if(hdfsf->state == DFSDM_FILTER_STATE_REG_INJ && hdfsf->Init.RegTrigger == DFSDM_FILTER_SW_TRIGGER)
+		sil_orw_mem((uint32_t *)(hdfsf->base+TOFF_DFSDM_FLTCR1), DFSDM_FLTCR1_RSWSTART);
+
+	/*
+	 *  インジェクト状態更新
+	 */
+	hdfsf->InjConvRemaining = (hdfsf->Init.InjScanMode == DFSDM_ENABLE) ? hdfsf->InjectedChannelsNbr : 1;
+
+	/*
+	 *  DFSDMフィルター状態更新
+	 */
+	hdfsf->state = (hdfsf->state == DFSDM_FILTER_STATE_INJ) ? DFSDM_FILTER_STATE_READY : DFSDM_FILTER_STATE_REG;
+}
+
+
+/*
+ *  DFSDMフィルター初期化
+ *  parameter1 hdfsc  DFSDMフィルターハンドラへのポインタ
+ *  return            正常終了時、E_OK
+ */
+ER
+dfsdm_filter_init(DFSDM_Filter_Handle_t *hdfsf)
+{
+	if(hdfsf == NULL)
+		return E_PAR;
+	if(hdfsf->Init.RegTrigger != DFSDM_FILTER_SW_TRIGGER && hdfsf->Init.RegTrigger != DFSDM_FILTER_SYNC_TRIGGER)
+		return E_PAR;
+	if((hdfsf->Init.RegFastMode & DFSDM_MASK) != 0)
+		return E_PAR;
+	if((hdfsf->Init.RegDmaMode & DFSDM_MASK) != 0)
+		return E_PAR;
+	if((hdfsf->Init.InjScanMode & DFSDM_MASK) != 0)
+		return E_PAR;
+	if((hdfsf->Init.InjDmaMode & DFSDM_MASK) != 0)
+		return E_PAR;
+	if(hdfsf->Init.FilterSincOrder != DFSDM_FILTER_FASTSINC_ORDER &&
+		hdfsf->Init.FilterSincOrder != DFSDM_FILTER_SINC1_ORDER &&
+			hdfsf->Init.FilterSincOrder != DFSDM_FILTER_SINC2_ORDER &&
+				hdfsf->Init.FilterSincOrder != DFSDM_FILTER_SINC3_ORDER &&
+					hdfsf->Init.FilterSincOrder != DFSDM_FILTER_SINC4_ORDER &&
+						hdfsf->Init.FilterSincOrder != DFSDM_FILTER_SINC5_ORDER)
+		return E_PAR;
+	if(hdfsf->Init.FilterOversampling < 1 || hdfsf->Init.FilterOversampling > 1024)
+		return E_PAR;
+	if(hdfsf->Init.FilterIntOversampling < 1 || hdfsf->Init.FilterIntOversampling > 256)
+		return E_PAR;
+
+	/*
+	 *  Check parameters compatibility */
+	if((hdfsf->base == TADR_DFSDM1_FILTER0_BASE) && 
+		((hdfsf->Init.RegTrigger  == DFSDM_FILTER_SYNC_TRIGGER) || 
+			(hdfsf->Init.InjTrigger == DFSDM_FILTER_SYNC_TRIGGER)))
+		return E_PAR;
+
+	/*
+	 *  DFSDMフィルターデフォルト設定
+	 */
+	hdfsf->RegularContMode     = DFSDM_CONTINUOUS_CONV_OFF;
+	hdfsf->InjectedChannelsNbr = 1;
+	hdfsf->InjConvRemaining    = 1;
+	hdfsf->errorcode           = DFSDM_FILTER_ERROR_NONE;
+
+	/*
+	 *  レギュラー変換設定
+	 */
+	sil_andw_mem((uint32_t *)(hdfsf->base+TOFF_DFSDM_FLTCR1), DFSDM_FLTCR1_RSYNC);
+	if(hdfsf->Init.RegFastMode == DFSDM_ENABLE)
+		sil_orw_mem((uint32_t *)(hdfsf->base+TOFF_DFSDM_FLTCR1), DFSDM_FLTCR1_FAST);
+	else
+		sil_andw_mem((uint32_t *)(hdfsf->base+TOFF_DFSDM_FLTCR1), DFSDM_FLTCR1_FAST);
+
+	if(hdfsf->Init.RegDmaMode == DFSDM_ENABLE)
+		sil_orw_mem((uint32_t *)(hdfsf->base+TOFF_DFSDM_FLTCR1), DFSDM_FLTCR1_RDMAEN);
+	else
+		sil_andw_mem((uint32_t *)(hdfsf->base+TOFF_DFSDM_FLTCR1), DFSDM_FLTCR1_RDMAEN);
+
+	/*
+	 *  インジェクト変換設定
+	 */
+	sil_andw_mem((uint32_t *)(hdfsf->base+TOFF_DFSDM_FLTCR1), (DFSDM_FLTCR1_JSYNC | DFSDM_FLTCR1_JEXTEN | DFSDM_FLTCR1_JEXTSEL));
+	if(hdfsf->Init.InjTrigger == DFSDM_FILTER_EXT_TRIGGER){
+		if((hdfsf->Init.InjExtTrigger & ~DFSDM_FLTCR1_JEXTSEL) != 0)
+			return E_PAR;
+		sil_orw_mem((uint32_t *)(hdfsf->base+TOFF_DFSDM_FLTCR1), hdfsf->Init.InjExtTrigger);
+	}
+
+	if(hdfsf->Init.InjScanMode == DFSDM_ENABLE)
+		sil_orw_mem((uint32_t *)(hdfsf->base+TOFF_DFSDM_FLTCR1), DFSDM_FLTCR1_JSCAN);
+	else
+		sil_andw_mem((uint32_t *)(hdfsf->base+TOFF_DFSDM_FLTCR1), DFSDM_FLTCR1_JSCAN);
+
+	if(hdfsf->Init.InjDmaMode == DFSDM_ENABLE)
+		sil_orw_mem((uint32_t *)(hdfsf->base+TOFF_DFSDM_FLTCR1), DFSDM_FLTCR1_JDMAEN);
+	else
+		sil_andw_mem((uint32_t *)(hdfsf->base+TOFF_DFSDM_FLTCR1), DFSDM_FLTCR1_JDMAEN);
+
+	/*
+	 *  フィルター用パラメータ設定
+	 */
+	sil_andw_mem((uint32_t *)(hdfsf->base+TOFF_DFSDM_FLTFCR), (DFSDM_FLTFCR_FORD | DFSDM_FLTFCR_FOSR | DFSDM_FLTFCR_IOSR));
+	sil_orw_mem((uint32_t *)(hdfsf->base+TOFF_DFSDM_FLTFCR), (hdfsf->Init.FilterSincOrder |
+                                    ((hdfsf->Init.FilterOversampling - 1) << 16) |
+                                  (hdfsf->Init.FilterIntOversampling - 1)));
+
+	/*
+	 *  DFSDMフィルター有効化
+	 */
+	sil_orw_mem((uint32_t *)(hdfsf->base+TOFF_DFSDM_FLTCR1), DFSDM_FLTCR1_DFEN);
+	hdfsf->state = DFSDM_FILTER_STATE_READY;
+	return E_OK;
+}
+
+/*
+ *  DFSDMフィルター無効化
+ *  parameter1 hdfsc  DFSDMフィルターハンドラへのポインタ
+ *  return            正常終了時、E_OK
+ */
+ER
+dfsdm_filter_deinit(DFSDM_Filter_Handle_t *hdfsf)
+{
+	if(hdfsf == NULL)
+		return E_PAR;
+
+	/*
+	 *  DFSDMフィルター有効化
+	 */
+	sil_andw_mem((uint32_t *)(hdfsf->base+TOFF_DFSDM_FLTCR1), DFSDM_FLTCR1_DFEN);
+	hdfsf->state = DFSDM_FILTER_STATE_RESET;
+	return E_OK;
+}
+
+/*
+ *  DFSDMフィルターレギュラー変換設定
+ *  parameter1 hdfsc    DFSDMフィルターハンドラへのポインタ
+ *  parameter2 Channel  チャネル番号
+ *  parameter3 ContMode コンティニュー有効無効設定
+ *  return              正常終了時、E_OK
+ */
+ER
+dfsdm_filter_config_reg(DFSDM_Filter_Handle_t *hdfsf, uint32_t Channel, uint32_t ContinuousMode)
+{
+	if(hdfsf == NULL)
+		return E_PAR;
+	if(Channel < DFSDM_CHANNEL_0 || Channel > DFSDM_CHANNEL_7)
+		return E_PAR;
+	if(ContinuousMode != DFSDM_CONTINUOUS_CONV_OFF && ContinuousMode != DFSDM_CONTINUOUS_CONV_ON)
+		return E_PAR;
+
+	/*
+	 *  状態判定
+	 */
+	if(hdfsf->state != DFSDM_FILTER_STATE_RESET && hdfsf->state != DFSDM_FILTER_STATE_ERROR){
+		/*
+		 *  レギュラー変換用、チャネルと継続モード設定
+		 */
+		sil_andw_mem((uint32_t *)(hdfsf->base+TOFF_DFSDM_FLTCR1), (DFSDM_FLTCR1_RCH | DFSDM_FLTCR1_RCONT));
+		if(ContinuousMode == DFSDM_CONTINUOUS_CONV_ON)
+			sil_orw_mem((uint32_t *)(hdfsf->base+TOFF_DFSDM_FLTCR1), (((Channel << 8) & DFSDM_FLTCR1_RCH) |
+                                                     DFSDM_FLTCR1_RCONT));
+		else
+			sil_orw_mem((uint32_t *)(hdfsf->base+TOFF_DFSDM_FLTCR1), ((Channel << 8) & DFSDM_FLTCR1_RCH));
+		hdfsf->RegularContMode = ContinuousMode;
+		return E_OK;
+	}
+	else
+		return E_OBJ;
+}
+
+/*
+ *  DFSDMフィルターインジェクト変換設定
+ *  parameter1 hdfsc    DFSDMフィルターハンドラへのポインタ
+ *  parameter2 Channel  チャネル番号
+ *  return              正常終了時、E_OK
+ */
+ER dfsdm_filter_config_inj(DFSDM_Filter_Handle_t *hdfsf, uint32_t Channel)
+{
+	if(hdfsf == NULL)
+		return E_PAR;
+
+	if(Channel == 0 || Channel > 0x000F00FF)
+		return E_PAR;
+
+	/*
+	 *  状態判定
+	 */
+	if(hdfsf->state != DFSDM_FILTER_STATE_RESET && hdfsf->state != DFSDM_FILTER_STATE_ERROR){
+		/*
+		 *  インジェクト変換用、チャネル設定
+		 */
+		sil_wrw_mem((uint32_t *)(hdfsf->base+TOFF_DFSDM_FLTJCHGR), (Channel & DFSDM_LSB_MASK));
+		hdfsf->InjectedChannelsNbr = DFSDM_GetInjChannelsNbr(Channel);
+		hdfsf->InjConvRemaining = (hdfsf->Init.InjScanMode == DFSDM_ENABLE) ? hdfsf->InjectedChannelsNbr : 1;
+		return E_OK;
+	}
+	else
+		return E_OBJ;
+}
+
+/*
+ *  DFSDMフィルターレギュラー変換DMAハーフ終了コールバック
+ */
+static void
+DFSDM_DMARegularHalfConvCplt(DMA_Handle_t *hdma)
+{
+	DFSDM_Filter_Handle_t* hdfsf = (DFSDM_Filter_Handle_t*) ((DMA_Handle_t*)hdma)->localdata;
+
+	/*
+	 *  コールバック関数の呼び出し
+	 */
+	if(hdfsf->regconvhalfcallback != NULL)
+		hdfsf->regconvhalfcallback(hdfsf);
+}
+
+/*
+ *  DFSDMフィルターレギュラー変換DMA終了コールバック
+ */
+static void
+DFSDM_DMARegularConvCplt(DMA_Handle_t *hdma)
+{
+	DFSDM_Filter_Handle_t* hdfsf = (DFSDM_Filter_Handle_t*) ((DMA_Handle_t*)hdma)->localdata;
+
+	/*
+	 *  コールバック関数の呼び出し
+	 */
+	if(hdfsf->regconvcallback != NULL)
+		hdfsf->regconvcallback(hdfsf);
+}
+
+/*
+ *  DFSDMフィルターインジェクト変換DMAハーフ終了コールバック
+ */
+static void
+DFSDM_DMAInjectedHalfConvCplt(DMA_Handle_t *hdma)
+{
+	DFSDM_Filter_Handle_t* hdfsf = (DFSDM_Filter_Handle_t*) ((DMA_Handle_t*)hdma)->localdata;
+
+	/*
+	 *  コールバック関数の呼び出し
+	 */
+	if(hdfsf->injconvhalfcallback != NULL)
+		hdfsf->injconvhalfcallback(hdfsf);
+}
+
+/*
+ *  DFSDMフィルターインジェクト変換DMA終了コールバック
+ */
+static void
+DFSDM_DMAInjectedConvCplt(DMA_Handle_t *hdma)
+{
+	DFSDM_Filter_Handle_t* hdfsf = (DFSDM_Filter_Handle_t*) ((DMA_Handle_t*)hdma)->localdata;
+
+	/*
+	 *  コールバック関数の呼び出し
+	 */
+	if(hdfsf->injconvcallback != NULL)
+		hdfsf->injconvcallback(hdfsf);
+}
+
+/*
+ *  DFSDMフィルターDMAエラーコールバック
+ */
+static void
+DFSDM_DMAError(DMA_Handle_t *hdma)
+{
+	DFSDM_Filter_Handle_t* hdfsf = (DFSDM_Filter_Handle_t*) ((DMA_Handle_t*)hdma)->localdata;
+
+	/*
+	 *  エラーコード設定
+	 */
+	hdfsf->errorcode = DFSDM_FILTER_ERROR_DMA;
+
+	/*
+	 *  DMAエラーコールバック
+	 */
+	if(hdfsf->errorcallback != NULL)
+		hdfsf->errorcallback(hdfsf);
+}
+
+
+/*
+ *  DFSDMフィルターレギュラー変換スタート(32BIT変換)
+ *  parameter1 hdfsc    DFSDMフィルターハンドラへのポインタ
+ *  paramter 2 pData    変換データ設定領域のポインタ
+ *  parameter3 Length   領域長
+ *  return              正常終了時、E_OK
+  */
+ER
+dfsdm_filterRegularStart(DFSDM_Filter_Handle_t *hdfsf, int32_t *pData, uint32_t Length)
+{
+	if(hdfsf == NULL || pData == NULL || Length == 0)
+		return E_PAR;
+
+	/*
+	 *  初期設定値の確認
+	 */
+	if((hdfsf->Init.RegTrigger == DFSDM_FILTER_SW_TRIGGER) && \
+          (hdfsf->RegularContMode == DFSDM_CONTINUOUS_CONV_OFF) && \
+          (hdfsf->hdmaReg->Init.Mode == DMA_NORMAL) && Length != 1)
+		return E_PAR;
+
+	if((hdfsf->Init.RegTrigger == DFSDM_FILTER_SW_TRIGGER) && \
+          (hdfsf->RegularContMode == DFSDM_CONTINUOUS_CONV_OFF) && \
+          (hdfsf->hdmaReg->Init.Mode == DMA_CIRCULAR))
+		return E_OBJ;
+
+	/*
+	 *  DMAの有効確認
+	 */
+	if((sil_rew_mem((uint32_t *)(hdfsf->base+TOFF_DFSDM_FLTCR1)) & DFSDM_FLTCR1_RDMAEN) == 0)
+		return E_OBJ;
+
+	/*
+	 *  DFSDMフィルターの状態チェック
+	 */
+	if(hdfsf->state == DFSDM_FILTER_STATE_READY || hdfsf->state == DFSDM_FILTER_STATE_INJ){
+		ER ercd = E_OK;
+		/*
+		 *  コールバック関数の設定
+		 */
+		hdfsf->hdmaReg->xfercallback = DFSDM_DMARegularConvCplt;
+		hdfsf->hdmaReg->errorcallback = DFSDM_DMAError;
+		hdfsf->hdmaReg->xferhalfcallback = (hdfsf->hdmaReg->Init.Mode == DMA_CIRCULAR) ? DFSDM_DMARegularHalfConvCplt : NULL;
+
+		/*
+		 *  DMAスタート
+		 */
+		if((ercd = dma_start(hdfsf->hdmaReg, (uint32_t)(hdfsf->base+TOFF_DFSDM_FLTRDATAR), (uint32_t)pData, Length)) != E_OK)
+			hdfsf->state = DFSDM_FILTER_STATE_ERROR;	/* DMAエラー */
+		else	/* レギュラー変換スタート */
+			DFSDM_RegConvStart(hdfsf);
+		return ercd;
+	}
+	else
+		return E_OBJ;
+}
+
+/*
+ *  DFSDMフィルターレギュラー変換スタート(16BIT変換)
+ *  parameter1 hdfsc    DFSDMフィルターハンドラへのポインタ
+ *  paramter 2 pData    変換データ設定領域のポインタ
+ *  parameter3 Length   領域長
+ *  return              正常終了時、E_OK
+ */
+ER
+dfsdm_filterRegularMsbStart(DFSDM_Filter_Handle_t *hdfsf, int16_t *pData, uint32_t Length)
+{
+	if(hdfsf == NULL || pData == NULL || Length == 0)
+		return E_PAR;
+
+	/*
+	 *  初期設定値の確認
+	 */
+	if((hdfsf->Init.RegTrigger == DFSDM_FILTER_SW_TRIGGER) && \
+          (hdfsf->RegularContMode == DFSDM_CONTINUOUS_CONV_OFF) && \
+          (hdfsf->hdmaReg->Init.Mode == DMA_NORMAL) && (Length != 1))
+		return E_PAR;
+
+	if((hdfsf->Init.RegTrigger == DFSDM_FILTER_SW_TRIGGER) && \
+          (hdfsf->RegularContMode == DFSDM_CONTINUOUS_CONV_OFF) && \
+          (hdfsf->hdmaReg->Init.Mode == DMA_CIRCULAR))
+		return E_OBJ;
+
+	/*
+	 *  DMAの有効確認
+	 */
+	if((sil_rew_mem((uint32_t *)(hdfsf->base+TOFF_DFSDM_FLTCR1)) & DFSDM_FLTCR1_RDMAEN) == 0)
+		return E_OBJ;
+
+	/*
+	 *  DFSDMフィルターの状態チェック
+	 */
+	if(hdfsf->state == DFSDM_FILTER_STATE_READY || hdfsf->state == DFSDM_FILTER_STATE_INJ){
+		ER ercd = E_OK;
+		/*
+		 *  コールバック関数の設定
+		 */
+		hdfsf->hdmaReg->xfercallback = DFSDM_DMARegularConvCplt;
+		hdfsf->hdmaReg->errorcallback = DFSDM_DMAError;
+		hdfsf->hdmaReg->xferhalfcallback = (hdfsf->hdmaReg->Init.Mode == DMA_CIRCULAR) ? DFSDM_DMARegularHalfConvCplt : NULL;
+
+		/*
+		 *  DMAスタート
+		 */
+		if((ercd = dma_start(hdfsf->hdmaReg, (uint32_t)(hdfsf->base+TOFF_DFSDM_FLTRDATAR+2), (uint32_t)pData, Length)) != E_OK)
+			hdfsf->state = DFSDM_FILTER_STATE_ERROR;	/* DMAスタートエラー */
+		else	/* レギュラー変換スタート */
+			DFSDM_RegConvStart(hdfsf);
+		return ercd;
+	}
+	else
+		return E_OBJ;
+}
+
+/*
+ *  DFSDMフィルターレギュラー変換停止
+ *  parameter1 hdfsc    DFSDMフィルターハンドラへのポインタ
+ *  return              正常終了時、E_OK
+ */
+ER
+dfsdm_filterRegularStop(DFSDM_Filter_Handle_t *hdfsf)
+{
+	ER ercd = E_OK;
+
+	if(hdfsf == NULL)
+		return E_PAR;
+
+	/*
+	 *  DFSDMフィルターの状態チェック
+	 */
+	if(hdfsf->state != DFSDM_FILTER_STATE_REG && hdfsf->state != DFSDM_FILTER_STATE_REG_INJ)
+		return E_OBJ;
+
+	 /*
+	  *  DMA停止
+	  */
+	if((ercd = dma_end(hdfsf->hdmaReg)) != E_OK)	/* Set DFSDM filter in error state */
+		hdfsf->state = DFSDM_FILTER_STATE_ERROR;
+	else	/* レギュラー変換停止 */
+		DFSDM_RegConvStop(hdfsf);
+	return ercd;
+}
+
+/*
+ *  DFSDMフィルターレギュラー変換値取得
+ *  parameter1 hdfsc    DFSDMフィルターハンドラへのポインタ
+ *  parameter2 Channel  DFSDMチャネル番号設定用ポインタ
+ *  return              レギュラー変換値
+ */
+int32_t
+dfsdm_filterGetRegularValue(DFSDM_Filter_Handle_t *hdfsf, uint32_t *Channel)
+{
+	uint32_t reg = 0;
+
+	if(hdfsf == NULL || Channel == NULL)
+		return 0;
+
+	/*
+	 *  レギュラー変換値とチャネル番号取出し
+	 */
+	reg = sil_rew_mem((uint32_t *)(hdfsf->base+TOFF_DFSDM_FLTRDATAR));
+
+	/* Extract channel and regular conversion value */
+	*Channel = (reg & DFSDM_FLTRDATAR_RDATACH);
+	return (int32_t)((reg & DFSDM_FLTRDATAR_RDATA) >> 18);
+}
+
+/*
+ *  DFSDMフィルターインジェクト変換スタート(32BIT変換)
+ *  parameter1 hdfsc    DFSDMフィルターハンドラへのポインタ
+ *  paramter 2 pData    変換データ設定領域のポインタ
+ *  parameter3 Length   領域長
+ *  return              正常終了時、E_OK
+ */
+ER
+dfsdm_filterInjectedStart(DFSDM_Filter_Handle_t *hdfsf, int32_t *pData, uint32_t Length)
+{
+	if(hdfsf == NULL || pData == NULL || Length == 0)
+		return E_PAR;
+
+	/*
+	 *  初期設定値の確認
+	 */
+	if((hdfsf->Init.InjTrigger == DFSDM_FILTER_SW_TRIGGER) && \
+          (hdfsf->hdmaInj->Init.Mode == DMA_NORMAL) && Length > hdfsf->InjConvRemaining)
+		return E_PAR;
+
+	if((hdfsf->Init.InjTrigger == DFSDM_FILTER_SW_TRIGGER) && hdfsf->hdmaInj->Init.Mode == DMA_CIRCULAR)
+		return E_OBJ;
+
+	/*
+	 *  DMAの有効確認
+	 */
+	if((sil_rew_mem((uint32_t *)(hdfsf->base+TOFF_DFSDM_FLTCR1)) & DFSDM_FLTCR1_JDMAEN) == 0)
+		return  E_OBJ;
+
+	/*
+	 *  DFSDMフィルターの状態チェック
+	 */
+	if(hdfsf->state == DFSDM_FILTER_STATE_READY || hdfsf->state == DFSDM_FILTER_STATE_REG){
+		ER ercd = E_OK;
+		/*
+		 *  コールバック関数の設定
+		 */
+		hdfsf->hdmaInj->xfercallback = DFSDM_DMAInjectedConvCplt;
+		hdfsf->hdmaInj->errorcallback = DFSDM_DMAError;
+		hdfsf->hdmaInj->xferhalfcallback = (hdfsf->hdmaInj->Init.Mode == DMA_CIRCULAR) ?\
+                                                   DFSDM_DMAInjectedHalfConvCplt : NULL;
+
+		/*
+		 *  DMAスタート
+		 */
+		if((ercd = dma_start(hdfsf->hdmaInj, (uint32_t)(hdfsf->base+TOFF_DFSDM_FLTJDATAR), (uint32_t)pData, Length)) != E_OK)
+			hdfsf->state = DFSDM_FILTER_STATE_ERROR;
+		else	/* インジェクト変換スタート */
+			DFSDM_InjConvStart(hdfsf);
+		return ercd;
+	}
+	else
+		return E_OBJ;
+}
+
+/*
+ *  DFSDMフィルターインジェクト変換スタート(16BIT変換)
+ *  parameter1 hdfsc    DFSDMフィルターハンドラへのポインタ
+ *  paramter 2 pData    変換データ設定領域のポインタ
+ *  parameter3 Length   領域長
+ *  return              正常終了時、E_OK
+ */
+ER
+dfsdm_filterInjectedMsbStart(DFSDM_Filter_Handle_t *hdfsf, int16_t *pData, uint32_t Length)
+{
+	if(hdfsf == NULL || pData == NULL || Length == 0)
+		return E_PAR;
+
+	/*
+	 *  初期設定値の確認
+	 */
+	if((hdfsf->Init.InjTrigger == DFSDM_FILTER_SW_TRIGGER) && \
+          (hdfsf->hdmaInj->Init.Mode == DMA_NORMAL) && (Length > hdfsf->InjConvRemaining)){
+		return E_PAR;
+	}
+	else if((hdfsf->Init.InjTrigger == DFSDM_FILTER_SW_TRIGGER) && \
+          (hdfsf->hdmaInj->Init.Mode == DMA_CIRCULAR)){
+		return E_OBJ;
+ 	}
+
+	/*
+	 *  DMAの有効確認
+	 */
+	if((sil_rew_mem((uint32_t *)(hdfsf->base+TOFF_DFSDM_FLTCR1)) & DFSDM_FLTCR1_JDMAEN) == 0)
+		return E_OBJ;
+
+	/*
+	 *  DFSDMフィルターの状態チェック
+	 */
+	if(hdfsf->state == DFSDM_FILTER_STATE_READY || hdfsf->state == DFSDM_FILTER_STATE_REG){
+		ER ercd = E_OK;
+		/*
+		 *  コールバック関数の設定
+		 */
+		hdfsf->hdmaInj->xfercallback = DFSDM_DMAInjectedConvCplt;
+		hdfsf->hdmaInj->errorcallback = DFSDM_DMAError;
+		hdfsf->hdmaInj->xferhalfcallback = (hdfsf->hdmaInj->Init.Mode == DMA_CIRCULAR) ? DFSDM_DMAInjectedHalfConvCplt : NULL;
+
+		/*
+		 *  DMAスタート
+		 */
+		if((ercd = dma_start(hdfsf->hdmaInj, (uint32_t)(hdfsf->base+TOFF_DFSDM_FLTJDATAR+2), (uint32_t)pData, Length)) != E_OK)
+			hdfsf->state = DFSDM_FILTER_STATE_ERROR;
+		else
+			DFSDM_InjConvStart(hdfsf);	/* インジェクト変換スタート */
+		return ercd;
+	}
+	else
+		return E_OBJ;
+}
+
+/*
+ *  DFSDMフィルターインジェクト変換停止
+ *  parameter1 hdfsc    DFSDMフィルターハンドラへのポインタ
+ *  return              正常終了時、E_OK
+ */
+ER
+dfsdm_filterInjectedStop(DFSDM_Filter_Handle_t *hdfsf)
+{
+	ER ercd = E_OK;
+
+	if(hdfsf == NULL)
+		return E_PAR;
+
+	/*
+	 *  DFSDMフィルターの状態チェック
+	 */
+	if(hdfsf->state != DFSDM_FILTER_STATE_INJ && hdfsf->state != DFSDM_FILTER_STATE_REG_INJ)
+		return E_OBJ;
+
+	/*
+	 *  DMA停止
+	 */
+	if((ercd = dma_end(hdfsf->hdmaInj)) != E_OK)
+		hdfsf->state = DFSDM_FILTER_STATE_ERROR;
+	else
+		DFSDM_InjConvStop(hdfsf);	/* インジェクト変換停止 */
+	return ercd;
+}
+
+/*
+ *  DFSDMフィルターインジェクト変換値取得
+ *  parameter1 hdfsc    DFSDMフィルターハンドラへのポインタ
+ *  parameter2 Channel  DFSDMチャネル番号設定用ポインタ
+ *  return              インジェクト変換値
+ */
+int32_t
+dfsdm_filterGetInjectedValue(DFSDM_Filter_Handle_t *hdfsf, uint32_t *Channel)
+{
+	uint32_t reg = 0;
+
+	if(hdfsf == NULL || Channel == NULL)
+		return 0;
+
+	/*
+	 *  インジェクト変換値とチャネルを取得
+	 */
+	reg = sil_rew_mem((uint32_t *)(hdfsf->base+TOFF_DFSDM_FLTRDATAR));
+
+	*Channel = (reg & DFSDM_FLTJDATAR_JDATACH);
+	return (int32_t)((reg & DFSDM_FLTJDATAR_JDATA) >> 8);
+}
+
+/*
+ *  アナルグウォッチドックスタート
+ *  parameter1 hdfsc    DFSDMフィルターハンドラへのポインタ
+ *  paramter 2 awdParam アナルグウォッチドック設定構造体へのポインタ
+ *  return              正常終了時、E_OK
+ */
+ER
+dfsdm_filterAwdStart(DFSDM_Filter_Handle_t *hdfsf, DFSDM_Filter_AwdParamTypeDef *awdParam)
+{
+	if(hdfsf == NULL)
+		return E_PAR;
+	if(awdParam->DataSource != DFSDM_FILTER_AWD_FILTER_DATA &&
+		awdParam->DataSource != DFSDM_FILTER_AWD_CHANNEL_DATA)
+		return E_PAR;
+	if(awdParam->Channel == 0 || awdParam->Channel > 0x000F00FF)
+		return E_PAR;
+	if(awdParam->HighThreshold < -8388608 && awdParam->HighThreshold > 8388607)
+		return E_PAR;
+	if(awdParam->LowThreshold < -8388608 && awdParam->LowThreshold > 8388607)
+		return E_PAR;
+	if(awdParam->HighBreakSignal > 0xF)
+		return E_PAR;
+	if(awdParam->LowBreakSignal > 0xF)
+		return E_PAR;
+
+	/*
+	 *  DFSDMフィルター状態チェック
+	 */
+	if(hdfsf->state == DFSDM_FILTER_STATE_RESET || hdfsf->state == DFSDM_FILTER_STATE_ERROR)
+		return E_OBJ;
+
+	/*
+	 *  アナルグウォッチドック・データソース設定
+	 */
+	sil_andw_mem((uint32_t *)(hdfsf->base+TOFF_DFSDM_FLTCR1), DFSDM_FLTCR1_AWFSEL);
+	sil_orw_mem((uint32_t *)(hdfsf->base+TOFF_DFSDM_FLTCR1), awdParam->DataSource);
+
+	/*
+	 *  スレッシュホールド、ブレークシグナル設定
+	 */
+	sil_andw_mem((uint32_t *)(hdfsf->base+TOFF_DFSDM_FLTAWHTR), (DFSDM_FLTAWHTR_AWHT | DFSDM_FLTAWHTR_BKAWH));
+	sil_orw_mem((uint32_t *)(hdfsf->base+TOFF_DFSDM_FLTAWHTR), ((awdParam->HighThreshold << 8) |
+                                        awdParam->HighBreakSignal));
+	sil_andw_mem((uint32_t *)(hdfsf->base+TOFF_DFSDM_FLTAWLTR), (DFSDM_FLTAWLTR_AWLT | DFSDM_FLTAWLTR_BKAWL));
+	sil_orw_mem((uint32_t *)(hdfsf->base+TOFF_DFSDM_FLTAWLTR), ((awdParam->LowThreshold << 8) |
+                                        awdParam->LowBreakSignal));
+
+	/*
+	 *  チャネルと割込み設定
+	 */
+	sil_andw_mem((uint32_t *)(hdfsf->base+TOFF_DFSDM_FLTCR2), DFSDM_FLTCR2_AWDCH);
+	sil_orw_mem((uint32_t *)(hdfsf->base+TOFF_DFSDM_FLTCR2), (((awdParam->Channel & DFSDM_LSB_MASK) << 16) |
+                                        DFSDM_FLTCR2_AWDIE));
+	return E_OK;
+}
+
+/*
+ *  アナルグウォッチドック停止
+ *  parameter1 hdfsc    DFSDMフィルターハンドラへのポインタ
+ *  return              正常終了時、E_OK
+ */
+ER
+dfsdm_filterAwdStop(DFSDM_Filter_Handle_t *hdfsf)
+{
+	if(hdfsf == NULL)
+		return E_PAR;
+
+	/*
+	 *  DFSDMフィルター状態チェック
+	 */
+	if(hdfsf->state == DFSDM_FILTER_STATE_RESET || hdfsf->state == DFSDM_FILTER_STATE_ERROR)
+		return E_OBJ;
+
+	/*
+	 *  チャネルと割込みのリセット
+	 */
+	sil_andw_mem((uint32_t *)(hdfsf->base+TOFF_DFSDM_FLTCR2), (DFSDM_FLTCR2_AWDCH | DFSDM_FLTCR2_AWDIE));
+
+	/*
+	 *  アナログウォッチドッグフラグクリア
+	 */
+	sil_wrw_mem((uint32_t *)(hdfsf->base+TOFF_DFSDM_FLTAWCFR), (DFSDM_FLTAWCFR_CLRAWHTF | DFSDM_FLTAWCFR_CLRAWLTF));
+
+	/*
+	 *  スレッシュホールドとブレークシグナルをリセット
+	 */
+	sil_andw_mem((uint32_t *)(hdfsf->base+TOFF_DFSDM_FLTAWHTR), (DFSDM_FLTAWHTR_AWHT | DFSDM_FLTAWHTR_BKAWH));
+	sil_andw_mem((uint32_t *)(hdfsf->base+TOFF_DFSDM_FLTAWLTR), (DFSDM_FLTAWLTR_AWLT | DFSDM_FLTAWLTR_BKAWL));
+
+	/*
+	 *  データソースをリセット
+	 */
+	sil_andw_mem((uint32_t *)(hdfsf->base+TOFF_DFSDM_FLTCR1), DFSDM_FLTCR1_AWFSEL);
+	return E_OK;
+}
+
+/*
+ *  DFSDMフィルター・エクストリーム検出スタート
+ *  parameter1 hdfsc    DFSDMフィルターハンドラへのポインタ
+ *  parameter2 Channel  チャネル番号
+ *  return              正常終了時、E_OK
+ */
+ER
+dfsdm_filterExdStart(DFSDM_Filter_Handle_t *hdfsf, uint32_t Channel)
+{
+	if(hdfsf == NULL)
+		return E_PAR;
+
+	/*
+	 *  DFSDMフィルター状態チェック
+	 */
+	if(hdfsf->state == DFSDM_FILTER_STATE_RESET || hdfsf->state == DFSDM_FILTER_STATE_ERROR)
+		return E_OBJ;
+
+	/*
+	 *  エクストリーム検出チャネル設定
+	 */
+	sil_andw_mem((uint32_t *)(hdfsf->base+TOFF_DFSDM_FLTCR2), DFSDM_FLTCR2_EXCH);
+	sil_orw_mem((uint32_t *)(hdfsf->base+TOFF_DFSDM_FLTCR2), ((Channel & DFSDM_LSB_MASK) << 8));
+	return E_OK;
+}
+
+/*
+ *  DFSDMフィルター・エクストリーム検出停止
+ *  parameter1 hdfsc    DFSDMフィルターハンドラへのポインタ
+ *  return              正常終了時、E_OK
+ */
+ER
+dfsdm_filterExdStop(DFSDM_Filter_Handle_t *hdfsf)
+{
+	volatile uint32_t     reg;
+
+	if(hdfsf == NULL)
+		return E_PAR;
+
+	/*
+	 *  DFSDMフィルター状態チェック
+	 */
+	if(hdfsf->state == DFSDM_FILTER_STATE_RESET || hdfsf->state == DFSDM_FILTER_STATE_ERROR)
+		return E_OBJ;
+
+	/*
+	 *  エクストリーム検出チャネルリセット
+	 */
+	sil_andw_mem((uint32_t *)(hdfsf->base+TOFF_DFSDM_FLTCR2), DFSDM_FLTCR2_EXCH);
+
+    /*
+	 *  エクストリーム検出値取得
+	 */
+	reg = sil_rew_mem((uint32_t *)(hdfsf->base+TOFF_DFSDM_FLTEXMAX));
+	reg = sil_rew_mem((uint32_t *)(hdfsf->base+TOFF_DFSDM_FLTEXMIN));
+    ((void)(reg));
+	return E_OK;
+}
+
+/*
+ *  DFSDMフィルター・エクストリーム検出最大値取得
+ *  parameter1 hdfsc    DFSDMフィルターハンドラへのポインタ
+ *  parameter2 Chnnel   チャネル保存領域のポインタ
+ *  return              最大値
+ */
+int32_t
+dfsdm_filterGetExdMaxValue(DFSDM_Filter_Handle_t *hdfsf, uint32_t *Channel)
+{
+	uint32_t reg = 0;
+
+	if(hdfsf == NULL || Channel == NULL)
+		return E_PAR;
+
+	/*
+	 *  チャネルと最大値取得
+	 */
+	reg = sil_rew_mem((uint32_t *)(hdfsf->base+TOFF_DFSDM_FLTEXMAX));
+	*Channel = (reg & DFSDM_FLTEXMAX_EXMAXCH);
+	return (int32_t)((reg & DFSDM_FLTEXMAX_EXMAX) >> 8);
+}
+
+/*
+ *  DFSDMフィルター・エクストリーム検出最小値取得
+ *  parameter1 hdfsc    DFSDMフィルターハンドラへのポインタ
+ *  parameter2 Chnnel   チャネル保存領域のポインタ
+ *  return              最小値
+ */
+int32_t
+dfsdm_filterGetExdMinValue(DFSDM_Filter_Handle_t *hdfsf, uint32_t *Channel)
+{
+	uint32_t reg = 0;
+
+	if(hdfsf == NULL || Channel == NULL)
+		return E_PAR;
+
+	/*
+	 *  チャネルと最小値取得
+	 */
+	reg = sil_rew_mem((uint32_t *)(hdfsf->base+TOFF_DFSDM_FLTEXMIN));
+	*Channel = (reg & DFSDM_FLTEXMIN_EXMINCH);
+	return (int32_t)((reg & DFSDM_FLTEXMIN_EXMIN) >> 8);
+}
+
+/*
+ *  変換時間取得
+ *  parameter1 hdfsc    DFSDMフィルターハンドラへのポインタ
+ *  return              時間(秒)
+ */
+uint32_t
+dfsdm_filterGetConvTimeValue(DFSDM_Filter_Handle_t *hdfsf)
+{
+	uint32_t reg = 0;
+
+	if(hdfsf == NULL)
+		return E_PAR;
+
+	/*
+	 *  変換時間レジスタ値取得
+	 */
+	reg = sil_rew_mem((uint32_t *)(hdfsf->base+TOFF_DFSDM_FLTCNVTIMR));
+	return (uint32_t)((reg & DFSDM_FLTCNVTIMR_CNVCNT) >> 4);
+}
+
+
+/*
+ *  DFSDMフィルター割込みハンドラ
+ */
+void dfsdm_irqhandler(DFSDM_Filter_Handle_t *hdfsf)
+{
+	DFSDM_Channel_Handle_t *hdfsc;
+	uint32_t isr = sil_rew_mem((uint32_t *)(hdfsf->base+TOFF_DFSDM_FLTISR));
+	uint32_t cr2 = sil_rew_mem((uint32_t *)(hdfsf->base+TOFF_DFSDM_FLTCR2));
+
+	/*
+	 * レギュラー変換オーバーランエラー
+	 */
+	if(((isr & cr2) & DFSDM_FLTISR_ROVRF) != 0){
+		/*
+		 *  オーバーラン要因クリア
+		 */
+		sil_wrw_mem((uint32_t *)(hdfsf->base+TOFF_DFSDM_FLTICR), DFSDM_FLTICR_CLRROVRF);
+
+		/*
+		 *  エラー設定とコールバック
+		 */
+		hdfsf->errorcode = DFSDM_FILTER_ERROR_REGULAR_OVERRUN;
+		if(hdfsf->errorcallback != NULL)
+			hdfsf->errorcallback(hdfsf);
+	}
+	/*
+	 *  インジェクト変換オーバーランエラー
+	 */
+	else if(((isr & cr2) & DFSDM_FLTISR_JOVRF) != 0){
+		/*
+		 *  オーバーラン要因クリア
+		 */
+		sil_wrw_mem((uint32_t *)(hdfsf->base+TOFF_DFSDM_FLTICR), DFSDM_FLTICR_CLRJOVRF);
+
+		/*
+		 *  エラー設定とコールバック
+		 */
+		hdfsf->errorcode = DFSDM_FILTER_ERROR_INJECTED_OVERRUN;
+		if(hdfsf->errorcallback != NULL)
+			hdfsf->errorcallback(hdfsf);
+	}
+	/*
+	 *  レギュラー変換終了
+	 */
+	else if(((isr & cr2) & DFSDM_FLTISR_REOCF) != 0){
+		/*
+		 *  コールバック
+		 */
+		if(hdfsf->regconvcallback != NULL)
+			hdfsf->regconvcallback(hdfsf);
+
+		/*
+		 *  非継続モード、かつ、ソフトウェアトリガの場合
+		 */
+		if((hdfsf->RegularContMode == DFSDM_CONTINUOUS_CONV_OFF) &&
+			(hdfsf->Init.RegTrigger == DFSDM_FILTER_SW_TRIGGER)){
+			/*
+			 *  レギュラー変換割込み停止
+			 */
+			sil_andw_mem((uint32_t *)(hdfsf->base+TOFF_DFSDM_FLTCR2), DFSDM_FLTCR2_REOCIE);
+
+			/*
+			 *  DFSDMフィルター状態更新
+			 */
+			hdfsf->state = (hdfsf->state == DFSDM_FILTER_STATE_REG) ? DFSDM_FILTER_STATE_READY : DFSDM_FILTER_STATE_INJ;
+		}
+	}
+	/*
+	 *  インジェクト変換終了
+	 */
+	else if(((isr & cr2) & DFSDM_FLTISR_JEOCF) != 0){
+		/*
+		 *  コールバック
+		 */
+		if(hdfsf->injconvcallback != NULL)
+			hdfsf->injconvcallback(hdfsf);
+
+		/*
+		 *  残りのインジェクト変換更新
+		 */
+		if(--hdfsf->InjConvRemaining == 0){
+			/*
+			 *  ソフトウェアトリガなら、インジェクト変換停止
+			 */
+			if(hdfsf->Init.InjTrigger == DFSDM_FILTER_SW_TRIGGER){
+				sil_andw_mem((uint32_t *)(hdfsf->base+TOFF_DFSDM_FLTCR2), DFSDM_FLTCR2_JEOCIE);
+				hdfsf->state = (hdfsf->state == DFSDM_FILTER_STATE_INJ) ? DFSDM_FILTER_STATE_READY : DFSDM_FILTER_STATE_REG;
+			}
+			/*
+			 *  インジェクト変換モード更新
+			 */
+			hdfsf->InjConvRemaining = (hdfsf->Init.InjScanMode == DFSDM_ENABLE) ? hdfsf->InjectedChannelsNbr : 1;
+		}
+	}
+	/*
+	 *  アナログウォッチドッグ発生
+	 */
+	else if(((isr & cr2) &DFSDM_FLTISR_AWDF) != 0){
+		uint32_t reg = sil_rew_mem((uint32_t *)(hdfsf->base+TOFF_DFSDM_FLTAWSR));
+		uint32_t threshold = 0;
+		uint32_t channel = 0;
+
+		/*
+		 *  チャネル番号とスレッシュホールド取得
+		 */
+		threshold = ((reg & DFSDM_FLTAWSR_AWLTF) != 0) ? DFSDM_AWD_LOW_THRESHOLD : DFSDM_AWD_HIGH_THRESHOLD;
+		if(threshold == DFSDM_AWD_HIGH_THRESHOLD){
+			reg = reg >> 8;
+		}
+		while((reg & 1) == 0){
+			channel++;
+			reg = reg >> 1;
+		}
+		/*
+		 *  アナルグウォッチドッグ・フラグクリア
+		 */
+		sil_wrw_mem((uint32_t *)(hdfsf->base+TOFF_DFSDM_FLTAWCFR), (threshold == DFSDM_AWD_HIGH_THRESHOLD) ? \
+                                        (1 << (8 + channel)) : (1 << channel));
+
+		/*
+		 *  アナルグウォッチドッグ・コールバック
+		 */
+		if(hdfsf->awdconvcallback != NULL)
+			hdfsf->awdconvcallback(hdfsf);
+	}
+	/*
+	 *  クロックアブセンス発生
+	 */
+	else if(hdfsf->base == TADR_DFSDM1_FILTER0_BASE &&
+		(isr & DFSDM_FLTISR_CKABF) != 0 && (cr2 & DFSDM_FLTCR2_CKABIE) != 0){
+		uint32_t reg = (sil_rew_mem((uint32_t *)(hdfsf->base+TOFF_DFSDM_FLTISR)) & DFSDM_FLTISR_CKABF) >> 16;
+		uint32_t channel = 0;
+
+		while(channel < DFSDM1_CHANNEL_NUMBER){
+			/*
+			 *  有効チャネルサーチ
+			 */
+			if(((reg & 1) != 0) && (Dfsdm1ChannelHandle[channel] != NULL)){
+				/*
+				 *  クロックアブセンス・イネーブルのチャネルをチェック
+				 */
+				if((sil_rew_mem((uint32_t *)(Dfsdm1ChannelHandle[channel]->base+TOFF_DFSDM_CHCFGR1)) & DFSDM_CHCFGR1_CKABEN) != 0){
+					/*
+					 *  クロックアブセンス・フラグクリア
+					 */
+					sil_wrw_mem((uint32_t *)(hdfsf->base+TOFF_DFSDM_FLTICR), (1 << (16 + channel)));
+
+					/*
+					 *  対応チャネルのコールバック
+					 */
+					hdfsc = Dfsdm1ChannelHandle[channel];
+					if(hdfsc != NULL && hdfsc->ckabcallback != NULL)
+						hdfsc->ckabcallback(hdfsc);
+				}
+			}
+			channel++;
+			reg = reg >> 1;
+		}
+	}
+	/*
+	 *  ショートサーキット・デテクション発生
+	 */
+	else if(hdfsf->base == TADR_DFSDM1_FILTER0_BASE &&
+		(isr & DFSDM_FLTISR_SCDF) != 0 && (cr2 & DFSDM_FLTCR2_SCDIE) != 0){
+		uint32_t reg = 0;
+		uint32_t channel = 0;
+
+		/*
+		 *  チャネル番号取得
+		 */
+		reg = (sil_rew_mem((uint32_t *)(hdfsf->base+TOFF_DFSDM_FLTISR)) & DFSDM_FLTISR_SCDF) >> 24;
+		while((reg & 1) == 0){
+			channel++;
+			reg = reg >> 1;
+		}
+
+		/*
+		 *  ショートサーキット・デテクションフラグクリア
+		 */
+		sil_wrw_mem((uint32_t *)(hdfsf->base+TOFF_DFSDM_FLTICR), (1 << (24 + channel)));
+
+		/*
+		 *  ショートサーキット・デテクション・コールバック
+		 */
+		hdfsc = Dfsdm1ChannelHandle[channel];
+		if(hdfsc != NULL && hdfsc->scdcallback != NULL)
+			hdfsc->scdcallback(hdfsc);
+	}
+}
+
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/pdic/stm32f7xx/dfsdm.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/pdic/stm32f7xx/dfsdm.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/pdic/stm32f7xx/dfsdm.h	(revision 457)
@@ -0,0 +1,336 @@
+/*
+ *  TOPPERS/ASP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Advanced Standard Profile Kernel
+ * 
+ *  Copyright (C) 2008-2011 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ *  Copyright (C) 2015-2017 by TOPPERS PROJECT Educational Working Group.
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+/*
+ * 
+ *  STM32F7xx DFSDMデバイスドライバの外部宣言
+ *
+ */
+
+#ifndef _DFSDM_H_
+#define _DFSDM_H_
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/*
+ *  DFSDM CHANNEL状態定義
+ */
+#define DFSDM_CHANNEL_STATE_RESET   0x00000000	/* DFSDM CHANNELリセット状態 */
+#define DFSDM_CHANNEL_STATE_READY   0x00000001	/* DFSDM CHANNELレディ状態 */
+#define DFSDM_CHANNEL_STATE_ERROR   0x00080000	/* DFSDM CHANNELエラー状態 */
+
+/*
+ *  DFSDM CHANNEL初期化定義
+ */
+typedef struct
+{
+	uint32_t                OutClockActivation;		/* アウトプットクロック有効無効 */
+	uint32_t                OutClockSelection;		/* アウトプットクロック選択 */
+	uint32_t                OutClockDivider;		/* アウトプットクロックデバイダー */
+	uint32_t                InputMultiplexer;		/* 入力：外部シリアルまたは内部レジスタ */
+	uint32_t                InputDataPacking;		/* 入力：データピッキング */
+	uint32_t                InputPins;				/* 入力：ピン */
+	uint32_t                SerialType;				/* シリアル種別：SPI or Manchester modes. */
+	uint32_t                SerialSpiClock;			/* SPIクロック選択：(external or internal with different sampling point) */
+	uint32_t                AwdFilterOrder;			/* アナログウオッチドッグ シンクフィルター順序 */
+	uint32_t                AwdOversampling;		/* アナログウオッチドッグ oversampliオーバーサンプリング RATIO */
+	int32_t                 Offset;					/* DFSDMチャネルオフセット */
+	uint32_t                RightBitShift;			/* DFSDMチャネル右ビットシフト */
+}DFSDM_Channel_Init_t;
+
+/*
+ *  DFSDM CHANNELハンドラ定義
+ */
+typedef struct DFSDM_Channel_struct DFSDM_Channel_Handle_t;
+struct DFSDM_Channel_struct
+{
+	uint32_t                base;					/* DFSDMチャネルベースアドレス */
+	DFSDM_Channel_Init_t    Init;					/* DFSDM初期化データ */
+	void                    (*ckabcallback)(DFSDM_Channel_Handle_t * hdfsc);	/* Channel Ckabコールバック関数 */
+	void                    (*scdcallback)(DFSDM_Channel_Handle_t * hdfsc);		/* Channel Scdコールバック関数 */
+	volatile uint32_t       state;					/* DFSDMチャネル状態 */
+};
+
+/*
+ *  DFSDMフィルター状態定義
+ */
+#define DFSDM_FILTER_STATE_RESET    0x00000000	/* DFSDMフィルターリセット状態 */
+#define DFSDM_FILTER_STATE_READY    0x00000001	/* DFSDMフィルターレディ状態 */
+#define DFSDM_FILTER_STATE_REG      0x00000002	/* DFSDMフィルターレギュラー変換状態 */
+#define DFSDM_FILTER_STATE_INJ      0x00000003	/* DFSDMフィルターインジェクト変換状態 */
+#define DFSDM_FILTER_STATE_REG_INJ  0x00000004	/* DFSDMフィルターレギュラー・インジェクト変換状態 */
+#define DFSDM_FILTER_STATE_ERROR    0x00080000	/* DFSDMフィルターエラー状態 */
+
+/*
+ *  DFSDMフィルターエラー定義e
+ */
+#define DFSDM_FILTER_ERROR_NONE             0x00000000	/* エラーなし */
+#define DFSDM_FILTER_ERROR_REGULAR_OVERRUN  0x00000001	/* レギュラー変換オーバランエラー */
+#define DFSDM_FILTER_ERROR_INJECTED_OVERRUN 0x00000002	/* インジェクト変換オーバーランエラー */
+#define DFSDM_FILTER_ERROR_DMA              0x00000003	/* DMAエラー */
+
+/*
+ *  DFSDMフィルター初期化定義
+ */
+typedef struct
+{
+	uint32_t                RegTrigger;				/* レギュラー変換：software or synchronous. */
+	uint32_t                RegFastMode;			/* レギュラー変換：fast mode Enable/disable fast mode */
+	uint32_t                RegDmaMode;				/* レギュラー変換：DMA Enable/disable */
+	uint32_t                InjTrigger;				/* インジェクト変換：Trigger: software, external or synchronous. */
+	uint32_t                InjScanMode;			/* インジェクト変換：scanning mode Enable/disable */
+	uint32_t                InjDmaMode;				/* インジェクト変換：DMA Enable/disable */
+	uint32_t                InjExtTrigger;			/* インジェクト変換：External trigger */
+	uint32_t                InjExtTriggerEdge;		/* インジェクト変換：External trigger edge: rising, falling or both. */
+	uint32_t                FilterSincOrder;		/* Sinc filter order. */
+	uint32_t                FilterOversampling;		/* Filter oversampling ratio. */
+	uint32_t                FilterIntOversampling;	/* Integrator oversampling ratio. */
+}DFSDM_Filter_Init_t;
+
+/*
+ *  DFSDMフィルターハンドラ定義
+ */
+typedef struct DFSDM_Filter_struct DFSDM_Filter_Handle_t;
+struct DFSDM_Filter_struct
+{
+	uint32_t                base;					/* DFSDMフィルターベースアドレス */
+	DFSDM_Filter_Init_t     Init;					/* DFSDMフィルター初期化データ */
+	DMA_Handle_t            *hdmaReg;				/* レギュラー変換用DMAハンドラへのポインタ */
+	DMA_Handle_t            *hdmaInj;				/* インジェクト変換用DMAハンドラへのポインタ */
+	uint32_t                RegularContMode;		/* レギュラー変換：continuous mode */
+	uint32_t                InjectedChannelsNbr;	/* インジェクト変換：Number of channels */
+	uint32_t                InjConvRemaining;		/* インジェクト変換：remaining */
+	void                    (*regconvcallback)(DFSDM_Filter_Handle_t * hdfsf);		/* RegConvコールバック関数 */
+	void                    (*regconvhalfcallback)(DFSDM_Filter_Handle_t * hdfsf);	/* RegConv halfコールバック関数 */
+	void                    (*injconvcallback)(DFSDM_Filter_Handle_t * hdfsf);		/* InjConvコールバック関数 */
+	void                    (*injconvhalfcallback)(DFSDM_Filter_Handle_t * hdfsf);	/* InjConv halfコールバック関数 */
+	void                    (*awdconvcallback)(DFSDM_Filter_Handle_t * hdfsf);		/* Analog Wdコールバック関数 */
+	void                    (*errorcallback)(DFSDM_Filter_Handle_t * hdfsf);		/* エラーコールバック関数 */
+	volatile uint32_t       state;					/* DFSDMフィルター状態 */
+	volatile uint32_t       errorcode;				/* DFSDMフィルターエラー */
+};
+
+/*
+ *  DFSDMフィルター analog watchdog parameters定義
+ */
+typedef struct
+{
+	uint32_t                DataSource;				/* データソース：digital filter or from channel watchdog filter. */
+	uint32_t                Channel;				/* チャネル選択. */
+	int32_t                 HighThreshold;			/* ハイスレッド設定 */
+	int32_t                 LowThreshold;			/* ロースレッド設定 */
+	uint32_t                HighBreakSignal;		/* ハイスレッド・ブレークシグナル */
+	uint32_t                LowBreakSignal;			/* ロースレッド・ブレークシグナル */
+} DFSDM_Filter_AwdParamTypeDef;
+
+
+/*
+ *  DFSDMイネーブル・ディーブル定義
+ */
+#define DFSDM_DISABLE               0x00000000
+#define DFSDM_ENABLE                0x00000001
+#define DFSDM_MASK                  (~DFSDM_ENABLE)
+
+/*
+ *  DFSDMチャネル OutClockSelection定義
+ */
+#define DFSDM_CHANNEL_OUTPUT_CLOCK_SYSTEM   0x00000000				/* ソース：ouput clock is system clock */
+#define DFSDM_CHANNEL_OUTPUT_CLOCK_AUDIO    DFSDM_CHCFGR1_CKOUTSRC  /* ソース：ouput clock is audio clock */
+
+/*
+ *  DFSDMチャネル InputMultiplexer定義
+ */
+#define DFSDM_CHANNEL_EXTERNAL_INPUTS       0x00000000				/* 外部インプット */
+#define DFSDM_CHANNEL_INTERNAL_REGISTER     DFSDM_CHCFGR1_DATMPX_1	/* 内部レジスタ */
+
+/*
+ *  DFSDMチャネル InputDataPacking定義
+ */
+#define DFSDM_CHANNEL_STANDARD_MODE         0x00000000				/* Standard data packing mode */
+#define DFSDM_CHANNEL_INTERLEAVED_MODE      DFSDM_CHCFGR1_DATPACK_0	/* Interleaved data packing mode */
+#define DFSDM_CHANNEL_DUAL_MODE             DFSDM_CHCFGR1_DATPACK_1	/* Dual data packing mode */
+
+/*
+ *  DFSDMチャネル InputPins定義
+ */
+#define DFSDM_CHANNEL_SAME_CHANNEL_PINS     0x00000000				/* インプットピン：pins on same channel */
+#define DFSDM_CHANNEL_FOLLOWING_CHANNEL_PINS DFSDM_CHCFGR1_CHINSEL	/* インプットピン：following channel */
+
+/*
+ *  DFSDMチャネル SerialType定義
+ */
+#define DFSDM_CHANNEL_SPI_RISING            0x00000000				/* SPI with rising edge */
+#define DFSDM_CHANNEL_SPI_FALLING           DFSDM_CHCFGR1_SITP_0	/* SPI with falling edge */
+#define DFSDM_CHANNEL_MANCHESTER_RISING     DFSDM_CHCFGR1_SITP_1	/* Manchester with rising edge */
+#define DFSDM_CHANNEL_MANCHESTER_FALLING    DFSDM_CHCFGR1_SITP		/* Manchester with falling edge */
+
+/*
+ *  DFSDMチャネル SerialSpi clock selection定義
+ */
+#define DFSDM_CHANNEL_SPI_CLOCK_EXTERNAL    0x00000000				/* 外部SPIクロック */
+#define DFSDM_CHANNEL_SPI_CLOCK_INTERNAL    DFSDM_CHCFGR1_SPICKSEL_0			/* 内部SPIクロック */
+#define DFSDM_CHANNEL_SPI_CLOCK_INTERNAL_DIV2_FALLING DFSDM_CHCFGR1_SPICKSEL_1	/* 内部SPIクロック divided by 2, falling edge */
+#define DFSDM_CHANNEL_SPI_CLOCK_INTERNAL_DIV2_RISING  DFSDM_CHCFGR1_SPICKSEL	/* 内部SPIクロック divided by 2, rising edge */
+
+/*
+ *  DFSDMチャネル analog watchdog filter order定義
+ */
+#define DFSDM_CHANNEL_FASTSINC_ORDER        0x00000000				/* FastSinc filter type */
+#define DFSDM_CHANNEL_SINC1_ORDER           DFSDM_CHAWSCDR_AWFORD_0	/* Sinc 1 filter type */
+#define DFSDM_CHANNEL_SINC2_ORDER           DFSDM_CHAWSCDR_AWFORD_1	/* Sinc 2 filter type */
+#define DFSDM_CHANNEL_SINC3_ORDER           DFSDM_CHAWSCDR_AWFORD	/* Sinc 3 filter type */
+
+
+/*
+ *  DFSDMフィルター Regular/Injected conversion trigger定義
+ */
+#define DFSDM_FILTER_SW_TRIGGER             0x00000000			/* Software trigger */
+#define DFSDM_FILTER_SYNC_TRIGGER           0x00000001			/* Synchronous with DFSDM_FLT0 */
+#define DFSDM_FILTER_EXT_TRIGGER            0x00000002			/* External trigger (only for injected conversion) */
+
+/*
+ *  DFSDMフィルター external trigger定義(DFSDM filter 0, 1, 2 and 3)
+ */
+#define DFSDM_FILTER_EXT_TRIG_TIM1_TRGO     0x00000000
+#define DFSDM_FILTER_EXT_TRIG_TIM1_TRGO2    DFSDM_FLTCR1_JEXTSEL_0
+#define DFSDM_FILTER_EXT_TRIG_TIM8_TRGO     DFSDM_FLTCR1_JEXTSEL_1
+#define DFSDM_FILTER_EXT_TRIG_TIM8_TRGO2    (DFSDM_FLTCR1_JEXTSEL_0 | DFSDM_FLTCR1_JEXTSEL_1)
+#define DFSDM_FILTER_EXT_TRIG_TIM3_TRGO     DFSDM_FLTCR1_JEXTSEL_2
+#define DFSDM_FILTER_EXT_TRIG_TIM4_TRGO     (DFSDM_FLTCR1_JEXTSEL_0 | DFSDM_FLTCR1_JEXTSEL_2)
+#define DFSDM_FILTER_EXT_TRIG_TIM10_OC1     (DFSDM_FLTCR1_JEXTSEL_1 | DFSDM_FLTCR1_JEXTSEL_2)
+#define DFSDM_FILTER_EXT_TRIG_TIM6_TRGO     (DFSDM_FLTCR1_JEXTSEL_0 | DFSDM_FLTCR1_JEXTSEL_1 | DFSDM_FLTCR1_JEXTSEL_2)
+#define DFSDM_FILTER_EXT_TRIG_TIM7_TRGO     DFSDM_FLTCR1_JEXTSEL_3
+#define DFSDM_FILTER_EXT_TRIG_EXTI11        (DFSDM_FLTCR1_JEXTSEL_3 | DFSDM_FLTCR1_JEXTSEL_4)
+#define DFSDM_FILTER_EXT_TRIG_EXTI15        (DFSDM_FLTCR1_JEXTSEL_0 | DFSDM_FLTCR1_JEXTSEL_3 | DFSDM_FLTCR1_JEXTSEL_4)							/* For DFSDM filter 0, 1, 2 and 3 */
+#define DFSDM_FILTER_EXT_TRIG_LPTIM1_OUT    (DFSDM_FLTCR1_JEXTSEL_1 | DFSDM_FLTCR1_JEXTSEL_3 | DFSDM_FLTCR1_JEXTSEL_4)
+
+/*
+ *  DFSDMフィルター external trigger edge定義
+ */
+#define DFSDM_FILTER_EXT_TRIG_RISING_EDGE   DFSDM_FLTCR1_JEXTEN_0	/* 外部 立上がりエッジ */
+#define DFSDM_FILTER_EXT_TRIG_FALLING_EDGE  DFSDM_FLTCR1_JEXTEN_1	/* 外部 立下りエッジ */
+#define DFSDM_FILTER_EXT_TRIG_BOTH_EDGES    DFSDM_FLTCR1_JEXTEN		/* 外部 両エッジ */
+
+/*
+ *  DFSDMフィルター sinc order定義
+ */
+#define DFSDM_FILTER_FASTSINC_ORDER         0x00000000							/* FastSinc filter type */
+#define DFSDM_FILTER_SINC1_ORDER            DFSDM_FLTFCR_FORD_0					/* Sinc 1 filter type */
+#define DFSDM_FILTER_SINC2_ORDER            DFSDM_FLTFCR_FORD_1					/* Sinc 2 filter type */
+#define DFSDM_FILTER_SINC3_ORDER            (DFSDM_FLTFCR_FORD_0 | DFSDM_FLTFCR_FORD_1)	/* Sinc 3 filter type */
+#define DFSDM_FILTER_SINC4_ORDER            DFSDM_FLTFCR_FORD_2					/* Sinc 4 filter type */
+#define DFSDM_FILTER_SINC5_ORDER            (DFSDM_FLTFCR_FORD_0 | DFSDM_FLTFCR_FORD_2)	/* Sinc 5 filter type */
+
+/*
+ *  DFSDMフィルター AwdDataSource DataSource定義
+ */
+#define DFSDM_FILTER_AWD_FILTER_DATA        0x00000000			/* デジタルフィルターから入力 */
+#define DFSDM_FILTER_AWD_CHANNEL_DATA       DFSDM_FLTCR1_AWFSEL	/* アナログウオッチドッグチャネルから入力 */
+
+/*
+ *  DFSDMチャネル定義
+ */
+#define DFSDM_CHANNEL_0                     0x00000001
+#define DFSDM_CHANNEL_1                     0x00010002
+#define DFSDM_CHANNEL_2                     0x00020004
+#define DFSDM_CHANNEL_3                     0x00030008
+#define DFSDM_CHANNEL_4                     0x00040010
+#define DFSDM_CHANNEL_5                     0x00050020
+#define DFSDM_CHANNEL_6                     0x00060040
+#define DFSDM_CHANNEL_7                     0x00070080
+
+/*
+ *  DFSDMフィルター Continuous Mode定義
+ */
+#define DFSDM_CONTINUOUS_CONV_OFF           0x00000000	/* 変換を継続しない */
+#define DFSDM_CONTINUOUS_CONV_ON            0x00000001	/* 変換を継続する */
+
+/*
+ *  DFSDMフィルター AwdThreshold定義
+ */
+#define DFSDM_AWD_HIGH_THRESHOLD            0x00000000	/* アナログウオッチドッグ ハイスレシュホールド */
+#define DFSDM_AWD_LOW_THRESHOLD             0x00000001	/* アナログウオッチドッグ ロースレシュホールド */
+
+
+extern void dfsdm_clockconfig(ID port, uint32_t AudioFreq);
+extern ER dfsdm_channel_init(DFSDM_Channel_Handle_t *hdfsc);
+extern ER dfsdm_channel_deinit(DFSDM_Channel_Handle_t *hdfsc);
+
+extern ER dfsdm_channelCkabStart(DFSDM_Channel_Handle_t *hdfsc);
+extern ER dfsdm_channelCkabStop(DFSDM_Channel_Handle_t *hdfsc);
+extern ER dfsdm_channelScdStart(DFSDM_Channel_Handle_t *hdfsc, uint32_t Threshold, uint32_t BreakSignal);
+extern ER dfsdm_channelScdStop(DFSDM_Channel_Handle_t *hdfsc);
+extern int16_t dfsdm_channelGetAwdValue(DFSDM_Channel_Handle_t *hdfsc);
+extern ER dfsdm_channelModifyOffset(DFSDM_Channel_Handle_t *hdfsc, int32_t Offset);
+
+
+extern ER dfsdm_filter_init(DFSDM_Filter_Handle_t *hdfsf);
+extern ER dfsdm_filter_deinit(DFSDM_Filter_Handle_t *hdfsf);
+extern ER dfsdm_filter_config_reg(DFSDM_Filter_Handle_t *hdfsf, uint32_t Channel, uint32_t ContinuousMode);
+extern ER dfsdm_filter_config_inj(DFSDM_Filter_Handle_t *hdfsf, uint32_t Channel);
+
+extern ER dfsdm_filterRegularStart(DFSDM_Filter_Handle_t *hdfsf, int32_t *pData, uint32_t Length);
+extern ER dfsdm_filterRegularMsbStart(DFSDM_Filter_Handle_t *hdfsf, int16_t *pData, uint32_t Length);
+extern ER dfsdm_filterRegularStop(DFSDM_Filter_Handle_t *hdfsf);
+extern ER dfsdm_filterInjectedStart(DFSDM_Filter_Handle_t *hdfsf, int32_t *pData, uint32_t Length);
+extern ER dfsdm_filterInjectedMsbStart(DFSDM_Filter_Handle_t *hdfsf, int16_t *pData, uint32_t Length);
+extern ER dfsdm_filterInjectedStop(DFSDM_Filter_Handle_t *hdfsf);
+extern ER dfsdm_filterAwdStart(DFSDM_Filter_Handle_t *hdfsf, DFSDM_Filter_AwdParamTypeDef* awdParam);
+extern ER dfsdm_filterAwdStop(DFSDM_Filter_Handle_t *hdfsf);
+extern ER dfsdm_filterExdStart(DFSDM_Filter_Handle_t *hdfsf, uint32_t Channel);
+extern ER dfsdm_filterExdStop(DFSDM_Filter_Handle_t *hdfsf);
+
+extern int32_t  dfsdm_filterGetRegularValue(DFSDM_Filter_Handle_t *hdfsf, uint32_t* Channel);
+extern int32_t  dfsdm_filterGetInjectedValue(DFSDM_Filter_Handle_t *hdfsf, uint32_t* Channel);
+extern int32_t  dfsdm_filterGetExdMaxValue(DFSDM_Filter_Handle_t *hdfsf, uint32_t* Channel);
+extern int32_t  dfsdm_filterGetExdMinValue(DFSDM_Filter_Handle_t *hdfsf, uint32_t* Channel);
+extern uint32_t dfsdm_filterGetConvTimeValue(DFSDM_Filter_Handle_t *hdfsf);
+
+extern void dfsdm_irqhandler(DFSDM_Filter_Handle_t *hdfsf);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif	/* _DFSDM_H_ */
+
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/pdic/stm32f7xx/dsi.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/pdic/stm32f7xx/dsi.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/pdic/stm32f7xx/dsi.c	(revision 457)
@@ -0,0 +1,1237 @@
+/*
+ *  TOPPERS/ASP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Advanced Standard Profile Kernel
+ * 
+ *  Copyright (C) 2008-2011 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ *  Copyright (C) 2015-2017 by TOPPERS PROJECT Educational Working Group.
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+/*
+ * STM32F746-DSI用デバイスドライバ
+ */
+
+#include <kernel.h>
+#include <t_syslog.h>
+#include <t_stdlib.h>
+#include "syssvc/serial.h"
+#include "syssvc/syslog.h"
+#include <target_syssvc.h>
+#include "ltdc.h"
+#include "dsi.h"
+
+#define sil_orw_mem(a, b)		sil_wrw_mem((a), sil_rew_mem(a) | (b))
+#define sil_andw_mem(a, b)		sil_wrw_mem((a), sil_rew_mem(a) & ~(b))
+#define sil_modw_mem(a, b, c)	sil_wrw_mem((a), (sil_rew_mem(a) & (~b)) | (c))
+
+
+#define DSI_TIMEOUT_VALUE  1000			/* 1秒 */
+
+#define DSI_MAX_RTPKT_SIZE 0x00000037	/* 最大リターンパケットサイズ */
+
+#define DSI_CMCR_MASK     (DSI_CMCR_GSW0TX | DSI_CMCR_GSW1TX | DSI_CMCR_GSW2TX |\
+                           DSI_CMCR_GSR0TX | DSI_CMCR_GSR1TX | DSI_CMCR_GSR2TX |\
+                           DSI_CMCR_GLWTX  | DSI_CMCR_DSW0TX | DSI_CMCR_DSW1TX |\
+                           DSI_CMCR_DSR0TX | DSI_CMCR_DLWTX  | DSI_CMCR_MRDPS)
+/*
+ *  DSIの初期設定を行う
+ *  parameter1 hdsi     DSIハンドラへのポインタ
+ *  return              正常ならE_OK
+ */
+ER
+dsi_init(DSI_Handle_t *hdsi)
+{
+	uint32_t tick = 0;
+	uint32_t unitIntervalx4 = 0;
+	uint32_t temp;
+
+	if(hdsi == NULL)
+		return E_PAR;
+
+	hdsi->state = DSI_STATE_BUSY;
+
+	/*
+	 *  DSI PLL設定
+	 */
+	sil_orw_mem((uint32_t *)(hdsi->base+TOFF_DSI_WRPCR), DSI_WRPCR_REGEN);
+
+    /*
+	 *  レディ待ち
+	 */
+	while((sil_rew_mem((uint32_t *)(hdsi->base+TOFF_DSI_WISR)) & DSI_WISR_RRS) == 0){
+		if(tick > DSI_TIMEOUT_VALUE)
+			return E_TMOUT;
+		tick++;
+		dly_tsk(1);
+	}
+
+    /*
+	 *  PLLの分周設定
+	 */
+	temp  = sil_rew_mem((uint32_t *)(hdsi->base+TOFF_DSI_WRPCR));
+	temp &= ~(DSI_WRPCR_PLL_NDIV | DSI_WRPCR_PLL_IDF | DSI_WRPCR_PLL_ODF);
+	temp |= ((hdsi->Init.pllndiv)<<2) | ((hdsi->Init.pllidf)<<11) | ((hdsi->Init.pllodf)<<16);
+	sil_wrw_mem((uint32_t *)(hdsi->base+TOFF_DSI_WRPCR), temp);
+
+	/*
+	 *  DSI PLLイネーブル、レディ待ち
+	 */
+    tick = 0;
+	sil_orw_mem((uint32_t *)(hdsi->base+TOFF_DSI_WRPCR), DSI_WRPCR_PLLEN);
+	while((sil_rew_mem((uint32_t *)(hdsi->base+TOFF_DSI_WISR)) & DSI_WISR_PLLLS) == 0){
+		if(tick > DSI_TIMEOUT_VALUE)
+			return E_TMOUT;
+		tick++;
+		dly_tsk(1);
+	}
+
+    /*
+	 *  D-PHYクロック、デジタルイネーブル
+	 */
+	sil_orw_mem((uint32_t *)(hdsi->base+TOFF_DSI_PCTLR), (DSI_PCTLR_CKE | DSI_PCTLR_DEN));
+
+    /*
+	 *  クロックレーンのコンフィギュレーション
+	 */
+	temp  = sil_rew_mem((uint32_t *)(hdsi->base+TOFF_DSI_CLCR));
+	temp &= ~(DSI_CLCR_DPCC | DSI_CLCR_ACR);
+	temp |= (DSI_CLCR_DPCC | hdsi->Init.AutomaticClockLaneControl);
+	sil_wrw_mem((uint32_t *)(hdsi->base+TOFF_DSI_CLCR), temp);
+
+    /*
+	 *  データレーンのコンフィギュレーション
+	 */
+	sil_modw_mem((uint32_t *)(hdsi->base+TOFF_DSI_PCONFR), DSI_PCONFR_NL, hdsi->Init.NumberOfLanes);
+
+	/*
+	 *  DSIクロックパラメータ設定
+	 */
+	sil_modw_mem((uint32_t *)(hdsi->base+TOFF_DSI_CCR), DSI_CCR_TXECKDIV, hdsi->Init.TXEscapeCkdiv);
+
+	/*
+	 *  ハイスピードモード設定
+	 */
+	temp = (hdsi->Init.pllidf > 0) ? hdsi->Init.pllidf : 1;
+	unitIntervalx4 = (4000000 * temp * (1 << hdsi->Init.pllodf)) / ((HSE_VALUE/1000) * hdsi->Init.pllndiv);
+	sil_modw_mem((uint32_t *)(hdsi->base+TOFF_DSI_WPCR0), DSI_WPCR0_UIX4, unitIntervalx4);
+
+    /*
+	 *  エラー割込み無効化
+	 */
+	sil_wrw_mem((uint32_t *)(hdsi->base+TOFF_DSI_IER0), 0);
+	sil_wrw_mem((uint32_t *)(hdsi->base+TOFF_DSI_IER1), 0);
+
+    /*
+	 *  エラー情報リセット、レディ設定
+	 */
+    hdsi->errorcode = DSI_ERROR_NONE;
+	hdsi->state = DSI_STATE_READY;
+	return E_OK;
+}
+
+/*
+ *  DSIの非有効化設定を行う
+ *  parameter1 hdsi     DSIハンドラへのポインタ
+ *  return              正常ならE_OK
+ */
+ER
+dsi_deinit(DSI_Handle_t *hdsi)
+{
+	if(hdsi == NULL)
+		return E_PAR;
+
+	hdsi->state = DSI_STATE_BUSY;
+
+	/*
+	 *  DSI WRAPPER無効化
+	 */
+	sil_andw_mem((uint32_t *)(hdsi->base+TOFF_DSI_WCR), DSI_WCR_DSIEN);
+
+	/*
+	 *  DSIモジュール無効化
+	 */
+	sil_andw_mem((uint32_t *)(hdsi->base+TOFF_DSI_CR), DSI_CR_EN);
+
+	/*
+	 *  D-PHYクロック、デジタル無効化
+	 */
+	sil_andw_mem((uint32_t *)(hdsi->base+TOFF_DSI_PCTLR), (DSI_PCTLR_CKE | DSI_PCTLR_DEN));
+
+	/*
+	 *  DSI PLLオフ
+	 */
+	sil_andw_mem((uint32_t *)(hdsi->base+TOFF_DSI_WRPCR), DSI_WRPCR_PLLEN);
+
+	/*
+	 *  レギュレータ無効化
+	 */
+	sil_andw_mem((uint32_t *)(hdsi->base+TOFF_DSI_WRPCR), DSI_WRPCR_REGEN);
+
+    /*
+	 *  エラー情報リセット、リセット設定
+	 */
+	hdsi->errorcode = DSI_ERROR_NONE;
+	hdsi->state = DSI_STATE_RESET;
+	return E_OK;
+}
+
+
+/*
+ *  DSIビデオコンフィギュレーション設定
+ *  parameter1 hdsi     DSIハンドラへのポインタ
+ *  parameter2 pini     DSIビデオコンフィギュレーション設定へのポインタ
+ *  return              正常ならE_OK
+ */
+ER
+dsi_configvideo(DSI_Handle_t *hdsi, DSI_VideoConfig_t *pini)
+{
+	uint32_t temp;
+
+	if(hdsi == NULL || pini == NULL)
+		return E_PAR;
+	if(pini->ColorCoding == DSI_RGB666 && (pini->LooselyPacked & ~DSI_LCOLCR_LPE) != 0)
+		return E_PAR;
+
+	/*
+	 *  ビデオモード選択
+	 */
+	sil_andw_mem((uint32_t *)(hdsi->base+TOFF_DSI_MCR), DSI_MCR_CMDM);
+	sil_andw_mem((uint32_t *)(hdsi->base+TOFF_DSI_WCFGR), DSI_WCFGR_DSIM);
+
+	/*
+	 *  ビデオモード設定
+	 */
+	sil_modw_mem((uint32_t *)(hdsi->base+TOFF_DSI_VMCR), DSI_VMCR_VMT, pini->Mode);
+
+	/*
+	 *  ビデオパケットサイズ設定
+	 */
+	sil_modw_mem((uint32_t *)(hdsi->base+TOFF_DSI_VPCR), DSI_VPCR_VPSIZE, pini->PacketSize);
+
+	/*
+	 *  チャンク番号設定
+	 */
+	sil_modw_mem((uint32_t *)(hdsi->base+TOFF_DSI_VCCR), DSI_VCCR_NUMC, pini->NumberOfChunks);
+
+	/*
+	 *  ナルパケットサイズ設定
+	 */
+	sil_modw_mem((uint32_t *)(hdsi->base+TOFF_DSI_VNPCR), DSI_VNPCR_NPSIZE, pini->NullPacketSize);
+
+	/*
+	 *  バーチャルチャネル設定
+	 */
+	sil_modw_mem((uint32_t *)(hdsi->base+TOFF_DSI_LVCIDR), DSI_LVCIDR_VCID, pini->VirtualChannelID);
+
+	/*
+	 *  コントロールシグナルの極性設定
+	 */
+	temp  = sil_rew_mem((uint32_t *)(hdsi->base+TOFF_DSI_LPCR));
+	temp &= ~(DSI_LPCR_DEP | DSI_LPCR_VSP | DSI_LPCR_HSP);
+	temp |= (pini->DEPolarity | pini->VSPolarity | pini->HSPolarity);
+	sil_wrw_mem((uint32_t *)(hdsi->base+TOFF_DSI_LPCR), temp);
+
+	/*
+	 *  カラーコーディング設定
+	 */
+	sil_modw_mem((uint32_t *)(hdsi->base+TOFF_DSI_LCOLCR), DSI_LCOLCR_COLC, pini->ColorCoding);
+	sil_modw_mem((uint32_t *)(hdsi->base+TOFF_DSI_WCFGR), DSI_WCFGR_COLMUX, ((pini->ColorCoding)<<1));
+
+	/*
+	 *  RGB666用 loosely packed variants設定
+	 */
+	if(pini->ColorCoding == DSI_RGB666){
+		sil_modw_mem((uint32_t *)(hdsi->base+TOFF_DSI_LCOLCR), DSI_LCOLCR_LPE, pini->LooselyPacked);
+	}
+
+	/*
+	 *  Horizontal Synchronization Active (HSA)クロック設定
+	 */
+	sil_modw_mem((uint32_t *)(hdsi->base+TOFF_DSI_VHSACR), DSI_VHSACR_HSA, pini->HorizontalSyncActive);
+
+	/*
+	 *  Horizontal Back Porch (HBP)クロック設定
+	 */
+	sil_modw_mem((uint32_t *)(hdsi->base+TOFF_DSI_VHBPCR), DSI_VHBPCR_HBP, pini->HorizontalBackPorch);
+
+	/*
+	 * total line time (HLINE=HSA+HBP+HACT+HFP)クロック設定
+	 */
+	sil_modw_mem((uint32_t *)(hdsi->base+TOFF_DSI_VLCR), DSI_VLCR_HLINE, pini->HorizontalLine);
+
+	/*
+	 *  Vertical Synchronization Active (VSA)クロック設定
+	 */
+	sil_modw_mem((uint32_t *)(hdsi->base+TOFF_DSI_VVSACR), DSI_VVSACR_VSA, pini->VerticalSyncActive);
+
+	/*
+	 *  Vertical Back Porch (VBP)クロック設定
+	 */
+	sil_modw_mem((uint32_t *)(hdsi->base+TOFF_DSI_VVBPCR), DSI_VVBPCR_VBP, pini->VerticalBackPorch);
+
+	/*
+	 *  Vertical Front Porch (VFP)クロック設定
+	 */
+	sil_modw_mem((uint32_t *)(hdsi->base+TOFF_DSI_VVFPCR), DSI_VVFPCR_VFP, pini->VerticalFrontPorch);
+
+	/*
+	 *  Vertical Active period設定
+	 */
+	sil_modw_mem((uint32_t *)(hdsi->base+TOFF_DSI_VVACR), DSI_VVACR_VA, pini->VerticalActive);
+
+	/*
+	 *  Command transmission modeモード設定
+	 */
+	sil_modw_mem((uint32_t *)(hdsi->base+TOFF_DSI_VMCR), DSI_VMCR_LPCE, pini->LPCommandEnable);
+
+	/*
+	 *  Low power 最大パケットサイズ設定
+	 */
+	sil_modw_mem((uint32_t *)(hdsi->base+TOFF_DSI_LPMCR), DSI_LPMCR_LPSIZE, ((pini->LPLargestPacketSize)<<16));
+
+	/*
+	 *  Low power VACT 最大パケットサイズ設定
+	 */
+	sil_modw_mem((uint32_t *)(hdsi->base+TOFF_DSI_LPMCR), DSI_LPMCR_VLPSIZE, pini->LPVACTLargestPacketSize);
+
+	/*
+	 *  LP transition in HFP period設定
+	 */
+	sil_modw_mem((uint32_t *)(hdsi->base+TOFF_DSI_VMCR), DSI_VMCR_LPHFPE, pini->LPHorizontalFrontPorchEnable);
+
+	/*
+	 *  LP transition in HBP period設定
+	 */
+	sil_modw_mem((uint32_t *)(hdsi->base+TOFF_DSI_VMCR), DSI_VMCR_LPHBPE, pini->LPHorizontalBackPorchEnable);
+
+	/*
+	 *  LP transition in VACT period設定
+	 */
+	sil_modw_mem((uint32_t *)(hdsi->base+TOFF_DSI_VMCR), DSI_VMCR_LPVAE, pini->LPVerticalActiveEnable);
+
+	/*
+	 *  LP transition in VFP period設定
+	 */
+	sil_modw_mem((uint32_t *)(hdsi->base+TOFF_DSI_VMCR), DSI_VMCR_LPVFPE, pini->LPVerticalFrontPorchEnable);
+
+	/*
+	 *  LP transition in VBP period設定
+	 */
+	sil_modw_mem((uint32_t *)(hdsi->base+TOFF_DSI_VMCR), DSI_VMCR_LPVBPE, pini->LPVerticalBackPorchEnable);
+
+	/*
+	 *  LP transition in vertical sync period設定
+	 */
+	sil_modw_mem((uint32_t *)(hdsi->base+TOFF_DSI_VMCR), DSI_VMCR_LPVSAE, pini->LPVerticalSyncActiveEnable);
+
+	/*
+	 *  request for an acknowledge response設定
+	 */
+	sil_modw_mem((uint32_t *)(hdsi->base+TOFF_DSI_VMCR), DSI_VMCR_FBTAAE, pini->FrameBTAAcknowledgeEnable);
+	return E_OK;
+}
+
+/*
+ *  LTDCの初期化パラメータをDSI VIDEOモードから設定
+ *  parameter1 hltdc     LTDCの初期設定構造体へのポインタ
+ *  parameter2 pini      DSI VIDEOモード設定構造体へのポインタ
+ *  return               正常ならばE_OK
+ */
+ER
+dci_configltdc(LTDC_Handle_t* hltdc, DSI_VideoConfig_t *pini)
+{
+	if(hltdc == NULL || pini == NULL)
+		return E_PAR;
+
+	/*
+	 *  LTDC用極性設定
+	 */
+	hltdc->Init.DEPolarity = (pini->DEPolarity == DSI_DATA_ENABLE_ACTIVE_HIGH) ? LTDC_DEPOLARITY_AL : LTDC_DEPOLARITY_AH;
+	hltdc->Init.VSPolarity = (pini->VSPolarity == DSI_VSYNC_ACTIVE_HIGH) ? LTDC_VSPOLARITY_AH : LTDC_VSPOLARITY_AL;
+	hltdc->Init.HSPolarity = (pini->HSPolarity == DSI_HSYNC_ACTIVE_HIGH) ? LTDC_HSPOLARITY_AH : LTDC_HSPOLARITY_AL;
+
+	/*
+	 *  LTDC用バーチャルタイミングパラメータ設定
+	 */
+	hltdc->Init.VerticalSync       = pini->VerticalSyncActive - 1;
+	hltdc->Init.AccumulatedVBP     = pini->VerticalSyncActive + pini->VerticalBackPorch - 1;
+	hltdc->Init.AccumulatedActiveH = pini->VerticalSyncActive + pini->VerticalBackPorch + pini->VerticalActive - 1;
+	hltdc->Init.TotalHeigh         = pini->VerticalSyncActive + pini->VerticalBackPorch + pini->VerticalActive + pini->VerticalFrontPorch - 1;
+	return E_OK;
+}
+
+/*
+ *  適合コマンドモード設定
+ *  parameter1 hdsi      DSIハンドラへのポインタ
+ *  parameter2 pcfg      コマンド設定定義へのポインタ
+ *  parameter3 actactive 転送ACK有効無効設定(DSI_ACTIVE/DSI_INACTIVE)
+ *  return               正常ならばE_OK
+ */
+ER
+dsi_configadaptedCmdMode(DSI_Handle_t *hdsi, DSI_CommandConfig_t *pcfg, uint32_t ackactive)
+{
+	uint32_t temp;
+
+	if(hdsi == NULL || pcfg == NULL)
+		return E_PAR;
+	/*
+	 *  コマンドモード設定
+	 */
+	sil_orw_mem((uint32_t *)(hdsi->base+TOFF_DSI_MCR), DSI_MCR_CMDM);
+	sil_andw_mem((uint32_t *)(hdsi->base+TOFF_DSI_WCFGR), DSI_WCFGR_DSIM);
+	sil_orw_mem((uint32_t *)(hdsi->base+TOFF_DSI_WCFGR), DSI_WCFGR_DSIM);
+
+	/*
+	 *  バーチャルチャネル設定
+	 */
+	sil_modw_mem((uint32_t *)(hdsi->base+TOFF_DSI_LVCIDR), DSI_LVCIDR_VCID, pcfg->VirtualChannelID);
+
+	/*
+	 *  極性と制御シグナル設定
+	 */
+	temp  = sil_rew_mem((uint32_t *)(hdsi->base+TOFF_DSI_LPCR));
+	temp &= ~(DSI_LPCR_DEP | DSI_LPCR_VSP | DSI_LPCR_HSP);
+	temp |= (pcfg->DEPolarity | pcfg->VSPolarity | pcfg->HSPolarity);
+	sil_wrw_mem((uint32_t *)(hdsi->base+TOFF_DSI_LPCR), temp);
+
+	/*
+	 *  カラーコーディング選択
+	 */
+	sil_modw_mem((uint32_t *)(hdsi->base+TOFF_DSI_LCOLCR), DSI_LCOLCR_COLC, pcfg->ColorCoding);
+	sil_modw_mem((uint32_t *)(hdsi->base+TOFF_DSI_WCFGR), DSI_WCFGR_COLMUX, ((pcfg->ColorCoding)<<1));
+
+	/*
+	 *  最大コマンドサイズ設定
+	 */
+	sil_modw_mem((uint32_t *)(hdsi->base+TOFF_DSI_LCCR), DSI_LCCR_CMDSIZE, pcfg->CommandSize);
+
+	/*
+	 *  ティアリングエフェクトソース、極性、リフレッシュモード設定
+	 */
+	temp  = sil_rew_mem((uint32_t *)(hdsi->base+TOFF_DSI_WCFGR));
+	temp &= ~(DSI_WCFGR_TESRC | DSI_WCFGR_TEPOL | DSI_WCFGR_AR | DSI_WCFGR_VSPOL);
+	temp |= (pcfg->TearingEffectSource | pcfg->TearingEffectPolarity | pcfg->AutomaticRefresh | pcfg->VSyncPol);
+	sil_wrw_mem((uint32_t *)(hdsi->base+TOFF_DSI_WCFGR), temp);
+
+	/*
+	 *  転送ACK設定
+	 */
+	sil_modw_mem((uint32_t *)(hdsi->base+TOFF_DSI_CMCR), DSI_CMCR_TEARE, (ackactive & 1));
+
+ 	/*
+	 * 割込み設定
+	 */
+	sil_orw_mem((uint32_t *)(hdsi->base+TOFF_DSI_WIER), (DSI_WIER_TEIE | DSI_WIER_ERIE));
+	return E_OK;
+}
+
+/*
+ *  コマンド転送モード設定
+ *  parameter1 hdsi     DSIハンドラへのポインタ
+ *  parameter2 lpcmode  コマンドモード設定ビット値
+ *  parameter3 ackactive ACKのアクティブ設定(DSI_ACTIVE/DSI_INACTIVE)
+ *  return               正常ならばE_OK
+ */
+ER
+dsi_configcommand(DSI_Handle_t *hdsi, uint32_t lpcmode, uint32_t ackactive)
+{
+	if(hdsi == NULL)
+		return E_PAR;
+	/*
+	 *  コマンド転送モード設定
+	 */
+	sil_andw_mem((uint32_t *)(hdsi->base+TOFF_DSI_CMCR), DSI_CMCR_MASK);
+	sil_orw_mem((uint32_t *)(hdsi->base+TOFF_DSI_CMCR), (lpcmode & DSI_CMCR_MASK));
+
+	/*
+	 *  パケットACK設定
+	 */
+	sil_modw_mem((uint32_t *)(hdsi->base+TOFF_DSI_CMCR), DSI_CMCR_ARE, (ackactive<<1));
+	return E_OK;
+}
+
+/*
+ *  DSI PHYタイミング設定
+ *  parameter1 hdsi    DSIハンドラへのポインタ
+ *  parameter2 ptime   
+  * @brief  Configure the DSI PHY timer parameters
+  * @param  hdsi: pointer to a DSI_Handle_t structure that contains
+  *               the configuration information for the DSI.
+  * @param  ptime: DSI_PHY_Time_t structure that contains
+  *                    the DSI PHY timing parameters
+  * @retval HAL status
+  */
+ER
+dsi_configPhyTimer(DSI_Handle_t *hdsi, DSI_PHY_Time_t *ptime)
+{
+	uint32_t maxTime, temp;
+
+	maxTime = (ptime->ClockLaneLP2HSTime > ptime->ClockLaneHS2LPTime)? ptime->ClockLaneLP2HSTime: ptime->ClockLaneHS2LPTime;
+
+	/*
+	 *  クロックレーンタイマー設定
+	 */
+	temp  = sil_rew_mem((uint32_t *)(hdsi->base+TOFF_DSI_CLTCR));
+	temp &= ~(DSI_CLTCR_LP2HS_TIME | DSI_CLTCR_HS2LP_TIME);
+	temp |= (maxTime | ((maxTime)<<16));
+	sil_wrw_mem((uint32_t *)(hdsi->base+TOFF_DSI_CLTCR), temp);
+
+	/*
+	 *  データレーンタイマー設定
+	 */
+	temp  = sil_rew_mem((uint32_t *)(hdsi->base+TOFF_DSI_DLTCR));
+	temp &= ~(DSI_DLTCR_MRD_TIME | DSI_DLTCR_LP2HS_TIME | DSI_DLTCR_HS2LP_TIME);
+	temp |= (ptime->DataLaneMaxReadTime | ((ptime->DataLaneLP2HSTime)<<16) | ((ptime->DataLaneHS2LPTime)<<24));
+	sil_wrw_mem((uint32_t *)(hdsi->base+TOFF_DSI_DLTCR), temp);
+
+	/*
+	 *  停止状態の後の HS転送待ち時間設定
+	 */
+	sil_modw_mem((uint32_t *)(hdsi->base+TOFF_DSI_PCONFR), DSI_PCONFR_SW_TIME, ptime->StopWaitTime<<8);
+	return E_OK;
+}
+
+/*
+ *  DSI HOSTタイムアウト設定
+ *  parameter1 hdsi    DSIハンドラへのポインタ
+ *  parameter2 ptimeout DSI_HostTimeout_t structure that contains
+ *  return             正常ならE_OK
+ */
+ER
+dsi_configHostTimeout(DSI_Handle_t *hdsi, DSI_HostTimeout_t *ptimeout)
+{
+	/*
+	 * timeout clock division factor設定
+	 */
+	sil_modw_mem((uint32_t *)(hdsi->base+TOFF_DSI_CCR), DSI_CCR_TOCKDIV, (ptimeout->TimeoutCkdiv<<8));
+
+	/*
+	 *  High-speed transmission timeout設定
+	 */
+	sil_modw_mem((uint32_t *)(hdsi->base+TOFF_DSI_TCCR0), DSI_TCCR0_HSTX_TOCNT, ptimeout->HighSpeedTransmissionTimeout<<16);
+
+	/*
+	 *  Low-power reception timeout設定
+	 */
+	sil_modw_mem((uint32_t *)(hdsi->base+TOFF_DSI_TCCR0), DSI_TCCR0_LPRX_TOCNT, ptimeout->LowPowerReceptionTimeout);
+
+	/*
+	 *  High-speed read timeout設定
+	 */
+	sil_modw_mem((uint32_t *)(hdsi->base+TOFF_DSI_TCCR1), DSI_TCCR1_HSRD_TOCNT, ptimeout->HighSpeedReadTimeout);
+
+	/*
+	 *  Low-power read timeout設定
+	 */
+	sil_modw_mem((uint32_t *)(hdsi->base+TOFF_DSI_TCCR2), DSI_TCCR2_LPRD_TOCNT, ptimeout->LowPowerReadTimeout);
+
+	/*
+	 *  High-speed write timeout設定
+	 */
+	sil_modw_mem((uint32_t *)(hdsi->base+TOFF_DSI_TCCR3), DSI_TCCR3_HSWR_TOCNT, ptimeout->HighSpeedWriteTimeout);
+
+	/*
+	 *  High-speed write presp mode設定
+	 */
+	sil_modw_mem((uint32_t *)(hdsi->base+TOFF_DSI_TCCR3), DSI_TCCR3_PM, ptimeout->HighSpeedWritePrespMode);
+
+	/*
+	 *  Low-speed write timeout設定
+	 */
+	sil_modw_mem((uint32_t *)(hdsi->base+TOFF_DSI_TCCR4), DSI_TCCR4_LPWR_TOCNT, ptimeout->LowPowerWriteTimeout);
+
+	/*
+	 *  BTA timeout設定
+	 */
+	sil_modw_mem((uint32_t *)(hdsi->base+TOFF_DSI_TCCR5), DSI_TCCR5_BTA_TOCNT, ptimeout->BTATimeout);
+	return E_OK;
+}
+
+/*
+ *  DSIモジュール実行開始
+ *  parameter1 hdsi    DSIハンドラへのポインタ
+ *  return             正常ならE_OK
+ */
+ER
+dsi_start(DSI_Handle_t *hdsi)
+{
+	/*
+	 *  DSIモジュール有効化
+	 */
+	sil_orw_mem((uint32_t *)(hdsi->base+TOFF_DSI_CR), DSI_CR_EN);
+
+	/*
+	 *  DSI WRAPPER有効化
+	 */
+	sil_orw_mem((uint32_t *)(hdsi->base+TOFF_DSI_WCR), DSI_WCR_DSIEN);
+	return E_OK;
+}
+
+/*
+ *  DSIモジュール停止
+ *  parameter1 hdsi    DSIハンドラへのポインタ
+ *  return             正常ならE_OK
+ */
+ER
+dsi_stop(DSI_Handle_t *hdsi)
+{
+	/*
+	 *  DSIモジュール無効化
+	 */
+	sil_andw_mem((uint32_t *)(hdsi->base+TOFF_DSI_CR), DSI_CR_EN);
+
+	/*
+	 *  DSI WRAPPER無効化
+	 */
+	sil_andw_mem((uint32_t *)(hdsi->base+TOFF_DSI_WCR), DSI_WCR_DSIEN);
+	return E_OK;
+}
+
+/*
+ *  ショートWRITEコマンド
+ *  parameter1 hdsi    DSIハンドラへのポインタ
+ *  parameter2 Channel Virtual channel ID.
+ *  parameter3 Mode    DSI short packet data type.
+ *  parameter4 Param1  DSC command or first generic parameter.
+ *  parameter5 Param2  DSC parameter or second generic parameter.
+ *  return             正常ならE_OK
+ */
+ER
+dsi_swrite(DSI_Handle_t *hdsi, uint32_t Channel, uint32_t Mode, uint32_t Param1, uint32_t Param2)
+{
+	uint32_t tick = 0;
+
+	if(hdsi == NULL)
+		return E_PAR;
+	/*
+	 *  書込みFIFOエンプティ待ち
+	 */
+	while((sil_rew_mem((uint32_t *)(hdsi->base+TOFF_DSI_GPSR)) & DSI_GPSR_CMDFE) == 0){
+		if(tick > DSI_TIMEOUT_VALUE)
+			return E_TMOUT;
+		tick++;
+		dly_tsk(1);
+	}
+
+	/*
+	 *  書込みコマンド設定
+	 */
+	sil_wrw_mem((uint32_t *)(hdsi->base+TOFF_DSI_GHCR), (Mode | (Channel<<6) | (Param1<<8) | (Param2<<16)));
+	return E_OK;
+}
+
+/*
+ *  ロングWRITEコマンド
+ *  parameter1 hdsi    DSIハンドラへのポインタ
+ *  parameter2 Channel Virtual channel ID.
+ *  parameter3 Mode    DSI long packet data type.
+ *  parameter4 NbParams: Number of parameters.
+ *  parameter5 Param1: DSC command or first generic parameter.
+ *  parameter6 buf: Pointer to parameter values table.
+ *  return             正常ならE_OK
+ */
+ER
+dsi_lwrite(DSI_Handle_t *hdsi, uint32_t Channel, uint32_t Mode, uint32_t NbParams, uint32_t Param1, uint8_t* buf)
+{
+	uint32_t no = 0;
+	uint32_t tick = 0;
+
+	if(hdsi == NULL)
+		return E_PAR;
+	/*
+	 *  書込みFIFOエンプティ待ち
+	 */
+	while((sil_rew_mem((uint32_t *)(hdsi->base+TOFF_DSI_GPSR)) & DSI_GPSR_CMDFE) == 0){
+		if(tick > DSI_TIMEOUT_VALUE)
+			return E_TMOUT;
+		tick++;
+		dly_tsk(1);
+	}
+
+	/* Set the DCS code hexadecimal on payload byte 1, and the other parameters on the write FIFO command*/
+	while(no < NbParams){
+		if(no == 0x00){
+			sil_wrw_mem((uint32_t *)(hdsi->base+TOFF_DSI_GPDR), (Param1 | \
+                            ((uint32_t)(*(buf + no)) << 8) | \
+                            ((uint32_t)(*(buf + no+1))<<16) | \
+                            ((uint32_t)(*(buf + no+2))<<24)));
+			no += 3;
+		}
+		else{
+			sil_wrw_mem((uint32_t *)(hdsi->base+TOFF_DSI_GPDR), ((uint32_t)(*(buf + no)) | \
+                            ((uint32_t)(*(buf + no+1)) << 8) | \
+                            ((uint32_t)(*(buf + no+2)) << 16) | \
+                            ((uint32_t)(*(buf + no+3)) << 24)));
+			no += 4;
+		}
+	}
+
+	/*
+	 *  書込みパケット設定
+	 */
+	sil_wrw_mem((uint32_t *)(hdsi->base+TOFF_DSI_GHCR), (Mode | (Channel<<6) | (((NbParams+1)&0x00FF)<<8) | (((NbParams+1)&0xFF00)<<8)));
+	return E_OK;
+}
+
+/*
+ *  DSIコマンドリード
+ *  parameter1 hdsi    DSIハンドラへのポインタ
+ *  parameter2 Channel Virtual channel ID
+ *  parameter3 Array   pointer to a buffer to store the payload of a read back operation.
+ *  parameter4 Size    Data size to be read (in byte).
+ *  parameter5 Mode    DSI read packet data type.
+ *  parameter6 DCSCmd  DCS get/read command.
+ *  parameter7 buf     設定領域へのポインタ
+ *  return             正常ならE_OK
+ */
+ER
+dsi_read(DSI_Handle_t *hdsi, uint32_t Channel, uint8_t* Array, uint32_t Size, uint32_t Mode, uint32_t DCSCmd, uint8_t* buf)
+{
+	uint32_t tick = 0;
+
+	if(Size > 2){	/* リターンパケットサイズ設定 */
+		dsi_swrite(hdsi, Channel, DSI_MAX_RTPKT_SIZE, ((Size)&0xFF), (((Size)>>8)&0xFF));
+	}
+
+	/*
+	 *  READコマンド設定
+	 */
+	if(Mode == DSI_DCS_SHORT_PKT_READ){
+		sil_wrw_mem((uint32_t *)(hdsi->base+TOFF_DSI_GHCR), (Mode | (Channel<<6) | (DCSCmd<<8) | (0<<16)));
+	}
+	else if(Mode == DSI_GEN_SHORT_PKT_READ_P0){
+		sil_wrw_mem((uint32_t *)(hdsi->base+TOFF_DSI_GHCR), (Mode | (Channel<<6) | (0<<8) | (0<<16)));
+	}
+	else if(Mode == DSI_GEN_SHORT_PKT_READ_P1){
+		sil_wrw_mem((uint32_t *)(hdsi->base+TOFF_DSI_GHCR), (Mode | (Channel<<6) | (buf[0]<<8) | (0<<16)));
+	}
+	else if(Mode == DSI_GEN_SHORT_PKT_READ_P2){
+		sil_wrw_mem((uint32_t *)(hdsi->base+TOFF_DSI_GHCR), (Mode | (Channel<<6) | (buf[0]<<8) | (buf[1]<<16)));
+	}
+	else{
+		return E_PAR;
+	}
+
+	/*
+	 *  読み出しFIFO設定待ち
+	 */
+	while((sil_rew_mem((uint32_t *)(hdsi->base+TOFF_DSI_GPSR)) & DSI_GPSR_PRDFE) != 0){
+		/* Check for the Timeout */
+		if(tick > DSI_TIMEOUT_VALUE)
+			return E_TMOUT;
+		tick++;
+		dly_tsk(1);
+	}
+
+	/*
+	 *  第一バイト取出し
+	 */
+	*((uint32_t *)Array) = sil_rew_mem((uint32_t *)(hdsi->base+TOFF_DSI_GPDR));
+	if(Size > 4){
+		Size -= 4;
+		Array += 4;
+	}
+	else{
+		return E_OK;
+	}
+
+	/*
+	 *  残りバイト取出し
+	 */
+	tick = 0;
+	while(((int)(Size)) > 0){
+		if((sil_rew_mem((uint32_t *)(hdsi->base+TOFF_DSI_GPSR)) & DSI_GPSR_PRDFE) == 0){
+			*((uint32_t *)Array) = sil_rew_mem((uint32_t *)(hdsi->base+TOFF_DSI_GPDR));
+			Size -= 4;
+			Array += 4;
+		}
+		if(tick > DSI_TIMEOUT_VALUE)
+			return E_TMOUT;
+		tick++;
+		dly_tsk(1);
+	}
+	return E_OK;
+}
+
+/*
+ *  ULPM(Ultra Low Power Mode設定(D-PHY PLL running)
+ *  parameter1 hdsi    DSIハンドラへのポインタ
+ *  return             正常ならE_OK
+ */
+ER
+dsi_enterULPMData(DSI_Handle_t *hdsi)
+{
+	uint32_t tick = 0;
+	uint32_t pconfrnl;
+
+	/*
+	 *  DSI Host PHY ULPSのデータレーンオン
+	 */
+	sil_orw_mem((uint32_t *)(hdsi->base+TOFF_DSI_PUCR), DSI_PUCR_URDL);
+
+ 	/*
+	 *  D-PHYアクティブレーン設定待ち
+	 */
+	pconfrnl = sil_rew_mem((uint32_t *)(hdsi->base+TOFF_DSI_PCONFR)) & DSI_PCONFR_NL;
+	if(pconfrnl == DSI_ONE_DATA_LANE){
+		while((sil_rew_mem((uint32_t *)(hdsi->base+TOFF_DSI_PSR)) & DSI_PSR_UAN0) != 0){
+			if(tick > DSI_TIMEOUT_VALUE)
+				return E_TMOUT;
+			tick++;
+			dly_tsk(1);
+		}
+	}
+	else if(pconfrnl == DSI_TWO_DATA_LANES){
+		while((sil_rew_mem((uint32_t *)(hdsi->base+TOFF_DSI_PSR)) & (DSI_PSR_UAN0 | DSI_PSR_UAN1)) != 0){
+			if(tick > DSI_TIMEOUT_VALUE)
+				return E_TMOUT;
+			tick++;
+			dly_tsk(1);
+		}
+	}
+	return E_OK;
+}
+
+/*
+ *  ULPM(Ultra Low Power Mode終了(D-PHY PLL running)
+ *  parameter1 hdsi    DSIハンドラへのポインタ
+ *  return             正常ならE_OK
+ */
+ER
+dsi_exitULPMData(DSI_Handle_t *hdsi)
+{
+	uint32_t tick = 0;
+	uint32_t pconfrnl;
+
+	/*
+	 *  DSI Host PHY ULPSのデータレーン終了
+	 */
+	sil_orw_mem((uint32_t *)(hdsi->base+TOFF_DSI_PUCR), DSI_PUCR_UEDL);
+
+	/*
+	 *  D-PHYレーンアクティブ待ち
+	 */
+	pconfrnl = sil_rew_mem((uint32_t *)(hdsi->base+TOFF_DSI_PCONFR)) & DSI_PCONFR_NL;
+	if(pconfrnl == DSI_ONE_DATA_LANE){
+		while((sil_rew_mem((uint32_t *)(hdsi->base+TOFF_DSI_PSR)) & DSI_PSR_UAN0) == 0){
+			if(tick > DSI_TIMEOUT_VALUE)
+				return E_TMOUT;
+			tick++;
+			dly_tsk(1);
+		}
+	}
+	else if(pconfrnl == DSI_TWO_DATA_LANES){
+		while((sil_rew_mem((uint32_t *)(hdsi->base+TOFF_DSI_PSR)) & (DSI_PSR_UAN0 | DSI_PSR_UAN1)) != (DSI_PSR_UAN0 | DSI_PSR_UAN1)){
+			if(tick > DSI_TIMEOUT_VALUE)
+				return E_TMOUT;
+			tick++;
+			dly_tsk(1);
+		}
+	}
+
+	/*
+	 *  DSI Host PHY ULPSのクロックとデータレーンビットをすべてオフ
+	 */
+	sil_wrw_mem((uint32_t *)(hdsi->base+TOFF_DSI_PUCR), 0);
+	return E_OK;
+}
+
+/*
+ *  ULPM(Ultra Low Power Mode設定(D-PHY PLL turned off)
+ *  parameter1 hdsi    DSIハンドラへのポインタ
+ *  return             正常ならE_OK
+ */
+ER
+dsi_enterULPM(DSI_Handle_t *hdsi)
+{
+	uint32_t tick = 0;
+	uint32_t pconfrnl;
+
+	/*
+	 *  D-PHY制御オフ
+	 */
+	sil_andw_mem((uint32_t *)(hdsi->base+TOFF_DSI_CLCR), DSI_CLCR_DPCC);
+
+	/*
+	 *  D-PHYからのクロックソースオン
+	 */
+	sil_orw_mem((uint32_t *)(TADR_RCC_BASE+TOFF_RCC_DCKCFGR2), RCC_DCKCFGR2_DSISEL);
+
+	/*
+	 *  DSI Host PHY ULPSのクロックとデータレーンオン
+	 */
+	sil_orw_mem((uint32_t *)(hdsi->base+TOFF_DSI_PUCR), (DSI_PUCR_URCL | DSI_PUCR_URDL));
+
+	/*
+	 * アクティブレーン終了待ち
+	 */
+	pconfrnl = sil_rew_mem((uint32_t *)(hdsi->base+TOFF_DSI_PCONFR)) & DSI_PCONFR_NL;
+	if(pconfrnl == DSI_ONE_DATA_LANE){
+		while((sil_rew_mem((uint32_t *)(hdsi->base+TOFF_DSI_PSR)) & (DSI_PSR_UAN0 | DSI_PSR_UANC)) != 0){
+			if(tick > DSI_TIMEOUT_VALUE)
+				return E_TMOUT;
+			tick++;
+			dly_tsk(1);
+		}
+	}
+	else if(pconfrnl == DSI_TWO_DATA_LANES){
+		while((sil_rew_mem((uint32_t *)(hdsi->base+TOFF_DSI_PSR)) & (DSI_PSR_UAN0 | DSI_PSR_UAN1 | DSI_PSR_UANC)) != 0){
+			if(tick > DSI_TIMEOUT_VALUE)
+				return E_TMOUT;
+			tick++;
+			dly_tsk(1);
+		}
+	}
+
+	/*
+	 *  DSI PLLオフ
+	 */
+	sil_andw_mem((uint32_t *)(hdsi->base+TOFF_DSI_WRPCR), DSI_WRPCR_PLLEN);
+	return E_OK;
+}
+
+/*
+ *  ULPM(Ultra Low Power Mode)終了(D-PHY PLL turned off)
+ *  parameter1 hdsi    DSIハンドラへのポインタ
+ *  return             正常ならE_OK
+ */
+ER
+dsi_exitULPM(DSI_Handle_t *hdsi)
+{
+	uint32_t tick = 0;
+	uint32_t pconfrnl;
+
+	/*
+	 *  DSI PLLオン
+	 */
+	sil_orw_mem((uint32_t *)(hdsi->base+TOFF_DSI_WRPCR), DSI_WRPCR_PLLEN);
+
+	/*
+	 *  DSI PLLロック待ち
+	 */
+	while((sil_rew_mem((uint32_t *)(hdsi->base+TOFF_DSI_WISR)) & DSI_WISR_PLLLS) == 0){
+		if(tick > DSI_TIMEOUT_VALUE)
+			return E_TMOUT;
+		tick++;
+		dly_tsk(1);
+	}
+
+	/*
+	 *  DSI Host PHY ULPSのクロックとデータレーン終了
+	 */
+	sil_orw_mem((uint32_t *)(hdsi->base+TOFF_DSI_PUCR), (DSI_PUCR_UECL | DSI_PUCR_UEDL));
+
+	/*
+	 * レーンアクティブレーン待ち
+	 */
+	tick = 0;
+	pconfrnl = sil_rew_mem((uint32_t *)(hdsi->base+TOFF_DSI_PCONFR)) & DSI_PCONFR_NL;
+	if(pconfrnl == DSI_ONE_DATA_LANE){
+		while((sil_rew_mem((uint32_t *)(hdsi->base+TOFF_DSI_PSR)) & (DSI_PSR_UAN0 | DSI_PSR_UANC)) != (DSI_PSR_UAN0 | DSI_PSR_UANC)){
+			/* Check for the Timeout */
+			if(tick > DSI_TIMEOUT_VALUE)
+				return E_TMOUT;
+			tick++;
+			dly_tsk(1);
+		}
+	}
+	else if(pconfrnl == DSI_TWO_DATA_LANES){
+		while((sil_rew_mem((uint32_t *)(hdsi->base+TOFF_DSI_PSR)) & (DSI_PSR_UAN0 | DSI_PSR_UAN1 | DSI_PSR_UANC)) != (DSI_PSR_UAN0 | DSI_PSR_UAN1 | DSI_PSR_UANC)){
+			/* Check for the Timeout */
+			if(tick > DSI_TIMEOUT_VALUE)
+				return E_TMOUT;
+			tick++;
+			dly_tsk(1);
+		}
+	}
+
+	/*
+	 *  DSI Host PHY ULPSのクロックとデータレーンビットをすべてオフ
+	 */
+	sil_wrw_mem((uint32_t *)(hdsi->base+TOFF_DSI_PUCR), 0);
+
+	/*
+	 *  D-PHYからのクロックソースオフ
+	 */
+	sil_andw_mem((uint32_t *)(TADR_RCC_BASE+TOFF_RCC_DCKCFGR2), RCC_DCKCFGR2_DSISEL);
+
+	/*
+	 *  D-PHY制御オオン
+	 */
+	sil_orw_mem((uint32_t *)(hdsi->base+TOFF_DSI_CLCR), DSI_CLCR_DPCC);
+
+	return E_OK;
+}
+
+/*
+ *  テストパターン生成開始
+ *  parameter1 hdsi    DSIハンドラへのポインタ
+ *  parameter2 mode    Pattern generator mode(0:color bars, 1:ber pattern)
+ *  parameter3 orient  Pattern generator orientation(0:垂直,1:水平)
+ */
+void
+dsi_startPatternGenerator(DSI_Handle_t *hdsi, uint32_t mode, uint32_t orient)
+{
+	mode   &= 1;
+	orient &= 1;
+	/* Configure pattern generator mode and orientation */
+	sil_andw_mem((uint32_t *)(hdsi->base+TOFF_DSI_VMCR), (DSI_VMCR_PGM | DSI_VMCR_PGO));
+	sil_orw_mem((uint32_t *)(hdsi->base+TOFF_DSI_VMCR), ((mode<<20) | (orient<<24)));
+
+	/* Enable pattern generator by setting PGE bit */
+	sil_orw_mem((uint32_t *)(hdsi->base+TOFF_DSI_VMCR), DSI_VMCR_PGE);
+}
+
+/*
+ *  テストパターン生成終了
+ *  parameter1 hdsi    DSIハンドラへのポインタ
+ */
+void
+dsi_stopPatternGenerator(DSI_Handle_t *hdsi)
+{
+	sil_andw_mem((uint32_t *)(hdsi->base+TOFF_DSI_VMCR), DSI_VMCR_PGE);
+}
+
+/*
+ *  カスタムラインピン設定
+ *  parameter1 hdsi    DSIハンドラへのポインタ
+ *  parameter2 customl カスタムレーン
+ *  parameter3 lane    レーン設定
+ *  parameter4 active  DSI_ACTIVE/DSI_INACTIVE
+ *  return             正常ならE_OK
+ */
+ER
+dsi_setLanePinsConfiguration(DSI_Handle_t *hdsi, uint32_t customlane, uint32_t lane, uint32_t active)
+{
+	if(hdsi == NULL)
+		return E_PAR;
+	active &= 1;
+	if(customlane == DSI_SWAP_LANE_PINS){
+		if(lane == DSI_CLOCK_LANE)		/* SWAP PINS on clock lane */
+			sil_modw_mem((uint32_t *)(hdsi->base+TOFF_DSI_WPCR0), DSI_WPCR0_SWCL, ((uint32_t)active << 6));
+		else if(lane == DSI_DATA_LANE0)	/* SWAP PINS on data lane 0 */
+			sil_modw_mem((uint32_t *)(hdsi->base+TOFF_DSI_WPCR0), DSI_WPCR0_SWDL0, ((uint32_t)active << 7));
+		else if(lane == DSI_DATA_LANE1)	/* SWAP PINS on data lane 1 */
+			sil_modw_mem((uint32_t *)(hdsi->base+TOFF_DSI_WPCR0), DSI_WPCR0_SWDL1, ((uint32_t)active << 8));
+		else
+			return E_PAR;
+	}
+	else if(customlane == DSI_INVERT_HS_SIGNAL){
+		if(lane == DSI_CLOCK_LANE)		/* INVERT HS SIGNAL on clock lane */
+			sil_modw_mem((uint32_t *)(hdsi->base+TOFF_DSI_WPCR0), DSI_WPCR0_HSICL, ((uint32_t)active << 9));
+		else if(lane == DSI_DATA_LANE0)	/* INVERT HS SIGNAL on data lane 0 */
+			sil_modw_mem((uint32_t *)(hdsi->base+TOFF_DSI_WPCR0), DSI_WPCR0_HSIDL0, ((uint32_t)active << 10));
+		else if(lane == DSI_DATA_LANE1)	/* INVERT HS SIGNAL on data lane 1 */
+			sil_modw_mem((uint32_t *)(hdsi->base+TOFF_DSI_WPCR0), DSI_WPCR0_HSIDL1, ((uint32_t)active << 11));
+		else
+			return E_PAR;
+	}
+	else
+		return E_PAR;
+	return E_OK;
+}
+
+/*
+ *  PHYタイミング設定
+ *  parameter1 hdsi    DSIハンドラへのポインタ
+ *  parameter2 timing  設定タイムング
+ *  parameter3 active  DSI_ACTIVE/DSI_INACTIVE
+ *  parameter4 value   設定値             the configuration information for the DSI.
+ *  return             正常ならE_OK
+ */
+ER
+dsi_setPHYTiming(DSI_Handle_t *hdsi, uint32_t timing, uint32_t active, uint32_t Value)
+{
+	if(hdsi == NULL)
+		return E_PAR;
+	active &= 1;
+	switch(timing){
+	case DSI_TCLK_POST:
+		sil_modw_mem((uint32_t *)(hdsi->base+TOFF_DSI_WPCR0), DSI_WPCR0_TCLKPOSTEN, (active << 27));
+		if(active == DSI_ACTIVE)
+			sil_modw_mem((uint32_t *)(hdsi->base+TOFF_DSI_WPCR4), DSI_WPCR4_TCLKPOST, Value & DSI_WPCR4_TCLKPOST);
+		break;
+	case DSI_TLPX_CLK:
+		sil_modw_mem((uint32_t *)(hdsi->base+TOFF_DSI_WPCR0), DSI_WPCR0_TLPXCEN, (active << 26));
+		if(active == DSI_ACTIVE)
+			sil_modw_mem((uint32_t *)(hdsi->base+TOFF_DSI_WPCR3), DSI_WPCR3_TLPXC, (Value << 24) & DSI_WPCR3_TLPXC);
+		break;
+	case DSI_THS_EXIT:
+		sil_modw_mem((uint32_t *)(hdsi->base+TOFF_DSI_WPCR0), DSI_WPCR0_THSEXITEN, (active << 25));
+		if(active == DSI_ACTIVE)
+			sil_modw_mem((uint32_t *)(hdsi->base+TOFF_DSI_WPCR3), DSI_WPCR3_THSEXIT, (Value << 16) & DSI_WPCR3_THSEXIT);
+		break;
+	case DSI_TLPX_DATA:
+		sil_modw_mem((uint32_t *)(hdsi->base+TOFF_DSI_WPCR0), DSI_WPCR0_TLPXDEN, (active << 24));
+		if(active == DSI_ACTIVE)
+			sil_modw_mem((uint32_t *)(hdsi->base+TOFF_DSI_WPCR3), DSI_WPCR3_TLPXD, (Value << 8) & DSI_WPCR3_TLPXD);
+		break;
+	case DSI_THS_ZERO:
+		sil_modw_mem((uint32_t *)(hdsi->base+TOFF_DSI_WPCR0), DSI_WPCR0_THSZEROEN, (active << 23));
+		if(active == DSI_ACTIVE)
+			sil_modw_mem((uint32_t *)(hdsi->base+TOFF_DSI_WPCR3), DSI_WPCR3_THSZERO, Value & DSI_WPCR3_THSZERO);
+		break;
+	case DSI_THS_TRAIL:
+		sil_modw_mem((uint32_t *)(hdsi->base+TOFF_DSI_WPCR0), DSI_WPCR0_THSTRAILEN, (active << 22));
+		if(active == DSI_ACTIVE)
+			sil_modw_mem((uint32_t *)(hdsi->base+TOFF_DSI_WPCR2), DSI_WPCR2_THSTRAIL, (Value << 24) & DSI_WPCR2_THSTRAIL);
+		break;
+	case DSI_THS_PREPARE:
+		sil_modw_mem((uint32_t *)(hdsi->base+TOFF_DSI_WPCR0), DSI_WPCR0_THSPREPEN, (active << 21));
+		if(active == DSI_ACTIVE)
+			sil_modw_mem((uint32_t *)(hdsi->base+TOFF_DSI_WPCR2), DSI_WPCR2_THSPREP, (Value << 16) & DSI_WPCR2_THSPREP);
+		break;
+	case DSI_TCLK_ZERO:
+		sil_modw_mem((uint32_t *)(hdsi->base+TOFF_DSI_WPCR0), DSI_WPCR0_TCLKZEROEN, (active << 20));
+		if(active == DSI_ACTIVE)
+			sil_modw_mem((uint32_t *)(hdsi->base+TOFF_DSI_WPCR2), DSI_WPCR2_TCLKZERO, (Value << 8) & DSI_WPCR2_TCLKZERO);
+		break;
+	case DSI_TCLK_PREPARE:
+		sil_modw_mem((uint32_t *)(hdsi->base+TOFF_DSI_WPCR0), DSI_WPCR0_TCLKPREPEN, (active << 19));
+		if(active == DSI_ACTIVE)
+			sil_modw_mem((uint32_t *)(hdsi->base+TOFF_DSI_WPCR2), DSI_WPCR2_TCLKPREP, Value & DSI_WPCR2_TCLKPREP);
+		break;
+	default:
+		return E_PAR;
+	}
+	return E_OK;
+}
+
+/*
+ *  クロック/データレーン強制停止
+ *  parameter1 hdsi    DSIハンドラへのポインタ
+ *  parameter2 lane    レーン選択(DSI_CLOCK_LANE/DSI_DATA_LANES)
+ *  parameter3 actine  DSI_ACTIVE/DSI_INACTIVE
+ *  return             正常ならE_OK
+ */
+ER
+dsi_forceTXStopMode(DSI_Handle_t *hdsi, uint32_t lane, uint32_t active)
+{
+	if(hdsi == NULL)
+		return E_PAR;
+	if(lane == DSI_CLOCK_LANE){
+		/*
+		 *  クロックレーンストップ
+		 */
+		sil_modw_mem((uint32_t *)(hdsi->base+TOFF_DSI_WPCR0), DSI_WPCR0_FTXSMCL, (active << 12));
+	}
+	else if(lane == DSI_DATA_LANES){
+		/*
+		 *  データレーンストップ
+		 */
+		sil_modw_mem((uint32_t *)(hdsi->base+TOFF_DSI_WPCR0), DSI_WPCR0_FTXSMDL, (active << 13));
+	}
+	return E_OK;
+}
+
+/*
+ *  DSI割込みハンドラ
+ */
+void dsi_irqhandler(DSI_Handle_t *hdsi)
+{
+	uint32_t isr0 = sil_rew_mem((uint32_t *)(hdsi->base+TOFF_DSI_ISR0));
+	uint32_t isr1 = sil_rew_mem((uint32_t *)(hdsi->base+TOFF_DSI_ISR1));
+
+	isr0 &= sil_rew_mem((uint32_t *)(hdsi->base+TOFF_DSI_IER0));
+	isr1 &= sil_rew_mem((uint32_t *)(hdsi->base+TOFF_DSI_IER1));
+
+	/*
+	 *  ティアリングエフェクトチェック
+	 */
+	if((sil_rew_mem((uint32_t *)(hdsi->base+TOFF_DSI_WISR)) & DSI_WISR_TEIF) != 0){
+		if((sil_rew_mem((uint32_t *)(hdsi->base+TOFF_DSI_WISR)) & DSI_WIER_TEIE) != 0){
+			/*
+			 *  ティアリングエフェクト割込みクリア
+			 */
+			sil_wrw_mem((uint32_t *)(hdsi->base+TOFF_DSI_WIFCR), DSI_WISR_TEIF);
+
+			/*
+			 *  ティアリングエフェクトコールバック
+			 */
+			if(hdsi->teffectcallback != NULL)
+				hdsi->teffectcallback(hdsi);
+		}
+	}
+
+	/*
+	 *  リフレッシュ終了イベントチェック
+	 */
+	if((sil_rew_mem((uint32_t *)(hdsi->base+TOFF_DSI_WISR)) & DSI_WISR_ERIF) != 0){
+		if((sil_rew_mem((uint32_t *)(hdsi->base+TOFF_DSI_WISR)) & DSI_WIER_ERIE) != 0){
+			/*
+			 *  リフレッシュ割込みクリア
+			 */
+			sil_wrw_mem((uint32_t *)(hdsi->base+TOFF_DSI_WIFCR), DSI_WISR_ERIF);
+
+			/*
+			 *  リフレッシュコールバック
+			 */
+			if(hdsi->refreshcallback != NULL)
+				hdsi->refreshcallback(hdsi);
+		}
+	}
+
+	/*
+	 *  エラーフラグチェック
+	 */
+	if((isr0 & DSI_INT_ACKERR_REQ) != 0)
+		hdsi->errorcode |= DSI_ERROR_ACK;
+	if((isr0 & DSI_INT_PHYERR_REQ) != 0)
+		hdsi->errorcode |= DSI_ERROR_PHY;
+	if((isr1 & DSI_ISR1_TOHSTX) != 0)
+		hdsi->errorcode |= DSI_ERROR_TX;
+	if((isr1 & DSI_ISR1_TOLPRX) != 0)
+		hdsi->errorcode |= DSI_ERROR_RX;
+	if((isr1 & (DSI_ISR1_ECCSE | DSI_ISR1_ECCME)) != 0)
+		hdsi->errorcode |= DSI_ERROR_ECC;
+	if((isr1 & DSI_ISR1_CRCE) != 0)
+		hdsi->errorcode |= DSI_ERROR_CRC;
+	if((isr1 & DSI_ISR1_PSE) != 0)
+		hdsi->errorcode |= DSI_ERROR_PSE;
+	if((isr1 & DSI_ISR1_EOTPE) != 0)
+		hdsi->errorcode |= DSI_ERROR_EOT;
+	if((isr1 & DSI_ISR1_LPWRE) != 0)
+		hdsi->errorcode |= DSI_ERROR_OVF;
+	if((isr1 & DSI_INT_GENERR_REQ) != 0)
+		hdsi->errorcode |= DSI_ERROR_GEN;
+
+	/*
+	 *  DSIエラーコールバック
+	 */
+	if(hdsi->errorcode != DSI_ERROR_NONE){
+		if(hdsi->errorcallback != NULL)
+			hdsi->errorcallback(hdsi);
+	}
+}
+
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/pdic/stm32f7xx/dsi.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/pdic/stm32f7xx/dsi.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/pdic/stm32f7xx/dsi.h	(revision 457)
@@ -0,0 +1,663 @@
+/*
+ *  TOPPERS/ASP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Advanced Standard Profile Kernel
+ * 
+ *  Copyright (C) 2008-2011 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ *  Copyright (C) 2015-2017 by TOPPERS PROJECT Educational Working Group.
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+/*
+ * 
+ *  STM32F7xx DSIデバイスドライバの外部宣言
+ *
+ */
+
+#ifndef _DSI_H_
+#define _DSI_H_
+
+#include "ltdc.h"
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+
+/*
+ *  DSI ACTIVE/INACTIVE設定
+ */
+#define DSI_INACTIVE              0
+#define DSI_ACTIVE                1
+
+/*
+ *  DSI_VideoConfig_t設定
+ */
+/*  ColorCoding設定 */
+#define DSI_RGB565               0x00000000	/* RGB565 color mode configuration */
+#define DSI_RGB666               0x00000003	/* RGB666 color mode configuration */
+#define DSI_RGB888               0x00000005
+
+/*  Mode設定 */
+#define DSI_VID_MODE_NB_PULSES   0x00000000
+#define DSI_VID_MODE_NB_EVENTS   0x00000001
+#define DSI_VID_MODE_BURST       0x00000002
+
+/*  LPCommandEnable設定 */
+#define DSI_LP_COMMAND_DISABLE   0x00000000
+#define DSI_LP_COMMAND_ENABLE    DSI_VMCR_LPCE
+
+/*  LPHorizontalFrontPorchEnable設定 */
+#define DSI_LP_HFP_DISABLE       0x00000000
+#define DSI_LP_HFP_ENABLE        DSI_VMCR_LPHFPE
+
+/*  LPHorizontalBackPorchEnable設定 */
+#define DSI_LP_HBP_DISABLE       0x00000000
+#define DSI_LP_HBP_ENABLE        DSI_VMCR_LPHBPE
+
+/*  LPVerticalActiveEnable設定 */
+#define DSI_LP_VACT_DISABLE      0x00000000
+#define DSI_LP_VACT_ENABLE       DSI_VMCR_LPVAE
+
+/*  LPVerticalFrontPorchEnable設定 */
+#define DSI_LP_VFP_DISABLE       0x00000000
+#define DSI_LP_VFP_ENABLE        DSI_VMCR_LPVFPE
+
+/*  LPVerticalBackPorchEnable設定 */
+#define DSI_LP_VBP_DISABLE       0x00000000
+#define DSI_LP_VBP_ENABLE        DSI_VMCR_LPVBPE
+
+/*  LPVerticalSyncActiveEnable設定 */
+#define DSI_LP_VSYNC_DISABLE     0x00000000
+#define DSI_LP_VSYNC_ENABLE      DSI_VMCR_LPVSAE
+
+/*  FrameBTAAcknowledgeEnable設定 */
+#define DSI_FBTAA_DISABLE        0x00000000
+#define DSI_FBTAA_ENABLE         DSI_VMCR_FBTAAE
+
+/*  LooselyPacked設定 */
+#define DSI_LOOSELY_PACKED_DISABLE 0x00000000
+#define DSI_LOOSELY_PACKED_ENABLE  DSI_LCOLCR_LPE
+
+/*  HSPolarity設定 */
+#define DSI_HSYNC_ACTIVE_HIGH    0x00000000
+#define DSI_HSYNC_ACTIVE_LOW     DSI_LPCR_HSP
+
+/*  VSPolarity設定 */
+#define DSI_VSYNC_ACTIVE_HIGH    0x00000000
+#define DSI_VSYNC_ACTIVE_LOW     DSI_LPCR_VSP
+
+/*  DEPolarity設定 */
+#define DSI_DATA_ENABLE_ACTIVE_HIGH 0x00000000
+#define DSI_DATA_ENABLE_ACTIVE_LOW  DSI_LPCR_DEP
+
+
+/*
+ *  DSI_CommandConfig_t設定
+ */
+/*  TearingEffectSource設定 */
+#define DSI_TE_DSILINK           0x00000000
+#define DSI_TE_EXTERNAL          DSI_WCFGR_TESRC
+
+/*  TearingEffectPolarity設定 */
+#define DSI_TE_RISING_EDGE       0x00000000
+#define DSI_TE_FALLING_EDGE      DSI_WCFGR_TEPOL
+
+/*  VSyncPol設定 */
+#define DSI_VSYNC_FALLING        0x00000000
+#define DSI_VSYNC_RISING         DSI_WCFGR_VSPOL
+
+/*  AutomaticRefresh設定 */
+#define DSI_AR_DISABLE           0x00000000
+#define DSI_AR_ENABLE            DSI_WCFGR_AR
+
+/*
+ *  LP COMMAND MODE(dsi_configcommand)設定ビット定義
+ */
+/*  DSI LP LPGen Short Write NoP */
+#define DSI_LP_GSW0P_DISABLE     0x00000000
+#define DSI_LP_GSW0P_ENABLE      DSI_CMCR_GSW0TX
+
+/*  DSI LP LPGen Short Write OneP */
+#define DSI_LP_GSW1P_DISABLE     0x00000000
+#define DSI_LP_GSW1P_ENABLE      DSI_CMCR_GSW1TX
+
+/*  DSI LP LPGen Short Write TwoP */
+#define DSI_LP_GSW2P_DISABLE     0x00000000
+#define DSI_LP_GSW2P_ENABLE      DSI_CMCR_GSW2TX
+
+/*  DSI LP LPGen Short Read NoP */
+#define DSI_LP_GSR0P_DISABLE     0x00000000
+#define DSI_LP_GSR0P_ENABLE      DSI_CMCR_GSR0TX
+
+/*  DSI LP LPGen Short Read OneP */
+#define DSI_LP_GSR1P_DISABLE     0x00000000
+#define DSI_LP_GSR1P_ENABLE      DSI_CMCR_GSR1TX
+
+/*  DSI LP LPGen Short Read TwoP */
+#define DSI_LP_GSR2P_DISABLE     0x00000000
+#define DSI_LP_GSR2P_ENABLE      DSI_CMCR_GSR2TX
+
+/*  DSI LP LPGen LongWrite */
+#define DSI_LP_GLW_DISABLE       0x00000000
+#define DSI_LP_GLW_ENABLE        DSI_CMCR_GLWTX
+
+/*  DSI LP LPDcs Short Write NoP */
+#define DSI_LP_DSW0P_DISABLE     0x00000000
+#define DSI_LP_DSW0P_ENABLE      DSI_CMCR_DSW0TX
+
+/*  DSI LP LPDcs Short Write OneP */
+#define DSI_LP_DSW1P_DISABLE     0x00000000
+#define DSI_LP_DSW1P_ENABLE      DSI_CMCR_DSW1TX
+
+/*  DSI LP LPDcs Short Read NoP */
+#define DSI_LP_DSR0P_DISABLE     0x00000000
+#define DSI_LP_DSR0P_ENABLE      DSI_CMCR_DSR0TX
+
+/*  DSI LP LPDcs Long Write */
+#define DSI_LP_DLW_DISABLE       0x00000000
+#define DSI_LP_DLW_ENABLE        DSI_CMCR_DLWTX
+
+/*  DSI LP LPMax Read Packet */
+#define DSI_LP_MRDP_DISABLE      0x00000000
+#define DSI_LP_MRDP_ENABLE       DSI_CMCR_MRDPS
+
+/*
+ *  DSI_HostTimeout_t設定
+ */
+/*  HighSpeedWritePrespMode設定 */
+#define DSI_HS_PM_DISABLE        0x00000000
+#define DSI_HS_PM_ENABLE         DSI_TCCR3_PM
+
+/*
+ *  DSI_Init_t設定
+ */
+/*  AutomaticClockLaneControl設定 */
+#define DSI_AUTO_CLK_LANE_CTRL_DISABLE 0x00000000
+#define DSI_AUTO_CLK_LANE_CTRL_ENABLE  DSI_CLCR_ACR
+
+/*  NumberOfLanes定義 */
+#define DSI_ONE_DATA_LANE        0
+#define DSI_TWO_DATA_LANES       1
+
+/*  pllidf設定 */
+#define DSI_PLL_IN_DIV1          0x00000001
+#define DSI_PLL_IN_DIV2          0x00000002
+#define DSI_PLL_IN_DIV3          0x00000003
+#define DSI_PLL_IN_DIV4          0x00000004
+#define DSI_PLL_IN_DIV5          0x00000005
+#define DSI_PLL_IN_DIV6          0x00000006
+#define DSI_PLL_IN_DIV7          0x00000007
+
+/*  pllodf設定 */
+#define DSI_PLL_OUT_DIV1         0x00000000
+#define DSI_PLL_OUT_DIV2         0x00000001
+#define DSI_PLL_OUT_DIV4         0x00000002
+#define DSI_PLL_OUT_DIV8         0x00000003
+
+
+/*
+ *  DSIショートWRITEコマンドモード定義(Mode)
+ */
+#define DSI_DCS_SHORT_PKT_WRITE_P0 0x00000005	/* DCS short write, no parameters */
+#define DSI_DCS_SHORT_PKT_WRITE_P1 0x00000015	/* DCS short write, one parameter */
+#define DSI_GEN_SHORT_PKT_WRITE_P0 0x00000003	/* Generic short write, no parameters */
+#define DSI_GEN_SHORT_PKT_WRITE_P1 0x00000013	/* Generic short write, one parameter */
+#define DSI_GEN_SHORT_PKT_WRITE_P2 0x00000023	/* Generic short write, two parameters */
+
+/*
+ *  DSIロングWRITEコマンドモード定義(Mode)
+ */
+#define DSI_DCS_LONG_PKT_WRITE    0x00000039	/* DCS long write     */
+#define DSI_GEN_LONG_PKT_WRITE    0x00000029	/* Generic long write */
+
+/*
+ *  DSIコマンドREADコマンドモード定義(Mode)
+ */
+#define DSI_DCS_SHORT_PKT_READ    0x00000006	/* DCS short read */
+#define DSI_GEN_SHORT_PKT_READ_P0 0x00000004	/* Generic short read, no parameters  */
+#define DSI_GEN_SHORT_PKT_READ_P1 0x00000014	/* Generic short read, one parameter  */
+#define DSI_GEN_SHORT_PKT_READ_P2 0x00000024	/* Generic short read, two parameters */
+
+/*
+ *  DSI DCSコマンドモード定義
+ */
+#define DSI_ENTER_IDLE_MODE       0x39
+#define DSI_ENTER_INVERT_MODE     0x21
+#define DSI_ENTER_NORMAL_MODE     0x13
+#define DSI_ENTER_PARTIAL_MODE    0x12
+#define DSI_ENTER_SLEEP_MODE      0x10
+#define DSI_EXIT_IDLE_MODE        0x38
+#define DSI_EXIT_INVERT_MODE      0x20
+#define DSI_EXIT_SLEEP_MODE       0x11
+#define DSI_GET_3D_CONTROL        0x3F
+#define DSI_GET_ADDRESS_MODE      0x0B
+#define DSI_GET_BLUE_CHANNEL      0x08
+#define DSI_GET_DIAGNOSTIC_RESULT 0x0F
+#define DSI_GET_DISPLAY_MODE      0x0D
+#define DSI_GET_GREEN_CHANNEL     0x07
+#define DSI_GET_PIXEL_FORMAT      0x0C
+#define DSI_GET_POWER_MODE        0x0A
+#define DSI_GET_RED_CHANNEL       0x06
+#define DSI_GET_SCANLINE          0x45
+#define DSI_GET_SIGNAL_MODE       0x0E
+#define DSI_NOP                   0x00
+#define DSI_READ_DDB_CONTINUE     0xA8
+#define DSI_READ_DDB_START        0xA1
+#define DSI_READ_MEMORY_CONTINUE  0x3E
+#define DSI_READ_MEMORY_START     0x2E
+#define DSI_SET_3D_CONTROL        0x3D
+#define DSI_SET_ADDRESS_MODE      0x36
+#define DSI_SET_COLUMN_ADDRESS    0x2A
+#define DSI_SET_DISPLAY_OFF       0x28
+#define DSI_SET_DISPLAY_ON        0x29
+#define DSI_SET_GAMMA_CURVE       0x26
+#define DSI_SET_PAGE_ADDRESS      0x2B
+#define DSI_SET_PARTIAL_COLUMNS   0x31
+#define DSI_SET_PARTIAL_ROWS      0x30
+#define DSI_SET_PIXEL_FORMAT      0x3A
+#define DSI_SET_SCROLL_AREA       0x33
+#define DSI_SET_SCROLL_START      0x37
+#define DSI_SET_TEAR_OFF          0x34
+#define DSI_SET_TEAR_ON           0x35
+#define DSI_SET_TEAR_SCANLINE     0x44
+#define DSI_SET_VSYNC_TIMING      0x40
+#define DSI_SOFT_RESET            0x01
+#define DSI_WRITE_LUT             0x2D
+#define DSI_WRITE_MEMORY_CONTINUE 0x3C
+#define DSI_WRITE_MEMORY_START    0x2C
+
+
+/*
+ *  DSIカスタムレーン定義(customlane)
+ */
+#define DSI_SWAP_LANE_PINS       0x00000000
+#define DSI_INVERT_HS_SIGNAL     0x00000001
+
+/*
+ *  DSIレーンタイミング定義(lane)
+ */
+#define DSI_CLOCK_LANE           0x00000000
+#define DSI_DATA_LANES           0x00000001
+#define DSI_DATA_LANE0           0x00000001
+#define DSI_DATA_LANE1           0x00000002
+
+/*
+ *  DSI PHYタイミング定義(timing)
+ */
+#define DSI_TCLK_POST            0x00000000
+#define DSI_TLPX_CLK             0x00000001
+#define DSI_THS_EXIT             0x00000002
+#define DSI_TLPX_DATA            0x00000003
+#define DSI_THS_ZERO             0x00000004
+#define DSI_THS_TRAIL            0x00000005
+#define DSI_THS_PREPARE          0x00000006
+#define DSI_TCLK_ZERO            0x00000007
+#define DSI_TCLK_PREPARE         0x00000008
+
+/*
+ *  DSIエラー定義
+ */
+#define DSI_ERROR_NONE           0x00000000		/* エラーなし */
+#define DSI_ERROR_ACK            0x00000001		/* ACKエラー */
+#define DSI_ERROR_PHY            0x00000002		/* PHYエラー */
+#define DSI_ERROR_TX             0x00000004		/* 送信エラー */
+#define DSI_ERROR_RX             0x00000008		/* 受信エラー */
+#define DSI_ERROR_ECC            0x00000010		/* ECCエラー */
+#define DSI_ERROR_CRC            0x00000020		/* CRCエラー */
+#define DSI_ERROR_PSE            0x00000040		/* パケットサイズエラー */
+#define DSI_ERROR_EOT            0x00000080		/* EOTエラー */
+#define DSI_ERROR_OVF            0x00000100		/* FIFOオーバーフローエラー */
+#define DSI_ERROR_GEN            0x00000200		/* ジェネリックFIFOエラー */
+
+/*
+ *  DSI状態定義
+ */
+#define DSI_STATE_RESET          0x00000000		/* DSI リセット状態 */
+#define DSI_STATE_READY          0x00000001		/* DSI レディ状態 */
+#define DSI_STATE_BUSY           0x00000002		/* DSI ビジィ状態 */
+#define DSI_STATE_ERROR          0x00010000		/* DSI エラー状態 */
+
+
+/*
+ *  DSI初期化設定定義
+ */
+typedef struct
+{
+	uint32_t           AutomaticClockLaneControl;	/* Automatic clock lane control */
+	uint32_t           TXEscapeCkdiv;				/* TX Escape clock division */
+	uint32_t           NumberOfLanes;				/* Number of lanes */
+    uint32_t           pllndiv;						/* PLL Loop Division Factor */
+    uint32_t           pllidf;						/* PLL Input Division Factor */
+	uint32_t           pllodf;						/* PLL Output Division Factor */
+} DSI_Init_t;
+
+/*
+ *  DSIビデオコンフィギュレーション設定
+ */
+typedef struct 
+{
+	uint32_t           VirtualChannelID;			/* Virtual channel ID */
+	uint32_t           ColorCoding;					/* Color coding for LTDC interface */
+	uint32_t           LooselyPacked;				/* Enable or disable loosely packed stream */
+	uint32_t           Mode;						/* Video mode type */
+	uint32_t           PacketSize;					/* Video packet size */
+	uint32_t           NumberOfChunks;				/* Number of chunks */
+	uint32_t           NullPacketSize;				/* Null packet size */
+	uint32_t           HSPolarity;					/* HSYNC pin polarity */
+	uint32_t           VSPolarity;					/* VSYNC pin polarity */
+	uint32_t           DEPolarity;					/* Data Enable pin polarity */
+	uint32_t           HorizontalSyncActive;		/* Horizontal synchronism active duration */
+	uint32_t           HorizontalBackPorch;			/* Horizontal back-porch duration */
+	uint32_t           HorizontalLine;				/* Horizontal line duration */
+	uint32_t           VerticalSyncActive;			/* Vertical synchronism active duration */
+	uint32_t           VerticalBackPorch;			/* Vertical back-porch duration */
+	uint32_t           VerticalFrontPorch;			/* Vertical front-porch duration */
+	uint32_t           VerticalActive;				/* Vertical active duration */
+	uint32_t           LPCommandEnable;				/* Low-power command enable */
+	uint32_t           LPLargestPacketSize;			/* the low power largest packet size that can fit in a line during VSA, VBP and VFP regions */
+	uint32_t           LPVACTLargestPacketSize;		/* the low power largest packet size that can fit in a line during VACT region */
+	uint32_t           LPHorizontalFrontPorchEnable;	/* Low-power horizontal front-porch enable */
+	uint32_t           LPHorizontalBackPorchEnable;	/* Low-power horizontal back-porch enable */
+	uint32_t           LPVerticalActiveEnable;		/* Low-power vertical active enable */
+	uint32_t           LPVerticalFrontPorchEnable;	/* Low-power vertical front-porch enable */
+	uint32_t           LPVerticalBackPorchEnable;	/* Low-power vertical back-porch enable */
+	uint32_t           LPVerticalSyncActiveEnable;	/* Low-power vertical sync active enable */
+	uint32_t           FrameBTAAcknowledgeEnable;	/* Frame bus-turn-around acknowledge enable */
+} DSI_VideoConfig_t;
+
+/*
+ *  DSI コマンドコンフィギュレーション定義
+ */
+typedef struct
+{
+	uint32_t           VirtualChannelID;			/* Virtual channel ID */
+	uint32_t           ColorCoding;					/* Color coding for LTDC interface */
+	uint32_t           CommandSize;					/* Maximum allowed size for an LTDC write memory command, measured in pixels */
+	uint32_t           TearingEffectSource;			/* Tearing effect source */
+	uint32_t           TearingEffectPolarity;		/* Tearing effect pin polarity */
+	uint32_t           HSPolarity;					/* HSYNC pin polarity */
+	uint32_t           VSPolarity;					/* VSYNC pin polarity */
+	uint32_t           DEPolarity;					/* Data Enable pin polarity */
+	uint32_t           VSyncPol;					/* VSync edge on which the LTDC is halted */
+	uint32_t           AutomaticRefresh;			/* Automatic refresh mode */
+} DSI_CommandConfig_t;
+
+/*
+ *  DSI PHY タイミング定義
+ */
+typedef struct
+{
+	uint32_t           ClockLaneHS2LPTime;			/* The maximum time that the D-PHY clock lane takes to go from high-speed to low-power transmission */
+	uint32_t           ClockLaneLP2HSTime;			/* The maximum time that the D-PHY clock lane takes to go from low-power to high-speed transmission */
+	uint32_t           DataLaneHS2LPTime;			/* The maximum time that the D-PHY data lanes takes to go from high-speed to low-power transmission */
+	uint32_t           DataLaneLP2HSTime;			/* The maximum time that the D-PHY data lanes takes to go from low-power to high-speed transmission */
+	uint32_t           DataLaneMaxReadTime;			/* The maximum time required to perform a read command */
+	uint32_t           StopWaitTime;				/* The minimum wait period to request a High-Speed transmission after the Stop state */
+} DSI_PHY_Time_t;
+
+/*
+ *  DSI HOSTタイムアウト定義
+ */
+typedef struct
+{
+	uint32_t           TimeoutCkdiv;				/* Time-out clock division */
+	uint32_t           HighSpeedTransmissionTimeout;	/* High-speed transmission time-out */
+	uint32_t           LowPowerReceptionTimeout;	/* Low-power reception time-out */
+	uint32_t           HighSpeedReadTimeout;		/* High-speed read time-out */
+	uint32_t           LowPowerReadTimeout;			/* Low-power read time-out */
+	uint32_t           HighSpeedWriteTimeout;		/* High-speed write time-out */
+	uint32_t           HighSpeedWritePrespMode;		/* High-speed write presp mode */
+	uint32_t           LowPowerWriteTimeout;		/* Low-speed write time-out */
+	uint32_t           BTATimeout;					/* BTA time-out */
+  
+} DSI_HostTimeout_t;
+
+/**
+  * @brief  DSI Handle Structure definition
+  */
+typedef struct DSI_Handle_s DSI_Handle_t;
+struct DSI_Handle_s
+{
+	uint32_t           base;			/* DSI ベースレジスタ */
+    DSI_Init_t         Init;			/* DSI required parameters    */
+	void               (*teffectcallback)(DSI_Handle_t * hdsi);	/* TearEffctコールバック関数 */
+	void               (*refreshcallback)(DSI_Handle_t * hdsi);	/* リフレッシュ終了コールバック関数 */
+	void               (*errorcallback)(DSI_Handle_t * hdsi);	/* エラーコールバック関数 */
+	volatile uint32_t  state;		  	/* DSI 実行状態 */
+	volatile uint32_t  errorcode;		/* DSI Error code */
+};
+
+extern ER dsi_init(DSI_Handle_t *hdsi);
+extern ER dsi_deinit(DSI_Handle_t *hdsi);
+extern ER dsi_configvideo(DSI_Handle_t *hdsi, DSI_VideoConfig_t *pini);
+extern ER dci_configltdc(LTDC_Handle_t* hltdc, DSI_VideoConfig_t *pini);
+extern ER dsi_configadaptedCmdMode(DSI_Handle_t *hdsi, DSI_CommandConfig_t *pcfg, uint32_t ackactive);
+extern ER dsi_configcommand(DSI_Handle_t *hdsi, uint32_t lpcmode, uint32_t ackactive);
+extern ER dsi_configPhyTimer(DSI_Handle_t *hdsi, DSI_PHY_Time_t *ptime);
+extern ER dsi_configHostTimeout(DSI_Handle_t *hdsi, DSI_HostTimeout_t *ptimeout);
+extern ER dsi_start(DSI_Handle_t *hdsi);
+extern ER dsi_stop(DSI_Handle_t *hdsi);
+extern ER dsi_swrite(DSI_Handle_t *hdsi, uint32_t Channel, uint32_t Mode, uint32_t Param1, uint32_t Param2);
+extern ER dsi_lwrite(DSI_Handle_t *hdsi, uint32_t Channel, uint32_t Mode, uint32_t NbParams, uint32_t Param1, uint8_t* buf);
+extern ER dsi_read(DSI_Handle_t *hdsi, uint32_t Channel, uint8_t* Array, uint32_t Size, uint32_t Mode, uint32_t DCSCmd, uint8_t* buf);
+extern ER dsi_enterULPMData(DSI_Handle_t *hdsi);
+extern ER dsi_exitULPMData(DSI_Handle_t *hdsi);
+extern ER dsi_enterULPM(DSI_Handle_t *hdsi);
+extern ER dsi_exitULPM(DSI_Handle_t *hdsi);
+extern void dsi_startPatternGenerator(DSI_Handle_t *hdsi, uint32_t Mode, uint32_t Orientation);
+extern void dsi_stopPatternGenerator(DSI_Handle_t *hdsi);
+extern ER dsi_setLanePinsConfiguration(DSI_Handle_t *hdsi, uint32_t CustomLane, uint32_t Lane, uint32_t active);
+extern ER dsi_setPHYTiming(DSI_Handle_t *hdsi, uint32_t Timing, uint32_t active, uint32_t Value);
+extern ER dsi_forceTXStopMode(DSI_Handle_t *hdsi, uint32_t Lane, uint32_t active);
+
+extern void dsi_irqhandler(DSI_Handle_t *hdsi);
+
+/*
+ *  SLEW RATE High-Speed Transmission Slew Rate Control on Clock Lane設定
+ */
+#define dsi_setSRateHSTXClock(h, v) sil_wrw_mem((uint32_t *)((h)->base+TOFF_DSI_WPCR1), \
+									((sil_rew_mem((uint32_t *)((h)->base+TOFF_DSI_WPCR1)) & ~DSI_WPCR1_HSTXSRCCL) |((v)<<16)))
+
+/*
+ *  SLEW RATE High-Speed Transmission Slew Rate Control on Data Lanes設定
+ */
+#define dsi_setSRateHSTXLane(h, v)  sil_wrw_mem((uint32_t *)((h)->base+TOFF_DSI_WPCR1), \
+									((sil_rew_mem((uint32_t *)((h)->base+TOFF_DSI_WPCR1)) & ~DSI_WPCR1_HSTXSRCDL) |((v)<<18)))
+
+/* 
+ *  SLEW RATE Low-Power transmission Slew Rate Compensation on Clock Lane設定
+ */
+#define dsi_setSRateLPTXClock(h, v) sil_wrw_mem((uint32_t *)((h)->base+TOFF_DSI_WPCR1), \
+									((sil_rew_mem((uint32_t *)((h)->base+TOFF_DSI_WPCR1)) & ~DSI_WPCR1_LPSRCCL) |((v)<<6)))
+
+/*
+ *  SLEW RATE Low-Power transmission Slew Rate Compensation on Data Lanes設定
+ */
+#define dsi_setSRateLPTXLane(h, v)  sil_wrw_mem((uint32_t *)((h)->base+TOFF_DSI_WPCR1), \
+									((sil_rew_mem((uint32_t *)((h)->base+TOFF_DSI_WPCR1)) & ~DSI_WPCR1_LPSRCDL) |((v)<<8)))
+
+/*
+ *  DEALYタイミング High-Speed Transmission Delay on Clock Lane設定
+ */
+#define dsi_setHSDealyClock(h, v)   sil_wrw_mem((uint32_t *)((h)->base+TOFF_DSI_WPCR1), \
+									((sil_rew_mem((uint32_t *)((h)->base+TOFF_DSI_WPCR1)) & ~DSI_WPCR1_HSTXDCL) |(v)))
+
+/*
+ *  DEAYタイミング High-Speed Transmission Delay on Data Lanes設定
+ */
+#define dsi_setHSDealyLane(h, v)    sil_wrw_mem((uint32_t *)((h)->base+TOFF_DSI_WPCR1), \
+									((sil_rew_mem((uint32_t *)((h)->base+TOFF_DSI_WPCR1)) & ~DSI_WPCR1_HSTXDDL) |((v)<<2)))
+
+
+/*
+ *  Configure the Generic interface read-back Virtual Channel ID.
+ */
+#define dsi_setGenericVCID(h, v)	sil_wrw_mem((uint32_t *)((h)->base+TOFF_DSI_GVCIDR), \
+									((sil_rew_mem((uint32_t *)((h)->base+TOFF_DSI_GVCIDR)) & ~DSI_GVCIDR_VCID) |(v)))
+
+/*
+ *  Configure the flow control parameters
+ */
+#define dsi_confFlowControl(h, v)	sil_wrw_mem((uint32_t *)((h)->base+TOFF_DSI_PCR), \
+									((sil_rew_mem((uint32_t *)((h)->base+TOFF_DSI_PCR)) & ~DSI_FLOW_CONTROL_ALL) |(v)))
+
+/*
+ *  Refresh the display in command mode
+ */
+#define dsi_refresh(h)				sil_wrw_mem((uint32_t *)((h)->base+TOFF_DSI_WCR), \
+									(sil_rew_mem((uint32_t *)((h)->base+TOFF_DSI_WCR)) | DSI_WCR_LTDCEN))
+
+/*
+ *  Controls the display color mode in Video mode
+ */
+#define dsi_colorMode(h, v)			sil_wrw_mem((uint32_t *)((h)->base+TOFF_DSI_WCR), \
+									((sil_rew_mem((uint32_t *)((h)->base+TOFF_DSI_WCR)) & ~DSI_WCR_COLM) |(v)))
+
+/*
+ *  Control the display shutdown in Video mode
+ */
+#define dsi_shutdown(h, v)			sil_wrw_mem((uint32_t *)((h)->base+TOFF_DSI_WCR), \
+									((sil_rew_mem((uint32_t *)((h)->base+TOFF_DSI_WCR)) & ~DSI_WCR_SHTDN) |((v)<<1)))
+
+/*
+ *  Low-Power Reception Filter Tuning
+ */
+#define dsi_setLowPowRXFilter(h, v)	sil_wrw_mem((uint32_t *)((h)->base+TOFF_DSI_WPCR1), \
+									((sil_rew_mem((uint32_t *)((h)->base+TOFF_DSI_WPCR1)) & ~DSI_WPCR1_LPRXFT) |((v)<<25)))
+
+/*
+ *  Activate an additional current path on all lanes to meet the SDDTx parameter
+ */
+#define dsi_setSDD(h, v)			sil_wrw_mem((uint32_t *)((h)->base+TOFF_DSI_WPCR1), \
+									((sil_rew_mem((uint32_t *)((h)->base+TOFF_DSI_WPCR1)) & ~DSI_WPCR1_SDDC) |((v)<<12)))
+
+/*
+ *  Forces LP Receiver in Low-Power Mode
+ */
+#define dsi_forceRXLowPower(h, v)	sil_wrw_mem((uint32_t *)((h)->base+TOFF_DSI_WPCR1), \
+									((sil_rew_mem((uint32_t *)((h)->base+TOFF_DSI_WPCR1)) & ~DSI_WPCR1_FLPRXLPM) |((v)<<22)))
+
+/*
+ *  Force Data Lanes in RX Mode after a BTA
+ */
+#define dsi_forceDataLanesRX(h, v)	sil_wrw_mem((uint32_t *)((h)->base+TOFF_DSI_WPCR0), \
+									((sil_rew_mem((uint32_t *)((h)->base+TOFF_DSI_WPCR0)) & ~DSI_WPCR0_TDDL) |((v)<<16)))
+
+/*
+ *  Enable a pull-down on the lanes to prevent from floating states when unused
+ */
+#define dsi_setPullDown(h, v)		sil_wrw_mem((uint32_t *)((h)->base+TOFF_DSI_WPCR0), \
+									((sil_rew_mem((uint32_t *)((h)->base+TOFF_DSI_WPCR0)) & ~DSI_WPCR0_PDEN) |((v)<<18)))
+
+/*
+ *  Switch off the contention detection on data lanes
+ */
+#define dsi_setContDetectOff(h, v)	sil_wrw_mem((uint32_t *)((h)->base+TOFF_DSI_WPCR0), \
+									((sil_rew_mem((uint32_t *)((h)->base+TOFF_DSI_WPCR0)) & ~DSI_WPCR0_CDOFFDL) |((v)<<14)))
+
+/*
+ *  エラー割込み設定
+ */
+#define DSI_INT_ACKERR_REQ (DSI_ISR0_AE0 | DSI_ISR0_AE1 | DSI_ISR0_AE2 | DSI_ISR0_AE3 | \
+                            DSI_ISR0_AE4 | DSI_ISR0_AE5 | DSI_ISR0_AE6 | DSI_ISR0_AE7 | \
+                            DSI_ISR0_AE8 | DSI_ISR0_AE9 | DSI_ISR0_AE10 | DSI_ISR0_AE11 | \
+                            DSI_ISR0_AE12 | DSI_ISR0_AE13 | DSI_ISR0_AE14 | DSI_ISR0_AE15)
+#define DSI_INT_PHYERR_REQ (DSI_ISR0_PE0 | DSI_ISR0_PE1 | DSI_ISR0_PE2 | DSI_ISR0_PE3 | DSI_ISR0_PE4)
+#define DSI_INT_GENERR_REQ (DSI_ISR1_GCWRE | DSI_ISR1_GPWRE | DSI_ISR1_GPTXE | DSI_ISR1_GPRDE | DSI_ISR1_GPRXE)
+
+/*
+ *  ACKエラー割込み要求
+ */
+#define dsi_int_ackerr(h)			sil_wrw_mem((uint32_t *)((h)->base+TOFF_DSI_IER0), \
+									(sil_rew_mem((uint32_t *)((h)->base+TOFF_DSI_IER0)) | DSI_INT_ACKERR_REQ))
+
+/*
+ *  PHYエラー割込み要求
+ */
+#define dsi_int_phyerr(h)			sil_wrw_mem((uint32_t *)((h)->base+TOFF_DSI_IER0), \
+									(sil_rew_mem((uint32_t *)((h)->base+TOFF_DSI_IER0)) | DSI_INT_PHYERR_REQ))
+
+/*
+ *  TXエラー割込み要求
+ */
+#define dsi_int_txerr(h)			sil_wrw_mem((uint32_t *)((h)->base+TOFF_DSI_IER1), \
+									(sil_rew_mem((uint32_t *)((h)->base+TOFF_DSI_IER1)) | DSI_ISR1_TOHSTX))
+
+/*
+ *  RXエラー割込み要求
+ */
+#define dsi_int_rxerr(h)			sil_wrw_mem((uint32_t *)((h)->base+TOFF_DSI_IER1), \
+									(sil_rew_mem((uint32_t *)((h)->base+TOFF_DSI_IER1)) | DSI_ISR1_TOLPRX))
+/*
+ *  ECCエラー割込み要求
+ */
+#define dsi_int_eccerr(h)			sil_wrw_mem((uint32_t *)((h)->base+TOFF_DSI_IER1), \
+									(sil_rew_mem((uint32_t *)((h)->base+TOFF_DSI_IER1)) | (DSI_ISR1_ECCSE | DSI_ISR1_ECCME)))
+
+/*
+ *  CRCエラー割込み要求
+ */
+#define dsi_int_crcerr(h)			sil_wrw_mem((uint32_t *)((h)->base+TOFF_DSI_IER1), \
+									(sil_rew_mem((uint32_t *)((h)->base+TOFF_DSI_IER1)) | DSI_ISR1_CRCE))
+
+/*
+ *  PSEエラー割込み要求
+ */
+#define dsi_int_pseerr(h)			sil_wrw_mem((uint32_t *)((h)->base+TOFF_DSI_IER1), \
+									(sil_rew_mem((uint32_t *)((h)->base+TOFF_DSI_IER1)) | DSI_ISR1_PSE))
+
+/*
+ *  EOTエラー割込み要求
+ */
+#define dsi_int_eoterr(h)			sil_wrw_mem((uint32_t *)((h)->base+TOFF_DSI_IER1), \
+									(sil_rew_mem((uint32_t *)((h)->base+TOFF_DSI_IER1)) | DSI_ISR1_EOTPE))
+
+/*
+ *  VOFエラー割込み要求
+ */
+#define dsi_int_voferr(h)			sil_wrw_mem((uint32_t *)((h)->base+TOFF_DSI_IER1), \
+									(sil_rew_mem((uint32_t *)((h)->base+TOFF_DSI_IER1)) | DSI_ISR1_LPWRE))
+
+/*
+ *  GENエラー割込み要求
+ */
+#define dsi_int_generr(h)			sil_wrw_mem((uint32_t *)((h)->base+TOFF_DSI_IER1), \
+									(sil_rew_mem((uint32_t *)((h)->base+TOFF_DSI_IER1)) | DSI_INT_GENERR_REQ))
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif	/* _DSI_H_ */
+
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/pdic/stm32f7xx/emac.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/pdic/stm32f7xx/emac.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/pdic/stm32f7xx/emac.c	(revision 457)
@@ -0,0 +1,1481 @@
+/*
+ *  TOPPERS/ASP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Advanced Standard Profile Kernel
+ * 
+ *  Copyright (C) 2008-2011 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ *  Copyright (C) 2015-2019 by TOPPERS PROJECT Educational Working Group.
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+/*
+ * 
+ *  STM32F7XX:EMAC(LWIP用)ドライバ関数群
+ *
+ */
+#include "kernel_impl.h"
+#include <t_syslog.h>
+#include <t_stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <sil.h>
+#include <target_syssvc.h>
+#include <string.h>
+#include "device.h"
+#include "phyreg.h"
+#include "emac.h"
+
+/*
+ *  SIL関数のマクロ定義
+ */
+#define sil_orw_mem(a, b)		sil_wrw_mem((a), sil_rew_mem(a) | (b))
+#define sil_andw_mem(a, b)		sil_wrw_mem((a), sil_rew_mem(a) & ~(b))
+#define sil_modw_mem(a, b, c)	sil_wrw_mem((a), (sil_rew_mem(a) & (~b)) | (c))
+
+#define MIN(a, b) ((a) > (b) ? (b) : (a))
+
+/*
+ *  EMACポートIDから管理ブロックを取り出すためのマクロ
+ */
+#define INDEX_EMAC(emacid)      ((uint_t)((emacid) - 1))
+
+/*
+ *  AUTO NEGOTIATION判定
+ */
+#define is_autonego(h)          (((h)->linkvalue & EMAC_LINK_AUTONEGO) != 0)
+
+/* MDIO の Ready 待ち時間(msec) */
+#define EMAC_MDIO_READY_WAIT_MSEC   50
+
+#define MII_CLKRANGE_150_250M	(0x10)
+
+
+/*
+ *  MIIモード定義
+ */
+#define EMAC_CTRL_PHYSEL_GMII_MII 0x0
+#define EMAC_CTRL_PHYSEL_RGMII    0x1
+
+/*
+ *  DESCRIPTOR定義
+ */
+/*  TX DESCRIPTERステータスビット定義 */
+#define DESC_TXSTS_OWNBYDMA     (1 << 31)		/* OWN bit: descriptor is owned by DMA engine */
+#define DESC_TXSTS_TXINT        (1 << 30)		/* Interrupt on Completion */
+#define DESC_TXSTS_TXLAST       (1 << 29)		/* Last Segment */
+#define DESC_TXSTS_TXFIRST      (1 << 28)		/* First Segment */
+#define DESC_TXSTS_TXCRCDIS     (1 << 27)		/* Disable CRC */
+
+#define DESC_TXSTS_TXPADDIS     (1 << 26)		/* Disable Padding */
+#define DESC_TXSTS_DMATTSE      (1 << 25)		/* Transmit Time Stamp Enable */
+#define DESC_TXSTS_TXCHECKINSCTRL (3 << 22)
+#define DESC_TXSTS_TXRINGEND    (1 << 21)		/* Transmit End of Ring */
+#define DESC_TXSTS_TXCHAIN      (1 << 20)		/* Second Address Chained */
+#define DESC_TXSTS_MSK          (0x1FFFF << 0)
+#define DESC_TXSTS_IHE          (1 << 16)		/* IP Header Error */
+#define DESC_TXSTS_ES           (1 << 15)		/* Error summary: OR of the following bits: UE || ED || EC || LCO || NC || LCA || FF || JT */
+#define DESC_TXSTS_JT           (1 << 14)		/* Jabber Timeout */
+#define DESC_TXSTS_FF           (1 << 13)		/* Frame Flushed: DMA/MTL flushed the frame due to SW flush */
+#define DESC_TXSTS_PCE          (1 << 12)		/* Payload Checksum Error */
+#define DESC_TXSTS_LCA          (1 << 11)		/* Loss of Carrier: carrier lost during transmission */
+#define DESC_TXSTS_NC           (1 << 10)		/* No Carrier: no carrier signal from the transceiver */
+#define DESC_TXSTS_LCO          (1 << 9)		/* Late Collision: transmission aborted due to collision */
+#define DESC_TXSTS_EC           (1 << 8)		/* Excessive Collision: transmission aborted after 16 collisions */
+#define DESC_TXSTS_VF           (1 << 7)		/* VLAN Frame */
+#define DESC_TXSTS_CC           (15 << 3)		/* Collision Count */
+#define DESC_TXSTS_ED           (1 << 2)		/* Excessive Deferral */
+#define DESC_TXSTS_UF           (1 << 1)		/* Underflow Error: late data arrival from the memory */
+#define DESC_TXSTS_DB           (1 << 0)		/* Deferred Bit */
+
+/*  RX DESCRIPTERステータスビット定義 */
+#define DESC_RXSTS_OWNBYDMA     (1 << 31)		/* OWN bit: descriptor is owned by DMA engine  */
+#define DESC_RXSTS_DAFILTERFAIL (1 << 30)		/* DA Filter Fail for the rx frame  */
+#define DESC_RXSTS_FRMLENMSK    (0x3FFF << 16)
+#define DESC_RXSTS_FRMLENSHFT   (16)
+
+#define DESC_RXSTS_ERROR        (1 << 15)		/* Error summary: OR of the following bits */
+#define DESC_RXSTS_DESCERROR    (1 << 14)		/* Descriptor error: no more descriptors for receive frame */
+#define DESC_RXSTS_SAFILTERFAIL (1 << 13)		/* SA Filter Fail for the received frame */
+#define DESC_RXSTS_FRAMELE      (1 << 12)		/* Frame size not matching with length field */
+#define DESC_RXSTS_OFERROR      (1 << 11)		/* Overflow Error: Frame was damaged due to buffer overflow */
+#define DESC_RXSTS_RXVLANTAG    (1 << 10)		/* VLAN Tag: received frame is a VLAN frame */
+#define DESC_RXSTS_RXFIRST      (1 << 9)		/* First descriptor of the frame */
+#define DESC_RXSTS_RXLAST       (1 << 8)		/* Last descriptor of the frame */
+#define DESC_RXSTS_IPV4HCE      (1 << 7)		/* IPC Checksum Error: Rx Ipv4 header checksum error */
+#define DESC_RXSTS_RXCOLLISION  (1 << 6)		/* Late collision occurred during reception */
+#define DESC_RXSTS_RXFRAMEETHER (1 << 5)		/* Frame type - Ethernet, otherwise 802.3 */
+#define DESC_RXSTS_RXWATCHDOG   (1 << 4)		/* Receive Watchdog Timeout: watchdog timer expired during reception */
+#define DESC_RXSTS_RXMIIERROR   (1 << 3)		/* Receive error: error reported by MII interface  */
+#define DESC_RXSTS_RXDRIBBLING  (1 << 2)		/* Dribble bit error: frame contains non int multiple of 8 bits  */
+#define DESC_RXSTS_RXCRC        (1 << 1)		/* CRC error */
+#define DESC_RXSTS_MAMPCE       (1 << 0))		/* Rx MAC Address/Payload Checksum Error: Rx MAC address matched/ Rx Payload Checksum Error */
+
+/*  TX DESCRIPTOR 制御ビット定義 */
+#define DESC_TXCTRL_SIZE1SHFT   (0)
+#define DESC_TXCTRL_SIZE1MASK   (0x1FFF << DESC_TXCTRL_SIZE1SHFT)
+#define DESC_TXCTRL_SIZE2SHFT   (16)
+#define DESC_TXCTRL_SIZE2MASK   (0x1FFF << DESC_TXCTRL_SIZE2SHFT)
+
+/*  RX DESCRIPTOR 制御ビット定義 */
+#define DESC_RXCTRL_RXINTDIS    (1 << 31)
+#define DESC_RXCTRL_RXRINGEND   (1 << 15)
+#define DESC_RXCTRL_RXCHAIN     (1 << 14)
+
+#define DESC_RXCTRL_SIZE1SHFT   (0)
+#define DESC_RXCTRL_SIZE1MASK   (0x1FFF << DESC_RXCTRL_SIZE1SHFT)
+#define DESC_RXCTRL_SIZE2SHFT   (16)
+#define DESC_RXCTRL_SIZE2MASK   (0x1FFF << DESC_RXCTRL_SIZE2SHFT)
+
+
+/*
+ *  EMAC制御設定
+ */
+#define ETH_MACCR_MASK          (ETH_MACCR_WD | ETH_MACCR_JD | ETH_MACCR_IFG | ETH_MACCR_CSD | \
+								 ETH_MACCR_FES | ETH_MACCR_ROD | ETH_MACCR_LM | ETH_MACCR_DM | \
+								 ETH_MACCR_IPCO | ETH_MACCR_RD | ETH_MACCR_APCS | ETH_MACCR_DC | \
+								 ETH_MACCR_BL)
+#define ETH_MACCR_INIT          (ETH_MACCR_IFG_96Bit | ETH_MACCR_FES | ETH_MACCR_DM | \
+								 ETH_MACCR_IPCO | ETH_MACCR_RD | ETH_MACCR_BL_10)
+#define ETH_MACFFR_INIT         (ETH_MACFFR_PCF_BlockAll)
+#define ETH_MACFCR_MASK         (ETH_MACFCR_PT | ETH_MACFCR_ZQPD | ETH_MACFCR_PLT | ETH_MACFCR_UPFD | \
+								 ETH_MACFCR_RFCE | ETH_MACFCR_TFCE)
+#define ETH_MACFCR_INIT         ((0<<16) | ETH_MACFCR_ZQPD | ETH_MACFCR_PLT_Minus4)
+#define ETH_MACVLANTR_INIT      ((0<<16) | 0x0000)
+
+#define ETH_DMAOMR_MASK         (ETH_DMAOMR_DTCEFD | ETH_DMAOMR_RSF | ETH_DMAOMR_TSF | ETH_DMAOMR_DFRF | \
+								 ETH_DMAOMR_ST | ETH_DMAOMR_TTC | ETH_DMAOMR_FEF | ETH_DMAOMR_FUGF | \
+								 ETH_DMAOMR_RTC | ETH_DMAOMR_OSF)
+#define ETH_DMAOMR_INIT         (ETH_DMAOMR_RSF | /* ETH_DMAOMR_TSF | */ ETH_DMAOMR_TTC_64Bytes | \
+								 ETH_DMAOMR_RTC_64Bytes | ETH_DMAOMR_OSF)
+#define ETH_DMABMR_INIT         (ETH_DMABMR_AAB | ETH_DMABMR_FB | ETH_DMABMR_RDP_32Beat | ETH_DMABMR_PBL_32Beat | \
+								 ETH_DMABMR_EDE | (0<<2) | ETH_DMABMR_RTPR_1_1)
+
+/*
+ *  EMAC-DMA割り込み設定
+ */
+#define DMA_INTER_RXSTAT_ERROR  (ETH_DMAIER_ROIE | ETH_DMAIER_RBUIE | ETH_DMAIER_RPSIE | ETH_DMAIER_RWTIE)
+#define DMA_INTR_NORMAL	        (ETH_DMAIER_NISE | ETH_DMAIER_RIE | ETH_DMAIER_TIE)
+#define DMA_INTR_ABNORMAL       (ETH_DMAIER_AISE | ETH_DMAIER_TUIE | ETH_DMAIER_ETIE | \
+								 ETH_DMAIER_FBEIE | ETH_DMAIER_TPSIE | ETH_DMAIER_TJTIE | \
+								 DMA_INTER_RXSTAT_ERROR)
+#define DMA_INTR_DEFAULT_MASK	(DMA_INTR_NORMAL | DMA_INTR_ABNORMAL | ETH_DMAIER_ERIE)
+
+/*
+ *  PHY FEATURES 定義
+ */
+#define ADVERTISE_MASK1         (ADVERTISE_10HALF   | ADVERTISE_10FULL    | \
+							     ADVERTISE_100HALF  | ADVERTISE_100FULL   | \
+								 ADVERTISE_100BASE4 | ADVERTISE_PAUSE_CAP | ADVERTISE_PAUSE_ASYM)
+
+
+/*
+ *  PHY-GPIO定義
+ */
+#define GPIO_ETH_AF              0x0B
+#define RMII_REF_CLK_PORT        TADR_GPIOA_BASE
+#define RMII_REF_CLK_BIN         1
+#define RMII_MDIO_PORT           TADR_GPIOA_BASE
+#define RMII_MDIO_PIN            2
+#define RMII_MDC_PORT            TADR_GPIOC_BASE
+#define RMII_MDC_PIN             1
+#define RMII_MII_CRS_DV_PORT     TADR_GPIOA_BASE
+#define RMII_MII_CRS_DV_PIN      7
+#define RMII_MII_RXD0_PORT       TADR_GPIOC_BASE
+#define RMII_MII_RXD0_PIN        4
+#define RMII_MII_RXD1_PORT       TADR_GPIOC_BASE
+#define RMII_MII_RXD1_PIN        5
+#define RMII_MII_RXER_PORT       TADR_GPIOG_BASE
+#define RMII_MII_RXER_PIN        2
+#define RMII_MII_TX_EN_PORT      TADR_GPIOG_BASE
+#define RMII_MII_TX_EN_PIN       11
+#define RMII_MII_TXD0_PORT       TADR_GPIOG_BASE
+#define RMII_MII_TXD0_PIN        13
+#ifndef RMII_MII_TXD1_PORT
+#define RMII_MII_TXD1_PORT       TADR_GPIOB_BASE
+#define RMII_MII_TXD1_PIN        13
+#endif
+
+/*
+ *  EMACハードウェア設定構造体
+ */
+typedef struct _I2C_PortControlBlock{
+	uint32_t              base;
+	uint8_t               intno;
+	uint8_t               physel_shift;
+	uint8_t               phy_sel;
+	uint8_t               phy_addr;
+} EMAC_PortControlBlock;
+
+/*
+ *  EMACポート設定テーブル
+ */
+static const EMAC_PortControlBlock emac_pcb[NUM_MACPORT] = {
+  {	TADR_ETH_BASE, IRQ_VECTOR_ETH, 23, EMAC_CTRL_PHYSEL_RGMII, 0}
+};
+
+/*
+ *  EMAC ハンドラ
+ */
+static EMAC_Handle_t EMacHandle[NUM_MACPORT];
+
+static uint32_t
+emac_ether_clockdiv(void)
+{
+#if SysFreHCLK >= 20000000 && SysFreHCLK < 35000000
+	/* CSR Clock Range between 20-35 MHz */
+    retrun (uint32_t)ETH_MACMIIAR_CR_Div16;
+#elif SysFreHCLK >= 35000000 && SysFreHCLK < 60000000
+    /* CSR Clock Range between 35-60 MHz */
+	return (uint32_t)ETH_MACMIIAR_CR_Div26;
+#elif SysFreHCLK >= 60000000 && SysFreHCLK < 100000000
+	/* CSR Clock Range between 60-100 MHz */
+	return (uint32_t)ETH_MACMIIAR_CR_Div42;
+#elif SysFreHCLK >= 100000000 && SysFreHCLK < 150000000
+	/* CSR Clock Range between 100-150 MHz */
+	return (uint32_t)ETH_MACMIIAR_CR_Div62;
+#else
+	/* CSR Clock Range between 150-216 MHz */
+	return (uint32_t)ETH_MACMIIAR_CR_Div102;
+#endif
+}
+
+/*
+ *  MDIOのREADY待ち
+ *  parameter1 base  EMACレジスタのベースアドレス
+ *  return     E_OKで正常終了
+ */
+static ER
+emac_mdio_wait_ready(uint32_t base)
+{
+	int     i;
+
+	for (i = 0; i < (EMAC_MDIO_READY_WAIT_MSEC*10); i++) {
+		if((sil_rew_mem((uint32_t *)(base+TOFF_ETH_MACMIIAR)) & ETH_MACMIIAR_MB) == 0)
+			return E_OK;
+		sil_dly_nse(100*1000);
+	}
+	syslog_0(LOG_ERROR, "EMAC:Error mdio timeout!");
+	return E_TMOUT;
+}
+
+/*
+ *  PHYレジスタへのデータ書き込み
+ *  parameter1 hmac  EMACハンドラへのポインタ
+ *  parameter2 reg   レジスタ番号
+ *  parameter3 val   書き込み値
+ *  return     E_OKで正常終了
+ */
+static ER
+emac_mdio_write(EMAC_Handle_t *hmac, int reg, int val)
+{
+	uint32_t miiaddr;
+	ER       ercd = E_TMOUT;
+
+	if(hmac->Init.semid != 0)
+		wai_sem(hmac->Init.semid);
+
+	miiaddr  = sil_rew_mem((uint32_t *)(hmac->base+TOFF_ETH_MACMIIAR)) & ETH_MACMIIAR_CR;
+	miiaddr |= ((hmac->phy_addr << 11) & ETH_MACMIIAR_PA) | \
+		  ((reg << 6) & ETH_MACMIIAR_MR) | ETH_MACMIIAR_MW;
+
+	/*
+	 *  READY待ち
+	 */
+	if(emac_mdio_wait_ready(hmac->base) == E_OK){
+		/*
+		 *  データ設定後、PHYアドレスセット
+		 */
+		sil_wrw_mem((uint32_t *)(hmac->base+TOFF_ETH_MACMIIDR), val);
+		sil_wrw_mem((uint32_t *)(hmac->base+TOFF_ETH_MACMIIAR), (miiaddr | ETH_MACMIIAR_MB));
+
+		/*
+		 *  READY待ち
+		 */
+		if (emac_mdio_wait_ready(hmac->base) == E_OK)
+			ercd = E_OK;
+	}
+
+	if(hmac->Init.semid != 0)
+		sig_sem(hmac->Init.semid);
+	return ercd;
+}
+
+/*
+ *  PHYレジスタからのデータ読み込み
+ *  parameter1 hmac  EMACハンドラへのポインタ
+ *  parameter2 reg   レジスタ番号
+ *  return     0以上でレジスタ値
+ */
+static int
+emac_mdio_read(EMAC_Handle_t *hmac, int reg)
+{
+	uint32_t miiaddr;
+	int     val = -1;
+
+	if(hmac->Init.semid != 0)
+		wai_sem(hmac->Init.semid);
+
+	miiaddr  = sil_rew_mem((uint32_t *)(hmac->base+TOFF_ETH_MACMIIAR)) & ETH_MACMIIAR_CR;
+	miiaddr |= ((hmac->phy_addr << 11) & ETH_MACMIIAR_PA) | ((reg << 6) & ETH_MACMIIAR_MR);
+
+	/*
+	 *  READY待ち
+	 */
+	if(emac_mdio_wait_ready(hmac->base) == E_OK){
+		/*
+		 *  PHYアドレスセット
+		 */
+		sil_wrw_mem((uint32_t *)(hmac->base+TOFF_ETH_MACMIIAR), (miiaddr | ETH_MACMIIAR_MB));
+
+		/*
+		 *  READY待ちの後、データ取得
+		 */
+		if(emac_mdio_wait_ready(hmac->base) == E_OK)
+			val = sil_rew_mem((uint32_t *)(hmac->base+TOFF_ETH_MACMIIDR)) & 0x0000ffffUL;
+	}
+
+	if(hmac->Init.semid != 0)
+		sig_sem(hmac->Init.semid);
+	return val;
+}
+
+/*
+ *  PHYの初期設定
+ *  parameter1 hmac   EMACハンドラへのポインタ
+ *  parameter2 phyadr PHYアドレス(32以上ならば自動センス)
+ *  return     E_OKで正常終了
+ */
+static ER
+emac_phy_init(EMAC_Handle_t *hmac, uint8_t phy_addr)
+{
+	int  val;
+
+	if(phy_addr < 0x20){
+		hmac->phy_addr = phy_addr;
+		val = emac_mdio_read(hmac, MII_PHYSID1);
+		if((val > 0) && (val != 0xffff))
+			return E_OK;
+		else{
+			syslog_1(LOG_ERROR, "EMAC:emac_phy_init Error unkown phy address(%d)", phy_addr);
+			return E_ID;
+		}
+	}
+
+	/*
+	 *  自動センスモード
+	 */
+	for(phy_addr = 0; phy_addr < 0x20; phy_addr++){
+		hmac->phy_addr = phy_addr;
+		val = emac_mdio_read(hmac, MII_PHYSID1);
+		if((val > 0) && (val != 0xffff))
+			return E_OK;
+	}
+	syslog_0(LOG_ERROR, "EMAC:emac_phy_init Error unkown phy address");
+	return E_ID;
+}
+
+/*
+ *  PHYをリセットする
+ *  parameter1 hmac  EMACハンドラへのポインタ
+ *  return     E_OKで正常終了
+ */
+static ER
+emac_phy_reset(EMAC_Handle_t *hmac)
+{
+	int i, val;
+
+	val = emac_mdio_read(hmac, MII_BMCR);
+	val &= ~(BMCR_ISOLATE | BMCR_ANENABLE);
+	val |= BMCR_RESET;
+	emac_mdio_write(hmac, MII_BMCR, val);
+
+	for(i = 0 ; i < 1000; i++){
+		val = emac_mdio_read(hmac, MII_BMCR);
+		if (val < 0)
+			break;
+		if ((val & BMCR_RESET) == 0) {
+			if (val & BMCR_ISOLATE) {
+				val &= (~BMCR_ISOLATE);
+				emac_mdio_write(hmac, MII_BMCR, val);
+			}
+			return E_OK;
+		}
+		dly_tsk(1);
+	}
+	syslog_0(LOG_ERROR, "EMAC:emac_phy_reset Error spin reset timeout");
+	return E_TMOUT;
+}
+
+/*
+ *  PHYの状態を取り出す
+ *  parameter1 hmac  EMACハンドラへのポインタ
+ *  return     PHYの状態値
+ */
+static uint32_t
+emac_phy_features(EMAC_Handle_t *hmac)
+{
+	uint32_t   bmsr;
+	uint32_t   mode = ADVERTISE_PAUSE_CAP | ADVERTISE_PAUSE_ASYM;
+
+	bmsr = emac_mdio_read(hmac, MII_BMSR);
+	if((bmsr & BMSR_10HALF) != 0)
+		mode |= ADVERTISE_10HALF;
+	if((bmsr & BMSR_10FULL) != 0)
+		mode |= ADVERTISE_10FULL;
+	if((bmsr & BMSR_100HALF) != 0)
+		mode |= ADVERTISE_100HALF;
+	if((bmsr & BMSR_100FULL) != 0)
+		mode |= ADVERTISE_100FULL;
+	return mode;
+}
+
+/*
+ *  PHY処理開始要求
+ *  parameter1 hmac  EMACハンドラへのポインタ
+ *  parameter2 link  PHY設定値
+ *  return     E_OKで正常終了
+ */
+static ER
+emac_phy_start(EMAC_Handle_t *hmac, uint32_t link)
+{
+	ER       ercd;
+	uint32_t id;
+	uint32_t mode, val;
+	int      speed = 0, duplex = 0;
+
+	/*
+	 *  PHYをリセットする
+	 */
+	if((ercd = emac_phy_reset(hmac)) != E_OK)
+		return ercd;
+
+	/*
+	 *  PHY情報を取得する
+	 */
+	hmac->phy_features = emac_phy_features(hmac);
+	syslog_1(LOG_INFO, "EMAC:emac_phy_start phy featurs[%08x]", hmac->phy_features);
+
+	/*
+	 *  PHYのチップIDの確認
+	 */
+	id  = (emac_mdio_read(hmac, MII_PHYSID1) << 16);
+	id |= (emac_mdio_read(hmac, MII_PHYSID2) & 0xffff);
+
+	syslog_2(LOG_INFO, "EMAC:emac_phy_start PHY-ID[OUI&Model:0x%x, Rev:0x%x]", id & ~0xf, id & 0xf);
+
+	/*
+	 *  オプション設定があれば、実行
+	 */
+	if(hmac->phy_opt_init)
+		hmac->phy_opt_init(hmac);
+
+	/*
+	 *  LINKパラメータを設定
+	 */
+	link &= ~EMAC_LINK_CONNECT;
+	hmac->linkvalue = link;
+
+	switch(link){
+	case EMAC_LINK_10BASE_FULL:
+		duplex = BMCR_FULLDPLX;
+	case EMAC_LINK_10BASE_HALF:
+		speed = BMCR_SPEED10;
+		break;
+	case EMAC_LINK_100BASE_FULL:
+		duplex = BMCR_FULLDPLX;
+	case EMAC_LINK_100BASE_HALF:
+		speed = BMCR_SPEED100;
+		break;
+	case EMAC_LINK_AUTONEGO:
+	default:
+		/* Setup Auto-negotiation */
+		hmac->linkvalue |= EMAC_LINK_AUTONEGO;
+		mode = hmac->phy_features;
+		val = emac_mdio_read(hmac, MII_ADVERTISE);
+		val &= ~ADVERTISE_MASK1;
+		val |= mode & ADVERTISE_MASK1;
+		emac_mdio_write(hmac, MII_ADVERTISE, val);
+		break;
+	}
+
+	val = emac_mdio_read(hmac, MII_BMCR);
+	val &= ~(BMCR_FULLDPLX | BMCR_SPEED100 | BMCR_ANENABLE);
+	val |= is_autonego(hmac) ? (BMCR_ANENABLE | BMCR_ANRESTART) : (speed | duplex);
+	emac_mdio_write(hmac, MII_BMCR, val);
+	return E_OK;
+}
+
+/*
+ *  AUTO-NEGOTIATION設定時のLINK状態の取得
+ *  parameter1 hmac  EMACハンドラへのポインタ
+ *  return     LINK状態
+ */
+static uint32_t
+emac_phy_link_autonego(EMAC_Handle_t *hmac)
+{
+	uint32_t  link_detect;
+	uint32_t  lpa;
+
+	lpa = emac_mdio_read(hmac, MII_LPA) & emac_mdio_read(hmac, MII_ADVERTISE);
+	if(lpa & LPA_100FULL)
+		link_detect = EMAC_LINK_100BASE_FULL;
+	else if(lpa & LPA_100HALF)
+		link_detect = EMAC_LINK_100BASE_HALF;
+	else if(lpa & LPA_10FULL)
+		link_detect = EMAC_LINK_10BASE_FULL;
+	else
+		link_detect = EMAC_LINK_10BASE_HALF;
+	return link_detect;
+}
+
+/*
+ *  マニュアル設定時のLINK状態の取得
+ *  parameter1 hmac  EMACハンドラへのポインタ
+ *  return     LINK状態
+ */
+static uint32_t
+emac_phy_link_manual(EMAC_Handle_t *hmac)
+{
+	uint32_t    link_detect;
+	int     bmcr;
+
+	bmcr = emac_mdio_read(hmac, MII_BMCR);
+
+	if(bmcr & BMCR_SPEED100)
+		link_detect = EMAC_SPEED_100BASE;
+	else
+		link_detect = EMAC_SPEED_10BASE;
+	link_detect |= (bmcr & BMCR_FULLDPLX) ? EMAC_DUPLEX_FULL : EMAC_DUPLEX_HALF;
+	return link_detect;
+}
+
+/*
+ *  DESCRIPTER領域の初期化
+ *  parameter1 hmac  EMACハンドラへのポインタ
+ */
+static void
+emac_bd_set(EMAC_Handle_t *hmac)
+{
+	uint32_t   *desc, *next;
+	uint8_t    *pdata = hmac->Init.databuffer;
+	int        i;
+
+	/*
+	 *  DESCRIPTOR/BUFFER領域ののキャッシュをクリア
+	 */
+	desc  = (uint32_t *)hmac->Init.quebuffer;
+	next  = (uint32_t *)(desc + DESC_TXRX_SIZE);
+
+	hmac->rx_top_desc = desc;
+	for(i = 0 ; i < hmac->Init.rxquecount ; i++) {
+		desc[DESC_TXRX_BUFFER] = (uint32_t)pdata;
+		desc[DESC_TXRX_NEXT]   = (uint32_t)next;
+		desc[DESC_TXRX_CONTROL] = 
+			(hmac->Init.paketbufsize & DESC_RXCTRL_SIZE1MASK) | \
+				      DESC_RXCTRL_RXCHAIN;
+		desc[DESC_TXRX_STATUS] = DESC_RXSTS_OWNBYDMA;
+
+		pdata += hmac->Init.paketbufsize;
+		desc  += DESC_TXRX_SIZE;
+		next  += DESC_TXRX_SIZE;
+	}
+	*(desc - DESC_TXRX_SIZE + DESC_TXRX_NEXT)
+			= (uint32_t)(hmac->rx_top_desc);
+
+	hmac->tx_top_desc = desc;
+	for(i = 0 ; i < hmac->Init.txquecount ; i++){
+		desc[DESC_TXRX_BUFFER] = (uint32_t)pdata;
+		desc[DESC_TXRX_NEXT]   = (uint32_t)next;
+		desc[DESC_TXRX_STATUS] &= ~(DESC_TXSTS_TXINT | DESC_TXSTS_TXLAST |
+				DESC_TXSTS_TXFIRST | DESC_TXSTS_TXCRCDIS | \
+				DESC_TXSTS_TXCHECKINSCTRL | \
+				DESC_TXSTS_TXRINGEND | DESC_TXSTS_TXPADDIS);
+		desc[DESC_TXRX_STATUS] |= DESC_TXSTS_TXCHAIN | DESC_TXSTS_TXCHECKINSCTRL;
+		desc[DESC_TXRX_CONTROL] = 0;
+		desc[DESC_TXRX_STATUS] &= ~(DESC_TXSTS_MSK | DESC_TXSTS_OWNBYDMA);
+
+		pdata += hmac->Init.paketbufsize;
+		desc  += DESC_TXRX_SIZE;
+		next  += DESC_TXRX_SIZE;
+	}
+	*(desc - DESC_TXRX_SIZE + DESC_TXRX_NEXT)
+			= (uint32_t)(hmac->tx_top_desc);
+}
+
+
+/*
+ *  EMACデバイスの初期化
+ *  parameter1 portid EMACのポートID
+ *  parameter2 ini    初期化構造体へのポインタ
+ *  return            ハンドラへのポインタ
+ */
+EMAC_Handle_t *
+emac_init(ID portid, EMAC_Init_t *ini)
+{
+	GPIO_Init_t GPIO_Init_Data;
+	const EMAC_PortControlBlock *pcb;
+	EMAC_Handle_t *hmac;
+	uint32_t base, no, tmp;
+	uint32_t timeout = 3000;
+
+	if(portid == 0 || portid > NUM_MACPORT)
+		return NULL;
+
+	no = INDEX_EMAC(portid);
+	pcb = &emac_pcb[no];
+	hmac = &EMacHandle[no];
+
+	hmac->base     = base = pcb->base;
+	hmac->intno    = pcb->intno;
+	memcpy(&hmac->Init, ini, sizeof(EMAC_Init_t));
+
+	/*
+	 *  PHY GPIO クロック設定
+	 */
+	sil_orw_mem((uint32_t *)(TADR_RCC_BASE+TOFF_RCC_AHB1ENR), RCC_AHB1ENR_GPIOAEN);
+	tmp = sil_rew_mem((uint32_t *)(TADR_RCC_BASE+TOFF_RCC_AHB1ENR));
+	sil_orw_mem((uint32_t *)(TADR_RCC_BASE+TOFF_RCC_AHB1ENR), RCC_AHB1ENR_GPIOCEN);
+	tmp = sil_rew_mem((uint32_t *)(TADR_RCC_BASE+TOFF_RCC_AHB1ENR));
+	sil_orw_mem((uint32_t *)(TADR_RCC_BASE+TOFF_RCC_AHB1ENR), RCC_AHB1ENR_GPIOGEN);
+	tmp = sil_rew_mem((uint32_t *)(TADR_RCC_BASE+TOFF_RCC_AHB1ENR));
+#ifdef RMII_MII_TXD1_CLOCK
+	sil_orw_mem((uint32_t *)(TADR_RCC_BASE+TOFF_RCC_AHB1ENR), RMII_MII_TXD1_CLOCK);
+	tmp = sil_rew_mem((uint32_t *)(TADR_RCC_BASE+TOFF_RCC_AHB1ENR));
+#endif
+
+	/*
+	 *  PHY GPIOピン設定
+	 */
+	GPIO_Init_Data.mode      = GPIO_MODE_AF;
+	GPIO_Init_Data.pull      = GPIO_OTYPE_PP;
+	GPIO_Init_Data.otype     = GPIO_NOPULL;
+	GPIO_Init_Data.speed     = GPIO_SPEED_HIGH;
+	GPIO_Init_Data.alternate = GPIO_ETH_AF;
+	gpio_setup(RMII_REF_CLK_PORT, &GPIO_Init_Data, RMII_REF_CLK_BIN);
+	gpio_setup(RMII_MDIO_PORT, &GPIO_Init_Data, RMII_MDIO_PIN);
+	gpio_setup(RMII_MDC_PORT, &GPIO_Init_Data, RMII_MDC_PIN);
+	gpio_setup(RMII_MII_CRS_DV_PORT, &GPIO_Init_Data, RMII_MII_CRS_DV_PIN);
+	gpio_setup(RMII_MII_RXD0_PORT, &GPIO_Init_Data, RMII_MII_RXD0_PIN);
+	gpio_setup(RMII_MII_RXD1_PORT, &GPIO_Init_Data, RMII_MII_RXD1_PIN);
+	gpio_setup(RMII_MII_RXER_PORT, &GPIO_Init_Data, RMII_MII_RXER_PIN);
+	gpio_setup(RMII_MII_TX_EN_PORT, &GPIO_Init_Data, RMII_MII_TX_EN_PIN);
+	gpio_setup(RMII_MII_TXD0_PORT, &GPIO_Init_Data, RMII_MII_TXD0_PIN);
+	gpio_setup(RMII_MII_TXD1_PORT, &GPIO_Init_Data, RMII_MII_TXD1_PIN);
+
+	/*
+	 *  EMACクロック設定
+	 */
+	sil_orw_mem((uint32_t *)(TADR_RCC_BASE+TOFF_RCC_AHB1ENR), RCC_AHB1ENR_ETHMACEN);
+	tmp = sil_rew_mem((uint32_t *)(TADR_RCC_BASE+TOFF_RCC_AHB1ENR));
+	sil_orw_mem((uint32_t *)(TADR_RCC_BASE+TOFF_RCC_AHB1ENR), RCC_AHB1ENR_ETHMACTXEN);
+	tmp = sil_rew_mem((uint32_t *)(TADR_RCC_BASE+TOFF_RCC_AHB1ENR));
+	sil_orw_mem((uint32_t *)(TADR_RCC_BASE+TOFF_RCC_AHB1ENR), RCC_AHB1ENR_ETHMACRXEN);
+	tmp = sil_rew_mem((uint32_t *)(TADR_RCC_BASE+TOFF_RCC_AHB1ENR));
+
+	dis_int(hmac->intno);
+	sil_orw_mem((uint32_t *)(TADR_RCC_BASE+TOFF_RCC_APB2ENR), RCC_APB2ENR_SYSCFGEN);
+	sil_andw_mem((uint32_t *)(TADR_SYSCFG_BASE+TOFF_SYSCFG_PMC), 1<<(pcb->physel_shift));
+	sil_orw_mem((uint32_t *)(TADR_SYSCFG_BASE+TOFF_SYSCFG_PMC), (pcb->phy_sel)<<(pcb->physel_shift));
+
+	/*
+	 *  MACをリセット
+	 */
+	sil_orw_mem((uint32_t *)(base+TOFF_ETH_DMABMR), ETH_DMABMR_SR);
+	while(timeout > 0){
+		if((sil_rew_mem((uint32_t *)(base+TOFF_ETH_DMABMR)) & ETH_DMABMR_SR) == 0)
+			break;
+		dly_tsk(1);
+		timeout--;
+	}
+
+	/* Get the ETHERNET MACMIIAR value */
+	tmp= sil_rew_mem((uint32_t *)(base+TOFF_ETH_MACMIIAR));
+	/* Clear CSR Clock Range CR[2:0] bits */
+	tmp &= ~ETH_MACMIIAR_CR;
+	tmp |= emac_ether_clockdiv();
+	sil_wrw_mem((uint32_t *)(base+TOFF_ETH_MACMIIAR), tmp);
+
+	/*
+	 *  DESCRIPTORの初期化
+	 */
+	emac_bd_set(hmac);
+
+	if(emac_phy_init(hmac, pcb->phy_addr) != E_OK)
+		return NULL;
+	hmac->macid = portid;
+	return hmac;
+}
+
+/*
+ *  EMAC終了処理
+ *  parameter1 hmac  EMACハンドラへのポインタ
+ *  return     E_OKで正常終了
+ */
+ER
+emac_deinit(EMAC_Handle_t *hmac)
+{
+	if(hmac == NULL || hmac->macid == 0 || hmac->macid > NUM_MACPORT)
+		return E_OBJ;
+	dis_int(hmac->intno);
+
+	/*
+	 *  EMACクロック停止
+	 */
+	sil_andw_mem((uint32_t *)(TADR_RCC_BASE+TOFF_RCC_AHB1ENR), RCC_AHB1ENR_ETHMACEN);
+	sil_andw_mem((uint32_t *)(TADR_RCC_BASE+TOFF_RCC_AHB1ENR), RCC_AHB1ENR_ETHMACTXEN);
+	sil_andw_mem((uint32_t *)(TADR_RCC_BASE+TOFF_RCC_AHB1ENR), RCC_AHB1ENR_ETHMACRXEN);
+
+	hmac->macid = 0;
+	return E_OK;
+}
+
+/*
+ *  EMAC送信要求
+ *  parameter1 hmac  EMACハンドラへのポインタ
+ *  parameter2 num   送信パケット数
+ */
+static void
+emac_send_req(EMAC_Handle_t *hmac, int num)
+{
+	volatile uint32_t *desc, *top;
+	uint32_t base = hmac->base;
+
+	if(num > 0){
+		top = desc = hmac->tx_cur_desc;
+		desc = (uint32_t *)(desc[DESC_TXRX_NEXT]);
+		dis_int(hmac->intno);
+		if(hmac->tx_wait == 0)
+			sil_andw_mem((uint32_t *)(hmac->base+TOFF_ETH_DMAOMR), ETH_DMAOMR_ST);
+		while (--num) {
+			/*
+			 *  連続DESCRIPTORの送信DMA KICK
+			 */
+			desc[DESC_TXRX_STATUS] |= DESC_TXSTS_OWNBYDMA;
+			hmac->tx_wait++;
+			desc = (uint32_t *)(desc[DESC_TXRX_NEXT]);
+		}
+		/*
+		 *  先頭のDESCRIPTORの送信DMA KICK
+		 */
+		top[DESC_TXRX_STATUS] |= DESC_TXSTS_OWNBYDMA;
+		hmac->tx_wait++;
+		hmac->tx_cur_desc = desc;
+		ena_int(hmac->intno);
+	}
+	else
+		sil_andw_mem((uint32_t *)(hmac->base+TOFF_ETH_DMAOMR), ETH_DMAOMR_ST);
+	if((sil_rew_mem((uint32_t *)(base+TOFF_ETH_DMASR)) & ETH_DMASR_TBUS) != 0){
+		sil_wrw_mem((uint32_t *)(base+TOFF_ETH_DMASR), ETH_DMASR_TBUS);
+		sil_wrw_mem((uint32_t *)(base+TOFF_ETH_DMATPDR), 0);
+	}
+	sil_orw_mem((uint32_t *)(base+TOFF_ETH_DMAOMR), ETH_DMAOMR_ST);
+}
+
+/*
+ *  EMAC送信処理
+ *  parameter1 hmac  EMACハンドラへのポインタ
+ *  parameter2 pktp  送信パケット構造体(LWIP型)
+ *  return     E_OKで正常終了
+ */
+ER
+emac_send(EMAC_Handle_t *hmac, struct emac_pkt *pktp)
+{
+	int      num, len, tlen, retry, i;
+	int      start = 1;
+	int      actlen = 0;
+	ER       ercd = E_OK;
+	volatile uint32_t *desc;
+	uint32_t info_word = 0;
+	volatile uint8_t  *pdata;
+	volatile uint8_t  *s, *d;
+
+	if(hmac == NULL || pktp == NULL)
+		return E_PAR;
+
+	desc = hmac->tx_cur_desc;
+	s = pktp->payload;
+	len = pktp->len;
+
+	for(num = 0 ; num < hmac->Init.txquecount && pktp != NULL ; num++){
+		if(pktp->len == 0)
+			break;
+
+		/*
+		 *  送信DESCRIPTORの開放待ち
+		 */
+		if((desc[DESC_TXRX_STATUS] & DESC_TXSTS_OWNBYDMA) != 0){
+			for (retry = 0; retry < 3; retry++) {
+				/* 送信ディスクリプタがフルのとき、開放されるのを待つ */
+				dly_tsk(10);
+				/* 再度チェックを行う */
+				if((desc[DESC_TXRX_STATUS] & DESC_TXSTS_OWNBYDMA) == 0)
+					break;
+				/* 念のため、送信の開始を再要求する */
+				emac_send_req(hmac, 0);
+			}
+			if((desc[DESC_TXRX_STATUS] & DESC_TXSTS_OWNBYDMA) != 0){
+				syslog_1(LOG_ERROR, "EMAC:emac_send retry(%d) no descriptor", retry+1);
+				ercd = E_TMOUT;
+				break;
+			}
+		}
+
+		/*
+		 *  送信データをバッファに書き込む
+		 */
+		pdata = d = (volatile uint8_t *)(desc[DESC_TXRX_BUFFER]);
+		while(actlen < hmac->Init.paketbufsize){
+			tlen = MIN(len, (hmac->Init.paketbufsize - actlen));
+			for(i = 0 ; i < tlen ; i++)
+				*d++ = *s++;
+			actlen += tlen;
+			len    -= tlen;
+			if(len == 0){
+				if((pktp = pktp->next) == NULL)
+					break;
+				if(pktp->len == 0)
+					break;
+				s = pktp->payload;
+				len = pktp->len;
+			}
+		}
+		syslog_4(LOG_DEBUG, "EMAC:emac_send(%d) desc[%08x] buf[%08x] actlen[%04x]", num, desc, pdata, actlen);
+
+		/*
+		 *  送信サイズと送信モードをセット
+		 */
+		desc[DESC_TXRX_CONTROL] = (actlen << DESC_TXCTRL_SIZE1SHFT) & DESC_TXCTRL_SIZE1MASK;
+
+		info_word  = desc[DESC_TXRX_STATUS];
+		info_word &= ~(DESC_TXSTS_MSK | DESC_TXSTS_TXFIRST | DESC_TXSTS_TXLAST);
+		info_word |= DESC_TXSTS_TXINT;
+
+		if (start) {
+			start = 0;
+			info_word |= DESC_TXSTS_TXFIRST;
+		}
+		/*
+		 *  次のデータ確認と終了マーク設定
+		 */
+		if(pktp == NULL || pktp->len == 0)
+			info_word |= DESC_TXSTS_TXLAST;
+		desc[DESC_TXRX_STATUS] = info_word;
+
+		/*
+		 *  次のDESCRIPTORへ更新する
+		 */
+		desc = (uint32_t *)(desc[DESC_TXRX_NEXT]);
+	}
+
+	/* パケットの終端までセットしていないときはエラー応答 */
+	if((info_word & DESC_TXSTS_TXLAST) == 0){
+		syslog_0(LOG_ERROR, "EMAC:emac_send last error !");
+		return -1;
+	}
+
+	/* 送信を要求する */
+	if(num > 0)
+		emac_send_req(hmac, num);
+	return ercd;
+}
+
+/*
+ *  次の受信DESCRIPTORを取得する
+ *  parameter1 hmac  EMACハンドラへのポインタ
+ *  return     次のDESCRIPTORへのポインタ
+ */
+volatile static uint32_t *
+emac_recv_desc_next(EMAC_Handle_t *hmac)
+{
+	volatile uint32_t *desc;
+
+	desc = hmac->rx_cur_desc;
+	desc[DESC_TXRX_CONTROL] = 
+		(hmac->Init.paketbufsize & DESC_RXCTRL_SIZE1MASK) | \
+			      DESC_RXCTRL_RXCHAIN;
+	desc[DESC_TXRX_STATUS]  = DESC_RXSTS_OWNBYDMA;
+	desc = (uint32_t *)(desc[DESC_TXRX_NEXT]);
+	hmac->rx_cur_desc = desc;
+	return desc;
+}
+
+/*
+ *  受信の先頭パケットのDESCRIPTORを探す
+ *  parameter1 hmac  EMACハンドラへのポインタ
+ *  return     NULLでなければ、受信の先頭DESCRIPTORへのポインタ
+ */
+volatile static uint32_t *
+emac_recv_sop_find(EMAC_Handle_t *hmac)
+{
+	int      num;
+	volatile uint32_t *desc = hmac->rx_cur_desc;
+	uint32_t info_word, length;
+
+	for(num = 0 ; num < hmac->Init.rxquecount ; num++) {
+		info_word = desc[DESC_TXRX_STATUS];
+
+		/*
+		 *  受信データなしのときは、終了する
+		 */
+		if ((info_word & DESC_RXSTS_OWNBYDMA) != 0)
+			break;
+
+		/*
+		 * 受信データあり場合、Start of Packet のチェックを行う
+		 */
+		length = (info_word & DESC_RXSTS_FRMLENMSK) >> DESC_RXSTS_FRMLENSHFT;
+		if (info_word & DESC_RXSTS_RXFIRST) {
+			if(length >= ETHER_HDR_SIZE)
+				return desc;
+		}
+		else
+			hmac->ifShortPkts++;
+
+		/*
+		 * 次のDESCRIPTORを取得する
+		 */
+		desc = emac_recv_desc_next(hmac);
+	}
+	return NULL;
+}
+
+/*
+ *  受信データ長の取り出し
+ *  parameter1 hmac  EMACハンドラへのポインタ
+ *  return     0でなければ、受信パケット長
+ */
+int
+emac_recv_length(EMAC_Handle_t *hmac)
+{
+	int      num, length = 0;
+	volatile uint32_t *desc;
+	uint32_t info_word;
+
+	/*
+	 *  受信パケットの確認し、ない場合は終了
+	 */
+	if((desc = emac_recv_sop_find(hmac)) == NULL)
+		return 0;
+
+	for(num = 0 ; num < hmac->Init.rxquecount ; num++){
+		info_word = desc[DESC_TXRX_STATUS];
+
+		/*  何も受信していないときは、終了する */
+		if ((info_word & DESC_RXSTS_OWNBYDMA) != 0)
+			break;
+
+		/*  受信データ長を取得する */
+		length += (desc[DESC_TXRX_STATUS] & DESC_RXSTS_FRMLENMSK) >> DESC_RXSTS_FRMLENSHFT;
+
+		/*
+		 *  End of Packetならば、終了
+		 */
+		if(info_word & DESC_RXSTS_RXLAST)
+			break;
+
+		/*
+		 *  次のDESCRIPTORを取得する
+		 */
+		desc = (uint32_t *)(desc[DESC_TXRX_NEXT]);
+	}
+	return length;
+}
+
+/*
+ *  受信パケットの取得
+ *  parameter1 hmac  EMACハンドラへのポインタ
+ *  parameter2 pktp  受信データ格納パケット構造体(LWIP型)
+ *  return     E_OKならば、受信パケット長
+ */
+ER
+emac_recv(EMAC_Handle_t *hmac, struct emac_pkt *pktp)
+{
+	int      num, actlen, i;
+	volatile uint32_t *desc;
+	volatile uint8_t  *b, *pdata;
+	uint32_t info_word, len, tlen;
+
+	if(pktp != NULL){
+		b = pktp->payload;
+		len = pktp->len;
+	}
+	else{
+		b = NULL;
+		len = 0;
+	}
+
+	sil_wrw_mem((uint32_t *)(hmac->base+TOFF_ETH_DMASR), ETH_DMASR_RS | DMA_INTER_RXSTAT_ERROR);
+
+	/*
+	 *  受信パケットの確認し、ない場合はエラー終了
+	 */
+	if((desc = emac_recv_sop_find(hmac)) == NULL)
+		return E_NOMEM;
+
+	for(num = 0 ; num < hmac->Init.rxquecount ; num++){
+		info_word = desc[DESC_TXRX_STATUS];
+
+		/*
+		 *  受信データがない場合、終了する
+		 */
+		if((info_word & DESC_RXSTS_OWNBYDMA) != 0)
+			break;
+
+		/*
+		 *  パケット格納領域がある場合は受信パケットを取得する
+		 */
+		if(b != NULL){
+			/* 受信データを取得する */
+			pdata = (uint8_t *)(desc[DESC_TXRX_BUFFER]);
+			actlen = (desc[DESC_TXRX_STATUS] & DESC_RXSTS_FRMLENMSK) >> DESC_RXSTS_FRMLENSHFT;
+			syslog_5(LOG_DEBUG, "EMAC:emac_recv num(%d) desc[%08x] b[%08x] pdata[%08x] actlen[%08x] !", num, desc, b, pdata, actlen);
+			syslog_4(LOG_DEBUG, "  12[%02x] 13[%02x] 14[%02x] 15[%02x]", pdata[12], pdata[13], pdata[14], pdata[15]);
+			while(actlen > 0){
+				tlen = MIN(len, actlen);
+				for(i = 0 ; i < tlen ; i++)
+					*b++ = *pdata++;
+				actlen -= tlen;
+				len    -= tlen;
+				if(len == 0 /*&& actlen > 0*/){
+					if((pktp = pktp->next) == NULL){
+						b = NULL;
+						break;
+					}
+					b = pktp->payload;
+					if((len = pktp->len) == 0){
+						b = NULL;
+						break;
+					}
+				}
+			}
+		}
+		/*
+		 *  次のDESCRIPTORの取得と更新
+		 */
+		desc = emac_recv_desc_next(hmac);
+
+		/*
+		 *  End of Packetの場合、正常終了
+		 */
+		if((info_word & DESC_RXSTS_RXLAST) != 0)
+			return E_OK;
+	}
+	return E_NOMEM;
+}
+
+/*
+ *  DESCRIPTORのリセット
+ *  parameter1 hmac  EMACハンドラへのポインタ
+ */
+static void
+emac_desc_reset(EMAC_Handle_t *hmac)
+{
+	volatile uint32_t *desc;
+	int      i;
+
+	/*
+	 *  送信ディスクリプタの初期化
+	 */
+	desc = hmac->tx_top_desc;
+	hmac->tx_cur_desc = desc;
+	for(i = 0 ; i < hmac->Init.txquecount ; i++) {
+		desc[DESC_TXRX_STATUS] &= ~(DESC_TXSTS_TXINT | DESC_TXSTS_TXLAST |
+				DESC_TXSTS_TXFIRST | DESC_TXSTS_TXCRCDIS | \
+				DESC_TXSTS_TXCHECKINSCTRL | \
+				DESC_TXSTS_TXRINGEND | DESC_TXSTS_TXPADDIS);
+		desc[DESC_TXRX_STATUS] |= DESC_TXSTS_TXCHAIN | DESC_TXSTS_TXCHECKINSCTRL;
+		desc[DESC_TXRX_CONTROL] = 0;
+		desc[DESC_TXRX_STATUS] &= ~(DESC_TXSTS_MSK | DESC_TXSTS_OWNBYDMA);
+		desc += DESC_TXRX_SIZE;
+	}
+
+	/*
+	 *  受信ディスクリプタの初期化
+	 */
+	desc = hmac->rx_top_desc;
+	hmac->rx_cur_desc = desc;
+	for (i = 0 ; i < hmac->Init.rxquecount ; i++) {
+		desc[DESC_TXRX_CONTROL] = 
+			(hmac->Init.paketbufsize & DESC_RXCTRL_SIZE1MASK) | DESC_RXCTRL_RXCHAIN;
+		desc[DESC_TXRX_STATUS] = DESC_RXSTS_OWNBYDMA;
+		desc += DESC_TXRX_SIZE;
+	}
+
+	sil_wrw_mem((uint32_t *)(hmac->base+TOFF_ETH_DMATDLAR), (uint32_t)(hmac->tx_top_desc));
+	sil_wrw_mem((uint32_t *)(hmac->base+TOFF_ETH_DMARDLAR), (uint32_t)(hmac->rx_top_desc));
+}
+
+/*
+ *  ETHERNET通信を開始する
+ *  parameter1 hmac  EMACハンドラへのポインタ
+ *  parameter2 link  通信モード
+ *  return     E_OKで正常終了
+ */
+ER
+emac_start(EMAC_Handle_t *hmac, uint32_t link)
+{
+	uint32_t   base, tmp;
+
+	if(hmac == NULL)
+		return E_PAR;
+	base = hmac->base;
+
+	/*
+	 *  PHYスタート
+	 */
+	emac_phy_start(hmac, link);
+
+	/*
+	 *  送受信を有効設定
+	 */
+	sil_orw_mem((uint32_t *)(base+TOFF_ETH_DMAOMR), ETH_DMAOMR_SR);
+
+	/*
+	 *  割り込みマスク設定
+	 */
+	sil_orw_mem((uint32_t *)(base+TOFF_ETH_DMAIER), DMA_INTR_DEFAULT_MASK);
+
+	/*
+	 *  割り込み許可
+	 */
+	ena_int(hmac->intno);
+
+	sil_wrw_mem((uint32_t *)(base+TOFF_ETH_DMASR), 0x0001FFFF);
+	sil_orw_mem((uint32_t *)(base+TOFF_ETH_MACCR), (ETH_MACCR_TE | ETH_MACCR_RE));
+	tmp = sil_rew_mem((uint32_t *)(base+TOFF_ETH_MACCR));
+	dly_tsk(1);
+	sil_wrw_mem((uint32_t *)(base+TOFF_ETH_MACCR), tmp);
+	return E_OK;
+}
+
+/*
+ *  ETHERNET通信を停止する
+ *  parameter1 hmac  EMACハンドラへのポインタ
+ *  parameter2 disable 送受信の無効化設定(1で無効化)
+ *  return     E_OKで正常終了
+ */
+ER
+emac_stop(EMAC_Handle_t *hmac, int disable)
+{
+	uint32_t base, tmp;
+	ER       ercd = E_OK;
+
+	if(hmac == NULL)
+		return E_PAR;
+	base = hmac->base;
+
+	/*
+	 * 割り込み停止
+	 */
+	dis_int(hmac->intno);
+	sil_wrw_mem((uint32_t *)(base+TOFF_ETH_DMAIER), 0);
+
+	if(disable == 1) {
+		/*
+		 *  送受信を無効に設定
+		 */
+		sil_andw_mem((uint32_t *)(base+TOFF_ETH_MACCR), ETH_MACCR_RE);
+		tmp = sil_rew_mem((uint32_t *)(base+TOFF_ETH_MACCR));
+		dly_tsk(1);
+		sil_wrw_mem((uint32_t *)(base+TOFF_ETH_MACCR), tmp);
+
+		dly_tsk(200);
+
+		/*
+		 *  受信済みパケットを破棄
+		 */
+		while(ercd == E_OK){
+			ercd = emac_recv(hmac, NULL);
+			dly_tsk(1);
+			syslog_1(LOG_NOTICE, "EMAC:emac_stop flush result(%d) !", ercd);
+		}
+		sil_andw_mem((uint32_t *)(base+TOFF_ETH_DMAOMR), ETH_DMAOMR_SR);
+		sil_andw_mem((uint32_t *)(base+TOFF_ETH_MACCR), ETH_MACCR_TE);
+		tmp = sil_rew_mem((uint32_t *)(base+TOFF_ETH_MACCR));
+		dly_tsk(1);
+		sil_wrw_mem((uint32_t *)(base+TOFF_ETH_MACCR), tmp);
+		sil_andw_mem((uint32_t *)(base+TOFF_ETH_DMAOMR), ETH_DMAOMR_ST);
+	}
+	return E_OK;
+}
+
+/*
+ *  LINK状態を取得する
+ *  parameter1 hmac  EMACハンドラへのポインタ
+ *  return     LINK状態(0で未接続)
+ */
+uint32_t
+emac_link_detect(EMAC_Handle_t *hmac)
+{
+	uint32_t link_detect = 0;
+	int      bmsr;
+
+	/* 最初は空読み */
+	emac_mdio_read(hmac, MII_BMSR);
+	bmsr = emac_mdio_read(hmac, MII_BMSR);
+	//syslog_2(LOG_INFO, "EMAC:phy_link_detect[%08x] phydev->auto_nego(%d)", bmsr, is_autonego(hmac));
+
+	if((bmsr >= 0) && (bmsr & BMSR_LSTATUS)){
+		link_detect = is_autonego(hmac)
+				? emac_phy_link_autonego(hmac)
+				: emac_phy_link_manual(hmac);
+	}
+	return link_detect;
+}
+
+/*
+ *  EMACの制御設定を行う
+ *  parameter1 hmac  EMACハンドラへのポインタ
+ *  parameter2 link  EMAC設定モード
+ *  return     E_OKで正常終了
+ */
+ER
+emac_link_mode_set(EMAC_Handle_t *hmac, uint32_t link)
+{
+	uint32_t base, conf;
+
+	if(hmac == NULL || link == 0)
+		return E_PAR;
+	base = hmac->base;
+	conf = sil_rew_mem((uint32_t *)(base+TOFF_ETH_MACCR));
+
+	if((link & EMAC_SPEED_MASK) != EMAC_SPEED_10BASE)
+		conf |= ETH_MACCR_FES;
+	else
+		conf &= ~ETH_MACCR_FES;
+
+	if((link & EMAC_DUPLEX_MASK) == EMAC_DUPLEX_FULL)
+		conf |= ETH_MACCR_DM;
+	else
+		conf &= ~ETH_MACCR_DM;
+	sil_wrw_mem((uint32_t *)(base+TOFF_ETH_MACCR), conf);
+	return E_OK;
+}
+
+/*
+ *  EMACをリセットする
+ *  parameter1 hmac   EMACハンドラへのポインタ
+ *  parameter2 macadr MACアドレスデータへのポインタ
+ *  return     E_OKで正常終了
+ */
+ER
+emac_reset(EMAC_Handle_t *hmac, uint8_t *mac_addr)
+{
+	uint32_t  timeout = 3000;
+	uint32_t  base, tmp;
+	uint32_t  macid_hi, macid_lo;
+	uint8_t   *b = (uint8_t *)&mac_addr[0];
+
+	if(hmac == NULL || mac_addr == NULL)
+		return E_PAR;
+	base = hmac->base;
+
+	/*
+	 *  MACをリセット
+	 */
+	sil_orw_mem((uint32_t *)(base+TOFF_ETH_DMABMR), ETH_DMABMR_SR);
+	while(timeout > 0){
+		if((sil_rew_mem((uint32_t *)(base+TOFF_ETH_DMABMR)) & ETH_DMABMR_SR) == 0)
+			break;
+		dly_tsk(1);
+		timeout--;
+	}
+
+	/* Get the ETHERNET MACMIIAR value */
+	tmp= sil_rew_mem((uint32_t *)(base+TOFF_ETH_MACMIIAR));
+	/* Clear CSR Clock Range CR[2:0] bits */
+	tmp &= ~ETH_MACMIIAR_CR;
+	tmp |= emac_ether_clockdiv();
+	sil_wrw_mem((uint32_t *)(base+TOFF_ETH_MACMIIAR), tmp);
+
+	/*
+	 *  送受信の停止
+	 */
+	emac_stop(hmac, 0);
+
+	/*
+	 *  MACアドレスの登録
+	 */
+	macid_lo = b[0] + (b[1] << 8) + (b[2] << 16) + (b[3] << 24);
+	macid_hi = b[4] + (b[5] << 8);
+	sil_wrw_mem((uint32_t *)(base+TOFF_ETH_MACA0HR), macid_hi);
+	sil_wrw_mem((uint32_t *)(base+TOFF_ETH_MACA0LR), macid_lo);
+
+	/*
+	 *  MACの設定
+	 */
+	sil_modw_mem((uint32_t *)(base+TOFF_ETH_MACCR), ETH_MACCR_MASK, ETH_MACCR_INIT);
+	tmp = sil_rew_mem((uint32_t *)(base+TOFF_ETH_MACCR));
+	dly_tsk(1);
+	sil_wrw_mem((uint32_t *)(base+TOFF_ETH_MACCR), tmp);
+
+	sil_wrw_mem((uint32_t *)(base+TOFF_ETH_MACFFR), ETH_MACFFR_INIT);
+	tmp = sil_rew_mem((uint32_t *)(base+TOFF_ETH_MACFFR));
+	dly_tsk(1);
+	sil_wrw_mem((uint32_t *)(base+TOFF_ETH_MACFFR), tmp);
+
+	sil_wrw_mem((uint32_t *)(base+TOFF_ETH_MACHTHR), 0x00000000);
+	sil_wrw_mem((uint32_t *)(base+TOFF_ETH_MACHTLR), 0x00000000);
+
+	sil_modw_mem((uint32_t *)(base+TOFF_ETH_MACFCR), ETH_MACFCR_MASK, ETH_MACFCR_INIT);
+	tmp = sil_rew_mem((uint32_t *)(base+TOFF_ETH_MACFCR));
+	dly_tsk(1);
+	sil_wrw_mem((uint32_t *)(base+TOFF_ETH_MACFCR), tmp);
+
+	sil_wrw_mem((uint32_t *)(base+TOFF_ETH_MACVLANTR), ETH_MACVLANTR_INIT);
+
+	sil_modw_mem((uint32_t *)(base+TOFF_ETH_DMAOMR), ETH_DMAOMR_MASK, ETH_DMAOMR_INIT);
+	tmp = sil_rew_mem((uint32_t *)(base+TOFF_ETH_DMAOMR));
+	dly_tsk(1);
+	sil_wrw_mem((uint32_t *)(base+TOFF_ETH_DMAOMR), tmp);
+
+	sil_wrw_mem((uint32_t *)(base+TOFF_ETH_DMABMR), ETH_DMABMR_INIT);
+	tmp = sil_rew_mem((uint32_t *)(base+TOFF_ETH_DMABMR));
+	dly_tsk(1);
+	sil_wrw_mem((uint32_t *)(base+TOFF_ETH_DMABMR), tmp);
+
+	/*
+	 *  送受信DESCRIPTERリセット
+	 */
+	emac_desc_reset(hmac);
+
+	sil_orw_mem((uint32_t *)(base+TOFF_ETH_MACCR), (ETH_MACCR_TE | ETH_MACCR_RE));
+	tmp = sil_rew_mem((uint32_t *)(base+TOFF_ETH_MACCR));
+	dly_tsk(1);
+	sil_wrw_mem((uint32_t *)(base+TOFF_ETH_MACCR), tmp);
+
+	sil_wrw_mem((uint32_t *)(base+TOFF_ETH_DMASR), 0x0001FFFF);
+	sil_orw_mem((uint32_t *)(base+TOFF_ETH_DMAOMR), ETH_DMAOMR_FTF);
+	tmp = sil_rew_mem((uint32_t *)(base+TOFF_ETH_DMAOMR));
+	dly_tsk(1);
+	sil_wrw_mem((uint32_t *)(base+TOFF_ETH_DMAOMR), tmp);
+	sil_orw_mem((uint32_t *)(base+TOFF_ETH_DMAOMR), ETH_DMAOMR_SR);
+	return E_OK;
+}
+
+
+/*
+ *  EMAC DMA用割り込み処理
+ */
+static int
+emac_dma_interrupt(EMAC_Handle_t *hmac, uint32_t status)
+{
+	int  event = 0;
+
+	if((status & 0x1FFFF) == 0)
+		return 0;
+	event = 0;
+
+	/*
+	 *  ABNORMAL割り込み
+	 */
+	if((status & ETH_DMASR_AIS) != 0) {
+		if((status & ETH_DMASR_TUS) != 0)
+			hmac->tx_undeflow_irq++;
+		if((status & ETH_DMASR_TJTS) != 0)
+			hmac->tx_jabber_irq++;
+		if((status & ETH_DMASR_ROS) != 0)
+			hmac->rx_overflow_irq++;
+		if((status & ETH_DMASR_RBUS) != 0)
+			hmac->rx_buf_unav_irq++;
+		if((status & ETH_DMASR_RPSS) != 0)
+			hmac->rx_process_stopped_irq++;
+		if((status & ETH_DMASR_RWTS) != 0)
+			hmac->rx_watchdog_irq++;
+		if((status & ETH_DMASR_ETS) != 0)
+			hmac->tx_early_irq++;
+		if((status & ETH_DMASR_TPSS) != 0)
+			hmac->tx_process_stopped_irq++;
+		if((status & ETH_DMASR_FBES) != 0){
+			hmac->fatal_bus_error_irq++;
+			event |= 0x0004;
+		}
+	}
+
+	/*
+	 *  TX/RX NORMAL割り込み
+	 */
+	if((status & ETH_DMASR_NIS) != 0)
+		hmac->normal_irq_n++;
+	if((status & ETH_DMASR_RS) != 0) {
+		uint32_t value = sil_rew_mem((uint32_t *)(hmac->base+TOFF_ETH_DMAIER));
+		/* to schedule NAPI on real RIE event. */
+		if((value & ETH_DMAIER_RIE) != 0){
+			hmac->rx_normal_irq_n++;
+			if(hmac->emacevent != NULL)
+				hmac->emacevent(hmac, 0, RECV_EVENT_DETECT);
+		}
+	}
+	if((status & ETH_DMASR_TS) != 0){
+		/*
+		 * 送信割り込みを通知する
+		 */
+		if(hmac->tx_wait != 0){
+			if(hmac->emacevent != NULL)
+				hmac->emacevent(hmac, 0, SEND_EVENT_DETECT);
+			if(hmac->tx_wait > 0)
+				hmac->tx_wait--;
+		}
+	}
+	if((status & ETH_DMASR_ERS) != 0)
+		hmac->rx_early_irq++;
+	return event;
+}
+
+/*
+ *  EMAC割り込みサービスルーチン
+ */
+void
+emac_hps_isr(intptr_t exinf)
+{
+	EMAC_Handle_t *hmac = &EMacHandle[INDEX_EMAC((uint32_t)exinf)];
+	uint32_t base, dstatus;
+	uint32_t event;
+
+	base = hmac->base;
+	dstatus = sil_rew_mem((uint32_t *)(base+TOFF_ETH_DMASR));
+	syslog_1(LOG_DEBUG, "emac_hps_isr SR[%08x]", dstatus);
+	if(dstatus != 0){
+		event = emac_dma_interrupt(hmac, dstatus);
+		sil_wrw_mem((uint32_t *)(base+TOFF_ETH_DMASR), (dstatus & 0x0001FFFB));
+		/*
+		 *  DMAエラーがあった場合、通知
+		 */
+		if(event != 0){
+			syslog_2(LOG_ERROR, "EMAC:emac_isr id(%d) DMA error[%08x] !", (int)exinf, event);
+			if(hmac->emacevent != NULL)
+				hmac->emacevent(hmac, 0, RESET_EVNT_DETECT);
+		}
+	}
+}
+
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/pdic/stm32f7xx/emac.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/pdic/stm32f7xx/emac.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/pdic/stm32f7xx/emac.h	(revision 457)
@@ -0,0 +1,206 @@
+/*
+ *  TOPPERS/ASP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Advanced Standard Profile Kernel
+ * 
+ *  Copyright (C) 2008-2011 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ *  Copyright (C) 2015-2019 by TOPPERS PROJECT Educational Working Group.
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+/*
+ * 
+ *  STMicroelectronics EMACデバイスドライバの外部宣言
+ *
+ */
+
+#ifndef _EMAC_H_
+#define _EMAC_H_
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/*
+ *  MACポート定義
+ */
+#define MAC1_PORTID             1
+#define NUM_MACPORT             1
+#define MACDEF_PORTID           MAC1_PORTID
+
+/*
+ *  MAC EVENT定義
+ */
+#define PHY_EVENT_DETECT        (1<<0)
+#define SEND_EVENT_DETECT       (1<<1)
+#define RECV_EVENT_DETECT       (1<<2)
+#define RESET_EVNT_DETECT       (1<<7)
+
+/*
+ *  ETHERNETアドレス長
+ */
+#define	ADLEN_ETHER	6
+#define ETHER_HDR_SIZE	((ADLEN_ETHER*2)+2)
+
+/*
+ *  LINK設定定義
+ */
+#define EMAC_LINK_CONNECT       0x00080000
+#define EMAC_LINK_AUTONEGO      0x00010000
+#define EMAC_DUPLEX_HALF        0x00000000			/* HALF DUPLEX */
+#define EMAC_DUPLEX_FULL        0x00000100			/* FULL DUPLEX */
+#define EMAC_DUPLEX_MASK        EMAC_DUPLEX_FULL	/* DUPLEX MASK */
+
+#define EMAC_SPEED_MASK         0x000000FF			/* LINK SPEED MASK */
+#define EMAC_SPEED_10BASE       0x00000003			/* LINK SPEED 10BASE */
+#define EMAC_SPEED_100BASE      0x00000004			/* LINK SPEED 100BASE */
+#define EMAC_SPEED_1000BASE     0x00000005			/* LINK SPEED 1000BASE */
+
+#define EMAC_LINK_10BASE2       0x00000001			/* 10Base2 */
+#define EMAC_LINK_10BASE5       0x00000002			/* 10Base5 */
+#define EMAC_LINK_10BASE_HALF   (EMAC_SPEED_10BASE   | EMAC_DUPLEX_HALF)
+#define EMAC_LINK_10BASE_FULL   (EMAC_SPEED_10BASE   | EMAC_DUPLEX_FULL)
+#define EMAC_LINK_100BASE_HALF  (EMAC_SPEED_100BASE  | EMAC_DUPLEX_HALF)
+#define EMAC_LINK_100BASE_FULL  (EMAC_SPEED_100BASE  | EMAC_DUPLEX_FULL)
+#define EMAC_LINK_1000BASE_HALF (EMAC_SPEED_1000BASE | EMAC_DUPLEX_HALF)
+#define EMAC_LINK_1000BASE_FULL (EMAC_SPEED_1000BASE | EMAC_DUPLEX_FULL)
+
+#define LINK_SPEED_OF_YOUR_NETIF_IN_BPS  100000000
+
+/*
+ *  DESCRIPTOR定義
+ */
+#define NUM_RX_DESC     8		/* 受信キューの個数 */
+#define NUM_TX_DESC     8		/* 送信キューの個数 */
+#define EMAC_DATA_ATTRIBUTE     (section(".ethDataSection"))
+
+/*
+ *  DESCRIPTOR COMMON定義
+ */
+#define DESC_TXRX_STATUS        0
+#define DESC_TXRX_CONTROL       1
+#define DESC_TXRX_BUFFER        2
+#define DESC_TXRX_NEXT          3
+#define DESC_TXRX_EXTSTATUS     4
+#define DESC_TXRX_TIMESTAMPLOW  6
+#define DESC_TXRX_TIMESTAMPHIGH 7
+#define DESC_TXRX_SIZE          8
+#define EMAC_QUE_SIZE           (DESC_TXRX_SIZE * 4)
+
+/*
+ *  EMACコンフュギュレーション構造体定義
+ */
+typedef struct
+{
+	uint32_t              paketbufsize;		/* EMAC パケットバッファサイズ */
+	uint32_t              rxquecount;		/* EMAC 受信ディスクリプタサイズ */
+	uint32_t              txquecount;		/* EMAC 送信ディスクリプタサイズ */
+	void                  *quebuffer;		/* EMAC ディスクリプタ先頭アドレス */
+	void                  *databuffer;		/* EMAC データ領域先頭アドレス */
+	ID                    semid;			/* EMAC 通信用セマフォ値 */
+}EMAC_Init_t;
+
+/*
+ *  EMACハンドラ定義
+ */
+typedef struct EMAC_Handle EMAC_Handle_t;
+struct EMAC_Handle {
+	uint32_t     base;
+	EMAC_Init_t  Init;
+	uint8_t      tx_wait;
+	uint8_t      intno;
+	uint8_t      macid;
+	uint8_t      phy_addr;
+	uint32_t     phy_features;
+	uint32_t     linkvalue;
+
+	volatile uint32_t *tx_top_desc;
+	volatile uint32_t *tx_cur_desc;
+	volatile uint32_t *rx_top_desc;
+	volatile uint32_t *rx_cur_desc;
+	void         (*emacevent)(EMAC_Handle_t *hmac, int, uint32_t);
+	void         (*phy_opt_init)(EMAC_Handle_t *hmac);
+
+	uint32_t     ifShortPkts;
+	uint32_t     mmc_tx_irq_n;
+	uint32_t     mmc_rx_irq_n;
+	uint32_t     mmc_rx_csum_offload_irq_n;
+	uint32_t     irq_receive_pmt_irq_n;
+	uint32_t     irq_tx_path_in_lpi_mode_n;
+	uint32_t     irq_tx_path_exit_lpi_mode_n;
+	uint32_t     irq_rx_path_in_lpi_mode_n;
+	uint32_t     irq_rx_path_exit_lpi_mode_n;
+
+	uint32_t     normal_irq_n;
+	uint32_t     fatal_bus_error_irq;
+	uint32_t     tx_undeflow_irq;
+	uint32_t     tx_jabber_irq;
+	uint32_t     tx_early_irq;
+	uint32_t     tx_process_stopped_irq;
+	uint32_t     rx_normal_irq_n;
+	uint32_t     rx_early_irq;
+	uint32_t     rx_overflow_irq;
+	uint32_t     rx_buf_unav_irq;
+	uint32_t     rx_process_stopped_irq;
+	uint32_t     rx_watchdog_irq;
+};
+
+/*
+ *  LWIP用パケットバッファ構造体
+ */
+struct emac_pkt {
+	struct emac_pkt *next;					/* next pbuf chain */
+	void         *payload;					/* pointer to the data buffer */
+	uint16_t     tot_len;					/* total length of this buffer and all next buffers in chain */
+	uint16_t     len;						/* length of this buffer */
+};
+
+
+extern EMAC_Handle_t *emac_init(ID portid, EMAC_Init_t *ini);
+extern ER   emac_deinit(EMAC_Handle_t *hmac);
+extern ER   emac_send(EMAC_Handle_t *hmac, struct emac_pkt *pktp);
+extern int  emac_recv_length(EMAC_Handle_t *hmac);
+extern ER   emac_recv(EMAC_Handle_t *hmac, struct emac_pkt *pktp);
+extern ER   emac_start(EMAC_Handle_t *hmac, uint32_t link_mode);
+extern ER   emac_stop(EMAC_Handle_t *hmac, int disable);
+extern uint32_t emac_link_detect(EMAC_Handle_t *hmac);
+extern ER   emac_link_mode_set(EMAC_Handle_t *hmac, uint32_t link_detect);
+extern ER   emac_reset(EMAC_Handle_t *hmac, uint8_t *mac_addr);
+extern void emac_hps_isr(intptr_t exinf);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _EMAC_H_ */
+
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/pdic/stm32f7xx/i2c.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/pdic/stm32f7xx/i2c.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/pdic/stm32f7xx/i2c.c	(revision 457)
@@ -0,0 +1,1099 @@
+/*
+ *  TOPPERS/ASP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Advanced Standard Profile Kernel
+ * 
+ *  Copyright (C) 2008-2011 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ *  Copyright (C) 2015-2018 by TOPPERS PROJECT Educational Working Group.
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+/*
+ * 
+ *  I2Cドライバ関数群
+ *
+ */
+#include "kernel_impl.h"
+#include <t_syslog.h>
+#include <t_stdlib.h>
+#include <string.h>
+#include <sil.h>
+#include <target_syssvc.h>
+#include "kernel_cfg.h"
+#include "device.h"
+#include "i2c.h"
+
+#define sil_orw_mem(a, b)		sil_wrw_mem((a), sil_rew_mem(a) | (b))
+#define sil_andw_mem(a, b)		sil_wrw_mem((a), sil_rew_mem(a) & ~(b))
+#define sil_modw_mem(a, b, c)	sil_wrw_mem((a), (sil_rew_mem(a) & (~b)) | (c))
+
+/*
+ *  I2CポートIDから管理ブロックを取り出すためのマクロ
+ */
+#define INDEX_I2C(i2cid)        ((uint_t)((i2cid) - 1))
+
+#define GPIO_AF4_I2C1           0x04	/* I2C1 Alternate Function mapping */
+#define GPIO_AF4_I2C2           0x04	/* I2C2 Alternate Function mapping */
+#define GPIO_AF4_I2C3           0x04	/* I2C3 Alternate Function mapping */
+#define GPIO_AF4_I2C4           0x04	/* I2C4 Alternate Function mapping */
+#define GPIO_AF11_I2C4          0x0B	/* I2C4 Alternate Function mapping */
+
+/*
+ *  I2Cポート設定テーブル
+ */
+static const I2C_PortControlBlock i2c_pcb[NUM_I2CPORT] = {
+  {	TADR_I2C1_BASE,
+	(TADR_RCC_BASE+TOFF_RCC_AHB1ENR),  RCC_AHB1ENR_GPIOBEN, RCC_AHB1ENR_GPIOBEN,
+	(TADR_RCC_BASE+TOFF_RCC_APB1ENR),  RCC_APB1ENR_I2C1EN,
+	(TADR_RCC_BASE+TOFF_RCC_APB1RSTR), RCC_APB1RSTR_I2C1RST,
+	TADR_GPIOB_BASE, TADR_GPIOB_BASE,
+	8, GPIO_AF4_I2C1, 9, GPIO_AF4_I2C1 },
+
+#if defined(TOPPERS_STM32F723_DISCOVERY)
+  {	TADR_I2C2_BASE,
+	(TADR_RCC_BASE+TOFF_RCC_AHB1ENR),  RCC_AHB1ENR_GPIOHEN, RCC_AHB1ENR_GPIOHEN,
+	(TADR_RCC_BASE+TOFF_RCC_APB1ENR),  RCC_APB1ENR_I2C2EN,
+	(TADR_RCC_BASE+TOFF_RCC_APB1RSTR), RCC_APB1RSTR_I2C2RST,
+	TADR_GPIOH_BASE, TADR_GPIOH_BASE,
+	4, GPIO_AF4_I2C2, 5, GPIO_AF4_I2C2 },
+
+  {	TADR_I2C3_BASE,
+	(TADR_RCC_BASE+TOFF_RCC_AHB1ENR),  RCC_AHB1ENR_GPIOAEN, RCC_AHB1ENR_GPIOHEN,
+	(TADR_RCC_BASE+TOFF_RCC_APB1ENR),  RCC_APB1ENR_I2C3EN,
+	(TADR_RCC_BASE+TOFF_RCC_APB1RSTR), RCC_APB1RSTR_I2C3RST,
+	TADR_GPIOA_BASE, TADR_GPIOH_BASE,
+	8, GPIO_AF4_I2C3, 8, GPIO_AF4_I2C3 },
+#else
+  {	TADR_I2C2_BASE,
+	(TADR_RCC_BASE+TOFF_RCC_AHB1ENR),  RCC_AHB1ENR_GPIOHEN, RCC_AHB1ENR_GPIOHEN,
+	(TADR_RCC_BASE+TOFF_RCC_APB1ENR),  RCC_APB1ENR_I2C2EN,
+	(TADR_RCC_BASE+TOFF_RCC_APB1RSTR), RCC_APB1RSTR_I2C2RST,
+	TADR_GPIOH_BASE, TADR_GPIOH_BASE,
+	1, GPIO_AF4_I2C2, 0, GPIO_AF4_I2C2 },
+
+  {	TADR_I2C3_BASE,
+	(TADR_RCC_BASE+TOFF_RCC_AHB1ENR),  RCC_AHB1ENR_GPIOHEN, RCC_AHB1ENR_GPIOHEN,
+	(TADR_RCC_BASE+TOFF_RCC_APB1ENR),  RCC_APB1ENR_I2C3EN,
+	(TADR_RCC_BASE+TOFF_RCC_APB1RSTR), RCC_APB1RSTR_I2C3RST,
+	TADR_GPIOH_BASE, TADR_GPIOH_BASE,
+	7, GPIO_AF4_I2C3, 8, GPIO_AF4_I2C3 },
+#endif
+
+#if defined(TOPPERS_STM32F769_DISCOVERY)
+  {	TADR_I2C4_BASE,
+	(TADR_RCC_BASE+TOFF_RCC_AHB1ENR),  RCC_AHB1ENR_GPIODEN, RCC_AHB1ENR_GPIOBEN,
+	(TADR_RCC_BASE+TOFF_RCC_APB1ENR),  RCC_APB1ENR_I2C4EN,
+	(TADR_RCC_BASE+TOFF_RCC_APB1RSTR), RCC_APB1RSTR_I2C4RST,
+	TADR_GPIOD_BASE, TADR_GPIOB_BASE,
+	12, GPIO_AF4_I2C4, 7, GPIO_AF11_I2C4 }
+#else
+  {	TADR_I2C4_BASE,
+	(TADR_RCC_BASE+TOFF_RCC_AHB1ENR),  RCC_AHB1ENR_GPIODEN, RCC_AHB1ENR_GPIODEN,
+	(TADR_RCC_BASE+TOFF_RCC_APB1ENR),  RCC_APB1ENR_I2C4EN,
+	(TADR_RCC_BASE+TOFF_RCC_APB1RSTR), RCC_APB1RSTR_I2C4RST,
+	TADR_GPIOD_BASE, TADR_GPIOB_BASE,
+	12, GPIO_AF4_I2C4, 13, GPIO_AF4_I2C4 }
+#endif
+};
+
+static I2C_Handle_t I2cHandle[NUM_I2CPORT];
+
+/*
+ *  I2C スタートストップモード定義
+ */
+#define I2C_NO_STARTSTOP    0x00000000
+
+/*
+ *  I2C リロードエンドモード定義
+ */
+#define I2C_SOFTEND_MODE    0x00000000
+
+#define TIMING_CLEAR_MASK   0xF0FFFFFF		/* I2C TIMING clear register Mask */
+
+#define I2C_CR1_TRANS1      (I2C_CR1_TCIE | I2C_CR1_STOPIE | I2C_CR1_NACKIE | I2C_CR1_TXIE | I2C_CR1_ADDRIE)
+#define I2C_CR1_TRANS2      (I2C_CR1_TCIE | I2C_CR1_STOPIE | I2C_CR1_NACKIE | I2C_CR1_TXIE)
+
+#define I2C_CR1_RECV1       (I2C_CR1_TCIE| I2C_CR1_STOPIE| I2C_CR1_NACKIE | I2C_CR1_RXIE | I2C_CR1_ADDRIE)
+#define I2C_CR1_RECV2       (I2C_CR1_TCIE| I2C_CR1_STOPIE| I2C_CR1_NACKIE | I2C_CR1_RXIE)
+#define I2C_CR1_ERROR       (I2C_CR1_ERRIE | I2C_CR1_TCIE | I2C_CR1_STOPIE | I2C_CR1_NACKIE)
+#define I2C_CR2_RESET       (I2C_CR2_SADD | I2C_CR2_HEAD10R | I2C_CR2_NBYTES | I2C_CR2_RELOAD | I2C_CR2_RD_WRN)
+
+/*
+ *  I2Cデバイスの初期化
+ *  parameter1 hi2c  I2Cハンドラへのポインタ
+ *  return           正常終了時、E_OK
+ */
+I2C_Handle_t *
+i2c_init(ID port, I2C_Init_t *pini)
+{
+	const I2C_PortControlBlock *ipcb;
+	GPIO_Init_t  gpio_init;
+	I2C_Handle_t *hi2c;
+	volatile uint32_t tmp;
+	int no;
+
+	if(port < I2C1_PORTID || port > NUM_I2CPORT)
+		return NULL;
+	if(pini == NULL)
+		return NULL;
+
+	no = INDEX_I2C(port);
+	ipcb = &i2c_pcb[no];
+
+	hi2c = &I2cHandle[no];
+	if(hi2c->State != I2C_STATE_RESET)
+		return NULL;
+	memcpy(&hi2c->Init, pini, sizeof(I2C_Init_t));
+	hi2c->base  = ipcb->base;
+	hi2c->State = I2C_STATE_BUSY;
+	hi2c->i2cid = port;
+
+	/*
+	 *  I2C-GPIOクロック設定
+	 */
+	sil_orw_mem((uint32_t *)ipcb->gioclockbase, ipcb->gioclockbit1);
+	tmp = sil_rew_mem((uint32_t *)ipcb->gioclockbase);
+	sil_orw_mem((uint32_t *)ipcb->gioclockbase, ipcb->gioclockbit2);
+	tmp = sil_rew_mem((uint32_t *)ipcb->gioclockbase);
+
+	/*
+	 *  SCLピン設定
+	 */
+	gpio_init.mode  = GPIO_MODE_AF;
+	gpio_init.pull  = GPIO_NOPULL;
+	gpio_init.otype = GPIO_OTYPE_OD;
+	gpio_init.speed = GPIO_SPEED_FAST;
+	gpio_init.alternate = ipcb->sclaf;
+	gpio_setup(ipcb->giobase1, &gpio_init, ipcb->sclpin);
+
+	/*
+	 *  SDAピン設定
+	 */
+	gpio_init.alternate = ipcb->sdaaf;
+	gpio_setup(ipcb->giobase2, &gpio_init, ipcb->sdapin);
+
+	sil_orw_mem((uint32_t *)ipcb->i2cclockbase, ipcb->i2cclockbit);
+	tmp = sil_rew_mem((uint32_t *)ipcb->i2cclockbase);
+	(void)(tmp);
+	sil_orw_mem((uint32_t *)ipcb->i2cresetbase, ipcb->i2cresetbit);
+	sil_andw_mem((uint32_t *)ipcb->i2cresetbase, ipcb->i2cresetbit);
+
+	/* I2C Disable */
+	sil_andw_mem((uint32_t *)(hi2c->base+TOFF_I2C_CR1), I2C_CR1_PE);
+
+	/*
+	 *  I2C TIMINGR設定
+	 */
+	sil_wrw_mem((uint32_t *)(hi2c->base+TOFF_I2C_TIMINGR), (hi2c->Init.Timing & TIMING_CLEAR_MASK));
+
+	/*
+	 *  I2Cアドレス1設定
+	 */
+	sil_andw_mem((uint32_t *)(hi2c->base+TOFF_I2C_OAR1), I2C_OAR1_OA1EN);
+	if(hi2c->Init.AddressingMode == I2C_ADDRESSINGMODE_7BIT)
+		sil_wrw_mem((uint32_t *)(hi2c->base+TOFF_I2C_OAR1), (I2C_OAR1_OA1EN | hi2c->Init.OwnAddress1));
+	else /* I2C_ADDRESSINGMODE_10BIT */
+		sil_wrw_mem((uint32_t *)(hi2c->base+TOFF_I2C_OAR1), (I2C_OAR1_OA1EN | I2C_OAR1_OA1MODE | hi2c->Init.OwnAddress1));
+
+	/*
+	 *  I2C CR2レジスタ設定
+	 */
+	if(hi2c->Init.AddressingMode == I2C_ADDRESSINGMODE_10BIT)
+		sil_wrw_mem((uint32_t *)(hi2c->base+TOFF_I2C_CR2), (I2C_CR2_ADD10));
+	sil_orw_mem((uint32_t *)(hi2c->base+TOFF_I2C_CR2), (I2C_CR2_AUTOEND | I2C_CR2_NACK));
+
+	/*
+	 *  I2Cアドレス2設定
+	 */
+	sil_wrw_mem((uint32_t *)(hi2c->base+TOFF_I2C_OAR2), (hi2c->Init.DualAddressMode | hi2c->Init.OwnAddress2 | (hi2c->Init.OwnAddress2Masks << 8)));
+
+	/*
+	 *  I2C CR1レジスタ設定
+	 */
+	sil_wrw_mem((uint32_t *)(hi2c->base+TOFF_I2C_CR1), (hi2c->Init.GeneralCallMode | hi2c->Init.NoStretchMode));
+	sil_orw_mem((uint32_t *)(hi2c->base+TOFF_I2C_CR1), I2C_CR1_PE);
+
+	hi2c->ErrorCode = I2C_ERROR_NONE;
+	hi2c->State = I2C_STATE_READY;
+	return hi2c;
+}
+
+/*
+ *  I2Cデバイスの無効化
+ *  parameter1 hi2c  I2Cハンドラへのポインタ
+ *  return           正常終了時、E_OK
+ */
+ER
+i2c_deinit(I2C_Handle_t *hi2c)
+{
+	/* ハンドラのチェック */
+	if(hi2c == NULL)
+		return E_PAR;
+
+	hi2c->State = I2C_STATE_BUSY;
+
+	/*
+	 *  I2Cクロック停止
+	 */
+	sil_andw_mem((uint32_t *)(hi2c->base+TOFF_I2C_CR1), I2C_CR1_PE);
+
+	hi2c->ErrorCode = I2C_ERROR_NONE;
+	hi2c->State = I2C_STATE_RESET;
+	return E_OK;
+}
+
+/*
+ *  I2C通信のスタート設定
+ *  parameter1 hi2c       I2Cハンドラへのポインタ
+ *  parameter2 DevAddress スレーブアドレス
+ *  parameter3 Size       メモリアドレスのサイズ
+ *  parameter4 Mode       設定モード
+ *  return     なし
+ */
+static void
+i2c_transfarconfig(I2C_Handle_t *hi2c, uint16_t DevAddress, uint8_t Size, uint32_t Mode, uint32_t Request)
+{
+	uint32_t tmpreg = 0;
+
+	/*
+	 * I2C CR2レジスタ再設定
+	 */
+	tmpreg = sil_rew_mem((uint32_t *)(hi2c->base+TOFF_I2C_CR2));
+	tmpreg &= (uint32_t)~((uint32_t)(I2C_CR2_SADD | I2C_CR2_NBYTES | I2C_CR2_RELOAD | I2C_CR2_AUTOEND | I2C_CR2_RD_WRN | I2C_CR2_START | I2C_CR2_STOP));
+	tmpreg |= (uint32_t)(((uint32_t)DevAddress & I2C_CR2_SADD) | (((uint32_t)Size << 16 ) & I2C_CR2_NBYTES) |
+            (uint32_t)Mode | (uint32_t)Request);
+	sil_wrw_mem((uint32_t *)(hi2c->base+TOFF_I2C_CR2), tmpreg);
+}
+
+/*
+ *  I2Cフラグを指定して設定待ち関数
+ *  parameter1 hi2c  I2Cハンドラへのポインタ
+ *  parameter2 Flag  待ちフラグ
+ *  parameter3 Timeout タイムアウト時間(ms)
+ *  return           正常終了 E_OK
+ */
+static ER
+i2c_waitsetflag(I2C_Handle_t *hi2c, uint32_t Flag, uint32_t Timeout)
+{
+	uint32_t tick = 0;
+
+	/*
+	 *  フラグ設定待ち
+	 */
+	while((sil_rew_mem((uint32_t *)(hi2c->base+TOFF_I2C_ISR)) & Flag) != Flag){
+		if(tick > Timeout){
+			hi2c->State= I2C_STATE_READY;
+			return E_TMOUT;
+		}
+		dly_tsk(1);
+		tick++;
+	}
+	return E_OK;
+}
+
+/*
+ *  I2C スレーブアドレスとメモリアドレス設定
+ *  parameter1 hi2c       I2Cハンドラへのポインタ
+ *  parameter2 DevAddress:スレーブアドレス
+ *  parameter3 MemAddress:メモリアドレス
+ *  parameter4 MemAddSize:メモリアドレスのサイズ
+ *  parameter5 Mode      :設定モード
+ *  parameter6 Timeout:タイムアウト時間(ms)
+ *  return     正常設定 E_OK
+ */
+static ER
+i2c_requestmemaddr(I2C_Handle_t *hi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint32_t Mode, uint32_t Timeout)
+{
+	ER err = E_OK;
+
+	i2c_transfarconfig(hi2c,DevAddress,MemAddSize, Mode, I2C_CR2_START);
+	/*
+	 * TXISフラグ設定待ち
+	 */
+	if((err = i2c_waitsetflag(hi2c, I2C_ISR_TXIS, Timeout)) != E_OK)
+		return err;
+
+	/*
+	 * メモリアドレス設定
+	 */
+	if(MemAddSize == I2C_MEMADD_SIZE_8BIT){	/* 8bit設定 */
+		sil_wrw_mem((uint32_t *)(hi2c->base+TOFF_I2C_TXDR), (MemAddress & 0xff));
+	}
+	else{									/* 16bit設定 */
+		/* メモリアドレスMSB設定 */
+		sil_wrw_mem((uint32_t *)(hi2c->base+TOFF_I2C_TXDR), ((MemAddress>>8) & 0xff));
+		if((err = i2c_waitsetflag(hi2c, I2C_ISR_TXIS, Timeout)) != E_OK)
+			return err;
+		/* メモリアドレスLSB設定 */
+		sil_wrw_mem((uint32_t *)(hi2c->base+TOFF_I2C_TXDR), (MemAddress & 0xff));
+	}
+	/*
+	 *  TC(R)フラグ設定待ち
+	 */
+	if(Mode == I2C_SOFTEND_MODE)
+		err = i2c_waitsetflag(hi2c, I2C_ISR_TC, Timeout);
+	else
+		err = i2c_waitsetflag(hi2c, I2C_ISR_TCR, Timeout);
+	return err;
+}
+
+/*
+ *  I2C転送待ち
+ *  parameter1 hi2c    I2Cハンドラへのポインタ
+ *  parameter2 Timeout:タイムアウト時間(ms)
+ */
+static ER
+i2c_transwait(I2C_Handle_t *hi2c, uint32_t Timeout)
+{
+	uint32_t tick = 0;
+
+	while(hi2c->State != I2C_STATE_READY){
+		if(tick >= Timeout)
+			return E_TMOUT;
+		if(hi2c->Init.semid != 0)
+			twai_sem(hi2c->Init.semid, 1);
+		else
+			dly_tsk(1);
+		tick++;
+	}
+	return E_OK;
+}
+
+/*
+ *  I2Cスレーブ受信
+ *  parameter1 hi2c   I2Cハンドラへのポインタ
+ *  parameter2 pData: 読み出しバッファへのポインタ
+ *  parameter3 Size:  読み出しサイズ
+ *  return            正常終了ならE_OK
+ */
+ER
+i2c_slaveread(I2C_Handle_t *hi2c, uint8_t *pData, uint16_t Size)
+{
+	ER err = E_OK;
+
+	if(pData == NULL || Size == 0)
+		return E_PAR;
+
+	/*
+	 *  読み出しロック
+	 */
+	if(hi2c->Init.semlock != 0)
+		wai_sem(hi2c->Init.semlock);
+
+	if(hi2c->State != I2C_STATE_READY){
+		if(hi2c->Init.semlock != 0)
+			sig_sem(hi2c->Init.semlock);
+		return E_OBJ;
+	}
+
+    hi2c->State = I2C_STATE_SLAVE_BUSY_RX;
+    hi2c->ErrorCode   = I2C_ERROR_NONE;
+
+    /*
+	 *  アドレス・アクノレッジ許可
+	 */
+	sil_andw_mem((uint32_t *)(hi2c->base+TOFF_I2C_CR2), I2C_CR2_NACK);
+
+    hi2c->pBuffPtr = pData;
+    hi2c->XferSize = Size;
+    hi2c->XferCount = Size;
+
+    /*
+	 *  読み出し割込み許可
+	 */
+	sil_orw_mem((uint32_t *)(hi2c->base+TOFF_I2C_CR1), (I2C_CR1_ERROR | I2C_CR1_ADDRIE | I2C_CR1_RXIE));
+	err = i2c_transwait(hi2c, 500);
+
+	/*
+	 *  ロック解除
+	 */
+	if(hi2c->Init.semlock != 0)
+		sig_sem(hi2c->Init.semlock);
+    return err;
+}
+
+/*
+ *  I2Cスレーブ送信
+ *  parameter1 hi2c   I2Cハンドラへのポインタ
+ *  parameter2 pData: 読み出しバッファへのポインタ
+ *  parameter3 Size:  読み出しサイズ
+ *  return            正常終了ならE_OK
+ */
+ER
+i2c_slavewrite(I2C_Handle_t *hi2c, uint8_t *pData, uint16_t Size)
+{
+	ER err = E_OK;
+
+	if(pData == NULL || Size == 0)
+		return E_PAR;
+
+	/*
+	 *  読み出しロック
+	 */
+	if(hi2c->Init.semlock != 0)
+		wai_sem(hi2c->Init.semlock);
+
+	if(hi2c->State != I2C_STATE_READY){
+		if(hi2c->Init.semlock != 0)
+			sig_sem(hi2c->Init.semlock);
+		return E_OBJ;
+	}
+
+    hi2c->State = I2C_STATE_SLAVE_BUSY_TX;
+    hi2c->ErrorCode   = I2C_ERROR_NONE;
+
+    /*
+	 *  アドレス・アクノレッジ許可
+	 */
+	sil_andw_mem((uint32_t *)(hi2c->base+TOFF_I2C_CR2), I2C_CR2_NACK);
+
+    hi2c->pBuffPtr = pData;
+    hi2c->XferSize = Size;
+    hi2c->XferCount = Size;
+
+    /*
+	 *  書き込み割込み許可
+	 */
+	sil_orw_mem((uint32_t *)(hi2c->base+TOFF_I2C_CR1), (I2C_CR1_ERROR | I2C_CR1_ADDRIE | I2C_CR1_TXIE));
+	err = i2c_transwait(hi2c, 500);
+
+	/*
+	 *  ロック解除
+	 */
+	if(hi2c->Init.semlock != 0)
+		sig_sem(hi2c->Init.semlock);
+    return err;
+}
+
+/*
+ *  I2Cマスターデータリード
+ *  parameter1 hi2c        I2Cハンドラへのポインタ
+ *  parameter2 DevAddress: スレーブアドレス
+ *  parameter3 MemAddress: メモリアドレス
+ *  parameter4 MemAddSize: メモリアドレスサイズ
+ *  parameter5 pData:      読み出しバッファへのポインタ
+ *  parameter6 Size:       読み出しサイズ
+ *  parameter7 Timeout:    タイムアウト時間(ms)
+ *  return                 正常終了ならE_OK
+ */
+ER
+i2c_memread(I2C_Handle_t *hi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint8_t *pData, uint16_t Size, uint32_t Timeout)
+{
+	ER err = E_OK;
+	uint32_t Mode = I2C_CR2_RELOAD;
+
+	if((pData == NULL) || (Size == 0))
+		return E_PAR;
+
+	/*
+	 *  読み出しロック
+	 */
+	if(hi2c->Init.semlock != 0)
+		wai_sem(hi2c->Init.semlock);
+
+	if(hi2c->State != I2C_STATE_READY
+		 || (sil_rew_mem((uint32_t *)(hi2c->base+TOFF_I2C_ISR)) & I2C_ISR_BUSY) == I2C_ISR_BUSY){
+		if(hi2c->Init.semlock != 0)
+			sig_sem(hi2c->Init.semlock);
+		return E_OBJ;
+	}
+
+	hi2c->State = I2C_STATE_MASTER_BUSY_RX;
+	hi2c->ErrorCode = I2C_ERROR_NONE;
+
+	hi2c->pBuffPtr = pData;
+	hi2c->XferCount = Size;
+	if(Size > 255)
+		hi2c->XferSize = 255;
+	else
+		hi2c->XferSize = Size;
+
+	/* スレーブアドレスと読み出しアドレスの設定 */
+	if(MemAddSize != 0){
+	    if((err = i2c_requestmemaddr(hi2c, DevAddress, MemAddress, MemAddSize, I2C_SOFTEND_MODE, Timeout)) != E_OK){
+			if(hi2c->Init.semlock != 0)
+				sig_sem(hi2c->Init.semlock);
+			return err;
+		}
+	}
+
+	/*
+	 *  アドレス書き込みフェーズ
+	 */
+    if( (hi2c->XferSize == 255) && (hi2c->XferSize < hi2c->XferCount) )
+		Mode = I2C_CR2_RELOAD;
+	else
+		Mode = I2C_CR2_AUTOEND;
+	i2c_transfarconfig(hi2c, DevAddress, hi2c->XferSize, Mode, (I2C_CR2_START | I2C_CR2_RD_WRN));
+
+    /*
+	 *  読み出し割込み許可
+	 */
+	sil_orw_mem((uint32_t *)(hi2c->base+TOFF_I2C_CR1), (I2C_CR1_ERROR | I2C_CR1_RXIE));
+	err = i2c_transwait(hi2c, Timeout);
+
+	/*
+	 *  ロック解除
+	 */
+	if(hi2c->Init.semlock != 0)
+		sig_sem(hi2c->Init.semlock);
+	return err;
+}
+
+/*
+ *  I2Cマスターデータライト
+ *  parameter1 hi2c        I2Cハンドラへのポインタ
+ *  parameter2 DevAddress: スレーブアドレス
+ *  parameter3 MemAddress: メモリアドレス
+ *  parameter4 MemAddSize: メモリアドレスサイズ
+ *  parameter5 pData:      書込みバッファへのポインタ
+ *  parameter6 Size:       書込みサイズ
+ *  parameter7 Timeout:    タイムアウト時間(ms)
+ */
+ER
+i2c_memwrite(I2C_Handle_t *hi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint8_t *pData, uint16_t Size, uint32_t Timeout)
+{
+	ER err = E_OK;
+	uint32_t Mode = I2C_CR2_RELOAD;
+	uint32_t Request = I2C_CR2_START /*I2C_GENERATE_START_WRITE*/;
+
+	if((pData == NULL) || (Size == 0))
+		return E_PAR;
+
+	/*
+	 *  書込みロック
+	 */
+	if(hi2c->Init.semlock != 0)
+		wai_sem(hi2c->Init.semlock);
+
+	if(hi2c->State != I2C_STATE_READY
+		  || (sil_rew_mem((uint32_t *)(hi2c->base+TOFF_I2C_ISR)) & I2C_ISR_BUSY) == I2C_ISR_BUSY){
+		if(hi2c->Init.semlock != 0)
+			sig_sem(hi2c->Init.semlock);
+		return E_OBJ;
+	}
+
+	hi2c->State = I2C_STATE_MASTER_BUSY_TX;
+	hi2c->ErrorCode = I2C_ERROR_NONE;
+
+	hi2c->pBuffPtr = pData;
+	hi2c->XferCount = Size;
+	if(Size > 255)
+		hi2c->XferSize = 255;
+	else
+		hi2c->XferSize = Size;
+
+	/* スレーブアドレスと書込みアドレスの設定 */
+	if(MemAddSize != 0){
+		Request = I2C_NO_STARTSTOP;
+		if((err = i2c_requestmemaddr(hi2c, DevAddress, MemAddress, MemAddSize, I2C_CR2_RELOAD, Timeout)) != E_OK){
+			if(hi2c->Init.semlock != 0)
+			sig_sem(hi2c->Init.semlock);
+			return err;
+		}
+	}
+
+	/*
+	 *  アドレス書き込みフェーズ
+	 */
+    if(hi2c->XferSize == 255 && hi2c->XferSize < hi2c->XferCount)
+		Mode = I2C_CR2_RELOAD;
+	else
+		Mode = I2C_CR2_AUTOEND;
+	i2c_transfarconfig(hi2c, DevAddress, hi2c->XferSize, Mode, Request);
+
+    /*
+	 *  書き込み割込み許可
+	 */
+	sil_orw_mem((uint32_t *)(hi2c->base+TOFF_I2C_CR1), (I2C_CR1_ERROR | I2C_CR1_TXIE));
+	err = i2c_transwait(hi2c, Timeout);
+
+	/*
+	 *  ロック解除
+	 */
+	if(hi2c->Init.semlock != 0)
+		sig_sem(hi2c->Init.semlock);
+	return err;
+}
+
+/*
+ *  I2Cレディチェック
+ *  parameter1 hi2c:       I2Cハンドラへのポインタ
+ *  parameter2 DevAddress: スレーブアドレス
+ *  parameter3 Trials:     トライアス値
+ *  parameter4 Timeout:    タイムアウト値
+ *  return                 レディならE_OK
+ */
+ER
+i2c_ready(I2C_Handle_t *hi2c, uint16_t DevAddress, uint32_t Trials, uint32_t Timeout)
+{
+	volatile uint32_t I2C_Trials = 0;
+	uint32_t tick = 0;
+	uint32_t tmp;
+
+	if(hi2c->State == I2C_STATE_READY){
+		if((sil_rew_mem((uint32_t *)(hi2c->base+TOFF_I2C_ISR)) & I2C_ISR_BUSY) != 0)
+			return E_OBJ;
+
+		/*
+		 *  アクセスロック
+		 */
+		if(hi2c->Init.semlock != 0)
+			wai_sem(hi2c->Init.semlock);
+
+		hi2c->State =     I2C_STATE_BUSY;
+		hi2c->ErrorCode = I2C_ERROR_NONE;
+
+		do{
+			/* スタート生成 */
+			if(hi2c->Init.AddressingMode == I2C_ADDRESSINGMODE_7BIT)
+				tmp = (((DevAddress & I2C_CR2_SADD) | I2C_CR2_START | I2C_CR2_AUTOEND) & ~I2C_CR2_RD_WRN);
+			else
+				tmp = (((DevAddress & I2C_CR2_SADD) | I2C_CR2_ADD10 | I2C_CR2_START) & ~I2C_CR2_RD_WRN);
+			sil_wrw_mem((uint32_t *)(hi2c->base+TOFF_I2C_CR2), tmp);
+
+		    /*
+			 *  ストップフラグまたはNACKフラグ待ち
+			 */
+			while((sil_rew_mem((uint32_t *)(hi2c->base+TOFF_I2C_ISR)) & (I2C_ISR_STOPF | I2C_ISR_NACKF)) == 0){
+				if(tick > Timeout){
+					/* Device is ready */
+					hi2c->State = I2C_STATE_READY;
+					/*
+					 *  ロック解除
+					 */
+					if(hi2c->Init.semlock != 0)
+						sig_sem(hi2c->Init.semlock);
+					return E_TMOUT;
+				}
+				dly_tsk(1);
+				tick++;
+			}
+
+			/* NACKフラグ状態 */
+			if((sil_rew_mem((uint32_t *)(hi2c->base+TOFF_I2C_ISR)) & I2C_ISR_NACKF) == 0){
+				/* ストップフラグリセット待ち */
+				if(i2c_waitsetflag(hi2c, I2C_ISR_STOPF, Timeout) != E_OK){
+					/*
+					 *  ロック解除
+					 */
+					if(hi2c->Init.semlock != 0)
+						sig_sem(hi2c->Init.semlock);
+					return E_TMOUT;
+				}
+
+				/* ストップフラグクリア */
+				sil_wrw_mem((uint32_t *)(hi2c->base+TOFF_I2C_ICR), I2C_ICR_STOPCF);
+
+				hi2c->State = I2C_STATE_READY;
+				/*
+				 *  ロック解除
+				 */
+				if(hi2c->Init.semlock != 0)
+					sig_sem(hi2c->Init.semlock);
+				return E_OK;
+			}
+			else{	/* ストップフラグ状態 */
+				/* ストップフラグリセット待ち */ 
+				if(i2c_waitsetflag(hi2c, I2C_ISR_STOPF, Timeout) != E_OK){
+					/*
+					 *  ロック解除
+					 */
+					if(hi2c->Init.semlock != 0)
+						sig_sem(hi2c->Init.semlock);
+					return E_TMOUT;
+				}
+
+				/* NACKフラグクリア */
+				sil_wrw_mem((uint32_t *)(hi2c->base+TOFF_I2C_ICR), I2C_ICR_NACKCF);
+
+				/* ストップフラグクリア */
+				sil_wrw_mem((uint32_t *)(hi2c->base+TOFF_I2C_ICR), I2C_ICR_STOPCF);
+			}
+
+			/* Check if the maximum allowed number of trials has been reached */
+			if(I2C_Trials++ == Trials){
+				/* ストップ生成 */
+				sil_orw_mem((uint32_t *)(hi2c->base+TOFF_I2C_CR2), I2C_CR2_STOP);
+
+				/* ストップフラグリセット待ち */ 
+				if(i2c_waitsetflag(hi2c, I2C_ISR_STOPF, Timeout) != E_OK){
+					/*
+					 *  ロック解除
+					 */
+					if(hi2c->Init.semlock != 0)
+						sig_sem(hi2c->Init.semlock);
+					return E_TMOUT;
+				}
+
+				/* ストップフラグクリア */
+				sil_wrw_mem((uint32_t *)(hi2c->base+TOFF_I2C_ICR), I2C_ICR_STOPCF);
+			}
+		}while(I2C_Trials < Trials);
+
+		hi2c->State = I2C_STATE_READY;
+		/*
+		 *  ロック解除
+		 */
+		if(hi2c->Init.semlock != 0)
+			sig_sem(hi2c->Init.semlock);
+	    return E_TMOUT;
+	}
+	else
+		return E_OBJ;
+}
+
+/*
+ *  I2Cマスター送信割込み
+ */
+static void
+i2c_mastertrans_isr(I2C_Handle_t *hi2c)
+{
+	uint32_t isr = sil_rew_mem((uint32_t *)(hi2c->base+TOFF_I2C_ISR));
+	uint16_t DevAddress;
+
+	if((isr & I2C_ISR_TXIS) != 0){	/* 送信中 */
+		sil_wrw_mem((uint32_t *)(hi2c->base+TOFF_I2C_TXDR), (*hi2c->pBuffPtr++));
+		hi2c->XferSize--;
+		hi2c->XferCount--;
+	}
+	else if((isr & I2C_ISR_TCR) != 0){	/* 送信再設定 */
+		if(hi2c->XferSize == 0 && hi2c->XferCount != 0){
+			DevAddress = sil_rew_mem((uint32_t *)(hi2c->base+TOFF_I2C_CR2)) & I2C_CR2_SADD;
+			if(hi2c->XferCount > 255){
+				i2c_transfarconfig(hi2c,DevAddress,255,  I2C_CR2_RELOAD, I2C_NO_STARTSTOP);
+				hi2c->XferSize = 255;
+			}
+			else{
+				i2c_transfarconfig(hi2c,DevAddress,hi2c->XferCount, I2C_CR2_AUTOEND, I2C_NO_STARTSTOP);
+				hi2c->XferSize = hi2c->XferCount;
+			}
+		}
+		else{	/* サイズエラー */
+			hi2c->ErrorCode |= I2C_ERROR_SIZE;
+			if(hi2c->errorcallback != NULL)
+				hi2c->errorcallback(hi2c);
+		}
+	}
+	else if((isr & I2C_ISR_TC) != 0){	/* 送信終了 */
+		if(hi2c->XferCount == 0){
+			sil_orw_mem((uint32_t *)(hi2c->base+TOFF_I2C_CR2), I2C_CR2_STOP);
+		}
+		else{	/* サイズエラー */
+			hi2c->ErrorCode |= I2C_ERROR_SIZE;
+			if(hi2c->errorcallback != NULL)
+				hi2c->errorcallback(hi2c);
+		}
+	}
+	else if((isr & I2C_ISR_STOPF) != 0){	/* ストップフラグ */
+		sil_andw_mem((uint32_t *)(hi2c->base+TOFF_I2C_CR1), (I2C_CR1_ERROR | I2C_CR1_TXIE));
+		/*
+		 *  ストップフラグクリア
+		 */
+		sil_wrw_mem((uint32_t *)(hi2c->base+TOFF_I2C_ICR), I2C_ICR_STOPCF);
+		/*
+		 * CR2をクリア
+		 */
+		sil_andw_mem((uint32_t *)(hi2c->base+TOFF_I2C_CR2), I2C_CR2_RESET);
+		hi2c->State = I2C_STATE_READY;
+		if(hi2c->writecallback != NULL)
+			hi2c->writecallback(hi2c);
+	}
+	else if((isr & I2C_ISR_NACKF) != 0){	/* NACKフラグ */
+		sil_wrw_mem((uint32_t *)(hi2c->base+TOFF_I2C_ICR), I2C_ICR_NACKCF);
+		hi2c->ErrorCode |= I2C_ERROR_AF;
+		if(hi2c->errorcallback != NULL)
+			hi2c->errorcallback(hi2c);
+	}
+}
+
+/*
+ *  I2Cマスター受信割込み
+ */
+static void
+i2c_masterreceiv_isr(I2C_Handle_t *hi2c)
+{
+	uint32_t isr = sil_rew_mem((uint32_t *)(hi2c->base+TOFF_I2C_ISR));
+	uint16_t DevAddress;
+
+	if((isr & I2C_ISR_RXNE) != 0){		/* 受信中 */
+		(*hi2c->pBuffPtr++) = sil_rew_mem((uint32_t *)(hi2c->base+TOFF_I2C_RXDR));
+		hi2c->XferSize--;
+		hi2c->XferCount--;
+	}
+	else if((isr & I2C_ISR_TCR) != 0){	/* 受信継続 */
+		if(hi2c->XferSize == 0 && hi2c->XferCount != 0){
+			DevAddress = sil_rew_mem((uint32_t *)(hi2c->base+TOFF_I2C_CR2)) & I2C_CR2_SADD;
+			if(hi2c->XferCount > 255){
+				i2c_transfarconfig(hi2c, DevAddress, 255, I2C_CR2_RELOAD, I2C_NO_STARTSTOP);
+				hi2c->XferSize = 255;
+			}
+			else{
+				i2c_transfarconfig(hi2c, DevAddress, hi2c->XferCount, I2C_CR2_AUTOEND, I2C_NO_STARTSTOP);
+				hi2c->XferSize = hi2c->XferCount;
+			}
+		}
+		else{	/* サイズエラー */
+			hi2c->ErrorCode |= I2C_ERROR_SIZE;
+			if(hi2c->errorcallback != NULL)
+				hi2c->errorcallback(hi2c);
+		}
+	}
+	else if((isr & I2C_ISR_TC) != 0){	/* 受信終了 */
+		if(hi2c->XferCount == 0){
+			sil_orw_mem((uint32_t *)(hi2c->base+TOFF_I2C_CR2), I2C_CR2_STOP);
+		}
+		else{
+			/* Wrong size Status regarding TCR flag event */
+			hi2c->ErrorCode |= I2C_ERROR_SIZE;
+			if(hi2c->errorcallback != NULL)
+				hi2c->errorcallback(hi2c);
+		}
+	}
+	else if((isr & I2C_ISR_STOPF) != 0){	/* ストップフラグ */
+		sil_andw_mem((uint32_t *)(hi2c->base+TOFF_I2C_CR1), (I2C_CR1_ERROR | I2C_CR1_RXIE));
+		/*
+		 *  ストップフラグクリア
+		 */
+		sil_wrw_mem((uint32_t *)(hi2c->base+TOFF_I2C_ICR), I2C_ICR_STOPCF);
+		/*
+		 * CR2をクリア
+		 */
+		sil_andw_mem((uint32_t *)(hi2c->base+TOFF_I2C_CR2), I2C_CR2_RESET);
+		hi2c->State = I2C_STATE_READY;
+		if(hi2c->readcallback != NULL)
+			hi2c->readcallback(hi2c);
+	}
+	else if((isr & I2C_ISR_NACKF) != 0){	/* NACKフラグ */
+		sil_wrw_mem((uint32_t *)(hi2c->base+TOFF_I2C_ICR), I2C_ICR_NACKCF);
+		hi2c->ErrorCode |= I2C_ERROR_AF;
+		if(hi2c->errorcallback != NULL)
+			hi2c->errorcallback(hi2c);
+	}
+}
+
+/*
+ *  I2Cスレーブ送信割込み
+ */
+static void
+i2c_slavesend_isr(I2C_Handle_t *hi2c)
+{
+	uint32_t isr = sil_rew_mem((uint32_t *)(hi2c->base+TOFF_I2C_ISR));
+
+	if((isr & I2C_ISR_NACKF) != 0){	/* NACKフラグ */
+		if(hi2c->XferCount == 0){	/* NACKをクリア */
+			sil_wrw_mem((uint32_t *)(hi2c->base+TOFF_I2C_ICR), I2C_ICR_NACKCF);
+		}
+		else{		/* データありでアクノレッジなしエラー */
+			sil_wrw_mem((uint32_t *)(hi2c->base+TOFF_I2C_ICR), I2C_ICR_NACKCF);
+			hi2c->ErrorCode |= I2C_ERROR_AF;
+			if(hi2c->errorcallback != NULL)
+				hi2c->errorcallback(hi2c);
+		}
+	}
+	else if((isr & I2C_ISR_ADDR) != 0){
+		/* Clear ADDR flag */
+		sil_wrw_mem((uint32_t *)(hi2c->base+TOFF_I2C_ICR), I2C_ICR_ADDRCF);
+	}
+	else if((isr & I2C_ISR_STOPF) != 0){	/* ストップフラグ */
+		sil_andw_mem((uint32_t *)(hi2c->base+TOFF_I2C_CR1), (I2C_CR1_ERROR | I2C_CR1_ADDRIE | I2C_CR1_RXIE | I2C_CR1_TXIE));
+	    /*
+		 *  アドレス・アクノレッジ禁止
+	 	 */
+		sil_orw_mem((uint32_t *)(hi2c->base+TOFF_I2C_CR2), I2C_CR2_NACK);
+		/*
+		 *  ストップフラグクリア
+		 */
+		sil_wrw_mem((uint32_t *)(hi2c->base+TOFF_I2C_ICR), I2C_ICR_STOPCF);
+		hi2c->State = I2C_STATE_READY;
+		if(hi2c->writecallback != NULL)
+			hi2c->writecallback(hi2c);
+	}
+	else if((isr & I2C_ISR_TXIS) != 0){	/* 送信状態 */
+		if(hi2c->XferCount > 0){
+			sil_wrw_mem((uint32_t *)(hi2c->base+TOFF_I2C_TXDR), (*hi2c->pBuffPtr++));
+			hi2c->XferCount--;
+		}
+	}
+}
+
+/*
+ *  I2Cスレーブ受信割込み
+ */
+static void
+i2c_slavereceiv_isr(I2C_Handle_t *hi2c)
+{
+	uint32_t isr = sil_rew_mem((uint32_t *)(hi2c->base+TOFF_I2C_ISR));
+
+	if((isr & I2C_ISR_NACKF) != 0){		/* NACKフラグ */
+		sil_wrw_mem((uint32_t *)(hi2c->base+TOFF_I2C_ICR), I2C_ICR_NACKCF);
+		hi2c->ErrorCode |= I2C_ERROR_AF;
+		if(hi2c->errorcallback != NULL)
+			hi2c->errorcallback(hi2c);
+	}
+	else if((isr & I2C_ISR_ADDR) != 0){	/* アドレスマッチ */
+	    sil_wrw_mem((uint32_t *)(hi2c->base+TOFF_I2C_ICR), I2C_ICR_ADDRCF);
+	}
+	else if((isr & I2C_ISR_RXNE) != 0){	/* 受信中 */
+		(*hi2c->pBuffPtr++) = sil_rew_mem((uint32_t *)(hi2c->base+TOFF_I2C_RXDR));
+		hi2c->XferSize--;
+		hi2c->XferCount--;
+	}
+	else if((isr & I2C_ISR_STOPF) != 0){/* ストップフラグ */
+		sil_andw_mem((uint32_t *)(hi2c->base+TOFF_I2C_CR1), (I2C_CR1_ERROR | I2C_CR1_ADDRIE | I2C_CR1_RXIE));
+	    /*
+		 *  アドレス・アクノレッジ禁止
+	 	 */
+		sil_orw_mem((uint32_t *)(hi2c->base+TOFF_I2C_CR2), I2C_CR2_NACK);
+		/*
+		 *  ストップフラグクリア
+		 */
+		sil_wrw_mem((uint32_t *)(hi2c->base+TOFF_I2C_ICR), I2C_ICR_STOPCF);
+		hi2c->State = I2C_STATE_READY;
+		if(hi2c->readcallback != NULL)
+			hi2c->readcallback(hi2c);
+	}
+}
+
+/*
+ *  I2C EV割込みハンドラ
+ */
+void
+i2c_ev_handler(I2C_Handle_t *hi2c)
+{
+	uint32_t cr1 = sil_rew_mem((uint32_t *)(hi2c->base+TOFF_I2C_CR1));
+	uint32_t isr = sil_rew_mem((uint32_t *)(hi2c->base+TOFF_I2C_ISR));
+
+	/*
+	 * I2C スレーブ送信モード
+	 */
+	if(((isr & (I2C_ISR_TXIS | I2C_ISR_TCR | I2C_ISR_TC | I2C_ISR_STOPF | I2C_ISR_NACKF | I2C_ISR_ADDR)) != 0) && ((cr1 & I2C_CR1_TRANS1) == I2C_CR1_TRANS1)){     
+		if(hi2c->State == I2C_STATE_SLAVE_BUSY_TX){
+			i2c_slavesend_isr(hi2c);
+		}
+	}
+	isr = sil_rew_mem((uint32_t *)(hi2c->base+TOFF_I2C_ISR));
+
+	/*
+	 *  I2C マスター送信モード
+	 */
+	if(((isr & (I2C_ISR_TXIS | I2C_ISR_TCR | I2C_ISR_TC | I2C_ISR_STOPF | I2C_ISR_NACKF)) != 0) && ((cr1 & I2C_CR1_TRANS2) == I2C_CR1_TRANS2)){
+		if(hi2c->State == I2C_STATE_MASTER_BUSY_TX){
+			i2c_mastertrans_isr(hi2c);
+		}
+	}
+	isr = sil_rew_mem((uint32_t *)(hi2c->base+TOFF_I2C_ISR));
+
+	/*
+	 *  I2C スレーブ受信モード
+	 */
+	if(((isr & (I2C_ISR_RXNE | I2C_ISR_TCR | I2C_ISR_TC | I2C_ISR_STOPF | I2C_ISR_NACKF | I2C_ISR_ADDR)) != 0) && ((cr1 & I2C_CR1_RECV1) == I2C_CR1_RECV1)){
+		if(hi2c->State == I2C_STATE_SLAVE_BUSY_RX){
+			i2c_slavereceiv_isr(hi2c);
+		}
+	} 
+	isr = sil_rew_mem((uint32_t *)(hi2c->base+TOFF_I2C_ISR));
+
+	/*
+	 *  I2C マスター受信モード
+	 */
+	if(((isr & (I2C_ISR_RXNE | I2C_ISR_TCR | I2C_ISR_TC | I2C_ISR_STOPF | I2C_ISR_NACKF)) != 0) && ((cr1 & I2C_CR1_RECV2) == I2C_CR1_RECV2)){
+		if(hi2c->State == I2C_STATE_MASTER_BUSY_RX){
+			i2c_masterreceiv_isr(hi2c);
+		}
+	}
+
+	if(hi2c->State == I2C_STATE_READY && hi2c->Init.semid != 0)
+		isig_sem(hi2c->Init.semid);
+}
+
+/*
+ *  I2C ER割込みハンドラ
+ */
+void
+i2c_er_handler(I2C_Handle_t *hi2c)
+{
+	uint32_t cr1 = sil_rew_mem((uint32_t *)(hi2c->base+TOFF_I2C_CR1));
+
+	/*
+	 *  I2C バスエラー
+	 */
+	if(((sil_rew_mem((uint32_t *)(hi2c->base+TOFF_I2C_ISR)) & I2C_ISR_BERR) != 0) && ((cr1 & I2C_CR1_ERRIE) != 0)){
+		hi2c->ErrorCode |= I2C_ERROR_BERR;
+		sil_wrw_mem((uint32_t *)(hi2c->base+TOFF_I2C_ICR), I2C_ICR_BERRCF);
+	}
+
+	/*
+	 *  I2C オーバーラン/アンダーラン
+	 */
+	if(((sil_rew_mem((uint32_t *)(hi2c->base+TOFF_I2C_ISR)) & I2C_ISR_OVR) != 0) && ((cr1 & I2C_CR1_ERRIE) != 0)){
+		hi2c->ErrorCode |= I2C_ERROR_OVR;
+		sil_wrw_mem((uint32_t *)(hi2c->base+TOFF_I2C_ICR), I2C_ICR_OVRCF);
+	}
+
+	/*
+	 *  I2C アービトレーション・ロス・エラー
+	 */
+	if(((sil_rew_mem((uint32_t *)(hi2c->base+TOFF_I2C_ISR)) & I2C_ISR_ARLO) != 0) && ((cr1 & I2C_CR1_ERRIE) != 0)){
+		hi2c->ErrorCode |= I2C_ERROR_ARLO;
+		sil_wrw_mem((uint32_t *)(hi2c->base+TOFF_I2C_ICR), I2C_ICR_ARLOCF);
+	}
+
+	/*
+	 *  エラーコールバック関数呼び出し
+	 */
+	if(hi2c->ErrorCode != I2C_ERROR_NONE){
+		hi2c->State = I2C_STATE_READY;
+		if(hi2c->errorcallback != NULL)
+			hi2c->errorcallback(hi2c);
+	}
+}
+
+/*
+ *  I2C EV割込みサービスルーチン
+ */
+void
+i2c_ev_isr(intptr_t exinf)
+{
+	i2c_ev_handler(&I2cHandle[INDEX_I2C((uint32_t)exinf)]);
+}
+
+/*
+ *  I2C ER割込みサービスルーチン
+ */
+void
+i2c_er_isr(intptr_t exinf)
+{
+	i2c_er_handler(&I2cHandle[INDEX_I2C((uint32_t)exinf)]);
+}
+
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/pdic/stm32f7xx/i2c.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/pdic/stm32f7xx/i2c.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/pdic/stm32f7xx/i2c.h	(revision 457)
@@ -0,0 +1,192 @@
+/*
+ *  TOPPERS/ASP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Advanced Standard Profile Kernel
+ * 
+ *  Copyright (C) 2008-2011 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ *  Copyright (C) 2015-2016 by TOPPERS PROJECT Educational Working Group.
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+/*
+ * 
+ *  STM32F7xx I2Cデバイスドライバの外部宣言
+ *
+ */
+
+#ifndef _I2C_H_
+#define _I2C_H_
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+
+/*
+ *  I2Cポート定義
+ */
+#define I2C1_PORTID             1
+#define I2C2_PORTID             2
+#define I2C3_PORTID             3
+#define I2C4_PORTID             4
+#define NUM_I2CPORT             4
+
+/*
+ *  I2Cアドレッシングモード
+ */
+#define I2C_ADDRESSINGMODE_7BIT  0x00000001
+#define I2C_ADDRESSINGMODE_10BIT 0x00000002
+
+/*
+ *  I2Cデュアルアドレッシングモード
+ */
+#define I2C_DUALADDRESS_DISABLE 0x00000000
+#define I2C_DUALADDRESS_ENABLE  I2C_OAR2_OA2EN
+
+/*
+ *  I2Cジェネラルコールアドレッシングモード
+ */
+#define I2C_GENERALCALL_DISABLE 0x00000000
+#define I2C_GENERALCALL_ENABLE  I2C_CR1_GCEN
+
+/*
+ *  I2Cノストラッチモード
+ */
+#define I2C_NOSTRETCH_DISABLE   0x00000000
+#define I2C_NOSTRETCH_ENABLE    I2C_CR1_NOSTRETCH
+
+/*
+ *  I2Cメモリアドレスモード
+ */
+#define I2C_MEMADD_SIZE_8BIT    0x00000001
+#define I2C_MEMADD_SIZE_16BIT   0x00000002
+
+/*
+ *  I2Cハードウェア設定構造体
+ */
+
+typedef struct _I2C_PortControlBlock{
+	uint32_t              base;
+	uint32_t              gioclockbase;
+	uint32_t              gioclockbit1;
+	uint32_t              gioclockbit2;
+	uint32_t              i2cclockbase;
+	uint32_t              i2cclockbit;
+	uint32_t              i2cresetbase;
+	uint32_t              i2cresetbit;
+
+	uint32_t              giobase1;
+	uint32_t              giobase2;
+	uint8_t               sclpin;
+	uint8_t               sclaf;
+	uint8_t               sdapin;
+	uint8_t               sdaaf;
+} I2C_PortControlBlock;
+
+/*
+ *  I2Cコンフュギュレーション構造体定義
+ */
+typedef struct
+{
+	uint32_t              Timing;			/* I2C I2C_TIMINGR値 */
+	uint32_t              OwnAddress1;		/* I2C 最初のデバイスの自分のアドレス */
+	uint32_t              AddressingMode;	/* I2C アドレッシングモード */
+	uint32_t              DualAddressMode;	/* I2C アドレスデュアルモード */
+	uint32_t              OwnAddress2;		/* I2C ２つ目のデバイスの自分のアドレス */
+	uint32_t              OwnAddress2Masks;	/* I2C ２つ目のデバイスアドレスのマスク値 */
+	uint32_t              GeneralCallMode;	/* I2C ジェネラル・コール・モード */
+	uint32_t              NoStretchMode;	/* I2C ノンストレッジモード */
+	int                   semid;			/* I2C 通信用セマフォ値 */
+	int                   semlock;			/* I2C ロックセマフォ値 */
+}I2C_Init_t;
+
+/*
+ *  I2C状態定義
+ */
+#define I2C_STATE_RESET     0x00		/* I2C リセット状態 */
+#define I2C_STATE_READY     0x01		/* I2C レディ状態 */
+#define I2C_STATE_BUSY      0x02		/* I2C ビジィ状態 */
+#define I2C_STATE_MASTER_BUSY_TX 0x12	/* I2C マスター送信中 */
+#define I2C_STATE_MASTER_BUSY_RX 0x22	/* I2C マスター受信中 */
+#define I2C_STATE_SLAVE_BUSY_TX  0x32	/* I2C スレーブ送信中 */
+#define I2C_STATE_SLAVE_BUSY_RX  0x42	/* I2C スレーブ受信中 */
+
+/*
+ *  I2Cエラー定義
+ */
+#define I2C_ERROR_NONE         0x00000000	/* No error              */
+#define I2C_ERROR_BERR         0x00000001	/* BERR error            */
+#define I2C_ERROR_ARLO         0x00000002	/* ARLO error            */
+#define I2C_ERROR_AF           0x00000004	/* ACKF error            */
+#define I2C_ERROR_OVR          0x00000008	/* OVR error             */
+#define I2C_ERROR_DMA          0x00000010	/* DMA transfer error    */
+#define I2C_ERROR_TIMEOUT      0x00000020	/* Timeout error         */
+#define I2C_ERROR_SIZE         0x00000040	/* Size Management error */
+
+/*
+ *  I2Cハンドラ定義
+ */
+typedef struct _I2C_Handle_t I2C_Handle_t;
+struct _I2C_Handle_t {
+	uint32_t                   base;		/* IPベースアドレス */
+	I2C_Init_t                 Init;		/* I2C初期設定パラメータ */
+	int                        i2cid;		/* I2C ID */
+	uint8_t                    *pBuffPtr;	/* I2C 通信バッファへのポインタ */
+	uint16_t                   XferSize;	/* I2C 通信サイズ */
+	volatile uint16_t          XferCount;	/* I2C 通信カウンタ */
+	void               (*writecallback)(I2C_Handle_t * hi2c);	/* 送信終了コールバック関数 */
+	void               (*readcallback)(I2C_Handle_t * hi2c);	/* 受信終了コールバック関数 */
+	void               (*errorcallback)(I2C_Handle_t * hi2c);	/* エラーコールバック関数 */
+	volatile uint32_t          State;		/* I2C 実行状態 */
+	volatile uint32_t          ErrorCode;	/* I2C Error code */
+};
+
+extern I2C_Handle_t *i2c_init(ID port, I2C_Init_t *pini);
+extern ER i2c_deinit (I2C_Handle_t *hi2c);
+extern ER i2c_slaveread(I2C_Handle_t *hi2c, uint8_t *pData, uint16_t Size);
+extern ER i2c_slavewrite(I2C_Handle_t *hi2c, uint8_t *pData, uint16_t Size);
+extern ER i2c_memread(I2C_Handle_t *hi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint8_t *pData, uint16_t Size, uint32_t Timeout);
+extern ER i2c_memwrite(I2C_Handle_t *hi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint8_t *pData, uint16_t Size, uint32_t Timeout);
+extern ER i2c_ready(I2C_Handle_t *pi2chandler, uint16_t DevAddress, uint32_t Trials, uint32_t Timeout);
+extern void i2c_ev_handler(I2C_Handle_t *pi2chandler);
+extern void i2c_er_handler(I2C_Handle_t *pi2chandler);
+extern void i2c_ev_isr(intptr_t exinf);
+extern void i2c_er_isr(intptr_t exinf);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif	/* _I2C_H_ */
+
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/pdic/stm32f7xx/ltdc.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/pdic/stm32f7xx/ltdc.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/pdic/stm32f7xx/ltdc.c	(revision 457)
@@ -0,0 +1,604 @@
+/*
+ *  TOPPERS/ASP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Advanced Standard Profile Kernel
+ * 
+ *  Copyright (C) 2008-2011 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ *  Copyright (C) 2015-2017 by TOPPERS PROJECT Educational Working Group.
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+/*
+ * STM32F746-LTDC用デバイスドライバ
+ */
+#include "kernel_impl.h"
+#include <t_syslog.h>
+#include <t_stdlib.h>
+#include <sil.h>
+#include <target_syssvc.h>
+#include "kernel_cfg.h"
+#include "device.h"
+#include "ltdc.h"
+
+
+/*
+ *  SIL関数のマクロ定義
+ */
+#define sil_orw_mem(a, b)		sil_wrw_mem((a), sil_rew_mem(a) | (b))
+#define sil_andw_mem(a, b)		sil_wrw_mem((a), sil_rew_mem(a) & ~(b))
+#define sil_modw_mem(a, b, c)	sil_wrw_mem((a), (sil_rew_mem(a) & (~b)) | (c))
+
+/*
+ *  AF 9セクション定義
+ */
+#define GPIO_AF9_CAN1           0x09	/* CAN1 Alternate Function mapping    */
+#define GPIO_AF9_CAN2           0x09	/* CAN2 Alternate Function mapping    */
+#define GPIO_AF9_TIM12          0x09	/* TIM12 Alternate Function mapping   */
+#define GPIO_AF9_TIM13          0x09	/* TIM13 Alternate Function mapping   */
+#define GPIO_AF9_TIM14          0x09	/* TIM14 Alternate Function mapping   */
+#define GPIO_AF9_QUADSPI        0x09	/* QUADSPI Alternate Function mapping */
+#define GPIO_AF9_LTDC           0x09	/* LCD-TFT Alternate Function mapping */
+
+/*
+ *  AF 14セクション定義
+ */
+#define GPIO_AF14_LTDC          0x0E	/* LCD-TFT alternate functionマップ値 */
+
+#define PLLSAI_TIMEOUT_VALUE   (100*1000)
+
+#define RCC_PLLSAICFGR_PLLSAIQ_POS    24
+#define RCC_PLLSAICFGR_PLLSAIP_POS    16
+
+#ifdef TOPPERS_STM32F7_DISCOVERY
+static const GPIO_Init_Table ltdc_gpio_table[] = {
+	{TADR_GPIOG_BASE, (GPIO_PIN_12) },
+	{TADR_GPIOE_BASE, (GPIO_PIN_4)  },
+	{TADR_GPIOI_BASE, (GPIO_PIN_8 | GPIO_PIN_9 | GPIO_PIN_10 | GPIO_PIN_13 | GPIO_PIN_14 | GPIO_PIN_15 ) },
+	{TADR_GPIOJ_BASE, (GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_3 | GPIO_PIN_4 | GPIO_PIN_5 | \
+			  GPIO_PIN_6 | GPIO_PIN_7 | GPIO_PIN_8 | GPIO_PIN_9 | GPIO_PIN_10 | GPIO_PIN_11 | \
+			  GPIO_PIN_13 | GPIO_PIN_14 | GPIO_PIN_15) },
+	{TADR_GPIOK_BASE, (GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_4 | GPIO_PIN_5 | GPIO_PIN_6 | GPIO_PIN_7) }
+};
+
+#define NUM_LTDC_GPIO_ITEM (sizeof(ltdc_gpio_table)/sizeof(GPIO_Init_Table))
+
+/*
+ *  LTDC GPIOの初期化
+ */
+static void
+ltdc_gpio_init(void)
+{
+	GPIO_Init_t GPIO_Init_Data;
+	int i, pin;
+	volatile uint32_t tmp;
+
+	/* LTDCクロック許可 */
+	sil_orw_mem((uint32_t *)(TADR_RCC_BASE+TOFF_RCC_APB2ENR), RCC_APB2ENR_LTDCEN);
+	tmp = sil_rew_mem((uint32_t *)(TADR_RCC_BASE+TOFF_RCC_APB2ENR));
+
+	/* LTDC用GPIOのクロック設定 */
+	sil_orw_mem((uint32_t *)(TADR_RCC_BASE+TOFF_RCC_AHB1ENR),
+			  RCC_AHB1ENR_GPIOEEN | RCC_AHB1ENR_GPIOGEN
+			| RCC_AHB1ENR_GPIOIEN | RCC_AHB1ENR_GPIOJEN
+			| RCC_AHB1ENR_GPIOKEN);
+	tmp = sil_rew_mem((uint32_t *)(TADR_RCC_BASE+TOFF_RCC_AHB1ENR));
+	(void)(tmp);
+
+	/* LTDC用GPIOの初期化パラメータ設定 */
+	GPIO_Init_Data.mode      = GPIO_MODE_AF;
+	GPIO_Init_Data.pull      = GPIO_NOPULL;
+	GPIO_Init_Data.otype     = GPIO_OTYPE_PP;
+	GPIO_Init_Data.speed     = GPIO_SPEED_FAST;
+	GPIO_Init_Data.alternate = GPIO_AF9_LTDC;
+
+	for(i = 0 ; i < NUM_LTDC_GPIO_ITEM ; i++){
+		for(pin = 0 ; pin < 16 ; pin++){
+			if((ltdc_gpio_table[i].pinmap & 1<<pin) != 0)
+				gpio_setup(ltdc_gpio_table[i].base, &GPIO_Init_Data, pin);
+		}
+		GPIO_Init_Data.alternate = GPIO_AF14_LTDC;
+	}
+
+	/* LCD表示用GPIOの設定 */
+	GPIO_Init_Data.mode      = GPIO_MODE_OUTPUT;
+	gpio_setup(TADR_GPIOI_BASE, &GPIO_Init_Data, PINPOSITION12);
+	gpio_setup(TADR_GPIOK_BASE, &GPIO_Init_Data, PINPOSITION3);
+
+	/* 表示許可LCD_DISPピンをアサート */
+	sil_wrw_mem((uint32_t *)(TADR_GPIOI_BASE+TOFF_GPIO_BSRR), GPIO_PIN_12);
+
+	/* バックライトLCD_BL_CTRLピンをアサート */
+	sil_wrw_mem((uint32_t *)(TADR_GPIOK_BASE+TOFF_GPIO_BSRR), GPIO_PIN_3);
+}
+#endif
+
+/*
+ *  LTDCのレイヤーのハードウェア初期設定する
+ *  parameter1 phandle   LTDCの初期設定構造体へのポインタ
+ *  parameter2 pLayerCfg レイヤーの初期設定構造体のポインタ
+ *  parameter3 LaerIdx   レイヤー番号
+ *  return               正常ならばE_OK
+ */
+static void
+LTDC_SetConfig(LTDC_Handle_t *phandle, LTDC_LayerCfg_t *pLayerCfg, uint32_t LayerIdx)
+{
+	uint32_t layer = TADR_LTDC_LAYER1+LayerIdx*LTDC_WINDOW_SIZE;
+	uint32_t bpcr  = sil_rew_mem((uint32_t *)(phandle->base+TOFF_LTDC_BPCR));
+	uint32_t tmp = 0;
+
+	/* 水平方向スタートストップ位置設定 */
+	tmp  = (pLayerCfg->WindowX1 + ((bpcr & LTDC_BPCR_AHBP) >> 16)) << 16;
+	tmp |= (pLayerCfg->WindowX0 + ((bpcr & LTDC_BPCR_AHBP) >> 16) + 1);
+	sil_wrw_mem((uint32_t *)(layer+TOFF_LTDCW_WHPCR), tmp);
+
+	/* 垂直方向スタートストップ位置設定 */
+	tmp  = (pLayerCfg->WindowY1 + (bpcr & LTDC_BPCR_AVBP)) << 16;
+	tmp |= (pLayerCfg->WindowY0 + (bpcr & LTDC_BPCR_AVBP) + 1);
+	sil_wrw_mem((uint32_t *)(layer+TOFF_LTDCW_WVPCR), tmp);
+
+	/* ピクセルフォーマットの指定 */
+	sil_modw_mem((uint32_t *)(layer+TOFF_LTDCW_PFCR), LTDC_PFCR_PF, pLayerCfg->PixelFormat);
+
+	/* デフォルトのカラー値を設定 */
+	tmp  = pLayerCfg->Backcolor.Blue;
+	tmp |= pLayerCfg->Backcolor.Green << 8;
+	tmp |= pLayerCfg->Backcolor.Red << 16;
+	tmp |= pLayerCfg->Alpha0 << 24;
+	sil_wrw_mem((uint32_t *)(layer+TOFF_LTDCW_DCCR), tmp);
+
+	/* アルファ値を設定 */
+	sil_wrw_mem((uint32_t *)(layer+TOFF_LTDCW_CACR), pLayerCfg->Alpha);
+
+	/* ブランディングファクターを設定 */
+	sil_wrw_mem((uint32_t *)(layer+TOFF_LTDCW_BFCR), (pLayerCfg->BlendingFactor1 | pLayerCfg->BlendingFactor2));
+
+	/* フレームバッファアドレスを設定 */
+	sil_wrw_mem((uint32_t *)(layer+TOFF_LTDCW_CFBAR), pLayerCfg->FBStartAdress);
+
+	/* バイト中のカラーフレームピッチの設定 */
+	if(pLayerCfg->PixelFormat == LTDC_PIXEL_FORMAT_ARGB8888)
+		tmp = 4;
+	else if (pLayerCfg->PixelFormat == LTDC_PIXEL_FORMAT_RGB888)
+		tmp = 3;
+	else if((pLayerCfg->PixelFormat == LTDC_PIXEL_FORMAT_ARGB4444) ||
+		(pLayerCfg->PixelFormat == LTDC_PIXEL_FORMAT_RGB565)   ||
+		  (pLayerCfg->PixelFormat == LTDC_PIXEL_FORMAT_ARGB1555) ||
+		    (pLayerCfg->PixelFormat == LTDC_PIXEL_FORMAT_AL88))
+		tmp = 2;
+	else
+		tmp = 1;
+	sil_wrw_mem((uint32_t *)(layer+TOFF_LTDCW_CFBLR), (((pLayerCfg->ImageWidth * tmp) << 16) | (((pLayerCfg->WindowX1 - pLayerCfg->WindowX0) * tmp)  + 3)));
+
+	/* フレームバッファライン数を設定 */
+	sil_wrw_mem((uint32_t *)(layer+TOFF_LTDCW_CFBLNR), pLayerCfg->ImageHeight);
+
+	/* LTDCレイヤーを許可 */
+	sil_orw_mem((uint32_t *)(layer+TOFF_LTDCW_CR), LTDC_CR_LEN);
+}
+
+/*
+ *  LTDCのウインドウのアルファ値を設定する
+ *  parameter1 phandle   LTDCの初期設定構造体へのポインタ
+ *  parameter2 Alpha     ウインドウアルファ値
+ *  parameter3 LaerIdx   レイヤー番号
+ *  return               正常ならばE_OK
+ */
+ER
+ltdc_setalpha(LTDC_Handle_t *phandle, uint32_t Alpha, uint32_t LayerIdx)
+{
+	LTDC_LayerCfg_t *pLayerCfg;
+
+	if(LayerIdx >= MAX_LAYER)
+		return E_PAR;
+	if(Alpha > 511)
+		return E_PAR;
+
+	/* レイヤーコンフィギュレーション領域のポインタ取得 */
+	pLayerCfg = &phandle->LayerCfg[LayerIdx];
+	/* ウインドウアルファ値設定 */
+	pLayerCfg->Alpha = Alpha;
+	/* LTDCレイヤー設定 */
+	LTDC_SetConfig(phandle, pLayerCfg, LayerIdx);
+	/* リロード */
+	sil_wrw_mem((uint32_t *)(phandle->base+TOFF_LTDC_SRCR), LTDC_SRCR_IMR);
+	return E_OK;
+}
+
+/*
+ *  LTDCのフレームバッファアドレスを設定する
+ *  parameter1 phandle   LTDCの初期設定構造体へのポインタ
+ *  parameter2 Alpha     アドレス値
+ *  parameter3 LaerIdx   レイヤー番号
+ *  return               正常ならばE_OK
+ */
+ER
+ltdc_setaddress(LTDC_Handle_t *phandle, uint32_t Address, uint32_t LayerIdx)
+{
+	LTDC_LayerCfg_t *pLayerCfg;
+
+	if(LayerIdx >= MAX_LAYER)
+		return E_PAR;
+
+	/* レイヤーコンフィギュレーション領域のポインタ取得 */
+	pLayerCfg = &phandle->LayerCfg[LayerIdx];
+	/* フレームバッファアドレス設定 */
+	pLayerCfg->FBStartAdress = Address;
+	/* LTDCレイヤー設定 */
+	LTDC_SetConfig(phandle, pLayerCfg, LayerIdx);
+	/* リロード */
+	sil_wrw_mem((uint32_t *)(phandle->base+TOFF_LTDC_SRCR), LTDC_SRCR_IMR);
+	return E_OK;
+}
+
+/*
+ *  LTDCのウインドウサイズ位置を設定する
+ *  parameter1 phandle   LTDCの初期設定構造体へのポインタ
+ *  parameter2 XSize     ウインドウXサイズ
+ *  parameter3 YSize     ウインドウYサイズ
+ *  parameter4 LaerIdx   レイヤー番号
+ *  return               正常ならばE_OK
+ */
+ER
+ltdc_setwindowsize(LTDC_Handle_t *phandle, uint32_t XSize, uint32_t YSize, uint32_t LayerIdx)
+{
+	LTDC_LayerCfg_t *pLayerCfg;
+
+	/* レイヤーコンフィギュレーション領域のポインタ取得 */
+	pLayerCfg = &phandle->LayerCfg[LayerIdx];
+	if(LayerIdx >= MAX_LAYER)
+		return E_PAR;
+	if(XSize > 8191 || YSize > 8191)
+		return E_PAR;
+
+	/* ウインドウX位置設定 */
+	pLayerCfg->WindowX0 = 0;
+	pLayerCfg->WindowX1 = XSize + pLayerCfg->WindowX0;
+	/* ウインドウY位置設定 */
+	pLayerCfg->WindowY0 = 0;
+	pLayerCfg->WindowY1 = YSize + pLayerCfg->WindowY0;
+	/* ウインドウXサイズ設定 */
+	pLayerCfg->ImageWidth = XSize;
+	/* ウインドウYサイズ */
+	pLayerCfg->ImageHeight = YSize;
+	/* LTDCレイヤー設定 */
+	LTDC_SetConfig(phandle, pLayerCfg, LayerIdx);
+	/* リロード */
+	sil_wrw_mem((uint32_t *)(phandle->base+TOFF_LTDC_SRCR), LTDC_SRCR_IMR);
+	return E_OK;
+}
+
+/*
+ *  LTDCのウインドウ位置を設定する
+ *  parameter1 phandle   LTDCの初期設定構造体へのポインタ
+ *  parameter2 X0        ウインドウX位置
+ *  parameter3 Y0        ウインドウY位置
+ *  parameter4 LaerIdx   レイヤー番号
+ *  return               正常ならばE_OK
+ */
+ER
+ltdc_setwindowposition(LTDC_Handle_t *phandle, uint32_t X0, uint32_t Y0, uint32_t LayerIdx)
+{
+	LTDC_LayerCfg_t *pLayerCfg;
+
+	/* レイヤーコンフィギュレーション領域のポインタ取得 */
+	pLayerCfg = &phandle->LayerCfg[LayerIdx];
+	if(LayerIdx >= MAX_LAYER)
+		return E_PAR;
+	if(X0 > 4095 || (X0+pLayerCfg->ImageWidth) > 65535)
+		return E_PAR;
+	if(Y0 > 4095 || (Y0+pLayerCfg->ImageHeight) > 65535)
+		return E_PAR;
+
+	/* ウインドウX位置設定 */
+	pLayerCfg->WindowX0 = X0;
+	pLayerCfg->WindowX1 = X0 + pLayerCfg->ImageWidth;
+	/* ウインドウY位置設定 */
+	pLayerCfg->WindowY0 = Y0;
+	pLayerCfg->WindowY1 = Y0 + pLayerCfg->ImageHeight;
+	/* LTDCレイヤー設定 */
+	LTDC_SetConfig(phandle, pLayerCfg, LayerIdx);
+	/* リロード */
+	sil_wrw_mem((uint32_t *)(phandle->base+TOFF_LTDC_SRCR), LTDC_SRCR_IMR);
+	return E_OK;
+}
+
+/*
+ *  カラーキーングの初期設定を行う
+ *  parameter1 phandle   LTDCの初期設定構造体へのポインタ
+ *  parameter2 RGBvalue  カラーキーイング番号
+ *  parameter3 LaerIdx   レイヤー番号
+ *  return               正常ならばE_OK
+ */
+ER
+ltdc_configcolorkeying(LTDC_Handle_t *phandle, uint32_t RGBValue, uint32_t LayerIdx)
+{
+	uint32_t layer = TADR_LTDC_LAYER1+LayerIdx*LTDC_WINDOW_SIZE;
+
+	if(LayerIdx >= MAX_LAYER)
+		return E_PAR;
+
+	/* カラーキーイング番号設定 */
+	sil_andw_mem((uint32_t *)(layer+TOFF_LTDCW_CKCR), (LTDC_CKCR_CKBLUE | LTDC_CKCR_CKGREEN | LTDC_CKCR_CKRED));
+	sil_wrw_mem((uint32_t *)(layer+TOFF_LTDCW_CKCR), RGBValue);
+	/* リロード */
+	sil_wrw_mem((uint32_t *)(phandle->base+TOFF_LTDC_SRCR), LTDC_SRCR_IMR);
+	return E_OK;
+}
+
+/*
+ *  カラーキーングを有効にする
+ *  parameter1 phandle   LTDCの初期設定構造体へのポインタ
+ *  parameter2 LaerIdx   レイヤー番号
+ *  return               正常ならばE_OK
+ */
+ER
+ltdc_enablecolorkeying(LTDC_Handle_t *phandle, uint32_t LayerIdx)
+{
+	if(LayerIdx >= MAX_LAYER)
+		return E_PAR;
+
+	/* COLKENビットをオン */
+	sil_orw_mem((uint32_t *)(TADR_LTDC_LAYER1+LayerIdx*LTDC_WINDOW_SIZE+TOFF_LTDCW_CR), LTDC_CR_COLKEN);
+	/* リロード */
+	sil_wrw_mem((uint32_t *)(phandle->base+TOFF_LTDC_SRCR), LTDC_SRCR_IMR);
+	return E_OK;
+}
+
+/*
+ *  カラーキーングを無効にする
+ *  parameter1 phandle   LTDCの初期設定構造体へのポインタ
+ *  parameter2 LaerIdx   レイヤー番号
+ *  return               正常ならばE_OK
+ */
+ER
+ltdc_disablecolorkeying(LTDC_Handle_t *phandle, uint32_t LayerIdx)
+{
+	if(LayerIdx >= MAX_LAYER)
+		return E_PAR;
+
+	/* COLKENビットをオフ */
+	sil_andw_mem((uint32_t *)(TADR_LTDC_LAYER1+LayerIdx*LTDC_WINDOW_SIZE+TOFF_LTDCW_CR), LTDC_CR_COLKEN);
+	/* リロード */
+	sil_wrw_mem((uint32_t *)(phandle->base+TOFF_LTDC_SRCR), LTDC_SRCR_IMR);
+	return E_OK;
+}
+
+/*
+ *  LTDCのレイヤー設定をおこなう
+ *  parameter1 phandle   LTDCの初期設定構造体へのポインタ
+ *  patameter2 pLayerCfg レイヤー設定構造体へのポインタ
+ *  parameter3 LaerIdx   レイヤー番号
+ *  return               正常ならばE_OK
+ */
+ER
+ltdc_configlayer(LTDC_Handle_t *phandle, LTDC_LayerCfg_t *pLayerCfg, uint32_t LayerIdx)
+{
+	if(LayerIdx >= MAX_LAYER)
+		return E_PAR;
+	/* レイヤーコンフィグレーション設定をコピー */
+	phandle->LayerCfg[LayerIdx] = *pLayerCfg;
+	/* LTDCレイヤー設定 */
+	LTDC_SetConfig(phandle, pLayerCfg, LayerIdx);
+	/* リロード */
+	sil_wrw_mem((uint32_t *)(phandle->base+TOFF_LTDC_SRCR), LTDC_SRCR_IMR);
+	return E_OK;
+}
+
+/*
+ *  LTDCラインイベント設定
+ *  parameter1 phandle   LTDCの初期設定構造体へのポインタ
+ *  patameter2 Line      ライン位置
+ *  return               正常ならばE_OK
+ */
+ER
+ltdc_lineevent(LTDC_Handle_t *phandle, uint32_t Line)
+{
+	/* Change LTDC peripheral state */
+	phandle->state = LTDC_STATE_BUSY;
+
+	/* Enable the Line interrupt */
+	sil_orw_mem((uint32_t *)(phandle->base+TOFF_LTDC_IER), LTDC_IER_LIE);
+
+	/* Sets the Line Interrupt position */
+	sil_wrw_mem((uint32_t *)(phandle->base+TOFF_LTDC_LIPCR), Line);
+
+	/* Change the LTDC state*/
+	phandle->state = LTDC_STATE_READY;
+	return E_OK;
+}
+
+/*
+ *  LTDCレジスタリロード設定
+ *  parameter1 phandle    LTDCの初期設定構造体へのポインタ
+ *  patameter2 ReloadType リロードタイプ
+ *  return                正常ならばE_OK
+ */
+ER
+ltdc_reload(LTDC_Handle_t *phandle, uint32_t ReloadType)
+{
+	/* Change LTDC peripheral state */
+	phandle->state = LTDC_STATE_BUSY;
+
+	/* Enable the Reload interrupt */  
+	sil_orw_mem((uint32_t *)(phandle->base+TOFF_LTDC_IER), LTDC_IER_RRIE);
+
+	/* Apply Reload type */
+	sil_wrw_mem((uint32_t *)(phandle->base+TOFF_LTDC_SRCR), ReloadType);
+
+	/* Change the LTDC state*/
+	phandle->state = LTDC_STATE_READY;
+	return E_OK;
+}
+
+/*
+ *  LTDCの初期設定を行う
+ *  parameter1 phandle  LTDCのハンドラへのポインタ
+ *  return              正常ならE_OK
+ */
+ER
+ltdc_init(LTDC_Handle_t *phandle)
+{
+	uint32_t timecount = 0;
+	uint32_t tmpreg0 = 0;
+	uint32_t tmpreg1 = 0;
+
+	/*
+	 * PLLSAIクロック停止
+     */
+	sil_andw_mem((uint32_t *)(TADR_RCC_BASE+TOFF_RCC_CR), RCC_CR_PLLSAION);
+
+    timecount = 0;
+	while((sil_rew_mem((uint32_t *)(TADR_RCC_BASE+TOFF_RCC_CR)) & (RCC_CR_PLLSAIRDY)) == RCC_CR_PLLSAIRDY){
+		if( timecount > PLLSAI_TIMEOUT_VALUE){
+			return E_TMOUT;	/* タイムアウト発生 */
+		}
+		sil_dly_nse(1000);
+		timecount++;
+	}
+
+	/*
+	 *  PLLSAIP/PLLSAIQ設定
+	 */
+	tmpreg0 = ((sil_rew_mem((uint32_t *)(TADR_RCC_BASE+TOFF_RCC_PLLSAICFGR)) & RCC_PLLSAICFGR_PLLSAIQ) >> RCC_PLLSAICFGR_PLLSAIQ_POS);
+	tmpreg1 = ((sil_rew_mem((uint32_t *)(TADR_RCC_BASE+TOFF_RCC_PLLSAICFGR)) & RCC_PLLSAICFGR_PLLSAIP) >> RCC_PLLSAICFGR_PLLSAIP_POS);
+	sil_wrw_mem((uint32_t *)(TADR_RCC_BASE+TOFF_RCC_PLLSAICFGR), (phandle->Init.pllsain << 6) | (tmpreg1 << 16) | (tmpreg0 << 24) | (phandle->Init.pllsair << 28));
+	sil_modw_mem((uint32_t *)(TADR_RCC_BASE+TOFF_RCC_DCKCFGR1), RCC_DCKCFGR1_PLLSAIDIVR, phandle->Init.saidivr);
+
+    /*
+	 *  PLLSAIクロック許可
+	 */
+	sil_orw_mem((uint32_t *)(TADR_RCC_BASE+TOFF_RCC_CR), RCC_CR_PLLSAION);
+
+    /*
+	 *  PLLSAIレディ待ち
+	 */
+	timecount = 0;
+	while((sil_rew_mem((uint32_t *)(TADR_RCC_BASE+TOFF_RCC_CR)) & (RCC_CR_PLLSAIRDY)) != RCC_CR_PLLSAIRDY){
+		if( timecount > PLLSAI_TIMEOUT_VALUE){
+			return E_TMOUT;	/* タイムアウト発生 */
+		}
+		sil_dly_nse(1000);
+		timecount++;
+	}
+
+#ifdef TOPPERS_STM32F7_DISCOVERY
+	/*
+	 *  LTDCの初期設定
+	 */
+	/* GPIO設定 */
+	ltdc_gpio_init();
+#endif
+
+	/* HS/VS/DE/PCの極性設定 */
+	sil_modw_mem((uint32_t *)(phandle->base+TOFF_LTDC_GCR), (LTDC_GCR_HSPOL | LTDC_GCR_VSPOL | LTDC_GCR_DEPOL | LTDC_GCR_PCPOL),
+				(phandle->Init.HSPolarity | phandle->Init.VSPolarity | phandle->Init.DEPolarity | phandle->Init.PCPolarity));
+	/* 同調サイズ設定 */
+	sil_modw_mem((uint32_t *)(phandle->base+TOFF_LTDC_SSCR), (LTDC_SSCR_VSH | LTDC_SSCR_HSW),
+				((phandle->Init.HorizontalSync << 16) | phandle->Init.VerticalSync));
+	/* バックポーチ設定 */
+	sil_modw_mem((uint32_t *)(phandle->base+TOFF_LTDC_BPCR), (LTDC_BPCR_AVBP | LTDC_BPCR_AHBP),
+				((phandle->Init.AccumulatedHBP << 16) | phandle->Init.AccumulatedVBP));
+	/* アクティブ幅設定 */
+	sil_modw_mem((uint32_t *)(phandle->base+TOFF_LTDC_AWCR), (LTDC_AWCR_AAH | LTDC_AWCR_AAW),
+				((phandle->Init.AccumulatedActiveW << 16) | phandle->Init.AccumulatedActiveH));
+	/* トータル幅設定 */
+	sil_modw_mem((uint32_t *)(phandle->base+TOFF_LTDC_TWCR), (LTDC_TWCR_TOTALH | LTDC_TWCR_TOTALW),
+				((phandle->Init.TotalWidth << 16) | phandle->Init.TotalHeigh));
+	/* バックグラウンドカラー設定 */
+	sil_modw_mem((uint32_t *)(phandle->base+TOFF_LTDC_BCCR), (LTDC_BCCR_BCBLUE | LTDC_BCCR_BCGREEN | LTDC_BCCR_BCRED),
+				((phandle->Init.Backcolor.Red << 16) | (phandle->Init.Backcolor.Green << 8) | phandle->Init.Backcolor.Blue));
+	/* エラーリセット */
+	sil_orw_mem((uint32_t *)(phandle->base+TOFF_LTDC_IER), (LTDC_IER_TERRIE | LTDC_IER_FUIE));
+	/* LTDC実行設定 */
+	sil_orw_mem((uint32_t *)(phandle->base+TOFF_LTDC_GCR), LTDC_GCR_LTDCEN);
+	phandle->state = LTDC_STATE_READY;
+	return E_OK;
+}
+
+/*
+ *  LTDC割込みハンドラ
+ */
+void
+ltdc_irqhandler(LTDC_Handle_t *phandle)
+{
+	uint32_t isr = sil_rew_mem((uint32_t *)(phandle->base+TOFF_LTDC_ISR));
+
+	/*
+	 *  割込みマスクとクリア
+	 */
+	sil_andw_mem((uint32_t *)(phandle->base+TOFF_LTDC_IER), isr);
+	sil_wrw_mem((uint32_t *)(phandle->base+TOFF_LTDC_ICR), isr);
+
+	/*
+	 *  転送エラーチェック
+	 */
+	if((isr & LTDC_ISR_TERRIF) != 0){
+		/* Update error code */
+		phandle->errorcode |= LTDC_ERROR_TE;
+		phandle->state      = LTDC_STATE_ERROR;
+		if(phandle->errorcallback != NULL)
+			phandle->errorcallback(phandle);
+	}
+
+	/*
+	 *  FIFOアンダーランエラーチェック
+	 */
+	if((isr & LTDC_ISR_FUIF) != 0){
+		/* Update error code */
+		phandle->errorcode |= LTDC_ERROR_FU;
+		phandle->state      = LTDC_STATE_ERROR;
+		if(phandle->errorcallback != NULL)
+			phandle->errorcallback(phandle);
+	}
+
+	/*
+	 *  ラインイベントチェック
+	 */
+	if((isr & LTDC_IER_LIE) != 0){
+		/* Change LTDC state */
+		phandle->state = LTDC_STATE_READY;
+		if(phandle->linecallback != NULL)
+			phandle->linecallback(phandle);
+	}
+
+	/*
+	 * リロードイベントチェック
+	 */
+	if((isr & LTDC_ISR_RRIF) != 0){
+		/* Change LTDC state */
+		phandle->state = LTDC_STATE_READY;
+		if(phandle->reloadcallback != NULL)
+			phandle->reloadcallback(phandle);
+	}
+}
+
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/pdic/stm32f7xx/ltdc.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/pdic/stm32f7xx/ltdc.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/pdic/stm32f7xx/ltdc.h	(revision 457)
@@ -0,0 +1,205 @@
+/*
+ *  TOPPERS/ASP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Advanced Standard Profile Kernel
+ * 
+ *  Copyright (C) 2008-2011 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ *  Copyright (C) 2015-2017 by TOPPERS PROJECT Educational Working Group.
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+/*
+ * STM32F746 LTDC用デバイスドライバの外部宣言
+ */
+
+#ifndef _LTDC_H_
+#define _LTDC_H_
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+#define MAX_LAYER  2
+
+/*
+ *  LTDC_HS_POLARITY LTDC HS POLARITY
+ */
+#define LTDC_HSPOLARITY_AL       0x00000000		/* Horizontal Synchronization is active low. */
+#define LTDC_HSPOLARITY_AH       LTDC_GCR_HSPOL	/* Horizontal Synchronization is active high. */
+
+/*
+ *  LTDC_VS_POLARITY LTDC VS POLARITY
+ */
+#define LTDC_VSPOLARITY_AL       0x00000000		/* Vertical Synchronization is active low. */
+#define LTDC_VSPOLARITY_AH       LTDC_GCR_VSPOL	/* Vertical Synchronization is active high. */
+
+/*
+ *  LTDC_DE_POLARITY LTDC DE POLARITY
+ */
+#define LTDC_DEPOLARITY_AL       0x00000000		/* Data Enable, is active low. */
+#define LTDC_DEPOLARITY_AH       LTDC_GCR_DEPOL	/* Data Enable, is active high. */
+
+/*
+ *  LTDC_BlendingFactor1 LTDC Blending Factor1
+ */
+#define LTDC_BLENDING_FACTOR1_CA    0x00000400	/* Blending factor : Cte Alpha */
+#define LTDC_BLENDING_FACTOR1_PAxCA 0x00000600	/* Blending factor : Cte Alpha x Pixel Alpha*/
+
+/*
+ *  LTDC_BlendingFactor2 LTDC Blending Factor2
+ */
+#define LTDC_BLENDING_FACTOR2_CA    0x00000005	/* Blending factor : Cte Alpha */
+#define LTDC_BLENDING_FACTOR2_PAxCA 0x00000007	/* Blending factor : Cte Alpha x Pixel Alpha*/
+
+/*
+ *  LTDC_PC_POLARITY LTDC PC POLARITY
+ */
+#define LTDC_PCPOLARITY_IPC      0x00000000		/* input pixel clock. */
+#define LTDC_PCPOLARITY_IIPC     LTDC_GCR_PCPOL	/* inverted input pixel clock. */
+
+/*
+ *  LTDCピクセルフォーマット定義
+ */
+#define LTDC_PIXEL_FORMAT_ARGB8888  0x00000000	/* ARGB8888 LTDC pixel format */
+#define LTDC_PIXEL_FORMAT_RGB888    0x00000001	/* RGB888 LTDC pixel format   */
+#define LTDC_PIXEL_FORMAT_RGB565    0x00000002	/* RGB565 LTDC pixel format   */
+#define LTDC_PIXEL_FORMAT_ARGB1555  0x00000003	/* ARGB1555 LTDC pixel format */
+#define LTDC_PIXEL_FORMAT_ARGB4444  0x00000004	/* ARGB4444 LTDC pixel format */
+#define LTDC_PIXEL_FORMAT_L8        0x00000005	/* L8 LTDC pixel format       */
+#define LTDC_PIXEL_FORMAT_AL44      0x00000006	/* AL44 LTDC pixel format     */
+#define LTDC_PIXEL_FORMAT_AL88      0x00000007	/* AL88 LTDC pixel format     */
+
+/*
+ *  LTDC状態定義
+ */
+#define LTDC_STATE_RESET         0x00000000		/* LTDC リセット状態 */
+#define LTDC_STATE_READY         0x00000001		/* LTDC レディ状態 */
+#define LTDC_STATE_BUSY          0x00000002		/* LTDC ビジィ状態 */
+#define LTDC_STATE_ERROR         0x00010000		/* LTDC エラー状態 */
+
+/*
+ *  LTDCエラー定義
+ */
+#define LTDC_ERROR_NONE          0x00000000		/* LTDC エラーなし */
+#define LTDC_ERROR_TE            0x00000001		/* LTDC 転送エラー */
+#define LTDC_ERROR_FU            0x00000002		/* LTDC FIFOアンダーラン */
+
+
+/*
+ *  LTDCカラー構造体定義
+ */
+typedef struct
+{
+	uint8_t	    Blue;			/* Configures the blue value. */
+	uint8_t     Green;			/* Configures the green value. */
+	uint8_t     Red;			/* Configures the red value. */
+	uint8_t     Reserved;		/* Reserved 0xFF */
+} Color_t;
+
+/*
+ *  LTDC初期化構造体定義
+ */
+typedef struct
+{
+	uint32_t    HSPolarity;		/* configures the horizontal synchronization polarity. */
+	uint32_t    VSPolarity;		/* configures the vertical synchronization polarity. */
+	uint32_t    DEPolarity;		/* configures the data enable polarity. */
+	uint32_t    PCPolarity;		/* configures the pixel clock polarity. */
+	uint32_t    HorizontalSync;	/* configures the number of Horizontal synchronization width. */
+	uint32_t    VerticalSync;	/* configures the number of Vertical synchronization height. */
+	uint32_t    AccumulatedHBP;	/* configures the accumulated horizontal back porch width. */
+	uint32_t    AccumulatedVBP;	/* configures the accumulated vertical back porch height. */
+	uint32_t    AccumulatedActiveW;	/* configures the accumulated active width. */
+	uint32_t    AccumulatedActiveH;	/* configures the accumulated active height. */
+	uint32_t    TotalWidth;		/* configures the total width. */
+	uint32_t    TotalHeigh;		/* configures the total height. */
+	Color_t     Backcolor;		/* configures the background color. */
+	uint32_t    pllsain;		/* configures the PLLSAIN */
+	uint32_t    pllsair;		/* configures the PLLSAIR */
+	uint32_t    saidivr;		/* configures the PLLSAIDIVR */
+} LTDC_Init_t;
+
+/*
+ *  LTDCレイヤー構造体定義
+ */
+typedef struct
+{
+	uint32_t    WindowX0;		/* Configures the Window Horizontal Start Position. */
+	uint32_t    WindowX1;		/* Configures the Window Horizontal Stop Position. */
+	uint32_t    WindowY0;		/* Configures the Window vertical Start Position. */
+	uint32_t    WindowY1;		/* Configures the Window vertical Stop Position. */
+	uint32_t    PixelFormat;	/* Specifies the pixel format. */
+	uint32_t    Alpha;			/* Specifies the constant alpha used for blending. */
+	uint32_t    Alpha0;			/* Configures the default alpha value. */
+	uint32_t    BlendingFactor1;/* Select the blending factor 1. */
+	uint32_t    BlendingFactor2;/* Select the blending factor 2. */
+	uint32_t    FBStartAdress;	/* Configures the color frame buffer address */
+	uint32_t    ImageWidth;		/* Configures the color frame buffer line length. */
+	uint32_t    ImageHeight;	/* Specifies the number of line in frame buffer. */
+	Color_t     Backcolor;		/* Configures the layer background color. */
+} LTDC_LayerCfg_t;
+
+/*
+ *  LTDCハンドラ構造体定義
+ */
+typedef struct _LTDC_Handle_t LTDC_Handle_t;
+struct _LTDC_Handle_t {
+	uint32_t           base;				/* LTDC ベースレジスタ */
+	LTDC_Init_t        Init;				/* LTDC parameters */
+	LTDC_LayerCfg_t LayerCfg[MAX_LAYER];	/* LTDC Layers parameters */
+	void               (*linecallback)(LTDC_Handle_t * hltdc);	/* ラインコールバック関数 */
+	void               (*reloadcallback)(LTDC_Handle_t * hltdc);/* リロードコールバック関数 */
+	void               (*errorcallback)(LTDC_Handle_t * hltdc);	/* エラーコールバック関数 */
+	volatile uint32_t  state;				/* LTDC 実行状態 */
+	volatile uint32_t  errorcode;			/* LTDC エラーコード */
+};
+
+extern ER ltdc_init(LTDC_Handle_t *phandle);
+extern ER ltdc_configlayer(LTDC_Handle_t *hltdc, LTDC_LayerCfg_t *pLayerCfg, uint32_t LayerIdx);
+extern ER ltdc_setwindowsize(LTDC_Handle_t *hltdc, uint32_t XSize, uint32_t YSize, uint32_t LayerIdx);
+extern ER ltdc_setwindowposition(LTDC_Handle_t *hltdc, uint32_t X0, uint32_t Y0, uint32_t LayerIdx);
+extern ER ltdc_setalpha(LTDC_Handle_t *hltdc, uint32_t Alpha, uint32_t LayerIdx);
+extern ER ltdc_setaddress(LTDC_Handle_t *hltdc, uint32_t Address, uint32_t LayerIdx);
+extern ER ltdc_configcolorkeying(LTDC_Handle_t *hltdc, uint32_t RGBValue, uint32_t LayerIdx);
+extern ER ltdc_enablecolorkeying(LTDC_Handle_t *hltdc, uint32_t LayerIdx);
+extern ER ltdc_disablecolorkeying(LTDC_Handle_t *hltdc, uint32_t LayerIdx);
+extern ER ltdc_lineevent(LTDC_Handle_t *phandle, uint32_t Line);
+extern ER ltdc_reload(LTDC_Handle_t *phandle, uint32_t ReloadType);
+extern void ltdc_irqhandler(LTDC_Handle_t *phandle);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/pdic/stm32f7xx/mcicmd.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/pdic/stm32f7xx/mcicmd.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/pdic/stm32f7xx/mcicmd.h	(revision 457)
@@ -0,0 +1,66 @@
+/*
+ *  TOPPERS/ASP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Advanced Standard Profile Kernel
+ * 
+ *  Copyright (C) 2008-2011 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ *  Copyright (C) 2015-2016 by TOPPERS PROJECT Educational Working Group.
+ * 
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+#ifndef _MCICMD_H_
+#define _MCICMD_H_
+
+#define MCIPCB              SDMMC_Handle_t
+#define MCIINFO             SDMMC_CardInfo_t
+
+#define SDDEV_BUS_WIDE_4B   SDMMC_BUS_WIDE_4B
+#define SDEV_INSWAIT_TIME   1500
+
+#define mci_ses_por         sdmmc_sense
+#define mci_opn_por         sdmmc_open
+#define mci_cls_por         sdmmc_close
+#define MciCheckCID         sdmmc_checkCID
+#define MciSetAddress       sdmmc_setaddress
+#define MciSendCID          sdmmc_sendCSD
+#define MciGetCardInfo      sdmmc_getcardinfo
+#define MciSelectCard       sdmmc_select_card
+#define MciConfiguration    sdmmc_configuration
+#define MciSetWideBus       sdmmc_set_widebus
+#define mci_red_blk         sdmmc_blockread
+#define mci_wri_blk         sdmmc_blockwrite
+#define mci_wai_trn         sdmmc_wait_transfar
+
+#include "sdmmc.h"
+
+#endif
+
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/pdic/stm32f7xx/phyreg.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/pdic/stm32f7xx/phyreg.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/pdic/stm32f7xx/phyreg.h	(revision 457)
@@ -0,0 +1,134 @@
+
+#ifndef _PHY_REG_
+#define _PHY_REG_
+
+#include <target_syssvc.h>
+
+/* Generic MII registers */
+#define MII_BMCR                0x00    /* Basic mode control register        */
+#define MII_BMSR                0x01    /* Basic mode status register         */
+#define MII_PHYSID1             0x02    /* PHYS ID 1                          */
+#define MII_PHYSID2             0x03    /* PHYS ID 2                          */
+#define MII_ADVERTISE           0x04    /* Advertisement control reg          */
+#define MII_LPA                 0x05    /* Link partner ability reg           */
+#define MII_EXPANSION           0x06    /* Expansion register                 */
+#define MII_CTRL1000            0x09    /* 1000BASE-T control                 */
+#define MII_STAT1000            0x0a    /* 1000BASE-T status                  */
+#define MII_ESTATUS             0x0f    /* Extended Status                    */
+#define MII_SPECIFICCR          0x10    /* Specific control register          */
+#define MII_DCOUNTER            0x12    /* Disconnect counter                 */
+#define MII_FCSCOUNTER          0x13    /* False carrier counter              */
+#define MII_NWAYTEST            0x14    /* N-way auto-neg test reg            */
+#define MII_RERRCOUNTER         0x15    /* Receive error counter              */
+#define MII_SREVISION           0x16    /* Silicon revision                   */
+#define MII_RESV1               0x17    /* Reserved...                        */
+#define MII_LBRERROR            0x18    /* Lpback, rx, bypass error           */
+#define MII_PHYADDR             0x19    /* PHY address                        */
+#define MII_RESV2               0x1a    /* Reserved...                        */
+#define MII_TPISTATUS           0x1b    /* TPI status for 10mbps              */
+#define MII_NCONFIG             0x1c    /* Network interface config           */
+
+/* Basic mode control register. */
+#define BMCR_RESV               0x003f  /* Unused...                          */
+#define BMCR_SPEED1000          0x0040  /* MSB of Speed (1000)                */
+#define BMCR_CTST               0x0080  /* Collision test                     */
+#define BMCR_FULLDPLX           0x0100  /* Full duplex                        */
+#define BMCR_ANRESTART          0x0200  /* Auto negotiation restart           */
+#define BMCR_ISOLATE            0x0400  /* Disconnect DP83840 from MII        */
+#define BMCR_PDOWN              0x0800  /* Powerdown the DP83840              */
+#define BMCR_ANENABLE           0x1000  /* Enable auto negotiation            */
+#define BMCR_SPEED100           0x2000  /* Select 100Mbps                     */
+#define BMCR_LOOPBACK           0x4000  /* TXD loopback bits                  */
+#define BMCR_RESET              0x8000  /* Reset the DP83840                  */
+#define BMCR_SPEED10            0x0000  /* Select 10Mbps                      */
+
+/* Basic mode status register. */
+#define BMSR_ERCAP              0x0001  /* Ext-reg capability                 */
+#define BMSR_JCD                0x0002  /* Jabber detected                    */
+#define BMSR_LSTATUS            0x0004  /* Link status                        */
+#define BMSR_ANEGCAPABLE        0x0008  /* Able to do auto-negotiation        */
+#define BMSR_RFAULT             0x0010  /* Remote fault detected              */
+#define BMSR_ANEGCOMPLETE       0x0020  /* Auto-negotiation complete          */
+#define BMSR_RESV               0x00c0  /* Unused...                          */
+#define BMSR_ESTATEN            0x0100	/* Extended Status in R15             */
+#define BMSR_100HALF2           0x0200  /* Can do 100BASE-T2 HDX              */
+#define BMSR_100FULL2           0x0400  /* Can do 100BASE-T2 FDX              */
+#define BMSR_10HALF             0x0800  /* Can do 10mbps, half-duplex         */
+#define BMSR_10FULL             0x1000  /* Can do 10mbps, full-duplex         */
+#define BMSR_100HALF            0x2000  /* Can do 100mbps, half-duplex        */
+#define BMSR_100FULL            0x4000  /* Can do 100mbps, full-duplex        */
+#define BMSR_100BASE4           0x8000  /* Can do 100mbps, 4k packets         */
+
+/* Advertisement control register. */
+#define ADVERTISE_SLCT          0x001f  /* Selector bits                      */
+#define ADVERTISE_CSMA          0x0001  /* Only selector supported            */
+#define ADVERTISE_10HALF        0x0020  /* Try for 10mbps half-duplex         */
+#define ADVERTISE_1000XFULL     0x0020  /* Try for 1000BASE-X full-duplex     */
+#define ADVERTISE_10FULL        0x0040  /* Try for 10mbps full-duplex         */
+#define ADVERTISE_1000XHALF     0x0040  /* Try for 1000BASE-X half-duplex     */
+#define ADVERTISE_100HALF       0x0080  /* Try for 100mbps half-duplex        */
+#define ADVERTISE_1000XPAUSE    0x0080  /* Try for 1000BASE-X pause           */
+#define ADVERTISE_100FULL       0x0100  /* Try for 100mbps full-duplex        */
+#define ADVERTISE_1000XPSE_ASYM 0x0100  /* Try for 1000BASE-X asym pause      */
+#define ADVERTISE_100BASE4      0x0200  /* Try for 100mbps 4k packets         */
+#define ADVERTISE_PAUSE_CAP     0x0400  /* Try for pause                      */
+#define ADVERTISE_PAUSE_ASYM    0x0800  /* Try for asymetric pause            */
+#define ADVERTISE_RESV          0x1000  /* Unused...                          */
+#define ADVERTISE_RFAULT        0x2000  /* Say we can detect faults           */
+#define ADVERTISE_LPACK         0x4000  /* Ack link partners response         */
+#define ADVERTISE_NPAGE         0x8000  /* Next page bit                      */
+
+/* 1000BASE-T Control register */
+#define ADVERTISE_1000FULL      0x0200  /* Advertise 1000BASE-T full duplex   */
+#define ADVERTISE_1000HALF      0x0100  /* Advertise 1000BASE-T half duplex   */
+
+/* Link partner ability register. */
+#define LPA_SLCT                0x001f  /* Same as advertise selector         */
+#define LPA_10HALF              0x0020  /* Can do 10mbps half-duplex          */
+#define LPA_1000XFULL           0x0020  /* Can do 1000BASE-X full-duplex      */
+#define LPA_10FULL              0x0040  /* Can do 10mbps full-duplex          */
+#define LPA_1000XHALF           0x0040  /* Can do 1000BASE-X half-duplex      */
+#define LPA_100HALF             0x0080  /* Can do 100mbps half-duplex         */
+#define LPA_1000XPAUSE          0x0080  /* Can do 1000BASE-X pause            */
+#define LPA_100FULL             0x0100  /* Can do 100mbps full-duplex         */
+#define LPA_1000XPAUSE_ASYM     0x0100  /* Can do 1000BASE-X pause asym       */
+#define LPA_100BASE4            0x0200  /* Can do 100mbps 4k packets          */
+#define LPA_PAUSE_CAP           0x0400  /* Can pause                          */
+#define LPA_PAUSE_ASYM          0x0800  /* Can pause asymetrically            */
+#define LPA_RESV                0x1000  /* Unused...                          */
+#define LPA_RFAULT              0x2000  /* Link partner faulted               */
+#define LPA_LPACK               0x4000  /* Link partner acked us              */
+#define LPA_NPAGE               0x8000  /* Next page bit                      */
+
+#define LPA_DUPLEX              (LPA_10FULL  | LPA_100FULL)
+#define LPA_100                 (LPA_100FULL | LPA_100HALF | LPA_100BASE4)
+
+/* 1000BASE-T Status register */
+#define LPA_1000LOCALRXOK       0x2000  /* Link partner local receiver status  */
+#define LPA_1000REMRXOK         0x1000  /* Link partner remote receiver status */
+#define LPA_1000FULL            0x0800  /* Link partner 1000BASE-T full duplex */
+#define LPA_1000HALF            0x0400  /* Link partner 1000BASE-T half duplex */
+
+/* Expansion register for auto-negotiation. */
+#define EXPANSION_NWAY          0x0001  /* Can do N-way auto-nego             */
+#define EXPANSION_LCWP          0x0002  /* Got new RX page code word          */
+#define EXPANSION_ENABLENPAGE   0x0004  /* This enables npage words           */
+#define EXPANSION_NPCAPABLE     0x0008  /* Link partner supports npage        */
+#define EXPANSION_MFAULTS       0x0010  /* Multiple faults detected           */
+#define EXPANSION_RESV          0xffe0  /* Unused...                          */
+
+#define ESTATUS_1000_TFULL      0x2000  /* Can do 1000BT Full                 */
+#define ESTATUS_1000_THALF      0x1000  /* Can do 1000BT Half                 */
+
+/* Specific control register */
+#define SPECIFICCR_CROSS_MASK   0x0060  /* Crossover mode mask                */
+#define SPECIFICCR_CROSS_MDI    0x0000  /* Manual MDI configuration           */
+#define SPECIFICCR_CROSS_MDIX   0x0020  /* Manual MDIX configuration          */
+#define SPECIFICCR_CROSS_AUTO   0x0060  /* Enable automatic crossover         */
+#define SPECIFICCR_INT_DISABLE  0x1000  /* Interrupt Disable                  */
+
+/* Externded PHY Specific Control Register */
+#define NWAYTEST_RGMII_RTC      0x0080  /* RGMII Receive Timing Control       */
+#define NWAYTEST_RGMII_TTC      0x0002  /* RGMII Transmit Timing Control      */
+
+#endif /* _PHY_REG_ */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/pdic/stm32f7xx/pinmode.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/pdic/stm32f7xx/pinmode.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/pdic/stm32f7xx/pinmode.c	(revision 457)
@@ -0,0 +1,171 @@
+/*
+ *  TOPPERS/ASP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Advanced Standard Profile Kernel
+ * 
+ *  Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
+ *                              Toyohashi Univ. of Technology, JAPAN
+ *  Copyright (C) 2004-2012 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ *  Copyright (C) 2015-2016 by TOPPERS PROJECT Educational Working Group.
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  $Id$
+ */
+
+/*
+ *  ARDUNO-PINドライバ
+ */
+
+#include <kernel.h>
+#include <t_syslog.h>
+#include <t_stdlib.h>
+#include <string.h>
+#include <target_syssvc.h>
+#include "syssvc/serial.h"
+#include "syssvc/syslog.h"
+#include "kernel_cfg.h"
+#include "device.h"
+#include "pinmode.h"
+
+#define sil_orw_mem(a, b)		sil_wrw_mem((a), sil_rew_mem(a) | (b))
+#define sil_andw_mem(a, b)		sil_wrw_mem((a), sil_rew_mem(a) & ~(b))
+#define sil_modw_mem(a, b, c)	sil_wrw_mem((a), (sil_rew_mem(a) & (~b)) | (c))
+
+
+static const Arduino_PortControlBlock Digital_Port[] = {
+#if defined(TOPPERS_STM32F7_DISCOVERY)
+  { (TADR_RCC_BASE+TOFF_RCC_AHB1ENR),  RCC_AHB1ENR_GPIOCEN, TADR_GPIOC_BASE, 7},	/* D0 */
+  { (TADR_RCC_BASE+TOFF_RCC_AHB1ENR),  RCC_AHB1ENR_GPIOCEN, TADR_GPIOC_BASE, 6},	/* D1 */
+  { (TADR_RCC_BASE+TOFF_RCC_AHB1ENR),  RCC_AHB1ENR_GPIOGEN, TADR_GPIOG_BASE, 6},	/* D2 */
+  { (TADR_RCC_BASE+TOFF_RCC_AHB1ENR),  RCC_AHB1ENR_GPIOBEN, TADR_GPIOB_BASE, 4},	/* D3 */
+  { (TADR_RCC_BASE+TOFF_RCC_AHB1ENR),  RCC_AHB1ENR_GPIOGEN, TADR_GPIOG_BASE, 7},	/* D4 */
+  { (TADR_RCC_BASE+TOFF_RCC_AHB1ENR),  RCC_AHB1ENR_GPIOAEN, TADR_GPIOA_BASE, 8},	/* D5 */
+  { (TADR_RCC_BASE+TOFF_RCC_AHB1ENR),  RCC_AHB1ENR_GPIOHEN, TADR_GPIOH_BASE, 6},	/* D6 */
+  { (TADR_RCC_BASE+TOFF_RCC_AHB1ENR),  RCC_AHB1ENR_GPIOIEN, TADR_GPIOI_BASE, 3},	/* D7 */
+  { (TADR_RCC_BASE+TOFF_RCC_AHB1ENR),  RCC_AHB1ENR_GPIOIEN, TADR_GPIOI_BASE, 2},	/* D8 */
+  { (TADR_RCC_BASE+TOFF_RCC_AHB1ENR),  RCC_AHB1ENR_GPIOAEN, TADR_GPIOA_BASE, 15},	/* D9 */
+  { (TADR_RCC_BASE+TOFF_RCC_AHB1ENR),  RCC_AHB1ENR_GPIOIEN, TADR_GPIOI_BASE, 0},	/* D10 */
+  { (TADR_RCC_BASE+TOFF_RCC_AHB1ENR),  RCC_AHB1ENR_GPIOBEN, TADR_GPIOB_BASE, 15},	/* D11 */
+  { (TADR_RCC_BASE+TOFF_RCC_AHB1ENR),  RCC_AHB1ENR_GPIOBEN, TADR_GPIOB_BASE, 14},	/* D12 */
+  { (TADR_RCC_BASE+TOFF_RCC_AHB1ENR),  RCC_AHB1ENR_GPIOIEN, TADR_GPIOI_BASE, 1}		/* D13 */
+#else	/* TOPPERS_STM32F746_NUCLEO144 TOPPERS_STM32F767_NUCLEO144 */
+  { (TADR_RCC_BASE+TOFF_RCC_AHB1ENR),  RCC_AHB1ENR_GPIOGEN, TADR_GPIOG_BASE, 9},	/* D0 */
+  { (TADR_RCC_BASE+TOFF_RCC_AHB1ENR),  RCC_AHB1ENR_GPIOGEN, TADR_GPIOG_BASE, 14},	/* D1 */
+  { (TADR_RCC_BASE+TOFF_RCC_AHB1ENR),  RCC_AHB1ENR_GPIOFEN, TADR_GPIOF_BASE, 15},	/* D2 */
+  { (TADR_RCC_BASE+TOFF_RCC_AHB1ENR),  RCC_AHB1ENR_GPIOEEN, TADR_GPIOE_BASE, 13},	/* D3 */
+  { (TADR_RCC_BASE+TOFF_RCC_AHB1ENR),  RCC_AHB1ENR_GPIOFEN, TADR_GPIOF_BASE, 14},	/* D4 */
+  { (TADR_RCC_BASE+TOFF_RCC_AHB1ENR),  RCC_AHB1ENR_GPIOEEN, TADR_GPIOE_BASE, 11},	/* D5 */
+  { (TADR_RCC_BASE+TOFF_RCC_AHB1ENR),  RCC_AHB1ENR_GPIOEEN, TADR_GPIOE_BASE, 9},	/* D6 */
+  { (TADR_RCC_BASE+TOFF_RCC_AHB1ENR),  RCC_AHB1ENR_GPIOFEN, TADR_GPIOF_BASE, 13},	/* D7 */
+  { (TADR_RCC_BASE+TOFF_RCC_AHB1ENR),  RCC_AHB1ENR_GPIOFEN, TADR_GPIOF_BASE, 12},	/* D8 */
+  { (TADR_RCC_BASE+TOFF_RCC_AHB1ENR),  RCC_AHB1ENR_GPIODEN, TADR_GPIOD_BASE, 15},	/* D9 */
+  { (TADR_RCC_BASE+TOFF_RCC_AHB1ENR),  RCC_AHB1ENR_GPIODEN, TADR_GPIOD_BASE, 14},	/* D10 */
+  { (TADR_RCC_BASE+TOFF_RCC_AHB1ENR),  RCC_AHB1ENR_GPIOAEN, TADR_GPIOA_BASE, 7},	/* D11 */
+  { (TADR_RCC_BASE+TOFF_RCC_AHB1ENR),  RCC_AHB1ENR_GPIOAEN, TADR_GPIOA_BASE, 6},	/* D12 */
+  { (TADR_RCC_BASE+TOFF_RCC_AHB1ENR),  RCC_AHB1ENR_GPIOAEN, TADR_GPIOA_BASE, 5}		/* D13 */
+#endif
+};
+
+#define NUM_DIGITAL_PORT (sizeof(Digital_Port)/sizeof(Arduino_PortControlBlock))
+
+static const Arduino_PortControlBlock Analog_Port[] = {
+#if defined(TOPPERS_STM32F7_DISCOVERY)
+  { (TADR_RCC_BASE+TOFF_RCC_AHB1ENR),  RCC_AHB1ENR_GPIOAEN, TADR_GPIOA_BASE, 0},	/* A0 */
+  { (TADR_RCC_BASE+TOFF_RCC_AHB1ENR),  RCC_AHB1ENR_GPIOFEN, TADR_GPIOF_BASE, 10},	/* A1 */
+  { (TADR_RCC_BASE+TOFF_RCC_AHB1ENR),  RCC_AHB1ENR_GPIOFEN, TADR_GPIOF_BASE, 9},	/* A2 */
+  { (TADR_RCC_BASE+TOFF_RCC_AHB1ENR),  RCC_AHB1ENR_GPIOFEN, TADR_GPIOF_BASE, 8},	/* A3 */
+  { (TADR_RCC_BASE+TOFF_RCC_AHB1ENR),  RCC_AHB1ENR_GPIOFEN, TADR_GPIOF_BASE, 7},	/* A4 */
+  { (TADR_RCC_BASE+TOFF_RCC_AHB1ENR),  RCC_AHB1ENR_GPIOFEN, TADR_GPIOF_BASE, 6}		/* A5 */
+#else	/* TOPPERS_STM32F746_NUCLEO144 TOPPERS_STM32F767_NUCLEO144 */
+  { (TADR_RCC_BASE+TOFF_RCC_AHB1ENR),  RCC_AHB1ENR_GPIOAEN, TADR_GPIOA_BASE, 3},	/* A0 */
+  { (TADR_RCC_BASE+TOFF_RCC_AHB1ENR),  RCC_AHB1ENR_GPIOCEN, TADR_GPIOC_BASE, 0},	/* A1 */
+  { (TADR_RCC_BASE+TOFF_RCC_AHB1ENR),  RCC_AHB1ENR_GPIOCEN, TADR_GPIOC_BASE, 3},	/* A2 */
+  { (TADR_RCC_BASE+TOFF_RCC_AHB1ENR),  RCC_AHB1ENR_GPIOFEN, TADR_GPIOF_BASE, 3},	/* A3 */
+  { (TADR_RCC_BASE+TOFF_RCC_AHB1ENR),  RCC_AHB1ENR_GPIOFEN, TADR_GPIOF_BASE, 5},	/* A4 */
+  { (TADR_RCC_BASE+TOFF_RCC_AHB1ENR),  RCC_AHB1ENR_GPIOFEN, TADR_GPIOF_BASE, 10}	/* A5 */
+#endif
+};
+
+#define NUM_ANALOG_PORT (sizeof(Analog_Port)/sizeof(Arduino_PortControlBlock))
+
+void
+pinClock(uint8_t no)
+{
+	const Arduino_PortControlBlock *ppcb = &Digital_Port[no];
+
+	if(no >= NUM_DIGITAL_PORT)
+		return;
+	sil_orw_mem((uint32_t *)ppcb->gioclockbase, ppcb->gioclockbit);
+}
+
+void
+digitalWrite(uint8_t no, int sw)
+{
+	const Arduino_PortControlBlock *ppcb = &Digital_Port[no];
+
+	if(no >= NUM_DIGITAL_PORT)
+		return;
+	if(sw == 0)
+		sil_wrw_mem((uint32_t *)(ppcb->giobase+TOFF_GPIO_BSRR), (1<<(ppcb->giopin+16)));
+	else
+		sil_wrw_mem((uint32_t *)(ppcb->giobase+TOFF_GPIO_BSRR), (1<<(ppcb->giopin)));
+}
+
+int
+digitalRead(uint8_t no)
+{
+	const Arduino_PortControlBlock *ppcb = &Digital_Port[no];
+ 	int sw;
+
+	if(no >= NUM_DIGITAL_PORT)
+		return 0;
+	sw = sil_rew_mem((uint32_t *)(ppcb->giobase+TOFF_GPIO_IDR));
+	sw = (sw>>(ppcb->giopin)) & 1;
+	return sw;
+}
+
+Arduino_PortControlBlock*
+getGpioTable(uint8_t mode, uint8_t no)
+{
+	if(mode == ANALOG_PIN){
+		if(no >= NUM_ANALOG_PORT)
+			return NULL;
+		return (Arduino_PortControlBlock*)&Analog_Port[no];
+	}
+	else{
+		if(no >= NUM_DIGITAL_PORT)
+			return NULL;
+		return (Arduino_PortControlBlock*)&Digital_Port[no];
+	}
+}
+
+
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/pdic/stm32f7xx/pinmode.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/pdic/stm32f7xx/pinmode.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/pdic/stm32f7xx/pinmode.h	(revision 457)
@@ -0,0 +1,91 @@
+/*
+ *  TOPPERS/ASP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Advanced Standard Profile Kernel
+ *
+ *  Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
+ *                              Toyohashi Univ. of Technology, JAPAN
+ *  Copyright (C) 2004-2010 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ *  Copyright (C) 2015-2016 by TOPPERS PROJECT Educational Working Group.
+ *
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ *
+ *  $Id$
+ */
+
+/*
+ *	ARDUNO-PINドライバのヘッダファイル
+ */
+
+#ifndef _PINMODE_H_
+#define _PINMODE_H_
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+#include "device.h"
+
+
+#define DIGITAL_PIN     0
+#define ANALOG_PIN      1
+
+
+#ifndef TOPPERS_MACRO_ONLY
+
+/*
+ *  ARDUINOO PIN 構造体
+ */
+typedef struct _Arduino_PortControlBlock{
+	uint32_t    gioclockbase;
+	uint32_t    gioclockbit;
+	uint32_t    giobase;
+	uint8_t     giopin;
+} Arduino_PortControlBlock;
+
+/*
+ *  関数のプロトタイプ宣言
+ */
+
+extern void pinClock(uint8_t no);
+extern int  digitalRead(uint8_t no);
+extern void digitalWrite(uint8_t no, int sw);
+extern Arduino_PortControlBlock *getGpioTable(uint8_t mode, uint8_t no);
+
+
+#endif /* TOPPERS_MACRO_ONLY */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif	/* _PINMODE_H_ */
+
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/pdic/stm32f7xx/qspi.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/pdic/stm32f7xx/qspi.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/pdic/stm32f7xx/qspi.c	(revision 457)
@@ -0,0 +1,1103 @@
+/*
+ *  TOPPERS/ASP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Advanced Standard Profile Kernel
+ * 
+ *  Copyright (C) 2008-2011 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ *  Copyright (C) 2015-2018 by TOPPERS PROJECT Educational Working Group.
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+/*
+ * 
+ *  QSPIドライバ関数群
+ *
+ */
+#include "kernel_impl.h"
+#include <t_syslog.h>
+#include <t_stdlib.h>
+#include <string.h>
+#include <sil.h>
+#include <target_syssvc.h>
+#include "device.h"
+#include "qspi.h"
+
+#define sil_orw_mem(a, b)		sil_wrw_mem((a), sil_rew_mem(a) | (b))
+#define sil_andw_mem(a, b)		sil_wrw_mem((a), sil_rew_mem(a) & ~(b))
+#define sil_modw_mem(a, b, c)	sil_wrw_mem((a), (sil_rew_mem(a) & (~b)) | (c))
+
+#define MIN(a, b) ((a) > (b) ? (b) : (a))
+
+/*
+ *  QSPIポートIDから管理ブロックを取り出すためのマクロ
+ */
+#define INDEX_QSPI(qspiid)      ((uint_t)((qspiid) - 1))
+
+#define GPIO_AF9_QUADSPI        ((uint8_t)0x09)  /* QUADSPI Alternate Function mapping */
+#define GPIO_AF10_QUADSPI       ((uint8_t)0x0A)  /* QUADSPI Alternate Function mapping */
+
+#ifndef QSPI_WRITE_SIZE
+#define QSPI_WRITE_SIZE         256
+#endif
+#define QPSI_TIMEOUT_DEFAULT_VALUE (5000)	/* 5sec */
+
+/*
+ *  QSPI通信レジスタ設定ファンクション定義
+ */
+#define QSPI_FUNCTIONAL_MODE_INDIRECT_WRITE 0x00000000			/* Indirect write mode*/
+#define QSPI_FUNCTIONAL_MODE_INDIRECT_READ  QUADSPI_CCR_FMODE_0	/* Indirect read mode*/
+#define QSPI_FUNCTIONAL_MODE_AUTO_POLLING   QUADSPI_CCR_FMODE_1	/* Automatic polling mode*/
+#define QSPI_FUNCTIONAL_MODE_MEMORY_MAPPED  QUADSPI_CCR_FMODE	/* Memory-mapped mode*/
+
+static const QSPI_PortControlBlock qspi_pcb[NUM_QSPIPORT] = {
+  {	TADR_QSPI_R_BASE, (TADR_RCC_BASE+TOFF_RCC_AHB1ENR),
+	RCC_AHB1ENR_GPIOBEN, TADR_GPIOB_BASE, 6,  GPIO_AF10_QUADSPI,
+	RCC_AHB1ENR_GPIOBEN, TADR_GPIOB_BASE, 2,  GPIO_AF9_QUADSPI,
+	RCC_AHB1ENR_GPIOCEN, TADR_GPIOC_BASE, 9,  GPIO_AF9_QUADSPI,
+	RCC_AHB1ENR_GPIOCEN, TADR_GPIOC_BASE, 10, GPIO_AF9_QUADSPI,
+	RCC_AHB1ENR_GPIOEEN, TADR_GPIOE_BASE, 2,  GPIO_AF9_QUADSPI,
+	RCC_AHB1ENR_GPIODEN, TADR_GPIOD_BASE, 13, GPIO_AF9_QUADSPI
+  }
+};
+
+QSPI_Handle_t QSPIHandle[NUM_QSPIPORT];
+
+/*
+ *  QSPIフラグセット待ち関数
+ *  parameter1 hi2c    I2Cハンドラへのポインタ
+ *  parameter2 flag    フラグ値
+ *  parameter3 result  最終フラグ値
+ *  parameter4 timeout タイムアウト値(ms)
+ *  parameter5 ptimout タイムアウト値設定領域
+ *  result     E_OKで正常終了
+ */
+static ER
+qspi_waitflag(QSPI_Handle_t *hqspi, uint32_t flag, uint32_t result, uint32_t timeout, uint32_t *ptimeout)
+{
+	uint32_t tick = 0;
+
+	while((sil_rew_mem((uint32_t *)(hqspi->base+TOFF_QUADSPI_SR)) & flag) != result){
+		if(tick > timeout){
+			hqspi->errorcode |= QSPI_ERROR_TIMEOUT;
+			return E_TMOUT;
+		}
+		tick++;
+		dly_tsk(1);
+	}
+	*ptimeout -= tick;
+	return E_OK;
+}
+
+/*
+ *  QSPIイベント待ち
+ *  parameter1 hi2c    I2Cハンドラへのポインタ
+ *  parameter2 status  変化待ちステータス値
+ *  parameter3 timeout タイムアウト値(ms)
+ *  result     E_OKで正常終了
+ */
+static ER
+qspi_eventwait(QSPI_Handle_t *hqspi, uint32_t status, uint32_t timeout)
+{
+	uint32_t tick = 0;
+
+	while(hqspi->status == status){
+		if(hqspi->semid != 0)
+			twai_sem(hqspi->semid, 1);
+		else
+			dly_tsk(1);
+		tick++;
+		if(tick > timeout)
+			return E_TMOUT;
+	}
+	if(hqspi->errorcode != QSPI_ERROR_NONE)
+		return E_SYS;
+	else
+		return E_OK;
+}
+
+/*
+ *  QSPIデバイスのリセット
+ *  parameter1 hqspi QSPIハンドラへのポインタ
+ *  return           正常終了時、E_OK
+ */
+static ER
+qspi_reinit(QSPI_Handle_t *hqspi)
+{
+	QSPI_Init_t *pini = &hqspi->Init;
+	ER       ercd = E_OK;
+	uint32_t timeout = hqspi->timeout;
+	uint32_t i, temp;
+
+	/*
+	 *  FIFOスレッシュホールド設定
+	 */
+	sil_modw_mem((uint32_t *)(hqspi->base+TOFF_QUADSPI_CR), QUADSPI_CR_FTHRES, (pini->fifothreshold - 1) << 8);
+
+	/*
+	 *  Ready待ち
+	 */
+	if((ercd = qspi_waitflag(hqspi, QUADSPI_SR_BUSY, 0, timeout, &timeout)) != E_OK)
+		return ercd;
+
+	/*
+	 *  QSPI CR設定
+	 */
+	temp  = sil_rew_mem((uint32_t *)(hqspi->base+TOFF_QUADSPI_CR));
+	temp &= ~(QUADSPI_CR_PRESCALER | QUADSPI_CR_SSHIFT);
+	temp |= (pini->clockprescaler << 24) | pini->sampleshift;
+#ifdef QUADSPI_CR_FSEL
+	temp &= ~QUADSPI_CR_FSEL;
+	temp |= pini->flashid;
+#endif
+#ifdef QUADSPI_CR_DFM
+	temp &= ~QUADSPI_CR_DFM;
+	temp |= pini->dualflash;
+#endif
+	sil_wrw_mem((uint32_t *)(hqspi->base+TOFF_QUADSPI_CR), temp);
+
+	/*
+	 *  QSPI DCR設定
+	 */
+
+	for(i = 0 ; i < 32 ; i++){
+		if((pini->device_size & (1<<i)) != 0)
+			break;
+	}
+	temp  = sil_rew_mem((uint32_t *)(hqspi->base+TOFF_QUADSPI_DCR));
+	temp &= ~(QUADSPI_DCR_FSIZE | QUADSPI_DCR_CSHT | QUADSPI_DCR_CKMODE);
+	temp |= (i << 16) | pini->chipselecthightime | pini->clockmode;
+	sil_wrw_mem((uint32_t *)(hqspi->base+TOFF_QUADSPI_DCR), temp);
+
+
+    /*
+	 *  QSPIイネーブル
+	 */
+	sil_orw_mem((uint32_t *)(hqspi->base+TOFF_QUADSPI_CR), QUADSPI_CR_EN);
+
+    /*
+	 *  QSPIハンドラ設定
+	 */
+    hqspi->errorcode = QSPI_ERROR_NONE;
+	hqspi->status    = QSPI_STATUS_READY;
+	return E_OK;
+}
+
+
+/*
+ *  QSPI通信レジスタ設定
+ *  parameter1 hqspi QSPIハンドラへのポインタ
+ *  parameter2 cmd   コマンドタイプ構造体へのポインタ
+ *  parameter3 fmode ファンクションモード
+ *  return           正常終了時、E_OK
+ */
+static void
+qspi_config(QSPI_Handle_t *hqspi, QSPI_Command_t *cmd, uint32_t fmode)
+{
+	QSPI_Init_t *pini = &hqspi->Init;
+	uint32_t instruction, alternatebytessize;
+	if(cmd->DataMode != QSPI_DATA_NONE && fmode != QSPI_FUNCTIONAL_MODE_MEMORY_MAPPED){
+		/*
+		 *  DLRレジスタ設定
+		 */
+		sil_wrw_mem((uint32_t *)(hqspi->base+TOFF_QUADSPI_DLR), (cmd->NbData - 1));
+	}
+
+	if(cmd->InstructionMode != QSPI_INSTRUCTION_NONE)
+		instruction = cmd->Instruction;
+	else
+		instruction = 0;
+
+	if(cmd->AlternateByteMode != QSPI_ALTERNATE_BYTES_NONE)
+		alternatebytessize = cmd->AlternateBytesSize;
+	else
+		alternatebytessize = 0;
+
+	/*
+	 *  ABRレジスタ設定
+	 */
+	sil_wrw_mem((uint32_t *)(hqspi->base+TOFF_QUADSPI_ABR), cmd->AlternateBytes);
+
+	if (cmd->AddressMode != QSPI_ADDRESS_NONE){
+		/*
+		 *  アドレス設定あり、CCR設定
+		 */
+		sil_wrw_mem((uint32_t *)(hqspi->base+TOFF_QUADSPI_CCR), 
+								(pini->ddrmode | pini->ddrholdhalfcycle | pini->sioomode | 
+								 cmd->DataMode | (cmd->DummyCycles << 18) | 
+								 alternatebytessize | cmd->AlternateByteMode | 
+								 cmd->AddressSize | cmd->AddressMode | cmd->InstructionMode | 
+								 instruction | fmode));
+		if (fmode != QSPI_FUNCTIONAL_MODE_MEMORY_MAPPED){
+			/* Configure QSPI: AR register with address value */
+			sil_wrw_mem((uint32_t *)(hqspi->base+TOFF_QUADSPI_AR), cmd->Address);
+		}
+	}
+	else{
+		/*
+		 *  アドレス設定なし、CCR設定
+		 */
+		sil_wrw_mem((uint32_t *)(hqspi->base+TOFF_QUADSPI_CCR), 
+								(pini->ddrmode | pini->ddrholdhalfcycle | pini->sioomode | 
+								 cmd->DataMode | (cmd->DummyCycles << 18) | 
+								 alternatebytessize | cmd->AlternateByteMode | 
+								 cmd->AddressMode | cmd->InstructionMode | 
+								 instruction | fmode));
+	}
+}
+
+/*
+ *  QSPIコマンド送信
+ *  parameter1 hqspi   QSPIハンドラへのポインタ
+ *  parameter2 cmd     コマンドタイプ構造体へのポインタ
+ *  parameter3 timeout タイムアウト時間(ms)
+ *  return           正常終了時、E_OK
+ */
+ER
+qspi_command(QSPI_Handle_t *hqspi, QSPI_Command_t *cmd, uint32_t Timeout)
+{
+	ER ercd = E_OK;
+
+	if(cmd->InstructionMode != QSPI_INSTRUCTION_NONE){
+		if(cmd->Instruction > 0xff)
+			return E_PAR;
+	}
+	if(cmd->AddressMode != QSPI_ADDRESS_NONE){
+		if((cmd->AddressSize & ~QUADSPI_CCR_ADSIZE) != 0)
+			return E_PAR;
+	}
+	if(cmd->AlternateByteMode != QSPI_ALTERNATE_BYTES_NONE){
+		if((cmd->AlternateBytesSize & ~QUADSPI_CCR_ABSIZE) != 0)
+			return E_PAR;
+	}
+	if(cmd->DummyCycles > 31)
+		return E_PAR;
+	if((cmd->DataMode & ~QUADSPI_CCR_DMODE) != 0)
+		return E_PAR;
+
+	if(hqspi->status != QSPI_STATUS_READY)
+		return E_OBJ;
+
+	/*
+	 *  ステータス、エラー初期化
+	 */
+	hqspi->errorcode = QSPI_ERROR_NONE;
+	hqspi->status = QSPI_STATUS_BUSY;
+
+	/*
+	 *  READY待ち
+	 */
+	ercd = qspi_waitflag(hqspi, QUADSPI_SR_BUSY, 0, Timeout, &Timeout);
+	if(ercd != E_OK)
+		return ercd;
+
+	if(cmd->DataMode == QSPI_DATA_NONE){
+		/*
+		 *  データ転送なしなら、割込みクリア
+		 */
+		sil_wrw_mem((uint32_t *)(hqspi->base+TOFF_QUADSPI_FCR), (QUADSPI_FCR_CTEF | QUADSPI_FCR_CTCF));
+	}
+
+	/*
+	 *  書込みモード通信レジスタ設定
+	 */
+	qspi_config(hqspi, cmd, QSPI_FUNCTIONAL_MODE_INDIRECT_WRITE);
+
+	if(cmd->DataMode == QSPI_DATA_NONE){
+        /*
+		 *  TCF設定待ち
+		 */
+		ercd = qspi_waitflag(hqspi, QUADSPI_SR_TCF, QUADSPI_SR_TCF, Timeout, &Timeout);
+
+		if(ercd == E_OK){
+			sil_orw_mem((uint32_t *)(hqspi->base+TOFF_QUADSPI_CR), (QUADSPI_CR_TEIE | QUADSPI_CR_TCIE));
+
+			/*
+			 *  QSPI割込み終了待ち
+			 */
+			ercd = qspi_eventwait(hqspi, QSPI_STATUS_BUSY, Timeout);
+		}
+	}
+	else	/* データ転送ありなら、正常終了 */
+		hqspi->status = QSPI_STATUS_READY;
+	return ercd;
+}
+
+/*
+ *  QSPIオートマチック ポーリングモード設定
+ *  parameter1 hqspi   QSPIハンドラへのポインタ
+ *  parameter2 cmd     コマンドタイプ構造体へのポインタ
+ *  parameter3 cfg     オートマチック ポーリングモード設定
+ *  parameter4 timeout タイムアウト時間(ms)
+ *  return           正常終了時、E_OK
+ */
+ER
+qspi_autopolling(QSPI_Handle_t *hqspi, QSPI_Command_t *cmd, QSPI_AutoPolling_t *cfg, uint32_t Timeout)
+{
+	ER ercd = E_OK;
+
+	if((cmd->InstructionMode & ~QUADSPI_CCR_IMODE) != 0)
+		return E_PAR;
+	if(cmd->InstructionMode != QSPI_INSTRUCTION_NONE && cmd->Instruction > 0xFF)
+		return E_PAR;
+	if((cmd->AddressMode & ~QUADSPI_CCR_ADMODE) != 0)
+		return E_PAR;
+	if(cmd->AddressMode != QSPI_ADDRESS_NONE && (cmd->AddressSize & ~QUADSPI_CCR_ADSIZE) != 0)
+		return E_PAR;
+	if((cmd->AlternateByteMode & ~QUADSPI_CCR_ABMODE) != 0)
+		return E_PAR;
+	if(cmd->AlternateByteMode != QSPI_ALTERNATE_BYTES_NONE && (cmd->AlternateBytesSize & ~QUADSPI_CCR_ABSIZE) != 0)
+		return E_PAR;
+	if(cmd->DummyCycles > 31)
+		return E_PAR;
+	if((cmd->DataMode & ~QUADSPI_CCR_DMODE) != 0)
+		return E_PAR;
+
+	if(cfg->Interval > QUADSPI_PIR_INTERVAL)
+		return E_PAR;
+	if(cfg->StatusBytesSize < 1 || cfg->StatusBytesSize > 4)
+		return E_PAR;
+	if((cfg->MatchMode & ~QUADSPI_CR_PMM) != 0)
+		return E_PAR;
+	if((cfg->AutomaticStop & ~QUADSPI_CR_APMS) != 0)
+		return E_PAR;
+
+	if(hqspi->status != QSPI_STATUS_READY)
+		return E_OBJ;
+
+	/*
+	 *  ステータス、エラー初期化
+	 */
+	hqspi->errorcode = QSPI_ERROR_NONE;
+	hqspi->status = QSPI_STATUS_BUSY_AP;
+
+	/*
+	 *  READY待ち
+	 */
+	ercd = qspi_waitflag(hqspi, QUADSPI_SR_BUSY, 0, Timeout, &Timeout);
+	if(ercd != E_OK)
+		return ercd;
+
+	/*
+	 *  PSMARレジスタ MATCH値セット
+	 */
+	sil_wrw_mem((uint32_t *)(hqspi->base+TOFF_QUADSPI_PSMAR), cfg->Match);
+
+	/*
+	 *  PSMKRレジスタ MASK値セット
+	 */
+	sil_wrw_mem((uint32_t *)(hqspi->base+TOFF_QUADSPI_PSMKR), cfg->Mask);
+
+	/*
+	 *  PIRレジスタ インターバル値セット
+	 */
+	sil_wrw_mem((uint32_t *)(hqspi->base+TOFF_QUADSPI_PIR), cfg->Interval);
+
+	/*
+	 *  CRレジスタ MATCHモード、オートマチックストップモードセット
+	 */
+	sil_modw_mem((uint32_t *)(hqspi->base+TOFF_QUADSPI_CR), (QUADSPI_CR_PMM | QUADSPI_CR_APMS), (cfg->MatchMode | cfg->AutomaticStop));
+
+	/* Clear interrupt */
+	sil_wrw_mem((uint32_t *)(hqspi->base+TOFF_QUADSPI_FCR), (QUADSPI_FCR_CTEF | QUADSPI_FCR_CSMF));
+
+	/*
+	 *  ステータスバイトサイズをセット
+	 */
+	cmd->NbData = cfg->StatusBytesSize;
+
+	/*
+	 *  通信用レジスタを設定
+	 */
+	qspi_config(hqspi, cmd, QSPI_FUNCTIONAL_MODE_AUTO_POLLING);
+
+	/*
+	 *  割込み設定と割込み待ち
+	 */
+	sil_orw_mem((uint32_t *)(hqspi->base+TOFF_QUADSPI_CR), (QUADSPI_CR_TEIE | QUADSPI_CR_SMIE));
+	return qspi_eventwait(hqspi, QSPI_STATUS_BUSY_AP, Timeout);
+}
+
+/*
+ *  QSPIデータ送信
+ *  parameter1 hqspi   QSPIハンドラへのポインタ
+ *  parameter2 pData   送信データ領域へのポインタ
+ *  parameter3 timeout タイムアウト時間(ms)
+ *  return           正常終了時、E_OK
+ */
+ER
+qspi_transmit(QSPI_Handle_t *hqspi, uint32_t *pData, uint32_t Timeout)
+{
+	if(pData == NULL)
+		return E_PAR;
+	if(hqspi->status != QSPI_STATUS_READY)
+		return E_OBJ;
+
+	/*
+	 *  ステータス、エラー初期化
+	 */
+	hqspi->errorcode = QSPI_ERROR_NONE;
+	hqspi->status = QSPI_STATUS_BUSY_TX;
+
+	/*
+	 *  通信データ設定
+	 */
+	hqspi->XferCount = 0;
+	hqspi->XferSize = sil_rew_mem((uint32_t *)(hqspi->base+TOFF_QUADSPI_DLR)) + 1;
+	hqspi->pBuffPtr = pData;
+
+	/*
+	 *  CCRレジスタにインダイレクト書込み設定
+	 */
+	sil_modw_mem((uint32_t *)(hqspi->base+TOFF_QUADSPI_CCR), QUADSPI_CCR_FMODE, QSPI_FUNCTIONAL_MODE_INDIRECT_WRITE);
+
+	/*
+	 *  割込みクリアと割込み設定
+	 */
+	sil_wrw_mem((uint32_t *)(hqspi->base+TOFF_QUADSPI_FCR), (QUADSPI_FCR_CTEF | QUADSPI_FCR_CTCF));
+	sil_orw_mem((uint32_t *)(hqspi->base+TOFF_QUADSPI_CR), (QUADSPI_CR_TEIE | QUADSPI_CR_FTIE | QUADSPI_CR_TCIE));
+
+	return qspi_eventwait(hqspi, QSPI_STATUS_BUSY_TX, Timeout);
+}
+
+/*
+ *  QSPIデータ受信
+ *  parameter1 hqspi   QSPIハンドラへのポインタ
+ *  parameter2 pData   受信データ領域へのポインタ
+ *  parameter3 timeout タイムアウト時間(ms)
+ *  return           正常終了時、E_OK
+ */
+ER
+qspi_receive(QSPI_Handle_t *hqspi, uint32_t *pData, uint32_t Timeout)
+{
+	uint32_t addr_reg = sil_rew_mem((uint32_t *)(hqspi->base+TOFF_QUADSPI_AR));
+
+	if(hqspi->status != QSPI_STATUS_READY)
+		return E_OBJ;
+	if(pData == NULL)
+		return E_PAR;
+
+	/*
+	 *  ステータス、エラー初期化
+	 */
+    hqspi->errorcode = QSPI_ERROR_NONE;
+	hqspi->status = QSPI_STATUS_BUSY_RX;
+
+	/*
+	 *  通信データ設定
+	 */
+	hqspi->XferCount = 0;
+	hqspi->XferSize = sil_rew_mem((uint32_t *)(hqspi->base+TOFF_QUADSPI_DLR)) + 1;
+	hqspi->pBuffPtr = pData;
+
+	/*
+	 *  CCRレジスタにインダイレクト読込み設定
+	 */
+	sil_modw_mem((uint32_t *)(hqspi->base+TOFF_QUADSPI_CCR), QUADSPI_CCR_FMODE, QSPI_FUNCTIONAL_MODE_INDIRECT_READ);
+
+	/*
+	 *  ARレジスタを再設定
+	 */
+	sil_wrw_mem((uint32_t *)(hqspi->base+TOFF_QUADSPI_AR), addr_reg);
+
+	/*
+	 *  割込みクリアと割込み設定
+	 */
+	sil_wrw_mem((uint32_t *)(hqspi->base+TOFF_QUADSPI_FCR), (QUADSPI_FCR_CTEF | QUADSPI_FCR_CTCF));
+	sil_orw_mem((uint32_t *)(hqspi->base+TOFF_QUADSPI_CR), (QUADSPI_CR_TEIE | QUADSPI_CR_FTIE | QUADSPI_CR_TCIE));
+
+	return qspi_eventwait(hqspi, QSPI_STATUS_BUSY_RX, Timeout);
+}
+
+
+/*
+ *  QSPIデバイスの初期化
+ *  parameter1 hi2c  I2Cハンドラへのポインタ
+ *  return           ハンドラへのポインタ
+ */
+QSPI_Handle_t *
+qspi_init(ID port, QSPI_Init_t *pini)
+{
+	GPIO_Init_t GPIO_Init_Data;
+	QSPI_Init_t *cfg;
+	const QSPI_PortControlBlock *qpcb;
+	QSPI_Handle_t *hqspi = NULL;
+    ER ercd = E_OK;
+	uint32_t no, temp;
+
+	if(port < QSPI1_PORTID || port > NUM_QSPIPORT)
+		return NULL;
+	if(pini == NULL)
+		return NULL;
+	if((pini->ddrmode & ~QUADSPI_CCR_DDRM) != 0)
+		return NULL;
+	if((pini->sioomode & ~QUADSPI_CCR_SIOO) != 0)
+		return NULL;
+
+	no = INDEX_QSPI(port);
+	hqspi = &QSPIHandle[no];
+	memset(hqspi, 0, sizeof(QSPI_Handle_t));
+	qpcb = &qspi_pcb[no];
+	hqspi->base     = qpcb->base;
+
+	/*
+	 *  QSPIクロックイネーブル後リセット
+	 */
+	sil_orw_mem((uint32_t *)(TADR_RCC_BASE+TOFF_RCC_AHB3ENR), RCC_AHB3ENR_QSPIEN);
+	temp = sil_rew_mem((uint32_t *)(TADR_RCC_BASE+TOFF_RCC_AHB3ENR));
+	sil_orw_mem((uint32_t *)(TADR_RCC_BASE+TOFF_RCC_AHB3RSTR), RCC_AHB3RSTR_QSPIRST);
+	sil_andw_mem((uint32_t *)(TADR_RCC_BASE+TOFF_RCC_AHB3RSTR), RCC_AHB3RSTR_QSPIRST);
+	(void)(temp);
+
+	/*
+	 *  GPIOの初期化
+	 */
+	sil_orw_mem((uint32_t *)(qpcb->gioclockbase), qpcb->giocsclockbit);
+	sil_orw_mem((uint32_t *)(qpcb->gioclockbase), qpcb->gioclkclockbit);
+	sil_orw_mem((uint32_t *)(qpcb->gioclockbase), qpcb->giod0clockbit);
+	sil_orw_mem((uint32_t *)(qpcb->gioclockbase), qpcb->giod1clockbit);
+	sil_orw_mem((uint32_t *)(qpcb->gioclockbase), qpcb->giod2clockbit);
+	sil_orw_mem((uint32_t *)(qpcb->gioclockbase), qpcb->giod3clockbit);
+
+	GPIO_Init_Data.mode      = GPIO_MODE_AF;
+	GPIO_Init_Data.pull      = GPIO_PULLUP;
+	GPIO_Init_Data.otype     = GPIO_OTYPE_PP;
+	GPIO_Init_Data.speed     = GPIO_SPEED_HIGH;
+	GPIO_Init_Data.alternate = qpcb->giocsaf;
+	gpio_setup(qpcb->giocsbase, &GPIO_Init_Data, qpcb->giocspin);
+
+	GPIO_Init_Data.pull      = GPIO_NOPULL;
+	GPIO_Init_Data.alternate = qpcb->gioclkaf;
+	gpio_setup(qpcb->gioclkbase, &GPIO_Init_Data, qpcb->gioclkpin);
+
+	GPIO_Init_Data.alternate = qpcb->giod0af;
+	gpio_setup(qpcb->giod0base, &GPIO_Init_Data, qpcb->giod0pin);
+
+	GPIO_Init_Data.alternate = qpcb->giod1af;
+	gpio_setup(qpcb->giod1base, &GPIO_Init_Data, qpcb->giod1pin);
+
+	GPIO_Init_Data.alternate = qpcb->giod2af;
+	gpio_setup(qpcb->giod2base, &GPIO_Init_Data, qpcb->giod2pin);
+
+	GPIO_Init_Data.alternate = qpcb->giod3af;
+	gpio_setup(qpcb->giod3base, &GPIO_Init_Data, qpcb->giod3pin);
+
+	hqspi->timeout = QPSI_TIMEOUT_DEFAULT_VALUE;
+	cfg = &hqspi->Init;
+	memcpy(cfg, pini, sizeof(QSPI_Init_t));
+
+	if((ercd = qspi_reinit(hqspi)) != E_OK)
+		return NULL;
+
+    /*
+	 *  初期化終了関数の実行
+	 */
+    if(pini->init_func != NULL){
+		ercd = pini->init_func(hqspi);
+		if(ercd != E_OK){
+			syslog_0(LOG_ERROR, "qspi_ini: config.init failed.");
+			return NULL;
+		}
+	}
+	return hqspi;
+}
+
+/*
+ *  QSPIデバイスの無効化
+ *  parameter1 hqspi QSPIハンドラへのポインタ
+ *  return           正常終了時、E_OK
+ */
+ER
+qspi_deinit(QSPI_Handle_t *hqspi)
+{
+    /*
+	 *  QSPI無効化
+	 */
+	sil_andw_mem((uint32_t *)(hqspi->base+TOFF_QUADSPI_CR), QUADSPI_CR_EN);
+    hqspi->errorcode = QSPI_ERROR_NONE;
+	hqspi->status    = QSPI_STATUS_RESET;
+
+	/*
+	 *  QSPIリセット後クロック停止
+	 */
+	sil_orw_mem((uint32_t *)(TADR_RCC_BASE+TOFF_RCC_AHB3RSTR), RCC_AHB3RSTR_QSPIRST);
+	sil_andw_mem((uint32_t *)(TADR_RCC_BASE+TOFF_RCC_AHB3RSTR), RCC_AHB3RSTR_QSPIRST);
+	sil_andw_mem((uint32_t *)(TADR_RCC_BASE+TOFF_RCC_AHB3ENR), RCC_AHB3ENR_QSPIEN);
+    return E_OK;
+}
+
+/*
+ *  インダイレクト・フラッシュ・リード
+ *  parameter1 hqspi QSPIハンドラへのポインタ
+ *  parameter2 dst   読み込みアドレス
+ *  parameter3 src   フラッシュROMスタートアドレス
+ *  parameter4 size  読み込みサイズ
+ *  return           正常終了時、E_OK
+ */
+ER
+qspi_read(QSPI_Handle_t *hqspi, void * dst, uint32_t src, uint32_t size) 
+{
+	QSPI_Init_t *cfg = &hqspi->Init;
+	QSPI_Command_t  sCommand;
+    ER ercd = E_OK;
+
+	if(hqspi == NULL)
+		return E_PAR;
+	if(src >= cfg->device_size)
+		return E_PAR;
+	if((src + size - 1) >= cfg->device_size)
+		return E_PAR;
+	if(size == 0)
+		return E_PAR;
+	/*
+	 *  パラメータアラインチェック
+	 */
+    if(((uintptr_t)dst & 0x3) || (src & 0x3) || (size & 0x3))
+		return E_PAR;
+
+	sCommand.InstructionMode   = hqspi->Init.inst_type;
+	sCommand.Instruction       = hqspi->Init.read_op_code;
+	sCommand.AddressMode       = hqspi->Init.read_addr_xfer_type;
+	sCommand.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;
+	sCommand.AddressSize       = hqspi->Init.addr_size;
+	sCommand.AlternateBytesSize = 0;
+	sCommand.Address           = src;
+	sCommand.DataMode          = hqspi->Init.read_data_xfer_type;
+	sCommand.NbData            = size;
+	sCommand.DummyCycles       = hqspi->Init.read_dummy_cycles;
+
+
+	if((ercd = qspi_command(hqspi, &sCommand, hqspi->timeout)) != E_OK)
+		return ercd;
+
+#ifdef TOPPERS_STM32F769_DISCOVERY
+	sil_modw_mem((uint32_t *)(hqspi->base+TOFF_QUADSPI_DCR), QUADSPI_DCR_CSHT, QSPI_CS_HIGH_TIME_1_CYCLE);
+#endif
+
+	ercd = qspi_receive(hqspi, dst, hqspi->timeout);
+#ifdef TOPPERS_STM32F769_DISCOVERY
+	sil_modw_mem((uint32_t *)(hqspi->base+TOFF_QUADSPI_DCR), QUADSPI_DCR_CSHT, QSPI_CS_HIGH_TIME_4_CYCLE);
+#endif
+	return ercd;
+}
+
+/*
+ *  インダイレクト・フラッシュ・ライト
+ *  parameter1 hqspi QSPIハンドラへのポインタ
+ *  parameter2 dst   フラッシュROMスタートアドレス
+ *  parameter3 src   書き込みデータアドレス
+ *  parameter4 size  書き込みサイズ
+ *  return           正常終了時、E_OK
+ */
+ER
+qspi_write(QSPI_Handle_t *hqspi, uint32_t dst, const void * src, uint32_t size)
+{
+	QSPI_Init_t *cfg = &hqspi->Init;
+	QSPI_Command_t sCommand;
+	uint32_t len, no = 0;
+	uint8_t  *p = (uint8_t *)src;
+	ER ercd = E_OK;
+
+	if(hqspi == NULL)
+		return E_PAR;
+	if(dst >= cfg->device_size)
+		return E_PAR;
+	if((dst + size - 1) >= cfg->device_size)
+		return E_PAR;
+	if(size == 0)
+		return E_PAR;
+	/*
+	 *  パラメータアラインチェック
+	 */
+    if(((uintptr_t)src & 0x3) || (dst & 0x3) || (size & 0x3))
+		return E_PAR;
+
+	while(no < size && ercd == E_OK){
+		len = MIN(size, QSPI_WRITE_SIZE);
+
+		/*
+		 *  書込みイネーブル設定
+		 */
+		if(hqspi->Init.enable_write_func != NULL)
+			ercd = hqspi->Init.enable_write_func(hqspi, hqspi->timeout);
+		if(ercd != E_OK)
+			return ercd;
+
+		/*
+		 *  書込みコマンド設定
+		 */
+		sCommand.InstructionMode   = hqspi->Init.inst_type;
+		sCommand.Instruction       = hqspi->Init.write_op_code;
+		sCommand.AddressMode       = hqspi->Init.write_addr_xfer_type;
+		sCommand.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;
+		sCommand.AddressSize       = hqspi->Init.addr_size;
+		sCommand.AlternateBytesSize = 0;
+		sCommand.Address           = dst + no;
+		sCommand.DataMode          = hqspi->Init.write_data_xfer_type;
+		sCommand.NbData            = len;
+		sCommand.DummyCycles       = hqspi->Init.write_dummy_cycles;
+
+		if((ercd = qspi_command(hqspi, &sCommand, hqspi->timeout)) != E_OK)
+			return ercd;
+
+		if((ercd = qspi_transmit(hqspi, (uint32_t *)(p+no), hqspi->timeout)) != E_OK)
+			return ercd;
+		/*
+		 *  書込み完了待ち
+		 */
+		if(hqspi->Init.wait_func != NULL)
+			ercd = hqspi->Init.wait_func(hqspi, hqspi->timeout);
+		no += len;
+	}
+	return ercd;
+}
+
+/*
+ *  セクター消去
+ *  parameter1 hqspi   QSPIハンドラへのポインタ
+ *  parameter2 address セクター先頭アドレス
+ *  return             正常終了時、E_OK
+ */
+ER
+qspi_erase_sector(QSPI_Handle_t *hqspi, uint32_t address)
+{
+	QSPI_Command_t sCommand;
+	ER ercd = E_OK;
+
+	/*
+	 *  書込みイネーブル設定
+	 */
+	if(hqspi->Init.enable_write_func != NULL)
+		ercd = hqspi->Init.enable_write_func(hqspi, hqspi->timeout);
+	if(ercd != E_OK)
+		return ercd;
+
+	/*
+	 *  ERASEコマンド設定
+	 */
+	sCommand.InstructionMode   = hqspi->Init.inst_type;	/* F */
+	sCommand.Instruction       = hqspi->Init.erase_cmds[0];
+	sCommand.AddressMode       = hqspi->Init.erase_addr_xfer_type;
+	sCommand.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;	/* F */
+	sCommand.AlternateBytesSize = 0;						/* NU */
+	sCommand.AddressSize       = hqspi->Init.addr_size;		/* F */
+	sCommand.Address           = address;
+	sCommand.DataMode          = QSPI_DATA_NONE;
+	sCommand.NbData            = 0;
+	sCommand.DummyCycles       = 0;
+
+	if((ercd = qspi_command(hqspi, &sCommand, hqspi->timeout)) != E_OK)
+		return ercd;
+
+	if(hqspi->Init.wait_func != NULL)
+		ercd = hqspi->Init.wait_func(hqspi, hqspi->timeout);
+	return ercd;
+}
+
+/*
+ *  フラッシュメモリの消去
+ *  parameter1 hqspi   QSPIハンドラへのポインタ
+ *  parameter2 address 消去領域の先頭アドレス
+ *  parameter3 size    消去バイトサイズ
+ *  return             正常終了時、E_OK
+ */
+ER
+qspi_erase(QSPI_Handle_t *hqspi, uint32_t address, uint32_t size)
+{
+	QSPI_Init_t *cfg = &hqspi->Init;
+    uint32_t actual_address = address;
+    uint32_t actual_size = size;
+    uint32_t remainder;
+    ER ercd = E_OK;
+
+    /*
+	 *  パラメータチェック
+	 */
+	if(hqspi == NULL)
+		return E_PAR;
+	if((address + size) > cfg->device_size)
+		return E_PAR;
+	if((address + size) > cfg->device_size)
+		return E_PAR;
+
+    /*
+	 *  消去アライン補正
+	 */
+	remainder = address % cfg->erase_sizes[0];
+	if(remainder != 0){
+		actual_address -= remainder;
+		actual_size += remainder;
+	}
+	remainder = actual_size % cfg->erase_sizes[0];
+	if(remainder != 0){
+		remainder = cfg->erase_sizes[0] - remainder;
+		actual_size += remainder;
+	}
+
+	/*
+	 *  補正が必要ならパラメータエラー
+	 */
+	if((actual_address != address) || (actual_size != size))
+		return E_PAR;
+
+	while(size > 0){
+		if((ercd = qspi_erase_sector(hqspi, address)) != E_OK)
+			break;
+		address += cfg->erase_sizes[0];
+		size    -= cfg->erase_sizes[0];
+	}
+	return ercd;
+}
+
+/*
+ *  ダイレクト・アクセス無効化
+ *  parameter1 hqspi   QSPIハンドラへのポインタ
+ *  return             正常終了時、E_OK
+ */
+ER
+qspi_direct_disable(QSPI_Handle_t *hqspi)
+{
+	/*
+	 *  QSPI無効化
+	 */
+	sil_andw_mem((uint32_t *)(hqspi->base+TOFF_QUADSPI_CR), QUADSPI_CR_EN);
+
+	/*
+	 *  QSPIリセット後クロック停止
+	 */
+	sil_orw_mem((uint32_t *)(TADR_RCC_BASE+TOFF_RCC_AHB3RSTR), RCC_AHB3RSTR_QSPIRST);
+	sil_andw_mem((uint32_t *)(TADR_RCC_BASE+TOFF_RCC_AHB3RSTR), RCC_AHB3RSTR_QSPIRST);
+	return qspi_reinit(hqspi);
+}
+
+/*
+ *  ダイレクト・アクセス有効化
+ *  parameter1 hqspi   QSPIハンドラへのポインタ
+ *  return             正常終了時、E_OK
+ */
+ER
+qspi_direct_enable(QSPI_Handle_t *hqspi)
+{
+	QSPI_Command_t sCommand;
+	uint32_t Timeout = hqspi->timeout;
+	ER ercd = E_OK;
+
+	if(hqspi->status != QSPI_STATUS_READY)
+		return E_OBJ;
+
+	/*
+	 *  読み出しコマンド設定
+	 */
+	sCommand.InstructionMode   = hqspi->Init.inst_type;
+	sCommand.Instruction       = hqspi->Init.read_op_code;
+	sCommand.AddressMode       = hqspi->Init.read_addr_xfer_type;
+	sCommand.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;
+	sCommand.AlternateBytesSize = 0;
+	sCommand.AddressSize       = hqspi->Init.addr_size;
+	sCommand.Address           = 0;
+	sCommand.DataMode          = hqspi->Init.read_data_xfer_type;
+	sCommand.NbData            = 0;
+	sCommand.DummyCycles       = hqspi->Init.read_dummy_cycles;
+
+	/*
+	 *  READY待ち
+	 */
+	if((ercd = qspi_waitflag(hqspi, QUADSPI_SR_BUSY, 0, Timeout, &Timeout)) != E_OK)
+		return ercd;
+
+	hqspi->errorcode = QSPI_ERROR_NONE;
+	hqspi->status = QSPI_STATUS_BUSY_MM;
+
+	/*
+	 *  通信レジスタ設定
+	 */
+	qspi_config(hqspi, &sCommand, QSPI_FUNCTIONAL_MODE_MEMORY_MAPPED);
+	return E_OK;
+}
+
+/*
+ *  QSPI割込みハンドラ
+ */
+void
+qspi_handler(QSPI_Handle_t *hqspi)
+{
+	uint32_t sr = sil_rew_mem((uint32_t *)(hqspi->base+TOFF_QUADSPI_SR));
+	uint32_t cr = sil_rew_mem((uint32_t *)(hqspi->base+TOFF_QUADSPI_CR));
+
+	hqspi->istatus = sr;
+	/*
+	 *  QSPI FIFOスレッシュ割込み
+	 */
+	if((sr & QUADSPI_SR_FTF) != 0 && (cr & QUADSPI_CR_FTIE) != 0){
+		if(hqspi->status == QSPI_STATUS_BUSY_TX){
+			/* Transmission process */
+			while((sil_rew_mem((uint32_t *)(hqspi->base+TOFF_QUADSPI_SR)) & QUADSPI_SR_FTF) != 0){
+				if(hqspi->XferCount < hqspi->XferSize){
+					sil_wrw_mem((uint32_t *)(hqspi->base+TOFF_QUADSPI_DR), *hqspi->pBuffPtr++);
+					hqspi->XferCount += 4;
+				}
+				else{	/* FIFO割込みマスク */
+					sil_andw_mem((uint32_t *)(hqspi->base+TOFF_QUADSPI_CR), QUADSPI_CR_FTIE);
+					break;
+				}
+			}
+		}
+		else if(hqspi->status == QSPI_STATUS_BUSY_RX){
+			/* Receiving Process */
+			while((sil_rew_mem((uint32_t *)(hqspi->base+TOFF_QUADSPI_SR)) & QUADSPI_SR_FTF) != 0){
+				if(hqspi->XferCount < hqspi->XferSize){
+					*hqspi->pBuffPtr++ = (uint32_t)sil_rew_mem((uint32_t *)(hqspi->base+TOFF_QUADSPI_DR));
+					hqspi->XferCount += 4;
+				}
+				else{	/* FIFO割込みマスク */
+					sil_andw_mem((uint32_t *)(hqspi->base+TOFF_QUADSPI_CR), QUADSPI_CR_FTIE);
+					break;
+				}
+			}
+		}
+	}
+
+	/*
+	 *  QSPI転送終了割込み
+	 */
+	else if((sr & QUADSPI_SR_TCF) != 0 && (cr & QUADSPI_CR_TCIE) != 0){
+		/*
+		 *  割込みクリア、要因マスク
+		 */
+		sil_wrw_mem((uint32_t *)(hqspi->base+TOFF_QUADSPI_FCR), QUADSPI_FCR_CTCF);
+		sil_andw_mem((uint32_t *)(hqspi->base+TOFF_QUADSPI_CR), (QUADSPI_CR_TCIE | QUADSPI_CR_TEIE | QUADSPI_CR_FTIE));
+
+		/* Transfer complete callback */
+		if(hqspi->status == QSPI_STATUS_BUSY_TX){
+			/* Change state of QSPI */
+			hqspi->status = QSPI_STATUS_READY;
+			if(hqspi->semid != 0)
+				isig_sem(hqspi->semid);
+	    }
+		else if(hqspi->status == QSPI_STATUS_BUSY_RX){
+			while((sil_rew_mem((uint32_t *)(hqspi->base+TOFF_QUADSPI_SR)) & QUADSPI_SR_FLEVEL) != 0){
+				if (hqspi->XferCount < hqspi->XferSize){
+					*hqspi->pBuffPtr++ = (uint32_t)sil_rew_mem((uint32_t *)(hqspi->base+TOFF_QUADSPI_DR));
+					hqspi->XferCount += 4;
+				}
+				else{
+					/* All data have been received for the transfer */
+					break;
+				}
+			}
+			/* Change state of QSPI */
+			hqspi->status = QSPI_STATUS_READY;
+			if(hqspi->semid != 0)
+				isig_sem(hqspi->semid);
+		}
+		else if(hqspi->status == QSPI_STATUS_BUSY){
+			/*
+			 *  コマンド送信終了
+			 */
+			hqspi->status = QSPI_STATUS_READY;
+			if(hqspi->semid != 0)
+				isig_sem(hqspi->semid);
+		}
+	}
+
+	/*
+	 *  QSPI Status Match割込み
+	 */
+	else if((sr & QUADSPI_SR_SMF) != 0 && (cr & QUADSPI_CR_SMIE) != 0){
+		/*
+		 *  STATUS MATCH割込みクリア
+		 */
+		sil_wrw_mem((uint32_t *)(hqspi->base+TOFF_QUADSPI_FCR), QUADSPI_FCR_CSMF);
+		/*
+		 *  AUTOMATIC POLL MODE終了
+		 */
+		if((sil_rew_mem((uint32_t *)(hqspi->base+TOFF_QUADSPI_CR)) & QUADSPI_CR_APMS) != 0){
+			/*
+			 *  割込みマスクとステータス変更
+			 */
+			sil_andw_mem((uint32_t *)(hqspi->base+TOFF_QUADSPI_CR), (QUADSPI_CR_SMIE | QUADSPI_CR_TEIE));
+			hqspi->status = QSPI_STATUS_READY;
+		}
+		if(hqspi->semid != 0)
+			isig_sem(hqspi->semid);
+	}
+
+	/*
+	 *  QSPI Transfer Error割込み
+	 */
+	else if((sr & QUADSPI_SR_TEF) != 0 && (cr & QUADSPI_CR_TEIE) != 0){
+		/* Clear interrupt */
+		sil_wrw_mem((uint32_t *)(hqspi->base+TOFF_QUADSPI_FCR), QUADSPI_FCR_CTEF);
+
+		/* Disable all the QSPI Interrupts */
+		sil_andw_mem((uint32_t *)(hqspi->base+TOFF_QUADSPI_CR), (QUADSPI_CR_SMIE | QUADSPI_CR_TCIE | QUADSPI_CR_TEIE | QUADSPI_CR_FTIE));
+
+		/* Set error code */
+		hqspi->errorcode |= QSPI_ERROR_TRANERR;
+
+		/* Change state of QSPI */
+		hqspi->status = QSPI_STATUS_READY;
+
+		/*
+		 *  エラーコールバック
+		 */
+		if(hqspi->errorcallback != NULL)
+			hqspi->errorcallback(hqspi);
+	}
+
+	/*
+	 *  QSPI Timeout割込み
+	 */
+	else if((sr & QUADSPI_SR_TOF) != 0 && (cr & QUADSPI_CR_TOIE) != 0){
+		/*
+		 *  タイマー割込みクリア
+		 */
+		sil_wrw_mem((uint32_t *)(hqspi->base+TOFF_QUADSPI_FCR), QUADSPI_FCR_CTOF);
+
+		/*
+		 *  タイムアウトコールバック
+		 */
+		if(hqspi->timeoutcallback != NULL)
+			hqspi->timeoutcallback(hqspi);
+	}
+}
+
+
+/*
+ *  QSPI割込みサービスルーチン
+ */
+void qspi_isr(intptr_t exinf)
+{
+	qspi_handler(&QSPIHandle[INDEX_QSPI((uint32_t)exinf)]);
+}
+
+
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/pdic/stm32f7xx/qspi.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/pdic/stm32f7xx/qspi.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/pdic/stm32f7xx/qspi.h	(revision 457)
@@ -0,0 +1,441 @@
+/*
+ *  TOPPERS/ASP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Advanced Standard Profile Kernel
+ * 
+ *  Copyright (C) 2008-2011 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ *  Copyright (C) 2015-2017 by TOPPERS PROJECT Educational Working Group.
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+/*
+ * 
+ *  QSPIデバイスドライバの外部宣言
+ *
+ */
+
+#ifndef _QSPI_H_
+#define _QSPI_H_
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif  /* __cplusplus */
+
+/*
+ *  QSPIポート定義
+ */
+#define QSPI1_PORTID            1
+#define NUM_QSPIPORT            1
+
+/*
+ *  フラッシュ・コマンド
+ */
+#define QSPI_STIG_OPCODE_WR_STAT_REG          (0x01)
+#define QSPI_STIG_OPCODE_PP                   (0x02)
+#define QSPI_STIG_OPCODE_READ                 (0x03)
+#define QSPI_STIG_OPCODE_WRDIS                (0x04)
+#define QSPI_STIG_OPCODE_RD_STAT_REG          (0x05)
+#define QSPI_STIG_OPCODE_WREN                 (0x06)
+#define QSPI_STIG_OPCODE_FASTREAD             (0x0B)
+#define QSPI_DEVSZ_BYTESPERSUBSECTOR_RESET    (0x10)
+#define QSPI_STIG_OPCODE_4BYTE_WRITE          (0x12)
+#define QSPI_STIG_OPCODE_4BYTE_READ           (0x13)
+#define QSPI_STIG_OPCODE_READ_CFG_REG         (0x15)
+#define QSPI_STIG_OPCODE_SUBSEC_ERASE         (0x20)
+#define QSPI_STIG_OPCODE_4BYTE_SEC_ERASE      (0x21)
+#define QSPI_STIG_OPCODE_QUAD_PP              (0x32)
+#define QSPI_STIG_OPCODE_4QUAD_WRITE          (0x34)
+#define QSPI_STIG_OPCODE_ENTER_QUAD_CMD       (0x35)
+#define QSPI_STIG_OPCODE_FASTREAD_DUAL_OUTPUT (0x3B)
+#define QSPI_STIG_OPCODE_4BYTE_BLOCK_ERASE    (0x5C)
+#define QSPI_STIG_OPCODE_CHIP_ERASE           (0x60)
+#define QSPI_STIG_OPCODE_FASTREAD_QUAD_OUTPUT (0x6B)
+#define QSPI_STIG_OPCODE_WRITE_VOL_CFG_REG_CMD (0x81)
+#define QSPI_STIG_OPCODE_READ_VOL_CFG_REG_CMD (0x85)
+#define QSPI_STIG_OPCODE_RDID                 (0x9F)
+#define QSPI_STIG_OPCODE_DUAL_PP              (0xA2)
+#define QSPI_STIG_OPCODE_ENTER_4BYTE_MODE     (0xB7)
+#define QSPI_STIG_OPCODE_FASTREAD_DUAL_IO     (0xBB)
+#define QSPI_STIG_OPCODE_DIE_ERASE            (0xC4)
+#define QSPI_STIG_OPCODE_WR_EXT_REG           (0xC5)
+#define QSPI_STIG_OPCODE_BULK_ERASE           (0xC7)
+#define QSPI_STIG_OPCODE_RD_EXT_REG           (0xC8)
+#define QSPI_STIG_OPCODE_SEC_ERASE            (0xD8)
+#define QSPI_STIG_OPCODE_4BYTE_Q_SEC_ERASE    (0xDC)
+#define QSPI_STIG_OPCODE_EXIT_4BYTE_MODE      (0xE9)
+#define QSPI_STIG_OPCODE_FASTREAD_QUAD_IO     (0xEB)
+#define QSPI_STIG_OPCODE_4QUAD_READ           (0xEC)
+
+/*
+ *  フラッシュコマンド Micron依存
+ */
+#define QSPI_STIG_OPCODE_N25Q512A_CLRFLGSR    (0x50)
+#define QSPI_STIG_OPCODE_N25Q512A_DISCVR_PARAM  (0x5A)
+#define QSPI_STIG_OPCODE_N25Q128              (0x61)
+#define QSPI_STIG_REGISTER_N25Q128_VECR       (0x65)
+#define QSPI_STIG_OPCODE_N25Q512A_RESET_EN    (0x66)
+#define QSPI_STIG_OPCODE_N25Q512A_RDFLGSR     (0x70)
+#define QSPI_STIG_OPCODE_N25Q512A_RESET_MEM   (0x99)
+
+/*
+ *  マニュファクチャID
+ */
+#define QSPI_STIG_RDID_JEDECID_MICRON         (0x20)
+#define QSPI_STIG_RDID_JEDECID_SPANSION       (0x01)
+#define QSPI_STIG_RDID_JEDECID_MACRONIX       (0xC2)
+
+
+#define QSPI_MAX_ERASE_CMDS  	2
+
+
+/*
+ *  QSPI Sample Shifting
+ */
+#define QSPI_SAMPLE_SHIFTING_NONE       0x00000000				/* No clock cycle shift to sample data */
+#define QSPI_SAMPLE_SHIFTING_HALFCYCLE  QUADSPI_CR_SSHIFT		/* 1/2 clock cycle shift to sample data */
+/**
+  * @}
+  */ 
+
+/*
+ *  QSPI ChipSelect High Time
+ */
+#define QSPI_CS_HIGH_TIME_1_CYCLE       0x00000000				/* nCS stay high for at least 1 clock cycle between commands */
+#define QSPI_CS_HIGH_TIME_2_CYCLE       QUADSPI_DCR_CSHT_0		/* nCS stay high for at least 2 clock cycles between commands */
+#define QSPI_CS_HIGH_TIME_3_CYCLE       QUADSPI_DCR_CSHT_1		/* nCS stay high for at least 3 clock cycles between commands */
+#define QSPI_CS_HIGH_TIME_4_CYCLE       (QUADSPI_DCR_CSHT_0 | QUADSPI_DCR_CSHT_1)	/* nCS stay high for at least 4 clock cycles between commands*/
+#define QSPI_CS_HIGH_TIME_5_CYCLE       QUADSPI_DCR_CSHT_2		/* nCS stay high for at least 5 clock cycles between commands */
+#define QSPI_CS_HIGH_TIME_6_CYCLE       (QUADSPI_DCR_CSHT_2 | QUADSPI_DCR_CSHT_0)	/* nCS stay high for at least 6 clock cycles between commands*/
+#define QSPI_CS_HIGH_TIME_7_CYCLE       (QUADSPI_DCR_CSHT_2 | QUADSPI_DCR_CSHT_1)	/* nCS stay high for at least 7 clock cycles between commands*/
+#define QSPI_CS_HIGH_TIME_8_CYCLE       QUADSPI_DCR_CSHT		/* nCS stay high for at least 8 clock cycles between commands */
+
+/*
+ *  QSPI Clock Mode
+ */
+#define QSPI_CLOCK_MODE_0               0x00000000				/* Clk stays low while nCS is released */
+#define QSPI_CLOCK_MODE_3               QUADSPI_DCR_CKMODE		/* Clk goes high while nCS is released */
+
+/*
+ *  QSPI Flash Select
+ */
+#define QSPI_FLASH_ID_1                 0x00000000				/* FLASH 1 selected */
+#define QSPI_FLASH_ID_2                 QUADSPI_CR_FSEL			/* FLASH 2 selected */
+
+/*
+ *  QSPI Dual Flash Mode
+ */
+#define QSPI_DUALFLASH_DISABLE          0x00000000				/* Dual-flash mode disabled */
+#define QSPI_DUALFLASH_ENABLE           QUADSPI_CR_DFM			/* Dual-flash mode enabled */
+
+/*
+ *  QSPI DDR Mode
+ */
+#define QSPI_DDR_MODE_DISABLE           0x00000000				/* Double data rate mode disabled */
+#define QSPI_DDR_MODE_ENABLE            QUADSPI_CCR_DDRM		/* Double data rate mode enabled */
+
+/*
+ *  QSPI DDR Data Output Delay
+ */
+#define QSPI_DDR_HHC_ANALOG_DELAY       0x00000000				/* Delay the data output using analog delay in DDR mode */
+#ifdef QUADSPI_CCR_DHHC
+#define QSPI_DDR_HHC_HALF_CLK_DELAY     QUADSPI_CCR_DHHC		/* Delay the data output by 1/2 clock cycle in DDR mode */
+#endif
+
+/*
+ *   QSPI Send Instruction Mode
+ */
+#define QSPI_SIOO_INST_EVERY_CMD        0x00000000				/* Send instruction on every transaction */
+#define QSPI_SIOO_INST_ONLY_FIRST_CMD   QUADSPI_CCR_SIOO		/* Send instruction only for the first command */
+
+
+
+/*
+ *  QSPI Address Size
+ */
+#define QSPI_ADDRESS_8_BITS             0x00000000				/* 8-bit address*/
+#define QSPI_ADDRESS_16_BITS            QUADSPI_CCR_ADSIZE_0	/* 16-bit address*/
+#define QSPI_ADDRESS_24_BITS            QUADSPI_CCR_ADSIZE_1	/* 24-bit address*/
+#define QSPI_ADDRESS_32_BITS            QUADSPI_CCR_ADSIZE		/* 32-bit address*/
+
+/*
+ *  QSPI Alternate Bytes Size
+ */
+#define QSPI_ALTERNATE_BYTES_8_BITS     0x00000000				/* 8-bit alternate bytes*/
+#define QSPI_ALTERNATE_BYTES_16_BITS    QUADSPI_CCR_ABSIZE_0	/* 16-bit alternate bytes*/
+#define QSPI_ALTERNATE_BYTES_24_BITS    QUADSPI_CCR_ABSIZE_1	/* 24-bit alternate bytes*/
+#define QSPI_ALTERNATE_BYTES_32_BITS    QUADSPI_CCR_ABSIZE		/* 32-bit alternate bytes*/
+
+/*
+ *  QSPI Instruction Mode
+ */
+#define QSPI_INSTRUCTION_NONE           0x00000000				/* No instruction*/
+#define QSPI_INSTRUCTION_1_LINE         QUADSPI_CCR_IMODE_0		/* Instruction on a single line*/
+#define QSPI_INSTRUCTION_2_LINES        QUADSPI_CCR_IMODE_1		/* Instruction on two lines*/
+#define QSPI_INSTRUCTION_4_LINES        QUADSPI_CCR_IMODE		/* Instruction on four lines*/
+
+/*
+ *  QSPI Address Mode
+ */
+#define QSPI_ADDRESS_NONE               0x00000000				/* No address*/
+#define QSPI_ADDRESS_1_LINE             QUADSPI_CCR_ADMODE_0	/* Address on a single line*/
+#define QSPI_ADDRESS_2_LINES            QUADSPI_CCR_ADMODE_1	/* Address on two lines*/
+#define QSPI_ADDRESS_4_LINES            QUADSPI_CCR_ADMODE		/* Address on four lines*/
+
+/*
+ *  QSPI Alternate Bytes Mode
+ */
+#define QSPI_ALTERNATE_BYTES_NONE       0x00000000				/* No alternate bytes*/
+#define QSPI_ALTERNATE_BYTES_1_LINE     QUADSPI_CCR_ABMODE_0	/* Alternate bytes on a single line*/
+#define QSPI_ALTERNATE_BYTES_2_LINES    QUADSPI_CCR_ABMODE_1	/* Alternate bytes on two lines*/
+#define QSPI_ALTERNATE_BYTES_4_LINES    QUADSPI_CCR_ABMODE		/* Alternate bytes on four lines*/
+
+/*
+ *  QSPI Data Mode
+ */
+#define QSPI_DATA_NONE                  0x00000000				/* No data */
+#define QSPI_DATA_1_LINE                QUADSPI_CCR_DMODE_0		/* Data on a single line */
+#define QSPI_DATA_2_LINES               QUADSPI_CCR_DMODE_1		/* Data on two lines */
+#define QSPI_DATA_4_LINES               QUADSPI_CCR_DMODE		/* Data on four lines */
+
+
+/*
+ *  QSPI Match Mode
+ */
+#define QSPI_MATCH_MODE_AND             0x00000000				/* AND match mode between unmasked bits */
+#define QSPI_MATCH_MODE_OR              QUADSPI_CR_PMM			/* OR match mode between unmasked bits*/
+
+/*
+ *  QSPI Automatic Stop
+ */
+#define QSPI_AUTOMATIC_STOP_DISABLE     0x00000000				/* AutoPolling stops only with abort or QSPI disabling*/
+#define QSPI_AUTOMATIC_STOP_ENABLE      QUADSPI_CR_APMS			/* AutoPolling stops as soon as there is a match*/
+
+
+/*
+ *  QSPI ステータス
+ */
+#define QSPI_STATUS_RESET   0x00000000	/* Peripheral not initialized                            */
+#define QSPI_STATUS_READY   0x00000001	/* Peripheral initialized and ready for use              */
+#define QSPI_STATUS_BUSY    0x00000002	/* Peripheral in indirect mode and busy                  */ 
+#define QSPI_STATUS_BUSY_TX 0x00000012	/* Peripheral in indirect mode with transmission ongoing */ 
+#define QSPI_STATUS_BUSY_RX 0x00000022	/* Peripheral in indirect mode with reception ongoing    */
+#define QSPI_STATUS_BUSY_AP 0x00000042	/* Peripheral in auto polling mode ongoing               */
+#define QSPI_STATUS_BUSY_MM 0x00000082	/* Peripheral in memory mapped mode ongoing              */
+#define QSPI_STATUS_ABORT   0x00010000	/* Peripheral with abort request ongoing                 */
+#define QSPI_STATUS_ERROR   0x00020000	/* Peripheral in error                                   */
+
+/*
+ *  QSPIエラー
+ */
+#define QSPI_ERROR_NONE     0x00000000		/* No error */
+#define QSPI_ERROR_TRANERR  0x00000002		/* transfer error */
+#define QSPI_ERROR_TIMEOUT  0x00001000		/* Timeout */
+
+
+
+/*
+ *  QSPIハードウェア設定構造体
+ */
+typedef struct _QSPI_PortControlBlock{
+	uint32_t              base;
+	uint32_t              gioclockbase;
+
+	uint32_t              giocsclockbit;
+	uint32_t              giocsbase;
+	uint32_t              giocspin;
+	uint32_t              giocsaf;
+	uint32_t              gioclkclockbit;
+	uint32_t              gioclkbase;
+	uint32_t              gioclkpin;
+	uint32_t              gioclkaf;
+	uint32_t              giod0clockbit;
+	uint32_t              giod0base;
+	uint32_t              giod0pin;
+	uint32_t              giod0af;
+	uint32_t              giod1clockbit;
+	uint32_t              giod1base;
+	uint32_t              giod1pin;
+	uint32_t              giod1af;
+	uint32_t              giod2clockbit;
+	uint32_t              giod2base;
+	uint32_t              giod2pin;
+	uint32_t              giod2af;
+	uint32_t              giod3clockbit;
+	uint32_t              giod3base;
+	uint32_t              giod3pin;
+	uint32_t              giod3af;
+} QSPI_PortControlBlock;
+
+
+typedef ER (*QSPI_INIT_FUNC_T)(void *h);
+typedef ER (*QSPI_EWRI_FUNC_T)(void *h, uint32_t timeout);
+typedef ER (*QSPI_WAIT_FUNC_T)(void *h, uint32_t timeout);
+
+/*
+ *  QSPIデバイス設定構造体
+ */
+typedef struct QSPI_Init
+{
+	uint16_t                manuf_id;
+    uint16_t                type_capacity;
+	uint32_t                clockprescaler;		/* prescaler factor for generating clock based on the AHB clock. */
+	uint32_t                fifothreshold;		/* threshold number of bytes in the FIFO (used only in indirect mode) */
+	uint32_t                sampleshift;		/* Sample Shift. The data is sampled 1/2 clock cycle delay later to take in account external signal delays */
+	uint32_t                chipselecthightime;	/* Chip Select High Time. */
+	uint32_t                clockmode;			/* the Clock Mode. It indicates the level that clock takes between commands. */
+	uint32_t                flashid;			/* the FlashID */
+	uint32_t                dualflash;			/* the Dual Flash Mode State */
+	uint32_t                ddrmode;
+	uint32_t                ddrholdhalfcycle;
+	uint32_t                sioomode;
+	uint32_t                addr_size;
+	uint32_t                inst_type;
+	uint32_t                inst_data_xfer_type;
+	uint32_t                read_op_code;
+	uint32_t                read_addr_xfer_type;
+	uint32_t                read_data_xfer_type;
+	uint32_t                read_dummy_cycles;
+	uint32_t                write_op_code;
+	uint32_t                write_addr_xfer_type;
+	uint32_t                write_data_xfer_type;
+	uint32_t                write_dummy_cycles;
+    uint8_t                 erase_count;
+    uint32_t                erase_sizes[QSPI_MAX_ERASE_CMDS];
+    uint8_t                 erase_cmds[QSPI_MAX_ERASE_CMDS];
+	uint32_t                erase_addr_xfer_type;
+	uint8_t                 erase_sector_idx;
+	uint32_t                device_size;
+	QSPI_INIT_FUNC_T        init_func;
+	QSPI_EWRI_FUNC_T        enable_write_func;
+	QSPI_WAIT_FUNC_T        wait_func;
+	const char              *friendly_name;
+} QSPI_Init_t;
+
+/*
+ *  QSPIコマンド定義型
+ */
+typedef struct
+{
+	uint32_t                InstructionMode;	/* the Instruction Mode */
+	uint32_t                Instruction;		/* the Instruction to be sent */
+	uint32_t                AddressMode;		/* the Address Mode */
+	uint32_t                AddressSize;		/* the Address Size */
+	uint32_t                Address;			/* the Address to be sent (Size from 1 to 4 bytes according AddressSize) */
+	uint32_t                AlternateByteMode;	/* the Alternate Bytes Mode */
+	uint32_t                AlternateBytesSize;	/* the Alternate Bytes Size */
+	uint32_t                AlternateBytes;		/* the Alternate Bytes to be sent (Size from 1 to 4 bytes according AlternateBytesSize) */
+	uint32_t                DummyCycles;		/* the Number of Dummy Cycles. */
+	uint32_t                DataMode;			/* the Data Mode (used for dummy cycles and data phases) */
+	uint32_t                NbData;				/* the number of data to transfer. (This is the number of bytes) */
+} QSPI_Command_t;
+
+/*
+ *  QSPIオートポーリング型
+ */
+typedef struct
+{
+	uint32_t                Match;				/* the value to be compared with the masked status register to get a match. */
+	uint32_t                Mask;				/* the mask to be applied to the status bytes received. */
+	uint32_t                Interval;			/* the number of clock cycles between two read during automatic polling phases. */
+	uint32_t                StatusBytesSize;	/* the size of the status bytes received. */
+	uint32_t                MatchMode;			/* the method used for determining a match. */
+	uint32_t                AutomaticStop;		/* if automatic polling is stopped after a match. */
+} QSPI_AutoPolling_t;
+
+/*
+ *  QSPIデバイスハンドラ定義
+ */
+typedef struct _QSPI_Handle_t QSPI_Handle_t;
+struct _QSPI_Handle_t
+{
+	uint32_t              base;			/* QSPI レジスタベースアドレス */
+	QSPI_Init_t           Init;			/* QSPI FLASHデータ */
+	uint32_t              *pBuffPtr;	/* QSPI 通信バッファへのポインタ */
+	uint32_t              XferSize;		/* QSPI 通信サイズ */
+	volatile uint32_t     XferCount;	/* QSPI 通信カウンタ */
+	void               (*timeoutcallback)(QSPI_Handle_t * hqspi);	/* タイムアウトコールバック関数 */
+	void               (*errorcallback)(QSPI_Handle_t * hqspi);		/* エラーコールバック関数 */
+	volatile uint32_t     istatus;		/* QSPI 割込みステータス */
+	uint32_t              timeout;		/* QSPI タイムアウト値(ms) */
+	int                   semid;		/* QSPI 通信用セマフォ値 */
+	uint32_t              status;		/* QSPI ステータス */
+	volatile uint32_t     errorcode;	/* QSPI エラーコード */
+};
+
+extern QSPI_Handle_t *qspi_init(ID portid, QSPI_Init_t *pini);
+extern ER qspi_deinit(QSPI_Handle_t *hqspi);
+extern ER qspi_read(QSPI_Handle_t *hqspi, void * dest, uint32_t src, uint32_t size);
+extern ER qspi_write(QSPI_Handle_t *hqspi, uint32_t dest, const void * src, uint32_t size);
+extern ER qspi_erase(QSPI_Handle_t *hqspi, uint32_t address, uint32_t size); 
+extern ER qspi_erase_sector(QSPI_Handle_t *hqspi, uint32_t address);
+extern ER qspi_direct_disable(QSPI_Handle_t *hqspi);
+extern ER qspi_direct_enable(QSPI_Handle_t *hqspi);
+extern void qspi_handler(QSPI_Handle_t *hqspi);
+extern void qspi_isr(intptr_t exinf);
+
+/*
+ *  CHIP消去
+ *  parameter1 hqspi   QSPIハンドラへのポインタ
+ *  return             正常終了時、E_OK
+ */
+#define qspi_erase_chip(h) qspi_erase(h, 0, (h)->Init.device_size)
+
+
+/*
+ *  セクターサイズを取り出す
+ *  parameter1 hqspi   QSPIハンドラへのポインタ
+ *  return             セクターバイトサイズ
+ */
+#define get_smallest_sector_size(h) (h)->Init.erase_sizes[(h)->Init.erase_sector_idx]
+
+
+/*
+ *  デバイスサイズを取り出す
+ *  parameter1 hqspi   QSPIハンドラへのポインタ
+ *  return             デバイスバイトサイズ
+ */
+#define qspi_get_device_size(h)  (h)->Init.device_size;
+
+extern ER qspi_command(QSPI_Handle_t *hqspi, QSPI_Command_t *cmd, uint32_t Timeout);
+extern ER qspi_autopolling(QSPI_Handle_t *hqspi, QSPI_Command_t *cmd, QSPI_AutoPolling_t *cfg, uint32_t Timeout);
+extern ER qspi_transmit(QSPI_Handle_t *hqspi, uint32_t *pData, uint32_t Timeout);
+extern ER qspi_receive(QSPI_Handle_t *hqspi, uint32_t *pData, uint32_t Timeout);
+
+
+#ifdef __cplusplus
+}
+#endif  /* __cplusplus */
+
+#endif	/* _QSPI_H_ */
+
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/pdic/stm32f7xx/sai.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/pdic/stm32f7xx/sai.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/pdic/stm32f7xx/sai.c	(revision 457)
@@ -0,0 +1,1136 @@
+/*
+ *  TOPPERS/ASP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Advanced Standard Profile Kernel
+ * 
+ *  Copyright (C) 2008-2011 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ *  Copyright (C) 2015-2018 by TOPPERS PROJECT Educational Working Group.
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+/*
+ * 
+ *  AUDIOドライバ関数群
+ *
+ */
+#include "kernel_impl.h"
+#include <t_syslog.h>
+#include <t_stdlib.h>
+#include <sil.h>
+#include <target_syssvc.h>
+#include <string.h>
+#include "device.h"
+#include "sai.h"
+
+/*
+ *  SIL関数のマクロ定義
+ */
+#define sil_orw_mem(a, b)		sil_wrw_mem((a), sil_rew_mem(a) | (b))
+#define sil_andw_mem(a, b)		sil_wrw_mem((a), sil_rew_mem(a) & ~(b))
+#define sil_modw_mem(a, b, c)	sil_wrw_mem((a), (sil_rew_mem(a) & (~b)) | (c))
+
+/*
+ *  AUDIOポートIDから管理ブロックを取り出すためのマクロ
+ */
+#define INDEX_AUDIO(id)         ((uint_t)((id) - 1))
+
+#define SAI_TIMEOUT_VALUE       (10*1000)	/* 10ms */
+#define PLLI2S_TIMEOUT_VALUE    100			/* Timeout value fixed to 100 ms  */
+#define EXTERNAL_CLOCK_VALUE    12288000	/* Value of the Internal oscillator in Hz*/
+
+#define FREQUENCY_44K           44100
+#define FREQUENCY_22K           22050
+#define FREQUENCY_11K           11025
+
+/*
+ *  AUDIOポート設定テーブル
+ */
+static const AUDIO_PortControlBlock audio_pcb[NUM_AUDIOPORT] = {
+  {	TADR_SAI1_BASE,
+	(TADR_RCC_BASE+TOFF_RCC_AHB1ENR), RCC_AHB1ENR_GPIOEEN,
+	(TADR_RCC_BASE+TOFF_RCC_AHB1ENR), RCC_AHB1ENR_GPIOGEN,
+	(TADR_RCC_BASE+TOFF_RCC_AHB1ENR), RCC_AHB1ENR_GPIOJEN,
+	(TADR_RCC_BASE+TOFF_RCC_AHB1ENR), RCC_AHB1ENR_DMA2EN,
+	(TADR_RCC_BASE+TOFF_RCC_AHB1ENR), RCC_AHB1ENR_DMA2EN,
+	(TADR_RCC_BASE+TOFF_RCC_APB2ENR), RCC_APB2ENR_SAI1EN,
+
+
+	TADR_GPIOE_BASE, TADR_GPIOG_BASE, TADR_GPIOE_BASE, TADR_GPIOJ_BASE,
+#ifdef TOPPERS_STM32F769_DISCOVERY
+	TADR_DMA2_STM3_BASE, DMA_CHANNEL_0, TADR_DMA2_STM4_BASE, DMA_CHANNEL_1,
+#else
+	TADR_DMA2_STM1_BASE, DMA_CHANNEL_0, TADR_DMA2_STM4_BASE, DMA_CHANNEL_1,
+#endif
+    7, 4, 5, 6, 3, 12, 0x06, 0x06},
+
+  {	TADR_SAI2_BASE,
+	(TADR_RCC_BASE+TOFF_RCC_AHB1ENR), RCC_AHB1ENR_GPIOIEN,
+	(TADR_RCC_BASE+TOFF_RCC_AHB1ENR), RCC_AHB1ENR_GPIOGEN,
+#ifdef TOPPERS_STM32F723_DISCOVERY
+	(TADR_RCC_BASE+TOFF_RCC_AHB1ENR), RCC_AHB1ENR_GPIOGEN,
+#else
+	(TADR_RCC_BASE+TOFF_RCC_AHB1ENR), RCC_AHB1ENR_GPIOHEN,
+#endif
+	(TADR_RCC_BASE+TOFF_RCC_AHB1ENR), RCC_AHB1ENR_DMA2EN,
+	(TADR_RCC_BASE+TOFF_RCC_AHB1ENR), RCC_AHB1ENR_DMA2EN,
+	(TADR_RCC_BASE+TOFF_RCC_APB2ENR), RCC_APB2ENR_SAI2EN,
+
+
+#ifdef TOPPERS_STM32F723_DISCOVERY
+	TADR_GPIOI_BASE, TADR_GPIOI_BASE, TADR_GPIOG_BASE, TADR_GPIOG_BASE,
+	TADR_DMA2_STM4_BASE, DMA_CHANNEL_3, TADR_DMA2_STM6_BASE, DMA_CHANNEL_3,
+#else
+	TADR_GPIOI_BASE, TADR_GPIOI_BASE, TADR_GPIOG_BASE, TADR_GPIOH_BASE,
+	TADR_DMA2_STM4_BASE, DMA_CHANNEL_3, TADR_DMA2_STM7_BASE, DMA_CHANNEL_0,
+#endif
+    4, 7, 5, 6, 10, 15, 0x0A, 0x0A}
+};
+
+static AUDIO_Handle_t  haudio_sai[NUM_AUDIOPORT];
+
+/*
+ *  SAI1割込みハンドラ
+ */
+static void
+audio_exti1_int_handler(void)
+{
+	audio_irqhandler(&haudio_sai[0]);
+}
+
+/*
+ *  SAI2割込みハンドラ
+ */
+static void
+audio_exti2_int_handler(void)
+{
+	audio_irqhandler(&haudio_sai[1]);
+}
+
+/*
+ *  SAIベースブロック取出し関数
+ */
+static uint32_t
+audio_get_blockbase(AUDIO_Handle_t *haudio, uint32_t mode)
+{
+	if(haudio == NULL || mode > 1)
+		return 0;
+	return haudio->base + mode * SAI_WINDOW_SIZE + 4;
+}
+
+/*
+ *  SAI BLOCKハードウェア起動
+ *  parameter1  haudio:AUDIOハンドラ
+ *  parameter2  mode:入出力モード
+ *  return      ERコード
+ */
+void
+audio_enable(AUDIO_Handle_t *haudio, uint32_t mode)
+{
+	uint32_t bbase = audio_get_blockbase(haudio, mode);
+
+	if(bbase == 0)
+		return;
+	sil_orw_mem((uint32_t *)(bbase+TOFF_SAI_CR1), SAI_xCR1_SAIEN);
+}
+
+
+/*
+ *  SAI BLOCKハードウェア停止
+ *  parameter1  haudio:AUDIOハンドラ
+ *  parameter2  mode:入出力モード
+ *  return      ERコード
+ */
+ER
+audio_disable(AUDIO_Handle_t *haudio, uint32_t mode)
+{
+	uint32_t tick = 0;
+	uint32_t bbase = audio_get_blockbase(haudio, mode);
+
+	if(bbase == 0)
+		return E_PAR;
+	sil_andw_mem((uint32_t *)(bbase+TOFF_SAI_CR1), SAI_xCR1_SAIEN);
+	while((sil_rew_mem((uint32_t *)(bbase+TOFF_SAI_CR1)) & SAI_xCR1_SAIEN) != 0){
+		if(tick > SAI_TIMEOUT_VALUE){	/* タイムアウト監視 */
+			haudio->ErrorCode |= AUDIO_ERROR_TIMEOUT;
+			return E_TMOUT;
+		}
+		sil_dly_nse(1000);
+		tick++;
+	}
+	return E_OK;
+}
+
+/*
+ *  AUDIOドライバ初期化関数
+ *  parammter1  id: ポートID
+ *  return      AUDIOハンドラ
+ */
+AUDIO_Handle_t *audio_init(ID id)
+{
+	static DMA_Handle_t hdma_sai_tx;
+	static DMA_Handle_t hdma_sai_rx;
+	GPIO_Init_t  gpio_init_structure;
+	const AUDIO_PortControlBlock *apcb;
+	AUDIO_Handle_t *haudio;
+	DMA_Handle_t *hdma;
+	volatile uint32_t tmpreg;
+	uint32_t no;
+
+	if(id > NUM_AUDIOPORT)
+		return NULL;
+	no = INDEX_AUDIO(id);
+	apcb = &audio_pcb[no];
+	haudio = &haudio_sai[no];
+
+	memset(haudio, 0, sizeof(AUDIO_Handle_t));
+	haudio->base = apcb->base;
+	haudio->pcb  = apcb;
+	/*
+	 *  SAIクロックイネーブル
+	 */
+	sil_orw_mem((uint32_t *)apcb->audioclockbase, apcb->audioclockbit);
+    tmpreg = sil_rew_mem((uint32_t *)apcb->audioclockbase);
+
+	/*
+	 *  OUT GPIOクロックイネーブル
+	 */
+	sil_orw_mem((uint32_t *)apcb->outgioclockbase, apcb->outgioclockbit);
+	tmpreg = sil_rew_mem((uint32_t *)apcb->outgioclockbase);
+
+	/*
+	 *  SAI FS, SCK, MCK,SDピン初期化
+	 */
+	gpio_init_structure.mode      = GPIO_MODE_AF;
+	gpio_init_structure.pull      = GPIO_NOPULL;
+	gpio_init_structure.otype     = GPIO_OTYPE_PP;
+	gpio_init_structure.speed     = GPIO_SPEED_HIGH;
+	gpio_init_structure.alternate = apcb->outaf;
+	gpio_setup(apcb->giofsobase, &gpio_init_structure, apcb->outfspin);
+
+	gpio_init_structure.alternate = apcb->outaf;
+	gpio_setup(apcb->giofsobase, &gpio_init_structure, apcb->outsckin);
+
+	gpio_init_structure.alternate =  apcb->outaf;
+	gpio_setup(apcb->giofsobase, &gpio_init_structure, apcb->outsdpin);
+
+	gpio_init_structure.alternate =  apcb->outaf;
+	gpio_setup(apcb->giomcobase, &gpio_init_structure, apcb->outmsckpin);
+
+	/*
+	 *  OUT-DMAイネーブル
+	 */
+	sil_orw_mem((uint32_t *)apcb->outdmaclockbase, apcb->outdmaclockbit);
+	tmpreg = sil_rew_mem((uint32_t *)apcb->outdmaclockbase);
+
+	hdma = &hdma_sai_tx;
+	hdma->Init.Channel             = apcb->outdmachannel;
+	hdma->Init.Direction           = DMA_MEMORY_TO_PERIPH;
+	hdma->Init.PeriphInc           = DMA_PINC_DISABLE;
+	hdma->Init.MemInc              = DMA_MINC_ENABLE;
+	hdma->Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD;
+	hdma->Init.MemDataAlignment    = DMA_MDATAALIGN_HALFWORD;
+	hdma->Init.Mode                = DMA_CIRCULAR;
+	hdma->Init.Priority            = DMA_PRIORITY_HIGH;
+	hdma->Init.FIFOMode            = DMA_FIFOMODE_ENABLE;
+	hdma->Init.FIFOThreshold       = DMA_FIFO_THRESHOLD_FULL;
+	hdma->Init.MemBurst            = DMA_MBURST_SINGLE;
+	hdma->Init.PeriphBurst         = DMA_PBURST_SINGLE;
+	hdma->base = apcb->outdmabase;
+
+	/*
+	 *  OUT-DMA設定
+	 */
+	haudio->hdmatx  = hdma;
+	hdma->localdata = haudio;
+	dma_deinit(hdma);
+	dma_init(hdma);
+
+	/*
+	 *  SD GPIOクロック設定
+	 */
+	sil_orw_mem((uint32_t *)apcb->ingioclockbase, apcb->ingioclockbit);
+	tmpreg = sil_rew_mem((uint32_t *)apcb->ingioclockbase);
+
+	/*
+	 *  SD GPIO設定
+	 */
+	gpio_init_structure.mode      = GPIO_MODE_AF;
+	gpio_init_structure.pull      = GPIO_NOPULL;
+	gpio_init_structure.otype     = GPIO_OTYPE_PP;
+	gpio_init_structure.speed     = GPIO_SPEED_FAST;
+	gpio_init_structure.alternate = apcb->inaf;
+	gpio_setup(apcb->giosdibase, &gpio_init_structure, apcb->insdpin);
+
+	/*
+	 *  AUDIO-割込みGPIOクロック設定
+	 */
+	sil_orw_mem((uint32_t *)apcb->intgioclockbase, apcb->intgioclockbit);
+	tmpreg = sil_rew_mem((uint32_t *)apcb->intgioclockbase);
+
+	/*
+	 *  AUDIO-割込みピンGPIO設定
+	 */
+	gpio_init_structure.mode      = GPIO_MODE_INPUT;
+	gpio_init_structure.pull      = GPIO_NOPULL;
+	gpio_init_structure.speed     = GPIO_SPEED_FAST;
+	gpio_setup(apcb->giointbase, &gpio_init_structure, apcb->inintpin);
+
+	/*
+	 *  IN-DMAクロック設定
+	 */
+	sil_orw_mem((uint32_t *)apcb->indmaclockbase, apcb->indmaclockbit);
+	tmpreg = sil_rew_mem((uint32_t *)apcb->indmaclockbase);
+	((void)(tmpreg));
+
+	hdma = &hdma_sai_rx;
+    hdma->Init.Channel             = apcb->indmachannel;
+    hdma->Init.Direction           = DMA_PERIPH_TO_MEMORY;
+    hdma->Init.PeriphInc           = DMA_PINC_DISABLE;
+    hdma->Init.MemInc              = DMA_MINC_ENABLE;
+    hdma->Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD;
+    hdma->Init.MemDataAlignment    = DMA_MDATAALIGN_HALFWORD;
+    hdma->Init.Mode                = DMA_CIRCULAR;
+    hdma->Init.Priority            = DMA_PRIORITY_HIGH;
+    hdma->Init.FIFOMode            = DMA_FIFOMODE_DISABLE;
+    hdma->Init.FIFOThreshold       = DMA_FIFO_THRESHOLD_FULL;
+    hdma->Init.MemBurst            = DMA_MBURST_SINGLE;
+    hdma->Init.PeriphBurst         = DMA_MBURST_SINGLE;
+    hdma->base = apcb->indmabase;
+
+#ifndef TOPPERS_STM32F769_DISCOVERY
+	/*
+	 *  IN-DMA設定
+	 */
+    haudio->hdmarx  = hdma;
+    hdma->localdata = haudio;
+    dma_deinit(hdma);
+    dma_init(hdma);
+#endif
+
+	/*
+	 * SAI割込み設定
+	 */
+	if(no == 0)
+		exti_func[apcb->inintpin] = audio_exti1_int_handler;
+	else
+		exti_func[apcb->inintpin] = audio_exti2_int_handler;
+	return haudio;
+}
+
+/*
+ *  AUDIOドライバ終了設定関数
+ *  parameter1  haudio:AUDIOハンドラ
+ *  parameter2  mode:入出力モード
+ */
+void
+audio_deinit(AUDIO_Handle_t *haudio, uint32_t mode)
+{
+	uint32_t bbase = audio_get_blockbase(haudio, mode);
+
+	if(bbase != 0 && haudio->pcb != NULL){
+		if(mode == AUDIO_OUT_BLOCK && haudio->hdmatx != NULL){
+			dma_deinit(haudio->hdmatx);	/* OUT-DMA停止 */
+		}
+		if(mode == AUDIO_IN_BLOCK && haudio->hdmarx != NULL){
+			/* Deinitialize the DMA stream */
+			dma_deinit(haudio->hdmarx);	/* IN-DMA停止 */
+		}
+
+		/*
+		 *  SAIハード、クロック停止
+		 */
+		audio_disable(haudio, mode);
+		sil_andw_mem((uint32_t *)haudio->pcb->audioclockbase, haudio->pcb->audioclockbit);
+	}
+}
+
+
+/*
+ *  AUDIO割込みフラグ取出し
+ *  parameter1  haudio:AUDIOハンドラ
+ *  parameter2  pini:初期化構造体
+ *  return      割込みフラグ
+ */
+static uint32_t
+audio_interruptflag(AUDIO_Handle_t *haudio, SAI_Init_t *pini)
+{
+	if(pini->AudioMode == SAI_MODESLAVE_RX || pini->AudioMode == SAI_MODESLAVE_TX)
+		return SAI_xIMR_OVRUDRIE | SAI_xIMR_AFSDETIE | SAI_xIMR_LFSDETIE;
+	else
+		return SAI_xIMR_OVRUDRIE | SAI_xIMR_WCKCFGIE;
+}
+
+/*
+ *  SAIの入力クロック取得
+ *  parameter1  haudio:AUDIOハンドラ
+ *  return      SAI入力クロック
+ */
+static uint32_t
+audio_get_inputclock(AUDIO_Handle_t *haudio)
+{
+	uint32_t tmp = 0;
+	uint32_t cfgr = 0;
+	/* This variable used to store the SAI clock frequency (value in Hz) */
+	uint32_t frequency = 0;
+	/* This variable used to store the VCO Input (value in Hz) */
+	uint32_t vcoinput = 0;
+	/* This variable used to store the SAI clock source */
+	uint32_t configreg   = sil_rew_mem((uint32_t *)(TADR_RCC_BASE+TOFF_RCC_PLLCFGR));
+	uint32_t clocksource = sil_rew_mem((uint32_t *)(TADR_RCC_BASE+TOFF_RCC_DCKCFGR1));
+
+    switch ((clocksource & (RCC_DCKCFGR1_SAI1SEL | RCC_DCKCFGR1_SAI2SEL))){
+    case 0: /* PLLSAI is the clock source for SAI*/ 
+		cfgr = sil_rew_mem((uint32_t *)(TADR_RCC_BASE+TOFF_RCC_PLLSAICFGR));
+        /* Configure the PLLSAI division factor */
+        /* PLLSAI_VCO Input  = PLL_SOURCE/PLLM */ 
+        if((configreg & RCC_PLLCFGR_PLLSRC) == RCC_PLLCFGR_PLLSRC_HSI){
+          /* In Case the PLL Source is HSI (Internal Clock) */
+          vcoinput = (HSI_VALUE / (uint32_t)(configreg & RCC_PLLCFGR_PLLM));
+        }
+        else{
+          /* In Case the PLL Source is HSE (External Clock) */
+          vcoinput = ((HSE_VALUE / (uint32_t)(configreg & RCC_PLLCFGR_PLLM)));
+        }
+        /* PLLSAI_VCO Output = PLLSAI_VCO Input * PLLSAIN */
+        /* SAI_CLK(first level) = PLLSAI_VCO Output/PLLSAIQ */
+        tmp = (cfgr & RCC_PLLSAICFGR_PLLSAIQ) >> 24;
+        frequency = (vcoinput * ((cfgr & RCC_PLLSAICFGR_PLLSAIN) >> 6))/(tmp);
+        
+        /* SAI_CLK_x = SAI_CLK(first level)/PLLSAIDIVQ */
+        frequency = frequency/(((clocksource & RCC_DCKCFGR1_PLLSAIDIVQ) >> 8) + 1);
+        break;
+    case RCC_DCKCFGR1_SAI1SEL_0: /* PLLI2S is the clock source for SAI*/
+    case RCC_DCKCFGR1_SAI2SEL_0: /* PLLI2S is the clock source for SAI*/
+		cfgr = sil_rew_mem((uint32_t *)(TADR_RCC_BASE+TOFF_RCC_PLLI2SCFGR));
+        /* Configure the PLLI2S division factor */
+        /* PLLI2S_VCO Input  = PLL_SOURCE/PLLM */ 
+        if((configreg & RCC_PLLCFGR_PLLSRC) == RCC_PLLCFGR_PLLSRC_HSI){
+          /* In Case the PLL Source is HSI (Internal Clock) */
+          vcoinput = (HSI_VALUE / (uint32_t)(configreg & RCC_PLLCFGR_PLLM));
+        }
+        else{
+          /* In Case the PLL Source is HSE (External Clock) */
+          vcoinput = ((HSE_VALUE / (uint32_t)(configreg & RCC_PLLCFGR_PLLM)));
+        }
+
+        /* PLLI2S_VCO Output = PLLI2S_VCO Input * PLLI2SN */
+        /* SAI_CLK(first level) = PLLI2S_VCO Output/PLLI2SQ */
+        tmp = (cfgr & RCC_PLLI2SCFGR_PLLI2SQ) >> 24;
+        frequency = (vcoinput * ((cfgr & RCC_PLLI2SCFGR_PLLI2SN) >> 6))/tmp;
+
+        /* SAI_CLK_x = SAI_CLK(first level)/PLLI2SDIVQ */
+        frequency = frequency/((clocksource & RCC_DCKCFGR1_PLLI2SDIVQ) + 1);
+        break;
+    case RCC_DCKCFGR1_SAI1SEL_1: /* External clock is the clock source for SAI*/
+    case RCC_DCKCFGR1_SAI2SEL_1: /* External clock is the clock source for SAI*/
+        frequency = EXTERNAL_CLOCK_VALUE;
+        break;
+    default :
+        break;
+    }
+	return frequency;
+}
+
+/*
+ *  SAIクロックコンフィグレーション
+ *  parameter1  haudio:AUDIOハンドラ
+ *  parameter2  AudioFreq: Audio周波数
+ *  parameter3  Params: 補助パラメータポインタ
+ */
+void
+audio_clockconfig(AUDIO_Handle_t *haudio, uint32_t AudioFreq, void *Params)
+{
+	uint32_t PLLI2SN, PLLI2SQ, PLLI2SDivQ;
+	uint32_t tick = 0;
+
+	/*
+	 *  AUDIO周波数からPLL設定値の取得
+	 */
+	if((AudioFreq == FREQUENCY_11K) || (AudioFreq == FREQUENCY_22K) || (AudioFreq == FREQUENCY_44K)){
+		/* Configure PLLI2S prescalers */
+		/* PLLI2S_VCO: VCO_429M
+		I2S_CLK(first level) = PLLI2S_VCO/PLLI2SQ = 429/2 = 214.5 Mhz
+		I2S_CLK_x = I2S_CLK(first level)/PLLI2SDIVQ = 214.5/19 = 11.289 Mhz */
+		PLLI2SN = 429;
+		PLLI2SQ = 2;
+		PLLI2SDivQ = 19;
+	}
+	else /* FREQUENCY_8K, FREQUENCY_16K, FREQUENCY_48K, FREQUENCY_96K */{
+		/* I2S clock config
+		PLLI2S_VCO: VCO_344M
+		I2S_CLK(first level) = PLLI2S_VCO/PLLI2SQ = 344/7 = 49.142 Mhz
+		I2S_CLK_x = I2S_CLK(first level)/PLLI2SDIVQ = 49.142/1 = 49.142 Mhz */
+		PLLI2SN = 344;
+		PLLI2SQ = 7;
+		PLLI2SDivQ = 1;
+	}
+
+	/*
+	 *  SAI1/2クロック設定
+	 */
+	if(haudio->base == TADR_SAI1_BASE){
+		sil_modw_mem((uint32_t *)(TADR_RCC_BASE+TOFF_RCC_DCKCFGR1), RCC_DCKCFGR1_SAI1SEL, RCC_DCKCFGR1_SAI1SEL_0);
+	}
+	else{
+		sil_modw_mem((uint32_t *)(TADR_RCC_BASE+TOFF_RCC_DCKCFGR1), RCC_DCKCFGR1_SAI2SEL, RCC_DCKCFGR1_SAI2SEL_0);
+	}
+  
+	/*
+	 *  PLLI2Sデゼーブル
+	 */
+	sil_andw_mem((uint32_t *)(TADR_RCC_BASE+TOFF_RCC_CR), RCC_CR_PLLI2SON);
+
+    /*
+	 *  PLLI2S停止待ち
+	 */
+	tick = 0;
+	while((sil_rew_mem((uint32_t *)(TADR_RCC_BASE+TOFF_RCC_CR)) & RCC_CR_PLLI2SRDY) != 0){
+		if(tick > PLLI2S_TIMEOUT_VALUE){
+			return;		/* タイムアウトエラー */
+		}
+		dly_tsk(1);
+		tick++;
+	}
+
+    /*
+	 *  PLLI2SSN/PLLI2SN値設定
+	 */
+	sil_modw_mem((uint32_t *)(TADR_RCC_BASE+TOFF_RCC_PLLI2SCFGR), (RCC_PLLI2SCFGR_PLLI2SN | RCC_PLLI2SCFGR_PLLI2SQ), ((PLLI2SN << 6) | (PLLI2SQ << 24)));
+
+	/*
+	 *  PLLI2SDIVQ設定
+	 */
+	sil_modw_mem((uint32_t *)(TADR_RCC_BASE+TOFF_RCC_DCKCFGR1), RCC_DCKCFGR1_PLLI2SDIVQ, (PLLI2SDivQ-1));
+
+	/*
+	 *  PLLI2Sイネーブル
+	 */
+	sil_orw_mem((uint32_t *)(TADR_RCC_BASE+TOFF_RCC_CR), RCC_CR_PLLI2SON);
+
+    /*
+	 *  PLLI2S再開待ち
+	 */
+	tick = 0;
+	while((sil_rew_mem((uint32_t *)(TADR_RCC_BASE+TOFF_RCC_CR)) & RCC_CR_PLLI2SRDY) == 0){
+		if(tick > PLLI2S_TIMEOUT_VALUE){
+			return;		/* タイムアウトエラー */
+		}
+		dly_tsk(1);
+		tick++;
+	}
+}
+
+/*
+ *  AUDIO動作開始関数
+ *  parameter1  haudio:AUDIOハンドラ
+ *  parameter2  mode:入出力モード
+ *  return      ERコード
+ */
+ER
+audio_start(AUDIO_Handle_t *haudio, uint32_t mode)
+{
+	ER ercd = E_OK;
+	SAI_Init_t *pini;
+	uint32_t gcr = 0;
+	uint32_t bbase = audio_get_blockbase(haudio, mode);
+
+	if(bbase == 0)
+		return E_PAR;
+
+	if(mode == AUDIO_OUT_BLOCK)
+		pini = &haudio->OutInit;
+	else
+		pini = &haudio->InInit;
+
+	/*
+	 *  SAIハードウェア停止
+	 */
+	ercd = audio_disable(haudio, mode);
+	if(ercd != E_OK)
+		return ercd;
+
+	/*
+	 *  ジェネラルコンフィグレーションレジスタ設定
+	 */
+	switch(pini->SynchroExt){
+	case SAI_SYNCEXT_DISABLE:
+		gcr = 0;
+		break;
+	case SAI_SYNCEXT_IN_ENABLE:
+		gcr = SAI_GCR_SYNCIN_0;
+		break;
+	case SAI_SYNCEXT_OUTBLOCKA_ENABLE:
+		gcr = SAI_GCR_SYNCOUT_0;
+		break;
+	case SAI_SYNCEXT_OUTBLOCKB_ENABLE:
+		gcr = SAI_GCR_SYNCOUT_1;
+		break;
+	default :
+		break;
+	}
+	sil_wrw_mem((uint32_t *)(haudio->base+TOFF_SAI_GCR), gcr);
+
+	/*
+	 *  マスタクロックデバイダ再設定
+     *  MCKDIV[3:0] = SAI_CK_x / FS * 512
+	 */
+	if(pini->AudioFrequency != 0){
+		uint32_t clock;
+
+		clock = (((audio_get_inputclock(haudio) * 10) / ((pini->AudioFrequency) * 512)));
+		pini->Mckdiv = clock / 10;
+		if((clock % 10) > 8){	/* 9を切り上げ */
+			pini->Mckdiv++;
+		}
+	}
+
+	/*
+	 *  SAI CR1設定
+	 */
+	sil_modw_mem((uint32_t *)(bbase+TOFF_SAI_CR1),
+			(SAI_xCR1_MODE | SAI_xCR1_PRTCFG |  SAI_xCR1_DS | SAI_xCR1_LSBFIRST | SAI_xCR1_CKSTR |
+			 SAI_xCR1_SYNCEN | SAI_xCR1_MONO | SAI_xCR1_OUTDRIV | SAI_xCR1_DMAEN | SAI_xCR1_NODIV | SAI_xCR1_MCKDIV),
+			(pini->AudioMode | pini->Protocol | pini->DataSize | pini->FirstBit |
+			 pini->ClockStrobing | pini->Synchro | pini->MonoStereoMode | pini->OutputDrive |
+			 pini->NoDivider | (pini->Mckdiv << 20) | pini->CompandingMode));
+
+	/*
+	 *  SAI CR2設定
+	 */
+	sil_modw_mem((uint32_t *)(bbase+TOFF_SAI_CR2),
+			(SAI_xCR2_FTH | SAI_xCR2_TRIS | SAI_xCR2_COMP),
+			(pini->FIFOThreshold | pini->CompandingMode | pini->TriState));
+
+	/*
+	 *  SAI フレーム設定
+	 */
+	sil_modw_mem((uint32_t *)(bbase+TOFF_SAI_FRCR),
+			(SAI_xFRCR_FRL | SAI_xFRCR_FSALL | SAI_xFRCR_FSDEF | SAI_xFRCR_FSPO | SAI_xFRCR_FSOFF),
+			((pini->FrameLength - 1) | pini->FSOffset | pini->FSDefinition | 
+			pini->FSPolarity | ((pini->ActiveFrameLength - 1) << 8)));
+
+	/*
+	 *  SAIブロックスロット設定
+	 */
+	sil_modw_mem((uint32_t *)(bbase+TOFF_SAI_SLOTR),
+			(SAI_xSLOTR_FBOFF | SAI_xSLOTR_SLOTSZ | SAI_xSLOTR_NBSLOT | SAI_xSLOTR_SLOTEN),
+			(pini->FirstBitOffset | pini->SlotSize | ((pini->SlotNumber - 1) <<  8)) | pini->SlotActive);
+
+	/*
+	 *  エラー設定初期化
+	 */
+	haudio->ErrorCode = AUDIO_ERROR_NONE;
+
+	/*
+	 *  ステータス設定
+	 */
+	haudio->status[mode] = AUDIO_STATUS_READY;
+	return ercd;
+}
+
+
+/*
+ *  AUDIO動作停止関数
+ *  parameter1  haudio:AUDIOハンドラ
+ *  parameter2  mode:入出力モード
+ *  return      ERコード
+ */
+ER
+audio_end(AUDIO_Handle_t *haudio, uint32_t mode)
+{
+	ER ercd = E_OK;
+	uint32_t bbase = audio_get_blockbase(haudio, mode);
+
+	if(bbase == 0)
+		return E_PAR;
+
+	/*
+	 *  割込みとフラグクリア、SAI停止
+	 */
+	sil_wrw_mem((uint32_t *)(bbase+TOFF_SAI_IMR), 0);
+	sil_wrw_mem((uint32_t *)(bbase+TOFF_SAI_CLRFR), 0xFFFFFFFF);
+	ercd = audio_disable(haudio, mode);
+
+	/*
+	 *  FIFOをフラッシュ
+	 */
+	sil_orw_mem((uint32_t *)(bbase+TOFF_SAI_CR2), SAI_xCR2_FFLUSH);
+
+	/*
+	 *  エラー設定初期化
+	 */
+	haudio->ErrorCode = AUDIO_ERROR_NONE;
+
+	/*
+	 *  ステータスをリセットに戻す
+	 */
+	haudio->status[mode] = AUDIO_STATUS_RESET;
+	return ercd;
+}
+
+/*
+ *  AUDIO 送信DMA完了コールバック関数
+ *  parameter1  hdma: DMAハンドラ
+ */
+static void
+audio_dmatx_tran(DMA_Handle_t *hdma)
+{
+	uint32_t tick = 0;
+	uint32_t bbase;
+
+	AUDIO_Handle_t* haudio = (AUDIO_Handle_t*)((DMA_Handle_t* )hdma)->localdata;
+
+	bbase = audio_get_blockbase(haudio, AUDIO_OUT_BLOCK);
+	if((sil_rew_mem((uint32_t *)(hdma->base+TOFF_DMAS_CR)) & DMA_SxCR_CIRC) == 0){
+		/*
+		 *  送信DMAを停止
+		 */
+		sil_andw_mem((uint32_t *)(bbase+TOFF_SAI_CR1), SAI_xCR1_DMAEN);
+
+		/*
+		 *  FIFOが空になるまで待ち
+		 */
+		while((sil_rew_mem((uint32_t *)(bbase+TOFF_SAI_SR)) & SAI_xSR_FLVL) != 0){
+			/* Check for the Timeout */
+			if(tick  > SAI_TIMEOUT_VALUE){
+				/*
+				 *  タイムアウトエラー設定
+				 */
+				haudio->ErrorCode |= AUDIO_ERROR_TIMEOUT;
+				if(haudio->errorcallback != NULL)
+					haudio->errorcallback(haudio);
+			}
+			tick++;
+			sil_dly_nse(1000);
+		}
+
+		/*
+		 *  エラー割込み停止
+		 */
+		sil_andw_mem((uint32_t *)(bbase+TOFF_SAI_IMR), audio_interruptflag(haudio, &haudio->OutInit));
+		haudio->status[AUDIO_OUT_BLOCK] = AUDIO_STATUS_READY;
+		haudio->XferCount = 0;
+	}
+	if(haudio->transcallback != NULL)
+		haudio->transcallback(haudio);
+}
+
+/*
+ *  AUDIO 送信DMAハーフコールバック関数
+ *  parameter1  hdma: DMAハンドラ
+ */
+static void
+audio_dmatx_halftran(DMA_Handle_t *hdma)
+{
+	AUDIO_Handle_t* haudio = (AUDIO_Handle_t*)((DMA_Handle_t*)hdma)->localdata;
+
+	if(haudio->transhalfcallback != NULL)
+		haudio->transhalfcallback(haudio);
+}
+
+/*
+ *  AUDIO 送信DMAエラーコールバック関数
+ *  parameter1  hdma: DMAハンドラ
+ */
+static void
+audio_dmatx_error(DMA_Handle_t *hdma)
+{
+	AUDIO_Handle_t* haudio = ( AUDIO_Handle_t*)((DMA_Handle_t* )hdma)->localdata;
+
+	/*
+	 *  送信DMA停止
+	 */
+	audio_dmastop(haudio, AUDIO_OUT_BLOCK);
+
+	/*
+	 *  ステータスをレディに戻す
+	 */
+	haudio->status[AUDIO_OUT_BLOCK] = AUDIO_STATUS_READY;
+	if(haudio->errorcallback != NULL)
+		haudio->errorcallback(haudio);
+	haudio->XferCount = 0;
+}
+
+/*
+ *  AUDIO 受信DMA完了コールバック関数
+ *  parameter1  hdma: DMAハンドラ
+ */
+static void
+audio_dmarx_recv(DMA_Handle_t *hdma)
+{
+	AUDIO_Handle_t* haudio = ( AUDIO_Handle_t* )((DMA_Handle_t* )hdma)->localdata;
+	uint32_t bbase;
+
+	bbase = audio_get_blockbase(haudio, AUDIO_IN_BLOCK);
+	if((sil_rew_mem((uint32_t *)(hdma->base+TOFF_DMAS_CR)) & DMA_SxCR_CIRC) == 0){
+		/*
+		 *  受信DMA停止
+		 */
+		sil_andw_mem((uint32_t *)(bbase+TOFF_SAI_CR1), SAI_xCR1_DMAEN);
+
+		/*
+		 *  エラー割込み停止
+		 */
+		sil_andw_mem((uint32_t *)(bbase+TOFF_SAI_IMR), audio_interruptflag(haudio, &haudio->InInit));
+
+		haudio->status[AUDIO_IN_BLOCK] = AUDIO_STATUS_READY;
+		haudio->XferCount = 0;
+	}
+	if(haudio->recevcallback != NULL)
+		haudio->recevcallback(haudio);
+}
+
+/*
+ *  AUDIO 受信DMAハーフコールバック関数
+ *  parameter1  hdma: DMAハンドラ
+ */
+static void
+audio_dmarx_recvhalf(DMA_Handle_t *hdma)
+{
+	AUDIO_Handle_t* haudio = (AUDIO_Handle_t*)((DMA_Handle_t*)hdma)->localdata;
+
+	if(haudio->recevhalfcallback != NULL)
+		haudio->recevhalfcallback(haudio);
+}
+
+/*
+ *  AUDIO 受信DMAエラーコールバック関数
+ *  parameter1  hdma: DMAハンドラ
+ */
+static void
+audio_dmarx_error(DMA_Handle_t *hdma)
+{
+	AUDIO_Handle_t* haudio = ( AUDIO_Handle_t* )((DMA_Handle_t* )hdma)->localdata;
+
+	/*
+	 *  受信DMA停止
+	 */
+	audio_dmastop(haudio, AUDIO_IN_BLOCK);
+
+	/*
+	 *  ステータスをレディに戻す
+	 */
+	haudio->status[AUDIO_IN_BLOCK]= AUDIO_STATUS_READY;
+	if(haudio->errorcallback != NULL)
+		haudio->errorcallback(haudio);
+	haudio->XferCount = 0;
+}
+
+
+/*
+ *  AUDIOデータ送信
+ *  parameter1  haudio:AUDIOハンドラ
+ *  parameter2  pData:送信データ領域
+ *  parameter3  Size:送信データサイズ
+ *  return      ERコード
+ */
+ER
+audio_transmit(AUDIO_Handle_t *haudio, uint8_t *pData, uint16_t Size)
+{
+	uint32_t bbase = audio_get_blockbase(haudio, AUDIO_OUT_BLOCK);
+
+	if(pData == NULL || Size == 0 || bbase == 0)
+		return E_PAR;
+
+	if(haudio->status[AUDIO_OUT_BLOCK] != AUDIO_STATUS_READY)
+		return E_OBJ;
+
+	haudio->pBuffPtr = pData;
+	haudio->XferSize = Size;
+	haudio->XferCount = Size;
+	haudio->status[AUDIO_OUT_BLOCK] = AUDIO_STATUS_BUSY_TX;
+
+	/*
+	 *  DMAコールバック関数設定
+	 */
+	haudio->hdmatx->xferhalfcallback = audio_dmatx_halftran;
+	haudio->hdmatx->xfercallback = audio_dmatx_tran;
+	haudio->hdmatx->errorcallback = audio_dmatx_error;
+
+	/*
+	 *  送信DMA起動
+	 */
+	dma_start(haudio->hdmatx, (uint32_t)pData, bbase+TOFF_SAI_DR, haudio->XferSize);
+
+	/*
+	 *  SAI起動
+	 */
+	if((sil_rew_mem((uint32_t *)(bbase+TOFF_SAI_CR1)) & SAI_xCR1_SAIEN) == 0){
+		sil_orw_mem((uint32_t *)(bbase+TOFF_SAI_CR1), SAI_xCR1_SAIEN);
+	}
+
+	/*
+	 *  エラー割込み設定
+	 */
+	sil_orw_mem((uint32_t *)(bbase+TOFF_SAI_IMR), audio_interruptflag(haudio, &haudio->OutInit));
+
+	/*
+	 *  SAI送信DMA要求
+	 */
+	sil_orw_mem((uint32_t *)(bbase+TOFF_SAI_CR1), SAI_xCR1_DMAEN);
+	return E_OK;
+}
+
+/*
+ *  AUDIOデータ受信
+ *  parameter1  haudio:AUDIOハンドラ
+ *  parameter2  pData:受信データ領域
+ *  parameter3  Size:受信データサイズ
+ *  return      ERコード
+ */
+ER
+audio_receive(AUDIO_Handle_t *haudio, uint8_t *pData, uint16_t Size)
+{
+	uint32_t bbase = audio_get_blockbase(haudio, AUDIO_IN_BLOCK);
+
+	if(pData == NULL || Size == 0 || bbase == 0)
+		return E_PAR;
+
+	if(haudio->status[AUDIO_IN_BLOCK] != AUDIO_STATUS_READY)
+		return E_OBJ;
+
+	haudio->pBuffPtr = pData;
+	haudio->XferSize = Size;
+	haudio->XferCount = Size;
+
+	haudio->status[AUDIO_IN_BLOCK] = AUDIO_STATUS_BUSY_RX;
+
+	/*
+	 *  DMAコールバック関数設定
+	 */
+	haudio->hdmarx->xferhalfcallback = audio_dmarx_recvhalf;
+	haudio->hdmarx->xfercallback = audio_dmarx_recv;
+	haudio->hdmarx->errorcallback = audio_dmarx_error;
+
+	/*
+	 *  受信DMA起動
+	 */
+	dma_start(haudio->hdmarx, bbase+TOFF_SAI_DR, (uint32_t)pData, haudio->XferSize);
+
+	/*
+	 *  SAI起動
+	 */
+	if((sil_rew_mem((uint32_t *)(bbase+TOFF_SAI_CR1)) & SAI_xCR1_SAIEN) == 0){
+		sil_orw_mem((uint32_t *)(bbase+TOFF_SAI_CR1), SAI_xCR1_SAIEN);
+	}
+
+	/*
+	 *  エラー割込み設定
+	 */
+	sil_orw_mem((uint32_t *)(bbase+TOFF_SAI_IMR), audio_interruptflag(haudio, &haudio->InInit));
+
+	/*
+	 *  SAI受信DMA要求
+	 */
+	sil_orw_mem((uint32_t *)(bbase+TOFF_SAI_CR1), SAI_xCR1_DMAEN);
+	return E_OK;
+}
+
+/*
+ *  AUDIOポーズ
+ *  parameter1  haudio:AUDIOハンドラ
+ *  parameter2  mode:入出力モード
+ *  return      ERコード
+  */
+ER
+audio_dmapause(AUDIO_Handle_t *haudio, uint32_t mode)
+{
+	uint32_t bbase = audio_get_blockbase(haudio, mode);
+
+	if(bbase == 0)
+		return E_PAR;
+	sil_andw_mem((uint32_t *)(bbase+TOFF_SAI_CR1), SAI_xCR1_DMAEN);
+	return E_OK; 
+}
+
+/*
+ *  AUDIOレジューム
+ *  parameter1  haudio:AUDIOハンドラ
+ *  parameter2  mode:入出力モード
+ *  return      ERコード
+ */
+ER
+audio_dmaresume(AUDIO_Handle_t *haudio, uint32_t mode)
+{
+	uint32_t bbase = audio_get_blockbase(haudio, mode);
+
+	if(bbase == 0)
+		return E_PAR;
+
+	/*
+	 *  SAI-DMA要求
+	 */
+	sil_orw_mem((uint32_t *)(bbase+TOFF_SAI_CR1), SAI_xCR1_DMAEN);
+
+	/*
+	 *  SAI起動
+	 */
+	if ((sil_rew_mem((uint32_t *)(bbase+TOFF_SAI_CR1)) & SAI_xCR1_SAIEN) == 0){
+		sil_orw_mem((uint32_t *)(bbase+TOFF_SAI_CR1), SAI_xCR1_SAIEN);
+	}
+	return E_OK;
+}
+
+/*
+ *  AUDIO用DMA停止
+ *  parameter1  haudio:AUDIOハンドラ
+ *  parameter2  mode:入出力モード
+ *  return      ERコード
+ */
+ER
+audio_dmastop(AUDIO_Handle_t *haudio, uint32_t mode)
+{
+	ER ercd = E_OK;
+	uint32_t bbase = audio_get_blockbase(haudio, mode);
+
+	if(bbase == 0)
+		return E_PAR;
+	/*
+	 *  SAI-DMA停止
+	 */
+	sil_andw_mem((uint32_t *)(bbase+TOFF_SAI_CR1), SAI_xCR1_DMAEN);
+
+	/*
+	 *  送信モードなら送信DMA停止
+	 */
+	if(haudio->hdmatx != NULL && mode == AUDIO_OUT_BLOCK){
+		dma_end(haudio->hdmatx);
+	}
+
+	/*
+	 *  受信モードなら受信DMA停止
+	 */
+	if(haudio->hdmarx != NULL && mode == AUDIO_IN_BLOCK){
+		dma_end(haudio->hdmarx);
+	}
+
+	/*
+	 *  SAI停止
+	 */
+	ercd = audio_disable(haudio, mode);
+
+	haudio->status[mode] = AUDIO_STATUS_READY;
+	return ercd;
+}
+
+/*
+ *  AUDIOハンドラ取出し
+ *  parameter1: id ポートID
+ */
+AUDIO_Handle_t *
+audio_gethandle(ID id)
+{
+	return &haudio_sai[INDEX_AUDIO(id)];
+}
+
+/*
+ *  AUDIOステータスの取出し
+ *  parameter1  haudio:AUDIOハンドラ
+ *  parameter2  mode:入出力モード
+ *  return      AUDIOステータス
+ */
+uint32_t
+audio_status(AUDIO_Handle_t *haudio, uint32_t mode)
+{
+	return haudio->status[mode];
+}
+
+/*
+ *  AUDIO割込みハンドラ
+ *  parameter1  haudio:AUDIOハンドラ
+ */
+void
+audio_irqhandler(AUDIO_Handle_t *haudio)
+{
+	uint32_t bbase, mode;
+    uint32_t sr, imr;
+
+	for(mode = AUDIO_OUT_BLOCK ; mode <= AUDIO_IN_BLOCK ; mode++){
+		bbase = audio_get_blockbase(haudio, mode);
+		sr = sil_rew_mem((uint32_t *)(bbase+TOFF_SAI_SR));
+		imr = sil_rew_mem((uint32_t *)(bbase+TOFF_SAI_IMR));
+
+		/*
+		 *  割込みステータス確認
+		 */
+		if(sr != 0x00000000){
+			/*
+			 *  オーバーラン/アンダーランチェック
+			 */
+			if((sr & SAI_xSR_OVRUDR) != 0 && (imr & SAI_xIMR_OVRUDRIE) != 0){
+				sil_wrw_mem((uint32_t *)(bbase+TOFF_SAI_CLRFR), SAI_xSR_OVRUDR);
+				haudio->ErrorCode = AUDIO_ERROR_OVRUDR;
+				if(haudio->audioerrorcallback != NULL)
+					haudio->audioerrorcallback(haudio, mode);
+			}
+
+			/*
+			 *  MUTE割込みチェック
+			 */
+			if((sr & SAI_xSR_MUTEDET) != 0 && (imr & SAI_xIMR_MUTEDETIE) != 0){
+				sil_wrw_mem((uint32_t *)(bbase+TOFF_SAI_CLRFR), SAI_xSR_MUTEDET);
+				if(haudio->audiomutecallback != NULL)
+					haudio->audiomutecallback(haudio, mode);
+			}
+
+			/*
+			 *  AFSDET割込みチェック
+			 */
+			if((sr & SAI_xSR_AFSDET) != 0 && (imr & SAI_xIMR_AFSDETIE) != 0){
+				haudio->ErrorCode = AUDIO_ERROR_AFSDET;
+				if(haudio->audioerrorcallback != NULL)
+					haudio->audioerrorcallback(haudio, mode);
+			}
+
+			/*
+			 *  LFSDET割込みチェック
+			 */
+			if((sr & SAI_xSR_LFSDET) != 0 && (imr & SAI_xIMR_LFSDETIE) != 0){
+				haudio->ErrorCode = AUDIO_ERROR_LFSDET;
+				if(haudio->audioerrorcallback != NULL)
+					haudio->audioerrorcallback(haudio, mode);
+			}
+
+			/*
+			 *  WCKCFG割込みチェック
+			 */
+			if((sr & SAI_xSR_WCKCFG) != 0 && (imr & SAI_xIMR_WCKCFGIE) != 0){
+				haudio->ErrorCode = AUDIO_ERROR_WCKCFG;
+				if(haudio->audioerrorcallback != NULL)
+					haudio->audioerrorcallback(haudio, mode);
+			}
+		}
+	}
+}
+
+
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/pdic/stm32f7xx/sai.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/pdic/stm32f7xx/sai.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/pdic/stm32f7xx/sai.h	(revision 457)
@@ -0,0 +1,355 @@
+/*
+ *  TOPPERS/ASP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Advanced Standard Profile Kernel
+ * 
+ *  Copyright (C) 2008-2011 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ *  Copyright (C) 2015-2016 by TOPPERS PROJECT Educational Working Group.
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+/*
+ * 
+ *  STM32F7xx SAIデバイスドライバの外部宣言
+ *
+ */
+
+#ifndef _SAI_H_
+#define _SAI_H_
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+
+/*
+ *  AUDIOポート定義
+ */
+#define AUDIO1_PORTID           1
+#define AUDIO2_PORTID           2
+#define NUM_AUDIOPORT           2
+
+/*
+ *  AUDIOハードウェア設定構造体
+ */
+typedef struct _AUDIO_PortControlBlock{
+	uint32_t                base;
+	uint32_t                outgioclockbase;
+	uint32_t                outgioclockbit;
+	uint32_t                ingioclockbase;
+	uint32_t                ingioclockbit;
+	uint32_t                intgioclockbase;
+	uint32_t                intgioclockbit;
+	uint32_t                outdmaclockbase;
+	uint32_t                outdmaclockbit;
+	uint32_t                indmaclockbase;
+	uint32_t                indmaclockbit;
+	uint32_t                audioclockbase;
+	uint32_t                audioclockbit;
+
+	uint32_t                giofsobase;
+	uint32_t                giomcobase;
+	uint32_t                giosdibase;
+	uint32_t                giointbase;
+	uint32_t                outdmabase;
+	uint32_t                outdmachannel;
+	uint32_t                indmabase;
+	uint32_t                indmachannel;
+	uint8_t                 outmsckpin;
+	uint8_t                 outfspin;
+	uint8_t                 outsckin;
+	uint8_t                 outsdpin;
+	uint8_t                 insdpin;
+	uint8_t                 inintpin;
+	uint8_t                 outaf;
+	uint8_t                 inaf;
+} AUDIO_PortControlBlock;
+
+/*
+ *  AUDIO初期化構造体 
+ */
+typedef struct {
+	uint32_t                AudioMode;			/* AUDIOモード */
+	uint32_t                Synchro;			/* SAIブロックシンクロ値 */
+	uint32_t                SynchroExt;			/* SAIブロックシンクロ拡張値 */
+	uint32_t                OutputDrive;		/* 出力デバイス */
+    uint32_t                NoDivider;			/* DIVIDER有効/無効 */
+	uint32_t                FIFOThreshold;		/* FIFOスレッシュホールド設定 */
+	uint32_t                AudioFrequency;		/* AUDIO サンプリング周波数 */
+	uint32_t                Mckdiv;				/* マスタークロックDIVIDER値 */
+	uint32_t                MonoStereoMode;		/* モノクロ/ステレオモード */
+	uint32_t                CompandingMode;		/* コンパウンディングモード */
+	uint32_t                TriState;           /* TRIStateマネージメント設定 */
+	uint32_t                Protocol;			/* SAI BLOCKプロトコル */
+	uint32_t                DataSize;			/* SAI BLOCKデータサイズ */
+	uint32_t                FirstBit;			/* MSB/LSB設定 */
+	uint32_t                ClockStrobing;		/* クロック・ストロービング設定 */
+
+	/*
+	 *  フレームデータ
+	 */
+	uint32_t                FrameLength;		/* フレーム長 */
+	uint32_t                ActiveFrameLength;	/* アクティブ・フレーム長 */
+	uint32_t                FSDefinition;		/* フレーム・シンクロナス定義 */
+	uint32_t                FSPolarity;         /* FS POLARITY設定 */
+	uint32_t                FSOffset;           /* FS OFFSET設定 */
+
+	/*
+	 *  スロット定義
+	 */
+	uint32_t                FirstBitOffset;		/* スロット中の最初のデータビット位置 */
+	uint32_t                SlotSize;			/* スロットサイズ */
+	uint32_t                SlotNumber;			/* スロット番号 */
+	uint32_t                SlotActive;			/* SLOTアクティブ設定 */
+}SAI_Init_t;
+
+/*
+ *  AUDIOハンドラ定義
+ */
+typedef struct _AUDIO_HandleStruct AUDIO_Handle_t;
+struct _AUDIO_HandleStruct
+{
+	uint32_t                base;			/* SAIデバイスのベースアドレス */
+	const AUDIO_PortControlBlock *pcb;		/* ハードウエア定義構造体へのポインタ */
+	SAI_Init_t              OutInit;		/* 出力ブロック初期設定 */
+	SAI_Init_t              InInit;			/* 入力ブロック初期設定 */
+	uint8_t                 *pBuffPtr;		/* データ領域へのポインタ */
+	uint16_t                XferSize;		/* データサイズ */
+	uint16_t                XferCount;		/* 送受信カウント */
+	DMA_Handle_t            *hdmatx;		/* 送信DMAハンドラへのポインタ */
+	DMA_Handle_t            *hdmarx;		/* 受信DMAハンドラへのポインタ */
+    void        (*audiomutecallback)(AUDIO_Handle_t *haudio, uint32_t mode); 	/* MUTEコールバック関数 */
+    void        (*audioerrorcallback)(AUDIO_Handle_t *haudio, uint32_t mode); 	/* 割込みエラーコールバック関数 */
+	void        (*transcallback)(AUDIO_Handle_t *haudio);		/* 送信終了コールバック関数 */
+	void        (*transhalfcallback)(AUDIO_Handle_t *haudio);	/* 送信終了コールバック関数 */
+	void        (*recevcallback)(AUDIO_Handle_t *haudio);		/* 受信終了コールバック関数 */
+	void        (*recevhalfcallback)(AUDIO_Handle_t *haudio);	/* 受信終了コールバック関数 */
+	void        (*errorcallback)(AUDIO_Handle_t *haudio);		/* エラーコールバック関数 */
+    volatile uint32_t       status[2];		/* AUDIOステータス */
+    volatile uint32_t       ErrorCode;		/* エラーコード */
+};
+
+
+/*
+ *  AUDIO設定モード定義
+ */
+#define AUDIO_OUT_BLOCK         0
+#define AUDIO_IN_BLOCK          1
+
+/*
+ *  AUDIOステータス定義
+ */
+#define AUDIO_STATUS_RESET      0x00		/* AUDIOデバイスリセット状態 */
+#define AUDIO_STATUS_READY      0x01		/* AUDIOデバイスレディ状態 */
+#define AUDIO_STATUS_BUSY       0x02		/* AUDIOデバイスビジィー状態 */
+#define AUDIO_STATUS_BUSY_TX    0x12		/* AUDIOデバイス送信ビジィー状態 */
+#define AUDIO_STATUS_BUSY_RX    0x22		/* AUDIOデバイス受信ビジィー状態 */
+#define AUDIO_STATUS_TIMEOUT    0x03		/* AUDIOデバイスタイムアウト状態 */
+#define AUDIO_STATUS_ERROR      0x04		/* AUDIOデバイスエラー状態 */                                                                        
+
+/*
+ *  AUDIOエラー定義
+ */
+#define AUDIO_ERROR_NONE        0x00000000		/* エラーなし */
+#define AUDIO_ERROR_OVRUDR      0x00000001		/* オーバーランまたはアンダーラン */
+#define AUDIO_ERROR_AFSDET      0x00000004		/* Anticipated Frame synchronisation detection */
+#define AUDIO_ERROR_LFSDET      0x00000008		/* Late Frame synchronisation detection        */
+#define AUDIO_ERROR_WCKCFG      0x00000010		/* Wrong clock configuration */ 
+#define AUDIO_ERROR_TIMEOUT     0x00000040		/* タイムアウト */
+
+/*
+ *  SAIブロックシンクロ拡張値(SynchroExt)
+ */
+#define SAI_SYNCEXT_DISABLE             0x00000000
+#define SAI_SYNCEXT_IN_ENABLE           0x00000001
+#define SAI_SYNCEXT_OUTBLOCKA_ENABLE    0x00000002
+#define SAI_SYNCEXT_OUTBLOCKB_ENABLE    0x00000004
+
+/*
+ *  AUDIOモード(AudioMode)
+ */
+#define SAI_MODEMASTER_TX               0x00000000
+#define SAI_MODEMASTER_RX               SAI_xCR1_MODE_0
+#define SAI_MODESLAVE_TX                SAI_xCR1_MODE_1
+#define SAI_MODESLAVE_RX                (SAI_xCR1_MODE_1 | SAI_xCR1_MODE_0)
+
+/*
+ *  SAI BLOCKプロトコル(Protocol)
+ */
+#define SAI_FREE_PROTOCOL               0x00000000
+#define SAI_SPDIF_PROTOCOL              SAI_xCR1_PRTCFG_0
+#define SAI_AC97_PROTOCOL               SAI_xCR1_PRTCFG_1
+
+/*
+ *  SAI BLOCKデータサイズ(DataSize)
+ */
+#define SAI_DATASIZE_8                  SAI_xCR1_DS_1
+#define SAI_DATASIZE_10                 (SAI_xCR1_DS_1 | SAI_xCR1_DS_0)
+#define SAI_DATASIZE_16                 SAI_xCR1_DS_2
+#define SAI_DATASIZE_20                 (SAI_xCR1_DS_2 | SAI_xCR1_DS_0)
+#define SAI_DATASIZE_24                 (SAI_xCR1_DS_2 | SAI_xCR1_DS_1)
+#define SAI_DATASIZE_32                 (SAI_xCR1_DS_2 | SAI_xCR1_DS_1 | SAI_xCR1_DS_0)
+
+/*
+ *  MSB/LSB設定(FirstBit)
+ */
+#define SAI_FIRSTBIT_MSB                0x00000000
+#define SAI_FIRSTBIT_LSB                SAI_xCR1_LSBFIRST
+
+/*
+ *  クロック・ストロービング設定(ClockStrobing)
+ */
+#define SAI_CLOCKSTROBING_FALLINGEDGE     ((uint32_t)0x00000000)
+#define SAI_CLOCKSTROBING_RISINGEDGE      ((uint32_t)SAI_xCR1_CKSTR)
+
+/*
+ *  SAIブロックシンクロ値(Synchro)
+ */
+#define SAI_ASYNCHRONOUS                0x00000000
+#define SAI_SYNCHRONOUS                 SAI_xCR1_SYNCEN_0
+#define SAI_SYNCHRONOUS_EXT             SAI_xCR1_SYNCEN_1
+
+/*
+ *  出力デバイス(OutputDrive)
+ */
+#define SAI_OUTPUTDRIVE_DISABLE         0x00000000
+#define SAI_OUTPUTDRIVE_ENABLE          SAI_xCR1_OUTDRIV
+
+/*
+ *  DIVIDER有効/無効(NoDivider)
+ */
+#define SAI_MASTERDIVIDER_ENABLE        0x00000000
+#define SAI_MASTERDIVIDER_DISABLE       SAI_xCR1_NODIV
+
+/*
+ *  フレーム・シンクロナス定義(FSDefinition)
+ */
+#define SAI_FS_STARTFRAME               0x00000000
+#define SAI_FS_CHANNEL_IDENTIFICATION   SAI_xFRCR_FSDEF
+
+/*
+ *  FS POLARITY設定(FSPolarity)
+ */
+#define SAI_FS_ACTIVE_LOW               0x00000000
+#define SAI_FS_ACTIVE_HIGH              SAI_xFRCR_FSPO
+
+/*
+ *  FS OFFSET設定(FSOffset)
+ */
+#define SAI_FS_FIRSTBIT                 0x00000000
+#define SAI_FS_BEFOREFIRSTBIT           SAI_xFRCR_FSOFF
+
+/*
+ *  SLOTサイズ設定(SlotSize)
+ */
+#define SAI_SLOTSIZE_DATASIZE           0x00000000
+#define SAI_SLOTSIZE_16B                SAI_xSLOTR_SLOTSZ_0
+#define SAI_SLOTSIZE_32B                SAI_xSLOTR_SLOTSZ_1
+
+/*
+ *  SLOTアクティブ設定(SlotActive)
+ */
+#define SAI_SLOT_NOTACTIVE              0x00000000
+#define SAI_SLOTACTIVE_0                0x00010000
+#define SAI_SLOTACTIVE_1                0x00020000
+#define SAI_SLOTACTIVE_2                0x00040000
+#define SAI_SLOTACTIVE_3                0x00080000
+#define SAI_SLOTACTIVE_4                0x00100000
+#define SAI_SLOTACTIVE_5                0x00200000
+#define SAI_SLOTACTIVE_6                0x00400000
+#define SAI_SLOTACTIVE_7                0x00800000
+#define SAI_SLOTACTIVE_8                0x01000000
+#define SAI_SLOTACTIVE_9                0x02000000
+#define SAI_SLOTACTIVE_10               0x04000000
+#define SAI_SLOTACTIVE_11               0x08000000
+#define SAI_SLOTACTIVE_12               0x10000000
+#define SAI_SLOTACTIVE_13               0x20000000
+#define SAI_SLOTACTIVE_14               0x40000000
+#define SAI_SLOTACTIVE_15               0x80000000
+#define SAI_SLOTACTIVE_ALL              0xFFFF0000
+
+/*
+ *  モノクロ/ステレオモード(MonoStereoMode)
+ */
+#define SAI_STEREOMODE                  0x00000000
+#define SAI_MONOMODE                    SAI_xCR1_MONO
+
+/*
+ *  TRIStateマネージメント設定(TriState)
+ */
+#define SAI_OUTPUT_NOTRELEASED          0x00000000
+#define SAI_OUTPUT_RELEASED             SAI_xCR2_TRIS
+
+/*
+ *  FIFOスレシュホールド設定(FIFOThreshold)
+ */
+#define SAI_FIFOTHRESHOLD_EMPTY         0x00000000
+#define SAI_FIFOTHRESHOLD_1QF           SAI_xCR2_FTH_0
+#define SAI_FIFOTHRESHOLD_HF            SAI_xCR2_FTH_1
+#define SAI_FIFOTHRESHOLD_3QF           (SAI_xCR2_FTH_1 | SAI_xCR2_FTH_0)
+#define SAI_FIFOTHRESHOLD_FULL          SAI_xCR2_FTH_2
+
+/*
+ *  コンパウンディングモード設定(CompandingMode)
+ */
+#define SAI_NOCOMPANDING                0x00000000
+#define SAI_ULAW_1CPL_COMPANDING        SAI_xCR2_COMP_1
+#define SAI_ALAW_1CPL_COMPANDING        (SAI_xCR2_COMP_1 | SAI_xCR2_COMP_0)
+#define SAI_ULAW_2CPL_COMPANDING        (SAI_xCR2_COMP_1 | SAI_xCR2_CPL)
+#define SAI_ALAW_2CPL_COMPANDING        (SAI_xCR2_COMP_1 | SAI_xCR2_COMP_0 | SAI_xCR2_CPL)
+
+
+extern AUDIO_Handle_t *audio_init(ID id);
+extern void audio_deinit(AUDIO_Handle_t *haudio, uint32_t mode);
+extern void audio_clockconfig(AUDIO_Handle_t *haudio, uint32_t AudioFreq, void *Params);
+
+extern ER audio_start(AUDIO_Handle_t *haudio, uint32_t mode);
+extern ER audio_end(AUDIO_Handle_t *haudio, uint32_t mode);
+extern ER audio_transmit(AUDIO_Handle_t *haudio, uint8_t *pData, uint16_t Size);
+extern ER audio_receive(AUDIO_Handle_t *haudio, uint8_t *pData, uint16_t Size);
+
+extern ER audio_dmapause(AUDIO_Handle_t *haudio, uint32_t mode);
+extern ER audio_dmaresume(AUDIO_Handle_t *haudio, uint32_t mode);
+extern ER audio_dmastop(AUDIO_Handle_t *haudio, uint32_t mode);
+extern void audio_enable(AUDIO_Handle_t *haudio, uint32_t mode);
+extern ER audio_disable(AUDIO_Handle_t *haudio, uint32_t mode);
+extern AUDIO_Handle_t *audio_gethandle(ID id);
+extern uint32_t audio_status(AUDIO_Handle_t *haudio, uint32_t mode);
+extern void audio_irqhandler(AUDIO_Handle_t *haudio);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif	/* _SAI_H_ */
+
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/pdic/stm32f7xx/sdmmc.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/pdic/stm32f7xx/sdmmc.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/pdic/stm32f7xx/sdmmc.c	(revision 457)
@@ -0,0 +1,1434 @@
+/*
+ *  TOPPERS/ASP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Advanced Standard Profile Kernel
+ * 
+ *  Copyright (C) 2008-2011 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ *  Copyright (C) 2015-2016 by TOPPERS PROJECT Educational Working Group.
+ * 
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+/*
+ *  STM32F746用 SDMMCドライバ
+ */
+#include "kernel_impl.h"
+#include <t_syslog.h>
+#include <t_stdlib.h>
+#include <sil.h>
+#include <target_syssvc.h>
+#include "kernel_cfg.h"
+#include "device.h"
+#include "sdmmc.h"
+
+#define sil_orw_mem(a, b)		sil_wrw_mem((a), sil_rew_mem(a) | (b))
+#define sil_andw_mem(a, b)		sil_wrw_mem((a), sil_rew_mem(a) & ~(b))
+#define sil_modw_mem(a, b, c)	sil_wrw_mem((a), (sil_rew_mem(a) & (~b)) | (c))
+
+#ifdef TOPPERS_STM32F769_DISCOVERY
+#define TADR_SDMMC_BASE         TADR_SDMMC2_BASE
+#define GPIO_AF10_SDMMC2        0x0A	/* SDMMC2 Alternate Function mapping */
+#define GPIO_AF11_SDMMC2        0x0B	/* SDMMC2 Alternate Function mapping */
+#define RCC_APB2ENR_SDMMCEN     RCC_APB2ENR_SDMMC2EN
+#define SD_DETECT_CLOCK         RCC_AHB1ENR_GPIOIEN
+#define SD_DETECT_PORT          TADR_GPIOI_BASE
+#define SD_DETECT_PIN           15
+#define TADR_DMA_RX             TADR_DMA2_STM0_BASE
+#define TADR_DMA_TX             TADR_DMA2_STM5_BASE
+#define DMA_RX_CHANNEL          DMA_CHANNEL_11
+#define DMA_TX_CHANNEL          DMA_CHANNEL_11
+
+#else
+#define TADR_SDMMC_BASE         TADR_SDMMC1_BASE
+#define GPIO_AF12_SDMMC1        0x0C	/* SDMMC1 Alternate Function mapping */
+#define RCC_APB2ENR_SDMMCEN     RCC_APB2ENR_SDIOEN
+#define SD_DETECT_CLOCK         RCC_AHB1ENR_GPIOCEN
+#define SD_DETECT_PORT          TADR_GPIOC_BASE
+#define SD_DETECT_PIN           13
+#define TADR_DMA_RX             TADR_DMA2_STM3_BASE
+#define TADR_DMA_TX             TADR_DMA2_STM6_BASE
+#define DMA_RX_CHANNEL          DMA_CHANNEL_4
+#define DMA_TX_CHANNEL          DMA_CHANNEL_4
+
+#endif
+
+
+#define CLKCR_CLEAR_MASK                ((SDMMC_CLKCR_CLKDIV  | SDMMC_CLKCR_PWRSAV |\
+                                          SDMMC_CLKCR_BYPASS  | SDMMC_CLKCR_WIDBUS |\
+                                          SDMMC_CLKCR_NEGEDGE | SDMMC_CLKCR_HWFC_EN))
+/* --- DCTRL Register ---*/
+/* SDMMC DCTRL Clear Mask */
+#define DCTRL_CLEAR_MASK                ((SDMMC_DCTRL_DTEN    | SDMMC_DCTRL_DTDIR |\
+                                          SDMMC_DCTRL_DTMODE  | SDMMC_DCTRL_DBLOCKSIZE))
+
+/* --- CMD Register ---*/
+/* CMD Register clear mask */
+#define CMD_CLEAR_MASK                  ((SDMMC_CMD_CMDINDEX | SDMMC_CMD_WAITRESP |\
+                                          SDMMC_CMD_WAITINT  | SDMMC_CMD_WAITPEND |\
+                                          SDMMC_CMD_CPSMEN   | SDMMC_CMD_SDIOSUSPEND))
+
+/*
+ *  SDMMCデータブロック長
+ */
+#define DATA_BLOCK_SIZE                 (9 << 4)
+
+/*
+ *  SDMMCでスタックに使用するフラグ
+ */
+#define SDMMC_STATIC_FLAGS              (SDMMC_STA_CCRCFAIL | SDMMC_STA_DCRCFAIL | SDMMC_STA_CTIMEOUT |\
+                                         SDMMC_STA_DTIMEOUT | SDMMC_STA_TXUNDERR | SDMMC_STA_RXOVERR  |\
+                                         SDMMC_STA_CMDREND  | SDMMC_STA_CMDSENT  | SDMMC_STA_DATAEND  |\
+                                         SDMMC_STA_DBCKEND)
+
+/*
+ *  RESPONSE1エラー値
+ */
+#define SD_OCR_ERROR                    0xFDFFE008
+
+/*
+ *  RESPONSE6エラー値
+ */
+#define SD_R6_GENERAL_UNKNOWN_ERROR     0x00002000
+#define SD_R6_ILLEGAL_CMD               0x00004000
+#define SD_R6_COM_CRC_FAILED            0x00008000
+
+#define SDMMC_WAIT_STATUS               (SDMMC_STA_CCRCFAIL | SDMMC_STA_CMDREND | SDMMC_STA_CTIMEOUT)
+#define SDMMC_INT1_ERROR                (SDMMC_STA_DCRCFAIL | SDMMC_STA_DTIMEOUT | SDMMC_STA_RXOVERR)
+#define SDMMC_INT2_ERROR                (SDMMC_INT1_ERROR | SDMMC_STA_TXUNDERR)
+#define SDMMC_INT_MASK                  (SDMMC_INT2_ERROR | SDMMC_STA_DATAEND | SDMMC_STA_TXFIFOHE | SDMMC_STA_RXFIFOHF)
+
+/*
+ *  カードタイプ定義
+ */
+#define SD_HIGH_CAPACITY                0x40000000
+#define SD_STD_CAPACITY                 0x00000000
+
+/*
+ *  SCRのビット定義
+ */
+#define SD_WIDE_BUS_SUPPORT             0x00040000
+#define SD_SINGLE_BUS_SUPPORT           0x00010000
+#define SD_CARD_LOCKED                  0x02000000
+
+/*
+ *  CSDのクラスサポート定義
+ */
+#define SD_CCCC_LOCK_UNLOCK             0x00000080
+#define SD_CCCC_WRITE_PROT              0x00000040
+#define SD_CCCC_ERASE                   0x00000020
+
+#define SD_MAX_VOLT_TRIAL               0x0000FFFF
+#define SDMMC_CMD0TIMEOUT               (5000*1000)
+
+
+static ER sdmmc_sendcommand(SDMMC_Handle_t *hsd, uint32_t cmd, uint32_t arg, ER (*func)(SDMMC_Handle_t *, uint32_t));
+
+static ER sdmmc_checkrep1(SDMMC_Handle_t *hsd, uint32_t Cmd);
+static ER sdmmc_checkrep2(SDMMC_Handle_t *hsd, uint32_t Cmd);
+static ER sdmmc_checkrep3(SDMMC_Handle_t *hsd, uint32_t Cmd);
+static ER sdmmc_checkrep6(SDMMC_Handle_t *hsd, uint32_t Cmd);
+static ER sdmmc_command_wait(SDMMC_Handle_t *hsd);
+
+static ER sdmmc_enable_widebus(SDMMC_Handle_t *hsd);
+static ER sdmmc_disable_widebus(SDMMC_Handle_t *hsd);
+static ER sdmmc_getSCR(SDMMC_Handle_t *hsd, uint32_t *pSCR);
+static ER sdmmc_getpstate(SDMMC_Handle_t *hsd, uint8_t *pStatus);
+
+static SDMMC_Handle_t SdHandle;
+
+/*
+ * SDMMC 受信DMAコールバック関数
+ */
+static void
+sdmmc_rxdma_callback(DMA_Handle_t *hdma)
+{
+	isig_sem(SDMMC_SEM);
+}
+
+/*
+ * SDMMC 送信DMAコールバック関数
+ */
+static void
+sdmmc_txdma_callback(DMA_Handle_t *hdma)
+{
+	isig_sem(SDMMC_SEM);
+}
+
+
+/*
+ *  SDMMC初期化
+ *  parameter1  addr: Pointer to SDMMC register base
+ */
+void
+sdmmc_init(intptr_t exinf)
+{
+	GPIO_Init_t GPIO_Init_Data;
+	volatile unsigned long tmp;
+
+	/* AHB1ENRクロックイネーブル */
+	sil_orw_mem((uint32_t *)(TADR_RCC_BASE+TOFF_RCC_AHB1ENR), SD_DETECT_CLOCK);
+#ifdef TOPPERS_STM32F769_DISCOVERY
+	sil_orw_mem((uint32_t *)(TADR_RCC_BASE+TOFF_RCC_AHB1ENR), RCC_AHB1ENR_GPIOBEN | RCC_AHB1ENR_GPIODEN | RCC_AHB1ENR_GPIOGEN);
+#else
+	sil_orw_mem((uint32_t *)(TADR_RCC_BASE+TOFF_RCC_AHB1ENR), RCC_AHB1ENR_GPIOCEN | RCC_AHB1ENR_GPIODEN);
+#endif
+	tmp = sil_rew_mem((uint32_t *)(TADR_RCC_BASE+TOFF_RCC_AHB1ENR));
+	sil_orw_mem((uint32_t *)(TADR_RCC_BASE+TOFF_RCC_AHB1ENR), RCC_AHB1ENR_DMA2EN);
+	tmp = sil_rew_mem((uint32_t *)(TADR_RCC_BASE+TOFF_RCC_AHB1ENR));
+
+	GPIO_Init_Data.mode      = GPIO_MODE_INPUT;
+	GPIO_Init_Data.pull      = GPIO_PULLUP;
+	GPIO_Init_Data.speed     = GPIO_SPEED_HIGH;
+	gpio_setup(SD_DETECT_PORT, &GPIO_Init_Data, SD_DETECT_PIN);
+
+	/* SDIOクロックイネーブル */
+	sil_orw_mem((uint32_t *)(TADR_RCC_BASE+TOFF_RCC_APB2ENR), RCC_APB2ENR_SDMMCEN);
+	tmp = sil_rew_mem((uint32_t *)(TADR_RCC_BASE+TOFF_RCC_APB2ENR));
+	(void)(tmp);
+
+	GPIO_Init_Data.mode      = GPIO_MODE_AF;
+	GPIO_Init_Data.pull      = GPIO_PULLUP;
+	GPIO_Init_Data.otype     = GPIO_OTYPE_PP;
+	GPIO_Init_Data.speed     = GPIO_SPEED_HIGH;
+#ifdef TOPPERS_STM32F769_DISCOVERY
+	GPIO_Init_Data.alternate = GPIO_AF10_SDMMC2;
+	gpio_setup(TADR_GPIOB_BASE, &GPIO_Init_Data, 3);
+	gpio_setup(TADR_GPIOB_BASE, &GPIO_Init_Data, 4);
+	GPIO_Init_Data.alternate = GPIO_AF11_SDMMC2;
+	gpio_setup(TADR_GPIOD_BASE, &GPIO_Init_Data, 6);
+	gpio_setup(TADR_GPIOD_BASE, &GPIO_Init_Data, 7);
+	gpio_setup(TADR_GPIOG_BASE, &GPIO_Init_Data, 9);
+	gpio_setup(TADR_GPIOG_BASE, &GPIO_Init_Data, 10);
+#else
+	GPIO_Init_Data.alternate = GPIO_AF12_SDMMC1;
+	gpio_setup(TADR_GPIOC_BASE, &GPIO_Init_Data, 8);
+	gpio_setup(TADR_GPIOC_BASE, &GPIO_Init_Data, 9);
+	gpio_setup(TADR_GPIOC_BASE, &GPIO_Init_Data, 10);
+	gpio_setup(TADR_GPIOC_BASE, &GPIO_Init_Data, 11);
+	gpio_setup(TADR_GPIOC_BASE, &GPIO_Init_Data, 12);
+	gpio_setup(TADR_GPIOD_BASE, &GPIO_Init_Data, 2);
+#endif
+}
+
+/*
+ *  SDカード有無チェック
+ */
+bool_t
+sdmmc_sense(int id)
+{
+	if((sil_rew_mem((uint32_t *)(SD_DETECT_PORT+TOFF_GPIO_IDR)) & (1<<SD_DETECT_PIN)) != 0)
+		return false;
+	else
+		return true;
+}
+
+/*
+ *  SDMMCオープン
+ */
+SDMMC_Handle_t*
+sdmmc_open(int id)
+{
+	static DMA_Handle_t dma_rx_handle;
+	static DMA_Handle_t dma_tx_handle;
+	ER       ercd = E_OK;
+	SDMMC_Handle_t *hsd = &SdHandle;
+	uint32_t response = 0, count = 0, validvoltage = 0;
+	uint32_t sdtype = SD_STD_CAPACITY;
+	int      timeout;
+
+	hsd->base       = TADR_SDMMC_BASE;
+	hsd->ClockMode  = SDMMC_TRANSFER_CLK_DIV;
+	hsd->BusWide    = SDMMC_BUS_WIDE_4B;
+	hsd->RetryCount = 32;
+	/*
+	 *  初期設定、BUS WIDEは１ビット
+	 */
+	sil_modw_mem((uint32_t *)(hsd->base+TOFF_SDIO_CLKCR), CLKCR_CLEAR_MASK, (SDMMC_INIT_CLK_DIV | SDMMC_BUS_WIDE_1B));
+
+	/*
+	 *  SDMMCクロック停止後、電源オンし、１秒後クロック再開
+	 */
+	sil_andw_mem((uint32_t *)(hsd->base+TOFF_SDIO_CLKCR), SDMMC_CLKCR_CLKEN);
+	sil_wrw_mem((uint32_t *)(hsd->base+TOFF_SDIO_POWER), SDMMC_POWER_PWRCTRL);
+
+	/*  1MSの待ち */
+	dly_tsk(1);
+	sil_orw_mem((uint32_t *)(hsd->base+TOFF_SDIO_CLKCR), SDMMC_CLKCR_CLKEN);
+
+	/*
+	 *  CMD0: GO IDLE STATE
+	 */
+	sdmmc_sendcommand(hsd, MCI_CMD0, 0, NULL);
+
+	/*  コマンドステート終了待ち */
+	timeout = 5000;
+	while((timeout > 0) && ((sil_rew_mem((uint32_t *)(hsd->base+TOFF_SDIO_STA)) & SDMMC_STA_CMDSENT) == 0)){
+		dly_tsk(1);
+		timeout--;
+	}
+	if(timeout == 0){
+		return NULL;
+	}
+
+	/* ステートフラグをクリア */
+	sil_wrw_mem((uint32_t *)(hsd->base+TOFF_SDIO_ICR), SDMMC_STATIC_FLAGS);
+
+	/*
+	 *  CMD8: SEND IF COND
+	 */
+	sdmmc_sendcommand(hsd, MCI_CMD8, 0x000001AA, NULL);
+	ercd = sdmmc_command_wait(hsd);
+	if(ercd != E_OK || ((sil_rew_mem((uint32_t *)(hsd->base+TOFF_SDIO_STA)) & SDMMC_STA_CTIMEOUT) != 0)){
+		/*
+		 * タイムアウトならタイムアウトをクリア
+		 */
+		sil_wrw_mem((uint32_t *)(hsd->base+TOFF_SDIO_ICR), SDMMC_STA_CTIMEOUT);
+	}
+	else if((sil_rew_mem((uint32_t *)(hsd->base+TOFF_SDIO_STA)) & SDMMC_STA_CMDREND) != 0){
+		/*
+		 *  レスポンスエンドならSDCARDV2.0確定
+		 */
+		sil_wrw_mem((uint32_t *)(hsd->base+TOFF_SDIO_ICR), SDMMC_STA_CMDREND);
+		hsd->cardtype = SD_CARD_V20; 
+		sdtype        = SD_HIGH_CAPACITY;
+	}
+
+	/*
+	 * CMD55を送信
+	 */
+	ercd = sdmmc_sendcommand(hsd, MCI_CMD55, 0, sdmmc_checkrep1);
+	if(ercd == E_OK){
+		/*
+		 *  SDCARD確定:VOLTAGEの確認
+		 */
+		while(validvoltage == 0 && count < SD_MAX_VOLT_TRIAL){
+			/* SEND CMD55 APP_CMD with RCA as 0 */
+			ercd = sdmmc_sendcommand(hsd, MCI_CMD55, 0, sdmmc_checkrep1);
+			if(ercd != E_OK){
+				return NULL;
+			}
+			/*
+			 * 引数0x8010000でCMD41を送信
+			 */
+			ercd = sdmmc_sendcommand(hsd, MCI_ACMD41, (0x80100000 | sdtype), sdmmc_checkrep3);
+			if(ercd != E_OK){
+				return NULL;
+			}
+			/*
+			 * レスポンスから制御ボルテージを取得
+			 */
+			response = sil_rew_mem((uint32_t *)(hsd->base+TOFF_SDIO_RESP));
+			validvoltage = (((response >> 31) == 1) ? 1 : 0);
+			count++;
+		}
+		if(count >= SD_MAX_VOLT_TRIAL){
+			return NULL;
+		}
+
+		if((response & SD_HIGH_CAPACITY) == SD_HIGH_CAPACITY){
+			/*
+			 *  HC-SDCARD確定
+			 */
+			hsd->cardtype = SD_CARD_HC;
+		}
+	}
+
+	/*
+	 *  受信DMAのコンフィギュレーション
+	 */
+	dma_rx_handle.Init.Channel             = DMA_RX_CHANNEL;
+	dma_rx_handle.Init.Direction           = DMA_PERIPH_TO_MEMORY;
+	dma_rx_handle.Init.PeriphInc           = DMA_PINC_DISABLE;
+	dma_rx_handle.Init.MemInc              = DMA_MINC_ENABLE;
+	dma_rx_handle.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD;
+	dma_rx_handle.Init.MemDataAlignment    = DMA_MDATAALIGN_BYTE;
+	dma_rx_handle.Init.Mode                = DMA_PFCTRL;
+	dma_rx_handle.Init.Priority            = DMA_PRIORITY_VERY_HIGH;
+	dma_rx_handle.Init.FIFOMode            = DMA_FIFOMODE_ENABLE;
+	dma_rx_handle.Init.FIFOThreshold       = DMA_FIFO_THRESHOLD_FULL;
+	dma_rx_handle.Init.MemBurst            = DMA_MBURST_INC4;
+	dma_rx_handle.Init.PeriphBurst         = DMA_PBURST_INC4;
+	dma_rx_handle.base = TADR_DMA_RX;
+
+	/*
+	 *  受信DMAハンドルの設定
+	 */
+	hsd->hdmarx = &dma_rx_handle;
+	dma_deinit(&dma_rx_handle);
+	dma_init(&dma_rx_handle);
+
+	/*
+	 *  送信DMAのコンフィギュレーション
+	 */
+	dma_tx_handle.Init.Channel             = DMA_TX_CHANNEL;
+	dma_tx_handle.Init.Direction           = DMA_MEMORY_TO_PERIPH;
+	dma_tx_handle.Init.PeriphInc           = DMA_PINC_DISABLE;
+	dma_tx_handle.Init.MemInc              = DMA_MINC_ENABLE;
+	dma_tx_handle.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD;
+	dma_tx_handle.Init.MemDataAlignment    = DMA_MDATAALIGN_BYTE;
+	dma_tx_handle.Init.Mode                = DMA_PFCTRL;
+	dma_tx_handle.Init.Priority            = DMA_PRIORITY_VERY_HIGH;
+	dma_tx_handle.Init.FIFOMode            = DMA_FIFOMODE_ENABLE;
+	dma_tx_handle.Init.FIFOThreshold       = DMA_FIFO_THRESHOLD_FULL;
+	dma_tx_handle.Init.MemBurst            = DMA_MBURST_INC4;
+	dma_tx_handle.Init.PeriphBurst         = DMA_PBURST_INC4;
+	dma_tx_handle.base = TADR_DMA_TX;
+
+	/*
+	 *  送信DMAハンドルの設定
+	 */
+	hsd->hdmatx = &dma_tx_handle;
+	dma_deinit(&dma_tx_handle);
+	dma_init(&dma_tx_handle); 
+  	return hsd;
+}
+
+/*
+ *  SDMMCクローズ
+ */
+ER
+sdmmc_close(SDMMC_Handle_t *hsd)
+{
+	if(hsd == NULL)
+		return E_PAR;
+
+	/* SDの電源オフ */ 
+	sil_wrw_mem((uint32_t *)(hsd->base+TOFF_SDIO_POWER), 0x00000000);
+	hsd->status = 3;
+	return E_OK;
+}
+
+/*
+ *  SDMMCカードイレーズ
+ *  parameter1  hsd: SDMMCハンドラ
+ *  parameter2  startaddr: スタートバイト位置
+ *  parameter3  endaddr: エンドバイト位置
+ *  return :ERコード
+ */
+ER
+sdmmc_erase(SDMMC_Handle_t *hsd, uint64_t startaddr, uint64_t endaddr)
+{
+	ER ercd = E_OK;
+	uint32_t delay = 0;
+	volatile uint32_t maxdelay = 0;
+	uint8_t cardstate = 0;
+
+	if(hsd == NULL)
+		return E_PAR;
+
+	/*
+	 *  イレーズコマンド有り無し判定
+	 */
+	if(((hsd->CSD[1] >> 20) & SD_CCCC_ERASE) == 0){
+		return E_OBJ;
+	}
+
+	/*
+	 *  コマンド受付待ちカウント取得
+	 */
+	maxdelay = 120000 / (((sil_rew_mem((uint32_t *)(hsd->base+TOFF_SDIO_CLKCR))) & 0xFF) + 2);
+
+	if((sil_rew_mem((uint32_t *)(hsd->base+TOFF_SDIO_RESP)) & SD_CARD_LOCKED) == SD_CARD_LOCKED){
+		return E_OBJ;
+	}
+
+	/*
+	 *  HC SDCARDの設定アドレス補正
+	 */
+	if(hsd->cardtype == SD_CARD_HC){
+		startaddr /= 512;
+		endaddr   /= 512;
+	}
+
+	/* According to sd-card spec 1.0 ERASE_GROUP_START (CMD32) and erase_group_end(CMD33) */
+	if(hsd->cardtype == SD_CARD_V11 || hsd->cardtype == SD_CARD_V20 || hsd->cardtype == SD_CARD_HC){
+		/* Send CMD32 SD_ERASE_GRP_START with argument as addr  */
+		ercd = sdmmc_sendcommand(hsd, MCI_CMD32, (uint32_t)startaddr, sdmmc_checkrep1);
+		if (ercd != E_OK){
+			return ercd;
+		}
+
+		/* Send CMD33 SD_ERASE_GRP_END with argument as addr  */
+		ercd = sdmmc_sendcommand(hsd, MCI_CMD33, (uint32_t)endaddr, sdmmc_checkrep1);
+		if(ercd != E_OK){
+			return ercd;
+		}
+	}
+
+	/*
+	 *  CMD38 ERASE送信
+	 */
+	ercd = sdmmc_sendcommand(hsd, MCI_CMD38, 0, sdmmc_checkrep1);
+	if(ercd != E_OK){
+		return ercd;
+	}
+
+	for (; delay < maxdelay; delay++){
+	}
+
+	/*
+	 *  プログラミング終了待ち
+	 */
+	ercd = sdmmc_getpstate(hsd, &cardstate);
+	delay = 120*1000;
+	while(delay > 0 && ercd == E_OK && ((cardstate == SD_CARD_PROGRAMMING) || (cardstate == SD_CARD_RECEIVING))){
+		ercd = sdmmc_getpstate(hsd, &cardstate);
+		dly_tsk(1);
+		delay--;
+	}
+	return ercd;
+}
+
+/*
+ *  SDMMCブロックREAD
+ *  parameter1  hsd: SDMMCハンドラ
+ *  parameter2  pbuf: 読み出しデータ格納領域のポインタ(uint32_t型)
+ *  parameter3  ReadAddr: カード上の読み出し位置
+ *  parameter4  blocksize: ブロックサイズ
+ *  parameter5  num: 読み出しブロック数
+ *  return      ERコード
+ */
+ER
+sdmmc_blockread(SDMMC_Handle_t *hsd, uint32_t *pbuf, uint64_t ReadAddr, uint32_t blocksize, uint32_t num)
+{
+	ER ercd = E_OK;
+
+	if(hsd == NULL)
+		return E_PAR;
+
+	/*
+	 *  データコントロールレジスタをクリア
+	 */
+	sil_wrw_mem((uint32_t *)(hsd->base+TOFF_SDIO_DCTRL), 0);
+
+	/*
+	 *  ステートをクリア
+	 */
+	hsd->status  = 0;
+
+	/*
+	 *  リードコマンド選択
+	 */
+	if(num > 1)
+		hsd->SdCmd = MCI_CMD18;
+	else
+		hsd->SdCmd = MCI_CMD17;
+
+	/*
+	 *  転送割込み設定
+	 */
+	sil_orw_mem((uint32_t *)(hsd->base+TOFF_SDIO_MASK), (SDMMC_INT1_ERROR | SDMMC_STA_DATAEND));
+
+	/*
+	 *  DMA転送設定
+	 */
+	sil_orw_mem((uint32_t *)(hsd->base+TOFF_SDIO_DCTRL), SDMMC_DCTRL_DMAEN);
+
+	/*
+	 *  コールバック関数設定
+	 */
+	hsd->hdmarx->xfercallback  = sdmmc_rxdma_callback;
+	hsd->hdmarx->errorcallback = NULL;
+
+	/*
+	 *  受信DMAスタート
+	 */
+	if(((uint32_t)pbuf) < 0x40000000)
+		flushinvalidatedcache_by_addr((uint8_t *)pbuf, (blocksize * num));
+	dma_start(hsd->hdmarx, hsd->base+TOFF_SDIO_FIFO, (uint32_t)pbuf, (uint32_t)(blocksize * num)/4);
+	if(hsd->cardtype == SD_CARD_HC){
+		blocksize = 512;
+		ReadAddr /= 512;
+	}
+
+	/*
+	 *  CMD16:ブロックサイズ設定
+	 */
+	ercd = sdmmc_sendcommand(hsd, MCI_CMD16, (uint32_t)blocksize, sdmmc_checkrep1);
+	if(ercd != E_OK){
+		return ercd;
+	}
+
+	/*
+	 *  SD-DPSMを設定
+	 */
+	sil_wrw_mem((uint32_t *)(hsd->base+TOFF_SDIO_DTIMER), 0xFFFFFFFF);
+	sil_wrw_mem((uint32_t *)(hsd->base+TOFF_SDIO_DLEN), blocksize * num);
+	sil_modw_mem((uint32_t *)(hsd->base+TOFF_SDIO_DCTRL), DCTRL_CLEAR_MASK,
+				(SDMMC_DBSIZE_512B | SDMMC_DCTRL_DTDIR | SDMMC_DCTRL_DTEN));
+
+	/*
+	 *  READコマンド送信
+	 */
+	ercd = sdmmc_sendcommand(hsd, hsd->SdCmd, (uint32_t)ReadAddr, sdmmc_checkrep1);
+
+	/*
+	 *  送信エラーならエラー設定をする
+	 */
+	if (ercd != E_OK){
+		hsd->status = 2;
+	}
+	return ercd;
+}
+
+/*
+ *  SDMMCブロックWRITE
+ *  parameter1  hsd: SDMMCハンドラ
+ *  parameter2  pbuf: 書込みデータ格納領域のポインタ(uint32_t型)
+ *  parameter3  WritedAddr: カード上の書き込み位置
+ *  parameter4  blocksize: ブロックサイズ
+ *  parameter5  num: 書込みブロック数
+ *  return      ERコード
+ */
+ER
+sdmmc_blockwrite(SDMMC_Handle_t *hsd, uint32_t *pbuf, uint64_t WriteAddr, uint32_t blocksize, uint32_t num)
+{
+	ER       ercd = E_OK;
+
+	if(hsd == NULL)
+		return E_PAR;
+
+	/*
+	 *  データコントロールレジスタをクリア
+	 */
+	sil_wrw_mem((uint32_t *)(hsd->base+TOFF_SDIO_DCTRL), 0);
+
+	/*
+	 *  ステートをクリア
+	 */
+	hsd->status = 0;
+
+	/*
+	 *  ライトコマンド選択
+	 */
+	if(num > 1)
+		hsd->SdCmd = MCI_CMD25;
+	else
+		hsd->SdCmd = MCI_CMD24;
+
+	/*
+	 *  転送割込み設定
+	 */
+	sil_orw_mem((uint32_t *)(hsd->base+TOFF_SDIO_MASK), (SDMMC_INT2_ERROR | SDMMC_STA_DATAEND));
+
+	/*
+	 *  コールバック関数設定
+	 */
+	hsd->hdmatx->xfercallback  = sdmmc_txdma_callback;
+	hsd->hdmatx->errorcallback = NULL;
+
+	/*
+	 *  送信DMAスタート
+	 */
+	if(((uint32_t)pbuf) < 0x40000000)
+		flushinvalidatedcache_by_addr((uint8_t *)pbuf, (blocksize * num));
+	dma_start(hsd->hdmatx, (uint32_t)pbuf, hsd->base+TOFF_SDIO_FIFO, (uint32_t)(blocksize * num)/4);
+	if(hsd->cardtype == SD_CARD_HC){
+		blocksize = 512;
+		WriteAddr /= 512;
+	}
+
+	/*
+	 *  DMA転送設定
+	 */
+	sil_orw_mem((uint32_t *)(hsd->base+TOFF_SDIO_DCTRL), SDMMC_DCTRL_DMAEN);
+
+	/*
+	 *  CMD16:ブロックサイズ設定
+	 */
+	ercd = sdmmc_sendcommand(hsd, MCI_CMD16, (uint32_t)blocksize, sdmmc_checkrep1);
+	if(ercd != E_OK){
+		return ercd;
+	}
+
+	/*
+	 *  WRITEコマンド送信
+	 */
+	ercd = sdmmc_sendcommand(hsd, hsd->SdCmd, (uint32_t)WriteAddr, sdmmc_checkrep1);
+	if(ercd != E_OK){
+		return ercd;
+	}
+
+	/*
+	 *  SD-DPSMを設定
+	 */
+	sil_wrw_mem((uint32_t *)(hsd->base+TOFF_SDIO_DTIMER), 0xFFFFFFFF);
+	sil_wrw_mem((uint32_t *)(hsd->base+TOFF_SDIO_DLEN), blocksize * num);
+	sil_modw_mem((uint32_t *)(hsd->base+TOFF_SDIO_DCTRL), DCTRL_CLEAR_MASK,
+					(SDMMC_DBSIZE_512B | SDMMC_DCTRL_DTEN));
+
+	/*
+	 *  送信エラーならエラー設定をする
+	 */
+	if(ercd != E_OK){
+		hsd->status = 2;
+	}
+	return ercd;
+}
+
+/*
+ *  SDMMCブロック転送終了待ち
+ *  parameter1  hsd: SDMMCハンドラ
+ *  parameter2  Timeout: タイムアウト値(1msec)
+ *  return      ERコード
+ */
+ER
+sdmmc_wait_transfar(SDMMC_Handle_t *hsd, uint32_t Timeout)
+{
+	DMA_Handle_t *hdma = hsd->hdmarx;
+	ER           tercd = E_OK, ercd = E_OK;
+	int          timeout;
+	uint32_t     tmp1, tmp2;
+
+	if(hsd == NULL)
+		return E_PAR;
+
+	if(Timeout > 60*1000);
+		Timeout = 60*1000;
+	timeout = Timeout;
+	/*
+	 *  DMA/SD転送の終了割込み待ち
+	 */
+	tmp1 = hdma->status;
+	tmp2 = hsd->status;
+
+	while((tmp1 == DMA_STATUS_BUSY || tmp2 == 0) && timeout > 0){
+		tmp1 = hdma->status;
+		tmp2 = hsd->status;
+		twai_sem(SDMMC_SEM, 10);
+		timeout -= 10;
+	}
+
+	timeout = Timeout;
+	if(hsd->status != 1){
+		ercd = hsd->status;
+	}
+
+	if(hsd->SdCmd == MCI_CMD18 || hsd->SdCmd == MCI_CMD17){	/* 読み出し処理待ち */
+		dma_end(hsd->hdmarx);
+		/*
+		 *  受信ACTオフ待ち
+		 */
+		while((sil_rew_mem((uint32_t *)(hsd->base+TOFF_SDIO_STA)) & SDMMC_STA_RXACT) != 0 && timeout > 0){
+			dly_tsk(1);
+			timeout--;  
+		}
+
+		/*
+		 *  マルチブロック転送ならCMD12を送信
+		 */
+		if(hsd->SdCmd == MCI_CMD18){
+			tercd = sdmmc_sendcommand(hsd, MCI_CMD12, 0, sdmmc_checkrep1);
+		}
+		if(ercd == E_OK)
+			ercd = tercd;
+		if(timeout == 0 && ercd == E_OK)
+			ercd = E_TMOUT;
+
+		/*
+		 *  転送フラグをクリア
+		 */
+		sil_wrw_mem((uint32_t *)(hsd->base+TOFF_SDIO_ICR), SDMMC_STATIC_FLAGS);
+	}
+	else{	/* 書き込み待ち処理 */
+		dma_end(hsd->hdmatx);
+		/*
+		 *  送信ACTオフ待ち
+		 */
+		while((sil_rew_mem((uint32_t *)(hsd->base+TOFF_SDIO_STA)) & SDMMC_STA_TXACT) != 0 && timeout > 0){
+			dly_tsk(1);
+			timeout--;
+		}
+
+		/*
+		 *  マルチブロック転送ならCMD12を送信
+		 */
+		if(hsd->SdCmd == MCI_CMD25){
+			tercd = sdmmc_sendcommand(hsd, MCI_CMD12, 0, sdmmc_checkrep1);
+		}
+		if(ercd == E_OK)
+			ercd = tercd;
+		if(timeout == 0 && ercd == E_OK)
+			ercd = E_TMOUT;
+
+		/*
+		 *  転送フラグをクリア
+		 */
+		sil_wrw_mem((uint32_t *)(hsd->base+TOFF_SDIO_ICR), SDMMC_STATIC_FLAGS);
+
+		/*
+		 *  送信終了待ち
+		 */
+		while(sdmmc_getstatus(hsd) != SD_TRANSFER_OK){
+			dly_tsk(1);
+		}
+	}
+	return ercd;
+}
+
+/*
+ *  SDカード割込みテストルーチン
+ *  parameter1  hsd: SDMMCハンドラ
+ */
+void
+sdmmc_checkint(SDMMC_Handle_t *hsd)
+{
+	uint32_t status = sil_rew_mem((uint32_t *)(hsd->base+TOFF_SDIO_STA));
+
+	/* データエンドを検証 */
+	if((status & SDMMC_STA_DATAEND) != 0){
+		sil_wrw_mem((uint32_t *)(hsd->base+TOFF_SDIO_ICR), SDMMC_STA_DATAEND);
+		hsd->status = 1;	/* 終了番号をセット */
+	}
+	else if((status & SDMMC_INT2_ERROR) != 0){
+ 		sil_wrw_mem((uint32_t *)(hsd->base+TOFF_SDIO_ICR), (status & SDMMC_INT2_ERROR));
+		hsd->status = E_SDTRS;
+	}
+
+	/* 割込みをマスク */
+	sil_andw_mem((uint32_t *)(hsd->base+TOFF_SDIO_MASK), SDMMC_INT_MASK);
+}
+
+
+/*
+ *  SDカードの情報を取り込む
+ *  parameter1  hsd: SDMMCハンドラ
+ *  parameter2  pCardInfo: カードインフォ構造体へのポインタ
+ *  return      ERコード
+ */
+ER
+sdmmc_getcardinfo(SDMMC_Handle_t *hsd, SDMMC_CardInfo_t *pCardInfo)
+{
+	ER ercd = E_OK;
+	uint32_t devicesize;
+	uint8_t  blocklen, mul;
+
+	pCardInfo->cardtype = (uint8_t)(hsd->cardtype);
+	pCardInfo->RCA      = (uint16_t)(hsd->RCA);
+
+	if(hsd->cardtype == SD_CARD_V11 || hsd->cardtype == SD_CARD_V20){
+		/* ブロック長を取り込む */
+		blocklen       = (uint8_t)((hsd->CSD[1] & 0x000F0000) >> 16);
+		devicesize = (hsd->CSD[1] & 0x000003FF) << 2;
+		devicesize |= (hsd->CSD[2] & 0xC0000000) >> 30;
+		mul = (hsd->CSD[2] & 0x00038000) >> 15;
+		pCardInfo->capacity  = (devicesize + 1) ;
+		pCardInfo->capacity *= (1 << (mul + 2));
+		pCardInfo->blocksize = 1 << (blocklen);
+		pCardInfo->capacity *= pCardInfo->blocksize;
+	}
+	else if(hsd->cardtype == SD_CARD_HC){
+		devicesize = (hsd->CSD[1] & 0x0000003F) << 16;
+		devicesize |= (hsd->CSD[2] & 0xFFFF0000) >> 16;
+		pCardInfo->capacity  = (uint64_t)(devicesize + 1) << 19 /* 512 * 1024*/;
+		pCardInfo->blocksize = 512;
+	}
+	else{
+		pCardInfo->capacity  = 0;
+		pCardInfo->blocksize = 512;
+		ercd = E_OBJ;
+	}
+	pCardInfo->maxsector = pCardInfo->capacity / 512;
+	pCardInfo->status    = (uint8_t)((hsd->CSD[3] >> 8) & 0xff);
+#if 1	/* ROI DEBUG */
+	syslog_1(LOG_NOTICE, "## status[%02x] ##", pCardInfo->status);
+	syslog_5(LOG_NOTICE, "## cardtype(%d) capacity[%08x%08x] blocksize(%d) maxsector(%u) ##", pCardInfo->cardtype, (uint32_t)(pCardInfo->capacity>>32), (uint32_t)(pCardInfo->capacity & 0xffffffff), pCardInfo->blocksize, pCardInfo->maxsector);
+#endif	/* ROI DEBUG */
+	return ercd;
+}
+
+/*
+ *  WIDE BUS設定
+ *  parameter1  hsd: SDMMCハンドラ
+ *  return      ERコード
+ */
+ER
+sdmmc_set_widebus(SDMMC_Handle_t *hsd)
+{
+	ER ercd = E_OK;
+
+	/* MMC Card does not support this feature */
+	if(hsd->cardtype == MMC_CARD){
+		return E_PAR;
+	}
+	else if(hsd->cardtype == SD_CARD_V11 || hsd->cardtype == SD_CARD_V20 || hsd->cardtype == SD_CARD_HC){
+		if(hsd->BusWide == SDMMC_BUS_WIDE_8B)
+			ercd = E_NOSPT;
+		else if(hsd->BusWide == SDMMC_BUS_WIDE_4B)
+			ercd = sdmmc_enable_widebus(hsd);
+		else if(hsd->BusWide == SDMMC_BUS_WIDE_1B)
+			ercd = sdmmc_disable_widebus(hsd);
+		else
+			ercd = E_PAR;
+		if(ercd == E_OK){
+			/*
+			 *  最終ペリフェラル設定
+			 */
+			sil_modw_mem((uint32_t *)(hsd->base+TOFF_SDIO_CLKCR), CLKCR_CLEAR_MASK, ((hsd->ClockMode | hsd->BusWide)));
+		}
+	}
+	return ercd;
+}
+
+/*
+ *  CIDの取得
+ *  SDカードCMD2,MMCカードCMD1送信後のレスポンス受信
+ *  parameter1  hsd: SDMMCハンドラ
+ *  return      ERコード
+ */
+ER
+sdmmc_checkCID(SDMMC_Handle_t *hsd)
+{
+	ER  ercd = E_OK;
+	int i;
+
+	if((sil_rew_mem((uint32_t *)(hsd->base+TOFF_SDIO_POWER)) & SDMMC_POWER_PWRCTRL) == 0){
+    	return E_OBJ;
+	}
+
+	if(hsd->cardtype == SD_IO_CARD)
+		return E_OK;
+	for(i = 0 ; i < hsd->RetryCount ; i++){
+	    /*
+		 *  CMD2送信
+		 */
+		ercd = sdmmc_sendcommand(hsd, MCI_CMD2, 0, sdmmc_checkrep2);
+		if(ercd == E_OK){
+			/*
+			 *  CID取り込み
+			 */
+			hsd->CID[0] = sil_rew_mem((uint32_t *)(hsd->base+TOFF_SDIO_RESP));
+			hsd->CID[1] = sil_rew_mem((uint32_t *)(hsd->base+TOFF_SDIO_RESP2));
+			hsd->CID[2] = sil_rew_mem((uint32_t *)(hsd->base+TOFF_SDIO_RESP3));
+			hsd->CID[3] = sil_rew_mem((uint32_t *)(hsd->base+TOFF_SDIO_RESP4));
+			return E_OK;
+		}
+		sil_dly_nse(2000);
+	}
+	return ercd;
+}
+
+/*
+ *  相対アドレス(RCA)の取得
+ *  parameter1  hsd: SDMMCハンドラ
+ *  return      ERコード
+ */
+ER
+sdmmc_setaddress(SDMMC_Handle_t *hsd)
+{
+	ER       ercd = E_OK;
+	int i;
+
+	if(hsd->cardtype == SD_CARD_V11 || hsd->cardtype == SD_CARD_V20 ||
+		hsd->cardtype == SD_IO_COMBO_CARD || hsd->cardtype == SD_CARD_HC){
+
+		for(i = 0 ; i < hsd->RetryCount ; i++){
+			/*
+			 *  CMD3送信、RCA受信
+			 */
+			ercd = sdmmc_sendcommand(hsd, MCI_CMD3, 0, sdmmc_checkrep6);
+		    if(ercd == E_OK)
+				return E_OK;
+			sil_dly_nse(2000);
+		}
+		return E_TMOUT;
+	}
+    hsd->RCA = 1;
+	return ercd;
+}
+
+/*
+ *  CSD(Card Specific DATA)の取得
+ *  parameter1  hsd: SDMMCハンドラ
+ *  return      ERコード
+ */
+ER
+sdmmc_sendCSD(SDMMC_Handle_t *hsd)
+{
+	ER  ercd = E_OK;
+	int i;
+
+	if(hsd->cardtype == SD_IO_CARD)
+		return E_OK;
+	for(i = 0 ; i < hsd->RetryCount ; i++){
+		/*
+		 *  CMD9送信、CSD要求
+		 */
+		ercd = sdmmc_sendcommand(hsd, MCI_CMD9, (uint32_t)(hsd->RCA << 16), sdmmc_checkrep2);
+		if(ercd == E_OK){
+			/*
+			 *  CSD取得
+			 */
+			hsd->CSD[0] = sil_rew_mem((uint32_t *)(hsd->base+TOFF_SDIO_RESP));
+			hsd->CSD[1] = sil_rew_mem((uint32_t *)(hsd->base+TOFF_SDIO_RESP2));
+			hsd->CSD[2] = sil_rew_mem((uint32_t *)(hsd->base+TOFF_SDIO_RESP3));
+			hsd->CSD[3] = sil_rew_mem((uint32_t *)(hsd->base+TOFF_SDIO_RESP4));
+			return E_OK;
+		}
+		sil_dly_nse(2000);
+	}
+	return ercd;
+}
+
+/*
+ *  SELECT_CARDコマンドの送信
+ *  parameter1  hsd: SDMMCハンドラ
+ *  return      ERコード
+ */
+ER
+sdmmc_select_card(SDMMC_Handle_t *hsd, uint64_t addr)
+{
+	ER  ercd = E_OK;
+	int i;
+
+	for(i = 0 ; i < hsd->RetryCount ; i++){
+		/*
+		 *  CMD7送信 カードセレクト
+		 */
+		ercd = sdmmc_sendcommand(hsd, MCI_CMD7, (uint32_t)addr, sdmmc_checkrep1);
+		if(ercd == E_OK)
+			return E_OK;
+		sil_dly_nse(2000);
+	}
+	return ercd;
+}
+
+/*
+ *  SDMMCコンフィギュレーション
+ *  parameter1  hsd: SDMMCハンドラ
+ *  return      ERコード
+ */
+ER
+sdmmc_configuration(SDMMC_Handle_t *hsd)
+{
+	/*
+	 *  最終コンフィギュレーション
+	 */
+	sil_modw_mem((uint32_t *)(hsd->base+TOFF_SDIO_CLKCR), CLKCR_CLEAR_MASK, ((hsd->ClockMode | SDMMC_BUS_WIDE_1B)));
+	return E_OK;
+}
+
+/*
+ *  SDカードステートを取得
+ *  parameter1  hsd: SDMMCハンドラ
+ *  return      カードステート
+ */
+uint32_t
+sdmmc_getstatus(SDMMC_Handle_t *hsd)
+{
+	ER ercd = E_OK;
+	uint32_t resp1 = 0;
+	uint32_t cardstate = SD_CARD_TRANSFER;
+
+	/*
+	 *  CMD13送信
+	 */
+	ercd = sdmmc_sendcommand(hsd, MCI_CMD13, (uint32_t)(hsd->RCA << 16), sdmmc_checkrep1);
+	if(ercd != E_OK){
+		return ercd;
+	}
+
+	/*
+	 *  SDカードステータス取り込み
+	 */
+	resp1 = sil_rew_mem((uint32_t *)(hsd->base+TOFF_SDIO_RESP));
+	cardstate = ((resp1 >> 9) & 0x0F);
+
+	/*
+	 *  カードステータスをカードステートに変換
+	 */
+	if(cardstate == SD_CARD_TRANSFER){
+		return SD_TRANSFER_OK;
+	}
+	else if(cardstate == SD_CARD_ERROR){
+		return SD_TRANSFER_ERROR;
+	}
+	else{
+		return SD_TRANSFER_BUSY;
+	}
+}
+
+/*
+ *  WIDE BUSモード設定
+ */
+static ER
+sdmmc_enable_widebus(SDMMC_Handle_t *hsd)
+{
+	ER ercd = E_OK;
+	uint32_t scr[2];
+
+	if((sil_rew_mem((uint32_t *)(hsd->base+TOFF_SDIO_RESP)) & SD_CARD_LOCKED) == SD_CARD_LOCKED){
+		return E_OBJ;
+	}
+	dly_tsk(1);
+
+	/* Get SCR Register */
+	ercd = sdmmc_getSCR(hsd, scr);
+	if(ercd != E_OK){
+		return ercd;
+	}
+
+	/*
+	 *  WIDE BUS設定処理
+	 */
+	if((scr[1] & SD_WIDE_BUS_SUPPORT) != 0){
+		/*
+		 *  CMD55送信(APPEDコマンド要求
+		 */
+		ercd = sdmmc_sendcommand(hsd, MCI_CMD55, (uint32_t)(hsd->RCA << 16), sdmmc_checkrep1);
+		if(ercd != E_OK){
+			return ercd;
+		}
+
+		/*
+		 *  WIDE BUS設定でACMD6コマンド送信
+		 */
+		ercd = sdmmc_sendcommand(hsd, MCI_ACMD6, 2, sdmmc_checkrep1);
+		return ercd;
+	}
+ 	return E_OBJ;
+}
+
+/*
+ *  WIDE BUSモード停止
+ */
+static ER
+sdmmc_disable_widebus(SDMMC_Handle_t *hsd)
+{
+	ER ercd = E_OK;
+	uint32_t scr[2];
+
+	if((sil_rew_mem((uint32_t *)(hsd->base+TOFF_SDIO_RESP)) & SD_CARD_LOCKED) == SD_CARD_LOCKED){
+		return E_SYS;
+	}
+	dly_tsk(1);
+
+	/* Get SCR Register */
+	ercd = sdmmc_getSCR(hsd, scr);
+	if(ercd != E_OK){
+		return ercd;
+	}
+
+	/*
+	 *  1ビットバス設定処理
+	 */
+	if((scr[1] & SD_SINGLE_BUS_SUPPORT) != 0){
+		/*
+		 *  CMD55送信(APPEDコマンド要求
+		 */
+		ercd = sdmmc_sendcommand(hsd, MCI_CMD55, (uint32_t)(hsd->RCA << 16), sdmmc_checkrep1);
+		if(ercd != E_OK){
+			return ercd;
+		}
+
+		/*
+		 *  1 BIT BUS設定でACMD6コマンド送信
+		 */
+		ercd = sdmmc_sendcommand(hsd, MCI_ACMD6, 0, sdmmc_checkrep1);
+		return ercd;
+	}
+    return E_OBJ;
+}
+
+/*
+ *  SCRの取得
+ */
+static ER
+sdmmc_getSCR(SDMMC_Handle_t *hsd, uint32_t *pSCR)
+{
+	ER ercd = E_OK;
+	uint32_t index = 0;
+	uint32_t recvdata[2];
+
+	/*
+	 * 8バイトブロックサイズ設定
+	 */
+	ercd = sdmmc_sendcommand(hsd, MCI_CMD16, 8, sdmmc_checkrep1);
+	if(ercd != E_OK){
+		return ercd;
+	}
+
+	/*
+	 *  CMD55送信(APPEDコマンド要求
+	 */
+	ercd = sdmmc_sendcommand(hsd, MCI_CMD55, (uint32_t)((hsd->RCA) << 16), sdmmc_checkrep1);
+	if(ercd != E_OK){
+		return ercd;
+	}
+	sil_wrw_mem((uint32_t *)(hsd->base+TOFF_SDIO_DTIMER),0xFFFFFFFF);
+	sil_wrw_mem((uint32_t *)(hsd->base+TOFF_SDIO_DLEN), 8);
+	sil_modw_mem((uint32_t *)(hsd->base+TOFF_SDIO_DCTRL), DCTRL_CLEAR_MASK,
+				(SDMMC_DBSIZE_8B | SDMMC_DCTRL_DTDIR | SDMMC_DCTRL_DTEN));
+  
+	/*
+	 *  ACMD51送信、SCR要求
+	 */
+	ercd = sdmmc_sendcommand(hsd, MCI_ACMD51, 0, sdmmc_checkrep1);
+	if(ercd != E_OK){
+		return ercd;
+	}
+
+	while((sil_rew_mem((uint32_t *)(hsd->base+TOFF_SDIO_STA)) & (SDMMC_INT1_ERROR | SDMMC_STA_DBCKEND)) == 0){
+		if((sil_rew_mem((uint32_t *)(hsd->base+TOFF_SDIO_STA)) & SDMMC_STA_RXDAVL) != 0){
+			*(recvdata + index) = sil_rew_mem((uint32_t *)(hsd->base+TOFF_SDIO_FIFO));
+			index++;
+		}
+	}
+
+	if((sil_rew_mem((uint32_t *)(hsd->base+TOFF_SDIO_STA)) & SDMMC_STA_DTIMEOUT) != 0){
+		sil_wrw_mem((uint32_t *)(hsd->base+TOFF_SDIO_ICR), SDMMC_STA_DTIMEOUT);
+		return E_TMOUT;
+	}
+	else if((sil_rew_mem((uint32_t *)(hsd->base+TOFF_SDIO_STA)) & SDMMC_STA_DCRCFAIL) != 0){
+		sil_wrw_mem((uint32_t *)(hsd->base+TOFF_SDIO_ICR), SDMMC_STA_DCRCFAIL);
+		return E_SDCRC;
+	}
+	else if((sil_rew_mem((uint32_t *)(hsd->base+TOFF_SDIO_STA)) & SDMMC_STA_RXOVERR) != 0){
+		sil_wrw_mem((uint32_t *)(hsd->base+TOFF_SDIO_ICR), SDMMC_STA_RXOVERR);
+    	return E_SDTRS;
+	}
+	/*
+	 *  スタティック・フラグをクリア
+	 */
+	sil_wrw_mem((uint32_t *)(hsd->base+TOFF_SDIO_ICR), SDMMC_STATIC_FLAGS);
+
+	*(pSCR + 1) = ((recvdata[0] & 0x000000FF) << 24)  | ((recvdata[0] & 0x0000FF00) << 8) |
+		((recvdata[0] & 0x00FF0000) >> 8) | ((recvdata[0] & 0xFF000000) >> 24);
+
+	*(pSCR) = ((recvdata[1] & 0x000000FF) << 24)  | ((recvdata[1] & 0x0000FF00) << 8) |
+		((recvdata[1] & 0x00FF0000) >> 8) | ((recvdata[1] & 0xFF000000) >> 24);
+	return E_OK;
+}
+
+/*
+ *  プログラミングステートを取り出す
+ */
+static
+ER sdmmc_getpstate(SDMMC_Handle_t *hsd, uint8_t *pStatus)
+{
+	volatile uint32_t respValue = 0;
+	ER  ercd;
+
+	sdmmc_sendcommand(hsd, MCI_CMD13, (uint32_t)(hsd->RCA << 16), NULL);
+	ercd = sdmmc_command_wait(hsd);
+	if(ercd != E_OK){
+		return ercd;
+	}
+	if((sil_rew_mem((uint32_t *)(hsd->base+TOFF_SDIO_STA)) & SDMMC_STA_CTIMEOUT) != 0){
+		sil_wrw_mem((uint32_t *)(hsd->base+TOFF_SDIO_ICR), SDMMC_STA_CTIMEOUT);
+		return E_TMOUT;
+	}
+	else if((sil_rew_mem((uint32_t *)(hsd->base+TOFF_SDIO_STA)) & SDMMC_STA_CCRCFAIL) != 0){
+		sil_wrw_mem((uint32_t *)(hsd->base+TOFF_SDIO_ICR), SDMMC_STA_CCRCFAIL);
+		return E_SDCRC;
+	}
+	else{	/* エラーなし */
+		/*
+		 *  レスポンス・コマンド・インデックスの確認
+		 */
+		if((uint8_t)sil_rew_mem((uint32_t *)(hsd->base+TOFF_SDIO_RESPCMD)) != (MCI_CMD13 & CMD_INDEX)){
+			return E_SDECMD;
+		}
+ 
+		/*
+		 *  スタティック・フラグをクリア
+	 	 */
+		sil_wrw_mem((uint32_t *)(hsd->base+TOFF_SDIO_ICR), SDMMC_STATIC_FLAGS);
+
+		/*
+		 *  レスポンス１を取得
+		 */
+		respValue = sil_rew_mem((uint32_t *)(hsd->base+TOFF_SDIO_RESP));
+
+		/*
+		 *  カードステータスを取り出す
+		 */
+		*pStatus = (uint8_t)((respValue >> 9) & 0x0000000F);
+
+		/*
+		 *  レスポンス１のエラーチェック
+	 	 */
+		if((respValue & SD_OCR_ERROR) == 0)
+			return E_OK;
+		else
+			return E_SYS;
+	}
+}
+
+/*
+ *  SDMMC割込みハンドラ
+ */
+void sdmmc_handler(void)
+{
+	sdmmc_checkint(&SdHandle);
+	isig_sem(SDMMC_SEM);
+}
+
+
+/*
+ * SDMMCコマンド送信
+ */
+static ER
+sdmmc_sendcommand(SDMMC_Handle_t *hsd, uint32_t cmd, uint32_t arg, ER (*func)(SDMMC_Handle_t *, uint32_t))
+{
+	uint32_t addr = hsd->base;
+
+	sil_wrw_mem((uint32_t *)(addr+TOFF_SDIO_ARG), arg);
+	sil_modw_mem((uint32_t *)(addr+TOFF_SDIO_CMD), CMD_CLEAR_MASK, ((cmd & CMD_MASK) | SDMMC_CMD_CPSMEN));
+	if(func != NULL){
+		ER ercd = sdmmc_command_wait(hsd);
+		if(ercd != E_OK){
+			return ercd;
+		}
+		if((sil_rew_mem((uint32_t *)(hsd->base+TOFF_SDIO_STA)) & SDMMC_STA_CTIMEOUT) != 0){
+			sil_wrw_mem((uint32_t *)(hsd->base+TOFF_SDIO_ICR), SDMMC_STA_CTIMEOUT);
+			return E_TMOUT;
+		}
+		return func(hsd, cmd);
+	}
+	else
+		return E_OK;
+}
+
+/*
+ *  R1レスポンス
+ */
+static ER
+sdmmc_checkrep1(SDMMC_Handle_t *hsd, uint32_t Cmd)
+{
+	uint32_t respValue;
+
+	if((sil_rew_mem((uint32_t *)(hsd->base+TOFF_SDIO_STA)) & SDMMC_STA_CCRCFAIL) != 0){
+		sil_wrw_mem((uint32_t *)(hsd->base+TOFF_SDIO_ICR), SDMMC_STA_CCRCFAIL);
+		return E_SDCRC;
+	}
+
+	/*
+	 *  レスポンス・コマンド・インデックス確認
+	 */
+	if((uint8_t)sil_rew_mem((uint32_t *)(hsd->base+TOFF_SDIO_RESPCMD)) != (Cmd & CMD_INDEX) && (Cmd & CMD_IGNOREIRES) == 0){
+		return E_SDECMD;
+	}
+
+	/*
+	 *  スタティック・フラグをクリア
+	 */
+	sil_wrw_mem((uint32_t *)(hsd->base+TOFF_SDIO_ICR), SDMMC_STATIC_FLAGS);
+
+	/*
+	 *  レスポンス１のエラーチェック
+	 */
+	respValue = sil_rew_mem((uint32_t *)(hsd->base+TOFF_SDIO_RESP));
+	if((respValue & SD_OCR_ERROR) == 0)
+		return E_OK;
+	else
+		return E_SDCOM;
+}
+
+/*
+ *  R2レスポンス
+ */
+static ER
+sdmmc_checkrep2(SDMMC_Handle_t *hsd, uint32_t Cmd)
+{
+	if((sil_rew_mem((uint32_t *)(hsd->base+TOFF_SDIO_STA)) & SDMMC_STA_CCRCFAIL) != 0){
+		sil_wrw_mem((uint32_t *)(hsd->base+TOFF_SDIO_ICR), SDMMC_STA_CCRCFAIL);
+		return E_SDCRC;
+	}
+	sil_wrw_mem((uint32_t *)(hsd->base+TOFF_SDIO_ICR), SDMMC_STATIC_FLAGS);
+	return E_OK;
+}
+
+/*
+ *  R3レスポンス
+ */
+static ER
+sdmmc_checkrep3(SDMMC_Handle_t *hsd, uint32_t Cmd)
+{
+	sil_wrw_mem((uint32_t *)(hsd->base+TOFF_SDIO_ICR), SDMMC_STATIC_FLAGS);
+	return E_OK;
+}
+
+/*
+ *  R6レスポンス
+ */
+static ER
+sdmmc_checkrep6(SDMMC_Handle_t *hsd, uint32_t Cmd)
+{
+	uint32_t respValue;
+
+	if((sil_rew_mem((uint32_t *)(hsd->base+TOFF_SDIO_STA)) & SDMMC_STA_CCRCFAIL) != 0){
+		sil_wrw_mem((uint32_t *)(hsd->base+TOFF_SDIO_ICR), SDMMC_STA_CCRCFAIL);
+		return E_SDCRC;
+	}
+
+	/*
+	 *  レスポンス・コマンド・インデックス確認
+	 */
+	if((uint8_t)sil_rew_mem((uint32_t *)(hsd->base+TOFF_SDIO_RESPCMD)) != (Cmd & CMD_INDEX)){
+		return E_SDECMD;
+	}
+	sil_wrw_mem((uint32_t *)(hsd->base+TOFF_SDIO_ICR), SDMMC_STATIC_FLAGS);
+
+	/*
+	 *  レスポンス１の確認
+	 */
+	respValue = sil_rew_mem((uint32_t *)(hsd->base+TOFF_SDIO_RESP));
+	if((respValue & SD_R6_GENERAL_UNKNOWN_ERROR) == SD_R6_GENERAL_UNKNOWN_ERROR){
+		return E_OBJ;
+	}
+	if((respValue & SD_R6_ILLEGAL_CMD) == SD_R6_ILLEGAL_CMD){
+		return E_SDECMD;
+	}
+	if((respValue & SD_R6_COM_CRC_FAILED) == SD_R6_COM_CRC_FAILED){
+		return E_SDCRC;
+	}
+    hsd->RCA = (uint16_t) (respValue >> 16);
+	return E_OK;
+}
+
+/*
+ *  コマンド転送待ち
+ */
+static ER
+sdmmc_command_wait(SDMMC_Handle_t *hsd)
+{
+	int timeout = SDMMC_CMD0TIMEOUT;
+
+	while((sil_rew_mem((uint32_t *)(hsd->base+TOFF_SDIO_STA)) & SDMMC_WAIT_STATUS) == 0){
+		if(timeout == 0)
+			return E_TMOUT;
+		sil_dly_nse(1000);
+		timeout--;
+	}
+	return E_OK;
+}
+
+
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/pdic/stm32f7xx/sdmmc.cfg
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/pdic/stm32f7xx/sdmmc.cfg	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/pdic/stm32f7xx/sdmmc.cfg	(revision 457)
@@ -0,0 +1,21 @@
+/*
+ *  @(#) $Id$
+ */
+
+/*
+ *  SDMMCドライバのコンフィギュレーションファイル
+ */
+
+#include "device.h"
+#include "sdmmc.h"
+
+ATT_INI({ TA_NULL, 0, sdmmc_init });
+CRE_SEM(SDMMC_SEM, { TA_TPRI, 0, 1 });
+
+DEF_INH(INHNO_SDMMC, { TA_NULL, sdmmc_handler });
+CFG_INT(INTNO_SDMMC, { TA_ENAINT | INTATR_SDMMC, INTPRI_SDMMC });
+ATT_ISR({TA_NULL,  DMARX_SID, INTNO_DMARX, stream_dma_isr, 1 });
+CFG_INT(INTNO_DMARX, { TA_ENAINT | INTATR_DMARX, INTPRI_DMARX });
+ATT_ISR({TA_NULL, DMATX_SID, INTNO_DMATX, stream_dma_isr, 1 });
+CFG_INT(INTNO_DMATX, { TA_ENAINT | INTATR_DMATX, INTPRI_DMATX });
+
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/pdic/stm32f7xx/sdmmc.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/pdic/stm32f7xx/sdmmc.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/pdic/stm32f7xx/sdmmc.h	(revision 457)
@@ -0,0 +1,291 @@
+/*
+ *  TOPPERS/ASP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Advanced Standard Profile Kernel
+ * 
+ *  Copyright (C) 2008-2011 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ *  Copyright (C) 2015-2016 by TOPPERS PROJECT Educational Working Group.
+ * 
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+/*
+ *  STM32F746用 SDMMCドライバインクルードファイル
+ */
+
+#ifndef _SDMMC_H_
+#define _SDMMC_H_
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+
+/*
+ *  SDカード設定
+ */
+#ifdef TOPPERS_STM32F769_DISCOVERY
+#define INHNO_SDMMC     IRQ_VECTOR_SDMMC2	/* 割込みハンドラ番号 */
+#define INTNO_SDMMC     IRQ_VECTOR_SDMMC2	/* 割込み番号 */
+#define INTPRI_SDMMC    -5          /* 割込み優先度 */
+#define INTATR_SDMMC    TA_EDGE     /* 割込み属性 */
+
+#define INHNO_DMARX     IRQ_VECTOR_DMA2_STREAM0	/* 割込みハンドラ番号 */
+#define INTNO_DMARX     IRQ_VECTOR_DMA2_STREAM0	/* 割込み番号 */
+#define INTPRI_DMARX    -6          /* 割込み優先度 */
+#define INTATR_DMARX    TA_EDGE     /* 割込み属性 */
+#define DMARX_SID       DMA2STM0_SID
+
+#define INHNO_DMATX     IRQ_VECTOR_DMA2_STREAM5	/* 割込みハンドラ番号 */
+#define INTNO_DMATX     IRQ_VECTOR_DMA2_STREAM5	/* 割込み番号 */
+#define INTPRI_DMATX    -6          /* 割込み優先度 */
+#define INTATR_DMATX    TA_EDGE     /* 割込み属性 */
+#define DMATX_SID       DMA2STM5_SID
+#else
+#define INHNO_SDMMC     IRQ_VECTOR_SDMMC	/* 割込みハンドラ番号 */
+#define INTNO_SDMMC     IRQ_VECTOR_SDMMC	/* 割込み番号 */
+#define INTPRI_SDMMC    -5          /* 割込み優先度 */
+#define INTATR_SDMMC    TA_EDGE     /* 割込み属性 */
+
+#define INHNO_DMARX     IRQ_VECTOR_DMA2_STREAM3	/* 割込みハンドラ番号 */
+#define INTNO_DMARX     IRQ_VECTOR_DMA2_STREAM3	/* 割込み番号 */
+#define INTPRI_DMARX    -6          /* 割込み優先度 */
+#define INTATR_DMARX    TA_EDGE     /* 割込み属性 */
+#define DMARX_SID       DMA2STM3_SID
+
+#define INHNO_DMATX     IRQ_VECTOR_DMA2_STREAM6	/* 割込みハンドラ番号 */
+#define INTNO_DMATX     IRQ_VECTOR_DMA2_STREAM6	/* 割込み番号 */
+#define INTPRI_DMATX    -6          /* 割込み優先度 */
+#define INTATR_DMATX    TA_EDGE     /* 割込み属性 */
+#define DMATX_SID       DMA2STM6_SID
+#endif
+
+
+#define CMD_SHORTRESP       (1<<6)	/* short response */
+#define CMD_LONGRESP        (1<<7)	/* long response */
+#define CMD_SLONGRESP       (CMD_SHORTRESP|CMD_LONGRESP)
+#define CMD_TIMEOUT         (1<<8)	/* timeout request bit */
+#define CMD_SETLAST         (1<<10)
+#define CMD_MASK            0xFFFF
+#define CMD_IGNOREIRES      (1<<16)
+#define CMD_INDEX           0x003F
+
+/*
+ *  SD/MMC コマンドリスト
+ */
+#define MCI_CMD0			(0x0000)								/* GO_IDLE_STATE(MMC) or RESET(SD) */
+#define MCI_CMD1			(0x0001|CMD_SHORTRESP|CMD_IGNOREIRES)	/* SEND_OP_COND(MMC) or CMD1(SD) */
+#define MCI_CMD2			(0x0002|CMD_SLONGRESP|CMD_IGNOREIRES)	/* ALL SEND_CID */
+#define MCI_CMD3			(0x0003|CMD_SHORTRESP)					/* SET_RELATE_ADDR */
+#define MCI_CMD6			(0x0006|CMD_SHORTRESP)
+#define MCI_CMD7			(0x0007|CMD_SHORTRESP)					/* SELECT/DESELECT_CARD */
+#define MCI_CMD8            (0x0008|CMD_SHORTRESP)					/* HS_SEND_EXT_CSD */
+#define MCI_CMD9			(0x0009|CMD_SLONGRESP|CMD_IGNOREIRES)	/* SEND_CSD */
+#define MCI_CMD12			(0x000C|CMD_SHORTRESP)					/* Stop either READ or WRITE operation */
+#define MCI_CMD13			(0x000D|CMD_SHORTRESP)					/* SEND_STATUS */
+#define MCI_CMD16			(0x0010|CMD_SHORTRESP)					/* SET_BLOCK_LEN */
+#define MCI_CMD17			(0x0011|CMD_SHORTRESP)					/* READ_SINGLE_BLOCK */
+#define MCI_CMD18			(0x0012|CMD_SHORTRESP)					/* READ_MULTI_BLOCK */
+#define MCI_CMD24			(0x0018|CMD_SHORTRESP)					/* WRITE_SINGLE_BLOCK */
+#define MCI_CMD25			(0x0019|CMD_SHORTRESP)					/* WRITE_MULTI_BLOCK */
+#define MCI_CMD32			(0x0020|CMD_SHORTRESP)					/* ERASE_GRP_START */
+#define MCI_CMD33			(0x0021|CMD_SHORTRESP)					/* ERASE_GRP_END */
+#define MCI_CMD38			(0x0026|CMD_SHORTRESP)					/* ERASE */
+#define MCI_CMD55			(0x0037|CMD_SHORTRESP)					/* APP_CMD, the following will a ACMD */
+
+#define MCI_ACMD6			(0x0006|CMD_SHORTRESP)					/* ACMD6 for SD card BUSWIDTH */
+#define MCI_ACMD13			(0x000D|CMD_SHORTRESP)					/* ACMD23 for SD card status */
+#define MCI_ACMD41			(0x0029|CMD_SHORTRESP|CMD_IGNOREIRES)	/* ACMD41 for SD card */
+#define MCI_ACMD51			(0x0033|CMD_SHORTRESP)					/* ACMD41 for SD SCR */
+
+#define RES_CMD1            (MCI_CMD1 & CMD_INDEX)
+#define RES_CMD12           (MCI_CMD12 & CMD_INDEX)
+#define RES_ACMD41          (MCI_ACMD41 & CMD_INDEX)
+
+#define OCR_INDEX			0x00FF8000
+
+#define CARD_STATUS_ACMD_ENABLE		(1<<5)
+#define CARD_STATUS_RDY_DATA		(1<<8)
+#define CARD_STATUS_CURRENT_STATE	(0x0F<<9)
+#define CARD_STATUS_ERASE_RESET		(1<<13)
+
+#define SLOW_RATE			1
+#define NORMAL_RATE			2
+
+#define SD_1_BIT 			0
+#define SD_4_BIT			1
+
+#define SD_CARD_V11         0
+#define SD_CARD_V20         1
+#define SD_CARD_HC          2
+#define MMC_CARD			3
+#define SD_IO_CARD          4
+#define HS_MM_CARD          5
+#define SD_IO_COMBO_CARD    6
+#define MMC_CARD_HC         7
+
+
+#define MCI_NOTEND          0
+#define MCI_END             1
+#define MCI_ERREND          2
+
+#define SDMODE_PROTECT      (1<<5)
+
+/*
+ *  SDMMC拡張エラー定義
+ */
+#define E_SDCOM             (-80)	/* コマンドエラー */
+#define E_SDCRC             (-81)	/* CRCエラー */
+#define E_SDECMD            (-82)	/* コマンドインデックスエラー */
+#define E_SDVOL             (-83)	/* 電圧エラー */
+#define E_SDTRS             (-84)	/* 通信エラー */
+
+/*
+ *  カード転送状態定義
+ */
+#define SD_TRANSFER_OK      0	/* 転送成功 */
+#define SD_TRANSFER_BUSY    1	/* 転送中 */
+#define SD_TRANSFER_ERROR   2	/* 転送エラー */
+
+
+/*
+ *  バス幅定義
+ */
+#define SDMMC_BUS_WIDE_1B   0x00000000
+#define SDMMC_BUS_WIDE_4B   SDMMC_CLKCR_WIDBUS_0
+#define SDMMC_BUS_WIDE_8B   SDMMC_CLKCR_WIDBUS_1
+
+
+/*
+ *  SDMMC用データブロックサイズ定義
+ */
+#define SDMMC_DBSIZE_1B     0x00000000
+#define SDMMC_DBSIZE_2B     SDMMC_DCTRL_DBLOCKSIZE_0
+#define SDMMC_DBSIZE_4B     SDMMC_DCTRL_DBLOCKSIZE_1
+#define SDMMC_DBSIZE_8B     (SDMMC_DCTRL_DBLOCKSIZE_0|SDMMC_DCTRL_DBLOCKSIZE_1)
+#define SDMMC_DBSIZE_16B    SDMMC_DCTRL_DBLOCKSIZE_2
+#define SDMMC_DBSIZE_32B    (SDMMC_DCTRL_DBLOCKSIZE_0|SDMMC_DCTRL_DBLOCKSIZE_2)
+#define SDMMC_DBSIZE_64B    (SDMMC_DCTRL_DBLOCKSIZE_1|SDMMC_DCTRL_DBLOCKSIZE_2)
+#define SDMMC_DBSIZE_128B   (SDMMC_DCTRL_DBLOCKSIZE_0|SDMMC_DCTRL_DBLOCKSIZE_1|SDMMC_DCTRL_DBLOCKSIZE_2)
+#define SDMMC_DBSIZE_256B   SDMMC_DCTRL_DBLOCKSIZE_3
+#define SDMMC_DBSIZE_512B   (SDMMC_DCTRL_DBLOCKSIZE_0|SDMMC_DCTRL_DBLOCKSIZE_3)
+#define SDMMC_DBSIZE_1024B  (SDMMC_DCTRL_DBLOCKSIZE_1|SDMMC_DCTRL_DBLOCKSIZE_3)
+#define SDMMC_DBSIZE_2048B  (SDMMC_DCTRL_DBLOCKSIZE_0|SDMMC_DCTRL_DBLOCKSIZE_1|SDMMC_DCTRL_DBLOCKSIZE_3) 
+#define SDMMC_DBSIZE_4096B  (SDMMC_DCTRL_DBLOCKSIZE_2|SDMMC_DCTRL_DBLOCKSIZE_3)
+#define SDMMC_DBSIZE_8192B  (SDMMC_DCTRL_DBLOCKSIZE_0|SDMMC_DCTRL_DBLOCKSIZE_2|SDMMC_DCTRL_DBLOCKSIZE_3)
+#define SDMMC_DBSIZE_16384B (SDMMC_DCTRL_DBLOCKSIZE_1|SDMMC_DCTRL_DBLOCKSIZE_2|SDMMC_DCTRL_DBLOCKSIZE_3)
+
+/*
+ *  SDMMC初期設定周波数
+ */
+#define SDMMC_INIT_CLK_DIV  0x76
+
+/*
+ *  SDMMCデータ転送用周波数
+ */
+#define SDMMC_TRANSFER_CLK_DIV 0x0
+
+
+/*
+ *  SDMMCハンドラ構造体定義
+ */
+
+typedef struct
+{
+	uint32_t                base;		/* SDMMCレジスタベースアドレス */
+	uint32_t                ClockMode;	/* 指定クロックモード */
+	uint32_t                BusWide;	/* 指定バス幅 */
+	uint32_t                RetryCount;	/* リトライ回数 */
+	uint32_t                cardtype;	/* カードタイプ */
+	uint32_t                RCA;		/* RCA値 */
+	uint32_t                CSD[4];		/* CSD値 */
+	uint32_t                CID[4];		/* CID値 */
+	volatile uint32_t       status;		/* 転送状態 */
+	volatile uint32_t       SdCmd;		/* 転送指定コマンド */
+	DMA_Handle_t            *hdmarx;	/* 受信用DMAハンドラ */
+	DMA_Handle_t            *hdmatx;	/* 送信用DMAハンドラ */
+}SDMMC_Handle_t;
+
+/*
+ *  SDMMCカード情報構造体
+ */
+typedef struct
+{
+	uint64_t                capacity;	/* 容量(バイト) */
+	uint32_t                blocksize;	/* ブロックサイズ */
+	uint32_t                maxsector;	/* 最大セクタ数 */
+	uint16_t                RCA;		/* SD RCA */
+	uint8_t                 cardtype;	/* カード種類 */
+	uint8_t                 status;		/* ステータス */
+
+}SDMMC_CardInfo_t;
+
+
+/*
+ *  CMD13カード状態
+ */
+#define SD_CARD_READY           0x00000001	/* カードレディ状態 */
+#define SD_CARD_IDENTIFICATION	0x00000002	/* カードアイデンティフィケーション状態 */
+#define SD_CARD_STANDBY         0x00000003	/* カードスタンバィ状態 */
+#define SD_CARD_TRANSFER        0x00000004	/* カード転送状態 */
+#define SD_CARD_SENDING         0x00000005	/* カード送信状態 */
+#define SD_CARD_RECEIVING       0x00000006	/* カード受信状態 */
+#define SD_CARD_PROGRAMMING     0x00000007	/* カードプログラミング状態 */
+#define SD_CARD_DISCONNECTED    0x00000008	/* カードディスコネクト状態 */
+#define SD_CARD_ERROR           0x000000FF	/* カードエラー状態 */
+
+
+extern void sdmmc_init(intptr_t exinf);
+extern bool_t sdmmc_sense(int id);
+extern SDMMC_Handle_t *sdmmc_open(int id);
+extern ER sdmmc_close(SDMMC_Handle_t *hsd);
+extern ER sdmmc_erase(SDMMC_Handle_t *hsd, uint64_t startaddr, uint64_t endaddr);
+extern ER sdmmc_blockread(SDMMC_Handle_t *hsd, uint32_t *pbuf, uint64_t ReadAddr, uint32_t blocksize, uint32_t num);
+extern ER sdmmc_blockwrite(SDMMC_Handle_t *hsd, uint32_t *pbuf, uint64_t WriteAddr, uint32_t blocksize, uint32_t num);
+extern ER sdmmc_wait_transfar(SDMMC_Handle_t *hsd, uint32_t Timeout);
+extern void sdmmc_checkint(SDMMC_Handle_t *hsd);
+
+extern ER sdmmc_getcardinfo(SDMMC_Handle_t *hsd, SDMMC_CardInfo_t *pCardInfo);
+extern ER sdmmc_checkCID(SDMMC_Handle_t *hsd);
+extern ER sdmmc_setaddress(SDMMC_Handle_t *hsd);
+extern ER sdmmc_sendCSD(SDMMC_Handle_t *hsd);
+extern ER sdmmc_select_card(SDMMC_Handle_t *hsd, uint64_t addr);
+extern ER sdmmc_configuration(SDMMC_Handle_t *hsd);
+extern ER sdmmc_set_widebus(SDMMC_Handle_t *hsd);
+extern uint32_t sdmmc_getstatus(SDMMC_Handle_t *hsd);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif /* _SDMMC_H_ */
+
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/pdic/stm32f7xx/sdram.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/pdic/stm32f7xx/sdram.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/pdic/stm32f7xx/sdram.c	(revision 457)
@@ -0,0 +1,444 @@
+/*
+ *
+ *  STM32F746-Discovery SDRAM設定
+ *
+ */
+#include "kernel_impl.h"
+#include <t_syslog.h>
+#include <t_stdlib.h>
+#include <sil.h>
+#include <target_syssvc.h>
+#include "device.h"
+
+/*
+ *  SIL関数のマクロ定義
+ */
+#define sil_orw_mem(a, b)		sil_wrw_mem((a), sil_rew_mem(a) | (b))
+#define sil_andw_mem(a, b)		sil_wrw_mem((a), sil_rew_mem(a) & ~(b))
+#define sil_modw_mem(a, b, c)	sil_wrw_mem((a), (sil_rew_mem(a) & (~b)) | (c))
+
+/*
+ *  AF 12セクション定義
+ */ 
+#define GPIO_AF12_FMC           0x0C	/* FMC Alternate Function mapping                      */
+#define GPIO_AF12_OTG_HS_FS     0x0C	/* OTG HS configured in FS, Alternate Function mapping */
+#define GPIO_AF12_SDMMC1        0x0C	/* SDMMC1 Alternate Function mapping                     */
+
+/*
+ *  SDRAM設定タイムアウト定義(μsec)
+ */
+#define SDRAM_TIMEOUT          (0xFFFF*1000)
+
+/*
+ *  FMC SDRAMモードコマンド定義
+ */
+#define FMC_SDRAM_CMD_NORMAL_MODE       0x00000000
+#define FMC_SDRAM_CMD_CLK_ENABLE        0x00000001
+#define FMC_SDRAM_CMD_PALL              0x00000002
+#define FMC_SDRAM_CMD_AUTOREFRESH_MODE  0x00000003
+#define FMC_SDRAM_CMD_LOAD_MODE         0x00000004
+#define FMC_SDRAM_CMD_SELFREFRESH_MODE  0x00000005
+#define FMC_SDRAM_CMD_POWERDOWN_MODE    0x00000006
+
+/*
+ *  FMC SDRAM カラムビット番号
+ */
+#define FMC_SDRAM_COLUMN_BITS_NUM_8     0x00000000
+#define FMC_SDRAM_COLUMN_BITS_NUM_9     0x00000001
+#define FMC_SDRAM_COLUMN_BITS_NUM_10    0x00000002
+#define FMC_SDRAM_COLUMN_BITS_NUM_11    0x00000003
+
+/*
+ *  FMC SDRAM ロービット番号
+ */
+#define FMC_SDRAM_ROW_BITS_NUM_11       0x00000000
+#define FMC_SDRAM_ROW_BITS_NUM_12       0x00000004
+#define FMC_SDRAM_ROW_BITS_NUM_13       0x00000008
+
+/*
+ *  FMC SDRAM メモリビット幅
+ */
+#define FMC_SDRAM_MEM_BUS_WIDTH_8       0x00000000
+#define FMC_SDRAM_MEM_BUS_WIDTH_16      0x00000010
+#define FMC_SDRAM_MEM_BUS_WIDTH_32      0x00000020
+
+/*
+ *  FMC SDRAM インターナルバンク番号
+ */
+#define FMC_SDRAM_INTERN_BANKS_NUM_2    0x00000000
+#define FMC_SDRAM_INTERN_BANKS_NUM_4    0x00000040
+
+/*
+ *  FMC SDRAM CAS レーテンシィ
+ */
+#define FMC_SDRAM_CAS_LATENCY_1         0x00000080
+#define FMC_SDRAM_CAS_LATENCY_2         0x00000100
+#define FMC_SDRAM_CAS_LATENCY_3         0x00000180
+
+/*
+ *  FMC SDRAM ライトプロテクション
+ */
+#define FMC_SDRAM_WRITE_PROTECTION_DISABLE  0x00000000
+#define FMC_SDRAM_WRITE_PROTECTION_ENABLE   0x00000200
+
+/*
+ *  FMC SDRAM リードブースト
+ */
+#define FMC_SDRAM_RBURST_DISABLE        0x00000000
+#define FMC_SDRAM_RBURST_ENABLE         0x00001000
+
+/*
+ *  FMC SDRAM リードパイプデレィ
+ */
+#define FMC_SDRAM_RPIPE_DELAY_0         0x00000000
+#define FMC_SDRAM_RPIPE_DELAY_1         0x00002000
+#define FMC_SDRAM_RPIPE_DELAY_2         0x00004000
+
+/*
+ *  FMC SDRAM Clock Period
+ */
+#define FMC_SDRAM_CLOCK_DISABLE         0x00000000
+#define FMC_SDRAM_CLOCK_PERIOD_2        0x00000800
+#define FMC_SDRAM_CLOCK_PERIOD_3        0x00000C00
+
+
+#define SDRAM_MODEREG_BURST_LENGTH_1             0x0000
+#define SDRAM_MODEREG_BURST_LENGTH_2             0x0001
+#define SDRAM_MODEREG_BURST_LENGTH_4             0x0002
+#define SDRAM_MODEREG_BURST_LENGTH_8             0x0004
+#define SDRAM_MODEREG_BURST_TYPE_SEQUENTIAL      0x0000
+#define SDRAM_MODEREG_BURST_TYPE_INTERLEAVED     0x0008
+#define SDRAM_MODEREG_CAS_LATENCY_2              0x0020
+#define SDRAM_MODEREG_CAS_LATENCY_3              0x0030
+#define SDRAM_MODEREG_OPERATING_MODE_STANDARD    0x0000
+#define SDRAM_MODEREG_WRITEBURST_MODE_PROGRAMMED 0x0000
+#define SDRAM_MODEREG_WRITEBURST_MODE_SINGLE     0x0200
+
+
+/*
+ *  FMC SDRAM コンフィギュレーション定義
+ */
+typedef struct {
+	uint32_t        ColumnBitsNumber;		/* Defines the number of bits of column address. FMC_NORSRAM_Bank */
+	uint32_t        RowBitsNumber;			/* Defines the number of bits of column address. FMC_SDRAM_Row_Bits_number. */
+	uint32_t        MemoryDataWidth;		/* Defines the memory device width. FMC_SDRAM_Memory_Bus_Width. */
+	uint32_t        InternalBankNumber;		/* Defines the number of the device's internal banks. FMC_SDRAM_Internal_Banks_Number. */
+	uint32_t        CASLatency;				/* Defines the SDRAM CAS latency in number of memory clock cycles. FMC_SDRAM_CAS_Latency. */
+	uint32_t        WriteProtection;		/* Enables the SDRAM device to be accessed in write mode. FMC_SDRAM_Write_Protection. */
+	uint32_t        SDClockPeriod;			/* Define the SDRAM Clock Period for both SDRAM devices and they allow 
+                                             to disable the clock before changing frequency. FMC_SDRAM_Clock_Period. */
+	uint32_t        ReadBurst;				/* This bit enable the SDRAM controller to anticipate the next read 
+                                             commands during the CAS latency and stores data in the Read FIFO. FMC_SDRAM_Read_Burst. */
+	uint32_t        ReadPipeDelay;			/* Define the delay in system clock cycles on read data path. FMC_SDRAM_Read_Pipe_Delay. */
+}FMC_SDRAM_Init_t;
+
+/*
+ *  FMC SDRAM タイミング パラメータ
+ */
+typedef struct {
+	uint32_t        LoadToActiveDelay;		/* Defines the delay between a Load Mode Register command and 
+                                              an active or Refresh command in number of memory clock cycles. */
+    uint32_t        ExitSelfRefreshDelay;	/* Defines the delay from releasing the self refresh command to 
+                                              issuing the Activate command in number of memory clock cycles. */
+    uint32_t        SelfRefreshTime;		/* Defines the minimum Self Refresh period in number of memory clock cycles.*/
+    uint32_t        RowCycleDelay;			/* Defines the delay between the Refresh command and the Activate command
+                                              and the delay between two consecutive Refresh commands in number of memory clock cycles. */
+    uint32_t        WriteRecoveryTime;		/* Defines the Write recovery Time in number of memory clock cycles. */
+    uint32_t        RPDelay;				/* Defines the delay between a Precharge Command and an other command 
+                                              in number of memory clock cycles. */
+    uint32_t        RCDDelay;				/* Defines the delay between the Activate Command and a Read/Write 
+                                              command in number of memory clock cycles. */
+}FMC_SDRAM_Timing_t;
+
+#if defined(TOPPERS_STM32F769_DISCOVERY)
+#define SDRAM_AHB1ENR (RCC_AHB1ENR_GPIODEN | RCC_AHB1ENR_GPIOEEN | \
+					   RCC_AHB1ENR_GPIOFEN | RCC_AHB1ENR_GPIOGEN | \
+					   RCC_AHB1ENR_GPIOHEN | RCC_AHB1ENR_GPIOIEN)
+#define SDRAM_MODEREG_CAS_LATENCY SDRAM_MODEREG_CAS_LATENCY_3
+#define REFLESH_RATE  1539
+static const GPIO_Init_Table sdram_gpio_table[] = {
+	{TADR_GPIOD_BASE, (GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_8 | GPIO_PIN_9 | GPIO_PIN_10 | GPIO_PIN_14 | GPIO_PIN_15) },
+	{TADR_GPIOE_BASE, (GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_7 | GPIO_PIN_8 | GPIO_PIN_9 | GPIO_PIN_10 | \
+					  GPIO_PIN_11 | GPIO_PIN_12 | GPIO_PIN_13 | GPIO_PIN_14 | GPIO_PIN_15) },
+	{TADR_GPIOF_BASE, (GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_3 | GPIO_PIN_4 | GPIO_PIN_5 | \
+					  GPIO_PIN_11 | GPIO_PIN_12 | GPIO_PIN_13 | GPIO_PIN_14 | GPIO_PIN_15) },
+	{TADR_GPIOG_BASE, (GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_4 | GPIO_PIN_5 | GPIO_PIN_8 | GPIO_PIN_15) },
+	{TADR_GPIOH_BASE, (GPIO_PIN_2 | GPIO_PIN_3 | GPIO_PIN_5 | GPIO_PIN_8 | GPIO_PIN_9 | GPIO_PIN_10 | \
+					  GPIO_PIN_11 | GPIO_PIN_12 | GPIO_PIN_13 | GPIO_PIN_14 | GPIO_PIN_15) },
+	{TADR_GPIOI_BASE, (GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_3 | GPIO_PIN_4 | GPIO_PIN_5 | \
+					  GPIO_PIN_6 | GPIO_PIN_7 | GPIO_PIN_9 | GPIO_PIN_10) }
+};
+
+static const FMC_SDRAM_Init_t sdinit = {
+	FMC_SDRAM_COLUMN_BITS_NUM_8,		/* ColumnBitsNumber */
+	FMC_SDRAM_ROW_BITS_NUM_12,			/* RowBitsNumber */
+	FMC_SDRAM_MEM_BUS_WIDTH_32,			/* MemoryDataWidth */
+	FMC_SDRAM_INTERN_BANKS_NUM_4,		/* InternalBankNumber */
+	FMC_SDRAM_CAS_LATENCY_3,			/* CASLatency */
+	FMC_SDRAM_WRITE_PROTECTION_DISABLE,	/* WriteProtection */
+	FMC_SDRAM_CLOCK_PERIOD_2,			/* SDClockPeriod */
+	FMC_SDRAM_RBURST_ENABLE,			/* ReadBurst */
+	FMC_SDRAM_RPIPE_DELAY_1				/* ReadPipeDelay */
+};
+static const FMC_SDRAM_Timing_t sdtiming = {
+	2,									/* LoadToActiveDelay */
+	7,									/* ExitSelfRefreshDelay */
+	4,									/* SelfRefreshTime */
+	7,									/* RowCycleDelay */
+	2,									/* WriteRecoveryTime */
+	2,									/* RPDelay */
+	2									/* RCDDelay */
+};
+
+#else
+#define SDRAM_AHB1ENR (RCC_AHB1ENR_GPIOCEN | RCC_AHB1ENR_GPIODEN | \
+					   RCC_AHB1ENR_GPIOEEN | RCC_AHB1ENR_GPIOFEN | \
+					   RCC_AHB1ENR_GPIOGEN | RCC_AHB1ENR_GPIOHEN)
+#define SDRAM_MODEREG_CAS_LATENCY SDRAM_MODEREG_CAS_LATENCY_2
+#define REFLESH_RATE  1292
+static const GPIO_Init_Table sdram_gpio_table[] = {
+	{TADR_GPIOC_BASE, (GPIO_PIN_3) },
+	{TADR_GPIOD_BASE, (GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_8 | GPIO_PIN_9 | GPIO_PIN_10 | GPIO_PIN_14 | GPIO_PIN_15) },
+	{TADR_GPIOE_BASE, (GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_7 | GPIO_PIN_8 | GPIO_PIN_9 | GPIO_PIN_10 | \
+					  GPIO_PIN_11 | GPIO_PIN_12 | GPIO_PIN_13 | GPIO_PIN_14 | GPIO_PIN_15) },
+	{TADR_GPIOF_BASE, (GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_3 | GPIO_PIN_4 | GPIO_PIN_5 | \
+					  GPIO_PIN_11 | GPIO_PIN_12 | GPIO_PIN_13 | GPIO_PIN_14 | GPIO_PIN_15) },
+	{TADR_GPIOG_BASE, (GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_4 | GPIO_PIN_5 | GPIO_PIN_8 | GPIO_PIN_15) },
+	{TADR_GPIOH_BASE, (GPIO_PIN_3 | GPIO_PIN_5) }
+};
+
+static const FMC_SDRAM_Init_t sdinit = {
+	FMC_SDRAM_COLUMN_BITS_NUM_8,		/* ColumnBitsNumber */
+	FMC_SDRAM_ROW_BITS_NUM_12,			/* RowBitsNumber */
+	FMC_SDRAM_MEM_BUS_WIDTH_16,			/* MemoryDataWidth */
+	FMC_SDRAM_INTERN_BANKS_NUM_4,		/* InternalBankNumber */
+	FMC_SDRAM_CAS_LATENCY_2,			/* CASLatency */
+	FMC_SDRAM_WRITE_PROTECTION_DISABLE,	/* WriteProtection */
+	FMC_SDRAM_CLOCK_PERIOD_2,			/* SDClockPeriod */
+	FMC_SDRAM_RBURST_ENABLE,			/* ReadBurst */
+	FMC_SDRAM_RPIPE_DELAY_1				/* ReadPipeDelay */
+};
+static const FMC_SDRAM_Timing_t sdtiming = {
+	2,									/* LoadToActiveDelay */
+	7,									/* ExitSelfRefreshDelay */
+	4,									/* SelfRefreshTime */
+	7,									/* RowCycleDelay */
+	2,									/* WriteRecoveryTime */
+	2,									/* RPDelay */
+	2									/* RCDDelay */
+};
+
+#endif
+
+#define NUM_SDRAM_GPIO_ITEM (sizeof(sdram_gpio_table)/sizeof(GPIO_Init_Table))
+
+/*
+ *  SDRAM GPIO初期化
+ */
+static void
+sdram_gpio_init(void)
+{
+	GPIO_Init_t GPIO_Init_Data;
+	int i, pin;
+	volatile uint32_t tmp;
+
+	/*
+	 *  GPIOクロック設定
+	 */
+	sil_orw_mem((uint32_t *)(TADR_RCC_BASE+TOFF_RCC_AHB1ENR), SDRAM_AHB1ENR);
+	tmp = sil_rew_mem((uint32_t *)(TADR_RCC_BASE+TOFF_RCC_AHB1ENR));
+
+	/*
+	 *  FMCクロック設定
+	 */
+	sil_orw_mem((uint32_t *)(TADR_RCC_BASE+TOFF_RCC_AHB3ENR), RCC_AHB3ENR_FSMCEN);
+	tmp = sil_rew_mem((uint32_t *)(TADR_RCC_BASE+TOFF_RCC_AHB3ENR));
+	(void)(tmp);
+
+	/*
+	 *  GPIO設定
+	 */
+	GPIO_Init_Data.mode      = GPIO_MODE_AF;
+	GPIO_Init_Data.pull      = GPIO_PULLUP;
+	GPIO_Init_Data.otype     = GPIO_OTYPE_PP;
+#if defined(TOPPERS_STM32F769_DISCOVERY)
+	GPIO_Init_Data.speed     = GPIO_SPEED_HIGH;
+#else
+	GPIO_Init_Data.speed     = GPIO_SPEED_FAST;
+#endif
+	GPIO_Init_Data.alternate = GPIO_AF12_FMC;
+
+	for(i = 0 ; i < NUM_SDRAM_GPIO_ITEM ; i++){
+		for(pin = 0 ; pin < 16 ; pin++){
+			if((sdram_gpio_table[i].pinmap & 1<<pin) != 0)
+				gpio_setup(sdram_gpio_table[i].base, &GPIO_Init_Data, pin);
+		}
+	}
+}
+
+/*
+ *  FMC SDRAMバンクへのコマンド送信
+ *  patameter1 mode   コマンド値
+ *  parameter2 target ターゲット番号
+ *  parameter3 num    バンク番号
+ *  parameter4 moder  モード
+ *  parameter5 timeout タイムアウト値
+ *  return     正常終了でtrue
+ */
+static bool_t
+FMC_SDRAM_SendCommand(uint32_t cmd, uint32_t target, uint32_t num, uint32_t moder, uint32_t Timeout)
+{
+	uint32_t tickstart = 0;
+
+	/*
+	 *  コマンドレジスタ設定
+	 */
+	sil_wrw_mem((uint32_t *)(TADR_FMC_R_BASE+TOFF_FMC_R_SDCMR), (cmd | target | ((num-1) << 5) | (moder << 9)));
+
+	/*
+	 *  コマンド送信待ち
+	 */
+	tickstart = 0;
+	while((sil_rew_mem((uint32_t *)(TADR_FMC_R_BASE+TOFF_FMC_R_SDSR)) & FMC_SDSR_BUSY) != 0){
+		if(tickstart > Timeout){
+			return false;
+		}
+		sil_dly_nse(1000);
+		tickstart++;
+	}
+	return true;
+}
+
+/*
+ *  拡張SDRAMの初期化
+ */
+void
+sdram_init(intptr_t exinf)
+{
+	uint32_t Bank = (uint32_t)exinf;
+	volatile uint32_t tmpr1 = 0;
+	volatile uint32_t tmpr2 = 0;
+
+    /*
+	 *  GPIO,クロック設定
+	 */
+    sdram_gpio_init();
+
+	/*
+	 *  SDRAM制御タイミング設定
+	 */
+	if (Bank != FMC_SDRAM_BANK2){	/* Bank1 */
+		tmpr1 = sil_rew_mem((uint32_t *)(TADR_FMC_R_BASE+TOFF_FMC_R_SDCR0));
+
+		/* Clear NC, NR, MWID, NB, CAS, WP, SDCLK, RBURST, and RPIPE bits */
+		tmpr1 &= ((uint32_t)~(FMC_SDCR1_NC  | FMC_SDCR1_NR | FMC_SDCR1_MWID | \
+							FMC_SDCR1_NB  | FMC_SDCR1_CAS | FMC_SDCR1_WP | \
+							FMC_SDCR1_SDCLK | FMC_SDCR1_RBURST | FMC_SDCR1_RPIPE));
+
+		tmpr1 |= (uint32_t)(sdinit.ColumnBitsNumber   |
+							sdinit.RowBitsNumber      |
+							sdinit.MemoryDataWidth    |
+							sdinit.InternalBankNumber |
+							sdinit.CASLatency         |
+							sdinit.WriteProtection    |
+							sdinit.SDClockPeriod      |
+							sdinit.ReadBurst          |
+							sdinit.ReadPipeDelay );
+		sil_wrw_mem((uint32_t *)(TADR_FMC_R_BASE+TOFF_FMC_R_SDCR0), tmpr1);
+
+		tmpr1 = sil_rew_mem((uint32_t *)(TADR_FMC_R_BASE+TOFF_FMC_R_SDTR0));
+		/* Clear TMRD, TXSR, TRAS, TRC, TWR, TRP and TRCD bits */
+		tmpr1 &= ((uint32_t)~(FMC_SDTR1_TMRD  | FMC_SDTR1_TXSR | FMC_SDTR1_TRAS | 
+							FMC_SDTR1_TRC  | FMC_SDTR1_TWR | FMC_SDTR1_TRP | FMC_SDTR1_TRCD));
+
+		tmpr1 |= (uint32_t)(((sdtiming.LoadToActiveDelay)-1)           |
+							(((sdtiming.ExitSelfRefreshDelay)-1) << 4) |
+							(((sdtiming.SelfRefreshTime)-1) << 8)      |
+							(((sdtiming.RowCycleDelay)-1) << 12)       |
+							(((sdtiming.WriteRecoveryTime)-1) <<16)    |
+							(((sdtiming.RPDelay)-1) << 20)             |
+							(((sdtiming.RCDDelay)-1) << 24));
+		sil_wrw_mem((uint32_t *)(TADR_FMC_R_BASE+TOFF_FMC_R_SDTR0), tmpr1);
+	}
+	else{ /* Bank 2 */
+		tmpr1 = sil_rew_mem((uint32_t *)(TADR_FMC_R_BASE+TOFF_FMC_R_SDCR0));
+
+		/* Clear NC, NR, MWID, NB, CAS, WP, SDCLK, RBURST, and RPIPE bits */
+		tmpr1 &= ((uint32_t)~(FMC_SDCR1_NC  | FMC_SDCR1_NR | FMC_SDCR1_MWID | 
+							FMC_SDCR1_NB  | FMC_SDCR1_CAS | FMC_SDCR1_WP | 
+							FMC_SDCR1_SDCLK | FMC_SDCR1_RBURST | FMC_SDCR1_RPIPE));
+
+		tmpr1 |= (uint32_t)(sdinit.SDClockPeriod      |
+							sdinit.ReadBurst          |
+							sdinit.ReadPipeDelay);
+
+		tmpr2 = sil_rew_mem((uint32_t *)(TADR_FMC_R_BASE+TOFF_FMC_R_SDCR1));
+		/* Clear NC, NR, MWID, NB, CAS, WP, SDCLK, RBURST, and RPIPE bits */
+		tmpr2 &= ((uint32_t)~(FMC_SDCR1_NC  | FMC_SDCR1_NR | FMC_SDCR1_MWID |
+							FMC_SDCR1_NB  | FMC_SDCR1_CAS | FMC_SDCR1_WP | 
+							FMC_SDCR1_SDCLK | FMC_SDCR1_RBURST | FMC_SDCR1_RPIPE));
+
+		tmpr2 |= (uint32_t)(sdinit.ColumnBitsNumber   |
+							sdinit.RowBitsNumber      |
+							sdinit.MemoryDataWidth    |
+							sdinit.InternalBankNumber |
+							sdinit.CASLatency         |
+							sdinit.WriteProtection);
+
+		sil_wrw_mem((uint32_t *)(TADR_FMC_R_BASE+TOFF_FMC_R_SDCR0), tmpr1);
+		sil_wrw_mem((uint32_t *)(TADR_FMC_R_BASE+TOFF_FMC_R_SDCR1), tmpr2);
+
+		tmpr1 = sil_rew_mem((uint32_t *)(TADR_FMC_R_BASE+TOFF_FMC_R_SDTR1));
+		/* Clear TMRD, TXSR, TRAS, TRC, TWR, TRP and TRCD bits */
+		tmpr1 &= ((uint32_t)~(FMC_SDTR1_TMRD  | FMC_SDTR1_TXSR | FMC_SDTR1_TRAS |
+							FMC_SDTR1_TRC  | FMC_SDTR1_TWR | FMC_SDTR1_TRP | FMC_SDTR1_TRCD));
+
+		tmpr1 |= (uint32_t)(((sdtiming.LoadToActiveDelay)-1)           |
+							(((sdtiming.ExitSelfRefreshDelay)-1) << 4) |
+							(((sdtiming.SelfRefreshTime)-1) << 8)      |
+							(((sdtiming.WriteRecoveryTime)-1) <<16)    |
+							(((sdtiming.RCDDelay)-1) << 24));
+
+		tmpr2 = sil_rew_mem((uint32_t *)(TADR_FMC_R_BASE+TOFF_FMC_R_SDTR0));
+
+		/* Clear TMRD, TXSR, TRAS, TRC, TWR, TRP and TRCD bits */
+		tmpr2 &= ((uint32_t)~(FMC_SDTR1_TMRD  | FMC_SDTR1_TXSR | FMC_SDTR1_TRAS |
+							FMC_SDTR1_TRC  | FMC_SDTR1_TWR | FMC_SDTR1_TRP | FMC_SDTR1_TRCD));
+		tmpr2 |= (uint32_t)((((sdtiming.RowCycleDelay)-1) << 12) |
+							(((sdtiming.RPDelay)-1) << 20)); 
+
+		sil_wrw_mem((uint32_t *)(TADR_FMC_R_BASE+TOFF_FMC_R_SDTR1), tmpr1);
+		sil_wrw_mem((uint32_t *)(TADR_FMC_R_BASE+TOFF_FMC_R_SDTR0), tmpr2);
+	}
+
+	/*
+	 * SDRAM外部デバイス設定
+	 */
+	/* クロックコンフィギュレーション許可コマンド */
+	FMC_SDRAM_SendCommand(FMC_SDRAM_CMD_CLK_ENABLE, FMC_SDCMR_CTB1, 1, 0, SDRAM_TIMEOUT);
+
+	/*  300us待ち */
+	sil_dly_nse(300*1000);
+
+	/*  PALLコンフィギュレーションコマンド */
+	FMC_SDRAM_SendCommand(FMC_SDRAM_CMD_PALL, FMC_SDCMR_CTB1, 1, 0, SDRAM_TIMEOUT);
+
+	/*  オートリフレッシュ設定コマンド */
+	FMC_SDRAM_SendCommand(FMC_SDRAM_CMD_AUTOREFRESH_MODE, FMC_SDCMR_CTB1, 8, 0, SDRAM_TIMEOUT);
+
+	/*  外部メモリプログラミングレジスタ設定 */
+	tmpr1 = (uint32_t)SDRAM_MODEREG_BURST_LENGTH_1         |
+                     SDRAM_MODEREG_BURST_TYPE_SEQUENTIAL   |
+                     SDRAM_MODEREG_CAS_LATENCY             |
+                     SDRAM_MODEREG_OPERATING_MODE_STANDARD |
+                     SDRAM_MODEREG_WRITEBURST_MODE_SINGLE;
+
+	FMC_SDRAM_SendCommand(FMC_SDRAM_CMD_LOAD_MODE, FMC_SDCMR_CTB1, 1, tmpr1, SDRAM_TIMEOUT);
+
+	/*  リフレッシュレート設定: (15.62 us x Freq) - 20 */
+	sil_wrw_mem((uint32_t *)(TADR_FMC_R_BASE+TOFF_FMC_R_SDRTR), (REFLESH_RATE)<< 1);
+
+	sil_orw_mem((uint32_t *)(TADR_RCC_BASE+TOFF_RCC_AHB1ENR), RCC_AHB1ENR_CRCEN);
+	tmpr1 = sil_rew_mem((uint32_t *)(TADR_RCC_BASE+TOFF_RCC_AHB1ENR));
+}
+
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/pdic/stm32f7xx/spi.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/pdic/stm32f7xx/spi.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/pdic/stm32f7xx/spi.c	(revision 457)
@@ -0,0 +1,1040 @@
+/*
+ *  TOPPERS/ASP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Advanced Standard Profile Kernel
+ * 
+ *  Copyright (C) 2008-2011 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ *  Copyright (C) 2015-2018 by TOPPERS PROJECT Educational Working Group.
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+/*
+ * 
+ *  SPIドライバ関数群
+ *
+ */
+#include "kernel_impl.h"
+#include <t_syslog.h>
+#include <t_stdlib.h>
+#include <string.h>
+#include <sil.h>
+#include <target_syssvc.h>
+#include "device.h"
+#include "spi.h"
+
+#define sil_orw_mem(a, b)		sil_wrw_mem((a), sil_rew_mem(a) | (b))
+#define sil_andw_mem(a, b)		sil_wrw_mem((a), sil_rew_mem(a) & ~(b))
+#define sil_modw_mem(a, b, c)	sil_wrw_mem((a), (sil_rew_mem(a) & (~b)) | (c))
+
+#ifndef SPI_GPIO_PP
+#define SPI_GPIO_PP     GPIO_PULLUP
+#endif
+#ifndef SPI_GPIO_SPEED
+#define SPI_GPIO_SPEED  GPIO_SPEED_HIGH
+#endif
+
+/*
+ *  SPIOポートIDから管理ブロックを取り出すためのマクロ
+ */
+#define INDEX_SPI(spiid)        ((uint_t)((spiid) - 1))
+
+#define GPIO_AF5_SPI1          ((uint8_t)0x05)  /* SPI1 Alternate Function mapping        */
+#define GPIO_AF5_SPI2          ((uint8_t)0x05)  /* SPI2 Alternate Function mapping        */
+
+#define SPI_TIMEOUT_VALUE  (10*1000)
+
+static const SPI_PortControlBlock spi_pcb[NUM_SPIPORT] = {
+  {	TADR_SPI1_BASE,
+#if defined(TOPPERS_STM32F723_DISCOVERY)
+	(TADR_RCC_BASE+TOFF_RCC_AHB1ENR), RCC_AHB1ENR_GPIOAEN, RCC_AHB1ENR_GPIOHEN,
+#else
+	(TADR_RCC_BASE+TOFF_RCC_AHB1ENR), RCC_AHB1ENR_GPIOAEN, RCC_AHB1ENR_GPIOAEN,
+#endif
+	(TADR_RCC_BASE+TOFF_RCC_APB2ENR), RCC_APB2ENR_SPI1EN,
+	(TADR_RCC_BASE+TOFF_RCC_AHB1ENR), RCC_AHB1ENR_DMA2EN,
+#if defined(TOPPERS_STM32F723_DISCOVERY)
+	TADR_GPIOA_BASE, TADR_GPIOH_BASE, TADR_GPIOH_BASE,
+	5, 4, 5, GPIO_AF5_SPI1,
+#else
+	TADR_GPIOA_BASE, TADR_GPIOA_BASE, TADR_GPIOA_BASE,
+	5, 6, 7, GPIO_AF5_SPI1,
+#endif
+	DMA_CHANNEL_3, TADR_DMA2_STM3_BASE,
+	DMA_CHANNEL_3, TADR_DMA2_STM2_BASE },
+
+  {	TADR_SPI2_BASE,
+#if defined(TOPPERS_STM32F769_DISCOVERY)
+	(TADR_RCC_BASE+TOFF_RCC_AHB1ENR), RCC_AHB1ENR_GPIOAEN, RCC_AHB1ENR_GPIOBEN,
+#else
+	(TADR_RCC_BASE+TOFF_RCC_AHB1ENR), RCC_AHB1ENR_GPIOBEN, RCC_AHB1ENR_GPIOIEN,
+#endif
+	(TADR_RCC_BASE+TOFF_RCC_APB1ENR), RCC_APB1ENR_SPI2EN,
+	(TADR_RCC_BASE+TOFF_RCC_AHB1ENR), RCC_AHB1ENR_DMA1EN,
+#if defined(TOPPERS_STM32F769_DISCOVERY)
+	TADR_GPIOA_BASE, TADR_GPIOB_BASE, TADR_GPIOB_BASE,
+	12, 14, 15, GPIO_AF5_SPI2,
+#elif defined(TOPPERS_STM32F7_DISCOVERY)
+	TADR_GPIOI_BASE, TADR_GPIOB_BASE, TADR_GPIOB_BASE,
+	1, 14, 15, GPIO_AF5_SPI2,
+#else
+	TADR_GPIOB_BASE, TADR_GPIOB_BASE, TADR_GPIOB_BASE,
+	13, 14, 15, GPIO_AF5_SPI2,
+#endif
+	DMA_CHANNEL_0, TADR_DMA1_STM4_BASE,
+	DMA_CHANNEL_0, TADR_DMA1_STM3_BASE },
+};
+
+static SPI_Handle_t SpiHandle[NUM_SPIPORT];
+static DMA_Handle_t hdma_tx[NUM_SPIPORT];
+static DMA_Handle_t hdma_rx[NUM_SPIPORT];
+
+
+/*
+ *  SPI状態変化待ち関数
+ *  parameter1  hspi: SPIハンドラへのポインタ
+ *  parameter2  Flag: チェックを行うSPIフラグ
+ *  parameter3  Status: 待ち状態
+ *  parameter4  Timeout: タイムアウト時間(マイクロ秒)
+ *  return ERコード
+ */
+static ER
+spi_waitflag(SPI_Handle_t *hspi, uint32_t Flag, bool_t Status, uint32_t Timeout)
+{
+  uint32_t tick = 0;
+
+	while(((sil_rew_mem((uint32_t *)(hspi->base+TOFF_SPI_SR)) & Flag) == Flag) == Status){
+		if(Timeout == 0 || tick > Timeout){
+			/*
+			 *  送受信とエラーフラグをリセット
+			 */
+			sil_andw_mem((uint32_t *)(hspi->base+TOFF_SPI_CR2), (SPI_CR2_TXEIE | SPI_CR2_RXNEIE | SPI_CR2_ERRIE));
+
+			/*
+			 *  SPIを停止
+			 */
+			sil_andw_mem((uint32_t *)(hspi->base+TOFF_SPI_CR1), SPI_CR1_SPE);
+
+			/*
+			 *  CRC演算を無効に
+			 */
+			if(hspi->Init.CRC == SPI_CRC_ENABLE){
+				sil_andw_mem((uint32_t *)(hspi->base+TOFF_SPI_CR1), SPI_CR1_CRCEN);
+				sil_orw_mem((uint32_t *)(hspi->base+TOFF_SPI_CR1), SPI_CR1_CRCEN);
+			}
+
+			hspi->status= SPI_STATUS_READY;
+			return E_TMOUT;
+		}
+		tick++;
+		sil_dly_nse(1000);
+	}
+	return E_OK;
+}
+
+/*
+ *  SPI DMA送信コールバック関数
+ */
+static void
+spi_dmatransmit_func(DMA_Handle_t *hdma)
+{
+	SPI_Handle_t* hspi = ( SPI_Handle_t* )hdma->localdata;
+	volatile uint32_t tmp;
+
+	/*
+	 *  TXEフラグセット待ち
+	 */
+	if(spi_waitflag(hspi, SPI_SR_TXE, false, SPI_TIMEOUT_VALUE) != E_OK){
+		hspi->ErrorCode |= SPI_ERROR_TIMEOUT;
+	}
+
+	/*
+	 *  TX DMA停止
+	 */
+	sil_andw_mem((uint32_t *)(hspi->base+TOFF_SPI_CR2), SPI_CR2_TXDMAEN);
+
+	/*
+	 *  SPI BUSYリセット待ち
+	 */
+	if(spi_waitflag(hspi, SPI_SR_BSY, true, SPI_TIMEOUT_VALUE) != E_OK){
+		hspi->ErrorCode |= SPI_ERROR_TIMEOUT;
+	}
+
+	hspi->TxXferCount = 0;
+	hspi->status = SPI_STATUS_READY;
+
+	/*
+	 *  2ライン転送でオーバーランが発生しているならリセット
+	 */
+	if(hspi->Init.Direction == SPI_DIRECTION_2LINES){
+		tmp = sil_rew_mem((uint32_t *)(hspi->base+TOFF_SPI_DR));
+		sil_andw_mem((uint32_t *)(hspi->base+TOFF_SPI_SR), SPI_SR_OVR);
+		((void)(tmp));
+	}
+	if(hspi->Init.semid != 0)
+		isig_sem(hspi->Init.semid);
+}
+
+/*
+ *  SPI DMA受信コールバック関数
+ */
+static void
+spi_dmareceive_func(DMA_Handle_t *hdma)
+{
+	SPI_Handle_t *hspi = (SPI_Handle_t *)hdma->localdata;
+	volatile uint32_t tmp;
+
+	if((hspi->Init.Mode == SPI_MODE_MASTER) &&
+		(hspi->Init.Direction == SPI_DIRECTION_1LINE || hspi->Init.Direction == SPI_DIRECTION_2LINES_RXONLY)){
+		/*
+		 *  SPIを停止
+		 */
+		sil_andw_mem((uint32_t *)(hspi->base+TOFF_SPI_CR1), SPI_CR1_SPE);
+	}
+
+	/*
+	 *  RX DMA停止
+	 */
+	sil_andw_mem((uint32_t *)(hspi->base+TOFF_SPI_CR2), (SPI_CR2_RXDMAEN));
+
+	hspi->RxXferCount = 0;
+
+	/*
+	 *  CRC演算
+	 */
+	if(hspi->Init.CRC == SPI_CRC_ENABLE){
+		/*
+		 *  受信終了待ち
+		 */
+		if(spi_waitflag(hspi, SPI_SR_RXNE, false, SPI_TIMEOUT_VALUE) != E_OK){
+			hspi->ErrorCode |= SPI_ERROR_TIMEOUT;
+		}
+
+		/*
+		 *  CRC読み捨て
+		 */
+		tmp = sil_rew_mem((uint32_t *)(hspi->base+TOFF_SPI_DR));
+		((void)(tmp));
+
+		/*
+		 *  CRCエラーチェック
+		 */
+		if((sil_rew_mem((uint32_t *)(hspi->base+TOFF_SPI_SR)) & SPI_SR_CRCERR) != 0){
+			hspi->ErrorCode |= SPI_ERROR_CRC;
+			sil_andw_mem((uint32_t *)(hspi->base+TOFF_SPI_SR), SPI_SR_CRCERR);
+		}
+	}
+	hspi->status = SPI_STATUS_READY;
+
+	if(hspi->Init.semid != 0)
+		isig_sem(hspi->Init.semid);
+}
+
+/*
+ *  SPI DMA送受信コールバック関数
+ */
+static void
+spi_dmatransrecv_func(DMA_Handle_t *hdma)
+{
+	SPI_Handle_t *hspi = (SPI_Handle_t *)hdma->localdata;
+	volatile uint32_t tmp;
+
+	/*
+	 *  CRC演算
+	 */
+	if(hspi->Init.CRC == SPI_CRC_ENABLE){
+		/*
+		 *  受信終了待ち
+		 */
+		if(spi_waitflag(hspi, SPI_SR_RXNE, false, SPI_TIMEOUT_VALUE) != E_OK){
+			hspi->ErrorCode |= SPI_ERROR_TIMEOUT;
+		}
+		/*
+		 *  CRC読み捨て
+		 */
+ 		tmp = sil_rew_mem((uint32_t *)(hspi->base+TOFF_SPI_DR));
+		((void)(tmp));
+
+		/*
+		 *  CRCエラーチェック
+		 */
+		if((sil_rew_mem((uint32_t *)(hspi->base+TOFF_SPI_SR)) & SPI_SR_CRCERR) != 0){
+			hspi->ErrorCode |= SPI_ERROR_CRC;
+			sil_andw_mem((uint32_t *)(hspi->base+TOFF_SPI_SR), SPI_SR_CRCERR);
+		}
+	}
+
+	/*
+	 *  TXEフラグセット待ち
+	 */
+	if(spi_waitflag(hspi, SPI_SR_TXE, false, SPI_TIMEOUT_VALUE) != E_OK){
+		hspi->ErrorCode |= SPI_ERROR_TIMEOUT;
+	}
+	/*
+	 *  TX DMA停止
+	 */
+	sil_andw_mem((uint32_t *)(hspi->base+TOFF_SPI_CR2), (SPI_CR2_TXDMAEN));
+
+	/*
+	 *  SPI BUSY終了待ち
+	 */
+	if(spi_waitflag(hspi, SPI_SR_BSY, true, SPI_TIMEOUT_VALUE) != E_OK){
+		hspi->ErrorCode |= SPI_ERROR_TIMEOUT;
+	}
+
+	/*
+	 *  RX DMA停止
+	 */
+	sil_andw_mem((uint32_t *)(hspi->base+TOFF_SPI_CR2), (SPI_CR2_RXDMAEN));
+
+	hspi->TxXferCount = 0;
+	hspi->RxXferCount = 0;
+	hspi->status = SPI_STATUS_READY;
+
+	if(hspi->Init.semid != 0)
+		isig_sem(hspi->Init.semid);
+}
+
+/*
+ *  SPI内部転送終了待ち
+ */
+ER
+spi_inwait(SPI_Handle_t *hspi, uint32_t timeout)
+{
+	ER ercd = E_OK;
+	int tick = timeout;
+
+	while((hspi->status & SPI_STATUS_BUSY) != 0 && tick > 0){
+		if(hspi->Init.semid != 0)
+    		twai_sem(hspi->Init.semid, 1);
+		else
+			dly_tsk(1);
+		tick--;
+	}
+	dma_end(hspi->hdmarx);
+	dma_end(hspi->hdmatx);
+	if(hspi->ErrorCode != 0)
+		ercd = E_OBJ;
+	else if(tick == 0)
+		ercd = E_TMOUT;
+	hspi->TxXferCount = 0;
+	hspi->RxXferCount = 0;
+	return ercd;
+}
+
+/*
+ *  SPI DMAエラーコールバック関数
+ */
+static
+void spi_dmaerror_func(DMA_Handle_t *hdma)
+{
+	SPI_Handle_t *hspi = (SPI_Handle_t *)hdma->localdata;
+
+	hspi->TxXferCount = 0;
+	hspi->RxXferCount = 0;
+	hspi->status= SPI_STATUS_READY;
+	hspi->ErrorCode |= SPI_ERROR_DMA;
+	syslog_2(LOG_ERROR, "SPI DMA Error handle[%08x] ErrorCode[%08x] !", hdma, hdma->ErrorCode);
+	sil_dly_nse(1000*500);	/* エラー時ハングアップ回避の0.5msec待ち */
+}
+
+/*
+ *  SPI初期設定
+ *  parameter1  port: SPIポート番号
+ *  parameter2  spii: SPI初期設定構造体へのポインタ
+ *  return SPIハンドラへのポインタ、NULLでエラー
+ */
+SPI_Handle_t *
+spi_init(ID port, SPI_Init_t *spii)
+{
+	GPIO_Init_t GPIO_Init_Data;
+	SPI_Handle_t *hspi;
+	const SPI_PortControlBlock *spcb;
+	DMA_Handle_t *hdma;
+	uint32_t no;
+	uint32_t frxth;
+	volatile uint32_t tmpreg;
+
+	if(port < SPI1_PORTID || port > NUM_SPIPORT)
+		return NULL;
+	if(spii == NULL)
+		return NULL;
+
+	no = INDEX_SPI(port);
+	hspi = &SpiHandle[no];
+	if(hspi->status != SPI_STATUS_RESET)
+		return NULL;
+	spcb = &spi_pcb[no];
+	memcpy(&hspi->Init, spii, sizeof(SPI_Init_t));
+	hspi->base = spcb->base;
+
+	/*
+	 *  SPI クロック設定
+	 */
+	sil_orw_mem((uint32_t *)spcb->gioclockbase, spcb->gioclockbit);
+	tmpreg = sil_rew_mem((uint32_t *)spcb->gioclockbase);
+	sil_orw_mem((uint32_t *)spcb->gioclockbase, spcb->gioclockbit2);
+	tmpreg = sil_rew_mem((uint32_t *)spcb->gioclockbase);
+	sil_orw_mem((uint32_t *)spcb->spiclockbase, spcb->spiclockbit);
+	tmpreg = sil_rew_mem((uint32_t *)spcb->spiclockbase);
+	sil_orw_mem((uint32_t *)spcb->dmaclockbase, spcb->dmaclockbit);
+	tmpreg = sil_rew_mem((uint32_t *)spcb->dmaclockbase);
+    ((void)(tmpreg));
+  
+	/*
+	 *  SPI GPIOピン設定
+	 */
+	GPIO_Init_Data.mode      = GPIO_MODE_AF;
+	GPIO_Init_Data.pull      = SPI_GPIO_PP;
+	GPIO_Init_Data.otype     = GPIO_OTYPE_PP;
+	GPIO_Init_Data.speed     = SPI_GPIO_SPEED;
+	GPIO_Init_Data.alternate = spcb->apvalue;
+	gpio_setup(spcb->giobase1, &GPIO_Init_Data, spcb->sckpin);
+	gpio_setup(spcb->giobase2, &GPIO_Init_Data, spcb->misopin);
+	gpio_setup(spcb->giobase3, &GPIO_Init_Data, spcb->mosipin);
+
+	/*
+	 *  SPI用受信DMP設定
+	 */
+	hdma = &hdma_tx[no];
+	hdma->base                     = spcb->dmatxbase;
+	hdma->Init.Channel             = spcb->dmatxchannel;
+	hdma->Init.Direction           = DMA_MEMORY_TO_PERIPH;
+	hdma->Init.PeriphInc           = DMA_PINC_DISABLE;
+	hdma->Init.MemInc              = DMA_MINC_ENABLE;
+	hdma->Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
+	hdma->Init.MemDataAlignment    = DMA_MDATAALIGN_BYTE;
+	hdma->Init.Mode                = DMA_NORMAL;
+	hdma->Init.Priority            = DMA_PRIORITY_LOW;
+	hdma->Init.FIFOMode            = DMA_FIFOMODE_DISABLE;
+	hdma->Init.FIFOThreshold       = DMA_FIFO_THRESHOLD_FULL;
+	hdma->Init.MemBurst            = DMA_MBURST_INC4;
+	hdma->Init.PeriphBurst         = DMA_PBURST_INC4;
+
+	dma_init(hdma);
+	hspi->hdmatx = hdma;
+	hdma->localdata                = hspi;
+
+	/*
+	 *  SPI用受信DMP設定
+	 */
+	hdma = &hdma_rx[no];
+	hdma->base                     = spcb->dmarxbase;
+	hdma->Init.Channel             = spcb->dmarxchannel;
+	hdma->Init.Direction           = DMA_PERIPH_TO_MEMORY;
+	hdma->Init.PeriphInc           = DMA_PINC_DISABLE;
+	hdma->Init.MemInc              = DMA_MINC_ENABLE;
+	hdma->Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
+	hdma->Init.MemDataAlignment    = DMA_MDATAALIGN_BYTE;
+	hdma->Init.Mode                = DMA_NORMAL;
+	hdma->Init.Priority            = DMA_PRIORITY_HIGH;
+	hdma->Init.FIFOMode            = DMA_FIFOMODE_DISABLE;
+	hdma->Init.FIFOThreshold       = DMA_FIFO_THRESHOLD_FULL;
+	hdma->Init.MemBurst            = DMA_MBURST_INC4;
+	hdma->Init.PeriphBurst         = DMA_PBURST_INC4; 
+
+	dma_init(hdma);
+	hspi->hdmarx = hdma;
+	hdma->localdata                = hspi;
+
+	/*
+	 *  SPIディゼーブル
+	 */
+	sil_andw_mem((uint32_t *)(hspi->base+TOFF_SPI_CR1), SPI_CR1_SPE);
+
+	/*
+	 *  FIFOスレッシュホールド設定
+	 */
+	if(hspi->Init.DataSize > SPI_DATASIZE_8BIT)
+		frxth = 0x00000000;
+	else
+		frxth = SPI_CR2_FRXTH;
+
+	/*
+	 *  CRC長の再設定
+	 */
+	if(hspi->Init.DataSize != SPI_DATASIZE_16BIT && hspi->Init.DataSize != SPI_DATASIZE_8BIT)
+		hspi->Init.CRC = SPI_CRC_DISABLE;
+	if(hspi->Init.CRCLength == SPI_CRC_LENGTH_DATASIZE){
+		if(hspi->Init.DataSize > SPI_DATASIZE_8BIT)
+			hspi->Init.CRCLength = SPI_CRC_LENGTH_16BIT;
+		else
+			hspi->Init.CRCLength = SPI_CRC_LENGTH_8BIT;
+	}
+
+	/*
+	 *  SPI CR1/CR2レジスタ設定
+	 */
+	sil_wrw_mem((uint32_t *)(hspi->base+TOFF_SPI_CR1), (hspi->Init.Mode | hspi->Init.Direction |
+							hspi->Init.CLKPolarity | hspi->Init.CLKPhase | (hspi->Init.NSS & SPI_CR1_SSM) |
+							hspi->Init.Prescaler | hspi->Init.SignBit | hspi->Init.CRC));
+
+	/*
+	 *  SPI NSS設定
+	 */
+	sil_wrw_mem((uint32_t *)(hspi->base+TOFF_SPI_CR2), (((hspi->Init.NSS >> 16) & SPI_CR2_SSOE) | hspi->Init.TIMode |
+							hspi->Init.DataSize | frxth));
+
+	/*
+	 *  SPI CRC多項式設定
+	 */
+	sil_wrw_mem((uint32_t *)(hspi->base+TOFF_SPI_CRCPR), hspi->Init.CRCPolynomial);
+
+	/*
+	 *  SPI I2CSモードをリセット
+	 */
+	sil_andw_mem((uint32_t *)(hspi->base+TOFF_SPI_I2SCFGR), SPI_I2SCFGR_I2SMOD);
+
+	hspi->ErrorCode = SPI_ERROR_NONE;
+	hspi->status = SPI_STATUS_READY;
+	return hspi;
+}
+
+/*
+ *  SPI終了設定
+ *  parameter1  hspi: SPIハンドラへのポインタ
+ *  return ERコード
+ */
+ER
+spi_deinit(SPI_Handle_t *hspi)
+{
+	if(hspi == NULL)
+		return E_PAR;
+
+	dma_deinit(hspi->hdmatx);
+	dma_deinit(hspi->hdmarx);
+
+	sil_andw_mem((uint32_t *)(hspi->base+TOFF_SPI_CR1), SPI_CR1_SPE);
+
+	hspi->ErrorCode = SPI_ERROR_NONE;
+	hspi->status = SPI_STATUS_RESET;
+	return E_OK;
+}
+
+/*
+ *  SPIモジュールのリセット
+ *  parameter1  hspi: SPIハンドラへのポインタ
+ *  return ERコード
+ */
+ER
+spi_reset(SPI_Handle_t *hspi)
+{
+	uint32_t frxth;
+
+	if(hspi == NULL)
+		return E_PAR;
+	/*
+	 *  SPIディゼーブル
+	 */
+	sil_andw_mem((uint32_t *)(hspi->base+TOFF_SPI_CR1), SPI_CR1_SPE);
+
+	/*
+	 *  FIFOスレッシュホールド設定
+	 */
+	if(hspi->Init.DataSize > SPI_DATASIZE_8BIT)
+		frxth = 0x00000000;
+	else
+		frxth = SPI_CR2_FRXTH;
+
+	/*
+	 *  CRC長の再設定
+	 */
+	if(hspi->Init.DataSize != SPI_DATASIZE_16BIT && hspi->Init.DataSize != SPI_DATASIZE_8BIT)
+		hspi->Init.CRC = SPI_CRC_DISABLE;
+	if(hspi->Init.CRCLength == SPI_CRC_LENGTH_DATASIZE){
+		if(hspi->Init.DataSize > SPI_DATASIZE_8BIT)
+			hspi->Init.CRCLength = SPI_CRC_LENGTH_16BIT;
+		else
+			hspi->Init.CRCLength = SPI_CRC_LENGTH_8BIT;
+	}
+
+	/*
+	 *  SPI CR1/CR2レジスタ設定
+	 */
+	sil_wrw_mem((uint32_t *)(hspi->base+TOFF_SPI_CR1), (hspi->Init.Mode | hspi->Init.Direction |
+							hspi->Init.CLKPolarity | hspi->Init.CLKPhase | (hspi->Init.NSS & SPI_CR1_SSM) |
+							hspi->Init.Prescaler | hspi->Init.SignBit | hspi->Init.CRC));
+
+	/*
+	 *  SPI NSS設定
+	 */
+	sil_wrw_mem((uint32_t *)(hspi->base+TOFF_SPI_CR2), (((hspi->Init.NSS >> 16) & SPI_CR2_SSOE) | hspi->Init.TIMode |
+							hspi->Init.DataSize | frxth));
+
+	/*
+	 *  SPI CRC多項式設定
+	 */
+	sil_wrw_mem((uint32_t *)(hspi->base+TOFF_SPI_CRCPR), hspi->Init.CRCPolynomial);
+
+	/*
+	 *  SPI I2CSモードをリセット
+	 */
+	sil_andw_mem((uint32_t *)(hspi->base+TOFF_SPI_I2SCFGR), SPI_I2SCFGR_I2SMOD);
+
+	hspi->ErrorCode = SPI_ERROR_NONE;
+	hspi->status = SPI_STATUS_READY;
+	return E_OK;
+}
+
+/*
+ *  SPI送信実行関数
+ *  parameter1  hspi: SPIハンドラへのポインタ
+ *  parameter2  pdata: 送信バッファへのポインタ(4バイトアライン)
+ *  parameter3  length: 送信サイズ(CRCでは+1)
+ *  return ERコード
+ */
+ER
+spi_transmit(SPI_Handle_t *hspi, uint8_t *pdata, uint16_t length)
+{
+	ER ercd = E_OK;
+
+	if(hspi == NULL || pdata == NULL || length == 0)
+		return E_PAR;
+	if((((uint32_t)pdata) & 3) != 0)
+		return E_PAR;
+
+	if(hspi->Init.semlock != 0)
+		wai_sem(hspi->Init.semlock);
+	if(hspi->status != SPI_STATUS_READY){
+		if(hspi->Init.semlock != 0)
+			sig_sem(hspi->Init.semlock);
+		return E_OBJ;
+	}
+
+	/* Configure communication */
+	hspi->xmode       = SPI_XMODE_TX;
+	hspi->status      = SPI_STATUS_BUSY;
+	hspi->ErrorCode   = SPI_ERROR_NONE;
+
+	hspi->pTxBuffPtr  = pdata;
+	hspi->TxXferSize  = length;
+	hspi->TxXferCount = length;
+	hspi->RxXferSize   = 0;
+	hspi->RxXferCount  = 0;
+
+    /*
+	 *  1ライン通信設定
+	 */
+	if(hspi->Init.Direction == SPI_DIRECTION_1LINE){
+		sil_orw_mem((uint32_t *)(hspi->base+TOFF_SPI_CR1), SPI_CR1_BIDIOE);
+	}
+
+	/*
+	 *  CRCモードなら設定を有効に
+	 */
+	if(hspi->Init.CRC == SPI_CRC_ENABLE){
+		sil_andw_mem((uint32_t *)(hspi->base+TOFF_SPI_CR1), SPI_CR1_CRCEN);
+		sil_orw_mem((uint32_t *)(hspi->base+TOFF_SPI_CR1), SPI_CR1_CRCEN);
+	}
+
+	/*
+	 *  送信DMAコントローラ設定
+	 */
+	hspi->hdmatx->xferhalfcallback = NULL;
+	hspi->hdmatx->xfercallback = spi_dmatransmit_func;
+	hspi->hdmatx->errorcallback = spi_dmaerror_func;
+
+	/*
+	 *  LAST DMA設定
+	 */
+	sil_andw_mem((uint32_t *)(hspi->base+TOFF_SPI_CR2), SPI_CR2_LDMATX);
+	if(hspi->Init.DataSize <= SPI_DATASIZE_8BIT && hspi->hdmatx->Init.MemDataAlignment == DMA_MDATAALIGN_HALFWORD){
+	    /* Check the even/odd of the data size + crc if enabled */
+		if((hspi->TxXferCount & 0x1) == 0){
+			sil_andw_mem((uint32_t *)(hspi->base+TOFF_SPI_CR2), SPI_CR2_LDMATX);
+			hspi->TxXferCount = (hspi->TxXferCount >> 1);
+		}
+		else{
+			sil_orw_mem((uint32_t *)(hspi->base+TOFF_SPI_CR2), SPI_CR2_LDMATX);
+			hspi->TxXferCount = (hspi->TxXferCount >> 1) + 1;
+		}
+	}
+
+	/*
+	 *  送信DMAコントローラ設定
+	 */
+	dma_start(hspi->hdmatx, (uint32_t)hspi->pTxBuffPtr, (uint32_t)(hspi->base+TOFF_SPI_DR), hspi->TxXferCount);
+
+	/*  SPI有効化 */
+	if((sil_rew_mem((uint32_t *)(hspi->base+TOFF_SPI_CR1)) & SPI_CR1_SPE) == 0)
+		sil_orw_mem((uint32_t *)(hspi->base+TOFF_SPI_CR1), SPI_CR1_SPE);
+
+	/*
+	 *  SPI送信DMA設定
+	 */
+	sil_orw_mem((uint32_t *)(hspi->base+TOFF_SPI_CR2), SPI_CR2_TXDMAEN);
+
+#if SPI_WAIT_TIME != 0
+	ercd = spi_inwait(hspi, SPI_WAIT_TIME * length);
+
+	if(hspi->Init.semlock != 0)
+		sig_sem(hspi->Init.semlock);
+#endif
+	return ercd;
+}
+
+/*
+ *  SPI受信実行関数
+ *  parameter1  hspi: SPIハンドラへのポインタ
+ *  parameter2  pdata: 受信バッファへのポインタ(4バイトアライン)
+ *  parameter3  length: 送信サイズ(CRCでは+1)
+ *  return ERコード
+ */
+ER
+spi_receive(SPI_Handle_t *hspi, uint8_t *pdata, uint16_t length)
+{
+	ER ercd = E_OK;
+
+	if(hspi == NULL || pdata == NULL || length == 0)
+		return E_PAR;
+	if((((uint32_t)pdata) & 3) != 0)
+		return E_PAR;
+
+	if(hspi->Init.semlock != 0)
+		wai_sem(hspi->Init.semlock);
+	if(hspi->status != SPI_STATUS_READY){
+		if(hspi->Init.semlock != 0)
+			sig_sem(hspi->Init.semlock);
+		return E_OBJ;
+	}
+
+    /*
+	 *  転送情報を設定
+	 */
+	hspi->xmode       = SPI_XMODE_RX;
+    hspi->status      = SPI_STATUS_BUSY;
+    hspi->ErrorCode   = SPI_ERROR_NONE;
+    hspi->pRxBuffPtr  = pdata;
+    hspi->RxXferSize  = length;
+    hspi->RxXferCount = length;
+    hspi->TxXferSize   = 0;
+    hspi->TxXferCount  = 0;
+
+    /*
+	 *  1ライン通信設定
+	 */
+    if(hspi->Init.Direction == SPI_DIRECTION_1LINE){
+		sil_andw_mem((uint32_t *)(hspi->base+TOFF_SPI_CR1), SPI_CR1_BIDIOE);
+    }
+    else if(hspi->Init.Direction == SPI_DIRECTION_2LINES){
+	    hspi->status = SPI_STATUS_READY;
+		if(hspi->Init.semlock != 0)
+			sig_sem(hspi->Init.semlock);
+		if(hspi->Init.Mode == SPI_MODE_MASTER){
+			/*
+			 *  送受信を行う
+			 */
+			memset(pdata, 0xff, length);
+			return spi_transrecv(hspi, pdata, pdata, length);
+		}
+		else
+			return E_PAR;
+    }
+
+	/*
+	 *  CRCモードなら設定を有効に
+	 */
+    if(hspi->Init.CRC == SPI_CRC_ENABLE){
+      sil_andw_mem((uint32_t *)(hspi->base+TOFF_SPI_CR1), SPI_CR1_CRCEN);
+      sil_orw_mem((uint32_t *)(hspi->base+TOFF_SPI_CR1), SPI_CR1_CRCEN);
+    }
+
+	/*
+	 *  スレッシュホールド設定
+	 */
+	sil_andw_mem((uint32_t *)(hspi->base+TOFF_SPI_CR2), SPI_CR2_LDMARX);
+	if( hspi->Init.DataSize > SPI_DATASIZE_8BIT){
+		sil_andw_mem((uint32_t *)(hspi->base+TOFF_SPI_CR2), SPI_CR2_FRXTH);
+	}
+	else{
+		sil_orw_mem((uint32_t *)(hspi->base+TOFF_SPI_CR2), SPI_CR2_FRXTH);
+	}
+
+    /*
+	 *  DMA受信コールバック関数設定
+	 */
+	if((hspi->Init.Mode == SPI_MODE_MASTER)
+		 && (hspi->Init.Direction == SPI_DIRECTION_1LINE || hspi->Init.Direction == SPI_DIRECTION_2LINES_RXONLY)){
+	    hspi->hdmarx->xfercallback = spi_dmareceive_func;
+	}
+	else{
+		hspi->hdmarx->xfercallback = spi_dmatransrecv_func;
+	}
+    hspi->hdmarx->xferhalfcallback = NULL;
+    hspi->hdmarx->errorcallback = spi_dmaerror_func;
+
+	/*
+	 *  受信DMAコントローラ設定
+	 */
+    dma_start(hspi->hdmarx, (uint32_t)(hspi->base+TOFF_SPI_DR), (uint32_t)hspi->pRxBuffPtr, hspi->RxXferCount);
+
+	/*  SPI有効化 */
+	if((sil_rew_mem((uint32_t *)(hspi->base+TOFF_SPI_CR1)) & SPI_CR1_SPE) == 0)
+		sil_orw_mem((uint32_t *)(hspi->base+TOFF_SPI_CR1), SPI_CR1_SPE);
+
+	/*
+	 *  SPI受信DMA設定
+	 */
+	sil_orw_mem((uint32_t *)(hspi->base+TOFF_SPI_CR2), (SPI_CR2_RXDMAEN));
+
+#if SPI_WAIT_TIME != 0
+	ercd = spi_inwait(hspi, SPI_WAIT_TIME * length);
+
+	if(hspi->Init.semlock != 0)
+		sig_sem(hspi->Init.semlock);
+#endif
+	return ercd;
+}
+
+/*
+ *  SPI送受信実行関数
+ *  parameter1  hspi: SPIハンドラへのポインタ
+ *  parameter2  ptxdata: 送信バッファへのポインタ(4バイトアライン)
+ *  parameter3  prxdata: 受信バッファへのポインタ(4バイトアライン)
+ *  parameter4  length: 送信サイズ(CRCでは+1)
+ *  return ERコード
+ */
+ER
+spi_transrecv(SPI_Handle_t *hspi, uint8_t *ptxdata, uint8_t *prxdata, uint16_t length)
+{
+	ER ercd = E_OK;
+
+	if(hspi == NULL || prxdata == NULL || length == 0)
+		return E_PAR;
+	if((((uint32_t)ptxdata) & 3) != 0 || (((uint32_t)prxdata) & 3) != 0)
+		return E_PAR;
+	if(hspi->Init.Direction != SPI_DIRECTION_2LINES && hspi->Init.Mode != SPI_MODE_MASTER)
+		return E_PAR;
+
+	if(hspi->Init.semlock != 0)
+		wai_sem(hspi->Init.semlock);
+	if(hspi->status != SPI_STATUS_READY){
+		if(hspi->Init.semlock != 0)
+			sig_sem(hspi->Init.semlock);
+		return E_OBJ;
+	}
+
+	hspi->xmode = SPI_XMODE_TXRX;
+	hspi->status = SPI_STATUS_BUSY;
+
+	/*
+	 *  転送情報を設定
+	 */
+	hspi->ErrorCode   = SPI_ERROR_NONE;
+	hspi->pTxBuffPtr  = (uint8_t*)ptxdata;
+	hspi->TxXferSize  = length;
+	hspi->TxXferCount = length;
+	hspi->pRxBuffPtr  = (uint8_t*)prxdata;
+	hspi->RxXferSize  = length;
+	hspi->RxXferCount = length;
+
+	/*
+	 *  CRCモードなら設定を有効に
+	 */
+	if(hspi->Init.CRC == SPI_CRC_ENABLE){
+		sil_andw_mem((uint32_t *)(hspi->base+TOFF_SPI_CR1), SPI_CR1_CRCEN);
+		sil_orw_mem((uint32_t *)(hspi->base+TOFF_SPI_CR1), SPI_CR1_CRCEN);
+	}
+
+    /*
+	 *  LAST DMAとスレッシュホールド設定
+	 */
+	sil_andw_mem((uint32_t *)(hspi->base+TOFF_SPI_CR2), SPI_CR2_LDMATX);
+	sil_andw_mem((uint32_t *)(hspi->base+TOFF_SPI_CR2), SPI_CR2_LDMARX);
+	if(hspi->Init.DataSize > SPI_DATASIZE_8BIT){
+		sil_andw_mem((uint32_t *)(hspi->base+TOFF_SPI_CR2), SPI_CR2_FRXTH);
+	}
+	else{
+		sil_orw_mem((uint32_t *)(hspi->base+TOFF_SPI_CR2), SPI_CR2_FRXTH);
+		if(hspi->hdmatx->Init.MemDataAlignment == DMA_MDATAALIGN_HALFWORD){
+	        if((hspi->TxXferSize & 0x1) == 0x0 ){
+				sil_andw_mem((uint32_t *)(hspi->base+TOFF_SPI_CR2), SPI_CR2_LDMATX);
+				hspi->TxXferCount = hspi->TxXferCount >> 1;
+			}
+			else{
+				sil_orw_mem((uint32_t *)(hspi->base+TOFF_SPI_CR2), SPI_CR2_LDMATX);
+				hspi->TxXferCount = (hspi->TxXferCount >> 1) + 1;
+			}
+		}
+		if(hspi->hdmarx->Init.MemDataAlignment == DMA_MDATAALIGN_HALFWORD){
+			sil_andw_mem((uint32_t *)(hspi->base+TOFF_SPI_CR2), SPI_CR2_FRXTH);
+			if((hspi->RxXferCount & 0x1) == 0){
+				sil_andw_mem((uint32_t *)(hspi->base+TOFF_SPI_CR2), SPI_CR2_LDMARX);
+				hspi->RxXferCount = hspi->RxXferCount >> 1;
+			}
+			else{
+				sil_orw_mem((uint32_t *)(hspi->base+TOFF_SPI_CR2), SPI_CR2_LDMARX);
+				hspi->RxXferCount = (hspi->RxXferCount >> 1) + 1;
+			}
+		}
+	}
+
+	/*
+	 *  DMA受信コールバック関数設定
+	 */
+	if((hspi->Init.Mode == SPI_MODE_MASTER)
+		 && (hspi->Init.Direction == SPI_DIRECTION_1LINE || hspi->Init.Direction == SPI_DIRECTION_2LINES_RXONLY)){
+		hspi->hdmarx->xfercallback = spi_dmareceive_func;
+	}
+	else{
+		hspi->hdmarx->xfercallback = spi_dmatransrecv_func;
+	}
+	hspi->hdmarx->xferhalfcallback = NULL;
+	hspi->hdmarx->errorcallback = spi_dmaerror_func;
+
+	/*
+	 *  受信DMAコントローラ設定
+	 */
+	dma_start(hspi->hdmarx, (uint32_t)(hspi->base+TOFF_SPI_DR), (uint32_t)hspi->pRxBuffPtr, hspi->RxXferCount);
+
+	/*
+	 *  SPI受信DMA設定
+	 */
+	sil_orw_mem((uint32_t *)(hspi->base+TOFF_SPI_CR2), SPI_CR2_RXDMAEN);
+
+	/*
+	 *  DMA送信コールバックの設定
+	 */
+	hspi->hdmatx->xfercallback = NULL;
+	hspi->hdmatx->errorcallback = spi_dmaerror_func;
+
+	/*
+	 *  送信DMAコントローラ設定
+	 */
+	dma_start(hspi->hdmatx, (uint32_t)hspi->pTxBuffPtr, (uint32_t)(hspi->base+TOFF_SPI_DR), hspi->TxXferCount);
+
+	/*
+	 *  SPIエラー割込み設定
+	 */
+	sil_orw_mem((uint32_t *)(hspi->base+TOFF_SPI_CR2), SPI_CR2_ERRIE);
+
+	/*  SPI有効化 */
+	if((sil_rew_mem((uint32_t *)(hspi->base+TOFF_SPI_CR1)) & SPI_CR1_SPE) == 0)
+		sil_orw_mem((uint32_t *)(hspi->base+TOFF_SPI_CR1), SPI_CR1_SPE);
+
+	/*
+	 *  SPI送信DMA設定
+	 */
+	sil_orw_mem((uint32_t *)(hspi->base+TOFF_SPI_CR2), SPI_CR2_TXDMAEN);
+
+#if SPI_WAIT_TIME != 0
+	ercd = spi_inwait(hspi, SPI_WAIT_TIME * length);
+
+	if(hspi->Init.semlock != 0)
+		sig_sem(hspi->Init.semlock);
+#endif
+	return ercd;
+}
+
+/*
+ *  SPI転送終了待ち
+ */
+ER
+spi_wait(SPI_Handle_t *hspi, uint32_t timeout)
+{
+	ER ercd = E_OK;
+
+#if SPI_WAIT_TIME == 0
+	if(hspi == NULL)
+		return E_PAR;
+	ercd = spi_inwait(hspi, timeout);
+	if(hspi->Init.semlock != 0)
+		sig_sem(hspi->Init.semlock);
+#endif
+	return ercd;
+}
+
+/*
+ *  SPI割込みサービスルーチン
+ */
+void
+spi_handler(SPI_Handle_t *hspi)
+{
+	volatile uint32_t tmp3 = 0;
+
+	/*
+	 *  割込みエラー判定
+	 */
+	if((sil_rew_mem((uint32_t *)(hspi->base+TOFF_SPI_CR2)) & SPI_CR2_ERRIE) != 0){
+		/*
+		 *  SPI CRCエラー判定
+		 */
+		if((sil_rew_mem((uint32_t *)(hspi->base+TOFF_SPI_SR)) & SPI_SR_CRCERR) != 0){
+			hspi->ErrorCode |= SPI_ERROR_CRC;
+			sil_andw_mem((uint32_t *)(hspi->base+TOFF_SPI_SR), SPI_SR_CRCERR);
+		}
+		/*
+		 *  SPI モードフォルト判定
+		 */
+		if((sil_rew_mem((uint32_t *)(hspi->base+TOFF_SPI_SR)) & SPI_SR_MODF) != 0){
+			hspi->ErrorCode |= SPI_ERROR_MODF;
+			sil_andw_mem((uint32_t *)(hspi->base+TOFF_SPI_SR), SPI_SR_MODF);
+            sil_andw_mem((uint32_t *)(hspi->base+TOFF_SPI_CR1), SPI_CR1_SPE);
+		}
+		/*
+		 *  SPI オーバーラン判定
+		 */
+		if((sil_rew_mem((uint32_t *)(hspi->base+TOFF_SPI_SR)) & SPI_SR_OVR) != 0){
+			if(hspi->xmode != SPI_XMODE_TX){
+				hspi->ErrorCode |= SPI_ERROR_OVR;
+				tmp3 = sil_rew_mem((uint32_t *)(hspi->base+TOFF_SPI_DR));
+				((void)(tmp3));
+				sil_andw_mem((uint32_t *)(hspi->base+TOFF_SPI_SR), SPI_SR_OVR);
+			}
+		}
+		/*
+		 *  SPI フレームエラー判定
+		 */
+		if((sil_rew_mem((uint32_t *)(hspi->base+TOFF_SPI_SR)) & SPI_SR_FRE) != 0){
+			hspi->ErrorCode |= SPI_ERROR_FRE;
+			sil_andw_mem((uint32_t *)(hspi->base+TOFF_SPI_SR), SPI_SR_FRE);
+		}
+		/*
+		 *  エラー発生時はレディに戻す
+		 */
+		if(hspi->ErrorCode != SPI_ERROR_NONE){
+            sil_andw_mem((uint32_t *)(hspi->base+TOFF_SPI_CR1), SPI_CR1_SPE);
+			hspi->status = SPI_STATUS_READY;
+			syslog_2(LOG_ERROR, "spi hanndler error[%08x] ErrorCode[%08x] !", hspi, hspi->ErrorCode);
+		}
+	}
+}
+
+
+/*
+ *  SPI割込みサービスルーチン
+ */
+void spi_isr(intptr_t exinf)
+{
+  spi_handler(&SpiHandle[INDEX_SPI((uint32_t)exinf)]);
+}
+
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/pdic/stm32f7xx/spi.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/pdic/stm32f7xx/spi.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/pdic/stm32f7xx/spi.h	(revision 457)
@@ -0,0 +1,259 @@
+/*
+ *  TOPPERS/ASP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Advanced Standard Profile Kernel
+ * 
+ *  Copyright (C) 2008-2011 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ *  Copyright (C) 2015-2016 by TOPPERS PROJECT Educational Working Group.
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+/*
+ * 
+ *  STM32F4XX SPIデバイスドライバの外部宣言
+ *
+ */
+
+#ifndef _SPI_H_
+#define _SPI_H_
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/*
+ *  SPIポート定義
+ */
+#define SPI1_PORTID             1
+#define SPI2_PORTID             2
+#define NUM_SPIPORT             2
+
+/*
+ *  SPI状態定義
+ */
+#define SPI_STATUS_RESET        0x00	/* SPI未使用状態 */
+#define SPI_STATUS_READY        0x01	/* SPIレディ状態 */
+#define SPI_STATUS_ERROR        0x02	/* SPIエラー状態 */
+#define SPI_STATUS_BUSY         0x04	/* SPI処理中 */
+
+/*
+ *  SPIエラー定義
+ */ 
+#define SPI_ERROR_NONE          0x00000000	/* No error */
+#define SPI_ERROR_MODF          0x00000001	/* MODF error */
+#define SPI_ERROR_CRC           0x00000002	/* CRC error */
+#define SPI_ERROR_OVR           0x00000004	/* OVR error */
+#define SPI_ERROR_FRE           0x00000008	/* FRE error */
+#define SPI_ERROR_DMA           0x00000010	/* DMA transfer error */
+#define SPI_ERROR_TIMEOUT       0x00000020
+
+/*
+ *  SPI転送モード
+ */
+#define SPI_XMODE_TX            0x00000000	/* 送信モード */
+#define SPI_XMODE_RX            0x00000001	/* 受信モード */
+#define SPI_XMODE_TXRX          0x00000002	/* 送受信モード */
+
+/*
+ *  SPIモード定義
+ */
+#define SPI_MODE_SLAVE          0x00000000
+#define SPI_MODE_MASTER         (SPI_CR1_MSTR | SPI_CR1_SSI)
+
+
+/*
+ *  SPIデータサイズ定義
+ */
+#define SPI_DATASIZE_4BIT       0x00000300
+#define SPI_DATASIZE_5BIT       0x00000400
+#define SPI_DATASIZE_6BIT       0x00000500
+#define SPI_DATASIZE_7BIT       0x00000600
+#define SPI_DATASIZE_8BIT       0x00000700
+#define SPI_DATASIZE_9BIT       0x00000800
+#define SPI_DATASIZE_10BIT      0x00000900
+#define SPI_DATASIZE_11BIT      0x00000A00
+#define SPI_DATASIZE_12BIT      0x00000B00
+#define SPI_DATASIZE_13BIT      0x00000C00
+#define SPI_DATASIZE_14BIT      0x00000D00
+#define SPI_DATASIZE_15BIT      0x00000E00
+#define SPI_DATASIZE_16BIT      0x00000F00
+
+/*
+ *  SPI転送クロック極性定義
+ */
+#define SPI_POLARITY_LOW        0x00000000
+#define SPI_POLARITY_HIGH       SPI_CR1_CPOL
+
+/*
+ *  SPIクロック位相定義
+ */
+#define SPI_PHASE_1EDGE         0x00000000
+#define SPI_PHASE_2EDGE         SPI_CR1_CPHA
+
+/*
+ *  SPI NSS定義
+ */
+#define SPI_NSS_SOFT            SPI_CR1_SSM
+#define SPI_NSS_HARD_INPUT      0x00000000
+#define SPI_NSS_HARD_OUTPUT     0x00040000
+
+/*
+ *  SPI MSB/LSB定義
+ */
+#define SPI_DATA_MSB            0x00000000
+#define SPI_DATA_LSB            SPI_CR1_LSBFIRST
+
+/*
+ *  SPIプリスケーラ設定
+ */
+#define SPI_BAUDRATEPRESCALER_2   0x00000000
+#define SPI_BAUDRATEPRESCALER_4   0x00000008
+#define SPI_BAUDRATEPRESCALER_8   0x00000010
+#define SPI_BAUDRATEPRESCALER_16  0x00000018
+#define SPI_BAUDRATEPRESCALER_32  0x00000020
+#define SPI_BAUDRATEPRESCALER_64  0x00000028
+#define SPI_BAUDRATEPRESCALER_128 0x00000030
+#define SPI_BAUDRATEPRESCALER_256 0x00000038
+
+/*
+ *  CRC長定義
+ */
+#define SPI_CRC_LENGTH_DATASIZE   0x00000000
+#define SPI_CRC_LENGTH_8BIT       0x00000001
+#define SPI_CRC_LENGTH_16BIT      0x00000002
+
+/*
+ *  SPI TIモード設定定義
+ */
+#define SPI_TIMODE_DISABLE      0x00000000
+#define SPI_TIMODE_ENABLE       SPI_CR2_FRF
+
+/*
+ *  SPIライン設定
+ */
+#define SPI_DIRECTION_2LINES             ((uint32_t)0x00000000)
+#define SPI_DIRECTION_2LINES_RXONLY      SPI_CR1_RXONLY
+#define SPI_DIRECTION_1LINE              SPI_CR1_BIDIMODE
+
+/*
+ *  SPI CRC設定定義
+ */
+#define SPI_CRC_DISABLE         0x00000000
+#define SPI_CRC_ENABLE          SPI_CR1_CRCEN
+
+/*
+ *  SPIハードウェア設定構造体
+ */
+
+typedef struct _SPI_PortControlBlock{
+	uint32_t              base;
+	uint32_t              gioclockbase;
+	uint32_t              gioclockbit;
+	uint32_t              gioclockbit2;
+	uint32_t              spiclockbase;
+	uint32_t              spiclockbit;
+	uint32_t              dmaclockbase;
+	uint32_t              dmaclockbit;
+
+	uint32_t              giobase1;
+	uint32_t              giobase2;
+	uint32_t              giobase3;
+	uint8_t               sckpin;
+	uint8_t               misopin;
+	uint8_t               mosipin;
+	uint8_t               apvalue;
+	uint32_t              dmatxchannel;
+	uint32_t              dmatxbase;
+	uint32_t              dmarxchannel;
+	uint32_t              dmarxbase;
+} SPI_PortControlBlock;
+
+/*
+ *  SPI 設定初期設定構造体
+ */
+typedef struct
+{
+	uint32_t              Mode;				/* SPIマスタースレーブ設定 */
+	uint32_t              Direction;		/* SPI転送方向 */
+    uint32_t              DataSize;			/* SPI転送データサイズ */
+	uint32_t              CLKPolarity;		/* SPI転送クロックの極性 */
+	uint32_t              CLKPhase;			/* SPIクロック位相 */
+	uint32_t              NSS;				/* SPI NSS */
+	uint32_t              Prescaler;		/* SPIクロック分周設定 */
+	uint32_t              SignBit;			/* SPI MSB/LSB設定 */
+	uint32_t              TIMode;			/* SPI TIモード */
+	uint32_t              CRC;				/* SPI CRC演算設定 */
+	uint32_t              CRCPolynomial;	/* SPI CRC多項式設定 */
+	uint32_t              CRCLength;		/* SPI CRC長 */
+	int                   semid;			/* SPI 通信用セマフォ値 */
+	int                   semlock;			/* SPI ロックセマフォ値 */
+}SPI_Init_t;
+
+/*
+ *  SPIハンドラ
+ */
+typedef struct _SPI_Handle_t
+{
+	uint32_t              base;				/* SPI registers base address */
+	SPI_Init_t            Init;				/* SPI communication parameters */
+	uint8_t               *pTxBuffPtr;		/* Pointer to SPI Tx transfer Buffer */
+	uint16_t              TxXferSize;		/* SPI Tx transfer size */
+	uint16_t              TxXferCount;		/* SPI Tx Transfer Counter */
+	uint8_t               *pRxBuffPtr;		/* Pointer to SPI Rx transfer Buffer */
+	uint16_t              RxXferSize;		/* SPI Rx transfer size */
+	uint16_t              RxXferCount;		/* SPI Rx Transfer Counter */
+	DMA_Handle_t          *hdmatx;			/* SPI Tx DMA handle parameters */
+	DMA_Handle_t          *hdmarx;			/* SPI Rx DMA handle parameters */
+	uint32_t              xmode;
+	volatile uint32_t     status;			/* SPI communication state */
+	volatile uint32_t     ErrorCode;		/* SPI Error code */
+}SPI_Handle_t;
+
+
+
+extern SPI_Handle_t *spi_init(ID port, SPI_Init_t *spii);
+extern ER spi_deinit(SPI_Handle_t *hspi);
+extern ER spi_reset(SPI_Handle_t *hspi);
+extern ER spi_transmit(SPI_Handle_t *hspi, uint8_t *pdata, uint16_t length);
+extern ER spi_receive(SPI_Handle_t *hspi, uint8_t *pdata, uint16_t length);
+extern ER spi_transrecv(SPI_Handle_t *hspi, uint8_t *ptxData, uint8_t *prxData, uint16_t length);
+extern ER spi_wait(SPI_Handle_t *hspi, uint32_t timeout);
+extern void spi_handler(SPI_Handle_t *hspi);
+extern void spi_isr(intptr_t exinf);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif	/* _SPI_H_ */
+
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/pdic/stm32f7xx/usb_otg.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/pdic/stm32f7xx/usb_otg.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/pdic/stm32f7xx/usb_otg.c	(revision 457)
@@ -0,0 +1,2785 @@
+/*
+ *  TOPPERS/ASP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Advanced Standard Profile Kernel
+ * 
+ *  Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
+ *                              Toyohashi Univ. of Technology, JAPAN
+ *  Copyright (C) 2015-2019 by TOPPERS PROJECT Educational Working Group.
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  $Id$
+ */
+
+/* 
+ *  USB_OTGドライバの本体
+ */
+
+#include "kernel_impl.h"
+#include <t_syslog.h>
+#include <t_stdlib.h>
+#include <string.h>
+#include <sil.h>
+#include "syssvc/serial.h"
+#include "syssvc/syslog.h"
+#include "kernel_cfg.h"
+#include <target_syssvc.h>
+#include "device.h"
+#include "usb_otg.h"
+
+#define sil_orw_mem(a, b)		sil_wrw_mem((a), sil_rew_mem(a) | (b))
+#define sil_andw_mem(a, b)		sil_wrw_mem((a), sil_rew_mem(a) & ~(b))
+#define sil_andxw_mem(a, b)		sil_wrw_mem((a), sil_rew_mem(a) & (b))
+#define sil_modw_mem(a, b, c)	sil_wrw_mem((a), (sil_rew_mem(a) & (~b)) | (c))
+
+#define get_usbmode(a)          (sil_rew_mem((uint32_t *)(USBOTG_BASE((a))+TOFF_USBO_GINTSTS)) & 1)
+#define get_int_status(a, b)    (sil_rew_mem((uint32_t *)(USBOTG_BASE((a))+TOFF_USBO_GINTSTS)) & (b))
+#define hc_int_status(a, b, c)  (sil_rew_mem((uint32_t *)(USBHC_BASE((a), (b))+TOFF_USBHC_HCINT)) & (c))
+#define get_haint_status(a)     (sil_rew_mem((uint32_t *)(USBH_BASE((a))+TOFF_USBH_HAINT)) & 0xFFFF)
+#define clear_host_int(a, b)    sil_wrw_mem((uint32_t *)(USBOTG_BASE((a))+TOFF_USBO_GINTSTS), (b))
+#define clear_dev_int(a, b)		sil_andxw_mem((uint32_t *)(USBOTG_BASE((a))+TOFF_USBO_GINTSTS), (b))
+#define clear_hc_int(a, b, c)   sil_wrw_mem((uint32_t *)(USBHC_BASE((a), (b))+TOFF_USBHC_HCINT), (c))
+#define clear_outep_int(a, b, c) sil_wrw_mem((uint32_t *)(USBOEP_BASE((a), (b))+TOFF_USBEO_DOEPINT), (c))
+#define clear_inep_int(a, b, c) sil_wrw_mem((uint32_t *)(USBIEP_BASE((a), (b))+TOFF_USBEI_DIEPINT), (c))
+#define get_inep_int_status(a)  ((sil_rew_mem((uint32_t *)(USBD_BASE((a))+TOFF_USBD_DAINT)) \
+								& sil_rew_mem((uint32_t *)(USBD_BASE((a))+TOFF_USBD_DAINTMSK))) & 0xFFFF)
+#define get_outep_int_status(a) (((sil_rew_mem((uint32_t *)(USBD_BASE((a))+TOFF_USBD_DAINT)) \
+								& sil_rew_mem((uint32_t *)(USBD_BASE((a))+TOFF_USBD_DAINTMSK))) & 0xFFFF0000) >> 16)
+
+#define get_packet_data(s)      ((s[0] & 0xff) | ((s[1] & 0xff)<<8) | ((s[2] & 0xff)<<16) | ((s[3] & 0xff)<<24))
+
+/*
+ *  USB用 AF10定義
+ */
+#define GPIO_AF10_OTG_FS        ((uint8_t)0x0AU)  /* OTG_FS Alternate Function mapping */
+#define GPIO_AF10_OTG_HS        ((uint8_t)0x0AU)  /* OTG_HS Alternate Function mapping */
+
+/*
+ *  デフォルトFIFO設定
+ */
+#define DEFAULT_FS_GRXFSIZ      0x80
+#define DEFAULT_HS_GRXFSIZ      0x200
+#define DEFAULT_FS_TXFIFO0_SIZ  0x60		/* 0x40 */
+#define DEFAULT_HS_TXFIFO0_SIZ  0x100
+#define DEFAULT_FS_TXFIFO1_SIZ  0x80		/* 0x40 */
+#define DEFAULT_HS_TXFIFO1_SIZ  0xE0
+
+
+/*
+ *  パケットサイズ定義
+ */
+#define USB_OTG_HS_MAX_PACKET_SIZE           512
+#define USB_OTG_FS_MAX_PACKET_SIZE           64
+#define USB_OTG_MAX_EP0_SIZE                 64
+
+/*
+ *  PHY周波数定義
+ */
+#define DSTS_ENUMSPD_HS_PHY_30MHZ_OR_60MHZ     (0 << 1)
+#define DSTS_ENUMSPD_FS_PHY_30MHZ_OR_60MHZ     (1 << 1)
+#define DSTS_ENUMSPD_LS_PHY_6MHZ               (2 << 1)
+#define DSTS_ENUMSPD_FS_PHY_48MHZ              (3 << 1)
+
+/*
+ * フレームインターバル定義
+ */
+#define DCFG_FRAME_INTERVAL_80                 0
+#define DCFG_FRAME_INTERVAL_85                 1
+#define DCFG_FRAME_INTERVAL_90                 2
+#define DCFG_FRAME_INTERVAL_95                 3
+
+/*
+ *  パケットステータス定義
+ */
+#define STS_GOUT_NAK                           1
+#define STS_DATA_UPDT                          2
+#define STS_XFER_COMP                          3
+#define STS_SETUP_COMP                         4
+#define STS_SETUP_UPDT                         6
+
+/*
+ *  PHYスピード定義
+ */
+#define HPRT0_PRTSPD_HIGH_SPEED                0
+#define HPRT0_PRTSPD_FULL_SPEED                1
+#define HPRT0_PRTSPD_LOW_SPEED                 2
+
+/*
+ *  ホストクラスエンドポイントタイプ定義
+ */
+#define HCCHAR_CTRL                            0
+#define HCCHAR_ISOC                            1
+#define HCCHAR_BULK                            2
+#define HCCHAR_INTR                            3
+
+
+#define GRXSTS_PKTSTS_IN                       2
+#define GRXSTS_PKTSTS_IN_XFER_COMP             3
+#define GRXSTS_PKTSTS_DATA_TOGGLE_ERR          5
+#define GRXSTS_PKTSTS_CH_HALTED                7
+
+#define RESET_TIMEOUT           (1000*100)		/* 1ms */
+#define HALT_TIMEOUT            (10*100)		/* 0.01ms */
+#ifndef USB_OTG_FS_WAKEUP_EXTI_LINE
+#define USB_OTG_FS_WAKEUP_EXTI_LINE         0x00040000  /* External interrupt line 18 Connected to the USB FS EXTI Line */
+#endif
+
+#define GHWCFG3_XFER_SIZE_CNTR_WIDTH           0x0000000f
+#define GHWCFG3_PACKET_SIZE_CNTR_WIDTH         0x00000070
+#define GHWCFG3_I2C                            0x00000100
+#define GHWCFG3_DFIFO_DEPTH                    0xffff0000
+#define GRXFSIZ_DEPTH                          0x0000ffff
+
+/*
+ *  USBポートIDから管理ブロックを取り出すためのマクロ
+ */
+#define INDEX_USB(usbid)        ((uint_t)((usbid) - 1))
+
+#ifndef TADR_USB_OTGHS_BASE
+#define NUM_USBHANDLE   1
+#else
+#define NUM_USBHANDLE   NUM_USBPORT
+#endif
+
+#if !defined(_STM32F7XX_H_)
+#define flushinvalidatedcache_by_addr(a, b)
+#endif
+
+static USB_OTG_Handle_t Husb[NUM_USBPORT];
+
+extern ER sysclock_config(int mode);
+
+/*
+ *  必要なら強制モードを設定する
+ *  強制モードならtrueを返す
+ */
+static bool_t
+usbo_force_mode_if_needed(USB_OTG_Handle_t *husb, bool_t host)
+{
+	uint32_t otgmode = get_usbmode(husb->base);
+	uint32_t reqmode = husb->Init.usb_otg_mode;
+	uint32_t gusbcfg;
+	uint32_t set, clear;
+
+	if (host && (otgmode == USB_OTG_MODE_HOST || reqmode == USB_OTG_MODE_DEVICE))
+		return false;
+	else if (!host && (otgmode == USB_OTG_MODE_DEVICE || reqmode == USB_OTG_MODE_HOST))
+		return false;
+
+	gusbcfg = sil_rew_mem((uint32_t *)(USBOTG_BASE(husb->base)+TOFF_USBO_GUSBCFG));
+	set = host ? USB_OTG_GUSBCFG_FHMOD : USB_OTG_GUSBCFG_FDMOD;
+	clear = host ? USB_OTG_GUSBCFG_FDMOD : USB_OTG_GUSBCFG_FHMOD;
+	gusbcfg &= ~clear;
+	gusbcfg |= set;
+	sil_wrw_mem((uint32_t *)(USBOTG_BASE(husb->base)+TOFF_USBO_GUSBCFG), gusbcfg);
+
+	dly_tsk(25);
+	return true;
+}
+
+/*
+ *  強制モードをクリアする
+ */
+static void
+usbo_clear_force_mode(USB_OTG_Handle_t *husb)
+{
+	uint32_t gusbcfg;
+
+	gusbcfg = sil_rew_mem((uint32_t *)(USBOTG_BASE(husb->base)+TOFF_USBO_GUSBCFG));
+	gusbcfg &= ~USB_OTG_GUSBCFG_FHMOD;
+	gusbcfg &= ~USB_OTG_GUSBCFG_FDMOD;
+	sil_wrw_mem((uint32_t *)(USBOTG_BASE(husb->base)+TOFF_USBO_GUSBCFG), gusbcfg);
+
+	/*
+	 *  設定変更による待ち
+	 */
+	dly_tsk(25);
+}
+
+/*
+ *  USB-OTGモードチェック
+ */
+static void
+usbo_get_hwparam(USB_OTG_Handle_t *husb)
+{
+	USB_OTG_HwParam_t *hw = &husb->hw_params;
+	uint32_t hwcfg3, grxfsiz;
+	unsigned int width;
+
+#ifdef TOFF_USBO_GHWCFG3
+	hwcfg3 = sil_rew_mem((uint32_t *)(husb->base+TOFF_USBO_GHWCFG3));
+#else
+	hwcfg3 = 0x200d1e8;
+#endif
+	grxfsiz = sil_rew_mem((uint32_t *)(husb->base+TOFF_USBO_GRXFSIZ));
+	syslog_2(LOG_NOTICE, "hwcfg3=%08x grxfsiz=%08x", hwcfg3, grxfsiz);
+
+	hw->en_multiple_tx_fifo = 0;
+	width = hwcfg3 & GHWCFG3_XFER_SIZE_CNTR_WIDTH;
+	hw->max_transfer_size = (1 << (width + 11)) - 1;
+	width = (hwcfg3 & GHWCFG3_PACKET_SIZE_CNTR_WIDTH) >> 4;
+	hw->max_packet_count = (1 << (width + 4)) - 1;
+	hw->total_fifo_size = (hwcfg3 & GHWCFG3_DFIFO_DEPTH) >> 16;
+	hw->host_rx_fifo_size = grxfsiz & GRXFSIZ_DEPTH;
+
+	syslog_1(LOG_NOTICE, "  max_transfer_size=%d", hw->max_transfer_size);
+	syslog_1(LOG_NOTICE, "  max_packet_count=%d", hw->max_packet_count);
+	syslog_1(LOG_NOTICE, "  en_multiple_tx_fifo=%d", hw->en_multiple_tx_fifo);
+	syslog_1(LOG_NOTICE, "  total_fifo_size=%d", hw->total_fifo_size);
+	syslog_1(LOG_NOTICE, "  host_rx_fifo_size=%d", hw->host_rx_fifo_size);
+}
+
+/*
+ *  USB OTG 省エネモード復帰
+ */
+static ER
+usbo_exit_hibernation(USB_OTG_Handle_t *husb, bool_t restore)
+{
+	/*
+	 *  リモートウェークアップシグナルクリア
+	 */
+	sil_andw_mem((uint32_t *)(USBD_BASE(husb->base)+TOFF_USBD_DCTL), USB_OTG_DCTL_RWUSIG);
+	return E_OK;
+}
+
+/*
+ *  USB OTG 省エネモード移行
+ */
+static ER
+usbo_enter_hibernation(USB_OTG_Handle_t *husb)
+{
+	sil_orw_mem((uint32_t *)(USBPGC_BASE(husb->base)), USB_OTG_PCGCCTL_STOPCLK);
+	/*Enter in STOP mode */
+	if(husb->Init.low_power_enable){
+		/* Set SLEEPDEEP bit and SleepOnExit of Cortex System Control Register */
+		sil_orw_mem((uint32_t *)(TADR_SCB_BASE+TOFF_SCB_SCR), (SCB_SCR_SLEEPDEEP_Msk | SCB_SCR_SLEEPONEXIT_Msk));
+	}
+	return E_OK;
+}
+
+/*
+ *  USB_OTGハードウェア初期化
+ *  parameter1 portid USBポートID
+ *  parameter2 pini   初期化構造体へのポインタ
+ *  return     NULLでなければUSBハンドラへのポインタ
+ */
+USB_OTG_Handle_t *
+usbo_init(ID portid, USB_OTG_Init_t *pini)
+{
+	GPIO_Init_t GPIO_Init_Data;
+	USB_OTG_Handle_t *husb;
+	uint32_t base;
+	uint32_t no;
+	volatile uint32_t tmpreg = 0x00U;
+
+	if(portid < USB1_PORTID || portid > NUM_USBHANDLE)
+		return NULL;
+
+	no = INDEX_USB(portid);
+	husb = &Husb[no];
+	memcpy(&husb->Init, pini, sizeof(USB_OTG_Init_t));
+
+	if(portid == USB1_PORTID){	/* USB OTG FSポート */
+		husb->base = TADR_USB_OTGFS_BASE;
+		/*
+		 *  GPIO/USBポートクロック起動
+		 */
+		sil_orw_mem((uint32_t *)ENABLE_FS_BASE1, ENABLE_FS_VAL1);
+#if defined(ENABLE_FS_BASE2)
+		sil_orw_mem((uint32_t *)ENABLE_FS_BASE2, ENABLE_FS_VAL2);
+#endif
+
+		/*USB DM and DP */
+		GPIO_Init_Data.mode      = GPIO_MODE_AF;
+		GPIO_Init_Data.pull      = GPIO_NOPULL;
+		GPIO_Init_Data.otype     = GPIO_OTYPE_PP;
+		GPIO_Init_Data.speed     = GPIO_SPEED_HIGH;
+		GPIO_Init_Data.alternate = GPIO_AF10_OTG_FS;
+		gpio_setup(TADR_FS_G1_BASE, &GPIO_Init_Data, FS_DM_PINNO);
+		gpio_setup(TADR_FS_G1_BASE, &GPIO_Init_Data, FS_DP_PINNO);
+
+#if defined(FS_ID_PINNO)
+		/*USB ID */
+		GPIO_Init_Data.mode      = GPIO_MODE_AF;
+		GPIO_Init_Data.pull      = GPIO_PULLUP;
+		GPIO_Init_Data.otype     = GPIO_OTYPE_OD;
+		GPIO_Init_Data.speed     = GPIO_SPEED_HIGH;
+		GPIO_Init_Data.alternate = GPIO_AF10_OTG_FS;
+		gpio_setup(TADR_FS_G1_BASE, &GPIO_Init_Data, FS_ID_PINNO);
+#endif
+
+#if defined(FS_VBUS_PINNO)
+		/* Configure VBUS Pin(DEVICE) */
+		GPIO_Init_Data.mode      = GPIO_MODE_INPUT;
+		GPIO_Init_Data.pull      = GPIO_NOPULL;
+		GPIO_Init_Data.otype     = GPIO_OTYPE_PP;
+		gpio_setup(TADR_FS_G1_BASE, &GPIO_Init_Data, FS_VBUS_PINNO);
+#endif
+
+#if defined(FS_POWERSW_PINO)
+		/* Configure POWER_SWITCH IO pin(HOST) */
+		GPIO_Init_Data.mode      = GPIO_MODE_OUTPUT;
+		GPIO_Init_Data.pull      = GPIO_NOPULL;
+#ifdef FS_G2_PORT_TYPE
+		GPIO_Init_Data.otype     = FS_G2_PORT_TYPE;
+#else
+		GPIO_Init_Data.otype     = GPIO_OTYPE_PP;
+#endif
+		GPIO_Init_Data.speed     = GPIO_SPEED_HIGH;
+		gpio_setup(TADR_FS_G2_BASE, &GPIO_Init_Data, FS_POWERSW_PINO);
+#endif
+
+		/*
+		 *  USB FSクロック設定
+		 */
+		sil_orw_mem((uint32_t *)(TADR_RCC_BASE+TOFF_RCC_USBFS), RCC_USBFSEN);
+		sil_orw_mem((uint32_t *)(TADR_RCC_BASE+TOFF_RCC_SYSFG), RCC_SYSGFGEN);
+		tmpreg = sil_rew_mem((uint32_t *)(TADR_RCC_BASE+TOFF_RCC_SYSFG));
+
+		/*
+		 *  FIFO設定値
+		 */
+		usbo_get_hwparam(husb);
+		husb->fifo_mem            = husb->hw_params.total_fifo_size;
+		husb->pcd_rx_fifo_sz      = DEFAULT_FS_GRXFSIZ;
+		husb->pcd_np_g_tx_fifo_sz = DEFAULT_FS_TXFIFO0_SIZ;
+		husb->pcd_tx_fifo_sz[1]   = DEFAULT_FS_TXFIFO1_SIZ;
+	}
+#ifdef TADR_USB_OTGHS_BASE
+	else{				/* USB OTG HSポート */
+		husb->base = TADR_USB_OTGHS_BASE;
+		/*
+		 *  GPIO/USBポートクロック起動
+		 */
+		sil_orw_mem((uint32_t *)ENABLE_HS_BASE, ENABLE_HS_VAL2);
+		sil_orw_mem((uint32_t *)ENABLE_HS_BASE, ENABLE_HS_VAL3);
+#if defined(TOPPERS_STM32F723_DISCOVERY)
+
+		/*USB DM and DP */
+		GPIO_Init_Data.mode      = GPIO_MODE_AF;
+		GPIO_Init_Data.pull      = GPIO_NOPULL;
+		GPIO_Init_Data.otype     = GPIO_OTYPE_PP;
+		GPIO_Init_Data.speed     = GPIO_SPEED_HIGH;
+		GPIO_Init_Data.alternate = GPIO_AF10_OTG_HS;
+		gpio_setup(TADR_GPIOB_BASE, &GPIO_Init_Data, 14);
+		gpio_setup(TADR_GPIOB_BASE, &GPIO_Init_Data, 15);
+
+		/* Configure POWER_SWITCH IO pin(HOST) */
+		GPIO_Init_Data.mode      = GPIO_MODE_OUTPUT;
+		GPIO_Init_Data.pull      = GPIO_NOPULL;
+		GPIO_Init_Data.speed     = GPIO_SPEED_HIGH;
+		GPIO_Init_Data.otype     = GPIO_OTYPE_PP;
+		gpio_setup(TADR_GPIOH_BASE, &GPIO_Init_Data, 12);
+
+
+		/*
+		 *  USB HS-PHYクロック設定
+		 */
+		sil_orw_mem((uint32_t *)(TADR_RCC_BASE+TOFF_RCC_AHB1ENR), RCC_AHB1ENR_OTGHSULPIEN);
+		tmpreg = sil_rew_mem((uint32_t *)(TADR_RCC_BASE+TOFF_RCC_AHB1ENR));
+
+		sil_orw_mem((uint32_t *)(TADR_RCC_BASE+TOFF_RCC_AHB1ENR), RCC_AHB1ENR_OTGHSULPIEN);
+		tmpreg = sil_rew_mem((uint32_t *)(TADR_RCC_BASE+TOFF_RCC_AHB1ENR));
+
+#else	/* !TOPPERS_STM32F723_DISCOVERY */
+		sil_orw_mem((uint32_t *)ENABLE_HS_BASE, ENABLE_HS_VAL4);
+		sil_orw_mem((uint32_t *)ENABLE_HS_BASE, ENABLE_HS_VAL5);
+		sil_orw_mem((uint32_t *)ENABLE_HS_BASE, ENABLE_HS_VAL1);
+
+		/* CLK */
+		GPIO_Init_Data.mode      = GPIO_MODE_AF;
+		GPIO_Init_Data.pull      = GPIO_NOPULL;
+		GPIO_Init_Data.otype     = GPIO_OTYPE_PP;
+		GPIO_Init_Data.speed     = GPIO_SPEED_HIGH;
+		GPIO_Init_Data.alternate = GPIO_AF10_OTG_HS;
+		gpio_setup(TADR_GPIOA_BASE, &GPIO_Init_Data, 5);
+
+		/* D0 */
+		gpio_setup(TADR_GPIOA_BASE, &GPIO_Init_Data, 3);
+
+		/* D1 D2 D3 D4 D5 D6 D7 */
+		gpio_setup(TADR_GPIOB_BASE, &GPIO_Init_Data, 0);
+		gpio_setup(TADR_GPIOB_BASE, &GPIO_Init_Data, 1);
+		gpio_setup(TADR_GPIOB_BASE, &GPIO_Init_Data, 5);
+		gpio_setup(TADR_GPIOB_BASE, &GPIO_Init_Data, 10);
+		gpio_setup(TADR_GPIOB_BASE, &GPIO_Init_Data, 11);
+		gpio_setup(TADR_GPIOB_BASE, &GPIO_Init_Data, 12);
+		gpio_setup(TADR_GPIOB_BASE, &GPIO_Init_Data, 13);
+
+		/* STP */
+		gpio_setup(TADR_GPIOC_BASE, &GPIO_Init_Data, 0);
+
+		/* NXT */
+		gpio_setup(TADR_GPIOH_BASE, &GPIO_Init_Data, 4);
+
+		/* DIR */
+		gpio_setup(TADR_HS_G1_BASE, &GPIO_Init_Data, HS_DIR_PINNNO);
+
+		/*
+		 *  USB HS-PHYクロック設定
+		 */
+		sil_orw_mem((uint32_t *)(TADR_RCC_BASE+TOFF_RCC_USBHS), RCC_USBHSUPEN);
+		tmpreg = sil_rew_mem((uint32_t *)(TADR_RCC_BASE+TOFF_RCC_USBHS));
+#endif	/* !TOPPERS_STM32F723_DISCOVERY */
+
+		/*
+		 *  USB HSクロック設定
+		 */
+		sil_orw_mem((uint32_t *)(TADR_RCC_BASE+TOFF_RCC_USBHS), RCC_USBHSEN);
+		tmpreg = sil_rew_mem((uint32_t *)(TADR_RCC_BASE+TOFF_RCC_USBHS));
+
+		/*
+		 *  FIFO設定値
+		 */
+		usbo_get_hwparam(husb);
+		husb->fifo_mem            = husb->hw_params.total_fifo_size;
+		husb->pcd_rx_fifo_sz      = DEFAULT_HS_GRXFSIZ;
+		husb->pcd_np_g_tx_fifo_sz = DEFAULT_HS_TXFIFO0_SIZ;
+		husb->pcd_tx_fifo_sz[1]   = DEFAULT_HS_TXFIFO1_SIZ;
+	}
+#endif
+	((void)(tmpreg));
+
+	/* DEVICE */
+	if(husb->Init.low_power_enable == 1){
+		/*
+		 *  WAKEUP割込み設定
+		 */
+#ifdef EXTI_PR_BASE
+		sil_wrw_mem((uint32_t *)EXTI_PR_BASE, USB_OTG_FS_WAKEUP_EXTI_LINE);
+		sil_andw_mem((uint32_t *)(TADR_EXTI_BASE+TOFF_EXTI_FTSR), USB_OTG_FS_WAKEUP_EXTI_LINE);
+		sil_orw_mem((uint32_t *)(TADR_EXTI_BASE+TOFF_EXTI_RTSR), USB_OTG_FS_WAKEUP_EXTI_LINE);
+#endif
+		sil_orw_mem((uint32_t *)EXTI_IMR_BASE, USB_OTG_FS_WAKEUP_EXTI_LINE);
+	}
+
+	base = husb->base;
+	/*
+	 *  USB OTGグローバル割込み禁止
+	 */
+	usbo_disableglobalint(husb);
+
+	/*
+	 *  USB OTGコア部初期化
+	 */
+	usbo_coreinit(husb);
+
+	/*
+	 *  USB OTGモード設定
+	 */
+	usbo_setcurrentmode(husb);
+
+	/*
+	 * VBUS Sensing Bを有効設定
+	 */
+#ifdef USB_OTG_GCCFG_VBDEN
+	sil_orw_mem((uint32_t *)(USBOTG_BASE(base)+TOFF_USBO_GCCFG), USB_OTG_GCCFG_VBDEN);
+	if(husb->Init.usb_otg_mode != USB_OTG_MODE_HOST){
+		if(husb->Init.vbus_sensing_enable == 0){
+			sil_andw_mem((uint32_t *)(USBOTG_BASE(base)+TOFF_USBO_GCCFG), USB_OTG_GCCFG_VBDEN);
+			sil_orw_mem((uint32_t *)(USBOTG_BASE(base)+TOFF_USBO_GOTGCTL), USB_OTG_GOTGCTL_BVALOEN);
+			sil_orw_mem((uint32_t *)(USBOTG_BASE(base)+TOFF_USBO_GOTGCTL), USB_OTG_GOTGCTL_BVALOVAL);
+		}
+	}
+#else
+	if(husb->Init.usb_otg_mode != USB_OTG_MODE_HOST){
+		sil_orw_mem((uint32_t *)(USBOTG_BASE(base)+TOFF_USBO_GCCFG), USB_OTG_GCCFG_VBUSBSEN);
+		if(husb->Init.vbus_sensing_enable == 0){
+			sil_orw_mem((uint32_t *)(USBOTG_BASE(base)+TOFF_USBO_GCCFG), USB_OTG_GCCFG_NOVBUSSENS);
+		}
+	}
+	else{
+		sil_andw_mem((uint32_t *)(USBOTG_BASE(base)+TOFF_USBO_GCCFG), USB_OTG_GCCFG_VBUSASEN);
+		sil_andw_mem((uint32_t *)(USBOTG_BASE(base)+TOFF_USBO_GCCFG), USB_OTG_GCCFG_VBUSBSEN);
+		sil_orw_mem((uint32_t *)(USBOTG_BASE(base)+TOFF_USBO_GCCFG), USB_OTG_GCCFG_NOVBUSSENS);
+	}
+#endif
+
+	/*
+	 *  リスタートPHYクロック
+	 */
+	sil_wrw_mem((uint32_t *)(USBPGC_BASE(base)), 0);
+
+	/*
+	 *  GINTのオールマスク設定
+	 */
+	sil_wrw_mem((uint32_t *)(USBOTG_BASE(base)+TOFF_USBO_GINTMSK), 0);
+
+	/*
+	 *  GINTオール割込みクリア
+	 */
+	sil_wrw_mem((uint32_t *)(USBOTG_BASE(base)+TOFF_USBO_GINTSTS), 0xFFFFFFFF);
+	return husb;
+}
+
+/*
+ *  USB OTGハードウェア停止
+ *  parameter1 husb  USBハンドラへのポインタ
+ *  return     常にE_OK
+ */
+ER
+usbo_deinit(USB_OTG_Handle_t *husb)
+{
+	if(husb->base == TADR_USB_OTGFS_BASE)
+		sil_andw_mem((uint32_t *)(TADR_RCC_BASE+TOFF_RCC_USBFS), RCC_USBFSEN);
+	else
+		sil_andw_mem((uint32_t *)(TADR_RCC_BASE+TOFF_RCC_USBHS), RCC_USBHSEN);
+	return E_OK;
+}
+
+/*
+ *  USB OTG割込み設定
+ *  parameter1 husb  USBハンドラへのポインタ
+ *  return     常にE_OK
+ */
+ER
+usbo_setupint(USB_OTG_Handle_t *husb)
+{
+	uint32_t base = husb->base;
+	uint32_t intmsk = USB_OTG_GINTMSK_PXFRM_IISOOXFRM | USB_OTG_GINTMSK_WUIM;
+
+	/*
+	 *  割込み禁止
+	 */
+	sil_wrw_mem((uint32_t *)(USBOTG_BASE(base)+TOFF_USBO_GINTMSK), 0);
+
+	/*
+	 *  割込みペンディングクリア
+	 */
+	sil_wrw_mem((uint32_t *)(USBOTG_BASE(base)+TOFF_USBO_GINTSTS), 0xFFFFFFFF);
+
+	/*
+	 *  DMA割込み許可
+	 */
+	if(husb->Init.dma_enable == 0){
+		intmsk |= USB_OTG_GINTMSK_RXFLVLM;
+	}
+
+	/*
+	 *  USB HOST割込み許可
+	 */
+	if(husb->Init.usb_otg_mode != USB_OTG_MODE_DEVICE){
+		intmsk |= (USB_OTG_GINTMSK_PRTIM | USB_OTG_GINTMSK_HCIM |\
+				   USB_OTG_GINTMSK_SOFM  | USB_OTG_GINTSTS_DISCINT);
+	}
+	/*
+	 *  USB DEVICE割込み許可
+	 */
+	if(husb->Init.usb_otg_mode != USB_OTG_MODE_HOST){
+		intmsk |= (USB_OTG_GINTMSK_USBSUSPM | USB_OTG_GINTMSK_USBRST |\
+                    USB_OTG_GINTMSK_ENUMDNEM | USB_OTG_GINTMSK_IEPINT |\
+                    USB_OTG_GINTMSK_OEPINT   | USB_OTG_GINTMSK_IISOIXFRM);
+	}
+
+	/*
+	 *  SOF割込み許可設定
+	 */
+	if(husb->Init.sof_enable){
+		intmsk |= USB_OTG_GINTMSK_SOFM;
+	}
+
+	/*
+	 *  SENSE ENABLE割込み許可設定
+	 */
+	if(husb->Init.vbus_sensing_enable == 1){
+		intmsk |= (USB_OTG_GINTMSK_SRQIM | USB_OTG_GINTMSK_OTGINT);
+	}
+	sil_wrw_mem((uint32_t *)(USBOTG_BASE(base)+TOFF_USBO_GINTMSK), intmsk);
+	return E_OK;
+}
+
+/*
+ *  USBコア部リセット
+ *  parameter1 husb  USBロジックベースアドレス
+ *  return     正常終了：E_OK タイムアウト：E_TMOUT
+ */
+static ER
+USB_CoreReset(uint32_t  base)
+{
+	uint32_t tick = 0;
+
+	/*
+	 *  AHBマスターのIDLEステート待ち
+	 */
+	do{
+		if(++tick > RESET_TIMEOUT)
+			return E_TMOUT;
+		sil_dly_nse(10*1000);
+	}
+	while ((sil_rew_mem((uint32_t *)(USBOTG_BASE(base)+TOFF_USBO_GRSTCTL)) & USB_OTG_GRSTCTL_AHBIDL) == 0);
+
+	/*
+	 *  コア、ソフトリセット要求
+	 */
+	tick = 0;
+	sil_orw_mem((uint32_t *)(USBOTG_BASE(base)+TOFF_USBO_GRSTCTL), USB_OTG_GRSTCTL_CSRST);
+	do{
+		if(++tick > RESET_TIMEOUT)
+			return E_TMOUT;
+		sil_dly_nse(10*1000);
+	}
+	while ((sil_rew_mem((uint32_t *)(USBOTG_BASE(base)+TOFF_USBO_GRSTCTL)) & USB_OTG_GRSTCTL_CSRST) != 0);
+	return E_OK;
+}
+
+/*
+ *  パケットデータ書き込み
+ *  parameter1 base  USB OTGレジスタベースアドレス
+ *  parameter2 src   書き込みデータのポインタ
+ *  parameter3 ch_ep_num エンドポイント、または、チャネル番号
+ *  parameter4 len   データ長
+ *  parameter5 dma   DMAモード(0:none-DMA、1:DMA)
+ */
+static void
+usbo_writePacket(uint32_t base, uint8_t *src, uint8_t ch_ep_num, uint16_t len, uint8_t dma)
+{
+	uint32_t count32b = 0 , i = 0;
+
+	if(dma == 0U){
+		count32b =  (len + 3) / 4;
+		for(i = 0 ; i < count32b; i++, src += 4){
+			sil_wrw_mem((uint32_t *)(USBD_FIFO(base, ch_ep_num)), get_packet_data(src));
+		}
+	}
+}
+
+/*
+ *  パケットデータ読み込み
+ *  parameter1 base USB OTGレジスタベースアドレス
+ *  parameter2 dest 読み込みデータのポインタ
+ *  parameter3 len  データ長
+ */
+static void *
+usbo_readPacket(uint32_t base, uint8_t *dest, uint16_t len)
+{
+	uint32_t i=0U;
+	uint32_t count32b = (len + 3U) / 4U;
+	uint32_t data;
+
+	for(i = 0 ; i < count32b; i++, dest += 4){
+		data = sil_rew_mem((uint32_t *)(USBD_FIFO(base, 0)));
+		dest[0] = (data & 0xff);
+		dest[1] = (data >> 8) & 0xff;
+		dest[2] = (data >> 16) & 0xff;
+		dest[3] = (data >> 24) & 0xff;
+	}
+	return ((void *)dest);
+}
+
+/*
+ *  USB HOSTのカレントフレーム番号を取り出す
+ *  parameter1 USBハンドラへのポインタ
+ *  return     ハンドラ番号
+*/
+uint32_t
+usbo_getcurrentframe(USB_OTG_Handle_t *husb)
+{
+	return (sil_rew_mem((uint32_t *)(USBH_BASE(husb->base)+TOFF_USBH_HFNUM)) & USB_OTG_HFNUM_FRNUM);
+}
+
+/*
+ *  USB OTGの機能設定を行う
+ *  parameter1 husb  USBハンドラへのポインタ
+ *     usb_otg_modeの設定：USB_OTG_MODE_DEVICE(USB DEVICE固定)
+ *                         USB_OTG_MODE_HOST(USB HOST固定)
+ *                         USB_OTG_MODE_DRD(デュアルモード)
+ *  return     常にE_OK
+ */
+ER
+usbo_setcurrentmode(USB_OTG_Handle_t *husb)
+{
+	uint32_t base = husb->base;
+	uint32_t gusbcfg = sil_rew_mem((uint32_t *)(USBOTG_BASE(base)+TOFF_USBO_GUSBCFG));
+
+	gusbcfg &= ~(USB_OTG_GUSBCFG_FHMOD | USB_OTG_GUSBCFG_FDMOD);
+
+	if(husb->Init.usb_otg_mode == USB_OTG_MODE_HOST){
+		gusbcfg |= USB_OTG_GUSBCFG_FHMOD;
+	}
+	else if(husb->Init.usb_otg_mode == USB_OTG_MODE_DEVICE){
+		gusbcfg |= USB_OTG_GUSBCFG_FDMOD;
+	}
+	sil_wrw_mem((uint32_t *)(USBOTG_BASE(base)+TOFF_USBO_GUSBCFG), gusbcfg);
+	dly_tsk(50);
+	return E_OK;
+}
+
+/*
+ *  USBコアの初期化
+ *  parameter1 husb  USBハンドラへのポインタ
+ *  return     常にE_OK
+ */
+ER
+usbo_coreinit(USB_OTG_Handle_t *husb)
+{
+	uint32_t base = husb->base;
+
+	if(husb->Init.phy_itface == USB_PHY_ULPI){	/* ULPI-PHY select */
+		sil_andw_mem((uint32_t *)(USBOTG_BASE(base)+TOFF_USBO_GCCFG), USB_OTG_GCCFG_PWRDWN);
+
+		/*
+		 *  ULPI-PHY初期化
+		 */
+		sil_andw_mem((uint32_t *)(USBOTG_BASE(base)+TOFF_USBO_GUSBCFG), (USB_OTG_GUSBCFG_TSDPS | USB_OTG_GUSBCFG_ULPIFSLS | USB_OTG_GUSBCFG_PHYSEL));
+
+		/*
+		 *  VBUSソース設定
+		 */
+		sil_andw_mem((uint32_t *)(USBOTG_BASE(base)+TOFF_USBO_GUSBCFG), (USB_OTG_GUSBCFG_ULPIEVBUSD | USB_OTG_GUSBCFG_ULPIEVBUSI));
+		if(husb->Init.use_external_vbus == 1){
+			sil_orw_mem((uint32_t *)(USBOTG_BASE(base)+TOFF_USBO_GUSBCFG), USB_OTG_GUSBCFG_ULPIEVBUSD);
+		}
+		/*
+		 *  コアリセット
+		 */
+		USB_CoreReset(base); 
+	}
+	else{	/* Embedded PHY select */
+		/*
+		 *  Embedded FS-PHY選択
+		 */
+		sil_orw_mem((uint32_t *)(USBOTG_BASE(base)+TOFF_USBO_GUSBCFG), USB_OTG_GUSBCFG_PHYSEL);
+
+		/*
+		 *  コアリセット
+		 */
+		USB_CoreReset(base);
+
+		/*
+		 *  電源ダウン解除
+		 */
+		sil_wrw_mem((uint32_t *)(USBOTG_BASE(base)+TOFF_USBO_GCCFG), USB_OTG_GCCFG_PWRDWN);
+	}
+ 
+	/*
+	 *  DMAモード設定
+	 */
+	if(husb->Init.dma_enable == 1){
+		sil_orw_mem((uint32_t *)(USBOTG_BASE(base)+TOFF_USBO_GAHBCFG), USB_OTG_GAHBCFG_DMAEN);
+	}
+	return E_OK;
+}
+
+/*
+ *  USBグローバル割込み許可
+ *  parameter1 husb  USBハンドラへのポインタ
+ *  return     常にE_OK
+ */
+ER
+usbo_enableglobalint(USB_OTG_Handle_t *husb)
+{
+	sil_orw_mem((uint32_t *)(USBOTG_BASE(husb->base)+TOFF_USBO_GAHBCFG), USB_OTG_GAHBCFG_GINT);
+	return E_OK;
+}
+
+/*
+ *  USBグローバル割込み禁止
+ *  parameter1 husb  USBハンドラへのポインタ
+ *  return     常にE_OK
+ */
+ER
+usbo_disableglobalint(USB_OTG_Handle_t *husb)
+{
+	sil_andw_mem((uint32_t *)(USBOTG_BASE(husb->base)+TOFF_USBO_GAHBCFG), USB_OTG_GAHBCFG_GINT);
+	return E_OK;
+}
+
+/*
+ *  送信FIFOのフラッシュ
+ *  parameter1 husb  USBハンドラへのポインタ
+ *  return     正常終了：E_OK、タイムアウト：E_TMOUT
+ */
+ER
+usbo_flushTxFifo(USB_OTG_Handle_t *husb, uint32_t num)
+{
+	uint32_t base = husb->base;
+	uint32_t tick = 0;
+
+	sil_wrw_mem((uint32_t *)(USBOTG_BASE(base)+TOFF_USBO_GRSTCTL), (USB_OTG_GRSTCTL_TXFFLSH |(uint32_t)(num << 6)));
+	do{
+		if(++tick > RESET_TIMEOUT)
+			return E_TMOUT;
+		sil_dly_nse(10*1000);
+	}while ((sil_rew_mem((uint32_t *)(USBOTG_BASE(base)+TOFF_USBO_GRSTCTL)) & USB_OTG_GRSTCTL_TXFFLSH) != 0);
+	return E_OK;
+}
+
+/*
+ *  受信FIFOのフラッシュ
+ *  parameter1 husb  USBハンドラへのポインタ
+ *  return     正常終了：E_OK、タイムアウト：E_TMOUT
+ */
+ER
+usbo_flushRxFifo(USB_OTG_Handle_t *husb)
+{
+	uint32_t base = husb->base;
+	uint32_t tick = 0;
+
+	sil_wrw_mem((uint32_t *)(USBOTG_BASE(base)+TOFF_USBO_GRSTCTL), USB_OTG_GRSTCTL_RXFFLSH);
+	do{
+		if(++tick > RESET_TIMEOUT)
+			return E_TMOUT;
+		sil_dly_nse(10*1000);
+	}while((sil_rew_mem((uint32_t *)(USBOTG_BASE(base)+TOFF_USBO_GRSTCTL)) & USB_OTG_GRSTCTL_RXFFLSH) != 0);
+
+#ifdef USB_OTG_GCCFG_VBDEN
+	sil_orw_mem((uint32_t *)(USBOTG_BASE(base)+TOFF_USBO_GCCFG), USB_OTG_GCCFG_VBDEN);
+#endif
+	return E_OK;
+}
+
+/*
+ *  FIFOの初期化
+ *  parameter1 husb  USBハンドラへのポインタ
+ *  return     常にE_OK
+ */
+ER
+usbo_initFiFo(USB_OTG_Handle_t *husb)
+{
+	unsigned int ep;
+	unsigned int addr;
+	uint32_t base = husb->base;
+	uint32_t val;
+
+	/*
+	 *  RX/NPTX FIFOサイズ設定
+	 */
+	sil_wrw_mem((uint32_t *)(USBOTG_BASE(base)+TOFF_USBO_GRXFSIZ), husb->pcd_np_g_tx_fifo_sz);
+	sil_wrw_mem((uint32_t *)(USBOTG_BASE(base)+TOFF_USBO_DIEPTXF0_HNPTXFSIZ),
+			(husb->pcd_np_g_tx_fifo_sz<<16) | husb->pcd_rx_fifo_sz);
+
+	/*
+	 *  すべてのTX FIFO設定
+	 */
+	addr = husb->pcd_rx_fifo_sz + husb->pcd_np_g_tx_fifo_sz;
+	for(ep = 1; ep < MAX_EPS_CHANNELS; ep++) {
+		if(husb->pcd_tx_fifo_sz[ep] == 0){
+			sil_wrw_mem((uint32_t *)(USBOTG_BASE(base)+TOFF_USBO_DIEPTXF+(ep-1)*4), 0);
+			continue;
+		}
+		val = addr | husb->pcd_tx_fifo_sz[ep] << 16;
+		if((addr + husb->pcd_tx_fifo_sz[ep]) > husb->fifo_mem)
+			syslog_1(LOG_ERROR, "insufficient fifo memory(%d)", ep);
+		addr += husb->pcd_tx_fifo_sz[ep];
+		sil_wrw_mem((uint32_t *)(USBOTG_BASE(base)+TOFF_USBO_DIEPTXF+(ep-1)*4), val);
+	}
+
+	/*
+	 * FIFOフラッシュ処理
+	 */
+	usbo_flushTxFifo(husb, 0x10);
+	usbo_flushRxFifo(husb);
+	return E_OK;
+}
+
+/*******************************************************************************
+                       USB HOST関数
+*******************************************************************************/
+/*
+ *  USB HOST初期化
+ *  parameter1 husb  USBハンドラへのポインタ
+ *  return     常にE_OK
+ */
+ER
+usbo_hostinit(USB_OTG_Handle_t *husb)
+{
+	uint32_t base = husb->base;
+	bool_t forced;
+	uint32_t val, i;
+
+	/* Disable the FS/LS support mode only */
+	if((husb->Init.speed == USB_SPEED_FULL) && (base != TADR_USB_OTGFS_BASE)){
+		sil_orw_mem((uint32_t *)(USBH_BASE(base)+TOFF_USBH_HCFG), USB_OTG_HCFG_FSLSS);
+	}
+	else{
+		sil_andw_mem((uint32_t *)(USBH_BASE(base)+TOFF_USBH_HCFG), USB_OTG_HCFG_FSLSS);
+	}
+
+	/*
+	 *  HOST RX-FIFOサイズ設定
+	 */
+	forced = usbo_force_mode_if_needed(husb, true);
+	sil_wrw_mem((uint32_t *)(USBOTG_BASE(base)+TOFF_USBO_GRXFSIZ), husb->pcd_np_g_tx_fifo_sz);
+	sil_wrw_mem((uint32_t *)(USBOTG_BASE(base)+TOFF_USBO_DIEPTXF0_HNPTXFSIZ),
+			(husb->pcd_np_g_tx_fifo_sz<<16) | husb->pcd_rx_fifo_sz);
+	val = (husb->pcd_rx_fifo_sz + husb->pcd_np_g_tx_fifo_sz) | husb->pcd_tx_fifo_sz[1] << 16;
+	sil_wrw_mem((uint32_t *)(USBOTG_BASE(base)+TOFF_USBO_HPTXFSIZ), val);
+
+	/*
+	 *  FIFOフラッシュ
+	 */
+	usbo_flushTxFifo(husb, 0x10U); /* all Tx FIFOs */
+	usbo_flushRxFifo(husb);
+	if(forced)
+		usbo_clear_force_mode(husb);
+
+	/*
+	 * チャネル割込みクリアとマスク
+	 */
+	for (i = 0 ; i < husb->Init.host_channels; i++){
+		sil_wrw_mem((uint32_t *)(USBHC_BASE(base, i)+TOFF_USBHC_HCINT), 0xFFFFFFFFU);
+		sil_wrw_mem((uint32_t *)(USBHC_BASE(base, i)+TOFF_USBHC_HCINTMSK), 0U);
+	}
+
+	/*
+	 *  L3ステート設定
+	 */
+	husb->lx_state = DWC2_L0;
+
+	/*
+	 *  HOST VBUS設定
+	 */
+	usbo_drivevbus(husb, 1);
+	dly_tsk(200U);
+	usbo_setupint(husb);
+	return E_OK;
+}
+
+/*
+ *  HOSTコア開始要求
+ *  parameter1 husb  USBハンドラへのポインタ
+ *  return     常にE_OK
+ */
+ER
+usbo_starthost(USB_OTG_Handle_t *husb)
+{
+	if(husb->Init.usb_otg_mode == USB_OTG_MODE_DRD
+			&& husb->lx_state != DWC2_L0){
+		usbo_hostinit(husb);
+		dly_tsk(25);
+		usbo_devdisconnect(husb);
+		dly_tsk(3);
+		usbo_devconnect(husb);
+	}
+	husb->lx_state = DWC2_L0;
+	return E_OK;
+}
+
+/*
+ *  HOSTコア停止要求
+ *  parameter1 husb  USBハンドラへのポインタ
+ *  return     常にE_OK
+ */
+ER
+usbo_stophost(USB_OTG_Handle_t *husb)
+{
+	uint32_t base = husb->base;
+	uint32_t tick = 0;
+	int      i;
+
+	usbo_disableglobalint(husb);
+
+	/*
+	 *  FIFOフラッシュ
+	 */
+	if(husb->Init.usb_otg_mode == USB_OTG_MODE_HOST){
+		usbo_flushTxFifo(husb, 0x10U);
+		usbo_flushRxFifo(husb);
+	}
+
+	/*
+	 *  HOSTチャネルキュークリア
+	 */
+	for(i = 0 ; i <= 15 ; i++){
+		sil_modw_mem((uint32_t *)(USBHC_BASE(base, i)+TOFF_USBHC_HCCHAR), (USB_OTG_HCCHAR_CHENA|USB_OTG_HCCHAR_EPDIR), USB_OTG_HCCHAR_CHDIS);
+	}
+
+	/*
+	 *  HOSTチャネルHALT
+	 */
+	for(i = 0, tick = 0 ; i <= 15 ; i++){
+		sil_modw_mem((uint32_t *)(USBHC_BASE(base, i)+TOFF_USBHC_HCCHAR), USB_OTG_HCCHAR_EPDIR, (USB_OTG_HCCHAR_CHDIS|USB_OTG_HCCHAR_CHENA));
+		do{
+			if(++tick > HALT_TIMEOUT)
+				break;
+			sil_dly_nse(10*1000);
+		}while((sil_rew_mem((uint32_t *)(USBHC_BASE(base, i)+TOFF_USBHC_HCCHAR)) & USB_OTG_HCCHAR_CHENA) != 0);
+	}
+
+	/*
+	 *  USBホスト用の割込みクリア
+	 */
+	sil_wrw_mem((uint32_t *)(USBH_BASE(base)+TOFF_USBH_HAINT), 0xFFFFFFFFU);
+	sil_wrw_mem((uint32_t *)(USBOTG_BASE(base)+TOFF_USBO_GINTSTS), 0xFFFFFFFFU);
+	husb->lx_state = DWC2_L3;
+	return E_OK;
+}
+
+/*
+ *  HOSTチャネルの初期化
+ *  parameter1 husb   USBハンドラへのポインタ
+ *  parameter2 ch_num チャネル番号(1-15)
+ *  parameter3 epnum  エンドポイント番号(1-15)
+ *  return     常にE_OK
+ */
+ER
+usbo_hc_init(USB_OTG_Handle_t *husb, uint8_t ch_num, uint8_t epnum)
+{
+	uint32_t base = husb->base;
+	uint8_t  address = husb->hc[ch_num].dev_addr;
+	uint8_t  speed   = husb->hc[ch_num].speed;
+	uint8_t  ep_type = husb->hc[ch_num].ep_type;
+	uint16_t mps     = husb->hc[ch_num].max_packet;
+	uint32_t hcint   = 0;
+
+	/*
+	 *  チャネルの割込みクリア
+	 */
+	sil_wrw_mem((uint32_t *)(USBHC_BASE(base, ch_num)+TOFF_USBHC_HCINT), 0xFFFFFFFFU);
+
+	/*
+	 *  エンドポイント型に従う初期化
+	 */
+	switch (ep_type) {
+	case EP_TYPE_CTRL:
+	case EP_TYPE_BULK:
+		hcint = USB_OTG_HCINTMSK_XFRCM  | USB_OTG_HCINTMSK_STALLM |\
+                USB_OTG_HCINTMSK_TXERRM | USB_OTG_HCINTMSK_DTERRM |\
+                USB_OTG_HCINTMSK_AHBERR | USB_OTG_HCINTMSK_NAKM;
+
+		if(epnum & 0x80U){
+			hcint |= USB_OTG_HCINTMSK_BBERRM;
+		}
+		else{
+			if(base != TADR_USB_OTGFS_BASE){
+				hcint |= USB_OTG_HCINTMSK_NYET | USB_OTG_HCINTMSK_ACKM;
+			}
+		}
+		break;
+
+	case EP_TYPE_INTR:
+		hcint = USB_OTG_HCINTMSK_XFRCM  | USB_OTG_HCINTMSK_STALLM |\
+                USB_OTG_HCINTMSK_TXERRM | USB_OTG_HCINTMSK_DTERRM |\
+                USB_OTG_HCINTMSK_NAKM   | USB_OTG_HCINTMSK_AHBERR | USB_OTG_HCINTMSK_FRMORM;
+
+		if(epnum & 0x80)
+			hcint |= USB_OTG_HCINTMSK_BBERRM;
+		break;
+	case EP_TYPE_ISOC:
+			hcint = USB_OTG_HCINTMSK_XFRCM  | USB_OTG_HCINTMSK_ACKM |\
+                    USB_OTG_HCINTMSK_AHBERR | USB_OTG_HCINTMSK_FRMORM;
+
+		if(epnum & 0x80)
+			hcint |= USB_OTG_HCINTMSK_TXERRM | USB_OTG_HCINTMSK_BBERRM;
+		break;
+	}
+	sil_wrw_mem((uint32_t *)(USBHC_BASE(base, ch_num)+TOFF_USBHC_HCINTMSK), hcint);
+
+	/*
+	 *  HOSTチャネル割込みマスク解除
+	 */
+	sil_orw_mem((uint32_t *)(USBH_BASE(base)+TOFF_USBH_HAINTMSK), (1 << ch_num));
+
+	/*
+	 *  HOSTチャネル割込み許可
+	 */
+	sil_orw_mem((uint32_t *)(USBOTG_BASE(base)+TOFF_USBO_GINTMSK), USB_OTG_GINTMSK_HCIM);
+
+	/*
+	 *  HCCHARレジスタ設定
+	 */
+	sil_wrw_mem((uint32_t *)(USBHC_BASE(base, ch_num)+TOFF_USBHC_HCCHAR), (((address << 22U) & USB_OTG_HCCHAR_DAD)  |\
+                             (((epnum & 0x7FU)<< 11U) & USB_OTG_HCCHAR_EPNUM)|\
+                             ((((epnum & 0x80U) == 0x80U)<< 15U) & USB_OTG_HCCHAR_EPDIR)|\
+                             (((speed == USB_SPEED_LOW)<< 17U) & USB_OTG_HCCHAR_LSDEV)|\
+                             ((ep_type << 18U) & USB_OTG_HCCHAR_EPTYP)|\
+                             (mps & USB_OTG_HCCHAR_MPSIZ)));
+
+	if(ep_type == EP_TYPE_INTR){
+		sil_orw_mem((uint32_t *)(USBHC_BASE(base, ch_num)+TOFF_USBHC_HCCHAR), USB_OTG_HCCHAR_ODDFRM);
+	}
+	return E_OK; 
+}
+
+/*
+ *  HOSTコアスピードを取り出す
+ *  parameter1 husb  USBハンドラへのポインタ
+ *  return     speed USB_SPEED_HIGH(High speed)
+ *                   USB_SPEED_FULL(Full speed)
+ *                   USB_SPEED_LOW(Low speed)
+ */
+uint32_t
+usbo_gethostspeed(USB_OTG_Handle_t *husb)
+{
+	volatile uint32_t hprt0;
+
+	hprt0 = sil_rew_mem((uint32_t*)(USBPRT_BASE(husb->base)));
+	return ((hprt0 & USB_OTG_HPRT_PSPD) >> 17);
+}
+
+/*
+ *  HOSTチャネル送信要求
+ *  parameter1 husb  USBハンドラへのポインタ
+ *  parameter2 ch_num チャネル番号(1-15)
+ *  return     常にE_OK
+ */
+ER
+usbo_hc_startxfer(USB_OTG_Handle_t *husb, uint8_t ch_num)
+{
+	USB_OTG_HCTypeDef *hc = &husb->hc[ch_num];
+	uint32_t base = husb->base;
+	uint8_t  is_oddframe = 0U; 
+	uint16_t len_words = 0U;   
+	uint16_t num_packets = 0U;
+	uint16_t max_hc_pkt_count = 256U;
+
+	if((base != TADR_USB_OTGFS_BASE) && (hc->speed == USB_SPEED_HIGH)){
+		if((husb->Init.dma_enable == 0) && (hc->do_ping == 1)){
+			/*
+			 * Do Ping
+			 */
+			sil_wrw_mem((uint32_t *)(USBHC_BASE(base, hc->ch_num)+TOFF_USBHC_HCTSIZ), ((1 << 19) & USB_OTG_HCTSIZ_PKTCNT) | USB_OTG_HCTSIZ_DOPING);
+			sil_modw_mem((uint32_t *)(USBHC_BASE(base, hc->ch_num)+TOFF_USBHC_HCCHAR), USB_OTG_HCCHAR_CHDIS, USB_OTG_HCCHAR_CHENA);
+			return E_OK;
+		}
+		else if(husb->Init.dma_enable == 1){
+			sil_andw_mem((uint32_t *)(USBHC_BASE(base, hc->ch_num)+TOFF_USBHC_HCINTMSK), (USB_OTG_HCINTMSK_NYET | USB_OTG_HCINTMSK_ACKM));
+			hc->do_ping = 0U;
+		}
+	}
+
+	/*
+	 *  パケット数、転送長の計算
+	 */
+	if(hc->xfer_len > 0){
+		num_packets = (hc->xfer_len + hc->max_packet - 1U) / hc->max_packet;
+
+		if(num_packets > max_hc_pkt_count){
+			num_packets = max_hc_pkt_count;
+			hc->xfer_len = num_packets * hc->max_packet;
+		}
+	}
+	else{
+		num_packets = 1;
+	}
+	if(hc->ep_is_in){
+		hc->xfer_len = num_packets * hc->max_packet;
+	}
+
+	/*
+	 *  HCTSIZレジスタ設定
+	 */
+	sil_wrw_mem((uint32_t *)(USBHC_BASE(base, hc->ch_num)+TOFF_USBHC_HCTSIZ), (((hc->xfer_len) & USB_OTG_HCTSIZ_XFRSIZ)) |\
+		((num_packets << 19U) & USB_OTG_HCTSIZ_PKTCNT) | (((hc->data_pid) << 29U) & USB_OTG_HCTSIZ_DPID));
+
+	if(husb->Init.dma_enable){
+		flushinvalidatedcache_by_addr(((uint8_t *)hc->xfer_buff), hc->xfer_len);
+		sil_wrw_mem((uint32_t *)(USBHC_BASE(base, hc->ch_num)+TOFF_USBHC_HCDMA), (uint32_t)hc->xfer_buff);
+	}
+
+	/*
+	 *  EVEN/ODDパケット設定
+	 */
+	is_oddframe = (sil_rew_mem((uint32_t *)(USBH_BASE(base)+TOFF_USBH_HFNUM)) & 0x01U) ? 0U : 1U;
+	sil_andw_mem((uint32_t *)(USBHC_BASE(base, hc->ch_num)+TOFF_USBHC_HCCHAR), USB_OTG_HCCHAR_ODDFRM);
+	sil_orw_mem((uint32_t *)(USBHC_BASE(base, hc->ch_num)+TOFF_USBHC_HCCHAR), (is_oddframe << 29U));
+
+	/*
+	 *  HOSTチャネルを有効化
+	 */
+	sil_modw_mem((uint32_t *)(USBHC_BASE(base, hc->ch_num)+TOFF_USBHC_HCCHAR), USB_OTG_HCCHAR_CHDIS, USB_OTG_HCCHAR_CHENA);
+
+	if(husb->Init.dma_enable == 0){	/* none DMAモード */
+		if((hc->ep_is_in == 0U) && (hc->xfer_len > 0U)){
+			switch(hc->ep_type) {
+			case EP_TYPE_CTRL:	/* NON PERIODIC転送 */
+			case EP_TYPE_BULK:
+				len_words = (hc->xfer_len + 3) / 4;
+				/*
+				 *  FIFO長を超える場合、NPTXFEMPTY割込みを設定
+				 */
+				if(len_words > (sil_rew_mem((uint32_t *)(USBOTG_BASE(base)+TOFF_USBO_HNPTXSTS)) & 0xFFFFU)){
+					sil_orw_mem((uint32_t *)(USBOTG_BASE(base)+TOFF_USBO_GINTMSK), USB_OTG_GINTMSK_NPTXFEM);
+				}
+				break;
+			case EP_TYPE_INTR:	/* PERIODIC 転送 */
+			case EP_TYPE_ISOC:
+				len_words = (hc->xfer_len + 3) / 4;
+				/*
+				 *  FIFO長を超える場合、PTXFEMPTY割込みを設定
+				 */
+				if(len_words > (sil_rew_mem((uint32_t *)(USBH_BASE(base)+TOFF_USBH_HPTXSTS)) & 0xFFFFU)){ /* split the transfer */
+					sil_orw_mem((uint32_t *)(USBOTG_BASE(base)+TOFF_USBO_GINTMSK), USB_OTG_GINTMSK_PTXFEM);
+				}
+				break;
+			default:
+				break;
+			}
+
+			/*
+			 *  パケット書き込み
+			 */
+			usbo_writePacket(base, hc->xfer_buff, hc->ch_num, hc->xfer_len, 0);
+		}
+	}
+	return E_OK;
+}
+
+/*
+ *  HOSTチャネルをHALTする
+ *  parameter1 husb  USBハンドラへのポインタ
+ *  parameter2 チャネル番号(1-15)
+ *  return     常にE_OK
+ */
+ER
+usbo_hc_halt(USB_OTG_Handle_t *husb, uint8_t ch_num)
+{
+	uint32_t base = husb->base;
+	uint32_t tick = 0;
+
+	/* HCCHARコントロールモード */
+	if((((sil_rew_mem((uint32_t *)(USBHC_BASE(base, ch_num)+TOFF_USBHC_HCCHAR)) & USB_OTG_HCCHAR_EPTYP) >> 18) == HCCHAR_CTRL)
+			|| ((((sil_rew_mem((uint32_t *)(USBHC_BASE(base, ch_num)+TOFF_USBHC_HCCHAR)) & USB_OTG_HCCHAR_EPTYP) >> 18) == HCCHAR_BULK))){
+		sil_orw_mem((uint32_t *)(USBHC_BASE(base, ch_num)+TOFF_USBHC_HCCHAR), USB_OTG_HCCHAR_CHDIS);
+		if((sil_rew_mem((uint32_t *)(USBOTG_BASE(base)+TOFF_USBO_HNPTXSTS)) & 0xFF0000U) == 0){
+			sil_andw_mem((uint32_t *)(USBHC_BASE(base, ch_num)+TOFF_USBHC_HCCHAR), USB_OTG_HCCHAR_CHENA);
+			sil_orw_mem((uint32_t *)(USBHC_BASE(base, ch_num)+TOFF_USBHC_HCCHAR), USB_OTG_HCCHAR_CHENA);
+			do{
+				if(++tick > HALT_TIMEOUT)
+					break;
+				sil_dly_nse(10*1000);
+			}while((sil_rew_mem((uint32_t *)(USBHC_BASE(base, ch_num)+TOFF_USBHC_HCCHAR)) & USB_OTG_HCCHAR_CHENA) != 0);
+		}
+		else{
+			sil_orw_mem((uint32_t *)(USBHC_BASE(base, ch_num)+TOFF_USBHC_HCCHAR), USB_OTG_HCCHAR_CHENA);
+		}
+	}
+	else{	/* その他 */
+		sil_orw_mem((uint32_t *)(USBHC_BASE(base, ch_num)+TOFF_USBHC_HCCHAR), USB_OTG_HCCHAR_CHDIS);
+		if((sil_rew_mem((uint32_t *)(USBH_BASE(base)+TOFF_USBH_HPTXSTS)) & 0xFFFF) == 0){
+			sil_andw_mem((uint32_t *)(USBHC_BASE(base, ch_num)+TOFF_USBHC_HCCHAR), USB_OTG_HCCHAR_CHENA);
+			sil_orw_mem((uint32_t *)(USBHC_BASE(base, ch_num)+TOFF_USBHC_HCCHAR), USB_OTG_HCCHAR_CHENA);
+			do{
+				if(++tick > HALT_TIMEOUT) 
+					break;
+				sil_dly_nse(10*1000);
+			}while((sil_rew_mem((uint32_t *)(USBHC_BASE(base, ch_num)+TOFF_USBHC_HCCHAR)) & USB_OTG_HCCHAR_CHENA) != 0);
+		}
+		else{
+			sil_orw_mem((uint32_t *)(USBHC_BASE(base, ch_num)+TOFF_USBHC_HCCHAR), USB_OTG_HCCHAR_CHENA);
+		}
+	}
+	return E_OK;
+}
+
+/*
+ *  USB OTG HOSTポートリセット
+ *  parameter1 husb  USBハンドラへのポインタ
+ *  return     常にE_OK
+ */
+ER
+usbo_resetport(USB_OTG_Handle_t *husb)
+{
+	uint32_t base = husb->base;
+	volatile uint32_t hprt0;
+
+	hprt0 = sil_rew_mem((uint32_t*)(USBPRT_BASE(base)));
+	hprt0 &= ~(USB_OTG_HPRT_PENA | USB_OTG_HPRT_PCDET | USB_OTG_HPRT_PENCHNG | USB_OTG_HPRT_POCCHNG);
+
+	sil_wrw_mem((uint32_t*)(USBPRT_BASE(base)), (USB_OTG_HPRT_PRST | hprt0));
+	dly_tsk (10);				/* See Note #1 */
+	sil_wrw_mem((uint32_t*)(USBPRT_BASE(base)), (~(USB_OTG_HPRT_PRST) & hprt0));
+	return E_OK;
+}
+
+/*
+ *  USB HOST VBUSの有効、無効設定
+ *  parameter1 husb  USBハンドラへのポインタ
+ *  parameter2 state 1:VBUS-ACTIVE 0:VBUS-INACTIVE
+ *  return     常にE_OK
+ */
+ER
+usbo_drivevbus(USB_OTG_Handle_t *husb, uint8_t state)
+{
+	uint32_t base = husb->base;
+	volatile uint32_t hprt0;
+
+	hprt0 = sil_rew_mem((uint32_t*)(USBPRT_BASE(base)));
+	hprt0 &= ~(USB_OTG_HPRT_PENA | USB_OTG_HPRT_PCDET | USB_OTG_HPRT_PENCHNG | USB_OTG_HPRT_POCCHNG);
+
+	if(((hprt0 & USB_OTG_HPRT_PPWR) == 0) && (state == 1)){
+		sil_wrw_mem((uint32_t*)(USBPRT_BASE(base)), (USB_OTG_HPRT_PPWR | hprt0));
+	}
+	if(((hprt0 & USB_OTG_HPRT_PPWR) != 0) && (state == 0)){
+		sil_wrw_mem((uint32_t*)(USBPRT_BASE(base)), ((~USB_OTG_HPRT_PPWR) & hprt0));
+	}
+	return E_OK; 
+}
+
+/*
+ *  HOST EXTERNAL VBUSの有効、無効設定
+ *  parameter1 husb  USBハンドラへのポインタ
+ *  parameter2 state 0:VBUS-ACTIVE 1:VBUS-INACTIVE
+ */
+void
+usbo_driveextvbus(USB_OTG_Handle_t *husb, uint8_t state)
+{
+#if defined(FS_EVBUS_PINNO)
+	if(husb->base == TADR_USB_OTGFS_BASE){
+	 	if(state == 0)
+			sil_wrw_mem((uint32_t *)(TADR_GPIOG_BASE+TOFF_GPIO_BSRR), (1<<(FS_EVBUS_PINNO+16)));
+		else
+			sil_wrw_mem((uint32_t *)(TADR_GPIOG_BASE+TOFF_GPIO_BSRR), (1<<(FS_EVBUS_PINNO)));
+	}
+#endif
+}
+
+/*
+ *  FSLSPClkSel設定
+ *  parameter1 husb  USBハンドラへのポインタ
+ *  parameter2 freq クロック周波数(48MHz,6MHzのみ有効)
+ */
+static void
+usbo_initFSLSPClkSel(USB_OTG_Handle_t *husb, uint32_t freq)
+{
+	uint32_t base = husb->base;
+	uint32_t hcfg = sil_rew_mem((uint32_t *)(USBH_BASE(base)+TOFF_USBH_HCFG));
+	hcfg &= ~USB_OTG_HCFG_FSLSPCS;
+	if(freq == 48000)
+		hcfg |= USB_OTG_HCFG_FSLSPCS_0;
+	else if(freq == 6000)
+		hcfg |= USB_OTG_HCFG_FSLSPCS_1;
+	sil_wrw_mem((uint32_t *)(USBH_BASE(base)+TOFF_USBH_HCFG), hcfg);
+
+	if(freq == 48000 || freq ==  6000){
+		sil_wrw_mem((uint32_t *)(USBH_BASE(base)+TOFF_USBH_HFIR), freq);
+	}
+}
+
+/*
+ *  HOSTチャネル割込み要求
+ *  parameter1 husb  USBハンドラへのポインタ
+ *  parameter2 chnum チャネル番号(1-15)
+ */
+static void
+usbo_hc_in_irqhandler(USB_OTG_Handle_t *husb, uint8_t chnum)
+{
+    USB_OTG_HCTypeDef *hc = &husb->hc[chnum];
+	uint32_t base = husb->base;
+
+	if(hc_int_status(base, chnum, USB_OTG_HCINT_AHBERR) != 0){
+		clear_hc_int(base, chnum, USB_OTG_HCINT_AHBERR);
+		sil_orw_mem((uint32_t *)(USBHC_BASE(base, chnum)+TOFF_USBHC_HCINTMSK), USB_OTG_HCINTMSK_CHHM);
+	}
+	else if(hc_int_status(base, chnum, USB_OTG_HCINT_ACK) != 0){
+		clear_hc_int(base, chnum, USB_OTG_HCINT_ACK);
+	}
+	else if(hc_int_status(base, chnum, USB_OTG_HCINT_STALL) != 0){
+		sil_orw_mem((uint32_t *)(USBHC_BASE(base, chnum)+TOFF_USBHC_HCINTMSK), USB_OTG_HCINTMSK_CHHM);
+		hc->state = USBO_HC_STALL;
+		usbo_hc_halt(husb, chnum);
+		clear_hc_int(base, chnum, USB_OTG_HCINT_NAK);
+		clear_hc_int(base, chnum, USB_OTG_HCINT_STALL);
+	}
+	else if(hc_int_status(base, chnum, USB_OTG_HCINT_DTERR) != 0){
+		sil_orw_mem((uint32_t *)(USBHC_BASE(base, chnum)+TOFF_USBHC_HCINTMSK), USB_OTG_HCINTMSK_CHHM);
+		usbo_hc_halt(husb, chnum);
+		clear_hc_int(base, chnum, USB_OTG_HCINT_NAK);
+		hc->state = USBO_HC_DATATGLERR;
+		clear_hc_int(base, chnum, USB_OTG_HCINT_DTERR);
+	}
+
+	if(hc_int_status(base, chnum, USB_OTG_HCINT_FRMOR) != 0){
+		sil_orw_mem((uint32_t *)(USBHC_BASE(base, chnum)+TOFF_USBHC_HCINTMSK), USB_OTG_HCINTMSK_CHHM);
+		usbo_hc_halt(husb, chnum);
+		clear_hc_int(base, chnum, USB_OTG_HCINT_FRMOR);
+	}
+	else if(hc_int_status(base, chnum, USB_OTG_HCINT_XFRC) != 0){
+		if (husb->Init.dma_enable){
+			hc->xfer_count = hc->xfer_len - (sil_rew_mem((uint32_t *)(USBHC_BASE(base, chnum)+TOFF_USBHC_HCTSIZ)) & USB_OTG_HCTSIZ_XFRSIZ);
+		}
+
+		hc->state = USBO_HC_XFRC;
+		hc->err_count = 0;
+		clear_hc_int(base, chnum, USB_OTG_HCINT_XFRC);
+
+		if((hc->ep_type == EP_TYPE_CTRL) || (hc->ep_type == EP_TYPE_BULK)){
+			sil_orw_mem((uint32_t *)(USBHC_BASE(base, chnum)+TOFF_USBHC_HCINTMSK), USB_OTG_HCINTMSK_CHHM);
+			usbo_hc_halt(husb, chnum);
+			clear_hc_int(base, chnum, USB_OTG_HCINT_NAK);
+		}
+		else if(hc->ep_type == EP_TYPE_INTR){
+			sil_orw_mem((uint32_t *)(USBHC_BASE(base, chnum)+TOFF_USBHC_HCCHAR), USB_OTG_HCCHAR_ODDFRM);
+			husb->hc[chnum].urb_state = URB_DONE;
+			if(husb->hostchangeurbcallback != NULL)
+				husb->hostchangeurbcallback(husb, chnum, husb->hc[chnum].urb_state);
+		}
+		hc->toggle_in ^= 1U;
+	}
+	else if(hc_int_status(base, chnum, USB_OTG_HCINT_CHH) != 0){
+		sil_andw_mem((uint32_t *)(USBHC_BASE(base, chnum)+TOFF_USBHC_HCINTMSK), USB_OTG_HCINTMSK_CHHM);
+		if(hc->state == USBO_HC_XFRC){
+			hc->urb_state  = URB_DONE;
+		}
+		else if(hc->state == USBO_HC_STALL){
+			hc->urb_state  = URB_STALL;
+		}
+		else if((hc->state == USBO_HC_XACTERR) || (hc->state == USBO_HC_DATATGLERR)){
+			if(hc->err_count++ > 3U){
+				hc->err_count = 0;
+				hc->urb_state = URB_ERROR;
+			}
+			else{
+				hc->urb_state = URB_NOTREADY;
+			}
+
+			/*
+			 *  チャネルの再アクティブ
+			 */
+			sil_modw_mem((uint32_t *)(USBHC_BASE(base, chnum)+TOFF_USBHC_HCCHAR), USB_OTG_HCCHAR_CHDIS, USB_OTG_HCCHAR_CHENA);
+		}
+		clear_hc_int(base, chnum, USB_OTG_HCINT_CHH);
+		if(husb->hostchangeurbcallback != NULL)
+			husb->hostchangeurbcallback(husb, chnum, husb->hc[chnum].urb_state);
+	}
+	else if(hc_int_status(base, chnum, USB_OTG_HCINT_TXERR) != 0){
+		sil_orw_mem((uint32_t *)(USBHC_BASE(base, chnum)+TOFF_USBHC_HCINTMSK), USB_OTG_HCINTMSK_CHHM);
+		hc->err_count++;
+		hc->state = USBO_HC_XACTERR;
+#if 1	/* ROI DEBUG */
+		syslog_1(LOG_NOTICE, "## SET USBO_HC_XACTERR1 [%08x] ##", sil_rew_mem((uint32_t *)(USBHC_BASE(base, chnum)+TOFF_USBHC_HCINT)));
+#endif	/* ROI DEBUG */
+		usbo_hc_halt(husb, chnum);
+		clear_hc_int(base, chnum, USB_OTG_HCINT_TXERR);
+	}
+	else if(hc_int_status(base, chnum, USB_OTG_HCINT_NAK) != 0){
+		if(hc->ep_type == EP_TYPE_INTR){
+			sil_orw_mem((uint32_t *)(USBHC_BASE(base, chnum)+TOFF_USBHC_HCINTMSK), USB_OTG_HCINTMSK_CHHM);
+			usbo_hc_halt(husb, chnum);
+		}
+		else if((hc->ep_type == EP_TYPE_CTRL) || (hc->ep_type == EP_TYPE_BULK)){
+			/*
+			 *  チャネルの再アクティブ
+			 */
+			sil_modw_mem((uint32_t *)(USBHC_BASE(base, chnum)+TOFF_USBHC_HCCHAR), USB_OTG_HCCHAR_CHDIS, USB_OTG_HCCHAR_CHENA);
+		}
+		hc->state = USBO_HC_NAK;
+		clear_hc_int(base, chnum, USB_OTG_HCINT_NAK);
+	}
+}
+
+/*
+ *  HOSTチャネルOUT割込み要求
+ *  parameter1 husb  USBハンドラへのポインタ
+ *  parameter2 chnum チャネル番号(1-15)
+ */
+static void
+usbo_hc_out_irqhandler(USB_OTG_Handle_t *husb, uint8_t chnum)
+{
+    USB_OTG_HCTypeDef *hc = &husb->hc[chnum];
+	uint32_t base = husb->base;
+
+	if(hc_int_status(base, chnum, USB_OTG_HCINT_AHBERR) != 0){
+		clear_hc_int(base, chnum, USB_OTG_HCINT_AHBERR);
+		sil_orw_mem((uint32_t *)(USBHC_BASE(base, chnum)+TOFF_USBHC_HCINTMSK), USB_OTG_HCINTMSK_CHHM);
+	}
+	else if(hc_int_status(base, chnum, USB_OTG_HCINT_ACK) != 0){
+		clear_hc_int(base, chnum, USB_OTG_HCINT_ACK);
+		if(hc->do_ping == 1U){
+			hc->state = USBO_HC_NYET;
+			sil_orw_mem((uint32_t *)(USBHC_BASE(base, chnum)+TOFF_USBHC_HCINTMSK), USB_OTG_HCINTMSK_CHHM);
+			usbo_hc_halt(husb, chnum);
+			hc->urb_state  = URB_NOTREADY;
+		}
+	}
+	else if(hc_int_status(base, chnum, USB_OTG_HCINT_NYET) != 0){
+		hc->state = USBO_HC_NYET;
+		hc->err_count= 0;
+		sil_orw_mem((uint32_t *)(USBHC_BASE(base, chnum)+TOFF_USBHC_HCINTMSK), USB_OTG_HCINTMSK_CHHM);
+		usbo_hc_halt(husb, chnum);
+		clear_hc_int(base, chnum, USB_OTG_HCINT_NYET);
+	}
+	else if(hc_int_status(base, chnum, USB_OTG_HCINT_FRMOR) != 0){
+		sil_orw_mem((uint32_t *)(USBHC_BASE(base, chnum)+TOFF_USBHC_HCINTMSK), USB_OTG_HCINTMSK_CHHM);
+		usbo_hc_halt(husb, chnum);
+		clear_hc_int(base, chnum, USB_OTG_HCINT_FRMOR);
+	}
+	else if(hc_int_status(base, chnum, USB_OTG_HCINT_XFRC) != 0){
+		hc->err_count = 0;
+		sil_orw_mem((uint32_t *)(USBHC_BASE(base, chnum)+TOFF_USBHC_HCINTMSK), USB_OTG_HCINTMSK_CHHM);
+		usbo_hc_halt(husb, chnum);
+		clear_hc_int(base, chnum, USB_OTG_HCINT_XFRC);
+		hc->state = USBO_HC_XFRC;
+	}
+	else if(hc_int_status(base, chnum, USB_OTG_HCINT_STALL) != 0){
+		clear_hc_int(base, chnum, USB_OTG_HCINT_STALL);
+		sil_orw_mem((uint32_t *)(USBHC_BASE(base, chnum)+TOFF_USBHC_HCINTMSK), USB_OTG_HCINTMSK_CHHM);
+		usbo_hc_halt(husb, chnum);
+		hc->state = USBO_HC_STALL;
+	}
+	else if(hc_int_status(base, chnum, USB_OTG_HCINT_NAK) != 0){
+		hc->err_count = 0;
+		sil_orw_mem((uint32_t *)(USBHC_BASE(base, chnum)+TOFF_USBHC_HCINTMSK), USB_OTG_HCINTMSK_CHHM);
+		usbo_hc_halt(husb, chnum);
+		hc->state = USBO_HC_NAK;
+		clear_hc_int(base, chnum, USB_OTG_HCINT_NAK);
+	}
+	else if(hc_int_status(base, chnum,USB_OTG_HCINT_TXERR) != 0){
+		sil_orw_mem((uint32_t *)(USBHC_BASE(base, chnum)+TOFF_USBHC_HCINTMSK), USB_OTG_HCINTMSK_CHHM);
+		usbo_hc_halt(husb, chnum);
+		hc->state = USBO_HC_XACTERR;
+#if 1	/* ROI DEBUG */
+    syslog_1(LOG_NOTICE, "## SET USBO_HC_XACTERR2 [%08x] ##", sil_rew_mem((uint32_t *)(USBHC_BASE(base, chnum)+TOFF_USBHC_HCINT)));
+#endif	/* ROI DEBUG */
+		clear_hc_int(base, chnum, USB_OTG_HCINT_TXERR);
+	}
+	else if(hc_int_status(base, chnum, USB_OTG_HCINT_DTERR) != 0){
+		sil_orw_mem((uint32_t *)(USBHC_BASE(base, chnum)+TOFF_USBHC_HCINTMSK), USB_OTG_HCINTMSK_CHHM);
+ 		usbo_hc_halt(husb, chnum);
+		clear_hc_int(base, chnum, USB_OTG_HCINT_NAK);
+		clear_hc_int(base, chnum, USB_OTG_HCINT_DTERR);
+		hc->state = USBO_HC_DATATGLERR;
+	}
+	else if(hc_int_status(base, chnum, USB_OTG_HCINT_CHH) != 0){
+		sil_andw_mem((uint32_t *)(USBHC_BASE(base, chnum)+TOFF_USBHC_HCINTMSK), USB_OTG_HCINTMSK_CHHM);
+		if(hc->state == USBO_HC_XFRC){
+			hc->urb_state  = URB_DONE;
+			if(hc->ep_type == EP_TYPE_BULK){
+				hc->toggle_out ^= 1U; 
+			}
+		}
+		else if (hc->state == USBO_HC_NAK){
+			hc->urb_state  = URB_NOTREADY;
+		}
+		else if (hc->state == USBO_HC_NYET){
+			hc->urb_state  = URB_NOTREADY;
+			hc->do_ping = 0U;
+		}
+		else if (hc->state == USBO_HC_STALL){
+			hc->urb_state  = URB_STALL;
+		}
+		else if((hc->state == USBO_HC_XACTERR) || (hc->state == USBO_HC_DATATGLERR)){
+			if(hc->err_count++ > 3){
+				hc->err_count = 0;
+				hc->urb_state = URB_ERROR;
+			}
+			else{
+				hc->urb_state = URB_NOTREADY;
+			}
+
+			/* re-activate the channel  */
+			sil_modw_mem((uint32_t *)(USBHC_BASE(base, chnum)+TOFF_USBHC_HCCHAR), USB_OTG_HCCHAR_CHDIS, USB_OTG_HCCHAR_CHENA);
+		}
+		clear_hc_int(base, chnum, USB_OTG_HCINT_CHH);
+		if(husb->hostchangeurbcallback != NULL)
+			husb->hostchangeurbcallback(husb, chnum, husb->hc[chnum].urb_state);
+	}
+}
+
+/*
+ *  RX QUEUE LEVEL割込み要求
+ *  parameter1 husb  USBハンドラへのポインタ
+ */
+static void
+usbo_rxqlvl_irqhandler(USB_OTG_Handle_t *husb)
+{
+	uint32_t base = husb->base;
+	uint8_t  channelnum = 0U;
+	uint32_t pktsts, pktcnt;
+	uint32_t temp = 0U;
+
+	temp = sil_rew_mem((uint32_t *)(USBOTG_BASE(base)+TOFF_USBO_GRXSTSP));
+	channelnum = temp &  USB_OTG_GRXSTSP_EPNUM;  
+	pktsts = (temp &  USB_OTG_GRXSTSP_PKTSTS) >> 17U;
+	pktcnt = (temp &  USB_OTG_GRXSTSP_BCNT) >> 4U;
+
+	switch(pktsts){
+	case GRXSTS_PKTSTS_IN:
+		/*
+		 *  HOSTバッファパケット読み込み
+		 */
+		if((pktcnt > 0) && (husb->hc[channelnum].xfer_buff != (void  *)0U)){
+			usbo_readPacket(husb->base, husb->hc[channelnum].xfer_buff, pktcnt);
+
+			/*
+			 *  マルチデータ処理
+			 */
+			husb->hc[channelnum].xfer_buff += pktcnt;
+			husb->hc[channelnum].xfer_count  += pktcnt;
+
+			if((sil_rew_mem((uint32_t *)(USBHC_BASE(base, channelnum)+TOFF_USBHC_HCTSIZ)) & USB_OTG_HCTSIZ_PKTCNT) > 0){
+				sil_modw_mem((uint32_t *)(USBHC_BASE(base, channelnum)+TOFF_USBHC_HCCHAR), USB_OTG_HCCHAR_CHDIS, USB_OTG_HCCHAR_CHENA);
+				husb->hc[channelnum].toggle_in ^= 1U;
+			}
+		}
+		break;
+
+	case GRXSTS_PKTSTS_DATA_TOGGLE_ERR:
+	case GRXSTS_PKTSTS_IN_XFER_COMP:
+	case GRXSTS_PKTSTS_CH_HALTED:
+	default:
+		break;
+	}
+}
+
+/*
+ *  HOSTポート割込み要求
+ *  parameter1 husb  USBハンドラへのポインタ
+ */
+static void
+usbo_port_irqhandler(USB_OTG_Handle_t *husb)
+{
+	uint32_t base = husb->base;
+	volatile uint32_t hprt0, hprt0_dup;
+
+	hprt0 = sil_rew_mem((uint32_t*)(USBPRT_BASE(base)));
+	hprt0_dup = hprt0 & ~USB_OTG_HPRT_PENA;
+
+	/*
+	 *  ポートコネクトチェック
+	 */
+	if((hprt0 & USB_OTG_HPRT_PCDET) != 0){
+		if((hprt0 & USB_OTG_HPRT_PCSTS) == USB_OTG_HPRT_PCSTS){
+			sil_andw_mem((uint32_t *)(USBOTG_BASE(base)+TOFF_USBO_GINTMSK), USB_OTG_GINTSTS_DISCINT);
+			if(husb->hostconnectcallback != NULL)
+				husb->hostconnectcallback(husb);
+		}
+	}
+
+	/*
+	 *  ポートイネーブル変化チェック
+	 */
+	if((hprt0 & USB_OTG_HPRT_PENCHNG) != 0){
+		if((hprt0 & USB_OTG_HPRT_PENA) != 0){
+			if(husb->Init.phy_itface  == USB_PHY_EMBEDDED){
+				if((hprt0 & USB_OTG_HPRT_PSPD) == (HPRT0_PRTSPD_LOW_SPEED << 17)){
+					usbo_initFSLSPClkSel(husb, 6000);
+				}
+				else{
+					usbo_initFSLSPClkSel(husb, 48000);
+				}
+			}
+			else{
+				if(husb->Init.speed == USB_SPEED_FULL){
+					sil_wrw_mem((uint32_t *)(USBH_BASE(base)+TOFF_USBH_HFIR), 60000U);
+				}
+			}
+
+			if(husb->hostconnectcallback != NULL)
+				husb->hostconnectcallback(husb);
+
+			if(husb->Init.speed == USB_SPEED_HIGH){
+				sil_orw_mem((uint32_t *)(USBOTG_BASE(base)+TOFF_USBO_GINTMSK), USB_OTG_GINTSTS_DISCINT);
+			}
+		}
+		else{
+			/*
+			 *  HPRTのクリーン
+			 */
+			sil_andw_mem((uint32_t*)(USBPRT_BASE(base)), (USB_OTG_HPRT_PENA | USB_OTG_HPRT_PCDET |\
+				USB_OTG_HPRT_PENCHNG | USB_OTG_HPRT_POCCHNG ));
+			sil_orw_mem((uint32_t *)(USBOTG_BASE(base)+TOFF_USBO_GINTMSK), USB_OTG_GINTSTS_DISCINT);
+		}
+	}
+
+	/*
+	 *  ポート割込みクリア
+	 */
+	sil_wrw_mem((uint32_t*)(USBPRT_BASE(base)), hprt0_dup);
+}
+
+/*
+ *  HOST割込みハンドラ
+ *  parameter1 husb  USBハンドラへのポインタ
+ */
+void
+usbo_hcd_irqhandler(USB_OTG_Handle_t *husb)
+{
+	uint32_t base = husb->base;
+	uint32_t msk  = sil_rew_mem((uint32_t *)(USBOTG_BASE(base)+TOFF_USBO_GINTMSK));
+	uint32_t i = 0, int_status = 0, intsts = 0;
+
+	/*
+	 *  許可しない要因の割込みは無視する
+	 */
+	if((intsts = get_int_status(base, msk)) == 0){
+		intsts = sil_rew_mem((uint32_t *)(USBOTG_BASE(base)+TOFF_USBO_GINTSTS));
+		syslog_1(LOG_EMERG, "usbo_hcd_irqhandler Error Intrrupt[%08x] !", intsts);
+		clear_host_int(base, intsts);
+		return;
+	}
+
+	if((intsts & USB_OTG_GINTSTS_PXFR_INCOMPISOOUT) != 0){
+		/*
+		 *  未要求割込み要因クリア
+		 */
+		clear_host_int(base, USB_OTG_GINTSTS_PXFR_INCOMPISOOUT);
+	}
+	if((intsts & USB_OTG_GINTSTS_IISOIXFR) != 0){
+		/*
+		 *  未要求割込み要因クリア
+		 */
+		clear_host_int(base, USB_OTG_GINTSTS_IISOIXFR);
+	}
+
+	if((intsts & USB_OTG_GINTSTS_PTXFE) != 0){
+		/*
+		 *  未要求割込み要因クリア
+		 */
+		clear_host_int(base, USB_OTG_GINTSTS_PTXFE);
+	}
+    if((intsts & USB_OTG_GINTSTS_MMIS) != 0){
+		/*
+		 *  未要求割込み要因クリア
+		 */
+		clear_host_int(base, USB_OTG_GINTSTS_MMIS);
+    }
+    /*
+	 *  HOSTディスコネクト割込み
+	 */
+	if((intsts & USB_OTG_GINTSTS_DISCINT) != 0){
+		/*
+		 *  HPRTのクリーンアップ
+		 */
+		sil_andw_mem((uint32_t*)(USBPRT_BASE(base)), (USB_OTG_HPRT_PENA | USB_OTG_HPRT_PCDET |\
+			USB_OTG_HPRT_PENCHNG | USB_OTG_HPRT_POCCHNG ));
+		if(husb->hostdisconnectcallback != NULL)
+			husb->hostdisconnectcallback(husb);
+		usbo_initFSLSPClkSel(husb, 48000);
+		clear_host_int(base, USB_OTG_GINTSTS_DISCINT);
+	}
+	/*
+	 *  HOSTポート割込み
+	 */
+	if((intsts & USB_OTG_GINTSTS_HPRTINT) != 0){
+		syslog_0(LOG_NOTICE, "## usbo_hcd_irqhandler USB_OTG_GINTSTS_HPRTINT ##");
+		usbo_port_irqhandler(husb);
+		if(husb->Init.usb_otg_mode == USB_OTG_MODE_DRD)
+			sil_dly_nse(10*1000*1000);	/* 注意：デバイスレディまでの待ち(割込みでしか待てない) */
+	}
+	/*
+	 *  Host SOF割込み
+	 */
+    if((intsts & USB_OTG_GINTSTS_SOF) != 0){
+		if(husb->hostsofcallback != NULL)
+			husb->hostsofcallback(husb);
+		clear_host_int(base, USB_OTG_GINTSTS_SOF);
+	}
+	/*
+	 *  HOSTチャネル割込み
+	 */
+	if((intsts & USB_OTG_GINTSTS_HCINT) != 0){
+		int_status = get_haint_status(base);
+		for(i = 0 ; i < husb->Init.host_channels; i++){
+			if(int_status & (1 << i)){
+				if((sil_rew_mem((uint32_t *)(USBHC_BASE(husb->base, i)+TOFF_USBHC_HCCHAR)) &  USB_OTG_HCCHAR_EPDIR) != 0)
+					usbo_hc_in_irqhandler(husb, i);
+				else
+					usbo_hc_out_irqhandler(husb, i);
+			}
+		}
+		clear_host_int(base, USB_OTG_GINTSTS_HCINT);
+	}
+	/*
+	 *  RXキューレベル割込み
+	 */
+	if((intsts & USB_OTG_GINTSTS_RXFLVL) != 0){
+		sil_andw_mem((uint32_t *)(USBOTG_BASE(base)+TOFF_USBO_GINTMSK), USB_OTG_GINTSTS_RXFLVL);
+		usbo_rxqlvl_irqhandler(husb);
+		sil_orw_mem((uint32_t *)(USBOTG_BASE(base)+TOFF_USBO_GINTMSK), USB_OTG_GINTSTS_RXFLVL);
+	}
+}
+
+/*******************************************************************************
+                       USB DEVICE関数
+*******************************************************************************/
+/*
+ *  USB DEVICEスピード設定
+ *  parameter1 base  USB OTGレジスタベースアドレス
+ *  parameter2 speed device speed USB_SPEED_HIGH(High speed mode)
+ *                                USB_SPEED_HIGH_IN_FULL(High speed core in Full Speed mode)
+ *                                USB_SPEED_FULL(Full speed mode)
+ *                                USB_SPEED_LOW(Low speed mode)
+ */
+static void
+usbo_setDevSpeed(uint32_t base, uint8_t speed)
+{
+	sil_orw_mem((uint32_t *)(USBD_BASE(base)+TOFF_USBD_DCFG), speed);
+}
+
+/*
+ *  デバイスコネクト
+ *  parameter1 husb  USBハンドラへのポインタ
+ *  return     常にE_OK
+ */
+ER
+usbo_devconnect(USB_OTG_Handle_t *husb)
+{
+	sil_andw_mem((uint32_t *)(USBD_BASE(husb->base)+TOFF_USBD_DCTL), USB_OTG_DCTL_SDIS);
+//	dly_tsk(3);
+	return E_OK;
+}
+
+/*
+ *  デバイスディスコネクト
+ *  parameter1 husb  USBハンドラへのポインタ
+ *  return     常にE_OK
+ */
+ER
+usbo_devdisconnect(USB_OTG_Handle_t *husb)
+{
+	sil_orw_mem((uint32_t *)(USBD_BASE(husb->base)+TOFF_USBD_DCTL), USB_OTG_DCTL_SDIS);
+//	dly_tsk(3);
+	return E_OK; 
+}
+
+/*
+ *  アクティブエンドポイント設定
+ *  parameter1 husb  USBハンドラへのポインタ
+ *  parameter2 ep    エンドポイント構造体へのポインタ
+ *  return     常にE_OK
+ */
+ER
+usbo_activateEndpoint(USB_OTG_Handle_t *husb, USB_OTG_EPTypeDef *ep)
+{
+	uint32_t base = husb->base;
+
+	if(ep->is_in == 1){
+		sil_orw_mem((uint32_t *)(USBD_BASE(base)+TOFF_USBD_DAINTMSK), USB_OTG_DAINTMSK_IEPM & (1 << (ep->num)));
+		if(((sil_rew_mem((uint32_t *)(USBIEP_BASE(base, ep->num)+TOFF_USBEI_DIEPCTL))) & USB_OTG_DIEPCTL_USBAEP) == 0){
+			sil_orw_mem((uint32_t *)(USBIEP_BASE(base, ep->num)+TOFF_USBEI_DIEPCTL), ((ep->maxpacket & USB_OTG_DIEPCTL_MPSIZ ) | (ep->type << 18U) |\
+				((ep->num) << 22U) | (USB_OTG_DIEPCTL_SD0PID_SEVNFRM) | (USB_OTG_DIEPCTL_USBAEP))); 
+		}
+	}
+	else{
+		sil_orw_mem((uint32_t *)(USBD_BASE(base)+TOFF_USBD_DAINTMSK), USB_OTG_DAINTMSK_OEPM & ((1 << (ep->num)) << 16));
+		if(((sil_rew_mem((uint32_t *)(USBOEP_BASE(base, ep->num)+TOFF_USBEO_DOEPCTL))) & USB_OTG_DIEPCTL_USBAEP) == 0){
+			sil_orw_mem((uint32_t *)(USBOEP_BASE(base, ep->num)+TOFF_USBEO_DOEPCTL), ((ep->maxpacket & USB_OTG_DOEPCTL_MPSIZ ) | (ep->type << 18U) |\
+				(USB_OTG_DIEPCTL_SD0PID_SEVNFRM)| (USB_OTG_DOEPCTL_USBAEP)));
+		}
+	}
+	return E_OK;
+}
+
+/*
+ *  ディスアクティブエンドポイント設定
+ *  parameter1 husb  USBハンドラへのポインタ
+ *  parameter2 ep    エンドポイント構造体へのポインタ
+ *  return     常にE_OK
+ */
+ER
+usbo_deactivateEndpoint(USB_OTG_Handle_t *husb, USB_OTG_EPTypeDef *ep)
+{
+	uint32_t base = husb->base;
+
+	if(ep->is_in == 1){
+		sil_andw_mem((uint32_t *)(USBD_BASE(base)+TOFF_USBD_DEACHMSK), (USB_OTG_DAINTMSK_IEPM & (1 << (ep->num))));
+		sil_andw_mem((uint32_t *)(USBD_BASE(base)+TOFF_USBD_DAINTMSK), (USB_OTG_DAINTMSK_IEPM & (1 << (ep->num))));
+		sil_andw_mem((uint32_t *)(USBIEP_BASE(base, ep->num)+TOFF_USBEI_DIEPCTL), USB_OTG_DIEPCTL_USBAEP);
+	}
+	else{
+		sil_andw_mem((uint32_t *)(USBD_BASE(base)+TOFF_USBD_DEACHMSK), (USB_OTG_DAINTMSK_OEPM & ((1 << (ep->num)) << 16)));
+		sil_andw_mem((uint32_t *)(USBD_BASE(base)+TOFF_USBD_DAINTMSK), (USB_OTG_DAINTMSK_OEPM & ((1 << (ep->num)) << 16)));
+		sil_andw_mem((uint32_t *)(USBOEP_BASE(base, ep->num)+TOFF_USBEO_DOEPCTL), USB_OTG_DOEPCTL_USBAEP);
+	}
+	return E_OK;
+}
+
+/*
+ *  エンドポイントにステール状態を設定
+ *  parameter1 husb  USBハンドラへのポインタ
+ *  parameter2 ep    エンドポイント構造体へのポインタ
+ *  return     常にE_OK
+ */
+ER
+usbo_epsetStall(USB_OTG_Handle_t *husb, USB_OTG_EPTypeDef *ep)
+{
+	uint32_t base = husb->base;
+
+	if(ep->is_in == 1){
+		if((sil_rew_mem((uint32_t *)(USBIEP_BASE(base, ep->num)+TOFF_USBEI_DIEPCTL)) & USB_OTG_DIEPCTL_EPENA) == 0){
+			sil_andw_mem((uint32_t *)(USBIEP_BASE(base, ep->num)+TOFF_USBEI_DIEPCTL), USB_OTG_DIEPCTL_EPDIS);
+		}
+		sil_orw_mem((uint32_t *)(USBIEP_BASE(base, ep->num)+TOFF_USBEI_DIEPCTL), USB_OTG_DIEPCTL_STALL);
+	}
+	else{
+		if((sil_rew_mem((uint32_t *)(USBOEP_BASE(base, ep->num)+TOFF_USBEO_DOEPCTL)) & USB_OTG_DOEPCTL_EPENA) == 0){
+			sil_andw_mem((uint32_t *)(USBOEP_BASE(base, ep->num)+TOFF_USBEO_DOEPCTL), USB_OTG_DOEPCTL_EPDIS);
+		}
+		sil_orw_mem((uint32_t *)(USBOEP_BASE(base, ep->num)+TOFF_USBEO_DOEPCTL), USB_OTG_DOEPCTL_STALL);
+	}
+	return E_OK;
+}
+
+/*
+ *  エンドポイントのステール状態をクリア
+ *  parameter1 husb  USBハンドラへのポインタ
+ *  parameter2 ep    エンドポイント構造体へのポインタ
+ *  return     常にE_OK
+ *
+ */
+ER
+usbo_epclearStall(USB_OTG_Handle_t *husb, USB_OTG_EPTypeDef *ep)
+{
+	uint32_t base = husb->base;
+
+	if(ep->is_in == 1){
+		sil_andw_mem((uint32_t *)(USBIEP_BASE(base, ep->num)+TOFF_USBEI_DIEPCTL), USB_OTG_DIEPCTL_STALL);
+		if(ep->type == EP_TYPE_INTR || ep->type == EP_TYPE_BULK){
+			sil_orw_mem((uint32_t *)(USBIEP_BASE(base, ep->num)+TOFF_USBEI_DIEPCTL), USB_OTG_DIEPCTL_SD0PID_SEVNFRM);	/* DATA0 */
+		}
+	}
+	else{
+		sil_andw_mem((uint32_t *)(USBOEP_BASE(base, ep->num)+TOFF_USBEO_DOEPCTL), USB_OTG_DOEPCTL_STALL);
+		if(ep->type == EP_TYPE_INTR || ep->type == EP_TYPE_BULK){
+			sil_orw_mem((uint32_t *)(USBOEP_BASE(base, ep->num)+TOFF_USBEO_DOEPCTL), USB_OTG_DOEPCTL_SD0PID_SEVNFRM);	/* DATA0 */
+		}
+	}
+	return E_OK;
+}
+
+/**
+ *  USBにデバイスアドレスを設定
+ *  parameter1 husb  USBハンドラへのポインタ
+ *  parameter2 addree デバイスアドレス(0-255)
+ *  return     常にE_OK
+ */
+ER
+usbo_setDevAddress(USB_OTG_Handle_t *husb, uint8_t address)
+{
+	husb->connected = 1;
+	sil_andw_mem((uint32_t *)(USBD_BASE(husb->base)+TOFF_USBD_DCFG), USB_OTG_DCFG_DAD);
+	sil_orw_mem((uint32_t *)(USBD_BASE(husb->base)+TOFF_USBD_DCFG), ((address << 4) & USB_OTG_DCFG_DAD));
+	return E_OK;
+}
+
+/*
+ *  USBデバイススピードを取り出す
+ *  parameter1 husb  USBハンドラへのポインタ
+ *  return     speed デバイススピード USB_SPEED_HIGH: High speed mode
+ *                                    USB_SPEED_FULL: Full speed mode
+ *                                    USB_SPEED_LOW: Low speed mode
+ */
+uint8_t
+usbo_getDevSpeed(USB_OTG_Handle_t *husb)
+{
+	uint8_t  speed = 0;
+	uint32_t status = sil_rew_mem((uint32_t *)(USBD_BASE(husb->base)+TOFF_USBD_DSTS));
+
+	if((status & USB_OTG_DSTS_ENUMSPD) == DSTS_ENUMSPD_HS_PHY_30MHZ_OR_60MHZ){
+		speed = USB_SPEED_HIGH;
+	}
+	else if(((status & USB_OTG_DSTS_ENUMSPD) == DSTS_ENUMSPD_FS_PHY_30MHZ_OR_60MHZ) || ((status & USB_OTG_DSTS_ENUMSPD) == DSTS_ENUMSPD_FS_PHY_48MHZ)){
+		speed = USB_SPEED_FULL;
+	}
+	else if((status & USB_OTG_DSTS_ENUMSPD) == DSTS_ENUMSPD_LS_PHY_6MHZ){
+		speed = USB_SPEED_LOW;
+	}
+	return speed;
+}
+
+/*
+ *  EP0-OUTスタート
+ *  parameter1 husb  USBハンドラへのポインタ
+ *  parameter2 psetup セットアップパケットデータへのポインタ
+ *  return     常にE_OK
+ */
+ER
+usbo_ep0_outstart(USB_OTG_Handle_t *husb, uint8_t *psetup)
+{
+	uint32_t base = husb->base;
+
+	sil_wrw_mem((uint32_t *)(USBOEP_BASE(base, 0)+TOFF_USBEO_DOEPTSIZ), 0);
+	sil_orw_mem((uint32_t *)(USBOEP_BASE(base, 0)+TOFF_USBEO_DOEPTSIZ), (USB_OTG_DOEPTSIZ_PKTCNT & (1U << 19U)));
+	sil_orw_mem((uint32_t *)(USBOEP_BASE(base, 0)+TOFF_USBEO_DOEPTSIZ), (3U * 8U));
+	sil_orw_mem((uint32_t *)(USBOEP_BASE(base, 0)+TOFF_USBEO_DOEPTSIZ), USB_OTG_DOEPTSIZ_STUPCNT);
+
+	if(husb->Init.dma_enable == 1){
+		flushinvalidatedcache_by_addr(psetup, 64);
+		sil_wrw_mem((uint32_t *)(USBOEP_BASE(base, 0)+TOFF_USBEO_DOEPDMA), (uint32_t)psetup);
+ 		/*
+		 *  EP0有効化
+		 */
+		sil_wrw_mem((uint32_t *)(USBOEP_BASE(base, 0)+TOFF_USBEO_DOEPCTL), 0x80008000);
+	}
+	return E_OK;
+}
+
+/*
+ *  EP0転送スタート
+ *  parameter1 husb  USBハンドラへのポインタ
+ *  parameter2 ep    エンドポイント構造体へのポインタ
+ *  return     常にE_OK
+ */
+ER
+usbo_ep0startxfer(USB_OTG_Handle_t *husb, USB_OTG_EPTypeDef *ep)
+{
+	uint32_t base   = husb->base;
+	uint8_t  epnum  = ep->num;
+
+	if(ep->is_in == 1){	/* INエンドポイント */
+		if(ep->xfer_len == 0){	/* ZERO-LENGTHパケット */
+			sil_andw_mem((uint32_t *)(USBIEP_BASE(base, epnum)+TOFF_USBEI_DIEPTSIZ), USB_OTG_DIEPTSIZ_PKTCNT);
+			sil_orw_mem((uint32_t *)(USBIEP_BASE(base, epnum)+TOFF_USBEI_DIEPTSIZ), (USB_OTG_DIEPTSIZ_PKTCNT & (1 << 19)));
+			sil_andw_mem((uint32_t *)(USBIEP_BASE(base, epnum)+TOFF_USBEI_DIEPTSIZ), USB_OTG_DIEPTSIZ_XFRSIZ);
+		}
+		else{	/* 通常パケット */
+			/*
+			 *  パケット数とデータ長に分けて設定(EP0なのでパケット数は1)
+			 */
+			sil_andw_mem((uint32_t *)(USBIEP_BASE(base, epnum)+TOFF_USBEI_DIEPTSIZ), USB_OTG_DIEPTSIZ_XFRSIZ);
+			sil_andw_mem((uint32_t *)(USBIEP_BASE(base, epnum)+TOFF_USBEI_DIEPTSIZ), USB_OTG_DIEPTSIZ_PKTCNT);
+			if(ep->xfer_len > ep->maxpacket){
+				ep->xfer_len = ep->maxpacket;
+			}
+			sil_orw_mem((uint32_t *)(USBIEP_BASE(base, epnum)+TOFF_USBEI_DIEPTSIZ), (USB_OTG_DIEPTSIZ_PKTCNT & (1 << 19)));
+			sil_orw_mem((uint32_t *)(USBIEP_BASE(base, epnum)+TOFF_USBEI_DIEPTSIZ), (USB_OTG_DIEPTSIZ_XFRSIZ & ep->xfer_len));
+		}
+
+		if(husb->Init.dma_enable == 1){
+			flushinvalidatedcache_by_addr(((uint8_t *)ep->dma_addr), ep->xfer_len);
+			sil_wrw_mem((uint32_t *)(USBIEP_BASE(base, epnum)+TOFF_USBEI_DIEPDMA), ep->dma_addr);
+		}
+		else{
+			/*
+			 *  DMAモードでない場合は、EMPTY割込みを設定
+			 */
+			if(ep->xfer_len > 0){
+				sil_orw_mem((uint32_t *)(USBD_BASE(base)+TOFF_USBD_DIEPEMPMSK), (1 << (ep->num)));
+			}
+		}
+		/*
+		 *  クリアNAK、エンドポイントイネーブル
+		 */
+		sil_orw_mem((uint32_t *)(USBIEP_BASE(base, epnum)+TOFF_USBEI_DIEPCTL), (USB_OTG_DIEPCTL_CNAK | USB_OTG_DIEPCTL_EPENA));
+	}
+	else{	 /* OUTエンドポイント */
+		/*
+		 *  パケット数とデータ長に分けて設定(EP0なのでパケット数は1)
+		 */
+		sil_andw_mem((uint32_t *)(USBOEP_BASE(base, epnum)+TOFF_USBEO_DOEPTSIZ), USB_OTG_DOEPTSIZ_XFRSIZ);
+		sil_andw_mem((uint32_t *)(USBOEP_BASE(base, epnum)+TOFF_USBEO_DOEPTSIZ), USB_OTG_DOEPTSIZ_PKTCNT);
+
+		if(ep->xfer_len > 0U){
+			ep->xfer_len = ep->maxpacket;
+		}
+
+		sil_orw_mem((uint32_t *)(USBOEP_BASE(base, epnum)+TOFF_USBEO_DOEPTSIZ), (USB_OTG_DOEPTSIZ_PKTCNT & (1 << 19)));
+		sil_orw_mem((uint32_t *)(USBOEP_BASE(base, epnum)+TOFF_USBEO_DOEPTSIZ), (USB_OTG_DOEPTSIZ_XFRSIZ & (ep->maxpacket)));
+
+		if(husb->Init.dma_enable == 1){
+			flushinvalidatedcache_by_addr(ep->xfer_buff, ep->xfer_len);
+			sil_wrw_mem((uint32_t *)(USBOEP_BASE(base, epnum)+TOFF_USBEO_DOEPDMA), (uint32_t)(ep->xfer_buff));
+		}
+		/*
+		 *  クリアNAK、エンドポイントイネーブル
+		 */
+		sil_orw_mem((uint32_t *)(USBOEP_BASE(base, epnum)+TOFF_USBEO_DOEPCTL), (USB_OTG_DOEPCTL_CNAK | USB_OTG_DOEPCTL_EPENA));
+	}
+	return E_OK;
+}
+
+/*
+ *  EPn転送スタート
+ *  parameter1 husb  USBハンドラへのポインタ
+ *  parameter2 ep    エンドポイント構造体へのポインタ
+ *  return     常にE_OK
+ */
+ER
+usbo_epstartxfer(USB_OTG_Handle_t *husb, USB_OTG_EPTypeDef *ep)
+{
+	uint32_t base   = husb->base;
+	uint16_t pktcnt = 0;
+	uint8_t  epnum  = ep->num;
+
+	if(ep->is_in == 1){	/* INエンドポイント */
+		if(ep->xfer_len == 0){	/* ZERO-LENGTHパケット */
+			sil_andw_mem((uint32_t *)(USBIEP_BASE(base, epnum)+TOFF_USBEI_DIEPTSIZ), USB_OTG_DIEPTSIZ_PKTCNT);
+			sil_orw_mem((uint32_t *)(USBIEP_BASE(base, epnum)+TOFF_USBEI_DIEPTSIZ), (USB_OTG_DIEPTSIZ_PKTCNT & (1 << 19)));
+			sil_andw_mem((uint32_t *)(USBIEP_BASE(base, epnum)+TOFF_USBEI_DIEPTSIZ), USB_OTG_DIEPTSIZ_XFRSIZ);
+		}
+		else{	/* 通常パケット */
+			/*
+			 *  パケット数とデータ長に分けて設定
+			 */
+			sil_andw_mem((uint32_t *)(USBIEP_BASE(base, epnum)+TOFF_USBEI_DIEPTSIZ), USB_OTG_DIEPTSIZ_XFRSIZ);
+			sil_andw_mem((uint32_t *)(USBIEP_BASE(base, epnum)+TOFF_USBEI_DIEPTSIZ), USB_OTG_DIEPTSIZ_PKTCNT);
+			sil_orw_mem((uint32_t *)(USBIEP_BASE(base, epnum)+TOFF_USBEI_DIEPTSIZ), (USB_OTG_DIEPTSIZ_PKTCNT & (((ep->xfer_len + ep->maxpacket -1)/ ep->maxpacket) << 19)));
+			sil_orw_mem((uint32_t *)(USBIEP_BASE(base, epnum)+TOFF_USBEI_DIEPTSIZ), (USB_OTG_DIEPTSIZ_XFRSIZ & ep->xfer_len));
+
+			if(ep->type == EP_TYPE_ISOC){
+				sil_andw_mem((uint32_t *)(USBIEP_BASE(base, epnum)+TOFF_USBEI_DIEPTSIZ), USB_OTG_DIEPTSIZ_MULCNT);
+				sil_orw_mem((uint32_t *)(USBIEP_BASE(base, epnum)+TOFF_USBEI_DIEPTSIZ), (USB_OTG_DIEPTSIZ_MULCNT & (1 << 29)));
+			}
+		}
+
+		if(husb->Init.dma_enable == 1){
+			flushinvalidatedcache_by_addr(((uint8_t *)ep->dma_addr), ep->xfer_len);
+			sil_wrw_mem((uint32_t *)(USBIEP_BASE(base, epnum)+TOFF_USBEI_DIEPDMA), ep->dma_addr);
+		}
+		else{
+			/*
+			 *  EPがISOCでない場合、送信データありならばEMPTY割込みを設定
+			 */
+			if(ep->type != EP_TYPE_ISOC && ep->xfer_len > 0){
+				sil_orw_mem((uint32_t *)(USBD_BASE(base)+TOFF_USBD_DIEPEMPMSK), (1 << (epnum)));
+			}
+		}
+
+		if(ep->type == EP_TYPE_ISOC){
+			if((sil_rew_mem((uint32_t *)(USBD_BASE(base)+TOFF_USBD_DSTS)) & (1 << 8)) == 0){
+				sil_orw_mem((uint32_t *)(USBIEP_BASE(base, epnum)+TOFF_USBEI_DIEPCTL), USB_OTG_DIEPCTL_SODDFRM);
+			}
+			else{
+				sil_orw_mem((uint32_t *)(USBIEP_BASE(base, epnum)+TOFF_USBEI_DIEPCTL), USB_OTG_DIEPCTL_SD0PID_SEVNFRM);
+			}
+		}
+		/*
+		 *  クリアNAK、エンドポイントイネーブル
+		 */
+		sil_orw_mem((uint32_t *)(USBIEP_BASE(base, epnum)+TOFF_USBEI_DIEPCTL), (USB_OTG_DIEPCTL_CNAK | USB_OTG_DIEPCTL_EPENA));
+
+		if(ep->type == EP_TYPE_ISOC){
+			usbo_writePacket(base, ep->xfer_buff, epnum, ep->xfer_len, husb->Init.dma_enable);
+		}
+	}
+	else{	 /* OUTエンドポイント */
+		/*
+		 *  パケット数とデータ長に分けて設定
+		 */
+		sil_andw_mem((uint32_t *)(USBOEP_BASE(base, epnum)+TOFF_USBEO_DOEPTSIZ), USB_OTG_DOEPTSIZ_XFRSIZ);
+		sil_andw_mem((uint32_t *)(USBOEP_BASE(base, epnum)+TOFF_USBEO_DOEPTSIZ), USB_OTG_DOEPTSIZ_PKTCNT);
+
+		if(ep->xfer_len == 0){	/* ZERO-LENGTHパケット */
+			sil_orw_mem((uint32_t *)(USBOEP_BASE(base, epnum)+TOFF_USBEO_DOEPTSIZ), (USB_OTG_DOEPTSIZ_XFRSIZ & ep->maxpacket));
+			sil_orw_mem((uint32_t *)(USBOEP_BASE(base, epnum)+TOFF_USBEO_DOEPTSIZ), (USB_OTG_DOEPTSIZ_PKTCNT & (1 << 19)));
+		}
+		else{	/* 通常パケット */
+			pktcnt = (ep->xfer_len + ep->maxpacket - 1)/ ep->maxpacket; 
+			sil_orw_mem((uint32_t *)(USBOEP_BASE(base, epnum)+TOFF_USBEO_DOEPTSIZ), (USB_OTG_DOEPTSIZ_PKTCNT & (pktcnt << 19)));
+			sil_orw_mem((uint32_t *)(USBOEP_BASE(base, epnum)+TOFF_USBEO_DOEPTSIZ), (USB_OTG_DOEPTSIZ_XFRSIZ & (ep->maxpacket * pktcnt)));
+		}
+
+		if(husb->Init.dma_enable == 1){
+			flushinvalidatedcache_by_addr(ep->xfer_buff, ep->xfer_len);
+			sil_wrw_mem((uint32_t *)(USBOEP_BASE(base, epnum)+TOFF_USBEO_DOEPDMA), (uint32_t)(ep->xfer_buff));
+		}
+
+		if(ep->type == EP_TYPE_ISOC){
+			if((sil_rew_mem((uint32_t *)(USBD_BASE(base)+TOFF_USBD_DSTS)) & (1 << 8)) == 0){
+				sil_orw_mem((uint32_t *)(USBOEP_BASE(base, epnum)+TOFF_USBEO_DOEPCTL), USB_OTG_DOEPCTL_SODDFRM);
+			}
+			else{
+				sil_orw_mem((uint32_t *)(USBOEP_BASE(base, epnum)+TOFF_USBEO_DOEPCTL), USB_OTG_DOEPCTL_SD0PID_SEVNFRM);
+			}
+		}
+		/*
+		 *  クリアNAK、エンドポイントイネーブル
+		 */
+		sil_orw_mem((uint32_t *)(USBOEP_BASE(base, epnum)+TOFF_USBEO_DOEPCTL), (USB_OTG_DOEPCTL_CNAK | USB_OTG_DOEPCTL_EPENA));
+	}
+	return E_OK;
+}
+
+/*
+ *  USBデバイス初期化
+ *  parameter1 husb  USBハンドラへのポインタ
+ *  return     常にE_OK
+ */
+ER
+usbo_devinit(USB_OTG_Handle_t *husb)
+{
+	uint32_t base = husb->base;
+	bool_t   forced;
+	uint32_t i = 0U;
+
+	/* Device mode configuration */
+	sil_orw_mem((uint32_t *)(USBD_BASE(base)+TOFF_USBD_DCFG), DCFG_FRAME_INTERVAL_80);
+
+	if(husb->Init.phy_itface == USB_PHY_ULPI){	/* ULIP-PHY設定 */
+		if(husb->Init.speed == USB_SPEED_HIGH){
+			/*
+			 *  ハイスピード固定
+			 */
+			usbo_setDevSpeed(base, USB_SPEED_HIGH);
+		}
+		else{
+			/*
+			 * ハイ・フル選択モード
+			 */
+			usbo_setDevSpeed(base, USB_SPEED_HIGH_IN_FULL);
+		}
+	}
+	else{	/* EMBEDDED-PHY設定 */
+		/*
+		 *  常にフルスピード
+		 */
+		usbo_setDevSpeed(base, USB_SPEED_FULL);
+	}
+
+	/*
+	 *  デバイスに関係する、すべての割込みをクリアする
+	 */
+	sil_wrw_mem((uint32_t *)(USBD_BASE(base)+TOFF_USBD_DIEPMSK),
+			(USB_OTG_DIEPMSK_TOM | USB_OTG_DIEPMSK_EPDM | USB_OTG_DIEPMSK_XFRCM));
+	sil_wrw_mem((uint32_t *)(USBD_BASE(base)+TOFF_USBD_DOEPMSK),
+			(USB_OTG_DOEPMSK_STUPM | USB_OTG_DOEPMSK_EPDM | USB_OTG_DOEPMSK_XFRCM));
+	sil_wrw_mem((uint32_t *)(USBD_BASE(base)+TOFF_USBD_DAINT), 0xFFFFFFFF);
+	sil_wrw_mem((uint32_t *)(USBD_BASE(base)+TOFF_USBD_DAINTMSK), 0);
+	for(i = 0 ; i < husb->Init.dev_endpoints ; i++){
+		if((sil_rew_mem((uint32_t *)(USBIEP_BASE(base, i)+TOFF_USBEI_DIEPCTL)) & USB_OTG_DIEPCTL_EPENA) != 0){
+			sil_wrw_mem((uint32_t *)(USBIEP_BASE(base, i)+TOFF_USBEI_DIEPCTL), (USB_OTG_DIEPCTL_EPDIS | USB_OTG_DIEPCTL_SNAK));
+		}
+		else{
+			sil_wrw_mem((uint32_t *)(USBIEP_BASE(base, i)+TOFF_USBEI_DIEPCTL), 0);
+		}
+		sil_wrw_mem((uint32_t *)(USBIEP_BASE(base, i)+TOFF_USBEI_DIEPTSIZ), 0);
+		sil_wrw_mem((uint32_t *)(USBIEP_BASE(base, i)+TOFF_USBEI_DIEPINT), 0xFF);
+	}
+
+	for (i = 0U; i < husb->Init.dev_endpoints; i++){
+		if((sil_rew_mem((uint32_t *)(USBOEP_BASE(base, i)+TOFF_USBEO_DOEPCTL)) & USB_OTG_DOEPCTL_EPENA) != 0){
+			sil_wrw_mem((uint32_t *)(USBOEP_BASE(base, i)+TOFF_USBEO_DOEPCTL), (USB_OTG_DOEPCTL_EPDIS | USB_OTG_DOEPCTL_SNAK));
+		}
+		else{
+			sil_wrw_mem((uint32_t *)(USBOEP_BASE(base, i)+TOFF_USBEO_DOEPCTL), 0);
+		}
+		sil_wrw_mem((uint32_t *)(USBOEP_BASE(base, i)+TOFF_USBEO_DOEPTSIZ), 0);
+		sil_wrw_mem((uint32_t *)(USBOEP_BASE(base, i)+TOFF_USBEO_DOEPINT), 0xFF);
+	}
+
+	usbo_devdisconnect(husb);
+	forced = usbo_force_mode_if_needed(husb, false);
+	usbo_initFiFo(husb);
+	if(forced)
+		usbo_clear_force_mode(husb);
+
+	if(husb->Init.dma_enable == 1){
+		/*
+		 *  DMAモードならスレッシュホールドパラメータを設定
+		 */
+		sil_wrw_mem((uint32_t *)(USBD_BASE(base)+TOFF_USBD_DTHRCTL), (USB_OTG_DTHRCTL_TXTHRLEN_6 | USB_OTG_DTHRCTL_RXTHRLEN_6));
+		sil_orw_mem((uint32_t *)(USBD_BASE(base)+TOFF_USBD_DTHRCTL), (USB_OTG_DTHRCTL_RXTHREN | USB_OTG_DTHRCTL_ISOTHREN | USB_OTG_DTHRCTL_NONISOTHREN));
+		i = sil_rew_mem((uint32_t *)(USBD_BASE(base)+TOFF_USBD_DTHRCTL));
+	}
+	if(husb->Init.usb_otg_mode == USB_OTG_MODE_DEVICE)
+		usbo_setupint(husb);
+	return E_OK;
+}
+
+/*
+ *  USBデバイス停止
+ *  parameter1 husb  USBハンドラへのポインタ
+ *  return     常にE_OK
+ */
+ER
+usbo_stopdevice(USB_OTG_Handle_t *husb)
+{
+	uint32_t base = husb->base;
+	uint32_t i;
+
+	/*
+	 *  エンドポイントの割込みクリア
+	 */
+	for(i = 0 ; i < 15 ; i++){
+		sil_wrw_mem((uint32_t *)(USBIEP_BASE(base, i)+TOFF_USBEI_DIEPINT), 0xFF);
+		sil_wrw_mem((uint32_t *)(USBOEP_BASE(base, i)+TOFF_USBEO_DOEPINT), 0xFF);
+	}
+	sil_wrw_mem((uint32_t *)(USBD_BASE(base)+TOFF_USBD_DAINT), 0xFFFFFFFF);
+
+	/*
+	 *  エンドポイントの割込み設定
+	 */
+	sil_wrw_mem((uint32_t *)(USBD_BASE(base)+TOFF_USBD_DIEPMSK), 0);
+	sil_wrw_mem((uint32_t *)(USBD_BASE(base)+TOFF_USBD_DOEPMSK), 0);
+	sil_wrw_mem((uint32_t *)(USBD_BASE(base)+TOFF_USBD_DAINTMSK), 0);
+
+	/*
+	 *  FIFOフラッシュ
+	 */
+	usbo_flushRxFifo(husb);
+	usbo_flushTxFifo(husb,  0x10);
+	return E_OK;
+}
+
+/*
+ *  LPM初期設定
+ */
+ER
+usbo_init_lpm(USB_OTG_Handle_t *husb)
+{
+#ifdef USB_OTG_GLPMCFG_LPMEN
+	uint32_t base = husb->base;
+
+	if(husb->Init.lpm_enable == 1){
+		husb->lpm_active = 1;
+		husb->lpm_state = PCD_LPM_L0_ACTIVE;
+		sil_orw_mem((uint32_t *)(USBOTG_BASE(base)+TOFF_USBO_GINTMSK), USB_OTG_GINTMSK_LPMINTM);
+		sil_orw_mem((uint32_t *)(USBOTG_BASE(base)+TOFF_USBO_GLPMCFG), (USB_OTG_GLPMCFG_LPMEN | USB_OTG_GLPMCFG_LPMACK | USB_OTG_GLPMCFG_ENBESL));
+	}
+#endif /* USB_OTG_GLPMCFG_LPMEN */
+	return E_OK;
+}
+
+/*
+ *  USB EP-IN割込み要因取得
+ *  parameter1 base USB OTGレジスタベースアドレス
+ *  parameter2 epnum エンドポイント番号
+ *  return     EP-IN割込み要因
+ */
+static uint32_t
+usbo_devInEPInterrupt(uint32_t base , uint8_t epnum)
+{
+	uint32_t msk, emp;
+
+	msk = sil_rew_mem((uint32_t *)(USBD_BASE(base)+TOFF_USBD_DIEPMSK));
+	emp = sil_rew_mem((uint32_t *)(USBD_BASE(base)+TOFF_USBD_DIEPEMPMSK));
+	msk |= ((emp >> epnum) & 0x1) << 7;
+	return sil_rew_mem((uint32_t *)(USBIEP_BASE(base, epnum)+TOFF_USBEI_DIEPINT)) & msk;
+}
+
+/*
+ *  USB EP-OUT割込み要因取得
+ *  parameter1 base USB OTGレジスタベースアドレス
+ *  parameter2 epnum エンドポイント番号
+ *  return     EP-OUT割込み要因
+ */
+static uint32_t
+usbo_devOutEPInterrupt(uint32_t base, uint8_t epnum)
+{
+	uint32_t v;
+	v = sil_rew_mem((uint32_t *)(USBOEP_BASE(base, epnum)+TOFF_USBEO_DOEPINT));
+	return v & sil_rew_mem((uint32_t *)(USBD_BASE(base)+TOFF_USBD_DOEPMSK));
+}
+
+
+/*
+ *  次のパケットを送信FIFOに設定
+ *  parameter1 husb  USBハンドラへのポインタ
+ *  parameter2 epnum エンドポイント番号
+ *  return     常にE_OK
+ */
+static ER
+usbo_writeemptyTxfifo(USB_OTG_Handle_t *husb, uint32_t epnum)
+{
+	uint32_t  base = husb->base;
+	USB_OTG_EPTypeDef *ep;
+	int32_t len = 0U;
+	uint32_t len32b;
+
+	ep = &husb->IN_ep[epnum];
+	len = ep->xfer_len - ep->xfer_count;
+
+	if(len > ep->maxpacket){
+		len = ep->maxpacket;
+	}
+	len32b = (len + 3) / 4;
+
+	while((sil_rew_mem((uint32_t *)(USBIEP_BASE(base, epnum)+TOFF_USBEI_DTXFSTS)) & USB_OTG_DTXFSTS_INEPTFSAV) > len32b
+          && ep->xfer_count < ep->xfer_len && ep->xfer_len != 0){
+		/*
+		 * 送信FIFOへのデータ書き込み
+		 */
+		len = ep->xfer_len - ep->xfer_count;
+		if(len > ep->maxpacket){
+			len = ep->maxpacket;
+		}
+		len32b = (len + 3) / 4;
+		usbo_writePacket(base, ep->xfer_buff, epnum, len, husb->Init.dma_enable); 
+		ep->xfer_buff  += len;
+		ep->xfer_count += len;
+	}
+
+	if(len <= 0){	/* 最後のパケットならばEMPTY割込みをマスク */
+		sil_andw_mem((uint32_t *)(USBD_BASE(base)+TOFF_USBD_DIEPEMPMSK), (1 << epnum));
+	}
+	return E_OK;
+}
+
+/*
+ *  DEVICE割込みハンドラ
+ *  parameter1 husb  USBハンドラへのポインタ
+ */
+void
+usbo_pcd_irqhandler(USB_OTG_Handle_t *husb)
+{
+	USB_OTG_EPTypeDef *ep;
+	uint32_t base = husb->base;
+	uint32_t msk  = sil_rew_mem((uint32_t *)(USBOTG_BASE(base)+TOFF_USBO_GINTMSK));
+	uint32_t i = 0U, ep_intr = 0U, epint = 0U, epnum = 0U;
+	uint32_t temp = 0;
+
+	/*
+	 *  割込みエラーチェック
+	 */
+	if((get_int_status(base, msk) == 0)){
+		uint32_t intsts = sil_rew_mem((uint32_t *)(USBOTG_BASE(base)+TOFF_USBO_GINTSTS));
+		syslog_1(LOG_EMERG, "usbo_pcd_irqhandler Error Intrrupt[%08x] !", intsts);
+		clear_dev_int(base, intsts);
+		return;
+	}
+
+    if((get_int_status(base, msk) & USB_OTG_GINTSTS_MMIS) != 0){
+		/*
+		 *  エラー割込み要因クリア
+		 */
+		clear_dev_int(base, USB_OTG_GINTSTS_MMIS);
+	}
+	if((get_int_status(base, msk) & USB_OTG_GINTSTS_OEPINT) != 0){
+		/*
+		 *  EP-OUT割込み
+		 */
+		ep_intr = get_outep_int_status(base);
+		for(epnum = 0 ; epnum < 16 ; epnum++){
+			if((ep_intr & (1<<epnum)) != 0){
+				epint = usbo_devOutEPInterrupt(base, epnum);
+				if((epint & USB_OTG_DOEPINT_XFRC) == USB_OTG_DOEPINT_XFRC){
+					clear_outep_int(base, epnum, USB_OTG_DOEPINT_XFRC);
+					if(husb->Init.dma_enable == 1U){
+						husb->OUT_ep[epnum].xfer_count = husb->OUT_ep[epnum].maxpacket- (sil_rew_mem((uint32_t *)(USBOEP_BASE(base, epnum)+TOFF_USBEO_DOEPTSIZ)) & USB_OTG_DOEPTSIZ_XFRSIZ); 
+						husb->OUT_ep[epnum].xfer_buff += husb->OUT_ep[epnum].maxpacket;
+					}
+					if(husb->devdataoutstagecallback != NULL)
+						husb->devdataoutstagecallback(husb, epnum);
+					if(husb->Init.dma_enable == 1 && epnum == 0 && husb->OUT_ep[epnum].xfer_len == 0){
+						/*
+						 *  DMAモードEP0 ZERO LENGTHパケット送信
+						 */
+						usbo_ep0_outstart(husb, (uint8_t *)husb->Setup);
+					}
+				}
+				if((epint & USB_OTG_DOEPINT_STUP) != 0){
+					/*
+					 *  SETUPパケット通知
+					 */
+					if(husb->devsetupstagecallback != NULL)
+						husb->devsetupstagecallback(husb);
+					clear_outep_int(base, epnum, USB_OTG_DOEPINT_STUP);
+				}
+				if((epint & USB_OTG_DOEPINT_OTEPDIS) != 0){
+					clear_outep_int(base, epnum, USB_OTG_DOEPINT_OTEPDIS);
+				}
+#ifdef USB_OTG_DOEPINT_OTEPSPR 
+				/*
+				 *  ステータスフェーズ受信割込み
+				 */
+				if((epint & USB_OTG_DOEPINT_OTEPSPR) != 0){
+					clear_outep_int(base, epnum, USB_OTG_DOEPINT_OTEPSPR);
+				}
+#endif /* USB_OTG_DOEPINT_OTEPSPR */
+			}
+		}
+	}
+	if((get_int_status(base, msk) & USB_OTG_GINTSTS_IEPINT) != 0){
+		/*
+		 *  EP-IN割込み
+		 */
+		ep_intr = get_inep_int_status(base);
+		for(epnum = 0 ; epnum < 16 ; epnum++){
+			if((ep_intr & (1<<epnum)) != 0){ /* In ITR */
+				epint = usbo_devInEPInterrupt(base, epnum);
+				if((epint & USB_OTG_DIEPINT_XFRC) != 0){
+					sil_andw_mem((uint32_t *)(USBD_BASE(base)+TOFF_USBD_DIEPEMPMSK), (1<<epnum));
+					clear_inep_int(base, epnum, USB_OTG_DIEPINT_XFRC);
+					if(husb->Init.dma_enable == 1){
+						husb->IN_ep[epnum].xfer_buff += husb->IN_ep[epnum].maxpacket; 
+					}
+					if(husb->devdatainstagecallback != NULL)
+						husb->devdatainstagecallback(husb, epnum);
+					if(husb->Init.dma_enable == 1 && epnum == 0 && husb->IN_ep[epnum].xfer_len == 0){
+						/*
+						 *  DMAモードEP0 ZERO LENGTHパケット送信
+						 */
+						usbo_ep0_outstart(husb, (uint8_t *)husb->Setup);
+					}
+				}
+				if((epint & USB_OTG_DIEPINT_TOC) != 0){
+					clear_inep_int(base, epnum, USB_OTG_DIEPINT_TOC);
+				}
+				if((epint & USB_OTG_DIEPINT_ITTXFE) != 0){
+					clear_inep_int(base, epnum, USB_OTG_DIEPINT_ITTXFE);
+				}
+				if((epint & USB_OTG_DIEPINT_INEPNE) != 0){
+					clear_inep_int(base, epnum, USB_OTG_DIEPINT_INEPNE);
+				}
+				if((epint & USB_OTG_DIEPINT_EPDISD) != 0){
+					clear_inep_int(base, epnum, USB_OTG_DIEPINT_EPDISD);
+				}
+				if((epint & USB_OTG_DIEPINT_TXFE) != 0){
+					usbo_writeemptyTxfifo(husb , epnum);
+				}
+			}
+		}
+	}
+	/*
+	 *  RESUME割込み
+	 */
+	if((get_int_status(base, msk) & USB_OTG_GINTSTS_WKUINT) != 0){
+		usbo_exit_hibernation(husb, true);		/* 省エネ復帰 */
+#ifdef USB_OTG_GLPMCFG_LPMEN
+		if(husb->lpm_state == PCD_LPM_L1_ACTIVE){
+			husb->lpm_state = PCD_LPM_L0_ACTIVE;
+			if(husb->devlpmcallback != NULL)
+				husb->devlpmcallback(husb, PCD_LPM_L0_ACTIVE);
+		}
+		else
+#endif /* USB_OTG_GLPMCFG_LPMEN */
+		{
+			if(husb->devresumecallback != NULL)
+				husb->devresumecallback(husb);
+		}
+		husb->lx_state = DWC2_L0;
+		clear_dev_int(base, USB_OTG_GINTSTS_WKUINT);
+	}
+    /*
+	 *  SUSPEND割込み
+	 */
+    if((get_int_status(base, msk) & USB_OTG_GINTSTS_USBSUSP) != 0){
+		if((sil_rew_mem((uint32_t *)(USBD_BASE(base)+TOFF_USBD_DSTS)) & USB_OTG_DSTS_SUSPSTS) != 0){
+			usbo_enter_hibernation(husb);		/* 省エネ移行 */
+			if(husb->devsuspendcallback != NULL && husb->connected)
+				husb->devsuspendcallback(husb);
+			if(husb->Init.usb_otg_mode == USB_OTG_MODE_DRD && husb->hostdisconnectcallback != NULL && husb->connected){
+				syslog_1(LOG_NOTICE, "usbo_pcd_irqhandler drd mode disconnect lx_state(%d) !", husb->lx_state);
+				husb->connected = 0;
+				husb->hostdisconnectcallback(husb);
+			}
+			husb->lx_state = DWC2_L2;
+		}
+		clear_dev_int(base, USB_OTG_GINTSTS_USBSUSP);
+	}
+#ifdef USB_OTG_GLPMCFG_LPMEN
+    /*
+	 *  LPM割込み
+	 */
+	if((get_int_status(base, msk) & USB_OTG_GINTSTS_LPMINT) != 0){
+		clear_dev_int(base, USB_OTG_GINTSTS_LPMINT);
+		if(husb->lpm_state == PCD_LPM_L0_ACTIVE){
+			husb->lpm_state = PCD_LPM_L1_ACTIVE;
+			husb->BESL = (sil_rew_mem((uint32_t *)(USBOTG_BASE(base)+TOFF_USBO_GLPMCFG)) & USB_OTG_GLPMCFG_BESL) >>2 ;
+			if(husb->devlpmcallback != NULL)
+				husb->devlpmcallback(husb, PCD_LPM_L1_ACTIVE);
+			husb->lx_state = DWC2_L1;
+		}
+		else{
+			if(husb->devsuspendcallback != NULL)
+				husb->devsuspendcallback(husb);
+			husb->lx_state = DWC2_L2;
+		}
+	}
+#endif /* USB_OTG_GLPMCFG_LPMEN */
+	/*
+	 * USB-RESET割込み
+	 */
+	if((get_int_status(base, msk) & USB_OTG_GINTSTS_USBRST) != 0){
+		sil_andw_mem((uint32_t *)(USBD_BASE(base)+TOFF_USBD_DCTL), USB_OTG_DCTL_RWUSIG);
+		usbo_flushTxFifo(husb, 0U);
+		for(i = 0; i < husb->Init.dev_endpoints ; i++){
+			sil_wrw_mem((uint32_t *)(USBIEP_BASE(base, i)+TOFF_USBEI_DIEPINT), 0xFF);
+			sil_wrw_mem((uint32_t *)(USBOEP_BASE(base, 0)+TOFF_USBEO_DOEPINT), 0xFF);
+		}
+		sil_wrw_mem((uint32_t *)(USBD_BASE(base)+TOFF_USBD_DAINT), 0xFFFFFFFF);
+		sil_orw_mem((uint32_t *)(USBD_BASE(base)+TOFF_USBD_DAINTMSK), 0x10001);
+		if(husb->Init.use_dedicated_ep1){
+			sil_orw_mem((uint32_t *)(USBD_BASE(base)+TOFF_USBD_DOUTEP1MSK), (USB_OTG_DOEPMSK_STUPM | USB_OTG_DOEPMSK_XFRCM | USB_OTG_DOEPMSK_EPDM));
+			sil_orw_mem((uint32_t *)(USBD_BASE(base)+TOFF_USBD_DINEP1MSK), (USB_OTG_DIEPMSK_TOM | USB_OTG_DIEPMSK_XFRCM | USB_OTG_DIEPMSK_EPDM));
+		}
+		else{
+#ifdef USB_OTG_DOEPINT_OTEPSPR
+			sil_orw_mem((uint32_t *)(USBD_BASE(base)+TOFF_USBD_DOEPMSK), (USB_OTG_DOEPMSK_STUPM | USB_OTG_DOEPMSK_XFRCM | USB_OTG_DOEPMSK_EPDM | USB_OTG_DOEPMSK_OTEPSPRM));
+#else
+			sil_orw_mem((uint32_t *)(USBD_BASE(base)+TOFF_USBD_DOEPMSK), (USB_OTG_DOEPMSK_STUPM | USB_OTG_DOEPMSK_XFRCM | USB_OTG_DOEPMSK_EPDM));
+#endif /* USB_OTG_DOEPINT_OTEPSPR */
+			sil_orw_mem((uint32_t *)(USBD_BASE(base)+TOFF_USBD_DIEPMSK), (USB_OTG_DIEPMSK_TOM | USB_OTG_DIEPMSK_XFRCM | USB_OTG_DIEPMSK_EPDM));
+		}
+		/*
+		 *  デフォルトアドレスをゼロに設定
+		 */
+		sil_andw_mem((uint32_t *)(USBD_BASE(base)+TOFF_USBD_DCFG), USB_OTG_DCFG_DAD);
+		/*
+		 *  SETUPパケット受信設定
+		 */
+		usbo_ep0_outstart(husb, (uint8_t *)husb->Setup);
+		clear_dev_int(base, USB_OTG_GINTSTS_USBRST);
+	}
+	/*
+	 *  ENUMERATIONハンドル終了割込み
+	 */
+	if((get_int_status(base, msk) & USB_OTG_GINTSTS_ENUMDNE) != 0){
+		/*
+		 *  USBアクティベートセットアップ
+		 */
+		sil_andw_mem((uint32_t *)(USBIEP_BASE(base, 0)+TOFF_USBEI_DIEPCTL), USB_OTG_DIEPCTL_MPSIZ);
+		if((sil_rew_mem((uint32_t *)(USBD_BASE(base)+TOFF_USBD_DSTS)) & USB_OTG_DSTS_ENUMSPD) == DSTS_ENUMSPD_LS_PHY_6MHZ){
+			sil_orw_mem((uint32_t *)(USBIEP_BASE(base, 0)+TOFF_USBEI_DIEPCTL), 3);
+		}
+		sil_orw_mem((uint32_t *)(USBD_BASE(base)+TOFF_USBD_DCTL), USB_OTG_DCTL_CGINAK);
+
+		sil_andw_mem((uint32_t *)(USBOTG_BASE(base)+TOFF_USBO_GUSBCFG), USB_OTG_GUSBCFG_TRDT);
+		if(usbo_getDevSpeed(husb) == USB_SPEED_HIGH){
+			husb->Init.speed     = USB_SPEED_HIGH;
+			sil_orw_mem((uint32_t *)(USBOTG_BASE(base)+TOFF_USBO_GUSBCFG), ((USBD_HS_TRDT_VALUE << 10) & USB_OTG_GUSBCFG_TRDT));
+		}
+		else{
+			husb->Init.speed     = USB_SPEED_FULL;
+
+        /*
+		 * USBTRDTの設定は、AHB周期設定(SysFreHCLK)に従う
+		 */
+#if (SysFreHCLK < 15000000)		/* under 15MHz */
+			temp = 0x0F;
+#elif (SysFreHCLK >= 15000000) && (SysFreHCLK < 16000000)	/* 15Mhz-16MHz */
+			temp = 0x0E;
+#elif (SysFreHCLK >= 16000000) && (SysFreHCLK < 17200000)	/* 16MHz-17.2MHz */
+			temp = 0x0D;
+#elif (SysFreHCLK >= 17200000) && (SysFreHCLK < 18500000)	/* 17.2MHz-18.5MHz */
+			temp = 0x0C;
+#elif (SysFreHCLK >= 18500000) && (SysFreHCLK < 20000000)	/* 18.5MHz-20MHz */
+			temp = 0x0B;
+#elif (SysFreHCLK >= 20000000) && (SysFreHCLK < 21800000)	/* 20MHz-21.8MHz */
+			temp = 0x0A;
+#elif (SysFreHCLK >= 21800000) && (SysFreHCLK < 24000000)	/* 21.8MHz-24MHz */
+			temp = 0x09;
+#elif (SysFreHCLK >= 24000000) && (SysFreHCLK < 27700000)	/* 24MHz-27.7MHz */
+			temp = 0x08;
+#elif (SysFreHCLK >= 27700000) && (SysFreHCLK < 32000000)	/* 27.7MHz-32MHz */
+			temp = 0x07;
+#else							/* over 32MHz */
+			temp = 0x06;
+#endif
+			sil_orw_mem((uint32_t *)(USBOTG_BASE(base)+TOFF_USBO_GUSBCFG), ((temp << 10) & USB_OTG_GUSBCFG_TRDT));
+		}
+		if(husb->devresetcallback != NULL)
+			husb->devresetcallback(husb);
+		clear_dev_int(base, USB_OTG_GINTSTS_ENUMDNE);
+	}
+    /*
+	 *  RXQLEVEL割込み
+	 */
+	if((get_int_status(base, msk) & USB_OTG_GINTSTS_RXFLVL) != 0){
+		sil_andw_mem((uint32_t *)(USBOTG_BASE(base)+TOFF_USBO_GINTMSK), USB_OTG_GINTSTS_RXFLVL);
+		temp = sil_rew_mem((uint32_t *)(USBOTG_BASE(base)+TOFF_USBO_GRXSTSP));
+		ep = &husb->OUT_ep[temp & USB_OTG_GRXSTSP_EPNUM];
+		if(((temp & USB_OTG_GRXSTSP_PKTSTS) >> 17U) ==  STS_DATA_UPDT){
+			if((temp & USB_OTG_GRXSTSP_BCNT) != 0){
+				usbo_readPacket(base, ep->xfer_buff, (temp & USB_OTG_GRXSTSP_BCNT) >> 4U);
+				ep->xfer_buff += (temp & USB_OTG_GRXSTSP_BCNT) >> 4U;
+				ep->xfer_count += (temp & USB_OTG_GRXSTSP_BCNT) >> 4U;
+			}
+		}
+		else if(((temp & USB_OTG_GRXSTSP_PKTSTS) >> 17U) ==  STS_SETUP_UPDT){
+			usbo_readPacket(base, (uint8_t *)husb->Setup, 8U);
+			ep->xfer_count += (temp & USB_OTG_GRXSTSP_BCNT) >> 4U;
+		}
+		sil_orw_mem((uint32_t *)(USBOTG_BASE(base)+TOFF_USBO_GINTMSK), USB_OTG_GINTSTS_RXFLVL);
+	}
+    /*
+	 *  DEVICE-SOF割込み
+	 */
+	if((get_int_status(base, msk) & USB_OTG_GINTSTS_SOF) != 0){
+		if(husb->devsofcallback != NULL)
+			husb->devsofcallback(husb);
+		clear_dev_int(base, USB_OTG_GINTSTS_SOF);
+	}
+    /*
+	 *  ISO IN未完結割込み
+	 */
+    if((get_int_status(base, msk) & USB_OTG_GINTSTS_IISOIXFR) != 0){
+		if(husb->devisoincallback != NULL)
+			husb->devisoincallback(husb, epnum);
+		clear_dev_int(base, USB_OTG_GINTSTS_IISOIXFR);
+    }
+	/*
+	 *  ISO OUT未完結割込み
+	 */
+	if((get_int_status(base, msk) & USB_OTG_GINTSTS_PXFR_INCOMPISOOUT) != 0){
+		if(husb->devisooutcallback != NULL)
+			husb->devisooutcallback(husb, epnum);
+		clear_dev_int(base, USB_OTG_GINTSTS_PXFR_INCOMPISOOUT);
+	}
+    /*
+	 *  コネクションイベント割込み
+	 */
+    if((get_int_status(base, msk) & USB_OTG_GINTSTS_SRQINT) != 0){
+		if(husb->devconnectcallback != NULL)
+			husb->devconnectcallback(husb);
+		clear_dev_int(base, USB_OTG_GINTSTS_SRQINT);
+	}
+    /*
+	 *  ディスコネクションイベント割込み
+	 */
+    if((get_int_status(base, msk) & USB_OTG_GINTSTS_OTGINT) != 0){
+		temp = sil_rew_mem((uint32_t *)(USBOTG_BASE(base)+TOFF_USBO_GOTGINT));
+		if((temp & USB_OTG_GOTGINT_SEDET) == USB_OTG_GOTGINT_SEDET){
+			husb->connected = 0;
+			if(husb->devdisconnectcallback != NULL)
+				husb->devdisconnectcallback(husb);
+		}
+		sil_orw_mem((uint32_t *)(USBOTG_BASE(base)+TOFF_USBO_GOTGINT), temp);
+	}
+}
+
+/*
+ *  USB-OTG割込みサービスルーチン
+ */
+void
+usb_otg_isr(intptr_t exinf)
+{
+	USB_OTG_Handle_t *husb = &Husb[INDEX_USB((uint32_t)exinf)];
+	if(get_usbmode(husb->base) == USB_OTG_MODE_DEVICE){
+		usbo_pcd_irqhandler(husb);
+	}
+	else{
+		usbo_hcd_irqhandler(husb);
+	}
+}
+
+/*
+ *  USB-OTG WAKEUP割込みサービスルーチン
+ */
+void usb_otg_wkup_isr(intptr_t exinf)
+{
+	USB_OTG_Handle_t *husb = &Husb[INDEX_USB((uint32_t)exinf)];
+
+	if(husb->Init.low_power_enable){
+		/*
+		 *  Cortex SLEEPDEEPビットリセット
+		 */
+		sil_andw_mem((uint32_t *)(TADR_SCB_BASE+TOFF_SCB_SCR), (SCB_SCR_SLEEPDEEP_Msk | SCB_SCR_SLEEPONEXIT_Msk));
+#if !defined(TOPPERS_STM32F4_DISCOVERY)
+		/*
+		 *  起動クロック再設定
+		 */
+		sysclock_config(0);
+#endif
+	}
+
+	/* ungate PHY clock */
+	sil_andw_mem((uint32_t *)(USBPGC_BASE(husb->base)), USB_OTG_PCGCCTL_STOPCLK);
+
+#ifdef EXTI_PR_BASE
+	/*
+	 *  EXTI WAKEUPペンディングビットクリア
+	 */
+	sil_wrw_mem((uint32_t *)EXTI_PR_BASE, USB_OTG_FS_WAKEUP_EXTI_LINE);
+#endif
+}
+
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/pdic/stm32f7xx/usb_otg.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/pdic/stm32f7xx/usb_otg.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/pdic/stm32f7xx/usb_otg.h	(revision 457)
@@ -0,0 +1,329 @@
+/*
+ *  TOPPERS/ASP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Advanced Standard Profile Kernel
+ *
+ *  Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
+ *                              Toyohashi Univ. of Technology, JAPAN
+ *  Copyright (C) 2015-2016 by TOPPERS PROJECT Educational Working Group.
+ *
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ *
+ *  $Id$
+ */
+
+/*
+ *	USB OTGデバイスドライバのヘッダファイル
+ */
+
+#ifndef _USB_OTG_H_
+#define _USB_OTG_H_
+
+
+/*
+ *  USBポート定義
+ */
+#define USB1_PORTID             1
+#define USB2_PORTID             2
+#define NUM_USBPORT             2
+
+/*
+ *  USB OTGモード
+ */
+#define USB_OTG_MODE_DEVICE     0
+#define USB_OTG_MODE_HOST       1
+#define USB_OTG_MODE_DRD        2
+
+/*
+ *  USB PHY定義
+ */
+#define USB_PHY_ULPI            1
+#define USB_PHY_EMBEDDED        2
+
+/*
+ *  エンドポイントタイプ
+ */
+#define EP_TYPE_CTRL            0
+#define EP_TYPE_ISOC            1
+#define EP_TYPE_BULK            2
+#define EP_TYPE_INTR            3
+#define EP_TYPE_MSK             3
+
+/*
+ *  USBスピード
+ */
+#define USB_SPEED_HIGH          0
+#define USB_SPEED_HIGH_IN_FULL  1
+#define USB_SPEED_LOW           2
+#define USB_SPEED_FULL          3
+
+
+#define HC_PID_DATA0            0
+#define HC_PID_DATA2            1
+#define HC_PID_DATA1            2
+#define HC_PID_SETUP            3
+
+/*
+ *  URB状態定義
+ */ 
+#define URB_IDLE                0
+#define URB_DONE                1
+#define URB_NOTREADY            2
+#define URB_NYET                3
+#define URB_ERROR               4
+#define URB_STALL               5
+
+/*
+ *  HOSTチャンネル状態定義
+ */
+#define USBO_HC_IDLE            0
+#define USBO_HC_XFRC            1
+#define USBO_HC_HALTED          2
+#define USBO_HC_NAK             3
+#define USBO_HC_NYET            4
+#define USBO_HC_STALL           5
+#define USBO_HC_XACTERR         6
+#define USBO_HC_BBLERR          7
+#define USBO_HC_DATATGLERR      8
+#define USBO_HC_FAIL            16
+
+/*
+ *  LPMアクティブパラメータ
+ */
+#define PCD_LPM_L0_ACTIVE       0x00		/* on */
+#define PCD_LPM_L1_ACTIVE       0x01		/* LPM L1 sleep */
+#define PCD_LPM_L2              0x02		/* suspend */
+#define PCD_LPM_L3              0x03		/* off */
+
+/*
+ *  エンドポイント・ホストチャネルの最大数
+ */
+#define MAX_EPS_CHANNELS        16
+
+/*
+ *  デバイスステート
+ */
+#define DWC2_L0                 0	/* On state */
+#define DWC2_L1                 1	/* LPM sleep state */
+#define DWC2_L2                 2	/* USB suspend state */
+#define DWC2_L3                 3	/* Off state */
+
+
+/*
+ *  USB OTGハードウェア情報
+ */
+typedef struct
+{
+	unsigned en_multiple_tx_fifo:1;
+	unsigned host_rx_fifo_size:16;
+	unsigned max_transfer_size:26;
+	unsigned max_packet_count:11;
+	unsigned total_fifo_size:16;
+}USB_OTG_HwParam_t;
+
+/*
+ *  USB OTG初期設定定義
+ */
+typedef struct
+{
+    uint32_t                usb_otg_mode;			/* USB OTGモード */
+    uint32_t                dev_endpoints;			/* デバイスエンドポイント数(1-15) */
+    uint32_t                host_channels;			/* ホストチャネル数(1-15) */
+    uint32_t                speed;					/* USBコアスピード */
+    uint32_t                dma_enable;				/* USB-DMA機能の有効無効設定(0 or 1) */
+    uint32_t                phy_itface;				/* PHYインターフェイス選択 */
+    uint32_t                sof_enable;				/* SOF割込みの有効無効設定(0 or 1) */
+    uint32_t                low_power_enable;		/* LOW POWERモード有効無効設定(0 or 1) */
+    uint32_t                lpm_enable;				/* Link Power Management有効無効設定(0 or 1) */
+    uint32_t                vbus_sensing_enable;	/* VBUSセンス有効無効設定(0 or 1) */
+    uint32_t                use_dedicated_ep1;		/* エンドポイント1専用割込み有効無効設定(0 or 1) */
+    uint32_t                use_external_vbus;		/* 外部VBUS有効無効設定(0 or 1) */
+}USB_OTG_Init_t;
+
+/*
+ *  エンドポイント定義
+ */
+typedef struct
+{
+    uint8_t                 num;					/* エンドポイント番号(0-14) */
+    uint8_t                 is_in : 1;				/* エンドポイントOUT/IN(0 or 1) */
+    uint8_t                 is_stall : 1;			/* エンドポイントスチール状態(0 or 1) */
+    uint8_t                 type : 2;				/* エンドポイントタイプ */
+    uint8_t                 data_pid_start : 1;		/* 初期データPID(0 or 1) */
+    uint8_t                 even_odd_frame : 1;		/* フレームパリティ(0 or 1) */
+    uint16_t                tx_fifo_num;			/* 転送FIFO番号(1-15) */
+    uint16_t                maxpacket;				/* エンドポイント最大パケットサイズ(0-64KB) */
+    uint8_t                 *xfer_buff;				/* 転送バッファポインター */
+    uint32_t                dma_addr;				/* DMA転送アドレス(32bitアライン) */
+    uint32_t                xfer_len;				/* 現在の転送数 */
+    uint32_t                xfer_count;				/* 指定転送カウント */
+}USB_OTG_EPTypeDef;
+
+/*
+ *  ホストクラス定義
+ */
+typedef struct
+{
+    uint8_t                 dev_addr;				/* USBデバイスアドレス(1-255) */
+    uint8_t                 ch_num;					/* Hostチャネル番号(1-15) */
+    uint8_t                 ep_num;					/* エンドポイント番号(1-15) */
+	uint8_t                 ep_is_in;				/* エンドポイントのディレクション(0 or 1) */
+	uint8_t                 speed;					/* USB Hostスピード */
+	uint8_t                 do_ping;				/* HSモードのPINGプロトコルの有効無効設定(0 or 1) */
+	uint8_t                 process_ping;			/* PINGプロトコル実行中フラグ(1で実行中) */
+	uint8_t                 ep_type;				/* エンドポイントタイプ(0-3) */
+	uint16_t                max_packet;				/* 最大パケットサイズ(64KB以内) */
+	uint8_t                 data_pid;				/* 初期設定データPID. */
+	uint8_t                 *xfer_buff;				/* 転送バッファへのポインタ */
+	uint32_t                xfer_len;				/* 現在の転送数 */
+	uint32_t                xfer_count;				/* 指定転送サイズ */
+	uint8_t                 toggle_in;				/* IN transfer current toggle flag. */
+	uint8_t                 toggle_out;				/* OUT transfer current toggle flag */
+	uint32_t                dma_addr;				/* DMA転送アドレス(4バイトアライン) */
+	uint32_t                err_count;				/* Hostチャネルエラーカウンター */
+	volatile uint8_t        urb_state;				/* URBステート */
+	volatile uint8_t        state;					/* Hostチャネルステート */
+}USB_OTG_HCTypeDef;
+
+
+#ifndef USBD_HS_TRDT_VALUE
+ #define USBD_HS_TRDT_VALUE           9U
+#endif /* USBD_HS_TRDT_VALUE */
+
+
+#define USBOTG_BASE(a)    ((uint32_t)(a))
+#define USBPGC_BASE(a)    ((uint32_t)(a)+USB_OTG_PCGCCTL_BASE)
+#define USBPRT_BASE(a)    ((uint32_t)(a)+USB_OTG_HOST_PORT_BASE)
+#define USBD_BASE(a)      ((uint32_t)(a)+USB_OTG_DEVICE_BASE)
+#define USBIEP_BASE(a, i) ((uint32_t)(a)+USB_OTG_IN_ENDPOINT_BASE+((i)*USBO_EP_REG_SIZE))
+#define USBOEP_BASE(a, i) ((uint32_t)(a)+USB_OTG_OUT_ENDPOINT_BASE+((i)*USBO_EP_REG_SIZE))
+#define USBD_FIFO(a, i)   ((uint32_t)(a)+USB_OTG_FIFO_BASE+((i)*USB_OTG_FIFO_SIZE))
+#define USBH_BASE(a)      ((uint32_t)(a)+USB_OTG_HOST_BASE)
+#define USBHC_BASE(a, i)  ((uint32_t)(a)+USB_OTG_HOST_CHANNEL_BASE+((i)*USBO_HOST_CHANNEL_REG_SIZE))
+
+
+#ifndef TOPPERS_MACRO_ONLY
+
+
+/*
+ *   USB_OTGデバイスハンドラ定義
+ */
+typedef struct _USB_OTG_Handle_t USB_OTG_Handle_t;
+struct _USB_OTG_Handle_t
+{
+	uint32_t              base;			/* USB OTG レジスタベースアドレス */
+	USB_OTG_Init_t        Init;			/* USB OTG 初期設定 */
+	USB_OTG_HCTypeDef     hc[MAX_EPS_CHANNELS];			/* HOST チャネルデータ */
+	USB_OTG_EPTypeDef     IN_ep[MAX_EPS_CHANNELS-1];	/* IN エンドポイントデータ */
+	USB_OTG_EPTypeDef     OUT_ep[MAX_EPS_CHANNELS-1];	/* OUT エンドポイントデータ */
+	volatile uint32_t     Setup[12];					/* Setup パケットバッファ */
+	uint8_t               lx_state;						/* lx state */
+	uint8_t               enabled;						/* device enabled */
+	uint8_t               connected;					/* device 接続中 */
+	uint8_t               dedicated_fifos;				/* device dedicated fifo mode */
+	uint32_t              resetbit;						/* usb reset bit */
+	uint32_t              fifo_mem;						/* fifo memoryサイズ */
+	uint32_t              pcd_rx_fifo_sz;				/* pcd rx fifoサイズ */
+	uint32_t              pcd_np_g_tx_fifo_sz;			/* pcd g tx fifoサイズ */
+	uint32_t              pcd_tx_fifo_sz[MAX_EPS_CHANNELS];	/* pcd tx fifoテーブル */
+#ifdef USB_OTG_GLPMCFG_LPMEN
+	volatile uint32_t     BESL;			/* BESL保存領域 */
+	volatile uint8_t      lpm_state;	/* LPM 状態 */
+	uint8_t               lpm_active;	/* Link Power Management有効無効設定(0 or 1) */
+#endif /* USB_OTG_GLPMCFG_LPMEN */
+	USB_OTG_HwParam_t     hw_params;					/* ハードウェア設定値 */
+	void                  (*hostsofcallback)(USB_OTG_Handle_t * hhcd);		/* sofコールバック関数 */
+ 	void                  (*hostconnectcallback)(USB_OTG_Handle_t * hhcd);	/* connectコールバック関数 */
+ 	void                  (*hostdisconnectcallback)(USB_OTG_Handle_t * hhcd);	/* disconnectコールバック関数 */
+ 	void                  (*hostchangeurbcallback)(USB_OTG_Handle_t * hhcd, uint8_t num, uint8_t state);	/* changeurbコールバック関数 */
+	void                  (*devsetupstagecallback)(USB_OTG_Handle_t * hhcd);
+	void                  (*devdataoutstagecallback)(USB_OTG_Handle_t * hhcd, uint8_t epnum);
+	void                  (*devdatainstagecallback)(USB_OTG_Handle_t * hhcd, uint8_t epnum);
+	void                  (*devsofcallback)(USB_OTG_Handle_t * hhcd);
+	void                  (*devresetcallback)(USB_OTG_Handle_t * hhcd);
+	void                  (*devsuspendcallback)(USB_OTG_Handle_t * hhcd);
+	void                  (*devresumecallback)(USB_OTG_Handle_t * hhcd);
+	void                  (*devisooutcallback)(USB_OTG_Handle_t * hhcd, uint8_t epnum);
+	void                  (*devisoincallback)(USB_OTG_Handle_t * hhcd, uint8_t epnum);
+	void                  (*devconnectcallback)(USB_OTG_Handle_t * hhcd);
+	void                  (*devdisconnectcallback)(USB_OTG_Handle_t * hhcd);
+	void                  (*devlpmcallback)(USB_OTG_Handle_t * hhcd, uint8_t msg);
+	void                  *pHost;		/* Pointer Host Stack Handler    */
+	void                  *pDev;		/* Pointer Device Stack Handler */
+};
+
+extern USB_OTG_Handle_t *usbo_init(ID portid, USB_OTG_Init_t *pini);
+extern ER usbo_deinit(USB_OTG_Handle_t *husb);
+extern ER usbo_devinit(USB_OTG_Handle_t *husb);
+extern ER usbo_coreinit(USB_OTG_Handle_t *husb);
+extern ER usbo_setupint(USB_OTG_Handle_t *husb);
+extern ER usbo_enableglobalint(USB_OTG_Handle_t *husb);
+extern ER usbo_disableglobalint(USB_OTG_Handle_t *husb);
+extern ER usbo_setcurrentmode(USB_OTG_Handle_t *husb);
+extern ER usbo_flushRxFifo(USB_OTG_Handle_t *husb);
+extern ER usbo_flushTxFifo(USB_OTG_Handle_t *husb, uint32_t num);
+extern ER usbo_initFiFo(USB_OTG_Handle_t *husb);
+extern ER usbo_activateEndpoint(USB_OTG_Handle_t *husb, USB_OTG_EPTypeDef *ep);
+extern ER usbo_deactivateEndpoint(USB_OTG_Handle_t *husb, USB_OTG_EPTypeDef *ep);
+extern ER usbo_epstartxfer(USB_OTG_Handle_t *husb, USB_OTG_EPTypeDef *ep);
+extern ER usbo_ep0startxfer(USB_OTG_Handle_t *husb, USB_OTG_EPTypeDef *ep);
+extern ER usbo_epsetStall(USB_OTG_Handle_t *husb, USB_OTG_EPTypeDef *ep);
+extern ER usbo_epclearStall(USB_OTG_Handle_t *husb, USB_OTG_EPTypeDef *ep);
+extern ER usbo_setDevAddress(USB_OTG_Handle_t *husb, uint8_t address);
+extern ER usbo_devconnect(USB_OTG_Handle_t *husb);
+extern ER usbo_devdisconnect(USB_OTG_Handle_t *husb);
+extern ER usbo_stopdevice(USB_OTG_Handle_t *husb);
+extern ER usbo_ep0_outstart(USB_OTG_Handle_t *husb, uint8_t *psetup);
+extern uint8_t usbo_getDevSpeed(USB_OTG_Handle_t *husb);
+extern ER usbo_init_lpm(USB_OTG_Handle_t *husb);
+
+extern ER usbo_hostinit(USB_OTG_Handle_t *husb);
+extern ER usbo_starthost(USB_OTG_Handle_t *husb);
+extern ER usbo_resetport(USB_OTG_Handle_t *husb);
+extern ER usbo_drivevbus(USB_OTG_Handle_t *husb, uint8_t state);
+extern void usbo_driveextvbus(USB_OTG_Handle_t *husb, uint8_t state);
+extern uint32_t usbo_gethostspeed(USB_OTG_Handle_t *husb);
+extern uint32_t usbo_getcurrentframe(USB_OTG_Handle_t *husb);
+extern ER usbo_hc_init(USB_OTG_Handle_t *husb, uint8_t ch_num, uint8_t epnum);
+extern ER usbo_hc_startxfer(USB_OTG_Handle_t *husb, uint8_t ch_num);
+extern ER usbo_hc_halt(USB_OTG_Handle_t *husb, uint8_t ch_num);
+extern ER usbo_stophost(USB_OTG_Handle_t *husb);
+
+extern void usbo_hcd_irqhandler(USB_OTG_Handle_t *husb);
+extern void usbo_pcd_irqhandler(USB_OTG_Handle_t *husb);
+
+extern void usb_otg_isr(intptr_t exinf);
+extern void usb_otg_wkup_isr(intptr_t exinf);
+
+extern void	usbh_task(intptr_t exinf);
+
+#endif /* TOPPERS_MACRO_ONLY */
+
+#endif	/* _USB_OTG_H_ */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/sample/Makefile
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/sample/Makefile	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/sample/Makefile	(revision 457)
@@ -0,0 +1,589 @@
+#
+#  TOPPERS/ASP Kernel
+#      Toyohashi Open Platform for Embedded Real-Time Systems/
+#      Advanced Standard Profile Kernel
+# 
+#  Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
+#                              Toyohashi Univ. of Technology, JAPAN
+#  Copyright (C) 2006-2014 by Embedded and Real-Time Systems Laboratory
+#              Graduate School of Information Science, Nagoya Univ., JAPAN
+# 
+#  ä¸è¨èä½æ¨©è
+ã¯ï¼ä»¥ä¸ã®(1)ï½(4)ã®æ¡ä»¶ãæºããå ´åã«éãï¼æ¬ã½ããã¦ã§
+#  ã¢ï¼æ¬ã½ããã¦ã§ã¢ãæ¹å¤ãããã®ãå«ãï¼ä»¥ä¸åãï¼ãä½¿ç¨ã»è¤è£½ã»æ¹
+#  å¤ã»åé
+å¸ï¼ä»¥ä¸ï¼å©ç¨ã¨å¼ã¶ï¼ãããã¨ãç¡åã§è¨±è«¾ããï¼
+#  (1) æ¬ã½ããã¦ã§ã¢ãã½ã¼ã¹ã³ã¼ãã®å½¢ã§å©ç¨ããå ´åã«ã¯ï¼ä¸è¨ã®èä½
+#      æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨ã®ç¡ä¿è¨¼è¦å®ãï¼ãã®ã¾ã¾ã®å½¢ã§ã½ã¼
+#      ã¹ã³ã¼ãä¸­ã«å«ã¾ãã¦ãããã¨ï¼
+#  (2) æ¬ã½ããã¦ã§ã¢ãï¼ã©ã¤ãã©ãªå½¢å¼ãªã©ï¼ä»ã®ã½ããã¦ã§ã¢éçºã«ä½¿
+#      ç¨ã§ããå½¢ã§åé
+å¸ããå ´åã«ã¯ï¼åé
+å¸ã«ä¼´ããã­ã¥ã¡ã³ãï¼å©ç¨
+#      è
+ããã¥ã¢ã«ãªã©ï¼ã«ï¼ä¸è¨ã®èä½æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨
+#      ã®ç¡ä¿è¨¼è¦å®ãæ²è¼ãããã¨ï¼
+#  (3) æ¬ã½ããã¦ã§ã¢ãï¼æ©å¨ã«çµã¿è¾¼ããªã©ï¼ä»ã®ã½ããã¦ã§ã¢éçºã«ä½¿
+#      ç¨ã§ããªãå½¢ã§åé
+å¸ããå ´åã«ã¯ï¼æ¬¡ã®ããããã®æ¡ä»¶ãæºããã
+#      ã¨ï¼
+#    (a) åé
+å¸ã«ä¼´ããã­ã¥ã¡ã³ãï¼å©ç¨è
+ããã¥ã¢ã«ãªã©ï¼ã«ï¼ä¸è¨ã®è
+#        ä½æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨ã®ç¡ä¿è¨¼è¦å®ãæ²è¼ãããã¨ï¼
+#    (b) åé
+å¸ã®å½¢æ
+ãï¼å¥ã«å®ããæ¹æ³ã«ãã£ã¦ï¼TOPPERSãã­ã¸ã§ã¯ãã«
+#        å ±åãããã¨ï¼
+#  (4) æ¬ã½ããã¦ã§ã¢ã®å©ç¨ã«ããç´æ¥çã¾ãã¯éæ¥çã«çãããããªãæ
+#      å®³ãããï¼ä¸è¨èä½æ¨©è
+ããã³TOPPERSãã­ã¸ã§ã¯ããå
+è²¬ãããã¨ï¼
+#      ã¾ãï¼æ¬ã½ããã¦ã§ã¢ã®ã¦ã¼ã¶ã¾ãã¯ã¨ã³ãã¦ã¼ã¶ããã®ãããªãç
+#      ç±ã«åºã¥ãè«æ±ãããï¼ä¸è¨èä½æ¨©è
+ããã³TOPPERSãã­ã¸ã§ã¯ãã
+#      å
+è²¬ãããã¨ï¼
+# 
+#  æ¬ã½ããã¦ã§ã¢ã¯ï¼ç¡ä¿è¨¼ã§æä¾ããã¦ãããã®ã§ããï¼ä¸è¨èä½æ¨©è
+ã
+#  ãã³TOPPERSãã­ã¸ã§ã¯ãã¯ï¼æ¬ã½ããã¦ã§ã¢ã«é¢ãã¦ï¼ç¹å®ã®ä½¿ç¨ç®ç
+#  ã«å¯¾ããé©åæ§ãå«ãã¦ï¼ãããªãä¿è¨¼ãè¡ããªãï¼ã¾ãï¼æ¬ã½ããã¦ã§
+#  ã¢ã®å©ç¨ã«ããç´æ¥çã¾ãã¯éæ¥çã«çãããããªãæå®³ã«é¢ãã¦ãï¼ã
+#  ã®è²¬ä»»ãè² ããªãï¼
+# 
+#  $Id$
+# 
+
+#
+#  ã¿ã¼ã²ããã®æå®ï¼Makefile.targetã§ä¸æ¸ããããã®ãé²ãããï¼
+#
+all:
+
+#
+#  ã¿ã¼ã²ããç¥ç§°ã®å®ç¾©
+#
+TARGET = @(TARGET)
+
+#
+#  ãã­ã°ã©ãã³ã°è¨èªã®å®ç¾©
+#
+SRCLANG = @(SRCLANG)
+ifeq ($(SRCLANG),c)
+  LIBS = -lc
+endif
+ifeq ($(SRCLANG),c++)
+  USE_CXX = true
+  CXXLIBS = -lstdc++ -lm -lc
+  CXXRTS = cxxrt.o newlibrt.o
+endif
+
+#
+#  ã½ã¼ã¹ãã¡ã¤ã«ã®ãã£ã¬ã¯ããªã®å®ç¾©
+#
+SRCDIR = @(SRCDIR)
+
+#
+#  ãªãã¸ã§ã¯ããã¡ã¤ã«åã®æ¡å¼µå­ã®è¨­å®
+#
+OBJEXT = @(OBJEXT)
+
+#
+#  å®è¡ç°å¢ã®å®ç¾©ï¼ã¿ã¼ã²ããä¾å­ã«ä¸æ¸ããããå ´åãããï¼
+#
+DBGENV := @(DBGENV)
+
+#
+#  ã«ã¼ãã«ã©ã¤ãã©ãªï¼libkernel.aï¼ã®ãã£ã¬ã¯ããªå
+#  ï¼ã«ã¼ãã«ã©ã¤ãã©ãªãmakeå¯¾è±¡ã«ããæã¯ï¼ç©ºã«å®ç¾©ããï¼
+#
+KERNEL_LIB = @(KERNEL_LIB)
+
+#
+#  ã«ã¼ãã«ãé¢æ°åä½ã§ã³ã³ãã¤ã«ãããã©ããã®å®ç¾©
+#
+KERNEL_FUNCOBJS = @(KERNEL_FUNCOBJS)
+
+#
+#  ãã¬ã¼ã¹ã­ã°ãåå¾ãããã©ããã®å®ç¾©
+#
+ENABLE_TRACE = @(ENABLE_TRACE)
+
+#
+#  ã¦ã¼ãã£ãªãã£ãã­ã°ã©ã ã®åç§°
+#
+PERL = @(PERL)
+CFG = @(CFG)
+
+#
+#  ãªãã¸ã§ã¯ããã¡ã¤ã«åã®å®ç¾©
+#
+OBJNAME = asp
+ifdef OBJEXT
+  OBJFILE = $(OBJNAME).$(OBJEXT)
+  CFG1_OUT = cfg1_out.$(OBJEXT)
+else
+  OBJFILE = $(OBJNAME)
+  CFG1_OUT = cfg1_out
+endif
+
+#
+#  ã¿ã¼ã²ããä¾å­é¨ã®ãã£ã¬ã¯ããªã®å®ç¾©
+#
+TARGETDIR = $(SRCDIR)/target/$(TARGET)
+
+#
+#  ã¿ã¼ã²ããä¾å­ã®å®ç¾©ã®ã¤ã³ã¯ã«ã¼ã
+#
+include $(TARGETDIR)/Makefile.target
+
+#
+#  ã³ã³ãã£ã®ã¥ã¬ã¼ã¿é¢ä¿ã®å¤æ°ã®å®ç¾©
+#
+CFG_TABS := --api-table $(SRCDIR)/kernel/kernel_api.csv \
+			--cfg1-def-table $(SRCDIR)/kernel/kernel_def.csv $(CFG_TABS)
+
+CFG_ASMOBJS := $(CFG_ASMOBJS)
+CFG_COBJS := kernel_cfg.o $(CFG_COBJS)
+CFG_OBJS := $(CFG_ASMOBJS) $(CFG_COBJS)
+CFG2_OUT_SRCS := kernel_cfg.h kernel_cfg.c $(CFG2_OUT_SRCS)
+
+#
+#  å
+±éã³ã³ãã¤ã«ãªãã·ã§ã³ã®å®ç¾©
+#
+COPTS := $(COPTS) -g @(COPTS)
+ifndef OMIT_WARNING_ALL
+  COPTS := $(COPTS) -Wall
+endif
+ifndef OMIT_OPTIMIZATION
+  COPTS := $(COPTS) -O2
+endif
+CDEFS := $(CDEFS) @(CDEFS)
+INCLUDES := -I. -I$(SRCDIR)/include -I$(SRCDIR)/arch -I$(SRCDIR) $(INCLUDES)
+LDFLAGS := $(LDFLAGS) @(LDFLAGS)
+CFG1_OUT_LDFLAGS := $(CFG1_OUT_LDFLAGS) @(LDFLAGS)
+LIBS := $(LIBS) $(CXXLIBS)
+CFLAGS = $(COPTS) $(CDEFS) $(INCLUDES)
+
+#
+#  ã¢ããªã±ã¼ã·ã§ã³ãã­ã°ã©ã ã«é¢ããå®ç¾©
+#
+APPLNAME = @(APPLNAME)
+APPLDIR = @(APPLDIR)
+APPL_CFG = $(APPLNAME).cfg
+
+APPL_DIR = $(APPLDIR) $(SRCDIR)/library
+APPL_ASMOBJS =
+ifdef USE_CXX
+  APPL_CXXOBJS = $(APPLNAME).o @(APPLOBJS)
+  APPL_COBJS =
+else
+  APPL_COBJS = $(APPLNAME).o @(APPLOBJS)
+endif
+APPL_COBJS := $(APPL_COBJS) log_output.o vasyslog.o t_perror.o strerror.o
+APPL_CFLAGS =
+APPL_LIBS =
+ifdef APPLDIR
+  INCLUDES := $(INCLUDES) $(foreach dir,$(APPLDIR),-I$(dir))
+endif
+
+#
+#  ã·ã¹ãã ãµã¼ãã¹ã«é¢ããå®ç¾©
+#
+SYSSVC_DIR := $(SYSSVC_DIR) $(SRCDIR)/syssvc $(SRCDIR)/library
+SYSSVC_ASMOBJS := $(SYSSVC_ASMOBJS)
+SYSSVC_COBJS := $(SYSSVC_COBJS) banner.o syslog.o serial.o logtask.o \
+				@(SYSSVCOBJS) $(CXXRTS)
+SYSSVC_CFLAGS := $(SYSSVC_CFLAGS)
+SYSSVC_LIBS := $(SYSSVC_LIBS)
+INCLUDES := $(INCLUDES)
+
+#
+#  ã«ã¼ãã«ã«é¢ããå®ç¾©
+#
+#  KERNEL_ASMOBJS: ã«ã¼ãã«ã©ã¤ãã©ãªã«å«ããï¼ã½ã¼ã¹ãã¢ã»ã³ããªè¨èªã®
+#				   ãªãã¸ã§ã¯ããã¡ã¤ã«ï¼
+#  KERNEL_COBJS: ã«ã¼ãã«ã®ã©ã¤ãã©ãªã«å«ããï¼ã½ã¼ã¹ãCè¨èªã§ï¼ã½ã¼ã¹
+#				 ãã¡ã¤ã«ã¨1å¯¾1ã«å¯¾å¿ãããªãã¸ã§ã¯ããã¡ã¤ã«ï¼
+#  KERNEL_LCSRCS: ã«ã¼ãã«ã®ã©ã¤ãã©ãªã«å«ããCè¨èªã®ã½ã¼ã¹ãã¡ã¤ã«ã§ï¼
+#				  1ã¤ã®ã½ã¼ã¹ãã¡ã¤ã«ããè¤æ°ã®ãªãã¸ã§ã¯ããã¡ã¤ã«ãç
+#				  æãããã®ï¼
+#  KERNEL_LCOBJS: ä¸ã®ã½ã¼ã¹ãã¡ã¤ã«ããçæããããªãã¸ã§ã¯ããã¡ã¤ã«ï¼
+#  KERNEL_AUX_COBJS: ã­ã¼ãã¢ã¸ã¥ã¼ã«ã«å«ããªããï¼ã«ã¼ãã«ã®ã½ã¼ã¹ãã¡
+#					 ã¤ã«ã¨åããªãã·ã§ã³ãé©ç¨ãã¦ã³ã³ãã¤ã«ãã¹ãï¼ã½ã¼
+#					 ã¹ãCè¨èªã®ãªãã¸ã§ã¯ããã¡ã¤ã«ï¼
+#
+KERNEL_DIR := $(KERNEL_DIR) $(SRCDIR)/kernel
+KERNEL_ASMOBJS := $(KERNEL_ASMOBJS)
+KERNEL_COBJS := $(KERNEL_COBJS)
+KERNEL_CFLAGS := $(KERNEL_CFLAGS) -I$(SRCDIR)/kernel
+ifdef OMIT_MAKEOFFSET
+  OFFSET_H =
+else
+  OFFSET_H = offset.h
+ifndef OFFSET_TF
+  KERNEL_AUX_COBJS := $(KERNEL_AUX_COBJS) makeoffset.o
+endif
+endif
+
+#
+#  ã¿ã¼ã²ãããã¡ã¤ã«ï¼è¤æ°ãåæã«é¸æãã¦ã¯ãªããªãï¼
+#
+all: $(OBJFILE)
+#all: $(OBJNAME).bin
+#all: $(OBJNAME).srec
+
+##### ä»¥ä¸ã¯ç·¨éããªããã¨ #####
+
+#
+#  ç°å¢ã«ä¾å­ããã³ã³ãã¤ã«ãªãã·ã§ã³ã®å®ç¾©
+#
+ifdef DBGENV
+  CDEFS := $(CDEFS) -D$(DBGENV)
+endif
+
+#
+#  ã«ã¼ãã«ã®ãã¡ã¤ã«æ§æã®å®ç¾©
+#
+include $(SRCDIR)/kernel/Makefile.kernel
+ifdef KERNEL_FUNCOBJS
+  KERNEL_LCSRCS := $(KERNEL_FCSRCS)
+  KERNEL_LCOBJS := $(foreach file,$(KERNEL_FCSRCS),$($(file:.c=)))
+else
+  KERNEL_CFLAGS := -DALLFUNC $(KERNEL_CFLAGS)
+  KERNEL_COBJS := $(KERNEL_COBJS) \
+					$(foreach file,$(KERNEL_FCSRCS),$(file:.c=.o))
+endif
+
+#
+#  ã½ã¼ã¹ãã¡ã¤ã«ã®ãããã£ã¬ã¯ããªã«é¢ããå®ç¾©
+#
+vpath %.c $(KERNEL_DIR) $(SYSSVC_DIR) $(APPL_DIR)
+vpath %.S $(KERNEL_DIR) $(SYSSVC_DIR) $(APPL_DIR)
+vpath %.cfg $(APPL_DIR)
+
+#
+#  ã³ã³ãã¤ã«ã®ããã®å¤æ°ã®å®ç¾©
+#
+KERNEL_LIB_OBJS = $(KERNEL_ASMOBJS) $(KERNEL_COBJS) $(KERNEL_LCOBJS)
+SYSSVC_OBJS = $(SYSSVC_ASMOBJS) $(SYSSVC_COBJS)
+APPL_OBJS = $(APPL_ASMOBJS) $(APPL_COBJS) $(APPL_CXXOBJS)
+ALL_OBJS = $(START_OBJS) $(APPL_OBJS) $(SYSSVC_OBJS) $(CFG_OBJS) \
+											$(END_OBJS) $(HIDDEN_OBJS)
+ifdef KERNEL_LIB
+  ALL_LIBS = $(APPL_LIBS) $(SYSSVC_LIBS) -lkernel $(LIBS)
+  LIBS_DEP = $(filter %.a,$(ALL_LIBS)) $(KERNEL_LIB)/libkernel.a
+  LDFLAGS := $(LDFLAGS) -L$(KERNEL_LIB)
+  REALCLEAN_FILES := libkernel.a $(REALCLEAN_FILES)
+else
+  ALL_LIBS = $(APPL_LIBS) $(SYSSVC_LIBS) libkernel.a $(LIBS)
+  LIBS_DEP = $(filter %.a,$(ALL_LIBS))
+endif
+
+ifdef TEXT_START_ADDRESS
+  LDFLAGS := $(LDFLAGS) -Wl,-Ttext,$(TEXT_START_ADDRESS)
+  CFG1_OUT_LDFLAGS := $(CFG1_OUT_LDFLAGS) -Wl,-Ttext,$(TEXT_START_ADDRESS)
+endif
+ifdef DATA_START_ADDRESS
+  LDFLAGS := $(LDFLAGS) -Wl,-Tdata,$(DATA_START_ADDRESS)
+  CFG1_OUT_LDFLAGS := $(CFG1_OUT_LDFLAGS) -Wl,-Tdata,$(DATA_START_ADDRESS)
+endif
+ifdef LDSCRIPT
+  LDFLAGS := $(LDFLAGS) -Wl,-T,$(LDSCRIPT)
+  CFG1_OUT_LDFLAGS := $(CFG1_OUT_LDFLAGS) -Wl,-T,$(LDSCRIPT)
+endif
+
+#
+#  ãªãã»ãããã¡ã¤ã«ï¼offset.hï¼ã®çæè¦å
+#
+ifdef OFFSET_TF
+offset.h: $(APPL_CFG) kernel_cfg.timestamp
+	$(CFG) --pass 3 --kernel asp $(INCLUDES) \
+				--rom-image cfg1_out.srec --symbol-table cfg1_out.syms \
+				-T $(OFFSET_TF) $(CFG_TABS) $<
+else
+offset.h: makeoffset.s $(SRCDIR)/utils/genoffset
+	$(PERL) $(SRCDIR)/utils/genoffset makeoffset.s > offset.h
+endif
+
+#
+#  ã«ã¼ãã«ã®ã³ã³ãã£ã®ã¥ã¬ã¼ã·ã§ã³ãã¡ã¤ã«ã®çæ
+#
+cfg1_out.c: $(APPL_CFG)
+	$(CFG) --pass 1 --kernel asp $(INCLUDES) $(CFG_TABS) $<
+
+$(CFG2_OUT_SRCS): kernel_cfg.timestamp
+kernel_cfg.timestamp: $(APPL_CFG) \
+						$(START_OBJS) cfg1_out.o $(END_OBJS) $(HIDDEN_OBJS)
+	$(LINK) $(CFLAGS) $(CFG1_OUT_LDFLAGS) -o $(CFG1_OUT) \
+						$(START_OBJS) cfg1_out.o $(END_OBJS)
+	$(NM) -n $(CFG1_OUT) > cfg1_out.syms
+	$(OBJCOPY) -O srec -S $(CFG1_OUT) cfg1_out.srec
+	$(CFG) --pass 2 --kernel asp $(INCLUDES) \
+				-T $(TARGETDIR)/target.tf $(CFG_TABS) $<
+	touch -r kernel_cfg.c kernel_cfg.timestamp
+
+#
+#  ã«ã¼ãã«ã©ã¤ãã©ãªãã¡ã¤ã«ã®çæ
+#
+libkernel.a: $(OFFSET_H) $(KERNEL_LIB_OBJS)
+	rm -f libkernel.a
+	$(AR) -rcs libkernel.a $(KERNEL_LIB_OBJS)
+	$(RANLIB) libkernel.a
+
+#
+#  ç¹å¥ãªä¾å­é¢ä¿ã®å®ç¾©
+#
+banner.o: kernel_cfg.timestamp $(filter-out banner.o,$(ALL_OBJS)) $(LIBS_DEP)
+
+#
+#  å
+¨ä½ã®ãªã³ã¯
+#
+$(OBJFILE): $(APPL_CFG) kernel_cfg.timestamp $(ALL_OBJS) $(LIBS_DEP)
+	$(LINK) $(CFLAGS) $(LDFLAGS) -o $(OBJFILE) $(START_OBJS) \
+			$(APPL_OBJS) $(SYSSVC_OBJS) $(CFG_OBJS) $(ALL_LIBS) $(END_OBJS)
+	$(NM) -n $(OBJFILE) > $(OBJNAME).syms
+	$(OBJCOPY) -O srec -S $(OBJFILE) $(OBJNAME).srec
+	$(CFG) --pass 3 --kernel asp $(INCLUDES) \
+				--rom-image $(OBJNAME).srec --symbol-table $(OBJNAME).syms \
+				-T $(TARGETDIR)/target_check.tf $(CFG_TABS) $<
+
+#
+#  ãã¤ããªãã¡ã¤ã«ã®çæ
+#
+$(OBJNAME).bin: $(OBJFILE)
+	$(OBJCOPY) -O binary -S $(OBJFILE) $(OBJNAME).bin
+
+#
+#  Sã¬ã³ã¼ããã¡ã¤ã«ã®çæ
+#
+$(OBJNAME).srec: $(OBJFILE)
+	$(OBJCOPY) -O srec -S $(OBJFILE) $(OBJNAME).srec
+
+#
+#  ã³ã³ãã¤ã«çµæã®æ¶å»
+#
+.PHONY: clean
+clean:
+	rm -f \#* *~ *.o $(CLEAN_FILES)
+	rm -f $(OBJFILE) $(OBJNAME).syms $(OBJNAME).srec $(OBJNAME).bin
+	rm -f kernel_cfg.timestamp $(CFG2_OUT_SRCS)
+	rm -f cfg1_out.c $(CFG1_OUT) cfg1_out.syms cfg1_out.srec
+ifndef KERNEL_LIB
+	rm -f libkernel.a
+endif
+	rm -f makeoffset.s offset.h
+
+.PHONY: cleankernel
+cleankernel:
+	rm -rf $(KERNEL_LIB_OBJS)
+	rm -f makeoffset.s offset.h
+
+.PHONY: cleandep
+cleandep:
+	if ! [ -f Makefile.depend ]; then \
+		rm -f kernel_cfg.timestamp $(CFG2_OUT_SRCS); \
+		rm -f cfg1_out.c cfg1_out.o $(CFG1_OUT) cfg1_out.syms cfg1_out.srec; \
+		rm -f makeoffset.s offset.h; \
+	fi
+	rm -f Makefile.depend
+
+.PHONY: realclean
+realclean: cleandep clean
+	rm -f $(REALCLEAN_FILES)
+
+#
+#  ã³ã³ãã£ã®ã¥ã¬ã¼ã¿ãçæãããã¡ã¤ã«ã®ã³ã³ãã¤ã«ã«ã¼ã«ã¨ä¾å­é¢ä¿ä½æ
+#  ã«ã¼ã«ã®å®ç¾©
+#
+#  ã³ã³ãã£ã®ã¥ã¬ã¼ã¿ãçæãããã¡ã¤ã«ã¯ï¼ã¢ããªã±ã¼ã·ã§ã³ãã­ã°ã©ã ç¨ï¼
+#  ã·ã¹ãã ãµã¼ãã¹ç¨ï¼ã«ã¼ãã«ç¨ã®ãã¹ã¦ã®ãªãã·ã§ã³ãä»ãã¦ã³ã³ãã¤ã«
+#  ããï¼
+#
+ALL_CFG_COBJS = $(CFG_COBJS) cfg1_out.o
+ALL_CFG_ASMOBJS = $(CFG_ASMOBJS)
+CFG_CFLAGS = $(APPL_CFLAGS) $(SYSSVC_CFLAGS) $(KERNEL_CFLAGS)
+
+$(ALL_CFG_COBJS): %.o: %.c
+	$(CC) -c $(CFLAGS) $(CFG_CFLAGS) $<
+
+$(ALL_CFG_COBJS:.o=.s): %.s: %.c
+	$(CC) -S $(CFLAGS) $(CFG_CFLAGS) $<
+
+$(ALL_CFG_COBJS:.o=.d): %.d: %.c
+	@$(PERL) $(SRCDIR)/utils/makedep -C $(CC) $(MAKEDEP_OPTS) \
+		-O "$(CFLAGS) $(CFG_CFLAGS)" $< >> Makefile.depend
+
+$(ALL_CFG_ASMOBJS): %.o: %.S
+	$(CC) -c $(CFLAGS) $(CFG_CFLAGS) $<
+
+$(ALL_CFG_ASMOBJS:.o=.d): %.d: %.S
+	@$(PERL) $(SRCDIR)/utils/makedep -C $(CC) $(MAKEDEP_OPTS) \
+		-O "$(CFLAGS) $(CFG_CFLAGS)" $< >> Makefile.depend
+
+#
+#  ç¹æ®ãªä¾å­é¢ä¿ä½æã«ã¼ã«ã®å®ç¾©
+#
+cfg1_out.depend: $(APPL_CFG)
+	@$(CFG) -M cfg1_out.c $(INCLUDES) $< >> Makefile.depend
+
+makeoffset.d: makeoffset.c
+	@$(PERL) $(SRCDIR)/utils/makedep -C $(CC) $(MAKEDEP_OPTS) \
+		-T "makeoffset.s" -O "$(CFLAGS) $(KERNEL_CFLAGS)" $< >> Makefile.depend
+
+#
+#  ä¾å­é¢ä¿ãã¡ã¤ã«ã®çæ
+#
+.PHONY: gendepend
+gendepend:
+	@echo "Generating Makefile.depend."
+
+.PHONY: depend
+ifdef KERNEL_LIB
+depend: cleandep kernel_cfg.timestamp gendepend \
+		cfg1_out.depend cfg1_out.d \
+		$(ALL_OBJS:.o=.d)
+else
+depend: cleandep $(OFFSET_H) kernel_cfg.timestamp gendepend \
+		cfg1_out.depend cfg1_out.d \
+		$(KERNEL_AUX_COBJS:.o=.d) $(KERNEL_ASMOBJS:.o=.d) \
+		$(KERNEL_COBJS:.o=.d) $(KERNEL_LCSRCS:.c=.d) $(ALL_OBJS:.o=.d)
+endif
+
+#
+#  ä¾å­é¢ä¿ãã¡ã¤ã«ãã¤ã³ã¯ã«ã¼ã
+#
+-include Makefile.depend
+
+#
+#  éçºãã¼ã«ã®ã³ãã³ãåã®å®ç¾©
+#
+ifeq ($(TOOL),gcc)
+  #
+  #  GNUéçºç°å¢ç¨
+  #
+  ifdef GCC_TARGET
+    GCC_TARGET_PREFIX = $(GCC_TARGET)-
+  else
+    GCC_TARGET_PREFIX =
+  endif
+  CC = $(GCC_TARGET_PREFIX)gcc
+  CXX = $(GCC_TARGET_PREFIX)g++
+  AS = $(GCC_TARGET_PREFIX)as
+  LD = $(GCC_TARGET_PREFIX)ld
+  AR = $(GCC_TARGET_PREFIX)ar
+  NM = $(GCC_TARGET_PREFIX)nm
+  RANLIB = $(GCC_TARGET_PREFIX)ranlib
+  OBJCOPY = $(GCC_TARGET_PREFIX)objcopy
+  OBJDUMP = $(GCC_TARGET_PREFIX)objdump
+endif
+
+ifdef USE_CXX
+  LINK = $(CXX)
+else
+  LINK = $(CC)
+endif
+
+#
+#  ã³ã³ãã¤ã«ã«ã¼ã«ã®å®ç¾©
+#
+KERNEL_ALL_COBJS = $(KERNEL_COBJS) $(KERNEL_AUX_COBJS)
+
+$(KERNEL_ALL_COBJS): %.o: %.c
+	$(CC) -c $(CFLAGS) $(KERNEL_CFLAGS) $<
+
+$(KERNEL_ALL_COBJS:.o=.s): %.s: %.c
+	$(CC) -S $(CFLAGS) $(KERNEL_CFLAGS) $<
+
+$(KERNEL_LCOBJS): %.o:
+	$(CC) -DTOPPERS_$(*F) -o $@ -c $(CFLAGS) $(KERNEL_CFLAGS) $<
+
+$(KERNEL_LCOBJS:.o=.s): %.s:
+	$(CC) -DTOPPERS_$(*F) -o $@ -S $(CFLAGS) $(KERNEL_CFLAGS) $<
+
+$(KERNEL_ASMOBJS): %.o: %.S
+	$(CC) -c $(CFLAGS) $(KERNEL_CFLAGS) $<
+
+$(SYSSVC_COBJS): %.o: %.c
+	$(CC) -c $(CFLAGS) $(SYSSVC_CFLAGS) $<
+
+$(SYSSVC_COBJS:.o=.s): %.s: %.c
+	$(CC) -S $(CFLAGS) $(SYSSVC_CFLAGS) $<
+
+$(SYSSVC_ASMOBJS): %.o: %.S
+	$(CC) -c $(CFLAGS) $(SYSSVC_CFLAGS) $<
+
+$(APPL_COBJS): %.o: %.c
+	$(CC) -c $(CFLAGS) $(APPL_CFLAGS) $<
+
+$(APPL_COBJS:.o=.s): %.s: %.c
+	$(CC) -S $(CFLAGS) $(APPL_CFLAGS) $<
+
+$(APPL_CXXOBJS): %.o: %.cpp
+	$(CXX) -c $(CFLAGS) $(APPL_CFLAGS) $<
+
+$(APPL_CXXOBJS:.o=.s): %.s: %.cpp
+	$(CXX) -S $(CFLAGS) $(APPL_CFLAGS) $<
+
+$(APPL_ASMOBJS): %.o: %.S
+	$(CC) -c $(CFLAGS) $(APPL_CFLAGS) $<
+
+#
+#  ä¾å­é¢ä¿ä½æã«ã¼ã«ã®å®ç¾©
+#
+$(KERNEL_COBJS:.o=.d): %.d: %.c
+	@$(PERL) $(SRCDIR)/utils/makedep -C $(CC) $(MAKEDEP_OPTS) \
+		-O "$(CFLAGS) $(KERNEL_CFLAGS)" $< >> Makefile.depend
+
+$(KERNEL_LCSRCS:.c=.d): %.d: %.c
+	@$(PERL) $(SRCDIR)/utils/makedep -C $(CC) $(MAKEDEP_OPTS) -T "$($*)" \
+		-O "-DALLFUNC $(CFLAGS) $(KERNEL_CFLAGS)" $< >> Makefile.depend
+
+$(KERNEL_ASMOBJS:.o=.d): %.d: %.S
+	@$(PERL) $(SRCDIR)/utils/makedep -C $(CC) $(MAKEDEP_OPTS) \
+		-O "$(CFLAGS) $(KERNEL_CFLAGS)" $< >> Makefile.depend
+
+$(SYSSVC_COBJS:.o=.d): %.d: %.c
+	@$(PERL) $(SRCDIR)/utils/makedep -C $(CC) $(MAKEDEP_OPTS) \
+		-O "$(CFLAGS) $(SYSSVC_CFLAGS)" $< >> Makefile.depend
+
+$(SYSSVC_ASMOBJS:.o=.d): %.d: %.S
+	@$(PERL) $(SRCDIR)/utils/makedep -C $(CC) $(MAKEDEP_OPTS) \
+		-O "$(CFLAGS) $(SYSSVC_CFLAGS)" $< >> Makefile.depend
+
+$(APPL_COBJS:.o=.d): %.d: %.c
+	@$(PERL) $(SRCDIR)/utils/makedep -C $(CC) $(MAKEDEP_OPTS) \
+		-O "$(CFLAGS) $(APPL_CFLAGS)" $< >> Makefile.depend
+
+$(APPL_CXXOBJS:.o=.d): %.d: %.cpp
+	@$(PERL) $(SRCDIR)/utils/makedep -C $(CXX) $(MAKEDEP_OPTS) \
+		-O "$(CFLAGS) $(APPL_CFLAGS)" $< >> Makefile.depend
+
+$(APPL_ASMOBJS:.o=.d): %.d: %.S
+	@$(PERL) $(SRCDIR)/utils/makedep -C $(CC) $(MAKEDEP_OPTS) \
+		-O "$(CFLAGS) $(APPL_CFLAGS)" $< >> Makefile.depend
+
+#
+#  ããã©ã«ãã³ã³ãã¤ã«ã«ã¼ã«ãä¸æ¸ã
+#
+%.o: %.c
+	@echo "*** Default compile rules should not be used."
+	$(CC) -c $(CFLAGS) $<
+
+%.s: %.c
+	@echo "*** Default compile rules should not be used."
+	$(CC) -S $(CFLAGS) $<
+
+%.o: %.cpp
+	@echo "*** Default compile rules should not be used."
+	$(CXX) -c $(CFLAGS) $<
+
+%.s: %.cpp
+	@echo "*** Default compile rules should not be used."
+	$(CXX) -S $(CFLAGS) $<
+
+%.o: %.S
+	@echo "*** Default compile rules should not be used."
+	$(CC) -c $(CFLAGS) $<
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/sample/sample1.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/sample/sample1.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/sample/sample1.c	(revision 457)
@@ -0,0 +1,559 @@
+/*
+ *  TOPPERS/ASP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Advanced Standard Profile Kernel
+ * 
+ *  Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
+ *                              Toyohashi Univ. of Technology, JAPAN
+ *  Copyright (C) 2004-2012 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  $Id$
+ */
+
+/* 
+ *  サンプルプログラム(1)の本体
+ *
+ *  ASPカーネルの基本的な動作を確認するためのサンプルプログラム．
+ *
+ *  プログラムの概要:
+ *
+ *  ユーザインタフェースを受け持つメインタスク（タスクID: MAIN_TASK，優
+ *  先度: MAIN_PRIORITY）と，3つの並行実行されるタスク（タスクID:
+ *  TASK1～TASK3，初期優先度: MID_PRIORITY）で構成される．また，起動周
+ *  期が2秒の周期ハンドラ（周期ハンドラID: CYCHDR1）を用いる．
+ *
+ *  並行実行されるタスクは，task_loop回空ループを実行する度に，タスクが
+ *  実行中であることをあらわすメッセージを表示する．空ループを実行する
+ *  のは，空ループなしでメッセージを出力すると，多量のメッセージが出力
+ *  され，プログラムの動作が確認しずらくなるためである．また，低速なシ
+ *  リアルポートを用いてメッセージを出力する場合に，すべてのメッセージ
+ *  が出力できるように，メッセージの量を制限するという理由もある．
+ *
+ *  周期ハンドラは，三つの優先度（HIGH_PRIORITY，MID_PRIORITY，
+ *  LOW_PRIORITY）のレディキューを回転させる．プログラムの起動直後は，
+ *  周期ハンドラは停止状態になっている．
+ *
+ *  メインタスクは，シリアルI/Oポートからの文字入力を行い（文字入力を
+ *  待っている間は，並行実行されるタスクが実行されている），入力された
+ *  文字に対応した処理を実行する．入力された文字と処理の関係は次の通り．
+ *  Control-Cまたは'Q'が入力されると，プログラムを終了する．
+ *
+ *  '1' : 対象タスクをTASK1に切り換える（初期設定）．
+ *  '2' : 対象タスクをTASK2に切り換える．
+ *  '3' : 対象タスクをTASK3に切り換える．
+ *  'a' : 対象タスクをact_tskにより起動する．
+ *  'A' : 対象タスクに対する起動要求をcan_actによりキャンセルする．
+ *  'e' : 対象タスクにext_tskを呼び出させ，終了させる．
+ *  't' : 対象タスクをter_tskにより強制終了する．
+ *  '>' : 対象タスクの優先度をHIGH_PRIORITYにする．
+ *  '=' : 対象タスクの優先度をMID_PRIORITYにする．
+ *  '<' : 対象タスクの優先度をLOW_PRIORITYにする．
+ *  'G' : 対象タスクの優先度をget_priで読み出す．
+ *  's' : 対象タスクにslp_tskを呼び出させ，起床待ちにさせる．
+ *  'S' : 対象タスクにtslp_tsk(10秒)を呼び出させ，起床待ちにさせる．
+ *  'w' : 対象タスクをwup_tskにより起床する．
+ *  'W' : 対象タスクに対する起床要求をcan_wupによりキャンセルする．
+ *  'l' : 対象タスクをrel_waiにより強制的に待ち解除にする．
+ *  'u' : 対象タスクをsus_tskにより強制待ち状態にする．
+ *  'm' : 対象タスクの強制待ち状態をrsm_tskにより解除する．
+ *  'd' : 対象タスクにdly_tsk(10秒)を呼び出させ，時間経過待ちにさせる．
+ *  'x' : 対象タスクに例外パターン0x0001の例外処理を要求する．
+ *  'X' : 対象タスクに例外パターン0x0002の例外処理を要求する．
+ *  'y' : 対象タスクにdis_texを呼び出させ，タスク例外を禁止する．
+ *  'Y' : 対象タスクにena_texを呼び出させ，タスク例外を許可する．
+ *  'r' : 3つの優先度（HIGH_PRIORITY，MID_PRIORITY，LOW_PRIORITY）のレ
+ *        ディキューを回転させる．
+ *  'c' : 周期ハンドラを動作開始させる．
+ *  'C' : 周期ハンドラを動作停止させる．
+ *  'b' : アラームハンドラを5秒後に起動するよう動作開始させる．
+ *  'B' : アラームハンドラを動作停止させる．
+ *  'z' : 対象タスクにCPU例外を発生させる（タスクを終了させる）．
+ *  'Z' : 対象タスクにCPUロック状態でCPU例外を発生させる（プログラムを
+ *        終了する）．
+ *  '@' : タスク3をacre_tskにより生成し，def_texによりタスク例外処理
+ *        ルーチンを設定する．
+ *  '!' : 対象タスクをdel_tskにより削除する．
+ *  'V' : get_utmで性能評価用システム時刻を2回読む．
+ *  'v' : 発行したシステムコールを表示する（デフォルト）．
+ *  'q' : 発行したシステムコールを表示しない．
+ */
+
+#include <kernel.h>
+#include <t_syslog.h>
+#include <t_stdlib.h>
+#include "syssvc/serial.h"
+#include "syssvc/syslog.h"
+#include "kernel_cfg.h"
+#include "sample1.h"
+
+/*
+ *  サービスコールのエラーのログ出力
+ */
+Inline void
+svc_perror(const char *file, int_t line, const char *expr, ER ercd)
+{
+	if (ercd < 0) {
+		t_perror(LOG_ERROR, file, line, expr, ercd);
+	}
+}
+
+#define	SVC_PERROR(expr)	svc_perror(__FILE__, __LINE__, #expr, (expr))
+
+/*
+ *  並行実行されるタスクへのメッセージ領域
+ */
+char	message[3];
+
+/*
+ *  ループ回数
+ */
+ulong_t	task_loop;		/* タスク内でのループ回数 */
+ulong_t	tex_loop;		/* 例外処理ルーチン内でのループ回数 */
+
+/*
+ *  並行実行されるタスク
+ */
+void task(intptr_t exinf)
+{
+	volatile ulong_t	i;
+	int_t		n = 0;
+	int_t		tskno = (int_t) exinf;
+	const char	*graph[] = { "|", "  +", "    *" };
+	char		c;
+
+	SVC_PERROR(ena_tex());
+	while (true) {
+		syslog(LOG_NOTICE, "task%d is running (%03d).   %s",
+										tskno, ++n, graph[tskno-1]);
+		for (i = 0; i < task_loop; i++);
+		c = message[tskno-1];
+		message[tskno-1] = 0;
+		switch (c) {
+		case 'e':
+			syslog(LOG_INFO, "#%d#ext_tsk()", tskno);
+			SVC_PERROR(ext_tsk());
+			assert(0);
+		case 's':
+			syslog(LOG_INFO, "#%d#slp_tsk()", tskno);
+			SVC_PERROR(slp_tsk());
+			break;
+		case 'S':
+			syslog(LOG_INFO, "#%d#tslp_tsk(10000)", tskno);
+			SVC_PERROR(tslp_tsk(10000));
+			break;
+		case 'd':
+			syslog(LOG_INFO, "#%d#dly_tsk(10000)", tskno);
+			SVC_PERROR(dly_tsk(10000));
+			break;
+		case 'y':
+			syslog(LOG_INFO, "#%d#dis_tex()", tskno);
+			SVC_PERROR(dis_tex());
+			break;
+		case 'Y':
+			syslog(LOG_INFO, "#%d#ena_tex()", tskno);
+			SVC_PERROR(ena_tex());
+			break;
+#ifdef CPUEXC1
+		case 'z':
+			syslog(LOG_NOTICE, "#%d#raise CPU exception", tskno);
+			RAISE_CPU_EXCEPTION;
+			break;
+		case 'Z':
+			SVC_PERROR(loc_cpu());
+			syslog(LOG_NOTICE, "#%d#raise CPU exception", tskno);
+			RAISE_CPU_EXCEPTION;
+			SVC_PERROR(unl_cpu());
+			break;
+#endif /* CPUEXC1 */
+		default:
+			break;
+		}
+	}
+}
+
+/*
+ *  並行して実行されるタスク用のタスク例外処理ルーチン
+ */
+void tex_routine(TEXPTN texptn, intptr_t exinf)
+{
+	volatile ulong_t	i;
+	int_t	tskno = (int_t) exinf;
+
+	syslog(LOG_NOTICE, "task%d receives exception 0x%04x.", tskno, texptn);
+	for (i = 0; i < tex_loop; i++);
+
+	if ((texptn & 0x8000U) != 0U) {
+		syslog(LOG_INFO, "#%d#ext_tsk()", tskno);
+		SVC_PERROR(ext_tsk());
+		assert(0);
+	}
+}
+
+/*
+ *  CPU例外ハンドラ
+ */
+#ifdef CPUEXC1
+
+void
+cpuexc_handler(void *p_excinf)
+{
+	ID		tskid;
+
+	syslog(LOG_NOTICE, "CPU exception handler (p_excinf = %08p).", p_excinf);
+	if (sns_ctx() != true) {
+		syslog(LOG_WARNING,
+					"sns_ctx() is not true in CPU exception handler.");
+	}
+	if (sns_dpn() != true) {
+		syslog(LOG_WARNING,
+					"sns_dpn() is not true in CPU exception handler.");
+	}
+	syslog(LOG_INFO, "sns_loc = %d sns_dsp = %d sns_tex = %d",
+									sns_loc(), sns_dsp(), sns_tex());
+	syslog(LOG_INFO, "xsns_dpn = %d xsns_xpn = %d",
+									xsns_dpn(p_excinf), xsns_xpn(p_excinf));
+
+	if (xsns_xpn(p_excinf)) {
+		syslog(LOG_NOTICE, "Sample program ends with exception.");
+		SVC_PERROR(ext_ker());
+		assert(0);
+	}
+
+	SVC_PERROR(iget_tid(&tskid));
+	SVC_PERROR(iras_tex(tskid, 0x8000U));
+}
+
+#endif /* CPUEXC1 */
+
+/*
+ *  周期ハンドラ
+ *
+ *  HIGH_PRIORITY，MID_PRIORITY，LOW_PRIORITY の各優先度のレディキュー
+ *  を回転させる．
+ */
+void cyclic_handler(intptr_t exinf)
+{
+	SVC_PERROR(irot_rdq(HIGH_PRIORITY));
+	SVC_PERROR(irot_rdq(MID_PRIORITY));
+	SVC_PERROR(irot_rdq(LOW_PRIORITY));
+}
+
+/*
+ *  アラームハンドラ
+ *
+ *  HIGH_PRIORITY，MID_PRIORITY，LOW_PRIORITY の各優先度のレディキュー
+ *  を回転させる．
+ */
+void alarm_handler(intptr_t exinf)
+{
+	SVC_PERROR(irot_rdq(HIGH_PRIORITY));
+	SVC_PERROR(irot_rdq(MID_PRIORITY));
+	SVC_PERROR(irot_rdq(LOW_PRIORITY));
+}
+
+/*
+ *  メインタスク
+ */
+void main_task(intptr_t exinf)
+{
+	char	c;
+	ID		tskid = TASK1;
+	int_t	tskno = 1;
+	ER_UINT	ercd;
+	PRI		tskpri;
+#ifndef TASK_LOOP
+	volatile ulong_t	i;
+	SYSTIM	stime1, stime2;
+#endif /* TASK_LOOP */
+#ifdef TOPPERS_SUPPORT_GET_UTM
+	SYSUTM	utime1, utime2;
+#endif /* TOPPERS_SUPPORT_GET_UTM */
+	T_CTSK	ctsk;
+	T_DTEX	dtex;
+	ID		TASK3 = -1;
+
+	SVC_PERROR(syslog_msk_log(LOG_UPTO(LOG_INFO), LOG_UPTO(LOG_EMERG)));
+	syslog(LOG_NOTICE, "Sample program starts (exinf = %d).", (int_t) exinf);
+
+	/*
+	 *  シリアルポートの初期化
+	 *
+	 *  システムログタスクと同じシリアルポートを使う場合など，シリアル
+	 *  ポートがオープン済みの場合にはここでE_OBJエラーになるが，支障は
+	 *  ない．
+	 */
+	ercd = serial_opn_por(TASK_PORTID);
+	if (ercd < 0 && MERCD(ercd) != E_OBJ) {
+		syslog(LOG_ERROR, "%s (%d) reported by `serial_opn_por'.",
+									itron_strerror(ercd), SERCD(ercd));
+	}
+	SVC_PERROR(serial_ctl_por(TASK_PORTID,
+							(IOCTL_CRLF | IOCTL_FCSND | IOCTL_FCRCV)));
+
+	/*
+ 	 *  ループ回数の設定
+	 *
+	 *  並行実行されるタスク内での空ループの回数（task_loop）は，空ルー
+	 *  プの実行時間が約0.4秒になるように設定する．この設定のために，
+	 *  LOOP_REF回の空ループの実行時間を，その前後でget_timを呼ぶことで
+	 *  測定し，その測定結果から空ループの実行時間が0.4秒になるループ回
+	 *  数を求め，task_loopに設定する．
+	 *
+	 *  LOOP_REFは，デフォルトでは1,000,000に設定しているが，想定したよ
+	 *  り遅いプロセッサでは，サンプルプログラムの実行開始に時間がかか
+	 *  りすぎるという問題を生じる．逆に想定したより速いプロセッサでは，
+	 *  LOOP_REF回の空ループの実行時間が短くなり，task_loopに設定する値
+	 *  の誤差が大きくなるという問題がある．
+	 *
+	 *  そこで，そのようなターゲットでは，target_test.hで，LOOP_REFを適
+	 *  切な値に定義するのが望ましい．
+	 *
+	 *  また，task_loopの値を固定したい場合には，その値をTASK_LOOPにマ
+	 *  クロ定義する．TASK_LOOPがマクロ定義されている場合，上記の測定を
+	 *  行わずに，TASK_LOOPに定義された値を空ループの回数とする．
+	 *
+	 * ターゲットによっては，空ループの実行時間の1回目の測定で，本来よ
+	 * りも長めになるものがある．このようなターゲットでは，MEASURE_TWICE
+	 * をマクロ定義することで，1回目の測定結果を捨てて，2回目の測定結果
+	 * を使う．
+	 *
+	 *  タスク例外処理ルーチン内での空ループの回数（tex_loop）は，
+	 *  task_loopの4分の1の値（空ループの実行時間が0.1秒になるループ回
+	 *  数）に設定する．
+	 */
+#ifdef TASK_LOOP
+	task_loop = TASK_LOOP;
+#else /* TASK_LOOP */
+
+#ifdef MEASURE_TWICE
+	task_loop = LOOP_REF;
+	SVC_PERROR(get_tim(&stime1));
+	for (i = 0; i < task_loop; i++);
+	SVC_PERROR(get_tim(&stime2));
+#endif /* MEASURE_TWICE */
+
+	task_loop = LOOP_REF;
+	SVC_PERROR(get_tim(&stime1));
+	for (i = 0; i < task_loop; i++);
+	SVC_PERROR(get_tim(&stime2));
+	task_loop = LOOP_REF * 400UL / (stime2 - stime1);
+
+#endif /* TASK_LOOP */
+	tex_loop = task_loop / 4;
+
+	/*
+ 	 *  タスクの起動
+	 */
+	SVC_PERROR(act_tsk(TASK1));
+	SVC_PERROR(act_tsk(TASK2));
+
+	/*
+ 	 *  メインループ
+	 */
+	do {
+		SVC_PERROR(serial_rea_dat(TASK_PORTID, &c, 1));
+		switch (c) {
+		case 'e':
+		case 's':
+		case 'S':
+		case 'd':
+		case 'y':
+		case 'Y':
+		case 'z':
+		case 'Z':
+			message[tskno-1] = c;
+			break;
+		case '1':
+			tskno = 1;
+			tskid = TASK1;
+			break;
+		case '2':
+			tskno = 2;
+			tskid = TASK2;
+			break;
+		case '3':
+			tskno = 3;
+			tskid = TASK3;
+			break;
+		case 'a':
+			syslog(LOG_INFO, "#act_tsk(%d)", tskno);
+			SVC_PERROR(act_tsk(tskid));
+			break;
+		case 'A':
+			syslog(LOG_INFO, "#can_act(%d)", tskno);
+			SVC_PERROR(ercd = can_act(tskid));
+			if (ercd >= 0) {
+				syslog(LOG_NOTICE, "can_act(%d) returns %d", tskno, ercd);
+			}
+			break;
+		case 't':
+			syslog(LOG_INFO, "#ter_tsk(%d)", tskno);
+			SVC_PERROR(ter_tsk(tskid));
+			break;
+		case '>':
+			syslog(LOG_INFO, "#chg_pri(%d, HIGH_PRIORITY)", tskno);
+			SVC_PERROR(chg_pri(tskid, HIGH_PRIORITY));
+			break;
+		case '=':
+			syslog(LOG_INFO, "#chg_pri(%d, MID_PRIORITY)", tskno);
+			SVC_PERROR(chg_pri(tskid, MID_PRIORITY));
+			break;
+		case '<':
+			syslog(LOG_INFO, "#chg_pri(%d, LOW_PRIORITY)", tskno);
+			SVC_PERROR(chg_pri(tskid, LOW_PRIORITY));
+			break;
+		case 'G':
+			syslog(LOG_INFO, "#get_pri(%d, &tskpri)", tskno);
+			SVC_PERROR(ercd = get_pri(tskid, &tskpri));
+			if (ercd >= 0) {
+				syslog(LOG_NOTICE, "priority of task %d is %d", tskno, tskpri);
+			}
+			break;
+		case 'w':
+			syslog(LOG_INFO, "#wup_tsk(%d)", tskno);
+			SVC_PERROR(wup_tsk(tskid));
+			break;
+		case 'W':
+			syslog(LOG_INFO, "#can_wup(%d)", tskno);
+			SVC_PERROR(ercd = can_wup(tskid));
+			if (ercd >= 0) {
+				syslog(LOG_NOTICE, "can_wup(%d) returns %d", tskno, ercd);
+			}
+			break;
+		case 'l':
+			syslog(LOG_INFO, "#rel_wai(%d)", tskno);
+			SVC_PERROR(rel_wai(tskid));
+			break;
+		case 'u':
+			syslog(LOG_INFO, "#sus_tsk(%d)", tskno);
+			SVC_PERROR(sus_tsk(tskid));
+			break;
+		case 'm':
+			syslog(LOG_INFO, "#rsm_tsk(%d)", tskno);
+			SVC_PERROR(rsm_tsk(tskid));
+			break;
+		case 'x':
+			syslog(LOG_INFO, "#ras_tex(%d, 0x0001U)", tskno);
+			SVC_PERROR(ras_tex(tskid, 0x0001U));
+			break;
+		case 'X':
+			syslog(LOG_INFO, "#ras_tex(%d, 0x0002U)", tskno);
+			SVC_PERROR(ras_tex(tskid, 0x0002U));
+			break;
+		case 'r':
+			syslog(LOG_INFO, "#rot_rdq(three priorities)");
+			SVC_PERROR(rot_rdq(HIGH_PRIORITY));
+			SVC_PERROR(rot_rdq(MID_PRIORITY));
+			SVC_PERROR(rot_rdq(LOW_PRIORITY));
+			break;
+		case 'c':
+			syslog(LOG_INFO, "#sta_cyc(1)");
+			SVC_PERROR(sta_cyc(CYCHDR1));
+			break;
+		case 'C':
+			syslog(LOG_INFO, "#stp_cyc(1)");
+			SVC_PERROR(stp_cyc(CYCHDR1));
+			break;
+		case 'b':
+			syslog(LOG_INFO, "#sta_alm(1, 5000)");
+			SVC_PERROR(sta_alm(ALMHDR1, 5000));
+			break;
+		case 'B':
+			syslog(LOG_INFO, "#stp_alm(1)");
+			SVC_PERROR(stp_alm(ALMHDR1));
+			break;
+		case '@':
+			ctsk.tskatr = TA_NULL;
+			ctsk.exinf = 3;
+			ctsk.task = task;
+			ctsk.itskpri = MID_PRIORITY;
+			ctsk.stksz = STACK_SIZE;
+			ctsk.stk = NULL;
+			SVC_PERROR(TASK3 = acre_tsk(&ctsk));
+
+			dtex.texatr = TA_NULL;
+			dtex.texrtn = tex_routine;
+			SVC_PERROR(def_tex(TASK3, &dtex));
+
+			syslog(LOG_NOTICE, "task3 is created with tskid = %d.",
+														(int_t) TASK3);
+			break;
+		case '!':
+			syslog(LOG_INFO, "#del_tsk(%d)", tskno);
+			SVC_PERROR(del_tsk(tskid));
+			break;
+
+		case 'V':
+#ifdef TOPPERS_SUPPORT_GET_UTM
+			SVC_PERROR(get_utm(&utime1));
+			SVC_PERROR(get_utm(&utime2));
+			syslog(LOG_NOTICE, "utime1 = %ld, utime2 = %ld",
+										(ulong_t) utime1, (ulong_t) utime2);
+#else /* TOPPERS_SUPPORT_GET_UTM */
+			syslog(LOG_NOTICE, "get_utm is not supported.");
+#endif /* TOPPERS_SUPPORT_GET_UTM */
+			break;
+
+		case 'v':
+			SVC_PERROR(syslog_msk_log(LOG_UPTO(LOG_INFO),
+										LOG_UPTO(LOG_EMERG)));
+			break;
+		case 'q':
+			SVC_PERROR(syslog_msk_log(LOG_UPTO(LOG_NOTICE),
+										LOG_UPTO(LOG_EMERG)));
+			break;
+
+#ifdef BIT_KERNEL
+		case ' ':
+			SVC_PERROR(loc_cpu());
+			{
+				extern ER	bit_kernel(void);
+
+				SVC_PERROR(ercd = bit_kernel());
+				if (ercd >= 0) {
+					syslog(LOG_NOTICE, "bit_kernel passed.");
+				}
+			}
+			SVC_PERROR(unl_cpu());
+			break;
+#endif /* BIT_KERNEL */
+
+		default:
+			break;
+		}
+	} while (c != '\003' && c != 'Q');
+
+	syslog(LOG_NOTICE, "Sample program ends.");
+	SVC_PERROR(ext_ker());
+	assert(0);
+}
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/sample/sample1.cfg
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/sample/sample1.cfg	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/sample/sample1.cfg	(revision 457)
@@ -0,0 +1,26 @@
+/*
+ *  $Id$
+ */
+
+/*
+ *  サンプルプログラム(1)のシステムコンフィギュレーションファイル
+ */
+INCLUDE("target_timer.cfg");
+INCLUDE("syssvc/syslog.cfg");
+INCLUDE("syssvc/banner.cfg");
+INCLUDE("syssvc/serial.cfg");
+INCLUDE("syssvc/logtask.cfg");
+
+#include "sample1.h"
+CRE_TSK(TASK1, { TA_NULL, 1, task, MID_PRIORITY, STACK_SIZE, NULL });
+CRE_TSK(TASK2, { TA_NULL, 2, task, MID_PRIORITY, STACK_SIZE, NULL });
+CRE_TSK(MAIN_TASK, { TA_ACT, 0, main_task, MAIN_PRIORITY, STACK_SIZE, NULL });
+AID_TSK(3);
+DEF_TEX(TASK1, { TA_NULL, tex_routine });
+DEF_TEX(TASK2, { TA_NULL, tex_routine });
+CRE_CYC(CYCHDR1, { TA_NULL, 0, cyclic_handler, 2000, 0 });
+CRE_ALM(ALMHDR1, { TA_NULL, 0, alarm_handler });
+#ifdef CPUEXC1
+DEF_EXC(CPUEXC1, { TA_NULL, cpuexc_handler });
+#endif /* CPUEXC1 */
+DEF_KMM({ KMM_SIZE, NULL });
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/sample/sample1.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/sample/sample1.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/sample/sample1.h	(revision 457)
@@ -0,0 +1,97 @@
+/*
+ *  TOPPERS/ASP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Advanced Standard Profile Kernel
+ *
+ *  Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
+ *                              Toyohashi Univ. of Technology, JAPAN
+ *  Copyright (C) 2004-2010 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ *
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ *
+ *  $Id$
+ */
+
+/*
+ *		サンプルプログラム(1)のヘッダファイル
+ */
+
+/*
+ *  ターゲット依存の定義
+ */
+#include "target_test.h"
+
+/*
+ *  各タスクの優先度の定義
+ */
+
+#define MAIN_PRIORITY	5		/* メインタスクの優先度 */
+								/* HIGH_PRIORITYより高くすること */
+
+#define HIGH_PRIORITY	9		/* 並行実行されるタスクの優先度 */
+#define MID_PRIORITY	10
+#define LOW_PRIORITY	11
+
+/*
+ *  ターゲットに依存する可能性のある定数の定義
+ */
+
+#ifndef TASK_PORTID
+#define	TASK_PORTID		1			/* 文字入力するシリアルポートID */
+#endif /* TASK_PORTID */
+
+#ifndef STACK_SIZE
+#define	STACK_SIZE		4096		/* タスクのスタックサイズ */
+#endif /* STACK_SIZE */
+
+#ifndef KMM_SIZE
+#define	KMM_SIZE		(STACK_SIZE * 16)	/* カーネルが割り付ける   */
+#endif /* KMM_SIZE */						/*     メモリ領域のサイズ */
+
+#ifndef LOOP_REF
+#define LOOP_REF		ULONG_C(1000000)	/* 速度計測用のループ回数 */
+#endif /* LOOP_REF */
+
+/*
+ *  関数のプロトタイプ宣言
+ */
+#ifndef TOPPERS_MACRO_ONLY
+
+extern void	task(intptr_t exinf);
+extern void	main_task(intptr_t exinf);
+extern void	tex_routine(TEXPTN texptn, intptr_t exinf);
+#ifdef CPUEXC1
+extern void	cpuexc_handler(void *p_excinf);
+#endif /* CPUEXC1 */
+extern void	cyclic_handler(intptr_t exinf);
+extern void	alarm_handler(intptr_t exinf);
+
+#endif /* TOPPERS_MACRO_ONLY */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/stmcube/Utilities/Fonts/font12.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/stmcube/Utilities/Fonts/font12.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/stmcube/Utilities/Fonts/font12.c	(revision 457)
@@ -0,0 +1,1464 @@
+/**
+  ******************************************************************************
+  * @file    Font12.c
+  * @author  MCD Application Team
+  * @version V1.0.0
+  * @date    18-February-2014
+  * @brief   This file provides text Font12 for STM32xx-EVAL's LCD driver. 
+  ******************************************************************************
+  * @attention
+  *
+  * <h2><center>&copy; COPYRIGHT(c) 2014 STMicroelectronics</center></h2>
+  *
+  * 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 STMicroelectronics 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.
+  *
+  ******************************************************************************
+  */
+
+/* Includes ------------------------------------------------------------------*/
+#include "fonts.h"
+
+/** @addtogroup Utilities
+  * @{
+  */
+  
+/** @addtogroup STM32_EVAL
+  * @{
+  */ 
+
+/** @addtogroup Common
+  * @{
+  */
+
+/** @addtogroup FONTS
+  * @brief      This file provides text Font12 for STM32xx-EVAL's LCD driver.
+  * @{
+  */  
+
+/** @defgroup FONTS_Private_Types
+  * @{
+  */ 
+/**
+  * @}
+  */ 
+
+
+/** @defgroup FONTS_Private_Defines
+  * @{
+  */
+/**
+  * @}
+  */ 
+
+
+/** @defgroup FONTS_Private_Macros
+  * @{
+  */
+/**
+  * @}
+  */ 
+  
+
+/** @defgroup FONTS_Private_Variables
+  * @{
+  */
+// 
+//  Font data for Courier New 12pt
+// 
+
+const uint8_t Font12_Table[] = 
+{
+	// @0 ' ' (7 pixels wide)
+	0x00, //        
+	0x00, //        
+	0x00, //        
+	0x00, //        
+	0x00, //        
+	0x00, //        
+	0x00, //        
+	0x00, //        
+	0x00, //        
+	0x00, //        
+	0x00, //        
+	0x00, //        
+
+	// @12 '!' (7 pixels wide)
+	0x00, //        
+	0x10, //    #   
+	0x10, //    #   
+	0x10, //    #   
+	0x10, //    #   
+	0x10, //    #   
+	0x00, //        
+	0x00, //        
+	0x10, //    #   
+	0x00, //        
+	0x00, //        
+	0x00, //        
+
+	// @24 '"' (7 pixels wide)
+	0x00, //        
+	0x6C, //  ## ## 
+	0x48, //  #  #  
+	0x48, //  #  #  
+	0x00, //        
+	0x00, //        
+	0x00, //        
+	0x00, //        
+	0x00, //        
+	0x00, //        
+	0x00, //        
+	0x00, //        
+
+	// @36 '#' (7 pixels wide)
+	0x00, //        
+	0x14, //    # # 
+	0x14, //    # # 
+	0x28, //   # #  
+	0x7C, //  ##### 
+	0x28, //   # #  
+	0x7C, //  ##### 
+	0x28, //   # #  
+	0x50, //  # #   
+	0x50, //  # #   
+	0x00, //        
+	0x00, //        
+
+	// @48 '$' (7 pixels wide)
+	0x00, //        
+	0x10, //    #   
+	0x38, //   ###  
+	0x40, //  #     
+	0x40, //  #     
+	0x38, //   ###  
+	0x48, //  #  #  
+	0x70, //  ###   
+	0x10, //    #   
+	0x10, //    #   
+	0x00, //        
+	0x00, //        
+
+	// @60 '%' (7 pixels wide)
+	0x00, //        
+	0x20, //   #    
+	0x50, //  # #   
+	0x20, //   #    
+	0x0C, //     ## 
+	0x70, //  ###   
+	0x08, //     #  
+	0x14, //    # # 
+	0x08, //     #  
+	0x00, //        
+	0x00, //        
+	0x00, //        
+
+	// @72 '&' (7 pixels wide)
+	0x00, //        
+	0x00, //        
+	0x00, //        
+	0x18, //    ##  
+	0x20, //   #    
+	0x20, //   #    
+	0x54, //  # # # 
+	0x48, //  #  #  
+	0x34, //   ## # 
+	0x00, //        
+	0x00, //        
+	0x00, //        
+
+	// @84 ''' (7 pixels wide)
+	0x00, //        
+	0x10, //    #   
+	0x10, //    #   
+	0x10, //    #   
+	0x10, //    #   
+	0x00, //        
+	0x00, //        
+	0x00, //        
+	0x00, //        
+	0x00, //        
+	0x00, //        
+	0x00, //        
+
+	// @96 '(' (7 pixels wide)
+	0x00, //        
+	0x08, //     #  
+	0x08, //     #  
+	0x10, //    #   
+	0x10, //    #   
+	0x10, //    #   
+	0x10, //    #   
+	0x10, //    #   
+	0x10, //    #   
+	0x08, //     #  
+	0x08, //     #  
+	0x00, //        
+
+	// @108 ')' (7 pixels wide)
+	0x00, //        
+	0x20, //   #    
+	0x20, //   #    
+	0x10, //    #   
+	0x10, //    #   
+	0x10, //    #   
+	0x10, //    #   
+	0x10, //    #   
+	0x10, //    #   
+	0x20, //   #    
+	0x20, //   #    
+	0x00, //        
+
+	// @120 '*' (7 pixels wide)
+	0x00, //        
+	0x10, //    #   
+	0x7C, //  ##### 
+	0x10, //    #   
+	0x28, //   # #  
+	0x28, //   # #  
+	0x00, //        
+	0x00, //        
+	0x00, //        
+	0x00, //        
+	0x00, //        
+	0x00, //        
+
+	// @132 '+' (7 pixels wide)
+	0x00, //        
+	0x00, //        
+	0x10, //    #   
+	0x10, //    #   
+	0x10, //    #   
+	0xFE, // #######
+	0x10, //    #   
+	0x10, //    #   
+	0x10, //    #   
+	0x00, //        
+	0x00, //        
+	0x00, //        
+
+	// @144 ',' (7 pixels wide)
+	0x00, //        
+	0x00, //        
+	0x00, //        
+	0x00, //        
+	0x00, //        
+	0x00, //        
+	0x00, //        
+	0x18, //    ##  
+	0x10, //    #   
+	0x30, //   ##   
+	0x20, //   #    
+	0x00, //        
+
+	// @156 '-' (7 pixels wide)
+	0x00, //        
+	0x00, //        
+	0x00, //        
+	0x00, //        
+	0x00, //        
+	0x7C, //  ##### 
+	0x00, //        
+	0x00, //        
+	0x00, //        
+	0x00, //        
+	0x00, //        
+	0x00, //        
+
+	// @168 '.' (7 pixels wide)
+	0x00, //        
+	0x00, //        
+	0x00, //        
+	0x00, //        
+	0x00, //        
+	0x00, //        
+	0x00, //        
+	0x30, //   ##   
+	0x30, //   ##   
+	0x00, //        
+	0x00, //        
+	0x00, //        
+
+	// @180 '/' (7 pixels wide)
+	0x00, //        
+	0x04, //      # 
+	0x04, //      # 
+	0x08, //     #  
+	0x08, //     #  
+	0x10, //    #   
+	0x10, //    #   
+	0x20, //   #    
+	0x20, //   #    
+	0x40, //  #     
+	0x00, //        
+	0x00, //        
+
+	// @192 '0' (7 pixels wide)
+	0x00, //        
+	0x38, //   ###  
+	0x44, //  #   # 
+	0x44, //  #   # 
+	0x44, //  #   # 
+	0x44, //  #   # 
+	0x44, //  #   # 
+	0x44, //  #   # 
+	0x38, //   ###  
+	0x00, //        
+	0x00, //        
+	0x00, //        
+
+	// @204 '1' (7 pixels wide)
+	0x00, //        
+	0x30, //   ##   
+	0x10, //    #   
+	0x10, //    #   
+	0x10, //    #   
+	0x10, //    #   
+	0x10, //    #   
+	0x10, //    #   
+	0x7C, //  ##### 
+	0x00, //        
+	0x00, //        
+	0x00, //        
+
+	// @216 '2' (7 pixels wide)
+	0x00, //        
+	0x38, //   ###  
+	0x44, //  #   # 
+	0x04, //      # 
+	0x08, //     #  
+	0x10, //    #   
+	0x20, //   #    
+	0x44, //  #   # 
+	0x7C, //  ##### 
+	0x00, //        
+	0x00, //        
+	0x00, //        
+
+	// @228 '3' (7 pixels wide)
+	0x00, //        
+	0x38, //   ###  
+	0x44, //  #   # 
+	0x04, //      # 
+	0x18, //    ##  
+	0x04, //      # 
+	0x04, //      # 
+	0x44, //  #   # 
+	0x38, //   ###  
+	0x00, //        
+	0x00, //        
+	0x00, //        
+
+	// @240 '4' (7 pixels wide)
+	0x00, //        
+	0x0C, //     ## 
+	0x14, //    # # 
+	0x14, //    # # 
+	0x24, //   #  # 
+	0x44, //  #   # 
+	0x7E, //  ######
+	0x04, //      # 
+	0x0E, //     ###
+	0x00, //        
+	0x00, //        
+	0x00, //        
+
+	// @252 '5' (7 pixels wide)
+	0x00, //        
+	0x3C, //   #### 
+	0x20, //   #    
+	0x20, //   #    
+	0x38, //   ###  
+	0x04, //      # 
+	0x04, //      # 
+	0x44, //  #   # 
+	0x38, //   ###  
+	0x00, //        
+	0x00, //        
+	0x00, //        
+
+	// @264 '6' (7 pixels wide)
+	0x00, //        
+	0x1C, //    ### 
+	0x20, //   #    
+	0x40, //  #     
+	0x78, //  ####  
+	0x44, //  #   # 
+	0x44, //  #   # 
+	0x44, //  #   # 
+	0x38, //   ###  
+	0x00, //        
+	0x00, //        
+	0x00, //        
+
+	// @276 '7' (7 pixels wide)
+	0x00, //        
+	0x7C, //  ##### 
+	0x44, //  #   # 
+	0x04, //      # 
+	0x08, //     #  
+	0x08, //     #  
+	0x08, //     #  
+	0x10, //    #   
+	0x10, //    #   
+	0x00, //        
+	0x00, //        
+	0x00, //        
+
+	// @288 '8' (7 pixels wide)
+	0x00, //        
+	0x38, //   ###  
+	0x44, //  #   # 
+	0x44, //  #   # 
+	0x38, //   ###  
+	0x44, //  #   # 
+	0x44, //  #   # 
+	0x44, //  #   # 
+	0x38, //   ###  
+	0x00, //        
+	0x00, //        
+	0x00, //        
+
+	// @300 '9' (7 pixels wide)
+	0x00, //        
+	0x38, //   ###  
+	0x44, //  #   # 
+	0x44, //  #   # 
+	0x44, //  #   # 
+	0x3C, //   #### 
+	0x04, //      # 
+	0x08, //     #  
+	0x70, //  ###   
+	0x00, //        
+	0x00, //        
+	0x00, //        
+
+	// @312 ':' (7 pixels wide)
+	0x00, //        
+	0x00, //        
+	0x00, //        
+	0x30, //   ##   
+	0x30, //   ##   
+	0x00, //        
+	0x00, //        
+	0x30, //   ##   
+	0x30, //   ##   
+	0x00, //        
+	0x00, //        
+	0x00, //        
+
+	// @324 ';' (7 pixels wide)
+	0x00, //        
+	0x00, //        
+	0x00, //        
+	0x18, //    ##  
+	0x18, //    ##  
+	0x00, //        
+	0x00, //        
+	0x18, //    ##  
+	0x30, //   ##   
+	0x20, //   #    
+	0x00, //        
+	0x00, //        
+
+	// @336 '<' (7 pixels wide)
+	0x00, //        
+	0x00, //        
+	0x0C, //     ## 
+	0x10, //    #   
+	0x60, //  ##    
+	0x80, // #      
+	0x60, //  ##    
+	0x10, //    #   
+	0x0C, //     ## 
+	0x00, //        
+	0x00, //        
+	0x00, //        
+
+	// @348 '=' (7 pixels wide)
+	0x00, //        
+	0x00, //        
+	0x00, //        
+	0x00, //        
+	0x7C, //  ##### 
+	0x00, //        
+	0x7C, //  ##### 
+	0x00, //        
+	0x00, //        
+	0x00, //        
+	0x00, //        
+	0x00, //        
+
+	// @360 '>' (7 pixels wide)
+	0x00, //        
+	0x00, //        
+	0xC0, // ##     
+	0x20, //   #    
+	0x18, //    ##  
+	0x04, //      # 
+	0x18, //    ##  
+	0x20, //   #    
+	0xC0, // ##     
+	0x00, //        
+	0x00, //        
+	0x00, //        
+
+	// @372 '?' (7 pixels wide)
+	0x00, //        
+	0x00, //        
+	0x18, //    ##  
+	0x24, //   #  # 
+	0x04, //      # 
+	0x08, //     #  
+	0x10, //    #   
+	0x00, //        
+	0x30, //   ##   
+	0x00, //        
+	0x00, //        
+	0x00, //        
+
+	// @384 '@' (7 pixels wide)
+	0x38, //   ###  
+	0x44, //  #   # 
+	0x44, //  #   # 
+	0x4C, //  #  ## 
+	0x54, //  # # # 
+	0x54, //  # # # 
+	0x4C, //  #  ## 
+	0x40, //  #     
+	0x44, //  #   # 
+	0x38, //   ###  
+	0x00, //        
+	0x00, //        
+
+	// @396 'A' (7 pixels wide)
+	0x00, //        
+	0x30, //   ##   
+	0x10, //    #   
+	0x28, //   # #  
+	0x28, //   # #  
+	0x28, //   # #  
+	0x7C, //  ##### 
+	0x44, //  #   # 
+	0xEE, // ### ###
+	0x00, //        
+	0x00, //        
+	0x00, //        
+
+	// @408 'B' (7 pixels wide)
+	0x00, //        
+	0xF8, // #####  
+	0x44, //  #   # 
+	0x44, //  #   # 
+	0x78, //  ####  
+	0x44, //  #   # 
+	0x44, //  #   # 
+	0x44, //  #   # 
+	0xF8, // #####  
+	0x00, //        
+	0x00, //        
+	0x00, //        
+
+	// @420 'C' (7 pixels wide)
+	0x00, //        
+	0x3C, //   #### 
+	0x44, //  #   # 
+	0x40, //  #     
+	0x40, //  #     
+	0x40, //  #     
+	0x40, //  #     
+	0x44, //  #   # 
+	0x38, //   ###  
+	0x00, //        
+	0x00, //        
+	0x00, //        
+
+	// @432 'D' (7 pixels wide)
+	0x00, //        
+	0xF0, // ####   
+	0x48, //  #  #  
+	0x44, //  #   # 
+	0x44, //  #   # 
+	0x44, //  #   # 
+	0x44, //  #   # 
+	0x48, //  #  #  
+	0xF0, // ####   
+	0x00, //        
+	0x00, //        
+	0x00, //        
+
+	// @444 'E' (7 pixels wide)
+	0x00, //        
+	0xFC, // ###### 
+	0x44, //  #   # 
+	0x50, //  # #   
+	0x70, //  ###   
+	0x50, //  # #   
+	0x40, //  #     
+	0x44, //  #   # 
+	0xFC, // ###### 
+	0x00, //        
+	0x00, //        
+	0x00, //        
+
+	// @456 'F' (7 pixels wide)
+	0x00, //        
+	0x7E, //  ######
+	0x22, //   #   #
+	0x28, //   # #  
+	0x38, //   ###  
+	0x28, //   # #  
+	0x20, //   #    
+	0x20, //   #    
+	0x70, //  ###   
+	0x00, //        
+	0x00, //        
+	0x00, //        
+
+	// @468 'G' (7 pixels wide)
+	0x00, //        
+	0x3C, //   #### 
+	0x44, //  #   # 
+	0x40, //  #     
+	0x40, //  #     
+	0x4E, //  #  ###
+	0x44, //  #   # 
+	0x44, //  #   # 
+	0x38, //   ###  
+	0x00, //        
+	0x00, //        
+	0x00, //        
+
+	// @480 'H' (7 pixels wide)
+	0x00, //        
+	0xEE, // ### ###
+	0x44, //  #   # 
+	0x44, //  #   # 
+	0x7C, //  ##### 
+	0x44, //  #   # 
+	0x44, //  #   # 
+	0x44, //  #   # 
+	0xEE, // ### ###
+	0x00, //        
+	0x00, //        
+	0x00, //        
+
+	// @492 'I' (7 pixels wide)
+	0x00, //        
+	0x7C, //  ##### 
+	0x10, //    #   
+	0x10, //    #   
+	0x10, //    #   
+	0x10, //    #   
+	0x10, //    #   
+	0x10, //    #   
+	0x7C, //  ##### 
+	0x00, //        
+	0x00, //        
+	0x00, //        
+
+	// @504 'J' (7 pixels wide)
+	0x00, //        
+	0x3C, //   #### 
+	0x08, //     #  
+	0x08, //     #  
+	0x08, //     #  
+	0x48, //  #  #  
+	0x48, //  #  #  
+	0x48, //  #  #  
+	0x30, //   ##   
+	0x00, //        
+	0x00, //        
+	0x00, //        
+
+	// @516 'K' (7 pixels wide)
+	0x00, //        
+	0xEE, // ### ###
+	0x44, //  #   # 
+	0x48, //  #  #  
+	0x50, //  # #   
+	0x70, //  ###   
+	0x48, //  #  #  
+	0x44, //  #   # 
+	0xE6, // ###  ##
+	0x00, //        
+	0x00, //        
+	0x00, //        
+
+	// @528 'L' (7 pixels wide)
+	0x00, //        
+	0x70, //  ###   
+	0x20, //   #    
+	0x20, //   #    
+	0x20, //   #    
+	0x20, //   #    
+	0x24, //   #  # 
+	0x24, //   #  # 
+	0x7C, //  ##### 
+	0x00, //        
+	0x00, //        
+	0x00, //        
+
+	// @540 'M' (7 pixels wide)
+	0x00, //        
+	0xEE, // ### ###
+	0x6C, //  ## ## 
+	0x6C, //  ## ## 
+	0x54, //  # # # 
+	0x54, //  # # # 
+	0x44, //  #   # 
+	0x44, //  #   # 
+	0xEE, // ### ###
+	0x00, //        
+	0x00, //        
+	0x00, //        
+
+	// @552 'N' (7 pixels wide)
+	0x00, //        
+	0xEE, // ### ###
+	0x64, //  ##  # 
+	0x64, //  ##  # 
+	0x54, //  # # # 
+	0x54, //  # # # 
+	0x54, //  # # # 
+	0x4C, //  #  ## 
+	0xEC, // ### ## 
+	0x00, //        
+	0x00, //        
+	0x00, //        
+
+	// @564 'O' (7 pixels wide)
+	0x00, //        
+	0x38, //   ###  
+	0x44, //  #   # 
+	0x44, //  #   # 
+	0x44, //  #   # 
+	0x44, //  #   # 
+	0x44, //  #   # 
+	0x44, //  #   # 
+	0x38, //   ###  
+	0x00, //        
+	0x00, //        
+	0x00, //        
+
+	// @576 'P' (7 pixels wide)
+	0x00, //        
+	0x78, //  ####  
+	0x24, //   #  # 
+	0x24, //   #  # 
+	0x24, //   #  # 
+	0x38, //   ###  
+	0x20, //   #    
+	0x20, //   #    
+	0x70, //  ###   
+	0x00, //        
+	0x00, //        
+	0x00, //        
+
+	// @588 'Q' (7 pixels wide)
+	0x00, //        
+	0x38, //   ###  
+	0x44, //  #   # 
+	0x44, //  #   # 
+	0x44, //  #   # 
+	0x44, //  #   # 
+	0x44, //  #   # 
+	0x44, //  #   # 
+	0x38, //   ###  
+	0x1C, //    ### 
+	0x00, //        
+	0x00, //        
+
+	// @600 'R' (7 pixels wide)
+	0x00, //        
+	0xF8, // #####  
+	0x44, //  #   # 
+	0x44, //  #   # 
+	0x44, //  #   # 
+	0x78, //  ####  
+	0x48, //  #  #  
+	0x44, //  #   # 
+	0xE2, // ###   #
+	0x00, //        
+	0x00, //        
+	0x00, //        
+
+	// @612 'S' (7 pixels wide)
+	0x00, //        
+	0x34, //   ## # 
+	0x4C, //  #  ## 
+	0x40, //  #     
+	0x38, //   ###  
+	0x04, //      # 
+	0x04, //      # 
+	0x64, //  ##  # 
+	0x58, //  # ##  
+	0x00, //        
+	0x00, //        
+	0x00, //        
+
+	// @624 'T' (7 pixels wide)
+	0x00, //        
+	0xFE, // #######
+	0x92, // #  #  #
+	0x10, //    #   
+	0x10, //    #   
+	0x10, //    #   
+	0x10, //    #   
+	0x10, //    #   
+	0x38, //   ###  
+	0x00, //        
+	0x00, //        
+	0x00, //        
+
+	// @636 'U' (7 pixels wide)
+	0x00, //        
+	0xEE, // ### ###
+	0x44, //  #   # 
+	0x44, //  #   # 
+	0x44, //  #   # 
+	0x44, //  #   # 
+	0x44, //  #   # 
+	0x44, //  #   # 
+	0x38, //   ###  
+	0x00, //        
+	0x00, //        
+	0x00, //        
+
+	// @648 'V' (7 pixels wide)
+	0x00, //        
+	0xEE, // ### ###
+	0x44, //  #   # 
+	0x44, //  #   # 
+	0x28, //   # #  
+	0x28, //   # #  
+	0x28, //   # #  
+	0x10, //    #   
+	0x10, //    #   
+	0x00, //        
+	0x00, //        
+	0x00, //        
+
+	// @660 'W' (7 pixels wide)
+	0x00, //        
+	0xEE, // ### ###
+	0x44, //  #   # 
+	0x44, //  #   # 
+	0x54, //  # # # 
+	0x54, //  # # # 
+	0x54, //  # # # 
+	0x54, //  # # # 
+	0x28, //   # #  
+	0x00, //        
+	0x00, //        
+	0x00, //        
+
+	// @672 'X' (7 pixels wide)
+	0x00, //        
+	0xC6, // ##   ##
+	0x44, //  #   # 
+	0x28, //   # #  
+	0x10, //    #   
+	0x10, //    #   
+	0x28, //   # #  
+	0x44, //  #   # 
+	0xC6, // ##   ##
+	0x00, //        
+	0x00, //        
+	0x00, //        
+
+	// @684 'Y' (7 pixels wide)
+	0x00, //        
+	0xEE, // ### ###
+	0x44, //  #   # 
+	0x28, //   # #  
+	0x28, //   # #  
+	0x10, //    #   
+	0x10, //    #   
+	0x10, //    #   
+	0x38, //   ###  
+	0x00, //        
+	0x00, //        
+	0x00, //        
+
+	// @696 'Z' (7 pixels wide)
+	0x00, //        
+	0x7C, //  ##### 
+	0x44, //  #   # 
+	0x08, //     #  
+	0x10, //    #   
+	0x10, //    #   
+	0x20, //   #    
+	0x44, //  #   # 
+	0x7C, //  ##### 
+	0x00, //        
+	0x00, //        
+	0x00, //        
+
+	// @708 '[' (7 pixels wide)
+	0x00, //        
+	0x38, //   ###  
+	0x20, //   #    
+	0x20, //   #    
+	0x20, //   #    
+	0x20, //   #    
+	0x20, //   #    
+	0x20, //   #    
+	0x20, //   #    
+	0x20, //   #    
+	0x38, //   ###  
+	0x00, //        
+
+	// @720 '\' (7 pixels wide)
+	0x00, //        
+	0x40, //  #     
+	0x20, //   #    
+	0x20, //   #    
+	0x20, //   #    
+	0x10, //    #   
+	0x10, //    #   
+	0x08, //     #  
+	0x08, //     #  
+	0x08, //     #  
+	0x00, //        
+	0x00, //        
+
+	// @732 ']' (7 pixels wide)
+	0x00, //        
+	0x38, //   ###  
+	0x08, //     #  
+	0x08, //     #  
+	0x08, //     #  
+	0x08, //     #  
+	0x08, //     #  
+	0x08, //     #  
+	0x08, //     #  
+	0x08, //     #  
+	0x38, //   ###  
+	0x00, //        
+
+	// @744 '^' (7 pixels wide)
+	0x00, //        
+	0x10, //    #   
+	0x10, //    #   
+	0x28, //   # #  
+	0x44, //  #   # 
+	0x00, //        
+	0x00, //        
+	0x00, //        
+	0x00, //        
+	0x00, //        
+	0x00, //        
+	0x00, //        
+
+	// @756 '_' (7 pixels wide)
+	0x00, //        
+	0x00, //        
+	0x00, //        
+	0x00, //        
+	0x00, //        
+	0x00, //        
+	0x00, //        
+	0x00, //        
+	0x00, //        
+	0x00, //        
+	0x00, //        
+	0xFE, // #######
+
+	// @768 '`' (7 pixels wide)
+	0x00, //        
+	0x10, //    #   
+	0x08, //     #  
+	0x00, //        
+	0x00, //        
+	0x00, //        
+	0x00, //        
+	0x00, //        
+	0x00, //        
+	0x00, //        
+	0x00, //        
+	0x00, //        
+
+	// @780 'a' (7 pixels wide)
+	0x00, //        
+	0x00, //        
+	0x00, //        
+	0x38, //   ###  
+	0x44, //  #   # 
+	0x3C, //   #### 
+	0x44, //  #   # 
+	0x44, //  #   # 
+	0x3E, //   #####
+	0x00, //        
+	0x00, //        
+	0x00, //        
+
+	// @792 'b' (7 pixels wide)
+	0x00, //        
+	0xC0, // ##     
+	0x40, //  #     
+	0x58, //  # ##  
+	0x64, //  ##  # 
+	0x44, //  #   # 
+	0x44, //  #   # 
+	0x44, //  #   # 
+	0xF8, // #####  
+	0x00, //        
+	0x00, //        
+	0x00, //        
+
+	// @804 'c' (7 pixels wide)
+	0x00, //        
+	0x00, //        
+	0x00, //        
+	0x3C, //   #### 
+	0x44, //  #   # 
+	0x40, //  #     
+	0x40, //  #     
+	0x44, //  #   # 
+	0x38, //   ###  
+	0x00, //        
+	0x00, //        
+	0x00, //        
+
+	// @816 'd' (7 pixels wide)
+	0x00, //        
+	0x0C, //     ## 
+	0x04, //      # 
+	0x34, //   ## # 
+	0x4C, //  #  ## 
+	0x44, //  #   # 
+	0x44, //  #   # 
+	0x44, //  #   # 
+	0x3E, //   #####
+	0x00, //        
+	0x00, //        
+	0x00, //        
+
+	// @828 'e' (7 pixels wide)
+	0x00, //        
+	0x00, //        
+	0x00, //        
+	0x38, //   ###  
+	0x44, //  #   # 
+	0x7C, //  ##### 
+	0x40, //  #     
+	0x40, //  #     
+	0x3C, //   #### 
+	0x00, //        
+	0x00, //        
+	0x00, //        
+
+	// @840 'f' (7 pixels wide)
+	0x00, //        
+	0x1C, //    ### 
+	0x20, //   #    
+	0x7C, //  ##### 
+	0x20, //   #    
+	0x20, //   #    
+	0x20, //   #    
+	0x20, //   #    
+	0x7C, //  ##### 
+	0x00, //        
+	0x00, //        
+	0x00, //        
+
+	// @852 'g' (7 pixels wide)
+	0x00, //        
+	0x00, //        
+	0x00, //        
+	0x36, //   ## ##
+	0x4C, //  #  ## 
+	0x44, //  #   # 
+	0x44, //  #   # 
+	0x44, //  #   # 
+	0x3C, //   #### 
+	0x04, //      # 
+	0x38, //   ###  
+	0x00, //        
+
+	// @864 'h' (7 pixels wide)
+	0x00, //        
+	0xC0, // ##     
+	0x40, //  #     
+	0x58, //  # ##  
+	0x64, //  ##  # 
+	0x44, //  #   # 
+	0x44, //  #   # 
+	0x44, //  #   # 
+	0xEE, // ### ###
+	0x00, //        
+	0x00, //        
+	0x00, //        
+
+	// @876 'i' (7 pixels wide)
+	0x00, //        
+	0x10, //    #   
+	0x00, //        
+	0x70, //  ###   
+	0x10, //    #   
+	0x10, //    #   
+	0x10, //    #   
+	0x10, //    #   
+	0x7C, //  ##### 
+	0x00, //        
+	0x00, //        
+	0x00, //        
+
+	// @888 'j' (7 pixels wide)
+	0x00, //        
+	0x10, //    #   
+	0x00, //        
+	0x78, //  ####  
+	0x08, //     #  
+	0x08, //     #  
+	0x08, //     #  
+	0x08, //     #  
+	0x08, //     #  
+	0x08, //     #  
+	0x70, //  ###   
+	0x00, //        
+
+	// @900 'k' (7 pixels wide)
+	0x00, //        
+	0xC0, // ##     
+	0x40, //  #     
+	0x5C, //  # ### 
+	0x48, //  #  #  
+	0x70, //  ###   
+	0x50, //  # #   
+	0x48, //  #  #  
+	0xDC, // ## ### 
+	0x00, //        
+	0x00, //        
+	0x00, //        
+
+	// @912 'l' (7 pixels wide)
+	0x00, //        
+	0x30, //   ##   
+	0x10, //    #   
+	0x10, //    #   
+	0x10, //    #   
+	0x10, //    #   
+	0x10, //    #   
+	0x10, //    #   
+	0x7C, //  ##### 
+	0x00, //        
+	0x00, //        
+	0x00, //        
+
+	// @924 'm' (7 pixels wide)
+	0x00, //        
+	0x00, //        
+	0x00, //        
+	0xE8, // ### #  
+	0x54, //  # # # 
+	0x54, //  # # # 
+	0x54, //  # # # 
+	0x54, //  # # # 
+	0xFE, // #######
+	0x00, //        
+	0x00, //        
+	0x00, //        
+
+	// @936 'n' (7 pixels wide)
+	0x00, //        
+	0x00, //        
+	0x00, //        
+	0xD8, // ## ##  
+	0x64, //  ##  # 
+	0x44, //  #   # 
+	0x44, //  #   # 
+	0x44, //  #   # 
+	0xEE, // ### ###
+	0x00, //        
+	0x00, //        
+	0x00, //        
+
+	// @948 'o' (7 pixels wide)
+	0x00, //        
+	0x00, //        
+	0x00, //        
+	0x38, //   ###  
+	0x44, //  #   # 
+	0x44, //  #   # 
+	0x44, //  #   # 
+	0x44, //  #   # 
+	0x38, //   ###  
+	0x00, //        
+	0x00, //        
+	0x00, //        
+
+	// @960 'p' (7 pixels wide)
+	0x00, //        
+	0x00, //        
+	0x00, //        
+	0xD8, // ## ##  
+	0x64, //  ##  # 
+	0x44, //  #   # 
+	0x44, //  #   # 
+	0x44, //  #   # 
+	0x78, //  ####  
+	0x40, //  #     
+	0xE0, // ###    
+	0x00, //        
+
+	// @972 'q' (7 pixels wide)
+	0x00, //        
+	0x00, //        
+	0x00, //        
+	0x36, //   ## ##
+	0x4C, //  #  ## 
+	0x44, //  #   # 
+	0x44, //  #   # 
+	0x44, //  #   # 
+	0x3C, //   #### 
+	0x04, //      # 
+	0x0E, //     ###
+	0x00, //        
+
+	// @984 'r' (7 pixels wide)
+	0x00, //        
+	0x00, //        
+	0x00, //        
+	0x6C, //  ## ## 
+	0x30, //   ##   
+	0x20, //   #    
+	0x20, //   #    
+	0x20, //   #    
+	0x7C, //  ##### 
+	0x00, //        
+	0x00, //        
+	0x00, //        
+
+	// @996 's' (7 pixels wide)
+	0x00, //        
+	0x00, //        
+	0x00, //        
+	0x3C, //   #### 
+	0x44, //  #   # 
+	0x38, //   ###  
+	0x04, //      # 
+	0x44, //  #   # 
+	0x78, //  ####  
+	0x00, //        
+	0x00, //        
+	0x00, //        
+
+	// @1008 't' (7 pixels wide)
+	0x00, //        
+	0x00, //        
+	0x20, //   #    
+	0x7C, //  ##### 
+	0x20, //   #    
+	0x20, //   #    
+	0x20, //   #    
+	0x22, //   #   #
+	0x1C, //    ### 
+	0x00, //        
+	0x00, //        
+	0x00, //        
+
+	// @1020 'u' (7 pixels wide)
+	0x00, //        
+	0x00, //        
+	0x00, //        
+	0xCC, // ##  ## 
+	0x44, //  #   # 
+	0x44, //  #   # 
+	0x44, //  #   # 
+	0x4C, //  #  ## 
+	0x36, //   ## ##
+	0x00, //        
+	0x00, //        
+	0x00, //        
+
+	// @1032 'v' (7 pixels wide)
+	0x00, //        
+	0x00, //        
+	0x00, //        
+	0xEE, // ### ###
+	0x44, //  #   # 
+	0x44, //  #   # 
+	0x28, //   # #  
+	0x28, //   # #  
+	0x10, //    #   
+	0x00, //        
+	0x00, //        
+	0x00, //        
+
+	// @1044 'w' (7 pixels wide)
+	0x00, //        
+	0x00, //        
+	0x00, //        
+	0xEE, // ### ###
+	0x44, //  #   # 
+	0x54, //  # # # 
+	0x54, //  # # # 
+	0x54, //  # # # 
+	0x28, //   # #  
+	0x00, //        
+	0x00, //        
+	0x00, //        
+
+	// @1056 'x' (7 pixels wide)
+	0x00, //        
+	0x00, //        
+	0x00, //        
+	0xCC, // ##  ## 
+	0x48, //  #  #  
+	0x30, //   ##   
+	0x30, //   ##   
+	0x48, //  #  #  
+	0xCC, // ##  ## 
+	0x00, //        
+	0x00, //        
+	0x00, //        
+
+	// @1068 'y' (7 pixels wide)
+	0x00, //        
+	0x00, //        
+	0x00, //        
+	0xEE, // ### ###
+	0x44, //  #   # 
+	0x24, //   #  # 
+	0x28, //   # #  
+	0x18, //    ##  
+	0x10, //    #   
+	0x10, //    #   
+	0x78, //  ####  
+	0x00, //        
+
+	// @1080 'z' (7 pixels wide)
+	0x00, //        
+	0x00, //        
+	0x00, //        
+	0x7C, //  ##### 
+	0x48, //  #  #  
+	0x10, //    #   
+	0x20, //   #    
+	0x44, //  #   # 
+	0x7C, //  ##### 
+	0x00, //        
+	0x00, //        
+	0x00, //        
+
+	// @1092 '{' (7 pixels wide)
+	0x00, //        
+	0x08, //     #  
+	0x10, //    #   
+	0x10, //    #   
+	0x10, //    #   
+	0x10, //    #   
+	0x20, //   #    
+	0x10, //    #   
+	0x10, //    #   
+	0x10, //    #   
+	0x08, //     #  
+	0x00, //        
+
+	// @1104 '|' (7 pixels wide)
+	0x00, //        
+	0x10, //    #   
+	0x10, //    #   
+	0x10, //    #   
+	0x10, //    #   
+	0x10, //    #   
+	0x10, //    #   
+	0x10, //    #   
+	0x10, //    #   
+	0x10, //    #   
+	0x00, //        
+	0x00, //        
+
+	// @1116 '}' (7 pixels wide)
+	0x00, //        
+	0x20, //   #    
+	0x10, //    #   
+	0x10, //    #   
+	0x10, //    #   
+	0x10, //    #   
+	0x08, //     #  
+	0x10, //    #   
+	0x10, //    #   
+	0x10, //    #   
+	0x20, //   #    
+	0x00, //        
+
+	// @1128 '~' (7 pixels wide)
+	0x00, //        
+	0x00, //        
+	0x00, //        
+	0x00, //        
+	0x00, //        
+	0x24, //   #  # 
+	0x58, //  # ##  
+	0x00, //        
+	0x00, //        
+	0x00, //        
+	0x00, //        
+	0x00, //        
+};
+
+sFONT Font12 = {
+  Font12_Table,
+  7, /* Width */
+  12, /* Height */
+};
+
+/**
+  * @}
+  */ 
+
+
+/** @defgroup FONTS_Private_Function_Prototypes
+  * @{
+  */ 
+/**
+  * @}
+  */ 
+
+
+/** @defgroup FONTS_Private_Functions
+  * @{
+  */
+    
+/**
+  * @}
+  */
+  
+/**
+  * @}
+  */ 
+
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */  
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/stmcube/Utilities/Fonts/font16.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/stmcube/Utilities/Fonts/font16.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/stmcube/Utilities/Fonts/font16.c	(revision 457)
@@ -0,0 +1,1844 @@
+/**
+  ******************************************************************************
+  * @file    font16.c
+  * @author  MCD Application Team
+  * @version V1.0.0
+  * @date    18-February-2014
+  * @brief   This file provides text font16 for STM32xx-EVAL's LCD driver. 
+  ******************************************************************************
+  * @attention
+  *
+  * <h2><center>&copy; COPYRIGHT(c) 2014 STMicroelectronics</center></h2>
+  *
+  * 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 STMicroelectronics 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.
+  *
+  ******************************************************************************
+  */
+
+/* Includes ------------------------------------------------------------------*/
+#include "fonts.h"
+
+/** @addtogroup Utilities
+  * @{
+  */
+  
+/** @addtogroup STM32_EVAL
+  * @{
+  */ 
+
+/** @addtogroup Common
+  * @{
+  */
+
+/** @addtogroup FONTS
+  * @brief      This file provides text font16 for STM32xx-EVAL's LCD driver.
+  * @{
+  */  
+
+/** @defgroup FONTS_Private_Types
+  * @{
+  */ 
+/**
+  * @}
+  */ 
+
+
+/** @defgroup FONTS_Private_Defines
+  * @{
+  */
+/**
+  * @}
+  */ 
+
+
+/** @defgroup FONTS_Private_Macros
+  * @{
+  */
+/**
+  * @}
+  */ 
+  
+
+/** @defgroup FONTS_Private_Variables
+  * @{
+  */
+// 
+//  Font data for Courier New 12pt
+// 
+
+const uint8_t Font16_Table[] = 
+{
+	// @0 ' ' (11 pixels wide)
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+
+	// @32 '!' (11 pixels wide)
+	0x00, 0x00, //            
+	0x0C, 0x00, //     ##     
+	0x0C, 0x00, //     ##     
+	0x0C, 0x00, //     ##     
+	0x0C, 0x00, //     ##     
+	0x0C, 0x00, //     ##     
+	0x0C, 0x00, //     ##     
+	0x0C, 0x00, //     ##     
+	0x0C, 0x00, //     ##     
+	0x00, 0x00, //            
+	0x0C, 0x00, //     ##     
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+
+	// @64 '"' (11 pixels wide)
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x1D, 0xC0, //    ### ### 
+	0x1D, 0xC0, //    ### ### 
+	0x08, 0x80, //     #   #  
+	0x08, 0x80, //     #   #  
+	0x08, 0x80, //     #   #  
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+
+	// @96 '#' (11 pixels wide)
+	0x00, 0x00, //            
+	0x0D, 0x80, //     ## ##  
+	0x0D, 0x80, //     ## ##  
+	0x0D, 0x80, //     ## ##  
+	0x0D, 0x80, //     ## ##  
+	0x3F, 0xC0, //   ######## 
+	0x1B, 0x00, //    ## ##   
+	0x3F, 0xC0, //   ######## 
+	0x1B, 0x00, //    ## ##   
+	0x1B, 0x00, //    ## ##   
+	0x1B, 0x00, //    ## ##   
+	0x1B, 0x00, //    ## ##   
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+
+	// @128 '$' (11 pixels wide)
+	0x04, 0x00, //      #     
+	0x1F, 0x80, //    ######  
+	0x31, 0x80, //   ##   ##  
+	0x31, 0x80, //   ##   ##  
+	0x38, 0x00, //   ###      
+	0x1E, 0x00, //    ####    
+	0x0F, 0x00, //     ####   
+	0x03, 0x80, //       ###  
+	0x31, 0x80, //   ##   ##  
+	0x31, 0x80, //   ##   ##  
+	0x3F, 0x00, //   ######   
+	0x04, 0x00, //      #     
+	0x04, 0x00, //      #     
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+
+	// @160 '%' (11 pixels wide)
+	0x00, 0x00, //            
+	0x18, 0x00, //    ##      
+	0x24, 0x00, //   #  #     
+	0x24, 0x00, //   #  #     
+	0x18, 0xC0, //    ##   ## 
+	0x07, 0x80, //      ####  
+	0x1E, 0x00, //    ####    
+	0x31, 0x80, //   ##   ##  
+	0x02, 0x40, //       #  # 
+	0x02, 0x40, //       #  # 
+	0x01, 0x80, //        ##  
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+
+	// @192 '&' (11 pixels wide)
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x0F, 0x00, //     ####   
+	0x18, 0x00, //    ##      
+	0x18, 0x00, //    ##      
+	0x18, 0x00, //    ##      
+	0x0C, 0x00, //     ##     
+	0x1D, 0x80, //    ### ##  
+	0x37, 0x00, //   ## ###   
+	0x33, 0x00, //   ##  ##   
+	0x1D, 0x80, //    ### ##  
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+
+	// @224 ''' (11 pixels wide)
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x07, 0x00, //      ###   
+	0x07, 0x00, //      ###   
+	0x02, 0x00, //       #    
+	0x02, 0x00, //       #    
+	0x02, 0x00, //       #    
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+
+	// @256 '(' (11 pixels wide)
+	0x00, 0x00, //            
+	0x03, 0x00, //       ##   
+	0x03, 0x00, //       ##   
+	0x06, 0x00, //      ##    
+	0x0E, 0x00, //     ###    
+	0x0C, 0x00, //     ##     
+	0x0C, 0x00, //     ##     
+	0x0C, 0x00, //     ##     
+	0x0C, 0x00, //     ##     
+	0x0E, 0x00, //     ###    
+	0x06, 0x00, //      ##    
+	0x03, 0x00, //       ##   
+	0x03, 0x00, //       ##   
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+
+	// @288 ')' (11 pixels wide)
+	0x00, 0x00, //            
+	0x18, 0x00, //    ##      
+	0x18, 0x00, //    ##      
+	0x0C, 0x00, //     ##     
+	0x06, 0x00, //      ##    
+	0x06, 0x00, //      ##    
+	0x06, 0x00, //      ##    
+	0x06, 0x00, //      ##    
+	0x06, 0x00, //      ##    
+	0x06, 0x00, //      ##    
+	0x0C, 0x00, //     ##     
+	0x1C, 0x00, //    ###     
+	0x18, 0x00, //    ##      
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+
+	// @320 '*' (11 pixels wide)
+	0x00, 0x00, //            
+	0x06, 0x00, //      ##    
+	0x06, 0x00, //      ##    
+	0x3F, 0xC0, //   ######## 
+	0x3F, 0xC0, //   ######## 
+	0x0F, 0x00, //     ####   
+	0x1F, 0x80, //    ######  
+	0x19, 0x80, //    ##  ##  
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+
+	// @352 '+' (11 pixels wide)
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x04, 0x00, //      #     
+	0x04, 0x00, //      #     
+	0x04, 0x00, //      #     
+	0x3F, 0x80, //   #######  
+	0x04, 0x00, //      #     
+	0x04, 0x00, //      #     
+	0x04, 0x00, //      #     
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+
+	// @384 ',' (11 pixels wide)
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x06, 0x00, //      ##    
+	0x04, 0x00, //      #     
+	0x0C, 0x00, //     ##     
+	0x08, 0x00, //     #      
+	0x08, 0x00, //     #      
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+
+	// @416 '-' (11 pixels wide)
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x3F, 0x80, //   #######  
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+
+	// @448 '.' (11 pixels wide)
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x0C, 0x00, //     ##     
+	0x0C, 0x00, //     ##     
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+
+	// @480 '/' (11 pixels wide)
+	0x00, 0xC0, //         ## 
+	0x00, 0xC0, //         ## 
+	0x01, 0x80, //        ##  
+	0x01, 0x80, //        ##  
+	0x03, 0x00, //       ##   
+	0x03, 0x00, //       ##   
+	0x06, 0x00, //      ##    
+	0x0C, 0x00, //     ##     
+	0x0C, 0x00, //     ##     
+	0x18, 0x00, //    ##      
+	0x18, 0x00, //    ##      
+	0x30, 0x00, //   ##       
+	0x30, 0x00, //   ##       
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+
+	// @512 '0' (11 pixels wide)
+	0x00, 0x00, //            
+	0x0E, 0x00, //     ###    
+	0x1B, 0x00, //    ## ##   
+	0x31, 0x80, //   ##   ##  
+	0x31, 0x80, //   ##   ##  
+	0x31, 0x80, //   ##   ##  
+	0x31, 0x80, //   ##   ##  
+	0x31, 0x80, //   ##   ##  
+	0x31, 0x80, //   ##   ##  
+	0x1B, 0x00, //    ## ##   
+	0x0E, 0x00, //     ###    
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+
+	// @544 '1' (11 pixels wide)
+	0x00, 0x00, //            
+	0x06, 0x00, //      ##    
+	0x3E, 0x00, //   #####    
+	0x06, 0x00, //      ##    
+	0x06, 0x00, //      ##    
+	0x06, 0x00, //      ##    
+	0x06, 0x00, //      ##    
+	0x06, 0x00, //      ##    
+	0x06, 0x00, //      ##    
+	0x06, 0x00, //      ##    
+	0x3F, 0xC0, //   ######## 
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+
+	// @576 '2' (11 pixels wide)
+	0x00, 0x00, //            
+	0x0F, 0x00, //     ####   
+	0x19, 0x80, //    ##  ##  
+	0x31, 0x80, //   ##   ##  
+	0x31, 0x80, //   ##   ##  
+	0x03, 0x00, //       ##   
+	0x06, 0x00, //      ##    
+	0x0C, 0x00, //     ##     
+	0x18, 0x00, //    ##      
+	0x30, 0x00, //   ##       
+	0x3F, 0x80, //   #######  
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+
+	// @608 '3' (11 pixels wide)
+	0x00, 0x00, //            
+	0x3F, 0x00, //   ######   
+	0x61, 0x80, //  ##    ##  
+	0x01, 0x80, //        ##  
+	0x03, 0x00, //       ##   
+	0x1F, 0x00, //    #####   
+	0x03, 0x80, //       ###  
+	0x01, 0x80, //        ##  
+	0x01, 0x80, //        ##  
+	0x61, 0x80, //  ##    ##  
+	0x3F, 0x00, //   ######   
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+
+	// @640 '4' (11 pixels wide)
+	0x00, 0x00, //            
+	0x07, 0x00, //      ###   
+	0x07, 0x00, //      ###   
+	0x0F, 0x00, //     ####   
+	0x0B, 0x00, //     # ##   
+	0x1B, 0x00, //    ## ##   
+	0x13, 0x00, //    #  ##   
+	0x33, 0x00, //   ##  ##   
+	0x3F, 0x80, //   #######  
+	0x03, 0x00, //       ##   
+	0x0F, 0x80, //     #####  
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+
+	// @672 '5' (11 pixels wide)
+	0x00, 0x00, //            
+	0x1F, 0x80, //    ######  
+	0x18, 0x00, //    ##      
+	0x18, 0x00, //    ##      
+	0x18, 0x00, //    ##      
+	0x1F, 0x00, //    #####   
+	0x11, 0x80, //    #   ##  
+	0x01, 0x80, //        ##  
+	0x01, 0x80, //        ##  
+	0x21, 0x80, //   #    ##  
+	0x1F, 0x00, //    #####   
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+
+	// @704 '6' (11 pixels wide)
+	0x00, 0x00, //            
+	0x07, 0x80, //      ####  
+	0x1C, 0x00, //    ###     
+	0x18, 0x00, //    ##      
+	0x30, 0x00, //   ##       
+	0x37, 0x00, //   ## ###   
+	0x39, 0x80, //   ###  ##  
+	0x31, 0x80, //   ##   ##  
+	0x31, 0x80, //   ##   ##  
+	0x19, 0x80, //    ##  ##  
+	0x0F, 0x00, //     ####   
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+
+	// @736 '7' (11 pixels wide)
+	0x00, 0x00, //            
+	0x7F, 0x00, //  #######   
+	0x43, 0x00, //  #    ##   
+	0x03, 0x00, //       ##   
+	0x06, 0x00, //      ##    
+	0x06, 0x00, //      ##    
+	0x06, 0x00, //      ##    
+	0x06, 0x00, //      ##    
+	0x0C, 0x00, //     ##     
+	0x0C, 0x00, //     ##     
+	0x0C, 0x00, //     ##     
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+
+	// @768 '8' (11 pixels wide)
+	0x00, 0x00, //            
+	0x1F, 0x00, //    #####   
+	0x31, 0x80, //   ##   ##  
+	0x31, 0x80, //   ##   ##  
+	0x31, 0x80, //   ##   ##  
+	0x1F, 0x00, //    #####   
+	0x31, 0x80, //   ##   ##  
+	0x31, 0x80, //   ##   ##  
+	0x31, 0x80, //   ##   ##  
+	0x31, 0x80, //   ##   ##  
+	0x1F, 0x00, //    #####   
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+
+	// @800 '9' (11 pixels wide)
+	0x00, 0x00, //            
+	0x1E, 0x00, //    ####    
+	0x33, 0x00, //   ##  ##   
+	0x31, 0x80, //   ##   ##  
+	0x31, 0x80, //   ##   ##  
+	0x33, 0x80, //   ##  ###  
+	0x1D, 0x80, //    ### ##  
+	0x01, 0x80, //        ##  
+	0x03, 0x00, //       ##   
+	0x07, 0x00, //      ###   
+	0x3C, 0x00, //   ####     
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+
+	// @832 ':' (11 pixels wide)
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x0C, 0x00, //     ##     
+	0x0C, 0x00, //     ##     
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x0C, 0x00, //     ##     
+	0x0C, 0x00, //     ##     
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+
+	// @864 ';' (11 pixels wide)
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x03, 0x00, //       ##   
+	0x03, 0x00, //       ##   
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x06, 0x00, //      ##    
+	0x04, 0x00, //      #     
+	0x08, 0x00, //     #      
+	0x08, 0x00, //     #      
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+
+	// @896 '<' (11 pixels wide)
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0xC0, //         ## 
+	0x03, 0x00, //       ##   
+	0x04, 0x00, //      #     
+	0x18, 0x00, //    ##      
+	0x60, 0x00, //  ##        
+	0x18, 0x00, //    ##      
+	0x04, 0x00, //      #     
+	0x03, 0x00, //       ##   
+	0x00, 0xC0, //         ## 
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+
+	// @928 '=' (11 pixels wide)
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x7F, 0xC0, //  ######### 
+	0x00, 0x00, //            
+	0x7F, 0xC0, //  ######### 
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+
+	// @960 '>' (11 pixels wide)
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x60, 0x00, //  ##        
+	0x18, 0x00, //    ##      
+	0x04, 0x00, //      #     
+	0x03, 0x00, //       ##   
+	0x00, 0xC0, //         ## 
+	0x03, 0x00, //       ##   
+	0x04, 0x00, //      #     
+	0x18, 0x00, //    ##      
+	0x60, 0x00, //  ##        
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+
+	// @992 '?' (11 pixels wide)
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x1F, 0x00, //    #####   
+	0x31, 0x80, //   ##   ##  
+	0x31, 0x80, //   ##   ##  
+	0x01, 0x80, //        ##  
+	0x07, 0x00, //      ###   
+	0x0C, 0x00, //     ##     
+	0x0C, 0x00, //     ##     
+	0x00, 0x00, //            
+	0x0C, 0x00, //     ##     
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+
+	// @1024 '@' (11 pixels wide)
+	0x00, 0x00, //            
+	0x0E, 0x00, //     ###    
+	0x11, 0x00, //    #   #   
+	0x21, 0x00, //   #    #   
+	0x21, 0x00, //   #    #   
+	0x27, 0x00, //   #  ###   
+	0x29, 0x00, //   # #  #   
+	0x29, 0x00, //   # #  #   
+	0x27, 0x00, //   #  ###   
+	0x20, 0x00, //   #        
+	0x11, 0x00, //    #   #   
+	0x0E, 0x00, //     ###    
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+
+	// @1056 'A' (11 pixels wide)
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x3F, 0x00, //   ######   
+	0x0F, 0x00, //     ####   
+	0x09, 0x00, //     #  #   
+	0x19, 0x80, //    ##  ##  
+	0x19, 0x80, //    ##  ##  
+	0x1F, 0x80, //    ######  
+	0x30, 0xC0, //   ##    ## 
+	0x30, 0xC0, //   ##    ## 
+	0x79, 0xE0, //  ####  ####
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+
+	// @1088 'B' (11 pixels wide)
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x7F, 0x00, //  #######   
+	0x31, 0x80, //   ##   ##  
+	0x31, 0x80, //   ##   ##  
+	0x31, 0x80, //   ##   ##  
+	0x3F, 0x00, //   ######   
+	0x31, 0x80, //   ##   ##  
+	0x31, 0x80, //   ##   ##  
+	0x31, 0x80, //   ##   ##  
+	0x7F, 0x00, //  #######   
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+
+	// @1120 'C' (11 pixels wide)
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x1F, 0x40, //    ##### # 
+	0x30, 0xC0, //   ##    ## 
+	0x60, 0x40, //  ##      # 
+	0x60, 0x00, //  ##        
+	0x60, 0x00, //  ##        
+	0x60, 0x00, //  ##        
+	0x60, 0x40, //  ##      # 
+	0x30, 0x80, //   ##    #  
+	0x1F, 0x00, //    #####   
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+
+	// @1152 'D' (11 pixels wide)
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x7F, 0x00, //  #######   
+	0x31, 0x80, //   ##   ##  
+	0x30, 0xC0, //   ##    ## 
+	0x30, 0xC0, //   ##    ## 
+	0x30, 0xC0, //   ##    ## 
+	0x30, 0xC0, //   ##    ## 
+	0x30, 0xC0, //   ##    ## 
+	0x31, 0x80, //   ##   ##  
+	0x7F, 0x00, //  #######   
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+
+	// @1184 'E' (11 pixels wide)
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x7F, 0x80, //  ########  
+	0x30, 0x80, //   ##    #  
+	0x30, 0x80, //   ##    #  
+	0x32, 0x00, //   ##  #    
+	0x3E, 0x00, //   #####    
+	0x32, 0x00, //   ##  #    
+	0x30, 0x80, //   ##    #  
+	0x30, 0x80, //   ##    #  
+	0x7F, 0x80, //  ########  
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+
+	// @1216 'F' (11 pixels wide)
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x7F, 0xC0, //  ######### 
+	0x30, 0x40, //   ##     # 
+	0x30, 0x40, //   ##     # 
+	0x32, 0x00, //   ##  #    
+	0x3E, 0x00, //   #####    
+	0x32, 0x00, //   ##  #    
+	0x30, 0x00, //   ##       
+	0x30, 0x00, //   ##       
+	0x7C, 0x00, //  #####     
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+
+	// @1248 'G' (11 pixels wide)
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x1E, 0x80, //    #### #  
+	0x31, 0x80, //   ##   ##  
+	0x60, 0x80, //  ##     #  
+	0x60, 0x00, //  ##        
+	0x60, 0x00, //  ##        
+	0x67, 0xC0, //  ##  ##### 
+	0x61, 0x80, //  ##    ##  
+	0x31, 0x80, //   ##   ##  
+	0x1F, 0x00, //    #####   
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+
+	// @1280 'H' (11 pixels wide)
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x7B, 0xC0, //  #### #### 
+	0x31, 0x80, //   ##   ##  
+	0x31, 0x80, //   ##   ##  
+	0x31, 0x80, //   ##   ##  
+	0x3F, 0x80, //   #######  
+	0x31, 0x80, //   ##   ##  
+	0x31, 0x80, //   ##   ##  
+	0x31, 0x80, //   ##   ##  
+	0x7B, 0xC0, //  #### #### 
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+
+	// @1312 'I' (11 pixels wide)
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x3F, 0xC0, //   ######## 
+	0x06, 0x00, //      ##    
+	0x06, 0x00, //      ##    
+	0x06, 0x00, //      ##    
+	0x06, 0x00, //      ##    
+	0x06, 0x00, //      ##    
+	0x06, 0x00, //      ##    
+	0x06, 0x00, //      ##    
+	0x3F, 0xC0, //   ######## 
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+
+	// @1344 'J' (11 pixels wide)
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x1F, 0xC0, //    ####### 
+	0x03, 0x00, //       ##   
+	0x03, 0x00, //       ##   
+	0x03, 0x00, //       ##   
+	0x03, 0x00, //       ##   
+	0x63, 0x00, //  ##   ##   
+	0x63, 0x00, //  ##   ##   
+	0x63, 0x00, //  ##   ##   
+	0x3E, 0x00, //   #####    
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+
+	// @1376 'K' (11 pixels wide)
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x7B, 0xC0, //  #### #### 
+	0x31, 0x80, //   ##   ##  
+	0x33, 0x00, //   ##  ##   
+	0x36, 0x00, //   ## ##    
+	0x3C, 0x00, //   ####     
+	0x3E, 0x00, //   #####    
+	0x33, 0x00, //   ##  ##   
+	0x31, 0x80, //   ##   ##  
+	0x79, 0xC0, //  ####  ### 
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+
+	// @1408 'L' (11 pixels wide)
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x7E, 0x00, //  ######    
+	0x18, 0x00, //    ##      
+	0x18, 0x00, //    ##      
+	0x18, 0x00, //    ##      
+	0x18, 0x00, //    ##      
+	0x18, 0x40, //    ##    # 
+	0x18, 0x40, //    ##    # 
+	0x18, 0x40, //    ##    # 
+	0x7F, 0xC0, //  ######### 
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+
+	// @1440 'M' (11 pixels wide)
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0xE0, 0xE0, // ###     ###
+	0x60, 0xC0, //  ##     ## 
+	0x71, 0xC0, //  ###   ### 
+	0x7B, 0xC0, //  #### #### 
+	0x6A, 0xC0, //  ## # # ## 
+	0x6E, 0xC0, //  ## ### ## 
+	0x64, 0xC0, //  ##  #  ## 
+	0x60, 0xC0, //  ##     ## 
+	0xFB, 0xE0, // ##### #####
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+
+	// @1472 'N' (11 pixels wide)
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x73, 0xC0, //  ###  #### 
+	0x31, 0x80, //   ##   ##  
+	0x39, 0x80, //   ###  ##  
+	0x3D, 0x80, //   #### ##  
+	0x35, 0x80, //   ## # ##  
+	0x37, 0x80, //   ## ####  
+	0x33, 0x80, //   ##  ###  
+	0x31, 0x80, //   ##   ##  
+	0x79, 0x80, //  ####  ##  
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+
+	// @1504 'O' (11 pixels wide)
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x1F, 0x00, //    #####   
+	0x31, 0x80, //   ##   ##  
+	0x60, 0xC0, //  ##     ## 
+	0x60, 0xC0, //  ##     ## 
+	0x60, 0xC0, //  ##     ## 
+	0x60, 0xC0, //  ##     ## 
+	0x60, 0xC0, //  ##     ## 
+	0x31, 0x80, //   ##   ##  
+	0x1F, 0x00, //    #####   
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+
+	// @1536 'P' (11 pixels wide)
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x7F, 0x00, //  #######   
+	0x31, 0x80, //   ##   ##  
+	0x31, 0x80, //   ##   ##  
+	0x31, 0x80, //   ##   ##  
+	0x31, 0x80, //   ##   ##  
+	0x3F, 0x00, //   ######   
+	0x30, 0x00, //   ##       
+	0x30, 0x00, //   ##       
+	0x7E, 0x00, //  ######    
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+
+	// @1568 'Q' (11 pixels wide)
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x1F, 0x00, //    #####   
+	0x31, 0x80, //   ##   ##  
+	0x60, 0xC0, //  ##     ## 
+	0x60, 0xC0, //  ##     ## 
+	0x60, 0xC0, //  ##     ## 
+	0x60, 0xC0, //  ##     ## 
+	0x60, 0xC0, //  ##     ## 
+	0x31, 0x80, //   ##   ##  
+	0x1F, 0x00, //    #####   
+	0x0C, 0xC0, //     ##  ## 
+	0x1F, 0x80, //    ######  
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+
+	// @1600 'R' (11 pixels wide)
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x7F, 0x00, //  #######   
+	0x31, 0x80, //   ##   ##  
+	0x31, 0x80, //   ##   ##  
+	0x31, 0x80, //   ##   ##  
+	0x3E, 0x00, //   #####    
+	0x33, 0x00, //   ##  ##   
+	0x31, 0x80, //   ##   ##  
+	0x31, 0x80, //   ##   ##  
+	0x7C, 0xE0, //  #####  ###
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+
+	// @1632 'S' (11 pixels wide)
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x1F, 0x80, //    ######  
+	0x31, 0x80, //   ##   ##  
+	0x31, 0x80, //   ##   ##  
+	0x38, 0x00, //   ###      
+	0x1F, 0x00, //    #####   
+	0x03, 0x80, //       ###  
+	0x31, 0x80, //   ##   ##  
+	0x31, 0x80, //   ##   ##  
+	0x3F, 0x00, //   ######   
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+
+	// @1664 'T' (11 pixels wide)
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x7F, 0x80, //  ########  
+	0x4C, 0x80, //  #  ##  #  
+	0x4C, 0x80, //  #  ##  #  
+	0x4C, 0x80, //  #  ##  #  
+	0x0C, 0x00, //     ##     
+	0x0C, 0x00, //     ##     
+	0x0C, 0x00, //     ##     
+	0x0C, 0x00, //     ##     
+	0x3F, 0x00, //   ######   
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+
+	// @1696 'U' (11 pixels wide)
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x7B, 0xC0, //  #### #### 
+	0x31, 0x80, //   ##   ##  
+	0x31, 0x80, //   ##   ##  
+	0x31, 0x80, //   ##   ##  
+	0x31, 0x80, //   ##   ##  
+	0x31, 0x80, //   ##   ##  
+	0x31, 0x80, //   ##   ##  
+	0x31, 0x80, //   ##   ##  
+	0x1F, 0x00, //    #####   
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+
+	// @1728 'V' (11 pixels wide)
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x7B, 0xC0, //  #### #### 
+	0x31, 0x80, //   ##   ##  
+	0x31, 0x80, //   ##   ##  
+	0x1B, 0x00, //    ## ##   
+	0x1B, 0x00, //    ## ##   
+	0x1B, 0x00, //    ## ##   
+	0x0A, 0x00, //     # #    
+	0x0E, 0x00, //     ###    
+	0x0E, 0x00, //     ###    
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+
+	// @1760 'W' (11 pixels wide)
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0xFB, 0xE0, // ##### #####
+	0x60, 0xC0, //  ##     ## 
+	0x64, 0xC0, //  ##  #  ## 
+	0x6E, 0xC0, //  ## ### ## 
+	0x6E, 0xC0, //  ## ### ## 
+	0x2A, 0x80, //   # # # #  
+	0x3B, 0x80, //   ### ###  
+	0x3B, 0x80, //   ### ###  
+	0x31, 0x80, //   ##   ##  
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+
+	// @1792 'X' (11 pixels wide)
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x7B, 0xC0, //  #### #### 
+	0x31, 0x80, //   ##   ##  
+	0x1B, 0x00, //    ## ##   
+	0x0E, 0x00, //     ###    
+	0x0E, 0x00, //     ###    
+	0x0E, 0x00, //     ###    
+	0x1B, 0x00, //    ## ##   
+	0x31, 0x80, //   ##   ##  
+	0x7B, 0xC0, //  #### #### 
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+
+	// @1824 'Y' (11 pixels wide)
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x79, 0xE0, //  ####  ####
+	0x30, 0xC0, //   ##    ## 
+	0x19, 0x80, //    ##  ##  
+	0x0F, 0x00, //     ####   
+	0x06, 0x00, //      ##    
+	0x06, 0x00, //      ##    
+	0x06, 0x00, //      ##    
+	0x06, 0x00, //      ##    
+	0x1F, 0x80, //    ######  
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+
+	// @1856 'Z' (11 pixels wide)
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x3F, 0x80, //   #######  
+	0x21, 0x80, //   #    ##  
+	0x23, 0x00, //   #   ##   
+	0x06, 0x00, //      ##    
+	0x04, 0x00, //      #     
+	0x0C, 0x00, //     ##     
+	0x18, 0x80, //    ##   #  
+	0x30, 0x80, //   ##    #  
+	0x3F, 0x80, //   #######  
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+
+	// @1888 '[' (11 pixels wide)
+	0x00, 0x00, //            
+	0x07, 0x80, //      ####  
+	0x06, 0x00, //      ##    
+	0x06, 0x00, //      ##    
+	0x06, 0x00, //      ##    
+	0x06, 0x00, //      ##    
+	0x06, 0x00, //      ##    
+	0x06, 0x00, //      ##    
+	0x06, 0x00, //      ##    
+	0x06, 0x00, //      ##    
+	0x06, 0x00, //      ##    
+	0x06, 0x00, //      ##    
+	0x07, 0x80, //      ####  
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+
+	// @1920 '\' (11 pixels wide)
+	0x30, 0x00, //   ##       
+	0x30, 0x00, //   ##       
+	0x18, 0x00, //    ##      
+	0x18, 0x00, //    ##      
+	0x0C, 0x00, //     ##     
+	0x0C, 0x00, //     ##     
+	0x06, 0x00, //      ##    
+	0x03, 0x00, //       ##   
+	0x03, 0x00, //       ##   
+	0x01, 0x80, //        ##  
+	0x01, 0x80, //        ##  
+	0x00, 0xC0, //         ## 
+	0x00, 0xC0, //         ## 
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+
+	// @1952 ']' (11 pixels wide)
+	0x00, 0x00, //            
+	0x1E, 0x00, //    ####    
+	0x06, 0x00, //      ##    
+	0x06, 0x00, //      ##    
+	0x06, 0x00, //      ##    
+	0x06, 0x00, //      ##    
+	0x06, 0x00, //      ##    
+	0x06, 0x00, //      ##    
+	0x06, 0x00, //      ##    
+	0x06, 0x00, //      ##    
+	0x06, 0x00, //      ##    
+	0x06, 0x00, //      ##    
+	0x1E, 0x00, //    ####    
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+
+	// @1984 '^' (11 pixels wide)
+	0x04, 0x00, //      #     
+	0x0A, 0x00, //     # #    
+	0x0A, 0x00, //     # #    
+	0x11, 0x00, //    #   #   
+	0x20, 0x80, //   #     #  
+	0x20, 0x80, //   #     #  
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+
+	// @2016 '_' (11 pixels wide)
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0xFF, 0xE0, // ###########
+
+	// @2048 '`' (11 pixels wide)
+	0x08, 0x00, //     #      
+	0x04, 0x00, //      #     
+	0x02, 0x00, //       #    
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+
+	// @2080 'a' (11 pixels wide)
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x1F, 0x00, //    #####   
+	0x01, 0x80, //        ##  
+	0x01, 0x80, //        ##  
+	0x1F, 0x80, //    ######  
+	0x31, 0x80, //   ##   ##  
+	0x33, 0x80, //   ##  ###  
+	0x1D, 0xC0, //    ### ### 
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+
+	// @2112 'b' (11 pixels wide)
+	0x00, 0x00, //            
+	0x70, 0x00, //  ###       
+	0x30, 0x00, //   ##       
+	0x30, 0x00, //   ##       
+	0x37, 0x00, //   ## ###   
+	0x39, 0x80, //   ###  ##  
+	0x30, 0xC0, //   ##    ## 
+	0x30, 0xC0, //   ##    ## 
+	0x30, 0xC0, //   ##    ## 
+	0x39, 0x80, //   ###  ##  
+	0x77, 0x00, //  ### ###   
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+
+	// @2144 'c' (11 pixels wide)
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x1E, 0x80, //    #### #  
+	0x31, 0x80, //   ##   ##  
+	0x60, 0x80, //  ##     #  
+	0x60, 0x00, //  ##        
+	0x60, 0x80, //  ##     #  
+	0x31, 0x80, //   ##   ##  
+	0x1F, 0x00, //    #####   
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+
+	// @2176 'd' (11 pixels wide)
+	0x00, 0x00, //            
+	0x03, 0x80, //       ###  
+	0x01, 0x80, //        ##  
+	0x01, 0x80, //        ##  
+	0x1D, 0x80, //    ### ##  
+	0x33, 0x80, //   ##  ###  
+	0x61, 0x80, //  ##    ##  
+	0x61, 0x80, //  ##    ##  
+	0x61, 0x80, //  ##    ##  
+	0x33, 0x80, //   ##  ###  
+	0x1D, 0xC0, //    ### ### 
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+
+	// @2208 'e' (11 pixels wide)
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x1F, 0x00, //    #####   
+	0x31, 0x80, //   ##   ##  
+	0x60, 0xC0, //  ##     ## 
+	0x7F, 0xC0, //  ######### 
+	0x60, 0x00, //  ##        
+	0x30, 0xC0, //   ##    ## 
+	0x1F, 0x80, //    ######  
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+
+	// @2240 'f' (11 pixels wide)
+	0x00, 0x00, //            
+	0x07, 0xE0, //      ######
+	0x0C, 0x00, //     ##     
+	0x0C, 0x00, //     ##     
+	0x3F, 0x80, //   #######  
+	0x0C, 0x00, //     ##     
+	0x0C, 0x00, //     ##     
+	0x0C, 0x00, //     ##     
+	0x0C, 0x00, //     ##     
+	0x0C, 0x00, //     ##     
+	0x3F, 0x80, //   #######  
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+
+	// @2272 'g' (11 pixels wide)
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x1D, 0xC0, //    ### ### 
+	0x33, 0x80, //   ##  ###  
+	0x61, 0x80, //  ##    ##  
+	0x61, 0x80, //  ##    ##  
+	0x61, 0x80, //  ##    ##  
+	0x33, 0x80, //   ##  ###  
+	0x1D, 0x80, //    ### ##  
+	0x01, 0x80, //        ##  
+	0x01, 0x80, //        ##  
+	0x1F, 0x00, //    #####   
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+
+	// @2304 'h' (11 pixels wide)
+	0x00, 0x00, //            
+	0x70, 0x00, //  ###       
+	0x30, 0x00, //   ##       
+	0x30, 0x00, //   ##       
+	0x37, 0x00, //   ## ###   
+	0x39, 0x80, //   ###  ##  
+	0x31, 0x80, //   ##   ##  
+	0x31, 0x80, //   ##   ##  
+	0x31, 0x80, //   ##   ##  
+	0x31, 0x80, //   ##   ##  
+	0x7B, 0xC0, //  #### #### 
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+
+	// @2336 'i' (11 pixels wide)
+	0x00, 0x00, //            
+	0x06, 0x00, //      ##    
+	0x06, 0x00, //      ##    
+	0x00, 0x00, //            
+	0x1E, 0x00, //    ####    
+	0x06, 0x00, //      ##    
+	0x06, 0x00, //      ##    
+	0x06, 0x00, //      ##    
+	0x06, 0x00, //      ##    
+	0x06, 0x00, //      ##    
+	0x3F, 0xC0, //   ######## 
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+
+	// @2368 'j' (11 pixels wide)
+	0x00, 0x00, //            
+	0x06, 0x00, //      ##    
+	0x06, 0x00, //      ##    
+	0x00, 0x00, //            
+	0x3F, 0x00, //   ######   
+	0x03, 0x00, //       ##   
+	0x03, 0x00, //       ##   
+	0x03, 0x00, //       ##   
+	0x03, 0x00, //       ##   
+	0x03, 0x00, //       ##   
+	0x03, 0x00, //       ##   
+	0x03, 0x00, //       ##   
+	0x03, 0x00, //       ##   
+	0x3E, 0x00, //   #####    
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+
+	// @2400 'k' (11 pixels wide)
+	0x00, 0x00, //            
+	0x70, 0x00, //  ###       
+	0x30, 0x00, //   ##       
+	0x30, 0x00, //   ##       
+	0x37, 0x80, //   ## ####  
+	0x36, 0x00, //   ## ##    
+	0x3C, 0x00, //   ####     
+	0x3C, 0x00, //   ####     
+	0x36, 0x00, //   ## ##    
+	0x33, 0x00, //   ##  ##   
+	0x77, 0xC0, //  ### ##### 
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+
+	// @2432 'l' (11 pixels wide)
+	0x00, 0x00, //            
+	0x1E, 0x00, //    ####    
+	0x06, 0x00, //      ##    
+	0x06, 0x00, //      ##    
+	0x06, 0x00, //      ##    
+	0x06, 0x00, //      ##    
+	0x06, 0x00, //      ##    
+	0x06, 0x00, //      ##    
+	0x06, 0x00, //      ##    
+	0x06, 0x00, //      ##    
+	0x3F, 0xC0, //   ######## 
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+
+	// @2464 'm' (11 pixels wide)
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x7F, 0x80, //  ########  
+	0x36, 0xC0, //   ## ## ## 
+	0x36, 0xC0, //   ## ## ## 
+	0x36, 0xC0, //   ## ## ## 
+	0x36, 0xC0, //   ## ## ## 
+	0x36, 0xC0, //   ## ## ## 
+	0x76, 0xE0, //  ### ## ###
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+
+	// @2496 'n' (11 pixels wide)
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x77, 0x00, //  ### ###   
+	0x39, 0x80, //   ###  ##  
+	0x31, 0x80, //   ##   ##  
+	0x31, 0x80, //   ##   ##  
+	0x31, 0x80, //   ##   ##  
+	0x31, 0x80, //   ##   ##  
+	0x7B, 0xC0, //  #### #### 
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+
+	// @2528 'o' (11 pixels wide)
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x1F, 0x00, //    #####   
+	0x31, 0x80, //   ##   ##  
+	0x60, 0xC0, //  ##     ## 
+	0x60, 0xC0, //  ##     ## 
+	0x60, 0xC0, //  ##     ## 
+	0x31, 0x80, //   ##   ##  
+	0x1F, 0x00, //    #####   
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+
+	// @2560 'p' (11 pixels wide)
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x77, 0x00, //  ### ###   
+	0x39, 0x80, //   ###  ##  
+	0x30, 0xC0, //   ##    ## 
+	0x30, 0xC0, //   ##    ## 
+	0x30, 0xC0, //   ##    ## 
+	0x39, 0x80, //   ###  ##  
+	0x37, 0x00, //   ## ###   
+	0x30, 0x00, //   ##       
+	0x30, 0x00, //   ##       
+	0x7C, 0x00, //  #####     
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+
+	// @2592 'q' (11 pixels wide)
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x1D, 0xC0, //    ### ### 
+	0x33, 0x80, //   ##  ###  
+	0x61, 0x80, //  ##    ##  
+	0x61, 0x80, //  ##    ##  
+	0x61, 0x80, //  ##    ##  
+	0x33, 0x80, //   ##  ###  
+	0x1D, 0x80, //    ### ##  
+	0x01, 0x80, //        ##  
+	0x01, 0x80, //        ##  
+	0x07, 0xC0, //      ##### 
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+
+	// @2624 'r' (11 pixels wide)
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x7B, 0x80, //  #### ###  
+	0x1C, 0xC0, //    ###  ## 
+	0x18, 0x00, //    ##      
+	0x18, 0x00, //    ##      
+	0x18, 0x00, //    ##      
+	0x18, 0x00, //    ##      
+	0x7F, 0x00, //  #######   
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+
+	// @2656 's' (11 pixels wide)
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x1F, 0x80, //    ######  
+	0x31, 0x80, //   ##   ##  
+	0x3C, 0x00, //   ####     
+	0x1F, 0x00, //    #####   
+	0x03, 0x80, //       ###  
+	0x31, 0x80, //   ##   ##  
+	0x3F, 0x00, //   ######   
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+
+	// @2688 't' (11 pixels wide)
+	0x00, 0x00, //            
+	0x18, 0x00, //    ##      
+	0x18, 0x00, //    ##      
+	0x18, 0x00, //    ##      
+	0x7F, 0x00, //  #######   
+	0x18, 0x00, //    ##      
+	0x18, 0x00, //    ##      
+	0x18, 0x00, //    ##      
+	0x18, 0x00, //    ##      
+	0x18, 0x80, //    ##   #  
+	0x0F, 0x00, //     ####   
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+
+	// @2720 'u' (11 pixels wide)
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x73, 0x80, //  ###  ###  
+	0x31, 0x80, //   ##   ##  
+	0x31, 0x80, //   ##   ##  
+	0x31, 0x80, //   ##   ##  
+	0x31, 0x80, //   ##   ##  
+	0x33, 0x80, //   ##  ###  
+	0x1D, 0xC0, //    ### ### 
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+
+	// @2752 'v' (11 pixels wide)
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x7B, 0xC0, //  #### #### 
+	0x31, 0x80, //   ##   ##  
+	0x31, 0x80, //   ##   ##  
+	0x1B, 0x00, //    ## ##   
+	0x1B, 0x00, //    ## ##   
+	0x0E, 0x00, //     ###    
+	0x0E, 0x00, //     ###    
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+
+	// @2784 'w' (11 pixels wide)
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0xF1, 0xE0, // ####   ####
+	0x60, 0xC0, //  ##     ## 
+	0x64, 0xC0, //  ##  #  ## 
+	0x6E, 0xC0, //  ## ### ## 
+	0x3B, 0x80, //   ### ###  
+	0x3B, 0x80, //   ### ###  
+	0x31, 0x80, //   ##   ##  
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+
+	// @2816 'x' (11 pixels wide)
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x7B, 0xC0, //  #### #### 
+	0x1B, 0x00, //    ## ##   
+	0x0E, 0x00, //     ###    
+	0x0E, 0x00, //     ###    
+	0x0E, 0x00, //     ###    
+	0x1B, 0x00, //    ## ##   
+	0x7B, 0xC0, //  #### #### 
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+
+	// @2848 'y' (11 pixels wide)
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x79, 0xE0, //  ####  ####
+	0x30, 0xC0, //   ##    ## 
+	0x19, 0x80, //    ##  ##  
+	0x19, 0x80, //    ##  ##  
+	0x0B, 0x00, //     # ##   
+	0x0F, 0x00, //     ####   
+	0x06, 0x00, //      ##    
+	0x06, 0x00, //      ##    
+	0x0C, 0x00, //     ##     
+	0x3E, 0x00, //   #####    
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+
+	// @2880 'z' (11 pixels wide)
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x3F, 0x80, //   #######  
+	0x21, 0x80, //   #    ##  
+	0x03, 0x00, //       ##   
+	0x0E, 0x00, //     ###    
+	0x18, 0x00, //    ##      
+	0x30, 0x80, //   ##    #  
+	0x3F, 0x80, //   #######  
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+
+	// @2912 '{' (11 pixels wide)
+	0x00, 0x00, //            
+	0x06, 0x00, //      ##    
+	0x0C, 0x00, //     ##     
+	0x0C, 0x00, //     ##     
+	0x0C, 0x00, //     ##     
+	0x0C, 0x00, //     ##     
+	0x0C, 0x00, //     ##     
+	0x18, 0x00, //    ##      
+	0x0C, 0x00, //     ##     
+	0x0C, 0x00, //     ##     
+	0x0C, 0x00, //     ##     
+	0x0C, 0x00, //     ##     
+	0x06, 0x00, //      ##    
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+
+	// @2944 '|' (11 pixels wide)
+	0x00, 0x00, //            
+	0x06, 0x00, //      ##    
+	0x06, 0x00, //      ##    
+	0x06, 0x00, //      ##    
+	0x06, 0x00, //      ##    
+	0x06, 0x00, //      ##    
+	0x06, 0x00, //      ##    
+	0x06, 0x00, //      ##    
+	0x06, 0x00, //      ##    
+	0x06, 0x00, //      ##    
+	0x06, 0x00, //      ##    
+	0x06, 0x00, //      ##    
+	0x06, 0x00, //      ##    
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+
+	// @2976 '}' (11 pixels wide)
+	0x00, 0x00, //            
+	0x0C, 0x00, //     ##     
+	0x06, 0x00, //      ##    
+	0x06, 0x00, //      ##    
+	0x06, 0x00, //      ##    
+	0x06, 0x00, //      ##    
+	0x06, 0x00, //      ##    
+	0x03, 0x00, //       ##   
+	0x06, 0x00, //      ##    
+	0x06, 0x00, //      ##    
+	0x06, 0x00, //      ##    
+	0x06, 0x00, //      ##    
+	0x0C, 0x00, //     ##     
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+
+	// @3008 '~' (11 pixels wide)
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x18, 0x00, //    ##      
+	0x24, 0x80, //   #  #  #  
+	0x03, 0x00, //       ##   
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+	0x00, 0x00, //            
+};
+
+sFONT Font16 = {
+  Font16_Table,
+  11, /* Width */
+  16, /* Height */
+};
+
+/**
+  * @}
+  */ 
+
+
+/** @defgroup FONTS_Private_Function_Prototypes
+  * @{
+  */ 
+/**
+  * @}
+  */ 
+
+
+/** @defgroup FONTS_Private_Functions
+  * @{
+  */
+    
+/**
+  * @}
+  */
+  
+/**
+  * @}
+  */ 
+
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */  
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/stmcube/Utilities/Fonts/font20.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/stmcube/Utilities/Fonts/font20.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/stmcube/Utilities/Fonts/font20.c	(revision 457)
@@ -0,0 +1,2223 @@
+/**
+  ******************************************************************************
+  * @file    font20.c
+  * @author  MCD Application Team
+  * @version V1.0.0
+  * @date    18-February-2014
+  * @brief   This file provides text font20 for STM32xx-EVAL's LCD driver. 
+  ******************************************************************************
+  * @attention
+  *
+  * <h2><center>&copy; COPYRIGHT(c) 2014 STMicroelectronics</center></h2>
+  *
+  * 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 STMicroelectronics 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.
+  *
+  ******************************************************************************
+  */
+
+/* Includes ------------------------------------------------------------------*/
+#include "fonts.h"
+
+/** @addtogroup Utilities
+  * @{
+  */
+  
+/** @addtogroup STM32_EVAL
+  * @{
+  */ 
+
+/** @addtogroup Common
+  * @{
+  */
+
+/** @addtogroup FONTS
+  * @brief      This file provides text font20 for STM32xx-EVAL's LCD driver.
+  * @{
+  */  
+
+/** @defgroup FONTS_Private_Types
+  * @{
+  */ 
+/**
+  * @}
+  */ 
+
+
+/** @defgroup FONTS_Private_Defines
+  * @{
+  */
+/**
+  * @}
+  */ 
+
+
+/** @defgroup FONTS_Private_Macros
+  * @{
+  */
+/**
+  * @}
+  */ 
+  
+
+/** @defgroup FONTS_Private_Variables
+  * @{
+  */
+
+// Character bitmaps for Courier New 15pt
+const uint8_t Font20_Table[] = 
+{
+	// @0 ' ' (14 pixels wide)
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+
+	// @40 '!' (14 pixels wide)
+	0x00, 0x00, //               
+	0x07, 0x00, //      ###      
+	0x07, 0x00, //      ###      
+	0x07, 0x00, //      ###      
+	0x07, 0x00, //      ###      
+	0x07, 0x00, //      ###      
+	0x07, 0x00, //      ###      
+	0x07, 0x00, //      ###      
+	0x02, 0x00, //       #       
+	0x02, 0x00, //       #       
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x07, 0x00, //      ###      
+	0x07, 0x00, //      ###      
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+
+	// @80 '"' (14 pixels wide)
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x1C, 0xE0, //    ###  ###   
+	0x1C, 0xE0, //    ###  ###   
+	0x1C, 0xE0, //    ###  ###   
+	0x08, 0x40, //     #    #    
+	0x08, 0x40, //     #    #    
+	0x08, 0x40, //     #    #    
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+
+	// @120 '#' (14 pixels wide)
+	0x0C, 0xC0, //     ##  ##    
+	0x0C, 0xC0, //     ##  ##    
+	0x0C, 0xC0, //     ##  ##    
+	0x0C, 0xC0, //     ##  ##    
+	0x0C, 0xC0, //     ##  ##    
+	0x3F, 0xF0, //   ##########  
+	0x3F, 0xF0, //   ##########  
+	0x0C, 0xC0, //     ##  ##    
+	0x0C, 0xC0, //     ##  ##    
+	0x3F, 0xF0, //   ##########  
+	0x3F, 0xF0, //   ##########  
+	0x0C, 0xC0, //     ##  ##    
+	0x0C, 0xC0, //     ##  ##    
+	0x0C, 0xC0, //     ##  ##    
+	0x0C, 0xC0, //     ##  ##    
+	0x0C, 0xC0, //     ##  ##    
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+
+	// @160 '$' (14 pixels wide)
+	0x03, 0x00, //       ##      
+	0x03, 0x00, //       ##      
+	0x07, 0xE0, //      ######   
+	0x0F, 0xE0, //     #######   
+	0x18, 0x60, //    ##    ##   
+	0x18, 0x00, //    ##         
+	0x1F, 0x00, //    #####      
+	0x0F, 0xC0, //     ######    
+	0x00, 0xE0, //         ###   
+	0x18, 0x60, //    ##    ##   
+	0x18, 0x60, //    ##    ##   
+	0x1F, 0xC0, //    #######    
+	0x1F, 0x80, //    ######     
+	0x03, 0x00, //       ##      
+	0x03, 0x00, //       ##      
+	0x03, 0x00, //       ##      
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+
+	// @200 '%' (14 pixels wide)
+	0x00, 0x00, //               
+	0x1C, 0x00, //    ###        
+	0x22, 0x00, //   #   #       
+	0x22, 0x00, //   #   #       
+	0x22, 0x00, //   #   #       
+	0x1C, 0x60, //    ###   ##   
+	0x01, 0xE0, //        ####   
+	0x0F, 0x80, //     #####     
+	0x3C, 0x00, //   ####        
+	0x31, 0xC0, //   ##   ###    
+	0x02, 0x20, //       #   #   
+	0x02, 0x20, //       #   #   
+	0x02, 0x20, //       #   #   
+	0x01, 0xC0, //        ###    
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+
+	// @240 '&' (14 pixels wide)
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x03, 0xE0, //       #####   
+	0x0F, 0xE0, //     #######   
+	0x0C, 0x00, //     ##        
+	0x0C, 0x00, //     ##        
+	0x06, 0x00, //      ##       
+	0x0F, 0x30, //     ####  ##  
+	0x1F, 0xF0, //    #########  
+	0x19, 0xE0, //    ##  ####   
+	0x18, 0xC0, //    ##   ##    
+	0x1F, 0xF0, //    #########  
+	0x07, 0xB0, //      #### ##  
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+
+	// @280 ''' (14 pixels wide)
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x03, 0x80, //       ###     
+	0x03, 0x80, //       ###     
+	0x03, 0x80, //       ###     
+	0x01, 0x00, //        #      
+	0x01, 0x00, //        #      
+	0x01, 0x00, //        #      
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+
+	// @320 '(' (14 pixels wide)
+	0x00, 0x00, //               
+	0x00, 0xC0, //         ##    
+	0x00, 0xC0, //         ##    
+	0x01, 0x80, //        ##     
+	0x01, 0x80, //        ##     
+	0x01, 0x80, //        ##     
+	0x03, 0x00, //       ##      
+	0x03, 0x00, //       ##      
+	0x03, 0x00, //       ##      
+	0x03, 0x00, //       ##      
+	0x03, 0x00, //       ##      
+	0x03, 0x00, //       ##      
+	0x01, 0x80, //        ##     
+	0x01, 0x80, //        ##     
+	0x01, 0x80, //        ##     
+	0x00, 0xC0, //         ##    
+	0x00, 0xC0, //         ##    
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+
+	// @360 ')' (14 pixels wide)
+	0x00, 0x00, //               
+	0x0C, 0x00, //     ##        
+	0x0C, 0x00, //     ##        
+	0x06, 0x00, //      ##       
+	0x06, 0x00, //      ##       
+	0x06, 0x00, //      ##       
+	0x03, 0x00, //       ##      
+	0x03, 0x00, //       ##      
+	0x03, 0x00, //       ##      
+	0x03, 0x00, //       ##      
+	0x03, 0x00, //       ##      
+	0x03, 0x00, //       ##      
+	0x06, 0x00, //      ##       
+	0x06, 0x00, //      ##       
+	0x06, 0x00, //      ##       
+	0x0C, 0x00, //     ##        
+	0x0C, 0x00, //     ##        
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+
+	// @400 '*' (14 pixels wide)
+	0x00, 0x00, //               
+	0x03, 0x00, //       ##      
+	0x03, 0x00, //       ##      
+	0x03, 0x00, //       ##      
+	0x1B, 0x60, //    ## ## ##   
+	0x1F, 0xE0, //    ########   
+	0x07, 0x80, //      ####     
+	0x07, 0x80, //      ####     
+	0x0F, 0xC0, //     ######    
+	0x0C, 0xC0, //     ##  ##    
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+
+	// @440 '+' (14 pixels wide)
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x03, 0x00, //       ##      
+	0x03, 0x00, //       ##      
+	0x03, 0x00, //       ##      
+	0x03, 0x00, //       ##      
+	0x3F, 0xF0, //   ##########  
+	0x3F, 0xF0, //   ##########  
+	0x03, 0x00, //       ##      
+	0x03, 0x00, //       ##      
+	0x03, 0x00, //       ##      
+	0x03, 0x00, //       ##      
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+
+	// @480 ',' (14 pixels wide)
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x03, 0x80, //       ###     
+	0x03, 0x00, //       ##      
+	0x03, 0x00, //       ##      
+	0x06, 0x00, //      ##       
+	0x06, 0x00, //      ##       
+	0x04, 0x00, //      #        
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+
+	// @520 '-' (14 pixels wide)
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x3F, 0xE0, //   #########   
+	0x3F, 0xE0, //   #########   
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+
+	// @560 '.' (14 pixels wide)
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x03, 0x80, //       ###     
+	0x03, 0x80, //       ###     
+	0x03, 0x80, //       ###     
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+
+	// @600 '/' (14 pixels wide)
+	0x00, 0x60, //          ##   
+	0x00, 0x60, //          ##   
+	0x00, 0xC0, //         ##    
+	0x00, 0xC0, //         ##    
+	0x00, 0xC0, //         ##    
+	0x01, 0x80, //        ##     
+	0x01, 0x80, //        ##     
+	0x03, 0x00, //       ##      
+	0x03, 0x00, //       ##      
+	0x06, 0x00, //      ##       
+	0x06, 0x00, //      ##       
+	0x0C, 0x00, //     ##        
+	0x0C, 0x00, //     ##        
+	0x0C, 0x00, //     ##        
+	0x18, 0x00, //    ##         
+	0x18, 0x00, //    ##         
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+
+	// @640 '0' (14 pixels wide)
+	0x00, 0x00, //               
+	0x0F, 0x80, //     #####     
+	0x1F, 0xC0, //    #######    
+	0x18, 0xC0, //    ##   ##    
+	0x30, 0x60, //   ##     ##   
+	0x30, 0x60, //   ##     ##   
+	0x30, 0x60, //   ##     ##   
+	0x30, 0x60, //   ##     ##   
+	0x30, 0x60, //   ##     ##   
+	0x30, 0x60, //   ##     ##   
+	0x30, 0x60, //   ##     ##   
+	0x18, 0xC0, //    ##   ##    
+	0x1F, 0xC0, //    #######    
+	0x0F, 0x80, //     #####     
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+
+	// @680 '1' (14 pixels wide)
+	0x00, 0x00, //               
+	0x03, 0x00, //       ##      
+	0x1F, 0x00, //    #####      
+	0x1F, 0x00, //    #####      
+	0x03, 0x00, //       ##      
+	0x03, 0x00, //       ##      
+	0x03, 0x00, //       ##      
+	0x03, 0x00, //       ##      
+	0x03, 0x00, //       ##      
+	0x03, 0x00, //       ##      
+	0x03, 0x00, //       ##      
+	0x03, 0x00, //       ##      
+	0x1F, 0xE0, //    ########   
+	0x1F, 0xE0, //    ########   
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+
+	// @720 '2' (14 pixels wide)
+	0x00, 0x00, //               
+	0x0F, 0x80, //     #####     
+	0x1F, 0xC0, //    #######    
+	0x38, 0xE0, //   ###   ###   
+	0x30, 0x60, //   ##     ##   
+	0x00, 0x60, //          ##   
+	0x00, 0xC0, //         ##    
+	0x01, 0x80, //        ##     
+	0x03, 0x00, //       ##      
+	0x06, 0x00, //      ##       
+	0x0C, 0x00, //     ##        
+	0x18, 0x00, //    ##         
+	0x3F, 0xE0, //   #########   
+	0x3F, 0xE0, //   #########   
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+
+	// @760 '3' (14 pixels wide)
+	0x00, 0x00, //               
+	0x0F, 0x80, //     #####     
+	0x3F, 0xC0, //   ########    
+	0x30, 0xE0, //   ##    ###   
+	0x00, 0x60, //          ##   
+	0x00, 0xE0, //         ###   
+	0x07, 0xC0, //      #####    
+	0x07, 0xC0, //      #####    
+	0x00, 0xE0, //         ###   
+	0x00, 0x60, //          ##   
+	0x00, 0x60, //          ##   
+	0x60, 0xE0, //  ##     ###   
+	0x7F, 0xC0, //  #########    
+	0x3F, 0x80, //   #######     
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+
+	// @800 '4' (14 pixels wide)
+	0x00, 0x00, //               
+	0x01, 0xC0, //        ###    
+	0x03, 0xC0, //       ####    
+	0x03, 0xC0, //       ####    
+	0x06, 0xC0, //      ## ##    
+	0x0C, 0xC0, //     ##  ##    
+	0x0C, 0xC0, //     ##  ##    
+	0x18, 0xC0, //    ##   ##    
+	0x30, 0xC0, //   ##    ##    
+	0x3F, 0xE0, //   #########   
+	0x3F, 0xE0, //   #########   
+	0x00, 0xC0, //         ##    
+	0x03, 0xE0, //       #####   
+	0x03, 0xE0, //       #####   
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+
+	// @840 '5' (14 pixels wide)
+	0x00, 0x00, //               
+	0x1F, 0xC0, //    #######    
+	0x1F, 0xC0, //    #######    
+	0x18, 0x00, //    ##         
+	0x18, 0x00, //    ##         
+	0x1F, 0x80, //    ######     
+	0x1F, 0xC0, //    #######    
+	0x18, 0xE0, //    ##   ###   
+	0x00, 0x60, //          ##   
+	0x00, 0x60, //          ##   
+	0x00, 0x60, //          ##   
+	0x30, 0xE0, //   ##    ###   
+	0x3F, 0xC0, //   ########    
+	0x1F, 0x80, //    ######     
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+
+	// @880 '6' (14 pixels wide)
+	0x00, 0x00, //               
+	0x03, 0xE0, //       #####   
+	0x0F, 0xE0, //     #######   
+	0x1E, 0x00, //    ####       
+	0x18, 0x00, //    ##         
+	0x38, 0x00, //   ###         
+	0x37, 0x80, //   ## ####     
+	0x3F, 0xC0, //   ########    
+	0x38, 0xE0, //   ###   ###   
+	0x30, 0x60, //   ##     ##   
+	0x30, 0x60, //   ##     ##   
+	0x18, 0xE0, //    ##   ###   
+	0x1F, 0xC0, //    #######    
+	0x07, 0x80, //      ####     
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+
+	// @920 '7' (14 pixels wide)
+	0x00, 0x00, //               
+	0x3F, 0xE0, //   #########   
+	0x3F, 0xE0, //   #########   
+	0x30, 0x60, //   ##     ##   
+	0x00, 0x60, //          ##   
+	0x00, 0xC0, //         ##    
+	0x00, 0xC0, //         ##    
+	0x00, 0xC0, //         ##    
+	0x01, 0x80, //        ##     
+	0x01, 0x80, //        ##     
+	0x01, 0x80, //        ##     
+	0x03, 0x00, //       ##      
+	0x03, 0x00, //       ##      
+	0x03, 0x00, //       ##      
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+
+	// @960 '8' (14 pixels wide)
+	0x00, 0x00, //               
+	0x0F, 0x80, //     #####     
+	0x1F, 0xC0, //    #######    
+	0x38, 0xE0, //   ###   ###   
+	0x30, 0x60, //   ##     ##   
+	0x38, 0xE0, //   ###   ###   
+	0x1F, 0xC0, //    #######    
+	0x1F, 0xC0, //    #######    
+	0x38, 0xE0, //   ###   ###   
+	0x30, 0x60, //   ##     ##   
+	0x30, 0x60, //   ##     ##   
+	0x38, 0xE0, //   ###   ###   
+	0x1F, 0xC0, //    #######    
+	0x0F, 0x80, //     #####     
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+
+	// @1000 '9' (14 pixels wide)
+	0x00, 0x00, //               
+	0x0F, 0x00, //     ####      
+	0x1F, 0xC0, //    #######    
+	0x38, 0xC0, //   ###   ##    
+	0x30, 0x60, //   ##     ##   
+	0x30, 0x60, //   ##     ##   
+	0x38, 0xE0, //   ###   ###   
+	0x1F, 0xE0, //    ########   
+	0x0F, 0x60, //     #### ##   
+	0x00, 0xE0, //         ###   
+	0x00, 0xC0, //         ##    
+	0x03, 0xC0, //       ####    
+	0x3F, 0x80, //   #######     
+	0x3E, 0x00, //   #####       
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+
+	// @1040 ':' (14 pixels wide)
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x03, 0x80, //       ###     
+	0x03, 0x80, //       ###     
+	0x03, 0x80, //       ###     
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x03, 0x80, //       ###     
+	0x03, 0x80, //       ###     
+	0x03, 0x80, //       ###     
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+
+	// @1080 ';' (14 pixels wide)
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x01, 0xC0, //        ###    
+	0x01, 0xC0, //        ###    
+	0x01, 0xC0, //        ###    
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x03, 0x80, //       ###     
+	0x03, 0x00, //       ##      
+	0x06, 0x00, //      ##       
+	0x06, 0x00, //      ##       
+	0x04, 0x00, //      #        
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+
+	// @1120 '<' (14 pixels wide)
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x30, //           ##  
+	0x00, 0xF0, //         ####  
+	0x03, 0xC0, //       ####    
+	0x07, 0x00, //      ###      
+	0x1C, 0x00, //    ###        
+	0x78, 0x00, //  ####         
+	0x1C, 0x00, //    ###        
+	0x07, 0x00, //      ###      
+	0x03, 0xC0, //       ####    
+	0x00, 0xF0, //         ####  
+	0x00, 0x30, //           ##  
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+
+	// @1160 '=' (14 pixels wide)
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x7F, 0xF0, //  ###########  
+	0x7F, 0xF0, //  ###########  
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x7F, 0xF0, //  ###########  
+	0x7F, 0xF0, //  ###########  
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+
+	// @1200 '>' (14 pixels wide)
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x30, 0x00, //   ##          
+	0x3C, 0x00, //   ####        
+	0x0F, 0x00, //     ####      
+	0x03, 0x80, //       ###     
+	0x00, 0xE0, //         ###   
+	0x00, 0x78, //          #### 
+	0x00, 0xE0, //         ###   
+	0x03, 0x80, //       ###     
+	0x0F, 0x00, //     ####      
+	0x3C, 0x00, //   ####        
+	0x30, 0x00, //   ##          
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+
+	// @1240 '?' (14 pixels wide)
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x0F, 0x80, //     #####     
+	0x1F, 0xC0, //    #######    
+	0x18, 0x60, //    ##    ##   
+	0x18, 0x60, //    ##    ##   
+	0x00, 0x60, //          ##   
+	0x01, 0xC0, //        ###    
+	0x03, 0x80, //       ###     
+	0x03, 0x00, //       ##      
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x07, 0x00, //      ###      
+	0x07, 0x00, //      ###      
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+
+	// @1280 '@' (14 pixels wide)
+	0x00, 0x00, //               
+	0x03, 0x80, //       ###     
+	0x0C, 0x80, //     ##  #     
+	0x08, 0x40, //     #    #    
+	0x10, 0x40, //    #     #    
+	0x10, 0x40, //    #     #    
+	0x11, 0xC0, //    #   ###    
+	0x12, 0x40, //    #  #  #    
+	0x12, 0x40, //    #  #  #    
+	0x12, 0x40, //    #  #  #    
+	0x11, 0xC0, //    #   ###    
+	0x10, 0x00, //    #          
+	0x08, 0x00, //     #         
+	0x08, 0x40, //     #    #    
+	0x07, 0x80, //      ####     
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+
+	// @1320 'A' (14 pixels wide)
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x1F, 0x80, //    ######     
+	0x1F, 0x80, //    ######     
+	0x03, 0x80, //       ###     
+	0x06, 0xC0, //      ## ##    
+	0x06, 0xC0, //      ## ##    
+	0x0C, 0xC0, //     ##  ##    
+	0x0C, 0x60, //     ##   ##   
+	0x1F, 0xE0, //    ########   
+	0x1F, 0xE0, //    ########   
+	0x30, 0x30, //   ##      ##  
+	0x78, 0x78, //  ####    #### 
+	0x78, 0x78, //  ####    #### 
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+
+	// @1360 'B' (14 pixels wide)
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x3F, 0x80, //   #######     
+	0x3F, 0xC0, //   ########    
+	0x18, 0x60, //    ##    ##   
+	0x18, 0x60, //    ##    ##   
+	0x18, 0xE0, //    ##   ###   
+	0x1F, 0xC0, //    #######    
+	0x1F, 0xE0, //    ########   
+	0x18, 0x70, //    ##    ###  
+	0x18, 0x30, //    ##     ##  
+	0x18, 0x30, //    ##     ##  
+	0x3F, 0xF0, //   ##########  
+	0x3F, 0xE0, //   #########   
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+
+	// @1400 'C' (14 pixels wide)
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x07, 0xB0, //      #### ##  
+	0x0F, 0xF0, //     ########  
+	0x1C, 0x70, //    ###   ###  
+	0x38, 0x30, //   ###     ##  
+	0x30, 0x00, //   ##          
+	0x30, 0x00, //   ##          
+	0x30, 0x00, //   ##          
+	0x30, 0x00, //   ##          
+	0x38, 0x30, //   ###     ##  
+	0x1C, 0x70, //    ###   ###  
+	0x0F, 0xE0, //     #######   
+	0x07, 0xC0, //      #####    
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+
+	// @1440 'D' (14 pixels wide)
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x7F, 0x80, //  ########     
+	0x7F, 0xC0, //  #########    
+	0x30, 0xE0, //   ##    ###   
+	0x30, 0x70, //   ##     ###  
+	0x30, 0x30, //   ##      ##  
+	0x30, 0x30, //   ##      ##  
+	0x30, 0x30, //   ##      ##  
+	0x30, 0x30, //   ##      ##  
+	0x30, 0x70, //   ##     ###  
+	0x30, 0xE0, //   ##    ###   
+	0x7F, 0xC0, //  #########    
+	0x7F, 0x80, //  ########     
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+
+	// @1480 'E' (14 pixels wide)
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x3F, 0xF0, //   ##########  
+	0x3F, 0xF0, //   ##########  
+	0x18, 0x30, //    ##     ##  
+	0x18, 0x30, //    ##     ##  
+	0x19, 0x80, //    ##  ##     
+	0x1F, 0x80, //    ######     
+	0x1F, 0x80, //    ######     
+	0x19, 0x80, //    ##  ##     
+	0x18, 0x30, //    ##     ##  
+	0x18, 0x30, //    ##     ##  
+	0x3F, 0xF0, //   ##########  
+	0x3F, 0xF0, //   ##########  
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+
+	// @1520 'F' (14 pixels wide)
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x3F, 0xF0, //   ##########  
+	0x3F, 0xF0, //   ##########  
+	0x18, 0x30, //    ##     ##  
+	0x18, 0x30, //    ##     ##  
+	0x19, 0x80, //    ##  ##     
+	0x1F, 0x80, //    ######     
+	0x1F, 0x80, //    ######     
+	0x19, 0x80, //    ##  ##     
+	0x18, 0x00, //    ##         
+	0x18, 0x00, //    ##         
+	0x3F, 0x00, //   ######      
+	0x3F, 0x00, //   ######      
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+
+	// @1560 'G' (14 pixels wide)
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x07, 0xB0, //      #### ##  
+	0x1F, 0xF0, //    #########  
+	0x18, 0x70, //    ##    ###  
+	0x30, 0x30, //   ##      ##  
+	0x30, 0x00, //   ##          
+	0x30, 0x00, //   ##          
+	0x31, 0xF8, //   ##   ###### 
+	0x31, 0xF8, //   ##   ###### 
+	0x30, 0x30, //   ##      ##  
+	0x18, 0x30, //    ##     ##  
+	0x1F, 0xF0, //    #########  
+	0x07, 0xC0, //      #####    
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+
+	// @1600 'H' (14 pixels wide)
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x3C, 0xF0, //   ####  ####  
+	0x3C, 0xF0, //   ####  ####  
+	0x18, 0x60, //    ##    ##   
+	0x18, 0x60, //    ##    ##   
+	0x18, 0x60, //    ##    ##   
+	0x1F, 0xE0, //    ########   
+	0x1F, 0xE0, //    ########   
+	0x18, 0x60, //    ##    ##   
+	0x18, 0x60, //    ##    ##   
+	0x18, 0x60, //    ##    ##   
+	0x3C, 0xF0, //   ####  ####  
+	0x3C, 0xF0, //   ####  ####  
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+
+	// @1640 'I' (14 pixels wide)
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x1F, 0xE0, //    ########   
+	0x1F, 0xE0, //    ########   
+	0x03, 0x00, //       ##      
+	0x03, 0x00, //       ##      
+	0x03, 0x00, //       ##      
+	0x03, 0x00, //       ##      
+	0x03, 0x00, //       ##      
+	0x03, 0x00, //       ##      
+	0x03, 0x00, //       ##      
+	0x03, 0x00, //       ##      
+	0x1F, 0xE0, //    ########   
+	0x1F, 0xE0, //    ########   
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+
+	// @1680 'J' (14 pixels wide)
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x03, 0xF8, //       ####### 
+	0x03, 0xF8, //       ####### 
+	0x00, 0x60, //          ##   
+	0x00, 0x60, //          ##   
+	0x00, 0x60, //          ##   
+	0x00, 0x60, //          ##   
+	0x30, 0x60, //   ##     ##   
+	0x30, 0x60, //   ##     ##   
+	0x30, 0x60, //   ##     ##   
+	0x30, 0xE0, //   ##    ###   
+	0x3F, 0xC0, //   ########    
+	0x0F, 0x80, //     #####     
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+
+	// @1720 'K' (14 pixels wide)
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x3E, 0xF8, //   ##### ##### 
+	0x3E, 0xF8, //   ##### ##### 
+	0x18, 0xE0, //    ##   ###   
+	0x19, 0x80, //    ##  ##     
+	0x1B, 0x00, //    ## ##      
+	0x1F, 0x00, //    #####      
+	0x1D, 0x80, //    ### ##     
+	0x18, 0xC0, //    ##   ##    
+	0x18, 0xC0, //    ##   ##    
+	0x18, 0x60, //    ##    ##   
+	0x3E, 0x78, //   #####  #### 
+	0x3E, 0x38, //   #####   ### 
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+
+	// @1760 'L' (14 pixels wide)
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x3F, 0x00, //   ######      
+	0x3F, 0x00, //   ######      
+	0x0C, 0x00, //     ##        
+	0x0C, 0x00, //     ##        
+	0x0C, 0x00, //     ##        
+	0x0C, 0x00, //     ##        
+	0x0C, 0x00, //     ##        
+	0x0C, 0x30, //     ##    ##  
+	0x0C, 0x30, //     ##    ##  
+	0x0C, 0x30, //     ##    ##  
+	0x3F, 0xF0, //   ##########  
+	0x3F, 0xF0, //   ##########  
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+
+	// @1800 'M' (14 pixels wide)
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x78, 0x78, //  ####    #### 
+	0x78, 0x78, //  ####    #### 
+	0x38, 0x70, //   ###    ###  
+	0x3C, 0xF0, //   ####  ####  
+	0x34, 0xB0, //   ## #  # ##  
+	0x37, 0xB0, //   ## #### ##  
+	0x37, 0xB0, //   ## #### ##  
+	0x33, 0x30, //   ##  ##  ##  
+	0x33, 0x30, //   ##  ##  ##  
+	0x30, 0x30, //   ##      ##  
+	0x7C, 0xF8, //  #####  ##### 
+	0x7C, 0xF8, //  #####  ##### 
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+
+	// @1840 'N' (14 pixels wide)
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x39, 0xF0, //   ###  #####  
+	0x3D, 0xF0, //   #### #####  
+	0x1C, 0x60, //    ###   ##   
+	0x1E, 0x60, //    ####  ##   
+	0x1E, 0x60, //    ####  ##   
+	0x1B, 0x60, //    ## ## ##   
+	0x1B, 0x60, //    ## ## ##   
+	0x19, 0xE0, //    ##  ####   
+	0x19, 0xE0, //    ##  ####   
+	0x18, 0xE0, //    ##   ###   
+	0x3E, 0xE0, //   ##### ###   
+	0x3E, 0x60, //   #####  ##   
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+
+	// @1880 'O' (14 pixels wide)
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x07, 0x80, //      ####     
+	0x0F, 0xC0, //     ######    
+	0x1C, 0xE0, //    ###  ###   
+	0x38, 0x70, //   ###    ###  
+	0x30, 0x30, //   ##      ##  
+	0x30, 0x30, //   ##      ##  
+	0x30, 0x30, //   ##      ##  
+	0x30, 0x30, //   ##      ##  
+	0x38, 0x70, //   ###    ###  
+	0x1C, 0xE0, //    ###  ###   
+	0x0F, 0xC0, //     ######    
+	0x07, 0x80, //      ####     
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+
+	// @1920 'P' (14 pixels wide)
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x3F, 0xC0, //   ########    
+	0x3F, 0xE0, //   #########   
+	0x18, 0x70, //    ##    ###  
+	0x18, 0x30, //    ##     ##  
+	0x18, 0x30, //    ##     ##  
+	0x18, 0x70, //    ##    ###  
+	0x1F, 0xE0, //    ########   
+	0x1F, 0xC0, //    #######    
+	0x18, 0x00, //    ##         
+	0x18, 0x00, //    ##         
+	0x3F, 0x00, //   ######      
+	0x3F, 0x00, //   ######      
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+
+	// @1960 'Q' (14 pixels wide)
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x07, 0x80, //      ####     
+	0x0F, 0xC0, //     ######    
+	0x1C, 0xE0, //    ###  ###   
+	0x38, 0x70, //   ###    ###  
+	0x30, 0x30, //   ##      ##  
+	0x30, 0x30, //   ##      ##  
+	0x30, 0x30, //   ##      ##  
+	0x30, 0x30, //   ##      ##  
+	0x38, 0x70, //   ###    ###  
+	0x1C, 0xE0, //    ###  ###   
+	0x0F, 0xC0, //     ######    
+	0x07, 0x80, //      ####     
+	0x07, 0xB0, //      #### ##  
+	0x0F, 0xF0, //     ########  
+	0x0C, 0xE0, //     ##  ###   
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+
+	// @2000 'R' (14 pixels wide)
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x3F, 0xC0, //   ########    
+	0x3F, 0xE0, //   #########   
+	0x18, 0x70, //    ##    ###  
+	0x18, 0x30, //    ##     ##  
+	0x18, 0x70, //    ##    ###  
+	0x1F, 0xE0, //    ########   
+	0x1F, 0xC0, //    #######    
+	0x18, 0xE0, //    ##   ###   
+	0x18, 0x60, //    ##    ##   
+	0x18, 0x70, //    ##    ###  
+	0x3E, 0x38, //   #####   ### 
+	0x3E, 0x18, //   #####    ## 
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+
+	// @2040 'S' (14 pixels wide)
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x0F, 0xB0, //     ##### ##  
+	0x1F, 0xF0, //    #########  
+	0x38, 0x70, //   ###    ###  
+	0x30, 0x30, //   ##      ##  
+	0x38, 0x00, //   ###         
+	0x1F, 0x80, //    ######     
+	0x07, 0xE0, //      ######   
+	0x00, 0x70, //          ###  
+	0x30, 0x30, //   ##      ##  
+	0x38, 0x70, //   ###    ###  
+	0x3F, 0xE0, //   #########   
+	0x37, 0xC0, //   ## #####    
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+
+	// @2080 'T' (14 pixels wide)
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x3F, 0xF0, //   ##########  
+	0x3F, 0xF0, //   ##########  
+	0x33, 0x30, //   ##  ##  ##  
+	0x33, 0x30, //   ##  ##  ##  
+	0x33, 0x30, //   ##  ##  ##  
+	0x03, 0x00, //       ##      
+	0x03, 0x00, //       ##      
+	0x03, 0x00, //       ##      
+	0x03, 0x00, //       ##      
+	0x03, 0x00, //       ##      
+	0x0F, 0xC0, //     ######    
+	0x0F, 0xC0, //     ######    
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+
+	// @2120 'U' (14 pixels wide)
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x3C, 0xF0, //   ####  ####  
+	0x3C, 0xF0, //   ####  ####  
+	0x18, 0x60, //    ##    ##   
+	0x18, 0x60, //    ##    ##   
+	0x18, 0x60, //    ##    ##   
+	0x18, 0x60, //    ##    ##   
+	0x18, 0x60, //    ##    ##   
+	0x18, 0x60, //    ##    ##   
+	0x18, 0x60, //    ##    ##   
+	0x1C, 0xE0, //    ###  ###   
+	0x0F, 0xC0, //     ######    
+	0x07, 0x80, //      ####     
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+
+	// @2160 'V' (14 pixels wide)
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x78, 0xF0, //  ####   ####  
+	0x78, 0xF0, //  ####   ####  
+	0x30, 0x60, //   ##     ##   
+	0x30, 0x60, //   ##     ##   
+	0x18, 0xC0, //    ##   ##    
+	0x18, 0xC0, //    ##   ##    
+	0x0D, 0x80, //     ## ##     
+	0x0D, 0x80, //     ## ##     
+	0x0D, 0x80, //     ## ##     
+	0x07, 0x00, //      ###      
+	0x07, 0x00, //      ###      
+	0x07, 0x00, //      ###      
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+
+	// @2200 'W' (14 pixels wide)
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x7C, 0x7C, //  #####   #####
+	0x7C, 0x7C, //  #####   #####
+	0x30, 0x18, //   ##       ## 
+	0x33, 0x98, //   ##  ###  ## 
+	0x33, 0x98, //   ##  ###  ## 
+	0x33, 0x98, //   ##  ###  ## 
+	0x36, 0xD8, //   ## ## ## ## 
+	0x16, 0xD0, //    # ## ## #  
+	0x1C, 0x70, //    ###   ###  
+	0x1C, 0x70, //    ###   ###  
+	0x1C, 0x70, //    ###   ###  
+	0x18, 0x30, //    ##     ##  
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+
+	// @2240 'X' (14 pixels wide)
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x78, 0xF0, //  ####   ####  
+	0x78, 0xF0, //  ####   ####  
+	0x30, 0x60, //   ##     ##   
+	0x18, 0xC0, //    ##   ##    
+	0x0D, 0x80, //     ## ##     
+	0x07, 0x00, //      ###      
+	0x07, 0x00, //      ###      
+	0x0D, 0x80, //     ## ##     
+	0x18, 0xC0, //    ##   ##    
+	0x30, 0x60, //   ##     ##   
+	0x78, 0xF0, //  ####   ####  
+	0x78, 0xF0, //  ####   ####  
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+
+	// @2280 'Y' (14 pixels wide)
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x3C, 0xF0, //   ####  ####  
+	0x3C, 0xF0, //   ####  ####  
+	0x18, 0x60, //    ##    ##   
+	0x0C, 0xC0, //     ##  ##    
+	0x07, 0x80, //      ####     
+	0x07, 0x80, //      ####     
+	0x03, 0x00, //       ##      
+	0x03, 0x00, //       ##      
+	0x03, 0x00, //       ##      
+	0x03, 0x00, //       ##      
+	0x0F, 0xC0, //     ######    
+	0x0F, 0xC0, //     ######    
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+
+	// @2320 'Z' (14 pixels wide)
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x1F, 0xE0, //    ########   
+	0x1F, 0xE0, //    ########   
+	0x18, 0x60, //    ##    ##   
+	0x18, 0xC0, //    ##   ##    
+	0x01, 0x80, //        ##     
+	0x03, 0x00, //       ##      
+	0x03, 0x00, //       ##      
+	0x06, 0x00, //      ##       
+	0x0C, 0x60, //     ##   ##   
+	0x18, 0x60, //    ##    ##   
+	0x1F, 0xE0, //    ########   
+	0x1F, 0xE0, //    ########   
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+
+	// @2360 '[' (14 pixels wide)
+	0x00, 0x00, //               
+	0x03, 0xC0, //       ####    
+	0x03, 0xC0, //       ####    
+	0x03, 0x00, //       ##      
+	0x03, 0x00, //       ##      
+	0x03, 0x00, //       ##      
+	0x03, 0x00, //       ##      
+	0x03, 0x00, //       ##      
+	0x03, 0x00, //       ##      
+	0x03, 0x00, //       ##      
+	0x03, 0x00, //       ##      
+	0x03, 0x00, //       ##      
+	0x03, 0x00, //       ##      
+	0x03, 0x00, //       ##      
+	0x03, 0x00, //       ##      
+	0x03, 0xC0, //       ####    
+	0x03, 0xC0, //       ####    
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+
+	// @2400 '\' (14 pixels wide)
+	0x18, 0x00, //    ##         
+	0x18, 0x00, //    ##         
+	0x0C, 0x00, //     ##        
+	0x0C, 0x00, //     ##        
+	0x0C, 0x00, //     ##        
+	0x06, 0x00, //      ##       
+	0x06, 0x00, //      ##       
+	0x03, 0x00, //       ##      
+	0x03, 0x00, //       ##      
+	0x01, 0x80, //        ##     
+	0x01, 0x80, //        ##     
+	0x00, 0xC0, //         ##    
+	0x00, 0xC0, //         ##    
+	0x00, 0xC0, //         ##    
+	0x00, 0x60, //          ##   
+	0x00, 0x60, //          ##   
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+
+	// @2440 ']' (14 pixels wide)
+	0x00, 0x00, //               
+	0x0F, 0x00, //     ####      
+	0x0F, 0x00, //     ####      
+	0x03, 0x00, //       ##      
+	0x03, 0x00, //       ##      
+	0x03, 0x00, //       ##      
+	0x03, 0x00, //       ##      
+	0x03, 0x00, //       ##      
+	0x03, 0x00, //       ##      
+	0x03, 0x00, //       ##      
+	0x03, 0x00, //       ##      
+	0x03, 0x00, //       ##      
+	0x03, 0x00, //       ##      
+	0x03, 0x00, //       ##      
+	0x03, 0x00, //       ##      
+	0x0F, 0x00, //     ####      
+	0x0F, 0x00, //     ####      
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+
+	// @2480 '^' (14 pixels wide)
+	0x00, 0x00, //               
+	0x02, 0x00, //       #       
+	0x07, 0x00, //      ###      
+	0x0D, 0x80, //     ## ##     
+	0x18, 0xC0, //    ##   ##    
+	0x30, 0x60, //   ##     ##   
+	0x20, 0x20, //   #       #   
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+
+	// @2520 '_' (14 pixels wide)
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0xFF, 0xFC, // ##############
+	0xFF, 0xFC, // ##############
+
+	// @2560 '`' (14 pixels wide)
+	0x00, 0x00, //               
+	0x04, 0x00, //      #        
+	0x03, 0x00, //       ##      
+	0x00, 0x80, //         #     
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+
+	// @2600 'a' (14 pixels wide)
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x0F, 0xC0, //     ######    
+	0x1F, 0xE0, //    ########   
+	0x00, 0x60, //          ##   
+	0x0F, 0xE0, //     #######   
+	0x1F, 0xE0, //    ########   
+	0x38, 0x60, //   ###    ##   
+	0x30, 0xE0, //   ##    ###   
+	0x3F, 0xF0, //   ##########  
+	0x1F, 0x70, //    ##### ###  
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+
+	// @2640 'b' (14 pixels wide)
+	0x00, 0x00, //               
+	0x70, 0x00, //  ###          
+	0x70, 0x00, //  ###          
+	0x30, 0x00, //   ##          
+	0x30, 0x00, //   ##          
+	0x37, 0x80, //   ## ####     
+	0x3F, 0xE0, //   #########   
+	0x38, 0x60, //   ###    ##   
+	0x30, 0x30, //   ##      ##  
+	0x30, 0x30, //   ##      ##  
+	0x30, 0x30, //   ##      ##  
+	0x38, 0x60, //   ###    ##   
+	0x7F, 0xE0, //  ##########   
+	0x77, 0x80, //  ### ####     
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+
+	// @2680 'c' (14 pixels wide)
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x07, 0xB0, //      #### ##  
+	0x1F, 0xF0, //    #########  
+	0x18, 0x30, //    ##     ##  
+	0x30, 0x30, //   ##      ##  
+	0x30, 0x00, //   ##          
+	0x30, 0x00, //   ##          
+	0x38, 0x30, //   ###     ##  
+	0x1F, 0xF0, //    #########  
+	0x0F, 0xC0, //     ######    
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+
+	// @2720 'd' (14 pixels wide)
+	0x00, 0x00, //               
+	0x00, 0x70, //          ###  
+	0x00, 0x70, //          ###  
+	0x00, 0x30, //           ##  
+	0x00, 0x30, //           ##  
+	0x07, 0xB0, //      #### ##  
+	0x1F, 0xF0, //    #########  
+	0x18, 0x70, //    ##    ###  
+	0x30, 0x30, //   ##      ##  
+	0x30, 0x30, //   ##      ##  
+	0x30, 0x30, //   ##      ##  
+	0x38, 0x70, //   ###    ###  
+	0x1F, 0xF8, //    ########## 
+	0x07, 0xB8, //      #### ### 
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+
+	// @2760 'e' (14 pixels wide)
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x07, 0x80, //      ####     
+	0x1F, 0xE0, //    ########   
+	0x18, 0x60, //    ##    ##   
+	0x3F, 0xF0, //   ##########  
+	0x3F, 0xF0, //   ##########  
+	0x30, 0x00, //   ##          
+	0x18, 0x30, //    ##     ##  
+	0x1F, 0xF0, //    #########  
+	0x07, 0xC0, //      #####    
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+
+	// @2800 'f' (14 pixels wide)
+	0x00, 0x00, //               
+	0x03, 0xF0, //       ######  
+	0x07, 0xF0, //      #######  
+	0x06, 0x00, //      ##       
+	0x06, 0x00, //      ##       
+	0x1F, 0xE0, //    ########   
+	0x1F, 0xE0, //    ########   
+	0x06, 0x00, //      ##       
+	0x06, 0x00, //      ##       
+	0x06, 0x00, //      ##       
+	0x06, 0x00, //      ##       
+	0x06, 0x00, //      ##       
+	0x1F, 0xE0, //    ########   
+	0x1F, 0xE0, //    ########   
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+
+	// @2840 'g' (14 pixels wide)
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x07, 0xB8, //      #### ### 
+	0x1F, 0xF8, //    ########## 
+	0x18, 0x70, //    ##    ###  
+	0x30, 0x30, //   ##      ##  
+	0x30, 0x30, //   ##      ##  
+	0x30, 0x30, //   ##      ##  
+	0x18, 0x70, //    ##    ###  
+	0x1F, 0xF0, //    #########  
+	0x07, 0xB0, //      #### ##  
+	0x00, 0x30, //           ##  
+	0x00, 0x70, //          ###  
+	0x0F, 0xE0, //     #######   
+	0x0F, 0xC0, //     ######    
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+
+	// @2880 'h' (14 pixels wide)
+	0x00, 0x00, //               
+	0x38, 0x00, //   ###         
+	0x38, 0x00, //   ###         
+	0x18, 0x00, //    ##         
+	0x18, 0x00, //    ##         
+	0x1B, 0xC0, //    ## ####    
+	0x1F, 0xE0, //    ########   
+	0x1C, 0x60, //    ###   ##   
+	0x18, 0x60, //    ##    ##   
+	0x18, 0x60, //    ##    ##   
+	0x18, 0x60, //    ##    ##   
+	0x18, 0x60, //    ##    ##   
+	0x3C, 0xF0, //   ####  ####  
+	0x3C, 0xF0, //   ####  ####  
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+
+	// @2920 'i' (14 pixels wide)
+	0x00, 0x00, //               
+	0x03, 0x00, //       ##      
+	0x03, 0x00, //       ##      
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x1F, 0x00, //    #####      
+	0x1F, 0x00, //    #####      
+	0x03, 0x00, //       ##      
+	0x03, 0x00, //       ##      
+	0x03, 0x00, //       ##      
+	0x03, 0x00, //       ##      
+	0x03, 0x00, //       ##      
+	0x1F, 0xE0, //    ########   
+	0x1F, 0xE0, //    ########   
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+
+	// @2960 'j' (14 pixels wide)
+	0x00, 0x00, //               
+	0x03, 0x00, //       ##      
+	0x03, 0x00, //       ##      
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x1F, 0xC0, //    #######    
+	0x1F, 0xC0, //    #######    
+	0x00, 0xC0, //         ##    
+	0x00, 0xC0, //         ##    
+	0x00, 0xC0, //         ##    
+	0x00, 0xC0, //         ##    
+	0x00, 0xC0, //         ##    
+	0x00, 0xC0, //         ##    
+	0x00, 0xC0, //         ##    
+	0x00, 0xC0, //         ##    
+	0x01, 0xC0, //        ###    
+	0x3F, 0x80, //   #######     
+	0x3F, 0x00, //   ######      
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+
+	// @3000 'k' (14 pixels wide)
+	0x00, 0x00, //               
+	0x38, 0x00, //   ###         
+	0x38, 0x00, //   ###         
+	0x18, 0x00, //    ##         
+	0x18, 0x00, //    ##         
+	0x1B, 0xE0, //    ## #####   
+	0x1B, 0xE0, //    ## #####   
+	0x1B, 0x00, //    ## ##      
+	0x1E, 0x00, //    ####       
+	0x1E, 0x00, //    ####       
+	0x1B, 0x00, //    ## ##      
+	0x19, 0x80, //    ##  ##     
+	0x39, 0xF0, //   ###  #####  
+	0x39, 0xF0, //   ###  #####  
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+
+	// @3040 'l' (14 pixels wide)
+	0x00, 0x00, //               
+	0x1F, 0x00, //    #####      
+	0x1F, 0x00, //    #####      
+	0x03, 0x00, //       ##      
+	0x03, 0x00, //       ##      
+	0x03, 0x00, //       ##      
+	0x03, 0x00, //       ##      
+	0x03, 0x00, //       ##      
+	0x03, 0x00, //       ##      
+	0x03, 0x00, //       ##      
+	0x03, 0x00, //       ##      
+	0x03, 0x00, //       ##      
+	0x1F, 0xE0, //    ########   
+	0x1F, 0xE0, //    ########   
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+
+	// @3080 'm' (14 pixels wide)
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x7E, 0xE0, //  ###### ###   
+	0x7F, 0xF0, //  ###########  
+	0x33, 0x30, //   ##  ##  ##  
+	0x33, 0x30, //   ##  ##  ##  
+	0x33, 0x30, //   ##  ##  ##  
+	0x33, 0x30, //   ##  ##  ##  
+	0x33, 0x30, //   ##  ##  ##  
+	0x7B, 0xB8, //  #### ### ### 
+	0x7B, 0xB8, //  #### ### ### 
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+
+	// @3120 'n' (14 pixels wide)
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x3B, 0xC0, //   ### ####    
+	0x3F, 0xE0, //   #########   
+	0x1C, 0x60, //    ###   ##   
+	0x18, 0x60, //    ##    ##   
+	0x18, 0x60, //    ##    ##   
+	0x18, 0x60, //    ##    ##   
+	0x18, 0x60, //    ##    ##   
+	0x3C, 0xF0, //   ####  ####  
+	0x3C, 0xF0, //   ####  ####  
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+
+	// @3160 'o' (14 pixels wide)
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x07, 0x80, //      ####     
+	0x1F, 0xE0, //    ########   
+	0x18, 0x60, //    ##    ##   
+	0x30, 0x30, //   ##      ##  
+	0x30, 0x30, //   ##      ##  
+	0x30, 0x30, //   ##      ##  
+	0x18, 0x60, //    ##    ##   
+	0x1F, 0xE0, //    ########   
+	0x07, 0x80, //      ####     
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+
+	// @3200 'p' (14 pixels wide)
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x77, 0x80, //  ### ####     
+	0x7F, 0xE0, //  ##########   
+	0x38, 0x60, //   ###    ##   
+	0x30, 0x30, //   ##      ##  
+	0x30, 0x30, //   ##      ##  
+	0x30, 0x30, //   ##      ##  
+	0x38, 0x60, //   ###    ##   
+	0x3F, 0xE0, //   #########   
+	0x37, 0x80, //   ## ####     
+	0x30, 0x00, //   ##          
+	0x30, 0x00, //   ##          
+	0x7C, 0x00, //  #####        
+	0x7C, 0x00, //  #####        
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+
+	// @3240 'q' (14 pixels wide)
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x07, 0xB8, //      #### ### 
+	0x1F, 0xF8, //    ########## 
+	0x18, 0x70, //    ##    ###  
+	0x30, 0x30, //   ##      ##  
+	0x30, 0x30, //   ##      ##  
+	0x30, 0x30, //   ##      ##  
+	0x18, 0x70, //    ##    ###  
+	0x1F, 0xF0, //    #########  
+	0x07, 0xB0, //      #### ##  
+	0x00, 0x30, //           ##  
+	0x00, 0x30, //           ##  
+	0x00, 0xF8, //         ##### 
+	0x00, 0xF8, //         ##### 
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+
+	// @3280 'r' (14 pixels wide)
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x3C, 0xE0, //   ####  ###   
+	0x3D, 0xF0, //   #### #####  
+	0x0F, 0x30, //     ####  ##  
+	0x0E, 0x00, //     ###       
+	0x0C, 0x00, //     ##        
+	0x0C, 0x00, //     ##        
+	0x0C, 0x00, //     ##        
+	0x3F, 0xC0, //   ########    
+	0x3F, 0xC0, //   ########    
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+
+	// @3320 's' (14 pixels wide)
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x07, 0xE0, //      ######   
+	0x1F, 0xE0, //    ########   
+	0x18, 0x60, //    ##    ##   
+	0x1E, 0x00, //    ####       
+	0x0F, 0xC0, //     ######    
+	0x01, 0xE0, //        ####   
+	0x18, 0x60, //    ##    ##   
+	0x1F, 0xE0, //    ########   
+	0x1F, 0x80, //    ######     
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+
+	// @3360 't' (14 pixels wide)
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x0C, 0x00, //     ##        
+	0x0C, 0x00, //     ##        
+	0x0C, 0x00, //     ##        
+	0x3F, 0xE0, //   #########   
+	0x3F, 0xE0, //   #########   
+	0x0C, 0x00, //     ##        
+	0x0C, 0x00, //     ##        
+	0x0C, 0x00, //     ##        
+	0x0C, 0x00, //     ##        
+	0x0C, 0x30, //     ##    ##  
+	0x0F, 0xF0, //     ########  
+	0x07, 0xC0, //      #####    
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+
+	// @3400 'u' (14 pixels wide)
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x38, 0xE0, //   ###   ###   
+	0x38, 0xE0, //   ###   ###   
+	0x18, 0x60, //    ##    ##   
+	0x18, 0x60, //    ##    ##   
+	0x18, 0x60, //    ##    ##   
+	0x18, 0x60, //    ##    ##   
+	0x18, 0xE0, //    ##   ###   
+	0x1F, 0xF0, //    #########  
+	0x0F, 0x70, //     #### ###  
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+
+	// @3440 'v' (14 pixels wide)
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x78, 0xF0, //  ####   ####  
+	0x78, 0xF0, //  ####   ####  
+	0x30, 0x60, //   ##     ##   
+	0x18, 0xC0, //    ##   ##    
+	0x18, 0xC0, //    ##   ##    
+	0x0D, 0x80, //     ## ##     
+	0x0D, 0x80, //     ## ##     
+	0x07, 0x00, //      ###      
+	0x07, 0x00, //      ###      
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+
+	// @3480 'w' (14 pixels wide)
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x78, 0xF0, //  ####   ####  
+	0x78, 0xF0, //  ####   ####  
+	0x32, 0x60, //   ##  #  ##   
+	0x32, 0x60, //   ##  #  ##   
+	0x37, 0xE0, //   ## ######   
+	0x1D, 0xC0, //    ### ###    
+	0x1D, 0xC0, //    ### ###    
+	0x18, 0xC0, //    ##   ##    
+	0x18, 0xC0, //    ##   ##    
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+
+	// @3520 'x' (14 pixels wide)
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x3C, 0xF0, //   ####  ####  
+	0x3C, 0xF0, //   ####  ####  
+	0x0C, 0xC0, //     ##  ##    
+	0x07, 0x80, //      ####     
+	0x03, 0x00, //       ##      
+	0x07, 0x80, //      ####     
+	0x0C, 0xC0, //     ##  ##    
+	0x3C, 0xF0, //   ####  ####  
+	0x3C, 0xF0, //   ####  ####  
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+
+	// @3560 'y' (14 pixels wide)
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x78, 0xF0, //  ####   ####  
+	0x78, 0xF0, //  ####   ####  
+	0x30, 0x60, //   ##     ##   
+	0x18, 0xC0, //    ##   ##    
+	0x18, 0xC0, //    ##   ##    
+	0x0D, 0x80, //     ## ##     
+	0x0F, 0x80, //     #####     
+	0x07, 0x00, //      ###      
+	0x06, 0x00, //      ##       
+	0x06, 0x00, //      ##       
+	0x0C, 0x00, //     ##        
+	0x7F, 0x00, //  #######      
+	0x7F, 0x00, //  #######      
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+
+	// @3600 'z' (14 pixels wide)
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x1F, 0xE0, //    ########   
+	0x1F, 0xE0, //    ########   
+	0x18, 0xC0, //    ##   ##    
+	0x01, 0x80, //        ##     
+	0x03, 0x00, //       ##      
+	0x06, 0x00, //      ##       
+	0x0C, 0x60, //     ##   ##   
+	0x1F, 0xE0, //    ########   
+	0x1F, 0xE0, //    ########   
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+
+	// @3640 '{' (14 pixels wide)
+	0x00, 0x00, //               
+	0x01, 0xC0, //        ###    
+	0x03, 0xC0, //       ####    
+	0x03, 0x00, //       ##      
+	0x03, 0x00, //       ##      
+	0x03, 0x00, //       ##      
+	0x03, 0x00, //       ##      
+	0x03, 0x00, //       ##      
+	0x07, 0x00, //      ###      
+	0x0E, 0x00, //     ###       
+	0x07, 0x00, //      ###      
+	0x03, 0x00, //       ##      
+	0x03, 0x00, //       ##      
+	0x03, 0x00, //       ##      
+	0x03, 0x00, //       ##      
+	0x03, 0xC0, //       ####    
+	0x01, 0xC0, //        ###    
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+
+	// @3680 '|' (14 pixels wide)
+	0x00, 0x00, //               
+	0x03, 0x00, //       ##      
+	0x03, 0x00, //       ##      
+	0x03, 0x00, //       ##      
+	0x03, 0x00, //       ##      
+	0x03, 0x00, //       ##      
+	0x03, 0x00, //       ##      
+	0x03, 0x00, //       ##      
+	0x03, 0x00, //       ##      
+	0x03, 0x00, //       ##      
+	0x03, 0x00, //       ##      
+	0x03, 0x00, //       ##      
+	0x03, 0x00, //       ##      
+	0x03, 0x00, //       ##      
+	0x03, 0x00, //       ##      
+	0x03, 0x00, //       ##      
+	0x03, 0x00, //       ##      
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+
+	// @3720 '}' (14 pixels wide)
+	0x00, 0x00, //               
+	0x1C, 0x00, //    ###        
+	0x1E, 0x00, //    ####       
+	0x06, 0x00, //      ##       
+	0x06, 0x00, //      ##       
+	0x06, 0x00, //      ##       
+	0x06, 0x00, //      ##       
+	0x06, 0x00, //      ##       
+	0x07, 0x00, //      ###      
+	0x03, 0x80, //       ###     
+	0x07, 0x00, //      ###      
+	0x06, 0x00, //      ##       
+	0x06, 0x00, //      ##       
+	0x06, 0x00, //      ##       
+	0x06, 0x00, //      ##       
+	0x1E, 0x00, //    ####       
+	0x1C, 0x00, //    ###        
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+
+	// @3760 '~' (14 pixels wide)
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x0E, 0x00, //     ###       
+	0x3F, 0x30, //   ######  ##  
+	0x33, 0xF0, //   ##  ######  
+	0x01, 0xE0, //        ####   
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+	0x00, 0x00, //               
+};
+
+
+sFONT Font20 = {
+  Font20_Table,
+  14, /* Width */
+  20, /* Height */
+};
+
+/**
+  * @}
+  */ 
+
+
+/** @defgroup FONTS_Private_Function_Prototypes
+  * @{
+  */ 
+/**
+  * @}
+  */ 
+
+
+/** @defgroup FONTS_Private_Functions
+  * @{
+  */
+    
+/**
+  * @}
+  */
+  
+/**
+  * @}
+  */ 
+
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */  
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/stmcube/Utilities/Fonts/font24.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/stmcube/Utilities/Fonts/font24.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/stmcube/Utilities/Fonts/font24.c	(revision 457)
@@ -0,0 +1,2600 @@
+/**
+  ******************************************************************************
+  * @file    font24.c
+  * @author  MCD Application Team
+  * @version V1.0.0
+  * @date    18-February-2014
+  * @brief   This file provides text font24 for STM32xx-EVAL's LCD driver. 
+  ******************************************************************************
+  * @attention
+  *
+  * <h2><center>&copy; COPYRIGHT(c) 2014 STMicroelectronics</center></h2>
+  *
+  * 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 STMicroelectronics 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.
+  *
+  ******************************************************************************
+  */
+
+/* Includes ------------------------------------------------------------------*/
+#include "fonts.h"
+
+/** @addtogroup Utilities
+  * @{
+  */
+  
+/** @addtogroup STM32_EVAL
+  * @{
+  */ 
+
+/** @addtogroup Common
+  * @{
+  */
+
+/** @addtogroup FONTS
+  * @brief      This file provides text font24 for STM32xx-EVAL's LCD driver.
+  * @{
+  */  
+
+/** @defgroup FONTS_Private_Types
+  * @{
+  */ 
+/**
+  * @}
+  */ 
+
+
+/** @defgroup FONTS_Private_Defines
+  * @{
+  */
+/**
+  * @}
+  */ 
+
+
+/** @defgroup FONTS_Private_Macros
+  * @{
+  */
+/**
+  * @}
+  */ 
+  
+
+/** @defgroup FONTS_Private_Variables
+  * @{
+  */
+const uint8_t Font24_Table [] = 
+{
+	// @0 ' ' (17 pixels wide)
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+
+	// @72 '!' (17 pixels wide)
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x03, 0x80, 0x00, //       ###        
+	0x03, 0x80, 0x00, //       ###        
+	0x03, 0x80, 0x00, //       ###        
+	0x03, 0x80, 0x00, //       ###        
+	0x03, 0x80, 0x00, //       ###        
+	0x03, 0x80, 0x00, //       ###        
+	0x03, 0x80, 0x00, //       ###        
+	0x03, 0x80, 0x00, //       ###        
+	0x03, 0x80, 0x00, //       ###        
+	0x01, 0x00, 0x00, //        #         
+	0x01, 0x00, 0x00, //        #         
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x03, 0x80, 0x00, //       ###        
+	0x03, 0x80, 0x00, //       ###        
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+
+	// @144 '"' (17 pixels wide)
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x0E, 0x70, 0x00, //     ###  ###     
+	0x0E, 0x70, 0x00, //     ###  ###     
+	0x0E, 0x70, 0x00, //     ###  ###     
+	0x04, 0x20, 0x00, //      #    #      
+	0x04, 0x20, 0x00, //      #    #      
+	0x04, 0x20, 0x00, //      #    #      
+	0x04, 0x20, 0x00, //      #    #      
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+
+	// @216 '#' (17 pixels wide)
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x06, 0x60, 0x00, //      ##  ##      
+	0x06, 0x60, 0x00, //      ##  ##      
+	0x06, 0x60, 0x00, //      ##  ##      
+	0x06, 0x60, 0x00, //      ##  ##      
+	0x06, 0x60, 0x00, //      ##  ##      
+	0x3F, 0xF8, 0x00, //   ###########    
+	0x3F, 0xF8, 0x00, //   ###########    
+	0x06, 0x60, 0x00, //      ##  ##      
+	0x0C, 0xC0, 0x00, //     ##  ##       
+	0x3F, 0xF8, 0x00, //   ###########    
+	0x3F, 0xF8, 0x00, //   ###########    
+	0x0C, 0xC0, 0x00, //     ##  ##       
+	0x0C, 0xC0, 0x00, //     ##  ##       
+	0x0C, 0xC0, 0x00, //     ##  ##       
+	0x0C, 0xC0, 0x00, //     ##  ##       
+	0x0C, 0xC0, 0x00, //     ##  ##       
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+
+	// @288 '$' (17 pixels wide)
+	0x00, 0x00, 0x00, //                  
+	0x01, 0x80, 0x00, //        ##        
+	0x01, 0x80, 0x00, //        ##        
+	0x07, 0xB0, 0x00, //      #### ##     
+	0x0F, 0xF0, 0x00, //     ########     
+	0x18, 0x70, 0x00, //    ##    ###     
+	0x18, 0x70, 0x00, //    ##    ###     
+	0x1C, 0x00, 0x00, //    ###           
+	0x0F, 0x80, 0x00, //     #####        
+	0x07, 0xE0, 0x00, //      ######      
+	0x00, 0xF0, 0x00, //         ####     
+	0x18, 0x30, 0x00, //    ##     ##     
+	0x1C, 0x30, 0x00, //    ###    ##     
+	0x1C, 0x70, 0x00, //    ###   ###     
+	0x1F, 0xE0, 0x00, //    ########      
+	0x1B, 0xC0, 0x00, //    ## ####       
+	0x01, 0x80, 0x00, //        ##        
+	0x01, 0x80, 0x00, //        ##        
+	0x01, 0x80, 0x00, //        ##        
+	0x01, 0x80, 0x00, //        ##        
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+
+	// @360 '%' (17 pixels wide)
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x07, 0x80, 0x00, //      ####        
+	0x0F, 0xC0, 0x00, //     ######       
+	0x1C, 0xE0, 0x00, //    ###  ###      
+	0x18, 0x60, 0x00, //    ##    ##      
+	0x18, 0x60, 0x00, //    ##    ##      
+	0x1C, 0xE0, 0x00, //    ###  ###      
+	0x0F, 0xF8, 0x00, //     #########    
+	0x07, 0xE0, 0x00, //      ######      
+	0x1F, 0xF0, 0x00, //    #########     
+	0x07, 0x38, 0x00, //      ###  ###    
+	0x06, 0x18, 0x00, //      ##    ##    
+	0x06, 0x18, 0x00, //      ##    ##    
+	0x07, 0x38, 0x00, //      ###  ###    
+	0x03, 0xF0, 0x00, //       ######     
+	0x01, 0xE0, 0x00, //        ####      
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+
+	// @432 '&' (17 pixels wide)
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x03, 0xF0, 0x00, //       ######     
+	0x07, 0xF0, 0x00, //      #######     
+	0x0C, 0x60, 0x00, //     ##   ##      
+	0x0C, 0x00, 0x00, //     ##           
+	0x0C, 0x00, 0x00, //     ##           
+	0x06, 0x00, 0x00, //      ##          
+	0x07, 0x00, 0x00, //      ###         
+	0x0F, 0x9C, 0x00, //     #####  ###   
+	0x1D, 0xFC, 0x00, //    ### #######   
+	0x18, 0xF0, 0x00, //    ##   ####     
+	0x18, 0x70, 0x00, //    ##    ###     
+	0x0F, 0xFC, 0x00, //     ##########   
+	0x07, 0xDC, 0x00, //      ##### ###   
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+
+	// @504 ''' (17 pixels wide)
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x03, 0x80, 0x00, //       ###        
+	0x03, 0x80, 0x00, //       ###        
+	0x03, 0x80, 0x00, //       ###        
+	0x01, 0x00, 0x00, //        #         
+	0x01, 0x00, 0x00, //        #         
+	0x01, 0x00, 0x00, //        #         
+	0x01, 0x00, 0x00, //        #         
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+
+	// @576 '(' (17 pixels wide)
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x18, 0x00, //            ##    
+	0x00, 0x38, 0x00, //           ###    
+	0x00, 0x70, 0x00, //          ###     
+	0x00, 0xF0, 0x00, //         ####     
+	0x00, 0xE0, 0x00, //         ###      
+	0x00, 0xE0, 0x00, //         ###      
+	0x01, 0xC0, 0x00, //        ###       
+	0x01, 0xC0, 0x00, //        ###       
+	0x01, 0xC0, 0x00, //        ###       
+	0x01, 0xC0, 0x00, //        ###       
+	0x01, 0xC0, 0x00, //        ###       
+	0x01, 0xC0, 0x00, //        ###       
+	0x00, 0xE0, 0x00, //         ###      
+	0x00, 0xE0, 0x00, //         ###      
+	0x00, 0x70, 0x00, //          ###     
+	0x00, 0x70, 0x00, //          ###     
+	0x00, 0x38, 0x00, //           ###    
+	0x00, 0x18, 0x00, //            ##    
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+
+	// @648 ')' (17 pixels wide)
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x18, 0x00, 0x00, //    ##            
+	0x1C, 0x00, 0x00, //    ###           
+	0x0E, 0x00, 0x00, //     ###          
+	0x0E, 0x00, 0x00, //     ###          
+	0x07, 0x00, 0x00, //      ###         
+	0x07, 0x00, 0x00, //      ###         
+	0x03, 0x80, 0x00, //       ###        
+	0x03, 0x80, 0x00, //       ###        
+	0x03, 0x80, 0x00, //       ###        
+	0x03, 0x80, 0x00, //       ###        
+	0x03, 0x80, 0x00, //       ###        
+	0x03, 0x80, 0x00, //       ###        
+	0x07, 0x00, 0x00, //      ###         
+	0x07, 0x00, 0x00, //      ###         
+	0x0F, 0x00, 0x00, //     ####         
+	0x0E, 0x00, 0x00, //     ###          
+	0x1C, 0x00, 0x00, //    ###           
+	0x18, 0x00, 0x00, //    ##            
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+
+	// @720 '*' (17 pixels wide)
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x01, 0x80, 0x00, //        ##        
+	0x01, 0x80, 0x00, //        ##        
+	0x01, 0x80, 0x00, //        ##        
+	0x1D, 0xB8, 0x00, //    ### ## ###    
+	0x1F, 0xF8, 0x00, //    ##########    
+	0x07, 0xE0, 0x00, //      ######      
+	0x03, 0xC0, 0x00, //       ####       
+	0x03, 0xC0, 0x00, //       ####       
+	0x06, 0x60, 0x00, //      ##  ##      
+	0x06, 0x60, 0x00, //      ##  ##      
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+
+	// @792 '+' (17 pixels wide)
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x01, 0x80, 0x00, //        ##        
+	0x01, 0x80, 0x00, //        ##        
+	0x01, 0x80, 0x00, //        ##        
+	0x01, 0x80, 0x00, //        ##        
+	0x01, 0x80, 0x00, //        ##        
+	0x3F, 0xFC, 0x00, //   ############   
+	0x3F, 0xFC, 0x00, //   ############   
+	0x01, 0x80, 0x00, //        ##        
+	0x01, 0x80, 0x00, //        ##        
+	0x01, 0x80, 0x00, //        ##        
+	0x01, 0x80, 0x00, //        ##        
+	0x01, 0x80, 0x00, //        ##        
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+
+	// @864 ',' (17 pixels wide)
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0xE0, 0x00, //         ###      
+	0x00, 0xC0, 0x00, //         ##       
+	0x01, 0xC0, 0x00, //        ###       
+	0x01, 0x80, 0x00, //        ##        
+	0x01, 0x80, 0x00, //        ##        
+	0x03, 0x00, 0x00, //       ##         
+	0x03, 0x00, 0x00, //       ##         
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+
+	// @936 '-' (17 pixels wide)
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x1F, 0xF8, 0x00, //    ##########    
+	0x1F, 0xF8, 0x00, //    ##########    
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+
+	// @1008 '.' (17 pixels wide)
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x03, 0xC0, 0x00, //       ####       
+	0x03, 0xC0, 0x00, //       ####       
+	0x03, 0xC0, 0x00, //       ####       
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+
+	// @1080 '/' (17 pixels wide)
+	0x00, 0x18, 0x00, //            ##    
+	0x00, 0x18, 0x00, //            ##    
+	0x00, 0x38, 0x00, //           ###    
+	0x00, 0x30, 0x00, //           ##     
+	0x00, 0x70, 0x00, //          ###     
+	0x00, 0x60, 0x00, //          ##      
+	0x00, 0x60, 0x00, //          ##      
+	0x00, 0xC0, 0x00, //         ##       
+	0x00, 0xC0, 0x00, //         ##       
+	0x01, 0x80, 0x00, //        ##        
+	0x01, 0x80, 0x00, //        ##        
+	0x03, 0x00, 0x00, //       ##         
+	0x03, 0x00, 0x00, //       ##         
+	0x06, 0x00, 0x00, //      ##          
+	0x06, 0x00, 0x00, //      ##          
+	0x0E, 0x00, 0x00, //     ###          
+	0x0C, 0x00, 0x00, //     ##           
+	0x1C, 0x00, 0x00, //    ###           
+	0x18, 0x00, 0x00, //    ##            
+	0x18, 0x00, 0x00, //    ##            
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+
+	// @1152 '0' (17 pixels wide)
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x03, 0xC0, 0x00, //       ####       
+	0x07, 0xE0, 0x00, //      ######      
+	0x0C, 0x30, 0x00, //     ##    ##     
+	0x0C, 0x30, 0x00, //     ##    ##     
+	0x18, 0x18, 0x00, //    ##      ##    
+	0x18, 0x18, 0x00, //    ##      ##    
+	0x18, 0x18, 0x00, //    ##      ##    
+	0x18, 0x18, 0x00, //    ##      ##    
+	0x18, 0x18, 0x00, //    ##      ##    
+	0x18, 0x18, 0x00, //    ##      ##    
+	0x18, 0x18, 0x00, //    ##      ##    
+	0x0C, 0x30, 0x00, //     ##    ##     
+	0x0C, 0x30, 0x00, //     ##    ##     
+	0x07, 0xE0, 0x00, //      ######      
+	0x03, 0xC0, 0x00, //       ####       
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+
+	// @1224 '1' (17 pixels wide)
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x80, 0x00, //         #        
+	0x07, 0x80, 0x00, //      ####        
+	0x1F, 0x80, 0x00, //    ######        
+	0x1D, 0x80, 0x00, //    ### ##        
+	0x01, 0x80, 0x00, //        ##        
+	0x01, 0x80, 0x00, //        ##        
+	0x01, 0x80, 0x00, //        ##        
+	0x01, 0x80, 0x00, //        ##        
+	0x01, 0x80, 0x00, //        ##        
+	0x01, 0x80, 0x00, //        ##        
+	0x01, 0x80, 0x00, //        ##        
+	0x01, 0x80, 0x00, //        ##        
+	0x01, 0x80, 0x00, //        ##        
+	0x1F, 0xF8, 0x00, //    ##########    
+	0x1F, 0xF8, 0x00, //    ##########    
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+
+	// @1296 '2' (17 pixels wide)
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x07, 0xC0, 0x00, //      #####       
+	0x1F, 0xF0, 0x00, //    #########     
+	0x38, 0x30, 0x00, //   ###     ##     
+	0x30, 0x18, 0x00, //   ##       ##    
+	0x30, 0x18, 0x00, //   ##       ##    
+	0x00, 0x18, 0x00, //            ##    
+	0x00, 0x30, 0x00, //           ##     
+	0x00, 0x60, 0x00, //          ##      
+	0x01, 0xC0, 0x00, //        ###       
+	0x03, 0x80, 0x00, //       ###        
+	0x06, 0x00, 0x00, //      ##          
+	0x0C, 0x00, 0x00, //     ##           
+	0x18, 0x00, 0x00, //    ##            
+	0x3F, 0xF8, 0x00, //   ###########    
+	0x3F, 0xF8, 0x00, //   ###########    
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+
+	// @1368 '3' (17 pixels wide)
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x03, 0xC0, 0x00, //       ####       
+	0x0F, 0xE0, 0x00, //     #######      
+	0x0C, 0x70, 0x00, //     ##   ###     
+	0x00, 0x30, 0x00, //           ##     
+	0x00, 0x30, 0x00, //           ##     
+	0x00, 0x60, 0x00, //          ##      
+	0x03, 0xC0, 0x00, //       ####       
+	0x03, 0xE0, 0x00, //       #####      
+	0x00, 0x70, 0x00, //          ###     
+	0x00, 0x18, 0x00, //            ##    
+	0x00, 0x18, 0x00, //            ##    
+	0x00, 0x18, 0x00, //            ##    
+	0x18, 0x38, 0x00, //    ##     ###    
+	0x1F, 0xF0, 0x00, //    #########     
+	0x0F, 0xC0, 0x00, //     ######       
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+
+	// @1440 '4' (17 pixels wide)
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0xE0, 0x00, //         ###      
+	0x01, 0xE0, 0x00, //        ####      
+	0x01, 0xE0, 0x00, //        ####      
+	0x03, 0x60, 0x00, //       ## ##      
+	0x06, 0x60, 0x00, //      ##  ##      
+	0x06, 0x60, 0x00, //      ##  ##      
+	0x0C, 0x60, 0x00, //     ##   ##      
+	0x0C, 0x60, 0x00, //     ##   ##      
+	0x18, 0x60, 0x00, //    ##    ##      
+	0x30, 0x60, 0x00, //   ##     ##      
+	0x3F, 0xF8, 0x00, //   ###########    
+	0x3F, 0xF8, 0x00, //   ###########    
+	0x00, 0x60, 0x00, //          ##      
+	0x03, 0xF8, 0x00, //       #######    
+	0x03, 0xF8, 0x00, //       #######    
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+
+	// @1512 '5' (17 pixels wide)
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x1F, 0xF0, 0x00, //    #########     
+	0x1F, 0xF0, 0x00, //    #########     
+	0x18, 0x00, 0x00, //    ##            
+	0x18, 0x00, 0x00, //    ##            
+	0x18, 0x00, 0x00, //    ##            
+	0x1B, 0xC0, 0x00, //    ## ####       
+	0x1F, 0xF0, 0x00, //    #########     
+	0x1C, 0x30, 0x00, //    ###    ##     
+	0x00, 0x18, 0x00, //            ##    
+	0x00, 0x18, 0x00, //            ##    
+	0x00, 0x18, 0x00, //            ##    
+	0x00, 0x18, 0x00, //            ##    
+	0x30, 0x30, 0x00, //   ##      ##     
+	0x3F, 0xF0, 0x00, //   ##########     
+	0x0F, 0xC0, 0x00, //     ######       
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+
+	// @1584 '6' (17 pixels wide)
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0xF8, 0x00, //         #####    
+	0x03, 0xF8, 0x00, //       #######    
+	0x07, 0x00, 0x00, //      ###         
+	0x0E, 0x00, 0x00, //     ###          
+	0x0C, 0x00, 0x00, //     ##           
+	0x18, 0x00, 0x00, //    ##            
+	0x1B, 0xC0, 0x00, //    ## ####       
+	0x1F, 0xF0, 0x00, //    #########     
+	0x1C, 0x30, 0x00, //    ###    ##     
+	0x18, 0x18, 0x00, //    ##      ##    
+	0x18, 0x18, 0x00, //    ##      ##    
+	0x18, 0x18, 0x00, //    ##      ##    
+	0x0C, 0x38, 0x00, //     ##    ###    
+	0x0F, 0xF0, 0x00, //     ########     
+	0x03, 0xE0, 0x00, //       #####      
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+
+	// @1656 '7' (17 pixels wide)
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x1F, 0xF8, 0x00, //    ##########    
+	0x1F, 0xF8, 0x00, //    ##########    
+	0x18, 0x18, 0x00, //    ##      ##    
+	0x18, 0x38, 0x00, //    ##     ###    
+	0x00, 0x30, 0x00, //           ##     
+	0x00, 0x30, 0x00, //           ##     
+	0x00, 0x70, 0x00, //          ###     
+	0x00, 0x60, 0x00, //          ##      
+	0x00, 0x60, 0x00, //          ##      
+	0x00, 0xE0, 0x00, //         ###      
+	0x00, 0xC0, 0x00, //         ##       
+	0x00, 0xC0, 0x00, //         ##       
+	0x01, 0xC0, 0x00, //        ###       
+	0x01, 0x80, 0x00, //        ##        
+	0x01, 0x80, 0x00, //        ##        
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+
+	// @1728 '8' (17 pixels wide)
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x07, 0xE0, 0x00, //      ######      
+	0x0F, 0xF0, 0x00, //     ########     
+	0x1C, 0x38, 0x00, //    ###    ###    
+	0x18, 0x18, 0x00, //    ##      ##    
+	0x18, 0x18, 0x00, //    ##      ##    
+	0x0C, 0x30, 0x00, //     ##    ##     
+	0x07, 0xE0, 0x00, //      ######      
+	0x07, 0xE0, 0x00, //      ######      
+	0x0C, 0x30, 0x00, //     ##    ##     
+	0x18, 0x18, 0x00, //    ##      ##    
+	0x18, 0x18, 0x00, //    ##      ##    
+	0x18, 0x18, 0x00, //    ##      ##    
+	0x1C, 0x38, 0x00, //    ###    ###    
+	0x0F, 0xF0, 0x00, //     ########     
+	0x07, 0xE0, 0x00, //      ######      
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+
+	// @1800 '9' (17 pixels wide)
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x07, 0xC0, 0x00, //      #####       
+	0x0F, 0xF0, 0x00, //     ########     
+	0x1C, 0x30, 0x00, //    ###    ##     
+	0x18, 0x18, 0x00, //    ##      ##    
+	0x18, 0x18, 0x00, //    ##      ##    
+	0x18, 0x18, 0x00, //    ##      ##    
+	0x0C, 0x38, 0x00, //     ##    ###    
+	0x0F, 0xF8, 0x00, //     #########    
+	0x03, 0xD8, 0x00, //       #### ##    
+	0x00, 0x18, 0x00, //            ##    
+	0x00, 0x30, 0x00, //           ##     
+	0x00, 0x70, 0x00, //          ###     
+	0x00, 0xE0, 0x00, //         ###      
+	0x1F, 0xC0, 0x00, //    #######       
+	0x1F, 0x00, 0x00, //    #####         
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+
+	// @1872 ':' (17 pixels wide)
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x03, 0xC0, 0x00, //       ####       
+	0x03, 0xC0, 0x00, //       ####       
+	0x03, 0xC0, 0x00, //       ####       
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x03, 0xC0, 0x00, //       ####       
+	0x03, 0xC0, 0x00, //       ####       
+	0x03, 0xC0, 0x00, //       ####       
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+
+	// @1944 ';' (17 pixels wide)
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0xF0, 0x00, //         ####     
+	0x00, 0xF0, 0x00, //         ####     
+	0x00, 0xF0, 0x00, //         ####     
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0xE0, 0x00, //         ###      
+	0x01, 0xC0, 0x00, //        ###       
+	0x01, 0x80, 0x00, //        ##        
+	0x01, 0x80, 0x00, //        ##        
+	0x03, 0x00, 0x00, //       ##         
+	0x02, 0x00, 0x00, //       #          
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+
+	// @2016 '<' (17 pixels wide)
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x1C, 0x00, //            ###   
+	0x00, 0x3C, 0x00, //           ####   
+	0x00, 0xF0, 0x00, //         ####     
+	0x03, 0xC0, 0x00, //       ####       
+	0x0F, 0x00, 0x00, //     ####         
+	0x3C, 0x00, 0x00, //   ####           
+	0xF0, 0x00, 0x00, // ####             
+	0x3C, 0x00, 0x00, //   ####           
+	0x0F, 0x00, 0x00, //     ####         
+	0x03, 0xC0, 0x00, //       ####       
+	0x00, 0xF0, 0x00, //         ####     
+	0x00, 0x3C, 0x00, //           ####   
+	0x00, 0x1C, 0x00, //            ###   
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+
+	// @2088 '=' (17 pixels wide)
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x7F, 0xFC, 0x00, //  #############   
+	0x7F, 0xFC, 0x00, //  #############   
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x7F, 0xFC, 0x00, //  #############   
+	0x7F, 0xFC, 0x00, //  #############   
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+
+	// @2160 '>' (17 pixels wide)
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x70, 0x00, 0x00, //  ###             
+	0x78, 0x00, 0x00, //  ####            
+	0x1E, 0x00, 0x00, //    ####          
+	0x07, 0x80, 0x00, //      ####        
+	0x01, 0xE0, 0x00, //        ####      
+	0x00, 0x78, 0x00, //          ####    
+	0x00, 0x1E, 0x00, //            ####  
+	0x00, 0x78, 0x00, //          ####    
+	0x01, 0xE0, 0x00, //        ####      
+	0x07, 0x80, 0x00, //      ####        
+	0x1E, 0x00, 0x00, //    ####          
+	0x78, 0x00, 0x00, //  ####            
+	0x70, 0x00, 0x00, //  ###             
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+
+	// @2232 '?' (17 pixels wide)
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x07, 0xC0, 0x00, //      #####       
+	0x0F, 0xE0, 0x00, //     #######      
+	0x18, 0x70, 0x00, //    ##    ###     
+	0x18, 0x30, 0x00, //    ##     ##     
+	0x18, 0x30, 0x00, //    ##     ##     
+	0x00, 0x70, 0x00, //          ###     
+	0x00, 0xE0, 0x00, //         ###      
+	0x03, 0xC0, 0x00, //       ####       
+	0x03, 0x80, 0x00, //       ###        
+	0x03, 0x00, 0x00, //       ##         
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x07, 0x00, 0x00, //      ###         
+	0x07, 0x00, 0x00, //      ###         
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+
+	// @2304 '@' (17 pixels wide)
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x03, 0xE0, 0x00, //       #####      
+	0x07, 0xF0, 0x00, //      #######     
+	0x0E, 0x38, 0x00, //     ###   ###    
+	0x0C, 0x18, 0x00, //     ##     ##    
+	0x18, 0x78, 0x00, //    ##    ####    
+	0x18, 0xF8, 0x00, //    ##   #####    
+	0x19, 0xD8, 0x00, //    ##  ### ##    
+	0x19, 0x98, 0x00, //    ##  ##  ##    
+	0x19, 0x98, 0x00, //    ##  ##  ##    
+	0x19, 0x98, 0x00, //    ##  ##  ##    
+	0x18, 0xF8, 0x00, //    ##   #####    
+	0x18, 0x78, 0x00, //    ##    ####    
+	0x18, 0x00, 0x00, //    ##            
+	0x0C, 0x00, 0x00, //     ##           
+	0x0E, 0x18, 0x00, //     ###    ##    
+	0x07, 0xF8, 0x00, //      ########    
+	0x03, 0xE0, 0x00, //       #####      
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+
+	// @2376 'A' (17 pixels wide)
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x1F, 0x80, 0x00, //    ######        
+	0x1F, 0xC0, 0x00, //    #######       
+	0x01, 0xC0, 0x00, //        ###       
+	0x03, 0x60, 0x00, //       ## ##      
+	0x03, 0x60, 0x00, //       ## ##      
+	0x06, 0x30, 0x00, //      ##   ##     
+	0x06, 0x30, 0x00, //      ##   ##     
+	0x0C, 0x30, 0x00, //     ##    ##     
+	0x0F, 0xF8, 0x00, //     #########    
+	0x1F, 0xF8, 0x00, //    ##########    
+	0x18, 0x0C, 0x00, //    ##       ##   
+	0x30, 0x0C, 0x00, //   ##        ##   
+	0xFC, 0x7F, 0x00, // ######   ####### 
+	0xFC, 0x7F, 0x00, // ######   ####### 
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+
+	// @2448 'B' (17 pixels wide)
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x7F, 0xE0, 0x00, //  ##########      
+	0x7F, 0xF0, 0x00, //  ###########     
+	0x18, 0x38, 0x00, //    ##     ###    
+	0x18, 0x18, 0x00, //    ##      ##    
+	0x18, 0x18, 0x00, //    ##      ##    
+	0x18, 0x38, 0x00, //    ##     ###    
+	0x1F, 0xF0, 0x00, //    #########     
+	0x1F, 0xF8, 0x00, //    ##########    
+	0x18, 0x1C, 0x00, //    ##      ###   
+	0x18, 0x0C, 0x00, //    ##       ##   
+	0x18, 0x0C, 0x00, //    ##       ##   
+	0x18, 0x0C, 0x00, //    ##       ##   
+	0x7F, 0xF8, 0x00, //  ############    
+	0x7F, 0xF0, 0x00, //  ###########     
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+
+	// @2520 'C' (17 pixels wide)
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x03, 0xEC, 0x00, //       ##### ##   
+	0x0F, 0xFC, 0x00, //     ##########   
+	0x1C, 0x1C, 0x00, //    ###     ###   
+	0x18, 0x0C, 0x00, //    ##       ##   
+	0x30, 0x0C, 0x00, //   ##        ##   
+	0x30, 0x00, 0x00, //   ##             
+	0x30, 0x00, 0x00, //   ##             
+	0x30, 0x00, 0x00, //   ##             
+	0x30, 0x00, 0x00, //   ##             
+	0x30, 0x00, 0x00, //   ##             
+	0x18, 0x0C, 0x00, //    ##       ##   
+	0x1C, 0x1C, 0x00, //    ###     ###   
+	0x0F, 0xF8, 0x00, //     #########    
+	0x03, 0xF0, 0x00, //       ######     
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+
+	// @2592 'D' (17 pixels wide)
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x7F, 0xC0, 0x00, //  #########       
+	0x7F, 0xF0, 0x00, //  ###########     
+	0x18, 0x38, 0x00, //    ##     ###    
+	0x18, 0x18, 0x00, //    ##      ##    
+	0x18, 0x0C, 0x00, //    ##       ##   
+	0x18, 0x0C, 0x00, //    ##       ##   
+	0x18, 0x0C, 0x00, //    ##       ##   
+	0x18, 0x0C, 0x00, //    ##       ##   
+	0x18, 0x0C, 0x00, //    ##       ##   
+	0x18, 0x0C, 0x00, //    ##       ##   
+	0x18, 0x18, 0x00, //    ##      ##    
+	0x18, 0x38, 0x00, //    ##     ###    
+	0x7F, 0xF0, 0x00, //  ###########     
+	0x7F, 0xE0, 0x00, //  ##########      
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+
+	// @2664 'E' (17 pixels wide)
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x7F, 0xF8, 0x00, //  ############    
+	0x7F, 0xF8, 0x00, //  ############    
+	0x18, 0x18, 0x00, //    ##      ##    
+	0x18, 0x18, 0x00, //    ##      ##    
+	0x19, 0x98, 0x00, //    ##  ##  ##    
+	0x19, 0x80, 0x00, //    ##  ##        
+	0x1F, 0x80, 0x00, //    ######        
+	0x1F, 0x80, 0x00, //    ######        
+	0x19, 0x80, 0x00, //    ##  ##        
+	0x19, 0x98, 0x00, //    ##  ##  ##    
+	0x18, 0x18, 0x00, //    ##      ##    
+	0x18, 0x18, 0x00, //    ##      ##    
+	0x7F, 0xF8, 0x00, //  ############    
+	0x7F, 0xF8, 0x00, //  ############    
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+
+	// @2736 'F' (17 pixels wide)
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x3F, 0xFC, 0x00, //   ############   
+	0x3F, 0xFC, 0x00, //   ############   
+	0x0C, 0x0C, 0x00, //     ##      ##   
+	0x0C, 0x0C, 0x00, //     ##      ##   
+	0x0C, 0xCC, 0x00, //     ##  ##  ##   
+	0x0C, 0xC0, 0x00, //     ##  ##       
+	0x0F, 0xC0, 0x00, //     ######       
+	0x0F, 0xC0, 0x00, //     ######       
+	0x0C, 0xC0, 0x00, //     ##  ##       
+	0x0C, 0xC0, 0x00, //     ##  ##       
+	0x0C, 0x00, 0x00, //     ##           
+	0x0C, 0x00, 0x00, //     ##           
+	0x3F, 0xC0, 0x00, //   ########       
+	0x3F, 0xC0, 0x00, //   ########       
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+
+	// @2808 'G' (17 pixels wide)
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x03, 0xEC, 0x00, //       ##### ##   
+	0x0F, 0xFC, 0x00, //     ##########   
+	0x1C, 0x1C, 0x00, //    ###     ###   
+	0x18, 0x0C, 0x00, //    ##       ##   
+	0x30, 0x0C, 0x00, //   ##        ##   
+	0x30, 0x00, 0x00, //   ##             
+	0x30, 0x00, 0x00, //   ##             
+	0x30, 0xFE, 0x00, //   ##    #######  
+	0x30, 0xFE, 0x00, //   ##    #######  
+	0x30, 0x0C, 0x00, //   ##        ##   
+	0x38, 0x0C, 0x00, //   ###       ##   
+	0x1C, 0x1C, 0x00, //    ###     ###   
+	0x0F, 0xFC, 0x00, //     ##########   
+	0x03, 0xF0, 0x00, //       ######     
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+
+	// @2880 'H' (17 pixels wide)
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x7E, 0x7E, 0x00, //  ######  ######  
+	0x7E, 0x7E, 0x00, //  ######  ######  
+	0x18, 0x18, 0x00, //    ##      ##    
+	0x18, 0x18, 0x00, //    ##      ##    
+	0x18, 0x18, 0x00, //    ##      ##    
+	0x18, 0x18, 0x00, //    ##      ##    
+	0x1F, 0xF8, 0x00, //    ##########    
+	0x1F, 0xF8, 0x00, //    ##########    
+	0x18, 0x18, 0x00, //    ##      ##    
+	0x18, 0x18, 0x00, //    ##      ##    
+	0x18, 0x18, 0x00, //    ##      ##    
+	0x18, 0x18, 0x00, //    ##      ##    
+	0x7E, 0x7E, 0x00, //  ######  ######  
+	0x7E, 0x7E, 0x00, //  ######  ######  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+
+	// @2952 'I' (17 pixels wide)
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x1F, 0xF8, 0x00, //    ##########    
+	0x1F, 0xF8, 0x00, //    ##########    
+	0x01, 0x80, 0x00, //        ##        
+	0x01, 0x80, 0x00, //        ##        
+	0x01, 0x80, 0x00, //        ##        
+	0x01, 0x80, 0x00, //        ##        
+	0x01, 0x80, 0x00, //        ##        
+	0x01, 0x80, 0x00, //        ##        
+	0x01, 0x80, 0x00, //        ##        
+	0x01, 0x80, 0x00, //        ##        
+	0x01, 0x80, 0x00, //        ##        
+	0x01, 0x80, 0x00, //        ##        
+	0x1F, 0xF8, 0x00, //    ##########    
+	0x1F, 0xF8, 0x00, //    ##########    
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+
+	// @3024 'J' (17 pixels wide)
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x07, 0xFE, 0x00, //      ##########  
+	0x07, 0xFE, 0x00, //      ##########  
+	0x00, 0x30, 0x00, //           ##     
+	0x00, 0x30, 0x00, //           ##     
+	0x00, 0x30, 0x00, //           ##     
+	0x00, 0x30, 0x00, //           ##     
+	0x00, 0x30, 0x00, //           ##     
+	0x30, 0x30, 0x00, //   ##      ##     
+	0x30, 0x30, 0x00, //   ##      ##     
+	0x30, 0x30, 0x00, //   ##      ##     
+	0x30, 0x30, 0x00, //   ##      ##     
+	0x30, 0x60, 0x00, //   ##     ##      
+	0x3F, 0xE0, 0x00, //   #########      
+	0x0F, 0x80, 0x00, //     #####        
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+
+	// @3096 'K' (17 pixels wide)
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x7F, 0x3E, 0x00, //  #######  #####  
+	0x7F, 0x3E, 0x00, //  #######  #####  
+	0x18, 0x30, 0x00, //    ##     ##     
+	0x18, 0x60, 0x00, //    ##    ##      
+	0x18, 0xC0, 0x00, //    ##   ##       
+	0x19, 0x80, 0x00, //    ##  ##        
+	0x1B, 0x80, 0x00, //    ## ###        
+	0x1F, 0xC0, 0x00, //    #######       
+	0x1C, 0xE0, 0x00, //    ###  ###      
+	0x18, 0x70, 0x00, //    ##    ###     
+	0x18, 0x30, 0x00, //    ##     ##     
+	0x18, 0x38, 0x00, //    ##     ###    
+	0x7F, 0x1F, 0x00, //  #######   ##### 
+	0x7F, 0x1F, 0x00, //  #######   ##### 
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+
+	// @3168 'L' (17 pixels wide)
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x7F, 0x80, 0x00, //  ########        
+	0x7F, 0x80, 0x00, //  ########        
+	0x0C, 0x00, 0x00, //     ##           
+	0x0C, 0x00, 0x00, //     ##           
+	0x0C, 0x00, 0x00, //     ##           
+	0x0C, 0x00, 0x00, //     ##           
+	0x0C, 0x00, 0x00, //     ##           
+	0x0C, 0x00, 0x00, //     ##           
+	0x0C, 0x0C, 0x00, //     ##      ##   
+	0x0C, 0x0C, 0x00, //     ##      ##   
+	0x0C, 0x0C, 0x00, //     ##      ##   
+	0x0C, 0x0C, 0x00, //     ##      ##   
+	0x7F, 0xFC, 0x00, //  #############   
+	0x7F, 0xFC, 0x00, //  #############   
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+
+	// @3240 'M' (17 pixels wide)
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0xF0, 0x0F, 0x00, // ####        #### 
+	0xF8, 0x1F, 0x00, // #####      ##### 
+	0x38, 0x1C, 0x00, //   ###      ###   
+	0x3C, 0x3C, 0x00, //   ####    ####   
+	0x3C, 0x3C, 0x00, //   ####    ####   
+	0x36, 0x6C, 0x00, //   ## ##  ## ##   
+	0x36, 0x6C, 0x00, //   ## ##  ## ##   
+	0x33, 0xCC, 0x00, //   ##  ####  ##   
+	0x33, 0xCC, 0x00, //   ##  ####  ##   
+	0x31, 0x8C, 0x00, //   ##   ##   ##   
+	0x30, 0x0C, 0x00, //   ##        ##   
+	0x30, 0x0C, 0x00, //   ##        ##   
+	0xFE, 0x7F, 0x00, // #######  ####### 
+	0xFE, 0x7F, 0x00, // #######  ####### 
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+
+	// @3312 'N' (17 pixels wide)
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x78, 0xFE, 0x00, //  ####   #######  
+	0x78, 0xFE, 0x00, //  ####   #######  
+	0x1C, 0x18, 0x00, //    ###     ##    
+	0x1E, 0x18, 0x00, //    ####    ##    
+	0x1F, 0x18, 0x00, //    #####   ##    
+	0x1B, 0x18, 0x00, //    ## ##   ##    
+	0x1B, 0x98, 0x00, //    ## ###  ##    
+	0x19, 0xD8, 0x00, //    ##  ### ##    
+	0x18, 0xD8, 0x00, //    ##   ## ##    
+	0x18, 0xF8, 0x00, //    ##   #####    
+	0x18, 0x78, 0x00, //    ##    ####    
+	0x18, 0x38, 0x00, //    ##     ###    
+	0x7F, 0x18, 0x00, //  #######   ##    
+	0x7F, 0x18, 0x00, //  #######   ##    
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+
+	// @3384 'O' (17 pixels wide)
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x03, 0xC0, 0x00, //       ####       
+	0x0F, 0xF0, 0x00, //     ########     
+	0x1C, 0x38, 0x00, //    ###    ###    
+	0x18, 0x18, 0x00, //    ##      ##    
+	0x38, 0x1C, 0x00, //   ###      ###   
+	0x30, 0x0C, 0x00, //   ##        ##   
+	0x30, 0x0C, 0x00, //   ##        ##   
+	0x30, 0x0C, 0x00, //   ##        ##   
+	0x30, 0x0C, 0x00, //   ##        ##   
+	0x38, 0x1C, 0x00, //   ###      ###   
+	0x18, 0x18, 0x00, //    ##      ##    
+	0x1C, 0x38, 0x00, //    ###    ###    
+	0x0F, 0xF0, 0x00, //     ########     
+	0x03, 0xC0, 0x00, //       ####       
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+
+	// @3456 'P' (17 pixels wide)
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x3F, 0xF0, 0x00, //   ##########     
+	0x3F, 0xF8, 0x00, //   ###########    
+	0x0C, 0x1C, 0x00, //     ##     ###   
+	0x0C, 0x0C, 0x00, //     ##      ##   
+	0x0C, 0x0C, 0x00, //     ##      ##   
+	0x0C, 0x0C, 0x00, //     ##      ##   
+	0x0C, 0x18, 0x00, //     ##     ##    
+	0x0F, 0xF8, 0x00, //     #########    
+	0x0F, 0xE0, 0x00, //     #######      
+	0x0C, 0x00, 0x00, //     ##           
+	0x0C, 0x00, 0x00, //     ##           
+	0x0C, 0x00, 0x00, //     ##           
+	0x3F, 0xC0, 0x00, //   ########       
+	0x3F, 0xC0, 0x00, //   ########       
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+
+	// @3528 'Q' (17 pixels wide)
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x03, 0xC0, 0x00, //       ####       
+	0x0F, 0xF0, 0x00, //     ########     
+	0x1C, 0x38, 0x00, //    ###    ###    
+	0x18, 0x18, 0x00, //    ##      ##    
+	0x38, 0x1C, 0x00, //   ###      ###   
+	0x30, 0x0C, 0x00, //   ##        ##   
+	0x30, 0x0C, 0x00, //   ##        ##   
+	0x30, 0x0C, 0x00, //   ##        ##   
+	0x30, 0x0C, 0x00, //   ##        ##   
+	0x38, 0x1C, 0x00, //   ###      ###   
+	0x18, 0x18, 0x00, //    ##      ##    
+	0x1C, 0x38, 0x00, //    ###    ###    
+	0x0F, 0xF0, 0x00, //     ########     
+	0x07, 0xC0, 0x00, //      #####       
+	0x07, 0xCC, 0x00, //      #####  ##   
+	0x0F, 0xFC, 0x00, //     ##########   
+	0x0C, 0x38, 0x00, //     ##    ###    
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+
+	// @3600 'R' (17 pixels wide)
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x7F, 0xE0, 0x00, //  ##########      
+	0x7F, 0xF0, 0x00, //  ###########     
+	0x18, 0x38, 0x00, //    ##     ###    
+	0x18, 0x18, 0x00, //    ##      ##    
+	0x18, 0x18, 0x00, //    ##      ##    
+	0x18, 0x38, 0x00, //    ##     ###    
+	0x1F, 0xF0, 0x00, //    #########     
+	0x1F, 0xC0, 0x00, //    #######       
+	0x18, 0xE0, 0x00, //    ##   ###      
+	0x18, 0x70, 0x00, //    ##    ###     
+	0x18, 0x30, 0x00, //    ##     ##     
+	0x18, 0x38, 0x00, //    ##     ###    
+	0x7F, 0x1E, 0x00, //  #######   ####  
+	0x7F, 0x0E, 0x00, //  #######    ###  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+
+	// @3672 'S' (17 pixels wide)
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x07, 0xD8, 0x00, //      ##### ##    
+	0x0F, 0xF8, 0x00, //     #########    
+	0x1C, 0x38, 0x00, //    ###    ###    
+	0x18, 0x18, 0x00, //    ##      ##    
+	0x18, 0x18, 0x00, //    ##      ##    
+	0x1E, 0x00, 0x00, //    ####          
+	0x0F, 0xC0, 0x00, //     ######       
+	0x03, 0xF0, 0x00, //       ######     
+	0x00, 0x78, 0x00, //          ####    
+	0x18, 0x18, 0x00, //    ##      ##    
+	0x18, 0x18, 0x00, //    ##      ##    
+	0x1C, 0x38, 0x00, //    ###    ###    
+	0x1F, 0xF0, 0x00, //    #########     
+	0x1B, 0xE0, 0x00, //    ## #####      
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+
+	// @3744 'T' (17 pixels wide)
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x3F, 0xFC, 0x00, //   ############   
+	0x3F, 0xFC, 0x00, //   ############   
+	0x31, 0x8C, 0x00, //   ##   ##   ##   
+	0x31, 0x8C, 0x00, //   ##   ##   ##   
+	0x31, 0x8C, 0x00, //   ##   ##   ##   
+	0x31, 0x8C, 0x00, //   ##   ##   ##   
+	0x01, 0x80, 0x00, //        ##        
+	0x01, 0x80, 0x00, //        ##        
+	0x01, 0x80, 0x00, //        ##        
+	0x01, 0x80, 0x00, //        ##        
+	0x01, 0x80, 0x00, //        ##        
+	0x01, 0x80, 0x00, //        ##        
+	0x0F, 0xF0, 0x00, //     ########     
+	0x0F, 0xF0, 0x00, //     ########     
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+
+	// @3816 'U' (17 pixels wide)
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x7E, 0x7E, 0x00, //  ######  ######  
+	0x7E, 0x7E, 0x00, //  ######  ######  
+	0x18, 0x18, 0x00, //    ##      ##    
+	0x18, 0x18, 0x00, //    ##      ##    
+	0x18, 0x18, 0x00, //    ##      ##    
+	0x18, 0x18, 0x00, //    ##      ##    
+	0x18, 0x18, 0x00, //    ##      ##    
+	0x18, 0x18, 0x00, //    ##      ##    
+	0x18, 0x18, 0x00, //    ##      ##    
+	0x18, 0x18, 0x00, //    ##      ##    
+	0x18, 0x18, 0x00, //    ##      ##    
+	0x0C, 0x30, 0x00, //     ##    ##     
+	0x0F, 0xF0, 0x00, //     ########     
+	0x03, 0xC0, 0x00, //       ####       
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+
+	// @3888 'V' (17 pixels wide)
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x7F, 0x7F, 0x00, //  ####### ####### 
+	0x7F, 0x7F, 0x00, //  ####### ####### 
+	0x18, 0x0C, 0x00, //    ##       ##   
+	0x0C, 0x18, 0x00, //     ##     ##    
+	0x0C, 0x18, 0x00, //     ##     ##    
+	0x0C, 0x18, 0x00, //     ##     ##    
+	0x06, 0x30, 0x00, //      ##   ##     
+	0x06, 0x30, 0x00, //      ##   ##     
+	0x03, 0x60, 0x00, //       ## ##      
+	0x03, 0x60, 0x00, //       ## ##      
+	0x03, 0x60, 0x00, //       ## ##      
+	0x01, 0xC0, 0x00, //        ###       
+	0x01, 0xC0, 0x00, //        ###       
+	0x00, 0x80, 0x00, //         #        
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+
+	// @3960 'W' (17 pixels wide)
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0xFE, 0x3F, 0x80, // #######   #######
+	0xFE, 0x3F, 0x80, // #######   #######
+	0x30, 0x06, 0x00, //   ##         ##  
+	0x30, 0x06, 0x00, //   ##         ##  
+	0x30, 0x86, 0x00, //   ##    #    ##  
+	0x19, 0xCC, 0x00, //    ##  ###  ##   
+	0x19, 0xCC, 0x00, //    ##  ###  ##   
+	0x1B, 0x6C, 0x00, //    ## ## ## ##   
+	0x1B, 0x6C, 0x00, //    ## ## ## ##   
+	0x1E, 0x7C, 0x00, //    ####  #####   
+	0x0E, 0x38, 0x00, //     ###   ###    
+	0x0E, 0x38, 0x00, //     ###   ###    
+	0x0C, 0x18, 0x00, //     ##     ##    
+	0x0C, 0x18, 0x00, //     ##     ##    
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+
+	// @4032 'X' (17 pixels wide)
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x7E, 0x7E, 0x00, //  ######  ######  
+	0x7E, 0x7E, 0x00, //  ######  ######  
+	0x18, 0x18, 0x00, //    ##      ##    
+	0x0C, 0x30, 0x00, //     ##    ##     
+	0x06, 0x60, 0x00, //      ##  ##      
+	0x03, 0xC0, 0x00, //       ####       
+	0x01, 0x80, 0x00, //        ##        
+	0x01, 0x80, 0x00, //        ##        
+	0x03, 0xC0, 0x00, //       ####       
+	0x06, 0x60, 0x00, //      ##  ##      
+	0x0C, 0x30, 0x00, //     ##    ##     
+	0x18, 0x18, 0x00, //    ##      ##    
+	0x7E, 0x7E, 0x00, //  ######  ######  
+	0x7E, 0x7E, 0x00, //  ######  ######  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+
+	// @4104 'Y' (17 pixels wide)
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x7C, 0x7E, 0x00, //  #####   ######  
+	0x7C, 0x7E, 0x00, //  #####   ######  
+	0x18, 0x18, 0x00, //    ##      ##    
+	0x0C, 0x30, 0x00, //     ##    ##     
+	0x06, 0x60, 0x00, //      ##  ##      
+	0x06, 0x60, 0x00, //      ##  ##      
+	0x03, 0xC0, 0x00, //       ####       
+	0x01, 0x80, 0x00, //        ##        
+	0x01, 0x80, 0x00, //        ##        
+	0x01, 0x80, 0x00, //        ##        
+	0x01, 0x80, 0x00, //        ##        
+	0x01, 0x80, 0x00, //        ##        
+	0x0F, 0xF0, 0x00, //     ########     
+	0x0F, 0xF0, 0x00, //     ########     
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+
+	// @4176 'Z' (17 pixels wide)
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x1F, 0xF8, 0x00, //    ##########    
+	0x1F, 0xF8, 0x00, //    ##########    
+	0x18, 0x18, 0x00, //    ##      ##    
+	0x18, 0x30, 0x00, //    ##     ##     
+	0x18, 0x60, 0x00, //    ##    ##      
+	0x18, 0xC0, 0x00, //    ##   ##       
+	0x01, 0x80, 0x00, //        ##        
+	0x03, 0x00, 0x00, //       ##         
+	0x06, 0x18, 0x00, //      ##    ##    
+	0x0C, 0x18, 0x00, //     ##     ##    
+	0x18, 0x18, 0x00, //    ##      ##    
+	0x30, 0x18, 0x00, //   ##       ##    
+	0x3F, 0xF8, 0x00, //   ###########    
+	0x3F, 0xF8, 0x00, //   ###########    
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+
+	// @4248 '[' (17 pixels wide)
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x01, 0xF0, 0x00, //        #####     
+	0x01, 0xF0, 0x00, //        #####     
+	0x01, 0x80, 0x00, //        ##        
+	0x01, 0x80, 0x00, //        ##        
+	0x01, 0x80, 0x00, //        ##        
+	0x01, 0x80, 0x00, //        ##        
+	0x01, 0x80, 0x00, //        ##        
+	0x01, 0x80, 0x00, //        ##        
+	0x01, 0x80, 0x00, //        ##        
+	0x01, 0x80, 0x00, //        ##        
+	0x01, 0x80, 0x00, //        ##        
+	0x01, 0x80, 0x00, //        ##        
+	0x01, 0x80, 0x00, //        ##        
+	0x01, 0x80, 0x00, //        ##        
+	0x01, 0x80, 0x00, //        ##        
+	0x01, 0x80, 0x00, //        ##        
+	0x01, 0xF0, 0x00, //        #####     
+	0x01, 0xF0, 0x00, //        #####     
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+
+	// @4320 '\' (17 pixels wide)
+	0x18, 0x00, 0x00, //    ##            
+	0x18, 0x00, 0x00, //    ##            
+	0x1C, 0x00, 0x00, //    ###           
+	0x0C, 0x00, 0x00, //     ##           
+	0x0E, 0x00, 0x00, //     ###          
+	0x06, 0x00, 0x00, //      ##          
+	0x06, 0x00, 0x00, //      ##          
+	0x03, 0x00, 0x00, //       ##         
+	0x03, 0x00, 0x00, //       ##         
+	0x01, 0x80, 0x00, //        ##        
+	0x01, 0x80, 0x00, //        ##        
+	0x00, 0xC0, 0x00, //         ##       
+	0x00, 0xC0, 0x00, //         ##       
+	0x00, 0x60, 0x00, //          ##      
+	0x00, 0x60, 0x00, //          ##      
+	0x00, 0x70, 0x00, //          ###     
+	0x00, 0x30, 0x00, //           ##     
+	0x00, 0x38, 0x00, //           ###    
+	0x00, 0x18, 0x00, //            ##    
+	0x00, 0x18, 0x00, //            ##    
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+
+	// @4392 ']' (17 pixels wide)
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x0F, 0x80, 0x00, //     #####        
+	0x0F, 0x80, 0x00, //     #####        
+	0x01, 0x80, 0x00, //        ##        
+	0x01, 0x80, 0x00, //        ##        
+	0x01, 0x80, 0x00, //        ##        
+	0x01, 0x80, 0x00, //        ##        
+	0x01, 0x80, 0x00, //        ##        
+	0x01, 0x80, 0x00, //        ##        
+	0x01, 0x80, 0x00, //        ##        
+	0x01, 0x80, 0x00, //        ##        
+	0x01, 0x80, 0x00, //        ##        
+	0x01, 0x80, 0x00, //        ##        
+	0x01, 0x80, 0x00, //        ##        
+	0x01, 0x80, 0x00, //        ##        
+	0x01, 0x80, 0x00, //        ##        
+	0x01, 0x80, 0x00, //        ##        
+	0x0F, 0x80, 0x00, //     #####        
+	0x0F, 0x80, 0x00, //     #####        
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+
+	// @4464 '^' (17 pixels wide)
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x80, 0x00, //         #        
+	0x01, 0xC0, 0x00, //        ###       
+	0x03, 0xE0, 0x00, //       #####      
+	0x07, 0x70, 0x00, //      ### ###     
+	0x06, 0x30, 0x00, //      ##   ##     
+	0x0C, 0x18, 0x00, //     ##     ##    
+	0x18, 0x0C, 0x00, //    ##       ##   
+	0x10, 0x04, 0x00, //    #         #   
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+
+	// @4536 '_' (17 pixels wide)
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0xFF, 0xFF, 0x00, // ################ 
+	0xFF, 0xFF, 0x00, // ################ 
+
+	// @4608 '`' (17 pixels wide)
+	0x00, 0x00, 0x00, //                  
+	0x03, 0x00, 0x00, //       ##         
+	0x03, 0x80, 0x00, //       ###        
+	0x00, 0xE0, 0x00, //         ###      
+	0x00, 0x60, 0x00, //          ##      
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+
+	// @4680 'a' (17 pixels wide)
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x0F, 0xC0, 0x00, //     ######       
+	0x1F, 0xE0, 0x00, //    ########      
+	0x00, 0x30, 0x00, //           ##     
+	0x00, 0x30, 0x00, //           ##     
+	0x07, 0xF0, 0x00, //      #######     
+	0x1F, 0xF0, 0x00, //    #########     
+	0x38, 0x30, 0x00, //   ###     ##     
+	0x30, 0x30, 0x00, //   ##      ##     
+	0x30, 0x70, 0x00, //   ##     ###     
+	0x1F, 0xFC, 0x00, //    ###########   
+	0x0F, 0xBC, 0x00, //     ##### ####   
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+
+	// @4752 'b' (17 pixels wide)
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x78, 0x00, 0x00, //  ####            
+	0x78, 0x00, 0x00, //  ####            
+	0x18, 0x00, 0x00, //    ##            
+	0x18, 0x00, 0x00, //    ##            
+	0x1B, 0xE0, 0x00, //    ## #####      
+	0x1F, 0xF8, 0x00, //    ##########    
+	0x1C, 0x18, 0x00, //    ###     ##    
+	0x18, 0x0C, 0x00, //    ##       ##   
+	0x18, 0x0C, 0x00, //    ##       ##   
+	0x18, 0x0C, 0x00, //    ##       ##   
+	0x18, 0x0C, 0x00, //    ##       ##   
+	0x18, 0x0C, 0x00, //    ##       ##   
+	0x1C, 0x18, 0x00, //    ###     ##    
+	0x7F, 0xF8, 0x00, //  ############    
+	0x7B, 0xE0, 0x00, //  #### #####      
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+
+	// @4824 'c' (17 pixels wide)
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x03, 0xEC, 0x00, //       ##### ##   
+	0x0F, 0xFC, 0x00, //     ##########   
+	0x1C, 0x1C, 0x00, //    ###     ###   
+	0x38, 0x0C, 0x00, //   ###       ##   
+	0x30, 0x0C, 0x00, //   ##        ##   
+	0x30, 0x00, 0x00, //   ##             
+	0x30, 0x00, 0x00, //   ##             
+	0x38, 0x0C, 0x00, //   ###       ##   
+	0x1C, 0x1C, 0x00, //    ###     ###   
+	0x0F, 0xF8, 0x00, //     #########    
+	0x03, 0xF0, 0x00, //       ######     
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+
+	// @4896 'd' (17 pixels wide)
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x78, 0x00, //          ####    
+	0x00, 0x78, 0x00, //          ####    
+	0x00, 0x18, 0x00, //            ##    
+	0x00, 0x18, 0x00, //            ##    
+	0x07, 0xD8, 0x00, //      ##### ##    
+	0x1F, 0xF8, 0x00, //    ##########    
+	0x18, 0x38, 0x00, //    ##     ###    
+	0x30, 0x18, 0x00, //   ##       ##    
+	0x30, 0x18, 0x00, //   ##       ##    
+	0x30, 0x18, 0x00, //   ##       ##    
+	0x30, 0x18, 0x00, //   ##       ##    
+	0x30, 0x18, 0x00, //   ##       ##    
+	0x18, 0x38, 0x00, //    ##     ###    
+	0x1F, 0xFE, 0x00, //    ############  
+	0x07, 0xDE, 0x00, //      ##### ####  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+
+	// @4968 'e' (17 pixels wide)
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x07, 0xE0, 0x00, //      ######      
+	0x1F, 0xF8, 0x00, //    ##########    
+	0x18, 0x18, 0x00, //    ##      ##    
+	0x30, 0x0C, 0x00, //   ##        ##   
+	0x3F, 0xFC, 0x00, //   ############   
+	0x3F, 0xFC, 0x00, //   ############   
+	0x30, 0x00, 0x00, //   ##             
+	0x30, 0x00, 0x00, //   ##             
+	0x18, 0x0C, 0x00, //    ##       ##   
+	0x1F, 0xFC, 0x00, //    ###########   
+	0x07, 0xF0, 0x00, //      #######     
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+
+	// @5040 'f' (17 pixels wide)
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x01, 0xFC, 0x00, //        #######   
+	0x03, 0xFC, 0x00, //       ########   
+	0x06, 0x00, 0x00, //      ##          
+	0x06, 0x00, 0x00, //      ##          
+	0x3F, 0xF8, 0x00, //   ###########    
+	0x3F, 0xF8, 0x00, //   ###########    
+	0x06, 0x00, 0x00, //      ##          
+	0x06, 0x00, 0x00, //      ##          
+	0x06, 0x00, 0x00, //      ##          
+	0x06, 0x00, 0x00, //      ##          
+	0x06, 0x00, 0x00, //      ##          
+	0x06, 0x00, 0x00, //      ##          
+	0x06, 0x00, 0x00, //      ##          
+	0x3F, 0xF0, 0x00, //   ##########     
+	0x3F, 0xF0, 0x00, //   ##########     
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+
+	// @5112 'g' (17 pixels wide)
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x07, 0xDE, 0x00, //      ##### ####  
+	0x1F, 0xFE, 0x00, //    ############  
+	0x18, 0x38, 0x00, //    ##     ###    
+	0x30, 0x18, 0x00, //   ##       ##    
+	0x30, 0x18, 0x00, //   ##       ##    
+	0x30, 0x18, 0x00, //   ##       ##    
+	0x30, 0x18, 0x00, //   ##       ##    
+	0x30, 0x18, 0x00, //   ##       ##    
+	0x18, 0x38, 0x00, //    ##     ###    
+	0x1F, 0xF8, 0x00, //    ##########    
+	0x07, 0xD8, 0x00, //      ##### ##    
+	0x00, 0x18, 0x00, //            ##    
+	0x00, 0x18, 0x00, //            ##    
+	0x00, 0x38, 0x00, //           ###    
+	0x0F, 0xF0, 0x00, //     ########     
+	0x0F, 0xC0, 0x00, //     ######       
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+
+	// @5184 'h' (17 pixels wide)
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x78, 0x00, 0x00, //  ####            
+	0x78, 0x00, 0x00, //  ####            
+	0x18, 0x00, 0x00, //    ##            
+	0x18, 0x00, 0x00, //    ##            
+	0x1B, 0xE0, 0x00, //    ## #####      
+	0x1F, 0xF0, 0x00, //    #########     
+	0x1C, 0x38, 0x00, //    ###    ###    
+	0x18, 0x18, 0x00, //    ##      ##    
+	0x18, 0x18, 0x00, //    ##      ##    
+	0x18, 0x18, 0x00, //    ##      ##    
+	0x18, 0x18, 0x00, //    ##      ##    
+	0x18, 0x18, 0x00, //    ##      ##    
+	0x18, 0x18, 0x00, //    ##      ##    
+	0x7E, 0x7E, 0x00, //  ######  ######  
+	0x7E, 0x7E, 0x00, //  ######  ######  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+
+	// @5256 'i' (17 pixels wide)
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x01, 0x80, 0x00, //        ##        
+	0x01, 0x80, 0x00, //        ##        
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x1F, 0x80, 0x00, //    ######        
+	0x1F, 0x80, 0x00, //    ######        
+	0x01, 0x80, 0x00, //        ##        
+	0x01, 0x80, 0x00, //        ##        
+	0x01, 0x80, 0x00, //        ##        
+	0x01, 0x80, 0x00, //        ##        
+	0x01, 0x80, 0x00, //        ##        
+	0x01, 0x80, 0x00, //        ##        
+	0x01, 0x80, 0x00, //        ##        
+	0x3F, 0xFC, 0x00, //   ############   
+	0x3F, 0xFC, 0x00, //   ############   
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+
+	// @5328 'j' (17 pixels wide)
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0xC0, 0x00, //         ##       
+	0x00, 0xC0, 0x00, //         ##       
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x1F, 0xF0, 0x00, //    #########     
+	0x1F, 0xF0, 0x00, //    #########     
+	0x00, 0x30, 0x00, //           ##     
+	0x00, 0x30, 0x00, //           ##     
+	0x00, 0x30, 0x00, //           ##     
+	0x00, 0x30, 0x00, //           ##     
+	0x00, 0x30, 0x00, //           ##     
+	0x00, 0x30, 0x00, //           ##     
+	0x00, 0x30, 0x00, //           ##     
+	0x00, 0x30, 0x00, //           ##     
+	0x00, 0x30, 0x00, //           ##     
+	0x00, 0x30, 0x00, //           ##     
+	0x00, 0x30, 0x00, //           ##     
+	0x00, 0x70, 0x00, //          ###     
+	0x1F, 0xE0, 0x00, //    ########      
+	0x1F, 0x80, 0x00, //    ######        
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+
+	// @5400 'k' (17 pixels wide)
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x3C, 0x00, 0x00, //   ####           
+	0x3C, 0x00, 0x00, //   ####           
+	0x0C, 0x00, 0x00, //     ##           
+	0x0C, 0x00, 0x00, //     ##           
+	0x0C, 0xF8, 0x00, //     ##  #####    
+	0x0C, 0xF8, 0x00, //     ##  #####    
+	0x0C, 0xC0, 0x00, //     ##  ##       
+	0x0D, 0x80, 0x00, //     ## ##        
+	0x0F, 0x80, 0x00, //     #####        
+	0x0F, 0x00, 0x00, //     ####         
+	0x0F, 0x80, 0x00, //     #####        
+	0x0D, 0xC0, 0x00, //     ## ###       
+	0x0C, 0xE0, 0x00, //     ##  ###      
+	0x3C, 0x7C, 0x00, //   ####   #####   
+	0x3C, 0x7C, 0x00, //   ####   #####   
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+
+	// @5472 'l' (17 pixels wide)
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x1F, 0x80, 0x00, //    ######        
+	0x1F, 0x80, 0x00, //    ######        
+	0x01, 0x80, 0x00, //        ##        
+	0x01, 0x80, 0x00, //        ##        
+	0x01, 0x80, 0x00, //        ##        
+	0x01, 0x80, 0x00, //        ##        
+	0x01, 0x80, 0x00, //        ##        
+	0x01, 0x80, 0x00, //        ##        
+	0x01, 0x80, 0x00, //        ##        
+	0x01, 0x80, 0x00, //        ##        
+	0x01, 0x80, 0x00, //        ##        
+	0x01, 0x80, 0x00, //        ##        
+	0x01, 0x80, 0x00, //        ##        
+	0x3F, 0xFC, 0x00, //   ############   
+	0x3F, 0xFC, 0x00, //   ############   
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+
+	// @5544 'm' (17 pixels wide)
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0xF7, 0x78, 0x00, // #### ### ####    
+	0xFF, 0xFC, 0x00, // ##############   
+	0x39, 0xCC, 0x00, //   ###  ###  ##   
+	0x31, 0x8C, 0x00, //   ##   ##   ##   
+	0x31, 0x8C, 0x00, //   ##   ##   ##   
+	0x31, 0x8C, 0x00, //   ##   ##   ##   
+	0x31, 0x8C, 0x00, //   ##   ##   ##   
+	0x31, 0x8C, 0x00, //   ##   ##   ##   
+	0x31, 0x8C, 0x00, //   ##   ##   ##   
+	0xFD, 0xEF, 0x00, // ###### #### #### 
+	0xFD, 0xEF, 0x00, // ###### #### #### 
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+
+	// @5616 'n' (17 pixels wide)
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x7B, 0xE0, 0x00, //  #### #####      
+	0x7F, 0xF0, 0x00, //  ###########     
+	0x1C, 0x38, 0x00, //    ###    ###    
+	0x18, 0x18, 0x00, //    ##      ##    
+	0x18, 0x18, 0x00, //    ##      ##    
+	0x18, 0x18, 0x00, //    ##      ##    
+	0x18, 0x18, 0x00, //    ##      ##    
+	0x18, 0x18, 0x00, //    ##      ##    
+	0x18, 0x18, 0x00, //    ##      ##    
+	0x7E, 0x7E, 0x00, //  ######  ######  
+	0x7E, 0x7E, 0x00, //  ######  ######  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+
+	// @5688 'o' (17 pixels wide)
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x03, 0xC0, 0x00, //       ####       
+	0x0F, 0xF0, 0x00, //     ########     
+	0x1C, 0x38, 0x00, //    ###    ###    
+	0x38, 0x1C, 0x00, //   ###      ###   
+	0x30, 0x0C, 0x00, //   ##        ##   
+	0x30, 0x0C, 0x00, //   ##        ##   
+	0x30, 0x0C, 0x00, //   ##        ##   
+	0x38, 0x1C, 0x00, //   ###      ###   
+	0x1C, 0x38, 0x00, //    ###    ###    
+	0x0F, 0xF0, 0x00, //     ########     
+	0x03, 0xC0, 0x00, //       ####       
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+
+	// @5760 'p' (17 pixels wide)
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x7B, 0xE0, 0x00, //  #### #####      
+	0x7F, 0xF8, 0x00, //  ############    
+	0x1C, 0x18, 0x00, //    ###     ##    
+	0x18, 0x0C, 0x00, //    ##       ##   
+	0x18, 0x0C, 0x00, //    ##       ##   
+	0x18, 0x0C, 0x00, //    ##       ##   
+	0x18, 0x0C, 0x00, //    ##       ##   
+	0x18, 0x0C, 0x00, //    ##       ##   
+	0x1C, 0x18, 0x00, //    ###     ##    
+	0x1F, 0xF8, 0x00, //    ##########    
+	0x1B, 0xE0, 0x00, //    ## #####      
+	0x18, 0x00, 0x00, //    ##            
+	0x18, 0x00, 0x00, //    ##            
+	0x18, 0x00, 0x00, //    ##            
+	0x7F, 0x00, 0x00, //  #######         
+	0x7F, 0x00, 0x00, //  #######         
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+
+	// @5832 'q' (17 pixels wide)
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x07, 0xDE, 0x00, //      ##### ####  
+	0x1F, 0xFE, 0x00, //    ############  
+	0x18, 0x38, 0x00, //    ##     ###    
+	0x30, 0x18, 0x00, //   ##       ##    
+	0x30, 0x18, 0x00, //   ##       ##    
+	0x30, 0x18, 0x00, //   ##       ##    
+	0x30, 0x18, 0x00, //   ##       ##    
+	0x30, 0x18, 0x00, //   ##       ##    
+	0x18, 0x38, 0x00, //    ##     ###    
+	0x1F, 0xF8, 0x00, //    ##########    
+	0x07, 0xD8, 0x00, //      ##### ##    
+	0x00, 0x18, 0x00, //            ##    
+	0x00, 0x18, 0x00, //            ##    
+	0x00, 0x18, 0x00, //            ##    
+	0x00, 0xFE, 0x00, //         #######  
+	0x00, 0xFE, 0x00, //         #######  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+
+	// @5904 'r' (17 pixels wide)
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x3E, 0x78, 0x00, //   #####  ####    
+	0x3E, 0xFC, 0x00, //   ##### ######   
+	0x07, 0xCC, 0x00, //      #####  ##   
+	0x07, 0x00, 0x00, //      ###         
+	0x06, 0x00, 0x00, //      ##          
+	0x06, 0x00, 0x00, //      ##          
+	0x06, 0x00, 0x00, //      ##          
+	0x06, 0x00, 0x00, //      ##          
+	0x06, 0x00, 0x00, //      ##          
+	0x3F, 0xF0, 0x00, //   ##########     
+	0x3F, 0xF0, 0x00, //   ##########     
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+
+	// @5976 's' (17 pixels wide)
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x07, 0xF8, 0x00, //      ########    
+	0x0F, 0xF8, 0x00, //     #########    
+	0x18, 0x18, 0x00, //    ##      ##    
+	0x18, 0x18, 0x00, //    ##      ##    
+	0x1F, 0x80, 0x00, //    ######        
+	0x0F, 0xF0, 0x00, //     ########     
+	0x00, 0xF8, 0x00, //         #####    
+	0x18, 0x18, 0x00, //    ##      ##    
+	0x18, 0x38, 0x00, //    ##     ###    
+	0x1F, 0xF0, 0x00, //    #########     
+	0x1F, 0xE0, 0x00, //    ########      
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+
+	// @6048 't' (17 pixels wide)
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x0C, 0x00, 0x00, //     ##           
+	0x0C, 0x00, 0x00, //     ##           
+	0x0C, 0x00, 0x00, //     ##           
+	0x0C, 0x00, 0x00, //     ##           
+	0x3F, 0xF0, 0x00, //   ##########     
+	0x3F, 0xF0, 0x00, //   ##########     
+	0x0C, 0x00, 0x00, //     ##           
+	0x0C, 0x00, 0x00, //     ##           
+	0x0C, 0x00, 0x00, //     ##           
+	0x0C, 0x00, 0x00, //     ##           
+	0x0C, 0x00, 0x00, //     ##           
+	0x0C, 0x00, 0x00, //     ##           
+	0x0C, 0x1C, 0x00, //     ##     ###   
+	0x07, 0xFC, 0x00, //      #########   
+	0x03, 0xF0, 0x00, //       ######     
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+
+	// @6120 'u' (17 pixels wide)
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x78, 0x78, 0x00, //  ####    ####    
+	0x78, 0x78, 0x00, //  ####    ####    
+	0x18, 0x18, 0x00, //    ##      ##    
+	0x18, 0x18, 0x00, //    ##      ##    
+	0x18, 0x18, 0x00, //    ##      ##    
+	0x18, 0x18, 0x00, //    ##      ##    
+	0x18, 0x18, 0x00, //    ##      ##    
+	0x18, 0x18, 0x00, //    ##      ##    
+	0x18, 0x38, 0x00, //    ##     ###    
+	0x0F, 0xFE, 0x00, //     ###########  
+	0x07, 0xDE, 0x00, //      ##### ####  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+
+	// @6192 'v' (17 pixels wide)
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x7C, 0x3E, 0x00, //  #####    #####  
+	0x7C, 0x3E, 0x00, //  #####    #####  
+	0x18, 0x18, 0x00, //    ##      ##    
+	0x18, 0x18, 0x00, //    ##      ##    
+	0x0C, 0x30, 0x00, //     ##    ##     
+	0x0C, 0x30, 0x00, //     ##    ##     
+	0x06, 0x60, 0x00, //      ##  ##      
+	0x06, 0x60, 0x00, //      ##  ##      
+	0x07, 0xE0, 0x00, //      ######      
+	0x03, 0xC0, 0x00, //       ####       
+	0x03, 0xC0, 0x00, //       ####       
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+
+	// @6264 'w' (17 pixels wide)
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x78, 0x3C, 0x00, //  ####     ####   
+	0x78, 0x3C, 0x00, //  ####     ####   
+	0x31, 0x18, 0x00, //   ##   #   ##    
+	0x33, 0x98, 0x00, //   ##  ###  ##    
+	0x33, 0x98, 0x00, //   ##  ###  ##    
+	0x1A, 0xB0, 0x00, //    ## # # ##     
+	0x1E, 0xF0, 0x00, //    #### ####     
+	0x1E, 0xF0, 0x00, //    #### ####     
+	0x1C, 0x60, 0x00, //    ###   ##      
+	0x0C, 0x60, 0x00, //     ##   ##      
+	0x0C, 0x60, 0x00, //     ##   ##      
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+
+	// @6336 'x' (17 pixels wide)
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x3E, 0x7C, 0x00, //   #####  #####   
+	0x3E, 0x7C, 0x00, //   #####  #####   
+	0x0C, 0x30, 0x00, //     ##    ##     
+	0x06, 0x60, 0x00, //      ##  ##      
+	0x03, 0xC0, 0x00, //       ####       
+	0x01, 0x80, 0x00, //        ##        
+	0x03, 0xC0, 0x00, //       ####       
+	0x06, 0x60, 0x00, //      ##  ##      
+	0x0C, 0x30, 0x00, //     ##    ##     
+	0x3E, 0x7C, 0x00, //   #####  #####   
+	0x3E, 0x7C, 0x00, //   #####  #####   
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+
+	// @6408 'y' (17 pixels wide)
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x7E, 0x1F, 0x00, //  ######    ##### 
+	0x7E, 0x1F, 0x00, //  ######    ##### 
+	0x18, 0x0C, 0x00, //    ##       ##   
+	0x0C, 0x18, 0x00, //     ##     ##    
+	0x0C, 0x18, 0x00, //     ##     ##    
+	0x06, 0x30, 0x00, //      ##   ##     
+	0x06, 0x30, 0x00, //      ##   ##     
+	0x03, 0x60, 0x00, //       ## ##      
+	0x03, 0xE0, 0x00, //       #####      
+	0x01, 0xC0, 0x00, //        ###       
+	0x00, 0xC0, 0x00, //         ##       
+	0x01, 0x80, 0x00, //        ##        
+	0x01, 0x80, 0x00, //        ##        
+	0x03, 0x00, 0x00, //       ##         
+	0x3F, 0xC0, 0x00, //   ########       
+	0x3F, 0xC0, 0x00, //   ########       
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+
+	// @6480 'z' (17 pixels wide)
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x1F, 0xF8, 0x00, //    ##########    
+	0x1F, 0xF8, 0x00, //    ##########    
+	0x18, 0x30, 0x00, //    ##     ##     
+	0x18, 0x60, 0x00, //    ##    ##      
+	0x00, 0xC0, 0x00, //         ##       
+	0x01, 0x80, 0x00, //        ##        
+	0x03, 0x00, 0x00, //       ##         
+	0x06, 0x18, 0x00, //      ##    ##    
+	0x0C, 0x18, 0x00, //     ##     ##    
+	0x1F, 0xF8, 0x00, //    ##########    
+	0x1F, 0xF8, 0x00, //    ##########    
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+
+	// @6552 '{' (17 pixels wide)
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0xE0, 0x00, //         ###      
+	0x01, 0xE0, 0x00, //        ####      
+	0x01, 0x80, 0x00, //        ##        
+	0x01, 0x80, 0x00, //        ##        
+	0x01, 0x80, 0x00, //        ##        
+	0x01, 0x80, 0x00, //        ##        
+	0x01, 0x80, 0x00, //        ##        
+	0x01, 0x80, 0x00, //        ##        
+	0x03, 0x80, 0x00, //       ###        
+	0x07, 0x00, 0x00, //      ###         
+	0x03, 0x80, 0x00, //       ###        
+	0x01, 0x80, 0x00, //        ##        
+	0x01, 0x80, 0x00, //        ##        
+	0x01, 0x80, 0x00, //        ##        
+	0x01, 0x80, 0x00, //        ##        
+	0x01, 0x80, 0x00, //        ##        
+	0x01, 0xE0, 0x00, //        ####      
+	0x00, 0xE0, 0x00, //         ###      
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+
+	// @6624 '|' (17 pixels wide)
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x01, 0x80, 0x00, //        ##        
+	0x01, 0x80, 0x00, //        ##        
+	0x01, 0x80, 0x00, //        ##        
+	0x01, 0x80, 0x00, //        ##        
+	0x01, 0x80, 0x00, //        ##        
+	0x01, 0x80, 0x00, //        ##        
+	0x01, 0x80, 0x00, //        ##        
+	0x01, 0x80, 0x00, //        ##        
+	0x01, 0x80, 0x00, //        ##        
+	0x01, 0x80, 0x00, //        ##        
+	0x01, 0x80, 0x00, //        ##        
+	0x01, 0x80, 0x00, //        ##        
+	0x01, 0x80, 0x00, //        ##        
+	0x01, 0x80, 0x00, //        ##        
+	0x01, 0x80, 0x00, //        ##        
+	0x01, 0x80, 0x00, //        ##        
+	0x01, 0x80, 0x00, //        ##        
+	0x01, 0x80, 0x00, //        ##        
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+
+	// @6696 '}' (17 pixels wide)
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x07, 0x00, 0x00, //      ###         
+	0x07, 0x80, 0x00, //      ####        
+	0x01, 0x80, 0x00, //        ##        
+	0x01, 0x80, 0x00, //        ##        
+	0x01, 0x80, 0x00, //        ##        
+	0x01, 0x80, 0x00, //        ##        
+	0x01, 0x80, 0x00, //        ##        
+	0x01, 0x80, 0x00, //        ##        
+	0x01, 0xC0, 0x00, //        ###       
+	0x00, 0xE0, 0x00, //         ###      
+	0x01, 0xC0, 0x00, //        ###       
+	0x01, 0x80, 0x00, //        ##        
+	0x01, 0x80, 0x00, //        ##        
+	0x01, 0x80, 0x00, //        ##        
+	0x01, 0x80, 0x00, //        ##        
+	0x01, 0x80, 0x00, //        ##        
+	0x07, 0x80, 0x00, //      ####        
+	0x07, 0x00, 0x00, //      ###         
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+
+	// @6768 '~' (17 pixels wide)
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x0E, 0x00, 0x00, //     ###          
+	0x1F, 0x18, 0x00, //    #####   ##    
+	0x3B, 0xB8, 0x00, //   ### ### ###    
+	0x31, 0xF0, 0x00, //   ##   #####     
+	0x00, 0xE0, 0x00, //         ###      
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+	0x00, 0x00, 0x00, //                  
+};
+
+sFONT Font24 = {
+  Font24_Table,
+  17, /* Width */
+  24, /* Height */
+};
+
+/**
+  * @}
+  */ 
+
+
+/** @defgroup FONTS_Private_Function_Prototypes
+  * @{
+  */ 
+/**
+  * @}
+  */ 
+
+
+/** @defgroup FONTS_Private_Functions
+  * @{
+  */
+    
+/**
+  * @}
+  */
+  
+/**
+  * @}
+  */ 
+
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */  
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/stmcube/Utilities/Fonts/font8.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/stmcube/Utilities/Fonts/font8.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/stmcube/Utilities/Fonts/font8.c	(revision 457)
@@ -0,0 +1,1084 @@
+/**
+  ******************************************************************************
+  * @file    Font8.c
+  * @author  MCD Application Team
+  * @version V1.0.0
+  * @date    18-February-2014
+  * @brief   This file provides text Font8 for STM32xx-EVAL's LCD driver. 
+  ******************************************************************************
+  * @attention
+  *
+  * <h2><center>&copy; COPYRIGHT(c) 2014 STMicroelectronics</center></h2>
+  *
+  * 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 STMicroelectronics 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.
+  *
+  ******************************************************************************
+  */
+
+/* Includes ------------------------------------------------------------------*/
+#include "fonts.h"
+
+/** @addtogroup Utilities
+  * @{
+  */
+  
+/** @addtogroup STM32_EVAL
+  * @{
+  */ 
+
+/** @addtogroup Common
+  * @{
+  */
+
+/** @addtogroup FONTS
+  * @brief      This file provides text Font8 for STM32xx-EVAL's LCD driver. 
+  * @{
+  */  
+
+/** @defgroup FONTS_Private_Types
+  * @{
+  */ 
+/**
+  * @}
+  */ 
+
+
+/** @defgroup FONTS_Private_Defines
+  * @{
+  */
+/**
+  * @}
+  */ 
+
+
+/** @defgroup FONTS_Private_Macros
+  * @{
+  */
+/**
+  * @}
+  */ 
+  
+
+/** @defgroup FONTS_Private_Variables
+  * @{
+  */
+// 
+//  Font data for Courier New 12pt
+// 
+
+const uint8_t Font8_Table[] = 
+{
+	// @0 ' ' (5 pixels wide)
+	0x00, //      
+	0x00, //      
+	0x00, //      
+	0x00, //      
+	0x00, //      
+	0x00, //      
+	0x00, //      
+	0x00, //      
+
+	// @8 '!' (5 pixels wide)
+	0x20, //   #  
+	0x20, //   #  
+	0x20, //   #  
+	0x20, //   #  
+	0x00, //      
+	0x20, //   #  
+	0x00, //      
+	0x00, //      
+
+	// @16 '"' (5 pixels wide)
+	0x50, //  # # 
+	0x50, //  # # 
+	0x00, //      
+	0x00, //      
+	0x00, //      
+	0x00, //      
+	0x00, //      
+	0x00, //      
+
+	// @24 '#' (5 pixels wide)
+	0x28, //   # #
+	0x50, //  # # 
+	0xF8, // #####
+	0x50, //  # # 
+	0xF8, // #####
+	0x50, //  # # 
+	0xA0, // # #  
+	0x00, //      
+
+	// @32 '$' (5 pixels wide)
+	0x20, //   #  
+	0x30, //   ## 
+	0x60, //  ##  
+	0x30, //   ## 
+	0x10, //    # 
+	0x60, //  ##  
+	0x20, //   #  
+	0x00, //      
+
+	// @40 '%' (5 pixels wide)
+	0x20, //   #  
+	0x20, //   #  
+	0x18, //    ##
+	0x60, //  ##  
+	0x10, //    # 
+	0x10, //    # 
+	0x00, //      
+	0x00, //      
+
+	// @48 '&' (5 pixels wide)
+	0x00, //      
+	0x38, //   ###
+	0x20, //   #  
+	0x60, //  ##  
+	0x50, //  # # 
+	0x78, //  ####
+	0x00, //      
+	0x00, //      
+
+	// @56 ''' (5 pixels wide)
+	0x20, //   #  
+	0x20, //   #  
+	0x20, //   #  
+	0x00, //      
+	0x00, //      
+	0x00, //      
+	0x00, //      
+	0x00, //      
+
+	// @64 '(' (5 pixels wide)
+	0x10, //    # 
+	0x20, //   #  
+	0x20, //   #  
+	0x20, //   #  
+	0x20, //   #  
+	0x20, //   #  
+	0x10, //    # 
+	0x00, //      
+
+	// @72 ')' (5 pixels wide)
+	0x40, //  #   
+	0x20, //   #  
+	0x20, //   #  
+	0x20, //   #  
+	0x20, //   #  
+	0x20, //   #  
+	0x40, //  #   
+	0x00, //      
+
+	// @80 '*' (5 pixels wide)
+	0x20, //   #  
+	0x70, //  ### 
+	0x20, //   #  
+	0x50, //  # # 
+	0x00, //      
+	0x00, //      
+	0x00, //      
+	0x00, //      
+
+	// @88 '+' (5 pixels wide)
+	0x00, //      
+	0x20, //   #  
+	0x20, //   #  
+	0xF8, // #####
+	0x20, //   #  
+	0x20, //   #  
+	0x00, //      
+	0x00, //      
+
+	// @96 ',' (5 pixels wide)
+	0x00, //      
+	0x00, //      
+	0x00, //      
+	0x00, //      
+	0x10, //    # 
+	0x20, //   #  
+	0x20, //   #  
+	0x00, //      
+
+	// @104 '-' (5 pixels wide)
+	0x00, //      
+	0x00, //      
+	0x00, //      
+	0x70, //  ### 
+	0x00, //      
+	0x00, //      
+	0x00, //      
+	0x00, //      
+
+	// @112 '.' (5 pixels wide)
+	0x00, //      
+	0x00, //      
+	0x00, //      
+	0x00, //      
+	0x00, //      
+	0x20, //   #  
+	0x00, //      
+	0x00, //      
+
+	// @120 '/' (5 pixels wide)
+	0x10, //    # 
+	0x20, //   #  
+	0x20, //   #  
+	0x20, //   #  
+	0x40, //  #   
+	0x40, //  #   
+	0x80, // #    
+	0x00, //      
+
+	// @128 '0' (5 pixels wide)
+	0x20, //   #  
+	0x50, //  # # 
+	0x50, //  # # 
+	0x50, //  # # 
+	0x50, //  # # 
+	0x20, //   #  
+	0x00, //      
+	0x00, //      
+
+	// @136 '1' (5 pixels wide)
+	0x60, //  ##  
+	0x20, //   #  
+	0x20, //   #  
+	0x20, //   #  
+	0x20, //   #  
+	0xF8, // #####
+	0x00, //      
+	0x00, //      
+
+	// @144 '2' (5 pixels wide)
+	0x20, //   #  
+	0x50, //  # # 
+	0x20, //   #  
+	0x20, //   #  
+	0x40, //  #   
+	0x70, //  ### 
+	0x00, //      
+	0x00, //      
+
+	// @152 '3' (5 pixels wide)
+	0x20, //   #  
+	0x50, //  # # 
+	0x10, //    # 
+	0x20, //   #  
+	0x10, //    # 
+	0x60, //  ##  
+	0x00, //      
+	0x00, //      
+
+	// @160 '4' (5 pixels wide)
+	0x10, //    # 
+	0x30, //   ## 
+	0x50, //  # # 
+	0x78, //  ####
+	0x10, //    # 
+	0x38, //   ###
+	0x00, //      
+	0x00, //      
+
+	// @168 '5' (5 pixels wide)
+	0x70, //  ### 
+	0x40, //  #   
+	0x60, //  ##  
+	0x10, //    # 
+	0x50, //  # # 
+	0x20, //   #  
+	0x00, //      
+	0x00, //      
+
+	// @176 '6' (5 pixels wide)
+	0x30, //   ## 
+	0x40, //  #   
+	0x60, //  ##  
+	0x50, //  # # 
+	0x50, //  # # 
+	0x60, //  ##  
+	0x00, //      
+	0x00, //      
+
+	// @184 '7' (5 pixels wide)
+	0x70, //  ### 
+	0x50, //  # # 
+	0x10, //    # 
+	0x20, //   #  
+	0x20, //   #  
+	0x20, //   #  
+	0x00, //      
+	0x00, //      
+
+	// @192 '8' (5 pixels wide)
+	0x20, //   #  
+	0x50, //  # # 
+	0x20, //   #  
+	0x50, //  # # 
+	0x50, //  # # 
+	0x20, //   #  
+	0x00, //      
+	0x00, //      
+
+	// @200 '9' (5 pixels wide)
+	0x30, //   ## 
+	0x50, //  # # 
+	0x50, //  # # 
+	0x30, //   ## 
+	0x10, //    # 
+	0x60, //  ##  
+	0x00, //      
+	0x00, //      
+
+	// @208 ':' (5 pixels wide)
+	0x00, //      
+	0x00, //      
+	0x20, //   #  
+	0x00, //      
+	0x00, //      
+	0x20, //   #  
+	0x00, //      
+	0x00, //      
+
+	// @216 ';' (5 pixels wide)
+	0x00, //      
+	0x00, //      
+	0x10, //    # 
+	0x00, //      
+	0x10, //    # 
+	0x20, //   #  
+	0x00, //      
+	0x00, //      
+
+	// @224 '<' (5 pixels wide)
+	0x00, //      
+	0x10, //    # 
+	0x20, //   #  
+	0xC0, // ##   
+	0x20, //   #  
+	0x10, //    # 
+	0x00, //      
+	0x00, //      
+
+	// @232 '=' (5 pixels wide)
+	0x00, //      
+	0x70, //  ### 
+	0x00, //      
+	0x70, //  ### 
+	0x00, //      
+	0x00, //      
+	0x00, //      
+	0x00, //      
+
+	// @240 '>' (5 pixels wide)
+	0x00, //      
+	0x40, //  #   
+	0x20, //   #  
+	0x18, //    ##
+	0x20, //   #  
+	0x40, //  #   
+	0x00, //      
+	0x00, //      
+
+	// @248 '?' (5 pixels wide)
+	0x20, //   #  
+	0x50, //  # # 
+	0x10, //    # 
+	0x20, //   #  
+	0x00, //      
+	0x20, //   #  
+	0x00, //      
+	0x00, //      
+
+	// @256 '@' (5 pixels wide)
+	0x30, //   ## 
+	0x48, //  #  #
+	0x48, //  #  #
+	0x58, //  # ##
+	0x48, //  #  #
+	0x40, //  #   
+	0x38, //   ###
+	0x00, //      
+
+	// @264 'A' (5 pixels wide)
+	0x60, //  ##  
+	0x20, //   #  
+	0x50, //  # # 
+	0x70, //  ### 
+	0x88, // #   #
+	0xD8, // ## ##
+	0x00, //      
+	0x00, //      
+
+	// @272 'B' (5 pixels wide)
+	0xF0, // #### 
+	0x48, //  #  #
+	0x70, //  ### 
+	0x48, //  #  #
+	0x48, //  #  #
+	0xF0, // #### 
+	0x00, //      
+	0x00, //      
+
+	// @280 'C' (5 pixels wide)
+	0x70, //  ### 
+	0x50, //  # # 
+	0x40, //  #   
+	0x40, //  #   
+	0x40, //  #   
+	0x30, //   ## 
+	0x00, //      
+	0x00, //      
+
+	// @288 'D' (5 pixels wide)
+	0xF0, // #### 
+	0x48, //  #  #
+	0x48, //  #  #
+	0x48, //  #  #
+	0x48, //  #  #
+	0xF0, // #### 
+	0x00, //      
+	0x00, //      
+
+	// @296 'E' (5 pixels wide)
+	0xF8, // #####
+	0x48, //  #  #
+	0x60, //  ##  
+	0x40, //  #   
+	0x48, //  #  #
+	0xF8, // #####
+	0x00, //      
+	0x00, //      
+
+	// @304 'F' (5 pixels wide)
+	0xF8, // #####
+	0x48, //  #  #
+	0x60, //  ##  
+	0x40, //  #   
+	0x40, //  #   
+	0xE0, // ###  
+	0x00, //      
+	0x00, //      
+
+	// @312 'G' (5 pixels wide)
+	0x70, //  ### 
+	0x40, //  #   
+	0x40, //  #   
+	0x58, //  # ##
+	0x50, //  # # 
+	0x30, //   ## 
+	0x00, //      
+	0x00, //      
+
+	// @320 'H' (5 pixels wide)
+	0xE8, // ### #
+	0x48, //  #  #
+	0x78, //  ####
+	0x48, //  #  #
+	0x48, //  #  #
+	0xE8, // ### #
+	0x00, //      
+	0x00, //      
+
+	// @328 'I' (5 pixels wide)
+	0x70, //  ### 
+	0x20, //   #  
+	0x20, //   #  
+	0x20, //   #  
+	0x20, //   #  
+	0x70, //  ### 
+	0x00, //      
+	0x00, //      
+
+	// @336 'J' (5 pixels wide)
+	0x38, //   ###
+	0x10, //    # 
+	0x10, //    # 
+	0x50, //  # # 
+	0x50, //  # # 
+	0x20, //   #  
+	0x00, //      
+	0x00, //      
+
+	// @344 'K' (5 pixels wide)
+	0xD8, // ## ##
+	0x50, //  # # 
+	0x60, //  ##  
+	0x70, //  ### 
+	0x50, //  # # 
+	0xD8, // ## ##
+	0x00, //      
+	0x00, //      
+
+	// @352 'L' (5 pixels wide)
+	0xE0, // ###  
+	0x40, //  #   
+	0x40, //  #   
+	0x40, //  #   
+	0x48, //  #  #
+	0xF8, // #####
+	0x00, //      
+	0x00, //      
+
+	// @360 'M' (5 pixels wide)
+	0xD8, // ## ##
+	0xD8, // ## ##
+	0xD8, // ## ##
+	0xA8, // # # #
+	0x88, // #   #
+	0xD8, // ## ##
+	0x00, //      
+	0x00, //      
+
+	// @368 'N' (5 pixels wide)
+	0xD8, // ## ##
+	0x68, //  ## #
+	0x68, //  ## #
+	0x58, //  # ##
+	0x58, //  # ##
+	0xE8, // ### #
+	0x00, //      
+	0x00, //      
+
+	// @376 'O' (5 pixels wide)
+	0x30, //   ## 
+	0x48, //  #  #
+	0x48, //  #  #
+	0x48, //  #  #
+	0x48, //  #  #
+	0x30, //   ## 
+	0x00, //      
+	0x00, //      
+
+	// @384 'P' (5 pixels wide)
+	0xF0, // #### 
+	0x48, //  #  #
+	0x48, //  #  #
+	0x70, //  ### 
+	0x40, //  #   
+	0xE0, // ###  
+	0x00, //      
+	0x00, //      
+
+	// @392 'Q' (5 pixels wide)
+	0x30, //   ## 
+	0x48, //  #  #
+	0x48, //  #  #
+	0x48, //  #  #
+	0x48, //  #  #
+	0x30, //   ## 
+	0x18, //    ##
+	0x00, //      
+
+	// @400 'R' (5 pixels wide)
+	0xF0, // #### 
+	0x48, //  #  #
+	0x48, //  #  #
+	0x70, //  ### 
+	0x48, //  #  #
+	0xE8, // ### #
+	0x00, //      
+	0x00, //      
+
+	// @408 'S' (5 pixels wide)
+	0x70, //  ### 
+	0x50, //  # # 
+	0x20, //   #  
+	0x10, //    # 
+	0x50, //  # # 
+	0x70, //  ### 
+	0x00, //      
+	0x00, //      
+
+	// @416 'T' (5 pixels wide)
+	0xF8, // #####
+	0xA8, // # # #
+	0x20, //   #  
+	0x20, //   #  
+	0x20, //   #  
+	0x70, //  ### 
+	0x00, //      
+	0x00, //      
+
+	// @424 'U' (5 pixels wide)
+	0xD8, // ## ##
+	0x48, //  #  #
+	0x48, //  #  #
+	0x48, //  #  #
+	0x48, //  #  #
+	0x30, //   ## 
+	0x00, //      
+	0x00, //      
+
+	// @432 'V' (5 pixels wide)
+	0xD8, // ## ##
+	0x88, // #   #
+	0x48, //  #  #
+	0x50, //  # # 
+	0x50, //  # # 
+	0x30, //   ## 
+	0x00, //      
+	0x00, //      
+
+	// @440 'W' (5 pixels wide)
+	0xD8, // ## ##
+	0x88, // #   #
+	0xA8, // # # #
+	0xA8, // # # #
+	0xA8, // # # #
+	0x50, //  # # 
+	0x00, //      
+	0x00, //      
+
+	// @448 'X' (5 pixels wide)
+	0xD8, // ## ##
+	0x50, //  # # 
+	0x20, //   #  
+	0x20, //   #  
+	0x50, //  # # 
+	0xD8, // ## ##
+	0x00, //      
+	0x00, //      
+
+	// @456 'Y' (5 pixels wide)
+	0xD8, // ## ##
+	0x88, // #   #
+	0x50, //  # # 
+	0x20, //   #  
+	0x20, //   #  
+	0x70, //  ### 
+	0x00, //      
+	0x00, //      
+
+	// @464 'Z' (5 pixels wide)
+	0x78, //  ####
+	0x48, //  #  #
+	0x10, //    # 
+	0x20, //   #  
+	0x48, //  #  #
+	0x78, //  ####
+	0x00, //      
+	0x00, //      
+
+	// @472 '[' (5 pixels wide)
+	0x30, //   ## 
+	0x20, //   #  
+	0x20, //   #  
+	0x20, //   #  
+	0x20, //   #  
+	0x20, //   #  
+	0x30, //   ## 
+	0x00, //      
+
+	// @480 '\' (5 pixels wide)
+	0x80, // #    
+	0x40, //  #   
+	0x40, //  #   
+	0x20, //   #  
+	0x20, //   #  
+	0x20, //   #  
+	0x10, //    # 
+	0x00, //      
+
+	// @488 ']' (5 pixels wide)
+	0x60, //  ##  
+	0x20, //   #  
+	0x20, //   #  
+	0x20, //   #  
+	0x20, //   #  
+	0x20, //   #  
+	0x60, //  ##  
+	0x00, //      
+
+	// @496 '^' (5 pixels wide)
+	0x20, //   #  
+	0x20, //   #  
+	0x50, //  # # 
+	0x00, //      
+	0x00, //      
+	0x00, //      
+	0x00, //      
+	0x00, //      
+
+	// @504 '_' (5 pixels wide)
+	0x00, //      
+	0x00, //      
+	0x00, //      
+	0x00, //      
+	0x00, //      
+	0x00, //      
+	0x00, //      
+	0xF8, // #####
+
+	// @512 '`' (5 pixels wide)
+	0x20, //   #  
+	0x10, //    # 
+	0x00, //      
+	0x00, //      
+	0x00, //      
+	0x00, //      
+	0x00, //      
+	0x00, //      
+
+	// @520 'a' (5 pixels wide)
+	0x00, //      
+	0x00, //      
+	0x30, //   ## 
+	0x10, //    # 
+	0x70, //  ### 
+	0x78, //  ####
+	0x00, //      
+	0x00, //      
+
+	// @528 'b' (5 pixels wide)
+	0xC0, // ##   
+	0x40, //  #   
+	0x70, //  ### 
+	0x48, //  #  #
+	0x48, //  #  #
+	0xF0, // #### 
+	0x00, //      
+	0x00, //      
+
+	// @536 'c' (5 pixels wide)
+	0x00, //      
+	0x00, //      
+	0x70, //  ### 
+	0x40, //  #   
+	0x40, //  #   
+	0x70, //  ### 
+	0x00, //      
+	0x00, //      
+
+	// @544 'd' (5 pixels wide)
+	0x18, //    ##
+	0x08, //     #
+	0x38, //   ###
+	0x48, //  #  #
+	0x48, //  #  #
+	0x38, //   ###
+	0x00, //      
+	0x00, //      
+
+	// @552 'e' (5 pixels wide)
+	0x00, //      
+	0x00, //      
+	0x70, //  ### 
+	0x70, //  ### 
+	0x40, //  #   
+	0x30, //   ## 
+	0x00, //      
+	0x00, //      
+
+	// @560 'f' (5 pixels wide)
+	0x10, //    # 
+	0x20, //   #  
+	0x70, //  ### 
+	0x20, //   #  
+	0x20, //   #  
+	0x70, //  ### 
+	0x00, //      
+	0x00, //      
+
+	// @568 'g' (5 pixels wide)
+	0x00, //      
+	0x00, //      
+	0x38, //   ###
+	0x48, //  #  #
+	0x48, //  #  #
+	0x38, //   ###
+	0x08, //     #
+	0x30, //   ## 
+
+	// @576 'h' (5 pixels wide)
+	0xC0, // ##   
+	0x40, //  #   
+	0x70, //  ### 
+	0x48, //  #  #
+	0x48, //  #  #
+	0xE8, // ### #
+	0x00, //      
+	0x00, //      
+
+	// @584 'i' (5 pixels wide)
+	0x20, //   #  
+	0x00, //      
+	0x60, //  ##  
+	0x20, //   #  
+	0x20, //   #  
+	0x70, //  ### 
+	0x00, //      
+	0x00, //      
+
+	// @592 'j' (5 pixels wide)
+	0x20, //   #  
+	0x00, //      
+	0x70, //  ### 
+	0x10, //    # 
+	0x10, //    # 
+	0x10, //    # 
+	0x10, //    # 
+	0x70, //  ### 
+
+	// @600 'k' (5 pixels wide)
+	0xC0, // ##   
+	0x40, //  #   
+	0x58, //  # ##
+	0x70, //  ### 
+	0x50, //  # # 
+	0xD8, // ## ##
+	0x00, //      
+	0x00, //      
+
+	// @608 'l' (5 pixels wide)
+	0x60, //  ##  
+	0x20, //   #  
+	0x20, //   #  
+	0x20, //   #  
+	0x20, //   #  
+	0x70, //  ### 
+	0x00, //      
+	0x00, //      
+
+	// @616 'm' (5 pixels wide)
+	0x00, //      
+	0x00, //      
+	0xD0, // ## # 
+	0xA8, // # # #
+	0xA8, // # # #
+	0xA8, // # # #
+	0x00, //      
+	0x00, //      
+
+	// @624 'n' (5 pixels wide)
+	0x00, //      
+	0x00, //      
+	0xF0, // #### 
+	0x48, //  #  #
+	0x48, //  #  #
+	0xC8, // ##  #
+	0x00, //      
+	0x00, //      
+
+	// @632 'o' (5 pixels wide)
+	0x00, //      
+	0x00, //      
+	0x30, //   ## 
+	0x48, //  #  #
+	0x48, //  #  #
+	0x30, //   ## 
+	0x00, //      
+	0x00, //      
+
+	// @640 'p' (5 pixels wide)
+	0x00, //      
+	0x00, //      
+	0xF0, // #### 
+	0x48, //  #  #
+	0x48, //  #  #
+	0x70, //  ### 
+	0x40, //  #   
+	0xE0, // ###  
+
+	// @648 'q' (5 pixels wide)
+	0x00, //      
+	0x00, //      
+	0x38, //   ###
+	0x48, //  #  #
+	0x48, //  #  #
+	0x38, //   ###
+	0x08, //     #
+	0x18, //    ##
+
+	// @656 'r' (5 pixels wide)
+	0x00, //      
+	0x00, //      
+	0x78, //  ####
+	0x20, //   #  
+	0x20, //   #  
+	0x70, //  ### 
+	0x00, //      
+	0x00, //      
+
+	// @664 's' (5 pixels wide)
+	0x00, //      
+	0x00, //      
+	0x30, //   ## 
+	0x20, //   #  
+	0x10, //    # 
+	0x60, //  ##  
+	0x00, //      
+	0x00, //      
+
+	// @672 't' (5 pixels wide)
+	0x00, //      
+	0x40, //  #   
+	0xF0, // #### 
+	0x40, //  #   
+	0x48, //  #  #
+	0x30, //   ## 
+	0x00, //      
+	0x00, //      
+
+	// @680 'u' (5 pixels wide)
+	0x00, //      
+	0x00, //      
+	0xD8, // ## ##
+	0x48, //  #  #
+	0x48, //  #  #
+	0x38, //   ###
+	0x00, //      
+	0x00, //      
+
+	// @688 'v' (5 pixels wide)
+	0x00, //      
+	0x00, //      
+	0xC8, // ##  #
+	0x48, //  #  #
+	0x30, //   ## 
+	0x30, //   ## 
+	0x00, //      
+	0x00, //      
+
+	// @696 'w' (5 pixels wide)
+	0x00, //      
+	0x00, //      
+	0xD8, // ## ##
+	0xA8, // # # #
+	0xA8, // # # #
+	0x50, //  # # 
+	0x00, //      
+	0x00, //      
+
+	// @704 'x' (5 pixels wide)
+	0x00, //      
+	0x00, //      
+	0x48, //  #  #
+	0x30, //   ## 
+	0x30, //   ## 
+	0x48, //  #  #
+	0x00, //      
+	0x00, //      
+
+	// @712 'y' (5 pixels wide)
+	0x00, //      
+	0x00, //      
+	0xD8, // ## ##
+	0x50, //  # # 
+	0x50, //  # # 
+	0x20, //   #  
+	0x20, //   #  
+	0x60, //  ##  
+
+	// @720 'z' (5 pixels wide)
+	0x00, //      
+	0x00, //      
+	0x78, //  ####
+	0x50, //  # # 
+	0x28, //   # #
+	0x78, //  ####
+	0x00, //      
+	0x00, //      
+
+	// @728 '{' (5 pixels wide)
+	0x10, //    # 
+	0x20, //   #  
+	0x20, //   #  
+	0x60, //  ##  
+	0x20, //   #  
+	0x20, //   #  
+	0x10, //    # 
+	0x00, //      
+
+	// @736 '|' (5 pixels wide)
+	0x20, //   #  
+	0x20, //   #  
+	0x20, //   #  
+	0x20, //   #  
+	0x20, //   #  
+	0x20, //   #  
+	0x20, //   #  
+	0x00, //      
+
+	// @744 '}' (5 pixels wide)
+	0x40, //  #   
+	0x20, //   #  
+	0x20, //   #  
+	0x30, //   ## 
+	0x20, //   #  
+	0x20, //   #  
+	0x40, //  #   
+	0x00, //      
+
+	// @752 '~' (5 pixels wide)
+	0x00, //      
+	0x00, //      
+	0x00, //      
+	0x28, //   # #
+	0x50, //  # # 
+	0x00, //      
+	0x00, //      
+	0x00, //      
+};
+
+sFONT Font8 = {
+  Font8_Table,
+  5, /* Width */
+  8, /* Height */
+};
+
+/**
+  * @}
+  */ 
+
+
+/** @defgroup FONTS_Private_Function_Prototypes
+  * @{
+  */ 
+/**
+  * @}
+  */ 
+
+
+/** @defgroup FONTS_Private_Functions
+  * @{
+  */
+    
+/**
+  * @}
+  */
+  
+/**
+  * @}
+  */ 
+
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */  
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/stmcube/Utilities/Fonts/fonts.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/stmcube/Utilities/Fonts/fonts.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/stmcube/Utilities/Fonts/fonts.h	(revision 457)
@@ -0,0 +1,134 @@
+/**
+  ******************************************************************************
+  * @file    fonts.h
+  * @author  MCD Application Team
+  * @version V1.0.0
+  * @date    18-February-2014
+  * @brief   Header for fonts.c file
+  ******************************************************************************
+  * @attention
+  *
+  * <h2><center>&copy; COPYRIGHT(c) 2014 STMicroelectronics</center></h2>
+  *
+  * 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 STMicroelectronics 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.
+  *
+  ******************************************************************************
+  */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __FONTS_H
+#define __FONTS_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include <stdint.h>
+
+/** @addtogroup Utilities
+  * @{
+  */
+  
+/** @addtogroup STM32_EVAL
+  * @{
+  */ 
+
+/** @addtogroup Common
+  * @{
+  */
+
+/** @addtogroup FONTS
+  * @{
+  */ 
+
+/** @defgroup FONTS_Exported_Types
+  * @{
+  */ 
+typedef struct _tFont
+{    
+  const uint8_t *table;
+  uint16_t Width;
+  uint16_t Height;
+  
+} sFONT;
+
+extern sFONT Font24;
+extern sFONT Font20;
+extern sFONT Font16;
+extern sFONT Font12;
+extern sFONT Font8;
+/**
+  * @}
+  */ 
+
+/** @defgroup FONTS_Exported_Constants
+  * @{
+  */ 
+#define LINE(x) ((x) * (((sFONT *)BSP_LCD_GetFont())->Height))
+
+/**
+  * @}
+  */ 
+
+/** @defgroup FONTS_Exported_Macros
+  * @{
+  */ 
+/**
+  * @}
+  */ 
+
+/** @defgroup FONTS_Exported_Functions
+  * @{
+  */ 
+/**
+  * @}
+  */
+
+#ifdef __cplusplus
+}
+#endif
+  
+#endif /* __FONTS_H */
+ 
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */ 
+
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */      
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/syssvc/banner.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/syssvc/banner.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/syssvc/banner.c	(revision 457)
@@ -0,0 +1,72 @@
+/*
+ *  TOPPERS/ASP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Advanced Standard Profile Kernel
+ * 
+ *  Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
+ *                              Toyohashi Univ. of Technology, JAPAN
+ *  Copyright (C) 2004-2014 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  $Id$
+ */
+
+/*
+ *		カーネル起動メッセージの出力
+ */
+
+#include <kernel.h>
+#include <t_syslog.h>
+#include "target_syssvc.h"
+#include "banner.h"
+
+#ifndef TARGET_COPYRIGHT
+#define TARGET_COPYRIGHT
+#endif /* TARGET_COPYRIGHT */
+
+static const char banner[] = "\n"
+"TOPPERS/ASP Kernel Release %d.%X.%d for " TARGET_NAME
+" (" __DATE__ ", " __TIME__ ")\n"
+"Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory\n"
+"                            Toyohashi Univ. of Technology, JAPAN\n"
+"Copyright (C) 2004-2014 by Embedded and Real-Time Systems Laboratory\n"
+"            Graduate School of Information Science, Nagoya Univ., JAPAN\n"
+TARGET_COPYRIGHT;
+
+void
+print_banner(intptr_t exinf)
+{
+	syslog_3(LOG_NOTICE, banner,
+				(TKERNEL_PRVER >> 12) & 0x0fU,
+				(TKERNEL_PRVER >> 4) & 0xffU,
+				TKERNEL_PRVER & 0x0fU);
+}
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/syssvc/banner.cfg
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/syssvc/banner.cfg	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/syssvc/banner.cfg	(revision 457)
@@ -0,0 +1,10 @@
+/*
+ *  @(#) $Id$
+ */
+
+/*
+ *		カーネル起動メッセージの出力のコンフィギュレーションファイル
+ */
+
+#include "syssvc/banner.h"
+ATT_INI({ TA_NULL, 0, print_banner });
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/syssvc/banner.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/syssvc/banner.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/syssvc/banner.h	(revision 457)
@@ -0,0 +1,53 @@
+/*
+ *  TOPPERS/ASP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Advanced Standard Profile Kernel
+ * 
+ *  Copyright (C) 2008 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *		カーネル起動メッセージの出力
+ */
+
+#ifndef TOPPERS_BANNER_H
+#define TOPPERS_BANNER_H
+
+/*
+ *  カーネル起動メッセージの出力
+ */
+extern void	print_banner(intptr_t exinf) throw();
+
+#endif /* TOPPERS_BANNER_H */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/syssvc/logtask.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/syssvc/logtask.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/syssvc/logtask.c	(revision 457)
@@ -0,0 +1,198 @@
+/*
+ *  TOPPERS/ASP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Advanced Standard Profile Kernel
+ * 
+ *  Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
+ *                              Toyohashi Univ. of Technology, JAPAN
+ *  Copyright (C) 2005-2011 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *		システムログタスク
+ */
+
+#include <kernel.h>
+#include <t_syslog.h>
+#include <log_output.h>
+#include "syssvc/serial.h"
+#include "syssvc/syslog.h"
+#include "logtask.h"
+
+/*
+ *  システムログタスクの出力先のポートID
+ */
+static ID	logtask_portid;
+
+/*
+ *  シリアルインタフェースへの1文字出力
+ */
+static void
+logtask_putc(char c)
+{
+	(void) serial_wri_dat(logtask_portid, &c, 1);
+}
+
+/*
+ *  システムログ出力の待ち合わせ
+ */
+ER
+logtask_flush(uint_t count)
+{
+	T_SYSLOG_RLOG	rlog;
+	T_SERIAL_RPOR	rpor;
+	ER				ercd, rercd;
+
+	if (sns_dpn()) {
+		ercd = E_CTX;
+	}
+	else {
+		for (;;) {
+			if (syslog_ref_log(&rlog) < 0) {
+				ercd = E_SYS;
+				goto error_exit;
+			}
+			if (rlog.count <= count) {
+				if (count == 0U) {
+					/*
+					 *  countが0の場合には，シリアルバッファが空かを確
+					 *  認する．
+					 */
+					if (serial_ref_por(logtask_portid, &rpor) < 0) {
+						ercd = E_SYS;
+						goto error_exit;
+					}
+					if (rpor.wricnt == 0U) {
+						ercd = E_OK;
+						goto error_exit;
+					}
+				}
+				else {
+					ercd = E_OK;
+					goto error_exit;
+				}
+			}
+
+			/*
+			 *  LOGTASK_FLUSH_WAITミリ秒待つ．
+			 */
+			rercd = dly_tsk(LOGTASK_FLUSH_WAIT);
+			if (rercd < 0) {
+				ercd = (rercd == E_RLWAI) ? rercd : E_SYS;
+				goto error_exit;
+			}
+		}
+	}
+
+  error_exit:
+	return(ercd);
+}
+
+/*
+ *  システムログタスクの本体
+ */
+void
+logtask_main(intptr_t exinf)
+{
+	SYSLOG	logbuf;
+	uint_t	lostlog;
+	ER_UINT	rercd;
+
+	logtask_portid = (ID) exinf;
+	(void) serial_opn_por(logtask_portid);
+	(void) syslog_msk_log(LOG_UPTO(LOG_NOTICE), LOG_UPTO(LOG_EMERG));
+	syslog_1(LOG_NOTICE, "System logging task is started on port %d.",
+													logtask_portid);
+	for (;;) {
+		lostlog = 0U;
+		while ((rercd = syslog_rea_log(&logbuf)) >= 0) {
+			lostlog += (uint_t) rercd;
+			if (logbuf.logtype >= LOG_TYPE_COMMENT) {
+				if (lostlog > 0U) {
+					syslog_lostmsg(lostlog, logtask_putc);
+					lostlog = 0U;
+				}
+				syslog_print(&logbuf, logtask_putc);
+				logtask_putc('\n');
+			}
+		}
+		if (lostlog > 0U) {
+			syslog_lostmsg(lostlog, logtask_putc);
+		}
+		(void) dly_tsk(LOGTASK_INTERVAL);
+	}
+}
+
+/*
+ *  システムログタスクの終了処理
+ */
+void
+logtask_terminate(intptr_t exinf)
+{
+	char	c;
+	SYSLOG	logbuf;
+	bool_t	msgflg = false;
+	ER_UINT	rercd;
+
+	/*
+	 *  シリアルインタフェースドライバの送信バッファに蓄積されたデータ
+	 *  を，低レベル出力機能を用いて出力する．
+	 */
+	while (serial_get_chr(logtask_portid, &c)) {
+		target_fput_log(c);
+	}
+
+	/*
+	 *  ログバッファに記録されたログ情報を，低レベル出力機能を用いて出
+	 *  力する．
+	 */
+	while ((rercd = syslog_rea_log(&logbuf)) >= 0) {
+		if (!msgflg) {
+			/*
+			 *  ログバッファに残ったログ情報であることを示す文字列を出
+			 *  力する．
+			 */
+			syslog_printf("-- buffered messages --\n", NULL, target_fput_log);
+			msgflg = true;
+		}
+		if (rercd > 0) {
+			syslog_lostmsg((uint_t) rercd, target_fput_log);
+		}
+		if (logbuf.logtype >= LOG_TYPE_COMMENT) {
+			syslog_print(&logbuf, target_fput_log);
+			target_fput_log('\n');
+		}
+	}
+}
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/syssvc/logtask.cfg
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/syssvc/logtask.cfg	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/syssvc/logtask.cfg	(revision 457)
@@ -0,0 +1,12 @@
+/*
+ *  @(#) $Id$
+ */
+
+/*
+ *		システムログタスクのコンフィギュレーションファイル
+ */
+
+#include "syssvc/logtask.h"
+CRE_TSK(LOGTASK, { TA_ACT, LOGTASK_PORTID, logtask_main,
+						LOGTASK_PRIORITY, LOGTASK_STACK_SIZE, NULL });
+ATT_TER({ TA_NULL, 0, logtask_terminate });
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/syssvc/logtask.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/syssvc/logtask.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/syssvc/logtask.h	(revision 457)
@@ -0,0 +1,101 @@
+/*
+ *  TOPPERS/ASP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Advanced Standard Profile Kernel
+ * 
+ *  Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
+ *                              Toyohashi Univ. of Technology, JAPAN
+ *  Copyright (C) 2004-2008 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *		システムログタスク
+ */
+
+#ifndef TOPPERS_LOGTASK_H
+#define TOPPERS_LOGTASK_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "target_syssvc.h"
+
+/*
+ *  システムログタスク関連の定数のデフォルト値の定義
+ */ 
+#ifndef LOGTASK_PRIORITY
+#define LOGTASK_PRIORITY	3		/* 初期優先度 */
+#endif /* LOGTASK_PRIORITY */
+
+#ifndef LOGTASK_STACK_SIZE
+#define LOGTASK_STACK_SIZE	1024	/* スタック領域のサイズ */
+#endif /* LOGTASK_STACK_SIZE */
+
+#ifndef LOGTASK_PORTID
+#define LOGTASK_PORTID		1		/* システムログ用のシリアルポート番号 */
+#endif /* LOGTASK_PORTID */
+
+#ifndef LOGTASK_INTERVAL
+#define LOGTASK_INTERVAL	10U		/* システムログタスクの動作間隔（ミリ秒）*/
+#endif /* LOGTASK_INTERVAL */
+
+#ifndef LOGTASK_FLUSH_WAIT
+#define LOGTASK_FLUSH_WAIT	1U		/* フラッシュ待ちの単位時間（ミリ秒）*/
+#endif /* LOGTASK_FLUSH_WAIT */
+
+/*
+ *  システムログ出力の待ち合わせ
+ *
+ *  ログバッファ中のログの数がcount以下になるまで待つ．countが0の場合に
+ *  は，シリアルバッファが空になるのも待つ．
+ */
+extern ER	logtask_flush(uint_t count) throw();
+
+/*
+ *  システムログタスクの本体
+ */
+extern void	logtask_main(intptr_t exinf) throw();
+
+/*
+ *  システムログタスクの終了処理
+ */
+extern void	logtask_terminate(intptr_t exinf) throw();
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* TOPPERS_LOGTASK_H */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/syssvc/malloc.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/syssvc/malloc.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/syssvc/malloc.c	(revision 457)
@@ -0,0 +1,395 @@
+/*
+ *  TOPPERS/ASP/FMP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Advanced Standard Profile Kernel
+ * 
+ *  Copyright (C) 2008-2011 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ *  Copyright (C) 2015-2020 by TOPPERS PROJECT Educational Working Group.
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+/*
+ * 
+ *  メモリアロケーション機能
+ *
+ */
+#include <kernel.h>
+#include <t_syslog.h>
+#include <stdlib.h>
+#include <string.h>
+#include "kernel_cfg.h"
+
+#ifndef CACHE_LINE_SIZE
+#define CACHE_LINE_SIZE	    32	/* default cacle line size */
+#endif
+
+#if defined(TLSF_SEM)	/* TLSF */
+#include "tlsf.h"
+
+/*
+ *  TLSF2.4.6には、アロケート、フリーを何度も繰り返すと
+ *  アロケート領域の先頭８バイトが破壊される問題がある.
+ *  TLSF側の修正は品質保証できないため、malloc/free関数で
+ *  対応を行う.
+ */
+#define TLSF_PTR_AREA_SIZE  8
+
+static void *memory_pool;
+
+/*
+ *  プール初期化
+ */
+void
+heap_init(intptr_t exinf)
+{
+	intptr_t *param = (intptr_t *)exinf;
+	uint32_t *p;
+	int i, size;
+	memory_pool = (void*)param[0];
+	p = (uint32_t *)param[0];
+	size = param[1] / sizeof(uint32_t);
+	for(i = 0 ; i < size ; i++)
+		*p++ = 0;
+	init_memory_pool(param[1], (void*)memory_pool);
+}
+
+/*
+ *  MALLOC
+ */
+void *
+__wrap__malloc_r(struct _reent *reent, size_t __size)
+{
+	void *mempool, *addr;
+	mempool = (void *)memory_pool;
+	if(mempool == NULL)
+		return NULL;
+	wai_sem(TLSF_SEM);
+	addr = (void*)malloc_ex(__size+TLSF_PTR_AREA_SIZE, mempool);
+	sig_sem(TLSF_SEM);
+	if(addr != NULL)
+		return addr+TLSF_PTR_AREA_SIZE;
+	else
+		return addr;
+}
+
+/*
+ *  CALLOC
+ */
+void *
+__wrap__calloc_r(struct _reent *reent, size_t __nmemb, size_t __size)
+{
+	void *mempool, *addr;
+	mempool = (void *)memory_pool;
+	if(mempool == NULL)
+		return NULL;
+	wai_sem(TLSF_SEM);
+	addr = (void*)malloc_ex((__nmemb * __size)+TLSF_PTR_AREA_SIZE, mempool);
+	sig_sem(TLSF_SEM);
+	if(addr != NULL){
+		memset(addr+TLSF_PTR_AREA_SIZE, 0, __nmemb * __size);
+		return addr+TLSF_PTR_AREA_SIZE;
+	}
+	else
+		return addr;
+}
+
+/*
+ *  REALLOC
+ */
+void *__wrap__realloc_r(struct _reent *reent, void *ptr, size_t __size)
+{
+	void *mempool, *addr;
+	mempool = (void *)memory_pool;
+	if(mempool == NULL)
+		return NULL;
+	wai_sem(TLSF_SEM);
+	addr = (void*)realloc_ex(ptr, __size+TLSF_PTR_AREA_SIZE, mempool);
+	sig_sem(TLSF_SEM);
+	if(addr != NULL)
+		return addr+TLSF_PTR_AREA_SIZE;
+	else
+		return addr;
+}
+
+/*
+ *  FREE
+ */
+void
+__wrap__free_r(struct _reent *reent, void *ptr)
+{
+	void *mempool = memory_pool;
+	if(ptr == NULL)
+		return;
+	if(mempool != NULL){
+		wai_sem(TLSF_SEM);
+		free_ex(ptr-TLSF_PTR_AREA_SIZE, mempool);
+		sig_sem(TLSF_SEM);
+	}
+}
+
+#elif(LOCAL_MALLOC)		/* LOCAL MALLOC */
+
+typedef struct _LMAP LMAP_t;
+struct _LMAP {
+  unsigned long lsize;		/* メモリサイズ */
+  LMAP_t *      laddr;		/* メモリスタートポインタ */
+};
+
+static LMAP_t lmap;
+
+/*
+ *  ローカルアロケータ初期化
+ */
+void
+heap_init(intptr_t exinf)
+{
+	intptr_t *param = (intptr_t *)exinf;
+	LMAP_t *plmap;
+
+	plmap = (LMAP_t *)param[0];
+	plmap->lsize = (unsigned long)param[1];
+	plmap->laddr = NULL;
+	lmap.lsize   = plmap->lsize;
+	lmap.laddr   = plmap;
+}
+
+/*
+ *  MALLOC
+ */
+void *
+__wrap__malloc_r(struct _reent *reent, size_t __size)
+{
+	LMAP_t *ph = &lmap;
+	LMAP_t *p;
+
+	__size = (__size+3+sizeof(unsigned int)) & ~3;
+	if(__size < sizeof(LMAP_t))
+		__size = sizeof(LMAP_t);
+
+	loc_cpu();
+	while((p = ph->laddr) != 0){
+		if(p->lsize >= __size && p->lsize < (__size+sizeof(LMAP_t))){
+			ph->laddr = p->laddr;
+			unl_cpu();
+			return (void *)(&p->laddr);
+		}
+		else if(p->lsize >= (__size+sizeof(LMAP_t))){
+			LMAP_t *pw = (LMAP_t *)((char *)p+__size);
+			pw->lsize = p->lsize-__size;
+			pw->laddr = p->laddr;
+			ph->laddr = pw;
+			p->lsize  = __size;
+			unl_cpu();
+			return (void *)(&p->laddr);
+		}
+		ph = p;
+	}
+	unl_cpu();
+	return NULL;
+}
+
+/*
+ *  CALLOC
+ */
+void *
+__wrap__calloc_r(struct _reent *reent, size_t __nmemb, size_t __size)
+{
+	return __wrap__malloc_r(reent, __nmemb * __size);
+}
+
+/*
+ *  FREE
+ */
+void
+__wrap__free_r(struct _reent *reent, void *ptr)
+{
+	LMAP_t *ph = &lmap;
+	LMAP_t *p;
+	char   *t, *pf;
+
+	if(ptr == NULL)
+		return;
+	p  = (LMAP_t *)((char *)ptr-sizeof(unsigned long));
+	t  = (char *)p+p->lsize;
+	loc_cpu();
+	for(;;){
+		if(ph->laddr == NULL){		/* 空きメモリなし */
+			p->laddr  = NULL;
+			ph->laddr = p;
+			break;
+		}
+		else if(t == (char *)ph->laddr){
+			p->lsize += (ph->laddr)->lsize;
+			p->laddr  = (ph->laddr)->laddr;
+			ph->laddr = p;
+			break;
+		}
+		else if(t < (char *)ph->laddr){
+			p->laddr = ph->laddr;
+			ph->laddr = p;
+			break;
+		}
+		ph = ph->laddr;
+		pf = (char *)ph+ph->lsize;
+		if(pf > (char *)p){			/* 領域オーバーラップ */
+			unl_cpu();
+			syslog_0(LOG_EMERG, "free:FATAL:irrguler free memory !");
+			return;
+		}
+		else if(pf == (char *)p){
+			ph->lsize += p->lsize;
+			if(t > (char *)ph->laddr){	/* 領域オーバーラップ */
+				unl_cpu();
+				syslog_0(LOG_EMERG, "free:FATAL:irrguler free memory !");
+				return;
+			}
+			else if(t == (char *)ph->laddr){
+				ph->lsize += (ph->laddr)->lsize;
+				ph->laddr  = (ph->laddr)->laddr;
+			}
+			break;
+		}
+	}
+	unl_cpu();
+}
+
+#else		/* LIBC MALLOC */
+#include <kernel_impl.h>
+
+static uintptr_t *heap_param;
+static int malloc_lock_count;
+
+/*
+ *  LIBCアロケータ初期化
+ */
+void
+heap_init(intptr_t exinf)
+{
+	heap_param = (uintptr_t *)exinf;
+	malloc_lock_count = 0;
+}
+
+void
+__malloc_lock(void * reent)
+{
+	malloc_lock_count++;
+	if (malloc_lock_count == 1){
+		ER ret;
+		if (sense_context())
+			ret = iloc_cpu();
+		else
+			ret = loc_cpu();
+		if (ret != E_OK)
+			syslog_1(LOG_ERROR, "__malloc_unlock: count[%d] loc_cpu", malloc_lock_count);
+	}
+}
+
+void
+__malloc_unlock(void * reent)
+{
+	malloc_lock_count--;
+	if (malloc_lock_count == 0){
+		ER ret;
+		if (sense_context())
+			ret = iunl_cpu();
+		else
+			ret = unl_cpu();
+		if (ret != E_OK)
+			syslog_1(LOG_ERROR, "__malloc_unlock: count[%d] unl_cpu error !", malloc_lock_count);
+	}
+}
+
+void *
+_sbrk(int incr)
+{ 
+	static char *heap_end = NULL;
+	char        *prev_heap_end;
+
+	if(incr < 0 || incr > heap_param[1]){
+		syslog_2(LOG_ERROR, "_sbrk: incr[%d] parameter error ! %d", incr, malloc_lock_count);
+		return (void *)-1;
+	}
+
+	if(heap_end == NULL)
+		heap_end = (char *)heap_param[0];
+
+	prev_heap_end  = heap_end;
+	heap_end      += incr;
+
+	if(heap_end < (char *)(heap_param[0]+heap_param[1]))
+		return (void *) prev_heap_end;
+	else{
+		heap_end = prev_heap_end;
+		syslog_2(LOG_ERROR, "_sbrk: incr[%d] allocation error ! %d", incr, malloc_lock_count);
+		return (void *)-1;
+	}
+}
+
+#endif
+
+/*
+ *  CACHE ALINE MALLOC
+ */
+void *
+malloc_cache(uint32_t len)
+{
+	void * addr = malloc(len+CACHE_LINE_SIZE);
+	uint32_t *p;
+	intptr_t uaddr;
+
+	if(addr == NULL)
+		return addr;
+	p = addr;
+	uaddr = (intptr_t)addr;
+	if((uaddr & (CACHE_LINE_SIZE-1)) != 0)
+		uaddr &= ~(CACHE_LINE_SIZE-1);
+	uaddr += CACHE_LINE_SIZE;
+	p = (uint32_t *)uaddr;
+	*(p-1) = (intptr_t)addr;
+	return p;
+}
+
+/*
+ *  CACHE ALINE FREE
+ */
+void
+free_cache(void *addr)
+{
+	intptr_t *p = addr;
+
+	if(addr == NULL)
+		return;
+	addr = (void*)(*(p-1));
+	free(addr);
+}
+
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/syssvc/serial.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/syssvc/serial.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/syssvc/serial.c	(revision 457)
@@ -0,0 +1,786 @@
+/*
+ *  TOPPERS/ASP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Advanced Standard Profile Kernel
+ * 
+ *  Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
+ *                              Toyohashi Univ. of Technology, JAPAN
+ *  Copyright (C) 2006-2013 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *		シリアルインタフェースドライバ
+ */
+
+#include <kernel.h>
+#include <t_syslog.h>
+#include "target_syssvc.h"
+#include "target_serial.h"
+#include "serial.h"
+#include "kernel_cfg.h"
+
+/*
+ *  バッファサイズのデフォルト値とバッファの定義
+ */
+#ifndef SERIAL_RCV_BUFSZ1
+#define	SERIAL_RCV_BUFSZ1	256			/* ポート1の受信バッファサイズ */
+#endif /* SERIAL_RCV_BUFSZ1 */
+
+#ifndef SERIAL_SND_BUFSZ1
+#define	SERIAL_SND_BUFSZ1	256			/* ポート1の送信バッファサイズ */
+#endif /* SERIAL_SND_BUFSZ1 */
+
+static char	rcv_buffer1[SERIAL_RCV_BUFSZ1];
+static char	snd_buffer1[SERIAL_SND_BUFSZ1];
+
+#if TNUM_PORT >= 2						/* ポート2に関する定義 */
+
+#ifndef SERIAL_RCV_BUFSZ2
+#define	SERIAL_RCV_BUFSZ2	256			/* ポート2の受信バッファサイズ */
+#endif /* SERIAL_RCV_BUFSZ2 */
+
+#ifndef SERIAL_SND_BUFSZ2
+#define	SERIAL_SND_BUFSZ2	256			/* ポート2の送信バッファサイズ */
+#endif /* SERIAL_SND_BUFSZ2 */
+
+static char	rcv_buffer2[SERIAL_RCV_BUFSZ2];
+static char	snd_buffer2[SERIAL_SND_BUFSZ2];
+
+#endif /* TNUM_PORT >= 2 */
+
+#if TNUM_PORT >= 3						/* ポート3に関する定義 */
+
+#ifndef SERIAL_RCV_BUFSZ3
+#define	SERIAL_RCV_BUFSZ3	256			/* ポート3の受信バッファサイズ */
+#endif /* SERIAL_RCV_BUFSZ3 */
+
+#ifndef SERIAL_SND_BUFSZ3
+#define	SERIAL_SND_BUFSZ3	256			/* ポート3の送信バッファサイズ */
+#endif /* SERIAL_SND_BUFSZ3 */
+
+static char	rcv_buffer3[SERIAL_RCV_BUFSZ3];
+static char	snd_buffer3[SERIAL_SND_BUFSZ3];
+
+#endif /* TNUM_PORT >= 3 */
+
+#if TNUM_PORT >= 4						/* ポート4に関する定義 */
+
+#ifndef SERIAL_RCV_BUFSZ4
+#define	SERIAL_RCV_BUFSZ4	256			/* ポート4の受信バッファサイズ */
+#endif /* SERIAL_RCV_BUFSZ4 */
+
+#ifndef SERIAL_SND_BUFSZ4
+#define	SERIAL_SND_BUFSZ4	256			/* ポート4の送信バッファサイズ */
+#endif /* SERIAL_SND_BUFSZ4 */
+
+static char	rcv_buffer4[SERIAL_RCV_BUFSZ4];
+static char	snd_buffer4[SERIAL_SND_BUFSZ4];
+
+#endif /* TNUM_PORT >= 4 */
+
+#if TNUM_PORT >= 5
+#error Serial interface driver supports up to 4 ports.
+#endif /* TNUM_PORT >= 5 */
+
+/*
+ *  フロー制御に関連する定数とマクロ
+ */
+#define	FC_STOP			'\023'		/* コントロール-S */
+#define	FC_START		'\021'		/* コントロール-Q */
+
+#define BUFCNT_STOP(bufsz)		((bufsz) * 3 / 4)	/* STOPを送る基準文字数 */
+#define BUFCNT_START(bufsz)		((bufsz) / 2)		/* STARTを送る基準文字数 */
+
+/*
+ *  シリアルポート初期化ブロック
+ */
+typedef struct serial_port_initialization_block {
+	ID		rcv_semid;		/* 受信バッファ管理用セマフォのID */
+	ID		snd_semid;		/* 送信バッファ管理用セマフォのID */
+	uint_t	rcv_bufsz;		/* 受信バッファサイズ */
+	char	*rcv_buffer;	/* 受信バッファ */
+	uint_t	snd_bufsz;		/* 送信バッファサイズ */
+	char	*snd_buffer;	/* 送信バッファ */
+} SPINIB;
+
+static const SPINIB spinib_table[TNUM_PORT] = {
+	{ SERIAL_RCV_SEM1, SERIAL_SND_SEM1,
+	  SERIAL_RCV_BUFSZ1, rcv_buffer1,
+	  SERIAL_SND_BUFSZ1, snd_buffer1 },
+#if TNUM_PORT >= 2
+	{ SERIAL_RCV_SEM2, SERIAL_SND_SEM2,
+	  SERIAL_RCV_BUFSZ2, rcv_buffer2,
+	  SERIAL_SND_BUFSZ2, snd_buffer2 },
+#endif /* TNUM_PORT >= 2 */
+#if TNUM_PORT >= 3
+	{ SERIAL_RCV_SEM3, SERIAL_SND_SEM3,
+	  SERIAL_RCV_BUFSZ3, rcv_buffer3,
+	  SERIAL_SND_BUFSZ3, snd_buffer3 },
+#endif /* TNUM_PORT >= 3 */
+#if TNUM_PORT >= 4
+	{ SERIAL_RCV_SEM4, SERIAL_SND_SEM4,
+	  SERIAL_RCV_BUFSZ4, rcv_buffer4,
+	  SERIAL_SND_BUFSZ4, snd_buffer4 },
+#endif /* TNUM_PORT >= 4 */
+};
+
+/*
+ *  シリアルポート管理ブロック
+ */
+typedef struct serial_port_control_block {
+	const SPINIB *p_spinib;		/* シリアルポート初期化ブロック */
+	SIOPCB	*p_siopcb;			/* シリアルI/Oポート管理ブロック */
+	bool_t	openflag;			/* オープン済みフラグ */
+	bool_t	errorflag;			/* エラーフラグ */
+	uint_t	ioctl;				/* 動作制御の設定値 */
+
+	uint_t	rcv_read_ptr;		/* 受信バッファ読出しポインタ */
+	uint_t	rcv_write_ptr;		/* 受信バッファ書込みポインタ */
+	uint_t	rcv_count;			/* 受信バッファ中の文字数 */
+	char	rcv_fc_chr;			/* 送るべきSTART/STOP */
+	bool_t	rcv_stopped;		/* STOPを送った状態か？ */
+
+	uint_t	snd_read_ptr;		/* 送信バッファ読出しポインタ */
+	uint_t	snd_write_ptr;		/* 送信バッファ書込みポインタ */
+	uint_t	snd_count;			/* 送信バッファ中の文字数 */
+	bool_t	snd_stopped;		/* STOPを受け取った状態か？ */
+} SPCB;
+
+static SPCB	spcb_table[TNUM_PORT];
+
+/*
+ *  シリアルポートIDからシリアルポート管理ブロックを取り出すためのマクロ
+ */
+#define INDEX_PORT(portid)	((uint_t)((portid) - 1))
+#define get_spcb(portid)	(&(spcb_table[INDEX_PORT(portid)]))
+
+/*
+ *  ポインタのインクリメント
+ */
+#define INC_PTR(ptr, bufsz) do {	\
+	if (++(ptr) == (bufsz)) {		\
+		(ptr) = 0;					\
+	 }								\
+} while (false)
+
+/*
+ *  サービスコール呼出しマクロ
+ *
+ *  サービスコール呼出しを含む式expを評価し，返値がエラー（負の値）の場
+ *  合には，ercにercd_expを評価した値を代入し，error_exitにgotoする．
+ */
+#define SVC(exp, ercd_exp) do {		\
+	if ((exp) < 0) {				\
+		ercd = (ercd_exp);			\
+		goto error_exit;			\
+	}								\
+} while (false)
+
+/*
+ *  E_SYSエラーの生成
+ */
+static ER
+gen_ercd_sys(SPCB *p_spcb)
+{
+	p_spcb->errorflag = true;
+	return(E_SYS);
+}
+
+/*
+ *  待ちに入るサービスコールからのエラーの変換
+ */
+static ER
+gen_ercd_wait(ER rercd, SPCB *p_spcb)
+{
+	switch (MERCD(rercd)) {
+	case E_RLWAI:
+	case E_DLT:
+		return(rercd);
+	default:
+		p_spcb->errorflag = true;
+		return(E_SYS);
+	}
+}
+
+/*
+ *  シリアルインタフェースドライバの初期化ルーチン
+ */
+void
+serial_initialize(intptr_t exinf)
+{
+	uint_t	i;
+	SPCB	*p_spcb;
+
+	for (i = 0; i < TNUM_PORT; i++) {
+		p_spcb = &(spcb_table[i]);
+		p_spcb->p_spinib = &(spinib_table[i]);
+		p_spcb->openflag = false;
+	}
+}
+
+/*
+ *  シリアルポートのオープン（サービスコール）
+ */
+ER
+serial_opn_por(ID portid)
+{
+	SPCB	*p_spcb;
+	ER		ercd;
+
+	if (sns_dpn()) {				/* コンテキストのチェック */
+		return(E_CTX);
+	}
+	if (!(1 <= portid && portid <= TNUM_PORT)) {
+		return(E_ID);				/* ポート番号のチェック */
+	}
+	p_spcb = get_spcb(portid);
+
+	SVC(dis_dsp(), gen_ercd_sys(p_spcb));
+	if (p_spcb->openflag) {			/* オープン済みかのチェック */
+		ercd = E_OBJ;
+	}
+	else {
+		/*
+		 *  変数の初期化
+		 */
+		p_spcb->ioctl = (IOCTL_ECHO | IOCTL_CRLF | IOCTL_FCSND | IOCTL_FCRCV);
+
+		p_spcb->rcv_read_ptr = 0U;
+		p_spcb->rcv_write_ptr = 0U;
+		p_spcb->rcv_count = 0U;
+		p_spcb->rcv_fc_chr = '\0';
+		p_spcb->rcv_stopped = false;
+
+		p_spcb->snd_read_ptr = 0U;
+		p_spcb->snd_write_ptr = 0U;
+		p_spcb->snd_count = 0U;
+		p_spcb->snd_stopped = false;
+
+		/*
+		 *  これ以降，割込みを禁止する．
+		 */
+		if (loc_cpu() < 0) {
+			ercd = E_SYS;
+			goto error_exit_enadsp;
+		}
+
+		/*
+		 *  ハードウェア依存のオープン処理
+		 */
+		p_spcb->p_siopcb = sio_opn_por(portid, (intptr_t) p_spcb);
+
+		/*
+		 *  受信通知コールバックを許可する．
+		 */
+		sio_ena_cbr(p_spcb->p_siopcb, SIO_RDY_RCV);
+		p_spcb->openflag = true;
+		p_spcb->errorflag = false;
+
+		if (unl_cpu() < 0) {
+			p_spcb->errorflag = true;
+			ercd = E_SYS;
+			goto error_exit_enadsp;
+		}
+		ercd = E_OK;
+	}
+
+  error_exit_enadsp:
+	SVC(ena_dsp(), gen_ercd_sys(p_spcb));
+
+  error_exit:
+	return(ercd);
+}
+
+/*
+ *  シリアルポートのクローズ（サービスコール）
+ */
+ER
+serial_cls_por(ID portid)
+{
+	SPCB	*p_spcb;
+	ER		ercd;
+	bool_t	eflag = false;
+
+	if (sns_dpn()) {				/* コンテキストのチェック */
+		return(E_CTX);
+	}
+	if (!(1 <= portid && portid <= TNUM_PORT)) {
+		return(E_ID);				/* ポート番号のチェック */
+	}
+	p_spcb = get_spcb(portid);
+
+	SVC(dis_dsp(), gen_ercd_sys(p_spcb));
+	if (!(p_spcb->openflag)) {		/* オープン済みかのチェック */
+		ercd = E_OBJ;
+	}
+	else {
+		/*
+		 *  ハードウェア依存のクローズ処理
+		 */
+		if (loc_cpu() < 0) {
+			eflag = true;
+		}
+		sio_cls_por(p_spcb->p_siopcb);
+		p_spcb->openflag = false;
+		if (unl_cpu() < 0) {
+			eflag = true;
+		}
+
+		/*
+		 *  セマフォの初期化
+		 */
+		if (ini_sem(p_spcb->p_spinib->snd_semid) < 0) {
+			eflag = true;
+		}
+		if (ini_sem(p_spcb->p_spinib->rcv_semid) < 0) {
+			eflag = true;
+		}
+
+		/*
+		 *  エラーコードの設定
+		 */
+		if (eflag) {
+			ercd = gen_ercd_sys(p_spcb);
+		}
+		else {
+			ercd = E_OK;
+		}
+	}
+	SVC(ena_dsp(), gen_ercd_sys(p_spcb));
+
+  error_exit:
+	return(ercd);
+}
+
+/*
+ *  シリアルポートへの文字送信
+ *
+ *  p_spcbで指定されるシリアルI/Oポートに対して，文字cを送信する．文字
+ *  を送信レジスタにいれた場合にはtrueを返す．そうでない場合には，送信
+ *  レジスタが空いたことを通知するコールバック関数を許可し，falseを返す．
+ *  この関数は，CPUロック状態で呼び出される．
+ */
+Inline bool_t
+serial_snd_chr(SPCB *p_spcb, char c)
+{
+	if (sio_snd_chr(p_spcb->p_siopcb, c)) {
+		return(true);
+	}
+	else {
+		sio_ena_cbr(p_spcb->p_siopcb, SIO_RDY_SND);
+		return(false);
+	}
+}
+
+/*
+ *  シリアルポートへの1文字送信
+ */
+static ER_BOOL
+serial_wri_chr(SPCB *p_spcb, char c)
+{
+	bool_t	buffer_full;
+	ER		ercd, rercd;
+
+	/*
+	 *  LFの前にCRを送信する．
+	 */
+	if (c == '\n' && (p_spcb->ioctl & IOCTL_CRLF) != 0U) {
+		/*
+		 *  以下のコードは再帰呼出しになっているが，引数cが'\n'の場合に
+		 *  引数cを'\r'として呼び出すことから，この再帰呼出しは2回目の
+		 *  呼び出しで必ず止まる．
+		 */
+		SVC(rercd = serial_wri_chr(p_spcb, '\r'), rercd);
+		if ((bool_t) rercd) {
+			SVC(rercd = wai_sem(p_spcb->p_spinib->snd_semid),
+										gen_ercd_wait(rercd, p_spcb));
+		}
+	}
+
+	SVC(loc_cpu(), gen_ercd_sys(p_spcb));
+	if (p_spcb->snd_count == 0U && !(p_spcb->snd_stopped)
+								&& serial_snd_chr(p_spcb, c)) {
+		/*
+		 *  シリアルI/Oデバイスの送信レジスタに文字を入れることに成功し
+		 *  た場合．
+		 */
+		buffer_full = false;
+	}
+	else {
+		/*
+		 *  送信バッファに文字を入れる．
+		 */
+		p_spcb->p_spinib->snd_buffer[p_spcb->snd_write_ptr] = c;
+		INC_PTR(p_spcb->snd_write_ptr, p_spcb->p_spinib->snd_bufsz);
+		p_spcb->snd_count++;
+		buffer_full = (p_spcb->snd_count == p_spcb->p_spinib->snd_bufsz);
+	}
+
+	SVC(unl_cpu(), gen_ercd_sys(p_spcb));
+	ercd = (ER_BOOL) buffer_full;
+
+  error_exit:
+	return(ercd);
+}
+
+/*
+ *  シリアルポートへの文字列送信（サービスコール）
+ */
+ER_UINT
+serial_wri_dat(ID portid, const char *buf, uint_t len)
+{
+	SPCB	*p_spcb;
+	bool_t	buffer_full;
+	uint_t	wricnt = 0U;
+	ER		ercd, rercd;
+
+	if (sns_dpn()) {				/* コンテキストのチェック */
+		return(E_CTX);
+	}
+	if (!(1 <= portid && portid <= TNUM_PORT)) {
+		return(E_ID);				/* ポート番号のチェック */
+	}
+
+	p_spcb = get_spcb(portid);
+	if (!(p_spcb->openflag)) {		/* オープン済みかのチェック */
+		return(E_OBJ);
+	}
+	if (p_spcb->errorflag) {		/* エラー状態かのチェック */
+		return(E_SYS);
+	}
+
+	buffer_full = true;				/* ループの1回めはwai_semする */
+	while (wricnt < len) {
+		if (buffer_full) {
+			SVC(rercd = wai_sem(p_spcb->p_spinib->snd_semid),
+										gen_ercd_wait(rercd, p_spcb));
+		}
+		SVC(rercd = serial_wri_chr(p_spcb, *buf++), rercd);
+		wricnt++;
+		buffer_full = (bool_t) rercd;
+	}
+	if (!buffer_full) {
+		SVC(sig_sem(p_spcb->p_spinib->snd_semid), gen_ercd_sys(p_spcb));
+	}
+	ercd = E_OK;
+
+  error_exit:
+	return(wricnt > 0U ? (ER_UINT) wricnt : ercd);
+}
+
+/*
+ *  シリアルポートからの1文字受信
+ */
+static bool_t
+serial_rea_chr(SPCB *p_spcb, char *p_c)
+{
+	bool_t	buffer_empty;
+	ER		ercd;
+
+	SVC(loc_cpu(), gen_ercd_sys(p_spcb));
+
+	/*
+	 *  受信バッファから文字を取り出す．
+	 */
+	*p_c = p_spcb->p_spinib->rcv_buffer[p_spcb->rcv_read_ptr];
+	INC_PTR(p_spcb->rcv_read_ptr, p_spcb->p_spinib->rcv_bufsz);
+	p_spcb->rcv_count--;
+	buffer_empty = (p_spcb->rcv_count == 0U);
+
+	/*
+	 *  STARTを送信する．
+	 */
+	if (p_spcb->rcv_stopped && p_spcb->rcv_count
+								<= BUFCNT_START(p_spcb->p_spinib->rcv_bufsz)) {
+		if (!serial_snd_chr(p_spcb, FC_START)) {
+			p_spcb->rcv_fc_chr = FC_START;
+		}
+		p_spcb->rcv_stopped = false;
+	}
+
+	SVC(unl_cpu(), gen_ercd_sys(p_spcb));
+	ercd = (ER_BOOL) buffer_empty;
+
+  error_exit:
+	return(ercd);
+}
+
+/*
+ *  シリアルポートからの文字列受信（サービスコール）
+ */
+ER_UINT
+serial_rea_dat(ID portid, char *buf, uint_t len)
+{
+	SPCB	*p_spcb;
+	bool_t	buffer_empty;
+	uint_t	reacnt = 0U;
+	char	c = '\0';		/* コンパイラの警告を抑止するために初期化する */
+	ER		ercd, rercd;
+
+	if (sns_dpn()) {				/* コンテキストのチェック */
+		return(E_CTX);
+	}
+	if (!(1 <= portid && portid <= TNUM_PORT)) {
+		return(E_ID);				/* ポート番号のチェック */
+	}
+
+	p_spcb = get_spcb(portid);
+	if (!(p_spcb->openflag)) {		/* オープン済みかのチェック */
+		return(E_OBJ);
+	}
+	if (p_spcb->errorflag) {		/* エラー状態かのチェック */
+		return(E_SYS);
+	}
+
+	buffer_empty = true;			/* ループの1回めはwai_semする */
+	while (reacnt < len) {
+		if (buffer_empty) {
+			SVC(rercd = wai_sem(p_spcb->p_spinib->rcv_semid),
+										gen_ercd_wait(rercd, p_spcb));
+		}
+		SVC(rercd = serial_rea_chr(p_spcb, &c), rercd);
+		*buf++ = c;
+		reacnt++;
+		buffer_empty = (bool_t) rercd;
+
+		/*
+		 *  エコーバック処理．
+		 */
+		if ((p_spcb->ioctl & IOCTL_ECHO) != 0U) {
+			SVC(rercd = wai_sem(p_spcb->p_spinib->snd_semid),
+										gen_ercd_wait(rercd, p_spcb));
+			SVC(rercd = serial_wri_chr(p_spcb, c), rercd);
+			if (!((bool_t) rercd)) {
+				SVC(sig_sem(p_spcb->p_spinib->snd_semid),
+										gen_ercd_sys(p_spcb));
+			}
+		}
+	}
+	if (!buffer_empty) {
+		SVC(sig_sem(p_spcb->p_spinib->rcv_semid), gen_ercd_sys(p_spcb));
+	}
+	ercd = E_OK;
+
+  error_exit:
+	return(reacnt > 0U ? (ER_UINT) reacnt : ercd);
+}
+
+/*
+ *  シリアルポートの制御（サービスコール）
+ */
+ER
+serial_ctl_por(ID portid, uint_t ioctl)
+{
+	SPCB	*p_spcb;
+
+	if (sns_dpn()) {				/* コンテキストのチェック */
+		return(E_CTX);
+	}
+	if (!(1 <= portid && portid <= TNUM_PORT)) {
+		return(E_ID);				/* ポート番号のチェック */
+	}
+
+	p_spcb = get_spcb(portid);
+	if (!(p_spcb->openflag)) {		/* オープン済みかのチェック */
+		return(E_OBJ);
+	}
+	if (p_spcb->errorflag) {		/* エラー状態かのチェック */
+		return(E_SYS);
+	}
+
+	p_spcb->ioctl = ioctl;
+	return(E_OK);
+}
+
+/*
+ *  シリアルポート状態の参照（サービスコール）
+ */
+ER
+serial_ref_por(ID portid, T_SERIAL_RPOR *pk_rpor)
+{
+	SPCB	*p_spcb;
+
+	if (sns_dpn()) {				/* コンテキストのチェック */
+		return(E_CTX);
+	}
+	if (!(1 <= portid && portid <= TNUM_PORT)) {
+		return(E_ID);				/* ポート番号のチェック */
+	}
+
+	p_spcb = get_spcb(portid);
+	if (!(p_spcb->openflag)) {		/* オープン済みかのチェック */
+		return(E_OBJ);
+	}
+	if (p_spcb->errorflag) {		/* エラー状態かのチェック */
+		return(E_SYS);
+	}
+
+	pk_rpor->reacnt = p_spcb->rcv_count;
+	pk_rpor->wricnt = p_spcb->snd_count;
+	return(E_OK);
+}
+
+/*
+ *  シリアルポートからの送信可能コールバック
+ */
+void
+sio_irdy_snd(intptr_t exinf)
+{
+	SPCB	*p_spcb;
+
+	p_spcb = (SPCB *) exinf;
+	if (p_spcb->rcv_fc_chr != '\0') {
+		/*
+		 *  START/STOP を送信する．
+		 */
+		(void) sio_snd_chr(p_spcb->p_siopcb, p_spcb->rcv_fc_chr);
+		p_spcb->rcv_fc_chr = '\0';
+	}
+	else if (!(p_spcb->snd_stopped) && p_spcb->snd_count > 0U) {
+		/*
+		 *  送信バッファ中から文字を取り出して送信する．
+		 */
+		(void) sio_snd_chr(p_spcb->p_siopcb,
+					p_spcb->p_spinib->snd_buffer[p_spcb->snd_read_ptr]);
+		INC_PTR(p_spcb->snd_read_ptr, p_spcb->p_spinib->snd_bufsz);
+		if (p_spcb->snd_count == p_spcb->p_spinib->snd_bufsz) {
+			if (isig_sem(p_spcb->p_spinib->snd_semid) < 0) {
+				p_spcb->errorflag = true;
+			}
+		}
+		p_spcb->snd_count--;
+	}
+	else {
+		/*
+		 *  送信すべき文字がない場合は，送信可能コールバックを禁止する．
+		 */
+		sio_dis_cbr(p_spcb->p_siopcb, SIO_RDY_SND);
+	}
+}
+
+/*
+ *  シリアルポートからの受信通知コールバック
+ */
+void
+sio_irdy_rcv(intptr_t exinf)
+{
+	SPCB	*p_spcb;
+	char	c;
+
+	p_spcb = (SPCB *) exinf;
+	c = (char) sio_rcv_chr(p_spcb->p_siopcb);
+	if ((p_spcb->ioctl & IOCTL_FCSND) != 0U && c == FC_STOP) {
+		/*
+		 *  送信を一時停止する．送信中の文字はそのまま送信する．
+		 */
+		p_spcb->snd_stopped = true;
+	}
+	else if (p_spcb->snd_stopped && (c == FC_START
+				|| (p_spcb->ioctl & IOCTL_FCANY) != 0U)) {
+		/*
+		 *  送信を再開する．
+		 */
+		p_spcb->snd_stopped = false;
+		if (p_spcb->snd_count > 0U) {
+			c = p_spcb->p_spinib->snd_buffer[p_spcb->snd_read_ptr];
+			if (serial_snd_chr(p_spcb, c)) {
+				INC_PTR(p_spcb->snd_read_ptr, p_spcb->p_spinib->snd_bufsz);
+				if (p_spcb->snd_count == p_spcb->p_spinib->snd_bufsz) {
+					if (isig_sem(p_spcb->p_spinib->snd_semid) < 0) {
+						p_spcb->errorflag = true;
+					}
+				}
+				p_spcb->snd_count--;
+			}
+		}
+	}
+	else if ((p_spcb->ioctl & IOCTL_FCSND) != 0U && c == FC_START) {
+		/*
+		 *  送信に対してフロー制御している場合，START は捨てる．
+		 */
+	}
+	else if (p_spcb->rcv_count == p_spcb->p_spinib->rcv_bufsz) {
+		/*
+		 *  バッファフルの場合，受信した文字を捨てる．
+		 */
+	}
+	else {
+		/*
+		 *  受信した文字を受信バッファに入れる．
+		 */
+		p_spcb->p_spinib->rcv_buffer[p_spcb->rcv_write_ptr] = c;
+		INC_PTR(p_spcb->rcv_write_ptr, p_spcb->p_spinib->rcv_bufsz);
+		if (p_spcb->rcv_count == 0U) {
+			if (isig_sem(p_spcb->p_spinib->rcv_semid) < 0) {
+				p_spcb->errorflag = true;
+			}
+		}
+		p_spcb->rcv_count++;
+
+		/*
+		 *  STOPを送信する．
+		 */
+		if ((p_spcb->ioctl & IOCTL_FCRCV) != 0U && !(p_spcb->rcv_stopped)
+						&& p_spcb->rcv_count
+							>= BUFCNT_STOP(p_spcb->p_spinib->rcv_bufsz)) {
+			if (!serial_snd_chr(p_spcb, FC_STOP)) {
+				p_spcb->rcv_fc_chr = FC_STOP;
+			}
+			p_spcb->rcv_stopped = true;
+		}
+	}
+}
+
+/*
+ *  シリアルインタフェースドライバからの未送信文字の取出し
+ */
+bool_t
+serial_get_chr(ID portid, char *p_c)
+{
+	SPCB	*p_spcb;
+
+	if (1 <= portid && portid <= TNUM_PORT) {	/* ポート番号のチェック */
+		p_spcb = get_spcb(portid);
+		if (p_spcb->openflag) {					/* オープン済みかのチェック */
+			if (p_spcb->snd_count > 0U) {
+				*p_c = p_spcb->p_spinib->snd_buffer[p_spcb->snd_read_ptr];
+				INC_PTR(p_spcb->snd_read_ptr, p_spcb->p_spinib->snd_bufsz);
+				p_spcb->snd_count--;
+				return(true);
+			}
+		}
+	}
+	return(false);
+}
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/syssvc/serial.cfg
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/syssvc/serial.cfg	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/syssvc/serial.cfg	(revision 457)
@@ -0,0 +1,28 @@
+/*
+ *  @(#) $Id$
+ */
+
+/*
+ *  シリアルインタフェースドライバのコンフィギュレーションファイル
+ */
+
+#include "target_syssvc.h"
+INCLUDE("target_serial.cfg");
+
+#include "syssvc/serial.h"
+ATT_INI({ TA_NULL, 0, serial_initialize });
+
+CRE_SEM(SERIAL_RCV_SEM1, { TA_TPRI, 0, 1 });
+CRE_SEM(SERIAL_SND_SEM1, { TA_TPRI, 1, 1 });
+#if TNUM_PORT >= 2
+CRE_SEM(SERIAL_RCV_SEM2, { TA_TPRI, 0, 1 });
+CRE_SEM(SERIAL_SND_SEM2, { TA_TPRI, 1, 1 });
+#endif /* TNUM_PORT >= 2 */
+#if TNUM_PORT >= 3
+CRE_SEM(SERIAL_RCV_SEM3, { TA_TPRI, 0, 1 });
+CRE_SEM(SERIAL_SND_SEM3, { TA_TPRI, 1, 1 });
+#endif /* TNUM_PORT >= 3 */
+#if TNUM_PORT >= 4
+CRE_SEM(SERIAL_RCV_SEM4, { TA_TPRI, 0, 1 });
+CRE_SEM(SERIAL_SND_SEM4, { TA_TPRI, 1, 1 });
+#endif /* TNUM_PORT >= 4 */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/syssvc/serial.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/syssvc/serial.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/syssvc/serial.h	(revision 457)
@@ -0,0 +1,98 @@
+/*
+ *  TOPPERS/ASP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Advanced Standard Profile Kernel
+ * 
+ *  Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
+ *                              Toyohashi Univ. of Technology, JAPAN
+ *  Copyright (C) 2004-2011 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *		シリアルインタフェースドライバ
+ */
+
+#ifndef TOPPERS_SERIAL_H
+#define TOPPERS_SERIAL_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ *  シリアルインタフェースドライバの用いるパケット
+ */
+typedef struct {
+	uint_t		reacnt;			/* 受信バッファ中の文字数 */
+	uint_t		wricnt;			/* 送信バッファ中の文字数 */
+} T_SERIAL_RPOR;
+
+/*
+ *  シリアルインタフェースドライバの初期化ルーチン
+ */
+extern void		serial_initialize(intptr_t exinf) throw();
+
+/*
+ *  シリアルインタフェースドライバからの未送信文字の取出し
+ */
+extern bool_t	serial_get_chr(ID portid, char *p_c) throw();
+
+/*
+ *  シリアルインタフェースドライバのサービスコール
+ */
+extern ER		serial_opn_por(ID portid) throw();
+extern ER		serial_cls_por(ID portid) throw();
+extern ER_UINT	serial_rea_dat(ID portid, char *buf, uint_t len) throw();
+extern ER_UINT	serial_wri_dat(ID portid, const char *buf, uint_t len) throw();
+extern ER		serial_ctl_por(ID portid, uint_t ioctl) throw();
+extern ER		serial_ref_por(ID portid, T_SERIAL_RPOR *pk_rpor) throw();
+
+/*
+ *  シリアルインタフェースドライバの動作制御用のための定数
+ *
+ *  以下の定数は，ビット毎に論理和をとって用いる．
+ */
+#define	IOCTL_NULL	0U			/* 指定なし */
+#define	IOCTL_ECHO	0x0001U		/* 受信した文字をエコーバック */
+#define	IOCTL_CRLF	0x0010U		/* LFを送信する前にCRを付加 */
+#define	IOCTL_FCSND	0x0100U		/* 送信に対してフロー制御を行う */
+#define	IOCTL_FCANY	0x0200U		/* どのような文字でも送信再開 */
+#define	IOCTL_FCRCV	0x0400U		/* 受信に対してフロー制御を行う */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* TOPPERS_SERIAL_H */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/syssvc/syslog.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/syssvc/syslog.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/syssvc/syslog.c	(revision 457)
@@ -0,0 +1,243 @@
+/*
+ *  TOPPERS/ASP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Advanced Standard Profile Kernel
+ * 
+ *  Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
+ *                              Toyohashi Univ. of Technology, JAPAN
+ *  Copyright (C) 2005-2015 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  $Id$
+ */
+
+/*
+ *		システムログ機能
+ */
+
+#include <sil.h>
+#undef TOPPERS_OMIT_SYSLOG
+#include <t_syslog.h>
+#include <log_output.h>
+#include "target_syssvc.h"
+#include "syslog.h"
+
+/*
+ *  トレースログマクロのデフォルト定義
+ */
+#ifndef LOG_SYSLOG_WRI_LOG_ENTER
+#define LOG_SYSLOG_WRI_LOG_ENTER(prio, p_syslog)
+#endif /* LOG_SYSLOG_WRI_LOG_ENTER */
+
+#ifndef LOG_SYSLOG_WRI_LOG_LEAVE
+#define LOG_SYSLOG_WRI_LOG_LEAVE(ercd)
+#endif /* LOG_SYSLOG_WRI_LOG_LEAVE */
+
+#ifndef LOG_SYSLOG_REA_LOG_ENTER
+#define LOG_SYSLOG_REA_LOG_ENTER(p_syslog)
+#endif /* LOG_SYSLOG_REA_LOG_ENTER */
+
+#ifndef LOG_SYSLOG_REA_LOG_LEAVE
+#define LOG_SYSLOG_REA_LOG_LEAVE(ercd, p_syslog)
+#endif /* LOG_SYSLOG_REA_LOG_LEAVE */
+
+#ifndef LOG_SYSLOG_MSK_LOG_ENTER
+#define LOG_SYSLOG_MSK_LOG_ENTER(logmask, lowmask)
+#endif /* LOG_SYSLOG_MSK_LOG_ENTER */
+
+#ifndef LOG_SYSLOG_MSK_LOG_LEAVE
+#define LOG_SYSLOG_MSK_LOG_LEAVE(ercd)
+#endif /* LOG_SYSLOG_MSK_LOG_LEAVE */
+
+#ifndef LOG_SYSLOG_REF_LOG_ENTER
+#define LOG_SYSLOG_REF_LOG_ENTER(pk_rlog)
+#endif /* LOG_SYSLOG_REF_LOG_ENTER */
+
+#ifndef LOG_SYSLOG_REF_LOG_LEAVE
+#define LOG_SYSLOG_REF_LOG_LEAVE(ercd, pk_rlog)
+#endif /* LOG_SYSLOG_REF_LOG_LEAVE */
+
+/*
+ *  現在のシステム時刻
+ *
+ *  ログ時刻を取り出すために，やむなく，カーネルの内部変数を参照してい
+ *  る．
+ */
+extern ulong_t	_kernel_current_time;
+
+/*
+ *  ログバッファとそれにアクセスするためのポインタ
+ */
+static SYSLOG	syslog_buffer[TCNT_SYSLOG_BUFFER];	/* ログバッファ */
+static uint_t	syslog_count;			/* ログバッファ中のログの数 */
+static uint_t	syslog_head;			/* 先頭のログの格納位置 */
+static uint_t	syslog_tail;			/* 次のログの格納位置 */
+static uint_t	syslog_lost;			/* 失われたログの数 */
+
+/*
+ *  出力すべきログ情報の重要度（ビットマップ）
+ */
+static uint_t	syslog_logmask;			/* ログバッファに記録すべき重要度 */
+static uint_t	syslog_lowmask_not;		/* 低レベル出力すべき重要度（反転）*/
+
+/*
+ *  システムログ機能の初期化
+ */
+void
+syslog_initialize(intptr_t exinf)
+{
+	syslog_count = 0U;
+	syslog_head = 0U;
+	syslog_tail = 0U;
+	syslog_lost = 0U;
+	syslog_logmask = 0U;
+	syslog_lowmask_not = 0U;
+}     
+
+/* 
+ *  ログ情報の出力
+ *
+ *  CPUロック状態や実行コンテキストによらず動作できるように実装してある．
+ */
+ER
+syslog_wri_log(uint_t prio, const SYSLOG *p_syslog)
+{
+	SIL_PRE_LOC;
+
+	LOG_SYSLOG_WRI_LOG_ENTER(prio, p_syslog);
+	SIL_LOC_INT();
+
+	/*
+	 *  ログ時刻の設定
+	 */
+	((SYSLOG *) p_syslog)->logtim = _kernel_current_time;
+
+	/*
+	 *  ログバッファに記録
+	 */
+	if ((syslog_logmask & LOG_MASK(prio)) != 0U) {
+		syslog_buffer[syslog_tail] = *p_syslog;
+		syslog_tail++;
+		if (syslog_tail >= TCNT_SYSLOG_BUFFER) {
+			syslog_tail = 0U;
+		}
+		if (syslog_count < TCNT_SYSLOG_BUFFER) {
+			syslog_count++;
+		}
+		else {
+			syslog_head = syslog_tail;
+			syslog_lost++;
+		}
+	}
+
+	/*
+	 *  低レベル出力
+	 */
+	if (((~syslog_lowmask_not) & LOG_MASK(prio)) != 0U) {
+		syslog_print(p_syslog, target_fput_log);
+		target_fput_log('\n');
+	}
+
+	SIL_UNL_INT();
+	LOG_SYSLOG_WRI_LOG_LEAVE(E_OK);
+	return(E_OK);
+}
+
+/*
+ *  ログバッファからの読出し
+ *
+ *  CPUロック状態や実行コンテキストによらず動作できるように実装してある．
+ */
+ER_UINT
+syslog_rea_log(SYSLOG *p_syslog)
+{
+	ER_UINT	ercd;
+	SIL_PRE_LOC;
+
+	LOG_SYSLOG_REA_LOG_ENTER(p_syslog);
+	SIL_LOC_INT();
+
+	/*
+	 *  ログバッファからの取出し
+	 */
+	if (syslog_count > 0U) {
+		*p_syslog = syslog_buffer[syslog_head];
+		syslog_count--;
+		syslog_head++;
+		if (syslog_head >= TCNT_SYSLOG_BUFFER) {
+			syslog_head = 0U;
+		}
+		ercd = (ER_UINT) syslog_lost;
+		syslog_lost = 0U;
+	}
+	else {
+		ercd = E_OBJ;
+	}
+
+	SIL_UNL_INT();
+	LOG_SYSLOG_REA_LOG_LEAVE(ercd, p_syslog);
+	return(ercd);
+}
+
+/* 
+ *  出力すべきログ情報の重要度の設定
+ */
+ER
+syslog_msk_log(uint_t logmask, uint_t lowmask)
+{
+	LOG_SYSLOG_MSK_LOG_ENTER(logmask, lowmask);
+	syslog_logmask = logmask;
+	syslog_lowmask_not = ~lowmask;
+	LOG_SYSLOG_MSK_LOG_LEAVE(E_OK);
+	return(E_OK);
+}
+
+/*
+ *  ログバッファの状態参照
+ */
+ER
+syslog_ref_log(T_SYSLOG_RLOG *pk_rlog)
+{
+	SIL_PRE_LOC;
+
+	LOG_SYSLOG_REF_LOG_ENTER(pk_rlog);
+	SIL_LOC_INT();
+
+	pk_rlog->count = syslog_count;
+	pk_rlog->lost = syslog_lost;
+	pk_rlog->logmask = syslog_logmask;
+	pk_rlog->lowmask = ~syslog_lowmask_not;
+
+	SIL_UNL_INT();
+	LOG_SYSLOG_REF_LOG_LEAVE(E_OK, pk_rlog);
+	return(E_OK);
+}
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/syssvc/syslog.cfg
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/syssvc/syslog.cfg	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/syssvc/syslog.cfg	(revision 457)
@@ -0,0 +1,10 @@
+/*
+ *  $Id$
+ */
+
+/*
+ *		システムログ機能のコンフィギュレーションファイル
+ */
+
+#include "syssvc/syslog.h"
+ATT_INI({ TA_NULL, 0, syslog_initialize });
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/syssvc/syslog.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/syssvc/syslog.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/syssvc/syslog.h	(revision 457)
@@ -0,0 +1,95 @@
+/*
+ *  TOPPERS/ASP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Advanced Standard Profile Kernel
+ * 
+ *  Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
+ *                              Toyohashi Univ. of Technology, JAPAN
+ *  Copyright (C) 2005-2008 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  $Id$
+ */
+
+/*
+ *		システムログ機能
+ */
+
+#ifndef TOPPERS_SYSLOG_H
+#define TOPPERS_SYSLOG_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ *  システムログ出力を行うための定義
+ */
+#include <t_syslog.h>
+
+/*
+ *  ログバッファとそれにアクセスするためのポインタ
+ */
+#ifndef TCNT_SYSLOG_BUFFER
+#define TCNT_SYSLOG_BUFFER	32		/* ログバッファのサイズ */
+#endif /* TCNT_SYSLOG_BUFFER */
+
+/*
+ *  システムログ機能の初期化
+ */
+extern void	syslog_initialize(intptr_t exinf) throw();
+
+/*
+ *  ログ情報の出力
+ */
+extern ER	syslog_wri_log(uint_t prio, const SYSLOG *p_syslog) throw();
+
+/*
+ *  ログバッファからのログ情報の読出し
+ */
+extern ER_UINT	syslog_rea_log(SYSLOG *p_syslog) throw();
+
+/* 
+ *  出力すべきログ情報の重要度の設定
+ */
+extern ER	syslog_msk_log(uint_t logmask, uint_t lowmask) throw();
+
+/* 
+ *  ログバッファの状態参照
+ */
+extern ER	syslog_ref_log(T_SYSLOG_RLOG *pk_rlog) throw();
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* TOPPERS_SYSLOG_H */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/syssvc/tlsf.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/syssvc/tlsf.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/syssvc/tlsf.c	(revision 457)
@@ -0,0 +1,1023 @@
+/* 
+ * Two Levels Segregate Fit memory allocator (TLSF)
+ * Version 2.4.6
+ *
+ * Written by Miguel Masmano Tello <mimastel@doctor.upv.es>
+ *
+ * Thanks to Ismael Ripoll for his suggestions and reviews
+ *
+ * Copyright (C) 2008, 2007, 2006, 2005, 2004
+ *
+ * This code is released using a dual license strategy: GPL/LGPL
+ * You can choose the licence that better fits your requirements.
+ *
+ * Released under the terms of the GNU General Public License Version 2.0
+ * Released under the terms of the GNU Lesser General Public License Version 2.1
+ *
+ */
+
+/*
+ * Code contributions:
+ *
+ * (Jul 28 2007)  Herman ten Brugge <hermantenbrugge@home.nl>:
+ *
+ * - Add 64 bit support. It now runs on x86_64 and solaris64.
+ * - I also tested this on vxworks/32and solaris/32 and i386/32 processors.
+ * - Remove assembly code. I could not measure any performance difference 
+ *   on my core2 processor. This also makes the code more portable.
+ * - Moved defines/typedefs from tlsf.h to tlsf.c
+ * - Changed MIN_BLOCK_SIZE to sizeof (free_ptr_t) and BHDR_OVERHEAD to 
+ *   (sizeof (bhdr_t) - MIN_BLOCK_SIZE). This does not change the fact 
+ *    that the minumum size is still sizeof 
+ *   (bhdr_t).
+ * - Changed all C++ comment style to C style. (// -> /.* ... *./)
+ * - Used ls_bit instead of ffs and ms_bit instead of fls. I did this to 
+ *   avoid confusion with the standard ffs function which returns 
+ *   different values.
+ * - Created set_bit/clear_bit fuctions because they are not present 
+ *   on x86_64.
+ * - Added locking support + extra file target.h to show how to use it.
+ * - Added get_used_size function (REMOVED in 2.4)
+ * - Added rtl_realloc and rtl_calloc function
+ * - Implemented realloc clever support.
+ * - Added some test code in the example directory.
+ * - Bug fixed (discovered by the rockbox project: www.rockbox.org).       
+ *
+ * (Oct 23 2006) Adam Scislowicz: 
+ *
+ * - Support for ARMv5 implemented
+ *
+ */
+
+/*#define USE_SBRK        (0) */
+/*#define USE_MMAP        (0) */
+
+#ifndef USE_PRINTF
+#define USE_PRINTF      (1)
+#endif
+
+#include <string.h>
+
+#ifndef TLSF_USE_LOCKS
+#define	TLSF_USE_LOCKS 	(0)
+#endif
+
+#ifndef TLSF_STATISTIC
+#define	TLSF_STATISTIC 	(0)
+#endif
+
+#ifndef USE_MMAP
+#define	USE_MMAP 	(0)
+#endif
+
+#ifndef USE_SBRK
+#define	USE_SBRK 	(0)
+#endif
+
+
+#if TLSF_USE_LOCKS
+#include "kernel.h"
+#include "kernel_cfg.h"
+#define TLSF_MLOCK_T ID
+#define TLSF_CREATE_LOCK(lock) (*lock = TLSF_SEM)
+#define TLSF_DESTROY_LOCK(lock) ini_sem(*lock)
+#define TLSF_ACQUIRE_LOCK(lock) wai_sem(*lock)
+#define TLSF_RELEASE_LOCK(lock) sig_sem(*lock)
+#else
+#define TLSF_CREATE_LOCK(_unused_)   do{}while(0)
+#define TLSF_DESTROY_LOCK(_unused_)  do{}while(0) 
+#define TLSF_ACQUIRE_LOCK(_unused_)  do{}while(0)
+#define TLSF_RELEASE_LOCK(_unused_)  do{}while(0)
+#endif
+
+#if TLSF_STATISTIC
+#define	TLSF_ADD_SIZE(tlsf, b) do {									\
+		tlsf->used_size += (b->size & BLOCK_SIZE) + BHDR_OVERHEAD;	\
+		if (tlsf->used_size > tlsf->max_size) 						\
+			tlsf->max_size = tlsf->used_size;						\
+		} while(0)
+
+#define	TLSF_REMOVE_SIZE(tlsf, b) do {								\
+		tlsf->used_size -= (b->size & BLOCK_SIZE) + BHDR_OVERHEAD;	\
+	} while(0)
+#else
+#define	TLSF_ADD_SIZE(tlsf, b)	     do{}while(0)
+#define	TLSF_REMOVE_SIZE(tlsf, b)    do{}while(0)
+#endif
+
+#if USE_MMAP || USE_SBRK
+#include <unistd.h>
+#endif
+
+#if USE_MMAP
+#include <sys/mman.h>
+#endif
+
+#include "tlsf.h"
+
+#if !defined(__GNUC__)
+#ifndef __inline__
+#define __inline__
+#endif
+#endif
+
+/* The  debug functions  only can  be used  when _DEBUG_TLSF_  is set. */
+#ifndef _DEBUG_TLSF_
+#define _DEBUG_TLSF_  (0)
+#endif
+
+/*************************************************************************/
+/* Definition of the structures used by TLSF */
+
+
+/* Some IMPORTANT TLSF parameters */
+/* Unlike the preview TLSF versions, now they are statics */
+#define BLOCK_ALIGN (sizeof(void *) * 2)
+
+#define MAX_FLI		(30)
+#define MAX_LOG2_SLI	(5)
+#define MAX_SLI		(1 << MAX_LOG2_SLI)     /* MAX_SLI = 2^MAX_LOG2_SLI */
+
+#define FLI_OFFSET	(6)     /* tlsf structure just will manage blocks bigger */
+/* than 128 bytes */
+#define SMALL_BLOCK	(128)
+#define REAL_FLI	(MAX_FLI - FLI_OFFSET)
+#define MIN_BLOCK_SIZE	(sizeof (free_ptr_t))
+#define BHDR_OVERHEAD	(sizeof (bhdr_t) - MIN_BLOCK_SIZE)
+#define TLSF_SIGNATURE	(0x2A59FA59)
+
+#define	PTR_MASK	(sizeof(void *) - 1)
+#define BLOCK_SIZE	(0xFFFFFFFF - PTR_MASK)
+
+#define GET_NEXT_BLOCK(_addr, _r) ((bhdr_t *) ((char *) (_addr) + (_r)))
+#define	MEM_ALIGN		  ((BLOCK_ALIGN) - 1)
+#define ROUNDUP_SIZE(_r)          (((_r) + MEM_ALIGN) & ~MEM_ALIGN)
+#define ROUNDDOWN_SIZE(_r)        ((_r) & ~MEM_ALIGN)
+#define ROUNDUP(_x, _v)           ((((~(_x)) + 1) & ((_v)-1)) + (_x))
+
+#define BLOCK_STATE	(0x1)
+#define PREV_STATE	(0x2)
+
+/* bit 0 of the block size */
+#define FREE_BLOCK	(0x1)
+#define USED_BLOCK	(0x0)
+
+/* bit 1 of the block size */
+#define PREV_FREE	(0x2)
+#define PREV_USED	(0x0)
+
+
+#define DEFAULT_AREA_SIZE (1024*10)
+
+#ifdef USE_MMAP
+#define PAGE_SIZE (getpagesize())
+#endif
+
+#ifdef USE_PRINTF
+#include <stdio.h>
+#include <t_stddef.h>
+#include <t_syslog.h>
+#define PRINT_MSG(fmt, args...) syslog(LOG_ERROR, fmt, ## args)
+#define ERROR_MSG(fmt, args...) syslog(LOG_ERROR, fmt, ## args)
+#else
+# if !defined(PRINT_MSG)
+#  define PRINT_MSG(fmt, args...)
+# endif
+# if !defined(ERROR_MSG)
+#  define ERROR_MSG(fmt, args...)
+# endif
+#endif
+
+typedef unsigned int u32_t;     /* NOTE: Make sure that this type is 4 bytes long on your computer */
+typedef unsigned char u8_t;     /* NOTE: Make sure that this type is 1 byte on your computer */
+
+typedef struct free_ptr_struct {
+    struct bhdr_struct *prev;
+    struct bhdr_struct *next;
+} free_ptr_t;
+
+typedef struct bhdr_struct {
+    /* This pointer is just valid if the first bit of size is set */
+    struct bhdr_struct *prev_hdr;
+    /* The size is stored in bytes */
+    size_t size;                /* bit 0 indicates whether the block is used and */
+    /* bit 1 allows to know whether the previous block is free */
+    union {
+        struct free_ptr_struct free_ptr;
+        u8_t buffer[1];         /*sizeof(struct free_ptr_struct)]; */
+    } ptr;
+} bhdr_t;
+
+/* This structure is embedded at the beginning of each area, giving us
+ * enough information to cope with a set of areas */
+
+typedef struct area_info_struct {
+    bhdr_t *end;
+    struct area_info_struct *next;
+} area_info_t;
+
+typedef struct TLSF_struct {
+    /* the TLSF's structure signature */
+    u32_t tlsf_signature;
+
+#if TLSF_USE_LOCKS
+    TLSF_MLOCK_T lock;
+#endif
+
+#if TLSF_STATISTIC
+    /* These can not be calculated outside tlsf because we
+     * do not know the sizes when freeing/reallocing memory. */
+    size_t used_size;
+    size_t max_size;
+#endif
+
+    /* A linked list holding all the existing areas */
+    area_info_t *area_head;
+
+    /* the first-level bitmap */
+    /* This array should have a size of REAL_FLI bits */
+    u32_t fl_bitmap;
+
+    /* the second-level bitmap */
+    u32_t sl_bitmap[REAL_FLI];
+
+    bhdr_t *matrix[REAL_FLI][MAX_SLI];
+} tlsf_t;
+
+
+/******************************************************************/
+/**************     Helping functions    **************************/
+/******************************************************************/
+static __inline__ void set_bit(int nr, u32_t * addr);
+static __inline__ void clear_bit(int nr, u32_t * addr);
+static __inline__ int ls_bit(int x);
+static __inline__ int ms_bit(int x);
+static __inline__ void MAPPING_SEARCH(size_t * _r, int *_fl, int *_sl);
+static __inline__ void MAPPING_INSERT(size_t _r, int *_fl, int *_sl);
+static __inline__ bhdr_t *FIND_SUITABLE_BLOCK(tlsf_t * _tlsf, int *_fl, int *_sl);
+static __inline__ bhdr_t *process_area(void *area, size_t size);
+#if USE_SBRK || USE_MMAP
+static __inline__ void *get_new_area(size_t * size);
+#endif
+
+static const int table[] = {
+    -1, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4,
+    4, 4,
+    4, 4, 4, 4, 4, 4, 4,
+    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+    5,
+    5, 5, 5, 5, 5, 5, 5,
+    6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+    6,
+    6, 6, 6, 6, 6, 6, 6,
+    6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+    6,
+    6, 6, 6, 6, 6, 6, 6,
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+    7,
+    7, 7, 7, 7, 7, 7, 7,
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+    7,
+    7, 7, 7, 7, 7, 7, 7,
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+    7,
+    7, 7, 7, 7, 7, 7, 7,
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+    7,
+    7, 7, 7, 7, 7, 7, 7
+};
+
+static __inline__ int ls_bit(int i)
+{
+    unsigned int a;
+    unsigned int x = i & -i;
+
+    a = x <= 0xffff ? (x <= 0xff ? 0 : 8) : (x <= 0xffffff ? 16 : 24);
+    return table[x >> a] + a;
+}
+
+static __inline__ int ms_bit(int i)
+{
+    unsigned int a;
+    unsigned int x = (unsigned int) i;
+
+    a = x <= 0xffff ? (x <= 0xff ? 0 : 8) : (x <= 0xffffff ? 16 : 24);
+    return table[x >> a] + a;
+}
+
+static __inline__ void set_bit(int nr, u32_t * addr)
+{
+    addr[nr >> 5] |= 1 << (nr & 0x1f);
+}
+
+static __inline__ void clear_bit(int nr, u32_t * addr)
+{
+    addr[nr >> 5] &= ~(1 << (nr & 0x1f));
+}
+
+static __inline__ void MAPPING_SEARCH(size_t * _r, int *_fl, int *_sl)
+{
+    int _t;
+
+    if (*_r < SMALL_BLOCK) {
+        *_fl = 0;
+        *_sl = *_r / (SMALL_BLOCK / MAX_SLI);
+    } else {
+        _t = (1 << (ms_bit(*_r) - MAX_LOG2_SLI)) - 1;
+        *_r = *_r + _t;
+        *_fl = ms_bit(*_r);
+        *_sl = (*_r >> (*_fl - MAX_LOG2_SLI)) - MAX_SLI;
+        *_fl -= FLI_OFFSET;
+        /*if ((*_fl -= FLI_OFFSET) < 0) // FL wil be always >0!
+         *_fl = *_sl = 0;
+         */
+        *_r &= ~_t;
+    }
+}
+
+static __inline__ void MAPPING_INSERT(size_t _r, int *_fl, int *_sl)
+{
+    if (_r < SMALL_BLOCK) {
+        *_fl = 0;
+        *_sl = _r / (SMALL_BLOCK / MAX_SLI);
+    } else {
+        *_fl = ms_bit(_r);
+        *_sl = (_r >> (*_fl - MAX_LOG2_SLI)) - MAX_SLI;
+        *_fl -= FLI_OFFSET;
+    }
+}
+
+
+static __inline__ bhdr_t *FIND_SUITABLE_BLOCK(tlsf_t * _tlsf, int *_fl, int *_sl)
+{
+    u32_t _tmp = _tlsf->sl_bitmap[*_fl] & (~0 << *_sl);
+    bhdr_t *_b = NULL;
+
+    if (_tmp) {
+        *_sl = ls_bit(_tmp);
+        _b = _tlsf->matrix[*_fl][*_sl];
+    } else {
+        *_fl = ls_bit(_tlsf->fl_bitmap & (~0 << (*_fl + 1)));
+        if (*_fl > 0) {         /* likely */
+            *_sl = ls_bit(_tlsf->sl_bitmap[*_fl]);
+            _b = _tlsf->matrix[*_fl][*_sl];
+        }
+    }
+    return _b;
+}
+
+
+#define EXTRACT_BLOCK_HDR(_b, _tlsf, _fl, _sl) do {					\
+		_tlsf -> matrix [_fl] [_sl] = _b -> ptr.free_ptr.next;		\
+		if (_tlsf -> matrix[_fl][_sl])								\
+			_tlsf -> matrix[_fl][_sl] -> ptr.free_ptr.prev = NULL;	\
+		else {														\
+			clear_bit (_sl, &_tlsf -> sl_bitmap [_fl]);				\
+			if (!_tlsf -> sl_bitmap [_fl])							\
+				clear_bit (_fl, &_tlsf -> fl_bitmap);				\
+		}															\
+		_b -> ptr.free_ptr.prev =  NULL;				\
+		_b -> ptr.free_ptr.next =  NULL;				\
+	}while(0)
+
+
+#define EXTRACT_BLOCK(_b, _tlsf, _fl, _sl) do {							\
+		if (_b -> ptr.free_ptr.next)									\
+			_b -> ptr.free_ptr.next -> ptr.free_ptr.prev = _b -> ptr.free_ptr.prev; \
+		if (_b -> ptr.free_ptr.prev)									\
+			_b -> ptr.free_ptr.prev -> ptr.free_ptr.next = _b -> ptr.free_ptr.next; \
+		if (_tlsf -> matrix [_fl][_sl] == _b) {							\
+			_tlsf -> matrix [_fl][_sl] = _b -> ptr.free_ptr.next;		\
+			if (!_tlsf -> matrix [_fl][_sl]) {							\
+				clear_bit (_sl, &_tlsf -> sl_bitmap[_fl]);				\
+				if (!_tlsf -> sl_bitmap [_fl])							\
+					clear_bit (_fl, &_tlsf -> fl_bitmap);				\
+			}															\
+		}																\
+		_b -> ptr.free_ptr.prev = NULL;					\
+		_b -> ptr.free_ptr.next = NULL;					\
+	} while(0)
+
+#define INSERT_BLOCK(_b, _tlsf, _fl, _sl) do {							\
+		_b -> ptr.free_ptr.prev = NULL; \
+		_b -> ptr.free_ptr.next = _tlsf -> matrix [_fl][_sl]; \
+		if (_tlsf -> matrix [_fl][_sl])									\
+			_tlsf -> matrix [_fl][_sl] -> ptr.free_ptr.prev = _b;		\
+		_tlsf -> matrix [_fl][_sl] = _b;								\
+		set_bit (_sl, &_tlsf -> sl_bitmap [_fl]);						\
+		set_bit (_fl, &_tlsf -> fl_bitmap);								\
+	} while(0)
+
+#if USE_SBRK || USE_MMAP
+static __inline__ void *get_new_area(size_t * size) 
+{
+    void *area;
+
+#if USE_SBRK
+    area = (void *)sbrk(0);
+    if (((void *)sbrk(*size)) != ((void *) -1))
+        return area;
+#endif
+
+#ifndef MAP_ANONYMOUS
+/* https://dev.openwrt.org/ticket/322 */
+# define MAP_ANONYMOUS MAP_ANON
+#endif
+
+
+#if USE_MMAP
+    *size = ROUNDUP(*size, PAGE_SIZE);
+    if ((area = mmap(0, *size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0)) != MAP_FAILED)
+        return area;
+#endif
+    return ((void *) ~0);
+}
+#endif
+
+static __inline__ bhdr_t *process_area(void *area, size_t size)
+{
+    bhdr_t *b, *lb, *ib;
+    area_info_t *ai;
+
+    ib = (bhdr_t *) area;
+    ib->size =
+        (sizeof(area_info_t) <
+         MIN_BLOCK_SIZE) ? MIN_BLOCK_SIZE : ROUNDUP_SIZE(sizeof(area_info_t)) | USED_BLOCK | PREV_USED;
+    b = (bhdr_t *) GET_NEXT_BLOCK(ib->ptr.buffer, ib->size & BLOCK_SIZE);
+    b->size = ROUNDDOWN_SIZE(size - 3 * BHDR_OVERHEAD - (ib->size & BLOCK_SIZE)) | USED_BLOCK | PREV_USED;
+    b->ptr.free_ptr.prev = b->ptr.free_ptr.next = 0;
+    lb = GET_NEXT_BLOCK(b->ptr.buffer, b->size & BLOCK_SIZE);
+    lb->prev_hdr = b;
+    lb->size = 0 | USED_BLOCK | PREV_FREE;
+    ai = (area_info_t *) ib->ptr.buffer;
+    ai->next = 0;
+    ai->end = lb;
+    return ib;
+}
+
+/******************************************************************/
+/******************** Begin of the allocator code *****************/
+/******************************************************************/
+
+static char *mp = NULL;         /* Default memory pool. */
+
+/******************************************************************/
+size_t init_memory_pool(size_t mem_pool_size, void *mem_pool)
+{
+/******************************************************************/
+    tlsf_t *tlsf;
+    bhdr_t *b, *ib;
+
+    if (!mem_pool || !mem_pool_size || mem_pool_size < sizeof(tlsf_t) + BHDR_OVERHEAD * 8) {
+        ERROR_MSG("init_memory_pool (): memory_pool invalid\n");
+        return -1;
+    }
+
+    if (((unsigned long) mem_pool & PTR_MASK)) {
+        ERROR_MSG("init_memory_pool (): mem_pool must be aligned to a word\n");
+        return -1;
+    }
+    tlsf = (tlsf_t *) mem_pool;
+    /* Check if already initialised */
+    if (tlsf->tlsf_signature == TLSF_SIGNATURE) {
+        mp = mem_pool;
+        b = GET_NEXT_BLOCK(mp, ROUNDUP_SIZE(sizeof(tlsf_t)));
+        return b->size & BLOCK_SIZE;
+    }
+
+    mp = mem_pool;
+
+    /* Zeroing the memory pool */
+    memset(mem_pool, 0, sizeof(tlsf_t));
+
+    tlsf->tlsf_signature = TLSF_SIGNATURE;
+
+    TLSF_CREATE_LOCK(&tlsf->lock);
+
+    ib = process_area(GET_NEXT_BLOCK
+                      (mem_pool, ROUNDUP_SIZE(sizeof(tlsf_t))), ROUNDDOWN_SIZE(mem_pool_size - sizeof(tlsf_t)));
+    b = GET_NEXT_BLOCK(ib->ptr.buffer, ib->size & BLOCK_SIZE);
+    free_ex(b->ptr.buffer, tlsf);
+    tlsf->area_head = (area_info_t *) ib->ptr.buffer;
+
+#if TLSF_STATISTIC
+    tlsf->used_size = mem_pool_size - (b->size & BLOCK_SIZE);
+    tlsf->max_size = tlsf->used_size;
+#endif
+
+    return (b->size & BLOCK_SIZE);
+}
+
+/******************************************************************/
+size_t add_new_area(void *area, size_t area_size, void *mem_pool)
+{
+/******************************************************************/
+    tlsf_t *tlsf = (tlsf_t *) mem_pool;
+    area_info_t *ptr, *ptr_prev, *ai;
+    bhdr_t *ib0, *b0, *lb0, *ib1, *b1, *lb1, *next_b;
+
+    memset(area, 0, area_size);
+    ptr = tlsf->area_head;
+    ptr_prev = 0;
+
+    ib0 = process_area(area, area_size);
+    b0 = GET_NEXT_BLOCK(ib0->ptr.buffer, ib0->size & BLOCK_SIZE);
+    lb0 = GET_NEXT_BLOCK(b0->ptr.buffer, b0->size & BLOCK_SIZE);
+
+    /* Before inserting the new area, we have to merge this area with the
+       already existing ones */
+
+    while (ptr) {
+        ib1 = (bhdr_t *) ((char *) ptr - BHDR_OVERHEAD);
+        b1 = GET_NEXT_BLOCK(ib1->ptr.buffer, ib1->size & BLOCK_SIZE);
+        lb1 = ptr->end;
+
+        /* Merging the new area with the next physically contigous one */
+        if ((unsigned long) ib1 == (unsigned long) lb0 + BHDR_OVERHEAD) {
+            if (tlsf->area_head == ptr) {
+                tlsf->area_head = ptr->next;
+                ptr = ptr->next;
+            } else {
+                ptr_prev->next = ptr->next;
+                ptr = ptr->next;
+            }
+
+            b0->size =
+                ROUNDDOWN_SIZE((b0->size & BLOCK_SIZE) +
+                               (ib1->size & BLOCK_SIZE) + 2 * BHDR_OVERHEAD) | USED_BLOCK | PREV_USED;
+
+            b1->prev_hdr = b0;
+            lb0 = lb1;
+
+            continue;
+        }
+
+        /* Merging the new area with the previous physically contigous
+           one */
+        if ((unsigned long) lb1->ptr.buffer == (unsigned long) ib0) {
+            if (tlsf->area_head == ptr) {
+                tlsf->area_head = ptr->next;
+                ptr = ptr->next;
+            } else {
+                ptr_prev->next = ptr->next;
+                ptr = ptr->next;
+            }
+
+            lb1->size =
+                ROUNDDOWN_SIZE((b0->size & BLOCK_SIZE) +
+                               (ib0->size & BLOCK_SIZE) + 2 * BHDR_OVERHEAD) | USED_BLOCK | (lb1->size & PREV_STATE);
+            next_b = GET_NEXT_BLOCK(lb1->ptr.buffer, lb1->size & BLOCK_SIZE);
+            next_b->prev_hdr = lb1;
+            b0 = lb1;
+            ib0 = ib1;
+
+            continue;
+        }
+        ptr_prev = ptr;
+        ptr = ptr->next;
+    }
+
+    /* Inserting the area in the list of linked areas */
+    ai = (area_info_t *) ib0->ptr.buffer;
+    ai->next = tlsf->area_head;
+    ai->end = lb0;
+    tlsf->area_head = ai;
+    free_ex(b0->ptr.buffer, mem_pool);
+    return (b0->size & BLOCK_SIZE);
+}
+
+
+/******************************************************************/
+size_t get_used_size(void *mem_pool)
+{
+/******************************************************************/
+#if TLSF_STATISTIC
+    return ((tlsf_t *) mem_pool)->used_size;
+#else
+    return 0;
+#endif
+}
+
+/******************************************************************/
+size_t get_max_size(void *mem_pool)
+{
+/******************************************************************/
+#if TLSF_STATISTIC
+    return ((tlsf_t *) mem_pool)->max_size;
+#else
+    return 0;
+#endif
+}
+
+/******************************************************************/
+void destroy_memory_pool(void *mem_pool)
+{
+/******************************************************************/
+    tlsf_t *tlsf = (tlsf_t *) mem_pool;
+
+    tlsf->tlsf_signature = 0;
+
+    TLSF_DESTROY_LOCK(&tlsf->lock);
+
+}
+
+
+/******************************************************************/
+void *tlsf_malloc(size_t size)
+{
+/******************************************************************/
+    void *ret;
+
+#if USE_MMAP || USE_SBRK
+    if (!mp) {
+        size_t area_size;
+        void *area;
+
+        area_size = sizeof(tlsf_t) + BHDR_OVERHEAD * 8; /* Just a safety constant */
+        area_size = (area_size > DEFAULT_AREA_SIZE) ? area_size : DEFAULT_AREA_SIZE;
+        area = get_new_area(&area_size);
+        if (area == ((void *) ~0))
+            return NULL;        /* Not enough system memory */
+        init_memory_pool(area_size, area);
+    }
+#endif
+
+    TLSF_ACQUIRE_LOCK(&((tlsf_t *)mp)->lock);
+
+    ret = malloc_ex(size, mp);
+
+    TLSF_RELEASE_LOCK(&((tlsf_t *)mp)->lock);
+
+    return ret;
+}
+
+/******************************************************************/
+void tlsf_free(void *ptr)
+{
+/******************************************************************/
+
+    TLSF_ACQUIRE_LOCK(&((tlsf_t *)mp)->lock);
+
+    free_ex(ptr, mp);
+
+    TLSF_RELEASE_LOCK(&((tlsf_t *)mp)->lock);
+
+}
+
+/******************************************************************/
+void *tlsf_realloc(void *ptr, size_t size)
+{
+/******************************************************************/
+    void *ret;
+
+#if USE_MMAP || USE_SBRK
+	if (!mp) {
+		return tlsf_malloc(size);
+	}
+#endif
+
+    TLSF_ACQUIRE_LOCK(&((tlsf_t *)mp)->lock);
+
+    ret = realloc_ex(ptr, size, mp);
+
+    TLSF_RELEASE_LOCK(&((tlsf_t *)mp)->lock);
+
+    return ret;
+}
+
+/******************************************************************/
+void *tlsf_calloc(size_t nelem, size_t elem_size)
+{
+/******************************************************************/
+    void *ret;
+
+    TLSF_ACQUIRE_LOCK(&((tlsf_t *)mp)->lock);
+
+    ret = calloc_ex(nelem, elem_size, mp);
+
+    TLSF_RELEASE_LOCK(&((tlsf_t *)mp)->lock);
+
+    return ret;
+}
+
+/******************************************************************/
+void *malloc_ex(size_t size, void *mem_pool)
+{
+/******************************************************************/
+    tlsf_t *tlsf = (tlsf_t *) mem_pool;
+    bhdr_t *b, *b2, *next_b;
+    int fl, sl;
+    size_t tmp_size;
+
+    size = (size < MIN_BLOCK_SIZE) ? MIN_BLOCK_SIZE : ROUNDUP_SIZE(size);
+
+    /* Rounding up the requested size and calculating fl and sl */
+    MAPPING_SEARCH(&size, &fl, &sl);
+
+    /* Searching a free block, recall that this function changes the values of fl and sl,
+       so they are not longer valid when the function fails */
+    b = FIND_SUITABLE_BLOCK(tlsf, &fl, &sl);
+#if USE_MMAP || USE_SBRK
+    if (!b) {
+        size_t area_size;
+        void *area;
+        /* Growing the pool size when needed */
+        area_size = size + BHDR_OVERHEAD * 8;   /* size plus enough room for the requered headers. */
+        area_size = (area_size > DEFAULT_AREA_SIZE) ? area_size : DEFAULT_AREA_SIZE;
+        area = get_new_area(&area_size);        /* Call sbrk or mmap */
+        if (area == ((void *) ~0))
+            return NULL;        /* Not enough system memory */
+        add_new_area(area, area_size, mem_pool);
+        /* Rounding up the requested size and calculating fl and sl */
+        MAPPING_SEARCH(&size, &fl, &sl);
+        /* Searching a free block */
+        b = FIND_SUITABLE_BLOCK(tlsf, &fl, &sl);
+    }
+#endif
+    if (!b)
+        return NULL;            /* Not found */
+
+    EXTRACT_BLOCK_HDR(b, tlsf, fl, sl);
+
+    /*-- found: */
+    next_b = GET_NEXT_BLOCK(b->ptr.buffer, b->size & BLOCK_SIZE);
+    /* Should the block be split? */
+    tmp_size = (b->size & BLOCK_SIZE) - size;
+    if (tmp_size >= sizeof(bhdr_t)) {
+        tmp_size -= BHDR_OVERHEAD;
+        b2 = GET_NEXT_BLOCK(b->ptr.buffer, size);
+        b2->size = tmp_size | FREE_BLOCK | PREV_USED;
+        next_b->prev_hdr = b2;
+        MAPPING_INSERT(tmp_size, &fl, &sl);
+        INSERT_BLOCK(b2, tlsf, fl, sl);
+
+        b->size = size | (b->size & PREV_STATE);
+    } else {
+        next_b->size &= (~PREV_FREE);
+        b->size &= (~FREE_BLOCK);       /* Now it's used */
+    }
+
+    TLSF_ADD_SIZE(tlsf, b);
+
+    return (void *) b->ptr.buffer;
+}
+
+/******************************************************************/
+void free_ex(void *ptr, void *mem_pool)
+{
+/******************************************************************/
+    tlsf_t *tlsf = (tlsf_t *) mem_pool;
+    bhdr_t *b, *tmp_b;
+    int fl = 0, sl = 0;
+
+    if (!ptr) {
+        return;
+    }
+    b = (bhdr_t *) ((char *) ptr - BHDR_OVERHEAD);
+    b->size |= FREE_BLOCK;
+
+    TLSF_REMOVE_SIZE(tlsf, b);
+
+    b->ptr.free_ptr.prev = NULL;
+    b->ptr.free_ptr.next = NULL;
+    tmp_b = GET_NEXT_BLOCK(b->ptr.buffer, b->size & BLOCK_SIZE);
+    if (tmp_b->size & FREE_BLOCK) {
+        MAPPING_INSERT(tmp_b->size & BLOCK_SIZE, &fl, &sl);
+        EXTRACT_BLOCK(tmp_b, tlsf, fl, sl);
+        b->size += (tmp_b->size & BLOCK_SIZE) + BHDR_OVERHEAD;
+    }
+    if (b->size & PREV_FREE) {
+        tmp_b = b->prev_hdr;
+        MAPPING_INSERT(tmp_b->size & BLOCK_SIZE, &fl, &sl);
+        EXTRACT_BLOCK(tmp_b, tlsf, fl, sl);
+        tmp_b->size += (b->size & BLOCK_SIZE) + BHDR_OVERHEAD;
+        b = tmp_b;
+    }
+    MAPPING_INSERT(b->size & BLOCK_SIZE, &fl, &sl);
+    INSERT_BLOCK(b, tlsf, fl, sl);
+
+    tmp_b = GET_NEXT_BLOCK(b->ptr.buffer, b->size & BLOCK_SIZE);
+    tmp_b->size |= PREV_FREE;
+    tmp_b->prev_hdr = b;
+}
+
+/******************************************************************/
+void *realloc_ex(void *ptr, size_t new_size, void *mem_pool)
+{
+/******************************************************************/
+    tlsf_t *tlsf = (tlsf_t *) mem_pool;
+    void *ptr_aux;
+    unsigned int cpsize;
+    bhdr_t *b, *tmp_b, *next_b;
+    int fl, sl;
+    size_t tmp_size;
+
+    if (!ptr) {
+        if (new_size)
+            return (void *) malloc_ex(new_size, mem_pool);
+        if (!new_size)
+            return NULL;
+    } else if (!new_size) {
+        free_ex(ptr, mem_pool);
+        return NULL;
+    }
+
+    b = (bhdr_t *) ((char *) ptr - BHDR_OVERHEAD);
+    next_b = GET_NEXT_BLOCK(b->ptr.buffer, b->size & BLOCK_SIZE);
+    new_size = (new_size < MIN_BLOCK_SIZE) ? MIN_BLOCK_SIZE : ROUNDUP_SIZE(new_size);
+    tmp_size = (b->size & BLOCK_SIZE);
+    if (new_size <= tmp_size) {
+	TLSF_REMOVE_SIZE(tlsf, b);
+        if (next_b->size & FREE_BLOCK) {
+            MAPPING_INSERT(next_b->size & BLOCK_SIZE, &fl, &sl);
+            EXTRACT_BLOCK(next_b, tlsf, fl, sl);
+            tmp_size += (next_b->size & BLOCK_SIZE) + BHDR_OVERHEAD;
+            next_b = GET_NEXT_BLOCK(next_b->ptr.buffer, next_b->size & BLOCK_SIZE);
+            /* We allways reenter this free block because tmp_size will
+               be greater then sizeof (bhdr_t) */
+        }
+        tmp_size -= new_size;
+        if (tmp_size >= sizeof(bhdr_t)) {
+            tmp_size -= BHDR_OVERHEAD;
+            tmp_b = GET_NEXT_BLOCK(b->ptr.buffer, new_size);
+            tmp_b->size = tmp_size | FREE_BLOCK | PREV_USED;
+            next_b->prev_hdr = tmp_b;
+            next_b->size |= PREV_FREE;
+            MAPPING_INSERT(tmp_size, &fl, &sl);
+            INSERT_BLOCK(tmp_b, tlsf, fl, sl);
+            b->size = new_size | (b->size & PREV_STATE);
+        }
+	TLSF_ADD_SIZE(tlsf, b);
+        return (void *) b->ptr.buffer;
+    }
+    if ((next_b->size & FREE_BLOCK)) {
+        if (new_size <= (tmp_size + (next_b->size & BLOCK_SIZE))) {
+			TLSF_REMOVE_SIZE(tlsf, b);
+            MAPPING_INSERT(next_b->size & BLOCK_SIZE, &fl, &sl);
+            EXTRACT_BLOCK(next_b, tlsf, fl, sl);
+            b->size += (next_b->size & BLOCK_SIZE) + BHDR_OVERHEAD;
+            next_b = GET_NEXT_BLOCK(b->ptr.buffer, b->size & BLOCK_SIZE);
+            next_b->prev_hdr = b;
+            next_b->size &= ~PREV_FREE;
+            tmp_size = (b->size & BLOCK_SIZE) - new_size;
+            if (tmp_size >= sizeof(bhdr_t)) {
+                tmp_size -= BHDR_OVERHEAD;
+                tmp_b = GET_NEXT_BLOCK(b->ptr.buffer, new_size);
+                tmp_b->size = tmp_size | FREE_BLOCK | PREV_USED;
+                next_b->prev_hdr = tmp_b;
+                next_b->size |= PREV_FREE;
+                MAPPING_INSERT(tmp_size, &fl, &sl);
+                INSERT_BLOCK(tmp_b, tlsf, fl, sl);
+                b->size = new_size | (b->size & PREV_STATE);
+            }
+			TLSF_ADD_SIZE(tlsf, b);
+            return (void *) b->ptr.buffer;
+        }
+    }
+
+    if (!(ptr_aux = malloc_ex(new_size, mem_pool))){
+        return NULL;
+    }      
+    
+    cpsize = ((b->size & BLOCK_SIZE) > new_size) ? new_size : (b->size & BLOCK_SIZE);
+
+    memcpy(ptr_aux, ptr, cpsize);
+
+    free_ex(ptr, mem_pool);
+    return ptr_aux;
+}
+
+
+/******************************************************************/
+void *calloc_ex(size_t nelem, size_t elem_size, void *mem_pool)
+{
+/******************************************************************/
+    void *ptr;
+
+    if (nelem <= 0 || elem_size <= 0)
+        return NULL;
+
+    if (!(ptr = malloc_ex(nelem * elem_size, mem_pool)))
+        return NULL;
+    memset(ptr, 0, nelem * elem_size);
+
+    return ptr;
+}
+
+
+
+#if _DEBUG_TLSF_
+
+/***************  DEBUG FUNCTIONS   **************/
+
+/* The following functions have been designed to ease the debugging of */
+/* the TLSF  structure.  For non-developing  purposes, it may  be they */
+/* haven't too much worth.  To enable them, _DEBUG_TLSF_ must be set.  */
+
+extern void dump_memory_region(unsigned char *mem_ptr, unsigned int size);
+extern void print_block(bhdr_t * b);
+extern void print_tlsf(tlsf_t * tlsf);
+void print_all_blocks(tlsf_t * tlsf);
+
+void dump_memory_region(unsigned char *mem_ptr, unsigned int size)
+{
+
+    unsigned long begin = (unsigned long) mem_ptr;
+    unsigned long end = (unsigned long) mem_ptr + size;
+    int column = 0;
+
+    begin >>= 2;
+    begin <<= 2;
+
+    end >>= 2;
+    end++;
+    end <<= 2;
+
+    PRINT_MSG("\nMemory region dumped: 0x%lx - 0x%lx\n\n", begin, end);
+
+    column = 0;
+    PRINT_MSG("0x%lx ", begin);
+
+    while (begin < end) {
+        if (((unsigned char *) begin)[0] == 0)
+            PRINT_MSG("00");
+        else
+            PRINT_MSG("%02x", ((unsigned char *) begin)[0]);
+        if (((unsigned char *) begin)[1] == 0)
+            PRINT_MSG("00 ");
+        else
+            PRINT_MSG("%02x ", ((unsigned char *) begin)[1]);
+        begin += 2;
+        column++;
+        if (column == 8) {
+            PRINT_MSG("\n0x%lx ", begin);
+            column = 0;
+        }
+
+    }
+    PRINT_MSG("\n\n");
+}
+
+void print_block(bhdr_t * b)
+{
+    if (!b)
+        return;
+    PRINT_MSG(">> [%p] (", b);
+    if ((b->size & BLOCK_SIZE))
+        PRINT_MSG("%lu bytes, ", (unsigned long) (b->size & BLOCK_SIZE));
+    else
+        PRINT_MSG("sentinel, ");
+    if ((b->size & BLOCK_STATE) == FREE_BLOCK)
+        PRINT_MSG("free [%p, %p], ", b->ptr.free_ptr.prev, b->ptr.free_ptr.next);
+    else
+        PRINT_MSG("used, ");
+    if ((b->size & PREV_STATE) == PREV_FREE)
+        PRINT_MSG("prev. free [%p])\n", b->prev_hdr);
+    else
+        PRINT_MSG("prev used)\n");
+}
+
+void print_tlsf(tlsf_t * tlsf)
+{
+    bhdr_t *next;
+    int i, j;
+
+    PRINT_MSG("\nTLSF at %p\n", tlsf);
+
+    PRINT_MSG("FL bitmap: 0x%x\n\n", (unsigned) tlsf->fl_bitmap);
+
+    for (i = 0; i < REAL_FLI; i++) {
+        if (tlsf->sl_bitmap[i])
+            PRINT_MSG("SL bitmap 0x%x\n", (unsigned) tlsf->sl_bitmap[i]);
+        for (j = 0; j < MAX_SLI; j++) {
+            next = tlsf->matrix[i][j];
+            if (next)
+                PRINT_MSG("-> [%d][%d]\n", i, j);
+            while (next) {
+                print_block(next);
+                next = next->ptr.free_ptr.next;
+            }
+        }
+    }
+}
+
+void print_all_blocks(tlsf_t * tlsf)
+{
+    area_info_t *ai;
+    bhdr_t *next;
+    PRINT_MSG("\nTLSF at %p\nALL BLOCKS\n\n", tlsf);
+    ai = tlsf->area_head;
+    while (ai) {
+        next = (bhdr_t *) ((char *) ai - BHDR_OVERHEAD);
+        while (next) {
+            print_block(next);
+            if ((next->size & BLOCK_SIZE))
+                next = GET_NEXT_BLOCK(next->ptr.buffer, next->size & BLOCK_SIZE);
+            else
+                next = NULL;
+        }
+        ai = ai->next;
+    }
+}
+
+#endif
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/syssvc/tlsf.cfg
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/syssvc/tlsf.cfg	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/syssvc/tlsf.cfg	(revision 457)
@@ -0,0 +1,5 @@
+/*
+ *  $Id$
+ */
+CRE_SEM(TLSF_SEM, { TA_NULL, 1, 1 });
+
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/syssvc/tlsf.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/syssvc/tlsf.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/syssvc/tlsf.h	(revision 457)
@@ -0,0 +1,39 @@
+/*
+ * Two Levels Segregate Fit memory allocator (TLSF)
+ * Version 2.4.6
+ *
+ * Written by Miguel Masmano Tello <mimastel@doctor.upv.es>
+ *
+ * Thanks to Ismael Ripoll for his suggestions and reviews
+ *
+ * Copyright (C) 2008, 2007, 2006, 2005, 2004
+ *
+ * This code is released using a dual license strategy: GPL/LGPL
+ * You can choose the licence that better fits your requirements.
+ *
+ * Released under the terms of the GNU General Public License Version 2.0
+ * Released under the terms of the GNU Lesser General Public License Version 2.1
+ *
+ */
+
+#ifndef _TLSF_H_
+#define _TLSF_H_
+
+//#include <sys/types.h>
+
+extern size_t init_memory_pool(size_t, void *);
+extern size_t get_used_size(void *);
+extern size_t get_max_size(void *);
+extern void destroy_memory_pool(void *);
+extern size_t add_new_area(void *, size_t, void *);
+extern void *malloc_ex(size_t, void *);
+extern void free_ex(void *, void *);
+extern void *realloc_ex(void *, size_t, void *);
+extern void *calloc_ex(size_t, size_t, void *);
+
+extern void *tlsf_malloc(size_t size);
+extern void tlsf_free(void *ptr);
+extern void *tlsf_realloc(void *ptr, size_t size);
+extern void *tlsf_calloc(size_t nelem, size_t elem_size);
+
+#endif
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/target/stm32f767nucleo144_gcc/E_PACKAGE
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/target/stm32f767nucleo144_gcc/E_PACKAGE	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/target/stm32f767nucleo144_gcc/E_PACKAGE	(revision 457)
@@ -0,0 +1,8 @@
+E_PACKAGE asp_stm32f767nucleo144_gcc
+VERSION %date
+
+INCLUDE MANIFEST
+INCLUDE ../../MANIFEST
+INCLUDE ../../arch/arm_m_gcc/MANIFEST
+INCLUDE ../../cfg/MANIFEST
+../../cfg/cfg/cfg.exe
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/target/stm32f767nucleo144_gcc/MANIFEST
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/target/stm32f767nucleo144_gcc/MANIFEST	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/target/stm32f767nucleo144_gcc/MANIFEST	(revision 457)
@@ -0,0 +1,26 @@
+PACKAGE asp_arch_arm_m_gcc
+
+E_PACKAGE
+Makefile.target
+MANIFEST
+stm32f7xx_ram.ld
+stm32f7xx_rom.ld
+target.tf
+target_asm.inc
+target_cfg1_out.h
+target_check.tf
+target_config.h
+target_kernel.h
+target_offset.tf
+target_rename.def
+target_rename.h
+target_serial.cfg
+target_serial.h
+target_sil.h
+target_stddef.h
+target_syssvc.h
+target_test.h
+target_timer.cfg
+target_timer.h
+target_unrename.h
+target_user.txt
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/target/stm32f767nucleo144_gcc/Makefile.target
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/target/stm32f767nucleo144_gcc/Makefile.target	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/target/stm32f767nucleo144_gcc/Makefile.target	(revision 457)
@@ -0,0 +1,131 @@
+#
+#		Makefile のターゲット依存部（stm32f767_nucleo144用）
+#
+
+#
+#  ボード名，プロセッサ名，開発環境名の定義
+#
+BOARD = stm32f767nucleo144_gcc
+CHIP  = stm32f7xx
+PRC   = arm_m
+TOOL  = gcc
+
+#
+#  実行環境の定義
+#
+ifeq ($(DBGENV),)
+DBGENV = RAM
+endif
+
+#
+#  FPUの方式
+#
+#FPU_USAGE := FPU_NO_PRESERV
+#FPU_USAGE := FPU_NO_LAZYSTACKING
+FPU_USAGE := FPU_LAZYSTACKING
+FPU_ARCH_MACRO := __TARGET_FPU_FPV5_DP
+FPU_ABI := hard
+
+#
+#  最適化したくない場合はtrueに定義
+#
+#OMIT_OPTIMIZATION = true
+
+#
+#  コンパイルオプション
+#
+INCLUDES := $(INCLUDES) -I$(TARGETDIR)
+COPTS := $(COPTS) 
+LDFLAGS := $(LDFLAGS)
+
+#
+#  カーネルに関する定義
+#
+KERNEL_DIR := $(KERNEL_DIR) $(TARGETDIR)
+KERNEL_ASMOBJS := $(KERNEL_ASMOBJS)
+KERNEL_COBJS := $(KERNEL_COBJS)
+
+#
+#  システムサービスに関する定義
+#
+SYSSVC_DIR := $(SYSSVC_DIR) $(TARGETDIR)
+SYSSVC_COBJS := $(SYSSVC_COBJS) target_inithook.o
+
+#
+#  トレースログに関する設定
+#
+ifeq ($(ENABLE_TRACE),true)
+      COPTS := $(COPTS) -DTOPPERS_ENABLE_TRACE
+      KERNEL_DIR := $(KERNEL_DIR) $(SRCDIR)/arch/logtrace
+      KERNEL_COBJS := $(KERNEL_COBJS) trace_config.o trace_dump.o
+endif
+
+#
+#  GNU開発環境のターゲットアーキテクチャの定義
+#
+GCC_TARGET = arm-none-eabi
+
+#
+#  シリアルポートの定義
+#
+COPTS := $(COPTS) -DSIO_PORTID=1
+
+#
+#  依存関係の定義
+#
+kernel_cfg.timestamp: $(TARGETDIR)/target.tf
+$(OBJFILE): $(TARGETDIR)/target_check.tf
+
+# 
+#  オフセットファイル生成のための定義 
+# 
+OFFSET_TF := $(TARGETDIR)/target_offset.tf
+
+#
+#  チップ依存部のインクルード
+#
+include $(SRCDIR)/arch/$(PRC)_$(TOOL)/$(CHIP)/Makefile.chip
+
+#
+#  フラッシュへの書き込み
+#
+UNAME_TARGET = Cygwin
+OPENOCD_PATH = /cygdrive/c/pleiades/OpenOCD/0.10.0-201510281129-dev/bin/openocd.exe
+OPENOCD_SCRIPT_PATH = c:/pleiades/OpenOCD/0.10.0-201510281129-dev/scripts
+OPENOCD_SCRIPT  = c:/pleiades/OpenOCD/0.10.0-201510281129-dev/scripts/board/stm32f4discovery.cfg
+
+ifeq ($(UNAME_TARGET), Cygwin)
+	GDB = arm-gdb_m0.exe
+else
+	GDB = $(ARDUINO_BASE_DIR_WIN)\hardware\tools\gcc-arm-none-eabi-4.8.3-2014q1\bin\arm-none-eabi-gdb
+endif
+
+run: $(OBJNAME).bin
+ifeq ($(UNAME_TARGET), Cygwin)
+	"`cygpath -u "$(OPENOCD_PATH)"`" -s "$(OPENOCD_SCRIPT_PATH)" -f "$(OPENOCD_SCRIPT)" -c "program ./$(OBJNAME).bin verify 0x08000000 reset exit"
+#-c "flash probe 0; flash write_image erase ./$(OBJNAME).axf 0x08000000 reset exit"
+else
+	"$(OPENOCD_PATH)" -s "$(OPENOCD_SCRIPT_PATH)" -f "$(OPENOCD_SCRIPT)" -c "program ./$(OBJNAME).bin verify 0x4000 reset exit"
+endif
+
+ocd: $(OBJNAME).bin
+ifeq ($(UNAME_TARGET), Cygwin)
+	cygstart "$(OPENOCD_PATH)" '-s "$(OPENOCD_SCRIPT_PATH)"' '-f "$(OPENOCD_SCRIPT)"'
+else
+	start /MIN "" "$(OPENOCD_PATH)" -s "$(OPENOCD_SCRIPT_PATH)" -f "$(OPENOCD_SCRIPT)"
+endif
+
+db: $(OBJNAME).bin
+ifeq ($(UNAME_TARGET), Cygwin)
+	$(GDB) $(OBJFILE) -x $(TARGETDIR)/gdb.ini
+else
+	$(GDB) $(OBJFILE) -x $(TARGETDIR)/gdb.ini
+endif
+
+d: $(OBJNAME).bin
+ifeq ($(UNAME_TARGET), Cygwin)
+	$(GDB) $(OBJFILE) -x $(TARGETDIR)/gdb_noflash.ini
+else
+
+endif
+
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/target/stm32f767nucleo144_gcc/gdb.ini
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/target/stm32f767nucleo144_gcc/gdb.ini	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/target/stm32f767nucleo144_gcc/gdb.ini	(revision 457)
@@ -0,0 +1,4 @@
+target remote localhost:3333
+monitor program ./asp.bin verify 0x08000000
+monitor reset halt
+monitor reset init
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/target/stm32f767nucleo144_gcc/stm32f7xx_ram.ld
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/target/stm32f767nucleo144_gcc/stm32f7xx_ram.ld	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/target/stm32f767nucleo144_gcc/stm32f7xx_ram.ld	(revision 457)
@@ -0,0 +1,91 @@
+MEMORY
+{
+    ROM (rx) : ORIGIN = 0x08000000, LENGTH = 2048K
+    RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 512K
+}
+
+OUTPUT_FORMAT("elf32-littlearm", "elf32-bigarm","elf32-littlearm") 
+OUTPUT_ARCH(arm)
+
+PROVIDE(hardware_init_hook = 0);
+PROVIDE(software_init_hook = 0);
+PROVIDE(software_term_hook = 0);
+STARTUP(start.o)
+ENTRY(_kernel__start)
+
+SECTIONS
+{
+    .text :
+    {  
+        __text = . ; 
+        KEEP(*(.vector))
+	    . = ALIGN(16);
+        *(.text*)
+        *(.glue_7t)
+        *(.glue_7)
+    } > RAM
+    _etext = .	;
+    PROVIDE (etext = .)	;
+
+    .rodata : { 
+        *(.rodata*) 
+    } > RAM
+
+    . = ALIGN(4);
+    .data   :  AT(__idata_start) 
+    {
+        __data_start = . ;
+        *(vtable)
+        *(.data*)
+    } > RAM
+    __idata_start = __data_start ;
+    __idata_end = __idata_start + SIZEOF(.data);
+    _edata  =  . ;
+    PROVIDE (edata = .);
+    . = ALIGN(4);
+
+    .bss       :
+    {
+       __bss_start = .	;
+      *(.bss*)
+      *(COMMON)
+      . = ALIGN(32 / 8);
+    } > RAM
+   . = ALIGN(32 / 8);
+     _end = .		;
+    __bss_end = .;
+    PROVIDE (end = .)	;
+
+    .comment 0 : { *(.comment) }
+
+  /* DWARF debug sections.
+     Symbols in the DWARF debugging sections are relative to 
+     the beginning of the section so we begin them at 0.  */
+
+  /* DWARF 1 */
+  .debug          0 : { *(.debug) }
+  .line           0 : { *(.line) }
+
+  /* GNU DWARF 1 extensions */
+  .debug_srcinfo  0 : { *(.debug_srcinfo) }
+  .debug_sfnames  0 : { *(.debug_sfnames) }
+
+  /* DWARF 1.1 and DWARF 2 */
+  .debug_aranges  0 : { *(.debug_aranges) }
+  .debug_pubnames 0 : { *(.debug_pubnames) }
+
+  /* DWARF 2 */
+  .debug_info     0 : { *(.debug_info) }
+  .debug_abbrev   0 : { *(.debug_abbrev) }
+  .debug_line     0 : { *(.debug_line) }
+  .debug_frame    0 : { *(.debug_frame) }
+  .debug_str      0 : { *(.debug_str) }
+  .debug_loc      0 : { *(.debug_loc) }
+  .debug_macinfo  0 : { *(.debug_macinfo) }
+
+  /* SGI/MIPS DWARF 2 extensions */
+  .debug_weaknames 0 : { *(.debug_weaknames) }
+  .debug_funcnames 0 : { *(.debug_funcnames) }
+  .debug_typenames 0 : { *(.debug_typenames) }
+  .debug_varnames  0 : { *(.debug_varnames) }
+}
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/target/stm32f767nucleo144_gcc/stm32f7xx_rom.ld
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/target/stm32f767nucleo144_gcc/stm32f7xx_rom.ld	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/target/stm32f767nucleo144_gcc/stm32f7xx_rom.ld	(revision 457)
@@ -0,0 +1,92 @@
+MEMORY
+{
+    ROM (rx) : ORIGIN = 0x08000000, LENGTH = 2048K
+    RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 480K
+	ETH_RAM(rwx) : ORIGIN = 0x20078000, LENGTH = 32K
+}
+
+OUTPUT_FORMAT("elf32-littlearm", "elf32-bigarm","elf32-littlearm") 
+OUTPUT_ARCH(arm)
+
+PROVIDE(hardware_init_hook = 0);
+PROVIDE(software_init_hook = 0);
+PROVIDE(software_term_hook = 0);
+STARTUP(start.o)
+
+SECTIONS
+{
+    .text :
+    {
+        __text = . ; 
+        *(.vector)
+	    . = ALIGN(16);
+        *(.text*)
+        *(.glue_7t)
+        *(.glue_7)
+    } > ROM
+    _etext = .	;
+    PROVIDE (etext = .)	;
+
+    .rodata : { 
+        *(.rodata*) 
+    } > ROM
+
+    . = ALIGN(4);
+    __idata_start = . ;
+    .data   :  AT(__idata_start) 
+    {
+        __data_start = . ;
+        *(vtable)
+        *(.data*)
+    } > RAM
+    __idata_end = __idata_start + SIZEOF(.data);
+    _edata  =  . ;
+    PROVIDE (edata = .);
+    . = ALIGN(4);
+
+    .bss       :
+    {
+       __bss_start = .	;
+      *(.bss*)
+      *(COMMON)
+      . = ALIGN(32 / 8);
+    } > RAM
+   . = ALIGN(32 / 8);
+     _end = .		;
+    __bss_end = .;
+    PROVIDE (end = .)	;
+
+    .ethDataSection (NOLOAD) : { *(.ethDataSection) } > ETH_RAM
+    .comment 0 : { *(.comment) }
+
+  /* DWARF debug sections.
+     Symbols in the DWARF debugging sections are relative to 
+     the beginning of the section so we begin them at 0.  */
+
+  /* DWARF 1 */
+  .debug          0 : { *(.debug) }
+  .line           0 : { *(.line) }
+
+  /* GNU DWARF 1 extensions */
+  .debug_srcinfo  0 : { *(.debug_srcinfo) }
+  .debug_sfnames  0 : { *(.debug_sfnames) }
+
+  /* DWARF 1.1 and DWARF 2 */
+  .debug_aranges  0 : { *(.debug_aranges) }
+  .debug_pubnames 0 : { *(.debug_pubnames) }
+
+  /* DWARF 2 */
+  .debug_info     0 : { *(.debug_info) }
+  .debug_abbrev   0 : { *(.debug_abbrev) }
+  .debug_line     0 : { *(.debug_line) }
+  .debug_frame    0 : { *(.debug_frame) }
+  .debug_str      0 : { *(.debug_str) }
+  .debug_loc      0 : { *(.debug_loc) }
+  .debug_macinfo  0 : { *(.debug_macinfo) }
+
+  /* SGI/MIPS DWARF 2 extensions */
+  .debug_weaknames 0 : { *(.debug_weaknames) }
+  .debug_funcnames 0 : { *(.debug_funcnames) }
+  .debug_typenames 0 : { *(.debug_typenames) }
+  .debug_varnames  0 : { *(.debug_varnames) }
+}
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/target/stm32f767nucleo144_gcc/target.tf
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/target/stm32f767nucleo144_gcc/target.tf	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/target/stm32f767nucleo144_gcc/target.tf	(revision 457)
@@ -0,0 +1,8 @@
+$ 
+$     パス2のターゲット依存テンプレート（stm32f767_nucleo144用）
+$ 
+
+$ 
+$  コア依存テンプレートのインクルード
+$ 
+$INCLUDE"arm_m_gcc/common/core.tf"$
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/target/stm32f767nucleo144_gcc/target_asm.inc
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/target/stm32f767nucleo144_gcc/target_asm.inc	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/target/stm32f767nucleo144_gcc/target_asm.inc	(revision 457)
@@ -0,0 +1,1 @@
+#include "arm_m_gcc/common/core_asm.inc"
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/target/stm32f767nucleo144_gcc/target_cfg1_out.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/target/stm32f767nucleo144_gcc/target_cfg1_out.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/target/stm32f767nucleo144_gcc/target_cfg1_out.h	(revision 457)
@@ -0,0 +1,10 @@
+/*
+ *		cfg1_out.cをリンクするために必要なスタブの定義
+ */
+
+STK_T *const	_kernel_istkpt = 0x00;
+
+/*
+ *  コア依存のスタブの定義 
+ */
+#include <core_cfg1_out.h>
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/target/stm32f767nucleo144_gcc/target_check.tf
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/target/stm32f767nucleo144_gcc/target_check.tf	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/target/stm32f767nucleo144_gcc/target_check.tf	(revision 457)
@@ -0,0 +1,8 @@
+$ 
+$     パス3のターゲット依存テンプレート（stm32f767_nucleo144用）
+$ 
+
+$ 
+$  パス3のコア依存のテンプレートのインクルード
+$ 
+$INCLUDE"arm_m_gcc/common/core_check.tf"$
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/target/stm32f767nucleo144_gcc/target_config.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/target/stm32f767nucleo144_gcc/target_config.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/target/stm32f767nucleo144_gcc/target_config.h	(revision 457)
@@ -0,0 +1,77 @@
+/*
+ *  TOPPERS/ASP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Advanced Standard Profile Kernel
+ * 
+ *  Copyright (C) 2008-2011 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ *  Copyright (C) 2015-2016 by 3rd Designing Center
+ *              Imageing System Development Division RICOH COMPANY, LTD.
+ *  Copyright (C) 2017-2017 by TOPPERS PROJECT Educational Working Group.
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *  チップ依存モジュール（stm32f767-nucleo144用）
+ *
+ *  カーネルのターゲット依存部のインクルードファイル．kernel_impl.hのター
+ *  ゲット依存部の位置付けとなる．
+ */
+
+#ifndef TOPPERS_TARGET_CONFIG_H
+#define TOPPERS_TARGET_CONFIG_H
+
+/*
+ *  ターゲット依存部のハードウェア資源の定義
+ */
+#include "stm32f7xx.h"
+
+/*
+ *  微少時間待ちのための定義（本来はSILのターゲット依存部）
+ */
+#define SIL_DLY_TIM1    100
+#define SIL_DLY_TIM2    9
+
+/*
+ *  トレースログに関する設定
+ */
+#ifdef TOPPERS_ENABLE_TRACE
+#include "logtrace/trace_config.h"
+#endif /* TOPPERS_ENABLE_TRACE */
+
+/*
+ *  チップ依存モジュール（stm32f7xx用）
+ */
+#include "arm_m_gcc/stm32f7xx/chip_config.h"
+
+#endif /* TOPPERS_TARGET_CONFIG_H */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/target/stm32f767nucleo144_gcc/target_inithook.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/target/stm32f767nucleo144_gcc/target_inithook.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/target/stm32f767nucleo144_gcc/target_inithook.c	(revision 457)
@@ -0,0 +1,581 @@
+/*
+ *  TOPPERS/ASP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Advanced Standard Profile Kernel
+ * 
+ *  Copyright (C) 2008-2011 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ *  Copyright (C) 2015-2016 by 3rd Designing Center
+ *              Imageing System Development Division RICOH COMPANY, LTD.
+ *  Copyright (C) 2017-2019 by TOPPERS PROJECT Educational Working Group.
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+#include <sil.h>
+#include "target_syssvc.h"
+
+/*
+ *  初期化プログラム（stm32f767-nucleo144用）
+ */
+
+#define PLL_M      (HSE_VALUE / 1000000)/* Possible value 0 and 63 */
+#define PLL_N      432
+#define PLL_Q      9
+#define PLL_R      7
+
+/*
+ *  TIMEOUT VALUES
+ */
+#define CLOCKSWITCH_TIMEOUT_VALUE      (5000*1000)		/* 5秒 */
+#define HSE_TIMEOUT_VALUE              (5000*1000)		/* 5秒 */
+#define PLL_TIMEOUT_VALUE              (100*1000)		/* 100 ms */
+#define PLLSAI_TIMEOUT_VALUE           (100*1000)		/* 100 ms  */
+#define PWR_OVERDRIVE_TIMEOUT_VALUE    (1000*1000)		/* 1秒 */
+
+/*
+ *  RCC_PLLP_Clock_Divider PLLP Clock Divider
+ */
+#define RCC_PLLP_DIV2                   0x00000002
+#define RCC_PLLP_DIV4                   0x00000004
+#define RCC_PLLP_DIV6                   0x00000006
+#define RCC_PLLP_DIV8                   0x00000008
+
+/*
+ *  RCC_APB1_APB2_Clock_Source RCC APB1/APB2 Clock Source
+ */
+#define RCC_HCLK_DIV1                   RCC_CFGR_PPRE1_DIV1
+#define RCC_HCLK_DIV2                   RCC_CFGR_PPRE1_DIV2
+#define RCC_HCLK_DIV4                   RCC_CFGR_PPRE1_DIV4
+#define RCC_HCLK_DIV8                   RCC_CFGR_PPRE1_DIV8
+#define RCC_HCLK_DIV16                  RCC_CFGR_PPRE1_DIV16
+
+/*
+ *  RCC_AHB_Clock_Source RCC AHB Clock Source
+ */
+#define RCC_SYSCLK_DIV1                 RCC_CFGR_HPRE_DIV1
+#define RCC_SYSCLK_DIV2                 RCC_CFGR_HPRE_DIV2
+#define RCC_SYSCLK_DIV4                 RCC_CFGR_HPRE_DIV4
+#define RCC_SYSCLK_DIV8                 RCC_CFGR_HPRE_DIV8
+#define RCC_SYSCLK_DIV16                RCC_CFGR_HPRE_DIV16
+#define RCC_SYSCLK_DIV64                RCC_CFGR_HPRE_DIV64
+#define RCC_SYSCLK_DIV128               RCC_CFGR_HPRE_DIV128
+#define RCC_SYSCLK_DIV256               RCC_CFGR_HPRE_DIV256
+#define RCC_SYSCLK_DIV512               RCC_CFGR_HPRE_DIV512
+
+#define RCC_CLK48SOURCE_PLL              0x00000000
+#define RCC_CLK48SOURCE_PLLSAIP          RCC_DCKCFGR2_CK48MSEL
+
+#define RCC_PLLSAIP_DIV8                 0x00000003
+
+/*
+ *  CORTEX MPU領域許可禁止
+ */
+#define MPU_REGION_ENABLE               0x01
+#define MPU_REGION_DISABLE              0x00
+
+/*
+ *  CORTEX MPU インストラクションアクセス許可禁止
+ */
+#define MPU_INSTRUCTION_ACCESS_ENABLE   0x00
+#define MPU_INSTRUCTION_ACCESS_DISABLE  0x01
+
+/*
+ *  CORTEX MPU インストラクションアクセスキャッシュ設定
+ */
+#define MPU_ACCESS_CACHEABLE            0x01
+#define MPU_ACCESS_NOT_CACHEABLE        0x00
+
+/*
+ *  CORTEX MPU インストラクションアクセスバッファ設定
+ */
+#define MPU_ACCESS_BUFFERABLE           0x01
+#define MPU_ACCESS_NOT_BUFFERABLE       0x00
+
+/*
+ *  CORTEX MPU インストラクションアクセス共有設定
+ */
+#define MPU_ACCESS_SHAREABLE            0x01
+#define MPU_ACCESS_NOT_SHAREABLE        0x00
+
+/*
+ *  GPIOアウトプット設定パラメータ
+ */
+#define GPIO_OTYPE_PP       0x0
+#define GPIO_OTYPE_OD       0x1
+
+/*
+ *  GPIOプルアップダウンパラメータ
+ */
+#define GPIO_NOPULL         0x00000000	/* No Pull-up or Pull-down activation  */
+#define GPIO_PULLUP         0x00000001	/* Pull-up activation                  */
+#define GPIO_PULLDOWN       0x00000002	/* Pull-down activation                */
+
+/*
+ *  GPIOモードパラメータ
+ */
+#define GPIO_MODE_INPUT     0x00000000	/* Input Floating Mode */
+#define GPIO_MODE_OUTPUT    0x00000001	/* Output Push Pull Mode */
+#define GPIO_MODE_AF        0x00000002	/* Alternate Function Push Pull Mode */
+#define GPIO_MODE_ANALOG    0x00000003	/* Analog Mode  */
+
+/*
+ *  GPIOアウトプット最大周波数パラメータ
+ */
+#define GPIO_SPEED_LOW      0x00000000	/* Low speed     */
+#define GPIO_SPEED_MEDIUM   0x00000001	/* Medium speed  */
+#define GPIO_SPEED_FAST     0x00000002	/* Fast speed    */
+#define GPIO_SPEED_HIGH     0x00000003	/* High speed    */
+
+
+#define LED1_POSITION                   1
+
+/*
+ *  キャッシュサイズID レジスタマクロ
+ */
+#define CCSIDR_WAYS(x)         (((x) & SCB_CCSIDR_ASSOCIATIVITY_Msk) >> SCB_CCSIDR_ASSOCIATIVITY_Pos)
+#define CCSIDR_SETS(x)         (((x) & SCB_CCSIDR_NUMSETS_Msk      ) >> SCB_CCSIDR_NUMSETS_Pos      )
+#define CCSIDR_LSSHIFT(x)      (((x) & SCB_CCSIDR_LINESIZE_Msk     ) /*>> SCB_CCSIDR_LINESIZE_Pos*/ )
+
+#define sil_mdw_mem(addr, mask, val)	sil_wrw_mem((addr), ((sil_rew_mem(addr) & ~(mask)) | (val)))
+#define sil_anw_mem(addr, mask)			sil_wrw_mem((addr), (sil_rew_mem(addr) & ~(mask)))
+#define sil_orw_mem(addr, val)			sil_wrw_mem((addr), (sil_rew_mem(addr) | (val)))
+
+ER sysclock_config(int mode);
+static void mpu_config(void);
+static void sysemclock_error(void);
+
+#ifndef TOPPERS_RAM_EXEC
+/*
+ *  低レベルのターゲット依存の初期化
+ *
+ *  スタートアップモジュールの中で，メモリの初期化の前に呼び出される．
+ */
+void hardware_init_hook(void)
+{
+	uint32_t reg_value;
+	uint32_t ccsidr, sshift, wshift, sw;
+	uint32_t sets, ways;
+
+	/*
+	 * RCCのリセットとコンフィギュレーション
+	 */
+	sil_orw_mem((uint32_t *)(TADR_RCC_BASE+TOFF_RCC_CR), RCC_CR_HSION);
+	sil_wrw_mem((uint32_t *)(TADR_RCC_BASE+TOFF_RCC_CFGR), 0x00000000);
+	sil_anw_mem((uint32_t *)(TADR_RCC_BASE+TOFF_RCC_CR), (RCC_CR_PLLON | RCC_CR_CSSON | RCC_CR_HSEON));
+	sil_wrw_mem((uint32_t *)(TADR_RCC_BASE+TOFF_RCC_PLLCFGR),
+		(0x20000000 | RCC_PLLCFGR_PLLQ_2 | RCC_PLLCFGR_PLLN_7 | RCC_PLLCFGR_PLLN_6 | RCC_PLLCFGR_PLLM_4));
+	sil_anw_mem((uint32_t *)(TADR_RCC_BASE+TOFF_RCC_CR), RCC_CR_HSEBYP);
+
+	/*
+	 *  全割込み禁止
+	 */
+	sil_wrw_mem((uint32_t *)(TADR_RCC_BASE+TOFF_RCC_CIR), 0x00000000);
+
+	/*
+	 *  メモリプロテクションユニットの初期化
+	 */
+	mpu_config();
+
+	/*
+	 *  キャッシュを有効化
+	 */
+	/* I-Cache有効化 */
+	Asm("dsb 0xF":::"memory");
+	Asm("isb 0xF":::"memory");
+	sil_wrw_mem((uint32_t *)(TADR_SCB_BASE+TOFF_SCB_ICIALLU), 0);	/* invalidate I-Cache */
+	sil_orw_mem((uint32_t *)(TADR_SCB_BASE+TOFF_SCB_CCR), SCB_CCR_IC_Msk);	/* enable I-Cache */
+	Asm("dsb 0xF":::"memory");
+	Asm("isb 0xF":::"memory");
+
+	/* D-Cache有効化 */
+	sil_wrw_mem((uint32_t *)(TADR_SCB_BASE+TOFF_SCB_CSSELR), ((0UL << 1) | 0UL));	/* Level 1 data cache */
+	ccsidr  = sil_rew_mem((uint32_t *)(TADR_SCB_BASE+TOFF_SCB_CCSIDR));
+    sets    = (uint32_t)(CCSIDR_SETS(ccsidr));
+    sshift  = (uint32_t)(CCSIDR_LSSHIFT(ccsidr) + 4UL);
+    ways    = (uint32_t)(CCSIDR_WAYS(ccsidr));
+    wshift  = (uint32_t)((uint32_t)__builtin_clz(ways) & 0x1FUL);
+
+    /* D-Chaheインバリデート */
+	Asm("dsb 0xF":::"memory");
+	do{
+		uint32_t tmpways = ways;
+		do {
+			sw = ((tmpways << wshift) | (sets << sshift));
+			sil_wrw_mem((uint32_t *)(TADR_SCB_BASE+TOFF_SCB_DCISW), sw);
+
+        } while(tmpways--);
+    }while(sets--);
+	Asm("dsb 0xF":::"memory");
+
+	sil_orw_mem((uint32_t *)(TADR_SCB_BASE+TOFF_SCB_CCR), SCB_CCR_DC_Msk);
+	Asm("dsb 0xF":::"memory");
+	Asm("isb 0xF":::"memory");
+
+
+	/*
+	 *  割込みグループ優先度設定
+	 */
+	reg_value = sil_rew_mem((uint32_t *)(TADR_SCB_BASE+TOFF_SCB_AIRCR));        /* read old register configuration    */
+	reg_value &= ~((uint32_t)(SCB_AIRCR_VECTKEY_Msk | SCB_AIRCR_PRIGROUP_Msk));	/* clear bits to change               */
+	reg_value  =  (reg_value                                   |
+                ((uint32_t)0x5FAUL << SCB_AIRCR_VECTKEY_Pos) |
+                ((NVIC_PRIORITYGROUP_4 & 0x07L) << 8));							/* Insert write key and priorty group */
+	sil_wrw_mem((uint32_t *)(TADR_SCB_BASE+TOFF_SCB_AIRCR), reg_value);
+
+	/*
+	 *  システムクロックを 216MHzに設定
+	 */
+	if(sysclock_config(0) != E_OK)
+		sysemclock_error();
+}
+#endif
+
+/*
+ *  USB CLOCK CONFIGURATION
+ */
+ER USB_RCC_PeriphCLKConfig(unsigned int pllsan, unsigned int pllsaip)
+{
+	unsigned int tickstart = 0U;
+	unsigned int pllsaiq = 0U;
+
+    /*
+	 * クロック48ソース設定
+	 */
+	sil_mdw_mem((uint32_t *)(TADR_RCC_BASE+TOFF_RCC_DCKCFGR2), RCC_DCKCFGR2_CK48MSEL, RCC_CLK48SOURCE_PLLSAIP);
+
+    /*
+	 *  PLLSAIクロックを停止
+	 */
+	sil_anw_mem((uint32_t *)(TADR_RCC_BASE+TOFF_RCC_CR), RCC_CR_PLLSAION);
+
+	tickstart = 0;
+	while((sil_rew_mem((uint32_t *)(TADR_RCC_BASE+TOFF_RCC_CR)) & RCC_CR_PLLSAIRDY) != 0){
+		if(tickstart  > PLLSAI_TIMEOUT_VALUE){
+			return E_TMOUT;
+		}
+		sil_dly_nse(1000);
+		tickstart++;
+    }
+
+    /*
+	 *  PLLSAIクロック設定
+	 */
+	pllsaiq = sil_rew_mem((uint32_t *)(TADR_RCC_BASE+TOFF_RCC_PLLSAICFGR)) & (RCC_PLLSAICFGR_PLLSAIQ | RCC_PLLSAICFGR_PLLSAIR);
+	/* Configure the PLLSAI division factors */
+	/* PLLSAI_VCO = f(VCO clock) = f(PLLSAI clock input) * (PLLI2SN/PLLSAIM) */
+	/* 48CLK = f(PLLSAI clock output) = f(VCO clock) / PLLSAIP */
+	pllsaiq |= (pllsan << 6)  | (pllsaip << 16);
+	sil_wrw_mem((uint32_t *)(TADR_RCC_BASE+TOFF_RCC_PLLSAICFGR), pllsaiq);
+
+    /*
+	 *  PLLSAIクロックを再開
+	 */
+	sil_orw_mem((uint32_t *)(TADR_RCC_BASE+TOFF_RCC_CR), RCC_CR_PLLSAION);
+
+	tickstart = 0;
+	while((sil_rew_mem((uint32_t *)(TADR_RCC_BASE+TOFF_RCC_CR)) & (RCC_CR_PLLSAIRDY)) == 0){
+		if( tickstart > PLLSAI_TIMEOUT_VALUE){
+			return E_TMOUT;
+		}
+		sil_dly_nse(1000);
+		tickstart++;
+	}
+	return E_OK;
+}
+
+/*
+ *  システムクロック設定
+ *  設定値：
+ *    System Clock source            = PLL (HSE)
+ *    SYSCLK(Hz)                     = 216000000
+ *    HCLK(Hz)                       = 216000000
+ *    AHB Prescaler                  = 1
+ *    APB1 Prescaler                 = 4
+ *    APB2 Prescaler                 = 2
+ *    HSE Frequency(Hz)              = 8000000
+ *    PLL_M                          = 8
+ *    PLL_N                          = 432
+ *    PLL_P                          = 2
+ *    PLL_Q                          = 9
+ *    PLL_R                          = 7
+ *    VDD(V)                         = 3.3
+ *    Main regulator output voltage  = Scale1 mode
+ *    Flash Latency(WS)              = 7
+ */
+ER sysclock_config(int mode)
+{
+	uint32_t tickstart = 0;
+	volatile uint32_t tmpreg;
+
+	/*
+	 *  HSEの初期設定
+	 */
+	sil_anw_mem((uint32_t *)(TADR_RCC_BASE+TOFF_RCC_CR), RCC_CR_HSEBYP);
+	sil_anw_mem((uint32_t *)(TADR_RCC_BASE+TOFF_RCC_CR), RCC_CR_HSEON);
+
+	/* HSEの無効化待ち */  
+	while((sil_rew_mem((uint32_t *)(TADR_RCC_BASE+TOFF_RCC_CR)) & RCC_CR_HSERDY) != 0){
+		if(tickstart > HSE_TIMEOUT_VALUE){
+			return E_TMOUT;
+		}
+		sil_dly_nse(1000);
+		tickstart++;
+	}
+
+	/* HSEの再設定 */
+	sil_anw_mem((uint32_t *)(TADR_RCC_BASE+TOFF_RCC_CR), RCC_CR_HSEON);
+	sil_orw_mem((uint32_t *)(TADR_RCC_BASE+TOFF_RCC_CR), RCC_CR_HSEBYP);
+	sil_orw_mem((uint32_t *)(TADR_RCC_BASE+TOFF_RCC_CR), RCC_CR_HSEON);
+
+	tickstart = 0;
+	/* HSEの再起動待ち */
+	while((sil_rew_mem((uint32_t *)(TADR_RCC_BASE+TOFF_RCC_CR)) & RCC_CR_HSERDY) == 0){
+		if(tickstart > HSE_TIMEOUT_VALUE){
+			return E_TMOUT;
+		}
+		sil_dly_nse(1000);
+		tickstart++;
+	}
+
+	/*
+	 *  PLLの初期設定
+	 */
+	/*  メインPLLの無効化. */
+	sil_anw_mem((uint32_t *)(TADR_RCC_BASE+TOFF_RCC_CR), RCC_CR_PLLON);
+
+	/*  PLLのレディ待ち */
+	tickstart = 0;
+	while((sil_rew_mem((uint32_t *)(TADR_RCC_BASE+TOFF_RCC_CR)) & RCC_CR_PLLRDY) != 0){
+		if(tickstart > PLL_TIMEOUT_VALUE){
+			return E_TMOUT;
+		}
+		sil_dly_nse(1000);
+		tickstart++;
+	}
+	/*  PLLレジスタ設定 */
+	sil_wrw_mem((uint32_t *)(TADR_RCC_BASE+TOFF_RCC_PLLCFGR), (0x20000000 | PLL_M | (PLL_N << 6) | ((RCC_PLLP_DIV2 >> 1) -1) << 16)
+			 | RCC_PLLCFGR_PLLSRC_HSE | (PLL_Q << 24) | (PLL_R << 28));
+
+	/*  メインPLLの有効化待ち */
+	sil_orw_mem((uint32_t *)(TADR_RCC_BASE+TOFF_RCC_CR), RCC_CR_PLLON);
+	tickstart = 0;
+
+	/*  PLLの有効化待ち */
+	while((sil_rew_mem((uint32_t *)(TADR_RCC_BASE+TOFF_RCC_CR)) & RCC_CR_PLLRDY) == 0){
+		if(tickstart > PLL_TIMEOUT_VALUE){
+			return E_TMOUT;
+		}
+		sil_dly_nse(1000);
+		tickstart++;
+	}
+
+
+	sil_orw_mem((uint32_t *)(TADR_RCC_BASE+TOFF_RCC_APB1ENR), RCC_APB1ENR_PWREN);
+	tmpreg = sil_rew_mem((uint32_t *)(TADR_RCC_BASE+TOFF_RCC_APB1ENR)) & RCC_APB1ENR_PWREN;
+	(void)(tmpreg);
+
+	/* 216MHz用のオーバードライブ設定 */
+	sil_orw_mem((uint32_t *)(TADR_PWR_BASE+TOFF_PWR_CR1), PWR_CR1_ODEN);
+
+	tickstart = 0;
+	while((sil_rew_mem((uint32_t *)(TADR_PWR_BASE+TOFF_PWR_CSR1)) & PWR_CSR1_ODRDY) != PWR_CSR1_ODRDY){
+		if(tickstart > PWR_OVERDRIVE_TIMEOUT_VALUE){
+			return E_TMOUT;
+		}
+		sil_dly_nse(1000);
+    	tickstart++;
+	}
+
+	/* オーバードライブスイッチを有効化 */
+	sil_orw_mem((uint32_t *)(TADR_PWR_BASE+TOFF_PWR_CR1), PWR_CR1_ODSWEN);
+
+	/* オーバードライブレディ待ち */
+	tickstart = 0;
+	while((sil_rew_mem((uint32_t *)(TADR_PWR_BASE+TOFF_PWR_CSR1)) & PWR_CSR1_ODSWRDY) != PWR_CSR1_ODSWRDY){
+		if(tickstart > PWR_OVERDRIVE_TIMEOUT_VALUE){
+			return E_TMOUT;
+		}
+		sil_dly_nse(1000);
+		tickstart++;
+	}
+
+	/*
+	 *  USBクロック設定
+	 */
+	USB_RCC_PeriphCLKConfig(384, RCC_PLLSAIP_DIV8);
+
+	/*
+	 *  フラッシュメモリから正しくデータを読み込めるように実行周波数に合わせて
+	 *  HCLKレイテンシィとデバイスの電源電圧調節する必要がある
+	 */
+	/*  CPU周波数の増大ケース */
+	if(FLASH_ACR_LATENCY_7WS > (sil_rew_mem((uint32_t *)(TADR_FLASH_R_BASE+TOFF_FLASH_ACR)) & FLASH_ACR_LATENCY)){
+
+		sil_mdw_mem((uint32_t *)(TADR_FLASH_R_BASE+TOFF_FLASH_ACR), FLASH_ACR_LATENCY, FLASH_ACR_LATENCY_7WS);
+		if((sil_rew_mem((uint32_t *)(TADR_FLASH_R_BASE+TOFF_FLASH_ACR)) & FLASH_ACR_LATENCY) != FLASH_ACR_LATENCY_7WS){
+			while(1) { ; }
+		}
+
+		sil_mdw_mem((uint32_t *)(TADR_RCC_BASE+TOFF_RCC_CFGR), RCC_CFGR_HPRE, RCC_SYSCLK_DIV1);
+		if((sil_rew_mem((uint32_t *)(TADR_RCC_BASE+TOFF_RCC_CR)) & RCC_CR_PLLRDY) == 0){
+			return E_SYS;
+		}
+
+		sil_mdw_mem((uint32_t *)(TADR_RCC_BASE+TOFF_RCC_CFGR), RCC_CFGR_SW, RCC_CFGR_SW_PLL);
+		while((sil_rew_mem((uint32_t *)(TADR_RCC_BASE+TOFF_RCC_CFGR)) & RCC_CFGR_SWS) != RCC_CFGR_SWS_PLL){
+			if(tickstart > CLOCKSWITCH_TIMEOUT_VALUE){
+				return E_TMOUT;
+			}
+			sil_dly_nse(1000);
+			tickstart++;
+		}
+	}
+	/*  CPU周波数の低下ケース */
+	else{
+		sil_mdw_mem((uint32_t *)(TADR_RCC_BASE+TOFF_RCC_CFGR), RCC_CFGR_HPRE, RCC_SYSCLK_DIV1);
+		if((sil_rew_mem((uint32_t *)(TADR_RCC_BASE+TOFF_RCC_CR)) & RCC_CR_PLLRDY) == 0){
+			return E_SYS;
+		}
+
+		while((sil_rew_mem((uint32_t *)(TADR_RCC_BASE+TOFF_RCC_CFGR)) & RCC_CFGR_SWS) != RCC_CFGR_SWS_PLL){
+			if(tickstart > CLOCKSWITCH_TIMEOUT_VALUE){
+				return E_TMOUT;
+			}
+			sil_dly_nse(1000);
+			tickstart++;
+		}
+
+		sil_mdw_mem((uint32_t *)(TADR_FLASH_R_BASE+TOFF_FLASH_ACR), FLASH_ACR_LATENCY, FLASH_ACR_LATENCY_7WS);
+		if((sil_rew_mem((uint32_t *)(TADR_FLASH_R_BASE+TOFF_FLASH_ACR)) & FLASH_ACR_LATENCY) != FLASH_ACR_LATENCY_7WS){
+			return E_SYS;
+		}
+	}
+
+	/*
+	 *  PCLK1初期設定
+	 */ 
+	sil_mdw_mem((uint32_t *)(TADR_RCC_BASE+TOFF_RCC_CFGR), RCC_CFGR_PPRE1, RCC_HCLK_DIV4);
+
+	/*
+	 *  PCLK2初期設定
+	 */
+	sil_mdw_mem((uint32_t *)(TADR_RCC_BASE+TOFF_RCC_CFGR), RCC_CFGR_PPRE2, (RCC_HCLK_DIV2 << 3));
+	return E_OK;
+}
+
+/*
+ *  メモリプロテクションユニットの設定
+ */
+static void mpu_config(void)
+{
+	/* Disable the MPU */
+	sil_anw_mem((uint32_t *)(TADR_SCB_BASE+TOFF_SCB_SHCSR), SCB_SHCSR_MEMFAULTENA_Msk);
+	sil_anw_mem((uint32_t *)(TADR_MPU_BASE+TOFF_MPU_CTRL), MPU_CTRL_ENABLE_Msk);
+
+	/* Set the Region number */
+	sil_wrw_mem((uint32_t *)(TADR_MPU_BASE+TOFF_MPU_RNR), MPU_REGION_NUMBER0);
+	sil_wrw_mem((uint32_t *)(TADR_MPU_BASE+TOFF_MPU_RBAR), 0x20020000);
+	sil_wrw_mem((uint32_t *)(TADR_MPU_BASE+TOFF_MPU_RASR),
+				((MPU_INSTRUCTION_ACCESS_ENABLE << MPU_RASR_XN_Pos)   |
+                 (MPU_REGION_FULL_ACCESS        << MPU_RASR_AP_Pos)   |
+                 (MPU_TEX_LEVEL0                << MPU_RASR_TEX_Pos)  |
+                 (MPU_ACCESS_NOT_SHAREABLE      << MPU_RASR_S_Pos)    |
+                 (MPU_ACCESS_CACHEABLE          << MPU_RASR_C_Pos)    |
+                 (MPU_ACCESS_NOT_BUFFERABLE     << MPU_RASR_B_Pos)    |
+                 (0x00                          << MPU_RASR_SRD_Pos)  |
+                 (MPU_REGION_SIZE_512KB         << MPU_RASR_SIZE_Pos) |
+                 (MPU_REGION_ENABLE             << MPU_RASR_ENABLE_Pos)));
+
+	sil_wrw_mem((uint32_t *)(TADR_MPU_BASE+TOFF_MPU_RNR), MPU_REGION_NUMBER1);
+	sil_wrw_mem((uint32_t *)(TADR_MPU_BASE+TOFF_MPU_RBAR), 0x20078000);
+	sil_wrw_mem((uint32_t *)(TADR_MPU_BASE+TOFF_MPU_RASR),
+				((MPU_INSTRUCTION_ACCESS_ENABLE << MPU_RASR_XN_Pos)   |
+                 (MPU_REGION_FULL_ACCESS        << MPU_RASR_AP_Pos)   |
+                 (MPU_TEX_LEVEL1                << MPU_RASR_TEX_Pos)  |
+                 (MPU_ACCESS_SHAREABLE          << MPU_RASR_S_Pos)    |
+                 (MPU_ACCESS_NOT_CACHEABLE      << MPU_RASR_C_Pos)    |
+                 (MPU_ACCESS_NOT_BUFFERABLE     << MPU_RASR_B_Pos)    |
+                 (0x00                          << MPU_RASR_SRD_Pos)  |
+                 (MPU_REGION_SIZE_32KB          << MPU_RASR_SIZE_Pos) |
+                 (MPU_REGION_ENABLE             << MPU_RASR_ENABLE_Pos)));
+
+	sil_wrw_mem((uint32_t *)(TADR_MPU_BASE+TOFF_MPU_RNR), MPU_REGION_NUMBER2);
+	sil_wrw_mem((uint32_t *)(TADR_MPU_BASE+TOFF_MPU_RBAR), 0x20078000);
+	sil_wrw_mem((uint32_t *)(TADR_MPU_BASE+TOFF_MPU_RASR),
+				((MPU_INSTRUCTION_ACCESS_ENABLE << MPU_RASR_XN_Pos)   |
+                 (MPU_REGION_FULL_ACCESS        << MPU_RASR_AP_Pos)   |
+                 (MPU_TEX_LEVEL0                << MPU_RASR_TEX_Pos)  |
+                 (MPU_ACCESS_SHAREABLE          << MPU_RASR_S_Pos)    |
+                 (MPU_ACCESS_NOT_CACHEABLE      << MPU_RASR_C_Pos)    |
+                 (MPU_ACCESS_BUFFERABLE         << MPU_RASR_B_Pos)    |
+                 (0x00                          << MPU_RASR_SRD_Pos)  |
+                 (MPU_REGION_SIZE_512B          << MPU_RASR_SIZE_Pos) |
+                 (MPU_REGION_ENABLE             << MPU_RASR_ENABLE_Pos)));
+
+	/* Enable the MPU */
+	sil_wrw_mem((uint32_t *)(TADR_MPU_BASE+TOFF_MPU_CTRL), (MPU_PRIVILEGED_DEFAULT | MPU_CTRL_ENABLE_Msk));
+	sil_orw_mem((uint32_t *)(TADR_SCB_BASE+TOFF_SCB_SHCSR), SCB_SHCSR_MEMFAULTENA_Msk);
+}
+
+/*
+ *  システムクロック設定エラー
+ */
+static void sysemclock_error(void)
+{
+	volatile uint32_t temp = 0x00;
+	uint32_t n = LED1_POSITION;
+
+	/*
+	 *  GPIO LEDクロック設定
+	 */
+	sil_orw_mem((uint32_t *)(TADR_RCC_BASE+TOFF_RCC_AHB1ENR), RCC_AHB1ENR_GPIOIEN);
+	temp = sil_rew_mem((uint32_t *)(TADR_RCC_BASE+TOFF_RCC_AHB1ENR));
+	(void)(temp);
+
+	/*
+	 * LED GPIO設定
+	 */
+	sil_mdw_mem((uint32_t *)(TADR_GPIOI_BASE+TOFF_GPIO_MODER), (3 << (n * 2)), (GPIO_MODE_OUTPUT << (n * 2)));
+	sil_mdw_mem((uint32_t *)(TADR_GPIOI_BASE+TOFF_GPIO_OSPEEDR), (3 << (n * 2)), (GPIO_SPEED_HIGH << (n * 2)));
+	sil_mdw_mem((uint32_t *)(TADR_GPIOI_BASE+TOFF_GPIO_OTYPER), (1 << n), (GPIO_OTYPE_PP<<n));
+	sil_mdw_mem((uint32_t *)(TADR_GPIOI_BASE+TOFF_GPIO_PUPDR), (3 << (n * 2)), (GPIO_PULLUP << (n * 2)));
+	while(1){
+		/* LED ON */
+		sil_wrw_mem((uint32_t *)(TADR_GPIOI_BASE+TOFF_GPIO_BSRR), (1<<n));
+		sil_dly_nse(200*1000*1000);
+		/* LED OFF */
+		sil_wrw_mem((uint32_t *)(TADR_GPIOI_BASE+TOFF_GPIO_BSRR), (1<<n)<<16);
+		sil_dly_nse(200*1000*1000);
+	}
+}
+
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/target/stm32f767nucleo144_gcc/target_kernel.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/target/stm32f767nucleo144_gcc/target_kernel.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/target/stm32f767nucleo144_gcc/target_kernel.h	(revision 457)
@@ -0,0 +1,61 @@
+/*
+ *  TOPPERS/ASP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Advanced Standard Profile Kernel
+ * 
+ *  Copyright (C) 2008-2011 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ *  Copyright (C) 2015-2016 by 3rd Designing Center
+ *              Imageing System Development Division RICOH COMPANY, LTD.
+ *  Copyright (C) 2017-2017 by TOPPERS PROJECT Educational Working Group.
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *  kernel.hのチップ依存部（stm32f767-nucleo144用）
+ *
+ *  このインクルードファイルは，kernel.hでインクルードされる．他のファ
+ *  イルから直接インクルードすることはない．このファイルをインクルード
+ *  する前に，t_stddef.hがインクルードされるので，それらに依存してもよ
+ *  い．
+ */
+
+#ifndef TOPPERS_TARGET_KERNEL_H
+#define TOPPERS_TARGET_KERNEL_H
+
+/*
+ *  チップで共通な定義（stm32f7xx用）
+ */
+#include "arm_m_gcc/stm32f7xx/chip_kernel.h"
+
+#endif /* TOPPERS_TARGET_KERNEL_H */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/target/stm32f767nucleo144_gcc/target_offset.tf
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/target/stm32f767nucleo144_gcc/target_offset.tf	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/target/stm32f767nucleo144_gcc/target_offset.tf	(revision 457)
@@ -0,0 +1,13 @@
+$
+$       オフセットファイル生成用テンプレートファイル（stm32f767_nucleo144用）
+$
+
+$
+$  標準テンプレートファイルのインクルード
+$
+$INCLUDE "kernel/genoffset.tf"$
+
+$ 
+$  コア依存テンプレートのインクルード（ARM-M用）
+$ 
+$INCLUDE"../../arch/arm_m_gcc/common/core_offset.tf"$
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/target/stm32f767nucleo144_gcc/target_rename.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/target/stm32f767nucleo144_gcc/target_rename.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/target/stm32f767nucleo144_gcc/target_rename.h	(revision 457)
@@ -0,0 +1,14 @@
+/* This file is generated from target_rename.def by genrename. */
+
+#ifndef TOPPERS_TARGET_RENAME_H
+#define TOPPERS_TARGET_RENAME_H
+
+
+#ifdef TOPPERS_LABEL_ASM
+
+
+#endif /* TOPPERS_LABEL_ASM */
+
+#include "arm_m_gcc/stm32f7xx/chip_rename.h"
+
+#endif /* TOPPERS_TARGET_RENAME_H */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/target/stm32f767nucleo144_gcc/target_serial.cfg
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/target/stm32f767nucleo144_gcc/target_serial.cfg	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/target/stm32f767nucleo144_gcc/target_serial.cfg	(revision 457)
@@ -0,0 +1,13 @@
+/*
+ *  @(#) $Id$
+ */
+
+/*
+ *    SIOドライバのコンフィギュレーションファイル
+ */
+#include "target_serial.h"
+ATT_INI({ TA_NULL, 0, sio_initialize });
+ATT_ISR({ TA_NULL, 1, INTNO_SIO1, sio_usart_isr, 1 });
+ATT_ISR({ TA_NULL, 2, INTNO_SIO2, sio_usart_isr, 1 });
+CFG_INT(INTNO_SIO1, { TA_ENAINT|INTATR_SIO, INTPRI_SIO });
+CFG_INT(INTNO_SIO2, { TA_ENAINT|INTATR_SIO, INTPRI_SIO });
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/target/stm32f767nucleo144_gcc/target_serial.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/target/stm32f767nucleo144_gcc/target_serial.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/target/stm32f767nucleo144_gcc/target_serial.h	(revision 457)
@@ -0,0 +1,114 @@
+/*
+ *  TOPPERS/ASP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Advanced Standard Profile Kernel
+ * 
+ *  Copyright (C) 2008-2011 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ *  Copyright (C) 2015-2016 by 3rd Designing Center
+ *              Imageing System Development Division RICOH COMPANY, LTD.
+ *  Copyright (C) 2017-2020 by TOPPERS PROJECT Educational Working Group.
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *    シリアルI/Oデバイス（SIO）ドライバ
+ */
+
+#ifndef TOPPERS_TARGET_SERIAL_H
+#define TOPPERS_TARGET_SERIAL_H
+
+/*
+ *  チップ依存モジュール（stm32f767-nucleo144用）
+ */
+
+/*
+ *  SIO用GPIOの設定
+ */
+#define TADR_U1T_GPIO_BASE TADR_GPIOD_BASE
+#define TADR_U1R_GPIO_BASE TADR_GPIOD_BASE
+#define TADR_U2T_GPIO_BASE TADR_GPIOG_BASE
+#define TADR_U2R_GPIO_BASE TADR_GPIOG_BASE
+#define TOFF_U1_APBNER     TOFF_RCC_APB1ENR
+#define TOFF_U2_APBNER     TOFF_RCC_APB2ENR
+#define TOFF_U1_APBRSTR    TOFF_RCC_APB1RSTR
+#define TOFF_U2_APBRSTR    TOFF_RCC_APB2RSTR
+#define GPIO_U1_AF         0x07
+#define GPIO_U2_AF         0x08
+#define ENABLE_U1_PORT     RCC_APB1ENR_USART3EN
+#define ENABLE_U2_PORT     RCC_APB2ENR_USART6EN
+#define ENABLE_U1T_GPIO    RCC_AHB1ENR_GPIODEN
+#define ENABLE_U1R_GPIO    RCC_AHB1ENR_GPIODEN
+#define ENABLE_U2T_GPIO    RCC_AHB1ENR_GPIOGEN
+#define ENABLE_U2R_GPIO    RCC_AHB1ENR_GPIOGEN
+#define RESET_U1_PORT      RCC_APB1RSTR_USART3RST
+#define RESET_U2_PORT      RCC_APB2RSTR_USART6RST
+#define TX1_PINPOS         8
+#define RX1_PINPOS         9
+#define TX2_PINPOS         14
+#define RX2_PINPOS         9
+
+/*
+ *  SIOのベースアドレス
+ */
+#define USART1_BASE        TADR_USART3_BASE
+#define USART2_BASE        TADR_USART6_BASE
+
+/*
+ *  CLOCKソース指定
+ */
+#define U1_CLOCK_SHIFT     4
+#define U2_CLOCK_SHIFT     10
+
+/*
+ *  シリアルI/Oポート数の定義
+ */
+#ifndef TNUM_SIOP
+#define TNUM_SIOP       2       /* サポートするシリアルI/Oポートの数 */
+#endif
+
+/*
+ *  SIOの割込みハンドラのベクタ番号
+ */
+#define INHNO_SIO1      IRQ_VECTOR_USART3
+#define INTNO_SIO1      IRQ_VECTOR_USART3
+#define INHNO_SIO2      IRQ_VECTOR_USART6
+#define INTNO_SIO2      IRQ_VECTOR_USART6
+
+#define INTPRI_SIO       -3        /* 割込み優先度 */
+#define INTATR_SIO       0         /* 割込み属性 */
+
+
+#include "arm_m_gcc/stm32f7xx/chip_serial.h"
+
+#endif /* TOPPERS_TARGET_SERIAL_H */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/target/stm32f767nucleo144_gcc/target_sil.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/target/stm32f767nucleo144_gcc/target_sil.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/target/stm32f767nucleo144_gcc/target_sil.h	(revision 457)
@@ -0,0 +1,60 @@
+/*
+ *  TOPPERS Software
+ *      Toyohashi Open Platform for Embedded Real-Time Systems
+ * 
+ *  Copyright (C) 2008-2011 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ *  Copyright (C) 2015-2016 by 3rd Designing Center
+ *              Imageing System Development Division RICOH COMPANY, LTD.
+ *  Copyright (C) 2017-2017 by TOPPERS PROJECT Educational Working Group.
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *   sil.hのチップ依存部（stm32f767-nucleo144用）
+ *
+ *  このインクルードファイルは，sil.hの先頭でインクルードされる．他のファ
+ *  イルからは直接インクルードすることはない．このファイルをインクルー
+ *  ドする前に，t_stddef.hがインクルードされるので，それらに依存しても
+ *  よい．
+ */
+
+#ifndef TOPPERS_TARGET_SIL_H
+#define TOPPERS_TARGET_SIL_H
+
+/*
+ *  チップ依存モジュール（stm32f7xx用）
+ */
+#include "arm_m_gcc/stm32f7xx/chip_sil.h"
+
+#endif /* TOPPERS_TARGET_SIL_H */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/target/stm32f767nucleo144_gcc/target_stddef.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/target/stm32f767nucleo144_gcc/target_stddef.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/target/stm32f767nucleo144_gcc/target_stddef.h	(revision 457)
@@ -0,0 +1,94 @@
+/*
+ *  TOPPERS Software
+ *      Toyohashi Open Platform for Embedded Real-Time Systems
+ * 
+ *  Copyright (C) 2008-2011 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ *  Copyright (C) 2015-2016 by 3rd Designing Center
+ *              Imageing System Development Division RICOH COMPANY, LTD.
+ *  Copyright (C) 2017-2017 by TOPPERS PROJECT Educational Working Group.
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *  t_stddef.hのターゲット依存部（stm32f767-nucleo144用）
+ *
+ *  このインクルードファイルは，t_stddef.hの先頭でインクルードされる．
+ *  他のファイルからは直接インクルードすることはない．他のインクルード
+ *  ファイルに先立って処理されるため，他のインクルードファイルに依存し
+ *  てはならない．
+ */
+
+#ifndef TOPPERS_TARGET_STDDEF_H
+#define TOPPERS_TARGET_STDDEF_H
+
+/*
+ *  ターゲットを識別するためのマクロの定義
+ */
+#define TOPPERS_STM32F767_NUCLEO144				/* システム略称 */
+
+/*
+ *  開発環境で共通な定義
+ *
+ *  開発環境でstdint.hが用意されている場合には，TOPPERS_STDINT_TYPE1の
+ *  マクロ定義を削除し，stdint.hをインクルードすればよい．
+ */
+#ifndef TOPPERS_MACRO_ONLY
+#include <stdint.h>
+#else
+#define TOPPERS_STDINT_TYPE1
+#endif
+#define TOPPERS_STDFLOAT_TYPE1
+#define _SYS__STDINT_H
+#define _STDINT_H
+#include "gcc/tool_stddef.h"
+
+/*
+ *  コア依存で共通な定義
+ */
+#include "arm_m_gcc/common/core_stddef.h"
+
+
+#ifndef TOPPERS_MACRO_ONLY
+
+/*
+ *  アサーションの失敗時の実行中断処理（T.B.D）
+ */
+Inline void
+TOPPERS_assert_abort(void)
+{
+    
+}
+
+#endif /* TOPPERS_MACRO_ONLY */
+#endif /* TOPPERS_TARGET_STDDEF_H */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/target/stm32f767nucleo144_gcc/target_syssvc.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/target/stm32f767nucleo144_gcc/target_syssvc.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/target/stm32f767nucleo144_gcc/target_syssvc.h	(revision 457)
@@ -0,0 +1,119 @@
+/*
+ *  TOPPERS/ASP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Advanced Standard Profile Kernel
+ * 
+ *  Copyright (C) 2008-2011 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ *  Copyright (C) 2015-2016 by 3rd Designing Center
+ *              Imageing System Development Division RICOH COMPANY, LTD.
+ *  Copyright (C) 2017-2017 by TOPPERS PROJECT Educational Working Group.
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *  システムサービスのターゲット依存部（stm32f767-nucleo144用）
+ *
+ *  システムサービスのターゲット依存部のインクルードファイル．このファ
+ *  イルの内容は，コンポーネント記述ファイルに記述され，このファイルは
+ *  無くなる見込み．
+ */
+
+#ifndef TOPPERS_TARGET_SYSSVC_H
+#define TOPPERS_TARGET_SYSSVC_H
+
+/*
+ *  ターゲットシステムのハードウェア資源の定義
+ */
+#include "stm32f7xx.h"
+
+/*
+ *  システムクロックの定義
+ */
+#define SystemFrequency     216000000
+#define SysFreHCLK          216000000	/* HCLK = MasterClock / 1 */
+#define SysFrePCLK1         54000000	/* PCLK1 = HCLK / 4 */
+#define SysFrePCLK2         108000000	/* PCLK2 = HCLK / 2 */
+#define HSE_VALUE           8000000
+#define HSI_VALUE           16000000
+#define LSE_VALUE           32768
+
+#define SYS_CLOCK		    (SystemFrequency)
+
+/*
+ *  トレースログに関する設定
+ */
+#ifdef TOPPERS_ENABLE_TRACE
+#include "logtrace/trace_config.h"
+#endif /* TOPPERS_ENABLE_TRACE */
+
+/*
+ *  起動メッセージのターゲットシステム名
+ */
+#define TARGET_NAME    "stm32f767-nucleo144(Cortex-M7)"
+
+/*
+ *  起動メッセージの著作権表示
+ */
+#define TARGET_COPYRIGHT \
+"Copyright (C) 2015-2017 by Education Working Group TOPPERS PROJECT, JAPAN\n" \
+
+/*
+ *  システムログの低レベル出力のための文字出力
+ *
+ *  ターゲット依存の方法で，文字cを表示/出力/保存する．
+ */
+extern void	target_fput_log(int8_t c);
+
+/*
+ *  サポートするシリアルポートの数
+ */
+#define TNUM_PORT        TNUM_SIOP
+
+/*
+ *  ログタスクが使用するポートID
+ */
+#define LOGTASK_PORTID   SIO_PORTID
+
+/*
+ *  ボーレート
+ */
+#define BPS_SETTING		(115200)
+
+/*
+ *  システムログタスク関連の定数の定義
+ *
+ *  デフォルト値の通り．
+ */
+
+#endif /* TOPPERS_TARGET_SYSSVC_H */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/target/stm32f767nucleo144_gcc/target_test.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/target/stm32f767nucleo144_gcc/target_test.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/target/stm32f767nucleo144_gcc/target_test.h	(revision 457)
@@ -0,0 +1,56 @@
+/*
+ *  TOPPERS/ASP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Advanced Standard Profile Kernel
+ * 
+ *  Copyright (C) 2008-2011 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ *  Copyright (C) 2015-2016 by 3rd Designing Center
+ *              Imageing System Development Division RICOH COMPANY, LTD.
+ *  Copyright (C) 2017-2017 by TOPPERS PROJECT Educational Working Group.
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *		テストプログラムのターゲット依存定義（stm32f767-nucleo144用）
+ */
+
+#ifndef TOPPERS_TARGET_TEST_H
+#define TOPPERS_TARGET_TEST_H
+
+/*
+ *  コア依存モジュール（ARM-M用）
+ */
+#include "arm_m_gcc/common/core_test.h"
+
+#endif /* TOPPERS_TARGET_TEST_H */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/target/stm32f767nucleo144_gcc/target_timer.cfg
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/target/stm32f767nucleo144_gcc/target_timer.cfg	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/target/stm32f767nucleo144_gcc/target_timer.cfg	(revision 457)
@@ -0,0 +1,8 @@
+/*
+ *  @(#) $Id$
+ */
+
+/*
+ *    タイマドライバのコンフィギュレーションファイル
+ */
+INCLUDE("arm_m_gcc/stm32f7xx/chip_timer.cfg");
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/target/stm32f767nucleo144_gcc/target_timer.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/target/stm32f767nucleo144_gcc/target_timer.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/target/stm32f767nucleo144_gcc/target_timer.h	(revision 457)
@@ -0,0 +1,61 @@
+/*
+ *  TOPPERS/ASP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Advanced Standard Profile Kernel
+ * 
+ *  Copyright (C) 2008-2011 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ *  Copyright (C) 2015-2016 by 3rd Designing Center
+ *              Imageing System Development Division RICOH COMPANY, LTD.
+ *  Copyright (C) 2017-2017 by TOPPERS PROJECT Educational Working Group.
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *  タイマドライバ（stm32f767-nucleo144用）
+ */
+
+#ifndef TOPPERS_TARGET_TIMER_H
+#define TOPPERS_TARGET_TIMER_H
+
+/*
+ *  ターゲット依存性定義
+ */
+#include "target_syssvc.h"
+
+/*
+ *  チップ依存モジュール（stm32f7xx用）
+ */
+#include "arm_m_gcc/stm32f7xx/chip_timer.h"
+
+#endif /* TOPPERS_TARGET_TIMER_H */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/target/stm32f767nucleo144_gcc/target_unrename.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/target/stm32f767nucleo144_gcc/target_unrename.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/target/stm32f767nucleo144_gcc/target_unrename.h	(revision 457)
@@ -0,0 +1,15 @@
+/* This file is generated from target_rename.def by genrename. */
+
+/* This file is included only when target_rename.h has been included. */
+#ifdef TOPPERS_TARGET_RENAME_H
+#undef TOPPERS_TARGET_RENAME_H
+
+
+#ifdef TOPPERS_LABEL_ASM
+
+
+#endif /* TOPPERS_LABEL_ASM */
+
+#include "arm_m_gcc/stm32f7xx/chip_unrename.h"
+
+#endif /* TOPPERS_TARGET_RENAME_H */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/target/stm32f767nucleo144_gcc/target_user.txt
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/target/stm32f767nucleo144_gcc/target_user.txt	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/target/stm32f767nucleo144_gcc/target_user.txt	(revision 457)
@@ -0,0 +1,72 @@
+=====================================================================
+                          stm32f767-nucleo 144依存部
+=====================================================================
+
+(1) 対応しているターゲットシステムの種類・構成
+
+stm32f746-nucleo 144依存部は，STM社STM32F767 nucleo-144をサポートしている．
+搭載しているチップはSTM32F767ZIT6である．
+
+(2) 使用する開発環境と動作検証した条件（バージョン，オプション等）
+
+コンパイラはGCCを用いる．動作確認に用いたコンパイラは以下の通りである．
+
+  gcc version 4.9(GCC ARM:2015q3-20150921)/5.4(GCC ARM:2016q2-20160622)
+
+(3) ターゲット定義事項の規定
+
+(3-1) 割込み優先度
+
+CFG_INTで使用可能な割込み優先度の範囲は，-16 ～ -1 である．ARM-Mプロセ
+ッサ依存部のマニュアルあるように，TMIN_INTPRIに設定可能な値の最大値は
+-15であり，カーネル管理内の割込みは-15 ～ -1 の優先度を設定可能であり，
+カーネル管理外の割込みの優先度としては-16が使用可能である．
+
+(4) メモリマップ
+
+プログラムはFLASHへデータはRAMへ配置する．配置を変更するには，
+stm32f7xx_ram.ld/stm32f7xx_rom.ld を変更すること．
+
+(5) シリアルインタフェースドライバの情報
+
+シリアルインタフェースドライバでは，UART3を用いる．通信フォーマットは，
+115200bps, 8bit, non-parity, 1topbitである．
+
+(6) システムログ機能の情報
+
+システムログの低レベル出力は，UART2を用いる．通信フォーマットは，
+115200bps, 8bit, non-parity, 1topbitである．
+
+(7) ディレクトリ構成・ファイル構成
+ ./stm32f767_nucleo144_gcc 
+   ./Makefile.target
+   ./stm32f7xx_ram.ld
+   ./stm32f7xx_rom.ld
+   ./target.tf
+   ./target_asm.inc
+   ./target_cfg1_out.h
+   ./target_check.tf
+   ./target_config.h
+   ./target_inithook.c
+   ./target_kernel.h
+   ./target_offset.tf
+   ./target_rename.def
+   ./target_rename.h
+   ./target_serial.cfg
+   ./target_serial.h
+   ./target_sil.h
+   ./target_stddef.h
+   ./target_syssvc.h
+   ./target_test.h
+   ./target_timer.cfg
+   ./target_timer.h
+   ./target_unrename.h
+   ./target_user.txt
+
+(8) バージョン履歴
+2017/02/05
+・最初のリリース
+2019/07/02
+・メモリモデル変更
+
+以上．
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/test/MANIFEST
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/test/MANIFEST	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/test/MANIFEST	(revision 457)
@@ -0,0 +1,59 @@
+PACKAGE asp
+
+MANIFEST
+bit_kernel.c
+perf0.c
+perf0.cfg
+perf0.h
+perf1.c
+perf1.cfg
+perf1.h
+perf2.c
+perf2.cfg
+perf2.h
+perf3.c
+perf3.cfg
+perf3.h
+perf4.c
+perf4.cfg
+perf4.h
+test_cpuexc.cfg
+test_cpuexc.h
+test_cpuexc.txt
+test_cpuexc1.c
+test_cpuexc2.c
+test_cpuexc3.c
+test_cpuexc4.c
+test_cpuexc5.c
+test_cpuexc6.c
+test_cpuexc7.c
+test_cpuexc8.c
+test_cpuexc9.c
+test_cpuexc10.c
+test_cpuexc11.c
+test_cpuexc12.c
+test_cpuexc13.c
+test_dlynse.c
+test_dlynse.cfg
+test_dlynse.h
+test_sem1.c
+test_sem1.cfg
+test_sem1.h
+test_sem2.c
+test_sem2.cfg
+test_sem2.h
+test_sysstat1.c
+test_sysstat1.cfg
+test_sysstat1.h
+test_task1.c
+test_task1.cfg
+test_task1.h
+test_tex1.c
+test_tex1.cfg
+test_tex1.h
+test_tex2.c
+test_tex2.cfg
+test_tex2.h
+test_utm1.c
+test_utm1.cfg
+test_utm1.h
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/test/bit_kernel.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/test/bit_kernel.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/test/bit_kernel.c	(revision 457)
@@ -0,0 +1,484 @@
+/*
+ *  TOPPERS/ASP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Advanced Standard Profile Kernel
+ * 
+ *  Copyright (C) 2005-2011 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *		カーネルの整合性検査
+ */
+
+#include "kernel/kernel_impl.h"
+#include "kernel/task.h"
+#include "kernel/wait.h"
+#include "kernel/semaphore.h"
+#include "kernel/eventflag.h"
+#include "kernel/dataqueue.h"
+#include "kernel/pridataq.h"
+#include "kernel/mailbox.h"
+#include "kernel/mutex.h"
+#include "kernel/mempfix.h"
+#include "kernel/time_event.h"
+
+/*
+ *   エラーコードの定義
+ */
+#define E_SYS_LINENO	ERCD(E_SYS, -(__LINE__))
+
+/*
+ *  管理ブロックのアドレスの正当性のチェック
+ */
+#define VALID_TCB(p_tcb) \
+		((((char *) p_tcb) - ((char *) tcb_table)) % sizeof(TCB) == 0 \
+			&& TMIN_TSKID <= TSKID(p_tcb) && TSKID(p_tcb) <= tmax_tskid)
+
+#define VALID_SEMCB(p_semcb) \
+		((((char *) p_semcb) - ((char *) semcb_table)) % sizeof(SEMCB) == 0 \
+			&& TMIN_SEMID <= SEMID(p_semcb) && SEMID(p_semcb) <= tmax_semid)
+				
+#define VALID_FLGCB(p_flgcb) \
+		((((char *) p_flgcb) - ((char *) flgcb_table)) % sizeof(FLGCB) == 0 \
+			&& TMIN_FLGID <= FLGID(p_flgcb) && FLGID(p_flgcb) <= tmax_flgid)
+
+#define VALID_DTQCB(p_dtqcb) \
+		((((char *) p_dtqcb) - ((char *) dtqcb_table)) % sizeof(DTQCB) == 0 \
+			&& TMIN_DTQID <= DTQID(p_dtqcb) && DTQID(p_dtqcb) <= tmax_dtqid)
+
+#define VALID_PDQCB(p_pdqcb) \
+		((((char *) p_pdqcb) - ((char *) pdqcb_table)) % sizeof(PDQCB) == 0 \
+			&& TMIN_PDQID <= PDQID(p_pdqcb) && PDQID(p_pdqcb) <= tmax_pdqid)
+
+#define VALID_MBXCB(p_mbxcb) \
+		((((char *) p_mbxcb) - ((char *) mbxcb_table)) % sizeof(MBXCB) == 0 \
+			&& TMIN_MBXID <= MBXID(p_mbxcb) && MBXID(p_mbxcb) <= tmax_mbxid)
+
+#define VALID_MTXCB(p_mtxcb) \
+		((((char *) p_mtxcb) - ((char *) mtxcb_table)) % sizeof(MTXCB) == 0 \
+			&& TMIN_MTXID <= MTXID(p_mtxcb) && MTXID(p_mtxcb) <= tmax_mtxid)
+
+#define VALID_MPFCB(p_mpfcb) \
+		((((char *) p_mpfcb) - ((char *) mpfcb_table)) % sizeof(MPFCB) == 0 \
+			&& TMIN_MPFID <= MPFID(p_mpfcb) && MPFID(p_mpfcb) <= tmax_mpfid)
+
+/*
+ *  キューのチェックのための関数
+ *
+ *  p_queueにp_entryが含まれているかを調べる．含まれていればtrue，含ま
+ *  れていない場合にはfalseを返す．ダブルリンクの不整合の場合にも，
+ *  falseを返す．
+ */
+static bool_t
+in_queue(QUEUE *p_queue, QUEUE *p_entry)
+{
+	QUEUE	*p_current, *p_next;
+
+	p_current = p_queue->p_next;
+	if (p_current->p_prev != p_queue) {
+		return(false);					/* ダブルリンクの不整合 */
+	}
+	while (p_current != p_queue) {
+		if (p_current == p_entry) {
+			return(true);				/* p_entryが含まれていた */
+		}
+
+		/*
+		 *  キューの次の要素に進む
+		 */
+		p_next = p_current->p_next;
+		if (p_next->p_prev != p_current) {
+			return(false);				 /* ダブルリンクの不整合 */
+		}
+		p_current = p_next;
+	}
+	return(false);
+}
+
+/*
+ *  スタック上を指しているかの検査
+ */
+static bool_t
+on_stack(void *addr, const TINIB *p_tinib)
+{
+	if (p_tinib->stk <= addr
+				&& addr < (void *)((char *)(p_tinib->stk) + p_tinib->stksz)) {
+		return(true);
+	}
+	return(false);
+}
+
+/*
+ *  タスク毎の整合性検査
+ */
+static ER
+bit_task(ID tskid)
+{
+	TCB			*p_tcb;
+	const TINIB	*p_tinib;
+	uint_t		tstat, tstat_wait, pri;
+	TMEVTB		*p_tmevtb;
+	SEMCB		*p_semcb;
+	FLGCB		*p_flgcb;
+	DTQCB		*p_dtqcb;
+	PDQCB		*p_pdqcb;
+	MBXCB		*p_mbxcb;
+	MTXCB		*p_mtxcb;
+	MPFCB		*p_mpfcb;
+
+	if (!(TMIN_TSKID <= (tskid) && (tskid) <= tmax_tskid)) {
+		return(E_ID);
+	}
+	p_tcb = get_tcb(tskid);
+	p_tinib = p_tcb->p_tinib;
+	tstat = p_tcb->tstat;
+	tstat_wait = (tstat & TS_WAIT_MASK);
+	pri = p_tcb->priority;
+
+	/*
+	 *  初期化ブロックへのポインタの検査
+	 */
+	if (p_tinib != &(tinib_table[INDEX_TSK(tskid)])) {
+		return(E_SYS_LINENO);
+	}
+
+	/*
+	 *  tstatの検査
+	 */
+	switch (tstat & (TS_RUNNABLE | TS_WAITING | TS_SUSPENDED)) {
+	case TS_DORMANT:
+		if (tstat != TS_DORMANT) {
+			return(E_SYS_LINENO);
+		}
+		break;
+	case TS_RUNNABLE:
+		if (tstat != TS_RUNNABLE) {
+			return(E_SYS_LINENO);
+		}
+		break;
+	case TS_WAITING:
+	case (TS_WAITING | TS_SUSPENDED):
+		if (!(TS_WAIT_DLY <= tstat_wait && tstat_wait <= TS_WAIT_MTX)) {
+			return(E_SYS_LINENO);
+		}
+		if ((tstat & ~(TS_WAIT_MASK | TS_RUNNABLE | TS_WAITING | TS_SUSPENDED))
+																	!= 0U) {
+			return(E_SYS_LINENO);
+		}
+		break;
+	case TS_SUSPENDED:
+		if (tstat != TS_SUSPENDED) {
+			return(E_SYS_LINENO);
+		}
+		break;
+	default:
+		return(E_SYS_LINENO);
+	}
+
+	/*
+	 *  actqueの検査
+	 */
+	if (TSTAT_DORMANT(tstat) && p_tcb->actque) {
+		return(E_SYS_LINENO);
+	}
+
+	/*
+	 *  タスク優先度の検査
+	 */
+	if (pri >= TNUM_TPRI) {
+		return(E_SYS_LINENO);
+	}
+
+	/*
+	 *  texptnの検査
+	 */
+	if (p_tcb->p_tinib->texrtn == NULL && p_tcb->texptn != 0U) {
+		return(E_SYS_LINENO);
+	}
+
+	/*
+	 *  休止状態におけるチェック
+	 */
+	if (TSTAT_DORMANT(tstat)) {
+		if (!(pri == p_tinib->ipriority)
+					&& (p_tcb->wupque == false)
+					&& (p_tcb->enatex == false)
+					&& (p_tcb->texptn == 0U)) {
+			return(E_SYS_LINENO);
+		}
+	}
+
+	/*
+	 *  実行できる状態におけるチェック
+	 */
+	if (TSTAT_RUNNABLE(tstat)) {
+		if (!in_queue(&ready_queue[pri], &(p_tcb->task_queue))) {
+			return(E_SYS_LINENO);
+		}
+	}
+
+	/*
+	 *  待ち状態におけるチェック
+	 */
+	if (TSTAT_WAITING(tstat)) {
+		if (!on_stack(p_tcb->p_winfo, p_tinib)) {
+			return(E_SYS_LINENO);
+		}
+		p_tmevtb = p_tcb->p_winfo->p_tmevtb;
+		if (p_tmevtb != NULL) {
+			if (!on_stack(p_tmevtb, p_tinib)) {
+				return(E_SYS_LINENO);
+			}
+			/*
+			 *  (*p_tmevtb)の検査（未完成）
+			 */
+		}
+
+		switch (tstat & TS_WAIT_MASK) {
+			case TS_WAIT_SLP:
+				if (p_tcb->wupque == true) {
+					return(E_SYS_LINENO);
+				}
+				break;
+
+			case TS_WAIT_DLY:
+				if (p_tmevtb == NULL) {
+					return(E_SYS_LINENO);
+				}
+				break;
+
+			case TS_WAIT_SEM:
+				p_semcb = ((WINFO_SEM *)(p_tcb->p_winfo))->p_semcb;
+				if (!VALID_SEMCB(p_semcb)) {
+					return(E_SYS_LINENO);
+				}
+				if (!in_queue(&(p_semcb->wait_queue), &(p_tcb->task_queue))) {
+					return(E_SYS_LINENO);
+				}
+				break;
+
+			case TS_WAIT_FLG:
+				p_flgcb = ((WINFO_FLG *)(p_tcb->p_winfo))->p_flgcb;
+				if (!VALID_FLGCB(p_flgcb)) {
+					return(E_SYS_LINENO);
+				}
+				if (!in_queue(&(p_flgcb->wait_queue), &(p_tcb->task_queue))) {
+					return(E_SYS_LINENO);
+				}
+				break;
+
+			case TS_WAIT_SDTQ:
+				p_dtqcb = ((WINFO_DTQ *)(p_tcb->p_winfo))->p_dtqcb;
+				if (!VALID_DTQCB(p_dtqcb)) {
+					return(E_SYS_LINENO);
+				}
+				if (!in_queue(&(p_dtqcb->swait_queue), &(p_tcb->task_queue))) {
+					return(E_SYS_LINENO);
+				}
+				break;
+
+			case TS_WAIT_RDTQ:
+				p_dtqcb = ((WINFO_DTQ *)(p_tcb->p_winfo))->p_dtqcb;
+				if (!VALID_DTQCB(p_dtqcb)) {
+					return(E_SYS_LINENO);
+				}
+				if (!in_queue(&(p_dtqcb->rwait_queue), &(p_tcb->task_queue))) {
+					return(E_SYS_LINENO);
+				}
+				break;
+
+			case TS_WAIT_SPDQ:
+				p_pdqcb = ((WINFO_PDQ *)(p_tcb->p_winfo))->p_pdqcb;
+				if (!VALID_PDQCB(p_pdqcb)) {
+					return(E_SYS_LINENO);
+				}
+				if (!in_queue(&(p_pdqcb->swait_queue), &(p_tcb->task_queue))) {
+					return(E_SYS_LINENO);
+				}
+				break;
+
+			case TS_WAIT_RPDQ:
+				p_pdqcb = ((WINFO_PDQ *)(p_tcb->p_winfo))->p_pdqcb;
+				if (!VALID_PDQCB(p_pdqcb)) {
+					return(E_SYS_LINENO);
+				}
+				if (!in_queue(&(p_pdqcb->rwait_queue), &(p_tcb->task_queue))) {
+					return(E_SYS_LINENO);
+				}
+				break;
+
+			case TS_WAIT_MBX:
+				p_mbxcb = ((WINFO_MBX *)(p_tcb->p_winfo))->p_mbxcb;
+				if (!VALID_MBXCB(p_mbxcb)) {
+					return(E_SYS_LINENO);
+				}
+				if (!in_queue(&(p_mbxcb->wait_queue), &(p_tcb->task_queue))) {
+					return(E_SYS_LINENO);
+				}
+				break;
+
+			case TS_WAIT_MTX:
+				p_mtxcb = ((WINFO_MTX *)(p_tcb->p_winfo))->p_mtxcb;
+				if (!VALID_MTXCB(p_mtxcb)) {
+					return(E_SYS_LINENO);
+				}
+				if (!in_queue(&(p_mtxcb->wait_queue), &(p_tcb->task_queue))) {
+					return(E_SYS_LINENO);
+				}
+				break;
+
+			case TS_WAIT_MPF:
+				p_mpfcb = ((WINFO_MPF *)(p_tcb->p_winfo))->p_mpfcb;
+				if (!VALID_MPFCB(p_mpfcb)) {
+					return(E_SYS_LINENO);
+				}
+				if (!in_queue(&(p_mpfcb->wait_queue), &(p_tcb->task_queue))) {
+					return(E_SYS_LINENO);
+				}
+				break;
+		}
+	}
+
+	/*
+	 *  tskctxbの検査
+	 */
+	if (!TSTAT_DORMANT(tstat) && p_tcb != p_runtsk) {
+		/*
+		 *  ターゲット依存の検査
+		 */
+#if 0
+		if (bit_tskctxb(&(p_tcb->tskctxb))) {
+			return(E_SYS_LINENO);
+		}
+#endif
+	}
+	return(E_OK);
+}
+
+/*
+ *  セマフォ毎の整合性検査
+ */
+#define INDEX_SEM(semid)	((uint_t)((semid) - TMIN_SEMID))
+#define get_semcb(semid)	(&(semcb_table[INDEX_SEM(semid)]))
+
+static ER
+bit_semaphore(ID semid)
+{
+	SEMCB			*p_semcb;
+	const SEMINIB	*p_seminib;
+	uint_t			semcnt;
+	QUEUE			*p_queue;
+	TCB				*p_tcb;
+
+	if (!(TMIN_SEMID <= (semid) && (semid) <= tmax_semid)) {
+		return(E_ID);
+	}
+	p_semcb = get_semcb(semid);
+	p_seminib = p_semcb->p_seminib;
+	semcnt = p_semcb->semcnt;
+
+	/*
+	 *  初期化ブロックへのポインタの検査
+	 */
+	if (p_seminib != &(seminib_table[INDEX_SEM(semid)])) {
+		return(E_SYS_LINENO);
+	}
+
+	/*
+	 *  semcntの検査
+	 */
+	if (semcnt > p_seminib->maxsem) {
+		return(E_SYS_LINENO);
+	}
+
+	/*
+	 *  wait_queueの検査
+	 */
+	if (semcnt == 0) {
+		p_queue = p_semcb->wait_queue.p_next;
+		while (p_queue != &(p_semcb->wait_queue)) {
+			p_tcb = (TCB *) p_queue;
+			p_queue = p_queue->p_next;
+			if (!VALID_TCB(p_tcb)) {
+				return(E_SYS_LINENO);
+			}
+			if (p_tcb->tstat != (TS_WAITING | TS_WAIT_SEM)) {
+				return(E_SYS_LINENO);
+			}
+			if (p_semcb != ((WINFO_SEM *)(p_tcb->p_winfo))->p_semcb) {
+				return(E_SYS_LINENO);
+			}
+		}
+	}
+	else {
+		if (!queue_empty(&(p_semcb->wait_queue))) {
+			return(E_SYS_LINENO);
+		}
+	}
+	return(E_OK);
+}
+
+/*
+ *  整合性検査ルーチン本体
+ */
+ER
+bit_kernel(void)
+{
+	ID		tskid;
+	ID		semid;
+	ER		ercd;
+
+	/*
+	 *  タスク毎の検査
+	 */
+	for (tskid = TMIN_TSKID; tskid <= tmax_tskid; tskid++) {
+		ercd = bit_task(tskid);
+		if (ercd != E_OK) {
+			return(ercd);
+		}
+	}
+
+	/*
+	 *  セマフォ毎の検査
+	 */
+	for (semid = TMIN_SEMID; semid <= tmax_semid; semid++) {
+		ercd = bit_semaphore(semid);
+		if (ercd != E_OK) {
+			return(ercd);
+		}
+	}
+
+	return(E_OK);
+}
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/test/perf0.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/test/perf0.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/test/perf0.c	(revision 457)
@@ -0,0 +1,83 @@
+/*
+ *  TOPPERS Software
+ *      Toyohashi Open Platform for Embedded Real-Time Systems
+ * 
+ *  Copyright (C) 2006-2009 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *		カーネル性能評価プログラム(0)
+ *
+ *  時間計測のオーバヘッドを計測するためのプログラム．
+ */
+
+#include <kernel.h>
+#include <t_syslog.h>
+#include <test_lib.h>
+#include <histogram.h>
+#include "kernel_cfg.h"
+#include "perf0.h"
+
+/*
+ *  計測回数と実行時間分布を記録する最大時間
+ */
+#define NO_MEASURE	10000U			/* 計測回数 */
+#define MAX_TIME	1000U			/* 実行時間分布を記録する最大時間 */
+
+/*
+ *  実行時間分布を記録するメモリ領域
+ */
+static uint_t	histarea1[MAX_TIME + 1];
+
+/*
+ *  メインタスク
+ */
+void main_task(intptr_t exinf)
+{
+	uint_t	i;
+
+	syslog_0(LOG_NOTICE, "Performance evaluation program (0)");
+	init_hist(1, MAX_TIME, histarea1);
+	syslog_flush();
+
+	for (i = 0; i < NO_MEASURE; i++) {
+		begin_measure(1);
+		end_measure(1);
+	}
+
+	syslog_0(LOG_NOTICE, "Measurement overhead");
+	print_hist(1);
+	test_finish();
+}
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/test/perf0.cfg
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/test/perf0.cfg	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/test/perf0.cfg	(revision 457)
@@ -0,0 +1,14 @@
+/*
+ *  @(#) $Id$
+ */
+
+/*
+ *  カーネル性能評価プログラム(0)のシステムコンフィギュレーションファイル
+ */
+INCLUDE("target_timer.cfg");
+INCLUDE("syssvc/syslog.cfg");
+INCLUDE("syssvc/banner.cfg");
+INCLUDE("syssvc/serial.cfg");
+
+#include "perf0.h"
+CRE_TSK(MAIN_TASK, { TA_ACT, 0, main_task, MAIN_PRIORITY, STACK_SIZE, NULL });
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/test/perf0.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/test/perf0.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/test/perf0.h	(revision 457)
@@ -0,0 +1,64 @@
+/*
+ *  TOPPERS Software
+ *      Toyohashi Open Platform for Embedded Real-Time Systems
+ * 
+ *  Copyright (C) 2006,2007 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *		カーネル性能評価プログラム(0)
+ */
+
+/*
+ *  ターゲット依存の定義
+ */
+#include "target_test.h"
+
+/*
+ *  各タスクの優先度の定義
+ */
+#define MAIN_PRIORITY	11		/* メインタスクの優先度 */
+
+/*
+ *  ターゲットに依存する可能性のある定数の定義
+ */
+#ifndef STACK_SIZE
+#define	STACK_SIZE		4096		/* タスクのスタックサイズ */
+#endif /* STACK_SIZE */
+
+/*
+ *  関数のプロトタイプ宣言
+ */
+extern void	main_task(intptr_t exinf);
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/test/perf1.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/test/perf1.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/test/perf1.c	(revision 457)
@@ -0,0 +1,116 @@
+/*
+ *  TOPPERS Software
+ *      Toyohashi Open Platform for Embedded Real-Time Systems
+ * 
+ *  Copyright (C) 2006-2009 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *		カーネル性能評価プログラム(1)
+ *
+ *  slp_tsk，wup_tskによるタスク切換え時間を計測するためのプログラム．
+ */
+
+#include <kernel.h>
+#include <t_syslog.h>
+#include <test_lib.h>
+#include <histogram.h>
+#include "kernel_cfg.h"
+#include "perf1.h"
+
+/*
+ *  計測回数と実行時間分布を記録する最大時間
+ */
+#define NO_MEASURE	10000U			/* 計測回数 */
+#define MAX_TIME	1000U			/* 実行時間分布を記録する最大時間 */
+
+/*
+ *  実行時間分布を記録するメモリ領域
+ */
+static uint_t	histarea1[MAX_TIME + 1];
+static uint_t	histarea2[MAX_TIME + 1];
+
+/*
+ *  計測タスク1（高優先度）
+ */
+void task1(intptr_t exinf)
+{
+	uint_t	i;
+
+	slp_tsk();
+	end_measure(1);
+	for (i = 1; i < NO_MEASURE; i++) {
+		begin_measure(2);
+		slp_tsk();
+		end_measure(1);
+	}
+	begin_measure(2);
+	slp_tsk();
+}
+
+/*
+ *  計測タスク2（中優先度）
+ */
+void task2(intptr_t exinf)
+{
+	uint_t	i;
+
+	for (i = 0; i < NO_MEASURE; i++) {
+		begin_measure(1);
+		wup_tsk(TASK1);
+		end_measure(2);
+	}
+	wup_tsk(TASK1);
+}
+
+/*
+ *  メインタスク（低優先度）
+ */
+void main_task(intptr_t exinf)
+{
+	syslog_0(LOG_NOTICE, "Performance evaluation program (1)");
+	init_hist(1, MAX_TIME, histarea1);
+	init_hist(2, MAX_TIME, histarea2);
+	syslog_flush();
+
+	act_tsk(TASK1);
+	act_tsk(TASK2);
+
+	syslog_0(LOG_NOTICE, "Execution times of wup_tsk -> slp_tsk");
+	print_hist(1);
+	syslog_0(LOG_NOTICE, "Execution times of slp_tsk -> wup_tsk");
+	print_hist(2);
+	test_finish();
+}
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/test/perf1.cfg
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/test/perf1.cfg	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/test/perf1.cfg	(revision 457)
@@ -0,0 +1,16 @@
+/*
+ *  @(#) $Id$
+ */
+
+/*
+ *  カーネル性能評価プログラム(1)のシステムコンフィギュレーションファイル
+ */
+INCLUDE("target_timer.cfg");
+INCLUDE("syssvc/syslog.cfg");
+INCLUDE("syssvc/banner.cfg");
+INCLUDE("syssvc/serial.cfg");
+
+#include "perf1.h"
+CRE_TSK(TASK1, { TA_NULL, 1, task1, TASK1_PRIORITY, STACK_SIZE, NULL });
+CRE_TSK(TASK2, { TA_NULL, 2, task2, TASK2_PRIORITY, STACK_SIZE, NULL });
+CRE_TSK(MAIN_TASK, { TA_ACT, 0, main_task, MAIN_PRIORITY, STACK_SIZE, NULL });
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/test/perf1.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/test/perf1.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/test/perf1.h	(revision 457)
@@ -0,0 +1,68 @@
+/*
+ *  TOPPERS Software
+ *      Toyohashi Open Platform for Embedded Real-Time Systems
+ * 
+ *  Copyright (C) 2006,2007 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *		カーネル性能評価プログラム(1)
+ */
+
+/*
+ *  ターゲット依存の定義
+ */
+#include "target_test.h"
+
+/*
+ *  各タスクの優先度の定義
+ */
+#define TASK1_PRIORITY	9		/* 計測タスク1の優先度 */
+#define TASK2_PRIORITY	10		/* 計測タスク2の優先度 */
+#define MAIN_PRIORITY	11		/* メインタスクの優先度 */
+
+/*
+ *  ターゲットに依存する可能性のある定数の定義
+ */
+#ifndef STACK_SIZE
+#define	STACK_SIZE		4096		/* タスクのスタックサイズ */
+#endif /* STACK_SIZE */
+
+/*
+ *  関数のプロトタイプ宣言
+ */
+extern void	task1(intptr_t exinf);
+extern void	task2(intptr_t exinf);
+extern void	main_task(intptr_t exinf);
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/test/perf2.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/test/perf2.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/test/perf2.c	(revision 457)
@@ -0,0 +1,115 @@
+/*
+ *  TOPPERS Software
+ *      Toyohashi Open Platform for Embedded Real-Time Systems
+ * 
+ *  Copyright (C) 2007-2009 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *		カーネル性能評価プログラム(2)
+ *
+ *  優先度データキューに蓄積されているデータの数により，snd_pdqの処理時
+ *  間がどのように変化するかを計測するためのプログラム．
+ */
+
+#include <kernel.h>
+#include <t_syslog.h>
+#include <test_lib.h>
+#include <histogram.h>
+#include "kernel_cfg.h"
+#include "perf2.h"
+
+/*
+ *  計測回数と実行時間分布を記録する最大時間
+ */
+#define NO_MEASURE	10000U			/* 計測回数 */
+#define MAX_TIME	1000U			/* 実行時間分布を記録する最大時間 */
+
+/*
+ *  実行時間分布を記録するメモリ領域
+ */
+static uint_t	histarea1[MAX_TIME + 1];
+
+/*
+ *  計測ルーチン
+ */
+void
+perf_eval(uint_t n)
+{
+	uint_t		i;
+	intptr_t	data;
+	PRI			pri;
+
+	ini_pdq(PDQ1);
+	init_hist(1, MAX_TIME, histarea1);
+
+	for (i = 0; i < n; i++) {
+		data = i;
+		snd_pdq(PDQ1, data, 1);
+	}
+
+	for (i = 0; i < NO_MEASURE; i++) {
+		data = i;
+		begin_measure(1);
+		snd_pdq(PDQ1, data, 2);
+		end_measure(1);
+		rcv_pdq(PDQ1, &data, &pri);
+	}
+
+	syslog_1(LOG_NOTICE, "Execution times of snd_pdq"
+								" when %d data are queued.", n);
+	print_hist(1);
+	syslog_flush();
+}
+
+/*
+ *  メインタスク（低優先度）
+ */
+void main_task(intptr_t exinf)
+{
+	syslog_0(LOG_NOTICE, "Performance evaluation program (2)");
+	syslog_flush();
+
+	perf_eval(0);
+	perf_eval(10);
+	perf_eval(20);
+	perf_eval(30);
+	perf_eval(40);
+	perf_eval(50);
+	perf_eval(100);
+	perf_eval(200);
+	perf_eval(300);
+	test_finish();
+}
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/test/perf2.cfg
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/test/perf2.cfg	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/test/perf2.cfg	(revision 457)
@@ -0,0 +1,15 @@
+/*
+ *  @(#) $Id$
+ */
+
+/*
+ *  カーネル性能評価プログラム(2)のシステムコンフィギュレーションファイル
+ */
+INCLUDE("target_timer.cfg");
+INCLUDE("syssvc/syslog.cfg");
+INCLUDE("syssvc/banner.cfg");
+INCLUDE("syssvc/serial.cfg");
+
+#include "perf2.h"
+CRE_TSK(MAIN_TASK, { TA_ACT, 0, main_task, MAIN_PRIORITY, STACK_SIZE, NULL });
+CRE_PDQ(PDQ1, { TA_NULL, 301, 16, NULL });
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/test/perf2.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/test/perf2.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/test/perf2.h	(revision 457)
@@ -0,0 +1,64 @@
+/*
+ *  TOPPERS Software
+ *      Toyohashi Open Platform for Embedded Real-Time Systems
+ * 
+ *  Copyright (C) 2007 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *		カーネル性能評価プログラム(2)
+ */
+
+/*
+ *  ターゲット依存の定義
+ */
+#include "target_test.h"
+
+/*
+ *  各タスクの優先度の定義
+ */
+#define MAIN_PRIORITY	11		/* メインタスクの優先度 */
+
+/*
+ *  ターゲットに依存する可能性のある定数の定義
+ */
+#ifndef STACK_SIZE
+#define	STACK_SIZE		4096		/* タスクのスタックサイズ */
+#endif /* STACK_SIZE */
+
+/*
+ *  関数のプロトタイプ宣言
+ */
+extern void	main_task(intptr_t exinf);
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/test/perf3.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/test/perf3.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/test/perf3.c	(revision 457)
@@ -0,0 +1,136 @@
+/*
+ *  TOPPERS Software
+ *      Toyohashi Open Platform for Embedded Real-Time Systems
+ * 
+ *  Copyright (C) 2007-2009 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *		カーネル性能評価プログラム(3)
+ *
+ *  待ち解除するタスクの数により，set_flgの処理時間がどのように変化する
+ *  かを計測するためのプログラム．
+ */
+
+#include <kernel.h>
+#include <t_syslog.h>
+#include <test_lib.h>
+#include <histogram.h>
+#include "kernel_cfg.h"
+#include "perf3.h"
+
+/*
+ *  計測回数と実行時間分布を記録する最大時間
+ */
+#define NO_MEASURE	10000U			/* 計測回数 */
+#define MAX_TIME	1000U			/* 実行時間分布を記録する最大時間 */
+
+/*
+ *  実行時間分布を記録するメモリ領域
+ */
+static uint_t	histarea1[MAX_TIME + 1];
+
+/*
+ *  計測タスクのリスト
+ */
+static ID task_list[20] = {
+	TASK1, TASK2, TASK3, TASK4, TASK5,
+	TASK6, TASK7, TASK8, TASK9, TASK10,
+	TASK11, TASK12, TASK13, TASK14, TASK15,
+	TASK16, TASK17, TASK18, TASK19, TASK20
+};
+
+/*
+ *  計測タスク（中優先度）
+ */
+void task(intptr_t exinf)
+{
+	FLGPTN	flgptn;
+
+	wai_flg(FLG1, 0x01U, TWF_ORW, &flgptn);
+}
+
+/*
+ *  計測ルーチン
+ */
+void
+perf_eval(uint_t n)
+{
+	uint_t		i, j;
+
+	init_hist(1, MAX_TIME, histarea1);
+
+	for (i = 0; i < NO_MEASURE; i++) {
+		ini_flg(FLG1);
+		for (j = 0; j < n; j++) {
+			act_tsk(task_list[j]);
+		}
+		chg_pri(TSK_SELF, MAIN_PRIORITY_LOW);
+		/* タスクが待ち状態に入るのを待つ */
+		chg_pri(TSK_SELF, TPRI_INI);
+
+		begin_measure(1);
+		set_flg(FLG1, 0x01U);
+		end_measure(1);
+
+		chg_pri(TSK_SELF, MAIN_PRIORITY_LOW);
+		/* タスクが終了するのを待つ */
+		chg_pri(TSK_SELF, TPRI_INI);
+	}
+
+	syslog_1(LOG_NOTICE, "Execution times of set_flg"
+							" when %d tasks are released from waiting.", n);
+	print_hist(1);
+	syslog_flush();
+}
+
+/*
+ *  メインタスク（高優先度）
+ */
+void main_task(intptr_t exinf)
+{
+	syslog_0(LOG_NOTICE, "Performance evaluation program (3)");
+	syslog_flush();
+
+	perf_eval(0);
+	perf_eval(1);
+	perf_eval(2);
+	perf_eval(3);
+	perf_eval(4);
+	perf_eval(5);
+	perf_eval(10);
+	perf_eval(20);
+	test_finish();
+}
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/test/perf3.cfg
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/test/perf3.cfg	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/test/perf3.cfg	(revision 457)
@@ -0,0 +1,35 @@
+/*
+ *  @(#) $Id$
+ */
+
+/*
+ *  カーネル性能評価プログラム(3)のシステムコンフィギュレーションファイル
+ */
+INCLUDE("target_timer.cfg");
+INCLUDE("syssvc/syslog.cfg");
+INCLUDE("syssvc/banner.cfg");
+INCLUDE("syssvc/serial.cfg");
+
+#include "perf3.h"
+CRE_TSK(TASK1, { TA_NULL, 1, task, TASK_PRIORITY, STACK_SIZE, NULL });
+CRE_TSK(TASK2, { TA_NULL, 2, task, TASK_PRIORITY, STACK_SIZE, NULL });
+CRE_TSK(TASK3, { TA_NULL, 3, task, TASK_PRIORITY, STACK_SIZE, NULL });
+CRE_TSK(TASK4, { TA_NULL, 4, task, TASK_PRIORITY, STACK_SIZE, NULL });
+CRE_TSK(TASK5, { TA_NULL, 5, task, TASK_PRIORITY, STACK_SIZE, NULL });
+CRE_TSK(TASK6, { TA_NULL, 6, task, TASK_PRIORITY, STACK_SIZE, NULL });
+CRE_TSK(TASK7, { TA_NULL, 7, task, TASK_PRIORITY, STACK_SIZE, NULL });
+CRE_TSK(TASK8, { TA_NULL, 8, task, TASK_PRIORITY, STACK_SIZE, NULL });
+CRE_TSK(TASK9, { TA_NULL, 9, task, TASK_PRIORITY, STACK_SIZE, NULL });
+CRE_TSK(TASK10, { TA_NULL, 10, task, TASK_PRIORITY, STACK_SIZE, NULL });
+CRE_TSK(TASK11, { TA_NULL, 11, task, TASK_PRIORITY, STACK_SIZE, NULL });
+CRE_TSK(TASK12, { TA_NULL, 12, task, TASK_PRIORITY, STACK_SIZE, NULL });
+CRE_TSK(TASK13, { TA_NULL, 13, task, TASK_PRIORITY, STACK_SIZE, NULL });
+CRE_TSK(TASK14, { TA_NULL, 14, task, TASK_PRIORITY, STACK_SIZE, NULL });
+CRE_TSK(TASK15, { TA_NULL, 15, task, TASK_PRIORITY, STACK_SIZE, NULL });
+CRE_TSK(TASK16, { TA_NULL, 16, task, TASK_PRIORITY, STACK_SIZE, NULL });
+CRE_TSK(TASK17, { TA_NULL, 17, task, TASK_PRIORITY, STACK_SIZE, NULL });
+CRE_TSK(TASK18, { TA_NULL, 18, task, TASK_PRIORITY, STACK_SIZE, NULL });
+CRE_TSK(TASK19, { TA_NULL, 19, task, TASK_PRIORITY, STACK_SIZE, NULL });
+CRE_TSK(TASK20, { TA_NULL, 20, task, TASK_PRIORITY, STACK_SIZE, NULL });
+CRE_TSK(MAIN_TASK, { TA_ACT, 0, main_task, MAIN_PRIORITY, STACK_SIZE, NULL });
+CRE_FLG(FLG1, { TA_WMUL, 0x00U });
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/test/perf3.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/test/perf3.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/test/perf3.h	(revision 457)
@@ -0,0 +1,67 @@
+/*
+ *  TOPPERS Software
+ *      Toyohashi Open Platform for Embedded Real-Time Systems
+ * 
+ *  Copyright (C) 2007 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *		カーネル性能評価プログラム(3)
+ */
+
+/*
+ *  ターゲット依存の定義
+ */
+#include "target_test.h"
+
+/*
+ *  各タスクの優先度の定義
+ */
+#define TASK_PRIORITY		10		/* タスクの優先度 */
+#define MAIN_PRIORITY		9		/* メインタスクの優先度 */
+#define MAIN_PRIORITY_LOW	11		/* メインタスクの低優先度 */
+
+/*
+ *  ターゲットに依存する可能性のある定数の定義
+ */
+#ifndef STACK_SIZE
+#define	STACK_SIZE		4096		/* タスクのスタックサイズ */
+#endif /* STACK_SIZE */
+
+/*
+ *  関数のプロトタイプ宣言
+ */
+extern void	task(intptr_t exinf);
+extern void	main_task(intptr_t exinf);
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/test/perf4.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/test/perf4.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/test/perf4.c	(revision 457)
@@ -0,0 +1,179 @@
+/*
+ *  TOPPERS Software
+ *      Toyohashi Open Platform for Embedded Real-Time Systems
+ * 
+ *  Copyright (C) 2006-2009 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *		カーネル性能評価プログラム(4)
+ *
+ *  act_tsk，iact_tskの処理時間とタスク切換え時間を計測するためのプログ
+ *  ラム．以下の3つの時間を測定する．
+ *
+ *  (1) タスク切換えを起こさないact_tskの処理時間．自タスクよりも優先度
+ *      の低いタスクに対してact_tskを発行し，休止状態から実行できる状態
+ *      に遷移させる処理の時間．
+ *
+ *  (2) タスク切換えを起こすact_tskの処理時間．自タスクよりも優先度の高
+ *      いタスクに対してact_tskを発行し，休止状態から実行できる状態に遷
+ *      移させ，タスク切換えを起こして，高い優先度のタスクの実行が始ま
+ *      るまでの時間．
+ *
+ *  (3) タスク切換えを起こすiact_tskの処理時間．周期ハンドラから，実行
+ *      状態のタスクよりも高い優先度のタスクに対してact_tskを発行し，休
+ *      止状態から実行できる状態に遷移させたあとに周期ハンドラからリター
+ *      ンし，タスク切換えを起こして，高い優先度のタスクの実行が始まる
+ *      までの時間．
+ */
+
+#include <kernel.h>
+#include <t_syslog.h>
+#include <test_lib.h>
+#include <histogram.h>
+#include "kernel_cfg.h"
+#include "perf4.h"
+
+/*
+ *  計測回数と実行時間分布を記録する最大時間
+ */
+#define NO_MEASURE	10000U			/* 計測回数 */
+#define MAX_TIME	1000U			/* 実行時間分布を記録する最大時間 */
+
+/*
+ *  実行時間分布を記録するメモリ領域
+ */
+static uint_t	histarea1[MAX_TIME + 1];
+static uint_t	histarea2[MAX_TIME + 1];
+static uint_t	histarea3[MAX_TIME + 1];
+
+/*
+ *  計測タスク1（高優先度）
+ */
+void task1(intptr_t exinf)
+{
+	end_measure(2);
+	ext_tsk();
+}
+
+/*
+ *  計測タスク2とメインタスクの共有変数
+ */
+volatile uint_t		task2_count;
+
+/*
+ *  計測タスク2（高優先度）
+ */
+void task2(intptr_t exinf)
+{
+	end_measure(3);
+	task2_count++;
+	ext_tsk();
+}
+
+/*
+ *  計測タスク3（低優先度）
+ */
+void task3(intptr_t exinf)
+{
+	ext_tsk();
+}
+
+/*
+ *  計測タスク4（最低優先度）
+ */
+void task4(intptr_t exinf)
+{
+	while (true) {
+		wup_tsk(MAIN_TASK);
+	}
+}
+
+/*
+ *  周期ハンドラ
+ */
+void cyclic_handler(intptr_t exinf)
+{
+	begin_measure(3);
+	iact_tsk(TASK2);
+}
+
+/*
+ *  メインタスク（中優先度）
+ */
+void main_task(intptr_t exinf)
+{
+	uint_t	i;
+
+	syslog_0(LOG_NOTICE, "Performance evaluation program (4)");
+	init_hist(1, MAX_TIME, histarea1);
+	init_hist(2, MAX_TIME, histarea2);
+	init_hist(3, MAX_TIME, histarea3);
+	syslog_flush();
+
+	/*
+	 *  タスク切換えを起こさないact_tskの処理時間の測定
+	 */
+	for (i = 0; i < NO_MEASURE; i++) {
+		begin_measure(1);
+		act_tsk(TASK3);
+		end_measure(1);
+		slp_tsk();
+	}
+
+	/*
+	 *  タスク切換えを起こすact_tskの処理時間の測定
+	 */
+	for (i = 0; i < NO_MEASURE; i++) {
+		begin_measure(2);
+		act_tsk(TASK1);
+	}
+
+	/*
+	 *  タスク切換えを起こすiact_tskの処理時間の測定（測定回数は10分の1）
+	 */
+	task2_count = 0;
+	sta_cyc(CYC1);
+	while (task2_count < NO_MEASURE / 10) ;
+	stp_cyc(CYC1);
+
+	syslog_0(LOG_NOTICE, "Execution times of act_tsk without task switch");
+	print_hist(1);
+	syslog_0(LOG_NOTICE, "Execution times of act_tsk with task switch");
+	print_hist(2);
+	syslog_0(LOG_NOTICE, "Execution times of iact_tsk with task switch");
+	print_hist(3);
+	test_finish();
+}
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/test/perf4.cfg
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/test/perf4.cfg	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/test/perf4.cfg	(revision 457)
@@ -0,0 +1,21 @@
+/*
+ *  @(#) $Id$
+ */
+
+/*
+ *  カーネル性能評価プログラム(4)のシステムコンフィギュレーションファイル
+ */
+INCLUDE("target_timer.cfg");
+INCLUDE("syssvc/syslog.cfg");
+INCLUDE("syssvc/banner.cfg");
+INCLUDE("syssvc/serial.cfg");
+
+#include "perf4.h"
+CRE_TSK(TASK1, { TA_NULL, 1, task1, TASK1_PRIORITY, STACK_SIZE, NULL });
+CRE_TSK(TASK2, { TA_NULL, 2, task2, TASK2_PRIORITY, STACK_SIZE, NULL });
+CRE_TSK(TASK3, { TA_NULL, 3, task3, TASK3_PRIORITY, STACK_SIZE, NULL });
+CRE_TSK(TASK4, { TA_ACT, 4, task4, TASK4_PRIORITY, STACK_SIZE, NULL });
+CRE_CYC(CYC1, { TA_NULL, 0, cyclic_handler,
+					(TIC_NUME + TIC_DENO - 1) / TIC_DENO,
+					(TIC_NUME + TIC_DENO - 1) / TIC_DENO });
+CRE_TSK(MAIN_TASK, { TA_ACT, 0, main_task, MAIN_PRIORITY, STACK_SIZE, NULL });
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/test/perf4.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/test/perf4.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/test/perf4.h	(revision 457)
@@ -0,0 +1,73 @@
+/*
+ *  TOPPERS Software
+ *      Toyohashi Open Platform for Embedded Real-Time Systems
+ * 
+ *  Copyright (C) 2006-2009 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *		カーネル性能評価プログラム(4)
+ */
+
+/*
+ *  ターゲット依存の定義
+ */
+#include "target_test.h"
+
+/*
+ *  各タスクの優先度の定義
+ */
+#define TASK1_PRIORITY	9		/* 計測タスク1の優先度 */
+#define TASK2_PRIORITY	9		/* 計測タスク2の優先度 */
+#define TASK3_PRIORITY	11		/* 計測タスク3の優先度 */
+#define TASK4_PRIORITY	12		/* 計測タスク4の優先度 */
+#define MAIN_PRIORITY	10		/* メインタスクの優先度 */
+
+/*
+ *  ターゲットに依存する可能性のある定数の定義
+ */
+#ifndef STACK_SIZE
+#define	STACK_SIZE		4096		/* タスクのスタックサイズ */
+#endif /* STACK_SIZE */
+
+/*
+ *  関数のプロトタイプ宣言
+ */
+extern void	task1(intptr_t exinf);
+extern void	task2(intptr_t exinf);
+extern void	task3(intptr_t exinf);
+extern void	task4(intptr_t exinf);
+extern void	cyclic_handler(intptr_t exinf);
+extern void	main_task(intptr_t exinf);
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/test/test_cpuexc.cfg
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/test/test_cpuexc.cfg	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/test/test_cpuexc.cfg	(revision 457)
@@ -0,0 +1,22 @@
+/*
+ *  @(#) $Id$
+ */
+
+/*
+ *  CPU例外処理のテスト(1)～(13)のシステムコンフィギュレーションファイル
+ */
+INCLUDE("target_timer.cfg");
+INCLUDE("syssvc/syslog.cfg");
+INCLUDE("syssvc/banner.cfg");
+INCLUDE("syssvc/serial.cfg");
+
+#include "test_cpuexc.h"
+
+CRE_TSK(TASK1, { TA_ACT, 1, task1, MID_PRIORITY, STACK_SIZE, NULL });
+DEF_TEX(TASK1, { TA_NULL, tex_task1 });
+
+CRE_TSK(TASK2, { TA_NULL, 2, task2, HIGH_PRIORITY, STACK_SIZE, NULL });
+
+CRE_ALM(ALM1, { TA_NULL, 1, alarm1_handler });
+
+DEF_EXC(CPUEXC1, { TA_NULL, cpuexc_handler });
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/test/test_cpuexc.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/test/test_cpuexc.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/test/test_cpuexc.h	(revision 457)
@@ -0,0 +1,76 @@
+/*
+ *  TOPPERS Software
+ *      Toyohashi Open Platform for Embedded Real-Time Systems
+ * 
+ *  Copyright (C) 2007 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/* 
+ *		CPU例外処理のテスト(1)～(13)
+ */
+
+/*
+ *  ターゲット依存の定義
+ */
+#include "target_test.h"
+
+/*
+ *  各タスクの優先度の定義
+ */
+#define HIGH_PRIORITY	9		/* 高優先度 */
+#define MID_PRIORITY	10		/* 中優先度 */
+
+/*
+ *  ターゲットに依存する可能性のある定数の定義
+ */
+#ifndef STACK_SIZE
+#define	STACK_SIZE		4096		/* タスクのスタックサイズ */
+#endif /* STACK_SIZE */
+
+/*
+ *  関数のプロトタイプ宣言
+ */
+#ifndef TOPPERS_MACRO_ONLY
+
+extern void	task1(intptr_t exinf);
+extern void	tex_task1(TEXPTN texptn, intptr_t exinf);
+
+extern void	task2(intptr_t exinf);
+
+extern void	alarm1_handler(intptr_t exinf);
+
+extern void	cpuexc_handler(void *p_excinf);
+
+#endif /* TOPPERS_MACRO_ONLY */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/test/test_cpuexc.txt
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/test/test_cpuexc.txt	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/test/test_cpuexc.txt	(revision 457)
@@ -0,0 +1,127 @@
+
+		CPU例外処理のテスト
+
+【テストの目的】
+
+CPU例外ハンドラの実行開始／リターン時のシステム状態と，CPU例外ハンドラ
+中でのxsns_dpnとxsns_xpnの動作を網羅的にテストする．
+
+【テスト項目】
+
+(A) CPU例外ハンドラ実行開始時にCPUロックフラグが変化しないこと
+
+(B) CPU例外ハンドラ実行開始時に割込み優先度マスクが変化しないこと
+	！CPU例外ハンドラ中で割込み優先度マスクを読めないため，テストできな
+	　い．
+
+(C) CPU例外ハンドラ実行開始時にディスパッチ禁止フラグが変化しないこと
+
+(D) CPU例外ハンドラ実行開始時にタスク例外処理禁止フラグが変化しないこと
+
+(E) CPU例外ハンドラリターン時にCPUロックフラグが元に戻ること
+
+(F) CPU例外ハンドラリターン時に割込み優先度マスクが元に戻ること
+
+(G) CPU例外ハンドラリターン時にディスパッチ禁止フラグが変化しないこと
+
+(H) CPU例外ハンドラリターン時にタスク例外処理禁止フラグが変化しないこと
+
+(I) xsns_xpnが正しい値を返すこと
+
+xsns_xpnは，CPU例外が発生した状況が次の条件をすべて満たす場合にfalse，
+そうでない場合にtrueを返す．
+　・タスクコンテキスト
+　・割込みロック解除状態
+　・CPUロック解除状態
+　・割込み優先度マスク全解除状態
+　・タスク例外許可状態
+
+(J) xsns_dpnが正しい値を返すこと
+
+xsns_dpnは，CPU例外が発生した状況が次の条件をすべて満たす場合にfalse，
+そうでない場合にtrueを返す．
+　・タスクコンテキスト
+　・割込みロック解除状態
+　・CPUロック解除状態
+　・割込み優先度マスク全解除状態
+　・ディスパッチ許可状態
+
+(K) タスク切換えによるリカバリーができること
+
+(L) タスク例外によるリカバリーができること
+
+【テストを実施する状況】
+
+CPU例外の発生する状況は，次のように分類することができる．これらの状況毎
+にテストプログラムを用意する．
+
+(a-1) 非タスクコンテキスト
+(a-2) タスクコンテキスト
+
+(b-1) 割込みロック状態
+(b-2) 割込みロック解除状態
+
+(c-1) CPUロック状態
+(c-2) CPUロック解除状態
+
+(d-1) 割込み優先度マスク＝TIPM_ENAALL
+(d-2) 割込み優先度マスク＝TMAX_INTPRI
+	 ！TMAX_INTPRI＝TMIN_INTPRIの場合は(d-3)と同じになるので実施しない．
+(d-3) 割込み優先度マスク＝TMIN_INTPRI
+(d-4) 割込み優先度マスク＝TMIN_INTPRI-1
+	 ！TMIN_INTPRI-1が設定できるかはターゲットに依存する．
+
+(e-1) ディスパッチ禁止状態
+(e-2) ディスパッチ許可状態
+
+(f-1) タスク例外禁止状態
+(f-2) タスク例外許可状態
+
+この組み合わせをすべてテストすることは現実的でないため，代表的なパター
+ンに絞り込む．
+
+まず，(a)～(c)の組み合わせで，次の5つのパターンをテストする．これらのテ
+ストをする際には，(d)～(f)については，(d-1)(e-1)(f-2)の組み合わせに固定
+する．
+
+(1) (a-1)(b-1)(c-2) → リカバリー不可
+	！(a-1)(b-1)(c-1)のテストは省く．
+(2) (a-1)(b-2)(c-1) → リカバリー不可
+(3) (a-1)(b-2)(c-2) → リカバリー不可
+
+(4) (a-2)(b-1)(c-2) → リカバリー不可
+	！(a-2)(b-1)(c-1)のテストは省く．
+(5) (a-2)(b-2)(c-1) → リカバリー不可
+
+次に，(a)～(c)を(a-2)(b-2)(c-2)に固定して，(d)～(f)の組み合わせで，次の
+8つのパターンをテストする．
+
+(6) (d-1)(e-2)(f-1) → タスク切換えによるリカバリー可能
+
+(7) (d-1)(e-1)(f-2) → タスク例外によるリカバリー可能
+
+(8) (d-2)(e-2)(f-2) → リカバリー不可
+	！(d-2)(e-1)(f-2)のテストは省く．
+
+(9) (d-3)(e-2)(f-2) → リカバリー不可
+	！(d-3)(e-1)(f-2)のテストは省く．
+
+(10) (d-4)(e-2)(f-2) → リカバリー不可
+	！(d-4)(e-1)(f-2)のテストは省く．
+
+(11) (d-1)(e-2)(f-2) → 両方法によるリカバリー可能
+
+(12) (d-1)(e-1)(f-1) → リカバリー不可
+		(d-2)～(d-4)×(e-1)×(f-1) のテスト（3パターン）は省く．
+
+(13) (d-3)(e-2)(f-1) → リカバリー不可
+		(d-2),(d-4)×(e-2)×(f-1) のテスト（2パターン）は省く．
+
+【使用リソース】
+
+TASK1: TA_ACT，中優先度，タスク例外処理ルーチン登録
+TASK2: TA_NULL，高優先度
+CPUEXC1: TA_NULL
+ALM1: TA_NULL
+
+以上
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/test/test_cpuexc1.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/test/test_cpuexc1.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/test/test_cpuexc1.c	(revision 457)
@@ -0,0 +1,188 @@
+/*
+ *  TOPPERS Software
+ *      Toyohashi Open Platform for Embedded Real-Time Systems
+ * 
+ *  Copyright (C) 2007-2013 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  $Id$
+ */
+
+/* 
+ *		CPU例外処理のテスト(1)
+ *
+ * 【テストの目的】
+ *
+ *  非タスクコンテキスト，割込ロック状態で発生したCPU例外におけるシステ
+ *  ム状態のテスト．割込み優先度マスク＝TIPM_ENAALL，ディスパッチ禁止状
+ *  態，タスク例外許可状態でテストする．
+ *
+ * 【テスト項目】
+ *
+ *  いずれも，非タスクコンテキスト，割込ロック状態で発生したCPU例外にお
+ *  いて，
+ *
+ *	(A) CPU例外ハンドラ実行開始時にCPUロックフラグが変化しないこと
+ *		！割込みロック状態で発生したCPU例外では，システム状態を正しく読
+ *		めることが保証されないため，テストできない．
+ *	(B) CPU例外ハンドラ実行開始時に割込み優先度マスクが変化しないこと
+ *		！割込みロック状態で発生したCPU例外では，システム状態を正しく読
+ *		めることが保証されないため，テストできない．
+ *	(C) CPU例外ハンドラ実行開始時にディスパッチ禁止フラグが変化しないこと
+ *		！割込みロック状態で発生したCPU例外では，システム状態を正しく読
+ *		めることが保証されないため，テストできない．
+ *	(D) CPU例外ハンドラ実行開始時にタスク例外処理禁止フラグが変化しないこと
+ *		！割込みロック状態で発生したCPU例外では，システム状態を正しく読
+ *		めることが保証されないため，テストできない．
+ *	(E) CPU例外ハンドラリターン時にCPUロックフラグが元に戻ること
+ *		！CPU例外ハンドラからリターンできる場合のみテストする．
+ *	(F) CPU例外ハンドラリターン時に割込み優先度マスクが元に戻ること
+ *		！CPU例外ハンドラからリターンできる場合のみテストする．
+ *	(G) CPU例外ハンドラリターン時にディスパッチ禁止フラグが変化しないこと
+ *		！CPU例外ハンドラからリターンできる場合のみテストする．
+ *	(H) CPU例外ハンドラリターン時にタスク例外処理禁止フラグが変化しないこと
+ *		！CPU例外ハンドラからリターンできる場合のみテストする．
+ *	(I) xsns_xpnがtrueを返すこと
+ *	(J) xsns_dpnがtrueを返すこと
+ *
+ * 【使用リソース】
+ *
+ *	TASK1: TA_ACT，中優先度，タスク例外処理ルーチン登録
+ *	CPUEXC1: TA_NULL
+ *	ALM1: TA_NULL
+ *
+ * 【テストシーケンス】
+ *
+ *	== TASK1（中優先度）==
+ *	1:	状態のチェック
+ *		dis_dsp()
+ *		ena_tex()
+ *	2:	状態のチェック
+ *		sta_alm(ALM1, 1U)
+ *		アラームハンドラ1の実行を待つ
+ *	== ALM1 ==
+ *	3:	状態のチェック
+ *		SIL_LOC_INT()
+ *		RAISE_CPU_EXCEPTION
+ *	== CPUEXC1 ==
+ *	4:	xsns_xpn() == true			... (I)
+ *		xsns_dpn() == true			... (J)
+ *	5:	CPU例外ハンドラからリターンできない場合は，ここで終了
+ *	5:	リターン
+ *	== ALM1（続き）==
+ *	6:	SIL_UNL_LOC()
+ *	7:	状態のチェック				... (E)(G)(H)
+ *		リターン
+ *	== TASK1（続き）==
+ *	8:	状態のチェック				... (F)
+ *	9:	テスト終了
+ */
+
+#include <sil.h>
+#include <kernel.h>
+#include <t_syslog.h>
+#include <test_lib.h>
+#include "kernel_cfg.h"
+#include "test_cpuexc.h"
+
+volatile bool_t	alm1_flag = false;
+
+void
+task1(intptr_t exinf)
+{
+	ER		ercd;
+
+	test_start(__FILE__);
+
+	check_point(1);
+	check_state(false, false, TIPM_ENAALL, false, false, true);
+	ercd = dis_dsp();
+	check_ercd(ercd, E_OK);
+	ercd = ena_tex();
+	check_ercd(ercd, E_OK);
+
+	check_point(2);
+	check_state(false, false, TIPM_ENAALL, true, true, false);
+	ercd = sta_alm(ALM1, 1U);
+	check_ercd(ercd, E_OK);
+
+	while (!(alm1_flag));
+
+	check_point(8);
+	check_state(false, false, TIPM_ENAALL, true, true, false);
+
+	check_finish(9);
+}
+
+void
+tex_task1(TEXPTN texptn, intptr_t exinf)
+{
+	check_point(0);
+}
+
+void
+task2(intptr_t exinf)
+{
+	check_point(0);
+}
+
+void
+alarm1_handler(intptr_t exinf)
+{
+	SIL_PRE_LOC;
+
+	check_point(3);
+	check_state_i(true, false, true, true, false);
+	SIL_LOC_INT();
+	RAISE_CPU_EXCEPTION;
+
+	check_point(6);
+	SIL_UNL_INT();
+
+	check_point(7);
+	check_state_i(true, false, true, true, false);
+	alm1_flag = true;
+}
+
+void
+cpuexc_handler(void *p_excinf)
+{
+	check_point(4);
+	check_assert(xsns_xpn(p_excinf) == true);
+	check_assert(xsns_dpn(p_excinf) == true);
+
+#ifdef CANNOT_RETURN_CPUEXC
+	check_finish(5);
+#endif /* CANNOT_RETURN_CPUEXC */
+
+	check_point(5);
+}
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/test/test_cpuexc10.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/test/test_cpuexc10.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/test/test_cpuexc10.c	(revision 457)
@@ -0,0 +1,162 @@
+/*
+ *  TOPPERS Software
+ *      Toyohashi Open Platform for Embedded Real-Time Systems
+ * 
+ *  Copyright (C) 2007-2015 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  $Id$
+ */
+
+/* 
+ *		CPU例外処理のテスト(10)
+ *
+ * 【テストの目的】
+ *
+ *  割込み優先度マスク＝TMIN_INTPRI-1，ディスパッチ許可状態，タスク例外
+ *  許可状態で発生したCPU例外におけるシステム状態のテスト．
+ *
+ *  このテストは，割込み優先度マスクをTMIN_INTPRI-1に設定できる場合のみ
+ *  実施する．
+ *
+ * 【テスト項目】
+ *
+ *  いずれも，割込み優先度マスク＝TMIN_INTPRI-1，ディスパッチ許可状態，
+ *  タスク例外許可状態で発生したCPU例外において，
+ *
+ *	(A) CPU例外ハンドラ実行開始時にCPUロックフラグが変化しないこと
+ *	(B) CPU例外ハンドラ実行開始時に割込み優先度マスクが変化しないこと
+ *		！CPU例外ハンドラ中で割込み優先度マスクを読めないため，テストで
+ *		きない．
+ *	(C) CPU例外ハンドラ実行開始時にディスパッチ禁止フラグが変化しないこと
+ *	(D) CPU例外ハンドラ実行開始時にタスク例外処理禁止フラグが変化しないこと
+ *	(E) CPU例外ハンドラリターン時にCPUロックフラグが元に戻ること
+ *		！CPU例外ハンドラからリターンできる場合のみテストする．
+ *	(F) CPU例外ハンドラリターン時に割込み優先度マスクが元に戻ること
+ *		！CPU例外ハンドラからリターンできる場合のみテストする．
+ *	(G) CPU例外ハンドラリターン時にディスパッチ禁止フラグが変化しないこと
+ *		！CPU例外ハンドラからリターンできる場合のみテストする．
+ *	(H) CPU例外ハンドラリターン時にタスク例外処理禁止フラグが変化しないこと
+ *		！CPU例外ハンドラからリターンできる場合のみテストする．
+ *	(I) xsns_xpnがtrueを返すこと
+ *	(J) xsns_dpnがtrueを返すこと
+ *
+ * 【使用リソース】
+ *
+ *	TASK1: TA_ACT，中優先度，タスク例外処理ルーチン登録
+ *	CPUEXC1: TA_NULL
+ *
+ * 【テストシーケンス】
+ *
+ *	== TASK1（中優先度）==
+ *	1:	状態のチェック
+ *		chg_ipm(TMIN_INTPRI-1)
+ *		ena_tex()
+ *	2:	状態のチェック
+ *		RAISE_CPU_EXCEPTION
+ *	== CPUEXC1 ==
+ *	3:	状態のチェック				... (A)(C)(D)
+ *		xsns_xpn() == true			... (I)
+ *		xsns_dpn() == true			... (J)
+ *	4:	CPU例外ハンドラからリターンできない場合は，ここで終了
+ *	4:	リターン
+ *	== TASK1（続き）==
+ *	5:	状態のチェック				... (E)(F)(G)(H)
+ *	6:	テスト終了
+ */
+
+#include <kernel.h>
+#include <test_lib.h>
+#include <t_syslog.h>
+#include "kernel_cfg.h"
+#include "test_cpuexc.h"
+
+void
+task1(intptr_t exinf)
+{
+	ER		ercd;
+
+	test_start(__FILE__);
+
+	check_point(1);
+	check_state(false, false, TIPM_ENAALL, false, false, true);
+	ercd = chg_ipm(TMIN_INTPRI - 1);
+	if (ercd == E_PAR) {
+		syslog_0(LOG_NOTICE, "This test program is not necessary.");
+		ext_ker();
+	}
+	check_ercd(ercd, E_OK);
+	ercd = ena_tex();
+	check_ercd(ercd, E_OK);
+
+	check_point(2);
+	check_state(false, false, TMIN_INTPRI - 1, false, true, false);
+	RAISE_CPU_EXCEPTION;
+
+	check_point(5);
+	check_state(false, false, TMIN_INTPRI - 1, false, true, false);
+
+	check_finish(6);
+}
+
+void
+tex_task1(TEXPTN texptn, intptr_t exinf)
+{
+	check_point(0);
+}
+
+void
+task2(intptr_t exinf)
+{
+	check_point(0);
+}
+
+void
+alarm1_handler(intptr_t exinf)
+{
+	check_point(0);
+}
+
+void
+cpuexc_handler(void *p_excinf)
+{
+	check_point(3);
+	check_state_i(true, false, false, true, false);
+	check_assert(xsns_xpn(p_excinf) == true);
+	check_assert(xsns_dpn(p_excinf) == true);
+
+#ifdef CANNOT_RETURN_CPUEXC
+	check_finish(4);
+#endif /* CANNOT_RETURN_CPUEXC */
+
+	check_point(4);
+}
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/test/test_cpuexc11.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/test/test_cpuexc11.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/test/test_cpuexc11.c	(revision 457)
@@ -0,0 +1,256 @@
+/*
+ *  TOPPERS Software
+ *      Toyohashi Open Platform for Embedded Real-Time Systems
+ * 
+ *  Copyright (C) 2007-2013 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  $Id$
+ */
+
+/* 
+ *		CPU例外処理のテスト(11)
+ *
+ * 【テストの目的】
+ *
+ *  割込み優先度マスク＝TIPM_ENAALL，ディスパッチ許可状態，タスク例外許
+ *  可状態で発生したCPU例外におけるシステム状態のテスト．タスク切換えに
+ *  よりリカバリーできることもテストする．
+ *
+ * 【テスト項目】
+ *
+ *  いずれも，割込み優先度マスク＝TIPM_ENAALL，ディスパッチ許可状態，タ
+ *  スク例外許可状態で発生したCPU例外において，
+ *
+ *	(A) CPU例外ハンドラ実行開始時にCPUロックフラグが変化しないこと
+ *	(B) CPU例外ハンドラ実行開始時に割込み優先度マスクが変化しないこと
+ *		！CPU例外ハンドラ中で割込み優先度マスクを読めないため，テストで
+ *		きない．
+ *	(C) CPU例外ハンドラ実行開始時にディスパッチ禁止フラグが変化しないこと
+ *	(D) CPU例外ハンドラ実行開始時にタスク例外処理禁止フラグが変化しないこと
+ *	(E) CPU例外ハンドラリターン時にCPUロックフラグが元に戻ること
+ *	(F) CPU例外ハンドラリターン時に割込み優先度マスクが元に戻ること
+ *	(G) CPU例外ハンドラリターン時にディスパッチ禁止フラグが変化しないこと
+ *	(H) CPU例外ハンドラリターン時にタスク例外処理禁止フラグが変化しないこと
+ *	(I) xsns_xpnがfalseを返すこと
+ *	(J) xsns_dpnがfalseを返すこと
+ *	(K) タスク切換えによるリカバリーができること
+ *	(L) タスク例外によるリカバリーができること
+ *
+ * 【使用リソース】
+ *
+ *	TASK1: TA_ACT，中優先度，タスク例外処理ルーチン登録
+ *	TASK2: TA_NULL，高優先度
+ *	CPUEXC1: TA_NULL
+ *
+ * 【テストシーケンス】
+ *
+ *	== TASK1（中優先度，1回目）==
+ *	1:	状態のチェック
+ *		ena_tex()
+ *	2:	状態のチェック
+ *		RAISE_CPU_EXCEPTION
+ *	== CPUEXC1（1回目）==
+ *	3:	状態のチェック				... (A)(C)(D)
+ *		xsns_xpn() == false			... (I)
+ *		xsns_dpn() == false			... (J)
+ *	4:	iact_tsk(TASK2)
+ *		iloc_cpu()
+ *		リターン
+ *	== TASK2（高優先度）==
+ *	5:	状態のチェック				... (E)(F)(G)(H)
+ *	6:	ter_tsk(TASK1)				... (K)
+ *	7:	act_tsk(TASK1)				... (K)
+ *	8:	ext_tsk()
+ *	== TASK1（中優先度，2回目）==
+ *	9:	状態のチェック				... (K)
+ *		ena_tex()
+ *	10:	状態のチェック
+ *		RAISE_CPU_EXCEPTION
+ *	== CPUEXC1（2回目）==
+ *	11:	状態のチェック				... (A)(C)(D)
+ *		xsns_xpn() == false			... (I)
+ *		xsns_dpn() == false			... (J)
+ *	12:	iras_tex(TASK1, 1U)
+ *		iloc_cpu()
+ *		リターン
+ *	== TASK1のタスク例外処理ルーチン ==
+ *	13:	状態のチェック				... (E)(F)(G)(H)
+ *	14:	act_tsk(TASK1)				... (L)
+ *	15:	ext_tsk()					... (L)
+ *	== TASK1（中優先度，3回目）==
+ *	16:	状態のチェック				... (L)
+ *	17:	テスト終了
+ */
+
+#include <kernel.h>
+#include <test_lib.h>
+#include <t_syslog.h>
+#include "kernel_cfg.h"
+#include "test_cpuexc.h"
+
+int_t	task1_count = 0;
+
+void
+task1(intptr_t exinf)
+{
+	ER		ercd;
+
+	switch (++task1_count) {
+	case 1:
+		test_start(__FILE__);
+
+		check_point(1);
+		check_state(false, false, TIPM_ENAALL, false, false, true);
+		ercd = ena_tex();
+		check_ercd(ercd, E_OK);
+
+		check_point(2);
+		check_state(false, false, TIPM_ENAALL, false, false, false);
+		RAISE_CPU_EXCEPTION;
+
+		check_point(0);
+		break;
+
+	case 2:
+		check_point(9);
+		check_state(false, false, TIPM_ENAALL, false, false, true);
+		ercd = ena_tex();
+		check_ercd(ercd, E_OK);
+
+		check_point(10);
+		check_state(false, false, TIPM_ENAALL, false, false, false);
+		RAISE_CPU_EXCEPTION;
+
+		check_point(0);
+		break;
+
+	case 3:
+		check_point(16);
+		check_state(false, false, TIPM_ENAALL, false, false, true);
+
+		check_finish(17);
+		break;
+
+	default:
+		check_point(0);
+		break;
+	}
+}
+
+void
+tex_task1(TEXPTN texptn, intptr_t exinf)
+{
+	ER		ercd;
+
+	check_point(13);
+	check_state(false, false, TIPM_ENAALL, false, false, true);
+
+	check_point(14);
+	ercd = act_tsk(TASK1);
+	check_ercd(ercd, E_OK);
+
+	check_point(15);
+	ercd = ext_tsk();
+	check_ercd(ercd, E_OK);
+
+	check_point(0);
+}
+
+void
+task2(intptr_t exinf)
+{
+	ER		ercd;
+
+	check_point(5);
+	check_state(false, false, TIPM_ENAALL, false, false, true);
+
+	check_point(6);
+	ercd = ter_tsk(TASK1);
+	check_ercd(ercd, E_OK);
+
+	check_point(7);
+	ercd = act_tsk(TASK1);
+	check_ercd(ercd, E_OK);
+
+	check_point(8);
+	ercd = ext_tsk();
+	check_ercd(ercd, E_OK);
+
+	check_point(0);
+}
+
+void
+alarm1_handler(intptr_t exinf)
+{
+	check_point(0);
+}
+
+int_t	cpuexc_count = 0;
+
+void
+cpuexc_handler(void *p_excinf)
+{
+	ER		ercd;
+
+	switch (++cpuexc_count) {
+	case 1:
+		check_point(3);
+		check_state_i(true, false, false, true, false);
+		check_assert(xsns_xpn(p_excinf) == false);
+		check_assert(xsns_dpn(p_excinf) == false);
+
+		check_point(4);
+		ercd = iact_tsk(TASK2);
+		check_ercd(ercd, E_OK);
+		ercd = iloc_cpu();
+		check_ercd(ercd, E_OK);
+		break;
+
+	case 2:
+		check_point(11);
+		check_state_i(true, false, false, true, false);
+		check_assert(xsns_xpn(p_excinf) == false);
+		check_assert(xsns_dpn(p_excinf) == false);
+
+		check_point(12);
+		ercd = iras_tex(TASK1, 1U);
+		check_ercd(ercd, E_OK);
+		ercd = iloc_cpu();
+		check_ercd(ercd, E_OK);
+		break;
+
+	default:
+		check_point(0);
+		break;
+	}
+}
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/test/test_cpuexc12.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/test/test_cpuexc12.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/test/test_cpuexc12.c	(revision 457)
@@ -0,0 +1,152 @@
+/*
+ *  TOPPERS Software
+ *      Toyohashi Open Platform for Embedded Real-Time Systems
+ * 
+ *  Copyright (C) 2007-2013 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  $Id$
+ */
+
+/* 
+ *		CPU例外処理のテスト(12)
+ *
+ * 【テストの目的】
+ *
+ *  割込み優先度マスク＝TIPM_ENAALL，ディスパッチ禁止状態，タスク例外禁
+ *  止状態で発生したCPU例外におけるシステム状態のテスト．
+ *
+ * 【テスト項目】
+ *
+ *  いずれも，割込み優先度マスク＝TIPM_ENAALL，ディスパッチ禁止状態，タ
+ *  スク例外禁止状態で発生したCPU例外において，
+ *
+ *	(A) CPU例外ハンドラ実行開始時にCPUロックフラグが変化しないこと
+ *	(B) CPU例外ハンドラ実行開始時に割込み優先度マスクが変化しないこと
+ *		！CPU例外ハンドラ中で割込み優先度マスクを読めないため，テストで
+ *		きない．
+ *	(C) CPU例外ハンドラ実行開始時にディスパッチ禁止フラグが変化しないこと
+ *	(D) CPU例外ハンドラ実行開始時にタスク例外処理禁止フラグが変化しないこと
+ *	(E) CPU例外ハンドラリターン時にCPUロックフラグが元に戻ること
+ *		！CPU例外ハンドラからリターンできる場合のみテストする．
+ *	(F) CPU例外ハンドラリターン時に割込み優先度マスクが元に戻ること
+ *		！CPU例外ハンドラからリターンできる場合のみテストする．
+ *	(G) CPU例外ハンドラリターン時にディスパッチ禁止フラグが変化しないこと
+ *		！CPU例外ハンドラからリターンできる場合のみテストする．
+ *	(H) CPU例外ハンドラリターン時にタスク例外処理禁止フラグが変化しないこと
+ *		！CPU例外ハンドラからリターンできる場合のみテストする．
+ *	(I) xsns_xpnがtrueを返すこと
+ *	(J) xsns_dpnがtrueを返すこと
+ *
+ * 【使用リソース】
+ *
+ *	TASK1: TA_ACT，中優先度，タスク例外処理ルーチン登録
+ *	CPUEXC1: TA_NULL
+ *
+ * 【テストシーケンス】
+ *
+ *	== TASK1（中優先度）==
+ *	1:	状態のチェック
+ *		dis_dsp()
+ *	2:	状態のチェック
+ *		RAISE_CPU_EXCEPTION
+ *	== CPUEXC1 ==
+ *	3:	状態のチェック				... (A)(C)(D)
+ *		xsns_xpn() == true			... (I)
+ *		xsns_dpn() == true			... (J)
+ *	4:	CPU例外ハンドラからリターンできない場合は，ここで終了
+ *	4:	リターン
+ *	== TASK1（続き）==
+ *	5:	状態のチェック				... (E)(F)(G)(H)
+ *	6:	テスト終了
+ */
+
+#include <kernel.h>
+#include <test_lib.h>
+#include <t_syslog.h>
+#include "kernel_cfg.h"
+#include "test_cpuexc.h"
+
+void
+task1(intptr_t exinf)
+{
+	ER		ercd;
+
+	test_start(__FILE__);
+
+	check_point(1);
+	check_state(false, false, TIPM_ENAALL, false, false, true);
+	ercd = dis_dsp();
+	check_ercd(ercd, E_OK);
+
+	check_point(2);
+	check_state(false, false, TIPM_ENAALL, true, true, true);
+	RAISE_CPU_EXCEPTION;
+
+	check_point(5);
+	check_state(false, false, TIPM_ENAALL, true, true, true);
+
+	check_finish(6);
+}
+
+void
+tex_task1(TEXPTN texptn, intptr_t exinf)
+{
+	check_point(0);
+}
+
+void
+task2(intptr_t exinf)
+{
+	check_point(0);
+}
+
+void
+alarm1_handler(intptr_t exinf)
+{
+	check_point(0);
+}
+
+void
+cpuexc_handler(void *p_excinf)
+{
+	check_point(3);
+	check_state_i(true, false, true, true, true);
+	check_assert(xsns_xpn(p_excinf) == true);
+	check_assert(xsns_dpn(p_excinf) == true);
+
+#ifdef CANNOT_RETURN_CPUEXC
+	check_finish(4);
+#endif /* CANNOT_RETURN_CPUEXC */
+
+	check_point(4);
+}
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/test/test_cpuexc13.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/test/test_cpuexc13.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/test/test_cpuexc13.c	(revision 457)
@@ -0,0 +1,152 @@
+/*
+ *  TOPPERS Software
+ *      Toyohashi Open Platform for Embedded Real-Time Systems
+ * 
+ *  Copyright (C) 2007-2013 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  $Id$
+ */
+
+/* 
+ *		CPU例外処理のテスト(13)
+ *
+ * 【テストの目的】
+ *
+ *  割込み優先度マスク＝TMIN_INTPRI，ディスパッチ許可状態，タスク例外禁
+ *  止状態で発生したCPU例外におけるシステム状態のテスト．
+ *
+ * 【テスト項目】
+ *
+ *  いずれも，割込み優先度マスク＝TMIN_INTPRI，ディスパッチ許可状態，タ
+ *  スク例外禁止状態で発生したCPU例外において，
+ *
+ *	(A) CPU例外ハンドラ実行開始時にCPUロックフラグが変化しないこと
+ *	(B) CPU例外ハンドラ実行開始時に割込み優先度マスクが変化しないこと
+ *		！CPU例外ハンドラ中で割込み優先度マスクを読めないため，テストで
+ *		きない．
+ *	(C) CPU例外ハンドラ実行開始時にディスパッチ禁止フラグが変化しないこと
+ *	(D) CPU例外ハンドラ実行開始時にタスク例外処理禁止フラグが変化しないこと
+ *	(E) CPU例外ハンドラリターン時にCPUロックフラグが元に戻ること
+ *		！CPU例外ハンドラからリターンできる場合のみテストする．
+ *	(F) CPU例外ハンドラリターン時に割込み優先度マスクが元に戻ること
+ *		！CPU例外ハンドラからリターンできる場合のみテストする．
+ *	(G) CPU例外ハンドラリターン時にディスパッチ禁止フラグが変化しないこと
+ *		！CPU例外ハンドラからリターンできる場合のみテストする．
+ *	(H) CPU例外ハンドラリターン時にタスク例外処理禁止フラグが変化しないこと
+ *		！CPU例外ハンドラからリターンできる場合のみテストする．
+ *	(I) xsns_xpnがtrueを返すこと
+ *	(J) xsns_dpnがtrueを返すこと
+ *
+ * 【使用リソース】
+ *
+ *	TASK1: TA_ACT，中優先度，タスク例外処理ルーチン登録
+ *	CPUEXC1: TA_NULL
+ *
+ * 【テストシーケンス】
+ *
+ *	== TASK1（中優先度）==
+ *	1:	状態のチェック
+ *		chg_ipm(TMIN_INTPRI)
+ *	2:	状態のチェック
+ *		RAISE_CPU_EXCEPTION
+ *	== CPUEXC1 ==
+ *	3:	状態のチェック				... (A)(C)(D)
+ *		xsns_xpn() == true			... (I)
+ *		xsns_dpn() == true			... (J)
+ *	4:	CPU例外ハンドラからリターンできない場合は，ここで終了
+ *	4:	リターン
+ *	== TASK1（続き）==
+ *	5:	状態のチェック				... (E)(F)(G)(H)
+ *	6:	テスト終了
+ */
+
+#include <kernel.h>
+#include <test_lib.h>
+#include <t_syslog.h>
+#include "kernel_cfg.h"
+#include "test_cpuexc.h"
+
+void
+task1(intptr_t exinf)
+{
+	ER		ercd;
+
+	test_start(__FILE__);
+
+	check_point(1);
+	check_state(false, false, TIPM_ENAALL, false, false, true);
+	ercd = chg_ipm(TMIN_INTPRI);
+	check_ercd(ercd, E_OK);
+
+	check_point(2);
+	check_state(false, false, TMIN_INTPRI, false, true, true);
+	RAISE_CPU_EXCEPTION;
+
+	check_point(5);
+	check_state(false, false, TMIN_INTPRI, false, true, true);
+
+	check_finish(6);
+}
+
+void
+tex_task1(TEXPTN texptn, intptr_t exinf)
+{
+	check_point(0);
+}
+
+void
+task2(intptr_t exinf)
+{
+	check_point(0);
+}
+
+void
+alarm1_handler(intptr_t exinf)
+{
+	check_point(0);
+}
+
+void
+cpuexc_handler(void *p_excinf)
+{
+	check_point(3);
+	check_state_i(true, false, false, true, true);
+	check_assert(xsns_xpn(p_excinf) == true);
+	check_assert(xsns_dpn(p_excinf) == true);
+
+#ifdef CANNOT_RETURN_CPUEXC
+	check_finish(4);
+#endif /* CANNOT_RETURN_CPUEXC */
+
+	check_point(4);
+}
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/test/test_cpuexc2.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/test/test_cpuexc2.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/test/test_cpuexc2.c	(revision 457)
@@ -0,0 +1,180 @@
+/*
+ *  TOPPERS Software
+ *      Toyohashi Open Platform for Embedded Real-Time Systems
+ * 
+ *  Copyright (C) 2007-2013 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  $Id$
+ */
+
+/* 
+ *		CPU例外処理のテスト(2)
+ *
+ * 【テストの目的】
+ *
+ *  非タスクコンテキスト，割込ロック解除，CPUロック状態で発生したCPU例
+ *  外におけるシステム状態のテスト．割込み優先度マスク＝TIPM_ENAALL，ディ
+ *  スパッチ禁止状態，タスク例外許可状態でテストする．
+ *
+ * 【テスト項目】
+ *
+ *  いずれも，非タスクコンテキスト，割込ロック解除，CPUロック状態で発生
+ *  したCPU例外において，
+ *
+ *	(A) CPU例外ハンドラ実行開始時にCPUロックフラグが変化しないこと
+ *	(B) CPU例外ハンドラ実行開始時に割込み優先度マスクが変化しないこと
+ *		！CPU例外ハンドラ中で割込み優先度マスクを読めないため，テストで
+ *		きない．
+ *	(C) CPU例外ハンドラ実行開始時にディスパッチ禁止フラグが変化しないこと
+ *	(D) CPU例外ハンドラ実行開始時にタスク例外処理禁止フラグが変化しないこと
+ *	(E) CPU例外ハンドラリターン時にCPUロックフラグが元に戻ること
+ *		！CPU例外ハンドラからリターンできる場合のみテストする．
+ *	(F) CPU例外ハンドラリターン時に割込み優先度マスクが元に戻ること
+ *		！CPU例外ハンドラからリターンできる場合のみテストする．
+ *	(G) CPU例外ハンドラリターン時にディスパッチ禁止フラグが変化しないこと
+ *		！CPU例外ハンドラからリターンできる場合のみテストする．
+ *	(H) CPU例外ハンドラリターン時にタスク例外処理禁止フラグが変化しないこと
+ *		！CPU例外ハンドラからリターンできる場合のみテストする．
+ *	(I) xsns_xpnがtrueを返すこと
+ *	(J) xsns_dpnがtrueを返すこと
+ *
+ * 【使用リソース】
+ *
+ *	TASK1: TA_ACT，中優先度，タスク例外処理ルーチン登録
+ *	CPUEXC1: TA_NULL
+ *	ALM1: TA_NULL
+ *
+ * 【テストシーケンス】
+ *
+ *	== TASK1（中優先度）==
+ *	1:	状態のチェック
+ *		dis_dsp()
+ *		ena_tex()
+ *	2:	状態のチェック
+ *		sta_alm(ALM1, 1U)
+ *		アラームハンドラ1の実行を待つ
+ *	== ALM1 ==
+ *	3:	状態のチェック
+ *		iloc_cpu()
+ *		RAISE_CPU_EXCEPTION
+ *	== CPUEXC1 ==
+ *	4:	状態のチェック				... (A)(C)(D)
+ *		xsns_xpn() == true			... (I)
+ *		xsns_dpn() == true			... (J)
+ *	5:	CPU例外ハンドラからリターンできない場合は，ここで終了
+ *	5:	リターン
+ *	== ALM1（続き）==
+ *	6:	状態のチェック				... (E)(G)(H)
+ *		リターン
+ *	== TASK1（続き）==
+ *	7:	状態のチェック				... (F)
+ *	8:	テスト終了
+ */
+
+#include <kernel.h>
+#include <test_lib.h>
+#include <t_syslog.h>
+#include "kernel_cfg.h"
+#include "test_cpuexc.h"
+
+volatile bool_t	alm1_flag = false;
+
+void
+task1(intptr_t exinf)
+{
+	ER		ercd;
+
+	test_start(__FILE__);
+
+	check_point(1);
+	check_state(false, false, TIPM_ENAALL, false, false, true);
+	ercd = dis_dsp();
+	check_ercd(ercd, E_OK);
+	ercd = ena_tex();
+	check_ercd(ercd, E_OK);
+
+	check_point(2);
+	check_state(false, false, TIPM_ENAALL, true, true, false);
+	ercd = sta_alm(ALM1, 1U);
+	check_ercd(ercd, E_OK);
+
+	while (!(alm1_flag));
+
+	check_point(7);
+	check_state(false, false, TIPM_ENAALL, true, true, false);
+
+	check_finish(8);
+}
+
+void
+tex_task1(TEXPTN texptn, intptr_t exinf)
+{
+	check_point(0);
+}
+
+void
+task2(intptr_t exinf)
+{
+	check_point(0);
+}
+
+void
+alarm1_handler(intptr_t exinf)
+{
+	ER		ercd;
+
+	check_point(3);
+	check_state_i(true, false, true, true, false);
+	ercd = iloc_cpu();
+	check_ercd(ercd, E_OK);
+	RAISE_CPU_EXCEPTION;
+
+	check_point(6);
+	check_state_i(true, true, true, true, false);
+	alm1_flag = true;
+}
+
+void
+cpuexc_handler(void *p_excinf)
+{
+	check_point(4);
+	check_state_i(true, true, true, true, false);
+	check_assert(xsns_xpn(p_excinf) == true);
+	check_assert(xsns_dpn(p_excinf) == true);
+
+#ifdef CANNOT_RETURN_CPUEXC
+	check_finish(5);
+#endif /* CANNOT_RETURN_CPUEXC */
+
+	check_point(5);
+}
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/test/test_cpuexc3.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/test/test_cpuexc3.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/test/test_cpuexc3.c	(revision 457)
@@ -0,0 +1,175 @@
+/*
+ *  TOPPERS Software
+ *      Toyohashi Open Platform for Embedded Real-Time Systems
+ * 
+ *  Copyright (C) 2007-2013 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  $Id$
+ */
+
+/* 
+ *		CPU例外処理のテスト(3)
+ *
+ * 【テストの目的】
+ *
+ *  非タスクコンテキスト，割込ロック解除，CPUロック解除で発生したCPU例
+ *  外におけるシステム状態のテスト．割込み優先度マスク＝TIPM_ENAALL，ディ
+ *  スパッチ禁止状態，タスク例外許可状態でテストする．
+ *
+ * 【テスト項目】
+ *
+ *  いずれも，非タスクコンテキスト，割込ロック解除，CPUロック解除で発生
+ *  したCPU例外において，
+ *
+ *	(A) CPU例外ハンドラ実行開始時にCPUロックフラグが変化しないこと
+ *	(B) CPU例外ハンドラ実行開始時に割込み優先度マスクが変化しないこと
+ *		！CPU例外ハンドラ中で割込み優先度マスクを読めないため，テストで
+ *		きない．
+ *	(C) CPU例外ハンドラ実行開始時にディスパッチ禁止フラグが変化しないこと
+ *	(D) CPU例外ハンドラ実行開始時にタスク例外処理禁止フラグが変化しないこと
+ *	(E) CPU例外ハンドラリターン時にCPUロックフラグが元に戻ること
+ *		！CPU例外ハンドラからリターンできる場合のみテストする．
+ *	(F) CPU例外ハンドラリターン時に割込み優先度マスクが元に戻ること
+ *		！CPU例外ハンドラからリターンできる場合のみテストする．
+ *	(G) CPU例外ハンドラリターン時にディスパッチ禁止フラグが変化しないこと
+ *		！CPU例外ハンドラからリターンできる場合のみテストする．
+ *	(H) CPU例外ハンドラリターン時にタスク例外処理禁止フラグが変化しないこと
+ *		！CPU例外ハンドラからリターンできる場合のみテストする．
+ *	(I) xsns_xpnがtrueを返すこと
+ *	(J) xsns_dpnがtrueを返すこと
+ *
+ * 【使用リソース】
+ *
+ *	TASK1: TA_ACT，中優先度，タスク例外処理ルーチン登録
+ *	CPUEXC1: TA_NULL
+ *	ALM1: TA_NULL
+ *
+ * 【テストシーケンス】
+ *
+ *	== TASK1（中優先度）==
+ *	1:	状態のチェック
+ *		dis_dsp()
+ *		ena_tex()
+ *	2:	状態のチェック
+ *		sta_alm(ALM1, 1U)
+ *		アラームハンドラ1の実行を待つ
+ *	== ALM1 ==
+ *	3:	状態のチェック
+ *		RAISE_CPU_EXCEPTION
+ *	== CPUEXC1 ==
+ *	4:	状態のチェック				... (A)(C)(D)
+ *		xsns_xpn() == true			... (I)
+ *		xsns_dpn() == true			... (J)
+ *	5:	CPU例外ハンドラからリターンできない場合は，ここで終了
+ *	5:	リターン
+ *	== ALM1（続き）==
+ *	6:	状態のチェック				... (E)(G)(H)
+ *		リターン
+ *	== TASK1（続き）==
+ *	7:	状態のチェック				... (F)
+ *	8:	テスト終了
+ */
+
+#include <kernel.h>
+#include <test_lib.h>
+#include <t_syslog.h>
+#include "kernel_cfg.h"
+#include "test_cpuexc.h"
+
+volatile bool_t	alm1_flag = false;
+
+void
+task1(intptr_t exinf)
+{
+	ER		ercd;
+
+	test_start(__FILE__);
+
+	check_point(1);
+	check_state(false, false, TIPM_ENAALL, false, false, true);
+	ercd = dis_dsp();
+	check_ercd(ercd, E_OK);
+	ercd = ena_tex();
+	check_ercd(ercd, E_OK);
+
+	check_point(2);
+	check_state(false, false, TIPM_ENAALL, true, true, false);
+	ercd = sta_alm(ALM1, 1U);
+	check_ercd(ercd, E_OK);
+
+	while (!(alm1_flag));
+
+	check_point(7);
+	check_state(false, false, TIPM_ENAALL, true, true, false);
+
+	check_finish(8);
+}
+
+void
+tex_task1(TEXPTN texptn, intptr_t exinf)
+{
+	check_point(0);
+}
+
+void
+task2(intptr_t exinf)
+{
+	check_point(0);
+}
+
+void
+alarm1_handler(intptr_t exinf)
+{
+	check_point(3);
+	check_state_i(true, false, true, true, false);
+	RAISE_CPU_EXCEPTION;
+
+	check_point(6);
+	check_state_i(true, false, true, true, false);
+	alm1_flag = true;
+}
+
+void
+cpuexc_handler(void *p_excinf)
+{
+	check_point(4);
+	check_state_i(true, false, true, true, false);
+	check_assert(xsns_xpn(p_excinf) == true);
+	check_assert(xsns_dpn(p_excinf) == true);
+
+#ifdef CANNOT_RETURN_CPUEXC
+	check_finish(5);
+#endif /* CANNOT_RETURN_CPUEXC */
+
+	check_point(5);
+}
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/test/test_cpuexc4.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/test/test_cpuexc4.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/test/test_cpuexc4.c	(revision 457)
@@ -0,0 +1,168 @@
+/*
+ *  TOPPERS Software
+ *      Toyohashi Open Platform for Embedded Real-Time Systems
+ * 
+ *  Copyright (C) 2007-2013 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  $Id$
+ */
+
+/* 
+ *		CPU例外処理のテスト(4)
+ *
+ * 【テストの目的】
+ *
+ *  タスクコンテキスト，割込ロック状態で発生したCPU例外におけるシステム
+ *  状態のテスト．割込み優先度マスク＝TIPM_ENAALL，ディスパッチ禁止状態，
+ *  タスク例外許可状態でテストする．
+ *
+ * 【テスト項目】
+ *
+ *  いずれも，タスクコンテキスト，割込ロック状態で発生したCPU例外におい
+ *  て，
+ *
+ *	(A) CPU例外ハンドラ実行開始時にCPUロックフラグが変化しないこと
+ *		！割込みロック状態で発生したCPU例外では，システム状態を正しく読
+ *		めることが保証されないため，テストできない．
+ *	(B) CPU例外ハンドラ実行開始時に割込み優先度マスクが変化しないこと
+ *		！割込みロック状態で発生したCPU例外では，システム状態を正しく読
+ *		めることが保証されないため，テストできない．
+ *	(C) CPU例外ハンドラ実行開始時にディスパッチ禁止フラグが変化しないこと
+ *		！割込みロック状態で発生したCPU例外では，システム状態を正しく読
+ *		めることが保証されないため，テストできない．
+ *	(D) CPU例外ハンドラ実行開始時にタスク例外処理禁止フラグが変化しないこと
+ *		！割込みロック状態で発生したCPU例外では，システム状態を正しく読
+ *		めることが保証されないため，テストできない．
+ *	(E) CPU例外ハンドラリターン時にCPUロックフラグが元に戻ること
+ *		！CPU例外ハンドラからリターンできる場合のみテストする．
+ *	(F) CPU例外ハンドラリターン時に割込み優先度マスクが元に戻ること
+ *		！CPU例外ハンドラからリターンできる場合のみテストする．
+ *	(G) CPU例外ハンドラリターン時にディスパッチ禁止フラグが変化しないこと
+ *		！CPU例外ハンドラからリターンできる場合のみテストする．
+ *	(H) CPU例外ハンドラリターン時にタスク例外処理禁止フラグが変化しないこと
+ *		！CPU例外ハンドラからリターンできる場合のみテストする．
+ *	(I) xsns_xpnがtrueを返すこと
+ *	(J) xsns_dpnがtrueを返すこと
+ *
+ * 【使用リソース】
+ *
+ *	TASK1: TA_ACT，中優先度，タスク例外処理ルーチン登録
+ *	CPUEXC1: TA_NULL
+ *
+ * 【テストシーケンス】
+ *
+ *	== TASK1（中優先度）==
+ *	1:	状態のチェック
+ *		dis_dsp()
+ *		ena_tex()
+ *	2:	状態のチェック
+ *		SIL_LOC_INT()
+ *		RAISE_CPU_EXCEPTION
+ *	== CPUEXC1 ==
+ *	3:	xsns_xpn() == true			... (I)
+ *		xsns_dpn() == true			... (J)
+ *	4:	CPU例外ハンドラからリターンできない場合は，ここで終了
+ *	4:	リターン
+ *	== TASK1（続き）==
+ *	5:	SIL_UNL_LOC()
+ *	6:	状態のチェック				... (E)(F)(G)(H)
+ *	7:	テスト終了
+ */
+
+#include <sil.h>
+#include <kernel.h>
+#include <test_lib.h>
+#include <t_syslog.h>
+#include "kernel_cfg.h"
+#include "test_cpuexc.h"
+
+void
+task1(intptr_t exinf)
+{
+	ER		ercd;
+	SIL_PRE_LOC;
+
+	test_start(__FILE__);
+
+	check_point(1);
+	check_state(false, false, TIPM_ENAALL, false, false, true);
+	ercd = dis_dsp();
+	check_ercd(ercd, E_OK);
+	ercd = ena_tex();
+	check_ercd(ercd, E_OK);
+
+	check_point(2);
+	check_state(false, false, TIPM_ENAALL, true, true, false);
+	SIL_LOC_INT();
+	RAISE_CPU_EXCEPTION;
+
+	check_point(5);
+	SIL_UNL_INT();
+
+	check_point(6);
+	check_state(false, false, TIPM_ENAALL, true, true, false);
+
+	check_finish(7);
+}
+
+void
+tex_task1(TEXPTN texptn, intptr_t exinf)
+{
+	check_point(0);
+}
+
+void
+task2(intptr_t exinf)
+{
+	check_point(0);
+}
+
+void
+alarm1_handler(intptr_t exinf)
+{
+	check_point(0);
+}
+
+void
+cpuexc_handler(void *p_excinf)
+{
+	check_point(3);
+	check_assert(xsns_xpn(p_excinf) == true);
+	check_assert(xsns_dpn(p_excinf) == true);
+
+#ifdef CANNOT_RETURN_CPUEXC
+	check_finish(4);
+#endif /* CANNOT_RETURN_CPUEXC */
+
+	check_point(4);
+}
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/test/test_cpuexc5.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/test/test_cpuexc5.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/test/test_cpuexc5.c	(revision 457)
@@ -0,0 +1,159 @@
+/*
+ *  TOPPERS Software
+ *      Toyohashi Open Platform for Embedded Real-Time Systems
+ * 
+ *  Copyright (C) 2007-2013 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  $Id$
+ */
+
+/* 
+ *		CPU例外処理のテスト(5)
+ *
+ * 【テストの目的】
+ *
+ *  タスクコンテキスト，割込ロック解除，CPUロック状態で発生したCPU例外
+ *  におけるシステム状態のテスト．割込み優先度マスク＝TIPM_ENAALL，ディ
+ *  スパッチ禁止状態，タスク例外許可状態でテストする．
+ *
+ * 【テスト項目】
+ *
+ *  いずれも，タスクコンテキスト，割込ロック解除，CPUロック状態で発生し
+ *  たCPU例外において，
+ *
+ *	(A) CPU例外ハンドラ実行開始時にCPUロックフラグが変化しないこと
+ *	(B) CPU例外ハンドラ実行開始時に割込み優先度マスクが変化しないこと
+ *		！CPU例外ハンドラ中で割込み優先度マスクを読めないため，テストで
+ *		きない．
+ *	(C) CPU例外ハンドラ実行開始時にディスパッチ禁止フラグが変化しないこと
+ *	(D) CPU例外ハンドラ実行開始時にタスク例外処理禁止フラグが変化しないこと
+ *	(E) CPU例外ハンドラリターン時にCPUロックフラグが元に戻ること
+ *		！CPU例外ハンドラからリターンできる場合のみテストする．
+ *	(F) CPU例外ハンドラリターン時に割込み優先度マスクが元に戻ること
+ *		！CPU例外ハンドラからリターンできる場合のみテストする．
+ *	(G) CPU例外ハンドラリターン時にディスパッチ禁止フラグが変化しないこと
+ *		！CPU例外ハンドラからリターンできる場合のみテストする．
+ *	(H) CPU例外ハンドラリターン時にタスク例外処理禁止フラグが変化しないこと
+ *		！CPU例外ハンドラからリターンできる場合のみテストする．
+ *	(I) xsns_xpnがtrueを返すこと
+ *	(J) xsns_dpnがtrueを返すこと
+ *
+ * 【使用リソース】
+ *
+ *	TASK1: TA_ACT，中優先度，タスク例外処理ルーチン登録
+ *	CPUEXC1: TA_NULL
+ *
+ * 【テストシーケンス】
+ *
+ *	== TASK1（中優先度）==
+ *	1:	状態のチェック
+ *		dis_dsp()
+ *		ena_tex()
+ *		loc_cpu()
+ *	2:	状態のチェック
+ *		RAISE_CPU_EXCEPTION
+ *	== CPUEXC1 ==
+ *	3:	状態のチェック				... (A)(C)(D)
+ *		xsns_xpn() == true			... (I)
+ *		xsns_dpn() == true			... (J)
+ *	4:	CPU例外ハンドラからリターンできない場合は，ここで終了
+ *	4:	リターン
+ *	== TASK1（続き）==
+ *	5:	状態のチェック				... (E)(F)(G)(H)
+ *	6:	テスト終了
+ */
+
+#include <kernel.h>
+#include <test_lib.h>
+#include <t_syslog.h>
+#include "kernel_cfg.h"
+#include "test_cpuexc.h"
+
+void
+task1(intptr_t exinf)
+{
+	ER		ercd;
+
+	test_start(__FILE__);
+
+	check_point(1);
+	check_state(false, false, TIPM_ENAALL, false, false, true);
+	ercd = dis_dsp();
+	check_ercd(ercd, E_OK);
+	ercd = ena_tex();
+	check_ercd(ercd, E_OK);
+	ercd = loc_cpu();
+	check_ercd(ercd, E_OK);
+
+	check_point(2);
+	check_state(false, true, TIPM_ENAALL, true, true, false);
+	RAISE_CPU_EXCEPTION;
+
+	check_point(5);
+	check_state(false, true, TIPM_ENAALL, true, true, false);
+
+	check_finish(6);
+}
+
+void
+tex_task1(TEXPTN texptn, intptr_t exinf)
+{
+	check_point(0);
+}
+
+void
+task2(intptr_t exinf)
+{
+	check_point(0);
+}
+
+void
+alarm1_handler(intptr_t exinf)
+{
+	check_point(0);
+}
+
+void
+cpuexc_handler(void *p_excinf)
+{
+	check_point(3);
+	check_state_i(true, true, true, true, false);
+	check_assert(xsns_xpn(p_excinf) == true);
+	check_assert(xsns_dpn(p_excinf) == true);
+
+#ifdef CANNOT_RETURN_CPUEXC
+	check_finish(4);
+#endif /* CANNOT_RETURN_CPUEXC */
+
+	check_point(4);
+}
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/test/test_cpuexc6.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/test/test_cpuexc6.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/test/test_cpuexc6.c	(revision 457)
@@ -0,0 +1,183 @@
+/*
+ *  TOPPERS Software
+ *      Toyohashi Open Platform for Embedded Real-Time Systems
+ * 
+ *  Copyright (C) 2007-2013 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  $Id$
+ */
+
+/* 
+ *		CPU例外処理のテスト(6)
+ *
+ * 【テストの目的】
+ *
+ *  割込み優先度マスク＝TIPM_ENAALL，ディスパッチ許可状態，タスク例外禁
+ *  止状態で発生したCPU例外におけるシステム状態のテスト．タスク切換えに
+ *  よりリカバリーできることもテストする．
+ *
+ * 【テスト項目】
+ *
+ *  いずれも，割込み優先度マスク＝TIPM_ENAALL，ディスパッチ許可状態，タ
+ *  スク例外禁止状態で発生したCPU例外において，
+ *
+ *	(A) CPU例外ハンドラ実行開始時にCPUロックフラグが変化しないこと
+ *	(B) CPU例外ハンドラ実行開始時に割込み優先度マスクが変化しないこと
+ *		！CPU例外ハンドラ中で割込み優先度マスクを読めないため，テストで
+ *		きない．
+ *	(C) CPU例外ハンドラ実行開始時にディスパッチ禁止フラグが変化しないこと
+ *	(D) CPU例外ハンドラ実行開始時にタスク例外処理禁止フラグが変化しないこと
+ *	(E) CPU例外ハンドラリターン時にCPUロックフラグが元に戻ること
+ *	(F) CPU例外ハンドラリターン時に割込み優先度マスクが元に戻ること
+ *	(G) CPU例外ハンドラリターン時にディスパッチ禁止フラグが変化しないこと
+ *	(H) CPU例外ハンドラリターン時にタスク例外処理禁止フラグが変化しないこと
+ *	(I) xsns_xpnがtrueを返すこと
+ *	(J) xsns_dpnがfalseを返すこと
+ *	(K) タスク切換えによるリカバリーができること
+ *
+ * 【使用リソース】
+ *
+ *	TASK1: TA_ACT，中優先度，タスク例外処理ルーチン登録
+ *	TASK2: TA_NULL，高優先度
+ *	CPUEXC1: TA_NULL
+ *
+ * 【テストシーケンス】
+ *
+ *	== TASK1（中優先度，1回目）==
+ *	1:	状態のチェック
+ *	2:	RAISE_CPU_EXCEPTION
+ *	== CPUEXC1 ==
+ *	3:	状態のチェック				... (A),(C),(D)
+ *		xsns_xpn() == true			... (I)
+ *		xsns_dpn() == false			... (J)
+ *  4:	iact_tsk(TASK2)
+ *		iloc_cpu()
+ *  	リターン
+ *	== TASK2（高優先度）==
+ *	5:	状態のチェック				... (E),(F),(G),(H)
+ *	6:	ter_tsk(TASK1)				... (K)
+ *	7:	act_tsk(TASK1)				... (K)
+ *	8:	ext_tsk()
+ *	== TASK1（中優先度，2回目）==
+ *	9:	状態のチェック				... (K)
+ *	10:	テスト終了
+ */
+
+#include <kernel.h>
+#include <test_lib.h>
+#include <t_syslog.h>
+#include "kernel_cfg.h"
+#include "test_cpuexc.h"
+
+int_t	task1_count = 0;
+
+void
+task1(intptr_t exinf)
+{
+	switch (++task1_count) {
+	case 1:
+		test_start(__FILE__);
+
+		check_point(1);
+		check_state(false, false, TIPM_ENAALL, false, false, true);
+
+		check_point(2);
+		RAISE_CPU_EXCEPTION;
+
+		check_point(0);
+		break;
+
+	case 2:
+		check_point(9);
+		check_state(false, false, TIPM_ENAALL, false, false, true);
+
+		check_finish(10);
+		break;
+
+	default:
+		check_point(0);
+		break;
+	}
+}
+
+void
+tex_task1(TEXPTN texptn, intptr_t exinf)
+{
+	check_point(0);
+}
+
+void
+task2(intptr_t exinf)
+{
+	ER		ercd;
+
+	check_point(5);
+	check_state(false, false, TIPM_ENAALL, false, false, true);
+
+	check_point(6);
+	ercd = ter_tsk(TASK1);
+	check_ercd(ercd, E_OK);
+
+	check_point(7);
+	ercd = act_tsk(TASK1);
+	check_ercd(ercd, E_OK);
+
+	check_point(8);
+	ercd = ext_tsk();
+	check_ercd(ercd, E_OK);
+
+	check_point(0);
+}
+
+void
+alarm1_handler(intptr_t exinf)
+{
+	check_point(0);
+}
+
+void
+cpuexc_handler(void *p_excinf)
+{
+	ER		ercd;
+
+	check_point(3);
+	check_state_i(true, false, false, true, true);
+	check_assert(xsns_xpn(p_excinf) == true);
+	check_assert(xsns_dpn(p_excinf) == false);
+
+	check_point(4);
+	ercd = iact_tsk(TASK2);
+	check_ercd(ercd, E_OK);
+	ercd = iloc_cpu();
+	check_ercd(ercd, E_OK);
+}
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/test/test_cpuexc7.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/test/test_cpuexc7.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/test/test_cpuexc7.c	(revision 457)
@@ -0,0 +1,187 @@
+/*
+ *  TOPPERS Software
+ *      Toyohashi Open Platform for Embedded Real-Time Systems
+ * 
+ *  Copyright (C) 2007-2013 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  $Id$
+ */
+
+/* 
+ *		CPU例外処理のテスト(7)
+ *
+ * 【テストの目的】
+ *
+ *  割込み優先度マスク＝TIPM_ENAALL，ディスパッチ禁止状態，タスク例外許
+ *  可状態で発生したCPU例外におけるシステム状態のテスト．タスク例外によ
+ *  りリカバリーできることもテストする．
+ *
+ * 【テスト項目】
+ *
+ *  いずれも，割込み優先度マスク＝TIPM_ENAALL，ディスパッチ禁止状態，タ
+ *  スク例外許可状態で発生したCPU例外において，
+ *
+ *	(A) CPU例外ハンドラ実行開始時にCPUロックフラグが変化しないこと
+ *	(B) CPU例外ハンドラ実行開始時に割込み優先度マスクが変化しないこと
+ *		！CPU例外ハンドラ中で割込み優先度マスクを読めないため，テストで
+ *		きない．
+ *	(C) CPU例外ハンドラ実行開始時にディスパッチ禁止フラグが変化しないこと
+ *	(D) CPU例外ハンドラ実行開始時にタスク例外処理禁止フラグが変化しないこと
+ *	(E) CPU例外ハンドラリターン時にCPUロックフラグが元に戻ること
+ *	(F) CPU例外ハンドラリターン時に割込み優先度マスクが元に戻ること
+ *	(G) CPU例外ハンドラリターン時にディスパッチ禁止フラグが変化しないこと
+ *	(H) CPU例外ハンドラリターン時にタスク例外処理禁止フラグが変化しないこと
+ *	(I) xsns_xpnがfalseを返すこと
+ *	(J) xsns_dpnがtrueを返すこと
+ *	(L) タスク例外によるリカバリーができること
+ *
+ * 【使用リソース】
+ *
+ *	TASK1: TA_ACT，中優先度，タスク例外処理ルーチン登録
+ *	CPUEXC1: TA_NULL
+ *
+ * 【テストシーケンス】
+ *
+ *	== TASK1（中優先度，1回目）==
+ *	1:	状態のチェック
+ *		dis_dsp()
+ *		ena_tex()
+ *	2:	状態のチェック
+ *		RAISE_CPU_EXCEPTION
+ *	== CPUEXC1 ==
+ *	3:	状態のチェック				... (A),(C),(D)
+ *		xsns_xpn() == false			... (I)
+ *		xsns_dpn() == true			... (J)
+ *	4:	iras_tex(TASK1, 1U)
+ *		iloc_cpu()
+ *		リターン
+ *	== TASK1のタスク例外処理ルーチン ==
+ *	5:	状態のチェック				... (E),(F),(G),(H)
+ *	6:	act_tsk(TASK1)				... (L)
+ *	7:	ext_tsk()					... (L)
+ *	== TASK1（中優先度，2回目）==
+ *	8:	状態のチェック				... (L)
+ *	9:	テスト終了
+ */
+
+#include <kernel.h>
+#include <test_lib.h>
+#include <t_syslog.h>
+#include "kernel_cfg.h"
+#include "test_cpuexc.h"
+
+int_t	task1_count = 0;
+
+void
+task1(intptr_t exinf)
+{
+	ER		ercd;
+
+	switch (++task1_count) {
+	case 1:
+		test_start(__FILE__);
+
+		check_point(1);
+		check_state(false, false, TIPM_ENAALL, false, false, true);
+		ercd = dis_dsp();
+		check_ercd(ercd, E_OK);
+		ercd = ena_tex();
+		check_ercd(ercd, E_OK);
+
+		check_point(2);
+		check_state(false, false, TIPM_ENAALL, true, true, false);
+		RAISE_CPU_EXCEPTION;
+
+		check_point(0);
+		break;
+
+	case 2:
+		check_point(8);
+		check_state(false, false, TIPM_ENAALL, false, false, true);
+
+		check_finish(9);
+		break;
+
+	default:
+		check_point(0);
+		break;
+	}
+}
+
+void
+tex_task1(TEXPTN texptn, intptr_t exinf)
+{
+	ER		ercd;
+
+	check_point(5);
+	check_state(false, false, TIPM_ENAALL, true, true, true);
+
+	check_point(6);
+	ercd = act_tsk(TASK1);
+	check_ercd(ercd, E_OK);
+
+	check_point(7);
+	ercd = ext_tsk();
+	check_ercd(ercd, E_OK);
+
+	check_point(0);
+}
+
+void
+task2(intptr_t exinf)
+{
+	check_point(0);
+}
+
+void
+alarm1_handler(intptr_t exinf)
+{
+	check_point(0);
+}
+
+void
+cpuexc_handler(void *p_excinf)
+{
+	ER		ercd;
+
+	check_point(3);
+	check_state_i(true, false, true, true, false);
+	check_assert(xsns_xpn(p_excinf) == false);
+	check_assert(xsns_dpn(p_excinf) == true);
+
+	check_point(4);
+	ercd = iras_tex(TASK1, 1U);
+	check_ercd(ercd, E_OK);
+	ercd = iloc_cpu();
+	check_ercd(ercd, E_OK);
+}
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/test/test_cpuexc8.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/test/test_cpuexc8.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/test/test_cpuexc8.c	(revision 457)
@@ -0,0 +1,162 @@
+/*
+ *  TOPPERS Software
+ *      Toyohashi Open Platform for Embedded Real-Time Systems
+ * 
+ *  Copyright (C) 2007-2013 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  $Id$
+ */
+
+/* 
+ *		CPU例外処理のテスト(8)
+ *
+ * 【テストの目的】
+ *
+ *  割込み優先度マスク＝TMAX_INTPRI，ディスパッチ許可状態，タスク例外許
+ *  可状態で発生したCPU例外におけるシステム状態のテスト．
+ *
+ *  このテストは，TMAX_INTPRIとTMIN_INTPRIが異なる場合のみ実施する．
+ *
+ * 【テスト項目】
+ *
+ *  いずれも，割込み優先度マスク＝TMAX_INTPRI，ディスパッチ許可状態，タ
+ *  スク例外許可状態で発生したCPU例外において，
+ *
+ *	(A) CPU例外ハンドラ実行開始時にCPUロックフラグが変化しないこと
+ *	(B) CPU例外ハンドラ実行開始時に割込み優先度マスクが変化しないこと
+ *		！CPU例外ハンドラ中で割込み優先度マスクを読めないため，テストで
+ *		きない．
+ *	(C) CPU例外ハンドラ実行開始時にディスパッチ禁止フラグが変化しないこと
+ *	(D) CPU例外ハンドラ実行開始時にタスク例外処理禁止フラグが変化しないこと
+ *	(E) CPU例外ハンドラリターン時にCPUロックフラグが元に戻ること
+ *		！CPU例外ハンドラからリターンできる場合のみテストする．
+ *	(F) CPU例外ハンドラリターン時に割込み優先度マスクが元に戻ること
+ *		！CPU例外ハンドラからリターンできる場合のみテストする．
+ *	(G) CPU例外ハンドラリターン時にディスパッチ禁止フラグが変化しないこと
+ *		！CPU例外ハンドラからリターンできる場合のみテストする．
+ *	(H) CPU例外ハンドラリターン時にタスク例外処理禁止フラグが変化しないこと
+ *		！CPU例外ハンドラからリターンできる場合のみテストする．
+ *	(I) xsns_xpnがtrueを返すこと
+ *	(J) xsns_dpnがtrueを返すこと
+ *
+ * 【使用リソース】
+ *
+ *	TASK1: TA_ACT，中優先度，タスク例外処理ルーチン登録
+ *	CPUEXC1: TA_NULL
+ *
+ * 【テストシーケンス】
+ *
+ *	== TASK1（中優先度）==
+ *	1:	状態のチェック
+ *		chg_ipm(TMAX_INTPRI)
+ *		ena_tex()
+ *	2:	状態のチェック
+ *		RAISE_CPU_EXCEPTION
+ *	== CPUEXC1 ==
+ *	3:	状態のチェック				... (A)(C)(D)
+ *		xsns_xpn() == true			... (I)
+ *		xsns_dpn() == true			... (J)
+ *	4:	CPU例外ハンドラからリターンできない場合は，ここで終了
+ *	4:	リターン
+ *	== TASK1（続き）==
+ *	5:	状態のチェック				... (E)(F)(G)(H)
+ *	6:	テスト終了
+ */
+
+#include <kernel.h>
+#include <test_lib.h>
+#include <t_syslog.h>
+#include "kernel_cfg.h"
+#include "test_cpuexc.h"
+
+void
+task1(intptr_t exinf)
+{
+	ER		ercd;
+
+	test_start(__FILE__);
+
+	if (TMAX_INTPRI == TMIN_INTPRI) {
+		syslog_0(LOG_NOTICE, "This test program is not necessary.");
+		ext_ker();
+	}
+
+	check_point(1);
+	check_state(false, false, TIPM_ENAALL, false, false, true);
+	ercd = chg_ipm(TMAX_INTPRI);
+	check_ercd(ercd, E_OK);
+	ercd = ena_tex();
+	check_ercd(ercd, E_OK);
+
+	check_point(2);
+	check_state(false, false, TMAX_INTPRI, false, true, false);
+	RAISE_CPU_EXCEPTION;
+
+	check_point(5);
+	check_state(false, false, TMAX_INTPRI, false, true, false);
+
+	check_finish(6);
+}
+
+void
+tex_task1(TEXPTN texptn, intptr_t exinf)
+{
+	check_point(0);
+}
+
+void
+task2(intptr_t exinf)
+{
+	check_point(0);
+}
+
+void
+alarm1_handler(intptr_t exinf)
+{
+	check_point(0);
+}
+
+void
+cpuexc_handler(void *p_excinf)
+{
+	check_point(3);
+	check_state_i(true, false, false, true, false);
+	check_assert(xsns_xpn(p_excinf) == true);
+	check_assert(xsns_dpn(p_excinf) == true);
+
+#ifdef CANNOT_RETURN_CPUEXC
+	check_finish(4);
+#endif /* CANNOT_RETURN_CPUEXC */
+
+	check_point(4);
+}
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/test/test_cpuexc9.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/test/test_cpuexc9.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/test/test_cpuexc9.c	(revision 457)
@@ -0,0 +1,155 @@
+/*
+ *  TOPPERS Software
+ *      Toyohashi Open Platform for Embedded Real-Time Systems
+ * 
+ *  Copyright (C) 2007-2013 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  $Id$
+ */
+
+/* 
+ *		CPU例外処理のテスト(9)
+ *
+ * 【テストの目的】
+ *
+ *  割込み優先度マスク＝TMIN_INTPRI，ディスパッチ許可状態，タスク例外許
+ *  可状態で発生したCPU例外におけるシステム状態のテスト．
+ *
+ * 【テスト項目】
+ *
+ *  いずれも，割込み優先度マスク＝TMIN_INTPRI，ディスパッチ許可状態，タ
+ *  スク例外許可状態で発生したCPU例外において，
+ *
+ *	(A) CPU例外ハンドラ実行開始時にCPUロックフラグが変化しないこと
+ *	(B) CPU例外ハンドラ実行開始時に割込み優先度マスクが変化しないこと
+ *		！CPU例外ハンドラ中で割込み優先度マスクを読めないため，テストで
+ *		きない．
+ *	(C) CPU例外ハンドラ実行開始時にディスパッチ禁止フラグが変化しないこと
+ *	(D) CPU例外ハンドラ実行開始時にタスク例外処理禁止フラグが変化しないこと
+ *	(E) CPU例外ハンドラリターン時にCPUロックフラグが元に戻ること
+ *		！CPU例外ハンドラからリターンできる場合のみテストする．
+ *	(F) CPU例外ハンドラリターン時に割込み優先度マスクが元に戻ること
+ *		！CPU例外ハンドラからリターンできる場合のみテストする．
+ *	(G) CPU例外ハンドラリターン時にディスパッチ禁止フラグが変化しないこと
+ *		！CPU例外ハンドラからリターンできる場合のみテストする．
+ *	(H) CPU例外ハンドラリターン時にタスク例外処理禁止フラグが変化しないこと
+ *		！CPU例外ハンドラからリターンできる場合のみテストする．
+ *	(I) xsns_xpnがtrueを返すこと
+ *	(J) xsns_dpnがtrueを返すこと
+ *
+ * 【使用リソース】
+ *
+ *	TASK1: TA_ACT，中優先度，タスク例外処理ルーチン登録
+ *	CPUEXC1: TA_NULL
+ *
+ * 【テストシーケンス】
+ *
+ *	== TASK1（中優先度）==
+ *	1:	状態のチェック
+ *		chg_ipm(TMIN_INTPRI)
+ *		ena_tex()
+ *	2:	状態のチェック
+ *		RAISE_CPU_EXCEPTION
+ *	== CPUEXC1 ==
+ *	3:	状態のチェック				... (A)(C)(D)
+ *		xsns_xpn() == true			... (I)
+ *		xsns_dpn() == true			... (J)
+ *	4:	CPU例外ハンドラからリターンできない場合は，ここで終了
+ *	4:	リターン
+ *	== TASK1（続き）==
+ *	5:	状態のチェック				... (E)(F)(G)(H)
+ *	6:	テスト終了
+ */
+
+#include <kernel.h>
+#include <test_lib.h>
+#include <t_syslog.h>
+#include "kernel_cfg.h"
+#include "test_cpuexc.h"
+
+void
+task1(intptr_t exinf)
+{
+	ER		ercd;
+
+	test_start(__FILE__);
+
+	check_point(1);
+	check_state(false, false, TIPM_ENAALL, false, false, true);
+	ercd = chg_ipm(TMIN_INTPRI);
+	check_ercd(ercd, E_OK);
+	ercd = ena_tex();
+	check_ercd(ercd, E_OK);
+
+	check_point(2);
+	check_state(false, false, TMIN_INTPRI, false, true, false);
+	RAISE_CPU_EXCEPTION;
+
+	check_point(5);
+	check_state(false, false, TMIN_INTPRI, false, true, false);
+
+	check_finish(6);
+}
+
+void
+tex_task1(TEXPTN texptn, intptr_t exinf)
+{
+	check_point(0);
+}
+
+void
+task2(intptr_t exinf)
+{
+	check_point(0);
+}
+
+void
+alarm1_handler(intptr_t exinf)
+{
+	check_point(0);
+}
+
+void
+cpuexc_handler(void *p_excinf)
+{
+	check_point(3);
+	check_state_i(true, false, false, true, false);
+	check_assert(xsns_xpn(p_excinf) == true);
+	check_assert(xsns_dpn(p_excinf) == true);
+
+#ifdef CANNOT_RETURN_CPUEXC
+	check_finish(4);
+#endif /* CANNOT_RETURN_CPUEXC */
+
+	check_point(4);
+}
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/test/test_dlynse.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/test/test_dlynse.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/test/test_dlynse.c	(revision 457)
@@ -0,0 +1,120 @@
+/*
+ *  TOPPERS Software
+ *      Toyohashi Open Platform for Embedded Real-Time Systems
+ * 
+ *  Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
+ *                              Toyohashi Univ. of Technology, JAPAN
+ *  Copyright (C) 2007-2013 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  $Id$
+ */
+
+/*
+ *		sil_dly_nseに関するテスト
+ */
+
+#include <kernel.h>
+#include <sil.h>
+#include <test_lib.h>
+#include <t_syslog.h>
+#include "kernel_cfg.h"
+#include "test_dlynse.h"
+
+/*
+ *  SIL_DLY_TIM1とSIL_DLY_TIM2を参照するために，カーネル用のヘッダファ
+ *  イルをインクルードする．
+ */
+#include "kernel/kernel_impl.h"
+
+#define	NO_LOOP		ULONG_C(1000000)
+
+SYSTIM	empty_time;
+
+static void
+test_empty(void)
+{
+	SYSTIM	stime, etime;
+	volatile ulong_t	i;
+
+	get_tim(&stime);
+	for (i = 0; i < NO_LOOP; i++) {
+	}
+	get_tim(&etime);
+	empty_time = etime - stime;
+	syslog(LOG_NOTICE, "empty loop: %u", empty_time);
+	syslog_flush();
+}
+
+static void
+test_dly_nse(ulong_t dlytim)
+{
+	SYSTIM	stime, etime, delay_time;
+	volatile ulong_t	i;
+
+	get_tim(&stime);
+	for (i = 0; i < NO_LOOP; i++) {
+		sil_dly_nse(dlytim);
+	}
+	get_tim(&etime);
+	delay_time = (etime - stime) - empty_time;
+	syslog(LOG_NOTICE, "sil_dly_nse(%u): %u %s", (uint_t)(dlytim),
+				(uint_t)(delay_time), delay_time > dlytim ? "OK" : "NG");
+	syslog_flush();
+}
+
+void
+main_task(intptr_t exinf)
+{
+	test_start(__FILE__);
+
+	test_empty();
+
+	syslog(LOG_NOTICE, "-- for fitting parameters --");
+	test_dly_nse(0);
+	test_dly_nse(SIL_DLY_TIM1);
+	test_dly_nse(SIL_DLY_TIM1 + SIL_DLY_TIM2 * 1);
+	test_dly_nse(SIL_DLY_TIM1 + SIL_DLY_TIM2 * 2);
+	test_dly_nse(SIL_DLY_TIM1 + SIL_DLY_TIM2 * 3);
+	test_dly_nse(SIL_DLY_TIM1 + SIL_DLY_TIM2 * 4);
+	test_dly_nse(SIL_DLY_TIM1 + SIL_DLY_TIM2 * 5);
+	test_dly_nse(SIL_DLY_TIM1 + SIL_DLY_TIM2 * 10);
+	test_dly_nse(SIL_DLY_TIM1 + SIL_DLY_TIM2 * 20);
+	test_dly_nse(SIL_DLY_TIM1 + SIL_DLY_TIM2 * 50);
+
+	syslog(LOG_NOTICE, "-- for checking boundary conditions --");
+	test_dly_nse(SIL_DLY_TIM1 + 1);
+	test_dly_nse(SIL_DLY_TIM1 + SIL_DLY_TIM2 * 1 + 1);
+	test_dly_nse(SIL_DLY_TIM1 + SIL_DLY_TIM2 * 2 + 1);
+
+	test_finish();
+}
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/test/test_dlynse.cfg
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/test/test_dlynse.cfg	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/test/test_dlynse.cfg	(revision 457)
@@ -0,0 +1,14 @@
+/*
+ *  @(#) $Id$
+ */
+
+/*
+ *  sil_dly_nseに関するテストのシステムコンフィギュレーションファイル
+ */
+INCLUDE("target_timer.cfg");
+INCLUDE("syssvc/syslog.cfg");
+INCLUDE("syssvc/banner.cfg");
+INCLUDE("syssvc/serial.cfg");
+
+#include "test_dlynse.h"
+CRE_TSK(MAIN_TASK, { TA_ACT, 0, main_task, MAIN_PRIORITY, STACK_SIZE, NULL });
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/test/test_dlynse.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/test/test_dlynse.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/test/test_dlynse.h	(revision 457)
@@ -0,0 +1,68 @@
+/*
+ *  TOPPERS Software
+ *      Toyohashi Open Platform for Embedded Real-Time Systems
+ * 
+ *  Copyright (C) 2006,2007 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *		sil_dly_nseに関するテスト
+ */
+
+/*
+ *  ターゲット依存の定義
+ */
+#include "target_test.h"
+
+/*
+ *  各タスクの優先度の定義
+ */
+#define MAIN_PRIORITY	10
+
+/*
+ *  ターゲットに依存する可能性のある定数の定義
+ */
+#ifndef STACK_SIZE
+#define	STACK_SIZE		4096		/* タスクのスタックサイズ */
+#endif /* STACK_SIZE */
+
+/*
+ *  関数のプロトタイプ宣言
+ */
+#ifndef TOPPERS_MACRO_ONLY
+
+extern void	main_task(intptr_t exinf);
+
+#endif /* TOPPERS_MACRO_ONLY */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/test/test_sem1.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/test/test_sem1.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/test/test_sem1.c	(revision 457)
@@ -0,0 +1,615 @@
+/*
+ *  TOPPERS Software
+ *      Toyohashi Open Platform for Embedded Real-Time Systems
+ * 
+ *  Copyright (C) 2008-2014 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  $Id$
+ */
+
+/* 
+ *		セマフォ機能のテスト(1)
+ *
+ * 【テストの目的】
+ *
+ *  sig_sem，wai_sem，CRE_SEMを網羅的にテストする．
+ *  ただし，CRE_SEMのエラーのテストは除く．
+ *
+ * 【テスト項目】
+ *
+ *	(A) sig_semの静的エラーのテスト
+ *		(A-1) 非タスクコンテキストからの呼出し
+ *		(A-2) CPUロック状態からの呼出し
+ *		(A-3) semidが不正（小さすぎる）
+ *		(A-4) semidが不正（大きすぎる）
+ *	(B) sig_semによりセマフォ待ち状態のタスクが待ち解除される
+ *		(B-1) 待ち解除されたタスクに切り換わる
+ *		(B-2) ディスパッチ保留状態で，切り換わらない
+ *		(B-3) 待ち解除されたタスクが強制待ち状態で，切り換わらない
+ *		(B-4) 待ち解除されたタスクが優先度が低く，切り換わらない
+ *	(C) sig_semによりセマフォの資源数が1増える
+ *		(C-1) セマフォの資源数が0から1になる
+ *		(C-2) セマフォの資源数が1から2になる
+ *	(D) sig_semがE_QOVRエラーとなる
+ *		(D-1) セマフォの最大資源数が1の時
+ *		(D-2) セマフォの最大資源数が2の時
+ *	(E) wai_semの静的エラーのテスト
+ *		(E-1) 非タスクコンテキストからの呼出し
+ *		(E-2) CPUロック状態からの呼出し
+ *		(E-3) ディスパッチ禁止状態からの呼出し
+ *		(E-4) 割込み優先度マスク全解除でない状態からの呼出し
+ *		(E-5) semidが不正（小さすぎる）
+ *		(E-6) semidが不正（大きすぎる）
+ *	(F) wai_semによりセマフォの資源数が1減る
+ *		(F-1) セマフォの資源数が1から0になる
+ *		(F-2) セマフォの資源数が2から1になる
+ *	(G) wai_semによりセマフォ待ち状態になる
+ *		(G-1) TA_TNULL属性のセマフォで，待っているタスクがなかった場合
+ *		(G-2) TA_TNULL属性のセマフォで，待っているタスクがあった場合
+ *		(G-3) TA_TPRI属性のセマフォで，待っているタスクがなかった場合
+ *		(G-4) TA_TPRI属性のセマフォで，優先度が高いタスクが待っている場合
+ *		(G-5) TA_TPRI属性のセマフォで，優先度が同じタスクが待っている場合
+ *		(G-6) TA_TPRI属性のセマフォで，優先度が低いタスクが待っている場合
+ *	(H) セマフォ待ち状態が強制解除される
+ *	(I) セマフォ待ち状態の間にセマフォが初期化される
+ *	(J) セマフォの資源数の初期値が正しく設定される
+ *		(J-1) セマフォの資源数の初期値が0
+ *		(J-2) セマフォの資源数の初期値が1
+ *		(J-3) セマフォの資源数の初期値が2
+ *
+ * 【使用リソース】
+ *
+ *	TASK1: 中優先度タスク，TA_ACT属性
+ *	TASK2: 高優先度タスク
+ *	TASK3: 低優先度タスク
+ *	TASK4: 中優先度タスク
+ *	TASK5: 中優先度タスク
+ *	ALM1:  アラームハンドラ
+ *  SEM1:  TA_NULL属性，初期資源数1，最大資源数1
+ *  SEM2:  TA_NULL属性，初期資源数2，最大資源数2
+ *  SEM3:  TA_TPRI属性，初期資源数0，最大資源数1
+ *
+ * 【テストシーケンス】
+ *
+ *	== TASK1（優先度：中）==
+ *  1:	ref_sem(SEM1, &rsem)
+ *		assert(rsem.wtskid == TSK_NONE)
+ *		assert(rsem.semcnt == 1)			... (J-2)
+ *  	ref_sem(SEM2, &rsem)
+ *		assert(rsem.wtskid == TSK_NONE)
+ *		assert(rsem.semcnt == 2)			... (J-3)
+ *  	ref_sem(SEM3, &rsem)
+ *		assert(rsem.wtskid == TSK_NONE)
+ *		assert(rsem.semcnt == 0)			... (J-1)
+ *	2:	loc_cpu()
+ *		sig_sem(SEM1) -> E_CTX				... (A-2)
+ *		wai_sem(SEM1) -> E_CTX				... (E-2)
+ *		unl_cpu()
+ *		dis_dsp()
+ *		wai_sem(SEM1) -> E_CTX				... (E-3)
+ *		ena_dsp()
+ *		chg_ipm(TMAX_INTPRI)
+ *		wai_sem(SEM1) -> E_CTX				... (E-4)
+ *		chg_ipm(TIPM_ENAALL)
+ *		sig_sem(0) -> E_ID					... (A-3)
+ *		wai_sem(0) -> E_ID					... (E-5)
+ *		sig_sem(TNUM_SEMID+1) -> E_ID		... (A-4)
+ *		wai_sem(TNUM_SEMID+1) -> E_ID		... (E-6)
+ *	3:	act_tsk(TASK3)
+ *	4:	slp_tsk()
+ *	== TASK3（優先度：低）==
+ *	5:	wai_sem(SEM1)						... (F-1)
+ *  6:	ref_sem(SEM1, &rsem)
+ *		assert(rsem.wtskid == TSK_NONE)
+ *		assert(rsem.semcnt == 0)
+ *	7:	sta_alm(ALM1, 10)
+ *	8:	wai_sem(SEM1)						... (G-1)
+ *	== ALM1 ==
+ *	9:	sig_sem(SEM1) -> E_CTX				... (A-1)
+ *		wai_sem(SEM1) -> E_CTX				... (E-1)
+ *	10:	iwup_tsk(TASK1)
+ *	11:	RETURN
+ *	== TASK1（続き）==
+ *	12:	act_tsk(TASK2)
+ *	== TASK2（優先度：高）==
+ *	13:	wai_sem(SEM1)						... (G-2)
+ *	== TASK1（続き）==
+ *  14:	ref_sem(SEM1, &rsem)
+ *		assert(rsem.wtskid == TASK3)
+ *		assert(rsem.semcnt == 0)
+ *	15:	sig_sem(SEM1)						... (B-4)
+ *	16:	sig_sem(SEM1)						... (B-1)
+ *	== TASK2（続き）==
+ *	17:	wai_sem(SEM1)						... (G-1)
+ *	== TASK1（続き）==
+ *	18: dis_dsp()
+ *	19:	sig_sem(SEM1)						... (B-2)
+ *	20:	ena_dsp()
+ *	== TASK2（続き）==
+ *	21:	wai_sem(SEM1)						... (G-1)
+ *	== TASK1（続き）==
+ *	22: sus_tsk(TASK2)
+ *	23:	sig_sem(SEM1)						... (B-3)
+ *	24: sig_sem(SEM1)						... (C-1)
+ *	25: sig_sem(SEM1) -> E_QOVR				... (D-1)
+ *  26:	ref_sem(SEM1, &rsem)
+ *		assert(rsem.wtskid == TSK_NONE)
+ *		assert(rsem.semcnt == 1)
+ *	27:	rsm_tsk(TASK2)
+ *	== TASK2（続き）==
+ *	28:	wai_sem(SEM2)						... (F-2)
+ *  29:	ref_sem(SEM2, &rsem)
+ *		assert(rsem.wtskid == TSK_NONE)
+ *		assert(rsem.semcnt == 1)
+ *	30:	wai_sem(SEM2)						... (F-1)
+ *	31: wai_sem(SEM2)						... (G-1)
+ *	== TASK1（続き）==
+ *	32:	sig_sem(SEM2)						... (B-1)
+ *	== TASK2（続き）==
+ *	33:	wai_sem(SEM3)						... (G-3)
+ *	== TASK1（続き）==
+ *	34:	sig_sem(SEM2)						... (C-1)
+ *	35:	sig_sem(SEM2)						... (C-2)
+ *  36:	ref_sem(SEM2, &rsem)
+ *		assert(rsem.wtskid == TSK_NONE)
+ *		assert(rsem.semcnt == 2)
+ *	37:	sig_sem(SEM2) -> E_QOVR				... (D-2)
+ *  38:	ref_sem(SEM2, &rsem)
+ *		assert(rsem.wtskid == TSK_NONE)
+ *		assert(rsem.semcnt == 2)
+ *	39:	tslp_tsk(10) -> E_TMOUT
+ *	== TASK3（続き）==
+ *	40:	wai_sem(SEM3)						... (G-4)
+ *	== TASK1（続き）==
+ *	41:	act_tsk(TASK4)
+ *	42:	act_tsk(TASK5)
+ *	43:	rot_rdq(TPRI_SELF)
+ *	== TASK4（優先度：中）==
+ *	44:	wai_sem(SEM3)						... (G-6)
+ *	== TASK5（優先度：中）==
+ *	45:	wai_sem(SEM3)						... (G-5)
+ *	== TASK1（続き）==
+ *	46:	sig_sem(SEM3)						... (B-1)
+ *	== TASK2（続き）==
+ *	47:	wai_sem(SEM1)
+ *		wai_sem(SEM1) -> E_RLWAI
+ *	== TASK1（続き）==
+ *	48:	sig_sem(SEM3)						... (B-4)
+ *	49:	tslp_tsk(10) -> E_TMOUT
+ *	== TASK4（続き）==
+ *	50:	ext_tsk() -> noreturn
+ *	== TASK1（続き）==
+ *	51:	sig_sem(SEM3)						... (B-4)
+ *	52:	tslp_tsk(10) -> E_TMOUT
+ *	== TASK5（続き）==
+ *	53:	ext_tsk() -> noreturn
+ *	== TASK1（続き）==
+ *	54:	sig_sem(SEM3)						... (B-4)
+ *	55:	tslp_tsk(10) -> E_TMOUT
+ *	== TASK3（続き）==
+ *	56:	ext_tsk() -> noreturn
+ *	== TASK1（続き）==
+ *	57: rel_wai(TASK2)						... (H)
+ *	== TASK2（続き）==
+ *	58:	wai_sem(SEM1) -> E_DLT
+ *	== TASK1（続き）==
+ *	59: ini_sem(SEM1)						... (I)
+ *	== TASK2（続き）==
+ *	60: ext_tsk() -> noreturn
+ *	== TASK1（続き）==
+ *	61: END
+ */
+
+#include <kernel.h>
+#include <test_lib.h>
+#include <t_syslog.h>
+#include "kernel_cfg.h"
+#include "test_sem1.h"
+
+/* DO NOT DELETE THIS LINE -- gentest depends on it. */
+
+void
+alarm1_handler(intptr_t exinf)
+{
+	ER_UINT	ercd;
+
+	check_point(9);
+	ercd = sig_sem(SEM1);
+	check_ercd(ercd, E_CTX);
+
+	ercd = wai_sem(SEM1);
+	check_ercd(ercd, E_CTX);
+
+	check_point(10);
+	ercd = iwup_tsk(TASK1);
+	check_ercd(ercd, E_OK);
+
+	check_point(11);
+	return;
+
+	check_point(0);
+}
+
+void
+task1(intptr_t exinf)
+{
+	ER_UINT	ercd;
+	T_RSEM	rsem;
+
+	test_start(__FILE__);
+
+	check_point(1);
+	ercd = ref_sem(SEM1, &rsem);
+	check_ercd(ercd, E_OK);
+
+	check_assert(rsem.wtskid == TSK_NONE);
+
+	check_assert(rsem.semcnt == 1);
+
+	ercd = ref_sem(SEM2, &rsem);
+	check_ercd(ercd, E_OK);
+
+	check_assert(rsem.wtskid == TSK_NONE);
+
+	check_assert(rsem.semcnt == 2);
+
+	ercd = ref_sem(SEM3, &rsem);
+	check_ercd(ercd, E_OK);
+
+	check_assert(rsem.wtskid == TSK_NONE);
+
+	check_assert(rsem.semcnt == 0);
+
+	check_point(2);
+	ercd = loc_cpu();
+	check_ercd(ercd, E_OK);
+
+	ercd = sig_sem(SEM1);
+	check_ercd(ercd, E_CTX);
+
+	ercd = wai_sem(SEM1);
+	check_ercd(ercd, E_CTX);
+
+	ercd = unl_cpu();
+	check_ercd(ercd, E_OK);
+
+	ercd = dis_dsp();
+	check_ercd(ercd, E_OK);
+
+	ercd = wai_sem(SEM1);
+	check_ercd(ercd, E_CTX);
+
+	ercd = ena_dsp();
+	check_ercd(ercd, E_OK);
+
+	ercd = chg_ipm(TMAX_INTPRI);
+	check_ercd(ercd, E_OK);
+
+	ercd = wai_sem(SEM1);
+	check_ercd(ercd, E_CTX);
+
+	ercd = chg_ipm(TIPM_ENAALL);
+	check_ercd(ercd, E_OK);
+
+	ercd = sig_sem(0);
+	check_ercd(ercd, E_ID);
+
+	ercd = wai_sem(0);
+	check_ercd(ercd, E_ID);
+
+	ercd = sig_sem(TNUM_SEMID+1);
+	check_ercd(ercd, E_ID);
+
+	ercd = wai_sem(TNUM_SEMID+1);
+	check_ercd(ercd, E_ID);
+
+	check_point(3);
+	ercd = act_tsk(TASK3);
+	check_ercd(ercd, E_OK);
+
+	check_point(4);
+	ercd = slp_tsk();
+	check_ercd(ercd, E_OK);
+
+	check_point(12);
+	ercd = act_tsk(TASK2);
+	check_ercd(ercd, E_OK);
+
+	check_point(14);
+	ercd = ref_sem(SEM1, &rsem);
+	check_ercd(ercd, E_OK);
+
+	check_assert(rsem.wtskid == TASK3);
+
+	check_assert(rsem.semcnt == 0);
+
+	check_point(15);
+	ercd = sig_sem(SEM1);
+	check_ercd(ercd, E_OK);
+
+	check_point(16);
+	ercd = sig_sem(SEM1);
+	check_ercd(ercd, E_OK);
+
+	check_point(18);
+	ercd = dis_dsp();
+	check_ercd(ercd, E_OK);
+
+	check_point(19);
+	ercd = sig_sem(SEM1);
+	check_ercd(ercd, E_OK);
+
+	check_point(20);
+	ercd = ena_dsp();
+	check_ercd(ercd, E_OK);
+
+	check_point(22);
+	ercd = sus_tsk(TASK2);
+	check_ercd(ercd, E_OK);
+
+	check_point(23);
+	ercd = sig_sem(SEM1);
+	check_ercd(ercd, E_OK);
+
+	check_point(24);
+	ercd = sig_sem(SEM1);
+	check_ercd(ercd, E_OK);
+
+	check_point(25);
+	ercd = sig_sem(SEM1);
+	check_ercd(ercd, E_QOVR);
+
+	check_point(26);
+	ercd = ref_sem(SEM1, &rsem);
+	check_ercd(ercd, E_OK);
+
+	check_assert(rsem.wtskid == TSK_NONE);
+
+	check_assert(rsem.semcnt == 1);
+
+	check_point(27);
+	ercd = rsm_tsk(TASK2);
+	check_ercd(ercd, E_OK);
+
+	check_point(32);
+	ercd = sig_sem(SEM2);
+	check_ercd(ercd, E_OK);
+
+	check_point(34);
+	ercd = sig_sem(SEM2);
+	check_ercd(ercd, E_OK);
+
+	check_point(35);
+	ercd = sig_sem(SEM2);
+	check_ercd(ercd, E_OK);
+
+	check_point(36);
+	ercd = ref_sem(SEM2, &rsem);
+	check_ercd(ercd, E_OK);
+
+	check_assert(rsem.wtskid == TSK_NONE);
+
+	check_assert(rsem.semcnt == 2);
+
+	check_point(37);
+	ercd = sig_sem(SEM2);
+	check_ercd(ercd, E_QOVR);
+
+	check_point(38);
+	ercd = ref_sem(SEM2, &rsem);
+	check_ercd(ercd, E_OK);
+
+	check_assert(rsem.wtskid == TSK_NONE);
+
+	check_assert(rsem.semcnt == 2);
+
+	check_point(39);
+	ercd = tslp_tsk(10);
+	check_ercd(ercd, E_TMOUT);
+
+	check_point(41);
+	ercd = act_tsk(TASK4);
+	check_ercd(ercd, E_OK);
+
+	check_point(42);
+	ercd = act_tsk(TASK5);
+	check_ercd(ercd, E_OK);
+
+	check_point(43);
+	ercd = rot_rdq(TPRI_SELF);
+	check_ercd(ercd, E_OK);
+
+	check_point(46);
+	ercd = sig_sem(SEM3);
+	check_ercd(ercd, E_OK);
+
+	check_point(48);
+	ercd = sig_sem(SEM3);
+	check_ercd(ercd, E_OK);
+
+	check_point(49);
+	ercd = tslp_tsk(10);
+	check_ercd(ercd, E_TMOUT);
+
+	check_point(51);
+	ercd = sig_sem(SEM3);
+	check_ercd(ercd, E_OK);
+
+	check_point(52);
+	ercd = tslp_tsk(10);
+	check_ercd(ercd, E_TMOUT);
+
+	check_point(54);
+	ercd = sig_sem(SEM3);
+	check_ercd(ercd, E_OK);
+
+	check_point(55);
+	ercd = tslp_tsk(10);
+	check_ercd(ercd, E_TMOUT);
+
+	check_point(57);
+	ercd = rel_wai(TASK2);
+	check_ercd(ercd, E_OK);
+
+	check_point(59);
+	ercd = ini_sem(SEM1);
+	check_ercd(ercd, E_OK);
+
+	check_finish(61);
+	check_point(0);
+}
+
+void
+task2(intptr_t exinf)
+{
+	ER_UINT	ercd;
+	T_RSEM	rsem;
+
+	check_point(13);
+	ercd = wai_sem(SEM1);
+	check_ercd(ercd, E_OK);
+
+	check_point(17);
+	ercd = wai_sem(SEM1);
+	check_ercd(ercd, E_OK);
+
+	check_point(21);
+	ercd = wai_sem(SEM1);
+	check_ercd(ercd, E_OK);
+
+	check_point(28);
+	ercd = wai_sem(SEM2);
+	check_ercd(ercd, E_OK);
+
+	check_point(29);
+	ercd = ref_sem(SEM2, &rsem);
+	check_ercd(ercd, E_OK);
+
+	check_assert(rsem.wtskid == TSK_NONE);
+
+	check_assert(rsem.semcnt == 1);
+
+	check_point(30);
+	ercd = wai_sem(SEM2);
+	check_ercd(ercd, E_OK);
+
+	check_point(31);
+	ercd = wai_sem(SEM2);
+	check_ercd(ercd, E_OK);
+
+	check_point(33);
+	ercd = wai_sem(SEM3);
+	check_ercd(ercd, E_OK);
+
+	check_point(47);
+	ercd = wai_sem(SEM1);
+	check_ercd(ercd, E_OK);
+
+	ercd = wai_sem(SEM1);
+	check_ercd(ercd, E_RLWAI);
+
+	check_point(58);
+	ercd = wai_sem(SEM1);
+	check_ercd(ercd, E_DLT);
+
+	check_point(60);
+	ercd = ext_tsk();
+
+	check_point(0);
+}
+
+void
+task3(intptr_t exinf)
+{
+	ER_UINT	ercd;
+	T_RSEM	rsem;
+
+	check_point(5);
+	ercd = wai_sem(SEM1);
+	check_ercd(ercd, E_OK);
+
+	check_point(6);
+	ercd = ref_sem(SEM1, &rsem);
+	check_ercd(ercd, E_OK);
+
+	check_assert(rsem.wtskid == TSK_NONE);
+
+	check_assert(rsem.semcnt == 0);
+
+	check_point(7);
+	ercd = sta_alm(ALM1, 10);
+	check_ercd(ercd, E_OK);
+
+	check_point(8);
+	ercd = wai_sem(SEM1);
+	check_ercd(ercd, E_OK);
+
+	check_point(40);
+	ercd = wai_sem(SEM3);
+	check_ercd(ercd, E_OK);
+
+	check_point(56);
+	ercd = ext_tsk();
+
+	check_point(0);
+}
+
+void
+task4(intptr_t exinf)
+{
+	ER_UINT	ercd;
+
+	check_point(44);
+	ercd = wai_sem(SEM3);
+	check_ercd(ercd, E_OK);
+
+	check_point(50);
+	ercd = ext_tsk();
+
+	check_point(0);
+}
+
+void
+task5(intptr_t exinf)
+{
+	ER_UINT	ercd;
+
+	check_point(45);
+	ercd = wai_sem(SEM3);
+	check_ercd(ercd, E_OK);
+
+	check_point(53);
+	ercd = ext_tsk();
+
+	check_point(0);
+}
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/test/test_sem1.cfg
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/test/test_sem1.cfg	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/test/test_sem1.cfg	(revision 457)
@@ -0,0 +1,23 @@
+/*
+ *  @(#) $Id$
+ */
+
+/*
+ *  セマフォ機能のテスト(1)のシステムコンフィギュレーションファイル
+ */
+INCLUDE("target_timer.cfg");
+INCLUDE("syssvc/syslog.cfg");
+INCLUDE("syssvc/banner.cfg");
+INCLUDE("syssvc/serial.cfg");
+
+#include "test_sem1.h"
+
+CRE_TSK(TASK1, { TA_ACT, 1, task1, MID_PRIORITY, STACK_SIZE, NULL });
+CRE_TSK(TASK2, { TA_NULL, 2, task2, HIGH_PRIORITY, STACK_SIZE, NULL });
+CRE_TSK(TASK3, { TA_NULL, 3, task3, LOW_PRIORITY, STACK_SIZE, NULL });
+CRE_TSK(TASK4, { TA_NULL, 4, task4, MID_PRIORITY, STACK_SIZE, NULL });
+CRE_TSK(TASK5, { TA_NULL, 5, task5, MID_PRIORITY, STACK_SIZE, NULL });
+CRE_ALM(ALM1, { TA_NULL, 1, alarm1_handler });
+CRE_SEM(SEM1, { TA_NULL, 1, 1 });
+CRE_SEM(SEM2, { TA_NULL, 2, 2 });
+CRE_SEM(SEM3, { TA_TPRI, 0, 1 });
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/test/test_sem1.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/test/test_sem1.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/test/test_sem1.h	(revision 457)
@@ -0,0 +1,75 @@
+/*
+ *  TOPPERS Software
+ *      Toyohashi Open Platform for Embedded Real-Time Systems
+ * 
+ *  Copyright (C) 2008 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/* 
+ *		セマフォ機能のテスト(1)
+ */
+
+/*
+ *  ターゲット依存の定義
+ */
+#include "target_test.h"
+
+/*
+ *  優先度の定義
+ */
+#define HIGH_PRIORITY	9		/* 高優先度 */
+#define MID_PRIORITY	10		/* 中優先度 */
+#define LOW_PRIORITY	11		/* 低優先度 */
+
+/*
+ *  ターゲットに依存する可能性のある定数の定義
+ */
+#ifndef STACK_SIZE
+#define	STACK_SIZE		4096		/* タスクのスタックサイズ */
+#endif /* STACK_SIZE */
+
+/*
+ *  関数のプロトタイプ宣言
+ */
+#ifndef TOPPERS_MACRO_ONLY
+
+extern void	task1(intptr_t exinf);
+extern void	task2(intptr_t exinf);
+extern void	task3(intptr_t exinf);
+extern void	task4(intptr_t exinf);
+extern void	task5(intptr_t exinf);
+extern void	alarm1_handler(intptr_t exinf);
+
+#endif /* TOPPERS_MACRO_ONLY */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/test/test_sem2.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/test/test_sem2.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/test/test_sem2.c	(revision 457)
@@ -0,0 +1,470 @@
+/*
+ *  TOPPERS Software
+ *      Toyohashi Open Platform for Embedded Real-Time Systems
+ * 
+ *  Copyright (C) 2008-2013 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  $Id$
+ */
+
+/* 
+ *		セマフォ機能のテスト(2)
+ *
+ * 【テストの目的】
+ *
+ *  isig_semを，sig_semとの違いを中心にテストする．
+ *  pol_sem，twai_semを，wai_semとの違いを中心にテストする．
+ *
+ * 【テスト項目】
+ *
+ *	(A) isig_semの静的エラーのテスト
+ *		(A-1) タスクコンテキストからの呼出し
+ *		(A-2) CPUロック状態からの呼出し
+ *	(B) isig_semによりセマフォ待ち状態のタスクが待ち解除される
+ *		(B-1) アイドル状態から，待ち解除されたタスクに切り換わる
+ *		(B-2) 実行状態のタスクから，待ち解除されたタスクに切り換わる
+ *		(B-3) ディスパッチ保留状態で，切り換わらない
+ *		(B-4) 待ち解除されたタスクが強制待ち状態で，切り換わらない
+ *		(B-5) 待ち解除されたタスクが優先度が低く，切り換わらない
+ *	(C) pol_semの静的エラーのテスト
+ *		(C-1) 非タスクコンテキストからの呼出し
+ *		(C-2) CPUロック状態からの呼出し
+ *		(C-3) ディスパッチ禁止状態からの呼出し（E_CTXエラーにならない）
+ *		(C-4) 割込み優先度マスク全解除でない状態からの呼出し（E_CTXエラー
+ *		      にならない）
+ *	(D) pol_semでポーリング失敗する
+ *	(E) twai_semの静的エラーのテスト
+ *		(E-1) 非タスクコンテキストからの呼出し
+ *		(E-2) CPUロック状態からの呼出し
+ *		(E-3) ディスパッチ禁止状態からの呼出し
+ *		(E-4) 割込み優先度マスク全解除でない状態からの呼出し
+ *		(E-5) tmoutが不正
+ *	(F) twai_semでtmout=TMO_POLの時にポーリング失敗する
+ *	(G) twai_semでtmout=TMO_FEVRの時にセマフォ待ち状態になる
+ *	(H) twai_semでtmoutにタイムアウトを設定した時に，タイムアウト付きの
+ *		セマフォ待ち状態になる
+ *
+ * 【使用リソース】
+ *
+ *	TASK1: 中優先度タスク，TA_ACT属性
+ *	TASK2: 高優先度タスク
+ *	TASK3: 低優先度タスク
+ *	TASK4: 中優先度タスク
+ *	TASK5: 中優先度タスク
+ *	ALM1:  アラームハンドラ
+ *  SEM1:  TA_NULL属性，初期資源数1，最大資源数1
+ *
+ * 【テストシーケンス】
+ *
+ *	== TASK1（優先度：中）==
+ *  1:	isig_sem(SEM1) -> E_CTX				... (A-1)
+ *	2:	loc_cpu()
+ *		pol_sem(SEM1) -> E_CTX				... (C-2)
+ *		twai_sem(SEM1, TMO_POL) -> E_CTX	... (E-2)
+ *		unl_cpu()
+ *	3:	dis_dsp()
+ *		pol_sem(SEM1)						... (C-3)
+ *		twai_sem(SEM1, TMO_POL) -> E_CTX	... (E-3)
+ *		ena_dsp()
+ *	4:	chg_ipm(TMAX_INTPRI)
+ *		pol_sem(SEM1) -> E_TMOUT			... (C-4)(D)
+ *		twai_sem(SEM1, TMO_POL) -> E_CTX	... (E-4)
+ *		chg_ipm(TIPM_ENAALL)
+ *	5:	twai_sem(SEM1, -2) -> E_PAR			... (E-5)
+ *		twai_sem(SEM1, TMO_POL) -> E_TMOUT	... (F)
+ *	6:	sta_alm(ALM1, 10)
+ *	7:	twai_sem(SEM1, TMO_FEVR)			... (G)
+ *	== ALM1-1 ==
+ *	8:	pol_sem(SEM1) -> E_CTX				... (C-1)
+ *		twai_sem(SEM1, TMO_POL) -> E_CTX	... (E-1)
+ *	9:	iloc_cpu()
+ *		isig_sem(SEM1) -> E_CTX				... (A-2)
+ *		iunl_cpu()
+ *	10:	isig_sem(SEM1)						... (B-1)
+ *		RETURN
+ *	== TASK1（続き）==
+ *	11:	act_tsk(TASK3)
+ *	12:	wai_sem(SEM1)
+ *	== TASK3（優先度：低）==
+ *	13:	sta_alm(ALM1, 10)
+ *		call(wait_var())
+ *	== ALM1-2 ==
+ *	14:	isig_sem(SEM1)						... (B-2)
+ *		call(signal_var())
+ *		RETURN
+ *	== TASK1（続き）==
+ *	15:	wai_sem(SEM1)
+ *	== TASK3（続き）==
+ *	16:	sta_alm(ALM1, 10)
+ *		dis_dsp()
+ *		call(wait_var())
+ *	== ALM1-3 ==
+ *	17:	isig_sem(SEM1)						... (B-3)
+ *		call(signal_var())
+ *		RETURN
+ *	== TASK3（続き）==
+ *	18:	ena_dsp()
+ *	== TASK1（続き）==
+ *	19:	wai_sem(SEM1)
+ *	== TASK3（続き）==
+ *	20:	sta_alm(ALM1, 10)
+ *		sus_tsk(TASK1)
+ *		call(wait_var())
+ *	== ALM1-4 ==
+ *	21:	isig_sem(SEM1)						... (B-4)
+ *		call(signal_var())
+ *		RETURN
+ *	== TASK3（続き）==
+ *	22:	rsm_tsk(TASK1)
+ *	== TASK1（続き）==
+ *	23:	act_tsk(TASK2)
+ *	== TASK2（優先度：高）==
+ *	24:	tslp_tsk(10) -> E_TMOUT
+ *	== TASK1（続き）==
+ *	25:	wai_sem(SEM1)
+ *	== TASK3（続き）==
+ *	26:	ext_tsk() -> noreturn
+ *	== TASK2（続き）==
+ *	27:	sta_alm(ALM1, 10)
+ *		call(wait_var())
+ *	== ALM1-5 ==
+ *	28:	isig_sem(SEM1)						... (B-5)
+ *		call(signal_var())
+ *		RETURN
+ *	== TASK2（続き）==
+ *	29:	ext_tsk() -> noreturn
+ *	== TASK1（続き）==
+ *	30:	sta_alm(ALM1, 10)
+ *	31:	twai_sem(SEM1, 100) -> E_RLWAI
+ *	== ALM1-6 ==
+ *	32:	irel_wai(TASK1)
+ *		RETURN
+ *	== TASK1（続き）==
+ *	33:	sta_alm(ALM1, 100)
+ *	34:	twai_sem(SEM1, 10) -> E_TMOUT		... (H)
+ *	35:	stp_alm(ALM1)
+ *	36:	END
+ */
+
+#include <kernel.h>
+#include <test_lib.h>
+#include <t_syslog.h>
+#include "kernel_cfg.h"
+#include "test_sem2.h"
+
+static volatile bool_t	flagvar;
+
+static void
+wait_var(void)
+{
+	flagvar = false;
+	while (!flagvar);
+}
+
+static void
+signal_var(void)
+{
+	flagvar = true;
+}
+
+/* DO NOT DELETE THIS LINE -- gentest depends on it. */
+
+static uint_t	alarm1_count = 0;
+
+void
+alarm1_handler(intptr_t exinf)
+{
+	ER_UINT	ercd;
+
+	switch (++alarm1_count) {
+	case 1:
+		check_point(8);
+		ercd = pol_sem(SEM1);
+		check_ercd(ercd, E_CTX);
+
+		ercd = twai_sem(SEM1, TMO_POL);
+		check_ercd(ercd, E_CTX);
+
+		check_point(9);
+		ercd = iloc_cpu();
+		check_ercd(ercd, E_OK);
+
+		ercd = isig_sem(SEM1);
+		check_ercd(ercd, E_CTX);
+
+		ercd = iunl_cpu();
+		check_ercd(ercd, E_OK);
+
+		check_point(10);
+		ercd = isig_sem(SEM1);
+		check_ercd(ercd, E_OK);
+
+		return;
+
+		check_point(0);
+
+	case 2:
+		check_point(14);
+		ercd = isig_sem(SEM1);
+		check_ercd(ercd, E_OK);
+
+		signal_var();
+
+		return;
+
+		check_point(0);
+
+	case 3:
+		check_point(17);
+		ercd = isig_sem(SEM1);
+		check_ercd(ercd, E_OK);
+
+		signal_var();
+
+		return;
+
+		check_point(0);
+
+	case 4:
+		check_point(21);
+		ercd = isig_sem(SEM1);
+		check_ercd(ercd, E_OK);
+
+		signal_var();
+
+		return;
+
+		check_point(0);
+
+	case 5:
+		check_point(28);
+		ercd = isig_sem(SEM1);
+		check_ercd(ercd, E_OK);
+
+		signal_var();
+
+		return;
+
+		check_point(0);
+
+	case 6:
+		check_point(32);
+		ercd = irel_wai(TASK1);
+		check_ercd(ercd, E_OK);
+
+		return;
+
+		check_point(0);
+
+	default:
+		check_point(0);
+	}
+	check_point(0);
+}
+
+void
+task1(intptr_t exinf)
+{
+	ER_UINT	ercd;
+
+	test_start(__FILE__);
+
+	check_point(1);
+	ercd = isig_sem(SEM1);
+	check_ercd(ercd, E_CTX);
+
+	check_point(2);
+	ercd = loc_cpu();
+	check_ercd(ercd, E_OK);
+
+	ercd = pol_sem(SEM1);
+	check_ercd(ercd, E_CTX);
+
+	ercd = twai_sem(SEM1, TMO_POL);
+	check_ercd(ercd, E_CTX);
+
+	ercd = unl_cpu();
+	check_ercd(ercd, E_OK);
+
+	check_point(3);
+	ercd = dis_dsp();
+	check_ercd(ercd, E_OK);
+
+	ercd = pol_sem(SEM1);
+	check_ercd(ercd, E_OK);
+
+	ercd = twai_sem(SEM1, TMO_POL);
+	check_ercd(ercd, E_CTX);
+
+	ercd = ena_dsp();
+	check_ercd(ercd, E_OK);
+
+	check_point(4);
+	ercd = chg_ipm(TMAX_INTPRI);
+	check_ercd(ercd, E_OK);
+
+	ercd = pol_sem(SEM1);
+	check_ercd(ercd, E_TMOUT);
+
+	ercd = twai_sem(SEM1, TMO_POL);
+	check_ercd(ercd, E_CTX);
+
+	ercd = chg_ipm(TIPM_ENAALL);
+	check_ercd(ercd, E_OK);
+
+	check_point(5);
+	ercd = twai_sem(SEM1, -2);
+	check_ercd(ercd, E_PAR);
+
+	ercd = twai_sem(SEM1, TMO_POL);
+	check_ercd(ercd, E_TMOUT);
+
+	check_point(6);
+	ercd = sta_alm(ALM1, 10);
+	check_ercd(ercd, E_OK);
+
+	check_point(7);
+	ercd = twai_sem(SEM1, TMO_FEVR);
+	check_ercd(ercd, E_OK);
+
+	check_point(11);
+	ercd = act_tsk(TASK3);
+	check_ercd(ercd, E_OK);
+
+	check_point(12);
+	ercd = wai_sem(SEM1);
+	check_ercd(ercd, E_OK);
+
+	check_point(15);
+	ercd = wai_sem(SEM1);
+	check_ercd(ercd, E_OK);
+
+	check_point(19);
+	ercd = wai_sem(SEM1);
+	check_ercd(ercd, E_OK);
+
+	check_point(23);
+	ercd = act_tsk(TASK2);
+	check_ercd(ercd, E_OK);
+
+	check_point(25);
+	ercd = wai_sem(SEM1);
+	check_ercd(ercd, E_OK);
+
+	check_point(30);
+	ercd = sta_alm(ALM1, 10);
+	check_ercd(ercd, E_OK);
+
+	check_point(31);
+	ercd = twai_sem(SEM1, 100);
+	check_ercd(ercd, E_RLWAI);
+
+	check_point(33);
+	ercd = sta_alm(ALM1, 100);
+	check_ercd(ercd, E_OK);
+
+	check_point(34);
+	ercd = twai_sem(SEM1, 10);
+	check_ercd(ercd, E_TMOUT);
+
+	check_point(35);
+	ercd = stp_alm(ALM1);
+	check_ercd(ercd, E_OK);
+
+	check_finish(36);
+	check_point(0);
+}
+
+void
+task2(intptr_t exinf)
+{
+	ER_UINT	ercd;
+
+	check_point(24);
+	ercd = tslp_tsk(10);
+	check_ercd(ercd, E_TMOUT);
+
+	check_point(27);
+	ercd = sta_alm(ALM1, 10);
+	check_ercd(ercd, E_OK);
+
+	wait_var();
+
+	check_point(29);
+	ercd = ext_tsk();
+
+	check_point(0);
+}
+
+void
+task3(intptr_t exinf)
+{
+	ER_UINT	ercd;
+
+	check_point(13);
+	ercd = sta_alm(ALM1, 10);
+	check_ercd(ercd, E_OK);
+
+	wait_var();
+
+	check_point(16);
+	ercd = sta_alm(ALM1, 10);
+	check_ercd(ercd, E_OK);
+
+	ercd = dis_dsp();
+	check_ercd(ercd, E_OK);
+
+	wait_var();
+
+	check_point(18);
+	ercd = ena_dsp();
+	check_ercd(ercd, E_OK);
+
+	check_point(20);
+	ercd = sta_alm(ALM1, 10);
+	check_ercd(ercd, E_OK);
+
+	ercd = sus_tsk(TASK1);
+	check_ercd(ercd, E_OK);
+
+	wait_var();
+
+	check_point(22);
+	ercd = rsm_tsk(TASK1);
+	check_ercd(ercd, E_OK);
+
+	check_point(26);
+	ercd = ext_tsk();
+
+	check_point(0);
+}
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/test/test_sem2.cfg
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/test/test_sem2.cfg	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/test/test_sem2.cfg	(revision 457)
@@ -0,0 +1,20 @@
+/*
+ *  @(#) $Id$
+ */
+
+/*
+ *  セマフォ機能のテスト(2)のシステムコンフィギュレーションファイル
+ */
+INCLUDE("target_timer.cfg");
+INCLUDE("syssvc/syslog.cfg");
+INCLUDE("syssvc/banner.cfg");
+INCLUDE("syssvc/serial.cfg");
+
+#include "test_sem2.h"
+
+CRE_TSK(TASK1, { TA_ACT, 1, task1, MID_PRIORITY, STACK_SIZE, NULL });
+CRE_TSK(TASK2, { TA_NULL, 2, task2, HIGH_PRIORITY, STACK_SIZE, NULL });
+CRE_TSK(TASK3, { TA_NULL, 3, task3, LOW_PRIORITY, STACK_SIZE, NULL });
+CRE_ALM(ALM1, { TA_NULL, 1, alarm1_handler });
+CRE_SEM(SEM1, { TA_NULL, 1, 1 });
+CRE_SEM(SEM2, { TA_TPRI, 0, 1 });
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/test/test_sem2.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/test/test_sem2.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/test/test_sem2.h	(revision 457)
@@ -0,0 +1,73 @@
+/*
+ *  TOPPERS Software
+ *      Toyohashi Open Platform for Embedded Real-Time Systems
+ * 
+ *  Copyright (C) 2008 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/* 
+ *		セマフォ機能のテスト(2)
+ */
+
+/*
+ *  ターゲット依存の定義
+ */
+#include "target_test.h"
+
+/*
+ *  優先度の定義
+ */
+#define HIGH_PRIORITY	9		/* 高優先度 */
+#define MID_PRIORITY	10		/* 中優先度 */
+#define LOW_PRIORITY	11		/* 低優先度 */
+
+/*
+ *  ターゲットに依存する可能性のある定数の定義
+ */
+#ifndef STACK_SIZE
+#define	STACK_SIZE		4096		/* タスクのスタックサイズ */
+#endif /* STACK_SIZE */
+
+/*
+ *  関数のプロトタイプ宣言
+ */
+#ifndef TOPPERS_MACRO_ONLY
+
+extern void	task1(intptr_t exinf);
+extern void	task2(intptr_t exinf);
+extern void	task3(intptr_t exinf);
+extern void	alarm1_handler(intptr_t exinf);
+
+#endif /* TOPPERS_MACRO_ONLY */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/test/test_sysstat1.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/test/test_sysstat1.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/test/test_sysstat1.c	(revision 457)
@@ -0,0 +1,241 @@
+/*
+ *  TOPPERS Software
+ *      Toyohashi Open Platform for Embedded Real-Time Systems
+ * 
+ *  Copyright (C) 2006-2013 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  $Id$
+ */
+
+/* 
+ *		システム状態に関するテスト(1)
+ *
+ *  テストシーケンス：
+ *
+ *	== TASK1（優先度：10）==
+ *	1:	初期状態のチェック
+ *	2:	loc_cpu() ... システム状態をランダムに変化させる
+ *		chg_ipm(TMAX_INTPRI) -> E_CTX
+ *	3:	unl_cpu()
+ *	4:	chg_ipm(TMAX_INTPRI)
+ *	5:	dis_dsp()
+ *	6:	ena_tex()
+ *	7:	chg_ipm(TIPM_ENAALL)
+ *	8:	ena_dsp()
+ *	9:	dis_tex()
+ *	10:	dis_dsp() ... タスク例外処理ルーチンを呼び出す準備
+ *		ena_tex()
+ *	11:	ras_tex(TSK_SELF, 0x0001)
+ *	== TASK1タスク例外処理ルーチン（1回目）==
+ *	12:	初期状態のチェック
+ *	13:	ena_dsp() ... 3つの状態を変化させ，リターンで元にもどるか調べる
+ *		chg_ipm(TMIN_INTPRI)
+ *		ena_tex()
+ *		リターン
+ *	== TASK1（続き）==
+ *	14:	戻ってきた状態のチェック
+ *	15:	loc_cpu() ... CPUロック状態のままタスクを終了させる
+ *	16:	リターン（＝タスク終了）
+ *	== TASK2（優先度：10）	==
+ *	17:	初期状態のチェック
+ *	18:	終了
+ */
+
+#include <kernel.h>
+#include <test_lib.h>
+#include <t_syslog.h>
+#include "kernel_cfg.h"
+#include "test_sysstat1.h"
+
+void
+tex_task1(TEXPTN texptn, intptr_t exinf)
+{
+	ER		ercd;
+
+	switch (texptn) {
+	case 0x0001:
+		check_point(12);
+		check_state(false, false, TIPM_ENAALL, true, true, true);
+
+		/*
+		 *  ディスパッチ許可，割込み優先度マスク変更，タスク例外処理許可
+		 */
+		check_point(13);
+		ercd = ena_dsp();
+		check_ercd(ercd, E_OK);
+		ercd = chg_ipm(TMIN_INTPRI);
+		check_ercd(ercd, E_OK);
+		ercd = ena_tex();
+		check_ercd(ercd, E_OK);
+		check_state(false, false, TMIN_INTPRI, false, true, false);
+		break;
+
+	default:
+		check_point(0);
+		break;
+	}
+}
+
+void
+task1(intptr_t exinf)
+{
+	ER		ercd;
+
+	test_start(__FILE__);
+
+	/*
+	 *  初期状態のチェック
+	 */
+	check_point(1);
+	check_state(false, false, TIPM_ENAALL, false, false, true);
+
+	/*
+	 *  CPUロック状態のチェック
+	 */
+	check_point(2);
+	ercd = loc_cpu();
+	check_ercd(ercd, E_OK);
+	check_state(false, true, TIPM_ENAALL, false, true, true);
+
+	/*
+	 *  割込み優先度マスク変更のチェック
+	 */
+	ercd = chg_ipm(TMAX_INTPRI);
+	check_ercd(ercd, E_CTX);
+	check_state(false, true, TIPM_ENAALL, false, true, true);
+
+	/*
+	 *  CPUロック解除のチェック
+	 */
+	check_point(3);
+	ercd = unl_cpu();
+	check_ercd(ercd, E_OK);
+	check_state(false, false, TIPM_ENAALL, false, false, true);
+
+	/*
+	 *  割込み優先度マスク変更のチェック
+	 */
+	check_point(4);
+	ercd = chg_ipm(TMAX_INTPRI);
+	check_ercd(ercd, E_OK);
+	check_state(false, false, TMAX_INTPRI, false, true, true);
+
+	/*
+	 *  ディスパッチ禁止のチェック
+	 */
+	check_point(5);
+	ercd = dis_dsp();
+	check_ercd(ercd, E_OK);
+	check_state(false, false, TMAX_INTPRI, true, true, true);
+
+	/*
+	 *  タスク例外処理許可のチェック
+	 */
+	check_point(6);
+	ercd = ena_tex();
+	check_ercd(ercd, E_OK);
+	check_state(false, false, TMAX_INTPRI, true, true, false);
+
+	/*
+	 *  割込み優先度マスク全解除のチェック
+	 */
+	check_point(7);
+	ercd = chg_ipm(TIPM_ENAALL);
+	check_ercd(ercd, E_OK);
+	check_state(false, false, TIPM_ENAALL, true, true, false);
+
+	/*
+	 *  ディスパッチ許可のチェック
+	 */
+	check_point(8);
+	ercd = ena_dsp();
+	check_ercd(ercd, E_OK);
+	check_state(false, false, TIPM_ENAALL, false, false, false);
+
+	/*
+	 *  タスク例外処理禁止のチェック
+	 */
+	check_point(9);
+	ercd = dis_tex();
+	check_ercd(ercd, E_OK);
+	check_state(false, false, TIPM_ENAALL, false, false, true);
+
+	/*
+	 *  ディスパッチ禁止，タスク例外処理許可
+	 */
+	check_point(10);
+	ercd = dis_dsp();
+	check_ercd(ercd, E_OK);
+	ercd = ena_tex();
+	check_ercd(ercd, E_OK);
+	check_state(false, false, TIPM_ENAALL, true, true, false);
+
+	/*
+	 *  タスク例外処理を要求
+	 */
+	check_point(11);
+	ercd = ras_tex(TSK_SELF, 0x0001);
+	/* ここでタスク例外処理ルーチンが動作する */
+	check_ercd(ercd, E_OK);
+
+	/*
+	 *  タスク例外処理からのリターンにより元の状態に戻っていることを
+	 *  チェック
+	 */
+	check_point(14);
+	check_state(false, false, TIPM_ENAALL, true, true, false);
+
+	/*
+	 *  CPUロック状態に
+	 */
+	check_point(15);
+	ercd = loc_cpu();
+	check_ercd(ercd, E_OK);
+
+	/*
+	 *  そのままタスク終了
+	 */
+	check_point(16);
+}
+
+void
+task2(intptr_t exinf)
+{
+	/*
+	 *  初期状態のチェック
+	 */
+	check_point(17);
+	check_state(false, false, TIPM_ENAALL, false, false, true);
+
+	check_finish(18);
+}
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/test/test_sysstat1.cfg
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/test/test_sysstat1.cfg	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/test/test_sysstat1.cfg	(revision 457)
@@ -0,0 +1,18 @@
+/*
+ *  @(#) $Id$
+ */
+
+/*
+ *  システム状態に関するテスト(1)のシステムコンフィギュレーションファイル
+ */
+INCLUDE("target_timer.cfg");
+INCLUDE("syssvc/syslog.cfg");
+INCLUDE("syssvc/banner.cfg");
+INCLUDE("syssvc/serial.cfg");
+
+#include "test_sysstat1.h"
+
+CRE_TSK(TASK1, { TA_ACT, 1, task1, TASK1_PRIORITY, STACK_SIZE, NULL });
+DEF_TEX(TASK1, { TA_NULL, tex_task1 });
+
+CRE_TSK(TASK2, { TA_ACT, 2, task2, TASK2_PRIORITY, STACK_SIZE, NULL });
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/test/test_sysstat1.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/test/test_sysstat1.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/test/test_sysstat1.h	(revision 457)
@@ -0,0 +1,72 @@
+/*
+ *  TOPPERS Software
+ *      Toyohashi Open Platform for Embedded Real-Time Systems
+ * 
+ *  Copyright (C) 2006,2007 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/* 
+ *		システム状態に関するテスト(1)
+ */
+
+/*
+ *  ターゲット依存の定義
+ */
+#include "target_test.h"
+
+/*
+ *  各タスクの優先度の定義
+ */
+#define TASK1_PRIORITY	10		/* タスク1の優先度 */
+#define TASK2_PRIORITY	10		/* タスク2の優先度 */
+
+/*
+ *  ターゲットに依存する可能性のある定数の定義
+ */
+#ifndef STACK_SIZE
+#define	STACK_SIZE		4096		/* タスクのスタックサイズ */
+#endif /* STACK_SIZE */
+
+/*
+ *  関数のプロトタイプ宣言
+ */
+#ifndef TOPPERS_MACRO_ONLY
+
+extern void	tex_task1(TEXPTN texptn, intptr_t exinf);
+extern void	task1(intptr_t exinf);
+
+extern void	task2(intptr_t exinf);
+
+#endif /* TOPPERS_MACRO_ONLY */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/test/test_task1.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/test/test_task1.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/test/test_task1.c	(revision 457)
@@ -0,0 +1,364 @@
+/*
+ *  TOPPERS Software
+ *      Toyohashi Open Platform for Embedded Real-Time Systems
+ * 
+ *  Copyright (C) 2007-2013 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  $Id$
+ */
+
+/* 
+ *		タスク管理モジュールのテスト(1)
+ *
+ * 【テストの目的】
+ *
+ *  make_runnableとmake_non_runnableを網羅的にテストする．
+ *
+ * 【テスト項目】
+ *
+ *	(A) 実行状態のタスクよりも高い優先度のタスクを実行できる状態にする
+ *		(A-1) ディスパッチ保留状態ではない場合
+ *		(A-2) ディスパッチ保留状態の場合
+ *	(B) 実行状態のタスクと同じ優先度のタスクを実行できる状態にする
+ *		！同じ優先度のタスクの中の末尾に入ることを確認する
+ *	(C) 実行状態のタスクよりも低い優先度のタスクを実行できる状態にする
+ *		！同じ優先度のタスクの中の末尾に入ることを確認する
+ *	(D) 実行できる状態のタスクがない状態で，タスクを実行できる状態にする
+ *		！この場合は，ディスパッチ保留状態ではない
+ *	(E) ディスパッチ保留状態で，実行状態になるべきだが実行可能状態タス
+ *		クよりも高い優先度のタスクを，実行できる状態にする
+ *	(F) ディスパッチ保留状態で，実行状態になるべきだが実行可能状態タス
+ *		クと同じ優先度のタスクを，実行できる状態にする
+ *	(G) ディスパッチ保留状態で，実行状態になるべきだが実行可能状態タス
+ *		クよりも低い優先度のタスクを，実行できる状態にする
+ *	(H) 実行状態のタスクを，実行できる状態でなくす
+ *		(H-1) 実行できる状態のタスクがなくなる場合
+ *		(H-2) 同一優先度のタスクがなくなる場合
+ *		(H-3) 同一優先度のタスクがなくならない場合
+ *	(I) 実行可能状態のタスクを，実行できる状態でなくす
+ *		(I-1) 同一優先度のタスクがなくなる場合
+ *		(I-2) 同一優先度のタスクがなくならない場合
+ *	(J) ディスパッチ保留状態で，実行状態になるべきだが実行可能状態となっ
+ *		ているタスクを，実行できる状態でなくす
+ *		(J-1) 同一優先度のタスクがなくなる場合
+ *		(J-2) 同一優先度のタスクがなくならない場合
+ *	(K) ディスパッチ保留状態で，実行可能状態になるべきだが実行状態のタ
+ *		スクを，実行できる状態でなくす
+ *		！ディスパッチ保留では，実行状態のタスクが実行できる状態でなく
+ *		なるような遷移を起こすことができないため，この状況は起こらない．
+ *
+ * 【使用リソース】
+ *
+ *	TASK1: 中優先度タスク，メインタスク，最初から起動
+ *	TASK2: 高優先度タスク
+ *	TASK3: 中優先度タスク
+ *	TASK4: 中優先度タスク
+ *	TASK5: 低優先度タスク
+ *	TASK6: 低優先度タスク
+ *	ALM1:  アラームハンドラ
+ *
+ * 【テストシーケンス】
+ *
+ *	== TASK1（優先度：中）==
+ *	1:	act_tsk(TASK2)					... (A-1)
+ *	== TASK2（優先度：高）==
+ *	2:	slp_tsk()						... (H-2)
+ *	== TASK1（続き）==
+ *	3:	act_tsk(TASK3)					... (B)
+ *	4:	act_tsk(TASK4)					... (B)
+ *	5:	slp_tsk()						... (H-3)
+ *	== TASK3（優先度：中）==
+ *	6:	slp_tsk()						... (H-3)
+ *	== TASK4（優先度：中）==
+ *	7:	wup_tsk(TASK1)
+ *	8:	slp_tsk()						... (H-3)
+ *	== TASK1（続き）==
+ *	9:	act_tsk(TASK5)					... (C)
+ *	10:	act_tsk(TASK6)					... (C)
+ *	11:	sus_tsk(TASK6)					... (I-2)
+ *	12:	sus_tsk(TASK5)					... (I-1)
+ *	13:	rsm_tsk(TASK5)					... (C)
+ *	14:	rsm_tsk(TASK6)					... (C)
+ *	15:	slp_tsk()						... (H-2)
+ *	== TASK5（優先度：低）==
+ *	16:	slp_tsk()						... (H-3)
+ *	== TASK6（優先度：低）==
+ *	17:	dis_dsp()
+ *	18:	wup_tsk(TASK1)					... (A-2)
+ *	19:	wup_tsk(TASK2)					... (E)
+ *	20:	sus_tsk(TASK2)					... (J-1)
+ *	21:	wup_tsk(TASK3)					... (F)
+ *	22:	wup_tsk(TASK4)					... (F)
+ *	23:	sus_tsk(TASK1)					... (J-2)
+ *	24:	ena_dsp()
+ *	== TASK3（続き）==
+ *	25:	slp_tsk()						... (H-3)
+ *	== TASK4（続き）==
+ *	26:	slp_tsk()						... (H-2)
+ *	== TASK6（続き）==
+ *	27:	dis_dsp()
+ *	28:	rsm_tsk(TASK1)					... (A-2)
+ *	29:	wup_tsk(TASK5)					... (G)
+ *	30:	ena_dsp()
+ *	== TASK1（続き）==
+ *	31:	slp_tsk()						... (H-2)
+ *	== TASK6（続き）==
+ *	32:	slp_tsk()						... (H-3)
+ *	== TASK5（続き）==
+ *	33:	sta_alm(ALM1, 10)
+ *	34:	slp_tsk()						... (H-1)
+ *	== ALM1 ==
+ *	35:	iget_tid(&tskid)
+ *		assert(tskid == TSK_NONE)
+ *	36:	iwup_tsk(TASK1)					... (D)
+ *	37:	RETURN
+ *	== TASK1（続き）==
+ *	38: END
+ */
+
+#include <kernel.h>
+#include <test_lib.h>
+#include <t_syslog.h>
+#include "kernel_cfg.h"
+#include "test_task1.h"
+
+/* DO NOT DELETE THIS LINE -- gentest depends on it. */
+
+void
+alarm1_handler(intptr_t exinf)
+{
+	ID		tskid;
+	ER_UINT	ercd;
+
+	check_point(35);
+	ercd = iget_tid(&tskid);
+	check_ercd(ercd, E_OK);
+
+	check_assert(tskid == TSK_NONE);
+
+	check_point(36);
+	ercd = iwup_tsk(TASK1);
+	check_ercd(ercd, E_OK);
+
+	check_point(37);
+	return;
+
+	check_point(0);
+}
+
+void
+task1(intptr_t exinf)
+{
+	ER_UINT	ercd;
+
+	test_start(__FILE__);
+
+	check_point(1);
+	ercd = act_tsk(TASK2);
+	check_ercd(ercd, E_OK);
+
+	check_point(3);
+	ercd = act_tsk(TASK3);
+	check_ercd(ercd, E_OK);
+
+	check_point(4);
+	ercd = act_tsk(TASK4);
+	check_ercd(ercd, E_OK);
+
+	check_point(5);
+	ercd = slp_tsk();
+	check_ercd(ercd, E_OK);
+
+	check_point(9);
+	ercd = act_tsk(TASK5);
+	check_ercd(ercd, E_OK);
+
+	check_point(10);
+	ercd = act_tsk(TASK6);
+	check_ercd(ercd, E_OK);
+
+	check_point(11);
+	ercd = sus_tsk(TASK6);
+	check_ercd(ercd, E_OK);
+
+	check_point(12);
+	ercd = sus_tsk(TASK5);
+	check_ercd(ercd, E_OK);
+
+	check_point(13);
+	ercd = rsm_tsk(TASK5);
+	check_ercd(ercd, E_OK);
+
+	check_point(14);
+	ercd = rsm_tsk(TASK6);
+	check_ercd(ercd, E_OK);
+
+	check_point(15);
+	ercd = slp_tsk();
+	check_ercd(ercd, E_OK);
+
+	check_point(31);
+	ercd = slp_tsk();
+	check_ercd(ercd, E_OK);
+
+	check_finish(38);
+	check_point(0);
+}
+
+void
+task2(intptr_t exinf)
+{
+	ER_UINT	ercd;
+
+	check_point(2);
+	ercd = slp_tsk();
+	check_ercd(ercd, E_OK);
+
+	check_point(0);
+}
+
+void
+task3(intptr_t exinf)
+{
+	ER_UINT	ercd;
+
+	check_point(6);
+	ercd = slp_tsk();
+	check_ercd(ercd, E_OK);
+
+	check_point(25);
+	ercd = slp_tsk();
+	check_ercd(ercd, E_OK);
+
+	check_point(0);
+}
+
+void
+task4(intptr_t exinf)
+{
+	ER_UINT	ercd;
+
+	check_point(7);
+	ercd = wup_tsk(TASK1);
+	check_ercd(ercd, E_OK);
+
+	check_point(8);
+	ercd = slp_tsk();
+	check_ercd(ercd, E_OK);
+
+	check_point(26);
+	ercd = slp_tsk();
+	check_ercd(ercd, E_OK);
+
+	check_point(0);
+}
+
+void
+task5(intptr_t exinf)
+{
+	ER_UINT	ercd;
+
+	check_point(16);
+	ercd = slp_tsk();
+	check_ercd(ercd, E_OK);
+
+	check_point(33);
+	ercd = sta_alm(ALM1, 10);
+	check_ercd(ercd, E_OK);
+
+	check_point(34);
+	ercd = slp_tsk();
+	check_ercd(ercd, E_OK);
+
+	check_point(0);
+}
+
+void
+task6(intptr_t exinf)
+{
+	ER_UINT	ercd;
+
+	check_point(17);
+	ercd = dis_dsp();
+	check_ercd(ercd, E_OK);
+
+	check_point(18);
+	ercd = wup_tsk(TASK1);
+	check_ercd(ercd, E_OK);
+
+	check_point(19);
+	ercd = wup_tsk(TASK2);
+	check_ercd(ercd, E_OK);
+
+	check_point(20);
+	ercd = sus_tsk(TASK2);
+	check_ercd(ercd, E_OK);
+
+	check_point(21);
+	ercd = wup_tsk(TASK3);
+	check_ercd(ercd, E_OK);
+
+	check_point(22);
+	ercd = wup_tsk(TASK4);
+	check_ercd(ercd, E_OK);
+
+	check_point(23);
+	ercd = sus_tsk(TASK1);
+	check_ercd(ercd, E_OK);
+
+	check_point(24);
+	ercd = ena_dsp();
+	check_ercd(ercd, E_OK);
+
+	check_point(27);
+	ercd = dis_dsp();
+	check_ercd(ercd, E_OK);
+
+	check_point(28);
+	ercd = rsm_tsk(TASK1);
+	check_ercd(ercd, E_OK);
+
+	check_point(29);
+	ercd = wup_tsk(TASK5);
+	check_ercd(ercd, E_OK);
+
+	check_point(30);
+	ercd = ena_dsp();
+	check_ercd(ercd, E_OK);
+
+	check_point(32);
+	ercd = slp_tsk();
+	check_ercd(ercd, E_OK);
+
+	check_point(0);
+}
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/test/test_task1.cfg
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/test/test_task1.cfg	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/test/test_task1.cfg	(revision 457)
@@ -0,0 +1,21 @@
+/*
+ *  @(#) $Id$
+ */
+
+/*
+ *  タスク管理モジュールのテスト(1)のシステムコンフィギュレーションファイル
+ */
+INCLUDE("target_timer.cfg");
+INCLUDE("syssvc/syslog.cfg");
+INCLUDE("syssvc/banner.cfg");
+INCLUDE("syssvc/serial.cfg");
+
+#include "test_task1.h"
+
+CRE_TSK(TASK1, { TA_ACT, 1, task1, MID_PRIORITY, STACK_SIZE, NULL });
+CRE_TSK(TASK2, { TA_NULL, 2, task2, HIGH_PRIORITY, STACK_SIZE, NULL });
+CRE_TSK(TASK3, { TA_NULL, 3, task3, MID_PRIORITY, STACK_SIZE, NULL });
+CRE_TSK(TASK4, { TA_NULL, 4, task4, MID_PRIORITY, STACK_SIZE, NULL });
+CRE_TSK(TASK5, { TA_NULL, 5, task5, LOW_PRIORITY, STACK_SIZE, NULL });
+CRE_TSK(TASK6, { TA_NULL, 6, task6, LOW_PRIORITY, STACK_SIZE, NULL });
+CRE_ALM(ALM1, { TA_NULL, 1, alarm1_handler });
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/test/test_task1.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/test/test_task1.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/test/test_task1.h	(revision 457)
@@ -0,0 +1,76 @@
+/*
+ *  TOPPERS Software
+ *      Toyohashi Open Platform for Embedded Real-Time Systems
+ * 
+ *  Copyright (C) 2007 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/* 
+ *		タスク管理モジュールのテスト(1)
+ */
+
+/*
+ *  ターゲット依存の定義
+ */
+#include "target_test.h"
+
+/*
+ *  優先度の定義
+ */
+#define HIGH_PRIORITY	4		/* 高優先度 */
+#define MID_PRIORITY	9		/* 中優先度 */
+#define LOW_PRIORITY	14		/* 低優先度 */
+
+/*
+ *  ターゲットに依存する可能性のある定数の定義
+ */
+#ifndef STACK_SIZE
+#define	STACK_SIZE		4096		/* タスクのスタックサイズ */
+#endif /* STACK_SIZE */
+
+/*
+ *  関数のプロトタイプ宣言
+ */
+#ifndef TOPPERS_MACRO_ONLY
+
+extern void	task1(intptr_t exinf);
+extern void	task2(intptr_t exinf);
+extern void	task3(intptr_t exinf);
+extern void	task4(intptr_t exinf);
+extern void	task5(intptr_t exinf);
+extern void	task6(intptr_t exinf);
+extern void	alarm1_handler(intptr_t exinf);
+
+#endif /* TOPPERS_MACRO_ONLY */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/test/test_tex1.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/test/test_tex1.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/test/test_tex1.c	(revision 457)
@@ -0,0 +1,567 @@
+/*
+ *  TOPPERS Software
+ *      Toyohashi Open Platform for Embedded Real-Time Systems
+ * 
+ *  Copyright (C) 2006-2013 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  $Id$
+ */
+
+/* 
+ *		タスク例外処理に関するテスト(1)
+ *
+ * 【テストの目的】
+ *
+ *  タスクからタスク例外処理ルーチンを起動する処理を網羅的にテストする．
+ *
+ * 【テスト項目】
+ *
+ *	(A) ras_texのエラー検出
+ *		(A-1) 対象タスクが休止状態［NGKI1413］
+ *		(A-2) 対象タスクのタスク例外処理ルーチンが定義されていない［NGKI1414］
+ *	(B) dis_texのエラー検出
+ *		(B-1) 自タスクのタスク例外処理ルーチンが定義されていない［NGKI1421］
+ *	(C) ena_texのエラー検出
+ *		(C-1) 自タスクのタスク例外処理ルーチンが定義されていない［NGKI1426］
+ *	(D) ref_texのエラー検出
+ *		(D-1) 対象タスクが休止状態［NGKI1439］
+ *		(D-2) 対象タスクのタスク例外処理ルーチンが定義されていない［NGKI1440］
+ *	(E) ras_texの正常処理［NGKI1415］
+ *		(E-1) 対象タスクが自タスク，タスク例外処理許可，かつ割込み優先
+ *			  度マスク全解除状態で，すぐに実行開始
+ *		(E-2) 対象タスクが自タスクでない
+ *		(E-3) 対象タスクが自タスクだが，タスク例外処理禁止
+ *		(E-4) 対象タスクが自タスクでタスク例外処理許可だが，割込み優先
+ *			  度マスクが全解除でない
+ *	(F) ena_texの正常処理［NGKI1427］
+ *		(F-1) タスク例外処理要求があり，かつ割込み優先度マスク全解除状
+ *			  態で，すぐに実行開始
+ *		(F-2) タスク例外処理要求がない
+ *		(F-3) タスク例外処理要求があるが，割込み優先度マスクが全解除で
+ *			  ない
+ *	(G) chg_ipmの正常処理
+ *		(G-1) タスク例外処理要求があり，かつタスク例外処理許可で，すぐ
+ *			  に実行開始
+ *		(G-2) タスク例外処理要求がない
+ *		(G-3) タスク例外処理要求があるが，タスク例外処理禁止
+ *		(G-4) タスク例外処理要求があるが，割込み優先度マスクが全解除で
+ *			  ない
+ *	(H) タスクディスパッチャによる起動
+ *		(H-1) ディスパッチ後のタスクがタスク例外許可でタスク例外処理要
+ *			  求あり
+ *	(I) タスク例外処理ルーチンからのリターンによる起動（連続起動）
+ *	(J) タスク例外処理ルーチンからの戻り時による状態復帰
+ *		(J-1) タスクに戻ってくる時
+ *		(J-2) タスク例外処理ルーチンが連続起動される時
+ *	(K) タスク例外処理ルーチンの多重起動
+ *	(L) タスク例外処理ルーチンからの戻り時のタスク切換え
+ *
+ * 【使用リソース】
+ *
+ *	TASK1: メインのタスク．自タスクに対してタスク例外処理を要求する
+ *	TASK2: 他タスクに対してタスク例外処理を要求する対象タスク
+ *	TASK3: タスク例外処理ルーチンが定義されていないタスク
+ *	TASK4: 休止状態のタスク
+ *
+ * 【テストシーケンス】
+ *
+ *	== TASK1（優先度：10）==
+ *	1:	state(false, false, TIPM_ENAALL, false, false, true)
+ *		ref_tex(TSK_SELF, &rtex)
+ *		assert((rtex.texstat & TTEX_DIS) != 0U)
+ *		assert(rtex.pndptn == 0U)
+ *		ras_tex(TASK3, 0x0001) -> E_OBJ		... (A-2)
+ *		ras_tex(TASK4, 0x0001) -> E_OBJ		... (A-1)
+ *		ref_tex(TASK3, &rtex) -> E_OBJ		... (D-2)
+ *		ref_tex(TASK4, &rtex) -> E_OBJ		... (D-1)
+ *	2:	ena_tex()							... (F-2)
+ *		state(false, false, TIPM_ENAALL, false, false, false)
+ *		ref_tex(TSK_SELF, &rtex)
+ *		assert((rtex.texstat & TTEX_ENA) != 0U)
+ *		assert(rtex.pndptn == 0U)
+ *	3:	ras_tex(TSK_SELF, 0x0001)			... (E-1)
+ *	== TASK1-TEX-1（1回目）==
+ *	4:	assert(texptn == 0x0001)
+ *		state(false, false, TIPM_ENAALL, false, false, true)
+ *	5:	dis_dsp() ... 4つの状態をそれぞれ変化させる
+ *		chg_ipm(TMAX_INTPRI)
+ *		ena_tex()
+ *		loc_cpu()
+ *		state(false, true, TMAX_INTPRI, true, true, false)
+ *		RETURN
+ *	== TASK1（続き）==
+ *	6:	state(false, false, TIPM_ENAALL, false, false, false)	... (J-1)
+ *	7:	dis_dsp() ... ディスパッチ禁止，タスク例外処理禁止
+ *		dis_tex()
+ *		state(false, false, TIPM_ENAALL, true, true, true)
+ *	8:	ras_tex(TASK1, 0x0002)				... (E-3)
+ *		ref_tex(TSK_SELF, &rtex)
+ *		assert((rtex.texstat & TTEX_DIS) != 0)
+ *		assert(rtex.pndptn == 0x0002)
+ *	9:	ena_tex()							... (F-1)
+ *	== TASK1-TEX-2（2回目）==
+ *	10:	assert(texptn == 0x0002)
+ *		state(false, false, TIPM_ENAALL, true, true, true)
+ *	11:	ras_tex(TASK1, 0x0001)				... (E-3)
+ *		ras_tex(TASK1, 0x0002)				... (E-3)
+ *	12:	ena_dsp() ... 3つの状態をそれぞれ変化させる
+ *		chg_ipm(TMAX_INTPRI)
+ *		loc_cpu()
+ *		state(false, true, TMAX_INTPRI, false, true, true)
+ *		RETURN								... (I)
+ *	== TASK1-TEX-3（3回目）==
+ *	13:	assert(texptn == 0x0003)
+ *		state(false, false, TIPM_ENAALL, true, true, true)	... (J-2)
+ *	14:	ena_dsp() ... ディスパッチ許可，タスク例外許可
+ *		chg_ipm(TMAX_INTPRI)
+ *		ena_tex()
+ *		state(false, false, TMAX_INTPRI, false, true, false)
+ *		chg_ipm(TIPM_ENAALL)				... (G-2)
+ *		chg_ipm(TMAX_INTPRI)
+ *	15: ras_tex(TSK_SELF, 0x0004)			... (E-4)
+ *		chg_ipm(TMAX_INTPRI)				... (G-4)
+ *		dis_tex()
+ *		chg_ipm(TIPM_ENAALL)				... (G-3)
+ *		chg_ipm(TMAX_INTPRI)
+ *		ena_tex()							... (F-3)
+ *	16:	chg_ipm(TIPM_ENAALL)				... (G-1)(K)
+ *	== TASK1-TEX-4（4回目）==
+ *	17:	assert(texptn == 0x0004)
+ *		state(false, false, TIPM_ENAALL, false, false, true)
+ *	18:	dis_dsp() ... 3つの状態をそれぞれ変化させる
+ *		chg_ipm(TMAX_INTPRI)
+ *		loc_cpu()
+ *		state(false, true, TMAX_INTPRI, true, true, true)
+ *		RETURN
+ *	== TASK1-TEX-3（3回目続き）==
+ *	19:	state(false, false, TIPM_ENAALL, false, false, false)
+ *		RETURN
+ *	== TASK1（続き）==
+ *	20:	state(false, false, TIPM_ENAALL, true, true, false)	... (J-1)
+ *	21: ena_dsp()
+ *		rot_rdq(TPRI_SELF)
+ *	== TASK2（優先度：10）	==
+ *	22:	state(false, false, TIPM_ENAALL, false, false, true)
+ *	23:	ena_tex()
+ *		state(false, false, TIPM_ENAALL, false, false, false)
+ *		rot_rdq(TPRI_SELF)
+ *	== TASK3（優先度：10）	==
+ *	24:	state(false, false, TIPM_ENAALL, false, false, true)
+ *	25:	ena_tex() -> E_OBJ					... (C-1)
+ *		state(false, false, TIPM_ENAALL, false, false, true)
+ *	26:	dis_tex() -> E_OBJ					... (B-1)
+ *		state(false, false, TIPM_ENAALL, false, false, true)
+ *		ext_tsk()
+ *	== TASK1（続き）==
+ *	27: ras_tex(TASK2, 0x0001)				... (E-2)
+ *		ref_tex(TASK2, &rtex)
+ *	28:	rot_rdq(TPRI_SELF)					... (H-1)
+ *	== TASK2-TEX-1（1回目）==
+ *	29:	assert(texptn == 0x0001)
+ *		state(false, false, TIPM_ENAALL, false, false, true)
+ *		RETURN
+ *	== TASK2（続き）==
+ *	30: ras_tex(TSK_SELF, 0x0002)
+ *	== TASK2-TEX-2（2回目）==
+ *	31:	assert(texptn == 0x0002)
+ *		state(false, false, TIPM_ENAALL, false, false, true)
+ *	32:	dis_dsp()
+ *		rot_rdq(TPRI_SELF)
+ *	33:	RETURN
+ *	== TASK1（続き）==
+ *	34:	RETURN
+ *	== TASK2（続き）==
+ *	35:	END
+ */
+
+#include <kernel.h>
+#include <test_lib.h>
+#include <t_syslog.h>
+#include "kernel_cfg.h"
+#include "test_tex1.h"
+
+/*
+ *  task4とtex_task4は生成されない
+ */
+
+void
+task4(intptr_t exinf)
+{
+	check_point(0);
+}
+
+void
+tex_task4(TEXPTN texptn, intptr_t exinf)
+{
+	check_point(0);
+}
+
+/* DO NOT DELETE THIS LINE -- gentest depends on it. */
+
+void
+task1(intptr_t exinf)
+{
+	ER_UINT	ercd;
+	T_RTEX	rtex;
+
+	test_start(__FILE__);
+
+	check_point(1);
+	check_state(false, false, TIPM_ENAALL, false, false, true);
+
+	ercd = ref_tex(TSK_SELF, &rtex);
+	check_ercd(ercd, E_OK);
+
+	check_assert((rtex.texstat & TTEX_DIS) != 0U);
+
+	check_assert(rtex.pndptn == 0U);
+
+	ercd = ras_tex(TASK3, 0x0001);
+	check_ercd(ercd, E_OBJ);
+
+	ercd = ras_tex(TASK4, 0x0001);
+	check_ercd(ercd, E_OBJ);
+
+	ercd = ref_tex(TASK3, &rtex);
+	check_ercd(ercd, E_OBJ);
+
+	ercd = ref_tex(TASK4, &rtex);
+	check_ercd(ercd, E_OBJ);
+
+	check_point(2);
+	ercd = ena_tex();
+	check_ercd(ercd, E_OK);
+
+	check_state(false, false, TIPM_ENAALL, false, false, false);
+
+	ercd = ref_tex(TSK_SELF, &rtex);
+	check_ercd(ercd, E_OK);
+
+	check_assert((rtex.texstat & TTEX_ENA) != 0U);
+
+	check_assert(rtex.pndptn == 0U);
+
+	check_point(3);
+	ercd = ras_tex(TSK_SELF, 0x0001);
+	check_ercd(ercd, E_OK);
+
+	check_point(6);
+	check_state(false, false, TIPM_ENAALL, false, false, false);
+
+	check_point(7);
+	ercd = dis_dsp();
+	check_ercd(ercd, E_OK);
+
+	ercd = dis_tex();
+	check_ercd(ercd, E_OK);
+
+	check_state(false, false, TIPM_ENAALL, true, true, true);
+
+	check_point(8);
+	ercd = ras_tex(TASK1, 0x0002);
+	check_ercd(ercd, E_OK);
+
+	ercd = ref_tex(TSK_SELF, &rtex);
+	check_ercd(ercd, E_OK);
+
+	check_assert((rtex.texstat & TTEX_DIS) != 0);
+
+	check_assert(rtex.pndptn == 0x0002);
+
+	check_point(9);
+	ercd = ena_tex();
+	check_ercd(ercd, E_OK);
+
+	check_point(20);
+	check_state(false, false, TIPM_ENAALL, true, true, false);
+
+	check_point(21);
+	ercd = ena_dsp();
+	check_ercd(ercd, E_OK);
+
+	ercd = rot_rdq(TPRI_SELF);
+	check_ercd(ercd, E_OK);
+
+	check_point(27);
+	ercd = ras_tex(TASK2, 0x0001);
+	check_ercd(ercd, E_OK);
+
+	ercd = ref_tex(TASK2, &rtex);
+	check_ercd(ercd, E_OK);
+
+	check_point(28);
+	ercd = rot_rdq(TPRI_SELF);
+	check_ercd(ercd, E_OK);
+
+	check_point(34);
+	return;
+
+	check_point(0);
+}
+
+static uint_t	tex_task1_count = 0;
+
+void
+tex_task1(TEXPTN texptn, intptr_t exinf)
+{
+	ER_UINT	ercd;
+
+	switch (++tex_task1_count) {
+	case 1:
+		check_point(4);
+		check_assert(texptn == 0x0001);
+
+		check_state(false, false, TIPM_ENAALL, false, false, true);
+
+		check_point(5);
+		ercd = dis_dsp();
+		check_ercd(ercd, E_OK);
+
+		ercd = chg_ipm(TMAX_INTPRI);
+		check_ercd(ercd, E_OK);
+
+		ercd = ena_tex();
+		check_ercd(ercd, E_OK);
+
+		ercd = loc_cpu();
+		check_ercd(ercd, E_OK);
+
+		check_state(false, true, TMAX_INTPRI, true, true, false);
+
+		return;
+
+		check_point(0);
+
+	case 2:
+		check_point(10);
+		check_assert(texptn == 0x0002);
+
+		check_state(false, false, TIPM_ENAALL, true, true, true);
+
+		check_point(11);
+		ercd = ras_tex(TASK1, 0x0001);
+		check_ercd(ercd, E_OK);
+
+		ercd = ras_tex(TASK1, 0x0002);
+		check_ercd(ercd, E_OK);
+
+		check_point(12);
+		ercd = ena_dsp();
+		check_ercd(ercd, E_OK);
+
+		ercd = chg_ipm(TMAX_INTPRI);
+		check_ercd(ercd, E_OK);
+
+		ercd = loc_cpu();
+		check_ercd(ercd, E_OK);
+
+		check_state(false, true, TMAX_INTPRI, false, true, true);
+
+		return;
+
+		check_point(0);
+
+	case 3:
+		check_point(13);
+		check_assert(texptn == 0x0003);
+
+		check_state(false, false, TIPM_ENAALL, true, true, true);
+
+		check_point(14);
+		ercd = ena_dsp();
+		check_ercd(ercd, E_OK);
+
+		ercd = chg_ipm(TMAX_INTPRI);
+		check_ercd(ercd, E_OK);
+
+		ercd = ena_tex();
+		check_ercd(ercd, E_OK);
+
+		check_state(false, false, TMAX_INTPRI, false, true, false);
+
+		ercd = chg_ipm(TIPM_ENAALL);
+		check_ercd(ercd, E_OK);
+
+		ercd = chg_ipm(TMAX_INTPRI);
+		check_ercd(ercd, E_OK);
+
+		check_point(15);
+		ercd = ras_tex(TSK_SELF, 0x0004);
+		check_ercd(ercd, E_OK);
+
+		ercd = chg_ipm(TMAX_INTPRI);
+		check_ercd(ercd, E_OK);
+
+		ercd = dis_tex();
+		check_ercd(ercd, E_OK);
+
+		ercd = chg_ipm(TIPM_ENAALL);
+		check_ercd(ercd, E_OK);
+
+		ercd = chg_ipm(TMAX_INTPRI);
+		check_ercd(ercd, E_OK);
+
+		ercd = ena_tex();
+		check_ercd(ercd, E_OK);
+
+		check_point(16);
+		ercd = chg_ipm(TIPM_ENAALL);
+		check_ercd(ercd, E_OK);
+
+		check_point(19);
+		check_state(false, false, TIPM_ENAALL, false, false, false);
+
+		return;
+
+		check_point(0);
+
+	case 4:
+		check_point(17);
+		check_assert(texptn == 0x0004);
+
+		check_state(false, false, TIPM_ENAALL, false, false, true);
+
+		check_point(18);
+		ercd = dis_dsp();
+		check_ercd(ercd, E_OK);
+
+		ercd = chg_ipm(TMAX_INTPRI);
+		check_ercd(ercd, E_OK);
+
+		ercd = loc_cpu();
+		check_ercd(ercd, E_OK);
+
+		check_state(false, true, TMAX_INTPRI, true, true, true);
+
+		return;
+
+		check_point(0);
+
+	default:
+		check_point(0);
+	}
+	check_point(0);
+}
+
+void
+task2(intptr_t exinf)
+{
+	ER_UINT	ercd;
+
+	check_point(22);
+	check_state(false, false, TIPM_ENAALL, false, false, true);
+
+	check_point(23);
+	ercd = ena_tex();
+	check_ercd(ercd, E_OK);
+
+	check_state(false, false, TIPM_ENAALL, false, false, false);
+
+	ercd = rot_rdq(TPRI_SELF);
+	check_ercd(ercd, E_OK);
+
+	check_point(30);
+	ercd = ras_tex(TSK_SELF, 0x0002);
+	check_ercd(ercd, E_OK);
+
+	check_finish(35);
+	check_point(0);
+}
+
+static uint_t	tex_task2_count = 0;
+
+void
+tex_task2(TEXPTN texptn, intptr_t exinf)
+{
+	ER_UINT	ercd;
+
+	switch (++tex_task2_count) {
+	case 1:
+		check_point(29);
+		check_assert(texptn == 0x0001);
+
+		check_state(false, false, TIPM_ENAALL, false, false, true);
+
+		return;
+
+		check_point(0);
+
+	case 2:
+		check_point(31);
+		check_assert(texptn == 0x0002);
+
+		check_state(false, false, TIPM_ENAALL, false, false, true);
+
+		check_point(32);
+		ercd = dis_dsp();
+		check_ercd(ercd, E_OK);
+
+		ercd = rot_rdq(TPRI_SELF);
+		check_ercd(ercd, E_OK);
+
+		check_point(33);
+		return;
+
+		check_point(0);
+
+	default:
+		check_point(0);
+	}
+	check_point(0);
+}
+
+void
+task3(intptr_t exinf)
+{
+	ER_UINT	ercd;
+
+	check_point(24);
+	check_state(false, false, TIPM_ENAALL, false, false, true);
+
+	check_point(25);
+	ercd = ena_tex();
+	check_ercd(ercd, E_OBJ);
+
+	check_state(false, false, TIPM_ENAALL, false, false, true);
+
+	check_point(26);
+	ercd = dis_tex();
+	check_ercd(ercd, E_OBJ);
+
+	check_state(false, false, TIPM_ENAALL, false, false, true);
+
+	ercd = ext_tsk();
+	check_ercd(ercd, E_OK);
+
+	check_point(0);
+}
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/test/test_tex1.cfg
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/test/test_tex1.cfg	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/test/test_tex1.cfg	(revision 457)
@@ -0,0 +1,24 @@
+/*
+ *  @(#) $Id$
+ */
+
+/*
+ *  タスク例外処理に関するテスト(1)のシステムコンフィギュレーションファイル
+ */
+INCLUDE("target_timer.cfg");
+INCLUDE("syssvc/syslog.cfg");
+INCLUDE("syssvc/banner.cfg");
+INCLUDE("syssvc/serial.cfg");
+
+#include "test_tex1.h"
+
+CRE_TSK(TASK1, { TA_ACT, 1, task1, TASK1_PRIORITY, STACK_SIZE, NULL });
+DEF_TEX(TASK1, { TA_NULL, tex_task1 });
+
+CRE_TSK(TASK2, { TA_ACT, 2, task2, TASK2_PRIORITY, STACK_SIZE, NULL });
+DEF_TEX(TASK2, { TA_NULL, tex_task2 });
+
+CRE_TSK(TASK3, { TA_ACT, 3, task3, TASK3_PRIORITY, STACK_SIZE, NULL });
+
+CRE_TSK(TASK4, { TA_NULL, 4, task4, TASK4_PRIORITY, STACK_SIZE, NULL });
+DEF_TEX(TASK4, { TA_NULL, tex_task4 });
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/test/test_tex1.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/test/test_tex1.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/test/test_tex1.h	(revision 457)
@@ -0,0 +1,80 @@
+/*
+ *  TOPPERS Software
+ *      Toyohashi Open Platform for Embedded Real-Time Systems
+ * 
+ *  Copyright (C) 2006,2007 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/* 
+ *		タスク例外処理に関するテスト(1)
+ */
+
+/*
+ *  ターゲット依存の定義
+ */
+#include "target_test.h"
+
+/*
+ *  各タスクの優先度の定義
+ */
+#define TASK1_PRIORITY	10		/* タスク1の優先度 */
+#define TASK2_PRIORITY	10		/* タスク2の優先度 */
+#define TASK3_PRIORITY	10		/* タスク3の優先度 */
+#define TASK4_PRIORITY	10		/* タスク4の優先度 */
+
+/*
+ *  ターゲットに依存する可能性のある定数の定義
+ */
+#ifndef STACK_SIZE
+#define	STACK_SIZE		4096		/* タスクのスタックサイズ */
+#endif /* STACK_SIZE */
+
+/*
+ *  関数のプロトタイプ宣言
+ */
+#ifndef TOPPERS_MACRO_ONLY
+
+extern void	tex_task1(TEXPTN texptn, intptr_t exinf);
+extern void	task1(intptr_t exinf);
+
+extern void	tex_task2(TEXPTN texptn, intptr_t exinf);
+extern void	task2(intptr_t exinf);
+
+extern void	task3(intptr_t exinf);
+
+extern void	tex_task4(TEXPTN texptn, intptr_t exinf);
+extern void	task4(intptr_t exinf);
+
+#endif /* TOPPERS_MACRO_ONLY */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/test/test_tex2.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/test/test_tex2.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/test/test_tex2.c	(revision 457)
@@ -0,0 +1,479 @@
+/*
+ *  TOPPERS Software
+ *      Toyohashi Open Platform for Embedded Real-Time Systems
+ * 
+ *  Copyright (C) 2007-2013 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  $Id$
+ */
+
+/* 
+ *		タスク例外処理に関するテスト(2)
+ *
+ * 【テストの目的】
+ *
+ *  割込みハンドラ（アラームハンドラ）およびCPU例外ハンドラからタスク例
+ *  外処理ルーチンを起動する処理を網羅的にテストする．
+ *
+ * 【テスト項目】
+ *
+ *	(A) iras_texのエラー検出
+ *		(A-1) 対象タスクが休止状態
+ *		(A-2) 対象タスクのタスク例外処理ルーチンが定義されていない
+ *	(B) 割込みハンドラから呼ばれたiras_texの正常処理
+ *		(B-1) 対象タスクが実行状態のタスクかつタスク例外処理許可
+ *		(B-2) 対象タスクが実行状態のタスクでない
+ *		(B-3) 対象タスクが実行状態のタスクだがタスク例外処理禁止
+ *	(C) CPU例外ハンドラから呼ばれたiras_texの正常処理
+ *		(C-1) 対象タスクが実行状態のタスクかつタスク例外処理許可
+ *		(C-2) 対象タスクが実行状態のタスクでない
+ *		(C-3) 対象タスクが実行状態のタスクだがタスク例外処理禁止
+ *				→ 実施しない（ターゲット非依存に実現できない）
+ *	(D) 割込みハンドラの出口処理による起動
+ *		(D-1) ディスパッチ後のタスクがタスク例外許可でタスク例外処理要
+ *			  求あり
+ *	(E) CPU例外ハンドラの出口処理による起動
+ *		(E-1) ディスパッチ後のタスクがタスク例外許可でタスク例外処理要
+ *			  求あり
+ *	(F) sns_texで実行状態のタスクがない
+ *
+ * 【使用リソース】
+ *
+ *	TASK1: メインのタスク．実行状態のタスクに対してタスク例外処理を要求す
+ *		   る対象タスク
+ *	TASK2: 実行状態でないタスクに対してタスク例外処理を要求する対象タスク
+ *	TASK3: タスク例外処理ルーチンが定義されていないタスク
+ *	TASK4: 休止状態のタスク
+ *	ALM1:  アラームハンドラ1
+ *	ALM2:  アラームハンドラ2
+ *	ALM3:  アラームハンドラ3
+ *	CPUEXC: CPU例外ハンドラ
+ *
+ * 【テストシーケンス】
+ *
+ *	== TASK1（優先度：10）==
+ *	1:	state(false, false, TIPM_ENAALL, false, false, true)
+ *		ref_tex(TSK_SELF, &rtex)
+ *		assert((rtex.texstat & TTEX_DIS) != 0U)
+ *		assert(rtex.pndptn == 0U)
+ *	2:	sta_alm(ALM1, 1U)
+ *		DO(while (!(alm1_flag)))	... アラームハンドラ1の実行を待つ
+ *	== ALM1 ==
+ *	3:	state_i(true, false, false, true, true)
+ *		iras_tex(TASK3, 0x0001) -> E_OBJ		... (A-2)
+ *		iras_tex(TASK4, 0x0001) -> E_OBJ		... (A-1)
+ *		iras_tex(TASK2, 0x0001)					... (B-2)
+ *		iras_tex(TASK1, 0x0001)					... (B-3)
+ *		DO(alm1_flag = true)
+ *		RETURN
+ *	== TASK1（続き）==
+ *	4:	ena_tex()
+ *	== TASK1-TEX-1（1回目）==
+ *	5:	assert(texptn == 0x0001)
+ *		state(false, false, TIPM_ENAALL, false, false, true)
+ *	6:	dis_dsp() ... 4つの状態をそれぞれ変化させる
+ *		chg_ipm(TMAX_INTPRI)
+ *		ena_tex()
+ *		loc_cpu()
+ *		state(false, true, TMAX_INTPRI, true, true, false)
+ *		RETURN
+ *	== TASK1（続き）==
+ *	7:	state(false, false, TIPM_ENAALL, false, false, false)
+ *		ref_tex(TSK_SELF, &rtex)
+ *		assert((rtex.texstat & TTEX_ENA) != 0U)
+ *		assert(rtex.pndptn == 0U)
+ *	8:	sta_alm(ALM2, 1U)
+ *		DO(while (!(alm2_flag)))
+ *	== ALM2 ==
+ *	9:	state_i(true, false, false, true, false)
+ *		iras_tex(TASK1, 0x0002)					... (B-1)
+ *		DO(alm2_flag = true)
+ *		RETURN									... (D-1)
+ *	== TASK1-TEX-2（2回目）==
+ *	10:	assert(texptn == 0x0002)
+ *		state(false, false, TIPM_ENAALL, false, false, true)
+ *		RETURN
+ *	== TASK1（続き）==
+ *	11:	sus_tsk(TASK2)
+ *		sus_tsk(TASK3)
+ *	12:	sta_alm(ALM3, 10U)
+ *	13:	dly_tsk(50U)
+ *	== ALM3 ==
+ *	14:	state_i(true, false, false, true, true)	... (F)［sns_tex()を含む］
+ *		iget_tid(&tskid)
+ *		assert(tskid == TSK_NONE)
+ *		iras_tex(TASK1, 0x0004)
+ *		DO(alm3_flag = true)
+ *		RETURN
+ *	== TASK1-TEX-3（3回目）==
+ *	15:	assert(texptn == 0x0004)
+ *		state(false, false, TIPM_ENAALL, false, false, true)
+ *		RETURN
+ *	== TASK1（続き）==
+ *	16:	rsm_tsk(TASK2)
+ *		rsm_tsk(TASK3)
+ *		dis_dsp()
+ *	17:	DO(RAISE_CPU_EXCEPTION)
+ *	== CPUEXC ==
+ *	18:	state_i(true, false, true, true, false)
+ *		assert(xsns_xpn(p_excinf) == false)
+ *		iras_tex(TASK3, 0x0010) -> E_OBJ		... (A-2)
+ *		iras_tex(TASK4, 0x0010) -> E_OBJ		... (A-1)
+ *		iras_tex(TASK2, 0x0010)					... (C-2)
+ *		iras_tex(TASK1, 0x0010)					... (C-1)
+ *		RETURN									... (E-1)
+ *	== TASK1-TEX-4（4回目）==
+ *	19:	assert(texptn == 0x0010)
+ *		state(false, false, TIPM_ENAALL, true, true, true)
+ *	20:	ext_tsk()
+ *	== TASK2（優先度：10）==
+ *	21:	state(false, false, TIPM_ENAALL, false, false, true)
+ *	22:	ena_tex()
+ *	== TASK2-TEX ==
+ *	23:	assert(texptn == 0x0011)
+ *		state(false, false, TIPM_ENAALL, false, false, true)
+ *		RETURN
+ *	== TASK2（続き）==
+ *	24:	sus_tsk(TASK3)
+ *	25:	END
+ */
+
+#include <kernel.h>
+#include <test_lib.h>
+#include <t_syslog.h>
+#include "kernel_cfg.h"
+#include "test_tex2.h"
+
+volatile bool_t	alm1_flag = false;
+volatile bool_t	alm2_flag = false;
+volatile bool_t	alm3_flag = false;
+
+/*
+ *  task3，task4とtex_task4は生成されない
+ */
+
+void
+task3(intptr_t exinf)
+{
+	check_point(0);
+}
+
+void
+task4(intptr_t exinf)
+{
+	check_point(0);
+}
+
+void
+tex_task4(TEXPTN texptn, intptr_t exinf)
+{
+	check_point(0);
+}
+
+/* DO NOT DELETE THIS LINE -- gentest depends on it. */
+
+void
+alarm1_handler(intptr_t exinf)
+{
+	ER_UINT	ercd;
+
+	check_point(3);
+	check_state_i(true, false, false, true, true);
+
+	ercd = iras_tex(TASK3, 0x0001);
+	check_ercd(ercd, E_OBJ);
+
+	ercd = iras_tex(TASK4, 0x0001);
+	check_ercd(ercd, E_OBJ);
+
+	ercd = iras_tex(TASK2, 0x0001);
+	check_ercd(ercd, E_OK);
+
+	ercd = iras_tex(TASK1, 0x0001);
+	check_ercd(ercd, E_OK);
+
+	alm1_flag = true;
+
+	return;
+
+	check_point(0);
+}
+
+void
+alarm2_handler(intptr_t exinf)
+{
+	ER_UINT	ercd;
+
+	check_point(9);
+	check_state_i(true, false, false, true, false);
+
+	ercd = iras_tex(TASK1, 0x0002);
+	check_ercd(ercd, E_OK);
+
+	alm2_flag = true;
+
+	return;
+
+	check_point(0);
+}
+
+void
+alarm3_handler(intptr_t exinf)
+{
+	ID		tskid;
+	ER_UINT	ercd;
+
+	check_point(14);
+	check_state_i(true, false, false, true, true);
+
+	ercd = iget_tid(&tskid);
+	check_ercd(ercd, E_OK);
+
+	check_assert(tskid == TSK_NONE);
+
+	ercd = iras_tex(TASK1, 0x0004);
+	check_ercd(ercd, E_OK);
+
+	alm3_flag = true;
+
+	return;
+
+	check_point(0);
+}
+
+void
+cpuexc_handler(void *p_excinf)
+{
+	ER_UINT	ercd;
+
+	check_point(18);
+	check_state_i(true, false, true, true, false);
+
+	check_assert(xsns_xpn(p_excinf) == false);
+
+	ercd = iras_tex(TASK3, 0x0010);
+	check_ercd(ercd, E_OBJ);
+
+	ercd = iras_tex(TASK4, 0x0010);
+	check_ercd(ercd, E_OBJ);
+
+	ercd = iras_tex(TASK2, 0x0010);
+	check_ercd(ercd, E_OK);
+
+	ercd = iras_tex(TASK1, 0x0010);
+	check_ercd(ercd, E_OK);
+
+	return;
+
+	check_point(0);
+}
+
+void
+task1(intptr_t exinf)
+{
+	ER_UINT	ercd;
+	T_RTEX	rtex;
+
+	test_start(__FILE__);
+
+	check_point(1);
+	check_state(false, false, TIPM_ENAALL, false, false, true);
+
+	ercd = ref_tex(TSK_SELF, &rtex);
+	check_ercd(ercd, E_OK);
+
+	check_assert((rtex.texstat & TTEX_DIS) != 0U);
+
+	check_assert(rtex.pndptn == 0U);
+
+	check_point(2);
+	ercd = sta_alm(ALM1, 1U);
+	check_ercd(ercd, E_OK);
+
+	while (!(alm1_flag));
+
+	check_point(4);
+	ercd = ena_tex();
+	check_ercd(ercd, E_OK);
+
+	check_point(7);
+	check_state(false, false, TIPM_ENAALL, false, false, false);
+
+	ercd = ref_tex(TSK_SELF, &rtex);
+	check_ercd(ercd, E_OK);
+
+	check_assert((rtex.texstat & TTEX_ENA) != 0U);
+
+	check_assert(rtex.pndptn == 0U);
+
+	check_point(8);
+	ercd = sta_alm(ALM2, 1U);
+	check_ercd(ercd, E_OK);
+
+	while (!(alm2_flag));
+
+	check_point(11);
+	ercd = sus_tsk(TASK2);
+	check_ercd(ercd, E_OK);
+
+	ercd = sus_tsk(TASK3);
+	check_ercd(ercd, E_OK);
+
+	check_point(12);
+	ercd = sta_alm(ALM3, 10U);
+	check_ercd(ercd, E_OK);
+
+	check_point(13);
+	ercd = dly_tsk(50U);
+	check_ercd(ercd, E_OK);
+
+	check_point(16);
+	ercd = rsm_tsk(TASK2);
+	check_ercd(ercd, E_OK);
+
+	ercd = rsm_tsk(TASK3);
+	check_ercd(ercd, E_OK);
+
+	ercd = dis_dsp();
+	check_ercd(ercd, E_OK);
+
+	check_point(17);
+	RAISE_CPU_EXCEPTION;
+
+	check_point(0);
+}
+
+static uint_t	tex_task1_count = 0;
+
+void
+tex_task1(TEXPTN texptn, intptr_t exinf)
+{
+	ER_UINT	ercd;
+
+	switch (++tex_task1_count) {
+	case 1:
+		check_point(5);
+		check_assert(texptn == 0x0001);
+
+		check_state(false, false, TIPM_ENAALL, false, false, true);
+
+		check_point(6);
+		ercd = dis_dsp();
+		check_ercd(ercd, E_OK);
+
+		ercd = chg_ipm(TMAX_INTPRI);
+		check_ercd(ercd, E_OK);
+
+		ercd = ena_tex();
+		check_ercd(ercd, E_OK);
+
+		ercd = loc_cpu();
+		check_ercd(ercd, E_OK);
+
+		check_state(false, true, TMAX_INTPRI, true, true, false);
+
+		return;
+
+		check_point(0);
+
+	case 2:
+		check_point(10);
+		check_assert(texptn == 0x0002);
+
+		check_state(false, false, TIPM_ENAALL, false, false, true);
+
+		return;
+
+		check_point(0);
+
+	case 3:
+		check_point(15);
+		check_assert(texptn == 0x0004);
+
+		check_state(false, false, TIPM_ENAALL, false, false, true);
+
+		return;
+
+		check_point(0);
+
+	case 4:
+		check_point(19);
+		check_assert(texptn == 0x0010);
+
+		check_state(false, false, TIPM_ENAALL, true, true, true);
+
+		check_point(20);
+		ercd = ext_tsk();
+		check_ercd(ercd, E_OK);
+
+		check_point(0);
+
+	default:
+		check_point(0);
+	}
+	check_point(0);
+}
+
+void
+task2(intptr_t exinf)
+{
+	ER_UINT	ercd;
+
+	check_point(21);
+	check_state(false, false, TIPM_ENAALL, false, false, true);
+
+	check_point(22);
+	ercd = ena_tex();
+	check_ercd(ercd, E_OK);
+
+	check_point(24);
+	ercd = sus_tsk(TASK3);
+	check_ercd(ercd, E_OK);
+
+	check_finish(25);
+	check_point(0);
+}
+
+void
+tex_task2(TEXPTN texptn, intptr_t exinf)
+{
+
+	check_point(23);
+	check_assert(texptn == 0x0011);
+
+	check_state(false, false, TIPM_ENAALL, false, false, true);
+
+	return;
+
+	check_point(0);
+}
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/test/test_tex2.cfg
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/test/test_tex2.cfg	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/test/test_tex2.cfg	(revision 457)
@@ -0,0 +1,30 @@
+/*
+ *  @(#) $Id$
+ */
+
+/*
+ *  タスク例外処理に関するテスト(2)のシステムコンフィギュレーションファイル
+ */
+INCLUDE("target_timer.cfg");
+INCLUDE("syssvc/syslog.cfg");
+INCLUDE("syssvc/banner.cfg");
+INCLUDE("syssvc/serial.cfg");
+
+#include "test_tex2.h"
+
+CRE_TSK(TASK1, { TA_ACT, 1, task1, TASK1_PRIORITY, STACK_SIZE, NULL });
+DEF_TEX(TASK1, { TA_NULL, tex_task1 });
+
+CRE_TSK(TASK2, { TA_ACT, 2, task2, TASK2_PRIORITY, STACK_SIZE, NULL });
+DEF_TEX(TASK2, { TA_NULL, tex_task2 });
+
+CRE_TSK(TASK3, { TA_ACT, 3, task3, TASK3_PRIORITY, STACK_SIZE, NULL });
+
+CRE_TSK(TASK4, { TA_NULL, 4, task4, TASK4_PRIORITY, STACK_SIZE, NULL });
+DEF_TEX(TASK4, { TA_NULL, tex_task4 });
+
+CRE_ALM(ALM1, { TA_NULL, 1, alarm1_handler });
+CRE_ALM(ALM2, { TA_NULL, 2, alarm2_handler });
+CRE_ALM(ALM3, { TA_NULL, 3, alarm3_handler });
+
+DEF_EXC(CPUEXC1, { TA_NULL, cpuexc_handler });
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/test/test_tex2.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/test/test_tex2.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/test/test_tex2.h	(revision 457)
@@ -0,0 +1,85 @@
+/*
+ *  TOPPERS Software
+ *      Toyohashi Open Platform for Embedded Real-Time Systems
+ * 
+ *  Copyright (C) 2007 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/* 
+ *		タスク例外処理に関するテスト(2)
+ */
+
+/*
+ *  ターゲット依存の定義
+ */
+#include "target_test.h"
+
+/*
+ *  各タスクの優先度の定義
+ */
+#define TASK1_PRIORITY	10		/* タスク1の優先度 */
+#define TASK2_PRIORITY	10		/* タスク2の優先度 */
+#define TASK3_PRIORITY	10		/* タスク3の優先度 */
+#define TASK4_PRIORITY	10		/* タスク4の優先度 */
+
+/*
+ *  ターゲットに依存する可能性のある定数の定義
+ */
+#ifndef STACK_SIZE
+#define	STACK_SIZE		4096		/* タスクのスタックサイズ */
+#endif /* STACK_SIZE */
+
+/*
+ *  関数のプロトタイプ宣言
+ */
+#ifndef TOPPERS_MACRO_ONLY
+
+extern void	tex_task1(TEXPTN texptn, intptr_t exinf);
+extern void	task1(intptr_t exinf);
+
+extern void	tex_task2(TEXPTN texptn, intptr_t exinf);
+extern void	task2(intptr_t exinf);
+
+extern void	task3(intptr_t exinf);
+
+extern void	tex_task4(TEXPTN texptn, intptr_t exinf);
+extern void	task4(intptr_t exinf);
+
+extern void	alarm1_handler(intptr_t exinf);
+extern void	alarm2_handler(intptr_t exinf);
+extern void	alarm3_handler(intptr_t exinf);
+extern void	cpuexc_handler(void *p_excinf);
+
+#endif /* TOPPERS_MACRO_ONLY */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/test/test_utm1.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/test/test_utm1.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/test/test_utm1.c	(revision 457)
@@ -0,0 +1,124 @@
+/*
+ *  TOPPERS Software
+ *      Toyohashi Open Platform for Embedded Real-Time Systems
+ * 
+ *  Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
+ *                              Toyohashi Univ. of Technology, JAPAN
+ *  Copyright (C) 2007-2010 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  $Id$
+ */
+
+/*
+ *		get_utmに関するテスト(1)
+ *
+ * 【テストの目的】
+ *
+ *  性能評価用システム時刻が逆行することがないことをテストする．
+ *
+ * 【テストの内容】
+ *
+ *  メインタスクでは，性能評価用システム時刻を繰り返し取得し，時刻が小
+ *  さくならないかをチェックする．それと並行して，周期ハンドラを1ミリ秒
+ *  周期で実行し，その中でも性能評価用システム時刻を取得して，時刻が小
+ *  さくならないかをチェックする．
+ *
+ *  なお，性能評価用システム時刻が最大値を超えて0に戻る状況は考慮してい
+ *  ない．
+ */
+
+#include <kernel.h>
+#include <test_lib.h>
+#include <t_syslog.h>
+#include "kernel_cfg.h"
+#include "test_utm1.h"
+
+#define	NO_LOOP		ULONG_C(100000)
+
+SYSUTM	recent_sysutm;
+char	*recent_sysutm_pos;
+uint_t	cyclic_count;
+
+void
+cyclic_handler(intptr_t exinf)
+{
+	SYSUTM		sysutm, prev_sysutm;
+	char		*prev_sysutm_pos;
+
+	iloc_cpu();
+	get_utm(&sysutm);
+	prev_sysutm = recent_sysutm;
+	prev_sysutm_pos = recent_sysutm_pos;
+	recent_sysutm = sysutm;
+	recent_sysutm_pos = "CYC";
+	iunl_cpu();
+
+	if (prev_sysutm > sysutm) {
+		syslog(LOG_NOTICE,
+				"system performance time goes back: %ld(%s) %ld(CYC)",
+				((long_t) prev_sysutm), prev_sysutm_pos, ((ulong_t) sysutm));
+	}
+	cyclic_count += 1;
+}
+
+void
+main_task(intptr_t exinf)
+{
+	SYSUTM		sysutm, prev_sysutm;
+	char		*prev_sysutm_pos;
+	ulong_t		i;
+
+	cyclic_count = 0U;
+	get_utm(&recent_sysutm);
+	syslog(LOG_NOTICE, "system performance time test starts.");
+
+	for (i = 0; i < NO_LOOP; i++) {
+		loc_cpu();
+		get_utm(&sysutm);
+		prev_sysutm = recent_sysutm;
+		prev_sysutm_pos = recent_sysutm_pos;
+		recent_sysutm = sysutm;
+		recent_sysutm_pos = "TSK";
+		unl_cpu();
+
+		if (prev_sysutm > sysutm) {
+			syslog(LOG_NOTICE,
+				"system performance time goes back: %ld(%s) %ld(TSK)",
+				((long_t) prev_sysutm), prev_sysutm_pos, ((ulong_t) sysutm));
+		}
+	}
+
+	syslog(LOG_NOTICE, "system performance time test finishes.");
+	syslog(LOG_NOTICE, "number of cyclic handler execution: %d", cyclic_count);
+	test_finish();
+}
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/test/test_utm1.cfg
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/test/test_utm1.cfg	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/test/test_utm1.cfg	(revision 457)
@@ -0,0 +1,16 @@
+/*
+ *  $Id$
+ */
+
+/*
+ *  get_utmに関するテスト(1)のシステムコンフィギュレーションファイル
+ */
+INCLUDE("target_timer.cfg");
+INCLUDE("syssvc/syslog.cfg");
+INCLUDE("syssvc/banner.cfg");
+INCLUDE("syssvc/serial.cfg");
+
+#include "test_utm1.h"
+
+CRE_CYC(CYC1, { TA_STA, 0, cyclic_handler, 2, 1 });
+CRE_TSK(MAIN_TASK, { TA_ACT, 0, main_task, MAIN_PRIORITY, STACK_SIZE, NULL });
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/test/test_utm1.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/test/test_utm1.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/test/test_utm1.h	(revision 457)
@@ -0,0 +1,69 @@
+/*
+ *  TOPPERS Software
+ *      Toyohashi Open Platform for Embedded Real-Time Systems
+ * 
+ *  Copyright (C) 2006-2010 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  $Id$
+ */
+
+/*
+ *		get_utmに関するテスト(1)
+ */
+
+/*
+ *  ターゲット依存の定義
+ */
+#include "target_test.h"
+
+/*
+ *  各タスクの優先度の定義
+ */
+#define MAIN_PRIORITY	10
+
+/*
+ *  ターゲットに依存する可能性のある定数の定義
+ */
+#ifndef STACK_SIZE
+#define	STACK_SIZE		4096		/* タスクのスタックサイズ */
+#endif /* STACK_SIZE */
+
+/*
+ *  関数のプロトタイプ宣言
+ */
+#ifndef TOPPERS_MACRO_ONLY
+
+extern void	cyclic_handler(intptr_t exinf);
+extern void	main_task(intptr_t exinf);
+
+#endif /* TOPPERS_MACRO_ONLY */
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/ui/snfont_disp/Makefile.config
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/ui/snfont_disp/Makefile.config	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/ui/snfont_disp/Makefile.config	(revision 457)
@@ -0,0 +1,57 @@
+#
+#   TOPPERS/ASP/FMP Kernel
+#       Toyohashi Open Platform for Embedded Real-Time Systems/
+#       Advanced Standard Profile Kernel
+#
+#   Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
+#                               Toyohashi Univ. of Technology, JAPAN
+#   Copyright (C) 2003-2008 by Ryosuke Takeuchi
+#                Platform Development Center RICOH COMPANY,LTD. JAPAN
+#   Copyright (C) 2017-2019 by TOPPERS PROJECT Educational Working Group.
+#
+#   上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+#   によって公表されている GNU General Public License の Version 2 に記
+#   述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+#   を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+#   利用と呼ぶ）することを無償で許諾する．
+#   (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+#       権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+#       スコード中に含まれていること．
+#   (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+#       用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+#       者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+#       の無保証規定を掲載すること．
+#   (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+#       用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+#       と．
+#     (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+#         作権表示，この利用条件および下記の無保証規定を掲載すること．
+#     (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+#         報告すること．
+#   (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+#       害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+#
+#   本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+#   よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+#   含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+#   接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+#
+#  @(#) $Id$
+#
+
+#
+#  Makefile のプロセッサ依存 (snfont_disp用)
+#
+
+#
+#  コンパイルオプション
+#
+INCLUDES := $(INCLUDES) -I$(SRCDIR)/ui/snfont_disp
+
+#
+#  プログラムに関する定義
+#
+SYSSVC_DIR := $(SYSSVC_DIR):$(SRCDIR)/ui/snfont_disp
+SYSSVC_COBJS := $(SYSSVC_COBJS) glcd_disp.o font9.o font12.o font16.o \
+	shinonome_font.o
+
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/ui/snfont_disp/font12.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/ui/snfont_disp/font12.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/ui/snfont_disp/font12.c	(revision 457)
@@ -0,0 +1,4577 @@
+/*
+ *  TOPPERS ECHONET Lite Communication Middleware
+ * 
+ *  Copyright (C) 2018 Cores Co., Ltd. Japan
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  $Id$
+ */
+
+/*
+ * 東雲フォント
+ * http://openlab.ring.gr.jp/efont/shinonome/
+ * Licence
+ * Public Domain
+ */
+
+
+#include "fonts.h"
+
+/*
+ *  001
+ */
+static const uint8_t Font12_01[] = {
+	6, 12,
+	1, 12,
+	0x00, //       
+	0x20, //   #   
+	0x20, //   #   
+	0x70, //  ###  
+	0x70, //  ###  
+	0xF8, // ##### 
+	0xF8, // ##### 
+	0x70, //  ###  
+	0x70, //  ###  
+	0x20, //   #   
+	0x20, //   #   
+	0x00  //       
+};
+
+/*
+ *  002
+ */
+static const uint8_t Font12_02[] = {
+	6, 12,
+	1, 12,
+	0x54, //  # # #
+	0xA8, // # # # 
+	0x54, //  # # #
+	0xA8, // # # # 
+	0x54, //  # # #
+	0xA8, // # # # 
+	0x54, //  # # #
+	0xA8, // # # # 
+	0x54, //  # # #
+	0xA8, // # # # 
+	0x54, //  # # #
+	0xA8  // # # # 
+};
+
+/*
+ *  003
+ */
+static const uint8_t Font12_03[] = {
+	6, 12,
+	1, 12,
+	0x00, //       
+	0xA0, // # #   
+	0xA0, // # #   
+	0xE0, // ###   
+	0xA0, // # #   
+	0xA0, // # #   
+	0x38, //   ### 
+	0x10, //    #  
+	0x10, //    #  
+	0x10, //    #  
+	0x10, //    #  
+	0x00  //       
+};
+
+/*
+ *  004
+ */
+static const uint8_t Font12_04[] = {
+	6, 12,
+	1, 12,
+	0x00, //       
+	0xE0, // ###   
+	0x80, // #     
+	0xE0, // ###   
+	0x80, // #     
+	0x80, // #     
+	0x38, //   ### 
+	0x20, //   #   
+	0x38, //   ### 
+	0x20, //   #   
+	0x20, //   #   
+	0x00  //       
+};
+
+/*
+ *  005
+ */
+static const uint8_t Font12_05[] = {
+	6, 12,
+	1, 12,
+	0x00, //       
+	0x60, //  ##   
+	0x80, // #     
+	0x80, // #     
+	0x80, // #     
+	0x60, //  ##   
+	0x30, //   ##  
+	0x28, //   # # 
+	0x30, //   ##  
+	0x28, //   # # 
+	0x28, //   # # 
+	0x00  //       
+};
+
+/*
+ *  006
+ */
+static const uint8_t Font12_06[] = {
+	6, 12,
+	1, 12,
+	0x00, //       
+	0x80, // #     
+	0x80, // #     
+	0x80, // #     
+	0x80, // #     
+	0xE0, // ###   
+	0x38, //   ### 
+	0x20, //   #   
+	0x38, //   ### 
+	0x20, //   #   
+	0x20, //   #   
+	0x00  //       
+};
+
+/*
+ *  007
+ */
+static const uint8_t Font12_07[] = {
+	6, 12,
+	1, 12,
+	0x00, //       
+	0x60, //  ##   
+	0x90, // #  #  
+	0x60, //  ##   
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0x00  //       
+};
+
+/*
+ *  008
+ */
+static const uint8_t Font12_08[] = {
+	6, 12,
+	1, 12,
+	0x00, //       
+	0x20, //   #   
+	0x20, //   #   
+	0x20, //   #   
+	0xF8, // ##### 
+	0x20, //   #   
+	0x20, //   #   
+	0x20, //   #   
+	0x00, //       
+	0xF8, // ##### 
+	0x00, //       
+	0x00  //       
+};
+
+/*
+ *  009
+ */
+static const uint8_t Font12_09[] = {
+	6, 12,
+	1, 12,
+	0x00, //       
+	0xC0, // ##    
+	0xA0, // # #   
+	0xA0, // # #   
+	0xA0, // # #   
+	0xA0, // # #   
+	0x20, //   #   
+	0x20, //   #   
+	0x20, //   #   
+	0x20, //   #   
+	0x38, //   ### 
+	0x00  //       
+};
+
+/*
+ *  010
+ */
+static const uint8_t Font12_10[] = {
+	6, 12,
+	1, 12,
+	0x00, //       
+	0xA0, // # #   
+	0xA0, // # #   
+	0xA0, // # #   
+	0xA0, // # #   
+	0x40, //  #    
+	0x30, //   ##  
+	0x28, //   # # 
+	0x30, //   ##  
+	0x28, //   # # 
+	0x28, //   # # 
+	0x00  //       
+};
+
+/*
+ *  011
+ */
+static const uint8_t Font12_11[] = {
+	6, 12,
+	1, 12,
+	0x20, //   #   
+	0x20, //   #   
+	0x20, //   #   
+	0x20, //   #   
+	0x20, //   #   
+	0xE0, // ###   
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0x00  //       
+};
+
+/*
+ *  012
+ */
+static const uint8_t Font12_12[] = {
+	6, 12,
+	1, 12,
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0xE0, // ###   
+	0x20, //   #   
+	0x20, //   #   
+	0x20, //   #   
+	0x20, //   #   
+	0x20, //   #   
+	0x20  //   #   
+};
+
+/*
+ *  013
+ */
+static const uint8_t Font12_13[] = {
+	6, 12,
+	1, 12,
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0x3C, //   ####
+	0x20, //   #   
+	0x20, //   #   
+	0x20, //   #   
+	0x20, //   #   
+	0x20, //   #   
+	0x20  //   #   
+};
+
+/*
+ *  014
+ */
+static const uint8_t Font12_14[] = {
+	6, 12,
+	1, 12,
+	0x20, //   #   
+	0x20, //   #   
+	0x20, //   #   
+	0x20, //   #   
+	0x20, //   #   
+	0x3C, //   ####
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0x00  //       
+};
+
+/*
+ *  015
+ */
+static const uint8_t Font12_15[] = {
+	6, 12,
+	1, 12,
+	0x20, //   #   
+	0x20, //   #   
+	0x20, //   #   
+	0x20, //   #   
+	0x20, //   #   
+	0xFC, // ######
+	0x20, //   #   
+	0x20, //   #   
+	0x20, //   #   
+	0x20, //   #   
+	0x20, //   #   
+	0x20  //   #   
+};
+
+/*
+ *  016
+ */
+static const uint8_t Font12_16[] = {
+	6, 12,
+	1, 12,
+	0xFC, // ######
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0x00  //       
+};
+
+/*
+ *  017
+ */
+static const uint8_t Font12_17[] = {
+	6, 12,
+	1, 12,
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0xFC, // ######
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0x00  //       
+};
+
+/*
+ *  018
+ */
+static const uint8_t Font12_18[] = {
+	6, 12,
+	1, 12,
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0xFC, // ######
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0x00  //       
+};
+
+/*
+ *  019
+ */
+static const uint8_t Font12_19[] = {
+	6, 12,
+	1, 12,
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0xFC, // ######
+	0x00, //       
+	0x00, //       
+	0x00  //       
+};
+
+/*
+ *  020
+ */
+static const uint8_t Font12_20[] = {
+	6, 12,
+	1, 12,
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0xFC  // ######
+};
+
+/*
+ *  021
+ */
+static const uint8_t Font12_21[] = {
+	6, 12,
+	1, 12,
+	0x20, //   #   
+	0x20, //   #   
+	0x20, //   #   
+	0x20, //   #   
+	0x20, //   #   
+	0x3C, //   ####
+	0x20, //   #   
+	0x20, //   #   
+	0x20, //   #   
+	0x20, //   #   
+	0x20, //   #   
+	0x20  //   #   
+};
+
+/*
+ *  022
+ */
+static const uint8_t Font12_22[] = {
+	6, 12,
+	1, 12,
+	0x20, //   #   
+	0x20, //   #   
+	0x20, //   #   
+	0x20, //   #   
+	0x20, //   #   
+	0xE0, // ###   
+	0x20, //   #   
+	0x20, //   #   
+	0x20, //   #   
+	0x20, //   #   
+	0x20, //   #   
+	0x20  //   #   
+};
+
+/*
+ *  023
+ */
+static const uint8_t Font12_23[] = {
+	6, 12,
+	1, 12,
+	0x20, //   #   
+	0x20, //   #   
+	0x20, //   #   
+	0x20, //   #   
+	0x20, //   #   
+	0xFC, // ######
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0x00  //       
+};
+
+/*
+ *  024
+ */
+static const uint8_t Font12_24[] = {
+	6, 12,
+	1, 12,
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0xFC, // ######
+	0x20, //   #   
+	0x20, //   #   
+	0x20, //   #   
+	0x20, //   #   
+	0x20, //   #   
+	0x20  //   #   
+};
+
+/*
+ *  025
+ */
+static const uint8_t Font12_25[] = {
+	6, 12,
+	1, 12,
+	0x20, //   #   
+	0x20, //   #   
+	0x20, //   #   
+	0x20, //   #   
+	0x20, //   #   
+	0x20, //   #   
+	0x20, //   #   
+	0x20, //   #   
+	0x20, //   #   
+	0x20, //   #   
+	0x20, //   #   
+	0x20  //   #   
+};
+
+/*
+ *  026
+ */
+static const uint8_t Font12_26[] = {
+	6, 12,
+	1, 12,
+	0x00, //       
+	0x00, //       
+	0x18, //    ## 
+	0x60, //  ##   
+	0x80, // #     
+	0x60, //  ##   
+	0x18, //    ## 
+	0xF8, // ##### 
+	0x00, //       
+	0xF8, // ##### 
+	0x00, //       
+	0x00  //       
+};
+
+/*
+ *  027
+ */
+static const uint8_t Font12_27[] = {
+	6, 12,
+	1, 12,
+	0x00, //       
+	0x00, //       
+	0xC0, // ##    
+	0x30, //   ##  
+	0x08, //     # 
+	0x30, //   ##  
+	0xC0, // ##    
+	0xF8, // ##### 
+	0x00, //       
+	0xF8, // ##### 
+	0x00, //       
+	0x00  //       
+};
+
+/*
+ *  028
+ */
+static const uint8_t Font12_28[] = {
+	6, 12,
+	1, 12,
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0xF8, // ##### 
+	0x50, //  # #  
+	0x50, //  # #  
+	0x50, //  # #  
+	0x50, //  # #  
+	0x58, //  # ## 
+	0x80, // #     
+	0x00, //       
+	0x00  //       
+};
+
+/*
+ *  029
+ */
+static const uint8_t Font12_29[] = {
+	6, 12,
+	1, 12,
+	0x00, //       
+	0x08, //     # 
+	0x08, //     # 
+	0x10, //    #  
+	0xF8, // ##### 
+	0x20, //   #   
+	0xF8, // ##### 
+	0x40, //  #    
+	0x80, // #     
+	0x80, // #     
+	0x00, //       
+	0x00  //       
+};
+
+/*
+ *  030
+ */
+static const uint8_t Font12_30[] = {
+	6, 12,
+	1, 12,
+	0x00, //       
+	0x18, //    ## 
+	0x20, //   #   
+	0x20, //   #   
+	0xF8, // ##### 
+	0x20, //   #   
+	0x20, //   #   
+	0x20, //   #   
+	0x60, //  ##   
+	0xA4, // # #  #
+	0x58, //  # ## 
+	0x00  //       
+};
+
+/*
+ *  031
+ */
+static const uint8_t Font12_31[] = {
+	6, 12,
+	1, 12,
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0x20, //   #   
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0x00  //       
+};
+
+/*
+ *  SPACE
+ */
+static const uint8_t Font12_32[] = {
+	6, 12,
+	0, 0
+};
+
+/*
+ *  !
+ */
+static const uint8_t Font12_33[] = {
+	6, 12,
+	1, 12,
+	0x00, //       
+	0x20, //   #   
+	0x20, //   #   
+	0x20, //   #   
+	0x20, //   #   
+	0x20, //   #   
+	0x20, //   #   
+	0x20, //   #   
+	0x20, //   #   
+	0x00, //       
+	0x20, //   #   
+	0x00, //       
+	0x00  //       
+};
+
+/*
+ *  '!'
+ */
+static const uint8_t Font12_34[] = {
+	6, 12,
+	1, 12,
+	0x00, //       
+	0x50, //  # #  
+	0x50, //  # #  
+	0x50, //  # #  
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0x00  //       
+};
+
+/*
+ *  '#'
+ */
+static const uint8_t Font12_35[] = {
+	6, 12,
+	1, 12,
+	0x00, //       
+	0x50, //  # #  
+	0x50, //  # #  
+	0xF8, // ##### 
+	0x50, //  # #  
+	0x50, //  # #  
+	0x50, //  # #  
+	0xF8, // ##### 
+	0x50, //  # #  
+	0x50, //  # #  
+	0x00, //       
+	0x00  //       
+};
+
+/*
+ *  '$'
+ */
+static const uint8_t Font12_36[] = {
+	6, 12,
+	1, 12,
+	0x00, //       
+	0x20, //   #   
+	0x70, //  ###  
+	0xA8, // # # # 
+	0xA8, // # # # 
+	0x60, //  ##   
+	0x30, //   ##  
+	0x28, //   # # 
+	0xA8, // # # # 
+	0x70, //  ###  
+	0x20, //   #   
+	0x00  //       
+};
+
+/*
+ *  '%'
+ */
+static const uint8_t Font12_37[] = {
+	6, 12,
+	1, 12,
+	0x00, //       
+	0x48, //  #  # 
+	0xA8, // # # # 
+	0x50, //  # #  
+	0x10, //    #  
+	0x20, //   #   
+	0x20, //   #   
+	0x50, //  # #  
+	0x68, //  ## # 
+	0x90, // #  #  
+	0x80, // #     
+	0x00  //       
+};
+
+/*
+ *  '&'
+ */
+static const uint8_t Font12_38[] = {
+	6, 12,
+	1, 12,
+	0x00, //       
+	0x60, //  ##   
+	0x90, // #  #  
+	0x90, // #  #  
+	0x60, //  ##   
+	0x40, //  #    
+	0xA8, // # # # 
+	0x90, // #  #  
+	0x90, // #  #  
+	0x68, //  ## # 
+	0x00, //       
+	0x00  //       
+};
+
+/*
+ *  '''
+ */
+static const uint8_t Font12_39[] = {
+	6, 12,
+	1, 12,
+	0x00, //       
+	0x30, //   ##  
+	0x10, //    #  
+	0x20, //   #   
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0x00  //       
+};
+
+/*
+ *  '('
+ */
+static const uint8_t Font12_40[] = {
+	6, 12,
+	1, 12,
+	0x00, //       
+	0x08, //     # 
+	0x10, //    #  
+	0x10, //    #  
+	0x20, //   #   
+	0x20, //   #   
+	0x20, //   #   
+	0x20, //   #   
+	0x10, //    #  
+	0x10, //    #  
+	0x08, //     # 
+	0x00  //       
+};
+
+/*
+ *  ')'
+ */
+static const uint8_t Font12_41[] = {
+	6, 12,
+	1, 12,
+	0x00, //       
+	0x80, // #     
+	0x40, //  #    
+	0x40, //  #    
+	0x20, //   #   
+	0x20, //   #   
+	0x20, //   #   
+	0x20, //   #   
+	0x40, //  #    
+	0x40, //  #    
+	0x80, // #     
+	0x00  //       
+};
+
+/*
+ *  '*'
+ */
+static const uint8_t Font12_42[] = {
+	6, 12,
+	1, 12,
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0x20, //   #   
+	0xA8, // # # # 
+	0x70, //  ###  
+	0xA8, // # # # 
+	0x20, //   #   
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0x00  //       
+};
+
+/*
+ *  '+'
+ */
+static const uint8_t Font12_43[] = {
+	6, 12,
+	1, 12,
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0x20, //   #   
+	0x20, //   #   
+	0xF8, // ##### 
+	0x20, //   #   
+	0x20, //   #   
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0x00  //       
+};
+
+/*
+ *  ','
+ */
+static const uint8_t Font12_44[] = {
+	6, 12,
+	1, 12,
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0x20, //   #   
+	0x20, //   #   
+	0x40, //  #    
+	0x00  //       
+};
+
+/*
+ *  '-'
+ */
+static const uint8_t Font12_45[] = {
+	6, 12,
+	1, 12,
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0xF8, // ##### 
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0x00  //       
+};
+
+/*
+ *  '.'
+ */
+static const uint8_t Font12_46[] = {
+	5, 12,
+	1, 12,
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0x20, //   #   
+	0x00, //       
+	0x00, //       
+	0x00  //       
+};
+
+/*
+ *  '/'
+ */
+static const uint8_t Font12_47[] = {
+	6, 12,
+	1, 12,
+	0x00, //       
+	0x08, //     # 
+	0x08, //     # 
+	0x10, //    #  
+	0x10, //    #  
+	0x20, //   #   
+	0x20, //   #   
+	0x40, //  #    
+	0x40, //  #    
+	0x80, // #     
+	0x80, // #     
+	0x00  //       
+};
+
+/*
+ *  '0'
+ */
+static const uint8_t Font12_48[] = {
+	6, 12,
+	1, 12,
+	0x00, //       
+	0x30, //   ##  
+	0x48, //  #  # 
+	0x48, //  #  # 
+	0x48, //  #  # 
+	0x48, //  #  # 
+	0x48, //  #  # 
+	0x48, //  #  # 
+	0x48, //  #  # 
+	0x30, //   ##  
+	0x00, //       
+	0x00  //       
+};
+
+/*
+ *  '1'
+ */
+static const uint8_t Font12_49[] = {
+	6, 12,
+	1, 12,
+	0x00, //       
+	0x20, //   #   
+	0xE0, // ###   
+	0x20, //   #   
+	0x20, //   #   
+	0x20, //   #   
+	0x20, //   #   
+	0x20, //   #   
+	0x20, //   #   
+	0x20, //   #   
+	0x00, //       
+	0x00  //       
+};
+
+/*
+ *  '2'
+ */
+static const uint8_t Font12_50[] = {
+	6, 12,
+	1, 12,
+	0x00, //       
+	0x70, //  ###  
+	0x88, // #   # 
+	0x88, // #   # 
+	0x08, //     # 
+	0x10, //    #  
+	0x20, //   #   
+	0x40, //  #    
+	0x80, // #     
+	0xF8, // ##### 
+	0x00, //       
+	0x00  //       
+};
+
+/*
+ *  '3'
+ */
+static const uint8_t Font12_51[] = {
+	6, 12,
+	1, 12,
+	0x00, //       
+	0x70, //  ###  
+	0x88, // #   # 
+	0x08, //     # 
+	0x30, //   ##  
+	0x08, //     # 
+	0x08, //     # 
+	0x88, // #   # 
+	0x88, // #   # 
+	0x70, //  ###  
+	0x00, //       
+	0x00  //       
+};
+
+/*
+ *  '4'
+ */
+static const uint8_t Font12_52[] = {
+	6, 12,
+	1, 12,
+	0x00, //       
+	0x10, //    #  
+	0x30, //   ##  
+	0x30, //   ##  
+	0x50, //  # #  
+	0x50, //  # #  
+	0x90, // #  #  
+	0xF8, // ##### 
+	0x10, //    #  
+	0x10, //    #  
+	0x00, //       
+	0x00  //       
+};
+
+/*
+ *  '5'
+ */
+static const uint8_t Font12_53[] = {
+	6, 12,
+	1, 12,
+	0x00, //       
+	0xF0, // ####  
+	0x80, // #     
+	0x80, // #     
+	0xF0, // ####  
+	0x88, // #   # 
+	0x08, //     # 
+	0x08, //     # 
+	0x88, // #   # 
+	0x70, //  ###  
+	0x00, //       
+	0x00  //       
+};
+
+/*
+ *  '6'
+ */
+static const uint8_t Font12_54[] = {
+	6, 12,
+	1, 12,
+	0x00, //       
+	0x30, //   ##  
+	0x40, //  #    
+	0x80, // #     
+	0xF0, // ####  
+	0x88, // #   # 
+	0x88, // #   # 
+	0x88, // #   # 
+	0x88, // #   # 
+	0x70, //  ###  
+	0x00, //       
+	0x00  //       
+};
+
+/*
+ *  '7'
+ */
+static const uint8_t Font12_55[] = {
+	6, 12,
+	1, 12,
+	0x00, //       
+	0xF8, // ##### 
+	0x08, //     # 
+	0x10, //    #  
+	0x10, //    #  
+	0x10, //    #  
+	0x20, //   #   
+	0x20, //   #   
+	0x20, //   #   
+	0x20, //   #   
+	0x00, //       
+	0x00  //       
+};
+
+/*
+ *  '8'
+ */
+static const uint8_t Font12_56[] = {
+	6, 12,
+	1, 12,
+	0x00, //       
+	0x70, //  ###  
+	0x88, // #   # 
+	0x88, // #   # 
+	0x70, //  ###  
+	0x88, // #   # 
+	0x88, // #   # 
+	0x88, // #   # 
+	0x88, // #   # 
+	0x70, //  ###  
+	0x00, //       
+	0x00  //       
+};
+
+/*
+ *  '9'
+ */
+static const uint8_t Font12_57[] = {
+	6, 12,
+	1, 12,
+	0x00, //       
+	0x70, //  ###  
+	0x88, // #   # 
+	0x88, // #   # 
+	0x88, // #   # 
+	0x78, //  #### 
+	0x08, //     # 
+	0x08, //     # 
+	0x10, //    #  
+	0x60, //  ##   
+	0x00, //       
+	0x00  //       
+};
+
+/*
+ *  ':'
+ */
+static const uint8_t Font12_58[] = {
+	5, 12,
+	1, 12,
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0x20, //   #   
+	0x00, //       
+	0x00, //       
+	0x20, //   #   
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0x00  //       
+};
+
+/*
+ *  ';'
+ */
+static const uint8_t Font12_59[] = {
+	5, 12,
+	1, 12,
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0x20, //   #   
+	0x00, //       
+	0x00, //       
+	0x20, //   #   
+	0x20, //   #   
+	0x40, //  #    
+	0x00, //       
+	0x00, //       
+	0x00  //       
+};
+
+/*
+ *  '<'
+ */
+static const uint8_t Font12_60[] = {
+	6, 12,
+	1, 12,
+	0x00, //       
+	0x00, //       
+	0x08, //     # 
+	0x10, //    #  
+	0x20, //   #   
+	0x40, //  #    
+	0x20, //   #   
+	0x10, //    #  
+	0x08, //     # 
+	0x00, //       
+	0x00, //       
+	0x00  //       
+};
+
+/*
+ *  '='
+ */
+static const uint8_t Font12_61[] = {
+	6, 12,
+	1, 12,
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0xF8, // ##### 
+	0x00, //       
+	0xF8, // ##### 
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0x00  //       
+};
+
+/*
+ *  '>'
+ */
+static const uint8_t Font12_62[] = {
+	6, 12,
+	1, 12,
+	0x00, //       
+	0x00, //       
+	0x40, //  #    
+	0x20, //   #   
+	0x10, //    #  
+	0x08, //     # 
+	0x10, //    #  
+	0x20, //   #   
+	0x40, //  #    
+	0x00, //       
+	0x00, //       
+	0x00  //       
+};
+
+/*
+ *  '?'
+ */
+static const uint8_t Font12_63[] = {
+	6, 12,
+	1, 12,
+	0x00, //       
+	0x70, //  ###  
+	0x88, // #   # 
+	0x88, // #   # 
+	0x10, //    #  
+	0x10, //    #  
+	0x20, //   #   
+	0x20, //   #   
+	0x00, //       
+	0x20, //   #   
+	0x00, //       
+	0x00  //       
+};
+
+/*
+ *  '@'
+ */
+static const uint8_t Font12_64[] = {
+	6, 12,
+	1, 12,
+	0x00, //       
+	0x70, //  ###  
+	0x88, // #   # 
+	0x98, // #  ## 
+	0xA8, // # # # 
+	0xA8, // # # # 
+	0xA8, // # # # 
+	0x90, // #  #  
+	0x88, // #   # 
+	0x70, //  ###  
+	0x00, //       
+	0x00  //       
+};
+
+/*
+ *  'A'
+ */
+static const uint8_t Font12_65[] = {
+	6, 12,
+	1, 12,
+	0x00, //       
+	0x20, //   #   
+	0x20, //   #   
+	0x50, //  # #  
+	0x50, //  # #  
+	0x50, //  # #  
+	0xF8, // ##### 
+	0x88, // #   # 
+	0x88, // #   # 
+	0x88, // #   # 
+	0x00, //       
+	0x00  //       
+};
+
+/*
+ *  'B'
+ */
+static const uint8_t Font12_66[] = {
+	6, 12,
+	1, 12,
+	0x00, //       
+	0xF0, // ####  
+	0x88, // #   # 
+	0x88, // #   # 
+	0x90, // #  #  
+	0xF0, // ####  
+	0x88, // #   # 
+	0x88, // #   # 
+	0x88, // #   # 
+	0xF0, // ####  
+	0x00, //       
+	0x00  //       
+};
+
+/*
+ *  'C'
+ */
+static const uint8_t Font12_67[] = {
+	6, 12,
+	1, 12,
+	0x00, //       
+	0x30, //   ##  
+	0x48, //  #  # 
+	0x88, // #   # 
+	0x80, // #     
+	0x80, // #     
+	0x80, // #     
+	0x88, // #   # 
+	0x48, //  #  # 
+	0x30, //   ##  
+	0x00, //       
+	0x00  //       
+};
+
+/*
+ *  'D'
+ */
+static const uint8_t Font12_68[] = {
+	6, 12,
+	1, 12,
+	0x00, //       
+	0xE0, // ###   
+	0x90, // #  #  
+	0x88, // #   # 
+	0x88, // #   # 
+	0x88, // #   # 
+	0x88, // #   # 
+	0x88, // #   # 
+	0x90, // #  #  
+	0xE0, // ###   
+	0x00, //       
+	0x00  //       
+};
+
+/*
+ *  'E'
+ */
+static const uint8_t Font12_69[] = {
+	6, 12,
+	1, 12,
+	0x00, //       
+	0xF8, // ##### 
+	0x80, // #     
+	0x80, // #     
+	0x80, // #     
+	0xF0, // ####  
+	0x80, // #     
+	0x80, // #     
+	0x80, // #     
+	0xF8, // ##### 
+	0x00, //       
+	0x00  //       
+};
+
+/*
+ *  'F'
+ */
+static const uint8_t Font12_70[] = {
+	6, 12,
+	1, 12,
+	0x00, //       
+	0xF8, // ##### 
+	0x80, // #     
+	0x80, // #     
+	0x80, // #     
+	0xF0, // ####  
+	0x80, // #     
+	0x80, // #     
+	0x80, // #     
+	0x80, // #     
+	0x00, //       
+	0x00  //       
+};
+
+/*
+ *  'G'
+ */
+static const uint8_t Font12_71[] = {
+	6, 12,
+	1, 12,
+	0x00, //       
+	0x30, //   ##  
+	0x48, //  #  # 
+	0x80, // #     
+	0x80, // #     
+	0xB8, // # ### 
+	0x88, // #   # 
+	0x88, // #   # 
+	0x48, //  #  # 
+	0x38, //   ### 
+	0x00, //       
+	0x00  //       
+};
+
+/*
+ *  'H'
+ */
+static const uint8_t Font12_72[] = {
+	6, 12,
+	1, 12,
+	0x00, //       
+	0x88, // #   # 
+	0x88, // #   # 
+	0x88, // #   # 
+	0x88, // #   # 
+	0xF8, // ##### 
+	0x88, // #   # 
+	0x88, // #   # 
+	0x88, // #   # 
+	0x88, // #   # 
+	0x00, //       
+	0x00  //       
+};
+
+/*
+ *  'I'
+ */
+static const uint8_t Font12_73[] = {
+	5, 12,
+	1, 12,
+	0x00, //       
+	0x70, //  ###  
+	0x20, //   #   
+	0x20, //   #   
+	0x20, //   #   
+	0x20, //   #   
+	0x20, //   #   
+	0x20, //   #   
+	0x20, //   #   
+	0x70, //  ###  
+	0x00, //       
+	0x00  //       
+};
+
+/*
+ *  'J'
+ */
+static const uint8_t Font12_74[] = {
+	6, 12,
+	1, 12,
+	0x00, //       
+	0x10, //    #  
+	0x10, //    #  
+	0x10, //    #  
+	0x10, //    #  
+	0x10, //    #  
+	0x10, //    #  
+	0x90, // #  #  
+	0x90, // #  #  
+	0x60, //  ##   
+	0x00, //       
+	0x00  //       
+};
+
+/*
+ *  'K'
+ */
+static const uint8_t Font12_75[] = {
+	6, 12,
+	1, 12,
+	0x00, //       
+	0x88, // #   # 
+	0x90, // #  #  
+	0xA0, // # #   
+	0xC0, // ##    
+	0xA0, // # #   
+	0xA0, // # #   
+	0x90, // #  #  
+	0x90, // #  #  
+	0x88, // #   # 
+	0x00, //       
+	0x00  //       
+};
+
+/*
+ *  'L'
+ */
+static const uint8_t Font12_76[] = {
+	6, 12,
+	1, 12,
+	0x00, //       
+	0x80, // #     
+	0x80, // #     
+	0x80, // #     
+	0x80, // #     
+	0x80, // #     
+	0x80, // #     
+	0x80, // #     
+	0x80, // #     
+	0xF8, // ##### 
+	0x00, //       
+	0x00  //       
+};
+
+/*
+ *  'M'
+ */
+static const uint8_t Font12_77[] = {
+	6, 12,
+	1, 12,
+	0x00, //       
+	0x88, // #   # 
+	0x88, // #   # 
+	0xD8, // ## ## 
+	0xD8, // ## ## 
+	0xD8, // ## ## 
+	0xA8, // # # # 
+	0xA8, // # # # 
+	0xA8, // # # # 
+	0x88, // #   # 
+	0x00, //       
+	0x00  //       
+};
+
+/*
+ *  'N'
+ */
+static const uint8_t Font12_78[] = {
+	6, 12,
+	1, 12,
+	0x00, //       
+	0x88, // #   # 
+	0xC8, // ##  # 
+	0xC8, // ##  # 
+	0xA8, // # # # 
+	0xA8, // # # # 
+	0x98, // #  ## 
+	0x98, // #  ## 
+	0x88, // #   # 
+	0x88, // #   # 
+	0x00, //       
+	0x00  //       
+};
+
+/*
+ *  'O'
+ */
+static const uint8_t Font12_79[] = {
+	6, 12,
+	1, 12,
+	0x00, //       
+	0x70, //  ###  
+	0x88, // #   # 
+	0x88, // #   # 
+	0x88, // #   # 
+	0x88, // #   # 
+	0x88, // #   # 
+	0x88, // #   # 
+	0x88, // #   # 
+	0x70, //  ###  
+	0x00, //       
+	0x00  //       
+};
+
+/*
+ *  'P'
+ */
+static const uint8_t Font12_80[] = {
+	6, 12,
+	1, 12,
+	0x00, //       
+	0xF0, // ####  
+	0x88, // #   # 
+	0x88, // #   # 
+	0x88, // #   # 
+	0xF0, // ####  
+	0x80, // #     
+	0x80, // #     
+	0x80, // #     
+	0x80, // #     
+	0x00, //       
+	0x00  //       
+};
+
+/*
+ *  'Q'
+ */
+static const uint8_t Font12_81[] = {
+	6, 12,
+	1, 12,
+	0x00, //       
+	0x70, //  ###  
+	0x88, // #   # 
+	0x88, // #   # 
+	0x88, // #   # 
+	0x88, // #   # 
+	0x88, // #   # 
+	0xA8, // # # # 
+	0x90, // #  #  
+	0x68, //  ## # 
+	0x00, //       
+	0x00  //       
+};
+
+/*
+ *  'R'
+ */
+static const uint8_t Font12_82[] = {
+	6, 12,
+	1, 12,
+	0x00, //       
+	0xF0, // ####  
+	0x88, // #   # 
+	0x88, // #   # 
+	0x88, // #   # 
+	0xF0, // ####  
+	0x90, // #  #  
+	0x88, // #   # 
+	0x88, // #   # 
+	0x88, // #   # 
+	0x00, //       
+	0x00  //       
+};
+
+/*
+ *  'S'
+ */
+static const uint8_t Font12_83[] = {
+	6, 12,
+	1, 12,
+	0x00, //       
+	0x70, //  ###  
+	0x88, // #   # 
+	0x80, // #     
+	0x60, //  ##   
+	0x10, //    #  
+	0x08, //     # 
+	0x88, // #   # 
+	0x88, // #   # 
+	0x70, //  ###  
+	0x00, //       
+	0x00  //       
+};
+
+/*
+ *  'T'
+ */
+static const uint8_t Font12_84[] = {
+	6, 12,
+	1, 12,
+	0x00, //       
+	0xF8, // ##### 
+	0x20, //   #   
+	0x20, //   #   
+	0x20, //   #   
+	0x20, //   #   
+	0x20, //   #   
+	0x20, //   #   
+	0x20, //   #   
+	0x20, //   #   
+	0x00, //       
+	0x00  //       
+};
+
+/*
+ *  'U'
+ */
+static const uint8_t Font12_85[] = {
+	6, 12,
+	1, 12,
+	0x00, //       
+	0x88, // #   # 
+	0x88, // #   # 
+	0x88, // #   # 
+	0x88, // #   # 
+	0x88, // #   # 
+	0x88, // #   # 
+	0x88, // #   # 
+	0x88, // #   # 
+	0x70, //  ###  
+	0x00, //       
+	0x00  //       
+};
+
+/*
+ *  'V'
+ */
+static const uint8_t Font12_86[] = {
+	6, 12,
+	1, 12,
+	0x00, //       
+	0x88, // #   # 
+	0x88, // #   # 
+	0x88, // #   # 
+	0x88, // #   # 
+	0x50, //  # #  
+	0x50, //  # #  
+	0x50, //  # #  
+	0x20, //   #   
+	0x20, //   #   
+	0x00, //       
+	0x00  //       
+};
+
+/*
+ *  'W'
+ */
+static const uint8_t Font12_87[] = {
+	6, 12,
+	1, 12,
+	0x00, //       
+	0xA8, // # # # 
+	0xA8, // # # # 
+	0xA8, // # # # 
+	0xA8, // # # # 
+	0xA8, // # # # 
+	0xA8, // # # # 
+	0x50, //  # #  
+	0x50, //  # #  
+	0x50, //  # #  
+	0x00, //       
+	0x00  //       
+};
+
+/*
+ *  'X'
+ */
+static const uint8_t Font12_88[] = {
+	6, 12,
+	1, 12,
+	0x00, //       
+	0x88, // #   # 
+	0x88, // #   # 
+	0x50, //  # #  
+	0x50, //  # #  
+	0x20, //   #   
+	0x50, //  # #  
+	0x50, //  # #  
+	0x88, // #   # 
+	0x88, // #   # 
+	0x00, //       
+	0x00  //       
+};
+
+/*
+ *  'Y'
+ */
+static const uint8_t Font12_89[] = {
+	6, 12,
+	1, 12,
+	0x00, //       
+	0x88, // #   # 
+	0x88, // #   # 
+	0x50, //  # #  
+	0x50, //  # #  
+	0x20, //   #   
+	0x20, //   #   
+	0x20, //   #   
+	0x20, //   #   
+	0x20, //   #   
+	0x00, //       
+	0x00  //       
+};
+
+/*
+ *  'Z'
+ */
+static const uint8_t Font12_90[] = {
+	6, 12,
+	1, 12,
+	0x00, //       
+	0xF8, // ##### 
+	0x08, //     # 
+	0x10, //    #  
+	0x10, //    #  
+	0x20, //   #   
+	0x40, //  #    
+	0x40, //  #    
+	0x80, // #     
+	0xF8, // ##### 
+	0x00, //       
+	0x00  //       
+};
+
+/*
+ *  '['
+ */
+static const uint8_t Font12_91[] = {
+	5, 12,
+	1, 12,
+	0x00, //       
+	0x38, //   ### 
+	0x20, //   #   
+	0x20, //   #   
+	0x20, //   #   
+	0x20, //   #   
+	0x20, //   #   
+	0x20, //   #   
+	0x20, //   #   
+	0x20, //   #   
+	0x20, //   #   
+	0x38  //   ### 
+};
+
+/*
+ *  '\'
+ */
+static const uint8_t Font12_92[] = {
+	6, 12,
+	1, 12,
+	0x00, //       
+	0x80, // #     
+	0x80, // #     
+	0x40, //  #    
+	0x40, //  #    
+	0x20, //   #   
+	0x20, //   #   
+	0x10, //    #  
+	0x10, //    #  
+	0x08, //     # 
+	0x08, //     # 
+	0x00  //       
+};
+
+/*
+ *  ']'
+ */
+static const uint8_t Font12_93[] = {
+	5, 12,
+	1, 12,
+	0x00, //       
+	0x70, //  ###  
+	0x10, //    #  
+	0x10, //    #  
+	0x10, //    #  
+	0x10, //    #  
+	0x10, //    #  
+	0x10, //    #  
+	0x10, //    #  
+	0x10, //    #  
+	0x10, //    #  
+	0x70  //  ###  
+};
+
+/*
+ *  '^'
+ */
+static const uint8_t Font12_94[] = {
+	6, 12,
+	1, 12,
+	0x00, //       
+	0x20, //   #   
+	0x50, //  # #  
+	0x88, // #   # 
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0x00  //       
+};
+
+/*
+ *  '_'
+ */
+static const uint8_t Font12_95[] = {
+	6, 12,
+	1, 12,
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0xF8, // ##### 
+	0x00, //       
+	0x00  //       
+};
+
+/*
+ *  '''
+ */
+static const uint8_t Font12_96[] = {
+	5, 12,
+	1, 12,
+	0x00, //       
+	0x30, //   ##  
+	0x20, //   #   
+	0x10, //    #  
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0x00  //       
+};
+
+/*
+ *  'a'
+ */
+static const uint8_t Font12_97[] = {
+	6, 12,
+	1, 12,
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0x70, //  ###  
+	0x88, // #   # 
+	0x18, //    ## 
+	0x68, //  ## # 
+	0x88, // #   # 
+	0x98, // #  ## 
+	0x68, //  ## # 
+	0x00, //       
+	0x00  //       
+};
+
+/*
+ *  'b'
+ */
+static const uint8_t Font12_98[] = {
+	6, 12,
+	1, 12,
+	0x00, //       
+	0x80, // #     
+	0x80, // #     
+	0xB0, // # ##  
+	0xC8, // ##  # 
+	0x88, // #   # 
+	0x88, // #   # 
+	0x88, // #   # 
+	0xC8, // ##  # 
+	0xB0, // # ##  
+	0x00, //       
+	0x00  //       
+};
+
+/*
+ *  'c'
+ */
+static const uint8_t Font12_99[] = {
+	6, 12,
+	1, 12,
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0x70, //  ###  
+	0x88, // #   # 
+	0x80, // #     
+	0x80, // #     
+	0x80, // #     
+	0x88, // #   # 
+	0x70, //  ###  
+	0x00, //       
+	0x00  //       
+};
+
+/*
+ *  'd'
+ */
+static const uint8_t Font12_100[] = {
+	6, 12,
+	1, 12,
+	0x00, //       
+	0x08, //     # 
+	0x08, //     # 
+	0x68, //  ## # 
+	0x98, // #  ## 
+	0x88, // #   # 
+	0x88, // #   # 
+	0x88, // #   # 
+	0x98, // #  ## 
+	0x68, //  ## # 
+	0x00, //       
+	0x00  //       
+};
+
+/*
+ *  'e'
+ */
+static const uint8_t Font12_101[] = {
+	6, 12,
+	1, 12,
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0x70, //  ###  
+	0x88, // #   # 
+	0x88, // #   # 
+	0xF8, // ##### 
+	0x80, // #     
+	0x88, // #   # 
+	0x70, //  ###  
+	0x00, //       
+	0x00  //       
+};
+
+/*
+ *  'f'
+ */
+static const uint8_t Font12_102[] = {
+	6, 12,
+	1, 12,
+	0x00, //       
+	0x18, //    ## 
+	0x20, //   #   
+	0x70, //  ###  
+	0x20, //   #   
+	0x20, //   #   
+	0x20, //   #   
+	0x20, //   #   
+	0x20, //   #   
+	0x20, //   #   
+	0x00, //       
+	0x00  //       
+};
+
+/*
+ *  'g'
+ */
+static const uint8_t Font12_103[] = {
+	6, 12,
+	1, 12,
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0x78, //  #### 
+	0x88, // #   # 
+	0x88, // #   # 
+	0x88, // #   # 
+	0x98, // #  ## 
+	0x68, //  ## # 
+	0x08, //     # 
+	0x88, // #   # 
+	0x70  //  ###  
+};
+
+/*
+ *  'h'
+ */
+static const uint8_t Font12_104[] = {
+	6, 12,
+	1, 12,
+	0x00, //       
+	0x80, // #     
+	0x80, // #     
+	0xB0, // # ##  
+	0xC8, // ##  # 
+	0x88, // #   # 
+	0x88, // #   # 
+	0x88, // #   # 
+	0x88, // #   # 
+	0x88, // #   # 
+	0x00, //       
+	0x00  //       
+};
+
+/*
+ *  'i'
+ */
+static const uint8_t Font12_105[] = {
+	5, 12,
+	1, 12,
+	0x00, //       
+	0x20, //   #   
+	0x00, //       
+	0x20, //   #   
+	0x20, //   #   
+	0x20, //   #   
+	0x20, //   #   
+	0x20, //   #   
+	0x20, //   #   
+	0x20, //   #   
+	0x00, //       
+	0x00  //       
+};
+
+/*
+ *  'j'
+ */
+static const uint8_t Font12_106[] = {
+	5, 12,
+	1, 12,
+	0x00, //       
+	0x20, //   #   
+	0x00, //       
+	0x20, //   #   
+	0x20, //   #   
+	0x20, //   #   
+	0x20, //   #   
+	0x20, //   #   
+	0x20, //   #   
+	0x20, //   #   
+	0x20, //   #   
+	0x40  //  #    
+};
+
+/*
+ *  'k'
+ */
+static const uint8_t Font12_107[] = {
+	5, 12,
+	1, 12,
+	0x00, //       
+	0x80, // #     
+	0x80, // #     
+	0x80, // #     
+	0x90, // #  #  
+	0xA0, // # #   
+	0xC0, // ##    
+	0xA0, // # #   
+	0x90, // #  #  
+	0x88, // #   # 
+	0x00, //       
+	0x00  //       
+};
+
+/*
+ *  'l'
+ */
+static const uint8_t Font12_108[] = {
+	5, 12,
+	1, 12,
+	0x00, //       
+	0x20, //   #   
+	0x20, //   #   
+	0x20, //   #   
+	0x20, //   #   
+	0x20, //   #   
+	0x20, //   #   
+	0x20, //   #   
+	0x20, //   #   
+	0x20, //   #   
+	0x00, //       
+	0x00  //       
+};
+
+/*
+ *  'm'
+ */
+static const uint8_t Font12_109[] = {
+	6, 12,
+	1, 12,
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0xF0, // ####  
+	0xA8, // # # # 
+	0xA8, // # # # 
+	0xA8, // # # # 
+	0xA8, // # # # 
+	0xA8, // # # # 
+	0xA8, // # # # 
+	0x00, //       
+	0x00  //       
+};
+
+/*
+ *  'n'
+ */
+static const uint8_t Font12_110[] = {
+	6, 12,
+	1, 12,
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0xB0, // # ##  
+	0xC8, // ##  # 
+	0x88, // #   # 
+	0x88, // #   # 
+	0x88, // #   # 
+	0x88, // #   # 
+	0x88, // #   # 
+	0x00, //       
+	0x00  //       
+};
+
+/*
+ *  'o'
+ */
+static const uint8_t Font12_111[] = {
+	6, 12,
+	1, 12,
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0x70, //  ###  
+	0x88, // #   # 
+	0x88, // #   # 
+	0x88, // #   # 
+	0x88, // #   # 
+	0x88, // #   # 
+	0x70, //  ###  
+	0x00, //       
+	0x00  //       
+};
+
+/*
+ *  'p'
+ */
+static const uint8_t Font12_112[] = {
+	6, 12,
+	1, 12,
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0xB0, // # ##  
+	0xC8, // ##  # 
+	0x88, // #   # 
+	0x88, // #   # 
+	0x88, // #   # 
+	0xC8, // ##  # 
+	0xB0, // # ##  
+	0x80, // #     
+	0x80  // #     
+};
+
+/*
+ *  'q'
+ */
+static const uint8_t Font12_113[] = {
+	6, 12,
+	1, 12,
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0x68, //  ## # 
+	0x98, // #  ## 
+	0x88, // #   # 
+	0x88, // #   # 
+	0x88, // #   # 
+	0x98, // #  ## 
+	0x68, //  ## # 
+	0x08, //     # 
+	0x08  //     # 
+};
+
+/*
+ *  'r'
+ */
+static const uint8_t Font12_114[] = {
+	6, 12,
+	1, 12,
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0x58, //  # ## 
+	0x60, //  ##   
+	0x40, //  #    
+	0x40, //  #    
+	0x40, //  #    
+	0x40, //  #    
+	0x40, //  #    
+	0x00, //       
+	0x00  //       
+};
+
+/*
+ *  's'
+ */
+static const uint8_t Font12_115[] = {
+	6, 12,
+	1, 12,
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0x70, //  ###  
+	0x88, // #   # 
+	0x40, //  #    
+	0x30, //   ##  
+	0x08, //     # 
+	0x88, // #   # 
+	0x70, //  ###  
+	0x00, //       
+	0x00  //       
+};
+
+/*
+ *  't'
+ */
+static const uint8_t Font12_116[] = {
+	6, 12,
+	1, 12,
+	0x00, //       
+	0x40, //  #    
+	0x40, //  #    
+	0xF0, // ####  
+	0x40, //  #    
+	0x40, //  #    
+	0x40, //  #    
+	0x40, //  #    
+	0x40, //  #    
+	0x60, //  ##   
+	0x00, //       
+	0x00  //       
+};
+
+/*
+ *  'u'
+ */
+static const uint8_t Font12_117[] = {
+	6, 12,
+	1, 12,
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0x88, // #   # 
+	0x88, // #   # 
+	0x88, // #   # 
+	0x88, // #   # 
+	0x88, // #   # 
+	0x98, // #  ## 
+	0x68, //  ## # 
+	0x00, //       
+	0x00  //       
+};
+
+/*
+ *  'v'
+ */
+static const uint8_t Font12_118[] = {
+	6, 12,
+	1, 12,
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0x88, // #   # 
+	0x88, // #   # 
+	0x88, // #   # 
+	0x50, //  # #  
+	0x50, //  # #  
+	0x20, //   #   
+	0x20, //   #   
+	0x00, //       
+	0x00  //       
+};
+
+/*
+ *  'w'
+ */
+static const uint8_t Font12_119[] = {
+	6, 12,
+	1, 12,
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0x88, // #   # 
+	0xA8, // # # # 
+	0xA8, // # # # 
+	0xA8, // # # # 
+	0xA8, // # # # 
+	0xA8, // # # # 
+	0x50, //  # #  
+	0x00, //       
+	0x00  //       
+};
+
+/*
+ *  'x'
+ */
+static const uint8_t Font12_120[] = {
+	6, 12,
+	1, 12,
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0x88, // #   # 
+	0x50, //  # #  
+	0x50, //  # #  
+	0x20, //   #   
+	0x50, //  # #  
+	0x50, //  # #  
+	0x88, // #   # 
+	0x00, //       
+	0x00  //       
+};
+
+/*
+ *  'y'
+ */
+static const uint8_t Font12_121[] = {
+	6, 12,
+	1, 12,
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0x88, // #   # 
+	0x88, // #   # 
+	0x48, //  #  # 
+	0x50, //  # #  
+	0x50, //  # #  
+	0x20, //   #   
+	0x20, //   #   
+	0x40, //  #    
+	0x80  // #     
+};
+
+/*
+ *  'z'
+ */
+static const uint8_t Font12_122[] = {
+	6, 12,
+	1, 12,
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0xF8, // ##### 
+	0x10, //    #  
+	0x10, //    #  
+	0x20, //   #   
+	0x40, //  #    
+	0x40, //  #    
+	0xF8, // ##### 
+	0x00, //       
+	0x00  //       
+};
+
+/*
+ *  '{'
+ */
+static const uint8_t Font12_123[] = {
+	5, 12,
+	1, 12,
+	0x00, //       
+	0x08, //     # 
+	0x10, //    #  
+	0x10, //    #  
+	0x10, //    #  
+	0x10, //    #  
+	0x20, //   #   
+	0x10, //    #  
+	0x10, //    #  
+	0x10, //    #  
+	0x10, //    #  
+	0x08  //     # 
+};
+
+/*
+ *  '|'
+ */
+static const uint8_t Font12_124[] = {
+	5, 12,
+	1, 12,
+	0x00, //       
+	0x20, //   #   
+	0x20, //   #   
+	0x20, //   #   
+	0x20, //   #   
+	0x20, //   #   
+	0x20, //   #   
+	0x20, //   #   
+	0x20, //   #   
+	0x20, //   #   
+	0x20, //   #   
+	0x20  //   #   
+};
+
+/*
+ *  '}'
+ */
+static const uint8_t Font12_125[] = {
+	5, 12,
+	1, 12,
+	0x00, //       
+	0x40, //  #    
+	0x20, //   #   
+	0x20, //   #   
+	0x20, //   #   
+	0x20, //   #   
+	0x10, //    #  
+	0x20, //   #   
+	0x20, //   #   
+	0x20, //   #   
+	0x20, //   #   
+	0x40  //  #    
+};
+
+/*
+ *  '->'
+ */
+static const uint8_t Font12_126[] = {
+	6, 12,
+	1, 12,
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0x48, //  #  # 
+	0xB0, // # ##  
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0x00  //       
+};
+
+/*
+ *  DEL
+ */
+static const uint8_t Font12_127[] = {
+	6, 12,
+	1, 12,
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0x00  //       
+};
+
+/*
+ *  yohaku
+ */
+static const uint8_t Font12_160[] = {
+	6, 12,
+	1, 12,
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0x00  //       
+};
+
+/*
+ *  syuryou
+ */
+static const uint8_t Font12_161[] = {
+	6, 12,
+	1, 12,
+	0x00, //       
+	0x20, //   #   
+	0x00, //       
+	0x20, //   #   
+	0x20, //   #   
+	0x20, //   #   
+	0x20, //   #   
+	0x20, //   #   
+	0x20, //   #   
+	0x20, //   #   
+	0x00, //       
+	0x00  //       
+};
+
+/*
+ *  kakko
+ */
+static const uint8_t Font12_162[] = {
+	6, 12,
+	1, 12,
+	0x00, //       
+	0x00, //       
+	0x10, //    #  
+	0x70, //  ###  
+	0x98, // #  ## 
+	0xA0, // # #   
+	0xA0, // # #   
+	0xA0, // # #   
+	0xC8, // ##  # 
+	0x70, //  ###  
+	0x40, //  #    
+	0x00  //       
+};
+
+/*
+ *  kakko tojiru
+ */
+static const uint8_t Font12_163[] = {
+	6, 12,
+	1, 12,
+	0x00, //       
+	0x10, //    #  
+	0x28, //   # # 
+	0x20, //   #   
+	0x78, //  #### 
+	0x20, //   #   
+	0x20, //   #   
+	0x20, //   #   
+	0x68, //  ## # 
+	0xA8, // # # # 
+	0x50, //  # #  
+	0x00  //       
+};
+
+/*
+ *  kutouten
+ */
+static const uint8_t Font12_164[] = {
+	6, 12,
+	1, 12,
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0x88, // #   # 
+	0x70, //  ###  
+	0x50, //  # #  
+	0x70, //  ###  
+	0x88, // #   # 
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0x00  //       
+};
+
+/*
+ *  cyuten
+ */
+static const uint8_t Font12_165[] = {
+	6, 12,
+	1, 12,
+	0x00, //       
+	0x88, // #   # 
+	0x88, // #   # 
+	0x50, //  # #  
+	0xF8, // ##### 
+	0x20, //   #   
+	0xF8, // ##### 
+	0x20, //   #   
+	0x20, //   #   
+	0x20, //   #   
+	0x00, //       
+	0x00  //       
+};
+
+/*
+ *  'WO'
+ */
+static const uint8_t Font12_166[] = {
+	6, 12,
+	1, 12,
+	0x00, //       
+	0x20, //   #   
+	0x20, //   #   
+	0x20, //   #   
+	0x20, //   #   
+	0x00, //       
+	0x00, //       
+	0x20, //   #   
+	0x20, //   #   
+	0x20, //   #   
+	0x20, //   #   
+	0x00  //       
+};
+
+/*
+ *  'aa'
+ */
+static const uint8_t Font12_167[] = {
+	6, 12,
+	1, 12,
+	0x00, //       
+	0x30, //   ##  
+	0x48, //  #  # 
+	0x40, //  #    
+	0x30, //   ##  
+	0x48, //  #  # 
+	0x30, //   ##  
+	0x08, //     # 
+	0x48, //  #  # 
+	0x48, //  #  # 
+	0x30, //   ##  
+	0x00  //       
+};
+
+/*
+ *  'ii'
+ */
+static const uint8_t Font12_168[] = {
+	6, 12,
+	1, 12,
+	0x00, //       
+	0x50, //  # #  
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0x00  //       
+};
+
+/*
+ *  'uu'
+ */
+static const uint8_t Font12_169[] = {
+	6, 12,
+	1, 12,
+	0x00, //       
+	0x70, //  ###  
+	0x88, // #   # 
+	0xB8, // # ### 
+	0xC8, // ##  # 
+	0xC8, // ##  # 
+	0xB8, // # ### 
+	0x88, // #   # 
+	0x70, //  ###  
+	0x00, //       
+	0x00, //       
+	0x00  //       
+};
+
+/*
+ *  'ee'
+ */
+static const uint8_t Font12_170[] = {
+	6, 12,
+	1, 12,
+	0x00, //       
+	0x60, //  ##   
+	0xA0, // # #   
+	0xA0, // # #   
+	0x50, //  # #  
+	0x00, //       
+	0xF0, // ####  
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0x00  //       
+};
+
+/*
+ *  'oo'
+ */
+static const uint8_t Font12_171[] = {
+	6, 12,
+	1, 12,
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0x28, //   # # 
+	0x50, //  # #  
+	0xA0, // # #   
+	0x50, //  # #  
+	0x28, //   # # 
+	0x00, //       
+	0x00, //       
+	0x00  //       
+};
+
+/*
+ *  'ya'
+ */
+static const uint8_t Font12_172[] = {
+	6, 12,
+	1, 12,
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0xF8, // ##### 
+	0x08, //     # 
+	0x08, //     # 
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0x00  //       
+};
+
+/*
+ *  'yu'
+ */
+static const uint8_t Font12_173[] = {
+	6, 12,
+	1, 12,
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0x70, //  ###  
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0x00, //       
+};
+
+/*
+ *  'yo'
+ */
+static const uint8_t Font12_174[] = {
+	6, 12,
+	1, 12,
+	0x00, //       
+	0x78, //  #### 
+	0x84, // #    #
+	0xB4, // # ## #
+	0xAC, // # # ##
+	0xB4, // # ## #
+	0xAC, // # # ##
+	0xAC, // # # ##
+	0x78, //  #### 
+	0x00, //       
+	0x00, //       
+	0x00  //       
+};
+
+
+/*
+ *  'tu'
+ */
+static const uint8_t Font12_175[] = {
+	6, 12,
+	1, 12,
+	0x00, //       
+	0x70, //  ###  
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0x00  //       
+};
+
+/*
+ *  '-'
+ */
+static const uint8_t Font12_176[] = {
+	6, 12,
+	1, 12,
+	0x30, //   ##  
+	0x48, //  #  # 
+	0x30, //   ##  
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0x00  //       
+};
+
+/*
+ *  'AA'
+ */
+static const uint8_t Font12_177[] = {
+	6, 12,
+	1, 12,
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0x20, //   #   
+	0x20, //   #   
+	0xF8, // ##### 
+	0x20, //   #   
+	0x20, //   #   
+	0xF8, // ##### 
+	0x00, //       
+	0x00, //       
+	0x00  //       
+};
+
+/*
+ *  'II'
+ */
+static const uint8_t Font12_178[] = {
+	6, 12,
+	1, 12,
+	0x40, //  #    
+	0xA0, // # #   
+	0x20, //   #   
+	0x40, //  #    
+	0xE0, // ###   
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0x00  //       
+};
+
+/*
+ *  'UU'
+ */
+static const uint8_t Font12_179[] = {
+	6, 12,
+	1, 12,
+	0xC0, // ##    
+	0x20, //   #   
+	0xC0, // ##    
+	0x20, //   #   
+	0xC0, // ##    
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0x00  //       
+};
+
+/*
+ *  'EE'
+ */
+static const uint8_t Font12_180[] = {
+	6, 12,
+	1, 12,
+	0x30, //   ##  
+	0x40, //  #    
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0x00  //       
+};
+
+/*
+ *  'OO'
+ */
+static const uint8_t Font12_181[] = {
+	6, 12,
+	1, 12,
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0x48, //  #  # 
+	0x48, //  #  # 
+	0x48, //  #  # 
+	0x48, //  #  # 
+	0x74, //  ### #
+	0x40, //  #    
+	0x40, //  #    
+	0x80  // #     
+};
+
+/*
+ *  'KA'
+ */
+static const uint8_t Font12_182[] = {
+	6, 12,
+	1, 12,
+	0x00, //       
+	0x38, //   ### 
+	0x68, //  ## # 
+	0x68, //  ## # 
+	0x28, //   # # 
+	0x28, //   # # 
+	0x28, //   # # 
+	0x28, //   # # 
+	0x28, //   # # 
+	0x28, //   # # 
+	0x28, //   # # 
+	0x00  //       
+};
+
+/*
+ *  'KI'
+ */
+static const uint8_t Font12_183[] = {
+	6, 12,
+	1, 12,
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0x30, //   ##  
+	0x30, //   ##  
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0x00  //       
+};
+
+/*
+ *  'KU'
+ */
+static const uint8_t Font12_184[] = {
+	6, 12,
+	1, 12,
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0x40, //  #    
+	0x60, //  ##   
+	0x10, //    #  
+	0x60  //  ##   
+};
+
+/*
+ *  'KE'
+ */
+static const uint8_t Font12_185[] = {
+	6, 12,
+	1, 12,
+	0x40, //  #    
+	0xC0, // ##    
+	0x40, //  #    
+	0x40, //  #    
+	0x40, //  #    
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0x00  //       
+};
+
+/*
+ *  'KO'
+ */
+static const uint8_t Font12_186[] = {
+	6, 12,
+	1, 12,
+	0x00, //       
+	0x60, //  ##   
+	0x90, // #  #  
+	0x90, // #  #  
+	0x60, //  ##   
+	0x00, //       
+	0xF0, // ####  
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0x00  //       
+};
+
+/*
+ *  'SA'
+ */
+static const uint8_t Font12_187[] = {
+	6, 12,
+	1, 12,
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0xA0, // # #   
+	0x50, //  # #  
+	0x28, //   # # 
+	0x50, //  # #  
+	0xA0, // # #   
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0x00  //       
+};
+
+/*
+ *  'SI'
+ */
+static const uint8_t Font12_188[] = {
+	6, 12,
+	1, 12,
+	0x80, // #     
+	0x90, // #  #  
+	0xA0, // # #   
+	0x50, //  # #  
+	0xB0, // # ##  
+	0x38, //   ### 
+	0x10, //    #  
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0x00  //       
+};
+
+/*
+ *  'SU'
+ */
+static const uint8_t Font12_189[] = {
+	6, 12,
+	1, 12,
+	0x80, // #     
+	0x90, // #  #  
+	0xA0, // # #   
+	0x58, //  # ## 
+	0x88, // #   # 
+	0x10, //    #  
+	0x38, //   ### 
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0x00  //       
+};
+
+/*
+ *  'SE'
+ */
+static const uint8_t Font12_190[] = {
+	6, 12,
+	1, 12,
+	0xC0, // ##    
+	0x20, //   #   
+	0xE0, // ###   
+	0x28, //   # # 
+	0xD8, // ## ## 
+	0x28, //   # # 
+	0x3C, //   ####
+	0x08, //     # 
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0x00  //       
+};
+
+/*
+ *  'SO'
+ */
+static const uint8_t Font12_191[] = {
+	6, 12,
+	1, 12,
+	0x00, //       
+	0x20, //   #   
+	0x00, //       
+	0x20, //   #   
+	0x20, //   #   
+	0x40, //  #    
+	0x40, //  #    
+	0x88, // #   # 
+	0x88, // #   # 
+	0x70, //  ###  
+	0x00, //       
+	0x00  //       
+};
+
+/*
+ *  'TA'
+ */
+static const uint8_t Font12_192[] = {
+	6, 12,
+	1, 12,
+	0x20, //   #   
+	0x10, //    #  
+	0x20, //   #   
+	0x20, //   #   
+	0x50, //  # #  
+	0x50, //  # #  
+	0x88, // #   # 
+	0xF8, // ##### 
+	0x88, // #   # 
+	0x88, // #   # 
+	0x00, //       
+	0x00  //       
+};
+
+/*
+ *  'TI'
+ */
+static const uint8_t Font12_193[] = {
+	6, 12,
+	1, 12,
+	0x20, //   #   
+	0x40, //  #    
+	0x20, //   #   
+	0x20, //   #   
+	0x50, //  # #  
+	0x50, //  # #  
+	0x88, // #   # 
+	0xF8, // ##### 
+	0x88, // #   # 
+	0x88, // #   # 
+	0x00, //       
+	0x00  //       
+};
+
+/*
+ *  'TU'
+ */
+static const uint8_t Font12_194[] = {
+	6, 12,
+	1, 12,
+	0x20, //   #   
+	0x50, //  # #  
+	0x20, //   #   
+	0x20, //   #   
+	0x50, //  # #  
+	0x50, //  # #  
+	0x88, // #   # 
+	0xF8, // ##### 
+	0x88, // #   # 
+	0x88, // #   # 
+	0x00, //       
+	0x00  //       
+};
+
+/*
+ *  'TE'
+ */
+static const uint8_t Font12_195[] = {
+	6, 12,
+	1, 12,
+	0x50, //  # #  
+	0xA0, // # #   
+	0x20, //   #   
+	0x20, //   #   
+	0x50, //  # #  
+	0x50, //  # #  
+	0x88, // #   # 
+	0xF8, // ##### 
+	0x88, // #   # 
+	0x88, // #   # 
+	0x00, //       
+	0x00  //       
+};
+
+/*
+ *  'TO'
+ */
+static const uint8_t Font12_196[] = {
+	6, 12,
+	1, 12,
+	0x50, //  # #  
+	0x00, //       
+	0x20, //   #   
+	0x20, //   #   
+	0x50, //  # #  
+	0x50, //  # #  
+	0x88, // #   # 
+	0xF8, // ##### 
+	0x88, // #   # 
+	0x88, // #   # 
+	0x00, //       
+	0x00  //       
+};
+
+/*
+ *  'NA'
+ */
+static const uint8_t Font12_197[] = {
+	6, 12,
+	1, 12,
+	0x20, //   #   
+	0x50, //  # #  
+	0x20, //   #   
+	0x20, //   #   
+	0x50, //  # #  
+	0x50, //  # #  
+	0x88, // #   # 
+	0xF8, // ##### 
+	0x88, // #   # 
+	0x88, // #   # 
+	0x00, //       
+	0x00  //       
+};
+
+/*
+ *  'NI'
+ */
+static const uint8_t Font12_198[] = {
+	6, 12,
+	1, 12,
+	0x00, //       
+	0x78, //  #### 
+	0x60, //  ##   
+	0xA0, // # #   
+	0xA0, // # #   
+	0xF8, // ##### 
+	0xA0, // # #   
+	0xA0, // # #   
+	0xA0, // # #   
+	0xB8, // # ### 
+	0x00, //       
+	0x00  //       
+};
+
+/*
+ *  'NU'
+ */
+static const uint8_t Font12_199[] = {
+	6, 12,
+	1, 12,
+	0x00, //       
+	0x30, //   ##  
+	0x48, //  #  # 
+	0x80, // #     
+	0x80, // #     
+	0x80, // #     
+	0x80, // #     
+	0x48, //  #  # 
+	0x30, //   ##  
+	0x10, //    #  
+	0x60, //  ##   
+	0x00  //       
+};
+
+/*
+ *  'NE'
+ */
+static const uint8_t Font12_200[] = {
+	6, 12,
+	1, 12,
+	0x40, //  #    
+	0x20, //   #   
+	0xF8, // ##### 
+	0x80, // #     
+	0x80, // #     
+	0xF0, // ####  
+	0x80, // #     
+	0x80, // #     
+	0x80, // #     
+	0xF8, // ##### 
+	0x00, //       
+	0x00  //       
+};
+
+/*
+ *  'NO'
+ */
+static const uint8_t Font12_201[] = {
+	6, 12,
+	1, 12,
+	0x10, //    #  
+	0x20, //   #   
+	0xF8, // ##### 
+	0x80, // #     
+	0x80, // #     
+	0xF0, // ####  
+	0x80, // #     
+	0x80, // #     
+	0x80, // #     
+	0xF8, // ##### 
+	0x00, //       
+	0x00  //       
+};
+
+/*
+ *  'HA'
+ */
+static const uint8_t Font12_202[] = {
+	6, 12,
+	1, 12,
+	0x20, //   #   
+	0x50, //  # #  
+	0xF8, // ##### 
+	0x80, // #     
+	0x80, // #     
+	0xF0, // ####  
+	0x80, // #     
+	0x80, // #     
+	0x80, // #     
+	0xF8, // ##### 
+	0x00, //       
+	0x00  //       
+};
+
+/*
+ *  'HI'
+ */
+static const uint8_t Font12_203[] = {
+	6, 12,
+	1, 12,
+	0x50, //  # #  
+	0x00, //       
+	0xF8, // ##### 
+	0x80, // #     
+	0x80, // #     
+	0xF0, // ####  
+	0x80, // #     
+	0x80, // #     
+	0x80, // #     
+	0xF8, // ##### 
+	0x00, //       
+	0x00  //       
+};
+
+/*
+ *  'HU'
+ */
+static const uint8_t Font12_204[] = {
+	6, 12,
+	1, 12,
+	0x40, //  #    
+	0x20, //   #   
+	0x70, //  ###  
+	0x20, //   #   
+	0x20, //   #   
+	0x20, //   #   
+	0x20, //   #   
+	0x20, //   #   
+	0x20, //   #   
+	0x70, //  ###  
+	0x00, //       
+	0x00  //       
+};
+
+/*
+ *  'HE'
+ */
+static const uint8_t Font12_205[] = {
+	6, 12,
+	1, 12,
+	0x10, //    #  
+	0x20, //   #   
+	0x70, //  ###  
+	0x20, //   #   
+	0x20, //   #   
+	0x20, //   #   
+	0x20, //   #   
+	0x20, //   #   
+	0x20, //   #   
+	0x70, //  ###  
+	0x00, //       
+	0x00  //       
+};
+
+/*
+ *  'HO'
+ */
+static const uint8_t Font12_206[] = {
+	6, 12,
+	1, 12,
+	0x20, //   #   
+	0x50, //  # #  
+	0x00, //       
+	0x70, //  ###  
+	0x20, //   #   
+	0x20, //   #   
+	0x20, //   #   
+	0x20, //   #   
+	0x20, //   #   
+	0x70, //  ###  
+	0x00, //       
+	0x00  //       
+};
+
+/*
+ *  'MA'
+ */
+static const uint8_t Font12_207[] = {
+	6, 12,
+	1, 12,
+	0x50, //  # #  
+	0x00, //       
+	0x70, //  ###  
+	0x20, //   #   
+	0x20, //   #   
+	0x20, //   #   
+	0x20, //   #   
+	0x20, //   #   
+	0x20, //   #   
+	0x70, //  ###  
+	0x00, //       
+	0x00  //       
+};
+
+/*
+ *  'MI'
+ */
+static const uint8_t Font12_208[] = {
+	6, 12,
+	1, 12,
+	0x00, //       
+	0xE0, // ###   
+	0x90, // #  #  
+	0x88, // #   # 
+	0x88, // #   # 
+	0xC8, // ##  # 
+	0x88, // #   # 
+	0x88, // #   # 
+	0x90, // #  #  
+	0xE0, // ###   
+	0x00, //       
+	0x00  //       
+};
+
+/*
+ *  'MU'
+ */
+static const uint8_t Font12_209[] = {
+	6, 12,
+	1, 12,
+	0x50, //  # #  
+	0xA0, // # #   
+	0x88, // #   # 
+	0xC8, // ##  # 
+	0xA8, // # # # 
+	0xA8, // # # # 
+	0x98, // #  ## 
+	0x98, // #  ## 
+	0x88, // #   # 
+	0x88, // #   # 
+	0x00, //       
+	0x00  //       
+};
+
+/*
+ *  'ME'
+ */
+static const uint8_t Font12_210[] = {
+	6, 12,
+	1, 12,
+	0x40, //  #    
+	0x20, //   #   
+	0x70, //  ###  
+	0x88, // #   # 
+	0x88, // #   # 
+	0x88, // #   # 
+	0x88, // #   # 
+	0x88, // #   # 
+	0x88, // #   # 
+	0x70, //  ###  
+	0x00, //       
+	0x00  //       
+};
+
+/*
+ *  'MO'
+ */
+static const uint8_t Font12_211[] = {
+	6, 12,
+	1, 12,
+	0x10, //    #  
+	0x20, //   #   
+	0x70, //  ###  
+	0x88, // #   # 
+	0x88, // #   # 
+	0x88, // #   # 
+	0x88, // #   # 
+	0x88, // #   # 
+	0x88, // #   # 
+	0x70, //  ###  
+	0x00, //       
+	0x00  //       
+};
+
+/*
+ *  'YA'
+ */
+static const uint8_t Font12_212[] = {
+	6, 12,
+	1, 12,
+	0x20, //   #   
+	0x50, //  # #  
+	0x70, //  ###  
+	0x88, // #   # 
+	0x88, // #   # 
+	0x88, // #   # 
+	0x88, // #   # 
+	0x88, // #   # 
+	0x88, // #   # 
+	0x70, //  ###  
+	0x00, //       
+	0x00  //       
+};
+
+/*
+ *  'YU'
+ */
+static const uint8_t Font12_213[] = {
+	6, 12,
+	1, 12,
+	0x28, //   # # 
+	0x50, //  # #  
+	0x70, //  ###  
+	0x88, // #   # 
+	0x88, // #   # 
+	0x88, // #   # 
+	0x88, // #   # 
+	0x88, // #   # 
+	0x88, // #   # 
+	0x70, //  ###  
+	0x00, //       
+	0x00  //       
+};
+
+/*
+ *  'YO'
+ */
+static const uint8_t Font12_214[] = {
+	6, 12,
+	1, 12,
+	0x50, //  # #  
+	0x00, //       
+	0x70, //  ###  
+	0x88, // #   # 
+	0x88, // #   # 
+	0x88, // #   # 
+	0x88, // #   # 
+	0x88, // #   # 
+	0x88, // #   # 
+	0x70, //  ###  
+	0x00, //       
+	0x00  //       
+};
+
+/*
+ *  'RA'
+ */
+static const uint8_t Font12_215[] = {
+	6, 12,
+	1, 12,
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0x88, // #   # 
+	0x50, //  # #  
+	0x20, //   #   
+	0x50, //  # #  
+	0x88, // #   # 
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0x00  //       
+};
+
+/*
+ *  'RI'
+ */
+static const uint8_t Font12_216[] = {
+	6, 12,
+	1, 12,
+	0x00, //       
+	0x34, //   ## #
+	0x4C, //  #  ##
+	0x48, //  #  # 
+	0x58, //  # ## 
+	0x68, //  ## # 
+	0x68, //  ## # 
+	0x48, //  #  # 
+	0xC8, // ##  # 
+	0xB0, // # ##  
+	0x00, //       
+	0x00  //       
+};
+
+/*
+ *  'RU'
+ */
+static const uint8_t Font12_217[] = {
+	6, 12,
+	1, 12,
+	0x40, //  #    
+	0x20, //   #   
+	0x88, // #   # 
+	0x88, // #   # 
+	0x88, // #   # 
+	0x88, // #   # 
+	0x88, // #   # 
+	0x88, // #   # 
+	0x88, // #   # 
+	0x70, //  ###  
+	0x00, //       
+	0x00  //       
+};
+
+/*
+ *  'RE'
+ */
+static const uint8_t Font12_218[] = {
+	6, 12,
+	1, 12,
+	0x10, //    #  
+	0x20, //   #   
+	0x88, // #   # 
+	0x88, // #   # 
+	0x88, // #   # 
+	0x88, // #   # 
+	0x88, // #   # 
+	0x88, // #   # 
+	0x88, // #   # 
+	0x70, //  ###  
+	0x00, //       
+	0x00  //       
+};
+
+/*
+ *  'RO'
+ */
+static const uint8_t Font12_219[] = {
+	6, 12,
+	1, 12,
+	0x20, //   #   
+	0x50, //  # #  
+	0x00, //       
+	0x88, // #   # 
+	0x88, // #   # 
+	0x88, // #   # 
+	0x88, // #   # 
+	0x88, // #   # 
+	0x88, // #   # 
+	0x70, //  ###  
+	0x00, //       
+	0x00  //       
+};
+
+/*
+ *  'WA'
+ */
+static const uint8_t Font12_220[] = {
+	6, 12,
+	1, 12,
+	0x50, //  # #  
+	0xA0, // # #   
+	0x00, //       
+	0x88, // #   # 
+	0x88, // #   # 
+	0x88, // #   # 
+	0x88, // #   # 
+	0x88, // #   # 
+	0x88, // #   # 
+	0x70, //  ###  
+	0x00, //       
+	0x00  //       
+};
+
+/*
+ *  'NN'
+ */
+static const uint8_t Font12_221[] = {
+	6, 12,
+	1, 12,
+	0x10, //    #  
+	0x20, //   #   
+	0x88, // #   # 
+	0x88, // #   # 
+	0x50, //  # #  
+	0x50, //  # #  
+	0x20, //   #   
+	0x20, //   #   
+	0x20, //   #   
+	0x20, //   #   
+	0x00, //       
+	0x00  //       
+};
+
+/*
+ *  dakuten
+ */
+static const uint8_t Font12_222[] = {
+	6, 12,
+	1, 12,
+	0x00, //       
+	0x40, //  #    
+	0x40, //  #    
+	0x70, //  ###  
+	0x48, //  #  # 
+	0x48, //  #  # 
+	0x48, //  #  # 
+	0x48, //  #  # 
+	0x70, //  ###  
+	0x40, //  #    
+	0x40, //  #    
+	0x00  //       
+};
+
+/*
+ *  maru
+ */
+static const uint8_t Font12_223[] = {
+	6, 12,
+	1, 12,
+	0x00, //       
+	0x30, //   ##  
+	0x48, //  #  # 
+	0x48, //  #  # 
+	0x48, //  #  # 
+	0x70, //  ###  
+	0x48, //  #  # 
+	0x48, //  #  # 
+	0x48, //  #  # 
+	0x50, //  # #  
+	0x40, //  #    
+	0x40  //  #    
+};
+
+/*
+ *  224
+ */
+static const uint8_t Font12_224[] = {
+	6, 12,
+	1, 12,
+	0x40, //  #    
+	0x20, //   #   
+	0x00, //       
+	0x70, //  ###  
+	0x88, // #   # 
+	0x18, //    ## 
+	0x68, //  ## # 
+	0x88, // #   # 
+	0x98, // #  ## 
+	0x68, //  ## # 
+	0x00, //       
+	0x00  //       
+};
+
+/*
+ *  225
+ */
+static const uint8_t Font12_225[] = {
+	6, 12,
+	1, 12,
+	0x10, //    #  
+	0x20, //   #   
+	0x00, //       
+	0x70, //  ###  
+	0x88, // #   # 
+	0x18, //    ## 
+	0x68, //  ## # 
+	0x88, // #   # 
+	0x98, // #  ## 
+	0x68, //  ## # 
+	0x00, //       
+	0x00  //       
+};
+
+/*
+ *  226
+ */
+static const uint8_t Font12_226[] = {
+	6, 12,
+	1, 12,
+	0x20, //   #   
+	0x50, //  # #  
+	0x00, //       
+	0x70, //  ###  
+	0x88, // #   # 
+	0x18, //    ## 
+	0x68, //  ## # 
+	0x88, // #   # 
+	0x98, // #  ## 
+	0x68, //  ## # 
+	0x00, //       
+	0x00  //       
+};
+
+/*
+ *  227
+ */
+static const uint8_t Font12_227[] = {
+	6, 12,
+	1, 12,
+	0x50, //  # #  
+	0xA0, // # #   
+	0x00, //       
+	0x70, //  ###  
+	0x88, // #   # 
+	0x18, //    ## 
+	0x68, //  ## # 
+	0x88, // #   # 
+	0x98, // #  ## 
+	0x68, //  ## # 
+	0x00, //       
+	0x00  //       
+};
+
+/*
+ *  228
+ */
+static const uint8_t Font12_228[] = {
+	6, 12,
+	1, 12,
+	0x00, //       
+	0x50, //  # #  
+	0x00, //       
+	0x70, //  ###  
+	0x88, // #   # 
+	0x18, //    ## 
+	0x68, //  ## # 
+	0x88, // #   # 
+	0x98, // #  ## 
+	0x68, //  ## # 
+	0x00, //       
+	0x00  //       
+};
+
+/*
+ *  229
+ */
+static const uint8_t Font12_229[] = {
+	6, 12,
+	1, 12,
+	0x20, //   #   
+	0x50, //  # #  
+	0x20, //   #   
+	0x70, //  ###  
+	0x88, // #   # 
+	0x18, //    ## 
+	0x68, //  ## # 
+	0x88, // #   # 
+	0x98, // #  ## 
+	0x68, //  ## # 
+	0x00, //       
+	0x00  //       
+};
+
+/*
+ *  230
+ */
+static const uint8_t Font12_230[] = {
+	6, 12,
+	1, 12,
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0x50, //  # #  
+	0xA8, // # # # 
+	0x28, //   # # 
+	0x78, //  #### 
+	0xA0, // # #   
+	0xA8, // # # # 
+	0x70, //  ###  
+	0x00, //       
+	0x00  //       
+};
+
+/*
+ *  231
+ */
+static const uint8_t Font12_231[] = {
+	6, 12,
+	1, 12,
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0x70, //  ###  
+	0x88, // #   # 
+	0x80, // #     
+	0x80, // #     
+	0x88, // #   # 
+	0x70, //  ###  
+	0x10, //    #  
+	0x60, //  ##   
+	0x00  //       
+};
+
+/*
+ *  232
+ */
+static const uint8_t Font12_232[] = {
+	6, 12,
+	1, 12,
+	0x40, //  #    
+	0x20, //   #   
+	0x00, //       
+	0x70, //  ###  
+	0x88, // #   # 
+	0x88, // #   # 
+	0xF8, // ##### 
+	0x80, // #     
+	0x88, // #   # 
+	0x70, //  ###  
+	0x00, //       
+	0x00  //       
+};
+
+/*
+ *  233
+ */
+static const uint8_t Font12_233[] = {
+	6, 12,
+	1, 12,
+	0x10, //    #  
+	0x20, //   #   
+	0x00, //       
+	0x70, //  ###  
+	0x88, // #   # 
+	0x88, // #   # 
+	0xF8, // ##### 
+	0x80, // #     
+	0x88, // #   # 
+	0x70, //  ###  
+	0x00, //       
+	0x00  //       
+};
+
+/*
+ *  234
+ */
+static const uint8_t Font12_234[] = {
+	6, 12,
+	1, 12,
+	0x20, //   #   
+	0x50, //  # #  
+	0x00, //       
+	0x70, //  ###  
+	0x88, // #   # 
+	0x88, // #   # 
+	0xF8, // ##### 
+	0x80, // #     
+	0x88, // #   # 
+	0x70, //  ###  
+	0x00, //       
+	0x00  //       
+};
+
+/*
+ *  235
+ */
+static const uint8_t Font12_235[] = {
+	6, 12,
+	1, 12,
+	0x00, //       
+	0x50, //  # #  
+	0x00, //       
+	0x70, //  ###  
+	0x88, // #   # 
+	0x88, // #   # 
+	0xF8, // ##### 
+	0x80, // #     
+	0x88, // #   # 
+	0x70, //  ###  
+	0x00, //       
+	0x00  //       
+};
+
+/*
+ *  236
+ */
+static const uint8_t Font12_236[] = {
+	6, 12,
+	1, 12,
+	0x40, //  #    
+	0x20, //   #   
+	0x00, //       
+	0x00, //       
+	0x20, //   #   
+	0x20, //   #   
+	0x20, //   #   
+	0x20, //   #   
+	0x20, //   #   
+	0x20, //   #   
+	0x00, //       
+	0x00  //       
+};
+
+/*
+ *  237
+ */
+static const uint8_t Font12_237[] = {
+	6, 12,
+	1, 12,
+	0x10, //    #  
+	0x20, //   #   
+	0x00, //       
+	0x00, //       
+	0x20, //   #   
+	0x20, //   #   
+	0x20, //   #   
+	0x20, //   #   
+	0x20, //   #   
+	0x20, //   #   
+	0x00, //       
+	0x00  //       
+};
+
+/*
+ *  238
+ */
+static const uint8_t Font12_238[] = {
+	6, 12,
+	1, 12,
+	0x20, //   #   
+	0x50, //  # #  
+	0x00, //       
+	0x00, //       
+	0x20, //   #   
+	0x20, //   #   
+	0x20, //   #   
+	0x20, //   #   
+	0x20, //   #   
+	0x20, //   #   
+	0x00, //       
+	0x00  //       
+};
+
+/*
+ *  239
+ */
+static const uint8_t Font12_239[] = {
+	6, 12,
+	1, 12,
+	0x00, //       
+	0x50, //  # #  
+	0x00, //       
+	0x00, //       
+	0x20, //   #   
+	0x20, //   #   
+	0x20, //   #   
+	0x20, //   #   
+	0x20, //   #   
+	0x20, //   #   
+	0x00, //       
+	0x00  //       
+};
+
+/*
+ *  240
+ */
+static const uint8_t Font12_240[] = {
+	6, 12,
+	1, 12,
+	0xA0, // # #   
+	0x40, //  #    
+	0xA0, // # #   
+	0x10, //    #  
+	0x70, //  ###  
+	0x88, // #   # 
+	0x88, // #   # 
+	0x88, // #   # 
+	0x88, // #   # 
+	0x70, //  ###  
+	0x00, //       
+	0x00  //       
+};
+
+/*
+ *  241
+ */
+static const uint8_t Font12_241[] = {
+	6, 12,
+	1, 12,
+	0x50, //  # #  
+	0xA0, // # #   
+	0x00, //       
+	0x00, //       
+	0xB0, // # ##  
+	0xC8, // ##  # 
+	0x88, // #   # 
+	0x88, // #   # 
+	0x88, // #   # 
+	0x88, // #   # 
+	0x00, //       
+	0x00  //       
+};
+
+/*
+ *  242
+ */
+static const uint8_t Font12_242[] = {
+	6, 12,
+	1, 12,
+	0x40, //  #    
+	0x20, //   #   
+	0x00, //       
+	0x70, //  ###  
+	0x88, // #   # 
+	0x88, // #   # 
+	0x88, // #   # 
+	0x88, // #   # 
+	0x88, // #   # 
+	0x70, //  ###  
+	0x00, //       
+	0x00  //       
+};
+
+/*
+ *  243
+ */
+static const uint8_t Font12_243[] = {
+	6, 12,
+	1, 12,
+	0x10, //    #  
+	0x20, //   #   
+	0x00, //       
+	0x70, //  ###  
+	0x88, // #   # 
+	0x88, // #   # 
+	0x88, // #   # 
+	0x88, // #   # 
+	0x88, // #   # 
+	0x70, //  ###  
+	0x00, //       
+	0x00  //       
+};
+
+/*
+ *  244
+ */
+static const uint8_t Font12_244[] = {
+	6, 12,
+	1, 12,
+	0x20, //   #   
+	0x50, //  # #  
+	0x00, //       
+	0x70, //  ###  
+	0x88, // #   # 
+	0x88, // #   # 
+	0x88, // #   # 
+	0x88, // #   # 
+	0x88, // #   # 
+	0x70, //  ###  
+	0x00, //       
+	0x00  //       
+};
+
+/*
+ *  245
+ */
+static const uint8_t Font12_245[] = {
+	6, 12,
+	1, 12,
+	0x50, //  # #  
+	0xA0, // # #   
+	0x00, //       
+	0x70, //  ###  
+	0x88, // #   # 
+	0x88, // #   # 
+	0x88, // #   # 
+	0x88, // #   # 
+	0x88, // #   # 
+	0x70, //  ###  
+	0x00, //       
+	0x00  //       
+};
+
+/*
+ *  246
+ */
+static const uint8_t Font12_246[] = {
+	6, 12,
+	1, 12,
+	0x00, //       
+	0x50, //  # #  
+	0x00, //       
+	0x70, //  ###  
+	0x88, // #   # 
+	0x88, // #   # 
+	0x88, // #   # 
+	0x88, // #   # 
+	0x88, // #   # 
+	0x70, //  ###  
+	0x00, //       
+	0x00  //       
+};
+
+/*
+ *  247
+ */
+static const uint8_t Font12_247[] = {
+	6, 12,
+	1, 12,
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0x20, //   #   
+	0x00, //       
+	0xF8, // ##### 
+	0x00, //       
+	0x20, //   #   
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0x00  //       
+};
+
+/*
+ *  248
+ */
+static const uint8_t Font12_248[] = {
+	6, 12,
+	1, 12,
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0x34, //   ## #
+	0x48, //  #  # 
+	0x58, //  # ## 
+	0x68, //  ## # 
+	0x48, //  #  # 
+	0xC8, // ##  # 
+	0x30, //   ##  
+	0x00, //       
+	0x00  //       
+};
+
+/*
+ *  249
+ */
+static const uint8_t Font12_249[] = {
+	6, 12,
+	1, 12,
+	0x40, //  #    
+	0x20, //   #   
+	0x00, //       
+	0x88, // #   # 
+	0x88, // #   # 
+	0x88, // #   # 
+	0x88, // #   # 
+	0x88, // #   # 
+	0x98, // #  ## 
+	0x68, //  ## # 
+	0x00, //       
+	0x00  //       
+};
+
+/*
+ *  250
+ */
+static const uint8_t Font12_250[] = {
+	6, 12,
+	1, 12,
+	0x10, //    #  
+	0x20, //   #   
+	0x00, //       
+	0x88, // #   # 
+	0x88, // #   # 
+	0x88, // #   # 
+	0x88, // #   # 
+	0x88, // #   # 
+	0x98, // #  ## 
+	0x68, //  ## # 
+	0x00, //       
+	0x00  //       
+};
+
+/*
+ *  251
+ */
+static const uint8_t Font12_251[] = {
+	6, 12,
+	1, 12,
+	0x20, //   #   
+	0x50, //  # #  
+	0x00, //       
+	0x88, // #   # 
+	0x88, // #   # 
+	0x88, // #   # 
+	0x88, // #   # 
+	0x88, // #   # 
+	0x98, // #  ## 
+	0x68, //  ## # 
+	0x00, //       
+	0x00  //       
+};
+
+/*
+ *  252
+ */
+static const uint8_t Font12_252[] = {
+	6, 12,
+	1, 12,
+	0x00, //       
+	0x50, //  # #  
+	0x00, //       
+	0x88, // #   # 
+	0x88, // #   # 
+	0x88, // #   # 
+	0x88, // #   # 
+	0x88, // #   # 
+	0x98, // #  ## 
+	0x68, //  ## # 
+	0x00, //       
+	0x00  //       
+};
+
+/*
+ *  253
+ */
+static const uint8_t Font12_253[] = {
+	6, 12,
+	1, 12,
+	0x10, //    #  
+	0x20, //   #   
+	0x00, //       
+	0x88, // #   # 
+	0x88, // #   # 
+	0x48, //  #  # 
+	0x50, //  # #  
+	0x50, //  # #  
+	0x20, //   #   
+	0x20, //   #   
+	0x40, //  #    
+	0x80  // #     
+};
+
+/*
+ *  254
+ */
+static const uint8_t Font12_254[] = {
+	6, 12,
+	1, 12,
+	/* 253 */
+	0x00, //       
+	0x00, //       
+	0x40, //  #    
+	0x40, //  #    
+	0x70, //  ###  
+	0x48, //  #  # 
+	0x48, //  #  # 
+	0x48, //  #  # 
+	0x48, //  #  # 
+	0x70, //  ###  
+	0x40, //  #    
+	0x40  //  #    
+};
+
+/*
+ *  255
+ */
+static const uint8_t Font12_255[] = {
+	6, 12,
+	1, 12,
+	0x00, //       
+	0x50, //  # #  
+	0x00, //       
+	0x88, // #   # 
+	0x88, // #   # 
+	0x48, //  #  # 
+	0x50, //  # #  
+	0x50, //  # #  
+	0x20, //   #   
+	0x20, //   #   
+	0x40, //  #    
+	0x80  // #     
+};
+
+
+const font_t *Font12[] = {
+	(font_t *)Font12_32,  (font_t *)Font12_01,  (font_t *)Font12_02,  (font_t *)Font12_03,
+	(font_t *)Font12_04,  (font_t *)Font12_05,  (font_t *)Font12_06,  (font_t *)Font12_07,
+	(font_t *)Font12_08,  (font_t *)Font12_09,  (font_t *)Font12_10,  (font_t *)Font12_11,
+	(font_t *)Font12_12,  (font_t *)Font12_13,  (font_t *)Font12_14,  (font_t *)Font12_15,
+	(font_t *)Font12_16,  (font_t *)Font12_17,  (font_t *)Font12_18,  (font_t *)Font12_19,
+	(font_t *)Font12_20,  (font_t *)Font12_21,  (font_t *)Font12_22,  (font_t *)Font12_23,
+	(font_t *)Font12_24,  (font_t *)Font12_25,  (font_t *)Font12_26,  (font_t *)Font12_27,
+	(font_t *)Font12_28,  (font_t *)Font12_29,  (font_t *)Font12_30,  (font_t *)Font12_31,
+	(font_t *)Font12_32,  (font_t *)Font12_33,  (font_t *)Font12_34,  (font_t *)Font12_35,
+	(font_t *)Font12_36,  (font_t *)Font12_37,  (font_t *)Font12_38,  (font_t *)Font12_39,
+	(font_t *)Font12_40,  (font_t *)Font12_41,  (font_t *)Font12_42,  (font_t *)Font12_43,
+	(font_t *)Font12_44,  (font_t *)Font12_45,  (font_t *)Font12_46,  (font_t *)Font12_47,
+	(font_t *)Font12_48,  (font_t *)Font12_49,  (font_t *)Font12_50,  (font_t *)Font12_51,
+	(font_t *)Font12_52,  (font_t *)Font12_53,  (font_t *)Font12_54,  (font_t *)Font12_55,
+	(font_t *)Font12_56,  (font_t *)Font12_57,  (font_t *)Font12_58,  (font_t *)Font12_59,
+	(font_t *)Font12_60,  (font_t *)Font12_61,  (font_t *)Font12_62,  (font_t *)Font12_63,
+	(font_t *)Font12_64,  (font_t *)Font12_65,  (font_t *)Font12_66,  (font_t *)Font12_67,
+	(font_t *)Font12_68,  (font_t *)Font12_69,  (font_t *)Font12_70,  (font_t *)Font12_71,
+	(font_t *)Font12_72,  (font_t *)Font12_73,  (font_t *)Font12_74,  (font_t *)Font12_75,
+	(font_t *)Font12_76,  (font_t *)Font12_77,  (font_t *)Font12_78,  (font_t *)Font12_79,
+	(font_t *)Font12_80,  (font_t *)Font12_81,  (font_t *)Font12_82,  (font_t *)Font12_83,
+	(font_t *)Font12_84,  (font_t *)Font12_85,  (font_t *)Font12_86,  (font_t *)Font12_87,
+	(font_t *)Font12_88,  (font_t *)Font12_89,  (font_t *)Font12_90,  (font_t *)Font12_91,
+	(font_t *)Font12_92,  (font_t *)Font12_93,  (font_t *)Font12_94,  (font_t *)Font12_95,
+	(font_t *)Font12_96,  (font_t *)Font12_97,  (font_t *)Font12_98,  (font_t *)Font12_99,
+	(font_t *)Font12_100, (font_t *)Font12_101, (font_t *)Font12_102, (font_t *)Font12_103,
+	(font_t *)Font12_104, (font_t *)Font12_105, (font_t *)Font12_106, (font_t *)Font12_107,
+	(font_t *)Font12_108, (font_t *)Font12_109, (font_t *)Font12_110, (font_t *)Font12_111,
+	(font_t *)Font12_112, (font_t *)Font12_113, (font_t *)Font12_114, (font_t *)Font12_115,
+	(font_t *)Font12_116, (font_t *)Font12_117, (font_t *)Font12_118, (font_t *)Font12_119,
+	(font_t *)Font12_120, (font_t *)Font12_121, (font_t *)Font12_122, (font_t *)Font12_123,
+	(font_t *)Font12_124, (font_t *)Font12_125, (font_t *)Font12_126, (font_t *)Font12_127,
+
+	0,                    0,                    0,                    0,
+	0,                    0,                    0,                    0,
+	0,                    0,                    0,                    0,
+	0,                    0,                    0,                    0,
+	0,                    0,                    0,                    0,
+	0,                    0,                    0,                    0,
+	0,                    0,                    0,                    0,
+	0,                    0,                    0,                    0,
+	(font_t *)Font12_160, (font_t *)Font12_161, (font_t *)Font12_162, (font_t *)Font12_163,
+	(font_t *)Font12_164, (font_t *)Font12_165, (font_t *)Font12_166, (font_t *)Font12_167,
+	(font_t *)Font12_168, (font_t *)Font12_169, (font_t *)Font12_170, (font_t *)Font12_171,
+	(font_t *)Font12_172, (font_t *)Font12_173, (font_t *)Font12_174, (font_t *)Font12_175,
+	(font_t *)Font12_176, (font_t *)Font12_177, (font_t *)Font12_178, (font_t *)Font12_179,
+	(font_t *)Font12_180, (font_t *)Font12_181, (font_t *)Font12_182, (font_t *)Font12_183,
+	(font_t *)Font12_184, (font_t *)Font12_185, (font_t *)Font12_186, (font_t *)Font12_187,
+	(font_t *)Font12_188, (font_t *)Font12_189, (font_t *)Font12_190, (font_t *)Font12_191,
+	(font_t *)Font12_192, (font_t *)Font12_193, (font_t *)Font12_194, (font_t *)Font12_195,
+	(font_t *)Font12_196, (font_t *)Font12_197, (font_t *)Font12_198, (font_t *)Font12_199,
+	(font_t *)Font12_200, (font_t *)Font12_201, (font_t *)Font12_202, (font_t *)Font12_203,
+	(font_t *)Font12_204, (font_t *)Font12_205, (font_t *)Font12_206, (font_t *)Font12_207,
+	(font_t *)Font12_208, (font_t *)Font12_209, (font_t *)Font12_210, (font_t *)Font12_211,
+	(font_t *)Font12_212, (font_t *)Font12_213, (font_t *)Font12_214, (font_t *)Font12_215,
+	(font_t *)Font12_216, (font_t *)Font12_217, (font_t *)Font12_218, (font_t *)Font12_219,
+	(font_t *)Font12_220, (font_t *)Font12_221, (font_t *)Font12_222, (font_t *)Font12_223,
+	(font_t *)Font12_224, (font_t *)Font12_225, (font_t *)Font12_226, (font_t *)Font12_227,
+	(font_t *)Font12_228, (font_t *)Font12_229, (font_t *)Font12_230, (font_t *)Font12_231,
+	(font_t *)Font12_232, (font_t *)Font12_233, (font_t *)Font12_234, (font_t *)Font12_235,
+	(font_t *)Font12_236, (font_t *)Font12_237, (font_t *)Font12_238, (font_t *)Font12_239,
+	(font_t *)Font12_240, (font_t *)Font12_241, (font_t *)Font12_242, (font_t *)Font12_243,
+	(font_t *)Font12_244, (font_t *)Font12_245, (font_t *)Font12_246, (font_t *)Font12_247,
+	(font_t *)Font12_248, (font_t *)Font12_249, (font_t *)Font12_250, (font_t *)Font12_251,
+	(font_t *)Font12_252, (font_t *)Font12_253, (font_t *)Font12_254, (font_t *)Font12_255
+};
+
+font_head_t Shinonome_Font12 = {
+	"shinonome_font12",
+	0x80,
+	0x00,
+	12,
+	12,
+	Font12,
+	NULL
+};
+
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/ui/snfont_disp/font16.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/ui/snfont_disp/font16.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/ui/snfont_disp/font16.c	(revision 457)
@@ -0,0 +1,5460 @@
+/*
+ *  TOPPERS ECHONET Lite Communication Middleware
+ * 
+ *  Copyright (C) 2018-2019 Cores Co., Ltd. Japan
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  $Id$
+ */
+
+/*
+ * 東雲フォント
+ * http://openlab.ring.gr.jp/efont/shinonome/
+ * Licence
+ * Public Domain
+ */
+
+
+#include "fonts.h"
+
+/*
+ *  001
+ */
+static const uint8_t Font16_01[] = {
+	8, 16,
+	1, 16,
+	0x10, //    #    
+	0x10, //    #    
+	0x38, //   ###   
+	0x38, //   ###   
+	0x7C, //  #####  
+	0x7C, //  #####  
+	0xFE, // ####### 
+	0xFE, // ####### 
+	0x7C, //  #####  
+	0x7C, //  #####  
+	0x38, //   ###   
+	0x38, //   ###   
+	0x10, //    #    
+	0x10, //    #    
+	0x00, //         
+	0x00  //         
+};
+
+/*
+ *  002
+ */
+static const uint8_t Font16_02[] = {
+	8, 16,
+	1, 16,
+	0x55, //  # # # #
+	0xAA, // # # # # 
+	0x55, //  # # # #
+	0xAA, // # # # # 
+	0x55, //  # # # #
+	0xAA, // # # # # 
+	0x55, //  # # # #
+	0xAA, // # # # # 
+	0x55, //  # # # #
+	0xAA, // # # # # 
+	0x55, //  # # # #
+	0xAA, // # # # # 
+	0x55, //  # # # #
+	0xAA, // # # # # 
+	0x00, //         
+	0x00  //         
+};
+
+/*
+ *  003
+ */
+static const uint8_t Font16_03[] = {
+	8, 16,
+	1, 16,
+	0x00, //         
+	0x88, // #   #   
+	0x88, // #   #   
+	0x88, // #   #   
+	0xF8, // #####   
+	0x88, // #   #   
+	0x88, // #   #   
+	0x88, // #   #   
+	0x00, //         
+	0x3E, //   ##### 
+	0x08, //     #   
+	0x08, //     #   
+	0x08, //     #   
+	0x08, //     #   
+	0x08, //     #   
+	0x08  //     #   
+};
+
+/*
+ *  004
+ */
+static const uint8_t Font16_04[] = {
+	8, 16,
+	1, 16,
+	0x00, //         
+	0xF8, // #####   
+	0x80, // #       
+	0x80, // #       
+	0xF0, // ####    
+	0x80, // #       
+	0x80, // #       
+	0x80, // #       
+	0x3E, //   ##### 
+	0x20, //   #     
+	0x20, //   #     
+	0x3C, //   ####  
+	0x20, //   #     
+	0x20, //   #     
+	0x20, //   #     
+	0x00  //         
+};
+
+/*
+ *  005
+ */
+static const uint8_t Font16_05[] = {
+	8, 16,
+	1, 16,
+	0x00, //         
+	0x70, //  ###    
+	0x88, // #   #   
+	0x80, // #       
+	0x80, // #       
+	0x80, // #       
+	0x88, // #   #   
+	0x70, //  ###    
+	0x00, //         
+	0x3C, //   ####  
+	0x22, //   #   # 
+	0x22, //   #   # 
+	0x3C, //   ####  
+	0x28, //   # #   
+	0x24, //   #  #  
+	0x22  //   #   # 
+};
+
+/*
+ *  006
+ */
+static const uint8_t Font16_06[] = {
+	8, 16,
+	1, 16,
+	0x00, //         
+	0x80, // #       
+	0x80, // #       
+	0x80, // #       
+	0x80, // #       
+	0x80, // #       
+	0x80, // #       
+	0xF8, // #####   
+	0x00, //         
+	0x3E, //   ##### 
+	0x20, //   #     
+	0x20, //   #     
+	0x3C, //   ####  
+	0x20, //   #     
+	0x20, //   #     
+	0x20  //   #     
+};
+
+/*
+ *  007
+ */
+static const uint8_t Font16_07[] = {
+	8, 16,
+	1, 16,
+	0x00, //         
+	0x00, //         
+	0x38, //   ###   
+	0x44, //  #   #  
+	0x44, //  #   #  
+	0x44, //  #   #  
+	0x38, //   ###   
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00  //         
+};
+
+/*
+ *  008
+ */
+static const uint8_t Font16_08[] = {
+	8, 16,
+	1, 16,
+	0x00, //         
+	0x00, //         
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0xFE, // ####### 
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0x00, //         
+	0xFE, // ####### 
+	0x00, //         
+	0x00, //         
+	0x00  //         
+};
+
+/*
+ *  009
+ */
+static const uint8_t Font16_09[] = {
+	8, 16,
+	1, 16,
+	0x00, //         
+	0x84, // #    #  
+	0xC4, // ##   #  
+	0xA4, // # #  #  
+	0xA4, // # #  #  
+	0x94, // #  # #  
+	0x94, // #  # #  
+	0x8C, // #   ##  
+	0x84, // #    #  
+	0x20, //   #     
+	0x20, //   #     
+	0x20, //   #     
+	0x20, //   #     
+	0x20, //   #     
+	0x20, //   #     
+	0x3E  //   ##### 
+};
+
+/*
+ *  010
+ */
+static const uint8_t Font16_10[] = {
+	8, 16,
+	1, 16,
+	0x00, //         
+	0x00, //         
+	0x88, // #   #   
+	0x88, // #   #   
+	0x88, // #   #   
+	0x50, //  # #    
+	0x50, //  # #    
+	0x20, //   #     
+	0x00, //         
+	0x3E, //   ##### 
+	0x08, //     #   
+	0x08, //     #   
+	0x08, //     #   
+	0x08, //     #   
+	0x08, //     #   
+	0x00  //         
+};
+
+/*
+ *  011
+ */
+static const uint8_t Font16_11[] = {
+	8, 16,
+	1, 16,
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0xF0, // ####    
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00  //         
+};
+
+/*
+ *  012
+ */
+static const uint8_t Font16_12[] = {
+	8, 16,
+	1, 16,
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0xF0, // ####    
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0x10  //    #    
+};
+
+/*
+ *  013
+ */
+static const uint8_t Font16_13[] = {
+	8, 16,
+	1, 16,
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x1F, //    #####
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0x10  //    #    
+};
+
+/*
+ *  014
+ */
+static const uint8_t Font16_14[] = {
+	8, 16,
+	1, 16,
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0x1F, //    #####
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00  //         
+};
+
+/*
+ *  015
+ */
+static const uint8_t Font16_15[] = {
+	8, 16,
+	1, 16,
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0xFF, // ########
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0x10  //    #    
+};
+
+/*
+ *  016
+ */
+static const uint8_t Font16_16[] = {
+	8, 16,
+	1, 16,
+	0x00, //         
+	0x00, //         
+	0xFF, // ########
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00  //         
+};
+
+/*
+ *  017
+ */
+static const uint8_t Font16_17[] = {
+	8, 16,
+	1, 16,
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0xFF, // ########
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00  //       
+};
+
+/*
+ *  018
+ */
+static const uint8_t Font16_18[] = {
+	8, 16,
+	1, 16,
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0xFF, // ########
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00  //       
+};
+
+/*
+ *  019
+ */
+static const uint8_t Font16_19[] = {
+	8, 16,
+	1, 16,
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0xFF, // ########
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00  //       
+};
+
+/*
+ *  020
+ */
+static const uint8_t Font16_20[] = {
+	8, 16,
+	1, 16,
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0xFF, // ########
+	0x00  //         
+};
+
+/*
+ *  021
+ */
+static const uint8_t Font16_21[] = {
+	8, 16,
+	1, 16,
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0x1F, //    #####
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0x10  //    #    
+};
+
+/*
+ *  022
+ */
+static const uint8_t Font16_22[] = {
+	8, 16,
+	1, 16,
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0xF0, // ####    
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0x10  //    #    
+};
+
+/*
+ *  023
+ */
+static const uint8_t Font16_23[] = {
+	8, 16,
+	1, 16,
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0xFF, // ########
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00  //         
+};
+
+/*
+ *  024
+ */
+static const uint8_t Font16_24[] = {
+	8, 16,
+	1, 16,
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0xFF, // ########
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0x10  //    #    
+};
+
+/*
+ *  025
+ */
+static const uint8_t Font16_25[] = {
+	8, 16,
+	1, 16,
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0x10  //    #    
+};
+
+/*
+ *  026
+ */
+static const uint8_t Font16_26[] = {
+	8, 16,
+	1, 16,
+	0x00, //         
+	0x00, //         
+	0x02, //       # 
+	0x0C, //     ##  
+	0x30, //   ##    
+	0xC0, // ##      
+	0x30, //   ##    
+	0x0C, //     ##  
+	0x02, //       # 
+	0x00, //         
+	0xFE, // ####### 
+	0x00, //         
+	0xFE, // ####### 
+	0x00, //         
+	0x00, //         
+	0x00  //         
+};
+
+/*
+ *  027
+ */
+static const uint8_t Font16_27[] = {
+	8, 16,
+	1, 16,
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x80, // #       
+	0x60, //  ##     
+	0x18, //    ##   
+	0x06, //      ## 
+	0x18, //    ##   
+	0x60, //  ##     
+	0x80, // #       
+	0xFE, // ####### 
+	0x00, //         
+	0xFE, // ####### 
+	0x00, //         
+	0x00, //         
+	0x00  //         
+};
+
+/*
+ *  028
+ */
+static const uint8_t Font16_28[] = {
+	8, 16,
+	1, 16,
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0xFE, // ####### 
+	0x24, //   #  #  
+	0x24, //   #  #  
+	0x24, //   #  #  
+	0x24, //   #  #  
+	0x44, //  #   #  
+	0x84, // #    #  
+	0x00, //         
+	0x00  //         
+};
+
+/*
+ *  029
+ */
+static const uint8_t Font16_29[] = {
+	8, 16,
+	1, 16,
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x02, //       # 
+	0x04, //      #  
+	0x08, //     #   
+	0xFE, // ####### 
+	0x10, //    #    
+	0xFE, // ####### 
+	0x20, //   #     
+	0x40, //  #      
+	0x80, // #       
+	0x00, //         
+	0x00, //         
+	0x00  //         
+};
+
+/*
+ *  030
+ */
+static const uint8_t Font16_30[] = {
+	8, 16,
+	1, 16,
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x0C, //     ##  
+	0x12, //    #  # 
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0x7C, //  #####  
+	0x10, //    #    
+	0x10, //    #    
+	0x3C, //   ####  
+	0x52, //  # #  # 
+	0x20, //   #     
+	0x00  //         
+};
+
+/*
+ *  031
+ */
+static const uint8_t Font16_31[] = {
+	8, 16,
+	1, 16,
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x10, //    #    
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00  //         
+};
+
+/*
+ *  SPACE
+ */
+static const uint8_t Font16_32[] = {
+	8, 16,
+	0, 0
+};
+
+/*
+ *  !
+ */
+static const uint8_t Font16_33[] = {
+	8, 16,
+	1, 16,
+	0x00, //         
+	0x18, //    ##   
+	0x18, //    ##   
+	0x18, //    ##   
+	0x18, //    ##   
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0x00, //         
+	0x00, //         
+	0x10, //    #    
+	0x10, //    #    
+	0x00  //         
+};
+
+/*
+ *  '!'
+ */
+static const uint8_t Font16_34[] = {
+	8, 16,
+	1, 16,
+	0x6C, //  ## ##  
+	0x24, //   #  #  
+	0x24, //   #  #  
+	0x48, //  #  #   
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00  //         
+};
+
+/*
+ *  '#'
+ */
+static const uint8_t Font16_35[] = {
+	8, 16,
+	1, 16,
+	0x00, //         
+	0x12, //    #  # 
+	0x12, //    #  # 
+	0x12, //    #  # 
+	0x7F, //  #######
+	0x24, //   #  #  
+	0x24, //   #  #  
+	0x24, //   #  #  
+	0x24, //   #  #  
+	0x24, //   #  #  
+	0xFE, // ####### 
+	0x48, //  #  #   
+	0x48, //  #  #   
+	0x48, //  #  #   
+	0x48, //  #  #   
+	0x00  //         
+};
+
+/*
+ *  '$'
+ */
+static const uint8_t Font16_36[] = {
+	8, 16,
+	1, 16,
+	0x10, //    #    
+	0x38, //   ###   
+	0x54, //  # # #  
+	0x92, // #  #  # 
+	0x92, // #  #  # 
+	0x90, // #  #    
+	0x50, //  # #    
+	0x38, //   ###   
+	0x14, //    # #  
+	0x12, //    #  # 
+	0x92, // #  #  # 
+	0x92, // #  #  # 
+	0x54, //  # # #  
+	0x38, //   ###   
+	0x10, //    #    
+	0x10  //    #    
+};
+
+/*
+ *  '%'
+ */
+static const uint8_t Font16_37[] = {
+	8, 16,
+	1, 16,
+	0x01, //        #
+	0x61, //  ##    #
+	0x92, // #  #  # 
+	0x92, // #  #  # 
+	0x94, // #  # #  
+	0x94, // #  # #  
+	0x68, //  ## #   
+	0x08, //     #   
+	0x10, //    #    
+	0x16, //    # ## 
+	0x29, //   # #  #
+	0x29, //   # #  #
+	0x49, //  #  #  #
+	0x49, //  #  #  #
+	0x86, // #    ## 
+	0x80  // #       
+};
+
+/*
+ *  '&'
+ */
+static const uint8_t Font16_38[] = {
+	8, 16,
+	1, 16,
+	0x00, //         
+	0x38, //   ###   
+	0x44, //  #   #  
+	0x44, //  #   #  
+	0x44, //  #   #  
+	0x28, //   # #   
+	0x10, //    #    
+	0x30, //   ##    
+	0x4A, //  #  # # 
+	0x8A, // #   # # 
+	0x84, // #    #  
+	0x84, // #    #  
+	0x4A, //  #  # # 
+	0x31, //   ##   #
+	0x00, //         
+	0x00  //         
+};
+
+/*
+ *  '''
+ */
+static const uint8_t Font16_39[] = {
+	8, 16,
+	1, 16,
+	0x60, //  ##     
+	0x20, //   #     
+	0x20, //   #     
+	0x40, //  #      
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00  //         
+};
+
+/*
+ *  '('
+ */
+static const uint8_t Font16_40[] = {
+	8, 16,
+	1, 16,
+	0x00, //         
+	0x02, //       # 
+	0x04, //      #  
+	0x08, //     #   
+	0x08, //     #   
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0x08, //     #   
+	0x08, //     #   
+	0x04, //      #  
+	0x02  //       # 
+};
+
+/*
+ *  ')'
+ */
+static const uint8_t Font16_41[] = {
+	8, 16,
+	1, 16,
+	0x00, //         
+	0x40, //  #      
+	0x20, //   #     
+	0x10, //    #    
+	0x10, //    #    
+	0x08, //     #   
+	0x08, //     #   
+	0x08, //     #   
+	0x08, //     #   
+	0x08, //     #   
+	0x08, //     #   
+	0x08, //     #   
+	0x10, //    #    
+	0x10, //    #    
+	0x20, //   #     
+	0x40  //  #      
+};
+
+/*
+ *  '*'
+ */
+static const uint8_t Font16_42[] = {
+	8, 16,
+	1, 16,
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x10, //    #    
+	0x92, // #  #  # 
+	0x54, //  # # #  
+	0x38, //   ###   
+	0x54, //  # # #  
+	0x92, // #  #  # 
+	0x10, //    #    
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00  //         
+};
+
+/*
+ *  '+'
+ */
+static const uint8_t Font16_43[] = {
+	8, 16,
+	1, 16,
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0xFE, // ####### 
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00  //         
+};
+
+/*
+ *  ','
+ */
+static const uint8_t Font16_44[] = {
+	8, 16,
+	1, 16,
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x60, //  ##     
+	0x20, //   #     
+	0x20, //   #     
+	0x40  //  #      
+};
+
+/*
+ *  '-'
+ */
+static const uint8_t Font16_45[] = {
+	8, 16,
+	1, 16,
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0xFE, // ####### 
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00  //         
+};
+
+/*
+ *  '.'
+ */
+static const uint8_t Font16_46[] = {
+	5, 12,
+	1, 16,
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x60, //  ##     
+	0x60, //  ##     
+	0x00, //         
+	0x00  //         
+};
+
+/*
+ *  '/'
+ */
+static const uint8_t Font16_47[] = {
+	8, 16,
+	1, 16,
+	0x00, //         
+	0x02, //       # 
+	0x02, //       # 
+	0x04, //      #  
+	0x04, //      #  
+	0x08, //     #   
+	0x08, //     #   
+	0x10, //    #    
+	0x10, //    #    
+	0x20, //   #     
+	0x20, //   #     
+	0x40, //  #      
+	0x40, //  #      
+	0x80, // #       
+	0x80, // #       
+	0x00  //         
+};
+
+/*
+ *  '0'
+ */
+static const uint8_t Font16_48[] = {
+	8, 16,
+	1, 16,
+	0x00, //         
+	0x18, //    ##   
+	0x24, //   #  #  
+	0x24, //   #  #  
+	0x42, //  #    # 
+	0x42, //  #    # 
+	0x42, //  #    # 
+	0x42, //  #    # 
+	0x42, //  #    # 
+	0x42, //  #    # 
+	0x42, //  #    # 
+	0x24, //   #  #  
+	0x24, //   #  #  
+	0x18, //    ##   
+	0x00, //         
+	0x00  //         
+};
+
+/*
+ *  '1'
+ */
+static const uint8_t Font16_49[] = {
+	8, 16,
+	1, 16,
+	0x00, //         
+	0x10, //    #    
+	0x10, //    #    
+	0x30, //   ##    
+	0x50, //  # #    
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0x00, //         
+	0x00  //         
+};
+
+/*
+ *  '2'
+ */
+static const uint8_t Font16_50[] = {
+	8, 16,
+	1, 16,
+	0x00, //         
+	0x18, //    ##   
+	0x24, //   #  #  
+	0x42, //  #    # 
+	0x42, //  #    # 
+	0x02, //       # 
+	0x04, //      #  
+	0x08, //     #   
+	0x10, //    #    
+	0x20, //   #     
+	0x20, //   #     
+	0x40, //  #      
+	0x40, //  #      
+	0x7E, //  ###### 
+	0x00, //         
+	0x00  //         
+};
+
+/*
+ *  '3'
+ */
+static const uint8_t Font16_51[] = {
+	8, 16,
+	1, 16,
+	0x00, //         
+	0x38, //   ###   
+	0x44, //  #   #  
+	0x82, // #     # 
+	0x82, // #     # 
+	0x02, //       # 
+	0x04, //      #  
+	0x38, //   ###   
+	0x04, //      #  
+	0x02, //       # 
+	0x82, // #     # 
+	0x82, // #     # 
+	0x44, //  #   #  
+	0x38, //   ###   
+	0x00, //         
+	0x00  //         
+};
+
+/*
+ *  '4'
+ */
+static const uint8_t Font16_52[] = {
+	8, 16,
+	1, 16,
+	0x00, //         
+	0x08, //     #   
+	0x18, //    ##   
+	0x18, //    ##   
+	0x28, //   # #   
+	0x28, //   # #   
+	0x48, //  #  #   
+	0x48, //  #  #   
+	0x88, // #   #   
+	0xFE, // ####### 
+	0x08, //     #   
+	0x08, //     #   
+	0x08, //     #   
+	0x08, //     #   
+	0x00, //         
+	0x00  //         
+};
+
+/*
+ *  '5'
+ */
+static const uint8_t Font16_53[] = {
+	8, 16,
+	1, 16,
+	0x00, //         
+	0x7C, //  #####  
+	0x40, //  #      
+	0x40, //  #      
+	0x40, //  #      
+	0xB8, // # ###   
+	0xC4, // ##   #  
+	0x82, // #     # 
+	0x02, //       # 
+	0x02, //       # 
+	0x82, // #     # 
+	0x82, // #     # 
+	0x44, //  #   #  
+	0x38, //   ###   
+	0x00, //         
+	0x00  //         
+};
+
+/*
+ *  '6'
+ */
+static const uint8_t Font16_54[] = {
+	8, 16,
+	1, 16,
+	0x00, //         
+	0x38, //   ###   
+	0x44, //  #   #  
+	0x40, //  #      
+	0x80, // #       
+	0x80, // #       
+	0xB8, // # ###   
+	0xC4, // ##   #  
+	0x82, // #     # 
+	0x82, // #     # 
+	0x82, // #     # 
+	0x82, // #     # 
+	0x44, //  #   #  
+	0x38, //   ###   
+	0x00, //         
+	0x00  //         
+};
+
+/*
+ *  '7'
+ */
+static const uint8_t Font16_55[] = {
+	8, 16,
+	1, 16,
+	0x00, //         
+	0xFE, // ####### 
+	0x02, //       # 
+	0x04, //      #  
+	0x04, //      #  
+	0x08, //     #   
+	0x08, //     #   
+	0x08, //     #   
+	0x08, //     #   
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0x00  //         
+};
+
+/*
+ *  '8'
+ */
+static const uint8_t Font16_56[] = {
+	8, 16,
+	1, 16,
+	0x00, //         
+	0x38, //   ###   
+	0x44, //  #   #  
+	0x82, // #     # 
+	0x82, // #     # 
+	0x82, // #     # 
+	0x44, //  #   #  
+	0x38, //   ###   
+	0x44, //  #   #  
+	0x82, // #     # 
+	0x82, // #     # 
+	0x82, // #     # 
+	0x44, //  #   #  
+	0x38, //   ###   
+	0x00, //         
+	0x00  //         
+};
+
+/*
+ *  '9'
+ */
+static const uint8_t Font16_57[] = {
+	8, 16,
+	1, 16,
+	0x00, //         
+	0x38, //   ###   
+	0x44, //  #   #  
+	0x82, // #     # 
+	0x82, // #     # 
+	0x82, // #     # 
+	0x82, // #     # 
+	0x46, //  #   ## 
+	0x3A, //   ### # 
+	0x02, //       # 
+	0x02, //       # 
+	0x82, // #     # 
+	0x44, //  #   #  
+	0x38, //   ###   
+	0x00, //         
+	0x00  //         
+};
+
+/*
+ *  ':'
+ */
+static const uint8_t Font16_58[] = {
+	5, 12,
+	1, 16,
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x18, //    ##   
+	0x18, //    ##   
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x18, //    ##   
+	0x18, //    ##   
+	0x00, //         
+	0x00, //         
+	0x00  //         
+};
+
+/*
+ *  ';'
+ */
+static const uint8_t Font16_59[] = {
+	5, 12,
+	1, 16,
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x18, //    ##   
+	0x18, //    ##   
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x18, //    ##   
+	0x08, //     #   
+	0x08, //     #   
+	0x10, //    #    
+	0x00, //         
+	0x00  //         
+};
+
+/*
+ *  '<'
+ */
+static const uint8_t Font16_60[] = {
+	8, 16,
+	1, 16,
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x02, //       # 
+	0x04, //      #  
+	0x08, //     #   
+	0x10, //    #    
+	0x20, //   #     
+	0x20, //   #     
+	0x10, //    #    
+	0x08, //     #   
+	0x04, //      #  
+	0x02, //       # 
+	0x00, //         
+	0x00, //         
+	0x00  //         
+};
+
+/*
+ *  '='
+ */
+static const uint8_t Font16_61[] = {
+	8, 16,
+	1, 16,
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0xFE, // ####### 
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0xFE, // ####### 
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00  //         
+};
+
+/*
+ *  '>'
+ */
+static const uint8_t Font16_62[] = {
+	8, 16,
+	1, 16,
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x40, //  #      
+	0x20, //   #     
+	0x10, //    #    
+	0x08, //     #   
+	0x04, //      #  
+	0x04, //      #  
+	0x08, //     #   
+	0x10, //    #    
+	0x20, //   #     
+	0x40, //  #      
+	0x00, //         
+	0x00, //         
+	0x00  //         
+};
+
+/*
+ *  '?'
+ */
+static const uint8_t Font16_63[] = {
+	8, 16,
+	1, 16,
+	0x00, //         
+	0x38, //   ###   
+	0x44, //  #   #  
+	0x82, // #     # 
+	0x82, // #     # 
+	0x82, // #     # 
+	0x04, //      #  
+	0x08, //     #   
+	0x08, //     #   
+	0x10, //    #    
+	0x10, //    #    
+	0x00, //         
+	0x00, //         
+	0x10, //    #    
+	0x10, //    #    
+	0x00  //         
+};
+
+/*
+ *  '@'
+ */
+static const uint8_t Font16_64[] = {
+	8, 16,
+	1, 16,
+	0x00, //         
+	0x18, //    ##   
+	0x24, //   #  #  
+	0x42, //  #    # 
+	0x5A, //  # ## # 
+	0xB5, // # ## # #
+	0xA5, // # #  # #
+	0xA5, // # #  # #
+	0xA5, // # #  # #
+	0x9A, // #  ## # 
+	0x40, //  #      
+	0x40, //  #      
+	0x22, //   #   # 
+	0x1C, //    ###  
+	0x00, //         
+	0x00  //         
+};
+
+/*
+ *  'A'
+ */
+static const uint8_t Font16_65[] = {
+	8, 16,
+	1, 16,
+	0x00, //         
+	0x10, //    #    
+	0x10, //    #    
+	0x28, //   # #   
+	0x28, //   # #   
+	0x28, //   # #   
+	0x44, //  #   #  
+	0x44, //  #   #  
+	0x44, //  #   #  
+	0x7C, //  #####  
+	0x82, // #     # 
+	0x82, // #     # 
+	0x82, // #     # 
+	0x82, // #     # 
+	0x00, //         
+	0x00  //         
+};
+
+/*
+ *  'B'
+ */
+static const uint8_t Font16_66[] = {
+	8, 16,
+	1, 16,
+	0x00, //         
+	0xF0, // ####    
+	0x88, // #   #   
+	0x84, // #    #  
+	0x84, // #    #  
+	0x84, // #    #  
+	0x88, // #   #   
+	0xF8, // #####   
+	0x84, // #    #  
+	0x82, // #     # 
+	0x82, // #     # 
+	0x82, // #     # 
+	0x84, // #    #  
+	0xF8, // #####   
+	0x00, //         
+	0x00  //         
+};
+
+/*
+ *  'C'
+ */
+static const uint8_t Font16_67[] = {
+	8, 16,
+	1, 16,
+	0x00, //         
+	0x38, //   ###   
+	0x44, //  #   #  
+	0x42, //  #    # 
+	0x80, // #       
+	0x80, // #       
+	0x80, // #       
+	0x80, // #       
+	0x80, // #       
+	0x80, // #       
+	0x80, // #       
+	0x42, //  #    # 
+	0x44, //  #   #  
+	0x38, //   ###   
+	0x00, //         
+	0x00  //         
+};
+
+/*
+ *  'D'
+ */
+static const uint8_t Font16_68[] = {
+	8, 16,
+	1, 16,
+	0x00, //         
+	0xF0, // ####    
+	0x88, // #   #   
+	0x84, // #    #  
+	0x84, // #    #  
+	0x82, // #     # 
+	0x82, // #     # 
+	0x82, // #     # 
+	0x82, // #     # 
+	0x82, // #     # 
+	0x84, // #    #  
+	0x84, // #    #  
+	0x88, // #   #   
+	0xF0, // ####    
+	0x00, //         
+	0x00  //         
+};
+
+/*
+ *  'E'
+ */
+static const uint8_t Font16_69[] = {
+	8, 16,
+	1, 16,
+	0x00, //         
+	0xFE, // ####### 
+	0x80, // #       
+	0x80, // #       
+	0x80, // #       
+	0x80, // #       
+	0x80, // #       
+	0xFC, // ######  
+	0x80, // #       
+	0x80, // #       
+	0x80, // #       
+	0x80, // #       
+	0x80, // #       
+	0xFE, // ####### 
+	0x00, //         
+	0x00  //         
+};
+
+/*
+ *  'F'
+ */
+static const uint8_t Font16_70[] = {
+	8, 16,
+	1, 16,
+	0x00, //         
+	0xFE, // ####### 
+	0x80, // #       
+	0x80, // #       
+	0x80, // #       
+	0x80, // #       
+	0x80, // #       
+	0xFC, // ######  
+	0x80, // #       
+	0x80, // #       
+	0x80, // #       
+	0x80, // #       
+	0x80, // #       
+	0x80, // #       
+	0x00, //         
+	0x00  //         
+};
+
+/*
+ *  'G'
+ */
+static const uint8_t Font16_71[] = {
+	8, 16,
+	1, 16,
+	0x00, //         
+	0x18, //    ##   
+	0x24, //   #  #  
+	0x42, //  #    # 
+	0x40, //  #      
+	0x80, // #       
+	0x80, // #       
+	0x8E, // #   ### 
+	0x82, // #     # 
+	0x82, // #     # 
+	0x82, // #     # 
+	0x42, //  #    # 
+	0x66, //  ##  ## 
+	0x1A, //    ## # 
+	0x00, //         
+	0x00  //         
+};
+
+/*
+ *  'H'
+ */
+static const uint8_t Font16_72[] = {
+	8, 16,
+	1, 16,
+	0x00, //         
+	0x82, // #     # 
+	0x82, // #     # 
+	0x82, // #     # 
+	0x82, // #     # 
+	0x82, // #     # 
+	0x82, // #     # 
+	0xFE, // ####### 
+	0x82, // #     # 
+	0x82, // #     # 
+	0x82, // #     # 
+	0x82, // #     # 
+	0x82, // #     # 
+	0x82, // #     # 
+	0x00, //         
+	0x00  //         
+};
+
+/*
+ *  'I'
+ */
+static const uint8_t Font16_73[] = {
+	5, 12,
+	1, 16,
+	0x00, //         
+	0x38, //   ###   
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0x38, //   ###   
+	0x00, //         
+	0x00  //         
+};
+
+/*
+ *  'J'
+ */
+static const uint8_t Font16_74[] = {
+	8, 16,
+	1, 16,
+	0x00, //         
+	0x02, //       # 
+	0x02, //       # 
+	0x02, //       # 
+	0x02, //       # 
+	0x02, //       # 
+	0x02, //       # 
+	0x02, //       # 
+	0x02, //       # 
+	0x02, //       # 
+	0x02, //       # 
+	0x42, //  #    # 
+	0x24, //   #  #  
+	0x18, //    ##   
+	0x00, //         
+	0x00  //         
+};
+
+/*
+ *  'K'
+ */
+static const uint8_t Font16_75[] = {
+	8, 16,
+	1, 16,
+	0x00, //         
+	0x42, //  #    # 
+	0x42, //  #    # 
+	0x44, //  #   #  
+	0x44, //  #   #  
+	0x48, //  #  #   
+	0x58, //  # ##   
+	0x68, //  ## #   
+	0x64, //  ##  #  
+	0x44, //  #   #  
+	0x42, //  #    # 
+	0x42, //  #    # 
+	0x41, //  #     #
+	0x41, //  #     #
+	0x00, //         
+	0x00  //         
+};
+
+/*
+ *  'L'
+ */
+static const uint8_t Font16_76[] = {
+	8, 16,
+	1, 16,
+	0x00, //         
+	0x40, //  #      
+	0x40, //  #      
+	0x40, //  #      
+	0x40, //  #      
+	0x40, //  #      
+	0x40, //  #      
+	0x40, //  #      
+	0x40, //  #      
+	0x40, //  #      
+	0x40, //  #      
+	0x40, //  #      
+	0x40, //  #      
+	0x7E, //  ###### 
+	0x00, //         
+	0x00  //         
+};
+
+/*
+ *  'M'
+ */
+static const uint8_t Font16_77[] = {
+	8, 16,
+	1, 16,
+	0x00, //         
+	0x82, // #     # 
+	0x82, // #     # 
+	0xC6, // ##   ## 
+	0xC6, // ##   ## 
+	0xC6, // ##   ## 
+	0xAA, // # # # # 
+	0xAA, // # # # # 
+	0xAA, // # # # # 
+	0x92, // #  #  # 
+	0x92, // #  #  # 
+	0x92, // #  #  # 
+	0x92, // #  #  # 
+	0x82, // #     # 
+	0x00, //         
+	0x00  //         
+};
+
+/*
+ *  'N'
+ */
+static const uint8_t Font16_78[] = {
+	8, 16,
+	1, 16,
+	0x00, //         
+	0x82, // #     # 
+	0xC2, // ##    # 
+	0xC2, // ##    # 
+	0xA2, // # #   # 
+	0xA2, // # #   # 
+	0x92, // #  #  # 
+	0x92, // #  #  # 
+	0x92, // #  #  # 
+	0x8A, // #   # # 
+	0x8A, // #   # # 
+	0x86, // #    ## 
+	0x86, // #    ## 
+	0x82, // #     # 
+	0x00, //         
+	0x00  //         
+};
+
+/*
+ *  'O'
+ */
+static const uint8_t Font16_79[] = {
+	8, 16,
+	1, 16,
+	0x00, //         
+	0x38, //   ###   
+	0x44, //  #   #  
+	0x44, //  #   #  
+	0x82, // #     # 
+	0x82, // #     # 
+	0x82, // #     # 
+	0x82, // #     # 
+	0x82, // #     # 
+	0x82, // #     # 
+	0x82, // #     # 
+	0x44, //  #   #  
+	0x44, //  #   #  
+	0x38, //   ###   
+	0x00, //         
+	0x00  //         
+};
+
+/*
+ *  'P'
+ */
+static const uint8_t Font16_80[] = {
+	8, 16,
+	1, 16,
+	0x00, //         
+	0xF8, // #####   
+	0x84, // #    #  
+	0x82, // #     # 
+	0x82, // #     # 
+	0x82, // #     # 
+	0x84, // #    #  
+	0xF8, // #####   
+	0x80, // #       
+	0x80, // #       
+	0x80, // #       
+	0x80, // #       
+	0x80, // #       
+	0x80, // #       
+	0x00, //         
+	0x00  //         
+};
+
+/*
+ *  'Q'
+ */
+static const uint8_t Font16_81[] = {
+	8, 16,
+	1, 16,
+	0x00, //         
+	0x38, //   ###   
+	0x44, //  #   #  
+	0x44, //  #   #  
+	0x82, // #     # 
+	0x82, // #     # 
+	0x82, // #     # 
+	0x82, // #     # 
+	0x82, // #     # 
+	0x82, // #     # 
+	0xBA, // # ### # 
+	0x44, //  #   #  
+	0x44, //  #   #  
+	0x38, //   ###   
+	0x08, //     #   
+	0x06  //      ## 
+};
+
+/*
+ *  'R'
+ */
+static const uint8_t Font16_82[] = {
+	8, 16,
+	1, 16,
+	0x00, //         
+	0xF8, // #####   
+	0x84, // #    #  
+	0x82, // #     # 
+	0x82, // #     # 
+	0x82, // #     # 
+	0x84, // #    #  
+	0xF8, // #####   
+	0x88, // #   #   
+	0x84, // #    #  
+	0x84, // #    #  
+	0x84, // #    #  
+	0x82, // #     # 
+	0x82, // #     # 
+	0x00, //         
+	0x00  //         
+};
+
+/*
+ *  'S'
+ */
+static const uint8_t Font16_83[] = {
+	8, 16,
+	1, 16,
+	0x00, //         
+	0x38, //   ###   
+	0x44, //  #   #  
+	0x82, // #     # 
+	0x82, // #     # 
+	0x80, // #       
+	0x60, //  ##     
+	0x18, //    ##   
+	0x04, //      #  
+	0x02, //       # 
+	0x82, // #     # 
+	0x82, // #     # 
+	0x44, //  #   #  
+	0x38, //   ###   
+	0x00, //         
+	0x00  //         
+};
+
+/*
+ *  'T'
+ */
+static const uint8_t Font16_84[] = {
+	8, 16,
+	1, 16,
+	0x00, //         
+	0xFE, // ####### 
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0x00, //         
+	0x00  //         
+};
+
+/*
+ *  'U'
+ */
+static const uint8_t Font16_85[] = {
+	8, 16,
+	1, 16,
+	0x00, //         
+	0x82, // #     # 
+	0x82, // #     # 
+	0x82, // #     # 
+	0x82, // #     # 
+	0x82, // #     # 
+	0x82, // #     # 
+	0x82, // #     # 
+	0x82, // #     # 
+	0x82, // #     # 
+	0x82, // #     # 
+	0x82, // #     # 
+	0x44, //  #   #  
+	0x38, //   ###   
+	0x00, //         
+	0x00  //         
+};
+
+/*
+ *  'V'
+ */
+static const uint8_t Font16_86[] = {
+	8, 16,
+	1, 16,
+	0x00, //         
+	0x82, // #     # 
+	0x82, // #     # 
+	0x82, // #     # 
+	0x82, // #     # 
+	0x44, //  #   #  
+	0x44, //  #   #  
+	0x44, //  #   #  
+	0x28, //   # #   
+	0x28, //   # #   
+	0x28, //   # #   
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0x00, //         
+	0x00  //         
+};
+
+/*
+ *  'W'
+ */
+static const uint8_t Font16_87[] = {
+	8, 16,
+	1, 16,
+	0x00, //         
+	0x92, // #  #  # 
+	0x92, // #  #  # 
+	0x92, // #  #  # 
+	0x92, // #  #  # 
+	0x92, // #  #  # 
+	0x92, // #  #  # 
+	0xAA, // # # # # 
+	0xAA, // # # # # 
+	0x6C, //  ## ##  
+	0x44, //  #   #  
+	0x44, //  #   #  
+	0x44, //  #   #  
+	0x44, //  #   #  
+	0x00, //         
+	0x00  //         
+};
+
+/*
+ *  'X'
+ */
+static const uint8_t Font16_88[] = {
+	8, 16,
+	1, 16,
+	0x00, //         
+	0x82, // #     # 
+	0x44, //  #   #  
+	0x44, //  #   #  
+	0x28, //   # #   
+	0x28, //   # #   
+	0x10, //    #    
+	0x28, //   # #   
+	0x28, //   # #   
+	0x28, //   # #   
+	0x44, //  #   #  
+	0x44, //  #   #  
+	0x82, // #     # 
+	0x82, // #     # 
+	0x00, //         
+	0x00  //         
+};
+
+/*
+ *  'Y'
+ */
+static const uint8_t Font16_89[] = {
+	8, 16,
+	1, 16,
+	0x00, //         
+	0x82, // #     # 
+	0x82, // #     # 
+	0x44, //  #   #  
+	0x44, //  #   #  
+	0x44, //  #   #  
+	0x28, //   # #   
+	0x28, //   # #   
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0x00, //         
+	0x00  //         
+};
+
+/*
+ *  'Z'
+ */
+static const uint8_t Font16_90[] = {
+	8, 16,
+	1, 16,
+	0x00, //         
+	0xFE, // ####### 
+	0x04, //      #  
+	0x04, //      #  
+	0x08, //     #   
+	0x08, //     #   
+	0x10, //    #    
+	0x10, //    #    
+	0x20, //   #     
+	0x20, //   #     
+	0x40, //  #      
+	0x40, //  #      
+	0x80, // #       
+	0xFE, // ####### 
+	0x00, //         
+	0x00  //         
+};
+
+/*
+ *  '['
+ */
+static const uint8_t Font16_91[] = {
+	5, 12,
+	1, 16,
+	0x1E, //    #### 
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0x1E  //    #### 
+};
+
+/*
+ *  '\'
+ */
+static const uint8_t Font16_92[] = {
+	8, 16,
+	1, 16,
+	0x00, //         
+	0x80, // #       
+	0x80, // #       
+	0x40, //  #      
+	0x40, //  #      
+	0x20, //   #     
+	0x20, //   #     
+	0x10, //    #    
+	0x10, //    #    
+	0x08, //     #   
+	0x08, //     #   
+	0x04, //      #  
+	0x04, //      #  
+	0x02, //       # 
+	0x02, //       # 
+	0x00  //         
+};
+
+/*
+ *  ']'
+ */
+static const uint8_t Font16_93[] = {
+	5, 12,
+	1, 16,
+	0xF0, // ####    
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0xF0  // ####    
+};
+
+/*
+ *  '^'
+ */
+static const uint8_t Font16_94[] = {
+	8, 16,
+	1, 16,
+	0x10, //    #    
+	0x28, //   # #   
+	0x44, //  #   #  
+	0x82, // #     # 
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00  //         
+};
+
+/*
+ *  '_'
+ */
+static const uint8_t Font16_95[] = {
+	8, 16,
+	1, 16,
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0xFE, // ####### 
+	0x00  //         
+};
+
+/*
+ *  '''
+ */
+static const uint8_t Font16_96[] = {
+	5, 12,
+	1, 16,
+	0x30, //   ##    
+	0x20, //   #     
+	0x20, //   #     
+	0x10, //    #    
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00  //         
+};
+
+/*
+ *  'a'
+ */
+static const uint8_t Font16_97[] = {
+	8, 16,
+	1, 16,
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x3C, //   ####  
+	0x42, //  #    # 
+	0x02, //       # 
+	0x3E, //   ##### 
+	0x42, //  #    # 
+	0x82, // #     # 
+	0x82, // #     # 
+	0x86, // #    ## 
+	0x7A, //  #### # 
+	0x00, //         
+	0x00  //         
+};
+
+/*
+ *  'b'
+ */
+static const uint8_t Font16_98[] = {
+	8, 16,
+	1, 16,
+	0x00, //         
+	0x80, // #       
+	0x80, // #       
+	0x80, // #       
+	0x80, // #       
+	0xB8, // # ###   
+	0xC4, // ##   #  
+	0x82, // #     # 
+	0x82, // #     # 
+	0x82, // #     # 
+	0x82, // #     # 
+	0x82, // #     # 
+	0xC4, // ##   #  
+	0xB8, // # ###   
+	0x00, //         
+	0x00  //         
+};
+
+/*
+ *  'c'
+ */
+static const uint8_t Font16_99[] = {
+	8, 16,
+	1, 16,
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x38, //   ###   
+	0x44, //  #   #  
+	0x82, // #     # 
+	0x80, // #       
+	0x80, // #       
+	0x80, // #       
+	0x82, // #     # 
+	0x44, //  #   #  
+	0x38, //   ###   
+	0x00, //         
+	0x00  //         
+};
+
+/*
+ *  'd'
+ */
+static const uint8_t Font16_100[] = {
+	8, 16,
+	1, 16,
+	0x00, //         
+	0x02, //       # 
+	0x02, //       # 
+	0x02, //       # 
+	0x02, //       # 
+	0x3A, //   ### # 
+	0x46, //  #   ## 
+	0x82, // #     # 
+	0x82, // #     # 
+	0x82, // #     # 
+	0x82, // #     # 
+	0x82, // #     # 
+	0x46, //  #   ## 
+	0x3A, //   ### # 
+	0x00, //         
+	0x00  //         
+};
+
+/*
+ *  'e'
+ */
+static const uint8_t Font16_101[] = {
+	8, 16,
+	1, 16,
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x38, //   ###   
+	0x44, //  #   #  
+	0x82, // #     # 
+	0x82, // #     # 
+	0xFE, // ####### 
+	0x80, // #       
+	0x82, // #     # 
+	0x44, //  #   #  
+	0x38, //   ###   
+	0x00, //         
+	0x00  //         
+};
+
+/*
+ *  'f'
+ */
+static const uint8_t Font16_102[] = {
+	8, 16,
+	1, 16,
+	0x00, //         
+	0x0C, //     ##  
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0x7C, //  #####  
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0x00, //         
+	0x00  //         
+};
+
+/*
+ *  'g'
+ */
+static const uint8_t Font16_103[] = {
+	8, 16,
+	1, 16,
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x3B, //   ### ##
+	0x44, //  #   #  
+	0x44, //  #   #  
+	0x44, //  #   #  
+	0x38, //   ###   
+	0x40, //  #      
+	0x78, //  ####   
+	0x84, // #    #  
+	0x82, // #     # 
+	0x82, // #     # 
+	0x7C  //  #####  
+};
+
+/*
+ *  'h'
+ */
+static const uint8_t Font16_104[] = {
+	8, 16,
+	1, 16,
+	0x00, //         
+	0x40, //  #      
+	0x40, //  #      
+	0x40, //  #      
+	0x40, //  #      
+	0x5C, //  # ###  
+	0x62, //  ##   # 
+	0x42, //  #    # 
+	0x42, //  #    # 
+	0x42, //  #    # 
+	0x42, //  #    # 
+	0x42, //  #    # 
+	0x42, //  #    # 
+	0x42, //  #    # 
+	0x00, //         
+	0x00  //         
+};
+
+/*
+ *  'i'
+ */
+static const uint8_t Font16_105[] = {
+	8, 16,
+	1, 16,
+	0x00, //         
+	0x10, //    #    
+	0x10, //    #    
+	0x00, //         
+	0x00, //         
+	0x30, //   ##    
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0x00, //         
+	0x00  //         
+};
+
+/*
+ *  'j'
+ */
+static const uint8_t Font16_106[] = {
+	8, 16,
+	1, 16,
+	0x00, //         
+	0x08, //     #   
+	0x08, //     #   
+	0x00, //         
+	0x00, //         
+	0x18, //    ##   
+	0x08, //     #   
+	0x08, //     #   
+	0x08, //     #   
+	0x08, //     #   
+	0x08, //     #   
+	0x08, //     #   
+	0x08, //     #   
+	0x08, //     #   
+	0x10, //    #    
+	0x60  //  ##     
+};
+
+/*
+ *  'k'
+ */
+static const uint8_t Font16_107[] = {
+	8, 16,
+	1, 16,
+	0x00, //         
+	0x40, //  #      
+	0x40, //  #      
+	0x40, //  #      
+	0x40, //  #      
+	0x42, //  #    # 
+	0x44, //  #   #  
+	0x48, //  #  #   
+	0x50, //  # #    
+	0x68, //  ## #   
+	0x44, //  #   #  
+	0x44, //  #   #  
+	0x42, //  #    # 
+	0x42, //  #    # 
+	0x00, //         
+	0x00  //         
+};
+
+/*
+ *  'l'
+ */
+static const uint8_t Font16_108[] = {
+	8, 16,
+	1, 16,
+	0x00, //         
+	0x30, //   ##    
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0x00, //         
+	0x00  //         
+};
+
+/*
+ *  'm'
+ */
+static const uint8_t Font16_109[] = {
+	8, 16,
+	1, 16,
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0xEC, // ### ##  
+	0x92, // #  #  # 
+	0x92, // #  #  # 
+	0x92, // #  #  # 
+	0x92, // #  #  # 
+	0x92, // #  #  # 
+	0x92, // #  #  # 
+	0x92, // #  #  # 
+	0x92, // #  #  # 
+	0x00, //         
+	0x00  //         
+};
+
+/*
+ *  'n'
+ */
+static const uint8_t Font16_110[] = {
+	8, 16,
+	1, 16,
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x5C, //  # ###  
+	0x62, //  ##   # 
+	0x42, //  #    # 
+	0x42, //  #    # 
+	0x42, //  #    # 
+	0x42, //  #    # 
+	0x42, //  #    # 
+	0x42, //  #    # 
+	0x42, //  #    # 
+	0x00, //         
+	0x00  //         
+};
+
+/*
+ *  'o'
+ */
+static const uint8_t Font16_111[] = {
+	8, 16,
+	1, 16,
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x38, //   ###   
+	0x44, //  #   #  
+	0x82, // #     # 
+	0x82, // #     # 
+	0x82, // #     # 
+	0x82, // #     # 
+	0x82, // #     # 
+	0x44, //  #   #  
+	0x38, //   ###   
+	0x00, //         
+	0x00  //         
+};
+
+/*
+ *  'p'
+ */
+static const uint8_t Font16_112[] = {
+	8, 16,
+	1, 16,
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0xB8, // # ###   
+	0xC4, // ##   #  
+	0x82, // #     # 
+	0x82, // #     # 
+	0x82, // #     # 
+	0x82, // #     # 
+	0xC4, // ##   #  
+	0xB8, // # ###   
+	0x80, // #       
+	0x80, // #       
+	0x80  // #       
+};
+
+/*
+ *  'q'
+ */
+static const uint8_t Font16_113[] = {
+	8, 16,
+	1, 16,
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x3A, //   ### # 
+	0x46, //  #   ## 
+	0x82, // #     # 
+	0x82, // #     # 
+	0x82, // #     # 
+	0x82, // #     # 
+	0x46, //  #   ## 
+	0x3A, //   ### # 
+	0x02, //       # 
+	0x02, //       # 
+	0x02  //       # 
+};
+
+/*
+ *  'r'
+ */
+static const uint8_t Font16_114[] = {
+	8, 16,
+	1, 16,
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x2C, //   # ##  
+	0x30, //   ##    
+	0x20, //   #     
+	0x20, //   #     
+	0x20, //   #     
+	0x20, //   #     
+	0x20, //   #     
+	0x20, //   #     
+	0x20, //   #     
+	0x00, //         
+	0x00  //         
+};
+
+/*
+ *  's'
+ */
+static const uint8_t Font16_115[] = {
+	8, 16,
+	1, 16,
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x3C, //   ####  
+	0x42, //  #    # 
+	0x40, //  #      
+	0x60, //  ##     
+	0x18, //    ##   
+	0x06, //      ## 
+	0x02, //       # 
+	0x42, //  #    # 
+	0x3C, //   ####  
+	0x00, //         
+	0x00  //         
+};
+
+/*
+ *  't'
+ */
+static const uint8_t Font16_116[] = {
+	8, 16,
+	1, 16,
+	0x00, //         
+	0x00, //         
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0x7C, //  #####  
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0x0C, //     ##  
+	0x00, //         
+	0x00  //         
+};
+
+/*
+ *  'u'
+ */
+static const uint8_t Font16_117[] = {
+	8, 16,
+	1, 16,
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x42, //  #    # 
+	0x42, //  #    # 
+	0x42, //  #    # 
+	0x42, //  #    # 
+	0x42, //  #    # 
+	0x42, //  #    # 
+	0x42, //  #    # 
+	0x46, //  #   ## 
+	0x3A, //   ### # 
+	0x00, //         
+	0x00  //         
+};
+
+/*
+ *  'v'
+ */
+static const uint8_t Font16_118[] = {
+	8, 16,
+	1, 16,
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x82, // #     # 
+	0x82, // #     # 
+	0x82, // #     # 
+	0x44, //  #   #  
+	0x44, //  #   #  
+	0x28, //   # #   
+	0x28, //   # #   
+	0x10, //    #    
+	0x10, //    #    
+	0x00, //         
+	0x00  //         
+};
+
+/*
+ *  'w'
+ */
+static const uint8_t Font16_119[] = {
+	8, 16,
+	1, 16,
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x92, // #  #  # 
+	0x92, // #  #  # 
+	0x92, // #  #  # 
+	0x92, // #  #  # 
+	0xAA, // # # # # 
+	0xAA, // # # # # 
+	0x44, //  #   #  
+	0x44, //  #   #  
+	0x44, //  #   #  
+	0x00, //         
+	0x00  //         
+};
+
+/*
+ *  'x'
+ */
+static const uint8_t Font16_120[] = {
+	8, 16,
+	1, 16,
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x82, // #     # 
+	0x44, //  #   #  
+	0x28, //   # #   
+	0x28, //   # #   
+	0x10, //    #    
+	0x28, //   # #   
+	0x28, //   # #   
+	0x44, //  #   #  
+	0x82, // #     # 
+	0x00, //         
+	0x00  //         
+};
+
+/*
+ *  'y'
+ */
+static const uint8_t Font16_121[] = {
+	8, 16,
+	1, 16,
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x82, // #     # 
+	0x82, // #     # 
+	0x44, //  #   #  
+	0x44, //  #   #  
+	0x28, //   # #   
+	0x28, //   # #   
+	0x18, //    ##   
+	0x10, //    #    
+	0x10, //    #    
+	0x20, //   #     
+	0xC0  // ##      
+};
+
+/*
+ *  'z'
+ */
+static const uint8_t Font16_122[] = {
+	8, 16,
+	1, 16,
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x7E, //  ###### 
+	0x04, //      #  
+	0x08, //     #   
+	0x08, //     #   
+	0x10, //    #    
+	0x10, //    #    
+	0x20, //   #     
+	0x40, //  #      
+	0xFE, // ####### 
+	0x00, //         
+	0x00  //         
+};
+
+/*
+ *  '{'
+ */
+static const uint8_t Font16_123[] = {
+	5, 12,
+	1, 16,
+	0x04, //      #  
+	0x08, //     #   
+	0x08, //     #   
+	0x08, //     #   
+	0x08, //     #   
+	0x08, //     #   
+	0x08, //     #   
+	0x10, //    #    
+	0x08, //     #   
+	0x08, //     #   
+	0x08, //     #   
+	0x08, //     #   
+	0x08, //     #   
+	0x08, //     #   
+	0x08, //     #   
+	0x04  //      #  
+};
+
+/*
+ *  '|'
+ */
+static const uint8_t Font16_124[] = {
+	5, 12,
+	1, 16,
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0x10  //    #    
+};
+
+/*
+ *  '}'
+ */
+static const uint8_t Font16_125[] = {
+	5, 12,
+	1, 16,
+	0x40, //  #      
+	0x20, //   #     
+	0x20, //   #     
+	0x20, //   #     
+	0x20, //   #     
+	0x20, //   #     
+	0x20, //   #     
+	0x10, //    #    
+	0x20, //   #     
+	0x20, //   #     
+	0x20, //   #     
+	0x20, //   #     
+	0x20, //   #     
+	0x20, //   #     
+	0x20, //   #     
+	0x40  //  #      
+};
+
+/*
+ *  '->'
+ */
+static const uint8_t Font16_126[] = {
+	8, 16,
+	1, 16,
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x60, //  ##     
+	0x92, // #  #  # 
+	0x0C, //     ##  
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00  //         
+};
+
+/*
+ *  DEL
+ */
+static const uint8_t Font16_127[] = {
+	8, 16,
+	1, 16,
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00  //         
+};
+
+/*
+ *  yohaku
+ */
+static const uint8_t Font16_160[] = {
+	8, 16,
+	1, 16,
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00  //         
+};
+
+/*
+ *  syuryou
+ */
+static const uint8_t Font16_161[] = {
+	8, 16,
+	1, 16,
+	0x00, //         
+	0x10, //    #    
+	0x10, //    #    
+	0x00, //         
+	0x00, //         
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0x30, //   ##    
+	0x30, //   ##    
+	0x30, //   ##    
+	0x30  //   ##    
+};
+
+/*
+ *  kakko
+ */
+static const uint8_t Font16_162[] = {
+	8, 16,
+	1, 16,
+	0x00, //         
+	0x00, //         
+	0x10, //    #    
+	0x3C, //   ####  
+	0x52, //  # #  # 
+	0x92, // #  #  # 
+	0x90, // #  #    
+	0x90, // #  #    
+	0x90, // #  #    
+	0x90, // #  #    
+	0x90, // #  #    
+	0x92, // #  #  # 
+	0x52, //  # #  # 
+	0x3C, //   ####  
+	0x10, //    #    
+	0x00  //         
+};
+
+/*
+ *  kakko tojiru
+ */
+static const uint8_t Font16_163[] = {
+	8, 16,
+	1, 16,
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x0C, //     ##  
+	0x12, //    #  # 
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0x7C, //  #####  
+	0x10, //    #    
+	0x10, //    #    
+	0x3C, //   ####  
+	0x52, //  # #  # 
+	0x20, //   #     
+	0x00  //         
+};
+
+/*
+ *  kutouten
+ */
+static const uint8_t Font16_164[] = {
+	8, 16,
+	1, 16,
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x42, //  #    # 
+	0x3C, //   ####  
+	0x24, //   #  #  
+	0x24, //   #  #  
+	0x3C, //   ####  
+	0x42, //  #    # 
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00  //         
+};
+
+/*
+ *  cyuten
+ */
+static const uint8_t Font16_165[] = {
+	8, 16,
+	1, 16,
+	0x82, // #     # 
+	0x82, // #     # 
+	0x44, //  #   #  
+	0x44, //  #   #  
+	0x44, //  #   #  
+	0x28, //   # #   
+	0x28, //   # #   
+	0xFE, // ####### 
+	0x10, //    #    
+	0xFE, // ####### 
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0x00, //         
+	0x00  //         
+};
+
+/*
+ *  'WO'
+ */
+static const uint8_t Font16_166[] = {
+	8, 16,
+	1, 16,
+	0x00, //         
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0x00, //         
+	0x00  //         
+};
+
+/*
+ *  'aa'
+ */
+static const uint8_t Font16_167[] = {
+	8, 16,
+	1, 16,
+	0x00, //         
+	0x3C, //   ####  
+	0x42, //  #    # 
+	0x40, //  #      
+	0x20, //   #     
+	0x3C, //   ####  
+	0x42, //  #    # 
+	0x42, //  #    # 
+	0x42, //  #    # 
+	0x3C, //   ####  
+	0x04, //      #  
+	0x02, //       # 
+	0x42, //  #    # 
+	0x3C, //   ####  
+	0x00, //         
+	0x00  //         
+};
+
+/*
+ *  'ii'
+ */
+static const uint8_t Font16_168[] = {
+	8, 16,
+	1, 16,
+	0x00, //         
+	0x24, //   #  #  
+	0x24, //   #  #  
+	0x24, //   #  #  
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00  //         
+};
+
+/*
+ *  'uu'
+ */
+static const uint8_t Font16_169[] = {
+	8, 16,
+	1, 16,
+	0x00, //         
+	0x00, //         
+	0x3C, //   ####  
+	0x42, //  #    # 
+	0x99, // #  ##  #
+	0xA5, // # #  # #
+	0xA1, // # #    #
+	0xA1, // # #    #
+	0xA1, // # #    #
+	0xA5, // # #  # #
+	0xA5, // # #  # #
+	0x9B, // #  ## ##
+	0x42, //  #    # 
+	0x3C, //   ####  
+	0x00, //         
+	0x00  //         
+};
+
+/*
+ *  'ee'
+ */
+static const uint8_t Font16_170[] = {
+	8, 16,
+	1, 16,
+	0x00, //         
+	0x1C, //    ###  
+	0x22, //   #   # 
+	0x1E, //    #### 
+	0x22, //   #   # 
+	0x26, //   #  ## 
+	0x1A, //    ## # 
+	0x00, //         
+	0x3E, //   ##### 
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00  //         
+};
+
+/*
+ *  'oo'
+ */
+static const uint8_t Font16_171[] = {
+	8, 16,
+	1, 16,
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x09, //     #  #
+	0x12, //    #  # 
+	0x24, //   #  #  
+	0x48, //  #  #   
+	0x90, // #  #    
+	0x90, // #  #    
+	0x48, //  #  #   
+	0x24, //   #  #  
+	0x12, //    #  # 
+	0x09, //     #  #
+	0x00, //         
+	0x00, //         
+	0x00  //         
+};
+
+/*
+ *  'ya'
+ */
+static const uint8_t Font16_172[] = {
+	8, 16,
+	1, 16,
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0xFE, // ####### 
+	0xFE, // ####### 
+	0x06, //      ## 
+	0x06, //      ## 
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00  //         
+};
+
+/*
+ *  'yu'
+ */
+static const uint8_t Font16_173[] = {
+	8, 16,
+	1, 16,
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0xFE, // ####### 
+	0xFE, // ####### 
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00  //         
+};
+
+/*
+ *  'yo'
+ */
+static const uint8_t Font16_174[] = {
+	8, 16,
+	1, 16,
+	0x00, //         
+	0x00, //         
+	0x3C, //   ####  
+	0x42, //  #    # 
+	0xB9, // # ###  #
+	0xA5, // # #  # #
+	0xA5, // # #  # #
+	0xB9, // # ###  #
+	0xA9, // # # #  #
+	0xA5, // # #  # #
+	0xA5, // # #  # #
+	0xA3, // # #   ##
+	0x42, //  #    # 
+	0x3C, //   ####  
+	0x00, //         
+	0x00  //         
+};
+
+
+/*
+ *  'tu'
+ */
+static const uint8_t Font16_175[] = {
+	8, 16,
+	1, 16,
+	0x00, //         
+	0x00, //         
+	0xFE, // ####### 
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00  //         
+};
+
+/*
+ *  '-'
+ */
+static const uint8_t Font16_176[] = {
+	8, 16,
+	1, 16,
+	0x00, //         
+	0x38, //   ###   
+	0x44, //  #   #  
+	0x44, //  #   #  
+	0x44, //  #   #  
+	0x38, //   ###   
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00  //         
+};
+
+/*
+ *  'AA'
+ */
+static const uint8_t Font16_177[] = {
+	8, 16,
+	1, 16,
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0xFE, // ####### 
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0x00, //         
+	0xFE, // ####### 
+	0x00, //         
+	0x00, //         
+	0x00  //         
+};
+
+/*
+ *  'II'
+ */
+static const uint8_t Font16_178[] = {
+	8, 16,
+	1, 16,
+	0x00, //         
+	0x18, //    ##   
+	0x24, //   #  #  
+	0x04, //      #  
+	0x08, //     #   
+	0x10, //    #    
+	0x20, //   #     
+	0x3C, //   ####  
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00  //         
+};
+
+/*
+ *  'UU'
+ */
+static const uint8_t Font16_179[] = {
+	8, 16,
+	1, 16,
+	0x00, //         
+	0x18, //    ##   
+	0x24, //   #  #  
+	0x04, //      #  
+	0x18, //    ##   
+	0x04, //      #  
+	0x24, //   #  #  
+	0x18, //    ##   
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00  //         
+};
+
+/*
+ *  'EE'
+ */
+static const uint8_t Font16_180[] = {
+	8, 16,
+	1, 16,
+	0x00, //         
+	0x0C, //     ##  
+	0x18, //    ##   
+	0x30, //   ##    
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00  //         
+};
+
+/*
+ *  'OO'
+ */
+static const uint8_t Font16_181[] = {
+	8, 16,
+	1, 16,
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x22, //   #   # 
+	0x22, //   #   # 
+	0x22, //   #   # 
+	0x44, //  #   #  
+	0x44, //  #   #  
+	0x6C, //  ## ##  
+	0x54, //  # # #  
+	0x82, // #     # 
+	0x80  // #       
+};
+
+/*
+ *  'KA'
+ */
+static const uint8_t Font16_182[] = {
+	8, 16,
+	1, 16,
+	0x00, //         
+	0x3C, //   ####  
+	0x74, //  ### #  
+	0x74, //  ### #  
+	0x74, //  ### #  
+	0x74, //  ### #  
+	0x34, //   ## #  
+	0x14, //    # #  
+	0x14, //    # #  
+	0x14, //    # #  
+	0x14, //    # #  
+	0x14, //    # #  
+	0x14, //    # #  
+	0x14, //    # #  
+	0x00, //         
+	0x00  //         
+};
+
+/*
+ *  'KI'
+ */
+static const uint8_t Font16_183[] = {
+	8, 16,
+	1, 16,
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x18, //    ##   
+	0x18, //    ##   
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00  //         
+};
+
+/*
+ *  'KU'
+ */
+static const uint8_t Font16_184[] = {
+	8, 16,
+	1, 16,
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x0C, //     ##  
+	0x08, //     #   
+	0x10  //    #    
+};
+
+/*
+ *  'KE'
+ */
+static const uint8_t Font16_185[] = {
+	8, 16,
+	1, 16,
+	0x00, //         
+	0x08, //     #   
+	0x18, //    ##   
+	0x28, //   # #   
+	0x08, //     #   
+	0x08, //     #   
+	0x08, //     #   
+	0x08, //     #   
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00  //         
+};
+
+/*
+ *  'KO'
+ */
+static const uint8_t Font16_186[] = {
+	8, 16,
+	1, 16,
+	0x00, //         
+	0x18, //    ##   
+	0x24, //   #  #  
+	0x24, //   #  #  
+	0x24, //   #  #  
+	0x24, //   #  #  
+	0x18, //    ##   
+	0x00, //         
+	0x3C, //   ####  
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00  //         
+};
+
+/*
+ *  'SA'
+ */
+static const uint8_t Font16_187[] = {
+	8, 16,
+	1, 16,
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x90, // #  #    
+	0x48, //  #  #   
+	0x24, //   #  #  
+	0x12, //    #  # 
+	0x09, //     #  #
+	0x09, //     #  #
+	0x12, //    #  # 
+	0x24, //   #  #  
+	0x48, //  #  #   
+	0x90, // #  #    
+	0x00, //         
+	0x00  //         
+};
+
+/*
+ *  'SI'
+ */
+static const uint8_t Font16_188[] = {
+	8, 16,
+	1, 16,
+	0x00, //         
+	0x40, //  #      
+	0xC4, // ##   #  
+	0x44, //  #   #  
+	0x48, //  #  #   
+	0x48, //  #  #   
+	0x50, //  # #    
+	0x12, //    #  # 
+	0x22, //   #   # 
+	0x26, //   #  ## 
+	0x4A, //  #  # # 
+	0x5F, //  # #####
+	0x82, // #     # 
+	0x82, // #     # 
+	0x00, //         
+	0x00  //         
+};
+
+/*
+ *  'SU'
+ */
+static const uint8_t Font16_189[] = {
+	8, 16,
+	1, 16,
+	0x00, //         
+	0x40, //  #      
+	0xC4, // ##   #  
+	0x44, //  #   #  
+	0x48, //  #  #   
+	0x48, //  #  #   
+	0x50, //  # #    
+	0x1C, //    ###  
+	0x32, //   ##  # 
+	0x22, //   #   # 
+	0x44, //  #   #  
+	0x48, //  #  #   
+	0x88, // #   #   
+	0x9E, // #  #### 
+	0x00, //         
+	0x00  //         
+};
+
+/*
+ *  'SE'
+ */
+static const uint8_t Font16_190[] = {
+	8, 16,
+	1, 16,
+	0x00, //         
+	0x60, //  ##     
+	0x92, // #  #  # 
+	0x12, //    #  # 
+	0x64, //  ##  #  
+	0x14, //    # #  
+	0x98, // #  ##   
+	0x6A, //  ## # # 
+	0x12, //    #  # 
+	0x16, //    # ## 
+	0x2A, //   # # # 
+	0x3F, //   ######
+	0x42, //  #    # 
+	0x42, //  #    # 
+	0x00, //         
+	0x00, //         
+};
+
+/*
+ *  'SO'
+ */
+static const uint8_t Font16_191[] = {
+	8, 16,
+	1, 16,
+	0x08, //     #   
+	0x08, //     #   
+	0x00, //         
+	0x00, //         
+	0x08, //     #   
+	0x08, //     #   
+	0x08, //     #   
+	0x10, //    #    
+	0x20, //   #     
+	0x20, //   #     
+	0x41, //  #     #
+	0x41, //  #     #
+	0x41, //  #     #
+	0x22, //   #   # 
+	0x1C, //    ###  
+	0x00  //         
+};
+
+/*
+ *  'TA'
+ */
+static const uint8_t Font16_192[] = {
+	8, 16,
+	1, 16,
+	0x30, //   ##    
+	0x10, //    #    
+	0x08, //     #   
+	0x10, //    #    
+	0x10, //    #    
+	0x28, //   # #   
+	0x28, //   # #   
+	0x44, //  #   #  
+	0x44, //  #   #  
+	0x7C, //  #####  
+	0x82, // #     # 
+	0x82, // #     # 
+	0x82, // #     # 
+	0x82, // #     # 
+	0x00, //         
+	0x00  //         
+};
+
+/*
+ *  'TI'
+ */
+static const uint8_t Font16_193[] = {
+	8, 16,
+	1, 16,
+	0x18, //    ##   
+	0x10, //    #    
+	0x20, //   #     
+	0x10, //    #    
+	0x10, //    #    
+	0x28, //   # #   
+	0x28, //   # #   
+	0x44, //  #   #  
+	0x44, //  #   #  
+	0x7C, //  #####  
+	0x82, // #     # 
+	0x82, // #     # 
+	0x82, // #     # 
+	0x82, // #     # 
+	0x00, //         
+	0x00  //         
+};
+
+/*
+ *  'TU'
+ */
+static const uint8_t Font16_194[] = {
+	8, 16,
+	1, 16,
+	0x10, //    #    
+	0x38, //   ###   
+	0x44, //  #   #  
+	0x10, //    #    
+	0x10, //    #    
+	0x28, //   # #   
+	0x28, //   # #   
+	0x44, //  #   #  
+	0x44, //  #   #  
+	0x7C, //  #####  
+	0x82, // #     # 
+	0x82, // #     # 
+	0x82, // #     # 
+	0x82, // #     # 
+	0x00, //         
+	0x00  //         
+};
+
+/*
+ *  'TE'
+ */
+static const uint8_t Font16_195[] = {
+	8, 16,
+	1, 16,
+	0x34, //   ## #  
+	0x58, //  # ##   
+	0x00, //         
+	0x10, //    #    
+	0x10, //    #    
+	0x28, //   # #   
+	0x28, //   # #   
+	0x44, //  #   #  
+	0x44, //  #   #  
+	0x7C, //  #####  
+	0x82, // #     # 
+	0x82, // #     # 
+	0x82, // #     # 
+	0x82, // #     # 
+	0x00, //         
+	0x00  //         
+};
+
+/*
+ *  'TO'
+ */
+static const uint8_t Font16_196[] = {
+	8, 16,
+	1, 16,
+	0x44, //  #   #  
+	0x44, //  #   #  
+	0x00, //         
+	0x10, //    #    
+	0x10, //    #    
+	0x28, //   # #   
+	0x28, //   # #   
+	0x44, //  #   #  
+	0x44, //  #   #  
+	0x7C, //  #####  
+	0x82, // #     # 
+	0x82, // #     # 
+	0x82, // #     # 
+	0x82, // #     # 
+	0x00, //         
+	0x00  //         
+};
+
+/*
+ *  'NA'
+ */
+static const uint8_t Font16_197[] = {
+	8, 16,
+	1, 16,
+	0x10, //    #    
+	0x28, //   # #   
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0x28, //   # #   
+	0x28, //   # #   
+	0x44, //  #   #  
+	0x44, //  #   #  
+	0x7C, //  #####  
+	0x82, // #     # 
+	0x82, // #     # 
+	0x82, // #     # 
+	0x82, // #     # 
+	0x00, //         
+	0x00  //         
+};
+
+/*
+ *  'NI'
+ */
+static const uint8_t Font16_198[] = {
+	8, 16,
+	1, 16,
+	0x00, //         
+	0x00, //         
+	0x1F, //    #####
+	0x28, //   # #   
+	0x28, //   # #   
+	0x28, //   # #   
+	0x2E, //   # ### 
+	0x48, //  #  #   
+	0x48, //  #  #   
+	0x78, //  ####   
+	0x88, // #   #   
+	0x88, // #   #   
+	0x88, // #   #   
+	0x8F, // #   ####
+	0x00, //         
+	0x00  //         
+};
+
+/*
+ *  'NU'
+ */
+static const uint8_t Font16_199[] = {
+	8, 16,
+	1, 16,
+	0x00, //         
+	0x38, //   ###   
+	0x44, //  #   #  
+	0x42, //  #    # 
+	0x80, // #       
+	0x80, // #       
+	0x80, // #       
+	0x80, // #       
+	0x80, // #       
+	0x80, // #       
+	0x42, //  #    # 
+	0x44, //  #   #  
+	0x38, //   ###   
+	0x08, //     #   
+	0x08, //     #   
+	0x10  //    #    
+};
+
+/*
+ *  'NE'
+ */
+static const uint8_t Font16_200[] = {
+	8, 16,
+	1, 16,
+	0x30, //   ##    
+	0x10, //    #    
+	0x08, //     #   
+	0xFE, // ####### 
+	0x80, // #       
+	0x80, // #       
+	0x80, // #       
+	0xFC, // ######  
+	0x80, // #       
+	0x80, // #       
+	0x80, // #       
+	0x80, // #       
+	0x80, // #       
+	0xFE, // ####### 
+	0x00, //         
+	0x00  //         
+};
+
+/*
+ *  'NO'
+ */
+static const uint8_t Font16_201[] = {
+	8, 16,
+	1, 16,
+	0x18, //    ##   
+	0x10, //    #    
+	0x20, //   #     
+	0xFE, // ####### 
+	0x80, // #       
+	0x80, // #       
+	0x80, // #       
+	0xFC, // ######  
+	0x80, // #       
+	0x80, // #       
+	0x80, // #       
+	0x80, // #       
+	0x80, // #       
+	0xFE, // ####### 
+	0x00, //         
+	0x00  //         
+};
+
+/*
+ *  'HA'
+ */
+static const uint8_t Font16_202[] = {
+	8, 16,
+	1, 16,
+	0x10, //    #    
+	0x38, //   ###   
+	0x44, //  #   #  
+	0xFE, // ####### 
+	0x80, // #       
+	0x80, // #       
+	0x80, // #       
+	0xFC, // ######  
+	0x80, // #       
+	0x80, // #       
+	0x80, // #       
+	0x80, // #       
+	0x80, // #       
+	0xFE, // ####### 
+	0x00, //         
+	0x00  //         
+};
+
+/*
+ *  'HI'
+ */
+static const uint8_t Font16_203[] = {
+	8, 16,
+	1, 16,
+	0x44, //  #   #  
+	0x44, //  #   #  
+	0x00, //         
+	0xFE, // ####### 
+	0x80, // #       
+	0x80, // #       
+	0x80, // #       
+	0xFC, // ######  
+	0x80, // #       
+	0x80, // #       
+	0x80, // #       
+	0x80, // #       
+	0x80, // #       
+	0xFE, // ####### 
+	0x00, //         
+	0x00  //         
+};
+
+/*
+ *  'HU'
+ */
+static const uint8_t Font16_204[] = {
+	8, 16,
+	1, 16,
+	0x30, //   ##    
+	0x10, //    #    
+	0x08, //     #   
+	0x38, //   ###   
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0x38, //   ###   
+	0x00, //         
+	0x00  //         
+};
+
+/*
+ *  'HE'
+ */
+static const uint8_t Font16_205[] = {
+	8, 16,
+	1, 16,
+	0x18, //    ##   
+	0x10, //    #    
+	0x20, //   #     
+	0x38, //   ###   
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0x38, //   ###   
+	0x00, //         
+	0x00  //         
+};
+
+/*
+ *  'HO'
+ */
+static const uint8_t Font16_206[] = {
+	8, 16,
+	1, 16,
+	0x10, //    #    
+	0x38, //   ###   
+	0x44, //  #   #  
+	0x38, //   ###   
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0x38, //   ###   
+	0x00, //         
+	0x00  //         
+};
+
+/*
+ *  'MA'
+ */
+static const uint8_t Font16_207[] = {
+	8, 16,
+	1, 16,
+	0x44, //  #   #  
+	0x44, //  #   #  
+	0x00, //         
+	0x38, //   ###   
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0x38, //   ###   
+	0x00, //         
+	0x00  //         
+};
+
+/*
+ *  'MI'
+ */
+static const uint8_t Font16_208[] = {
+	8, 16,
+	1, 16,
+	0x00, //         
+	0x70, //  ###    
+	0x48, //  #  #   
+	0x44, //  #   #  
+	0x44, //  #   #  
+	0x42, //  #    # 
+	0x42, //  #    # 
+	0xF2, // ####  # 
+	0x42, //  #    # 
+	0x42, //  #    # 
+	0x44, //  #   #  
+	0x44, //  #   #  
+	0x48, //  #  #   
+	0x70, //  ###    
+	0x00, //         
+	0x00  //         
+};
+
+/*
+ *  'MU'
+ */
+static const uint8_t Font16_209[] = {
+	8, 16,
+	1, 16,
+	0x34, //   ## #  
+	0x58, //  # ##   
+	0x82, // #     # 
+	0x82, // #     # 
+	0xC2, // ##    # 
+	0xC2, // ##    # 
+	0xA2, // # #   # 
+	0xA2, // # #   # 
+	0x92, // #  #  # 
+	0x8A, // #   # # 
+	0x8A, // #   # # 
+	0x86, // #    ## 
+	0x86, // #    ## 
+	0x82, // #     # 
+	0x00, //         
+	0x00  //         
+};
+
+/*
+ *  'ME'
+ */
+static const uint8_t Font16_210[] = {
+	8, 16,
+	1, 16,
+	0x30, //   ##    
+	0x10, //    #    
+	0x08, //     #   
+	0x38, //   ###   
+	0x44, //  #   #  
+	0x82, // #     # 
+	0x82, // #     # 
+	0x82, // #     # 
+	0x82, // #     # 
+	0x82, // #     # 
+	0x82, // #     # 
+	0x82, // #     # 
+	0x44, //  #   #  
+	0x38, //   ###   
+	0x00, //         
+	0x00  //         
+};
+
+/*
+ *  'MO'
+ */
+static const uint8_t Font16_211[] = {
+	8, 16,
+	1, 16,
+	0x18, //    ##   
+	0x10, //    #    
+	0x20, //   #     
+	0x38, //   ###   
+	0x44, //  #   #  
+	0x82, // #     # 
+	0x82, // #     # 
+	0x82, // #     # 
+	0x82, // #     # 
+	0x82, // #     # 
+	0x82, // #     # 
+	0x82, // #     # 
+	0x44, //  #   #  
+	0x38, //   ###   
+	0x00, //         
+	0x00  //         
+};
+
+/*
+ *  'YA'
+ */
+static const uint8_t Font16_212[] = {
+	8, 16,
+	1, 16,
+	0x10, //    #    
+	0x38, //   ###   
+	0x44, //  #   #  
+	0x38, //   ###   
+	0x44, //  #   #  
+	0x82, // #     # 
+	0x82, // #     # 
+	0x82, // #     # 
+	0x82, // #     # 
+	0x82, // #     # 
+	0x82, // #     # 
+	0x82, // #     # 
+	0x44, //  #   #  
+	0x38, //   ###   
+	0x00, //         
+	0x00  //         
+};
+
+/*
+ *  'YU'
+ */
+static const uint8_t Font16_213[] = {
+	8, 16,
+	1, 16,
+	0x34, //   ## #  
+	0x58, //  # ##   
+	0x00, //         
+	0x38, //   ###   
+	0x44, //  #   #  
+	0x82, // #     # 
+	0x82, // #     # 
+	0x82, // #     # 
+	0x82, // #     # 
+	0x82, // #     # 
+	0x82, // #     # 
+	0x82, // #     # 
+	0x44, //  #   #  
+	0x38, //   ###   
+	0x00, //         
+	0x00  //         
+};
+
+/*
+ *  'YO'
+ */
+static const uint8_t Font16_214[] = {
+	8, 16,
+	1, 16,
+	0x44, //  #   #  
+	0x44, //  #   #  
+	0x00, //         
+	0x38, //   ###   
+	0x44, //  #   #  
+	0x82, // #     # 
+	0x82, // #     # 
+	0x82, // #     # 
+	0x82, // #     # 
+	0x82, // #     # 
+	0x82, // #     # 
+	0x82, // #     # 
+	0x44, //  #   #  
+	0x38, //   ###   
+	0x00, //         
+	0x00  //         
+};
+
+/*
+ *  'RA'
+ */
+static const uint8_t Font16_215[] = {
+	8, 16,
+	1, 16,
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x81, // #      #
+	0x42, //  #    # 
+	0x24, //   #  #  
+	0x18, //    ##   
+	0x18, //    ##   
+	0x24, //   #  #  
+	0x42, //  #    # 
+	0x81, // #      #
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00  //         
+};
+
+/*
+ *  'RI'
+ */
+static const uint8_t Font16_216[] = {
+	8, 16,
+	1, 16,
+	0x02, //       # 
+	0x02, //       # 
+	0x3C, //   ####  
+	0x44, //  #   #  
+	0x86, // #    ## 
+	0x8A, // #   # # 
+	0x8A, // #   # # 
+	0x92, // #  #  # 
+	0x92, // #  #  # 
+	0xA2, // # #   # 
+	0xA2, // # #   # 
+	0xC2, // ##    # 
+	0x44, //  #   #  
+	0x78, //  ####   
+	0x80, // #       
+	0x80  // #       
+};
+
+/*
+ *  'RU'
+ */
+static const uint8_t Font16_217[] = {
+	8, 16,
+	1, 16,
+	0x30, //   ##    
+	0x10, //    #    
+	0x08, //     #   
+	0x82, // #     # 
+	0x82, // #     # 
+	0x82, // #     # 
+	0x82, // #     # 
+	0x82, // #     # 
+	0x82, // #     # 
+	0x82, // #     # 
+	0x82, // #     # 
+	0x82, // #     # 
+	0x44, //  #   #  
+	0x38, //   ###   
+	0x00, //         
+	0x00  //         
+};
+
+/*
+ *  'RE'
+ */
+static const uint8_t Font16_218[] = {
+	8, 16,
+	1, 16,
+	0x18, //    ##   
+	0x10, //    #    
+	0x20, //   #     
+	0x82, // #     # 
+	0x82, // #     # 
+	0x82, // #     # 
+	0x82, // #     # 
+	0x82, // #     # 
+	0x82, // #     # 
+	0x82, // #     # 
+	0x82, // #     # 
+	0x82, // #     # 
+	0x44, //  #   #  
+	0x38, //   ###   
+	0x00, //         
+	0x00  //         
+};
+
+/*
+ *  'RO'
+ */
+static const uint8_t Font16_219[] = {
+	8, 16,
+	1, 16,
+	0x10, //    #    
+	0x38, //   ###   
+	0x44, //  #   #  
+	0x00, //         
+	0x82, // #     # 
+	0x82, // #     # 
+	0x82, // #     # 
+	0x82, // #     # 
+	0x82, // #     # 
+	0x82, // #     # 
+	0x82, // #     # 
+	0x82, // #     # 
+	0x44, //  #   #  
+	0x38, //   ###   
+	0x00, //         
+	0x00  //         
+};
+
+/*
+ *  'WA'
+ */
+static const uint8_t Font16_220[] = {
+	8, 16,
+	1, 16,
+	0x44, //  #   #  
+	0x44, //  #   #  
+	0x00, //         
+	0x82, // #     # 
+	0x82, // #     # 
+	0x82, // #     # 
+	0x82, // #     # 
+	0x82, // #     # 
+	0x82, // #     # 
+	0x82, // #     # 
+	0x82, // #     # 
+	0x82, // #     # 
+	0x44, //  #   #  
+	0x38, //   ###   
+	0x00, //         
+	0x00, //         
+};
+
+/*
+ *  'NN'
+ */
+static const uint8_t Font16_221[] = {
+	8, 16,
+	1, 16,
+	0x18, //    ##   
+	0x10, //    #    
+	0xA2, // # #   # 
+	0x82, // #     # 
+	0x44, //  #   #  
+	0x44, //  #   #  
+	0x28, //   # #   
+	0x28, //   # #   
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0x00, //         
+	0x00  //         
+};
+
+/*
+ *  dakuten
+ */
+static const uint8_t Font16_222[] = {
+	8, 16,
+	1, 16,
+	0x80, // #       
+	0x80, // #       
+	0xF8, // #####   
+	0x84, // #    #  
+	0x82, // #     # 
+	0x82, // #     # 
+	0x84, // #    #  
+	0xF8, // #####   
+	0x80, // #       
+	0x80, // #       
+	0x80, // #       
+	0x80, // #       
+	0x80, // #       
+	0x80, // #       
+	0x00, //         
+	0x00  //         
+};
+
+/*
+ *  maru
+ */
+static const uint8_t Font16_223[] = {
+	8, 16,
+	1, 16,
+	0x00, //         
+	0x78, //  ####   
+	0x84, // #    #  
+	0x82, // #     # 
+	0x82, // #     # 
+	0x84, // #    #  
+	0xB8, // # ###   
+	0x84, // #    #  
+	0x82, // #     # 
+	0x82, // #     # 
+	0x82, // #     # 
+	0x82, // #     # 
+	0x84, // #    #  
+	0xB8, // # ###   
+	0x00, //         
+	0x00  //         
+};
+
+/*
+ *  224
+ */
+static const uint8_t Font16_224[] = {
+	8, 16,
+	1, 16,
+	0x00, //         
+	0x30, //   ##    
+	0x10, //    #    
+	0x08, //     #   
+	0x00, //         
+	0x3C, //   ####  
+	0x42, //  #    # 
+	0x02, //       # 
+	0x3E, //   ##### 
+	0x42, //  #    # 
+	0x82, // #     # 
+	0x82, // #     # 
+	0x86, // #    ## 
+	0x7A, //  #### # 
+	0x00, //         
+	0x00  //         
+};
+
+/*
+ *  225
+ */
+static const uint8_t Font16_225[] = {
+	8, 16,
+	1, 16,
+	0x00, //         
+	0x18, //    ##   
+	0x10, //    #    
+	0x20, //   #     
+	0x00, //         
+	0x3C, //   ####  
+	0x42, //  #    # 
+	0x02, //       # 
+	0x3E, //   ##### 
+	0x42, //  #    # 
+	0x82, // #     # 
+	0x82, // #     # 
+	0x86, // #    ## 
+	0x7A, //  #### # 
+	0x00, //         
+	0x00  //         
+};
+
+/*
+ *  226
+ */
+static const uint8_t Font16_226[] = {
+	8, 16,
+	1, 16,
+	0x00, //         
+	0x10, //    #    
+	0x38, //   ###   
+	0x44, //  #   #  
+	0x00, //         
+	0x3C, //   ####  
+	0x42, //  #    # 
+	0x02, //       # 
+	0x3E, //   ##### 
+	0x42, //  #    # 
+	0x82, // #     # 
+	0x82, // #     # 
+	0x86, // #    ## 
+	0x7A, //  #### # 
+	0x00, //         
+	0x00  //         
+};
+
+/*
+ *  227
+ */
+static const uint8_t Font16_227[] = {
+	8, 16,
+	1, 16,
+	0x00, //         
+	0x34, //   ## #  
+	0x58, //  # ##   
+	0x00, //         
+	0x00, //         
+	0x3C, //   ####  
+	0x42, //  #    # 
+	0x02, //       # 
+	0x3E, //   ##### 
+	0x42, //  #    # 
+	0x82, // #     # 
+	0x82, // #     # 
+	0x86, // #    ## 
+	0x7A, //  #### # 
+	0x00, //         
+	0x00  //         
+};
+
+/*
+ *  228
+ */
+static const uint8_t Font16_228[] = {
+	8, 16,
+	1, 16,
+	0x00, //         
+	0x00, //         
+	0x24, //   #  #  
+	0x24, //   #  #  
+	0x00, //         
+	0x3C, //   ####  
+	0x42, //  #    # 
+	0x02, //       # 
+	0x3E, //   ##### 
+	0x42, //  #    # 
+	0x82, // #     # 
+	0x82, // #     # 
+	0x86, // #    ## 
+	0x7A, //  #### # 
+	0x00, //         
+	0x00  //         
+};
+
+/*
+ *  229
+ */
+static const uint8_t Font16_229[] = {
+	8, 16,
+	1, 16,
+	0x00, //         
+	0x10, //    #    
+	0x28, //   # #   
+	0x10, //    #    
+	0x00, //         
+	0x3C, //   ####  
+	0x42, //  #    # 
+	0x02, //       # 
+	0x3E, //   ##### 
+	0x42, //  #    # 
+	0x82, // #     # 
+	0x82, // #     # 
+	0x86, // #    ## 
+	0x7A, //  #### # 
+	0x00, //         
+	0x00  //         
+};
+
+/*
+ *  230
+ */
+static const uint8_t Font16_230[] = {
+	8, 16,
+	1, 16,
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x6C, //  ## ##  
+	0x92, // #  #  # 
+	0x12, //    #  # 
+	0x3E, //   ##### 
+	0x50, //  # #    
+	0x90, // #  #    
+	0x92, // #  #  # 
+	0x92, // #  #  # 
+	0x6C, //  ## ##  
+	0x00, //         
+	0x00  //         
+};
+
+/*
+ *  231
+ */
+static const uint8_t Font16_231[] = {
+	8, 16,
+	1, 16,
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x38, //   ###   
+	0x44, //  #   #  
+	0x82, // #     # 
+	0x80, // #       
+	0x80, // #       
+	0x80, // #       
+	0x82, // #     # 
+	0x44, //  #   #  
+	0x38, //   ###   
+	0x10, //    #    
+	0x10, //    #    
+	0x20  //   #     
+};
+
+/*
+ *  232
+ */
+static const uint8_t Font16_232[] = {
+	8, 16,
+	1, 16,
+	0x00, //         
+	0x30, //   ##    
+	0x10, //    #    
+	0x08, //     #   
+	0x00, //         
+	0x38, //   ###   
+	0x44, //  #   #  
+	0x82, // #     # 
+	0x82, // #     # 
+	0xFE, // ####### 
+	0x80, // #       
+	0x82, // #     # 
+	0x44, //  #   #  
+	0x38, //   ###   
+	0x00, //         
+	0x00  //         
+};
+
+/*
+ *  233
+ */
+static const uint8_t Font16_233[] = {
+	8, 16,
+	1, 16,
+	0x00, //         
+	0x18, //    ##   
+	0x10, //    #    
+	0x20, //   #     
+	0x00, //         
+	0x38, //   ###   
+	0x44, //  #   #  
+	0x82, // #     # 
+	0x82, // #     # 
+	0xFE, // ####### 
+	0x80, // #       
+	0x82, // #     # 
+	0x44, //  #   #  
+	0x38, //   ###   
+	0x00, //         
+	0x00  //         
+};
+
+/*
+ *  234
+ */
+static const uint8_t Font16_234[] = {
+	8, 16,
+	1, 16,
+	0x00, //         
+	0x10, //    #    
+	0x38, //   ###   
+	0x44, //  #   #  
+	0x00, //         
+	0x38, //   ###   
+	0x44, //  #   #  
+	0x82, // #     # 
+	0x82, // #     # 
+	0xFE, // ####### 
+	0x80, // #       
+	0x82, // #     # 
+	0x44, //  #   #  
+	0x38, //   ###   
+	0x00, //         
+	0x00  //         
+};
+
+/*
+ *  235
+ */
+static const uint8_t Font16_235[] = {
+	8, 16,
+	1, 16,
+	0x00, //         
+	0x44, //  #   #  
+	0x44, //  #   #  
+	0x00, //         
+	0x00, //         
+	0x38, //   ###   
+	0x44, //  #   #  
+	0x82, // #     # 
+	0x82, // #     # 
+	0xFE, // ####### 
+	0x80, // #       
+	0x82, // #     # 
+	0x44, //  #   #  
+	0x38, //   ###   
+	0x00, //         
+	0x00  //         
+};
+
+/*
+ *  236
+ */
+static const uint8_t Font16_236[] = {
+	8, 16,
+	1, 16,
+	0x00, //         
+	0x30, //   ##    
+	0x10, //    #    
+	0x08, //     #   
+	0x00, //         
+	0x30, //   ##    
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0x00, //         
+	0x00  //         
+};
+
+/*
+ *  237
+ */
+static const uint8_t Font16_237[] = {
+	8, 16,
+	1, 16,
+	0x00, //         
+	0x18, //    ##   
+	0x10, //    #    
+	0x20, //   #     
+	0x00, //         
+	0x30, //   ##    
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0x00, //         
+	0x00  //         
+};
+
+/*
+ *  238
+ */
+static const uint8_t Font16_238[] = {
+	8, 16,
+	1, 16,
+	0x00, //         
+	0x10, //    #    
+	0x38, //   ###   
+	0x44, //  #   #  
+	0x00, //         
+	0x30, //   ##    
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0x00, //         
+	0x00  //         
+};
+
+/*
+ *  239
+ */
+static const uint8_t Font16_239[] = {
+	8, 16,
+	1, 16,
+	0x00, //         
+	0x44, //  #   #  
+	0x44, //  #   #  
+	0x00, //         
+	0x00, //         
+	0x30, //   ##    
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0x10, //    #    
+	0x00, //         
+	0x00  //         
+};
+
+/*
+ *  240
+ */
+static const uint8_t Font16_240[] = {
+	8, 16,
+	1, 16,
+	0x00, //         
+	0x64, //  ##  #  
+	0x18, //    ##   
+	0x30, //   ##    
+	0x48, //  #  #   
+	0x38, //   ###   
+	0x44, //  #   #  
+	0x82, // #     # 
+	0x82, // #     # 
+	0x82, // #     # 
+	0x82, // #     # 
+	0x82, // #     # 
+	0x44, //  #   #  
+	0x38, //   ###   
+	0x00, //         
+	0x00  //         
+};
+
+/*
+ *  241
+ */
+static const uint8_t Font16_241[] = {
+	8, 16,
+	1, 16,
+	0x00, //         
+	0x34, //   ## #  
+	0x58, //  # ##   
+	0x00, //         
+	0x00, //         
+	0x5C, //  # ###  
+	0x62, //  ##   # 
+	0x42, //  #    # 
+	0x42, //  #    # 
+	0x42, //  #    # 
+	0x42, //  #    # 
+	0x42, //  #    # 
+	0x42, //  #    # 
+	0x42, //  #    # 
+	0x00, //         
+	0x00  //         
+};
+
+/*
+ *  242
+ */
+static const uint8_t Font16_242[] = {
+	8, 16,
+	1, 16,
+	0x00, //         
+	0x30, //   ##    
+	0x10, //    #    
+	0x08, //     #   
+	0x00, //         
+	0x38, //   ###   
+	0x44, //  #   #  
+	0x82, // #     # 
+	0x82, // #     # 
+	0x82, // #     # 
+	0x82, // #     # 
+	0x82, // #     # 
+	0x44, //  #   #  
+	0x38, //   ###   
+	0x00, //         
+	0x00  //         
+};
+
+/*
+ *  243
+ */
+static const uint8_t Font16_243[] = {
+	8, 16,
+	1, 16,
+	0x00, //         
+	0x18, //    ##   
+	0x10, //    #    
+	0x20, //   #     
+	0x00, //         
+	0x38, //   ###   
+	0x44, //  #   #  
+	0x82, // #     # 
+	0x82, // #     # 
+	0x82, // #     # 
+	0x82, // #     # 
+	0x82, // #     # 
+	0x44, //  #   #  
+	0x38, //   ###   
+	0x00, //         
+	0x00  //         
+};
+
+/*
+ *  244
+ */
+static const uint8_t Font16_244[] = {
+	8, 16,
+	1, 16,
+	0x00, //         
+	0x10, //    #    
+	0x38, //   ###   
+	0x44, //  #   #  
+	0x00, //         
+	0x38, //   ###   
+	0x44, //  #   #  
+	0x82, // #     # 
+	0x82, // #     # 
+	0x82, // #     # 
+	0x82, // #     # 
+	0x82, // #     # 
+	0x44, //  #   #  
+	0x38, //   ###   
+	0x00, //         
+	0x00  //         
+};
+
+/*
+ *  245
+ */
+static const uint8_t Font16_245[] = {
+	8, 16,
+	1, 16,
+	0x00, //         
+	0x34, //   ## #  
+	0x58, //  # ##   
+	0x00, //         
+	0x00, //         
+	0x38, //   ###   
+	0x44, //  #   #  
+	0x82, // #     # 
+	0x82, // #     # 
+	0x82, // #     # 
+	0x82, // #     # 
+	0x82, // #     # 
+	0x44, //  #   #  
+	0x38, //   ###   
+	0x00, //         
+	0x00  //         
+};
+
+/*
+ *  246
+ */
+static const uint8_t Font16_246[] = {
+	8, 16,
+	1, 16,
+	0x00, //       
+	0x50, //  # #  
+	0x00, //       
+	0x70, //  ###  
+	0x88, // #   # 
+	0x88, // #   # 
+	0x88, // #   # 
+	0x88, // #   # 
+	0x88, // #   # 
+	0x70, //  ###  
+	0x00, //       
+	0x00  //       
+};
+
+/*
+ *  247
+ */
+static const uint8_t Font16_247[] = {
+	8, 16,
+	1, 16,
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x10, //    #    
+	0x10, //    #    
+	0x00, //         
+	0xFE, // ####### 
+	0x00, //         
+	0x10, //    #    
+	0x10, //    #    
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00  //         
+};
+
+/*
+ *  248
+ */
+static const uint8_t Font16_248[] = {
+	8, 16,
+	1, 16,
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x00, //         
+	0x3A, //   ### # 
+	0x44, //  #   #  
+	0x8A, // #   # # 
+	0x8A, // #   # # 
+	0x92, // #  #  # 
+	0xA2, // # #   # 
+	0xA2, // # #   # 
+	0x44, //  #   #  
+	0xB8, // # ###   
+	0x00, //         
+	0x00  //         
+};
+
+/*
+ *  249
+ */
+static const uint8_t Font16_249[] = {
+	8, 16,
+	1, 16,
+	0x00, //         
+	0x30, //   ##    
+	0x10, //    #    
+	0x08, //     #   
+	0x00, //         
+	0x42, //  #    # 
+	0x42, //  #    # 
+	0x42, //  #    # 
+	0x42, //  #    # 
+	0x42, //  #    # 
+	0x42, //  #    # 
+	0x42, //  #    # 
+	0x46, //  #   ## 
+	0x3A, //   ### # 
+	0x00, //         
+	0x00  //         
+};
+
+/*
+ *  250
+ */
+static const uint8_t Font16_250[] = {
+	8, 16,
+	1, 16,
+	0x00, //         
+	0x18, //    ##   
+	0x10, //    #    
+	0x20, //   #     
+	0x00, //         
+	0x42, //  #    # 
+	0x42, //  #    # 
+	0x42, //  #    # 
+	0x42, //  #    # 
+	0x42, //  #    # 
+	0x42, //  #    # 
+	0x42, //  #    # 
+	0x46, //  #   ## 
+	0x3A, //   ### # 
+	0x00, //         
+	0x00  //         
+};
+
+/*
+ *  251
+ */
+static const uint8_t Font16_251[] = {
+	8, 16,
+	1, 16,
+	0x00, //         
+	0x10, //    #    
+	0x38, //   ###   
+	0x44, //  #   #  
+	0x00, //         
+	0x42, //  #    # 
+	0x42, //  #    # 
+	0x42, //  #    # 
+	0x42, //  #    # 
+	0x42, //  #    # 
+	0x42, //  #    # 
+	0x42, //  #    # 
+	0x46, //  #   ## 
+	0x3A, //   ### # 
+	0x00, //         
+	0x00  //         
+};
+
+/*
+ *  252
+ */
+static const uint8_t Font16_252[] = {
+	8, 16,
+	1, 16,
+	0x00, //         
+	0x24, //   #  #  
+	0x24, //   #  #  
+	0x00, //         
+	0x00, //         
+	0x42, //  #    # 
+	0x42, //  #    # 
+	0x42, //  #    # 
+	0x42, //  #    # 
+	0x42, //  #    # 
+	0x42, //  #    # 
+	0x42, //  #    # 
+	0x46, //  #   ## 
+	0x3A, //   ### # 
+	0x00, //         
+	0x00  //         
+};
+
+/*
+ *  253
+ */
+static const uint8_t Font16_253[] = {
+	8, 16,
+	1, 16,
+	0x00, //         
+	0x0C, //     ##  
+	0x08, //     #   
+	0x10, //    #    
+	0x00, //         
+	0x42, //  #    # 
+	0x42, //  #    # 
+	0x22, //   #   # 
+	0x24, //   #  #  
+	0x14, //    # #  
+	0x08, //     #   
+	0x08, //     #   
+	0x10, //    #    
+	0x10, //    #    
+	0x20, //   #     
+	0x40  //  #      
+};
+
+/*
+ *  254
+ */
+static const uint8_t Font16_254[] = {
+	8, 16,
+	1, 16,
+	/* 253 */
+	0x00, //         
+	0x00, //         
+	0x40, //  #      
+	0x40, //  #      
+	0x40, //  #      
+	0x78, //  ####   
+	0x44, //  #   #  
+	0x42, //  #    # 
+	0x42, //  #    # 
+	0x42, //  #    # 
+	0x44, //  #   #  
+	0x78, //  ####   
+	0x40, //  #      
+	0x40, //  #      
+	0x40, //  #      
+	0x40  //  #      
+};
+
+/*
+ *  255
+ */
+static const uint8_t Font16_255[] = {
+	8, 16,
+	1, 16,
+	0x00, //         
+	0x24, //   #  #  
+	0x24, //   #  #  
+	0x00, //         
+	0x00, //         
+	0x42, //  #    # 
+	0x42, //  #    # 
+	0x22, //   #   # 
+	0x24, //   #  #  
+	0x14, //    # #  
+	0x08, //     #   
+	0x08, //     #   
+	0x10, //    #    
+	0x10, //    #    
+	0x20, //   #     
+	0x40  //  #      
+};
+
+
+const font_t *Font16[] = {
+	(font_t *)Font16_32,  (font_t *)Font16_01,  (font_t *)Font16_02,  (font_t *)Font16_03,
+	(font_t *)Font16_04,  (font_t *)Font16_05,  (font_t *)Font16_06,  (font_t *)Font16_07,
+	(font_t *)Font16_08,  (font_t *)Font16_09,  (font_t *)Font16_10,  (font_t *)Font16_11,
+	(font_t *)Font16_12,  (font_t *)Font16_13,  (font_t *)Font16_14,  (font_t *)Font16_15,
+	(font_t *)Font16_16,  (font_t *)Font16_17,  (font_t *)Font16_18,  (font_t *)Font16_19,
+	(font_t *)Font16_20,  (font_t *)Font16_21,  (font_t *)Font16_22,  (font_t *)Font16_23,
+	(font_t *)Font16_24,  (font_t *)Font16_25,  (font_t *)Font16_26,  (font_t *)Font16_27,
+	(font_t *)Font16_28,  (font_t *)Font16_29,  (font_t *)Font16_30,  (font_t *)Font16_31,
+	(font_t *)Font16_32,  (font_t *)Font16_33,  (font_t *)Font16_34,  (font_t *)Font16_35,
+	(font_t *)Font16_36,  (font_t *)Font16_37,  (font_t *)Font16_38,  (font_t *)Font16_39,
+	(font_t *)Font16_40,  (font_t *)Font16_41,  (font_t *)Font16_42,  (font_t *)Font16_43,
+	(font_t *)Font16_44,  (font_t *)Font16_45,  (font_t *)Font16_46,  (font_t *)Font16_47,
+	(font_t *)Font16_48,  (font_t *)Font16_49,  (font_t *)Font16_50,  (font_t *)Font16_51,
+	(font_t *)Font16_52,  (font_t *)Font16_53,  (font_t *)Font16_54,  (font_t *)Font16_55,
+	(font_t *)Font16_56,  (font_t *)Font16_57,  (font_t *)Font16_58,  (font_t *)Font16_59,
+	(font_t *)Font16_60,  (font_t *)Font16_61,  (font_t *)Font16_62,  (font_t *)Font16_63,
+	(font_t *)Font16_64,  (font_t *)Font16_65,  (font_t *)Font16_66,  (font_t *)Font16_67,
+	(font_t *)Font16_68,  (font_t *)Font16_69,  (font_t *)Font16_70,  (font_t *)Font16_71,
+	(font_t *)Font16_72,  (font_t *)Font16_73,  (font_t *)Font16_74,  (font_t *)Font16_75,
+	(font_t *)Font16_76,  (font_t *)Font16_77,  (font_t *)Font16_78,  (font_t *)Font16_79,
+	(font_t *)Font16_80,  (font_t *)Font16_81,  (font_t *)Font16_82,  (font_t *)Font16_83,
+	(font_t *)Font16_84,  (font_t *)Font16_85,  (font_t *)Font16_86,  (font_t *)Font16_87,
+	(font_t *)Font16_88,  (font_t *)Font16_89,  (font_t *)Font16_90,  (font_t *)Font16_91,
+	(font_t *)Font16_92,  (font_t *)Font16_93,  (font_t *)Font16_94,  (font_t *)Font16_95,
+	(font_t *)Font16_96,  (font_t *)Font16_97,  (font_t *)Font16_98,  (font_t *)Font16_99,
+	(font_t *)Font16_100, (font_t *)Font16_101, (font_t *)Font16_102, (font_t *)Font16_103,
+	(font_t *)Font16_104, (font_t *)Font16_105, (font_t *)Font16_106, (font_t *)Font16_107,
+	(font_t *)Font16_108, (font_t *)Font16_109, (font_t *)Font16_110, (font_t *)Font16_111,
+	(font_t *)Font16_112, (font_t *)Font16_113, (font_t *)Font16_114, (font_t *)Font16_115,
+	(font_t *)Font16_116, (font_t *)Font16_117, (font_t *)Font16_118, (font_t *)Font16_119,
+	(font_t *)Font16_120, (font_t *)Font16_121, (font_t *)Font16_122, (font_t *)Font16_123,
+	(font_t *)Font16_124, (font_t *)Font16_125, (font_t *)Font16_126, (font_t *)Font16_127,
+
+	0,                    0,                    0,                    0,
+	0,                    0,                    0,                    0,
+	0,                    0,                    0,                    0,
+	0,                    0,                    0,                    0,
+	0,                    0,                    0,                    0,
+	0,                    0,                    0,                    0,
+	0,                    0,                    0,                    0,
+	0,                    0,                    0,                    0,
+	(font_t *)Font16_160, (font_t *)Font16_161, (font_t *)Font16_162, (font_t *)Font16_163,
+	(font_t *)Font16_164, (font_t *)Font16_165, (font_t *)Font16_166, (font_t *)Font16_167,
+	(font_t *)Font16_168, (font_t *)Font16_169, (font_t *)Font16_170, (font_t *)Font16_171,
+	(font_t *)Font16_172, (font_t *)Font16_173, (font_t *)Font16_174, (font_t *)Font16_175,
+	(font_t *)Font16_176, (font_t *)Font16_177, (font_t *)Font16_178, (font_t *)Font16_179,
+	(font_t *)Font16_180, (font_t *)Font16_181, (font_t *)Font16_182, (font_t *)Font16_183,
+	(font_t *)Font16_184, (font_t *)Font16_185, (font_t *)Font16_186, (font_t *)Font16_187,
+	(font_t *)Font16_188, (font_t *)Font16_189, (font_t *)Font16_190, (font_t *)Font16_191,
+	(font_t *)Font16_192, (font_t *)Font16_193, (font_t *)Font16_194, (font_t *)Font16_195,
+	(font_t *)Font16_196, (font_t *)Font16_197, (font_t *)Font16_198, (font_t *)Font16_199,
+	(font_t *)Font16_200, (font_t *)Font16_201, (font_t *)Font16_202, (font_t *)Font16_203,
+	(font_t *)Font16_204, (font_t *)Font16_205, (font_t *)Font16_206, (font_t *)Font16_207,
+	(font_t *)Font16_208, (font_t *)Font16_209, (font_t *)Font16_210, (font_t *)Font16_211,
+	(font_t *)Font16_212, (font_t *)Font16_213, (font_t *)Font16_214, (font_t *)Font16_215,
+	(font_t *)Font16_216, (font_t *)Font16_217, (font_t *)Font16_218, (font_t *)Font16_219,
+	(font_t *)Font16_220, (font_t *)Font16_221, (font_t *)Font16_222, (font_t *)Font16_223,
+	(font_t *)Font16_224, (font_t *)Font16_225, (font_t *)Font16_226, (font_t *)Font16_227,
+	(font_t *)Font16_228, (font_t *)Font16_229, (font_t *)Font16_230, (font_t *)Font16_231,
+	(font_t *)Font16_232, (font_t *)Font16_233, (font_t *)Font16_234, (font_t *)Font16_235,
+	(font_t *)Font16_236, (font_t *)Font16_237, (font_t *)Font16_238, (font_t *)Font16_239,
+	(font_t *)Font16_240, (font_t *)Font16_241, (font_t *)Font16_242, (font_t *)Font16_243,
+	(font_t *)Font16_244, (font_t *)Font16_245, (font_t *)Font16_246, (font_t *)Font16_247,
+	(font_t *)Font16_248, (font_t *)Font16_249, (font_t *)Font16_250, (font_t *)Font16_251,
+	(font_t *)Font16_252, (font_t *)Font16_253, (font_t *)Font16_254, (font_t *)Font16_255
+};
+
+font_head_t Shinonome_Font16 = {
+	"shinonome_font16",
+	0x80,
+	0x00,
+	16,
+	16,
+	Font16,
+	NULL
+};
+
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/ui/snfont_disp/font9.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/ui/snfont_disp/font9.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/ui/snfont_disp/font9.c	(revision 457)
@@ -0,0 +1,3316 @@
+
+
+#include "fonts.h"
+
+/*
+ *  001
+ */
+static const uint8_t Font9_01[] = {
+	6, 9,
+	1, 9,
+	0x00, //       
+	0x20, //   #   
+	0x20, //   #   
+	0x70, //  ###  
+	0xF8, // ##### 
+	0x70, //  ###  
+	0x20, //   #   
+	0x20, //   #   
+	0x00  //       
+};
+
+/*
+ *  002
+ */
+static const uint8_t Font9_02[] = {
+	6, 9,
+	1, 9,
+	0x54, //  # # #
+	0xA8, // # # # 
+	0x54, //  # # #
+	0xA8, // # # # 
+	0x54, //  # # #
+	0xA8, // # # # 
+	0x54, //  # # #
+	0xA8, // # # # 
+	0x54  //  # # #
+};
+
+/*
+ *  003
+ */
+static const uint8_t Font9_03[] = {
+	6, 9,
+	1, 9,
+	0x00, //       
+	0xA0, // # #   
+	0xE0, // ###   
+	0xA0, // # #   
+	0x38, //   ### 
+	0x10, //    #  
+	0x10, //    #  
+	0x10, //    #  
+	0x00  //       
+};
+
+/*
+ *  004
+ */
+static const uint8_t Font9_04[] = {
+	6, 9,
+	1, 9,
+	0x00, //       
+	0xE0, // ###   
+	0xE0, // ###   
+	0x80, // #     
+	0x38, //   ### 
+	0x38, //   ### 
+	0x20, //   #   
+	0x20, //   #   
+	0x00  //       
+};
+
+/*
+ *  005
+ */
+static const uint8_t Font9_05[] = {
+	6, 9,
+	1, 9,
+	0x00, //       
+	0x60, //  ##   
+	0x80, // #     
+	0x60, //  ##   
+	0x30, //   ##  
+	0x28, //   # # 
+	0x30, //   ##  
+	0x28, //   # # 
+	0x00  //       
+};
+
+/*
+ *  006
+ */
+static const uint8_t Font9_06[] = {
+	6, 9,
+	1, 9,
+	0x00, //       
+	0x80, // #     
+	0x80, // #     
+	0xE0, // ###   
+	0x38, //   ### 
+	0x20, //   #   
+	0x38, //   ### 
+	0x20, //   #   
+	0x00  //       
+};
+
+/*
+ *  007
+ */
+static const uint8_t Font9_07[] = {
+	6, 9,
+	1, 9,
+	0x00, //       
+	0x60, //  ##   
+	0x90, // #  #  
+	0x60, //  ##   
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0x00  //       
+};
+
+/*
+ *  008
+ */
+static const uint8_t Font9_08[] = {
+	6, 9,
+	1, 9,
+	0x00, //       
+	0x20, //   #   
+	0x20, //   #   
+	0xF8, // ##### 
+	0x20, //   #   
+	0x20, //   #   
+	0x00, //       
+	0xF8, // ##### 
+	0x00  //       
+};
+
+/*
+ *  009
+ */
+static const uint8_t Font9_09[] = {
+	6, 9,
+	1, 9,
+	0x00, //       
+	0xC0, // ##    
+	0xA0, // # #   
+	0xA0, // # #   
+	0x20, //   #   
+	0x20, //   #   
+	0x20, //   #   
+	0x38, //   ### 
+	0x00  //       
+};
+
+/*
+ *  010
+ */
+static const uint8_t Font9_10[] = {
+	6, 9,
+	1, 9,
+	0x00, //       
+	0xA0, // # #   
+	0xA0, // # #   
+	0x40, //  #    
+	0x30, //   ##  
+	0x28, //   # # 
+	0x30, //   ##  
+	0x28, //   # # 
+	0x00  //       
+};
+
+/*
+ *  011
+ */
+static const uint8_t Font9_11[] = {
+	6, 9,
+	1, 9,
+	0x20, //   #   
+	0x20, //   #   
+	0x20, //   #   
+	0x20, //   #   
+	0xE0, // ###   
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0x00  //       
+};
+
+/*
+ *  012
+ */
+static const uint8_t Font9_12[] = {
+	6, 9,
+	1, 9,
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0xE0, // ###   
+	0x20, //   #   
+	0x20, //   #   
+	0x20, //   #   
+	0x20  //   #   
+};
+
+/*
+ *  013
+ */
+static const uint8_t Font9_13[] = {
+	6, 9,
+	1, 9,
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0x3C, //   ####
+	0x20, //   #   
+	0x20, //   #   
+	0x20, //   #   
+	0x20  //   #   
+};
+
+/*
+ *  014
+ */
+static const uint8_t Font9_14[] = {
+	6, 9,
+	1, 9,
+	0x20, //   #   
+	0x20, //   #   
+	0x20, //   #   
+	0x20, //   #   
+	0x3C, //   ####
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0x00, //       
+};
+
+/*
+ *  015
+ */
+static const uint8_t Font9_15[] = {
+	6, 9,
+	1, 9,
+	0x20, //   #   
+	0x20, //   #   
+	0x20, //   #   
+	0x20, //   #   
+	0xFC, // ######
+	0x20, //   #   
+	0x20, //   #   
+	0x20, //   #   
+	0x20  //   #   
+};
+
+/*
+ *  016
+ */
+static const uint8_t Font9_16[] = {
+	6, 9,
+	1, 9,
+	0xFC, // ######
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0x00  //       
+};
+
+/*
+ *  017
+ */
+static const uint8_t Font9_17[] = {
+	6, 9,
+	1, 9,
+	0x00, //       
+	0x00, //       
+	0xFC, // ######
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0x00  //       
+};
+
+/*
+ *  018
+ */
+static const uint8_t Font9_18[] = {
+	6, 9,
+	1, 9,
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0xFC, // ######
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0x00  //       
+};
+
+/*
+ *  019
+ */
+static const uint8_t Font9_19[] = {
+	6, 9,
+	1, 9,
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0xFC, // ######
+	0x00, //       
+	0x00  //       
+};
+
+/*
+ *  020
+ */
+static const uint8_t Font9_20[] = {
+	6, 9,
+	1, 9,
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0xFC  // ######
+};
+
+/*
+ *  021
+ */
+static const uint8_t Font9_21[] = {
+	6, 9,
+	1, 9,
+	0x20, //   #   
+	0x20, //   #   
+	0x20, //   #   
+	0x20, //   #   
+	0x3C, //   ####
+	0x20, //   #   
+	0x20, //   #   
+	0x20, //   #   
+	0x20  //   #   
+};
+
+/*
+ *  022
+ */
+static const uint8_t Font9_22[] = {
+	6, 9,
+	1, 9,
+	0x20, //   #   
+	0x20, //   #   
+	0x20, //   #   
+	0x20, //   #   
+	0xE0, // ###   
+	0x20, //   #   
+	0x20, //   #   
+	0x20, //   #   
+	0x20  //   #   
+};
+
+/*
+ *  023
+ */
+static const uint8_t Font9_23[] = {
+	6, 9,
+	1, 9,
+	0x20, //   #   
+	0x20, //   #   
+	0x20, //   #   
+	0x20, //   #   
+	0xFC, // ######
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0x00  //       
+};
+
+/*
+ *  024
+ */
+static const uint8_t Font9_24[] = {
+	6, 9,
+	1, 9,
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0xFC, // ######
+	0x20, //   #   
+	0x20, //   #   
+	0x20, //   #   
+	0x20  //   #   
+};
+
+/*
+ *  025
+ */
+static const uint8_t Font9_25[] = {
+	6, 9,
+	1, 9,
+	0x20, //   #   
+	0x20, //   #   
+	0x20, //   #   
+	0x20, //   #   
+	0x20, //   #   
+	0x20, //   #   
+	0x20, //   #   
+	0x20, //   #   
+	0x20  //   #   
+};
+
+/*
+ *  026
+ */
+static const uint8_t Font9_26[] = {
+	6, 9,
+	1, 9,
+	0x00, //       
+	0x38, //   ### 
+	0xC0, // ##    
+	0x38, //   ### 
+	0xF8, // ##### 
+	0x00, //       
+	0xF8, // ##### 
+	0x00, //       
+	0x00  //       
+};
+
+/*
+ *  027
+ */
+static const uint8_t Font9_27[] = {
+	6, 9,
+	1, 9,
+	0x00, //       
+	0xE0, // ###   
+	0x18, //    ## 
+	0xE0, // ###   
+	0xF8, // ##### 
+	0x00, //       
+	0xF8, // ##### 
+	0x00, //       
+	0x00  //       
+};
+
+/*
+ *  028
+ */
+static const uint8_t Font9_28[] = {
+	6, 9,
+	1, 9,
+	0x00, //       
+	0xF8, // ##### 
+	0x50, //  # #  
+	0x50, //  # #  
+	0x50, //  # #  
+	0x58, //  # ## 
+	0x80, // #     
+	0x00, //       
+	0x00  //       
+};
+
+/*
+ *  029
+ */
+static const uint8_t Font9_29[] = {
+	6, 9,
+	1, 9,
+	0x00, //       
+	0x08, //     # 
+	0x10, //    #  
+	0xF8, // ##### 
+	0x20, //   #   
+	0xF8, // ##### 
+	0x40, //  #    
+	0x80, // #     
+	0x00  //       
+};
+
+/*
+ *  030
+ */
+static const uint8_t Font9_30[] = {
+	6, 9,
+	1, 9,
+	0x00, //       
+	0x18, //    ## 
+	0x20, //   #   
+	0xF8, // ##### 
+	0x20, //   #   
+	0x60, //  ##   
+	0xA4, // # #  #
+	0x58, //  # ## 
+	0x00, //       
+};
+
+/*
+ *  031
+ */
+static const uint8_t Font9_31[] = {
+	6, 9,
+	1, 9,
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0x20, //   #   
+	0x00, //       
+	0x00, //       
+	0x00, //       
+	0x00  //       
+};
+
+
+/*
+ *  SPACE
+ */
+static const uint8_t Font9_32[] = {
+	5, 9,
+	0, 0
+};
+
+/*
+ *  !
+ */
+static const uint8_t Font9_33[] = {
+	5, 9,
+	1, 9,
+	0x40, //  #   
+	0x40, //  #   
+	0x40, //  #   
+	0x00, //      
+	0x00, //      
+	0x40, //  #   
+	0x00, //      
+	0x00, //      
+	0x00  //      
+};
+
+/*
+ *  '!'
+ */
+static const uint8_t Font9_34[] = {
+	6, 9,
+	1, 9,
+	0x50, //  # # 
+	0x50, //  # # 
+	0x50, //  # # 
+	0x00, //      
+	0x00, //      
+	0x00, //      
+	0x00, //      
+	0x00, //      
+	0x00  //      
+};
+
+/*
+ *  '#'
+ */
+static const uint8_t Font9_35[] = {
+	6, 9,
+	1, 9,
+	0x50, //  # # 
+	0x50, //  # # 
+	0xF8, // #####
+	0x50, //  # # 
+	0xF8, // #####
+	0x50, //  # # 
+	0x50, //  # # 
+	0x00, //      
+	0x00  //      
+};
+
+/*
+ *  '$'
+ */
+static const uint8_t Font9_36[] = {
+	6, 9,
+	1, 9,
+	0x20, //   #  
+	0x78, //  ####
+	0xA0, // # #  
+	0x70, //  ### 
+	0x28, //   # #
+	0xF0, // #### 
+	0x20, //   #  
+	0x00, //      
+	0x00  //      
+};
+
+/*
+ *  '%'
+ */
+static const uint8_t Font9_37[] = {
+	6, 9,
+	1, 9,
+	0xC0, // ##   
+	0xC8, // ##  #
+	0x10, //    # 
+	0x20, //   #  
+	0x40, //  #   
+	0x98, // #  ##
+	0x18, //    ##
+	0x00, //      
+	0x00  //      
+};
+
+/*
+ *  '&'
+ */
+static const uint8_t Font9_38[] = {
+	6, 9,
+	1, 9,
+	0x60, //  ##  
+	0x90, // #  # 
+	0xA0, // # #  
+	0x20, //  #   
+	0xA8, // # # #
+	0x90, // #  # 
+	0x68, //  ## #
+	0x00, //      
+	0x00  //      
+};
+
+/*
+ *  '''
+ */
+static const uint8_t Font9_39[] = {
+	5, 9,
+	1, 9,
+	0x60, //  ##  
+	0x20, //   #  
+	0x40, //  #   
+	0x00, //      
+	0x00, //      
+	0x00, //      
+	0x00, //      
+	0x00, //      
+	0x00  //      
+};
+
+/*
+ *  '('
+ */
+static const uint8_t Font9_40[] = {
+	5, 9,
+	1, 9,
+	0x10, //    # 
+	0x20, //   #  
+	0x40, //  #   
+	0x40, //  #   
+	0x40, //  #   
+	0x20, //   #  
+	0x10, //    # 
+	0x00, //      
+	0x00  //      
+};
+
+/*
+ *  ')'
+ */
+static const uint8_t Font9_41[] = {
+	5, 9,
+	1, 9,
+	0x40, //  #   
+	0x20, //   #  
+	0x10, //    # 
+	0x10, //    # 
+	0x10, //    # 
+	0x20, //   #  
+	0x40, //  #   
+	0x00, //      
+	0x00  //      
+};
+
+/*
+ *  '*'
+ */
+static const uint8_t Font9_42[] = {
+	6, 9,
+	1, 9,
+	0x00, //      
+	0x20, //   #  
+	0xA8, // # # #
+	0x70, //  ### 
+	0xA8, // # # #
+	0x20, //   #  
+	0x00, //      
+	0x00, //      
+	0x00  //      
+};
+
+/*
+ *  '+'
+ */
+static const uint8_t Font9_43[] = {
+	6, 9,
+	1, 9,
+	0x00, //      
+	0x20, //   #  
+	0x20, //   #  
+	0xF8, // #####
+	0x20, //   #  
+	0x20, //   #  
+	0x00, //      
+	0x00, //      
+	0x00  //      
+};
+
+/*
+ *  ','
+ */
+static const uint8_t Font9_44[] = {
+	5, 9,
+	1, 9,
+	0x00, //      
+	0x00, //      
+	0x00, //      
+	0x00, //      
+	0x60, //  ##  
+	0x20, //   #  
+	0x40, //  #   
+	0x00, //      
+	0x00  //      
+};
+
+/*
+ *  '-'
+ */
+static const uint8_t Font9_45[] = {
+	6, 9,
+	1, 9,
+	0x00, //      
+	0x00, //      
+	0x00, //      
+	0xF8, // #####
+	0x00, //      
+	0x00, //      
+	0x00, //      
+	0x00, //      
+	0x00  //      
+};
+
+/*
+ *  '.'
+ */
+static const uint8_t Font9_46[] = {
+	5, 9,
+	1, 9,
+	0x00, //      
+	0x00, //      
+	0x00, //      
+	0x00, //      
+	0x00, //      
+	0x60, //  ##  
+	0x60, //  ##  
+	0x00, //      
+	0x00  //      
+};
+
+/*
+ *  '/'
+ */
+static const uint8_t Font9_47[] = {
+	6, 9,
+	1, 9,
+	0x00, //      
+	0x08, //     #
+	0x10, //    # 
+	0x20, //   #  
+	0x40, //  #   
+	0x80, // #    
+	0x00, //      
+	0x00, //      
+	0x00  //      
+};
+
+/*
+ *  '0'
+ */
+static const uint8_t Font9_48[] = {
+	6, 9,
+	1, 9,
+	0x70, //  ### 
+	0x88, // #   #
+	0x98, // #  ##
+	0xA8, // # # #
+	0xC8, // ##  #
+	0x88, // #   #
+	0x70, //  ### 
+	0x00, //      
+	0x00  //      
+};
+
+/*
+ *  '1'
+ */
+static const uint8_t Font9_49[] = {
+	6, 9,
+	1, 9,
+	0x20, //   #  
+	0x60, //  ##  
+	0x20, //   #  
+	0x20, //   #  
+	0x20, //   #  
+	0x20, //   #  
+	0x70, //  ### 
+	0x00, //      
+	0x00  //      
+};
+
+/*
+ *  '2'
+ */
+static const uint8_t Font9_50[] = {
+	6, 9,
+	1, 9,
+	0x70, //  ### 
+	0x88, // #   #
+	0x08, //     #
+	0x10, //    # 
+	0x20, //   #  
+	0x40, //  #   
+	0xF8, // #####
+	0x00, //      
+	0x00  //      
+};
+
+/*
+ *  '3'
+ */
+static const uint8_t Font9_51[] = {
+	6, 9,
+	1, 9,
+	0xF8, // #####
+	0x10, //    # 
+	0x20, //   #  
+	0x10, //    # 
+	0x08, //     #
+	0x88, // #   #
+	0x70, //  ### 
+	0x00, //      
+	0x00  //      
+};
+
+/*
+ *  '4'
+ */
+static const uint8_t Font9_52[] = {
+	6, 9,
+	1, 9,
+	0x10, //    # 
+	0x30, //   ## 
+	0x50, //  # # 
+	0x90, // #  # 
+	0xF8, // #####
+	0x10, //    # 
+	0x10, //    # 
+	0x00, //      
+	0x00  //      
+};
+
+/*
+ *  '5'
+ */
+static const uint8_t Font9_53[] = {
+	6, 9,
+	1, 9,
+	0xF8, // #####
+	0x80, // #    
+	0xF0, // #### 
+	0x08, //     #
+	0x08, //     #
+	0x88, // #   #
+	0x70, //  ### 
+	0x00, //      
+	0x00  //      
+};
+
+/*
+ *  '6'
+ */
+static const uint8_t Font9_54[] = {
+	6, 9,
+	1, 9,
+	0x30, //   ## 
+	0x40, //  #   
+	0x80, // #    
+	0xF0, // #### 
+	0x88, // #   #
+	0x88, // #   #
+	0x70, //  ### 
+	0x00, //      
+	0x00  //      
+};
+
+/*
+ *  '7'
+ */
+static const uint8_t Font9_55[] = {
+	6, 9,
+	1, 9,
+	0xF8, // #####
+	0x08, //     #
+	0x10, //    # 
+	0x20, //   #  
+	0x40, //  #   
+	0x40, //  #   
+	0x40, //  #   
+	0x00, //      
+	0x00  //      
+};
+
+/*
+ *  '8'
+ */
+static const uint8_t Font9_56[] = {
+	6, 9,
+	1, 9,
+	0x70, //  ### 
+	0x88, // #   #
+	0x88, // #   #
+	0x70, //  ### 
+	0x88, // #   #
+	0x88, // #   #
+	0x70, //  ### 
+	0x00, //      
+	0x00  //      
+};
+
+/*
+ *  '9'
+ */
+static const uint8_t Font9_57[] = {
+	6, 9,
+	1, 9,
+	0x70, //  ### 
+	0x88, // #   #
+	0x88, // #   #
+	0x78, //  ####
+	0x08, //     #
+	0x10, //    # 
+	0x60, //  ##  
+	0x00, //      
+	0x00  //      
+};
+
+/*
+ *  ':'
+ */
+static const uint8_t Font9_58[] = {
+	5, 9,
+	1, 9,
+	0x00, //      
+	0x60, //  ##  
+	0x60, //  ##  
+	0x00, //      
+	0x60, //  ##  
+	0x60, //  ##  
+	0x00, //      
+	0x00, //      
+	0x00  //      
+};
+
+/*
+ *  ';'
+ */
+static const uint8_t Font9_59[] = {
+	5, 9,
+	1, 9,
+	0x00, //      
+	0x60, //  ##  
+	0x60, //  ##  
+	0x00, //      
+	0x60, //  ##  
+	0x20, //   #  
+	0x40, //  #   
+	0x00, //      
+	0x00  //      
+};
+
+/*
+ *  '<'
+ */
+static const uint8_t Font9_60[] = {
+	6, 9,
+	1, 9,
+	0x10, //    # 
+	0x20, //   #  
+	0x40, //  #   
+	0x80, // #    
+	0x40, //  #   
+	0x20, //   #  
+	0x10, //    # 
+	0x00, //      
+	0x00  //      
+};
+
+/*
+ *  '='
+ */
+static const uint8_t Font9_61[] = {
+	6, 9,
+	1, 9,
+	0x00, //      
+	0x00, //      
+	0xF8, // #####
+	0x00, //      
+	0xF8, // #####
+	0x00, //      
+	0x00, //      
+	0x00, //      
+	0x00  //      
+};
+
+/*
+ *  '>'
+ */
+static const uint8_t Font9_62[] = {
+	6, 9,
+	1, 9,
+	0x40, //  #   
+	0x20, //   #  
+	0x10, //    # 
+	0x08, //     #
+	0x10, //    # 
+	0x20, //   #  
+	0x40, //  #   
+	0x00, //      
+	0x00  //      
+};
+
+/*
+ *  '?'
+ */
+static const uint8_t Font9_63[] = {
+	6, 9,
+	1, 9,
+	0x70, //  ### 
+	0x88, // #   #
+	0x08, //     #
+	0x10, //    # 
+	0x20, //   #  
+	0x00, //      
+	0x20, //   #  
+	0x00, //      
+	0x00  //      
+};
+
+/*
+ *  '@'
+ */
+static const uint8_t Font9_64[] = {
+	6, 9,
+	1, 9,
+	0x70, //  ### 
+	0x88, // #   #
+	0x08, //     #
+	0x68, //  ## #
+	0xA8, // # # #
+	0xA8, // # # #
+	0x70, //  ### 
+	0x00, //      
+	0x00  //      
+};
+
+/*
+ *  'A'
+ */
+static const uint8_t Font9_65[] = {
+	6, 9,
+	1, 9,
+	0x70, //  ### 
+	0x88, // #   #
+	0x88, // #   #
+	0x88, // #   #
+	0xF8, // #####
+	0x88, // #   #
+	0x88, // #   #
+	0x00, //      
+	0x00  //      
+};
+
+/*
+ *  'B'
+ */
+static const uint8_t Font9_66[] = {
+	6, 9,
+	1, 9,
+	0xF0, // #### 
+	0x88, // #   #
+	0x88, // #   #
+	0xF0, // #### 
+	0x88, // #   #
+	0x88, // #   #
+	0xF0, // #### 
+	0x00, //      
+	0x00  //      
+};
+
+/*
+ *  'C'
+ */
+static const uint8_t Font9_67[] = {
+	6, 9,
+	1, 9,
+	0x70, //  ### 
+	0x88, // #   #
+	0x80, // #    
+	0x80, // #    
+	0x80, // #    
+	0x88, // #   #
+	0x70, //  ### 
+	0x00, //      
+	0x00  //      
+};
+
+/*
+ *  'D'
+ */
+static const uint8_t Font9_68[] = {
+	6, 9,
+	1, 9,
+	0xE0, // ###  
+	0x90, // #  # 
+	0x88, // #   #
+	0x88, // #   #
+	0x88, // #   #
+	0x90, // #  # 
+	0xE0, // ###  
+	0x00, //      
+	0x00  //      
+};
+
+/*
+ *  'E'
+ */
+static const uint8_t Font9_69[] = {
+	6, 9,
+	1, 9,
+	0xF8, // #####
+	0x80, // #    
+	0x80, // #    
+	0xF0, // #### 
+	0x80, // #    
+	0x80, // #    
+	0xF8, // #####
+	0x00, //      
+	0x00  //      
+};
+
+/*
+ *  'F'
+ */
+static const uint8_t Font9_70[] = {
+	6, 9,
+	1, 9,
+	0xF8, // #####
+	0x80, // #    
+	0x80, // #    
+	0xF0, // #### 
+	0x80, // #    
+	0x80, // #    
+	0x80, // #    
+	0x00, //      
+	0x00  //      
+};
+
+/*
+ *  'G'
+ */
+static const uint8_t Font9_71[] = {
+	6, 9,
+	1, 9,
+	0x70, //  ### 
+	0x88, // #   #
+	0x80, // #    
+	0xB8, // # ###
+	0x88, // #   #
+	0x88, // #   #
+	0x78, //  ####
+	0x00, //      
+	0x00  //      
+};
+
+/*
+ *  'H'
+ */
+static const uint8_t Font9_72[] = {
+	6, 9,
+	1, 9,
+	0x88, // #   #
+	0x88, // #   #
+	0x88, // #   #
+	0xF8, // #####
+	0x88, // #   #
+	0x88, // #   #
+	0x88, // #   #
+	0x00, //      
+	0x00  //      
+};
+
+/*
+ *  'I'
+ */
+static const uint8_t Font9_73[] = {
+	5, 9,
+	1, 9,
+	0x70, //  ### 
+	0x20, //   #  
+	0x20, //   #  
+	0x20, //   #  
+	0x20, //   #  
+	0x20, //   #  
+	0x70, //  ### 
+	0x00, //      
+	0x00  //      
+};
+
+/*
+ *  'J'
+ */
+static const uint8_t Font9_74[] = {
+	6, 9,
+	1, 9,
+	0x38, //   ###
+	0x10, //    # 
+	0x10, //    # 
+	0x10, //    # 
+	0x10, //    # 
+	0x90, // #  # 
+	0x60, //  ##  
+	0x00, //      
+	0x00  //      
+};
+
+/*
+ *  'K'
+ */
+static const uint8_t Font9_75[] = {
+	6, 9,
+	1, 9,
+	0x88, // #   #
+	0x90, // #  # 
+	0xA0, // # #  
+	0xC0, // ##   
+	0xA0, // # #  
+	0x98, // #  # 
+	0x88, // #   #
+	0x00, //      
+	0x00  //      
+};
+
+/*
+ *  'L'
+ */
+static const uint8_t Font9_76[] = {
+	6, 9,
+	1, 9,
+	0x80, // #    
+	0x80, // #    
+	0x80, // #    
+	0x80, // #    
+	0x80, // #    
+	0x80, // #    
+	0xF8, // #####
+	0x00, //      
+	0x00  //      
+};
+
+/*
+ *  'M'
+ */
+static const uint8_t Font9_77[] = {
+	6, 9,
+	1, 9,
+	0x88, // #   #
+	0xD8, // ## ##
+	0xA8, // # # #
+	0xA8, // # # #
+	0x88, // #   #
+	0x88, // #   #
+	0x88, // #   #
+	0x00, //      
+	0x00  //      
+};
+
+/*
+ *  'N'
+ */
+static const uint8_t Font9_78[] = {
+	6, 9,
+	1, 9,
+	0x88, // #   #
+	0x88, // #   #
+	0xC8, // ##  #
+	0xA8, // # # #
+	0x98, // #  ##
+	0x88, // #   #
+	0x88, // #   #
+	0x00, //      
+	0x00  //      
+};
+
+/*
+ *  'O'
+ */
+static const uint8_t Font9_79[] = {
+	6, 9,
+	1, 9,
+	0x70, //  ### 
+	0x88, // #   #
+	0x88, // #   #
+	0x88, // #   #
+	0x88, // #   #
+	0x88, // #   #
+	0x70, //  ### 
+	0x00, //      
+	0x00  //      
+};
+
+/*
+ *  'P'
+ */
+static const uint8_t Font9_80[] = {
+	6, 9,
+	1, 9,
+	0xF0, // #### 
+	0x88, // #   #
+	0x88, // #   #
+	0xF0, // #### 
+	0x80, // #    
+	0x80, // #    
+	0x80, // #    
+	0x00, //      
+	0x00  //      
+};
+
+/*
+ *  'Q'
+ */
+static const uint8_t Font9_81[] = {
+	6, 9,
+	1, 9,
+	0x70, //  ### 
+	0x88, // #   #
+	0x88, // #   #
+	0x88, // #   #
+	0xA8, // # # #
+	0x90, // #  # 
+	0x68, //  ## #
+	0x00, //      
+	0x00  //      
+};
+
+/*
+ *  'R'
+ */
+static const uint8_t Font9_82[] = {
+	6, 9,
+	1, 9,
+	0xF0, // #### 
+	0x88, // #   #
+	0x88, // #   #
+	0xF0, // #### 
+	0xA0, // # #  
+	0x90, // #  # 
+	0x88, // #   #
+	0x00, //      
+	0x00  //      
+};
+
+/*
+ *  'S'
+ */
+static const uint8_t Font9_83[] = {
+	6, 9,
+	1, 9,
+	0x78, //  ####
+	0x80, // #    
+	0x80, // #    
+	0x70, //  ### 
+	0x08, //     #
+	0x08, //     #
+	0xF0, // #### 
+	0x00, //      
+	0x00  //      
+};
+
+/*
+ *  'T'
+ */
+static const uint8_t Font9_84[] = {
+	6, 9,
+	1, 9,
+	0xF8, // #####
+	0x20, //   # 
+	0x20, //   #  
+	0x20, //   #  
+	0x20, //   #  
+	0x20, //   #  
+	0x20, //   #  
+	0x00, //      
+	0x00  //      
+};
+
+/*
+ *  'U'
+ */
+static const uint8_t Font9_85[] = {
+	6, 9,
+	1, 9,
+	0x88, // #   #
+	0x88, // #   #
+	0x88, // #   #
+	0x88, // #   #
+	0x88, // #   #
+	0x88, // #   #
+	0x70, //  ### 
+	0x00, //      
+	0x00  //      
+};
+
+/*
+ *  'V'
+ */
+static const uint8_t Font9_86[] = {
+	6, 9,
+	1, 9,
+	0x88, // #   #
+	0x88, // #   #
+	0x88, // #   #
+	0x88, // #   #
+	0x88, // #   #
+	0x48, //  # # 
+	0x20, //   #  
+	0x00, //      
+	0x00  //      
+};
+
+/*
+ *  'W'
+ */
+static const uint8_t Font9_87[] = {
+	6, 9,
+	1, 9,
+	0x88, // #   #
+	0x88, // #   #
+	0x88, // #   #
+	0xA8, // # # #
+	0xA8, // # # #
+	0xA8, // # # #
+	0x50, //  # # 
+	0x00, //      
+	0x00  //      
+};
+
+/*
+ *  'X'
+ */
+static const uint8_t Font9_88[] = {
+	6, 9,
+	1, 9,
+	0x88, // #   #
+	0x88, // #   #
+	0x50, //  # # 
+	0x20, //   #  
+	0x50, //  # # 
+	0x88, // #   #
+	0x88, // #   #
+	0x00, //      
+	0x00  //      
+};
+
+/*
+ *  'Y'
+ */
+static const uint8_t Font9_89[] = {
+	6, 9,
+	1, 9,
+	0x88, // #   #
+	0x88, // #   #
+	0x88, // #   #
+	0x50, //  # # 
+	0x20, //   #  
+	0x20, //   #  
+	0x20, //   #  
+	0x00, //      
+	0x00  //      
+};
+
+/*
+ *  'Z'
+ */
+static const uint8_t Font9_90[] = {
+	6, 9,
+	1, 9,
+	0xF8, // #####
+	0x08, //     #
+	0x10, //    # 
+	0x20, //   #  
+	0x40, //  #   
+	0x80, // #    
+	0xF8, // #####
+	0x00, //      
+	0x00  //      
+};
+
+/*
+ *  '['
+ */
+static const uint8_t Font9_91[] = {
+	5, 9,
+	1, 9,
+	0x70, //  ### 
+	0x40, //  #   
+	0x40, //  #   
+	0x40, //  #   
+	0x40, //  #   
+	0x40, //  #   
+	0x70, //  ### 
+	0x00, //      
+	0x00  //      
+};
+
+/*
+ *  '\'
+ */
+static const uint8_t Font9_92[] = {
+	6, 9,
+	1, 9,
+	0x88, // #   #
+	0x50, //  # # 
+	0xF8, // #####
+	0x20, //   #  
+	0xF8, // #####
+	0x20, //   #  
+	0x20, //   #  
+	0x00, //      
+	0x00  //      
+};
+
+/*
+ *  ']'
+ */
+static const uint8_t Font9_93[] = {
+	5, 9,
+	1, 9,
+	0x70, //  ### 
+	0x10, //    # 
+	0x10, //    # 
+	0x10, //    # 
+	0x10, //    # 
+	0x10, //    # 
+	0x70, //  ### 
+	0x00, //      
+	0x00  //      
+};
+
+/*
+ *  '^'
+ */
+static const uint8_t Font9_94[] = {
+	6, 9,
+	1, 9,
+	0x20, //   #  
+	0x50, //  # # 
+	0x88, // #   #
+	0x00, //      
+	0x00, //      
+	0x00, //      
+	0x00, //      
+	0x00, //      
+	0x00  //      
+};
+
+/*
+ *  '_'
+ */
+static const uint8_t Font9_95[] = {
+	6, 9,
+	1, 9,
+	0x00, //      
+	0x00, //      
+	0x00, //      
+	0x00, //      
+	0x00, //      
+	0x00, //      
+	0x00, //      
+	0x00, //      
+	0xF8  // #####
+};
+
+/*
+ *  '''
+ */
+static const uint8_t Font9_96[] = {
+	5, 9,
+	1, 9,
+	0x40, //  #   
+	0x20, //   #  
+	0x10, //    # 
+	0x00, //      
+	0x00, //      
+	0x00, //      
+	0x00, //      
+	0x00, //      
+	0x00  //      
+};
+
+/*
+ *  'a'
+ */
+static const uint8_t Font9_97[] = {
+	6, 9,
+	1, 9,
+	0x00, //      
+	0x00, //      
+	0x70, //  ### 
+	0x08, //     #
+	0x78, //  ####
+	0x88, // #   #
+	0x78, //  ####
+	0x00, //      
+	0x00  //      
+};
+
+/*
+ *  'b'
+ */
+static const uint8_t Font9_98[] = {
+	6, 9,
+	1, 9,
+	0x80, // #    
+	0x80, // #    
+	0xB0, // # ## 
+	0xC8, // ##  #
+	0x88, // #   #
+	0x88, // #   #
+	0xF0, // #### 
+	0x00, //      
+	0x00  //      
+};
+
+/*
+ *  'c'
+ */
+static const uint8_t Font9_99[] = {
+	6, 9,
+	1, 9,
+	0x00, //      
+	0x00, //      
+	0x70, //  ### 
+	0x80, // #    
+	0x80, // #    
+	0x88, // #   #
+	0x70, //  ### 
+	0x00, //      
+	0x00  //      
+};
+
+/*
+ *  'd'
+ */
+static const uint8_t Font9_100[] = {
+	6, 9,
+	1, 9,
+	0x08, //     #
+	0x08, //     #
+	0x68, //  ## #
+	0x98, // #  ##
+	0x88, // #   #
+	0x88, // #   #
+	0x78, //  ####
+	0x00, //      
+	0x00  //      
+};
+
+/*
+ *  'e'
+ */
+static const uint8_t Font9_101[] = {
+	6, 9,
+	1, 9,
+	0x00, //      
+	0x00, //      
+	0x70, //  ### 
+	0x88, // #   #
+	0xF8, // #####
+	0x80, // #    
+	0x70, //  ### 
+	0x00, //      
+	0x00  //      
+};
+
+/*
+ *  'f'
+ */
+static const uint8_t Font9_102[] = {
+	6, 9,
+	1, 9,
+	0x30, //   ## 
+	0x48, //  #  #
+	0x40, //  #   
+	0xE0, // ### 
+	0x40, //  #   
+	0x40, //  #   
+	0x40, //  #   
+	0x00, //      
+	0x00  //      
+};
+
+/*
+ *  'g'
+ */
+static const uint8_t Font9_103[] = {
+	6, 9,
+	1, 9,
+	0x00, //      
+	0x78, //  ####
+	0x88, // #   #
+	0x88, // #   #
+	0x78, //  ####
+	0x08, //     #
+	0x08, //     #
+	0x70, //  ### 
+	0x00  //      
+};
+
+/*
+ *  'h'
+ */
+static const uint8_t Font9_104[] = {
+	6, 9,
+	1, 9,
+	0x80, // #    
+	0x80, // #    
+	0xB0, // # ## 
+	0xC8, // ##  #
+	0x88, // #   #
+	0x88, // #   #
+	0x88, // #   #
+	0x00, //      
+	0x00  //      
+};
+
+/*
+ *  'i'
+ */
+static const uint8_t Font9_105[] = {
+	5, 9,
+	1, 9,
+	0x20, //   #  
+	0x00, //      
+	0x60, //  ##  
+	0x20, //   #  
+	0x20, //   #  
+	0x20, //   #  
+	0x70, //  ### 
+	0x00, //      
+	0x00  //      
+};
+
+/*
+ *  'j'
+ */
+static const uint8_t Font9_106[] = {
+	5, 9,
+	1, 9,
+	0x20, //   #  
+	0x00, //      
+	0x30, //   ## 
+	0x10, //    # 
+	0x10, //    # 
+	0x10, //    # 
+	0x90, // #  # 
+	0x60, //  ##  
+	0x00  //      
+};
+
+/*
+ *  'k'
+ */
+static const uint8_t Font9_107[] = {
+	5, 9,
+	1, 9,
+	0x80, // #    
+	0x80, // #    
+	0x90, // #  # 
+	0xA0, // # #  
+	0xC0, // ##   
+	0xA0, // # #  
+	0x90, // #  # 
+	0x00, //      
+	0x00  //      
+};
+
+/*
+ *  'l'
+ */
+static const uint8_t Font9_108[] = {
+	5, 9,
+	1, 9,
+	0x60, //  ##  
+	0x20, //   #  
+	0x20, //   #  
+	0x20, //   #  
+	0x20, //   #  
+	0x20, //   #  
+	0x70, //  ### 
+	0x00, //      
+	0x00  //      
+};
+
+/*
+ *  'm'
+ */
+static const uint8_t Font9_109[] = {
+	6, 9,
+	1, 9,
+	0x00, //      
+	0x00, //      
+	0xD0, // ## # 
+	0xA8, // # # #
+	0xA8, // # # #
+	0x98, // #   #
+	0x98, // #   #
+	0x00, //      
+	0x00  //      
+};
+
+/*
+ *  'n'
+ */
+static const uint8_t Font9_110[] = {
+	6, 9,
+	1, 9,
+	0x00, //      
+	0x00, //      
+	0xB0, // # ## 
+	0xC8, // ##  #
+	0x88, // #   #
+	0x88, // #   #
+	0x88, // #   #
+	0x00, //      
+	0x00  //      
+};
+
+/*
+ *  'o'
+ */
+static const uint8_t Font9_111[] = {
+	6, 9,
+	1, 9,
+	0x00, //      
+	0x00, //      
+	0x70, //  ### 
+	0x88, // #   #
+	0x88, // #   #
+	0x88, // #   #
+	0x70, //  ### 
+	0x00, //      
+	0x00  //      
+};
+
+/*
+ *  'p'
+ */
+static const uint8_t Font9_112[] = {
+	6, 9,
+	1, 9,
+	0x00, //      
+	0x00, //      
+	0xF0, // #### 
+	0x88, // #   #
+	0xF0, // #### 
+	0x80, // #    
+	0x80, // #    
+	0x80, // #    
+	0x00  //      
+};
+
+/*
+ *  'q'
+ */
+static const uint8_t Font9_113[] = {
+	6, 9,
+	1, 9,
+	0x00, //      
+	0x00, //      
+	0x68, //  ## #
+	0x98, // #  ##
+	0x78, //  ####
+	0x08, //     #
+	0x08, //     #
+	0x08, //     #
+	0x00  //      
+};
+
+/*
+ *  'r'
+ */
+static const uint8_t Font9_114[] = {
+	6, 9,
+	1, 9,
+	0x00, //      
+	0x00, //      
+	0xB0, // # ##
+	0xC8, // ##  #
+	0x80, // #    
+	0x80, // #    
+	0x80, // #    
+	0x00, //      
+	0x00  //      
+};
+
+/*
+ *  's'
+ */
+static const uint8_t Font9_115[] = {
+	6, 9,
+	1, 9,
+	0x00, //      
+	0x00, //      
+	0x70, //  ### 
+	0x80, // #    
+	0x70, //  ### 
+	0x08, //     #
+	0xF0, // #### 
+	0x00, //      
+	0x00  //      
+};
+
+/*
+ *  't'
+ */
+static const uint8_t Font9_116[] = {
+	6, 9,
+	1, 9,
+	0x40, //  #   
+	0x40, //  #   
+	0xE0, // ###  
+	0x40, //  #   
+	0x40, //  #   
+	0x48, //  #  #
+	0x30, //   ## 
+	0x00, //      
+	0x00  //      
+};
+
+/*
+ *  'u'
+ */
+static const uint8_t Font9_117[] = {
+	6, 9,
+	1, 9,
+	0x00, //      
+	0x00, //      
+	0x88, // #   #
+	0x88, // #   #
+	0x88, // #   #
+	0x98, // #  ##
+	0x68, //  ## #
+	0x00, //      
+	0x00  //      
+};
+
+/*
+ *  'v'
+ */
+static const uint8_t Font9_118[] = {
+	6, 9,
+	1, 9,
+	0x00, //      
+	0x00, //      
+	0x88, // #   #
+	0x88, // #   #
+	0x88, // #   #
+	0x50, //  # # 
+	0x20, //   #  
+	0x00, //      
+	0x00  //      
+};
+
+/*
+ *  'w'
+ */
+static const uint8_t Font9_119[] = {
+	6, 9,
+	1, 9,
+	0x00, //      
+	0x00, //      
+	0x88, // #   #
+	0x88, // #   #
+	0xA8, // # # #
+	0xA8, // # # #
+	0x50, //  # # 
+	0x00, //      
+	0x00  //      
+};
+
+/*
+ *  'x'
+ */
+static const uint8_t Font9_120[] = {
+	6, 9,
+	1, 9,
+	0x00, //      
+	0x00, //      
+	0x88, // #   #
+	0x50, //  # # 
+	0x20, //   #  
+	0x50, //  # # 
+	0x88, // #   #
+	0x00, //      
+	0x00  //      
+};
+
+/*
+ *  'y'
+ */
+static const uint8_t Font9_121[] = {
+	6, 9,
+	1, 9,
+	0x00, //      
+	0x00, //      
+	0x88, // #   #
+	0x88, // #   #
+	0x78, //  ####
+	0x08, //     #
+	0x08, //     #
+	0x70, //  ### 
+	0x00  //      
+};
+
+/*
+ *  'z'
+ */
+static const uint8_t Font9_122[] = {
+	6, 9,
+	1, 9,
+	0x00, //      
+	0x00, //      
+	0xF8, // #####
+	0x10, //    # 
+	0x20, //   #  
+	0x40, //  #   
+	0xF8, // #####
+	0x00, //      
+	0x00  //      
+};
+
+/*
+ *  '{'
+ */
+static const uint8_t Font9_123[] = {
+	5, 9,
+	1, 9,
+	0x10, //    # 
+	0x20, //   #  
+	0x20, //   #  
+	0x40, //  #   
+	0x20, //   #  
+	0x20, //   #  
+	0x10, //    # 
+	0x00, //      
+	0x00  //      
+};
+
+/*
+ *  '|'
+ */
+static const uint8_t Font9_124[] = {
+	5, 9,
+	1, 9,
+	0x20, //   #  
+	0x20, //   #  
+	0x20, //   #  
+	0x20, //   #  
+	0x20, //   #  
+	0x20, //   #  
+	0x20, //   #  
+	0x00, //      
+	0x00  //      
+};
+
+/*
+ *  '}'
+ */
+static const uint8_t Font9_125[] = {
+	5, 9,
+	1, 9,
+	0x40, //  #   
+	0x20, //   #  
+	0x20, //   #  
+	0x10, //    # 
+	0x20, //   #  
+	0x20, //   #  
+	0x40, //  #   
+	0x00, //      
+	0x00  //      
+};
+
+/*
+ *  '->'
+ */
+static const uint8_t Font9_126[] = {
+	6, 9,
+	1, 9,
+	0x00, //      
+	0x20, //   #  
+	0x10, //    # 
+	0xF8, // #####
+	0x10, //    # 
+	0x20, //   #  
+	0x00, //      
+	0x00, //      
+	0x00  //      
+};
+
+/*
+ *  '<-'
+ */
+static const uint8_t Font9_127[] = {
+	6, 9,
+	1, 9,
+	0x00, //      
+	0x20, //   #  
+	0x40, //  #   
+	0xF8, // #####
+	0x40, //  #   
+	0x20, //   #  
+	0x00, //      
+	0x00, //      
+	0x00  //      
+};
+
+/*
+ *  yohaku
+ */
+static const uint8_t Font9_160[] = {
+	6, 9,
+	1, 9,
+	0x00, //      
+	0x00, //      
+	0x00, //      
+	0x00, //      
+	0x00, //      
+	0x00, //      
+	0x00, //      
+	0x00, //      
+	0x00  //      
+};
+
+/*
+ *  syuryou
+ */
+static const uint8_t Font9_161[] = {
+	6, 9,
+	1, 9,
+	0x00, //      
+	0x00, //      
+	0x00, //      
+	0x00, //      
+	0xE0, // ###  
+	0xA0, // # #  
+	0xE0, // ###  
+	0x00, //      
+	0x00  //      
+};
+
+/*
+ *  kakko
+ */
+static const uint8_t Font9_162[] = {
+	6, 9,
+	1, 9,
+	0x38, //   ###
+	0x20, //   #  
+	0x20, //   #  
+	0x20, //   #  
+	0x00, //      
+	0x00, //      
+	0x00, //      
+	0x00, //      
+	0x00  //      
+};
+
+/*
+ *  kakko tojiru
+ */
+static const uint8_t Font9_163[] = {
+	6, 9,
+	1, 9,
+	0x00, //      
+	0x00, //      
+	0x00, //      
+	0x20, //   #  
+	0x20, //   #  
+	0x20, //   #  
+	0xE0, // ###  
+	0x00, //      
+	0x00  //      
+};
+
+/*
+ *  kutouten
+ */
+static const uint8_t Font9_164[] = {
+	6, 9,
+	1, 9,
+	0x00, //      
+	0x00, //      
+	0x00, //      
+	0x00, //      
+	0x80, // #    
+	0x40, //  #   
+	0x20, //   #  
+	0x00, //      
+	0x00  //      
+};
+
+/*
+ *  cyuten
+ */
+static const uint8_t Font9_165[] = {
+	6, 9,
+	1, 9,
+	0x00, //      
+	0x00, //      
+	0x00, //      
+	0x60, //  ##  
+	0x60, //  ##  
+	0x00, //      
+	0x00, //      
+	0x00, //      
+	0x00  //      
+};
+
+/*
+ *  'WO'
+ */
+static const uint8_t Font9_166[] = {
+	6, 9,
+	1, 9,
+	0x00, //      
+	0xF8, // #####
+	0x08, //     #
+	0xF8, // #####
+	0x08, //     #
+	0x10, //    # 
+	0x20, //   #  
+	0x00, //      
+	0x00  //      
+};
+
+/*
+ *  'aa'
+ */
+static const uint8_t Font9_167[] = {
+	6, 9,
+	1, 9,
+	0x00, //      
+	0x00, //      
+	0xF8, // #####
+	0x08, //     #
+	0x30, //   ## 
+	0x20, //   #  
+	0x40, //  #   
+	0x00, //      
+	0x00  //      
+};
+
+/*
+ *  'ii'
+ */
+static const uint8_t Font9_168[] = {
+	6, 9,
+	1, 9,
+	0x00, //      
+	0x00, //      
+	0x10, //    # 
+	0x20, //   #  
+	0x60, //  ##  
+	0xA0, // # #  
+	0x20, //   #  
+	0x00, //      
+	0x00  //      
+};
+
+/*
+ *  'uu'
+ */
+static const uint8_t Font9_169[] = {
+	6, 9,
+	1, 9,
+	0x00, //      
+	0x00, //      
+	0x20, //   #  
+	0xF8, // #####
+	0x88, // #   #
+	0x08, //     #
+	0x30, //   ## 
+	0x00, //      
+	0x00  //      
+};
+
+/*
+ *  'ee'
+ */
+static const uint8_t Font9_170[] = {
+	6, 9,
+	1, 9,
+	0x00, //      
+	0x00, //      
+	0x00, //      
+	0xF8, // #####
+	0x20, //   #  
+	0x20, //   #  
+	0xF8, // #####
+	0x00, //      
+	0x00  //      
+};
+
+/*
+ *  'oo'
+ */
+static const uint8_t Font9_171[] = {
+	6, 9,
+	1, 9,
+	0x00, //      
+	0x00, //      
+	0x10, //    # 
+	0xF8, // #####
+	0x30, //   ## 
+	0xA0, //  # # 
+	0x90, // #  # 
+	0x00, //      
+	0x00  //      
+};
+
+/*
+ *  'ya'
+ */
+static const uint8_t Font9_172[] = {
+	6, 9,
+	1, 9,
+	0x00, //      
+	0x00, //      
+	0x40, //  #   
+	0xF8, // #####
+	0x48, //  #  #
+	0x50, //  # # 
+	0x40, //  #   
+	0x00, //      
+	0x00  //      
+};
+
+/*
+ *  'yu'
+ */
+static const uint8_t Font9_173[] = {
+	6, 9,
+	1, 9,
+	0x00, //      
+	0x00, //      
+	0x00, //      
+	0x70, //  ### 
+	0x10, //    # 
+	0x10, //    # 
+	0xF8, // #####
+	0x00, //      
+	0x00  //      
+};
+
+/*
+ *  'yo'
+ */
+static const uint8_t Font9_174[] = {
+	6, 9,
+	1, 9,
+	0x00, //      
+	0x00, //      
+	0xF0, // #### 
+	0x10, //    # 
+	0xF0, // #### 
+	0x10, //    # 
+	0xF0, // #### 
+	0x00, //      
+	0x00  //      
+};
+
+
+/*
+ *  'tu'
+ */
+static const uint8_t Font9_175[] = {
+	6, 9,
+	1, 9,
+	0x00, //      
+	0x00, //      
+	0x00, //      
+	0xA8, // # # #
+	0xA8, // # # #
+	0x08, //     #
+	0x30, //   ## 
+	0x00, //      
+	0x00  //      
+};
+
+/*
+ *  '-'
+ */
+static const uint8_t Font9_176[] = {
+	6, 9,
+	1, 9,
+	0x00, //      
+	0x00, //      
+	0x00, //      
+	0xF8, // #####
+	0x00, //      
+	0x00, //      
+	0x00, //      
+	0x00, //      
+	0x00  //      
+};
+
+/*
+ *  'AA'
+ */
+static const uint8_t Font9_177[] = {
+	6, 9,
+	1, 9,
+	0xF8, // #####
+	0x08, //     #
+	0x28, //   # #
+	0x30, //   ## 
+	0x20, //   #  
+	0x20, //   #  
+	0x40, //  #   
+	0x00, //      
+	0x00  //      
+};
+
+/*
+ *  'II'
+ */
+static const uint8_t Font9_178[] = {
+	6, 9,
+	1, 9,
+	0x08, //     #
+	0x10, //    # 
+	0x20, //   #  
+	0x60, //  ##  
+	0xA0, // # #  
+	0x20, //   #  
+	0x20, //   #  
+	0x00, //      
+	0x00  //      
+};
+
+/*
+ *  'UU'
+ */
+static const uint8_t Font9_179[] = {
+	6, 9,
+	1, 9,
+	0x20, //   #  
+	0xF8, // #####
+	0x88, // #   #
+	0x88, // #   #
+	0x08, //     #
+	0x10, //    # 
+	0x20, //   #  
+	0x00, //      
+	0x00  //      
+};
+
+/*
+ *  'EE'
+ */
+static const uint8_t Font9_180[] = {
+	6, 9,
+	1, 9,
+	0x00, //      
+	0xF8, // #####
+	0x20, //   #  
+	0x20, //   #  
+	0x20, //   #  
+	0x20, //   #  
+	0xF8, // #####
+	0x00, //      
+	0x00  //      
+};
+
+/*
+ *  'OO'
+ */
+static const uint8_t Font9_181[] = {
+	6, 9,
+	1, 9,
+	0x10, //    # 
+	0xF8, // #####
+	0x10, //    # 
+	0x30, //   ## 
+	0x50, //  # # 
+	0x90, // #  # 
+	0x10, //    # 
+	0x00, //      
+	0x00  //      
+};
+
+/*
+ *  'KA'
+ */
+static const uint8_t Font9_182[] = {
+	6, 9,
+	1, 9,
+	0x40, //  #   
+	0xF8, // #####
+	0x48, //  #  #
+	0x48, //  #  #
+	0x48, //  #  #
+	0x48, //  #  #
+	0x90, // #  # 
+	0x00, //      
+	0x00  //      
+};
+
+/*
+ *  'KI'
+ */
+static const uint8_t Font9_183[] = {
+	6, 9,
+	1, 9,
+	0x20, //   #  
+	0xF8, // #####
+	0x20, //   #  
+	0xF8, // #####
+	0x20, //   #  
+	0x20, //   #  
+	0x20, //   #  
+	0x00, //      
+	0x00  //      
+};
+
+/*
+ *  'KU'
+ */
+static const uint8_t Font9_184[] = {
+	6, 9,
+	1, 9,
+	0x00, //      
+	0x78, //  ####
+	0x48, //  #  #
+	0x88, // #   #
+	0x08, //     #
+	0x10, //    # 
+	0x60, //  ##  
+	0x00, //      
+	0x00  //      
+};
+
+/*
+ *  'KE'
+ */
+static const uint8_t Font9_185[] = {
+	6, 9,
+	1, 9,
+	0x40, //  #   
+	0x78, //  ####
+	0x90, // #  # 
+	0x10, //    # 
+	0x10, //    # 
+	0x10, //    # 
+	0x20, //   #  
+	0x00, //      
+	0x00  //      
+};
+
+/*
+ *  'KO'
+ */
+static const uint8_t Font9_186[] = {
+	6, 9,
+	1, 9,
+	0x00, //      
+	0xF8, // #####
+	0x08, //     #
+	0x08, //     #
+	0x08, //     #
+	0x08, //     #
+	0xF8, // #####
+	0x00, //      
+	0x00  //      
+};
+
+/*
+ *  'SA'
+ */
+static const uint8_t Font9_187[] = {
+	6, 9,
+	1, 9,
+	0x50, //  # # 
+	0xF8, // #####
+	0x50, //  # # 
+	0x50, //  # # 
+	0x10, //    # 
+	0x20, //   #  
+	0x40, //  #   
+	0x00, //      
+	0x00  //      
+};
+
+/*
+ *  'SI'
+ */
+static const uint8_t Font9_188[] = {
+	6, 9,
+	1, 9,
+	0x00, //      
+	0xC0, // ##   
+	0x08, //     #
+	0xC8, // ##  #
+	0x08, //     #
+	0x10, //    # 
+	0xE0, // ###  
+	0x00, //      
+	0x00  //      
+};
+
+/*
+ *  'SU'
+ */
+static const uint8_t Font9_189[] = {
+	6, 9,
+	1, 9,
+	0x00, //      
+	0xF8, // #####
+	0x08, //     #
+	0x10, //    # 
+	0x20, //   #  
+	0x50, //  # # 
+	0x88, // #   #
+	0x00, //      
+	0x00  //      
+};
+
+/*
+ *  'SE'
+ */
+static const uint8_t Font9_190[] = {
+	6, 9,
+	1, 9,
+	0x40, //  #   
+	0xF8, // #####
+	0x48, //  #  #
+	0x50, //  # # 
+	0x40, //  #   
+	0x40, //  #   
+	0x38, //   ###
+	0x00, //      
+	0x00  //      
+};
+
+/*
+ *  'SO'
+ */
+static const uint8_t Font9_191[] = {
+	6, 9,
+	1, 9,
+	0x00, //      
+	0x88, // #   #
+	0x88, // #   #
+	0x48, //  #  #
+	0x08, //     #
+	0x10, //    # 
+	0x60, //  ##  
+	0x00, //      
+	0x00  //      
+};
+
+/*
+ *  'TA'
+ */
+static const uint8_t Font9_192[] = {
+	6, 9,
+	1, 9,
+	0x00, //      
+	0x78, //  ####
+	0x48, //  #  #
+	0xA8, // # # #
+	0x18, //    ##
+	0x10, //    # 
+	0x60, //  ##  
+	0x00, //      
+	0x00  //      
+};
+
+/*
+ *  'TI'
+ */
+static const uint8_t Font9_193[] = {
+	6, 9,
+	1, 9,
+	0x10, //    # 
+	0xE0, // ###  
+	0x20, //   #  
+	0xF8, // #####
+	0x20, //   #  
+	0x20, //   #  
+	0x40, //  #   
+	0x00, //      
+	0x00  //      
+};
+
+/*
+ *  'TU'
+ */
+static const uint8_t Font9_194[] = {
+	6, 9,
+	1, 9,
+	0x00, //      
+	0xA8, // # # #
+	0xA8, // # # #
+	0xA8, // # # #
+	0x08, //     #
+	0x10, //    # 
+	0x20, //   #  
+	0x00, //      
+	0x00  //      
+};
+
+/*
+ *  'TE'
+ */
+static const uint8_t Font9_195[] = {
+	6, 9,
+	1, 9,
+	0x70, //  ### 
+	0x00, //      
+	0xF8, // #####
+	0x20, //   #  
+	0x20, //   #  
+	0x20, //   #  
+	0x40, //  #   
+	0x00, //      
+	0x00  //      
+};
+
+/*
+ *  'TO'
+ */
+static const uint8_t Font9_196[] = {
+	6, 9,
+	1, 9,
+	0x40, //  #   
+	0x40, //  #   
+	0x40, //  #   
+	0x60, //  ##  
+	0x50, //  # # 
+	0x40, //  #   
+	0x40, //  #   
+	0x00, //      
+	0x00  //      
+};
+
+/*
+ *  'NA'
+ */
+static const uint8_t Font9_197[] = {
+	6, 9,
+	1, 9,
+	0x20, //   #  
+	0x20, //   #  
+	0xF8, // #####
+	0x20, //   #  
+	0x20, //   #  
+	0x40, //  #   
+	0x80, // #    
+	0x00, //      
+	0x00  //      
+};
+
+/*
+ *  'NI'
+ */
+static const uint8_t Font9_198[] = {
+	6, 9,
+	1, 9,
+	0x00, //      
+	0x70, //  ### 
+	0x00, //      
+	0x00, //      
+	0x00, //      
+	0x00, //      
+	0xF8, // #####
+	0x00, //      
+	0x00  //      
+};
+
+/*
+ *  'NU'
+ */
+static const uint8_t Font9_199[] = {
+	6, 9,
+	1, 9,
+	0x00, //      
+	0xF8, // #####
+	0x08, //     #
+	0x50, //  # # 
+	0x40, //   #  
+	0x50, //  # # 
+	0x80, // #    
+	0x00, //      
+	0x00  //      
+};
+
+/*
+ *  'NE'
+ */
+static const uint8_t Font9_200[] = {
+	6, 9,
+	1, 9,
+	0x20, //   #  
+	0xF8, // #####
+	0x10, //    # 
+	0x20, //   #  
+	0x70, //  ### 
+	0xA8, // # # #
+	0x20, //   #  
+	0x00, //      
+	0x00  //      
+};
+
+/*
+ *  'NO'
+ */
+static const uint8_t Font9_201[] = {
+	6, 9,
+	1, 9,
+	0x10, //    # 
+	0x10, //    # 
+	0x10, //    # 
+	0x10, //    # 
+	0x10, //    # 
+	0x20, //   #  
+	0x40, //  #   
+	0x00, //      
+	0x00  //      
+};
+
+/*
+ *  'HA'
+ */
+static const uint8_t Font9_202[] = {
+	6, 9,
+	1, 9,
+	0x00, //      
+	0x20, //   #  
+	0x10, //    # 
+	0x88, // #   #
+	0x88, // #   #
+	0x88, // #   #
+	0x88, // #   #
+	0x00, //      
+	0x00  //      
+};
+
+/*
+ *  'HI'
+ */
+static const uint8_t Font9_203[] = {
+	6, 9,
+	1, 9,
+	0x80, // #    
+	0x80, // #    
+	0xF8, // #####
+	0x80, // #    
+	0x80, // #    
+	0x80, // #    
+	0x78, //  ####
+	0x00, //      
+	0x00  //      
+};
+
+/*
+ *  'HU'
+ */
+static const uint8_t Font9_204[] = {
+	6, 9,
+	1, 9,
+	0x00, //      
+	0xF8, // #####
+	0x08, //     #
+	0x08, //     #
+	0x08, //     #
+	0x10, //    # 
+	0x60, //  ##  
+	0x00, //      
+	0x00  //      
+};
+
+/*
+ *  'HE'
+ */
+static const uint8_t Font9_205[] = {
+	6, 9,
+	1, 9,
+	0x00, //      
+	0x40, //  #   
+	0xA0, // # #  
+	0x10, //    # 
+	0x08, //     #
+	0x08, //     #
+	0x00, //      
+	0x00, //      
+	0x00  //      
+};
+
+/*
+ *  'HO'
+ */
+static const uint8_t Font9_206[] = {
+	6, 9,
+	1, 9,
+	0x20, //   #  
+	0xF8, // #####
+	0x20, //   #  
+	0x20, //   #  
+	0xA8, // # # #
+	0xA8, // # # #
+	0x20, //   #  
+	0x00, //      
+	0x00  //      
+};
+
+/*
+ *  'MA'
+ */
+static const uint8_t Font9_207[] = {
+	6, 9,
+	1, 9,
+	0x00, //      
+	0xF8, // #####
+	0x08, //     #
+	0x08, //     #
+	0x50, //  # # 
+	0x20, //   #  
+	0x10, //    # 
+	0x00, //      
+	0x00  //      
+};
+
+/*
+ *  'MI'
+ */
+static const uint8_t Font9_208[] = {
+	6, 9,
+	1, 9,
+	0x00, //      
+	0x70, //  ### 
+	0x00, //      
+	0x70, //  ### 
+	0x00, //      
+	0x70, //  ### 
+	0x08, //     #
+	0x00, //      
+	0x00  //      
+};
+
+/*
+ *  'MU'
+ */
+static const uint8_t Font9_209[] = {
+	6, 9,
+	1, 9,
+	0x00, //      
+	0x20, //   #  
+	0x40, //  #   
+	0x80, // #    
+	0x88, // #   #
+	0xF8, // #####
+	0x08, //     #
+	0x00, //      
+	0x00  //      
+};
+
+/*
+ *  'ME'
+ */
+static const uint8_t Font9_210[] = {
+	6, 9,
+	1, 9,
+	0x00, //      
+	0x08, //     #
+	0x08, //     #
+	0x50, //  # # 
+	0x20, //   #  
+	0x50, //  # # 
+	0x80, // #    
+	0x00, //      
+	0x00  //      
+};
+
+/*
+ *  'MO'
+ */
+static const uint8_t Font9_211[] = {
+	6, 9,
+	1, 9,
+	0x00, //      
+	0xF8, // #####
+	0x40, //  #   
+	0xF8, // #####
+	0x40, //  #   
+	0x40, //  #   
+	0x38, //   ###
+	0x00, //      
+	0x00  //      
+};
+
+/*
+ *  'YA'
+ */
+static const uint8_t Font9_212[] = {
+	6, 9,
+	1, 9,
+	0x40, //  #   
+	0x40, //  #   
+	0xF8, // #####
+	0x48, //  #  #
+	0x50, //  # # 
+	0x40, //  #   
+	0x40, //  #   
+	0x00, //      
+	0x00  //      
+};
+
+/*
+ *  'YU'
+ */
+static const uint8_t Font9_213[] = {
+	6, 9,
+	1, 9,
+	0x00, //      
+	0x70, //  ### 
+	0x10, //    # 
+	0x10, //    # 
+	0x10, //    # 
+	0x10, //    # 
+	0xF8, // #####
+	0x00, //      
+	0x00  //      
+};
+
+/*
+ *  'YO'
+ */
+static const uint8_t Font9_214[] = {
+	6, 9,
+	1, 9,
+	0x00, //      
+	0xF8, // ######
+	0x08, //      #
+	0xF8, // ######
+	0x08, //      #
+	0x08, //      #
+	0xF8, // ######
+	0x00, //      
+	0x00  //      
+};
+
+/*
+ *  'RA'
+ */
+static const uint8_t Font9_215[] = {
+	6, 9,
+	1, 9,
+	0x70, //  ### 
+	0x00, //      
+	0xF8, // #####
+	0x08, //     #
+	0x08, //     #
+	0x10, //    # 
+	0x20, //   #  
+	0x00, //      
+	0x00  //      
+};
+
+/*
+ *  'RI'
+ */
+static const uint8_t Font9_216[] = {
+	6, 9,
+	1, 9,
+	0x90, // #  # 
+	0x90, // #  # 
+	0x90, // #  # 
+	0x90, // #  # 
+	0x10, //    # 
+	0x20, //   #  
+	0x40, //  #   
+	0x00, //      
+	0x00  //      
+};
+
+/*
+ *  'RU'
+ */
+static const uint8_t Font9_217[] = {
+	6, 9,
+	1, 9,
+	0x00, //      
+	0x20, //   #  
+	0xA0, // # #  
+	0xA0, // # #  
+	0xA8, // # # #
+	0xA8, // # # #
+	0xB0, // # ## 
+	0x00, //      
+	0x00  //      
+};
+
+/*
+ *  'RE'
+ */
+static const uint8_t Font9_218[] = {
+	6, 9,
+	1, 9,
+	0x00, //      
+	0x80, // #    
+	0x80, // #    
+	0x88, // #   #
+	0x90, // #  # 
+	0xA0, // # #  
+	0xC0, // ##   
+	0x00, //      
+	0x00  //      
+};
+
+/*
+ *  'RO'
+ */
+static const uint8_t Font9_219[] = {
+	6, 9,
+	1, 9,
+	0x00, //      
+	0xF8, // #####
+	0x88, // #   #
+	0x88, // #   #
+	0x88, // #   #
+	0x88, // #   #
+	0xF8, // #####
+	0x00, //      
+	0x00  //      
+};
+
+/*
+ *  'WA'
+ */
+static const uint8_t Font9_220[] = {
+	6, 9,
+	1, 9,
+	0x00, //      
+	0xF8, // #####
+	0x88, // #   #
+	0x88, // #   #
+	0x08, //     #
+	0x10, //    # 
+	0x20, //   #  
+	0x00, //      
+	0x00  //      
+};
+
+/*
+ *  'NN'
+ */
+static const uint8_t Font9_221[] = {
+	6, 9,
+	1, 9,
+	0x00, //      
+	0xC0, // ##   
+	0x00, //      
+	0x08, //     #
+	0x08, //     #
+	0x10, //    # 
+	0xE0, // ###  
+	0x00, //      
+	0x00  //      
+};
+
+/*
+ *  dakuten
+ */
+static const uint8_t Font9_222[] = {
+	6, 9,
+	1, 9,
+	0x20, //   #  
+	0x90, // #  # 
+	0x40, //  #   
+	0x00, //      
+	0x00, //      
+	0x00, //      
+	0x00, //      
+	0x00, //      
+	0x00  //      
+};
+
+/*
+ *  maru
+ */
+static const uint8_t Font9_223[] = {
+	6, 9,
+	1, 9,
+	0xE0, // ###  
+	0xA0, // # #  
+	0xE0, // ###  
+	0x00, //      
+	0x00, //      
+	0x00, //      
+	0x00, //      
+	0x00, //      
+	0x00  //      
+};
+
+
+
+static const font_t *Font9[] = {
+	(font_t *)Font9_32,  (font_t *)Font9_01,  (font_t *)Font9_02,  (font_t *)Font9_03,
+	(font_t *)Font9_04,  (font_t *)Font9_05,  (font_t *)Font9_06,  (font_t *)Font9_07,
+	(font_t *)Font9_08,  (font_t *)Font9_09,  (font_t *)Font9_10,  (font_t *)Font9_11,
+	(font_t *)Font9_12,  (font_t *)Font9_13,  (font_t *)Font9_14,  (font_t *)Font9_15,
+	(font_t *)Font9_16,  (font_t *)Font9_17,  (font_t *)Font9_18,  (font_t *)Font9_19,
+	(font_t *)Font9_20,  (font_t *)Font9_21,  (font_t *)Font9_22,  (font_t *)Font9_23,
+	(font_t *)Font9_24,  (font_t *)Font9_25,  (font_t *)Font9_26,  (font_t *)Font9_27,
+	(font_t *)Font9_28,  (font_t *)Font9_29,  (font_t *)Font9_30,  (font_t *)Font9_31,
+	(font_t *)Font9_32,  (font_t *)Font9_33,  (font_t *)Font9_34,  (font_t *)Font9_35,
+	(font_t *)Font9_36,  (font_t *)Font9_37,  (font_t *)Font9_38,  (font_t *)Font9_39,
+	(font_t *)Font9_40,  (font_t *)Font9_41,  (font_t *)Font9_42,  (font_t *)Font9_43,
+	(font_t *)Font9_44,  (font_t *)Font9_45,  (font_t *)Font9_46,  (font_t *)Font9_47,
+	(font_t *)Font9_48,  (font_t *)Font9_49,  (font_t *)Font9_50,  (font_t *)Font9_51,
+	(font_t *)Font9_52,  (font_t *)Font9_53,  (font_t *)Font9_54,  (font_t *)Font9_55,
+	(font_t *)Font9_56,  (font_t *)Font9_57,  (font_t *)Font9_58,  (font_t *)Font9_59,
+	(font_t *)Font9_60,  (font_t *)Font9_61,  (font_t *)Font9_62,  (font_t *)Font9_63,
+	(font_t *)Font9_64,  (font_t *)Font9_65,  (font_t *)Font9_66,  (font_t *)Font9_67,
+	(font_t *)Font9_68,  (font_t *)Font9_69,  (font_t *)Font9_70,  (font_t *)Font9_71,
+	(font_t *)Font9_72,  (font_t *)Font9_73,  (font_t *)Font9_74,  (font_t *)Font9_75,
+	(font_t *)Font9_76,  (font_t *)Font9_77,  (font_t *)Font9_78,  (font_t *)Font9_79,
+	(font_t *)Font9_80,  (font_t *)Font9_81,  (font_t *)Font9_82,  (font_t *)Font9_83,
+	(font_t *)Font9_84,  (font_t *)Font9_85,  (font_t *)Font9_86,  (font_t *)Font9_87,
+	(font_t *)Font9_88,  (font_t *)Font9_89,  (font_t *)Font9_90,  (font_t *)Font9_91,
+	(font_t *)Font9_92,  (font_t *)Font9_93,  (font_t *)Font9_94,  (font_t *)Font9_95,
+	(font_t *)Font9_96,  (font_t *)Font9_97,  (font_t *)Font9_98,  (font_t *)Font9_99,
+	(font_t *)Font9_100, (font_t *)Font9_101, (font_t *)Font9_102, (font_t *)Font9_103,
+	(font_t *)Font9_104, (font_t *)Font9_105, (font_t *)Font9_106, (font_t *)Font9_107,
+	(font_t *)Font9_108, (font_t *)Font9_109, (font_t *)Font9_110, (font_t *)Font9_111,
+	(font_t *)Font9_112, (font_t *)Font9_113, (font_t *)Font9_114, (font_t *)Font9_115,
+	(font_t *)Font9_116, (font_t *)Font9_117, (font_t *)Font9_118, (font_t *)Font9_119,
+	(font_t *)Font9_120, (font_t *)Font9_121, (font_t *)Font9_122, (font_t *)Font9_123,
+	(font_t *)Font9_124, (font_t *)Font9_125, (font_t *)Font9_126, (font_t *)Font9_127,
+
+	0,                    0,                    0,                    0,
+	0,                    0,                    0,                    0,
+	0,                    0,                    0,                    0,
+	0,                    0,                    0,                    0,
+	0,                    0,                    0,                    0,
+	0,                    0,                    0,                    0,
+	0,                    0,                    0,                    0,
+	0,                    0,                    0,                    0,
+	(font_t *)Font9_160, (font_t *)Font9_161, (font_t *)Font9_162, (font_t *)Font9_163,
+	(font_t *)Font9_164, (font_t *)Font9_165, (font_t *)Font9_166, (font_t *)Font9_167,
+	(font_t *)Font9_168, (font_t *)Font9_169, (font_t *)Font9_170, (font_t *)Font9_171,
+	(font_t *)Font9_172, (font_t *)Font9_173, (font_t *)Font9_174, (font_t *)Font9_175,
+	(font_t *)Font9_176, (font_t *)Font9_177, (font_t *)Font9_178, (font_t *)Font9_179,
+	(font_t *)Font9_180, (font_t *)Font9_181, (font_t *)Font9_182, (font_t *)Font9_183,
+	(font_t *)Font9_184, (font_t *)Font9_185, (font_t *)Font9_186, (font_t *)Font9_187,
+	(font_t *)Font9_188, (font_t *)Font9_189, (font_t *)Font9_190, (font_t *)Font9_191,
+	(font_t *)Font9_192, (font_t *)Font9_193, (font_t *)Font9_194, (font_t *)Font9_195,
+	(font_t *)Font9_196, (font_t *)Font9_197, (font_t *)Font9_198, (font_t *)Font9_199,
+	(font_t *)Font9_200, (font_t *)Font9_201, (font_t *)Font9_202, (font_t *)Font9_203,
+	(font_t *)Font9_204, (font_t *)Font9_205, (font_t *)Font9_206, (font_t *)Font9_207,
+	(font_t *)Font9_208, (font_t *)Font9_209, (font_t *)Font9_210, (font_t *)Font9_211,
+	(font_t *)Font9_212, (font_t *)Font9_213, (font_t *)Font9_214, (font_t *)Font9_215,
+	(font_t *)Font9_216, (font_t *)Font9_217, (font_t *)Font9_218, (font_t *)Font9_219,
+	(font_t *)Font9_220, (font_t *)Font9_221, (font_t *)Font9_222, (font_t *)Font9_223,
+};
+
+font_head_t Embedded_Font9 = {
+	"embedded_font9",
+	0x00,
+	0x00,
+	6,
+	9,
+	Font9,
+	NULL
+};
+
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/ui/snfont_disp/fonts.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/ui/snfont_disp/fonts.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/ui/snfont_disp/fonts.h	(revision 457)
@@ -0,0 +1,110 @@
+/*
+ *  TOPPERS BASE PLATFORM MIDDLEWARE
+ * 
+ *  Copyright (C) 2017-2018 by TOPPERS PROJECT
+ *                             Educational Working Group.
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  $Id$
+ */
+
+/*
+ *  FONTのヘッダファイル
+ */
+
+#ifndef _FONTS_H_
+#define _FONTS_H_
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+#include <t_stddef.h>
+
+#define NUM_FONTS   224
+
+#ifndef TOPPERS_MACRO_ONLY
+
+/*
+ *  FONT構造体定義
+ */
+typedef struct _font_s {
+	uint8_t     width;
+	uint8_t     height;
+	uint8_t     stride;
+	uint8_t     iheight;
+	uint8_t     image[8];
+} font_t;
+
+/*
+ *  FONTヘッダ構造体定義
+ */
+typedef struct _font_head_s {
+	const char  font_name[32];
+	uint8_t     file_attribute;
+	uint8_t     font_attribute;
+	uint8_t     font_width;
+	uint8_t     font_height;
+	const font_t **font_table;
+	void        *pdata;
+} font_head_t;
+
+typedef struct font_file_head_s {
+	char           magic[4];
+	char           name[32];
+	unsigned int   fsize;
+	unsigned int   csize;
+	unsigned int   isize;
+	unsigned int   off_cnv_table1;
+	unsigned int   siz_cnv_table1;
+	unsigned int   off_cnv_table2;
+	unsigned int   siz_cnv_table2;
+	unsigned int   off_cnv_table3;
+	unsigned int   siz_cnv_table3;
+	unsigned int   off_2byte_font;
+	unsigned int   siz_2byte_font;
+	unsigned int   off_3byte_font;
+	unsigned int   siz_3byte_font;
+} font_file_head_t;
+
+extern font_head_t Embedded_Font9;
+extern font_head_t Shinonome_Font12;
+extern font_head_t Shinonome_Font16;
+
+
+#endif /* TOPPERS_MACRO_ONLY */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/ui/snfont_disp/glcd_disp.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/ui/snfont_disp/glcd_disp.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/ui/snfont_disp/glcd_disp.c	(revision 457)
@@ -0,0 +1,1276 @@
+/*
+ *  TOPPERS BASE PLATFORM MIDDLEWARE
+ * 
+ *  Copyright (C) 2017-2019 by TOPPERS PROJECT
+ *                             Educational Working Group.
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  $Id$
+ */
+/* 
+ *  GRAPHIC-LCDテキスト表示プログラムの本体
+ */
+
+#include <kernel.h>
+#include <t_syslog.h>
+#include <t_stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <target_syssvc.h>
+#include "syssvc/serial.h"
+#include "syssvc/syslog.h"
+#ifndef NOT_USEFILFONT
+#include "fcntl.h"
+#endif
+#include "glcd_disp.h"
+
+/*
+ *  東雲漢字のイメージデータは以下のファイルにある
+ *  東雲フォントを使用する場合は、以下のフォントデータを
+ *  デフォルトドライブのrootに置いてください
+ *  shinonome_font12.fnt(12x12)
+ *  shinonome_font16.fnt(16x16)
+ */
+
+
+#define NUM_FONT_WORK   2
+
+typedef struct font_work_s {
+	FILE     *pffont;
+	uint8_t  arrtibute;
+	uint8_t  image_size;
+	uint16_t num_table2B;
+	uint32_t num_table3B;
+	uint32_t offset_image_2B;
+	uint32_t offset_image_3B;
+	uint8_t  table[256];
+} font_work_t;
+
+#ifndef NOT_USEFILFONT
+/*
+ *  2バイトコード　1バイト目
+ */
+static const uint8_t Utf8CodeTable_2B_1st[][2] = {
+	{0xC2, 0x06},
+	{0xC3, 0x02},
+	{0xCE, 0x27},
+	{0xCF, 0x09},
+	{0xD0, 0x31},
+	{0xD1, 0x11}
+};
+
+/*
+ *  3バイトコード 1バイト目
+ */
+static const uint8_t Utf8CodeTable_3B_1st[][2] = {
+	{0xE2, 0x0E},
+	{0xE3, 0x04},
+	{0xE4, 0x08},
+	{0xE5, 0x40},
+	{0xE6, 0x40},
+	{0xE7, 0x3F},
+	{0xE8, 0x3F},
+	{0xE9, 0x3C},
+	{0xEF, 0x03}
+};
+
+/*
+ *  3バイトコード 2バイト目
+ */
+static const uint8_t Utf8CodeTable_3B_2nd[][2] = {
+	{0x80, 0x0E},
+	{0x84, 0x02},
+	{0x86, 0x04},
+	{0x87, 0x02},
+	{0x88, 0x14},
+	{0x89, 0x07},
+	{0x8A, 0x05},
+	{0x8C, 0x01},
+	{0x94, 0x1E},
+	{0x95, 0x02},
+	{0x96, 0x06},
+	{0x97, 0x06},
+	{0x98, 0x02},
+	{0x99, 0x05},
+	{0x80, 0x15},
+	{0x81, 0x3F},
+	{0x82, 0x37},
+	{0x83, 0x3B},
+	{0xB8, 0x1F},
+	{0xB9, 0x13},
+	{0xBA, 0x23},
+	{0xBB, 0x1E},
+	{0xBC, 0x13},
+	{0xBD, 0x1A},
+	{0xBE, 0x14},
+	{0xBF, 0x1A},
+	{0x80, 0x1A},
+	{0x81, 0x12},
+	{0x82, 0x0F},
+	{0x83, 0x13},
+	{0x84, 0x14},
+	{0x85, 0x21},
+	{0x86, 0x24},
+	{0x87, 0x1B},
+	{0x88, 0x1B},
+	{0x89, 0x1A},
+	{0x8A, 0x17},
+	{0x8B, 0x1C},
+	{0x8C, 0x1A},
+	{0x8D, 0x21},
+	{0x8E, 0x11},
+	{0x8F, 0x24},
+	{0x90, 0x1E},
+	{0x91, 0x14},
+	{0x92, 0x16},
+	{0x93, 0x13},
+	{0x94, 0x0E},
+	{0x95, 0x0F},
+	{0x96, 0x17},
+	{0x97, 0x0D},
+	{0x98, 0x0E},
+	{0x99, 0x0D},
+	{0x9A, 0x0D},
+	{0x9B, 0x17},
+	{0x9C, 0x16},
+	{0x9D, 0x0E},
+	{0x9E, 0x0C},
+	{0x9F, 0x12},
+	{0xA0, 0x13},
+	{0xA1, 0x14},
+	{0xA2, 0x0F},
+	{0xA3, 0x1D},
+	{0xA4, 0x1A},
+	{0xA5, 0x1A},
+	{0xA6, 0x13},
+	{0xA7, 0x12},
+	{0xA8, 0x0F},
+	{0xA9, 0x0A},
+	{0xAA, 0x06},
+	{0xAB, 0x0E},
+	{0xAC, 0x0B},
+	{0xAD, 0x1A},
+	{0xAE, 0x21},
+	{0xAF, 0x22},
+	{0xB0, 0x1F},
+	{0xB1, 0x19},
+	{0xB2, 0x11},
+	{0xB3, 0x0F},
+	{0xB4, 0x0F},
+	{0xB5, 0x0B},
+	{0xB6, 0x0E},
+	{0xB7, 0x1A},
+	{0xB8, 0x15},
+	{0xB9, 0x1C},
+	{0xBA, 0x14},
+	{0xBB, 0x21},
+	{0xBC, 0x1F},
+	{0xBD, 0x1B},
+	{0xBE, 0x1F},
+	{0xBF, 0x14},
+	{0x80, 0x16},
+	{0x81, 0x1C},
+	{0x82, 0x1C},
+	{0x83, 0x17},
+	{0x84, 0x16},
+	{0x85, 0x20},
+	{0x86, 0x14},
+	{0x87, 0x16},
+	{0x88, 0x1D},
+	{0x89, 0x17},
+	{0x8A, 0x19},
+	{0x8B, 0x22},
+	{0x8C, 0x11},
+	{0x8D, 0x12},
+	{0x8E, 0x1C},
+	{0x8F, 0x12},
+	{0x90, 0x0F},
+	{0x91, 0x09},
+	{0x92, 0x12},
+	{0x93, 0x18},
+	{0x94, 0x14},
+	{0x95, 0x16},
+	{0x96, 0x1B},
+	{0x97, 0x19},
+	{0x98, 0x17},
+	{0x99, 0x17},
+	{0x9A, 0x15},
+	{0x9B, 0x18},
+	{0x9C, 0x1F},
+	{0x9D, 0x1F},
+	{0x9E, 0x17},
+	{0x9F, 0x1C},
+	{0xA0, 0x12},
+	{0xA1, 0x17},
+	{0xA2, 0x1A},
+	{0xA3, 0x16},
+	{0xA4, 0x1C},
+	{0xA5, 0x1A},
+	{0xA6, 0x12},
+	{0xA7, 0x17},
+	{0xA8, 0x1A},
+	{0xA9, 0x0D},
+	{0xAA, 0x10},
+	{0xAB, 0x0D},
+	{0xAC, 0x12},
+	{0xAD, 0x19},
+	{0xAE, 0x1A},
+	{0xAF, 0x10},
+	{0xB0, 0x0D},
+	{0xB1, 0x15},
+	{0xB2, 0x1B},
+	{0xB3, 0x16},
+	{0xB4, 0x14},
+	{0xB5, 0x11},
+	{0xB6, 0x0E},
+	{0xB7, 0x1B},
+	{0xB8, 0x1C},
+	{0xB9, 0x10},
+	{0xBA, 0x13},
+	{0xBB, 0x14},
+	{0xBC, 0x13},
+	{0xBD, 0x11},
+	{0xBE, 0x0F},
+	{0xBF, 0x16},
+	{0x80, 0x12},
+	{0x81, 0x0A},
+	{0x82, 0x0D},
+	{0x83, 0x09},
+	{0x84, 0x09},
+	{0x85, 0x0F},
+	{0x86, 0x0D},
+	{0x87, 0x16},
+	{0x88, 0x12},
+	{0x89, 0x15},
+	{0x8A, 0x0E},
+	{0x8B, 0x15},
+	{0x8C, 0x12},
+	{0x8D, 0x0E},
+	{0x8E, 0x09},
+	{0x8F, 0x0F},
+	{0x90, 0x0D},
+	{0x91, 0x12},
+	{0x92, 0x07},
+	{0x93, 0x11},
+	{0x94, 0x1D},
+	{0x95, 0x20},
+	{0x96, 0x18},
+	{0x97, 0x18},
+	{0x98, 0x0D},
+	{0x99, 0x19},
+	{0x9A, 0x15},
+	{0x9B, 0x19},
+	{0x9C, 0x13},
+	{0x9D, 0x0D},
+	{0x9E, 0x10},
+	{0x9F, 0x10},
+	{0xA0, 0x0D},
+	{0xA1, 0x08},
+	{0xA2, 0x14},
+	{0xA3, 0x0F},
+	{0xA4, 0x0D},
+	{0xA5, 0x16},
+	{0xA6, 0x14},
+	{0xA7, 0x12},
+	{0xA8, 0x16},
+	{0xA9, 0x16},
+	{0xAA, 0x13},
+	{0xAB, 0x20},
+	{0xAC, 0x15},
+	{0xAD, 0x17},
+	{0xAE, 0x15},
+	{0xAF, 0x13},
+	{0xB0, 0x13},
+	{0xB1, 0x11},
+	{0xB2, 0x1C},
+	{0xB3, 0x16},
+	{0xB4, 0x1F},
+	{0xB5, 0x1A},
+	{0xB6, 0x1A},
+	{0xB7, 0x16},
+	{0xB8, 0x19},
+	{0xB9, 0x18},
+	{0xBA, 0x0E},
+	{0xBC, 0x03},
+	{0xBD, 0x17},
+	{0xBE, 0x18},
+	{0xBF, 0x12},
+	{0x80, 0x16},
+	{0x81, 0x16},
+	{0x82, 0x19},
+	{0x83, 0x14},
+	{0x84, 0x10},
+	{0x85, 0x14},
+	{0x86, 0x18},
+	{0x87, 0x19},
+	{0x88, 0x1E},
+	{0x89, 0x15},
+	{0x8A, 0x12},
+	{0x8B, 0x17},
+	{0x8C, 0x16},
+	{0x8D, 0x0D},
+	{0x8E, 0x12},
+	{0x8F, 0x15},
+	{0x90, 0x12},
+	{0x91, 0x14},
+	{0x92, 0x10},
+	{0x93, 0x11},
+	{0x94, 0x10},
+	{0x95, 0x13},
+	{0x96, 0x17},
+	{0x97, 0x11},
+	{0x98, 0x0E},
+	{0x99, 0x0E},
+	{0x9A, 0x0D},
+	{0x9B, 0x16},
+	{0x9C, 0x13},
+	{0x9D, 0x13},
+	{0x9E, 0x0A},
+	{0x9F, 0x0F},
+	{0xA0, 0x0F},
+	{0xA1, 0x19},
+	{0xA2, 0x14},
+	{0xA3, 0x17},
+	{0xA4, 0x10},
+	{0xA5, 0x13},
+	{0xA6, 0x19},
+	{0xA7, 0x0A},
+	{0xA8, 0x1A},
+	{0xA9, 0x18},
+	{0xAA, 0x1B},
+	{0xAB, 0x1C},
+	{0xAC, 0x18},
+	{0xAD, 0x15},
+	{0xAE, 0x0B},
+	{0xB0, 0x03},
+	{0xB1, 0x12},
+	{0xB2, 0x22},
+	{0xB3, 0x1B},
+	{0xB4, 0x0C},
+	{0xB5, 0x0A},
+	{0xB6, 0x09},
+	{0xB7, 0x13},
+	{0xB8, 0x0C},
+	{0xB9, 0x12},
+	{0xBA, 0x13},
+	{0xBB, 0x12},
+	{0xBC, 0x18},
+	{0xBD, 0x0F},
+	{0xBE, 0x12},
+	{0xBF, 0x16},
+	{0x80, 0x23},
+	{0x81, 0x27},
+	{0x82, 0x12},
+	{0x83, 0x0C},
+	{0x84, 0x06},
+	{0x85, 0x15},
+	{0x86, 0x12},
+	{0x87, 0x1B},
+	{0x88, 0x0B},
+	{0x89, 0x0F},
+	{0x8A, 0x0E},
+	{0x8B, 0x0B},
+	{0x8C, 0x13},
+	{0x8D, 0x0D},
+	{0x8E, 0x0B},
+	{0x8F, 0x0C},
+	{0x90, 0x0E},
+	{0x91, 0x12},
+	{0x92, 0x01},
+	{0x95, 0x01},
+	{0x96, 0x1B},
+	{0x97, 0x0D},
+	{0x98, 0x09},
+	{0x99, 0x1D},
+	{0x9A, 0x1E},
+	{0x9B, 0x1C},
+	{0x9C, 0x18},
+	{0x9D, 0x18},
+	{0x9E, 0x12},
+	{0x9F, 0x0E},
+	{0xA0, 0x19},
+	{0xA1, 0x12},
+	{0xA2, 0x05},
+	{0xA3, 0x11},
+	{0xA4, 0x14},
+	{0xA5, 0x0A},
+	{0xA6, 0x0C},
+	{0xA7, 0x15},
+	{0xA8, 0x0C},
+	{0xA9, 0x10},
+	{0xAA, 0x05},
+	{0xAB, 0x15},
+	{0xAC, 0x11},
+	{0xAD, 0x0E},
+	{0xAE, 0x10},
+	{0xAF, 0x13},
+	{0xB0, 0x19},
+	{0xB1, 0x0A},
+	{0xB3, 0x09},
+	{0xB4, 0x13},
+	{0xB5, 0x11},
+	{0xB6, 0x0D},
+	{0xB7, 0x0F},
+	{0xB8, 0x03},
+	{0xB9, 0x05},
+	{0xBA, 0x17},
+	{0xBB, 0x19},
+	{0xBC, 0x0A},
+	{0xBD, 0x12},
+	{0xBE, 0x05},
+	{0xBC, 0x3D},
+	{0xBD, 0x1F},
+	{0xBF, 0x05}
+};
+
+/*
+ *  2バイトコード 2バイト目
+ */
+static const uint8_t Utf8CodeTable_2B_2nd[] = {
+	0xA7, 0xA8, 0xB0, 0xB1, 0xB4, 0xB6, 0x97, 0xB7, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, /* 0000-0015 */
+	0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0x9F, 0xA0, 0xA1, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8, 0xA9,	/* 0016-0031 */
+	0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF, 0x80,	/* 0032-0047 */
+	0x81, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x81, 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96,	/* 0048-0063 */
+	0x97, 0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0x9F, 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6,	/* 0064-0079 */
+	0xA7, 0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF, 0xB0, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6,	/* 0080-0095 */
+	0xB7, 0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF, 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86,	/* 0096-0111 */
+	0x87, 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F, 0x91                                      /* 0112-0121 */
+};
+
+// 3バイトコード 3バイト目 bitmapデータ
+static const uint8_t Utf8CodeTable_3B_3rd[] = {
+	0x90, 0x95, 0x98, 0x99, 0x9C, 0x9D, 0xA0, 0xA1, 0xA5, 0xA6, 0xB0, 0xB2, 0xB3, 0xBB, 0x83, 0xAB,	/* 0000-0015 */
+	0x90, 0x91, 0x92, 0x93, 0x92, 0x94, 0x80, 0x82, 0x83, 0x87, 0x88, 0x8B, 0x9A, 0x9D, 0x9E, 0xA0,	/* 0016-0031 */
+	0xA5, 0xA7, 0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xB4, 0xB5, 0xBD, 0x92, 0xA0, 0xA1, 0xA6, 0xA7, 0xAA,	/* 0032-0047 */
+	0xAB, 0x82, 0x83, 0x86, 0x87, 0xA5, 0x92, 0x80, 0x81, 0x82, 0x83, 0x8C, 0x8F, 0x90, 0x93, 0x94,	/* 0048-0063 */
+	0x97, 0x98, 0x9B, 0x9C, 0x9D, 0xA0, 0xA3, 0xA4, 0xA5, 0xA8, 0xAB, 0xAC, 0xAF, 0xB0, 0xB3, 0xB4,	/* 0064-0079 */
+	0xB7, 0xB8, 0xBB, 0xBC, 0xBF, 0x82, 0x8B, 0xA0, 0xA1, 0xB2, 0xB3, 0xBC, 0xBD, 0x86, 0x87, 0x8B,	/* 0080-0095 */
+	0x8E, 0x8F, 0xAF, 0x85, 0x86, 0x80, 0x82, 0xAA, 0xAD, 0xAF, 0x80, 0x81, 0x82, 0x83, 0x85, 0x86,	/* 0096-0111 */
+	0x87, 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F, 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x81,	/* 0112-0127 */
+	0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F, 0x90, 0x91, /* 0128-0143 */
+	0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0x9F, 0xA0, 0xA1, /* 0144-0159 */
+	0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF, 0xB0, 0xB1, /* 0160-0175 */
+	0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF, 0x80, 0x81, /* 0176-0191 */
+	0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F, 0x90, 0x91, /* 0192-0207 */
+	0x92, 0x93, 0x9B, 0x9C, 0x9D, 0x9E, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8, 0xA9, 0xAA, /* 0208-0223 */
+	0xAB, 0xAC, 0xAD, 0xAE, 0xAF, 0xB0, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 0xBA, /* 0224-0239 */
+	0xBB, 0xBC, 0xBD, 0xBE, 0xBF, 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8A, /* 0240-0255 */
+	0x8B, 0x8C, 0x8D, 0x8E, 0x8F, 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9A, /* 0256-0271 */
+	0x9B, 0x9C, 0x9D, 0x9E, 0x9F, 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8, 0xA9, 0xAA, /* 0272-0287 */
+	0xAB, 0xAC, 0xAD, 0xAE, 0xAF, 0xB0, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xBB, 0xBC, 0xBD, 0xBE, /* 0288-0303 */
+	0x80, 0x81, 0x83, 0x87, 0x88, 0x89, 0x8A, 0x8B, 0x8D, 0x8E, 0x90, 0x91, 0x94, 0x95, 0x96, 0x97, /* 0304-0319 */
+	0x98, 0x99, 0x9E, 0xA1, 0xA6, 0xAA, 0xAD, 0xB1, 0xB2, 0xB6, 0xB8, 0xB9, 0xBB, 0xBC, 0xBF, 0x82, /* 0320-0335 */
+	0x83, 0x85, 0x8B, 0x8D, 0x8E, 0x8F, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9D, 0x9E, 0x9F, 0xA2, 0xB1, /* 0336-0351 */
+	0xB3, 0xBE, 0x80, 0x82, 0x85, 0x86, 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8E, 0x91, 0x92, 0x94, 0x95, /* 0352-0367 */
+	0x98, 0x99, 0x9B, 0x9C, 0x9E, 0x9F, 0xA0, 0xA1, 0xA2, 0xA4, 0xA5, 0xA6, 0xA8, 0xAB, 0xAC, 0xAD, /* 0368-0383 */
+	0xAE, 0xB0, 0xB3, 0xB6, 0xBA, 0x80, 0x81, 0x82, 0x84, 0x86, 0x87, 0x8A, 0x8B, 0x8D, 0x8E, 0x8F, /* 0384-0399 */
+	0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9D, 0x9E, 0x9F, 0xA3, 0xA4, 0xA5, 0xAD, 0xAE, 0xB0, 0xB2, /* 0400-0415 */
+	0xB6, 0xB7, 0xBB, 0x81, 0x89, 0x8A, 0x8D, 0x8E, 0x8F, 0x90, 0x91, 0x9A, 0x9C, 0x9D, 0xAF, 0xB0, /* 0416-0431 */
+	0xB4, 0xB6, 0xB8, 0xBA, 0xBC, 0xBD, 0x83, 0x86, 0x87, 0x8D, 0x8E, 0x8F, 0x90, 0x91, 0x93, 0x95, /* 0432-0447 */
+	0x97, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0xA9, 0xAF, 0xB0, 0xB3, 0xB5, 0xB6, 0xBB, 0xBC, 0xBF, /* 0448-0463 */
+	0x83, 0x86, 0x88, 0x8B, 0x8D, 0x8F, 0x91, 0x96, 0x98, 0x9B, 0x9D, 0xA0, 0xA1, 0xAB, 0xAD, 0xAE, /* 0464-0479 */
+	0xAF, 0xB5, 0xB6, 0xBF, 0x82, 0x83, 0x84, 0x8A, 0x8E, 0x90, 0x91, 0x94, 0x97, 0x98, 0x9A, 0x9B, /* 0480-0495 */
+	0x9D, 0x9F, 0xA1, 0xA3, 0xA4, 0xA5, 0xAE, 0xAF, 0xB3, 0xB5, 0xB6, 0xB8, 0xBA, 0xBE, 0x85, 0x86, /* 0496-0511 */
+	0x89, 0x8B, 0x8D, 0x8F, 0x91, 0x92, 0x94, 0x96, 0x99, 0x9A, 0x9F, 0xA1, 0xA3, 0xA4, 0xA5, 0xA6, /* 0512-0527 */
+	0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xB6, 0xB9, 0x83, 0x87, 0x88, 0x89, 0x8F, 0x90, 0x95, 0x96, /* 0528-0543 */
+	0x9A, 0x9C, 0xA5, 0xAC, 0xB2, 0xB4, 0xB5, 0xB6, 0xB8, 0xBD, 0x80, 0x85, 0x8D, 0x91, 0x98, 0x99, /* 0544-0559 */
+	0x9A, 0xAC, 0xAD, 0xB2, 0xB3, 0xB4, 0xB5, 0xB7, 0xBE, 0x82, 0x85, 0x89, 0x8A, 0x8D, 0x8F, 0x91, /* 0560-0575 */
+	0x95, 0x96, 0x9A, 0x9E, 0xA3, 0xA5, 0xA7, 0xAD, 0xAE, 0xB5, 0xB9, 0xBB, 0x80, 0x81, 0x82, 0x84, /* 0576-0591 */
+	0x89, 0x92, 0x94, 0x95, 0x96, 0x98, 0x9A, 0x9F, 0xA1, 0xAA, 0xB2, 0xB7, 0xBA, 0xBB, 0xBC, 0xBF, /* 0592-0607 */
+	0x80, 0x81, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8B, 0x8C, 0x8D, 0x8E, 0x90, 0x92, 0x94, /* 0608-0623 */
+	0x9A, 0x9C, 0xA2, 0xA5, 0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xB1, 0xB5, 0xB6, 0xB7, 0xB8, /* 0624-0639 */
+	0xBC, 0x80, 0x82, 0x85, 0x86, 0x89, 0x8A, 0x8C, 0x8D, 0x8F, 0x90, 0x91, 0x92, 0x93, 0x95, 0x96, /* 0640-0655 */
+	0x97, 0x99, 0xA0, 0xA2, 0xA4, 0xA5, 0xA6, 0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xB0, 0xB1, 0xB2, 0xB3, /* 0656-0671 */
+	0xB4, 0xB5, 0xB6, 0xB7, 0xBD, 0x84, 0x85, 0x86, 0x89, 0x8B, 0x8C, 0x8D, 0x96, 0x9B, 0x9C, 0x9D, /* 0672-0687 */
+	0xA0, 0xA1, 0xA6, 0xA7, 0xA9, 0xAA, 0xAD, 0xB0, 0xB1, 0xB5, 0xB6, 0xB8, 0xB9, 0xBA, 0xBD, 0xBE, /* 0688-0703 */
+	0x80, 0x83, 0x84, 0x86, 0x87, 0x88, 0x8A, 0x8B, 0x8E, 0x91, 0x94, 0x97, 0x9D, 0xA4, 0xA5, 0xA7, /* 0704-0719 */
+	0xA9, 0xAA, 0xAE, 0xB0, 0xB3, 0xB6, 0xB7, 0xB8, 0xB9, 0xBA, 0xBB, 0x83, 0x84, 0x87, 0x8A, 0x8B, /* 0720-0735 */
+	0x8C, 0x8D, 0x8F, 0x94, 0x96, 0x9B, 0x9E, 0xA3, 0xA4, 0xA5, 0xA9, 0xAA, 0xAF, 0xB0, 0xB1, 0xB2, /* 0736-0751 */
+	0xB3, 0xB4, 0xB5, 0xBD, 0xBF, 0x83, 0x87, 0x88, 0x89, 0x8D, 0x91, 0x92, 0x94, 0x9B, 0x9F, 0xA0, /* 0752-0767 */
+	0xA3, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xB1, 0xB4, 0xB5, 0xB9, 0xBC, 0xBE, 0x81, 0x83, 0x85, 0x87, /* 0768-0783 */
+	0x89, 0x8D, 0x92, 0x95, 0x97, 0x98, 0x99, 0x9D, 0x9E, 0x9F, 0xA0, 0xA2, 0xA3, 0xA4, 0xA6, 0xA7, /* 0784-0799 */
+	0xB2, 0xB3, 0xB5, 0xB8, 0xB9, 0xBA, 0xBE, 0xBF, 0x81, 0x82, 0x85, 0x86, 0x88, 0x8D, 0x8F, 0x90, /* 0800-0815 */
+	0x95, 0x96, 0x97, 0x99, 0x9A, 0x9D, 0xA0, 0xA1, 0xA3, 0xAA, 0xAF, 0xB1, 0xB3, 0xB8, 0xB9, 0xBA, /* 0816-0831 */
+	0xBB, 0xBF, 0x80, 0x81, 0x83, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8A, 0x8D, 0x91, 0x92, 0x93, 0x94, /* 0832-0847 */
+	0x97, 0x98, 0x9A, 0x9C, 0x9E, 0xA0, 0xA6, 0xA9, 0xAE, 0xAF, 0xB0, 0xB1, 0xB3, 0xB4, 0xB5, 0xB7, /* 0848-0863 */
+	0xB8, 0xBB, 0xBF, 0x82, 0x84, 0x96, 0x98, 0x9A, 0x9F, 0xA0, 0xA5, 0xA6, 0xA8, 0xA9, 0xAD, 0xAE, /* 0864-0879 */
+	0xB0, 0xB3, 0xB6, 0xBB, 0x82, 0x83, 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x94, 0x96, 0x97, /* 0880-0895 */
+	0x99, 0x9B, 0x9F, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF, /* 0896-0911 */
+	0xB0, 0xB1, 0xB2, 0xB3, 0xB6, 0xB7, 0xB8, 0xBA, 0x81, 0x83, 0x84, 0x88, 0x89, 0x8A, 0x8B, 0x8C, /* 0912-0927 */
+	0x8D, 0x8E, 0x8F, 0x90, 0x91, 0x9B, 0x9D, 0x9F, 0xA0, 0xA6, 0xA9, 0xAB, 0xAC, 0xAD, 0xAE, 0xB6, /* 0928-0943 */
+	0xB8, 0xB9, 0xBB, 0xBC, 0xBD, 0xBE, 0x80, 0x82, 0x86, 0x88, 0x89, 0x8A, 0x8E, 0x91, 0x9F, 0xA8, /* 0944-0959 */
+	0xAA, 0xB0, 0xB1, 0xB3, 0xB5, 0xB6, 0xB7, 0xBB, 0xBC, 0xBD, 0x80, 0x84, 0x86, 0x8B, 0x8C, 0x8E, /* 0960-0975 */
+	0x8F, 0x90, 0x92, 0xA2, 0xA4, 0xA5, 0xA8, 0xAB, 0xAC, 0xAF, 0xB2, 0xB3, 0xB8, 0xBC, 0xBD, 0xBE, /* 0976-0991 */
+	0x80, 0x81, 0x82, 0x84, 0x87, 0x88, 0x89, 0x98, 0xA1, 0xA2, 0xA5, 0xA6, 0xA8, 0xA9, 0xAD, 0xAE, /* 0992-1007 */
+	0xB2, 0xBA, 0xBD, 0x84, 0x86, 0x87, 0x8F, 0x90, 0x94, 0x96, 0xAE, 0xAF, 0xB1, 0xB3, 0xB8, 0xB9, /* 1008-1023 */
+	0xBE, 0x80, 0x84, 0x85, 0x86, 0x8C, 0x8F, 0x93, 0x96, 0x97, 0x9C, 0x9D, 0xA3, 0xBB, 0xBC, 0xBE, 
+	0x80, 0x83, 0x84, 0x87, 0x89, 0x8A, 0x8B, 0x98, 0x99, 0x9A, 0x9C, 0x9D, 0x9E, 0x9F, 0xA7, 0xA8, 
+	0xA9, 0xAA, 0xAB, 0xAC, 0xAE, 0xB0, 0xB6, 0x84, 0x85, 0x87, 0x94, 0x9A, 0x9C, 0x9F, 0xA3, 0xA4, 
+	0xB7, 0xB9, 0xBD, 0xBE, 0x86, 0x89, 0x94, 0x96, 0x97, 0x98, 0x9B, 0xA9, 0xAF, 0xB1, 0xB2, 0xB4, 
+	0xB6, 0xB8, 0x82, 0x8C, 0x8E, 0x90, 0x9B, 0xA4, 0xA8, 0xAA, 0xAB, 0xAC, 0xB4, 0xB8, 0xBA, 0x80, 
+	0x86, 0x87, 0x8A, 0x8F, 0x94, 0xA0, 0xA2, 0xA5, 0xAE, 0xB4, 0xB6, 0xBC, 0x80, 0x81, 0x82, 0x83, 
+	0x88, 0x8E, 0x91, 0x93, 0x97, 0x98, 0x9A, 0x9B, 0x9E, 0xA0, 0xA3, 0xAE, 0xB0, 0xB2, 0xB3, 0xB9, 
+	0xBA, 0xBD, 0xBF, 0x80, 0x83, 0x84, 0x88, 0x89, 0x8B, 0x8D, 0x8F, 0x92, 0x93, 0x96, 0x98, 0x9C, 
+	0x9F, 0xA6, 0xA7, 0xA8, 0xAD, 0xB0, 0xB7, 0xB8, 0xBB, 0x80, 0x82, 0x87, 0x8A, 0x8E, 0x8F, 0x90, 
+	0x91, 0xA1, 0xA4, 0xA6, 0xA9, 0xAA, 0xBF, 0x82, 0x88, 0x89, 0x8B, 0x93, 0xA0, 0xA2, 0xA3, 0xA4, 
+	0xAA, 0xB0, 0xB3, 0x80, 0x83, 0x86, 0x8B, 0x8E, 0x92, 0x93, 0x94, 0x96, 0x9C, 0x9F, 0xA0, 0xA3, 
+	0xB4, 0xB7, 0xB9, 0xBA, 0xBC, 0x80, 0x82, 0x85, 0x86, 0x8A, 0x8B, 0x95, 0x99, 0x9D, 0xA1, 0xA4, 
+	0xAA, 0xAF, 0xB0, 0xB1, 0xB4, 0xB5, 0xBA, 0xBD, 0x80, 0x81, 0x8A, 0x8B, 0x91, 0x92, 0x94, 0x97, 
+	0x98, 0x99, 0x9A, 0x9E, 0xA2, 0xA9, 0xAB, 0xB0, 0xB2, 0xB5, 0xB9, 0xBE, 0x83, 0x85, 0x93, 0x97, 
+	0x9C, 0x9F, 0xA8, 0xAB, 0xAE, 0xB3, 0xB8, 0xB9, 0xBA, 0xBB, 0xBE, 0x81, 0x85, 0x87, 0x8A, 0x8C, 
+	0x91, 0x93, 0x95, 0x97, 0x98, 0x99, 0x9C, 0x9E, 0x9F, 0xA4, 0xA5, 0xAB, 0xAC, 0xAE, 0xAF, 0xB0, 
+	0xB1, 0xB2, 0xB7, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0x82, 0x89, 0x8A, 0x8F, 0x90, 0x95, 0x96, 0x98, 
+	0x99, 0x9A, 0x9B, 0x9C, 0xA2, 0xA5, 0xA7, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xB1, 0xB2, 0xB7, 
+	0xB8, 0xBE, 0x84, 0x87, 0x88, 0x89, 0x8E, 0x8F, 0x90, 0x91, 0x94, 0x95, 0x97, 0x98, 0x9A, 0xA0, 
+	0xA2, 0xA5, 0xA7, 0xA8, 0xA9, 0xAA, 0xAC, 0xAE, 0xB3, 0xB4, 0xB8, 0xBD, 0x81, 0x82, 0x83, 0x84, 
+	0x8A, 0x8D, 0x93, 0x96, 0x99, 0x9B, 0x9D, 0xA3, 0xA5, 0xA8, 0xAC, 0xB2, 0xB9, 0xBB, 0xBE, 0x86, 
+	0x89, 0x8B, 0x90, 0x91, 0x93, 0x94, 0x99, 0x9A, 0x9C, 0xA5, 0xA6, 0xA8, 0xAA, 0xAB, 0xB6, 0xBB, 
+	0xBF, 0x81, 0x83, 0x89, 0x91, 0x98, 0x9A, 0x9C, 0x9F, 0xA0, 0xA5, 0xA9, 0xAF, 0xB5, 0xB6, 0xBC, 
+	0x80, 0x81, 0x86, 0x89, 0x9A, 0xA2, 0xA6, 0xAA, 0xAC, 0xBF, 0x92, 0x9A, 0x9B, 0xBC, 0xBD, 0xBE, 
+	0x81, 0x82, 0x89, 0x8B, 0x8C, 0x90, 0x96, 0x97, 0xA1, 0xA3, 0xA6, 0xA9, 0xBA, 0xBB, 0x89, 0x8B, 
+	0x8C, 0x96, 0xA2, 0xAA, 0xAC, 0xB0, 0xB2, 0xB6, 0xBE, 0x80, 0x83, 0x85, 0x90, 0x91, 0x94, 0x95, 
+	0x97, 0x98, 0x9A, 0x9B, 0x9C, 0x9D, 0x9F, 0xA3, 0xA4, 0xA5, 0xA6, 0xA9, 0xAB, 0xB0, 0xB1, 0xB3, 
+	0xB5, 0xB8, 0xBA, 0x80, 0x83, 0x85, 0x87, 0x88, 0x89, 0x8B, 0x8C, 0x8D, 0x8F, 0x95, 0x97, 0x98, 
+	0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0x9F, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xAE, 0xB0, 0xB3, 0xB4, 0xB5, 
+	0xB6, 0xB8, 0xB9, 0xBF, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x89, 0x8C, 0x90, 0x92, 0x93, 0x94, 
+	0x9B, 0x9D, 0x9E, 0x9F, 0xA1, 0xA2, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8, 0xA9, 0xAB, 0xAE, 0xB0, 0xB3, 
+	0xB5, 0xB6, 0xB8, 0xBA, 0xBE, 0xBF, 0x81, 0x82, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8A, 0x8B, 
+	0x8D, 0x8E, 0x8F, 0x91, 0x93, 0x96, 0x9A, 0xA0, 0xA2, 0xA4, 0xA8, 0xAD, 0xB1, 0xB8, 0xB9, 0xBA, 
+	0xBB, 0xBC, 0xBD, 0xBE, 0xBF, 0x80, 0x81, 0x85, 0x86, 0x88, 0x8A, 0x8B, 0x8D, 0x8E, 0x8F, 0x90, 
+	0x91, 0x93, 0x95, 0x9E, 0xA0, 0xA1, 0xA4, 0xA5, 0xAC, 0xAE, 0xAF, 0xB1, 0xB6, 0xB9, 0x8C, 0x90, 
+	0x91, 0x94, 0xA1, 0xA8, 0xA9, 0xAB, 0xAC, 0xB1, 0xB3, 0xB6, 0xB7, 0xB8, 0xBB, 0xBC, 0xBE, 0x85, 
+	0x87, 0x99, 0xA0, 0xA1, 0xA8, 0xA9, 0xAA, 0xAD, 0xAF, 0xB0, 0xB6, 0xBA, 0xBB, 0xBD, 0x87, 0x8B, 
+	0x8E, 0x91, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9A, 0x9B, 0x9F, 0xA2, 0xA9, 0x8B, 0x8C, 0x8E, 
+	0x90, 0x92, 0x9C, 0xA9, 0xAC, 0xAF, 0xB3, 0xB6, 0x82, 0x84, 0x87, 0x8B, 0x8C, 0x90, 0x9D, 0xA2, 
+	0xAC, 0xAE, 0xB7, 0xBA, 0xBC, 0xBD, 0x89, 0x8C, 0x8D, 0x92, 0x93, 0x96, 0x9B, 0x9D, 0x9E, 0xA1, 
+	0xA3, 0xA5, 0xA6, 0xA7, 0xA8, 0xAB, 0xAE, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 0xB7, 0xBB, 0xBD, 0xBE, 
+	0x82, 0x83, 0x86, 0x8B, 0x8C, 0x91, 0x96, 0x99, 0x9A, 0x9B, 0x9D, 0xA5, 0xAB, 0xAD, 0xAF, 0xB0, 
+	0xB3, 0xB6, 0xB7, 0xB8, 0xBD, 0x80, 0x83, 0x84, 0x85, 0x87, 0x8C, 0x8E, 0x94, 0x95, 0x97, 0x9F, 
+	0xA1, 0xA2, 0xA3, 0xA4, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE, 
+	0xBF, 0x81, 0x83, 0x84, 0x87, 0x8A, 0x8F, 0x95, 0x96, 0x97, 0x9A, 0x9C, 0xA0, 0xA6, 0xA7, 0xAB, 
+	0xAD, 0xB5, 0xB6, 0xB7, 0xB8, 0x81, 0x82, 0x83, 0x88, 0x89, 0x8A, 0x8F, 0x90, 0x93, 0x96, 0x9A, 
+	0x9B, 0x9D, 0x9F, 0xA0, 0xA1, 0xA2, 0xA3, 0xA8, 0xA9, 0xAC, 0xB0, 0xB1, 0xB3, 0xB4, 0xB6, 0xB7, 
+	0xB8, 0xBA, 0xBB, 0xBC, 0xBE, 0xBF, 0x81, 0x83, 0x84, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8F, 0x90, 
+	0x91, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x9B, 0x9F, 0xA5, 0xA6, 0xA7, 0xA9, 0xAD, 0xAF, 0xB1, 
+	0xB5, 0xB7, 0xB8, 0xBC, 0xBE, 0x81, 0x88, 0x8A, 0x8C, 0x8E, 0x91, 0x93, 0x96, 0x97, 0x99, 0x9C, 
+	0x9D, 0xA1, 0xA2, 0xA6, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xB0, 0xB1, 0xB3, 0xB7, 0xB9, 0xBC, 0xBF, 
+	0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x87, 0x88, 0x8A, 0x8B, 0x8C, 0x90, 0x91, 0x92, 0x93, 0x97, 
+	0x98, 0x99, 0x9E, 0xA0, 0xA1, 0xA8, 0xA9, 0xAA, 0xAD, 0xAE, 0xB3, 0xB4, 0xB9, 0xBC, 0xBD, 0x83, 
+	0x85, 0x8C, 0x8D, 0x96, 0x97, 0x98, 0x99, 0x9C, 0x9D, 0xA0, 0xA4, 0xAB, 0xB0, 0xB1, 0xB5, 0xB8, 
+	0xBB, 0xBD, 0xBF, 0x8E, 0x8F, 0x90, 0x92, 0x95, 0x96, 0x99, 0x9B, 0x9C, 0x9D, 0xA0, 0xA1, 0xA5, 
+	0xA6, 0xA7, 0xA8, 0xA9, 0xAA, 0xAB, 0xAF, 0xB1, 0xBA, 0x81, 0x82, 0x83, 0x86, 0x8A, 0x8B, 0x8D, 
+	0x90, 0x92, 0x95, 0x99, 0x9A, 0x9F, 0xA0, 0xA2, 0xA3, 0xA4, 0xA5, 0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 
+	0xAD, 0xAF, 0xB0, 0xB5, 0xB7, 0x81, 0x83, 0x84, 0x89, 0x8B, 0x8C, 0x8D, 0x92, 0x94, 0x96, 0x97, 
+	0x9A, 0x9B, 0x9F, 0xA0, 0xA3, 0xA6, 0xA7, 0xA9, 0xAA, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB8, 0xBC, 
+	0xBD, 0x85, 0x86, 0x87, 0x91, 0x93, 0x98, 0x9A, 0x9C, 0x9F, 0xA0, 0xA1, 0xA3, 0xA7, 0xA8, 0xB0, 
+	0xB1, 0xB3, 0xB4, 0xB6, 0xB7, 0xB9, 0xBA, 0xBB, 0x80, 0x81, 0x83, 0x86, 0x88, 0x89, 0x8D, 0x8E, 
+	0x8F, 0x95, 0x9A, 0x9B, 0x9F, 0xA1, 0xA7, 0xA8, 0xAC, 0xB4, 0xBC, 0xBD, 0xBE, 0xBF, 0x82, 0x84, 
+	0x87, 0x88, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x93, 0x95, 0x98, 0x99, 0x9A, 0x9D, 0x9F, 0xA2, 0xA3, 
+	0xA5, 0xA7, 0xA8, 0xAB, 0xAE, 0xAF, 0xB0, 0xB1, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xBE, 0x82, 0x87, 
+	0x8A, 0x8E, 0x90, 0x91, 0x94, 0x96, 0x99, 0x9A, 0xA4, 0xA7, 0xA9, 0xAB, 0xAC, 0xAE, 0xB2, 0xB6, 
+	0xBA, 0xBE, 0x83, 0x86, 0x87, 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x90, 0xA3, 0xA6, 0xB2, 0xB4, 
+	0xB6, 0xB7, 0xB8, 0xBA, 0xBC, 0xBD, 0xBE, 0xBF, 0x80, 0x88, 0x89, 0x8A, 0x8C, 0x8D, 0x8E, 0x90, 
+	0x91, 0x92, 0x94, 0x96, 0x9A, 0x9B, 0x9D, 0x9E, 0x9F, 0xA1, 0xA6, 0xAA, 0xAE, 0xAF, 0xB0, 0xB2, 
+	0xB3, 0xB4, 0xB8, 0xBB, 0xBF, 0x80, 0x81, 0x87, 0x88, 0x89, 0x8B, 0x8D, 0x8E, 0x93, 0x95, 0x98, 
+	0x9B, 0x9E, 0xA0, 0xA3, 0xA8, 0xAE, 0xB1, 0xB6, 0xB9, 0xBC, 0xBE, 0xBF, 0x80, 0x82, 0x83, 0x84, 
+	0x89, 0x8A, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x9B, 0x9C, 0x9E, 0xAB, 0xAC, 0xB1, 
+	0xB5, 0xB9, 0xBB, 0xBC, 0xBD, 0x82, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8A, 0x8C, 0x8D, 0x8F, 0x90, 
+	0x91, 0x92, 0x93, 0x94, 0x97, 0x98, 0x99, 0x9B, 0x9C, 0x9D, 0xA0, 0xA1, 0xAC, 0xAD, 0xAE, 0xAF, 
+	0xB1, 0xB3, 0xB5, 0xB6, 0xB7, 0xBE, 0xBF, 0x81, 0x82, 0x87, 0x88, 0x89, 0x8C, 0x91, 0x99, 0x9F, 
+	0xA7, 0xA8, 0xAB, 0xAF, 0xBA, 0xBD, 0xBE, 0xBF, 0x89, 0x8C, 0x8D, 0x8F, 0x90, 0x95, 0x97, 0x9C, 
+	0xA7, 0xA8, 0xA9, 0xAB, 0xAE, 0xB2, 0xB6, 0xB7, 0xBA, 0xBB, 0x80, 0x83, 0x88, 0x89, 0x8C, 0x8E, 
+	0x8F, 0x92, 0x96, 0x98, 0x9B, 0x9F, 0xA0, 0xA1, 0xA2, 0xA3, 0xA5, 0xA7, 0xA8, 0xA9, 0xAA, 0xAB, 
+	0xAC, 0xB2, 0xB4, 0xB5, 0xBB, 0xBE, 0x80, 0x83, 0x84, 0x86, 0x89, 0x8F, 0x90, 0x92, 0x96, 0x9A, 
+	0x9B, 0xA1, 0xA3, 0xA9, 0xAE, 0xB4, 0xB6, 0xBA, 0x86, 0x8D, 0x8F, 0x93, 0x96, 0x97, 0x9C, 0xA6, 
+	0xA8, 0xAC, 0xAD, 0xB4, 0xB6, 0xBA, 0xBE, 0x82, 0x8E, 0x98, 0xA7, 0xA9, 0xAF, 0xB6, 0xB8, 0xBA, 
+	0x83, 0x88, 0x92, 0x93, 0x95, 0x9A, 0x9E, 0xA4, 0xA5, 0xA9, 0xAB, 0xAD, 0xAE, 0xB0, 0xB2, 0xB9, 
+	0xBB, 0xBC, 0x81, 0x82, 0x85, 0x87, 0x8D, 0x92, 0x94, 0x98, 0x9A, 0xA0, 0xA1, 0xA2, 0xA3, 0xA6, 
+	0xA7, 0xAC, 0xAF, 0xB1, 0xB2, 0xB4, 0xB6, 0xBA, 0xBD, 0xBE, 0x80, 0x85, 0x98, 0x9C, 0x9D, 0xA3, 
+	0xA4, 0xAA, 0xAB, 0xAC, 0xAF, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 0xBB, 0xBE, 0xBF, 0x85, 0x88, 
+	0x8D, 0x8F, 0x91, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9D, 0x9E, 0xA2, 0xA3, 0xA6, 0xAC, 0xB0, 0xB2, 
+	0xB4, 0xB5, 0xB7, 0xB8, 0x82, 0x83, 0x87, 0x88, 0x89, 0x8C, 0x8E, 0x90, 0x91, 0x97, 0x99, 0x9B, 
+	0x9C, 0x9F, 0xA1, 0xA4, 0xA5, 0xA7, 0xAB, 0xAC, 0xAD, 0xAF, 0xB0, 0xB7, 0xB9, 0xBC, 0xBD, 0x81, 
+	0x83, 0x84, 0x85, 0x86, 0x8B, 0x8C, 0x8F, 0x92, 0x97, 0x99, 0x9B, 0xA0, 0xA1, 0xA2, 0xA5, 0xA6, 
+	0xA7, 0xA8, 0xA9, 0xAC, 0xAD, 0xB1, 0xBA, 0xBB, 0x82, 0x83, 0x86, 0x87, 0x8A, 0x8C, 0x8E, 0x8F, 
+	0x93, 0x94, 0x9C, 0x9F, 0xA0, 0xA5, 0xA7, 0xA8, 0xAD, 0xAF, 0xB4, 0xB5, 0xB6, 0xBC, 0xBF, 0x81, 
+	0x82, 0x83, 0x84, 0x89, 0x8B, 0x8F, 0x92, 0x9D, 0x9E, 0x9F, 0xA2, 0xA4, 0xA6, 0xA7, 0xA8, 0xA9, 
+	0xAE, 0xAF, 0xB0, 0xB4, 0xB6, 0xBA, 0x81, 0x83, 0x84, 0x87, 0x88, 0x89, 0x8E, 0x91, 0x96, 0x97, 
+	0x98, 0x9D, 0xA2, 0xA6, 0xAB, 0xAE, 0xB4, 0xB8, 0xB9, 0xBC, 0xBE, 0x81, 0x84, 0x87, 0x89, 0x96, 
+	0x99, 0x9A, 0x9C, 0x9D, 0xA0, 0xA6, 0xA9, 0xB0, 0xB2, 0xB3, 0xB4, 0xB5, 0xB7, 0xB8, 0xB9, 0xBC, 
+	0xBD, 0xBE, 0xBF, 0x80, 0x83, 0x88, 0x89, 0x8B, 0x8D, 0x8F, 0x94, 0x95, 0x96, 0x97, 0x9B, 0x9D, 
+	0x9E, 0x9F, 0xA6, 0xA7, 0xA8, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xB1, 0xB4, 0xB6, 0xB7, 0xB8, 0xBA, 
+	0xBD, 0xBF, 0x81, 0x86, 0x89, 0x8E, 0x8F, 0x90, 0x91, 0x93, 0x96, 0x99, 0x9C, 0x9E, 0x9F, 0xA0, 
+	0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xAA, 0xAD, 0xAF, 0xB0, 0xB1, 0xB2, 0xB3, 0xB5, 0xB7, 0xBC, 0xBE, 
+	0xBF, 0x85, 0x87, 0x89, 0x8B, 0x8C, 0x90, 0x95, 0x97, 0x9A, 0x9C, 0x9D, 0xA0, 0xA1, 0xA2, 0xA6, 
+	0xA9, 0xAF, 0xB3, 0xB4, 0xB6, 0xB7, 0xB8, 0xB9, 0x81, 0x84, 0x86, 0x8A, 0x8E, 0x8F, 0x90, 0x91, 
+	0x93, 0x94, 0x98, 0x9A, 0x9D, 0x9E, 0xA2, 0xA4, 0xA7, 0xA9, 0xAC, 0xAE, 0xAF, 0xB1, 0xB3, 0xB4, 
+	0xB5, 0xBB, 0xBE, 0xBF, 0x82, 0x83, 0x84, 0x93, 0x96, 0x97, 0x9E, 0xA1, 0xA2, 0xA9, 0xAA, 0xAB, 
+	0xB2, 0xB4, 0xB8, 0xB9, 0xBC, 0xBD, 0x80, 0x81, 0x82, 0x83, 0x86, 0x88, 0x8D, 0x8E, 0x90, 0x91, 
+	0x93, 0x94, 0x99, 0x9C, 0x9D, 0x9F, 0xA3, 0xA7, 0xB4, 0xB6, 0xB7, 0xBE, 0xBF, 0x81, 0x83, 0x85, 
+	0x8D, 0x8F, 0x93, 0x94, 0x97, 0x9B, 0x9D, 0x9F, 0xA0, 0xA2, 0xA6, 0xA7, 0xA8, 0xAD, 0xAF, 0xB0, 
+	0xB1, 0xB3, 0xB5, 0xB6, 0xB9, 0xBA, 0xBC, 0x84, 0x86, 0x89, 0x8A, 0x8B, 0x8D, 0x92, 0x94, 0x95, 
+	0x97, 0x98, 0x9A, 0x9F, 0xA0, 0xA1, 0xA3, 0xA7, 0xAE, 0xAF, 0xB2, 0xB9, 0xBA, 0x80, 0x81, 0x84, 
+	0x85, 0x88, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F, 0x92, 0x99, 0x9A, 0x9B, 0x9C, 0xA1, 0xA2, 0xA3, 0xA5, 
+	0xA6, 0xA8, 0xAA, 0xB0, 0xB4, 0xB6, 0xB9, 0xBD, 0xBF, 0x8A, 0x93, 0x94, 0x95, 0x99, 0x9A, 0x9C, 
+	0x9D, 0x9E, 0xA0, 0xA1, 0xA2, 0xAA, 0xAB, 0xAD, 0xAE, 0xAF, 0xB3, 0xB4, 0xB5, 0xB7, 0xB8, 0xB9, 
+	0xBC, 0xBD, 0xBE, 0x81, 0x82, 0x8A, 0x8E, 0x91, 0x94, 0x95, 0x9B, 0x9C, 0xA0, 0xA7, 0xAE, 0xB1, 
+	0xB2, 0xB4, 0xBB, 0xBE, 0xBF, 0x81, 0x83, 0x87, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x90, 0x93, 0x98, 
+	0x99, 0x9D, 0x9E, 0xA7, 0xA8, 0xAB, 0xAD, 0xB2, 0xB9, 0xBB, 0xBD, 0xBF, 0x82, 0x85, 0x8A, 0x8B, 
+	0x8C, 0x92, 0x93, 0x94, 0x97, 0x99, 0x9B, 0x9E, 0x9F, 0xA1, 0xA2, 0xA3, 0xA9, 0xAA, 0xAB, 0xAE, 
+	0xB5, 0xB6, 0xB8, 0xB9, 0xBA, 0xBD, 0x84, 0x87, 0x88, 0x8B, 0x98, 0x99, 0x9F, 0xA1, 0xA2, 0xA6, 
+	0xB2, 0xB8, 0xBF, 0x80, 0x84, 0x8D, 0x8E, 0x90, 0x97, 0x9C, 0xA0, 0xA2, 0xA3, 0xAA, 0xAC, 0xAE, 
+	0xB3, 0xB8, 0xBB, 0x81, 0x82, 0x83, 0x91, 0x93, 0x9A, 0x9B, 0x9E, 0x9F, 0xA8, 0xAA, 0xBA, 0xBB, 
+	0x84, 0x85, 0x8A, 0x92, 0x96, 0x9D, 0x9F, 0xA0, 0xA1, 0xA3, 0xA7, 0xB2, 0xB7, 0xB8, 0xB9, 0xBA, 
+	0xBD, 0xBE, 0x83, 0x87, 0x89, 0x8C, 0x8E, 0x90, 0x93, 0x94, 0x99, 0x9B, 0x9F, 0xA1, 0xA2, 0xA3, 
+	0xA4, 0xA6, 0xA9, 0xAA, 0xAF, 0xB3, 0xB4, 0xB8, 0xB9, 0xBB, 0xBF, 0x80, 0x83, 0x84, 0x86, 0x89, 
+	0x8A, 0x8B, 0x8D, 0x95, 0x96, 0x98, 0x9E, 0xA4, 0xAA, 0xAB, 0xAF, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 
+	0xB7, 0xBA, 0xBB, 0xBC, 0xBF, 0x80, 0x85, 0x86, 0x8B, 0x8D, 0x8E, 0x92, 0x93, 0x94, 0x98, 0x9B, 
+	0x9F, 0xAB, 0xAC, 0xAF, 0xB3, 0x88, 0x8F, 0x91, 0x93, 0x94, 0x97, 0x9B, 0xA3, 0xA4, 0xB4, 0xB7, 
+	0xB8, 0xBE, 0x80, 0x81, 0x82, 0x8E, 0x90, 0x95, 0x97, 0x9A, 0x9D, 0x9E, 0x9F, 0xA0, 0xA2, 0xA8, 
+	0xAA, 0xB0, 0xB2, 0xB3, 0xBA, 0xBD, 0xBE, 0x81, 0x82, 0x83, 0x88, 0x8C, 0x8D, 0x90, 0x92, 0x93, 
+	0x96, 0x99, 0x9A, 0x9B, 0xA1, 0xA2, 0xAB, 0xAE, 0xB1, 0xB3, 0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 
+	0xBE, 0xBF, 0x81, 0x84, 0x85, 0x89, 0x8A, 0x8C, 0x93, 0x95, 0x97, 0x99, 0x9B, 0x9D, 0xA1, 0xA2, 
+	0xA3, 0xA5, 0xA8, 0xAA, 0xAF, 0xB0, 0xB1, 0xB3, 0x8B, 0x8C, 0x92, 0x97, 0x99, 0x9B, 0x9E, 0x9F, 
+	0xA5, 0xA9, 0xAA, 0xAB, 0xB2, 0xB3, 0xB5, 0xB6, 0xB8, 0xBB, 0xBD, 0xBE, 0x81, 0x84, 0x85, 0x99, 
+	0x9A, 0x9C, 0xA3, 0xA4, 0xA6, 0xA9, 0xAA, 0xAC, 0xAE, 0xB4, 0xB7, 0xB8, 0xB9, 0x85, 0x88, 0x8C, 
+	0x8E, 0x93, 0x95, 0x99, 0x9B, 0x9C, 0xAF, 0xB2, 0xB5, 0xB8, 0xBC, 0x80, 0x85, 0x86, 0x87, 0x8B, 
+	0x8C, 0x91, 0x92, 0x95, 0x98, 0x99, 0x9E, 0xA1, 0xA4, 0xA6, 0xA8, 0xAA, 0xAB, 0xAC, 0xAE, 0xB1, 
+	0xB3, 0xB5, 0xB7, 0xB9, 0xBA, 0xBB, 0x85, 0x87, 0x88, 0x89, 0x8A, 0x8B, 0x93, 0x95, 0x99, 0x9A, 
+	0x9B, 0x9D, 0x9F, 0xA0, 0xA1, 0xA3, 0xA4, 0xA5, 0xA6, 0xA9, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF, 0xB8, 
+	0xBA, 0xBE, 0x83, 0x8A, 0x8D, 0x8E, 0x96, 0x98, 0x9B, 0x9F, 0xA7, 0xAB, 0xAE, 0xAF, 0xB2, 0xB6, 
+	0xBE, 0xBF, 0x80, 0x82, 0x8C, 0x8F, 0x90, 0x96, 0x98, 0x9C, 0x9D, 0x9F, 0xA2, 0xA5, 0xAA, 0xAF, 
+	0xB2, 0xB6, 0xB7, 0xBA, 0xBD, 0x82, 0x84, 0x85, 0x89, 0x8B, 0x8C, 0x91, 0x93, 0x94, 0x95, 0x9D, 
+	0x9E, 0xAC, 0xAF, 0xB2, 0xB4, 0xB7, 0xB8, 0xBE, 0xBF, 0x81, 0x82, 0x86, 0x89, 0x8F, 0x91, 0x93, 
+	0x94, 0x95, 0xA0, 0xA2, 0xA3, 0xAB, 0xAC, 0xB1, 0xB2, 0xB8, 0xBE, 0xBF, 0x81, 0x85, 0x94, 0x98, 
+	0x9B, 0x9C, 0x9F, 0xA4, 0xA6, 0xAD, 0xAE, 0xAF, 0xB0, 0xB4, 0xB8, 0xBA, 0xBC, 0x80, 0x81, 0x82,
+	0x84, 0x86, 0x8E, 0x91, 0x97, 0xA1, 0xA3, 0xA4, 0xAA, 0xB1, 0xB3, 0xB9, 0x80, 0x81, 0x82, 0x83, 
+	0x86, 0x94, 0x95, 0x98, 0x9B, 0x9F, 0xA0, 0xA1, 0xA4, 0xAB, 0xAC, 0xAE, 0xAF, 0xB1, 0xB3, 0xB6, 
+	0xBA, 0xBE, 0x81, 0x89, 0x8B, 0x8F, 0x91, 0x95, 0x98, 0x9A, 0x9B, 0x9D, 0x9E, 0x9F, 0xA6, 0xA7, 
+	0xAC, 0xB0, 0xB2, 0xBE, 0x8C, 0x91, 0x98, 0xA3, 0xAB, 0xAF, 0xB0, 0xB8, 0xBC, 0xBD, 0x89, 0x8A, 
+	0x8E, 0x92, 0x99, 0xAC, 0xAD, 0xAE, 0xAF, 0xB3, 0xB8, 0xB9, 0xBA, 0x88, 0x8B, 0x8F, 0x99, 0x9D, 
+	0x9F, 0xB1, 0xB9, 0xBD, 0x89, 0x94, 0x99, 0x9A, 0x9C, 0xA1, 0xA6, 0xB6, 0xBC, 0x89, 0x8C, 0x8E, 
+	0x95, 0x96, 0x99, 0xA2, 0xA4, 0xA5, 0xA6, 0xA7, 0xA9, 0xAC, 0xAE, 0xBD, 0x84, 0x88, 0x8A, 0x8F, 
+	0x94, 0x95, 0x99, 0x9F, 0xA8, 0xAC, 0xB1, 0xB9, 0xBE, 0x83, 0x88, 0x89, 0x8E, 0x90, 0x92, 0x94, 
+	0x95, 0x97, 0x9F, 0xA0, 0xA5, 0xA6, 0xA7, 0xAC, 0xAD, 0xAE, 0xB5, 0xB9, 0xBB, 0xBC, 0xBF, 0x86, 
+	0x8D, 0x90, 0x9B, 0xA8, 0xAA, 0xAC, 0xAD, 0xB0, 0xB2, 0xB5, 0xB6, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE, 
+	0xBF, 0x80, 0x86, 0x87, 0x88, 0x8B, 0x8C, 0x92, 0x98, 0x99, 0x9B, 0x9D, 0x9F, 0xA1, 0xA2, 0xA7, 
+	0xA9, 0xB2, 0xB4, 0xB9, 0xBD, 0xBE, 0x80, 0x81, 0x82, 0x87, 0x92, 0x96, 0xA0, 0xA2, 0xA7, 0xAC, 
+	0xAF, 0xB2, 0xB6, 0xB9, 0x82, 0x83, 0x84, 0x86, 0x8E, 0x90, 0x92, 0x97, 0x99, 0x9B, 0xA0, 0xA1, 
+	0xA2, 0xA9, 0xAC, 0xAD, 0xB7, 0xB8, 0xB9, 0xBC, 0xBD, 0x8A, 0x96, 0x97, 0x9B, 0x9C, 0x9D, 0x9F, 
+	0xA5, 0xA9, 0xAA, 0xAB, 0xAE, 0xAF, 0xB4, 0xB6, 0xB7, 0xBE, 0xBF, 0x84, 0x85, 0x8E, 0x8F, 0x97, 
+	0xA3, 0xA8, 0xAA, 0xB0, 0xB2, 0xB5, 0xB8, 0xBA, 0xBB, 0x84, 0x87, 0x89, 0x8B, 0x96, 0xA9, 0xB2, 
+	0xB3, 0xBB, 0x80, 0x82, 0x88, 0x8A, 0x8D, 0x8E, 0x9E, 0xA0, 0xA5, 0xAA, 0xAD, 0xAE, 0xB1, 0xB8, 
+	0xBE, 0x83, 0x85, 0x86, 0x89, 0xA2, 0xA5, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xBA, 0xBF, 0x81, 0x95, 
+	0x99, 0x9A, 0x9B, 0x9C, 0x9E, 0x9F, 0xA0, 0xA3, 0xA4, 0xA9, 0xAA, 0xAF, 0xB0, 0xB3, 0xB6, 0xBE, 
+	0x83, 0x8B, 0x9E, 0xA2, 0xA7, 0xB0, 0xBD, 0x8A, 0x8F, 0x94, 0x9C, 0xA0, 0xA2, 0xA3, 0xA6, 0xA7, 
+	0xA9, 0xAE, 0xB0, 0xB1, 0xB2, 0xB6, 0xB7, 0xB8, 0x83, 0x84, 0x85, 0x8C, 0x8D, 0x8E, 0x91, 0x93, 
+	0x95, 0x98, 0x9A, 0x9C, 0x9E, 0x9F, 0xA3, 0xA5, 0xA6, 0xA8, 0xAB, 0xAC, 0xB0, 0xB1, 0xB2, 0xB3, 
+	0xB7, 0xB8, 0xBA, 0xBB, 0xBC, 0x84, 0x86, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8F, 0x91, 0x94, 0x99, 
+	0x9A, 0x9B, 0x9C, 0x9D, 0xA0, 0xA2, 0xA4, 0xA5, 0xA6, 0xA7, 0xA9, 0xAA, 0xAB, 0xAD, 0xB0, 0xB3, 
+	0xB4, 0xB6, 0xB7, 0xB8, 0xBF, 0x82, 0x86, 0x87, 0x89, 0x8A, 0x8B, 0x8E, 0x8F, 0x91, 0x94, 0x9A, 
+	0x9D, 0xA3, 0xA5, 0xAB, 0xB1, 0xB2, 0xB3, 0xB5, 0xB8, 0xB9, 0xBC, 0xBD, 0xBE, 0x82, 0x83, 0x85, 
+	0x87, 0x8A, 0x8D, 0x92, 0x94, 0x95, 0x98, 0x99, 0x9B, 0x9E, 0xA2, 0xA3, 0xA9, 0xB0, 0xB2, 0xB3, 
+	0xB4, 0xBA, 0xBC, 0xBE, 0xBF, 0x81, 0x89, 0x8B, 0x8D, 0x9F, 0xA0, 0xA1, 0xA2, 0xA4, 0xA7, 0xB0, 
+	0xB4, 0xBB, 0x82, 0x86, 0x87, 0x88, 0x8C, 0x92, 0x96, 0x98, 0x9C, 0xA1, 0xA2, 0xA7, 0xA8, 0xA9, 
+	0xAA, 0xAC, 0xB0, 0xB2, 0xB6, 0xB8, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE, 0x80, 0x83, 0x84, 0x86, 0x87, 
+	0x88, 0x8B, 0x8E, 0x90, 0x93, 0x96, 0x99, 0x9A, 0xAE, 0xB0, 0xB4, 0xB7, 0xB8, 0xB9, 0xBA, 0xBF, 
+	0x82, 0x83, 0x86, 0x88, 0x8A, 0x8D, 0x92, 0x96, 0x97, 0x9B, 0x9C, 0x9E, 0x9F, 0xA1, 0xA3, 0xA4, 
+	0xA5, 0xA7, 0xAA, 0xAE, 0xB2, 0xB4, 0xB8, 0xBB, 0xBE, 0x81, 0x84, 0x87, 0x88, 0x89, 0x8B, 0x8C, 
+	0x9B, 0x9E, 0x9F, 0xA0, 0xA4, 0xA5, 0xA6, 0xA9, 0xB7, 0xB8, 0xBA, 0xBC, 0x80, 0x87, 0x9A, 0x9B, 
+	0xA1, 0xA3, 0xA5, 0xA6, 0xA8, 0xAB, 0xB9, 0xBE, 0xBF, 0x8B, 0x8E, 0x91, 0x9E, 0xA0, 0xA5, 0xAC, 
+	0xAD, 0xB0, 0xB3, 0xB6, 0xB9, 0xBB, 0xBC, 0xBD, 0xBF, 0x87, 0x8D, 0x97, 0x9A, 0x9B, 0x9C, 0xA2, 
+	0xA3, 0xA5, 0xA7, 0xA9, 0xAD, 0xAE, 0xAF, 0xB3, 0xBC, 0x82, 0x8C, 0x92, 0x94, 0x95, 0xA0, 0xA5, 
+	0xA6, 0xA7, 0xB2, 0xB4, 0xBA, 0xBF, 0x85, 0x9D, 0xAB, 0xAC, 0xAF, 0xB2, 0xB4, 0xBC, 0x81, 0x86, 
+	0x87, 0x8C, 0x8D, 0x8E, 0x91, 0x93, 0x95, 0x97, 0x9A, 0xA3, 0xA7, 0xA9, 0xAA, 0xAF, 0xB5, 0xBA, 
+	0xBC, 0xBE, 0x81, 0x85, 0x86, 0x8A, 0x8B, 0x90, 0x91, 0x94, 0x9A, 0xA7, 0xA8, 0xAC, 0xAF, 0xB4, 
+	0xBD, 0x81, 0x87, 0x8E, 0x91, 0x92, 0x99, 0xA6, 0xAA, 0xAB, 0xAC, 0xBA, 0xBC, 0xBE, 0x80, 0x81, 
+	0x87, 0x88, 0x89, 0x90, 0x93, 0x95, 0x96, 0x97, 0x9A, 0x9D, 0x9E, 0x9F, 0xA0, 0xA2, 0xA5, 0xA8, 
+	0xAD, 0xB7, 0xBA, 0xBF, 0x80, 0x81, 0x84, 0x85, 0x8A, 0x8D, 0x8E, 0x8F, 0x9D, 0xA6, 0xA7, 0xAA, 
+	0xAE, 0xB0, 0xB3, 0xB9, 0xBA, 0xBD, 0xBE, 0xBF, 0x80, 0x81, 0x89, 0x8B, 0x91, 0x92, 0x95, 0x98, 
+	0x9F, 0xA1, 0xA3, 0xA4, 0xA6, 0xA7, 0xA9, 0xAC, 0xB0, 0xBB, 0x80, 0x88, 0x8B, 0x8D, 0x8E, 0x94, 
+	0x97, 0x98, 0x99, 0x9A, 0x9C, 0x9F, 0xA0, 0xAE, 0xB1, 0xB2, 0xB7, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF, 
+	0x80, 0x82, 0x83, 0x86, 0x89, 0x8D, 0x8E, 0x8F, 0x90, 0x97, 0xA1, 0xA2, 0xA3, 0xA9, 0xAB, 0xB0, 
+	0xB4, 0xB6, 0xB9, 0xBA, 0xBD, 0xBF, 0x81, 0x83, 0x84, 0x88, 0x92, 0x93, 0x95, 0x96, 0x97, 0x98, 
+	0x9F, 0xA9, 0xAA, 0xAE, 0xAF, 0xB0, 0xB6, 0xBA, 0xBF, 0x83, 0x84, 0x85, 0x87, 0x88, 0x8A, 0x8B, 
+	0x8D, 0x8F, 0x92, 0x93, 0x95, 0x99, 0x9A, 0x9C, 0x9D, 0x9F, 0xA0, 0xA1, 0xA2, 0xA3, 0xA5, 0xA6, 
+	0xAA, 0xAD, 0xAF, 0xB0, 0xB6, 0xB8, 0xB9, 0xBA, 0xBF, 0x82, 0x84, 0x86, 0x88, 0x8A, 0x8B, 0x8F, 
+	0x91, 0x98, 0x99, 0x9B, 0x9E, 0xA0, 0xA5, 0xA6, 0xA8, 0xAC, 0xB3, 0xB5, 0xB6, 0xB9, 0x85, 0x86, 
+	0x88, 0x89, 0x8B, 0x8C, 0x8D, 0x8F, 0x90, 0x91, 0x92, 0x94, 0x96, 0x9D, 0xA5, 0xA7, 0xAC, 0xAE, 
+	0xB0, 0xB1, 0xB4, 0xB5, 0xBA, 0x86, 0x87, 0x8B, 0x8D, 0x8F, 0x92, 0x94, 0x95, 0x97, 0x98, 0x99, 
+	0x9A, 0x9C, 0x9D, 0x9F, 0xA1, 0xAA, 0xAD, 0xB1, 0xB4, 0xB8, 0x80, 0x81, 0x84, 0x86, 0x87, 0x89, 
+	0x8B, 0x8C, 0x8F, 0x9D, 0xA0, 0xA4, 0xA5, 0xA6, 0xA9, 0xAD, 0xB3, 0xB6, 0xB7, 0x80, 0x87, 0x8D, 
+	0x91, 0x92, 0x93, 0x94, 0x97, 0x9F, 0xA1, 0xA3, 0xA7, 0xAA, 0xAB, 0xB7, 0xB8, 0xBD, 0xBE, 0xBF, 
+	0x80, 0x83, 0x8C, 0x8D, 0x8F, 0x90, 0x94, 0x96, 0x98, 0x9F, 0xA0, 0xA4, 0xA5, 0xAC, 0xB3, 0xB5, 
+	0xBE, 0x81, 0x82, 0x83, 0x89, 0x8B, 0x8D, 0x90, 0x92, 0x95, 0x97, 0x98, 0x9B, 0x9F, 0xA1, 0xA2, 
+	0xA4, 0xA5, 0xA7, 0xA8, 0xAB, 0xAD, 0xAE, 0xB1, 0xB2, 0xB3, 0xB9, 0xBD, 0xBE, 0x80, 0x82, 0x85, 
+	0x8A, 0x8E, 0x92, 0x96, 0x98, 0x9C, 0x9E, 0x9F, 0xA0, 0xA2, 0xA7, 0xAF, 0xB2, 0xB4, 0xB6, 0xB8, 
+	0xBA, 0xBB, 0xBE, 0x80, 0x82, 0x84, 0x85, 0x86, 0x8A, 0x8B, 0x8D, 0x90, 0x94, 0x95, 0x97, 0x98, 
+	0x99, 0x9A, 0x9B, 0x9C, 0xA0, 0xA1, 0xA2, 0xAB, 0xAC, 0xAE, 0xAF, 0xB0, 0xB2, 0xB3, 0xB5, 0xB9, 
+	0xBA, 0xBF, 0x82, 0x83, 0x84, 0x85, 0x86, 0x8B, 0x8C, 0x8E, 0x8F, 0x90, 0x96, 0x9B, 0x9E, 0xA1, 
+	0xA2, 0xA3, 0xA6, 0xA8, 0xAE, 0xB1, 0xB2, 0xB3, 0xB5, 0xB6, 0xB9, 0xBD, 0x89, 0x8F, 0x93, 0x99, 
+	0x9A, 0x9B, 0x9C, 0x9F, 0xA2, 0xA3, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF, 0xB0, 0xB1, 0xB2, 0xB4, 0xB5, 
+	0xB8, 0xBA, 0xBB, 0xBD, 0xBE, 0xBF, 0x87, 0x8A, 0x8B, 0x8F, 0x91, 0x92, 0x95, 0x98, 0x9A, 0x9C, 
+	0x9D, 0x9E, 0xA0, 0xA1, 0xA4, 0xA8, 0xA9, 0xAC, 0xAF, 0xB2, 0xB4, 0xBB, 0x81, 0x84, 0x85, 0x89, 
+	0x8A, 0x8B, 0x92, 0x9B, 0x9E, 0x9F, 0xA1, 0xA2, 0xA3, 0xA6, 0xAB, 0xAE, 0xB1, 0xB2, 0xB5, 0xB7, 
+	0xB9, 0xBA, 0xBB, 0xBD, 0xBE, 0x81, 0x83, 0x86, 0x8A, 0x8B, 0x8D, 0x94, 0x95, 0x96, 0x99, 0x9A, 
+	0x9D, 0x9E, 0xA6, 0xA7, 0xA9, 0xAA, 0xAD, 0xB0, 0xB9, 0xBB, 0xBC, 0xBD, 0xBF, 0x82, 0x83, 0x88, 
+	0x89, 0x8C, 0x8E, 0x8F, 0x90, 0x92, 0x93, 0x94, 0x96, 0x9B, 0x9C, 0xB6, 0xB8, 0xBA, 0x85, 0x8C, 
+	0x8D, 0x8E, 0x90, 0x91, 0x94, 0x95, 0x98, 0x9F, 0xA0, 0xA7, 0xA8, 0xA9, 0xAA, 0xAB, 0xAE, 0xB0, 
+	0xB2, 0xB5, 0xB7, 0xB8, 0xB9, 0x82, 0x83, 0x85, 0x86, 0x87, 0x88, 0x8A, 0x8C, 0x8E, 0x94, 0x9A, 
+	0x9D, 0x9E, 0xA3, 0xA4, 0xA8, 0xA9, 0xAE, 0xAF, 0xB2, 0xB6, 0xB8, 0xB9, 0xBD, 0x81, 0x85, 0x86, 
+	0x8A, 0x8C, 0x92, 0x94, 0x95, 0xA0, 0xA1, 0xA6, 0xA9, 0xAB, 0xB0, 0xB3, 0xB9, 0xBB, 0xBC, 0x80, 
+	0x81, 0x83, 0x84, 0x85, 0x86, 0x8B, 0x8C, 0x90, 0x92, 0x95, 0x97, 0x98, 0x99, 0x9C, 0xA1, 0xA8, 
+	0xB3, 0xB6, 0xBB, 0xBD, 0xBF, 0x86, 0x8A, 0x92, 0x96, 0x98, 0x9A, 0x9E, 0x9F, 0xA1, 0xA2, 0xA8, 
+	0xAF, 0xB0, 0xB2, 0xB3, 0xB4, 0xB6, 0xB7, 0xB9, 0xBD, 0xBE, 0xBF, 0x84, 0x85, 0x86, 0x87, 0x89, 
+	0x8B, 0x8C, 0x93, 0x96, 0x98, 0x9A, 0x9B, 0x9D, 0xA1, 0xA2, 0xA5, 0xA9, 0xAA, 0xAC, 0xAD, 0xAF, 
+	0xB1, 0xB2, 0xB4, 0xBA, 0x83, 0x84, 0x86, 0x8C, 0x8E, 0x96, 0x99, 0x9A, 0x9B, 0x9D, 0x9E, 0xA1, 
+	0xA4, 0xA5, 0xAF, 0xB1, 0xB4, 0xB8, 0xBC, 0xBD, 0x82, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8A, 0x9A, 
+	0x9B, 0xA3, 0xA9, 0xAF, 0xB1, 0xB3, 0xB9, 0xBE, 0x86, 0x8B, 0x8E, 0x90, 0x91, 0x93, 0x94, 0x95, 
+	0x9F, 0xA5, 0xA6, 0xAB, 0xAE, 0xB0, 0xB1, 0xB4, 0xB8, 0xB9, 0xBA, 0xBF, 0x80, 0x82, 0x83, 0x88, 
+	0x8A, 0x8F, 0x93, 0x95, 0x9A, 0x9C, 0x9D, 0xA0, 0xA3, 0xA4, 0xA8, 0xA9, 0xB0, 0xB3, 0xB5, 0xB8, 
+	0xBA, 0xBD, 0xBE, 0xBF, 0x80, 0x82, 0x86, 0x88, 0x89, 0x8D, 0x91, 0x93, 0x98, 0x99, 0x9A, 0x9F, 
+	0xA0, 0xA3, 0xA5, 0xA7, 0xA8, 0xAA, 0xAD, 0xB3, 0xB4, 0xBA, 0xBB, 0xBC, 0xBE, 0x81, 0x82, 0x85, 
+	0x87, 0x88, 0x89, 0x8A, 0x8C, 0x8D, 0x8E, 0x90, 0x92, 0x96, 0x97, 0x98, 0x9B, 0x9C, 0x9E, 0x9F, 
+	0xA9, 0xAA, 0xAB, 0xAC, 0xAE, 0xB3, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 0x80, 0x87, 0x98, 0x99, 0x9A, 
+	0x9D, 0x9F, 0xA2, 0xA4, 0xA6, 0xA8, 0xAA, 0xAB, 0xAE, 0xAF, 0xB1, 0xB2, 0xB6, 0xB7, 0xB8, 0xBE, 
+	0x8B, 0x8D, 0x92, 0x99, 0x9D, 0x9F, 0xA5, 0xA6, 0xAB, 0xAC, 0xAD, 0xAF, 0xB1, 0xB3, 0xB8, 0xB9, 
+	0xBB, 0xBD, 0x85, 0x91, 0x92, 0x93, 0x94, 0x97, 0x99, 0x9B, 0x9C, 0x9E, 0x9F, 0xA1, 0xA3, 0xA5, 
+	0xA6, 0xA7, 0xAB, 0xB1, 0xB3, 0xB4, 0xB9, 0xBA, 0xBB, 0x82, 0x83, 0x84, 0x85, 0x86, 0x89, 0x8E, 
+	0x96, 0x97, 0x98, 0x9C, 0xA3, 0xA8, 0xAB, 0xAF, 0xB1, 0xB2, 0xB4, 0xB5, 0xB6, 0xB8, 0xB9, 0x80, 
+	0x85, 0x89, 0x8A, 0x8F, 0x90, 0x92, 0x98, 0xB3, 0xB5, 0xB7, 0xBB, 0xBC, 0x85, 0x87, 0x89, 0x8A, 
+	0x8E, 0x93, 0x96, 0x9A, 0x9E, 0x9F, 0xA0, 0xA2, 0xA8, 0xAA, 0xAB, 0xB1, 0xB5, 0xBD, 0x81, 0x85, 
+	0x8A, 0x8C, 0x8E, 0x93, 0x96, 0x98, 0x9C, 0x9F, 0xA0, 0xA9, 0xAB, 0xAF, 0xB0, 0xB1, 0xB2, 0xB4, 
+	0xB7, 0xBB, 0xBD, 0x83, 0x84, 0x87, 0x8B, 0x8C, 0x8D, 0x8E, 0x93, 0xA0, 0xA2, 0xA9, 0xAA, 0xAC, 
+	0xB1, 0xB5, 0xB8, 0xBC, 0xBD, 0x86, 0x89, 0x8E, 0x97, 0x9B, 0xA1, 0xA2, 0xA3, 0xA6, 0xA9, 0xAB, 
+	0xAC, 0xAD, 0xAE, 0xAF, 0xB1, 0xB5, 0xB7, 0xB9, 0xBA, 0x82, 0x84, 0x8B, 0x90, 0x94, 0x99, 0x9C, 
+	0x9F, 0xA1, 0xAD, 0xB2, 0xB8, 0xB9, 0xBB, 0xBC, 0xBF, 0x81, 0x84, 0x86, 0x89, 0x8A, 0x8B, 0x8D, 
+	0x90, 0x91, 0x96, 0x99, 0x9A, 0xAC, 0xAE, 0xB4, 0xBC, 0xBF, 0x80, 0x86, 0x91, 0x93, 0x94, 0x95, 
+	0x97, 0x98, 0x9A, 0x9F, 0xA1, 0xA6, 0xAC, 0xAD, 0xB5, 0xBD, 0x80, 0x81, 0x83, 0x88, 0x89, 0x8A, 
+	0x8B, 0x8E, 0x95, 0x97, 0x98, 0x9A, 0xA3, 0xA8, 0xA9, 0xAA, 0xAD, 0xB7, 0xBE, 0x80, 0x84, 0x87, 
+	0x88, 0x8A, 0x90, 0x91, 0x94, 0x97, 0x99, 0x9B, 0x9C, 0xA4, 0xA6, 0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 
+	0xAE, 0xAF, 0xB9, 0xBA, 0x81, 0x89, 0x8D, 0x8F, 0x90, 0x95, 0x9C, 0x9D, 0xA4, 0xA5, 0xA9, 0xAA, 
+	0xB7, 0xB9, 0xBA, 0xBB, 0xBE, 0x82, 0x86, 0x87, 0x8A, 0x8B, 0x93, 0x96, 0x97, 0x9A, 0xA2, 0xAD, 
+	0xAF, 0xB0, 0xBF, 0x8D, 0x8E, 0x90, 0x94, 0x95, 0x9A, 0x9C, 0x9E, 0x9F, 0xA7, 0xAB, 0xB1, 0xB9, 
+	0xBB, 0x8A, 0x8B, 0x8C, 0x93, 0x95, 0xA3, 0xA4, 0xA9, 0xAA, 0xAB, 0xAF, 0xB0, 0xB6, 0x84, 0x86, 
+	0x87, 0x89, 0x8B, 0x8D, 0x8E, 0x94, 0x99, 0x9B, 0x9E, 0x9F, 0xA4, 0xA9, 0xAC, 0xAD, 0xAE, 0xAF, 
+	0xB8, 0xB9, 0xBB, 0xBE, 0x80, 0x82, 0x83, 0x86, 0x88, 0x89, 0x8A, 0x8D, 0x91, 0x92, 0x98, 0x9A, 
+	0x9C, 0xA5, 0xA9, 0xB4, 0xB7, 0xBB, 0xBF, 0x89, 0x8B, 0x8C, 0x8E, 0x93, 0x95, 0x97, 0x99, 0x9F, 
+	0xA0, 0xA3, 0xA6, 0xA8, 0xAA, 0xAE, 0xB4, 0xB6, 0xB8, 0xBF, 0x82, 0x8D, 0x9F, 0xA2, 0xAB, 0xAF, 
+	0xB3, 0xBA, 0xBB, 0xBD, 0x80, 0x84, 0x86, 0x87, 0x8B, 0x90, 0x92, 0xA0, 0xAF, 0xB2, 0xB6, 0xB7, 
+	0xB9, 0xBB, 0xBE, 0x85, 0x8D, 0x8E, 0x8F, 0x91, 0x95, 0x96, 0xA1, 0xA2, 0xA3, 0xA7, 0xB1, 0xB6, 
+	0xB9, 0xBB, 0x80, 0x82, 0x84, 0x86, 0x8C, 0x8D, 0x92, 0x93, 0x97, 0x99, 0x9B, 0x9D, 0x9E, 0xA1, 
+	0xA2, 0xA3, 0xA8, 0xAB, 0xB0, 0xB2, 0xB5, 0xB7, 0xBD, 0xBE, 0xBF, 0x81, 0x82, 0x88, 0x8B, 0x8D, 
+	0x92, 0x96, 0x97, 0x99, 0x9E, 0xA2, 0xA4, 0xAB, 0xAE, 0xB0, 0xB1, 0xB4, 0xB5, 0xB7, 0xBF, 0x81, 
+	0x82, 0x83, 0x84, 0x85, 0x8F, 0x94, 0x95, 0x98, 0x99, 0x9C, 0x9D, 0x9F, 0xA1, 0xA8, 0xB2, 0xB3, 
+	0xB4, 0xB8, 0xB9, 0xBC, 0xBD, 0xBE, 0x82, 0x84, 0x87, 0x8A, 0x8C, 0x90, 0x92, 0x93, 0x9D, 0x9E, 
+	0xA5, 0xAA, 0xAB, 0xB6, 0xB8, 0xBB, 0x81, 0x83, 0x84, 0x8C, 0x8D, 0x96, 0x9E, 0x9F, 0xA0, 0xA4, 
+	0xA6, 0xAA, 0xAD, 0xAF, 0xB2, 0xB4, 0xB7, 0xBE, 0xBF, 0x81, 0x83, 0x86, 0x87, 0x88, 0x8A, 0x8B, 
+	0x8F, 0x93, 0x96, 0x97, 0x98, 0x9A, 0xA1, 0xA6, 0xA7, 0xA9, 0xAA, 0xAC, 0xAF, 0xB2, 0xB3, 0xBA, 
+	0xBD, 0xBF, 0x80, 0x92, 0x9A, 0x9C, 0x9D, 0xA3, 0xA6, 0xA7, 0xB4, 0xB8, 0x80, 0x82, 0x83, 0x88, 
+	0x8A, 0x8C, 0x8E, 0x90, 0x93, 0x96, 0x97, 0x98, 0x9B, 0x9D, 0x9F, 0xA3, 0xA5, 0xAA, 0xAD, 0xB1, 
+	0xB3, 0xB4, 0xB6, 0xBA, 0xBB, 0xBC, 0x81, 0x86, 0x88, 0x90, 0x91, 0x92, 0x94, 0x95, 0x9B, 0x9E, 
+	0xA0, 0xA2, 0xA3, 0xA6, 0xA9, 0xAB, 0xAC, 0xAD, 0xAE, 0xB0, 0xB1, 0xB2, 0xB3, 0xBC, 0x82, 0x84, 
+	0x85, 0x87, 0x89, 0x8C, 0x8D, 0x91, 0x93, 0x95, 0x98, 0x9A, 0x9E, 0xA0, 0xA1, 0xA3, 0xA4, 0xA5, 
+	0xA6, 0xA8, 0xAC, 0xAD, 0xB0, 0xB2, 0xB9, 0xBC, 0xBF, 0x82, 0x84, 0x87, 0x8B, 0x8C, 0x8D, 0x8F, 
+	0x92, 0x96, 0x9A, 0x9B, 0x9C, 0x9E, 0xA0, 0xA1, 0xA2, 0xA4, 0xA6, 0xA7, 0xAB, 0xAD, 0xAE, 0xB1, 
+	0xB3, 0xB7, 0xB8, 0xBA, 0xBE, 0x80, 0x81, 0x82, 0x84, 0x87, 0x8C, 0x8E, 0x90, 0x94, 0x96, 0x97, 
+	0x99, 0x9A, 0x9B, 0x9D, 0xA0, 0xA1, 0xA6, 0xA8, 0xAB, 0xAC, 0xB3, 0xB9, 0xBE, 0x81, 0x89, 0x8C, 
+	0x8E, 0x8F, 0x96, 0x98, 0x9A, 0x9B, 0x9C, 0x9F, 0xA6, 0xAB, 0xAC, 0xAF, 0xB0, 0xB1, 0xB2, 0xB4, 
+	0xB7, 0xBD, 0x80, 0x83, 0x8A, 0x8C, 0x8E, 0x90, 0x92, 0x93, 0x96, 0x99, 0x9A, 0xB7, 0xBA, 0xBF, 
+	0x81, 0x86, 0x88, 0x8A, 0x8C, 0x8E, 0x90, 0x95, 0x9A, 0xA1, 0xA2, 0xAA, 0xAB, 0xAC, 0xB8, 0xB9, 
+	0xBA, 0xBC, 0x82, 0x85, 0x89, 0x8A, 0x8C, 0x8D, 0x8E, 0x94, 0x98, 0x9D, 0x9E, 0xA0, 0xA1, 0xA2, 
+	0xA7, 0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF, 0xB0, 0xB2, 0xB3, 0xB4, 0xB6, 0xB7, 0xB8, 
+	0xBB, 0xBC, 0xBD, 0xBF, 0x80, 0x81, 0x82, 0x83, 0x84, 0x87, 0x88, 0x8A, 0x8D, 0x8E, 0x91, 0x93, 
+	0x9A, 0x9B, 0x9C, 0x9E, 0xA0, 0xA2, 0xA3, 0xA4, 0xA6, 0xAA, 0xAD, 0xBA, 0xBB, 0xBC, 0xBD, 0x84, 
+	0x85, 0x87, 0x88, 0x8A, 0x8B, 0x8D, 0x8F, 0x90, 0x93, 0x94, 0x96, 0xA4, 0xA6, 0xA7, 0xAB, 0xAD, 
+	0xB0, 0xB1, 0xB3, 0xB4, 0xB7, 0x81, 0x85, 0x8A, 0x99, 0xA3, 0xA8, 0xB3, 0xBA, 0xBE, 0x82, 0x8B, 
+	0x8C, 0x8F, 0x96, 0x9A, 0x9B, 0x9D, 0x9F, 0xA1, 0xA3, 0xA8, 0xAA, 0xAB, 0xAF, 0xB3, 0xB5, 0xBC, 
+	0xBF, 0x88, 0x89, 0x8A, 0x8F, 0x90, 0x9D, 0x9E, 0x9F, 0xAA, 0xB0, 0xB4, 0xB5, 0x82, 0x84, 0x87, 
+	0x88, 0x89, 0x8A, 0x8C, 0x90, 0x95, 0x99, 0x9F, 0xA0, 0xA3, 0xA4, 0xB2, 0xB4, 0xB6, 0xBC, 0x81, 
+	0x84, 0x85, 0x87, 0x8A, 0x8B, 0x8D, 0x91, 0x93, 0x94, 0x99, 0xA1, 0xAA, 0xAB, 0xAC, 0xAF, 0xB0, 
+	0xB1, 0xBE, 0x85, 0x86, 0x88, 0x8A, 0x8B, 0x8C, 0x8D, 0x92, 0x9B, 0x9F, 0xA2, 0xA3, 0xAB, 0xB8, 
+	0xBB, 0xBC, 0xBD, 0xBE, 0x83, 0x85, 0x89, 0x8A, 0x8C, 0x92, 0x93, 0x94, 0x95, 0x99, 0x9B, 0x9C, 
+	0x9D, 0x9F, 0xA6, 0xA9, 0xAA, 0xAF, 0xB3, 0xB8, 0xB9, 0xBB, 0xBE, 0xBF, 0x82, 0x84, 0x85, 0x86, 
+	0x89, 0x8C, 0x8D, 0x8E, 0x97, 0x9C, 0x9F, 0xA1, 0xA2, 0xA3, 0xA4, 0x9B, 0x9C, 0x9E, 0x9F, 0xA3, 
+	0xA7, 0xA8, 0xAD, 0xAE, 0xAF, 0xB0, 0xB1, 0xB2, 0xB7, 0xBA, 0xBB, 0xBC, 0xBF, 0x82, 0x84, 0x85, 
+	0x8E, 0x91, 0x94, 0x9A, 0xA2, 0xA5, 0xA6, 0xA9, 0xAA, 0xAB, 0xAD, 0xAF, 0xB0, 0xB4, 0xB7, 0xB8, 
+	0xB9, 0xBA, 0xBD, 0x80, 0x81, 0x83, 0x85, 0x86, 0x8B, 0x8D, 0x8E, 0x8F, 0x90, 0x91, 0x93, 0x94, 
+	0x95, 0x96, 0x97, 0x99, 0x9A, 0x9D, 0x9E, 0x9F, 0xA0, 0xA1, 0xA2, 0xA3, 0xA7, 0xAE, 0xB1, 0xB2, 
+	0xB5, 0xB6, 0xB8, 0xB9, 0xBC, 0xBE, 0x81, 0x82, 0x85, 0x87, 0x89, 0x8A, 0x8B, 0x8D, 0x8E, 0x8F, 
+	0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x98, 0x99, 0x9C, 0x9E, 0xA0, 0xA1, 0xA3, 0xA5, 0xA8, 
+	0xA9, 0xAD, 0xAE, 0xAF, 0xB2, 0xB5, 0xB6, 0xB7, 0xB8, 0xBA, 0xBC, 0xBD, 0xBF, 0x80, 0x81, 0x82, 
+	0x83, 0x84, 0x87, 0x89, 0x8A, 0x8F, 0x91, 0xA3, 0xA6, 0xA8, 0xAA, 0xAF, 0xB1, 0xB5, 0xB8, 0x81, 
+	0x8A, 0x8E, 0x9B, 0xA1, 0xA2, 0xA4, 0xA8, 0xAD, 0xB5, 0xB7, 0xBD, 0x82, 0x92, 0x99, 0xAD, 0xB0, 
+	0xB2, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x92, 0x94, 0x96, 0x98, 0xA2, 0xA3, 0xA5, 0xA9, 0xAA, 
+	0xAC, 0xB2, 0xB3, 0xB5, 0xB7, 0xB8, 0x82, 0x87, 0x89, 0x8B, 0x8D, 0x90, 0x92, 0x97, 0x9C, 0xA2, 
+	0xA4, 0xAA, 0xAB, 0xAF, 0xB4, 0xB5, 0xB8, 0xBA, 0x80, 0x81, 0x86, 0x87, 0x88, 0x89, 0x8B, 0x8C, 
+	0x8D, 0x8E, 0x8F, 0x90, 0x91, 0x96, 0x98, 0x9B, 0x9C, 0x9D, 0x9F, 0xA1, 0xA3, 0xA6, 0xA7, 0xB5, 
+	0xB6, 0xBC, 0xBF, 0x8D, 0x8E, 0x91, 0x94, 0x95, 0x9E, 0xA9, 0xAC, 0xB4, 0xB7, 0xBF, 0x84, 0x85, 
+	0x88, 0x89, 0x8B, 0x90, 0x97, 0x9A, 0x9B, 0x9E, 0xA2, 0xA4, 0xA6, 0xB1, 0xBE, 0x80, 0x83, 0x85, 
+	0x91, 0x93, 0x95, 0x96, 0x98, 0x9A, 0x9B, 0x9C, 0xAD, 0xB7, 0xB9, 0x8F, 0x92, 0xA4, 0xA9, 0xAA, 
+	0xAD, 0xB2, 0xB3, 0xB8, 0xBA, 0xBC, 0x86, 0x8F, 0x90, 0x98, 0x99, 0x9A, 0xA0, 0xA2, 0xA3, 0xA6, 
+	0xA8, 0xAB, 0xAC, 0xAE, 0xAF, 0xB2, 0xB5, 0xBA, 0xBB, 0x84, 0x8B, 0x8D, 0x94, 0x96, 0x9B, 0x9C, 
+	0xA0, 0xAC, 0xAE, 0xB5, 0xBC, 0xBE, 0x8C, 0x94, 0x96, 0x97, 0x9A, 0xA7, 0xAC, 0xAD, 0xAE, 0xB0, 
+	0xB9, 0x83, 0x88, 0x90, 0x91, 0x96, 0x97, 0x98, 0x9D, 0xA1, 0xA4, 0xA5, 0xA8, 0x83, 0x87, 0x90, 
+	0x93, 0x94, 0x98, 0x99, 0x9A, 0xA1, 0xAB, 0xB5, 0xB6, 0xB8, 0xBA, 0x81, 0x84, 0x91, 0x92, 0x93, 
+	0x9A, 0x9B, 0x9E, 0xA0, 0xA2, 0xAA, 0xB0, 0xB5, 0xB7, 0xBC, 0xBD, 0xBE, 0xBF, 0x81, 0xB7, 0x80, 
+	0x82, 0x83, 0x87, 0x89, 0x8A, 0x8B, 0x8F, 0x91, 0x93, 0x94, 0x96, 0x98, 0x99, 0xA0, 0xA2, 0xA3, 
+	0xA4, 0xA5, 0xA7, 0xA8, 0xAD, 0xB2, 0xB9, 0xBB, 0xBC, 0xBE, 0x83, 0x87, 0x8A, 0x8C, 0x8D, 0x94, 
+	0x95, 0x96, 0x98, 0x9C, 0xA1, 0xA2, 0xA5, 0x9C, 0xA1, 0xA8, 0xAA, 0xAE, 0xAF, 0xB2, 0xBB, 0xBF, 
+	0x80, 0x82, 0x84, 0x8B, 0x8C, 0x8D, 0x8F, 0x90, 0x9B, 0x9C, 0x9D, 0x9E, 0x9F, 0xA2, 0xA3, 0xA4, 
+	0xA5, 0xA6, 0xAA, 0xAC, 0xB0, 0xB2, 0xB3, 0xB5, 0xB6, 0xB7, 0xB8, 0xBA, 0xBD, 0x85, 0x86, 0x88, 
+	0x8A, 0x8B, 0x8D, 0x8E, 0x8F, 0x94, 0x95, 0x97, 0x98, 0x99, 0x9B, 0x9C, 0xA0, 0xA3, 0xA7, 0xA8, 
+	0xAA, 0xB0, 0xB1, 0xB2, 0xB4, 0xB6, 0xB7, 0xB8, 0xB9, 0xBB, 0xBC, 0x80, 0x81, 0x84, 0x85, 0x86, 
+	0x87, 0x89, 0x8B, 0x8C, 0x8D, 0x8E, 0x91, 0x95, 0x96, 0x99, 0x9B, 0x9C, 0xA2, 0xA3, 0xA8, 0xAA, 
+	0xAB, 0xB0, 0xB2, 0xB6, 0xB7, 0xB9, 0xBB, 0x80, 0x84, 0x86, 0x87, 0x88, 0x8A, 0x8D, 0x8E, 0x8F, 
+	0x91, 0x93, 0x96, 0x99, 0x9C, 0x9E, 0xA4, 0xA7, 0xAA, 0xB0, 0xB2, 0xB8, 0xB9, 0xBD, 0xBE, 0x82, 
+	0x84, 0x86, 0x88, 0x89, 0x92, 0x96, 0x99, 0x9C, 0x9E, 0xA0, 0xA1, 0xA2, 0xA4, 0xA6, 0xA8, 0xA9, 
+	0xAB, 0xAD, 0xB1, 0xB4, 0xB9, 0xBA, 0xBC, 0x81, 0x84, 0x85, 0x86, 0x8B, 0x8D, 0x8F, 0x90, 0x98, 
+	0x9C, 0xA0, 0xA3, 0xA6, 0xA8, 0xAB, 0xAD, 0xB3, 0xB4, 0x83, 0x86, 0x88, 0x8B, 0x93, 0x9C, 0xAD, 
+	0xAE, 0xB2, 0xB3, 0xB5, 0xB6, 0xBB, 0xBF, 0x81, 0x82, 0x83, 0x85, 0x86, 0x88, 0x8C, 0x8F, 0x90, 
+	0x91, 0x92, 0x93, 0x97, 0x98, 0x9A, 0xA1, 0xA4, 0xAC, 0xAD, 0xB4, 0xB7, 0xB8, 0xBB, 0xBC, 0xBD, 
+	0x86, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F, 0x94, 0x95, 0x98, 0x9B, 0x9E, 0xA7, 0xAB, 0xAF, 0xB0, 0xB1, 
+	0xB3, 0xB4, 0xA8, 0xAA, 0xAF, 0xB1, 0xB6, 0x83, 0x84, 0x86, 0x9B, 0x9C, 0x9F, 0xA2, 0xA9, 0xAB, 
+	0xAD, 0xAE, 0xAF, 0xB2, 0xB4, 0xBC, 0xBD, 0xBE, 0x83, 0x85, 0x89, 0x8A, 0x8C, 0x90, 0x92, 0x93, 
+	0x94, 0x98, 0x9D, 0x9E, 0xA0, 0xA1, 0xA4, 0xA8, 0xAC, 0xAE, 0xBD, 0xBE, 0x82, 0x85, 0x89, 0x8B, 
+	0x8C, 0x90, 0x91, 0x92, 0x95, 0x97, 0x96, 0x97, 0x98, 0x99, 0xA5, 0xA8, 0xAC, 0xAD, 0xAE, 0xB3, 
+	0xB4, 0xBC, 0x81, 0x84, 0x85, 0x86, 0x88, 0x90, 0x91, 0x92, 0x95, 0x98, 0x9B, 0x9D, 0x9F, 0xA2, 
+	0xAD, 0xAE, 0xB1, 0xB2, 0xB8, 0xBB, 0xBF, 0x81, 0x85, 0x8E, 0x8F, 0x92, 0x93, 0x99, 0xA8, 0xAB, 
+	0xB0, 0xB7, 0xBE, 0x80, 0x82, 0x83, 0x85, 0x8D, 0x95, 0x97, 0x9A, 0x9B, 0x9F, 0xA2, 0xA4, 0xA5, 
+	0xA9, 0xAA, 0xAB, 0xA8, 0xAD, 0xB0, 0xB8, 0xBC, 0x80, 0x84, 0x8F, 0x91, 0x93, 0x94, 0x98, 0x9E, 
+	0x9F, 0xA2, 0xA3, 0xA6, 0xAA, 0xAB, 0xAD, 0xAE, 0xAF, 0xB1, 0xB4, 0xB7, 0xBB, 0x86, 0x98, 0x9A, 
+	0x9F, 0xA2, 0xA3, 0xA5, 0xA7, 0xA8, 0xA9, 0xAA, 0xAE, 0xAF, 0xB1, 0xB2, 0xBB, 0xBC, 0x81, 0x82, 
+	0x83, 0x84, 0x85, 0x8D, 0x8E, 0x8F, 0x91, 0x94, 0x98, 0x9A, 0xAF, 0xB4, 0x83, 0x8E, 0x91, 0x92, 
+	0x93, 0x96, 0x97, 0x9F, 0xA0, 0xA8, 0xAA, 0xAB, 0xAD, 0xAE, 0xB4, 0xB9, 0x80, 0x86, 0x89, 0x8A, 
+	0x8F, 0x91, 0x92, 0x94, 0x96, 0x9B, 0xA1, 0xA2, 0xA3, 0xA4, 0xA8, 0xB0, 0xB1, 0xB2, 0xB5, 0x84, 
+	0x86, 0x88, 0x89, 0x8A, 0x8C, 0x8D, 0x90, 0x92, 0x93, 0x94, 0x95, 0x9B, 0xA1, 0xA4, 0xA5, 0xAD, 
+	0xAE, 0xAF, 0xB0, 0xB2, 0xB9, 0xBA, 0xBB, 0xBE, 0x86, 0x87, 0x88, 0x92, 0x97, 0x9A, 0xA0, 0xA7, 
+	0xB6, 0xB8, 0xA5, 0xA7, 0xA9, 0xAB, 0xAC, 0xB0, 0xB3, 0xB4, 0xB6, 0x83, 0x86, 0x87, 0x88, 0x89, 
+	0x8E, 0x92, 0x95, 0x9B, 0x9F, 0xA3, 0xA6, 0xA8, 0xAA, 0xAB, 0xAC, 0xBB, 0xBE, 0xBF, 0x81, 0x84, 
+	0x86, 0x88, 0x90, 0x91, 0x99, 0x9C, 0x9D, 0x9E, 0xA0, 0xA1, 0xA4, 0xAC, 0xAF, 0xB2, 0xBA, 0x87, 
+	0x89, 0x8F, 0x9A, 0xA4, 0xA9, 0xAB, 0xAF, 0xB2, 0xB4, 0xB8, 0xBA, 0xBB, 0x81, 0x82, 0x84, 0x86, 
+	0x8F, 0x93, 0x99, 0xA6, 0xAD, 0xAF, 0xB2, 0xB8, 0xB9, 0xBA, 0xBD, 0x9A, 0x9B, 0x9E, 0xB5, 0xB8, 
+	0xB9, 0xBD, 0xBF, 0x81, 0x88, 0x8B, 0x8C, 0x91, 0x92, 0x93, 0x95, 0x97, 0x9D, 0x9F, 0xA5, 0xA6, 
+	0xA9, 0xAA, 0xAD, 0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBE, 0xBF, 0x84, 0x8C, 0x8D, 0x8E, 0x8F, 0x90, 
+	0x92, 0x94, 0x98, 0x99, 0x9B, 0x9C, 0x9D, 0x9E, 0xA0, 0xA5, 0xA8, 0xAF, 0xB4, 0xB6, 0xB7, 0xB9, 
+	0xBB, 0xBC, 0xBD, 0x87, 0x88, 0x8E, 0x93, 0x95, 0xA0, 0xA1, 0xAC, 0xBB, 0xBE, 0x8A, 0x8B, 0x8E, 
+	0x8F, 0x92, 0x94, 0x9F, 0xA0, 0xA1, 0xA2, 0xA3, 0xA6, 0xA7, 0xAA, 0xAC, 0xB2, 0xB6, 0xB7, 0x8D, 
+	0x95, 0x9C, 0x9D, 0xA0, 0x81, 0x83, 0x84, 0x85, 0x86, 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 
+	0x8F, 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 
+	0x9F, 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 
+	0xAF, 0xB0, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE, 
+	0xBF, 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 
+	0x8F, 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 
+	0xA0, 0xA1, 0xA2, 0xA3, 0xA5
+};
+
+
+#define UTF8_CODE_2B_1_NUM  (sizeof(Utf8CodeTable_2B_1st)/2)
+#define UTF8_CODE_3B_1_NUM  (sizeof(Utf8CodeTable_3B_1st)/2)
+#define UTF8_CODE_3B_2_NUM  (sizeof(Utf8CodeTable_3B_2nd)/2)
+#define UTF8_CODE_2B_2_NUM  sizeof(Utf8CodeTable_2B_2nd)
+#define UTF8_CODE_3B_3_NUM  sizeof(Utf8CodeTable_3B_3rd)
+
+static font_work_t FontWork[NUM_FONT_WORK];
+static uint8_t     font_data[256];
+#endif
+
+/*
+ *  フォントの幅を取得する
+ *  param1  phead: フォントヘッダ
+ *  param2  c: キャラクタ
+ *  param3  len:キャラクタの長さ領域へのポインタ
+ *  return  フォント幅
+ */
+static int
+GetFontWidth(font_head_t *phead, uint8_t c, int *len)
+{
+	const font_t  **pf = phead->font_table;
+	int   width;
+
+	width = phead->font_width;
+	*len = 1;
+	if(phead->file_attribute == 0){
+		if(c < 0x80 || c >= 0xA0)
+			width = pf[c]->width;
+	}
+	else if((c & 0xE0) == 0xC0)
+		*len = 2;
+	else if((c & 0xF0) == 0xE0)
+		*len = 3;
+	else if((c & 0xF8) == 0xF0)
+		*len = 4;
+	else if(c < 0x80 || c >= 0xA0)
+		width = pf[c]->width;
+	return width;
+}
+
+#ifndef NOT_USEFILFONT
+/*
+ *  2バイトコードビットマップ番号
+ */
+static int
+GetFont2BNo(font_work_t *pft, uint8_t *ptr)
+{
+	int      totalk = 0;
+	uint32_t i, j;
+
+	for(i = 0 ; i < UTF8_CODE_2B_1_NUM; i++){
+		if(Utf8CodeTable_2B_1st[i][0] == ptr[0]) {
+			for(j = 0 ; j < Utf8CodeTable_2B_1st[i][1] ; j++) {
+				if(Utf8CodeTable_2B_2nd[totalk] == ptr[1])
+					return totalk;
+				totalk++;
+			}
+		}
+		else
+			totalk += Utf8CodeTable_2B_1st[i][1];
+	}
+	return -1;
+}
+
+/*
+ *  3バイトコードビットマップ番号
+ */
+static int
+GetFont3BNo(font_work_t *pft, uint8_t *ptr)
+{
+	int      totalk = 0;
+	int      totalj = 0;
+	uint32_t i, j, k;
+
+	for(i = 0 ; i < UTF8_CODE_3B_1_NUM ; i++){
+		if(Utf8CodeTable_3B_1st[i][0] == ptr[0]){
+			for(j = 0 ; j < Utf8CodeTable_3B_1st[i][1]; j++){
+				if(Utf8CodeTable_3B_2nd[totalj][0] == ptr[1]){
+					for(k = 0 ; k < Utf8CodeTable_3B_2nd[totalj][1]; k++) {
+						if(Utf8CodeTable_3B_3rd[totalk] == ptr[2])
+							return totalk;
+						totalk++;
+					}
+					return -1;
+				}
+				else	/*読み飛ばすbitmap個数を蓄積*/
+					totalk += Utf8CodeTable_3B_2nd[totalj][1];
+				totalj++;
+			}
+		}
+		else{	/*読み飛ばすbitmap個数を蓄積*/
+			for(j = 0 ; j < Utf8CodeTable_3B_1st[i][1] ; j++){
+				totalk += Utf8CodeTable_3B_2nd[totalj][1];
+				totalj++;
+			}
+		}
+	}
+	return -1;
+}
+#endif
+
+/*
+ *  文字描画
+ *  param1  pDrawProp: Pointer to Draw Prop
+ *  param2  x0: 文字描画 X座標始点
+ *  param3  y0: 文字描画 Y座標始点
+ *  param4  c:  文字イメージへのポインタ
+ */
+#ifndef MAX_FONT_IMAGE
+static void
+DrawChar(LCD_DrawProp_t *pDrawProp, uint16_t x0, uint16_t y0, const font_t *pf)
+{
+	LCD_Handler_t *hlcd = pDrawProp->hlcd;
+	uint32_t h, w;
+	const uint8_t  *pchar;
+
+	for(h = 0 ; h < pf->height ; h++){
+		pchar = (pf->image + pf->stride * h);
+		for(w = 0; w < pf->width ; w++){
+			if(pf->stride != 0 && (pchar[w/8] & (1 << (7 - (w % 8)))) != 0){
+				lcd_drawPixel(hlcd, (x0 + w), (y0 + h), pDrawProp->TextColor);
+			}
+			else{
+				lcd_drawPixel(hlcd, (x0 + w), (y0 + h), pDrawProp->BackColor);
+			}
+		}
+	}
+}
+#else
+static void
+DrawChar(LCD_DrawProp_t *pDrawProp, uint16_t x0, uint16_t y0, const font_t *pf)
+{
+	LCD_Handler_t *hlcd = pDrawProp->hlcd;
+	uint32_t h, w;
+	const uint8_t *pchar;
+#ifdef TRS_COLOR_T
+	TRS_COLOR_T image[MAX_FONT_IMAGE];
+#else
+	color_t     image[MAX_FONT_IMAGE];
+#endif
+
+	for(h = 0 ; h < pf->height ; h++){
+		pchar = (pf->image + pf->stride * h);
+		for(w = 0; w < pf->width ; w++){
+			if(pf->stride != 0 && (pchar[w/8] & (1 << (7 - (w % 8)))) != 0){
+				image[w] = pDrawProp->TextColor;
+			}
+			else{
+				image[w] = pDrawProp->BackColor;
+			}
+		}
+		lcd_drawImageHLine(hlcd, x0, (y0 + h), pf->width, image);
+	}
+}
+#endif
+
+/*
+ *  一文字描画(UTF8)
+ *  param1  pDrawProp: Pointer to Draw Prop
+ *  param2  x0: 文字描画 X座標始点
+ *  param3  y0: 文字描画 Y座標始点
+ *  param4  描画コードへのポインタ
+ */
+static void
+lcd_DisplayData(LCD_DrawProp_t *pDrawProp, uint16_t x0, uint16_t y0, uint8_t *ptr)
+{
+	font_head_t  *phead = (font_head_t *)pDrawProp->pFont;
+	DrawChar(pDrawProp, x0, y0, lcd_getFontTable(phead, ptr));
+}
+
+/*
+ *  フォントデータからフォントテーブルを取り出す
+ *  param1  phead: フォントヘッダ
+ *  param2  ptr: フォントデータへのポインタ
+ *  return  フォントテーブルへのポインタ
+ */
+const font_t *
+lcd_getFontTable(font_head_t *phead, uint8_t *ptr)
+{
+	const font_t **pf = phead->font_table;
+	int len;
+#ifndef NOT_USEFILFONT
+	char  fname[32+4];
+	font_t *pwf = (font_t *)font_data;
+	font_file_head_t *pffh;
+	font_work_t  *pft = NULL;
+	int no, i, k, off = 0;
+#endif
+
+	GetFontWidth(phead, *ptr, &len);
+	if(len == 1)
+		return pf[*ptr];
+	else if(phead->file_attribute == 0)
+		return pf[*ptr];
+	else{
+#ifndef NOT_USEFILFONT
+		pwf->width   = phead->font_width;
+		pwf->height  = phead->font_height;
+		pwf->stride  = (phead->font_width + 7) >> 3;
+		pwf->iheight = phead->font_height;
+		memset(pwf->image, 0, pwf->height * pwf->stride);
+
+		if(phead->pdata == NULL){
+			for(i = 0 ; i < NUM_FONT_WORK ; i++){
+				if(FontWork[i].pffont == NULL){
+					pft = &FontWork[i];
+					break;
+				}
+			}
+			if(pft != NULL){
+				sprintf(fname, "%s.fnt", phead->font_name);
+				pft->pffont = fopen(fname, "rb");
+				if(pft->pffont != NULL){
+					if(fread(pft->table, sizeof(font_file_head_t), 1, pft->pffont) != 1){
+						phead->file_attribute = 0x00;
+						fclose(pft->pffont);
+						pft->pffont = NULL;
+					}
+					else{
+						pffh = (font_file_head_t *)pft->table;
+						pft->offset_image_2B = pffh->off_2byte_font;
+						pft->offset_image_3B = pffh->off_3byte_font;
+						pft->num_table2B = pffh->siz_2byte_font;
+						pft->num_table3B = pffh->siz_3byte_font;
+						pft->image_size  = pffh->csize + pffh->isize;
+						phead->pdata = pft;
+					}
+				}
+				else
+					phead->file_attribute = 0x00;
+			}
+			else
+				phead->file_attribute = 0x00;
+		}
+		if((pft = phead->pdata) != NULL){
+			no = -1;
+			if(len == 2){
+				no = GetFont2BNo(pft, ptr);
+				off = pft->offset_image_2B;
+			}
+			else if(len == 3){
+				no = GetFont3BNo(pft, ptr);
+				off = pft->offset_image_3B;
+			}
+			if(no >= 0){
+				uint32_t length = 0;
+				uint32_t data = 0, j, c;
+				fseek(pft->pffont, (no * pft->image_size + off), SEEK_SET);
+				fread(pft->table, pft->image_size, 1, pft->pffont);
+
+				for(i = j = k = no = 0 ; i < phead->font_height ; i++){
+					while(length < phead->font_width){
+						data <<= 8;
+						data |= pft->table[no+1];
+						length += 8;
+						no++;
+					}
+					j = phead->font_width;
+					while(j >= 8){
+						c = data >> (length - 8);
+						j -= 8;
+						length -= 8;
+						pwf->image[k++] = c;
+					}
+					if(j > 0){
+						c = data << (8-j);
+						length -= j;
+						pwf->image[k++] = c;
+					}
+				}
+			}
+		}
+		return pwf;
+#else
+		return pf[*ptr];
+#endif
+	}
+}
+
+/*
+ *  文字列表示ラインクリア
+ *  param1  pDrawProp: Pointer to Draw Prop
+ *  param2  ライン番号
+ */
+void
+lcd_clearStringLine(LCD_DrawProp_t *pDrawProp, uint16_t Line)
+{
+	font_head_t *phead = (font_head_t *)pDrawProp->pFont;
+	lcd_fillRect(pDrawProp->hlcd, 0, (Line * phead->font_height), pDrawProp->hlcd->_width, phead->font_height, pDrawProp->BackColor);
+}
+
+/*
+ *  一文字描画
+ *  param1  pDrawProp: Pointer to Draw Prop
+ *  param2  x0: 文字描画 X座標始点
+ *  param3  y0: 文字描画 Y座標始点
+ *  param4  描画アスキーコード(範囲は0x20から0x7Eまで)
+ */
+void
+lcd_DisplayChar(LCD_DrawProp_t *pDrawProp, uint16_t x0, uint16_t y0, uint8_t Ascii)
+{
+	font_head_t  *phead = (font_head_t *)pDrawProp->pFont;
+	const font_t **pf   = phead->font_table;
+
+	DrawChar(pDrawProp, x0, y0, pf[Ascii]);
+}
+
+/*
+ *  文字列描画
+ *  param1  pDrawProp: Pointer to Draw Prop
+ *  param1  x0: 文字列描画 X座標始点
+ *  param2  y0: 文字列描画 Y座標始点
+ *  param3  Text: 描画文字列へのポインタ
+ *  param4  Mode: 表示モード
+ */
+void
+lcd_DisplayStringAt(LCD_DrawProp_t *pDrawProp, uint16_t x0, uint16_t y0, uint8_t *Text, Line_ModeTypdef Mode)
+{
+	LCD_Handler_t *hlcd = pDrawProp->hlcd;
+	font_head_t   *phead = (font_head_t *)pDrawProp->pFont;
+	const font_t  **pf = phead->font_table;
+	uint16_t ref_column = 1;
+	uint32_t size = 0;
+	uint8_t  *ptr = (uint8_t *)Text, c;
+	int      wid, len  = 1;
+
+	/* Get the text size */
+	while(*ptr){
+		size += GetFontWidth(phead, *ptr, &len);
+		ptr  += len;
+	}
+
+	switch (Mode){
+	case CENTER_MODE:
+		ref_column = x0 + (hlcd->_width - size) / 2;
+		break;
+	case LEFT_MODE:
+		ref_column = x0;
+		break;
+	case RIGHT_MODE:
+		ref_column = - x0 + (hlcd->_width - size);
+		break;
+	default:
+		ref_column = x0;
+		break;
+	}
+
+	/*
+	 *  開始カラム位置をスクリーン内に収める
+	 */
+	if((ref_column < 1) || (ref_column >= 0x8000)){
+		ref_column = 1;
+	}
+
+	/*
+	 *  一文字描画を使って文字列を描画する
+	 */
+	while (((c = *Text) != 0) && pf[c] != 0 && (ref_column + (wid = GetFontWidth(phead, c, &len))) <= hlcd->_width){
+		lcd_DisplayData(pDrawProp, ref_column, y0, Text);
+		ref_column += wid;	/* 次のカラムに移動 */
+		Text += len;		/* 次の文字に移動 */
+	}
+}
+
+/*
+ *  文字列描画
+ *  param1  pDrawProp: Pointer to Draw Prop
+ *  param2  x0: 文字列描画 X座標始点
+ *  param3  y0: 文字列描画 Y座標始点
+ *  param4  Text: 描画文字列へのポインタ
+ */
+void
+lcd_DisplayStringAtLine(LCD_DrawProp_t *pDrawProp, uint16_t Line, uint8_t *ptr)
+{
+	font_head_t  *phead = (font_head_t *)pDrawProp->pFont;
+	const font_t *pf;
+
+	pf = phead->font_table[' '];
+	lcd_DisplayStringAt(pDrawProp, 0, Line * pf->height, ptr, LEFT_MODE);
+}
+
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/ui/snfont_disp/glcd_disp.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/ui/snfont_disp/glcd_disp.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/ui/snfont_disp/glcd_disp.h	(revision 457)
@@ -0,0 +1,123 @@
+/*
+ *  TOPPERS BASE PLATFORM MIDDLEWARE
+ * 
+ *  Copyright (C) 2017-2018 by TOPPERS PROJECT
+ *                             Educational Working Group.
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+#ifndef _GLCD_DISP_H_
+#define _GLCD_DISP_H_
+
+#ifdef __cplusplus
+ extern "C" {
+#endif 
+
+#include "glcd_core.h"
+#include "fonts.h"
+
+/*
+ *  テキスト表示ラインモード定義
+ */
+typedef enum
+{
+	CENTER_MODE = 0x01,	/* Center mode */
+	RIGHT_MODE,			/* Right mode  */
+	LEFT_MODE			/* Left mode   */
+}Line_ModeTypdef;
+
+
+#define Font8   Embedded_Font9
+#define Font12  Shinonome_Font12
+#define Font16  Shinonome_Font16
+
+/*
+ *  BSP表示関数変換定義
+ */
+#define BSP_LCD_Init()                  lcd_init(pHLCD, LCD_ORIENTATION_LANDSCAPE)
+#define BSP_LCD_DeInit()                lcd_deinit(pHLCD)
+#define BSP_LCD_LayerDefaultInit(a, b)  lcd_layerdefaultinit(pHLCD, pDRAWPROP, (a), (b))
+#define BSP_LCD_SetLayerWindow(i, x, y, w, h) lcd_setAddrWindow(pHLCD, (i), (x), (y), (w), (h))
+
+#define BSP_LCD_Clear(c)                lcd_clear(pHLCD, (c))
+#define BSP_LCD_ReadPixel(x, y)         lcd_readPixel(pHLCD, (x), (y))
+#define BSP_LCD_DrawPixel(x, y, c)      lcd_drawPixel(pHLCD, (x), (y), (c))
+#define BSP_LCD_DrawHLine(x, y, w)      lcd_drawFastHLine(pHLCD, (x), (y), (w), pDRAWPROP->TextColor)
+#define BSP_LCD_DrawVLine(x, y, h)      lcd_drawFastVLine(pHLCD, (x), (y), (h), pDRAWPROP->TextColor)
+#define BSP_LCD_DrawBitmap(x, y, p)     lcd_drawBitmap(pHLCD, (x), (y), (p))
+#define BSP_LCD_DrawRGBImage(x, y, xs, ys, p) lcd_drawRGBImage(pHLCD, (x), (y), (xs), (xy), (p))
+#define BSP_LCD_DisplayOn()             lcd_displayOn(pHLCD)
+#define BSP_LCD_DisplayOff()            lcd_displayOff(pHLCD)
+#define BSP_LCD_FillRect(x, y, w,h)     lcd_fillRect(pHLCD, (x), (y), (w), (h), pDRAWPROP->TextColor)
+
+#define BSP_LCD_DrawLine(x, y, x2, y2)  lcd_drawLine(pDRAWPROP, (x), (y), (x2), (y2))
+#define BSP_LCD_DrawRect(x, y, w, h)    lcd_drawRect(pDRAWPROP, (x), (y), (w), (h))
+#define BSP_LCD_DrawCircle(x, y, r)     lcd_DrawCircle(pDRAWPROP, (x), (y), (r))
+#define BSP_LCD_DrawEllipse(x, y, xr, yr) lcd_DrawEllipse(pDRAWPROP, (x), (y), (xr), (yr))
+#define BSP_LCD_DrawPolygon(a, b)       lcd_drawPolygon(pDRAWPROP, (a), (b))
+#define BSP_LCD_FillCircle(x, y, r)     lcd_fillCircle(pDRAWPROP, (x), (y), (r))
+#define BSP_LCD_FillEllipse(x, y, xr, yr) lcd_fillEllipse(pDRAWPROP, (x), (y), (xr), (yr))
+#define BSP_LCD_FillPolygon(a, b)       lcd_fillPolygon(pDRAWPROP, (a), (b))
+
+#define BSP_LCD_ClearStringLine(l)      lcd_clearStringLine(pDRAWPROP, (l))
+#define BSP_LCD_DisplayChar(x, y, a)    lcd_DisplayChar(pDRAWPROP, (x), (y), (a))
+#define BSP_LCD_DisplayStringAt(x, y, t, m) lcd_DisplayStringAt(pDRAWPROP, (x), (y), (t), (m))
+#define BSP_LCD_DisplayStringAtLine(l, p) lcd_DisplayStringAtLine(pDRAWPROP, (l), (p))
+
+#define BSP_LCD_SelectLayer(a)          pHLCD->layer = (a)
+#define BSP_LCD_GetXSize()              pHLCD->_width
+#define BSP_LCD_GetYSize()              pHLCD->_height
+#define BSP_LCD_SetTextColor(c)         pDRAWPROP->TextColor = (c)
+#define BSP_LCD_GetTextColor()          pDRAWPROP->TextColor
+#define BSP_LCD_SetBackColor(c)         pDRAWPROP->BackColor = (c)
+#define BSP_LCD_GetBackColor()          pDRAWPROP->BackColor
+#define BSP_LCD_SetFont(f)              pDRAWPROP->pFont = (f)
+#define BSP_LCD_GetFont()               ((sFONT *)pDRAWPROP->pFont)
+
+
+extern const font_t *lcd_getFontTable(font_head_t *phead, uint8_t *ptr);
+extern void lcd_clearStringLine(LCD_DrawProp_t *pDrawProp, uint16_t Line);
+extern void lcd_DisplayChar(LCD_DrawProp_t *pDrawProp, uint16_t Xpos, uint16_t Ypos, uint8_t Ascii);
+extern void lcd_DisplayStringAt(LCD_DrawProp_t *pDrawProp, uint16_t Xpos, uint16_t Ypos, uint8_t *Text, Line_ModeTypdef Mode);
+extern void lcd_DisplayStringAtLine(LCD_DrawProp_t *pDrawProp, uint16_t Line, uint8_t *ptr);
+
+#ifdef USE_ROMFONT
+extern const uint8_t romfont[];
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _GLCD_DISP_H_ */
+
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/ui/snfont_disp/shinonome_font.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/ui/snfont_disp/shinonome_font.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/ui/snfont_disp/shinonome_font.c	(revision 457)
@@ -0,0 +1,22472 @@
+
+#ifdef USE_ROMFONT
+
+#include "kernel.h"
+
+const uint8_t romfont[] = {
+	0x00,  0x02,  0x01,  0xD4,  's',   'h',   'i',   'n',   'o',   'n',   'o',   'm',   'e',   '_',   'f',   'o', 	/* 00000 */
+	'n',   't',   '1',   '2',   '.',   'f',   'n',   't',   0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00, 	/* 00010 */
+	'F',   'O',   'N',   'T',   's',   'h',   'i',   'n',   'o',   'n',   'o',   'm',   'e',   '_',   'f',   'o', 	/* 00020 */
+	'n',   't',   '1',   '2',   0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00, 	/* 00030 */
+	0x00,  0x00,  0x00,  0x00,  0xB1,  0x01,  0x02,  0x00,  0x01,  0x00,  0x00,  0x00,  0x12,  0x00,  0x00,  0x00, 	/* 00040 */
+	0x58,  0x00,  0x00,  0x00,  0x06,  0x00,  0x00,  0x00,  0x64,  0x00,  0x00,  0x00,  0x09,  0x00,  0x00,  0x00, 	/* 00050 */
+	0x76,  0x00,  0x00,  0x00,  0x57,  0x01,  0x00,  0x00,  0x24,  0x03,  0x00,  0x00,  0x7A,  0x00,  0x00,  0x00, 	/* 00060 */
+	0x32,  0x0C,  0x00,  0x00,  0x65,  0x1A,  0x00,  0x00,  0xC2,  0x06,  0xC3,  0x02,  0xCE,  0x27,  0xCF,  0x09, 	/* 00070 */
+	0xD0,  0x31,  0xD1,  0x11,  0xE2,  0x0E,  0xE3,  0x04,  0xE4,  0x08,  0xE5,  0x40,  0xE6,  0x40,  0xE7,  0x3F, 	/* 00080 */
+	0xE8,  0x3F,  0xE9,  0x3C,  0xEF,  0x03,  0x80,  0x0E,  0x84,  0x02,  0x86,  0x04,  0x87,  0x02,  0x88,  0x14, 	/* 00090 */
+	0x89,  0x07,  0x8A,  0x05,  0x8C,  0x01,  0x94,  0x1E,  0x95,  0x02,  0x96,  0x06,  0x97,  0x06,  0x98,  0x02, 	/* 000A0 */
+	0x99,  0x05,  0x80,  0x15,  0x81,  0x3F,  0x82,  0x37,  0x83,  0x3B,  0xB8,  0x1F,  0xB9,  0x13,  0xBA,  0x23, 	/* 000B0 */
+	0xBB,  0x1E,  0xBC,  0x13,  0xBD,  0x1A,  0xBE,  0x14,  0xBF,  0x1A,  0x80,  0x1A,  0x81,  0x12,  0x82,  0x0F, 	/* 000C0 */
+	0x83,  0x13,  0x84,  0x14,  0x85,  0x21,  0x86,  0x24,  0x87,  0x1B,  0x88,  0x1B,  0x89,  0x1A,  0x8A,  0x17, 	/* 000D0 */
+	0x8B,  0x1C,  0x8C,  0x1A,  0x8D,  0x21,  0x8E,  0x11,  0x8F,  0x24,  0x90,  0x1E,  0x91,  0x14,  0x92,  0x16, 	/* 000E0 */
+	0x93,  0x13,  0x94,  0x0E,  0x95,  0x0F,  0x96,  0x17,  0x97,  0x0D,  0x98,  0x0E,  0x99,  0x0D,  0x9A,  0x0D, 	/* 000F0 */
+	0x9B,  0x17,  0x9C,  0x16,  0x9D,  0x0E,  0x9E,  0x0C,  0x9F,  0x12,  0xA0,  0x13,  0xA1,  0x14,  0xA2,  0x0F, 	/* 00100 */
+	0xA3,  0x1D,  0xA4,  0x1A,  0xA5,  0x1A,  0xA6,  0x13,  0xA7,  0x12,  0xA8,  0x0F,  0xA9,  0x0A,  0xAA,  0x06, 	/* 00110 */
+	0xAB,  0x0E,  0xAC,  0x0B,  0xAD,  0x1A,  0xAE,  0x21,  0xAF,  0x22,  0xB0,  0x1F,  0xB1,  0x19,  0xB2,  0x11, 	/* 00120 */
+	0xB3,  0x0F,  0xB4,  0x0F,  0xB5,  0x0B,  0xB6,  0x0E,  0xB7,  0x1A,  0xB8,  0x15,  0xB9,  0x1C,  0xBA,  0x14, 	/* 00130 */
+	0xBB,  0x21,  0xBC,  0x1F,  0xBD,  0x1B,  0xBE,  0x1F,  0xBF,  0x14,  0x80,  0x16,  0x81,  0x1C,  0x82,  0x1C, 	/* 00140 */
+	0x83,  0x17,  0x84,  0x16,  0x85,  0x20,  0x86,  0x14,  0x87,  0x16,  0x88,  0x1D,  0x89,  0x17,  0x8A,  0x19, 	/* 00150 */
+	0x8B,  0x22,  0x8C,  0x11,  0x8D,  0x12,  0x8E,  0x1C,  0x8F,  0x12,  0x90,  0x0F,  0x91,  0x09,  0x92,  0x12, 	/* 00160 */
+	0x93,  0x18,  0x94,  0x14,  0x95,  0x16,  0x96,  0x1B,  0x97,  0x19,  0x98,  0x17,  0x99,  0x17,  0x9A,  0x15, 	/* 00170 */
+	0x9B,  0x18,  0x9C,  0x1F,  0x9D,  0x1F,  0x9E,  0x17,  0x9F,  0x1C,  0xA0,  0x12,  0xA1,  0x17,  0xA2,  0x1A, 	/* 00180 */
+	0xA3,  0x16,  0xA4,  0x1C,  0xA5,  0x1A,  0xA6,  0x12,  0xA7,  0x17,  0xA8,  0x1A,  0xA9,  0x0D,  0xAA,  0x10, 	/* 00190 */
+	0xAB,  0x0D,  0xAC,  0x12,  0xAD,  0x19,  0xAE,  0x1A,  0xAF,  0x10,  0xB0,  0x0D,  0xB1,  0x15,  0xB2,  0x1B, 	/* 001A0 */
+	0xB3,  0x16,  0xB4,  0x14,  0xB5,  0x11,  0xB6,  0x0E,  0xB7,  0x1B,  0xB8,  0x1C,  0xB9,  0x10,  0xBA,  0x13, 	/* 001B0 */
+	0xBB,  0x14,  0xBC,  0x13,  0xBD,  0x11,  0xBE,  0x0F,  0xBF,  0x16,  0x80,  0x12,  0x81,  0x0A,  0x82,  0x0D, 	/* 001C0 */
+	0x83,  0x09,  0x84,  0x09,  0x85,  0x0F,  0x86,  0x0D,  0x87,  0x16,  0x88,  0x12,  0x89,  0x15,  0x8A,  0x0E, 	/* 001D0 */
+	0x8B,  0x15,  0x8C,  0x12,  0x8D,  0x0E,  0x8E,  0x09,  0x8F,  0x0F,  0x90,  0x0D,  0x91,  0x12,  0x92,  0x07, 	/* 001E0 */
+	0x93,  0x11,  0x94,  0x1D,  0x95,  0x20,  0x96,  0x18,  0x97,  0x18,  0x98,  0x0D,  0x99,  0x19,  0x9A,  0x15, 	/* 001F0 */
+	0x9B,  0x19,  0x9C,  0x13,  0x9D,  0x0D,  0x9E,  0x10,  0x9F,  0x10,  0xA0,  0x0D,  0xA1,  0x08,  0xA2,  0x14, 	/* 00200 */
+	0xA3,  0x0F,  0xA4,  0x0D,  0xA5,  0x16,  0xA6,  0x14,  0xA7,  0x12,  0xA8,  0x16,  0xA9,  0x16,  0xAA,  0x13, 	/* 00210 */
+	0xAB,  0x20,  0xAC,  0x15,  0xAD,  0x17,  0xAE,  0x15,  0xAF,  0x13,  0xB0,  0x13,  0xB1,  0x11,  0xB2,  0x1C, 	/* 00220 */
+	0xB3,  0x16,  0xB4,  0x1F,  0xB5,  0x1A,  0xB6,  0x1A,  0xB7,  0x16,  0xB8,  0x19,  0xB9,  0x18,  0xBA,  0x0E, 	/* 00230 */
+	0xBC,  0x03,  0xBD,  0x17,  0xBE,  0x18,  0xBF,  0x12,  0x80,  0x16,  0x81,  0x16,  0x82,  0x19,  0x83,  0x14, 	/* 00240 */
+	0x84,  0x10,  0x85,  0x14,  0x86,  0x18,  0x87,  0x19,  0x88,  0x1E,  0x89,  0x15,  0x8A,  0x12,  0x8B,  0x17, 	/* 00250 */
+	0x8C,  0x16,  0x8D,  0x0D,  0x8E,  0x12,  0x8F,  0x15,  0x90,  0x12,  0x91,  0x14,  0x92,  0x10,  0x93,  0x11, 	/* 00260 */
+	0x94,  0x10,  0x95,  0x13,  0x96,  0x17,  0x97,  0x11,  0x98,  0x0E,  0x99,  0x0E,  0x9A,  0x0D,  0x9B,  0x16, 	/* 00270 */
+	0x9C,  0x13,  0x9D,  0x13,  0x9E,  0x0A,  0x9F,  0x0F,  0xA0,  0x0F,  0xA1,  0x19,  0xA2,  0x14,  0xA3,  0x17, 	/* 00280 */
+	0xA4,  0x10,  0xA5,  0x13,  0xA6,  0x19,  0xA7,  0x0A,  0xA8,  0x1A,  0xA9,  0x18,  0xAA,  0x1B,  0xAB,  0x1C, 	/* 00290 */
+	0xAC,  0x18,  0xAD,  0x15,  0xAE,  0x0B,  0xB0,  0x03,  0xB1,  0x12,  0xB2,  0x22,  0xB3,  0x1B,  0xB4,  0x0C, 	/* 002A0 */
+	0xB5,  0x0A,  0xB6,  0x09,  0xB7,  0x13,  0xB8,  0x0C,  0xB9,  0x12,  0xBA,  0x13,  0xBB,  0x12,  0xBC,  0x18, 	/* 002B0 */
+	0xBD,  0x0F,  0xBE,  0x12,  0xBF,  0x16,  0x80,  0x23,  0x81,  0x27,  0x82,  0x12,  0x83,  0x0C,  0x84,  0x06, 	/* 002C0 */
+	0x85,  0x15,  0x86,  0x12,  0x87,  0x1B,  0x88,  0x0B,  0x89,  0x0F,  0x8A,  0x0E,  0x8B,  0x0B,  0x8C,  0x13, 	/* 002D0 */
+	0x8D,  0x0D,  0x8E,  0x0B,  0x8F,  0x0C,  0x90,  0x0E,  0x91,  0x12,  0x92,  0x01,  0x95,  0x01,  0x96,  0x1B, 	/* 002E0 */
+	0x97,  0x0D,  0x98,  0x09,  0x99,  0x1D,  0x9A,  0x1E,  0x9B,  0x1C,  0x9C,  0x18,  0x9D,  0x18,  0x9E,  0x12, 	/* 002F0 */
+	0x9F,  0x0E,  0xA0,  0x19,  0xA1,  0x12,  0xA2,  0x05,  0xA3,  0x11,  0xA4,  0x14,  0xA5,  0x0A,  0xA6,  0x0C, 	/* 00300 */
+	0xA7,  0x15,  0xA8,  0x0C,  0xA9,  0x10,  0xAA,  0x05,  0xAB,  0x15,  0xAC,  0x11,  0xAD,  0x0E,  0xAE,  0x10, 	/* 00310 */
+	0xAF,  0x13,  0xB0,  0x19,  0xB1,  0x0A,  0xB3,  0x09,  0xB4,  0x13,  0xB5,  0x11,  0xB6,  0x0D,  0xB7,  0x0F, 	/* 00320 */
+	0xB8,  0x03,  0xB9,  0x05,  0xBA,  0x17,  0xBB,  0x19,  0xBC,  0x0A,  0xBD,  0x12,  0xBE,  0x05,  0xBC,  0x3D, 	/* 00330 */
+	0xBD,  0x1F,  0xBF,  0x05,  0xA7,  0x0E,  0x01,  0x10,  0x18,  0x00,  0xC0,  0x0E,  0x01,  0x30,  0x19,  0x00, 	/* 00340 */
+	0xE0,  0x06,  0x00,  0x30,  0x11,  0x00,  0xE0,  0xA8,  0x19,  0x81,  0x98,  0x00,  0x00,  0x00,  0x00,  0x00, 	/* 00350 */
+	0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0xB0,  0x00,  0x03,  0x00,  0x48,  0x04, 	/* 00360 */
+	0x80,  0x30,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0xB1,  0x00,  0x00, 	/* 00370 */
+	0x40,  0x04,  0x00,  0x40,  0x04,  0x07,  0xFC,  0x04,  0x00,  0x40,  0x04,  0x00,  0x00,  0x7F,  0xC0,  0x00, 	/* 00380 */
+	0xB4,  0x02,  0x00,  0x40,  0x08,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00, 	/* 00390 */
+	0x00,  0x00,  0x00,  0xB6,  0x0F,  0x01,  0xD0,  0x1D,  0x01,  0xD0,  0x0D,  0x00,  0x50,  0x05,  0x00,  0x50, 	/* 003A0 */
+	0x05,  0x00,  0x50,  0x05,  0x00,  0x00,  0x97,  0x00,  0x00,  0x00,  0x20,  0x41,  0x08,  0x09,  0x00,  0x60, 	/* 003B0 */
+	0x06,  0x00,  0x90,  0x10,  0x82,  0x04,  0x00,  0x00,  0x00,  0xB7,  0x00,  0x00,  0x00,  0x0C,  0x00,  0xC0, 	/* 003C0 */
+	0x00,  0x00,  0x00,  0x7F,  0xC0,  0x00,  0x00,  0x00,  0xC0,  0x0C,  0x00,  0x00,  0x91,  0x00,  0x00,  0x40, 	/* 003D0 */
+	0x04,  0x00,  0xA0,  0x0A,  0x01,  0x10,  0x11,  0x01,  0xF0,  0x20,  0x82,  0x08,  0x71,  0xC0,  0x00,  0x92, 	/* 003E0 */
+	0x00,  0x03,  0xE0,  0x11,  0x01,  0x08,  0x11,  0x01,  0xE0,  0x11,  0x01,  0x08,  0x10,  0x81,  0x10,  0x3E, 	/* 003F0 */
+	0x00,  0x00,  0x93,  0x00,  0x03,  0xF0,  0x11,  0x01,  0x08,  0x10,  0x01,  0x00,  0x10,  0x01,  0x00,  0x10, 	/* 00400 */
+	0x01,  0x00,  0x38,  0x00,  0x00,  0x94,  0x00,  0x00,  0x40,  0x04,  0x00,  0x40,  0x0A,  0x00,  0xA0,  0x11, 	/* 00410 */
+	0x01,  0x10,  0x20,  0x82,  0x08,  0x7F,  0xC0,  0x00,  0x95,  0x00,  0x03,  0xF8,  0x10,  0x41,  0x00,  0x11, 	/* 00420 */
+	0x01,  0xF0,  0x11,  0x01,  0x00,  0x10,  0x41,  0x04,  0x3F,  0x80,  0x00,  0x96,  0x00,  0x03,  0xFC,  0x20, 	/* 00430 */
+	0x84,  0x10,  0x02,  0x00,  0x40,  0x04,  0x00,  0x80,  0x10,  0x42,  0x04,  0x7F,  0xC0,  0x00,  0x97,  0x00, 	/* 00440 */
+	0x07,  0x1C,  0x20,  0x82,  0x08,  0x20,  0x83,  0xF8,  0x20,  0x82,  0x08,  0x20,  0x82,  0x08,  0x71,  0xC0, 	/* 00450 */
+	0x00,  0x98,  0x00,  0x00,  0xE0,  0x11,  0x02,  0x08,  0x51,  0x45,  0xF4,  0x51,  0x44,  0x04,  0x20,  0x81, 	/* 00460 */
+	0x10,  0x0E,  0x00,  0x00,  0x99,  0x00,  0x00,  0xE0,  0x04,  0x00,  0x40,  0x04,  0x00,  0x40,  0x04,  0x00, 	/* 00470 */
+	0x40,  0x04,  0x00,  0x40,  0x0E,  0x00,  0x00,  0x9A,  0x00,  0x03,  0xB8,  0x11,  0x01,  0x20,  0x14,  0x01, 	/* 00480 */
+	0x80,  0x14,  0x01,  0x20,  0x11,  0x01,  0x08,  0x39,  0xC0,  0x00,  0x9B,  0x00,  0x00,  0x40,  0x04,  0x00, 	/* 00490 */
+	0xA0,  0x0A,  0x01,  0x10,  0x11,  0x01,  0x10,  0x20,  0x82,  0x08,  0x71,  0xC0,  0x00,  0x9C,  0x00,  0x0C, 	/* 004A0 */
+	0x06,  0x40,  0x46,  0x0C,  0x60,  0xC5,  0x14,  0x51,  0x44,  0xA4,  0x4A,  0x44,  0x44,  0xE4,  0xE0,  0x00, 	/* 004B0 */
+	0x9D,  0x00,  0x03,  0x1C,  0x18,  0x81,  0x48,  0x14,  0x81,  0x28,  0x12,  0x81,  0x18,  0x11,  0x81,  0x08, 	/* 004C0 */
+	0x38,  0x80,  0x00,  0x9E,  0x00,  0x03,  0xFC,  0x20,  0x40,  0x00,  0x10,  0x81,  0xF8,  0x10,  0x80,  0x00, 	/* 004D0 */
+	0x00,  0x02,  0x04,  0x3F,  0xC0,  0x00,  0x9F,  0x00,  0x00,  0xE0,  0x11,  0x02,  0x08,  0x40,  0x44,  0x04, 	/* 004E0 */
+	0x40,  0x44,  0x04,  0x20,  0x81,  0x10,  0x0E,  0x00,  0x00,  0xA0,  0x00,  0x07,  0xFC,  0x20,  0x82,  0x08, 	/* 004F0 */
+	0x20,  0x82,  0x08,  0x20,  0x82,  0x08,  0x20,  0x82,  0x08,  0x71,  0xC0,  0x00,  0xA1,  0x00,  0x03,  0xE0, 	/* 00500 */
+	0x11,  0x01,  0x08,  0x10,  0x81,  0x10,  0x1E,  0x01,  0x00,  0x10,  0x01,  0x00,  0x38,  0x00,  0x00,  0xA3, 	/* 00510 */
+	0x00,  0x07,  0xF0,  0x21,  0x01,  0x08,  0x08,  0x00,  0x40,  0x04,  0x00,  0x80,  0x10,  0x42,  0x04,  0x7F, 	/* 00520 */
+	0x80,  0x00,  0xA4,  0x00,  0x07,  0xFC,  0x44,  0x44,  0x44,  0x04,  0x00,  0x40,  0x04,  0x00,  0x40,  0x04, 	/* 00530 */
+	0x00,  0x40,  0x0E,  0x00,  0x00,  0xA5,  0x00,  0x03,  0xB8,  0x44,  0x44,  0x44,  0x04,  0x00,  0x40,  0x04, 	/* 00540 */
+	0x00,  0x40,  0x04,  0x00,  0x40,  0x0E,  0x00,  0x00,  0xA6,  0x00,  0x00,  0xE0,  0x04,  0x01,  0xF0,  0x24, 	/* 00550 */
+	0x82,  0x48,  0x24,  0x81,  0xF0,  0x04,  0x00,  0x40,  0x0E,  0x00,  0x00,  0xA7,  0x00,  0x07,  0x1C,  0x20, 	/* 00560 */
+	0x81,  0x10,  0x0A,  0x00,  0x40,  0x04,  0x00,  0xA0,  0x11,  0x02,  0x08,  0x71,  0xC0,  0x00,  0xA8,  0x00, 	/* 00570 */
+	0x00,  0xE0,  0x44,  0x42,  0x48,  0x24,  0x82,  0x48,  0x15,  0x00,  0xE0,  0x04,  0x00,  0x40,  0x0E,  0x00, 	/* 00580 */
+	0x00,  0xA9,  0x00,  0x00,  0xE0,  0x11,  0x02,  0x08,  0x20,  0x82,  0x08,  0x20,  0x81,  0x10,  0x4A,  0x44, 	/* 00590 */
+	0xA4,  0x7B,  0xC0,  0x00,  0xB1,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x0C,  0x81,  0x28,  0x23,  0x02, 	/* 005A0 */
+	0x20,  0x24,  0x02,  0x60,  0x19,  0x80,  0x00,  0xB2,  0x00,  0x00,  0x30,  0x04,  0x80,  0x48,  0x09,  0x00, 	/* 005B0 */
+	0xA0,  0x11,  0x01,  0x10,  0x32,  0x02,  0xC0,  0x40,  0x04,  0x00,  0xB3,  0x00,  0x00,  0x00,  0x00,  0x01, 	/* 005C0 */
+	0x8C,  0x25,  0x00,  0x20,  0x04,  0x00,  0x40,  0x08,  0x00,  0x80,  0x10,  0x00,  0x00,  0xB4,  0x00,  0x00, 	/* 005D0 */
+	0x60,  0x09,  0x80,  0x40,  0x02,  0x00,  0x60,  0x09,  0x01,  0x10,  0x21,  0x02,  0x20,  0x1C,  0x00,  0x00, 	/* 005E0 */
+	0xB5,  0x00,  0x00,  0x00,  0x00,  0x00,  0xE0,  0x11,  0x01,  0x00,  0x0C,  0x01,  0x00,  0x21,  0x02,  0x20, 	/* 005F0 */
+	0x1C,  0x00,  0x00,  0xB6,  0x00,  0x00,  0x80,  0x09,  0x80,  0x70,  0x04,  0x00,  0x80,  0x10,  0x01,  0x00, 	/* 00600 */
+	0x10,  0x00,  0xC0,  0x22,  0x01,  0xC0,  0xB7,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x13,  0x02,  0xC8, 	/* 00610 */
+	0x08,  0x81,  0x10,  0x11,  0x02,  0x20,  0x02,  0x00,  0x20,  0xB8,  0x00,  0x00,  0x30,  0x04,  0x80,  0x88, 	/* 00620 */
+	0x10,  0x81,  0xF8,  0x21,  0x02,  0x10,  0x22,  0x02,  0x40,  0x18,  0x00,  0x00,  0xB9,  0x00,  0x00,  0x00, 	/* 00630 */
+	0x00,  0x00,  0x20,  0x04,  0x00,  0x80,  0x08,  0x01,  0x00,  0x10,  0x81,  0x30,  0x0C,  0x00,  0x00,  0xBA, 	/* 00640 */
+	0x00,  0x00,  0x00,  0x00,  0x01,  0x08,  0x09,  0x00,  0xA0,  0x1C,  0x01,  0x40,  0x24,  0x82,  0x48,  0x43, 	/* 00650 */
+	0x00,  0x00,  0xBB,  0x00,  0x00,  0x00,  0x0C,  0x00,  0x20,  0x02,  0x00,  0x20,  0x06,  0x00,  0xA0,  0x11, 	/* 00660 */
+	0x02,  0x10,  0x20,  0xC0,  0x00,  0xBC,  0x00,  0x00,  0x00,  0x00,  0x00,  0x88,  0x08,  0x81,  0x08,  0x11, 	/* 00670 */
+	0x02,  0x10,  0x33,  0x02,  0xCC,  0x40,  0x04,  0x00,  0xBD,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x10, 	/* 00680 */
+	0x80,  0x88,  0x09,  0x01,  0x10,  0x12,  0x01,  0x40,  0x38,  0x00,  0x00,  0xBE,  0x00,  0x00,  0x40,  0x03, 	/* 00690 */
+	0x80,  0x40,  0x08,  0x00,  0x60,  0x08,  0x01,  0x00,  0x0E,  0x00,  0x10,  0x11,  0x00,  0xE0,  0xBF,  0x00, 	/* 006A0 */
+	0x00,  0x00,  0x00,  0x00,  0x00,  0x0E,  0x01,  0x10,  0x21,  0x02,  0x10,  0x21,  0x02,  0x20,  0x1C,  0x00, 	/* 006B0 */
+	0x00,  0x80,  0x00,  0x00,  0x00,  0x00,  0x00,  0x04,  0x1F,  0x82,  0x90,  0x0A,  0x01,  0x20,  0x14,  0x02, 	/* 006C0 */
+	0x48,  0x43,  0x00,  0x00,  0x81,  0x00,  0x00,  0x00,  0x00,  0x00,  0x70,  0x08,  0x81,  0x08,  0x10,  0x81, 	/* 006D0 */
+	0x90,  0x16,  0x02,  0x00,  0x20,  0x02,  0x00,  0x83,  0x00,  0x00,  0x00,  0x00,  0x00,  0x04,  0x07,  0x81, 	/* 006E0 */
+	0xA0,  0x21,  0x02,  0x10,  0x21,  0x01,  0x20,  0x0C,  0x00,  0x00,  0x84,  0x00,  0x00,  0x00,  0x00,  0x81, 	/* 006F0 */
+	0xF0,  0x24,  0x00,  0x40,  0x08,  0x00,  0x80,  0x10,  0x01,  0x20,  0x0C,  0x00,  0x00,  0x85,  0x00,  0x00, 	/* 00700 */
+	0x00,  0x00,  0x00,  0x00,  0x21,  0x05,  0x08,  0x10,  0x81,  0x10,  0x21,  0x02,  0x60,  0x18,  0x00,  0x00, 	/* 00710 */
+	0x86,  0x00,  0x00,  0x10,  0x01,  0x00,  0x20,  0x0F,  0x01,  0x28,  0x22,  0x42,  0x44,  0x24,  0x81,  0xF0, 	/* 00720 */
+	0x08,  0x00,  0x80,  0x87,  0x00,  0x00,  0x00,  0x00,  0x81,  0x08,  0x29,  0x02,  0x60,  0x04,  0x00,  0xC0, 	/* 00730 */
+	0x14,  0x02,  0x28,  0x21,  0x00,  0x00,  0x88,  0x00,  0x00,  0x10,  0x01,  0x02,  0x28,  0x12,  0x41,  0x24, 	/* 00740 */
+	0x24,  0x42,  0x48,  0x1F,  0x00,  0x80,  0x08,  0x00,  0x80,  0x89,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00, 	/* 00750 */
+	0x10,  0x82,  0x04,  0x20,  0x44,  0x44,  0x44,  0x44,  0xC8,  0x33,  0x00,  0x00,  0x81,  0x19,  0x80,  0x00, 	/* 00760 */
+	0x3F,  0x81,  0x04,  0x10,  0x01,  0x10,  0x1F,  0x01,  0x10,  0x10,  0x41,  0x04,  0x3F,  0x80,  0x00,  0x90, 	/* 00770 */
+	0x00,  0x00,  0x40,  0x04,  0x00,  0xA0,  0x0A,  0x01,  0x10,  0x11,  0x01,  0xF0,  0x20,  0x82,  0x08,  0x71, 	/* 00780 */
+	0xC0,  0x00,  0x91,  0x00,  0x03,  0xF8,  0x10,  0x81,  0x00,  0x10,  0x01,  0xE0,  0x11,  0x01,  0x08,  0x10, 	/* 00790 */
+	0x81,  0x10,  0x3E,  0x00,  0x00,  0x92,  0x00,  0x03,  0xE0,  0x11,  0x01,  0x08,  0x11,  0x01,  0xE0,  0x11, 	/* 007A0 */
+	0x01,  0x08,  0x10,  0x81,  0x10,  0x3E,  0x00,  0x00,  0x93,  0x00,  0x03,  0xF0,  0x11,  0x01,  0x08,  0x10, 	/* 007B0 */
+	0x01,  0x00,  0x10,  0x01,  0x00,  0x10,  0x01,  0x00,  0x38,  0x00,  0x00,  0x94,  0x00,  0x01,  0xFC,  0x09, 	/* 007C0 */
+	0x00,  0x90,  0x09,  0x00,  0x90,  0x09,  0x01,  0x10,  0x11,  0x02,  0x10,  0x7F,  0xC4,  0x04,  0x95,  0x00, 	/* 007D0 */
+	0x03,  0xF8,  0x10,  0x41,  0x00,  0x11,  0x01,  0xF0,  0x11,  0x01,  0x00,  0x10,  0x41,  0x04,  0x3F,  0x80, 	/* 007E0 */
+	0x00,  0x96,  0x00,  0x04,  0xE4,  0x24,  0x82,  0x48,  0x15,  0x00,  0xE0,  0x15,  0x02,  0x50,  0x24,  0x82, 	/* 007F0 */
+	0x48,  0x6E,  0xC0,  0x00,  0x97,  0x00,  0x00,  0xE0,  0x11,  0x02,  0x10,  0x01,  0x00,  0x60,  0x01,  0x00, 	/* 00800 */
+	0x08,  0x20,  0x83,  0x10,  0x2E,  0x00,  0x00,  0x98,  0x00,  0x03,  0x8C,  0x11,  0x81,  0x28,  0x12,  0x81, 	/* 00810 */
+	0x48,  0x14,  0x81,  0x88,  0x18,  0x81,  0x08,  0x39,  0xC0,  0x00,  0x99,  0x09,  0x00,  0x60,  0x38,  0xC1, 	/* 00820 */
+	0x18,  0x12,  0x81,  0x28,  0x14,  0x81,  0x88,  0x18,  0x81,  0x08,  0x39,  0xC0,  0x00,  0x9A,  0x00,  0x03, 	/* 00830 */
+	0x88,  0x11,  0x41,  0x20,  0x14,  0x01,  0x80,  0x14,  0x01,  0x20,  0x11,  0x01,  0x08,  0x39,  0xC0,  0x00, 	/* 00840 */
+	0x9B,  0x00,  0x01,  0xFC,  0x04,  0x80,  0x48,  0x04,  0x80,  0x48,  0x08,  0x80,  0x88,  0x08,  0x85,  0x08, 	/* 00850 */
+	0x21,  0xC0,  0x00,  0x9C,  0x00,  0x06,  0x0C,  0x20,  0x83,  0x18,  0x31,  0x82,  0xA8,  0x2A,  0x84,  0x44, 	/* 00860 */
+	0x44,  0x44,  0x44,  0xE0,  0xE0,  0x00,  0x9D,  0x00,  0x07,  0x1C,  0x20,  0x82,  0x08,  0x20,  0x83,  0xF8, 	/* 00870 */
+	0x20,  0x82,  0x08,  0x20,  0x82,  0x08,  0x71,  0xC0,  0x00,  0x9E,  0x00,  0x00,  0xE0,  0x11,  0x02,  0x08, 	/* 00880 */
+	0x40,  0x44,  0x04,  0x40,  0x44,  0x04,  0x20,  0x81,  0x10,  0x0E,  0x00,  0x00,  0x9F,  0x00,  0x07,  0xF8, 	/* 00890 */
+	0x21,  0x02,  0x10,  0x21,  0x02,  0x10,  0x21,  0x02,  0x10,  0x21,  0x02,  0x10,  0x73,  0x80,  0x00,  0xA0, 	/* 008A0 */
+	0x00,  0x03,  0xE0,  0x11,  0x01,  0x08,  0x10,  0x81,  0x10,  0x1E,  0x01,  0x00,  0x10,  0x01,  0x00,  0x38, 	/* 008B0 */
+	0x00,  0x00,  0xA1,  0x00,  0x00,  0x74,  0x08,  0xC1,  0x04,  0x20,  0x02,  0x00,  0x20,  0x02,  0x00,  0x10, 	/* 008C0 */
+	0x40,  0x88,  0x07,  0x00,  0x00,  0xA2,  0x00,  0x07,  0xFC,  0x44,  0x44,  0x44,  0x04,  0x00,  0x40,  0x04, 	/* 008D0 */
+	0x00,  0x40,  0x04,  0x00,  0x40,  0x0E,  0x00,  0x00,  0xA3,  0x00,  0x07,  0x1C,  0x20,  0x81,  0x10,  0x11, 	/* 008E0 */
+	0x00,  0xA0,  0x0A,  0x00,  0x40,  0x04,  0x02,  0x40,  0x18,  0x00,  0x00,  0xA4,  0x00,  0x00,  0xE0,  0x04, 	/* 008F0 */
+	0x01,  0xF0,  0x24,  0x84,  0x44,  0x44,  0x42,  0x48,  0x1F,  0x00,  0x40,  0x0E,  0x00,  0x00,  0xA5,  0x00, 	/* 00900 */
+	0x07,  0x1C,  0x20,  0x81,  0x10,  0x0A,  0x00,  0x40,  0x04,  0x00,  0xA0,  0x11,  0x02,  0x08,  0x71,  0xC0, 	/* 00910 */
+	0x00,  0xA6,  0x00,  0x07,  0x38,  0x21,  0x02,  0x10,  0x21,  0x02,  0x10,  0x21,  0x02,  0x10,  0x21,  0x02, 	/* 00920 */
+	0x10,  0x7F,  0xC0,  0x04,  0xA7,  0x00,  0x07,  0x38,  0x21,  0x02,  0x10,  0x21,  0x02,  0x10,  0x13,  0x00, 	/* 00930 */
+	0xD0,  0x01,  0x00,  0x10,  0x03,  0x80,  0x00,  0xA8,  0x00,  0x0E,  0xEE,  0x44,  0x44,  0x44,  0x44,  0x44, 	/* 00940 */
+	0x44,  0x44,  0x44,  0x44,  0x44,  0x44,  0x44,  0xFF,  0xE0,  0x00,  0xA9,  0x00,  0x0E,  0xEE,  0x44,  0x44, 	/* 00950 */
+	0x44,  0x44,  0x44,  0x44,  0x44,  0x44,  0x44,  0x44,  0x44,  0x44,  0xFF,  0xF0,  0x01,  0xAA,  0x00,  0x03, 	/* 00960 */
+	0x80,  0x48,  0x00,  0x80,  0x08,  0x00,  0xF0,  0x08,  0x80,  0x84,  0x08,  0x40,  0x88,  0x1F,  0x00,  0x00, 	/* 00970 */
+	0xAB,  0x00,  0x06,  0x1C,  0x20,  0x82,  0x08,  0x20,  0x83,  0x88,  0x24,  0x82,  0x28,  0x22,  0x82,  0x48, 	/* 00980 */
+	0x79,  0xC0,  0x00,  0xAC,  0x00,  0x03,  0x00,  0x10,  0x01,  0x00,  0x1E,  0x01,  0x10,  0x10,  0x81,  0x08, 	/* 00990 */
+	0x10,  0x81,  0x10,  0x1E,  0x00,  0x00,  0xAD,  0x00,  0x02,  0xE0,  0x31,  0x02,  0x08,  0x00,  0x80,  0xC8, 	/* 009A0 */
+	0x13,  0x80,  0x08,  0x20,  0x81,  0x10,  0x0E,  0x00,  0x00,  0xAE,  0x00,  0x0E,  0x30,  0x44,  0x84,  0x84, 	/* 009B0 */
+	0x48,  0x47,  0x84,  0x48,  0x44,  0x84,  0x48,  0x44,  0x48,  0xE3,  0x00,  0x00,  0xAF,  0x00,  0x00,  0xFC, 	/* 009C0 */
+	0x10,  0x82,  0x08,  0x10,  0x80,  0xF8,  0x02,  0x80,  0x48,  0x08,  0x81,  0x08,  0x71,  0xC0,  0x00,  0xB0, 	/* 009D0 */
+	0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x06,  0x00,  0x90,  0x07,  0x00,  0x90,  0x11,  0x01,  0x20,  0x0D, 	/* 009E0 */
+	0x80,  0x00,  0xB1,  0x00,  0x00,  0x30,  0x0C,  0x01,  0x00,  0x20,  0x02,  0xC0,  0x32,  0x02,  0x10,  0x21, 	/* 009F0 */
+	0x01,  0x20,  0x0C,  0x00,  0x00,  0xB2,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x3E,  0x01,  0x10,  0x11, 	/* 00A00 */
+	0x01,  0xE0,  0x11,  0x01,  0x10,  0x3E,  0x00,  0x00,  0xB3,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x3E, 	/* 00A10 */
+	0x01,  0x10,  0x10,  0x01,  0x00,  0x10,  0x01,  0x00,  0x38,  0x00,  0x00,  0xB4,  0x00,  0x00,  0x00,  0x00, 	/* 00A20 */
+	0x00,  0x00,  0x1F,  0x80,  0x90,  0x09,  0x00,  0x90,  0x11,  0x01,  0x10,  0x7F,  0x84,  0x08,  0xB5,  0x00, 	/* 00A30 */
+	0x00,  0x00,  0x00,  0x00,  0x00,  0x0C,  0x01,  0x20,  0x21,  0x03,  0xF0,  0x20,  0x01,  0x10,  0x0E,  0x00, 	/* 00A40 */
+	0x00,  0xB6,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x6E,  0xC1,  0x50,  0x15,  0x00,  0xE0,  0x15,  0x02, 	/* 00A50 */
+	0x48,  0x6E,  0xC0,  0x00,  0xB7,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x07,  0x01,  0x88,  0x00,  0x80, 	/* 00A60 */
+	0x70,  0x00,  0x81,  0x08,  0x0F,  0x00,  0x00,  0xB8,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x39,  0xC1, 	/* 00A70 */
+	0x18,  0x12,  0x81,  0x48,  0x18,  0x81,  0x08,  0x39,  0xC0,  0x00,  0xB9,  0x00,  0x00,  0x90,  0x06,  0x00, 	/* 00A80 */
+	0x00,  0x39,  0xC1,  0x18,  0x12,  0x81,  0x48,  0x18,  0x81,  0x08,  0x39,  0xC0,  0x00,  0xBA,  0x00,  0x00, 	/* 00A90 */
+	0x00,  0x00,  0x00,  0x00,  0x39,  0x01,  0x28,  0x14,  0x01,  0x80,  0x14,  0x01,  0x20,  0x39,  0x80,  0x00, 	/* 00AA0 */
+	0xBB,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x1F,  0x00,  0xA0,  0x0A,  0x00,  0xA0,  0x12,  0x05,  0x20, 	/* 00AB0 */
+	0x27,  0x00,  0x00,  0xBC,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x60,  0xC3,  0x18,  0x31,  0x82,  0xA8, 	/* 00AC0 */
+	0x2A,  0x82,  0x48,  0x75,  0xC0,  0x00,  0xBD,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x3B,  0x81,  0x10, 	/* 00AD0 */
+	0x11,  0x01,  0xF0,  0x11,  0x01,  0x10,  0x3B,  0x80,  0x00,  0xBE,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00, 	/* 00AE0 */
+	0x0E,  0x01,  0x10,  0x20,  0x82,  0x08,  0x20,  0x81,  0x10,  0x0E,  0x00,  0x00,  0xBF,  0x00,  0x00,  0x00, 	/* 00AF0 */
+	0x00,  0x00,  0x00,  0x3F,  0x81,  0x10,  0x11,  0x01,  0x10,  0x11,  0x01,  0x10,  0x3B,  0x80,  0x00,  0x80, 	/* 00B00 */
+	0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x36,  0x01,  0x90,  0x10,  0x81,  0x08,  0x19,  0x01,  0x60,  0x10, 	/* 00B10 */
+	0x03,  0x80,  0x81,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x0E,  0x01,  0x10,  0x20,  0x02,  0x00,  0x20, 	/* 00B20 */
+	0x01,  0x10,  0x0E,  0x00,  0x00,  0x82,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x3F,  0x82,  0x48,  0x04, 	/* 00B30 */
+	0x00,  0x40,  0x04,  0x00,  0x40,  0x0E,  0x00,  0x00,  0x83,  0x00,  0x00,  0x00,  0x00,  0x03,  0x9C,  0x10, 	/* 00B40 */
+	0x80,  0x88,  0x05,  0x00,  0x30,  0x02,  0x00,  0x40,  0x24,  0x01,  0x80,  0x84,  0x00,  0x00,  0xE0,  0x04, 	/* 00B50 */
+	0x01,  0x50,  0x2E,  0x84,  0x44,  0x44,  0x44,  0x44,  0x2E,  0x81,  0x50,  0x04,  0x00,  0xE0,  0x85,  0x00, 	/* 00B60 */
+	0x00,  0x00,  0x00,  0x00,  0x00,  0x3B,  0x81,  0x10,  0x0A,  0x00,  0x40,  0x0A,  0x01,  0x10,  0x3B,  0x80, 	/* 00B70 */
+	0x00,  0x86,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x3B,  0x81,  0x10,  0x11,  0x01,  0x10,  0x11,  0x01, 	/* 00B80 */
+	0x10,  0x3F,  0x80,  0x08,  0x87,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x3B,  0x81,  0x10,  0x11,  0x00, 	/* 00B90 */
+	0xF0,  0x01,  0x00,  0x10,  0x03,  0x80,  0x00,  0x88,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x24,  0x82, 	/* 00BA0 */
+	0x48,  0x24,  0x82,  0x48,  0x24,  0x82,  0x48,  0x3F,  0x80,  0x00,  0x89,  0x00,  0x00,  0x00,  0x00,  0x00, 	/* 00BB0 */
+	0x00,  0x49,  0x04,  0x90,  0x49,  0x04,  0x90,  0x49,  0x04,  0x90,  0x7F,  0xC0,  0x04,  0x8A,  0x00,  0x00, 	/* 00BC0 */
+	0x00,  0x00,  0x00,  0x00,  0x30,  0x05,  0x00,  0x1E,  0x01,  0x10,  0x11,  0x01,  0x10,  0x3E,  0x00,  0x00, 	/* 00BD0 */
+	0x8B,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x73,  0x82,  0x10,  0x21,  0x03,  0x90,  0x25,  0x02,  0x50, 	/* 00BE0 */
+	0x7B,  0x80,  0x00,  0x8C,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x38,  0x01,  0x00,  0x1E,  0x01,  0x10, 	/* 00BF0 */
+	0x11,  0x01,  0x10,  0x3E,  0x00,  0x00,  0x8D,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x1E,  0x02,  0x10, 	/* 00C00 */
+	0x0B,  0x01,  0x50,  0x01,  0x02,  0x10,  0x1E,  0x00,  0x00,  0x8E,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00, 	/* 00C10 */
+	0x73,  0x02,  0x48,  0x28,  0x43,  0x84,  0x28,  0x42,  0x48,  0x73,  0x00,  0x00,  0x8F,  0x00,  0x00,  0x00, 	/* 00C20 */
+	0x00,  0x00,  0x00,  0x0F,  0x81,  0x10,  0x11,  0x00,  0xF0,  0x09,  0x01,  0x10,  0x3B,  0x80,  0x00,  0x91, 	/* 00C30 */
+	0x00,  0x00,  0x00,  0x12,  0x00,  0x00,  0x0C,  0x01,  0x20,  0x21,  0x03,  0xF0,  0x20,  0x01,  0x10,  0x0E, 	/* 00C40 */
+	0x00,  0x00,  0x90,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x0F,  0x00,  0x00,  0x00, 	/* 00C50 */
+	0x00,  0x00,  0x00,  0x00,  0x00,  0x95,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0xFF, 	/* 00C60 */
+	0xF0,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x98,  0x00,  0x20,  0x04,  0x00,  0x40,  0x06,  0x00, 	/* 00C70 */
+	0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x99,  0x30,  0x01,  0x00,  0x10, 	/* 00C80 */
+	0x02,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x9C,  0x01, 	/* 00C90 */
+	0x20,  0x24,  0x02,  0x40,  0x36,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00, 	/* 00CA0 */
+	0x00,  0x9D,  0x6C,  0x02,  0x40,  0x24,  0x04,  0x80,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00, 	/* 00CB0 */
+	0x00,  0x00,  0x00,  0x00,  0xA0,  0x04,  0x00,  0xE0,  0x24,  0x87,  0xFC,  0x24,  0x80,  0xE0,  0x0E,  0x00, 	/* 00CC0 */
+	0x40,  0x04,  0x00,  0x40,  0x04,  0x00,  0x40,  0xA1,  0x0E,  0x00,  0xE0,  0x24,  0x87,  0xFC,  0x24,  0x80, 	/* 00CD0 */
+	0x40,  0x04,  0x02,  0x48,  0x7F,  0xC2,  0x48,  0x0E,  0x00,  0xE0,  0xA5,  0x00,  0x00,  0x00,  0x00,  0x00, 	/* 00CE0 */
+	0x00,  0x00,  0x02,  0x08,  0x20,  0x80,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0xA6,  0x00,  0x00, 	/* 00CF0 */
+	0x00,  0x00,  0x00,  0x00,  0x00,  0x04,  0x44,  0x44,  0x40,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00, 	/* 00D00 */
+	0xB0,  0x31,  0x04,  0x90,  0x4A,  0x04,  0xC0,  0x34,  0x00,  0x80,  0x10,  0x01,  0x44,  0x2A,  0xA4,  0xAA, 	/* 00D10 */
+	0x44,  0x40,  0x00,  0xB2,  0x18,  0x00,  0x80,  0x08,  0x01,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00, 	/* 00D20 */
+	0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0xB3,  0x36,  0x01,  0x20,  0x12,  0x02,  0x40,  0x00,  0x00,  0x00, 	/* 00D30 */
+	0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0xBB,  0x00,  0x04,  0x62,  0x26,  0x41,  0x08, 	/* 00D40 */
+	0x09,  0x06,  0x66,  0x66,  0x60,  0x90,  0x10,  0x82,  0x64,  0x46,  0x20,  0x00,  0x83,  0x00,  0x02,  0x34, 	/* 00D50 */
+	0x54,  0xC2,  0x84,  0x10,  0x01,  0x00,  0x10,  0x01,  0x00,  0x10,  0x40,  0x88,  0x07,  0x00,  0x00,  0xAB, 	/* 00D60 */
+	0x04,  0x00,  0xA0,  0x0A,  0x00,  0x40,  0x0A,  0x00,  0xA0,  0x11,  0x01,  0xF0,  0x20,  0x82,  0x08,  0x71, 	/* 00D70 */
+	0xC0,  0x00,  0x90,  0x00,  0x00,  0x00,  0x00,  0x00,  0xC0,  0x30,  0x0F,  0xFF,  0x30,  0x00,  0xC0,  0x00, 	/* 00D80 */
+	0x00,  0x00,  0x00,  0x00,  0x00,  0x91,  0x02,  0x00,  0x20,  0x07,  0x00,  0x70,  0x0A,  0x80,  0xA8,  0x02, 	/* 00D90 */
+	0x00,  0x20,  0x02,  0x00,  0x20,  0x02,  0x00,  0x20,  0x92,  0x00,  0x00,  0x00,  0x00,  0x00,  0x30,  0x00, 	/* 00DA0 */
+	0xCF,  0xFF,  0x00,  0xC0,  0x30,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x93,  0x02,  0x00,  0x20,  0x02, 	/* 00DB0 */
+	0x00,  0x20,  0x02,  0x00,  0x20,  0x0A,  0x80,  0xA8,  0x07,  0x00,  0x70,  0x02,  0x00,  0x20,  0x92,  0x00, 	/* 00DC0 */
+	0x00,  0x00,  0x00,  0x80,  0x04,  0xFF,  0xE0,  0x01,  0xFF,  0xE0,  0x04,  0x00,  0x80,  0x00,  0x00,  0x00, 	/* 00DD0 */
+	0x00,  0x94,  0x00,  0x00,  0x00,  0x10,  0x82,  0x04,  0x7F,  0xE8,  0x01,  0x7F,  0xE2,  0x04,  0x10,  0x80, 	/* 00DE0 */
+	0x00,  0x00,  0x00,  0x00,  0x80,  0x00,  0x04,  0x04,  0x40,  0x42,  0x08,  0x3F,  0x81,  0x10,  0x11,  0x00, 	/* 00DF0 */
+	0xA0,  0x0A,  0x00,  0x40,  0x04,  0x00,  0x00,  0x82,  0x00,  0x00,  0x70,  0x08,  0x80,  0x08,  0x06,  0x80, 	/* 00E00 */
+	0x98,  0x11,  0x83,  0x10,  0x33,  0x01,  0x20,  0x0C,  0x00,  0x00,  0x83,  0x00,  0x03,  0xFC,  0x00,  0x40, 	/* 00E10 */
+	0x04,  0x00,  0x43,  0xFC,  0x00,  0x40,  0x04,  0x00,  0x43,  0xFC,  0x00,  0x00,  0x00,  0x87,  0x00,  0x0F, 	/* 00E20 */
+	0xFE,  0x7F,  0xC6,  0x04,  0x20,  0x83,  0x08,  0x11,  0x01,  0x90,  0x0A,  0x00,  0xE0,  0x04,  0x00,  0x40, 	/* 00E30 */
+	0x88,  0x00,  0x00,  0x00,  0x0F,  0xC1,  0x00,  0x20,  0x03,  0xFC,  0x20,  0x01,  0x00,  0x0F,  0xC0,  0x00, 	/* 00E40 */
+	0x00,  0x00,  0x00,  0x8B,  0x00,  0x00,  0x00,  0x3F,  0x00,  0x08,  0x00,  0x43,  0xFC,  0x00,  0x40,  0x08, 	/* 00E50 */
+	0x3F,  0x00,  0x00,  0x00,  0x00,  0x00,  0x9A,  0x03,  0xF0,  0x20,  0x02,  0x00,  0x40,  0x04,  0x00,  0x40, 	/* 00E60 */
+	0x08,  0x04,  0x80,  0xE8,  0x03,  0x00,  0x10,  0x00,  0x00,  0x9D,  0x00,  0x00,  0x00,  0x00,  0x01,  0x8C, 	/* 00E70 */
+	0x25,  0x24,  0x20,  0x42,  0x02,  0x52,  0x18,  0xC0,  0x00,  0x00,  0x00,  0x00,  0x9E,  0x00,  0x00,  0x00, 	/* 00E80 */
+	0x00,  0x03,  0x18,  0x4A,  0x48,  0x42,  0x84,  0x24,  0xA4,  0x31,  0x80,  0x00,  0x00,  0x00,  0x00,  0xA0, 	/* 00E90 */
+	0x00,  0x00,  0x04,  0x00,  0x80,  0x10,  0x02,  0x00,  0x40,  0x08,  0x01,  0x00,  0x20,  0x07,  0xFE,  0x00, 	/* 00EA0 */
+	0x00,  0x00,  0xA5,  0x09,  0x00,  0x90,  0x09,  0x00,  0x90,  0x09,  0x00,  0x90,  0x09,  0x00,  0x90,  0x09, 	/* 00EB0 */
+	0x00,  0x90,  0x09,  0x00,  0x90,  0xA7,  0x00,  0x00,  0x40,  0x04,  0x00,  0xA0,  0x0A,  0x01,  0x10,  0x11, 	/* 00EC0 */
+	0x02,  0x08,  0x20,  0x84,  0x04,  0x40,  0x40,  0x00,  0xA8,  0x00,  0x04,  0x04,  0x40,  0x42,  0x08,  0x20, 	/* 00ED0 */
+	0x81,  0x10,  0x11,  0x00,  0xA0,  0x0A,  0x00,  0x40,  0x04,  0x00,  0x00,  0xA9,  0x00,  0x01,  0xE0,  0x21, 	/* 00EE0 */
+	0x04,  0x08,  0x40,  0x84,  0x08,  0x40,  0x84,  0x08,  0x40,  0x84,  0x08,  0x40,  0x80,  0x00,  0xAA,  0x00, 	/* 00EF0 */
+	0x04,  0x08,  0x40,  0x84,  0x08,  0x40,  0x84,  0x08,  0x40,  0x84,  0x08,  0x40,  0x82,  0x10,  0x1E,  0x00, 	/* 00F00 */
+	0x00,  0xAB,  0x00,  0xC0,  0x10,  0x02,  0x00,  0x20,  0x03,  0x00,  0x30,  0x01,  0x00,  0x18,  0x01,  0x80, 	/* 00F10 */
+	0x08,  0x01,  0x00,  0x60,  0xAC,  0x06,  0x60,  0x88,  0x11,  0x01,  0x10,  0x19,  0x81,  0x98,  0x08,  0x80, 	/* 00F20 */
+	0xCC,  0x0C,  0xC0,  0x44,  0x08,  0x83,  0x30,  0xB4,  0x00,  0x00,  0x00,  0x06,  0x00,  0x60,  0x00,  0x00, 	/* 00F30 */
+	0x00,  0x00,  0x00,  0x00,  0x30,  0xC3,  0x0C,  0x00,  0x00,  0x00,  0xB5,  0x00,  0x00,  0x00,  0x61,  0x86, 	/* 00F40 */
+	0x18,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x0C,  0x00,  0xC0,  0x00,  0x00,  0x00,  0xBD,  0x00,  0x00, 	/* 00F50 */
+	0x00,  0x00,  0x01,  0x98,  0x22,  0x44,  0x22,  0x44,  0x22,  0x44,  0x19,  0x80,  0x00,  0x00,  0x00,  0x00, 	/* 00F60 */
+	0x92,  0x00,  0x01,  0x80,  0x18,  0x00,  0x00,  0x7F,  0xE0,  0x00,  0x00,  0x07,  0xFE,  0x00,  0x00,  0x18, 	/* 00F70 */
+	0x01,  0x80,  0x00,  0xA0,  0x00,  0x00,  0x10,  0x01,  0x00,  0x20,  0x7F,  0xC0,  0x40,  0x04,  0x07,  0xFC, 	/* 00F80 */
+	0x08,  0x01,  0x00,  0x10,  0x00,  0x00,  0xA1,  0x00,  0x00,  0x00,  0x00,  0x07,  0xFE,  0x00,  0x00,  0x00, 	/* 00F90 */
+	0x7F,  0xE0,  0x00,  0x00,  0x07,  0xFE,  0x00,  0x00,  0x00,  0xA6,  0x00,  0x00,  0x06,  0x03,  0x81,  0xC0, 	/* 00FA0 */
+	0x60,  0x01,  0xC0,  0x03,  0x80,  0x06,  0x7F,  0xE0,  0x00,  0x7F,  0xE0,  0x00,  0xA7,  0x00,  0x06,  0x00, 	/* 00FB0 */
+	0x1C,  0x00,  0x38,  0x00,  0x60,  0x38,  0x1C,  0x06,  0x00,  0x7F,  0xE0,  0x00,  0x7F,  0xE0,  0x00,  0xAA, 	/* 00FC0 */
+	0x00,  0x00,  0x00,  0x04,  0x40,  0x88,  0x11,  0x02,  0x20,  0x44,  0x02,  0x20,  0x11,  0x00,  0x88,  0x04, 	/* 00FD0 */
+	0x40,  0x00,  0xAB,  0x00,  0x00,  0x00,  0x44,  0x02,  0x20,  0x11,  0x00,  0x88,  0x04,  0x40,  0x88,  0x11, 	/* 00FE0 */
+	0x02,  0x20,  0x44,  0x00,  0x00,  0x82,  0x00,  0x00,  0x00,  0x1F,  0xE2,  0x00,  0x40,  0x04,  0x00,  0x40, 	/* 00FF0 */
+	0x04,  0x00,  0x20,  0x01,  0xFE,  0x00,  0x00,  0x00,  0x83,  0x00,  0x00,  0x00,  0x7F,  0x80,  0x04,  0x00, 	/* 01000 */
+	0x20,  0x02,  0x00,  0x20,  0x02,  0x00,  0x47,  0xF8,  0x00,  0x00,  0x00,  0x86,  0x00,  0x00,  0x00,  0x1F, 	/* 01010 */
+	0xE2,  0x00,  0x40,  0x04,  0x00,  0x20,  0x01,  0xFE,  0x00,  0x00,  0x00,  0x3F,  0xE0,  0x00,  0x87,  0x00, 	/* 01020 */
+	0x00,  0x00,  0x7F,  0x80,  0x04,  0x00,  0x20,  0x02,  0x00,  0x47,  0xF8,  0x00,  0x00,  0x00,  0x7F,  0xC0, 	/* 01030 */
+	0x00,  0xA5,  0x00,  0x00,  0x40,  0x04,  0x00,  0x40,  0x04,  0x00,  0x40,  0x04,  0x00,  0x40,  0x04,  0x07, 	/* 01040 */
+	0xFE,  0x00,  0x00,  0x00,  0x92,  0x0F,  0x03,  0x0C,  0x40,  0x20,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00, 	/* 01050 */
+	0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x80,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x0F, 	/* 01060 */
+	0xFF,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x81,  0x00,  0x00,  0x00,  0x00,  0x00, 	/* 01070 */
+	0x00,  0x00,  0x0F,  0xFF,  0xFF,  0xF0,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x82,  0x04,  0x00, 	/* 01080 */
+	0x40,  0x04,  0x00,  0x40,  0x04,  0x00,  0x40,  0x04,  0x00,  0x40,  0x04,  0x00,  0x40,  0x04,  0x00,  0x40, 	/* 01090 */
+	0x83,  0x06,  0x00,  0x60,  0x06,  0x00,  0x60,  0x06,  0x00,  0x60,  0x06,  0x00,  0x60,  0x06,  0x00,  0x60, 	/* 010A0 */
+	0x06,  0x00,  0x60,  0x8C,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x7F,  0x04,  0x00,  0x40, 	/* 010B0 */
+	0x04,  0x00,  0x40,  0x04,  0x00,  0x40,  0x8F,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x7F, 	/* 010C0 */
+	0x07,  0xF0,  0x60,  0x06,  0x00,  0x60,  0x06,  0x00,  0x60,  0x90,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00, 	/* 010D0 */
+	0x00,  0x0F,  0xC0,  0x04,  0x00,  0x40,  0x04,  0x00,  0x40,  0x04,  0x00,  0x40,  0x93,  0x00,  0x00,  0x00, 	/* 010E0 */
+	0x00,  0x00,  0x00,  0x00,  0x0F,  0xE0,  0xFE,  0x00,  0x60,  0x06,  0x00,  0x60,  0x06,  0x00,  0x60,  0x94, 	/* 010F0 */
+	0x04,  0x00,  0x40,  0x04,  0x00,  0x40,  0x04,  0x00,  0x7F,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00, 	/* 01100 */
+	0x00,  0x00,  0x97,  0x06,  0x00,  0x60,  0x06,  0x00,  0x60,  0x06,  0x00,  0x7F,  0x07,  0xF0,  0x00,  0x00, 	/* 01110 */
+	0x00,  0x00,  0x00,  0x00,  0x00,  0x98,  0x04,  0x00,  0x40,  0x04,  0x00,  0x40,  0x04,  0x0F,  0xC0,  0x00, 	/* 01120 */
+	0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x9B,  0x06,  0x00,  0x60,  0x06,  0x00,  0x60,  0x06, 	/* 01130 */
+	0x0F,  0xE0,  0xFE,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x9C,  0x04,  0x00,  0x40,  0x04, 	/* 01140 */
+	0x00,  0x40,  0x04,  0x00,  0x7F,  0x04,  0x00,  0x40,  0x04,  0x00,  0x40,  0x04,  0x00,  0x40,  0x9D,  0x04, 	/* 01150 */
+	0x00,  0x40,  0x04,  0x00,  0x40,  0x04,  0x00,  0x7F,  0x07,  0xF0,  0x40,  0x04,  0x00,  0x40,  0x04,  0x00, 	/* 01160 */
+	0x40,  0xA0,  0x06,  0x00,  0x60,  0x06,  0x00,  0x60,  0x06,  0x00,  0x7F,  0x06,  0x00,  0x60,  0x06,  0x00, 	/* 01170 */
+	0x60,  0x06,  0x00,  0x60,  0xA3,  0x06,  0x00,  0x60,  0x06,  0x00,  0x60,  0x06,  0x00,  0x7F,  0x07,  0xF0, 	/* 01180 */
+	0x60,  0x06,  0x00,  0x60,  0x06,  0x00,  0x60,  0xA4,  0x04,  0x00,  0x40,  0x04,  0x00,  0x40,  0x04,  0x0F, 	/* 01190 */
+	0xC0,  0x04,  0x00,  0x40,  0x04,  0x00,  0x40,  0x04,  0x00,  0x40,  0xA5,  0x04,  0x00,  0x40,  0x04,  0x00, 	/* 011A0 */
+	0x40,  0x04,  0x0F,  0xC0,  0xFC,  0x00,  0x40,  0x04,  0x00,  0x40,  0x04,  0x00,  0x40,  0xA8,  0x06,  0x00, 	/* 011B0 */
+	0x60,  0x06,  0x00,  0x60,  0x06,  0x0F,  0xE0,  0x06,  0x00,  0x60,  0x06,  0x00,  0x60,  0x06,  0x00,  0x60, 	/* 011C0 */
+	0xAB,  0x06,  0x00,  0x60,  0x06,  0x00,  0x60,  0x06,  0x0F,  0xE0,  0xFE,  0x00,  0x60,  0x06,  0x00,  0x60, 	/* 011D0 */
+	0x06,  0x00,  0x60,  0xAC,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x0F,  0xFF,  0x04,  0x00,  0x40, 	/* 011E0 */
+	0x04,  0x00,  0x40,  0x04,  0x00,  0x40,  0xAF,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x0F,  0xFF, 	/* 011F0 */
+	0xFF,  0xF0,  0x40,  0x04,  0x00,  0x40,  0x04,  0x00,  0x40,  0xB0,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00, 	/* 01200 */
+	0x00,  0x0F,  0xFF,  0x06,  0x00,  0x60,  0x06,  0x00,  0x60,  0x06,  0x00,  0x60,  0xB3,  0x00,  0x00,  0x00, 	/* 01210 */
+	0x00,  0x00,  0x00,  0x00,  0x0F,  0xFF,  0xFF,  0xF0,  0x60,  0x06,  0x00,  0x60,  0x06,  0x00,  0x60,  0xB4, 	/* 01220 */
+	0x04,  0x00,  0x40,  0x04,  0x00,  0x40,  0x04,  0x0F,  0xFF,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00, 	/* 01230 */
+	0x00,  0x00,  0xB7,  0x04,  0x00,  0x40,  0x04,  0x00,  0x40,  0x04,  0x0F,  0xFF,  0xFF,  0xF0,  0x00,  0x00, 	/* 01240 */
+	0x00,  0x00,  0x00,  0x00,  0x00,  0xB8,  0x06,  0x00,  0x60,  0x06,  0x00,  0x60,  0x06,  0x0F,  0xFF,  0x00, 	/* 01250 */
+	0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0xBB,  0x06,  0x00,  0x60,  0x06,  0x00,  0x60,  0x06, 	/* 01260 */
+	0x0F,  0xFF,  0xFF,  0xF0,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0xBC,  0x04,  0x00,  0x40,  0x04, 	/* 01270 */
+	0x00,  0x40,  0x04,  0x0F,  0xFF,  0x04,  0x00,  0x40,  0x04,  0x00,  0x40,  0x04,  0x00,  0x40,  0xBF,  0x04, 	/* 01280 */
+	0x00,  0x40,  0x04,  0x00,  0x40,  0x04,  0x0F,  0xFF,  0xFF,  0xF0,  0x40,  0x04,  0x00,  0x40,  0x04,  0x00, 	/* 01290 */
+	0x40,  0x82,  0x06,  0x00,  0x60,  0x06,  0x00,  0x60,  0x06,  0x0F,  0xFF,  0x06,  0x00,  0x60,  0x06,  0x00, 	/* 012A0 */
+	0x60,  0x06,  0x00,  0x60,  0x8B,  0x06,  0x00,  0x60,  0x06,  0x00,  0x60,  0x06,  0x0F,  0xFF,  0xFF,  0xF0, 	/* 012B0 */
+	0x60,  0x06,  0x00,  0x60,  0x06,  0x00,  0x60,  0xA0,  0x00,  0x0F,  0xFE,  0xFF,  0xEF,  0xFE,  0xFF,  0xEF, 	/* 012C0 */
+	0xFE,  0xFF,  0xEF,  0xFE,  0xFF,  0xEF,  0xFE,  0xFF,  0xEF,  0xFE,  0xA1,  0x00,  0x0F,  0xFE,  0x80,  0x28, 	/* 012D0 */
+	0x02,  0x80,  0x28,  0x02,  0x80,  0x28,  0x02,  0x80,  0x28,  0x02,  0x80,  0x2F,  0xFE,  0xB2,  0x04,  0x00, 	/* 012E0 */
+	0x40,  0x0E,  0x00,  0xE0,  0x1F,  0x01,  0xF0,  0x3F,  0x83,  0xF8,  0x7F,  0xC7,  0xFC,  0xFF,  0xE0,  0x00, 	/* 012F0 */
+	0xB3,  0x04,  0x00,  0x40,  0x0A,  0x00,  0xA0,  0x11,  0x01,  0x10,  0x20,  0x82,  0x08,  0x40,  0x44,  0x04, 	/* 01300 */
+	0xFF,  0xE0,  0x00,  0xBC,  0x00,  0x0F,  0xFE,  0x7F,  0xC7,  0xFC,  0x3F,  0x83,  0xF8,  0x1F,  0x01,  0xF0, 	/* 01310 */
+	0x0E,  0x00,  0xE0,  0x04,  0x00,  0x40,  0xBD,  0x00,  0x0F,  0xFE,  0x40,  0x44,  0x04,  0x20,  0x82,  0x08, 	/* 01320 */
+	0x11,  0x01,  0x10,  0x0A,  0x00,  0xA0,  0x04,  0x00,  0x40,  0x86,  0x00,  0x00,  0x40,  0x0E,  0x01,  0xF0, 	/* 01330 */
+	0x3F,  0x87,  0xFC,  0xFF,  0xE7,  0xFC,  0x3F,  0x81,  0xF0,  0x0E,  0x00,  0x40,  0x87,  0x00,  0x00,  0x40, 	/* 01340 */
+	0x0A,  0x01,  0x10,  0x20,  0x84,  0x04,  0x80,  0x24,  0x04,  0x20,  0x81,  0x10,  0x0A,  0x00,  0x40,  0x8B, 	/* 01350 */
+	0x00,  0x00,  0xE0,  0x31,  0x84,  0x04,  0x40,  0x48,  0x02,  0x80,  0x28,  0x02,  0x40,  0x44,  0x04,  0x31, 	/* 01360 */
+	0x80,  0xE0,  0x8E,  0x00,  0x00,  0xE0,  0x31,  0x84,  0xE4,  0x51,  0x4A,  0x0A,  0xA0,  0xAA,  0x0A,  0x51, 	/* 01370 */
+	0x44,  0xE4,  0x31,  0x80,  0xE0,  0x8F,  0x00,  0x00,  0xE0,  0x3F,  0x87,  0xFC,  0x7F,  0xCF,  0xFE,  0xFF, 	/* 01380 */
+	0xEF,  0xFE,  0x7F,  0xC7,  0xFC,  0x3F,  0x80,  0xE0,  0xAF,  0x0F,  0x03,  0x0C,  0x40,  0x24,  0x02,  0x80, 	/* 01390 */
+	0x18,  0x01,  0x80,  0x18,  0x01,  0x40,  0x24,  0x02,  0x30,  0xC0,  0xF0,  0x85,  0x00,  0x00,  0x40,  0x04, 	/* 013A0 */
+	0x00,  0xE0,  0xFF,  0xE7,  0xFC,  0x3F,  0x81,  0xF0,  0x3F,  0x83,  0xB8,  0x60,  0xC0,  0x00,  0x86,  0x00, 	/* 013B0 */
+	0x00,  0x40,  0x04,  0x00,  0xA0,  0xFB,  0xE4,  0x04,  0x20,  0x81,  0x10,  0x24,  0x83,  0xB8,  0x60,  0xC0, 	/* 013C0 */
+	0x00,  0x80,  0x00,  0x00,  0xE0,  0x11,  0x01,  0x10,  0x11,  0x00,  0xE0,  0x04,  0x00,  0x40,  0x3F,  0x80, 	/* 013D0 */
+	0x40,  0x04,  0x00,  0x40,  0x82,  0x00,  0x00,  0x3E,  0x00,  0x60,  0x0A,  0x01,  0x20,  0x22,  0x3C,  0x04, 	/* 013E0 */
+	0x40,  0x44,  0x04,  0x40,  0x38,  0x00,  0x00,  0xAA,  0x02,  0x00,  0x30,  0x03,  0x80,  0x2C,  0x02,  0x40, 	/* 013F0 */
+	0x24,  0x02,  0x80,  0x20,  0x1E,  0x03,  0xE0,  0x1C,  0x00,  0x00,  0xAD,  0x08,  0x00,  0x80,  0x08,  0x00, 	/* 01400 */
+	0x80,  0x08,  0x00,  0xB0,  0x0D,  0x80,  0x98,  0x09,  0x00,  0xA0,  0x0C,  0x00,  0x00,  0xAF,  0x01,  0x00, 	/* 01410 */
+	0x10,  0x09,  0xC0,  0xFC,  0x3F,  0x03,  0x90,  0x09,  0xC0,  0xFC,  0x3F,  0x03,  0x90,  0x08,  0x00,  0x80, 	/* 01420 */
+	0x80,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00, 	/* 01430 */
+	0x00,  0x00,  0x00,  0x81,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00, 	/* 01440 */
+	0x00,  0x04,  0x00,  0x20,  0x02,  0x00,  0x82,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00, 	/* 01450 */
+	0x00,  0x00,  0x00,  0x00,  0x03,  0x00,  0x48,  0x03,  0x00,  0x83,  0x00,  0x00,  0x00,  0x00,  0x00,  0x90, 	/* 01460 */
+	0x09,  0x00,  0x90,  0x12,  0x01,  0x20,  0x24,  0x00,  0x00,  0x00,  0x00,  0x00,  0x85,  0x00,  0x00,  0x00, 	/* 01470 */
+	0x08,  0x00,  0xF8,  0x08,  0x81,  0x10,  0x21,  0x04,  0xA0,  0x06,  0x00,  0x10,  0x00,  0x80,  0x00,  0x86, 	/* 01480 */
+	0x00,  0x00,  0x04,  0x00,  0x40,  0x08,  0x01,  0x01,  0xA0,  0x26,  0x04,  0x90,  0x50,  0x06,  0x00,  0x00, 	/* 01490 */
+	0x00,  0x00,  0x87,  0x00,  0x00,  0xE0,  0x31,  0x84,  0x04,  0x40,  0x48,  0x02,  0x80,  0x28,  0x02,  0x40, 	/* 014A0 */
+	0x44,  0x04,  0x31,  0x80,  0xE0,  0x88,  0x00,  0x40,  0x08,  0x00,  0x80,  0x10,  0x01,  0x00,  0x20,  0x02, 	/* 014B0 */
+	0x00,  0x10,  0x01,  0x00,  0x08,  0x00,  0x80,  0x04,  0x89,  0x20,  0x01,  0x00,  0x10,  0x00,  0x80,  0x08, 	/* 014C0 */
+	0x00,  0x40,  0x04,  0x00,  0x80,  0x08,  0x01,  0x00,  0x10,  0x02,  0x00,  0x8A,  0x02,  0x40,  0x48,  0x04, 	/* 014D0 */
+	0x80,  0x90,  0x09,  0x01,  0x20,  0x12,  0x00,  0x90,  0x09,  0x00,  0x48,  0x04,  0x80,  0x24,  0x8B,  0x24, 	/* 014E0 */
+	0x01,  0x20,  0x12,  0x00,  0x90,  0x09,  0x00,  0x48,  0x04,  0x80,  0x90,  0x09,  0x01,  0x20,  0x12,  0x02, 	/* 014F0 */
+	0x40,  0x8C,  0x03,  0xC0,  0x20,  0x02,  0x00,  0x20,  0x02,  0x00,  0x20,  0x02,  0x00,  0x20,  0x00,  0x00, 	/* 01500 */
+	0x00,  0x00,  0x00,  0x00,  0x8D,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x04,  0x00,  0x40,  0x04,  0x00, 	/* 01510 */
+	0x40,  0x04,  0x00,  0x40,  0x04,  0x03,  0xC0,  0x8E,  0x07,  0xC0,  0x44,  0x05,  0xC0,  0x50,  0x05,  0x00, 	/* 01520 */
+	0x50,  0x05,  0x00,  0x70,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x8F,  0x00,  0x00,  0x00,  0x00,  0x00, 	/* 01530 */
+	0x00,  0x0E,  0x00,  0xA0,  0x0A,  0x00,  0xA0,  0x0A,  0x03,  0xA0,  0x22,  0x03,  0xE0,  0x90,  0x03,  0xC0, 	/* 01540 */
+	0x38,  0x03,  0x80,  0x30,  0x03,  0x00,  0x30,  0x03,  0x00,  0x30,  0x03,  0x00,  0x38,  0x03,  0x80,  0x3C, 	/* 01550 */
+	0x91,  0x3C,  0x01,  0xC0,  0x1C,  0x00,  0xC0,  0x0C,  0x00,  0xC0,  0x0C,  0x00,  0xC0,  0x0C,  0x01,  0xC0, 	/* 01560 */
+	0x1C,  0x03,  0xC0,  0x92,  0x00,  0x07,  0xFE,  0x7F,  0xE0,  0x00,  0xFF,  0xFF,  0xFF,  0x06,  0x00,  0x60, 	/* 01570 */
+	0x06,  0x00,  0x60,  0x06,  0x00,  0x60,  0x93,  0x00,  0x00,  0x00,  0x00,  0x0F,  0xFF,  0xFF,  0xF0,  0x00, 	/* 01580 */
+	0x00,  0x0F,  0xFF,  0xFF,  0xF0,  0x00,  0x00,  0x00,  0x00,  0x94,  0x00,  0xC0,  0x30,  0x02,  0x00,  0x20, 	/* 01590 */
+	0x02,  0x00,  0x20,  0x02,  0x00,  0x20,  0x02,  0x00,  0x20,  0x03,  0x00,  0x0C,  0x95,  0x30,  0x00,  0xC0, 	/* 015A0 */
+	0x04,  0x00,  0x40,  0x04,  0x00,  0x40,  0x04,  0x00,  0x40,  0x04,  0x00,  0x40,  0x0C,  0x03,  0x00,  0x81, 	/* 015B0 */
+	0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x08,  0x01,  0xE0,  0x0A,  0x01,  0xF0,  0x1C,  0x82,  0x88,  0x11, 	/* 015C0 */
+	0x00,  0x00,  0x82,  0x08,  0x00,  0x80,  0x3F,  0x00,  0x80,  0x0F,  0x01,  0x28,  0x32,  0x45,  0x44,  0x4C, 	/* 015D0 */
+	0x44,  0x88,  0x33,  0x00,  0x00,  0x83,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x01,  0x00,  0x12, 	/* 015E0 */
+	0x02,  0x10,  0x29,  0x01,  0x00,  0x00,  0x00,  0x00,  0x84,  0x00,  0x00,  0x00,  0x20,  0x02,  0x10,  0x40, 	/* 015F0 */
+	0x84,  0x08,  0x40,  0x44,  0x84,  0x28,  0x41,  0x00,  0x00,  0x00,  0x00,  0x85,  0x00,  0x00,  0x00,  0x00, 	/* 01600 */
+	0x00,  0x00,  0x10,  0x00,  0xC0,  0x1C,  0x02,  0x20,  0x02,  0x00,  0x40,  0x18,  0x00,  0x00,  0x86,  0x08, 	/* 01610 */
+	0x00,  0x60,  0x00,  0x00,  0xE0,  0x31,  0x00,  0x08,  0x00,  0x80,  0x08,  0x01,  0x00,  0x60,  0x18,  0x00, 	/* 01620 */
+	0x00,  0x87,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x10,  0x00,  0x80,  0x3E,  0x00,  0x40,  0x18,  0x02, 	/* 01630 */
+	0x40,  0x47,  0x00,  0x00,  0x88,  0x08,  0x00,  0x60,  0x00,  0x01,  0xF0,  0x01,  0x00,  0x20,  0x04,  0x00, 	/* 01640 */
+	0xC0,  0x12,  0x02,  0x20,  0x41,  0xC0,  0x00,  0x89,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x08,  0x03, 	/* 01650 */
+	0xD0,  0x08,  0x80,  0xE0,  0x19,  0x02,  0x90,  0x12,  0x00,  0x00,  0x8A,  0x08,  0x00,  0x80,  0x0E,  0x47, 	/* 01660 */
+	0x82,  0x08,  0x20,  0xF0,  0x18,  0x82,  0x84,  0x48,  0x44,  0x88,  0x33,  0x00,  0x00,  0x8B,  0x00,  0x01, 	/* 01670 */
+	0x00,  0x10,  0x87,  0xC4,  0x12,  0x41,  0x22,  0x12,  0x22,  0x20,  0x22,  0x05,  0x20,  0x0C,  0x00,  0x00, 	/* 01680 */
+	0x8C,  0x00,  0x01,  0x0A,  0x10,  0xA7,  0xC4,  0x12,  0x41,  0x22,  0x12,  0x22,  0x20,  0x22,  0x05,  0x20, 	/* 01690 */
+	0x0C,  0x00,  0x00,  0x8D,  0x04,  0x00,  0x70,  0x3C,  0x00,  0x38,  0x3E,  0x00,  0x10,  0x0E,  0x81,  0x18, 	/* 016A0 */
+	0x20,  0x01,  0x00,  0x0F,  0x00,  0x00,  0x8E,  0x05,  0x40,  0x74,  0x3C,  0x00,  0x38,  0x3E,  0x00,  0x10, 	/* 016B0 */
+	0x0E,  0x81,  0x18,  0x20,  0x01,  0x00,  0x0F,  0x00,  0x00,  0x8F,  0x00,  0x00,  0x20,  0x02,  0x00,  0x40, 	/* 016C0 */
+	0x08,  0x01,  0x00,  0x10,  0x00,  0x80,  0x04,  0x00,  0x20,  0x02,  0x00,  0x00,  0x90,  0x00,  0x00,  0x40, 	/* 016D0 */
+	0x06,  0x80,  0xA8,  0x10,  0x02,  0x00,  0x20,  0x01,  0x00,  0x08,  0x00,  0x40,  0x04,  0x00,  0x00,  0x91, 	/* 016E0 */
+	0x00,  0x82,  0x08,  0x20,  0xE2,  0x78,  0x40,  0x84,  0x08,  0x40,  0x85,  0x08,  0x20,  0x80,  0x10,  0x06, 	/* 016F0 */
+	0x00,  0x00,  0x92,  0x01,  0x52,  0x15,  0x20,  0xE2,  0x78,  0x40,  0x84,  0x08,  0x40,  0x85,  0x08,  0x20, 	/* 01700 */
+	0x80,  0x10,  0x06,  0x00,  0x00,  0x93,  0x00,  0x01,  0x00,  0x0F,  0x80,  0x00,  0x00,  0x00,  0x00,  0x00, 	/* 01710 */
+	0x02,  0x00,  0x20,  0x41,  0xF8,  0x00,  0x00,  0x00,  0x94,  0x00,  0x02,  0x14,  0x1F,  0x40,  0x00,  0x00, 	/* 01720 */
+	0x00,  0x00,  0x00,  0x04,  0x00,  0x40,  0x83,  0xF0,  0x00,  0x00,  0x00,  0x95,  0x04,  0x00,  0x40,  0x02, 	/* 01730 */
+	0xC3,  0xF0,  0x02,  0x00,  0x10,  0x1E,  0x82,  0x18,  0x20,  0x01,  0x80,  0x07,  0x00,  0x00,  0x96,  0x09, 	/* 01740 */
+	0x40,  0x94,  0x05,  0x87,  0xE0,  0x04,  0x00,  0x20,  0x3D,  0x04,  0x30,  0x40,  0x03,  0x00,  0x0E,  0x00, 	/* 01750 */
+	0x00,  0x97,  0x00,  0x01,  0x00,  0x10,  0x01,  0x00,  0x10,  0x01,  0x00,  0x10,  0x01,  0x00,  0x10,  0x40, 	/* 01760 */
+	0x98,  0x06,  0x00,  0x00,  0x98,  0x00,  0x01,  0x00,  0x11,  0x41,  0x14,  0x10,  0x01,  0x00,  0x10,  0x01, 	/* 01770 */
+	0x00,  0x10,  0x40,  0x98,  0x06,  0x00,  0x00,  0x99,  0x02,  0x00,  0x20,  0x7F,  0xC0,  0x20,  0x0E,  0x01, 	/* 01780 */
+	0x20,  0x12,  0x00,  0xE0,  0x02,  0x00,  0x40,  0x18,  0x00,  0x00,  0x9A,  0x02,  0xA0,  0x2A,  0x7F,  0xC0, 	/* 01790 */
+	0x20,  0x0E,  0x01,  0x20,  0x12,  0x00,  0xE0,  0x02,  0x00,  0x40,  0x18,  0x00,  0x00,  0x9B,  0x00,  0x00, 	/* 017A0 */
+	0x10,  0x11,  0x01,  0x1E,  0x7F,  0x01,  0x10,  0x11,  0x01,  0x20,  0x10,  0x00,  0x80,  0x07,  0x80,  0x00, 	/* 017B0 */
+	0x9C,  0x00,  0x00,  0x2A,  0x22,  0xA2,  0x38,  0xFE,  0x02,  0x20,  0x22,  0x02,  0x40,  0x20,  0x01,  0x00, 	/* 017C0 */
+	0x0F,  0x00,  0x00,  0x9D,  0x00,  0x01,  0xF0,  0x02,  0x00,  0x40,  0x09,  0xC7,  0xE0,  0x04,  0x00,  0x80, 	/* 017D0 */
+	0x08,  0x00,  0x40,  0x03,  0x00,  0x00,  0x9E,  0x00,  0x01,  0xFA,  0x02,  0xA0,  0x40,  0x09,  0xC7,  0xE0, 	/* 017E0 */
+	0x04,  0x00,  0x80,  0x08,  0x00,  0x40,  0x03,  0x00,  0x00,  0x9F,  0x08,  0x00,  0x80,  0x7E,  0x01,  0x00, 	/* 017F0 */
+	0x10,  0xC1,  0x30,  0x20,  0x02,  0x00,  0x24,  0x04,  0x40,  0x43,  0xC0,  0x00,  0xA0,  0x08,  0x00,  0x8A, 	/* 01800 */
+	0x7E,  0xA1,  0x00,  0x10,  0xC1,  0x30,  0x20,  0x02,  0x00,  0x24,  0x04,  0x40,  0x43,  0xC0,  0x00,  0xA1, 	/* 01810 */
+	0x10,  0x01,  0x00,  0x7F,  0x01,  0x00,  0x10,  0x02,  0x60,  0x39,  0x02,  0x08,  0x00,  0x80,  0x30,  0x1C, 	/* 01820 */
+	0x00,  0x00,  0xA2,  0x10,  0x01,  0x14,  0x7F,  0x41,  0x00,  0x10,  0x02,  0x60,  0x39,  0x02,  0x08,  0x00, 	/* 01830 */
+	0x80,  0x30,  0x1C,  0x00,  0x00,  0xA3,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x0E, 	/* 01840 */
+	0x03,  0x10,  0x01,  0x00,  0x20,  0x0C,  0x00,  0x00,  0xA4,  0x00,  0x00,  0x00,  0x0F,  0x0F,  0x08,  0x00, 	/* 01850 */
+	0x40,  0x04,  0x00,  0x80,  0x30,  0x0C,  0x00,  0x00,  0x00,  0x00,  0x00,  0xA5,  0x00,  0x00,  0x0A,  0x1E, 	/* 01860 */
+	0xAE,  0x10,  0x00,  0x80,  0x08,  0x01,  0x00,  0x60,  0x18,  0x00,  0x00,  0x00,  0x00,  0x00,  0xA6,  0x00, 	/* 01870 */
+	0x00,  0x1C,  0x7E,  0x00,  0x20,  0x04,  0x00,  0x80,  0x08,  0x00,  0x80,  0x04,  0x00,  0x38,  0x00,  0x00, 	/* 01880 */
+	0x00,  0xA7,  0x00,  0x00,  0x38,  0xFC,  0x00,  0x54,  0x09,  0x41,  0x00,  0x10,  0x01,  0x00,  0x08,  0x00, 	/* 01890 */
+	0x70,  0x00,  0x00,  0x00,  0xA8,  0x00,  0x00,  0x80,  0x08,  0x00,  0x80,  0x04,  0xC0,  0x70,  0x0C,  0x01, 	/* 018A0 */
+	0x00,  0x20,  0x01,  0x00,  0x0F,  0xC0,  0x00,  0xA9,  0x00,  0x00,  0x8A,  0x08,  0xA0,  0x80,  0x04,  0xC0, 	/* 018B0 */
+	0x70,  0x0C,  0x01,  0x00,  0x20,  0x01,  0x00,  0x0F,  0xC0,  0x00,  0xAA,  0x08,  0x00,  0x80,  0x3E,  0x41, 	/* 018C0 */
+	0x0A,  0x10,  0x82,  0x08,  0x20,  0x84,  0x78,  0x08,  0xC0,  0x8A,  0x07,  0x00,  0x00,  0xAB,  0x00,  0x02, 	/* 018D0 */
+	0x00,  0x21,  0x82,  0x60,  0x40,  0x04,  0x00,  0x40,  0x04,  0x40,  0x44,  0x05,  0x3C,  0x20,  0x00,  0x00, 	/* 018E0 */
+	0xAC,  0x00,  0x00,  0x20,  0x22,  0x02,  0xF8,  0x32,  0x42,  0x22,  0x34,  0x25,  0x42,  0x49,  0xA4,  0xA4, 	/* 018F0 */
+	0x31,  0xC0,  0x00,  0xAD,  0x10,  0x01,  0x00,  0x10,  0x07,  0xB8,  0x14,  0x41,  0x84,  0x10,  0x43,  0x04, 	/* 01900 */
+	0x31,  0xC5,  0x26,  0x11,  0x80,  0x00,  0xAE,  0x00,  0x00,  0xF0,  0x14,  0x82,  0x44,  0x44,  0x24,  0x42, 	/* 01910 */
+	0x48,  0x24,  0x84,  0x30,  0x80,  0x30,  0x00,  0x00,  0x00,  0xAF,  0x00,  0x02,  0x08,  0x20,  0xE2,  0xF8, 	/* 01920 */
+	0x40,  0x84,  0x08,  0x40,  0x84,  0x78,  0x48,  0xC5,  0x8A,  0x27,  0x00,  0x00,  0xB0,  0x00,  0x52,  0x0D, 	/* 01930 */
+	0x20,  0x82,  0xFC,  0x40,  0x84,  0x08,  0x40,  0x84,  0x78,  0x48,  0xC5,  0x8A,  0x27,  0x00,  0x00,  0xB1, 	/* 01940 */
+	0x00,  0x62,  0x09,  0x20,  0xE2,  0xF8,  0x40,  0x84,  0x08,  0x40,  0x84,  0x78,  0x48,  0xC5,  0x8A,  0x27, 	/* 01950 */
+	0x00,  0x00,  0xB2,  0x00,  0x00,  0x20,  0x1C,  0x00,  0x88,  0x10,  0x81,  0x0C,  0x20,  0xA2,  0x08,  0x20, 	/* 01960 */
+	0x81,  0x10,  0x0E,  0x00,  0x00,  0xB3,  0x00,  0x00,  0x45,  0x38,  0x51,  0x10,  0x21,  0x02,  0x18,  0x41, 	/* 01970 */
+	0x44,  0x10,  0x41,  0x02,  0x20,  0x1C,  0x00,  0x00,  0xB4,  0x00,  0x60,  0x89,  0x70,  0x61,  0x10,  0x21, 	/* 01980 */
+	0x02,  0x18,  0x41,  0x44,  0x10,  0x41,  0x02,  0x20,  0x1C,  0x00,  0x00,  0xB5,  0x00,  0x00,  0x80,  0x07, 	/* 01990 */
+	0x00,  0x00,  0x04,  0x00,  0x48,  0x12,  0x41,  0x22,  0x21,  0x25,  0x10,  0x0E,  0x00,  0x00,  0xB6,  0x00, 	/* 019A0 */
+	0x00,  0x8A,  0x07,  0xA0,  0x00,  0x04,  0x00,  0x48,  0x12,  0x41,  0x22,  0x21,  0x25,  0x10,  0x0E,  0x00, 	/* 019B0 */
+	0x00,  0xB7,  0x00,  0x00,  0x86,  0x07,  0x90,  0x06,  0x04,  0x00,  0x48,  0x12,  0x41,  0x22,  0x21,  0x25, 	/* 019C0 */
+	0x10,  0x0E,  0x00,  0x00,  0xB8,  0x00,  0x00,  0x00,  0x00,  0x00,  0xC0,  0x12,  0x06,  0x10,  0x00,  0x80, 	/* 019D0 */
+	0x04,  0x00,  0x20,  0x00,  0x00,  0x00,  0x00,  0xB9,  0x00,  0x00,  0x0A,  0x00,  0xA0,  0xC0,  0x12,  0x06, 	/* 019E0 */
+	0x10,  0x00,  0x80,  0x04,  0x00,  0x20,  0x00,  0x00,  0x00,  0x00,  0xBA,  0x00,  0x00,  0x0C,  0x01,  0x20, 	/* 019F0 */
+	0xCC,  0x12,  0x02,  0x10,  0xC0,  0x80,  0x04,  0x00,  0x20,  0x00,  0x00,  0x00,  0x00,  0xBB,  0x00,  0x02, 	/* 01A00 */
+	0xFE,  0x20,  0x82,  0x08,  0x47,  0xC4,  0x08,  0x40,  0x84,  0x78,  0x48,  0xC5,  0x8A,  0x27,  0x00,  0x00, 	/* 01A10 */
+	0xBC,  0x00,  0x52,  0xFD,  0x20,  0x82,  0x08,  0x47,  0xC4,  0x08,  0x40,  0x84,  0x78,  0x48,  0xC5,  0x8A, 	/* 01A20 */
+	0x27,  0x00,  0x00,  0xBD,  0x00,  0x62,  0xF9,  0x20,  0xE2,  0x08,  0x47,  0xC4,  0x08,  0x40,  0x84,  0x78, 	/* 01A30 */
+	0x48,  0xC5,  0x8A,  0x27,  0x00,  0x00,  0xBE,  0x02,  0x00,  0x20,  0x3F,  0xC0,  0x20,  0x03,  0x83,  0xE0, 	/* 01A40 */
+	0x02,  0x01,  0xE0,  0x23,  0x82,  0x24,  0x1C,  0x00,  0x00,  0xBF,  0x00,  0x03,  0xC0,  0x04,  0x00,  0x48, 	/* 01A50 */
+	0x04,  0x81,  0xF8,  0x28,  0xC4,  0x8A,  0x50,  0x82,  0x10,  0x02,  0x00,  0x00,  0x80,  0x08,  0x00,  0x80, 	/* 01A60 */
+	0x7C,  0xC0,  0x82,  0x38,  0x04,  0x80,  0x48,  0x05,  0x04,  0x30,  0x41,  0x04,  0x0F,  0x80,  0x00,  0x81, 	/* 01A70 */
+	0x00,  0x00,  0x20,  0x27,  0x02,  0xA8,  0x32,  0x42,  0x42,  0x54,  0x24,  0x82,  0x48,  0x43,  0x08,  0x03, 	/* 01A80 */
+	0x00,  0x00,  0x82,  0x08,  0x00,  0x80,  0x3E,  0x00,  0x80,  0x11,  0x07,  0xE0,  0x10,  0x01,  0x08,  0x10, 	/* 01A90 */
+	0x80,  0x90,  0x06,  0x00,  0x00,  0x83,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x0A,  0x00,  0xB8,  0x3D, 	/* 01AA0 */
+	0x40,  0x84,  0x05,  0x80,  0x40,  0x04,  0x00,  0x00,  0x84,  0x04,  0x02,  0x40,  0x23,  0x81,  0x64,  0x3A, 	/* 01AB0 */
+	0x2D,  0x04,  0x09,  0x80,  0x80,  0x08,  0x00,  0x40,  0x04,  0x00,  0x00,  0x85,  0x00,  0x00,  0x00,  0x00, 	/* 01AC0 */
+	0x00,  0x00,  0x02,  0x01,  0x38,  0x16,  0x41,  0xA4,  0x13,  0x80,  0x20,  0x04,  0x00,  0x00,  0x86,  0x02, 	/* 01AD0 */
+	0x00,  0x20,  0x47,  0x84,  0xA4,  0x52,  0x26,  0x22,  0x6A,  0x44,  0x78,  0x42,  0x00,  0x40,  0x08,  0x00, 	/* 01AE0 */
+	0x00,  0x87,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x04,  0x00,  0x70,  0x04,  0x00,  0x40,  0x1E,  0x02, 	/* 01AF0 */
+	0x58,  0x18,  0x00,  0x00,  0x88,  0x04,  0x00,  0x40,  0x04,  0x00,  0x78,  0x04,  0x00,  0x40,  0x04,  0x03, 	/* 01B00 */
+	0xC0,  0x47,  0x04,  0x4C,  0x38,  0x00,  0x00,  0x89,  0x08,  0x00,  0x60,  0x00,  0x02,  0x00,  0x20,  0x02, 	/* 01B10 */
+	0xF0,  0x30,  0x82,  0x08,  0x00,  0x80,  0x30,  0x1C,  0x00,  0x00,  0x8A,  0x01,  0x00,  0x88,  0x08,  0x81, 	/* 01B20 */
+	0x08,  0x10,  0x81,  0x08,  0x14,  0x80,  0x88,  0x00,  0x80,  0x10,  0x06,  0x00,  0x00,  0x8B,  0x00,  0x01, 	/* 01B30 */
+	0xF0,  0x02,  0x00,  0x40,  0x0F,  0x01,  0x88,  0x20,  0x44,  0x04,  0x0C,  0x81,  0x30,  0x0E,  0x00,  0x00, 	/* 01B40 */
+	0x8C,  0x10,  0x01,  0x00,  0x13,  0x01,  0x48,  0x78,  0x81,  0x08,  0x10,  0x83,  0x08,  0x30,  0x85,  0x06, 	/* 01B50 */
+	0x10,  0x00,  0x00,  0x8D,  0x00,  0x01,  0xF0,  0x02,  0x00,  0x40,  0x0F,  0x01,  0x88,  0x20,  0x44,  0x04, 	/* 01B60 */
+	0x00,  0x80,  0x10,  0x0E,  0x00,  0x00,  0x8E,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x08,  0x01,  0xC0, 	/* 01B70 */
+	0x0B,  0x80,  0xC4,  0x18,  0x42,  0x88,  0x09,  0x00,  0x00,  0x8F,  0x10,  0x01,  0x00,  0x10,  0x01,  0xB8, 	/* 01B80 */
+	0x74,  0x41,  0x82,  0x10,  0x23,  0x02,  0x50,  0x41,  0x18,  0x10,  0x00,  0x00,  0x90,  0x00,  0x01,  0xE0, 	/* 01B90 */
+	0x02,  0x00,  0x20,  0x0F,  0x81,  0x44,  0x24,  0x24,  0x82,  0x4B,  0x23,  0x4C,  0x03,  0x80,  0x00,  0x91, 	/* 01BA0 */
+	0x00,  0x01,  0xF8,  0x02,  0x00,  0xF8,  0x10,  0x42,  0x64,  0x09,  0x80,  0x60,  0x00,  0x02,  0xCC,  0x43, 	/* 01BB0 */
+	0x20,  0x00,  0x92,  0x04,  0x00,  0x40,  0x3F,  0x00,  0x80,  0x10,  0xC3,  0x90,  0x46,  0x00,  0xA0,  0x12, 	/* 01BC0 */
+	0x01,  0x00,  0x0F,  0x80,  0x00,  0x93,  0x00,  0x00,  0x40,  0x04,  0x00,  0x80,  0x08,  0x01,  0x00,  0x1C, 	/* 01BD0 */
+	0x02,  0x20,  0x22,  0x24,  0x24,  0x41,  0x80,  0x00,  0x9B,  0x20,  0x09,  0x00,  0x50,  0x04,  0x00,  0x00, 	/* 01BE0 */
+	0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x9C,  0x00,  0x04,  0x00,  0xA0, 	/* 01BF0 */
+	0x0A,  0x00,  0x40,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x9D,  0x00, 	/* 01C00 */
+	0x00,  0x00,  0x00,  0x00,  0x00,  0x18,  0x00,  0x60,  0x01,  0x00,  0x38,  0x04,  0x00,  0x00,  0x00,  0x00, 	/* 01C10 */
+	0x00,  0x9E,  0x00,  0x00,  0x10,  0x04,  0x80,  0x20,  0x30,  0x00,  0xC0,  0x02,  0x00,  0x70,  0x08,  0x00, 	/* 01C20 */
+	0x00,  0x00,  0x00,  0x00,  0xA1,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x03,  0xF0,  0x09,  0x00, 	/* 01C30 */
+	0xE0,  0x08,  0x00,  0x80,  0x10,  0x00,  0x00,  0xA2,  0x00,  0x00,  0x00,  0xFF,  0xC0,  0x04,  0x08,  0x80, 	/* 01C40 */
+	0x90,  0x0E,  0x00,  0x80,  0x08,  0x01,  0x00,  0x20,  0x00,  0x00,  0xA3,  0x00,  0x00,  0x00,  0x00,  0x00, 	/* 01C50 */
+	0x00,  0x02,  0x00,  0x20,  0x04,  0x00,  0xC0,  0x34,  0x00,  0x40,  0x04,  0x00,  0x00,  0xA4,  0x00,  0x00, 	/* 01C60 */
+	0x08,  0x00,  0x80,  0x10,  0x02,  0x00,  0xE0,  0x32,  0x00,  0x20,  0x02,  0x00,  0x20,  0x02,  0x00,  0x00, 	/* 01C70 */
+	0xA5,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x08,  0x00,  0x80,  0x3F,  0x02,  0x10,  0x22,  0x00,  0x40, 	/* 01C80 */
+	0x18,  0x00,  0x00,  0xA6,  0x04,  0x00,  0x40,  0x04,  0x07,  0xFC,  0x40,  0x44,  0x04,  0x40,  0x80,  0x08, 	/* 01C90 */
+	0x01,  0x00,  0x60,  0x18,  0x00,  0x00,  0xA7,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00, 	/* 01CA0 */
+	0x1F,  0x00,  0x40,  0x04,  0x03,  0xF8,  0x00,  0x00,  0x00,  0xA8,  0x00,  0x00,  0x00,  0x00,  0x03,  0xFC, 	/* 01CB0 */
+	0x04,  0x00,  0x40,  0x04,  0x00,  0x40,  0x04,  0x07,  0xFE,  0x00,  0x00,  0x00,  0xA9,  0x00,  0x00,  0x00, 	/* 01CC0 */
+	0x00,  0x00,  0x00,  0x02,  0x00,  0x20,  0x3F,  0x80,  0x60,  0x0A,  0x03,  0x20,  0x06,  0x00,  0x00,  0xAA, 	/* 01CD0 */
+	0x01,  0x00,  0x10,  0x01,  0x03,  0xFE,  0x03,  0x00,  0x30,  0x05,  0x00,  0x90,  0x31,  0x00,  0x10,  0x03, 	/* 01CE0 */
+	0x00,  0x00,  0xAB,  0x04,  0x00,  0x40,  0x04,  0x03,  0xFC,  0x04,  0x40,  0x44,  0x04,  0x40,  0x84,  0x08, 	/* 01CF0 */
+	0x41,  0x04,  0x21,  0x80,  0x00,  0xAC,  0x04,  0xA0,  0x4A,  0x04,  0x03,  0xFC,  0x04,  0x40,  0x44,  0x04, 	/* 01D00 */
+	0x40,  0x84,  0x08,  0x41,  0x04,  0x21,  0x80,  0x00,  0xAD,  0x04,  0x00,  0x40,  0x07,  0x87,  0xC0,  0x04, 	/* 01D10 */
+	0x00,  0x7C,  0x7E,  0x00,  0x20,  0x02,  0x00,  0x20,  0x02,  0x00,  0x00,  0xAE,  0x04,  0xA0,  0x4A,  0x07, 	/* 01D20 */
+	0x87,  0xC0,  0x04,  0x00,  0x7C,  0x7E,  0x00,  0x20,  0x02,  0x00,  0x20,  0x02,  0x00,  0x00,  0xAF,  0x00, 	/* 01D30 */
+	0x00,  0x40,  0x07,  0xC0,  0x44,  0x08,  0x41,  0x08,  0x20,  0x80,  0x10,  0x02,  0x00,  0xC0,  0x30,  0x00, 	/* 01D40 */
+	0x00,  0xB0,  0x00,  0x50,  0x45,  0x07,  0xC0,  0x44,  0x08,  0x41,  0x08,  0x20,  0x80,  0x10,  0x02,  0x00, 	/* 01D50 */
+	0xC0,  0x30,  0x00,  0x00,  0xB1,  0x00,  0x01,  0x00,  0x10,  0x01,  0xFE,  0x11,  0x02,  0x10,  0x41,  0x00, 	/* 01D60 */
+	0x10,  0x02,  0x00,  0x40,  0x18,  0x00,  0x00,  0xB2,  0x00,  0x01,  0x05,  0x10,  0x51,  0xFC,  0x11,  0x02, 	/* 01D70 */
+	0x10,  0x41,  0x00,  0x10,  0x02,  0x00,  0x40,  0x18,  0x00,  0x00,  0xB3,  0x00,  0x00,  0x00,  0x3F,  0xC0, 	/* 01D80 */
+	0x04,  0x00,  0x40,  0x04,  0x00,  0x40,  0x04,  0x3F,  0xC0,  0x04,  0x00,  0x00,  0x00,  0xB4,  0x00,  0x00, 	/* 01D90 */
+	0x0A,  0x00,  0xA7,  0xF8,  0x00,  0x80,  0x08,  0x00,  0x80,  0x08,  0x00,  0x87,  0xF8,  0x00,  0x80,  0x00, 	/* 01DA0 */
+	0xB5,  0x00,  0x00,  0x88,  0x08,  0x80,  0x88,  0x7F,  0xE0,  0x88,  0x08,  0x80,  0x88,  0x01,  0x00,  0x20, 	/* 01DB0 */
+	0x0C,  0x00,  0x00,  0xB6,  0x00,  0x01,  0x15,  0x11,  0x51,  0x10,  0x7F,  0xC1,  0x10,  0x11,  0x01,  0x10, 	/* 01DC0 */
+	0x02,  0x00,  0x40,  0x18,  0x00,  0x00,  0xB7,  0x00,  0x03,  0x00,  0x08,  0x00,  0x04,  0x60,  0x41,  0x08, 	/* 01DD0 */
+	0x00,  0x80,  0x10,  0x02,  0x00,  0xC0,  0x70,  0x00,  0x00,  0xB8,  0x00,  0x03,  0x0A,  0x08,  0xA0,  0x00, 	/* 01DE0 */
+	0x60,  0x41,  0x04,  0x00,  0x80,  0x10,  0x02,  0x00,  0xC0,  0x70,  0x00,  0x00,  0xB9,  0x00,  0x00,  0x00, 	/* 01DF0 */
+	0x3F,  0x80,  0x08,  0x00,  0x80,  0x10,  0x01,  0x00,  0x28,  0x04,  0x41,  0x82,  0x60,  0x20,  0x00,  0xBA, 	/* 01E00 */
+	0x00,  0x00,  0x0A,  0x3F,  0xA0,  0x08,  0x00,  0x80,  0x10,  0x01,  0x00,  0x28,  0x04,  0x41,  0x82,  0x60, 	/* 01E10 */
+	0x20,  0x00,  0xBB,  0x00,  0x01,  0x00,  0x10,  0x01,  0x1C,  0x1E,  0x4F,  0x08,  0x11,  0x01,  0x20,  0x10, 	/* 01E20 */
+	0x01,  0x00,  0x0F,  0x80,  0x00,  0xBC,  0x00,  0x01,  0x0A,  0x10,  0xA1,  0x1C,  0x1E,  0x4F,  0x08,  0x11, 	/* 01E30 */
+	0x01,  0x20,  0x10,  0x01,  0x00,  0x0F,  0x80,  0x00,  0xBD,  0x00,  0x00,  0x00,  0x20,  0x41,  0x04,  0x10, 	/* 01E40 */
+	0x40,  0x08,  0x00,  0x80,  0x10,  0x02,  0x00,  0xC0,  0x30,  0x00,  0x00,  0xBE,  0x00,  0x00,  0x0A,  0x20, 	/* 01E50 */
+	0xA1,  0x04,  0x10,  0x40,  0x08,  0x00,  0x80,  0x10,  0x02,  0x00,  0xC0,  0x30,  0x00,  0x00,  0xBF,  0x00, 	/* 01E60 */
+	0x00,  0x40,  0x07,  0xC0,  0x84,  0x10,  0x46,  0x68,  0x01,  0x80,  0x10,  0x02,  0x00,  0xC0,  0x30,  0x00, 	/* 01E70 */
+	0x00,  0x80,  0x00,  0x00,  0x45,  0x07,  0xD0,  0x84,  0x10,  0x46,  0x68,  0x01,  0x80,  0x10,  0x02,  0x00, 	/* 01E80 */
+	0xC0,  0x30,  0x00,  0x00,  0x81,  0x00,  0x00,  0x18,  0x3E,  0x00,  0x20,  0x02,  0x07,  0xFE,  0x02,  0x00, 	/* 01E90 */
+	0x20,  0x02,  0x00,  0x40,  0x18,  0x00,  0x00,  0x82,  0x00,  0x00,  0x1D,  0x3E,  0x50,  0x20,  0x02,  0x07, 	/* 01EA0 */
+	0xFE,  0x02,  0x00,  0x20,  0x02,  0x00,  0x40,  0x18,  0x00,  0x00,  0x83,  0x00,  0x00,  0x00,  0x00,  0x00, 	/* 01EB0 */
+	0x00,  0x08,  0x02,  0x48,  0x14,  0x81,  0x10,  0x01,  0x00,  0x60,  0x18,  0x00,  0x00,  0x84,  0x00,  0x00, 	/* 01EC0 */
+	0x80,  0x44,  0x42,  0x44,  0x24,  0x42,  0x08,  0x00,  0x80,  0x10,  0x02,  0x00,  0xC0,  0x30,  0x00,  0x00, 	/* 01ED0 */
+	0x85,  0x00,  0xA0,  0x8A,  0x44,  0x02,  0x44,  0x24,  0x42,  0x08,  0x00,  0x80,  0x10,  0x02,  0x00,  0xC0, 	/* 01EE0 */
+	0x30,  0x00,  0x00,  0x86,  0x00,  0x00,  0x00,  0x1F,  0x80,  0x00,  0x00,  0x07,  0xFE,  0x02,  0x00,  0x20, 	/* 01EF0 */
+	0x04,  0x00,  0x80,  0x30,  0x00,  0x00,  0x87,  0x00,  0x00,  0x0A,  0x1F,  0xA0,  0x00,  0x00,  0x07,  0xFE, 	/* 01F00 */
+	0x02,  0x00,  0x20,  0x04,  0x00,  0x80,  0x30,  0x00,  0x00,  0x88,  0x10,  0x01,  0x00,  0x10,  0x01,  0x00, 	/* 01F10 */
+	0x1C,  0x01,  0x30,  0x10,  0x81,  0x00,  0x10,  0x01,  0x00,  0x10,  0x00,  0x00,  0x89,  0x10,  0x01,  0x14, 	/* 01F20 */
+	0x11,  0x41,  0x00,  0x1C,  0x01,  0x30,  0x10,  0x81,  0x00,  0x10,  0x01,  0x00,  0x10,  0x00,  0x00,  0x8A, 	/* 01F30 */
+	0x02,  0x00,  0x20,  0x02,  0x07,  0xFE,  0x02,  0x00,  0x20,  0x02,  0x00,  0x40,  0x04,  0x00,  0x80,  0x30, 	/* 01F40 */
+	0x00,  0x00,  0x8B,  0x00,  0x00,  0x00,  0x00,  0x01,  0xF8,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x7F, 	/* 01F50 */
+	0xE0,  0x00,  0x00,  0x00,  0x00,  0x8C,  0x00,  0x00,  0x00,  0x1F,  0xC0,  0x04,  0x00,  0x80,  0xC8,  0x03, 	/* 01F60 */
+	0x00,  0x28,  0x04,  0x41,  0x82,  0x60,  0x00,  0x00,  0x8D,  0x04,  0x00,  0x40,  0x3F,  0x80,  0x08,  0x01, 	/* 01F70 */
+	0x00,  0x60,  0x1D,  0x86,  0x46,  0x04,  0x00,  0x40,  0x04,  0x00,  0x00,  0x8E,  0x00,  0x00,  0x00,  0x00, 	/* 01F80 */
+	0x40,  0x04,  0x00,  0x80,  0x08,  0x01,  0x00,  0x20,  0x0C,  0x03,  0x00,  0x00,  0x00,  0x00,  0x8F,  0x00, 	/* 01F90 */
+	0x00,  0x00,  0x00,  0x00,  0x90,  0x08,  0x80,  0x88,  0x10,  0x41,  0x04,  0x10,  0x22,  0x02,  0x40,  0x20, 	/* 01FA0 */
+	0x00,  0x90,  0x00,  0x00,  0x05,  0x00,  0x50,  0x90,  0x08,  0x80,  0x88,  0x10,  0x41,  0x04,  0x10,  0x22, 	/* 01FB0 */
+	0x02,  0x40,  0x20,  0x00,  0x91,  0x00,  0x00,  0x06,  0x00,  0x90,  0x96,  0x08,  0x80,  0x88,  0x10,  0x41, 	/* 01FC0 */
+	0x04,  0x10,  0x22,  0x02,  0x40,  0x20,  0x00,  0x92,  0x00,  0x02,  0x00,  0x20,  0x02,  0x00,  0x21,  0x83, 	/* 01FD0 */
+	0xE0,  0x20,  0x02,  0x00,  0x20,  0x01,  0xFC,  0x00,  0x00,  0x00,  0x93,  0x00,  0x02,  0x0A,  0x20,  0xA2, 	/* 01FE0 */
+	0x00,  0x23,  0x83,  0xC0,  0x20,  0x02,  0x00,  0x20,  0x01,  0xFC,  0x00,  0x00,  0x00,  0x94,  0x00,  0x02, 	/* 01FF0 */
+	0x0C,  0x21,  0x22,  0x0C,  0x23,  0x83,  0xC0,  0x20,  0x02,  0x00,  0x20,  0x01,  0xFC,  0x00,  0x00,  0x00, 	/* 02000 */
+	0x95,  0x00,  0x00,  0x00,  0x7F,  0xC0,  0x04,  0x00,  0x40,  0x08,  0x00,  0x80,  0x10,  0x02,  0x00,  0xC0, 	/* 02010 */
+	0x30,  0x00,  0x00,  0x96,  0x01,  0x40,  0x14,  0x7F,  0x80,  0x08,  0x00,  0x80,  0x10,  0x01,  0x00,  0x20, 	/* 02020 */
+	0x04,  0x01,  0x80,  0x60,  0x00,  0x00,  0x97,  0x00,  0xC0,  0x12,  0x7F,  0xC0,  0x08,  0x00,  0x80,  0x10, 	/* 02030 */
+	0x01,  0x00,  0x20,  0x04,  0x01,  0x80,  0x60,  0x00,  0x00,  0x98,  0x00,  0x00,  0x00,  0x00,  0x00,  0xC0, 	/* 02040 */
+	0x12,  0x02,  0x10,  0x40,  0x80,  0x04,  0x00,  0x20,  0x00,  0x00,  0x00,  0x00,  0x99,  0x00,  0x00,  0x0A, 	/* 02050 */
+	0x00,  0xA0,  0xC0,  0x12,  0x02,  0x10,  0x40,  0x80,  0x04,  0x00,  0x20,  0x00,  0x00,  0x00,  0x00,  0x9A, 	/* 02060 */
+	0x00,  0x00,  0x0C,  0x01,  0x20,  0xCC,  0x12,  0x02,  0x10,  0x40,  0x80,  0x04,  0x00,  0x20,  0x00,  0x00, 	/* 02070 */
+	0x00,  0x00,  0x9B,  0x04,  0x00,  0x40,  0x04,  0x07,  0xFC,  0x04,  0x01,  0x50,  0x14,  0x82,  0x44,  0x24, 	/* 02080 */
+	0x44,  0x40,  0x0C,  0x00,  0x00,  0x9C,  0x08,  0x00,  0x94,  0x09,  0x4F,  0xF8,  0x08,  0x02,  0xA0,  0x29, 	/* 02090 */
+	0x04,  0x88,  0x48,  0x88,  0x80,  0x18,  0x00,  0x00,  0x9D,  0x08,  0x00,  0x8C,  0x09,  0x2F,  0xEC,  0x08, 	/* 020A0 */
+	0x02,  0xA0,  0x29,  0x04,  0x88,  0x48,  0x88,  0x80,  0x18,  0x00,  0x00,  0x9E,  0x00,  0x00,  0x00,  0x7F, 	/* 020B0 */
+	0xC0,  0x04,  0x00,  0x80,  0x10,  0x32,  0x00,  0xC0,  0x02,  0x00,  0x10,  0x00,  0x00,  0x00,  0x9F,  0x00, 	/* 020C0 */
+	0x01,  0xC0,  0x03,  0x00,  0x08,  0x00,  0x01,  0xC0,  0x02,  0x00,  0x00,  0x38,  0x00,  0x60,  0x01,  0x80, 	/* 020D0 */
+	0x00,  0xA0,  0x00,  0x00,  0x40,  0x04,  0x00,  0x40,  0x08,  0x00,  0xA0,  0x11,  0x01,  0x08,  0x27,  0x87, 	/* 020E0 */
+	0x84,  0x00,  0x40,  0x00,  0xA1,  0x00,  0x00,  0x04,  0x00,  0x40,  0x04,  0x0C,  0x40,  0x38,  0x00,  0x80, 	/* 020F0 */
+	0x14,  0x02,  0x20,  0xC0,  0x30,  0x00,  0x00,  0xA2,  0x00,  0x00,  0x00,  0x3F,  0x80,  0x80,  0x08,  0x07, 	/* 02100 */
+	0xFE,  0x08,  0x00,  0x80,  0x08,  0x00,  0x7C,  0x00,  0x00,  0x00,  0xA3,  0x00,  0x00,  0x00,  0x00,  0x00, 	/* 02110 */
+	0x00,  0x08,  0x00,  0x80,  0x0B,  0xC3,  0xC8,  0x05,  0x00,  0x40,  0x04,  0x00,  0x00,  0xA4,  0x00,  0x01, 	/* 02120 */
+	0x00,  0x10,  0x01,  0x1E,  0x1E,  0x4E,  0x88,  0x09,  0x00,  0x80,  0x04,  0x00,  0x40,  0x04,  0x00,  0x00, 	/* 02130 */
+	0xA5,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x1E,  0x00,  0x20,  0x02,  0x03,  0xF8, 	/* 02140 */
+	0x00,  0x00,  0x00,  0xA6,  0x00,  0x00,  0x00,  0x00,  0x03,  0xF8,  0x00,  0x80,  0x08,  0x01,  0x00,  0x10, 	/* 02150 */
+	0x01,  0x07,  0xFE,  0x00,  0x00,  0x00,  0xA7,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x03,  0xF0, 	/* 02160 */
+	0x01,  0x01,  0xF0,  0x01,  0x00,  0x10,  0x3F,  0x00,  0x00,  0xA8,  0x00,  0x00,  0x00,  0x7F,  0xC0,  0x04, 	/* 02170 */
+	0x00,  0x43,  0xFC,  0x00,  0x40,  0x04,  0x00,  0x47,  0xFC,  0x00,  0x40,  0x00,  0xA9,  0x00,  0x03,  0xF8, 	/* 02180 */
+	0x00,  0x00,  0x00,  0x7F,  0xC0,  0x04,  0x00,  0x80,  0x08,  0x01,  0x00,  0x60,  0x38,  0x00,  0x00,  0xAA, 	/* 02190 */
+	0x00,  0x01,  0x08,  0x10,  0x81,  0x08,  0x10,  0x81,  0x08,  0x10,  0x80,  0x10,  0x01,  0x00,  0x20,  0x0C, 	/* 021A0 */
+	0x00,  0x00,  0xAB,  0x00,  0x00,  0x20,  0x12,  0x01,  0x20,  0x12,  0x01,  0x22,  0x12,  0x21,  0x24,  0x22, 	/* 021B0 */
+	0x82,  0x30,  0x40,  0x00,  0x00,  0xAC,  0x00,  0x02,  0x00,  0x20,  0x02,  0x00,  0x20,  0x02,  0x00,  0x20, 	/* 021C0 */
+	0x82,  0x10,  0x22,  0x02,  0xC0,  0x30,  0x00,  0x00,  0xAD,  0x00,  0x00,  0x00,  0x3F,  0xC2,  0x04,  0x20, 	/* 021D0 */
+	0x42,  0x04,  0x20,  0x42,  0x04,  0x3F,  0xC2,  0x04,  0x00,  0x00,  0x00,  0xAE,  0x00,  0x00,  0x00,  0x00, 	/* 021E0 */
+	0x00,  0x00,  0x00,  0x03,  0xF0,  0x21,  0x02,  0x10,  0x02,  0x00,  0x40,  0x18,  0x00,  0x00,  0xAF,  0x00, 	/* 021F0 */
+	0x00,  0x00,  0x3F,  0xC2,  0x04,  0x20,  0x42,  0x04,  0x00,  0x80,  0x08,  0x01,  0x00,  0x60,  0x18,  0x00, 	/* 02200 */
+	0x00,  0xB0,  0x01,  0x00,  0x10,  0x01,  0x07,  0xFC,  0x11,  0x01,  0x10,  0x11,  0x07,  0xFE,  0x01,  0x00, 	/* 02210 */
+	0x10,  0x01,  0x00,  0x00,  0xB1,  0x00,  0x00,  0x00,  0x3F,  0x80,  0x08,  0x05,  0x00,  0x60,  0x04,  0x00, 	/* 02220 */
+	0x40,  0x04,  0x07,  0xFC,  0x00,  0x00,  0x00,  0xB2,  0x00,  0x00,  0x00,  0x3F,  0xC0,  0x04,  0x00,  0x41, 	/* 02230 */
+	0xFC,  0x00,  0x80,  0x08,  0x01,  0x00,  0x60,  0x38,  0x00,  0x00,  0xB3,  0x00,  0x00,  0x00,  0x60,  0x01, 	/* 02240 */
+	0x04,  0x00,  0x40,  0x08,  0x00,  0x80,  0x10,  0x02,  0x00,  0xC0,  0x70,  0x00,  0x00,  0xB4,  0x04,  0xA0, 	/* 02250 */
+	0x4A,  0x04,  0x07,  0xFC,  0x40,  0x44,  0x04,  0x00,  0x80,  0x08,  0x01,  0x00,  0x60,  0x18,  0x00,  0x00, 	/* 02260 */
+	0xB5,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x08,  0x00,  0x80,  0x3F,  0x00,  0x90,  0x09,  0x01,  0x10, 	/* 02270 */
+	0x26,  0x00,  0x00,  0xB6,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x08,  0x00,  0x80,  0x0F,  0x83,  0x20, 	/* 02280 */
+	0x02,  0x00,  0x40,  0x18,  0x00,  0x00,  0xBB,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x60, 	/* 02290 */
+	0x06,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0xBC,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00, 	/* 022A0 */
+	0x00,  0x03,  0xFC,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0xBD,  0x00,  0x00,  0x00, 	/* 022B0 */
+	0x00,  0x00,  0x00,  0x00,  0x03,  0x00,  0x0C,  0x00,  0x20,  0x01,  0x00,  0x00,  0x00,  0x00,  0x00,  0xBE, 	/* 022C0 */
+	0x00,  0x00,  0x00,  0x01,  0x00,  0x48,  0x02,  0x03,  0x00,  0x0C,  0x00,  0x20,  0x01,  0x00,  0x00,  0x00, 	/* 022D0 */
+	0x00,  0x00,  0x80,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x07,  0xFE,  0x00,  0x00,  0x00,  0x00, 	/* 022E0 */
+	0x00,  0x00,  0x00,  0x00,  0x00,  0x81,  0x00,  0x0F,  0xFE,  0x04,  0x00,  0x40,  0x04,  0x00,  0x40,  0x04, 	/* 022F0 */
+	0x00,  0x40,  0x04,  0x00,  0x40,  0x04,  0x00,  0xC0,  0x83,  0x10,  0x01,  0x00,  0x10,  0x01,  0x00,  0x11, 	/* 02300 */
+	0xEF,  0xE0,  0x10,  0x01,  0x00,  0x10,  0x01,  0x04,  0x10,  0x40,  0xFC,  0x87,  0x00,  0x0F,  0xFE,  0x08, 	/* 02310 */
+	0x00,  0x80,  0x0F,  0x80,  0x88,  0x08,  0x80,  0x88,  0x10,  0x81,  0x08,  0x20,  0x84,  0x30,  0x88,  0x04, 	/* 02320 */
+	0x00,  0x40,  0x04,  0x0F,  0xFE,  0x04,  0x00,  0x40,  0x24,  0x01,  0x40,  0x0C,  0x00,  0xA0,  0x31,  0x8C, 	/* 02330 */
+	0x06,  0x89,  0x00,  0x07,  0xFC,  0x00,  0x00,  0x00,  0x00,  0x03,  0xF8,  0x00,  0x00,  0x00,  0x00,  0x00, 	/* 02340 */
+	0x00,  0xFF,  0xE0,  0x00,  0x8A,  0x04,  0x00,  0x40,  0x04,  0x00,  0x40,  0x04,  0x00,  0x7C,  0x04,  0x00, 	/* 02350 */
+	0x40,  0x04,  0x00,  0x40,  0x04,  0x0F,  0xFE,  0x8B,  0x00,  0x0F,  0xFE,  0x04,  0x00,  0x40,  0x07,  0x00, 	/* 02360 */
+	0x48,  0x04,  0x40,  0x40,  0x04,  0x00,  0x40,  0x04,  0x00,  0x40,  0x8D,  0x00,  0x07,  0xFE,  0x02,  0x00, 	/* 02370 */
+	0x40,  0x06,  0x00,  0xD8,  0x34,  0x4C,  0x42,  0x04,  0x00,  0x40,  0x04,  0x00,  0x40,  0x8E,  0x10,  0x01, 	/* 02380 */
+	0x00,  0x1F,  0xC1,  0x00,  0x1F,  0x02,  0x10,  0x01,  0x0F,  0xFE,  0x01,  0x00,  0x10,  0x01,  0x00,  0x60, 	/* 02390 */
+	0x90,  0x00,  0x0F,  0xFE,  0x04,  0x02,  0x7C,  0x24,  0x02,  0x40,  0x3F,  0xE2,  0x02,  0x00,  0x20,  0x02, 	/* 023A0 */
+	0x00,  0x40,  0x18,  0x91,  0x00,  0x03,  0xF8,  0x04,  0x80,  0x48,  0x04,  0x87,  0xFE,  0x04,  0x80,  0x88, 	/* 023B0 */
+	0x08,  0x80,  0x88,  0x08,  0x87,  0xFE,  0x94,  0x00,  0x01,  0xF8,  0x10,  0x81,  0x08,  0x1F,  0x81,  0x08, 	/* 023C0 */
+	0x10,  0x81,  0xF8,  0x10,  0x81,  0x08,  0x10,  0x87,  0xFE,  0x95,  0x00,  0x0F,  0xFE,  0x02,  0x00,  0x60, 	/* 023D0 */
+	0x0D,  0x83,  0x44,  0xC4,  0x20,  0x40,  0x04,  0x00,  0x40,  0x00,  0x0F,  0xFE,  0x96,  0x24,  0x82,  0x48, 	/* 023E0 */
+	0x24,  0x82,  0x48,  0xFF,  0xE2,  0x48,  0x24,  0x82,  0x48,  0x27,  0x82,  0x00,  0x20,  0x03,  0xFC,  0x97, 	/* 023F0 */
+	0x24,  0x82,  0x48,  0x24,  0x82,  0x48,  0x24,  0x8F,  0xFE,  0x24,  0x82,  0x48,  0x24,  0x82,  0x48,  0x24, 	/* 02400 */
+	0x83,  0xF8,  0x98,  0x00,  0x00,  0x18,  0x3E,  0x02,  0x00,  0x20,  0x03,  0xFC,  0x21,  0x02,  0x10,  0x21, 	/* 02410 */
+	0x02,  0x10,  0x21,  0x0F,  0xFE,  0x99,  0x00,  0x0F,  0xFF,  0x04,  0x00,  0x40,  0x7F,  0xE4,  0x62,  0x49, 	/* 02420 */
+	0x25,  0x0A,  0x60,  0xA4,  0x02,  0x40,  0x24,  0x06,  0x9E,  0x00,  0x03,  0xF0,  0x02,  0x00,  0x44,  0xF6, 	/* 02430 */
+	0x81,  0x70,  0x15,  0x02,  0x48,  0xC4,  0x60,  0xC0,  0x00,  0x0F,  0xFE,  0xA1,  0x00,  0x0F,  0xFE,  0x04, 	/* 02440 */
+	0x00,  0x40,  0xFF,  0xE8,  0x42,  0xA4,  0xAA,  0x4A,  0xA4,  0xAB,  0xFA,  0xA0,  0x28,  0x06,  0xA6,  0x20, 	/* 02450 */
+	0x81,  0x10,  0x12,  0x0F,  0xFE,  0x0A,  0x04,  0xA4,  0x2A,  0x42,  0xA8,  0x2B,  0x00,  0xA0,  0xFF,  0xE0, 	/* 02460 */
+	0x00,  0xAA,  0x04,  0x00,  0x40,  0x0A,  0x01,  0x10,  0x24,  0x84,  0x44,  0x84,  0x20,  0x40,  0x04,  0x00, 	/* 02470 */
+	0x40,  0x04,  0x00,  0x40,  0xAD,  0x04,  0x00,  0x40,  0x7F,  0xC4,  0x44,  0x44,  0x44,  0x44,  0x7F,  0xC0, 	/* 02480 */
+	0x40,  0x04,  0x00,  0x40,  0x04,  0x00,  0x40,  0xB1,  0x09,  0x00,  0x90,  0x49,  0x24,  0x92,  0x49,  0x24, 	/* 02490 */
+	0x92,  0x49,  0x27,  0x9E,  0x49,  0x20,  0x90,  0x11,  0x02,  0x10,  0xB2,  0x04,  0x00,  0x40,  0x7F,  0xC4, 	/* 024A0 */
+	0x44,  0x7F,  0xC0,  0x40,  0xFF,  0xE8,  0x42,  0xFF,  0xE0,  0x40,  0x04,  0x00,  0x40,  0xB6,  0x00,  0x00, 	/* 024B0 */
+	0x00,  0x00,  0x01,  0x00,  0x08,  0x00,  0x40,  0x04,  0x00,  0x20,  0x02,  0x00,  0x00,  0x00,  0x00,  0x00, 	/* 024C0 */
+	0xB8,  0x10,  0x01,  0x00,  0x10,  0x0F,  0xF0,  0x11,  0x01,  0x10,  0x51,  0x03,  0x10,  0x19,  0x02,  0x52, 	/* 024D0 */
+	0x45,  0x28,  0x0E,  0xB9,  0x00,  0x03,  0xF8,  0x20,  0x82,  0x88,  0x24,  0x82,  0x48,  0xFF,  0xE2,  0x08, 	/* 024E0 */
+	0x20,  0x84,  0x08,  0x40,  0x88,  0x18,  0xBB,  0x08,  0x00,  0x40,  0x7F,  0xC0,  0x40,  0x04,  0x00,  0x40, 	/* 024F0 */
+	0x3F,  0x80,  0x40,  0x04,  0x00,  0x40,  0x04,  0x0F,  0xFE,  0xBC,  0x11,  0x01,  0x10,  0x11,  0x0F,  0xFC, 	/* 02500 */
+	0x11,  0x01,  0x50,  0x13,  0x0F,  0xFE,  0x11,  0x01,  0x10,  0x21,  0x04,  0x10,  0xBF,  0x02,  0x00,  0x20, 	/* 02510 */
+	0x02,  0x00,  0x20,  0x02,  0x00,  0x20,  0x02,  0x00,  0x20,  0x04,  0x00,  0x40,  0x08,  0x03,  0x00,  0x82, 	/* 02520 */
+	0x00,  0x81,  0x08,  0x10,  0x81,  0x08,  0x28,  0x80,  0x90,  0x05,  0x00,  0x20,  0x05,  0x00,  0x88,  0x30, 	/* 02530 */
+	0x4C,  0x03,  0x83,  0x00,  0x07,  0xF0,  0x09,  0x00,  0x90,  0x0B,  0xC0,  0x84,  0x08,  0x40,  0x84,  0x10, 	/* 02540 */
+	0x41,  0x04,  0x20,  0x44,  0x18,  0x85,  0x08,  0x00,  0x80,  0x0F,  0x01,  0x10,  0x11,  0x02,  0x20,  0x42, 	/* 02550 */
+	0x00,  0x40,  0x0A,  0x01,  0x10,  0x20,  0x8C,  0x06,  0x8B,  0x04,  0x00,  0x40,  0x3F,  0xC0,  0x04,  0x00, 	/* 02560 */
+	0x80,  0x10,  0x02,  0x02,  0x40,  0x28,  0x03,  0x00,  0x4C,  0x08,  0x3F,  0x8D,  0x20,  0x02,  0x00,  0x3F, 	/* 02570 */
+	0xE2,  0x40,  0x44,  0x04,  0x7C,  0x84,  0x00,  0x40,  0x07,  0xC0,  0x40,  0x04,  0x00,  0x40,  0x8E,  0x01, 	/* 02580 */
+	0x87,  0xE0,  0x04,  0x82,  0x48,  0x15,  0x01,  0x40,  0xFF,  0xE0,  0x40,  0x04,  0x00,  0x40,  0x04,  0x00, 	/* 02590 */
+	0xC0,  0x8F,  0x03,  0xC7,  0xC0,  0x04,  0x00,  0x40,  0x7F,  0xC0,  0x08,  0x01,  0x04,  0x60,  0x58,  0x06, 	/* 025A0 */
+	0x00,  0x98,  0x08,  0x7E,  0x95,  0x01,  0xC7,  0xE0,  0x42,  0x07,  0xFE,  0x42,  0x07,  0xFE,  0x42,  0x05, 	/* 025B0 */
+	0xFC,  0x52,  0x49,  0x24,  0x93,  0x80,  0x20,  0x96,  0x03,  0x87,  0xC0,  0x04,  0x0F,  0xFE,  0x04,  0x01, 	/* 025C0 */
+	0x50,  0xF5,  0x61,  0x58,  0x15,  0x23,  0x52,  0xD4,  0xE0,  0x40,  0x97,  0x03,  0x83,  0xE0,  0x04,  0x0F, 	/* 025D0 */
+	0xFE,  0x24,  0x87,  0xFC,  0x24,  0x8F,  0xFE,  0x0E,  0x03,  0x58,  0xC4,  0x60,  0x40,  0x98,  0x03,  0x83, 	/* 025E0 */
+	0xC0,  0x04,  0x0F,  0xFE,  0x15,  0x07,  0x56,  0x15,  0x83,  0x52,  0xD4,  0xE0,  0xE0,  0x35,  0x8C,  0x46, 	/* 025F0 */
+	0x99,  0x00,  0x03,  0xF8,  0x00,  0x80,  0x10,  0x02,  0x00,  0x40,  0x08,  0x01,  0x00,  0x20,  0x04,  0x02, 	/* 02600 */
+	0x40,  0x23,  0xFE,  0x9D,  0x08,  0x00,  0x80,  0x08,  0x07,  0xF0,  0x09,  0x00,  0x90,  0x09,  0x00,  0x90, 	/* 02610 */
+	0x11,  0x01,  0x12,  0x21,  0x24,  0x0E,  0x9E,  0x10,  0x01,  0x00,  0x3F,  0xE2,  0x00,  0x5F,  0x88,  0x10, 	/* 02620 */
+	0x02,  0x00,  0xC0,  0x10,  0x02,  0x02,  0x20,  0x21,  0xFE,  0x9F,  0x04,  0x02,  0x40,  0x24,  0x02,  0x78, 	/* 02630 */
+	0x3C,  0x8E,  0x48,  0x24,  0x82,  0x48,  0x27,  0x02,  0x02,  0x20,  0x21,  0xFE,  0xA2,  0x22,  0x02,  0x20, 	/* 02640 */
+	0x22,  0x0A,  0xA0,  0xAA,  0x0A,  0xA0,  0xAA,  0x0A,  0xA0,  0xAA,  0x0F,  0xA2,  0x82,  0x20,  0x1E,  0xB1, 	/* 02650 */
+	0x05,  0x00,  0x90,  0x71,  0x01,  0x10,  0x11,  0x0F,  0xF0,  0x11,  0x01,  0x10,  0x7D,  0x04,  0x52,  0x45, 	/* 02660 */
+	0x27,  0xCE,  0xB3,  0x0D,  0x0F,  0x50,  0x95,  0x05,  0x90,  0x01,  0x07,  0xD0,  0x09,  0x01,  0x10,  0xFD, 	/* 02670 */
+	0x01,  0x12,  0x11,  0x23,  0x0E,  0xBE,  0x22,  0x0F,  0xA0,  0x23,  0xEF,  0xC0,  0x8B,  0xCF,  0x84,  0x88, 	/* 02680 */
+	0x8F,  0x90,  0x22,  0x0F,  0xC2,  0x24,  0x22,  0x3E,  0x80,  0x08,  0x01,  0xF0,  0x22,  0x0F,  0xF8,  0x24, 	/* 02690 */
+	0x83,  0xF8,  0x24,  0x87,  0xFC,  0x44,  0x47,  0xFC,  0x04,  0x20,  0x3E,  0x82,  0x0E,  0x8F,  0x48,  0x54, 	/* 026A0 */
+	0x89,  0x28,  0x7C,  0x82,  0x88,  0xFE,  0x8A,  0xA8,  0xFA,  0x8A,  0xA9,  0x92,  0x9A,  0xE7,  0x85,  0x04, 	/* 026B0 */
+	0x00,  0x40,  0x04,  0x00,  0x40,  0x04,  0x00,  0x40,  0x04,  0x00,  0x40,  0x04,  0x00,  0x40,  0x04,  0x00, 	/* 026C0 */
+	0xC0,  0x86,  0x00,  0x07,  0xFC,  0x00,  0x80,  0x10,  0x06,  0x00,  0x40,  0x04,  0x00,  0x40,  0x04,  0x00, 	/* 026D0 */
+	0x40,  0x04,  0x00,  0xC0,  0x88,  0x00,  0x03,  0xF8,  0x01,  0x01,  0xA0,  0x04,  0x0F,  0xFE,  0x04,  0x40, 	/* 026E0 */
+	0x48,  0x04,  0x00,  0x40,  0x04,  0x00,  0xC0,  0x89,  0x08,  0x00,  0xF0,  0x31,  0x00,  0x20,  0x3F,  0x80, 	/* 026F0 */
+	0x48,  0xFF,  0xE0,  0x48,  0x3F,  0x80,  0x40,  0x04,  0x00,  0xC0,  0x8A,  0x04,  0x0F,  0xFE,  0x24,  0x81, 	/* 02700 */
+	0x50,  0x7F,  0xC0,  0x44,  0xFF,  0xE0,  0x44,  0x7F,  0xC0,  0x40,  0x04,  0x00,  0xC0,  0x8B,  0x04,  0x0F, 	/* 02710 */
+	0xFE,  0x24,  0x83,  0xF8,  0x04,  0x07,  0xF8,  0x04,  0x8F,  0xFE,  0x04,  0x87,  0xF8,  0x04,  0x00,  0xC0, 	/* 02720 */
+	0x8C,  0x00,  0x00,  0x00,  0x7F,  0xC0,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x0F,  0xFE, 	/* 02730 */
+	0x00,  0x00,  0x00,  0x8E,  0x00,  0x07,  0xFC,  0x04,  0x00,  0x40,  0x04,  0x0F,  0xFE,  0x04,  0x00,  0x40, 	/* 02740 */
+	0x04,  0x00,  0x40,  0x04,  0x00,  0xC0,  0x91,  0x00,  0x03,  0xF8,  0x00,  0x00,  0x00,  0xFF,  0xE0,  0x40, 	/* 02750 */
+	0x04,  0x00,  0x90,  0x08,  0x81,  0x38,  0x7C,  0x40,  0x04,  0x92,  0x00,  0x07,  0xFC,  0x10,  0x01,  0x00, 	/* 02760 */
+	0x1F,  0x01,  0x10,  0x21,  0x02,  0x10,  0x7E,  0x00,  0x20,  0x02,  0x0F,  0xFE,  0x94,  0x00,  0x03,  0xFC, 	/* 02770 */
+	0x04,  0x00,  0x40,  0x04,  0x03,  0xF8,  0x04,  0x80,  0x48,  0x08,  0x80,  0x88,  0x08,  0x87,  0xFE,  0x95, 	/* 02780 */
+	0x08,  0x80,  0x88,  0x08,  0x87,  0xFE,  0x08,  0x80,  0x88,  0x08,  0x87,  0xFE,  0x08,  0x80,  0x88,  0x10, 	/* 02790 */
+	0x82,  0x08,  0x98,  0x00,  0x07,  0xFC,  0x00,  0x03,  0xF8,  0x20,  0x82,  0x08,  0x3F,  0x82,  0x08,  0x20, 	/* 027A0 */
+	0x83,  0xF8,  0x00,  0x0F,  0xFE,  0x99,  0x00,  0x0F,  0xFE,  0x10,  0x01,  0x00,  0x1F,  0x01,  0x90,  0x25, 	/* 027B0 */
+	0x03,  0x10,  0x4A,  0x04,  0xA0,  0x02,  0x0F,  0xFE,  0x9B,  0x12,  0x05,  0x20,  0x5A,  0x45,  0x38,  0x52, 	/* 027C0 */
+	0x25,  0xE2,  0xF1,  0xE0,  0x00,  0x3F,  0x80,  0x00,  0x00,  0x0F,  0xFE,  0x9C,  0x00,  0x07,  0xFE,  0x09, 	/* 027D0 */
+	0x00,  0x90,  0x3F,  0xC2,  0x94,  0x29,  0x42,  0x94,  0x3F,  0xC0,  0x90,  0x09,  0x07,  0xFE,  0x9E,  0x00, 	/* 027E0 */
+	0x0F,  0xFE,  0x09,  0x00,  0x90,  0x79,  0xE4,  0x02,  0x40,  0x27,  0x9E,  0x09,  0x00,  0x90,  0x09,  0x0F, 	/* 027F0 */
+	0xFE,  0x9F,  0x00,  0x07,  0xFC,  0x04,  0x00,  0x80,  0x1F,  0xEF,  0x32,  0x92,  0xA9,  0x2C,  0x93,  0x4F, 	/* 02800 */
+	0x22,  0x0C,  0x0F,  0xFE,  0xA0,  0x00,  0x00,  0x00,  0x00,  0x00,  0x40,  0x04,  0x00,  0x40,  0xFF,  0xE0, 	/* 02810 */
+	0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0xA1,  0x04,  0x00,  0x40,  0x04,  0x0F,  0xFE,  0x20,  0x02, 	/* 02820 */
+	0x00,  0x20,  0x02,  0x00,  0x20,  0x02,  0x00,  0x1F,  0xC0,  0x00,  0xA2,  0x04,  0x00,  0x40,  0xFF,  0xE0, 	/* 02830 */
+	0x00,  0x1E,  0x01,  0x20,  0x12,  0x01,  0x20,  0x12,  0x02,  0x22,  0x22,  0x24,  0x1E,  0xA4,  0x04,  0x00, 	/* 02840 */
+	0x40,  0xFF,  0xE1,  0x10,  0x10,  0x82,  0x14,  0x51,  0x00,  0xA0,  0x04,  0x00,  0xA0,  0x31,  0x8C,  0x06, 	/* 02850 */
+	0xA5,  0x04,  0x0F,  0xFE,  0x08,  0x00,  0xA0,  0x72,  0x01,  0x40,  0x0C,  0x81,  0x90,  0x62,  0x00,  0xD0, 	/* 02860 */
+	0x30,  0x8C,  0x04,  0xA6,  0x04,  0x00,  0x40,  0x7F,  0xE0,  0x90,  0x09,  0x02,  0x94,  0x29,  0x24,  0x92, 	/* 02870 */
+	0x89,  0x21,  0x10,  0x11,  0x02,  0x30,  0xA8,  0x04,  0x0F,  0xFE,  0x3F,  0x82,  0x08,  0x3F,  0x80,  0x00, 	/* 02880 */
+	0x7F,  0xC0,  0x10,  0x06,  0x00,  0x40,  0x04,  0x00,  0xC0,  0xAB,  0x04,  0x0F,  0xFE,  0x3F,  0x82,  0x08, 	/* 02890 */
+	0x3F,  0x80,  0x00,  0x3F,  0x80,  0x20,  0xFF,  0xE0,  0x40,  0x04,  0x00,  0xC0,  0xAC,  0x04,  0x0F,  0xFE, 	/* 028A0 */
+	0x00,  0x03,  0xF8,  0x20,  0x82,  0x08,  0x3F,  0x80,  0x40,  0x24,  0x82,  0x44,  0x44,  0x40,  0xC0,  0xAD, 	/* 028B0 */
+	0x04,  0x0F,  0xFE,  0x00,  0x03,  0xF8,  0x20,  0x8F,  0xFE,  0x80,  0x27,  0xFC,  0x04,  0x00,  0x40,  0x04, 	/* 028C0 */
+	0x00,  0xC0,  0xAE,  0x04,  0x0F,  0xFE,  0x00,  0x03,  0xF8,  0x20,  0x83,  0xF8,  0x00,  0x0F,  0xFE,  0x8A, 	/* 028D0 */
+	0x20,  0xA0,  0x12,  0x26,  0x1E,  0xB0,  0x04,  0x0F,  0xFE,  0x00,  0x03,  0xF8,  0x20,  0x83,  0xF8,  0x20, 	/* 028E0 */
+	0x83,  0xF8,  0x05,  0x02,  0x48,  0x44,  0x40,  0xC0,  0xB3,  0x04,  0x0F,  0xFE,  0x00,  0x03,  0xF8,  0x20, 	/* 028F0 */
+	0x8F,  0xFE,  0x83,  0x23,  0xC0,  0x07,  0xC7,  0xC0,  0x04,  0x20,  0x3E,  0xB6,  0x04,  0x0F,  0xFE,  0x2E, 	/* 02900 */
+	0x82,  0xA8,  0x2E,  0x83,  0xF8,  0x00,  0x01,  0xF0,  0x11,  0x01,  0xF0,  0x11,  0x0F,  0xFE,  0xBA,  0x04, 	/* 02910 */
+	0x00,  0x40,  0x04,  0x00,  0x40,  0x04,  0x00,  0x40,  0x0A,  0x00,  0xA0,  0x11,  0x02,  0x08,  0x40,  0x48, 	/* 02920 */
+	0x02,  0x80,  0x11,  0x01,  0x10,  0x11,  0x02,  0x10,  0x3F,  0xE6,  0x10,  0xA1,  0x02,  0x10,  0x21,  0x02, 	/* 02930 */
+	0x10,  0x21,  0x02,  0x10,  0x81,  0x10,  0x01,  0x00,  0x27,  0xC2,  0x00,  0x60,  0x0A,  0x00,  0x20,  0x02, 	/* 02940 */
+	0x00,  0x20,  0x02,  0x00,  0x2F,  0xE2,  0x00,  0x82,  0x12,  0x01,  0x20,  0x12,  0x02,  0xFE,  0x22,  0x26, 	/* 02950 */
+	0x22,  0xA2,  0x22,  0x22,  0x22,  0x22,  0x42,  0x24,  0x22,  0x8C,  0x84,  0x00,  0x03,  0xFE,  0x22,  0x02, 	/* 02960 */
+	0x20,  0x22,  0x02,  0x20,  0x22,  0x02,  0x50,  0x45,  0x04,  0x88,  0x90,  0x42,  0x02,  0x86,  0x11,  0x01, 	/* 02970 */
+	0x10,  0x11,  0x02,  0x10,  0x21,  0x86,  0x14,  0xA1,  0x22,  0x12,  0x21,  0x02,  0x10,  0x21,  0x02,  0x10, 	/* 02980 */
+	0x87,  0x24,  0x02,  0x40,  0x24,  0x05,  0xF8,  0x44,  0x8C,  0x48,  0x44,  0x84,  0x48,  0x48,  0x84,  0x8A, 	/* 02990 */
+	0x50,  0xA6,  0x06,  0x8A,  0x04,  0x00,  0x40,  0x0A,  0x01,  0x10,  0x3F,  0x8C,  0x06,  0x00,  0x03,  0xF8, 	/* 029A0 */
+	0x01,  0x00,  0x20,  0x02,  0x00,  0x40,  0x8B,  0x04,  0x00,  0x40,  0x0A,  0x01,  0x10,  0x20,  0x8D,  0x16, 	/* 029B0 */
+	0x11,  0x01,  0x10,  0x11,  0x02,  0x10,  0x21,  0x04,  0x10,  0x8D,  0x10,  0x01,  0xF8,  0x14,  0x82,  0x48, 	/* 029C0 */
+	0x24,  0x86,  0x4E,  0xA4,  0xA2,  0x42,  0x24,  0x22,  0x82,  0x28,  0x23,  0x0C,  0x8E,  0x10,  0x81,  0x08, 	/* 029D0 */
+	0x10,  0x81,  0x08,  0x10,  0x81,  0x08,  0x10,  0x82,  0x94,  0x29,  0x44,  0x62,  0x42,  0x28,  0x41,  0x8F, 	/* 029E0 */
+	0x12,  0x01,  0x20,  0x12,  0x02,  0x20,  0x22,  0x06,  0x20,  0xA4,  0x82,  0x44,  0x24,  0x42,  0x9E,  0x3E, 	/* 029F0 */
+	0x22,  0x02,  0x94,  0x10,  0x01,  0xFC,  0x10,  0x42,  0x08,  0x21,  0x06,  0x10,  0xBF,  0xE2,  0x10,  0x21, 	/* 02A00 */
+	0x02,  0x10,  0x21,  0x02,  0x30,  0x95,  0x11,  0x01,  0x10,  0x11,  0x02,  0x10,  0x3F,  0xF6,  0x10,  0xA1, 	/* 02A10 */
+	0x02,  0x10,  0x21,  0x02,  0x10,  0x2F,  0xC2,  0x00,  0x96,  0x11,  0x01,  0x50,  0x25,  0x02,  0x5C,  0x67, 	/* 02A20 */
+	0x4B,  0xD4,  0x25,  0x42,  0x54,  0x25,  0x82,  0x42,  0x24,  0x22,  0x3E,  0x97,  0x21,  0x02,  0x10,  0x21, 	/* 02A30 */
+	0x05,  0xFE,  0x41,  0x0C,  0x90,  0x49,  0x05,  0x50,  0x42,  0x04,  0x50,  0x48,  0x85,  0x06,  0x98,  0x10, 	/* 02A40 */
+	0x81,  0x08,  0x10,  0x82,  0xFE,  0x20,  0x86,  0x88,  0xA4,  0x82,  0x48,  0x20,  0x82,  0x08,  0x20,  0x82, 	/* 02A50 */
+	0x18,  0x99,  0x11,  0x01,  0x10,  0x11,  0x02,  0x92,  0x29,  0x26,  0x92,  0xA9,  0x22,  0x92,  0x29,  0x22, 	/* 02A60 */
+	0x92,  0x2F,  0xE2,  0x82,  0x9D,  0x04,  0x00,  0x40,  0x0A,  0x01,  0x10,  0x20,  0x8C,  0x06,  0x3F,  0x80, 	/* 02A70 */
+	0x40,  0x04,  0x00,  0x40,  0x04,  0x0F,  0xFE,  0x9E,  0x10,  0x01,  0xFE,  0x12,  0x22,  0x22,  0x22,  0x26, 	/* 02A80 */
+	0xA2,  0xAA,  0x23,  0x22,  0x22,  0x22,  0x42,  0x24,  0x22,  0x8C,  0x9F,  0x10,  0xC1,  0xF0,  0x11,  0x02, 	/* 02A90 */
+	0x10,  0x21,  0x07,  0xFE,  0xA1,  0x02,  0x10,  0x21,  0x02,  0x10,  0x21,  0x02,  0x10,  0xA3,  0x12,  0x81, 	/* 02AA0 */
+	0x24,  0x12,  0x02,  0x3E,  0x3E,  0x06,  0x10,  0xA1,  0x02,  0x10,  0x20,  0x82,  0x0A,  0x20,  0x62,  0x02, 	/* 02AB0 */
+	0xA4,  0x04,  0x00,  0x40,  0x0A,  0x01,  0x10,  0x3F,  0x8C,  0x06,  0x3F,  0xC0,  0x44,  0x04,  0x40,  0x58, 	/* 02AC0 */
+	0x04,  0x00,  0x40,  0xA5,  0x20,  0x42,  0x04,  0x28,  0x42,  0x44,  0x24,  0x42,  0x24,  0x20,  0x42,  0x84, 	/* 02AD0 */
+	0x30,  0xC4,  0x0A,  0x83,  0x10,  0xC0,  0xAD,  0x10,  0x01,  0xFE,  0x12,  0x22,  0x22,  0x2A,  0x26,  0x62, 	/* 02AE0 */
+	0xA3,  0x22,  0x2E,  0x22,  0x32,  0x42,  0x24,  0x22,  0x8C,  0xAE,  0x10,  0x01,  0x7E,  0x14,  0x02,  0x40, 	/* 02AF0 */
+	0x27,  0xC6,  0x64,  0xA5,  0x42,  0x58,  0x28,  0x82,  0x98,  0x32,  0x42,  0xC2,  0xB0,  0x23,  0x02,  0xC0, 	/* 02B00 */
+	0x29,  0xE4,  0x92,  0x49,  0x2C,  0x92,  0x49,  0x24,  0x92,  0x4B,  0x25,  0xDC,  0x41,  0x04,  0x10,  0xB2, 	/* 02B10 */
+	0x11,  0x01,  0x10,  0x1F,  0xE2,  0x92,  0x29,  0x26,  0x92,  0xAF,  0xE2,  0x10,  0x21,  0x02,  0x10,  0x21, 	/* 02B20 */
+	0x02,  0x10,  0xB6,  0x11,  0x01,  0x50,  0x15,  0x02,  0xFC,  0x29,  0x07,  0x10,  0xBF,  0xE2,  0x10,  0x21, 	/* 02B30 */
+	0x02,  0x10,  0x21,  0x02,  0x10,  0xB7,  0x12,  0x01,  0x20,  0x15,  0x02,  0x88,  0x30,  0x46,  0x4A,  0xA4, 	/* 02B40 */
+	0x92,  0x48,  0x24,  0x82,  0x88,  0x28,  0x83,  0x08,  0xBB,  0x10,  0xC1,  0xF0,  0x11,  0x02,  0x10,  0x21, 	/* 02B50 */
+	0x07,  0xFF,  0xA1,  0x02,  0x10,  0x21,  0x02,  0x10,  0x2F,  0xE2,  0x00,  0x81,  0x04,  0x00,  0x40,  0x0A, 	/* 02B60 */
+	0x01,  0x10,  0x24,  0x8C,  0x46,  0x04,  0x02,  0x78,  0x24,  0x02,  0x40,  0x24,  0x0F,  0xFE,  0x89,  0x22, 	/* 02B70 */
+	0x02,  0x20,  0x3F,  0xE4,  0x00,  0x4F,  0x0C,  0x90,  0x49,  0x04,  0x90,  0x49,  0x05,  0x12,  0x51,  0x26, 	/* 02B80 */
+	0x0E,  0x8A,  0x10,  0x01,  0xFC,  0x12,  0x42,  0x24,  0x7F,  0xEA,  0x24,  0x22,  0x42,  0xFC,  0x22,  0x02, 	/* 02B90 */
+	0x20,  0x24,  0x02,  0x80,  0x8D,  0x10,  0x01,  0xFE,  0x12,  0x02,  0x20,  0x22,  0x06,  0xF8,  0xA2,  0x82, 	/* 02BA0 */
+	0x48,  0x24,  0x82,  0x48,  0x24,  0x83,  0xFE,  0x8E,  0x11,  0x01,  0x10,  0x1F,  0xE2,  0x10,  0x21,  0x06, 	/* 02BB0 */
+	0xFE,  0xA0,  0x42,  0x44,  0x22,  0x82,  0x10,  0x26,  0x83,  0x86,  0x8F,  0x12,  0x01,  0x28,  0x12,  0x42, 	/* 02BC0 */
+	0x20,  0x3F,  0xE6,  0x20,  0xA2,  0x02,  0x50,  0x25,  0x02,  0x88,  0x30,  0x42,  0x02,  0x90,  0x12,  0x81, 	/* 02BD0 */
+	0x24,  0x12,  0x02,  0x3C,  0x3E,  0x06,  0x28,  0xA2,  0x82,  0x10,  0x23,  0x02,  0x4A,  0x38,  0x62,  0x02, 	/* 02BE0 */
+	0x91,  0x11,  0x01,  0x10,  0x11,  0x03,  0xFE,  0x21,  0x06,  0x38,  0xA3,  0x82,  0x54,  0x29,  0x23,  0x11, 	/* 02BF0 */
+	0x21,  0x02,  0x10,  0x9A,  0x04,  0x00,  0x40,  0x0A,  0x01,  0x10,  0x3F,  0x8C,  0x06,  0x00,  0x07,  0xFC, 	/* 02C00 */
+	0x0A,  0x01,  0x30,  0x7C,  0x80,  0x08,  0x9C,  0x22,  0x02,  0x20,  0x2F,  0x84,  0x28,  0x44,  0xAC,  0xA6, 	/* 02C10 */
+	0x52,  0x05,  0xFE,  0x42,  0x04,  0x20,  0x42,  0x04,  0x20,  0x9D,  0x10,  0x01,  0x7C,  0x10,  0x02,  0x00, 	/* 02C20 */
+	0x2F,  0xE6,  0x20,  0xA2,  0x02,  0x28,  0x24,  0x42,  0x5C,  0x2E,  0x22,  0x02,  0xAF,  0x11,  0x01,  0x10, 	/* 02C30 */
+	0x22,  0x02,  0x7E,  0x64,  0x2A,  0x42,  0x27,  0xE2,  0x42,  0x24,  0x22,  0x42,  0x24,  0x22,  0x7E,  0xB0, 	/* 02C40 */
+	0x11,  0x01,  0x10,  0x1F,  0xE2,  0x10,  0x21,  0x06,  0x10,  0xA7,  0xC2,  0x44,  0x24,  0x42,  0x44,  0x24, 	/* 02C50 */
+	0x42,  0x7C,  0xB4,  0x22,  0x03,  0x24,  0x2A,  0x44,  0xA8,  0x5F,  0xCC,  0x20,  0x42,  0x05,  0xFE,  0x42, 	/* 02C60 */
+	0x04,  0x20,  0x42,  0x04,  0x20,  0xB6,  0x12,  0x01,  0x20,  0x25,  0x02,  0x48,  0x6F,  0xCB,  0x02,  0x2F, 	/* 02C70 */
+	0xC2,  0x24,  0x22,  0x42,  0x38,  0x22,  0x02,  0x20,  0xB8,  0x11,  0x01,  0x10,  0x1F,  0xE2,  0x92,  0x2F, 	/* 02C80 */
+	0xE6,  0x92,  0xA9,  0x22,  0xFE,  0x21,  0x02,  0x10,  0x21,  0x02,  0x10,  0xBA,  0x10,  0x01,  0xFE,  0x10, 	/* 02C90 */
+	0x22,  0xFA,  0x20,  0x26,  0xF2,  0xA9,  0x22,  0x92,  0x2F,  0x22,  0x02,  0x20,  0x22,  0x06,  0xBC,  0x20, 	/* 02CA0 */
+	0x42,  0x84,  0x28,  0x44,  0xA4,  0x49,  0x4C,  0x84,  0x48,  0x44,  0x84,  0x4A,  0xC4,  0xCA,  0x71,  0x14, 	/* 02CB0 */
+	0x20,  0xBD,  0x28,  0x02,  0x80,  0x28,  0xE5,  0xEA,  0x4A,  0xAC,  0xAA,  0x4A,  0xA4,  0xAA,  0x52,  0xA5, 	/* 02CC0 */
+	0x2A,  0x62,  0xE4,  0xC0,  0x83,  0x10,  0x01,  0x7E,  0x25,  0x22,  0x52,  0x65,  0x2A,  0x7E,  0x25,  0x22, 	/* 02CD0 */
+	0x52,  0x25,  0x22,  0x52,  0x27,  0xE2,  0x00,  0x86,  0x10,  0x01,  0x7C,  0x14,  0x42,  0x44,  0x27,  0xC6, 	/* 02CE0 */
+	0x44,  0xA4,  0x42,  0x44,  0x27,  0xC2,  0x00,  0x20,  0x02,  0xFF,  0x87,  0x11,  0x01,  0xFE,  0x18,  0x22, 	/* 02CF0 */
+	0x00,  0x3F,  0xE6,  0x10,  0xA1,  0x02,  0x10,  0x21,  0x02,  0x10,  0x21,  0x02,  0x30,  0x8D,  0x11,  0x01, 	/* 02D00 */
+	0x10,  0x11,  0x02,  0xFE,  0x20,  0x46,  0x84,  0xA4,  0x42,  0x44,  0x24,  0x82,  0x48,  0x21,  0x03,  0xFE, 	/* 02D10 */
+	0x8E,  0x10,  0xC1,  0xF0,  0x19,  0x02,  0x90,  0x2F,  0xE6,  0x90,  0xA9,  0x02,  0x88,  0x2E,  0x83,  0x0A, 	/* 02D20 */
+	0x20,  0x62,  0xFA,  0x8F,  0x12,  0x01,  0x10,  0x1F,  0xE2,  0x10,  0x21,  0x06,  0x10,  0xA7,  0xC2,  0x10, 	/* 02D30 */
+	0x21,  0x02,  0x10,  0x21,  0x02,  0xFE,  0x90,  0x22,  0x02,  0x20,  0x22,  0x05,  0xFE,  0x42,  0x0C,  0x40, 	/* 02D40 */
+	0x47,  0xE4,  0x90,  0x51,  0x04,  0x10,  0x4F,  0xE4,  0x00,  0x91,  0x22,  0x02,  0x20,  0x22,  0x07,  0xFE, 	/* 02D50 */
+	0x42,  0x0C,  0x40,  0x44,  0x04,  0xFC,  0x54,  0x46,  0x44,  0x44,  0x44,  0x7C,  0x93,  0x11,  0x01,  0x10, 	/* 02D60 */
+	0x11,  0x03,  0xFE,  0x21,  0x06,  0x38,  0xA3,  0x82,  0x54,  0x29,  0x23,  0x7D,  0x21,  0x02,  0x10,  0x95, 	/* 02D70 */
+	0x10,  0x01,  0xFF,  0x10,  0x42,  0x04,  0x2F,  0x46,  0x94,  0xA9,  0x42,  0x94,  0x2F,  0x42,  0x04,  0x20, 	/* 02D80 */
+	0x42,  0x0C,  0x97,  0x12,  0x01,  0xFE,  0x18,  0x22,  0x82,  0x24,  0x06,  0x4C,  0xA7,  0x02,  0x40,  0x24, 	/* 02D90 */
+	0x02,  0x42,  0x24,  0x22,  0x3E,  0x99,  0x04,  0x00,  0x40,  0x0A,  0x03,  0x18,  0xDF,  0x60,  0x40,  0x7F, 	/* 02DA0 */
+	0xC0,  0x40,  0x24,  0x82,  0x44,  0x44,  0x40,  0xC0,  0x9A,  0x22,  0x02,  0xA0,  0x2A,  0x04,  0xFC,  0x52, 	/* 02DB0 */
+	0x0C,  0x20,  0x5F,  0xE4,  0x20,  0x45,  0x04,  0x50,  0x48,  0x85,  0x04,  0x9B,  0x25,  0x02,  0x50,  0x2F, 	/* 02DC0 */
+	0xC4,  0x54,  0x5F,  0xCD,  0x50,  0x5F,  0xE4,  0x52,  0x45,  0x24,  0x94,  0x49,  0x05,  0x10,  0x9C,  0x12, 	/* 02DD0 */
+	0x01,  0x20,  0x13,  0xE2,  0x50,  0x25,  0x06,  0x9E,  0xA1,  0x02,  0x10,  0x21,  0xE2,  0x10,  0x21,  0x02, 	/* 02DE0 */
+	0x10,  0x9D,  0x12,  0x01,  0x20,  0x17,  0xE2,  0x42,  0x28,  0x27,  0xF2,  0xA9,  0x22,  0x92,  0x2F,  0x22, 	/* 02DF0 */
+	0x02,  0x20,  0x22,  0x0C,  0x9E,  0x2F,  0xC2,  0x00,  0x2F,  0xE4,  0x20,  0x42,  0x0D,  0xFE,  0x44,  0x84, 	/* 02E00 */
+	0x48,  0x4F,  0x04,  0x18,  0x42,  0x45,  0xC2,  0xA9,  0x20,  0x03,  0xFC,  0x30,  0x45,  0xFC,  0x52,  0x4D, 	/* 02E10 */
+	0x24,  0x5F,  0xC5,  0xAC,  0x5A,  0xC6,  0xB5,  0x62,  0x34,  0x21,  0xAF,  0x14,  0x41,  0x28,  0x1F,  0xE2, 	/* 02E20 */
+	0x10,  0x21,  0x06,  0xFC,  0xA1,  0x02,  0x10,  0x3F,  0xE2,  0x10,  0x21,  0x02,  0x10,  0xB0,  0x10,  0x01, 	/* 02E30 */
+	0xFE,  0x11,  0x02,  0x20,  0x2F,  0xC6,  0x84,  0xA8,  0x42,  0xFC,  0x28,  0x42,  0x84,  0x28,  0x42,  0xFC, 	/* 02E40 */
+	0xB3,  0x22,  0x02,  0x20,  0x3F,  0xC4,  0x20,  0x42,  0x0D,  0xFE,  0x42,  0x04,  0x20,  0x5F,  0xC4,  0x20, 	/* 02E50 */
+	0x42,  0x07,  0xFE,  0xB5,  0x18,  0x41,  0x44,  0x24,  0x82,  0xFE,  0x64,  0x8A,  0x48,  0x3F,  0xF2,  0x48, 	/* 02E60 */
+	0x24,  0x82,  0x88,  0x28,  0x83,  0x08,  0xB6,  0x11,  0x01,  0x10,  0x1F,  0xE2,  0x10,  0x21,  0x06,  0xFC, 	/* 02E70 */
+	0xA0,  0x02,  0xFC,  0x28,  0x42,  0x84,  0x28,  0x42,  0xFC,  0xBB,  0x25,  0x02,  0x50,  0x25,  0x45,  0x54, 	/* 02E80 */
+	0x4D,  0x8C,  0x50,  0x4D,  0x85,  0x54,  0x45,  0x04,  0x92,  0x49,  0x25,  0x0E,  0xBC,  0x11,  0x01,  0x10, 	/* 02E90 */
+	0x1F,  0xE2,  0x28,  0x24,  0x46,  0xCA,  0xA4,  0x82,  0x28,  0x21,  0x02,  0x28,  0x24,  0x43,  0x82,  0xBF, 	/* 02EA0 */
+	0x11,  0x01,  0xFE,  0x11,  0x02,  0xFE,  0x29,  0x26,  0x92,  0xAF,  0xE2,  0x90,  0x25,  0x02,  0x30,  0x24, 	/* 02EB0 */
+	0x83,  0x86,  0x83,  0x10,  0x01,  0xFC,  0x18,  0x42,  0x84,  0x28,  0x46,  0xFC,  0xA0,  0x02,  0xA8,  0x2A, 	/* 02EC0 */
+	0x82,  0xAA,  0x32,  0xA2,  0x06,  0x86,  0x04,  0x00,  0x40,  0xFF,  0xE2,  0x48,  0x24,  0x83,  0x58,  0x4E, 	/* 02ED0 */
+	0x48,  0x42,  0x0E,  0x03,  0x58,  0xC4,  0x60,  0x40,  0x88,  0x12,  0x01,  0x3C,  0x14,  0x43,  0xA8,  0x21, 	/* 02EE0 */
+	0x06,  0x68,  0xB9,  0xE2,  0x22,  0x2D,  0x42,  0x08,  0x23,  0x02,  0xC0,  0x8B,  0x20,  0x23,  0xFA,  0x28, 	/* 02EF0 */
+	0xA4,  0x8A,  0x5E,  0xAD,  0x2A,  0x5A,  0xA6,  0x4A,  0x44,  0xA4,  0x82,  0x50,  0x26,  0x06,  0x8D,  0x12, 	/* 02F00 */
+	0x01,  0xFC,  0x12,  0x02,  0x20,  0x3F,  0xE6,  0x08,  0xBF,  0xE2,  0x88,  0x24,  0x82,  0x08,  0x20,  0x82, 	/* 02F10 */
+	0x18,  0x8F,  0x21,  0x02,  0x90,  0x2F,  0xE4,  0x90,  0x51,  0x0D,  0xFF,  0x41,  0x04,  0x38,  0x45,  0x45, 	/* 02F20 */
+	0x93,  0x41,  0x04,  0x10,  0x91,  0x12,  0x01,  0x20,  0x1F,  0xE2,  0x20,  0x27,  0xC6,  0x44,  0xAF,  0xC3, 	/* 02F30 */
+	0x44,  0x27,  0xC2,  0x44,  0x24,  0x42,  0x4C,  0x96,  0x04,  0x00,  0xA0,  0x31,  0x8D,  0xF6,  0x00,  0x07, 	/* 02F40 */
+	0xFC,  0x4A,  0x44,  0xA4,  0x7F,  0xC4,  0xA4,  0x4A,  0x44,  0xAC,  0x98,  0x22,  0x03,  0xFE,  0x30,  0x25, 	/* 02F50 */
+	0x0A,  0x43,  0x0C,  0xE0,  0x42,  0x04,  0x3E,  0x5E,  0x04,  0x20,  0x42,  0x24,  0x1E,  0x9B,  0x12,  0x41, 	/* 02F60 */
+	0x24,  0x12,  0x42,  0xFE,  0x22,  0x46,  0x24,  0xA2,  0x43,  0xFF,  0x20,  0x02,  0x24,  0x24,  0x22,  0x82, 	/* 02F70 */
+	0x9D,  0x11,  0x01,  0x10,  0x1F,  0xE2,  0x10,  0x22,  0x26,  0x54,  0xAD,  0x83,  0x50,  0x24,  0x82,  0x48, 	/* 02F80 */
+	0x27,  0x42,  0xC2,  0xA0,  0x22,  0x02,  0x20,  0x3F,  0xC5,  0x24,  0x4A,  0x8C,  0xA0,  0x7F,  0xE4,  0x20, 	/* 02F90 */
+	0x43,  0x04,  0x48,  0x48,  0x47,  0x02,  0xA1,  0x10,  0x01,  0xFE,  0x12,  0x82,  0x28,  0x2F,  0xE6,  0xAA, 	/* 02FA0 */
+	0xAA,  0xA2,  0xAA,  0x2A,  0xA2,  0xAA,  0x2F,  0xE2,  0x80,  0xAB,  0x21,  0x02,  0x10,  0x2F,  0xE4,  0x80, 	/* 02FB0 */
+	0x48,  0x0C,  0x7C,  0x44,  0x05,  0xFE,  0x44,  0x84,  0xE8,  0x43,  0x84,  0xC4,  0xAD,  0x20,  0x02,  0xFE, 	/* 02FC0 */
+	0x28,  0x24,  0xFE,  0x48,  0x8C,  0x88,  0x4B,  0x44,  0x8C,  0x50,  0x25,  0x61,  0x61,  0x04,  0x08,  0xAE, 	/* 02FD0 */
+	0x28,  0x02,  0xFE,  0x28,  0x05,  0x7C,  0x55,  0x4C,  0x54,  0x5F,  0xE4,  0x94,  0x49,  0x45,  0xFE,  0x50, 	/* 02FE0 */
+	0x44,  0x18,  0xAF,  0x10,  0x01,  0x7C,  0x10,  0x42,  0xFE,  0x24,  0x06,  0x7E,  0xA9,  0x03,  0x10,  0x2F, 	/* 02FF0 */
+	0xE2,  0x28,  0x24,  0x43,  0x82,  0xB5,  0x17,  0xC1,  0x04,  0x17,  0xC2,  0x04,  0x3F,  0xF7,  0x01,  0xB7, 	/* 03000 */
+	0xD2,  0x04,  0x26,  0x82,  0x10,  0x22,  0x82,  0xC6,  0xB6,  0x10,  0x01,  0x7C,  0x14,  0x42,  0x44,  0x27, 	/* 03010 */
+	0xC6,  0x20,  0xA4,  0x02,  0xFE,  0x28,  0x22,  0x82,  0x28,  0x22,  0xFE,  0xBF,  0x10,  0x01,  0xFE,  0x11, 	/* 03020 */
+	0x02,  0xFE,  0x29,  0x26,  0xFE,  0xA9,  0x22,  0xFE,  0x25,  0x02,  0x30,  0x24,  0x83,  0x86,  0x82,  0x10, 	/* 03030 */
+	0xC1,  0xF0,  0x12,  0x42,  0xC8,  0x23,  0x06,  0x24,  0xAF,  0xA2,  0x10,  0x25,  0x42,  0x52,  0x29,  0x22, 	/* 03040 */
+	0x10,  0x83,  0x20,  0x02,  0xFC,  0x28,  0x44,  0x84,  0x4F,  0xCC,  0x10,  0x49,  0x04,  0x9E,  0x49,  0x04, 	/* 03050 */
+	0xD0,  0x53,  0x06,  0x0E,  0x84,  0x25,  0x03,  0x94,  0x29,  0x22,  0x90,  0x7F,  0xE4,  0x90,  0xCD,  0x44, 	/* 03060 */
+	0x94,  0x58,  0x86,  0x9A,  0x4A,  0x65,  0x82,  0x8A,  0x11,  0x01,  0x24,  0x1F,  0xA2,  0x28,  0x22,  0xA6, 	/* 03070 */
+	0x4E,  0xAA,  0x02,  0x3C,  0x26,  0x42,  0x98,  0x26,  0xC3,  0x82,  0x8E,  0x27,  0xC2,  0x44,  0x24,  0x45, 	/* 03080 */
+	0x44,  0x4F,  0xCA,  0x44,  0x24,  0x42,  0x7C,  0x54,  0x44,  0xC4,  0x84,  0x41,  0xFE,  0x90,  0x23,  0x23, 	/* 03090 */
+	0xCA,  0x24,  0xA4,  0x4A,  0x7F,  0xAC,  0xCA,  0x4E,  0xA5,  0x5A,  0x64,  0xA4,  0x42,  0x44,  0x24,  0x46, 	/* 030A0 */
+	0x91,  0x10,  0x01,  0xFC,  0x12,  0x82,  0x10,  0x2F,  0xE6,  0x92,  0xAF,  0xE2,  0x92,  0x2F,  0xE2,  0x92, 	/* 030B0 */
+	0x29,  0x22,  0x96,  0x94,  0x20,  0x02,  0xFC,  0x28,  0x44,  0xFC,  0x48,  0x4C,  0xFC,  0x48,  0x44,  0xFC, 	/* 030C0 */
+	0x45,  0x04,  0x50,  0x49,  0x25,  0x0E,  0x97,  0x12,  0x81,  0x24,  0x15,  0x22,  0x92,  0x22,  0x86,  0x44, 	/* 030D0 */
+	0xA8,  0x23,  0x7D,  0x24,  0x42,  0x44,  0x24,  0x42,  0x7C,  0x98,  0x20,  0xC3,  0xF8,  0x2C,  0x85,  0x24, 	/* 030E0 */
+	0x62,  0x2D,  0xFC,  0x41,  0x84,  0x20,  0x7F,  0xE4,  0x20,  0x42,  0x04,  0x60,  0x9A,  0x10,  0x01,  0xFC, 	/* 030F0 */
+	0x1A,  0x42,  0xFC,  0x2A,  0x46,  0xA4,  0xAF,  0xC2,  0x20,  0x2F,  0xC2,  0x20,  0x22,  0x03,  0xFE,  0x9B, 	/* 03100 */
+	0x24,  0x02,  0x78,  0x28,  0x84,  0x10,  0x5F,  0xCD,  0x24,  0x52,  0x45,  0xFC,  0x45,  0x04,  0x52,  0x49, 	/* 03110 */
+	0x25,  0x0E,  0x9D,  0x20,  0x02,  0xFC,  0x28,  0x44,  0x84,  0x4F,  0xCC,  0x20,  0x7F,  0xE4,  0x70,  0x4A, 	/* 03120 */
+	0x85,  0x24,  0x62,  0x24,  0x20,  0x9F,  0x24,  0x02,  0x50,  0x28,  0x85,  0xF4,  0x48,  0x0C,  0xFC,  0x52, 	/* 03130 */
+	0x06,  0x20,  0x7F,  0xE4,  0x50,  0x48,  0x87,  0x06,  0xA1,  0x13,  0x81,  0x00,  0x1F,  0xE2,  0x00,  0x27, 	/* 03140 */
+	0xC6,  0x00,  0xA7,  0xC2,  0x00,  0x27,  0xC2,  0x44,  0x24,  0x42,  0x7C,  0xA3,  0x20,  0x02,  0xFC,  0x28, 	/* 03150 */
+	0x44,  0x84,  0x4F,  0xCC,  0x00,  0x4F,  0xC4,  0x20,  0x5F,  0xE4,  0x30,  0x44,  0x85,  0x86,  0xA4,  0x28, 	/* 03160 */
+	0x82,  0x50,  0x3F,  0xC2,  0x24,  0x5F,  0xC5,  0x20,  0xDF,  0xE4,  0x62,  0x4A,  0x25,  0x22,  0x62,  0xC4, 	/* 03170 */
+	0x20,  0xA5,  0x21,  0x03,  0xFF,  0x21,  0x04,  0xFE,  0x49,  0x2C,  0xFE,  0x49,  0x24,  0xFE,  0x41,  0x05, 	/* 03180 */
+	0xFF,  0x41,  0x04,  0x10,  0xAE,  0x24,  0x02,  0x7E,  0x2C,  0x45,  0x28,  0x51,  0x8D,  0xE4,  0x51,  0x35, 	/* 03190 */
+	0x68,  0x51,  0x25,  0x64,  0x41,  0x84,  0xE0,  0xAF,  0x22,  0x03,  0xFE,  0x32,  0x45,  0x24,  0x57,  0xED, 	/* 031A0 */
+	0xC4,  0x56,  0x45,  0x54,  0x55,  0x46,  0x44,  0x64,  0x44,  0x4C,  0xB3,  0x25,  0x02,  0x50,  0x3D,  0xE4, 	/* 031B0 */
+	0x50,  0x45,  0x0D,  0xDE,  0x45,  0x04,  0x50,  0x7D,  0xE4,  0x90,  0x49,  0x05,  0x10,  0xB5,  0x21,  0x02, 	/* 031C0 */
+	0xFE,  0x21,  0x04,  0xFE,  0x41,  0x0D,  0xFF,  0x42,  0x04,  0x52,  0x4D,  0x45,  0x48,  0x47,  0x44,  0xC2, 	/* 031D0 */
+	0xB6,  0x28,  0x02,  0x9E,  0x2E,  0x24,  0x8A,  0x7F,  0xAC,  0x8A,  0x4C,  0xA5,  0xA4,  0x5A,  0x46,  0x8C, 	/* 031E0 */
+	0x49,  0x24,  0xA2,  0xB8,  0x21,  0x02,  0xFE,  0x21,  0x04,  0x7C,  0x42,  0x8D,  0xFF,  0x45,  0x45,  0xFB, 	/* 031F0 */
+	0x41,  0x04,  0xFE,  0x41,  0x04,  0x10,  0xBA,  0x22,  0x02,  0x20,  0x3F,  0xE4,  0x50,  0xCA,  0xC5,  0xFA, 	/* 03200 */
+	0x6A,  0x84,  0xF8,  0x4A,  0x84,  0xF8,  0x42,  0x24,  0x1E,  0xBE,  0x22,  0x02,  0x40,  0x3F,  0xC5,  0x24, 	/* 03210 */
+	0x5F,  0xCD,  0x24,  0x5F,  0xC4,  0x90,  0x7F,  0xE4,  0x10,  0x41,  0x04,  0x10,  0x85,  0x22,  0x02,  0x20, 	/* 03220 */
+	0x3F,  0xE4,  0x88,  0x48,  0x8D,  0x54,  0x52,  0x24,  0x20,  0x7F,  0xE4,  0x20,  0x42,  0x04,  0x20,  0x86, 	/* 03230 */
+	0x20,  0x03,  0xFF,  0x21,  0x05,  0xFF,  0x51,  0x1D,  0xDD,  0x55,  0x55,  0x55,  0x5B,  0xB5,  0x11,  0x51, 	/* 03240 */
+	0x15,  0x13,  0x89,  0x04,  0x00,  0xA0,  0x31,  0x8F,  0xFE,  0x20,  0x83,  0xF8,  0x20,  0x83,  0xF8,  0x20, 	/* 03250 */
+	0x03,  0xFC,  0x50,  0x49,  0xFC,  0x8B,  0x20,  0x03,  0xFE,  0x32,  0x25,  0x22,  0x5F,  0xED,  0x22,  0x57, 	/* 03260 */
+	0xA5,  0x4A,  0x54,  0xA5,  0x7A,  0x50,  0x25,  0xFE,  0x8D,  0x11,  0x01,  0x10,  0x1F,  0xE2,  0x44,  0x22, 	/* 03270 */
+	0x87,  0xFE,  0xA0,  0x02,  0x7C,  0x24,  0x42,  0x44,  0x24,  0x42,  0x7C,  0x8F,  0x24,  0x02,  0x7E,  0x24, 	/* 03280 */
+	0x45,  0xB8,  0x52,  0x8D,  0xC6,  0x51,  0x85,  0x14,  0x5F,  0xE5,  0x10,  0x42,  0x84,  0xC6,  0x91,  0x10, 	/* 03290 */
+	0x01,  0xEE,  0x1A,  0xA2,  0xEE,  0x2A,  0xA6,  0xEE,  0xA8,  0x22,  0x82,  0x28,  0x22,  0x82,  0x28,  0x22, 	/* 032A0 */
+	0x86,  0x92,  0x20,  0x23,  0xF2,  0x24,  0xA4,  0xAA,  0x5D,  0xAC,  0x4A,  0x5F,  0xA4,  0x4A,  0x44,  0xA4, 	/* 032B0 */
+	0x72,  0x58,  0x24,  0x06,  0x94,  0x20,  0x02,  0xFE,  0x28,  0x24,  0xFE,  0x49,  0x0C,  0xD4,  0x4D,  0x45, 	/* 032C0 */
+	0x7C,  0x51,  0x06,  0x92,  0x49,  0x24,  0xFE,  0x96,  0x11,  0x01,  0x10,  0x1F,  0xC2,  0x10,  0x3F,  0xE6, 	/* 032D0 */
+	0x44,  0xAF,  0xE2,  0x10,  0x2F,  0xC2,  0x10,  0x21,  0x02,  0x10,  0x99,  0x20,  0x02,  0x7C,  0x20,  0x45, 	/* 032E0 */
+	0xFE,  0x54,  0x0D,  0x7C,  0x59,  0x05,  0x10,  0x5F,  0xE5,  0x28,  0x44,  0x45,  0x82,  0x9A,  0x22,  0x03, 	/* 032F0 */
+	0xFE,  0x23,  0x04,  0x48,  0x58,  0x4F,  0xFE,  0x40,  0x44,  0xF4,  0x49,  0x44,  0xF4,  0x40,  0x44,  0x0C, 	/* 03300 */
+	0x9F,  0x14,  0x81,  0x48,  0x1F,  0xC2,  0x48,  0x3F,  0xE6,  0x00,  0xAF,  0xC2,  0x84,  0x2F,  0xC2,  0x84, 	/* 03310 */
+	0x28,  0x42,  0xFC,  0xA1,  0x17,  0xC1,  0x44,  0x17,  0xC2,  0x44,  0x27,  0xC6,  0x00,  0xAF,  0xE2,  0x82, 	/* 03320 */
+	0x2F,  0xE2,  0x82,  0x28,  0x22,  0xFE,  0xA3,  0x29,  0x02,  0x90,  0x29,  0xF7,  0xF2,  0x49,  0x2C,  0xEA, 	/* 03330 */
+	0x4A,  0xC4,  0xA4,  0x52,  0x45,  0x2A,  0x62,  0xA4,  0xD1,  0xA4,  0x21,  0x02,  0xFE,  0x21,  0x04,  0x7C, 	/* 03340 */
+	0x54,  0x4D,  0x7C,  0x54,  0x45,  0x7C,  0x54,  0x45,  0x7C,  0x50,  0x05,  0xFE,  0xA5,  0x22,  0x02,  0x20, 	/* 03350 */
+	0x3F,  0xE5,  0x52,  0x45,  0x0C,  0x9E,  0x50,  0x05,  0xFC,  0x42,  0x04,  0x20,  0x42,  0x07,  0xFE,  0xA6, 	/* 03360 */
+	0x22,  0x42,  0xA8,  0x3F,  0xC4,  0x20,  0x5F,  0xEC,  0x50,  0x48,  0x85,  0xF4,  0x61,  0x24,  0xF0,  0x48, 	/* 03370 */
+	0x44,  0x7C,  0xA8,  0x20,  0x02,  0xFE,  0x28,  0x24,  0xFE,  0x49,  0x0C,  0xFF,  0x49,  0x04,  0x90,  0x57, 	/* 03380 */
+	0xE5,  0x42,  0x64,  0x24,  0x7E,  0xA9,  0x22,  0x03,  0xFC,  0x22,  0x04,  0xF8,  0x42,  0x0F,  0xFE,  0x52, 	/* 03390 */
+	0x45,  0x24,  0x5F,  0xC5,  0x04,  0x50,  0x45,  0x0C,  0xAA,  0x22,  0x02,  0xCC,  0x28,  0x42,  0xEC,  0x48, 	/* 033A0 */
+	0x44,  0x84,  0xCF,  0xC4,  0x50,  0x45,  0x04,  0x52,  0x49,  0x25,  0x0E,  0xAB,  0x22,  0x02,  0x20,  0x25, 	/* 033B0 */
+	0x04,  0x88,  0x5F,  0xCE,  0x02,  0x5F,  0xC5,  0x54,  0x5F,  0xC5,  0x54,  0x55,  0x45,  0x0C,  0xAC,  0x22, 	/* 033C0 */
+	0x02,  0x3E,  0x22,  0x05,  0xFC,  0x50,  0x4D,  0xFC,  0x50,  0x45,  0xFC,  0x42,  0x07,  0xFE,  0x42,  0x04, 	/* 033D0 */
+	0x20,  0xAD,  0x20,  0xC2,  0xF0,  0x22,  0x05,  0xFE,  0x47,  0x0C,  0xA8,  0x52,  0x64,  0x40,  0x5F,  0xE4, 	/* 033E0 */
+	0xC8,  0x43,  0x05,  0xCC,  0xB6,  0x10,  0x01,  0xFC,  0x18,  0x42,  0x84,  0x2F,  0xC6,  0x84,  0xAF,  0xC2, 	/* 033F0 */
+	0x84,  0x3F,  0xE2,  0x28,  0x24,  0x43,  0x82,  0xB9,  0x11,  0x01,  0x28,  0x14,  0x42,  0xBA,  0x31,  0x16, 	/* 03400 */
+	0xFE,  0xA9,  0x22,  0xFE,  0x23,  0x02,  0x28,  0x24,  0x42,  0x82,  0x83,  0x20,  0x03,  0xFE,  0x37,  0xC5, 	/* 03410 */
+	0x44,  0x57,  0xCD,  0x44,  0x5F,  0xE5,  0x24,  0x56,  0x85,  0x18,  0x56,  0x45,  0xFE,  0x87,  0x20,  0x03, 	/* 03420 */
+	0xEE,  0x32,  0x25,  0x22,  0x5E,  0xED,  0x00,  0x5E,  0xE5,  0x12,  0x50,  0xA5,  0xE4,  0x50,  0xA5,  0x31, 	/* 03430 */
+	0x88,  0x20,  0x02,  0xFC,  0x28,  0x44,  0xFC,  0x48,  0x4C,  0xFC,  0x44,  0x04,  0xFE,  0x59,  0x26,  0xAA, 	/* 03440 */
+	0x4F,  0xA4,  0x0C,  0x89,  0x12,  0x01,  0x7C,  0x12,  0x43,  0xFF,  0x24,  0x46,  0x7C,  0xA1,  0x02,  0xFC, 	/* 03450 */
+	0x29,  0x03,  0xFE,  0x21,  0x02,  0x10,  0x8F,  0x2F,  0xC2,  0x00,  0x3F,  0xC5,  0x04,  0x5F,  0xCD,  0x00, 	/* 03460 */
+	0x5F,  0xE5,  0xAA,  0x5F,  0xE6,  0xAA,  0x6A,  0xA4,  0x86,  0x90,  0x21,  0x02,  0xFE,  0x24,  0x44,  0x28, 	/* 03470 */
+	0x4F,  0xEC,  0x88,  0x49,  0x44,  0xE8,  0x49,  0x25,  0x64,  0x51,  0x86,  0x60,  0x95,  0x29,  0x02,  0x90, 	/* 03480 */
+	0x2F,  0x64,  0x98,  0x4F,  0x2F,  0x8E,  0x40,  0x04,  0xFC,  0x48,  0x44,  0xFC,  0x48,  0x44,  0xFC,  0x96, 	/* 03490 */
+	0x22,  0x02,  0x20,  0x2F,  0xC4,  0x28,  0x5F,  0xEC,  0x30,  0x44,  0x84,  0xFC,  0x74,  0x44,  0x7C,  0x44, 	/* 034A0 */
+	0x44,  0x7C,  0x9A,  0x28,  0x82,  0x88,  0x28,  0x87,  0xFF,  0x49,  0x4C,  0xB4,  0x5D,  0x45,  0x54,  0x54, 	/* 034B0 */
+	0x85,  0xD8,  0x42,  0x44,  0x42,  0x9C,  0x11,  0x01,  0xFE,  0x10,  0x02,  0x7C,  0x24,  0x47,  0xFF,  0xB0, 	/* 034C0 */
+	0x12,  0x7C,  0x21,  0x02,  0x10,  0x21,  0x02,  0x30,  0xA5,  0x20,  0x82,  0x3E,  0x3C,  0xA4,  0x7F,  0x48, 	/* 034D0 */
+	0xAD,  0xFE,  0x44,  0x85,  0x7E,  0x4C,  0x84,  0x7E,  0x4A,  0x85,  0x1F,  0xAC,  0x24,  0x02,  0x40,  0x27, 	/* 034E0 */
+	0xE4,  0xAA,  0x56,  0xAE,  0x9A,  0x42,  0x24,  0x4C,  0x56,  0x05,  0x52,  0x64,  0x54,  0x3C,  0xB2,  0x20, 	/* 034F0 */
+	0x03,  0xFC,  0x32,  0x45,  0xFC,  0x52,  0x4D,  0x24,  0x5F,  0xC4,  0x20,  0x55,  0x45,  0x52,  0x64,  0xA4, 	/* 03500 */
+	0x38,  0xB4,  0x20,  0x23,  0xEA,  0x32,  0xA5,  0x2A,  0x5E,  0xA5,  0x2A,  0xDE,  0xA5,  0x2A,  0x5E,  0xA4, 	/* 03510 */
+	0x42,  0x4A,  0x25,  0x06,  0xB5,  0x11,  0x01,  0x1E,  0x11,  0x02,  0xFC,  0x28,  0x46,  0xFC,  0xA8,  0x42, 	/* 03520 */
+	0xFC,  0x28,  0x42,  0xFC,  0x24,  0x43,  0x82,  0xB6,  0x20,  0x02,  0xFC,  0x2A,  0x44,  0xFC,  0x4A,  0x4C, 	/* 03530 */
+	0xFC,  0x42,  0x05,  0xFE,  0x52,  0xA5,  0x3A,  0x5C,  0xA5,  0x06,  0xB8,  0x22,  0x02,  0x30,  0x24,  0x84, 	/* 03540 */
+	0xF4,  0x50,  0x2F,  0xCA,  0x54,  0xA5,  0xD4,  0x55,  0x45,  0xD4,  0x54,  0xA5,  0x4A,  0xBD,  0x29,  0x02, 	/* 03550 */
+	0x50,  0x22,  0x05,  0xF8,  0x44,  0x8C,  0x7C,  0x48,  0x45,  0xFE,  0x60,  0x24,  0xAA,  0x52,  0x24,  0x0C, 	/* 03560 */
+	0x80,  0x22,  0x02,  0x40,  0x3F,  0xC5,  0x24,  0x5F,  0xCD,  0x24,  0x5F,  0xC4,  0x68,  0x46,  0x84,  0xB6, 	/* 03570 */
+	0x4A,  0x25,  0x1E,  0x85,  0x22,  0x83,  0xFE,  0x22,  0x05,  0xFC,  0x52,  0x4D,  0xFC,  0x52,  0x44,  0x08, 	/* 03580 */
+	0x7F,  0xE4,  0x88,  0x44,  0x84,  0x18,  0x8D,  0x21,  0x03,  0xFE,  0x24,  0x84,  0x48,  0x5F,  0xED,  0x22, 	/* 03590 */
+	0x5F,  0xE4,  0x20,  0x43,  0xC4,  0x44,  0x48,  0x47,  0x18,  0x91,  0x28,  0x42,  0xC4,  0x35,  0xE5,  0xD4, 	/* 035A0 */
+	0x47,  0xEC,  0x84,  0x72,  0x45,  0xFE,  0x47,  0x04,  0xA8,  0x52,  0x64,  0x20,  0x98,  0x04,  0x00,  0xA0, 	/* 035B0 */
+	0x31,  0x8C,  0x46,  0x24,  0x85,  0x54,  0x24,  0x85,  0x54,  0xFF,  0xE0,  0x40,  0x04,  0x00,  0x40,  0x99, 	/* 035C0 */
+	0x24,  0x82,  0xFE,  0x24,  0x85,  0xFE,  0x50,  0x0D,  0x7E,  0x55,  0x25,  0x7E,  0x55,  0x25,  0x7E,  0x65, 	/* 035D0 */
+	0x24,  0x56,  0x9A,  0x28,  0x82,  0x88,  0x3F,  0xE5,  0x54,  0x62,  0x4D,  0x54,  0x55,  0x44,  0x88,  0x4C, 	/* 035E0 */
+	0x85,  0x34,  0x62,  0x44,  0x42,  0xAC,  0x11,  0x01,  0x92,  0x1F,  0xE2,  0x48,  0x29,  0x06,  0xFE,  0xB9, 	/* 035F0 */
+	0x02,  0xFC,  0x29,  0x02,  0xFC,  0x29,  0x02,  0xFE,  0xAD,  0x22,  0x03,  0xFE,  0x31,  0x05,  0x7C,  0x51, 	/* 03600 */
+	0x4D,  0xFE,  0xD5,  0x25,  0x7E,  0x55,  0x25,  0x7E,  0x55,  0x26,  0x56,  0xB2,  0x28,  0x82,  0x88,  0x3E, 	/* 03610 */
+	0xF4,  0x92,  0x7F,  0x2C,  0xAA,  0x7E,  0xC4,  0x84,  0x4E,  0xC4,  0xAA,  0x53,  0x26,  0x61,  0xB3,  0x22, 	/* 03620 */
+	0x83,  0xFE,  0x2A,  0x44,  0xFC,  0x4A,  0x4C,  0xFC,  0x42,  0xC5,  0xF2,  0x40,  0x87,  0xFE,  0x48,  0x84, 	/* 03630 */
+	0x18,  0xB4,  0x20,  0x03,  0xFE,  0x53,  0xC5,  0x24,  0xD3,  0xC5,  0x00,  0x57,  0xE5,  0x5A,  0x55,  0xA5, 	/* 03640 */
+	0x7E,  0x50,  0x05,  0xFE,  0xB5,  0x11,  0x01,  0xFC,  0x21,  0x02,  0xFC,  0x61,  0x0B,  0xFE,  0x24,  0x42, 	/* 03650 */
+	0x7C,  0x24,  0x42,  0x7C,  0x26,  0x43,  0x82,  0xB7,  0x14,  0x01,  0x7E,  0x2C,  0x43,  0x7C,  0x64,  0x4B, 	/* 03660 */
+	0xFF,  0x24,  0x02,  0xFE,  0x32,  0xA2,  0xD2,  0x22,  0x22,  0xCC,  0xBE,  0x20,  0x02,  0xFE,  0x21,  0x05, 	/* 03670 */
+	0x3C,  0x56,  0x4D,  0xBC,  0x52,  0x45,  0x3C,  0x56,  0x44,  0xFC,  0x43,  0x44,  0xC2,  0x82,  0x22,  0x02, 	/* 03680 */
+	0xFC,  0x2A,  0x47,  0xFE,  0x4A,  0x4C,  0xFC,  0x4A,  0x45,  0xFE,  0x44,  0x84,  0xC8,  0x43,  0x05,  0xCC, 	/* 03690 */
+	0x85,  0x22,  0x82,  0xFE,  0x22,  0x84,  0xFE,  0x49,  0x2C,  0xFE,  0x41,  0x04,  0xFE,  0x41,  0x04,  0x7C, 	/* 036A0 */
+	0x41,  0x04,  0xFE,  0x89,  0x04,  0x00,  0xA0,  0x31,  0x8D,  0xF6,  0x00,  0x07,  0xBC,  0x4A,  0x47,  0xBC, 	/* 036B0 */
+	0x20,  0x83,  0x0C,  0x49,  0x28,  0x22,  0x8A,  0x3F,  0xE2,  0x50,  0x3F,  0xC5,  0x54,  0x5F,  0xCC,  0x20, 	/* 036C0 */
+	0x7F,  0xE4,  0xFC,  0x58,  0xA6,  0xF8,  0x48,  0x24,  0x7E,  0x8D,  0x27,  0x43,  0xC4,  0x24,  0xF5,  0xF5, 	/* 036D0 */
+	0x55,  0x5D,  0xF5,  0x55,  0x55,  0xF5,  0x44,  0x55,  0xE5,  0x47,  0x95,  0x8B,  0x8F,  0x23,  0x82,  0x50, 	/* 036E0 */
+	0x3F,  0xE4,  0x92,  0x4F,  0xEC,  0x32,  0x5D,  0x44,  0x68,  0x59,  0xC4,  0x6A,  0x58,  0x94,  0x30,  0x91, 	/* 036F0 */
+	0x17,  0xC1,  0x10,  0x2F,  0xE2,  0x28,  0x2C,  0x66,  0x38,  0xA2,  0x82,  0xFE,  0x2B,  0xA2,  0xAA,  0x2B, 	/* 03700 */
+	0xA2,  0x86,  0x95,  0x25,  0x03,  0x54,  0x3F,  0xE6,  0x50,  0x5F,  0xCC,  0x20,  0x4F,  0xC4,  0x20,  0x5F, 	/* 03710 */
+	0xE4,  0x50,  0x48,  0x87,  0x06,  0x96,  0x22,  0x03,  0xFE,  0x22,  0x05,  0xFC,  0x50,  0x4D,  0xFC,  0x48, 	/* 03720 */
+	0x87,  0xFE,  0x40,  0x05,  0xFC,  0x50,  0x45,  0xFC,  0x9A,  0x22,  0x03,  0xFE,  0x22,  0x05,  0x54,  0x48, 	/* 03730 */
+	0x8D,  0xFC,  0x68,  0xA4,  0xF8,  0x42,  0x84,  0xA4,  0x52,  0x44,  0x60,  0x9E,  0x20,  0xC3,  0xF4,  0x29, 	/* 03740 */
+	0x25,  0xF8,  0x48,  0x8C,  0xFC,  0x48,  0x44,  0xFE,  0x51,  0x25,  0x4A,  0x6A,  0x24,  0x8C,  0xA3,  0x24, 	/* 03750 */
+	0x83,  0xFE,  0x24,  0x85,  0xFF,  0x44,  0x8C,  0xB4,  0x51,  0x24,  0xFC,  0x48,  0x44,  0xFC,  0x48,  0x44, 	/* 03760 */
+	0xFC,  0xA5,  0x22,  0x02,  0xFC,  0x22,  0x07,  0xFE,  0x48,  0x8D,  0xDC,  0x48,  0x85,  0xDC,  0x7F,  0xE4, 	/* 03770 */
+	0x50,  0x49,  0x25,  0x0E,  0xA7,  0x14,  0x41,  0x28,  0x2F,  0xE2,  0x92,  0x6F,  0xEA,  0x92,  0x2F,  0xE2, 	/* 03780 */
+	0x7C,  0x24,  0x42,  0x7C,  0x24,  0x42,  0x7C,  0xAD,  0x24,  0x43,  0xFE,  0x35,  0x45,  0xFF,  0x4C,  0xCD, 	/* 03790 */
+	0x55,  0x66,  0x74,  0xFC,  0x48,  0x44,  0xFC,  0x48,  0x44,  0xFC,  0xAE,  0x21,  0x02,  0xFE,  0x24,  0x45, 	/* 037A0 */
+	0xFF,  0x49,  0x2C,  0xFE,  0x49,  0x24,  0xFE,  0x41,  0x04,  0xFE,  0x41,  0x05,  0xFF,  0xB5,  0x20,  0x03, 	/* 037B0 */
+	0xFE,  0x2A,  0x44,  0xFC,  0x4A,  0x4D,  0xFE,  0x40,  0x04,  0xFC,  0x4A,  0x44,  0xFC,  0x4A,  0x45,  0xFE, 	/* 037C0 */
+	0xB9,  0x20,  0x03,  0xFE,  0x25,  0x05,  0xFE,  0x55,  0x2D,  0xFE,  0x48,  0x44,  0xFC,  0x4F,  0xC4,  0x84, 	/* 037D0 */
+	0x4F,  0xC5,  0x86,  0xBB,  0x20,  0x83,  0xC8,  0x37,  0xE5,  0x54,  0x5D,  0x4D,  0x3E,  0x5C,  0x87,  0x48, 	/* 037E0 */
+	0x57,  0xE5,  0x48,  0x5C,  0x84,  0x08,  0x80,  0x24,  0x83,  0xFE,  0x22,  0x04,  0xFC,  0x42,  0x0F,  0xFE, 	/* 037F0 */
+	0x4D,  0x45,  0xFE,  0x45,  0x45,  0xCA,  0x45,  0x64,  0xC2,  0x81,  0x24,  0x82,  0x50,  0x2F,  0xE5,  0x90, 	/* 03800 */
+	0x6F,  0xCC,  0x90,  0x4F,  0xE4,  0x00,  0x5D,  0xE5,  0x52,  0x57,  0x25,  0x06,  0x82,  0x22,  0x82,  0xFE, 	/* 03810 */
+	0x2A,  0xA4,  0xFE,  0x4A,  0xAD,  0xFE,  0x50,  0x05,  0xFE,  0x55,  0x25,  0x4C,  0x67,  0x44,  0xC2,  0x84, 	/* 03820 */
+	0x21,  0x02,  0xFC,  0x24,  0x83,  0xFE,  0x48,  0x44,  0xFC,  0xC8,  0x44,  0xFC,  0x56,  0x05,  0x54,  0x64, 	/* 03830 */
+	0xA4,  0x38,  0x89,  0x22,  0x02,  0x30,  0x24,  0x84,  0xFC,  0x50,  0x2D,  0xDD,  0x55,  0x45,  0xDC,  0x48, 	/* 03840 */
+	0x84,  0xCC,  0x51,  0x26,  0x20,  0x92,  0x2F,  0xC2,  0x20,  0x3F,  0xE5,  0x22,  0x57,  0xAC,  0x00,  0x5F, 	/* 03850 */
+	0xE4,  0x20,  0x4F,  0xE4,  0xAA,  0x4A,  0xA4,  0xAE,  0x94,  0x21,  0x02,  0xFE,  0x21,  0x05,  0xFE,  0x4F, 	/* 03860 */
+	0xAC,  0x20,  0x5F,  0xE4,  0x04,  0x7F,  0xE5,  0x64,  0x5D,  0x44,  0x0C,  0x95,  0x21,  0x02,  0xFE,  0x22, 	/* 03870 */
+	0xA5,  0xDE,  0x4D,  0x4D,  0x5A,  0x64,  0x44,  0x7C,  0x44,  0x44,  0x7C,  0x48,  0x45,  0x04,  0x96,  0x3E, 	/* 03880 */
+	0x83,  0x48,  0x3E,  0xE5,  0x30,  0x5E,  0x0D,  0x4E,  0x5F,  0x04,  0x00,  0x5F,  0xC5,  0x54,  0x55,  0x47, 	/* 03890 */
+	0xFE,  0x98,  0x22,  0x02,  0xFC,  0x22,  0x47,  0xFE,  0x4F,  0xCC,  0x20,  0x7F,  0xE5,  0x2A,  0x5F,  0xC5, 	/* 038A0 */
+	0x54,  0x55,  0x47,  0xFE,  0x9A,  0x24,  0x83,  0xFE,  0x24,  0x85,  0xFC,  0x55,  0x4D,  0xFC,  0x40,  0x07, 	/* 038B0 */
+	0xFE,  0x67,  0xA5,  0xC8,  0x43,  0x05,  0xC0,  0x9F,  0x2A,  0x42,  0x58,  0x3F,  0xE5,  0x7A,  0x54,  0xAC, 	/* 038C0 */
+	0xFC,  0x48,  0x44,  0xFC,  0x48,  0x44,  0xFC,  0x44,  0x45,  0x82,  0xA1,  0x20,  0x02,  0xFC,  0x2A,  0x44, 	/* 038D0 */
+	0xFC,  0x4A,  0x4C,  0xFC,  0x40,  0x07,  0xFE,  0x6A,  0xA7,  0xFE,  0x6A,  0xA7,  0xFE,  0xAA,  0x3F,  0xE2, 	/* 038E0 */
+	0x20,  0x27,  0x84,  0x48,  0x5F,  0xED,  0x6A,  0x4B,  0x45,  0x7A,  0x4C,  0x85,  0x30,  0x46,  0x85,  0x86, 	/* 038F0 */
+	0xB2,  0x2C,  0x82,  0x1E,  0x3E,  0x84,  0x08,  0x5F,  0xEC,  0x10,  0x5D,  0xE4,  0x12,  0x5F,  0xE5,  0x52, 	/* 03900 */
+	0x55,  0x25,  0xDE,  0xB7,  0x3D,  0xE2,  0x00,  0x3D,  0xE6,  0xAA,  0x5F,  0xED,  0xFC,  0x55,  0x45,  0xFC, 	/* 03910 */
+	0x5A,  0xA5,  0xCC,  0x6A,  0xA5,  0xCE,  0xBA,  0x2A,  0xA3,  0xF4,  0x2B,  0xF5,  0xF4,  0x55,  0x4D,  0xFE, 	/* 03920 */
+	0x45,  0x45,  0xF4,  0x45,  0xE7,  0xF4,  0x53,  0x46,  0x1F,  0xBB,  0x2A,  0x43,  0xFE,  0x34,  0xA4,  0x78, 	/* 03930 */
+	0x4F,  0xCC,  0xDC,  0x4B,  0x44,  0xFC,  0x41,  0x05,  0xFE,  0x4A,  0x45,  0x52,  0xBC,  0x2E,  0xE2,  0xAA, 	/* 03940 */
+	0x3F,  0xE5,  0x68,  0x52,  0x8D,  0xFF,  0x55,  0xA5,  0x7A,  0x55,  0x45,  0xF4,  0x52,  0xA6,  0x31,  0xBF, 	/* 03950 */
+	0x11,  0x01,  0x10,  0x11,  0x01,  0x10,  0x11,  0x01,  0x10,  0x11,  0x01,  0x10,  0x21,  0x02,  0x12,  0x41, 	/* 03960 */
+	0x28,  0x0E,  0x80,  0x00,  0x0F,  0xFE,  0x11,  0x01,  0x10,  0x11,  0x01,  0x10,  0x11,  0x01,  0x10,  0x21, 	/* 03970 */
+	0x02,  0x12,  0x41,  0x28,  0x0E,  0x81,  0x08,  0x00,  0x80,  0x13,  0x02,  0x0C,  0x7F,  0x20,  0xA0,  0x0A, 	/* 03980 */
+	0x00,  0xA0,  0x12,  0x01,  0x22,  0x22,  0x24,  0x1E,  0x83,  0x00,  0x01,  0xF8,  0x00,  0x00,  0x00,  0x7F, 	/* 03990 */
+	0xE0,  0x90,  0x09,  0x00,  0x90,  0x11,  0x01,  0x12,  0x21,  0x24,  0x0E,  0x84,  0x00,  0x03,  0xF8,  0x20, 	/* 039A0 */
+	0x82,  0x08,  0x20,  0x83,  0xF8,  0x0A,  0x00,  0xA0,  0x0A,  0x01,  0x22,  0x22,  0x2C,  0x1E,  0x85,  0x08, 	/* 039B0 */
+	0x00,  0x80,  0xFF,  0xE0,  0xA0,  0x11,  0x87,  0xE4,  0x12,  0x01,  0x20,  0x12,  0x02,  0x22,  0x42,  0x28, 	/* 039C0 */
+	0x1E,  0x86,  0x0A,  0x00,  0xA4,  0x4A,  0x42,  0xA8,  0x2B,  0x00,  0xA0,  0x1B,  0x02,  0xAC,  0xD2,  0x01, 	/* 039D0 */
+	0x22,  0x22,  0x2C,  0x1E,  0x87,  0x02,  0x05,  0xA4,  0x44,  0x44,  0x64,  0x49,  0x45,  0x04,  0x7F,  0xC0, 	/* 039E0 */
+	0xA0,  0x0A,  0x01,  0x22,  0x22,  0x2C,  0x1E,  0x88,  0x04,  0x02,  0x40,  0x24,  0x03,  0xF8,  0x24,  0x04, 	/* 039F0 */
+	0x40,  0xFF,  0xE0,  0xA0,  0x0A,  0x01,  0x22,  0x22,  0x2C,  0x1E,  0x89,  0x04,  0x04,  0x48,  0x24,  0x82, 	/* 03A00 */
+	0x50,  0x04,  0x07,  0xFE,  0x0A,  0x00,  0xA0,  0x12,  0x01,  0x22,  0x22,  0x2C,  0x1E,  0x8B,  0x04,  0x00, 	/* 03A10 */
+	0x40,  0xFF,  0xE0,  0x40,  0x3F,  0x82,  0x08,  0x20,  0x83,  0xF8,  0x0A,  0x00,  0xA2,  0x12,  0x2E,  0x1E, 	/* 03A20 */
+	0x8C,  0x0B,  0x01,  0x10,  0x20,  0x8D,  0xFE,  0x20,  0x82,  0x08,  0x3F,  0x80,  0xA0,  0x0A,  0x01,  0x22, 	/* 03A30 */
+	0x22,  0x2C,  0x1E,  0x8D,  0x08,  0x00,  0xF0,  0x12,  0x02,  0x40,  0xFF,  0xC2,  0x44,  0x24,  0x43,  0xFC, 	/* 03A40 */
+	0x0A,  0x01,  0x22,  0x22,  0x2C,  0x1E,  0x8E,  0x01,  0xC7,  0xE0,  0x04,  0x07,  0xFC,  0x44,  0x44,  0x44, 	/* 03A50 */
+	0x7F,  0xC0,  0xA0,  0x0B,  0x01,  0x2A,  0x22,  0x2C,  0x1E,  0x90,  0x4F,  0x84,  0x88,  0x48,  0x84,  0xF8, 	/* 03A60 */
+	0x48,  0x84,  0x88,  0x4F,  0x84,  0x20,  0x12,  0x01,  0x22,  0x22,  0x2C,  0x1E,  0x92,  0x08,  0x03,  0x38, 	/* 03A70 */
+	0x20,  0x82,  0x08,  0x3B,  0x82,  0x08,  0x20,  0x83,  0xF8,  0x09,  0x00,  0x92,  0x11,  0x26,  0x0E,  0x94, 	/* 03A80 */
+	0x08,  0x00,  0xF0,  0x12,  0x02,  0x40,  0xFF,  0xC4,  0x44,  0x44,  0x47,  0xFC,  0x0B,  0x01,  0x2A,  0x22, 	/* 03A90 */
+	0x2C,  0x1E,  0x9A,  0x24,  0x81,  0x50,  0xFF,  0xE8,  0x02,  0xBF,  0xA2,  0x08,  0x20,  0x83,  0xF8,  0x0A, 	/* 03AA0 */
+	0x00,  0xA0,  0x32,  0x2C,  0x1E,  0x9C,  0x14,  0x06,  0xFC,  0x4A,  0x44,  0xE4,  0x4A,  0x47,  0xBC,  0x4E, 	/* 03AB0 */
+	0x40,  0x00,  0x0A,  0x01,  0x22,  0x22,  0x2C,  0x1E,  0xA2,  0x10,  0x8F,  0xFE,  0x10,  0x87,  0xBC,  0x4A, 	/* 03AC0 */
+	0x44,  0xA4,  0x7B,  0xC3,  0x18,  0x31,  0x83,  0x6A,  0x5A,  0xA8,  0x46,  0xA5,  0x00,  0x01,  0xC0,  0x04, 	/* 03AD0 */
+	0x00,  0x40,  0x04,  0x00,  0x40,  0x0A,  0x00,  0xA0,  0x11,  0x02,  0x08,  0x40,  0x48,  0x02,  0xA8,  0x04, 	/* 03AE0 */
+	0x00,  0x40,  0x0A,  0x01,  0x10,  0x20,  0x8F,  0xFE,  0x04,  0x00,  0x40,  0x3F,  0x80,  0x40,  0x04,  0x0F, 	/* 03AF0 */
+	0xFE,  0xA9,  0x00,  0x0F,  0xFE,  0x04,  0x0F,  0xFE,  0x84,  0x2B,  0x5A,  0x94,  0xA9,  0x4A,  0xAD,  0x6C, 	/* 03B00 */
+	0x62,  0x84,  0x28,  0x46,  0xAA,  0x1C,  0x00,  0xA0,  0x11,  0x02,  0xE8,  0xC0,  0x67,  0x94,  0x69,  0x45, 	/* 03B10 */
+	0xA8,  0x6A,  0x85,  0x94,  0x49,  0x45,  0x94,  0xAB,  0x00,  0x01,  0xF0,  0x01,  0x00,  0x10,  0x11,  0x01, 	/* 03B20 */
+	0x10,  0x11,  0x01,  0x08,  0x20,  0x82,  0x04,  0x40,  0x48,  0x02,  0xAC,  0x11,  0x01,  0x10,  0x11,  0x02, 	/* 03B30 */
+	0x08,  0x24,  0x44,  0x42,  0x84,  0x00,  0x90,  0x08,  0x81,  0x78,  0x78,  0x40,  0x04,  0xAD,  0x04,  0x00, 	/* 03B40 */
+	0x40,  0x04,  0x0F,  0xFE,  0x00,  0x01,  0x20,  0x11,  0x02,  0x08,  0x20,  0x44,  0x04,  0x80,  0x40,  0x00, 	/* 03B50 */
+	0xAE,  0x16,  0x01,  0x20,  0x21,  0x04,  0x08,  0xBF,  0x60,  0x80,  0x08,  0x01,  0xF0,  0x11,  0x00,  0x10, 	/* 03B60 */
+	0x01,  0x00,  0x60,  0xB1,  0x11,  0x01,  0x10,  0x11,  0x07,  0xFC,  0x11,  0x01,  0x10,  0x11,  0x0F,  0xFE, 	/* 03B70 */
+	0x01,  0x01,  0x08,  0x20,  0x4C,  0x04,  0xB5,  0x03,  0x03,  0xC0,  0x20,  0x02,  0x00,  0x3F,  0xC2,  0x10, 	/* 03B80 */
+	0x21,  0x02,  0x10,  0xFF,  0xE1,  0x20,  0x21,  0x8C,  0x04,  0xB6,  0x11,  0x01,  0x10,  0x7F,  0xC1,  0x10, 	/* 03B90 */
+	0x1F,  0x01,  0x10,  0x1F,  0x01,  0x10,  0xFF,  0xE1,  0x10,  0x20,  0xCC,  0x02,  0xB7,  0x3F,  0x02,  0x10, 	/* 03BA0 */
+	0x3F,  0x02,  0x10,  0x3F,  0x02,  0x10,  0x3F,  0x00,  0x00,  0xFF,  0xE1,  0x20,  0x21,  0x8C,  0x04,  0xB8, 	/* 03BB0 */
+	0x0A,  0x00,  0xA0,  0x7F,  0xC4,  0xA4,  0x4A,  0x47,  0xFC,  0x4A,  0x44,  0xA4,  0xFF,  0xE1,  0x10,  0x20, 	/* 03BC0 */
+	0xCC,  0x02,  0xBC,  0x11,  0x0F,  0xFE,  0x0A,  0x07,  0xFC,  0x0A,  0x4F,  0xFE,  0x0A,  0x47,  0xFC,  0x1B, 	/* 03BD0 */
+	0x02,  0xA8,  0xCA,  0x60,  0xA0,  0x80,  0x12,  0x4F,  0x38,  0x12,  0x23,  0xFE,  0xE4,  0x83,  0xF8,  0x24, 	/* 03BE0 */
+	0x87,  0xFC,  0x11,  0x0F,  0xFF,  0x30,  0x8C,  0x04,  0x82,  0x00,  0x07,  0xFE,  0x40,  0x24,  0x02,  0x40, 	/* 03BF0 */
+	0x24,  0x02,  0x40,  0x24,  0x02,  0x40,  0x24,  0x02,  0x40,  0x24,  0x06,  0x85,  0x04,  0x00,  0x40,  0x7F, 	/* 03C00 */
+	0xE4,  0x42,  0x44,  0x24,  0xA2,  0x51,  0x26,  0x0A,  0x40,  0x24,  0x02,  0x40,  0x24,  0x06,  0x86,  0x00, 	/* 03C10 */
+	0x07,  0xFC,  0x44,  0x44,  0x44,  0x44,  0x47,  0xFC,  0x40,  0x44,  0x04,  0x40,  0x44,  0x04,  0x40,  0x44, 	/* 03C20 */
+	0x0C,  0x89,  0x04,  0x00,  0x40,  0x3F,  0x82,  0x48,  0x24,  0x83,  0xF8,  0x24,  0x82,  0x48,  0xFF,  0xE2, 	/* 03C30 */
+	0x08,  0x20,  0x82,  0x18,  0x8A,  0x00,  0x03,  0xFC,  0x29,  0x42,  0x94,  0x29,  0x42,  0x94,  0xFF,  0xE2, 	/* 03C40 */
+	0x94,  0x29,  0x42,  0x94,  0x29,  0x42,  0x0C,  0x8C,  0x7B,  0xC4,  0xA4,  0x4A,  0x44,  0xA4,  0x4A,  0x4F, 	/* 03C50 */
+	0xFE,  0x4A,  0x44,  0xA4,  0x4A,  0x44,  0xA4,  0x4A,  0x49,  0xCC,  0x8D,  0x00,  0x07,  0xFC,  0x04,  0x03, 	/* 03C60 */
+	0xF8,  0x24,  0x83,  0xF8,  0x24,  0x82,  0x48,  0xFF,  0xE2,  0x08,  0x20,  0x82,  0x18,  0x8F,  0x00,  0x07, 	/* 03C70 */
+	0xFE,  0x49,  0x24,  0x92,  0x50,  0xE6,  0x02,  0x4F,  0x24,  0x92,  0x49,  0x24,  0xF2,  0x40,  0x24,  0x06, 	/* 03C80 */
+	0x90,  0x7F,  0xE4,  0x02,  0x5F,  0xA4,  0x02,  0x5F,  0xA0,  0x00,  0x3F,  0xC2,  0x04,  0x3F,  0x42,  0xFC, 	/* 03C90 */
+	0x20,  0x42,  0x0C,  0x91,  0x04,  0x07,  0xFC,  0x44,  0x47,  0xFC,  0x44,  0x47,  0xFC,  0x20,  0x82,  0xE8, 	/* 03CA0 */
+	0x20,  0x82,  0xE8,  0x20,  0x82,  0x18,  0x92,  0x00,  0x07,  0xFC,  0x40,  0x47,  0xFC,  0x40,  0x47,  0xFC, 	/* 03CB0 */
+	0x20,  0x83,  0xF8,  0x20,  0x83,  0xF8,  0x20,  0x83,  0xF8,  0x93,  0x11,  0x07,  0xFC,  0x11,  0x07,  0xFC, 	/* 03CC0 */
+	0x11,  0x0F,  0xFE,  0x24,  0x83,  0xF8,  0x24,  0x8F,  0xFE,  0x20,  0x82,  0x18,  0x95,  0x7F,  0xC4,  0x04, 	/* 03CD0 */
+	0x5F,  0x44,  0x04,  0x5F,  0x43,  0x20,  0xFF,  0xC4,  0x44,  0x7F,  0xC0,  0xA0,  0x32,  0x2C,  0x1E,  0x96, 	/* 03CE0 */
+	0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0xFF,  0xE8,  0x02,  0x80,  0x20,  0x00,  0x00,  0x00,  0x00,  0x00, 	/* 03CF0 */
+	0x00,  0x00,  0x97,  0x00,  0x0F,  0xFE,  0x80,  0x28,  0x02,  0x1E,  0x01,  0x20,  0x12,  0x01,  0x20,  0x12, 	/* 03D00 */
+	0x01,  0x22,  0x22,  0x2C,  0x1E,  0x99,  0x00,  0x0F,  0xFE,  0x90,  0x29,  0x02,  0x1F,  0x81,  0x00,  0x1F, 	/* 03D10 */
+	0x00,  0x10,  0xFF,  0xE0,  0x10,  0x01,  0x00,  0x60,  0xA0,  0x00,  0x0F,  0xFE,  0x80,  0xAF,  0xCA,  0x03, 	/* 03D20 */
+	0xEF,  0xC8,  0x2A,  0x82,  0xA8,  0x28,  0x84,  0x9A,  0x48,  0x28,  0x7E,  0xA2,  0x00,  0x0F,  0xFE,  0x80, 	/* 03D30 */
+	0x2B,  0xFA,  0x0C,  0x45,  0x24,  0xE7,  0x81,  0xB0,  0x76,  0x81,  0xA4,  0x62,  0x00,  0xC0,  0xA4,  0x00, 	/* 03D40 */
+	0x0F,  0xFF,  0x84,  0x11,  0xF0,  0xE2,  0x07,  0xFC,  0x44,  0x44,  0x44,  0x7F,  0xC0,  0xB0,  0x32,  0xAC, 	/* 03D50 */
+	0x1E,  0xA5,  0x00,  0x0F,  0xFE,  0x80,  0x2B,  0xFA,  0x20,  0x83,  0xF8,  0x20,  0x83,  0xF8,  0x04,  0x0F, 	/* 03D60 */
+	0xFE,  0x11,  0x86,  0x04,  0xA6,  0x00,  0x0F,  0xFE,  0x81,  0x27,  0x9C,  0x01,  0x0F,  0xFC,  0x54,  0x45, 	/* 03D70 */
+	0x28,  0x51,  0x85,  0x24,  0x94,  0x28,  0xFE,  0xA8,  0x00,  0x0F,  0xFE,  0x80,  0x2B,  0xFA,  0x00,  0x03, 	/* 03D80 */
+	0xF8,  0x20,  0x87,  0xFC,  0x44,  0x47,  0xFC,  0x44,  0x47,  0xFC,  0xA9,  0x00,  0x0F,  0xFE,  0x88,  0x2B, 	/* 03D90 */
+	0x9A,  0x20,  0x83,  0xB8,  0x20,  0x83,  0xF8,  0x08,  0x03,  0xFE,  0xD5,  0x22,  0x0C,  0xAA,  0x00,  0x0F, 	/* 03DA0 */
+	0xFE,  0x92,  0x2F,  0xFE,  0x21,  0x03,  0xF0,  0x21,  0x0F,  0xFE,  0x29,  0x07,  0xF8,  0xA9,  0x62,  0xB0, 	/* 03DB0 */
+	0xAB,  0x08,  0x00,  0x40,  0x04,  0x00,  0x00,  0x01,  0x00,  0x20,  0x04,  0x00,  0x40,  0x08,  0x00,  0x80, 	/* 03DC0 */
+	0x08,  0x00,  0x00,  0xAC,  0x04,  0x00,  0xF8,  0x10,  0x82,  0x90,  0xC6,  0x00,  0xA0,  0x31,  0x8C,  0xC6, 	/* 03DD0 */
+	0x02,  0x01,  0x80,  0x06,  0x00,  0x10,  0xB0,  0x01,  0x08,  0x10,  0x41,  0x04,  0x11,  0x1D,  0x20,  0x5C, 	/* 03DE0 */
+	0x05,  0x82,  0x94,  0x49,  0x25,  0x11,  0x81,  0x08,  0x30,  0xB1,  0x00,  0x09,  0xFE,  0x44,  0x04,  0x40, 	/* 03DF0 */
+	0x07,  0xC0,  0x44,  0x08,  0x42,  0x88,  0x4F,  0x84,  0x88,  0x80,  0x89,  0xFF,  0xB2,  0x01,  0x08,  0x10, 	/* 03E00 */
+	0x41,  0x04,  0xFF,  0x09,  0x10,  0x91,  0x09,  0x12,  0xFF,  0x49,  0x04,  0x10,  0x81,  0x08,  0x10,  0xB3, 	/* 03E10 */
+	0x01,  0x08,  0x10,  0x4F,  0xE4,  0x12,  0x01,  0x20,  0x12,  0x3F,  0xF4,  0x10,  0x41,  0x08,  0x28,  0x84, 	/* 03E20 */
+	0x41,  0x83,  0xB4,  0x00,  0x08,  0xFE,  0x44,  0x84,  0x48,  0x04,  0x81,  0xFE,  0x01,  0x82,  0x18,  0x42, 	/* 03E30 */
+	0x84,  0xC8,  0xB0,  0x88,  0x18,  0xB5,  0x00,  0x08,  0xFC,  0x48,  0x44,  0x84,  0x08,  0x40,  0xFC,  0x25, 	/* 03E40 */
+	0x04,  0x50,  0x45,  0x08,  0x92,  0x91,  0x22,  0x0E,  0xB6,  0x02,  0x08,  0x20,  0x42,  0x84,  0x44,  0x09, 	/* 03E50 */
+	0xE1,  0xE2,  0x00,  0x02,  0xFC,  0x48,  0x44,  0x84,  0x88,  0x48,  0xFC,  0xB7,  0x02,  0x08,  0x20,  0x45, 	/* 03E60 */
+	0x04,  0x98,  0x1F,  0xC2,  0x02,  0x0F,  0xC2,  0x24,  0x42,  0x44,  0x38,  0x82,  0x08,  0x20,  0xBD,  0x00, 	/* 03E70 */
+	0x29,  0xEA,  0x48,  0xA4,  0x8A,  0x1E,  0xA1,  0x2A,  0x1A,  0xA6,  0x6A,  0x44,  0xA8,  0x42,  0x88,  0x21, 	/* 03E80 */
+	0x06,  0x84,  0x02,  0x09,  0xFE,  0x42,  0x04,  0xFC,  0x02,  0x41,  0xFE,  0x22,  0x45,  0xFE,  0x44,  0x88, 	/* 03E90 */
+	0xE8,  0x83,  0x81,  0xC4,  0x85,  0x00,  0x09,  0xFE,  0x52,  0x25,  0xFE,  0x12,  0x21,  0x22,  0x3F,  0xA5, 	/* 03EA0 */
+	0x8A,  0x58,  0xA9,  0xFA,  0x90,  0x21,  0xFE,  0x86,  0x04,  0x48,  0x48,  0x4F,  0xE4,  0x90,  0x19,  0x02, 	/* 03EB0 */
+	0xFC,  0x29,  0x04,  0x90,  0x4F,  0xC8,  0x90,  0x89,  0x00,  0xFE,  0x89,  0x02,  0x09,  0xFE,  0x40,  0x04, 	/* 03EC0 */
+	0xFC,  0x08,  0x40,  0x84,  0x2F,  0xC4,  0x20,  0x4A,  0x88,  0xA4,  0x92,  0x40,  0x60,  0x8B,  0x00,  0x08, 	/* 03ED0 */
+	0xFE,  0x49,  0x24,  0xBA,  0x09,  0x20,  0xFE,  0x28,  0x24,  0xBA,  0x4A,  0xA8,  0xBA,  0x90,  0x22,  0x06, 	/* 03EE0 */
+	0x8C,  0x02,  0x09,  0xFC,  0x42,  0x05,  0xFE,  0x05,  0x03,  0x9E,  0x04,  0x04,  0x78,  0x58,  0x88,  0x70, 	/* 03EF0 */
+	0x8D,  0x8B,  0x06,  0x8D,  0x02,  0x09,  0xFE,  0x42,  0x04,  0xFC,  0x0A,  0x40,  0xFC,  0x2A,  0x44,  0xFC, 	/* 03F00 */
+	0x47,  0x08,  0xAC,  0xB2,  0x20,  0x20,  0x96,  0x04,  0x88,  0x50,  0x4F,  0xE1,  0x90,  0x0F,  0xC4,  0x90, 	/* 03F10 */
+	0x8F,  0xE8,  0x40,  0x04,  0x0F,  0xFE,  0x04,  0x00,  0x40,  0x9B,  0x01,  0x09,  0xFF,  0x4A,  0xA4,  0xBA, 	/* 03F20 */
+	0x08,  0x20,  0xFE,  0x27,  0xC4,  0x00,  0x5F,  0xF8,  0x92,  0x91,  0x10,  0x30,  0x9C,  0x02,  0x0B,  0xFE, 	/* 03F30 */
+	0x50,  0x41,  0x74,  0x15,  0x41,  0xFC,  0x01,  0x82,  0xE0,  0x5F,  0xE4,  0xA8,  0x92,  0x48,  0x20,  0x9D, 	/* 03F40 */
+	0x23,  0xE2,  0x42,  0xB9,  0x46,  0x48,  0x1F,  0xE1,  0x0A,  0x1E,  0x86,  0xAE,  0x5E,  0x88,  0xA8,  0x95, 	/* 03F50 */
+	0x82,  0x46,  0xA0,  0x1F,  0x01,  0x10,  0x11,  0x01,  0x10,  0x11,  0x01,  0x10,  0x11,  0x01,  0x10,  0x21, 	/* 03F60 */
+	0x02,  0x12,  0x41,  0x28,  0x0E,  0xA1,  0x00,  0x01,  0xF0,  0x11,  0x01,  0x10,  0x11,  0x01,  0x90,  0x15, 	/* 03F70 */
+	0x01,  0x50,  0x11,  0x02,  0x12,  0x21,  0x24,  0x0E,  0xA6,  0x20,  0x02,  0x38,  0x3A,  0x82,  0xA8,  0x4A, 	/* 03F80 */
+	0x84,  0xA8,  0xAA,  0xA1,  0x2A,  0x14,  0x62,  0x80,  0x46,  0x08,  0x1F,  0xA7,  0x00,  0x07,  0xFC,  0x44, 	/* 03F90 */
+	0x44,  0x44,  0x5F,  0x45,  0x54,  0x55,  0x45,  0x54,  0x55,  0x45,  0x75,  0x84,  0x38,  0x41,  0xA9,  0x00, 	/* 03FA0 */
+	0x07,  0xFC,  0x44,  0x44,  0x44,  0x7F,  0xC4,  0x44,  0x4E,  0x44,  0xD4,  0x54,  0xC6,  0x45,  0x84,  0x38, 	/* 03FB0 */
+	0x41,  0xAA,  0x00,  0x07,  0xFC,  0x44,  0x44,  0x44,  0x54,  0x45,  0x74,  0x54,  0x45,  0x44,  0x54,  0x57, 	/* 03FC0 */
+	0xFB,  0x40,  0x38,  0x01,  0xAD,  0x20,  0xC2,  0xF0,  0x41,  0x0D,  0xFE,  0x41,  0x04,  0xFC,  0x40,  0x01, 	/* 03FD0 */
+	0xF0,  0x11,  0x01,  0x12,  0x21,  0x24,  0x0E,  0xB0,  0x00,  0x07,  0xFC,  0x44,  0x45,  0xF4,  0x51,  0x45, 	/* 03FE0 */
+	0xF4,  0x51,  0x45,  0xF4,  0x44,  0x45,  0xF5,  0x84,  0x3B,  0xF9,  0xB1,  0x20,  0x0A,  0xBC,  0xFA,  0x40, 	/* 03FF0 */
+	0x24,  0xFA,  0x40,  0x24,  0xFA,  0x48,  0xA4,  0xFA,  0x45,  0x24,  0x7C,  0x4C,  0x87,  0xB5,  0x40,  0x24, 	/* 04000 */
+	0x02,  0x40,  0x24,  0x02,  0x40,  0x24,  0x02,  0x40,  0x24,  0x02,  0x40,  0x24,  0x02,  0x7F,  0xE4,  0x02, 	/* 04010 */
+	0xB6,  0x00,  0x84,  0x0A,  0x50,  0xA4,  0x92,  0x45,  0x24,  0x22,  0x45,  0x24,  0x8A,  0x70,  0xA4,  0x02, 	/* 04020 */
+	0x7F,  0xE4,  0x00,  0xB8,  0x00,  0x01,  0xF0,  0x11,  0x01,  0x10,  0x11,  0x0F,  0x1E,  0x80,  0x28,  0x02, 	/* 04030 */
+	0x80,  0x28,  0x02,  0xFF,  0xE0,  0x00,  0xB9,  0x00,  0x0F,  0x1E,  0x91,  0x29,  0x12,  0x91,  0x29,  0x12, 	/* 04040 */
+	0x9F,  0x28,  0x02,  0x80,  0x28,  0x02,  0xFF,  0xE0,  0x00,  0xBA,  0x04,  0x00,  0x40,  0x24,  0x82,  0x48, 	/* 04050 */
+	0x24,  0x83,  0xF8,  0x04,  0x04,  0x44,  0x44,  0x44,  0x44,  0x44,  0x47,  0xFC,  0xBD,  0x00,  0x07,  0xFC, 	/* 04060 */
+	0x04,  0x08,  0x42,  0x8E,  0xAA,  0x2A,  0x97,  0x28,  0xAA,  0xB2,  0x68,  0x62,  0x80,  0x2F,  0xFE,  0xBE, 	/* 04070 */
+	0x00,  0x01,  0xF8,  0x01,  0x08,  0x62,  0x84,  0x2B,  0xFE,  0xAD,  0x6A,  0xCA,  0xBD,  0x68,  0x62,  0x8C, 	/* 04080 */
+	0x2F,  0xFE,  0x80,  0x00,  0x07,  0xFE,  0x02,  0x20,  0x22,  0x02,  0x20,  0x22,  0x04,  0x20,  0x42,  0x08, 	/* 04090 */
+	0x20,  0x82,  0x10,  0x22,  0x0C,  0x83,  0x00,  0x07,  0xFE,  0x04,  0x20,  0x42,  0x04,  0x21,  0xC2,  0x06, 	/* 040A0 */
+	0x20,  0x52,  0x08,  0x20,  0x82,  0x10,  0x22,  0x0C,  0x84,  0x00,  0x07,  0xFC,  0x04,  0x40,  0x44,  0x44, 	/* 040B0 */
+	0x42,  0x44,  0x14,  0x40,  0x84,  0x0E,  0x41,  0x1E,  0x20,  0x44,  0x18,  0x86,  0x09,  0x00,  0x90,  0x08, 	/* 040C0 */
+	0x81,  0x08,  0x20,  0x45,  0xFA,  0x84,  0x90,  0x48,  0x04,  0x80,  0x88,  0x10,  0x82,  0x30,  0x87,  0x00, 	/* 040D0 */
+	0x04,  0xFE,  0x41,  0x24,  0xD2,  0xF1,  0x24,  0x12,  0x41,  0x24,  0x92,  0x3A,  0x20,  0x22,  0x04,  0x21, 	/* 040E0 */
+	0x8C,  0x88,  0x00,  0x20,  0x52,  0x05,  0x20,  0x52,  0xC9,  0x22,  0x92,  0x11,  0x21,  0x92,  0x25,  0x22, 	/* 040F0 */
+	0x42,  0x40,  0x28,  0x06,  0x8A,  0x00,  0x27,  0xD2,  0x11,  0x21,  0x12,  0x11,  0x2F,  0xD2,  0x11,  0x21, 	/* 04100 */
+	0x12,  0x11,  0x21,  0x02,  0x10,  0x21,  0x06,  0x8B,  0x1C,  0x2F,  0x12,  0x11,  0x21,  0x12,  0x11,  0x2F, 	/* 04110 */
+	0xF2,  0x11,  0x21,  0x12,  0x11,  0x21,  0x02,  0x20,  0x24,  0x06,  0x8E,  0x20,  0x22,  0x0A,  0x7E,  0xA5, 	/* 04120 */
+	0x6A,  0x96,  0xA2,  0x6A,  0x2A,  0xA4,  0xAA,  0x92,  0xA2,  0x22,  0x42,  0x20,  0xC6,  0x91,  0x00,  0x2F, 	/* 04130 */
+	0xD2,  0x49,  0x24,  0x92,  0x49,  0x2F,  0xF2,  0x49,  0x24,  0x92,  0x49,  0x24,  0x82,  0x48,  0x28,  0x86, 	/* 04140 */
+	0x94,  0x20,  0x22,  0x12,  0x7D,  0x22,  0x52,  0x25,  0x22,  0x52,  0xFF,  0x22,  0x12,  0x31,  0x22,  0x82, 	/* 04150 */
+	0x48,  0x28,  0x06,  0x97,  0x00,  0x2F,  0xD2,  0x21,  0x22,  0x12,  0x3D,  0x24,  0x52,  0x65,  0x29,  0x92, 	/* 04160 */
+	0x09,  0x21,  0x02,  0x20,  0x24,  0x06,  0x9D,  0x20,  0x02,  0x7E,  0xF9,  0x20,  0x92,  0x11,  0x22,  0x52, 	/* 04170 */
+	0x39,  0x26,  0x92,  0xA6,  0x22,  0x22,  0x24,  0x22,  0x8C,  0xA4,  0x10,  0x29,  0x52,  0x55,  0x25,  0x92, 	/* 04180 */
+	0x7D,  0x21,  0x12,  0x11,  0x2F,  0xF2,  0x11,  0x21,  0x02,  0x10,  0x21,  0x06,  0xA5,  0x00,  0x27,  0xD2, 	/* 04190 */
+	0x45,  0x24,  0x52,  0x7D,  0x22,  0x12,  0x3D,  0x22,  0x52,  0x25,  0x22,  0x42,  0x44,  0x29,  0x86,  0xA7, 	/* 041A0 */
+	0x20,  0x02,  0x7E,  0xF9,  0x22,  0x12,  0x21,  0x2F,  0xD2,  0x21,  0x22,  0x12,  0x51,  0x24,  0xA2,  0xFA, 	/* 041B0 */
+	0x20,  0x4C,  0xA9,  0x0C,  0x27,  0x12,  0x11,  0x21,  0x12,  0xFD,  0x23,  0x12,  0x39,  0x25,  0x52,  0x50, 	/* 041C0 */
+	0x29,  0x02,  0x10,  0x21,  0x06,  0xAA,  0x00,  0x2F,  0xEA,  0xAA,  0xAA,  0xAA,  0xAA,  0xAF,  0xFA,  0xAA, 	/* 041D0 */
+	0xAA,  0xAA,  0xAA,  0xAA,  0xA2,  0xAA,  0x28,  0x66,  0xAE,  0x06,  0x27,  0x92,  0x11,  0x21,  0x12,  0xFF, 	/* 041E0 */
+	0x21,  0x12,  0x11,  0x27,  0xD2,  0x45,  0x24,  0x42,  0x44,  0x27,  0xC6,  0xB0,  0x00,  0x2F,  0xF2,  0x11, 	/* 041F0 */
+	0x22,  0x92,  0xFD,  0x21,  0x32,  0x11,  0x2F,  0xD2,  0x11,  0x21,  0x02,  0x1E,  0x2E,  0x06,  0xB3,  0x10, 	/* 04200 */
+	0x2F,  0xEA,  0x28,  0xA4,  0x4A,  0xBA,  0xA0,  0x0A,  0xFE,  0xA2,  0x0A,  0x3C,  0xA4,  0x42,  0x04,  0x21, 	/* 04210 */
+	0x86,  0xB6,  0x50,  0x25,  0x12,  0x7D,  0x29,  0x12,  0xFF,  0x21,  0x12,  0x7D,  0x25,  0x52,  0x55,  0x25, 	/* 04220 */
+	0x52,  0x58,  0x21,  0x06,  0xB7,  0x7C,  0x24,  0x52,  0x45,  0x27,  0xD2,  0x51,  0x27,  0xD2,  0x55,  0x25, 	/* 04230 */
+	0x52,  0xD5,  0x2D,  0x42,  0x5C,  0x21,  0x06,  0xB8,  0x24,  0x81,  0x48,  0x15,  0x07,  0xFC,  0x0A,  0x0F, 	/* 04240 */
+	0xFE,  0x11,  0x03,  0xF8,  0xC9,  0x60,  0x90,  0x11,  0x02,  0x60,  0xB9,  0x04,  0x26,  0x92,  0x11,  0x22, 	/* 04250 */
+	0x92,  0xC5,  0x21,  0x12,  0xFF,  0x21,  0x92,  0x35,  0x25,  0x02,  0x90,  0x21,  0x06,  0xBA,  0x10,  0x2F, 	/* 04260 */
+	0xF2,  0x11,  0x27,  0xD2,  0x55,  0x25,  0x52,  0x55,  0x23,  0x92,  0x55,  0x29,  0x02,  0x10,  0x21,  0x06, 	/* 04270 */
+	0xBB,  0x10,  0x21,  0x12,  0xFF,  0x21,  0x12,  0x29,  0x26,  0x92,  0x15,  0x22,  0x52,  0x48,  0x21,  0x82, 	/* 04280 */
+	0x24,  0x2C,  0x06,  0x83,  0x44,  0x22,  0x92,  0xFD,  0x21,  0x52,  0x7D,  0x29,  0x12,  0xFD,  0x21,  0x52, 	/* 04290 */
+	0x35,  0x25,  0xC2,  0x90,  0x21,  0x06,  0x84,  0x00,  0x2F,  0xF2,  0x55,  0x25,  0x52,  0xA9,  0x25,  0x52, 	/* 042A0 */
+	0x55,  0x20,  0x12,  0xFD,  0x21,  0x02,  0x1E,  0x2F,  0x06,  0x87,  0x00,  0x27,  0x92,  0x49,  0x27,  0x92, 	/* 042B0 */
+	0x49,  0x27,  0x92,  0x49,  0x24,  0x92,  0x79,  0x22,  0x82,  0x44,  0x28,  0x06,  0x8A,  0x10,  0x29,  0x52, 	/* 042C0 */
+	0x59,  0x27,  0xD2,  0x45,  0x27,  0xD2,  0x45,  0x27,  0xD2,  0x45,  0x24,  0x42,  0x44,  0x24,  0xC6,  0x8B, 	/* 042D0 */
+	0x10,  0x2F,  0xD2,  0x11,  0x27,  0xD2,  0x45,  0x24,  0x52,  0x7D,  0x22,  0x92,  0x28,  0x24,  0x86,  0x48, 	/* 042E0 */
+	0x18,  0x7F,  0x8C,  0x10,  0x21,  0x12,  0xFF,  0x21,  0x12,  0xFD,  0x29,  0x52,  0x95,  0x2F,  0xD2,  0x39, 	/* 042F0 */
+	0x25,  0x42,  0x90,  0x21,  0x06,  0x8D,  0x21,  0x01,  0x20,  0xFF,  0xE0,  0x00,  0x7A,  0x44,  0xA4,  0x7A, 	/* 04300 */
+	0x44,  0xA4,  0x7A,  0x44,  0xA4,  0x48,  0x45,  0x8C,  0x8F,  0x88,  0x04,  0xBE,  0x50,  0xAF,  0x8A,  0x52, 	/* 04310 */
+	0xA5,  0x1A,  0xFC,  0xE5,  0x0B,  0x51,  0x25,  0x12,  0x92,  0x29,  0x4C,  0x94,  0x00,  0x27,  0xCA,  0x44, 	/* 04320 */
+	0xA7,  0xCA,  0x44,  0xA7,  0xCA,  0x20,  0xA7,  0xEA,  0xAA,  0xA4,  0xA2,  0x92,  0x22,  0xC6,  0x96,  0x10, 	/* 04330 */
+	0x21,  0x12,  0xFF,  0x24,  0x52,  0x29,  0x2F,  0xF2,  0x01,  0x27,  0xD2,  0x45,  0x24,  0x42,  0x7C,  0x24, 	/* 04340 */
+	0x06,  0x9B,  0x00,  0x2F,  0xEA,  0x82,  0xAC,  0x6A,  0xAA,  0xAF,  0xEA,  0x92,  0xAD,  0x6A,  0xD6,  0xAF, 	/* 04350 */
+	0xE2,  0x82,  0x28,  0x66,  0x9E,  0x10,  0x2F,  0xF2,  0x11,  0x22,  0x92,  0x45,  0x2F,  0xF2,  0x05,  0x27, 	/* 04360 */
+	0x52,  0x55,  0x27,  0x42,  0x04,  0x20,  0xC6,  0xA3,  0x10,  0x22,  0x92,  0x45,  0x2B,  0xB2,  0x11,  0x27, 	/* 04370 */
+	0xD2,  0x55,  0x27,  0xD2,  0x19,  0x21,  0x42,  0x22,  0x2C,  0x06,  0xA4,  0x10,  0x2F,  0xF2,  0x45,  0x23, 	/* 04380 */
+	0x92,  0x29,  0x2C,  0x72,  0x7D,  0x24,  0x52,  0x7D,  0x24,  0x42,  0x44,  0x28,  0xC6,  0xA5,  0x78,  0x20, 	/* 04390 */
+	0x92,  0x39,  0x20,  0x92,  0xFF,  0x21,  0x32,  0x55,  0x23,  0x92,  0x58,  0x29,  0x62,  0x10,  0x23,  0x06, 	/* 043A0 */
+	0xA9,  0x0C,  0x27,  0x0A,  0x10,  0xAF,  0xFA,  0x54,  0xAD,  0x6A,  0x54,  0xAD,  0x6A,  0x38,  0xA5,  0x42, 	/* 043B0 */
+	0x90,  0x21,  0x06,  0xAA,  0x20,  0x81,  0x10,  0xFF,  0xE6,  0xA4,  0x5A,  0x46,  0xA4,  0x5A,  0x44,  0x8C, 	/* 043C0 */
+	0xFF,  0xC0,  0x44,  0x18,  0x4E,  0x18,  0xAF,  0x00,  0x2F,  0xD2,  0x01,  0x27,  0xD2,  0x45,  0x27,  0xD2, 	/* 043D0 */
+	0x01,  0x2F,  0xD2,  0x95,  0x2F,  0xC2,  0x94,  0x2F,  0xC6,  0xB0,  0x0C,  0x27,  0x12,  0x11,  0x2F,  0xF2, 	/* 043E0 */
+	0x55,  0x2F,  0xF2,  0x55,  0x2F,  0xF2,  0x39,  0x25,  0x42,  0x92,  0x21,  0x06,  0xB1,  0x20,  0x03,  0x7E, 	/* 043F0 */
+	0x49,  0x2F,  0x52,  0x21,  0x2F,  0xB2,  0xA9,  0xAF,  0x97,  0x32,  0x22,  0xA2,  0x44,  0x28,  0x8C,  0xB2, 	/* 04400 */
+	0x10,  0x2F,  0xF2,  0x93,  0x27,  0xD2,  0x11,  0x27,  0xD2,  0x11,  0x2F,  0xF2,  0x01,  0x27,  0xC2,  0x44, 	/* 04410 */
+	0x27,  0xC6,  0xB3,  0x44,  0x2F,  0xEA,  0x44,  0xA1,  0x0A,  0x28,  0xA4,  0x4A,  0xBE,  0xA0,  0x0A,  0x7C, 	/* 04420 */
+	0xA4,  0x42,  0x44,  0x27,  0xC6,  0xB4,  0x10,  0x25,  0x52,  0x7D,  0x20,  0x12,  0xFF,  0x20,  0x12,  0x7D, 	/* 04430 */
+	0x24,  0x52,  0x7D,  0x24,  0x82,  0x3C,  0x2E,  0x06,  0xB5,  0x10,  0x22,  0x82,  0x45,  0x2F,  0xD2,  0x45, 	/* 04440 */
+	0x27,  0xD2,  0x45,  0x27,  0xD2,  0x41,  0x2B,  0xC2,  0xA4,  0x23,  0xC6,  0xBD,  0xFF,  0x22,  0x8A,  0xFE, 	/* 04450 */
+	0xAA,  0xAA,  0xFE,  0xA0,  0x0A,  0x7C,  0xA0,  0x0A,  0xFE,  0xA5,  0x42,  0x92,  0x23,  0x06,  0xBF,  0x54, 	/* 04460 */
+	0x2A,  0x92,  0x55,  0x27,  0xD2,  0x55,  0x27,  0xD2,  0x55,  0x2F,  0xF2,  0x39,  0x25,  0x42,  0x92,  0x21, 	/* 04470 */
+	0x06,  0x83,  0x10,  0x27,  0xD2,  0x15,  0x2F,  0xF2,  0x15,  0x2F,  0xF2,  0x55,  0x27,  0xD2,  0x55,  0x27, 	/* 04480 */
+	0xC2,  0x1E,  0x2E,  0x06,  0x87,  0x1C,  0x21,  0x12,  0x7D,  0x26,  0x52,  0x79,  0x24,  0x12,  0x7D,  0x25, 	/* 04490 */
+	0x32,  0x6D,  0x25,  0xC2,  0xAA,  0x21,  0x06,  0x88,  0x78,  0x84,  0xFE,  0x79,  0x44,  0x14,  0x7F,  0xEC, 	/* 044A0 */
+	0x88,  0x7B,  0xE0,  0x08,  0x7F,  0xE0,  0x82,  0x10,  0x26,  0x1C,  0x89,  0x20,  0x2D,  0xE2,  0xAB,  0x2A, 	/* 044B0 */
+	0xB2,  0xF5,  0x22,  0x92,  0xFD,  0x21,  0x12,  0xFD,  0x29,  0x02,  0x5C,  0x2F,  0x06,  0x8D,  0x20,  0x23, 	/* 044C0 */
+	0x12,  0x49,  0x2B,  0x52,  0x01,  0x2F,  0xD2,  0xB5,  0x2F,  0xD2,  0x49,  0x26,  0xD2,  0xB2,  0x29,  0x06, 	/* 044D0 */
+	0x91,  0x10,  0x2F,  0xEA,  0x28,  0xAF,  0x7A,  0x56,  0xAB,  0x5A,  0x44,  0xA7,  0xCA,  0x44,  0xA7,  0xC2, 	/* 044E0 */
+	0x44,  0x28,  0x46,  0x92,  0x20,  0x03,  0x7E,  0x48,  0xAF,  0x4A,  0x01,  0xAF,  0xDA,  0xB6,  0xAF,  0xD2, 	/* 044F0 */
+	0x51,  0x25,  0xA2,  0xA4,  0x28,  0x8C,  0x94,  0x20,  0x03,  0x7E,  0x48,  0xAF,  0x6A,  0x02,  0xAF,  0xDA, 	/* 04500 */
+	0xB4,  0xAF,  0xD6,  0x51,  0x35,  0xA2,  0xA4,  0x28,  0x8C,  0x9B,  0x04,  0x00,  0x40,  0x04,  0x07,  0xFC, 	/* 04510 */
+	0x04,  0x40,  0x44,  0x04,  0x40,  0x84,  0x08,  0x41,  0x04,  0x20,  0x44,  0x18,  0x9F,  0x01,  0x00,  0x10, 	/* 04520 */
+	0xF1,  0x02,  0xFE,  0x21,  0x22,  0x12,  0x21,  0x22,  0x92,  0x32,  0x2C,  0x22,  0x04,  0x20,  0x8C,  0xA0, 	/* 04530 */
+	0x20,  0x02,  0x00,  0x21,  0xEF,  0xD2,  0x25,  0x22,  0x52,  0x25,  0x22,  0x52,  0x25,  0x24,  0x52,  0x45, 	/* 04540 */
+	0xE9,  0x80,  0xA3,  0x04,  0x02,  0x48,  0x24,  0x44,  0xD2,  0x86,  0x21,  0x80,  0xE4,  0x07,  0xFC,  0x04, 	/* 04550 */
+	0x40,  0x84,  0x10,  0x46,  0x18,  0xA9,  0x01,  0x07,  0x90,  0x49,  0x04,  0xFE,  0x79,  0x24,  0x92,  0x49, 	/* 04560 */
+	0x27,  0x92,  0x49,  0x25,  0xE2,  0xE2,  0x20,  0x4C,  0xAA,  0x10,  0x0F,  0xBC,  0x28,  0x44,  0xA8,  0x31, 	/* 04570 */
+	0x02,  0xE8,  0xC4,  0x67,  0xFC,  0x04,  0x40,  0x44,  0x18,  0x46,  0x18,  0xAB,  0x10,  0x81,  0x08,  0x7C, 	/* 04580 */
+	0x81,  0x3E,  0x10,  0xAF,  0xEA,  0x10,  0xA1,  0x12,  0x29,  0x23,  0xD2,  0xC2,  0x20,  0x4C,  0xAC,  0x21, 	/* 04590 */
+	0x02,  0x10,  0x3D,  0x04,  0x7E,  0x45,  0x2F,  0x52,  0x55,  0x25,  0x52,  0x75,  0x20,  0x62,  0x04,  0x21, 	/* 045A0 */
+	0x8C,  0xAD,  0x01,  0x0F,  0x90,  0x29,  0x02,  0xFE,  0x49,  0x25,  0x92,  0x81,  0x27,  0x92,  0x4A,  0x24, 	/* 045B0 */
+	0xA2,  0x4C,  0x27,  0x8C,  0xB1,  0x0C,  0x87,  0x08,  0x40,  0x87,  0xFE,  0x50,  0xA5,  0xCA,  0x54,  0xA5, 	/* 045C0 */
+	0x4A,  0x55,  0x25,  0x52,  0xA6,  0x2C,  0xCC,  0xB4,  0x48,  0x42,  0x44,  0x14,  0x8F,  0xFE,  0x88,  0x28, 	/* 045D0 */
+	0x82,  0x7F,  0x80,  0x88,  0x08,  0x81,  0x08,  0x20,  0x84,  0x30,  0xB5,  0x04,  0x01,  0x50,  0x14,  0x83, 	/* 045E0 */
+	0xFC,  0x0A,  0x0F,  0xFE,  0x11,  0x02,  0x88,  0xFF,  0x60,  0x90,  0x11,  0x02,  0x60,  0xB9,  0x11,  0x01, 	/* 045F0 */
+	0x10,  0xFD,  0x02,  0xFE,  0x49,  0x28,  0xD2,  0x29,  0x21,  0x12,  0x12,  0x22,  0xA2,  0x44,  0x28,  0x8C, 	/* 04600 */
+	0xBC,  0x21,  0x02,  0x10,  0xFD,  0x02,  0x7E,  0x21,  0x2F,  0x92,  0x01,  0x27,  0x92,  0x4A,  0x24,  0xA2, 	/* 04610 */
+	0x4C,  0x27,  0x8C,  0xBE,  0x11,  0x01,  0x10,  0xFD,  0x02,  0x7E,  0x51,  0x2D,  0x12,  0x29,  0x24,  0x92, 	/* 04620 */
+	0x92,  0x22,  0xA2,  0x44,  0x28,  0x8C,  0x81,  0x01,  0x0F,  0xD0,  0x55,  0x05,  0x7E,  0xA9,  0x25,  0x52, 	/* 04630 */
+	0x01,  0x2F,  0xD2,  0x11,  0x21,  0x22,  0x1A,  0x2E,  0x4C,  0x83,  0x21,  0x0F,  0xD0,  0x21,  0x0F,  0xFE, 	/* 04640 */
+	0x85,  0x27,  0x92,  0x11,  0x21,  0xD2,  0xF1,  0x21,  0x22,  0x12,  0x23,  0x4C,  0x85,  0x11,  0x07,  0xD0, 	/* 04650 */
+	0x11,  0x07,  0xFE,  0x55,  0x25,  0x52,  0x7D,  0x23,  0x92,  0x35,  0x25,  0x22,  0x92,  0x21,  0x4C,  0x87, 	/* 04660 */
+	0x3F,  0x80,  0x90,  0x3F,  0xC2,  0x44,  0x3F,  0xC2,  0x44,  0x3F,  0xC0,  0x40,  0x7F,  0xE0,  0x82,  0x30, 	/* 04670 */
+	0x2C,  0x0C,  0x89,  0x20,  0x83,  0xC8,  0x48,  0x8F,  0xFE,  0x54,  0xA5,  0x4A,  0x7C,  0xA1,  0x92,  0x29, 	/* 04680 */
+	0x22,  0xAC,  0x48,  0x18,  0x7F,  0x8D,  0x11,  0x0F,  0xD0,  0x01,  0x07,  0xFE,  0x49,  0x24,  0x92,  0x79, 	/* 04690 */
+	0x21,  0x12,  0x59,  0x25,  0x62,  0x92,  0x23,  0x4C,  0x92,  0x51,  0x0F,  0x90,  0x51,  0x07,  0x7E,  0x21, 	/* 046A0 */
+	0x2F,  0x92,  0xA9,  0x2F,  0x92,  0x22,  0x2F,  0xA2,  0x24,  0x22,  0x8C,  0x95,  0x1D,  0x0F,  0x10,  0x13, 	/* 046B0 */
+	0xEF,  0xD2,  0x55,  0x27,  0xD2,  0x55,  0x27,  0xD2,  0x11,  0x27,  0xA2,  0x1E,  0x2E,  0x4C,  0x97,  0x3F, 	/* 046C0 */
+	0x82,  0x08,  0x3F,  0x82,  0x08,  0x3F,  0x87,  0x90,  0x4F,  0xE7,  0x92,  0x49,  0x27,  0x92,  0x5A,  0x2E, 	/* 046D0 */
+	0x4C,  0x98,  0x49,  0x0F,  0xD0,  0x49,  0x07,  0xFE,  0x49,  0x27,  0x92,  0x49,  0x2F,  0xD2,  0xA9,  0x2C, 	/* 046E0 */
+	0xD2,  0x82,  0x27,  0xCC,  0x99,  0x02,  0x0F,  0xBE,  0x0C,  0x85,  0x28,  0x21,  0x8F,  0xE6,  0x29,  0x02, 	/* 046F0 */
+	0xFC,  0x61,  0x4A,  0x24,  0x24,  0x46,  0x98,  0x9D,  0x01,  0x07,  0x54,  0x5F,  0xE5,  0x10,  0x7F,  0xE5, 	/* 04700 */
+	0x28,  0x55,  0x47,  0xFE,  0x52,  0x55,  0x24,  0x54,  0x4B,  0x98,  0x9E,  0x11,  0x05,  0x54,  0x2A,  0x84, 	/* 04710 */
+	0x44,  0xFF,  0xE8,  0x82,  0x08,  0x07,  0xFC,  0x08,  0x40,  0x84,  0x10,  0x46,  0x18,  0x9F,  0x11,  0x0F, 	/* 04720 */
+	0xFE,  0x11,  0x03,  0xF8,  0x20,  0x83,  0xF8,  0x20,  0x8F,  0xFE,  0x24,  0x87,  0xFC,  0x88,  0xA3,  0x30, 	/* 04730 */
+	0xA0,  0xEE,  0x86,  0x68,  0xAA,  0x86,  0x7E,  0xAA,  0xA1,  0x0A,  0x28,  0xAC,  0x4A,  0x31,  0x2C,  0x92, 	/* 04740 */
+	0x32,  0x2C,  0x4C,  0xA2,  0x11,  0x07,  0x90,  0x17,  0xCF,  0xD4,  0x5B,  0xC9,  0x56,  0x7E,  0x20,  0x40, 	/* 04750 */
+	0x7F,  0xC0,  0x44,  0x08,  0x43,  0x18,  0xA3,  0x21,  0x0F,  0x90,  0x21,  0x07,  0xFE,  0x21,  0x2F,  0xD2, 	/* 04760 */
+	0x49,  0x27,  0x92,  0x49,  0x27,  0xA2,  0x2A,  0x2C,  0x4C,  0xA4,  0x29,  0x0F,  0xD0,  0x29,  0x07,  0xFE, 	/* 04770 */
+	0x55,  0x27,  0xD2,  0x11,  0x27,  0xD2,  0x11,  0x27,  0x92,  0x1E,  0x2F,  0x4C,  0xA6,  0x55,  0x0A,  0x90, 	/* 04780 */
+	0x55,  0x07,  0xFE,  0x55,  0x27,  0xD2,  0x55,  0x27,  0xD2,  0x19,  0x23,  0x52,  0x52,  0x29,  0x4C,  0xA7, 	/* 04790 */
+	0x41,  0x07,  0xD0,  0x49,  0x07,  0xFE,  0x91,  0x27,  0xD2,  0xD1,  0x27,  0xD2,  0x51,  0x27,  0xD2,  0x52, 	/* 047A0 */
+	0x27,  0xCC,  0xB2,  0x7D,  0x01,  0x10,  0xFF,  0xE5,  0x52,  0x7D,  0x25,  0x52,  0x7D,  0x21,  0x22,  0xFC, 	/* 047B0 */
+	0xC4,  0x08,  0x52,  0x48,  0x92,  0xB3,  0x0D,  0x0F,  0x10,  0x11,  0x0F,  0xFE,  0xD5,  0x2D,  0xD2,  0xB5, 	/* 047C0 */
+	0x2F,  0xD2,  0x11,  0x2F,  0xE2,  0x5A,  0x29,  0x4C,  0xB5,  0x00,  0x87,  0xE8,  0x54,  0x87,  0xFE,  0x7E, 	/* 047D0 */
+	0xA6,  0xAA,  0x7E,  0xA4,  0x8A,  0x7E,  0xAA,  0xB2,  0xBE,  0x22,  0x6C,  0xB8,  0x48,  0x8F,  0xE8,  0x48, 	/* 047E0 */
+	0x8E,  0xFE,  0xAA,  0xAE,  0xEA,  0x50,  0xAF,  0xCA,  0x51,  0x27,  0xD2,  0x52,  0x27,  0xCC,  0xB9,  0x10, 	/* 047F0 */
+	0x01,  0x00,  0x3F,  0xE2,  0x02,  0x40,  0x28,  0x02,  0x00,  0x20,  0x02,  0x00,  0x20,  0x02,  0x00,  0x40, 	/* 04800 */
+	0x18,  0xBA,  0x10,  0x01,  0x00,  0x1F,  0xC2,  0x04,  0x40,  0x49,  0x04,  0x08,  0x40,  0x44,  0x04,  0x40, 	/* 04810 */
+	0x04,  0x00,  0x40,  0x18,  0xBE,  0x20,  0x02,  0x00,  0x3F,  0xE2,  0x42,  0x44,  0x24,  0x42,  0x8A,  0x20, 	/* 04820 */
+	0x92,  0x17,  0xA7,  0x8A,  0x00,  0x20,  0x0C,  0xBF,  0x20,  0x02,  0x00,  0x3F,  0xE2,  0x92,  0x49,  0x28, 	/* 04830 */
+	0x92,  0x11,  0x21,  0x22,  0x22,  0x24,  0x42,  0x08,  0x21,  0x0C,  0x81,  0x10,  0x01,  0x00,  0x1F,  0xC1, 	/* 04840 */
+	0x24,  0x22,  0x45,  0x24,  0x8C,  0x40,  0x64,  0x09,  0xC1,  0x06,  0x20,  0x40,  0x18,  0x82,  0x10,  0x01, 	/* 04850 */
+	0x00,  0x1F,  0xE2,  0x02,  0x30,  0x25,  0x32,  0x9C,  0x21,  0x02,  0x11,  0x20,  0xF2,  0x00,  0x20,  0x0C, 	/* 04860 */
+	0x85,  0x10,  0x01,  0x00,  0x1F,  0xC2,  0x04,  0xDE,  0x40,  0x24,  0x02,  0x43,  0xE4,  0x20,  0x82,  0x02, 	/* 04870 */
+	0x20,  0x21,  0xFE,  0x86,  0x10,  0x01,  0x00,  0x3F,  0xE2,  0x92,  0x49,  0x2B,  0x92,  0x17,  0x21,  0x2A, 	/* 04880 */
+	0x22,  0x24,  0x42,  0x08,  0x40,  0x18,  0x88,  0x10,  0x01,  0x00,  0x3F,  0xE2,  0x02,  0x42,  0x2B,  0xAA, 	/* 04890 */
+	0x24,  0xA2,  0xAA,  0x30,  0xA3,  0xFA,  0x00,  0x40,  0x18,  0x8D,  0x10,  0x01,  0xFE,  0x25,  0x27,  0xFA, 	/* 048A0 */
+	0x84,  0x23,  0xFA,  0x24,  0xA3,  0xFA,  0x24,  0xA3,  0xFA,  0x24,  0xA0,  0x1C,  0x8F,  0x21,  0x02,  0x10, 	/* 048B0 */
+	0xFB,  0xE2,  0x22,  0x57,  0xAE,  0xAA,  0xFA,  0xA2,  0x3C,  0x3A,  0x04,  0xA2,  0x0A,  0x23,  0x1E,  0x90, 	/* 048C0 */
+	0x10,  0x01,  0xFE,  0x20,  0x27,  0xFA,  0x9F,  0x21,  0x12,  0x3F,  0xA2,  0x4A,  0x3F,  0xA2,  0x4A,  0x3F, 	/* 048D0 */
+	0xA0,  0x1C,  0x95,  0x20,  0x02,  0x00,  0x20,  0x02,  0x10,  0x22,  0x02,  0x40,  0x38,  0x0E,  0x00,  0x20, 	/* 048E0 */
+	0x02,  0x04,  0x20,  0x41,  0xFC,  0x96,  0x12,  0x01,  0x20,  0x12,  0x42,  0x24,  0x22,  0x86,  0x30,  0xA2, 	/* 048F0 */
+	0x02,  0x20,  0x22,  0x02,  0x22,  0x22,  0x22,  0x1E,  0x97,  0x12,  0x01,  0x20,  0x12,  0x01,  0x26,  0xF3, 	/* 04900 */
+	0x81,  0x20,  0x12,  0x01,  0x20,  0x32,  0x0D,  0x22,  0x12,  0x21,  0x1E,  0x99,  0x7A,  0x04,  0xA0,  0x7A, 	/* 04910 */
+	0x04,  0xA6,  0x7B,  0x80,  0x20,  0xFA,  0x01,  0x22,  0x5E,  0x27,  0x1E,  0x5C,  0x08,  0x3F,  0x9A,  0x00, 	/* 04920 */
+	0x07,  0xFF,  0x40,  0x04,  0x00,  0x40,  0x04,  0x00,  0x40,  0x04,  0x00,  0x40,  0x04,  0x00,  0x7F,  0xF4, 	/* 04930 */
+	0x00,  0x9D,  0x00,  0x07,  0xFE,  0x42,  0x04,  0x20,  0x5F,  0xC5,  0x24,  0x52,  0x45,  0x24,  0x52,  0x84, 	/* 04940 */
+	0x20,  0x42,  0x07,  0xFE,  0xA0,  0x00,  0x07,  0xFE,  0x41,  0x84,  0xE0,  0x48,  0x04,  0xFC,  0x49,  0x04, 	/* 04950 */
+	0x90,  0x51,  0x06,  0x10,  0x41,  0x07,  0xFE,  0xA1,  0x00,  0x0F,  0xFE,  0x80,  0x0B,  0xFC,  0x84,  0x08, 	/* 04960 */
+	0x40,  0x9F,  0x88,  0x40,  0x84,  0x0B,  0xFC,  0x80,  0x0F,  0xFE,  0xA3,  0x00,  0x07,  0xFE,  0x40,  0x05, 	/* 04970 */
+	0xFC,  0x52,  0x45,  0xFC,  0x52,  0x45,  0xFC,  0x42,  0x04,  0x20,  0x42,  0x07,  0xFE,  0xAA,  0x00,  0x0F, 	/* 04980 */
+	0xFE,  0x8A,  0x08,  0xA0,  0xBB,  0xC8,  0xA0,  0xBB,  0xC8,  0xA0,  0xFB,  0xE9,  0x20,  0xA2,  0x0F,  0xFE, 	/* 04990 */
+	0xAF,  0x00,  0x0F,  0xFE,  0xA2,  0x89,  0x7E,  0xCD,  0x0A,  0x7C,  0x85,  0x09,  0x7C,  0x95,  0x0A,  0x7E, 	/* 049A0 */
+	0xA0,  0x0F,  0xFE,  0xB1,  0x00,  0x0F,  0xFE,  0x84,  0x09,  0xF8,  0x94,  0x8F,  0xFE,  0x90,  0x89,  0xF8, 	/* 049B0 */
+	0x90,  0x89,  0xF8,  0xB0,  0x4F,  0xFE,  0xB3,  0x00,  0x0F,  0xFE,  0x86,  0x08,  0x90,  0xB0,  0xCF,  0xB8, 	/* 049C0 */
+	0xAA,  0x8B,  0xB8,  0x91,  0x09,  0xA8,  0xA4,  0x4F,  0xFE,  0xB8,  0x00,  0x0F,  0xFE,  0x20,  0x02,  0x00, 	/* 049D0 */
+	0x20,  0x02,  0x00,  0x20,  0x02,  0x00,  0x20,  0x02,  0x00,  0x10,  0x00,  0xFC,  0xB9,  0x00,  0x0F,  0xFE, 	/* 049E0 */
+	0x92,  0x09,  0x20,  0x92,  0x4A,  0x24,  0xC1,  0xC8,  0x00,  0x80,  0x0F,  0xFE,  0x80,  0x00,  0x00,  0xBA, 	/* 049F0 */
+	0x00,  0x07,  0xFE,  0x40,  0x84,  0x08,  0x59,  0x04,  0x50,  0x42,  0x04,  0x50,  0x48,  0x85,  0x00,  0x7F, 	/* 04A00 */
+	0xE4,  0x00,  0xBB,  0x00,  0x07,  0xFE,  0x48,  0x04,  0xF8,  0x52,  0x06,  0x20,  0x5F,  0xC4,  0x20,  0x45, 	/* 04A10 */
+	0x04,  0x88,  0x50,  0x07,  0xFE,  0xBF,  0x00,  0x0F,  0xFE,  0x89,  0x0B,  0xFC,  0x89,  0x0F,  0xFC,  0x88, 	/* 04A20 */
+	0x09,  0xF8,  0xA8,  0x8C,  0xF8,  0x80,  0x0F,  0xFE,  0x80,  0x00,  0x0F,  0xFE,  0x40,  0x04,  0xF8,  0x48, 	/* 04A30 */
+	0x84,  0xF8,  0x40,  0x07,  0xDE,  0x65,  0x27,  0xDE,  0x40,  0x07,  0xFE,  0x81,  0x04,  0x00,  0x40,  0x04, 	/* 04A40 */
+	0x00,  0x40,  0xFF,  0xE0,  0x40,  0x04,  0x00,  0x40,  0x04,  0x00,  0x40,  0x04,  0x00,  0x40,  0x83,  0x00, 	/* 04A50 */
+	0x80,  0x70,  0x7C,  0x00,  0x40,  0x04,  0x0F,  0xFE,  0x04,  0x00,  0x40,  0x04,  0x00,  0x40,  0x04,  0x00, 	/* 04A60 */
+	0x40,  0x85,  0x24,  0x42,  0x44,  0x24,  0x42,  0x44,  0x24,  0x4F,  0xFE,  0x24,  0x42,  0x44,  0x24,  0x44, 	/* 04A70 */
+	0x44,  0x44,  0x48,  0x04,  0x86,  0x08,  0x00,  0x80,  0x7F,  0x01,  0x10,  0x11,  0x02,  0x12,  0x44,  0xE0, 	/* 04A80 */
+	0x40,  0xFF,  0xE0,  0x40,  0x04,  0x00,  0x40,  0x87,  0x01,  0x00,  0xD0,  0x71,  0x01,  0x10,  0x11,  0x0F, 	/* 04A90 */
+	0xFE,  0x11,  0x01,  0x10,  0x11,  0x02,  0x10,  0x21,  0x04,  0x10,  0x88,  0x10,  0x01,  0x00,  0x1F,  0xC2, 	/* 04AA0 */
+	0x20,  0x42,  0x00,  0x20,  0xFF,  0xE0,  0x20,  0x02,  0x00,  0x20,  0x02,  0x00,  0x20,  0x89,  0x04,  0x00, 	/* 04AB0 */
+	0x40,  0x7F,  0xC0,  0x40,  0x14,  0x81,  0x48,  0x10,  0x8F,  0xFE,  0x10,  0x82,  0x08,  0x20,  0x84,  0x08, 	/* 04AC0 */
+	0x8A,  0x04,  0x02,  0x48,  0x14,  0x81,  0x50,  0x7F,  0xC0,  0x40,  0x04,  0x0F,  0xFE,  0x04,  0x00,  0x40, 	/* 04AD0 */
+	0x04,  0x00,  0x40,  0x8D,  0x00,  0x07,  0xC2,  0x04,  0x20,  0x42,  0x04,  0x20,  0x42,  0x7F,  0xE4,  0x40, 	/* 04AE0 */
+	0x44,  0x04,  0x40,  0x44,  0x04,  0x7E,  0x91,  0x08,  0x03,  0xFC,  0x24,  0x43,  0xFC,  0x24,  0x43,  0xFC, 	/* 04AF0 */
+	0x12,  0x02,  0x20,  0xFF,  0xF0,  0x20,  0x02,  0x00,  0x20,  0x92,  0x04,  0x00,  0x40,  0x7F,  0xC1,  0x10, 	/* 04B00 */
+	0x11,  0x02,  0xA8,  0x44,  0x4F,  0xFE,  0x04,  0x00,  0x40,  0x04,  0x00,  0x40,  0x93,  0x04,  0x00,  0x7C, 	/* 04B10 */
+	0x04,  0x03,  0xF8,  0x20,  0x83,  0xF8,  0x20,  0x83,  0xF8,  0x04,  0x0F,  0xFE,  0x04,  0x00,  0x40,  0x94, 	/* 04B20 */
+	0x42,  0x04,  0xFC,  0x42,  0x4F,  0x24,  0x44,  0x44,  0x98,  0x48,  0x87,  0xFE,  0x54,  0xA5,  0x4A,  0x65, 	/* 04B30 */
+	0x24,  0xE6,  0x97,  0x04,  0x0F,  0xFE,  0x04,  0x00,  0x40,  0x7F,  0xC5,  0x14,  0x4A,  0x45,  0xF4,  0x44, 	/* 04B40 */
+	0x45,  0xF4,  0x44,  0x44,  0x4C,  0x98,  0x24,  0x41,  0x28,  0x3F,  0x82,  0x48,  0x3F,  0x82,  0x48,  0x3F, 	/* 04B50 */
+	0x80,  0x40,  0xFF,  0xE0,  0x40,  0x04,  0x00,  0x40,  0x9A,  0x42,  0x45,  0xFE,  0x42,  0x05,  0xFC,  0xF2, 	/* 04B60 */
+	0x45,  0xFC,  0x52,  0x47,  0xFE,  0x40,  0x84,  0x88,  0x44,  0x84,  0x18,  0x9C,  0x08,  0x00,  0x80,  0x08, 	/* 04B70 */
+	0x00,  0xC0,  0x0A,  0x00,  0x90,  0x08,  0x80,  0x88,  0x08,  0x00,  0x80,  0x08,  0x00,  0x80,  0x9E,  0x04, 	/* 04B80 */
+	0x00,  0x40,  0xFF,  0xE0,  0x40,  0x06,  0x00,  0x50,  0x04,  0x80,  0x48,  0x04,  0x00,  0x40,  0x04,  0x00, 	/* 04B90 */
+	0x40,  0xA0,  0x04,  0x00,  0x40,  0x04,  0x00,  0x7E,  0x04,  0x00,  0x40,  0x04,  0x03,  0xF8,  0x20,  0x82, 	/* 04BA0 */
+	0x08,  0x20,  0x83,  0xF8,  0xA6,  0x11,  0x01,  0x10,  0x7D,  0x01,  0x10,  0xFD,  0x81,  0x14,  0x11,  0x27, 	/* 04BB0 */
+	0xD2,  0x11,  0x01,  0xF0,  0xE1,  0x00,  0x10,  0xA9,  0x00,  0x01,  0xFC,  0x10,  0x41,  0x04,  0x10,  0x41, 	/* 04BC0 */
+	0x04,  0x10,  0x41,  0x04,  0x13,  0x81,  0x00,  0x10,  0x01,  0x00,  0xAE,  0x01,  0xC3,  0xE0,  0x20,  0x03, 	/* 04BD0 */
+	0xFE,  0x20,  0x02,  0xF8,  0x28,  0x82,  0x88,  0x2B,  0x04,  0x80,  0x48,  0x28,  0x7E,  0xAF,  0x0C,  0x07, 	/* 04BE0 */
+	0x1E,  0x41,  0x24,  0x92,  0x49,  0x24,  0x92,  0x49,  0x25,  0x92,  0xE9,  0xC0,  0x90,  0x11,  0x02,  0x10, 	/* 04BF0 */
+	0xB0,  0x08,  0x07,  0x3E,  0x42,  0x24,  0x22,  0x7A,  0x24,  0x22,  0x42,  0x24,  0x22,  0x7A,  0xC4,  0x20, 	/* 04C00 */
+	0x02,  0x00,  0x20,  0xB1,  0x08,  0x01,  0xF0,  0x62,  0x00,  0x40,  0x3F,  0xE2,  0x00,  0x2F,  0x82,  0x88, 	/* 04C10 */
+	0x48,  0x84,  0x9A,  0x88,  0x20,  0x7E,  0xB3,  0x00,  0x07,  0xDE,  0x45,  0x27,  0xD2,  0x45,  0x24,  0x52, 	/* 04C20 */
+	0x7D,  0x25,  0x12,  0x49,  0xC7,  0x50,  0xC5,  0x00,  0x10,  0xB4,  0x20,  0x02,  0x1E,  0xFD,  0x22,  0x12, 	/* 04C30 */
+	0x21,  0x2F,  0xD2,  0x21,  0x22,  0x92,  0x4D,  0xC7,  0x50,  0xC5,  0x00,  0x10,  0xB5,  0x0C,  0x07,  0x1E, 	/* 04C40 */
+	0x45,  0x26,  0x52,  0x55,  0xA4,  0x56,  0x45,  0x25,  0x92,  0xE9,  0xC0,  0x90,  0x11,  0x02,  0x10,  0xB7, 	/* 04C50 */
+	0x04,  0x02,  0x48,  0x24,  0x47,  0xFC,  0x0A,  0x0F,  0xFE,  0x11,  0x03,  0xF8,  0xD1,  0x61,  0x70,  0x10, 	/* 04C60 */
+	0x40,  0xFC,  0xB8,  0x20,  0x03,  0xDE,  0x51,  0x29,  0x12,  0x7F,  0x21,  0x12,  0x5D,  0x25,  0x12,  0x51, 	/* 04C70 */
+	0xC5,  0xD0,  0xE1,  0x00,  0x10,  0xBB,  0x10,  0x02,  0x9E,  0x25,  0x25,  0x52,  0x91,  0x22,  0x92,  0x45, 	/* 04C80 */
+	0x2F,  0xB2,  0x49,  0xC4,  0x90,  0x49,  0x07,  0x90,  0xBF,  0x20,  0x0C,  0xEE,  0x8A,  0xAA,  0xEA,  0xAA, 	/* 04C90 */
+	0xAA,  0xAA,  0xAE,  0xAA,  0x8A,  0xEC,  0xE2,  0xA8,  0x5D,  0x88,  0x08,  0x82,  0x00,  0x03,  0xFE,  0x20, 	/* 04CA0 */
+	0x02,  0x00,  0x20,  0x02,  0x00,  0x20,  0x02,  0x00,  0x20,  0x04,  0x00,  0x40,  0x08,  0x00,  0x84,  0x00, 	/* 04CB0 */
+	0x03,  0xFE,  0x20,  0x02,  0x00,  0x2F,  0x82,  0x88,  0x28,  0x82,  0x88,  0x2B,  0x04,  0x82,  0x48,  0x28, 	/* 04CC0 */
+	0x7E,  0x96,  0x00,  0x07,  0xFE,  0x4A,  0x84,  0x88,  0x7F,  0x44,  0xA4,  0x4C,  0xA4,  0xD2,  0x4C,  0x45, 	/* 04CD0 */
+	0x48,  0x95,  0x2A,  0x3E,  0x98,  0x00,  0x07,  0xFE,  0x40,  0x05,  0xFC,  0x52,  0x45,  0xFC,  0x52,  0x45, 	/* 04CE0 */
+	0xFC,  0x42,  0x09,  0xFC,  0x82,  0x07,  0xFE,  0x9A,  0x00,  0x07,  0xFE,  0x50,  0x85,  0xF8,  0x50,  0x85, 	/* 04CF0 */
+	0xF8,  0x40,  0x05,  0xF8,  0x41,  0x07,  0xFE,  0x82,  0x00,  0x60,  0x9F,  0x00,  0x03,  0xFE,  0x22,  0x02, 	/* 04D00 */
+	0xFC,  0x28,  0x42,  0xFC,  0x28,  0x42,  0xFC,  0x42,  0x85,  0x24,  0xA2,  0x20,  0x60,  0xA0,  0x00,  0x07, 	/* 04D10 */
+	0xFE,  0x40,  0x05,  0xE2,  0x52,  0xA5,  0xEA,  0x52,  0xA5,  0xEA,  0x52,  0xA5,  0xEA,  0x94,  0x2A,  0x26, 	/* 04D20 */
+	0xA5,  0x00,  0x07,  0xFE,  0x65,  0x05,  0xA0,  0x7F,  0xE4,  0xAA,  0x6A,  0xC6,  0xA8,  0x7E,  0xC4,  0x94, 	/* 04D30 */
+	0x89,  0x29,  0x21,  0xA6,  0x00,  0x07,  0xFE,  0x40,  0x07,  0xFC,  0x44,  0x05,  0xF8,  0x5F,  0x85,  0x08, 	/* 04D40 */
+	0x5F,  0x86,  0x88,  0x87,  0x0B,  0x8E,  0xA8,  0x00,  0x07,  0xFE,  0x40,  0x07,  0xE4,  0x40,  0x47,  0xFF, 	/* 04D50 */
+	0x64,  0x47,  0xE4,  0x65,  0x45,  0x84,  0x8E,  0x4B,  0x0C,  0xA9,  0x7F,  0xE4,  0x00,  0x5D,  0xE5,  0x54, 	/* 04D60 */
+	0x5D,  0x45,  0x7E,  0x5C,  0x85,  0x18,  0x59,  0x85,  0x68,  0x9A,  0xA3,  0x46,  0xAD,  0x00,  0x07,  0xFE, 	/* 04D70 */
+	0x54,  0xC5,  0xCA,  0x40,  0x85,  0xFE,  0x54,  0x85,  0xC8,  0x55,  0x45,  0xD4,  0x95,  0x49,  0x62,  0xAE, 	/* 04D80 */
+	0x00,  0x07,  0xFE,  0x54,  0x47,  0xF8,  0x55,  0x05,  0xDE,  0x55,  0x45,  0xD4,  0x55,  0x47,  0xF4,  0x9A, 	/* 04D90 */
+	0x42,  0x44,  0xB0,  0x00,  0x07,  0xFE,  0x59,  0x07,  0x50,  0x51,  0xE7,  0xE4,  0x65,  0x47,  0xD8,  0x6C, 	/* 04DA0 */
+	0x87,  0xD8,  0xA6,  0x42,  0xC2,  0xB3,  0x24,  0x41,  0x28,  0x7F,  0xE4,  0x10,  0x5F,  0x04,  0x9E,  0x7E, 	/* 04DB0 */
+	0x45,  0x54,  0x5E,  0x85,  0x4C,  0xBD,  0x20,  0x62,  0xB6,  0x04,  0x00,  0x40,  0x04,  0x00,  0x40,  0x08, 	/* 04DC0 */
+	0x00,  0x80,  0x09,  0x01,  0x08,  0x10,  0x42,  0x3E,  0xFC,  0x20,  0x02,  0xBB,  0x04,  0x00,  0x40,  0x7F, 	/* 04DD0 */
+	0xC0,  0x40,  0x04,  0x0F,  0xFE,  0x04,  0x00,  0x90,  0x08,  0x81,  0x38,  0x7C,  0x40,  0x04,  0x82,  0x0A, 	/* 04DE0 */
+	0x01,  0x10,  0x7E,  0x80,  0x40,  0xFF,  0xE1,  0x30,  0x2C,  0x87,  0x34,  0x8C,  0xA3,  0x10,  0x06,  0x03, 	/* 04DF0 */
+	0x80,  0x83,  0x08,  0x01,  0x10,  0x7F,  0xC2,  0x08,  0x51,  0x2F,  0x5E,  0x0E,  0x03,  0x98,  0xC6,  0x61, 	/* 04E00 */
+	0x90,  0x06,  0x07,  0x80,  0x88,  0x00,  0x03,  0xF8,  0x00,  0x81,  0x08,  0x10,  0x80,  0x90,  0x09,  0x00, 	/* 04E10 */
+	0x60,  0x06,  0x00,  0x90,  0x30,  0x8C,  0x06,  0x89,  0x00,  0x07,  0xFC,  0x08,  0x40,  0x48,  0x14,  0x81, 	/* 04E20 */
+	0x10,  0x09,  0x00,  0xA0,  0x04,  0x00,  0xA0,  0x31,  0x8C,  0x06,  0x8A,  0x00,  0x03,  0xF8,  0x08,  0x80, 	/* 04E30 */
+	0x90,  0x09,  0xC1,  0x44,  0x14,  0x41,  0x28,  0x21,  0x82,  0x18,  0x46,  0x49,  0x82,  0x8B,  0x08,  0x00, 	/* 04E40 */
+	0x80,  0xFF,  0xE0,  0x80,  0x08,  0x01,  0xF8,  0x10,  0x81,  0x50,  0x22,  0x04,  0x70,  0x98,  0x86,  0x06, 	/* 04E50 */
+	0x8C,  0x00,  0x0F,  0xBE,  0x08,  0x20,  0xA2,  0x49,  0x42,  0x94,  0x10,  0x81,  0x88,  0x25,  0x42,  0x24, 	/* 04E60 */
+	0x44,  0x28,  0x81,  0x8D,  0x00,  0x03,  0xFC,  0x20,  0x02,  0x00,  0x3F,  0x82,  0x08,  0x29,  0x02,  0x90, 	/* 04E70 */
+	0x46,  0x04,  0x60,  0x99,  0x06,  0x0C,  0x8E,  0x08,  0x04,  0xFC,  0x48,  0x44,  0xC4,  0x4C,  0x44,  0xA8, 	/* 04E80 */
+	0x4A,  0x84,  0x90,  0x79,  0x0C,  0xA8,  0x0C,  0x40,  0x82,  0x94,  0x20,  0x02,  0x7C,  0x38,  0x42,  0x44, 	/* 04E90 */
+	0x22,  0x8F,  0xA8,  0x21,  0x03,  0x10,  0xAA,  0x8A,  0xA8,  0xA4,  0x46,  0x82,  0x96,  0x00,  0x0F,  0xC0, 	/* 04EA0 */
+	0x4B,  0xE4,  0x82,  0x7A,  0x24,  0x94,  0x79,  0x44,  0x88,  0x79,  0x8C,  0xA4,  0x0C,  0x20,  0x81,  0x97, 	/* 04EB0 */
+	0x01,  0xC7,  0xE4,  0x24,  0x41,  0x28,  0xFF,  0xE8,  0x02,  0xBF,  0x21,  0x10,  0x0A,  0x00,  0x60,  0x19, 	/* 04EC0 */
+	0x06,  0x0C,  0x99,  0x10,  0x01,  0x3E,  0x28,  0x24,  0xA2,  0x7E,  0x2A,  0x54,  0x21,  0x4F,  0x88,  0x20, 	/* 04ED0 */
+	0x8A,  0x94,  0xAA,  0x26,  0x41,  0x9B,  0x20,  0x0A,  0xBE,  0x6A,  0x07,  0x20,  0xFF,  0xE2,  0x22,  0x3A, 	/* 04EE0 */
+	0x4E,  0x54,  0x45,  0x84,  0x88,  0x89,  0x40,  0x62,  0x9F,  0x14,  0x0E,  0x5E,  0x84,  0x2F,  0x5E,  0x84, 	/* 04EF0 */
+	0x2F,  0xFE,  0x04,  0x07,  0xFC,  0x19,  0x80,  0x60,  0x1B,  0x06,  0x0C,  0xA1,  0x38,  0x02,  0x3E,  0xFC, 	/* 04F00 */
+	0x2A,  0x52,  0x71,  0x48,  0xD4,  0x20,  0x87,  0x88,  0xCC,  0xC7,  0x94,  0x4A,  0x27,  0xC1,  0xA2,  0x0A, 	/* 04F10 */
+	0x02,  0xA8,  0xFF,  0xE1,  0x10,  0x7F,  0xC0,  0x40,  0xFF,  0xE4,  0xF8,  0x7A,  0x84,  0x90,  0xFA,  0x80, 	/* 04F20 */
+	0xC6,  0xA3,  0x00,  0x00,  0x00,  0x7F,  0xE4,  0x02,  0x40,  0x24,  0x02,  0x40,  0x24,  0x02,  0x40,  0x24, 	/* 04F30 */
+	0x02,  0x7F,  0xE4,  0x02,  0xA4,  0x04,  0x00,  0x40,  0x04,  0x0F,  0xFE,  0x04,  0x00,  0x40,  0x04,  0x03, 	/* 04F40 */
+	0xF8,  0x20,  0x82,  0x08,  0x20,  0x83,  0xF8,  0xA5,  0x10,  0x01,  0x00,  0x3F,  0xE2,  0x02,  0x5F,  0x29, 	/* 04F50 */
+	0x12,  0x11,  0x21,  0x12,  0x1F,  0x20,  0x02,  0x00,  0x20,  0x0C,  0xA8,  0x00,  0x00,  0xFE,  0xF1,  0x29, 	/* 04F60 */
+	0x12,  0x91,  0x29,  0x12,  0x91,  0x29,  0x12,  0x92,  0x2F,  0x22,  0x04,  0x20,  0x8C,  0xA9,  0x00,  0x00, 	/* 04F70 */
+	0x3E,  0x7A,  0x24,  0xA2,  0x4A,  0x24,  0xA2,  0x4A,  0x24,  0xA2,  0x7A,  0x24,  0x2C,  0x02,  0x00,  0x20, 	/* 04F80 */
+	0xAA,  0x00,  0x07,  0xF8,  0x40,  0x84,  0x08,  0x40,  0x84,  0x08,  0x7F,  0x80,  0x00,  0x11,  0x01,  0x08, 	/* 04F90 */
+	0x20,  0x4C,  0x04,  0xAB,  0x00,  0x8F,  0x48,  0x94,  0x89,  0x48,  0x94,  0x89,  0x48,  0x94,  0x89,  0x4E, 	/* 04FA0 */
+	0xF7,  0x88,  0xC8,  0x00,  0x80,  0x08,  0xAC,  0x00,  0x07,  0xFC,  0x08,  0x40,  0x84,  0x10,  0x42,  0x18, 	/* 04FB0 */
+	0x40,  0x03,  0xF8,  0x20,  0x82,  0x08,  0x20,  0x83,  0xF8,  0xAD,  0x07,  0x8F,  0x08,  0x94,  0x89,  0x48, 	/* 04FC0 */
+	0x94,  0x89,  0x48,  0x94,  0x89,  0x48,  0xF8,  0x80,  0x84,  0x10,  0x42,  0x02,  0xAE,  0x00,  0x00,  0xFE, 	/* 04FD0 */
+	0xF1,  0x09,  0x10,  0x91,  0x09,  0x10,  0x91,  0x09,  0x10,  0x91,  0x0F,  0x10,  0x01,  0x00,  0x30,  0xAF, 	/* 04FE0 */
+	0x00,  0x0F,  0xFE,  0x00,  0x83,  0xE8,  0x22,  0x82,  0x28,  0x22,  0x83,  0xE8,  0x20,  0x80,  0x08,  0x00, 	/* 04FF0 */
+	0x80,  0x18,  0xB0,  0x04,  0x00,  0x40,  0x08,  0x81,  0x04,  0x23,  0xCF,  0xC2,  0x00,  0x23,  0xFC,  0x20, 	/* 05000 */
+	0x42,  0x04,  0x20,  0x43,  0xFC,  0xB1,  0x04,  0x00,  0x40,  0xF4,  0x49,  0x44,  0x94,  0x89,  0x50,  0x96, 	/* 05010 */
+	0x09,  0xC0,  0x94,  0x0F,  0x42,  0x04,  0x20,  0x3E,  0xB2,  0x04,  0x00,  0x40,  0x7F,  0xC4,  0x44,  0x44, 	/* 05020 */
+	0x47,  0xFC,  0x24,  0x01,  0x40,  0x0C,  0x00,  0xA0,  0x31,  0x8C,  0x06,  0xB3,  0x08,  0x00,  0x80,  0x08, 	/* 05030 */
+	0x0F,  0xFE,  0x08,  0x00,  0x80,  0x10,  0x01,  0xFC,  0x30,  0x45,  0x04,  0x90,  0x41,  0xFC,  0xB6,  0x01, 	/* 05040 */
+	0x00,  0x10,  0xF1,  0x09,  0x10,  0x9F,  0xE9,  0x10,  0x91,  0x09,  0x10,  0x91,  0x0F,  0x10,  0x01,  0x00, 	/* 05050 */
+	0x10,  0xB7,  0x00,  0x03,  0xF8,  0x20,  0x83,  0xF8,  0x00,  0x0F,  0xFE,  0x10,  0x01,  0xF8,  0x20,  0x80, 	/* 05060 */
+	0x08,  0x00,  0x80,  0x30,  0xB8,  0x00,  0x07,  0xFE,  0x00,  0x23,  0xFA,  0x00,  0x21,  0xF2,  0x11,  0x21, 	/* 05070 */
+	0x12,  0x1F,  0x20,  0x02,  0x00,  0x20,  0x0C,  0xBA,  0x03,  0x00,  0x10,  0xF1,  0x09,  0x10,  0x91,  0x09, 	/* 05080 */
+	0x10,  0x93,  0x09,  0x28,  0xF4,  0x80,  0x44,  0x08,  0x43,  0x02,  0x81,  0x00,  0x00,  0xFC,  0xF1,  0x09, 	/* 05090 */
+	0x10,  0x91,  0x09,  0xFE,  0x91,  0x09,  0x10,  0xF1,  0x00,  0x10,  0x01,  0x00,  0x30,  0x83,  0x04,  0x00, 	/* 050A0 */
+	0x40,  0xF7,  0xE9,  0x80,  0x90,  0x09,  0xFC,  0x90,  0x89,  0x30,  0xF4,  0x00,  0x82,  0x08,  0x20,  0x7E, 	/* 050B0 */
+	0x84,  0x08,  0x00,  0xF8,  0x10,  0x82,  0x90,  0x46,  0x00,  0x90,  0x10,  0x83,  0xFC,  0xD0,  0xA1,  0x08, 	/* 050C0 */
+	0x10,  0x81,  0xF8,  0x88,  0x04,  0x00,  0x40,  0x0A,  0x01,  0x10,  0x3F,  0x8C,  0x06,  0x00,  0x03,  0xF8, 	/* 050D0 */
+	0x20,  0x82,  0x08,  0x20,  0x83,  0xF8,  0x89,  0x04,  0x00,  0x40,  0xFF,  0xE0,  0x40,  0x04,  0x07,  0xFC, 	/* 050E0 */
+	0x00,  0x03,  0xF8,  0x20,  0x82,  0x08,  0x20,  0x83,  0xF8,  0x8A,  0x00,  0x03,  0xF8,  0x20,  0x82,  0x08, 	/* 050F0 */
+	0x3F,  0x80,  0x40,  0x7F,  0xC4,  0x44,  0x44,  0x44,  0x44,  0x45,  0x80,  0x40,  0x8B,  0x00,  0x80,  0x08, 	/* 05100 */
+	0xF0,  0x89,  0xFE,  0x90,  0x89,  0x48,  0x92,  0x89,  0x28,  0x90,  0x8F,  0x08,  0x00,  0x80,  0x18,  0x8C, 	/* 05110 */
+	0x00,  0x07,  0xFE,  0x40,  0x24,  0x02,  0x5F,  0xA4,  0x02,  0x5F,  0xA5,  0x0A,  0x50,  0xA5,  0xFA,  0x40, 	/* 05120 */
+	0x24,  0x06,  0x8D,  0x04,  0x00,  0x40,  0x0F,  0x81,  0x08,  0x29,  0x04,  0x60,  0x04,  0x00,  0xFE,  0x38, 	/* 05130 */
+	0x2C,  0x82,  0x08,  0x20,  0xFE,  0x8E,  0x01,  0xC3,  0xE0,  0x20,  0x02,  0x00,  0x3F,  0xE2,  0x00,  0x20, 	/* 05140 */
+	0x02,  0xFC,  0x48,  0x44,  0x84,  0x88,  0x40,  0xFC,  0x8F,  0x04,  0x07,  0xFE,  0x04,  0x03,  0xFC,  0x24, 	/* 05150 */
+	0x42,  0x44,  0x3F,  0xC1,  0x40,  0x0C,  0x00,  0xA0,  0x31,  0x8C,  0x06,  0x90,  0x01,  0x00,  0x10,  0xF1, 	/* 05160 */
+	0x09,  0x10,  0x9F,  0xE9,  0x10,  0x91,  0x09,  0x10,  0xF1,  0x00,  0x10,  0x1F,  0xE0,  0x00,  0x91,  0x04, 	/* 05170 */
+	0x00,  0x80,  0x10,  0x07,  0xFE,  0x40,  0x24,  0x02,  0x4F,  0x24,  0x92,  0x49,  0x24,  0xF2,  0x40,  0x24, 	/* 05180 */
+	0x06,  0x9B,  0x00,  0x07,  0xF8,  0x08,  0x8F,  0xFE,  0x08,  0x80,  0x88,  0x7F,  0x81,  0x00,  0x3F,  0x85, 	/* 05190 */
+	0x08,  0x90,  0x81,  0xF8,  0x9D,  0x04,  0x0F,  0xFE,  0x21,  0x01,  0x20,  0x0C,  0x00,  0xA0,  0x31,  0x8C, 	/* 051A0 */
+	0x06,  0x3F,  0x82,  0x08,  0x20,  0x83,  0xF8,  0x9F,  0x02,  0x00,  0x30,  0xE5,  0x0A,  0x48,  0xAF,  0xCB, 	/* 051B0 */
+	0x02,  0xA0,  0x0A,  0xFC,  0xA0,  0x8E,  0x08,  0x01,  0x00,  0x20,  0xA0,  0x02,  0x0E,  0x28,  0xA2,  0x4A, 	/* 051C0 */
+	0x20,  0xBF,  0xEA,  0x20,  0xA2,  0x0A,  0x50,  0xE5,  0x00,  0x88,  0x10,  0x46,  0x02,  0xA6,  0x00,  0x07, 	/* 051D0 */
+	0xFE,  0x06,  0x00,  0xD8,  0x34,  0x4C,  0x42,  0x04,  0x03,  0xFC,  0x20,  0x42,  0x04,  0x20,  0x43,  0xFC, 	/* 051E0 */
+	0xA9,  0x03,  0x00,  0x90,  0xE9,  0x0A,  0x88,  0xB0,  0x4B,  0xFA,  0xA4,  0x8A,  0x48,  0xE4,  0x80,  0x88, 	/* 051F0 */
+	0x08,  0x81,  0x30,  0xAB,  0x04,  0x00,  0xA0,  0x11,  0x02,  0xE8,  0xC0,  0x67,  0xF8,  0x02,  0x00,  0x40, 	/* 05200 */
+	0x3F,  0x82,  0x08,  0x20,  0x83,  0xF8,  0xAC,  0x00,  0xCF,  0x70,  0x94,  0x09,  0x40,  0x97,  0xE9,  0x48, 	/* 05210 */
+	0x94,  0x89,  0x48,  0xF4,  0x80,  0x88,  0x08,  0x81,  0x08,  0xAD,  0x02,  0x0F,  0x20,  0x9F,  0xE9,  0x00, 	/* 05220 */
+	0x97,  0x89,  0x48,  0x94,  0x89,  0x48,  0xF4,  0x80,  0x4A,  0x08,  0xA1,  0x06,  0xAE,  0x02,  0x00,  0x28, 	/* 05230 */
+	0xF2,  0x49,  0x46,  0x9F,  0xA9,  0x28,  0x92,  0x89,  0x28,  0x94,  0x8F,  0x4A,  0x08,  0xA1,  0x06,  0xB6, 	/* 05240 */
+	0x01,  0x00,  0x10,  0xEF,  0xEA,  0x92,  0xA9,  0x2A,  0x92,  0xAA,  0xAA,  0xC6,  0xE8,  0x20,  0x82,  0x08, 	/* 05250 */
+	0x20,  0x86,  0xB8,  0x00,  0x00,  0xFC,  0xF2,  0x49,  0x28,  0x92,  0xE9,  0x22,  0x93,  0x29,  0x54,  0xF4, 	/* 05260 */
+	0x80,  0x4C,  0x09,  0x21,  0x61,  0xB9,  0x02,  0x00,  0x20,  0xF3,  0xE9,  0x42,  0x95,  0x49,  0x90,  0x91, 	/* 05270 */
+	0x09,  0x10,  0xF2,  0x80,  0x28,  0x04,  0x41,  0x82,  0xBB,  0x04,  0x00,  0x40,  0xE7,  0xEA,  0x6A,  0xAA, 	/* 05280 */
+	0xAA,  0xAA,  0xB2,  0xAA,  0x52,  0xA5,  0x2E,  0x92,  0x02,  0x20,  0x4C,  0xBC,  0x00,  0x81,  0xF8,  0xE2, 	/* 05290 */
+	0x8A,  0x48,  0xA4,  0x8A,  0x78,  0xBC,  0x8A,  0x48,  0xA4,  0x8E,  0x4A,  0x04,  0xA0,  0xC6,  0xBD,  0x01, 	/* 052A0 */
+	0x00,  0x50,  0xE5,  0x0A,  0x7E,  0xA9,  0x0B,  0x10,  0xBF,  0xEA,  0x10,  0xA1,  0x0E,  0x10,  0x01,  0x00, 	/* 052B0 */
+	0x10,  0xBE,  0x7F,  0xC0,  0x80,  0x08,  0x07,  0xF8,  0x10,  0x81,  0x08,  0xFF,  0xE0,  0x00,  0x3F,  0x82, 	/* 052C0 */
+	0x08,  0x20,  0x83,  0xF8,  0x80,  0x00,  0x00,  0xFE,  0xF4,  0x89,  0x48,  0x94,  0x89,  0xFE,  0x92,  0x89, 	/* 052D0 */
+	0x28,  0xF4,  0x80,  0x88,  0x10,  0x80,  0x18,  0x82,  0x00,  0x03,  0xF8,  0x20,  0x82,  0x08,  0x3F,  0x80, 	/* 052E0 */
+	0x40,  0x08,  0x07,  0xFC,  0x40,  0x44,  0x04,  0x40,  0x47,  0xFC,  0x86,  0x00,  0x03,  0xF8,  0x20,  0x82, 	/* 052F0 */
+	0x08,  0x3F,  0x80,  0x40,  0xFF,  0xE0,  0xE0,  0x35,  0x8C,  0x46,  0x04,  0x00,  0x40,  0x88,  0x00,  0x03, 	/* 05300 */
+	0xF8,  0x20,  0x82,  0x08,  0x3F,  0x80,  0x00,  0x7F,  0xC0,  0x40,  0x3F,  0x80,  0x40,  0x04,  0x0F,  0xFE, 	/* 05310 */
+	0x89,  0x1F,  0x85,  0x08,  0x50,  0x85,  0xF8,  0x40,  0x07,  0xF8,  0x40,  0x80,  0x08,  0xFF,  0xE1,  0x20, 	/* 05320 */
+	0x21,  0x8C,  0x04,  0x8A,  0x04,  0x02,  0x40,  0x24,  0x03,  0xFC,  0x24,  0x04,  0x40,  0xFF,  0xE0,  0x00, 	/* 05330 */
+	0x3F,  0x82,  0x08,  0x20,  0x83,  0xF8,  0x8E,  0x00,  0x00,  0x7E,  0xF4,  0x29,  0x42,  0x97,  0xE9,  0x60, 	/* 05340 */
+	0x95,  0x09,  0x50,  0xF8,  0x80,  0x88,  0x10,  0x42,  0x02,  0x91,  0x01,  0xC7,  0xE0,  0x04,  0x00,  0x40, 	/* 05350 */
+	0xFF,  0xE0,  0xA0,  0x11,  0x03,  0xF8,  0xD1,  0x61,  0x10,  0x11,  0x01,  0xF0,  0x9F,  0x01,  0x00,  0x10, 	/* 05360 */
+	0xEF,  0xEA,  0x10,  0xA1,  0x0A,  0xA4,  0xA4,  0x4A,  0x28,  0xA1,  0x4E,  0x62,  0x1F,  0xE0,  0x02,  0xA8, 	/* 05370 */
+	0x00,  0x07,  0xFC,  0x44,  0x45,  0xF4,  0x44,  0x47,  0xFC,  0x40,  0x45,  0xF4,  0x51,  0x45,  0xF4,  0x80, 	/* 05380 */
+	0x48,  0x0C,  0xAA,  0x00,  0x00,  0x7C,  0xF4,  0x49,  0x44,  0x94,  0x49,  0x7C,  0x92,  0x89,  0x28,  0xF4, 	/* 05390 */
+	0x80,  0x4A,  0x08,  0xA3,  0x06,  0xB0,  0x12,  0x05,  0x26,  0x5F,  0x85,  0x20,  0x52,  0x25,  0xE2,  0xE1, 	/* 053A0 */
+	0xE0,  0x00,  0x3F,  0x82,  0x08,  0x20,  0x83,  0xF8,  0xB1,  0x00,  0xC0,  0xF0,  0xEA,  0x8A,  0xA8,  0xAA, 	/* 053B0 */
+	0x8A,  0xA8,  0xAA,  0x8A,  0xA8,  0xEB,  0x41,  0x2C,  0x1F,  0xA2,  0x09,  0xB3,  0x02,  0x00,  0x20,  0xEF, 	/* 053C0 */
+	0xCA,  0x20,  0xA2,  0x0B,  0xFE,  0xA2,  0x0A,  0x70,  0xAA,  0x8F,  0x26,  0x02,  0x00,  0x20,  0xB5,  0x00, 	/* 053D0 */
+	0x01,  0xFE,  0xE0,  0x4A,  0xF4,  0xA9,  0x4A,  0x94,  0xA9,  0x4A,  0xF4,  0xA8,  0x4E,  0x04,  0x00,  0x40, 	/* 053E0 */
+	0x0C,  0xB6,  0x04,  0x00,  0x5E,  0xE4,  0x2B,  0xF2,  0xAA,  0xAA,  0xAA,  0xAA,  0xAB,  0xA4,  0xA4,  0x4E, 	/* 053F0 */
+	0xAA,  0x11,  0x22,  0x21,  0xB7,  0x00,  0x00,  0xFE,  0xE9,  0x2A,  0xFE,  0xA9,  0x2A,  0x92,  0xAF,  0xEA, 	/* 05400 */
+	0x90,  0xE1,  0x08,  0x10,  0x01,  0x00,  0x10,  0xBB,  0x01,  0x00,  0x10,  0xEF,  0xEA,  0x92,  0xAF,  0xEA, 	/* 05410 */
+	0x92,  0xA9,  0x2A,  0xFE,  0xE9,  0x08,  0x10,  0x01,  0x00,  0x10,  0xBC,  0x00,  0xC1,  0xF0,  0xE2,  0x4B, 	/* 05420 */
+	0x24,  0xAA,  0x8A,  0xA0,  0xBF,  0xEA,  0x20,  0xE2,  0x00,  0x20,  0x02,  0x00,  0x60,  0xBD,  0x04,  0x00, 	/* 05430 */
+	0xA0,  0x11,  0x03,  0xE8,  0xC0,  0x67,  0xBC,  0x4A,  0x44,  0xA4,  0x4A,  0x47,  0xB8,  0x02,  0x00,  0x20, 	/* 05440 */
+	0x80,  0x00,  0x00,  0x7C,  0xF4,  0x49,  0x44,  0x97,  0xC9,  0x44,  0x94,  0x49,  0x7C,  0xF4,  0x48,  0x44, 	/* 05450 */
+	0x04,  0x41,  0xFE,  0x84,  0x01,  0x00,  0x92,  0xE9,  0x2A,  0x92,  0xA9,  0x2A,  0xFE,  0xA1,  0x0A,  0x92, 	/* 05460 */
+	0xA9,  0x2E,  0x92,  0x09,  0x20,  0xFE,  0x86,  0x04,  0x00,  0x40,  0xE7,  0xEA,  0x82,  0xAF,  0xAB,  0x4A, 	/* 05470 */
+	0xA4,  0xAA,  0x7A,  0xA4,  0x4E,  0x40,  0x04,  0x20,  0x3E,  0x8B,  0x02,  0x00,  0x20,  0xF7,  0xF9,  0x50, 	/* 05480 */
+	0x95,  0x09,  0x9E,  0x91,  0x09,  0x10,  0x91,  0xEF,  0x10,  0x01,  0x00,  0x10,  0x8C,  0x0C,  0x07,  0x00, 	/* 05490 */
+	0x13,  0xE1,  0x22,  0xFE,  0x21,  0x22,  0x3A,  0x23,  0x62,  0x52,  0x25,  0x22,  0x93,  0xE1,  0x00,  0x8E, 	/* 054A0 */
+	0x20,  0x83,  0x88,  0x28,  0x86,  0x98,  0x92,  0x42,  0xC2,  0x43,  0xE8,  0x00,  0x3F,  0x82,  0x08,  0x20, 	/* 054B0 */
+	0x83,  0xF8,  0x8F,  0x01,  0x00,  0x08,  0xE7,  0x0A,  0x12,  0xA1,  0x4B,  0xF8,  0xA3,  0x8A,  0x34,  0xA5, 	/* 054C0 */
+	0x2E,  0x91,  0x11,  0x00,  0x30,  0x90,  0x04,  0x40,  0x44,  0xE4,  0x4A,  0xBE,  0xA8,  0x4B,  0xA4,  0xA9, 	/* 054D0 */
+	0x4A,  0x94,  0xA8,  0x4E,  0x84,  0x08,  0x40,  0x8C,  0x92,  0x00,  0x07,  0xBC,  0x4A,  0x44,  0xA4,  0x7B, 	/* 054E0 */
+	0xC0,  0x00,  0x1E,  0x01,  0x20,  0x12,  0x01,  0x22,  0x22,  0x24,  0x1E,  0xA2,  0x7B,  0xC4,  0xA4,  0x4A, 	/* 054F0 */
+	0x47,  0xBC,  0x00,  0x03,  0xF8,  0x00,  0x0F,  0xFE,  0x08,  0x01,  0xF8,  0x20,  0x80,  0x70,  0xA4,  0x02, 	/* 05500 */
+	0x01,  0xFE,  0xF0,  0x2B,  0x1A,  0xAE,  0x0A,  0x20,  0xA3,  0xEB,  0xE0,  0xA2,  0x0E,  0x20,  0x02,  0x20, 	/* 05510 */
+	0x1E,  0xA5,  0x00,  0x01,  0xFE,  0xE2,  0x0A,  0x48,  0xBF,  0xCA,  0x24,  0xA2,  0x0B,  0xFC,  0xA2,  0x0E, 	/* 05520 */
+	0x20,  0x02,  0x03,  0xFE,  0xA8,  0x04,  0x00,  0x40,  0xE7,  0xE0,  0x94,  0x11,  0x03,  0x28,  0xC4,  0x40, 	/* 05530 */
+	0x82,  0x3F,  0x82,  0x08,  0x20,  0x83,  0xF8,  0xAB,  0x00,  0x07,  0xBE,  0x4A,  0x24,  0xA2,  0x7A,  0x26, 	/* 05540 */
+	0x3E,  0x60,  0x85,  0x14,  0x51,  0x24,  0xA2,  0x86,  0x08,  0x1F,  0xAC,  0x02,  0x00,  0x20,  0xFF,  0xEA, 	/* 05550 */
+	0x48,  0xA4,  0x8A,  0x84,  0xB4,  0xAA,  0x50,  0xE2,  0x08,  0x50,  0x08,  0x83,  0x06,  0xAF,  0x01,  0x00, 	/* 05560 */
+	0x1C,  0xF2,  0x49,  0x64,  0x99,  0x89,  0x14,  0x92,  0x29,  0x7D,  0x9A,  0x4F,  0x24,  0x02,  0x40,  0x3C, 	/* 05570 */
+	0xB2,  0x08,  0x80,  0x48,  0xE5,  0x0A,  0xFC,  0xA2,  0x0A,  0x20,  0xBF,  0xEA,  0x20,  0xE3,  0x00,  0x48, 	/* 05580 */
+	0x08,  0x43,  0x02,  0xB3,  0x01,  0x00,  0x10,  0xFF,  0xE9,  0x10,  0x92,  0x49,  0x68,  0x91,  0x09,  0x24, 	/* 05590 */
+	0x9C,  0x8F,  0x38,  0x06,  0x41,  0x82,  0xB8,  0x01,  0x80,  0x14,  0x7F,  0xE4,  0x10,  0x5D,  0x24,  0x12, 	/* 055A0 */
+	0x5D,  0x45,  0x54,  0x54,  0x85,  0xCA,  0x81,  0x68,  0x22,  0xBC,  0x00,  0x01,  0xF8,  0x10,  0x81,  0x78, 	/* 055B0 */
+	0x14,  0x87,  0xFE,  0x40,  0x25,  0xFA,  0x50,  0xA5,  0xFA,  0x50,  0x24,  0x06,  0xBD,  0x00,  0x00,  0xFE, 	/* 055C0 */
+	0xE9,  0x2A,  0x92,  0xAF,  0xEA,  0x92,  0xA9,  0x2A,  0x9A,  0xAA,  0x6E,  0xA6,  0x0C,  0x20,  0xFE,  0xBE, 	/* 055D0 */
+	0x02,  0x00,  0x20,  0xEF,  0xCA,  0x24,  0xA2,  0x8B,  0xFE,  0xA2,  0x0A,  0x4C,  0xBF,  0x0E,  0x40,  0x04, 	/* 055E0 */
+	0x40,  0x3C,  0x80,  0x04,  0x0F,  0xFE,  0x00,  0x03,  0xF8,  0x20,  0x82,  0x08,  0x3F,  0x80,  0x84,  0x34, 	/* 055F0 */
+	0x8D,  0x20,  0x1D,  0x87,  0x06,  0x81,  0x00,  0x03,  0xF0,  0x21,  0x02,  0x10,  0x21,  0x03,  0xF0,  0x00, 	/* 05600 */
+	0x0F,  0xBE,  0x8A,  0x28,  0xA2,  0x8A,  0x2F,  0xBE,  0x82,  0x00,  0x00,  0xFE,  0xE2,  0x8A,  0x28,  0xAF, 	/* 05610 */
+	0xEA,  0xAA,  0xAA,  0xAA,  0xCE,  0xE8,  0x28,  0x82,  0x0F,  0xE0,  0x80,  0x84,  0x04,  0x80,  0x48,  0xE4, 	/* 05620 */
+	0x8A,  0xFC,  0xA4,  0x8A,  0x48,  0xA4,  0x8B,  0xFE,  0xA5,  0x0E,  0x48,  0x08,  0x41,  0x04,  0x87,  0x01, 	/* 05630 */
+	0x00,  0x10,  0xEF,  0xCA,  0x10,  0xA1,  0x0B,  0xFE,  0xA1,  0x0A,  0x10,  0xAF,  0xCE,  0x10,  0x01,  0x01, 	/* 05640 */
+	0xFE,  0x88,  0x01,  0x00,  0x10,  0xF2,  0x89,  0x28,  0x94,  0x49,  0xBA,  0x90,  0x09,  0x7C,  0xF4,  0x40, 	/* 05650 */
+	0x44,  0x04,  0x40,  0x7C,  0x89,  0x11,  0x07,  0xD8,  0x11,  0x41,  0x10,  0xFF,  0xE0,  0x10,  0x79,  0x44, 	/* 05660 */
+	0x94,  0x48,  0x84,  0x9A,  0x7A,  0x60,  0x42,  0x98,  0x04,  0x00,  0x5E,  0xE8,  0x0B,  0x40,  0xA5,  0xFA, 	/* 05670 */
+	0x84,  0xB8,  0x4A,  0x84,  0xA8,  0x4E,  0x84,  0x08,  0x40,  0x8C,  0xA1,  0x1F,  0x81,  0x08,  0x1F,  0x83, 	/* 05680 */
+	0xFC,  0x20,  0x43,  0xFC,  0x20,  0x43,  0xFC,  0x20,  0x43,  0xFC,  0x19,  0x86,  0x06,  0xA2,  0x00,  0x01, 	/* 05690 */
+	0xFE,  0xE1,  0x0A,  0xFC,  0xA1,  0x0B,  0xFE,  0xA4,  0x8A,  0x48,  0xBF,  0xEE,  0x48,  0x08,  0x81,  0x08, 	/* 056A0 */
+	0xA5,  0x00,  0x07,  0xFC,  0x3E,  0x82,  0x28,  0x3E,  0x80,  0x08,  0xFF,  0xE0,  0x08,  0x3E,  0x82,  0x28, 	/* 056B0 */
+	0x3E,  0x80,  0x18,  0xA6,  0x02,  0x81,  0xCC,  0xE4,  0xAA,  0x48,  0xBF,  0xEA,  0x4A,  0xA6,  0xAA,  0xCC, 	/* 056C0 */
+	0xB4,  0x8E,  0x5A,  0x06,  0x60,  0xC2,  0xA8,  0x02,  0x01,  0x24,  0xEA,  0x8A,  0xFC,  0xA8,  0x4A,  0x84, 	/* 056D0 */
+	0xAF,  0xCA,  0x84,  0xAF,  0xCE,  0x84,  0x08,  0x40,  0x8C,  0xA9,  0x00,  0x0E,  0xFE,  0xA9,  0x2A,  0xFE, 	/* 056E0 */
+	0xA9,  0x2A,  0x92,  0xAF,  0xEA,  0x10,  0xEF,  0xE8,  0x10,  0x01,  0x01,  0xFF,  0xAD,  0x00,  0x0F,  0xBE, 	/* 056F0 */
+	0x8A,  0x28,  0xA2,  0xFB,  0xE0,  0x48,  0x04,  0x4F,  0xFE,  0x04,  0x00,  0xA0,  0x31,  0x8C,  0x06,  0xAE, 	/* 05700 */
+	0x02,  0x00,  0x28,  0xFF,  0xCA,  0x28,  0xBF,  0xEA,  0x20,  0xA7,  0xCA,  0x98,  0xB1,  0x0E,  0xFE,  0x01, 	/* 05710 */
+	0x00,  0x30,  0xB2,  0x20,  0x62,  0x78,  0xF4,  0x02,  0x7E,  0x34,  0x8E,  0x48,  0x28,  0x86,  0x08,  0x3F, 	/* 05720 */
+	0x82,  0x08,  0x20,  0x83,  0xF8,  0xBA,  0x01,  0x40,  0x12,  0xFF,  0xFA,  0x10,  0xAF,  0xEA,  0x92,  0xAF, 	/* 05730 */
+	0xEA,  0x92,  0xAF,  0xEE,  0x92,  0x09,  0x20,  0x96,  0xBD,  0x00,  0x01,  0xFE,  0xE1,  0x0A,  0xFC,  0xA9, 	/* 05740 */
+	0x4A,  0xFC,  0xA9,  0x4A,  0xFC,  0xA5,  0x0E,  0x20,  0x0D,  0x83,  0x06,  0x84,  0x00,  0x00,  0x7C,  0xF4, 	/* 05750 */
+	0x49,  0x44,  0x97,  0xC9,  0x44,  0x97,  0xC9,  0x44,  0x94,  0x4F,  0x7C,  0x02,  0x40,  0xC2,  0x86,  0x01, 	/* 05760 */
+	0x00,  0x24,  0xFF,  0xA9,  0x28,  0x92,  0xA9,  0x4E,  0x9A,  0x09,  0x3C,  0x96,  0x4F,  0x98,  0x06,  0xC1, 	/* 05770 */
+	0x82,  0x87,  0x00,  0x07,  0xFE,  0x40,  0x05,  0xFE,  0x4A,  0x44,  0x98,  0x4A,  0x89,  0xC6,  0x3F,  0xC2, 	/* 05780 */
+	0x04,  0x20,  0x43,  0xFC,  0x8F,  0x06,  0x40,  0x18,  0xEE,  0x4A,  0x10,  0xBF,  0xFA,  0x50,  0xA7,  0xEA, 	/* 05790 */
+	0xD2,  0xF5,  0x22,  0x52,  0x05,  0x60,  0x10,  0x90,  0x02,  0x07,  0xFE,  0x42,  0x05,  0xFC,  0x42,  0x47, 	/* 057A0 */
+	0xFE,  0x42,  0x45,  0xFC,  0x40,  0x05,  0xFC,  0x90,  0x41,  0xFC,  0x94,  0x00,  0x00,  0xFE,  0xF1,  0x09, 	/* 057B0 */
+	0x7C,  0x92,  0x49,  0x24,  0x9F,  0xF9,  0x00,  0x97,  0xCF,  0x44,  0x04,  0x40,  0x7C,  0x96,  0x00,  0x01, 	/* 057C0 */
+	0xFE,  0xE2,  0x8A,  0x28,  0xAF,  0xEA,  0xAA,  0xAA,  0xAA,  0xAA,  0xAF,  0xEE,  0x28,  0x02,  0x81,  0xFE, 	/* 057D0 */
+	0xAE,  0x11,  0x01,  0x20,  0x3F,  0xE6,  0x20,  0xBF,  0xC2,  0x20,  0x3F,  0xC2,  0x20,  0x3F,  0xE2,  0x04, 	/* 057E0 */
+	0x20,  0x43,  0xFC,  0xAF,  0x04,  0x8E,  0x90,  0xAF,  0xEB,  0x90,  0xA9,  0x0A,  0xFC,  0xA9,  0x0A,  0x90, 	/* 057F0 */
+	0xAF,  0xCE,  0x90,  0x09,  0x00,  0xFE,  0xB1,  0x00,  0x00,  0x7C,  0xE4,  0x4A,  0x7C,  0xA4,  0x4A,  0x7C, 	/* 05800 */
+	0xA0,  0x0A,  0xFE,  0xE8,  0x20,  0xFE,  0x08,  0x20,  0xFE,  0xB3,  0x00,  0x01,  0xFE,  0xE0,  0x0A,  0xFE, 	/* 05810 */
+	0xA8,  0x2A,  0xFE,  0xA9,  0x0A,  0xFE,  0xF1,  0x01,  0x28,  0x24,  0x41,  0x82,  0xB8,  0x02,  0x0E,  0x30, 	/* 05820 */
+	0xA4,  0x8A,  0xF4,  0xB0,  0x2A,  0xFC,  0xA0,  0x8A,  0x30,  0xF5,  0x01,  0x44,  0x24,  0xA0,  0x38,  0xB9, 	/* 05830 */
+	0x08,  0x80,  0x88,  0xFE,  0xCA,  0x8C,  0xA9,  0x2A,  0xE9,  0xAA,  0x4A,  0xA2,  0xEA,  0x81,  0x24,  0x22, 	/* 05840 */
+	0x20,  0xC2,  0xBE,  0x00,  0xC0,  0xF0,  0xE1,  0x0A,  0xFE,  0xA5,  0x4B,  0xFF,  0xA5,  0x4A,  0x54,  0xAF, 	/* 05850 */
+	0xEE,  0x10,  0x01,  0x01,  0xFE,  0x80,  0x00,  0x00,  0xFE,  0xE8,  0x8A,  0xBC,  0xA8,  0x8A,  0xFE,  0xA8, 	/* 05860 */
+	0x8A,  0x88,  0xEB,  0xC1,  0x08,  0x10,  0x82,  0x7E,  0x84,  0x00,  0x01,  0xFE,  0xE2,  0x0A,  0x60,  0xB9, 	/* 05870 */
+	0x2A,  0x2C,  0xA4,  0x8B,  0x9C,  0xE2,  0xA8,  0xC9,  0x30,  0x80,  0x30,  0x85,  0x02,  0x00,  0x3E,  0xE2, 	/* 05880 */
+	0x0A,  0xFC,  0xA8,  0x4A,  0xFC,  0xA8,  0x4A,  0xFC,  0xA2,  0x0F,  0xFE,  0x02,  0x00,  0x20,  0x86,  0x04, 	/* 05890 */
+	0x0F,  0xFF,  0x10,  0x80,  0x90,  0x7F,  0xE4,  0x92,  0x51,  0x26,  0xFE,  0x49,  0x24,  0x92,  0x4F,  0x24, 	/* 058A0 */
+	0x06,  0x8C,  0x02,  0x01,  0xFE,  0xF5,  0x2B,  0x52,  0xA5,  0x0A,  0x8E,  0xB0,  0x0A,  0xFC,  0xA2,  0x0E, 	/* 058B0 */
+	0x20,  0x02,  0x01,  0xFE,  0x8F,  0xFB,  0xE8,  0xA2,  0xFB,  0xE8,  0xA2,  0xFB,  0xE8,  0x02,  0x9F,  0x29, 	/* 058C0 */
+	0x12,  0x91,  0x29,  0xF2,  0x80,  0x28,  0x06,  0x93,  0xFA,  0x00,  0x3E,  0x7A,  0x44,  0xD4,  0x78,  0x84, 	/* 058D0 */
+	0x14,  0x46,  0x28,  0x00,  0x3F,  0x82,  0x08,  0x20,  0x83,  0xF8,  0x96,  0x02,  0x00,  0x24,  0xEA,  0x8B, 	/* 058E0 */
+	0x30,  0xA4,  0x8B,  0xA6,  0xA2,  0x0A,  0x24,  0xEA,  0x81,  0x30,  0x0C,  0x83,  0x06,  0x97,  0x02,  0x00, 	/* 058F0 */
+	0x3E,  0xF2,  0x29,  0x42,  0x98,  0xC9,  0x10,  0x96,  0xE9,  0x42,  0x97,  0x6F,  0x42,  0x04,  0x20,  0x7E, 	/* 05900 */
+	0x9C,  0x00,  0x01,  0xFE,  0xEA,  0xAA,  0x64,  0xA5,  0xAA,  0x91,  0xAF,  0xEA,  0x12,  0xAA,  0xAE,  0x44, 	/* 05910 */
+	0x0A,  0xA1,  0x11,  0x9D,  0x03,  0x01,  0xC0,  0xE4,  0xEA,  0x4A,  0xBF,  0xAA,  0x4A,  0xAE,  0xAA,  0xEE, 	/* 05920 */
+	0xF5,  0x82,  0x46,  0x04,  0x00,  0x40,  0xA3,  0x08,  0x00,  0x8E,  0xEF,  0xAB,  0x2A,  0xAF,  0xAA,  0x2A, 	/* 05930 */
+	0xAB,  0xAA,  0xAA,  0xAA,  0xAE,  0xBC,  0x1C,  0x80,  0x08,  0xBB,  0x04,  0x07,  0xFC,  0x11,  0x0F,  0xFE, 	/* 05940 */
+	0x84,  0x23,  0xF8,  0x24,  0x82,  0x70,  0x04,  0x07,  0xFC,  0x40,  0x47,  0xFC,  0xBC,  0x02,  0x01,  0xFC, 	/* 05950 */
+	0xE8,  0x8A,  0x50,  0xBF,  0xEB,  0x22,  0xBF,  0xEA,  0xA4,  0xAA,  0x4E,  0xA4,  0x0A,  0xC0,  0x20,  0xBE, 	/* 05960 */
+	0x06,  0x81,  0xC8,  0xE4,  0xAB,  0xFA,  0xA4,  0xCA,  0xE8,  0xAD,  0x8B,  0x48,  0xA5,  0x4E,  0x54,  0x06, 	/* 05970 */
+	0x20,  0x41,  0x80,  0x01,  0x01,  0xFE,  0xF2,  0x2B,  0x3A,  0xA4,  0x8A,  0xB0,  0xA2,  0x8A,  0x44,  0xBF, 	/* 05980 */
+	0xEE,  0x44,  0x04,  0x40,  0x7C,  0x83,  0x01,  0x00,  0x10,  0xFF,  0xEA,  0x10,  0xAF,  0xEA,  0xCA,  0xAB, 	/* 05990 */
+	0x2A,  0xFE,  0xA9,  0x2E,  0xFE,  0x09,  0x20,  0x96,  0x84,  0x11,  0x07,  0xFC,  0x04,  0x03,  0xF8,  0x04, 	/* 059A0 */
+	0x07,  0xFC,  0x24,  0x8F,  0xFE,  0x00,  0x03,  0xF8,  0x20,  0x83,  0xF8,  0x87,  0x08,  0x20,  0x82,  0xFE, 	/* 059B0 */
+	0xAA,  0x8A,  0xBE,  0xAA,  0xAA,  0xAA,  0xAB,  0xEA,  0xEC,  0xA9,  0xA2,  0x28,  0x20,  0x86,  0x89,  0x04, 	/* 059C0 */
+	0x00,  0x7C,  0xE4,  0x4A,  0xFE,  0xA9,  0x0B,  0xBE,  0xAA,  0x8A,  0xC8,  0xAF,  0xEE,  0x98,  0x0A,  0x40, 	/* 059D0 */
+	0xC2,  0x8A,  0x00,  0xC0,  0x0A,  0xEF,  0xEA,  0x88,  0xAF,  0xAA,  0x8A,  0xAF,  0xAA,  0x9C,  0xEF,  0x41, 	/* 059E0 */
+	0x0E,  0x11,  0x22,  0x22,  0x8B,  0x0A,  0x80,  0xA8,  0xFF,  0xEA,  0xA8,  0xAB,  0x8A,  0x80,  0xAF,  0xEA, 	/* 059F0 */
+	0x20,  0xFF,  0xE0,  0xE8,  0x32,  0x60,  0x20,  0x98,  0x01,  0x00,  0x92,  0xE9,  0x2A,  0xFE,  0xA0,  0x0B, 	/* 05A00 */
+	0xFF,  0xA2,  0x0A,  0xFE,  0xAA,  0xAE,  0xAA,  0x0A,  0xA0,  0x86,  0x99,  0x07,  0xEE,  0x44,  0xAF,  0xCA, 	/* 05A10 */
+	0x10,  0xAF,  0xFA,  0x30,  0xAD,  0x8A,  0x2B,  0xED,  0xC8,  0x2A,  0x0C,  0x90,  0x10,  0x9A,  0x02,  0x00, 	/* 05A20 */
+	0x3C,  0xE4,  0x8A,  0xFE,  0xAA,  0xAA,  0xAA,  0xAC,  0xEA,  0x92,  0xFF,  0xF0,  0x28,  0x04,  0x61,  0x81, 	/* 05A30 */
+	0x9C,  0x04,  0x0F,  0xFE,  0x04,  0x07,  0xFC,  0x20,  0x83,  0xF8,  0x11,  0x0F,  0xFE,  0x00,  0x03,  0xF8, 	/* 05A40 */
+	0x20,  0x83,  0xF8,  0x9D,  0x0F,  0xCE,  0x84,  0xAF,  0xCA,  0x84,  0xAF,  0xCA,  0x40,  0xA7,  0xEE,  0x92, 	/* 05A50 */
+	0x1E,  0x22,  0x8A,  0x07,  0xA0,  0x0C,  0x9E,  0x04,  0x00,  0x4E,  0xEF,  0xAA,  0x9A,  0xAF,  0xAA,  0x9A, 	/* 05A60 */
+	0xAF,  0xAA,  0x8A,  0xAE,  0xAE,  0x8C,  0x0E,  0x80,  0x88,  0x9F,  0x00,  0x00,  0xFE,  0xE9,  0x2A,  0xFE, 	/* 05A70 */
+	0xA9,  0x2A,  0xFE,  0xA4,  0x4A,  0x7C,  0xA4,  0x4E,  0x7C,  0x04,  0x40,  0x4C,  0xA7,  0x01,  0x0F,  0xFE, 	/* 05A80 */
+	0xB0,  0x2A,  0xFC,  0xA0,  0x0A,  0xFC,  0xA8,  0x4A,  0xFC,  0xE8,  0x40,  0xFC,  0x00,  0x01,  0xFE,  0xA8, 	/* 05A90 */
+	0x01,  0x01,  0xFE,  0xE0,  0x0A,  0x78,  0xA4,  0x8A,  0x78,  0xBF,  0xEB,  0x02,  0xE5,  0x00,  0x50,  0x09, 	/* 05AA0 */
+	0x23,  0x0E,  0xA9,  0x02,  0x00,  0x30,  0xE4,  0x8B,  0xB6,  0xA0,  0x0A,  0xEA,  0xAA,  0xAA,  0xF4,  0xAB, 	/* 05AB0 */
+	0x4E,  0xF4,  0x8A,  0xA0,  0xAA,  0xAA,  0x04,  0x0F,  0xFE,  0x04,  0x07,  0x5C,  0x55,  0x47,  0x5C,  0x04, 	/* 05AC0 */
+	0x0F,  0xFE,  0x28,  0x42,  0x58,  0x23,  0x0F,  0x8C,  0xAB,  0x04,  0x0F,  0xFE,  0xA4,  0xAB,  0xEA,  0xA5, 	/* 05AD0 */
+	0x2B,  0xE4,  0xAF,  0x8A,  0x20,  0xFF,  0xE0,  0x50,  0x08,  0x83,  0x06,  0xAC,  0x03,  0x83,  0xC0,  0x04, 	/* 05AE0 */
+	0x0F,  0xFC,  0x1F,  0x03,  0x18,  0xDF,  0x67,  0xFC,  0x5F,  0x45,  0x14,  0x5F,  0x44,  0x0C,  0xAE,  0x7B, 	/* 05AF0 */
+	0xC4,  0xA4,  0x7B,  0xC3,  0xF8,  0x24,  0x83,  0xF8,  0x24,  0x83,  0xF8,  0x04,  0x0F,  0xFE,  0x04,  0x00, 	/* 05B00 */
+	0x40,  0xB0,  0x02,  0x00,  0x50,  0xEF,  0x8B,  0x04,  0xAF,  0xAA,  0x88,  0xAF,  0x8A,  0xF8,  0xAA,  0x4E, 	/* 05B10 */
+	0x98,  0x0C,  0xC3,  0x82,  0xB6,  0x28,  0x81,  0x50,  0xFF,  0xE8,  0x02,  0xBF,  0x22,  0x10,  0x3F,  0x00, 	/* 05B20 */
+	0x80,  0x7F,  0x84,  0x08,  0x40,  0x87,  0xF8,  0x84,  0x00,  0x01,  0xFE,  0xE2,  0x0A,  0xFC,  0xA8,  0x4A, 	/* 05B30 */
+	0xFC,  0xA8,  0x4A,  0xFC,  0xA3,  0xCE,  0xC8,  0x07,  0x83,  0x86,  0x85,  0x02,  0x0E,  0xFC,  0xA8,  0x4A, 	/* 05B40 */
+	0xFC,  0xA8,  0x4A,  0xFC,  0xA8,  0x4A,  0xFC,  0xE1,  0x43,  0xFE,  0x06,  0x81,  0x86,  0x87,  0x04,  0x07, 	/* 05B50 */
+	0xFC,  0x24,  0x82,  0x48,  0x55,  0x4F,  0xFE,  0x00,  0x07,  0xFC,  0x51,  0x45,  0xF4,  0x40,  0x47,  0xFC, 	/* 05B60 */
+	0x94,  0x04,  0x60,  0x78,  0xE4,  0x2A,  0x3E,  0xAA,  0x4A,  0xBC,  0xAA,  0x4A,  0xBC,  0xAA,  0x4E,  0xFF, 	/* 05B70 */
+	0x04,  0x41,  0x82,  0x9A,  0x02,  0x0E,  0xF8,  0xA8,  0x8A,  0x88,  0xAF,  0x8A,  0x80,  0xAF,  0xEE,  0x80, 	/* 05B80 */
+	0x0F,  0xE1,  0x52,  0x12,  0xA2,  0x0C,  0x9C,  0x01,  0x00,  0xFE,  0xE1,  0x4B,  0xFE,  0xA2,  0x4A,  0x78, 	/* 05B90 */
+	0xBA,  0x2A,  0xFE,  0xA8,  0x4E,  0xFC,  0x08,  0x40,  0xFC,  0x9F,  0x04,  0x40,  0x28,  0xEF,  0xEA,  0x10, 	/* 05BA0 */
+	0xAF,  0xCA,  0x10,  0xBF,  0xFA,  0x40,  0xEF,  0xC1,  0x10,  0x21,  0x00,  0xFE,  0xA3,  0x00,  0x0F,  0xFE, 	/* 05BB0 */
+	0x88,  0x2F,  0xBA,  0x00,  0x2F,  0xBA,  0xAA,  0xAA,  0xAA,  0xFA,  0xAA,  0xBA,  0xA8,  0x2A,  0x86,  0xA4, 	/* 05BC0 */
+	0x02,  0x01,  0x24,  0xFF,  0xCA,  0x40,  0xBF,  0xEA,  0x20,  0xAF,  0xCA,  0xA4,  0xAF,  0xCE,  0x28,  0x03, 	/* 05BD0 */
+	0xC1,  0xC2,  0xB7,  0x04,  0x80,  0x48,  0xFE,  0x8A,  0x4F,  0xBF,  0x2A,  0x52,  0xBE,  0xAA,  0x8A,  0xAE, 	/* 05BE0 */
+	0x4E,  0xAC,  0x13,  0x22,  0x61,  0xB9,  0x10,  0x80,  0xBE,  0xE0,  0x8B,  0x3E,  0xAA,  0xAA,  0x3E,  0xBA, 	/* 05BF0 */
+	0xAA,  0xBE,  0xA8,  0x8E,  0xBE,  0x16,  0x82,  0x1F,  0xBD,  0x09,  0x01,  0xF0,  0xE9,  0xCB,  0xF4,  0xAA, 	/* 05C00 */
+	0xCA,  0xA8,  0xBE,  0x8A,  0xC8,  0xFB,  0x82,  0x94,  0x4A,  0x40,  0xC2,  0xBE,  0x04,  0x80,  0x48,  0xFE, 	/* 05C10 */
+	0xEA,  0x94,  0xAA,  0xEA,  0xF4,  0xAA,  0x4A,  0xBF,  0xEA,  0x41,  0x24,  0x22,  0xA0,  0xD1,  0x86,  0x04, 	/* 05C20 */
+	0x81,  0xFE,  0xE4,  0x8A,  0xFE,  0xA9,  0x2A,  0xFE,  0xA1,  0x0A,  0xFE,  0xE1,  0x08,  0xFE,  0x06,  0xC1, 	/* 05C30 */
+	0x83,  0x89,  0x04,  0x0F,  0xFE,  0x04,  0x03,  0xF8,  0x20,  0x87,  0xFC,  0x09,  0x0F,  0xFE,  0x10,  0x0F, 	/* 05C40 */
+	0xBE,  0x2A,  0x2D,  0xBE,  0x94,  0x00,  0x00,  0xFE,  0xE8,  0x0A,  0xBC,  0xAA,  0x4A,  0xBC,  0xA8,  0x0A, 	/* 05C50 */
+	0xFE,  0xAD,  0xAE,  0xFE,  0x08,  0x00,  0xFE,  0x96,  0x02,  0x01,  0xFC,  0xE2,  0x0A,  0xFC,  0xA2,  0x0B, 	/* 05C60 */
+	0xFE,  0xA8,  0x8A,  0xF8,  0xA8,  0x8E,  0xF8,  0x04,  0x81,  0x84,  0x97,  0x24,  0x81,  0x50,  0xFF,  0xE9, 	/* 05C70 */
+	0x12,  0xDF,  0xA7,  0xE0,  0x40,  0x23,  0xFE,  0x20,  0x83,  0xF8,  0x20,  0x83,  0xF8,  0x98,  0x02,  0x00, 	/* 05C80 */
+	0x3C,  0xE2,  0x0A,  0xFE,  0xAA,  0x0A,  0xFE,  0xAA,  0x4A,  0x9C,  0xAA,  0xAE,  0xAC,  0x16,  0x82,  0xFE, 	/* 05C90 */
+	0x9B,  0x02,  0x03,  0xFE,  0xE0,  0x0A,  0x88,  0xBF,  0xEA,  0x88,  0xAA,  0xAE,  0xAA,  0x2A,  0xA5,  0xAA, 	/* 05CA0 */
+	0x68,  0x88,  0x88,  0xA9,  0x08,  0x83,  0xFE,  0xE8,  0x8B,  0xFC,  0xAA,  0x8B,  0xFE,  0xAA,  0x8B,  0xFC, 	/* 05CB0 */
+	0xE2,  0x03,  0xFE,  0x02,  0x00,  0x20,  0xAF,  0x02,  0x00,  0xFC,  0xE2,  0x4A,  0xFE,  0xA2,  0x4A,  0xFC, 	/* 05CC0 */
+	0xAA,  0xAB,  0xAE,  0xFF,  0xE1,  0x22,  0x1A,  0xE2,  0xAA,  0xB1,  0x00,  0x00,  0xFF,  0xE8,  0x1A,  0xFF, 	/* 05CD0 */
+	0xA8,  0xEA,  0xBE,  0xAA,  0xAA,  0xFF,  0xED,  0x51,  0x5D,  0x17,  0x52,  0x47,  0xB2,  0x04,  0x0F,  0xFE, 	/* 05CE0 */
+	0xA4,  0xAA,  0xFA,  0xA9,  0xEA,  0xFA,  0xA9,  0xAA,  0xFE,  0xE4,  0xA9,  0xF2,  0x05,  0x20,  0x66,  0xB4, 	/* 05CF0 */
+	0x05,  0x01,  0x7E,  0xF5,  0x0B,  0xEE,  0xA3,  0xCA,  0x48,  0xAF,  0xEA,  0x92,  0xAF,  0xEE,  0x92,  0x0F, 	/* 05D00 */
+	0xE1,  0x02,  0xB6,  0x0A,  0x20,  0xAC,  0xFF,  0x8A,  0xA8,  0xAE,  0xFA,  0xAA,  0xAE,  0xAA,  0xAA,  0xBF, 	/* 05D10 */
+	0xAE,  0x6A,  0x09,  0x21,  0x22,  0xB8,  0x08,  0x00,  0x80,  0xEF,  0xEB,  0xB4,  0xAB,  0x4B,  0xFE,  0xAB, 	/* 05D20 */
+	0x4A,  0xB4,  0xBF,  0xEE,  0x00,  0x15,  0x42,  0x4A,  0x82,  0x08,  0x81,  0xFE,  0xE5,  0x0B,  0xFC,  0xB5, 	/* 05D30 */
+	0x4B,  0x9C,  0xBF,  0xCA,  0x08,  0xBF,  0xEE,  0x88,  0x04,  0x80,  0x18,  0x8C,  0x04,  0x40,  0x28,  0xEF, 	/* 05D40 */
+	0xEA,  0x92,  0xAF,  0xEA,  0x92,  0xAF,  0xEA,  0x44,  0xE7,  0xC0,  0x44,  0x04,  0x40,  0x7C,  0x8E,  0x02, 	/* 05D50 */
+	0x00,  0xFC,  0xE2,  0x0B,  0xFE,  0xB0,  0x2A,  0xFC,  0xA0,  0x0A,  0xFC,  0xA8,  0x4E,  0xFC,  0x04,  0x81, 	/* 05D60 */
+	0xFE,  0x90,  0x00,  0x07,  0xBC,  0x4A,  0x47,  0xBC,  0x00,  0x07,  0xFC,  0x04,  0x0F,  0xFE,  0x00,  0x07, 	/* 05D70 */
+	0xBC,  0x4A,  0x47,  0xBC,  0x9B,  0x01,  0x00,  0x5E,  0xE5,  0x0B,  0xFF,  0xA9,  0x2A,  0xD6,  0xAB,  0xAA, 	/* 05D80 */
+	0xFE,  0xE9,  0x28,  0xBA,  0x0D,  0x60,  0xFE,  0xA4,  0x04,  0x81,  0xFE,  0xE4,  0x8A,  0xEC,  0xB5,  0xAA, 	/* 05D90 */
+	0x49,  0xAF,  0xCA,  0x00,  0xBF,  0xEE,  0x94,  0x11,  0x20,  0x30,  0xA8,  0x00,  0x07,  0xBC,  0x4A,  0x47, 	/* 05DA0 */
+	0xBC,  0x04,  0x0F,  0xFE,  0x0A,  0x03,  0x18,  0xFB,  0xE4,  0xA4,  0x4A,  0x47,  0xBC,  0xAA,  0x07,  0xC0, 	/* 05DB0 */
+	0x44,  0xE7,  0xCA,  0xEE,  0xAA,  0xAA,  0xEE,  0xA1,  0x0B,  0xFE,  0xA3,  0x8E,  0x54,  0x19,  0x30,  0x10, 	/* 05DC0 */
+	0xAB,  0x02,  0x00,  0xFC,  0xE4,  0x8B,  0xFE,  0xA8,  0x4A,  0xFC,  0xA8,  0x4A,  0xFC,  0xA1,  0x0F,  0x54, 	/* 05DD0 */
+	0x14,  0x62,  0x3C,  0xAC,  0x08,  0x80,  0xEE,  0xF5,  0x4A,  0x44,  0xBF,  0xEA,  0x10,  0xAA,  0x8A,  0xA8, 	/* 05DE0 */
+	0xF7,  0x41,  0x22,  0x22,  0x03,  0xFE,  0xB4,  0x02,  0x01,  0xFC,  0xEA,  0x8B,  0xFE,  0xA4,  0x8A,  0xFC, 	/* 05DF0 */
+	0xA8,  0x4A,  0xFC,  0xA8,  0x4E,  0xFC,  0x04,  0x41,  0x82,  0xB8,  0x04,  0x0E,  0x5F,  0xBF,  0x8A,  0x4F, 	/* 05E00 */
+	0xB5,  0x9B,  0x5F,  0xBF,  0x9B,  0x4F,  0xE4,  0x98,  0x5F,  0x06,  0xA0,  0x11,  0xBA,  0x08,  0x43,  0xF8, 	/* 05E10 */
+	0xF5,  0x0B,  0x50,  0xBF,  0xEA,  0x94,  0xBF,  0x4A,  0x94,  0xFD,  0x42,  0xB4,  0x4A,  0x40,  0xC4,  0x80, 	/* 05E20 */
+	0x02,  0x01,  0xFE,  0xF4,  0x2A,  0xD4,  0xAB,  0xAB,  0x00,  0xAF,  0xEA,  0xAA,  0xBF,  0xFE,  0x08,  0x00, 	/* 05E30 */
+	0x80,  0x18,  0x86,  0x04,  0x81,  0xFE,  0xE4,  0x8A,  0x10,  0xBF,  0xEA,  0x44,  0xA7,  0xCA,  0x00,  0xFF, 	/* 05E40 */
+	0xE1,  0x4A,  0x17,  0xA1,  0x06,  0x87,  0x04,  0x4E,  0x44,  0xAE,  0xEA,  0x44,  0xBF,  0xFA,  0x54,  0xAD, 	/* 05E50 */
+	0x6A,  0xFE,  0xF7,  0xD9,  0x55,  0x25,  0x50,  0x64,  0x8A,  0x01,  0x00,  0x7C,  0xE4,  0x4A,  0x7C,  0xA4, 	/* 05E60 */
+	0x4A,  0xFE,  0xA9,  0x2A,  0xFE,  0xE9,  0x23,  0xFF,  0x04,  0x40,  0x84,  0x8F,  0x02,  0x01,  0xFC,  0xE2, 	/* 05E70 */
+	0x0B,  0xFE,  0xAA,  0xAA,  0xF8,  0xAA,  0x8F,  0xFE,  0x12,  0x21,  0x38,  0x2E,  0x04,  0x3E,  0x94,  0x02, 	/* 05E80 */
+	0x01,  0xFC,  0xE2,  0x0B,  0xFE,  0xAA,  0xAA,  0xF8,  0xA4,  0x4F,  0xFA,  0x12,  0x21,  0x38,  0x2E,  0x04, 	/* 05E90 */
+	0x3E,  0xA0,  0x08,  0x21,  0x7A,  0xF5,  0xAB,  0xBA,  0xA4,  0xAA,  0xAA,  0xBF,  0xAA,  0x4A,  0xBF,  0xAF, 	/* 05EA0 */
+	0x52,  0x0F,  0x23,  0x86,  0xA2,  0x04,  0x0F,  0xFE,  0x24,  0x8F,  0xFE,  0x91,  0x27,  0xF8,  0x11,  0x0F, 	/* 05EB0 */
+	0xFE,  0x34,  0x45,  0x28,  0x9D,  0x87,  0x06,  0xA5,  0x05,  0x01,  0xFE,  0xE5,  0x0A,  0x70,  0xA8,  0xAB, 	/* 05EC0 */
+	0xFC,  0xAD,  0x8A,  0xDA,  0xFF,  0xA0,  0x86,  0x15,  0x42,  0x4A,  0xAE,  0x26,  0xED,  0xEA,  0x6A,  0xC5, 	/* 05ED0 */
+	0xEA,  0xE8,  0x92,  0xEE,  0x48,  0x87,  0xFE,  0x4F,  0x24,  0x92,  0x4F,  0x24,  0x06,  0xB4,  0x3B,  0x82, 	/* 05EE0 */
+	0xA8,  0x7F,  0xC4,  0x10,  0x5D,  0x04,  0x9C,  0x7E,  0x45,  0x54,  0x5C,  0x85,  0x48,  0xBD,  0x48,  0x62, 	/* 05EF0 */
+	0xB6,  0x1D,  0xC1,  0x54,  0xFD,  0xCB,  0x54,  0xBD,  0xCB,  0x54,  0xBD,  0xCA,  0x22,  0xBF,  0xEE,  0x48, 	/* 05F00 */
+	0x03,  0x01,  0xCC,  0xBC,  0x00,  0xC1,  0xF4,  0xE9,  0x2B,  0xFE,  0xA5,  0x2B,  0xFE,  0xA4,  0x4B,  0xFE, 	/* 05F10 */
+	0xE2,  0x43,  0x94,  0x3C,  0x42,  0x0C,  0x80,  0x08,  0x83,  0xFE,  0xE8,  0x8B,  0xFE,  0xAA,  0xAB,  0xFE, 	/* 05F20 */
+	0xAA,  0xAB,  0xFD,  0xE8,  0x43,  0xFE,  0x09,  0x40,  0x8C,  0x81,  0x0F,  0xC0,  0x48,  0xE7,  0x8A,  0x48, 	/* 05F30 */
+	0xBF,  0xCA,  0x08,  0xBF,  0xEB,  0x54,  0xFD,  0xC1,  0x56,  0x3F,  0xC0,  0x44,  0x82,  0x7B,  0xC4,  0xA4, 	/* 05F40 */
+	0xFF,  0xE0,  0x80,  0x3F,  0x82,  0x08,  0x3F,  0x82,  0x08,  0x3F,  0x87,  0xBC,  0xAA,  0xA3,  0xB8,  0x83, 	/* 05F50 */
+	0x04,  0xA1,  0xF4,  0xEB,  0xEA,  0xB4,  0xB5,  0x4A,  0x5E,  0xBF,  0x4A,  0x54,  0xED,  0xE1,  0x74,  0x25, 	/* 05F60 */
+	0x40,  0x5E,  0x88,  0x04,  0x81,  0xFE,  0xE4,  0x8B,  0xFE,  0xAA,  0xAB,  0xBA,  0xA5,  0x6B,  0xE3,  0xE0, 	/* 05F70 */
+	0x01,  0xFE,  0x04,  0x81,  0xF4,  0x8E,  0x01,  0x41,  0xD4,  0xF6,  0x2B,  0xFF,  0xB6,  0xAB,  0x7E,  0xBE, 	/* 05F80 */
+	0xAB,  0x7E,  0xF5,  0x41,  0xDC,  0x19,  0x42,  0x5C,  0x91,  0x00,  0x01,  0xFE,  0xF8,  0x2B,  0xFE,  0xB7, 	/* 05F90 */
+	0xCB,  0x54,  0xB7,  0xEF,  0xD6,  0x97,  0xE1,  0x1A,  0x27,  0x64,  0x0C,  0x93,  0x08,  0x0E,  0x9E,  0xBE, 	/* 05FA0 */
+	0xAA,  0x8A,  0xBE,  0xAA,  0xF4,  0xB2,  0x0B,  0xFE,  0xF5,  0x41,  0xAC,  0x10,  0x41,  0xFC,  0x97,  0x00, 	/* 05FB0 */
+	0x0F,  0xFE,  0x80,  0x28,  0x02,  0x80,  0x28,  0x02,  0x80,  0x28,  0x02,  0x80,  0x28,  0x02,  0xFF,  0xE8, 	/* 05FC0 */
+	0x02,  0x98,  0x00,  0x0F,  0xFE,  0x80,  0x2B,  0xF2,  0xA1,  0x2A,  0x12,  0xBF,  0x2A,  0x02,  0xA0,  0xA9, 	/* 05FD0 */
+	0xFA,  0x80,  0x28,  0x06,  0x9A,  0x00,  0x07,  0xFE,  0x44,  0x24,  0x42,  0x44,  0x24,  0x42,  0x4A,  0x24, 	/* 05FE0 */
+	0xA2,  0x51,  0x26,  0x0A,  0x40,  0x27,  0xFE,  0x9B,  0x00,  0x0F,  0xFE,  0x8A,  0x28,  0xA2,  0x8A,  0x29, 	/* 05FF0 */
+	0x26,  0xA1,  0xEC,  0x02,  0x80,  0x2F,  0xFE,  0x00,  0x00,  0x00,  0x9E,  0x00,  0x07,  0xFE,  0x40,  0x24, 	/* 06000 */
+	0x02,  0x4F,  0x24,  0x92,  0x49,  0x24,  0xF2,  0x40,  0x24,  0x02,  0x7F,  0xE0,  0x00,  0xA0,  0x00,  0x07, 	/* 06010 */
+	0xFE,  0x44,  0x24,  0x42,  0x7F,  0xA4,  0x42,  0x44,  0x24,  0xA2,  0x51,  0x26,  0x0A,  0x40,  0x27,  0xFE, 	/* 06020 */
+	0xA3,  0x00,  0x07,  0xFE,  0x41,  0x24,  0x12,  0x7F,  0xE4,  0x12,  0x51,  0x24,  0x92,  0x41,  0x24,  0x32, 	/* 06030 */
+	0x40,  0x27,  0xFE,  0xAE,  0x00,  0x0F,  0xFE,  0x94,  0x29,  0x42,  0xA5,  0xAE,  0x72,  0xA4,  0x2A,  0x42, 	/* 06040 */
+	0xA4,  0xAA,  0x7A,  0x80,  0x2F,  0xFE,  0xB0,  0x00,  0x07,  0xFE,  0x44,  0x24,  0x42,  0x7F,  0xA4,  0x42, 	/* 06050 */
+	0x4C,  0x24,  0xE2,  0x55,  0x26,  0x4A,  0x44,  0x27,  0xFE,  0xB2,  0x00,  0x07,  0xFE,  0x49,  0x24,  0x92, 	/* 06060 */
+	0x7F,  0xE4,  0x92,  0x49,  0x27,  0xFE,  0x49,  0x24,  0x92,  0x50,  0x27,  0xFE,  0xB3,  0x00,  0x07,  0xFE, 	/* 06070 */
+	0x44,  0xA5,  0x2A,  0x49,  0x24,  0x12,  0x72,  0x24,  0xE2,  0x45,  0x24,  0x8A,  0x70,  0x27,  0xFE,  0xB9, 	/* 06080 */
+	0x00,  0x0F,  0xFE,  0x84,  0x28,  0xA2,  0x91,  0x2E,  0x0E,  0xBF,  0xA8,  0x4A,  0x84,  0xA8,  0x72,  0x84, 	/* 06090 */
+	0x2F,  0xFE,  0xBA,  0x00,  0x07,  0xFE,  0x44,  0x24,  0x42,  0x7F,  0xE4,  0x42,  0x5F,  0xA5,  0x0A,  0x50, 	/* 060A0 */
+	0xA5,  0xFA,  0x40,  0x27,  0xFE,  0xBD,  0x00,  0x07,  0xFE,  0x40,  0x27,  0xFA,  0x44,  0x24,  0x42,  0x5F, 	/* 060B0 */
+	0x24,  0x52,  0x44,  0xA7,  0xFA,  0x40,  0x27,  0xFE,  0xBF,  0x00,  0x0F,  0xFE,  0x88,  0x2B,  0xFA,  0x90, 	/* 060C0 */
+	0x2B,  0xF2,  0xD1,  0x29,  0xF2,  0x9F,  0x29,  0x12,  0x93,  0x2F,  0xFE,  0x80,  0x00,  0x0F,  0xFE,  0x91, 	/* 060D0 */
+	0x2E,  0x1E,  0x88,  0x2F,  0xFA,  0x88,  0x28,  0xF2,  0x91,  0x29,  0x12,  0xA6,  0x2F,  0xFE,  0x83,  0x00, 	/* 060E0 */
+	0x0F,  0xFE,  0x85,  0x2B,  0xFA,  0x84,  0x2B,  0xFA,  0xA4,  0xAB,  0xFA,  0xA4,  0xAB,  0xFA,  0xA4,  0xAF, 	/* 060F0 */
+	0xFE,  0x84,  0x00,  0x0F,  0xFE,  0x80,  0x2B,  0xFA,  0x88,  0x2B,  0xFA,  0x88,  0xAF,  0xFE,  0xA0,  0xAB, 	/* 06100 */
+	0xFA,  0x80,  0x2F,  0xFE,  0x88,  0x00,  0x0F,  0xFE,  0x95,  0x2A,  0x4A,  0xDF,  0x68,  0xA2,  0xFF,  0xE9, 	/* 06110 */
+	0x1A,  0xBF,  0x6D,  0x0A,  0x8F,  0xAF,  0xFE,  0x89,  0x00,  0x0F,  0xFE,  0x84,  0x2B,  0xF2,  0x84,  0x2F, 	/* 06120 */
+	0xFE,  0x91,  0x2B,  0xFA,  0x84,  0x2B,  0xFA,  0x84,  0x2F,  0xFE,  0x8B,  0x00,  0x0F,  0xFE,  0x82,  0xAF, 	/* 06130 */
+	0xFE,  0x82,  0x2B,  0xAA,  0xAA,  0xAB,  0x9A,  0x8D,  0x6F,  0x2E,  0x84,  0x6F,  0xFE,  0x8D,  0x00,  0x0F, 	/* 06140 */
+	0xFE,  0x84,  0x2B,  0xF2,  0x85,  0x2F,  0xFE,  0x91,  0x2B,  0xF2,  0xA2,  0x2B,  0xFE,  0x82,  0x2F,  0xFE, 	/* 06150 */
+	0x8F,  0x00,  0x0F,  0xFE,  0x95,  0x2B,  0xFA,  0x84,  0x2F,  0xFE,  0x9F,  0x2E,  0x2E,  0x9E,  0x29,  0x12, 	/* 06160 */
+	0x8F,  0x2F,  0xFE,  0x92,  0x00,  0x07,  0xFE,  0x44,  0x25,  0xFA,  0x44,  0x27,  0xFE,  0x50,  0xA5,  0xFA, 	/* 06170 */
+	0x4E,  0xA7,  0x52,  0x44,  0xA7,  0xFE,  0x93,  0x00,  0x0F,  0xFE,  0x9F,  0x29,  0x12,  0xBF,  0xAA,  0x0A, 	/* 06180 */
+	0xBF,  0xAB,  0xFA,  0xA0,  0xAB,  0xFA,  0x93,  0x2F,  0xFE,  0x96,  0x00,  0x0F,  0xFE,  0x9F,  0x29,  0x12, 	/* 06190 */
+	0x9F,  0x28,  0x42,  0xFF,  0xEA,  0xEA,  0xAA,  0xAB,  0xFA,  0x80,  0x2F,  0xFE,  0x98,  0x00,  0x0F,  0xFE, 	/* 061A0 */
+	0x84,  0x2F,  0xFE,  0x95,  0x29,  0xF2,  0xBF,  0xA8,  0x12,  0xFF,  0xE9,  0x12,  0x83,  0x2F,  0xFE,  0x9C, 	/* 061B0 */
+	0x00,  0x0F,  0xFE,  0x80,  0x2B,  0xFA,  0xAA,  0xAF,  0xFE,  0x91,  0x29,  0xF2,  0xB5,  0xA9,  0x62,  0xB9, 	/* 061C0 */
+	0xAF,  0xFE,  0x9F,  0x04,  0x00,  0x40,  0x04,  0x00,  0x40,  0x7F,  0xC0,  0x40,  0x04,  0x00,  0x40,  0x04, 	/* 061D0 */
+	0x00,  0x40,  0xFF,  0xE0,  0x00,  0xA6,  0x23,  0x02,  0x10,  0x21,  0x0F,  0x90,  0x21,  0x02,  0x10,  0x23, 	/* 061E0 */
+	0x02,  0xA8,  0x34,  0x8C,  0x44,  0x08,  0x43,  0x02,  0xA7,  0x00,  0x03,  0xFE,  0x20,  0x02,  0x20,  0x22, 	/* 061F0 */
+	0x03,  0xFC,  0x22,  0x02,  0x20,  0x22,  0x04,  0x20,  0x5F,  0xE8,  0x00,  0xA8,  0x04,  0x00,  0x40,  0xFF, 	/* 06200 */
+	0xE0,  0x80,  0x32,  0x02,  0x20,  0x7F,  0xCA,  0x20,  0x22,  0x02,  0x20,  0x3F,  0xE2,  0x00,  0xAD,  0x04, 	/* 06210 */
+	0x00,  0x40,  0x3F,  0xC0,  0x40,  0x04,  0x07,  0xFE,  0x04,  0x00,  0x40,  0x7F,  0xC0,  0x40,  0x04,  0x0F, 	/* 06220 */
+	0xFE,  0xB0,  0x01,  0x02,  0x50,  0x25,  0x0F,  0x5C,  0x27,  0x43,  0xD4,  0x25,  0x42,  0x54,  0x35,  0x8C, 	/* 06230 */
+	0x40,  0x04,  0x20,  0x3E,  0xB7,  0x20,  0x02,  0xFE,  0x21,  0x0F,  0x90,  0x21,  0x82,  0x14,  0x21,  0x22, 	/* 06240 */
+	0x90,  0x31,  0x0C,  0x10,  0x01,  0x00,  0x10,  0xB8,  0x21,  0x02,  0x10,  0x21,  0x0F,  0x92,  0x29,  0x22, 	/* 06250 */
+	0x92,  0x29,  0x22,  0x92,  0x39,  0x2C,  0x92,  0x09,  0x20,  0xFE,  0xBB,  0x20,  0x62,  0x78,  0x24,  0x0F, 	/* 06260 */
+	0x40,  0x27,  0xE2,  0x48,  0x24,  0x83,  0x48,  0xC8,  0x80,  0x88,  0x10,  0x80,  0x08,  0x80,  0x21,  0x02, 	/* 06270 */
+	0x10,  0x21,  0x0F,  0x10,  0x25,  0xE2,  0x50,  0x25,  0x02,  0x50,  0x35,  0x0C,  0x50,  0x05,  0x01,  0xFE, 	/* 06280 */
+	0x82,  0x00,  0x02,  0x7E,  0x24,  0x02,  0x40,  0xF7,  0xC2,  0x64,  0x26,  0x42,  0x54,  0x38,  0x8C,  0x98, 	/* 06290 */
+	0x12,  0x40,  0xC2,  0x87,  0x22,  0x02,  0x20,  0x27,  0xEF,  0x42,  0x28,  0x23,  0x62,  0x20,  0xA3,  0x32, 	/* 062A0 */
+	0x2C,  0x2C,  0x02,  0x00,  0x20,  0x0C,  0x8A,  0x22,  0x02,  0x20,  0x2F,  0xE2,  0x20,  0xFA,  0x02,  0x3C, 	/* 062B0 */
+	0x22,  0x42,  0x24,  0x34,  0x4C,  0x44,  0x08,  0x41,  0x18,  0x8E,  0x04,  0x02,  0x40,  0x24,  0x02,  0x7E, 	/* 062C0 */
+	0xF9,  0x22,  0x94,  0x31,  0x02,  0x30,  0x32,  0x8E,  0x48,  0x08,  0x43,  0x02,  0x8F,  0x20,  0x02,  0xFE, 	/* 062D0 */
+	0x20,  0x8F,  0x88,  0x21,  0x82,  0x34,  0x25,  0x22,  0x92,  0x31,  0x0C,  0x10,  0x01,  0x00,  0x10,  0x90, 	/* 062E0 */
+	0x04,  0x02,  0x48,  0x24,  0x82,  0x48,  0x55,  0x44,  0xE4,  0x84,  0x20,  0x40,  0x7F,  0xC0,  0x40,  0x04, 	/* 062F0 */
+	0x0F,  0xFE,  0x91,  0x01,  0x02,  0x10,  0x2F,  0xE2,  0x00,  0xFF,  0x82,  0x48,  0x24,  0x82,  0x48,  0x34, 	/* 06300 */
+	0x8C,  0x4A,  0x08,  0xA1,  0x0E,  0xA1,  0x21,  0x02,  0x10,  0x2F,  0xEF,  0x92,  0x29,  0x42,  0xFC,  0x28, 	/* 06310 */
+	0x43,  0xC4,  0xCA,  0x81,  0x10,  0x26,  0x81,  0x86,  0xA4,  0x21,  0x02,  0x10,  0x2F,  0xEF,  0x92,  0x2F, 	/* 06320 */
+	0xE2,  0x92,  0x29,  0x22,  0xFE,  0x31,  0x0C,  0x10,  0x01,  0x00,  0x10,  0xA6,  0x20,  0x02,  0x7E,  0x24, 	/* 06330 */
+	0x22,  0x42,  0xF7,  0xE2,  0x42,  0x24,  0x22,  0x42,  0x37,  0xEC,  0x00,  0x00,  0x00,  0xFF,  0xA9,  0x24, 	/* 06340 */
+	0x82,  0x48,  0x24,  0x8F,  0xFE,  0x24,  0x82,  0x48,  0x27,  0x82,  0x48,  0x34,  0x8C,  0x48,  0x04,  0x80, 	/* 06350 */
+	0x78,  0xAA,  0x20,  0x02,  0xFE,  0x21,  0x42,  0x94,  0xF5,  0x82,  0x30,  0x2F,  0xE2,  0x10,  0x39,  0x0C, 	/* 06360 */
+	0x10,  0x01,  0x00,  0x10,  0xBF,  0x22,  0x42,  0x24,  0x24,  0x4F,  0x7E,  0x2C,  0x43,  0x64,  0x25,  0x42, 	/* 06370 */
+	0x54,  0x34,  0x4C,  0x44,  0x04,  0x40,  0x4C,  0x82,  0x01,  0x83,  0xE0,  0x04,  0x07,  0xFC,  0x24,  0x8F, 	/* 06380 */
+	0xFE,  0x24,  0x82,  0x48,  0x7F,  0xC0,  0x40,  0x04,  0x0F,  0xFE,  0x88,  0x12,  0x81,  0x24,  0x22,  0xE7, 	/* 06390 */
+	0xF0,  0xA1,  0x02,  0x0A,  0x20,  0x60,  0x42,  0x7F,  0xC0,  0x40,  0x04,  0x0F,  0xFE,  0x89,  0x22,  0x02, 	/* 063A0 */
+	0x20,  0x27,  0xCF,  0x44,  0x2F,  0x43,  0x54,  0x25,  0x42,  0x64,  0x35,  0x8C,  0x42,  0x04,  0x20,  0x3E, 	/* 063B0 */
+	0x8B,  0x00,  0x27,  0xF2,  0x29,  0x22,  0x92,  0xFF,  0x22,  0x92,  0x48,  0x28,  0x46,  0x3F,  0x80,  0x40, 	/* 063C0 */
+	0x04,  0x0F,  0xFE,  0x93,  0x01,  0x02,  0x10,  0x2F,  0xE2,  0x20,  0xF2,  0x82,  0xCA,  0x23,  0x22,  0x24, 	/* 063D0 */
+	0x34,  0x8C,  0x14,  0x06,  0x21,  0x82,  0xA0,  0x20,  0x02,  0x7C,  0x24,  0x4F,  0x7C,  0x24,  0x42,  0x7C, 	/* 063E0 */
+	0x25,  0x22,  0x54,  0x34,  0x8C,  0x48,  0x07,  0x41,  0x82,  0xA2,  0x20,  0x42,  0x78,  0x24,  0x0F,  0x40, 	/* 063F0 */
+	0x27,  0xE2,  0x40,  0x24,  0x02,  0x7E,  0x36,  0x2C,  0xA2,  0x0A,  0x21,  0x3E,  0xA3,  0x0F,  0xE2,  0x00, 	/* 06400 */
+	0x27,  0xC2,  0x44,  0xFC,  0x42,  0x7C,  0x24,  0x42,  0xC4,  0x37,  0xCE,  0x00,  0x00,  0x01,  0xFE,  0xA4, 	/* 06410 */
+	0x20,  0x02,  0xFE,  0x22,  0x8F,  0x44,  0x2F,  0xA2,  0x10,  0x21,  0x02,  0xFE,  0x31,  0x0C,  0x10,  0x01, 	/* 06420 */
+	0x01,  0xFE,  0xAA,  0x28,  0x42,  0x44,  0x24,  0x8F,  0xFE,  0x24,  0x82,  0x48,  0x3F,  0xE2,  0x48,  0x34, 	/* 06430 */
+	0x8C,  0x88,  0x08,  0x81,  0x08,  0xB0,  0x22,  0x02,  0x3C,  0x22,  0x0F,  0x20,  0x2F,  0xE2,  0x00,  0x2F, 	/* 06440 */
+	0xE3,  0x20,  0xC3,  0x80,  0x24,  0x02,  0x00,  0x20,  0xB3,  0x02,  0x02,  0x3E,  0x24,  0x02,  0xA0,  0xF3, 	/* 06450 */
+	0xF2,  0x44,  0x2C,  0x42,  0x44,  0x34,  0x4C,  0x44,  0x04,  0x40,  0x4C,  0x80,  0x01,  0x83,  0xE0,  0x04, 	/* 06460 */
+	0x0F,  0xFE,  0x15,  0x2F,  0x5C,  0x15,  0x03,  0x52,  0xD4,  0xE3,  0xF8,  0x04,  0x0F,  0xFE,  0x83,  0x21, 	/* 06470 */
+	0x02,  0x18,  0x22,  0x4F,  0xFE,  0x24,  0x22,  0x7C,  0x29,  0x02,  0x10,  0x3F,  0xEC,  0x30,  0x04,  0x81, 	/* 06480 */
+	0x86,  0x86,  0x21,  0x02,  0x3C,  0x24,  0x8F,  0xFE,  0x25,  0x22,  0x7E,  0x25,  0x23,  0x52,  0xC7,  0xE0, 	/* 06490 */
+	0x42,  0x08,  0x21,  0x06,  0x8B,  0x20,  0x02,  0xFE,  0x29,  0x22,  0xFE,  0xF9,  0x22,  0x92,  0x2F,  0xE2, 	/* 064A0 */
+	0x10,  0x37,  0xEC,  0x10,  0x01,  0x00,  0xFF,  0x8E,  0x00,  0xC2,  0x0A,  0x2F,  0xE2,  0x88,  0xF8,  0xA2, 	/* 064B0 */
+	0xEA,  0x2A,  0xC3,  0xA4,  0xCA,  0x41,  0xAD,  0x25,  0x34,  0x21,  0x92,  0x20,  0xE2,  0xF0,  0x25,  0x42, 	/* 064C0 */
+	0x52,  0xF8,  0x22,  0x08,  0x2F,  0xE2,  0x08,  0x34,  0x8C,  0x28,  0x00,  0x80,  0x18,  0x93,  0x21,  0x82, 	/* 064D0 */
+	0xF0,  0x24,  0xA2,  0x2C,  0xFF,  0x02,  0x08,  0x2F,  0xE2,  0x08,  0x34,  0x8C,  0x28,  0x00,  0x80,  0x18, 	/* 064E0 */
+	0x94,  0x21,  0x42,  0x12,  0x27,  0xFF,  0x90,  0x27,  0xE2,  0x52,  0x27,  0xE2,  0x52,  0x37,  0xEC,  0x52, 	/* 064F0 */
+	0x05,  0x20,  0x56,  0x96,  0x24,  0x83,  0xFE,  0x24,  0x8F,  0x48,  0x25,  0x02,  0x92,  0x29,  0x43,  0x98, 	/* 06500 */
+	0x29,  0x0C,  0x90,  0x09,  0x20,  0x8E,  0x9C,  0x11,  0x0F,  0xFE,  0x11,  0x03,  0xB8,  0x55,  0x49,  0x53, 	/* 06510 */
+	0x11,  0x00,  0x40,  0x7F,  0xC0,  0x40,  0x04,  0x0F,  0xFE,  0x9F,  0x01,  0x84,  0x14,  0x5F,  0xE4,  0x10, 	/* 06520 */
+	0xFD,  0x25,  0x52,  0x55,  0x45,  0xCC,  0x62,  0x8C,  0xCA,  0x31,  0x60,  0x22,  0xA0,  0x21,  0x02,  0x7C, 	/* 06530 */
+	0x24,  0x4F,  0x7C,  0x24,  0x02,  0x7E,  0x24,  0x23,  0x7E,  0xC1,  0x01,  0xFF,  0x01,  0x00,  0x10,  0xA3, 	/* 06540 */
+	0x21,  0x02,  0x10,  0x2F,  0xEF,  0x44,  0x24,  0x42,  0x6A,  0x29,  0x23,  0xFF,  0x21,  0x0C,  0x10,  0x01, 	/* 06550 */
+	0x00,  0x10,  0xB4,  0x21,  0x02,  0xFE,  0x21,  0x0F,  0xBC,  0x2A,  0x42,  0xBC,  0x2A,  0x43,  0xBC,  0x6A, 	/* 06560 */
+	0x48,  0xBC,  0x08,  0x00,  0xFE,  0xB7,  0x22,  0x02,  0x20,  0xFF,  0x82,  0x28,  0xFA,  0x85,  0x28,  0x56, 	/* 06570 */
+	0x8F,  0xB8,  0x22,  0x8F,  0x4A,  0x24,  0xA2,  0x86,  0xB9,  0x21,  0x02,  0x10,  0x2F,  0xE2,  0x44,  0xF2, 	/* 06580 */
+	0x83,  0xFE,  0x20,  0x02,  0x7C,  0x34,  0x4C,  0x44,  0x04,  0x40,  0x7C,  0xBA,  0x11,  0x07,  0xFC,  0x11, 	/* 06590 */
+	0x01,  0xF0,  0x11,  0x01,  0xF0,  0x11,  0x0F,  0xFE,  0x24,  0x8D,  0xF6,  0x04,  0x07,  0xFC,  0xBC,  0x21, 	/* 065A0 */
+	0x02,  0xFE,  0x21,  0x0F,  0x28,  0x24,  0x43,  0xFE,  0x20,  0x43,  0xF4,  0xE9,  0x40,  0xF4,  0x00,  0x40, 	/* 065B0 */
+	0x0C,  0x80,  0x20,  0x02,  0xFE,  0x28,  0x2F,  0xFE,  0x28,  0x82,  0xAA,  0x2A,  0xA3,  0xBE,  0xE8,  0x81, 	/* 065C0 */
+	0x4A,  0x14,  0xA2,  0x7E,  0x82,  0x24,  0x81,  0x50,  0xFF,  0xE8,  0x02,  0x9F,  0x21,  0x10,  0x11,  0x01, 	/* 065D0 */
+	0xF0,  0x04,  0x07,  0xFC,  0x04,  0x0F,  0xFE,  0x85,  0x00,  0x0F,  0xBE,  0xA0,  0x2F,  0xA4,  0x89,  0x4F, 	/* 065E0 */
+	0x88,  0xA1,  0x4F,  0xE2,  0x04,  0x03,  0xF8,  0x04,  0x0F,  0xFE,  0x86,  0x02,  0x42,  0x28,  0x27,  0xE2, 	/* 065F0 */
+	0xC8,  0xF4,  0x82,  0x7E,  0x24,  0x82,  0x48,  0x37,  0xEC,  0x48,  0x04,  0x80,  0x7E,  0x8A,  0x00,  0x0F, 	/* 06600 */
+	0xFE,  0x11,  0x0F,  0x1E,  0x80,  0x2F,  0x1E,  0x11,  0x0F,  0xFE,  0x04,  0x07,  0xFC,  0x04,  0x0F,  0xFE, 	/* 06610 */
+	0x8B,  0x20,  0x02,  0xEE,  0x2A,  0xAF,  0xAA,  0x2E,  0xE2,  0xAA,  0x2A,  0xA2,  0xEE,  0x3A,  0xAC,  0xAA, 	/* 06620 */
+	0x13,  0x22,  0x66,  0x95,  0x02,  0x0F,  0xFE,  0xA4,  0x0C,  0x7C,  0xAC,  0x4B,  0x7C,  0xE4,  0x48,  0x4C, 	/* 06630 */
+	0x84,  0x07,  0xFC,  0x04,  0x0F,  0xFE,  0x99,  0x20,  0x02,  0xFE,  0x22,  0x82,  0xFE,  0xFA,  0xA2,  0xAA, 	/* 06640 */
+	0x2F,  0xE2,  0x10,  0x37,  0xCC,  0x10,  0x01,  0x01,  0xFE,  0x9D,  0x20,  0x02,  0x7C,  0x24,  0x4F,  0x5C, 	/* 06650 */
+	0x25,  0x42,  0xFE,  0x28,  0x22,  0xBA,  0x3A,  0xAC,  0xAA,  0x0B,  0xA0,  0x86,  0xA1,  0x20,  0x02,  0xFC, 	/* 06660 */
+	0x48,  0x4C,  0xFC,  0x42,  0x07,  0xFE,  0x4A,  0x85,  0x24,  0x04,  0x03,  0xF8,  0x04,  0x0F,  0xFE,  0xA4, 	/* 06670 */
+	0x27,  0xC2,  0x44,  0x27,  0xCF,  0x44,  0x27,  0xC2,  0x00,  0x2F,  0xE3,  0x10,  0xE9,  0xE0,  0x90,  0x17, 	/* 06680 */
+	0x02,  0x0F,  0xAA,  0x04,  0x42,  0xFE,  0x24,  0x42,  0x7C,  0xF4,  0x42,  0x7C,  0x24,  0x43,  0xFE,  0x2A, 	/* 06690 */
+	0x8C,  0xEC,  0x08,  0x00,  0x7E,  0xAF,  0x04,  0x03,  0xF8,  0x04,  0x07,  0xFC,  0x20,  0x8F,  0xBE,  0x20, 	/* 066A0 */
+	0x8F,  0xFE,  0x00,  0x0F,  0xFC,  0x12,  0x2E,  0x1E,  0xB0,  0x20,  0x02,  0xFE,  0x2A,  0x42,  0xBC,  0xFA, 	/* 066B0 */
+	0x42,  0xBC,  0x29,  0x02,  0xFE,  0x3A,  0x4C,  0x98,  0x0E,  0x40,  0xFE,  0xB1,  0x20,  0x0F,  0xBE,  0x22, 	/* 066C0 */
+	0x2F,  0xE4,  0x4B,  0xE3,  0x22,  0xFE,  0xA2,  0x2C,  0xFA,  0x42,  0x2C,  0x23,  0x22,  0x21,  0xB4,  0x20, 	/* 066D0 */
+	0x02,  0x7C,  0x24,  0x42,  0x7C,  0xF4,  0x42,  0xFF,  0x24,  0x02,  0xFE,  0x32,  0xAC,  0xD2,  0x02,  0x20, 	/* 066E0 */
+	0xCC,  0xB5,  0x02,  0x02,  0x24,  0x2F,  0xC2,  0x28,  0xFF,  0xE2,  0x20,  0x27,  0xC2,  0xC4,  0x37,  0xCC, 	/* 066F0 */
+	0x44,  0x04,  0x40,  0x7C,  0xBA,  0x20,  0x02,  0xFE,  0x29,  0x22,  0xFE,  0xF9,  0x22,  0xFE,  0x22,  0x83, 	/* 06700 */
+	0xCC,  0xCC,  0xA3,  0x48,  0x04,  0x80,  0x88,  0xBD,  0x20,  0x02,  0xFE,  0x2A,  0xA2,  0xFE,  0xF0,  0x02, 	/* 06710 */
+	0xFE,  0x21,  0x02,  0x10,  0x39,  0xCC,  0x90,  0x09,  0x00,  0xFE,  0x80,  0x4F,  0xE4,  0x82,  0x4F,  0xEF, 	/* 06720 */
+	0xC4,  0x4A,  0x84,  0xFE,  0x5A,  0x86,  0xA8,  0xCF,  0xE1,  0x28,  0x24,  0x80,  0x88,  0x81,  0x00,  0x07, 	/* 06730 */
+	0xFC,  0x44,  0x47,  0xFC,  0x44,  0x47,  0xFC,  0xC0,  0x63,  0x18,  0xC4,  0x63,  0xF8,  0x04,  0x0F,  0xFE, 	/* 06740 */
+	0x8A,  0x21,  0x02,  0x20,  0x2F,  0xCF,  0x94,  0x2F,  0xC2,  0x94,  0x2F,  0xC2,  0x34,  0x3B,  0xAC,  0x5E, 	/* 06750 */
+	0x09,  0x23,  0x0E,  0x8B,  0x11,  0x05,  0x54,  0x95,  0x42,  0xA8,  0x44,  0x4F,  0xFE,  0x84,  0x20,  0x40, 	/* 06760 */
+	0x7F,  0xC0,  0x40,  0x04,  0x0F,  0xFE,  0x91,  0x44,  0x02,  0x9E,  0xFD,  0x21,  0x1E,  0x55,  0x27,  0xDE, 	/* 06770 */
+	0x11,  0x26,  0x66,  0x04,  0x03,  0xFC,  0x04,  0x07,  0xFE,  0x92,  0x00,  0x85,  0xC8,  0x57,  0xE5,  0x48, 	/* 06780 */
+	0xF4,  0x85,  0xFF,  0x54,  0x45,  0x7E,  0x76,  0x4D,  0xD4,  0x00,  0x40,  0x0C,  0x94,  0x24,  0x83,  0xFE, 	/* 06790 */
+	0x24,  0x8F,  0x30,  0x24,  0x82,  0x84,  0x37,  0xA2,  0x00,  0x3F,  0xCC,  0x84,  0x08,  0x40,  0xFC,  0x97, 	/* 067A0 */
+	0x41,  0x02,  0x28,  0x8C,  0x64,  0x7C,  0x01,  0x02,  0xFE,  0x45,  0x48,  0xB2,  0x04,  0x07,  0xFC,  0x04, 	/* 067B0 */
+	0x0F,  0xFE,  0x98,  0x01,  0x02,  0xFE,  0x29,  0x0F,  0xFE,  0x29,  0x22,  0xFF,  0x29,  0x23,  0xFE,  0xC8, 	/* 067C0 */
+	0x01,  0x7E,  0x24,  0x20,  0x7E,  0x99,  0x01,  0x02,  0xFE,  0x27,  0xC2,  0x44,  0xF7,  0xC2,  0x00,  0x2F, 	/* 067D0 */
+	0xE2,  0x82,  0x3B,  0xAC,  0xAA,  0x0B,  0xA0,  0x86,  0x9A,  0x20,  0x02,  0xFE,  0x28,  0x22,  0x7E,  0xF3, 	/* 067E0 */
+	0x02,  0xDA,  0x22,  0xC2,  0xD8,  0x32,  0xCC,  0x4B,  0x18,  0x80,  0x30,  0x9E,  0x04,  0x0F,  0xFE,  0x91, 	/* 067F0 */
+	0x27,  0xFC,  0x11,  0x07,  0xFC,  0x11,  0x0F,  0xFE,  0x24,  0x8D,  0xF6,  0x04,  0x07,  0xFC,  0xA2,  0x22, 	/* 06800 */
+	0x02,  0xFC,  0x28,  0x4F,  0x84,  0x2F,  0xC2,  0x80,  0x2F,  0xE3,  0x80,  0xCF,  0xE1,  0x52,  0x1A,  0xA2, 	/* 06810 */
+	0x0C,  0xA9,  0x24,  0x02,  0x7E,  0x28,  0x0F,  0x7C,  0x24,  0x42,  0x7C,  0x20,  0x07,  0xFE,  0xCA,  0xA0, 	/* 06820 */
+	0xAA,  0x0A,  0xA3,  0xFF,  0xAB,  0x01,  0x02,  0xFE,  0x21,  0x02,  0x7C,  0xFC,  0x42,  0x7C,  0x24,  0x42, 	/* 06830 */
+	0x7C,  0x34,  0x4D,  0xFF,  0x02,  0x40,  0xC2,  0xB0,  0x44,  0x02,  0x7E,  0x88,  0x04,  0x7C,  0x05,  0x45, 	/* 06840 */
+	0xFE,  0x89,  0x48,  0xFC,  0x04,  0x07,  0xFC,  0x04,  0x0F,  0xFE,  0xB2,  0x24,  0x02,  0x7E,  0x2C,  0x4F, 	/* 06850 */
+	0x7C,  0x24,  0x42,  0xFE,  0x24,  0x02,  0xFE,  0x3A,  0xAD,  0x2A,  0x05,  0x20,  0x0C,  0xB5,  0x02,  0x07, 	/* 06860 */
+	0xFE,  0x45,  0x05,  0xFE,  0x45,  0x25,  0xFE,  0x49,  0x05,  0xEE,  0x42,  0x05,  0xFC,  0x42,  0x0B,  0xFE, 	/* 06870 */
+	0xB9,  0x10,  0x6F,  0xF8,  0x56,  0x07,  0xFE,  0x56,  0x47,  0xE4,  0x12,  0x4F,  0xC4,  0x14,  0x43,  0xF8, 	/* 06880 */
+	0x04,  0x0F,  0xFE,  0xBE,  0x21,  0x0F,  0xD0,  0x4F,  0xCF,  0x94,  0x13,  0x4F,  0x94,  0x12,  0xC3,  0x42, 	/* 06890 */
+	0x04,  0x07,  0xFC,  0x04,  0x0F,  0xFE,  0x83,  0x42,  0x05,  0xFC,  0x48,  0x84,  0x50,  0xFF,  0xE4,  0x88, 	/* 068A0 */
+	0x4F,  0x84,  0x88,  0x7F,  0x8C,  0x50,  0x09,  0x23,  0x0E,  0x85,  0x7F,  0xE5,  0x54,  0x7C,  0x85,  0x7E, 	/* 068B0 */
+	0x7C,  0xA1,  0x0C,  0x1C,  0x8E,  0x58,  0x04,  0x03,  0xF8,  0x04,  0x0F,  0xFE,  0x93,  0x11,  0x0F,  0xFE, 	/* 068C0 */
+	0x11,  0x03,  0xF8,  0x20,  0x83,  0xF8,  0x20,  0x8F,  0xFE,  0x24,  0x85,  0xF4,  0x84,  0x27,  0xFC,  0x97, 	/* 068D0 */
+	0x04,  0x42,  0x28,  0x2F,  0xE2,  0x92,  0xFF,  0xE2,  0x92,  0x2F,  0xE2,  0x44,  0x37,  0xCC,  0x44,  0x04, 	/* 068E0 */
+	0x40,  0x7C,  0x9C,  0xF4,  0x49,  0x28,  0xAF,  0xEE,  0x20,  0x9E,  0xC9,  0x30,  0xF5,  0x88,  0x96,  0x86, 	/* 068F0 */
+	0x07,  0xF8,  0x04,  0x0F,  0xFE,  0x9F,  0x02,  0x04,  0x3C,  0x42,  0x05,  0xFE,  0xF5,  0xA5,  0xE0,  0x57, 	/* 06900 */
+	0xE5,  0x28,  0x7A,  0xAD,  0xEE,  0x22,  0x85,  0xFF,  0xA8,  0x3F,  0x82,  0x48,  0x3F,  0x82,  0x48,  0x7F, 	/* 06910 */
+	0xC0,  0x40,  0xFF,  0xE5,  0x24,  0x95,  0x27,  0xFC,  0x04,  0x0F,  0xFE,  0xAB,  0x24,  0x42,  0xFE,  0x22, 	/* 06920 */
+	0x82,  0xFE,  0xFA,  0xA2,  0xCE,  0x28,  0x22,  0xFE,  0x30,  0x8C,  0xFF,  0x04,  0x80,  0x18,  0xAE,  0x71, 	/* 06930 */
+	0x05,  0xFE,  0x52,  0x86,  0x5E,  0x5B,  0xE5,  0x22,  0x73,  0xE4,  0x22,  0x44,  0x63,  0xFC,  0x04,  0x0F, 	/* 06940 */
+	0xFF,  0xB3,  0x02,  0x02,  0xFC,  0x2A,  0x8F,  0xFE,  0x24,  0x82,  0xFC,  0x28,  0x42,  0xFC,  0x38,  0x4C, 	/* 06950 */
+	0xFC,  0x04,  0x41,  0x82,  0xB8,  0x24,  0x82,  0xFE,  0x25,  0x82,  0xFC,  0xF1,  0x02,  0xFE,  0x22,  0x02, 	/* 06960 */
+	0x7C,  0x3C,  0x4C,  0x7C,  0x04,  0x40,  0x7C,  0xB9,  0x2E,  0xE2,  0xAA,  0x2E,  0xEF,  0xAA,  0x2E,  0xE2, 	/* 06970 */
+	0x82,  0x2B,  0xA2,  0xAA,  0x3B,  0xAC,  0xAA,  0x0B,  0xA0,  0x86,  0xBA,  0x22,  0x02,  0xFE,  0x2B,  0x62, 	/* 06980 */
+	0xDA,  0xFF,  0xE2,  0xBA,  0x2D,  0x62,  0x92,  0x31,  0x0C,  0xFE,  0x02,  0x80,  0xC6,  0xBB,  0x21,  0x02, 	/* 06990 */
+	0xFE,  0x25,  0x42,  0x54,  0xFB,  0xA2,  0xFF,  0x20,  0x02,  0xFE,  0x3A,  0xAC,  0xBA,  0x08,  0x20,  0xFE, 	/* 069A0 */
+	0xBE,  0x0B,  0xCF,  0x24,  0x57,  0xCF,  0xA4,  0x33,  0xCD,  0xB4,  0x2A,  0x8D,  0x76,  0x04,  0x07,  0xFC, 	/* 069B0 */
+	0x04,  0x0F,  0xFE,  0x81,  0x78,  0x84,  0xBE,  0x79,  0x44,  0x3F,  0x78,  0x84,  0xBE,  0xB8,  0x80,  0x48, 	/* 069C0 */
+	0x7F,  0xC0,  0x40,  0x04,  0x0F,  0xFE,  0x85,  0x04,  0x0F,  0xFE,  0x22,  0x85,  0x7E,  0x2C,  0x85,  0x7C, 	/* 069D0 */
+	0xF4,  0x82,  0x7E,  0x44,  0x03,  0xF8,  0x04,  0x0F,  0xFE,  0x87,  0x42,  0x07,  0xFE,  0x50,  0x4F,  0x74, 	/* 069E0 */
+	0x55,  0x45,  0xFC,  0x40,  0x05,  0xF8,  0x68,  0x8C,  0xF8,  0x08,  0x83,  0xFE,  0x8A,  0x01,  0x02,  0xFE, 	/* 069F0 */
+	0x21,  0x02,  0xFE,  0xFA,  0xA2,  0xFE,  0x21,  0x03,  0xFF,  0x2D,  0x4D,  0x48,  0x27,  0x40,  0xC2,  0x8C, 	/* 06A00 */
+	0x21,  0x02,  0xFE,  0x24,  0x8F,  0xAC,  0x32,  0xA2,  0xFE,  0x22,  0x83,  0xFE,  0xCD,  0x23,  0x4C,  0x07, 	/* 06A10 */
+	0x41,  0xC2,  0x91,  0x38,  0x02,  0x3C,  0xFC,  0x4A,  0x64,  0x51,  0x4F,  0xC8,  0x49,  0x47,  0xA2,  0x04, 	/* 06A20 */
+	0x03,  0xF8,  0x04,  0x0F,  0xFE,  0x93,  0x00,  0x07,  0xFE,  0x54,  0xC5,  0xEA,  0x53,  0xE5,  0xE8,  0x53, 	/* 06A30 */
+	0x49,  0x62,  0x04,  0x03,  0xF8,  0x04,  0x0F,  0xFE,  0x95,  0x42,  0x05,  0xFE,  0x48,  0x84,  0xF8,  0xFF, 	/* 06A40 */
+	0xE5,  0x02,  0x4F,  0x84,  0x62,  0x7B,  0x4C,  0x58,  0x19,  0x60,  0x60,  0x97,  0x22,  0x02,  0xFC,  0x22, 	/* 06A50 */
+	0x4F,  0xFE,  0x22,  0x02,  0xFE,  0x2D,  0x43,  0x2A,  0xDF,  0xC1,  0x54,  0x15,  0x43,  0xFE,  0x98,  0x3F, 	/* 06A60 */
+	0x82,  0x48,  0x3F,  0x82,  0x48,  0xFF,  0xEA,  0xAA,  0xFB,  0xEA,  0xAA,  0xFF,  0xE3,  0xF8,  0x04,  0x0F, 	/* 06A70 */
+	0xFE,  0x99,  0x21,  0x02,  0xFE,  0x2A,  0x8F,  0xFE,  0x2A,  0x82,  0xFE,  0x2D,  0x43,  0xFC,  0xCD,  0x41, 	/* 06A80 */
+	0x7C,  0x12,  0x42,  0xC2,  0x9C,  0x4F,  0xC4,  0x84,  0x5F,  0xEE,  0x10,  0x5F,  0xE5,  0x9A,  0x55,  0x64, 	/* 06A90 */
+	0xFC,  0x60,  0x09,  0xFE,  0x04,  0x81,  0xF4,  0x9E,  0x21,  0x02,  0xFF,  0x2A,  0xA2,  0xFE,  0xF0,  0x02, 	/* 06AA0 */
+	0xD6,  0x2D,  0x62,  0x28,  0x3C,  0xAC,  0xAA,  0x03,  0x40,  0xE2,  0x9F,  0x22,  0x0F,  0xFE,  0x48,  0x4F, 	/* 06AB0 */
+	0xFC,  0x4A,  0x07,  0xBC,  0x4A,  0x25,  0x9E,  0x04,  0x03,  0xF8,  0x04,  0x0F,  0xFE,  0xA4,  0x21,  0x03, 	/* 06AC0 */
+	0xFE,  0x2A,  0xAF,  0xEE,  0x22,  0x82,  0xFE,  0x22,  0x83,  0xFE,  0xC6,  0x21,  0xD4,  0x06,  0x80,  0xC6, 	/* 06AD0 */
+	0xA5,  0x20,  0x02,  0xFF,  0x2A,  0xAF,  0xBE,  0x2B,  0xE2,  0x88,  0x2F,  0xE2,  0xD5,  0x3B,  0xEC,  0xAA, 	/* 06AE0 */
+	0x0A,  0xA1,  0x7F,  0xAB,  0x04,  0x00,  0x40,  0x04,  0x00,  0x40,  0xFF,  0xE0,  0x40,  0x04,  0x00,  0x40, 	/* 06AF0 */
+	0x04,  0x00,  0x40,  0x7F,  0xC0,  0x00,  0xAC,  0x00,  0x00,  0x08,  0x07,  0x07,  0xC0,  0x04,  0x00,  0x40, 	/* 06B00 */
+	0xFF,  0xE0,  0x40,  0x04,  0x00,  0x40,  0x7F,  0xC0,  0x00,  0xAE,  0x21,  0x02,  0x10,  0x21,  0x0A,  0x10, 	/* 06B10 */
+	0x7F,  0xE2,  0x10,  0x21,  0x06,  0x10,  0xA1,  0x02,  0x10,  0x2F,  0xC2,  0x00,  0xAF,  0x11,  0x05,  0x10, 	/* 06B20 */
+	0x51,  0x05,  0x10,  0xFF,  0xF1,  0x10,  0xF1,  0x05,  0x10,  0x51,  0x05,  0x10,  0x91,  0x01,  0x7C,  0xB0, 	/* 06B30 */
+	0x02,  0x07,  0xFE,  0x02,  0x03,  0xFC,  0x00,  0x03,  0xFC,  0x24,  0x43,  0xFC,  0x20,  0x04,  0x00,  0x40, 	/* 06B40 */
+	0x08,  0x00,  0xB1,  0x04,  0x03,  0xF8,  0x04,  0x0F,  0xFE,  0x00,  0x0F,  0xFE,  0x90,  0x29,  0x02,  0x1F, 	/* 06B50 */
+	0x01,  0x00,  0x10,  0x40,  0xFC,  0xB2,  0x04,  0x0F,  0xFE,  0x04,  0x03,  0xF8,  0x00,  0x0F,  0xFE,  0x80, 	/* 06B60 */
+	0x29,  0x22,  0x12,  0x01,  0x22,  0x22,  0x2C,  0x1E,  0xB7,  0x04,  0x0F,  0xFE,  0x04,  0x03,  0xF8,  0x00, 	/* 06B70 */
+	0x0F,  0xFE,  0x8A,  0x2B,  0xFA,  0x2A,  0x83,  0xF8,  0x0A,  0x0F,  0xFE,  0xB9,  0x04,  0x0F,  0xFE,  0x04, 	/* 06B80 */
+	0x03,  0xF8,  0x00,  0x0F,  0xFE,  0x80,  0x2B,  0xFA,  0x20,  0x83,  0xF8,  0x11,  0x0F,  0xFE,  0xBA,  0x04, 	/* 06B90 */
+	0x0F,  0xFE,  0x04,  0x03,  0xF8,  0x00,  0x0F,  0xFE,  0x8A,  0x2B,  0xBA,  0x20,  0x83,  0xB8,  0x0A,  0x0F, 	/* 06BA0 */
+	0xFE,  0xBB,  0x1F,  0xE4,  0x14,  0x45,  0xCF,  0x70,  0x48,  0xE5,  0xFC,  0x48,  0x44,  0xFC,  0x78,  0x4C, 	/* 06BB0 */
+	0xFC,  0x08,  0x40,  0x8C,  0xBC,  0x04,  0x07,  0xFC,  0x04,  0x0F,  0xFE,  0x80,  0x2B,  0xFA,  0x0A,  0x03, 	/* 06BC0 */
+	0xB8,  0x20,  0x83,  0xB8,  0x0A,  0x0F,  0xFE,  0xBD,  0x04,  0x07,  0xFC,  0x04,  0x0F,  0xFE,  0x00,  0x27, 	/* 06BD0 */
+	0xF8,  0x04,  0x0F,  0xFE,  0x7A,  0x44,  0x94,  0x78,  0x40,  0x0C,  0x82,  0x08,  0x00,  0x80,  0x08,  0x01, 	/* 06BE0 */
+	0xF8,  0x10,  0x82,  0x10,  0x51,  0x08,  0xA0,  0x04,  0x00,  0xA0,  0x31,  0x8C,  0x06,  0x89,  0x04,  0x0F, 	/* 06BF0 */
+	0xFE,  0x09,  0x02,  0x98,  0x29,  0x45,  0x32,  0x88,  0x21,  0xF8,  0x69,  0x00,  0x60,  0x19,  0x8E,  0x06, 	/* 06C00 */
+	0x8A,  0x08,  0x00,  0x80,  0x88,  0x09,  0xF8,  0x50,  0x82,  0x10,  0x51,  0x08,  0xA0,  0x04,  0x00,  0xA0, 	/* 06C10 */
+	0x31,  0x8C,  0x06,  0x8F,  0x00,  0x0F,  0xFE,  0x08,  0x03,  0xF8,  0x20,  0x83,  0xF8,  0x20,  0x83,  0xF8, 	/* 06C20 */
+	0x1F,  0x07,  0x10,  0x0E,  0x0F,  0x1E,  0x90,  0x0F,  0x83,  0x10,  0xFF,  0xE4,  0x92,  0x7F,  0xE2,  0x04, 	/* 06C30 */
+	0x3F,  0xC2,  0x04,  0x3F,  0xC1,  0x88,  0xE7,  0x03,  0x8E,  0x95,  0x04,  0x00,  0x40,  0x0F,  0xC0,  0x84, 	/* 06C40 */
+	0x10,  0x42,  0xC8,  0x42,  0x80,  0x10,  0x02,  0x00,  0x40,  0x18,  0x06,  0x00,  0x96,  0x21,  0x02,  0x10, 	/* 06C50 */
+	0x3D,  0x02,  0x50,  0x45,  0x06,  0x58,  0x99,  0x40,  0x92,  0x11,  0x01,  0x10,  0x21,  0x04,  0x10,  0x98, 	/* 06C60 */
+	0x20,  0x02,  0x1E,  0x3D,  0x22,  0x52,  0x45,  0x25,  0x52,  0x89,  0x20,  0x92,  0x11,  0xC1,  0x10,  0x21, 	/* 06C70 */
+	0x04,  0x10,  0x99,  0x00,  0x07,  0xFC,  0x40,  0x47,  0xFC,  0x44,  0x44,  0xF4,  0x49,  0x45,  0x54,  0x62, 	/* 06C80 */
+	0x44,  0x45,  0x48,  0x39,  0x01,  0x9A,  0x04,  0x00,  0x78,  0x08,  0x83,  0x50,  0x06,  0x81,  0x9E,  0x62, 	/* 06C90 */
+	0x20,  0xE4,  0x31,  0x80,  0x30,  0x0C,  0x07,  0x00,  0x9B,  0x00,  0x03,  0xF0,  0x01,  0x01,  0xF0,  0x01, 	/* 06CA0 */
+	0x0F,  0xFE,  0x08,  0x01,  0xF8,  0x71,  0x00,  0xA0,  0x0C,  0x07,  0x00,  0x9C,  0x04,  0x00,  0x40,  0xFF, 	/* 06CB0 */
+	0xE1,  0x20,  0x13,  0xC2,  0x24,  0x65,  0x4A,  0xA8,  0x31,  0x02,  0x30,  0x2C,  0x83,  0x06,  0xA2,  0x12, 	/* 06CC0 */
+	0x0F,  0xFE,  0x12,  0x07,  0xFC,  0x4A,  0x47,  0xFC,  0x00,  0x0F,  0xFE,  0x8F,  0x23,  0x90,  0x06,  0x07, 	/* 06CD0 */
+	0x80,  0xA5,  0x01,  0x0F,  0x9C,  0xAA,  0x4F,  0xD8,  0xA9,  0x0F,  0xA8,  0x24,  0xEF,  0x92,  0x32,  0xA6, 	/* 06CE0 */
+	0x84,  0xA1,  0x82,  0x60,  0xA7,  0x04,  0x00,  0x40,  0x04,  0x00,  0x40,  0xFF,  0xE0,  0x40,  0x0A,  0x00, 	/* 06CF0 */
+	0xA0,  0x11,  0x01,  0x10,  0x20,  0x8C,  0x06,  0xA9,  0x00,  0x07,  0xFC,  0x04,  0x00,  0x40,  0x04,  0x0F, 	/* 06D00 */
+	0xFE,  0x04,  0x00,  0xA0,  0x0A,  0x01,  0x10,  0x20,  0x8C,  0x06,  0xAA,  0x04,  0x00,  0x40,  0x04,  0x07, 	/* 06D10 */
+	0xFE,  0x04,  0x00,  0x40,  0x0A,  0x00,  0xA0,  0x11,  0x01,  0x88,  0x24,  0x4C,  0x02,  0xAB,  0x04,  0x00, 	/* 06D20 */
+	0x40,  0x04,  0x07,  0xFC,  0x04,  0x00,  0x40,  0xFF,  0xE0,  0xA0,  0x0A,  0x01,  0x10,  0x20,  0x8C,  0x06, 	/* 06D30 */
+	0xAC,  0x04,  0x00,  0x40,  0x3F,  0x80,  0x48,  0x04,  0x80,  0x48,  0xFF,  0xE0,  0x40,  0x06,  0x00,  0x90, 	/* 06D40 */
+	0x30,  0x8C,  0x06,  0xAD,  0x01,  0x80,  0xE0,  0x74,  0x00,  0x40,  0x04,  0x0F,  0xFE,  0x04,  0x00,  0xC0, 	/* 06D50 */
+	0x0A,  0x01,  0x10,  0x20,  0x8C,  0x06,  0xAE,  0x04,  0x00,  0x40,  0x3F,  0x82,  0x48,  0x24,  0x82,  0x48, 	/* 06D60 */
+	0xFF,  0xE0,  0xC0,  0x0A,  0x01,  0x10,  0x20,  0x8C,  0x06,  0xB1,  0x04,  0x02,  0x40,  0x24,  0x03,  0xF8, 	/* 06D70 */
+	0x44,  0x04,  0x40,  0xFF,  0xE0,  0x40,  0x0A,  0x01,  0x10,  0x20,  0x8C,  0x06,  0xB2,  0x04,  0x00,  0x40, 	/* 06D80 */
+	0xFF,  0xE0,  0x40,  0x0A,  0x03,  0x18,  0xC4,  0x60,  0x40,  0x7F,  0xC0,  0x40,  0x04,  0x00,  0x40,  0xB7, 	/* 06D90 */
+	0x04,  0x0F,  0xFE,  0x04,  0x07,  0xF8,  0x04,  0x87,  0xF8,  0x44,  0x07,  0xFE,  0x0A,  0x21,  0x14,  0x20, 	/* 06DA0 */
+	0x8C,  0x06,  0xB8,  0x04,  0x0F,  0xFE,  0x0A,  0x03,  0x18,  0xDF,  0x60,  0x00,  0x7F,  0xC0,  0x80,  0x0F, 	/* 06DB0 */
+	0x81,  0x08,  0x00,  0x80,  0x30,  0xBE,  0x04,  0x00,  0x40,  0xFF,  0xE2,  0x48,  0x24,  0x82,  0x48,  0x55, 	/* 06DC0 */
+	0x48,  0x62,  0x0A,  0x01,  0x10,  0x20,  0x8C,  0x06,  0x84,  0x04,  0x00,  0x40,  0xFF,  0xE1,  0x50,  0x24, 	/* 06DD0 */
+	0x8F,  0xFE,  0x24,  0x83,  0xF8,  0x24,  0x83,  0xF8,  0x04,  0x20,  0x3E,  0x87,  0x04,  0x07,  0xFC,  0x0A, 	/* 06DE0 */
+	0x01,  0x10,  0x60,  0x8F,  0xFE,  0x00,  0x83,  0xE8,  0x22,  0x83,  0xE8,  0x00,  0x80,  0x18,  0x88,  0x04, 	/* 06DF0 */
+	0x0F,  0xFE,  0x0A,  0x01,  0x10,  0x3F,  0x8C,  0x06,  0x7F,  0xC0,  0x40,  0x15,  0x82,  0x44,  0x44,  0x20, 	/* 06E00 */
+	0xC0,  0x89,  0x04,  0x07,  0xFC,  0x04,  0x03,  0xF8,  0x0A,  0x0F,  0xFE,  0x24,  0x8D,  0xF6,  0x04,  0x03, 	/* 06E10 */
+	0xF8,  0x04,  0x00,  0x40,  0x8E,  0x04,  0x0F,  0xFE,  0x0A,  0x03,  0x18,  0xC4,  0x63,  0xF8,  0x04,  0x07, 	/* 06E20 */
+	0xFC,  0x04,  0x03,  0xF8,  0x04,  0x0F,  0xFE,  0x8F,  0x04,  0x07,  0xFC,  0x04,  0x03,  0xFC,  0x0A,  0x0F, 	/* 06E30 */
+	0xFE,  0x21,  0x8D,  0xE6,  0x04,  0x07,  0xFC,  0x1B,  0x06,  0x0C,  0x90,  0x08,  0x01,  0xF0,  0xE2,  0x07, 	/* 06E40 */
+	0xFC,  0x4A,  0x44,  0xA4,  0x71,  0xC4,  0x44,  0xFF,  0xE0,  0x40,  0x1B,  0x0E,  0x0E,  0x91,  0x10,  0x07, 	/* 06E50 */
+	0xBE,  0x11,  0x27,  0xD2,  0x11,  0x21,  0xA2,  0xE4,  0xC0,  0x40,  0xFF,  0xE0,  0xA0,  0x31,  0x8C,  0x06, 	/* 06E60 */
+	0x94,  0x04,  0x0F,  0xFE,  0x11,  0x02,  0x48,  0xDF,  0x60,  0x40,  0x15,  0x01,  0x10,  0xFF,  0xE1,  0x10, 	/* 06E70 */
+	0x21,  0x04,  0x10,  0x95,  0x04,  0x0F,  0xFE,  0x09,  0x02,  0x94,  0x49,  0x29,  0x32,  0x04,  0x0F,  0xFE, 	/* 06E80 */
+	0x04,  0x00,  0xA0,  0x31,  0x8C,  0x06,  0x97,  0x04,  0x0F,  0xFE,  0x0A,  0x01,  0x10,  0x3F,  0x8D,  0x06, 	/* 06E90 */
+	0x1F,  0x81,  0x00,  0xFF,  0xE1,  0x20,  0x11,  0x87,  0xE4,  0x98,  0x51,  0x07,  0x10,  0x1F,  0xEF,  0x10, 	/* 06EA0 */
+	0x51,  0x05,  0x7C,  0x94,  0x00,  0x40,  0xFF,  0xE0,  0xA0,  0x31,  0x8C,  0x06,  0x9A,  0x01,  0xC7,  0xE8, 	/* 06EB0 */
+	0x24,  0x42,  0x44,  0x49,  0x03,  0x20,  0x0C,  0x87,  0xFC,  0x04,  0x4F,  0xFE,  0x1B,  0x0E,  0x0E,  0xA0, 	/* 06EC0 */
+	0x17,  0x02,  0x08,  0x7F,  0xC8,  0xA2,  0x3F,  0x82,  0xA8,  0x33,  0x83,  0xF8,  0x24,  0x8F,  0xFE,  0x1B, 	/* 06ED0 */
+	0x0E,  0x0E,  0xA2,  0x04,  0x0F,  0xFE,  0x0A,  0x03,  0x18,  0xC4,  0x67,  0xFC,  0x05,  0x0F,  0xFE,  0x30, 	/* 06EE0 */
+	0x8D,  0xF8,  0x10,  0x81,  0xF8,  0xA5,  0x08,  0x01,  0x00,  0x7F,  0xC5,  0x54,  0x4E,  0x47,  0xFC,  0x55, 	/* 06EF0 */
+	0x46,  0x4C,  0xFF,  0xE0,  0xA0,  0x31,  0x8C,  0x06,  0xA7,  0x08,  0x07,  0xFC,  0x5E,  0x45,  0x54,  0x7F, 	/* 06F00 */
+	0xC4,  0xE4,  0x55,  0x46,  0x4C,  0xFF,  0xE0,  0x40,  0x1B,  0x0E,  0x0E,  0xA8,  0x10,  0x69,  0x78,  0x75, 	/* 06F10 */
+	0x21,  0x34,  0x3F,  0xED,  0x48,  0x12,  0x81,  0x18,  0xFF,  0xE0,  0xA0,  0x31,  0x8C,  0x06,  0xA9,  0x04, 	/* 06F20 */
+	0x0F,  0xFE,  0x0A,  0x03,  0x18,  0xC0,  0x6F,  0xFC,  0x49,  0x04,  0xF0,  0x40,  0x05,  0xDC,  0x55,  0x43, 	/* 06F30 */
+	0xFE,  0xAA,  0x08,  0x0F,  0xFE,  0x15,  0x03,  0xF8,  0xE4,  0x63,  0xF0,  0x24,  0x03,  0xF8,  0x01,  0x0F, 	/* 06F40 */
+	0xFE,  0x11,  0x00,  0x30,  0xAC,  0x50,  0xE5,  0x1A,  0xF6,  0x41,  0x18,  0xF6,  0x85,  0xFE,  0x52,  0x89, 	/* 06F50 */
+	0x58,  0xFF,  0xE0,  0xA0,  0x31,  0x8C,  0x06,  0xAE,  0x04,  0x0F,  0xFE,  0x15,  0x07,  0xF8,  0x24,  0x6F, 	/* 06F60 */
+	0xF8,  0x24,  0x07,  0xFC,  0x44,  0x47,  0xFC,  0x44,  0x47,  0xFC,  0xB3,  0x04,  0x00,  0x40,  0x04,  0x0F, 	/* 06F70 */
+	0xFE,  0x09,  0x00,  0x90,  0x11,  0x01,  0x10,  0x2E,  0x00,  0x60,  0x19,  0x8E,  0x06,  0xB4,  0x40,  0x04, 	/* 06F80 */
+	0x7C,  0x40,  0x4F,  0xC4,  0x54,  0x45,  0x28,  0x52,  0x89,  0x10,  0xF1,  0x82,  0xA8,  0x44,  0x48,  0x82, 	/* 06F90 */
+	0xB8,  0x40,  0x04,  0x7C,  0x51,  0x0F,  0x10,  0x51,  0x05,  0xFE,  0x51,  0x09,  0x10,  0xF1,  0x02,  0x90, 	/* 06FA0 */
+	0x41,  0x08,  0x10,  0xBD,  0x20,  0x02,  0x7C,  0x20,  0x4F,  0x88,  0x51,  0x05,  0x10,  0x5F,  0xE9,  0x10, 	/* 06FB0 */
+	0xF1,  0x02,  0x90,  0x41,  0x08,  0x30,  0x81,  0x41,  0x04,  0x10,  0x51,  0x0F,  0xBE,  0x52,  0x25,  0x62, 	/* 06FC0 */
+	0x59,  0x29,  0x12,  0xF0,  0x22,  0x82,  0x40,  0x28,  0x0C,  0x82,  0x20,  0x02,  0x00,  0x23,  0xEF,  0xE2, 	/* 06FD0 */
+	0x2A,  0x22,  0xA2,  0x4A,  0x24,  0xA2,  0xF2,  0x21,  0xA2,  0x23,  0xE4,  0x00,  0x83,  0x20,  0x02,  0x3C, 	/* 06FE0 */
+	0x20,  0x4F,  0x84,  0x48,  0x44,  0xBC,  0x4A,  0x09,  0x20,  0xF2,  0x02,  0xA2,  0x42,  0x28,  0x1E,  0x84, 	/* 06FF0 */
+	0x04,  0x00,  0x40,  0xFF,  0xE2,  0x00,  0x20,  0x01,  0xFC,  0x08,  0x0F,  0xFE,  0x11,  0x03,  0x90,  0x0E, 	/* 07000 */
+	0x07,  0x1C,  0x8A,  0x20,  0xC2,  0xF0,  0x21,  0x0F,  0x10,  0x51,  0x05,  0xFF,  0x51,  0x09,  0x10,  0xF1, 	/* 07010 */
+	0x02,  0x90,  0x4F,  0xE8,  0x00,  0x8D,  0x40,  0x04,  0x7E,  0x52,  0x4F,  0xA4,  0x52,  0x45,  0xFE,  0x52, 	/* 07020 */
+	0x49,  0x24,  0xF2,  0x42,  0xC4,  0x44,  0x48,  0x84,  0x93,  0x41,  0x04,  0x10,  0x57,  0xEF,  0x90,  0x51, 	/* 07030 */
+	0x05,  0x7C,  0x50,  0x49,  0x24,  0xF1,  0x82,  0x98,  0x42,  0x48,  0xC2,  0x96,  0x20,  0xC2,  0x70,  0x21, 	/* 07040 */
+	0x0F,  0x90,  0x51,  0x05,  0xFE,  0x51,  0x09,  0x10,  0xF2,  0x82,  0xA8,  0x44,  0x48,  0x82,  0x99,  0x21, 	/* 07050 */
+	0x02,  0x10,  0x25,  0x4F,  0xD4,  0x55,  0x25,  0x52,  0x59,  0x69,  0x34,  0xF0,  0x82,  0x90,  0x46,  0x09, 	/* 07060 */
+	0x80,  0x9B,  0x04,  0x04,  0x44,  0x44,  0x47,  0xFC,  0x00,  0x0F,  0xFE,  0x08,  0x07,  0xFC,  0x11,  0x03, 	/* 07070 */
+	0xA0,  0x0F,  0x0F,  0x0C,  0x9D,  0x51,  0x05,  0x10,  0x51,  0x07,  0xFF,  0x52,  0x41,  0x24,  0xF2,  0x45, 	/* 07080 */
+	0x44,  0x56,  0x45,  0x18,  0x53,  0x49,  0xC2,  0xA3,  0x44,  0x84,  0x48,  0x54,  0x8F,  0x48,  0x57,  0xB5, 	/* 07090 */
+	0x4E,  0x54,  0x89,  0x48,  0xF4,  0x82,  0xC8,  0x47,  0x98,  0xC7,  0xA5,  0x01,  0xC7,  0xE4,  0x48,  0x42, 	/* 070A0 */
+	0x48,  0x25,  0x00,  0x80,  0xFF,  0xE1,  0x10,  0x11,  0x03,  0x20,  0x0F,  0x07,  0x0C,  0xA8,  0x22,  0x02, 	/* 070B0 */
+	0x20,  0x2F,  0xEF,  0x20,  0x52,  0x05,  0x3C,  0x52,  0x49,  0x24,  0xF2,  0x42,  0xC4,  0x44,  0x48,  0x98, 	/* 070C0 */
+	0xAC,  0x40,  0x04,  0x7E,  0x51,  0x0F,  0x90,  0x51,  0x05,  0x20,  0x53,  0xE9,  0x32,  0xF5,  0x22,  0xD2, 	/* 070D0 */
+	0x49,  0x28,  0x1E,  0xB2,  0x40,  0x04,  0x7C,  0x54,  0x4F,  0xC4,  0x57,  0xC5,  0x44,  0x54,  0x49,  0x44, 	/* 070E0 */
+	0xF7,  0xC2,  0x80,  0x40,  0x08,  0xFE,  0xB9,  0x41,  0x04,  0x10,  0x47,  0xCF,  0x10,  0x51,  0x05,  0xFE, 	/* 070F0 */
+	0x51,  0x09,  0x38,  0xF5,  0x42,  0x92,  0x41,  0x08,  0x10,  0xBB,  0x04,  0x0F,  0xFE,  0x04,  0x03,  0xF8, 	/* 07100 */
+	0x04,  0x8F,  0xFE,  0x04,  0x8F,  0xFE,  0x11,  0x03,  0x10,  0x0E,  0x07,  0x18,  0xBE,  0x04,  0x00,  0x40, 	/* 07110 */
+	0x7F,  0xC1,  0x10,  0x0A,  0x0F,  0xFE,  0x08,  0x0F,  0xFE,  0x11,  0x03,  0x20,  0x0E,  0x07,  0x18,  0x86, 	/* 07120 */
+	0x47,  0xE4,  0x42,  0x55,  0x2F,  0xCA,  0x57,  0xF5,  0x42,  0x55,  0x29,  0x4A,  0xF4,  0x22,  0xFF,  0x44, 	/* 07130 */
+	0x28,  0x0E,  0x89,  0x41,  0x04,  0x10,  0x4F,  0xEF,  0x10,  0x57,  0xC5,  0x54,  0x55,  0x49,  0x54,  0xF5, 	/* 07140 */
+	0x42,  0xD8,  0x41,  0x08,  0x10,  0x8B,  0x42,  0x04,  0x20,  0x52,  0x8F,  0x44,  0x54,  0xC5,  0xF2,  0x50, 	/* 07150 */
+	0x29,  0x7C,  0xF4,  0x42,  0xC4,  0x44,  0x48,  0x7C,  0x90,  0x40,  0x04,  0x7C,  0x54,  0x4F,  0xC4,  0x57, 	/* 07160 */
+	0xC5,  0x44,  0x54,  0x49,  0x7C,  0xF4,  0x42,  0xC4,  0x44,  0x48,  0xFE,  0x91,  0x41,  0x04,  0x10,  0x51, 	/* 07170 */
+	0x0F,  0xFE,  0x51,  0x05,  0x10,  0x51,  0x09,  0x7C,  0xF4,  0x42,  0xC4,  0x44,  0x48,  0x7C,  0x93,  0x41, 	/* 07180 */
+	0x04,  0x50,  0x55,  0x0F,  0x7E,  0x55,  0x05,  0x90,  0x51,  0x09,  0x7C,  0xF1,  0x02,  0x90,  0x41,  0x08, 	/* 07190 */
+	0xFE,  0x94,  0x01,  0x83,  0xE0,  0x04,  0x0F,  0xFE,  0x0E,  0x03,  0x58,  0xC8,  0x67,  0xFC,  0x11,  0x03, 	/* 071A0 */
+	0xE0,  0x0D,  0x87,  0x04,  0x99,  0x42,  0x34,  0x2E,  0x52,  0x4F,  0x44,  0x54,  0x45,  0xDF,  0x54,  0x49, 	/* 071B0 */
+	0x44,  0xF4,  0x42,  0xC4,  0x44,  0x48,  0x5F,  0x9A,  0x41,  0x44,  0x14,  0x55,  0x5F,  0x55,  0x53,  0x65, 	/* 071C0 */
+	0x14,  0x53,  0x69,  0x55,  0xF5,  0x52,  0x94,  0x42,  0x58,  0x43,  0x9C,  0x20,  0x81,  0x10,  0xFF,  0xE0, 	/* 071D0 */
+	0x40,  0x7F,  0xC0,  0x40,  0xFF,  0xE2,  0x00,  0xFF,  0xE3,  0x18,  0x0E,  0x07,  0x1C,  0xA5,  0x41,  0x04, 	/* 071E0 */
+	0x10,  0x57,  0xEF,  0x94,  0x51,  0x85,  0xFE,  0x51,  0x09,  0x20,  0xF7,  0xC2,  0xA0,  0x42,  0x28,  0x1E, 	/* 071F0 */
+	0xA6,  0x04,  0x07,  0xFC,  0x09,  0x01,  0xA0,  0x06,  0x03,  0x98,  0x10,  0x8F,  0xFE,  0x29,  0x46,  0xB4, 	/* 07200 */
+	0x31,  0x8C,  0xE6,  0xA8,  0x41,  0x04,  0xFE,  0x51,  0x0F,  0xFE,  0x51,  0x25,  0x7E,  0x55,  0x09,  0x7E, 	/* 07210 */
+	0xF5,  0x22,  0x96,  0x42,  0x88,  0xC6,  0xAA,  0x20,  0x02,  0xFE,  0x22,  0x0F,  0x28,  0x55,  0xC5,  0xE2, 	/* 07220 */
+	0x51,  0x09,  0x10,  0xF7,  0xC2,  0x90,  0x41,  0x08,  0xFE,  0xAB,  0x40,  0x04,  0x7E,  0x54,  0x8F,  0x48, 	/* 07230 */
+	0x57,  0xE5,  0x42,  0x54,  0x29,  0x7E,  0xF4,  0x82,  0xC8,  0x44,  0x88,  0x7E,  0xB6,  0x41,  0x04,  0x10, 	/* 07240 */
+	0x52,  0x8F,  0xA8,  0x54,  0x45,  0xBA,  0x90,  0x0D,  0x7C,  0x34,  0x42,  0xC4,  0x44,  0x48,  0x7C,  0xBB, 	/* 07250 */
+	0x40,  0x04,  0x7E,  0x55,  0x2F,  0xD2,  0x57,  0xE5,  0x52,  0x55,  0x29,  0x5A,  0xF5,  0x62,  0xE6,  0x46, 	/* 07260 */
+	0x28,  0x7E,  0xBF,  0x04,  0x04,  0x7E,  0x25,  0x20,  0x94,  0x22,  0x8C,  0xC6,  0x04,  0x0F,  0xFE,  0x08, 	/* 07270 */
+	0x81,  0x90,  0x07,  0x03,  0x8C,  0x81,  0x01,  0x44,  0x12,  0x7F,  0xF4,  0x10,  0x7D,  0x25,  0x52,  0x7F, 	/* 07280 */
+	0x45,  0x4C,  0x54,  0x95,  0x4D,  0x89,  0x3B,  0x61,  0x83,  0x41,  0x04,  0x10,  0x57,  0xCF,  0x90,  0x51, 	/* 07290 */
+	0x05,  0xFE,  0x51,  0x09,  0x10,  0xF7,  0xC2,  0x90,  0x41,  0x08,  0xFE,  0x89,  0x42,  0x04,  0x7C,  0x45, 	/* 072A0 */
+	0x4F,  0xFC,  0x55,  0x45,  0x7C,  0x50,  0x09,  0xFE,  0xF2,  0x02,  0xBC,  0x40,  0x48,  0x18,  0x91,  0x41, 	/* 072B0 */
+	0x02,  0x54,  0x85,  0x24,  0xB2,  0x20,  0x8C,  0x30,  0x0C,  0x0F,  0xFE,  0x11,  0x01,  0xA0,  0x07,  0x07, 	/* 072C0 */
+	0x8C,  0x98,  0x22,  0x02,  0x20,  0x27,  0xCF,  0xC4,  0x57,  0xC5,  0x44,  0x57,  0xC9,  0x52,  0xF5,  0x42, 	/* 072D0 */
+	0xC8,  0x46,  0x49,  0x82,  0x9A,  0x40,  0x04,  0x7C,  0x45,  0x4F,  0x7C,  0x55,  0x45,  0x54,  0x57,  0xC9, 	/* 072E0 */
+	0x10,  0xFF,  0xE2,  0x92,  0x42,  0x28,  0x4C,  0x9C,  0x40,  0x05,  0xEE,  0x4A,  0xAF,  0xAA,  0x5E,  0xA5, 	/* 072F0 */
+	0xAC,  0x5A,  0xA9,  0xEA,  0xEA,  0xA2,  0xAE,  0x4A,  0x89,  0x68,  0x9F,  0x23,  0xE2,  0x22,  0x2B,  0xEF, 	/* 07300 */
+	0xC0,  0x4B,  0xE4,  0xA2,  0x4B,  0xE9,  0x22,  0xF3,  0xE2,  0xA2,  0x42,  0x28,  0x26,  0xA0,  0x47,  0xE4, 	/* 07310 */
+	0x40,  0x55,  0xCF,  0x40,  0x57,  0xE5,  0x50,  0x55,  0xA9,  0x5A,  0xF5,  0x42,  0x94,  0x49,  0xA9,  0x62, 	/* 07320 */
+	0xA5,  0x47,  0x64,  0x25,  0x52,  0x4F,  0x24,  0x5F,  0xF5,  0x24,  0x53,  0x59,  0x65,  0xF2,  0x62,  0xAC, 	/* 07330 */
+	0x42,  0x58,  0x63,  0xA9,  0x21,  0x02,  0x3C,  0x24,  0x8F,  0x90,  0x57,  0xC5,  0x54,  0x55,  0x49,  0x7C, 	/* 07340 */
+	0xF2,  0x82,  0xAA,  0x44,  0xA8,  0x86,  0xAF,  0x43,  0xC4,  0xA4,  0x5A,  0x4F,  0xBC,  0x58,  0x05,  0xFC, 	/* 07350 */
+	0x50,  0x49,  0x04,  0xFF,  0xE2,  0xA8,  0x44,  0x48,  0x82,  0xB5,  0x40,  0x05,  0xFE,  0x4A,  0x0F,  0xBE, 	/* 07360 */
+	0x5E,  0xA5,  0xAA,  0x5E,  0xA9,  0xA4,  0xEA,  0xA2,  0xEA,  0x73,  0x18,  0x20,  0xB6,  0x00,  0x0F,  0xFC, 	/* 07370 */
+	0x48,  0x47,  0xA4,  0x79,  0x84,  0x94,  0xFE,  0x20,  0x80,  0xFF,  0xE3,  0x10,  0x0E,  0x07,  0x18,  0xBC, 	/* 07380 */
+	0x20,  0x02,  0x3C,  0x22,  0x4F,  0xBC,  0x52,  0x45,  0x3C,  0x50,  0x09,  0x7E,  0xF4,  0x22,  0xFE,  0x44, 	/* 07390 */
+	0x28,  0x7E,  0x80,  0x40,  0x04,  0xFF,  0x4A,  0x2F,  0xC2,  0x5C,  0xE5,  0xAA,  0x5A,  0xA9,  0xAA,  0xFA, 	/* 073A0 */
+	0xE2,  0xC2,  0x48,  0x28,  0x86,  0x81,  0x3F,  0x82,  0x48,  0xFF,  0xE2,  0x48,  0x7F,  0xC4,  0x44,  0x7F, 	/* 073B0 */
+	0xC1,  0x00,  0xFF,  0xE3,  0x10,  0x0E,  0x07,  0x18,  0x86,  0x61,  0x00,  0xFE,  0xC9,  0x21,  0xFC,  0x2A, 	/* 073C0 */
+	0x4C,  0x98,  0x16,  0x6F,  0xFE,  0x11,  0x03,  0x20,  0x0F,  0x0F,  0x0E,  0x89,  0x41,  0x04,  0x10,  0x5F, 	/* 073D0 */
+	0xEF,  0x42,  0x56,  0xE5,  0xAA,  0x5A,  0xA9,  0x6C,  0xE4,  0x82,  0x48,  0x48,  0xA9,  0x06,  0x9A,  0x40, 	/* 073E0 */
+	0xE4,  0x78,  0x54,  0x8F,  0x7E,  0x54,  0x85,  0x66,  0x5C,  0x29,  0x7C,  0xF4,  0x42,  0xFC,  0x44,  0x48, 	/* 073F0 */
+	0x7C,  0xA2,  0x40,  0x84,  0x10,  0x57,  0xEF,  0xCA,  0x57,  0xE5,  0x4A,  0x57,  0xE9,  0x14,  0xF2,  0x42, 	/* 07400 */
+	0xFF,  0x40,  0x48,  0x04,  0xA6,  0x27,  0xC2,  0x04,  0x23,  0xCF,  0x04,  0x57,  0xF5,  0x51,  0x57,  0xF9, 	/* 07410 */
+	0x52,  0xF5,  0x22,  0xD6,  0x41,  0x08,  0x10,  0xAA,  0x11,  0x0F,  0xFE,  0x11,  0x83,  0xB4,  0x55,  0x29, 	/* 07420 */
+	0x10,  0x08,  0x0F,  0xFE,  0x11,  0x03,  0x20,  0x0F,  0x07,  0x0C,  0xAC,  0x40,  0x64,  0x78,  0x45,  0x4F, 	/* 07430 */
+	0x92,  0x50,  0xC5,  0xF0,  0x51,  0x09,  0x10,  0xFF,  0xC2,  0x90,  0x41,  0x08,  0xFE,  0xBF,  0x4F,  0xE4, 	/* 07440 */
+	0x10,  0x55,  0xCF,  0x50,  0x5B,  0xE5,  0x7C,  0x54,  0x49,  0x7C,  0xF4,  0x42,  0xFC,  0x44,  0x48,  0x4C, 	/* 07450 */
+	0x92,  0x44,  0x44,  0xFE,  0x54,  0x4F,  0x7C,  0x54,  0x45,  0x7C,  0x51,  0x09,  0xFE,  0xE3,  0x82,  0x54, 	/* 07460 */
+	0x49,  0x28,  0x10,  0x9A,  0x40,  0x04,  0x7E,  0x55,  0x2F,  0xFE,  0x54,  0x05,  0x5E,  0x55,  0x29,  0x5E, 	/* 07470 */
+	0xF5,  0x22,  0x9E,  0x49,  0x29,  0x1E,  0x9B,  0x20,  0xE2,  0xF2,  0x25,  0x4F,  0x28,  0x5F,  0xE5,  0x20, 	/* 07480 */
+	0x5F,  0xE9,  0x20,  0xF7,  0xC2,  0x54,  0x48,  0xC8,  0x72,  0xBC,  0x20,  0x02,  0x7C,  0x25,  0x4F,  0x54, 	/* 07490 */
+	0x56,  0xC5,  0x7C,  0x50,  0x09,  0xFE,  0xEA,  0xA2,  0xAA,  0x4A,  0xA9,  0xFF,  0xBD,  0x40,  0x04,  0x7C, 	/* 074A0 */
+	0x45,  0x0F,  0xFC,  0x55,  0x05,  0x7C,  0x55,  0x09,  0x7E,  0xE0,  0xA2,  0xAA,  0x4A,  0x29,  0x1C,  0xBE, 	/* 074B0 */
+	0x42,  0x84,  0xFC,  0x42,  0x8F,  0xFE,  0x51,  0x05,  0x7C,  0x55,  0x49,  0x7C,  0xE5,  0x42,  0xFE,  0x44, 	/* 074C0 */
+	0x48,  0x4C,  0x81,  0x41,  0x04,  0xFE,  0x58,  0x2F,  0x7C,  0x51,  0x05,  0xF2,  0x52,  0xC9,  0xD8,  0xF2, 	/* 074D0 */
+	0xC2,  0xCA,  0x40,  0x88,  0x30,  0x82,  0x41,  0x04,  0x6E,  0x44,  0xAF,  0x6E,  0x54,  0xA5,  0x6E,  0x50, 	/* 074E0 */
+	0x89,  0xFF,  0xE2,  0x42,  0x18,  0x41,  0x48,  0x62,  0x89,  0x40,  0x84,  0x08,  0x57,  0xEF,  0x50,  0x5D, 	/* 074F0 */
+	0x05,  0x5E,  0x56,  0x89,  0xC8,  0xF7,  0xE2,  0x48,  0x49,  0x49,  0x62,  0x8B,  0x40,  0x04,  0xEE,  0x42, 	/* 07500 */
+	0x2F,  0xEE,  0x58,  0x85,  0xEE,  0x56,  0x69,  0xAA,  0xF6,  0x62,  0xAA,  0x42,  0x28,  0xCC,  0x8C,  0x48, 	/* 07510 */
+	0x85,  0xFE,  0x45,  0x0F,  0xFC,  0x55,  0x45,  0xFE,  0x55,  0x49,  0xFC,  0xF5,  0x02,  0xD8,  0x55,  0x68, 	/* 07520 */
+	0x50,  0x90,  0x40,  0x85,  0xF8,  0x55,  0xAF,  0xFE,  0x55,  0xA5,  0xFA,  0x54,  0xA9,  0xF2,  0xD5,  0xA2, 	/* 07530 */
+	0x54,  0x59,  0xA9,  0x32,  0x96,  0x4F,  0xE4,  0x28,  0x4F,  0xEF,  0xAA,  0x5F,  0xE5,  0x00,  0x57,  0xC9, 	/* 07540 */
+	0x00,  0xFF,  0xE2,  0x54,  0x49,  0x28,  0x30,  0x97,  0x40,  0x04,  0x7E,  0x55,  0xCF,  0xD4,  0x55,  0xC5, 	/* 07550 */
+	0x40,  0x57,  0xE9,  0x5A,  0xF5,  0xA2,  0xFE,  0x44,  0x08,  0x7E,  0xA1,  0x41,  0x04,  0xFE,  0x44,  0x4F, 	/* 07560 */
+	0x28,  0x5F,  0xE5,  0x92,  0x5F,  0xE9,  0x92,  0xFB,  0xA2,  0xAA,  0x4B,  0xA8,  0x86,  0xA3,  0x4F,  0xC4, 	/* 07570 */
+	0x10,  0x45,  0xCF,  0x50,  0x5F,  0xE5,  0x40,  0x57,  0xC9,  0x40,  0xE7,  0xE2,  0x2A,  0x45,  0x28,  0x8C, 	/* 07580 */
+	0xA6,  0x49,  0x24,  0x54,  0x4F,  0xEF,  0x82,  0x57,  0xC5,  0x44,  0x57,  0xC9,  0x10,  0xFF,  0xE2,  0x92, 	/* 07590 */
+	0x49,  0x48,  0x10,  0xA9,  0x44,  0x84,  0x48,  0x5F,  0x8F,  0x4F,  0x5F,  0xA5,  0x52,  0x5F,  0xA9,  0x4A, 	/* 075A0 */
+	0xEE,  0x43,  0x54,  0x44,  0xA8,  0x51,  0xBA,  0x4E,  0xE4,  0xAA,  0x5E,  0xEF,  0xAA,  0x5E,  0xE5,  0x82, 	/* 075B0 */
+	0x5B,  0xA9,  0xAA,  0xEB,  0xA2,  0xAA,  0x4B,  0xA8,  0x86,  0xBB,  0x4E,  0xE4,  0xAA,  0x5E,  0xEF,  0xAA, 	/* 075C0 */
+	0x5E,  0xE5,  0x92,  0x5F,  0xE9,  0x92,  0xEB,  0xA2,  0xD6,  0x49,  0x28,  0x86,  0x89,  0x41,  0x04,  0xFE, 	/* 075D0 */
+	0x51,  0x0F,  0xFC,  0x54,  0x45,  0x7C,  0x52,  0x89,  0xFE,  0xF0,  0x02,  0xFC,  0x44,  0x48,  0x7C,  0x8B, 	/* 075E0 */
+	0x2E,  0xE2,  0xAA,  0x2E,  0xEF,  0x00,  0x57,  0xC5,  0x54,  0x57,  0xC9,  0x54,  0xF7,  0xC2,  0x90,  0x4F, 	/* 075F0 */
+	0xE8,  0x10,  0x8C,  0x40,  0xC4,  0xF0,  0x41,  0x0F,  0xFE,  0x53,  0xC5,  0x6A,  0x5B,  0x99,  0xFE,  0xEB, 	/* 07600 */
+	0xA2,  0xAA,  0x4B,  0xA8,  0x86,  0x96,  0x78,  0x84,  0xBE,  0x79,  0x44,  0x7F,  0x78,  0x84,  0xBE,  0xB8, 	/* 07610 */
+	0x80,  0x88,  0xFF,  0xE3,  0x10,  0x0E,  0x07,  0x18,  0xA2,  0x41,  0x04,  0xFE,  0x52,  0x8F,  0xC4,  0x52, 	/* 07620 */
+	0xA5,  0xFC,  0x52,  0x89,  0xFE,  0xF5,  0x42,  0xC8,  0x47,  0x48,  0xC2,  0xAA,  0x41,  0x04,  0xFE,  0x48, 	/* 07630 */
+	0x2F,  0x7C,  0x55,  0x45,  0xBE,  0x54,  0x49,  0xFC,  0xF4,  0x42,  0x7C,  0x42,  0x48,  0xC2,  0xAC,  0x47, 	/* 07640 */
+	0xC4,  0x10,  0x4F,  0xEF,  0x92,  0x5B,  0xA5,  0x00,  0x5F,  0xE9,  0x10,  0xFF,  0xE2,  0xAA,  0x4A,  0xA8, 	/* 07650 */
+	0x86,  0xB0,  0xFB,  0xE8,  0xA2,  0xFB,  0xE8,  0xA2,  0xFB,  0xE5,  0x14,  0x8A,  0x2F,  0xFE,  0x11,  0x03, 	/* 07660 */
+	0x10,  0x0E,  0x07,  0x1C,  0xB2,  0x08,  0x0F,  0xBE,  0xAA,  0xAF,  0xFE,  0xAA,  0xAF,  0xBE,  0x4A,  0x4F, 	/* 07670 */
+	0xBE,  0x5C,  0xA5,  0x6A,  0x59,  0x2B,  0x26,  0xB6,  0x42,  0x04,  0x7C,  0x54,  0x4F,  0x7C,  0x54,  0x45, 	/* 07680 */
+	0xFE,  0x59,  0x29,  0xFE,  0xE9,  0x22,  0xFE,  0x44,  0x48,  0x84,  0xBE,  0x44,  0x04,  0x5E,  0x5E,  0xAF, 	/* 07690 */
+	0x56,  0x5F,  0x05,  0x5E,  0x55,  0x29,  0xFE,  0xE5,  0x22,  0xDE,  0x56,  0xA8,  0x51,  0x80,  0x47,  0xC4, 	/* 076A0 */
+	0x10,  0x57,  0xEF,  0xD2,  0x57,  0xA5,  0x5E,  0x5F,  0x29,  0x5E,  0xEF,  0x22,  0xDE,  0x55,  0x28,  0x5E, 	/* 076B0 */
+	0x83,  0x41,  0x04,  0xFE,  0x50,  0x0F,  0xEE,  0x5A,  0xA5,  0xFE,  0x52,  0x89,  0xFE,  0xE3,  0x22,  0xCC, 	/* 076C0 */
+	0x44,  0x48,  0xE2,  0x85,  0x4A,  0x84,  0xAC,  0x55,  0x8F,  0xFE,  0x55,  0x85,  0x5A,  0x5D,  0xA9,  0x54, 	/* 076D0 */
+	0xED,  0xC2,  0x54,  0x47,  0xA9,  0x91,  0x90,  0x00,  0x03,  0xF8,  0x01,  0x00,  0x20,  0x04,  0x00,  0x40, 	/* 076E0 */
+	0xFF,  0xE0,  0x40,  0x04,  0x00,  0x40,  0x04,  0x00,  0xC0,  0x91,  0x00,  0x03,  0xF8,  0x01,  0x00,  0x20, 	/* 076F0 */
+	0x04,  0xC0,  0x70,  0x1C,  0x0E,  0x40,  0x04,  0x00,  0x40,  0x04,  0x00,  0xC0,  0x94,  0x02,  0x0F,  0xA0, 	/* 07700 */
+	0x0A,  0x01,  0x20,  0x22,  0x03,  0xA0,  0xE2,  0x02,  0x20,  0x22,  0x02,  0x20,  0x22,  0x26,  0x1E,  0x95, 	/* 07710 */
+	0x7F,  0x80,  0x88,  0x08,  0x80,  0x9E,  0x10,  0x23,  0xFA,  0xC3,  0x40,  0x40,  0xFF,  0xE0,  0x40,  0x04, 	/* 07720 */
+	0x00,  0xC0,  0x97,  0x04,  0x00,  0x40,  0xFF,  0xE8,  0x02,  0x9F,  0x20,  0x20,  0x04,  0x0F,  0xFE,  0x04, 	/* 07730 */
+	0x00,  0x40,  0x04,  0x00,  0xC0,  0x98,  0x08,  0x00,  0x80,  0xFF,  0xE0,  0x80,  0x17,  0xC1,  0x08,  0x21, 	/* 07740 */
+	0x06,  0xFE,  0xA1,  0x02,  0x10,  0x21,  0x02,  0x30,  0x9A,  0x07,  0xC7,  0x88,  0x44,  0x44,  0x42,  0xBF, 	/* 07750 */
+	0x80,  0x30,  0x04,  0x0F,  0xFE,  0x04,  0x00,  0x40,  0x04,  0x00,  0xC0,  0x9B,  0x04,  0x07,  0xFC,  0x04, 	/* 07760 */
+	0x0F,  0xFE,  0x80,  0x29,  0xF2,  0x02,  0x00,  0x40,  0xFF,  0xE0,  0x40,  0x04,  0x00,  0xC0,  0x9C,  0x02, 	/* 07770 */
+	0x0F,  0xA0,  0x13,  0xE2,  0x24,  0x24,  0x43,  0x54,  0xE9,  0x82,  0x08,  0x21,  0x82,  0x14,  0x22,  0x46, 	/* 07780 */
+	0xC2,  0x9D,  0x04,  0x00,  0x44,  0x3F,  0x80,  0x50,  0xFF,  0xE0,  0x40,  0x1F,  0x8E,  0x30,  0x7F,  0xE0, 	/* 07790 */
+	0x40,  0x04,  0x00,  0xC0,  0x9F,  0x00,  0x03,  0xF8,  0x02,  0x00,  0x40,  0xFF,  0xE0,  0x40,  0x04,  0x00, 	/* 077A0 */
+	0xC0,  0x7F,  0xC4,  0xA4,  0x4A,  0x4F,  0xFE,  0xA3,  0x03,  0x87,  0xC0,  0x04,  0x0F,  0xFE,  0x0E,  0x03, 	/* 077B0 */
+	0x58,  0xDF,  0x60,  0x20,  0x7F,  0xC0,  0x40,  0x04,  0x00,  0xC0,  0xA4,  0x00,  0x6F,  0x7C,  0x15,  0x42, 	/* 077C0 */
+	0x54,  0x25,  0x42,  0x54,  0x35,  0x4E,  0x54,  0x25,  0x42,  0x52,  0x25,  0x66,  0xBD,  0xA5,  0x10,  0x0F, 	/* 077D0 */
+	0xFE,  0x25,  0x26,  0x4C,  0x19,  0x42,  0x62,  0xDF,  0x00,  0x20,  0xFF,  0xE0,  0x40,  0x04,  0x00,  0xC0, 	/* 077E0 */
+	0xA6,  0x24,  0x41,  0x28,  0xFF,  0xE8,  0x02,  0x9F,  0x20,  0x20,  0x04,  0x07,  0xFE,  0x04,  0x00,  0x40, 	/* 077F0 */
+	0x04,  0x00,  0xC0,  0xA9,  0x00,  0x8F,  0x88,  0x17,  0xF1,  0x10,  0x26,  0x42,  0x94,  0x30,  0xA6,  0x12, 	/* 07800 */
+	0xA2,  0x42,  0x4C,  0x23,  0x26,  0xC1,  0xAB,  0x00,  0x4F,  0x78,  0x11,  0x02,  0x64,  0x21,  0x83,  0x24, 	/* 07810 */
+	0xEF,  0xA2,  0x12,  0x25,  0x42,  0x52,  0x29,  0x26,  0x10,  0xB0,  0x10,  0x8F,  0x88,  0x07,  0xE7,  0x8A, 	/* 07820 */
+	0x48,  0xA7,  0x8A,  0x03,  0xA7,  0xCE,  0x08,  0xAF,  0xEA,  0x11,  0x13,  0x21,  0xB1,  0x00,  0x07,  0xFC, 	/* 07830 */
+	0x40,  0x47,  0xFC,  0x47,  0x05,  0xFC,  0x42,  0x07,  0xFC,  0x48,  0x8B,  0xFE,  0x88,  0x81,  0x98,  0xB3, 	/* 07840 */
+	0x11,  0x0F,  0xFE,  0x29,  0x4D,  0x68,  0x29,  0x4F,  0xBE,  0x08,  0x23,  0xF8,  0x03,  0x0F,  0xFE,  0x04, 	/* 07850 */
+	0x00,  0xC0,  0xB5,  0x30,  0x4D,  0xF8,  0xB5,  0xCB,  0x6A,  0xFE,  0xAF,  0xC0,  0xB5,  0xCB,  0x44,  0xF7, 	/* 07860 */
+	0xE3,  0xC8,  0x30,  0x85,  0x18,  0xB8,  0x1A,  0x06,  0x5C,  0x4A,  0x47,  0x5C,  0x4A,  0x4F,  0xFE,  0x80, 	/* 07870 */
+	0x29,  0xF0,  0x02,  0x0F,  0xFE,  0x04,  0x00,  0xC0,  0xBA,  0x07,  0xCF,  0x10,  0x1F,  0xE2,  0x92,  0x2B, 	/* 07880 */
+	0xA3,  0x00,  0xEF,  0xE2,  0x20,  0x2F,  0xE2,  0xAA,  0x2A,  0xA6,  0x86,  0x80,  0x00,  0x00,  0x00,  0x04, 	/* 07890 */
+	0x00,  0x40,  0x04,  0x0F,  0xFE,  0x80,  0x28,  0x02,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x83,  0x04, 	/* 078A0 */
+	0x00,  0x40,  0xFF,  0xE8,  0x02,  0x90,  0x21,  0x00,  0x11,  0x81,  0xE0,  0x10,  0x01,  0x04,  0x10,  0x40, 	/* 078B0 */
+	0xFC,  0x85,  0x04,  0x0F,  0xFE,  0x80,  0x28,  0x12,  0x0E,  0x07,  0x80,  0x08,  0x00,  0xFE,  0xF8,  0x00, 	/* 078C0 */
+	0x80,  0x08,  0x40,  0x7C,  0x87,  0x04,  0x0F,  0xFE,  0x80,  0x2B,  0xFA,  0x04,  0x00,  0x40,  0x7F,  0xC0, 	/* 078D0 */
+	0x40,  0x04,  0x00,  0x40,  0x04,  0x00,  0xC0,  0x88,  0x04,  0x0F,  0xFE,  0x80,  0x28,  0x12,  0x01,  0x07, 	/* 078E0 */
+	0xFC,  0x01,  0x01,  0x10,  0x09,  0x00,  0x10,  0x01,  0x00,  0x30,  0x89,  0x04,  0x0F,  0xFE,  0x88,  0x28, 	/* 078F0 */
+	0x82,  0x08,  0x0F,  0xFE,  0x11,  0x01,  0x10,  0x3D,  0x00,  0x60,  0x19,  0x86,  0x04,  0x8B,  0x04,  0x00, 	/* 07900 */
+	0x40,  0xFF,  0xE8,  0x02,  0x84,  0x20,  0x40,  0xFF,  0xE0,  0x40,  0x0E,  0x03,  0x58,  0xC4,  0x60,  0x40, 	/* 07910 */
+	0x8C,  0x04,  0x0F,  0xFE,  0x80,  0x29,  0xF2,  0x00,  0x00,  0x00,  0xFF,  0xE0,  0xA0,  0x0A,  0x01,  0x22, 	/* 07920 */
+	0x22,  0x2C,  0x1E,  0x8D,  0x04,  0x00,  0x40,  0xFF,  0xE8,  0x02,  0x84,  0x20,  0x40,  0xFF,  0xE0,  0x00, 	/* 07930 */
+	0x11,  0x01,  0x08,  0x20,  0x4C,  0x04,  0x8F,  0x04,  0x0F,  0xFE,  0x88,  0x20,  0x80,  0xFF,  0xE0,  0x80, 	/* 07940 */
+	0x14,  0x01,  0x40,  0x25,  0x04,  0x88,  0x8F,  0x43,  0x04,  0x95,  0x04,  0x0F,  0xFE,  0x80,  0x20,  0x00, 	/* 07950 */
+	0xFF,  0xE0,  0x80,  0x10,  0x01,  0xFC,  0x30,  0x45,  0x04,  0x90,  0x41,  0xFC,  0x97,  0x04,  0x0F,  0xFE, 	/* 07960 */
+	0x80,  0x29,  0xF2,  0x00,  0x00,  0x00,  0xFF,  0xE0,  0x50,  0x24,  0x82,  0x44,  0x44,  0x40,  0xC0,  0x98, 	/* 07970 */
+	0x04,  0x0F,  0xFE,  0x80,  0x29,  0xF2,  0x11,  0x01,  0x10,  0x1F,  0x01,  0x00,  0x1F,  0x81,  0x08,  0x10, 	/* 07980 */
+	0x81,  0xF8,  0x99,  0x04,  0x0F,  0xFE,  0x84,  0x28,  0x42,  0x3F,  0x82,  0x48,  0x24,  0x83,  0xF8,  0x24, 	/* 07990 */
+	0x82,  0x48,  0x3F,  0x80,  0x00,  0x9A,  0x04,  0x0F,  0xFE,  0x80,  0x28,  0x02,  0x3F,  0x80,  0x40,  0x04, 	/* 079A0 */
+	0x02,  0x78,  0x24,  0x03,  0x40,  0x4C,  0x08,  0x3E,  0x9B,  0x04,  0x0F,  0xFE,  0x80,  0x2A,  0x02,  0x3B, 	/* 079B0 */
+	0xC2,  0xA4,  0x4A,  0x4A,  0xA4,  0x13,  0x81,  0x22,  0x22,  0x24,  0x1E,  0x9C,  0x04,  0x0F,  0xFE,  0x80, 	/* 079C0 */
+	0x29,  0xF2,  0x11,  0x01,  0x10,  0x1F,  0x01,  0x10,  0x1F,  0x01,  0x10,  0x11,  0x0F,  0xFE,  0x9D,  0x04, 	/* 079D0 */
+	0x0F,  0xFE,  0x80,  0x28,  0x02,  0x3F,  0x80,  0x40,  0x04,  0x03,  0xF0,  0x04,  0x00,  0x48,  0x04,  0x4F, 	/* 079E0 */
+	0xFE,  0x9F,  0x04,  0x0F,  0xFE,  0x84,  0x28,  0x42,  0x3F,  0x80,  0x40,  0x3F,  0x80,  0x40,  0xFF,  0xE0, 	/* 079F0 */
+	0xA0,  0x31,  0x8C,  0x06,  0xA2,  0x04,  0x0F,  0xFE,  0x88,  0x28,  0xF2,  0x11,  0x06,  0xA0,  0x06,  0x03, 	/* 07A00 */
+	0x98,  0xDF,  0xE1,  0x08,  0x10,  0x81,  0xF8,  0xA3,  0x04,  0x0F,  0xFE,  0x80,  0x2B,  0xFA,  0x00,  0x03, 	/* 07A10 */
+	0xF8,  0x20,  0x83,  0xF8,  0x20,  0x83,  0xF8,  0x00,  0x0F,  0xFE,  0xA4,  0x04,  0x0F,  0xFE,  0x80,  0x2B, 	/* 07A20 */
+	0xFA,  0x0A,  0x01,  0x18,  0x7E,  0x40,  0x40,  0x7F,  0xC0,  0x40,  0x04,  0x0F,  0xFE,  0xA5,  0x04,  0x0F, 	/* 07A30 */
+	0xFE,  0x88,  0x2F,  0xFA,  0x10,  0x01,  0xF8,  0x30,  0x85,  0xF8,  0x90,  0x81,  0xF8,  0x10,  0x81,  0x18, 	/* 07A40 */
+	0xA6,  0x04,  0x0F,  0xFE,  0x80,  0x2F,  0xFC,  0x44,  0x04,  0x40,  0x7F,  0x84,  0x08,  0x7F,  0x84,  0x40, 	/* 07A50 */
+	0x44,  0x07,  0xFE,  0xAE,  0x04,  0x0F,  0xFE,  0x80,  0x29,  0xF2,  0x11,  0x01,  0x10,  0x1F,  0x00,  0x80, 	/* 07A60 */
+	0x3F,  0x82,  0x08,  0x20,  0x83,  0xF8,  0xB0,  0x04,  0x0F,  0xFE,  0x84,  0x27,  0xFC,  0x11,  0x00,  0xA0, 	/* 07A70 */
+	0xFF,  0xE0,  0x40,  0x7F,  0xC0,  0x40,  0x04,  0x00,  0x40,  0xB3,  0x04,  0x0F,  0xFE,  0x84,  0x2B,  0xFA, 	/* 07A80 */
+	0x04,  0x03,  0xF8,  0x04,  0x07,  0xFC,  0x00,  0x03,  0xF8,  0x20,  0x83,  0xF8,  0xB4,  0x04,  0x0F,  0xFE, 	/* 07A90 */
+	0x9F,  0x29,  0x12,  0x1F,  0x01,  0x10,  0x1F,  0x00,  0x80,  0xFF,  0xE3,  0x10,  0x0E,  0x07,  0x18,  0xB5, 	/* 07AA0 */
+	0x04,  0x0F,  0xFE,  0x84,  0x2A,  0x4A,  0x15,  0x03,  0xF8,  0x20,  0x83,  0xF8,  0x20,  0x83,  0xF8,  0x20, 	/* 07AB0 */
+	0x82,  0x18,  0xB6,  0x04,  0x0F,  0xFE,  0x80,  0x2B,  0xFA,  0x08,  0x01,  0x54,  0x6B,  0x41,  0x68,  0x6A, 	/* 07AC0 */
+	0x81,  0x24,  0x62,  0x20,  0xC0,  0xB8,  0x04,  0x0F,  0xFE,  0x80,  0x2B,  0xFE,  0x20,  0x02,  0xF8,  0x20, 	/* 07AD0 */
+	0x03,  0xFC,  0x4A,  0x44,  0x98,  0x8C,  0x83,  0x06,  0xB9,  0x04,  0x0F,  0xFE,  0x92,  0x29,  0x12,  0x24, 	/* 07AE0 */
+	0x84,  0xA8,  0x11,  0x02,  0x08,  0xFF,  0xE2,  0x08,  0x20,  0x83,  0xF8,  0xBF,  0x04,  0x0F,  0xFE,  0x80, 	/* 07AF0 */
+	0x29,  0xFE,  0x11,  0x02,  0x7C,  0x64,  0x4A,  0x44,  0x27,  0xC2,  0x44,  0x24,  0x42,  0x7C,  0x82,  0x04, 	/* 07B00 */
+	0x0F,  0xFE,  0xA0,  0x2A,  0x02,  0x3B,  0xC2,  0x04,  0xFE,  0x82,  0x28,  0xB1,  0x0A,  0x98,  0xA2,  0x42, 	/* 07B10 */
+	0x42,  0x83,  0x04,  0x0F,  0xFE,  0x84,  0x28,  0xF2,  0x32,  0x0F,  0xF8,  0x24,  0x83,  0xF8,  0x0B,  0x00, 	/* 07B20 */
+	0xAA,  0x32,  0x2C,  0x1E,  0x84,  0x04,  0x0F,  0xFE,  0x84,  0x27,  0xF8,  0x0A,  0x03,  0x10,  0xFF,  0xE0, 	/* 07B30 */
+	0x08,  0x3E,  0x82,  0x28,  0x3E,  0x80,  0x18,  0x85,  0x04,  0x0F,  0xFE,  0x80,  0x2B,  0xFA,  0x04,  0x03, 	/* 07B40 */
+	0xF8,  0x24,  0x83,  0xF8,  0x24,  0x83,  0xF8,  0x11,  0x86,  0x04,  0x86,  0x04,  0x0F,  0xFE,  0x88,  0x28, 	/* 07B50 */
+	0x52,  0x51,  0x45,  0x22,  0x94,  0xA1,  0xF8,  0x24,  0x04,  0x44,  0x44,  0x47,  0xFC,  0x87,  0x04,  0x0F, 	/* 07B60 */
+	0xFE,  0x81,  0x27,  0xDC,  0x01,  0x0F,  0xFC,  0x28,  0x42,  0xA8,  0x29,  0x82,  0x98,  0x4A,  0x48,  0x7E, 	/* 07B70 */
+	0x89,  0x04,  0x0F,  0xFE,  0x90,  0x29,  0x12,  0x22,  0x03,  0xFC,  0x62,  0x0B,  0xF8,  0x22,  0x03,  0xF8, 	/* 07B80 */
+	0x22,  0x03,  0xFC,  0x8C,  0x04,  0x0F,  0xFE,  0x80,  0x27,  0xFC,  0x20,  0x83,  0xF8,  0x00,  0x07,  0xFC, 	/* 07B90 */
+	0x44,  0x47,  0xFC,  0x44,  0x47,  0xFC,  0x90,  0x04,  0x0F,  0xFE,  0x90,  0x25,  0x12,  0x57,  0xC7,  0x10, 	/* 07BA0 */
+	0x1F,  0xEF,  0x18,  0x53,  0x85,  0x54,  0x59,  0x29,  0x10,  0x92,  0x04,  0x0F,  0xFE,  0x92,  0x2F,  0xFA, 	/* 07BB0 */
+	0x12,  0x07,  0xF8,  0x12,  0x0F,  0xFC,  0x29,  0x04,  0x48,  0x98,  0x60,  0x60,  0x93,  0x04,  0x0F,  0xFE, 	/* 07BC0 */
+	0x80,  0x2B,  0xFA,  0x24,  0x83,  0xF8,  0x24,  0x87,  0xFC,  0x45,  0x45,  0xF4,  0x41,  0x44,  0x0C,  0x94, 	/* 07BD0 */
+	0x04,  0x0F,  0xFE,  0x80,  0x29,  0xF2,  0x11,  0x01,  0xF0,  0x11,  0x0F,  0xFE,  0x24,  0x02,  0x7C,  0x5C, 	/* 07BE0 */
+	0x08,  0x7E,  0x9B,  0x04,  0x0F,  0xFE,  0x91,  0x27,  0xFC,  0x11,  0x03,  0xF8,  0x20,  0x83,  0xF8,  0x20, 	/* 07BF0 */
+	0x83,  0xF8,  0x1A,  0x2E,  0x1E,  0x9D,  0x04,  0x0F,  0xFE,  0xAF,  0xA2,  0x0A,  0xAF,  0x86,  0x08,  0x3F, 	/* 07C00 */
+	0xE7,  0x02,  0xAF,  0xC2,  0x48,  0x23,  0x03,  0xCE,  0x9E,  0x04,  0x0F,  0xFE,  0x91,  0x2B,  0xFA,  0x11, 	/* 07C10 */
+	0x03,  0xF8,  0x20,  0x83,  0xF8,  0x20,  0x8F,  0xFE,  0x1B,  0x0E,  0x0E,  0x9F,  0x04,  0x0F,  0xFE,  0x80, 	/* 07C20 */
+	0x2B,  0xBE,  0x4A,  0x4B,  0x18,  0x2F,  0x4C,  0x02,  0x7F,  0xE2,  0x58,  0xC4,  0x40,  0xC0,  0xA1,  0x04, 	/* 07C30 */
+	0x0F,  0xFE,  0x88,  0x29,  0xF2,  0x11,  0x01,  0xF0,  0x11,  0x0F,  0xFE,  0x28,  0xCD,  0xFB,  0x08,  0x83, 	/* 07C40 */
+	0x30,  0xA2,  0x04,  0x0F,  0xFE,  0x97,  0xA5,  0x0A,  0x57,  0x87,  0x08,  0x1F,  0xEF,  0x82,  0x57,  0xC5, 	/* 07C50 */
+	0x24,  0x53,  0x89,  0xC6,  0xA4,  0x04,  0x0F,  0xFE,  0x90,  0x25,  0x7E,  0x51,  0x07,  0x7C,  0x11,  0x4F, 	/* 07C60 */
+	0xFE,  0x50,  0x05,  0x7C,  0x54,  0x49,  0x7C,  0xA5,  0x04,  0x0F,  0xFE,  0x80,  0x2F,  0xBE,  0x29,  0x45, 	/* 07C70 */
+	0xAC,  0x25,  0x00,  0xA0,  0x33,  0x8D,  0xC6,  0x03,  0x03,  0xC0,  0xA6,  0x04,  0x0F,  0xFE,  0x90,  0x29, 	/* 07C80 */
+	0xFA,  0x24,  0x87,  0xFE,  0x20,  0x83,  0xF8,  0x20,  0x83,  0xF8,  0x11,  0x06,  0x0C,  0xA7,  0x04,  0x0F, 	/* 07C90 */
+	0xFE,  0x8C,  0x2A,  0xAA,  0x47,  0xC0,  0x00,  0x7F,  0xC4,  0xA4,  0xFF,  0xE0,  0x40,  0x04,  0x00,  0xC0, 	/* 07CA0 */
+	0xA8,  0x04,  0x0F,  0xFE,  0x91,  0x2B,  0xFA,  0x11,  0x07,  0xFC,  0x25,  0x07,  0xFC,  0x8E,  0x21,  0x50, 	/* 07CB0 */
+	0x64,  0xC0,  0x40,  0xA9,  0x04,  0x0F,  0xFE,  0x87,  0x23,  0xC8,  0x15,  0x0F,  0xFE,  0x0E,  0x03,  0xF8, 	/* 07CC0 */
+	0xE4,  0xE3,  0xF8,  0x24,  0x83,  0xF8,  0xAB,  0x04,  0x0F,  0xFE,  0x88,  0x2B,  0x3A,  0x20,  0x83,  0xB8, 	/* 07CD0 */
+	0x20,  0x83,  0xFE,  0x15,  0x22,  0xAA,  0xCA,  0x21,  0x0C,  0xAE,  0x04,  0x0F,  0xFE,  0x84,  0x2B,  0xFA, 	/* 07CE0 */
+	0x0E,  0x05,  0x14,  0x3F,  0x8D,  0x16,  0x1F,  0x01,  0x58,  0x64,  0x40,  0xC0,  0xB0,  0x04,  0x0F,  0xFE, 	/* 07CF0 */
+	0x80,  0x2B,  0xFA,  0x2A,  0x8F,  0xFE,  0x20,  0x83,  0xF8,  0x08,  0x43,  0x28,  0xDD,  0x83,  0x06,  0xB3, 	/* 07D00 */
+	0x04,  0x0F,  0xFE,  0x82,  0x27,  0xBE,  0x14,  0x87,  0x9C,  0x12,  0xA7,  0xF8,  0x20,  0x83,  0xF8,  0x19, 	/* 07D10 */
+	0x86,  0x04,  0xB5,  0x04,  0x0F,  0xFE,  0x92,  0x27,  0xFC,  0x2A,  0x0F,  0xFC,  0x48,  0x47,  0xBC,  0x4A, 	/* 07D20 */
+	0x07,  0xBC,  0x4A,  0x25,  0x9E,  0xB6,  0x04,  0x0F,  0xFE,  0x91,  0x67,  0xEA,  0x11,  0x07,  0xFE,  0x25, 	/* 07D30 */
+	0x43,  0xFC,  0x20,  0x83,  0xF8,  0x11,  0x86,  0x04,  0xB8,  0x01,  0x00,  0x10,  0x01,  0x0F,  0xFE,  0x01, 	/* 07D40 */
+	0x00,  0x10,  0x21,  0x01,  0x10,  0x11,  0x00,  0x10,  0x01,  0x00,  0x30,  0xBA,  0x04,  0x07,  0xFC,  0x04, 	/* 07D50 */
+	0x00,  0x40,  0xFF,  0xE0,  0x10,  0x7F,  0xE1,  0x10,  0x09,  0x00,  0x90,  0x01,  0x00,  0x30,  0xBE,  0x20, 	/* 07D60 */
+	0x42,  0x04,  0x20,  0x4F,  0xFF,  0x08,  0x44,  0xA4,  0x29,  0x41,  0x14,  0x10,  0x42,  0x84,  0x44,  0x48, 	/* 07D70 */
+	0x0C,  0xBF,  0x04,  0x07,  0xFC,  0x04,  0x03,  0xF8,  0x04,  0x0F,  0xFE,  0x08,  0x8F,  0xFE,  0x10,  0x82, 	/* 07D80 */
+	0x88,  0x44,  0x80,  0x18,  0x81,  0x10,  0x41,  0x04,  0x7C,  0x41,  0x7E,  0x10,  0x4F,  0xE4,  0x11,  0x47, 	/* 07D90 */
+	0xC4,  0x10,  0x41,  0x04,  0x1C,  0x4E,  0x0C,  0x82,  0x04,  0x0F,  0xFE,  0x04,  0x03,  0xF8,  0x24,  0x83, 	/* 07DA0 */
+	0xF8,  0x24,  0x8F,  0xFE,  0x21,  0x01,  0x10,  0x01,  0x00,  0x30,  0x84,  0x20,  0x47,  0x84,  0x48,  0x47, 	/* 07DB0 */
+	0xFE,  0x48,  0x47,  0xA4,  0x4D,  0x4F,  0x94,  0x18,  0x42,  0x84,  0xC8,  0x41,  0x8C,  0x85,  0x20,  0x42, 	/* 07DC0 */
+	0x04,  0xF8,  0x42,  0x7E,  0xF8,  0x48,  0xA4,  0x89,  0x4F,  0x84,  0x50,  0x45,  0x0C,  0x50,  0x18,  0xFF, 	/* 07DD0 */
+	0x86,  0x20,  0xC2,  0xF0,  0xAA,  0x46,  0x54,  0x25,  0x82,  0x08,  0x3F,  0xE6,  0x08,  0xA8,  0x82,  0x48, 	/* 07DE0 */
+	0x20,  0x82,  0x18,  0x87,  0x50,  0xE5,  0x79,  0x51,  0x65,  0x0C,  0x77,  0x81,  0x04,  0xFF,  0xF5,  0x04, 	/* 07DF0 */
+	0x54,  0x45,  0x24,  0x90,  0x41,  0x0C,  0x88,  0x04,  0x0F,  0xFE,  0x24,  0x83,  0xF8,  0x24,  0x83,  0xF8, 	/* 07E00 */
+	0x04,  0x87,  0xFC,  0x01,  0x2F,  0xFE,  0x21,  0x01,  0x30,  0x89,  0x00,  0x47,  0xC4,  0x44,  0x47,  0xFE, 	/* 07E10 */
+	0x40,  0x47,  0xD4,  0x41,  0x47,  0xD4,  0x48,  0x4A,  0xA4,  0xAA,  0x41,  0x8C,  0x8A,  0x11,  0x07,  0xFE, 	/* 07E20 */
+	0x0A,  0x03,  0xFC,  0x2A,  0x43,  0x3C,  0x3F,  0xC0,  0x10,  0xFF,  0xE1,  0x10,  0x09,  0x00,  0x30,  0x8B, 	/* 07E30 */
+	0x3F,  0x80,  0x08,  0x3F,  0x80,  0x08,  0xFF,  0xE2,  0x22,  0xFB,  0xE0,  0x10,  0xFF,  0xE1,  0x10,  0x09, 	/* 07E40 */
+	0x00,  0x30,  0x8D,  0x2A,  0x4A,  0xA4,  0x6C,  0x4F,  0xFF,  0x44,  0x42,  0x84,  0x7D,  0x41,  0x0C,  0x7C, 	/* 07E50 */
+	0x41,  0x04,  0x1C,  0x4E,  0x0C,  0x8E,  0x44,  0x82,  0xFC,  0x02,  0x0E,  0x7C,  0x24,  0x42,  0x7C,  0x5C, 	/* 07E60 */
+	0x48,  0xFE,  0x01,  0x0F,  0xFE,  0x11,  0x00,  0x30,  0x8F,  0x04,  0x00,  0x40,  0x04,  0x00,  0x50,  0x24, 	/* 07E70 */
+	0x82,  0x44,  0x44,  0x44,  0x42,  0x84,  0x20,  0x40,  0x04,  0x00,  0xC0,  0x91,  0x04,  0x00,  0x40,  0x05, 	/* 07E80 */
+	0x02,  0x48,  0x24,  0x42,  0x42,  0x44,  0xA8,  0xC8,  0x01,  0x00,  0x20,  0x0C,  0x03,  0x00,  0x93,  0x10, 	/* 07E90 */
+	0x01,  0x00,  0x10,  0x01,  0xFE,  0x22,  0x04,  0x20,  0x12,  0x81,  0x24,  0x22,  0x24,  0x22,  0x02,  0x00, 	/* 07EA0 */
+	0x60,  0x96,  0x04,  0x01,  0x50,  0x14,  0x82,  0x44,  0x44,  0x40,  0xC0,  0x04,  0x0F,  0xFE,  0x04,  0x00, 	/* 07EB0 */
+	0xA0,  0x31,  0x8C,  0x06,  0x9A,  0x04,  0x04,  0x44,  0x24,  0x42,  0x48,  0xFF,  0xE8,  0x02,  0x9F,  0x29, 	/* 07EC0 */
+	0x12,  0x91,  0x29,  0xF2,  0x80,  0x28,  0x06,  0xA0,  0x48,  0x8F,  0xC8,  0x4A,  0xC7,  0xAA,  0x4A,  0xA7, 	/* 07ED0 */
+	0xC9,  0x48,  0xAF,  0xDA,  0xA8,  0x4C,  0xC8,  0x83,  0x07,  0xC0,  0xA2,  0x08,  0x00,  0x80,  0x08,  0x0F, 	/* 07EE0 */
+	0xFE,  0x0A,  0x00,  0xA0,  0x0A,  0x00,  0xA0,  0x12,  0x01,  0x22,  0x22,  0x2C,  0x1E,  0xA4,  0x04,  0x80, 	/* 07EF0 */
+	0x44,  0x04,  0x07,  0xFE,  0x04,  0x00,  0x60,  0x06,  0x00,  0xA0,  0x0A,  0x01,  0x22,  0x22,  0x24,  0x1E, 	/* 07F00 */
+	0xA8,  0x20,  0x82,  0x88,  0x25,  0x0F,  0xD4,  0x2A,  0x42,  0x88,  0x29,  0x22,  0xA2,  0x28,  0x44,  0x88, 	/* 07F10 */
+	0x49,  0x28,  0x7E,  0xAD,  0x04,  0x07,  0xF8,  0x04,  0x02,  0x50,  0xFF,  0xC2,  0x10,  0x00,  0x0F,  0xFE, 	/* 07F20 */
+	0x12,  0x01,  0x24,  0x22,  0x4C,  0x1C,  0xB1,  0x21,  0x0F,  0xD4,  0x01,  0x27,  0xFE,  0x49,  0x04,  0x90, 	/* 07F30 */
+	0x7B,  0x02,  0x30,  0x6B,  0x0A,  0x52,  0x29,  0x26,  0x0E,  0xB8,  0x00,  0x03,  0xFE,  0x20,  0x22,  0x02, 	/* 07F40 */
+	0x3F,  0xE2,  0x00,  0x20,  0x02,  0x00,  0x20,  0x04,  0x00,  0x40,  0x08,  0x00,  0xB9,  0x00,  0x07,  0xFC, 	/* 07F50 */
+	0x04,  0x40,  0x44,  0xFF,  0xF0,  0x44,  0x04,  0x47,  0xFC,  0x04,  0x00,  0x80,  0x08,  0x01,  0x00,  0xBA, 	/* 07F60 */
+	0x00,  0x01,  0xFC,  0x10,  0x41,  0x04,  0x10,  0x41,  0xFC,  0x14,  0x01,  0x40,  0x22,  0x02,  0x10,  0x40, 	/* 07F70 */
+	0x88,  0x06,  0xBB,  0x00,  0x07,  0xFC,  0x40,  0x44,  0x04,  0x7F,  0xC4,  0x40,  0x7F,  0x84,  0x48,  0x44, 	/* 07F80 */
+	0x84,  0x4A,  0x88,  0xA1,  0x06,  0xBC,  0x00,  0x03,  0xFC,  0x20,  0x42,  0x04,  0x3F,  0xC2,  0x80,  0x28, 	/* 07F90 */
+	0xC2,  0xF0,  0x28,  0x04,  0x82,  0x48,  0x28,  0x7E,  0xBD,  0x3F,  0x82,  0x08,  0x20,  0x83,  0xF8,  0x21, 	/* 07FA0 */
+	0x02,  0x10,  0x2C,  0x84,  0x34,  0x40,  0x29,  0xC0,  0x03,  0x00,  0x08,  0xBE,  0x00,  0x03,  0xFC,  0x20, 	/* 07FB0 */
+	0x43,  0xFC,  0x23,  0x82,  0xE0,  0x23,  0xC3,  0xE0,  0x23,  0xE7,  0xE0,  0x42,  0x28,  0x1E,  0xBF,  0x00, 	/* 07FC0 */
+	0x07,  0xFC,  0x40,  0x44,  0x04,  0x7F,  0xC4,  0x24,  0x7A,  0x84,  0xB0,  0x4B,  0x09,  0x28,  0xA2,  0x60, 	/* 07FD0 */
+	0x60,  0x80,  0x00,  0x03,  0xFC,  0x20,  0x43,  0xFC,  0x20,  0x03,  0xFE,  0x20,  0x22,  0xF2,  0x49,  0x24, 	/* 07FE0 */
+	0x92,  0x8F,  0x20,  0x0C,  0x81,  0x00,  0x03,  0xFE,  0x20,  0x22,  0x02,  0x3F,  0xE2,  0x90,  0x29,  0x22, 	/* 07FF0 */
+	0xF4,  0x49,  0x84,  0x92,  0x9F,  0x23,  0x0E,  0x85,  0x00,  0x03,  0xFC,  0x20,  0x43,  0xFC,  0x22,  0x03, 	/* 08000 */
+	0xFE,  0x22,  0x02,  0x20,  0x5F,  0xC5,  0x04,  0x90,  0x41,  0xFC,  0x86,  0x00,  0x07,  0xFE,  0x40,  0x27, 	/* 08010 */
+	0xFE,  0x42,  0x05,  0x22,  0x5F,  0xE5,  0x22,  0x52,  0x29,  0xFA,  0x90,  0x21,  0xFE,  0x88,  0x00,  0x07, 	/* 08020 */
+	0xFE,  0x40,  0x27,  0xFE,  0x42,  0x05,  0x24,  0x52,  0x45,  0xFC,  0x42,  0x06,  0x22,  0xA2,  0x23,  0xFE, 	/* 08030 */
+	0x8A,  0x00,  0x03,  0xFE,  0x20,  0x23,  0xFE,  0x22,  0x03,  0xFE,  0x32,  0x23,  0x22,  0x5F,  0xE5,  0x22, 	/* 08040 */
+	0x92,  0x21,  0xFE,  0x8B,  0x3F,  0xC2,  0x04,  0x3F,  0xC2,  0x00,  0x3F,  0xE2,  0x50,  0x28,  0xC3,  0xF2, 	/* 08050 */
+	0x42,  0x05,  0xFC,  0x82,  0x07,  0xFE,  0x8D,  0x00,  0x07,  0xFE,  0x40,  0x27,  0xFE,  0x40,  0x07,  0xFE, 	/* 08060 */
+	0x5D,  0x06,  0x56,  0x55,  0x88,  0x92,  0x11,  0x26,  0x0E,  0x8E,  0x00,  0x07,  0xFE,  0x40,  0x27,  0xFE, 	/* 08070 */
+	0x42,  0x05,  0x24,  0x4A,  0x87,  0xFE,  0x47,  0x04,  0xA8,  0x92,  0x68,  0x20,  0x8F,  0x00,  0x07,  0xFC, 	/* 08080 */
+	0x40,  0x47,  0xFC,  0x50,  0x87,  0xFC,  0x49,  0x04,  0x90,  0x7F,  0xE8,  0x90,  0x91,  0x02,  0x10,  0x90, 	/* 08090 */
+	0x00,  0x07,  0xFC,  0x40,  0x47,  0xFC,  0x48,  0x85,  0x3E,  0x68,  0x84,  0xFE,  0x52,  0x4B,  0x18,  0x92, 	/* 080A0 */
+	0x41,  0xC2,  0x91,  0x7F,  0xE4,  0x02,  0x7F,  0xE5,  0x24,  0x4A,  0x85,  0xFC,  0x50,  0x45,  0xFC,  0x50, 	/* 080B0 */
+	0x45,  0xFC,  0x90,  0x41,  0x0C,  0x93,  0x00,  0x07,  0xFE,  0x40,  0x27,  0xFE,  0x50,  0x45,  0xFC,  0x50, 	/* 080C0 */
+	0x45,  0xFC,  0x50,  0x49,  0xFC,  0x8C,  0xC3,  0x02,  0x95,  0x00,  0x07,  0xFC,  0x40,  0x47,  0xFC,  0x49, 	/* 080D0 */
+	0x05,  0xFC,  0x49,  0x07,  0xFC,  0x4A,  0x28,  0x94,  0x8E,  0x83,  0x06,  0x9E,  0x3F,  0xC2,  0x04,  0x3F, 	/* 080E0 */
+	0xE2,  0xF8,  0x3A,  0x82,  0xF8,  0x22,  0x03,  0xFE,  0x62,  0xA6,  0x7E,  0xB8,  0x22,  0x06,  0xA0,  0x3F, 	/* 080F0 */
+	0xE2,  0x02,  0x3F,  0xE2,  0x20,  0x2F,  0xC2,  0x28,  0x3F,  0xF2,  0x7C,  0x4C,  0x45,  0x7C,  0xA4,  0x40, 	/* 08100 */
+	0x7C,  0xA1,  0x00,  0x07,  0xFC,  0x40,  0x47,  0xFC,  0x4A,  0x87,  0xFE,  0x4F,  0x85,  0x24,  0x7F,  0xE9, 	/* 08110 */
+	0x90,  0x87,  0x03,  0x8C,  0xA4,  0x7F,  0xE4,  0x02,  0x7F,  0xE5,  0x24,  0x5F,  0xC5,  0x24,  0x5F,  0xC4, 	/* 08120 */
+	0xF8,  0x48,  0x88,  0xF8,  0x88,  0x80,  0xF8,  0xA5,  0x00,  0x07,  0xFC,  0x40,  0x47,  0xFC,  0x52,  0x06, 	/* 08130 */
+	0xBE,  0x56,  0x47,  0xBC,  0x51,  0xC5,  0x64,  0x51,  0x89,  0xE6,  0xAC,  0x00,  0x07,  0xFC,  0x40,  0x47, 	/* 08140 */
+	0xFC,  0x42,  0x07,  0x2E,  0x5F,  0xC5,  0x54,  0x7F,  0xE9,  0xF2,  0x85,  0x23,  0xEC,  0xAE,  0x04,  0x00, 	/* 08150 */
+	0x40,  0x44,  0x44,  0x44,  0x44,  0x44,  0x44,  0x44,  0x47,  0xFC,  0x48,  0x00,  0x80,  0x10,  0x02,  0x00, 	/* 08160 */
+	0xAF,  0x04,  0x00,  0x5C,  0xFE,  0x00,  0x40,  0x44,  0x44,  0x44,  0x44,  0x47,  0xFC,  0x44,  0x00,  0x42, 	/* 08170 */
+	0x04,  0x20,  0x3E,  0xB1,  0x04,  0x00,  0x40,  0x04,  0x00,  0x40,  0x04,  0x04,  0x44,  0x44,  0x44,  0x44, 	/* 08180 */
+	0x44,  0x44,  0x44,  0x7F,  0xC4,  0x04,  0xB6,  0x04,  0x04,  0x44,  0x44,  0x47,  0xFC,  0x00,  0x0F,  0xFE, 	/* 08190 */
+	0x04,  0x20,  0x42,  0x04,  0x20,  0x82,  0x30,  0x2C,  0x0C,  0xB9,  0x22,  0x02,  0x20,  0xAB,  0xFA,  0xC0, 	/* 081A0 */
+	0xAB,  0xCA,  0x84,  0xA8,  0x8A,  0x90,  0xA9,  0x0F,  0xA2,  0x02,  0x20,  0x1E,  0x8C,  0x04,  0x04,  0x44, 	/* 081B0 */
+	0x7F,  0xC0,  0x00,  0x7F,  0x80,  0x90,  0x09,  0x01,  0xFC,  0x14,  0x82,  0x30,  0x46,  0x89,  0x86,  0x90, 	/* 081C0 */
+	0x01,  0x02,  0x10,  0x2F,  0xEA,  0x90,  0xA9,  0x0A,  0xFE,  0xAA,  0x4A,  0xA4,  0xA9,  0x8F,  0x88,  0x03, 	/* 081D0 */
+	0x40,  0xC2,  0x91,  0x04,  0x04,  0x44,  0x7F,  0xC0,  0x40,  0x0A,  0x03,  0x18,  0xDF,  0x60,  0x00,  0x3F, 	/* 081E0 */
+	0x80,  0x10,  0x02,  0x00,  0x40,  0x94,  0x0A,  0x01,  0x10,  0x20,  0x8D,  0xFE,  0x08,  0x81,  0x08,  0x63, 	/* 081F0 */
+	0x00,  0x40,  0x44,  0x44,  0x44,  0x44,  0x47,  0xFC,  0xA1,  0x00,  0x0F,  0xFE,  0x91,  0x28,  0x92,  0x8A, 	/* 08200 */
+	0x2F,  0xFE,  0x84,  0x2A,  0x4A,  0xA4,  0xAB,  0xFA,  0x80,  0x28,  0x06,  0xA8,  0x20,  0x02,  0x3C,  0xAA, 	/* 08210 */
+	0x4A,  0xA4,  0xAB,  0xCA,  0xA4,  0xAA,  0x4A,  0xBC,  0xAA,  0x4F,  0xA4,  0x8A,  0x40,  0x7E,  0xA9,  0x04, 	/* 08220 */
+	0x04,  0x44,  0x44,  0x47,  0xFC,  0x00,  0x0F,  0xFE,  0x10,  0x01,  0x00,  0x3F,  0xC5,  0x04,  0x90,  0x41, 	/* 08230 */
+	0xFC,  0xAB,  0x21,  0x02,  0x10,  0xA9,  0x0A,  0xFE,  0xAD,  0x2A,  0xD2,  0xAD,  0x2A,  0xFE,  0xFD,  0x28, 	/* 08240 */
+	0x52,  0x05,  0x20,  0x7E,  0xAC,  0x20,  0x02,  0xFE,  0x29,  0x2A,  0xFE,  0xA9,  0x2A,  0x92,  0xAF,  0xEA, 	/* 08250 */
+	0x90,  0xF9,  0x08,  0x10,  0x01,  0x00,  0x10,  0xB1,  0x22,  0x82,  0x24,  0x43,  0xED,  0xE0,  0x41,  0x04, 	/* 08260 */
+	0x0A,  0x44,  0x60,  0x40,  0x44,  0x44,  0x44,  0x44,  0x47,  0xFC,  0xB3,  0x01,  0x83,  0xE0,  0x20,  0x03, 	/* 08270 */
+	0xFC,  0x21,  0x02,  0x10,  0xFF,  0xE0,  0x40,  0x44,  0x44,  0x44,  0x44,  0x47,  0xFC,  0xB6,  0x20,  0x82, 	/* 08280 */
+	0x08,  0xA9,  0x0A,  0xBE,  0xAA,  0x2A,  0xA2,  0xAA,  0x2A,  0xBE,  0xAA,  0x2F,  0xA2,  0x02,  0x20,  0x3E, 	/* 08290 */
+	0xB7,  0x20,  0x02,  0x3E,  0xAA,  0x2A,  0xA2,  0xAB,  0xEA,  0xA8,  0xAB,  0xEA,  0xA8,  0xAA,  0xAF,  0xA6, 	/* 082A0 */
+	0x03,  0x60,  0xC2,  0xB8,  0x44,  0x44,  0x44,  0x7F,  0xC0,  0x00,  0x7F,  0xE4,  0x00,  0x5F,  0xC4,  0x20, 	/* 082B0 */
+	0x7F,  0xE4,  0x20,  0x82,  0x00,  0x20,  0xBB,  0x20,  0xC2,  0x38,  0xAA,  0x8A,  0xA8,  0xAA,  0x8A,  0xBE, 	/* 082C0 */
+	0xAA,  0x8A,  0xA8,  0xFA,  0xA0,  0xF6,  0x00,  0x60,  0xF2,  0xBC,  0x20,  0x02,  0x7E,  0xA8,  0x8A,  0xAC, 	/* 082D0 */
+	0xAC,  0xAA,  0x88,  0xAF,  0xFA,  0x88,  0xA8,  0x8F,  0x88,  0x00,  0x80,  0x08,  0xBE,  0x21,  0x02,  0x10, 	/* 082E0 */
+	0x21,  0x0A,  0x9E,  0xA9,  0x0A,  0x90,  0xA9,  0x0A,  0xFE,  0xAC,  0x2F,  0xC2,  0x04,  0x20,  0x7E,  0x85, 	/* 082F0 */
+	0x21,  0x02,  0x24,  0xAF,  0xEA,  0xA4,  0xAA,  0x4A,  0xA4,  0xAF,  0xFA,  0xA4,  0xFA,  0x40,  0x44,  0x04, 	/* 08300 */
+	0x40,  0x84,  0x87,  0x04,  0x04,  0x44,  0x44,  0x47,  0xFC,  0x0A,  0x01,  0x10,  0x3F,  0x8C,  0x06,  0x3F, 	/* 08310 */
+	0x82,  0x08,  0x20,  0x83,  0xF8,  0x99,  0x21,  0x02,  0x10,  0x27,  0xCA,  0x90,  0xAF,  0xEA,  0x88,  0xAF, 	/* 08320 */
+	0xEA,  0x88,  0xAC,  0x8F,  0xA8,  0x00,  0x80,  0x18,  0xA0,  0x21,  0x02,  0x10,  0xA9,  0xCA,  0x90,  0xAF, 	/* 08330 */
+	0xEA,  0x80,  0xAF,  0xEA,  0x90,  0xF9,  0xC8,  0x12,  0x01,  0x00,  0x10,  0xA1,  0x01,  0x02,  0x10,  0x2F, 	/* 08340 */
+	0xE2,  0x12,  0xAD,  0x4A,  0xB8,  0xAF,  0xEA,  0x90,  0xA9,  0x0F,  0xA8,  0x04,  0x41,  0x82,  0xA8,  0x02, 	/* 08350 */
+	0x82,  0xCC,  0x24,  0xA2,  0x48,  0x2F,  0xEA,  0xC8,  0xAE,  0xAA,  0xCA,  0xAC,  0x4F,  0xCC,  0x05,  0x60, 	/* 08360 */
+	0xC2,  0xA9,  0x04,  0x04,  0x44,  0x7F,  0xC0,  0xD0,  0x71,  0x41,  0x12,  0xFF,  0xE1,  0x14,  0x1D,  0x4F, 	/* 08370 */
+	0x0A,  0x11,  0x63,  0x22,  0xAA,  0x22,  0x82,  0x24,  0xAD,  0x4A,  0x92,  0xAA,  0x8A,  0xA4,  0xAF,  0xEA, 	/* 08380 */
+	0xA5,  0xAA,  0x4F,  0xA4,  0x02,  0x40,  0x3C,  0xAD,  0x20,  0x82,  0x2C,  0xAA,  0xAA,  0xC9,  0xAB,  0xFA, 	/* 08390 */
+	0xA2,  0xAB,  0xEA,  0xA2,  0xAB,  0xEF,  0xA2,  0x02,  0x20,  0x26,  0xAF,  0x04,  0x04,  0x44,  0x7F,  0xC0, 	/* 083A0 */
+	0xF0,  0x71,  0x00,  0xE0,  0x31,  0x8C,  0x46,  0x7F,  0xC0,  0x40,  0xFF,  0xE0,  0x40,  0xB0,  0x22,  0x02, 	/* 083B0 */
+	0x3C,  0xA4,  0x4A,  0xB8,  0xAA,  0x8A,  0xD4,  0xA9,  0x3A,  0xFC,  0xF9,  0x00,  0xFE,  0x01,  0x00,  0x10, 	/* 083C0 */
+	0xB6,  0x08,  0x03,  0xF8,  0x20,  0x83,  0xF8,  0x20,  0x83,  0xFE,  0x20,  0x03,  0xFE,  0x08,  0x24,  0x92, 	/* 083D0 */
+	0x7F,  0x20,  0x0C,  0xBA,  0x20,  0x02,  0xFF,  0xA8,  0x8A,  0xBE,  0xAA,  0xAA,  0xBE,  0xAA,  0xAA,  0xBE, 	/* 083E0 */
+	0xAA,  0x8F,  0x90,  0x02,  0xC0,  0xC3,  0xBB,  0x21,  0x02,  0x24,  0xAF,  0xAA,  0xA8,  0xAA,  0xAA,  0xC6, 	/* 083F0 */
+	0xA9,  0x0A,  0xBC,  0xFE,  0x40,  0x18,  0x06,  0x81,  0x86,  0xBD,  0x21,  0x02,  0x10,  0x27,  0xEA,  0xD4, 	/* 08400 */
+	0xAD,  0x4A,  0xBA,  0xA9,  0x2A,  0x90,  0xAA,  0x8F,  0xA4,  0x04,  0x21,  0x81,  0x87,  0x44,  0x47,  0xFC, 	/* 08410 */
+	0x04,  0x0F,  0xFE,  0x80,  0x23,  0xF8,  0x00,  0x0F,  0xFE,  0x04,  0x02,  0x58,  0xC4,  0x60,  0xC0,  0x8B, 	/* 08420 */
+	0x04,  0x04,  0x44,  0x7F,  0xC0,  0x00,  0x7F,  0xC2,  0x48,  0xFF,  0xE2,  0x48,  0x7F,  0xC0,  0x40,  0x7F, 	/* 08430 */
+	0xC0,  0x40,  0x8E,  0x21,  0x02,  0xFE,  0x21,  0x0A,  0xA8,  0xAC,  0x4A,  0xFE,  0xA8,  0x4A,  0xF4,  0xFD, 	/* 08440 */
+	0x48,  0x74,  0x00,  0x40,  0x0C,  0x91,  0x04,  0x04,  0x44,  0x7F,  0xC2,  0x08,  0x3F,  0x82,  0x08,  0x3F, 	/* 08450 */
+	0x82,  0x20,  0x3A,  0x42,  0x38,  0x3E,  0x2E,  0x1E,  0x94,  0x04,  0x04,  0x44,  0x7F,  0xC1,  0x10,  0x12, 	/* 08460 */
+	0x03,  0xFE,  0x62,  0x0B,  0xFC,  0x22,  0x03,  0xFC,  0x22,  0x03,  0xFE,  0x95,  0x20,  0x02,  0xFE,  0xA9, 	/* 08470 */
+	0x0A,  0xFC,  0xA9,  0x0A,  0xFE,  0xA9,  0x0A,  0x90,  0xFF,  0xC1,  0x10,  0x11,  0x02,  0xFE,  0x96,  0x44, 	/* 08480 */
+	0x47,  0xFC,  0x00,  0x07,  0xFE,  0x42,  0x05,  0xFC,  0x42,  0x07,  0xFE,  0x42,  0x05,  0xFC,  0x82,  0x03, 	/* 08490 */
+	0xFE,  0x97,  0x44,  0x44,  0x44,  0x7F,  0xC0,  0x00,  0xFF,  0xE9,  0x12,  0xBF,  0xA8,  0x42,  0xA4,  0xAA, 	/* 084A0 */
+	0x4A,  0xBF,  0xA8,  0x06,  0x98,  0x21,  0x02,  0x28,  0xAC,  0x4A,  0x82,  0xAF,  0xDA,  0x80,  0xAF,  0xEA, 	/* 084B0 */
+	0xAA,  0xAF,  0xEF,  0xAA,  0x0A,  0xA0,  0x86,  0x99,  0x04,  0x04,  0x44,  0x7F,  0xC0,  0xA0,  0x11,  0x03, 	/* 084C0 */
+	0xF8,  0xC0,  0x67,  0xFC,  0x4A,  0x47,  0xFC,  0x4A,  0x44,  0xAC,  0x9A,  0x21,  0x02,  0x7C,  0xA9,  0x0A, 	/* 084D0 */
+	0xFE,  0xAA,  0x8A,  0xAA,  0xAD,  0x6A,  0xBC,  0xFE,  0x40,  0x98,  0x06,  0x81,  0x86,  0x9B,  0x20,  0x02, 	/* 084E0 */
+	0xFE,  0xA8,  0x2A,  0xFE,  0xA9,  0x0A,  0xD4,  0xAD,  0x4A,  0xFC,  0xF9,  0x21,  0x92,  0x19,  0x22,  0xFE, 	/* 084F0 */
+	0x9F,  0x04,  0x04,  0x44,  0x44,  0x47,  0xFC,  0x0A,  0x01,  0x10,  0x3F,  0x8C,  0x46,  0x7F,  0xC2,  0x48, 	/* 08500 */
+	0x15,  0x0F,  0xFE,  0xA2,  0x20,  0xC2,  0x74,  0xAD,  0x2A,  0x92,  0xAB,  0xCA,  0x94,  0xAF,  0xEA,  0x94, 	/* 08510 */
+	0xAF,  0xCF,  0x90,  0x01,  0x00,  0x30,  0xA9,  0x04,  0x04,  0x44,  0x7F,  0xC0,  0x00,  0x79,  0xE4,  0x92, 	/* 08520 */
+	0x79,  0xE4,  0x92,  0x79,  0xE4,  0x92,  0x49,  0x29,  0xA6,  0x8B,  0x20,  0x02,  0xFE,  0xA9,  0x2A,  0xFE, 	/* 08530 */
+	0xA8,  0x0A,  0xBE,  0xAA,  0x2A,  0xBE,  0xFA,  0x20,  0xBE,  0x12,  0x22,  0x3E,  0x8C,  0x04,  0x04,  0x44, 	/* 08540 */
+	0x44,  0x47,  0xFC,  0x49,  0x04,  0x9E,  0xFD,  0xA4,  0xAC,  0x78,  0x84,  0x94,  0x4A,  0x47,  0xC2,  0x8E, 	/* 08550 */
+	0x20,  0x02,  0xFC,  0x2A,  0x4A,  0xFC,  0xAA,  0x4A,  0xFC,  0xAA,  0x0A,  0xFE,  0xAA,  0xAF,  0xF6,  0x08, 	/* 08560 */
+	0x20,  0x86,  0x90,  0x44,  0x44,  0x44,  0x7F,  0xC4,  0x34,  0x7C,  0x45,  0xF4,  0x55,  0x45,  0xF4,  0x46, 	/* 08570 */
+	0x44,  0x55,  0xBF,  0xB8,  0x09,  0x92,  0x00,  0x01,  0xF0,  0x11,  0x01,  0x10,  0xFF,  0xE8,  0xA2,  0xFB, 	/* 08580 */
+	0xE0,  0x40,  0x44,  0x44,  0x44,  0x44,  0x47,  0xFC,  0x9C,  0x44,  0x44,  0x44,  0x7F,  0xC0,  0x40,  0x7F, 	/* 08590 */
+	0xC1,  0x10,  0x0A,  0x0F,  0xFE,  0x3E,  0x42,  0x24,  0x3E,  0x40,  0x0C,  0xA9,  0x24,  0x43,  0xFC,  0x04, 	/* 085A0 */
+	0x0F,  0xFF,  0x10,  0x81,  0xF8,  0x00,  0x07,  0xFE,  0x4F,  0x24,  0x92,  0x4F,  0x24,  0x06,  0xAC,  0x04, 	/* 085B0 */
+	0x08,  0x42,  0xFF,  0xE0,  0x80,  0x3F,  0x82,  0x48,  0x3F,  0x82,  0x4C,  0x3F,  0xA0,  0xAE,  0x32,  0x2C, 	/* 085C0 */
+	0x1E,  0xAF,  0x24,  0x42,  0x28,  0xAF,  0xEA,  0x90,  0xAF,  0xCA,  0x90,  0xAF,  0xEA,  0xA0,  0xFF,  0xE8, 	/* 085D0 */
+	0x90,  0x11,  0x02,  0xFE,  0xB3,  0x04,  0x04,  0x44,  0x7F,  0xC1,  0x10,  0x7F,  0xC0,  0x40,  0x3F,  0x80, 	/* 085E0 */
+	0x40,  0xFF,  0xE2,  0xF8,  0x42,  0x0B,  0xFC,  0xB6,  0x20,  0x02,  0xEE,  0x22,  0x2A,  0xEE,  0xA8,  0x8A, 	/* 085F0 */
+	0xEE,  0xAE,  0x6A,  0xAA,  0xAE,  0x6F,  0xAA,  0x02,  0x20,  0xCC,  0x82,  0x21,  0x02,  0x7E,  0xAA,  0x8A, 	/* 08600 */
+	0xFE,  0xAC,  0x4A,  0xFC,  0xAC,  0x4A,  0xFC,  0xF9,  0x00,  0xFE,  0x01,  0x00,  0x10,  0x84,  0x04,  0x04, 	/* 08610 */
+	0x44,  0x7F,  0xC1,  0x02,  0xFF,  0xC5,  0x50,  0x7D,  0xE5,  0x54,  0x7D,  0x41,  0x24,  0xFE,  0x41,  0x44, 	/* 08620 */
+	0x87,  0x20,  0x02,  0xFE,  0xAB,  0x8A,  0xA8,  0xAB,  0x8A,  0x80,  0xAF,  0xEA,  0xDA,  0xAD,  0xAF,  0xFE, 	/* 08630 */
+	0x08,  0x00,  0xFE,  0x8B,  0x01,  0x02,  0x3C,  0x22,  0x4A,  0xBC,  0xAA,  0x4A,  0xBE,  0xAA,  0x0A,  0xBE, 	/* 08640 */
+	0xF8,  0x20,  0x56,  0x05,  0x20,  0x8C,  0x8C,  0x04,  0x04,  0x44,  0x7F,  0xC2,  0x08,  0x3F,  0x82,  0x08, 	/* 08650 */
+	0x3F,  0xE2,  0x00,  0x3F,  0xE4,  0xA2,  0x55,  0x28,  0x0C,  0x90,  0x04,  0x04,  0x44,  0x7F,  0xCE,  0x7C, 	/* 08660 */
+	0xBC,  0x8A,  0x38,  0xCD,  0x6B,  0x7C,  0xA9,  0x0A,  0xFC,  0xE1,  0x09,  0xFE,  0x9D,  0x23,  0x02,  0x54, 	/* 08670 */
+	0xAA,  0xAA,  0xC4,  0xAB,  0xAA,  0x81,  0xAF,  0xCA,  0xC4,  0xAF,  0xCF,  0xC4,  0x02,  0x81,  0xFE,  0xA2, 	/* 08680 */
+	0x21,  0x02,  0x7C,  0xA9,  0x0A,  0xFE,  0xAA,  0x4A,  0xFE,  0xAA,  0x4A,  0xFE,  0xF8,  0x00,  0xFE,  0x02, 	/* 08690 */
+	0xA1,  0xCE,  0xAC,  0x22,  0x82,  0xFE,  0xA1,  0x0A,  0xFC,  0xA9,  0x0A,  0xFE,  0xA9,  0x4A,  0xFE,  0xFC, 	/* 086A0 */
+	0xA1,  0x64,  0x04,  0xD0,  0xD3,  0xAE,  0x21,  0x02,  0x18,  0xAA,  0x4A,  0xFE,  0xA8,  0x1A,  0xFE,  0xAD, 	/* 086B0 */
+	0xAA,  0xFE,  0xFC,  0x80,  0x48,  0x0B,  0x41,  0x22,  0xB7,  0x04,  0x04,  0x42,  0x7F,  0xE4,  0xBE,  0x71, 	/* 086C0 */
+	0x44,  0x48,  0x7F,  0xE9,  0x08,  0xFE,  0xE1,  0x38,  0x2A,  0xC4,  0x43,  0xBA,  0x44,  0x44,  0x44,  0x7F, 	/* 086D0 */
+	0xC2,  0x3E,  0x31,  0x04,  0xBE,  0x7A,  0x2A,  0xBE,  0x2A,  0x23,  0x3E,  0x21,  0x42,  0x63,  0xBC,  0x22, 	/* 086E0 */
+	0x02,  0xFE,  0x2A,  0x2A,  0xA2,  0xAF,  0xEA,  0x8A,  0xAA,  0xAA,  0xEE,  0xFA,  0xA1,  0xFF,  0x02,  0x80, 	/* 086F0 */
+	0xC4,  0xBD,  0x04,  0x04,  0x44,  0x7F,  0xC8,  0x4C,  0x54,  0xA3,  0xE8,  0x61,  0xEA,  0xE8,  0x30,  0x8E, 	/* 08700 */
+	0xF4,  0x2B,  0x4C,  0xE2,  0x89,  0x23,  0x82,  0x50,  0xAF,  0xCA,  0xC4,  0xAF,  0xEA,  0xA4,  0xAF,  0x6A, 	/* 08710 */
+	0xFC,  0xAD,  0x4F,  0xFC,  0x02,  0xA0,  0xCE,  0x8C,  0x44,  0x47,  0xFC,  0x02,  0x07,  0xFE,  0x5D,  0x04, 	/* 08720 */
+	0x9F,  0x7E,  0x25,  0x6A,  0x5C,  0xC5,  0x44,  0xBC,  0xA8,  0x72,  0x8D,  0x04,  0x04,  0x44,  0x7F,  0xC7, 	/* 08730 */
+	0x90,  0x27,  0xCF,  0xD4,  0x77,  0xCA,  0xD4,  0xFF,  0xC5,  0x18,  0x32,  0xAC,  0xCE,  0x92,  0x44,  0x4A, 	/* 08740 */
+	0xEA,  0x40,  0x4A,  0xEA,  0xF1,  0xE2,  0xE4,  0x7A,  0xEA,  0xF5,  0x04,  0x04,  0x44,  0x44,  0x47,  0xFC, 	/* 08750 */
+	0x93,  0x44,  0x47,  0xFC,  0x43,  0xE7,  0xC8,  0xAB,  0xEB,  0xA2,  0xAB,  0xEB,  0xBE,  0xAA,  0x2F,  0xFE, 	/* 08760 */
+	0x51,  0x48,  0xA2,  0x96,  0x44,  0x47,  0xFC,  0x3B,  0x82,  0xA8,  0x7F,  0xE5,  0xD0,  0x4B,  0xF7,  0xD4, 	/* 08770 */
+	0x5F,  0x45,  0x48,  0x7D,  0x48,  0x62,  0x9B,  0x12,  0x41,  0x24,  0x24,  0x82,  0x48,  0x49,  0x09,  0x20, 	/* 08780 */
+	0x49,  0x02,  0x48,  0x24,  0x81,  0x24,  0x12,  0x41,  0x24,  0x9D,  0x20,  0x22,  0x22,  0x22,  0x22,  0x22, 	/* 08790 */
+	0x22,  0x22,  0x22,  0x22,  0x22,  0x22,  0x22,  0x24,  0x22,  0x40,  0x28,  0x02,  0x9E,  0x10,  0x21,  0x22, 	/* 087A0 */
+	0x12,  0x21,  0x22,  0x5B,  0x25,  0x6A,  0x96,  0xA1,  0x22,  0x12,  0x22,  0x22,  0x20,  0x24,  0x02,  0xA1, 	/* 087B0 */
+	0x05,  0x24,  0x52,  0x25,  0x20,  0xA4,  0x0A,  0x4F,  0x48,  0x2A,  0x42,  0xA2,  0x25,  0x22,  0x52,  0x58, 	/* 087C0 */
+	0x08,  0x7F,  0xA3,  0x28,  0x81,  0x50,  0x7F,  0xC4,  0x44,  0x7F,  0xC4,  0x44,  0x7F,  0xC0,  0x40,  0xFF, 	/* 087D0 */
+	0xE1,  0xF0,  0xE4,  0xE0,  0x40,  0xA5,  0x00,  0x00,  0x00,  0x7F,  0xC0,  0x40,  0x04,  0x00,  0x40,  0x04, 	/* 087E0 */
+	0x00,  0x40,  0x04,  0x00,  0x40,  0xFF,  0xE0,  0x00,  0xA6,  0x08,  0x00,  0x80,  0x08,  0x0F,  0xFE,  0x08, 	/* 087F0 */
+	0x00,  0x80,  0x10,  0x01,  0xFC,  0x22,  0x04,  0x20,  0x82,  0x03,  0xFE,  0xA7,  0x00,  0x00,  0xFE,  0xFA, 	/* 08800 */
+	0x02,  0x20,  0x22,  0x02,  0x3E,  0x24,  0x22,  0x02,  0x38,  0x2C,  0x02,  0x00,  0x20,  0x0C,  0xA8,  0x00, 	/* 08810 */
+	0x07,  0xFE,  0x40,  0x04,  0x00,  0x7F,  0xC4,  0x04,  0x40,  0x47,  0xFC,  0x40,  0x04,  0x00,  0x40,  0x07, 	/* 08820 */
+	0xFE,  0xAB,  0x00,  0x07,  0xFC,  0x04,  0x02,  0x48,  0x24,  0x82,  0x48,  0x24,  0x85,  0x54,  0x4E,  0x28, 	/* 08830 */
+	0x42,  0x04,  0x0F,  0xFF,  0xAE,  0x11,  0x00,  0xA0,  0x7F,  0xC0,  0x40,  0x3F,  0x80,  0x40,  0xFF,  0xE2, 	/* 08840 */
+	0x00,  0x3F,  0xC4,  0x20,  0x82,  0x03,  0xFE,  0xB1,  0x00,  0x07,  0xF8,  0x00,  0x80,  0x08,  0x00,  0x87, 	/* 08850 */
+	0xF8,  0x40,  0x04,  0x00,  0x40,  0x44,  0x04,  0x40,  0x43,  0xFC,  0xB2,  0x00,  0x0F,  0xF8,  0x00,  0x84, 	/* 08860 */
+	0x08,  0x40,  0x87,  0xF8,  0x40,  0x04,  0x00,  0x40,  0x04,  0x02,  0x40,  0x23,  0xFE,  0xB3,  0x00,  0x07, 	/* 08870 */
+	0xF8,  0x40,  0x84,  0x08,  0x40,  0x87,  0xF8,  0x40,  0x04,  0x00,  0x40,  0x04,  0x02,  0x40,  0x23,  0xFE, 	/* 08880 */
+	0xB4,  0x00,  0x07,  0xFC,  0x44,  0x44,  0x44,  0x44,  0x47,  0xFC,  0x40,  0x04,  0x00,  0x40,  0x04,  0x02, 	/* 08890 */
+	0x40,  0x23,  0xFE,  0xB5,  0x01,  0xC7,  0xE0,  0x40,  0x07,  0xFE,  0x40,  0x05,  0xF8,  0x52,  0x85,  0x28, 	/* 088A0 */
+	0x5F,  0x89,  0x00,  0x90,  0x20,  0xFE,  0xB7,  0x09,  0x00,  0x90,  0x7F,  0xE0,  0x90,  0xFF,  0xF1,  0x08, 	/* 088B0 */
+	0x1F,  0x82,  0x14,  0xDF,  0x31,  0x00,  0x10,  0x80,  0xF8,  0xBB,  0x04,  0x02,  0x48,  0x15,  0x07,  0xFC, 	/* 088C0 */
+	0x0A,  0x0F,  0xFE,  0x11,  0x03,  0xF8,  0xC1,  0x61,  0xF0,  0x10,  0x40,  0xFC,  0xBD,  0x00,  0x0F,  0xBE, 	/* 088D0 */
+	0x08,  0x2F,  0xBE,  0x82,  0x07,  0x9E,  0x11,  0x07,  0xFC,  0x11,  0x0F,  0xFE,  0x20,  0x8C,  0x04,  0xBE, 	/* 088E0 */
+	0x04,  0x00,  0x40,  0x04,  0x07,  0xFC,  0x44,  0x44,  0x44,  0x44,  0x44,  0x44,  0x45,  0x80,  0x40,  0x04, 	/* 088F0 */
+	0x00,  0x40,  0x82,  0x04,  0x00,  0x40,  0xFF,  0xE0,  0x40,  0x3F,  0xC2,  0x44,  0x24,  0x42,  0x44,  0x24, 	/* 08900 */
+	0x42,  0x58,  0x04,  0x00,  0x40,  0x83,  0x04,  0x00,  0x40,  0xFF,  0xE0,  0xA0,  0x0A,  0x01,  0xFC,  0x32, 	/* 08910 */
+	0x45,  0x24,  0x92,  0x41,  0x24,  0x13,  0x80,  0x20,  0x86,  0x20,  0x02,  0x3C,  0xFA,  0x4A,  0xA4,  0xAA, 	/* 08920 */
+	0x4A,  0xB4,  0xAA,  0xCA,  0xA4,  0xBA,  0x42,  0x45,  0x24,  0x52,  0x83,  0x8B,  0x01,  0x83,  0xE0,  0x22, 	/* 08930 */
+	0x03,  0xFE,  0x21,  0x0F,  0x8A,  0x04,  0x67,  0xFC,  0x44,  0x44,  0x44,  0x45,  0x80,  0x40,  0x8C,  0x18, 	/* 08940 */
+	0x80,  0x70,  0x78,  0x80,  0x80,  0xFF,  0xE1,  0x20,  0x3F,  0xC5,  0x24,  0x92,  0x41,  0x38,  0x12,  0x00, 	/* 08950 */
+	0x20,  0x91,  0x10,  0x0F,  0xFE,  0x25,  0x24,  0x8C,  0x39,  0x4E,  0x62,  0x04,  0x07,  0xFC,  0x44,  0x44, 	/* 08960 */
+	0x44,  0x45,  0x80,  0x40,  0x96,  0x21,  0x02,  0x10,  0xF9,  0x0A,  0x9E,  0xA9,  0x0A,  0x90,  0xA9,  0x0A, 	/* 08970 */
+	0xFE,  0xBC,  0x22,  0x42,  0x24,  0x22,  0x7E,  0x99,  0x21,  0x02,  0x50,  0xFD,  0x0A,  0xFE,  0xA9,  0x0A, 	/* 08980 */
+	0x90,  0xAF,  0xEA,  0x90,  0xBA,  0x82,  0x28,  0x24,  0x42,  0x82,  0x9A,  0x1F,  0x80,  0x08,  0xFF,  0xE0, 	/* 08990 */
+	0x08,  0x1F,  0x8F,  0xFE,  0x84,  0x2B,  0xFA,  0x24,  0x82,  0x48,  0x27,  0x00,  0x40,  0x9B,  0x08,  0x03, 	/* 089A0 */
+	0xF8,  0x20,  0x83,  0xF8,  0x20,  0x83,  0xF8,  0x04,  0x07,  0xFC,  0x44,  0x44,  0x44,  0x45,  0x80,  0x40, 	/* 089B0 */
+	0x9D,  0x04,  0x0F,  0xFE,  0x20,  0x81,  0x10,  0xFF,  0xE8,  0x42,  0x7F,  0xC4,  0x44,  0x44,  0x44,  0x58, 	/* 089C0 */
+	0x04,  0x00,  0x40,  0xA5,  0x21,  0x02,  0x10,  0xF7,  0xE9,  0x52,  0xF5,  0x28,  0x52,  0xF5,  0x29,  0x52, 	/* 089D0 */
+	0x95,  0xC9,  0x50,  0xF1,  0x00,  0x10,  0xAB,  0x40,  0x04,  0x7E,  0xF1,  0x09,  0x10,  0xF7,  0xE8,  0x52, 	/* 089E0 */
+	0xF5,  0x29,  0x52,  0x95,  0x29,  0x56,  0xF1,  0x00,  0x10,  0xAD,  0x02,  0x07,  0xFE,  0x48,  0x87,  0xFE, 	/* 089F0 */
+	0x48,  0x84,  0xF8,  0x42,  0x05,  0xFC,  0x52,  0x49,  0x24,  0x93,  0x80,  0x20,  0xAF,  0x24,  0x8F,  0xFE, 	/* 08A00 */
+	0x24,  0x83,  0xF8,  0x00,  0x0F,  0xFE,  0x84,  0x2B,  0xFA,  0x24,  0x82,  0x48,  0x27,  0x00,  0x40,  0xB0, 	/* 08A10 */
+	0x2F,  0x82,  0x08,  0xAF,  0x8A,  0x08,  0xBF,  0xEB,  0x22,  0xAF,  0xE2,  0xA4,  0x2A,  0x44,  0xAC,  0x42, 	/* 08A20 */
+	0x08,  0x20,  0xB3,  0x23,  0xE2,  0x20,  0xFB,  0xCA,  0xA0,  0xAB,  0xCA,  0xA0,  0xAF,  0xEA,  0xB2,  0xBA, 	/* 08A30 */
+	0xC2,  0x28,  0x23,  0x42,  0x63,  0xB6,  0x2A,  0x8F,  0xFE,  0x2A,  0x82,  0xAA,  0x2E,  0x64,  0x00,  0xFF, 	/* 08A40 */
+	0xE8,  0x42,  0xBF,  0xA2,  0x48,  0x25,  0x80,  0x40,  0xB7,  0x21,  0x42,  0x14,  0xFB,  0xEA,  0xA8,  0xAE, 	/* 08A50 */
+	0x8A,  0xBE,  0xAA,  0x8A,  0xA8,  0xBB,  0xE2,  0x28,  0x22,  0x82,  0x3E,  0xB8,  0x24,  0x81,  0x50,  0xFF, 	/* 08A60 */
+	0xE9,  0xF2,  0x91,  0x21,  0xF0,  0x04,  0x03,  0xFC,  0x24,  0x42,  0x44,  0x24,  0x80,  0x40,  0xBD,  0x20, 	/* 08A70 */
+	0x02,  0xFE,  0xF8,  0x2A,  0xFE,  0xA8,  0x2A,  0xFE,  0xAC,  0x4A,  0xFC,  0xBC,  0x42,  0x7C,  0x24,  0x42, 	/* 08A80 */
+	0x7C,  0x80,  0x21,  0x02,  0x1E,  0xF9,  0x0A,  0xFC,  0xAC,  0x4A,  0xFC,  0xAC,  0x4A,  0xFC,  0xBC,  0x42, 	/* 08A90 */
+	0x7C,  0x22,  0x42,  0xC2,  0x83,  0x21,  0x02,  0x7E,  0xF9,  0x2A,  0xFF,  0xAB,  0xCA,  0xA4,  0xAB,  0xCA, 	/* 08AA0 */
+	0x88,  0xBB,  0xC2,  0x28,  0x27,  0xE2,  0x08,  0x84,  0x27,  0xC2,  0x44,  0xFF,  0xCA,  0xC0,  0xAF,  0xEA, 	/* 08AB0 */
+	0xD8,  0xAD,  0x4B,  0xFA,  0xA4,  0x82,  0x7E,  0x28,  0x83,  0x7E,  0x85,  0x27,  0xE2,  0x00,  0xFB,  0xCA, 	/* 08AC0 */
+	0xA4,  0xAB,  0xCA,  0x80,  0xAF,  0xEA,  0xD2,  0xBF,  0xEA,  0x52,  0x25,  0x22,  0x7E,  0x87,  0x20,  0x4F, 	/* 08AD0 */
+	0xFE,  0x22,  0x4F,  0x94,  0x20,  0x4F,  0x8C,  0x04,  0x07,  0xFC,  0x44,  0x44,  0x44,  0x45,  0x80,  0x40, 	/* 08AE0 */
+	0x8C,  0x27,  0xC2,  0x44,  0xFF,  0xCA,  0xC4,  0xAF,  0xCA,  0xD2,  0xAB,  0x4B,  0xFE,  0xA2,  0x82,  0x28, 	/* 08AF0 */
+	0x24,  0xA2,  0x86,  0x8E,  0x2F,  0xE2,  0x82,  0xF3,  0xCA,  0xA4,  0xAB,  0xCA,  0xA4,  0xAB,  0xCA,  0x90, 	/* 08B00 */
+	0xBF,  0xE2,  0x08,  0x22,  0x42,  0xC2,  0x94,  0x27,  0xC2,  0x44,  0xFF,  0xCA,  0xC4,  0xAF,  0xEA,  0xAA, 	/* 08B10 */
+	0xAF,  0xEB,  0x80,  0xA7,  0xC2,  0x48,  0x23,  0x02,  0xCC,  0x95,  0x11,  0x0F,  0xFE,  0x11,  0x03,  0xF8, 	/* 08B20 */
+	0x3F,  0x82,  0x08,  0xFF,  0xE2,  0x48,  0x7F,  0xCA,  0x4A,  0x25,  0x80,  0x40,  0x97,  0x20,  0x02,  0xFE, 	/* 08B30 */
+	0xF9,  0x6A,  0xFE,  0xA9,  0x2A,  0xF6,  0xAD,  0x6A,  0xFA,  0xB9,  0xA2,  0xEA,  0x29,  0x62,  0xFE,  0x9F, 	/* 08B40 */
+	0x22,  0x82,  0xFC,  0x25,  0xAF,  0xE8,  0xAF,  0xEA,  0x88,  0xAE,  0xAA,  0xAA,  0xAE,  0x4B,  0xAC,  0x2F, 	/* 08B50 */
+	0x42,  0x22,  0xA1,  0x20,  0xE2,  0xF2,  0x25,  0x4F,  0xFE,  0xAB,  0x8A,  0xD4,  0xA9,  0x2A,  0xFF,  0xBD, 	/* 08B60 */
+	0x2A,  0x7E,  0x25,  0x22,  0x7E,  0xA2,  0x21,  0x02,  0xFE,  0x22,  0x8F,  0xFE,  0xAD,  0x4A,  0xFC,  0xAD, 	/* 08B70 */
+	0x4A,  0xFC,  0xB9,  0x0A,  0x7C,  0x21,  0x02,  0xFE,  0xA3,  0xAA,  0x07,  0x3E,  0xFE,  0x4A,  0x94,  0xB8, 	/* 08B80 */
+	0x8A,  0xB4,  0x84,  0x23,  0xFC,  0x24,  0x42,  0x44,  0x25,  0x80,  0x40,  0xA4,  0x69,  0x0A,  0x5E,  0xFA, 	/* 08B90 */
+	0x4B,  0xD4,  0xA8,  0x8B,  0x94,  0x8E,  0x20,  0x40,  0x7F,  0xC4,  0x44,  0x45,  0x80,  0x40,  0xB2,  0x00, 	/* 08BA0 */
+	0x07,  0xFC,  0x04,  0x00,  0x40,  0x04,  0x0F,  0xFE,  0x04,  0x00,  0x40,  0x04,  0x00,  0x40,  0x04,  0x00, 	/* 08BB0 */
+	0x40,  0xB3,  0x00,  0x07,  0xFC,  0x04,  0x82,  0x48,  0x15,  0x01,  0x40,  0xFF,  0xE0,  0x40,  0x04,  0x00, 	/* 08BC0 */
+	0x40,  0x04,  0x00,  0x40,  0xB4,  0x10,  0x01,  0x00,  0x1F,  0xC2,  0x20,  0x42,  0x09,  0xFC,  0x12,  0x01, 	/* 08BD0 */
+	0x20,  0x7F,  0xE0,  0x20,  0x02,  0x00,  0x20,  0xB5,  0x00,  0x07,  0xBC,  0x20,  0x82,  0x08,  0x20,  0x8F, 	/* 08BE0 */
+	0xFE,  0x20,  0x82,  0x08,  0x20,  0x82,  0x08,  0x20,  0x82,  0x08,  0xB6,  0x20,  0x81,  0x08,  0x11,  0x07, 	/* 08BF0 */
+	0xFC,  0x11,  0x01,  0x10,  0xFF,  0xE1,  0x10,  0x11,  0x02,  0x10,  0x21,  0x04,  0x10,  0xB8,  0x04,  0x00, 	/* 08C00 */
+	0x40,  0x7F,  0xC0,  0x40,  0xFF,  0xE2,  0x08,  0x11,  0x0F,  0xFE,  0x04,  0x07,  0xFC,  0x04,  0x00,  0x40, 	/* 08C10 */
+	0xB9,  0x20,  0x8F,  0x88,  0x21,  0x4F,  0xA2,  0x8F,  0xDF,  0x88,  0x88,  0x8F,  0xFE,  0x20,  0x8F,  0x88, 	/* 08C20 */
+	0x20,  0x82,  0x08,  0xBA,  0x04,  0x00,  0x40,  0x08,  0x07,  0x10,  0x11,  0x00,  0xA0,  0x04,  0x00,  0x88, 	/* 08C30 */
+	0x10,  0x42,  0x3C,  0xFC,  0x20,  0x02,  0xBB,  0x00,  0x02,  0x7E,  0x20,  0x24,  0x02,  0xC8,  0x22,  0x82, 	/* 08C40 */
+	0x10,  0x22,  0x02,  0x28,  0x24,  0x82,  0xF4,  0x20,  0x4C,  0xBC,  0x11,  0x01,  0x10,  0x21,  0x0A,  0xFE, 	/* 08C50 */
+	0x49,  0x22,  0x92,  0x11,  0x22,  0x92,  0x25,  0x23,  0xE2,  0xC6,  0x20,  0x4C,  0xBD,  0x04,  0x08,  0x42, 	/* 08C60 */
+	0x94,  0xA9,  0x4A,  0xA5,  0x2C,  0xE6,  0xB5,  0xA9,  0x4A,  0xEF,  0x68,  0x42,  0xFF,  0xE8,  0x02,  0xBE, 	/* 08C70 */
+	0x24,  0x85,  0x54,  0xA6,  0x85,  0x54,  0xF5,  0xC1,  0x44,  0xFF,  0xE2,  0x44,  0x22,  0x85,  0x12,  0x46, 	/* 08C80 */
+	0xAB,  0x86,  0xBF,  0x02,  0x00,  0x20,  0x3F,  0xE2,  0x00,  0x20,  0x02,  0x00,  0x20,  0x02,  0x00,  0x20, 	/* 08C90 */
+	0x04,  0x00,  0x40,  0x08,  0x00,  0x81,  0x02,  0x03,  0xFE,  0x20,  0x02,  0x00,  0x3F,  0xE2,  0x10,  0x21, 	/* 08CA0 */
+	0x02,  0x10,  0x41,  0x04,  0x10,  0x81,  0x00,  0x30,  0x83,  0x02,  0x03,  0xFE,  0x20,  0x02,  0x20,  0x22, 	/* 08CB0 */
+	0x02,  0x20,  0x22,  0x02,  0x48,  0x44,  0x44,  0xBA,  0xBC,  0x20,  0x02,  0x84,  0x02,  0x00,  0x20,  0x7F, 	/* 08CC0 */
+	0xE4,  0x00,  0x42,  0x04,  0x20,  0x5F,  0xC4,  0x20,  0x42,  0x08,  0x20,  0x9F,  0xE0,  0x00,  0x87,  0x02, 	/* 08CD0 */
+	0x07,  0xFE,  0x40,  0x05,  0x10,  0x51,  0x05,  0x12,  0x5D,  0xC5,  0x10,  0x51,  0x05,  0x12,  0x9D,  0x2B, 	/* 08CE0 */
+	0x0E,  0x8A,  0x02,  0x00,  0x20,  0x7F,  0xE4,  0x00,  0x42,  0x05,  0xFE,  0x42,  0x04,  0x70,  0x4A,  0x85, 	/* 08CF0 */
+	0x24,  0xA2,  0x20,  0x20,  0x8F,  0x02,  0x07,  0xFE,  0x40,  0x05,  0xFC,  0x40,  0x84,  0x70,  0x7F,  0xE4, 	/* 08D00 */
+	0x24,  0x42,  0x88,  0x20,  0x82,  0x00,  0x60,  0x95,  0x04,  0x07,  0xFE,  0x41,  0x85,  0xE0,  0x52,  0x05, 	/* 08D10 */
+	0x20,  0x5F,  0xC5,  0x10,  0x51,  0x07,  0xCA,  0x80,  0x67,  0xF2,  0x96,  0x02,  0x07,  0xFE,  0x50,  0x05, 	/* 08D20 */
+	0xFC,  0x50,  0x46,  0xF4,  0x41,  0x45,  0xF4,  0x50,  0x89,  0x00,  0x90,  0x20,  0xFE,  0x97,  0x02,  0x00, 	/* 08D30 */
+	0x20,  0x3F,  0xE2,  0x20,  0x22,  0x02,  0x3E,  0x22,  0x02,  0x20,  0x5F,  0xC5,  0x04,  0x90,  0x41,  0xFC, 	/* 08D40 */
+	0x9A,  0x02,  0x07,  0xFE,  0x42,  0x05,  0xFC,  0x42,  0x47,  0xFF,  0x42,  0x45,  0xFC,  0x46,  0x04,  0x50, 	/* 08D50 */
+	0x88,  0x83,  0x06,  0x9C,  0x04,  0x07,  0xFE,  0x48,  0x84,  0x88,  0x57,  0xE5,  0x08,  0x74,  0x85,  0x28, 	/* 08D60 */
+	0x52,  0x85,  0x08,  0x90,  0x81,  0x18,  0xA0,  0x02,  0x07,  0xFE,  0x48,  0x44,  0x48,  0x7F,  0xE4,  0x20, 	/* 08D70 */
+	0x4F,  0xC4,  0x20,  0x42,  0x0B,  0xFE,  0x82,  0x00,  0x20,  0xA6,  0x04,  0x07,  0xFE,  0x49,  0x07,  0xFE, 	/* 08D80 */
+	0x49,  0x04,  0xF0,  0x40,  0x05,  0xF8,  0x49,  0x08,  0x60,  0x8D,  0x87,  0x06,  0xA7,  0x02,  0x07,  0xFE, 	/* 08D90 */
+	0x40,  0x05,  0x28,  0x52,  0x85,  0xA8,  0x67,  0x44,  0x22,  0x5F,  0xC8,  0x20,  0x82,  0x03,  0xFE,  0xAB, 	/* 08DA0 */
+	0x02,  0x07,  0xFE,  0x42,  0x07,  0xFE,  0x52,  0x45,  0xFC,  0x52,  0x45,  0xFC,  0x42,  0x0B,  0xFE,  0x82, 	/* 08DB0 */
+	0x00,  0x20,  0xAD,  0x02,  0x07,  0xFE,  0x40,  0x07,  0x86,  0x4B,  0x85,  0x08,  0x7F,  0xE4,  0x88,  0x68, 	/* 08DC0 */
+	0x85,  0xBE,  0xA6,  0x04,  0x1E,  0xB5,  0x02,  0x07,  0xFE,  0x42,  0x07,  0xFE,  0x4A,  0x85,  0xFC,  0x72, 	/* 08DD0 */
+	0x65,  0xFC,  0x52,  0x45,  0xFC,  0x82,  0x28,  0x1E,  0xB6,  0x04,  0x07,  0xFE,  0x40,  0x04,  0x90,  0x7F, 	/* 08DE0 */
+	0xC4,  0x90,  0x49,  0x04,  0xF0,  0x40,  0x05,  0x54,  0x95,  0x2A,  0x52,  0xB7,  0x02,  0x07,  0xFE,  0x42, 	/* 08DF0 */
+	0x05,  0xFC,  0x42,  0x47,  0xFE,  0x42,  0x45,  0xFC,  0x52,  0x48,  0xF8,  0xB2,  0x60,  0x60,  0xB8,  0x02, 	/* 08E00 */
+	0x07,  0xFE,  0x42,  0x05,  0xFC,  0x42,  0x47,  0xFE,  0x52,  0x45,  0xFC,  0x52,  0x45,  0xFC,  0x52,  0x49, 	/* 08E10 */
+	0x2C,  0x81,  0x02,  0x07,  0xFE,  0x40,  0x05,  0xE2,  0x52,  0xA5,  0xEA,  0x52,  0xA5,  0xEA,  0x52,  0xA9, 	/* 08E20 */
+	0xEA,  0x8A,  0x21,  0x06,  0x82,  0x02,  0x07,  0xFE,  0x48,  0x04,  0x9E,  0x7F,  0x24,  0x92,  0x5D,  0xE5, 	/* 08E30 */
+	0xB2,  0x69,  0xEA,  0x92,  0x89,  0x20,  0x9E,  0x83,  0x02,  0x07,  0xFE,  0x5A,  0x46,  0x98,  0x50,  0xA7, 	/* 08E40 */
+	0xFC,  0x45,  0x37,  0xFC,  0x45,  0x04,  0x90,  0x91,  0x26,  0x0E,  0x88,  0x02,  0x07,  0xFE,  0x40,  0x07, 	/* 08E50 */
+	0xFE,  0x48,  0x84,  0xF8,  0x48,  0x84,  0xF8,  0x47,  0x89,  0xC8,  0x87,  0x03,  0x8E,  0x89,  0x02,  0x07, 	/* 08E60 */
+	0xFE,  0x45,  0x05,  0xFE,  0x45,  0x47,  0xFE,  0x45,  0x45,  0xFC,  0x4D,  0x89,  0x54,  0xA5,  0x20,  0x50, 	/* 08E70 */
+	0x8A,  0x04,  0x07,  0xFE,  0x48,  0x05,  0xDC,  0x55,  0x45,  0xD4,  0x55,  0x85,  0xD4,  0x59,  0x29,  0x52, 	/* 08E80 */
+	0x9D,  0xC3,  0x30,  0x8F,  0x04,  0x07,  0xFE,  0x48,  0x05,  0xDC,  0x55,  0x45,  0xD4,  0x55,  0x65,  0xE0, 	/* 08E90 */
+	0x53,  0xE9,  0xD4,  0x90,  0xC0,  0xF2,  0x90,  0x04,  0x07,  0xFE,  0x48,  0x05,  0xFE,  0x55,  0x45,  0xD4, 	/* 08EA0 */
+	0x57,  0xE5,  0xD8,  0x51,  0x89,  0xAA,  0x92,  0xA0,  0xC6,  0x93,  0x04,  0x07,  0xFE,  0x48,  0x07,  0xFE, 	/* 08EB0 */
+	0x5D,  0x25,  0x54,  0x5D,  0x87,  0xD6,  0x49,  0x2B,  0xF2,  0x89,  0xC1,  0x90,  0x96,  0x04,  0x07,  0xFE, 	/* 08EC0 */
+	0x40,  0x07,  0xDE,  0x54,  0xA6,  0xD6,  0x54,  0xA4,  0xB0,  0x72,  0xC9,  0xC0,  0x81,  0x80,  0xE0,  0x9A, 	/* 08ED0 */
+	0x04,  0x07,  0xFE,  0x48,  0x47,  0xE4,  0x4B,  0xE7,  0xC4,  0x66,  0x47,  0xD4,  0x64,  0x49,  0x84,  0x8E, 	/* 08EE0 */
+	0x47,  0x0C,  0x9B,  0x02,  0x07,  0xFE,  0x5F,  0xC5,  0x24,  0x5F,  0xC5,  0x24,  0x7F,  0xE4,  0x20,  0x7F, 	/* 08EF0 */
+	0xEA,  0xFA,  0xC2,  0x03,  0xFE,  0x9D,  0x02,  0x07,  0xFE,  0x54,  0x27,  0xDC,  0x55,  0x05,  0xDF,  0x55, 	/* 08F00 */
+	0x45,  0xD4,  0x55,  0x4B,  0xF4,  0x9A,  0x42,  0x44,  0x9F,  0x04,  0x07,  0xFE,  0x48,  0x07,  0xFE,  0x49, 	/* 08F10 */
+	0x25,  0xD2,  0x5D,  0xE5,  0x52,  0x5D,  0xE4,  0x92,  0xBF,  0x28,  0xA6,  0xA0,  0x02,  0x07,  0xFF,  0x48, 	/* 08F20 */
+	0x86,  0xA8,  0x5C,  0xF4,  0x8A,  0x7F,  0xA6,  0x34,  0x7A,  0x46,  0xAA,  0xBA,  0xA2,  0x71,  0xA1,  0x02, 	/* 08F30 */
+	0x07,  0xFE,  0x48,  0x05,  0xFE,  0x75,  0x45,  0x54,  0x7F,  0xE5,  0x54,  0x55,  0x47,  0xFE,  0x95,  0x42, 	/* 08F40 */
+	0x2A,  0xA2,  0x04,  0x07,  0xFE,  0x5A,  0x84,  0x92,  0x50,  0xC7,  0xBA,  0x4A,  0x87,  0xA6,  0x67,  0xCB, 	/* 08F50 */
+	0x94,  0x89,  0x83,  0x66,  0xA3,  0x02,  0x07,  0xFE,  0x49,  0x07,  0xFC,  0x49,  0x07,  0xFE,  0x52,  0x45, 	/* 08F60 */
+	0xFC,  0x52,  0x49,  0xFC,  0x88,  0x43,  0x02,  0xA8,  0x02,  0x07,  0xFE,  0x50,  0x05,  0xDE,  0x68,  0xA7, 	/* 08F70 */
+	0xF6,  0x6A,  0x47,  0xEE,  0x6B,  0x4B,  0xFE,  0xA2,  0x42,  0x64,  0xA9,  0x04,  0x07,  0xFE,  0x42,  0x07, 	/* 08F80 */
+	0xFE,  0x55,  0x45,  0x74,  0x50,  0x45,  0xFC,  0x42,  0x0B,  0xFE,  0x8A,  0x83,  0x26,  0xAC,  0x04,  0x07, 	/* 08F90 */
+	0xFE,  0x43,  0x85,  0xFE,  0x52,  0x05,  0x7E,  0x52,  0x05,  0x7E,  0x55,  0x49,  0xFE,  0xAA,  0xA5,  0xFF, 	/* 08FA0 */
+	0xB0,  0x04,  0x07,  0xFE,  0x40,  0x87,  0xFE,  0x54,  0x85,  0xFE,  0x56,  0xA5,  0xFE,  0x55,  0x49,  0xDA, 	/* 08FB0 */
+	0xB6,  0xA0,  0x46,  0xB1,  0x02,  0x07,  0xFE,  0x55,  0x26,  0xA4,  0x55,  0xE5,  0xD4,  0x55,  0xE7,  0xF4, 	/* 08FC0 */
+	0x6B,  0xEB,  0xF4,  0xA1,  0x41,  0xDE,  0xB3,  0x04,  0x07,  0xFE,  0x40,  0x87,  0xFE,  0x54,  0x85,  0xFE, 	/* 08FD0 */
+	0x56,  0xA7,  0xFE,  0x45,  0x49,  0x5A,  0xBE,  0xA0,  0x46,  0xB4,  0x00,  0x07,  0x80,  0x10,  0x02,  0x00, 	/* 08FE0 */
+	0x78,  0x00,  0x80,  0x48,  0x04,  0x80,  0x30,  0x03,  0x00,  0x4C,  0x08,  0x3F,  0xB6,  0x00,  0x6F,  0x78, 	/* 08FF0 */
+	0x11,  0x02,  0x10,  0x45,  0xE7,  0x50,  0x15,  0x05,  0x50,  0x25,  0x03,  0xFE,  0x4C,  0x08,  0x3F,  0xB7, 	/* 09000 */
+	0x00,  0xCF,  0x70,  0x11,  0x02,  0x10,  0x41,  0x07,  0xFE,  0x11,  0x05,  0x10,  0x21,  0x03,  0x7C,  0x4C, 	/* 09010 */
+	0x08,  0x3E,  0xB8,  0x01,  0x0E,  0x10,  0x21,  0x04,  0xFE,  0xE9,  0x22,  0x92,  0xAF,  0xEA,  0x92,  0x69, 	/* 09020 */
+	0x22,  0xFE,  0x58,  0x08,  0x7F,  0xBA,  0x01,  0x07,  0x7C,  0x11,  0x42,  0xFE,  0x41,  0x47,  0x7C,  0x11, 	/* 09030 */
+	0x05,  0x7C,  0x21,  0x03,  0x7E,  0x4D,  0x08,  0x3F,  0xBB,  0x00,  0x0E,  0xFE,  0x28,  0x22,  0xBA,  0x4A, 	/* 09040 */
+	0xAE,  0xAA,  0x2B,  0xAA,  0x82,  0x6F,  0xE2,  0x00,  0x58,  0x08,  0x7E,  0xBC,  0x00,  0x0E,  0xFE,  0x22, 	/* 09050 */
+	0x84,  0xFE,  0xEA,  0xA2,  0xAA,  0x2C,  0xEA,  0x82,  0x68,  0x23,  0xFE,  0x4C,  0x08,  0x3F,  0xBE,  0x11, 	/* 09060 */
+	0x01,  0x10,  0x11,  0x01,  0x10,  0xFF,  0xE1,  0x10,  0x11,  0x01,  0x10,  0x11,  0x02,  0x10,  0x21,  0x04, 	/* 09070 */
+	0x10,  0xBF,  0x11,  0x01,  0x10,  0x11,  0x01,  0x10,  0xFF,  0xE1,  0x10,  0x11,  0x01,  0x10,  0x11,  0x01, 	/* 09080 */
+	0x10,  0x11,  0x01,  0xF0,  0x81,  0x08,  0x00,  0xA0,  0x11,  0x87,  0xE4,  0x11,  0x01,  0x10,  0x11,  0x0F, 	/* 09090 */
+	0xFE,  0x11,  0x01,  0x10,  0x21,  0x04,  0x10,  0x83,  0x04,  0x0F,  0xFE,  0x09,  0x01,  0x08,  0x7F,  0x41, 	/* 090A0 */
+	0x14,  0x11,  0x0F,  0xFE,  0x11,  0x01,  0x10,  0x21,  0x04,  0x10,  0x84,  0x00,  0x07,  0xFC,  0x04,  0x03, 	/* 090B0 */
+	0xF8,  0x04,  0x0F,  0xFE,  0x11,  0x01,  0x10,  0xFF,  0xE1,  0x10,  0x21,  0x04,  0x10,  0x89,  0x51,  0x07, 	/* 090C0 */
+	0x10,  0x1F,  0xEF,  0x10,  0x51,  0x09,  0x7C,  0x10,  0x01,  0x10,  0xFF,  0xF1,  0x10,  0x11,  0x02,  0x10, 	/* 090D0 */
+	0x8A,  0xA9,  0x07,  0x10,  0xFB,  0xEA,  0xA4,  0xFD,  0x8A,  0x94,  0x9A,  0x21,  0x10,  0xFF,  0xE1,  0x10, 	/* 090E0 */
+	0x11,  0x02,  0x10,  0x8B,  0x05,  0x00,  0x48,  0x04,  0x00,  0x7E,  0xFC,  0x00,  0x40,  0x04,  0x00,  0x20, 	/* 090F0 */
+	0x02,  0x00,  0x12,  0x00,  0xA0,  0x06,  0x8C,  0x02,  0x80,  0x24,  0x02,  0x0F,  0xFE,  0x02,  0x00,  0x20, 	/* 09100 */
+	0x01,  0x0F,  0xD0,  0x00,  0x80,  0x0A,  0x00,  0x60,  0x02,  0x8D,  0x02,  0x80,  0x24,  0x02,  0x0F,  0xFE, 	/* 09110 */
+	0x02,  0x00,  0x20,  0x7D,  0x00,  0x10,  0x00,  0x81,  0xCA,  0xE0,  0x60,  0x02,  0x8F,  0x02,  0x00,  0x28, 	/* 09120 */
+	0x02,  0x4F,  0xFE,  0x02,  0x07,  0xE0,  0x12,  0x01,  0x10,  0x11,  0x01,  0xD4,  0xE0,  0xC0,  0x04,  0x90, 	/* 09130 */
+	0x02,  0x87,  0xA4,  0x02,  0x0F,  0xFE,  0x02,  0x00,  0x20,  0x7A,  0x00,  0x10,  0x0D,  0x03,  0x0A,  0xC0, 	/* 09140 */
+	0x60,  0x02,  0x91,  0x10,  0xCD,  0x0A,  0x2F,  0xE5,  0x08,  0x80,  0x82,  0xF8,  0xF2,  0x82,  0x24,  0x72, 	/* 09150 */
+	0x46,  0x3A,  0xAE,  0x22,  0x01,  0x93,  0x1F,  0x80,  0x08,  0x00,  0x83,  0xF8,  0x20,  0x02,  0x00,  0x3F, 	/* 09160 */
+	0xC0,  0x04,  0x00,  0x40,  0x04,  0x00,  0x80,  0x70,  0x94,  0x00,  0x07,  0xFC,  0x04,  0x40,  0x44,  0x7F, 	/* 09170 */
+	0xC4,  0x40,  0x7F,  0xE0,  0x42,  0x04,  0x20,  0x42,  0x04,  0xC0,  0x40,  0x95,  0x00,  0x47,  0xC4,  0x04, 	/* 09180 */
+	0x40,  0x44,  0x7C,  0x44,  0x04,  0x7C,  0x40,  0x44,  0x04,  0x40,  0x44,  0x04,  0x43,  0x84,  0x96,  0x00, 	/* 09190 */
+	0x03,  0xF0,  0x01,  0x00,  0x10,  0x3F,  0x02,  0x00,  0x3F,  0x82,  0x08,  0x00,  0x80,  0x08,  0x03,  0x0F, 	/* 091A0 */
+	0xFE,  0x97,  0x12,  0x0F,  0xFC,  0x12,  0x41,  0x24,  0xFF,  0xC9,  0x20,  0xFF,  0xE1,  0x22,  0x12,  0x21, 	/* 091B0 */
+	0x22,  0x22,  0xC4,  0x20,  0x98,  0x01,  0x0F,  0x10,  0x11,  0x01,  0x10,  0xF1,  0x08,  0x10,  0xF2,  0x01, 	/* 091C0 */
+	0x28,  0x12,  0x41,  0x4C,  0x2F,  0x2C,  0x02,  0x9B,  0x01,  0x0F,  0x50,  0x15,  0x01,  0x5C,  0xF7,  0x49, 	/* 091D0 */
+	0xD4,  0xF5,  0x41,  0x5C,  0x15,  0x01,  0x40,  0x24,  0x2C,  0x3E,  0x9F,  0x11,  0x00,  0xA0,  0x7F,  0xC0, 	/* 091E0 */
+	0x44,  0x3F,  0xC4,  0x40,  0x7F,  0xE0,  0x42,  0x0C,  0x23,  0x42,  0xC4,  0xC0,  0x40,  0xA5,  0x02,  0x0F, 	/* 091F0 */
+	0x20,  0x13,  0xE1,  0x50,  0xF9,  0x08,  0x10,  0xF5,  0x41,  0x52,  0x15,  0x21,  0x92,  0x21,  0x0C,  0x30, 	/* 09200 */
+	0xA6,  0x01,  0x0F,  0x10,  0x1F,  0xE1,  0x10,  0xF1,  0x48,  0xA4,  0xF4,  0x81,  0x28,  0x11,  0x81,  0x24, 	/* 09210 */
+	0x2F,  0xAC,  0x02,  0xA7,  0x00,  0x6F,  0x78,  0x15,  0x41,  0x54,  0xF5,  0x48,  0x54,  0xF5,  0x41,  0x54, 	/* 09220 */
+	0x15,  0xA1,  0x96,  0x29,  0xED,  0x65,  0xA9,  0x20,  0x0F,  0xFE,  0x4A,  0x43,  0x18,  0x2A,  0x4D,  0xF2, 	/* 09230 */
+	0x01,  0x03,  0xF0,  0x20,  0x07,  0xF8,  0x40,  0x80,  0x70,  0xAD,  0x00,  0x0F,  0xFE,  0x14,  0x41,  0x44, 	/* 09240 */
+	0xF7,  0xC8,  0x44,  0xF7,  0xC1,  0x44,  0x14,  0x41,  0x7C,  0x2C,  0x4C,  0x04,  0xAF,  0x04,  0x0F,  0xFE, 	/* 09250 */
+	0x09,  0x02,  0x94,  0x51,  0x29,  0xFA,  0x00,  0x83,  0xF8,  0x20,  0x07,  0xFC,  0x40,  0x40,  0x18,  0xB1, 	/* 09260 */
+	0x00,  0x0F,  0xBE,  0x08,  0x2F,  0xBE,  0x82,  0x0F,  0xBE,  0x08,  0x24,  0x92,  0x38,  0xEC,  0xB2,  0x08, 	/* 09270 */
+	0x23,  0x0C,  0xB5,  0x00,  0x0F,  0x7C,  0x14,  0x01,  0x7C,  0xF4,  0x08,  0x7C,  0xF4,  0x01,  0xFE,  0x15, 	/* 09280 */
+	0x41,  0x48,  0x27,  0x4D,  0x82,  0xB7,  0x02,  0x0F,  0x28,  0x14,  0x41,  0xFE,  0xF1,  0x28,  0x7C,  0xF5, 	/* 09290 */
+	0x41,  0x7C,  0x15,  0x41,  0x12,  0x21,  0xEC,  0xE2,  0xB8,  0x00,  0x0E,  0xEE,  0x2A,  0xA2,  0xAA,  0xEE, 	/* 092A0 */
+	0xE8,  0xAA,  0xEA,  0xA2,  0xEE,  0x2A,  0xA2,  0xAA,  0x2B,  0x2D,  0x66,  0xBC,  0x00,  0x0F,  0xEE,  0x24, 	/* 092B0 */
+	0x22,  0xE2,  0xEA,  0xE8,  0xA8,  0xEE,  0xEA,  0xAA,  0x2A,  0x22,  0xA2,  0x2E,  0x2C,  0x0C,  0xBE,  0x09, 	/* 092C0 */
+	0x2E,  0x54,  0x2F,  0xC2,  0x94,  0xEF,  0xC8,  0x94,  0xEF,  0xC2,  0x10,  0x3F,  0xE2,  0x10,  0x21,  0x0C, 	/* 092D0 */
+	0x10,  0x81,  0x00,  0x0F,  0xFE,  0x17,  0x41,  0x54,  0xF7,  0x48,  0x0C,  0xFF,  0xE1,  0x04,  0x17,  0x41, 	/* 092E0 */
+	0x54,  0x17,  0x46,  0x0C,  0x88,  0x07,  0x7F,  0x55,  0x17,  0x71,  0x3E,  0xF2,  0xA8,  0x3E,  0xF2,  0xA1, 	/* 092F0 */
+	0x3E,  0x10,  0x81,  0xFF,  0x10,  0x86,  0x08,  0x8A,  0x00,  0x0F,  0xFE,  0x29,  0x42,  0xFC,  0xE9,  0x48, 	/* 09300 */
+	0xFC,  0xFF,  0xE2,  0x94,  0x2F,  0xC2,  0x94,  0x2F,  0xCD,  0xFE,  0x8C,  0x00,  0x0F,  0xFE,  0x26,  0x82, 	/* 09310 */
+	0xA4,  0xFF,  0xE9,  0xB6,  0x96,  0xAF,  0xB6,  0x32,  0x23,  0xB6,  0x36,  0xAD,  0xB6,  0x8E,  0x44,  0x8B, 	/* 09320 */
+	0xF4,  0x50,  0xAF,  0xFE,  0x6B,  0xCA,  0xEA,  0x01,  0x01,  0xF0,  0x20,  0x03,  0xF8,  0x00,  0x80,  0x30, 	/* 09330 */
+	0x91,  0x08,  0x00,  0x80,  0x08,  0x00,  0xF8,  0x08,  0x81,  0x08,  0x11,  0x03,  0xF0,  0x21,  0x00,  0x20, 	/* 09340 */
+	0x02,  0x0F,  0xFF,  0x93,  0x04,  0x02,  0x48,  0x14,  0x81,  0x50,  0x7F,  0xC0,  0x04,  0x00,  0x43,  0xFC, 	/* 09350 */
+	0x00,  0x40,  0x04,  0x7F,  0xC0,  0x04,  0x96,  0x0F,  0x81,  0x10,  0x3E,  0x00,  0x20,  0xFF,  0xE0,  0xC0, 	/* 09360 */
+	0x32,  0x2C,  0xDC,  0x33,  0x80,  0xD4,  0x71,  0x20,  0x60,  0x97,  0x21,  0x0F,  0x7C,  0x21,  0x0F,  0x7C, 	/* 09370 */
+	0x21,  0x0F,  0x7C,  0x21,  0x07,  0xF8,  0x00,  0x8F,  0xFE,  0x00,  0x87,  0xF8,  0x99,  0x0F,  0x81,  0x10, 	/* 09380 */
+	0xFF,  0xE0,  0x00,  0xFF,  0xEA,  0x4A,  0x3F,  0x82,  0x48,  0xFF,  0xE1,  0xF0,  0xE4,  0xE0,  0x40,  0x9C, 	/* 09390 */
+	0x0F,  0x01,  0x20,  0xFF,  0xEA,  0x94,  0x72,  0x2F,  0xFD,  0x71,  0x4A,  0xAC,  0x11,  0x0F,  0xFE,  0x11, 	/* 093A0 */
+	0x02,  0x10,  0x9D,  0x1F,  0x02,  0x20,  0xFF,  0xEA,  0x48,  0x69,  0x4F,  0xCA,  0x73,  0xEA,  0x9C,  0x12, 	/* 093B0 */
+	0xAF,  0xFE,  0x11,  0x02,  0x10,  0xA1,  0x02,  0x00,  0x20,  0x04,  0x80,  0x88,  0x11,  0x02,  0x24,  0x04, 	/* 093C0 */
+	0x40,  0x88,  0x01,  0x00,  0x20,  0x0C,  0x03,  0x00,  0xA2,  0x00,  0x8F,  0xC8,  0x49,  0x04,  0x94,  0x4A, 	/* 093D0 */
+	0x4F,  0xC8,  0x48,  0x84,  0x92,  0x48,  0x24,  0x84,  0x48,  0x88,  0x90,  0xA6,  0x04,  0x07,  0xFE,  0x10, 	/* 093E0 */
+	0x80,  0x90,  0x3F,  0xE2,  0x10,  0x26,  0x43,  0x88,  0x27,  0x25,  0x84,  0x43,  0x8B,  0xC0,  0xA9,  0x18, 	/* 093F0 */
+	0x8E,  0x48,  0xA5,  0x05,  0x94,  0x52,  0x42,  0x08,  0xFC,  0x83,  0x12,  0x68,  0x26,  0x04,  0xA0,  0x82, 	/* 09400 */
+	0x10,  0xAA,  0x20,  0x83,  0xC8,  0x21,  0x0F,  0xD4,  0xAE,  0x4F,  0x08,  0xA4,  0xA9,  0xD2,  0xA8,  0x4A, 	/* 09410 */
+	0x85,  0xA8,  0x94,  0x7F,  0xAB,  0x00,  0x87,  0xC8,  0x55,  0x07,  0xD4,  0x56,  0x47,  0xC8,  0x44,  0x87, 	/* 09420 */
+	0xD2,  0x6C,  0x27,  0xC4,  0x44,  0x88,  0xD0,  0xAC,  0x24,  0x42,  0x44,  0x24,  0x8F,  0xFA,  0x25,  0x23, 	/* 09430 */
+	0x64,  0x6D,  0x46,  0xCA,  0xB4,  0x2A,  0x44,  0x24,  0x42,  0x48,  0xAD,  0x10,  0x4F,  0xE4,  0x10,  0x87, 	/* 09440 */
+	0xD0,  0x02,  0x47,  0xC4,  0x44,  0x87,  0xD2,  0x44,  0x22,  0x84,  0x1C,  0x8E,  0x10,  0xB0,  0x10,  0x8F, 	/* 09450 */
+	0xE8,  0x45,  0x02,  0x94,  0xFE,  0x44,  0x48,  0x7C,  0x84,  0x52,  0x7E,  0x21,  0x04,  0xFC,  0x81,  0x10, 	/* 09460 */
+	0xB1,  0x7C,  0x84,  0x48,  0x7D,  0x04,  0x64,  0x7C,  0x41,  0x08,  0xFE,  0x84,  0x52,  0x7C,  0x25,  0x44, 	/* 09470 */
+	0x92,  0x83,  0x10,  0xB3,  0x02,  0x00,  0x20,  0x05,  0x00,  0x90,  0x12,  0x00,  0x20,  0x04,  0x00,  0xC0, 	/* 09480 */
+	0x14,  0x00,  0x40,  0x04,  0x00,  0x40,  0xB7,  0x22,  0x02,  0x20,  0x5F,  0xE9,  0x20,  0x22,  0x02,  0x3C, 	/* 09490 */
+	0x62,  0x4A,  0x24,  0x24,  0x42,  0x44,  0x28,  0x43,  0x18,  0xB9,  0x27,  0x82,  0x48,  0x54,  0xA9,  0x4A, 	/* 094A0 */
+	0x28,  0x63,  0xF8,  0x64,  0x8A,  0x48,  0x23,  0x02,  0x30,  0x24,  0x83,  0x86,  0xBC,  0x21,  0x02,  0x10, 	/* 094B0 */
+	0x4F,  0xEA,  0x92,  0x29,  0x44,  0xFC,  0xC8,  0x44,  0xA8,  0x4A,  0x85,  0x90,  0x56,  0x85,  0x86,  0xBF, 	/* 094C0 */
+	0x25,  0x02,  0x50,  0x5F,  0xCA,  0x54,  0x2F,  0xC5,  0x50,  0xDF,  0xE4,  0x52,  0x45,  0x24,  0x96,  0x49, 	/* 094D0 */
+	0x05,  0x10,  0x80,  0x22,  0x02,  0x10,  0x5F,  0xE5,  0x10,  0x91,  0x02,  0x10,  0x27,  0xC6,  0x10,  0xA1, 	/* 094E0 */
+	0x02,  0x10,  0x21,  0x02,  0xFE,  0x81,  0x20,  0x02,  0xFE,  0x41,  0x05,  0x10,  0x95,  0x02,  0x5E,  0x25, 	/* 094F0 */
+	0x06,  0x50,  0xA5,  0x02,  0x50,  0x25,  0x03,  0xFE,  0x82,  0x27,  0xC2,  0x44,  0x54,  0x49,  0x44,  0x27, 	/* 09500 */
+	0xC2,  0x44,  0x64,  0x4A,  0x7C,  0x24,  0x42,  0x44,  0x24,  0x43,  0xFF,  0x83,  0x21,  0x02,  0x90,  0x49, 	/* 09510 */
+	0x0A,  0xFE,  0x29,  0x05,  0x10,  0xE1,  0x04,  0xFC,  0x41,  0x04,  0x10,  0x41,  0x05,  0xFE,  0x84,  0x20, 	/* 09520 */
+	0x02,  0xFC,  0x50,  0x49,  0x68,  0x21,  0x02,  0x28,  0x6D,  0x6A,  0x10,  0x2F,  0xC2,  0x10,  0x21,  0x03, 	/* 09530 */
+	0xFE,  0x85,  0x22,  0x02,  0xFC,  0x52,  0x09,  0x20,  0x3F,  0xE2,  0x08,  0x7F,  0xEA,  0x88,  0x24,  0x82, 	/* 09540 */
+	0x08,  0x20,  0x82,  0x18,  0x87,  0x24,  0x02,  0x40,  0x47,  0xEA,  0x82,  0x2F,  0xA5,  0x4A,  0xC7,  0xA4, 	/* 09550 */
+	0x4A,  0x44,  0xA4,  0x7A,  0x40,  0x24,  0x0C,  0x88,  0x20,  0x02,  0x7C,  0x54,  0x45,  0x7C,  0x94,  0x42, 	/* 09560 */
+	0x7C,  0x65,  0x2A,  0x52,  0x24,  0xC2,  0x48,  0x27,  0x42,  0xC2,  0x8A,  0x20,  0x02,  0xFE,  0x48,  0x24, 	/* 09570 */
+	0xBA,  0xAA,  0xA2,  0xAA,  0x4A,  0xAC,  0xAA,  0x4B,  0xA4,  0x82,  0x4F,  0xE4,  0x80,  0x8B,  0x22,  0x02, 	/* 09580 */
+	0xFC,  0x42,  0x4B,  0xFE,  0x22,  0x44,  0xFC,  0x42,  0x0C,  0xFC,  0x42,  0x05,  0xFE,  0x42,  0x04,  0x20, 	/* 09590 */
+	0x8C,  0x22,  0x02,  0x48,  0x49,  0x0A,  0x68,  0x24,  0x45,  0xFA,  0xC2,  0x24,  0x78,  0x5C,  0x84,  0x30, 	/* 095A0 */
+	0x46,  0x87,  0x86,  0x90,  0x22,  0x02,  0x30,  0x44,  0x8A,  0x84,  0x3F,  0xA4,  0x20,  0xDF,  0xE4,  0x20, 	/* 095B0 */
+	0x4A,  0x84,  0xA4,  0x52,  0x24,  0x60,  0x91,  0x20,  0x02,  0xFE,  0x45,  0x4A,  0x54,  0x2A,  0x84,  0x54, 	/* 095C0 */
+	0xC5,  0x44,  0x00,  0x4F,  0xE4,  0x10,  0x41,  0x05,  0xFE,  0x92,  0x22,  0x02,  0x20,  0x4F,  0xCA,  0x20, 	/* 095D0 */
+	0x22,  0x05,  0xFE,  0xC2,  0x04,  0xA0,  0x4B,  0xC5,  0x60,  0x63,  0x04,  0x0E,  0x93,  0x24,  0x42,  0x24, 	/* 095E0 */
+	0x42,  0x8A,  0xFE,  0x21,  0x04,  0x90,  0x49,  0xEC,  0x90,  0x49,  0x05,  0x50,  0x53,  0x06,  0x0E,  0x97, 	/* 095F0 */
+	0x20,  0x02,  0xF8,  0x48,  0x8A,  0xF8,  0x28,  0x85,  0xFE,  0xC0,  0x87,  0xFE,  0x48,  0x84,  0x48,  0x40, 	/* 09600 */
+	0x84,  0x18,  0x98,  0x25,  0x02,  0x50,  0x5D,  0xEA,  0x50,  0x25,  0x05,  0xDC,  0xC5,  0x04,  0x50,  0x7D, 	/* 09610 */
+	0xE4,  0x90,  0x49,  0x05,  0x10,  0x99,  0x21,  0x02,  0x90,  0x49,  0xEA,  0x90,  0x29,  0x05,  0xFE,  0xC1, 	/* 09620 */
+	0x04,  0x90,  0x49,  0xE4,  0xD0,  0x53,  0x06,  0x0E,  0x9E,  0x28,  0x82,  0x88,  0x48,  0x8B,  0x54,  0x22, 	/* 09630 */
+	0x24,  0x00,  0xC2,  0x05,  0x3C,  0x52,  0x05,  0xA0,  0x56,  0x06,  0x1E,  0xA0,  0x22,  0x02,  0x20,  0x5F, 	/* 09640 */
+	0xEA,  0x20,  0x2A,  0x84,  0xA8,  0xD7,  0x46,  0x32,  0x46,  0x84,  0xA4,  0x52,  0x24,  0x20,  0xA1,  0x50, 	/* 09650 */
+	0x05,  0x0E,  0x9F,  0xAA,  0x4A,  0x3F,  0xA4,  0x4A,  0xD7,  0xA5,  0x4A,  0x54,  0xA5,  0x7C,  0x7C,  0x84, 	/* 09660 */
+	0x08,  0xA8,  0x22,  0x02,  0xFC,  0x48,  0x4A,  0xFC,  0x28,  0x44,  0xFC,  0x40,  0x0D,  0xFE,  0x42,  0x04, 	/* 09670 */
+	0xFC,  0x42,  0x05,  0xFE,  0xA9,  0x24,  0x02,  0x7E,  0x54,  0x49,  0xFC,  0x24,  0x42,  0x7C,  0x62,  0x0A, 	/* 09680 */
+	0x3C,  0x2C,  0x82,  0x30,  0x25,  0x83,  0x86,  0xAA,  0x21,  0xC2,  0xE0,  0x49,  0x0A,  0xFE,  0x29,  0x04, 	/* 09690 */
+	0xFC,  0x4C,  0x4C,  0xFC,  0x54,  0x45,  0x7C,  0x64,  0x44,  0x7C,  0xAD,  0x21,  0xC2,  0x24,  0x4D,  0x4A, 	/* 096A0 */
+	0x48,  0x23,  0x04,  0xFC,  0xD2,  0x07,  0xFE,  0x42,  0x05,  0x24,  0x52,  0x45,  0xFC,  0xAE,  0x24,  0x42, 	/* 096B0 */
+	0x44,  0x55,  0x49,  0x57,  0x3F,  0xA4,  0x0A,  0xDF,  0xA4,  0xA4,  0x4A,  0x44,  0xAA,  0x51,  0x24,  0x21, 	/* 096C0 */
+	0xB3,  0x21,  0x02,  0xFE,  0x51,  0x05,  0xFE,  0xAA,  0xA2,  0xAA,  0x2F,  0xE6,  0x20,  0xA5,  0x42,  0xD2, 	/* 096D0 */
+	0x34,  0x62,  0x3C,  0xB4,  0x25,  0x03,  0x50,  0x55,  0xE9,  0xF4,  0x22,  0x45,  0xF4,  0xC5,  0x45,  0xE8, 	/* 096E0 */
+	0x44,  0x84,  0x74,  0x59,  0x44,  0x22,  0xB9,  0x24,  0x83,  0xE8,  0x4A,  0xFB,  0xF2,  0x21,  0x25,  0xEA, 	/* 096F0 */
+	0xD2,  0xA5,  0xE4,  0x52,  0x45,  0xEA,  0x52,  0xA5,  0x71,  0xBC,  0x28,  0x83,  0xE8,  0x52,  0xFB,  0xEA, 	/* 09700 */
+	0x32,  0xA5,  0xF2,  0xC9,  0x25,  0xEC,  0x48,  0x44,  0xE4,  0x52,  0xA6,  0x51,  0xBD,  0x15,  0x45,  0x54, 	/* 09710 */
+	0x5F,  0x78,  0x4A,  0x2B,  0x22,  0x4A,  0x4A,  0xAD,  0xF4,  0x44,  0x45,  0x6C,  0x65,  0x24,  0x61,  0x83, 	/* 09720 */
+	0x08,  0x00,  0x40,  0x02,  0x00,  0xA0,  0x08,  0x02,  0x84,  0x28,  0x24,  0x82,  0x48,  0x28,  0x88,  0x08, 	/* 09730 */
+	0x80,  0x78,  0x85,  0x08,  0x00,  0x48,  0x04,  0x81,  0x08,  0x11,  0x05,  0x14,  0x52,  0x25,  0x42,  0x98, 	/* 09740 */
+	0x01,  0x08,  0x30,  0x8C,  0xF8,  0x8C,  0x00,  0x03,  0xF8,  0x00,  0x83,  0xF8,  0x20,  0x02,  0x04,  0x1F, 	/* 09750 */
+	0xC0,  0x40,  0x52,  0x45,  0x22,  0x90,  0x90,  0xF8,  0x8D,  0x00,  0x07,  0xFC,  0x04,  0x41,  0x44,  0x08, 	/* 09760 */
+	0x43,  0x44,  0xC1,  0x81,  0x80,  0x54,  0x45,  0x12,  0x91,  0x20,  0xF0,  0x96,  0x20,  0x82,  0x08,  0x20, 	/* 09770 */
+	0x82,  0xFE,  0x70,  0x87,  0x48,  0xA2,  0x82,  0x28,  0x20,  0x82,  0x08,  0x20,  0x82,  0x18,  0x97,  0x04, 	/* 09780 */
+	0x00,  0x40,  0xFF,  0xE0,  0x40,  0x04,  0x07,  0xFC,  0x00,  0x01,  0x40,  0x52,  0x45,  0x2A,  0x90,  0xA0, 	/* 09790 */
+	0xF8,  0x98,  0x04,  0x00,  0x40,  0xFF,  0xE2,  0x00,  0x20,  0x01,  0xF8,  0x04,  0x01,  0x20,  0x52,  0x45, 	/* 097A0 */
+	0x02,  0x90,  0xA0,  0xF8,  0x99,  0x21,  0x02,  0x10,  0x21,  0x02,  0xFE,  0x74,  0x06,  0xC0,  0xA4,  0x02, 	/* 097B0 */
+	0x40,  0x24,  0x02,  0x40,  0x24,  0x02,  0x3E,  0x9C,  0x04,  0x00,  0x40,  0x7F,  0xE4,  0x20,  0x41,  0x04, 	/* 097C0 */
+	0x50,  0x54,  0x45,  0x42,  0x54,  0x2A,  0x48,  0xA4,  0x80,  0x38,  0x9D,  0x01,  0x87,  0xE0,  0x08,  0x0F, 	/* 097D0 */
+	0xFE,  0x0A,  0x01,  0x10,  0x24,  0x8C,  0x46,  0x26,  0x82,  0x54,  0x45,  0x40,  0xC0,  0xA0,  0x04,  0x00, 	/* 097E0 */
+	0x40,  0x7F,  0xC4,  0x44,  0x44,  0x47,  0xFC,  0x04,  0x01,  0x40,  0x52,  0x45,  0x22,  0x90,  0xA0,  0xF8, 	/* 097F0 */
+	0xA4,  0x24,  0x02,  0x40,  0x27,  0xC2,  0x90,  0x71,  0x07,  0x10,  0xAF,  0xE2,  0x10,  0x21,  0x02,  0x10, 	/* 09800 */
+	0x21,  0x02,  0x10,  0xAB,  0x22,  0x02,  0x20,  0x2F,  0xC2,  0x24,  0x72,  0x46,  0xFE,  0xA2,  0x02,  0x30, 	/* 09810 */
+	0x23,  0x02,  0x48,  0x28,  0x43,  0x02,  0xB0,  0x22,  0x02,  0x20,  0x2F,  0x82,  0x2A,  0x74,  0xA6,  0x86, 	/* 09820 */
+	0xA1,  0x02,  0xFE,  0x21,  0x02,  0x10,  0x21,  0x02,  0x10,  0xB1,  0x22,  0x02,  0x20,  0x22,  0x06,  0xFE, 	/* 09830 */
+	0x7A,  0x26,  0xA2,  0xA3,  0x02,  0x30,  0x23,  0x02,  0x52,  0x25,  0x22,  0x8E,  0xB5,  0x04,  0x00,  0xA0, 	/* 09840 */
+	0x11,  0x02,  0xE8,  0xC0,  0x63,  0xF8,  0x01,  0x00,  0x60,  0x52,  0x45,  0x22,  0x90,  0xA0,  0xF8,  0xB8, 	/* 09850 */
+	0x20,  0x02,  0xF8,  0x24,  0x82,  0x48,  0x74,  0x86,  0xFE,  0xA4,  0x82,  0x48,  0x24,  0x82,  0x48,  0x24, 	/* 09860 */
+	0x83,  0xFE,  0xBB,  0x20,  0x62,  0x78,  0x24,  0x02,  0x40,  0x77,  0xE6,  0xC8,  0xA4,  0x82,  0x48,  0x24, 	/* 09870 */
+	0x82,  0x88,  0x28,  0x83,  0x08,  0xBD,  0x10,  0x01,  0x00,  0x3F,  0xC4,  0x94,  0x92,  0x42,  0x44,  0x05, 	/* 09880 */
+	0x81,  0x20,  0x52,  0x45,  0x02,  0x90,  0xA0,  0xF8,  0xBF,  0x0B,  0x01,  0x08,  0x20,  0x4D,  0xFB,  0x04, 	/* 09890 */
+	0x80,  0x88,  0x33,  0x00,  0x00,  0x14,  0x05,  0x24,  0x90,  0xA0,  0xF8,  0x8E,  0x10,  0x01,  0x00,  0x3F, 	/* 098A0 */
+	0xE2,  0x40,  0x47,  0xC8,  0x40,  0x07,  0xC0,  0x40,  0x54,  0x45,  0x22,  0x90,  0xA0,  0xF8,  0x8F,  0x21, 	/* 098B0 */
+	0x02,  0x10,  0x2F,  0xC2,  0x94,  0x79,  0x46,  0x94,  0xBF,  0xE2,  0x10,  0x21,  0x02,  0x28,  0x24,  0x43, 	/* 098C0 */
+	0x82,  0x90,  0x24,  0x02,  0x40,  0x37,  0xE2,  0x82,  0x68,  0x27,  0x7A,  0xA4,  0xA2,  0x4A,  0x27,  0xA2, 	/* 098D0 */
+	0x02,  0x20,  0x22,  0x0C,  0x92,  0x10,  0x0F,  0xBC,  0x28,  0x44,  0xA8,  0x31,  0x02,  0xA8,  0xC4,  0x41, 	/* 098E0 */
+	0x40,  0x52,  0x45,  0x02,  0x90,  0xA0,  0xF8,  0x95,  0x20,  0x82,  0x10,  0x27,  0xE3,  0x42,  0x6C,  0x26, 	/* 098F0 */
+	0x42,  0xA7,  0xE2,  0x42,  0x24,  0x22,  0x42,  0x27,  0xE2,  0x00,  0x96,  0x22,  0x02,  0x20,  0x2F,  0xE2, 	/* 09900 */
+	0x20,  0x75,  0x06,  0x7E,  0xAD,  0x22,  0xD2,  0x35,  0x22,  0x5C,  0x25,  0x02,  0x10,  0x99,  0x21,  0x02, 	/* 09910 */
+	0x10,  0x21,  0x02,  0xFE,  0x71,  0x06,  0x90,  0xA1,  0x02,  0x7C,  0x24,  0x42,  0x44,  0x24,  0x42,  0x7C, 	/* 09920 */
+	0x9B,  0x20,  0x02,  0x7C,  0x24,  0x43,  0x44,  0x6C,  0x46,  0x7C,  0xA4,  0x42,  0x44,  0x24,  0x42,  0x7C, 	/* 09930 */
+	0x20,  0x02,  0xFF,  0x9C,  0x21,  0x02,  0x10,  0x22,  0x86,  0x7C,  0x68,  0x2B,  0xFD,  0xA2,  0x42,  0x24, 	/* 09940 */
+	0x22,  0x42,  0x38,  0x22,  0x02,  0x20,  0x9D,  0x00,  0x03,  0xFC,  0x24,  0x43,  0xFC,  0x24,  0x42,  0x44, 	/* 09950 */
+	0x3F,  0xC1,  0x40,  0x52,  0x45,  0x2A,  0x90,  0xA0,  0xF8,  0xA0,  0x08,  0x01,  0x10,  0x7E,  0xC0,  0x02, 	/* 09960 */
+	0x3F,  0x82,  0x08,  0x20,  0x83,  0xF8,  0x48,  0x05,  0x44,  0x91,  0x20,  0xF0,  0xA1,  0x22,  0x02,  0x20, 	/* 09970 */
+	0x22,  0x82,  0x24,  0x74,  0xC6,  0x72,  0xB8,  0x22,  0x7C,  0x24,  0x42,  0x44,  0x24,  0x42,  0x7C,  0xA5, 	/* 09980 */
+	0x10,  0x01,  0xF0,  0x22,  0x07,  0xF8,  0x00,  0x81,  0xF8,  0x00,  0x87,  0xF8,  0x44,  0x05,  0x24,  0x90, 	/* 09990 */
+	0xA0,  0xF8,  0xA6,  0x20,  0x02,  0x7E,  0x21,  0x02,  0x54,  0x75,  0x46,  0x92,  0xAF,  0xF2,  0x10,  0x21, 	/* 099A0 */
+	0x02,  0x10,  0x21,  0x02,  0x10,  0xA7,  0x21,  0x02,  0x50,  0x27,  0xC2,  0x50,  0x75,  0x06,  0x90,  0xA7, 	/* 099B0 */
+	0xC2,  0x10,  0x21,  0x02,  0x10,  0x21,  0x02,  0xFE,  0xA8,  0x20,  0x03,  0xBC,  0x4A,  0x4A,  0xA4,  0x12, 	/* 099C0 */
+	0xC2,  0x22,  0xC1,  0xE0,  0x40,  0x52,  0x45,  0x22,  0x90,  0xA0,  0xF8,  0xA9,  0x20,  0x02,  0x7E,  0x24, 	/* 099D0 */
+	0x22,  0x42,  0x77,  0xE6,  0x50,  0xA5,  0x22,  0x5C,  0x29,  0x02,  0x92,  0x31,  0x22,  0x0E,  0xAA,  0x2F, 	/* 099E0 */
+	0xC2,  0x44,  0x22,  0x82,  0x10,  0x72,  0x86,  0xC6,  0xA1,  0x02,  0x10,  0x2F,  0xC2,  0x10,  0x21,  0x03, 	/* 099F0 */
+	0xFE,  0xAB,  0x22,  0x82,  0x28,  0x2F,  0xE2,  0x2A,  0x7F,  0xE6,  0xA8,  0xAF,  0xF2,  0x29,  0x22,  0x92, 	/* 09A00 */
+	0x2E,  0x24,  0x82,  0x88,  0xAF,  0x21,  0x02,  0x10,  0x21,  0x06,  0xFC,  0x61,  0x0B,  0x10,  0xBF,  0xE2, 	/* 09A10 */
+	0x20,  0x22,  0x82,  0x48,  0x27,  0xC3,  0xC4,  0xB1,  0x10,  0x01,  0x00,  0x3F,  0xE4,  0x4A,  0xB9,  0x21, 	/* 09A20 */
+	0x72,  0x44,  0xC2,  0x20,  0x49,  0x24,  0x91,  0x88,  0x50,  0x7C,  0xBA,  0x23,  0x02,  0x08,  0x20,  0x03, 	/* 09A30 */
+	0x30,  0x69,  0x26,  0xF4,  0xA3,  0x82,  0x34,  0x25,  0x23,  0x91,  0x21,  0x02,  0x30,  0x81,  0x11,  0x81, 	/* 09A40 */
+	0xE0,  0x22,  0x05,  0xFE,  0xC2,  0x04,  0x20,  0x5F,  0xC4,  0x00,  0x14,  0x05,  0x24,  0x90,  0xA0,  0xF8, 	/* 09A50 */
+	0x82,  0x24,  0x02,  0x40,  0x27,  0xE2,  0x82,  0x6F,  0xA7,  0x4A,  0xA7,  0xA2,  0x4A,  0x27,  0xA2,  0x02, 	/* 09A60 */
+	0x20,  0x22,  0x0C,  0x83,  0x21,  0x02,  0x10,  0x27,  0xC2,  0x10,  0x67,  0xE7,  0x08,  0xAF,  0xE2,  0x08, 	/* 09A70 */
+	0x24,  0x82,  0x28,  0x20,  0x82,  0x18,  0x86,  0x20,  0x02,  0xFE,  0x24,  0x02,  0x7C,  0x76,  0x47,  0x54, 	/* 09A80 */
+	0xA5,  0x42,  0xC8,  0x2A,  0x82,  0xA8,  0x20,  0x83,  0xFE,  0x8A,  0x42,  0x04,  0xFC,  0x42,  0x46,  0x24, 	/* 09A90 */
+	0xD4,  0x4C,  0x98,  0x48,  0x87,  0xFE,  0x54,  0xA5,  0x4A,  0x55,  0x26,  0x66,  0x8B,  0x04,  0x00,  0x40, 	/* 09AA0 */
+	0xFF,  0xF0,  0x90,  0x29,  0x42,  0x92,  0x4B,  0x28,  0x40,  0x12,  0x45,  0x02,  0x90,  0xA0,  0xF8,  0x8D, 	/* 09AB0 */
+	0x21,  0x02,  0x52,  0x25,  0x23,  0x34,  0x69,  0x06,  0xFE,  0xA2,  0x82,  0x28,  0x22,  0x82,  0x48,  0x24, 	/* 09AC0 */
+	0xA2,  0x86,  0x90,  0x07,  0x8F,  0xC8,  0x24,  0x82,  0x68,  0x3D,  0xAE,  0x4A,  0x08,  0x61,  0x40,  0x52, 	/* 09AD0 */
+	0x45,  0x22,  0x90,  0xA0,  0xF8,  0x92,  0x20,  0x02,  0xFE,  0x20,  0x02,  0x7C,  0x74,  0x46,  0xC4,  0xA7, 	/* 09AE0 */
+	0xC2,  0x44,  0x24,  0x42,  0x7C,  0x20,  0x02,  0xFF,  0x95,  0x20,  0x02,  0x1E,  0xFD,  0x22,  0x52,  0x69, 	/* 09AF0 */
+	0x21,  0x92,  0x25,  0xEC,  0x40,  0x52,  0x45,  0x02,  0x90,  0xA0,  0xF8,  0x99,  0x20,  0x81,  0x10,  0x7F, 	/* 09B00 */
+	0xC0,  0x40,  0x3F,  0x80,  0x40,  0xFF,  0xE0,  0x40,  0x52,  0x45,  0x22,  0x90,  0xA0,  0xF8,  0x9A,  0x04, 	/* 09B10 */
+	0x03,  0xF8,  0x04,  0x0F,  0xFE,  0x04,  0x03,  0xF8,  0x04,  0x0F,  0xFE,  0x14,  0x05,  0x24,  0x90,  0xA0, 	/* 09B20 */
+	0xF8,  0x9F,  0x24,  0x02,  0x40,  0x27,  0xE2,  0x82,  0x79,  0x26,  0x52,  0xAA,  0xA2,  0xDA,  0x28,  0xA2, 	/* 09B30 */
+	0xFA,  0x20,  0x22,  0x0C,  0xA0,  0x22,  0x02,  0x20,  0x2F,  0xE3,  0x40,  0x64,  0x86,  0x88,  0xBB,  0xE2, 	/* 09B40 */
+	0x88,  0x28,  0x82,  0x88,  0x2F,  0xE2,  0x80,  0xA2,  0x20,  0x02,  0x7E,  0x24,  0x82,  0x4A,  0x65,  0xA7, 	/* 09B50 */
+	0x5C,  0x6E,  0x8A,  0x48,  0x28,  0x82,  0x94,  0x36,  0x43,  0x82,  0xA3,  0x08,  0x06,  0x80,  0x0F,  0xE1, 	/* 09B60 */
+	0x24,  0x22,  0x0C,  0xD8,  0x30,  0x60,  0x80,  0x54,  0x85,  0x44,  0x91,  0x40,  0xF0,  0xA4,  0x21,  0x02, 	/* 09B70 */
+	0x20,  0x2F,  0xE2,  0xAA,  0x6A,  0xA7,  0xAA,  0xAA,  0xA2,  0xAA,  0x2A,  0xA2,  0xAA,  0x3F,  0xF2,  0x00, 	/* 09B80 */
+	0xA5,  0x01,  0x0F,  0xC8,  0x48,  0x44,  0x94,  0x79,  0x04,  0x92,  0x7B,  0x24,  0xD1,  0x4D,  0x1F,  0xD2, 	/* 09B90 */
+	0x09,  0x20,  0x8E,  0xA8,  0x20,  0x02,  0x7C,  0x24,  0x46,  0x7C,  0x74,  0x4A,  0xFC,  0xA6,  0x22,  0x54, 	/* 09BA0 */
+	0x25,  0x82,  0x48,  0x27,  0x42,  0xC2,  0xA9,  0x00,  0x07,  0xFC,  0x44,  0x47,  0xFC,  0x4A,  0x47,  0x1C, 	/* 09BB0 */
+	0x7F,  0xC1,  0x40,  0x52,  0x45,  0x22,  0x90,  0xA0,  0xF8,  0xAA,  0x22,  0x02,  0x3C,  0x24,  0x43,  0x68, 	/* 09BC0 */
+	0x69,  0x06,  0x28,  0xA4,  0x42,  0xFE,  0x34,  0x52,  0x44,  0x24,  0x42,  0x7C,  0xAB,  0x20,  0x02,  0xFE, 	/* 09BD0 */
+	0x28,  0x22,  0xBA,  0x78,  0x26,  0xBA,  0xAA,  0xA2,  0xAA,  0x2B,  0xA2,  0xA2,  0x28,  0x22,  0x86,  0xAC, 	/* 09BE0 */
+	0x20,  0xC2,  0xF0,  0x21,  0x02,  0x10,  0x7F,  0xE6,  0x10,  0xA1,  0x02,  0xFC,  0x28,  0x42,  0x84,  0x28, 	/* 09BF0 */
+	0x42,  0xFC,  0xAD,  0x11,  0x01,  0x10,  0x7F,  0xC1,  0x10,  0x11,  0x0F,  0xFE,  0x11,  0x02,  0x88,  0xEA, 	/* 09C00 */
+	0xE2,  0x94,  0x49,  0x41,  0x80,  0xAF,  0x08,  0x03,  0xF8,  0x20,  0x83,  0xF8,  0x20,  0x83,  0xF8,  0x20, 	/* 09C10 */
+	0x83,  0xF8,  0x54,  0x45,  0x22,  0x90,  0xA0,  0xF8,  0xB0,  0x21,  0x02,  0x10,  0x22,  0x82,  0x28,  0x74, 	/* 09C20 */
+	0x46,  0xBA,  0xB0,  0x02,  0x7C,  0x24,  0x42,  0x44,  0x24,  0x42,  0x7C,  0xB5,  0x04,  0x0F,  0xFE,  0x04, 	/* 09C30 */
+	0x03,  0xFC,  0x24,  0x43,  0xFC,  0x24,  0x43,  0xFC,  0x14,  0x05,  0x24,  0x90,  0xA0,  0xF8,  0xB7,  0x11, 	/* 09C40 */
+	0x01,  0x10,  0x3F,  0xE6,  0x58,  0xA9,  0x43,  0x12,  0x21,  0x02,  0x50,  0x52,  0x45,  0x22,  0x90,  0xA0, 	/* 09C50 */
+	0xF8,  0x81,  0x20,  0x02,  0x7E,  0x24,  0x22,  0x7E,  0x70,  0x06,  0xFE,  0xA4,  0x22,  0x7E,  0x24,  0x22, 	/* 09C60 */
+	0x7E,  0x24,  0x22,  0x46,  0x83,  0x20,  0x02,  0xFE,  0x29,  0x22,  0xFE,  0x79,  0x26,  0x9A,  0xAB,  0xA2, 	/* 09C70 */
+	0xB6,  0x2D,  0x62,  0x92,  0x29,  0x22,  0xFE,  0x84,  0x21,  0x02,  0x54,  0x25,  0x42,  0x92,  0x77,  0xC7, 	/* 09C80 */
+	0x44,  0xA7,  0xC2,  0x44,  0x27,  0xC2,  0x44,  0x24,  0x42,  0x4C,  0x89,  0x01,  0xC7,  0xE4,  0x24,  0x8F, 	/* 09C90 */
+	0xFE,  0x0E,  0x03,  0x58,  0xC4,  0x60,  0x20,  0x2A,  0x42,  0x82,  0x48,  0xA8,  0x78,  0x8B,  0x21,  0x02, 	/* 09CA0 */
+	0xFE,  0x24,  0x42,  0x38,  0x72,  0x86,  0xC4,  0xA8,  0x22,  0x7C,  0x24,  0x42,  0x44,  0x24,  0x42,  0x7C, 	/* 09CB0 */
+	0x8C,  0x24,  0x42,  0x28,  0x2F,  0xE2,  0x12,  0x77,  0xE6,  0x90,  0xAF,  0xE2,  0x32,  0x25,  0x22,  0x92, 	/* 09CC0 */
+	0x31,  0xC2,  0x10,  0x8D,  0x20,  0x02,  0xFC,  0x28,  0x42,  0xFC,  0x78,  0x46,  0xFC,  0xA0,  0x02,  0xFC, 	/* 09CD0 */
+	0x22,  0x03,  0xFE,  0x22,  0x02,  0x20,  0x92,  0x27,  0x82,  0x48,  0x27,  0x82,  0x00,  0x6F,  0xC7,  0xA4, 	/* 09CE0 */
+	0xAA,  0x42,  0xFC,  0x28,  0x02,  0x80,  0x28,  0x22,  0x7E,  0x94,  0x22,  0x02,  0x3E,  0x24,  0x02,  0xFC, 	/* 09CF0 */
+	0x65,  0x47,  0x54,  0xA7,  0xE2,  0x94,  0x29,  0x42,  0xFE,  0x20,  0x42,  0x18,  0x96,  0x21,  0x02,  0xFE, 	/* 09D00 */
+	0x21,  0x02,  0xFE,  0x78,  0x26,  0xBA,  0xA0,  0x82,  0x10,  0x2F,  0xE2,  0x10,  0x21,  0x02,  0x30,  0x97, 	/* 09D10 */
+	0x22,  0x02,  0x38,  0x24,  0x82,  0x90,  0x7F,  0xC6,  0x94,  0xA9,  0x42,  0xFC,  0x23,  0x02,  0x52,  0x29, 	/* 09D20 */
+	0x23,  0x0E,  0x9A,  0x21,  0x02,  0xFE,  0x21,  0x02,  0xFE,  0x79,  0x26,  0x92,  0xAF,  0xE2,  0x38,  0x23, 	/* 09D30 */
+	0x42,  0x52,  0x29,  0x12,  0x10,  0x9B,  0x21,  0x02,  0x24,  0x2F,  0xE2,  0x2A,  0x62,  0x87,  0x46,  0xAA, 	/* 09D40 */
+	0x02,  0x3C,  0x26,  0x42,  0x98,  0x22,  0x42,  0xC2,  0x9F,  0x20,  0x02,  0xFE,  0x21,  0x02,  0xFC,  0x62, 	/* 09D50 */
+	0x47,  0x24,  0xAF,  0xF2,  0x00,  0x27,  0xC2,  0x44,  0x24,  0x42,  0x7C,  0xA0,  0x22,  0x02,  0x20,  0x6B, 	/* 09D60 */
+	0xEA,  0xC4,  0x29,  0x42,  0x88,  0x29,  0x42,  0x62,  0x14,  0x05,  0x24,  0x90,  0xA0,  0xF8,  0xA3,  0x04, 	/* 09D70 */
+	0x03,  0xF8,  0x24,  0x83,  0xF8,  0x04,  0x07,  0xFC,  0x44,  0x47,  0xFC,  0x04,  0x05,  0x24,  0x90,  0xA0, 	/* 09D80 */
+	0xF8,  0xA6,  0x24,  0x42,  0x28,  0x27,  0xC7,  0x44,  0x6C,  0x4A,  0x44,  0xA7,  0xC2,  0x28,  0x22,  0x82, 	/* 09D90 */
+	0x4A,  0x28,  0xA3,  0x06,  0xA7,  0x23,  0x23,  0xCA,  0x24,  0xA3,  0xFA,  0x64,  0xA7,  0x6A,  0xAD,  0xA2, 	/* 09DA0 */
+	0xCA,  0x34,  0xA2,  0x42,  0x24,  0x22,  0x46,  0xA9,  0x22,  0x22,  0x92,  0x25,  0x42,  0x48,  0x70,  0x06, 	/* 09DB0 */
+	0xCA,  0xAA,  0xA2,  0x92,  0x2A,  0xA2,  0xCA,  0x28,  0x22,  0xFE,  0xAA,  0x00,  0x0F,  0xFE,  0x0A,  0x07, 	/* 09DC0 */
+	0xFC,  0x4A,  0x47,  0xFC,  0x0A,  0x0F,  0xFE,  0x54,  0x05,  0x24,  0x90,  0xA0,  0xF8,  0xB2,  0x0A,  0x07, 	/* 09DD0 */
+	0xBC,  0x0A,  0x07,  0xBC,  0x0A,  0x0F,  0xBE,  0x0A,  0x01,  0x20,  0x44,  0x45,  0x22,  0x90,  0xA0,  0xF8, 	/* 09DE0 */
+	0xB3,  0x04,  0x0F,  0xFE,  0x04,  0x0B,  0xF8,  0xA0,  0x8B,  0xF8,  0xA0,  0x8F,  0xFE,  0x04,  0x05,  0x24, 	/* 09DF0 */
+	0x90,  0xA0,  0xF8,  0xB4,  0x21,  0x02,  0xFE,  0x24,  0x42,  0x44,  0x6A,  0xA7,  0x12,  0xA1,  0x03,  0xFE, 	/* 09E00 */
+	0x21,  0x02,  0x10,  0x21,  0x02,  0x10,  0xB5,  0x20,  0x02,  0x7E,  0x24,  0x03,  0x7C,  0x6C,  0x06,  0x7C, 	/* 09E10 */
+	0xA4,  0x03,  0xFF,  0x25,  0x22,  0x4C,  0x25,  0x42,  0xE2,  0xB6,  0xFB,  0xE8,  0xA2,  0xFB,  0xE8,  0xA2, 	/* 09E20 */
+	0xFB,  0xE8,  0x42,  0x8A,  0x2A,  0x8A,  0xA8,  0x6C,  0x92,  0x87,  0x28,  0x06,  0xB8,  0x20,  0xC2,  0x70, 	/* 09E30 */
+	0x21,  0x02,  0xFE,  0x73,  0x86,  0xD6,  0xA1,  0x02,  0x7C,  0x20,  0x82,  0xFE,  0x21,  0x02,  0x30,  0xBC, 	/* 09E40 */
+	0x21,  0x02,  0x1E,  0x21,  0x02,  0xFC,  0x78,  0x46,  0xFC,  0xA8,  0x42,  0xFC,  0x21,  0x03,  0xFE,  0x21, 	/* 09E50 */
+	0x02,  0x10,  0xBD,  0x22,  0x03,  0xFE,  0x22,  0x02,  0xFC,  0x62,  0x47,  0xFE,  0xA2,  0x42,  0xFE,  0x24, 	/* 09E60 */
+	0x82,  0xC8,  0x23,  0x02,  0xCC,  0x85,  0x21,  0x02,  0xFE,  0x21,  0x02,  0xFC,  0x71,  0x06,  0xFF,  0xA4, 	/* 09E70 */
+	0x42,  0x7C,  0x24,  0x42,  0x7C,  0x24,  0x42,  0x4C,  0x86,  0x20,  0x02,  0xFE,  0x29,  0x22,  0xFA,  0x79, 	/* 09E80 */
+	0x26,  0xFE,  0xA9,  0x22,  0xBA,  0x2A,  0xA2,  0xBA,  0x30,  0x22,  0x06,  0x87,  0x21,  0x02,  0xFE,  0x20, 	/* 09E90 */
+	0x02,  0x7C,  0x74,  0x46,  0xFC,  0xA0,  0x02,  0x78,  0x21,  0x03,  0xFE,  0x21,  0x02,  0x30,  0x91,  0x02, 	/* 09EA0 */
+	0x80,  0x24,  0xFF,  0xE7,  0x94,  0x49,  0x87,  0xB0,  0x0C,  0xAF,  0x36,  0x14,  0x05,  0x24,  0x90,  0xA0, 	/* 09EB0 */
+	0xF8,  0x93,  0x21,  0x02,  0x54,  0x29,  0x22,  0x7C,  0x73,  0x06,  0xFE,  0xA4,  0x82,  0xFC,  0x34,  0xA2, 	/* 09EC0 */
+	0x58,  0x24,  0x22,  0x3E,  0x98,  0x20,  0x02,  0xFE,  0x2A,  0xA2,  0x92,  0x6F,  0xE7,  0x92,  0xAB,  0xE2, 	/* 09ED0 */
+	0xA2,  0x2A,  0x22,  0x9A,  0x30,  0x22,  0x06,  0x9A,  0x24,  0x02,  0x40,  0x27,  0xE6,  0xAA,  0x64,  0xAB, 	/* 09EE0 */
+	0x92,  0xA2,  0x42,  0x40,  0x2D,  0x42,  0xD2,  0x34,  0x62,  0x3C,  0x9C,  0x22,  0x42,  0x24,  0x27,  0xE3, 	/* 09EF0 */
+	0x24,  0x6F,  0xF6,  0x80,  0xA7,  0xC2,  0x44,  0x27,  0xC2,  0x44,  0x24,  0x42,  0x7C,  0x9F,  0x24,  0x42, 	/* 09F00 */
+	0x48,  0x27,  0xE6,  0xC8,  0x74,  0x8B,  0x7E,  0xA4,  0x82,  0x48,  0x27,  0xE2,  0x48,  0x24,  0x82,  0x7E, 	/* 09F10 */
+	0xA0,  0x04,  0x0F,  0xFE,  0x24,  0x83,  0xF8,  0x24,  0x83,  0xF8,  0x04,  0x8F,  0xFC,  0x04,  0x25,  0x24, 	/* 09F20 */
+	0x90,  0xA0,  0xF8,  0xA1,  0x00,  0x0F,  0xFE,  0x0A,  0x07,  0xBC,  0x40,  0x47,  0xBC,  0x0A,  0x0F,  0xFE, 	/* 09F30 */
+	0x04,  0x05,  0x24,  0x90,  0xA0,  0xF8,  0xA3,  0x52,  0x05,  0x20,  0x7F,  0xE9,  0x6A,  0x16,  0xA3,  0xAA, 	/* 09F40 */
+	0xD5,  0x21,  0x2C,  0x14,  0x05,  0x24,  0x90,  0xA0,  0xF8,  0xA7,  0x20,  0x02,  0x7C,  0x24,  0x42,  0x7C, 	/* 09F50 */
+	0x74,  0x46,  0xFC,  0xA4,  0x42,  0x7C,  0x24,  0x42,  0xFF,  0x22,  0x42,  0xC2,  0xA8,  0x22,  0x82,  0x48, 	/* 09F60 */
+	0x2F,  0xC6,  0x10,  0x6F,  0xEB,  0x30,  0xA4,  0x83,  0xA6,  0x2D,  0x02,  0x64,  0x21,  0x82,  0xE0,  0xB0, 	/* 09F70 */
+	0x22,  0x02,  0xFE,  0x22,  0x07,  0x7C,  0x69,  0x0A,  0xFE,  0xA4,  0x42,  0x7C,  0x24,  0x42,  0x7C,  0x24, 	/* 09F80 */
+	0x42,  0x4C,  0xB1,  0x25,  0x42,  0x54,  0x2A,  0x82,  0x54,  0x65,  0x47,  0x20,  0xAF,  0xE2,  0x8A,  0x2E, 	/* 09F90 */
+	0xA2,  0x9A,  0x2A,  0x62,  0xFE,  0xB3,  0x20,  0x0F,  0xFC,  0x24,  0x46,  0x7C,  0x74,  0x4A,  0xFC,  0xA4, 	/* 09FA0 */
+	0x42,  0x7C,  0x54,  0x05,  0x24,  0x91,  0x20,  0xF0,  0xB4,  0x21,  0x02,  0x92,  0x29,  0x22,  0xFE,  0x70, 	/* 09FB0 */
+	0x07,  0xFF,  0xA2,  0x02,  0xFE,  0x2A,  0xA2,  0xAA,  0x2A,  0xA2,  0x86,  0xB6,  0x22,  0x02,  0x7C,  0x24, 	/* 09FC0 */
+	0x42,  0x7C,  0x74,  0x46,  0xFC,  0xA0,  0x02,  0xFE,  0x21,  0x02,  0x7C,  0x21,  0x02,  0xFE,  0xB7,  0x04, 	/* 09FD0 */
+	0x07,  0xFC,  0x0A,  0x0F,  0xFF,  0x31,  0x85,  0xF4,  0x91,  0x21,  0xF0,  0x04,  0x05,  0x24,  0x90,  0xA0, 	/* 09FE0 */
+	0xF8,  0xB9,  0x11,  0x0F,  0xFE,  0x15,  0x0F,  0xFE,  0x08,  0x03,  0xF8,  0xD0,  0x81,  0xF8,  0x54,  0x05, 	/* 09FF0 */
+	0x24,  0x90,  0xA0,  0xF8,  0xBA,  0x20,  0x02,  0xFC,  0x28,  0x42,  0xFC,  0x78,  0x46,  0xFC,  0xA5,  0x02, 	/* 0A000 */
+	0xFE,  0x31,  0x02,  0x7C,  0x21,  0x03,  0xFE,  0xBB,  0x40,  0x25,  0xEA,  0x52,  0xAD,  0x2A,  0xFE,  0xAD, 	/* 0A010 */
+	0x2A,  0x5E,  0xA5,  0x2A,  0x5E,  0xA4,  0xC2,  0x52,  0x26,  0x06,  0x80,  0x22,  0x83,  0xC8,  0x24,  0xA2, 	/* 0A020 */
+	0x4A,  0x7E,  0xC6,  0x68,  0xAD,  0x82,  0xC8,  0x35,  0x42,  0x54,  0x26,  0x22,  0x41,  0x81,  0x31,  0x0E, 	/* 0A030 */
+	0x52,  0x25,  0x2F,  0x94,  0x21,  0x87,  0x24,  0xAC,  0x22,  0x20,  0x2A,  0x42,  0x82,  0x48,  0xA8,  0x78, 	/* 0A040 */
+	0x83,  0x21,  0x02,  0xFE,  0x28,  0x22,  0x7C,  0x70,  0x06,  0xFC,  0xA4,  0x42,  0x7C,  0x24,  0x42,  0x7C, 	/* 0A050 */
+	0x20,  0x02,  0xFE,  0x86,  0x4B,  0xCA,  0x40,  0x33,  0xE4,  0x88,  0xC4,  0x84,  0x88,  0x48,  0x84,  0x18, 	/* 0A060 */
+	0x14,  0x05,  0x24,  0x92,  0xA0,  0xF8,  0x88,  0x04,  0x00,  0xA0,  0x31,  0x8F,  0xD6,  0x25,  0x43,  0xD4, 	/* 0A070 */
+	0x24,  0x42,  0xCC,  0x14,  0x05,  0x24,  0x90,  0xA0,  0xF8,  0x89,  0x21,  0x02,  0x28,  0x24,  0x42,  0xBA, 	/* 0A080 */
+	0x70,  0x06,  0xEA,  0xAA,  0xA2,  0xEA,  0x2A,  0xA2,  0xEA,  0x2A,  0x22,  0xA6,  0x8D,  0x7D,  0x04,  0x50, 	/* 0A090 */
+	0x7D,  0xF5,  0x22,  0x7C,  0xC4,  0x8C,  0xE7,  0x20,  0x40,  0x52,  0x45,  0x22,  0x90,  0xA0,  0xF8,  0x8E, 	/* 0A0A0 */
+	0x24,  0x02,  0x7E,  0x2C,  0x46,  0x7C,  0x74,  0x4A,  0x7C,  0xA2,  0x02,  0x7C,  0x24,  0x43,  0xA8,  0x23, 	/* 0A0B0 */
+	0x83,  0xC6,  0x8F,  0x04,  0x07,  0xFC,  0x11,  0x0F,  0xFE,  0x20,  0x83,  0xF8,  0x20,  0x83,  0xF8,  0x54, 	/* 0A0C0 */
+	0x05,  0x24,  0x90,  0xA0,  0xF8,  0x95,  0x2E,  0xE2,  0xAA,  0x2E,  0xE2,  0x00,  0x77,  0xC6,  0x00,  0xBF, 	/* 0A0D0 */
+	0xF2,  0x20,  0x23,  0xC2,  0x44,  0x20,  0x42,  0x18,  0x9A,  0x3F,  0x82,  0x48,  0x3F,  0x82,  0x48,  0xFF, 	/* 0A0E0 */
+	0xE8,  0xA2,  0x97,  0x2B,  0x8A,  0x14,  0x65,  0x24,  0x90,  0xA0,  0xF8,  0x9B,  0x01,  0xC7,  0xE8,  0x15, 	/* 0A0F0 */
+	0x0F,  0xFE,  0x8A,  0x2A,  0x94,  0x27,  0xA5,  0xF2,  0x71,  0x00,  0xE0,  0x1B,  0x0E,  0x0E,  0x9F,  0x02, 	/* 0A100 */
+	0x47,  0xFE,  0x42,  0x07,  0xD4,  0x41,  0x47,  0xCA,  0xA5,  0x63,  0xE2,  0x04,  0x05,  0x24,  0x90,  0xA0, 	/* 0A110 */
+	0xF8,  0xA1,  0x24,  0x02,  0x40,  0x27,  0xE2,  0xAA,  0x76,  0xA6,  0x9A,  0xA2,  0x22,  0x4C,  0x26,  0x02, 	/* 0A120 */
+	0xD4,  0x34,  0x62,  0x3C,  0xA7,  0x21,  0x02,  0x20,  0x2F,  0xC3,  0xA4,  0x6F,  0xC6,  0xA4,  0xAF,  0xC2, 	/* 0A130 */
+	0x54,  0x25,  0xA2,  0x5E,  0x29,  0x13,  0x0F,  0xA8,  0x23,  0x8F,  0xA8,  0x22,  0xAF,  0xCE,  0x03,  0xCF, 	/* 0A140 */
+	0xA4,  0x89,  0x83,  0xE6,  0x54,  0x05,  0x22,  0x90,  0x90,  0xF8,  0xAC,  0x44,  0x02,  0x9E,  0xFF,  0x21, 	/* 0A150 */
+	0x1E,  0x55,  0x27,  0xDE,  0x12,  0x22,  0x46,  0x54,  0x05,  0x24,  0x90,  0xA0,  0xF8,  0xB4,  0x21,  0x02, 	/* 0A160 */
+	0x28,  0x24,  0x46,  0xBA,  0x74,  0x4A,  0x7C,  0xA4,  0x42,  0x7C,  0x24,  0x02,  0xBE,  0x2A,  0x22,  0x3E, 	/* 0A170 */
+	0xBC,  0x24,  0xC2,  0x70,  0x24,  0x26,  0x7E,  0x72,  0x4A,  0xBC,  0xAA,  0x42,  0xBC,  0x2A,  0x42,  0xFE, 	/* 0A180 */
+	0x23,  0x42,  0xC2,  0xBD,  0x21,  0x43,  0xFE,  0x29,  0x42,  0xFC,  0x79,  0x46,  0xFC,  0xA9,  0x42,  0x08, 	/* 0A190 */
+	0x3F,  0xE2,  0x88,  0x24,  0x82,  0x18,  0xBE,  0x48,  0x04,  0xFE,  0x50,  0x0C,  0xFC,  0xE0,  0x0F,  0xFC, 	/* 0A1A0 */
+	0x55,  0x44,  0xE4,  0x5F,  0xC4,  0x64,  0x4D,  0x25,  0x42,  0xBF,  0x00,  0x07,  0xFE,  0x44,  0x05,  0xFC, 	/* 0A1B0 */
+	0x50,  0x45,  0xFC,  0x4A,  0x85,  0x24,  0x82,  0x05,  0x44,  0x52,  0xA8,  0xF8,  0x82,  0x4F,  0xE2,  0x24, 	/* 0A1C0 */
+	0x81,  0x84,  0xFE,  0x09,  0x22,  0xFE,  0x49,  0x28,  0x96,  0x44,  0x05,  0x24,  0x90,  0xA0,  0xF8,  0x84, 	/* 0A1D0 */
+	0x20,  0x02,  0xFE,  0x22,  0x82,  0xFE,  0x7A,  0xA6,  0xFE,  0xA1,  0x02,  0xFE,  0x23,  0x82,  0x54,  0x39, 	/* 0A1E0 */
+	0x22,  0x10,  0x87,  0x19,  0xC6,  0x14,  0x7A,  0x64,  0x80,  0x7B,  0xE4,  0xA4,  0x79,  0x84,  0x98,  0x8E, 	/* 0A1F0 */
+	0x65,  0x44,  0x52,  0xA8,  0xFA,  0x88,  0x21,  0x01,  0x20,  0xFF,  0xE2,  0x10,  0x52,  0x8A,  0x50,  0x4A, 	/* 0A200 */
+	0x4F,  0xBC,  0x54,  0x05,  0x24,  0x90,  0xA0,  0xF8,  0x8A,  0x22,  0x42,  0x48,  0x3F,  0xE2,  0x50,  0x6F, 	/* 0A210 */
+	0xC7,  0x54,  0xBF,  0xE2,  0x54,  0x3F,  0xC2,  0xD8,  0x35,  0x42,  0x50,  0x8B,  0x22,  0x44,  0xB8,  0xFA, 	/* 0A220 */
+	0x24,  0xDE,  0x7A,  0x44,  0xB8,  0x7A,  0x24,  0x9E,  0x14,  0x05,  0x24,  0x90,  0xA0,  0xF8,  0x8C,  0x24, 	/* 0A230 */
+	0x42,  0xFE,  0x24,  0x46,  0x10,  0x7F,  0xEB,  0x40,  0xA3,  0xC2,  0xA8,  0x2A,  0x82,  0xA8,  0x2A,  0xA3, 	/* 0A240 */
+	0x06,  0x8D,  0x20,  0x02,  0xFC,  0x29,  0x42,  0xB4,  0x7C,  0xC6,  0xFC,  0xA0,  0x02,  0xFE,  0x2A,  0xA2, 	/* 0A250 */
+	0xAA,  0x2A,  0xA3,  0xFF,  0x8E,  0x21,  0x02,  0xFE,  0x21,  0x02,  0x7C,  0x74,  0x46,  0xFC,  0xA4,  0x42, 	/* 0A260 */
+	0x7C,  0x24,  0x43,  0xFE,  0x22,  0x82,  0xC4,  0x93,  0x2F,  0xE2,  0x28,  0x2F,  0xE3,  0xAA,  0x6F,  0xE6, 	/* 0A270 */
+	0x00,  0xAF,  0xC2,  0x00,  0x2F,  0xE2,  0x54,  0x29,  0x22,  0x30,  0x95,  0x11,  0x0F,  0xFE,  0x11,  0x03, 	/* 0A280 */
+	0xF8,  0x20,  0x83,  0xF8,  0x20,  0x8F,  0xFE,  0x28,  0x85,  0xD4,  0xAA,  0xA1,  0x80,  0x98,  0x21,  0x02, 	/* 0A290 */
+	0x28,  0x2F,  0xC2,  0x48,  0x6B,  0x47,  0xFE,  0xA2,  0x82,  0x4C,  0x39,  0x32,  0x64,  0x21,  0x82,  0xE0, 	/* 0A2A0 */
+	0x99,  0x10,  0x4F,  0xF8,  0x55,  0x07,  0xDF,  0x55,  0x4F,  0xF4,  0x11,  0x41,  0x24,  0x54,  0x05,  0x24, 	/* 0A2B0 */
+	0x90,  0xA0,  0xF8,  0x9A,  0x44,  0x25,  0xFC,  0x45,  0x05,  0xF0,  0xF5,  0xFD,  0xF4,  0xD5,  0x45,  0xF4, 	/* 0A2C0 */
+	0x45,  0x45,  0xF4,  0x45,  0x44,  0x64,  0x9D,  0x7F,  0xE4,  0x90,  0x7F,  0xE4,  0x90,  0x7F,  0xE4,  0x80, 	/* 0A2D0 */
+	0x57,  0xC6,  0x44,  0x7F,  0xE5,  0x44,  0x90,  0xA0,  0xF8,  0x9F,  0x46,  0x87,  0x88,  0x49,  0xE7,  0xEA, 	/* 0A2E0 */
+	0xEA,  0xAF,  0xEA,  0x6A,  0xA7,  0xEA,  0x48,  0xA5,  0xEA,  0x4D,  0x27,  0xAC,  0xA2,  0x27,  0xC2,  0x44, 	/* 0A2F0 */
+	0x27,  0xC6,  0x44,  0x7F,  0xEA,  0xAA,  0xAF,  0xE2,  0x00,  0x2F,  0xC2,  0x44,  0x23,  0x83,  0xC6,  0xA3, 	/* 0A300 */
+	0x23,  0xE2,  0x2A,  0x2F,  0xE7,  0x54,  0x6F,  0xCA,  0x7E,  0xA4,  0x22,  0x7E,  0x24,  0x22,  0x7E,  0x22, 	/* 0A310 */
+	0x42,  0xC2,  0xA5,  0x22,  0x82,  0xA8,  0x27,  0xE3,  0x28,  0x6C,  0x86,  0x3E,  0xB8,  0x82,  0xBE,  0x2A, 	/* 0A320 */
+	0x22,  0xFE,  0x32,  0x02,  0x1F,  0xA7,  0xFB,  0xC2,  0x10,  0xFF,  0xC2,  0x10,  0x7F,  0xC0,  0x08,  0x7F, 	/* 0A330 */
+	0x80,  0x08,  0x7F,  0x85,  0x44,  0x92,  0xA0,  0xF8,  0xA8,  0x20,  0x02,  0xEE,  0x2A,  0xA2,  0xEA,  0x7A, 	/* 0A340 */
+	0xA6,  0xBF,  0xAE,  0x42,  0xC4,  0x2A,  0xC2,  0xED,  0x39,  0x52,  0x23,  0xAB,  0x24,  0x42,  0x44,  0x4A, 	/* 0A350 */
+	0xAB,  0x11,  0x29,  0xC6,  0x90,  0xAD,  0x03,  0x3E,  0x54,  0x05,  0x24,  0x90,  0xA0,  0xF8,  0xAE,  0x07, 	/* 0A360 */
+	0x80,  0x40,  0x7F,  0xE4,  0x72,  0x7C,  0x05,  0x3E,  0x5F,  0xC5,  0x24,  0x5F,  0xC4,  0xA4,  0x98,  0xAA, 	/* 0A370 */
+	0x78,  0xAF,  0x24,  0x02,  0x7E,  0x24,  0x42,  0xFC,  0x74,  0x46,  0x7C,  0xBF,  0xF2,  0x40,  0x27,  0xE2, 	/* 0A380 */
+	0xAA,  0x25,  0x22,  0xAC,  0xB0,  0x7C,  0x44,  0x44,  0x7F,  0xE4,  0x24,  0x7D,  0x44,  0x84,  0xAA,  0x4A, 	/* 0A390 */
+	0xAC,  0x14,  0x05,  0x24,  0x90,  0xA0,  0xF8,  0xB1,  0x21,  0x42,  0xFE,  0x25,  0x42,  0x7C,  0x75,  0x46, 	/* 0A3A0 */
+	0xFE,  0xA1,  0x42,  0xFE,  0x20,  0x83,  0xFE,  0x24,  0x82,  0x18,  0xB3,  0x20,  0x02,  0xFE,  0x2A,  0x22, 	/* 0A3B0 */
+	0xFA,  0x79,  0xA6,  0xF4,  0xAA,  0xA2,  0xF1,  0x21,  0x02,  0x7C,  0x21,  0x03,  0xFE,  0xB4,  0x2E,  0xE2, 	/* 0A3C0 */
+	0x22,  0x26,  0x62,  0xAA,  0x77,  0x67,  0xAA,  0xA3,  0x22,  0x7C,  0x24,  0x42,  0x7C,  0x24,  0x42,  0x7C, 	/* 0A3D0 */
+	0xB5,  0x21,  0x02,  0xFE,  0x29,  0x02,  0xFC,  0x79,  0x46,  0xFE,  0xA9,  0x42,  0xFC,  0x2D,  0x42,  0xFC, 	/* 0A3E0 */
+	0x35,  0x42,  0x4C,  0xB6,  0x04,  0x07,  0xFE,  0x49,  0x07,  0xFC,  0x49,  0x47,  0xFE,  0x5A,  0x46,  0x7A, 	/* 0A3F0 */
+	0x49,  0x2B,  0x60,  0x89,  0x87,  0x06,  0xB7,  0x21,  0x02,  0xFE,  0x29,  0x02,  0xFC,  0x79,  0x46,  0xFE, 	/* 0A400 */
+	0xA9,  0x42,  0xFC,  0x2D,  0x42,  0xB8,  0x35,  0x62,  0x10,  0xBE,  0x2A,  0x0D,  0x7E,  0x2B,  0x24,  0x54, 	/* 0A410 */
+	0xFD,  0x04,  0xA8,  0x7C,  0x60,  0x40,  0x52,  0x45,  0x22,  0x90,  0xA0,  0xF8,  0x82,  0x7F,  0xC0,  0x80, 	/* 0A420 */
+	0x1F,  0x01,  0x10,  0xFF,  0xEA,  0xAA,  0x49,  0x41,  0xFA,  0x19,  0x06,  0x60,  0x1B,  0x0E,  0x0E,  0x87, 	/* 0A430 */
+	0x1A,  0x4E,  0x24,  0x27,  0xEF,  0xA4,  0x23,  0xC7,  0xA4,  0x4A,  0x47,  0xBC,  0x14,  0x05,  0x24,  0x90, 	/* 0A440 */
+	0xA0,  0xF8,  0x8A,  0x22,  0x42,  0xFE,  0x42,  0x45,  0xFF,  0xD4,  0xA5,  0x7E,  0x54,  0xA6,  0x7E,  0x44, 	/* 0A450 */
+	0xA5,  0x22,  0x52,  0x98,  0xF8,  0x8E,  0x24,  0x42,  0x28,  0x2F,  0xE6,  0x92,  0x7F,  0xEA,  0x92,  0xAF, 	/* 0A460 */
+	0xE2,  0x44,  0x27,  0xC2,  0x44,  0x24,  0x42,  0x7C,  0x90,  0x29,  0x22,  0x54,  0x2F,  0xE6,  0x38,  0x75, 	/* 0A470 */
+	0x4A,  0x92,  0xA4,  0x42,  0x7E,  0x2B,  0x43,  0x3E,  0x24,  0x43,  0x84,  0x91,  0x8F,  0xE4,  0x90,  0x4F, 	/* 0A480 */
+	0xC0,  0x90,  0x2F,  0xE5,  0x52,  0x92,  0xA2,  0x0C,  0x14,  0x05,  0x22,  0x50,  0x98,  0xF9,  0x94,  0x22, 	/* 0A490 */
+	0x42,  0x28,  0x27,  0xE2,  0xC8,  0x77,  0xE6,  0xC8,  0xA7,  0xE2,  0x48,  0x27,  0xE2,  0x00,  0x26,  0xA2, 	/* 0A4A0 */
+	0x95,  0x96,  0x10,  0xCF,  0xCA,  0x54,  0x8B,  0x7E,  0x38,  0x85,  0x58,  0x92,  0x41,  0x42,  0x54,  0x05, 	/* 0A4B0 */
+	0x24,  0x90,  0xA0,  0xF8,  0x99,  0x04,  0x0F,  0xFE,  0x04,  0x07,  0xFC,  0x20,  0x83,  0xF8,  0xFF,  0xE2, 	/* 0A4C0 */
+	0x08,  0x3F,  0x85,  0x44,  0x90,  0xA0,  0xF8,  0x9A,  0x27,  0xE2,  0x5A,  0x27,  0xE2,  0x00,  0x77,  0xE6, 	/* 0A4D0 */
+	0xD2,  0xA7,  0xE2,  0x52,  0x2F,  0xF2,  0x10,  0x21,  0x02,  0x10,  0xA4,  0x22,  0x03,  0xFC,  0x2A,  0x87, 	/* 0A4E0 */
+	0xFE,  0x64,  0x8A,  0xFC,  0xA8,  0x42,  0xFC,  0x28,  0x42,  0xFC,  0x24,  0x43,  0x82,  0xA7,  0x21,  0x02, 	/* 0A4F0 */
+	0xFE,  0x24,  0x87,  0xFE,  0x68,  0x0A,  0x7C,  0xA5,  0x42,  0x7C,  0x25,  0x42,  0xFE,  0x21,  0x03,  0xFF, 	/* 0A500 */
+	0xA9,  0x19,  0x0E,  0x3C,  0x22,  0x4F,  0xBC,  0x22,  0x47,  0xBC,  0x4A,  0x47,  0xBC,  0x14,  0x05,  0x24, 	/* 0A510 */
+	0x90,  0xA0,  0xF8,  0xAB,  0x2E,  0xE2,  0xAA,  0x2E,  0xE2,  0xAA,  0x6E,  0xE7,  0x92,  0xAF,  0xE2,  0xAA, 	/* 0A520 */
+	0x2A,  0xA2,  0x92,  0x2A,  0xA2,  0xC6,  0xAC,  0x27,  0xC2,  0x44,  0x27,  0xC2,  0x44,  0x7F,  0xE6,  0x10, 	/* 0A530 */
+	0xAF,  0xE2,  0x44,  0x27,  0xC2,  0x94,  0x31,  0x22,  0x30,  0xAE,  0x28,  0x02,  0xFE,  0x2D,  0x43,  0x54, 	/* 0A540 */
+	0x6F,  0xE6,  0x54,  0xA5,  0x42,  0xFE,  0x20,  0x02,  0x94,  0x2A,  0xA3,  0x2A,  0xB2,  0x04,  0x0F,  0xFE, 	/* 0A550 */
+	0x84,  0x2B,  0xFA,  0x04,  0x0F,  0xFE,  0x4A,  0x47,  0xFC,  0x54,  0x05,  0x24,  0x90,  0xA0,  0xF8,  0xB6, 	/* 0A560 */
+	0x22,  0x02,  0xFC,  0x24,  0x83,  0xFE,  0x68,  0x46,  0xFC,  0xA8,  0x42,  0xFC,  0x25,  0x02,  0xD4,  0x34, 	/* 0A570 */
+	0xA2,  0x3A,  0xBA,  0x27,  0x82,  0x90,  0x3F,  0xE6,  0xA8,  0x7C,  0xEA,  0xB8,  0x28,  0x02,  0xFE,  0x28, 	/* 0A580 */
+	0x02,  0xFC,  0x34,  0x42,  0x7C,  0xBE,  0x40,  0xA4,  0xFE,  0x68,  0x85,  0xFA,  0xCE,  0x4C,  0xAC,  0xDF, 	/* 0A590 */
+	0x66,  0x22,  0x45,  0x05,  0x4A,  0x64,  0x24,  0x3E,  0x83,  0x48,  0x8F,  0xE8,  0x57,  0xE7,  0xCA,  0x10, 	/* 0A5A0 */
+	0xA7,  0xD2,  0x12,  0x2F,  0xCC,  0x14,  0x05,  0x24,  0x90,  0xA0,  0xF8,  0x86,  0x27,  0xC2,  0x44,  0x27, 	/* 0A5B0 */
+	0xC2,  0xEE,  0x7A,  0xA6,  0xEE,  0xA1,  0x02,  0xFE,  0x23,  0x82,  0x54,  0x29,  0x32,  0x10,  0x87,  0x0B, 	/* 0A5C0 */
+	0xCF,  0x24,  0x57,  0xCF,  0xA4,  0x33,  0xCD,  0xAA,  0x2B,  0x4D,  0x62,  0x14,  0x05,  0x24,  0x90,  0xA0, 	/* 0A5D0 */
+	0xF8,  0x88,  0x48,  0x04,  0xFE,  0x54,  0xA7,  0xFA,  0xD5,  0x6D,  0xF0,  0x55,  0xE5,  0xF4,  0x51,  0x45, 	/* 0A5E0 */
+	0x1E,  0x61,  0x44,  0x34,  0x89,  0x02,  0x07,  0xFE,  0x4A,  0x85,  0x7E,  0x7C,  0x85,  0x7E,  0x54,  0x85, 	/* 0A5F0 */
+	0x7E,  0x4A,  0x0A,  0x94,  0xA8,  0xA4,  0x7A,  0x8A,  0x22,  0x02,  0x40,  0x2F,  0xE2,  0xD6,  0x7B,  0xA6, 	/* 0A600 */
+	0xFE,  0xAB,  0xA2,  0xD6,  0x29,  0x23,  0xFF,  0x22,  0x82,  0xC6,  0x8B,  0x2E,  0x82,  0xA8,  0xF5,  0xE3, 	/* 0A610 */
+	0xF8,  0x6E,  0xC7,  0x5A,  0xA6,  0xA2,  0x48,  0x14,  0x05,  0x24,  0x90,  0xA0,  0xF8,  0x8C,  0x2F,  0xE2, 	/* 0A620 */
+	0xAA,  0x2F,  0xE3,  0x10,  0x6F,  0xE6,  0x10,  0xBF,  0xF2,  0x44,  0x3F,  0xF2,  0x10,  0x2F,  0xE2,  0x10, 	/* 0A630 */
+	0x8D,  0x21,  0x03,  0xFF,  0x2A,  0xA2,  0xBA,  0x78,  0x26,  0xFE,  0xA7,  0x82,  0x10,  0x2F,  0xE2,  0x5C, 	/* 0A640 */
+	0x39,  0x32,  0x10,  0x90,  0x21,  0x02,  0xFE,  0x21,  0x03,  0xFE,  0x6A,  0xA6,  0xFE,  0xA1,  0x03,  0xFF, 	/* 0A650 */
+	0x25,  0x42,  0xC8,  0x37,  0x42,  0xC2,  0xA3,  0x48,  0x83,  0xFE,  0x88,  0x84,  0xF8,  0x3F,  0xE6,  0xAA, 	/* 0A660 */
+	0xAA,  0xAB,  0x76,  0x22,  0x65,  0x44,  0x52,  0xA8,  0xFA,  0xA6,  0x27,  0xC2,  0x10,  0x2F,  0xE3,  0x92, 	/* 0A670 */
+	0x6D,  0xA6,  0x00,  0xAF,  0xE2,  0x40,  0x2F,  0xE2,  0xAA,  0x2A,  0xA2,  0x86,  0xB2,  0x24,  0x8D,  0x5E, 	/* 0A680 */
+	0x3F,  0x4C,  0x54,  0x5E,  0xC4,  0x48,  0x5F,  0x44,  0x22,  0x14,  0x05,  0x24,  0x50,  0xA8,  0xFA,  0xB4, 	/* 0A690 */
+	0x44,  0x84,  0x4C,  0x5F,  0xAC,  0x4E,  0xFF,  0x8C,  0xA8,  0x5B,  0xA4,  0xAA,  0x5B,  0x44,  0xA6,  0x4B, 	/* 0A6A0 */
+	0xA7,  0xC2,  0xB6,  0x49,  0xE4,  0x8A,  0x5E,  0xAC,  0x96,  0xFE,  0x0E,  0xBE,  0x7F,  0x25,  0x9E,  0x5D, 	/* 0A6B0 */
+	0x26,  0xBE,  0x49,  0x44,  0xA2,  0xB7,  0x21,  0x03,  0xFF,  0x2A,  0xA2,  0xFE,  0x71,  0x06,  0xD6,  0xA1, 	/* 0A6C0 */
+	0x02,  0xD6,  0x26,  0x22,  0xD4,  0x34,  0x82,  0x66,  0xB8,  0x39,  0xCA,  0xF0,  0xB9,  0x4A,  0xE8,  0xB9, 	/* 0A6D0 */
+	0x48,  0x7E,  0xF9,  0x02,  0xD4,  0xA5,  0x21,  0x24,  0x50,  0xA8,  0xFA,  0xBA,  0x52,  0x85,  0x2C,  0x6D, 	/* 0A6E0 */
+	0xAC,  0x0E,  0xFF,  0x8C,  0xAA,  0x5B,  0xA4,  0xAC,  0x5B,  0x44,  0xAE,  0x4B,  0xA7,  0xC2,  0xBC,  0x20, 	/* 0A6F0 */
+	0x02,  0xEE,  0x2A,  0xA2,  0xEE,  0x7A,  0xA6,  0xEE,  0xA2,  0x42,  0x7E,  0x2C,  0x82,  0x7E,  0x24,  0x82, 	/* 0A700 */
+	0x7E,  0xBD,  0x22,  0x82,  0xFE,  0x22,  0x82,  0xEE,  0x7A,  0xA6,  0xEE,  0xA2,  0x42,  0x7E,  0x2C,  0x82, 	/* 0A710 */
+	0x7E,  0x24,  0x82,  0x7E,  0xBE,  0x2F,  0xE2,  0x44,  0x27,  0xC2,  0x44,  0x7F,  0xE6,  0x04,  0xBF,  0xE2, 	/* 0A720 */
+	0xAA,  0x2E,  0xE2,  0xAB,  0x3F,  0xE2,  0x22,  0xBF,  0x21,  0x0F,  0xDE,  0x22,  0xAF,  0x88,  0x8A,  0x87, 	/* 0A730 */
+	0xD4,  0x4A,  0x27,  0x98,  0x4B,  0x53,  0x51,  0x39,  0x2E,  0x0E,  0x80,  0x44,  0x8A,  0xF4,  0x50,  0xAF, 	/* 0A740 */
+	0xDE,  0x20,  0x8A,  0xEC,  0xBA,  0xA2,  0xE8,  0x14,  0x05,  0x24,  0x90,  0xA0,  0xF8,  0x88,  0x04,  0x00, 	/* 0A750 */
+	0x48,  0x04,  0x4F,  0xFE,  0x04,  0x00,  0x48,  0x02,  0x80,  0x30,  0x05,  0x01,  0x8A,  0x60,  0x60,  0x02, 	/* 0A760 */
+	0x89,  0x04,  0x80,  0x44,  0x7F,  0xE4,  0x40,  0x44,  0x04,  0x44,  0x42,  0x44,  0xA8,  0x71,  0x0C,  0x2A, 	/* 0A770 */
+	0x0C,  0x63,  0x02,  0x8A,  0x02,  0x00,  0x24,  0x02,  0x23,  0xFE,  0x22,  0x02,  0x24,  0x22,  0x42,  0x28, 	/* 0A780 */
+	0x21,  0x04,  0x2A,  0x44,  0x69,  0x82,  0x8C,  0x02,  0x80,  0x24,  0x7F,  0xE4,  0x20,  0x42,  0x04,  0x24, 	/* 0A790 */
+	0x7A,  0x44,  0x18,  0x41,  0x24,  0x2A,  0x8C,  0x6B,  0x02,  0x8D,  0x02,  0x80,  0x24,  0x7F,  0xE4,  0x20, 	/* 0A7A0 */
+	0x42,  0x05,  0x24,  0x4A,  0x44,  0x98,  0x41,  0x24,  0x2A,  0x8C,  0x6B,  0x02,  0x8E,  0x02,  0x00,  0x28, 	/* 0A7B0 */
+	0x02,  0x4F,  0xFE,  0x12,  0x01,  0x24,  0x1D,  0x4F,  0x18,  0x13,  0x02,  0x4A,  0x28,  0x64,  0x02,  0x90, 	/* 0A7C0 */
+	0x02,  0x80,  0x24,  0x7F,  0xE4,  0x20,  0x42,  0x47,  0xA4,  0x4A,  0x84,  0x98,  0x49,  0x06,  0xAA,  0x54, 	/* 0A7D0 */
+	0x68,  0x82,  0x91,  0x0A,  0x07,  0x28,  0x12,  0x41,  0x20,  0xFF,  0xE1,  0x24,  0x12,  0x41,  0xD4,  0xF1, 	/* 0A7E0 */
+	0x81,  0x2A,  0x14,  0x63,  0x02,  0x92,  0x02,  0x80,  0x24,  0xFF,  0xE0,  0x20,  0x2A,  0x42,  0xA4,  0xFE, 	/* 0A7F0 */
+	0x82,  0x98,  0x29,  0x04,  0xAA,  0x8C,  0x60,  0x82,  0x94,  0x08,  0x8F,  0xFE,  0x05,  0x00,  0x22,  0x0D, 	/* 0A800 */
+	0xA7,  0x06,  0x08,  0x8F,  0xFF,  0x04,  0x80,  0x32,  0x0C,  0xE7,  0x02,  0x96,  0x02,  0x80,  0x24,  0xFF, 	/* 0A810 */
+	0xE0,  0x20,  0x7A,  0x44,  0xA4,  0x4A,  0x47,  0x98,  0x01,  0x81,  0xAA,  0xE4,  0x61,  0x82,  0x9A,  0x01, 	/* 0A820 */
+	0x40,  0x12,  0x7F,  0xF4,  0x90,  0x4F,  0x24,  0x92,  0x7F,  0xA4,  0x8A,  0x5A,  0x46,  0xAD,  0xA9,  0x38, 	/* 0A830 */
+	0xA1,  0x9B,  0xFF,  0xE0,  0x80,  0x7F,  0xC4,  0x04,  0x7F,  0xC4,  0x04,  0x7F,  0xC0,  0x84,  0xFF,  0xE0, 	/* 0A840 */
+	0x58,  0x0F,  0x27,  0x0E,  0x9D,  0x01,  0x07,  0x94,  0x49,  0x24,  0x9E,  0x7F,  0x04,  0x92,  0x79,  0x24, 	/* 0A850 */
+	0x8C,  0x78,  0x83,  0x1A,  0x4A,  0x68,  0x42,  0x9E,  0xFF,  0xE0,  0x80,  0x3F,  0x82,  0x08,  0x3F,  0x82, 	/* 0A860 */
+	0x08,  0xFF,  0xE8,  0x92,  0x7F,  0xC0,  0x48,  0x0F,  0x27,  0x0E,  0x9F,  0x21,  0x0F,  0x98,  0x21,  0x4F, 	/* 0A870 */
+	0x9E,  0x8F,  0x0F,  0x94,  0x89,  0x4F,  0x98,  0x20,  0x8F,  0x9A,  0x22,  0x62,  0x42,  0xA1,  0x49,  0x4F, 	/* 0A880 */
+	0xD2,  0x49,  0xE7,  0xF0,  0x49,  0x47,  0x94,  0x49,  0x4F,  0xD8,  0xA8,  0x8C,  0xDA,  0x82,  0x67,  0xC2, 	/* 0A890 */
+	0xA6,  0x25,  0x49,  0x52,  0x49,  0x07,  0xDE,  0x57,  0x07,  0xD4,  0x55,  0x47,  0xC8,  0x11,  0x8F,  0xEA, 	/* 0A8A0 */
+	0x12,  0x61,  0x42,  0xAA,  0x10,  0x87,  0xCC,  0x10,  0xAF,  0xFF,  0x24,  0x87,  0xEA,  0x48,  0xAF,  0xEC, 	/* 0A8B0 */
+	0x48,  0x47,  0xED,  0x49,  0x37,  0xE1,  0xAE,  0xFD,  0x46,  0xD2,  0xB5,  0x06,  0xFE,  0xB5,  0x01,  0x94, 	/* 0A8C0 */
+	0x25,  0x4C,  0xAC,  0x10,  0x86,  0x4A,  0x19,  0x6E,  0x22,  0xAF,  0x1D,  0x01,  0x14,  0x7D,  0x25,  0x50, 	/* 0A8D0 */
+	0x53,  0xE5,  0xD0,  0x41,  0x25,  0x4A,  0x74,  0xC5,  0x6A,  0x99,  0x66,  0x22,  0xB0,  0xEE,  0xCA,  0xAA, 	/* 0A8E0 */
+	0xEE,  0x87,  0xFF,  0x54,  0x87,  0xCA,  0x54,  0xA7,  0xCC,  0x10,  0x4F,  0xED,  0x11,  0x31,  0x21,  0xB2, 	/* 0A8F0 */
+	0x20,  0xC3,  0xCA,  0x20,  0x87,  0xFF,  0x50,  0x85,  0xCA,  0x64,  0xA7,  0xCA,  0x44,  0x45,  0x4D,  0x89, 	/* 0A900 */
+	0x3B,  0xE1,  0xB3,  0xEE,  0xC6,  0x6A,  0xAA,  0x86,  0x7F,  0xAA,  0x84,  0x4A,  0x48,  0xA7,  0xEC,  0xC8, 	/* 0A910 */
+	0x47,  0xED,  0x49,  0x37,  0xE1,  0xB4,  0x11,  0x07,  0xD4,  0x11,  0x2F,  0xFE,  0x55,  0x07,  0xD2,  0x29, 	/* 0A920 */
+	0x27,  0xD4,  0x28,  0x8F,  0xDA,  0x2A,  0x6C,  0x42,  0xB8,  0x00,  0x07,  0xFE,  0x00,  0x03,  0xFC,  0x20, 	/* 0A930 */
+	0x42,  0x04,  0x3F,  0xC2,  0x00,  0x20,  0x04,  0x00,  0x40,  0x08,  0x00,  0xBB,  0x00,  0x07,  0xFE,  0x00, 	/* 0A940 */
+	0x03,  0xFC,  0x20,  0x43,  0xFC,  0x22,  0x03,  0xFE,  0x42,  0x04,  0x50,  0x88,  0x83,  0x06,  0xBF,  0x7F, 	/* 0A950 */
+	0xE0,  0x00,  0x3F,  0xC2,  0x04,  0x3F,  0xC2,  0x20,  0x3F,  0xE2,  0x40,  0x47,  0xC4,  0x84,  0x90,  0x46, 	/* 0A960 */
+	0x18,  0x80,  0x00,  0x6F,  0xB8,  0x02,  0x07,  0xA0,  0x4B,  0xF4,  0xA4,  0x7A,  0x44,  0x24,  0x44,  0x44, 	/* 0A970 */
+	0x44,  0x88,  0x48,  0x04,  0x81,  0x7F,  0xE0,  0x00,  0x3F,  0xC2,  0x04,  0x3F,  0xC2,  0x00,  0x3F,  0xC3, 	/* 0A980 */
+	0x54,  0x5F,  0xC5,  0x54,  0x95,  0x41,  0x0C,  0x87,  0xFF,  0xE0,  0x00,  0x7F,  0xC4,  0x04,  0x7F,  0xC4, 	/* 0A990 */
+	0x00,  0x5D,  0xE4,  0x42,  0x75,  0xA4,  0xC6,  0xB5,  0xA8,  0xC6,  0x88,  0x00,  0x0F,  0xFE,  0x40,  0x47, 	/* 0A9A0 */
+	0xFC,  0x4F,  0x84,  0x88,  0x5F,  0xC5,  0x24,  0x5F,  0xC9,  0x00,  0x90,  0x20,  0xFE,  0x89,  0x3F,  0xE0, 	/* 0A9B0 */
+	0x00,  0x3F,  0xE2,  0x02,  0x3F,  0xE2,  0x50,  0x3D,  0xE2,  0x50,  0x5D,  0xE4,  0x50,  0xBD,  0xE0,  0x90, 	/* 0A9C0 */
+	0x8B,  0x00,  0x80,  0x30,  0x3C,  0x00,  0x40,  0x7F,  0xC0,  0x40,  0x04,  0x0F,  0xFE,  0x04,  0x00,  0x40, 	/* 0A9D0 */
+	0x04,  0x00,  0xC0,  0x8D,  0x02,  0x00,  0x20,  0x02,  0x0F,  0xFE,  0x02,  0x00,  0x28,  0x03,  0x00,  0x60, 	/* 0A9E0 */
+	0x1A,  0x06,  0x20,  0x02,  0x00,  0x60,  0x8E,  0x22,  0x02,  0x20,  0x22,  0x0F,  0xA0,  0x22,  0x02,  0x20, 	/* 0A9F0 */
+	0x32,  0x0E,  0x20,  0x22,  0x02,  0x22,  0x22,  0x26,  0x1E,  0x93,  0x20,  0x02,  0x7E,  0x20,  0x8F,  0x08, 	/* 0AA00 */
+	0x20,  0x82,  0x08,  0x30,  0x8E,  0x08,  0x20,  0x82,  0x08,  0x20,  0x86,  0x18,  0x95,  0x21,  0x02,  0x10, 	/* 0AA10 */
+	0x21,  0x0F,  0x10,  0x21,  0x02,  0x20,  0x32,  0x8E,  0x24,  0x24,  0x42,  0x4E,  0x2F,  0x26,  0x02,  0x98, 	/* 0AA20 */
+	0x20,  0xC2,  0xF0,  0x22,  0x0F,  0x20,  0x22,  0x03,  0xFE,  0x32,  0x0E,  0x20,  0x22,  0x02,  0x22,  0x22, 	/* 0AA30 */
+	0x26,  0x1E,  0x9B,  0x20,  0x02,  0xFC,  0x21,  0x0F,  0x90,  0x21,  0x02,  0x10,  0x39,  0x0E,  0x10,  0x21, 	/* 0AA40 */
+	0x02,  0x10,  0x3F,  0xE6,  0x00,  0x9E,  0x20,  0x02,  0x7C,  0x21,  0x0F,  0x90,  0x21,  0x02,  0xFE,  0x31, 	/* 0AA50 */
+	0x0E,  0x10,  0x21,  0x02,  0x10,  0x21,  0x06,  0x10,  0xA0,  0x20,  0x02,  0xFE,  0x20,  0x2F,  0x54,  0x24, 	/* 0AA60 */
+	0xC2,  0x28,  0x32,  0x8E,  0x10,  0x21,  0x02,  0x28,  0x24,  0x46,  0x82,  0xA3,  0x20,  0x02,  0x7E,  0x24, 	/* 0AA70 */
+	0x2F,  0xC2,  0x24,  0x22,  0x42,  0x34,  0x2E,  0x42,  0x24,  0x22,  0x42,  0x27,  0xE6,  0x42,  0xA8,  0x20, 	/* 0AA80 */
+	0x02,  0xFE,  0x21,  0x2F,  0x12,  0x25,  0x22,  0x32,  0x31,  0xAE,  0x17,  0x21,  0x22,  0x22,  0x22,  0x26, 	/* 0AA90 */
+	0x4C,  0xAE,  0x22,  0x82,  0x28,  0x22,  0x8F,  0x44,  0x28,  0x22,  0xFD,  0x32,  0x4E,  0x24,  0x22,  0x42, 	/* 0AAA0 */
+	0x44,  0x24,  0x46,  0x98,  0xB1,  0x20,  0x02,  0x7C,  0x22,  0x4F,  0xA8,  0x22,  0xE2,  0x22,  0x35,  0x2E, 	/* 0AAB0 */
+	0x54,  0x24,  0xC2,  0x94,  0x2A,  0x27,  0x41,  0xB6,  0x21,  0x02,  0x10,  0x21,  0x0F,  0xFC,  0x21,  0x02, 	/* 0AAC0 */
+	0x10,  0x3F,  0xEE,  0x10,  0x22,  0x82,  0x28,  0x24,  0x47,  0x82,  0xB9,  0x24,  0x82,  0x48,  0x24,  0x8F, 	/* 0AAD0 */
+	0x4B,  0x27,  0xC2,  0x48,  0x34,  0x8E,  0x48,  0x24,  0x82,  0x49,  0x27,  0x96,  0xC7,  0xBC,  0x40,  0x04, 	/* 0AAE0 */
+	0xFE,  0x48,  0x0F,  0xBC,  0x4A,  0x44,  0xA4,  0x6A,  0x4C,  0xAC,  0x4A,  0x05,  0x22,  0x52,  0x2E,  0x1E, 	/* 0AAF0 */
+	0xBE,  0x22,  0x82,  0x24,  0x22,  0x02,  0xFE,  0xFA,  0x42,  0x24,  0x22,  0x83,  0x98,  0xE1,  0x02,  0x2A, 	/* 0AB00 */
+	0x2C,  0x66,  0x02,  0xBF,  0x00,  0x03,  0xF8,  0x01,  0x00,  0x22,  0xEF,  0x42,  0x48,  0x3F,  0x82,  0x48, 	/* 0AB10 */
+	0x5F,  0x44,  0x44,  0x84,  0x20,  0xC0,  0x80,  0x21,  0x02,  0x10,  0x2F,  0xEF,  0x10,  0x21,  0x02,  0xFC, 	/* 0AB20 */
+	0x30,  0x4E,  0x28,  0x21,  0x82,  0x18,  0x22,  0x46,  0xC2,  0x82,  0x20,  0x02,  0xFE,  0x21,  0x0F,  0x90, 	/* 0AB30 */
+	0x21,  0x02,  0x7C,  0x31,  0x0E,  0x10,  0x21,  0x02,  0x10,  0x21,  0x06,  0xFE,  0x83,  0x21,  0x02,  0x10, 	/* 0AB40 */
+	0x2F,  0xEF,  0x10,  0x21,  0x02,  0x18,  0x31,  0x4E,  0x12,  0x21,  0x02,  0x10,  0x21,  0x06,  0x10,  0x84, 	/* 0AB50 */
+	0x21,  0x02,  0x10,  0x25,  0x8F,  0x54,  0x25,  0x22,  0x96,  0x31,  0x4E,  0x38,  0x20,  0x82,  0x10,  0x26, 	/* 0AB60 */
+	0x07,  0x80,  0x89,  0x22,  0x02,  0x20,  0x22,  0x0F,  0xFC,  0x22,  0x42,  0x24,  0x3F,  0xEE,  0x20,  0x25, 	/* 0AB70 */
+	0x02,  0x48,  0x28,  0x47,  0x02,  0x8A,  0x20,  0x02,  0xFE,  0x29,  0x2F,  0x92,  0x29,  0x22,  0xFE,  0x38, 	/* 0AB80 */
+	0x0E,  0x80,  0x28,  0x02,  0x82,  0x28,  0x26,  0x7E,  0x91,  0x22,  0x02,  0xDE,  0x29,  0x2F,  0x92,  0x29, 	/* 0AB90 */
+	0x22,  0x92,  0x39,  0x2E,  0x92,  0x2F,  0x23,  0x9C,  0x21,  0x06,  0x10,  0x92,  0x20,  0x02,  0x7C,  0x22, 	/* 0ABA0 */
+	0x8F,  0x90,  0x2F,  0xE2,  0x14,  0x31,  0x8E,  0x10,  0x21,  0x02,  0x10,  0x21,  0x06,  0x30,  0x93,  0x20, 	/* 0ABB0 */
+	0x62,  0x7C,  0x25,  0x4F,  0x54,  0x25,  0x42,  0x54,  0x35,  0x4E,  0x54,  0x25,  0x42,  0x52,  0x25,  0x26, 	/* 0ABC0 */
+	0x91,  0x94,  0x20,  0x02,  0xFE,  0x20,  0x8F,  0x90,  0x23,  0x82,  0x54,  0x39,  0x2E,  0x10,  0x21,  0x02, 	/* 0ABD0 */
+	0x10,  0x21,  0x06,  0x10,  0x95,  0x27,  0x82,  0x48,  0x24,  0x8F,  0x4A,  0x28,  0x63,  0x00,  0x2F,  0xCE, 	/* 0ABE0 */
+	0x04,  0x22,  0x82,  0x10,  0x26,  0x87,  0x86,  0x96,  0x20,  0x82,  0x48,  0x22,  0x8F,  0x08,  0x24,  0x82, 	/* 0ABF0 */
+	0x28,  0x30,  0x8E,  0x0E,  0x2F,  0x82,  0x08,  0x20,  0x86,  0x08,  0x97,  0x22,  0x02,  0x20,  0x2F,  0xCF, 	/* 0AC00 */
+	0x00,  0x27,  0x82,  0x48,  0x34,  0x8E,  0x48,  0x24,  0x82,  0x4A,  0x28,  0xA7,  0x06,  0x98,  0x20,  0x42, 	/* 0AC10 */
+	0x78,  0x24,  0x0F,  0x40,  0x27,  0xE2,  0x48,  0x34,  0x8E,  0x48,  0x28,  0x82,  0x88,  0x30,  0x86,  0x08, 	/* 0AC20 */
+	0x9B,  0x48,  0x84,  0x88,  0x48,  0x8E,  0x9E,  0x5E,  0xA4,  0xAA,  0x6A,  0xAC,  0xAA,  0x4B,  0x24,  0xA6, 	/* 0AC30 */
+	0x4A,  0x1D,  0x1F,  0x9C,  0x24,  0x02,  0x40,  0x2F,  0xEF,  0x40,  0x24,  0x02,  0x7C,  0x34,  0x4E,  0x68, 	/* 0AC40 */
+	0x29,  0x82,  0x98,  0x32,  0x46,  0xC2,  0x9E,  0x20,  0x02,  0x7C,  0x24,  0x4F,  0x44,  0x27,  0xC2,  0x50, 	/* 0AC50 */
+	0x35,  0x0E,  0x48,  0x24,  0x82,  0x84,  0x28,  0x47,  0x02,  0xAB,  0x21,  0x02,  0x10,  0x2F,  0xEF,  0x92, 	/* 0AC60 */
+	0x29,  0x42,  0xFC,  0x38,  0x4E,  0xA8,  0x2A,  0x82,  0x90,  0x32,  0x86,  0x46,  0xAC,  0x22,  0x02,  0x20, 	/* 0AC70 */
+	0x22,  0x0F,  0x48,  0x24,  0x42,  0xFE,  0x30,  0x2E,  0x7C,  0x24,  0x42,  0x44,  0x24,  0x46,  0x7C,  0xB1, 	/* 0AC80 */
+	0x24,  0x02,  0x40,  0x27,  0xEF,  0x42,  0x2B,  0xA2,  0x0A,  0x37,  0xAE,  0x44,  0x24,  0x02,  0x42,  0x24, 	/* 0AC90 */
+	0x26,  0x3E,  0xB5,  0x20,  0xC2,  0x70,  0x25,  0x0F,  0x50,  0x25,  0x02,  0x7E,  0x34,  0x8E,  0x48,  0x24, 	/* 0ACA0 */
+	0xA2,  0xE6,  0x20,  0x66,  0xF2,  0xB9,  0x21,  0x02,  0x10,  0x2F,  0xEF,  0x10,  0x21,  0x02,  0x7C,  0x31, 	/* 0ACB0 */
+	0x0E,  0x38,  0x25,  0x42,  0x93,  0x21,  0x06,  0x10,  0xBB,  0x21,  0x02,  0x10,  0x2F,  0xEF,  0x92,  0x29, 	/* 0ACC0 */
+	0x22,  0xFE,  0x39,  0x2E,  0x92,  0x2F,  0xE2,  0x10,  0x21,  0x06,  0x10,  0xBC,  0x20,  0x02,  0xFE,  0x29, 	/* 0ACD0 */
+	0x2F,  0x92,  0x2F,  0xE2,  0x92,  0x39,  0x2E,  0xFE,  0x21,  0x02,  0x10,  0x21,  0x06,  0x10,  0xBD,  0x21, 	/* 0ACE0 */
+	0x02,  0x10,  0x21,  0x0F,  0xFE,  0x29,  0x22,  0x92,  0x39,  0x2E,  0xFE,  0x29,  0x22,  0x92,  0x29,  0x26, 	/* 0ACF0 */
+	0xFE,  0x82,  0x45,  0x05,  0xFC,  0x45,  0x4E,  0x54,  0x5F,  0xC5,  0x50,  0x7F,  0xEC,  0x52,  0x45,  0x24, 	/* 0AD00 */
+	0x92,  0x49,  0xCD,  0x10,  0x85,  0x20,  0x02,  0x7C,  0x24,  0x4F,  0xC4,  0x27,  0xC2,  0x44,  0x34,  0x4E, 	/* 0AD10 */
+	0x44,  0x27,  0xC2,  0x00,  0x20,  0x06,  0xFF,  0x86,  0x20,  0x62,  0x78,  0x24,  0x0F,  0xC0,  0x27,  0xF2, 	/* 0AD20 */
+	0x48,  0x34,  0x8E,  0x58,  0x24,  0xE2,  0x49,  0x28,  0x86,  0x08,  0x87,  0x4F,  0xC4,  0x84,  0x4A,  0x4F, 	/* 0AD30 */
+	0x94,  0x5F,  0xE4,  0x84,  0x6A,  0x4C,  0x94,  0x48,  0x44,  0xFE,  0x48,  0x4C,  0x18,  0x88,  0x21,  0x02, 	/* 0AD40 */
+	0x10,  0x21,  0x0F,  0x9E,  0x21,  0x02,  0x10,  0x31,  0x0E,  0x7E,  0x24,  0x22,  0x42,  0x24,  0x26,  0x7E, 	/* 0AD50 */
+	0x89,  0x21,  0x02,  0x10,  0x21,  0x0F,  0xFE,  0x20,  0x42,  0x84,  0x34,  0x4E,  0x44,  0x22,  0x82,  0x28, 	/* 0AD60 */
+	0x21,  0x06,  0xFE,  0x8A,  0x22,  0x22,  0x22,  0x22,  0x2F,  0x5F,  0x24,  0x22,  0xD2,  0x34,  0xAE,  0x4A, 	/* 0AD70 */
+	0x24,  0x22,  0x42,  0x24,  0x26,  0x46,  0x8C,  0x21,  0x02,  0x54,  0x25,  0x2F,  0x90,  0x2F,  0xE2,  0x10, 	/* 0AD80 */
+	0x31,  0x0E,  0xFE,  0x21,  0x02,  0x10,  0x21,  0x06,  0x10,  0x8D,  0x21,  0x02,  0x10,  0x22,  0x0F,  0x7E, 	/* 0AD90 */
+	0x24,  0x22,  0x42,  0x37,  0xEE,  0x42,  0x24,  0x22,  0x42,  0x24,  0x26,  0x7E,  0x8F,  0x40,  0x0F,  0xFC, 	/* 0ADA0 */
+	0x4A,  0x4F,  0x18,  0x2A,  0x4C,  0x32,  0x1C,  0x07,  0xFC,  0x04,  0x0F,  0xFE,  0x04,  0x00,  0xC0,  0x90, 	/* 0ADB0 */
+	0x20,  0x02,  0x7E,  0x24,  0x2F,  0x42,  0x27,  0xE2,  0x00,  0x3F,  0xEE,  0x12,  0x21,  0x22,  0x22,  0x24, 	/* 0ADC0 */
+	0x26,  0x8C,  0x91,  0x24,  0x42,  0x44,  0x24,  0x4F,  0xFE,  0x24,  0x42,  0x44,  0x34,  0x4E,  0x7C,  0x24, 	/* 0ADD0 */
+	0x42,  0x44,  0x24,  0x46,  0x7C,  0x92,  0x20,  0x02,  0x7E,  0x24,  0x0F,  0x40,  0x27,  0xC2,  0x44,  0x34, 	/* 0ADE0 */
+	0x4E,  0x7C,  0x24,  0x02,  0x40,  0x24,  0x06,  0x7E,  0x93,  0x20,  0x02,  0xFE,  0x22,  0x0F,  0x20,  0x22, 	/* 0ADF0 */
+	0x02,  0x40,  0x37,  0xEE,  0xA2,  0x2A,  0x23,  0x22,  0x22,  0x26,  0x3E,  0x94,  0x22,  0x82,  0x24,  0x22, 	/* 0AE00 */
+	0x02,  0x3E,  0xFE,  0x02,  0x24,  0x21,  0x43,  0x98,  0xE1,  0x02,  0x2A,  0x2C,  0x66,  0x02,  0x97,  0x48, 	/* 0AE10 */
+	0x84,  0x88,  0x50,  0x85,  0x7E,  0xE4,  0xA5,  0x4A,  0x48,  0xA7,  0x4A,  0xD2,  0xA5,  0xEA,  0x73,  0x2C, 	/* 0AE20 */
+	0x26,  0x98,  0x24,  0x02,  0x40,  0x27,  0xEF,  0x42,  0x28,  0x22,  0xBA,  0x32,  0xAE,  0x2A,  0x23,  0xA2, 	/* 0AE30 */
+	0x22,  0x20,  0x26,  0x0C,  0x99,  0x21,  0x02,  0x10,  0x29,  0x2F,  0x92,  0x29,  0x22,  0xFE,  0x31,  0x0E, 	/* 0AE40 */
+	0x92,  0x29,  0x22,  0x92,  0x29,  0x26,  0xFE,  0x9B,  0x20,  0x02,  0xFE,  0x21,  0x2F,  0x12,  0x22,  0x22, 	/* 0AE50 */
+	0x4C,  0x38,  0x0E,  0x7E,  0x24,  0x22,  0x42,  0x24,  0x26,  0x7E,  0x9C,  0x10,  0x0E,  0xFE,  0x21,  0x02, 	/* 0AE60 */
+	0x7C,  0xF9,  0x02,  0x7C,  0x39,  0x0E,  0x10,  0x2F,  0xE4,  0x10,  0x41,  0x08,  0x10,  0x9D,  0x20,  0x02, 	/* 0AE70 */
+	0xFE,  0x21,  0x0F,  0x7C,  0x21,  0x02,  0x7C,  0x31,  0x0E,  0x10,  0x2F,  0xE2,  0x10,  0x21,  0x06,  0x10, 	/* 0AE80 */
+	0xA0,  0x20,  0x02,  0x4E,  0x24,  0xAF,  0x6A,  0x2A,  0xA2,  0xAA,  0x3A,  0xAE,  0x6A,  0x23,  0x22,  0x53, 	/* 0AE90 */
+	0x28,  0x87,  0x07,  0xA1,  0x21,  0x02,  0x10,  0x2F,  0xEF,  0x80,  0x29,  0x02,  0x90,  0x39,  0x0E,  0xA8, 	/* 0AEA0 */
+	0x2A,  0x42,  0xAE,  0x37,  0x26,  0x02,  0xAC,  0x20,  0xC2,  0xF0,  0x21,  0x0F,  0x10,  0x2F,  0xE2,  0x10, 	/* 0AEB0 */
+	0x31,  0x0E,  0x7C,  0x24,  0x42,  0x44,  0x24,  0x46,  0x7C,  0xAD,  0x21,  0x42,  0x12,  0x21,  0x0F,  0xFE, 	/* 0AEC0 */
+	0x21,  0x02,  0xF0,  0x35,  0x0E,  0x48,  0x25,  0xA2,  0x6A,  0x38,  0x66,  0x02,  0xAE,  0x21,  0x02,  0x10, 	/* 0AED0 */
+	0x2F,  0xFF,  0x10,  0x21,  0x02,  0x7E,  0x30,  0x0E,  0x7E,  0x24,  0x22,  0x42,  0x27,  0xE6,  0x40,  0xAF, 	/* 0AEE0 */
+	0x20,  0x02,  0x7C,  0x20,  0x8F,  0x12,  0x2F,  0x22,  0x3C,  0x33,  0x8E,  0x54,  0x29,  0x43,  0x12,  0x23, 	/* 0AEF0 */
+	0x06,  0xFE,  0xB1,  0x24,  0x82,  0x48,  0x24,  0x8F,  0xFE,  0x24,  0x82,  0x48,  0x34,  0x8E,  0xFF,  0x21, 	/* 0AF00 */
+	0x02,  0x48,  0x24,  0x46,  0x84,  0xB3,  0x24,  0x81,  0x50,  0x7F,  0xC0,  0xA0,  0xFF,  0xE2,  0x68,  0xDC, 	/* 0AF10 */
+	0x63,  0xF8,  0x04,  0x07,  0xFC,  0x04,  0x00,  0xC0,  0xB5,  0x22,  0x02,  0x20,  0x2F,  0xEF,  0x20,  0x23, 	/* 0AF20 */
+	0xE2,  0x44,  0x34,  0x8E,  0xFE,  0x38,  0x82,  0x88,  0x28,  0x86,  0x98,  0xB6,  0x22,  0xA2,  0x2A,  0x25, 	/* 0AF30 */
+	0x4F,  0x2A,  0x22,  0xA2,  0x10,  0x31,  0xEE,  0x22,  0x2E,  0x42,  0x18,  0x23,  0x06,  0xC0,  0xB7,  0x22, 	/* 0AF40 */
+	0x02,  0xFC,  0x22,  0x0F,  0x28,  0x3F,  0xE2,  0x60,  0x2B,  0xCF,  0x20,  0x27,  0xC2,  0x44,  0x20,  0x46, 	/* 0AF50 */
+	0x18,  0xBE,  0x21,  0x02,  0x10,  0x22,  0x8F,  0x44,  0x2F,  0xE3,  0x01,  0x30,  0x0E,  0x7C,  0x24,  0x42, 	/* 0AF60 */
+	0x44,  0x24,  0x46,  0x7C,  0xBF,  0x04,  0x00,  0xA0,  0x31,  0x8D,  0xF6,  0x11,  0x01,  0xF0,  0x1C,  0x07, 	/* 0AF70 */
+	0xFC,  0x04,  0x0F,  0xFE,  0x04,  0x00,  0xC0,  0x81,  0x22,  0x02,  0xFC,  0x22,  0x0F,  0x20,  0x2F,  0xE2, 	/* 0AF80 */
+	0x08,  0x3F,  0xEE,  0x88,  0x24,  0x82,  0x08,  0x20,  0x86,  0x18,  0x82,  0x21,  0x02,  0x10,  0x27,  0xCF, 	/* 0AF90 */
+	0x90,  0x21,  0x02,  0xFE,  0x31,  0x0E,  0x10,  0x27,  0xC2,  0x10,  0x21,  0x06,  0xFE,  0x87,  0x28,  0x02, 	/* 0AFA0 */
+	0x8C,  0x2F,  0x0F,  0x82,  0x27,  0xE2,  0x00,  0x3F,  0xCE,  0x84,  0x2F,  0xC2,  0x84,  0x28,  0x46,  0xFC, 	/* 0AFB0 */
+	0x88,  0x14,  0x01,  0xBE,  0x74,  0xA1,  0x8A,  0x75,  0x21,  0xA6,  0xE3,  0x83,  0xFC,  0x02,  0x0F,  0xFE, 	/* 0AFC0 */
+	0x02,  0x00,  0x60,  0x89,  0x21,  0x02,  0xFE,  0x28,  0x2F,  0xA2,  0x22,  0x02,  0xFF,  0x32,  0x4E,  0x24, 	/* 0AFD0 */
+	0x26,  0x42,  0x18,  0x22,  0x46,  0xC2,  0x8C,  0x22,  0x02,  0x3E,  0x24,  0x4F,  0x64,  0x29,  0x82,  0x14, 	/* 0AFE0 */
+	0x32,  0x2E,  0x7D,  0x2A,  0x42,  0x24,  0x22,  0x46,  0x3C,  0x91,  0x22,  0x82,  0x28,  0x22,  0x8F,  0xAA, 	/* 0AFF0 */
+	0x26,  0xC2,  0x28,  0x36,  0xCE,  0xAA,  0x2A,  0xA2,  0x28,  0x24,  0x96,  0x87,  0x99,  0x48,  0x82,  0x48, 	/* 0B000 */
+	0xFF,  0xE1,  0x20,  0x3F,  0x04,  0x88,  0xBF,  0x60,  0x40,  0x7F,  0x80,  0x40,  0x04,  0x01,  0x80,  0x9F, 	/* 0B010 */
+	0x21,  0x02,  0x10,  0x2F,  0xEF,  0x10,  0x25,  0x22,  0x54,  0x3F,  0xEE,  0x10,  0x21,  0x02,  0x28,  0x24, 	/* 0B020 */
+	0x47,  0x82,  0xA7,  0x20,  0x02,  0xFE,  0x22,  0x2F,  0x66,  0x26,  0x62,  0xAA,  0x33,  0x2E,  0x66,  0x2A, 	/* 0B030 */
+	0xA3,  0x32,  0x22,  0x26,  0x66,  0xA8,  0x22,  0x02,  0x28,  0x24,  0x4F,  0x7A,  0x28,  0x22,  0xFC,  0x31, 	/* 0B040 */
+	0x0E,  0xFE,  0x21,  0x02,  0x28,  0x24,  0x46,  0x83,  0xAB,  0x21,  0x02,  0x54,  0x25,  0x4F,  0x54,  0x25, 	/* 0B050 */
+	0x42,  0xBA,  0x39,  0x2E,  0x10,  0x2F,  0xE2,  0x10,  0x21,  0x06,  0xFF,  0xAF,  0x20,  0x02,  0xFE,  0x28, 	/* 0B060 */
+	0x0F,  0xBC,  0x28,  0x02,  0xFE,  0x3B,  0x2E,  0xB4,  0x2A,  0x82,  0xA8,  0x33,  0x46,  0x62,  0xBA,  0x20, 	/* 0B070 */
+	0x22,  0xEC,  0x22,  0x4F,  0x24,  0x24,  0x42,  0xFF,  0x32,  0x4E,  0xA4,  0x2A,  0x42,  0x5F,  0x2B,  0x07, 	/* 0B080 */
+	0x0F,  0xBD,  0x22,  0x02,  0x38,  0x24,  0x8F,  0x90,  0x2F,  0xE2,  0x92,  0x39,  0x2E,  0xFE,  0x22,  0x82, 	/* 0B090 */
+	0x29,  0x24,  0x96,  0x87,  0xBE,  0x21,  0x02,  0x10,  0x2F,  0xEF,  0x10,  0x25,  0x42,  0x54,  0x2B,  0xAF, 	/* 0B0A0 */
+	0x12,  0x22,  0x82,  0x28,  0x24,  0x46,  0x82,  0xBF,  0x20,  0xC2,  0xF0,  0x21,  0x0F,  0xFE,  0x21,  0x02, 	/* 0B0B0 */
+	0xFE,  0x39,  0x2E,  0xFE,  0x29,  0x22,  0xFE,  0x21,  0x06,  0x10,  0x89,  0x20,  0x02,  0xFC,  0x28,  0x4F, 	/* 0B0C0 */
+	0x84,  0x2F,  0xC2,  0x10,  0x39,  0x0E,  0x9E,  0x29,  0x02,  0xD0,  0x33,  0x06,  0x0E,  0x8C,  0x40,  0x25, 	/* 0B0D0 */
+	0xEA,  0x52,  0xAF,  0x2A,  0x5E,  0xA4,  0x8A,  0x6E,  0xAC,  0xAA,  0x4A,  0xA5,  0x22,  0x62,  0x2C,  0xC6, 	/* 0B0E0 */
+	0x8D,  0x27,  0xC2,  0x44,  0x27,  0xCF,  0xC4,  0x27,  0xC2,  0x00,  0x3F,  0xEE,  0x10,  0x21,  0x02,  0xFE, 	/* 0B0F0 */
+	0x21,  0x06,  0x10,  0x8F,  0x20,  0x02,  0xFE,  0x28,  0x2F,  0xFE,  0x28,  0x22,  0xFE,  0x31,  0x0E,  0x10, 	/* 0B100 */
+	0x27,  0xE2,  0x10,  0x21,  0x06,  0xFF,  0x90,  0x27,  0xE2,  0x42,  0x27,  0xEF,  0x80,  0x27,  0xE2,  0x42, 	/* 0B110 */
+	0x37,  0xEE,  0x42,  0x27,  0xE2,  0x42,  0x24,  0x26,  0x46,  0x95,  0x21,  0x42,  0x12,  0x2F,  0xFF,  0x10, 	/* 0B120 */
+	0x2F,  0xE2,  0x92,  0x3F,  0xEE,  0x92,  0x2F,  0xE2,  0x92,  0x29,  0x26,  0x96,  0x97,  0x21,  0x02,  0x50, 	/* 0B130 */
+	0x25,  0xEF,  0x50,  0x2F,  0xE2,  0x10,  0x35,  0x4E,  0x52,  0x2B,  0x62,  0x0A,  0x23,  0x06,  0xC0,  0x9C, 	/* 0B140 */
+	0x21,  0x02,  0xFE,  0x29,  0x2F,  0xFE,  0x29,  0x22,  0xFE,  0x31,  0x0E,  0xFC,  0x24,  0x42,  0x28,  0x23, 	/* 0B150 */
+	0x86,  0xC6,  0xA7,  0x21,  0x02,  0xFE,  0x21,  0x0F,  0x7C,  0x22,  0x82,  0xFE,  0x35,  0x4F,  0xBB,  0x21, 	/* 0B160 */
+	0x02,  0x7C,  0x21,  0x06,  0x10,  0xA8,  0x21,  0x02,  0x10,  0x22,  0x8F,  0xD6,  0x27,  0xC2,  0x10,  0x3F, 	/* 0B170 */
+	0xEE,  0x00,  0x27,  0xC2,  0x44,  0x24,  0x46,  0x7C,  0xA9,  0x2F,  0xE2,  0x00,  0x2F,  0xEF,  0x82,  0x2F, 	/* 0B180 */
+	0xE2,  0x90,  0x39,  0x0E,  0xFE,  0x31,  0x03,  0x28,  0x24,  0x46,  0x82,  0xAB,  0x4E,  0xE4,  0xAA,  0x4E, 	/* 0B190 */
+	0xEF,  0xAA,  0x4E,  0xE4,  0x82,  0x68,  0x2C,  0x82,  0x48,  0x24,  0x82,  0x48,  0x2C,  0x86,  0xAE,  0x20, 	/* 0B1A0 */
+	0x02,  0xFC,  0x28,  0x4F,  0xFC,  0x29,  0x02,  0xFE,  0x39,  0x0E,  0x90,  0x2F,  0xC3,  0x44,  0x34,  0x46, 	/* 0B1B0 */
+	0x7C,  0xB2,  0x29,  0x22,  0x54,  0x27,  0xCF,  0x10,  0x2F,  0xE2,  0x28,  0x34,  0x4E,  0xBB,  0x20,  0x82, 	/* 0B1C0 */
+	0x78,  0x24,  0x46,  0x3C,  0xB6,  0x40,  0xC4,  0xF0,  0x41,  0x0F,  0xFE,  0x45,  0x45,  0xFF,  0x65,  0x4C, 	/* 0B1D0 */
+	0x54,  0x4F,  0xE4,  0x10,  0x41,  0x0D,  0xFE,  0xB7,  0x21,  0x02,  0xFE,  0x21,  0x0F,  0x7C,  0x21,  0x42, 	/* 0B1E0 */
+	0xFE,  0x31,  0x4E,  0x7C,  0x25,  0x02,  0x5E,  0x2B,  0x07,  0x0F,  0xBA,  0x21,  0x02,  0x10,  0x2F,  0xEF, 	/* 0B1F0 */
+	0x28,  0x24,  0x42,  0xBA,  0x30,  0x0E,  0xFC,  0x21,  0x02,  0x54,  0x29,  0x26,  0x30,  0xBB,  0x21,  0x02, 	/* 0B200 */
+	0x28,  0x24,  0x4F,  0xBA,  0x20,  0x02,  0xFE,  0x30,  0x4E,  0x08,  0x23,  0x02,  0xAA,  0x32,  0x26,  0x1E, 	/* 0B210 */
+	0x80,  0x22,  0x82,  0xC8,  0x28,  0xEF,  0xF2,  0x2B,  0x62,  0xA4,  0x3A,  0x4E,  0xA4,  0x2A,  0xC2,  0xAA, 	/* 0B220 */
+	0x33,  0x26,  0x21,  0x83,  0x20,  0x02,  0x7C,  0x20,  0x4F,  0x7C,  0x20,  0x42,  0xFF,  0x39,  0x1E,  0xFF, 	/* 0B230 */
+	0x25,  0x22,  0x52,  0x25,  0x66,  0x10,  0x88,  0x20,  0xC2,  0xF2,  0x25,  0x2F,  0x44,  0x2F,  0xE2,  0x82, 	/* 0B240 */
+	0x37,  0xCE,  0x48,  0x22,  0x82,  0x10,  0x22,  0x86,  0xC6,  0x89,  0x21,  0x02,  0x1E,  0x21,  0x0F,  0xFE, 	/* 0B250 */
+	0x24,  0x22,  0x7E,  0x34,  0x2E,  0x7E,  0x21,  0x02,  0xFF,  0x21,  0x06,  0x10,  0x8C,  0x24,  0x81,  0x50, 	/* 0B260 */
+	0xFF,  0xE9,  0xF2,  0x91,  0x23,  0xF8,  0x04,  0x07,  0xFC,  0x04,  0x0F,  0xFE,  0x04,  0x00,  0xC0,  0x8E, 	/* 0B270 */
+	0x22,  0x03,  0xFC,  0x22,  0x0F,  0x50,  0x28,  0x83,  0xFE,  0x30,  0x4E,  0xF4,  0x29,  0x42,  0xF4,  0x20, 	/* 0B280 */
+	0x46,  0x0C,  0x8F,  0x48,  0x04,  0x80,  0x4F,  0xEE,  0xC2,  0x57,  0xA6,  0xA2,  0x4F,  0xA6,  0x22,  0xCA, 	/* 0B290 */
+	0xA4,  0xFA,  0x40,  0x2C,  0x0C,  0x92,  0x22,  0x82,  0x28,  0x2E,  0xEF,  0x28,  0x22,  0x82,  0xEE,  0x32, 	/* 0B2A0 */
+	0x8E,  0x28,  0x3E,  0xF2,  0x48,  0x24,  0x86,  0x88,  0x96,  0x21,  0x02,  0xFE,  0x22,  0x8F,  0x2E,  0x24, 	/* 0B2B0 */
+	0xA2,  0x56,  0x3E,  0xAE,  0x4C,  0x24,  0x42,  0x4A,  0x25,  0x26,  0x61,  0x98,  0x20,  0x02,  0xFE,  0x28, 	/* 0B2C0 */
+	0x2F,  0xFE,  0x28,  0x82,  0xAA,  0x3A,  0xAE,  0xBE,  0x28,  0x82,  0xCA,  0x34,  0xA6,  0x7E,  0x9B,  0x22, 	/* 0B2D0 */
+	0x42,  0x24,  0x2F,  0x4F,  0x24,  0x2F,  0xC2,  0x26,  0x32,  0x5E,  0xF5,  0x22,  0x42,  0x34,  0x2C,  0x46, 	/* 0B2E0 */
+	0x04,  0x9F,  0x41,  0x05,  0xFE,  0x50,  0x2F,  0x02,  0x4F,  0xC4,  0x10,  0x69,  0x0C,  0x9C,  0x49,  0x04, 	/* 0B2F0 */
+	0xD0,  0x53,  0x0E,  0x0E,  0xA0,  0x21,  0x02,  0xFE,  0x20,  0x0F,  0x7C,  0x24,  0x42,  0x44,  0x37,  0xCE, 	/* 0B300 */
+	0x10,  0x25,  0x42,  0x52,  0x29,  0x26,  0x30,  0xA1,  0x20,  0xE2,  0xF2,  0x29,  0x2F,  0x54,  0x24,  0x82, 	/* 0B310 */
+	0x10,  0x3F,  0xEE,  0x38,  0x25,  0x42,  0x92,  0x31,  0x16,  0x10,  0xA2,  0x20,  0x02,  0xFE,  0x2A,  0xAF, 	/* 0B320 */
+	0x28,  0x2C,  0xE2,  0x10,  0x3F,  0xEE,  0x10,  0x23,  0x82,  0x54,  0x29,  0x36,  0x10,  0xA3,  0x50,  0x27, 	/* 0B330 */
+	0xD2,  0x91,  0x27,  0xD2,  0x54,  0x25,  0x46,  0x07,  0x83,  0xFC,  0x02,  0x0F,  0xFE,  0x02,  0x00,  0x60, 	/* 0B340 */
+	0xA5,  0x21,  0x02,  0xFE,  0x24,  0x4F,  0x28,  0x2F,  0xF2,  0x10,  0x3F,  0xFE,  0x24,  0x22,  0x42,  0x78, 	/* 0B350 */
+	0x21,  0x46,  0xE2,  0xA7,  0x21,  0x02,  0x10,  0x2F,  0xEF,  0xAA,  0x22,  0x82,  0xC6,  0x30,  0x0E,  0x7E, 	/* 0B360 */
+	0x21,  0x02,  0x10,  0x21,  0x06,  0xFE,  0xA8,  0x22,  0x42,  0x28,  0x27,  0xEF,  0x48,  0x2C,  0x82,  0x7C, 	/* 0B370 */
+	0x34,  0x8E,  0x48,  0x27,  0xC2,  0x48,  0x24,  0x86,  0x7E,  0xA9,  0x21,  0x02,  0x10,  0x2F,  0xFF,  0x54, 	/* 0B380 */
+	0x29,  0x23,  0x7D,  0x35,  0x4E,  0x7C,  0x25,  0x42,  0x7C,  0x21,  0x16,  0x0F,  0xAA,  0x24,  0x82,  0x48, 	/* 0B390 */
+	0x2F,  0xCF,  0x48,  0x3F,  0xE2,  0x00,  0x3F,  0xCE,  0x84,  0x2F,  0xC2,  0x84,  0x28,  0x46,  0xFC,  0xAB, 	/* 0B3A0 */
+	0x20,  0x03,  0xFE,  0x2A,  0x0F,  0xBE,  0x2E,  0x22,  0xAA,  0x3E,  0xCE,  0xA4,  0x2A,  0x42,  0xEA,  0x33, 	/* 0B3B0 */
+	0x26,  0x21,  0xAC,  0x24,  0x02,  0x40,  0x27,  0xEF,  0xA2,  0x2A,  0xA2,  0x72,  0x3F,  0xAE,  0x22,  0x27, 	/* 0B3C0 */
+	0x22,  0xAA,  0x22,  0x26,  0x2C,  0xB2,  0x27,  0xC2,  0x44,  0x27,  0xCF,  0x44,  0x27,  0xC2,  0x20,  0x37, 	/* 0B3D0 */
+	0xEE,  0xC2,  0x37,  0xA2,  0x42,  0x23,  0xA6,  0x0C,  0xB4,  0x20,  0x02,  0xFE,  0x28,  0x2F,  0xFE,  0x29, 	/* 0B3E0 */
+	0x22,  0x92,  0x3F,  0xEE,  0x9A,  0x29,  0x62,  0xFE,  0x28,  0x26,  0xFE,  0xB5,  0x42,  0x04,  0x20,  0x43, 	/* 0B3F0 */
+	0x0F,  0x48,  0x4F,  0xC5,  0x02,  0x7D,  0xDD,  0x54,  0x55,  0x45,  0xDC,  0x41,  0x0C,  0x10,  0xBB,  0x20, 	/* 0B400 */
+	0x02,  0xFC,  0x24,  0x4F,  0x38,  0x2C,  0x62,  0x10,  0x3F,  0xEE,  0x92,  0x2F,  0xE2,  0x14,  0x21,  0xE6, 	/* 0B410 */
+	0xF2,  0xBE,  0x23,  0xC2,  0x44,  0x2F,  0x82,  0x08,  0xFF,  0xE2,  0x10,  0x26,  0xA3,  0x9C,  0xE6,  0xA2, 	/* 0B420 */
+	0x19,  0x26,  0x86,  0x10,  0x80,  0x21,  0x03,  0xFE,  0x21,  0x0F,  0xFE,  0x29,  0x22,  0xD6,  0x3B,  0xAE, 	/* 0B430 */
+	0xFE,  0x23,  0x82,  0x54,  0x29,  0x36,  0x10,  0x83,  0x48,  0x84,  0x50,  0x5F,  0xEE,  0x00,  0x5E,  0xA5, 	/* 0B440 */
+	0x2A,  0x7E,  0xAD,  0x2A,  0x5E,  0xA5,  0x2A,  0x52,  0x2D,  0x66,  0x84,  0x21,  0x02,  0x28,  0x24,  0x6F, 	/* 0B450 */
+	0xB8,  0x20,  0x02,  0xEA,  0x3A,  0xAE,  0xF4,  0x2B,  0x42,  0xEA,  0x2A,  0xA6,  0xAA,  0x86,  0x2E,  0x42, 	/* 0B460 */
+	0x28,  0x2F,  0x2F,  0x4C,  0x28,  0x43,  0x7E,  0x21,  0x1E,  0xFE,  0x21,  0x02,  0x28,  0x24,  0x47,  0x82, 	/* 0B470 */
+	0x89,  0x27,  0xC2,  0x48,  0x23,  0x0F,  0xFE,  0x23,  0x42,  0x50,  0x3B,  0x0E,  0xFE,  0x23,  0x82,  0x54, 	/* 0B480 */
+	0x29,  0x26,  0x10,  0x8F,  0x24,  0x42,  0xFE,  0x22,  0x4F,  0x24,  0x20,  0x02,  0xFE,  0x39,  0x2E,  0x92, 	/* 0B490 */
+	0x2F,  0xE2,  0x92,  0x29,  0x26,  0xFE,  0x90,  0x20,  0x02,  0x7C,  0x24,  0x4F,  0x7C,  0x24,  0x43,  0xFE, 	/* 0B4A0 */
+	0x21,  0x0E,  0x50,  0x25,  0xC2,  0xD0,  0x33,  0x06,  0x0F,  0x92,  0x20,  0xC2,  0xF0,  0x21,  0x0F,  0xFE, 	/* 0B4B0 */
+	0x21,  0x02,  0xD6,  0x39,  0x2E,  0x92,  0x2D,  0x62,  0x92,  0x29,  0x26,  0xFE,  0x96,  0x27,  0xC2,  0x44, 	/* 0B4C0 */
+	0x27,  0xCF,  0x00,  0x2F,  0xE2,  0x44,  0x37,  0xCE,  0x44,  0x27,  0xC2,  0x44,  0x2F,  0xC6,  0x04,  0x9A, 	/* 0B4D0 */
+	0x20,  0x02,  0x7C,  0x24,  0x4F,  0x7C,  0x24,  0x42,  0xFF,  0x34,  0x0E,  0xFE,  0x32,  0xA2,  0xD2,  0x22, 	/* 0B4E0 */
+	0x26,  0xCC,  0x9B,  0x22,  0x02,  0x3C,  0x24,  0x8F,  0xFE,  0x2A,  0xA2,  0xAA,  0x3C,  0xEE,  0x92,  0x3F, 	/* 0B4F0 */
+	0xF2,  0x18,  0x22,  0x46,  0xC3,  0xA1,  0x40,  0x05,  0xFC,  0x50,  0x4F,  0xFC,  0x50,  0x05,  0xFE,  0x72, 	/* 0B500 */
+	0xCD,  0xFA,  0x51,  0x05,  0x7C,  0x61,  0x0D,  0xFE,  0xA3,  0x21,  0x02,  0x92,  0x29,  0x2F,  0xFE,  0x20, 	/* 0B510 */
+	0x02,  0xFE,  0x32,  0x0E,  0xFE,  0x2A,  0xA2,  0xAA,  0x2A,  0xA6,  0x86,  0xA9,  0x24,  0x82,  0x49,  0x27, 	/* 0B520 */
+	0xEF,  0x48,  0x24,  0x92,  0xF7,  0x30,  0x8E,  0x7E,  0x24,  0x22,  0x7E,  0x24,  0x26,  0x7E,  0xAE,  0x20, 	/* 0B530 */
+	0x02,  0xFE,  0x29,  0x2F,  0x7C,  0x21,  0x02,  0xFE,  0x39,  0x2E,  0xFE,  0x21,  0x02,  0xFF,  0x21,  0x06, 	/* 0B540 */
+	0x10,  0xB4,  0x20,  0xE2,  0xF4,  0x2A,  0x4F,  0x58,  0x2F,  0xC2,  0x40,  0x3F,  0xEE,  0x40,  0x2F,  0xC2, 	/* 0B550 */
+	0xA4,  0x31,  0x86,  0xE6,  0xB6,  0x40,  0x05,  0xFE,  0x4A,  0xAF,  0xAA,  0x4E,  0xC4,  0xAA,  0x6E,  0xAC, 	/* 0B560 */
+	0xAA,  0x4A,  0xA4,  0xEC,  0x5A,  0x8C,  0x28,  0xBA,  0x20,  0xE2,  0xF2,  0x29,  0x2F,  0x54,  0x2F,  0xE2, 	/* 0B570 */
+	0x10,  0x3F,  0xEE,  0x10,  0x29,  0x22,  0x92,  0x29,  0x26,  0xFE,  0x86,  0x24,  0x82,  0xFC,  0x24,  0x8F, 	/* 0B580 */
+	0xFE,  0x21,  0x02,  0xFC,  0x39,  0x4E,  0xFC,  0x29,  0x43,  0xFE,  0x28,  0x46,  0x8C,  0x8D,  0x2F,  0xC2, 	/* 0B590 */
+	0x84,  0x2F,  0xCF,  0x00,  0x2F,  0xC2,  0x84,  0x3F,  0xCE,  0xFC,  0x28,  0x42,  0xFC,  0x24,  0xC7,  0x82, 	/* 0B5A0 */
+	0x8F,  0x21,  0x42,  0xFE,  0x25,  0x4F,  0x7C,  0x25,  0x42,  0x7C,  0x35,  0x4E,  0x08,  0x3F,  0xE2,  0x88, 	/* 0B5B0 */
+	0x24,  0x86,  0x18,  0x93,  0x24,  0x42,  0x28,  0x2F,  0xEF,  0x10,  0x27,  0xC2,  0x10,  0x3F,  0xFE,  0x40, 	/* 0B5C0 */
+	0x27,  0xC2,  0x90,  0x31,  0x06,  0xFE,  0x96,  0x21,  0xE2,  0x32,  0x2E,  0xCF,  0x18,  0x2E,  0x02,  0x40, 	/* 0B5D0 */
+	0x37,  0xEE,  0x90,  0x3F,  0xE2,  0x10,  0x29,  0x26,  0xFE,  0x97,  0x21,  0x02,  0x7C,  0x24,  0x4F,  0xFC, 	/* 0B5E0 */
+	0x24,  0x42,  0x7E,  0x34,  0x0E,  0x7E,  0x22,  0x22,  0xAA,  0x2F,  0xA6,  0x0C,  0x9C,  0x22,  0x02,  0xD6, 	/* 0B5F0 */
+	0x29,  0x2F,  0xD6,  0x29,  0x22,  0xFE,  0x31,  0x0E,  0xFE,  0x24,  0x82,  0x30,  0x22,  0x86,  0xC4,  0xA6, 	/* 0B600 */
+	0x20,  0x02,  0xEE,  0x22,  0x2F,  0xEE,  0x28,  0x82,  0xEE,  0x36,  0x6E,  0xAA,  0x26,  0x62,  0xAA,  0x22, 	/* 0B610 */
+	0x26,  0xCC,  0xA8,  0x27,  0xC2,  0x44,  0x27,  0xCF,  0x44,  0x27,  0xC2,  0x00,  0x3F,  0xEE,  0x66,  0x2A, 	/* 0B620 */
+	0xA2,  0x66,  0x2A,  0xA6,  0xCC,  0xAC,  0x49,  0xC5,  0xD4,  0x55,  0x4F,  0xD4,  0x56,  0x65,  0xC0,  0x77, 	/* 0B630 */
+	0xCD,  0xD4,  0x55,  0x45,  0x48,  0x65,  0x4C,  0x62,  0xAD,  0x24,  0x83,  0xFE,  0x24,  0x8F,  0x30,  0x24, 	/* 0B640 */
+	0x82,  0x84,  0x37,  0xAE,  0x00,  0x2F,  0xC2,  0x84,  0x28,  0x46,  0xFC,  0xB4,  0x04,  0x0F,  0xFE,  0x91, 	/* 0B650 */
+	0x23,  0xF8,  0x11,  0x0F,  0xFF,  0x11,  0x02,  0xE8,  0xC4,  0x63,  0xF8,  0x04,  0x00,  0xC0,  0xB6,  0x21, 	/* 0B660 */
+	0x02,  0x18,  0x22,  0x4F,  0x7A,  0x2C,  0x52,  0x7C,  0x34,  0x4E,  0x7C,  0x28,  0x02,  0xFC,  0x34,  0x46, 	/* 0B670 */
+	0x7C,  0xBA,  0x24,  0x42,  0x7E,  0x2C,  0x8F,  0x7E,  0x24,  0x82,  0x7E,  0x34,  0x8E,  0xFE,  0x22,  0x42, 	/* 0B680 */
+	0x26,  0x24,  0x26,  0x8C,  0xBE,  0x20,  0x82,  0xFF,  0x29,  0x5F,  0x14,  0x26,  0x72,  0x40,  0x37,  0xFE, 	/* 0B690 */
+	0x50,  0x25,  0xE2,  0x90,  0x21,  0xE6,  0x10,  0x82,  0x2F,  0xE2,  0x44,  0x27,  0xCF,  0x44,  0x27,  0xC2, 	/* 0B6A0 */
+	0x44,  0x3F,  0xFE,  0x84,  0x24,  0x82,  0x00,  0x2C,  0xC7,  0x02,  0x8E,  0x20,  0x02,  0xFE,  0x26,  0x6F, 	/* 0B6B0 */
+	0xAA,  0x26,  0x62,  0xAA,  0x31,  0x8E,  0x66,  0x39,  0x92,  0x64,  0x21,  0x86,  0xE0,  0x98,  0x21,  0x02, 	/* 0B6C0 */
+	0xFE,  0x24,  0x4F,  0x28,  0x2F,  0xE2,  0x92,  0x3B,  0xAE,  0x92,  0x2B,  0xA2,  0xAA,  0x2B,  0xA6,  0x86, 	/* 0B6D0 */
+	0xA7,  0x21,  0x02,  0x92,  0x2F,  0xEF,  0x48,  0x25,  0x02,  0xFE,  0x39,  0x0E,  0xFC,  0x29,  0x02,  0xFC, 	/* 0B6E0 */
+	0x29,  0x06,  0xFE,  0xA9,  0x04,  0x07,  0xFE,  0x48,  0x87,  0xFE,  0x5D,  0xC6,  0xAA,  0x48,  0x85,  0xF8, 	/* 0B6F0 */
+	0x42,  0x0B,  0xFE,  0x82,  0x00,  0xC0,  0xAF,  0x21,  0x0F,  0x90,  0x27,  0xCF,  0x94,  0x51,  0x5F,  0xA5, 	/* 0B700 */
+	0x27,  0x33,  0xF8,  0x02,  0x0F,  0xFE,  0x02,  0x00,  0x60,  0xB6,  0x21,  0x42,  0xFF,  0x25,  0x2F,  0x7E, 	/* 0B710 */
+	0x25,  0x22,  0xFE,  0x30,  0xAE,  0xFE,  0x20,  0x42,  0xFE,  0x22,  0x46,  0x0C,  0xB8,  0x22,  0x82,  0xFE, 	/* 0B720 */
+	0x22,  0x8F,  0x7C,  0x24,  0x42,  0x7C,  0x37,  0xCE,  0x10,  0x2F,  0xE2,  0x30,  0x24,  0x87,  0x86,  0xBA, 	/* 0B730 */
+	0x20,  0x03,  0xFE,  0x2A,  0xAF,  0x66,  0x2B,  0xA2,  0x66,  0x32,  0x0E,  0x7C,  0x24,  0x42,  0x7C,  0x24, 	/* 0B740 */
+	0x46,  0x7C,  0x83,  0x11,  0xCF,  0xD4,  0x55,  0x57,  0xFF,  0x55,  0x4F,  0xDC,  0x12,  0x33,  0xF8,  0x02, 	/* 0B750 */
+	0x0F,  0xFE,  0x02,  0x00,  0x60,  0x88,  0x22,  0x82,  0xAA,  0x25,  0x4F,  0xFE,  0x29,  0x22,  0x92,  0x2F, 	/* 0B760 */
+	0xCE,  0x14,  0x22,  0x42,  0x24,  0x24,  0x46,  0x98,  0x92,  0x4A,  0x84,  0xA8,  0x5F,  0xFE,  0xAA,  0x5F, 	/* 0B770 */
+	0xA4,  0xB2,  0x6E,  0xAC,  0xA4,  0x4E,  0x44,  0xAA,  0x4B,  0x2C,  0xA1,  0x93,  0x21,  0x02,  0x7C,  0x21, 	/* 0B780 */
+	0x0F,  0xFE,  0x24,  0x42,  0xFE,  0x34,  0x4E,  0xFE,  0x27,  0xC2,  0x28,  0x24,  0xA6,  0x86,  0x95,  0x54, 	/* 0B790 */
+	0x25,  0x5C,  0x7F,  0x0F,  0x50,  0x5D,  0xE5,  0x54,  0x7D,  0x4D,  0x54,  0x7F,  0x44,  0xD4,  0x52,  0x4E, 	/* 0B7A0 */
+	0x44,  0x9A,  0x48,  0x84,  0xEC,  0x4A,  0xAE,  0xBE,  0x56,  0x84,  0x48,  0x69,  0x4D,  0x22,  0x40,  0x05, 	/* 0B7B0 */
+	0x54,  0x52,  0xAE,  0x2A,  0x9E,  0x21,  0x02,  0xFC,  0x24,  0x8F,  0xFE,  0x20,  0x02,  0x7C,  0x35,  0x4E, 	/* 0B7C0 */
+	0x7C,  0x25,  0x42,  0xFE,  0x21,  0x07,  0xFF,  0xA4,  0x44,  0x85,  0xE8,  0x4A,  0xFF,  0xF2,  0x41,  0x25, 	/* 0B7D0 */
+	0xEA,  0x72,  0xAD,  0xE4,  0x52,  0x45,  0xEA,  0x52,  0xAD,  0x71,  0xA5,  0x2F,  0x42,  0x28,  0x2E,  0xAF, 	/* 0B7E0 */
+	0x44,  0x2F,  0xE3,  0x35,  0x2E,  0x6E,  0x9C,  0x2F,  0x42,  0x28,  0x23,  0x46,  0xD2,  0xA9,  0x21,  0x02, 	/* 0B7F0 */
+	0xFE,  0x2A,  0xAF,  0x7C,  0x2C,  0x62,  0x7C,  0x34,  0x4E,  0x7C,  0x21,  0x02,  0x54,  0x29,  0x26,  0x30, 	/* 0B800 */
+	0xAB,  0x48,  0x04,  0xFF,  0x5A,  0xAF,  0xAA,  0x5F,  0xF4,  0xAA,  0x6A,  0xAD,  0xFF,  0x40,  0x04,  0xAA, 	/* 0B810 */
+	0x4A,  0x9D,  0x25,  0xAD,  0x21,  0xC2,  0xE4,  0x2A,  0x8F,  0xFE,  0x27,  0x02,  0xA8,  0x32,  0x4E,  0xFE, 	/* 0B820 */
+	0x2A,  0x52,  0xFC,  0x2A,  0x46,  0xFC,  0xAE,  0x27,  0xC2,  0x44,  0x27,  0xCF,  0x44,  0x3F,  0xE2,  0xA0, 	/* 0B830 */
+	0x2F,  0xEF,  0xAA,  0x2E,  0xA2,  0xA4,  0x2E,  0xA6,  0x32,  0xB0,  0x2E,  0xE2,  0x22,  0x2E,  0xEF,  0x88, 	/* 0B840 */
+	0x2E,  0xE2,  0x48,  0x3F,  0xCE,  0x48,  0x24,  0x83,  0xFE,  0x24,  0x87,  0x84,  0xB2,  0x45,  0x05,  0x54, 	/* 0B850 */
+	0x7F,  0xEE,  0x50,  0x5F,  0xC4,  0x20,  0x6F,  0xCC,  0x20,  0x5F,  0xE4,  0x30,  0x44,  0x8D,  0x86,  0xB9, 	/* 0B860 */
+	0x2A,  0x22,  0x54,  0x2F,  0xEF,  0x82,  0x27,  0xC2,  0x44,  0x37,  0xCE,  0x44,  0x27,  0xC2,  0x28,  0x24, 	/* 0B870 */
+	0xA6,  0x86,  0xBB,  0x28,  0x82,  0x7E,  0x20,  0x8F,  0x7E,  0x2A,  0x22,  0x14,  0x3F,  0xEE,  0x88,  0x2B, 	/* 0B880 */
+	0xE2,  0x88,  0x34,  0x86,  0x3F,  0xBC,  0x20,  0xA2,  0xFE,  0x28,  0x8F,  0xFA,  0x28,  0xA2,  0xF4,  0x35, 	/* 0B890 */
+	0x5E,  0x7B,  0x29,  0x12,  0xAA,  0x32,  0x26,  0x1E,  0x81,  0x41,  0x05,  0xFE,  0x49,  0x4E,  0x94,  0x57, 	/* 0B8A0 */
+	0xE5,  0x68,  0x6B,  0xED,  0x68,  0x7F,  0xE4,  0xA8,  0x52,  0x8E,  0x3E,  0x82,  0x27,  0xC2,  0x10,  0x2F, 	/* 0B8B0 */
+	0xEF,  0xDA,  0x2B,  0x62,  0x92,  0x30,  0x0E,  0xFE,  0x29,  0x22,  0xFE,  0x29,  0x26,  0xFE,  0x85,  0x22, 	/* 0B8C0 */
+	0x03,  0xFE,  0x2D,  0x42,  0xF4,  0xF8,  0x42,  0xFC,  0x24,  0x83,  0x78,  0xE4,  0x82,  0x78,  0x20,  0x06, 	/* 0B8D0 */
+	0xFE,  0x87,  0x2F,  0xE2,  0xAA,  0x2F,  0xEF,  0x7C,  0x21,  0x02,  0xFE,  0x24,  0x83,  0xFE,  0xE1,  0x02, 	/* 0B8E0 */
+	0xFC,  0x21,  0x06,  0x10,  0x8D,  0x27,  0xC2,  0x44,  0x27,  0xCF,  0xEE,  0x2A,  0xA2,  0xEE,  0x31,  0x0E, 	/* 0B8F0 */
+	0xFE,  0x23,  0x82,  0x54,  0x29,  0x26,  0x10,  0x92,  0x22,  0x02,  0x70,  0x2A,  0x8F,  0xFC,  0x2A,  0x22, 	/* 0B900 */
+	0xD4,  0x3F,  0xCE,  0x20,  0x2F,  0xE2,  0xAA,  0x2F,  0xA6,  0x86,  0x94,  0x23,  0xC2,  0x48,  0x2F,  0xFF, 	/* 0B910 */
+	0x94,  0x2E,  0x72,  0x9C,  0x38,  0x0E,  0xFF,  0x28,  0x02,  0xBE,  0x2A,  0x27,  0x3E,  0x98,  0x78,  0x84, 	/* 0B920 */
+	0xBE,  0x79,  0x44,  0x7E,  0x78,  0x84,  0xBE,  0xB9,  0x81,  0xE0,  0x02,  0x0F,  0xFE,  0x02,  0x00,  0x60, 	/* 0B930 */
+	0x9A,  0x23,  0xC2,  0x20,  0x2F,  0xEF,  0xBA,  0x2D,  0xE2,  0x80,  0x3F,  0xEE,  0x9A,  0x2A,  0xC2,  0xDA, 	/* 0B940 */
+	0x32,  0x96,  0x58,  0xA0,  0x21,  0x02,  0xFE,  0x22,  0x8F,  0xEA,  0x2B,  0xC2,  0xB4,  0x35,  0x2E,  0x7C, 	/* 0B950 */
+	0x24,  0x42,  0x7C,  0x24,  0x46,  0x84,  0xA1,  0x21,  0x02,  0xFE,  0x24,  0x4F,  0xFE,  0x28,  0x22,  0x7C, 	/* 0B960 */
+	0x32,  0x4E,  0xFA,  0x21,  0x22,  0x7C,  0x21,  0x06,  0xFE,  0xA2,  0x2F,  0xE2,  0x22,  0x2E,  0xEF,  0x22, 	/* 0B970 */
+	0x2E,  0xE2,  0x48,  0x3F,  0xEE,  0x90,  0x2F,  0xC2,  0xFC,  0x29,  0x06,  0xFE,  0xA3,  0x21,  0x02,  0xFE, 	/* 0B980 */
+	0x21,  0x0F,  0x7E,  0x20,  0x22,  0x7C,  0x31,  0x0F,  0xFE,  0x2E,  0x42,  0xB4,  0x2E,  0x46,  0x0C,  0xA6, 	/* 0B990 */
+	0x41,  0x05,  0xFE,  0x50,  0x2E,  0xEE,  0x5A,  0xA4,  0x44,  0x6B,  0xAD,  0x00,  0x5F,  0xE4,  0x94,  0x51, 	/* 0B9A0 */
+	0x2C,  0x30,  0xA7,  0x18,  0x06,  0xEC,  0x48,  0x46,  0x6C,  0x4A,  0x4F,  0xFE,  0x11,  0x82,  0xF4,  0xC2, 	/* 0B9B0 */
+	0x27,  0xFE,  0x02,  0x00,  0x60,  0xAC,  0x51,  0xE5,  0xE2,  0x51,  0x4F,  0x28,  0x4F,  0xE5,  0x0A,  0x5E, 	/* 0B9C0 */
+	0xCF,  0x48,  0x5E,  0xE4,  0x68,  0x4B,  0x8D,  0x26,  0xAF,  0x21,  0x02,  0xFE,  0x29,  0x2F,  0x54,  0x2B, 	/* 0B9D0 */
+	0x82,  0xFC,  0x34,  0x4E,  0x7C,  0x24,  0x42,  0x7C,  0x22,  0x46,  0xC2,  0xB1,  0x5D,  0xE5,  0x52,  0x5D, 	/* 0B9E0 */
+	0xEF,  0x52,  0x5F,  0xE5,  0x52,  0x7B,  0x2D,  0x4A,  0x5F,  0x65,  0x52,  0x57,  0x2D,  0x06,  0xB2,  0x44, 	/* 0B9F0 */
+	0x04,  0xFC,  0x55,  0x4F,  0xF4,  0x55,  0x85,  0xB4,  0x7F,  0x2C,  0x92,  0x7F,  0x24,  0xDC,  0x53,  0x0E, 	/* 0BA00 */
+	0x10,  0xB4,  0x41,  0x05,  0xFE,  0x52,  0x8F,  0x7C,  0x52,  0x85,  0xFE,  0x55,  0x47,  0x7C,  0xD5,  0x45, 	/* 0BA10 */
+	0x7C,  0x62,  0x4C,  0xC2,  0xB6,  0x28,  0x82,  0xEE,  0x35,  0x4F,  0x28,  0x2F,  0xE2,  0x00,  0x3E,  0xAE, 	/* 0BA20 */
+	0xAA,  0x2E,  0xA2,  0xAA,  0x2E,  0x26,  0xA6,  0xBA,  0x5F,  0xE5,  0x4A,  0x5F,  0xEE,  0x90,  0x55,  0x25, 	/* 0BA30 */
+	0xFC,  0x75,  0x2D,  0xCE,  0x55,  0x25,  0xFC,  0x55,  0x2D,  0x4E,  0xBD,  0x52,  0x45,  0x74,  0x6D,  0xAF, 	/* 0BA40 */
+	0x74,  0x55,  0x86,  0xDA,  0x7F,  0xEC,  0x20,  0x5F,  0xE4,  0x68,  0x4A,  0x4C,  0x20,  0xBE,  0x5F,  0xE4, 	/* 0BA50 */
+	0x20,  0x47,  0x8E,  0x48,  0x5F,  0xE5,  0x6A,  0x6B,  0x4D,  0x7A,  0x4C,  0x85,  0x30,  0x46,  0x8D,  0x86, 	/* 0BA60 */
+	0x80,  0x2A,  0x8F,  0x5E,  0x6A,  0xCA,  0x5A,  0x2A,  0x8F,  0xFE,  0x11,  0x02,  0xE8,  0xC4,  0x63,  0xF8, 	/* 0BA70 */
+	0x04,  0x00,  0xC0,  0x85,  0x24,  0x42,  0xFE,  0x24,  0x4F,  0xFE,  0x2A,  0xA2,  0x7D,  0x34,  0x4E,  0x7C, 	/* 0BA80 */
+	0x24,  0x42,  0x7C,  0x22,  0x46,  0xC2,  0x98,  0x21,  0x03,  0xFE,  0x2A,  0xAF,  0xEE,  0x22,  0x82,  0xFE, 	/* 0BA90 */
+	0x32,  0x8E,  0xFE,  0x26,  0x23,  0xD4,  0x26,  0x86,  0xC6,  0x9C,  0x29,  0x22,  0xFE,  0x24,  0x8F,  0x7C, 	/* 0BAA0 */
+	0x2C,  0x82,  0x7C,  0x34,  0x8E,  0xFE,  0x2B,  0xA2,  0xEE,  0x2B,  0xA6,  0x86,  0x9D,  0x2F,  0xE2,  0x44, 	/* 0BAB0 */
+	0x27,  0xCF,  0x44,  0x2F,  0xE2,  0x04,  0x3F,  0xFE,  0xAA,  0x2E,  0xE2,  0xAA,  0x2F,  0xF6,  0x22,  0xA3, 	/* 0BAC0 */
+	0x44,  0x8A,  0xF4,  0x50,  0xAF,  0xFE,  0x6E,  0xCB,  0xBA,  0x2E,  0xC7,  0xF0,  0x04,  0x0F,  0xFE,  0x04, 	/* 0BAD0 */
+	0x00,  0xC0,  0xA4,  0x54,  0xA7,  0xF4,  0x55,  0xEF,  0xF4,  0x5B,  0x45,  0xFE,  0x69,  0x4D,  0xF4,  0x49, 	/* 0BAE0 */
+	0xE5,  0xF4,  0x55,  0x4E,  0x1E,  0xAA,  0x22,  0xC2,  0x54,  0x26,  0x4F,  0xFE,  0x28,  0x22,  0x7C,  0x34, 	/* 0BAF0 */
+	0x4E,  0x7C,  0x24,  0x42,  0x7C,  0x22,  0xA6,  0xC6,  0xAB,  0x2E,  0xE2,  0xAA,  0x2E,  0xE7,  0xAA,  0x6F, 	/* 0BB00 */
+	0xEA,  0x48,  0xAF,  0xE3,  0x48,  0x27,  0xE2,  0x24,  0x21,  0x82,  0xE6,  0xAC,  0x2E,  0x82,  0xAE,  0x2F, 	/* 0BB10 */
+	0x0F,  0xAE,  0x2E,  0xA2,  0x7E,  0x34,  0x4E,  0x7C,  0x24,  0x42,  0x7C,  0x22,  0xA6,  0xC6,  0xAF,  0x02, 	/* 0BB20 */
+	0x07,  0xFE,  0x02,  0x00,  0x20,  0x3F,  0x80,  0x88,  0x08,  0x80,  0x50,  0x02,  0x00,  0x50,  0x18,  0x86, 	/* 0BB30 */
+	0x06,  0xB4,  0x04,  0x00,  0x40,  0x07,  0xE0,  0x40,  0x04,  0x07,  0xF8,  0x11,  0x01,  0x10,  0x0A,  0x00, 	/* 0BB40 */
+	0x60,  0x19,  0x8E,  0x06,  0xB5,  0x08,  0x00,  0x80,  0x08,  0x01,  0xFE,  0x10,  0x82,  0x88,  0x49,  0x00, 	/* 0BB50 */
+	0x50,  0x02,  0x00,  0x50,  0x18,  0x8E,  0x06,  0xB6,  0x12,  0x01,  0x20,  0x53,  0xE5,  0x24,  0x54,  0x45, 	/* 0BB60 */
+	0x64,  0x59,  0x45,  0x18,  0x70,  0x8D,  0x18,  0x12,  0x41,  0xC2,  0xB7,  0x02,  0x0F,  0xA0,  0x43,  0xE4, 	/* 0BB70 */
+	0x24,  0x74,  0x45,  0x64,  0x9A,  0x89,  0x18,  0x11,  0x02,  0x28,  0x24,  0x4D,  0x82,  0xB8,  0x22,  0x02, 	/* 0BB80 */
+	0x20,  0x33,  0xE5,  0x24,  0x54,  0x4D,  0x64,  0x5A,  0x85,  0x18,  0x51,  0x05,  0x28,  0x44,  0x45,  0x82, 	/* 0BB90 */
+	0xB9,  0x02,  0x0F,  0xA0,  0x0B,  0xE0,  0xA4,  0xFC,  0x48,  0x64,  0x8A,  0x88,  0x10,  0x89,  0x87,  0xA8, 	/* 0BBA0 */
+	0x04,  0x41,  0x82,  0xBB,  0x02,  0x00,  0x20,  0xF2,  0x02,  0x7E,  0x24,  0x42,  0xA4,  0x22,  0x83,  0x18, 	/* 0BBB0 */
+	0xC1,  0x00,  0x28,  0x04,  0x41,  0x82,  0xBE,  0x22,  0x02,  0x20,  0xFE,  0x02,  0x3E,  0x24,  0x43,  0xC4, 	/* 0BBC0 */
+	0x2A,  0x82,  0xA8,  0x49,  0x04,  0xA8,  0x8C,  0x43,  0x82,  0xBF,  0x02,  0x0F,  0xE0,  0x12,  0x01,  0x3E, 	/* 0BBD0 */
+	0x5E,  0x45,  0x24,  0x55,  0x45,  0x08,  0x54,  0x85,  0x94,  0xE2,  0x20,  0xC1,  0x85,  0x21,  0x02,  0x10, 	/* 0BBE0 */
+	0x22,  0x0F,  0xBE,  0x24,  0x42,  0xA4,  0x7A,  0x44,  0x98,  0x48,  0x84,  0x98,  0x7A,  0x40,  0xC2,  0x88, 	/* 0BBF0 */
+	0x21,  0x02,  0x10,  0xF9,  0xE5,  0x24,  0x4A,  0x44,  0xC4,  0x89,  0x43,  0x18,  0x10,  0x82,  0x94,  0x42, 	/* 0BC00 */
+	0x48,  0x42,  0x8D,  0x10,  0x83,  0x08,  0x28,  0xF4,  0x48,  0x78,  0x89,  0x3E,  0x7C,  0x21,  0x14,  0x58, 	/* 0BC10 */
+	0xC5,  0x48,  0x91,  0x43,  0x62,  0x8F,  0x41,  0x04,  0x10,  0x7D,  0xF8,  0x12,  0x7E,  0x25,  0x72,  0xFD, 	/* 0BC20 */
+	0x45,  0x4C,  0x54,  0x8F,  0xCC,  0x89,  0x23,  0x61,  0x91,  0x19,  0x01,  0x50,  0xFD,  0xE1,  0x24,  0x92, 	/* 0BC30 */
+	0x45,  0x54,  0x58,  0x83,  0x58,  0x55,  0x89,  0x24,  0x14,  0x43,  0x82,  0x95,  0x21,  0x0F,  0xD0,  0x21, 	/* 0BC40 */
+	0xEF,  0xA4,  0xAA,  0x4A,  0xD4,  0xF9,  0x43,  0x08,  0x68,  0x86,  0x94,  0xA2,  0x42,  0xC2,  0x96,  0x11, 	/* 0BC50 */
+	0x01,  0x10,  0x7D,  0xF1,  0x24,  0xFC,  0x42,  0x14,  0xFD,  0x82,  0x08,  0x38,  0xC2,  0x94,  0x4A,  0x29, 	/* 0BC60 */
+	0xC2,  0x97,  0x02,  0x07,  0xA0,  0x4B,  0xE4,  0xA4,  0x7C,  0x44,  0xD4,  0x79,  0x84,  0x88,  0x79,  0x82, 	/* 0BC70 */
+	0xA4,  0x44,  0x48,  0x82,  0x98,  0x11,  0x03,  0x10,  0x29,  0xE4,  0x64,  0x7A,  0x49,  0x44,  0x7D,  0x41, 	/* 0BC80 */
+	0x18,  0x58,  0x85,  0x58,  0x92,  0x43,  0x42,  0x99,  0x21,  0x02,  0x50,  0xF9,  0x02,  0xBE,  0xFE,  0x42, 	/* 0BC90 */
+	0x64,  0x79,  0x49,  0x18,  0x1C,  0x8F,  0x18,  0x12,  0x43,  0xC2,  0x9D,  0x21,  0x06,  0x90,  0x69,  0xEA, 	/* 0BCA0 */
+	0x54,  0xFE,  0x4A,  0x74,  0xA5,  0x4B,  0x48,  0xEC,  0x8A,  0x54,  0xA6,  0x4A,  0xC2,  0x9E,  0x21,  0x06, 	/* 0BCB0 */
+	0x90,  0xA5,  0xF2,  0x12,  0xFA,  0x28,  0xB2,  0xBD,  0x4A,  0x94,  0xA8,  0x8B,  0x98,  0x8A,  0x49,  0xC2, 	/* 0BCC0 */
+	0xA2,  0x01,  0x07,  0xD0,  0x11,  0xEF,  0xE4,  0x4A,  0x47,  0xC4,  0x49,  0x47,  0x94,  0x4C,  0x87,  0x98, 	/* 0BCD0 */
+	0xCA,  0x40,  0xC2,  0xA3,  0x52,  0x0F,  0xA0,  0x53,  0xEF,  0xA4,  0x04,  0x47,  0xC4,  0x4A,  0x87,  0xA8, 	/* 0BCE0 */
+	0x49,  0x07,  0xA8,  0x4C,  0x45,  0x82,  0xA6,  0x12,  0x0F,  0xE0,  0x03,  0xE7,  0xA4,  0x4C,  0x47,  0xC4, 	/* 0BCF0 */
+	0x01,  0x47,  0x94,  0x10,  0x8F,  0xC8,  0x11,  0x43,  0x62,  0xAC,  0x29,  0x0F,  0xD0,  0x29,  0xE2,  0x24, 	/* 0BD00 */
+	0x7E,  0x44,  0x54,  0xF5,  0x45,  0x48,  0x54,  0x87,  0x58,  0x06,  0x41,  0x82,  0xB0,  0x2A,  0x0A,  0xA0, 	/* 0BD10 */
+	0x73,  0xEF,  0xA4,  0x34,  0x46,  0xA4,  0xA2,  0x8F,  0xD8,  0x48,  0x87,  0x18,  0x2A,  0x4C,  0x42,  0xB2, 	/* 0BD20 */
+	0x10,  0x8F,  0xC8,  0x78,  0xE4,  0x88,  0x7B,  0xE0,  0x02,  0xFD,  0x28,  0x54,  0xB4,  0xCB,  0x48,  0xB5, 	/* 0BD30 */
+	0x48,  0x62,  0xB4,  0x22,  0x0F,  0xBE,  0xAA,  0x4F,  0xA4,  0x75,  0x8A,  0x94,  0x22,  0x27,  0xFC,  0x04, 	/* 0BD40 */
+	0x02,  0x7C,  0x24,  0x0F,  0xFE,  0xB5,  0x22,  0x0F,  0xA0,  0x53,  0xE5,  0x24,  0xFC,  0x4A,  0xD4,  0xF9, 	/* 0BD50 */
+	0x4A,  0x88,  0xF8,  0x8C,  0x94,  0xFA,  0x48,  0xC2,  0xB7,  0x2A,  0x0F,  0xA0,  0x23,  0xEF,  0xA4,  0xAC, 	/* 0BD60 */
+	0x4F,  0xE4,  0xAA,  0x8F,  0x90,  0x41,  0x87,  0xA8,  0x4C,  0x49,  0x82,  0xB8,  0x7D,  0x05,  0x50,  0xFF, 	/* 0BD70 */
+	0xF5,  0x52,  0xFE,  0x25,  0x62,  0x7D,  0x42,  0x14,  0xFC,  0x84,  0x94,  0x3A,  0x4E,  0x42,  0x82,  0x11, 	/* 0BD80 */
+	0x02,  0x90,  0x45,  0xEB,  0x94,  0x02,  0x4F,  0xE4,  0xB5,  0x4F,  0xC8,  0x48,  0x86,  0xD4,  0x52,  0x4A, 	/* 0BD90 */
+	0x42,  0x83,  0xA9,  0x07,  0x1E,  0xFE,  0x4A,  0x54,  0xF4,  0x8A,  0xD4,  0x02,  0x2F,  0xFE,  0x22,  0x47, 	/* 0BDA0 */
+	0xB8,  0x92,  0x26,  0x1E,  0x87,  0x04,  0x00,  0x40,  0x7F,  0xE1,  0x08,  0x10,  0x80,  0x90,  0x09,  0x00, 	/* 0BDB0 */
+	0x60,  0x04,  0x00,  0xA0,  0x11,  0x86,  0x06,  0x88,  0x04,  0x0F,  0xFE,  0x11,  0x00,  0xE0,  0x0A,  0x03, 	/* 0BDC0 */
+	0x18,  0xDF,  0x60,  0x20,  0xFF,  0xE0,  0x40,  0x04,  0x00,  0xC0,  0x89,  0x04,  0x0F,  0xFE,  0x11,  0x00, 	/* 0BDD0 */
+	0xE0,  0x31,  0x8E,  0x0E,  0x3F,  0x82,  0x08,  0x3F,  0x82,  0x08,  0x20,  0x84,  0x08,  0x8C,  0x20,  0x82, 	/* 0BDE0 */
+	0x6C,  0xF8,  0xA2,  0xFE,  0xA2,  0x8A,  0xA8,  0x6B,  0x82,  0xA8,  0x5A,  0x84,  0xB4,  0x8E,  0x61,  0x82, 	/* 0BDF0 */
+	0x8E,  0x04,  0x0F,  0xFE,  0x31,  0x80,  0xE0,  0x1B,  0x0E,  0x0E,  0x3F,  0x42,  0x04,  0x3F,  0xC2,  0xD4, 	/* 0BE00 */
+	0x54,  0xC8,  0x44,  0x90,  0x0A,  0x07,  0xBC,  0x0A,  0x07,  0xBC,  0x0A,  0x0F,  0xBE,  0x16,  0x0F,  0xFE, 	/* 0BE10 */
+	0x11,  0x00,  0xE0,  0x1B,  0x0E,  0x0C,  0x91,  0x04,  0x0F,  0x5E,  0x2F,  0x82,  0x28,  0x2A,  0x8F,  0xBE, 	/* 0BE20 */
+	0x2A,  0x82,  0x48,  0x2A,  0x82,  0xA8,  0xF0,  0x82,  0x3E,  0x97,  0x02,  0x03,  0x20,  0x0A,  0x00,  0x20, 	/* 0BE30 */
+	0x62,  0x01,  0x20,  0x02,  0x00,  0x3E,  0xFE,  0x00,  0x20,  0x02,  0x00,  0x20,  0x99,  0x20,  0x4A,  0xA4, 	/* 0BE40 */
+	0x71,  0x42,  0x04,  0xFA,  0x42,  0x14,  0x70,  0x76,  0x9C,  0xA6,  0x4A,  0x04,  0x20,  0x42,  0x04,  0x9B, 	/* 0BE50 */
+	0x20,  0x43,  0xC4,  0x4A,  0x49,  0x14,  0x7C,  0x45,  0x64,  0x7D,  0x45,  0x47,  0x7F,  0xC4,  0x44,  0x44, 	/* 0BE60 */
+	0x48,  0xC4,  0x9C,  0x10,  0x41,  0xA4,  0x25,  0x44,  0x04,  0xBA,  0x41,  0x14,  0x7C,  0x71,  0x3C,  0x54, 	/* 0BE70 */
+	0x45,  0x44,  0x90,  0x43,  0x04,  0x9F,  0x48,  0x4F,  0xE4,  0x49,  0x47,  0x84,  0x4A,  0x47,  0x94,  0x48, 	/* 0BE80 */
+	0x4F,  0xC7,  0xAB,  0xCC,  0xC4,  0x80,  0x47,  0xC4,  0xA1,  0x21,  0x0F,  0x90,  0x22,  0x8F,  0xE4,  0x89, 	/* 0BE90 */
+	0xAF,  0x88,  0x8C,  0x8F,  0xA8,  0x21,  0xEF,  0xE8,  0x20,  0x82,  0x08,  0xA4,  0x00,  0x80,  0x30,  0x3C, 	/* 0BEA0 */
+	0x02,  0x00,  0x3F,  0xE2,  0x20,  0x22,  0x02,  0x20,  0x22,  0x04,  0x20,  0x42,  0x08,  0x20,  0xA5,  0x01, 	/* 0BEB0 */
+	0xC3,  0xE0,  0x20,  0x02,  0x00,  0x3F,  0xE2,  0x20,  0x22,  0x02,  0xE0,  0x43,  0x04,  0x28,  0x82,  0x40, 	/* 0BEC0 */
+	0x20,  0xA7,  0x0B,  0x01,  0x08,  0x69,  0x60,  0x60,  0x19,  0x86,  0x76,  0x3C,  0x02,  0x00,  0x3F,  0xE2, 	/* 0BED0 */
+	0x20,  0x42,  0x08,  0x20,  0xAB,  0x00,  0x6F,  0xF8,  0x22,  0x02,  0x20,  0x43,  0xE7,  0xA4,  0xCA,  0x44, 	/* 0BEE0 */
+	0xA4,  0x4A,  0x44,  0xC4,  0x78,  0x40,  0x04,  0xAC,  0x20,  0x6F,  0xB8,  0x22,  0x0F,  0xA0,  0xAB,  0xEF, 	/* 0BEF0 */
+	0xA4,  0xAA,  0x4F,  0xA4,  0x24,  0x4F,  0xC4,  0x28,  0x42,  0x04,  0xAD,  0x10,  0x49,  0x78,  0xDA,  0x0B, 	/* 0BF00 */
+	0x20,  0xFF,  0xE9,  0x24,  0xBA,  0x4B,  0x64,  0xD2,  0x49,  0x24,  0xFC,  0x40,  0x04,  0xAF,  0x48,  0x64, 	/* 0BF10 */
+	0xB8,  0xFE,  0x04,  0xBE,  0x7A,  0x44,  0xA4,  0x7A,  0x44,  0xA4,  0xFE,  0x42,  0xA4,  0x44,  0x48,  0x84, 	/* 0BF20 */
+	0xB0,  0x20,  0x4F,  0xF8,  0x4A,  0x04,  0xA0,  0xFF,  0xE2,  0x24,  0xFA,  0x43,  0x24,  0x6A,  0x46,  0x44, 	/* 0BF30 */
+	0xA8,  0x42,  0x04,  0xB7,  0xAC,  0x2D,  0x5C,  0xAD,  0x0F,  0xD0,  0x85,  0xFF,  0xD4,  0xAD,  0x4D,  0x54, 	/* 0BF40 */
+	0xAD,  0x4F,  0xD4,  0x86,  0x4F,  0xC4,  0xB9,  0x04,  0x00,  0x40,  0xFF,  0xE0,  0x80,  0x08,  0x00,  0xF8, 	/* 0BF50 */
+	0x08,  0x80,  0x88,  0x10,  0x81,  0x08,  0x20,  0x84,  0x30,  0xBC,  0x21,  0x02,  0x10,  0xFA,  0x82,  0x28, 	/* 0BF60 */
+	0x24,  0x43,  0x92,  0x28,  0x82,  0xA0,  0x49,  0x04,  0x88,  0x88,  0x43,  0x04,  0xBD,  0x22,  0x02,  0x20, 	/* 0BF70 */
+	0xF7,  0xE4,  0x90,  0x75,  0xC5,  0x74,  0x5D,  0x45,  0x54,  0x55,  0xC9,  0x50,  0x14,  0x26,  0x3E,  0x81, 	/* 0BF80 */
+	0x04,  0x07,  0xFE,  0x10,  0x80,  0x90,  0xFF,  0xE8,  0x42,  0xFF,  0xA0,  0x80,  0x0F,  0x80,  0x88,  0x10, 	/* 0BF90 */
+	0x86,  0x30,  0x83,  0x22,  0x02,  0x20,  0xFF,  0xE2,  0x40,  0x2B,  0xE3,  0xAA,  0x2A,  0xA2,  0xFF,  0x4A, 	/* 0BFA0 */
+	0x24,  0xA2,  0x8A,  0x23,  0x26,  0x84,  0x24,  0x02,  0x40,  0xF7,  0xE4,  0x80,  0x50,  0xC7,  0x70,  0x51, 	/* 0BFB0 */
+	0xC5,  0x70,  0x51,  0xE9,  0xF0,  0x91,  0x23,  0x0E,  0x85,  0x22,  0x02,  0x20,  0xFF,  0xE2,  0x28,  0x24, 	/* 0BFC0 */
+	0xA3,  0x94,  0x29,  0x82,  0xB4,  0x4D,  0x44,  0x92,  0x89,  0x13,  0x10,  0x86,  0x22,  0x02,  0x20,  0xF7, 	/* 0BFD0 */
+	0xE4,  0x90,  0x7F,  0xE5,  0x10,  0x57,  0xC5,  0x54,  0x55,  0x49,  0x5C,  0x95,  0x03,  0x10,  0x8B,  0x22, 	/* 0BFE0 */
+	0x02,  0x20,  0xF3,  0xE4,  0x40,  0x77,  0xC5,  0x90,  0x55,  0x05,  0x5C,  0x55,  0x05,  0x70,  0x95,  0x06, 	/* 0BFF0 */
+	0x8E,  0x8C,  0x22,  0x02,  0x20,  0xFB,  0xE4,  0x50,  0x75,  0x05,  0x7E,  0x59,  0x05,  0x10,  0x57,  0xC9, 	/* 0C000 */
+	0x10,  0x11,  0x06,  0xFE,  0x8F,  0x22,  0x02,  0x20,  0xFF,  0xE2,  0x50,  0x2B,  0xE3,  0xC8,  0x28,  0x82, 	/* 0C010 */
+	0xFE,  0x48,  0x84,  0x94,  0x8A,  0x43,  0x42,  0x92,  0x22,  0x02,  0x7E,  0xF9,  0x04,  0xFE,  0x42,  0x47, 	/* 0C020 */
+	0x7A,  0x50,  0x45,  0x54,  0x55,  0x49,  0x54,  0x15,  0x46,  0x83,  0x97,  0x22,  0x02,  0x7E,  0xFA,  0x42, 	/* 0C030 */
+	0xFE,  0x22,  0x43,  0xBC,  0x2A,  0x42,  0xBC,  0x4A,  0x44,  0xFE,  0x89,  0x43,  0x62,  0x99,  0x20,  0x42, 	/* 0C040 */
+	0xF8,  0xF9,  0x44,  0x58,  0x7F,  0xE5,  0x34,  0x55,  0x25,  0xFD,  0x55,  0x49,  0x7C,  0x15,  0x46,  0x7C, 	/* 0C050 */
+	0x9B,  0x22,  0x02,  0x3E,  0xF4,  0xC4,  0xF4,  0x75,  0x85,  0xFE,  0x53,  0x45,  0x7E,  0x5D,  0x59,  0x7C, 	/* 0C060 */
+	0x15,  0x46,  0x7C,  0xA0,  0x00,  0x07,  0xFC,  0x04,  0x00,  0x40,  0xFF,  0xE0,  0x40,  0x06,  0x00,  0xA0, 	/* 0C070 */
+	0x0A,  0x01,  0x22,  0x22,  0x2C,  0x1E,  0xA1,  0x00,  0x07,  0xFC,  0x04,  0x04,  0x40,  0x44,  0x07,  0xFE, 	/* 0C080 */
+	0x46,  0x00,  0xA0,  0x0A,  0x01,  0x22,  0x22,  0x2C,  0x1E,  0xA2,  0x00,  0x07,  0xFE,  0x4A,  0x87,  0xA8, 	/* 0C090 */
+	0x4A,  0x84,  0xFE,  0x79,  0x84,  0x18,  0x52,  0x85,  0xAA,  0x64,  0xA8,  0x86,  0xA5,  0x00,  0x03,  0xF8, 	/* 0C0A0 */
+	0x20,  0x82,  0x08,  0x20,  0x82,  0x08,  0x3F,  0x82,  0x08,  0x20,  0x82,  0x08,  0x20,  0x83,  0xF8,  0xA6, 	/* 0C0B0 */
+	0x00,  0x03,  0xF8,  0x20,  0x82,  0x08,  0x3F,  0x82,  0x08,  0x20,  0x82,  0x08,  0x3F,  0x80,  0x00,  0x00, 	/* 0C0C0 */
+	0x0F,  0xFE,  0xA7,  0x40,  0x04,  0xFC,  0x48,  0x44,  0x84,  0x48,  0x44,  0xFC,  0x48,  0x44,  0x84,  0x48, 	/* 0C0D0 */
+	0x44,  0x84,  0x4F,  0xC4,  0x00,  0xA8,  0x40,  0x04,  0x38,  0x7C,  0x04,  0x04,  0x3F,  0xC0,  0x00,  0x3F, 	/* 0C0E0 */
+	0x82,  0x08,  0x3F,  0x82,  0x08,  0x20,  0x83,  0xF8,  0xA9,  0x00,  0x03,  0xFC,  0x20,  0x43,  0xFC,  0x20, 	/* 0C0F0 */
+	0x43,  0xFC,  0x04,  0x00,  0x40,  0xFF,  0xE0,  0x40,  0x04,  0x00,  0x40,  0xAC,  0x10,  0x01,  0x00,  0x3F, 	/* 0C100 */
+	0xE2,  0x02,  0x5F,  0x29,  0x12,  0x1F,  0x21,  0x12,  0x11,  0x21,  0xF2,  0x00,  0x20,  0x0C,  0xAD,  0x20, 	/* 0C110 */
+	0x02,  0x3E,  0x22,  0x2F,  0xA2,  0x2B,  0xE2,  0xA2,  0x2A,  0x22,  0xA2,  0x2A,  0x24,  0xBE,  0x48,  0x18, 	/* 0C120 */
+	0x7F,  0xB1,  0x3F,  0x82,  0x08,  0x3F,  0x82,  0x08,  0x3F,  0x80,  0x00,  0x7F,  0xC0,  0x40,  0xFF,  0xE0, 	/* 0C130 */
+	0x40,  0x04,  0x00,  0x40,  0xBA,  0x00,  0x0F,  0xFE,  0x91,  0x09,  0x10,  0x91,  0x0F,  0x10,  0x9F,  0xC9, 	/* 0C140 */
+	0x10,  0x91,  0x0F,  0x10,  0x01,  0x01,  0xFE,  0xBB,  0x00,  0x03,  0xF8,  0x20,  0x83,  0xF8,  0x20,  0x83, 	/* 0C150 */
+	0xF8,  0x04,  0x0F,  0xFE,  0x31,  0x80,  0xE0,  0x19,  0x8E,  0x06,  0x82,  0x3F,  0xC2,  0x04,  0x3F,  0xC2, 	/* 0C160 */
+	0x04,  0x3F,  0xC0,  0x80,  0x73,  0xE4,  0x22,  0x42,  0x25,  0xA2,  0xE2,  0xC0,  0x20,  0x83,  0x3F,  0x82, 	/* 0C170 */
+	0x08,  0x3F,  0x82,  0x08,  0x3F,  0x80,  0x00,  0x7F,  0xE4,  0x40,  0x44,  0x04,  0xA0,  0x91,  0x0A,  0x0C, 	/* 0C180 */
+	0x86,  0x00,  0x03,  0xFC,  0x20,  0x43,  0xFC,  0x20,  0x43,  0xFC,  0x22,  0x03,  0xE6,  0x23,  0x82,  0x22, 	/* 0C190 */
+	0x3A,  0x2E,  0x1E,  0x87,  0x00,  0x03,  0xFC,  0x20,  0x43,  0xFC,  0x20,  0x43,  0xFC,  0x1D,  0x06,  0x90, 	/* 0C1A0 */
+	0xFF,  0xE1,  0x10,  0x21,  0x04,  0x10,  0x8A,  0x3F,  0x82,  0x08,  0x3F,  0x82,  0x08,  0x3F,  0x80,  0x00, 	/* 0C1B0 */
+	0xFF,  0xE0,  0x40,  0x7F,  0xC0,  0xA0,  0x31,  0x8C,  0x06,  0x8C,  0x00,  0x03,  0xF8,  0x20,  0x83,  0xF8, 	/* 0C1C0 */
+	0x20,  0x83,  0xF8,  0x00,  0x07,  0xFC,  0x40,  0x47,  0xFC,  0x40,  0x47,  0xFC,  0x8E,  0x00,  0x07,  0xBE, 	/* 0C1D0 */
+	0x4A,  0x24,  0xA2,  0x7B,  0xE4,  0xA2,  0x4A,  0x24,  0xBE,  0x7A,  0x24,  0x22,  0x04,  0x20,  0x86,  0x8F, 	/* 0C1E0 */
+	0x07,  0x87,  0xE0,  0x42,  0x07,  0xFE,  0x41,  0x05,  0x8A,  0xE0,  0x63,  0xFA,  0x20,  0x83,  0xF8,  0x20, 	/* 0C1F0 */
+	0x83,  0xF8,  0x93,  0x00,  0x01,  0xFC,  0x10,  0x41,  0xFC,  0x10,  0x41,  0xFC,  0x08,  0x01,  0xFE,  0x64, 	/* 0C200 */
+	0xA0,  0x92,  0x32,  0x20,  0xCC,  0x94,  0x11,  0x07,  0xFC,  0x11,  0x01,  0x10,  0xFF,  0xE0,  0x00,  0x3F, 	/* 0C210 */
+	0x82,  0x08,  0x3F,  0x82,  0x08,  0x20,  0x83,  0xF8,  0x9C,  0x00,  0x03,  0xF8,  0x20,  0x83,  0xF8,  0x20, 	/* 0C220 */
+	0x8F,  0xFE,  0x10,  0x01,  0xFC,  0x29,  0x44,  0x94,  0x92,  0x42,  0x58,  0x9F,  0x00,  0x03,  0xFC,  0x20, 	/* 0C230 */
+	0x43,  0xFC,  0x20,  0x43,  0xFC,  0x24,  0x03,  0xFC,  0x44,  0x09,  0xF8,  0x04,  0x07,  0xFE,  0xA0,  0x02, 	/* 0C240 */
+	0x0E,  0x20,  0xAF,  0xCA,  0xA4,  0xAA,  0x4E,  0xA4,  0xBF,  0xEA,  0x30,  0xA5,  0x0E,  0x48,  0x08,  0x43, 	/* 0C250 */
+	0x02,  0xA5,  0x04,  0x03,  0xF8,  0x04,  0x07,  0xFC,  0x0A,  0x0F,  0xFE,  0x20,  0x85,  0xF4,  0x91,  0x21, 	/* 0C260 */
+	0xF0,  0x11,  0x01,  0xF0,  0xA7,  0x02,  0x0E,  0x20,  0xBF,  0xCA,  0x20,  0xA2,  0x0F,  0xFC,  0xA2,  0x0A, 	/* 0C270 */
+	0x70,  0xAA,  0x8F,  0x26,  0x82,  0x00,  0x20,  0xA8,  0x02,  0x0F,  0x20,  0x93,  0xF9,  0x50,  0x95,  0x0F, 	/* 0C280 */
+	0x9E,  0x91,  0x09,  0x10,  0x91,  0xEF,  0x10,  0x01,  0x00,  0x10,  0xAD,  0x00,  0x0F,  0xFE,  0x91,  0x29, 	/* 0C290 */
+	0x12,  0x92,  0x2F,  0x4C,  0x98,  0x09,  0x7E,  0x94,  0x2F,  0x42,  0x04,  0x20,  0x7E,  0xAF,  0x3F,  0x82, 	/* 0C2A0 */
+	0x08,  0x3F,  0x82,  0x08,  0x3F,  0x80,  0x00,  0xFF,  0xE0,  0x40,  0x27,  0xC3,  0x40,  0x4C,  0x08,  0x3E, 	/* 0C2B0 */
+	0xB4,  0x3F,  0xC2,  0x04,  0x3F,  0xC2,  0x04,  0x3F,  0xC0,  0x80,  0x75,  0xE4,  0x52,  0x45,  0x2F,  0x9C, 	/* 0C2C0 */
+	0x09,  0x01,  0x10,  0xB5,  0x00,  0x00,  0xFE,  0xE8,  0x2A,  0xFE,  0xAA,  0x0E,  0xA0,  0xAA,  0x6A,  0xB8, 	/* 0C2D0 */
+	0xAA,  0x0F,  0x22,  0x12,  0x22,  0x1E,  0xB6,  0x00,  0x07,  0x9E,  0x01,  0x27,  0x12,  0x13,  0xEF,  0x52, 	/* 0C2E0 */
+	0x39,  0x23,  0x52,  0x55,  0xE5,  0x20,  0x91,  0x83,  0x07,  0xBC,  0x00,  0x01,  0xFC,  0x10,  0x41,  0xFC, 	/* 0C2F0 */
+	0x10,  0x83,  0xFC,  0x50,  0xA9,  0xF9,  0x10,  0x81,  0xF8,  0x00,  0x0F,  0xFE,  0xBF,  0x01,  0x0E,  0x10, 	/* 0C300 */
+	0xAF,  0xEA,  0x80,  0xA9,  0x0E,  0x90,  0xA9,  0x0A,  0x90,  0xAA,  0x8F,  0x44,  0x1F,  0xA2,  0x02,  0x81, 	/* 0C310 */
+	0x00,  0x07,  0xFC,  0x40,  0x47,  0xFC,  0x40,  0x47,  0xFC,  0x4A,  0x42,  0xA8,  0x3B,  0x8D,  0x24,  0x22, 	/* 0C320 */
+	0x24,  0x1E,  0x82,  0x02,  0x0E,  0xFC,  0xA2,  0x0A,  0x20,  0xBF,  0xEE,  0x08,  0xBF,  0xEA,  0x88,  0xA4, 	/* 0C330 */
+	0x8A,  0x08,  0xE0,  0x80,  0x18,  0x83,  0x00,  0x03,  0xF8,  0x20,  0x83,  0xF8,  0x20,  0x83,  0xF8,  0x44, 	/* 0C340 */
+	0x42,  0x48,  0xFF,  0xE0,  0xA0,  0x32,  0x2C,  0x1E,  0x84,  0x02,  0x0E,  0x20,  0xB2,  0x4A,  0xA4,  0xAA, 	/* 0C350 */
+	0x8F,  0xFE,  0xA5,  0x0A,  0x50,  0xA5,  0x0E,  0x90,  0x11,  0x22,  0x0E,  0x89,  0x00,  0x0F,  0xFE,  0x29, 	/* 0C360 */
+	0x47,  0xBC,  0x08,  0x4F,  0xFE,  0x00,  0x03,  0xF8,  0x20,  0x83,  0xF8,  0x20,  0x83,  0xF8,  0x8B,  0x00, 	/* 0C370 */
+	0x07,  0xFC,  0x4A,  0x42,  0xA4,  0x2A,  0x8F,  0xFE,  0x00,  0x03,  0xF8,  0x20,  0x83,  0xF8,  0x20,  0x83, 	/* 0C380 */
+	0xF8,  0x8F,  0x3F,  0x82,  0x08,  0x3F,  0x82,  0x08,  0x3F,  0x8F,  0xFE,  0x88,  0x27,  0xFE,  0x11,  0x03, 	/* 0C390 */
+	0xE0,  0x0D,  0x87,  0x04,  0x92,  0x0F,  0xEE,  0x28,  0xA2,  0x8A,  0xFE,  0xAA,  0xAE,  0xAA,  0xAA,  0xAA, 	/* 0C3A0 */
+	0xAA,  0xAC,  0xEE,  0x82,  0x0F,  0xE0,  0x80,  0x9D,  0x04,  0x07,  0xF8,  0x04,  0x8F,  0xFE,  0x04,  0x87, 	/* 0C3B0 */
+	0xF8,  0x04,  0x0F,  0xFC,  0x20,  0x83,  0xF8,  0x20,  0x8F,  0xFE,  0x9E,  0x00,  0x4E,  0xC8,  0xA7,  0x0B, 	/* 0C3C0 */
+	0xA8,  0xBF,  0xEE,  0x50,  0xA7,  0xCA,  0xD4,  0xB5,  0x4E,  0x54,  0x05,  0xC0,  0x10,  0x9F,  0x3F,  0xC2, 	/* 0C3D0 */
+	0x04,  0x3F,  0xC2,  0x04,  0x3F,  0xC0,  0x14,  0x7F,  0xE4,  0x10,  0x79,  0x44,  0x88,  0x69,  0x69,  0x22, 	/* 0C3E0 */
+	0xA2,  0x20,  0x6F,  0xB8,  0x22,  0x03,  0x3E,  0xE2,  0x82,  0x48,  0x28,  0x87,  0xFC,  0x40,  0x47,  0xFC, 	/* 0C3F0 */
+	0x40,  0x47,  0xFC,  0xA4,  0x00,  0x01,  0xFE,  0xF1,  0x09,  0x7C,  0x92,  0x4F,  0x24,  0x9F,  0xF9,  0x00, 	/* 0C400 */
+	0x97,  0xC9,  0x44,  0xF4,  0x40,  0x7C,  0xA6,  0x04,  0x0E,  0x7E,  0xA4,  0x0A,  0xFC,  0xB5,  0x4E,  0x54, 	/* 0C410 */
+	0xBF,  0xEA,  0x94,  0xA9,  0x4E,  0xFE,  0x00,  0x40,  0x18,  0xA7,  0x01,  0x0F,  0x50,  0x97,  0xE9,  0x90, 	/* 0C420 */
+	0x91,  0x0F,  0xFF,  0x91,  0x09,  0x7C,  0x94,  0x4F,  0x44,  0x04,  0x40,  0x7C,  0xA8,  0x1F,  0x81,  0x08, 	/* 0C430 */
+	0x1F,  0x81,  0x08,  0x7F,  0xE4,  0x00,  0x5F,  0xE4,  0xA4,  0x49,  0x84,  0x88,  0x8E,  0x49,  0x82,  0xA9, 	/* 0C440 */
+	0x02,  0x00,  0x78,  0xE9,  0x0B,  0xFC,  0xAA,  0x4E,  0xA4,  0xAF,  0xCA,  0x50,  0xA5,  0x0E,  0x92,  0x11, 	/* 0C450 */
+	0x22,  0x0E,  0xAE,  0x20,  0x81,  0x10,  0xFF,  0xE4,  0xA4,  0x2A,  0x8F,  0xFE,  0x00,  0x03,  0xF8,  0x20, 	/* 0C460 */
+	0x83,  0xF8,  0x20,  0x83,  0xF8,  0xAF,  0x3F,  0x82,  0x08,  0x3F,  0x82,  0x08,  0xFF,  0xE0,  0x00,  0x3F, 	/* 0C470 */
+	0x82,  0x08,  0x3F,  0x80,  0x50,  0x24,  0x8C,  0xC4,  0xB0,  0x04,  0x2E,  0x5C,  0xA5,  0x0B,  0xF0,  0xA5, 	/* 0C480 */
+	0xEE,  0xD4,  0xAF,  0x4B,  0x54,  0xA5,  0x4A,  0x64,  0xE4,  0x40,  0x44,  0xB4,  0x01,  0x0F,  0xFE,  0x91, 	/* 0C490 */
+	0x09,  0x7C,  0x91,  0x0F,  0xFE,  0x94,  0x49,  0x7C,  0x94,  0x4F,  0x7C,  0x04,  0x40,  0x4C,  0xB6,  0x00, 	/* 0C4A0 */
+	0x03,  0xF8,  0x20,  0x83,  0xF8,  0x20,  0x83,  0xF8,  0x00,  0x0F,  0xBE,  0x8A,  0x2F,  0xBE,  0x8A,  0x2F, 	/* 0C4B0 */
+	0xBE,  0xBA,  0x40,  0x07,  0xBE,  0x92,  0x27,  0xE2,  0x12,  0x22,  0xBE,  0x44,  0x0B,  0xF8,  0x20,  0x83, 	/* 0C4C0 */
+	0xF8,  0x20,  0x83,  0xF8,  0x81,  0x02,  0x01,  0xFC,  0xE2,  0x0A,  0xA8,  0xBF,  0xEE,  0x88,  0xA0,  0x0B, 	/* 0C4D0 */
+	0xFE,  0xE5,  0x08,  0x52,  0x09,  0x23,  0x0E,  0x83,  0x3F,  0x82,  0x08,  0x3F,  0x82,  0x08,  0x3F,  0x80, 	/* 0C4E0 */
+	0xA0,  0xFB,  0xE0,  0xA0,  0x7B,  0xC0,  0xA0,  0xF3,  0xE2,  0x20,  0x84,  0x02,  0x0F,  0xFE,  0xB0,  0x2A, 	/* 0C4F0 */
+	0xFC,  0xA0,  0x0E,  0xFC,  0xA8,  0x4A,  0xFC,  0xA8,  0x4E,  0xFC,  0x00,  0x01,  0xFE,  0x87,  0x0E,  0xEE, 	/* 0C500 */
+	0xA2,  0xAA,  0x2A,  0xEE,  0xA8,  0x0E,  0x9E,  0xAE,  0x2A,  0x8A,  0xA8,  0x4E,  0xE4,  0x08,  0xA0,  0x91, 	/* 0C510 */
+	0x88,  0x3F,  0x82,  0x08,  0x3F,  0x82,  0x08,  0xFF,  0xE8,  0x42,  0x7F,  0xC2,  0x48,  0x3F,  0x82,  0x48, 	/* 0C520 */
+	0xFF,  0xE0,  0x40,  0x89,  0x1F,  0xEF,  0x22,  0xAF,  0xCA,  0x20,  0xAF,  0xCE,  0xA4,  0xAF,  0xCA,  0xA4, 	/* 0C530 */
+	0xAF,  0xCE,  0x20,  0x1F,  0xE0,  0x20,  0x8E,  0x08,  0x8F,  0xFE,  0xA8,  0x8A,  0x20,  0xAF,  0xCE,  0xA4, 	/* 0C540 */
+	0xAA,  0x4B,  0xFE,  0xA2,  0x0E,  0x30,  0x04,  0x81,  0x84,  0x91,  0x00,  0x03,  0xF8,  0x20,  0x83,  0xF8, 	/* 0C550 */
+	0x24,  0x87,  0xFC,  0x05,  0x0F,  0xFE,  0x30,  0x8D,  0xF8,  0x10,  0x81,  0xF8,  0x96,  0x00,  0xEE,  0xF2, 	/* 0C560 */
+	0xA5,  0x4A,  0xFE,  0xA2,  0x0F,  0xFE,  0xA2,  0x0A,  0x7C,  0xA6,  0x4E,  0x98,  0x13,  0x42,  0xC2,  0x97, 	/* 0C570 */
+	0x01,  0x0F,  0xFE,  0x94,  0x49,  0x48,  0x9F,  0xEF,  0x00,  0x97,  0xC9,  0x44,  0x97,  0xCF,  0x44,  0x04, 	/* 0C580 */
+	0x40,  0x7C,  0x98,  0x00,  0x0E,  0x7C,  0xA4,  0x4A,  0x7C,  0xE4,  0x4B,  0xFF,  0xA4,  0x0A,  0xFE,  0xF2, 	/* 0C590 */
+	0xA0,  0xD2,  0x02,  0x20,  0xCC,  0x9D,  0x00,  0x0F,  0xFE,  0xB0,  0x2A,  0xFC,  0xA8,  0x4E,  0xFC,  0xA8, 	/* 0C5A0 */
+	0x4A,  0xFC,  0xA2,  0x0F,  0xFE,  0x04,  0x81,  0x84,  0xA2,  0x20,  0x02,  0x3C,  0xFA,  0x4A,  0xBC,  0xFA, 	/* 0C5B0 */
+	0x4A,  0xFE,  0xAA,  0x0F,  0xBE,  0x24,  0xA2,  0x92,  0x22,  0x22,  0x4C,  0xA6,  0x00,  0x07,  0xFE,  0x48, 	/* 0C5C0 */
+	0x87,  0xDE,  0x48,  0x85,  0xDC,  0x6A,  0xA5,  0xFC,  0x50,  0x49,  0xFC,  0x90,  0x41,  0xFC,  0xAB,  0x10, 	/* 0C5D0 */
+	0x4F,  0xF8,  0x52,  0x07,  0xBE,  0x52,  0x4F,  0xE4,  0x14,  0x43,  0xF8,  0x20,  0x83,  0xF8,  0x20,  0x83, 	/* 0C5E0 */
+	0xF8,  0xAE,  0x11,  0x0F,  0xFE,  0x11,  0x03,  0xF8,  0x20,  0x83,  0xF8,  0x20,  0x8F,  0xFE,  0x31,  0x85, 	/* 0C5F0 */
+	0xF4,  0x91,  0x21,  0xF0,  0xB4,  0x3F,  0x82,  0x08,  0x3F,  0x82,  0x08,  0x7F,  0xC1,  0x10,  0xFF,  0xE2, 	/* 0C600 */
+	0x48,  0x55,  0x49,  0xF2,  0x64,  0xC0,  0xC0,  0xB8,  0x01,  0x00,  0xFE,  0xEA,  0xAA,  0x7C,  0xAC,  0x6F, 	/* 0C610 */
+	0x7D,  0xA4,  0x4A,  0x7C,  0xA5,  0x4E,  0x92,  0x11,  0x20,  0x30,  0xB9,  0x4F,  0xC2,  0x84,  0x0F,  0xC8, 	/* 0C620 */
+	0x84,  0x4F,  0xC0,  0x28,  0xE7,  0xE2,  0xC8,  0x27,  0xE2,  0x7E,  0x5C,  0x88,  0x7F,  0xBC,  0xA9,  0x07, 	/* 0C630 */
+	0x1E,  0xFA,  0x4A,  0xD4,  0xF8,  0x8A,  0x94,  0x8E,  0x23,  0xF8,  0x20,  0x83,  0xF8,  0x20,  0x83,  0xF8, 	/* 0C640 */
+	0xBE,  0x04,  0x8F,  0xF8,  0xA0,  0xFA,  0xEA,  0xAB,  0x2E,  0xE2,  0xA0,  0xAB,  0xEC,  0xA4,  0x4F,  0xEC, 	/* 0C650 */
+	0x05,  0x20,  0xE2,  0x81,  0x20,  0x07,  0xFC,  0x4A,  0x87,  0xBE,  0x51,  0x85,  0xAA,  0x64,  0xE3,  0xF8, 	/* 0C660 */
+	0x20,  0x83,  0xF8,  0x20,  0x8F,  0xFE,  0x84,  0x04,  0x81,  0xFE,  0xE4,  0x8A,  0xFE,  0xA5,  0x4F,  0xFE, 	/* 0C670 */
+	0xA5,  0x4A,  0xFE,  0xA1,  0x0F,  0xFF,  0x01,  0x00,  0x10,  0x87,  0x3F,  0x82,  0x08,  0xFF,  0xE0,  0x40, 	/* 0C680 */
+	0xFF,  0xEA,  0x52,  0x94,  0xA3,  0xF8,  0x00,  0x0F,  0xFE,  0x11,  0x87,  0xE4,  0x89,  0x01,  0x0E,  0xFC, 	/* 0C690 */
+	0xA1,  0x0A,  0xFE,  0xA4,  0x4E,  0xEE,  0xA4,  0x4B,  0xFE,  0xA2,  0x8E,  0x2A,  0x04,  0xA1,  0x86,  0x96, 	/* 0C6A0 */
+	0x00,  0xCE,  0xF4,  0xAA,  0x8B,  0xFE,  0xB6,  0xAE,  0xD4,  0xB3,  0xEA,  0x78,  0xAC,  0x8F,  0x30,  0x04, 	/* 0C6B0 */
+	0x81,  0x86,  0x99,  0x0F,  0xEE,  0xAA,  0xAF,  0xEA,  0x10,  0xAF,  0xEE,  0x14,  0xBF,  0xFA,  0x7C,  0xAC, 	/* 0C6C0 */
+	0x4F,  0x7C,  0x04,  0x40,  0x7C,  0x9A,  0x08,  0x8F,  0xFE,  0xAA,  0x8B,  0xFE,  0xB0,  0x2E,  0xFC,  0xBD, 	/* 0C6D0 */
+	0x2A,  0x3A,  0xAC,  0xCE,  0x3A,  0x0C,  0x90,  0x30,  0x9C,  0x00,  0x0F,  0xFE,  0xA2,  0x2A,  0xEE,  0xA2, 	/* 0C6E0 */
+	0x2F,  0xFE,  0xA9,  0x0A,  0xFE,  0xB9,  0x0E,  0xFC,  0x09,  0x00,  0xFE,  0x9D,  0x07,  0xCF,  0x44,  0x97, 	/* 0C6F0 */
+	0xC9,  0x28,  0x97,  0xCF,  0x28,  0x9F,  0xE9,  0x54,  0x9D,  0x6F,  0x39,  0x0D,  0x60,  0x10,  0xA0,  0x01, 	/* 0C700 */
+	0x0E,  0xFE,  0xAA,  0x8A,  0xFC,  0xAA,  0x8E,  0xFE,  0xAD,  0x4A,  0xFC,  0xAD,  0x4F,  0x7C,  0x12,  0x42, 	/* 0C710 */
+	0xC2,  0xA6,  0x04,  0x4E,  0xFE,  0xA1,  0x0B,  0xFE,  0xA4,  0x8F,  0x8A,  0xBF,  0xEA,  0xC8,  0xBA,  0xAE, 	/* 0C720 */
+	0xD4,  0x04,  0xC1,  0x92,  0xA9,  0x3F,  0x82,  0x08,  0xFF,  0xE4,  0xA4,  0x7B,  0xC1,  0x10,  0x7F,  0xE1, 	/* 0C730 */
+	0x10,  0xFF,  0xE3,  0xA4,  0xC9,  0x83,  0xC6,  0xB0,  0x00,  0x07,  0xFC,  0x40,  0x44,  0x04,  0x40,  0x44, 	/* 0C740 */
+	0x04,  0x7E,  0x44,  0x04,  0x40,  0x44,  0x04,  0x40,  0x47,  0xFC,  0xB2,  0x09,  0x00,  0x90,  0x09,  0x07, 	/* 0C750 */
+	0xFE,  0x49,  0x24,  0x92,  0x7F,  0xE4,  0x92,  0x49,  0x24,  0x92,  0x49,  0x27,  0xFE,  0xB3,  0x08,  0x00, 	/* 0C760 */
+	0x80,  0x7F,  0x84,  0x88,  0x7F,  0x84,  0x88,  0x7F,  0xC0,  0x88,  0x07,  0x01,  0xA2,  0xE1,  0xA0,  0x06, 	/* 0C770 */
+	0xB4,  0x00,  0x0F,  0xFE,  0x04,  0x03,  0xF8,  0x24,  0x83,  0xF8,  0x24,  0x83,  0xF8,  0x14,  0x00,  0xC0, 	/* 0C780 */
+	0x33,  0x0C,  0x0E,  0xB5,  0x05,  0x00,  0x48,  0x7F,  0xC4,  0x44,  0x7F,  0x44,  0x44,  0x7F,  0xC0,  0x44, 	/* 0C790 */
+	0x04,  0x80,  0x32,  0x1D,  0xAE,  0x06,  0xB7,  0x00,  0x03,  0xFC,  0x20,  0x43,  0xFC,  0x20,  0x43,  0xFC, 	/* 0C7A0 */
+	0x10,  0x03,  0xFE,  0xD2,  0x21,  0x52,  0x1F,  0xA0,  0x0C,  0xB8,  0x04,  0x07,  0xFC,  0x04,  0x4F,  0xFE, 	/* 0C7B0 */
+	0x04,  0x47,  0xFC,  0x04,  0x0F,  0xFE,  0x20,  0x83,  0xF8,  0x20,  0x83,  0xF8,  0xB9,  0x09,  0x0F,  0xFE, 	/* 0C7C0 */
+	0x09,  0x07,  0xFE,  0x49,  0x27,  0xFE,  0x49,  0x27,  0xFE,  0x20,  0x43,  0xFC,  0x20,  0x43,  0xFC,  0xBC, 	/* 0C7D0 */
+	0x3F,  0x82,  0x08,  0x3F,  0x82,  0x08,  0xFF,  0xE9,  0x12,  0xFF,  0xE7,  0xF8,  0x11,  0x00,  0xE0,  0x1B, 	/* 0C7E0 */
+	0x0E,  0x0E,  0xBD,  0x20,  0x81,  0x10,  0x7F,  0xC4,  0x44,  0x7F,  0xC4,  0x44,  0x7F,  0xC3,  0xF8,  0x20, 	/* 0C7F0 */
+	0x83,  0xF8,  0x20,  0x83,  0xF8,  0xBE,  0x0E,  0x01,  0x10,  0x20,  0x8F,  0xFE,  0x55,  0x44,  0xE4,  0x7F, 	/* 0C800 */
+	0xC3,  0xF8,  0x20,  0x83,  0xF8,  0x20,  0x83,  0xF8,  0xBF,  0x20,  0x8F,  0xBE,  0x20,  0x8F,  0xBE,  0x20, 	/* 0C810 */
+	0x85,  0x14,  0x8A,  0x23,  0xF8,  0x20,  0x83,  0xF8,  0x20,  0x83,  0xF8,  0x80,  0x3F,  0x82,  0x08,  0x3F, 	/* 0C820 */
+	0x82,  0x08,  0xFF,  0xE4,  0x80,  0x7F,  0xC4,  0xA4,  0x79,  0x44,  0x98,  0xFA,  0x40,  0xC2,  0x83,  0x04, 	/* 0C830 */
+	0x00,  0xA0,  0x3F,  0x8C,  0x06,  0x7F,  0xC6,  0x4C,  0x55,  0x47,  0xFC,  0x20,  0x83,  0xF8,  0x20,  0x83, 	/* 0C840 */
+	0xF8,  0x88,  0x00,  0x01,  0xFC,  0x10,  0x41,  0x04,  0x1F,  0xC1,  0x04,  0x10,  0x41,  0xFC,  0x10,  0x42, 	/* 0C850 */
+	0x04,  0x20,  0x44,  0x0C,  0x89,  0x04,  0x07,  0xFE,  0x04,  0x00,  0x80,  0x1F,  0xC1,  0x84,  0x2F,  0xC4, 	/* 0C860 */
+	0x84,  0x8F,  0xC0,  0x84,  0x08,  0x40,  0x8C,  0x8B,  0x00,  0x03,  0xDE,  0x25,  0x22,  0x52,  0x3D,  0xE2, 	/* 0C870 */
+	0x52,  0x25,  0x23,  0xDE,  0x25,  0x22,  0x52,  0x46,  0x28,  0xC6,  0x8D,  0x00,  0x07,  0x7E,  0x54,  0x25, 	/* 0C880 */
+	0x4C,  0x74,  0x05,  0x7C,  0x54,  0x47,  0x54,  0x54,  0x85,  0x58,  0x56,  0x4B,  0x42,  0x8F,  0x01,  0x07, 	/* 0C890 */
+	0x10,  0x55,  0x25,  0x52,  0x75,  0x25,  0x7E,  0x51,  0x07,  0x52,  0x55,  0x25,  0x52,  0x95,  0x2B,  0x7E, 	/* 0C8A0 */
+	0x94,  0x84,  0x04,  0x5E,  0x29,  0x2F,  0xF2,  0x11,  0xE5,  0x52,  0x55,  0x25,  0x5E,  0x7D,  0x21,  0x22, 	/* 0C8B0 */
+	0x22,  0x24,  0x46,  0x95,  0x04,  0x47,  0x24,  0x52,  0x85,  0xFC,  0x71,  0x05,  0x10,  0x5F,  0xE7,  0x10, 	/* 0C8C0 */
+	0x51,  0x05,  0x28,  0x54,  0x4B,  0x82,  0x96,  0x02,  0x07,  0x10,  0x57,  0xC5,  0x44,  0x77,  0xC5,  0x44, 	/* 0C8D0 */
+	0x57,  0xC7,  0x52,  0x54,  0xC5,  0x48,  0x57,  0x4B,  0xC2,  0x97,  0x10,  0x07,  0xDE,  0x45,  0x27,  0xDE, 	/* 0C8E0 */
+	0x45,  0x27,  0xD2,  0x51,  0xE4,  0x92,  0x4D,  0x27,  0x22,  0xC2,  0x20,  0x46,  0x9B,  0x23,  0xCF,  0xE4, 	/* 0C8F0 */
+	0x43,  0xC4,  0x24,  0x43,  0xC3,  0xC4,  0x09,  0x87,  0xFC,  0x04,  0x03,  0xF8,  0x04,  0x0F,  0xFE,  0x9D, 	/* 0C900 */
+	0x20,  0x0F,  0xBE,  0x22,  0x2F,  0xA2,  0x8B,  0xEF,  0xA2,  0x8A,  0x2F,  0xBE,  0x22,  0x2F,  0xA2,  0x24, 	/* 0C910 */
+	0x22,  0x86,  0x9E,  0x10,  0x83,  0xFC,  0x10,  0x81,  0xF8,  0x10,  0x8F,  0xFE,  0x10,  0x83,  0xFC,  0xD0, 	/* 0C920 */
+	0xA1,  0xF9,  0x10,  0x82,  0x18,  0x9F,  0x24,  0x02,  0x5E,  0xFF,  0x22,  0x52,  0x3D,  0xE2,  0x52,  0x3D, 	/* 0C930 */
+	0x22,  0x5E,  0xFF,  0x22,  0xA2,  0x46,  0x28,  0x46,  0xA6,  0x04,  0x47,  0xFE,  0x55,  0x45,  0xFE,  0x78, 	/* 0C940 */
+	0x25,  0x7C,  0x5D,  0x27,  0x3C,  0x5C,  0xC5,  0x3A,  0x5C,  0x9B,  0x30,  0xA7,  0x04,  0x8F,  0xFE,  0xAA, 	/* 0C950 */
+	0x8B,  0xFE,  0xE0,  0x2A,  0xEE,  0xAA,  0x8E,  0xEE,  0xAA,  0x8A,  0xEE,  0xAA,  0x8A,  0xA6,  0xA8,  0x04, 	/* 0C960 */
+	0x00,  0x40,  0x04,  0x0F,  0xFE,  0x0E,  0x00,  0xE0,  0x15,  0x02,  0x48,  0x44,  0x48,  0x42,  0x04,  0x00, 	/* 0C970 */
+	0x40,  0xAA,  0x04,  0x00,  0x40,  0x3F,  0x80,  0x40,  0x04,  0x0F,  0xFE,  0x04,  0x00,  0xE0,  0x35,  0x8C, 	/* 0C980 */
+	0x46,  0x04,  0x00,  0x40,  0xAB,  0x04,  0x00,  0x40,  0xFF,  0xE0,  0x40,  0x04,  0x03,  0xF8,  0x04,  0x00, 	/* 0C990 */
+	0xE0,  0x35,  0x8C,  0x46,  0x04,  0x00,  0x40,  0xAC,  0x04,  0x00,  0x40,  0x04,  0x0F,  0xFE,  0x0E,  0x00, 	/* 0C9A0 */
+	0xE0,  0x15,  0x02,  0x48,  0x5F,  0x48,  0x42,  0x04,  0x00,  0x40,  0xAD,  0x12,  0x01,  0x20,  0xFE,  0x01, 	/* 0C9B0 */
+	0x20,  0x12,  0x03,  0xA0,  0x36,  0x05,  0x20,  0x92,  0x01,  0x22,  0x12,  0x21,  0x1E,  0xAE,  0x04,  0x00, 	/* 0C9C0 */
+	0x48,  0x04,  0x4F,  0xFE,  0x04,  0x02,  0x50,  0x25,  0x02,  0x50,  0x25,  0x24,  0x52,  0x84,  0xE0,  0x40, 	/* 0C9D0 */
+	0xB1,  0x04,  0x02,  0x40,  0x24,  0x03,  0xFC,  0x24,  0x04,  0x40,  0xFF,  0xE0,  0xE0,  0x35,  0x8C,  0x46, 	/* 0C9E0 */
+	0x04,  0x00,  0x40,  0xB4,  0x11,  0x01,  0x10,  0x11,  0x07,  0xD0,  0x11,  0x83,  0x14,  0x39,  0x25,  0x52, 	/* 0C9F0 */
+	0x91,  0x01,  0x10,  0x11,  0x01,  0x10,  0xB6,  0x00,  0x07,  0xF0,  0x09,  0x00,  0x9E,  0x10,  0x22,  0x42, 	/* 0CA00 */
+	0x44,  0xCF,  0xFE,  0x0E,  0x03,  0x58,  0xC4,  0x60,  0x40,  0xB7,  0x20,  0x02,  0x7E,  0x21,  0x2F,  0x92, 	/* 0CA10 */
+	0x21,  0x23,  0x12,  0x69,  0x26,  0x22,  0xA2,  0x2A,  0x42,  0x28,  0x23,  0x0C,  0xB8,  0x21,  0x02,  0x10, 	/* 0CA20 */
+	0x21,  0x0F,  0xFE,  0x21,  0x23,  0x12,  0x69,  0x26,  0x12,  0xA2,  0x2A,  0x22,  0x24,  0x22,  0x8C,  0xBA, 	/* 0CA30 */
+	0x20,  0x02,  0x3C,  0x22,  0x4F,  0xA4,  0x22,  0x46,  0x24,  0x72,  0x46,  0xA4,  0xA2,  0x4A,  0x45,  0x24, 	/* 0CA40 */
+	0x52,  0x83,  0xBD,  0x20,  0x02,  0xFE,  0x22,  0x0F,  0xA0,  0x22,  0x06,  0x7C,  0x74,  0x46,  0x84,  0xA0, 	/* 0CA50 */
+	0x4A,  0x04,  0x20,  0x42,  0x18,  0xBF,  0x04,  0x00,  0x40,  0xFF,  0xE0,  0x40,  0x7F,  0xC4,  0x44,  0x44, 	/* 0CA60 */
+	0x44,  0xEC,  0x15,  0x02,  0x48,  0xC4,  0x60,  0x40,  0x81,  0x23,  0x02,  0x10,  0xF9,  0x02,  0x10,  0x21, 	/* 0CA70 */
+	0x07,  0x10,  0x6A,  0x8A,  0x28,  0xA4,  0x42,  0x44,  0x28,  0x23,  0x01,  0x86,  0x20,  0x02,  0x7C,  0xF9, 	/* 0CA80 */
+	0x02,  0x10,  0x31,  0x06,  0xFE,  0x61,  0x0A,  0x10,  0xA1,  0x02,  0x10,  0x21,  0x02,  0x10,  0x89,  0x20, 	/* 0CA90 */
+	0x82,  0x08,  0x21,  0x0F,  0xA4,  0x24,  0x43,  0x08,  0x69,  0x26,  0x62,  0xA0,  0x4A,  0x08,  0x21,  0x02, 	/* 0CAA0 */
+	0x60,  0x8E,  0x04,  0x0F,  0xFE,  0x0E,  0x01,  0x50,  0x24,  0x8C,  0x46,  0x3F,  0x00,  0x20,  0xFF,  0xE0, 	/* 0CAB0 */
+	0x40,  0x04,  0x00,  0xC0,  0x8F,  0x04,  0x00,  0x40,  0xFF,  0xE0,  0xE0,  0x15,  0x02,  0x48,  0xC4,  0x63, 	/* 0CAC0 */
+	0xF8,  0x20,  0x82,  0x08,  0x20,  0x83,  0xF8,  0x90,  0x20,  0x82,  0x08,  0x20,  0x8F,  0xFE,  0x20,  0x86, 	/* 0CAD0 */
+	0x18,  0x71,  0x86,  0xA8,  0xA4,  0x8A,  0x88,  0x20,  0x82,  0x18,  0x91,  0x10,  0x41,  0x04,  0x7F,  0xF1, 	/* 0CAE0 */
+	0x04,  0x30,  0x43,  0xA4,  0x55,  0x45,  0x14,  0x90,  0x41,  0x04,  0x10,  0x41,  0x0C,  0x93,  0x22,  0x02, 	/* 0CAF0 */
+	0x20,  0x23,  0xEF,  0x22,  0x24,  0x26,  0xA2,  0x71,  0x2A,  0x92,  0xA0,  0x22,  0x02,  0x20,  0x22,  0x0C, 	/* 0CB00 */
+	0x96,  0x20,  0x82,  0x08,  0x20,  0x8F,  0xFE,  0x24,  0x87,  0x48,  0x6A,  0x8A,  0x30,  0xA1,  0x02,  0x28, 	/* 0CB10 */
+	0x24,  0x43,  0x82,  0x99,  0x22,  0x02,  0x28,  0xFA,  0x42,  0x3E,  0x2E,  0x07,  0x20,  0x6A,  0x0A,  0x10, 	/* 0CB20 */
+	0xA1,  0x02,  0x0A,  0x20,  0x62,  0x02,  0x9C,  0x21,  0x02,  0x10,  0x21,  0x0F,  0x90,  0x27,  0xC2,  0x10, 	/* 0CB30 */
+	0x71,  0x06,  0x90,  0xA1,  0x0A,  0x10,  0x21,  0x02,  0xFE,  0x9E,  0x20,  0x02,  0x7C,  0x20,  0x4F,  0x84, 	/* 0CB40 */
+	0x20,  0x43,  0x7C,  0x6C,  0x06,  0x40,  0xA4,  0x0A,  0x42,  0x24,  0x22,  0x3E,  0x9F,  0x04,  0x07,  0xFE, 	/* 0CB50 */
+	0x04,  0x03,  0xFC,  0x24,  0x42,  0x44,  0x3F,  0xC0,  0xE0,  0x15,  0x02,  0x48,  0xC4,  0x60,  0x40,  0xA0, 	/* 0CB60 */
+	0x20,  0x02,  0x7C,  0xF9,  0x02,  0x10,  0x21,  0x07,  0x10,  0x69,  0x0A,  0x10,  0xA1,  0x02,  0x10,  0x21, 	/* 0CB70 */
+	0x02,  0xFE,  0xA1,  0x08,  0x01,  0xF8,  0x31,  0x0C,  0xA0,  0x1F,  0x0E,  0x4E,  0x04,  0x0F,  0xFE,  0x0E, 	/* 0CB80 */
+	0x03,  0x58,  0xC4,  0x60,  0x40,  0xA2,  0x04,  0x00,  0x40,  0xFF,  0xE0,  0xE0,  0x35,  0x8C,  0x46,  0x04, 	/* 0CB90 */
+	0x07,  0xFC,  0x04,  0x00,  0x40,  0x04,  0x0F,  0xFE,  0xA3,  0x21,  0x02,  0x10,  0xF9,  0x02,  0x10,  0x29, 	/* 0CBA0 */
+	0x27,  0x92,  0x69,  0x2A,  0x92,  0xA9,  0x22,  0x92,  0x29,  0x22,  0xFE,  0xA4,  0x20,  0x02,  0xFE,  0xFA, 	/* 0CBB0 */
+	0x02,  0x20,  0x23,  0xC7,  0x24,  0x6A,  0x4A,  0x24,  0xA4,  0x42,  0x44,  0x28,  0x43,  0x18,  0xA5,  0x04, 	/* 0CBC0 */
+	0x00,  0x40,  0x7F,  0xC2,  0x48,  0x14,  0x81,  0x50,  0xFF,  0xE0,  0xE0,  0x15,  0x02,  0x48,  0xC4,  0x60, 	/* 0CBD0 */
+	0x40,  0xAA,  0x21,  0x02,  0x10,  0xF5,  0x42,  0x54,  0x35,  0x26,  0x92,  0x71,  0x4A,  0x34,  0xA0,  0x82, 	/* 0CBE0 */
+	0x10,  0x26,  0x03,  0x80,  0xAD,  0x22,  0x02,  0x20,  0x2F,  0xEF,  0x00,  0x27,  0x86,  0x48,  0x74,  0x86, 	/* 0CBF0 */
+	0xC8,  0xA4,  0x8A,  0x4A,  0x28,  0xA3,  0x06,  0xAF,  0x20,  0x02,  0xFE,  0x20,  0x8F,  0x88,  0x21,  0x07, 	/* 0CC00 */
+	0x18,  0x6B,  0x46,  0x52,  0xA9,  0x2A,  0x10,  0x21,  0x02,  0x10,  0xB0,  0x04,  0x00,  0x40,  0xFF,  0xE0, 	/* 0CC10 */
+	0x40,  0x0E,  0x03,  0x58,  0xC4,  0x60,  0x40,  0x04,  0x05,  0x24,  0x49,  0x28,  0x92,  0xB1,  0x04,  0x0F, 	/* 0CC20 */
+	0xFE,  0x04,  0x07,  0xFC,  0x44,  0x47,  0xFC,  0x44,  0x47,  0xFC,  0x0E,  0x03,  0x58,  0xC4,  0x60,  0x40, 	/* 0CC30 */
+	0xB2,  0x00,  0x03,  0xF8,  0x20,  0x83,  0xF8,  0x20,  0x83,  0xF8,  0x04,  0x0F,  0xFE,  0x0E,  0x03,  0x58, 	/* 0CC40 */
+	0xC4,  0x60,  0x40,  0xB3,  0x04,  0x0F,  0xFE,  0x04,  0x00,  0xE0,  0x35,  0x8C,  0x46,  0x3F,  0x82,  0x08, 	/* 0CC50 */
+	0x3F,  0x82,  0x08,  0x20,  0x83,  0xF8,  0xB5,  0x24,  0x02,  0x40,  0x27,  0xCF,  0x50,  0x29,  0x06,  0x10, 	/* 0CC60 */
+	0x77,  0xE6,  0x90,  0xA1,  0x0A,  0x10,  0x21,  0x02,  0x10,  0xB7,  0x20,  0x02,  0xFC,  0x2A,  0x4F,  0xA4, 	/* 0CC70 */
+	0x2A,  0x46,  0xFC,  0x78,  0x06,  0x80,  0xA8,  0x0A,  0x82,  0x28,  0x22,  0x7E,  0xBC,  0x27,  0xC2,  0x04, 	/* 0CC80 */
+	0xFA,  0x82,  0x10,  0x2F,  0xE7,  0x12,  0x69,  0x4A,  0x10,  0xA1,  0x02,  0x10,  0x21,  0x02,  0x30,  0xBE, 	/* 0CC90 */
+	0x23,  0x82,  0x28,  0xF2,  0x82,  0x44,  0x25,  0x46,  0x92,  0x71,  0x0A,  0xA0,  0xA2,  0x82,  0x4C,  0x2F, 	/* 0CCA0 */
+	0x22,  0x02,  0xBF,  0x20,  0x02,  0x7E,  0x24,  0x0F,  0xC0,  0x27,  0xC6,  0x44,  0x75,  0x46,  0xD8,  0xA4, 	/* 0CCB0 */
+	0x8A,  0x94,  0x2A,  0x43,  0x42,  0x85,  0x20,  0x02,  0x7E,  0xFA,  0x42,  0x24,  0x32,  0x46,  0xFE,  0x62, 	/* 0CCC0 */
+	0x4A,  0x24,  0xA2,  0x42,  0x44,  0x24,  0x42,  0x84,  0x87,  0x29,  0x02,  0x90,  0x29,  0x0F,  0x92,  0x2F, 	/* 0CCD0 */
+	0xC2,  0x90,  0x79,  0x06,  0x90,  0xA9,  0x0A,  0x92,  0x2F,  0x23,  0x8E,  0x89,  0x20,  0x02,  0xFE,  0xF9, 	/* 0CCE0 */
+	0x02,  0x10,  0x21,  0x07,  0x7C,  0x69,  0x0A,  0x10,  0xA1,  0x02,  0x10,  0x21,  0x02,  0xFE,  0x8B,  0x22, 	/* 0CCF0 */
+	0x02,  0x20,  0xFF,  0xE2,  0x20,  0x22,  0x07,  0x3C,  0x6A,  0x4A,  0x24,  0xA2,  0x42,  0x44,  0x24,  0x42, 	/* 0CD00 */
+	0x98,  0x8C,  0x24,  0x82,  0x48,  0xFC,  0x42,  0x44,  0x28,  0x27,  0x7C,  0x6A,  0x4A,  0x24,  0xA2,  0x42, 	/* 0CD10 */
+	0x24,  0x24,  0x42,  0x98,  0x90,  0x20,  0x42,  0x78,  0x24,  0x0F,  0xC0,  0x27,  0xE3,  0x48,  0x6C,  0x86, 	/* 0CD20 */
+	0x48,  0xA4,  0x8A,  0x88,  0x28,  0x83,  0x08,  0x95,  0x22,  0x02,  0x20,  0x22,  0x0F,  0xFE,  0x2A,  0x26, 	/* 0CD30 */
+	0xB2,  0x73,  0x06,  0xB0,  0xA5,  0x0A,  0x52,  0x29,  0x23,  0x0E,  0x97,  0x21,  0x02,  0x10,  0xFF,  0xE2, 	/* 0CD40 */
+	0x10,  0x33,  0x87,  0x38,  0x6D,  0x4A,  0x52,  0xA9,  0x02,  0x10,  0x21,  0x02,  0x10,  0x9A,  0x22,  0x02, 	/* 0CD50 */
+	0x20,  0x23,  0xEF,  0xA4,  0x24,  0x47,  0x44,  0x6A,  0x86,  0xA8,  0xA1,  0x0A,  0x18,  0x22,  0x42,  0xC2, 	/* 0CD60 */
+	0x9C,  0x00,  0x03,  0xFC,  0x24,  0x43,  0xFC,  0x24,  0x43,  0xFC,  0x04,  0x07,  0xFE,  0x0E,  0x03,  0x58, 	/* 0CD70 */
+	0xC4,  0x60,  0x40,  0x9D,  0x21,  0x02,  0x10,  0x27,  0xEF,  0x90,  0x21,  0x06,  0xFC,  0x70,  0x46,  0x68, 	/* 0CD80 */
+	0xA1,  0x0A,  0x28,  0x24,  0x43,  0x82,  0xA0,  0x22,  0x02,  0x20,  0x2F,  0x8F,  0xA8,  0x22,  0xA7,  0x46, 	/* 0CD90 */
+	0x69,  0x06,  0xFE,  0xA1,  0x0A,  0x10,  0x21,  0x02,  0x10,  0xA1,  0x23,  0x42,  0xE4,  0xF2,  0x42,  0x24, 	/* 0CDA0 */
+	0x32,  0x46,  0xFE,  0x62,  0x4A,  0x24,  0xA2,  0x42,  0x44,  0x24,  0x42,  0x84,  0xA2,  0x20,  0x02,  0x7E, 	/* 0CDB0 */
+	0x24,  0x4F,  0xC4,  0x26,  0x43,  0x58,  0x6C,  0x86,  0x54,  0xA5,  0x4A,  0x60,  0x24,  0x02,  0x7E,  0xA6, 	/* 0CDC0 */
+	0x27,  0xE2,  0x00,  0xFF,  0xE2,  0x42,  0x24,  0x27,  0x7E,  0x6C,  0x0A,  0x40,  0xA4,  0x02,  0x80,  0x28, 	/* 0CDD0 */
+	0x03,  0x00,  0xA9,  0x04,  0x0F,  0xFE,  0x04,  0x00,  0xE0,  0x35,  0x8C,  0x46,  0x11,  0x02,  0x4C,  0xC4, 	/* 0CDE0 */
+	0x20,  0x90,  0x13,  0x87,  0xC4,  0xAF,  0x21,  0x02,  0x10,  0x21,  0x0F,  0xFE,  0x21,  0x06,  0x10,  0x71, 	/* 0CDF0 */
+	0x06,  0xFC,  0xA4,  0x4A,  0x44,  0x24,  0x42,  0x7C,  0xB3,  0x20,  0x02,  0x7C,  0xFC,  0x42,  0x44,  0x34, 	/* 0CE00 */
+	0x46,  0xC4,  0x67,  0xCA,  0x00,  0xA2,  0x82,  0x24,  0x24,  0x22,  0x82,  0xB4,  0x20,  0x02,  0x7C,  0xFC, 	/* 0CE10 */
+	0x42,  0x44,  0x27,  0xC7,  0x00,  0x6F,  0xEA,  0x12,  0xA1,  0x22,  0x22,  0x24,  0x22,  0x8C,  0xB6,  0x20, 	/* 0CE20 */
+	0x0F,  0xBC,  0x2A,  0x42,  0xA4,  0x4A,  0x4B,  0x3C,  0x04,  0x0F,  0xFE,  0x0E,  0x03,  0x58,  0xC4,  0x60, 	/* 0CE30 */
+	0x40,  0xB7,  0x28,  0x02,  0x80,  0xF8,  0xE3,  0xEA,  0x2A,  0xA7,  0xAA,  0x7A,  0xAA,  0xAA,  0xAA,  0xA2, 	/* 0CE40 */
+	0xAA,  0x32,  0xE2,  0xC0,  0xB8,  0x22,  0x02,  0x20,  0xFB,  0xE2,  0x42,  0x28,  0x27,  0x3A,  0x6A,  0xAA, 	/* 0CE50 */
+	0x2A,  0xA3,  0xA2,  0x02,  0x20,  0x22,  0x0C,  0xB9,  0x22,  0x02,  0x20,  0xFB,  0xE2,  0x42,  0x2B,  0xA7, 	/* 0CE60 */
+	0x2A,  0x6A,  0xAA,  0x3A,  0xA2,  0xC2,  0x20,  0x22,  0x12,  0x1F,  0x81,  0x20,  0x82,  0x7E,  0x24,  0x2F, 	/* 0CE70 */
+	0x42,  0x22,  0x06,  0x26,  0x73,  0x86,  0xA0,  0xA2,  0x0A,  0x22,  0x22,  0x22,  0x1E,  0x84,  0x20,  0x02, 	/* 0CE80 */
+	0x7E,  0x21,  0x0F,  0x90,  0x27,  0xE2,  0x52,  0x75,  0xA6,  0xE6,  0xA6,  0x6A,  0x42,  0x24,  0x22,  0x46, 	/* 0CE90 */
+	0x86,  0x21,  0x02,  0x10,  0xF9,  0x02,  0xFE,  0x30,  0x46,  0xC4,  0x64,  0x4A,  0x24,  0xA2,  0x82,  0x28, 	/* 0CEA0 */
+	0x21,  0x02,  0xFE,  0x8A,  0x22,  0x02,  0x3C,  0x24,  0x4F,  0xC8,  0x23,  0x07,  0x28,  0x74,  0x66,  0xB0, 	/* 0CEB0 */
+	0xA0,  0xCA,  0x60,  0x21,  0x82,  0x06,  0x8E,  0x22,  0x42,  0x24,  0xFC,  0x42,  0x7E,  0x2C,  0x47,  0x44, 	/* 0CEC0 */
+	0x6E,  0x4A,  0x54,  0xA4,  0x42,  0x44,  0x24,  0x42,  0x4C,  0x8F,  0x21,  0x02,  0x10,  0x22,  0x0F,  0x7E, 	/* 0CED0 */
+	0x24,  0x26,  0x42,  0x77,  0xE6,  0xC2,  0xA4,  0x2A,  0x42,  0x24,  0x22,  0x7E,  0x90,  0x11,  0x0F,  0xFE, 	/* 0CEE0 */
+	0x11,  0x01,  0xF0,  0x11,  0x01,  0xF0,  0x04,  0x0F,  0xFE,  0x0E,  0x03,  0x58,  0xC4,  0x60,  0x40,  0x91, 	/* 0CEF0 */
+	0x24,  0x42,  0x44,  0x2F,  0xEF,  0xC4,  0x24,  0x46,  0x44,  0x77,  0xC6,  0xC4,  0xA4,  0x4A,  0x44,  0x24, 	/* 0CF00 */
+	0x42,  0x7C,  0x93,  0x22,  0x01,  0x20,  0xCF,  0x80,  0x2A,  0x32,  0xAC,  0x46,  0x04,  0x0F,  0xFE,  0x0E, 	/* 0CF10 */
+	0x03,  0x58,  0xC4,  0x60,  0x40,  0x94,  0x3F,  0x80,  0x90,  0x06,  0x0F,  0xFE,  0x0C,  0x43,  0x48,  0xCC, 	/* 0CF20 */
+	0x0F,  0xFE,  0x0E,  0x03,  0x58,  0xC4,  0x60,  0x40,  0x98,  0x20,  0x02,  0xFE,  0x21,  0x0F,  0x90,  0x21, 	/* 0CF30 */
+	0x07,  0x20,  0x6B,  0xE6,  0x62,  0xAA,  0x2B,  0x22,  0x22,  0x22,  0x3E,  0x9A,  0x21,  0x02,  0x10,  0x21, 	/* 0CF40 */
+	0x0F,  0x10,  0x2F,  0xE6,  0x92,  0x79,  0x26,  0xFE,  0xA9,  0x2A,  0x92,  0x29,  0x22,  0xFE,  0x9D,  0x20, 	/* 0CF50 */
+	0xC2,  0x70,  0xFC,  0x02,  0x40,  0x27,  0xE7,  0x48,  0x6D,  0x8A,  0x4C,  0xA8,  0xA2,  0x88,  0x30,  0x82, 	/* 0CF60 */
+	0x08,  0x9E,  0x24,  0x02,  0x40,  0xFF,  0xE2,  0x50,  0x29,  0x07,  0x1C,  0x69,  0x0A,  0x10,  0xA1,  0xC2, 	/* 0CF70 */
+	0x10,  0x21,  0x02,  0x10,  0xA2,  0x20,  0xC2,  0x70,  0xF4,  0x82,  0x48,  0x27,  0xE7,  0x48,  0x6C,  0x8A, 	/* 0CF80 */
+	0x4A,  0xA4,  0x62,  0x76,  0x38,  0x22,  0xF8,  0xA4,  0x20,  0x02,  0x3C,  0xFA,  0x42,  0x24,  0x33,  0xC6, 	/* 0CF90 */
+	0xA4,  0x62,  0x4A,  0x3C,  0xA2,  0x42,  0x24,  0x22,  0x42,  0xFE,  0xA7,  0x20,  0x62,  0x78,  0xFD,  0x42, 	/* 0CFA0 */
+	0x54,  0x25,  0x47,  0x54,  0x6D,  0x4A,  0x54,  0xA5,  0xC2,  0x56,  0x27,  0xE2,  0x81,  0xA9,  0x20,  0x02, 	/* 0CFB0 */
+	0x7E,  0xFD,  0x02,  0x5C,  0x35,  0x46,  0xE4,  0x64,  0x8A,  0x4C,  0xA5,  0x22,  0x62,  0x24,  0x02,  0x7E, 	/* 0CFC0 */
+	0xAC,  0x04,  0x0F,  0xFE,  0x04,  0x07,  0xFC,  0x64,  0xC5,  0x54,  0x7F,  0xC0,  0xE0,  0x15,  0x02,  0x48, 	/* 0CFD0 */
+	0xC4,  0x60,  0x40,  0xAE,  0x20,  0x82,  0x08,  0xFC,  0xA2,  0x4A,  0x24,  0xA7,  0x7E,  0x68,  0x8A,  0x4A, 	/* 0CFE0 */
+	0xA4,  0xA2,  0x4A,  0x24,  0xA2,  0x7E,  0xAF,  0x20,  0x02,  0xFE,  0xF0,  0x42,  0x04,  0x37,  0x46,  0xD4, 	/* 0CFF0 */
+	0x65,  0x4A,  0x54,  0xA7,  0x42,  0x04,  0x20,  0x42,  0x0C,  0xB1,  0x22,  0x02,  0x10,  0x2F,  0xEF,  0x10, 	/* 0D000 */
+	0x21,  0x03,  0x10,  0x6F,  0xC6,  0x10,  0xA1,  0x0A,  0x10,  0x21,  0x02,  0xFE,  0xB3,  0x22,  0x02,  0xCE, 	/* 0D010 */
+	0x2A,  0xAF,  0xAA,  0x2A,  0xA6,  0xAA,  0x7A,  0xA6,  0xAA,  0xAE,  0xAA,  0xAE,  0x22,  0x82,  0x48,  0xB4, 	/* 0D020 */
+	0x12,  0x05,  0x26,  0x5B,  0x85,  0x20,  0x5E,  0x2F,  0x1E,  0x04,  0x0F,  0xFE,  0x0E,  0x03,  0x58,  0xC4, 	/* 0D030 */
+	0x60,  0x40,  0xB5,  0x20,  0x02,  0x7C,  0x25,  0x4F,  0xD4,  0x25,  0x46,  0xFE,  0x75,  0x46,  0xD4,  0xA5, 	/* 0D040 */
+	0x4A,  0x54,  0x25,  0x42,  0x4C,  0xBB,  0x04,  0x0F,  0xFE,  0x0E,  0x01,  0x50,  0x24,  0x8D,  0xF6,  0x11, 	/* 0D050 */
+	0x01,  0xF0,  0x11,  0x01,  0xF0,  0x11,  0x0F,  0xFE,  0xBE,  0x20,  0x02,  0xFE,  0x21,  0x0F,  0x90,  0x25, 	/* 0D060 */
+	0x06,  0x5C,  0x75,  0x06,  0xD0,  0xA5,  0x0A,  0x50,  0x25,  0x02,  0xFE,  0xBF,  0x21,  0x02,  0x10,  0x2F, 	/* 0D070 */
+	0xEF,  0x10,  0x27,  0xE6,  0x52,  0x75,  0x26,  0xD2,  0xA5,  0x2A,  0x56,  0x21,  0x02,  0x10,  0x82,  0x27, 	/* 0D080 */
+	0xC2,  0x44,  0x25,  0x4F,  0x4C,  0x2F,  0xE3,  0x44,  0x6D,  0x46,  0x4C,  0xA4,  0x4A,  0x7E,  0x20,  0x42, 	/* 0D090 */
+	0x18,  0x83,  0x20,  0x42,  0x78,  0x24,  0x0F,  0x7E,  0x25,  0x03,  0x50,  0x6D,  0xE6,  0x52,  0xA9,  0x2A, 	/* 0D0A0 */
+	0xA2,  0x32,  0x22,  0x4C,  0x84,  0x48,  0x42,  0x48,  0x25,  0x0F,  0xFE,  0x84,  0x28,  0x42,  0x7F,  0xC0, 	/* 0D0B0 */
+	0xE0,  0x15,  0x02,  0x48,  0xC4,  0x60,  0x40,  0x93,  0x21,  0x02,  0x10,  0x22,  0x8F,  0x44,  0x3F,  0xE2, 	/* 0D0C0 */
+	0x10,  0x71,  0x06,  0xFC,  0xA1,  0x0A,  0x10,  0x21,  0x02,  0xFE,  0x96,  0x20,  0x02,  0xFE,  0x22,  0x8F, 	/* 0D0D0 */
+	0xA8,  0x2F,  0xE2,  0xAA,  0x7A,  0xA6,  0xCE,  0xA8,  0x2A,  0x82,  0x2F,  0xE2,  0x80,  0x97,  0x00,  0x0F, 	/* 0D0E0 */
+	0xFE,  0x0A,  0x07,  0xFC,  0x4A,  0x47,  0xFC,  0x04,  0x0F,  0xFE,  0x0E,  0x03,  0x58,  0xC4,  0x60,  0x40, 	/* 0D0F0 */
+	0x9E,  0x00,  0x07,  0xBC,  0x20,  0x8F,  0xFE,  0x20,  0x82,  0x48,  0x04,  0x0F,  0xFE,  0x0E,  0x03,  0x58, 	/* 0D100 */
+	0xC4,  0x60,  0x40,  0xA1,  0x21,  0x02,  0x10,  0x2F,  0xEF,  0x28,  0x24,  0x46,  0xCA,  0x72,  0x86,  0x28, 	/* 0D110 */
+	0xA1,  0x0A,  0x28,  0x24,  0x43,  0x82,  0xA2,  0x20,  0x02,  0xFE,  0x21,  0x0F,  0x20,  0x27,  0xC6,  0x44, 	/* 0D120 */
+	0x74,  0x46,  0x7C,  0xA4,  0x4A,  0x44,  0x24,  0x42,  0x7C,  0xA9,  0x20,  0x02,  0xFE,  0xF2,  0x22,  0x66, 	/* 0D130 */
+	0x2A,  0xA7,  0x22,  0x6A,  0x2A,  0x66,  0xAA,  0xA2,  0x22,  0x22,  0x22,  0x66,  0xAA,  0x21,  0x02,  0x50, 	/* 0D140 */
+	0x27,  0xCF,  0xD0,  0x29,  0x06,  0xFE,  0x71,  0x06,  0xB8,  0xA3,  0x8A,  0x54,  0x29,  0x22,  0x10,  0xAB, 	/* 0D150 */
+	0x21,  0x02,  0x10,  0xFF,  0xE2,  0x20,  0x23,  0xE7,  0x44,  0x6C,  0x8B,  0x7E,  0xA4,  0x82,  0x48,  0x24, 	/* 0D160 */
+	0x82,  0x58,  0xB2,  0x21,  0x02,  0x12,  0x27,  0xCF,  0x14,  0x2F,  0xE6,  0x20,  0x77,  0xE6,  0xA0,  0xA3, 	/* 0D170 */
+	0xCA,  0x44,  0x20,  0x42,  0x18,  0xB4,  0x28,  0x02,  0x80,  0x2F,  0xEF,  0x80,  0x37,  0xC6,  0x54,  0x75, 	/* 0D180 */
+	0x47,  0xFE,  0xA4,  0x4A,  0x44,  0x24,  0x42,  0x4C,  0xB8,  0x21,  0x02,  0x10,  0x2F,  0xEF,  0x20,  0x22, 	/* 0D190 */
+	0x87,  0x68,  0x69,  0x06,  0x24,  0xAC,  0x8A,  0x18,  0x22,  0x42,  0xC2,  0xB9,  0x20,  0x02,  0x7C,  0x24, 	/* 0D1A0 */
+	0x4F,  0x7C,  0x24,  0x46,  0x7C,  0x76,  0x26,  0xD4,  0xA5,  0x8A,  0x48,  0x27,  0x42,  0xC2,  0xBC,  0x22, 	/* 0D1B0 */
+	0x02,  0x3C,  0x22,  0x4F,  0x64,  0x29,  0x86,  0x14,  0x72,  0x26,  0xFD,  0xA2,  0x4A,  0x24,  0x22,  0x42, 	/* 0D1C0 */
+	0x3C,  0xBD,  0x12,  0x01,  0x28,  0x7E,  0x41,  0x20,  0xFF,  0xE1,  0x20,  0xFE,  0x41,  0x14,  0x38,  0x85, 	/* 0D1D0 */
+	0x4A,  0x91,  0x61,  0x22,  0x80,  0x20,  0x83,  0x88,  0x4B,  0xEA,  0xA8,  0x12,  0x82,  0xFE,  0xC0,  0x80, 	/* 0D1E0 */
+	0x48,  0xFF,  0xE0,  0xE0,  0x35,  0x8C,  0x46,  0x81,  0x22,  0x02,  0x5C,  0x28,  0x0F,  0x20,  0x25,  0xE6, 	/* 0D1F0 */
+	0xC8,  0x74,  0x86,  0xC8,  0xA4,  0x8A,  0x48,  0x24,  0x82,  0x58,  0x82,  0x21,  0x02,  0x10,  0x27,  0xCF, 	/* 0D200 */
+	0x90,  0x21,  0x06,  0xFE,  0x71,  0x06,  0x90,  0xA7,  0xCA,  0x10,  0x21,  0x02,  0xFE,  0x83,  0x22,  0x82, 	/* 0D210 */
+	0x28,  0x2A,  0xAF,  0xAA,  0x26,  0xC2,  0x28,  0x76,  0xC6,  0xAA,  0xA2,  0xAA,  0x28,  0x24,  0xA2,  0x86, 	/* 0D220 */
+	0x86,  0x20,  0x02,  0xFE,  0xF8,  0x02,  0xBE,  0x28,  0x87,  0x88,  0x6B,  0xCA,  0x88,  0xA8,  0x82,  0xBE, 	/* 0D230 */
+	0x28,  0x02,  0xFE,  0x88,  0x04,  0x0F,  0xFE,  0x88,  0x2B,  0xFA,  0x11,  0x00,  0xE0,  0x35,  0x8F,  0xFE, 	/* 0D240 */
+	0x0E,  0x03,  0x58,  0xC4,  0x60,  0x40,  0x8D,  0x21,  0x02,  0x10,  0xFF,  0xE2,  0x28,  0x27,  0xC6,  0x82, 	/* 0D250 */
+	0x7F,  0xDA,  0x20,  0xA3,  0xC2,  0x44,  0x20,  0x42,  0x18,  0x8E,  0x20,  0x02,  0x7E,  0xF9,  0x02,  0x24, 	/* 0D260 */
+	0x2F,  0xA7,  0x12,  0x69,  0x0A,  0x7C,  0xA1,  0x02,  0x10,  0x21,  0x02,  0xFE,  0x90,  0x20,  0x02,  0xFE, 	/* 0D270 */
+	0x28,  0x2F,  0xBA,  0x28,  0x26,  0xBA,  0x7A,  0xA6,  0xAA,  0xAB,  0xAA,  0x82,  0x28,  0x22,  0x86,  0x91, 	/* 0D280 */
+	0x3F,  0x81,  0x10,  0x0E,  0x03,  0x18,  0xFF,  0xC4,  0xA4,  0x35,  0x8C,  0xE4,  0xFF,  0xE0,  0xE0,  0x35, 	/* 0D290 */
+	0x8C,  0x46,  0x93,  0x20,  0x02,  0xFE,  0x20,  0x0F,  0x7C,  0x24,  0x46,  0x44,  0x77,  0xC6,  0xC4,  0xA4, 	/* 0D2A0 */
+	0x4A,  0x7C,  0x20,  0x02,  0xFE,  0x94,  0x21,  0x02,  0x10,  0x2F,  0xEF,  0x10,  0x21,  0x06,  0x7C,  0x70, 	/* 0D2B0 */
+	0x06,  0xFC,  0xA4,  0x4A,  0x44,  0x24,  0x42,  0x7C,  0x99,  0x21,  0x02,  0x24,  0xFF,  0xE2,  0x12,  0x25, 	/* 0D2C0 */
+	0x07,  0x7C,  0x69,  0x0A,  0x10,  0xAF,  0xE2,  0x10,  0x21,  0x02,  0x10,  0x9C,  0x22,  0x42,  0x94,  0x25, 	/* 0D2D0 */
+	0x4F,  0xC8,  0x21,  0x07,  0x20,  0x6F,  0xE6,  0x48,  0xA4,  0x8A,  0xF0,  0x22,  0x82,  0xC4,  0x9D,  0x28, 	/* 0D2E0 */
+	0x42,  0x84,  0xFE,  0x42,  0xBE,  0x6E,  0x47,  0xA4,  0xAE,  0x4B,  0x3E,  0x24,  0x42,  0x44,  0x24,  0x42, 	/* 0D2F0 */
+	0x84,  0x9F,  0x22,  0x82,  0x24,  0x2F,  0xCF,  0x20,  0x2F,  0xC6,  0x20,  0x7F,  0xE6,  0x94,  0xA1,  0x8A, 	/* 0D300 */
+	0x2A,  0x2C,  0x63,  0x02,  0xA3,  0x21,  0x02,  0x92,  0xF5,  0x22,  0x54,  0x21,  0x07,  0x7E,  0x68,  0x2A, 	/* 0D310 */
+	0x02,  0xA7,  0xE2,  0x02,  0x20,  0x22,  0xFE,  0xA7,  0x21,  0x02,  0x10,  0x22,  0x8F,  0x44,  0x28,  0x26, 	/* 0D320 */
+	0x7C,  0x70,  0x06,  0xFE,  0xA2,  0x0A,  0x48,  0x25,  0xC2,  0xE4,  0xB4,  0x20,  0xE2,  0xF4,  0xF5,  0x22, 	/* 0D330 */
+	0x52,  0x28,  0x07,  0x7C,  0x68,  0x8A,  0x10,  0xAF,  0xE2,  0x10,  0x21,  0x02,  0x30,  0xB6,  0x2F,  0xC2, 	/* 0D340 */
+	0x48,  0x23,  0x0F,  0xFE,  0x29,  0x26,  0x92,  0x7F,  0xE6,  0x92,  0xAF,  0xEA,  0x92,  0x29,  0x22,  0x96, 	/* 0D350 */
+	0xB7,  0x21,  0x02,  0x3C,  0xF4,  0x82,  0xFE,  0x25,  0x27,  0x52,  0x6F,  0xEA,  0x52,  0xA7,  0xE2,  0x42, 	/* 0D360 */
+	0x28,  0x23,  0x06,  0xBE,  0x20,  0x02,  0xFC,  0xF2,  0x43,  0xFF,  0x22,  0x47,  0x24,  0x6F,  0xCA,  0x40, 	/* 0D370 */
+	0xAB,  0xE3,  0x22,  0x22,  0x22,  0x3E,  0xBF,  0x27,  0xC2,  0x44,  0xFF,  0xC2,  0x44,  0x27,  0xC7,  0x00, 	/* 0D380 */
+	0x6F,  0xEA,  0x10,  0xAF,  0xE2,  0x10,  0x21,  0x02,  0x10,  0x81,  0x80,  0x05,  0xF8,  0x84,  0x85,  0x4C, 	/* 0D390 */
+	0x28,  0xA5,  0x32,  0x84,  0x0F,  0xFE,  0x0E,  0x03,  0x58,  0xC4,  0x60,  0x40,  0x83,  0x20,  0x62,  0xF8, 	/* 0D3A0 */
+	0xF4,  0x82,  0x48,  0x2B,  0xE7,  0xC8,  0x64,  0x8B,  0x48,  0xAF,  0xE2,  0x40,  0x2B,  0x03,  0x0F,  0x85, 	/* 0D3B0 */
+	0x24,  0x02,  0x7E,  0xF4,  0x02,  0xFC,  0x2D,  0x47,  0x54,  0x6F,  0xE6,  0x54,  0xA5,  0x4A,  0xFE,  0x28, 	/* 0D3C0 */
+	0x42,  0x18,  0x8D,  0x22,  0x02,  0x7C,  0xFC,  0x42,  0x7C,  0x24,  0x47,  0x7C,  0x6A,  0x6A,  0x38,  0xAE, 	/* 0D3D0 */
+	0x02,  0x20,  0x22,  0x22,  0x1E,  0x8F,  0x25,  0x02,  0x50,  0xFF,  0xE2,  0x90,  0x21,  0x07,  0x7E,  0x69, 	/* 0D3E0 */
+	0x0A,  0x00,  0xA7,  0xC2,  0x44,  0x24,  0x42,  0x7C,  0x93,  0x21,  0x02,  0x10,  0x2F,  0xEF,  0x44,  0x22, 	/* 0D3F0 */
+	0x86,  0xFE,  0x71,  0x06,  0x10,  0xAF,  0xEA,  0x10,  0x21,  0x02,  0x10,  0x94,  0x20,  0x62,  0x78,  0xFC, 	/* 0D400 */
+	0x02,  0x7F,  0x24,  0x07,  0x7E,  0x6E,  0xAA,  0x6A,  0xAB,  0xE2,  0xA0,  0x32,  0x22,  0x1E,  0x97,  0x20, 	/* 0D410 */
+	0x02,  0xFE,  0x21,  0x0F,  0xFE,  0x25,  0x27,  0x7E,  0x6D,  0x2A,  0x7E,  0xA5,  0x02,  0x30,  0x26,  0xC2, 	/* 0D420 */
+	0x83,  0x9B,  0x20,  0x03,  0xEE,  0xFA,  0xA2,  0xAA,  0x3E,  0xC6,  0xAA,  0x6A,  0xAB,  0xEA,  0xAA,  0xA2, 	/* 0D430 */
+	0xAC,  0x32,  0x82,  0xC8,  0x9D,  0x22,  0x02,  0x3E,  0x24,  0x45,  0xA8,  0x53,  0x8D,  0xC6,  0x51,  0x05, 	/* 0D440 */
+	0xFE,  0x53,  0x85,  0x54,  0x59,  0x24,  0x10,  0x9F,  0x08,  0x03,  0xF8,  0x20,  0x83,  0xFE,  0x20,  0x03, 	/* 0D450 */
+	0xFC,  0x04,  0x40,  0x58,  0xFF,  0xF0,  0xE0,  0x35,  0x8C,  0x46,  0xA0,  0x20,  0x02,  0x7C,  0xFC,  0x42, 	/* 0D460 */
+	0x44,  0x27,  0xC7,  0x10,  0x6A,  0x0A,  0x7E,  0xA4,  0x22,  0x42,  0x24,  0x22,  0x7E,  0xA2,  0x21,  0x02, 	/* 0D470 */
+	0x92,  0x25,  0x4F,  0x10,  0x27,  0xC2,  0x44,  0x77,  0xC6,  0xC4,  0xA7,  0xCA,  0x44,  0x24,  0x42,  0x4C, 	/* 0D480 */
+	0xA6,  0x11,  0x0F,  0xFE,  0x11,  0x03,  0xB8,  0x55,  0x49,  0x12,  0x11,  0x01,  0xF8,  0x71,  0x00,  0xA0, 	/* 0D490 */
+	0x0C,  0x07,  0x00,  0xA7,  0x20,  0x02,  0xFE,  0x21,  0x0F,  0xFC,  0x22,  0x46,  0x24,  0x7F,  0xE6,  0x80, 	/* 0D4A0 */
+	0xA7,  0xCA,  0x44,  0xA4,  0x42,  0x7C,  0xA8,  0x18,  0x47,  0x24,  0x12,  0x4F,  0xE4,  0x3A,  0x45,  0x4C, 	/* 0D4B0 */
+	0x94,  0x0F,  0xFE,  0x0E,  0x03,  0x58,  0xC4,  0x60,  0x40,  0xAD,  0x21,  0x02,  0x24,  0xFF,  0xE2,  0x2A, 	/* 0D4C0 */
+	0x22,  0x87,  0x46,  0x6A,  0x0A,  0x3C,  0xA6,  0x42,  0x98,  0x23,  0x42,  0xC2,  0xAF,  0x24,  0x42,  0x28, 	/* 0D4D0 */
+	0x2F,  0xEF,  0x12,  0x27,  0xE2,  0x90,  0x7F,  0xE6,  0x32,  0xA3,  0x2A,  0x52,  0x39,  0x42,  0x10,  0xB0, 	/* 0D4E0 */
+	0x20,  0x62,  0x05,  0x2F,  0xFF,  0x04,  0x25,  0x47,  0x54,  0x6F,  0xD6,  0x55,  0xA5,  0x2A,  0x96,  0x30, 	/* 0D4F0 */
+	0x92,  0x11,  0xB1,  0x20,  0x02,  0xFE,  0x29,  0x2F,  0x92,  0x2F,  0xE6,  0x92,  0x7B,  0xA6,  0xBA,  0xAD, 	/* 0D500 */
+	0x6A,  0xD6,  0x29,  0x22,  0xFE,  0xB3,  0x21,  0x02,  0xFE,  0xF2,  0x82,  0x4C,  0x2F,  0x27,  0x00,  0x65, 	/* 0D510 */
+	0x4A,  0x54,  0xA5,  0x42,  0x55,  0x25,  0x52,  0x83,  0xB5,  0x20,  0x8F,  0xFE,  0x31,  0x86,  0xAC,  0xA4, 	/* 0D520 */
+	0xA2,  0x08,  0x1F,  0x01,  0x10,  0x19,  0x02,  0x52,  0x41,  0x28,  0x0E,  0xB6,  0x20,  0x02,  0x7E,  0x24, 	/* 0D530 */
+	0x2F,  0x7E,  0x24,  0x06,  0x7E,  0x74,  0x86,  0xFE,  0xA4,  0x82,  0x7D,  0x28,  0x92,  0x87,  0xB9,  0x20, 	/* 0D540 */
+	0xC2,  0x70,  0xFC,  0x02,  0x7C,  0x34,  0x86,  0xC8,  0x64,  0x8A,  0xFE,  0xA0,  0x02,  0x24,  0x24,  0x22, 	/* 0D550 */
+	0x82,  0xBA,  0x11,  0x0F,  0xFE,  0x39,  0x85,  0x74,  0x95,  0x21,  0x10,  0xFF,  0xE0,  0x60,  0x05,  0x80, 	/* 0D560 */
+	0x44,  0x04,  0x00,  0x40,  0xBC,  0x21,  0x02,  0xFE,  0x21,  0x0F,  0x7C,  0x21,  0x02,  0xFE,  0x72,  0x46, 	/* 0D570 */
+	0xFE,  0xA6,  0x4A,  0x94,  0x30,  0x42,  0x0C,  0x84,  0x04,  0x0F,  0xFE,  0x19,  0x07,  0xFC,  0x24,  0x8F, 	/* 0D580 */
+	0xFE,  0x24,  0x8F,  0xFE,  0x0E,  0x03,  0x58,  0xC4,  0x60,  0x40,  0x86,  0x21,  0x02,  0x10,  0xFA,  0x82, 	/* 0D590 */
+	0x44,  0x2F,  0xE7,  0x01,  0x6F,  0xEA,  0xAA,  0xAF,  0xE2,  0xAA,  0x2A,  0xA2,  0x86,  0x89,  0x21,  0x02, 	/* 0D5A0 */
+	0x7C,  0x24,  0x4F,  0x7C,  0x24,  0x47,  0x7C,  0x69,  0x06,  0x7E,  0xA5,  0x2A,  0x52,  0x25,  0x62,  0x10, 	/* 0D5B0 */
+	0x8A,  0x11,  0x0F,  0xFE,  0x11,  0x01,  0xF0,  0x11,  0x0F,  0xFE,  0x24,  0x84,  0x44,  0xBF,  0xA1,  0x50, 	/* 0D5C0 */
+	0x64,  0xC0,  0x40,  0x8B,  0x24,  0x42,  0x44,  0x2F,  0xEF,  0x44,  0x27,  0xC7,  0x44,  0x6F,  0xC6,  0x44, 	/* 0D5D0 */
+	0xAF,  0xEA,  0x28,  0x24,  0x42,  0x84,  0x8D,  0x20,  0x02,  0xFC,  0xF8,  0x42,  0xFC,  0x28,  0x46,  0xFC, 	/* 0D5E0 */
+	0x79,  0x0A,  0xF2,  0xA9,  0xC2,  0x90,  0x2F,  0x23,  0x8E,  0x92,  0x21,  0x02,  0xFE,  0x21,  0x0F,  0x7C, 	/* 0D5F0 */
+	0x22,  0x86,  0xFE,  0x75,  0x46,  0xBA,  0xA1,  0x0A,  0xFE,  0x21,  0x02,  0x10,  0x94,  0x20,  0x62,  0x78, 	/* 0D600 */
+	0xFC,  0x82,  0x7E,  0x24,  0x87,  0x76,  0x6C,  0x2A,  0x7C,  0xA4,  0x42,  0x7C,  0x24,  0x42,  0x7C,  0x95, 	/* 0D610 */
+	0x21,  0x02,  0xFE,  0xF8,  0x22,  0x82,  0x27,  0xC7,  0x00,  0x6F,  0xEA,  0x10,  0xA5,  0x42,  0x92,  0x31, 	/* 0D620 */
+	0x22,  0x30,  0x97,  0x04,  0x0F,  0xFE,  0x4E,  0x47,  0x58,  0xC4,  0x6F,  0xFE,  0x04,  0x07,  0xFC,  0x4E, 	/* 0D630 */
+	0x47,  0x58,  0xC4,  0x60,  0x40,  0x98,  0x20,  0x8F,  0xFE,  0x20,  0x8F,  0xBE,  0xAA,  0xAA,  0xAA,  0xAA, 	/* 0D640 */
+	0xA3,  0x0C,  0x69,  0xA6,  0x99,  0xA2,  0x82,  0x08,  0x9A,  0x20,  0x02,  0xEE,  0x2A,  0xAF,  0xAA,  0x2E, 	/* 0D650 */
+	0xE6,  0xAA,  0x7A,  0xA6,  0xEE,  0xAA,  0xAA,  0xAA,  0x2A,  0xA2,  0xB6,  0x9F,  0x21,  0x02,  0xFE,  0x21, 	/* 0D660 */
+	0x0F,  0x7E,  0x25,  0x23,  0x7E,  0x6D,  0x26,  0x7E,  0xA3,  0x8A,  0x54,  0x29,  0x22,  0x10,  0xA0,  0x44, 	/* 0D670 */
+	0x42,  0x48,  0xFF,  0xE9,  0xF2,  0x91,  0x21,  0xF0,  0x04,  0x0F,  0xFE,  0x0E,  0x03,  0x58,  0xC4,  0x60, 	/* 0D680 */
+	0x40,  0xA1,  0x20,  0x02,  0xFE,  0xFC,  0x62,  0xAA,  0x2F,  0xE7,  0x92,  0x6D,  0x6A,  0xD6,  0xAD,  0x62, 	/* 0D690 */
+	0xFE,  0x28,  0x22,  0x86,  0xA3,  0x21,  0x02,  0x7C,  0xF1,  0x42,  0xFE,  0x21,  0x47,  0x7C,  0x69,  0x2A, 	/* 0D6A0 */
+	0x54,  0xA3,  0x82,  0x54,  0x39,  0x22,  0x30,  0xA7,  0x21,  0x42,  0x1C,  0x2F,  0x0F,  0x14,  0x21,  0xA2, 	/* 0D6B0 */
+	0xE6,  0x71,  0x46,  0x1E,  0xAF,  0x4A,  0x18,  0x26,  0xA3,  0x86,  0xAE,  0x04,  0x07,  0xFC,  0x0E,  0x03, 	/* 0D6C0 */
+	0x58,  0xC4,  0x61,  0x48,  0x10,  0x8F,  0xFE,  0x31,  0x85,  0xAC,  0x94,  0xA1,  0x08,  0xAF,  0x21,  0x02, 	/* 0D6D0 */
+	0x28,  0x24,  0x4F,  0xBA,  0x20,  0x06,  0xFC,  0x70,  0x86,  0x10,  0xA2,  0x8A,  0xAA,  0x2A,  0x23,  0x1E, 	/* 0D6E0 */
+	0xB2,  0x21,  0x02,  0xFE,  0x21,  0x0F,  0x7C,  0x21,  0x46,  0xFE,  0x71,  0x46,  0xFE,  0xA2,  0x4A,  0x74, 	/* 0D6F0 */
+	0x21,  0x82,  0xE4,  0xB9,  0x21,  0x02,  0x1E,  0xF9,  0x02,  0x7C,  0x24,  0x47,  0x7C,  0x6C,  0x4A,  0x7C, 	/* 0D700 */
+	0xA1,  0x02,  0xFE,  0x21,  0x02,  0x10,  0xBA,  0x21,  0x02,  0xFE,  0x28,  0x2F,  0xFE,  0x24,  0x46,  0x44, 	/* 0D710 */
+	0x77,  0xC6,  0xC0,  0xA7,  0xEA,  0x42,  0x24,  0x22,  0x7E,  0x80,  0x21,  0x02,  0x10,  0x2F,  0xEF,  0x82, 	/* 0D720 */
+	0x2E,  0xE7,  0xAA,  0x6A,  0xA7,  0x6A,  0xA2,  0x8A,  0x48,  0x28,  0xA3,  0x06,  0x81,  0x21,  0x02,  0xFE, 	/* 0D730 */
+	0xF8,  0x02,  0x7C,  0x24,  0x47,  0x7C,  0x68,  0x0A,  0x7C,  0xA0,  0x82,  0xFF,  0x21,  0x02,  0x30,  0x84, 	/* 0D740 */
+	0x21,  0x02,  0xFE,  0xF4,  0x42,  0x28,  0x3F,  0xE6,  0x20,  0x7F,  0xEA,  0x48,  0xA4,  0x82,  0xF0,  0x22, 	/* 0D750 */
+	0x82,  0xC4,  0x85,  0x21,  0x02,  0x7E,  0x21,  0x0F,  0x28,  0x24,  0x46,  0xFE,  0x70,  0x46,  0x74,  0xA5, 	/* 0D760 */
+	0x4A,  0x74,  0x20,  0x42,  0x0C,  0x88,  0x22,  0x02,  0x20,  0xFB,  0xE2,  0x42,  0x29,  0x27,  0x56,  0x63, 	/* 0D770 */
+	0xAA,  0xFE,  0xA3,  0xA2,  0x56,  0x29,  0x22,  0x0C,  0x8B,  0x21,  0x02,  0xFE,  0x20,  0x0F,  0xFC,  0x24, 	/* 0D780 */
+	0x46,  0x44,  0x77,  0xC6,  0x90,  0xA5,  0x4A,  0x52,  0x29,  0x22,  0x30,  0x8C,  0x21,  0x02,  0xFE,  0xFA, 	/* 0D790 */
+	0xA2,  0xAA,  0x22,  0x87,  0x4E,  0x68,  0x0A,  0x7C,  0xA1,  0x02,  0x10,  0x21,  0x02,  0xFE,  0x8D,  0x20, 	/* 0D7A0 */
+	0x82,  0x7E,  0x20,  0x8F,  0xBC,  0x22,  0x42,  0xBC,  0x7A,  0x46,  0xBC,  0xAA,  0x4A,  0xBC,  0x28,  0x02, 	/* 0D7B0 */
+	0xFE,  0x8E,  0x22,  0x42,  0x28,  0x27,  0xEF,  0x48,  0x2C,  0x86,  0x7C,  0x74,  0x86,  0xC8,  0xA7,  0xCA, 	/* 0D7C0 */
+	0x48,  0x24,  0x82,  0x7E,  0x8F,  0x20,  0x02,  0xFE,  0xF2,  0x82,  0x28,  0x2E,  0xE7,  0x82,  0x68,  0x2A, 	/* 0D7D0 */
+	0x82,  0xAE,  0xE2,  0x28,  0x22,  0x82,  0xFE,  0x92,  0x24,  0x02,  0x5E,  0x27,  0x2F,  0x42,  0x24,  0xA3, 	/* 0D7E0 */
+	0xFA,  0x64,  0xC6,  0xE4,  0xAD,  0x4B,  0x4A,  0x25,  0x22,  0x62,  0x99,  0x27,  0xC2,  0x44,  0x27,  0xCF, 	/* 0D7F0 */
+	0xC4,  0x27,  0xC6,  0x00,  0x7F,  0xE6,  0x82,  0xAF,  0xEA,  0x82,  0x28,  0x22,  0xFE,  0x9A,  0x2E,  0xE2, 	/* 0D800 */
+	0xAA,  0xFE,  0xE2,  0xAA,  0x2E,  0xE7,  0x82,  0x68,  0x2A,  0x82,  0xA8,  0x22,  0x82,  0x28,  0x22,  0x86, 	/* 0D810 */
+	0x9B,  0x24,  0x83,  0xFE,  0x24,  0x8F,  0x20,  0x23,  0x06,  0x52,  0x6D,  0xC7,  0x50,  0xA5,  0x0A,  0x50, 	/* 0D820 */
+	0x25,  0x22,  0x4E,  0x9C,  0x21,  0x02,  0x28,  0x24,  0x4F,  0xFA,  0x21,  0x06,  0xFC,  0x79,  0x46,  0xFC, 	/* 0D830 */
+	0xA1,  0x0A,  0x28,  0x24,  0x43,  0x82,  0xA1,  0x20,  0x23,  0xF2,  0x2C,  0xAE,  0xAA,  0x3D,  0xA6,  0x4A, 	/* 0D840 */
+	0x7E,  0xA6,  0x4A,  0xA4,  0xAA,  0x72,  0x38,  0x22,  0x06,  0xA2,  0x20,  0x02,  0xFE,  0xF8,  0x22,  0xFE, 	/* 0D850 */
+	0x29,  0x27,  0x92,  0x6F,  0xEA,  0x9A,  0xA9,  0x62,  0xFE,  0x28,  0x22,  0xFE,  0xA3,  0x22,  0x82,  0x28, 	/* 0D860 */
+	0xFF,  0xE2,  0xAA,  0x2A,  0xA6,  0xFE,  0x7A,  0xAA,  0xAA,  0xBF,  0xF2,  0x28,  0x24,  0x42,  0x84,  0xA5, 	/* 0D870 */
+	0x24,  0x02,  0x8E,  0xFF,  0xA2,  0x4A,  0x24,  0xA7,  0xFA,  0x64,  0xAA,  0x4A,  0xAA,  0xA2,  0x9A,  0x30, 	/* 0D880 */
+	0xE2,  0x00,  0xA6,  0x21,  0x02,  0x54,  0xF9,  0x22,  0x7C,  0x22,  0x87,  0xFE,  0x64,  0x4A,  0x92,  0xB7, 	/* 0D890 */
+	0xD2,  0x24,  0x24,  0x42,  0x98,  0xA8,  0x20,  0x82,  0x7E,  0xFC,  0x02,  0x54,  0x25,  0x47,  0x5F,  0x66, 	/* 0D8A0 */
+	0x4A,  0x74,  0xAA,  0xC2,  0xA4,  0x32,  0x42,  0x2C,  0xAA,  0x24,  0x42,  0x28,  0xFF,  0xE2,  0x28,  0x22, 	/* 0D8B0 */
+	0x87,  0x2A,  0x6A,  0xAA,  0x6C,  0xA6,  0xC2,  0x28,  0x22,  0x82,  0xFE,  0xB0,  0x20,  0x03,  0xFE,  0xFA, 	/* 0D8C0 */
+	0xA2,  0xAA,  0x2E,  0xC7,  0xAC,  0x6E,  0xAA,  0xAA,  0xAA,  0xA3,  0xEC,  0x22,  0x82,  0x28,  0xB4,  0x25, 	/* 0D8D0 */
+	0xC2,  0x94,  0x29,  0x4F,  0xD5,  0x29,  0x32,  0xA0,  0x7D,  0xE6,  0x92,  0xAF,  0x4A,  0x88,  0x29,  0x42, 	/* 0D8E0 */
+	0xA2,  0xB6,  0x2A,  0xA2,  0x92,  0xFA,  0xA2,  0xFE,  0x22,  0x87,  0x4A,  0x6A,  0x6A,  0x3C,  0xA4,  0x42, 	/* 0D8F0 */
+	0xA8,  0x23,  0x82,  0xC6,  0xB9,  0x22,  0x42,  0x7E,  0xFA,  0x42,  0x3C,  0x22,  0x47,  0x3C,  0x6A,  0x4A, 	/* 0D900 */
+	0xFE,  0xAA,  0x82,  0xCE,  0x28,  0x02,  0x7E,  0xBD,  0x22,  0x02,  0x3C,  0x24,  0x4F,  0x78,  0x21,  0x06, 	/* 0D910 */
+	0xFE,  0x73,  0x26,  0xCC,  0xA1,  0xAA,  0xE9,  0x20,  0x82,  0x30,  0xBF,  0x21,  0x02,  0xFE,  0x21,  0x0F, 	/* 0D920 */
+	0xFE,  0x22,  0x87,  0xFE,  0x74,  0x46,  0xFE,  0xB4,  0x5A,  0x7C,  0x24,  0x42,  0x7C,  0x8A,  0x20,  0x02, 	/* 0D930 */
+	0x7C,  0x24,  0x4F,  0x7C,  0x24,  0x47,  0xFF,  0x74,  0x0A,  0xFE,  0xB2,  0xA2,  0xD2,  0x22,  0x22,  0xCC, 	/* 0D940 */
+	0x93,  0x20,  0x02,  0xFE,  0x28,  0xEF,  0xF2,  0x29,  0x26,  0xFE,  0x7D,  0x66,  0xFE,  0xA9,  0x2A,  0x96, 	/* 0D950 */
+	0x2F,  0xD3,  0x05,  0x94,  0x24,  0x02,  0xFE,  0x24,  0xAF,  0xEA,  0x25,  0x26,  0xEC,  0x75,  0x06,  0x10, 	/* 0D960 */
+	0xAF,  0xEA,  0x18,  0x22,  0x42,  0xC2,  0x95,  0x24,  0x02,  0xFE,  0x24,  0x0F,  0x7C,  0x29,  0x06,  0x7E, 	/* 0D970 */
+	0x70,  0x06,  0xFC,  0xA4,  0x4A,  0x7C,  0x24,  0x42,  0x4C,  0x99,  0x20,  0x42,  0xF4,  0x25,  0x4F,  0x2F, 	/* 0D980 */
+	0x3F,  0x46,  0x26,  0x76,  0xE6,  0x6D,  0xAB,  0x5B,  0x24,  0x22,  0x42,  0x64,  0x9A,  0x11,  0x0F,  0xFE, 	/* 0D990 */
+	0x11,  0x03,  0xB8,  0xD5,  0x61,  0x10,  0xFF,  0xE0,  0x44,  0x27,  0x82,  0x40,  0x5C,  0x08,  0x3E,  0x9C, 	/* 0D9A0 */
+	0x24,  0x02,  0x4E,  0xFF,  0xA2,  0x4A,  0x24,  0xE7,  0x4A,  0x6E,  0xAA,  0xAE,  0xAA,  0xA2,  0xEA,  0x21, 	/* 0D9B0 */
+	0x22,  0x26,  0x9D,  0x21,  0x02,  0xFE,  0x21,  0x0F,  0xFE,  0x2D,  0x66,  0xBA,  0x79,  0x26,  0xFE,  0xA3, 	/* 0D9C0 */
+	0x8A,  0x54,  0x29,  0x22,  0x10,  0x9E,  0x20,  0x02,  0xFE,  0x2A,  0xAF,  0xFE,  0x21,  0x07,  0x10,  0x6F, 	/* 0D9D0 */
+	0xE6,  0x20,  0xA3,  0xCA,  0x24,  0x24,  0x42,  0x98,  0xA0,  0x21,  0x02,  0xFE,  0x21,  0x0F,  0xFE,  0x2A, 	/* 0D9E0 */
+	0xA2,  0x92,  0x7F,  0xE6,  0x92,  0xAF,  0xEA,  0x92,  0x29,  0x22,  0x96,  0xA1,  0x21,  0x02,  0x10,  0x22, 	/* 0D9F0 */
+	0x8F,  0x7C,  0x28,  0x26,  0xEB,  0x7A,  0xA6,  0xF4,  0xAB,  0x4A,  0xEA,  0x2A,  0xA2,  0xAA,  0xA2,  0x24, 	/* 0DA00 */
+	0x42,  0x28,  0x2F,  0xEF,  0x28,  0x2F,  0xE2,  0xAA,  0x7A,  0xA6,  0xCE,  0xA8,  0x2A,  0xFE,  0x28,  0x22, 	/* 0DA10 */
+	0xFE,  0xAA,  0x25,  0x42,  0x54,  0x2F,  0xEF,  0x54,  0x25,  0xC6,  0x40,  0x77,  0xE6,  0x10,  0xAF,  0xEA, 	/* 0DA20 */
+	0x38,  0x25,  0x42,  0x92,  0xAB,  0x27,  0xC2,  0x44,  0xFF,  0xC2,  0x00,  0x2F,  0xE7,  0x44,  0x6F,  0xCA, 	/* 0DA30 */
+	0x44,  0xA7,  0xC2,  0x46,  0x2F,  0xC2,  0x04,  0xAD,  0x0A,  0x02,  0xA8,  0xFF,  0xE1,  0x10,  0x7F,  0xC0, 	/* 0DA40 */
+	0x40,  0x3F,  0x80,  0x40,  0xFF,  0xE1,  0x50,  0x24,  0x84,  0x44,  0xAE,  0x21,  0x02,  0xFC,  0x21,  0x4F, 	/* 0DA50 */
+	0x18,  0x2F,  0xE6,  0x30,  0x74,  0x86,  0xFC,  0xB4,  0x4A,  0x7C,  0x24,  0x42,  0x7C,  0xAF,  0x20,  0xC2, 	/* 0DA60 */
+	0x78,  0x24,  0x8F,  0x7E,  0x24,  0x87,  0x7E,  0x6E,  0x26,  0x7E,  0xAA,  0x2A,  0xBE,  0x32,  0x22,  0x3E, 	/* 0DA70 */
+	0xB3,  0x22,  0x42,  0xFE,  0x22,  0x4F,  0xBC,  0x22,  0x46,  0x3C,  0x71,  0x06,  0xFE,  0xA3,  0x8A,  0x54, 	/* 0DA80 */
+	0x29,  0x22,  0x10,  0xB4,  0x21,  0x02,  0xFE,  0xF4,  0x42,  0x28,  0x2F,  0xE7,  0x92,  0x69,  0x2A,  0x7C, 	/* 0DA90 */
+	0xA5,  0x42,  0x54,  0x25,  0x82,  0x10,  0xB5,  0x20,  0x02,  0xFE,  0x22,  0x0F,  0x40,  0x2E,  0xE6,  0x12, 	/* 0DAA0 */
+	0x7D,  0xA7,  0x54,  0xB5,  0x4B,  0xDA,  0x23,  0x02,  0xFE,  0xB7,  0x29,  0x02,  0x92,  0xFF,  0xC2,  0x90, 	/* 0DAB0 */
+	0x2B,  0x27,  0xCE,  0x60,  0x0B,  0x7C,  0xA4,  0x42,  0x7C,  0x24,  0x42,  0x7C,  0xB8,  0x22,  0x83,  0xC8, 	/* 0DAC0 */
+	0x24,  0x8F,  0x4A,  0x3F,  0xA6,  0x6C,  0x6D,  0x87,  0x48,  0xA4,  0xCA,  0x54,  0x25,  0x22,  0x61,  0xB9, 	/* 0DAD0 */
+	0x20,  0x02,  0x7C,  0xFA,  0x42,  0x26,  0x23,  0xA7,  0x2A,  0x65,  0x2A,  0xAC,  0xAF,  0xE2,  0xAA,  0x2A, 	/* 0DAE0 */
+	0xA3,  0xFF,  0xBC,  0x21,  0x02,  0x54,  0x2F,  0xEF,  0x38,  0x25,  0x46,  0x92,  0x72,  0x06,  0xFE,  0xA2, 	/* 0DAF0 */
+	0x8A,  0x48,  0x23,  0x82,  0xC4,  0xBD,  0x08,  0x09,  0xF2,  0x51,  0x41,  0xF0,  0x31,  0xCD,  0xF2,  0x04, 	/* 0DB00 */
+	0x0F,  0xFE,  0x0E,  0x03,  0x58,  0xC4,  0x60,  0x40,  0xBE,  0x21,  0x02,  0x7C,  0x24,  0x4F,  0xFC,  0x24, 	/* 0DB10 */
+	0x46,  0x7C,  0x79,  0x2A,  0x54,  0xA3,  0x82,  0x54,  0x29,  0x22,  0x30,  0x81,  0x21,  0x02,  0xFE,  0xF8, 	/* 0DB20 */
+	0x22,  0xFC,  0x21,  0x07,  0x24,  0x6F,  0xAA,  0x12,  0xA7,  0xC2,  0x10,  0x21,  0x02,  0xFE,  0x82,  0x20, 	/* 0DB30 */
+	0x02,  0xEE,  0x2A,  0xAF,  0xEA,  0x2A,  0xA6,  0xBF,  0x7E,  0x46,  0xC4,  0xAA,  0xCA,  0xED,  0x29,  0x52, 	/* 0DB40 */
+	0x23,  0x8A,  0x28,  0x82,  0x88,  0xFF,  0xE2,  0x6A,  0x26,  0xA6,  0xBE,  0x7A,  0xA7,  0xEA,  0xAB,  0xEA, 	/* 0DB50 */
+	0x88,  0x28,  0x82,  0x88,  0x8E,  0x2F,  0xE2,  0x10,  0x27,  0xEF,  0x42,  0x27,  0xE2,  0x42,  0x77,  0xE6, 	/* 0DB60 */
+	0x3C,  0xA6,  0x4A,  0x98,  0x21,  0x42,  0xE3,  0x91,  0x21,  0x42,  0xFE,  0xF5,  0x42,  0x7C,  0x25,  0x47, 	/* 0DB70 */
+	0x7C,  0x6D,  0x4A,  0x04,  0xAF,  0xE2,  0x44,  0x22,  0x42,  0x0C,  0x94,  0x24,  0x02,  0x4E,  0x2F,  0xAF, 	/* 0DB80 */
+	0x9A,  0x2F,  0xC6,  0x9A,  0x7F,  0x96,  0xC9,  0xAA,  0x9A,  0xDE,  0x39,  0x82,  0x08,  0x95,  0x21,  0x02, 	/* 0DB90 */
+	0xFE,  0x28,  0x2F,  0xAA,  0x25,  0x46,  0x92,  0x62,  0x87,  0x44,  0xAF,  0xEA,  0x44,  0x24,  0x42,  0x7C, 	/* 0DBA0 */
+	0x9B,  0x22,  0x02,  0xFC,  0x22,  0x0F,  0xFC,  0x25,  0x07,  0xFE,  0x69,  0x87,  0x64,  0xAF,  0xEA,  0x70, 	/* 0DBB0 */
+	0x3A,  0xC2,  0x20,  0x9C,  0x21,  0x02,  0xFE,  0xF4,  0x42,  0x28,  0x3F,  0xE7,  0x22,  0x6F,  0xCA,  0x20, 	/* 0DBC0 */
+	0xA3,  0xC2,  0x44,  0x24,  0x42,  0x98,  0xA0,  0x20,  0x02,  0xFE,  0x28,  0x2F,  0x7C,  0x24,  0x43,  0x7C, 	/* 0DBD0 */
+	0x6C,  0x46,  0x7C,  0xA1,  0x0A,  0xFE,  0x24,  0x82,  0x84,  0xA7,  0x20,  0x02,  0xFE,  0xFA,  0x82,  0xEE, 	/* 0DBE0 */
+	0x2A,  0x86,  0xEE,  0x7A,  0x8A,  0xEE,  0xAA,  0x82,  0xC8,  0x28,  0x82,  0xFE,  0xAE,  0x11,  0x05,  0x54, 	/* 0DBF0 */
+	0x2A,  0x84,  0x44,  0xFF,  0xE8,  0x42,  0x7F,  0xC0,  0xE0,  0x15,  0x02,  0x48,  0xC4,  0x60,  0x40,  0xB1, 	/* 0DC00 */
+	0x21,  0x02,  0xFE,  0x20,  0x0F,  0x7C,  0x24,  0x46,  0xFE,  0x74,  0x46,  0x7C,  0xA3,  0x2A,  0xEA,  0x23, 	/* 0DC10 */
+	0x42,  0x62,  0xB2,  0x20,  0x02,  0x7C,  0xF5,  0x42,  0x54,  0x26,  0xC7,  0x7C,  0x68,  0x0A,  0xFE,  0xAA, 	/* 0DC20 */
+	0xA2,  0xAA,  0x2A,  0xA3,  0xFF,  0xB4,  0x22,  0xF2,  0xC5,  0x29,  0x5F,  0x95,  0x2B,  0x56,  0xDB,  0x70, 	/* 0DC30 */
+	0x06,  0xFE,  0xA5,  0x2A,  0x7E,  0x25,  0x22,  0x7E,  0xBB,  0x27,  0xC2,  0x44,  0xF7,  0xC2,  0x44,  0x27, 	/* 0DC40 */
+	0xC7,  0x00,  0x6E,  0xEA,  0x66,  0xBB,  0xA2,  0x66,  0x3B,  0xA2,  0x66,  0xBE,  0x27,  0xC2,  0x44,  0xF5, 	/* 0DC50 */
+	0xC2,  0x54,  0x2F,  0xE7,  0x82,  0x6F,  0xCA,  0x44,  0xA7,  0xC2,  0x44,  0x24,  0x42,  0x4C,  0xBF,  0x21, 	/* 0DC60 */
+	0x02,  0x92,  0xFF,  0xE2,  0x00,  0x2F,  0xF7,  0x00,  0x6F,  0xEA,  0x42,  0xA7,  0xE2,  0x44,  0x22,  0x82, 	/* 0DC70 */
+	0xFE,  0x81,  0x21,  0x02,  0xFE,  0xF0,  0x02,  0x7C,  0x24,  0x47,  0x7C,  0x60,  0x0A,  0xFE,  0xAB,  0xA2, 	/* 0DC80 */
+	0xAA,  0x2B,  0xA2,  0x86,  0x83,  0x23,  0x87,  0xAA,  0x4A,  0x64,  0xDC,  0xFA,  0x44,  0x98,  0x5A,  0x4F, 	/* 0DC90 */
+	0xFE,  0x0E,  0x03,  0x58,  0xC4,  0x60,  0x40,  0x87,  0x24,  0xC2,  0x70,  0x24,  0x2F,  0x3E,  0x2A,  0x46, 	/* 0DCA0 */
+	0xBC,  0x7A,  0x46,  0xBC,  0xAA,  0x4A,  0xFE,  0x22,  0x42,  0xC2,  0x8A,  0x29,  0xEF,  0xD2,  0x11,  0xE5, 	/* 0DCB0 */
+	0x52,  0x7D,  0xE2,  0x22,  0x44,  0x6F,  0xFE,  0x0E,  0x03,  0x58,  0xC4,  0x60,  0x40,  0x8B,  0x24,  0x82, 	/* 0DCC0 */
+	0xFC,  0x24,  0x8F,  0xFC,  0x24,  0x86,  0xFE,  0x75,  0x46,  0x7C,  0xA5,  0x4A,  0xFE,  0x24,  0x42,  0x4C, 	/* 0DCD0 */
+	0x8C,  0x20,  0x42,  0x88,  0xF5,  0xE2,  0x12,  0x61,  0xE7,  0xD0,  0x65,  0xEA,  0x52,  0xA5,  0x22,  0x5E, 	/* 0DCE0 */
+	0x2A,  0x03,  0x1F,  0x8D,  0x21,  0x02,  0x28,  0x2C,  0x4F,  0x7E,  0x24,  0x42,  0x7C,  0x74,  0x46,  0xFC, 	/* 0DCF0 */
+	0xA4,  0x0A,  0xBE,  0x32,  0x22,  0x3E,  0x8E,  0x24,  0x42,  0x28,  0x2F,  0xEF,  0x10,  0x27,  0xC7,  0x10, 	/* 0DD00 */
+	0x6F,  0xF6,  0x20,  0xA7,  0xEA,  0x88,  0x30,  0x82,  0x7E,  0x90,  0x21,  0x02,  0x20,  0x2F,  0xCF,  0x94, 	/* 0DD10 */
+	0x2F,  0xC6,  0x94,  0x7F,  0xC6,  0xB4,  0xA3,  0xAA,  0x5E,  0x29,  0x03,  0x0E,  0x93,  0x27,  0xC2,  0x10, 	/* 0DD20 */
+	0xFF,  0xE2,  0x00,  0x27,  0xC7,  0x44,  0x6F,  0xCA,  0x44,  0xA7,  0xC2,  0x44,  0x27,  0xC2,  0xC2,  0x98, 	/* 0DD30 */
+	0x22,  0x42,  0xFE,  0x21,  0x0F,  0x7C,  0x21,  0x06,  0xFE,  0x79,  0x26,  0x54,  0xA3,  0x8A,  0xD4,  0x21, 	/* 0DD40 */
+	0x22,  0x30,  0x99,  0x21,  0x02,  0xFE,  0x21,  0x0F,  0xFC,  0x24,  0x46,  0x7C,  0x74,  0x46,  0xFC,  0xA4, 	/* 0DD50 */
+	0x4A,  0xFF,  0x22,  0x82,  0xC4,  0x9D,  0x21,  0x02,  0x7C,  0xFC,  0x42,  0x7C,  0x24,  0x47,  0x7E,  0x6C, 	/* 0DD60 */
+	0x0A,  0x7E,  0xA2,  0x22,  0xAA,  0x2F,  0xA2,  0x0C,  0x9E,  0x22,  0x02,  0xFC,  0xF4,  0x82,  0xFE,  0x20, 	/* 0DD70 */
+	0x07,  0xFC,  0x6A,  0x4A,  0xFC,  0xAA,  0x42,  0xFC,  0x22,  0x22,  0x1E,  0xA7,  0x10,  0x6F,  0xF8,  0x52, 	/* 0DD80 */
+	0x07,  0xBE,  0x52,  0x4F,  0xA4,  0x14,  0x40,  0x40,  0xFF,  0xE3,  0x70,  0xC4,  0xE0,  0x40,  0xA8,  0x24, 	/* 0DD90 */
+	0x03,  0xFE,  0x20,  0xAF,  0xEA,  0x2A,  0xC6,  0xEA,  0x70,  0xA6,  0xEA,  0xA4,  0xAB,  0xEC,  0x24,  0x82, 	/* 0DDA0 */
+	0xC8,  0xAB,  0x21,  0x02,  0xFE,  0xF9,  0x02,  0x7C,  0x35,  0x46,  0xFC,  0x65,  0x4A,  0xFE,  0xA8,  0x82, 	/* 0DDB0 */
+	0x48,  0x20,  0x82,  0x18,  0xAD,  0x20,  0xC2,  0x0A,  0x2F,  0xEF,  0x88,  0x2A,  0xA6,  0xBA,  0x7A,  0xA6, 	/* 0DDC0 */
+	0xFA,  0xAA,  0x4A,  0xF4,  0x2A,  0xB3,  0x31,  0xB2,  0x24,  0x22,  0x72,  0xFA,  0xA2,  0xF6,  0x2D,  0x26, 	/* 0DDD0 */
+	0xFA,  0x7D,  0x6A,  0xF3,  0xA9,  0xE2,  0x92,  0x29,  0x23,  0x32,  0xB9,  0x21,  0x02,  0x7C,  0xF4,  0x42, 	/* 0DDE0 */
+	0x7C,  0x24,  0x47,  0x7C,  0x69,  0x0A,  0xD6,  0xA1,  0x03,  0xFE,  0x21,  0x02,  0x10,  0xBB,  0x21,  0xE2, 	/* 0DDF0 */
+	0x52,  0x25,  0xEF,  0xF2,  0x25,  0xE6,  0xF2,  0x75,  0x26,  0x5E,  0xA4,  0xCA,  0xAC,  0x31,  0x52,  0x63, 	/* 0DE00 */
+	0xBD,  0x22,  0x82,  0xFE,  0x22,  0x8F,  0xFE,  0x2A,  0xA2,  0xFE,  0x7A,  0xA6,  0xFE,  0xA4,  0x4A,  0x7C, 	/* 0DE10 */
+	0x24,  0x42,  0x7C,  0xBF,  0x22,  0x42,  0xFE,  0xF2,  0x42,  0xFE,  0x29,  0x26,  0xFE,  0x71,  0x0A,  0xFC, 	/* 0DE20 */
+	0xA1,  0x02,  0xFC,  0x21,  0x03,  0xFE,  0x82,  0x44,  0x8A,  0x54,  0x5E,  0xAF,  0xBE,  0x2E,  0x87,  0xBC, 	/* 0DE30 */
+	0xAE,  0xA0,  0x40,  0xFF,  0xE0,  0xE0,  0x35,  0x8C,  0x46,  0x85,  0x25,  0x42,  0x54,  0x29,  0x4F,  0x5A, 	/* 0DE40 */
+	0x26,  0xA6,  0xA8,  0x68,  0x87,  0xAE,  0xAA,  0x8A,  0xA8,  0x2D,  0x82,  0x87,  0x8A,  0x2A,  0x82,  0x48, 	/* 0DE50 */
+	0xF5,  0xE2,  0xAC,  0x75,  0xAA,  0x68,  0x28,  0x80,  0x40,  0xFF,  0xE0,  0xA0,  0x31,  0x8C,  0x06,  0x8B, 	/* 0DE60 */
+	0x23,  0xE2,  0x94,  0x24,  0xCF,  0x3E,  0x22,  0xA7,  0xBE,  0x6A,  0xA6,  0xBE,  0xAA,  0xAA,  0xA6,  0x34, 	/* 0DE70 */
+	0x02,  0x3F,  0x8C,  0x27,  0xC2,  0x54,  0x2F,  0xEF,  0xA8,  0x2F,  0x86,  0x7C,  0x74,  0x46,  0x7C,  0xA4, 	/* 0DE80 */
+	0x4A,  0x7C,  0x24,  0x42,  0x82,  0x92,  0x21,  0x02,  0xFE,  0x2A,  0x2F,  0x90,  0x22,  0x42,  0xAA,  0x73, 	/* 0DE90 */
+	0x26,  0xCE,  0xA1,  0x0A,  0x92,  0x29,  0x22,  0xFE,  0x93,  0x21,  0x02,  0xFE,  0x29,  0x2F,  0xFF,  0x29, 	/* 0DEA0 */
+	0x26,  0xFE,  0x79,  0x26,  0xFF,  0xA2,  0x4A,  0x44,  0x23,  0x82,  0xE4,  0x94,  0x25,  0x42,  0xA8,  0xF5, 	/* 0DEB0 */
+	0x42,  0x7C,  0x35,  0x46,  0xFC,  0x65,  0x4A,  0xFE,  0xA3,  0x82,  0x54,  0x29,  0x22,  0x10,  0x97,  0x27, 	/* 0DEC0 */
+	0xC2,  0x10,  0x2F,  0xEF,  0x92,  0x2D,  0xA6,  0xB6,  0x70,  0x06,  0xFF,  0xA2,  0x0A,  0x3C,  0x20,  0x42, 	/* 0DED0 */
+	0x18,  0x99,  0x2F,  0xE2,  0x28,  0xFF,  0xE2,  0xAA,  0x2F,  0xE7,  0x00,  0x6F,  0xCA,  0x00,  0xAF,  0xE2, 	/* 0DEE0 */
+	0x54,  0x29,  0x22,  0x30,  0x9B,  0x20,  0x02,  0xFE,  0x2A,  0xAF,  0x76,  0x2A,  0xA6,  0x76,  0x72,  0xC6, 	/* 0DEF0 */
+	0x4A,  0xAB,  0x1A,  0xC4,  0x21,  0x82,  0xE0,  0x9E,  0x20,  0x02,  0xFE,  0xFB,  0xC2,  0xA4,  0x2B,  0xC6, 	/* 0DF00 */
+	0x80,  0x7E,  0xEA,  0xAA,  0xAA,  0xA2,  0xEE,  0x28,  0x02,  0xFE,  0x9F,  0x21,  0x02,  0xFC,  0x22,  0x8F, 	/* 0DF10 */
+	0xFE,  0x24,  0x43,  0x7C,  0x6C,  0x46,  0x7C,  0xA1,  0x0B,  0xFE,  0x21,  0x02,  0x10,  0xA1,  0x22,  0x82, 	/* 0DF20 */
+	0xFE,  0xFA,  0x82,  0x7C,  0x74,  0x46,  0xFC,  0x67,  0xCA,  0x10,  0xAF,  0xE2,  0x30,  0x24,  0x83,  0x86, 	/* 0DF30 */
+	0xA2,  0x22,  0x02,  0x7C,  0x24,  0x4F,  0xFC,  0x24,  0x46,  0x7E,  0x74,  0x06,  0x7E,  0xAA,  0xAA,  0x96, 	/* 0DF40 */
+	0x30,  0x22,  0x0C,  0xA3,  0x22,  0x42,  0xFE,  0x21,  0x0F,  0x7C,  0x21,  0x06,  0xFE,  0x71,  0x06,  0x34, 	/* 0DF50 */
+	0xAD,  0x8A,  0x34,  0x2D,  0x22,  0x30,  0xA9,  0x24,  0x02,  0x7C,  0x29,  0x0F,  0x7E,  0x22,  0x83,  0x7E, 	/* 0DF60 */
+	0x6D,  0x07,  0x7C,  0xA5,  0x0A,  0x7C,  0x25,  0x02,  0x7E,  0xAA,  0x22,  0x42,  0x7E,  0xF2,  0x42,  0xFF, 	/* 0DF70 */
+	0x21,  0x06,  0x7E,  0x75,  0x26,  0xFE,  0xA5,  0x2A,  0x7E,  0x22,  0x42,  0xC2,  0xAB,  0x2F,  0xE2,  0xAA, 	/* 0DF80 */
+	0x2F,  0xAF,  0x94,  0x2F,  0x46,  0xAA,  0x7F,  0x26,  0x10,  0xA7,  0xCA,  0x10,  0x21,  0x02,  0xFE,  0xAE, 	/* 0DF90 */
+	0x20,  0x02,  0xFE,  0xF2,  0x82,  0xFE,  0x2A,  0xA6,  0xFE,  0x71,  0x0A,  0x52,  0xA5,  0x42,  0x98,  0x22, 	/* 0DFA0 */
+	0x42,  0xC2,  0xB5,  0x22,  0x42,  0x28,  0x27,  0xEF,  0xC8,  0x27,  0xC3,  0x48,  0x6F,  0xC6,  0x48,  0xA7, 	/* 0DFB0 */
+	0xEA,  0x00,  0x2D,  0x43,  0x2A,  0xB6,  0x27,  0xC2,  0x44,  0x27,  0xCF,  0x44,  0x2F,  0xF7,  0xA0,  0x6F, 	/* 0DFC0 */
+	0xE6,  0xAA,  0xAE,  0xAA,  0xA4,  0x3E,  0xA2,  0x31,  0xB8,  0x2A,  0xA2,  0x6C,  0x2F,  0xEF,  0x44,  0x22, 	/* 0DFD0 */
+	0x86,  0xFE,  0x71,  0x06,  0x7C,  0xA1,  0x0A,  0xFE,  0x24,  0x42,  0x82,  0xB9,  0x22,  0x22,  0xF2,  0x22, 	/* 0DFE0 */
+	0x2F,  0xFF,  0x20,  0x26,  0xFA,  0x79,  0x66,  0xF2,  0xA9,  0x2A,  0x7A,  0x38,  0x22,  0x06,  0xBA,  0x24, 	/* 0DFF0 */
+	0x82,  0xFE,  0x24,  0x8F,  0xFE,  0x25,  0x46,  0xFE,  0x75,  0x46,  0xFE,  0xA1,  0x0A,  0xFE,  0x21,  0x02, 	/* 0E000 */
+	0x10,  0xBD,  0x28,  0x83,  0xFC,  0x25,  0x0F,  0xFC,  0x2D,  0x42,  0x8C,  0x6F,  0xC7,  0xFE,  0xA4,  0x8A, 	/* 0E010 */
+	0x28,  0x20,  0x82,  0x18,  0x84,  0x20,  0x42,  0xF4,  0x24,  0xFF,  0xEA,  0x2B,  0x26,  0xEA,  0x7A,  0xC6, 	/* 0E020 */
+	0xE4,  0xAA,  0x4A,  0xEA,  0x33,  0x22,  0x21,  0x87,  0x20,  0xC2,  0x70,  0x22,  0x0F,  0xFC,  0x22,  0x26, 	/* 0E030 */
+	0x1E,  0x70,  0x06,  0xEE,  0xA4,  0x4A,  0xEE,  0x24,  0x42,  0x33,  0x88,  0x27,  0xC2,  0x10,  0x2F,  0xEF, 	/* 0E040 */
+	0x44,  0x2E,  0xE7,  0x44,  0x7F,  0xE6,  0x00,  0xAF,  0xEA,  0x28,  0x24,  0xA3,  0x86,  0x8B,  0x27,  0xC2, 	/* 0E050 */
+	0x10,  0x2F,  0xEF,  0x28,  0x24,  0x46,  0xBA,  0x72,  0x86,  0xFE,  0xAB,  0xAA,  0xAA,  0x2B,  0xA2,  0x86, 	/* 0E060 */
+	0x98,  0x27,  0xC2,  0x28,  0x2F,  0xEF,  0x34,  0x2D,  0x06,  0xFE,  0x7A,  0xA6,  0xCE,  0xAB,  0xAA,  0xAA, 	/* 0E070 */
+	0x2B,  0xA2,  0x86,  0x99,  0x27,  0x02,  0x16,  0x2E,  0x8F,  0x2A,  0x24,  0x46,  0x82,  0x77,  0xC6,  0xC4, 	/* 0E080 */
+	0xA7,  0xCA,  0x44,  0x22,  0x82,  0xFE,  0x9F,  0x22,  0x42,  0x48,  0x2F,  0xCF,  0x5A,  0x2F,  0xE6,  0x14, 	/* 0E090 */
+	0x7F,  0xE6,  0x94,  0xAD,  0x8A,  0xAA,  0x31,  0x62,  0x62,  0xA1,  0x23,  0x82,  0xC8,  0x2F,  0xEF,  0x92, 	/* 0E0A0 */
+	0x2F,  0xE2,  0x30,  0x7D,  0xA6,  0x2C,  0xAD,  0x8A,  0x2C,  0x2C,  0xA2,  0x30,  0xA2,  0x20,  0x82,  0xFE, 	/* 0E0B0 */
+	0x2A,  0x8F,  0xAE,  0x2D,  0x46,  0xBE,  0x7A,  0x06,  0xBE,  0xAB,  0x2A,  0xDE,  0x29,  0x22,  0x96,  0xA6, 	/* 0E0C0 */
+	0x21,  0x02,  0xFC,  0x24,  0x8F,  0xFE,  0x20,  0x06,  0x7C,  0x75,  0x46,  0x7C,  0xA5,  0x4A,  0xFE,  0x21, 	/* 0E0D0 */
+	0x02,  0xFE,  0xB2,  0x21,  0x02,  0xFE,  0x21,  0x0F,  0x7C,  0x20,  0x07,  0x7C,  0x6C,  0x46,  0x7C,  0xA2, 	/* 0E0E0 */
+	0x8A,  0xFE,  0x24,  0x42,  0x7C,  0xB8,  0x27,  0xC2,  0x44,  0x27,  0xCF,  0x44,  0x27,  0xC6,  0x00,  0x7E, 	/* 0E0F0 */
+	0xE6,  0xAA,  0xAE,  0xEA,  0xAA,  0x2A,  0xA2,  0xEE,  0xBF,  0x20,  0x02,  0xFE,  0x25,  0x4F,  0x7C,  0x25, 	/* 0E100 */
+	0x47,  0x7C,  0x68,  0x06,  0xFE,  0xA5,  0x4A,  0x7C,  0x25,  0x42,  0xFE,  0x80,  0x22,  0x03,  0xFE,  0x28, 	/* 0E110 */
+	0x4F,  0xF4,  0x2D,  0x46,  0xFC,  0x70,  0x06,  0x78,  0xA4,  0x8A,  0x78,  0x24,  0x82,  0xFE,  0x84,  0x24, 	/* 0E120 */
+	0x02,  0xE8,  0x2A,  0x8F,  0xEE,  0x2A,  0xA6,  0xF2,  0x75,  0xA6,  0xF4,  0xA4,  0x4A,  0x64,  0x2A,  0xA3, 	/* 0E130 */
+	0x71,  0x8D,  0x21,  0x02,  0xFC,  0x24,  0x8F,  0xFE,  0x24,  0x46,  0x7C,  0x74,  0x46,  0x7C,  0xAA,  0x0A, 	/* 0E140 */
+	0xD4,  0x34,  0xA2,  0x38,  0x8E,  0x21,  0x02,  0x30,  0x24,  0x8F,  0xCC,  0x2B,  0x66,  0xCC,  0x6F,  0xC7, 	/* 0E150 */
+	0x10,  0xAF,  0xEA,  0x96,  0x2F,  0xA2,  0x86,  0x90,  0x23,  0xC2,  0x48,  0x2F,  0xEF,  0x94,  0x2E,  0x76, 	/* 0E160 */
+	0x9C,  0x78,  0x06,  0xFE,  0xA8,  0x0A,  0xBE,  0x32,  0x22,  0x3E,  0x97,  0x79,  0x04,  0xFC,  0x7A,  0x84, 	/* 0E170 */
+	0x7E,  0x79,  0x04,  0xFE,  0xB9,  0x00,  0x40,  0xFF,  0xE0,  0xE0,  0x35,  0x8C,  0x46,  0x9C,  0x21,  0x02, 	/* 0E180 */
+	0x28,  0xF4,  0x42,  0x82,  0x2F,  0xF7,  0xAA,  0x69,  0x2A,  0xFE,  0xA4,  0x42,  0x7C,  0x24,  0x42,  0x7C, 	/* 0E190 */
+	0xA0,  0x29,  0x0F,  0xDE,  0x2A,  0x47,  0xF4,  0xD4,  0x87,  0x54,  0x1A,  0x20,  0x40,  0xFF,  0xE0,  0xE0, 	/* 0E1A0 */
+	0x35,  0x8C,  0x46,  0xA2,  0x22,  0x02,  0x50,  0x28,  0x8F,  0x74,  0x20,  0x27,  0xDC,  0x75,  0x47,  0xDC, 	/* 0E1B0 */
+	0xA4,  0x8A,  0x48,  0x2B,  0x43,  0x12,  0xA3,  0x21,  0x02,  0xFE,  0x21,  0x0F,  0x54,  0x25,  0x46,  0xBA, 	/* 0E1C0 */
+	0x71,  0x06,  0xFE,  0xAA,  0xAA,  0xBA,  0x28,  0x22,  0xFE,  0xAA,  0x21,  0x02,  0x10,  0x23,  0x8F,  0xAA, 	/* 0E1D0 */
+	0x27,  0xC6,  0xAA,  0x73,  0x86,  0x10,  0xAF,  0xEA,  0x38,  0x25,  0x42,  0x92,  0xAC,  0x28,  0x83,  0xFC, 	/* 0E1E0 */
+	0x2A,  0x8F,  0xFC,  0x28,  0x47,  0x7C,  0x6D,  0x06,  0x34,  0xAD,  0x8A,  0x34,  0x2D,  0x22,  0x20,  0xAE, 	/* 0E1F0 */
+	0x21,  0x02,  0xFE,  0xF1,  0x02,  0x7E,  0x30,  0x26,  0xFC,  0x61,  0x0A,  0xFF,  0xAE,  0x22,  0xBF,  0x2E, 	/* 0E200 */
+	0xA2,  0x02,  0xB3,  0x21,  0x02,  0xFE,  0x2B,  0x2F,  0x54,  0x2B,  0x86,  0xFC,  0x74,  0x46,  0x7C,  0xA4, 	/* 0E210 */
+	0x4A,  0x7C,  0x22,  0x42,  0x42,  0xB8,  0x21,  0x02,  0xFE,  0x2A,  0x2F,  0x54,  0x2B,  0xA7,  0x00,  0x6F, 	/* 0E220 */
+	0xE6,  0xAA,  0xBF,  0xFA,  0x08,  0x20,  0x82,  0x18,  0xBB,  0x2E,  0x82,  0x88,  0x2E,  0xEF,  0xB0,  0x2E, 	/* 0E230 */
+	0x07,  0x8E,  0x6E,  0x06,  0x00,  0xAF,  0xEA,  0xAA,  0x2A,  0xA3,  0xFF,  0x81,  0x21,  0x02,  0xFE,  0x2B, 	/* 0E240 */
+	0x6F,  0x28,  0x2B,  0x46,  0xCE,  0x71,  0x26,  0x7C,  0xA5,  0x4A,  0x7C,  0x21,  0x42,  0xFA,  0x82,  0x20, 	/* 0E250 */
+	0x02,  0xFE,  0x26,  0x6F,  0xAA,  0x26,  0x66,  0x2A,  0x74,  0x86,  0xFC,  0xB9,  0x0A,  0xFC,  0x29,  0x02, 	/* 0E260 */
+	0xFC,  0x83,  0x20,  0x02,  0xFF,  0x28,  0x8F,  0xBE,  0x2A,  0xA6,  0xFF,  0x7A,  0x26,  0xBE,  0xAA,  0x2A, 	/* 0E270 */
+	0xBE,  0x2C,  0x12,  0xFF,  0x91,  0x27,  0xC2,  0x54,  0x27,  0xCF,  0x54,  0x27,  0xC7,  0x00,  0x6E,  0xE6, 	/* 0E280 */
+	0xAA,  0xAE,  0xEA,  0xAA,  0x2A,  0xA2,  0xEE,  0x93,  0x23,  0xC2,  0x48,  0x2F,  0xEF,  0x92,  0x2F,  0xE6, 	/* 0E290 */
+	0x92,  0x7F,  0xE6,  0xAA,  0xB2,  0x9A,  0xFE,  0x28,  0x22,  0xFE,  0x9A,  0x2E,  0xE2,  0xAA,  0x2E,  0xEF, 	/* 0E2A0 */
+	0xAA,  0x2F,  0xE6,  0xAA,  0x7B,  0xA6,  0x92,  0xAB,  0xAA,  0xAA,  0x2B,  0xA2,  0x86,  0x9B,  0x28,  0x82, 	/* 0E2B0 */
+	0xEE,  0x35,  0x4F,  0x44,  0x2E,  0xE6,  0xAA,  0x7E,  0xA6,  0xAA,  0xAE,  0xAA,  0x8E,  0x2E,  0x82,  0xA8, 	/* 0E2C0 */
+	0x9E,  0x24,  0x82,  0x8E,  0x31,  0x4E,  0xDC,  0x2B,  0xE7,  0xE8,  0x64,  0xA7,  0x7A,  0xAE,  0xCB,  0x5A, 	/* 0E2D0 */
+	0x26,  0x92,  0x58,  0x9F,  0x29,  0x23,  0x54,  0x2B,  0xAF,  0xEC,  0x2B,  0xA7,  0xEE,  0x6B,  0xA6,  0x10, 	/* 0E2E0 */
+	0xBF,  0xEA,  0x34,  0x25,  0x22,  0x10,  0xA8,  0x22,  0x02,  0x3C,  0x22,  0x0F,  0xFE,  0x29,  0x06,  0xBE, 	/* 0E2F0 */
+	0x79,  0x06,  0xBE,  0xAA,  0xAA,  0xBE,  0x32,  0xA2,  0x7F,  0xAA,  0x20,  0x02,  0xFE,  0x2A,  0x4F,  0xFE, 	/* 0E300 */
+	0x2A,  0xC6,  0xF6,  0x7A,  0x46,  0x90,  0xA9,  0x0B,  0x5E,  0x25,  0x02,  0xFE,  0xBA,  0x27,  0xC2,  0x10, 	/* 0E310 */
+	0x2F,  0xEF,  0x92,  0x2D,  0xA6,  0xB6,  0x79,  0x26,  0x00,  0xAD,  0x6A,  0xAA,  0x2A,  0xA2,  0xD6,  0xBB, 	/* 0E320 */
+	0x2E,  0xE2,  0xAA,  0x2E,  0xEF,  0xAA,  0x2E,  0xE6,  0x44,  0x7A,  0xA6,  0x20,  0xBF,  0xEA,  0x64,  0x23, 	/* 0E330 */
+	0x82,  0x64,  0x84,  0x2E,  0xE2,  0xAA,  0x2E,  0xEF,  0x92,  0x2F,  0xE6,  0x92,  0x7F,  0xE6,  0x96,  0xAF, 	/* 0E340 */
+	0xEA,  0xBA,  0x2D,  0x62,  0x92,  0x85,  0x22,  0x02,  0xDC,  0x2A,  0x4F,  0xFC,  0x2B,  0x47,  0xFE,  0x74, 	/* 0E350 */
+	0x86,  0xBC,  0xB1,  0x2A,  0xFC,  0x21,  0x02,  0x30,  0x8A,  0x22,  0x82,  0xFE,  0x22,  0x8F,  0xEE,  0x2A, 	/* 0E360 */
+	0xA6,  0xEE,  0x74,  0x06,  0x7E,  0xAC,  0x8A,  0x7E,  0x24,  0x82,  0x7E,  0x92,  0x45,  0x0A,  0xE8,  0x51, 	/* 0E370 */
+	0x2F,  0xFE,  0x6E,  0xCB,  0xBA,  0x2E,  0x80,  0x40,  0xFF,  0xE1,  0xF0,  0xE4,  0xE0,  0x40,  0x96,  0x2E, 	/* 0E380 */
+	0x82,  0xAE,  0x2F,  0x0F,  0xFE,  0x2A,  0xA6,  0xFE,  0x74,  0x46,  0x7C,  0xA4,  0x4A,  0x7C,  0x22,  0xA2, 	/* 0E390 */
+	0xCE,  0x9D,  0x24,  0x8F,  0xBE,  0x75,  0xCA,  0xAA,  0x7F,  0xC4,  0xA4,  0x7F,  0xC4,  0x88,  0x7F,  0xE5, 	/* 0E3A0 */
+	0x28,  0x48,  0x8F,  0x58,  0x9F,  0x4A,  0x05,  0xFE,  0x4A,  0xAF,  0xFE,  0x45,  0xAC,  0xFE,  0xDA,  0xAE, 	/* 0E3B0 */
+	0xFE,  0xCA,  0x44,  0xF4,  0x4A,  0x54,  0xFB,  0xA0,  0x10,  0x01,  0x00,  0x10,  0x01,  0xFE,  0x24,  0x42, 	/* 0E3C0 */
+	0x48,  0x44,  0x00,  0x60,  0x0A,  0x01,  0x10,  0x20,  0x8C,  0x06,  0xA1,  0x04,  0x04,  0x40,  0x24,  0x02, 	/* 0E3D0 */
+	0x7E,  0x0A,  0x21,  0x24,  0x02,  0x02,  0x30,  0x45,  0x04,  0x48,  0x88,  0x4B,  0x02,  0xA3,  0x1A,  0x06, 	/* 0E3E0 */
+	0x20,  0x42,  0x04,  0x3E,  0x7D,  0x25,  0x54,  0x59,  0x05,  0x10,  0x53,  0x05,  0x28,  0x94,  0x41,  0x82, 	/* 0E3F0 */
+	0xA7,  0x02,  0x0F,  0xA0,  0x82,  0x0C,  0xBE,  0xAA,  0xA9,  0x4C,  0x94,  0x8A,  0x88,  0xC9,  0x88,  0x14, 	/* 0E400 */
+	0xFA,  0x40,  0xC2,  0xB2,  0x2A,  0x02,  0xA0,  0x47,  0xE9,  0x22,  0x15,  0x42,  0x90,  0x45,  0x0F,  0xD0, 	/* 0E410 */
+	0x4A,  0x84,  0xA8,  0x4C,  0x47,  0x82,  0xB7,  0x65,  0x01,  0x90,  0x65,  0xE1,  0x2A,  0xFC,  0xC2,  0x08, 	/* 0E420 */
+	0x7C,  0x85,  0x48,  0xD5,  0x45,  0xD4,  0x52,  0x21,  0x41,  0xB8,  0x11,  0x02,  0x90,  0xF5,  0xE2,  0x2A, 	/* 0E430 */
+	0x3C,  0xC5,  0x08,  0x90,  0x8F,  0xC8,  0x11,  0x42,  0x94,  0x42,  0x28,  0x41,  0xB9,  0x21,  0x02,  0x10, 	/* 0E440 */
+	0xFD,  0xE3,  0x2A,  0x4A,  0xCF,  0xC8,  0x04,  0x87,  0x48,  0x55,  0x47,  0x54,  0x06,  0x40,  0xC2,  0xBA, 	/* 0E450 */
+	0x4A,  0x04,  0xA0,  0xFE,  0x04,  0xBE,  0x7D,  0x24,  0xD4,  0x79,  0x04,  0x90,  0xFD,  0x05,  0x28,  0x4C, 	/* 0E460 */
+	0x49,  0x82,  0xBD,  0x22,  0x02,  0x20,  0x52,  0x04,  0xBE,  0xFD,  0x22,  0x54,  0xF9,  0x02,  0x10,  0xB1, 	/* 0E470 */
+	0x86,  0xA8,  0x34,  0x4C,  0x82,  0xBE,  0x22,  0x0F,  0xA0,  0x22,  0x07,  0xBE,  0x05,  0x27,  0x54,  0x01, 	/* 0E480 */
+	0x0F,  0x90,  0x32,  0x8A,  0xA8,  0xA4,  0x46,  0x82,  0x83,  0x19,  0x0E,  0x10,  0x21,  0xEF,  0x9A,  0x22, 	/* 0E490 */
+	0xC6,  0x28,  0xBC,  0x8A,  0x88,  0xF9,  0x4A,  0x94,  0xAA,  0x2F,  0xC1,  0x87,  0x02,  0x07,  0xA0,  0x4B, 	/* 0E4A0 */
+	0xE7,  0xAA,  0x4A,  0xC7,  0xC8,  0x20,  0x87,  0xC8,  0xA5,  0x45,  0x54,  0x76,  0x21,  0xC1,  0x89,  0x29, 	/* 0E4B0 */
+	0x05,  0x10,  0xFD,  0x05,  0x3E,  0xFE,  0xA5,  0x4C,  0xFE,  0x85,  0x4C,  0xFC,  0xC5,  0x8A,  0xD5,  0x25, 	/* 0E4C0 */
+	0x21,  0x8C,  0x01,  0x0F,  0xD0,  0xE9,  0xEA,  0xAA,  0xEA,  0xC0,  0xC8,  0xF8,  0x80,  0x98,  0xE9,  0x4A, 	/* 0E4D0 */
+	0xA4,  0xEC,  0x21,  0x81,  0x8E,  0x51,  0x0F,  0x90,  0x51,  0xEF,  0x9A,  0xAA,  0xAF,  0xAC,  0x24,  0x8F, 	/* 0E4E0 */
+	0x88,  0x21,  0x8F,  0x94,  0x52,  0x48,  0xC2,  0x90,  0x01,  0x0F,  0xD0,  0x81,  0xEB,  0xAA,  0xAC,  0xCB, 	/* 0E4F0 */
+	0x88,  0xEE,  0x8A,  0xA8,  0xEF,  0x48,  0x14,  0xFE,  0x28,  0x41,  0x93,  0x41,  0x07,  0xD0,  0x51,  0x07, 	/* 0E500 */
+	0xDE,  0xAA,  0xA7,  0xCC,  0x50,  0x8F,  0xC8,  0x51,  0x87,  0xD4,  0x52,  0x47,  0xC2,  0x94,  0x21,  0x03, 	/* 0E510 */
+	0x90,  0x21,  0xE7,  0xEA,  0x54,  0xC7,  0xA8,  0x5E,  0x85,  0x48,  0x75,  0x45,  0x54,  0x9E,  0x23,  0x41, 	/* 0E520 */
+	0x99,  0x21,  0x03,  0x10,  0x49,  0xEB,  0x5A,  0x7A,  0xC4,  0x88,  0xFC,  0x86,  0xC8,  0xB5,  0x46,  0xD4, 	/* 0E530 */
+	0xB5,  0x22,  0x61,  0x9B,  0x21,  0x03,  0x10,  0x49,  0x0B,  0xDE,  0x02,  0xAF,  0xCC,  0xB4,  0x8F,  0xC8, 	/* 0E540 */
+	0x29,  0x42,  0x94,  0x56,  0x28,  0x41,  0x9F,  0x10,  0x87,  0x68,  0x52,  0x87,  0xEE,  0x4B,  0xA6,  0xAC, 	/* 0E550 */
+	0x6E,  0x86,  0xA8,  0x6A,  0xCF,  0xF4,  0x2A,  0x2C,  0x41,  0xA1,  0x29,  0x0F,  0xD0,  0x29,  0x0F,  0xDE, 	/* 0E560 */
+	0xB6,  0xAF,  0xCC,  0x48,  0x87,  0xC8,  0xD0,  0xC7,  0xD4,  0x52,  0x27,  0xC1,  0xA2,  0x04,  0x00,  0x40, 	/* 0E570 */
+	0x04,  0x00,  0x40,  0x24,  0x02,  0x7C,  0x24,  0x02,  0x40,  0x24,  0x02,  0x40,  0x24,  0x0F,  0xFE,  0xA3, 	/* 0E580 */
+	0x00,  0x07,  0xFC,  0x04,  0x00,  0x40,  0x04,  0x02,  0x7C,  0x24,  0x02,  0x40,  0x24,  0x02,  0x40,  0x24, 	/* 0E590 */
+	0x0F,  0xFE,  0xA4,  0x12,  0x01,  0x20,  0x12,  0x01,  0x20,  0x5E,  0x65,  0x38,  0x52,  0x05,  0x20,  0x52, 	/* 0E5A0 */
+	0x05,  0x22,  0x5E,  0x2E,  0x1E,  0xA6,  0x01,  0x47,  0xD2,  0x01,  0x0F,  0xFE,  0x11,  0x01,  0x10,  0x5F, 	/* 0E5B0 */
+	0x05,  0x10,  0x50,  0xA5,  0xEA,  0xF0,  0x60,  0x02,  0xA9,  0x04,  0x02,  0x40,  0x27,  0x82,  0x40,  0x24, 	/* 0E5C0 */
+	0x0F,  0xFE,  0x05,  0x02,  0x48,  0x4D,  0x48,  0x24,  0x0C,  0x07,  0x00,  0xAA,  0x00,  0x0F,  0xFE,  0x04, 	/* 0E5D0 */
+	0x00,  0xE0,  0x35,  0x8C,  0x46,  0x7F,  0xE0,  0x40,  0x27,  0xC2,  0x40,  0x24,  0x0F,  0xFE,  0xAF,  0x04, 	/* 0E5E0 */
+	0x02,  0x78,  0x24,  0x0F,  0xFE,  0x64,  0xC5,  0x54,  0x7F,  0xC4,  0xE4,  0x55,  0x46,  0x4C,  0x44,  0x47, 	/* 0E5F0 */
+	0xFC,  0xB3,  0x02,  0x01,  0x3C,  0x12,  0x0F,  0xFE,  0x01,  0x47,  0xFE,  0x5D,  0x04,  0x14,  0x7F,  0x45, 	/* 0E600 */
+	0xAA,  0x69,  0x68,  0xA2,  0xB4,  0x00,  0x07,  0xFE,  0x48,  0x87,  0xDE,  0x48,  0x85,  0xDC,  0x6A,  0xA4, 	/* 0E610 */
+	0xA8,  0x52,  0x09,  0x3C,  0x92,  0x07,  0xFE,  0xB8,  0x47,  0xCF,  0x04,  0x97,  0xEF,  0x04,  0xFF,  0xE8, 	/* 0E620 */
+	0x92,  0xFF,  0xC2,  0x54,  0xFD,  0x42,  0x5C,  0x35,  0x0C,  0x10,  0xB9,  0x00,  0x0F,  0xFE,  0x08,  0x00, 	/* 0E630 */
+	0xF8,  0x08,  0x81,  0x48,  0x23,  0x00,  0x10,  0x02,  0x00,  0x40,  0x18,  0x06,  0x00,  0xBB,  0x00,  0x0F, 	/* 0E640 */
+	0xFE,  0x22,  0x02,  0x24,  0x3A,  0x44,  0xA8,  0x4B,  0x0A,  0xA0,  0x12,  0x01,  0x22,  0x22,  0x24,  0x1E, 	/* 0E650 */
+	0xBF,  0x02,  0x0F,  0xBC,  0x22,  0x42,  0x44,  0x79,  0x85,  0x00,  0xDF,  0xCB,  0x44,  0x12,  0x82,  0x10, 	/* 0E660 */
+	0x46,  0x89,  0x86,  0x80,  0x00,  0xCF,  0xF0,  0x21,  0x02,  0x10,  0x79,  0x04,  0xFE,  0x69,  0x09,  0x10, 	/* 0E670 */
+	0x12,  0x82,  0x28,  0x44,  0x49,  0x82,  0x83,  0x01,  0x0F,  0x90,  0x27,  0xC2,  0x54,  0x75,  0x45,  0x54, 	/* 0E680 */
+	0x5F,  0xEB,  0x10,  0x22,  0x82,  0x28,  0x44,  0x49,  0x82,  0x84,  0x00,  0x8F,  0xC8,  0x21,  0x42,  0x22, 	/* 0E690 */
+	0x7C,  0x94,  0xB0,  0x6C,  0x49,  0x18,  0x16,  0x22,  0x04,  0x41,  0x88,  0x60,  0x86,  0x00,  0x8F,  0xC8, 	/* 0E6A0 */
+	0x21,  0x43,  0x92,  0x4A,  0x64,  0xFA,  0xA8,  0x01,  0x3E,  0x12,  0x22,  0x22,  0x42,  0x28,  0x3E,  0x89, 	/* 0E6B0 */
+	0x02,  0x0F,  0xA0,  0x43,  0xE7,  0x42,  0x57,  0xA5,  0xAA,  0x73,  0xA9,  0x2A,  0x22,  0xA2,  0x3A,  0x40, 	/* 0E6C0 */
+	0x28,  0x0C,  0x8A,  0x01,  0x0F,  0xD0,  0x25,  0x03,  0x7C,  0x59,  0x05,  0x10,  0xBF,  0xE1,  0x38,  0x25, 	/* 0E6D0 */
+	0x42,  0x92,  0x41,  0x08,  0x10,  0x8B,  0x01,  0x4F,  0xD2,  0x27,  0xC3,  0x90,  0x2F,  0xC4,  0x90,  0x6F, 	/* 0E6E0 */
+	0xE9,  0x0A,  0x10,  0xC2,  0x1A,  0x46,  0x68,  0x02,  0x8D,  0x00,  0xCF,  0xF8,  0x25,  0x42,  0x52,  0x78, 	/* 0E6F0 */
+	0x25,  0x7C,  0x50,  0x8B,  0x10,  0x2F,  0xE2,  0x10,  0x41,  0x08,  0x30,  0x95,  0x01,  0x0F,  0x90,  0x2F, 	/* 0E700 */
+	0xE2,  0x24,  0x7A,  0x84,  0xFE,  0x68,  0x09,  0x00,  0x17,  0xC2,  0x44,  0x44,  0x48,  0x7C,  0x96,  0x01, 	/* 0E710 */
+	0x0F,  0xFE,  0x21,  0x07,  0x3C,  0x5A,  0x45,  0xBC,  0x7A,  0x49,  0xBC,  0x2A,  0x42,  0xBC,  0x48,  0x08, 	/* 0E720 */
+	0xFE,  0x98,  0x01,  0x4F,  0x9E,  0x27,  0x42,  0x0A,  0x79,  0x64,  0xE4,  0x69,  0x69,  0xF8,  0x11,  0x42, 	/* 0E730 */
+	0x0A,  0x43,  0x68,  0xC2,  0x9E,  0x00,  0x0F,  0xBC,  0x22,  0x42,  0x7E,  0x74,  0x25,  0x7E,  0x54,  0x2B, 	/* 0E740 */
+	0x7E,  0x24,  0x22,  0x7E,  0x42,  0x48,  0x42,  0xA4,  0x04,  0x0F,  0xFE,  0x26,  0x42,  0xBC,  0x72,  0x45, 	/* 0E750 */
+	0xFE,  0x52,  0x0B,  0x7E,  0x2A,  0xA2,  0x4A,  0x49,  0x28,  0x0C,  0xAA,  0x01,  0x0F,  0xFE,  0x21,  0x02, 	/* 0E760 */
+	0xFE,  0x78,  0x25,  0x7C,  0x50,  0x0B,  0x7C,  0x24,  0x42,  0x7C,  0x42,  0x89,  0xFE,  0xAB,  0x0E,  0xEF, 	/* 0E770 */
+	0xAA,  0x4E,  0xE7,  0x00,  0x57,  0xC5,  0x54,  0xB7,  0xC1,  0x54,  0x27,  0xC2,  0x10,  0x4F,  0xE8,  0x10, 	/* 0E780 */
+	0xAF,  0x00,  0x0F,  0xFE,  0x4B,  0x27,  0x54,  0x53,  0x85,  0xFC,  0xB4,  0x41,  0x7C,  0x24,  0x42,  0x7C, 	/* 0E790 */
+	0x42,  0x48,  0xC2,  0xB1,  0x04,  0x8F,  0x4C,  0x4F,  0xA7,  0x4E,  0x5F,  0x85,  0xEA,  0xBB,  0xA1,  0xAA, 	/* 0E7A0 */
+	0x2B,  0x43,  0xA4,  0x4F,  0xA9,  0x91,  0xB2,  0x0A,  0x8F,  0xAC,  0x4D,  0xA7,  0x0E,  0x5F,  0x85,  0xAA, 	/* 0E7B0 */
+	0xBB,  0xA1,  0xAA,  0x2B,  0x43,  0xAC,  0x4F,  0xA9,  0x91,  0xB3,  0x00,  0x01,  0xF0,  0x11,  0x01,  0x10, 	/* 0E7C0 */
+	0x21,  0x2C,  0x0E,  0x3F,  0x01,  0x10,  0x0A,  0x00,  0x40,  0x1B,  0x0E,  0x0E,  0xB4,  0x03,  0x8F,  0xA8, 	/* 0E7D0 */
+	0x82,  0x8C,  0xAA,  0xAC,  0x69,  0x3C,  0x90,  0x4A,  0xA4,  0xC9,  0x88,  0x08,  0xFB,  0x40,  0xC2,  0xB5, 	/* 0E7E0 */
+	0x17,  0x86,  0x48,  0x44,  0x84,  0x4A,  0x78,  0x64,  0x7C,  0x70,  0x44,  0x28,  0x5A,  0x8E,  0x10,  0x42, 	/* 0E7F0 */
+	0x84,  0x46,  0xB7,  0x1B,  0x86,  0x28,  0x7A,  0x84,  0xAA,  0x7A,  0x64,  0xC0,  0x7B,  0xC4,  0x04,  0x79, 	/* 0E800 */
+	0x44,  0x88,  0x49,  0x4B,  0x62,  0xBA,  0x93,  0x85,  0x28,  0x22,  0x85,  0xAA,  0x84,  0x62,  0x00,  0xF7, 	/* 0E810 */
+	0xC2,  0x44,  0x72,  0x86,  0x90,  0xA2,  0x82,  0xC6,  0xBB,  0x23,  0x8F,  0xA8,  0x22,  0x87,  0xAA,  0x04, 	/* 0E820 */
+	0x6F,  0x80,  0x8B,  0xC7,  0x04,  0x52,  0x85,  0x90,  0x52,  0x88,  0xC4,  0xBC,  0x21,  0xCF,  0x94,  0x21, 	/* 0E830 */
+	0x4F,  0x95,  0x8A,  0x77,  0x40,  0x07,  0xE7,  0x12,  0x51,  0x45,  0x48,  0x59,  0x49,  0x62,  0xBF,  0x7D, 	/* 0E840 */
+	0xC4,  0x54,  0x45,  0x47,  0xD5,  0x52,  0x77,  0xE0,  0x55,  0xE5,  0x52,  0x7F,  0x49,  0x88,  0xA5,  0x44, 	/* 0E850 */
+	0x62,  0x80,  0x43,  0x89,  0xA8,  0x8A,  0x8D,  0xAA,  0x8C,  0x6F,  0x80,  0x27,  0xC2,  0x24,  0xF9,  0x42, 	/* 0E860 */
+	0x18,  0x3A,  0x4C,  0x42,  0x85,  0x23,  0x8F,  0xA8,  0x52,  0x85,  0x4A,  0xF8,  0x62,  0x7C,  0xE8,  0x43, 	/* 0E870 */
+	0x64,  0xD9,  0x83,  0x48,  0xD1,  0x43,  0x62,  0x86,  0x01,  0xCF,  0xD4,  0x81,  0x5B,  0x95,  0xAA,  0x3B, 	/* 0E880 */
+	0xC0,  0x83,  0xEE,  0xE2,  0xAB,  0x4E,  0xE8,  0x81,  0x4F,  0xE2,  0x8B,  0x00,  0x01,  0xFC,  0x12,  0x41, 	/* 0E890 */
+	0x24,  0x12,  0x4F,  0xFE,  0x24,  0x42,  0x44,  0x24,  0x47,  0xFE,  0x00,  0x40,  0x18,  0x8D,  0x00,  0x01, 	/* 0E8A0 */
+	0xFC,  0x14,  0x41,  0x24,  0x10,  0x4F,  0xFF,  0x24,  0x42,  0x24,  0x20,  0x47,  0xFE,  0x40,  0x80,  0x30, 	/* 0E8B0 */
+	0x8E,  0x20,  0x03,  0xFE,  0x40,  0x09,  0xF8,  0x14,  0x81,  0x48,  0xFF,  0xE2,  0x48,  0x24,  0x87,  0xFE, 	/* 0E8C0 */
+	0x40,  0x80,  0x30,  0x92,  0x04,  0x07,  0xFC,  0x04,  0x07,  0xFC,  0x04,  0x0F,  0xFE,  0x24,  0x8F,  0xFE, 	/* 0E8D0 */
+	0x48,  0x87,  0xF8,  0x00,  0x80,  0x30,  0x93,  0x40,  0x87,  0xFE,  0x80,  0x87,  0x94,  0x4F,  0xE6,  0x82, 	/* 0E8E0 */
+	0x7B,  0x4C,  0xB4,  0xAB,  0x4F,  0xB6,  0x15,  0x66,  0x82,  0x94,  0x42,  0x04,  0x20,  0x42,  0x04,  0x24, 	/* 0E8F0 */
+	0x7A,  0x44,  0x28,  0x43,  0x04,  0x20,  0x42,  0x05,  0xA2,  0x62,  0x2C,  0x1E,  0x98,  0x00,  0x07,  0xFC, 	/* 0E900 */
+	0x44,  0x47,  0xFC,  0x44,  0x47,  0xFC,  0x22,  0x03,  0xAC,  0x23,  0x02,  0x22,  0x3E,  0x2E,  0x1E,  0x9B, 	/* 0E910 */
+	0x01,  0x80,  0xE0,  0x78,  0x00,  0x80,  0x7F,  0xC0,  0x80,  0x08,  0x0F,  0xFE,  0x08,  0x00,  0x82,  0x08, 	/* 0E920 */
+	0x20,  0x7E,  0x9F,  0x04,  0x02,  0x48,  0x24,  0x44,  0xCA,  0x83,  0x20,  0xF8,  0x74,  0x00,  0x7C,  0x7C, 	/* 0E930 */
+	0x00,  0x7E,  0xFC,  0x10,  0x3F,  0xAB,  0x04,  0x0F,  0xFE,  0x3F,  0x82,  0x08,  0xFF,  0xE8,  0x3A,  0x9C, 	/* 0E940 */
+	0x27,  0xF8,  0x08,  0x0F,  0xFC,  0x08,  0x20,  0x7E,  0xAC,  0x09,  0x43,  0x12,  0xEF,  0xE2,  0x10,  0x3D, 	/* 0E950 */
+	0x2E,  0x5C,  0x23,  0x83,  0x54,  0xE9,  0x22,  0x30,  0x20,  0x11,  0xFF,  0xAF,  0x09,  0x23,  0x54,  0xE9, 	/* 0E960 */
+	0x82,  0x28,  0x3C,  0x4E,  0x10,  0x25,  0x23,  0x94,  0xE2,  0x82,  0xC4,  0x20,  0x11,  0xFF,  0xB3,  0x03, 	/* 0E970 */
+	0x03,  0xC0,  0x08,  0x07,  0xF8,  0x08,  0x40,  0x7C,  0x10,  0x83,  0x9E,  0xE7,  0x03,  0xDE,  0xE7,  0x21, 	/* 0E980 */
+	0xCE,  0x88,  0x10,  0xCF,  0xF0,  0x89,  0x0B,  0x96,  0xAF,  0x8F,  0x90,  0x49,  0x67,  0xF8,  0x49,  0x07, 	/* 0E990 */
+	0x90,  0x49,  0x2F,  0xCE,  0x8F,  0x01,  0x00,  0x60,  0x7C,  0x04,  0x40,  0x44,  0x04,  0x7C,  0x7C,  0x04, 	/* 0E9A0 */
+	0x20,  0x42,  0x04,  0x12,  0x58,  0xAE,  0x06,  0x91,  0x00,  0x03,  0xFC,  0x20,  0x42,  0x04,  0x3F,  0xC2, 	/* 0E9B0 */
+	0x20,  0x3F,  0xE2,  0x10,  0x21,  0x02,  0x0A,  0x38,  0x6E,  0x02,  0x93,  0x20,  0x02,  0x7E,  0xFC,  0x28, 	/* 0E9C0 */
+	0x42,  0x87,  0xE8,  0x48,  0x87,  0xF8,  0x48,  0x94,  0x47,  0x46,  0x07,  0x21,  0x82,  0x94,  0x20,  0x03, 	/* 0E9D0 */
+	0xF8,  0x20,  0x05,  0xF0,  0x80,  0x07,  0xF8,  0x00,  0x80,  0x08,  0x00,  0x80,  0x0A,  0x00,  0x60,  0x02, 	/* 0E9E0 */
+	0x97,  0x20,  0x03,  0xFC,  0x20,  0x05,  0xF0,  0x80,  0x07,  0xF8,  0x04,  0x83,  0x48,  0x08,  0x81,  0x4A, 	/* 0E9F0 */
+	0x20,  0x6C,  0x02,  0x9B,  0x20,  0x03,  0xFC,  0x20,  0x05,  0xF8,  0x80,  0x07,  0xF8,  0x24,  0x82,  0x28, 	/* 0EA00 */
+	0x7D,  0x89,  0x4A,  0x24,  0x64,  0xC2,  0xA3,  0x20,  0x03,  0xFC,  0x20,  0x05,  0xF8,  0x80,  0x07,  0xF8, 	/* 0EA10 */
+	0x49,  0x82,  0xA8,  0x7F,  0x81,  0xCA,  0x6A,  0x60,  0x82,  0xA4,  0x20,  0x03,  0xFC,  0x20,  0x05,  0xF0, 	/* 0EA20 */
+	0x80,  0x0F,  0xFC,  0x7F,  0x44,  0x94,  0x7F,  0x45,  0x56,  0x63,  0x67,  0xF2,  0xB4,  0x04,  0x00,  0x40, 	/* 0EA30 */
+	0x04,  0x40,  0x64,  0x7E,  0x80,  0xD0,  0x0D,  0x01,  0x48,  0x24,  0x44,  0x42,  0x04,  0x00,  0xC0,  0xB7, 	/* 0EA40 */
+	0x04,  0x04,  0x40,  0x24,  0x42,  0x64,  0x06,  0x8F,  0x50,  0x15,  0x01,  0x48,  0x24,  0x44,  0x42,  0x84, 	/* 0EA50 */
+	0x00,  0xC0,  0xB8,  0x0C,  0x00,  0x20,  0x00,  0x01,  0xC4,  0x06,  0x8F,  0xF0,  0x15,  0x01,  0x48,  0x24, 	/* 0EA60 */
+	0x4C,  0x42,  0x04,  0x00,  0xC0,  0xBE,  0x40,  0x02,  0xFC,  0x08,  0x48,  0x84,  0x48,  0x40,  0x84,  0x09, 	/* 0EA70 */
+	0x82,  0x80,  0x48,  0x04,  0x82,  0x88,  0x28,  0x7E,  0x80,  0x40,  0x02,  0xFE,  0x01,  0x08,  0x10,  0x41, 	/* 0EA80 */
+	0x00,  0x10,  0x01,  0x02,  0x10,  0x41,  0x04,  0x10,  0x81,  0x08,  0x30,  0x81,  0x41,  0x02,  0x10,  0x01, 	/* 0EA90 */
+	0x08,  0x10,  0x4F,  0xE0,  0x10,  0x01,  0x02,  0x10,  0x41,  0x04,  0x10,  0x81,  0x08,  0x10,  0x82,  0x04, 	/* 0EAA0 */
+	0x00,  0x50,  0x04,  0x8F,  0xFE,  0x04,  0x04,  0x64,  0x26,  0x80,  0xD0,  0x34,  0x8C,  0x44,  0x04,  0x20, 	/* 0EAB0 */
+	0xC0,  0x8E,  0x40,  0x02,  0x78,  0x04,  0x88,  0x48,  0x44,  0x80,  0x68,  0x05,  0x82,  0x48,  0x44,  0x84, 	/* 0EAC0 */
+	0x8A,  0x88,  0xA9,  0x06,  0x90,  0x42,  0x02,  0x20,  0x03,  0xE8,  0x22,  0x44,  0x20,  0x64,  0x09,  0x42, 	/* 0EAD0 */
+	0x08,  0x40,  0x84,  0x10,  0x86,  0x09,  0x80,  0x95,  0x41,  0x02,  0x10,  0x01,  0x08,  0x10,  0x41,  0x00, 	/* 0EAE0 */
+	0x92,  0x09,  0x22,  0x92,  0x49,  0x24,  0x92,  0x89,  0x28,  0xFE,  0x97,  0x40,  0x03,  0xFC,  0x02,  0x08, 	/* 0EAF0 */
+	0x20,  0x42,  0x03,  0xFE,  0x02,  0x02,  0x20,  0x42,  0x04,  0x20,  0x82,  0x08,  0x20,  0x9A,  0x40,  0x02, 	/* 0EB00 */
+	0xFC,  0x02,  0x08,  0x20,  0x5F,  0xE0,  0x40,  0x07,  0xC2,  0x84,  0x48,  0x44,  0x04,  0x80,  0x48,  0x18, 	/* 0EB10 */
+	0x9D,  0x44,  0x02,  0x40,  0x04,  0x0B,  0xFE,  0x44,  0x80,  0x88,  0x09,  0x02,  0xD0,  0x52,  0x04,  0x58, 	/* 0EB20 */
+	0x88,  0x4B,  0x02,  0x9E,  0x00,  0x07,  0xFC,  0x04,  0x00,  0x40,  0xFF,  0xE0,  0x44,  0x06,  0x4F,  0x68, 	/* 0EB30 */
+	0x15,  0x02,  0x48,  0xC4,  0x60,  0xC0,  0x9F,  0x40,  0x02,  0xFC,  0x01,  0x08,  0x10,  0x41,  0x00,  0x10, 	/* 0EB40 */
+	0x01,  0x02,  0x10,  0x41,  0x04,  0x10,  0x9F,  0xE8,  0x00,  0xA0,  0x41,  0x02,  0x50,  0x05,  0x08,  0x5C, 	/* 0EB50 */
+	0x47,  0x41,  0xD4,  0x05,  0x42,  0x54,  0x45,  0x84,  0x40,  0x84,  0x28,  0x3E,  0xA2,  0x42,  0x02,  0x20, 	/* 0EB60 */
+	0x02,  0x08,  0x20,  0x4F,  0xC0,  0x20,  0x02,  0x02,  0x20,  0x42,  0x04,  0x20,  0x82,  0x09,  0xFE,  0xA8, 	/* 0EB70 */
+	0x40,  0x02,  0x7E,  0x04,  0x28,  0x42,  0x44,  0x20,  0x42,  0x07,  0xE2,  0x42,  0x44,  0x24,  0x42,  0x84, 	/* 0EB80 */
+	0x28,  0x7E,  0xAA,  0x40,  0x03,  0xFE,  0x02,  0x08,  0x20,  0x42,  0x00,  0xFC,  0x02,  0x02,  0x20,  0x42, 	/* 0EB90 */
+	0x04,  0x20,  0x82,  0x09,  0xFE,  0xB0,  0x41,  0x02,  0x10,  0x01,  0x08,  0x10,  0x4F,  0xE0,  0x10,  0x03, 	/* 0EBA0 */
+	0x02,  0x30,  0x44,  0x84,  0x68,  0x89,  0x49,  0x02,  0xB2,  0x40,  0x03,  0xF8,  0x04,  0x88,  0x50,  0x45, 	/* 0EBB0 */
+	0xC0,  0x44,  0x0A,  0x42,  0xA8,  0x49,  0x04,  0x98,  0x92,  0x4A,  0xC2,  0xB3,  0x40,  0x02,  0xFE,  0x08, 	/* 0EBC0 */
+	0x08,  0x80,  0x4F,  0xC0,  0x84,  0x0C,  0x82,  0xA8,  0x49,  0x05,  0x18,  0x92,  0x4A,  0xC2,  0xBA,  0x42, 	/* 0EBD0 */
+	0x02,  0x20,  0x1F,  0xC8,  0x24,  0x42,  0x40,  0x24,  0x3F,  0xF2,  0x30,  0x45,  0x04,  0x48,  0x88,  0x4B, 	/* 0EBE0 */
+	0x02,  0xBD,  0x50,  0x03,  0xFC,  0x10,  0x0A,  0xF8,  0x40,  0x01,  0xF8,  0x00,  0x82,  0x08,  0x40,  0xA4, 	/* 0EBF0 */
+	0x0A,  0x80,  0x68,  0x02,  0xBE,  0x44,  0x82,  0x48,  0x04,  0x88,  0x84,  0x48,  0x43,  0x7E,  0x02,  0x52, 	/* 0EC00 */
+	0x24,  0x42,  0x44,  0x44,  0x84,  0x48,  0x98,  0x81,  0x42,  0x02,  0x10,  0x01,  0x08,  0x40,  0x44,  0x01, 	/* 0EC10 */
+	0x40,  0x14,  0x45,  0x42,  0x64,  0x24,  0x4A,  0x84,  0x88,  0x38,  0x82,  0x40,  0xC2,  0x70,  0x04,  0x08, 	/* 0EC20 */
+	0x40,  0x47,  0xE0,  0x48,  0x04,  0x82,  0x48,  0x44,  0x84,  0x88,  0x88,  0x89,  0x08,  0x83,  0x40,  0xC2, 	/* 0EC30 */
+	0xF0,  0x02,  0x08,  0x20,  0x42,  0x01,  0xFE,  0x02,  0x02,  0x30,  0x43,  0x04,  0x48,  0x88,  0x4B,  0x02, 	/* 0EC40 */
+	0x88,  0x42,  0x02,  0x20,  0x1F,  0xE9,  0x22,  0x52,  0x20,  0x30,  0x03,  0x02,  0x30,  0x45,  0x04,  0x52, 	/* 0EC50 */
+	0x89,  0x29,  0x0E,  0x8C,  0x82,  0x04,  0x26,  0x1F,  0x80,  0x20,  0x92,  0x45,  0x24,  0x12,  0x43,  0xFC, 	/* 0EC60 */
+	0x52,  0x04,  0x22,  0x82,  0x28,  0x1E,  0x8D,  0x40,  0x02,  0xFE,  0x02,  0x08,  0x20,  0x47,  0xC0,  0x44, 	/* 0EC70 */
+	0x08,  0x42,  0x88,  0x5F,  0x85,  0x08,  0x80,  0x8B,  0xFE,  0x90,  0x42,  0x02,  0x20,  0x02,  0x09,  0xFE, 	/* 0EC80 */
+	0x42,  0x02,  0x70,  0x07,  0x02,  0x68,  0x4A,  0x84,  0xA4,  0x92,  0x28,  0x20,  0x92,  0x42,  0x02,  0x3C, 	/* 0EC90 */
+	0x02,  0x48,  0x44,  0x49,  0x80,  0x00,  0x0F,  0xC2,  0x44,  0x42,  0x84,  0x10,  0x86,  0x89,  0x86,  0x93, 	/* 0ECA0 */
+	0x04,  0x00,  0x4C,  0xF7,  0x01,  0x60,  0x25,  0x8C,  0x46,  0x0C,  0x03,  0xF8,  0x20,  0x83,  0xF8,  0x20, 	/* 0ECB0 */
+	0x83,  0xF8,  0x96,  0x41,  0x02,  0x10,  0x0F,  0xE8,  0x92,  0x49,  0x20,  0x92,  0x0F,  0xE2,  0x10,  0x41, 	/* 0ECC0 */
+	0x04,  0x10,  0x81,  0x08,  0x10,  0x99,  0x41,  0x02,  0x10,  0x05,  0x48,  0x54,  0x45,  0x20,  0x92,  0x11, 	/* 0ECD0 */
+	0x60,  0x34,  0x20,  0x84,  0x10,  0x46,  0x09,  0x80,  0x9A,  0x41,  0x02,  0x10,  0x01,  0x08,  0x90,  0x49, 	/* 0ECE0 */
+	0xE0,  0x90,  0x09,  0x02,  0x90,  0x49,  0x04,  0x90,  0x89,  0x0B,  0xFE,  0x9B,  0x82,  0x04,  0x20,  0x3F, 	/* 0ECF0 */
+	0xE8,  0x20,  0x5F,  0xC1,  0x24,  0x12,  0x43,  0x24,  0x52,  0x45,  0x38,  0x82,  0x08,  0x20,  0xA1,  0x47, 	/* 0ED00 */
+	0x82,  0x48,  0x04,  0x88,  0x4A,  0x58,  0x60,  0xF8,  0x00,  0x82,  0x48,  0x43,  0x04,  0x30,  0x84,  0x89, 	/* 0ED10 */
+	0x86,  0xA2,  0x40,  0x02,  0x7E,  0x04,  0x28,  0x42,  0x47,  0xE0,  0x50,  0x05,  0x02,  0x48,  0x44,  0x84, 	/* 0ED20 */
+	0x84,  0x88,  0x49,  0x02,  0xAB,  0x42,  0x02,  0x20,  0x3F,  0xE8,  0x20,  0x42,  0x01,  0xFC,  0x06,  0x02, 	/* 0ED30 */
+	0x70,  0x4A,  0x85,  0x24,  0xA2,  0x28,  0x20,  0xAE,  0x40,  0x02,  0x7C,  0x04,  0x48,  0x44,  0x47,  0xC0, 	/* 0ED40 */
+	0x44,  0x04,  0x42,  0x7C,  0x44,  0x44,  0x44,  0x84,  0x49,  0xFE,  0xB1,  0x42,  0x02,  0x20,  0x1F,  0xE9, 	/* 0ED50 */
+	0x02,  0x50,  0x22,  0x40,  0x04,  0xC2,  0x70,  0x44,  0x04,  0x40,  0x84,  0x28,  0x3E,  0xB3,  0x40,  0x02, 	/* 0ED60 */
+	0xFE,  0x00,  0x48,  0x04,  0x4F,  0x40,  0x94,  0x09,  0x42,  0xF4,  0x40,  0x44,  0x04,  0x80,  0x48,  0x0C, 	/* 0ED70 */
+	0xB8,  0x45,  0x02,  0xFC,  0x05,  0x48,  0x54,  0x5F,  0xC1,  0x50,  0x1F,  0xE2,  0x52,  0x45,  0x24,  0x52, 	/* 0ED80 */
+	0x89,  0xC9,  0x10,  0xB9,  0x41,  0x02,  0x10,  0x01,  0x08,  0xFE,  0x49,  0x20,  0x92,  0x09,  0x22,  0xFE, 	/* 0ED90 */
+	0x49,  0x24,  0x92,  0x89,  0x28,  0xFE,  0xBA,  0x40,  0x02,  0xFE,  0x09,  0x28,  0x92,  0x49,  0x20,  0xFE, 	/* 0EDA0 */
+	0x09,  0x22,  0x92,  0x49,  0x24,  0x92,  0x89,  0x28,  0xFE,  0xBB,  0x42,  0x02,  0x20,  0x02,  0x88,  0x44, 	/* 0EDB0 */
+	0x49,  0xE1,  0xE2,  0x00,  0x02,  0xFC,  0x48,  0x44,  0x84,  0x88,  0x48,  0xFC,  0xBC,  0x40,  0x02,  0xFE, 	/* 0EDC0 */
+	0x01,  0x28,  0x12,  0x42,  0x20,  0x4C,  0x08,  0x02,  0x7E,  0x44,  0x24,  0x42,  0x84,  0x28,  0x7E,  0xBD, 	/* 0EDD0 */
+	0x42,  0x02,  0x20,  0x02,  0x09,  0xFE,  0x42,  0x00,  0x20,  0x02,  0x02,  0xFC,  0x48,  0x44,  0x84,  0x88, 	/* 0EDE0 */
+	0x48,  0xFC,  0xBE,  0x42,  0x02,  0x20,  0x02,  0x08,  0x3E,  0x42,  0x00,  0x20,  0x02,  0x02,  0xFC,  0x48, 	/* 0EDF0 */
+	0x44,  0x84,  0x88,  0x48,  0xFC,  0xBF,  0x45,  0x02,  0x50,  0x05,  0x00,  0x88,  0x88,  0x85,  0x04,  0x2F, 	/* 0EE00 */
+	0xA2,  0x88,  0x48,  0x84,  0x88,  0x88,  0x88,  0xF8,  0x81,  0x40,  0x02,  0xFC,  0x08,  0x48,  0x84,  0x48, 	/* 0EE10 */
+	0x40,  0xFC,  0x05,  0x02,  0x50,  0x45,  0x04,  0x92,  0x89,  0x29,  0x0E,  0x84,  0x45,  0x42,  0x54,  0x05, 	/* 0EE20 */
+	0x49,  0xFE,  0x45,  0x40,  0x54,  0x05,  0x42,  0x5C,  0x45,  0x04,  0x40,  0x87,  0xE8,  0x40,  0x85,  0x40, 	/* 0EE30 */
+	0x02,  0xFE,  0x09,  0x28,  0x92,  0x49,  0x22,  0x92,  0x09,  0xA2,  0xAA,  0x4A,  0x64,  0xC6,  0x88,  0x28, 	/* 0EE40 */
+	0xFE,  0x89,  0x08,  0x03,  0xF8,  0x20,  0x83,  0xF8,  0x20,  0x83,  0xF8,  0x04,  0x4F,  0xD8,  0x15,  0x02, 	/* 0EE50 */
+	0x48,  0xC4,  0x60,  0xC0,  0x8A,  0x41,  0x02,  0x10,  0x02,  0x08,  0xFC,  0x48,  0x40,  0x84,  0x08,  0x42, 	/* 0EE60 */
+	0xFC,  0x48,  0x44,  0x84,  0x88,  0x48,  0xFC,  0x8C,  0x42,  0x02,  0x10,  0x01,  0x48,  0x44,  0x44,  0x81, 	/* 0EE70 */
+	0x48,  0x15,  0x45,  0x62,  0x64,  0x24,  0xCA,  0xB4,  0x88,  0x38,  0x93,  0x80,  0x85,  0xC8,  0x04,  0x88, 	/* 0EE80 */
+	0x48,  0x5C,  0x81,  0x10,  0x1D,  0x03,  0x54,  0x45,  0x44,  0x52,  0x85,  0xE9,  0xB2,  0x95,  0x41,  0x02, 	/* 0EE90 */
+	0x10,  0x0F,  0xE8,  0x10,  0x41,  0x01,  0xFF,  0x01,  0x02,  0x28,  0x42,  0x44,  0x5C,  0x8E,  0x28,  0x02, 	/* 0EEA0 */
+	0x97,  0x40,  0x03,  0xFE,  0x15,  0x29,  0x52,  0x55,  0x21,  0x52,  0x15,  0x23,  0x9E,  0x50,  0x25,  0x02, 	/* 0EEB0 */
+	0x9F,  0xE8,  0x00,  0x99,  0x40,  0x02,  0xFE,  0x01,  0x08,  0x54,  0x45,  0x20,  0x90,  0x1F,  0xF2,  0x10, 	/* 0EEC0 */
+	0x41,  0x04,  0x10,  0x81,  0x08,  0x10,  0x9B,  0x40,  0xE2,  0xF0,  0x01,  0x08,  0x10,  0x4F,  0xE0,  0x04, 	/* 0EED0 */
+	0x00,  0x82,  0x10,  0x4A,  0x04,  0xC0,  0x8B,  0x09,  0x0F,  0x9D,  0x40,  0xC2,  0x70,  0x04,  0x08,  0x40, 	/* 0EEE0 */
+	0x47,  0xE0,  0x48,  0x06,  0x82,  0x58,  0x44,  0xC4,  0x8A,  0x88,  0x89,  0x08,  0xA1,  0x44,  0x02,  0x40, 	/* 0EEF0 */
+	0x07,  0xE8,  0x42,  0x4F,  0xA1,  0x0A,  0x07,  0xA2,  0x44,  0x44,  0x04,  0x42,  0x84,  0x28,  0x3E,  0xA2, 	/* 0EF00 */
+	0x41,  0x02,  0x10,  0x0F,  0xE8,  0x92,  0x49,  0x40,  0xFC,  0x08,  0x42,  0xC8,  0x4B,  0x05,  0x30,  0x94, 	/* 0EF10 */
+	0x8B,  0x86,  0xA3,  0x42,  0x02,  0x20,  0x02,  0x09,  0xFE,  0x40,  0x40,  0x84,  0x08,  0x42,  0x44,  0x44, 	/* 0EF20 */
+	0x84,  0x48,  0x84,  0x89,  0xFE,  0xA5,  0x40,  0x02,  0xFE,  0x08,  0x28,  0x82,  0x4F,  0xE0,  0xA0,  0x0A, 	/* 0EF30 */
+	0x62,  0xB8,  0x4A,  0x05,  0x22,  0x92,  0x2A,  0x1E,  0xA8,  0x42,  0x02,  0x10,  0x0F,  0xE8,  0x10,  0x41, 	/* 0EF40 */
+	0x00,  0x10,  0x07,  0xC2,  0x10,  0x41,  0x04,  0x10,  0x81,  0x08,  0xFE,  0xAA,  0x40,  0x02,  0xFE,  0x08, 	/* 0EF50 */
+	0x28,  0x82,  0x4F,  0xE0,  0x82,  0x08,  0x22,  0xFE,  0x48,  0x24,  0x82,  0x88,  0x28,  0xFE,  0xAF,  0x40, 	/* 0EF60 */
+	0x02,  0xFC,  0x08,  0x48,  0xFC,  0x49,  0x00,  0x90,  0x0F,  0xE2,  0x88,  0x48,  0x84,  0x86,  0x8B,  0x69, 	/* 0EF70 */
+	0xC2,  0xB0,  0x04,  0x07,  0xFC,  0x04,  0x03,  0xF8,  0x0A,  0x0F,  0xFE,  0x24,  0x85,  0x54,  0x8E,  0x31, 	/* 0EF80 */
+	0x50,  0x64,  0xC0,  0x40,  0xB1,  0x42,  0x02,  0x20,  0x0F,  0xC8,  0xA4,  0x4A,  0x42,  0xA4,  0x1F,  0xE2, 	/* 0EF90 */
+	0x20,  0x42,  0x04,  0x50,  0x88,  0x8B,  0x06,  0xB3,  0x43,  0x02,  0x08,  0x00,  0x08,  0x72,  0x41,  0xC1, 	/* 0EFA0 */
+	0xD8,  0x05,  0x82,  0x54,  0x49,  0x25,  0x11,  0x81,  0x08,  0x30,  0x8B,  0x48,  0x82,  0x48,  0x05,  0x09, 	/* 0EFB0 */
+	0xFE,  0x42,  0x00,  0xFC,  0x02,  0x02,  0x20,  0x5F,  0xE4,  0x20,  0x82,  0x08,  0x20,  0x8C,  0x40,  0x23, 	/* 0EFC0 */
+	0xEA,  0x08,  0xA8,  0x8A,  0x4E,  0xA3,  0x2A,  0x1A,  0xA2,  0x6A,  0x44,  0xA4,  0x42,  0x88,  0x29,  0x06, 	/* 0EFD0 */
+	0x92,  0x4F,  0xE2,  0x28,  0x02,  0x88,  0xFE,  0x4A,  0xA0,  0xAA,  0x0A,  0xA2,  0xCE,  0x48,  0x24,  0x82, 	/* 0EFE0 */
+	0x8F,  0xE8,  0x80,  0x97,  0x4A,  0x02,  0xA0,  0x0F,  0xC9,  0x20,  0x52,  0x03,  0xFE,  0x05,  0x02,  0x50, 	/* 0EFF0 */
+	0x49,  0x04,  0x92,  0x91,  0x2A,  0x0E,  0x99,  0x41,  0x02,  0x10,  0x09,  0x00,  0xFE,  0x89,  0x05,  0x10, 	/* 0F000 */
+	0x0F,  0xE2,  0x38,  0x45,  0x44,  0x92,  0x91,  0x18,  0x10,  0x9B,  0x42,  0x02,  0x3C,  0x04,  0x48,  0xC8, 	/* 0F010 */
+	0x53,  0x00,  0x28,  0x04,  0x42,  0xFE,  0x54,  0x54,  0x44,  0x84,  0x48,  0x7C,  0x9E,  0x40,  0x02,  0xFE, 	/* 0F020 */
+	0x08,  0x28,  0xBA,  0x48,  0x20,  0xBA,  0x0A,  0xA2,  0xAA,  0x2B,  0xA4,  0x82,  0x48,  0x28,  0x86,  0x9F, 	/* 0F030 */
+	0x42,  0x03,  0xFE,  0x02,  0x09,  0xFC,  0x42,  0x41,  0xFC,  0x12,  0x03,  0xFE,  0x42,  0x24,  0x56,  0x88, 	/* 0F040 */
+	0x8B,  0x06,  0xA5,  0x41,  0x02,  0xFE,  0x01,  0x29,  0xFF,  0x41,  0x20,  0xFE,  0x01,  0x02,  0xFE,  0x41, 	/* 0F050 */
+	0x05,  0xFF,  0x81,  0x08,  0x10,  0xA9,  0x42,  0x02,  0x20,  0x1F,  0xC9,  0x24,  0x5F,  0xC1,  0x24,  0x1F, 	/* 0F060 */
+	0xC2,  0x20,  0x42,  0x84,  0x10,  0x86,  0xA9,  0x86,  0xAA,  0x44,  0x82,  0x48,  0x04,  0x89,  0xFE,  0x44, 	/* 0F070 */
+	0x80,  0x48,  0x04,  0x83,  0xFE,  0x40,  0x04,  0x48,  0x88,  0x49,  0x02,  0xAB,  0x41,  0x02,  0x20,  0x0F, 	/* 0F080 */
+	0xE8,  0xAA,  0x4A,  0xA0,  0xAA,  0x0A,  0xA2,  0xAA,  0x4A,  0xA4,  0xAA,  0x9F,  0xF8,  0x00,  0xB2,  0x08, 	/* 0F090 */
+	0x24,  0x92,  0x29,  0x20,  0x92,  0xAD,  0xA5,  0xB6,  0x09,  0x22,  0x92,  0x49,  0x25,  0x12,  0x91,  0x2A, 	/* 0F0A0 */
+	0x02,  0xB3,  0x90,  0x05,  0x00,  0x15,  0xEB,  0xF2,  0x55,  0x21,  0x52,  0x15,  0x23,  0x52,  0x35,  0x24, 	/* 0F0B0 */
+	0x92,  0x55,  0xEA,  0x00,  0xB5,  0x44,  0x02,  0x40,  0x07,  0xE8,  0x82,  0x57,  0xA0,  0x4A,  0x07,  0xA2, 	/* 0F0C0 */
+	0x4A,  0x44,  0xA4,  0x7A,  0x80,  0x28,  0x0C,  0xB6,  0x44,  0x02,  0x40,  0x0F,  0xE8,  0x82,  0x50,  0xA0, 	/* 0F0D0 */
+	0xDA,  0x0A,  0xA2,  0xDA,  0x48,  0xA4,  0xFA,  0x88,  0x28,  0x0C,  0xB8,  0x82,  0x05,  0x24,  0x0A,  0x48, 	/* 0F0E0 */
+	0xA8,  0x42,  0x03,  0xFE,  0x05,  0x02,  0x50,  0x45,  0x04,  0x52,  0x89,  0x29,  0x0E,  0xBB,  0x40,  0xC2, 	/* 0F0F0 */
+	0xF0,  0x02,  0x08,  0x20,  0x5F,  0xE0,  0x20,  0x02,  0x02,  0xFC,  0x48,  0x44,  0x84,  0x88,  0x48,  0xFC, 	/* 0F100 */
+	0xBD,  0x42,  0x02,  0x20,  0x05,  0x08,  0x88,  0x50,  0x42,  0xFA,  0x00,  0x02,  0x00,  0x4F,  0xC4,  0x84, 	/* 0F110 */
+	0x88,  0x48,  0xFC,  0xBE,  0x40,  0xC2,  0xF0,  0x08,  0x48,  0xB8,  0x4A,  0x20,  0xBC,  0x0B,  0x02,  0xB0, 	/* 0F120 */
+	0x4A,  0x85,  0x24,  0x92,  0x2A,  0x20,  0x81,  0x42,  0x03,  0xFC,  0x02,  0x08,  0x48,  0x5F,  0x40,  0x04, 	/* 0F130 */
+	0x0A,  0x82,  0xA8,  0x4A,  0x84,  0xAA,  0x92,  0xAA,  0x06,  0x84,  0x44,  0x02,  0x78,  0x19,  0x00,  0xFC, 	/* 0F140 */
+	0x82,  0x45,  0xFE,  0x02,  0x42,  0xFC,  0x42,  0x04,  0x20,  0x82,  0x08,  0x60,  0x85,  0x42,  0x82,  0x3C, 	/* 0F150 */
+	0x1E,  0x08,  0x3C,  0x4E,  0x00,  0x2E,  0x1F,  0x42,  0x18,  0x21,  0x04,  0x6A,  0x58,  0x68,  0x02,  0x99, 	/* 0F160 */
+	0x88,  0x64,  0x98,  0x09,  0x0B,  0xD0,  0x49,  0xE2,  0x94,  0x0D,  0x43,  0x94,  0x49,  0x44,  0x94,  0x8A, 	/* 0F170 */
+	0x49,  0xC4,  0x9A,  0x42,  0x02,  0x48,  0x1F,  0xC8,  0x52,  0x45,  0x01,  0x8E,  0x04,  0x02,  0x7C,  0x58, 	/* 0F180 */
+	0x84,  0x70,  0x8D,  0x8B,  0x06,  0x9C,  0x41,  0x82,  0xE0,  0x08,  0x08,  0xFC,  0x49,  0x00,  0x90,  0x09, 	/* 0F190 */
+	0x03,  0xFE,  0x40,  0x04,  0x88,  0x88,  0x49,  0x04,  0xA3,  0x41,  0x03,  0xFE,  0x10,  0x29,  0xFA,  0x40, 	/* 0F1A0 */
+	0x00,  0x00,  0x1F,  0xE2,  0x50,  0x45,  0x04,  0x92,  0x89,  0x29,  0x0E,  0xA4,  0x42,  0x03,  0xFE,  0x12, 	/* 0F1B0 */
+	0x29,  0x20,  0x5F,  0xE0,  0x40,  0x05,  0x02,  0x90,  0x4A,  0x45,  0x24,  0x84,  0xE8,  0xF2,  0xA6,  0x41, 	/* 0F1C0 */
+	0x22,  0x11,  0x0F,  0xE8,  0x10,  0x4F,  0xE0,  0x92,  0x0F,  0xE2,  0x92,  0x4F,  0xE4,  0x92,  0x89,  0x28, 	/* 0F1D0 */
+	0x96,  0xA9,  0x41,  0x02,  0x90,  0x0F,  0xC8,  0x90,  0x51,  0x01,  0xFE,  0x00,  0x02,  0xFC,  0x48,  0x44, 	/* 0F1E0 */
+	0x84,  0x88,  0x48,  0xFC,  0xAA,  0x42,  0x02,  0x20,  0x0F,  0xC8,  0x84,  0x4F,  0xC0,  0x84,  0x0F,  0xC2, 	/* 0F1F0 */
+	0xA2,  0x49,  0x44,  0x88,  0x8E,  0x49,  0x82,  0xAC,  0x40,  0x03,  0xFC,  0x12,  0x49,  0xFC,  0x52,  0x41, 	/* 0F200 */
+	0x24,  0x1F,  0xC2,  0x20,  0x5F,  0xC4,  0x20,  0x82,  0x0B,  0xFE,  0xAE,  0x40,  0xC2,  0xF0,  0x12,  0x48, 	/* 0F210 */
+	0xA4,  0x48,  0x81,  0xFC,  0x01,  0x82,  0x20,  0x5F,  0xE4,  0x20,  0x82,  0x08,  0x60,  0xB4,  0x48,  0x82, 	/* 0F220 */
+	0xA8,  0x12,  0x48,  0x50,  0x45,  0x00,  0x88,  0x10,  0x42,  0xFA,  0x48,  0x84,  0x88,  0x88,  0x88,  0xF8, 	/* 0F230 */
+	0xB7,  0x44,  0x02,  0x7E,  0x04,  0x08,  0xFC,  0x55,  0x40,  0x54,  0x07,  0xE2,  0x94,  0x49,  0x44,  0xFE, 	/* 0F240 */
+	0x80,  0x48,  0x18,  0xB8,  0x4F,  0xC2,  0x04,  0x0F,  0xC8,  0x04,  0x5F,  0xF1,  0x01,  0x1F,  0xD2,  0x44, 	/* 0F250 */
+	0x42,  0x84,  0x10,  0x86,  0x89,  0x86,  0xB9,  0x42,  0x02,  0x20,  0x1F,  0xC8,  0x20,  0x4A,  0x80,  0xA8, 	/* 0F260 */
+	0x17,  0x42,  0x22,  0x45,  0x04,  0x48,  0x88,  0x49,  0x02,  0x85,  0x4F,  0xC2,  0x84,  0x0F,  0xC8,  0x84, 	/* 0F270 */
+	0x48,  0x40,  0xFC,  0x02,  0x02,  0x20,  0x5F,  0xC4,  0x20,  0x82,  0x0B,  0xFE,  0x88,  0x42,  0x03,  0x24, 	/* 0F280 */
+	0x0A,  0x48,  0xA8,  0x4F,  0xC0,  0x84,  0x0F,  0xC2,  0x84,  0x4F,  0xC4,  0x84,  0x88,  0x48,  0x8C,  0x8C, 	/* 0F290 */
+	0x40,  0x02,  0xFE,  0x02,  0xC8,  0x10,  0x4F,  0xE0,  0x92,  0x0F,  0xE2,  0x92,  0x4F,  0xE4,  0x92,  0x89, 	/* 0F2A0 */
+	0x28,  0x96,  0x8E,  0x80,  0x65,  0xDC,  0x04,  0x40,  0x84,  0x91,  0x45,  0xD6,  0x05,  0x41,  0x54,  0x4D, 	/* 0F2B0 */
+	0x44,  0xDE,  0x93,  0x0A,  0x0F,  0x93,  0x4F,  0xE2,  0x82,  0x0F,  0xE8,  0x00,  0x4F,  0xE0,  0x82,  0x0F, 	/* 0F2C0 */
+	0xE2,  0x82,  0x4F,  0xE4,  0x82,  0x88,  0x28,  0x86,  0x95,  0x48,  0x82,  0x50,  0x1F,  0xC8,  0x24,  0x4F, 	/* 0F2D0 */
+	0xC1,  0x20,  0x1F,  0xE2,  0x22,  0x46,  0x24,  0xA2,  0x92,  0xC8,  0x20,  0x99,  0x40,  0x03,  0xFE,  0x00, 	/* 0F2E0 */
+	0x01,  0xFC,  0x90,  0x45,  0xFC,  0x11,  0x03,  0xFE,  0x51,  0x05,  0x28,  0xA4,  0x49,  0x82,  0x9B,  0x42, 	/* 0F2F0 */
+	0x02,  0xFE,  0x02,  0x08,  0xFC,  0x42,  0x01,  0xFE,  0x04,  0x83,  0xFE,  0x48,  0x85,  0x48,  0xA0,  0x88, 	/* 0F300 */
+	0x18,  0x9C,  0x41,  0x02,  0xFE,  0x01,  0x08,  0x7C,  0x40,  0x00,  0xFE,  0x08,  0x22,  0xAA,  0x42,  0x84, 	/* 0F310 */
+	0x2A,  0x84,  0xA9,  0x86,  0xAF,  0x40,  0x03,  0xFE,  0x11,  0x09,  0x7C,  0x51,  0x01,  0xFE,  0x11,  0x03, 	/* 0F320 */
+	0x10,  0x57,  0xC5,  0x10,  0x91,  0x0A,  0xFE,  0xB2,  0x41,  0x02,  0xFE,  0x05,  0x08,  0x5E,  0x49,  0x20, 	/* 0F330 */
+	0x9A,  0x1A,  0x46,  0xB4,  0x4C,  0x84,  0x94,  0x8A,  0x28,  0xC2,  0xB5,  0x40,  0x03,  0xFE,  0x02,  0x09, 	/* 0F340 */
+	0x32,  0x55,  0x61,  0xDA,  0x13,  0x23,  0x5A,  0x59,  0x65,  0x62,  0x90,  0x29,  0xFE,  0xB8,  0x80,  0x05, 	/* 0F350 */
+	0xFE,  0x12,  0x29,  0xFE,  0x52,  0x21,  0x22,  0x17,  0xA3,  0x4A,  0x54,  0xA5,  0x7A,  0x90,  0x29,  0xFE, 	/* 0F360 */
+	0xBC,  0x82,  0x05,  0xFE,  0x00,  0x00,  0xFC,  0x88,  0x44,  0x84,  0x0F,  0xC2,  0x20,  0x4A,  0x84,  0xA4, 	/* 0F370 */
+	0x92,  0x48,  0x60,  0x80,  0x42,  0x03,  0xFE,  0x10,  0x29,  0x02,  0x5F,  0xC0,  0x20,  0x0A,  0x02,  0xBC, 	/* 0F380 */
+	0x4A,  0x04,  0xA0,  0x96,  0x0A,  0x1E,  0x85,  0x48,  0x22,  0x9C,  0x09,  0x0B,  0xF0,  0x49,  0xE0,  0xD4, 	/* 0F390 */
+	0x1B,  0x45,  0x94,  0x69,  0x44,  0xA4,  0x8C,  0x48,  0x84,  0x86,  0x4C,  0xC2,  0x30,  0x0C,  0x8B,  0xFE, 	/* 0F3A0 */
+	0x44,  0x00,  0xFC,  0x18,  0x45,  0xFC,  0x68,  0x44,  0xFC,  0x88,  0x48,  0x8C,  0x87,  0x48,  0x82,  0x88, 	/* 0F3B0 */
+	0x1F,  0xC8,  0x88,  0x4F,  0x80,  0x88,  0x0F,  0x82,  0x88,  0x5F,  0xE4,  0x08,  0x8C,  0x49,  0x04,  0x8B, 	/* 0F3C0 */
+	0x88,  0x84,  0x88,  0x3F,  0xE8,  0x88,  0x5D,  0xC1,  0xDC,  0x1B,  0xA6,  0xAA,  0x6A,  0x84,  0x88,  0x88, 	/* 0F3D0 */
+	0x88,  0x88,  0x8C,  0x42,  0x02,  0xA8,  0x0A,  0x49,  0x22,  0x5F,  0xE1,  0x02,  0x17,  0xA3,  0x4A,  0x54, 	/* 0F3E0 */
+	0xA5,  0x7A,  0x90,  0x29,  0x06,  0x91,  0x48,  0x02,  0x80,  0x0F,  0xE8,  0x92,  0x49,  0x43,  0xF4,  0x08, 	/* 0F3F0 */
+	0xC5,  0xC8,  0x5A,  0x8A,  0x94,  0xAA,  0x48,  0xC2,  0x92,  0x82,  0x05,  0xFE,  0x02,  0x00,  0xFC,  0x82, 	/* 0F400 */
+	0x45,  0xFE,  0x02,  0x43,  0xFE,  0x44,  0x84,  0xC8,  0x87,  0x09,  0x8E,  0x95,  0x42,  0x02,  0xFC,  0x02, 	/* 0F410 */
+	0x0B,  0xFE,  0x44,  0x80,  0x48,  0x18,  0xE2,  0x20,  0x5F,  0xC4,  0x20,  0x82,  0x09,  0xFE,  0x98,  0x48, 	/* 0F420 */
+	0x02,  0x80,  0x0F,  0xE9,  0x42,  0x67,  0xA0,  0xA2,  0x1F,  0xA2,  0x22,  0x4A,  0xA4,  0xAA,  0x8F,  0xA8, 	/* 0F430 */
+	0x0C,  0x99,  0x42,  0x03,  0xFE,  0x10,  0x29,  0xFA,  0x40,  0x00,  0x00,  0x1F,  0xE2,  0x20,  0x4A,  0x84, 	/* 0F440 */
+	0xA4,  0x92,  0x48,  0x60,  0x9E,  0x44,  0x42,  0x54,  0x05,  0x49,  0xF2,  0x45,  0x20,  0xE9,  0x0E,  0x82, 	/* 0F450 */
+	0xC8,  0x54,  0xC5,  0x52,  0x85,  0xE8,  0x72,  0xA1,  0x42,  0x42,  0xA8,  0x0A,  0x09,  0x30,  0x44,  0x81, 	/* 0F460 */
+	0x86,  0x02,  0x42,  0xA8,  0x4A,  0x05,  0x30,  0x84,  0x89,  0x86,  0xA4,  0x48,  0x42,  0x84,  0x3F,  0x40, 	/* 0F470 */
+	0x8A,  0x88,  0xA4,  0xF1,  0x0A,  0x42,  0xA2,  0x52,  0x85,  0x24,  0xA2,  0x28,  0xC2,  0xA6,  0x42,  0x02, 	/* 0F480 */
+	0x20,  0x05,  0x08,  0x88,  0x5F,  0xC2,  0x22,  0x02,  0x03,  0xFC,  0x42,  0x04,  0xA4,  0x86,  0x8B,  0xFE, 	/* 0F490 */
+	0xA8,  0x81,  0xC5,  0xE8,  0x0A,  0x41,  0x12,  0x9F,  0xC4,  0x24,  0x3F,  0xE0,  0x24,  0x5F,  0xC4,  0x20, 	/* 0F4A0 */
+	0x82,  0x08,  0x60,  0xAA,  0x41,  0x02,  0x10,  0x02,  0x88,  0x44,  0x4F,  0xE1,  0x01,  0x0F,  0xE2,  0xAA, 	/* 0F4B0 */
+	0x4F,  0xE4,  0xAA,  0x8A,  0xA8,  0x86,  0xAB,  0x40,  0xE2,  0xF0,  0x12,  0x48,  0xA4,  0x48,  0x82,  0xFE, 	/* 0F4C0 */
+	0x02,  0x02,  0x20,  0x4F,  0xC4,  0x20,  0x82,  0x09,  0xFE,  0xAC,  0x41,  0x02,  0xFE,  0x04,  0x48,  0x44, 	/* 0F4D0 */
+	0x4A,  0xA1,  0x11,  0x01,  0x02,  0xFE,  0x41,  0x04,  0x10,  0x81,  0x08,  0x10,  0xAE,  0x44,  0x82,  0x50, 	/* 0F4E0 */
+	0x0F,  0xE9,  0x90,  0x69,  0x00,  0xFC,  0x09,  0x02,  0x90,  0x4F,  0xC4,  0x90,  0x89,  0x08,  0xFE,  0xB1, 	/* 0F4F0 */
+	0x40,  0x03,  0xFE,  0x15,  0x29,  0x52,  0x49,  0x01,  0x2E,  0x02,  0x02,  0xFE,  0x46,  0x84,  0xA4,  0x92, 	/* 0F500 */
+	0x28,  0x20,  0xB3,  0x41,  0x03,  0xFE,  0x0F,  0xC8,  0x84,  0x4F,  0xC0,  0x00,  0x0F,  0xC2,  0x08,  0x5F, 	/* 0F510 */
+	0xE4,  0x10,  0x81,  0x08,  0x30,  0xB5,  0x4A,  0xA2,  0xAA,  0x0A,  0xA8,  0xEE,  0x48,  0x20,  0xFE,  0x08, 	/* 0F520 */
+	0x22,  0xEE,  0x4A,  0xA5,  0x2A,  0x92,  0xAA,  0x02,  0xB7,  0x40,  0x02,  0xFC,  0x08,  0x48,  0xFC,  0x48, 	/* 0F530 */
+	0x40,  0xFC,  0x09,  0x02,  0xF2,  0x49,  0xC4,  0x90,  0x8F,  0x29,  0x8E,  0xB9,  0x42,  0x02,  0x20,  0x1F, 	/* 0F540 */
+	0xE8,  0xA8,  0x52,  0x42,  0xFA,  0x0A,  0x82,  0xF8,  0x4A,  0x84,  0xF8,  0x82,  0x28,  0x1E,  0xBA,  0x42, 	/* 0F550 */
+	0x83,  0xFE,  0x02,  0x88,  0x10,  0x46,  0xA1,  0x86,  0x02,  0x43,  0xFE,  0x42,  0x84,  0x10,  0x86,  0xA9, 	/* 0F560 */
+	0x86,  0xBB,  0x40,  0xC2,  0xF0,  0x02,  0x09,  0xFE,  0x43,  0x00,  0x48,  0x0A,  0x43,  0x22,  0x4B,  0x44, 	/* 0F570 */
+	0xAA,  0x92,  0xA8,  0x60,  0x85,  0x42,  0x03,  0xFC,  0x02,  0x08,  0xF8,  0x42,  0x03,  0xFE,  0x08,  0x82, 	/* 0F580 */
+	0xF8,  0x48,  0x84,  0xF8,  0x88,  0x88,  0x98,  0x87,  0x4F,  0xC2,  0x84,  0x0F,  0xC8,  0x84,  0x4F,  0xC0, 	/* 0F590 */
+	0x40,  0x0F,  0xE3,  0x4A,  0x47,  0x24,  0x4A,  0x83,  0xA8,  0x0C,  0x88,  0x42,  0x03,  0xFE,  0x08,  0x88, 	/* 0F5A0 */
+	0x70,  0x4D,  0x83,  0x8E,  0x0F,  0x82,  0x88,  0x4F,  0x84,  0x88,  0x90,  0x8A,  0x08,  0x89,  0x42,  0x02, 	/* 0F5B0 */
+	0xA0,  0x0B,  0xC8,  0xA0,  0x5F,  0xE0,  0x28,  0x0A,  0x42,  0xAA,  0x56,  0xA4,  0x10,  0x86,  0x09,  0x80, 	/* 0F5C0 */
+	0x8A,  0x49,  0x22,  0x92,  0x0D,  0x68,  0xBA,  0x49,  0x20,  0xFE,  0x09,  0x22,  0xBA,  0x4B,  0xA4,  0xD6, 	/* 0F5D0 */
+	0x95,  0x29,  0x12,  0x8B,  0x41,  0x02,  0x50,  0x05,  0xC8,  0x50,  0x45,  0x01,  0xFE,  0x00,  0x02,  0x86, 	/* 0F5E0 */
+	0x46,  0x84,  0x00,  0x86,  0xC9,  0x82,  0x93,  0x43,  0xC3,  0xC4,  0x12,  0x48,  0xA8,  0x4A,  0x80,  0xFC, 	/* 0F5F0 */
+	0x02,  0x03,  0xFE,  0x42,  0x04,  0x30,  0x84,  0x89,  0x86,  0x95,  0x52,  0x22,  0xAA,  0x04,  0xA9,  0xFA, 	/* 0F600 */
+	0x44,  0xA0,  0x4A,  0x1F,  0xA2,  0x4A,  0x46,  0xA4,  0x92,  0x90,  0x2A,  0x06,  0x99,  0x43,  0xC2,  0x44, 	/* 0F610 */
+	0x08,  0x88,  0xFE,  0x4A,  0xA0,  0xAA,  0x0C,  0xE2,  0x92,  0x5F,  0xF4,  0x28,  0x84,  0x48,  0x83,  0x9A, 	/* 0F620 */
+	0x41,  0x02,  0xFE,  0x01,  0x28,  0x14,  0x5F,  0xF0,  0x30,  0x07,  0xC2,  0xC4,  0x57,  0xC4,  0x44,  0x84, 	/* 0F630 */
+	0x48,  0x7C,  0x9B,  0x40,  0xC2,  0x0A,  0x1F,  0xE1,  0x08,  0x9E,  0xA5,  0x0A,  0x1E,  0xC3,  0xA8,  0x5A, 	/* 0F640 */
+	0xC5,  0xF5,  0x92,  0x3A,  0x41,  0x9D,  0x43,  0x02,  0x10,  0x02,  0x88,  0x7C,  0x48,  0x21,  0xEB,  0x0A, 	/* 0F650 */
+	0xA2,  0xEA,  0x4B,  0x44,  0xEA,  0x8A,  0xA8,  0xAA,  0x9F,  0x41,  0x03,  0xFE,  0x00,  0x08,  0xFC,  0x48, 	/* 0F660 */
+	0x41,  0xFE,  0x10,  0x22,  0xFC,  0x41,  0x04,  0x10,  0x81,  0x08,  0x30,  0xA0,  0x4F,  0xE2,  0x80,  0x8F, 	/* 0F670 */
+	0xC4,  0x84,  0x0F,  0xC2,  0x80,  0x4F,  0xE8,  0x40,  0xFF,  0xE0,  0xE0,  0x35,  0x8C,  0x46,  0xA1,  0x41, 	/* 0F680 */
+	0x03,  0xFE,  0x14,  0x89,  0xFE,  0x54,  0x81,  0x78,  0x10,  0x03,  0xFC,  0x54,  0x85,  0x30,  0xA5,  0x8D, 	/* 0F690 */
+	0x86,  0xA3,  0x82,  0x04,  0x20,  0x3F,  0xE0,  0x70,  0x8A,  0x85,  0xFC,  0x28,  0xA2,  0xF8,  0x48,  0x84, 	/* 0F6A0 */
+	0xF8,  0x88,  0x8B,  0xFE,  0xA4,  0x88,  0x87,  0xF8,  0x08,  0x83,  0xFE,  0xA2,  0xA5,  0xCA,  0x04,  0xA2, 	/* 0F6B0 */
+	0x8A,  0x7E,  0xA4,  0x92,  0x89,  0x29,  0xAC,  0xA5,  0x80,  0x05,  0xFC,  0x10,  0x49,  0xFC,  0x50,  0x01, 	/* 0F6C0 */
+	0xFE,  0x12,  0xC3,  0x7A,  0x51,  0x05,  0x7C,  0x91,  0x0A,  0xFE,  0xA6,  0x40,  0x02,  0xFC,  0x08,  0x48, 	/* 0F6D0 */
+	0xBC,  0x4A,  0x41,  0xFE,  0x10,  0x23,  0x7A,  0x54,  0xA5,  0x7A,  0x90,  0x29,  0x06,  0xA9,  0x40,  0x02, 	/* 0F6E0 */
+	0xF8,  0x08,  0x88,  0xF8,  0x48,  0x80,  0xF8,  0x00,  0x03,  0xFC,  0x55,  0x45,  0x54,  0x95,  0x4B,  0xFE, 	/* 0F6F0 */
+	0xAB,  0x4A,  0x82,  0xA8,  0x3F,  0xE8,  0xA8,  0x4B,  0x80,  0x80,  0x0F,  0xC2,  0x20,  0x7F,  0xE4,  0xF8, 	/* 0F700 */
+	0xB2,  0x68,  0x20,  0xAC,  0x80,  0x25,  0xEA,  0x12,  0xA9,  0x2A,  0x5E,  0xA1,  0x2A,  0x1E,  0xA3,  0x2A, 	/* 0F710 */
+	0x5E,  0xA4,  0xC2,  0x92,  0x2A,  0x06,  0xAD,  0x4F,  0xE2,  0x92,  0x0F,  0xE8,  0x92,  0x49,  0x20,  0xFE, 	/* 0F720 */
+	0x04,  0x42,  0x7C,  0x44,  0x44,  0x7C,  0x84,  0x48,  0x4C,  0xAE,  0x44,  0x83,  0xFE,  0x04,  0x88,  0x00, 	/* 0F730 */
+	0x5F,  0xE0,  0x04,  0x0F,  0x42,  0x94,  0x49,  0x44,  0xF4,  0x80,  0x48,  0x0C,  0xAF,  0x89,  0x04,  0x90, 	/* 0F740 */
+	0x1F,  0xC8,  0x90,  0x7F,  0xE0,  0x50,  0x08,  0x85,  0xF6,  0x61,  0x08,  0xF0,  0x88,  0x48,  0x7C,  0xB8, 	/* 0F750 */
+	0x48,  0x82,  0x88,  0x3F,  0xE0,  0x90,  0x8B,  0xE4,  0xE4,  0x0A,  0x82,  0xBE,  0x4A,  0x85,  0x28,  0x92, 	/* 0F760 */
+	0x8A,  0xD8,  0xBA,  0x40,  0x83,  0xC8,  0x14,  0xC9,  0x5A,  0x5D,  0xA1,  0x69,  0x1C,  0x93,  0x5A,  0x54, 	/* 0F770 */
+	0x45,  0xC8,  0x83,  0x08,  0xC0,  0xBE,  0x80,  0x07,  0xFE,  0x22,  0x21,  0xFC,  0x82,  0x05,  0xFC,  0x12, 	/* 0F780 */
+	0x45,  0xFC,  0x42,  0x07,  0xFE,  0x82,  0x08,  0x20,  0x83,  0x87,  0xE7,  0x88,  0x08,  0x80,  0xBE,  0xBC, 	/* 0F790 */
+	0x84,  0xBE,  0x0C,  0x83,  0x88,  0x4B,  0xE4,  0x88,  0x90,  0x8A,  0x08,  0x8A,  0x41,  0x02,  0xFE,  0x01, 	/* 0F7A0 */
+	0x08,  0xFE,  0x42,  0x81,  0xFF,  0x04,  0x42,  0xFE,  0x51,  0x14,  0xFE,  0x82,  0x88,  0xC6,  0x8D,  0x41, 	/* 0F7B0 */
+	0x02,  0x92,  0x09,  0x28,  0xFE,  0x40,  0x00,  0xFE,  0x06,  0x02,  0xFE,  0x4A,  0xA4,  0xAA,  0x8A,  0xA8, 	/* 0F7C0 */
+	0x86,  0x8E,  0x40,  0x03,  0xFE,  0x02,  0x08,  0x40,  0x5F,  0xE1,  0x4A,  0x17,  0xA3,  0x4A,  0x57,  0xA5, 	/* 0F7D0 */
+	0x4A,  0x94,  0xA9,  0xFE,  0x96,  0x88,  0x04,  0x9E,  0x09,  0x23,  0xF2,  0x89,  0xE4,  0x92,  0x1F,  0x23, 	/* 0F7E0 */
+	0x3E,  0x53,  0x25,  0xF2,  0x82,  0x28,  0x46,  0x98,  0x48,  0x02,  0x9E,  0x09,  0x2B,  0xF2,  0x49,  0xE0, 	/* 0F7F0 */
+	0x92,  0x1D,  0x25,  0xBE,  0x69,  0x2A,  0x92,  0x89,  0x28,  0x9E,  0x9B,  0x48,  0x83,  0xFC,  0x08,  0x88, 	/* 0F800 */
+	0xF8,  0x48,  0x80,  0xF8,  0x08,  0x83,  0xFE,  0x55,  0x05,  0x8C,  0x90,  0x08,  0xFE,  0x9F,  0x44,  0x02, 	/* 0F810 */
+	0xFC,  0x08,  0x48,  0xFC,  0x48,  0x40,  0xFC,  0x00,  0x03,  0xFE,  0x42,  0x04,  0xFC,  0x82,  0x0B,  0xFE, 	/* 0F820 */
+	0xA7,  0x4F,  0xC2,  0x28,  0x0F,  0xC8,  0xA4,  0x4F,  0xC0,  0xA4,  0x0F,  0xC2,  0x10,  0x5F,  0xE4,  0x22, 	/* 0F830 */
+	0x84,  0x29,  0x8C,  0xAB,  0x84,  0x87,  0x88,  0x08,  0xA0,  0x9A,  0xBF,  0xA4,  0xAC,  0x1C,  0x81,  0xA8, 	/* 0F840 */
+	0x68,  0xC4,  0x94,  0x8A,  0x28,  0xC1,  0xAE,  0x40,  0x03,  0xFF,  0x02,  0x88,  0xFE,  0x4A,  0xA0,  0xAA, 	/* 0F850 */
+	0x0F,  0xE2,  0x10,  0x4F,  0xE4,  0x10,  0x81,  0x09,  0xFF,  0xAF,  0x40,  0x02,  0x7C,  0x04,  0x48,  0x7C, 	/* 0F860 */
+	0x44,  0x41,  0xFF,  0x04,  0x02,  0xFE,  0x52,  0xA4,  0xD2,  0x82,  0x28,  0xCC,  0xB2,  0x41,  0xC2,  0xE8, 	/* 0F870 */
+	0x0A,  0x49,  0x12,  0x5F,  0xA0,  0x40,  0x1F,  0xE2,  0x40,  0x4F,  0xC4,  0xA4,  0x91,  0x8A,  0x66,  0xB6, 	/* 0F880 */
+	0x41,  0x02,  0xFC,  0x08,  0x48,  0xFC,  0x48,  0x40,  0xFC,  0x01,  0x22,  0xFC,  0x43,  0x84,  0x54,  0x99, 	/* 0F890 */
+	0x28,  0x30,  0xBE,  0x82,  0x07,  0xFE,  0x15,  0x41,  0x52,  0xA5,  0x24,  0xFC,  0x00,  0x42,  0xFC,  0x48, 	/* 0F8A0 */
+	0x05,  0xFE,  0x90,  0x28,  0x1C,  0xBF,  0x40,  0x02,  0xFE,  0x08,  0x28,  0xFE,  0x48,  0x20,  0xFE,  0x02, 	/* 0F8B0 */
+	0x82,  0x2A,  0x4A,  0xA4,  0x6C,  0x82,  0x89,  0xFF,  0x80,  0x89,  0x05,  0xFC,  0x09,  0x03,  0xFE,  0x82, 	/* 0F8C0 */
+	0x07,  0xFE,  0x22,  0x22,  0xAA,  0x6A,  0xA6,  0xFA,  0xA8,  0x2A,  0x06,  0x82,  0x88,  0x27,  0xFA,  0x08, 	/* 0F8D0 */
+	0xA3,  0xEA,  0xAA,  0xA6,  0xAA,  0x3E,  0xA0,  0x8A,  0x5C,  0xA5,  0xA2,  0xA8,  0x28,  0x86,  0x8C,  0x4E, 	/* 0F8E0 */
+	0x82,  0x30,  0x0D,  0x48,  0x48,  0x4F,  0xC1,  0x4A,  0x24,  0x81,  0xFE,  0x44,  0x84,  0x48,  0x88,  0xAB, 	/* 0F8F0 */
+	0x06,  0x8F,  0x41,  0x03,  0xFE,  0x11,  0x01,  0x7E,  0x91,  0x25,  0xFF,  0x11,  0x23,  0x7E,  0x51,  0x05, 	/* 0F900 */
+	0x7E,  0x94,  0x2A,  0x7E,  0x90,  0x40,  0x03,  0xFE,  0x11,  0x09,  0x7C,  0x54,  0x41,  0x7C,  0x14,  0x43, 	/* 0F910 */
+	0x7C,  0x51,  0x45,  0x52,  0xA9,  0x2C,  0x30,  0x96,  0x44,  0x82,  0x50,  0x8F,  0xE5,  0x90,  0x0F,  0xC2, 	/* 0F920 */
+	0x90,  0x4F,  0xE8,  0x40,  0xFF,  0xE0,  0x40,  0x04,  0x00,  0x40,  0x98,  0x42,  0x02,  0xF8,  0x02,  0x09, 	/* 0F930 */
+	0xFE,  0x45,  0x00,  0x88,  0x1F,  0xC2,  0x04,  0x5F,  0xC5,  0x54,  0x95,  0x4B,  0xFE,  0x9C,  0x84,  0x05, 	/* 0F940 */
+	0x9E,  0x14,  0xA9,  0x2A,  0x56,  0xA1,  0xB6,  0x00,  0x03,  0xFC,  0x52,  0x45,  0xFC,  0x92,  0x49,  0xFC, 	/* 0F950 */
+	0x9D,  0x45,  0x02,  0xFC,  0x05,  0x08,  0xFC,  0x45,  0x01,  0xFE,  0x0A,  0x42,  0xFC,  0x4A,  0x45,  0xFE, 	/* 0F960 */
+	0x88,  0x48,  0x8C,  0x9F,  0x40,  0x03,  0xFE,  0x10,  0x28,  0xFC,  0x48,  0x40,  0xFC,  0x08,  0x42,  0xFC, 	/* 0F970 */
+	0x42,  0x05,  0xFE,  0x88,  0x89,  0x04,  0xA2,  0x48,  0x82,  0x48,  0x05,  0x0B,  0xFE,  0x48,  0x80,  0x88, 	/* 0F980 */
+	0x10,  0x43,  0xFE,  0x55,  0x45,  0x54,  0x95,  0x4B,  0xFE,  0xA5,  0x42,  0x83,  0xFE,  0x12,  0x41,  0xFC, 	/* 0F990 */
+	0x92,  0x45,  0xFC,  0x12,  0x40,  0x08,  0x7F,  0xE4,  0x88,  0x84,  0x88,  0x18,  0xAA,  0x40,  0xC2,  0xF4, 	/* 0F9A0 */
+	0x09,  0x29,  0x22,  0x42,  0x80,  0xD0,  0x02,  0x42,  0xFA,  0x41,  0x04,  0xFE,  0x84,  0x89,  0x86,  0xAF, 	/* 0F9B0 */
+	0x91,  0x04,  0x9E,  0x06,  0xA1,  0xFA,  0x84,  0xE5,  0x5A,  0x15,  0xA1,  0xFE,  0x54,  0xA4,  0x4A,  0x89, 	/* 0F9C0 */
+	0x29,  0x26,  0xB2,  0x46,  0x03,  0xAC,  0x12,  0x49,  0xAC,  0x52,  0x41,  0xAC,  0x02,  0x03,  0xFE,  0x48, 	/* 0F9D0 */
+	0x84,  0x50,  0x87,  0x0B,  0x8E,  0xB6,  0x42,  0x03,  0xFE,  0x10,  0x29,  0xAA,  0x4A,  0x41,  0x54,  0x08, 	/* 0F9E0 */
+	0x83,  0x04,  0x4F,  0xA4,  0x88,  0x88,  0x88,  0xF8,  0xB7,  0x40,  0x03,  0xFE,  0x10,  0x29,  0xFE,  0x52, 	/* 0F9F0 */
+	0x21,  0xD6,  0x13,  0xA3,  0xD2,  0x53,  0xA5,  0xD6,  0x92,  0x29,  0xFE,  0xBA,  0x80,  0x05,  0xDE,  0x04, 	/* 0FA00 */
+	0x21,  0xCE,  0x91,  0x05,  0xDE,  0x04,  0x23,  0x5A,  0x4C,  0x65,  0x5A,  0x84,  0x29,  0x8C,  0xBD,  0x5F, 	/* 0FA10 */
+	0xE3,  0x00,  0x1F,  0xE9,  0x52,  0x54,  0xC1,  0x74,  0x2C,  0x20,  0x08,  0x5F,  0xE4,  0x88,  0x84,  0x88, 	/* 0FA20 */
+	0x18,  0x82,  0x42,  0x03,  0xFE,  0x08,  0x88,  0x50,  0x7F,  0xE2,  0x22,  0x1F,  0xC2,  0x20,  0x43,  0xC4, 	/* 0FA30 */
+	0x44,  0x88,  0x4B,  0x18,  0x84,  0x41,  0x02,  0x28,  0x04,  0x48,  0xBA,  0x58,  0x50,  0xFC,  0x08,  0x42, 	/* 0FA40 */
+	0xFC,  0x48,  0x05,  0x7E,  0xA4,  0x28,  0x7E,  0x85,  0x40,  0xA2,  0x09,  0x1F,  0xF1,  0x08,  0x9F,  0xA5, 	/* 0FA50 */
+	0x2A,  0x1B,  0xA3,  0x6C,  0x52,  0x45,  0x5D,  0x99,  0x3A,  0x21,  0x89,  0x4F,  0xC2,  0x84,  0x0F,  0xC8, 	/* 0FA60 */
+	0x84,  0x4F,  0xC1,  0x24,  0x0A,  0x83,  0xFE,  0x45,  0x04,  0x52,  0x89,  0x2B,  0x0E,  0x8B,  0x48,  0x42, 	/* 0FA70 */
+	0x48,  0x1F,  0xE8,  0x88,  0x4A,  0xA1,  0x32,  0x35,  0x40,  0xCC,  0x48,  0x85,  0x54,  0xBF,  0xE8,  0x22, 	/* 0FA80 */
+	0x8C,  0x49,  0x02,  0x9E,  0x0A,  0x49,  0x58,  0x51,  0x43,  0x62,  0x14,  0x95,  0x7E,  0x54,  0x89,  0x5C, 	/* 0FA90 */
+	0x92,  0xA9,  0x08,  0x91,  0x47,  0xC2,  0x44,  0x05,  0xC8,  0x54,  0x5F,  0xF1,  0x45,  0x17,  0xD2,  0x44, 	/* 0FAA0 */
+	0x47,  0xC4,  0x44,  0x84,  0x48,  0x4C,  0x93,  0x82,  0x07,  0xFE,  0x20,  0x20,  0x20,  0x9F,  0xC4,  0x88, 	/* 0FAB0 */
+	0x05,  0x03,  0xFE,  0x42,  0x05,  0xFC,  0x82,  0x08,  0x20,  0x94,  0x41,  0xE2,  0xE4,  0x09,  0x29,  0x12, 	/* 0FAC0 */
+	0x40,  0x00,  0x20,  0x0C,  0xC2,  0x84,  0x4E,  0xC4,  0x84,  0x88,  0x48,  0xFC,  0x95,  0x01,  0x07,  0x54, 	/* 0FAD0 */
+	0x5F,  0xE5,  0x10,  0x7F,  0xE5,  0x28,  0x55,  0x47,  0x92,  0x55,  0x55,  0x78,  0x59,  0x6B,  0x10,  0x9D, 	/* 0FAE0 */
+	0x42,  0x02,  0x20,  0x1F,  0xC8,  0x88,  0x45,  0x03,  0xFE,  0x12,  0x81,  0xF8,  0x52,  0x85,  0xFA,  0x82, 	/* 0FAF0 */
+	0x28,  0x1E,  0x9E,  0x4A,  0x83,  0xFE,  0x0A,  0x88,  0xF8,  0x40,  0x01,  0xFE,  0x12,  0x23,  0xFE,  0x4A, 	/* 0FB00 */
+	0x44,  0xA4,  0x8B,  0x88,  0x20,  0xAC,  0x40,  0x02,  0xFE,  0x00,  0x01,  0xFE,  0x90,  0x25,  0xFE,  0x17, 	/* 0FB10 */
+	0xE3,  0x52,  0x57,  0xE5,  0x40,  0x94,  0x2A,  0x3E,  0xAF,  0x95,  0x45,  0x54,  0x3F,  0xE1,  0x54,  0xA7, 	/* 0FB20 */
+	0x64,  0x00,  0x1F,  0xE3,  0x22,  0x5F,  0xE4,  0xA4,  0x8A,  0xC8,  0x20,  0xB2,  0x42,  0x02,  0x48,  0x0F, 	/* 0FB30 */
+	0x48,  0x44,  0x4A,  0xA1,  0xFF,  0x04,  0xC2,  0xB3,  0x5D,  0x84,  0x66,  0x81,  0x88,  0xE0,  0xB4,  0x41, 	/* 0FB40 */
+	0x02,  0xFE,  0x04,  0x48,  0x28,  0x4F,  0xE0,  0x92,  0x0F,  0xE2,  0x92,  0x4B,  0xA4,  0xAA,  0x8B,  0xA8, 	/* 0FB50 */
+	0x86,  0xB7,  0x42,  0x02,  0x3E,  0x02,  0x01,  0xFE,  0x92,  0x25,  0x8A,  0x15,  0x23,  0xA6,  0x55,  0x25, 	/* 0FB60 */
+	0x8A,  0x92,  0x29,  0xFE,  0xB8,  0x99,  0x04,  0x10,  0x3F,  0xE0,  0x28,  0xBA,  0x84,  0x08,  0x3B,  0xE4, 	/* 0FB70 */
+	0x08,  0x7C,  0x8A,  0x48,  0xA4,  0x8B,  0xC8,  0xBE,  0x82,  0x07,  0xFE,  0x08,  0x81,  0x04,  0xBF,  0xA5, 	/* 0FB80 */
+	0x08,  0x1F,  0x80,  0x52,  0x49,  0x47,  0x88,  0x8B,  0x49,  0xC2,  0xBF,  0x44,  0x82,  0x48,  0x1F,  0xE8, 	/* 0FB90 */
+	0x48,  0x5F,  0xF0,  0x20,  0x1F,  0xE3,  0x22,  0x57,  0xA5,  0x6A,  0x9B,  0x69,  0x22,  0x81,  0x42,  0x02, 	/* 0FBA0 */
+	0x3C,  0x04,  0x89,  0x90,  0x4F,  0xE0,  0x92,  0x0F,  0xE2,  0x92,  0x4F,  0xE4,  0x00,  0x8A,  0xA9,  0x25, 	/* 0FBB0 */
+	0x82,  0x5F,  0xE2,  0x28,  0x0F,  0xE8,  0xAA,  0x4F,  0xE0,  0x00,  0x0F,  0xC2,  0x00,  0x5F,  0xE4,  0x54, 	/* 0FBC0 */
+	0x89,  0x28,  0x30,  0x86,  0x42,  0x03,  0xFE,  0x07,  0x09,  0xAE,  0x42,  0x00,  0x48,  0x1A,  0x62,  0x2C, 	/* 0FBD0 */
+	0x5F,  0x04,  0xA8,  0x92,  0x68,  0x60,  0x89,  0x41,  0x03,  0xFE,  0x12,  0x81,  0xFE,  0x92,  0xA5,  0xFE, 	/* 0FBE0 */
+	0x14,  0x83,  0x4A,  0x57,  0xC5,  0x48,  0xA7,  0x98,  0xC7,  0x8F,  0x9F,  0xC5,  0x04,  0x1F,  0xC9,  0x00, 	/* 0FBF0 */
+	0x5F,  0xE1,  0x10,  0x1F,  0xE3,  0x92,  0x5D,  0xA5,  0xB6,  0xAD,  0xA8,  0xB6,  0x91,  0x88,  0x04,  0x9E, 	/* 0FC00 */
+	0x3D,  0x42,  0x54,  0xBD,  0x46,  0x7E,  0x3C,  0x42,  0x0C,  0x7C,  0xC6,  0x14,  0xBD,  0x4A,  0x26,  0x93, 	/* 0FC10 */
+	0x42,  0x03,  0xFE,  0x15,  0x41,  0x24,  0x95,  0x45,  0xFC,  0x02,  0x01,  0xFE,  0x52,  0x25,  0x52,  0x9E, 	/* 0FC20 */
+	0xA9,  0x06,  0x94,  0x82,  0x07,  0xFE,  0x20,  0x21,  0xFC,  0x82,  0x05,  0xFC,  0x12,  0x43,  0xFC,  0x52, 	/* 0FC30 */
+	0x45,  0xFC,  0x88,  0x4B,  0x02,  0x95,  0x44,  0x83,  0xFE,  0x04,  0x89,  0xFE,  0x54,  0xA1,  0xFE,  0x14, 	/* 0FC40 */
+	0xA1,  0xFE,  0x48,  0x44,  0xFC,  0x88,  0x48,  0xFC,  0xA0,  0x44,  0x83,  0xFE,  0x04,  0x88,  0xFC,  0x48, 	/* 0FC50 */
+	0x40,  0xFC,  0x08,  0x42,  0xFC,  0x42,  0x05,  0xFE,  0x8D,  0x8B,  0x06,  0xA2,  0x89,  0x07,  0xFE,  0x09, 	/* 0FC60 */
+	0x01,  0xFC,  0x92,  0x45,  0xFC,  0x02,  0x03,  0xFC,  0x42,  0x05,  0xFC,  0x85,  0x8B,  0x86,  0xA3,  0x41, 	/* 0FC70 */
+	0x02,  0xFE,  0x01,  0x0A,  0x7C,  0x55,  0x40,  0x7C,  0x35,  0x41,  0x7C,  0x51,  0x05,  0x7E,  0xA9,  0x0A, 	/* 0FC80 */
+	0x7F,  0xAB,  0x4F,  0xC2,  0x84,  0x0F,  0xC8,  0x84,  0x5F,  0xE1,  0x4A,  0x1F,  0xE2,  0x00,  0x4F,  0xC4, 	/* 0FC90 */
+	0x48,  0x83,  0x09,  0xCE,  0xAC,  0x42,  0x02,  0xFC,  0x02,  0x08,  0xFC,  0x42,  0x03,  0xFE,  0x08,  0x82, 	/* 0FCA0 */
+	0xF8,  0x48,  0x84,  0xF8,  0x84,  0x89,  0x84,  0xB1,  0x88,  0x47,  0xE4,  0x08,  0x73,  0xED,  0xAB,  0x66, 	/* 0FCB0 */
+	0xA4,  0x3E,  0x40,  0xC4,  0x5A,  0xC5,  0x8A,  0xA9,  0x28,  0xA1,  0xB2,  0xBB,  0xC4,  0xA0,  0x0B,  0xC3, 	/* 0FCC0 */
+	0xA0,  0xA3,  0xC6,  0x20,  0x3F,  0xE0,  0xA2,  0x4B,  0x44,  0xA8,  0x8B,  0x4B,  0x62,  0xB8,  0x08,  0x2B, 	/* 0FCD0 */
+	0xE4,  0x49,  0x83,  0xF0,  0xAB,  0xE7,  0xF4,  0x2B,  0x43,  0xF4,  0x49,  0x47,  0xF4,  0x8A,  0x48,  0xC4, 	/* 0FCE0 */
+	0xBE,  0x44,  0x42,  0xFE,  0x01,  0x08,  0xFC,  0x41,  0x01,  0xFE,  0x03,  0x02,  0x12,  0x5F,  0xA4,  0x54, 	/* 0FCF0 */
+	0x99,  0x38,  0x30,  0xBF,  0x50,  0xC7,  0x72,  0x12,  0xCF,  0x70,  0x5F,  0xE5,  0x48,  0x91,  0x80,  0x4C, 	/* 0FD00 */
+	0xFF,  0x03,  0x58,  0xC4,  0x60,  0xC0,  0x81,  0x80,  0x08,  0xFF,  0xF1,  0x08,  0x3E,  0x7A,  0x22,  0x3E, 	/* 0FD10 */
+	0x2A,  0x2F,  0x3E,  0x32,  0x26,  0xBE,  0xA5,  0x22,  0x21,  0x85,  0x48,  0x02,  0xFC,  0x12,  0x0A,  0xFE, 	/* 0FD20 */
+	0x45,  0x00,  0xFE,  0x19,  0x02,  0xFC,  0x49,  0x04,  0xFC,  0x89,  0x08,  0xFE,  0x94,  0x49,  0xE3,  0xEA, 	/* 0FD30 */
+	0x08,  0xA3,  0xCA,  0x8F,  0x27,  0x24,  0x1D,  0x02,  0x64,  0x5F,  0xA4,  0xA8,  0xB2,  0x48,  0x20,  0x98, 	/* 0FD40 */
+	0x41,  0xC3,  0xE4,  0x0A,  0x89,  0xFE,  0x47,  0x00,  0xA8,  0x32,  0x63,  0xFC,  0x52,  0x45,  0xFC,  0x92, 	/* 0FD50 */
+	0x49,  0xFC,  0x9B,  0x44,  0x43,  0xDE,  0x15,  0x49,  0xFE,  0x4C,  0xC1,  0x54,  0x26,  0x60,  0xFC,  0x48, 	/* 0FD60 */
+	0x44,  0xFC,  0x88,  0x48,  0xFC,  0x9C,  0x88,  0x85,  0xDE,  0x08,  0x81,  0xDE,  0x8C,  0x85,  0x34,  0x20, 	/* 0FD70 */
+	0x20,  0xFC,  0x48,  0x44,  0xFC,  0x88,  0x48,  0xFC,  0x9F,  0x42,  0x02,  0xCC,  0x08,  0x40,  0xEC,  0x88, 	/* 0FD80 */
+	0x44,  0xFC,  0x04,  0x02,  0x7E,  0x48,  0x25,  0x52,  0x84,  0xA8,  0x0C,  0xA4,  0x5D,  0xE3,  0x52,  0x1D, 	/* 0FD90 */
+	0xE1,  0x52,  0x9D,  0xE5,  0x02,  0x17,  0xA1,  0x22,  0x57,  0xA5,  0x22,  0x97,  0xA9,  0x06,  0xA6,  0x82, 	/* 0FDA0 */
+	0x07,  0xFE,  0x25,  0x20,  0xF8,  0x98,  0xC6,  0xFA,  0x08,  0x80,  0xF8,  0x4A,  0x84,  0xA4,  0x92,  0x48, 	/* 0FDB0 */
+	0x60,  0xAD,  0x80,  0x07,  0xFE,  0x05,  0x03,  0xFE,  0xA5,  0x27,  0xFE,  0x1F,  0xC3,  0x04,  0x5F,  0xC4, 	/* 0FDC0 */
+	0x20,  0xBF,  0xE8,  0x20,  0xAE,  0x88,  0x07,  0xEE,  0x08,  0xAB,  0xEA,  0x62,  0xE3,  0xEA,  0x22,  0xA3, 	/* 0FDD0 */
+	0xEE,  0x48,  0xA7,  0xEA,  0x89,  0x28,  0xA6,  0xAF,  0x4F,  0x82,  0x08,  0x1F,  0xE8,  0x08,  0x5F,  0xC0, 	/* 0FDE0 */
+	0x94,  0x1D,  0xC2,  0x08,  0x5F,  0xE4,  0x88,  0x84,  0x88,  0x18,  0xB0,  0x42,  0x02,  0xFC,  0x0A,  0x4B, 	/* 0FDF0 */
+	0xFF,  0x40,  0x00,  0xFC,  0x08,  0x42,  0xFC,  0x48,  0x44,  0xFC,  0x84,  0xC9,  0x82,  0xB4,  0xA4,  0x85, 	/* 0FE00 */
+	0x48,  0x0B,  0xE1,  0x8A,  0xAF,  0xF4,  0xD4,  0x1B,  0xE2,  0xD2,  0x49,  0xE4,  0x92,  0x89,  0x2B,  0x1E, 	/* 0FE10 */
+	0xB8,  0x48,  0x83,  0xFE,  0x08,  0x82,  0xAA,  0xAA,  0xA4,  0xFC,  0x08,  0x42,  0xFC,  0x48,  0x44,  0xFC, 	/* 0FE20 */
+	0x88,  0x49,  0x0C,  0xBA,  0x40,  0x02,  0xFE,  0x08,  0x28,  0xFE,  0x49,  0xC0,  0xFE,  0x09,  0x02,  0xEE, 	/* 0FE30 */
+	0x54,  0x45,  0xEE,  0xA4,  0x48,  0xCC,  0xBC,  0x42,  0x02,  0xFC,  0x04,  0x8B,  0xFE,  0x4A,  0x40,  0xFC, 	/* 0FE40 */
+	0x0A,  0x42,  0xFC,  0x42,  0x05,  0xFC,  0x82,  0x0B,  0xFE,  0x80,  0x40,  0x03,  0xFE,  0x2B,  0xA9,  0xAA, 	/* 0FE50 */
+	0x53,  0x22,  0x66,  0x04,  0x42,  0x66,  0x55,  0x45,  0x54,  0x97,  0x49,  0xDE,  0x81,  0x42,  0x02,  0xA0, 	/* 0FE60 */
+	0x0B,  0xC8,  0xA0,  0x5F,  0xE0,  0x44,  0x14,  0x43,  0x76,  0x55,  0x45,  0x54,  0x9D,  0x4B,  0x3E,  0x82, 	/* 0FE70 */
+	0x88,  0x06,  0xA8,  0x2A,  0x83,  0xEF,  0x81,  0x27,  0xEA,  0x08,  0xA3,  0xE4,  0x48,  0x44,  0xEC,  0xB1, 	/* 0FE80 */
+	0x28,  0x61,  0x84,  0x47,  0x02,  0x16,  0x0E,  0x88,  0x2B,  0x47,  0x40,  0x82,  0x17,  0xD2,  0x44,  0x47, 	/* 0FE90 */
+	0xC4,  0x44,  0x82,  0x89,  0xFE,  0x86,  0x47,  0xC2,  0x10,  0x1F,  0xE8,  0x44,  0x4E,  0xE0,  0x44,  0x1F, 	/* 0FEA0 */
+	0xF2,  0x00,  0x4F,  0xE4,  0x28,  0x84,  0xA9,  0x86,  0x8E,  0x44,  0x43,  0xF4,  0x04,  0x89,  0xF2,  0x40, 	/* 0FEB0 */
+	0x21,  0xE4,  0x12,  0x83,  0xE2,  0x49,  0x24,  0xA4,  0x86,  0x89,  0x90,  0x91,  0xBF,  0xE4,  0x50,  0x1D, 	/* 0FEC0 */
+	0xC1,  0x54,  0x95,  0x45,  0xDC,  0x05,  0x03,  0xFC,  0x52,  0x45,  0xFC,  0x92,  0x49,  0xFC,  0x97,  0x5D, 	/* 0FED0 */
+	0xE3,  0x52,  0x1D,  0xE9,  0x52,  0x5D,  0xE1,  0x02,  0x17,  0xA3,  0x4A,  0x57,  0xA5,  0x4A,  0x97,  0xA9, 	/* 0FEE0 */
+	0x06,  0xA1,  0x47,  0xC2,  0x44,  0x07,  0xC8,  0xEE,  0x4A,  0xA0,  0xEE,  0x01,  0x02,  0xFE,  0x43,  0x84, 	/* 0FEF0 */
+	0x54,  0x89,  0x38,  0x10,  0xA3,  0x88,  0x87,  0xE8,  0x09,  0x43,  0xD4,  0xA6,  0x27,  0xDD,  0x24,  0x83, 	/* 0FF00 */
+	0xC8,  0x4B,  0xE7,  0xC8,  0x88,  0x88,  0x88,  0xA4,  0x9F,  0xC5,  0x54,  0x1F,  0xC0,  0xF8,  0x82,  0x07, 	/* 0FF10 */
+	0xFE,  0x08,  0x83,  0xFE,  0x42,  0x05,  0xFC,  0x82,  0x08,  0x20,  0xAA,  0x9F,  0xC4,  0x20,  0x3F,  0xE2, 	/* 0FF20 */
+	0x22,  0xBB,  0xA4,  0x30,  0x0C,  0xC3,  0x33,  0x4F,  0xE4,  0x22,  0x82,  0xC8,  0x20,  0xB1,  0x5E,  0xE3, 	/* 0FF30 */
+	0x2A,  0x12,  0xA9,  0xEA,  0x55,  0x31,  0xF0,  0x15,  0xE3,  0x4A,  0x5F,  0xA5,  0x44,  0x96,  0xAA,  0xB1, 	/* 0FF40 */
+	0xB3,  0x42,  0x02,  0xFE,  0x08,  0xA8,  0xF6,  0x4D,  0x20,  0xFE,  0x0B,  0xA2,  0xD6,  0x41,  0x05,  0xFF, 	/* 0FF50 */
+	0x86,  0xC9,  0x83,  0xB9,  0x47,  0x82,  0x90,  0x1F,  0xE9,  0x28,  0x5C,  0xE1,  0x38,  0x10,  0x03,  0xFE, 	/* 0FF60 */
+	0x50,  0x05,  0x7C,  0x94,  0x4A,  0x7C,  0x80,  0x49,  0x03,  0xD0,  0x15,  0xE9,  0xD4,  0x56,  0x41,  0xE4, 	/* 0FF70 */
+	0x09,  0x43,  0xE8,  0x48,  0x84,  0xD4,  0x96,  0x4A,  0xC2,  0x81,  0x9F,  0xE5,  0x52,  0x1F,  0xE0,  0x80, 	/* 0FF80 */
+	0x8F,  0xE5,  0x22,  0x0F,  0xA2,  0xAA,  0x4F,  0xA4,  0x2A,  0x87,  0xA9,  0x8C,  0x82,  0x42,  0x03,  0xFE, 	/* 0FF90 */
+	0x15,  0x09,  0xFC,  0x55,  0x41,  0xFE,  0x15,  0x43,  0xFC,  0x55,  0x05,  0x58,  0xAD,  0x4B,  0x50,  0x83, 	/* 0FFA0 */
+	0x85,  0x05,  0xFC,  0x15,  0x41,  0xFC,  0x95,  0x45,  0xFE,  0x10,  0x01,  0xFE,  0x55,  0x05,  0x56,  0x94, 	/* 0FFB0 */
+	0x8A,  0xE6,  0x86,  0x42,  0x03,  0xFC,  0x0A,  0x8B,  0xFE,  0x48,  0x80,  0xFC,  0x08,  0x42,  0xFC,  0x48, 	/* 0FFC0 */
+	0x44,  0xFC,  0x84,  0x49,  0x82,  0x94,  0x40,  0x03,  0xFE,  0x0A,  0x89,  0x24,  0x5F,  0xE1,  0x76,  0x1A, 	/* 0FFD0 */
+	0xA3,  0x76,  0x57,  0x65,  0xAA,  0x97,  0x69,  0x22,  0x95,  0x4F,  0xC2,  0x84,  0x0F,  0xC8,  0x84,  0x4F, 	/* 0FFE0 */
+	0xC0,  0x44,  0x0A,  0xA2,  0x54,  0x4A,  0xA5,  0xFE,  0x95,  0x4A,  0x2A,  0x98,  0x42,  0x03,  0xFE,  0x11, 	/* 0FFF0 */
+	0x28,  0xA8,  0x4A,  0x21,  0x1A,  0x1F,  0xC1,  0x54,  0x7F,  0xE4,  0x10,  0x81,  0x08,  0x30,  0x9B,  0x48, 	/* 10000 */
+	0x83,  0xFE,  0x0A,  0x89,  0xFE,  0x50,  0x20,  0xFC,  0x1A,  0x42,  0x74,  0x59,  0x84,  0x74,  0x99,  0x28, 	/* 10010 */
+	0x30,  0x9F,  0x41,  0x03,  0xFE,  0x02,  0xA9,  0xFC,  0x4B,  0x80,  0xB4,  0x15,  0x22,  0x84,  0x4F,  0xC4, 	/* 10020 */
+	0x84,  0x8F,  0xC9,  0x04,  0xA0,  0x42,  0x03,  0xFE,  0x07,  0x88,  0x48,  0x5F,  0xE1,  0x02,  0x0F,  0xC2, 	/* 10030 */
+	0x64,  0x5B,  0x84,  0x54,  0x99,  0x28,  0x60,  0xA1,  0x9F,  0xC4,  0x20,  0x3F,  0xE2,  0x22,  0xAF,  0xA4, 	/* 10040 */
+	0x00,  0x1F,  0xE2,  0x20,  0x5F,  0xC5,  0x54,  0x95,  0x49,  0x0C,  0xA4,  0x82,  0x05,  0xFE,  0x02,  0x0B, 	/* 10050 */
+	0xFE,  0x40,  0x40,  0xF8,  0x02,  0x07,  0xFE,  0x5C,  0x45,  0x7E,  0x9D,  0x48,  0x0C,  0xAB,  0xBD,  0x06, 	/* 10060 */
+	0x90,  0x3D,  0xE2,  0x50,  0xBE,  0x06,  0x9E,  0x3C,  0x00,  0x00,  0x5F,  0xC5,  0x54,  0x95,  0x4B,  0xFE, 	/* 10070 */
+	0xAC,  0x43,  0xC2,  0x20,  0x1F,  0xE9,  0x02,  0x4F,  0x81,  0x54,  0x28,  0xA1,  0xFC,  0x68,  0xA4,  0xF8, 	/* 10080 */
+	0x88,  0x88,  0xF8,  0xAE,  0x88,  0x84,  0xAA,  0x09,  0xC1,  0x7F,  0x92,  0x27,  0x14,  0x13,  0xE1,  0x08, 	/* 10090 */
+	0x57,  0xF5,  0x14,  0x92,  0x29,  0x41,  0xAF,  0x40,  0x03,  0xDE,  0x04,  0x23,  0xDE,  0x84,  0x25,  0xDE, 	/* 100A0 */
+	0x08,  0x82,  0xFC,  0x59,  0x04,  0xFC,  0x89,  0x08,  0xFE,  0xB1,  0x41,  0x02,  0xFE,  0x09,  0x28,  0x54, 	/* 100B0 */
+	0x49,  0x80,  0x7C,  0x0C,  0x42,  0x7C,  0x44,  0x44,  0x7C,  0x82,  0x48,  0xC2,  0xB3,  0x59,  0x43,  0xDE, 	/* 100C0 */
+	0x2A,  0x4B,  0xFE,  0x48,  0x41,  0xAC,  0x2D,  0x60,  0xFC,  0x48,  0x44,  0xFC,  0x88,  0x48,  0xFC,  0xB6, 	/* 100D0 */
+	0x5E,  0xF3,  0x29,  0x1E,  0xF9,  0x29,  0x5E,  0xF1,  0x79,  0x11,  0x13,  0x7D,  0x51,  0x15,  0x7D,  0x94, 	/* 100E0 */
+	0x59,  0x7D,  0xBA,  0x40,  0xA3,  0xCE,  0x17,  0x89,  0xCA,  0x54,  0x41,  0x5A,  0x1C,  0xE3,  0x78,  0x54, 	/* 100F0 */
+	0xA5,  0xC4,  0x88,  0xCB,  0x52,  0xBE,  0x43,  0xC2,  0x20,  0x1F,  0xE9,  0x3A,  0x5E,  0x01,  0x1E,  0x17, 	/* 10100 */
+	0xC3,  0x54,  0x57,  0xC5,  0x74,  0x9A,  0xAA,  0x38,  0x81,  0x44,  0x83,  0xFE,  0x02,  0x09,  0xFC,  0x4A, 	/* 10110 */
+	0x81,  0x24,  0x0F,  0xA2,  0x88,  0x4F,  0xA4,  0xA4,  0x89,  0x89,  0xE6,  0x89,  0x42,  0x03,  0xFE,  0x14, 	/* 10120 */
+	0x28,  0x9C,  0x4C,  0xC0,  0x84,  0x0F,  0xC2,  0x40,  0x4F,  0xE5,  0x02,  0x8A,  0xA9,  0x0C,  0x8B,  0x42, 	/* 10130 */
+	0x03,  0xFE,  0x11,  0xA0,  0xE8,  0x8B,  0x05,  0xFE,  0x0A,  0x81,  0xFC,  0x6A,  0xA4,  0xF8,  0x8A,  0x88, 	/* 10140 */
+	0xF8,  0x8F,  0x4A,  0x23,  0x72,  0x15,  0xA9,  0xDA,  0x44,  0xA0,  0xAA,  0x0F,  0xA3,  0x4A,  0x5F,  0xA5, 	/* 10150 */
+	0x52,  0x8F,  0x29,  0x86,  0x91,  0x4F,  0xC2,  0x84,  0x0F,  0xC8,  0x48,  0x4F,  0xC0,  0x48,  0x1F,  0xE0, 	/* 10160 */
+	0x54,  0x4D,  0x65,  0x39,  0x8D,  0x68,  0x10,  0x95,  0x88,  0x04,  0xBE,  0x2E,  0x82,  0x9E,  0xBF,  0x24, 	/* 10170 */
+	0x9E,  0x1B,  0x22,  0x9E,  0x6B,  0x24,  0x5E,  0x89,  0x4B,  0x22,  0x98,  0x43,  0xC2,  0x20,  0x1F,  0xE9, 	/* 10180 */
+	0x22,  0x5F,  0x81,  0x7E,  0x15,  0x43,  0x7C,  0x55,  0x46,  0xFE,  0xAA,  0xAD,  0xFF,  0x9A,  0x90,  0x87, 	/* 10190 */
+	0xD4,  0x11,  0x43,  0xA2,  0xAC,  0x17,  0xFE,  0x2B,  0x63,  0xDA,  0x53,  0x67,  0xDA,  0x91,  0x29,  0x36, 	/* 101A0 */
+	0x9B,  0x42,  0x03,  0xFE,  0x10,  0x09,  0xFC,  0x48,  0x80,  0xF8,  0x1D,  0xC3,  0x54,  0x57,  0x45,  0xDC, 	/* 101B0 */
+	0x95,  0x4A,  0xE6,  0x9D,  0x9F,  0xE5,  0xFC,  0x14,  0x81,  0xFE,  0x95,  0xC5,  0xEA,  0x14,  0x83,  0x10, 	/* 101C0 */
+	0x55,  0x05,  0x5C,  0x95,  0x0A,  0xFE,  0x9E,  0x89,  0xC7,  0xD4,  0x0A,  0x49,  0xC8,  0x4B,  0xE3,  0xCA, 	/* 101D0 */
+	0x17,  0xF5,  0xCA,  0x57,  0xE5,  0xC8,  0x94,  0x89,  0x58,  0x9F,  0x48,  0x83,  0xFE,  0x0A,  0x89,  0xFE, 	/* 101E0 */
+	0x42,  0x83,  0xFF,  0x1A,  0xA3,  0xFE,  0x52,  0x25,  0xAE,  0x9A,  0xAA,  0xAA,  0xA6,  0x40,  0x83,  0xE8, 	/* 101F0 */
+	0x09,  0xE8,  0x8C,  0x5B,  0xE2,  0x48,  0x0D,  0xE1,  0x72,  0x4D,  0xE5,  0x52,  0xA5,  0x28,  0x9E,  0xA7, 	/* 10200 */
+	0x89,  0x07,  0xFE,  0x15,  0x01,  0x5E,  0xBE,  0x25,  0x5E,  0x1D,  0x03,  0x5C,  0x5D,  0x05,  0x5C,  0x95, 	/* 10210 */
+	0x29,  0x4E,  0xAC,  0x88,  0x04,  0x9E,  0x3E,  0x88,  0x9E,  0x7F,  0x22,  0xBE,  0x3F,  0x25,  0x9E,  0x5D, 	/* 10220 */
+	0x26,  0xBE,  0xA8,  0xC8,  0x92,  0xB0,  0x40,  0x03,  0xFE,  0x15,  0x49,  0xFE,  0x7B,  0xA2,  0xD6,  0x3B, 	/* 10230 */
+	0xA4,  0xD6,  0x4B,  0xA8,  0xD6,  0x9B,  0xAA,  0x96,  0xB2,  0x89,  0x05,  0x50,  0x23,  0xE1,  0xD4,  0x81, 	/* 10240 */
+	0x47,  0xE4,  0x2B,  0x43,  0xE8,  0x54,  0x85,  0x54,  0xAB,  0x4A,  0x22,  0xBE,  0xBD,  0xE6,  0x52,  0x3D, 	/* 10250 */
+	0xE2,  0x22,  0xAF,  0xA6,  0x22,  0x2F,  0xA2,  0xAA,  0x6F,  0xA6,  0x72,  0xAA,  0xAA,  0x26,  0x8C,  0x44, 	/* 10260 */
+	0x83,  0xFE,  0x04,  0x89,  0xDC,  0x55,  0x41,  0xDC,  0x04,  0x02,  0xFE,  0x59,  0x04,  0xFC,  0x89,  0x08, 	/* 10270 */
+	0xFE,  0x91,  0x5D,  0xE2,  0x00,  0x1D,  0xC9,  0x54,  0x5F,  0xE1,  0x28,  0x1F,  0xE3,  0x2A,  0x5F,  0xE5, 	/* 10280 */
+	0x6C,  0x94,  0xAA,  0xEE,  0x98,  0x94,  0xA7,  0xF4,  0x15,  0xEB,  0xF4,  0x69,  0x43,  0xFE,  0x09,  0x47, 	/* 10290 */
+	0xF4,  0x49,  0xE7,  0xF4,  0x95,  0x4A,  0x1E,  0xA3,  0x89,  0x45,  0x7A,  0x08,  0x51,  0xFF,  0x8D,  0x65, 	/* 102A0 */
+	0x7D,  0x00,  0x42,  0xFC,  0x48,  0x04,  0xFE,  0x80,  0x28,  0x1C,  0xAB,  0x04,  0x00,  0x40,  0x04,  0x42, 	/* 102B0 */
+	0x44,  0x24,  0x84,  0x50,  0x44,  0x00,  0x60,  0x0A,  0x00,  0x90,  0x30,  0x8C,  0x06,  0xAF,  0x20,  0x02, 	/* 102C0 */
+	0xFE,  0x20,  0x8A,  0x88,  0xB0,  0x82,  0x08,  0x20,  0x82,  0x08,  0x50,  0x84,  0x88,  0x80,  0x80,  0x18, 	/* 102D0 */
+	0xB0,  0x00,  0x03,  0xFE,  0x22,  0x02,  0x24,  0x2A,  0x42,  0xA4,  0x32,  0x82,  0x20,  0x45,  0x04,  0x50, 	/* 102E0 */
+	0x88,  0x83,  0x06,  0xB8,  0x08,  0x00,  0xF0,  0x11,  0x06,  0x60,  0x09,  0x83,  0x46,  0xC4,  0x01,  0x44, 	/* 102F0 */
+	0x6D,  0x80,  0xA0,  0x31,  0x0C,  0x0E,  0xBC,  0x22,  0x02,  0x20,  0x2B,  0xE7,  0x42,  0xA4,  0x2A,  0xA2, 	/* 10300 */
+	0x21,  0x23,  0x12,  0x50,  0x24,  0x82,  0x80,  0x20,  0x0C,  0xBD,  0x12,  0x42,  0x48,  0x49,  0x02,  0x48, 	/* 10310 */
+	0x24,  0x80,  0x00,  0x04,  0x42,  0x44,  0x24,  0x84,  0xA0,  0x31,  0x8C,  0x06,  0x89,  0x2F,  0xE2,  0x00, 	/* 10320 */
+	0x27,  0xE6,  0xC2,  0x74,  0x2A,  0x7E,  0x24,  0x02,  0x40,  0x54,  0x04,  0x80,  0x88,  0x01,  0x00,  0x8A, 	/* 10330 */
+	0x24,  0x02,  0x40,  0x24,  0x06,  0xFE,  0x75,  0x2A,  0x54,  0x29,  0x02,  0x10,  0x52,  0x84,  0x28,  0x84, 	/* 10340 */
+	0x49,  0x82,  0x8E,  0x04,  0x01,  0x44,  0x24,  0x80,  0x60,  0x19,  0x86,  0x44,  0x14,  0x01,  0x44,  0x26, 	/* 10350 */
+	0x80,  0x90,  0x30,  0x8C,  0x06,  0x92,  0x21,  0x02,  0x10,  0x21,  0x46,  0xD4,  0x75,  0x2A,  0x52,  0xA9, 	/* 10360 */
+	0x62,  0x34,  0x50,  0x84,  0x90,  0x46,  0x09,  0x80,  0x99,  0x04,  0x00,  0xFC,  0x74,  0x81,  0x30,  0x0E, 	/* 10370 */
+	0x0F,  0x40,  0x24,  0x42,  0x44,  0x44,  0x80,  0xA0,  0x31,  0x8C,  0x06,  0xAC,  0x20,  0x02,  0x7E,  0x24, 	/* 10380 */
+	0x06,  0xC0,  0x77,  0xEA,  0x42,  0xA4,  0x22,  0x7E,  0x54,  0x04,  0xC0,  0x44,  0x08,  0x7E,  0xAD,  0x44, 	/* 10390 */
+	0x44,  0x44,  0x7F,  0xC0,  0x00,  0x7F,  0xC5,  0x48,  0x54,  0x85,  0x50,  0x46,  0x04,  0x90,  0x90,  0x8E, 	/* 103A0 */
+	0x06,  0xAE,  0x22,  0x02,  0x20,  0x27,  0xE6,  0x82,  0x77,  0xAA,  0x4A,  0xA4,  0xA2,  0x7C,  0x34,  0x04, 	/* 103B0 */
+	0xC0,  0x44,  0x28,  0x3E,  0xAF,  0x20,  0x02,  0x7E,  0x24,  0x26,  0xC2,  0x77,  0xAA,  0x6A,  0xA6,  0xA2, 	/* 103C0 */
+	0x6A,  0x57,  0xA4,  0xC2,  0x44,  0x28,  0x46,  0xB3,  0x20,  0x02,  0x7E,  0x21,  0x06,  0x90,  0x77,  0xEA, 	/* 103D0 */
+	0x52,  0xA6,  0xA2,  0x66,  0x34,  0x24,  0xC2,  0x44,  0x28,  0x46,  0xB8,  0x24,  0x02,  0x40,  0x27,  0xE6, 	/* 103E0 */
+	0xD0,  0x75,  0x0A,  0x9E,  0xA1,  0x02,  0x10,  0x51,  0xE4,  0x90,  0x41,  0x08,  0x10,  0xB9,  0x04,  0x00, 	/* 103F0 */
+	0x40,  0x07,  0xE0,  0x40,  0x3F,  0x82,  0x08,  0x20,  0x83,  0xF8,  0x00,  0x05,  0x24,  0x49,  0x28,  0x92, 	/* 10400 */
+	0xBA,  0x22,  0x01,  0x20,  0x04,  0x07,  0xF0,  0x09,  0x01,  0xFC,  0x10,  0x43,  0xFE,  0x40,  0x29,  0x52, 	/* 10410 */
+	0x2A,  0xA4,  0x0C,  0x88,  0x00,  0x2F,  0xD2,  0x21,  0x23,  0xD2,  0x65,  0x29,  0x42,  0x08,  0x23,  0x02, 	/* 10420 */
+	0xC0,  0x64,  0xA4,  0x49,  0x28,  0x92,  0x8B,  0x22,  0x02,  0x20,  0x3F,  0xE4,  0x70,  0xC7,  0x04,  0xA8, 	/* 10430 */
+	0x52,  0x46,  0x22,  0x42,  0x02,  0x24,  0x49,  0x28,  0x92,  0x8F,  0x08,  0x03,  0xF8,  0x20,  0x83,  0xF8, 	/* 10440 */
+	0x20,  0x03,  0xFE,  0x20,  0x03,  0xFE,  0x01,  0x25,  0x4A,  0x4A,  0x28,  0x0C,  0x99,  0x21,  0x02,  0x1C, 	/* 10450 */
+	0x2A,  0x47,  0x24,  0x65,  0x8A,  0x18,  0xA2,  0x42,  0x7E,  0x5A,  0x54,  0xA4,  0x42,  0x48,  0x3C,  0x9D, 	/* 10460 */
+	0x3F,  0x80,  0x10,  0x06,  0x4F,  0x68,  0x15,  0x02,  0x48,  0xC4,  0x60,  0xC0,  0xFF,  0xE0,  0x00,  0x4A, 	/* 10470 */
+	0x48,  0x92,  0x9F,  0x20,  0x02,  0x7E,  0x25,  0x26,  0xD2,  0x77,  0xEA,  0x52,  0xA5,  0x22,  0x5A,  0x36, 	/* 10480 */
+	0xA4,  0xE6,  0x44,  0x28,  0x7E,  0xB1,  0x20,  0x02,  0xFE,  0x2A,  0xA6,  0xAA,  0x7C,  0xEA,  0x82,  0xAB, 	/* 10490 */
+	0xA2,  0xAA,  0x2A,  0xA5,  0xBA,  0x48,  0x28,  0x86,  0xB9,  0x04,  0x0F,  0xFE,  0x00,  0x03,  0xF8,  0x20, 	/* 104A0 */
+	0x87,  0xFC,  0x03,  0x00,  0x40,  0x0C,  0x04,  0x24,  0x49,  0x28,  0x92,  0xBD,  0x24,  0x02,  0x7C,  0x2A, 	/* 104B0 */
+	0x47,  0x18,  0xBE,  0x6A,  0x10,  0x27,  0xC2,  0x10,  0x37,  0xC4,  0x90,  0x4F,  0xE8,  0x10,  0x89,  0x00, 	/* 104C0 */
+	0x0F,  0xFE,  0x04,  0x02,  0x7C,  0x24,  0x0F,  0xFE,  0x3F,  0xC2,  0x00,  0x3F,  0xC5,  0x54,  0x6A,  0x48, 	/* 104D0 */
+	0x18,  0x94,  0x20,  0x82,  0x0E,  0x23,  0x26,  0x84,  0xB0,  0x8A,  0x5E,  0x25,  0x22,  0x52,  0x55,  0xE4, 	/* 104E0 */
+	0xD2,  0x85,  0x20,  0x5E,  0x99,  0x21,  0x02,  0x10,  0x2F,  0xE6,  0xC4,  0xB2,  0x8A,  0xFE,  0x20,  0x02, 	/* 104F0 */
+	0x7C,  0x34,  0x44,  0xC4,  0x44,  0x48,  0x7C,  0x9A,  0x10,  0x8F,  0xFE,  0x11,  0x03,  0xB8,  0x55,  0x49, 	/* 10500 */
+	0x12,  0x04,  0x02,  0x44,  0x24,  0x84,  0xA0,  0x31,  0x8C,  0x06,  0x9C,  0x20,  0x02,  0x7E,  0x24,  0x26, 	/* 10510 */
+	0xC2,  0xB7,  0xEA,  0x42,  0x27,  0xE2,  0x48,  0x37,  0xE4,  0xC8,  0x45,  0x98,  0xEF,  0xA1,  0x20,  0x03, 	/* 10520 */
+	0xFE,  0x6A,  0x8A,  0xA8,  0xFF,  0xC2,  0xA8,  0x2A,  0x8F,  0xFE,  0x00,  0x04,  0xA4,  0x49,  0x28,  0x92, 	/* 10530 */
+	0xA6,  0x11,  0x01,  0x20,  0x3F,  0xE6,  0x20,  0xBF,  0xC2,  0x20,  0x3F,  0xC2,  0x20,  0x3F,  0xE4,  0x04, 	/* 10540 */
+	0x49,  0x28,  0x92,  0xB6,  0x11,  0x41,  0xD2,  0x35,  0x04,  0xFE,  0xA9,  0x01,  0x18,  0x22,  0x4C,  0xC2, 	/* 10550 */
+	0x00,  0x05,  0x24,  0x49,  0x28,  0x02,  0xBC,  0x22,  0x02,  0xFC,  0x22,  0x06,  0x68,  0x7F,  0xCA,  0x48, 	/* 10560 */
+	0xAF,  0xE2,  0x28,  0x52,  0x84,  0xCA,  0x48,  0xA9,  0x06,  0x89,  0x21,  0x02,  0xFE,  0x21,  0x06,  0xFC, 	/* 10570 */
+	0xB9,  0x4A,  0xFC,  0x29,  0x42,  0xFC,  0x53,  0x84,  0xD4,  0x89,  0x20,  0x10,  0x8C,  0x22,  0x02,  0x7C, 	/* 10580 */
+	0x24,  0x46,  0xFC,  0xB4,  0x4A,  0x7C,  0x20,  0x02,  0xFE,  0x31,  0x04,  0xFC,  0x41,  0x08,  0xFE,  0x8E, 	/* 10590 */
+	0x20,  0x81,  0x10,  0xFF,  0xE4,  0x84,  0x7A,  0x44,  0xA4,  0x7A,  0x44,  0xA4,  0x58,  0xC0,  0x00,  0x49, 	/* 105A0 */
+	0x48,  0x92,  0x95,  0x00,  0x0F,  0xBC,  0x92,  0x4B,  0xA4,  0xAA,  0x4A,  0xBC,  0x9A,  0x09,  0x22,  0xF9, 	/* 105B0 */
+	0xE0,  0x00,  0x4A,  0x48,  0x92,  0x96,  0x20,  0xE2,  0xF2,  0x25,  0x47,  0x34,  0x6F,  0xEA,  0x20,  0xBF, 	/* 105C0 */
+	0xE2,  0x20,  0x57,  0xE4,  0x54,  0x49,  0xC9,  0x62,  0x99,  0x20,  0x02,  0xFE,  0x22,  0x86,  0xFE,  0xBA, 	/* 105D0 */
+	0xAA,  0xAA,  0x2F,  0xE2,  0x10,  0x57,  0xC4,  0x90,  0x81,  0x00,  0xFE,  0xA2,  0x22,  0x0A,  0xA8,  0x55, 	/* 105E0 */
+	0x08,  0x88,  0xFF,  0xC8,  0x04,  0x7F,  0x80,  0x88,  0x08,  0x87,  0xEA,  0x08,  0x60,  0x82,  0xA4,  0x22, 	/* 105F0 */
+	0x42,  0xFE,  0x22,  0x46,  0xFC,  0x72,  0x4A,  0x3C,  0x21,  0x02,  0xFE,  0x53,  0x84,  0x54,  0x99,  0x28, 	/* 10600 */
+	0x10,  0xA5,  0x23,  0xC2,  0x44,  0x28,  0x86,  0xFE,  0x6A,  0xAB,  0xAA,  0x2C,  0xE2,  0x92,  0x3F,  0xF4, 	/* 10610 */
+	0x90,  0x46,  0x89,  0x86,  0xA6,  0x02,  0x0F,  0x3E,  0x94,  0x29,  0xFA,  0xF4,  0xA9,  0x4A,  0x97,  0xAF, 	/* 10620 */
+	0x02,  0x00,  0xC4,  0x00,  0x4A,  0x48,  0x92,  0xA7,  0x00,  0x0F,  0xFC,  0x92,  0x49,  0x24,  0xF4,  0x89, 	/* 10630 */
+	0xFC,  0x94,  0x49,  0x44,  0xF7,  0xC0,  0x00,  0x52,  0x48,  0x92,  0xA9,  0x20,  0x02,  0x7E,  0x69,  0x07, 	/* 10640 */
+	0x7E,  0xA4,  0x2A,  0x7E,  0x24,  0x22,  0x7E,  0x54,  0x24,  0xFE,  0x42,  0x48,  0xC2,  0xAC,  0x20,  0x02, 	/* 10650 */
+	0x7C,  0x24,  0x46,  0xFC,  0xB4,  0x4A,  0xFE,  0x24,  0x02,  0xFE,  0x34,  0xA4,  0x92,  0x42,  0x28,  0xCC, 	/* 10660 */
+	0xAE,  0x04,  0x87,  0xFC,  0x05,  0x0F,  0xFE,  0x08,  0x03,  0xF8,  0xD0,  0x81,  0xF8,  0x10,  0x81,  0xF8, 	/* 10670 */
+	0x2A,  0x44,  0x92,  0xBD,  0x2F,  0xE2,  0x00,  0x2F,  0xC2,  0x84,  0x6F,  0xC7,  0x80,  0xAF,  0xE2,  0xDA, 	/* 10680 */
+	0x2B,  0x65,  0xDA,  0x49,  0x28,  0xB6,  0x84,  0x22,  0x02,  0x7C,  0x24,  0x46,  0xFC,  0x74,  0x4A,  0x7C, 	/* 10690 */
+	0xA4,  0x42,  0x7C,  0x21,  0x05,  0x4A,  0x46,  0x28,  0x9E,  0x88,  0x00,  0x05,  0xFE,  0x55,  0x25,  0xF2, 	/* 106A0 */
+	0x53,  0xE5,  0x30,  0x5F,  0x05,  0x52,  0x9E,  0xE0,  0x00,  0x4A,  0x48,  0x92,  0x8A,  0x22,  0x44,  0xB8, 	/* 106B0 */
+	0xFA,  0x24,  0xDE,  0x78,  0x04,  0xA4,  0x7B,  0x84,  0xA2,  0x89,  0xE0,  0x00,  0x52,  0x48,  0x92,  0x8F, 	/* 106C0 */
+	0x3F,  0x80,  0x40,  0xFF,  0xE0,  0x40,  0xFF,  0xE6,  0x4C,  0x55,  0x4F,  0xFE,  0x04,  0x0F,  0xFE,  0x4A, 	/* 106D0 */
+	0x48,  0x92,  0x94,  0x21,  0x02,  0xFE,  0x28,  0x26,  0x2A,  0xB5,  0x4A,  0x28,  0x2C,  0x62,  0x00,  0x57, 	/* 106E0 */
+	0xC4,  0x44,  0x84,  0x40,  0x7C,  0x95,  0x20,  0x02,  0x7C,  0x21,  0x06,  0xFE,  0x6C,  0x4B,  0x7C,  0xA4, 	/* 106F0 */
+	0x42,  0x7C,  0x34,  0x44,  0xFC,  0x42,  0xC8,  0xC2,  0x99,  0x00,  0x0F,  0xDE,  0x91,  0x2B,  0x92,  0xA9, 	/* 10700 */
+	0xEA,  0x90,  0xB9,  0x29,  0x12,  0xFC,  0xE0,  0x00,  0x4A,  0x48,  0x92,  0x9F,  0x11,  0x0F,  0xD0,  0x7B, 	/* 10710 */
+	0xC4,  0x94,  0x7B,  0x41,  0x14,  0xFA,  0xC1,  0x46,  0x38,  0x25,  0x24,  0x49,  0x28,  0x92,  0xA8,  0x7C, 	/* 10720 */
+	0x44,  0x7E,  0x7E,  0x44,  0x94,  0x48,  0x4A,  0xA4,  0xAA,  0xC0,  0x44,  0x24,  0x84,  0x40,  0x1B,  0x0E, 	/* 10730 */
+	0x0E,  0xAC,  0x22,  0x07,  0xA0,  0x23,  0xEF,  0xA4,  0x25,  0x43,  0x94,  0x28,  0x84,  0x94,  0x9A,  0x20, 	/* 10740 */
+	0x00,  0x4A,  0x48,  0x92,  0xB1,  0x21,  0x0F,  0x90,  0x27,  0xCF,  0x94,  0x53,  0x4F,  0x94,  0x22,  0xC3, 	/* 10750 */
+	0xA4,  0xC4,  0x64,  0x08,  0x52,  0x48,  0x92,  0xB9,  0x04,  0x0F,  0xFE,  0x04,  0x07,  0xFC,  0x20,  0x83, 	/* 10760 */
+	0xF8,  0x11,  0x0F,  0xFE,  0x20,  0x83,  0xF8,  0x52,  0x48,  0x92,  0xBE,  0x22,  0x42,  0xFE,  0x25,  0x56, 	/* 10770 */
+	0x54,  0x6F,  0xFB,  0x04,  0xA7,  0x52,  0x55,  0x57,  0x54,  0x52,  0x47,  0x68,  0x19,  0x83,  0x24,  0xC2, 	/* 10780 */
+	0x6A,  0x2A,  0x86,  0xFE,  0x7A,  0x8A,  0x48,  0x25,  0x42,  0xA2,  0x30,  0x05,  0x54,  0x4A,  0xA9,  0x2A, 	/* 10790 */
+	0x88,  0x27,  0x02,  0x16,  0x2E,  0x86,  0xAA,  0x77,  0xCA,  0x82,  0x27,  0xC2,  0x44,  0x57,  0xC4,  0x44, 	/* 107A0 */
+	0x82,  0x80,  0xFE,  0x89,  0x24,  0x82,  0xF8,  0x20,  0xE6,  0xEA,  0x7B,  0xAA,  0xEA,  0xA1,  0x42,  0xE4, 	/* 107B0 */
+	0x35,  0x45,  0xEA,  0x44,  0xA8,  0xD1,  0x8E,  0x21,  0x02,  0xFE,  0x22,  0x86,  0xBA,  0x74,  0x4A,  0xFE, 	/* 107C0 */
+	0xA4,  0x52,  0x7C,  0x31,  0x04,  0x54,  0x49,  0x28,  0x30,  0x90,  0x29,  0x22,  0x54,  0x6F,  0xE7,  0x38, 	/* 107D0 */
+	0xA5,  0x4A,  0x92,  0x24,  0x42,  0x7E,  0x5B,  0x45,  0x3E,  0x84,  0x41,  0x84,  0x92,  0x21,  0x02,  0x7C, 	/* 107E0 */
+	0x21,  0x06,  0xFE,  0x74,  0x4A,  0xEE,  0xA4,  0x42,  0xFE,  0x50,  0x04,  0xFE,  0x42,  0x88,  0xCE,  0x94, 	/* 107F0 */
+	0x20,  0xC2,  0xF2,  0x25,  0x46,  0xFE,  0x73,  0x8A,  0x54,  0xA9,  0x22,  0x7F,  0x35,  0x24,  0xFE,  0x45, 	/* 10800 */
+	0x28,  0x7E,  0x95,  0x0A,  0x0F,  0xFE,  0x0A,  0x02,  0xE8,  0x20,  0xEE,  0xE8,  0x2A,  0xAE,  0xEA,  0x20, 	/* 10810 */
+	0x62,  0xA4,  0x49,  0x28,  0x92,  0x97,  0x2E,  0xE2,  0xAA,  0x2E,  0xE6,  0xAA,  0xBE,  0xEA,  0xBA,  0x2A, 	/* 10820 */
+	0xA2,  0xBA,  0x5A,  0xA4,  0xBA,  0x4C,  0xA8,  0x86,  0x9F,  0x55,  0x42,  0xA8,  0x44,  0x4F,  0xFE,  0x80, 	/* 10830 */
+	0x2B,  0xFA,  0x20,  0x83,  0xF8,  0x08,  0x07,  0xFC,  0x40,  0x47,  0xFC,  0xA0,  0x22,  0x02,  0xFE,  0x2D, 	/* 10840 */
+	0x66,  0xBA,  0x79,  0x2A,  0xFE,  0xAB,  0xA2,  0xD6,  0x39,  0x24,  0xFF,  0x42,  0x88,  0xC6,  0xA5,  0x27, 	/* 10850 */
+	0xC2,  0x44,  0x27,  0xC6,  0xEE,  0x7A,  0xAA,  0xEE,  0x21,  0x02,  0xFE,  0x53,  0x84,  0x54,  0x89,  0x30, 	/* 10860 */
+	0x10,  0xA6,  0x2E,  0xE2,  0x82,  0x2E,  0xAA,  0xA4,  0xB6,  0xA6,  0xD0,  0x29,  0x22,  0x54,  0x2F,  0xE5, 	/* 10870 */
+	0x38,  0x4D,  0x68,  0x10,  0xA7,  0x25,  0x42,  0x22,  0x2B,  0xC6,  0x50,  0xB2,  0xAA,  0xDA,  0x26,  0xC2, 	/* 10880 */
+	0x5A,  0x36,  0x94,  0x48,  0x4B,  0x09,  0x1F,  0xAC,  0x24,  0x02,  0x8E,  0x2E,  0xA6,  0xAA,  0x7F,  0x3A, 	/* 10890 */
+	0xA0,  0xAF,  0xE2,  0x4A,  0x2F,  0xA5,  0x44,  0x46,  0xA9,  0x91,  0xAD,  0x2F,  0xE2,  0xAA,  0x2F,  0xE6, 	/* 108A0 */
+	0xC0,  0xB7,  0xEA,  0xA2,  0x3F,  0xA2,  0xAA,  0x5F,  0xA4,  0x2A,  0x83,  0xA1,  0xCC,  0xAE,  0x2E,  0x82, 	/* 108B0 */
+	0x08,  0x7F,  0xAA,  0xEA,  0x2E,  0xC5,  0xB4,  0x8E,  0x20,  0x40,  0x7F,  0xC1,  0x10,  0x0E,  0x0F,  0x1E, 	/* 108C0 */
+	0xB5,  0x24,  0x82,  0x3C,  0x28,  0x86,  0x7E,  0x71,  0x4A,  0xFE,  0xA4,  0x82,  0x7E,  0x34,  0x84,  0x7C, 	/* 108D0 */
+	0x4A,  0x89,  0x1F,  0xB9,  0x00,  0x0F,  0xBE,  0x61,  0x0B,  0x6A,  0xD9,  0xC3,  0x6A,  0xD1,  0x82,  0x50, 	/* 108E0 */
+	0x24,  0x44,  0xE8,  0x31,  0x8C,  0x06,  0xBB,  0x20,  0xC2,  0x70,  0x2F,  0xE6,  0x10,  0x7F,  0xEA,  0xD6, 	/* 108F0 */
+	0x2B,  0xA2,  0xFE,  0x51,  0x04,  0xFE,  0x4D,  0x49,  0x2A,  0xBC,  0x22,  0x02,  0xFC,  0x22,  0x46,  0xFE, 	/* 10900 */
+	0x72,  0x0A,  0xFC,  0xA5,  0x42,  0xAA,  0x2F,  0xC5,  0xB4,  0x4B,  0x49,  0xFE,  0xBF,  0x20,  0x02,  0xFE, 	/* 10910 */
+	0x25,  0xA6,  0xB6,  0x75,  0xAA,  0x36,  0xA2,  0x42,  0xFE,  0x34,  0x84,  0xFE,  0x44,  0x88,  0x7E,  0x86, 	/* 10920 */
+	0x27,  0xC2,  0x44,  0x27,  0xC6,  0xA8,  0x77,  0xCA,  0x28,  0x2F,  0xE2,  0x54,  0x55,  0x64,  0xB9,  0x8D, 	/* 10930 */
+	0x60,  0x10,  0x8D,  0x29,  0x23,  0x54,  0x2B,  0xA7,  0xEC,  0x6B,  0xAB,  0xEE,  0xAB,  0xA3,  0x10,  0x2F, 	/* 10940 */
+	0xE4,  0x58,  0x49,  0x48,  0x10,  0x90,  0x21,  0x02,  0x1C,  0x21,  0x06,  0xFE,  0x69,  0x0B,  0xFE,  0xAD, 	/* 10950 */
+	0x42,  0xFC,  0x3D,  0x44,  0xFE,  0x4A,  0xA9,  0x7F,  0x9B,  0x2E,  0xE2,  0xAA,  0x2E,  0xE6,  0xAA,  0x7E, 	/* 10960 */
+	0xEA,  0x92,  0xAF,  0xE2,  0xD6,  0x3F,  0xE4,  0xBA,  0x4D,  0x68,  0x92,  0xA8,  0x3F,  0xC5,  0xD4,  0x55, 	/* 10970 */
+	0x4F,  0xFE,  0x91,  0x2F,  0xFC,  0x3B,  0x85,  0x54,  0xFF,  0xE4,  0x44,  0x9B,  0x26,  0x0C,  0xAA,  0x00, 	/* 10980 */
+	0xC3,  0xF0,  0x25,  0x02,  0x50,  0x25,  0x02,  0x50,  0x24,  0x82,  0x48,  0x24,  0x84,  0x44,  0x44,  0x48, 	/* 10990 */
+	0x42,  0xAC,  0x0C,  0x07,  0x3E,  0x46,  0xA5,  0x6A,  0x57,  0xE5,  0x60,  0x56,  0x05,  0x62,  0x55,  0xE5, 	/* 109A0 */
+	0x20,  0x51,  0x89,  0x07,  0xAD,  0x03,  0x87,  0xD0,  0x28,  0x84,  0x48,  0x7F,  0xC0,  0x44,  0xFF,  0xE0, 	/* 109B0 */
+	0x44,  0x7F,  0xC0,  0x40,  0x04,  0x00,  0xC0,  0xB0,  0x01,  0xC7,  0xE8,  0x24,  0x42,  0x24,  0x5F,  0xC8, 	/* 109C0 */
+	0x80,  0xFF,  0xE1,  0x00,  0x1F,  0x82,  0x90,  0x47,  0x0B,  0x8E,  0xB2,  0x03,  0xC3,  0xC8,  0x24,  0x44, 	/* 109D0 */
+	0x24,  0xBF,  0x82,  0x08,  0x3F,  0xC2,  0x04,  0x3F,  0xE2,  0xAA,  0x55,  0x2A,  0x0C,  0xB5,  0x03,  0xCF, 	/* 109E0 */
+	0xC8,  0x25,  0x0F,  0xFE,  0x91,  0x2F,  0xFE,  0x48,  0x87,  0xFE,  0x4C,  0x87,  0xA8,  0x58,  0x8E,  0x58, 	/* 109F0 */
+	0xB6,  0x0A,  0x00,  0x90,  0x10,  0x82,  0x04,  0xD1,  0x21,  0x12,  0x09,  0x00,  0xA0,  0x04,  0x00,  0xA0, 	/* 10A00 */
+	0x31,  0x8C,  0x06,  0xBA,  0x0B,  0x03,  0x0C,  0xC9,  0x20,  0x60,  0x39,  0xCF,  0xFE,  0x49,  0x47,  0x98, 	/* 10A10 */
+	0x49,  0x47,  0xD2,  0xC9,  0xC0,  0x90,  0xBB,  0x01,  0x03,  0x20,  0x0C,  0x00,  0xB0,  0x30,  0x8C,  0x00, 	/* 10A20 */
+	0x11,  0x01,  0x10,  0x2A,  0x00,  0x40,  0x1B,  0x0E,  0x0E,  0xBC,  0x13,  0xC1,  0x24,  0xD2,  0x43,  0x24, 	/* 10A30 */
+	0x2B,  0xC4,  0x24,  0x8A,  0x44,  0xBC,  0x32,  0x42,  0xA4,  0x42,  0x48,  0x7E,  0xBD,  0x04,  0x0F,  0xFE, 	/* 10A40 */
+	0x04,  0x09,  0x52,  0x64,  0xC9,  0x52,  0x64,  0xC9,  0x52,  0x0A,  0x01,  0x10,  0x20,  0x8C,  0x06,  0xBE, 	/* 10A50 */
+	0x00,  0x0F,  0xFE,  0x24,  0x84,  0x44,  0xFF,  0xEC,  0xE6,  0xB5,  0xAC,  0xE6,  0xCE,  0x6B,  0x5A,  0xCE, 	/* 10A60 */
+	0x68,  0x46,  0xBF,  0x08,  0x40,  0x84,  0x08,  0x40,  0x84,  0x0F,  0xC0,  0x04,  0x3F,  0xC0,  0x44,  0x04, 	/* 10A70 */
+	0x40,  0x44,  0x08,  0x43,  0x04,  0x80,  0x11,  0x05,  0x10,  0x51,  0x05,  0xFE,  0x71,  0x01,  0x38,  0xF3, 	/* 10A80 */
+	0x85,  0x54,  0x55,  0x49,  0x92,  0x11,  0x01,  0x10,  0x86,  0x11,  0x05,  0xFE,  0x55,  0x45,  0x54,  0xFB, 	/* 10A90 */
+	0xA1,  0xFE,  0xF1,  0x05,  0xFE,  0x56,  0xA5,  0x7A,  0x94,  0x21,  0x7E,  0x87,  0x12,  0x01,  0x20,  0x12, 	/* 10AA0 */
+	0x01,  0xFC,  0x10,  0x01,  0x00,  0x1F,  0x81,  0x10,  0x21,  0x02,  0x10,  0x41,  0x08,  0x10,  0x88,  0x50, 	/* 10AB0 */
+	0x05,  0x7E,  0x54,  0x05,  0x40,  0x7F,  0xC4,  0x44,  0x76,  0x45,  0x68,  0x55,  0x85,  0x58,  0x9A,  0x49, 	/* 10AC0 */
+	0x42,  0x8B,  0x51,  0x45,  0x1E,  0x5F,  0x45,  0x18,  0x72,  0xA4,  0xC6,  0x72,  0x45,  0x3E,  0x5E,  0x45, 	/* 10AD0 */
+	0x1A,  0x96,  0x69,  0x02,  0x8C,  0x50,  0x85,  0x10,  0x57,  0xE7,  0xD2,  0x47,  0xE4,  0x52,  0x7F,  0xE4, 	/* 10AE0 */
+	0xA8,  0x4A,  0x84,  0xFE,  0x88,  0x88,  0x88,  0x92,  0x55,  0x45,  0x54,  0x5F,  0xE5,  0x54,  0x75,  0xC4, 	/* 10AF0 */
+	0x40,  0x77,  0xE5,  0x10,  0x5F,  0xE5,  0x38,  0x5D,  0x6B,  0x10,  0x98,  0x51,  0x05,  0xFE,  0x51,  0x05, 	/* 10B00 */
+	0xFE,  0x79,  0x24,  0xFE,  0x74,  0x45,  0x7C,  0x54,  0x45,  0x7C,  0x92,  0x49,  0xC2,  0x99,  0x00,  0x01, 	/* 10B10 */
+	0xFC,  0x11,  0x01,  0x10,  0x11,  0x0F,  0xFE,  0x03,  0x00,  0x50,  0x09,  0x03,  0x10,  0xC1,  0x00,  0x30, 	/* 10B20 */
+	0x9B,  0x04,  0x02,  0x40,  0x24,  0x03,  0xFC,  0x44,  0x08,  0x40,  0x04,  0x0F,  0xFE,  0x04,  0x00,  0x40, 	/* 10B30 */
+	0x04,  0x00,  0x40,  0x9D,  0x12,  0x05,  0x20,  0x52,  0x07,  0xE2,  0x92,  0x49,  0x38,  0x1A,  0x03,  0x20, 	/* 10B40 */
+	0xD2,  0x01,  0x22,  0x12,  0x21,  0x1E,  0x9F,  0x08,  0x00,  0x90,  0x10,  0x87,  0xFC,  0x24,  0x43,  0xFC, 	/* 10B50 */
+	0x44,  0x08,  0x40,  0xFF,  0xE0,  0x40,  0x04,  0x00,  0x40,  0xA1,  0x11,  0x05,  0x10,  0x51,  0x07,  0x90, 	/* 10B60 */
+	0x97,  0xE1,  0x10,  0x19,  0x0F,  0x10,  0x11,  0x01,  0x10,  0x11,  0x01,  0xFF,  0xA2,  0x04,  0x0F,  0xFE, 	/* 10B70 */
+	0x80,  0x2A,  0x42,  0x24,  0x03,  0xF8,  0x44,  0x04,  0x40,  0xFF,  0xE0,  0x40,  0x04,  0x00,  0x40,  0xA7, 	/* 10B80 */
+	0x12,  0x05,  0x20,  0x52,  0x07,  0xBE,  0x54,  0x49,  0x44,  0x1A,  0x83,  0x28,  0xD1,  0x01,  0x28,  0x14, 	/* 10B90 */
+	0x41,  0x82,  0xA9,  0x24,  0x0A,  0x40,  0xA7,  0xEF,  0x6A,  0xA6,  0xAA,  0xAA,  0x3A,  0xAE,  0x4A,  0x25, 	/* 10BA0 */
+	0x22,  0x92,  0x22,  0x22,  0x4C,  0xB2,  0x21,  0x0A,  0x50,  0xA5,  0x0F,  0x7E,  0xA9,  0x0A,  0x90,  0x31, 	/* 10BB0 */
+	0x0E,  0x7C,  0x21,  0x02,  0x10,  0x21,  0x02,  0xFE,  0xB4,  0x20,  0xCA,  0x70,  0xA5,  0x0F,  0x50,  0xA5, 	/* 10BC0 */
+	0x02,  0x7E,  0x34,  0x8E,  0x48,  0x24,  0xA2,  0xE6,  0x20,  0x62,  0xF2,  0xB9,  0x20,  0x8A,  0x7E,  0xA0, 	/* 10BD0 */
+	0x8F,  0x88,  0xAF,  0xFA,  0x04,  0x37,  0xEE,  0x24,  0x21,  0x42,  0x04,  0x20,  0x42,  0x0C,  0xBD,  0x04, 	/* 10BE0 */
+	0x0F,  0xFE,  0x05,  0x01,  0xA0,  0xFF,  0xE8,  0x92,  0x9E,  0xA2,  0x40,  0x3F,  0x84,  0x40,  0xFF,  0xE0, 	/* 10BF0 */
+	0x40,  0xBE,  0x20,  0x0A,  0xFE,  0xA1,  0x0F,  0xFC,  0xA2,  0x42,  0x24,  0x3F,  0xFE,  0x00,  0x27,  0xE2, 	/* 10C00 */
+	0x42,  0x24,  0x22,  0x7E,  0x80,  0x00,  0x07,  0xFE,  0x40,  0x27,  0xFE,  0x5E,  0xE4,  0x20,  0x5E,  0xE5, 	/* 10C10 */
+	0x20,  0x5F,  0xCA,  0x20,  0x9F,  0xE0,  0x20,  0x81,  0x7C,  0x21,  0x12,  0xFD,  0x23,  0x92,  0x55,  0x29, 	/* 10C20 */
+	0x06,  0x24,  0x03,  0xFC,  0x44,  0x0F,  0xFE,  0x04,  0x00,  0x40,  0x82,  0x7A,  0x01,  0x3E,  0xFE,  0xA3, 	/* 10C30 */
+	0xAA,  0x55,  0x29,  0x26,  0x24,  0x03,  0xFC,  0x44,  0x0F,  0xFE,  0x04,  0x00,  0x40,  0x87,  0x24,  0x03, 	/* 10C40 */
+	0xFC,  0x44,  0x0F,  0xFE,  0x04,  0x01,  0x48,  0x52,  0x87,  0xBE,  0x94,  0x8F,  0xBF,  0x10,  0x81,  0x08, 	/* 10C50 */
+	0x92,  0x21,  0x0A,  0xFE,  0xA7,  0xCF,  0x44,  0xA7,  0xC2,  0x00,  0x3F,  0xEE,  0x82,  0x2B,  0xA2,  0xAA, 	/* 10C60 */
+	0x2B,  0xA2,  0x86,  0x96,  0x11,  0x05,  0x54,  0xAA,  0x84,  0x44,  0xFF,  0xEA,  0x42,  0x3F,  0xC4,  0x40, 	/* 10C70 */
+	0xFF,  0xE0,  0x40,  0x04,  0x00,  0x40,  0xA0,  0x22,  0x8A,  0xFE,  0xA1,  0x0F,  0x7E,  0xA1,  0x0A,  0xFE, 	/* 10C80 */
+	0x34,  0xAE,  0xFE,  0x24,  0xA2,  0xE5,  0x25,  0xB2,  0xC1,  0xA2,  0x21,  0x0A,  0xFE,  0xA1,  0x0F,  0xFE, 	/* 10C90 */
+	0xA9,  0x2A,  0xFE,  0x34,  0x4E,  0x7C,  0x24,  0x42,  0x7C,  0x22,  0x42,  0xC2,  0xA7,  0x22,  0x8A,  0xFE, 	/* 10CA0 */
+	0xA1,  0x0F,  0x7C,  0xA1,  0x0A,  0xFE,  0x34,  0xAE,  0xFF,  0x2C,  0xA3,  0x64,  0x22,  0xE2,  0xD2,  0xAC, 	/* 10CB0 */
+	0x04,  0x00,  0x48,  0x04,  0x40,  0x40,  0xFF,  0xE0,  0x40,  0x0A,  0x00,  0xA0,  0x11,  0x01,  0x10,  0x20, 	/* 10CC0 */
+	0x8C,  0x06,  0xAF,  0x90,  0x06,  0x7C,  0x44,  0x4A,  0x44,  0x24,  0x42,  0x44,  0x65,  0x8A,  0x40,  0x24, 	/* 10CD0 */
+	0x02,  0x42,  0x24,  0x2C,  0x3E,  0xB2,  0x90,  0x86,  0x08,  0x40,  0x8A,  0xFE,  0x20,  0x82,  0x18,  0x61, 	/* 10CE0 */
+	0x8A,  0x28,  0x24,  0x82,  0x88,  0xC0,  0x84,  0x18,  0xB6,  0x11,  0x01,  0x14,  0x91,  0x25,  0x10,  0x1F, 	/* 10CF0 */
+	0xE1,  0x10,  0x31,  0x05,  0x28,  0x92,  0x81,  0x44,  0x18,  0x41,  0x02,  0xB9,  0x92,  0x86,  0x24,  0x42, 	/* 10D00 */
+	0x0B,  0xFE,  0x22,  0x02,  0x60,  0x66,  0x0A,  0x60,  0x26,  0x02,  0xA2,  0xCA,  0x25,  0x1E,  0x82,  0x90, 	/* 10D10 */
+	0x05,  0xFE,  0x21,  0x06,  0x10,  0xA1,  0x02,  0xFC,  0x31,  0x06,  0x10,  0xA1,  0x02,  0x10,  0x21,  0x0C, 	/* 10D20 */
+	0xFE,  0x83,  0x90,  0x06,  0xF8,  0x44,  0x8A,  0x48,  0x24,  0x82,  0xFE,  0x64,  0x8A,  0x48,  0x24,  0x82, 	/* 10D30 */
+	0x48,  0xC4,  0x85,  0xFE,  0x84,  0x91,  0x06,  0x10,  0x41,  0x2A,  0x52,  0x25,  0x42,  0x90,  0x69,  0x0A, 	/* 10D40 */
+	0x10,  0x22,  0x82,  0x28,  0xC4,  0x45,  0x82,  0x86,  0x91,  0x06,  0x10,  0x4F,  0xEA,  0x92,  0x29,  0x22, 	/* 10D50 */
+	0x92,  0x6F,  0xEA,  0x10,  0x21,  0x02,  0x10,  0xC1,  0x04,  0x10,  0x8E,  0x90,  0x06,  0xFE,  0x49,  0x2A, 	/* 10D60 */
+	0x92,  0x2F,  0xE2,  0x92,  0x69,  0x2A,  0xFE,  0x21,  0x02,  0x10,  0xC1,  0x04,  0x10,  0x90,  0xA0,  0xC6, 	/* 10D70 */
+	0xF0,  0x4A,  0x8A,  0xA8,  0x2A,  0x82,  0xA8,  0x6A,  0x8A,  0xA8,  0x2A,  0x82,  0xB4,  0x2B,  0xCD,  0x62, 	/* 10D80 */
+	0x92,  0x92,  0x86,  0x28,  0x4F,  0xEA,  0x2A,  0x2F,  0xE2,  0xA8,  0x2F,  0xF6,  0x29,  0xA2,  0x92,  0x4B, 	/* 10D90 */
+	0xC4,  0x84,  0x88,  0x97,  0x94,  0x06,  0x40,  0x47,  0xEA,  0x82,  0x28,  0x23,  0x7A,  0x64,  0xAA,  0x4A, 	/* 10DA0 */
+	0x27,  0xA2,  0x02,  0x20,  0x2C,  0x0C,  0x99,  0x90,  0x06,  0x7C,  0x44,  0x4A,  0x44,  0x27,  0xC2,  0x44, 	/* 10DB0 */
+	0x64,  0x4A,  0x7C,  0x24,  0x42,  0x44,  0x24,  0x4D,  0xFE,  0x9B,  0x91,  0x06,  0x20,  0x47,  0xEA,  0x42, 	/* 10DC0 */
+	0x24,  0x22,  0x42,  0x67,  0xEA,  0x42,  0x24,  0x22,  0x42,  0x27,  0xEC,  0x42,  0xA0,  0x90,  0x06,  0x7C, 	/* 10DD0 */
+	0x44,  0x4A,  0x7C,  0x24,  0x42,  0x7C,  0x64,  0x2A,  0x64,  0x25,  0x82,  0x48,  0xC7,  0x44,  0xC2,  0xA1, 	/* 10DE0 */
+	0x91,  0x06,  0x10,  0x5F,  0xEA,  0x28,  0x24,  0x42,  0xC6,  0x74,  0x4A,  0x28,  0x21,  0x02,  0x28,  0xC4, 	/* 10DF0 */
+	0x45,  0x82,  0xA2,  0x92,  0x06,  0x3C,  0x42,  0x4A,  0x6C,  0x29,  0x82,  0x24,  0x64,  0x2B,  0xBD,  0x22, 	/* 10E00 */
+	0x42,  0x24,  0xC2,  0x44,  0x3C,  0xA9,  0x91,  0x06,  0xFE,  0x48,  0x2A,  0x8A,  0x20,  0x83,  0xFE,  0x60, 	/* 10E10 */
+	0x8A,  0x48,  0x22,  0x82,  0x08,  0x20,  0x8C,  0x18,  0xAC,  0x92,  0x06,  0x20,  0x42,  0x0B,  0xFC,  0x32, 	/* 10E20 */
+	0x43,  0x24,  0x7F,  0xCA,  0x20,  0x22,  0x82,  0x24,  0x23,  0xED,  0xC2,  0xAD,  0x92,  0x05,  0x20,  0x2F, 	/* 10E30 */
+	0xC7,  0x24,  0xAA,  0x82,  0xA0,  0x3F,  0xE6,  0x20,  0xA2,  0x02,  0x50,  0x28,  0x8D,  0x06,  0xB7,  0x97, 	/* 10E40 */
+	0xE6,  0x42,  0x47,  0xEA,  0x00,  0x27,  0xE2,  0x42,  0x67,  0xEA,  0x42,  0x27,  0xE2,  0x42,  0xC4,  0x24, 	/* 10E50 */
+	0x46,  0xB8,  0x90,  0x05,  0xFE,  0x29,  0x26,  0xFE,  0xA9,  0x22,  0x92,  0x3F,  0xE6,  0x10,  0xA7,  0xC2, 	/* 10E60 */
+	0x10,  0x21,  0x0D,  0xFF,  0xB9,  0x92,  0x06,  0x20,  0x5F,  0xEA,  0x20,  0x2A,  0x82,  0xA8,  0x77,  0x4A, 	/* 10E70 */
+	0x22,  0x25,  0x02,  0x50,  0xC8,  0x85,  0x06,  0xBC,  0x92,  0x06,  0x20,  0x4F,  0xCA,  0x84,  0x2F,  0xC2, 	/* 10E80 */
+	0x84,  0x6F,  0xCA,  0xA4,  0x29,  0x82,  0x88,  0x2E,  0x4D,  0x82,  0xBD,  0x90,  0x06,  0x7C,  0x44,  0x4A, 	/* 10E90 */
+	0x44,  0x27,  0xC2,  0x44,  0x67,  0xCA,  0x44,  0x24,  0x42,  0x7C,  0x22,  0x4C,  0xC2,  0x8A,  0x92,  0x06, 	/* 10EA0 */
+	0x40,  0x4D,  0xCA,  0x84,  0x2D,  0xC2,  0x84,  0x6F,  0xCA,  0x50,  0x25,  0x02,  0x50,  0xC9,  0x25,  0x0E, 	/* 10EB0 */
+	0x96,  0x97,  0xC6,  0x44,  0x47,  0xCA,  0x44,  0x27,  0xC2,  0x00,  0x6F,  0xEA,  0x82,  0x2F,  0xE2,  0x82, 	/* 10EC0 */
+	0xC8,  0x24,  0xFE,  0x97,  0x92,  0x06,  0xFC,  0x42,  0x0A,  0x50,  0x28,  0x83,  0xFE,  0x60,  0x4A,  0xF4, 	/* 10ED0 */
+	0x29,  0x42,  0xF4,  0xC0,  0x44,  0x0C,  0x9B,  0x90,  0x05,  0x7C,  0x20,  0x86,  0x10,  0xAF,  0xE2,  0x10, 	/* 10EE0 */
+	0x31,  0x06,  0x30,  0xAF,  0xE2,  0xAA,  0x2A,  0xAD,  0xFF,  0x9C,  0x91,  0x06,  0xFC,  0x41,  0x0A,  0xFC, 	/* 10EF0 */
+	0x21,  0x03,  0xFE,  0x69,  0x4A,  0x94,  0x2F,  0xC2,  0x84,  0xC8,  0x44,  0x8C,  0x9D,  0x91,  0x06,  0xFE, 	/* 10F00 */
+	0x44,  0x4A,  0x44,  0x26,  0xA2,  0xB2,  0x71,  0x0A,  0xFE,  0x21,  0x02,  0x10,  0xC1,  0x04,  0x10,  0x9F, 	/* 10F10 */
+	0x9A,  0x26,  0x52,  0x45,  0x4A,  0x00,  0x27,  0xC2,  0x54,  0x67,  0xCA,  0x54,  0x27,  0xC2,  0x95,  0x29, 	/* 10F20 */
+	0x3D,  0x11,  0xA5,  0x90,  0x06,  0xFC,  0x4A,  0x4A,  0xFC,  0x2A,  0x42,  0xFC,  0x60,  0x0B,  0xFE,  0x25, 	/* 10F30 */
+	0x42,  0x48,  0xC7,  0x45,  0x82,  0xA9,  0x90,  0x06,  0xFC,  0x48,  0x4A,  0xFC,  0x28,  0x42,  0xFC,  0x65, 	/* 10F40 */
+	0x0A,  0xFE,  0x31,  0x02,  0x7C,  0xC1,  0x05,  0xFE,  0xAA,  0x92,  0x05,  0xFC,  0x22,  0x86,  0x30,  0xBF, 	/* 10F50 */
+	0xE2,  0x20,  0x67,  0xCA,  0xC4,  0x37,  0xC2,  0x44,  0x24,  0x4C,  0x7C,  0xAB,  0x94,  0x45,  0xFE,  0x24, 	/* 10F60 */
+	0x86,  0x48,  0xAF,  0xE2,  0x92,  0x39,  0x26,  0xFE,  0xA9,  0x22,  0x92,  0x2F,  0xEC,  0x00,  0xAE,  0x10, 	/* 10F70 */
+	0x8F,  0xCC,  0x10,  0xAF,  0xC8,  0xCF,  0xEB,  0x48,  0xFC,  0x89,  0x54,  0xFD,  0x49,  0x52,  0x96,  0x29, 	/* 10F80 */
+	0x41,  0xAF,  0x91,  0x06,  0x92,  0x49,  0x2A,  0xFE,  0x20,  0x03,  0xFE,  0x61,  0x0A,  0xFE,  0x2A,  0xA2, 	/* 10F90 */
+	0xAA,  0xCA,  0xA4,  0x86,  0xB4,  0x94,  0x06,  0x7C,  0x44,  0x4A,  0xFE,  0x3A,  0x02,  0xBE,  0x6C,  0x8A, 	/* 10FA0 */
+	0xC8,  0x2B,  0xE2,  0x88,  0xC9,  0x44,  0xA2,  0xB6,  0x94,  0x46,  0x28,  0x4F,  0xEA,  0x28,  0x2F,  0xE2, 	/* 10FB0 */
+	0xAA,  0x6A,  0xAA,  0xCE,  0x28,  0x22,  0xFE,  0x28,  0x2C,  0xFE,  0xB7,  0x44,  0x82,  0x8C,  0xFE,  0xA2, 	/* 10FC0 */
+	0x88,  0xFF,  0xEB,  0x48,  0xB4,  0x8D,  0xC8,  0x85,  0x4F,  0xD4,  0x86,  0x2F,  0xC1,  0xBE,  0x97,  0xC6, 	/* 10FD0 */
+	0x44,  0x45,  0xCA,  0x54,  0x3F,  0xF3,  0x7D,  0x64,  0x5A,  0x7C,  0x24,  0x42,  0x7C,  0xC4,  0x44,  0x4C, 	/* 10FE0 */
+	0xBF,  0x91,  0x06,  0xFE,  0x41,  0x0B,  0xFF,  0x27,  0xC2,  0x44,  0x67,  0xCA,  0x32,  0x25,  0x23,  0xCC, 	/* 10FF0 */
+	0x25,  0x4C,  0xE2,  0x84,  0x96,  0x45,  0x06,  0x2F,  0x56,  0x04,  0xAE,  0xF2,  0x04,  0x2E,  0x46,  0x04, 	/* 11000 */
+	0xAE,  0xC2,  0xAA,  0x2F,  0x2C,  0x21,  0x85,  0x90,  0x05,  0x7E,  0x2C,  0x86,  0xBE,  0xAA,  0xA2,  0xEA, 	/* 11010 */
+	0x38,  0xA6,  0xEA,  0xAA,  0xA2,  0xAE,  0x2E,  0x8C,  0x08,  0x8E,  0x50,  0xE5,  0x72,  0x70,  0xC1,  0x70, 	/* 11020 */
+	0xFF,  0xE5,  0x48,  0x51,  0x89,  0x48,  0xFF,  0xE0,  0xA0,  0x39,  0x8C,  0x06,  0x8F,  0x92,  0x86,  0xFE, 	/* 11030 */
+	0x42,  0x8A,  0x7C,  0x34,  0x42,  0xFC,  0x67,  0xCA,  0x10,  0x2F,  0xE2,  0x30,  0xC4,  0x85,  0x86,  0x97, 	/* 11040 */
+	0x9F,  0xF6,  0x80,  0x4D,  0x4A,  0xA8,  0x2F,  0xF2,  0xA5,  0x6D,  0x4A,  0xD4,  0x2F,  0x62,  0xA6,  0xD2, 	/* 11050 */
+	0x95,  0x49,  0xA3,  0x25,  0x09,  0x54,  0x49,  0x2F,  0x90,  0xAF,  0xEF,  0x90,  0xA9,  0x0F,  0x98,  0x02, 	/* 11060 */
+	0x8F,  0xA4,  0x8C,  0x4F,  0x82,  0xA8,  0x9F,  0xE6,  0xAA,  0x4F,  0xEA,  0x80,  0x2F,  0xE3,  0x22,  0x6F, 	/* 11070 */
+	0xAA,  0xAA,  0x2F,  0xA2,  0x2A,  0xC3,  0xA5,  0xCC,  0xAA,  0x91,  0x06,  0x28,  0x47,  0xCB,  0x83,  0x2F, 	/* 11080 */
+	0xE2,  0xD6,  0x6B,  0xAA,  0xFE,  0x24,  0x42,  0x7C,  0xC4,  0x44,  0x7C,  0xB0,  0x91,  0x06,  0xFF,  0x49, 	/* 11090 */
+	0x1A,  0xAA,  0x32,  0x52,  0x1C,  0x6F,  0xEA,  0xAA,  0x3F,  0xF2,  0x10,  0xC1,  0x04,  0x30,  0xB2,  0x94, 	/* 110A0 */
+	0x87,  0xFE,  0x45,  0x0A,  0x88,  0x2F,  0xE3,  0x90,  0x6F,  0xEA,  0x90,  0x2F,  0xE2,  0x48,  0xC3,  0x05, 	/* 110B0 */
+	0xCE,  0xB5,  0x95,  0x46,  0xA8,  0x45,  0x4A,  0xFE,  0x2A,  0xA2,  0x92,  0x6A,  0xAA,  0xFE,  0x2D,  0xA2, 	/* 110C0 */
+	0xB6,  0xCD,  0xB5,  0xB1,  0xB8,  0xEE,  0x8A,  0xAC,  0xEE,  0xA7,  0xC8,  0x57,  0xE7,  0xC8,  0x54,  0x87, 	/* 110D0 */
+	0xC8,  0x00,  0xCF,  0xD4,  0x46,  0x27,  0xC1,  0xBA,  0xA8,  0x06,  0x9E,  0x5E,  0xAC,  0x8A,  0x7F,  0x66, 	/* 110E0 */
+	0xBE,  0x7F,  0x2C,  0x9E,  0x5D,  0x26,  0xBE,  0x48,  0xCC,  0xB2,  0xBB,  0x38,  0x82,  0x0C,  0x7C,  0xA5, 	/* 110F0 */
+	0x3E,  0x5C,  0x84,  0x08,  0x5C,  0x85,  0x4C,  0x7D,  0x46,  0x52,  0xBE,  0x2A,  0x41,  0x84,  0x04,  0x00, 	/* 11100 */
+	0x40,  0xFF,  0xE0,  0x80,  0x09,  0x01,  0x10,  0x72,  0x00,  0xC0,  0x05,  0x00,  0x88,  0x1F,  0xCE,  0x04, 	/* 11110 */
+	0x87,  0x04,  0x0F,  0xFE,  0x04,  0x04,  0x92,  0x26,  0x42,  0x94,  0x5F,  0x20,  0x50,  0xFF,  0xE0,  0x40, 	/* 11120 */
+	0x04,  0x00,  0x40,  0x89,  0x00,  0x07,  0xFC,  0x04,  0x00,  0x40,  0x04,  0x00,  0x40,  0x3F,  0x80,  0x40, 	/* 11130 */
+	0x05,  0x00,  0x48,  0x04,  0x8F,  0xFE,  0x8B,  0x00,  0x07,  0xFC,  0x04,  0x00,  0x40,  0x04,  0x00,  0x40, 	/* 11140 */
+	0x3F,  0x80,  0x40,  0x04,  0x00,  0x40,  0x04,  0x0F,  0xFE,  0x96,  0x02,  0x0F,  0xA0,  0x23,  0xC2,  0x24, 	/* 11150 */
+	0xF4,  0x42,  0x48,  0x28,  0x82,  0x18,  0x39,  0x4C,  0x24,  0x04,  0x21,  0x82,  0xA9,  0x00,  0x00,  0xFC, 	/* 11160 */
+	0xF0,  0x02,  0x00,  0x20,  0x0F,  0xFE,  0x25,  0x02,  0x50,  0x35,  0x0C,  0x90,  0x11,  0x22,  0x0E,  0xB2, 	/* 11170 */
+	0x02,  0x00,  0x20,  0xF3,  0x02,  0x48,  0x2F,  0xCF,  0x02,  0x2F,  0xC2,  0x24,  0x2A,  0x43,  0x38,  0xC2, 	/* 11180 */
+	0x00,  0x20,  0xB3,  0x02,  0x80,  0x2C,  0xF2,  0xA2,  0x4E,  0x27,  0x82,  0xC8,  0xF4,  0x82,  0x48,  0x24, 	/* 11190 */
+	0x43,  0x46,  0xC4,  0x60,  0x42,  0xBB,  0x01,  0x00,  0x10,  0xFF,  0xE2,  0x94,  0x29,  0x0F,  0xFC,  0x2A, 	/* 111A0 */
+	0x42,  0xA4,  0x39,  0x8D,  0x18,  0x12,  0x42,  0xC2,  0x80,  0x01,  0x00,  0x20,  0xF7,  0xE2,  0x42,  0x24, 	/* 111B0 */
+	0x22,  0x42,  0xF7,  0xE2,  0x42,  0x24,  0x23,  0x42,  0xC4,  0x20,  0x7E,  0x82,  0x00,  0x00,  0xFE,  0xF0, 	/* 111C0 */
+	0x42,  0x74,  0x25,  0x42,  0x54,  0xF5,  0x42,  0x74,  0x20,  0x43,  0x04,  0xC0,  0x40,  0x0C,  0x88,  0x08, 	/* 111D0 */
+	0x00,  0x80,  0xE8,  0xE5,  0xEA,  0x4A,  0xA4,  0xAA,  0xEA,  0xA4,  0xAA,  0x4A,  0xA7,  0x2A,  0x92,  0xE2, 	/* 111E0 */
+	0x60,  0x8A,  0x00,  0x0F,  0xFE,  0x2A,  0xA2,  0xAA,  0xFA,  0xA2,  0xAA,  0x2F,  0xF2,  0xAA,  0x3A,  0xAC, 	/* 111F0 */
+	0xAA,  0x0A,  0xA0,  0x86,  0x8D,  0x01,  0x0F,  0x90,  0x22,  0x82,  0x44,  0xF8,  0xA2,  0x31,  0x2C,  0x42, 	/* 11200 */
+	0x1A,  0x36,  0x4E,  0x08,  0x03,  0x00,  0xC0,  0x8E,  0x04,  0x0F,  0x40,  0x27,  0xE2,  0x90,  0x31,  0x0F, 	/* 11210 */
+	0x18,  0x25,  0x42,  0x54,  0x39,  0x2D,  0x12,  0x01,  0x00,  0x30,  0x9E,  0x02,  0x00,  0x3C,  0xF2,  0x42, 	/* 11220 */
+	0x64,  0x29,  0x82,  0x14,  0xF2,  0x22,  0xFD,  0x22,  0x43,  0x24,  0xC2,  0x40,  0x3C,  0xA0,  0x01,  0x0F, 	/* 11230 */
+	0x50,  0x25,  0x02,  0x7C,  0x29,  0x0F,  0x90,  0x2F,  0xE2,  0x18,  0x33,  0x4C,  0x52,  0x19,  0x00,  0x10, 	/* 11240 */
+	0xA5,  0x00,  0x00,  0xFE,  0xF4,  0x42,  0x44,  0x27,  0xC2,  0x44,  0xF7,  0xC2,  0x44,  0x24,  0x43,  0x7C, 	/* 11250 */
+	0xDC,  0x40,  0x04,  0xAA,  0x01,  0x0F,  0x10,  0x2F,  0xC2,  0x10,  0xF1,  0x02,  0xFE,  0x21,  0x02,  0x10, 	/* 11260 */
+	0x3F,  0xCE,  0x10,  0x01,  0x01,  0xFE,  0xAD,  0x02,  0x0F,  0x3E,  0x2A,  0x82,  0xA8,  0x2A,  0x8F,  0xBE, 	/* 11270 */
+	0x2A,  0x82,  0xA8,  0x22,  0x83,  0x48,  0xE4,  0x80,  0x9E,  0xAE,  0x1F,  0xEF,  0x02,  0x57,  0xE5,  0x12, 	/* 11280 */
+	0x57,  0xEF,  0x56,  0x55,  0x65,  0x56,  0x75,  0x69,  0x12,  0x21,  0x12,  0x11,  0xB1,  0x02,  0x40,  0x94, 	/* 11290 */
+	0xF5,  0x42,  0x48,  0x21,  0x02,  0x20,  0xFF,  0xE2,  0x48,  0x24,  0x83,  0xF0,  0xC2,  0x80,  0xC4,  0xB8, 	/* 112A0 */
+	0x00,  0x00,  0xFE,  0xF1,  0x02,  0x7C,  0x22,  0x42,  0x24,  0xFF,  0xF2,  0x00,  0x27,  0xE3,  0x42,  0xC4, 	/* 112B0 */
+	0x20,  0x7E,  0xBE,  0x07,  0xEF,  0xC2,  0x27,  0xE2,  0x42,  0x27,  0xEF,  0xC2,  0x27,  0xE2,  0x28,  0x32, 	/* 112C0 */
+	0x8C,  0x49,  0x08,  0x93,  0x07,  0x83,  0x01,  0x0F,  0x18,  0x21,  0x42,  0xFE,  0xF1,  0x02,  0x92,  0x27, 	/* 112D0 */
+	0xC2,  0x38,  0x35,  0x4E,  0x93,  0x01,  0x00,  0x30,  0x85,  0x01,  0x00,  0x20,  0xF7,  0xC2,  0x44,  0x27, 	/* 112E0 */
+	0xC2,  0x44,  0xF7,  0xC2,  0x52,  0x25,  0x43,  0x48,  0xC7,  0x40,  0xC2,  0x86,  0x00,  0x00,  0xFE,  0xF9, 	/* 112F0 */
+	0x22,  0xFE,  0x29,  0x2F,  0x92,  0x2F,  0xE2,  0x10,  0x27,  0xC3,  0x10,  0xC1,  0x01,  0xFF,  0x89,  0x02, 	/* 11300 */
+	0x0F,  0xFC,  0x22,  0x02,  0x48,  0x3F,  0xCF,  0x04,  0x2A,  0x82,  0xA8,  0x3A,  0x8C,  0xAA,  0x12,  0xA2, 	/* 11310 */
+	0x06,  0xA2,  0x00,  0x00,  0xFE,  0xF1,  0x02,  0x30,  0x2C,  0xAF,  0x1C,  0x22,  0x82,  0xCC,  0x31,  0xAC, 	/* 11320 */
+	0x69,  0x18,  0x80,  0x30,  0xA5,  0x01,  0x00,  0x1C,  0xF1,  0x02,  0xFE,  0x2A,  0x22,  0xFC,  0xFA,  0x02, 	/* 11330 */
+	0xBE,  0x2A,  0x83,  0x28,  0xD4,  0xA2,  0x86,  0xB2,  0x02,  0x80,  0x28,  0xFE,  0xE2,  0x28,  0x22,  0x82, 	/* 11340 */
+	0xEE,  0xF2,  0x82,  0x28,  0x2E,  0xF3,  0x28,  0xC4,  0x80,  0x88,  0xB3,  0x04,  0x4E,  0x44,  0x5F,  0xF4, 	/* 11350 */
+	0x44,  0x4E,  0xEE,  0xEE,  0x4D,  0xD5,  0x54,  0x55,  0x46,  0x44,  0x84,  0x40,  0x44,  0xB4,  0xFB,  0xE2, 	/* 11360 */
+	0x08,  0xFB,  0xE2,  0x08,  0xF7,  0xE0,  0xE0,  0x31,  0x8D,  0xF6,  0x00,  0x03,  0xF8,  0x01,  0x00,  0x60, 	/* 11370 */
+	0xB5,  0x00,  0x0F,  0xBE,  0x20,  0x8F,  0xBE,  0x20,  0x8F,  0xBE,  0x22,  0x43,  0xB8,  0x22,  0x02,  0x22, 	/* 11380 */
+	0x3E,  0x2C,  0x1E,  0xB6,  0xFB,  0xE2,  0x08,  0xFB,  0xE2,  0x08,  0xFB,  0xE0,  0x00,  0x7F,  0xC4,  0x44, 	/* 11390 */
+	0x7F,  0xC4,  0x00,  0x40,  0x23,  0xFE,  0xBA,  0x08,  0x80,  0x48,  0xF3,  0xE2,  0x88,  0x24,  0x82,  0x7E, 	/* 113A0 */
+	0xF0,  0x82,  0x48,  0x29,  0x43,  0x92,  0xD3,  0xE1,  0x02,  0xBF,  0x0F,  0xEF,  0x92,  0x27,  0xC2,  0x10, 	/* 113B0 */
+	0x27,  0xCF,  0x54,  0x27,  0xC2,  0x54,  0x37,  0xCC,  0x10,  0x0F,  0xE0,  0x10,  0x81,  0x00,  0x00,  0xFE, 	/* 113C0 */
+	0xF8,  0x22,  0xBA,  0x28,  0x22,  0xBA,  0xF0,  0x02,  0x7C,  0x24,  0x43,  0x7C,  0xC4,  0x40,  0x7C,  0x95, 	/* 113D0 */
+	0x00,  0x00,  0xFE,  0xFA,  0x22,  0xEE,  0x28,  0x0F,  0x9E,  0x2E,  0x22,  0x8A,  0x38,  0xAC,  0xE4,  0x08, 	/* 113E0 */
+	0xA0,  0x91,  0x99,  0x05,  0x40,  0x54,  0xFA,  0x82,  0x54,  0x25,  0x42,  0xFE,  0xF8,  0xA2,  0xEA,  0x29, 	/* 113F0 */
+	0x23,  0xAA,  0xCC,  0x20,  0xFE,  0x9A,  0x04,  0x0F,  0x5E,  0x45,  0x25,  0xF2,  0x45,  0xEE,  0x52,  0x5F, 	/* 11400 */
+	0x25,  0x3E,  0x73,  0x2D,  0xF2,  0x02,  0x20,  0x46,  0x9B,  0x04,  0x8F,  0xFE,  0x44,  0x84,  0x58,  0x4F, 	/* 11410 */
+	0xCF,  0x94,  0x49,  0x45,  0xFE,  0x71,  0x0C,  0x28,  0x04,  0x41,  0x82,  0x9C,  0x01,  0x00,  0x28,  0xF4, 	/* 11420 */
+	0x42,  0xBA,  0x20,  0x02,  0xEA,  0xFA,  0xA2,  0xF4,  0x2B,  0x43,  0xF4,  0xCA,  0xA0,  0xAA,  0x9E,  0x01, 	/* 11430 */
+	0x00,  0x92,  0xF9,  0x22,  0xFE,  0x20,  0x0F,  0xFE,  0x24,  0x02,  0xFE,  0x3A,  0xAC,  0xAA,  0x0A,  0xA0, 	/* 11440 */
+	0x86,  0x9F,  0x00,  0x0F,  0xBE,  0x20,  0x8F,  0xBE,  0x20,  0x8F,  0xBE,  0x09,  0x01,  0x50,  0x52,  0x45, 	/* 11450 */
+	0x42,  0x98,  0xA6,  0xF8,  0xA0,  0x04,  0x0F,  0x9E,  0x2A,  0xA2,  0xAA,  0x2E,  0xAF,  0x92,  0x22,  0xC2, 	/* 11460 */
+	0xFE,  0x39,  0x2C,  0xFE,  0x09,  0x20,  0xFE,  0xA3,  0x01,  0x00,  0x54,  0xF9,  0x22,  0x7C,  0x24,  0x42, 	/* 11470 */
+	0x7C,  0xF4,  0x42,  0x7C,  0x24,  0x43,  0x7C,  0xC4,  0xC1,  0x82,  0xA4,  0x00,  0x80,  0x1E,  0xF2,  0xA2, 	/* 11480 */
+	0xE4,  0x21,  0x8F,  0x60,  0x27,  0xE2,  0x90,  0x3F,  0xF2,  0x92,  0xC9,  0x20,  0xFE,  0xA9,  0x11,  0x05, 	/* 11490 */
+	0x54,  0x2A,  0x84,  0x44,  0xFF,  0xE8,  0x02,  0x7F,  0xC0,  0x40,  0x3F,  0xC0,  0x50,  0x04,  0x8F,  0xFE, 	/* 114A0 */
+	0xAA,  0x00,  0x00,  0xFE,  0xF9,  0x02,  0xFC,  0x29,  0x02,  0xFC,  0xF9,  0x02,  0xFE,  0x20,  0x23,  0xAA, 	/* 114B0 */
+	0xCA,  0x21,  0x0C,  0xAF,  0x04,  0x00,  0x5C,  0xFF,  0x42,  0xB4,  0x2F,  0x8F,  0xB4,  0x2F,  0x22,  0x92, 	/* 114C0 */
+	0x3D,  0x2C,  0xBC,  0x0F,  0x03,  0x90,  0xB0,  0x01,  0x00,  0x20,  0xFF,  0xC2,  0xA4,  0x2F,  0xCF,  0xA4, 	/* 114D0 */
+	0x2F,  0xC2,  0x54,  0x35,  0xAC,  0x9E,  0x11,  0x26,  0x0E,  0xB3,  0x04,  0x40,  0x28,  0xFF,  0xE2,  0x10, 	/* 114E0 */
+	0x27,  0xCF,  0x10,  0x2F,  0xE2,  0x40,  0x37,  0xEC,  0x90,  0x11,  0x02,  0xFE,  0xB6,  0x00,  0xC0,  0xF2, 	/* 114F0 */
+	0xF1,  0x22,  0x94,  0x24,  0x82,  0xFE,  0xF1,  0x02,  0xFE,  0x21,  0x03,  0x92,  0xC9,  0x20,  0xFE,  0xBE, 	/* 11500 */
+	0x02,  0x80,  0xFE,  0xF2,  0x82,  0xFE,  0x29,  0x22,  0xFE,  0xF1,  0x02,  0xFC,  0x21,  0x03,  0xFC,  0xC1, 	/* 11510 */
+	0x01,  0xFE,  0x83,  0x02,  0x0F,  0xFE,  0x55,  0x45,  0x24,  0x55,  0x4F,  0xFC,  0x42,  0x05,  0xFE,  0x55, 	/* 11520 */
+	0x2F,  0x7A,  0x1C,  0xA1,  0x06,  0x8B,  0x01,  0x00,  0xFE,  0xF2,  0x82,  0xFE,  0x24,  0x42,  0x7C,  0xF4, 	/* 11530 */
+	0x42,  0x7C,  0x21,  0x03,  0xFE,  0xC1,  0x00,  0x10,  0x9E,  0x02,  0x80,  0xAA,  0xFF,  0xF2,  0x28,  0x2F, 	/* 11540 */
+	0xE2,  0x10,  0xFF,  0xE2,  0x10,  0x2F,  0xF3,  0x28,  0xC4,  0x41,  0x82,  0xA2,  0x1F,  0xCE,  0x50,  0x5D, 	/* 11550 */
+	0xC5,  0x54,  0x55,  0x45,  0xDC,  0xE5,  0x05,  0xFC,  0x52,  0x47,  0xFC,  0x92,  0x41,  0xFC,  0xA7,  0x01, 	/* 11560 */
+	0x07,  0xFC,  0x4A,  0x87,  0xFE,  0x41,  0x0B,  0xBC,  0x29,  0x0F,  0xFE,  0x04,  0x07,  0xFC,  0x04,  0x8F, 	/* 11570 */
+	0xFE,  0xB0,  0x1F,  0xCF,  0x54,  0x3F,  0xC2,  0x00,  0xFF,  0xE2,  0x84,  0x2F,  0xC3,  0x64,  0xCD,  0x81, 	/* 11580 */
+	0x48,  0x24,  0x60,  0x40,  0xBD,  0xFF,  0xE4,  0x44,  0xFF,  0xEC,  0xE6,  0xB5,  0xAC,  0xE6,  0xB5,  0xAC, 	/* 11590 */
+	0xE6,  0x04,  0x07,  0xFC,  0x04,  0x8F,  0xFE,  0x8A,  0x03,  0xCF,  0x48,  0x2F,  0xE2,  0xAA,  0x2F,  0xEF, 	/* 115A0 */
+	0x7C,  0x24,  0x42,  0xFC,  0x34,  0x4C,  0x78,  0x19,  0x80,  0xE6,  0x8F,  0x04,  0x81,  0xFE,  0xFA,  0x82, 	/* 115B0 */
+	0xAE,  0x3F,  0x22,  0xEE,  0xFA,  0x82,  0xEE,  0x2A,  0x83,  0xEE,  0xCA,  0x90,  0xA7,  0x94,  0x0E,  0xE0, 	/* 115C0 */
+	0xAA,  0xFE,  0xE2,  0xAA,  0x2E,  0xE2,  0x44,  0xEA,  0xA3,  0xFE,  0x24,  0x83,  0xF0,  0xC2,  0x80,  0xC4, 	/* 115D0 */
+	0x9C,  0x00,  0xC3,  0xF0,  0x25,  0x02,  0x50,  0x25,  0x02,  0x50,  0x24,  0x82,  0x68,  0x25,  0x84,  0x74, 	/* 115E0 */
+	0x79,  0x48,  0x02,  0xA0,  0x20,  0x6F,  0xF8,  0x25,  0x45,  0x54,  0xFD,  0x40,  0x54,  0xFD,  0x44,  0x54, 	/* 115F0 */
+	0x75,  0x49,  0x5C,  0x17,  0x66,  0x8A,  0xA2,  0xF8,  0xE2,  0x74,  0xFD,  0x4A,  0xD4,  0xFD,  0x40,  0x54, 	/* 11600 */
+	0x75,  0x40,  0x54,  0xFD,  0xC7,  0x54,  0xA9,  0xE3,  0x61,  0xA3,  0x42,  0x85,  0xC8,  0xFB,  0xEB,  0xB4, 	/* 11610 */
+	0x5A,  0xCF,  0xBE,  0x5A,  0x8F,  0xA8,  0x5F,  0xE5,  0xA8,  0x5F,  0x8A,  0x08,  0xA6,  0x00,  0x0F,  0xFC, 	/* 11620 */
+	0x10,  0x01,  0x00,  0x1F,  0x01,  0x10,  0x19,  0x01,  0x50,  0x21,  0x22,  0x72,  0x39,  0x2C,  0x0E,  0xA7, 	/* 11630 */
+	0x01,  0x0F,  0x90,  0x41,  0x04,  0x10,  0x7F,  0xE4,  0x90,  0x69,  0x05,  0x90,  0x49,  0x05,  0x92,  0x68, 	/* 11640 */
+	0x2C,  0x7E,  0xA9,  0x00,  0x4F,  0x98,  0x47,  0x04,  0x10,  0x79,  0x04,  0xFE,  0x69,  0x05,  0x90,  0x49, 	/* 11650 */
+	0x05,  0x92,  0x68,  0x2C,  0x7E,  0xAE,  0x12,  0x01,  0x10,  0x28,  0x8C,  0xA6,  0x13,  0x03,  0xD0,  0x00, 	/* 11660 */
+	0x0F,  0xFE,  0x15,  0x01,  0x30,  0x2D,  0x2F,  0x0E,  0xB0,  0x01,  0x8F,  0xA8,  0x42,  0x44,  0x24,  0x7C, 	/* 11670 */
+	0x24,  0xFC,  0x69,  0x45,  0x94,  0x4A,  0x45,  0xD8,  0x68,  0x2C,  0x7E,  0xB1,  0x00,  0x4F,  0x98,  0x47, 	/* 11680 */
+	0x04,  0x10,  0x79,  0xE4,  0xF0,  0x69,  0xE5,  0xF0,  0x49,  0x25,  0x8E,  0x68,  0x0C,  0x7E,  0xB2,  0x01, 	/* 11690 */
+	0x0F,  0x9C,  0x47,  0x04,  0x10,  0x7D,  0x44,  0xD4,  0x6D,  0x45,  0xFC,  0x49,  0x25,  0x8E,  0x68,  0x0C, 	/* 116A0 */
+	0x7E,  0xB6,  0x44,  0x02,  0xBE,  0xFD,  0x02,  0x90,  0x29,  0xC2,  0xA4,  0xFF,  0x42,  0xAC,  0x2A,  0x42, 	/* 116B0 */
+	0xA5,  0x4B,  0xB8,  0xE1,  0xB7,  0x04,  0x0E,  0x7E,  0x09,  0x42,  0x10,  0xC6,  0x81,  0x86,  0x00,  0x0F, 	/* 116C0 */
+	0xFE,  0x15,  0x01,  0x10,  0x2D,  0x2F,  0x0E,  0xB8,  0x00,  0x0F,  0xFE,  0x40,  0x84,  0x10,  0x7B,  0xC4, 	/* 116D0 */
+	0xA4,  0x6B,  0xC5,  0xA4,  0x4A,  0x45,  0xBC,  0x68,  0x2C,  0x7E,  0x83,  0x79,  0x02,  0x54,  0xFD,  0x43, 	/* 116E0 */
+	0x10,  0x6A,  0x8A,  0x44,  0xFF,  0xE0,  0x80,  0x0F,  0x81,  0x2A,  0x3F,  0xAE,  0x06,  0x84,  0x00,  0x0F, 	/* 116F0 */
+	0xFE,  0x52,  0x0F,  0xBC,  0xAA,  0x4A,  0xA4,  0xFB,  0x42,  0x2C,  0xFA,  0x42,  0x24,  0x3A,  0xDC,  0x73, 	/* 11700 */
+	0x85,  0x00,  0x0F,  0xBE,  0x42,  0x04,  0x3E,  0x7A,  0xA4,  0xBE,  0x6A,  0xA5,  0xBE,  0x4A,  0x84,  0xFE, 	/* 11710 */
+	0x74,  0x8C,  0xBE,  0x8C,  0x00,  0x0F,  0xFE,  0xBA,  0x0A,  0xBC,  0xBA,  0x48,  0x24,  0xFF,  0x4B,  0x6C, 	/* 11720 */
+	0xB6,  0x4F,  0xE4,  0x82,  0xDF,  0xF3,  0x8D,  0x11,  0x0F,  0xFE,  0x11,  0x07,  0xFC,  0x4A,  0x4F,  0xFE, 	/* 11730 */
+	0x80,  0x23,  0xFC,  0x19,  0x01,  0x50,  0x2F,  0x2F,  0x0E,  0x8E,  0x20,  0x0F,  0xFE,  0x22,  0x0F,  0xBC, 	/* 11740 */
+	0xAA,  0x4F,  0xA4,  0xAB,  0x4F,  0xAC,  0x16,  0x4F,  0xA4,  0x52,  0xE3,  0x72,  0x91,  0x88,  0x05,  0x7E, 	/* 11750 */
+	0xFA,  0x0A,  0xBC,  0xFA,  0x4A,  0xA4,  0xFB,  0x45,  0x2C,  0x72,  0x45,  0x44,  0x75,  0xC4,  0xE6,  0x93, 	/* 11760 */
+	0x79,  0x04,  0xFC,  0x7A,  0x84,  0x7E,  0x79,  0x0A,  0xBC,  0x39,  0x0F,  0xFE,  0x19,  0x01,  0x50,  0x2F, 	/* 11770 */
+	0x2F,  0x0E,  0x95,  0x04,  0x0F,  0xFE,  0x2A,  0x81,  0x3E,  0x7A,  0x81,  0x3E,  0x20,  0x0F,  0xFE,  0x19, 	/* 11780 */
+	0x01,  0x50,  0x2F,  0x2F,  0x0E,  0x98,  0x10,  0x81,  0x08,  0x10,  0x8F,  0xFE,  0x10,  0x81,  0x08,  0x1F, 	/* 11790 */
+	0x81,  0x08,  0x10,  0x81,  0x08,  0x10,  0x81,  0xF8,  0x9A,  0x21,  0x0F,  0xFC,  0x21,  0x03,  0xF0,  0x21, 	/* 117A0 */
+	0x03,  0xF0,  0x21,  0x0F,  0xFE,  0x49,  0x07,  0x1C,  0x40,  0x03,  0xFC,  0x9C,  0x1A,  0x4E,  0x24,  0x22, 	/* 117B0 */
+	0x42,  0x7E,  0xFA,  0x42,  0x24,  0x22,  0x47,  0xBC,  0x4A,  0x44,  0xA4,  0x4A,  0x47,  0xBC,  0x9E,  0x44, 	/* 117C0 */
+	0x42,  0x48,  0xFF,  0xEB,  0xFA,  0xA0,  0xA3,  0xF8,  0x11,  0x0F,  0xFE,  0x11,  0x01,  0xF0,  0x11,  0x01, 	/* 117D0 */
+	0xF0,  0x9F,  0x04,  0x02,  0x40,  0x24,  0x07,  0xFC,  0x44,  0x08,  0x40,  0x04,  0x03,  0xF8,  0x04,  0x00, 	/* 117E0 */
+	0x40,  0x04,  0x0F,  0xFE,  0xA3,  0x02,  0x07,  0xFE,  0x10,  0x80,  0x90,  0x3F,  0xE2,  0xA0,  0x2F,  0xC3, 	/* 117F0 */
+	0x20,  0x4F,  0xC4,  0x20,  0x82,  0x03,  0xFE,  0xA5,  0x10,  0x05,  0x7E,  0x55,  0x27,  0xFE,  0x95,  0x21, 	/* 11800 */
+	0x7E,  0x79,  0x01,  0x7E,  0x11,  0x23,  0xA2,  0xC2,  0x20,  0xCC,  0xA6,  0x02,  0x8F,  0xA8,  0x23,  0xEF, 	/* 11810 */
+	0xA8,  0xAC,  0x8F,  0xBE,  0xA8,  0x8F,  0x88,  0x67,  0xE2,  0x00,  0x58,  0x08,  0x7F,  0xA8,  0x00,  0x03, 	/* 11820 */
+	0xFE,  0x22,  0x22,  0x22,  0x3F,  0xE2,  0x22,  0x22,  0x23,  0xFE,  0x22,  0x22,  0x22,  0x42,  0x28,  0x26, 	/* 11830 */
+	0xAB,  0x04,  0x80,  0x44,  0xFF,  0xE0,  0x40,  0x7F,  0xC4,  0x44,  0x7F,  0xC4,  0x44,  0x7F,  0xC4,  0x44, 	/* 11840 */
+	0x44,  0x44,  0x4C,  0xAC,  0x00,  0x03,  0xF8,  0x19,  0x00,  0x60,  0x7F,  0xC4,  0x44,  0x7F,  0xC4,  0x44, 	/* 11850 */
+	0x7F,  0xC4,  0x44,  0x44,  0x44,  0x4C,  0xB0,  0x00,  0x07,  0xFC,  0x44,  0x44,  0x44,  0x44,  0x47,  0xFC, 	/* 11860 */
+	0x44,  0x44,  0x44,  0x44,  0x44,  0x44,  0x7F,  0xC0,  0x00,  0xB1,  0x04,  0x00,  0x40,  0x04,  0x07,  0xFC, 	/* 11870 */
+	0x44,  0x44,  0x44,  0x44,  0x47,  0xFC,  0x44,  0x44,  0x44,  0x44,  0x47,  0xFC,  0xB2,  0x00,  0x07,  0xFC, 	/* 11880 */
+	0x44,  0x44,  0x44,  0x7F,  0xC4,  0x44,  0x44,  0x47,  0xFC,  0x04,  0x00,  0x40,  0x04,  0x00,  0x40,  0xB3, 	/* 11890 */
+	0x04,  0x00,  0x40,  0x7F,  0xC4,  0x44,  0x7F,  0xC4,  0x44,  0x44,  0x47,  0xFC,  0x04,  0x00,  0x40,  0x04, 	/* 118A0 */
+	0x00,  0x40,  0xB7,  0x00,  0x03,  0xFC,  0x24,  0x43,  0xFC,  0x24,  0x43,  0xFC,  0x04,  0x07,  0xFE,  0x04, 	/* 118B0 */
+	0x20,  0x42,  0x18,  0x26,  0x0C,  0xB8,  0x10,  0x01,  0x00,  0x3F,  0xE2,  0x02,  0x7F,  0xAA,  0x4A,  0x3F, 	/* 118C0 */
+	0xA2,  0x4A,  0x24,  0xA3,  0xFA,  0x00,  0x40,  0x18,  0xBA,  0x00,  0x0F,  0xC0,  0xA7,  0xEA,  0x48,  0xFC, 	/* 118D0 */
+	0x8A,  0x48,  0xA4,  0x8A,  0x48,  0xFC,  0x80,  0x08,  0x00,  0x80,  0x18,  0xBB,  0x00,  0x0F,  0xFE,  0x04, 	/* 118E0 */
+	0x03,  0xF8,  0xA4,  0xAA,  0x4A,  0xBF,  0xAA,  0x4A,  0xA4,  0xAB,  0xFA,  0x80,  0x2F,  0xFE,  0xBC,  0x3F, 	/* 118F0 */
+	0x82,  0x48,  0x3F,  0x82,  0x48,  0x24,  0x83,  0xF8,  0x00,  0x0F,  0xFE,  0x04,  0x00,  0x40,  0x04,  0x00, 	/* 11900 */
+	0xC0,  0x84,  0x08,  0x44,  0x44,  0x24,  0x82,  0x10,  0x7F,  0xC4,  0x44,  0x44,  0x47,  0xFC,  0x44,  0x44, 	/* 11910 */
+	0x44,  0x44,  0x47,  0xFC,  0x86,  0x10,  0x81,  0x08,  0xFE,  0x80,  0x08,  0x7C,  0x85,  0x48,  0x55,  0x07, 	/* 11920 */
+	0xD8,  0x55,  0x45,  0x52,  0x56,  0x67,  0xFA,  0x89,  0x01,  0x0F,  0x90,  0xAF,  0xCA,  0x90,  0xA9,  0x0F, 	/* 11930 */
+	0xFE,  0xA9,  0x0A,  0x90,  0xAA,  0x8F,  0xA8,  0x04,  0x40,  0x82,  0x8A,  0x02,  0x4F,  0xA4,  0xAF,  0xFA, 	/* 11940 */
+	0xA4,  0xAA,  0x4F,  0xA4,  0xAF,  0xFA,  0xA4,  0xAA,  0x4F,  0xA4,  0x04,  0x40,  0x84,  0x8B,  0x01,  0x0F, 	/* 11950 */
+	0x90,  0xAB,  0xEA,  0xA4,  0xAA,  0x4F,  0xC4,  0xA9,  0x4A,  0x98,  0xA8,  0x8F,  0x98,  0x86,  0x41,  0x82, 	/* 11960 */
+	0x8C,  0x00,  0x03,  0xFC,  0x24,  0x43,  0xFC,  0x24,  0x43,  0xFC,  0x0A,  0x03,  0x18,  0xC9,  0x60,  0x90, 	/* 11970 */
+	0x11,  0x02,  0x10,  0x8D,  0x00,  0x8F,  0x88,  0xA9,  0x4A,  0x94,  0xAA,  0x2F,  0xD5,  0xA9,  0x4A,  0x94, 	/* 11980 */
+	0xAA,  0x4F,  0xA4,  0x04,  0x40,  0x84,  0x8F,  0x00,  0x03,  0xFC,  0x24,  0x43,  0xFC,  0x24,  0x43,  0xFC, 	/* 11990 */
+	0x00,  0x0F,  0xFE,  0x24,  0x42,  0x28,  0x3D,  0x8E,  0x06,  0x91,  0x20,  0x02,  0x7E,  0x25,  0x22,  0xD2, 	/* 119A0 */
+	0x75,  0x26,  0x7E,  0xA5,  0x22,  0x52,  0x35,  0x24,  0xD2,  0x47,  0xE8,  0x40,  0x94,  0x01,  0x00,  0x92, 	/* 119B0 */
+	0xFD,  0x4A,  0x90,  0xAF,  0xEA,  0x90,  0xF9,  0x0A,  0xFE,  0xA9,  0x0F,  0x90,  0x01,  0x00,  0x10,  0x99, 	/* 119C0 */
+	0x18,  0x06,  0x7E,  0x41,  0x25,  0x12,  0x4A,  0x27,  0x42,  0xC8,  0xC3,  0xFC,  0x24,  0x43,  0xFC,  0x24, 	/* 119D0 */
+	0x43,  0xFC,  0x9A,  0x08,  0x01,  0x10,  0x7E,  0x80,  0x44,  0xFF,  0xE0,  0xA0,  0x31,  0x8F,  0xFE,  0x24, 	/* 119E0 */
+	0x83,  0xF8,  0x24,  0x83,  0xF8,  0x9B,  0x00,  0x8F,  0x88,  0xA9,  0x4A,  0xA2,  0xAC,  0x9F,  0x90,  0xAE, 	/* 119F0 */
+	0x4A,  0x88,  0xAB,  0x2F,  0x84,  0x01,  0x80,  0x60,  0x9C,  0x04,  0x0F,  0xFE,  0x09,  0x03,  0x20,  0x14, 	/* 11A00 */
+	0x80,  0xFC,  0xF0,  0x23,  0xFA,  0x24,  0x83,  0xF8,  0x24,  0x83,  0xF8,  0x9D,  0x22,  0x02,  0x20,  0xFB, 	/* 11A10 */
+	0xC0,  0x24,  0xFC,  0x4A,  0xC8,  0xA8,  0x8F,  0x98,  0xA9,  0x4A,  0xA4,  0xFC,  0x20,  0x82,  0xA0,  0x08, 	/* 11A20 */
+	0x03,  0xF8,  0x20,  0x83,  0xF8,  0x20,  0x83,  0xF8,  0x00,  0x07,  0xFC,  0x44,  0x47,  0xFC,  0x44,  0x47, 	/* 11A30 */
+	0xFC,  0xA2,  0x7F,  0xC4,  0x44,  0x7F,  0xC4,  0x44,  0x7F,  0xC2,  0x48,  0xFF,  0xE2,  0x48,  0x7F,  0xC0, 	/* 11A40 */
+	0x40,  0xFF,  0xE0,  0x40,  0xA4,  0x00,  0x8F,  0x88,  0xAF,  0xEA,  0x88,  0xAF,  0xFF,  0x84,  0xAF,  0xEA, 	/* 11A50 */
+	0xC4,  0xAA,  0x4F,  0x84,  0x00,  0x40,  0x0C,  0xA5,  0x01,  0x0F,  0x9C,  0xAA,  0x4A,  0xD4,  0xA8,  0x8F, 	/* 11A60 */
+	0x94,  0xAA,  0x2A,  0xFD,  0xAA,  0x4F,  0xA4,  0x02,  0x40,  0x3C,  0xA6,  0x01,  0x0F,  0x90,  0xAF,  0xCA, 	/* 11A70 */
+	0x90,  0xA9,  0x0F,  0xFE,  0xA9,  0x0A,  0x90,  0xAF,  0xCF,  0x90,  0x01,  0x00,  0xFE,  0xA7,  0x00,  0x03, 	/* 11A80 */
+	0xFC,  0x24,  0x43,  0xFC,  0x24,  0x43,  0xFC,  0x19,  0x06,  0x60,  0x19,  0x8F,  0xFE,  0x10,  0x81,  0xF8, 	/* 11A90 */
+	0xA9,  0x01,  0x0F,  0x90,  0xAF,  0xEA,  0x90,  0xA9,  0x2F,  0xAA,  0xAE,  0xCA,  0xA8,  0xAA,  0x4F,  0xA4, 	/* 11AA0 */
+	0x03,  0xA0,  0x61,  0xAA,  0x01,  0xC7,  0xE8,  0x24,  0x81,  0x50,  0xFF,  0xE0,  0xE0,  0x35,  0x8F,  0xFE, 	/* 11AB0 */
+	0x24,  0x83,  0xF8,  0x24,  0x83,  0xF8,  0xAB,  0x04,  0x03,  0xF8,  0x04,  0x8F,  0xFE,  0x04,  0x83,  0xF8, 	/* 11AC0 */
+	0x04,  0x0F,  0xFE,  0x24,  0x83,  0xF8,  0x24,  0x8F,  0xFE,  0xAD,  0x01,  0x0F,  0x90,  0xAA,  0x8A,  0xC4, 	/* 11AD0 */
+	0xAF,  0xAF,  0x90,  0xAF,  0xEA,  0x90,  0xAB,  0x4F,  0xD2,  0x09,  0x20,  0x30,  0xB0,  0x00,  0x07,  0xFC, 	/* 11AE0 */
+	0x44,  0x47,  0xFC,  0x44,  0x47,  0xFC,  0x11,  0x07,  0xFC,  0x11,  0x0F,  0xFE,  0x21,  0x8C,  0x04,  0xB3, 	/* 11AF0 */
+	0x3F,  0x82,  0x48,  0x3F,  0x82,  0x48,  0xFF,  0xEB,  0xFA,  0xA0,  0xA3,  0xF8,  0x20,  0x83,  0xF8,  0x20, 	/* 11B00 */
+	0x8F,  0xFE,  0xB4,  0x01,  0x0F,  0xFE,  0xA9,  0x0A,  0xBC,  0xF9,  0x0A,  0xFE,  0xAA,  0x4A,  0xBE,  0xFC, 	/* 11B10 */
+	0x40,  0x64,  0x09,  0x40,  0x0C,  0xB6,  0x24,  0x81,  0x50,  0xFF,  0xE8,  0x02,  0xBF,  0xA2,  0x08,  0x3F, 	/* 11B20 */
+	0x87,  0xFC,  0x44,  0x47,  0xFC,  0x44,  0x47,  0xFC,  0xB7,  0x07,  0xEF,  0x92,  0xAE,  0xCA,  0xA4,  0xAD, 	/* 11B30 */
+	0xAF,  0x80,  0xAF,  0xEA,  0x92,  0xAD,  0xAF,  0xA4,  0x05,  0xA0,  0x91,  0xB8,  0x01,  0x0F,  0xFC,  0xA9, 	/* 11B40 */
+	0x0A,  0xA8,  0xAC,  0x4F,  0xFE,  0xA8,  0x4A,  0xF4,  0xAD,  0x4F,  0xF4,  0x00,  0x40,  0x0C,  0xBF,  0x24, 	/* 11B50 */
+	0x85,  0x54,  0xA6,  0x85,  0x54,  0xF5,  0xC1,  0x44,  0xFF,  0xE7,  0xC4,  0x56,  0x87,  0xD2,  0x56,  0xA7, 	/* 11B60 */
+	0xC6,  0x82,  0x3F,  0x82,  0x48,  0x3F,  0x83,  0xF8,  0x60,  0xC1,  0xB0,  0xE0,  0xEF,  0xFE,  0xA0,  0xA3, 	/* 11B70 */
+	0xF8,  0x20,  0x8F,  0xFE,  0x86,  0x00,  0x0F,  0xFE,  0x15,  0x4F,  0x7C,  0x85,  0x4F,  0xFE,  0x50,  0x0F, 	/* 11B80 */
+	0x7C,  0x55,  0x4F,  0x7C,  0x25,  0x4C,  0xFE,  0x87,  0x01,  0x0F,  0xFE,  0xA9,  0x0A,  0xFE,  0xA8,  0x2F, 	/* 11B90 */
+	0xFC,  0xA9,  0x0A,  0xFE,  0xAE,  0x4F,  0xB4,  0x0E,  0x40,  0x0C,  0x89,  0x3F,  0x82,  0x48,  0x3F,  0x8F, 	/* 11BA0 */
+	0xBE,  0xAA,  0xAF,  0xBE,  0x7F,  0xE9,  0x02,  0x1F,  0x82,  0x90,  0x06,  0x0F,  0xFE,  0x8A,  0x3F,  0x82, 	/* 11BB0 */
+	0x48,  0x3F,  0x8F,  0xBE,  0xAA,  0xAF,  0xBE,  0x00,  0x0F,  0xFE,  0x91,  0x21,  0xF0,  0x11,  0x0F,  0xFE, 	/* 11BC0 */
+	0x8B,  0x00,  0x07,  0xFE,  0x04,  0x40,  0x48,  0x24,  0x02,  0x40,  0x27,  0xC2,  0x40,  0x24,  0x05,  0x40, 	/* 11BD0 */
+	0x4C,  0x08,  0x3E,  0x8E,  0x01,  0x0F,  0xFE,  0x11,  0x02,  0x7C,  0x25,  0x4B,  0xD4,  0xA7,  0xCA,  0x10, 	/* 11BE0 */
+	0xA3,  0x8B,  0xD4,  0xE1,  0x28,  0x10,  0x8F,  0x01,  0x0F,  0x90,  0x17,  0xC2,  0x10,  0x22,  0xCB,  0xFA, 	/* 11BF0 */
+	0xAA,  0x8A,  0xA8,  0xAA,  0x8B,  0xA8,  0xEA,  0xA9,  0x06,  0x91,  0x47,  0xE7,  0x84,  0x42,  0x84,  0x98, 	/* 11C00 */
+	0x3F,  0xE4,  0x12,  0x79,  0x49,  0x50,  0x7D,  0xC2,  0x70,  0x55,  0x88,  0x86,  0x94,  0x02,  0x03,  0xFE, 	/* 11C10 */
+	0xA0,  0x06,  0x00,  0x3F,  0xE2,  0x10,  0x61,  0x0A,  0x10,  0x21,  0x04,  0x10,  0x41,  0x08,  0x30,  0x9A, 	/* 11C20 */
+	0x02,  0x03,  0xFE,  0xA0,  0x06,  0x20,  0x23,  0xC2,  0x44,  0x64,  0x8A,  0x88,  0x21,  0x04,  0x28,  0x44, 	/* 11C30 */
+	0x49,  0x82,  0x9D,  0x02,  0x03,  0xFF,  0xA1,  0x06,  0x10,  0x29,  0x22,  0x92,  0x69,  0x2A,  0x92,  0x29, 	/* 11C40 */
+	0x24,  0x92,  0x4F,  0xE8,  0x82,  0xA3,  0x02,  0x03,  0xFE,  0xA2,  0x86,  0x24,  0x3F,  0xE2,  0x20,  0x63, 	/* 11C50 */
+	0x0A,  0x30,  0x25,  0x04,  0x50,  0x49,  0x2B,  0x0E,  0xA5,  0x02,  0x03,  0xFE,  0xA1,  0x06,  0x10,  0x22, 	/* 11C60 */
+	0x82,  0x44,  0x6C,  0xAB,  0x48,  0x24,  0x84,  0x48,  0x48,  0x89,  0x08,  0xAB,  0x02,  0x03,  0xFE,  0xA7, 	/* 11C70 */
+	0x86,  0x48,  0x24,  0xA2,  0x86,  0x77,  0x8A,  0x08,  0x24,  0x84,  0x30,  0x45,  0x89,  0x86,  0xB1,  0x02, 	/* 11C80 */
+	0x03,  0xFE,  0xA4,  0x06,  0x7E,  0x28,  0x22,  0xF2,  0x75,  0x2A,  0x72,  0x24,  0xC4,  0x40,  0x44,  0x28, 	/* 11C90 */
+	0x3E,  0xB2,  0x02,  0x03,  0xFF,  0xA1,  0x06,  0xFE,  0x29,  0x22,  0x94,  0x6F,  0xEA,  0xA2,  0x29,  0x45, 	/* 11CA0 */
+	0x08,  0x53,  0x4A,  0xC2,  0xB3,  0x02,  0x03,  0xFE,  0xA0,  0x06,  0x88,  0x3F,  0xE2,  0x88,  0x68,  0x8A, 	/* 11CB0 */
+	0xF8,  0x28,  0x84,  0x88,  0x48,  0x88,  0xF8,  0xB5,  0x02,  0x03,  0xFE,  0xA0,  0x06,  0x50,  0x25,  0x03, 	/* 11CC0 */
+	0x76,  0x75,  0x8B,  0x50,  0x35,  0x05,  0x52,  0x5F,  0x2B,  0x0E,  0xB8,  0x02,  0x03,  0xFE,  0xA0,  0x06, 	/* 11CD0 */
+	0x7C,  0x24,  0x42,  0x44,  0x67,  0xCA,  0x44,  0x24,  0x44,  0x7C,  0x40,  0x09,  0xFE,  0xB9,  0x02,  0x03, 	/* 11CE0 */
+	0xFE,  0xA2,  0x06,  0x50,  0x28,  0x83,  0x24,  0x64,  0x2B,  0x90,  0x22,  0x44,  0xC8,  0x43,  0x09,  0xC0, 	/* 11CF0 */
+	0xBC,  0x02,  0x03,  0xFE,  0xA4,  0x06,  0x78,  0x38,  0x82,  0x70,  0x6D,  0x8B,  0x06,  0x26,  0x04,  0x10, 	/* 11D00 */
+	0x4E,  0x08,  0x18,  0xBD,  0x02,  0x03,  0xFE,  0xA0,  0x06,  0x7C,  0x24,  0x42,  0x44,  0x67,  0xCA,  0x44, 	/* 11D10 */
+	0x27,  0xC4,  0x44,  0x44,  0x49,  0xFE,  0xBE,  0x02,  0x03,  0xFE,  0x28,  0x0A,  0x80,  0x6F,  0xC3,  0x20, 	/* 11D20 */
+	0x62,  0x0B,  0xFE,  0x23,  0x04,  0x48,  0x48,  0x4B,  0x02,  0x82,  0x02,  0x03,  0xFE,  0xA8,  0x06,  0x8E, 	/* 11D30 */
+	0x3E,  0xA2,  0xAA,  0x6A,  0xAA,  0xAA,  0x2A,  0xA4,  0xAA,  0x52,  0xEA,  0xC0,  0x83,  0x02,  0x03,  0xFE, 	/* 11D40 */
+	0xA2,  0x06,  0x20,  0x3F,  0xE2,  0x20,  0x74,  0x8A,  0x90,  0x27,  0x04,  0x48,  0x4B,  0xCB,  0xC4,  0x85, 	/* 11D50 */
+	0x01,  0x03,  0xFF,  0xA0,  0x06,  0xFE,  0x21,  0x02,  0xFE,  0x69,  0x2A,  0xAA,  0x2A,  0xA4,  0xC6,  0x48, 	/* 11D60 */
+	0x28,  0x86,  0x87,  0x02,  0x03,  0xFE,  0x20,  0x0A,  0x00,  0x6F,  0xE2,  0x10,  0x61,  0x0A,  0x9E,  0x29, 	/* 11D70 */
+	0x04,  0x90,  0x49,  0x09,  0xFE,  0x8A,  0x02,  0x03,  0xFE,  0xA2,  0x06,  0x50,  0x28,  0x83,  0xFE,  0x62, 	/* 11D80 */
+	0x0A,  0x20,  0x2F,  0x84,  0x20,  0x42,  0x0B,  0xFE,  0x8D,  0x02,  0x03,  0xFE,  0xA2,  0x07,  0xFC,  0x22, 	/* 11D90 */
+	0x43,  0xFC,  0x72,  0x0B,  0xFC,  0x22,  0x44,  0x6C,  0x49,  0x0B,  0x0E,  0x92,  0x02,  0x03,  0xFE,  0xA8, 	/* 11DA0 */
+	0x86,  0x50,  0x3F,  0xC2,  0x20,  0x7F,  0xCA,  0x20,  0x3F,  0xE4,  0x20,  0x42,  0x08,  0x20,  0x94,  0x02, 	/* 11DB0 */
+	0x03,  0xFE,  0xA2,  0x06,  0xFC,  0x22,  0x03,  0xFE,  0x60,  0x8B,  0xFE,  0x28,  0x84,  0x48,  0x40,  0x80, 	/* 11DC0 */
+	0x18,  0x95,  0x02,  0x03,  0xFE,  0x20,  0x0A,  0xFC,  0x68,  0x42,  0xFC,  0x68,  0x4A,  0xFC,  0x2A,  0x22, 	/* 11DD0 */
+	0x94,  0x4E,  0x89,  0x86,  0x98,  0x02,  0x03,  0xFE,  0xA0,  0x06,  0xFE,  0x20,  0x02,  0xFC,  0x68,  0x4A, 	/* 11DE0 */
+	0xFC,  0x28,  0x84,  0x48,  0x45,  0x09,  0xFE,  0x99,  0x02,  0x03,  0xFE,  0xA0,  0x07,  0xFE,  0x29,  0x23, 	/* 11DF0 */
+	0x24,  0x69,  0x2B,  0xFC,  0x22,  0x04,  0x20,  0x42,  0x0B,  0xFE,  0x9B,  0x02,  0x03,  0xFE,  0xA0,  0x06, 	/* 11E00 */
+	0xFE,  0x26,  0x82,  0xFE,  0x69,  0x2A,  0xFE,  0x29,  0x24,  0xFE,  0x49,  0x28,  0x96,  0x9E,  0x02,  0x03, 	/* 11E10 */
+	0xFE,  0xA0,  0x07,  0xFE,  0x27,  0x02,  0xAC,  0x72,  0x2A,  0x20,  0x3F,  0xC5,  0x04,  0x50,  0x49,  0xFC, 	/* 11E20 */
+	0xA2,  0x02,  0x03,  0xFE,  0xA2,  0x06,  0xCA,  0x24,  0xA3,  0xFA,  0x64,  0xAA,  0xEA,  0x2E,  0xA5,  0x52, 	/* 11E30 */
+	0x54,  0x28,  0x46,  0xA3,  0x02,  0x03,  0xFE,  0xA2,  0x06,  0x20,  0x3F,  0xC2,  0x20,  0x6F,  0x8A,  0x40, 	/* 11E40 */
+	0x2A,  0x45,  0x82,  0x68,  0xA8,  0x78,  0xA9,  0x02,  0x03,  0xFE,  0xA2,  0x06,  0xFC,  0x2A,  0x42,  0xFC, 	/* 11E50 */
+	0x6A,  0x4A,  0xFC,  0x28,  0x84,  0x50,  0x47,  0x09,  0x8E,  0xB0,  0x02,  0x03,  0xFE,  0xA2,  0x46,  0xA8, 	/* 11E60 */
+	0x32,  0x02,  0x50,  0x78,  0xCA,  0x24,  0x2A,  0x85,  0x20,  0x45,  0x8B,  0x86,  0xB2,  0x02,  0x03,  0xFF, 	/* 11E70 */
+	0xA4,  0x46,  0x44,  0x3F,  0xF2,  0x44,  0x65,  0x5B,  0x55,  0x35,  0x55,  0x55,  0x55,  0x5A,  0x44,  0xB3, 	/* 11E80 */
+	0x04,  0x03,  0xFE,  0xA8,  0x86,  0x88,  0x3F,  0xE2,  0x88,  0x7D,  0xCB,  0xDC,  0x2A,  0xA4,  0xAA,  0x4A, 	/* 11E90 */
+	0x88,  0x88,  0xB4,  0x02,  0x03,  0xFE,  0xA8,  0x06,  0x9E,  0x2F,  0x23,  0x52,  0x65,  0x2B,  0xF2,  0x25, 	/* 11EA0 */
+	0x24,  0xB2,  0x91,  0xE2,  0x10,  0xBA,  0x02,  0x03,  0xFE,  0xA2,  0x06,  0xFC,  0x29,  0x42,  0xFC,  0x69, 	/* 11EB0 */
+	0x4A,  0xFC,  0x25,  0x05,  0xFE,  0x41,  0x08,  0x10,  0xBC,  0x02,  0x03,  0xFE,  0xA0,  0x06,  0xFE,  0x29, 	/* 11EC0 */
+	0x22,  0xFE,  0x69,  0x2A,  0xBA,  0x2A,  0xA4,  0xBA,  0x48,  0x28,  0xFE,  0xBE,  0x02,  0x03,  0xFE,  0xA0, 	/* 11ED0 */
+	0x06,  0xFF,  0x2A,  0x26,  0xCE,  0xAC,  0xA2,  0xAA,  0x4A,  0xE4,  0xE2,  0x48,  0x28,  0x86,  0xBF,  0x02, 	/* 11EE0 */
+	0x03,  0xFE,  0xA0,  0x86,  0xF0,  0x22,  0x03,  0xFE,  0x6A,  0x8B,  0x24,  0x3F,  0xE4,  0xC8,  0x43,  0x09, 	/* 11EF0 */
+	0xC8,  0x81,  0x02,  0x03,  0xFE,  0xA2,  0x07,  0xFC,  0x28,  0x82,  0xD8,  0x72,  0x4A,  0x20,  0x3F,  0xE4, 	/* 11F00 */
+	0x20,  0x42,  0x08,  0x20,  0x89,  0x02,  0x03,  0xFE,  0xA5,  0x06,  0xF8,  0x30,  0x63,  0xD4,  0x75,  0x4B, 	/* 11F10 */
+	0xE8,  0x36,  0x85,  0xD4,  0x55,  0x49,  0x54,  0x8B,  0x02,  0x03,  0xFE,  0xA0,  0x06,  0xFC,  0x2F,  0x42, 	/* 11F20 */
+	0xA4,  0x6F,  0xCA,  0xAC,  0x2F,  0xC5,  0x24,  0x52,  0xAA,  0xF6,  0x8D,  0x02,  0x03,  0xFE,  0xAF,  0x86, 	/* 11F30 */
+	0x88,  0x2F,  0x82,  0x88,  0x7F,  0xEA,  0x40,  0x2F,  0xE5,  0x2A,  0x65,  0x28,  0xA4,  0x9F,  0x02,  0x03, 	/* 11F40 */
+	0xFE,  0xA0,  0x06,  0xFC,  0x2A,  0x42,  0xBC,  0x6C,  0x4A,  0xFC,  0x20,  0x04,  0xFE,  0x4A,  0xAB,  0xFF, 	/* 11F50 */
+	0xA0,  0x02,  0x03,  0xFE,  0xA2,  0x07,  0xAC,  0x22,  0x03,  0xDC,  0x68,  0x8B,  0x76,  0x28,  0x84,  0xF8, 	/* 11F60 */
+	0x48,  0x88,  0x98,  0xA1,  0x02,  0x03,  0xFE,  0xA2,  0x06,  0xD8,  0x32,  0x62,  0xF8,  0x68,  0x8A,  0xF8, 	/* 11F70 */
+	0x28,  0x05,  0x7E,  0x54,  0x2A,  0x7E,  0xA2,  0x02,  0x03,  0xFE,  0xA4,  0x06,  0xEE,  0x2A,  0xA2,  0xEA, 	/* 11F80 */
+	0x6B,  0x3B,  0xFE,  0x2A,  0xA4,  0xE4,  0x52,  0xCA,  0x72,  0xA4,  0x02,  0x03,  0xFE,  0xA2,  0x06,  0xDE, 	/* 11F90 */
+	0x2A,  0xA2,  0xF2,  0x7A,  0xCA,  0xFE,  0x29,  0x24,  0xFE,  0x49,  0x28,  0xFE,  0xA7,  0x02,  0x03,  0xFE, 	/* 11FA0 */
+	0xA2,  0x06,  0xFE,  0x2B,  0xC2,  0xE2,  0x69,  0xEA,  0xBC,  0x2A,  0x05,  0x7E,  0x52,  0x0A,  0x3E,  0xB0, 	/* 11FB0 */
+	0x02,  0x03,  0xFE,  0xAF,  0xC6,  0x94,  0x2F,  0xC2,  0x94,  0x6F,  0xCA,  0x48,  0x23,  0x45,  0xFE,  0x45, 	/* 11FC0 */
+	0x49,  0x92,  0xB4,  0x02,  0x03,  0xFE,  0xA2,  0x07,  0xFE,  0x24,  0x83,  0xFE,  0x68,  0x4A,  0xFC,  0x28, 	/* 11FD0 */
+	0x45,  0xFE,  0x42,  0x08,  0x20,  0xBB,  0x02,  0x03,  0xFE,  0xAF,  0xC6,  0xA4,  0x3F,  0xE2,  0xA4,  0x6F, 	/* 11FE0 */
+	0xCA,  0x40,  0x3F,  0xE4,  0x88,  0x47,  0x09,  0xC8,  0x82,  0x02,  0x03,  0xFE,  0xA2,  0x07,  0xFE,  0x35, 	/* 11FF0 */
+	0x42,  0x88,  0x7F,  0xCA,  0x8A,  0x2F,  0x84,  0xA8,  0x52,  0x48,  0x60,  0x86,  0x02,  0x03,  0xFE,  0xB6, 	/* 12000 */
+	0xA6,  0xDC,  0x24,  0x82,  0xB4,  0x7F,  0xEB,  0x22,  0x2F,  0xC4,  0x24,  0x44,  0x48,  0x98,  0x87,  0x02, 	/* 12010 */
+	0x03,  0xFF,  0xAE,  0xE6,  0xAA,  0x2E,  0xE2,  0xAA,  0x6F,  0x6A,  0xAA,  0x2B,  0xA4,  0xAA,  0x4B,  0xA8, 	/* 12020 */
+	0x86,  0x88,  0x02,  0x03,  0xFE,  0xAE,  0x86,  0x32,  0x2C,  0xC3,  0xDE,  0x65,  0x4B,  0xD6,  0x33,  0xC5, 	/* 12030 */
+	0xD4,  0x44,  0xC9,  0xB2,  0x8C,  0x02,  0x03,  0xFE,  0xA7,  0x86,  0x48,  0x27,  0x86,  0xEE,  0xAA,  0xA2, 	/* 12040 */
+	0xEE,  0x21,  0x05,  0x12,  0x51,  0x29,  0xFE,  0x92,  0x02,  0x03,  0xFE,  0xA2,  0x86,  0x44,  0x2E,  0xA3, 	/* 12050 */
+	0xAB,  0x6E,  0xAA,  0xA2,  0x2A,  0x64,  0x54,  0x54,  0xAA,  0x3A,  0x96,  0x02,  0x03,  0xFF,  0xA0,  0x46, 	/* 12060 */
+	0xE4,  0x2B,  0xF2,  0xEA,  0x68,  0xAA,  0xFF,  0x3A,  0x44,  0xBF,  0x4E,  0x48,  0x84,  0x98,  0x02,  0x03, 	/* 12070 */
+	0xFE,  0xA4,  0x87,  0xFE,  0x2A,  0x42,  0xFC,  0x6A,  0x4A,  0xFC,  0x3F,  0xE5,  0x2A,  0x5F,  0xA9,  0x06, 	/* 12080 */
+	0x9C,  0x02,  0x03,  0xFE,  0xA0,  0x06,  0xEE,  0x2A,  0xA2,  0xEA,  0x6B,  0x3A,  0xFE,  0x2A,  0xA4,  0xFA, 	/* 12090 */
+	0x56,  0x4A,  0x9A,  0xA1,  0x02,  0x03,  0xFE,  0xA8,  0x06,  0xFE,  0x29,  0x42,  0xE8,  0x65,  0xEB,  0xEA, 	/* 120A0 */
+	0x34,  0x85,  0xFE,  0x4D,  0x89,  0x26,  0xA2,  0x02,  0x03,  0xFE,  0xA4,  0x46,  0xFE,  0x21,  0x02,  0xFE, 	/* 120B0 */
+	0x64,  0x8A,  0xFC,  0x34,  0x64,  0x7C,  0x45,  0xA8,  0xE7,  0xA7,  0x02,  0x03,  0xFE,  0xA0,  0x06,  0xFE, 	/* 120C0 */
+	0x2A,  0x82,  0xFE,  0x6E,  0xCA,  0xBA,  0x29,  0x04,  0xDE,  0x55,  0x0A,  0xFE,  0xA8,  0x02,  0x03,  0xFE, 	/* 120D0 */
+	0xA2,  0x07,  0xFE,  0x32,  0x23,  0xAE,  0x69,  0x0A,  0xFE,  0x59,  0x06,  0xFC,  0x49,  0x08,  0xFE,  0xA9, 	/* 120E0 */
+	0x02,  0x03,  0xFE,  0xA4,  0x07,  0xFE,  0x24,  0xA3,  0xFE,  0x77,  0x2B,  0xFE,  0x25,  0x24,  0xFE,  0x54, 	/* 120F0 */
+	0xC8,  0x52,  0xAA,  0x02,  0x03,  0xFE,  0xA2,  0x87,  0xDE,  0x24,  0x83,  0xFF,  0x65,  0x2A,  0xDE,  0x2F, 	/* 12100 */
+	0x25,  0x5E,  0x54,  0xC8,  0x52,  0xAC,  0x04,  0x07,  0xFE,  0xD1,  0x4D,  0xC8,  0x69,  0xE7,  0xE8,  0xEB, 	/* 12110 */
+	0xCF,  0xE8,  0x6B,  0xEB,  0xE8,  0x94,  0x82,  0xA8,  0xB0,  0x02,  0x03,  0xFE,  0xAA,  0x87,  0x4A,  0x2B, 	/* 12120 */
+	0xE7,  0xD4,  0xB5,  0xE3,  0xF4,  0x6B,  0xE7,  0xF4,  0xA1,  0x41,  0xDE,  0xB2,  0x02,  0x03,  0xFE,  0xA4, 	/* 12130 */
+	0x07,  0xBE,  0x34,  0x83,  0xDE,  0x75,  0x2B,  0xDE,  0x35,  0x25,  0xFE,  0x54,  0xAA,  0x11,  0xB6,  0x00, 	/* 12140 */
+	0x00,  0x00,  0x3C,  0x80,  0x50,  0x8A,  0x25,  0x14,  0x20,  0x8C,  0x06,  0x00,  0x00,  0x00,  0x00,  0x00, 	/* 12150 */
+	0x00,  0xB8,  0x38,  0x80,  0xA8,  0x8B,  0x25,  0x14,  0x20,  0x85,  0xF4,  0x84,  0x23,  0xF8,  0x04,  0x00, 	/* 12160 */
+	0xA0,  0x31,  0x8C,  0x06,  0xBA,  0x3A,  0x40,  0xA8,  0x49,  0x23,  0x14,  0x3F,  0x84,  0x94,  0x89,  0x27, 	/* 12170 */
+	0xFE,  0x09,  0x00,  0x92,  0x31,  0x2C,  0x0E,  0xBB,  0x3A,  0x40,  0xA8,  0x49,  0x23,  0x14,  0x3F,  0x84, 	/* 12180 */
+	0x04,  0xBF,  0xA2,  0x08,  0x3F,  0x81,  0x10,  0x0A,  0x07,  0xFC,  0xBC,  0x3A,  0x80,  0xB2,  0x51,  0x42, 	/* 12190 */
+	0x08,  0x73,  0xC9,  0x2A,  0x74,  0xC4,  0xF8,  0x72,  0x81,  0x10,  0x12,  0x86,  0xC6,  0xBD,  0x04,  0x00, 	/* 121A0 */
+	0x40,  0x08,  0x03,  0xF8,  0x20,  0x82,  0x08,  0x20,  0x83,  0xF8,  0x20,  0x82,  0x08,  0x20,  0x83,  0xF8, 	/* 121B0 */
+	0xBE,  0x00,  0x0F,  0xFE,  0x04,  0x00,  0x80,  0x3F,  0x82,  0x08,  0x20,  0x83,  0xF8,  0x20,  0x82,  0x08, 	/* 121C0 */
+	0x20,  0x83,  0xF8,  0x80,  0x08,  0x03,  0xF8,  0x20,  0x83,  0xF8,  0x20,  0x82,  0x08,  0x3F,  0x81,  0x18, 	/* 121D0 */
+	0x1E,  0x01,  0x00,  0x10,  0x20,  0xFE,  0x83,  0x04,  0x00,  0x80,  0x3F,  0x82,  0x08,  0x3F,  0x82,  0x08, 	/* 121E0 */
+	0x3F,  0x80,  0xA0,  0x0A,  0x01,  0x22,  0x22,  0x2C,  0x1E,  0x84,  0x11,  0x02,  0x10,  0x79,  0xE4,  0xA2, 	/* 121F0 */
+	0x4A,  0x27,  0xD2,  0x48,  0xA4,  0x8A,  0x48,  0x27,  0x82,  0x00,  0x20,  0x0C,  0x86,  0x42,  0x04,  0x26, 	/* 12200 */
+	0x7B,  0x84,  0x20,  0x5A,  0x2E,  0x5E,  0x08,  0x03,  0xF8,  0x20,  0x83,  0xF8,  0x20,  0x83,  0xF8,  0x87, 	/* 12210 */
+	0x08,  0x03,  0xF8,  0x20,  0x83,  0xF8,  0x20,  0x83,  0xF8,  0x00,  0x07,  0xFC,  0x04,  0x03,  0xF8,  0x04, 	/* 12220 */
+	0x0F,  0xFE,  0x88,  0x20,  0x04,  0x7E,  0xF4,  0x09,  0x40,  0x97,  0xCF,  0x44,  0x96,  0x49,  0x58,  0x98, 	/* 12230 */
+	0x8F,  0x98,  0x12,  0x42,  0xC2,  0x8B,  0x04,  0x03,  0xF8,  0x20,  0x83,  0xF8,  0x20,  0x83,  0xF8,  0x04, 	/* 12240 */
+	0x0F,  0xFE,  0x31,  0x8C,  0x46,  0x3F,  0x80,  0x40,  0x8E,  0x21,  0x04,  0x10,  0xFF,  0xE9,  0x28,  0x94, 	/* 12250 */
+	0x4F,  0x8A,  0x94,  0x89,  0x28,  0x91,  0x0F,  0x28,  0x0C,  0x43,  0x02,  0x90,  0x08,  0x03,  0xF8,  0x20, 	/* 12260 */
+	0x83,  0xF8,  0x20,  0x87,  0xFC,  0x04,  0x07,  0x5C,  0x04,  0x0F,  0xFE,  0x04,  0x00,  0x40,  0x93,  0x25, 	/* 12270 */
+	0x04,  0x50,  0xF7,  0xE9,  0x90,  0x91,  0x0F,  0xFE,  0x90,  0x09,  0x7C,  0x94,  0x4F,  0x44,  0x04,  0x40, 	/* 12280 */
+	0x7C,  0x96,  0x21,  0x04,  0x10,  0xFF,  0xE9,  0x82,  0x97,  0xCF,  0x00,  0x9F,  0xE9,  0x28,  0x92,  0x8F, 	/* 12290 */
+	0x4A,  0x08,  0xA1,  0x06,  0x99,  0x20,  0x2F,  0xBC,  0x22,  0x07,  0x3E,  0x6A,  0x4A,  0x44,  0x20,  0x43, 	/* 122A0 */
+	0xFC,  0x20,  0x43,  0xFC,  0x20,  0x43,  0xFC,  0x9A,  0x21,  0x04,  0x92,  0xFF,  0xE9,  0x00,  0x9F,  0xEF, 	/* 122B0 */
+	0x00,  0x97,  0xC9,  0x44,  0x97,  0xCF,  0x44,  0x02,  0x81,  0xFE,  0xAE,  0x02,  0x00,  0x20,  0x3F,  0xE2, 	/* 122C0 */
+	0x22,  0x22,  0x43,  0xF8,  0x20,  0x82,  0x90,  0x25,  0x04,  0x20,  0x4D,  0x8B,  0x06,  0xB0,  0x11,  0x01, 	/* 122D0 */
+	0x10,  0x7F,  0xE5,  0x42,  0x7B,  0xA5,  0x2A,  0x7A,  0xA6,  0xBA,  0x52,  0xC5,  0xA0,  0xA6,  0x24,  0x1E, 	/* 122E0 */
+	0xB4,  0x10,  0x82,  0x88,  0xF7,  0xE5,  0x2A,  0x52,  0xC5,  0xFE,  0x92,  0x23,  0xB4,  0x4A,  0x8B,  0x2C, 	/* 122F0 */
+	0x2D,  0x2C,  0xA1,  0xB7,  0x20,  0x8F,  0xC8,  0x23,  0xFF,  0xAA,  0x02,  0x87,  0xBE,  0x4A,  0x27,  0xB2, 	/* 12300 */
+	0x4B,  0x43,  0x48,  0x19,  0x4E,  0x22,  0xB8,  0x00,  0x8F,  0xC8,  0xA7,  0xF2,  0x29,  0xFA,  0xAA,  0xBE, 	/* 12310 */
+	0xFB,  0x2A,  0xAA,  0xFA,  0x42,  0x4C,  0xFD,  0x22,  0xA1,  0xB9,  0x10,  0x01,  0x7F,  0x7D,  0xD5,  0x48, 	/* 12320 */
+	0x53,  0xE7,  0xAA,  0x6B,  0xE6,  0xAA,  0x53,  0xE5,  0x08,  0xAB,  0xF4,  0x08,  0xBA,  0x40,  0x87,  0x88, 	/* 12330 */
+	0xAB,  0xE7,  0xAA,  0x2A,  0xC4,  0xBE,  0x5A,  0x27,  0xB4,  0xAA,  0x87,  0xCC,  0x2D,  0x25,  0xA1,  0xBF, 	/* 12340 */
+	0x00,  0x00,  0x00,  0x3F,  0xC2,  0x94,  0x29,  0x42,  0x94,  0x29,  0x42,  0x94,  0x29,  0x42,  0x94,  0xFF, 	/* 12350 */
+	0xF0,  0x00,  0x82,  0x00,  0x03,  0xF8,  0x04,  0x00,  0x40,  0xFF,  0xE0,  0x40,  0x04,  0x00,  0xC0,  0x7F, 	/* 12360 */
+	0xC4,  0xA4,  0x4A,  0x4F,  0xFE,  0x83,  0x00,  0x0F,  0xFE,  0x02,  0x00,  0xD8,  0x34,  0x4C,  0x42,  0x04, 	/* 12370 */
+	0x07,  0xFC,  0x4A,  0x44,  0xA4,  0x4A,  0x4F,  0xFE,  0x86,  0x17,  0x01,  0x10,  0x20,  0x87,  0xF4,  0x89, 	/* 12380 */
+	0x20,  0x90,  0x11,  0x02,  0x60,  0x7F,  0xC4,  0xA4,  0x4A,  0x4F,  0xFE,  0x88,  0x00,  0x07,  0xF0,  0x11, 	/* 12390 */
+	0x01,  0xFC,  0x2A,  0x42,  0x44,  0x5A,  0x48,  0x18,  0x7F,  0xC4,  0xA4,  0x4A,  0x4F,  0xFE,  0x8A,  0x20, 	/* 123A0 */
+	0x81,  0x08,  0x09,  0x0F,  0xFE,  0x11,  0x01,  0x10,  0x20,  0x87,  0xFC,  0xAA,  0xA2,  0xA8,  0x2A,  0x8F, 	/* 123B0 */
+	0xFE,  0x8D,  0x04,  0x03,  0xF8,  0x04,  0x0F,  0xFE,  0x0A,  0x01,  0x18,  0x7E,  0x40,  0x00,  0x7F,  0xC4, 	/* 123C0 */
+	0xA4,  0x4A,  0x4F,  0xFE,  0x92,  0x04,  0x00,  0xA0,  0x11,  0x03,  0xF8,  0xC0,  0x63,  0xF8,  0x20,  0x83, 	/* 123D0 */
+	0xF8,  0x7F,  0xC4,  0xA4,  0x4A,  0x4F,  0xFE,  0x96,  0x20,  0x81,  0x10,  0x7F,  0xC0,  0x40,  0x3F,  0x80, 	/* 123E0 */
+	0x40,  0xFF,  0xE0,  0x00,  0x7F,  0xC4,  0xA4,  0x4A,  0x4F,  0xFE,  0x97,  0x08,  0x08,  0xFE,  0x4A,  0x41, 	/* 123F0 */
+	0x28,  0x45,  0x08,  0x88,  0x90,  0x67,  0xFC,  0x4A,  0x44,  0xA4,  0x4A,  0x4F,  0xFE,  0x9B,  0x02,  0x80, 	/* 12400 */
+	0x24,  0x7F,  0xE4,  0x20,  0x7A,  0x44,  0x98,  0x49,  0xA9,  0xA6,  0x7F,  0xC4,  0xA4,  0x4A,  0x4F,  0xFE, 	/* 12410 */
+	0x9C,  0x44,  0x02,  0x7E,  0x85,  0x24,  0x94,  0x13,  0x04,  0x48,  0x88,  0x67,  0xFC,  0x4A,  0x44,  0xA4, 	/* 12420 */
+	0x4A,  0x4F,  0xFE,  0x9E,  0x11,  0x0F,  0xFE,  0x05,  0x00,  0x34,  0x1C,  0xCF,  0xFE,  0x04,  0x80,  0x32, 	/* 12430 */
+	0x18,  0xE7,  0xFC,  0x4A,  0x4F,  0xFE,  0x9F,  0x00,  0x07,  0xBC,  0x4A,  0x47,  0xBC,  0x4A,  0x47,  0xBC, 	/* 12440 */
+	0x04,  0x40,  0x8C,  0x7F,  0xC4,  0xA4,  0x4A,  0x4F,  0xFE,  0xA1,  0x04,  0x07,  0xF8,  0x04,  0x8F,  0xFE, 	/* 12450 */
+	0x00,  0x8F,  0xFE,  0x32,  0x84,  0x94,  0xFF,  0xE4,  0xA4,  0x4A,  0x4F,  0xFF,  0xA3,  0xFA,  0x0A,  0x20, 	/* 12460 */
+	0xFB,  0xE8,  0xC0,  0xF8,  0x0A,  0x3C,  0xF8,  0x00,  0x00,  0x7F,  0xC4,  0xA4,  0x4A,  0x4F,  0xFE,  0xA4, 	/* 12470 */
+	0x23,  0x87,  0xAA,  0x4C,  0xE6,  0x80,  0xFF,  0xC5,  0xA4,  0x49,  0x89,  0xE6,  0x7F,  0xC4,  0xA4,  0x4A, 	/* 12480 */
+	0x4F,  0xFE,  0xA5,  0x20,  0x04,  0x4E,  0x85,  0x2D,  0xEE,  0x8E,  0x2D,  0x56,  0xA4,  0xA8,  0xC2,  0x7F, 	/* 12490 */
+	0xC4,  0xA4,  0x4A,  0x4F,  0xFE,  0xA7,  0x07,  0x80,  0x40,  0x7F,  0xE4,  0x9C,  0x7E,  0x25,  0xFE,  0x52, 	/* 124A0 */
+	0x45,  0xFC,  0x52,  0x47,  0xFE,  0xA5,  0x27,  0xFF,  0xAA,  0x4F,  0x82,  0x88,  0x8F,  0x84,  0x88,  0x0F, 	/* 124B0 */
+	0xE2,  0xAA,  0x55,  0x28,  0x0C,  0x7F,  0xC4,  0xA4,  0x4A,  0x4F,  0xFE,  0xAE,  0x00,  0x03,  0xF8,  0x20, 	/* 124C0 */
+	0x82,  0x08,  0x3F,  0x82,  0x08,  0x20,  0x83,  0xF8,  0x20,  0x82,  0x08,  0x20,  0x83,  0xF8,  0xB2,  0x02, 	/* 124D0 */
+	0x0F,  0xFF,  0x20,  0x01,  0xFE,  0x00,  0x01,  0xFC,  0x10,  0x41,  0xFC,  0x10,  0x41,  0xFC,  0x10,  0x41, 	/* 124E0 */
+	0xFC,  0xB4,  0x04,  0x0F,  0xFE,  0x04,  0x09,  0xF8,  0x90,  0x89,  0xF8,  0x90,  0x89,  0xF8,  0x90,  0x89, 	/* 124F0 */
+	0xF8,  0x80,  0x0F,  0xFE,  0xB8,  0x10,  0x01,  0x3E,  0x12,  0x2F,  0xE2,  0x13,  0xE3,  0x22,  0x3A,  0x25, 	/* 12500 */
+	0x7E,  0x52,  0x29,  0x22,  0x12,  0x21,  0x3E,  0xBB,  0x03,  0x8F,  0x48,  0x94,  0x89,  0x44,  0xF8,  0x29, 	/* 12510 */
+	0xFC,  0x92,  0x0F,  0x3C,  0x94,  0x49,  0x04,  0xF0,  0x40,  0x18,  0xBE,  0x00,  0xC3,  0xF0,  0x22,  0x03, 	/* 12520 */
+	0xFE,  0x22,  0x02,  0xFC,  0x28,  0x42,  0xFC,  0x48,  0x44,  0xFC,  0x88,  0x40,  0xFC,  0x81,  0x04,  0x01, 	/* 12530 */
+	0x48,  0x24,  0x4C,  0xCA,  0x01,  0x01,  0xF8,  0xF0,  0x81,  0xF8,  0x10,  0x81,  0xF8,  0x10,  0x81,  0xF8, 	/* 12540 */
+	0x84,  0x00,  0x00,  0xFF,  0xF1,  0x09,  0x5E,  0xF5,  0x29,  0x52,  0x95,  0x2F,  0x52,  0x97,  0xE9,  0x02, 	/* 12550 */
+	0xF0,  0x20,  0x0C,  0x87,  0x01,  0x0F,  0x10,  0x91,  0x49,  0x54,  0xF5,  0x29,  0x51,  0xF9,  0x49,  0x34, 	/* 12560 */
+	0x90,  0x8F,  0x10,  0x06,  0x01,  0x80,  0x88,  0x01,  0x0F,  0x10,  0x9F,  0xE9,  0x92,  0xF9,  0x29,  0x18, 	/* 12570 */
+	0x91,  0x8F,  0x18,  0x92,  0x89,  0x29,  0xF4,  0x91,  0x87,  0x89,  0x00,  0x07,  0xFE,  0x44,  0x27,  0xFE, 	/* 12580 */
+	0x40,  0x04,  0xFC,  0x48,  0x44,  0xFC,  0x48,  0x44,  0xFC,  0x88,  0x48,  0xFC,  0x8B,  0x00,  0xC7,  0xF0, 	/* 12590 */
+	0x08,  0x0F,  0xFE,  0x10,  0x0F,  0xFE,  0x30,  0x85,  0xF8,  0x90,  0x81,  0xF8,  0x10,  0x81,  0xF8,  0x8C, 	/* 125A0 */
+	0x00,  0x01,  0xF8,  0x90,  0x89,  0xF8,  0x90,  0x89,  0xF8,  0x90,  0x89,  0xF8,  0x80,  0x0F,  0xFE,  0x25, 	/* 125B0 */
+	0x8C,  0x46,  0x9B,  0x01,  0x0F,  0x10,  0x97,  0xC9,  0x10,  0xF1,  0x09,  0xFE,  0x91,  0x0F,  0x38,  0x93, 	/* 125C0 */
+	0x49,  0x52,  0xF9,  0x00,  0x10,  0x9E,  0x40,  0xC4,  0x70,  0x78,  0x23,  0xFE,  0x90,  0x89,  0xF8,  0x90, 	/* 125D0 */
+	0x89,  0xF8,  0x90,  0x8F,  0xFE,  0x19,  0x8E,  0x06,  0x9F,  0x04,  0x0F,  0xFE,  0x04,  0x03,  0xF0,  0x21, 	/* 125E0 */
+	0x03,  0xF0,  0x21,  0x03,  0xF0,  0x21,  0x0F,  0xFE,  0x13,  0x0E,  0x0C,  0xA0,  0x00,  0x0F,  0x7E,  0x94, 	/* 125F0 */
+	0x2F,  0x42,  0x97,  0xE9,  0x48,  0xF7,  0xF9,  0x48,  0x94,  0x4F,  0x45,  0x07,  0x31,  0x81,  0xA4,  0x00, 	/* 12600 */
+	0x0F,  0x7E,  0x94,  0x29,  0x7E,  0xF5,  0x09,  0x50,  0x95,  0x2F,  0x5C,  0x95,  0x0F,  0x92,  0x09,  0x21, 	/* 12610 */
+	0x0E,  0xA5,  0x11,  0x05,  0xD2,  0x51,  0xC5,  0x50,  0x79,  0x2B,  0xFE,  0x20,  0x83,  0xF8,  0x20,  0x83, 	/* 12620 */
+	0xF8,  0x20,  0x83,  0xF8,  0xA6,  0x09,  0x0E,  0x90,  0xA9,  0x0A,  0x92,  0xEF,  0x4A,  0x98,  0xA9,  0x0E, 	/* 12630 */
+	0x90,  0xA9,  0x0A,  0x92,  0xEF,  0x23,  0x0E,  0xA9,  0x01,  0x0F,  0x10,  0x9F,  0xE9,  0x10,  0xF5,  0x49, 	/* 12640 */
+	0x24,  0x92,  0x8F,  0x18,  0x91,  0x09,  0x24,  0xF2,  0xE0,  0xF2,  0xB7,  0x04,  0x01,  0x50,  0x3F,  0x84, 	/* 12650 */
+	0xA4,  0xFF,  0xE1,  0x10,  0x3F,  0x86,  0x0C,  0xBF,  0xA3,  0xF8,  0x20,  0x83,  0xF8,  0xB8,  0x02,  0x0F, 	/* 12660 */
+	0x28,  0x94,  0x49,  0xFE,  0xF5,  0x29,  0x50,  0x97,  0xEF,  0x90,  0x91,  0x09,  0xFF,  0xF1,  0x00,  0x10, 	/* 12670 */
+	0xBA,  0x05,  0x0E,  0x50,  0xA5,  0x4F,  0x54,  0xAD,  0x8A,  0x50,  0xED,  0x8B,  0x54,  0xA5,  0x2E,  0x90, 	/* 12680 */
+	0x09,  0x21,  0x0E,  0xBC,  0x00,  0x0F,  0x7C,  0x94,  0x49,  0x7C,  0xF4,  0x49,  0x44,  0x97,  0xCF,  0x42, 	/* 12690 */
+	0x95,  0x49,  0x48,  0xF7,  0x40,  0xC2,  0x80,  0x11,  0x0F,  0xFE,  0x04,  0x07,  0xFC,  0x04,  0x0F,  0xFE, 	/* 126A0 */
+	0x10,  0x83,  0xF8,  0x50,  0x89,  0xF8,  0x10,  0x81,  0xF8,  0x87,  0x08,  0x8E,  0x50,  0xBF,  0xCA,  0x24, 	/* 126B0 */
+	0xEF,  0xCA,  0xA0,  0xAF,  0xEE,  0x22,  0xA6,  0x2A,  0xA2,  0xF2,  0xC0,  0x20,  0x9A,  0x00,  0x0E,  0xFE, 	/* 126C0 */
+	0xA9,  0x0A,  0xFC,  0xE9,  0x0A,  0xFE,  0xA9,  0x0E,  0x90,  0xAF,  0xCF,  0x10,  0x11,  0x02,  0xFE,  0x9B, 	/* 126D0 */
+	0x02,  0x0E,  0xFE,  0xA2,  0x0A,  0x7C,  0xE2,  0x0B,  0xFE,  0xAA,  0x4E,  0xA4,  0xAF,  0xCA,  0x84,  0xE8, 	/* 126E0 */
+	0x40,  0x8C,  0xA1,  0x01,  0xCE,  0xE0,  0xA2,  0x0B,  0xFC,  0xEA,  0x8B,  0xFE,  0xEA,  0x8A,  0xA8,  0xBF, 	/* 126F0 */
+	0xCE,  0x20,  0x02,  0x03,  0xFE,  0xA3,  0x20,  0x03,  0xBE,  0x22,  0x2F,  0xD4,  0x58,  0x85,  0x54,  0xB6, 	/* 12700 */
+	0x23,  0xF8,  0x20,  0x83,  0xF8,  0x20,  0x83,  0xF8,  0xA5,  0x02,  0x0E,  0x40,  0xAF,  0xCA,  0xA4,  0xEF, 	/* 12710 */
+	0xCA,  0xA4,  0xAF,  0xCE,  0x50,  0xA9,  0x0B,  0xFE,  0xE1,  0x00,  0x10,  0xA6,  0x02,  0x0E,  0xFC,  0xA2, 	/* 12720 */
+	0x0B,  0xFE,  0xE5,  0x0A,  0x92,  0xB2,  0xEE,  0x20,  0xAF,  0xCA,  0x20,  0xE2,  0x03,  0xFE,  0xA8,  0x02, 	/* 12730 */
+	0x0E,  0xCC,  0xA8,  0x4A,  0x84,  0xED,  0xCA,  0x84,  0xAF,  0xCE,  0x30,  0xA3,  0x0A,  0x52,  0xE9,  0x21, 	/* 12740 */
+	0x0E,  0xAB,  0x02,  0x0F,  0xFE,  0xA2,  0x0A,  0xFC,  0xE2,  0x4B,  0xFE,  0xAF,  0xCE,  0x20,  0xAB,  0xEE, 	/* 12750 */
+	0xE0,  0x13,  0x02,  0x0E,  0xB9,  0x02,  0x0E,  0x20,  0xAF,  0xCA,  0x24,  0xE2,  0x8B,  0xFE,  0xA2,  0x8E, 	/* 12760 */
+	0x7C,  0xAC,  0x4B,  0x7C,  0xE4,  0x40,  0x7C,  0xBE,  0x04,  0x07,  0xFC,  0x4A,  0x47,  0xFC,  0x04,  0x0F, 	/* 12770 */
+	0xFE,  0x11,  0x0F,  0xFE,  0x04,  0x07,  0xFC,  0x04,  0x00,  0x40,  0xBF,  0x07,  0x80,  0x40,  0xFF,  0xE9, 	/* 12780 */
+	0x22,  0x9F,  0x22,  0x48,  0x4A,  0x43,  0xF8,  0xD1,  0x61,  0xF0,  0x11,  0x01,  0xF0,  0x8B,  0x04,  0xCE, 	/* 12790 */
+	0x70,  0xA4,  0x2A,  0x7E,  0xEA,  0x4A,  0xBC,  0xAA,  0x4E,  0xBC,  0xA8,  0x0A,  0xFE,  0xE2,  0x40,  0xC2, 	/* 127A0 */
+	0x8E,  0x01,  0x0F,  0xFE,  0xB1,  0x2A,  0xFC,  0xE1,  0x0A,  0xFC,  0xA1,  0x0F,  0xFF,  0xA1,  0x0A,  0x7C, 	/* 127B0 */
+	0xE4,  0x40,  0x7C,  0x91,  0x00,  0x0F,  0xFE,  0xB0,  0x2A,  0xFC,  0xE8,  0x4A,  0xFC,  0xA8,  0x4E,  0xFC, 	/* 127C0 */
+	0xA2,  0x0B,  0xFE,  0xE4,  0x81,  0x84,  0x9E,  0x08,  0x8F,  0xFE,  0xA8,  0x8A,  0xF8,  0xE2,  0x0B,  0xFE, 	/* 127D0 */
+	0xA2,  0x2E,  0xAA,  0xAA,  0xAB,  0x76,  0xE2,  0x22,  0x26,  0xA0,  0x0A,  0x4E,  0x68,  0xBF,  0xEB,  0x02, 	/* 127E0 */
+	0xEF,  0xCA,  0x84,  0xA8,  0x4E,  0xFC,  0xA2,  0x0A,  0xFC,  0xE2,  0x03,  0xFE,  0xA5,  0xAA,  0x05,  0x3E, 	/* 127F0 */
+	0xFE,  0x4A,  0x94,  0xF8,  0x8A,  0x94,  0xAE,  0x23,  0xF8,  0x20,  0x83,  0xF8,  0x20,  0x83,  0xF8,  0xAC, 	/* 12800 */
+	0x01,  0xEE,  0xE4,  0xAA,  0x4A,  0x58,  0xFF,  0xEB,  0x02,  0xAE,  0x4F,  0x3E,  0xB5,  0x4A,  0xFE,  0xE8, 	/* 12810 */
+	0x41,  0x04,  0xAD,  0xE2,  0x0B,  0xFE,  0xA2,  0x0F,  0x54,  0xA8,  0x8B,  0xFC,  0xE8,  0xAA,  0xF8,  0xAA, 	/* 12820 */
+	0x8E,  0xA4,  0x92,  0x40,  0x60,  0xB0,  0x00,  0x8F,  0xE8,  0xA4,  0xEB,  0xEA,  0xEA,  0xAA,  0xEA,  0xAB, 	/* 12830 */
+	0xAE,  0xE4,  0xAA,  0x4B,  0xEA,  0xE3,  0x20,  0x21,  0xB3,  0x02,  0x0E,  0xFC,  0xA4,  0x8B,  0xFE,  0xE0, 	/* 12840 */
+	0x0A,  0xFC,  0xAA,  0x4E,  0xFC,  0xAA,  0x4A,  0xFC,  0xE2,  0x01,  0xFE,  0xB6,  0x02,  0x0E,  0xFC,  0xAA, 	/* 12850 */
+	0x4B,  0xFE,  0xE0,  0x0A,  0xFC,  0xA8,  0x4E,  0xFC,  0xA8,  0x4A,  0xFC,  0xE4,  0x41,  0x82,  0xB9,  0x00, 	/* 12860 */
+	0xCF,  0xF4,  0xAA,  0x8B,  0xFE,  0xF5,  0x2A,  0xCC,  0xB3,  0xAE,  0x7A,  0xBC,  0x8A,  0x30,  0xE6,  0x81, 	/* 12870 */
+	0x86,  0xBB,  0x03,  0xCE,  0x48,  0xAF,  0xEA,  0xA8,  0xEC,  0xEA,  0xB8,  0xEF,  0xEA,  0x80,  0xAB,  0x8F, 	/* 12880 */
+	0x7C,  0x14,  0x42,  0x7C,  0xBC,  0x02,  0x0E,  0x50,  0xA8,  0x8B,  0x74,  0xE0,  0x2B,  0xDC,  0xB5,  0x4F, 	/* 12890 */
+	0xDC,  0xA4,  0x8A,  0x48,  0xEB,  0x41,  0x12,  0xBD,  0x20,  0x8F,  0xBE,  0x20,  0x8F,  0xFC,  0x4A,  0x47, 	/* 128A0 */
+	0x98,  0x52,  0x4F,  0xFA,  0x20,  0x83,  0xF8,  0x20,  0x83,  0xF8,  0xBF,  0x7B,  0xC4,  0xA4,  0x7B,  0xC4, 	/* 128B0 */
+	0xA4,  0x7B,  0xC4,  0xA4,  0x21,  0x03,  0xFE,  0x62,  0x0B,  0xFC,  0x22,  0x03,  0xFE,  0x87,  0x08,  0x8F, 	/* 128C0 */
+	0xFE,  0xAA,  0x8B,  0xFE,  0xF0,  0x2A,  0xFC,  0xA7,  0x2F,  0xAC,  0xAD,  0xCA,  0x2A,  0xEC,  0x90,  0x30, 	/* 128D0 */
+	0x8D,  0x7B,  0xC4,  0xA4,  0x7B,  0xC4,  0xA4,  0x3F,  0xC6,  0x40,  0xBF,  0x82,  0x40,  0x7F,  0xC1,  0x98, 	/* 128E0 */
+	0x0E,  0x0F,  0x1E,  0x97,  0x04,  0x07,  0xFC,  0x11,  0x05,  0xF0,  0x51,  0x07,  0xFC,  0x20,  0x8F,  0xDE, 	/* 128F0 */
+	0x28,  0xAB,  0xAE,  0xAA,  0xAF,  0xFF,  0x9A,  0x0F,  0xEE,  0x82,  0xAF,  0xEE,  0x90,  0xAD,  0x6A,  0xFC, 	/* 12900 */
+	0xED,  0x4A,  0xFE,  0xFA,  0xA1,  0xFA,  0x22,  0xA0,  0xF4,  0x9B,  0x00,  0x07,  0xF8,  0x01,  0x01,  0xA0, 	/* 12910 */
+	0x04,  0x0F,  0xFE,  0x04,  0x40,  0xC8,  0x14,  0x02,  0x40,  0xC4,  0x00,  0xC0,  0x9C,  0x01,  0x0F,  0x90, 	/* 12920 */
+	0x12,  0x86,  0x28,  0x14,  0x4F,  0xBA,  0x10,  0x03,  0x7C,  0x50,  0x49,  0x04,  0x10,  0x83,  0x08,  0xA2, 	/* 12930 */
+	0x10,  0x01,  0x00,  0x1F,  0xC2,  0x40,  0x44,  0x00,  0x40,  0xFF,  0xE0,  0x40,  0x06,  0x00,  0x90,  0x30, 	/* 12940 */
+	0x8C,  0x06,  0xA3,  0x08,  0x00,  0x90,  0x10,  0xC7,  0xF2,  0x10,  0x01,  0xFC,  0x24,  0x04,  0x40,  0xFF, 	/* 12950 */
+	0xE0,  0xA0,  0x31,  0x8C,  0x06,  0xA5,  0x20,  0x02,  0x00,  0x7F,  0xE5,  0x22,  0x92,  0x2F,  0xE2,  0x12, 	/* 12960 */
+	0x21,  0x22,  0x2A,  0x22,  0x7E,  0x42,  0x08,  0x00,  0xA7,  0x40,  0x24,  0x3A,  0x78,  0xAA,  0x0A,  0x23, 	/* 12970 */
+	0xAF,  0xC2,  0x27,  0xA3,  0x0A,  0x50,  0xA4,  0x8A,  0x80,  0xA0,  0x32,  0xA9,  0x40,  0x04,  0x7E,  0x7C, 	/* 12980 */
+	0x0A,  0x40,  0xA7,  0xC2,  0x44,  0x7C,  0x42,  0x7C,  0x34,  0x04,  0xC0,  0x44,  0x08,  0x7E,  0xAD,  0x40, 	/* 12990 */
+	0x04,  0x7E,  0x78,  0x05,  0x3C,  0x92,  0x41,  0x24,  0x7B,  0xC1,  0x00,  0x2C,  0x42,  0xA4,  0x42,  0x88, 	/* 129A0 */
+	0xFF,  0xAE,  0x40,  0xC4,  0x70,  0x79,  0x0A,  0xFE,  0x23,  0x4F,  0xD2,  0x29,  0x02,  0xFE,  0x52,  0x44, 	/* 129B0 */
+	0x64,  0x81,  0x80,  0x64,  0xAF,  0x47,  0xC4,  0x10,  0x77,  0xEA,  0x28,  0xAC,  0x62,  0x38,  0xF2,  0x82, 	/* 129C0 */
+	0xFE,  0x5B,  0xA4,  0xAA,  0x8B,  0xA0,  0x86,  0xB3,  0x00,  0x07,  0xFE,  0x04,  0x00,  0x40,  0x08,  0x00, 	/* 129D0 */
+	0x80,  0x1F,  0xC2,  0x84,  0x48,  0x48,  0x84,  0x08,  0x40,  0xFC,  0xBC,  0x00,  0x0F,  0xFE,  0x21,  0x02, 	/* 129E0 */
+	0x10,  0x41,  0x07,  0x90,  0xC9,  0x04,  0x90,  0x49,  0x04,  0x90,  0x79,  0x00,  0x7E,  0x82,  0x01,  0x0F, 	/* 129F0 */
+	0xD0,  0x21,  0x82,  0x54,  0x45,  0x47,  0x52,  0xD9,  0x65,  0x34,  0x50,  0x87,  0x10,  0x06,  0x01,  0x80, 	/* 12A00 */
+	0x8C,  0x04,  0x0F,  0xDE,  0x24,  0xA2,  0x5A,  0x4E,  0xA7,  0x4A,  0xD4,  0xA5,  0x5A,  0x56,  0xA5,  0x12, 	/* 12A10 */
+	0x71,  0x20,  0x26,  0x92,  0x04,  0x8F,  0x48,  0x24,  0x82,  0x4A,  0x47,  0xC7,  0x48,  0xD4,  0x85,  0x48, 	/* 12A20 */
+	0x54,  0x85,  0x4A,  0x77,  0xA0,  0xC6,  0x94,  0x00,  0x0F,  0xFE,  0x22,  0x42,  0x24,  0x42,  0x47,  0xFE, 	/* 12A30 */
+	0xCA,  0x44,  0xA4,  0x4A,  0x47,  0xC4,  0x04,  0x40,  0x84,  0x95,  0x02,  0x0F,  0xA0,  0x2F,  0x82,  0x28, 	/* 12A40 */
+	0x42,  0xA7,  0x46,  0xD9,  0x05,  0xFE,  0x51,  0x05,  0x10,  0x71,  0x00,  0x10,  0xA0,  0x00,  0x0F,  0xBC, 	/* 12A50 */
+	0x22,  0x42,  0x24,  0x43,  0xC7,  0xA4,  0xCA,  0x44,  0xBC,  0x4A,  0x44,  0xA4,  0x7A,  0x40,  0xFE,  0xA5, 	/* 12A60 */
+	0x00,  0x6F,  0xF8,  0x24,  0x82,  0x48,  0x47,  0xE7,  0x48,  0xD4,  0x85,  0x48,  0x56,  0x45,  0x86,  0x70, 	/* 12A70 */
+	0x60,  0x7A,  0xA6,  0x12,  0x05,  0x24,  0x5B,  0x85,  0x20,  0x5E,  0x2F,  0x1E,  0x00,  0x0F,  0xFE,  0x08, 	/* 12A80 */
+	0x03,  0xF8,  0xD0,  0x81,  0xF8,  0xA7,  0x01,  0x0F,  0x90,  0x21,  0x02,  0x1E,  0x41,  0x07,  0x90,  0xC9, 	/* 12A90 */
+	0x04,  0xFC,  0x4C,  0x44,  0xC4,  0x7C,  0x40,  0x7C,  0xB2,  0x02,  0x0F,  0xA0,  0x27,  0xE2,  0x82,  0x47, 	/* 12AA0 */
+	0xA7,  0x8A,  0xCB,  0xA4,  0xAC,  0x4A,  0x04,  0xA0,  0x7A,  0x20,  0x1E,  0xB4,  0x01,  0x0F,  0x90,  0x27, 	/* 12AB0 */
+	0xE2,  0x52,  0x45,  0x47,  0x7C,  0xD4,  0x45,  0x64,  0x55,  0x87,  0x98,  0x0A,  0x41,  0x42,  0xBA,  0x00, 	/* 12AC0 */
+	0x4F,  0xF8,  0x24,  0x02,  0x7E,  0x45,  0x07,  0x50,  0xD5,  0xC5,  0x54,  0x59,  0x47,  0xA4,  0x12,  0x42, 	/* 12AD0 */
+	0x4C,  0xBF,  0x00,  0x8F,  0x88,  0x27,  0xE2,  0x40,  0x44,  0x87,  0x48,  0xD4,  0x85,  0x4C,  0x55,  0x47, 	/* 12AE0 */
+	0x96,  0x0F,  0xA1,  0x02,  0x85,  0x01,  0x0F,  0x90,  0x27,  0xC2,  0x10,  0x41,  0x07,  0xFE,  0xD1,  0x05, 	/* 12AF0 */
+	0x10,  0x57,  0xC5,  0x10,  0x71,  0x00,  0xFE,  0x9D,  0x01,  0x0F,  0xD2,  0x23,  0x42,  0x7C,  0x44,  0x47, 	/* 12B00 */
+	0x44,  0xD7,  0xC5,  0x44,  0x57,  0xC5,  0x44,  0x74,  0x40,  0x4C,  0xAB,  0x01,  0x0F,  0xFE,  0x23,  0x02, 	/* 12B10 */
+	0x48,  0x4F,  0x47,  0x04,  0xDA,  0x85,  0xA8,  0x5A,  0x87,  0xAA,  0x0A,  0xA1,  0x06,  0xAC,  0x00,  0x0F, 	/* 12B20 */
+	0xFE,  0x21,  0x02,  0xFC,  0x49,  0x47,  0xFC,  0xD9,  0x45,  0xFC,  0x55,  0x07,  0x20,  0x0D,  0x83,  0x06, 	/* 12B30 */
+	0xAF,  0x00,  0x0F,  0xFC,  0x24,  0x42,  0x7C,  0x44,  0x47,  0x7C,  0xD4,  0x45,  0x7C,  0x52,  0x85,  0x28, 	/* 12B40 */
+	0x74,  0xA0,  0x86,  0xB2,  0x01,  0x4F,  0xD2,  0x22,  0xA2,  0x4A,  0x41,  0x47,  0xA2,  0xCC,  0x14,  0xBE, 	/* 12B50 */
+	0x4A,  0x24,  0xA2,  0x7A,  0x20,  0x3E,  0xB4,  0x02,  0x4F,  0x24,  0x2F,  0xE2,  0x24,  0x45,  0x07,  0x52, 	/* 12B60 */
+	0xDD,  0x45,  0x58,  0x55,  0x05,  0x50,  0x75,  0x20,  0x4E,  0xBC,  0x00,  0x0F,  0xEE,  0x2A,  0xA2,  0xAA, 	/* 12B70 */
+	0x4E,  0xE7,  0xAA,  0xDA,  0xA5,  0xEE,  0x5A,  0xA5,  0xAA,  0x7A,  0xA1,  0x76,  0x81,  0x10,  0x87,  0xFE, 	/* 12B80 */
+	0x10,  0x81,  0xF8,  0x10,  0x81,  0xF8,  0x10,  0x8F,  0xFF,  0x14,  0x82,  0xFC,  0xD8,  0xB0,  0xF8,  0x86, 	/* 12B90 */
+	0x41,  0x02,  0xFE,  0x89,  0x24,  0xFC,  0x2A,  0x44,  0x98,  0x96,  0x6F,  0xFE,  0x08,  0x03,  0xFC,  0xD0, 	/* 12BA0 */
+	0x41,  0xFC,  0x87,  0x01,  0x0F,  0xFE,  0x28,  0x22,  0x00,  0x7F,  0xE5,  0x10,  0xD5,  0x05,  0x50,  0x55, 	/* 12BB0 */
+	0xC7,  0x50,  0x0B,  0x01,  0x0E,  0x8C,  0x02,  0x0F,  0xBC,  0x24,  0x42,  0x78,  0x40,  0x87,  0xFE,  0xD1, 	/* 12BC0 */
+	0x25,  0xDA,  0x53,  0x45,  0x54,  0x79,  0x20,  0x30,  0x8D,  0x00,  0x0F,  0x7C,  0x24,  0x42,  0x7C,  0x44, 	/* 12BD0 */
+	0x47,  0xFE,  0xD0,  0x45,  0xFE,  0x52,  0x45,  0x14,  0x70,  0x40,  0x0C,  0x8E,  0x01,  0x0F,  0x90,  0x2F, 	/* 12BE0 */
+	0xE2,  0x44,  0x44,  0x47,  0x6C,  0xD9,  0x25,  0x10,  0x5F,  0xE5,  0x10,  0x71,  0x00,  0x10,  0x91,  0x01, 	/* 12BF0 */
+	0x0F,  0xA0,  0x27,  0xE2,  0x52,  0x47,  0xE7,  0x52,  0xD7,  0xE5,  0x28,  0x54,  0x85,  0xFE,  0x70,  0x80, 	/* 12C00 */
+	0x08,  0x93,  0x02,  0x4F,  0x48,  0x27,  0xE2,  0xC8,  0x54,  0x87,  0x7E,  0xD4,  0x85,  0x48,  0x57,  0xE5, 	/* 12C10 */
+	0x48,  0x74,  0x80,  0x7E,  0x95,  0x01,  0x0F,  0xFE,  0x21,  0x02,  0x28,  0x44,  0x47,  0xFE,  0xD0,  0x45, 	/* 12C20 */
+	0x74,  0x55,  0x45,  0x74,  0x70,  0x40,  0x0C,  0x97,  0x00,  0x8F,  0x08,  0x2F,  0xF2,  0x81,  0x47,  0x77, 	/* 12C30 */
+	0x55,  0xD5,  0x55,  0xB7,  0x51,  0x45,  0x24,  0x74,  0x50,  0x83,  0x9A,  0x01,  0x0F,  0x90,  0x2F,  0xE2, 	/* 12C40 */
+	0x44,  0x42,  0x87,  0xFE,  0xD0,  0x05,  0x7C,  0x54,  0x45,  0x44,  0x74,  0x40,  0x7C,  0xA3,  0x00,  0x0F, 	/* 12C50 */
+	0xFC,  0x24,  0x42,  0x7C,  0x44,  0x47,  0x7C,  0xD2,  0x05,  0x7E,  0x5D,  0x25,  0x6A,  0x77,  0xA0,  0x0C, 	/* 12C60 */
+	0xA7,  0x00,  0x8F,  0xBE,  0x22,  0x2F,  0xBE,  0x3A,  0x2E,  0x3E,  0x00,  0x0F,  0xFE,  0x10,  0x03,  0xFC, 	/* 12C70 */
+	0xD0,  0x41,  0xFC,  0xA9,  0x00,  0x0F,  0xFE,  0x22,  0x02,  0x7C,  0x44,  0x47,  0x7C,  0xD4,  0x45,  0x7C, 	/* 12C80 */
+	0x54,  0x45,  0x7C,  0x72,  0x40,  0xC2,  0xAA,  0x02,  0x4F,  0xFE,  0x22,  0x42,  0x3C,  0x42,  0x47,  0x3C, 	/* 12C90 */
+	0xD2,  0x45,  0xFF,  0x55,  0x45,  0x66,  0x74,  0x00,  0x7E,  0xAF,  0x02,  0xAF,  0xAA,  0x25,  0x42,  0x2A, 	/* 12CA0 */
+	0x42,  0xA7,  0x7E,  0xD4,  0xA5,  0x6A,  0x55,  0x25,  0x6A,  0x74,  0x60,  0x7E,  0xB5,  0x01,  0x0F,  0x9E, 	/* 12CB0 */
+	0x21,  0x02,  0x7C,  0x44,  0x47,  0x7C,  0xD4,  0x45,  0x7C,  0x54,  0x45,  0x7C,  0x72,  0x40,  0xC2,  0xBA, 	/* 12CC0 */
+	0x01,  0x0F,  0xFE,  0x2A,  0x22,  0x28,  0x47,  0xE7,  0xC8,  0xD7,  0xC5,  0x48,  0x57,  0xC5,  0x48,  0x74, 	/* 12CD0 */
+	0x80,  0x7E,  0xBC,  0x00,  0x0F,  0xFE,  0x24,  0x82,  0x7E,  0x44,  0x87,  0x7E,  0xD4,  0x85,  0x7E,  0x50, 	/* 12CE0 */
+	0x25,  0x56,  0x75,  0x20,  0x8C,  0xBE,  0x00,  0x0F,  0xFE,  0x24,  0x22,  0x7E,  0x45,  0x47,  0x7E,  0xD5, 	/* 12CF0 */
+	0x45,  0x7F,  0x56,  0xA7,  0xA4,  0x4B,  0xA1,  0x61,  0x81,  0x04,  0x4F,  0x28,  0x2F,  0xE2,  0x24,  0x42, 	/* 12D00 */
+	0x47,  0xDA,  0xD5,  0xA5,  0x24,  0x56,  0xC5,  0x5A,  0x7F,  0xE0,  0x12,  0x85,  0x01,  0x0F,  0xFE,  0x24, 	/* 12D10 */
+	0x42,  0x28,  0x4F,  0xE7,  0x92,  0xDF,  0xE5,  0x20,  0x53,  0xC5,  0x24,  0x74,  0x40,  0x98,  0x86,  0x00, 	/* 12D20 */
+	0x0F,  0xFC,  0x24,  0x42,  0x5C,  0x45,  0x47,  0xFF,  0xD4,  0x55,  0x7C,  0x54,  0x45,  0x7C,  0x74,  0x40, 	/* 12D30 */
+	0x4C,  0x8A,  0x00,  0x07,  0xFC,  0x10,  0x03,  0xF8,  0x50,  0x81,  0xF8,  0xFB,  0xF2,  0x08,  0x79,  0xEC, 	/* 12D40 */
+	0xB2,  0x4D,  0x27,  0x9E,  0x8B,  0x04,  0x4F,  0x28,  0x2F,  0xE2,  0x10,  0x47,  0xC7,  0x10,  0xDF,  0xE5, 	/* 12D50 */
+	0x20,  0x57,  0xE5,  0x88,  0x70,  0x80,  0x7E,  0x90,  0x23,  0x87,  0xAA,  0x4A,  0xEF,  0xFC,  0x5A,  0x44, 	/* 12D60 */
+	0x98,  0x9E,  0x67,  0xFE,  0x08,  0x03,  0xFC,  0xD0,  0x41,  0xFC,  0x91,  0x01,  0x0F,  0x92,  0x2F,  0xE2, 	/* 12D70 */
+	0x00,  0x4F,  0xE7,  0x00,  0xD7,  0xC5,  0x44,  0x57,  0xC5,  0x44,  0x72,  0x80,  0xFE,  0x94,  0x04,  0x4F, 	/* 12D80 */
+	0x74,  0x25,  0xE2,  0xB4,  0x43,  0xE7,  0x44,  0xD9,  0x45,  0xFE,  0x53,  0x85,  0x54,  0x79,  0x20,  0x10, 	/* 12D90 */
+	0x9A,  0x01,  0x0F,  0xFE,  0x25,  0x42,  0x7C,  0x45,  0x47,  0x7C,  0xD1,  0x25,  0xFD,  0x50,  0x45,  0xFE, 	/* 12DA0 */
+	0x72,  0x40,  0x0C,  0xA7,  0x01,  0x0F,  0xFE,  0x21,  0x02,  0x7C,  0x41,  0x07,  0xFF,  0xD4,  0x45,  0x7C, 	/* 12DB0 */
+	0x54,  0x45,  0x7C,  0x72,  0x40,  0xC2,  0xA8,  0x02,  0x07,  0xFE,  0x48,  0x87,  0xFE,  0x5D,  0xC6,  0xAA, 	/* 12DC0 */
+	0x48,  0x87,  0xFE,  0x48,  0x09,  0xFC,  0xA8,  0x40,  0xFC,  0xAC,  0x11,  0xCF,  0xD4,  0x12,  0x67,  0xFC, 	/* 12DD0 */
+	0x55,  0x47,  0xCC,  0x83,  0x2F,  0xFE,  0x10,  0x03,  0xFC,  0xD0,  0x41,  0xFC,  0xAF,  0x04,  0x4F,  0xAA, 	/* 12DE0 */
+	0x2D,  0xC2,  0x56,  0x4F,  0xE7,  0x1A,  0xDF,  0xF5,  0x4A,  0x54,  0xC5,  0xBA,  0x72,  0x60,  0xC2,  0xB4, 	/* 12DF0 */
+	0x06,  0xAF,  0xAC,  0x2A,  0xA2,  0x44,  0x4B,  0xA7,  0x01,  0xD7,  0xC5,  0x44,  0x57,  0xC5,  0x24,  0x71, 	/* 12E00 */
+	0x80,  0xFE,  0xBD,  0x01,  0x0F,  0x7C,  0x21,  0x02,  0xFE,  0x44,  0x47,  0xEE,  0xD4,  0x45,  0xFE,  0x50, 	/* 12E10 */
+	0x05,  0xFE,  0x72,  0x80,  0xCE,  0x81,  0x02,  0x4F,  0x28,  0x27,  0xE2,  0xC8,  0x47,  0xE7,  0x48,  0xD7, 	/* 12E20 */
+	0xE5,  0x48,  0x57,  0xE5,  0x00,  0x76,  0xA0,  0x95,  0x87,  0x01,  0x0F,  0xFE,  0x24,  0xA2,  0x76,  0x45, 	/* 12E30 */
+	0xA7,  0xFE,  0xD5,  0xA5,  0x76,  0x51,  0x05,  0xFF,  0x72,  0x80,  0xC6,  0x8E,  0x04,  0x8F,  0xFE,  0x24, 	/* 12E40 */
+	0x82,  0xEC,  0x55,  0xA4,  0x48,  0x7F,  0xED,  0x10,  0x55,  0xE5,  0x50,  0x77,  0x00,  0x8F,  0x91,  0x05, 	/* 12E50 */
+	0x2F,  0xB4,  0x27,  0xE2,  0x42,  0x43,  0xC7,  0x24,  0xD3,  0xC5,  0x7E,  0x55,  0x25,  0x7E,  0x75,  0x20, 	/* 12E60 */
+	0x7E,  0x92,  0x04,  0x4F,  0xFE,  0x21,  0x02,  0x7C,  0x41,  0x07,  0xFE,  0xD2,  0x85,  0xCA,  0x5F,  0xE5, 	/* 12E70 */
+	0x44,  0x7E,  0xA0,  0x52,  0x99,  0x09,  0xEF,  0xEA,  0x28,  0x42,  0x9F,  0x47,  0x67,  0x44,  0xDF,  0x45, 	/* 12E80 */
+	0xA6,  0x5F,  0x47,  0x5C,  0x0B,  0x41,  0x23,  0xA6,  0x01,  0x0F,  0xFE,  0x25,  0x42,  0x7E,  0x45,  0x47, 	/* 12E90 */
+	0x7F,  0xD6,  0xA5,  0x7E,  0x56,  0xA7,  0xBE,  0x49,  0x41,  0x22,  0xAA,  0x00,  0x0F,  0xFE,  0x26,  0x82, 	/* 12EA0 */
+	0x7E,  0x45,  0x47,  0x7C,  0xD5,  0x45,  0x7C,  0x57,  0xE7,  0xD2,  0x0F,  0xA1,  0x46,  0xAB,  0x09,  0x2F, 	/* 12EB0 */
+	0x54,  0x2B,  0xA2,  0xEC,  0x4B,  0xA7,  0xEE,  0xDB,  0xA5,  0x10,  0x5F,  0xE7,  0x34,  0x0D,  0x20,  0x10, 	/* 12EC0 */
+	0xAC,  0x2A,  0x8F,  0x5E,  0x2A,  0xC7,  0x5A,  0xAA,  0x8F,  0xFE,  0x11,  0x03,  0xF8,  0xC8,  0x61,  0xF8, 	/* 12ED0 */
+	0x68,  0x80,  0xF8,  0xBA,  0x00,  0x03,  0xF8,  0x00,  0x00,  0x00,  0xFF,  0xE0,  0x40,  0x24,  0x82,  0x44, 	/* 12EE0 */
+	0x44,  0x28,  0x42,  0x04,  0x00,  0xC0,  0xBC,  0x22,  0x02,  0x20,  0xFA,  0x00,  0xA0,  0x12,  0x03,  0x20, 	/* 12EF0 */
+	0x6A,  0x0A,  0x60,  0x22,  0x02,  0x22,  0x22,  0x22,  0x1E,  0xBE,  0x21,  0x02,  0x10,  0xF9,  0x01,  0x10, 	/* 12F00 */
+	0x17,  0xC2,  0x10,  0x71,  0x06,  0x90,  0xA1,  0x02,  0x10,  0x2F,  0xE2,  0x00,  0x80,  0x00,  0x07,  0x3C, 	/* 12F10 */
+	0x02,  0x40,  0x24,  0xFA,  0x42,  0x3C,  0xAA,  0x0A,  0xA0,  0xAA,  0x0A,  0xA2,  0xA2,  0x22,  0x1E,  0x81, 	/* 12F20 */
+	0x20,  0x02,  0x3C,  0xFA,  0x40,  0xA8,  0x13,  0x02,  0x28,  0x72,  0x4A,  0xA2,  0x22,  0x22,  0x2C,  0x22, 	/* 12F30 */
+	0x02,  0x20,  0x87,  0x20,  0xC2,  0x78,  0xFC,  0x80,  0xC8,  0x14,  0x82,  0x7E,  0x74,  0x8A,  0xC8,  0x24, 	/* 12F40 */
+	0x82,  0x44,  0x27,  0x62,  0xC2,  0x88,  0x20,  0x42,  0x78,  0xF4,  0x01,  0x40,  0x17,  0xE2,  0x48,  0x74, 	/* 12F50 */
+	0x8A,  0xC8,  0x24,  0x82,  0x88,  0x28,  0x83,  0x08,  0x89,  0x21,  0x02,  0x10,  0xF1,  0x01,  0x10,  0x15, 	/* 12F60 */
+	0xE2,  0x50,  0x75,  0x0A,  0x50,  0x25,  0x02,  0x50,  0x25,  0x02,  0xFE,  0x90,  0x21,  0x02,  0x10,  0xFF, 	/* 12F70 */
+	0xF1,  0x10,  0x21,  0x02,  0x20,  0x73,  0xEA,  0xE2,  0x26,  0x22,  0xA2,  0x22,  0x22,  0x3E,  0x93,  0x02, 	/* 12F80 */
+	0x8F,  0x24,  0x07,  0xEF,  0x20,  0x22,  0x0A,  0xA4,  0xAA,  0x4A,  0xD4,  0xAC,  0x8A,  0x88,  0x21,  0x42, 	/* 12F90 */
+	0x62,  0x95,  0xF1,  0x00,  0x08,  0xF8,  0x02,  0x12,  0x21,  0x2A,  0xD4,  0xAD,  0x4A,  0x9A,  0xA9,  0x2A, 	/* 12FA0 */
+	0x30,  0x25,  0x22,  0x0E,  0x96,  0x20,  0x02,  0x7C,  0xF4,  0x41,  0x44,  0x27,  0xC2,  0x44,  0x74,  0x4A, 	/* 12FB0 */
+	0xFC,  0x24,  0x42,  0x44,  0x24,  0x42,  0xFE,  0x97,  0x00,  0x67,  0x38,  0x02,  0x80,  0x28,  0xFA,  0x82, 	/* 12FC0 */
+	0x3E,  0xAA,  0x8A,  0xA8,  0xAA,  0x4A,  0x76,  0xA0,  0x22,  0x7A,  0x9A,  0x02,  0x07,  0x20,  0x03,  0xE0, 	/* 12FD0 */
+	0x30,  0xFD,  0x02,  0x5E,  0xA9,  0x0A,  0x90,  0xA9,  0xEA,  0x90,  0xA1,  0x02,  0x10,  0x9D,  0x20,  0x02, 	/* 12FE0 */
+	0x7C,  0xF4,  0x41,  0x44,  0x24,  0x42,  0x7C,  0x72,  0x8A,  0xA8,  0x22,  0x82,  0x4A,  0x24,  0xA2,  0x86, 	/* 12FF0 */
+	0x9E,  0x21,  0x02,  0x10,  0xFF,  0xE1,  0x52,  0x17,  0xE2,  0x52,  0x35,  0x26,  0xFE,  0xA1,  0x02,  0x10, 	/* 13000 */
+	0x21,  0x02,  0x10,  0x9F,  0x04,  0x04,  0x44,  0x7F,  0xC0,  0x40,  0x7F,  0xE4,  0x02,  0x7F,  0xA0,  0x00, 	/* 13010 */
+	0xFF,  0xE1,  0x58,  0x64,  0x60,  0xC0,  0xA0,  0x00,  0x07,  0x7E,  0x00,  0x20,  0x3A,  0xF8,  0x22,  0x3A, 	/* 13020 */
+	0xAA,  0xAA,  0xAA,  0xAB,  0xAA,  0x82,  0xA0,  0x22,  0x06,  0xA2,  0x22,  0x02,  0x20,  0xF4,  0x01,  0x7E, 	/* 13030 */
+	0x29,  0x02,  0x10,  0x75,  0x4A,  0xD2,  0x25,  0x22,  0x92,  0x21,  0x02,  0x30,  0xA5,  0x24,  0x42,  0x28, 	/* 13040 */
+	0xF7,  0xE1,  0x10,  0x11,  0x02,  0x7C,  0x71,  0x0A,  0x90,  0x2F,  0xE2,  0x10,  0x21,  0x02,  0x10,  0xA8, 	/* 13050 */
+	0xFF,  0xE0,  0xA0,  0x7F,  0xC4,  0xA4,  0x7F,  0xC0,  0x00,  0x7F,  0xC0,  0x00,  0xFF,  0xE2,  0x58,  0xC4, 	/* 13060 */
+	0x60,  0xC0,  0xAD,  0x20,  0x03,  0xFC,  0x4A,  0x8A,  0x90,  0x52,  0x82,  0x46,  0xDF,  0x80,  0x00,  0x7F, 	/* 13070 */
+	0xE2,  0x50,  0x24,  0x84,  0xC4,  0xB7,  0x21,  0x02,  0x7E,  0xF1,  0x01,  0x7C,  0x21,  0x02,  0xFE,  0x72, 	/* 13080 */
+	0x4A,  0xFE,  0x26,  0x42,  0x94,  0x30,  0x42,  0x0C,  0xBA,  0x02,  0x47,  0x24,  0x0F,  0xE0,  0x24,  0xFB, 	/* 13090 */
+	0xC2,  0x24,  0xAB,  0xCA,  0xA4,  0xAA,  0x4A,  0x7E,  0xA1,  0x42,  0x62,  0xBF,  0x01,  0x0F,  0x1E,  0x02, 	/* 130A0 */
+	0x4F,  0xFE,  0x20,  0x8A,  0xFE,  0xA8,  0xAA,  0xAA,  0xA9,  0xCA,  0x2A,  0x2C,  0x92,  0x18,  0x80,  0x04, 	/* 130B0 */
+	0x0F,  0xFE,  0x2A,  0x82,  0xE8,  0x20,  0x83,  0xF8,  0x7F,  0xC0,  0x00,  0xFF,  0xE2,  0x48,  0xC4,  0x40, 	/* 130C0 */
+	0xC0,  0x81,  0x21,  0x0F,  0xFE,  0x33,  0x02,  0xD8,  0x65,  0x4A,  0x12,  0x3F,  0x80,  0x00,  0xFF,  0xE2, 	/* 130D0 */
+	0x48,  0xC4,  0x40,  0xC0,  0x84,  0x20,  0x02,  0x7C,  0xF0,  0x41,  0x7C,  0x20,  0x42,  0xFE,  0x79,  0x2A, 	/* 130E0 */
+	0x54,  0x23,  0x82,  0xD4,  0x21,  0x22,  0x30,  0x85,  0x29,  0x22,  0x54,  0xF7,  0xC1,  0x54,  0x27,  0xC3, 	/* 130F0 */
+	0x54,  0x6F,  0xCA,  0x10,  0x2F,  0xE2,  0x10,  0x21,  0x02,  0x10,  0x8A,  0x04,  0x0E,  0xFE,  0x04,  0xAF, 	/* 13100 */
+	0xEA,  0x24,  0xAA,  0x72,  0xBA,  0x6A,  0x90,  0xAF,  0xEA,  0x90,  0x22,  0x82,  0xC6,  0x8D,  0x27,  0xC2, 	/* 13110 */
+	0x44,  0xF5,  0xC1,  0x54,  0x25,  0x42,  0xFE,  0x78,  0x2A,  0xBA,  0x2A,  0xA2,  0xAA,  0x2B,  0xA2,  0x86, 	/* 13120 */
+	0x8E,  0x21,  0x02,  0x1E,  0xF1,  0x01,  0x7C,  0x24,  0x42,  0x7C,  0x74,  0x4A,  0xFC,  0x24,  0x42,  0x7C, 	/* 13130 */
+	0x22,  0x42,  0xC2,  0x8F,  0x2F,  0xE2,  0x00,  0xF7,  0xC1,  0x44,  0x27,  0xC3,  0x00,  0x6F,  0xEA,  0x92, 	/* 13140 */
+	0x2F,  0xE2,  0x92,  0x29,  0x22,  0xFE,  0x9D,  0x07,  0xC7,  0x54,  0x07,  0xCF,  0xD4,  0x27,  0xCB,  0x28, 	/* 13150 */
+	0xB4,  0xEB,  0x78,  0xAC,  0x8A,  0x30,  0x24,  0x83,  0x86,  0xA6,  0x28,  0xE4,  0xFA,  0xAA,  0xA6,  0x3A, 	/* 13160 */
+	0xAA,  0xE2,  0xF8,  0x20,  0x87,  0xFC,  0x00,  0x0F,  0xFE,  0x15,  0x06,  0x4C,  0xA7,  0x01,  0x0F,  0xFE, 	/* 13170 */
+	0x01,  0x0F,  0x7C,  0x24,  0x4A,  0xFC,  0xAA,  0x8A,  0xFE,  0xA8,  0x0A,  0x7C,  0x24,  0x42,  0x7C,  0xAA, 	/* 13180 */
+	0x0E,  0xEF,  0xAA,  0x0E,  0xEF,  0x80,  0x27,  0xCA,  0xD4,  0xAF,  0xCA,  0xD4,  0xA7,  0xCA,  0x10,  0x2F, 	/* 13190 */
+	0xE2,  0x10,  0xAE,  0x01,  0x87,  0x7E,  0x05,  0xAF,  0xFE,  0x25,  0xAA,  0xFE,  0xA8,  0x0A,  0xFE,  0xAC, 	/* 131A0 */
+	0x4A,  0x7C,  0x22,  0x82,  0xFE,  0xB0,  0x2F,  0xE2,  0x54,  0xF9,  0x21,  0xFE,  0x29,  0x22,  0xD6,  0x7B, 	/* 131B0 */
+	0xAA,  0xD6,  0x2B,  0xA2,  0xD6,  0x29,  0x22,  0x96,  0xB3,  0x01,  0x07,  0x7E,  0x00,  0x0F,  0xEE,  0x2A, 	/* 131C0 */
+	0xAA,  0xEE,  0xB2,  0x8B,  0xFE,  0xB2,  0x2A,  0xD4,  0x24,  0x82,  0xE6,  0xB9,  0x01,  0xC7,  0xE0,  0x04, 	/* 131D0 */
+	0x07,  0xFC,  0x44,  0x47,  0xFC,  0x04,  0x0F,  0xFE,  0x86,  0x28,  0x52,  0xBE,  0xA8,  0x06,  0xBA,  0x00, 	/* 131E0 */
+	0x07,  0xFC,  0x44,  0x47,  0xFC,  0x44,  0x47,  0xFC,  0x04,  0x0F,  0xFE,  0x86,  0x28,  0x52,  0xBE,  0xA8, 	/* 131F0 */
+	0x06,  0xBD,  0x04,  0x00,  0xB0,  0x3F,  0xCC,  0x93,  0x26,  0x42,  0x94,  0x3F,  0xC0,  0x40,  0x7F,  0xE4, 	/* 13200 */
+	0x52,  0x5F,  0xA4,  0x0A,  0xBE,  0x01,  0x87,  0xE0,  0x04,  0x00,  0x40,  0xFF,  0xE0,  0x40,  0x0E,  0x01, 	/* 13210 */
+	0x50,  0x24,  0x8C,  0x46,  0x04,  0x00,  0x40,  0xBF,  0x01,  0xC3,  0xE0,  0x04,  0x0F,  0xFE,  0x0E,  0x03, 	/* 13220 */
+	0x58,  0xC4,  0x60,  0x90,  0x09,  0x00,  0x92,  0x31,  0x2C,  0x0E,  0x80,  0x00,  0x83,  0xF0,  0x04,  0x0F, 	/* 13230 */
+	0xFE,  0x0E,  0x03,  0x58,  0xC4,  0x63,  0xF0,  0x09,  0xC0,  0x84,  0x10,  0x46,  0x18,  0x81,  0x0D,  0x07, 	/* 13240 */
+	0x10,  0x11,  0x01,  0x10,  0x7D,  0x03,  0x20,  0x3A,  0x85,  0x24,  0x52,  0x49,  0x5E,  0x1E,  0x21,  0x02, 	/* 13250 */
+	0x89,  0x01,  0x83,  0xE0,  0x04,  0x0F,  0xFE,  0x04,  0x8F,  0xFE,  0x04,  0x87,  0xF8,  0x0E,  0x03,  0x58, 	/* 13260 */
+	0xC4,  0x60,  0x40,  0x8B,  0x19,  0x0E,  0x10,  0x21,  0x22,  0x52,  0xFD,  0x42,  0x98,  0x71,  0x06,  0x90, 	/* 13270 */
+	0xA2,  0x8A,  0x28,  0x24,  0x42,  0x82,  0x91,  0x18,  0x4E,  0x24,  0x21,  0x42,  0x04,  0xFA,  0x43,  0x14, 	/* 13280 */
+	0x68,  0x46,  0x0F,  0xA7,  0x42,  0x04,  0x20,  0x42,  0x04,  0x92,  0x31,  0x0E,  0x10,  0x25,  0x82,  0x54, 	/* 13290 */
+	0xF5,  0x22,  0x96,  0x71,  0x46,  0xB8,  0xA0,  0x8A,  0x10,  0x26,  0x03,  0x80,  0x95,  0x14,  0x8E,  0x48, 	/* 132A0 */
+	0x24,  0x8F,  0x49,  0x27,  0xA7,  0x4C,  0x74,  0x8A,  0x48,  0xA4,  0x8A,  0x48,  0x27,  0x92,  0xC7,  0x98, 	/* 132B0 */
+	0x12,  0x0E,  0x10,  0x21,  0x4F,  0x24,  0x2A,  0x86,  0xA8,  0x7B,  0x46,  0xB2,  0xB2,  0x2A,  0x60,  0x3A, 	/* 132C0 */
+	0x42,  0x1C,  0x9F,  0x10,  0x0E,  0x7C,  0x24,  0x42,  0x44,  0xFF,  0xC2,  0x44,  0x74,  0x46,  0xFC,  0xA4, 	/* 132D0 */
+	0x4A,  0x44,  0x24,  0x42,  0xFE,  0xA1,  0x12,  0x0E,  0x28,  0x22,  0x42,  0xFE,  0xF2,  0x02,  0x24,  0x72, 	/* 132E0 */
+	0x46,  0xA4,  0xA5,  0x8A,  0x48,  0x29,  0x43,  0x22,  0xA3,  0x19,  0x0E,  0x10,  0x2F,  0xE2,  0x10,  0xF9, 	/* 132F0 */
+	0x02,  0x7C,  0x71,  0x06,  0xB8,  0xA3,  0x8A,  0x54,  0x29,  0x22,  0x10,  0xA4,  0x30,  0x0E,  0xFE,  0x21, 	/* 13300 */
+	0x42,  0x54,  0xFB,  0x86,  0x30,  0x7F,  0xEA,  0x90,  0xA1,  0x02,  0x10,  0x21,  0x02,  0x10,  0xA6,  0x04, 	/* 13310 */
+	0x07,  0xFC,  0x04,  0x03,  0xF8,  0x0A,  0x0F,  0xFE,  0x26,  0x85,  0xC4,  0xBF,  0xB0,  0xE0,  0x35,  0x80, 	/* 13320 */
+	0x40,  0xA7,  0x31,  0x0E,  0x10,  0x27,  0xC2,  0x54,  0xF5,  0x42,  0x54,  0x7F,  0xF6,  0x90,  0xA3,  0x0A, 	/* 13330 */
+	0x28,  0x24,  0x42,  0x82,  0xA9,  0x31,  0x0E,  0x50,  0x25,  0x0F,  0x7E,  0x29,  0x06,  0x10,  0x77,  0xEA, 	/* 13340 */
+	0x90,  0xA2,  0x82,  0x28,  0x24,  0x43,  0x82,  0xAC,  0x18,  0x0E,  0x7E,  0x22,  0x02,  0x20,  0xFB,  0xE2, 	/* 13350 */
+	0x22,  0x72,  0x26,  0xBE,  0xA2,  0x0A,  0x20,  0x22,  0x02,  0x3E,  0xB0,  0x1A,  0x0E,  0x20,  0x27,  0xE2, 	/* 13360 */
+	0x50,  0xF9,  0x02,  0x18,  0x75,  0x46,  0xD4,  0xA5,  0x2A,  0x92,  0x21,  0x02,  0x30,  0xBB,  0x1A,  0x0E, 	/* 13370 */
+	0x3C,  0x24,  0x4F,  0xA8,  0x21,  0x07,  0x68,  0x69,  0xE6,  0x22,  0xAD,  0x4A,  0x08,  0x23,  0x02,  0xC0, 	/* 13380 */
+	0x80,  0x12,  0x4E,  0x18,  0x26,  0x42,  0xFE,  0xF5,  0x02,  0x7C,  0x6D,  0x47,  0x54,  0xA5,  0x4A,  0x5C, 	/* 13390 */
+	0x21,  0x02,  0x10,  0x88,  0x17,  0xCE,  0x44,  0x27,  0xC2,  0x44,  0xF7,  0xC2,  0x00,  0x77,  0xC6,  0x90, 	/* 133A0 */
+	0xA1,  0x0A,  0xFE,  0x21,  0x02,  0x10,  0x8B,  0x18,  0x0E,  0x7C,  0x24,  0x42,  0x44,  0xFF,  0xC2,  0x00, 	/* 133B0 */
+	0x77,  0xC6,  0x90,  0xA7,  0xCA,  0x10,  0x21,  0x02,  0xFE,  0x8D,  0x11,  0x0E,  0x54,  0x29,  0x22,  0x10, 	/* 133C0 */
+	0xF7,  0xC2,  0x44,  0x77,  0xC6,  0xC4,  0xA7,  0xCA,  0x44,  0x24,  0x42,  0x4C,  0x8E,  0x14,  0x4E,  0x28, 	/* 133D0 */
+	0x27,  0xC2,  0x44,  0xFC,  0x42,  0x7C,  0x71,  0x86,  0x98,  0xA2,  0x8A,  0x2A,  0x24,  0xA2,  0x86,  0x94, 	/* 133E0 */
+	0x09,  0x0F,  0x28,  0x24,  0x42,  0x3A,  0xF8,  0x02,  0x7C,  0x70,  0x86,  0x90,  0xA2,  0x8A,  0x6A,  0x2A, 	/* 133F0 */
+	0x52,  0x1C,  0x97,  0x08,  0x8F,  0x10,  0x27,  0xE2,  0x52,  0xFF,  0xE2,  0x52,  0x77,  0xE6,  0x28,  0xAF, 	/* 13400 */
+	0xEA,  0x08,  0x20,  0x82,  0x08,  0x98,  0x1A,  0x4E,  0x24,  0x27,  0xEF,  0xA4,  0x23,  0xC7,  0x24,  0x6B, 	/* 13410 */
+	0xC6,  0x24,  0xAF,  0xFA,  0x14,  0x22,  0x22,  0x42,  0x99,  0x19,  0x0E,  0x7E,  0x21,  0x02,  0xBC,  0xFA, 	/* 13420 */
+	0x42,  0xBC,  0x7A,  0x46,  0xBC,  0xAA,  0x4A,  0xBC,  0x28,  0x02,  0xFE,  0x9A,  0x12,  0x4E,  0x28,  0x27, 	/* 13430 */
+	0xE2,  0x48,  0xFC,  0x82,  0x7C,  0x74,  0x86,  0xC8,  0xA7,  0xCA,  0x48,  0x24,  0x82,  0x7E,  0x9C,  0x31, 	/* 13440 */
+	0x0E,  0x7E,  0x21,  0x02,  0xFE,  0xF2,  0x82,  0xCE,  0x61,  0x07,  0x3C,  0xAE,  0x42,  0x18,  0x22,  0x82, 	/* 13450 */
+	0xC6,  0x9F,  0x04,  0x0F,  0xFE,  0x2A,  0x82,  0xE8,  0x20,  0x83,  0xF8,  0x7F,  0xC0,  0x40,  0xFF,  0xE1, 	/* 13460 */
+	0x50,  0x24,  0xCC,  0x42,  0xA0,  0x17,  0xEE,  0x52,  0x25,  0x22,  0x7E,  0xF5,  0x22,  0x7E,  0x75,  0x26, 	/* 13470 */
+	0x7A,  0xA6,  0xAA,  0xBA,  0x28,  0x23,  0x06,  0xAE,  0x18,  0xCE,  0x70,  0x21,  0x02,  0xFE,  0xFD,  0x42, 	/* 13480 */
+	0x7C,  0x75,  0x46,  0xFC,  0xA1,  0x0A,  0x7C,  0x21,  0x02,  0xFE,  0xB1,  0x10,  0xEE,  0x74,  0x25,  0x22, 	/* 13490 */
+	0x8A,  0xF9,  0x02,  0x7C,  0x75,  0x46,  0xFC,  0xA5,  0x4A,  0xFE,  0x24,  0x42,  0x4C,  0xB2,  0x18,  0xEE, 	/* 134A0 */
+	0x7A,  0x22,  0xAF,  0xAC,  0x22,  0x87,  0x5E,  0x6D,  0x26,  0xD2,  0xA5,  0xEA,  0x52,  0x25,  0x22,  0x5E, 	/* 134B0 */
+	0xB7,  0x18,  0x0E,  0x7E,  0x24,  0xA2,  0x7E,  0xFC,  0xA2,  0x7E,  0x72,  0x86,  0xCF,  0xA3,  0xCA,  0xE4, 	/* 134C0 */
+	0x21,  0x82,  0xE6,  0xBB,  0x10,  0xEE,  0xF4,  0x25,  0x42,  0x92,  0xF2,  0x22,  0x6C,  0x74,  0x46,  0xC4, 	/* 134D0 */
+	0xA6,  0xCA,  0x44,  0x24,  0x42,  0x7C,  0xBC,  0x31,  0x0E,  0xFE,  0x28,  0x22,  0xFC,  0xFA,  0x03,  0x32, 	/* 134E0 */
+	0x6D,  0x4B,  0x38,  0xAD,  0x43,  0x12,  0x21,  0x02,  0x60,  0xBD,  0x12,  0x4E,  0xFE,  0x23,  0x02,  0x4E, 	/* 134F0 */
+	0xFC,  0x42,  0x78,  0x74,  0x26,  0xFE,  0xA4,  0x4A,  0x7C,  0x24,  0x42,  0x7C,  0xBE,  0x04,  0x0F,  0xFE, 	/* 13500 */
+	0x11,  0x07,  0xFC,  0x51,  0x45,  0xF4,  0x43,  0xC3,  0xC0,  0xFF,  0xE3,  0x58,  0xC4,  0x60,  0x40,  0xBF, 	/* 13510 */
+	0x19,  0x0E,  0xFE,  0x20,  0x02,  0x7C,  0xFC,  0x42,  0x7C,  0x6F,  0xE7,  0x82,  0xAB,  0xAA,  0xAA,  0x2B, 	/* 13520 */
+	0xA2,  0x86,  0x80,  0x23,  0x8F,  0xA8,  0x22,  0x8F,  0xAA,  0x8C,  0xE7,  0x80,  0x23,  0xCF,  0x84,  0x72, 	/* 13530 */
+	0x86,  0x90,  0xA2,  0x82,  0x46,  0x82,  0x31,  0x0E,  0xFE,  0x21,  0x0F,  0xFE,  0x29,  0x26,  0xFE,  0x79, 	/* 13540 */
+	0x26,  0xFE,  0xA0,  0x8A,  0xA8,  0x2A,  0x23,  0x1A,  0x83,  0x11,  0x0E,  0xFE,  0x28,  0x22,  0xAA,  0xFB, 	/* 13550 */
+	0x42,  0x52,  0x72,  0x86,  0x44,  0xAF,  0xEA,  0x44,  0x24,  0x42,  0x7C,  0x86,  0x11,  0x0E,  0x7C,  0x24, 	/* 13560 */
+	0x4F,  0xFC,  0x24,  0x43,  0x7C,  0x65,  0x47,  0x9A,  0xA1,  0x0A,  0x64,  0x21,  0x82,  0xE0,  0x89,  0x17, 	/* 13570 */
+	0xEE,  0x42,  0x27,  0xEF,  0x48,  0x26,  0xE6,  0x48,  0x75,  0x86,  0x5E,  0xAA,  0x8A,  0xFE,  0x30,  0x82, 	/* 13580 */
+	0x08,  0x8D,  0x11,  0x0E,  0xFE,  0x21,  0x02,  0x7C,  0xF1,  0x02,  0xFE,  0x74,  0x46,  0xFC,  0xA4,  0x4A, 	/* 13590 */
+	0x7C,  0x22,  0x42,  0xC2,  0x8E,  0x80,  0x0F,  0x7E,  0x81,  0x07,  0xBE,  0x02,  0x27,  0xBE,  0x22,  0x2F, 	/* 135A0 */
+	0xBE,  0x22,  0x27,  0x3E,  0xAA,  0x42,  0x42,  0x8F,  0x31,  0xEE,  0xE4,  0x29,  0x42,  0x58,  0xFF,  0xC2, 	/* 135B0 */
+	0x04,  0x77,  0xC6,  0x04,  0xAF,  0xCA,  0xB4,  0x2A,  0xA2,  0x9E,  0x90,  0x1A,  0x0E,  0x3C,  0x24,  0x82, 	/* 135C0 */
+	0x7C,  0xFD,  0x42,  0x7C,  0x75,  0x46,  0xFE,  0xA9,  0x2A,  0xFE,  0x21,  0x12,  0x0F,  0x97,  0x11,  0x0E, 	/* 135D0 */
+	0xFE,  0x25,  0x4F,  0x7C,  0x25,  0x46,  0x7C,  0x71,  0x46,  0xFA,  0xA3,  0x0A,  0xAA,  0x32,  0x22,  0x1E, 	/* 135E0 */
+	0xA1,  0x19,  0x0E,  0xFE,  0x21,  0x02,  0x54,  0xF5,  0x42,  0xBA,  0x71,  0x06,  0xFE,  0xAA,  0xAA,  0xBA, 	/* 135F0 */
+	0x28,  0x22,  0xFE,  0xA2,  0x11,  0x0E,  0x5C,  0x25,  0x0F,  0xFE,  0x20,  0xA6,  0xFE,  0x78,  0x86,  0xFA, 	/* 13600 */
+	0xAA,  0xAA,  0xB4,  0x2A,  0xC3,  0x52,  0xA3,  0x11,  0x0E,  0xFE,  0x22,  0x82,  0x44,  0xFA,  0xA2,  0xFC, 	/* 13610 */
+	0x72,  0x86,  0xFE,  0xA5,  0x2B,  0xCC,  0x27,  0x42,  0xC2,  0xA9,  0x10,  0xEE,  0xF4,  0x25,  0x22,  0x88, 	/* 13620 */
+	0xFF,  0xC2,  0x10,  0x7F,  0xE6,  0x04,  0xAF,  0xCA,  0x54,  0x2C,  0xA3,  0x3E,  0xAB,  0x32,  0x8E,  0xFE, 	/* 13630 */
+	0x22,  0x8F,  0x50,  0x27,  0xE6,  0xD0,  0x77,  0xC6,  0x50,  0xAF,  0xEA,  0x48,  0x23,  0x02,  0xCE,  0xB0, 	/* 13640 */
+	0x11,  0x0E,  0xFE,  0x2A,  0xA2,  0xEE,  0xF2,  0x82,  0xFE,  0x72,  0x86,  0xFE,  0xA2,  0x2B,  0xD4,  0x24, 	/* 13650 */
+	0x82,  0xE6,  0xB4,  0x04,  0x00,  0x40,  0xFF,  0xE8,  0x02,  0x80,  0x21,  0x70,  0x11,  0x01,  0x10,  0x20, 	/* 13660 */
+	0x82,  0x08,  0x40,  0x48,  0x02,  0xB6,  0x04,  0x0F,  0xFE,  0x92,  0x29,  0x22,  0x12,  0x42,  0x5C,  0x44, 	/* 13670 */
+	0x07,  0xF0,  0x09,  0x00,  0x92,  0x11,  0x26,  0x0E,  0xB9,  0x04,  0x0F,  0xFE,  0x8A,  0x21,  0x24,  0xE1, 	/* 13680 */
+	0xC1,  0xF8,  0x00,  0x83,  0xF8,  0x20,  0x03,  0xFC,  0x00,  0x40,  0x38,  0xBA,  0x04,  0x0F,  0xFE,  0x92, 	/* 13690 */
+	0x29,  0x22,  0x12,  0x42,  0x1C,  0x40,  0x03,  0xFC,  0x04,  0x00,  0x40,  0x04,  0x0F,  0xFE,  0xBD,  0x04, 	/* 136A0 */
+	0x0F,  0xFE,  0x8A,  0x21,  0x24,  0xE1,  0xC1,  0x10,  0x7F,  0xC1,  0x10,  0xFF,  0xE1,  0x10,  0x21,  0x04, 	/* 136B0 */
+	0x10,  0xBF,  0x04,  0x0F,  0xFE,  0x8A,  0x27,  0x3C,  0x00,  0x07,  0xFC,  0x11,  0x01,  0x10,  0xFF,  0xE0, 	/* 136C0 */
+	0xD0,  0x31,  0x0C,  0x30,  0x81,  0x04,  0x0F,  0xFE,  0x92,  0x29,  0x22,  0x12,  0x42,  0x5C,  0x44,  0x0F, 	/* 136D0 */
+	0xFE,  0x04,  0x00,  0xA0,  0x31,  0x8C,  0x06,  0x83,  0x04,  0x0F,  0xFE,  0x8A,  0x28,  0xA2,  0x73,  0xC0, 	/* 136E0 */
+	0x00,  0x4F,  0xCF,  0xA4,  0x42,  0x44,  0x24,  0x34,  0x40,  0x98,  0x84,  0x04,  0x0F,  0xFE,  0x92,  0x21, 	/* 136F0 */
+	0x20,  0x29,  0xE4,  0x80,  0x0F,  0xE3,  0x40,  0xC7,  0xC0,  0x40,  0x07,  0xC0,  0x40,  0x88,  0x04,  0x0F, 	/* 13700 */
+	0xFE,  0x8A,  0x21,  0x24,  0xE1,  0xC2,  0x10,  0x2F,  0xCC,  0x94,  0x31,  0x42,  0xA4,  0x5C,  0x4E,  0x98, 	/* 13710 */
+	0x92,  0x04,  0x0F,  0xFE,  0x8A,  0x21,  0x3C,  0x60,  0x0F,  0xFE,  0x11,  0x87,  0xE4,  0x04,  0x03,  0xF8, 	/* 13720 */
+	0x04,  0x0F,  0xFE,  0x93,  0x04,  0x0F,  0xFE,  0x92,  0x2A,  0x9E,  0x4A,  0x01,  0x18,  0x7E,  0x40,  0x40, 	/* 13730 */
+	0x52,  0x45,  0x02,  0x91,  0x20,  0xF0,  0x95,  0x04,  0x0F,  0xFE,  0x8A,  0x21,  0x24,  0xE1,  0xC0,  0xA0, 	/* 13740 */
+	0x4A,  0xC2,  0xB0,  0x3B,  0x8D,  0x24,  0x22,  0x24,  0x1E,  0x96,  0x04,  0x0F,  0xFE,  0x8A,  0x27,  0x3C, 	/* 13750 */
+	0x24,  0x03,  0xF8,  0x44,  0x0F,  0xFE,  0x04,  0x03,  0xF8,  0x20,  0x83,  0xF8,  0x97,  0x04,  0x0F,  0xFE, 	/* 13760 */
+	0x8A,  0x21,  0x24,  0xE1,  0xE7,  0xFC,  0x47,  0x45,  0x94,  0x76,  0x44,  0xB4,  0x70,  0xC7,  0xFC,  0x98, 	/* 13770 */
+	0x04,  0x0F,  0xFE,  0x8A,  0x27,  0x3C,  0x3F,  0x80,  0x88,  0xFF,  0xE0,  0x88,  0x7F,  0x83,  0xFC,  0xD0, 	/* 13780 */
+	0x41,  0xFC,  0x9F,  0x04,  0x0F,  0xFE,  0x90,  0xA3,  0xF8,  0xE0,  0xE3,  0xF8,  0x22,  0x03,  0x24,  0x3F, 	/* 13790 */
+	0xC4,  0x20,  0xA2,  0x43,  0xFC,  0xA9,  0x04,  0x0F,  0xFE,  0x8A,  0x2F,  0x3C,  0x3F,  0x82,  0x78,  0x24, 	/* 137A0 */
+	0x8F,  0xFE,  0x9F,  0x29,  0x12,  0x9F,  0x28,  0x06,  0xAA,  0x04,  0x0F,  0xFE,  0x8A,  0x27,  0x1C,  0x42, 	/* 137B0 */
+	0x02,  0xFC,  0x82,  0x05,  0xFE,  0x02,  0x02,  0xFC,  0x42,  0x0B,  0xFE,  0xAE,  0x04,  0x0F,  0xFE,  0x8A, 	/* 137C0 */
+	0x27,  0x3E,  0x10,  0x07,  0xBE,  0x48,  0x27,  0x9E,  0x4A,  0x0F,  0xBE,  0x28,  0x2D,  0x8C,  0xAF,  0x04, 	/* 137D0 */
+	0x0F,  0xFE,  0x8A,  0x27,  0x3C,  0x1B,  0x07,  0xFC,  0x04,  0x07,  0xFC,  0x04,  0x0F,  0xFE,  0x4A,  0x48, 	/* 137E0 */
+	0x92,  0xB0,  0x04,  0x0F,  0xFE,  0x8A,  0x2F,  0x3C,  0x0F,  0x07,  0x20,  0x2C,  0x0F,  0xFC,  0x24,  0x0F, 	/* 137F0 */
+	0xFE,  0x44,  0x47,  0xFC,  0xB6,  0x04,  0x0F,  0xFE,  0x8A,  0x27,  0x3C,  0xFF,  0xE2,  0x48,  0x7F,  0xC4, 	/* 13800 */
+	0x44,  0xFF,  0xE3,  0x10,  0x0E,  0x07,  0x18,  0xBA,  0x04,  0x0F,  0xFE,  0x8A,  0x27,  0x3C,  0x20,  0x07, 	/* 13810 */
+	0xBC,  0x22,  0x4F,  0xFC,  0x32,  0x42,  0xBC,  0x42,  0xA8,  0xCE,  0xBF,  0x04,  0x0F,  0xFE,  0x8A,  0x2F, 	/* 13820 */
+	0x3C,  0x73,  0x85,  0x48,  0x6B,  0x05,  0x68,  0x5D,  0x67,  0x7C,  0x41,  0x04,  0xFE,  0x83,  0x04,  0x0F, 	/* 13830 */
+	0xFE,  0x95,  0x26,  0xEC,  0x04,  0x07,  0xFC,  0x24,  0x87,  0xFC,  0x44,  0x47,  0xFC,  0x04,  0x20,  0x3E, 	/* 13840 */
+	0x84,  0x04,  0x0F,  0xFE,  0x8A,  0x27,  0x3C,  0x10,  0x07,  0xBC,  0x40,  0x47,  0xFC,  0x24,  0x83,  0x6A, 	/* 13850 */
+	0x24,  0x6F,  0x72,  0x85,  0x04,  0x0F,  0xFE,  0x8A,  0x27,  0x3C,  0x21,  0x07,  0xDE,  0x46,  0x47,  0xD4, 	/* 13860 */
+	0x11,  0x4F,  0xC8,  0x25,  0x45,  0xA2,  0x87,  0x04,  0x0F,  0xFE,  0x8A,  0x27,  0x1C,  0xFF,  0xE4,  0xA4, 	/* 13870 */
+	0x7F,  0xC2,  0x08,  0x3F,  0x82,  0x08,  0x3F,  0x86,  0x0C,  0x88,  0x04,  0x0F,  0xFE,  0x8A,  0x27,  0x3C, 	/* 13880 */
+	0x04,  0x07,  0xFC,  0x4A,  0x4F,  0xBE,  0x8A,  0x2F,  0xBE,  0x0A,  0x10,  0x7F,  0x8A,  0x04,  0x0F,  0xFE, 	/* 13890 */
+	0x8A,  0x27,  0x3C,  0x18,  0x8E,  0xBE,  0xB3,  0x4F,  0xAC,  0x37,  0xE6,  0xCA,  0xA7,  0xE2,  0x42,  0x8B, 	/* 138A0 */
+	0x04,  0x00,  0x40,  0x04,  0x07,  0xFC,  0x00,  0x82,  0x08,  0x10,  0x81,  0x08,  0x09,  0x00,  0x90,  0x02, 	/* 138B0 */
+	0x0F,  0xFE,  0x8D,  0x21,  0x02,  0x10,  0x21,  0x0F,  0x90,  0x11,  0x09,  0xFE,  0x51,  0x05,  0x10,  0x21, 	/* 138C0 */
+	0x03,  0x90,  0xC1,  0x00,  0x10,  0x8F,  0x20,  0xC2,  0x70,  0x21,  0x0F,  0x90,  0x11,  0x09,  0xFE,  0x51, 	/* 138D0 */
+	0x05,  0x10,  0x21,  0x03,  0x90,  0xC1,  0x00,  0x10,  0x92,  0x08,  0x00,  0x80,  0x7F,  0xC2,  0x10,  0x12, 	/* 138E0 */
+	0x0F,  0xFE,  0x00,  0x83,  0xC8,  0x24,  0x82,  0x48,  0x3C,  0x80,  0x18,  0x93,  0x20,  0xC2,  0x70,  0x21, 	/* 138F0 */
+	0x0F,  0x9E,  0x17,  0x09,  0x10,  0x51,  0xE5,  0xF0,  0x21,  0x03,  0x92,  0xC1,  0x20,  0x0E,  0x95,  0x20, 	/* 13900 */
+	0x82,  0x28,  0x22,  0x4F,  0xA4,  0x14,  0x29,  0x7D,  0x59,  0x45,  0x14,  0x22,  0x43,  0xA4,  0xC4,  0x40, 	/* 13910 */
+	0x98,  0x99,  0x21,  0x02,  0x10,  0x21,  0x0F,  0x9E,  0x11,  0x09,  0x10,  0x51,  0x05,  0x7C,  0x24,  0x43, 	/* 13920 */
+	0xC4,  0xC4,  0x40,  0x7C,  0x9A,  0x21,  0x02,  0xFE,  0x28,  0x2F,  0x80,  0x17,  0xE9,  0x10,  0x51,  0x05, 	/* 13930 */
+	0x10,  0x21,  0x03,  0x90,  0xC1,  0x00,  0x30,  0x9C,  0x04,  0x07,  0xFC,  0x11,  0x0F,  0xFE,  0x00,  0x03, 	/* 13940 */
+	0xF8,  0x24,  0x83,  0xF8,  0x24,  0x83,  0xFA,  0x04,  0x20,  0x3E,  0x9D,  0x21,  0x02,  0x10,  0x2F,  0xEF, 	/* 13950 */
+	0x84,  0x14,  0x49,  0x24,  0x52,  0x45,  0x28,  0x22,  0x83,  0x88,  0xC1,  0x00,  0xFE,  0x9F,  0x04,  0x07, 	/* 13960 */
+	0xFC,  0x11,  0x0F,  0xFE,  0x00,  0x03,  0xF8,  0x20,  0x83,  0xF8,  0x20,  0x83,  0xFA,  0x09,  0x2F,  0x0E, 	/* 13970 */
+	0xA0,  0x04,  0x07,  0xFC,  0x11,  0x0F,  0xFE,  0x20,  0x83,  0xF8,  0x20,  0x83,  0xF8,  0x04,  0x0F,  0xFE, 	/* 13980 */
+	0x04,  0x00,  0x40,  0xA1,  0x20,  0x02,  0xFE,  0x21,  0x0F,  0xA0,  0x17,  0xC9,  0x44,  0x54,  0x45,  0x7C, 	/* 13990 */
+	0x24,  0x43,  0xC4,  0xC4,  0x40,  0x7C,  0xA2,  0x20,  0x82,  0x14,  0x27,  0xAF,  0xA2,  0x12,  0x09,  0x3E, 	/* 139A0 */
+	0x52,  0x85,  0x48,  0x23,  0xE3,  0x98,  0xC2,  0x40,  0xC2,  0xA3,  0x01,  0x02,  0x24,  0x2F,  0xEF,  0xAA, 	/* 139B0 */
+	0x12,  0x89,  0xCE,  0x52,  0x04,  0xBC,  0x36,  0x4C,  0x18,  0x03,  0x81,  0xC6,  0xA5,  0x04,  0x07,  0xFC, 	/* 139C0 */
+	0x11,  0x0F,  0xFE,  0x24,  0x83,  0xF8,  0x24,  0x83,  0xF8,  0x04,  0x07,  0xFC,  0x04,  0x0F,  0xFE,  0xA6, 	/* 139D0 */
+	0x21,  0x02,  0x10,  0x2F,  0xEF,  0x90,  0x17,  0xC9,  0x54,  0x55,  0x45,  0x7C,  0x23,  0x83,  0x54,  0xC9, 	/* 139E0 */
+	0x20,  0x10,  0xAA,  0x00,  0x0F,  0xBE,  0xA2,  0x2F,  0x94,  0xF8,  0x8A,  0x14,  0xFA,  0x20,  0x40,  0x7F, 	/* 139F0 */
+	0xE1,  0x08,  0x09,  0x0F,  0xFE,  0xAD,  0x20,  0x02,  0x7C,  0x24,  0x4F,  0xFC,  0x14,  0x49,  0x7C,  0x52, 	/* 13A00 */
+	0x05,  0x7E,  0x2C,  0xA3,  0x56,  0xC7,  0xE0,  0x0C,  0xAF,  0x21,  0x02,  0x92,  0xF9,  0x21,  0xFE,  0x50, 	/* 13A10 */
+	0x05,  0xFE,  0x52,  0x06,  0xFE,  0x7A,  0xAC,  0xAA,  0x0A,  0xA0,  0x86,  0xB0,  0x27,  0xE2,  0x40,  0x27, 	/* 13A20 */
+	0xEF,  0xEA,  0x17,  0xE9,  0x6A,  0x57,  0xE5,  0x48,  0x27,  0xE3,  0x48,  0xC8,  0x80,  0xFE,  0xB6,  0x11, 	/* 13A30 */
+	0x0F,  0xFC,  0x52,  0x8F,  0xFE,  0x00,  0x07,  0xBC,  0x4A,  0x47,  0xBC,  0x2A,  0x82,  0xAA,  0x4C,  0xA8, 	/* 13A40 */
+	0x86,  0xB8,  0x10,  0x87,  0xFE,  0x29,  0x4F,  0xFE,  0x4A,  0x47,  0xBC,  0x4A,  0x47,  0xBC,  0x31,  0x83, 	/* 13A50 */
+	0x1A,  0x5A,  0xA9,  0x46,  0xB9,  0x22,  0x02,  0x20,  0x22,  0x03,  0xBE,  0x52,  0x85,  0x48,  0x94,  0x81, 	/* 13A60 */
+	0x08,  0x10,  0x81,  0x08,  0x10,  0x81,  0x18,  0xBA,  0x42,  0x04,  0x20,  0x7B,  0xE9,  0x48,  0x11,  0x00, 	/* 13A70 */
+	0x00,  0x7F,  0x80,  0x00,  0x00,  0x00,  0x00,  0xFF,  0xE0,  0x00,  0xBF,  0x42,  0x07,  0xBE,  0x94,  0x82, 	/* 13A80 */
+	0x10,  0x7F,  0xC0,  0x40,  0x04,  0x0F,  0xFE,  0x04,  0x00,  0x40,  0x04,  0x00,  0x40,  0x82,  0x42,  0x07, 	/* 13A90 */
+	0xBE,  0x94,  0x82,  0x50,  0x04,  0x0F,  0xF8,  0x04,  0x83,  0x48,  0x0C,  0x80,  0xAA,  0x31,  0xAC,  0x06, 	/* 13AA0 */
+	0x84,  0x42,  0x07,  0xBE,  0x94,  0x82,  0x10,  0x00,  0x07,  0xFC,  0x11,  0x01,  0x10,  0xFF,  0xE1,  0x10, 	/* 13AB0 */
+	0x21,  0x04,  0x10,  0x86,  0x42,  0x07,  0xBE,  0x94,  0x82,  0x10,  0x3F,  0x82,  0x48,  0x24,  0x83,  0xF8, 	/* 13AC0 */
+	0x20,  0x02,  0x00,  0x20,  0x21,  0xFE,  0x88,  0x42,  0x07,  0xBE,  0x94,  0x82,  0x10,  0x7E,  0x01,  0x20, 	/* 13AD0 */
+	0x13,  0x81,  0x08,  0x29,  0x04,  0x60,  0x9B,  0x06,  0x0C,  0x8A,  0x42,  0x07,  0xBE,  0x94,  0x82,  0x10, 	/* 13AE0 */
+	0x03,  0x83,  0xD0,  0x25,  0x02,  0x50,  0x24,  0x84,  0x48,  0x44,  0x48,  0x42,  0x8B,  0x42,  0x07,  0xBE, 	/* 13AF0 */
+	0x94,  0x82,  0x10,  0x3F,  0x80,  0x48,  0xFF,  0xE0,  0x48,  0x3F,  0x80,  0x40,  0x08,  0x03,  0x00,  0x8F, 	/* 13B00 */
+	0x42,  0x07,  0xBE,  0x94,  0x81,  0x10,  0x10,  0x01,  0xFE,  0x29,  0x24,  0x92,  0x92,  0x22,  0x22,  0x04, 	/* 13B10 */
+	0x40,  0x18,  0x91,  0x41,  0x07,  0xDE,  0xA2,  0x81,  0x04,  0x03,  0x03,  0xC0,  0x04,  0x0F,  0xFE,  0x04, 	/* 13B20 */
+	0x00,  0xA0,  0x31,  0x8C,  0x06,  0x98,  0x42,  0x07,  0xBE,  0x94,  0x82,  0x10,  0x04,  0x00,  0x7E,  0x04, 	/* 13B30 */
+	0x00,  0x40,  0x3F,  0x82,  0x08,  0x20,  0x83,  0xF8,  0x99,  0x42,  0x07,  0xBE,  0x94,  0x82,  0x10,  0x14, 	/* 13B40 */
+	0x01,  0x40,  0x3F,  0xC4,  0x40,  0xBF,  0x80,  0x40,  0x04,  0x0F,  0xFE,  0x9B,  0x42,  0x07,  0xBE,  0x52, 	/* 13B50 */
+	0x89,  0x48,  0x25,  0x00,  0x40,  0x7F,  0xC4,  0x44,  0x7F,  0xC4,  0x44,  0x44,  0x47,  0xFC,  0x9E,  0x42, 	/* 13B60 */
+	0x07,  0xBE,  0x94,  0x82,  0x50,  0x0A,  0x01,  0x18,  0xFF,  0x40,  0x02,  0x3F,  0x82,  0x08,  0x20,  0x83, 	/* 13B70 */
+	0xF8,  0xA0,  0x42,  0x04,  0x20,  0x7B,  0xE5,  0x48,  0x89,  0x00,  0x40,  0xFF,  0xE0,  0x10,  0x21,  0x01, 	/* 13B80 */
+	0x10,  0x12,  0x0F,  0xFE,  0xA5,  0x21,  0x03,  0xDE,  0x52,  0x40,  0x88,  0xFF,  0xE0,  0x02,  0x7F,  0xA0, 	/* 13B90 */
+	0x02,  0x3E,  0x22,  0x22,  0x3E,  0x20,  0x06,  0xA6,  0x42,  0x07,  0xBE,  0x94,  0x82,  0x10,  0x10,  0x82, 	/* 13BA0 */
+	0xFE,  0x68,  0x8A,  0x48,  0x24,  0x82,  0x08,  0x20,  0x82,  0x18,  0xA8,  0x42,  0x07,  0xBE,  0x94,  0x82, 	/* 13BB0 */
+	0x10,  0x04,  0x0F,  0xFE,  0x0E,  0x01,  0x50,  0x24,  0x8D,  0xF6,  0x04,  0x00,  0x40,  0xAC,  0x42,  0x07, 	/* 13BC0 */
+	0xBE,  0x94,  0x87,  0xFC,  0x04,  0x47,  0xFC,  0x44,  0x07,  0xFE,  0x0C,  0x23,  0x42,  0xC4,  0xC0,  0x40, 	/* 13BD0 */
+	0xB3,  0x42,  0x07,  0xBE,  0x94,  0x82,  0x10,  0x20,  0x0F,  0xBE,  0x2A,  0x22,  0xA2,  0x2A,  0x24,  0xA2, 	/* 13BE0 */
+	0x4B,  0xEB,  0x00,  0xB5,  0x42,  0x07,  0xBE,  0x94,  0x82,  0x10,  0x40,  0x02,  0xFC,  0x88,  0x44,  0x84, 	/* 13BF0 */
+	0x09,  0x82,  0x80,  0x48,  0x28,  0x7E,  0xB6,  0x42,  0x07,  0xBE,  0x94,  0x82,  0x10,  0x20,  0x03,  0xF8, 	/* 13C00 */
+	0x44,  0x00,  0x40,  0x7F,  0xE0,  0xA0,  0x31,  0x8C,  0x06,  0xB9,  0x42,  0x07,  0xBE,  0x94,  0x82,  0x10, 	/* 13C10 */
+	0x25,  0x02,  0x50,  0xFF,  0xE2,  0x50,  0x25,  0x02,  0x70,  0x20,  0x03,  0xFC,  0x85,  0x42,  0x07,  0xBE, 	/* 13C20 */
+	0x94,  0x82,  0x50,  0x14,  0x03,  0xFC,  0x44,  0x0F,  0xFE,  0x12,  0x01,  0x20,  0x22,  0x2C,  0x1E,  0x86, 	/* 13C30 */
+	0x42,  0x07,  0xBE,  0x94,  0x83,  0xF8,  0x04,  0x8F,  0xFE,  0x04,  0x83,  0xF8,  0x04,  0x07,  0xFC,  0x04, 	/* 13C40 */
+	0x00,  0x40,  0x88,  0x42,  0x07,  0xBE,  0x94,  0x80,  0x84,  0x07,  0x87,  0xC0,  0x04,  0x0F,  0xFE,  0x04, 	/* 13C50 */
+	0x03,  0xF8,  0x20,  0x83,  0xF8,  0x89,  0x42,  0x07,  0xBC,  0xA4,  0x81,  0x50,  0x7F,  0xC0,  0x40,  0xFF, 	/* 13C60 */
+	0xE0,  0x10,  0x7F,  0xC1,  0x10,  0x09,  0x00,  0x30,  0x8B,  0x42,  0x07,  0xBE,  0x94,  0x87,  0x90,  0x4F, 	/* 13C70 */
+	0xE7,  0x92,  0x49,  0x24,  0x92,  0x79,  0x24,  0xA2,  0x4A,  0x29,  0xCC,  0x8C,  0x42,  0x07,  0xBE,  0x94, 	/* 13C80 */
+	0x82,  0x50,  0x0A,  0x03,  0x18,  0xC0,  0x63,  0xF8,  0x04,  0x01,  0xF0,  0x04,  0x0F,  0xFE,  0x8D,  0x42, 	/* 13C90 */
+	0x07,  0xBE,  0x94,  0x82,  0x10,  0x10,  0x01,  0xFE,  0x3F,  0x2D,  0x12,  0x1F,  0x21,  0x12,  0x1F,  0x20, 	/* 13CA0 */
+	0x0C,  0x8F,  0x42,  0x07,  0xBE,  0x94,  0x82,  0x20,  0x22,  0x83,  0xFE,  0x62,  0x4A,  0x18,  0x21,  0x02, 	/* 13CB0 */
+	0x2A,  0x2C,  0x62,  0x02,  0x90,  0x42,  0x07,  0xBE,  0x94,  0x82,  0x10,  0x7F,  0xE5,  0xFC,  0x42,  0x04, 	/* 13CC0 */
+	0xF8,  0x42,  0x05,  0xFC,  0x40,  0x07,  0xFE,  0x91,  0x42,  0x07,  0xBE,  0x94,  0x81,  0x10,  0xFF,  0x82, 	/* 13CD0 */
+	0x48,  0x24,  0x82,  0x68,  0x35,  0x8E,  0x4A,  0x08,  0xA1,  0x06,  0x92,  0x21,  0x07,  0xBE,  0xA4,  0x81, 	/* 13CE0 */
+	0x10,  0x7F,  0xE4,  0x02,  0x5F,  0xA4,  0x02,  0x5F,  0xA5,  0x0A,  0x5F,  0xA4,  0x06,  0x94,  0x41,  0x07, 	/* 13CF0 */
+	0xBE,  0xA4,  0x81,  0x48,  0x0A,  0x01,  0x10,  0x2E,  0x8C,  0x06,  0x3F,  0x82,  0x08,  0x20,  0x83,  0xF8, 	/* 13D00 */
+	0x96,  0x42,  0x07,  0xBE,  0x94,  0x82,  0x10,  0xFF,  0xE0,  0x40,  0x7F,  0xC4,  0x44,  0x4E,  0xC3,  0x58, 	/* 13D10 */
+	0xC4,  0x60,  0x40,  0x9D,  0x42,  0x07,  0xBE,  0x94,  0x82,  0xF0,  0x12,  0x07,  0xF8,  0x04,  0x8F,  0xFE, 	/* 13D20 */
+	0x04,  0x87,  0xF8,  0x04,  0x00,  0xC0,  0xA5,  0x42,  0x07,  0xBE,  0x94,  0x82,  0x10,  0x3F,  0x82,  0x08, 	/* 13D30 */
+	0x3F,  0x80,  0x80,  0x7F,  0xC4,  0x04,  0x40,  0x47,  0xFC,  0xA7,  0x42,  0x07,  0xBE,  0x94,  0x82,  0x10, 	/* 13D40 */
+	0x3F,  0x82,  0x08,  0x3F,  0x82,  0x08,  0x3F,  0x80,  0x92,  0x31,  0x2C,  0x0E,  0xAC,  0x42,  0x07,  0xBE, 	/* 13D50 */
+	0x94,  0x82,  0x10,  0x02,  0x47,  0xFE,  0x42,  0x07,  0x94,  0x49,  0x44,  0x8A,  0x69,  0x69,  0x22,  0xAE, 	/* 13D60 */
+	0x42,  0x07,  0xBE,  0x94,  0x82,  0x10,  0x7F,  0xC0,  0x40,  0x24,  0x82,  0x48,  0x55,  0x48,  0x42,  0x04, 	/* 13D70 */
+	0x0F,  0xFE,  0xB0,  0x42,  0x07,  0xBE,  0x94,  0x83,  0x50,  0x17,  0xE2,  0xA0,  0x6B,  0xEB,  0x20,  0x23, 	/* 13D80 */
+	0xE2,  0x20,  0x22,  0x02,  0x20,  0xB1,  0x41,  0x07,  0xBE,  0x94,  0x82,  0x20,  0x23,  0xE3,  0x44,  0x5A, 	/* 13D90 */
+	0x4D,  0x28,  0x51,  0x85,  0x18,  0x52,  0x44,  0xC2,  0xB4,  0x42,  0x07,  0xBE,  0x94,  0x82,  0x10,  0x04, 	/* 13DA0 */
+	0x0F,  0xFE,  0x24,  0x82,  0x48,  0x55,  0x48,  0xA2,  0x31,  0x8C,  0x06,  0xB5,  0x42,  0x07,  0xBE,  0x94, 	/* 13DB0 */
+	0x82,  0x10,  0xF0,  0x61,  0x78,  0x21,  0x07,  0x5C,  0xD5,  0x03,  0x7E,  0x2C,  0x0C,  0x3F,  0xBA,  0x42, 	/* 13DC0 */
+	0x07,  0xBE,  0x94,  0x82,  0x10,  0x7F,  0xE5,  0xFC,  0x42,  0x04,  0xFC,  0x42,  0x25,  0xFC,  0x40,  0x07, 	/* 13DD0 */
+	0xFE,  0x86,  0x41,  0x07,  0xDF,  0x92,  0x47,  0xFC,  0x44,  0x44,  0xA4,  0x51,  0x44,  0x20,  0x7B,  0xC4, 	/* 13DE0 */
+	0x20,  0x5A,  0x2E,  0x1E,  0x87,  0x21,  0x07,  0xBE,  0x94,  0x87,  0xFE,  0x44,  0x25,  0xFA,  0x44,  0x25, 	/* 13DF0 */
+	0xFA,  0x50,  0xA5,  0xFA,  0x40,  0x27,  0xFE,  0x8B,  0x42,  0x07,  0xBE,  0x94,  0x82,  0x10,  0xFF,  0xE0, 	/* 13E00 */
+	0x90,  0x7E,  0x42,  0x1C,  0xFF,  0xE1,  0x98,  0x07,  0x27,  0x8E,  0x8D,  0x42,  0x07,  0xBE,  0x94,  0x82, 	/* 13E10 */
+	0x10,  0x2F,  0xEF,  0x88,  0x2B,  0xE2,  0xAA,  0x3A,  0xAE,  0xAE,  0x28,  0x86,  0xFE,  0x8F,  0x42,  0x07, 	/* 13E20 */
+	0xBE,  0x95,  0x83,  0xE8,  0x22,  0x45,  0xF8,  0x04,  0x8F,  0xFE,  0x04,  0x87,  0xF8,  0x04,  0x00,  0xC0, 	/* 13E30 */
+	0x92,  0x42,  0x07,  0xBE,  0x94,  0x83,  0xF0,  0x01,  0x0F,  0xFC,  0x01,  0x0F,  0xFE,  0xBF,  0xA2,  0x48, 	/* 13E40 */
+	0x25,  0x80,  0x40,  0x94,  0x42,  0x07,  0xBE,  0x94,  0x80,  0x40,  0x4F,  0xC2,  0x84,  0x88,  0x44,  0xFC, 	/* 13E50 */
+	0x28,  0x44,  0x84,  0x88,  0x48,  0xFC,  0x95,  0x42,  0x07,  0xBE,  0x94,  0x81,  0x10,  0x7F,  0xE1,  0x08, 	/* 13E60 */
+	0x1F,  0x81,  0xF8,  0x10,  0x87,  0xFE,  0x19,  0x8E,  0x06,  0x97,  0x42,  0x07,  0xBE,  0x94,  0x83,  0xF8, 	/* 13E70 */
+	0x20,  0x83,  0xF8,  0x20,  0x83,  0xF8,  0x20,  0x8F,  0xFE,  0x11,  0x02,  0x10,  0x98,  0x42,  0x07,  0xBE, 	/* 13E80 */
+	0x94,  0x82,  0x10,  0x7F,  0xC5,  0xF4,  0x44,  0x47,  0xFC,  0x4E,  0x47,  0x5C,  0x44,  0x47,  0xFC,  0x99, 	/* 13E90 */
+	0x42,  0x07,  0xBE,  0x94,  0x87,  0xBE,  0x4A,  0x24,  0xA4,  0x7B,  0xE4,  0xB2,  0x7A,  0xC4,  0xA4,  0x4A, 	/* 13EA0 */
+	0xC9,  0xD2,  0x9A,  0x42,  0x07,  0xBE,  0x94,  0x81,  0x10,  0x10,  0x22,  0x92,  0x45,  0x2B,  0xF2,  0x01, 	/* 13EB0 */
+	0x27,  0xD2,  0x44,  0x27,  0xC6,  0x9C,  0x42,  0x07,  0xBE,  0x94,  0x82,  0x50,  0xFF,  0xE8,  0xA2,  0x31, 	/* 13EC0 */
+	0xEC,  0x00,  0x3F,  0x80,  0x40,  0x04,  0x0F,  0xFE,  0x9D,  0x42,  0x07,  0xBE,  0x94,  0x82,  0x10,  0x24, 	/* 13ED0 */
+	0x4F,  0xFE,  0x24,  0x42,  0x44,  0x37,  0xCE,  0x44,  0x24,  0x46,  0x7C,  0x9F,  0x42,  0x07,  0xBE,  0x94, 	/* 13EE0 */
+	0x83,  0xF8,  0x20,  0x83,  0xF8,  0x20,  0x83,  0xF8,  0x22,  0x43,  0xB8,  0x22,  0x2F,  0x9E,  0xA1,  0x41, 	/* 13EF0 */
+	0x07,  0xDE,  0x92,  0x4F,  0xFE,  0x80,  0x29,  0xF2,  0x11,  0x01,  0xF0,  0x10,  0x01,  0xF8,  0x10,  0x81, 	/* 13F00 */
+	0xF8,  0xAA,  0x41,  0x07,  0xDE,  0x92,  0x82,  0x50,  0x3F,  0x82,  0x48,  0x3F,  0x82,  0x48,  0xFF,  0xE0, 	/* 13F10 */
+	0x40,  0x04,  0x00,  0x40,  0xAD,  0x42,  0x07,  0xBE,  0x94,  0x81,  0x20,  0xFF,  0xE4,  0x80,  0x7A,  0x44, 	/* 13F20 */
+	0xA4,  0x7A,  0x44,  0xA4,  0x48,  0x45,  0x8C,  0xB1,  0x42,  0x07,  0xBE,  0x94,  0x82,  0x10,  0x23,  0xEF, 	/* 13F30 */
+	0xA2,  0x23,  0xE7,  0x22,  0x73,  0xEA,  0xA2,  0xA2,  0x22,  0x3E,  0xB4,  0x41,  0x07,  0xDF,  0x92,  0x42, 	/* 13F40 */
+	0x14,  0x7F,  0xE4,  0x10,  0x7D,  0x44,  0x14,  0x5C,  0x85,  0x5A,  0x5E,  0x68,  0x42,  0xB8,  0x42,  0x07, 	/* 13F50 */
+	0xBE,  0x94,  0x83,  0xFC,  0x05,  0x0F,  0xFE,  0x06,  0x01,  0xF8,  0x30,  0x8D,  0xF8,  0x10,  0x81,  0xF8, 	/* 13F60 */
+	0x80,  0x42,  0x07,  0xBE,  0x94,  0x82,  0x10,  0x7D,  0xE4,  0x52,  0x7D,  0x24,  0x52,  0x7D,  0x25,  0x1C, 	/* 13F70 */
+	0x79,  0x0C,  0x50,  0x81,  0x42,  0x07,  0xBE,  0x94,  0x83,  0xF8,  0x20,  0x83,  0xF8,  0x20,  0x87,  0xFC, 	/* 13F80 */
+	0x04,  0x03,  0xF8,  0x04,  0x0F,  0xFE,  0x84,  0x42,  0x07,  0xBE,  0x94,  0x82,  0x10,  0xFF,  0xC5,  0x64, 	/* 13F90 */
+	0x7E,  0x45,  0x64,  0x7E,  0x81,  0x22,  0xFE,  0x21,  0x1E,  0x86,  0x42,  0x07,  0xBE,  0x94,  0x82,  0x90, 	/* 13FA0 */
+	0x0F,  0x81,  0x10,  0xFF,  0xE0,  0xC8,  0x73,  0x00,  0xE8,  0xF2,  0x60,  0xC0,  0x87,  0x42,  0x07,  0xBE, 	/* 13FB0 */
+	0x94,  0x82,  0x10,  0xFF,  0xE4,  0x08,  0x7F,  0xC5,  0x54,  0x55,  0x45,  0xFC,  0x95,  0x49,  0x5C,  0x89, 	/* 13FC0 */
+	0x42,  0x07,  0xBE,  0x94,  0x8F,  0xBC,  0x22,  0x4F,  0x56,  0x04,  0x0F,  0xFE,  0x0E,  0x03,  0x58,  0xC4, 	/* 13FD0 */
+	0x60,  0x40,  0x8B,  0x42,  0x07,  0xBE,  0x94,  0x87,  0xFE,  0x42,  0x07,  0xFE,  0x52,  0x85,  0xB8,  0x66, 	/* 13FE0 */
+	0x44,  0x90,  0x50,  0x87,  0xFE,  0x8C,  0x42,  0x07,  0xBE,  0x94,  0x41,  0x78,  0x20,  0x83,  0xFE,  0x62, 	/* 13FF0 */
+	0x0A,  0x7C,  0x29,  0x02,  0xFE,  0x22,  0x82,  0xC6,  0x8F,  0x42,  0x07,  0xBE,  0x94,  0x82,  0x10,  0x49, 	/* 14000 */
+	0x0F,  0xFE,  0x4B,  0x24,  0xD4,  0x79,  0x04,  0x98,  0x4A,  0x47,  0xC2,  0x9D,  0x42,  0x07,  0xBE,  0x94, 	/* 14010 */
+	0x81,  0x10,  0x7F,  0xC1,  0x10,  0x7F,  0xE2,  0x48,  0x3F,  0x82,  0x48,  0xFF,  0xE2,  0x08,  0xA0,  0x42, 	/* 14020 */
+	0x07,  0xBE,  0x94,  0x82,  0x40,  0x47,  0xE5,  0xA4,  0xD3,  0x85,  0xD6,  0x57,  0xC5,  0x38,  0x4D,  0x44, 	/* 14030 */
+	0x12,  0xA4,  0x42,  0x07,  0xBE,  0x94,  0x82,  0x10,  0x3F,  0xC2,  0x20,  0x3F,  0xC2,  0x20,  0x3F,  0xE5, 	/* 14040 */
+	0x52,  0x54,  0x28,  0x0C,  0xA5,  0x42,  0x07,  0xBE,  0x94,  0x8F,  0xFE,  0x0A,  0x07,  0xFC,  0x4A,  0x47, 	/* 14050 */
+	0xFC,  0x04,  0x0F,  0xFE,  0x35,  0x8C,  0x46,  0xA6,  0x42,  0x07,  0xBE,  0x94,  0x83,  0xFC,  0x29,  0x42, 	/* 14060 */
+	0x64,  0x29,  0x43,  0xFC,  0x22,  0x63,  0xF8,  0x22,  0x2F,  0x9E,  0xA9,  0x42,  0x07,  0xBE,  0x94,  0x82, 	/* 14070 */
+	0x00,  0x7F,  0xE4,  0x88,  0x7B,  0xE4,  0x2A,  0x7A,  0xA4,  0xAA,  0x7A,  0xE4,  0x08,  0xAD,  0x41,  0x07, 	/* 14080 */
+	0xDF,  0x92,  0x42,  0x48,  0x7F,  0xC1,  0x10,  0xFF,  0xE2,  0x48,  0x3F,  0x83,  0xF8,  0x24,  0x20,  0x3E, 	/* 14090 */
+	0xB3,  0x42,  0x07,  0xBE,  0x94,  0x87,  0xFC,  0x44,  0x47,  0xFC,  0xFF,  0xE2,  0x48,  0xFF,  0xE0,  0x40, 	/* 140A0 */
+	0x7F,  0xC0,  0x40,  0xB6,  0x41,  0x07,  0xBE,  0x94,  0x87,  0xFC,  0x04,  0x02,  0x78,  0x24,  0x0F,  0xFE, 	/* 140B0 */
+	0x10,  0x01,  0xFE,  0x2A,  0xA4,  0x0C,  0xB7,  0x42,  0x07,  0xBE,  0x94,  0x84,  0x38,  0x2C,  0x88,  0x38, 	/* 140C0 */
+	0x4D,  0x4F,  0x7A,  0x21,  0x02,  0xFC,  0x59,  0x08,  0x7F,  0x80,  0x42,  0x07,  0xBE,  0x94,  0x87,  0xFC, 	/* 140D0 */
+	0x04,  0x0F,  0xFE,  0x20,  0x83,  0xF8,  0x20,  0x83,  0xF8,  0x10,  0x86,  0x04,  0x87,  0x42,  0x07,  0xBE, 	/* 140E0 */
+	0x94,  0x82,  0x20,  0xFF,  0xE2,  0x50,  0x3B,  0xE2,  0xC8,  0x2B,  0xE4,  0x98,  0x8A,  0x43,  0x42,  0x8D, 	/* 140F0 */
+	0x42,  0x07,  0xBE,  0x94,  0x82,  0x50,  0xFF,  0xE2,  0x48,  0x7F,  0xC4,  0x44,  0xFF,  0xE3,  0x10,  0x0E, 	/* 14100 */
+	0x07,  0x18,  0x91,  0x42,  0x07,  0xBE,  0x94,  0x82,  0x50,  0xFF,  0xE2,  0x08,  0xFF,  0xE2,  0x08,  0x3F, 	/* 14110 */
+	0x83,  0x24,  0xD5,  0x83,  0x86,  0x92,  0x42,  0x07,  0xBE,  0x94,  0x83,  0xF8,  0x20,  0x83,  0xF8,  0x20, 	/* 14120 */
+	0x8F,  0xFE,  0x24,  0x8C,  0x66,  0x09,  0x03,  0xE8,  0x93,  0x42,  0x07,  0xBE,  0x94,  0x87,  0xC8,  0x55, 	/* 14130 */
+	0x47,  0xE4,  0x54,  0x87,  0xD2,  0x6C,  0x27,  0xC4,  0x44,  0x88,  0xD0,  0x94,  0x42,  0x07,  0xBE,  0x94, 	/* 14140 */
+	0x82,  0x50,  0xFF,  0xE1,  0x10,  0x7F,  0xC1,  0x10,  0xFF,  0xE3,  0x24,  0xD5,  0x83,  0x86,  0x97,  0x42, 	/* 14150 */
+	0x07,  0xBE,  0x94,  0x82,  0xF8,  0x92,  0x84,  0xAC,  0x54,  0xA8,  0xB0,  0xFF,  0xE3,  0x58,  0xC4,  0x60, 	/* 14160 */
+	0x40,  0x9F,  0x42,  0x07,  0xBE,  0x94,  0x82,  0x10,  0x7F,  0xC4,  0xA4,  0x7F,  0xC2,  0x08,  0x3F,  0x82, 	/* 14170 */
+	0x08,  0xFF,  0xE0,  0x40,  0xA1,  0x41,  0x07,  0xDF,  0x92,  0x47,  0xBE,  0x4A,  0x27,  0xBE,  0x4E,  0x27, 	/* 14180 */
+	0x9E,  0x4F,  0x24,  0x92,  0x4F,  0x24,  0x06,  0xA3,  0x42,  0x07,  0xBE,  0x94,  0x83,  0xF8,  0x24,  0x8F, 	/* 14190 */
+	0xFE,  0x20,  0x83,  0xF8,  0x20,  0x83,  0xF8,  0x11,  0x8E,  0x04,  0xA7,  0x42,  0x07,  0xBE,  0xA4,  0x81, 	/* 141A0 */
+	0x10,  0x7F,  0xC1,  0x10,  0xFF,  0xE2,  0x48,  0x3F,  0x82,  0x48,  0x3F,  0x86,  0x0C,  0xAA,  0x42,  0x07, 	/* 141B0 */
+	0xBE,  0x94,  0x87,  0xBC,  0x52,  0x8F,  0xFC,  0x52,  0x8B,  0xFE,  0x20,  0x83,  0xF8,  0x20,  0x83,  0xF8, 	/* 141C0 */
+	0xAB,  0x42,  0x07,  0xBE,  0x94,  0x83,  0xF8,  0x04,  0x8F,  0xFE,  0x55,  0x45,  0x54,  0x7F,  0xC4,  0x44, 	/* 141D0 */
+	0x75,  0xC9,  0x54,  0xB7,  0x42,  0x07,  0xBE,  0x94,  0x80,  0xF8,  0x71,  0x03,  0xFE,  0x25,  0x03,  0x9E, 	/* 141E0 */
+	0x20,  0x04,  0xFC,  0x48,  0x48,  0xFC,  0xB8,  0x42,  0x07,  0xBE,  0xA4,  0x81,  0x10,  0x4B,  0xEF,  0xEA, 	/* 141F0 */
+	0x4A,  0xC7,  0xBE,  0x4B,  0x2F,  0xEC,  0x52,  0xC8,  0xD2,  0xBD,  0x42,  0x07,  0xBE,  0x94,  0x82,  0x50, 	/* 14200 */
+	0x0A,  0x03,  0x18,  0xFB,  0xE4,  0xA4,  0x7B,  0xC1,  0x10,  0x2A,  0x8C,  0x46,  0xBE,  0x42,  0x07,  0xBE, 	/* 14210 */
+	0x94,  0x87,  0xFE,  0x49,  0x07,  0xFE,  0x49,  0x47,  0xFE,  0x59,  0x8A,  0x94,  0xC9,  0x20,  0x90,  0xBF, 	/* 14220 */
+	0x42,  0x07,  0xBE,  0x96,  0x85,  0xFE,  0x2A,  0x80,  0xF8,  0x8A,  0x87,  0xFE,  0x08,  0x82,  0x48,  0x40, 	/* 14230 */
+	0x88,  0x18,  0x80,  0x42,  0x07,  0xBE,  0x94,  0x82,  0x5E,  0x28,  0xAF,  0xAA,  0x2F,  0x22,  0xFC,  0x3A, 	/* 14240 */
+	0x4E,  0xFC,  0x2A,  0x46,  0xFC,  0x83,  0x42,  0x07,  0xBE,  0x94,  0x87,  0xD0,  0x51,  0xE7,  0xE0,  0x44, 	/* 14250 */
+	0x07,  0xDC,  0x50,  0x07,  0xFC,  0x4A,  0x4F,  0xFE,  0x8C,  0x42,  0x07,  0xBE,  0x94,  0x87,  0xFC,  0x04, 	/* 14260 */
+	0x0F,  0xFE,  0x7F,  0xA0,  0x40,  0xFF,  0xE4,  0xC8,  0x7A,  0x80,  0x18,  0x8D,  0x42,  0x07,  0xBE,  0x94, 	/* 14270 */
+	0x82,  0x28,  0xFF,  0xC2,  0x28,  0xFF,  0xE2,  0x44,  0x77,  0xCA,  0xFC,  0x24,  0x42,  0x7C,  0x8F,  0x42, 	/* 14280 */
+	0x07,  0xBE,  0x94,  0x82,  0x20,  0xFF,  0xE2,  0x24,  0x3B,  0xC2,  0xBC,  0x2A,  0x44,  0xFE,  0x49,  0x4B, 	/* 14290 */
+	0x62,  0x90,  0x42,  0x07,  0xBE,  0x94,  0x82,  0x10,  0x75,  0x45,  0xBE,  0x71,  0x05,  0xFE,  0x75,  0x45, 	/* 142A0 */
+	0xBA,  0x55,  0x4B,  0x92,  0x94,  0x42,  0x07,  0xBE,  0x94,  0x82,  0x10,  0xF9,  0xEA,  0xA4,  0xFA,  0x4A, 	/* 142B0 */
+	0xD4,  0xF9,  0x84,  0x88,  0x31,  0x4C,  0xA2,  0x96,  0x42,  0x07,  0xBE,  0x94,  0x87,  0xD0,  0x11,  0x4F, 	/* 142C0 */
+	0xFE,  0x29,  0x0E,  0xF4,  0x29,  0x4E,  0xEA,  0x2D,  0x6F,  0x22,  0x98,  0x42,  0x07,  0xBE,  0x94,  0x82, 	/* 142D0 */
+	0x10,  0x75,  0x45,  0xFA,  0x72,  0x85,  0xFE,  0x75,  0x45,  0xFA,  0x56,  0x8B,  0xA4,  0x9F,  0x41,  0x07, 	/* 142E0 */
+	0xDE,  0x92,  0x42,  0x08,  0xFB,  0xE2,  0x12,  0xFE,  0xCA,  0xBE,  0xFA,  0x27,  0x3E,  0xA9,  0x22,  0x21, 	/* 142F0 */
+	0xA0,  0x42,  0x07,  0xBE,  0x94,  0x82,  0x3E,  0xFE,  0x04,  0xBC,  0xFC,  0x44,  0xBC,  0x7A,  0x04,  0xBC, 	/* 14300 */
+	0x7A,  0x24,  0x9E,  0xA4,  0x42,  0x07,  0xBE,  0x94,  0x82,  0x90,  0x55,  0x4F,  0xFE,  0x29,  0x0E,  0xF4, 	/* 14310 */
+	0x29,  0x4E,  0xEA,  0x2D,  0x6F,  0x22,  0xA5,  0x42,  0x07,  0xBE,  0xA4,  0x80,  0xA0,  0x3F,  0x8C,  0x06, 	/* 14320 */
+	0xEE,  0xEA,  0xAA,  0x7F,  0xC4,  0xA4,  0x7F,  0xC4,  0xA4,  0xAC,  0x42,  0x07,  0xBE,  0x94,  0x82,  0x14, 	/* 14330 */
+	0xFA,  0x85,  0xFE,  0x6A,  0x87,  0xBC,  0xFA,  0x8A,  0xBC,  0xFA,  0x88,  0xBE,  0xB3,  0x04,  0x04,  0x48, 	/* 14340 */
+	0x24,  0x82,  0x50,  0xFF,  0xE0,  0xE0,  0x0E,  0x01,  0x50,  0x24,  0x8C,  0x46,  0x04,  0x00,  0x40,  0xB5, 	/* 14350 */
+	0x21,  0x0A,  0x90,  0x71,  0x02,  0x10,  0xFF,  0xE2,  0x10,  0x71,  0x07,  0x10,  0xA9,  0x0A,  0x10,  0x21, 	/* 14360 */
+	0x02,  0x10,  0xBE,  0x20,  0x0A,  0xFE,  0x71,  0x22,  0x12,  0xF9,  0x22,  0x72,  0x71,  0xA6,  0x96,  0xA2, 	/* 14370 */
+	0x2A,  0x22,  0x24,  0x22,  0x8C,  0x81,  0x20,  0xCA,  0xF0,  0x71,  0x02,  0x10,  0xF1,  0x02,  0xFE,  0x71, 	/* 14380 */
+	0x06,  0x90,  0xA1,  0x0A,  0x10,  0x21,  0x02,  0x10,  0x82,  0x08,  0x00,  0xF0,  0x31,  0x0C,  0x60,  0x19, 	/* 14390 */
+	0x8E,  0x46,  0x24,  0x81,  0x50,  0xFF,  0xE0,  0xE0,  0x35,  0x8C,  0x46,  0x83,  0x24,  0x8A,  0xC8,  0x74, 	/* 143A0 */
+	0x82,  0x48,  0xFF,  0xA2,  0x4C,  0x74,  0x86,  0xC8,  0xA4,  0x8A,  0x4A,  0x27,  0xA2,  0xC6,  0x89,  0x22, 	/* 143B0 */
+	0x8A,  0xA8,  0x72,  0x86,  0x44,  0xF8,  0x22,  0x7D,  0x71,  0x47,  0x14,  0xAA,  0x4A,  0x24,  0x24,  0x42, 	/* 143C0 */
+	0x98,  0x8B,  0x22,  0x0A,  0xA0,  0x77,  0x82,  0x28,  0xFA,  0xA2,  0x46,  0x71,  0x07,  0x7E,  0xA9,  0x0A, 	/* 143D0 */
+	0x10,  0x21,  0x02,  0x10,  0x8D,  0x20,  0x4A,  0x98,  0x6F,  0x07,  0x10,  0xFF,  0xE2,  0x10,  0x71,  0x06, 	/* 143E0 */
+	0xFE,  0xA9,  0x0A,  0x12,  0x21,  0x22,  0x0E,  0x90,  0x20,  0x0A,  0xBE,  0x70,  0x02,  0x3E,  0xFA,  0x22, 	/* 143F0 */
+	0x22,  0x73,  0xE6,  0xA0,  0xA4,  0x0A,  0x40,  0x28,  0x03,  0x00,  0x92,  0x21,  0x0A,  0x90,  0x71,  0x02, 	/* 14400 */
+	0x7E,  0xF8,  0x42,  0x44,  0x72,  0x46,  0xA4,  0xA2,  0x8A,  0x28,  0x21,  0x02,  0xFE,  0x95,  0x20,  0x8A, 	/* 14410 */
+	0x90,  0x71,  0x02,  0x3E,  0xFA,  0x22,  0x22,  0x73,  0xE7,  0x22,  0xAA,  0x2A,  0x22,  0x22,  0x22,  0x3E, 	/* 14420 */
+	0x97,  0x20,  0x02,  0xFC,  0xB4,  0x46,  0x44,  0xFF,  0xC2,  0x44,  0x74,  0x47,  0x7C,  0xAC,  0x4A,  0x44, 	/* 14430 */
+	0x24,  0x42,  0xFE,  0x98,  0x21,  0x0A,  0x90,  0x71,  0x02,  0x1E,  0xF9,  0x02,  0x10,  0x71,  0x06,  0xFC, 	/* 14440 */
+	0xA4,  0x4A,  0x44,  0x24,  0x42,  0x7C,  0x9B,  0x04,  0x07,  0xF8,  0x04,  0x8F,  0xFE,  0x04,  0x87,  0xFC, 	/* 14450 */
+	0x64,  0xC5,  0x54,  0x7F,  0xC4,  0xE4,  0x55,  0x4A,  0x4C,  0x9F,  0xFF,  0xE0,  0xA0,  0x7F,  0xC4,  0xA4, 	/* 14460 */
+	0x7F,  0xC6,  0x4C,  0x15,  0x0F,  0xFE,  0x0E,  0x03,  0x58,  0xC4,  0x60,  0x40,  0xA1,  0x20,  0x0A,  0xFE, 	/* 14470 */
+	0x74,  0x22,  0x7A,  0xFC,  0x22,  0x42,  0x77,  0xA6,  0xEA,  0xA6,  0xAA,  0x7A,  0x24,  0x22,  0x46,  0xA2, 	/* 14480 */
+	0x02,  0x0E,  0x7E,  0x09,  0x42,  0x28,  0xCC,  0x62,  0x48,  0x15,  0x0F,  0xFE,  0x0E,  0x03,  0x58,  0xC4, 	/* 14490 */
+	0x60,  0x40,  0xA4,  0x10,  0x07,  0xFC,  0x55,  0x44,  0xE4,  0x7F,  0xC5,  0x54,  0x64,  0xCF,  0xFE,  0x08, 	/* 144A0 */
+	0x01,  0xF8,  0x00,  0x80,  0x30,  0xA5,  0x04,  0x0F,  0x5E,  0x2D,  0x22,  0x62,  0xFF,  0xE8,  0x48,  0xEE, 	/* 144B0 */
+	0xE2,  0xE2,  0x35,  0x22,  0x42,  0x24,  0x2C,  0x4C,  0xA7,  0x20,  0x8A,  0x88,  0x77,  0xE2,  0x48,  0xFC, 	/* 144C0 */
+	0x82,  0x48,  0x77,  0xE6,  0xC8,  0xA4,  0x8A,  0x88,  0x2F,  0xF3,  0x00,  0xA8,  0x20,  0x0A,  0xFE,  0x71, 	/* 144D0 */
+	0x02,  0x20,  0xFF,  0xE2,  0x42,  0x74,  0x27,  0x7E,  0xAC,  0x2A,  0x42,  0x24,  0x22,  0x7E,  0xAB,  0x20, 	/* 144E0 */
+	0x0A,  0xFE,  0x72,  0x02,  0x40,  0xFF,  0xE2,  0xAA,  0x7A,  0xA6,  0xAA,  0xAA,  0xAA,  0xAA,  0x2A,  0xA2, 	/* 144F0 */
+	0x86,  0xAD,  0x21,  0x02,  0x90,  0xB2,  0x86,  0x44,  0xFF,  0xE2,  0x01,  0x70,  0x06,  0xFC,  0xA4,  0x4A, 	/* 14500 */
+	0x44,  0x24,  0x42,  0x7C,  0xAE,  0x21,  0x0A,  0xFC,  0x74,  0x42,  0x7C,  0xFC,  0x42,  0x7C,  0x75,  0x26, 	/* 14510 */
+	0xD4,  0xA4,  0x8A,  0x48,  0x27,  0x42,  0xC2,  0xB1,  0x20,  0x09,  0xF8,  0x4A,  0xC1,  0xAA,  0x64,  0xA8, 	/* 14520 */
+	0x98,  0x24,  0x41,  0x48,  0xFF,  0xE0,  0xE0,  0x35,  0x8C,  0x46,  0xB2,  0x10,  0x01,  0xDE,  0x21,  0x27, 	/* 14530 */
+	0xCC,  0x99,  0x46,  0x22,  0x24,  0x81,  0x50,  0xFF,  0xE0,  0xE0,  0x35,  0x8C,  0x46,  0xB3,  0x20,  0x0A, 	/* 14540 */
+	0xFE,  0x71,  0x02,  0x7E,  0xFD,  0x22,  0x7E,  0x75,  0x26,  0xFE,  0xA5,  0x0A,  0x30,  0x22,  0x82,  0xC6, 	/* 14550 */
+	0xB9,  0x21,  0x0A,  0x90,  0x77,  0xE2,  0x44,  0xFC,  0x43,  0x6C,  0x69,  0x26,  0x10,  0xAF,  0xEA,  0x10, 	/* 14560 */
+	0x21,  0x02,  0x10,  0xBD,  0x21,  0x0A,  0x90,  0x7F,  0xE2,  0x82,  0xF7,  0xC3,  0x00,  0x6F,  0xE6,  0x10, 	/* 14570 */
+	0xA5,  0x4A,  0x52,  0x29,  0x22,  0x30,  0xBE,  0x21,  0x0A,  0xFE,  0x71,  0x02,  0x7C,  0xF9,  0x02,  0xFE, 	/* 14580 */
+	0x74,  0x47,  0x7C,  0xAC,  0x4A,  0x7C,  0x24,  0x42,  0x4C,  0x80,  0x22,  0x8A,  0xFE,  0x72,  0x82,  0x20, 	/* 14590 */
+	0xFA,  0x82,  0x68,  0x76,  0xA6,  0xAC,  0xA2,  0x8A,  0x28,  0x22,  0xA2,  0x26,  0x82,  0x22,  0x4A,  0xFE, 	/* 145A0 */
+	0x72,  0x42,  0x3C,  0xFA,  0x42,  0x3C,  0x72,  0x46,  0xFF,  0xA5,  0x4A,  0x66,  0x24,  0x02,  0x3E,  0x85, 	/* 145B0 */
+	0x27,  0xCA,  0xA8,  0x71,  0x02,  0x7E,  0xFB,  0x42,  0x50,  0x71,  0x06,  0xFE,  0xA3,  0x8A,  0x54,  0x29, 	/* 145C0 */
+	0x22,  0x10,  0x8A,  0x24,  0xEB,  0x4A,  0x7F,  0xA2,  0x4A,  0xF4,  0xE2,  0x4A,  0x6E,  0xA7,  0xAE,  0xAA, 	/* 145D0 */
+	0xAA,  0xEA,  0x21,  0x22,  0x26,  0x8E,  0x20,  0x02,  0xFE,  0xB8,  0x06,  0xBE,  0xFA,  0xA2,  0xBE,  0x7A, 	/* 145E0 */
+	0xA7,  0xBE,  0xA8,  0x8A,  0xBE,  0x28,  0x83,  0x7E,  0x92,  0x22,  0x4A,  0xFE,  0x72,  0x42,  0x7E,  0xFC, 	/* 145F0 */
+	0x02,  0x7E,  0x76,  0xA6,  0x7E,  0xAA,  0xAA,  0xBE,  0x32,  0xA2,  0x26,  0x96,  0x28,  0x8A,  0xFF,  0x74, 	/* 14600 */
+	0x82,  0x5E,  0xFC,  0xA2,  0x7F,  0x64,  0xA7,  0x5E,  0xAC,  0x0A,  0x5E,  0x29,  0x23,  0x1E,  0x98,  0x21, 	/* 14610 */
+	0x0A,  0xFE,  0x78,  0x22,  0xFE,  0xF9,  0x02,  0x6A,  0x71,  0xA7,  0x6C,  0xA9,  0xAA,  0x69,  0x20,  0x82, 	/* 14620 */
+	0x30,  0x9C,  0x02,  0x07,  0xFE,  0x48,  0x87,  0xFE,  0x48,  0x86,  0xAA,  0x6A,  0xA5,  0x24,  0x7F,  0xE4, 	/* 14630 */
+	0xA8,  0xB2,  0x40,  0x20,  0x9E,  0x24,  0x8F,  0xFE,  0x15,  0x02,  0x48,  0xFF,  0xE2,  0x48,  0x3F,  0x82, 	/* 14640 */
+	0x48,  0x7F,  0xC1,  0x10,  0xFF,  0xF6,  0x0C,  0x9F,  0x22,  0x8A,  0xFE,  0x72,  0x82,  0xFE,  0xFA,  0xA2, 	/* 14650 */
+	0xFE,  0x6A,  0xA7,  0xFE,  0xA4,  0x4A,  0x7C,  0x24,  0x42,  0x7C,  0xA0,  0x21,  0x0A,  0xFE,  0x75,  0x02, 	/* 14660 */
+	0x7C,  0xFD,  0x42,  0x7E,  0x75,  0x46,  0xFE,  0xA5,  0x42,  0xB8,  0x35,  0x62,  0x10,  0xA2,  0x24,  0x8A, 	/* 14670 */
+	0xFE,  0x74,  0x82,  0x7C,  0xFC,  0x42,  0x7C,  0x74,  0x46,  0xFC,  0xA1,  0x0A,  0xFE,  0x22,  0x82,  0xC6, 	/* 14680 */
+	0xA7,  0x23,  0xEA,  0xA2,  0x73,  0xE2,  0x22,  0xFF,  0xF3,  0x2A,  0x6B,  0xE6,  0xAA,  0xA2,  0xAA,  0x3E, 	/* 14690 */
+	0x20,  0x82,  0x7F,  0xAF,  0x27,  0xCA,  0x90,  0x7F,  0xE2,  0x92,  0xFB,  0xA3,  0x00,  0x6F,  0xE6,  0x20, 	/* 146A0 */
+	0xAF,  0xEA,  0xAA,  0x2A,  0xA2,  0x86,  0xB2,  0x20,  0x0B,  0x7E,  0x75,  0x42,  0x7E,  0xFD,  0x42,  0x7E, 	/* 146B0 */
+	0x76,  0xA6,  0x7E,  0xAA,  0xAA,  0xBE,  0x32,  0x22,  0x26,  0xB4,  0x6F,  0xE2,  0x66,  0x2A,  0xA5,  0x26, 	/* 146C0 */
+	0x8E,  0xA2,  0x22,  0xAC,  0x87,  0x7E,  0xFD,  0x03,  0x7C,  0x6D,  0x0A,  0x7E,  0xB6,  0x2F,  0xEA,  0xB6, 	/* 146D0 */
+	0xFD,  0xA2,  0x36,  0xAD,  0xAF,  0x92,  0xAA,  0x47,  0x7E,  0xFC,  0x83,  0x7C,  0x6C,  0x8A,  0x7E,  0xB8, 	/* 146E0 */
+	0x04,  0x00,  0x80,  0x31,  0x00,  0xA0,  0x0D,  0x01,  0x0C,  0x7F,  0x20,  0x40,  0x24,  0x82,  0x44,  0x44, 	/* 146F0 */
+	0x40,  0x40,  0xBA,  0x22,  0x02,  0x20,  0xD2,  0x05,  0x20,  0x22,  0x05,  0x20,  0xFA,  0x02,  0x20,  0xB2, 	/* 14700 */
+	0x0A,  0xA0,  0xA2,  0x22,  0x1E,  0xBB,  0x01,  0xC7,  0xE0,  0x04,  0x82,  0x90,  0x12,  0x00,  0xC8,  0xFF, 	/* 14710 */
+	0xC0,  0x42,  0x25,  0x02,  0x48,  0x44,  0x40,  0x40,  0xBE,  0x20,  0x42,  0x24,  0xD2,  0x45,  0x24,  0x22, 	/* 14720 */
+	0x45,  0x24,  0xFA,  0x4A,  0x2F,  0xAF,  0x4A,  0x84,  0xA0,  0x42,  0x04,  0x80,  0x20,  0x02,  0x7C,  0xD0, 	/* 14730 */
+	0x45,  0x04,  0x20,  0x45,  0x3C,  0xFA,  0x02,  0x20,  0xB2,  0x0A,  0xA2,  0xA2,  0x22,  0x1E,  0x82,  0x20, 	/* 14740 */
+	0x82,  0x08,  0xC0,  0x85,  0x7E,  0x20,  0x85,  0x48,  0xFA,  0x82,  0x28,  0xB0,  0x8A,  0x88,  0xA0,  0x82, 	/* 14750 */
+	0x18,  0x84,  0x22,  0x02,  0x20,  0xD3,  0xE5,  0x22,  0x24,  0x24,  0xA2,  0xF9,  0x22,  0x12,  0xB0,  0x2A, 	/* 14760 */
+	0x82,  0xA0,  0x22,  0x0C,  0x85,  0x20,  0x02,  0x7C,  0xD1,  0x05,  0x10,  0x21,  0x05,  0x10,  0xF9,  0x02, 	/* 14770 */
+	0x90,  0xB1,  0x0A,  0x90,  0xAF,  0xE2,  0x00,  0x86,  0x20,  0x02,  0x7C,  0xD1,  0x05,  0x10,  0x21,  0x05, 	/* 14780 */
+	0x7E,  0xF9,  0x02,  0x10,  0xB1,  0x0A,  0x90,  0xA1,  0x02,  0x30,  0x8A,  0x04,  0x0F,  0xFE,  0x11,  0x00, 	/* 14790 */
+	0xE0,  0x31,  0x8C,  0x56,  0x1A,  0x00,  0x4C,  0xFF,  0xA1,  0x50,  0x24,  0xC4,  0x42,  0x8B,  0x21,  0x04, 	/* 147A0 */
+	0x10,  0x9F,  0xE6,  0x44,  0x54,  0x4F,  0xA8,  0x2A,  0x8B,  0x10,  0xA9,  0x0A,  0xA8,  0xA4,  0x42,  0x82, 	/* 147B0 */
+	0x8D,  0x21,  0x04,  0x10,  0x91,  0x06,  0xFE,  0x49,  0x2F,  0x92,  0x2A,  0xAB,  0xAA,  0xAC,  0x6A,  0x82, 	/* 147C0 */
+	0xA8,  0x22,  0x86,  0x90,  0x20,  0x02,  0x7C,  0xD2,  0x45,  0x24,  0x22,  0x45,  0x7E,  0xFA,  0x42,  0x24, 	/* 147D0 */
+	0xB2,  0x4A,  0xA4,  0xA2,  0x42,  0x7E,  0x94,  0x21,  0x22,  0x1C,  0xDF,  0x05,  0x14,  0x25,  0x45,  0x54, 	/* 147E0 */
+	0xFD,  0x42,  0x7C,  0xB1,  0x0A,  0x92,  0xA1,  0x22,  0x0E,  0x95,  0x24,  0x84,  0x48,  0x94,  0x86,  0x48, 	/* 147F0 */
+	0x57,  0xAF,  0xCC,  0x2C,  0x8B,  0x48,  0xAC,  0x8A,  0x48,  0xA7,  0xA2,  0xC6,  0x97,  0x21,  0x02,  0x10, 	/* 14800 */
+	0xD1,  0x85,  0x54,  0x25,  0x25,  0x52,  0xF5,  0x02,  0x94,  0xB0,  0x4A,  0x88,  0xA1,  0x02,  0x60,  0x98, 	/* 14810 */
+	0x22,  0x02,  0x20,  0xD2,  0x05,  0xFE,  0x22,  0x05,  0x28,  0xFA,  0x82,  0x48,  0xB4,  0x8A,  0xD4,  0xAB, 	/* 14820 */
+	0xE3,  0x02,  0x99,  0x20,  0xC2,  0x70,  0xD5,  0x05,  0x50,  0x25,  0x65,  0x78,  0xFD,  0x02,  0x48,  0xB4, 	/* 14830 */
+	0x8A,  0xCA,  0xA7,  0x62,  0xC2,  0x9A,  0x20,  0x02,  0x78,  0xD4,  0x85,  0x50,  0x25,  0xC5,  0x64,  0xFD, 	/* 14840 */
+	0x42,  0x58,  0xB4,  0x8A,  0x94,  0xAA,  0x43,  0x42,  0x9B,  0x22,  0x82,  0x28,  0xD2,  0x85,  0x24,  0x24, 	/* 14850 */
+	0x25,  0x7D,  0xF9,  0x42,  0x14,  0xB1,  0x4A,  0xA4,  0xA4,  0x42,  0x98,  0x9C,  0x20,  0x02,  0x3C,  0xD0, 	/* 14860 */
+	0x05,  0x00,  0x2F,  0xE5,  0x10,  0xF9,  0x02,  0x18,  0xB2,  0x4A,  0xA4,  0xAF,  0xA2,  0x02,  0xA0,  0x04, 	/* 14870 */
+	0x07,  0xFC,  0x04,  0x03,  0xF8,  0x04,  0x0F,  0xFE,  0x19,  0x00,  0xEC,  0xF5,  0x21,  0x48,  0x64,  0x40, 	/* 14880 */
+	0x40,  0xA1,  0x22,  0x02,  0x20,  0xDF,  0xE5,  0x20,  0x22,  0x05,  0x3C,  0xFA,  0x42,  0x24,  0xB2,  0x4A, 	/* 14890 */
+	0xC4,  0xA4,  0x42,  0x98,  0xA2,  0x04,  0x0F,  0xFE,  0x04,  0x0F,  0xFE,  0x8C,  0x2B,  0x32,  0x0C,  0x87, 	/* 148A0 */
+	0xFC,  0x15,  0x42,  0x48,  0xC4,  0x40,  0x40,  0xAB,  0x12,  0x05,  0x3C,  0x5A,  0x05,  0x22,  0x5D,  0xEF, 	/* 148B0 */
+	0x60,  0x19,  0x80,  0x68,  0x7F,  0xC1,  0x52,  0x24,  0x84,  0x44,  0xAC,  0x21,  0x02,  0x10,  0xD1,  0x05, 	/* 148C0 */
+	0x7E,  0x25,  0x25,  0x52,  0xFF,  0xE2,  0x52,  0xB5,  0x2A,  0xD2,  0xA5,  0x22,  0x7E,  0xAE,  0x22,  0x0F, 	/* 148D0 */
+	0xE0,  0x32,  0x06,  0xA2,  0xA2,  0x22,  0x5E,  0x09,  0x03,  0xA0,  0x04,  0xCF,  0xF2,  0x25,  0x84,  0x44, 	/* 148E0 */
+	0xAF,  0x7F,  0xC4,  0x44,  0x7F,  0xC4,  0x44,  0x7F,  0xC0,  0x90,  0x73,  0x00,  0xCC,  0xFF,  0x23,  0x58, 	/* 148F0 */
+	0xC4,  0x60,  0x40,  0xB0,  0x10,  0x01,  0x3E,  0xE2,  0xA2,  0xAA,  0x12,  0xA2,  0xBE,  0xFE,  0xA1,  0x2A, 	/* 14900 */
+	0x5A,  0xA5,  0x6A,  0x93,  0xE1,  0x00,  0xB2,  0x25,  0x42,  0x54,  0xD5,  0x45,  0xFE,  0x25,  0x45,  0x54, 	/* 14910 */
+	0xFD,  0x42,  0x54,  0xB5,  0xCA,  0xC0,  0xA4,  0x02,  0x7E,  0xB3,  0x21,  0x02,  0x10,  0xD7,  0xE5,  0x52, 	/* 14920 */
+	0x27,  0xE5,  0x52,  0xFD,  0x22,  0x7E,  0xB1,  0x0A,  0x90,  0xA1,  0x02,  0x10,  0xB5,  0x21,  0x02,  0x7E, 	/* 14930 */
+	0xD4,  0x25,  0x00,  0x2F,  0xE5,  0x08,  0xF8,  0x82,  0x08,  0xB0,  0x8A,  0x88,  0xA8,  0x82,  0x18,  0xB9, 	/* 14940 */
+	0x20,  0x02,  0x7E,  0xD1,  0x25,  0x12,  0x22,  0x25,  0x4C,  0xF8,  0x02,  0x3E,  0xB2,  0x2A,  0xA2,  0xA2, 	/* 14950 */
+	0x22,  0x3E,  0xBA,  0x22,  0x44,  0x24,  0x92,  0x46,  0x7E,  0x4A,  0x4F,  0xA4,  0x2A,  0x43,  0x3C,  0xAA, 	/* 14960 */
+	0x4A,  0xA4,  0xA2,  0x42,  0x3C,  0xBF,  0x22,  0x02,  0x20,  0xD2,  0x85,  0x24,  0x25,  0xC5,  0x62,  0xF8, 	/* 14970 */
+	0x22,  0x7C,  0xB4,  0x4A,  0xC4,  0xA4,  0x42,  0x7C,  0x82,  0x21,  0x02,  0x1C,  0xD2,  0x45,  0x68,  0x21, 	/* 14980 */
+	0x85,  0x24,  0xFC,  0x22,  0x98,  0xB0,  0x4A,  0xB0,  0xA0,  0xC2,  0x02,  0x83,  0x21,  0x02,  0x10,  0xD7, 	/* 14990 */
+	0xE5,  0x10,  0x21,  0x45,  0x64,  0xFA,  0x82,  0x10,  0xB1,  0x8A,  0xA4,  0xAF,  0xE2,  0x02,  0x84,  0x20, 	/* 149A0 */
+	0x02,  0x7C,  0xD4,  0x45,  0x44,  0x27,  0xC5,  0x44,  0xFC,  0x42,  0xFC,  0xB4,  0x4A,  0xC4,  0xA4,  0x43, 	/* 149B0 */
+	0xFE,  0x85,  0x20,  0x02,  0x7E,  0xD4,  0x25,  0x42,  0x25,  0xE5,  0x56,  0xFD,  0x62,  0x56,  0xB5,  0xEA, 	/* 149C0 */
+	0xC2,  0xA4,  0x22,  0x46,  0x86,  0x21,  0x02,  0x54,  0xD5,  0x45,  0x92,  0x27,  0xC5,  0x10,  0xF9,  0x02, 	/* 149D0 */
+	0xFE,  0xB1,  0x0A,  0x90,  0xA1,  0x02,  0x10,  0x8B,  0x20,  0x82,  0x08,  0xD7,  0xE5,  0x40,  0x24,  0x85, 	/* 149E0 */
+	0x48,  0xFC,  0x82,  0x48,  0xB5,  0x4B,  0x56,  0xAB,  0xA3,  0x02,  0x8C,  0x20,  0x02,  0x7C,  0xD2,  0x45, 	/* 149F0 */
+	0x18,  0x22,  0x85,  0x46,  0xF9,  0x02,  0x10,  0xB7,  0xCA,  0x90,  0xA1,  0x02,  0xFE,  0x8E,  0x21,  0x02, 	/* 14A00 */
+	0x1E,  0xD2,  0x05,  0x50,  0x29,  0xF5,  0x24,  0xF6,  0x42,  0xA4,  0xB2,  0x4A,  0xA4,  0xA2,  0x42,  0x2C, 	/* 14A10 */
+	0x8F,  0x21,  0x04,  0x10,  0x97,  0xE6,  0x52,  0x57,  0xEF,  0xD2,  0x2F,  0xEB,  0x14,  0xA8,  0x8A,  0x9A, 	/* 14A20 */
+	0xA6,  0x63,  0x82,  0x90,  0x21,  0x02,  0x10,  0xDF,  0xE5,  0x10,  0x21,  0x05,  0x7C,  0xF8,  0x02,  0x7C, 	/* 14A30 */
+	0xB4,  0x4A,  0xC4,  0xA4,  0x42,  0x7C,  0x96,  0x21,  0x02,  0x92,  0xD5,  0x25,  0x54,  0x21,  0x05,  0x7E, 	/* 14A40 */
+	0xFA,  0x82,  0x28,  0xB2,  0x8A,  0xC8,  0xA4,  0xA2,  0x86,  0x9B,  0x22,  0x02,  0x3E,  0x26,  0x45,  0x98, 	/* 14A50 */
+	0x53,  0x4D,  0xD2,  0x56,  0x85,  0x34,  0x5F,  0xA5,  0x54,  0x49,  0x24,  0x10,  0x9E,  0x21,  0x02,  0x10, 	/* 14A60 */
+	0xDF,  0xE5,  0x28,  0x24,  0x45,  0x0A,  0xFA,  0x82,  0x28,  0xA9,  0x0A,  0xA8,  0xA4,  0x42,  0x82,  0xA1, 	/* 14A70 */
+	0x21,  0x02,  0x1C,  0xD2,  0x45,  0x64,  0x21,  0x85,  0x14,  0xFA,  0x22,  0x7D,  0xAA,  0x4A,  0xA4,  0xA2, 	/* 14A80 */
+	0x42,  0x3C,  0xA2,  0x21,  0x04,  0x10,  0x93,  0xE6,  0x42,  0x53,  0xAF,  0xAA,  0x2B,  0xAB,  0x2A,  0xAA, 	/* 14A90 */
+	0xAA,  0xBA,  0xA0,  0x22,  0x0C,  0xA3,  0x22,  0x22,  0x14,  0xD7,  0xE5,  0x14,  0x21,  0x45,  0x7E,  0xF9, 	/* 14AA0 */
+	0x42,  0x14,  0xB2,  0x4A,  0xA4,  0xA4,  0x42,  0x84,  0xA6,  0x21,  0x02,  0x10,  0xD2,  0x85,  0x44,  0x2F, 	/* 14AB0 */
+	0xC5,  0x02,  0xF8,  0x02,  0x7C,  0xB4,  0x4A,  0xC4,  0xA4,  0x42,  0x7C,  0xA8,  0x21,  0x44,  0x12,  0x97, 	/* 14AC0 */
+	0xE6,  0x28,  0x4A,  0x8F,  0xF8,  0x2A,  0xAB,  0x2A,  0xAA,  0x4A,  0x4C,  0xA1,  0x62,  0x62,  0xAE,  0x10, 	/* 14AD0 */
+	0x0F,  0xDE,  0x29,  0x24,  0x92,  0x31,  0x22,  0x9E,  0xC4,  0x81,  0xB0,  0x04,  0xCF,  0xFA,  0x25,  0x04, 	/* 14AE0 */
+	0x4C,  0xB1,  0x21,  0x02,  0x10,  0xD7,  0xE5,  0x10,  0x22,  0x45,  0x7C,  0xFA,  0xA2,  0x28,  0xB2,  0x8A, 	/* 14AF0 */
+	0xAA,  0xA4,  0xA2,  0x86,  0xB2,  0x20,  0x82,  0x08,  0xCB,  0x25,  0x14,  0x20,  0x85,  0x14,  0xFF,  0xE2, 	/* 14B00 */
+	0x08,  0xB2,  0xCA,  0xAA,  0xA4,  0xA2,  0x08,  0xB3,  0x21,  0x02,  0x3C,  0xD6,  0x45,  0x18,  0x22,  0x45, 	/* 14B10 */
+	0x52,  0xF9,  0x02,  0x7C,  0xB5,  0x0A,  0xFE,  0xA1,  0x02,  0x10,  0xB5,  0x21,  0x02,  0x10,  0xD2,  0x85, 	/* 14B20 */
+	0x44,  0x2B,  0xA5,  0x00,  0xFF,  0xE2,  0x20,  0xB2,  0x8A,  0x48,  0xAF,  0x42,  0x04,  0xB6,  0x22,  0x02, 	/* 14B30 */
+	0x38,  0xD4,  0x85,  0x10,  0x27,  0xC5,  0x54,  0xFD,  0x42,  0x7C,  0xB4,  0x0A,  0xC2,  0xA4,  0x22,  0x3E, 	/* 14B40 */
+	0xB9,  0x23,  0xE4,  0x22,  0x93,  0xE6,  0x00,  0x4B,  0xEF,  0xA2,  0x2B,  0xEB,  0x22,  0xAB,  0xEA,  0xA2, 	/* 14B50 */
+	0xA2,  0x22,  0x26,  0xBD,  0x20,  0x02,  0x3C,  0xD2,  0x45,  0x24,  0x23,  0xC5,  0x10,  0xFA,  0x02,  0x3E, 	/* 14B60 */
+	0xB2,  0x2A,  0xA2,  0xAA,  0x22,  0x3E,  0x89,  0x20,  0x44,  0x78,  0x91,  0x06,  0x7E,  0x4B,  0x8F,  0xD4, 	/* 14B70 */
+	0x29,  0x2B,  0x7C,  0xA9,  0x4A,  0x96,  0xA2,  0x22,  0x4C,  0x8F,  0x20,  0x62,  0x78,  0xD2,  0x45,  0x2A, 	/* 14B80 */
+	0x24,  0xA5,  0x10,  0xFF,  0xEA,  0x14,  0xB2,  0x4A,  0xB8,  0xA1,  0x42,  0x62,  0x93,  0x20,  0x02,  0x7E, 	/* 14B90 */
+	0xD2,  0xA5,  0x2A,  0x25,  0x45,  0x2A,  0xFA,  0xA2,  0x00,  0xB3,  0xEA,  0x88,  0xA0,  0x82,  0x7F,  0x99, 	/* 14BA0 */
+	0x24,  0x82,  0x48,  0xD6,  0xA5,  0x5C,  0x27,  0xE5,  0x48,  0xFD,  0xC2,  0x5C,  0xB6,  0xAA,  0xC8,  0xA4, 	/* 14BB0 */
+	0x82,  0x7E,  0x9A,  0x21,  0x02,  0xFE,  0xD1,  0x05,  0x7C,  0x20,  0x05,  0x7E,  0xFC,  0x22,  0x28,  0xB2, 	/* 14BC0 */
+	0x8A,  0xA8,  0xA2,  0xA2,  0x46,  0x9B,  0x20,  0x02,  0x7E,  0xD0,  0xA5,  0x2A,  0x21,  0xA5,  0x22,  0xF4, 	/* 14BD0 */
+	0xC2,  0x10,  0xAA,  0x8A,  0xA2,  0xB2,  0x52,  0x1C,  0x9C,  0x21,  0x02,  0x10,  0xDF,  0xE5,  0x82,  0x2B, 	/* 14BE0 */
+	0xA5,  0x00,  0xFF,  0xE2,  0x10,  0xB5,  0x4B,  0x52,  0xA9,  0x22,  0x30,  0x9F,  0x20,  0x02,  0x7E,  0xD0, 	/* 14BF0 */
+	0x05,  0x7E,  0x24,  0x25,  0x7E,  0xFC,  0x82,  0x7E,  0xB4,  0x8A,  0x54,  0xA9,  0x43,  0x22,  0xA2,  0x20, 	/* 14C00 */
+	0x02,  0x7E,  0xD4,  0x25,  0x52,  0x27,  0xE5,  0x52,  0xFF,  0xE2,  0x52,  0xB7,  0xAA,  0x6A,  0xAB,  0xA3, 	/* 14C10 */
+	0x06,  0xA3,  0x21,  0x04,  0x34,  0x95,  0x26,  0x7E,  0x4A,  0x8F,  0xFE,  0x2C,  0x4A,  0xBA,  0xB2,  0x8A, 	/* 14C20 */
+	0xB8,  0xA2,  0x42,  0x1C,  0xAB,  0x21,  0x42,  0x1E,  0xDF,  0x05,  0x14,  0x21,  0xA5,  0x26,  0xF9,  0x42, 	/* 14C30 */
+	0x1E,  0xB7,  0x0A,  0x94,  0xA1,  0xA2,  0xE6,  0xAC,  0x20,  0xC2,  0x72,  0xD4,  0xA5,  0x24,  0x27,  0xE5, 	/* 14C40 */
+	0x42,  0xFF,  0xC2,  0x24,  0xAA,  0x8A,  0x98,  0xA2,  0x42,  0xC2,  0xAD,  0x22,  0x42,  0x28,  0xD7,  0xE5, 	/* 14C50 */
+	0xC8,  0x24,  0x85,  0x7C,  0xFC,  0x82,  0x48,  0xB7,  0xCA,  0xC8,  0xA4,  0x82,  0x7E,  0xAE,  0xF9,  0x00, 	/* 14C60 */
+	0x1E,  0x7A,  0x44,  0xD8,  0x79,  0x44,  0x22,  0x8C,  0x8B,  0x30,  0x0C,  0xCF,  0xFA,  0x14,  0x86,  0x44, 	/* 14C70 */
+	0xAF,  0x22,  0x02,  0x20,  0xD3,  0xE5,  0x42,  0x2B,  0xE5,  0x52,  0xFF,  0xE2,  0x12,  0xB5,  0x6A,  0x7E, 	/* 14C80 */
+	0xA0,  0x22,  0x0C,  0xB0,  0x20,  0x82,  0x7E,  0xD4,  0x25,  0x3C,  0x22,  0x45,  0x24,  0xFB,  0xC2,  0x20, 	/* 14C90 */
+	0xB3,  0xEA,  0xA2,  0xA2,  0x22,  0x3E,  0xB1,  0x20,  0x02,  0x7E,  0xD4,  0xA5,  0x6A,  0x25,  0x25,  0x7E, 	/* 14CA0 */
+	0xFD,  0x22,  0x56,  0xB5,  0x6A,  0xFE,  0xA4,  0x22,  0x46,  0xB2,  0x20,  0x02,  0x7E,  0xD4,  0x65,  0x6A, 	/* 14CB0 */
+	0x27,  0xE5,  0x52,  0xFF,  0xE2,  0x52,  0xB5,  0x2A,  0xCE,  0xA4,  0x22,  0x46,  0xB4,  0x2E,  0xE2,  0x22, 	/* 14CC0 */
+	0xDC,  0xC5,  0x44,  0x2A,  0xA5,  0x00,  0xFE,  0xE2,  0x22,  0xAA,  0xAA,  0x44,  0xAA,  0xA3,  0x12,  0xB5, 	/* 14CD0 */
+	0x20,  0x64,  0x7C,  0x95,  0x26,  0x4A,  0x48,  0x8F,  0x90,  0x2F,  0xEB,  0x10,  0xAB,  0x8A,  0xD4,  0xA9, 	/* 14CE0 */
+	0x22,  0x10,  0xB8,  0x22,  0x04,  0x30,  0x94,  0x86,  0x84,  0x5F,  0xEF,  0x01,  0x2F,  0xEA,  0xAA,  0xBF, 	/* 14CF0 */
+	0xEA,  0xAA,  0xAA,  0xA2,  0x86,  0xBA,  0x21,  0x02,  0x7C,  0xD1,  0x05,  0x28,  0x24,  0x45,  0x7E,  0xF8, 	/* 14D00 */
+	0x42,  0x74,  0xB5,  0x4A,  0xF4,  0xA8,  0x42,  0x0C,  0xBB,  0x20,  0x84,  0x7E,  0x94,  0x26,  0x42,  0x4B, 	/* 14D10 */
+	0xCF,  0x88,  0x2A,  0x8B,  0x2E,  0xAA,  0x8A,  0xA8,  0xA5,  0x82,  0x87,  0xBD,  0x21,  0x02,  0x1E,  0xD1, 	/* 14D20 */
+	0x05,  0x7C,  0x24,  0x45,  0x7C,  0xFC,  0x42,  0x7C,  0xB1,  0x0A,  0xFE,  0xA9,  0x02,  0x10,  0xBE,  0x21, 	/* 14D30 */
+	0x04,  0x7C,  0x91,  0x06,  0x7E,  0x52,  0x8F,  0xA4,  0x2D,  0xEB,  0x24,  0xAE,  0x8A,  0x90,  0xA2,  0x82, 	/* 14D40 */
+	0xC6,  0xBF,  0x21,  0x02,  0x7C,  0xD4,  0x45,  0x7C,  0x24,  0x45,  0x7C,  0xF9,  0x02,  0x7E,  0xB5,  0x2A, 	/* 14D50 */
+	0xD2,  0xA5,  0x62,  0x10,  0x87,  0x22,  0xA4,  0x2A,  0x95,  0x46,  0x2A,  0x52,  0xAF,  0x80,  0x2B,  0xEB, 	/* 14D60 */
+	0x2A,  0xAB,  0xEA,  0xAA,  0xA2,  0xA2,  0x3E,  0x8A,  0x00,  0x07,  0xDE,  0x50,  0x27,  0xD4,  0x7C,  0x85, 	/* 14D70 */
+	0x14,  0x7E,  0x23,  0x18,  0x0E,  0x4F,  0xFE,  0x15,  0x26,  0x48,  0x8B,  0x22,  0x82,  0x28,  0xD6,  0xE5, 	/* 14D80 */
+	0x28,  0x22,  0x85,  0xEE,  0xF2,  0x82,  0x28,  0xBE,  0xEA,  0x28,  0xA4,  0x82,  0x88,  0x8F,  0x22,  0x82, 	/* 14D90 */
+	0x28,  0xD5,  0x45,  0x12,  0x22,  0x85,  0x7C,  0xF8,  0x42,  0x50,  0xB4,  0xCA,  0xAA,  0xAA,  0x22,  0x18, 	/* 14DA0 */
+	0x91,  0x20,  0x02,  0x7C,  0xD0,  0x45,  0x7C,  0x20,  0x45,  0x7E,  0xF9,  0x42,  0x54,  0xB3,  0x8A,  0x54, 	/* 14DB0 */
+	0xA9,  0x22,  0x30,  0x92,  0x21,  0x02,  0x7E,  0xD1,  0x45,  0x18,  0x2F,  0xE5,  0x20,  0xF7,  0xC2,  0xA4, 	/* 14DC0 */
+	0xB3,  0xCA,  0xA4,  0xA2,  0x42,  0x3C,  0x95,  0x21,  0x04,  0xFE,  0x92,  0x46,  0x18,  0x52,  0x4F,  0xE6, 	/* 14DD0 */
+	0x2B,  0xDB,  0x24,  0xAB,  0xCA,  0xA4,  0xA4,  0x42,  0x84,  0x98,  0x20,  0xC4,  0x0A,  0x97,  0xE6,  0x48, 	/* 14DE0 */
+	0x57,  0xAF,  0x4A,  0x2F,  0xAA,  0x6C,  0xB7,  0xCA,  0xCE,  0xA9,  0x23,  0x22,  0x9A,  0x21,  0x02,  0x7C, 	/* 14DF0 */
+	0xD4,  0x45,  0x7C,  0x24,  0x45,  0x7C,  0xF9,  0x22,  0x54,  0xB3,  0x8A,  0xD4,  0xA1,  0x22,  0x30,  0x9C, 	/* 14E00 */
+	0x20,  0x6F,  0xF8,  0x8A,  0x4F,  0xE8,  0x89,  0x0F,  0xA4,  0x27,  0xEF,  0x92,  0xAB,  0x4A,  0xD2,  0xB9, 	/* 14E10 */
+	0x02,  0x10,  0x9D,  0x23,  0xC2,  0x24,  0xD3,  0xC5,  0x00,  0x27,  0xE5,  0x24,  0xFB,  0xC2,  0x24,  0xAB, 	/* 14E20 */
+	0xCA,  0xA4,  0xAF,  0xC2,  0x04,  0x9E,  0x23,  0xC4,  0xD4,  0x99,  0x46,  0x95,  0x5E,  0x3F,  0x80,  0x2F, 	/* 14E30 */
+	0xCA,  0x94,  0xBF,  0x4A,  0x88,  0xA9,  0x42,  0xA2,  0xA0,  0x21,  0x02,  0xFE,  0xD4,  0x45,  0x28,  0x2F, 	/* 14E40 */
+	0xE4,  0x92,  0xFF,  0xC2,  0x54,  0xB5,  0x4A,  0xD4,  0xA1,  0x02,  0x10,  0xA1,  0x27,  0xC4,  0x44,  0x97, 	/* 14E50 */
+	0xC6,  0x48,  0x57,  0xEF,  0xC8,  0x2E,  0x4B,  0x7E,  0xAC,  0x4A,  0x7C,  0xA4,  0x42,  0x7C,  0xA4,  0x25, 	/* 14E60 */
+	0x42,  0xFE,  0xD5,  0x45,  0x5C,  0x24,  0x05,  0x7E,  0xF9,  0x02,  0x7E,  0xB1,  0x8A,  0xB4,  0xA5,  0x22, 	/* 14E70 */
+	0x10,  0xA8,  0x2F,  0xE2,  0x00,  0xD7,  0xC5,  0x44,  0x27,  0xC5,  0x40,  0xFF,  0xE2,  0x6A,  0xB7,  0xEA, 	/* 14E80 */
+	0xAA,  0xB2,  0xA2,  0x26,  0xA9,  0x20,  0xC2,  0x74,  0xD2,  0x85,  0xFE,  0x22,  0x05,  0x7E,  0xFA,  0x02, 	/* 14E90 */
+	0x3C,  0xB5,  0x4A,  0x58,  0xAA,  0x42,  0x42,  0xAC,  0x20,  0x02,  0xFE,  0xD1,  0x05,  0x20,  0x2F,  0xE5, 	/* 14EA0 */
+	0xAA,  0xFB,  0xA2,  0xAA,  0xBB,  0xAA,  0xAA,  0xAA,  0xA2,  0xFE,  0xAF,  0x21,  0x02,  0x7E,  0xD1,  0x25, 	/* 14EB0 */
+	0x7F,  0x22,  0x25,  0x3E,  0xF8,  0x82,  0x3E,  0xAA,  0x8A,  0xFF,  0xA0,  0x82,  0x08,  0xB2,  0x20,  0x84, 	/* 14EC0 */
+	0xE8,  0x9A,  0xC6,  0xAA,  0x4F,  0xAF,  0xB9,  0x2A,  0xBA,  0xEA,  0xBB,  0xAA,  0xE4,  0xA1,  0x82,  0x60, 	/* 14ED0 */
+	0xB4,  0x21,  0x02,  0xFE,  0xD1,  0x05,  0x7C,  0x25,  0x45,  0x7C,  0xFD,  0x42,  0x7C,  0xA3,  0x8B,  0x54, 	/* 14EE0 */
+	0xA9,  0x22,  0x10,  0xBB,  0x20,  0x44,  0xFC,  0x96,  0x46,  0x57,  0x4F,  0x6F,  0xAA,  0x2A,  0xAA,  0xF4, 	/* 14EF0 */
+	0xB2,  0x4A,  0xAA,  0xAF,  0x22,  0x21,  0x81,  0x27,  0x82,  0x08,  0xD7,  0x85,  0x08,  0x27,  0xE5,  0x32, 	/* 14F00 */
+	0xFD,  0x42,  0x28,  0xB5,  0xCA,  0xAA,  0xA4,  0x82,  0x18,  0x84,  0x27,  0xC2,  0x54,  0xD7,  0xC5,  0x54, 	/* 14F10 */
+	0x27,  0xC5,  0x7E,  0xF9,  0x22,  0xFE,  0xB9,  0x2A,  0xFE,  0xA1,  0x22,  0x0E,  0x85,  0x20,  0x84,  0x0A, 	/* 14F20 */
+	0x97,  0xE6,  0x48,  0x57,  0xAF,  0xEA,  0x27,  0xAB,  0x54,  0xA5,  0x4A,  0xAD,  0xAD,  0x33,  0x21,  0x89, 	/* 14F30 */
+	0x20,  0x04,  0xFE,  0x92,  0x46,  0x4A,  0x4E,  0xEF,  0x80,  0x2F,  0xEB,  0x3C,  0xAA,  0x4A,  0xBC,  0xA2, 	/* 14F40 */
+	0x42,  0x3C,  0x8A,  0x23,  0xC4,  0x24,  0x97,  0xC6,  0x82,  0x57,  0xDF,  0xA8,  0x2C,  0x4A,  0xFE,  0xB5, 	/* 14F50 */
+	0x5A,  0xD4,  0xA5,  0x42,  0xFE,  0x8B,  0x20,  0x44,  0x48,  0x93,  0xE6,  0x92,  0x55,  0xEF,  0x10,  0x2D, 	/* 14F60 */
+	0xEB,  0x52,  0xB5,  0x2A,  0x5E,  0xAB,  0x03,  0x0F,  0x92,  0x24,  0x44,  0x28,  0x97,  0xE6,  0x10,  0x53, 	/* 14F70 */
+	0xCF,  0x90,  0x2F,  0xEB,  0x20,  0xAF,  0xEA,  0x48,  0xA8,  0x82,  0x7E,  0x9B,  0x21,  0x42,  0xFE,  0xD1, 	/* 14F80 */
+	0x05,  0x7C,  0x25,  0x45,  0x7C,  0xF5,  0x42,  0xFE,  0xB2,  0x4A,  0x94,  0xA0,  0x42,  0x0C,  0x9E,  0x21, 	/* 14F90 */
+	0x02,  0xFE,  0xD7,  0xC5,  0x44,  0x27,  0xC5,  0x00,  0xFF,  0xE2,  0x82,  0xAB,  0xAB,  0xAA,  0xAB,  0xA2, 	/* 14FA0 */
+	0x86,  0x9F,  0x20,  0x04,  0x7E,  0x94,  0x06,  0x7E,  0x55,  0xAF,  0xD4,  0x27,  0x2B,  0x44,  0xAF,  0xFA, 	/* 14FB0 */
+	0xA4,  0xB0,  0x42,  0x0C,  0xA1,  0x21,  0x04,  0xFE,  0x99,  0x26,  0x7C,  0x52,  0x8F,  0xA8,  0x2F,  0xEB, 	/* 14FC0 */
+	0x10,  0xAF,  0xCA,  0x90,  0xA1,  0x02,  0x10,  0xA2,  0x0A,  0x47,  0xFA,  0x52,  0x05,  0xFE,  0x74,  0x85, 	/* 14FD0 */
+	0xA4,  0x5D,  0x27,  0x28,  0x5F,  0xC5,  0x54,  0x59,  0x2B,  0x10,  0xA3,  0x38,  0x62,  0xB8,  0xB8,  0xAA, 	/* 14FE0 */
+	0xB2,  0xB9,  0x4A,  0x8C,  0xB9,  0x28,  0x7E,  0xFA,  0xA5,  0xAC,  0x54,  0xA9,  0x08,  0xA6,  0x24,  0x02, 	/* 14FF0 */
+	0x52,  0xD8,  0xC5,  0x7E,  0x24,  0x85,  0x68,  0xFA,  0x82,  0xAE,  0xBA,  0x8A,  0xD8,  0xAC,  0x82,  0x86, 	/* 15000 */
+	0xAB,  0x21,  0x02,  0x1E,  0xD3,  0x45,  0x48,  0x23,  0x45,  0x4A,  0xFF,  0xD2,  0x48,  0xB7,  0xEA,  0x48, 	/* 15010 */
+	0xAA,  0x83,  0x1F,  0xAE,  0x21,  0x04,  0xFE,  0x98,  0x26,  0xBE,  0x4A,  0x8F,  0x5E,  0x2D,  0x2A,  0x52, 	/* 15020 */
+	0xB5,  0xEA,  0xD2,  0xA5,  0x22,  0x5E,  0xB1,  0x25,  0x44,  0x54,  0x95,  0x46,  0xAA,  0x55,  0x1F,  0x48, 	/* 15030 */
+	0x2A,  0x8A,  0xAE,  0xBA,  0x8A,  0xB8,  0xAC,  0x82,  0x87,  0xB2,  0x27,  0xE4,  0x52,  0x97,  0xE6,  0x52, 	/* 15040 */
+	0x4F,  0xEF,  0xB0,  0x2C,  0xCB,  0x32,  0xAF,  0xEA,  0x54,  0xA9,  0x22,  0x10,  0xB5,  0x27,  0xC2,  0x44, 	/* 15050 */
+	0xD7,  0xC5,  0x44,  0x2F,  0xE5,  0xAA,  0xFF,  0xE2,  0x00,  0xB7,  0xCA,  0xA4,  0xA1,  0x82,  0xE6,  0xB7, 	/* 15060 */
+	0x27,  0xC4,  0x54,  0x9F,  0xE6,  0x54,  0x4F,  0xEF,  0x92,  0x2F,  0xEA,  0x10,  0xB7,  0xEA,  0xA4,  0xA1, 	/* 15070 */
+	0x82,  0x64,  0xB9,  0x27,  0xE4,  0x28,  0x9F,  0xE6,  0xAA,  0x4F,  0xEF,  0x80,  0x2B,  0xCB,  0x00,  0xAF, 	/* 15080 */
+	0xEA,  0x54,  0xA9,  0x22,  0x30,  0xBA,  0x28,  0x84,  0x7E,  0xA0,  0x86,  0xBE,  0x56,  0xAF,  0x3E,  0x3E, 	/* 15090 */
+	0xAA,  0x7E,  0xB4,  0x8A,  0x7E,  0xAA,  0x83,  0x1F,  0xBB,  0x02,  0x07,  0xFE,  0x49,  0x07,  0xFE,  0x4A, 	/* 150A0 */
+	0x86,  0xAA,  0x6E,  0xA5,  0x90,  0x46,  0xC7,  0xFA,  0x8A,  0x83,  0x24,  0xBD,  0x22,  0x02,  0x7E,  0xD4, 	/* 150B0 */
+	0xA5,  0x56,  0x26,  0xE5,  0x4A,  0xFD,  0x22,  0x7E,  0xB0,  0xAA,  0xA5,  0xA5,  0x22,  0x4E,  0xBE,  0x21, 	/* 150C0 */
+	0x02,  0xFE,  0xD1,  0x05,  0x7C,  0x21,  0x05,  0xFE,  0xF4,  0x42,  0x7C,  0xB4,  0x4A,  0xFC,  0xA2,  0x42, 	/* 150D0 */
+	0xC2,  0x81,  0x42,  0x07,  0xBE,  0xAA,  0x4F,  0xD4,  0xA9,  0x8F,  0xE6,  0x1D,  0x00,  0xA8,  0x7F,  0xC1, 	/* 150E0 */
+	0x54,  0x64,  0xC0,  0x40,  0x83,  0x21,  0x04,  0x92,  0x9F,  0xE6,  0x00,  0x4E,  0xEF,  0xAA,  0x2E,  0xEA, 	/* 150F0 */
+	0xAA,  0xBE,  0xEA,  0xAA,  0xAA,  0xA2,  0xB6,  0x86,  0x20,  0x04,  0xFE,  0x95,  0xA6,  0x36,  0x55,  0xAF, 	/* 15100 */
+	0xB6,  0x2A,  0x83,  0x4C,  0xA9,  0x2A,  0x65,  0xA1,  0x82,  0x60,  0x8A,  0x24,  0xA2,  0x4A,  0xDF,  0x86, 	/* 15110 */
+	0x4E,  0x24,  0x85,  0xFA,  0xFA,  0xA2,  0xAC,  0xBB,  0x4A,  0xA4,  0xBF,  0xA2,  0x12,  0x8B,  0xFB,  0x82, 	/* 15120 */
+	0x2A,  0xFC,  0xEA,  0xFC,  0xFA,  0x42,  0x18,  0xFE,  0x63,  0x28,  0x0D,  0x0F,  0xFE,  0x15,  0x06,  0x4C, 	/* 15130 */
+	0x8D,  0x21,  0x02,  0x7C,  0xD1,  0x45,  0x7E,  0x21,  0x45,  0xFE,  0xF7,  0x62,  0x5A,  0xB7,  0xEB,  0x52, 	/* 15140 */
+	0xAB,  0xA3,  0x56,  0x94,  0x24,  0x83,  0xFC,  0xDA,  0xA6,  0xA8,  0x3F,  0xF5,  0x08,  0xFE,  0xA2,  0xAA, 	/* 15150 */
+	0xBE,  0x4A,  0xAC,  0xAF,  0x22,  0x22,  0x95,  0x22,  0x84,  0xFE,  0x91,  0x06,  0x7C,  0x51,  0x0F,  0xFE, 	/* 15160 */
+	0x25,  0x4A,  0xFE,  0xB0,  0x0A,  0xFC,  0xA4,  0x42,  0x7C,  0x96,  0x2A,  0x84,  0xA8,  0x9F,  0xE6,  0xAA, 	/* 15170 */
+	0x5F,  0x2F,  0x0A,  0x2E,  0x4B,  0xA4,  0xAE,  0xAA,  0xAA,  0x2B,  0x22,  0xA1,  0x99,  0x20,  0xC4,  0x72, 	/* 15180 */
+	0x95,  0x46,  0xFE,  0x53,  0x8F,  0xD4,  0x29,  0x2A,  0x7D,  0xB5,  0x4A,  0xFC,  0xA5,  0x42,  0x7C,  0x9A, 	/* 15190 */
+	0x21,  0x04,  0xFE,  0x91,  0x06,  0xBA,  0x56,  0x4F,  0xBE,  0x2A,  0x5B,  0x3C,  0xA9,  0x4A,  0xB2,  0xA5, 	/* 151A0 */
+	0x22,  0x30,  0x9D,  0x2E,  0xE4,  0xAA,  0x9E,  0xE6,  0xAA,  0x4F,  0xEF,  0xAA,  0x2B,  0xAA,  0xAA,  0xBB, 	/* 151B0 */
+	0xAA,  0xAA,  0xAD,  0xA2,  0x82,  0x9E,  0x23,  0xC4,  0x10,  0x97,  0xE6,  0x24,  0x57,  0xEF,  0xA4,  0x2F, 	/* 151C0 */
+	0xEA,  0x00,  0xB7,  0xEA,  0xA8,  0xA2,  0xA2,  0x46,  0xA6,  0x21,  0xE2,  0xF2,  0xD3,  0xE5,  0x28,  0x2F, 	/* 151D0 */
+	0xE5,  0xAA,  0xFE,  0xA2,  0x3E,  0xB2,  0xCA,  0xAA,  0xA4,  0xE2,  0xB1,  0xA7,  0x27,  0xC2,  0x10,  0xDF, 	/* 151E0 */
+	0xE6,  0x92,  0x2B,  0xA5,  0x80,  0xFF,  0xC2,  0x00,  0xAF,  0xEA,  0xA8,  0xA5,  0xC2,  0xE2,  0xA9,  0x2F, 	/* 151F0 */
+	0xE4,  0xAA,  0x9E,  0xE6,  0x28,  0x4E,  0xEF,  0xAA,  0x2E,  0xEA,  0xAA,  0xBE,  0xEA,  0xA0,  0xA2,  0x22, 	/* 15200 */
+	0x1E,  0xAA,  0x21,  0x02,  0x30,  0xD2,  0x85,  0x44,  0x2F,  0xE5,  0xAB,  0xF9,  0x22,  0xFE,  0xB4,  0x4B, 	/* 15210 */
+	0x7C,  0xA4,  0x42,  0x7C,  0xAD,  0x11,  0x0F,  0xFE,  0x11,  0x0F,  0xFE,  0xA5,  0x2D,  0x7E,  0xA5,  0x6F, 	/* 15220 */
+	0xFE,  0x95,  0x2B,  0xD6,  0xD5,  0xA9,  0x66,  0xB0,  0x23,  0x82,  0x28,  0xD3,  0x85,  0x00,  0x2E,  0xE5, 	/* 15230 */
+	0xAA,  0xFE,  0xE2,  0x10,  0xAF,  0xEA,  0xB8,  0xA5,  0x42,  0x92,  0xB9,  0x2F,  0xE4,  0xAA,  0x9F,  0xE6, 	/* 15240 */
+	0x78,  0x51,  0x0F,  0xFE,  0x2A,  0x8B,  0x7E,  0xA9,  0x0A,  0xFC,  0xA1,  0x02,  0x10,  0xBB,  0x27,  0xC4, 	/* 15250 */
+	0x10,  0x9F,  0xE6,  0x92,  0x4B,  0xAF,  0x80,  0x2F,  0xEB,  0x20,  0xAF,  0xEA,  0xAA,  0xAA,  0xA2,  0x86, 	/* 15260 */
+	0xBC,  0x2A,  0x44,  0xDA,  0x9A,  0x46,  0xFE,  0x49,  0x2F,  0xFE,  0x2A,  0x4A,  0xDA,  0xBA,  0x4A,  0xFE, 	/* 15270 */
+	0xA9,  0x22,  0xFE,  0xBD,  0x21,  0x04,  0xFE,  0x99,  0x26,  0x34,  0x55,  0x8F,  0xBC,  0x2E,  0x4A,  0x3C, 	/* 15280 */
+	0xB2,  0x4A,  0xBC,  0xA1,  0x42,  0x62,  0xBF,  0x2E,  0x84,  0x8E,  0x9E,  0x86,  0xB0,  0x4E,  0x0F,  0x8E, 	/* 15290 */
+	0x2E,  0x0A,  0x7C,  0xB5,  0x4A,  0xD4,  0xA5,  0x42,  0xFE,  0x82,  0x42,  0x07,  0xBE,  0x94,  0x83,  0xF8, 	/* 152A0 */
+	0x20,  0x83,  0xF8,  0x20,  0x8F,  0xFE,  0x25,  0x8D,  0xE6,  0x15,  0x06,  0x4C,  0x83,  0x21,  0x04,  0xFE, 	/* 152B0 */
+	0x92,  0x86,  0xD6,  0x55,  0x4F,  0x52,  0x2A,  0x5B,  0x3C,  0xAA,  0x4A,  0xBC,  0xA2,  0x42,  0x44,  0x88, 	/* 152C0 */
+	0x24,  0x04,  0x5E,  0x9E,  0x86,  0x5E,  0x55,  0x2F,  0xFE,  0x21,  0x2A,  0xFE,  0xBB,  0x2A,  0xBE,  0xAE, 	/* 152D0 */
+	0xA2,  0x11,  0x89,  0x22,  0x42,  0x7E,  0xD2,  0x45,  0x7E,  0x25,  0xA5,  0x3C,  0xFA,  0x42,  0x3C,  0xAA, 	/* 152E0 */
+	0x4A,  0xBC,  0xA1,  0x42,  0x62,  0x8C,  0x21,  0x04,  0xFE,  0x91,  0x06,  0xFE,  0x4A,  0xAF,  0xFE,  0x24, 	/* 152F0 */
+	0x4A,  0x7C,  0xB4,  0x4A,  0xFC,  0xA2,  0x42,  0xC2,  0x8E,  0x24,  0x84,  0x4C,  0x9E,  0xA6,  0x4E,  0x5F, 	/* 15300 */
+	0x8F,  0xAA,  0x2B,  0xAB,  0xAA,  0xAB,  0x4B,  0xA5,  0xAF,  0xB3,  0x91,  0x8F,  0x20,  0x82,  0xFE,  0xDA, 	/* 15310 */
+	0xA2,  0xBE,  0x4A,  0xAF,  0xBE,  0x29,  0x4A,  0xE6,  0xB8,  0x8A,  0xBE,  0xB0,  0x82,  0xFF,  0x90,  0x24, 	/* 15320 */
+	0x04,  0x5F,  0x9F,  0x46,  0xAE,  0x5A,  0xAF,  0x1E,  0x2A,  0xA2,  0xAE,  0xB4,  0xAA,  0xAE,  0xA8,  0xA3, 	/* 15330 */
+	0x11,  0x92,  0x20,  0x04,  0xFF,  0x9A,  0xA6,  0xBE,  0x4A,  0xAF,  0xBE,  0x2F,  0xFA,  0xAA,  0xBC,  0x9A, 	/* 15340 */
+	0xBE,  0xA8,  0x83,  0x7F,  0x93,  0x2E,  0xE4,  0xAA,  0x9E,  0xE6,  0xAA,  0x5E,  0xEF,  0x44,  0x2A,  0xAB, 	/* 15350 */
+	0x10,  0xAF,  0xEA,  0x64,  0xA1,  0x82,  0xE4,  0x94,  0x23,  0xC4,  0xC8,  0x97,  0xC6,  0x44,  0x57,  0xEF, 	/* 15360 */
+	0xC8,  0x2E,  0xEA,  0x7C,  0xB5,  0x4A,  0xFC,  0xA5,  0x23,  0x9E,  0x96,  0x2A,  0x84,  0xAC,  0x9A,  0xA6, 	/* 15370 */
+	0xDE,  0x54,  0x8F,  0xFA,  0x2A,  0xAB,  0xBA,  0xAA,  0x4B,  0xB5,  0xAB,  0xB3,  0xD1,  0x9B,  0x04,  0x07, 	/* 15380 */
+	0xFC,  0x04,  0x0F,  0xFE,  0x24,  0x8B,  0xF8,  0xA9,  0x0B,  0xE8,  0xA9,  0x4F,  0xFE,  0x73,  0x4A,  0xD2, 	/* 15390 */
+	0x9C,  0x2E,  0x82,  0xAE,  0xDF,  0x05,  0xFE,  0x2A,  0xA4,  0xFE,  0xF4,  0x42,  0x7C,  0xB4,  0x4A,  0x7C, 	/* 153A0 */
+	0xA2,  0xA2,  0xC6,  0xB6,  0x20,  0x02,  0x00,  0x3F,  0xC4,  0x40,  0x84,  0x0F,  0xFE,  0x04,  0x04,  0x44, 	/* 153B0 */
+	0x44,  0x44,  0x44,  0x7F,  0xC4,  0x04,  0xB8,  0x20,  0x02,  0x3E,  0x3C,  0x85,  0x08,  0x90,  0x8F,  0xC8, 	/* 153C0 */
+	0x10,  0x85,  0x48,  0x54,  0x85,  0x48,  0x7C,  0x84,  0x3E,  0xBA,  0x41,  0x04,  0x10,  0x79,  0x0A,  0x7C, 	/* 153D0 */
+	0x21,  0x4F,  0x94,  0x27,  0xEA,  0x90,  0xA9,  0x8A,  0xA8,  0xFC,  0x48,  0x82,  0x85,  0x41,  0xC4,  0x10, 	/* 153E0 */
+	0x7F,  0xEA,  0xA0,  0x2B,  0xCF,  0x86,  0x2F,  0x8A,  0xAA,  0xA9,  0xCF,  0xFF,  0x88,  0x81,  0x18,  0x8C, 	/* 153F0 */
+	0x7B,  0xC4,  0xA4,  0x7B,  0xC4,  0xA4,  0x7B,  0xC2,  0x94,  0xD6,  0x21,  0xFC,  0x24,  0x0F,  0xFE,  0x24, 	/* 15400 */
+	0x43,  0xFC,  0x8D,  0x3F,  0x82,  0x48,  0x3F,  0x8F,  0xBE,  0xAA,  0xAF,  0xBE,  0x20,  0x03,  0xFC,  0x44, 	/* 15410 */
+	0x0F,  0xFE,  0x24,  0x43,  0xFC,  0x8E,  0x47,  0xC4,  0x44,  0x7F,  0xCA,  0x10,  0x2F,  0xEF,  0x92,  0x23, 	/* 15420 */
+	0xAA,  0x80,  0xAF,  0xEA,  0x94,  0xFA,  0xE8,  0x72,  0x90,  0x42,  0x84,  0xFE,  0x7A,  0x8A,  0xEE,  0x2A, 	/* 15430 */
+	0xAF,  0xEE,  0x21,  0x0A,  0xBE,  0xAE,  0x8A,  0xBE,  0xFA,  0x88,  0x3E,  0x91,  0x00,  0x0F,  0xFE,  0x91, 	/* 15440 */
+	0x2D,  0x12,  0xB5,  0x29,  0x32,  0x99,  0x2A,  0x9A,  0xA2,  0xAC,  0x22,  0x84,  0x28,  0x06,  0x94,  0x00, 	/* 15450 */
+	0x0F,  0xFE,  0x91,  0x28,  0xA2,  0xFF,  0xE8,  0x42,  0xBF,  0xA9,  0x02,  0x90,  0x29,  0x02,  0x8F,  0x28, 	/* 15460 */
+	0x06,  0x95,  0x00,  0x0F,  0xFE,  0x8A,  0x28,  0xA2,  0x13,  0xC2,  0x00,  0x3F,  0x80,  0x40,  0xFF,  0xE0, 	/* 15470 */
+	0x40,  0x04,  0x00,  0x40,  0x98,  0x00,  0x0F,  0xFE,  0x91,  0x2F,  0xFE,  0x00,  0x0F,  0xFE,  0x02,  0x00, 	/* 15480 */
+	0xC0,  0x35,  0x8C,  0x46,  0x04,  0x00,  0x40,  0x9F,  0x00,  0x0F,  0xFE,  0x91,  0x2F,  0xFE,  0x04,  0x00, 	/* 15490 */
+	0x40,  0xFF,  0xE0,  0x40,  0x3F,  0x82,  0x08,  0x20,  0x83,  0xF8,  0xA0,  0x7F,  0xC4,  0xA4,  0x7F,  0xC0, 	/* 154A0 */
+	0x00,  0x7F,  0xC4,  0x04,  0x7F,  0xC4,  0x40,  0x7F,  0xC4,  0x20,  0x79,  0xAC,  0x06,  0xA7,  0x00,  0x07, 	/* 154B0 */
+	0xFE,  0x49,  0x27,  0xFE,  0x10,  0x8F,  0xFE,  0x30,  0x83,  0x9C,  0x56,  0xC5,  0x4A,  0x90,  0x81,  0x08, 	/* 154C0 */
+	0xA8,  0x7F,  0xC4,  0xA4,  0x7F,  0xC0,  0x80,  0xFF,  0xE3,  0xF8,  0x64,  0xCB,  0xFA,  0x24,  0x83,  0xF8, 	/* 154D0 */
+	0x04,  0x20,  0x3E,  0xA9,  0x7F,  0xE4,  0x92,  0x7F,  0xE0,  0x40,  0x07,  0xC0,  0x40,  0x3F,  0x82,  0x08, 	/* 154E0 */
+	0x3F,  0x82,  0x08,  0xFF,  0xE0,  0x40,  0xAA,  0x00,  0x07,  0xFC,  0x4A,  0x47,  0xFC,  0x0A,  0x07,  0xBC, 	/* 154F0 */
+	0x0A,  0x07,  0xBC,  0x0A,  0x0F,  0x3E,  0x12,  0x02,  0x20,  0xAB,  0x00,  0x07,  0xFC,  0x4A,  0x47,  0xFC, 	/* 15500 */
+	0x11,  0x07,  0xD0,  0x11,  0x8F,  0xF4,  0x11,  0x27,  0xD0,  0x1D,  0x0F,  0x10,  0xAE,  0x00,  0x07,  0xFC, 	/* 15510 */
+	0x4A,  0x47,  0xFC,  0x04,  0x0F,  0xFE,  0x04,  0x05,  0xF8,  0x50,  0x85,  0xF8,  0x50,  0x87,  0xFE,  0xB0, 	/* 15520 */
+	0x7F,  0xE4,  0x92,  0x7F,  0xE0,  0x00,  0x39,  0x2F,  0xF2,  0x01,  0x27,  0xD2,  0x01,  0x27,  0xD2,  0x44, 	/* 15530 */
+	0x27,  0xC6,  0xB2,  0x7F,  0xC4,  0xA4,  0x7F,  0xC0,  0x40,  0x7F,  0xC0,  0x50,  0xFF,  0xE1,  0xF8,  0x30, 	/* 15540 */
+	0x8D,  0xF8,  0x10,  0x81,  0xF8,  0xB5,  0x7F,  0xE4,  0x92,  0x7F,  0xE0,  0x00,  0x3F,  0xE2,  0x20,  0x3F, 	/* 15550 */
+	0xC2,  0x20,  0x3F,  0xE4,  0x4A,  0x52,  0x28,  0x8C,  0xB7,  0x7F,  0xE4,  0x92,  0x7F,  0xE1,  0x20,  0x2B, 	/* 15560 */
+	0xCF,  0xA2,  0x49,  0xE7,  0xA0,  0x4A,  0xC7,  0xB0,  0x4A,  0x25,  0x9E,  0xB8,  0x7F,  0xE4,  0x92,  0x7F, 	/* 15570 */
+	0xE2,  0x04,  0x10,  0x4F,  0xFE,  0x00,  0x47,  0xA4,  0x01,  0x47,  0x84,  0x48,  0x47,  0x8C,  0xB9,  0x7F, 	/* 15580 */
+	0xC4,  0xA4,  0x7F,  0xC2,  0x48,  0x25,  0x06,  0xFE,  0x79,  0x0A,  0xFC,  0x29,  0x02,  0xFC,  0x29,  0x02, 	/* 15590 */
+	0xFE,  0x82,  0x7F,  0xE4,  0x92,  0x7F,  0xE2,  0x3C,  0x42,  0x49,  0x3E,  0x6A,  0x2F,  0xBE,  0x2A,  0x2B, 	/* 155A0 */
+	0x3E,  0xAA,  0x22,  0x26,  0x83,  0x7F,  0xC5,  0x24,  0x7F,  0xC0,  0xA0,  0xFF,  0xE2,  0x08,  0x3F,  0x82, 	/* 155B0 */
+	0x08,  0xFF,  0xE3,  0x4C,  0xD5,  0xA0,  0x40,  0x85,  0x00,  0x07,  0xFE,  0x49,  0x27,  0xFE,  0x2A,  0x8D, 	/* 155C0 */
+	0x3E,  0x2E,  0x8F,  0xBE,  0x2A,  0x8B,  0x3E,  0xAA,  0x82,  0x3E,  0x86,  0x7F,  0xC4,  0xA4,  0x7F,  0xC2, 	/* 155D0 */
+	0xA0,  0xFF,  0xC4,  0xA2,  0x79,  0xE4,  0xBC,  0x7A,  0x24,  0x9E,  0x52,  0x48,  0x92,  0x87,  0x7F,  0xC4, 	/* 155E0 */
+	0xA4,  0x7F,  0xC5,  0x10,  0xFF,  0xE5,  0x18,  0xFA,  0x4A,  0xFE,  0xFF,  0x42,  0x54,  0xFF,  0x42,  0x0C, 	/* 155F0 */
+	0x88,  0x7F,  0xC4,  0xA4,  0x7F,  0xC5,  0x00,  0xFF,  0xE5,  0x28,  0xFB,  0xCA,  0xA8,  0xFB,  0xE2,  0x02, 	/* 15600 */
+	0xFA,  0xA2,  0x4C,  0x8A,  0x20,  0x81,  0x10,  0xFF,  0xE0,  0x40,  0x04,  0x07,  0xFC,  0x04,  0x00,  0x40, 	/* 15610 */
+	0xFF,  0xE0,  0x40,  0x04,  0x00,  0x40,  0x8C,  0x20,  0x81,  0x10,  0x7F,  0xC0,  0x40,  0x3F,  0x80,  0x40, 	/* 15620 */
+	0xFF,  0xE0,  0x90,  0x09,  0x01,  0x10,  0x21,  0x2C,  0x0E,  0x8E,  0x20,  0x81,  0x10,  0x7F,  0xC0,  0x40, 	/* 15630 */
+	0x3F,  0x80,  0x40,  0x7F,  0xC0,  0x40,  0xFF,  0xE0,  0xA0,  0x31,  0x8C,  0x06,  0x94,  0x20,  0x81,  0x10, 	/* 15640 */
+	0x7F,  0xC0,  0x40,  0x04,  0x03,  0xF8,  0x04,  0x00,  0x40,  0xFF,  0xE5,  0x24,  0x49,  0x28,  0x92,  0x9A, 	/* 15650 */
+	0x49,  0x05,  0x10,  0x21,  0x8F,  0xA4,  0x27,  0xEF,  0x81,  0x27,  0xC3,  0xA4,  0xE2,  0x42,  0x38,  0x42, 	/* 15660 */
+	0x08,  0x20,  0x9D,  0x48,  0x65,  0x78,  0x24,  0x8F,  0xC8,  0x24,  0x8F,  0xFE,  0x24,  0x83,  0xC8,  0xE6, 	/* 15670 */
+	0x82,  0xCA,  0x40,  0x68,  0xF2,  0x9E,  0x11,  0x07,  0xFC,  0x04,  0x03,  0xFC,  0x04,  0x0F,  0xFE,  0x10, 	/* 15680 */
+	0x03,  0xF8,  0x24,  0x85,  0xFE,  0x88,  0x87,  0xFE,  0xA3,  0x00,  0x07,  0xF8,  0x08,  0x8F,  0xFE,  0x3F, 	/* 15690 */
+	0x85,  0x08,  0x9F,  0x81,  0x10,  0x7F,  0xC0,  0x40,  0xFF,  0xE0,  0x40,  0xA4,  0x02,  0x27,  0xD4,  0x27, 	/* 156A0 */
+	0xEF,  0xE8,  0x24,  0x87,  0xFE,  0x20,  0x83,  0xC8,  0x67,  0xE6,  0x48,  0xA4,  0x83,  0xC8,  0xA8,  0x11, 	/* 156B0 */
+	0x07,  0xFC,  0x04,  0x03,  0xF8,  0x04,  0x0F,  0xFE,  0x24,  0x09,  0x7E,  0x4A,  0x43,  0x20,  0x4D,  0x8B, 	/* 156C0 */
+	0x06,  0xA9,  0x11,  0x07,  0xFE,  0x04,  0x03,  0xFC,  0x04,  0x07,  0xFE,  0x12,  0x4F,  0xFE,  0x11,  0x47, 	/* 156D0 */
+	0xCA,  0x13,  0x63,  0x02,  0xAE,  0x11,  0x0F,  0xFE,  0x04,  0x07,  0xFC,  0x04,  0x0F,  0xFE,  0x52,  0x4B, 	/* 156E0 */
+	0xFA,  0x04,  0x0F,  0xFE,  0x1B,  0x0E,  0x0E,  0xAF,  0x48,  0x05,  0x3C,  0x22,  0x4F,  0xFC,  0x22,  0x4F, 	/* 156F0 */
+	0xBC,  0x22,  0x03,  0x3E,  0xE5,  0x22,  0xEA,  0x47,  0xA8,  0x0C,  0xB2,  0x11,  0x07,  0xFC,  0x04,  0x03, 	/* 15700 */
+	0xF8,  0x04,  0x0F,  0xFE,  0x71,  0x4F,  0xFE,  0x69,  0x4B,  0xC8,  0x09,  0x63,  0x22,  0xB6,  0x91,  0x05, 	/* 15710 */
+	0xFE,  0x2A,  0xAF,  0xBA,  0x28,  0x2F,  0xFE,  0x20,  0x03,  0x7C,  0xE4,  0x42,  0x7C,  0x44,  0x49,  0xFF, 	/* 15720 */
+	0xB8,  0x04,  0x0F,  0xFE,  0x40,  0x03,  0xFC,  0x20,  0x8F,  0xFE,  0xAA,  0xAE,  0xFA,  0xA5,  0xAF,  0xEE, 	/* 15730 */
+	0xA4,  0xAA,  0x92,  0xB9,  0x11,  0x0F,  0xFE,  0x3F,  0x80,  0x40,  0xFF,  0xE5,  0x14,  0x9B,  0x2F,  0xFC, 	/* 15740 */
+	0x04,  0x0F,  0xFE,  0x1B,  0x0E,  0x0E,  0xBD,  0x00,  0x0F,  0xFE,  0x08,  0x24,  0xA2,  0x29,  0x20,  0x82, 	/* 15750 */
+	0x18,  0x62,  0x8A,  0xCB,  0x20,  0x82,  0x08,  0x21,  0x86,  0x81,  0x09,  0x01,  0x48,  0x24,  0x4C,  0x93, 	/* 15760 */
+	0x3F,  0x80,  0x04,  0xFF,  0xE4,  0x92,  0x28,  0xA3,  0x8E,  0xCB,  0x21,  0x86,  0x85,  0x20,  0x02,  0xFE, 	/* 15770 */
+	0xF9,  0x22,  0x36,  0x25,  0xAF,  0x12,  0x13,  0x65,  0x5A,  0x29,  0x23,  0x36,  0x4C,  0x08,  0x3F,  0x86, 	/* 15780 */
+	0xFB,  0xE2,  0x8A,  0xDB,  0x62,  0x8A,  0xCB,  0x20,  0x80,  0xFF,  0x81,  0x0A,  0x24,  0x6F,  0xFE,  0x04, 	/* 15790 */
+	0x00,  0x40,  0x8A,  0x20,  0x02,  0x7E,  0x21,  0x2F,  0xB6,  0x15,  0xA9,  0x12,  0x51,  0x25,  0x36,  0x25, 	/* 157A0 */
+	0xA3,  0x12,  0xC1,  0x20,  0x36,  0x8C,  0x00,  0x0F,  0xBE,  0x49,  0x22,  0x8A,  0xCB,  0x21,  0x86,  0x04, 	/* 157B0 */
+	0x07,  0xFC,  0x11,  0x00,  0x90,  0x0A,  0x0F,  0xFE,  0x92,  0x00,  0x0F,  0xBE,  0x49,  0x23,  0x8E,  0xCB, 	/* 157C0 */
+	0x21,  0x86,  0x08,  0x03,  0xF8,  0x20,  0x83,  0xF8,  0x20,  0x83,  0xF8,  0x94,  0x90,  0x05,  0xFE,  0x22, 	/* 157D0 */
+	0x2F,  0xB2,  0x26,  0xAF,  0xA2,  0x22,  0x63,  0x6A,  0xEB,  0x22,  0x22,  0x42,  0x28,  0x66,  0x95,  0x04, 	/* 157E0 */
+	0x00,  0xA0,  0x3F,  0x8C,  0x06,  0x3F,  0x82,  0x08,  0x3F,  0x8F,  0xBE,  0x28,  0xAD,  0xB6,  0x28,  0xAC, 	/* 157F0 */
+	0xB2,  0xA0,  0x00,  0x0F,  0xBE,  0x49,  0x22,  0x8A,  0xCB,  0x20,  0x40,  0xFF,  0xE2,  0x48,  0x55,  0x4F, 	/* 15800 */
+	0xFE,  0x04,  0x00,  0x40,  0xA1,  0x0A,  0x0F,  0xBE,  0x0A,  0x07,  0xBC,  0x0A,  0x0F,  0xBE,  0x12,  0x0F, 	/* 15810 */
+	0xBE,  0x28,  0xAD,  0xB6,  0x28,  0xAC,  0xB2,  0xA6,  0x11,  0x0F,  0xFE,  0x7A,  0x44,  0xA4,  0x7A,  0x44, 	/* 15820 */
+	0xA4,  0x58,  0xCF,  0xBE,  0x28,  0xAD,  0xB6,  0x28,  0xAC,  0xB2,  0xA9,  0xF8,  0x00,  0xFE,  0x79,  0x24, 	/* 15830 */
+	0xB6,  0x7D,  0xA4,  0x12,  0x7F,  0x6D,  0x5A,  0xD5,  0x27,  0xD2,  0x55,  0x24,  0xD6,  0xAB,  0x00,  0x0F, 	/* 15840 */
+	0xFC,  0xB4,  0x06,  0xC0,  0xB7,  0xE2,  0x68,  0x22,  0x8F,  0xA8,  0x8A,  0x8F,  0xA8,  0x8A,  0xAF,  0xC6, 	/* 15850 */
+	0xB0,  0x20,  0x8F,  0x94,  0x22,  0x2F,  0xC1,  0x8F,  0xEF,  0x92,  0x8D,  0xAF,  0xB6,  0x21,  0x2F,  0xB6, 	/* 15860 */
+	0x25,  0xA2,  0x12,  0xB3,  0xFB,  0x8A,  0x2A,  0xFC,  0xAB,  0x7E,  0xCA,  0x4F,  0x98,  0x06,  0x6F,  0xFC, 	/* 15870 */
+	0x29,  0x4D,  0xEC,  0x29,  0x4C,  0xE4,  0xB9,  0x20,  0x0F,  0x7E,  0x21,  0x25,  0x36,  0xFD,  0xA5,  0x12, 	/* 15880 */
+	0xFB,  0x60,  0x5A,  0xF9,  0x25,  0x36,  0x50,  0x18,  0xFF,  0xBB,  0x18,  0x0E,  0xFE,  0x71,  0x2F,  0x92, 	/* 15890 */
+	0x35,  0xA6,  0xB6,  0xA1,  0x2F,  0xB6,  0xAD,  0xAF,  0x92,  0xA9,  0x2F,  0xB6,  0xBC,  0xFF,  0xC4,  0xA4, 	/* 158A0 */
+	0x29,  0x47,  0xFC,  0x24,  0x83,  0xF8,  0x24,  0x87,  0xFC,  0x11,  0x0F,  0xFF,  0x11,  0x8E,  0x06,  0x80, 	/* 158B0 */
+	0x27,  0xE2,  0x12,  0xAB,  0x67,  0x12,  0x27,  0xEF,  0xA8,  0x53,  0xE5,  0x68,  0x5B,  0xE5,  0x3E,  0x82, 	/* 158C0 */
+	0x80,  0x3E,  0x81,  0x04,  0x00,  0x40,  0x7F,  0xC0,  0x50,  0x06,  0x0F,  0xFE,  0x18,  0x02,  0x98,  0xCE, 	/* 158D0 */
+	0x00,  0x80,  0x08,  0x40,  0x7C,  0x83,  0x04,  0x00,  0x44,  0x3F,  0x80,  0x50,  0xFF,  0xE0,  0x40,  0x0F, 	/* 158E0 */
+	0xC3,  0x80,  0xCF,  0x80,  0x08,  0x00,  0x80,  0x30,  0x84,  0x04,  0x07,  0xFC,  0x05,  0x0F,  0xFE,  0x38, 	/* 158F0 */
+	0x8C,  0xF0,  0x08,  0x47,  0xFC,  0x08,  0x0F,  0xFC,  0x08,  0x20,  0x7E,  0x85,  0x04,  0x03,  0xF8,  0x04, 	/* 15900 */
+	0x80,  0x50,  0xFF,  0xE0,  0x40,  0x1F,  0x83,  0x08,  0xDF,  0x81,  0x08,  0x10,  0x81,  0xF8,  0x86,  0x04, 	/* 15910 */
+	0x07,  0xFC,  0x05,  0x0F,  0xFE,  0x38,  0xCC,  0xF0,  0x08,  0x23,  0xFE,  0x20,  0x83,  0xF8,  0x20,  0x83, 	/* 15920 */
+	0xF8,  0x8B,  0x04,  0x07,  0xFC,  0x05,  0x0F,  0xFE,  0x30,  0x0C,  0xFC,  0x00,  0x0F,  0xFE,  0x11,  0x87, 	/* 15930 */
+	0xE4,  0x04,  0x0F,  0xFE,  0x8C,  0x00,  0x0F,  0xFE,  0x02,  0x00,  0x40,  0x7F,  0xE4,  0x92,  0x49,  0x24, 	/* 15940 */
+	0x92,  0x49,  0x24,  0x92,  0x49,  0x24,  0x06,  0x90,  0x00,  0x4F,  0x84,  0x20,  0x4F,  0xFF,  0xA8,  0x4A, 	/* 15950 */
+	0xA4,  0xA9,  0x4A,  0x94,  0xA8,  0x4A,  0x84,  0xA8,  0x49,  0x8C,  0x92,  0x04,  0x00,  0x4C,  0x7F,  0x00, 	/* 15960 */
+	0x40,  0x7F,  0xC0,  0x40,  0xFF,  0xE0,  0x40,  0x0E,  0x03,  0x58,  0xC4,  0x60,  0x40,  0x95,  0x22,  0x42, 	/* 15970 */
+	0x24,  0xFA,  0x42,  0x7E,  0x7A,  0x42,  0x24,  0xFA,  0x46,  0xFE,  0x72,  0x4A,  0xA4,  0xA4,  0x42,  0x84, 	/* 15980 */
+	0x97,  0x20,  0xCF,  0xF0,  0x21,  0x0F,  0x9E,  0x27,  0x0F,  0x90,  0x21,  0xE7,  0x70,  0x69,  0x0A,  0x12, 	/* 15990 */
+	0xA1,  0x22,  0x0E,  0x98,  0x20,  0x03,  0xBC,  0xE0,  0x02,  0x00,  0xFF,  0xE2,  0x10,  0xF9,  0x02,  0x14, 	/* 159A0 */
+	0x72,  0x46,  0xAE,  0xA7,  0x22,  0x02,  0x99,  0x20,  0x03,  0x7C,  0xE5,  0x42,  0x54,  0xF5,  0x42,  0x54, 	/* 159B0 */
+	0xFF,  0xC2,  0x40,  0x74,  0x06,  0xC0,  0xA4,  0x22,  0x3E,  0x9C,  0x20,  0x03,  0xBC,  0xE2,  0x42,  0x24, 	/* 159C0 */
+	0xFB,  0xC2,  0x20,  0xFA,  0x02,  0x3E,  0x72,  0x26,  0xA2,  0xA2,  0x22,  0x3E,  0xA1,  0x20,  0x82,  0xE8, 	/* 159D0 */
+	0xFA,  0x82,  0xBE,  0xFE,  0xA2,  0xAA,  0xFA,  0xA2,  0xEA,  0x6A,  0xA6,  0xBA,  0xBD,  0x22,  0x2C,  0xA8, 	/* 159E0 */
+	0x20,  0x02,  0xFE,  0xF5,  0xC2,  0x40,  0xFF,  0xE2,  0x5A,  0xFD,  0x43,  0x7A,  0x68,  0x46,  0xFE,  0xB1, 	/* 159F0 */
+	0x42,  0x0C,  0xB3,  0x00,  0x0F,  0xFE,  0x21,  0x02,  0x10,  0x3F,  0x02,  0x10,  0x3F,  0x02,  0x10,  0x21, 	/* 15A00 */
+	0xE3,  0xF0,  0xE1,  0x00,  0x10,  0xB6,  0x00,  0x0F,  0xFC,  0x4A,  0x44,  0xA8,  0x7B,  0x04,  0xB8,  0x7A, 	/* 15A10 */
+	0x44,  0xA2,  0x4E,  0x27,  0xBC,  0xCA,  0x00,  0xA0,  0xBB,  0x01,  0x0F,  0xD0,  0x51,  0x07,  0x10,  0x55, 	/* 15A20 */
+	0xC5,  0x50,  0x75,  0x05,  0x50,  0x55,  0x07,  0x50,  0xD5,  0x01,  0xFE,  0xBD,  0x01,  0x0F,  0x90,  0x5F, 	/* 15A30 */
+	0xE5,  0x92,  0x79,  0x25,  0x10,  0x71,  0x85,  0x18,  0x5A,  0x8F,  0x2A,  0x14,  0xA1,  0x86,  0xBF,  0x01, 	/* 15A40 */
+	0x0F,  0xD0,  0x51,  0x47,  0x54,  0x55,  0x45,  0x98,  0x71,  0x05,  0x28,  0x52,  0x87,  0x44,  0xD8,  0x41, 	/* 15A50 */
+	0x02,  0x86,  0x01,  0x0F,  0x90,  0x52,  0x85,  0x44,  0x7F,  0xE5,  0x01,  0x7F,  0xC5,  0x24,  0x52,  0x4F, 	/* 15A60 */
+	0x38,  0x12,  0x01,  0x20,  0x8A,  0x02,  0x0F,  0xCE,  0x5A,  0xA7,  0xAA,  0x5A,  0xA5,  0xAA,  0x7A,  0xA5, 	/* 15A70 */
+	0xAA,  0x5E,  0xAF,  0x2E,  0x14,  0x81,  0x88,  0x92,  0x00,  0xCF,  0xF0,  0x51,  0x05,  0x10,  0x7F,  0xE5, 	/* 15A80 */
+	0x10,  0x71,  0x05,  0x7C,  0x54,  0x4F,  0x44,  0x14,  0x41,  0x7C,  0x96,  0x00,  0x0F,  0xFE,  0x4A,  0x27, 	/* 15A90 */
+	0xA2,  0x4A,  0x2F,  0xBE,  0x08,  0x07,  0xFE,  0x04,  0x01,  0xF8,  0x04,  0x07,  0xFE,  0x98,  0x01,  0x0F, 	/* 15AA0 */
+	0xFE,  0x55,  0x25,  0x7E,  0x75,  0x25,  0x7E,  0x70,  0x05,  0xFF,  0x51,  0x0F,  0x3C,  0x10,  0x41,  0x18, 	/* 15AB0 */
+	0x9A,  0xFC,  0x04,  0xFE,  0x7A,  0x44,  0x98,  0x7E,  0x4C,  0x82,  0x0B,  0x87,  0xC2,  0x26,  0xCD,  0x58, 	/* 15AC0 */
+	0x24,  0x6C,  0x40,  0x9E,  0xFB,  0xE8,  0xA2,  0xFB,  0xE8,  0xA2,  0xFB,  0xE8,  0x02,  0xBF,  0xA9,  0x12, 	/* 15AD0 */
+	0x9F,  0x29,  0x12,  0xBF,  0x28,  0x16,  0x9F,  0x40,  0x07,  0xDE,  0x91,  0x2F,  0xF2,  0x29,  0xE4,  0x40, 	/* 15AE0 */
+	0xFF,  0xE1,  0x08,  0x1F,  0x81,  0x0E,  0x7F,  0x80,  0x08,  0xA1,  0x02,  0x8F,  0xA8,  0x55,  0x45,  0x92, 	/* 15AF0 */
+	0x72,  0x45,  0x2C,  0x77,  0x45,  0x00,  0x54,  0x8F,  0xAA,  0x1A,  0x21,  0x1A,  0xA2,  0x01,  0x0F,  0xFE, 	/* 15B00 */
+	0x54,  0x25,  0x42,  0x77,  0xC5,  0x10,  0x75,  0x05,  0x5C,  0x55,  0x07,  0x70,  0xD5,  0x81,  0x86,  0xA8, 	/* 15B10 */
+	0x02,  0x2F,  0xA2,  0x54,  0x47,  0xAA,  0x54,  0x55,  0xEF,  0x72,  0x55,  0x24,  0x5F,  0xF7,  0x24,  0xD2, 	/* 15B20 */
+	0x41,  0x44,  0xAF,  0x01,  0x1F,  0xA2,  0x55,  0x55,  0x22,  0x77,  0x75,  0x11,  0x75,  0x55,  0x55,  0x57, 	/* 15B30 */
+	0x77,  0x55,  0xD2,  0x51,  0x44,  0xB0,  0x02,  0x0F,  0xFE,  0x55,  0x25,  0x5E,  0x76,  0x65,  0x4A,  0x75, 	/* 15B40 */
+	0x25,  0x7E,  0x53,  0x07,  0x6A,  0xDA,  0x21,  0x1E,  0xB2,  0x13,  0x8F,  0xEA,  0x57,  0xE7,  0xE8,  0x41, 	/* 15B50 */
+	0x88,  0x64,  0x7F,  0xE1,  0x08,  0x1F,  0x81,  0x0E,  0xFF,  0x80,  0x08,  0xB3,  0x24,  0x45,  0x6A,  0xA9, 	/* 15B60 */
+	0x06,  0x5C,  0xA7,  0x02,  0x8E,  0x7F,  0xE1,  0x08,  0x1F,  0x81,  0x0E,  0xFF,  0x80,  0x08,  0xB4,  0x01, 	/* 15B70 */
+	0x0F,  0xFE,  0x51,  0x07,  0xFE,  0x5A,  0xA5,  0xAA,  0x7F,  0xE5,  0x20,  0x52,  0x8F,  0x6A,  0x1A,  0x21, 	/* 15B80 */
+	0x1A,  0xB6,  0x7F,  0xC1,  0x10,  0x1F,  0x01,  0x10,  0x7F,  0x80,  0x10,  0xFF,  0xE4,  0xA4,  0x7B,  0xC4, 	/* 15B90 */
+	0xA4,  0xFF,  0xC0,  0x84,  0xB7,  0x02,  0x4F,  0xFE,  0x55,  0x55,  0x54,  0x7F,  0xF5,  0x04,  0x77,  0x55, 	/* 15BA0 */
+	0x55,  0x57,  0x67,  0x5A,  0xD7,  0xA1,  0x11,  0xB9,  0x00,  0x8F,  0xFF,  0x55,  0x17,  0x1A,  0x55,  0x55, 	/* 15BB0 */
+	0x8F,  0x77,  0xE5,  0x5A,  0x5F,  0xFF,  0x08,  0x10,  0x81,  0x18,  0xBD,  0xF1,  0x05,  0xFE,  0x71,  0x05, 	/* 15BC0 */
+	0xFE,  0xFA,  0xA1,  0xFE,  0xF0,  0x05,  0x7E,  0x73,  0x05,  0x6A,  0xFA,  0x21,  0x1E,  0xBE,  0xFA,  0x04, 	/* 15BD0 */
+	0xBE,  0xFC,  0x44,  0xBC,  0x7A,  0x24,  0x9E,  0xFF,  0xE1,  0x10,  0x1F,  0x01,  0x10,  0xFF,  0xE0,  0x10, 	/* 15BE0 */
+	0xBF,  0x04,  0x03,  0xF8,  0x04,  0x8F,  0xFE,  0x04,  0x83,  0xF8,  0x04,  0x07,  0xFC,  0x04,  0x0F,  0xFE, 	/* 15BF0 */
+	0x04,  0x00,  0x40,  0x84,  0x81,  0x0F,  0x7C,  0x81,  0x4F,  0xFE,  0x41,  0x47,  0xFC,  0x51,  0x0F,  0xBC, 	/* 15C00 */
+	0x11,  0x03,  0x7E,  0x49,  0x08,  0x10,  0x85,  0x04,  0x07,  0xFC,  0x04,  0x4F,  0xFF,  0x04,  0x47,  0xFC, 	/* 15C10 */
+	0x55,  0x45,  0x54,  0x7F,  0xC4,  0x44,  0x75,  0xC9,  0x54,  0x86,  0x01,  0x07,  0xFC,  0x41,  0x47,  0xFE, 	/* 15C20 */
+	0x41,  0x47,  0x7C,  0x41,  0x0F,  0xFC,  0x51,  0x04,  0xFE,  0x79,  0x0C,  0x50,  0x87,  0xFA,  0x00,  0x3E, 	/* 15C30 */
+	0x7D,  0x44,  0x98,  0x7E,  0x68,  0x40,  0x7F,  0xC0,  0x44,  0xFF,  0xE0,  0x40,  0x7F,  0xC0,  0x40,  0x89, 	/* 15C40 */
+	0x04,  0x00,  0x40,  0xFF,  0xE8,  0x42,  0x8A,  0x2B,  0x1A,  0x84,  0x28,  0x42,  0x8A,  0x2B,  0x1A,  0x80, 	/* 15C50 */
+	0x28,  0x06,  0x8B,  0x01,  0x07,  0x10,  0x51,  0x05,  0xFE,  0x71,  0x25,  0x12,  0x51,  0x27,  0x12,  0x52, 	/* 15C60 */
+	0x25,  0x22,  0x54,  0x2B,  0x8C,  0x8C,  0x77,  0x85,  0x48,  0x54,  0x85,  0x48,  0x74,  0x85,  0x48,  0x54, 	/* 15C70 */
+	0x87,  0x48,  0x54,  0x85,  0x4A,  0x58,  0xAB,  0x86,  0x93,  0x04,  0x0F,  0xFE,  0x40,  0x03,  0xFC,  0x00, 	/* 15C80 */
+	0x03,  0xF8,  0x20,  0x83,  0xF8,  0x20,  0x83,  0xF8,  0x20,  0x82,  0x18,  0x96,  0x24,  0x81,  0x48,  0x15, 	/* 15C90 */
+	0x00,  0x40,  0x3F,  0x82,  0x08,  0x3F,  0x82,  0x08,  0x3F,  0x82,  0x08,  0x20,  0x82,  0x18,  0x98,  0x00, 	/* 15CA0 */
+	0x47,  0x84,  0x48,  0x44,  0xBF,  0x78,  0x44,  0x84,  0x4A,  0x47,  0x94,  0x49,  0x44,  0x84,  0x48,  0x49, 	/* 15CB0 */
+	0x8C,  0x9A,  0x01,  0x07,  0x10,  0x51,  0x05,  0x10,  0x7F,  0xC5,  0x10,  0x51,  0x07,  0x10,  0x51,  0x05, 	/* 15CC0 */
+	0x10,  0x5F,  0xEB,  0x00,  0x9B,  0x00,  0x07,  0x7C,  0x51,  0x05,  0x10,  0x71,  0x05,  0x10,  0x51,  0x07, 	/* 15CD0 */
+	0x10,  0x51,  0x05,  0x10,  0x5F,  0xEB,  0x00,  0x9D,  0x7B,  0xE4,  0x88,  0x48,  0x84,  0x88,  0x7F,  0xF4, 	/* 15CE0 */
+	0x88,  0x48,  0x87,  0x88,  0x48,  0x84,  0x88,  0x48,  0x89,  0x88,  0xA1,  0x03,  0x87,  0xA8,  0x4A,  0x84, 	/* 15CF0 */
+	0xAA,  0x7C,  0x64,  0x80,  0x4F,  0xC7,  0x84,  0x4A,  0x84,  0x90,  0x4A,  0x89,  0xC6,  0xA2,  0x01,  0x07, 	/* 15D00 */
+	0x90,  0x4F,  0xE4,  0x90,  0x79,  0x04,  0xFE,  0x4A,  0x47,  0xA4,  0x49,  0x84,  0x98,  0x4A,  0x49,  0xC2, 	/* 15D10 */
+	0xA5,  0x00,  0x07,  0x7E,  0x55,  0x25,  0x52,  0x75,  0x25,  0x7E,  0x54,  0x07,  0x40,  0x54,  0x05,  0x42, 	/* 15D20 */
+	0x54,  0x2B,  0x3E,  0xA9,  0x00,  0x07,  0xFE,  0x00,  0x07,  0xFE,  0x40,  0x27,  0xFE,  0x50,  0x45,  0xFC, 	/* 15D30 */
+	0x50,  0x45,  0xFC,  0x90,  0x41,  0x0C,  0xAA,  0x02,  0x0F,  0x20,  0x9F,  0xE9,  0x20,  0xF2,  0x09,  0x3C, 	/* 15D40 */
+	0x92,  0x4F,  0x24,  0x94,  0x49,  0x44,  0x98,  0x4B,  0x18,  0xAC,  0x01,  0x07,  0x94,  0x49,  0x24,  0xFE, 	/* 15D50 */
+	0x79,  0x04,  0x90,  0x49,  0x87,  0x98,  0x4A,  0x84,  0xAA,  0x4C,  0xA9,  0x86,  0xAD,  0x07,  0x0E,  0x10, 	/* 15D60 */
+	0xA1,  0x0A,  0xFE,  0xE9,  0x2A,  0x92,  0xAA,  0xAE,  0xAA,  0xAC,  0x6A,  0x82,  0xA8,  0x2A,  0x86,  0xAF, 	/* 15D70 */
+	0x04,  0x02,  0x78,  0x24,  0x0F,  0xFE,  0x00,  0x03,  0xF8,  0x20,  0x83,  0xF8,  0x20,  0x83,  0xF8,  0x20, 	/* 15D80 */
+	0x82,  0x18,  0xB1,  0x01,  0x07,  0x10,  0x51,  0x05,  0xFE,  0x72,  0x05,  0x28,  0x52,  0x87,  0x48,  0x55, 	/* 15D90 */
+	0x45,  0x92,  0x59,  0xEB,  0x32,  0xB2,  0x04,  0x0F,  0xFE,  0x09,  0x01,  0x38,  0x7C,  0x43,  0xF8,  0x20, 	/* 15DA0 */
+	0x83,  0xF8,  0x20,  0x83,  0xF8,  0x20,  0x82,  0x18,  0xB4,  0x30,  0x80,  0xD0,  0x07,  0x07,  0x88,  0x08, 	/* 15DB0 */
+	0x0F,  0xFE,  0x10,  0x83,  0xF8,  0xD0,  0x81,  0xF8,  0x10,  0x81,  0x18,  0xBA,  0x01,  0x07,  0x10,  0x5F, 	/* 15DC0 */
+	0xE5,  0x10,  0x71,  0x05,  0x7E,  0x55,  0x27,  0x52,  0x55,  0x25,  0x56,  0x51,  0x0B,  0x10,  0x83,  0x00, 	/* 15DD0 */
+	0x07,  0xFC,  0x44,  0x47,  0xFC,  0x44,  0x47,  0xFC,  0x20,  0x83,  0xF8,  0x20,  0x83,  0xF8,  0x20,  0x82, 	/* 15DE0 */
+	0x18,  0x84,  0x04,  0x07,  0xFC,  0x44,  0x47,  0xFC,  0x44,  0x47,  0xFC,  0x20,  0x83,  0xF8,  0x20,  0x83, 	/* 15DF0 */
+	0xF8,  0x20,  0x82,  0x18,  0x86,  0x00,  0x07,  0xBC,  0x4A,  0x44,  0xA4,  0x7B,  0xC4,  0xA4,  0x4A,  0x47, 	/* 15E00 */
+	0xA4,  0x4B,  0xC4,  0x80,  0x48,  0x09,  0xFE,  0x8C,  0x0A,  0x0F,  0xA6,  0x0B,  0x83,  0xA2,  0xC9,  0xE3, 	/* 15E10 */
+	0xF8,  0x20,  0x83,  0xF8,  0x20,  0x83,  0xF8,  0x20,  0x82,  0x18,  0x8E,  0x01,  0x0F,  0x10,  0x92,  0x89, 	/* 15E20 */
+	0x24,  0xF4,  0xE9,  0xF2,  0x90,  0x0F,  0x7C,  0x94,  0x49,  0x44,  0x94,  0x4B,  0x7C,  0x96,  0x01,  0x07, 	/* 15E30 */
+	0x98,  0x4B,  0x44,  0xD2,  0x7F,  0xC4,  0x90,  0x49,  0x07,  0xFE,  0x49,  0x04,  0x90,  0x49,  0x09,  0x90, 	/* 15E40 */
+	0x99,  0x02,  0x07,  0xA0,  0x4B,  0xE4,  0xD0,  0x7D,  0x04,  0x9E,  0x49,  0x07,  0x90,  0x49,  0xE4,  0x90, 	/* 15E50 */
+	0x49,  0x09,  0x90,  0x9A,  0x00,  0x07,  0xFE,  0x48,  0x84,  0x88,  0x79,  0x04,  0x9C,  0x4B,  0x27,  0xD0, 	/* 15E60 */
+	0x49,  0x04,  0x90,  0x49,  0x09,  0xFE,  0x9B,  0x00,  0x07,  0x7E,  0x55,  0x25,  0x52,  0x77,  0xE5,  0x52, 	/* 15E70 */
+	0x55,  0x27,  0x7E,  0x51,  0x05,  0x10,  0x51,  0x0B,  0x10,  0x9D,  0x00,  0xC7,  0x70,  0x55,  0x05,  0x50, 	/* 15E80 */
+	0x75,  0x05,  0x7E,  0x54,  0x87,  0x48,  0x54,  0x85,  0xEA,  0x50,  0x6B,  0xFA,  0x9E,  0x04,  0x07,  0x40, 	/* 15E90 */
+	0x57,  0xE5,  0x82,  0x77,  0xA5,  0x0A,  0x50,  0xA7,  0x7A,  0x54,  0xC5,  0x40,  0x54,  0x2B,  0x3E,  0xA1, 	/* 15EA0 */
+	0x00,  0x02,  0x3E,  0x22,  0x2F,  0xE2,  0x23,  0xE2,  0x22,  0x7A,  0x24,  0xBE,  0x4A,  0x24,  0xA2,  0x7A, 	/* 15EB0 */
+	0x20,  0x46,  0xA4,  0x44,  0x44,  0x94,  0x52,  0x44,  0xC4,  0x49,  0x47,  0xFC,  0x51,  0x45,  0xF4,  0x51, 	/* 15EC0 */
+	0x45,  0xF5,  0x51,  0x59,  0x33,  0xA5,  0x00,  0x0F,  0xFE,  0x24,  0x02,  0x7C,  0x54,  0x0B,  0xFE,  0x20, 	/* 15ED0 */
+	0x83,  0xF8,  0x20,  0x83,  0xF8,  0x20,  0x82,  0x18,  0xAF,  0x01,  0x07,  0x10,  0x5F,  0xE5,  0x28,  0x77, 	/* 15EE0 */
+	0xC5,  0x83,  0x57,  0xE7,  0x20,  0x53,  0xC5,  0x24,  0x50,  0x4B,  0x18,  0xB1,  0x01,  0x07,  0x92,  0x4D, 	/* 15EF0 */
+	0x24,  0xB4,  0x79,  0x04,  0xFE,  0x4A,  0x87,  0xA8,  0x4A,  0x84,  0xCA,  0x4C,  0xA9,  0x86,  0xB4,  0x00, 	/* 15F00 */
+	0x0E,  0xFE,  0xA8,  0x2A,  0xBA,  0xE8,  0x2A,  0xBA,  0xAA,  0xAE,  0xAA,  0xAB,  0xAA,  0x82,  0xA8,  0x2A, 	/* 15F10 */
+	0x86,  0xB8,  0x04,  0x0E,  0x40,  0xA7,  0xEA,  0x82,  0xF0,  0xAA,  0xDA,  0xAA,  0xAE,  0xDA,  0xA8,  0xAA, 	/* 15F20 */
+	0xFA,  0xA0,  0x2A,  0x0C,  0xBC,  0x04,  0x47,  0x24,  0x52,  0x85,  0x7E,  0x72,  0x45,  0x24,  0x5F,  0xF7, 	/* 15F30 */
+	0x24,  0x52,  0x45,  0x24,  0x54,  0x4B,  0x84,  0xBD,  0x22,  0x02,  0x24,  0x4B,  0x8F,  0x60,  0x06,  0x27, 	/* 15F40 */
+	0x9E,  0x4A,  0x07,  0xA4,  0x4B,  0x87,  0xA0,  0x4A,  0x25,  0x9E,  0x82,  0x02,  0x07,  0xA4,  0x4B,  0x84, 	/* 15F50 */
+	0xA0,  0x7A,  0x24,  0x9E,  0x48,  0x07,  0xBE,  0x4A,  0x24,  0xBE,  0x4A,  0x29,  0xBE,  0x85,  0x04,  0x03, 	/* 15F60 */
+	0xF8,  0x04,  0x82,  0x98,  0xFB,  0xE2,  0x92,  0xDA,  0x63,  0xF8,  0x20,  0x83,  0xF8,  0x20,  0x82,  0x18, 	/* 15F70 */
+	0x86,  0x01,  0x07,  0x1E,  0x52,  0x45,  0xFE,  0x74,  0x05,  0x5C,  0x55,  0x47,  0x54,  0x55,  0xC5,  0x50, 	/* 15F80 */
+	0x59,  0x2B,  0x0E,  0x87,  0x02,  0x0E,  0xFC,  0xA2,  0x4A,  0x24,  0xE4,  0x4A,  0x98,  0xA8,  0x8F,  0xFE, 	/* 15F90 */
+	0xAA,  0xAA,  0xAA,  0xAA,  0xAB,  0x54,  0x88,  0x00,  0xC7,  0x70,  0x54,  0x25,  0x5C,  0x75,  0x15,  0x52, 	/* 15FA0 */
+	0x55,  0xC7,  0x58,  0x55,  0x45,  0x54,  0x55,  0x2B,  0x91,  0x89,  0x02,  0x07,  0x10,  0x50,  0x05,  0x70, 	/* 15FB0 */
+	0x71,  0x25,  0xFC,  0x53,  0x87,  0x54,  0x55,  0x45,  0x92,  0x51,  0x1B,  0x30,  0x8A,  0x04,  0x0F,  0x5E, 	/* 15FC0 */
+	0x04,  0x0F,  0xBE,  0x11,  0x03,  0xF8,  0xD1,  0x61,  0xF0,  0x11,  0x01,  0xF0,  0x11,  0x01,  0x30,  0x9A, 	/* 15FD0 */
+	0x04,  0x0E,  0x4E,  0xBF,  0xAA,  0x4A,  0xE4,  0xAB,  0xFA,  0xA4,  0xAE,  0xAA,  0xAB,  0xCB,  0xD8,  0xA0, 	/* 15FE0 */
+	0x8A,  0x08,  0x9B,  0x00,  0x07,  0xFC,  0x55,  0x45,  0xA8,  0x75,  0x45,  0x54,  0x50,  0x07,  0xFC,  0x52, 	/* 15FF0 */
+	0x05,  0x20,  0x52,  0x0B,  0xFC,  0xA3,  0x00,  0x03,  0xFE,  0x20,  0x03,  0xFE,  0x2A,  0x44,  0xD8,  0x98, 	/* 16000 */
+	0x63,  0xFC,  0x20,  0x43,  0xFC,  0x20,  0x42,  0x0C,  0xA9,  0x22,  0x02,  0x7E,  0x2A,  0x44,  0x38,  0x54, 	/* 16010 */
+	0x4D,  0xFE,  0x54,  0x55,  0x7C,  0x54,  0x45,  0x7C,  0x44,  0x44,  0x4C,  0xAF,  0x01,  0x47,  0x12,  0x57, 	/* 16020 */
+	0xE5,  0x10,  0x77,  0xE5,  0x52,  0x57,  0xE7,  0x52,  0x57,  0xE5,  0x52,  0x55,  0x2B,  0x56,  0xB1,  0x04, 	/* 16030 */
+	0x47,  0x24,  0x52,  0x85,  0x7C,  0x74,  0x45,  0x44,  0x57,  0xC7,  0x28,  0x52,  0x85,  0x2A,  0x54,  0xAB, 	/* 16040 */
+	0x46,  0xB3,  0x02,  0x2E,  0x92,  0xA5,  0x4A,  0x48,  0xE0,  0x0A,  0x8A,  0xAE,  0xAE,  0x92,  0xAA,  0xAA, 	/* 16050 */
+	0xCA,  0xA8,  0x2A,  0xFE,  0xB9,  0x00,  0x07,  0x7C,  0x54,  0x05,  0x7C,  0x74,  0x05,  0x7C,  0x54,  0x07, 	/* 16060 */
+	0xFE,  0x55,  0x45,  0x48,  0x57,  0x4B,  0xC2,  0xBE,  0x01,  0x07,  0x7E,  0x55,  0x25,  0x7E,  0x75,  0x25, 	/* 16070 */
+	0x7E,  0x52,  0x87,  0x48,  0x5F,  0xF5,  0x08,  0x50,  0x8B,  0x08,  0x86,  0x02,  0x87,  0x28,  0x5F,  0xE5, 	/* 16080 */
+	0xAA,  0x7A,  0xA5,  0xFE,  0x5A,  0xA7,  0xAA,  0x5F,  0xF5,  0x14,  0x52,  0x2B,  0x42,  0x8B,  0x01,  0x07, 	/* 16090 */
+	0x10,  0x5F,  0xE5,  0x28,  0x73,  0xC5,  0x54,  0x5E,  0xC7,  0x58,  0x54,  0x85,  0x54,  0x56,  0x4B,  0x42, 	/* 160A0 */
+	0x8E,  0xFB,  0xEA,  0x02,  0xFB,  0x4A,  0x08,  0xFB,  0x63,  0xF8,  0x20,  0x83,  0xF8,  0x20,  0x83,  0xF8, 	/* 160B0 */
+	0x20,  0x82,  0x18,  0x90,  0x04,  0x07,  0xFE,  0x48,  0x85,  0xFE,  0x6A,  0x84,  0x98,  0x5F,  0xC5,  0x24, 	/* 160C0 */
+	0x5D,  0xC9,  0x24,  0x9D,  0xC1,  0x0C,  0x91,  0x01,  0x07,  0x7E,  0x54,  0x05,  0x52,  0x75,  0x25,  0x5F, 	/* 160D0 */
+	0x57,  0x27,  0x5A,  0x55,  0x65,  0x52,  0x59,  0x2B,  0x16,  0x93,  0x02,  0x87,  0x28,  0x5E,  0xE5,  0x28, 	/* 160E0 */
+	0x72,  0x85,  0xEE,  0x52,  0x87,  0x28,  0x5E,  0xE5,  0x48,  0x54,  0x8B,  0x88,  0x94,  0x01,  0x07,  0xFE, 	/* 160F0 */
+	0x5A,  0xA5,  0xAA,  0x72,  0x85,  0x4E,  0x58,  0x07,  0x7C,  0x51,  0x05,  0x10,  0x51,  0x0B,  0xFE,  0x95, 	/* 16100 */
+	0x01,  0x0E,  0x10,  0xBF,  0xEB,  0x02,  0xEE,  0xEA,  0xAA,  0xAA,  0xAF,  0x6E,  0xA2,  0x8A,  0x48,  0xA8, 	/* 16110 */
+	0xAB,  0x06,  0x9F,  0x01,  0x07,  0xFE,  0x58,  0x25,  0xFE,  0x71,  0x05,  0x2C,  0x5F,  0xA7,  0x10,  0x57, 	/* 16120 */
+	0xC5,  0x10,  0x51,  0x0B,  0xFE,  0xA5,  0x00,  0x07,  0x7C,  0x54,  0x45,  0x7C,  0x74,  0x45,  0x7C,  0x55, 	/* 16130 */
+	0x07,  0x7E,  0x59,  0x05,  0x7C,  0x51,  0x0B,  0xFE,  0xA6,  0x05,  0x47,  0x54,  0x5A,  0x85,  0x54,  0x75, 	/* 16140 */
+	0x45,  0x00,  0x57,  0xE7,  0x4A,  0x56,  0xA5,  0x5A,  0x56,  0x6B,  0x7E,  0xAB,  0x00,  0xC7,  0x70,  0x51, 	/* 16150 */
+	0x05,  0xFE,  0x75,  0x45,  0x7C,  0x55,  0x47,  0x7C,  0x51,  0x05,  0x7C,  0x51,  0x09,  0xFE,  0xAE,  0x00, 	/* 16160 */
+	0x07,  0x7E,  0x55,  0x25,  0x52,  0x77,  0xE5,  0x52,  0x57,  0xE7,  0x20,  0x53,  0x45,  0x6A,  0x5A,  0x0B, 	/* 16170 */
+	0x1E,  0xB0,  0x00,  0x0F,  0xFE,  0xA2,  0x8A,  0xFE,  0xEA,  0xAA,  0xFE,  0xA2,  0x0F,  0xFE,  0xA4,  0x8A, 	/* 16180 */
+	0xC8,  0xA3,  0x0A,  0xCC,  0xB1,  0x00,  0x87,  0x3E,  0x5C,  0xA5,  0x7F,  0x74,  0xA5,  0xBE,  0x5C,  0x87, 	/* 16190 */
+	0x7E,  0x5C,  0x85,  0x7E,  0x5A,  0x8B,  0x1F,  0xB4,  0x03,  0x07,  0x56,  0x55,  0x25,  0x52,  0x77,  0x65, 	/* 161A0 */
+	0x52,  0x55,  0x27,  0x76,  0x51,  0x05,  0x28,  0x54,  0x4B,  0x82,  0xB8,  0x00,  0x07,  0x7C,  0x54,  0x45, 	/* 161B0 */
+	0x7C,  0x74,  0x45,  0xFF,  0x54,  0x07,  0xFE,  0x52,  0xA5,  0xD2,  0x92,  0x2B,  0x4C,  0xB9,  0x04,  0x07, 	/* 161C0 */
+	0x7E,  0x5C,  0x45,  0x7C,  0x74,  0x45,  0x7C,  0x52,  0x07,  0x3C,  0x54,  0x85,  0xB0,  0x52,  0x8B,  0xC6, 	/* 161D0 */
+	0xBA,  0x01,  0x07,  0x7C,  0x54,  0x45,  0x7C,  0x74,  0x45,  0x7C,  0x51,  0x27,  0xDC,  0x53,  0x85,  0x54, 	/* 161E0 */
+	0x59,  0x29,  0x30,  0xBF,  0xE3,  0xCB,  0x24,  0xAB,  0xCA,  0x24,  0xE3,  0xCB,  0xA2,  0xAB,  0x4E,  0xA8, 	/* 161F0 */
+	0xAA,  0x8A,  0xF6,  0xB4,  0x0B,  0x3E,  0x80,  0x01,  0x07,  0xFE,  0x54,  0x45,  0x28,  0x7F,  0xE5,  0x92, 	/* 16200 */
+	0x5F,  0xE7,  0x20,  0x53,  0xC5,  0x24,  0x54,  0x4B,  0x98,  0x82,  0x22,  0x0F,  0xBE,  0x25,  0x23,  0xAC, 	/* 16210 */
+	0x2E,  0x84,  0xA4,  0xB2,  0x23,  0xF8,  0x20,  0x83,  0xF8,  0x20,  0x84,  0x18,  0x83,  0x00,  0x07,  0x7C, 	/* 16220 */
+	0x55,  0x45,  0x54,  0x76,  0xC5,  0x7C,  0x50,  0x07,  0xFE,  0x5A,  0xA5,  0xAA,  0x5A,  0xAB,  0xFF,  0x88, 	/* 16230 */
+	0x0F,  0xE7,  0x00,  0x57,  0xC5,  0x44,  0x77,  0xC5,  0x00,  0x57,  0xE7,  0x5A,  0x56,  0xE5,  0x7E,  0x55, 	/* 16240 */
+	0x2B,  0x56,  0x8A,  0x01,  0x47,  0x7E,  0x51,  0x05,  0x7E,  0x75,  0x25,  0x7E,  0x55,  0x27,  0x04,  0x5F, 	/* 16250 */
+	0xF5,  0x44,  0x52,  0x4B,  0x0C,  0x8F,  0x04,  0x0F,  0xFE,  0x11,  0x01,  0xF0,  0x00,  0x0F,  0xFE,  0x91, 	/* 16260 */
+	0x23,  0xF8,  0x20,  0x83,  0xF8,  0x20,  0x82,  0x18,  0x93,  0x02,  0x07,  0x7E,  0x5C,  0x45,  0x7C,  0x74, 	/* 16270 */
+	0x45,  0x7E,  0x52,  0x07,  0x7E,  0x5A,  0xA5,  0x2A,  0x55,  0x2B,  0x0C,  0x95,  0x00,  0x07,  0x7E,  0x55, 	/* 16280 */
+	0x65,  0x7E,  0x75,  0x25,  0x56,  0x57,  0x67,  0x6A,  0x57,  0xA5,  0x4A,  0x55,  0x6B,  0x7E,  0x9A,  0x07, 	/* 16290 */
+	0x80,  0x40,  0x3F,  0xE2,  0x48,  0x3F,  0xE3,  0x22,  0x3F,  0xE2,  0x84,  0x2F,  0xC4,  0x84,  0x4F,  0xC8, 	/* 162A0 */
+	0x84,  0x9C,  0x02,  0x87,  0xFE,  0x52,  0x85,  0x7C,  0x74,  0x45,  0x7C,  0x54,  0x47,  0x7C,  0x51,  0x05, 	/* 162B0 */
+	0xFE,  0x52,  0x8B,  0x46,  0x9D,  0x71,  0x05,  0xFE,  0x53,  0x85,  0x54,  0x79,  0x25,  0x28,  0x5C,  0x67, 	/* 162C0 */
+	0x10,  0x5D,  0x65,  0x38,  0x55,  0x4B,  0xB2,  0xA0,  0x00,  0x07,  0xFE,  0x55,  0xA5,  0xB6,  0x7D,  0xA5, 	/* 162D0 */
+	0x36,  0x52,  0x87,  0x4C,  0x59,  0x35,  0x64,  0x51,  0x8B,  0x60,  0xA3,  0x01,  0x07,  0xFE,  0x5A,  0xA5, 	/* 162E0 */
+	0x4E,  0x78,  0x05,  0x7E,  0x52,  0xC7,  0xFA,  0x51,  0x05,  0x7C,  0x51,  0x0B,  0xFE,  0xA4,  0x07,  0xC7, 	/* 162F0 */
+	0x10,  0x5F,  0xE5,  0x92,  0x7B,  0xA5,  0x92,  0x50,  0x07,  0x7C,  0x50,  0x45,  0xFE,  0x50,  0x4B,  0x7C, 	/* 16300 */
+	0xA8,  0x04,  0x4E,  0xE4,  0xA4,  0x8B,  0xF2,  0xE0,  0x2A,  0xE4,  0xAA,  0x8E,  0xE2,  0xB1,  0x2A,  0xA4, 	/* 16310 */
+	0xAE,  0x8B,  0x10,  0xA9,  0x00,  0x87,  0x0A,  0x5F,  0xE5,  0x08,  0x7F,  0x85,  0x08,  0x57,  0x87,  0x58, 	/* 16320 */
+	0x57,  0x45,  0x54,  0x57,  0x2B,  0x89,  0xB0,  0x00,  0xC7,  0x72,  0x55,  0x45,  0xFE,  0x73,  0x85,  0x54, 	/* 16330 */
+	0x59,  0x27,  0x7F,  0x55,  0x25,  0x7E,  0x55,  0x2B,  0x7E,  0xB3,  0x02,  0x87,  0xFE,  0x51,  0x05,  0x7C, 	/* 16340 */
+	0x71,  0x05,  0xFE,  0x55,  0x47,  0xFE,  0x50,  0x05,  0x7C,  0x94,  0x4B,  0x7C,  0xB5,  0x04,  0x47,  0xFE, 	/* 16350 */
+	0x54,  0x45,  0x10,  0x77,  0xE5,  0x24,  0x55,  0xA7,  0x10,  0x5F,  0xF5,  0x10,  0x51,  0x0B,  0x10,  0xB8, 	/* 16360 */
+	0x00,  0x87,  0xBE,  0x55,  0x05,  0x1E,  0x7A,  0x45,  0x5F,  0x5D,  0x27,  0x5E,  0x55,  0x25,  0x56,  0x5B, 	/* 16370 */
+	0x0B,  0x0F,  0xBA,  0x02,  0x07,  0xFE,  0x52,  0x85,  0x7E,  0x7C,  0x85,  0x7E,  0x54,  0x85,  0xFE,  0x48, 	/* 16380 */
+	0x44,  0xFC,  0x88,  0x40,  0x8C,  0xBD,  0x03,  0xC7,  0x48,  0x5F,  0xE5,  0x58,  0x76,  0xE5,  0x5C,  0x54, 	/* 16390 */
+	0x07,  0x7E,  0x54,  0x05,  0xBC,  0x52,  0x4B,  0x3C,  0xBE,  0x01,  0x07,  0x28,  0x57,  0xC5,  0x83,  0x7F, 	/* 163A0 */
+	0xE5,  0xBA,  0x59,  0x27,  0xFE,  0x54,  0x45,  0x7C,  0x54,  0x4B,  0x7C,  0xBF,  0x02,  0x8E,  0xFE,  0xAA, 	/* 163B0 */
+	0xAA,  0xFE,  0xEA,  0xAA,  0xFE,  0xA8,  0x0E,  0xFE,  0xAB,  0x2A,  0xAC,  0xB3,  0x4A,  0xE2,  0x80,  0x7D, 	/* 163C0 */
+	0xC4,  0x55,  0x7F,  0x75,  0x7C,  0x7D,  0x49,  0x48,  0x23,  0x63,  0xFC,  0x20,  0x43,  0xFC,  0x20,  0x42, 	/* 163D0 */
+	0x0C,  0x82,  0x7C,  0x84,  0x7E,  0x7D,  0x44,  0x3E,  0x7C,  0x8A,  0x7E,  0x3C,  0x83,  0xFC,  0x20,  0x43, 	/* 163E0 */
+	0xFC,  0x20,  0x42,  0x0C,  0x86,  0x01,  0x0E,  0xFC,  0xA4,  0x8B,  0xFE,  0xE8,  0x4A,  0xFC,  0xA8,  0x4E, 	/* 163F0 */
+	0xFC,  0xA5,  0x0A,  0xD4,  0xB4,  0xAA,  0x3A,  0x88,  0x02,  0x87,  0xFE,  0x52,  0x85,  0x7C,  0x74,  0x45, 	/* 16400 */
+	0x7C,  0x54,  0x47,  0x7E,  0x55,  0x25,  0xEA,  0x57,  0xAB,  0x0C,  0x89,  0x01,  0x07,  0x10,  0x52,  0x85, 	/* 16410 */
+	0x7C,  0x78,  0x25,  0xEF,  0x5A,  0xA7,  0xEE,  0x54,  0x45,  0x44,  0x5A,  0xAB,  0x12,  0x8D,  0x01,  0x07, 	/* 16420 */
+	0xFE,  0x52,  0x85,  0xD6,  0x75,  0x45,  0x52,  0x5B,  0x47,  0x44,  0x57,  0xC5,  0x44,  0x57,  0xCB,  0x84, 	/* 16430 */
+	0x91,  0x07,  0xC7,  0x10,  0x5F,  0xE5,  0x92,  0x7B,  0xA5,  0x00,  0x5F,  0xE7,  0x20,  0x5F,  0xE5,  0xAA, 	/* 16440 */
+	0x5A,  0xAB,  0x86,  0x93,  0x02,  0x47,  0xFF,  0x52,  0x45,  0x04,  0x77,  0xF5,  0x74,  0x54,  0x57,  0x76, 	/* 16450 */
+	0x55,  0x45,  0xF6,  0x5C,  0xBB,  0x71,  0x98,  0x02,  0xA7,  0x54,  0x52,  0xA5,  0x7E,  0x76,  0xA5,  0x52, 	/* 16460 */
+	0x56,  0xA7,  0x7E,  0x55,  0xA5,  0x76,  0x55,  0xAB,  0x91,  0x99,  0x04,  0x87,  0xFE,  0x54,  0x85,  0x30, 	/* 16470 */
+	0x74,  0x85,  0x7A,  0x5E,  0xC7,  0x58,  0x58,  0x65,  0x54,  0x56,  0xAB,  0xAA,  0x9A,  0x01,  0xC7,  0x10, 	/* 16480 */
+	0x57,  0xE5,  0x50,  0x75,  0xE5,  0x7E,  0x56,  0xA7,  0x7E,  0x56,  0xA5,  0xBE,  0x5A,  0xAB,  0x7F,  0x9F, 	/* 16490 */
+	0x04,  0x87,  0xFE,  0x54,  0x85,  0x04,  0x77,  0xE5,  0x44,  0x5F,  0xC7,  0x56,  0x5F,  0x65,  0x74,  0x5D, 	/* 164A0 */
+	0xAB,  0x71,  0xA0,  0x44,  0x8A,  0xF4,  0x50,  0xAF,  0xFE,  0x6B,  0xCA,  0xEA,  0x7F,  0xC4,  0x44,  0x5B, 	/* 164B0 */
+	0x44,  0x44,  0x5B,  0x44,  0x0C,  0xA3,  0x00,  0x07,  0xFE,  0x44,  0x04,  0x40,  0x7F,  0xC4,  0x04,  0x40, 	/* 164C0 */
+	0x47,  0xFC,  0x44,  0x04,  0x40,  0x44,  0x07,  0xFE,  0xA5,  0x00,  0x8F,  0xC8,  0x90,  0x89,  0x08,  0xFC, 	/* 164D0 */
+	0x88,  0x48,  0xFC,  0x89,  0x14,  0x91,  0x49,  0x14,  0xFE,  0x20,  0x41,  0xA7,  0x00,  0xC0,  0x0A,  0xBF, 	/* 164E0 */
+	0xEA,  0x08,  0xEF,  0xA2,  0xAA,  0xEF,  0xAA,  0x94,  0xAF,  0x42,  0xAA,  0x4F,  0x38,  0x21,  0xA8,  0x04, 	/* 164F0 */
+	0x0F,  0x40,  0xA7,  0xEA,  0x80,  0xF7,  0xC9,  0x44,  0x97,  0xCF,  0x00,  0xAE,  0xEA,  0xAA,  0xFA,  0xA0, 	/* 16500 */
+	0xEE,  0xAA,  0x04,  0x00,  0x80,  0x3F,  0x82,  0x08,  0x20,  0x83,  0xF8,  0x20,  0x82,  0x08,  0x3F,  0x82, 	/* 16510 */
+	0x08,  0x20,  0x83,  0xF8,  0xAD,  0x08,  0x03,  0xF8,  0x20,  0x83,  0xF8,  0x20,  0x83,  0xF8,  0x20,  0x83, 	/* 16520 */
+	0xF8,  0x04,  0x07,  0xFE,  0x19,  0x86,  0x06,  0xB3,  0x00,  0x0F,  0xFE,  0x04,  0x00,  0x90,  0x13,  0x87, 	/* 16530 */
+	0xC4,  0x04,  0x47,  0xFC,  0x04,  0x00,  0x40,  0x04,  0x0F,  0xFE,  0xB4,  0x02,  0x0F,  0xA0,  0x23,  0xE4, 	/* 16540 */
+	0xA4,  0xFC,  0x42,  0xA4,  0x22,  0x8F,  0x98,  0x21,  0x02,  0x28,  0x34,  0x4C,  0x82,  0xBA,  0x04,  0x07, 	/* 16550 */
+	0xFC,  0x04,  0x07,  0xFC,  0x20,  0x8F,  0xFE,  0x80,  0x27,  0xFC,  0x13,  0x03,  0xE8,  0x04,  0x0F,  0xFE, 	/* 16560 */
+	0xBB,  0x01,  0x0F,  0xFE,  0x21,  0x05,  0x7C,  0xFA,  0x82,  0x7E,  0x22,  0x4F,  0xFA,  0x29,  0x12,  0x7E, 	/* 16570 */
+	0x33,  0x4C,  0x52,  0xBC,  0x04,  0x00,  0x80,  0x33,  0xC2,  0x04,  0x20,  0x42,  0x04,  0x3B,  0xC2,  0x04, 	/* 16580 */
+	0x20,  0x42,  0x04,  0x3F,  0xC0,  0x00,  0xBE,  0x14,  0x06,  0x5C,  0x44,  0x44,  0x44,  0x75,  0xC4,  0x44, 	/* 16590 */
+	0x44,  0x47,  0x5C,  0x04,  0x00,  0xA0,  0x31,  0x8C,  0x06,  0x81,  0x0C,  0x03,  0x1C,  0x20,  0x43,  0xDC, 	/* 165A0 */
+	0x20,  0x42,  0x04,  0x3F,  0xC0,  0x90,  0xFF,  0xF0,  0x90,  0x11,  0x02,  0x10,  0x82,  0x04,  0x03,  0xF8, 	/* 165B0 */
+	0x04,  0x07,  0xFC,  0x0A,  0x07,  0xFE,  0x24,  0x85,  0xB4,  0x91,  0x21,  0xB0,  0x11,  0x01,  0xF0,  0x85, 	/* 165C0 */
+	0x08,  0x07,  0x3C,  0x40,  0x47,  0xFC,  0x24,  0x83,  0xF8,  0x24,  0x83,  0xF8,  0x04,  0x0F,  0xFE,  0x18, 	/* 165D0 */
+	0x26,  0x0C,  0x87,  0x18,  0x06,  0xEC,  0x48,  0x46,  0x9C,  0x4E,  0x47,  0x2C,  0x4A,  0x44,  0xA4,  0xFF, 	/* 165E0 */
+	0xE1,  0x10,  0x20,  0xCC,  0x02,  0x88,  0x10,  0x06,  0xFC,  0x4A,  0x47,  0xFC,  0x4A,  0x44,  0xE4,  0x7B, 	/* 165F0 */
+	0xC4,  0xE4,  0xFF,  0xE0,  0x90,  0x10,  0x86,  0x04,  0x89,  0x18,  0x06,  0xEC,  0x48,  0x46,  0xEC,  0x4A, 	/* 16600 */
+	0x4F,  0xFE,  0x15,  0x02,  0x48,  0xDF,  0x60,  0x40,  0x3F,  0x80,  0x40,  0x8A,  0x11,  0x0F,  0xFE,  0x11, 	/* 16610 */
+	0x03,  0xFE,  0x62,  0x0B,  0xFC,  0x22,  0x03,  0xFE,  0x0C,  0x03,  0x1C,  0x20,  0x43,  0xFC,  0x8C,  0x01, 	/* 16620 */
+	0x87,  0xE0,  0x04,  0x00,  0x40,  0xFF,  0xE0,  0x40,  0x04,  0x03,  0xF8,  0x20,  0x82,  0x08,  0x20,  0x83, 	/* 16630 */
+	0xF8,  0x8D,  0x04,  0x00,  0xA0,  0x11,  0x03,  0xF8,  0xC4,  0x60,  0x40,  0x7F,  0xC0,  0x40,  0x3F,  0x82, 	/* 16640 */
+	0x08,  0x20,  0x83,  0xF8,  0x8E,  0x04,  0x00,  0xA0,  0x31,  0x8C,  0x46,  0x3F,  0x80,  0x40,  0x7F,  0xC0, 	/* 16650 */
+	0x00,  0x3F,  0x82,  0x08,  0x20,  0x83,  0xF8,  0x90,  0x18,  0x6E,  0x38,  0x22,  0x82,  0x28,  0xFE,  0x82, 	/* 16660 */
+	0x3E,  0x22,  0x87,  0xA8,  0x4A,  0x44,  0xA6,  0x7B,  0x20,  0x62,  0x92,  0x10,  0x01,  0x3E,  0x29,  0x44, 	/* 16670 */
+	0x48,  0xBB,  0xF1,  0x0A,  0x7C,  0xC1,  0x08,  0x78,  0x84,  0x88,  0x48,  0x87,  0x98,  0x96,  0x20,  0xC3, 	/* 16680 */
+	0x0A,  0x4B,  0xEF,  0x88,  0x23,  0xE2,  0x2A,  0xFF,  0xE2,  0x2A,  0x7B,  0xE4,  0xAA,  0x4A,  0xA7,  0xA6, 	/* 16690 */
+	0x97,  0x21,  0x43,  0x12,  0x7F,  0xEA,  0x90,  0xFF,  0xE2,  0x52,  0xFF,  0xE0,  0x52,  0x77,  0xE5,  0x52, 	/* 166A0 */
+	0x55,  0x27,  0x56,  0x98,  0x21,  0x02,  0xFE,  0x58,  0x28,  0xBC,  0xFA,  0x42,  0x24,  0xFB,  0xC2,  0x20, 	/* 166B0 */
+	0x7B,  0xE4,  0xA2,  0x4A,  0x27,  0xBE,  0x9B,  0x20,  0x82,  0x08,  0x38,  0x82,  0xBE,  0x4A,  0x87,  0xA8, 	/* 166C0 */
+	0x8A,  0x81,  0x7E,  0x10,  0x82,  0x08,  0x40,  0x88,  0x08,  0x9C,  0x03,  0xC7,  0xC8,  0x28,  0x81,  0x50, 	/* 166D0 */
+	0xFF,  0xE8,  0x0A,  0x3B,  0xE4,  0xA8,  0xAA,  0x81,  0xFE,  0x20,  0x8C,  0x08,  0x9E,  0x20,  0x03,  0xFC, 	/* 166E0 */
+	0x6A,  0x8B,  0xFE,  0x2A,  0x8F,  0xFE,  0x20,  0x83,  0xBE,  0x4A,  0x8B,  0x7E,  0x20,  0x8C,  0x08,  0x9F, 	/* 166F0 */
+	0x04,  0x01,  0xF8,  0x10,  0x81,  0x48,  0x12,  0x8F,  0xFE,  0x10,  0x81,  0x48,  0x22,  0x82,  0x28,  0x40, 	/* 16700 */
+	0x88,  0x18,  0xA9,  0x21,  0xC7,  0x84,  0x49,  0x46,  0x94,  0x5A,  0x24,  0xAA,  0xFC,  0x94,  0x88,  0x69, 	/* 16710 */
+	0x45,  0x94,  0x4B,  0xA9,  0xE2,  0xAA,  0x11,  0x02,  0x10,  0x7F,  0xE5,  0x00,  0x73,  0x85,  0x28,  0xFE, 	/* 16720 */
+	0x85,  0x28,  0x74,  0x85,  0x4A,  0x58,  0xAB,  0x06,  0xAB,  0x20,  0x87,  0x88,  0x4F,  0xE6,  0x90,  0x59, 	/* 16730 */
+	0x04,  0x9E,  0xFD,  0x24,  0x92,  0x6A,  0x25,  0xA2,  0x4C,  0x29,  0x8C,  0xAC,  0x23,  0x87,  0xA8,  0x4A, 	/* 16740 */
+	0x86,  0xAA,  0x5C,  0xE4,  0x80,  0xFF,  0xC4,  0x84,  0x6A,  0x85,  0x90,  0x4A,  0x89,  0xC6,  0xAE,  0x20, 	/* 16750 */
+	0x07,  0xBE,  0x48,  0x06,  0xBE,  0x5A,  0x24,  0xA2,  0xFF,  0xE4,  0xA0,  0x6A,  0x05,  0xC0,  0x4C,  0x09, 	/* 16760 */
+	0x80,  0xB3,  0x20,  0x87,  0x88,  0x48,  0x86,  0xBE,  0x5A,  0xA4,  0xAA,  0xFE,  0xA4,  0xBE,  0x6A,  0xA5, 	/* 16770 */
+	0xAA,  0x4A,  0xA9,  0xBE,  0xB5,  0x20,  0x87,  0x88,  0x4F,  0xE6,  0xC2,  0x5C,  0x24,  0xA0,  0xFE,  0xC4, 	/* 16780 */
+	0xB0,  0x6A,  0x05,  0xA2,  0x4A,  0x29,  0x9E,  0xB6,  0x20,  0x87,  0x90,  0x4B,  0xE6,  0xA2,  0x5A,  0x24, 	/* 16790 */
+	0xA2,  0xFB,  0xE4,  0xA2,  0x6A,  0x25,  0xA2,  0x4A,  0x29,  0xBE,  0xB7,  0x20,  0x87,  0x88,  0x4F,  0xE6, 	/* 167A0 */
+	0x90,  0x59,  0x44,  0xE4,  0xFA,  0x84,  0x90,  0x69,  0x45,  0xA4,  0x4F,  0xA9,  0x82,  0xB8,  0x20,  0x07, 	/* 167B0 */
+	0xFE,  0x48,  0x46,  0x84,  0x5B,  0xC4,  0xAC,  0xFE,  0xC4,  0xAC,  0x6B,  0xC5,  0x84,  0x48,  0x49,  0x8C, 	/* 167C0 */
+	0xB9,  0x22,  0x87,  0xA8,  0x4A,  0x86,  0xA4,  0x5C,  0x24,  0x80,  0xFF,  0xC4,  0xA4,  0x6A,  0x45,  0xA4, 	/* 167D0 */
+	0x4A,  0x49,  0xBC,  0x80,  0x20,  0x67,  0xBC,  0x4A,  0xA6,  0xCA,  0x5B,  0xC4,  0x84,  0xFC,  0x84,  0xBE, 	/* 167E0 */
+	0x68,  0x85,  0x88,  0x48,  0x89,  0x98,  0x87,  0x20,  0x22,  0xFC,  0x72,  0x85,  0x28,  0x74,  0x85,  0xFE, 	/* 167F0 */
+	0xF2,  0x85,  0xA8,  0x7A,  0x85,  0x5E,  0x56,  0x0B,  0x9F,  0x98,  0x21,  0x87,  0xAE,  0x4A,  0xA6,  0xBE, 	/* 16800 */
+	0x5A,  0xA4,  0xBE,  0xF8,  0x84,  0xFE,  0x6A,  0x45,  0x98,  0x49,  0x49,  0xE2,  0x99,  0x20,  0x87,  0x94, 	/* 16810 */
+	0x4A,  0xA6,  0xFF,  0x5A,  0x24,  0xBE,  0xFE,  0x24,  0xBE,  0x6A,  0x05,  0xDE,  0x4D,  0x29,  0x9E,  0x9A, 	/* 16820 */
+	0x22,  0x87,  0xFE,  0x4A,  0x86,  0xFE,  0x5A,  0xA4,  0xFE,  0xFA,  0xA4,  0xFE,  0x6A,  0x45,  0xBC,  0x4A, 	/* 16830 */
+	0x49,  0xBC,  0x9D,  0x27,  0xE7,  0x90,  0x4F,  0xE6,  0x92,  0x5D,  0xA4,  0xB6,  0xF8,  0x04,  0xBE,  0x68, 	/* 16840 */
+	0x25,  0xFF,  0x48,  0x29,  0xBE,  0x9F,  0x21,  0x07,  0xFC,  0x4A,  0x86,  0xFE,  0x5D,  0x44,  0xFC,  0xFD, 	/* 16850 */
+	0x44,  0xFC,  0x69,  0x05,  0xFC,  0x49,  0x09,  0xFE,  0xA2,  0x21,  0x07,  0xFE,  0x4B,  0x46,  0xB4,  0x5D, 	/* 16860 */
+	0xA4,  0xFE,  0xF9,  0x04,  0xFE,  0x6D,  0xA5,  0xDA,  0x4C,  0x29,  0xFE,  0xA4,  0x22,  0x87,  0xFE,  0x49, 	/* 16870 */
+	0x06,  0xFC,  0x59,  0x04,  0xFE,  0xFA,  0xA4,  0xFE,  0x6A,  0xC5,  0xAA,  0x4F,  0x69,  0xA2,  0xA6,  0x4E, 	/* 16880 */
+	0x8E,  0x8E,  0xAE,  0x8E,  0xB0,  0xAE,  0x0F,  0x8E,  0xAE,  0x0E,  0x00,  0xAF,  0xCA,  0x54,  0xA5,  0x4A, 	/* 16890 */
+	0xFE,  0xA8,  0x22,  0x47,  0xFE,  0x4A,  0x46,  0xFE,  0x5C,  0x24,  0xBE,  0xFE,  0xA4,  0x9A,  0x6E,  0xC5, 	/* 168A0 */
+	0x9A,  0x4E,  0x99,  0x90,  0xAA,  0x21,  0xC7,  0xA8,  0x4F,  0xE6,  0xAA,  0x5B,  0xE4,  0xAA,  0xFB,  0xE4, 	/* 168B0 */
+	0xAA,  0x6D,  0x55,  0xBE,  0x4A,  0x29,  0xBE,  0xAB,  0x41,  0xCF,  0x10,  0x97,  0xED,  0x56,  0xB7,  0x89, 	/* 168C0 */
+	0x5E,  0xFF,  0xE9,  0x6A,  0xD7,  0xEB,  0x6A,  0x9A,  0xAB,  0x7F,  0xAE,  0x00,  0x03,  0xF0,  0x21,  0x03, 	/* 168D0 */
+	0xF0,  0x21,  0x02,  0x10,  0x3F,  0x02,  0x88,  0x25,  0x02,  0x20,  0x39,  0x0E,  0x0C,  0xAF,  0x08,  0x03, 	/* 168E0 */
+	0xF0,  0x21,  0x02,  0x10,  0x3F,  0x02,  0x10,  0x3F,  0x02,  0x08,  0x29,  0x02,  0x60,  0x39,  0x0E,  0x0C, 	/* 168F0 */
+	0xB1,  0x50,  0x0F,  0xBC,  0x52,  0x4F,  0xBC,  0xAA,  0x4F,  0xBC,  0x23,  0x2F,  0xAC,  0x22,  0x8F,  0xA4, 	/* 16900 */
+	0x53,  0xA8,  0x61,  0xB2,  0x10,  0x01,  0xF0,  0x22,  0x0C,  0x40,  0x7F,  0x84,  0x88,  0x48,  0x87,  0xF8, 	/* 16910 */
+	0x40,  0x04,  0x04,  0x40,  0x43,  0xFC,  0xB6,  0x28,  0x8F,  0xEE,  0xAB,  0x4F,  0xFE,  0xAA,  0xAF,  0xEA, 	/* 16920 */
+	0x7B,  0xE4,  0xA0,  0x7A,  0x05,  0x22,  0x3E,  0x2E,  0x1E,  0xB7,  0xA8,  0x8F,  0x9E,  0xAA,  0x4F,  0xC8, 	/* 16930 */
+	0x03,  0xEF,  0xEA,  0x7A,  0xA4,  0xBE,  0x7A,  0x04,  0xA2,  0x2E,  0x2F,  0x1E,  0xB8,  0x20,  0x82,  0x08, 	/* 16940 */
+	0x20,  0x8A,  0xAA,  0xAA,  0xAA,  0xAA,  0xAA,  0xAF,  0xBE,  0x20,  0x82,  0x08,  0x40,  0x88,  0x08,  0xBE, 	/* 16950 */
+	0x11,  0x0F,  0xFE,  0x11,  0x00,  0x00,  0x21,  0x02,  0x10,  0x12,  0x00,  0xA0,  0x04,  0x00,  0xA0,  0x31, 	/* 16960 */
+	0x8C,  0x06,  0x8B,  0x11,  0x0F,  0xFE,  0x11,  0x03,  0xF8,  0x04,  0x00,  0x40,  0xFF,  0xE0,  0x40,  0x04, 	/* 16970 */
+	0x00,  0x40,  0x04,  0x00,  0xC0,  0x8D,  0x11,  0x0F,  0xFE,  0x11,  0x01,  0x00,  0x3F,  0xC2,  0x04,  0x48, 	/* 16980 */
+	0x48,  0x44,  0x04,  0x40,  0x04,  0x00,  0x40,  0x18,  0x92,  0x11,  0x0F,  0xFE,  0x11,  0x01,  0x50,  0x04, 	/* 16990 */
+	0x0F,  0xFE,  0x20,  0x02,  0x00,  0x20,  0x02,  0x00,  0x20,  0x01,  0xFC,  0x99,  0x11,  0x0F,  0xFE,  0x11, 	/* 169A0 */
+	0x01,  0x50,  0x04,  0x07,  0xFC,  0x04,  0x00,  0x40,  0xFF,  0xE0,  0xA0,  0x31,  0x8C,  0x06,  0x9D,  0x11, 	/* 169B0 */
+	0x0F,  0xFE,  0x11,  0x01,  0x50,  0x04,  0x07,  0xFC,  0x00,  0x80,  0x30,  0x2C,  0x03,  0x00,  0x4C,  0x08, 	/* 169C0 */
+	0x3E,  0x9F,  0x11,  0x0F,  0xFE,  0x11,  0x01,  0xF0,  0x11,  0x41,  0x14,  0x20,  0xC7,  0xF0,  0x11,  0x00, 	/* 169D0 */
+	0xE0,  0x1B,  0x0E,  0x0E,  0xA5,  0x10,  0x8F,  0xFE,  0x11,  0x01,  0x50,  0x0A,  0x01,  0x10,  0x29,  0x8C, 	/* 169E0 */
+	0x96,  0x09,  0x01,  0x10,  0x11,  0x02,  0x10,  0xA6,  0x11,  0x0F,  0xFE,  0x11,  0x07,  0xFC,  0x00,  0x03, 	/* 169F0 */
+	0xFC,  0x20,  0x43,  0xFC,  0x20,  0x04,  0x00,  0x40,  0x08,  0x00,  0xAB,  0x11,  0x0F,  0xFE,  0x11,  0x00, 	/* 16A00 */
+	0x00,  0x7F,  0xC0,  0x00,  0xFF,  0xE1,  0x20,  0x12,  0x01,  0x22,  0x22,  0x2C,  0x1E,  0xAC,  0x11,  0x0F, 	/* 16A10 */
+	0xFE,  0x11,  0x00,  0x00,  0x09,  0x01,  0x08,  0x20,  0x4F,  0xFA,  0x08,  0x80,  0x88,  0x10,  0x86,  0x30, 	/* 16A20 */
+	0xAD,  0x11,  0x0F,  0xFE,  0x11,  0x00,  0x00,  0x7F,  0xC4,  0x44,  0x44,  0x47,  0xFC,  0x40,  0x04,  0x02, 	/* 16A30 */
+	0x40,  0x23,  0xFE,  0xAF,  0x11,  0x0F,  0xFE,  0x11,  0x01,  0x10,  0x00,  0x01,  0x40,  0x52,  0x85,  0x24, 	/* 16A40 */
+	0x50,  0x29,  0x0A,  0x90,  0x80,  0xF8,  0xB1,  0x11,  0x01,  0x10,  0xFF,  0xE1,  0x90,  0x0A,  0x01,  0x22, 	/* 16A50 */
+	0x32,  0xC5,  0x30,  0x92,  0x01,  0x22,  0x12,  0x21,  0x1E,  0xB3,  0x11,  0x0F,  0xFE,  0x11,  0x00,  0x40, 	/* 16A60 */
+	0xFF,  0xE0,  0x80,  0x08,  0x00,  0xF8,  0x08,  0x81,  0x08,  0x20,  0x8C,  0x30,  0xB8,  0x11,  0x0F,  0xFE, 	/* 16A70 */
+	0x11,  0x01,  0x10,  0x7F,  0xC0,  0x00,  0xFF,  0xE0,  0x40,  0x09,  0x01,  0x38,  0x7C,  0x40,  0x04,  0xB9, 	/* 16A80 */
+	0x11,  0x0F,  0xFE,  0x11,  0x00,  0x1C,  0x3E,  0x02,  0x00,  0x3F,  0xE2,  0x20,  0x22,  0x04,  0x20,  0x42, 	/* 16A90 */
+	0x08,  0x20,  0xBB,  0x20,  0x03,  0xFE,  0x24,  0x26,  0x4A,  0xBF,  0xA2,  0x42,  0x3F,  0xE4,  0x42,  0xA4, 	/* 16AA0 */
+	0xA3,  0xFA,  0x08,  0x23,  0x0C,  0xBD,  0x11,  0x0F,  0xFE,  0x11,  0x07,  0xFE,  0x21,  0x02,  0x10,  0xFF, 	/* 16AB0 */
+	0xE0,  0x50,  0x09,  0x03,  0x10,  0xC1,  0x00,  0x30,  0x85,  0x11,  0x0F,  0xFE,  0x11,  0x00,  0x84,  0x0A, 	/* 16AC0 */
+	0x4C,  0xA4,  0x2A,  0x41,  0x24,  0x12,  0x42,  0xA4,  0x48,  0x48,  0x0C,  0x91,  0x11,  0x0F,  0xFE,  0x11, 	/* 16AD0 */
+	0x02,  0x00,  0x3B,  0xC2,  0xA4,  0x4A,  0x46,  0xA4,  0x9B,  0x81,  0x22,  0x22,  0x24,  0x1E,  0x92,  0x11, 	/* 16AE0 */
+	0x0F,  0xFE,  0x11,  0x00,  0x40,  0x3F,  0x82,  0x48,  0x3F,  0x82,  0x48,  0xFF,  0xE2,  0x08,  0x20,  0x82, 	/* 16AF0 */
+	0x18,  0x93,  0x11,  0x0F,  0xFE,  0x15,  0x00,  0xA0,  0x31,  0x8D,  0xF6,  0x00,  0x07,  0xFC,  0x04,  0x40, 	/* 16B00 */
+	0x44,  0x05,  0x80,  0x40,  0x94,  0x11,  0x0F,  0xFE,  0x11,  0x00,  0x40,  0x08,  0x81,  0x34,  0xFC,  0x20, 	/* 16B10 */
+	0x02,  0x3F,  0x82,  0x08,  0x20,  0x83,  0xF8,  0x97,  0x11,  0x0F,  0xFE,  0x11,  0x01,  0x10,  0x7F,  0xC4, 	/* 16B20 */
+	0x44,  0x44,  0x47,  0xFC,  0x44,  0x44,  0x44,  0x44,  0x47,  0xFC,  0x99,  0x11,  0x0F,  0xFE,  0x11,  0x01, 	/* 16B30 */
+	0x50,  0x04,  0x07,  0xFC,  0x00,  0x82,  0x08,  0x11,  0x00,  0x90,  0x0A,  0x0F,  0xFE,  0x9B,  0x11,  0x0F, 	/* 16B40 */
+	0xFE,  0x11,  0x00,  0x00,  0xFF,  0xE0,  0x08,  0x3E,  0x82,  0x28,  0x22,  0x83,  0xE8,  0x00,  0x80,  0x18, 	/* 16B50 */
+	0x9C,  0x11,  0x0F,  0xFE,  0x11,  0x03,  0xF8,  0x20,  0x82,  0x08,  0x3F,  0x82,  0x08,  0x3F,  0x82,  0x08, 	/* 16B60 */
+	0x20,  0x83,  0xF8,  0x9E,  0x11,  0x0F,  0xFE,  0x11,  0x02,  0x00,  0x3F,  0xC4,  0x04,  0x7E,  0x4A,  0x24, 	/* 16B70 */
+	0x3E,  0x82,  0x00,  0x20,  0x21,  0xFE,  0x9F,  0x11,  0x0F,  0xFE,  0x11,  0x01,  0x00,  0x3F,  0xE2,  0x02, 	/* 16B80 */
+	0x5E,  0x29,  0x22,  0x12,  0x21,  0xE2,  0x00,  0x20,  0x0C,  0xA1,  0x11,  0x0F,  0xFE,  0x11,  0x00,  0x00, 	/* 16B90 */
+	0x20,  0x82,  0x88,  0x24,  0x82,  0x48,  0x20,  0x82,  0x98,  0x32,  0x4C,  0xC2,  0xA3,  0x11,  0x0F,  0xFE, 	/* 16BA0 */
+	0x11,  0x00,  0x00,  0x7F,  0xC4,  0x00,  0x7F,  0x84,  0x08,  0x7F,  0x84,  0x00,  0x40,  0x07,  0xFC,  0xA5, 	/* 16BB0 */
+	0x11,  0x0F,  0xFE,  0x11,  0x00,  0x80,  0x08,  0x0F,  0xFE,  0x08,  0x01,  0xF8,  0x30,  0x85,  0x08,  0x90, 	/* 16BC0 */
+	0x81,  0xF8,  0xA6,  0x11,  0x0F,  0xFE,  0x11,  0x01,  0x50,  0x04,  0x0F,  0xFE,  0x04,  0x00,  0x40,  0x3F, 	/* 16BD0 */
+	0x82,  0x08,  0x20,  0x83,  0xF8,  0xA7,  0x11,  0x0F,  0xFE,  0x11,  0x00,  0x40,  0xFF,  0xE8,  0x02,  0xBF, 	/* 16BE0 */
+	0xA0,  0x40,  0x04,  0x00,  0x40,  0x04,  0x00,  0xC0,  0xAB,  0x11,  0x0F,  0xFE,  0x11,  0x01,  0x50,  0x07, 	/* 16BF0 */
+	0xC0,  0x40,  0x04,  0x03,  0xF8,  0x20,  0x82,  0x08,  0x20,  0x83,  0xF8,  0xB1,  0x11,  0x07,  0xFC,  0x15, 	/* 16C00 */
+	0x00,  0x40,  0x3F,  0x82,  0x48,  0x24,  0x8F,  0xFE,  0x04,  0x00,  0xA0,  0x31,  0x8C,  0x06,  0xB3,  0x11, 	/* 16C10 */
+	0x0F,  0xFE,  0x11,  0x00,  0xFC,  0x10,  0x86,  0x90,  0x06,  0x01,  0x98,  0xEC,  0x60,  0x10,  0x06,  0x01, 	/* 16C20 */
+	0x80,  0xB4,  0x11,  0x0F,  0xFE,  0x11,  0x00,  0x00,  0x3F,  0x82,  0x08,  0x3F,  0x82,  0x08,  0x3F,  0x82, 	/* 16C30 */
+	0x08,  0x20,  0x8F,  0xFE,  0xB9,  0x11,  0x0F,  0xFE,  0x11,  0x07,  0xFC,  0x05,  0x02,  0x48,  0x44,  0x4F, 	/* 16C40 */
+	0xFE,  0x04,  0x00,  0x40,  0x04,  0x00,  0x40,  0xBA,  0x11,  0x0F,  0xFE,  0x11,  0x03,  0xF8,  0x24,  0x82, 	/* 16C50 */
+	0x28,  0xFF,  0xE4,  0x88,  0x44,  0x87,  0xFC,  0x00,  0x80,  0x30,  0xBB,  0x11,  0x0F,  0xFE,  0x11,  0x01, 	/* 16C60 */
+	0x08,  0x20,  0x82,  0xFE,  0x60,  0x8A,  0x88,  0x24,  0x82,  0x48,  0x20,  0x82,  0x18,  0x82,  0x11,  0x0F, 	/* 16C70 */
+	0xFE,  0x11,  0x01,  0x58,  0x44,  0x47,  0xFE,  0x42,  0x04,  0x24,  0x41,  0x84,  0x2A,  0x44,  0x69,  0x82, 	/* 16C80 */
+	0x83,  0x11,  0x0F,  0xFE,  0x11,  0x01,  0x10,  0x47,  0xC2,  0x44,  0x84,  0x44,  0x58,  0x14,  0x02,  0x42, 	/* 16C90 */
+	0x24,  0x24,  0x3E,  0x84,  0x11,  0x0F,  0xFE,  0x11,  0x02,  0x10,  0x21,  0xEF,  0xD2,  0x25,  0x22,  0x52, 	/* 16CA0 */
+	0x25,  0x24,  0x52,  0x45,  0xE9,  0x80,  0x85,  0x11,  0x0F,  0xFE,  0x11,  0x07,  0xF8,  0x11,  0x00,  0xA0, 	/* 16CB0 */
+	0xFF,  0xE0,  0xC4,  0x14,  0x82,  0x40,  0xC4,  0x00,  0xC0,  0x86,  0x11,  0x0F,  0xFE,  0x11,  0x01,  0x80, 	/* 16CC0 */
+	0x63,  0xC4,  0x24,  0x4A,  0x44,  0xA4,  0x7A,  0x4C,  0xB8,  0x12,  0x02,  0x20,  0x89,  0x11,  0x0F,  0xFE, 	/* 16CD0 */
+	0x11,  0x01,  0x50,  0x04,  0x0F,  0xFE,  0x04,  0x07,  0xFC,  0x0E,  0x03,  0x58,  0xC4,  0x60,  0x40,  0x8E, 	/* 16CE0 */
+	0x11,  0x0F,  0xFE,  0x11,  0x07,  0xF8,  0x13,  0x00,  0xC0,  0x33,  0x0C,  0x4E,  0x3F,  0x80,  0x40,  0x04, 	/* 16CF0 */
+	0x0F,  0xFE,  0x96,  0x11,  0x0F,  0xFE,  0x11,  0x00,  0x80,  0x1F,  0x87,  0x10,  0x0E,  0x03,  0x18,  0xFF, 	/* 16D00 */
+	0xE2,  0x08,  0x20,  0x83,  0xF8,  0x97,  0x11,  0x0F,  0xFE,  0x11,  0x00,  0x40,  0x0F,  0x81,  0x08,  0x6B, 	/* 16D10 */
+	0x00,  0xC0,  0x3F,  0xCD,  0x04,  0x10,  0x41,  0xFC,  0x98,  0x11,  0x0F,  0xFE,  0x11,  0x03,  0xF8,  0x08, 	/* 16D20 */
+	0x81,  0x08,  0x23,  0x0F,  0xFE,  0x49,  0x24,  0x92,  0x4A,  0x2B,  0x4C,  0x9C,  0x11,  0x0F,  0xFE,  0x11, 	/* 16D30 */
+	0x0F,  0xFE,  0x0A,  0x07,  0xFC,  0x4A,  0x44,  0xA4,  0x51,  0xC6,  0x04,  0x40,  0x47,  0xFC,  0xA3,  0x11, 	/* 16D40 */
+	0x0F,  0xFE,  0x11,  0x00,  0xF8,  0x28,  0x82,  0xF8,  0x20,  0x03,  0xF8,  0x04,  0x8F,  0xFE,  0x19,  0x86, 	/* 16D50 */
+	0x06,  0xA8,  0x11,  0x0F,  0xFE,  0x11,  0x01,  0x50,  0x47,  0xE2,  0x52,  0x29,  0x40,  0x90,  0x11,  0x02, 	/* 16D60 */
+	0x28,  0xCC,  0x43,  0x02,  0xAB,  0x11,  0x0F,  0xFE,  0x11,  0x04,  0x10,  0x27,  0xE8,  0x40,  0x44,  0x00, 	/* 16D70 */
+	0x40,  0x14,  0x02,  0x40,  0x44,  0x04,  0x3C,  0xAF,  0x11,  0x0F,  0xFE,  0x11,  0x01,  0x28,  0x22,  0x43, 	/* 16D80 */
+	0xFE,  0x62,  0x0A,  0x20,  0x25,  0x02,  0x50,  0x28,  0x83,  0x04,  0xB1,  0x11,  0x0F,  0xFE,  0x11,  0x02, 	/* 16D90 */
+	0x40,  0x24,  0x07,  0xFC,  0x84,  0x0F,  0xFE,  0x0E,  0x03,  0x58,  0xC4,  0x60,  0x40,  0xB2,  0x11,  0x0F, 	/* 16DA0 */
+	0xFE,  0x11,  0x01,  0x08,  0x10,  0x86,  0x72,  0x25,  0x21,  0x8C,  0x10,  0x82,  0x94,  0xFF,  0xE0,  0x42, 	/* 16DB0 */
+	0xB4,  0x11,  0x0F,  0xFE,  0x11,  0x07,  0xFC,  0x40,  0x45,  0xF4,  0x51,  0x45,  0x14,  0x51,  0x45,  0xF4, 	/* 16DC0 */
+	0x40,  0x47,  0xFC,  0xB5,  0x11,  0x0F,  0xFE,  0x11,  0x07,  0xFC,  0x44,  0x44,  0x44,  0x7F,  0xC4,  0x44, 	/* 16DD0 */
+	0x4A,  0x45,  0x14,  0x60,  0xC7,  0xFC,  0xB6,  0x11,  0x0F,  0xFE,  0x15,  0x00,  0xA0,  0x31,  0x8C,  0x46, 	/* 16DE0 */
+	0x7F,  0xC0,  0x40,  0x15,  0x02,  0x48,  0xC4,  0x40,  0x40,  0xB8,  0x10,  0x8F,  0xFE,  0x10,  0x87,  0xFE, 	/* 16DF0 */
+	0x10,  0x81,  0xF8,  0x10,  0x81,  0xF8,  0x10,  0xE1,  0xF8,  0xE0,  0x80,  0x08,  0xB9,  0x11,  0x0F,  0xFE, 	/* 16E00 */
+	0x11,  0x05,  0x10,  0x4B,  0xCF,  0xE4,  0x4A,  0x44,  0xA4,  0xF2,  0x42,  0xA4,  0x47,  0xC8,  0x00,  0x80, 	/* 16E10 */
+	0x11,  0x0F,  0xFE,  0x11,  0x01,  0x00,  0x3F,  0xC2,  0x04,  0x5E,  0x49,  0x24,  0x1E,  0x41,  0x24,  0x1E, 	/* 16E20 */
+	0x40,  0x18,  0x85,  0x11,  0x0F,  0xFE,  0x15,  0x00,  0xA0,  0x11,  0x03,  0xF8,  0xC0,  0x63,  0xF8,  0x20, 	/* 16E30 */
+	0x82,  0x08,  0x20,  0x83,  0xF8,  0x89,  0x11,  0x0F,  0xFE,  0x11,  0x03,  0xF8,  0x20,  0x83,  0xF8,  0x20, 	/* 16E40 */
+	0x83,  0xF8,  0x04,  0x0F,  0xFE,  0x04,  0x00,  0x40,  0x8A,  0x12,  0x0F,  0xFE,  0x12,  0x00,  0x04,  0xFE, 	/* 16E50 */
+	0x42,  0xA4,  0x2A,  0x4F,  0xE4,  0x2A,  0x44,  0xA4,  0x48,  0x48,  0x8C,  0x8F,  0x11,  0x0F,  0xFE,  0x11, 	/* 16E60 */
+	0x01,  0x0C,  0x17,  0x02,  0x10,  0x21,  0x07,  0xFE,  0xA1,  0x02,  0x10,  0x2F,  0xC2,  0x00,  0x90,  0x11, 	/* 16E70 */
+	0x0F,  0xFE,  0x11,  0x00,  0x80,  0xFF,  0xE1,  0x00,  0x2F,  0xC6,  0x08,  0xBF,  0xE2,  0x10,  0x21,  0x02, 	/* 16E80 */
+	0x30,  0x92,  0x11,  0x0F,  0xFE,  0x11,  0x00,  0x40,  0xFF,  0xE2,  0x00,  0x1F,  0xC2,  0x48,  0x24,  0x82, 	/* 16E90 */
+	0x4A,  0x44,  0xA8,  0x06,  0x98,  0x11,  0x0F,  0xFE,  0x11,  0x01,  0x10,  0x22,  0x0A,  0x20,  0x7F,  0xE2, 	/* 16EA0 */
+	0x20,  0x62,  0x0A,  0x20,  0x2F,  0xC2,  0x00,  0xB3,  0x11,  0x0F,  0xFE,  0x11,  0x07,  0xFC,  0x00,  0x03, 	/* 16EB0 */
+	0xF8,  0x20,  0x82,  0x08,  0x3F,  0x81,  0x10,  0x0A,  0x0F,  0xFE,  0xB5,  0x11,  0x0F,  0xFE,  0x11,  0x07, 	/* 16EC0 */
+	0xFC,  0x04,  0x43,  0xC4,  0x16,  0x46,  0x18,  0x14,  0x05,  0x24,  0x90,  0xA0,  0xF8,  0xB7,  0x11,  0x0F, 	/* 16ED0 */
+	0xFE,  0x09,  0x02,  0x00,  0x3F,  0xE4,  0x08,  0x5E,  0x8D,  0x28,  0x52,  0x85,  0xE8,  0x40,  0x84,  0x18, 	/* 16EE0 */
+	0xBB,  0x11,  0x0F,  0xFE,  0x11,  0x01,  0x10,  0xA1,  0x44,  0x54,  0xA5,  0x83,  0x50,  0x53,  0x09,  0x28, 	/* 16EF0 */
+	0x14,  0x46,  0x82,  0xBC,  0x11,  0x0F,  0xFF,  0x15,  0x00,  0xA0,  0x31,  0x8D,  0xF6,  0x04,  0x07,  0xFC, 	/* 16F00 */
+	0x05,  0x02,  0x4C,  0xC4,  0x20,  0xC0,  0x85,  0x11,  0x0F,  0xFE,  0x11,  0x02,  0x20,  0x3F,  0xC4,  0x08, 	/* 16F10 */
+	0x48,  0x8C,  0x88,  0x44,  0x84,  0x50,  0x45,  0x05,  0xFE,  0x87,  0x11,  0x0F,  0xFE,  0x11,  0x07,  0x90, 	/* 16F20 */
+	0x4B,  0xE4,  0x92,  0x79,  0x24,  0x92,  0x79,  0x24,  0xE2,  0x72,  0x2C,  0x4C,  0x89,  0x11,  0x0F,  0xFE, 	/* 16F30 */
+	0x11,  0x01,  0x82,  0x71,  0x21,  0x12,  0xFD,  0x23,  0x12,  0x39,  0x25,  0x52,  0x90,  0x21,  0x06,  0x8A, 	/* 16F40 */
+	0x11,  0x0F,  0xFE,  0x11,  0x05,  0x10,  0x51,  0x07,  0x10,  0x1F,  0xEF,  0x10,  0x51,  0x05,  0x10,  0x51, 	/* 16F50 */
+	0x09,  0xFE,  0x8E,  0x11,  0x0F,  0xFE,  0x11,  0x04,  0x10,  0x25,  0x48,  0x54,  0x45,  0x20,  0x96,  0x33, 	/* 16F60 */
+	0x44,  0x08,  0x83,  0x08,  0xC0,  0x93,  0x11,  0x0F,  0xFE,  0x11,  0x02,  0x00,  0x3F,  0xE4,  0x00,  0x9F, 	/* 16F70 */
+	0x81,  0x28,  0xFF,  0xE2,  0x48,  0x7F,  0xC0,  0x30,  0x96,  0x11,  0x0F,  0xFE,  0x11,  0x0F,  0xFE,  0x24, 	/* 16F80 */
+	0x84,  0x90,  0xDB,  0x02,  0x48,  0x7F,  0xC0,  0x40,  0x04,  0x0F,  0xFE,  0x9A,  0x11,  0x0F,  0xFE,  0x11, 	/* 16F90 */
+	0x0F,  0x06,  0x17,  0x82,  0x10,  0x75,  0xC9,  0x50,  0x55,  0x02,  0x7E,  0x58,  0x08,  0x7F,  0x9E,  0x11, 	/* 16FA0 */
+	0x0F,  0xFE,  0x11,  0x00,  0x40,  0xFF,  0xE8,  0x02,  0x3F,  0x80,  0x00,  0xFF,  0xE0,  0xA0,  0x32,  0x2C, 	/* 16FB0 */
+	0x1E,  0x9F,  0x11,  0x0F,  0xFE,  0x15,  0x00,  0xA0,  0x11,  0x03,  0xF8,  0xC2,  0x60,  0x40,  0x3F,  0x82, 	/* 16FC0 */
+	0x08,  0x20,  0x83,  0xF8,  0xA0,  0x11,  0x0F,  0xFE,  0x11,  0x83,  0xF0,  0x04,  0x0F,  0xFE,  0x0E,  0x03, 	/* 16FD0 */
+	0x58,  0xDF,  0x60,  0x9C,  0x10,  0x46,  0x18,  0xA2,  0x11,  0x0F,  0xFE,  0x11,  0x00,  0x40,  0xFF,  0xE2, 	/* 16FE0 */
+	0x48,  0x24,  0x85,  0x54,  0x8A,  0x21,  0x10,  0x20,  0x8C,  0x06,  0xA8,  0x11,  0x0F,  0xFE,  0x15,  0x03, 	/* 16FF0 */
+	0xF8,  0x20,  0x83,  0xF8,  0x20,  0x83,  0xF8,  0x24,  0x42,  0x28,  0x39,  0x86,  0x06,  0xAA,  0x11,  0x0F, 	/* 17000 */
+	0xFE,  0x11,  0x00,  0xD0,  0x71,  0x81,  0x14,  0xFF,  0xE1,  0x14,  0x1C,  0x8F,  0x1A,  0x16,  0x63,  0x02, 	/* 17010 */
+	0xAB,  0x11,  0x0F,  0xFE,  0x11,  0x03,  0xF8,  0x20,  0x83,  0xF8,  0x20,  0x83,  0xF8,  0x04,  0x0F,  0xFE, 	/* 17020 */
+	0x1B,  0x0E,  0x0E,  0xB1,  0x11,  0x0F,  0xFE,  0x15,  0x07,  0xFC,  0x24,  0x81,  0x50,  0xFF,  0xE0,  0xE0, 	/* 17030 */
+	0x15,  0x02,  0x48,  0xC4,  0x60,  0x40,  0xB5,  0x11,  0x0F,  0xFE,  0x15,  0x00,  0x80,  0x3F,  0x82,  0x48, 	/* 17040 */
+	0x24,  0x83,  0xF8,  0x0C,  0x01,  0x52,  0x24,  0xAC,  0x3E,  0xBD,  0x11,  0x0F,  0xFE,  0x11,  0x00,  0x40, 	/* 17050 */
+	0xFF,  0xE0,  0xA0,  0x31,  0x8D,  0x16,  0x11,  0x0F,  0xFC,  0x21,  0x04,  0x10,  0x81,  0x11,  0x0F,  0xFE, 	/* 17060 */
+	0x15,  0x07,  0xFC,  0x04,  0x03,  0xF8,  0x04,  0x0F,  0xFE,  0x24,  0x83,  0xF8,  0x20,  0x82,  0x18,  0x85, 	/* 17070 */
+	0x11,  0x0F,  0xFE,  0x15,  0x0F,  0xFE,  0x80,  0x2B,  0xF2,  0x21,  0x03,  0xF0,  0x20,  0x03,  0xF8,  0x20, 	/* 17080 */
+	0x83,  0xF8,  0x8A,  0x11,  0x0F,  0xFE,  0x11,  0x02,  0x00,  0x3F,  0xE4,  0x4A,  0x95,  0x27,  0xFE,  0x0E, 	/* 17090 */
+	0x21,  0x52,  0x64,  0xA0,  0x4C,  0x8C,  0x09,  0x0F,  0xFF,  0x09,  0x07,  0xFE,  0x43,  0x25,  0xC2,  0x44, 	/* 170A0 */
+	0x27,  0xFE,  0x4E,  0x27,  0x5A,  0x44,  0x27,  0xFE,  0x8E,  0x11,  0x0F,  0xFE,  0x11,  0x03,  0xF8,  0x20, 	/* 170B0 */
+	0x83,  0xF8,  0x20,  0x83,  0xF8,  0x22,  0x43,  0xB8,  0x22,  0x2F,  0x9E,  0x93,  0x11,  0x0F,  0xFE,  0x11, 	/* 170C0 */
+	0x03,  0xF8,  0x24,  0x83,  0xF8,  0x24,  0x8F,  0xFE,  0x0E,  0x03,  0x58,  0xC4,  0x60,  0x40,  0x96,  0x12, 	/* 170D0 */
+	0x0F,  0xFE,  0x12,  0x03,  0xF8,  0x20,  0x83,  0xF8,  0x20,  0x87,  0xFC,  0x40,  0x47,  0xFC,  0x40,  0x47, 	/* 170E0 */
+	0xFC,  0x98,  0x11,  0x0F,  0xFE,  0x11,  0x02,  0x38,  0x24,  0x8F,  0x44,  0x29,  0x27,  0x10,  0xAA,  0x8A, 	/* 170F0 */
+	0x24,  0x2F,  0xC2,  0x04,  0x9C,  0x11,  0x0F,  0xFE,  0x13,  0x87,  0xC8,  0x24,  0x81,  0x50,  0x04,  0x0F, 	/* 17100 */
+	0xFE,  0x0E,  0x03,  0x58,  0xC4,  0x60,  0x40,  0x9F,  0x11,  0x0F,  0xFE,  0x11,  0x00,  0xF0,  0x71,  0x03, 	/* 17110 */
+	0xF8,  0x24,  0x83,  0xF8,  0x0B,  0x01,  0x28,  0x22,  0x2C,  0x1E,  0xA0,  0x11,  0x0F,  0xFE,  0x11,  0x05, 	/* 17120 */
+	0x10,  0x2F,  0xE8,  0x94,  0x49,  0x00,  0xFC,  0x2A,  0x45,  0x18,  0x52,  0x4A,  0x42,  0xA9,  0x11,  0x0F, 	/* 17130 */
+	0xFE,  0x15,  0x07,  0xFC,  0x11,  0x00,  0xA0,  0xFF,  0xE0,  0x00,  0x3F,  0x82,  0x08,  0x20,  0x83,  0xF8, 	/* 17140 */
+	0xAB,  0x11,  0x0F,  0xFE,  0x11,  0x0F,  0xFE,  0x04,  0x07,  0xFC,  0x44,  0x47,  0xFC,  0x04,  0x03,  0xF8, 	/* 17150 */
+	0x04,  0x0F,  0xFE,  0xAF,  0x11,  0x0F,  0xFE,  0x11,  0x07,  0xFC,  0x24,  0x8F,  0xFE,  0x24,  0x87,  0xFC, 	/* 17160 */
+	0x04,  0x0F,  0xFE,  0x04,  0x00,  0x40,  0xB0,  0x12,  0x0F,  0xFC,  0x12,  0x00,  0x0C,  0xFF,  0x81,  0xA8, 	/* 17170 */
+	0x2A,  0x83,  0xA8,  0xEA,  0x82,  0xA4,  0x2A,  0xC7,  0x7A,  0xB1,  0x11,  0x0F,  0xFE,  0x15,  0x07,  0xFC, 	/* 17180 */
+	0x04,  0x0F,  0xFE,  0x28,  0x8C,  0xF6,  0x19,  0x06,  0x60,  0x0D,  0x8F,  0x06,  0xB2,  0x11,  0x0F,  0xFE, 	/* 17190 */
+	0x11,  0x00,  0xA0,  0xFB,  0xE0,  0xA0,  0x7B,  0xC0,  0xA0,  0xF3,  0xE1,  0x20,  0x22,  0x0C,  0x20,  0xB4, 	/* 171A0 */
+	0x11,  0x0F,  0xFE,  0x15,  0x00,  0x80,  0xFF,  0xE3,  0xF8,  0x64,  0xCB,  0xFA,  0x24,  0x83,  0xF8,  0x04, 	/* 171B0 */
+	0x20,  0x3E,  0xB7,  0x11,  0x0F,  0xFE,  0x11,  0x03,  0xF8,  0xFF,  0xE0,  0x08,  0xFF,  0xE8,  0x42,  0xBF, 	/* 171C0 */
+	0xA2,  0x48,  0x25,  0x80,  0x40,  0xBB,  0x11,  0x0F,  0xFE,  0x11,  0x01,  0x10,  0xFF,  0xE1,  0x10,  0x3B, 	/* 171D0 */
+	0x83,  0x58,  0x55,  0x45,  0x92,  0x91,  0x01,  0x10,  0xBD,  0x11,  0x0F,  0xFE,  0x11,  0x02,  0x00,  0x3B, 	/* 171E0 */
+	0xC2,  0x04,  0xFA,  0x42,  0x14,  0x68,  0x86,  0x58,  0xA2,  0x42,  0xC2,  0x83,  0x11,  0x0F,  0xFE,  0x11, 	/* 171F0 */
+	0x00,  0x40,  0x7F,  0xC1,  0x10,  0x31,  0x84,  0xA4,  0xFF,  0xE0,  0x40,  0x04,  0x00,  0x40,  0x84,  0x09, 	/* 17200 */
+	0x07,  0xFE,  0x29,  0x03,  0xFE,  0x30,  0x25,  0xFA,  0x94,  0x23,  0xFA,  0x04,  0x22,  0x4A,  0x3F,  0xA0, 	/* 17210 */
+	0x0C,  0x87,  0x11,  0x0F,  0xFE,  0x11,  0x03,  0xF8,  0x20,  0x03,  0xF0,  0x20,  0x0F,  0xFE,  0x24,  0x82, 	/* 17220 */
+	0x30,  0x39,  0x86,  0x06,  0x8B,  0x11,  0x0F,  0xFE,  0x15,  0x07,  0xFE,  0x3F,  0xC0,  0x44,  0xFF,  0xF0, 	/* 17230 */
+	0x44,  0x7F,  0xE1,  0x88,  0x0F,  0x07,  0x0C,  0x8C,  0x11,  0x0F,  0xFF,  0x11,  0x00,  0x00,  0x7B,  0xE4, 	/* 17240 */
+	0xA2,  0x7B,  0xE4,  0xA2,  0x4B,  0xE7,  0xA2,  0x04,  0x20,  0x86,  0x8D,  0x11,  0x0F,  0xFF,  0x11,  0x04, 	/* 17250 */
+	0xFE,  0x25,  0x48,  0x54,  0x49,  0x21,  0xFF,  0x21,  0x04,  0x10,  0x81,  0x08,  0x10,  0x8E,  0x11,  0x0F, 	/* 17260 */
+	0xFE,  0x11,  0x07,  0xFC,  0x04,  0x0F,  0xFE,  0x35,  0x8C,  0x46,  0x7F,  0xC1,  0x10,  0x0F,  0x07,  0x8C, 	/* 17270 */
+	0x93,  0x11,  0x0F,  0xFE,  0x15,  0x0F,  0xFE,  0x80,  0x29,  0xF2,  0x11,  0x01,  0xF0,  0x11,  0x01,  0xF0, 	/* 17280 */
+	0x11,  0x0F,  0xFE,  0xA0,  0x11,  0x0F,  0xFE,  0x11,  0x07,  0xBC,  0x4A,  0x46,  0xB4,  0x5A,  0xC6,  0xB4, 	/* 17290 */
+	0x5A,  0xC4,  0xA4,  0x4A,  0x49,  0xCC,  0xA2,  0x11,  0x0F,  0xFE,  0x11,  0x04,  0x40,  0x27,  0xC8,  0x84, 	/* 172A0 */
+	0x5F,  0x40,  0x14,  0x2F,  0x84,  0x80,  0x88,  0x28,  0x7E,  0xA9,  0x11,  0x0F,  0xFE,  0x12,  0x0E,  0x10, 	/* 172B0 */
+	0x25,  0x2F,  0xD2,  0x25,  0x47,  0x10,  0x69,  0x0A,  0x28,  0x24,  0x43,  0x82,  0xAA,  0x11,  0x0F,  0xFE, 	/* 172C0 */
+	0x11,  0x01,  0x88,  0xE2,  0x82,  0x18,  0xFC,  0x87,  0x28,  0x68,  0xEA,  0x78,  0x20,  0x82,  0x08,  0xAC, 	/* 172D0 */
+	0x11,  0x0F,  0xFE,  0x24,  0x83,  0xF8,  0x24,  0x83,  0xF8,  0x04,  0x07,  0xFE,  0x45,  0x24,  0x7A,  0x78, 	/* 172E0 */
+	0xA4,  0x06,  0xB1,  0x11,  0x0F,  0xFE,  0x15,  0x0F,  0xFE,  0x80,  0x27,  0xFC,  0x20,  0x83,  0xF8,  0x20, 	/* 172F0 */
+	0x83,  0xF8,  0x00,  0x0F,  0xFE,  0xB5,  0x11,  0x0F,  0xFE,  0x11,  0x03,  0xF8,  0x20,  0x82,  0xF8,  0x28, 	/* 17300 */
+	0x8F,  0xFE,  0x9F,  0x29,  0x12,  0x9F,  0x28,  0x06,  0xB8,  0x11,  0x0F,  0xFE,  0x11,  0x01,  0x40,  0x65, 	/* 17310 */
+	0xC4,  0x44,  0x75,  0xC4,  0x44,  0x75,  0xC0,  0xA0,  0x31,  0x8C,  0x06,  0xBC,  0x11,  0x0F,  0xFE,  0x11, 	/* 17320 */
+	0x07,  0xBC,  0x4A,  0x47,  0xBC,  0x00,  0x0F,  0xFE,  0x08,  0x01,  0xF8,  0x20,  0x80,  0x30,  0xBD,  0x11, 	/* 17330 */
+	0x0F,  0xFE,  0x15,  0x05,  0x78,  0x24,  0x88,  0xB0,  0x43,  0x00,  0xC8,  0x3F,  0xE4,  0x88,  0x88,  0x88, 	/* 17340 */
+	0xF8,  0x86,  0x11,  0x0F,  0xFE,  0x11,  0x02,  0x7C,  0x24,  0x44,  0x7C,  0xC1,  0x05,  0xFE,  0x43,  0x84, 	/* 17350 */
+	0x54,  0x59,  0x24,  0x10,  0x89,  0x10,  0x8F,  0xFE,  0x11,  0x02,  0x50,  0xFF,  0xE2,  0x50,  0x3F,  0x80, 	/* 17360 */
+	0x40,  0xFF,  0xE3,  0x58,  0xC4,  0x60,  0x40,  0x8E,  0x11,  0x0F,  0xFE,  0x11,  0x02,  0x20,  0x3F,  0xC4, 	/* 17370 */
+	0x24,  0xBF,  0xE2,  0x24,  0x5F,  0xCC,  0x20,  0x5F,  0xE4,  0x20,  0x97,  0x11,  0x0F,  0xFE,  0x15,  0x07, 	/* 17380 */
+	0xF8,  0x06,  0x0F,  0xFE,  0x08,  0x01,  0xF8,  0x30,  0x8D,  0xF8,  0x10,  0x81,  0xF8,  0x9B,  0x11,  0x0F, 	/* 17390 */
+	0xFE,  0x11,  0x03,  0xF8,  0x20,  0x83,  0xF8,  0x20,  0x83,  0xFE,  0x33,  0x2D,  0xCA,  0x0F,  0xA0,  0x0C, 	/* 173A0 */
+	0xA1,  0x09,  0x0F,  0xFE,  0x29,  0x03,  0xFE,  0x44,  0xA7,  0xFA,  0x84,  0x23,  0xFA,  0x24,  0xA3,  0xFA, 	/* 173B0 */
+	0x24,  0xA2,  0x5C,  0xA2,  0x11,  0x0F,  0xFE,  0x11,  0x00,  0x40,  0xFF,  0xE0,  0xA0,  0x35,  0x8C,  0x26, 	/* 173C0 */
+	0x3F,  0x82,  0xA8,  0x2A,  0x8F,  0xFE,  0xA3,  0x11,  0x0F,  0xFE,  0x11,  0x07,  0xFC,  0x04,  0x0F,  0xFE, 	/* 173D0 */
+	0x24,  0x83,  0xF8,  0x24,  0x87,  0xFC,  0x04,  0x0F,  0xFE,  0xA6,  0x11,  0x0F,  0xFE,  0x15,  0x07,  0xF8, 	/* 173E0 */
+	0x08,  0x8F,  0xFE,  0x10,  0x81,  0xF8,  0x3F,  0xC2,  0x40,  0xFF,  0xE0,  0x40,  0xA9,  0x11,  0x0F,  0xFE, 	/* 173F0 */
+	0x11,  0x02,  0x00,  0x47,  0xCF,  0x54,  0x95,  0x4F,  0x7C,  0x94,  0x09,  0x40,  0xF4,  0x20,  0x3E,  0xAB, 	/* 17400 */
+	0x11,  0x0F,  0xFE,  0x11,  0x02,  0x00,  0x23,  0xCF,  0xE4,  0x23,  0xC7,  0xA4,  0x4B,  0xC4,  0xA4,  0x7C, 	/* 17410 */
+	0x40,  0x8C,  0xAC,  0x11,  0x0F,  0xFE,  0x11,  0x0F,  0xFE,  0x22,  0x0F,  0xBC,  0x2A,  0x2F,  0x3E,  0x11, 	/* 17420 */
+	0x0F,  0xFE,  0x11,  0x06,  0x10,  0xAD,  0x11,  0x0F,  0xFE,  0x11,  0x07,  0xBC,  0x48,  0x47,  0xBC,  0x40, 	/* 17430 */
+	0x07,  0xBE,  0x41,  0x27,  0x8C,  0x41,  0x44,  0x62,  0xAE,  0x11,  0x0F,  0xFE,  0x11,  0x03,  0x38,  0x42, 	/* 17440 */
+	0x87,  0x2A,  0x44,  0x67,  0xBC,  0x42,  0x47,  0x98,  0xC3,  0x44,  0xC2,  0xAF,  0x11,  0x0F,  0xFE,  0x11, 	/* 17450 */
+	0x02,  0x10,  0x29,  0xED,  0x22,  0x2A,  0x2F,  0xD2,  0x28,  0xAB,  0x02,  0xA8,  0x22,  0x0C,  0xB1,  0x12, 	/* 17460 */
+	0x0F,  0xFE,  0x32,  0x03,  0xFC,  0x52,  0x4B,  0xF4,  0x24,  0x44,  0x98,  0x08,  0x05,  0x54,  0x91,  0x20, 	/* 17470 */
+	0xF0,  0xB5,  0x11,  0x0F,  0xFE,  0x11,  0x01,  0xF0,  0x49,  0x43,  0x0A,  0x3F,  0xCC,  0x43,  0x3F,  0xC0, 	/* 17480 */
+	0x60,  0x19,  0x86,  0x06,  0xB7,  0x11,  0x0F,  0xFE,  0x11,  0x0F,  0xFE,  0x84,  0x27,  0xFC,  0x24,  0x83, 	/* 17490 */
+	0xF8,  0x24,  0x8F,  0xFE,  0x04,  0x00,  0x40,  0xB9,  0x11,  0x0F,  0xFE,  0x11,  0x02,  0x20,  0xFB,  0xE2, 	/* 174A0 */
+	0x48,  0x2B,  0xE3,  0xEA,  0x2A,  0xC4,  0xA8,  0x8A,  0x23,  0x1E,  0xBA,  0x12,  0x0F,  0xFE,  0x12,  0x03, 	/* 174B0 */
+	0xF8,  0x20,  0x8F,  0xFE,  0x11,  0x01,  0xF0,  0x11,  0x01,  0xFE,  0xF1,  0x00,  0x10,  0x82,  0x11,  0x0F, 	/* 174C0 */
+	0xFE,  0x15,  0x00,  0x40,  0x7F,  0xC1,  0x10,  0xFF,  0xE8,  0x42,  0x3F,  0x82,  0x48,  0x27,  0x00,  0x40, 	/* 174D0 */
+	0x84,  0x11,  0x0F,  0xFE,  0x11,  0x0F,  0xFE,  0x80,  0xA7,  0x8A,  0x03,  0xCF,  0xC8,  0x2A,  0x82,  0x88, 	/* 174E0 */
+	0x49,  0xA8,  0x7E,  0x8B,  0x11,  0x0F,  0xFE,  0x11,  0x02,  0x1C,  0x2F,  0x4A,  0xA4,  0x65,  0x82,  0x08, 	/* 174F0 */
+	0x6F,  0xEA,  0x48,  0x22,  0x82,  0x18,  0x90,  0x11,  0x0F,  0xFE,  0x11,  0x00,  0x40,  0x3F,  0x82,  0x48, 	/* 17500 */
+	0x3F,  0x82,  0x48,  0x3F,  0xA1,  0x24,  0x22,  0xAC,  0x1E,  0x94,  0x10,  0x8F,  0xFE,  0x11,  0x0E,  0x20, 	/* 17510 */
+	0xAF,  0xCA,  0x20,  0xFF,  0xEA,  0x08,  0xBF,  0xEA,  0x88,  0xE4,  0x80,  0x18,  0x99,  0x11,  0x0F,  0xFE, 	/* 17520 */
+	0x15,  0x0F,  0xFE,  0x80,  0x27,  0xFC,  0x14,  0x4E,  0x68,  0x1B,  0x0E,  0x78,  0x1A,  0x66,  0x60,  0x9C, 	/* 17530 */
+	0x20,  0x8F,  0xBE,  0x20,  0x87,  0xBC,  0x00,  0x0F,  0xBE,  0x20,  0x8B,  0x2C,  0xAA,  0xAA,  0xAA,  0xA2, 	/* 17540 */
+	0xA6,  0x18,  0x9F,  0x11,  0x0F,  0xFE,  0x11,  0x02,  0x10,  0xFB,  0xE1,  0x42,  0x5B,  0xA5,  0x2A,  0x22, 	/* 17550 */
+	0xA3,  0xBA,  0xC0,  0x20,  0x0C,  0xA1,  0x11,  0x0F,  0xFE,  0x15,  0x07,  0xFC,  0x11,  0x0F,  0xFE,  0x84, 	/* 17560 */
+	0x27,  0xFE,  0x08,  0x00,  0xF8,  0x10,  0x86,  0x30,  0xAD,  0x11,  0x0F,  0xFE,  0x21,  0x03,  0xFC,  0x65, 	/* 17570 */
+	0x4B,  0xF4,  0x29,  0x83,  0xFC,  0x44,  0x4A,  0x54,  0x3F,  0x40,  0x98,  0xB2,  0x11,  0x0F,  0xFE,  0x12, 	/* 17580 */
+	0x84,  0xFC,  0x22,  0x08,  0xFC,  0x4A,  0x40,  0xFC,  0x2A,  0x44,  0xFC,  0x4A,  0x48,  0xAC,  0xB8,  0x11, 	/* 17590 */
+	0x0F,  0xFE,  0x11,  0x03,  0xF8,  0x02,  0x27,  0x5C,  0x15,  0x02,  0x48,  0xDF,  0x60,  0x00,  0x4A,  0x48, 	/* 175A0 */
+	0x92,  0xB9,  0x11,  0x0F,  0xFE,  0x19,  0x83,  0x30,  0x7F,  0xC0,  0xA4,  0xFF,  0xE0,  0xA4,  0x7F,  0xC1, 	/* 175B0 */
+	0xB0,  0x2A,  0x84,  0xA4,  0xBB,  0x11,  0x0F,  0xFE,  0x11,  0x07,  0xBC,  0x08,  0x47,  0xBC,  0x42,  0x07, 	/* 175C0 */
+	0xBC,  0x29,  0x45,  0xAC,  0x29,  0x41,  0x8C,  0xBC,  0x11,  0x0F,  0xFE,  0x15,  0x00,  0xA0,  0x35,  0x8F, 	/* 175D0 */
+	0xF6,  0x21,  0x03,  0xF0,  0x21,  0x03,  0xF8,  0x50,  0x89,  0xF8,  0xBF,  0x11,  0x0F,  0xFE,  0x11,  0x00, 	/* 175E0 */
+	0x40,  0xFF,  0xE2,  0x08,  0x3F,  0x80,  0x00,  0xFF,  0xE9,  0x12,  0x9F,  0x28,  0x06,  0x81,  0x11,  0x0F, 	/* 175F0 */
+	0xFE,  0x11,  0x07,  0xFC,  0x0A,  0x0F,  0xFE,  0x26,  0x8D,  0xC6,  0x7F,  0xC1,  0x58,  0x64,  0x40,  0x40, 	/* 17600 */
+	0x84,  0x11,  0x0F,  0xFE,  0x15,  0x0F,  0xFE,  0x04,  0x83,  0xB0,  0x0C,  0x8F,  0xFC,  0x24,  0xA3,  0xF8, 	/* 17610 */
+	0x24,  0x83,  0xF8,  0x86,  0x11,  0x0F,  0xFE,  0x15,  0x07,  0xFE,  0x49,  0x07,  0xFC,  0x49,  0x04,  0xF0, 	/* 17620 */
+	0x5F,  0xC5,  0x24,  0x93,  0x80,  0x20,  0x89,  0x11,  0x0F,  0xFE,  0x15,  0x0F,  0xFE,  0x91,  0x22,  0x48, 	/* 17630 */
+	0x4A,  0x43,  0x18,  0xC0,  0x63,  0xF8,  0x20,  0x83,  0xF8,  0x8A,  0x21,  0x0F,  0xFE,  0x15,  0x00,  0xE0, 	/* 17640 */
+	0x35,  0x8D,  0xA6,  0x7F,  0xC1,  0x8C,  0x6B,  0x41,  0x8C,  0x6B,  0x41,  0x8C,  0x8B,  0x11,  0x0F,  0xFE, 	/* 17650 */
+	0x11,  0x00,  0x40,  0x7F,  0xC0,  0x40,  0xFF,  0xE1,  0x08,  0x7F,  0xC2,  0xAA,  0x2A,  0x8F,  0xFE,  0x8D, 	/* 17660 */
+	0x11,  0x0F,  0xFE,  0x15,  0x07,  0xFC,  0x05,  0x0F,  0xFE,  0x18,  0xC2,  0xF0,  0xC8,  0x23,  0xFE,  0x20, 	/* 17670 */
+	0x83,  0xF8,  0x90,  0x11,  0x0F,  0xFE,  0x11,  0x07,  0xFE,  0x40,  0x07,  0xFC,  0x56,  0x87,  0x9C,  0x41, 	/* 17680 */
+	0x0B,  0xFE,  0x11,  0x00,  0x30,  0x91,  0x11,  0x0F,  0xFE,  0x11,  0x00,  0x40,  0xFF,  0xE2,  0x08,  0xFF, 	/* 17690 */
+	0xE2,  0x08,  0x3F,  0xA1,  0xA4,  0xE9,  0x83,  0xC6,  0x96,  0x11,  0x0F,  0xFE,  0x11,  0x07,  0xFC,  0x51, 	/* 176A0 */
+	0x44,  0xE4,  0x51,  0x47,  0xFC,  0x22,  0x43,  0xB8,  0x22,  0x2F,  0x9E,  0x99,  0x11,  0x0F,  0xFE,  0x11, 	/* 176B0 */
+	0x00,  0x40,  0x7F,  0xE5,  0x24,  0x5A,  0xC5,  0x74,  0x62,  0x25,  0xFC,  0x82,  0x0B,  0xFE,  0x9A,  0x11, 	/* 176C0 */
+	0x0F,  0xFE,  0x11,  0x01,  0x20,  0x27,  0xE2,  0xA4,  0x69,  0x8A,  0xA4,  0x2D,  0xA2,  0xE5,  0x21,  0x82, 	/* 176D0 */
+	0x60,  0xAC,  0x11,  0x0F,  0xFF,  0x11,  0x04,  0x7E,  0x2C,  0x40,  0x38,  0xED,  0x72,  0x7C,  0x21,  0x02, 	/* 176E0 */
+	0xFE,  0x59,  0x08,  0x7F,  0xAE,  0x11,  0x0F,  0xFE,  0x13,  0x05,  0xFC,  0x22,  0x00,  0xFC,  0xEA,  0x42, 	/* 176F0 */
+	0xFC,  0x2A,  0x43,  0xFE,  0x52,  0x08,  0xFF,  0xB4,  0x11,  0x0F,  0xFE,  0x15,  0x0F,  0xFE,  0x24,  0x83, 	/* 17700 */
+	0xF8,  0x24,  0xC7,  0xFE,  0x01,  0x0F,  0xFE,  0x11,  0x00,  0xB0,  0xBC,  0x11,  0x0F,  0xFE,  0x11,  0x07, 	/* 17710 */
+	0xBC,  0x18,  0xC6,  0xB4,  0x1C,  0xC6,  0xB4,  0x32,  0xCC,  0xCA,  0x03,  0x03,  0xC0,  0xBF,  0x11,  0x0F, 	/* 17720 */
+	0xFE,  0x15,  0x0F,  0xFE,  0x80,  0x29,  0x7E,  0x11,  0x02,  0x7C,  0x64,  0x4A,  0x7C,  0x24,  0x42,  0x7C, 	/* 17730 */
+	0x80,  0x11,  0x0F,  0xFE,  0x11,  0x07,  0xDE,  0x29,  0x22,  0x94,  0xFF,  0xE0,  0x12,  0x7D,  0x24,  0x5C, 	/* 17740 */
+	0x7D,  0x04,  0x10,  0x86,  0x11,  0x0F,  0xFE,  0x11,  0x04,  0xFC,  0x22,  0x09,  0xFE,  0x44,  0x81,  0xA4, 	/* 17750 */
+	0x27,  0xA5,  0xC8,  0x83,  0x09,  0xCC,  0x91,  0x11,  0x0F,  0xFE,  0x11,  0x07,  0xFC,  0x4A,  0x47,  0xFC, 	/* 17760 */
+	0x02,  0x87,  0xFE,  0x52,  0x44,  0x98,  0x41,  0xA8,  0x66,  0x93,  0x11,  0x0F,  0xFE,  0x20,  0x83,  0xF8, 	/* 17770 */
+	0x20,  0x87,  0xFC,  0x4A,  0x47,  0xFC,  0x11,  0x00,  0xE0,  0x1B,  0x8E,  0x06,  0x94,  0x11,  0x0F,  0xFE, 	/* 17780 */
+	0x11,  0x01,  0xFE,  0x20,  0x27,  0xFA,  0x91,  0x23,  0xFA,  0x3F,  0xA2,  0x4A,  0x3F,  0xA0,  0x0C,  0x95, 	/* 17790 */
+	0x11,  0x0F,  0xFE,  0x11,  0x02,  0xA8,  0xFF,  0xE2,  0xAA,  0xCE,  0x6F,  0xFE,  0xA4,  0xA2,  0x48,  0x27, 	/* 177A0 */
+	0x00,  0x40,  0x97,  0x11,  0x0F,  0xFE,  0x11,  0x00,  0x40,  0x7F,  0xE4,  0x90,  0x7F,  0xE4,  0x90,  0x4F, 	/* 177B0 */
+	0x04,  0x00,  0x95,  0x4A,  0x2A,  0x98,  0x11,  0x0F,  0xFE,  0x15,  0x01,  0xB0,  0x7E,  0x82,  0x48,  0x55, 	/* 177C0 */
+	0x4F,  0xBE,  0x35,  0x8D,  0x96,  0x06,  0x03,  0x80,  0x9A,  0x11,  0x0F,  0xFE,  0x11,  0x07,  0xC4,  0x44, 	/* 177D0 */
+	0x47,  0xFE,  0x40,  0x47,  0xD4,  0x49,  0x46,  0xC4,  0xAA,  0x42,  0xAC,  0x9F,  0x11,  0x0F,  0xFE,  0x11, 	/* 177E0 */
+	0x02,  0x20,  0x23,  0xEF,  0xE0,  0x23,  0xE3,  0xC8,  0x2B,  0xE4,  0x88,  0x89,  0x43,  0x62,  0xA1,  0x11, 	/* 177F0 */
+	0x0F,  0xFE,  0x11,  0x03,  0xFE,  0x4A,  0x4B,  0x18,  0x2E,  0x6C,  0x00,  0x7F,  0xE2,  0x48,  0xC4,  0x40, 	/* 17800 */
+	0xC0,  0xA6,  0x11,  0x0F,  0xFE,  0x15,  0x03,  0xF8,  0x20,  0x83,  0xF8,  0x20,  0x83,  0xFE,  0x20,  0x03, 	/* 17810 */
+	0xFE,  0x4A,  0xA9,  0x0C,  0xAC,  0x11,  0x0F,  0xFE,  0x11,  0x0F,  0x90,  0x17,  0xE2,  0x28,  0x3F,  0xC2, 	/* 17820 */
+	0x02,  0xA5,  0x4B,  0xD4,  0xE5,  0x48,  0x86,  0xAD,  0x11,  0x0F,  0xFE,  0x11,  0x0E,  0x30,  0xA7,  0x8C, 	/* 17830 */
+	0x84,  0xB7,  0xEA,  0x08,  0xBF,  0xEC,  0x48,  0x85,  0xC8,  0xE4,  0xB5,  0x11,  0x0F,  0xFE,  0x11,  0x47, 	/* 17840 */
+	0xFE,  0x41,  0x05,  0xF4,  0x55,  0x45,  0xF4,  0x52,  0x85,  0xEA,  0x55,  0x69,  0xE2,  0xBD,  0x11,  0x0F, 	/* 17850 */
+	0xFE,  0x11,  0x05,  0x50,  0x39,  0xEF,  0xE4,  0x96,  0x4B,  0x54,  0xBC,  0x8D,  0x48,  0x95,  0x49,  0x62, 	/* 17860 */
+	0x80,  0x11,  0x0F,  0xFE,  0x31,  0x8F,  0xBE,  0x20,  0x8F,  0xBE,  0xAA,  0xAA,  0xAA,  0x71,  0xC6,  0xAA, 	/* 17870 */
+	0xA4,  0x92,  0x08,  0x81,  0x11,  0x0F,  0xFE,  0x11,  0x03,  0xF8,  0x00,  0x8F,  0xFE,  0x7B,  0xC1,  0x24, 	/* 17880 */
+	0xFF,  0xE1,  0x08,  0x08,  0x80,  0x18,  0x83,  0x11,  0x0F,  0xFE,  0x11,  0x07,  0xFC,  0x24,  0x8F,  0xFE, 	/* 17890 */
+	0x15,  0x03,  0xF8,  0xE4,  0xE3,  0xF8,  0x24,  0x83,  0xF8,  0x88,  0x11,  0x0F,  0xFE,  0x11,  0x07,  0xFC, 	/* 178A0 */
+	0x55,  0x47,  0xFC,  0x20,  0x83,  0xF8,  0x20,  0x8F,  0xFE,  0x04,  0x00,  0x40,  0x89,  0x08,  0x8F,  0xFE, 	/* 178B0 */
+	0x2A,  0x83,  0xFE,  0x22,  0x07,  0xFC,  0xA2,  0x03,  0xFC,  0x22,  0x03,  0xFE,  0x52,  0x48,  0x92,  0x8A, 	/* 178C0 */
+	0x11,  0x0F,  0xFE,  0x11,  0x00,  0xC0,  0x2A,  0x44,  0x8A,  0x07,  0x81,  0x08,  0x69,  0x46,  0x72,  0xA5, 	/* 178D0 */
+	0x31,  0xCE,  0x8B,  0x11,  0x0F,  0xFE,  0x15,  0x02,  0x40,  0x27,  0x82,  0x40,  0xFF,  0xE1,  0x08,  0x5A, 	/* 178E0 */
+	0xE5,  0x28,  0x5E,  0x8E,  0x3E,  0x8E,  0x11,  0x0F,  0xFE,  0x11,  0x03,  0xF8,  0x04,  0x0F,  0xFE,  0x3B, 	/* 178F0 */
+	0x8C,  0xE6,  0x7F,  0xC4,  0xE4,  0x4A,  0x44,  0xEC,  0x95,  0x11,  0x0F,  0xFE,  0x11,  0x0A,  0x7C,  0x44, 	/* 17900 */
+	0x44,  0xBA,  0xA2,  0x82,  0xFE,  0x6A,  0xAA,  0xCE,  0x28,  0x2C,  0xFE,  0x97,  0x12,  0x0F,  0xFE,  0x12, 	/* 17910 */
+	0x07,  0xBC,  0x4A,  0x44,  0xE4,  0x79,  0x81,  0x24,  0x5F,  0xE5,  0x24,  0x5E,  0x4E,  0x3C,  0x98,  0x11, 	/* 17920 */
+	0x0F,  0xFE,  0x15,  0x03,  0xF8,  0xFB,  0xE2,  0x08,  0x7B,  0xC2,  0x08,  0xFF,  0xE0,  0xA0,  0x32,  0x2C, 	/* 17930 */
+	0x1E,  0x9A,  0x11,  0x0F,  0xFE,  0x1F,  0x01,  0x10,  0x1F,  0x07,  0xFC,  0x4A,  0x4F,  0xFE,  0x10,  0x01, 	/* 17940 */
+	0xF8,  0x20,  0x80,  0x30,  0xA3,  0x11,  0x0F,  0xFE,  0x11,  0xC7,  0xE4,  0x24,  0x8F,  0xFE,  0xA0,  0xAB, 	/* 17950 */
+	0xBE,  0x2A,  0x85,  0xFE,  0x10,  0x86,  0x08,  0xA8,  0x11,  0x0F,  0xFE,  0x11,  0x07,  0xFE,  0x54,  0x87, 	/* 17960 */
+	0xEF,  0x49,  0x56,  0xA4,  0x6A,  0x47,  0xE4,  0x48,  0xA9,  0x31,  0xA9,  0x11,  0x0F,  0xFE,  0x11,  0x04, 	/* 17970 */
+	0xFC,  0x28,  0x48,  0xFC,  0x5F,  0xE0,  0x40,  0x2F,  0xE5,  0x2A,  0x4D,  0x28,  0x2C,  0xAA,  0x09,  0x0F, 	/* 17980 */
+	0xFE,  0x29,  0x07,  0xFE,  0x6A,  0x8A,  0xA8,  0xFF,  0xF2,  0xA8,  0xFF,  0xE4,  0xA4,  0x49,  0x28,  0x92, 	/* 17990 */
+	0xAD,  0x11,  0x0F,  0xFE,  0x11,  0x07,  0xF8,  0x04,  0x8F,  0xFE,  0x55,  0x47,  0x5C,  0x44,  0x47,  0xFC, 	/* 179A0 */
+	0x55,  0x49,  0x54,  0xB7,  0x11,  0x0F,  0xFE,  0x11,  0x0F,  0xFE,  0x52,  0x02,  0x7C,  0xFC,  0x42,  0xFC, 	/* 179B0 */
+	0x34,  0x42,  0x7C,  0x22,  0x46,  0xC2,  0xBE,  0x11,  0x0F,  0xFE,  0x11,  0x07,  0xFC,  0x04,  0x0F,  0xFE, 	/* 179C0 */
+	0x84,  0x27,  0x5C,  0x44,  0x47,  0xFC,  0x44,  0x47,  0xFC,  0x80,  0x11,  0x0F,  0xFE,  0x11,  0x04,  0xF8, 	/* 179D0 */
+	0x2A,  0x88,  0xD8,  0x4F,  0x80,  0x00,  0x3F,  0xC5,  0x54,  0x55,  0x4B,  0xFE,  0x84,  0x11,  0x0F,  0xFE, 	/* 179E0 */
+	0x12,  0x89,  0xFE,  0x52,  0x41,  0xFC,  0x92,  0x47,  0xFE,  0x08,  0x84,  0x48,  0x80,  0x88,  0x18,  0x87, 	/* 179F0 */
+	0x11,  0x0F,  0xFE,  0x11,  0x03,  0x58,  0x55,  0xEB,  0xFA,  0x21,  0x25,  0xFA,  0xCA,  0x44,  0xB4,  0x52, 	/* 17A00 */
+	0xA4,  0x12,  0x88,  0x11,  0x0F,  0xFE,  0x15,  0x00,  0xA0,  0x31,  0x8F,  0xFE,  0x4A,  0x47,  0xFC,  0x20, 	/* 17A10 */
+	0x83,  0xF8,  0x20,  0x83,  0xF8,  0x8A,  0x11,  0x0F,  0xFE,  0x11,  0x03,  0xC4,  0x49,  0x4F,  0xD4,  0x55, 	/* 17A20 */
+	0x47,  0xD4,  0x55,  0x47,  0xC4,  0x54,  0x4A,  0xAC,  0x90,  0x11,  0x0F,  0xFE,  0x19,  0x0F,  0x7C,  0x21, 	/* 17A30 */
+	0x0F,  0xFE,  0x32,  0x86,  0xDE,  0x62,  0x4A,  0xD8,  0x22,  0x82,  0xC6,  0x91,  0x11,  0x0F,  0xFE,  0x11, 	/* 17A40 */
+	0x0F,  0xFE,  0x24,  0x83,  0xF8,  0x24,  0x8F,  0xFE,  0x24,  0x83,  0xF8,  0x24,  0x8F,  0xFE,  0x94,  0x11, 	/* 17A50 */
+	0x0F,  0xFE,  0x11,  0x07,  0xFC,  0x24,  0x86,  0x4C,  0x95,  0x27,  0xFC,  0x51,  0x45,  0xF4,  0x40,  0x47, 	/* 17A60 */
+	0xFC,  0x97,  0x11,  0x0F,  0xFE,  0x11,  0x07,  0xFE,  0x4F,  0x27,  0xFE,  0x50,  0xA5,  0xFA,  0x4A,  0xA7, 	/* 17A70 */
+	0x92,  0x4C,  0xA7,  0xFE,  0x99,  0x11,  0x0F,  0xFE,  0x11,  0x04,  0x44,  0x74,  0x86,  0x7E,  0xAC,  0x8F, 	/* 17A80 */
+	0x7E,  0x24,  0x85,  0x7E,  0x44,  0x88,  0x7E,  0x9B,  0x12,  0x0F,  0xFE,  0x12,  0x04,  0x10,  0xFF,  0xE9, 	/* 17A90 */
+	0x44,  0xF2,  0x88,  0xFE,  0xF9,  0x08,  0xFC,  0xF9,  0x08,  0x10,  0x9C,  0x11,  0x0F,  0xFF,  0x11,  0x87, 	/* 17AA0 */
+	0xFE,  0x4A,  0x47,  0xA4,  0x47,  0xE7,  0x88,  0xAF,  0xEA,  0x88,  0xB8,  0x80,  0x08,  0xA4,  0x11,  0x0F, 	/* 17AB0 */
+	0xFE,  0x11,  0x0F,  0xA8,  0x22,  0x83,  0xEE,  0x4A,  0x86,  0xEE,  0x92,  0x82,  0xEE,  0x42,  0x89,  0xFF, 	/* 17AC0 */
+	0xA6,  0x11,  0x0F,  0xFE,  0x15,  0x07,  0xFE,  0x4A,  0x07,  0xFC,  0x4A,  0x47,  0xFC,  0x50,  0x05,  0xFE, 	/* 17AD0 */
+	0x95,  0x2A,  0x4C,  0xA8,  0x11,  0x0F,  0xFE,  0x11,  0x07,  0xFC,  0x4A,  0x4F,  0xFE,  0x80,  0x27,  0xFC, 	/* 17AE0 */
+	0x2A,  0x4C,  0xB8,  0x32,  0x2C,  0x1E,  0xA9,  0x11,  0x0F,  0xFE,  0x11,  0x0E,  0xFE,  0xA4,  0x4C,  0xFE, 	/* 17AF0 */
+	0xAA,  0x8A,  0xBE,  0xAC,  0x8C,  0xBC,  0x90,  0x8A,  0x7E,  0xAA,  0x11,  0x0F,  0xFE,  0x11,  0x02,  0x06, 	/* 17B00 */
+	0xFB,  0x84,  0xA0,  0xFF,  0xE1,  0x24,  0xFE,  0x43,  0xA4,  0x52,  0x49,  0x44,  0xAB,  0x11,  0x0F,  0xFE, 	/* 17B10 */
+	0x11,  0x07,  0xFC,  0x04,  0x0F,  0xFE,  0x24,  0x83,  0xF8,  0x24,  0x8F,  0xFE,  0x52,  0x48,  0x92,  0xAC, 	/* 17B20 */
+	0x11,  0x0F,  0xFE,  0x15,  0x05,  0xF4,  0x31,  0x8D,  0xF6,  0x11,  0x0F,  0xFF,  0x0E,  0x03,  0x58,  0xC4, 	/* 17B30 */
+	0x60,  0x40,  0xAE,  0x11,  0x0F,  0xFE,  0x11,  0x0A,  0xA0,  0x73,  0xEF,  0xA4,  0x74,  0x4A,  0x94,  0xFD, 	/* 17B40 */
+	0x85,  0x08,  0x31,  0x4C,  0xA2,  0xAF,  0x11,  0x0F,  0xFE,  0x4A,  0x47,  0xFC,  0x08,  0x07,  0xFC,  0x0A, 	/* 17B50 */
+	0x0F,  0xFF,  0x10,  0x83,  0xF8,  0xD0,  0x81,  0xF8,  0xB9,  0x11,  0x0F,  0xFE,  0x15,  0x07,  0xFC,  0x20, 	/* 17B60 */
+	0x8F,  0xFE,  0x80,  0x27,  0xFC,  0x11,  0x83,  0xE4,  0x04,  0x0F,  0xFE,  0xBA,  0x11,  0x0F,  0xFE,  0x15, 	/* 17B70 */
+	0x0F,  0xFE,  0x0A,  0x4F,  0x58,  0x55,  0x4B,  0xFA,  0x20,  0x83,  0xF8,  0x20,  0x84,  0x08,  0x81,  0x11, 	/* 17B80 */
+	0x0F,  0xFE,  0x15,  0x0F,  0xFE,  0x11,  0x07,  0xFC,  0x51,  0x45,  0xF4,  0x04,  0x0F,  0xFE,  0x1F,  0x0E, 	/* 17B90 */
+	0x4E,  0x89,  0x11,  0x0F,  0xFE,  0x11,  0x02,  0x28,  0xF7,  0xC2,  0x28,  0xFF,  0xE2,  0x7C,  0x74,  0x4A, 	/* 17BA0 */
+	0xFC,  0x24,  0x42,  0x7C,  0x8D,  0x11,  0x0F,  0xFE,  0x11,  0x07,  0xD0,  0x51,  0xE7,  0xE0,  0x79,  0xE5, 	/* 17BB0 */
+	0x00,  0x7F,  0xC4,  0xA4,  0x4A,  0x4F,  0xFE,  0x8F,  0x11,  0x0F,  0xFE,  0x11,  0x00,  0x08,  0xBF,  0xEA, 	/* 17BC0 */
+	0xF8,  0xEA,  0xA2,  0xFA,  0xE9,  0xAA,  0xF4,  0xAA,  0xA4,  0xF1,  0x90,  0x11,  0x0F,  0xFE,  0x11,  0x03, 	/* 17BD0 */
+	0x10,  0xD7,  0xC6,  0xC4,  0xF7,  0xC2,  0x44,  0xD7,  0xC2,  0xA8,  0xCA,  0xA3,  0x46,  0x95,  0x11,  0x0F, 	/* 17BE0 */
+	0xFE,  0x11,  0x02,  0x7C,  0xF5,  0x42,  0x7C,  0xF5,  0x42,  0xFE,  0x69,  0x2B,  0xFE,  0x28,  0xA2,  0x86, 	/* 17BF0 */
+	0x9C,  0x11,  0x0F,  0xFE,  0x11,  0x0F,  0xA0,  0x23,  0xEF,  0xCA,  0x71,  0x2A,  0xE6,  0x31,  0x8D,  0xF6, 	/* 17C00 */
+	0x35,  0x8C,  0xC6,  0x9D,  0x11,  0x0F,  0xFE,  0x11,  0x0F,  0xFC,  0x29,  0x4D,  0x74,  0x79,  0xC1,  0xA6, 	/* 17C10 */
+	0x60,  0x0F,  0xFE,  0x11,  0x87,  0xE4,  0xA4,  0x11,  0x0F,  0xFE,  0x11,  0x07,  0x54,  0x5F,  0xE5,  0x28, 	/* 17C20 */
+	0x7F,  0xE5,  0x54,  0x7D,  0x65,  0x39,  0x55,  0x4B,  0x10,  0xA5,  0x11,  0x0F,  0xFE,  0x5F,  0x44,  0xA8, 	/* 17C30 */
+	0xAF,  0x45,  0xAA,  0xFF,  0xE0,  0x40,  0xFF,  0xF3,  0x58,  0xC4,  0x60,  0x40,  0xA9,  0x11,  0x0F,  0xFE, 	/* 17C40 */
+	0x11,  0x09,  0xFC,  0x4A,  0x83,  0xFE,  0x8A,  0x85,  0xFC,  0x2A,  0xA4,  0xF8,  0x4A,  0x88,  0xF8,  0xAA, 	/* 17C50 */
+	0x11,  0x0F,  0xFE,  0x11,  0x07,  0xD0,  0x55,  0xEF,  0xE4,  0x56,  0x4F,  0xD4,  0x29,  0x44,  0x88,  0x39, 	/* 17C60 */
+	0x44,  0x62,  0xB7,  0x11,  0x0F,  0xFE,  0x11,  0x06,  0xFC,  0x01,  0x0F,  0xFE,  0x02,  0x07,  0x7C,  0x0C, 	/* 17C70 */
+	0x4F,  0x7C,  0x94,  0x4F,  0x7C,  0xB9,  0x09,  0x0F,  0xFE,  0x09,  0x0E,  0x7C,  0x04,  0x4F,  0x7C,  0x04, 	/* 17C80 */
+	0x4F,  0x7E,  0x02,  0xAF,  0xD6,  0x97,  0xAF,  0x0C,  0xBA,  0x11,  0x0F,  0xFE,  0x11,  0x07,  0xBC,  0x4A, 	/* 17C90 */
+	0x47,  0xBC,  0x4A,  0x45,  0xF4,  0x74,  0x45,  0xF4,  0x54,  0x45,  0xF4,  0xBB,  0x12,  0x0F,  0xFE,  0x17, 	/* 17CA0 */
+	0x08,  0x50,  0x7F,  0xC1,  0x54,  0x9D,  0xC4,  0x20,  0x1F,  0xC2,  0xB0,  0x52,  0xC8,  0x20,  0xBE,  0x11, 	/* 17CB0 */
+	0x0F,  0xFE,  0x11,  0x02,  0x7E,  0xF9,  0x22,  0x6C,  0xFB,  0xCA,  0xA4,  0xFB,  0xC7,  0x24,  0xAB,  0xC2, 	/* 17CC0 */
+	0x42,  0x82,  0x11,  0x0F,  0xFE,  0x14,  0x85,  0x14,  0x8F,  0x02,  0x94,  0xA5,  0x29,  0xCE,  0x04,  0x0F, 	/* 17CD0 */
+	0xFE,  0x35,  0x8C,  0x46,  0x86,  0x11,  0x0F,  0xFE,  0x15,  0x07,  0xFE,  0x4C,  0x47,  0x7C,  0x4F,  0x84, 	/* 17CE0 */
+	0xA8,  0x5F,  0xC5,  0x54,  0x95,  0x4B,  0xFE,  0x87,  0x11,  0x0F,  0xFE,  0x11,  0x07,  0x0C,  0xA7,  0x0F, 	/* 17CF0 */
+	0x90,  0xAF,  0xEF,  0x98,  0xAB,  0x4F,  0xB2,  0x2D,  0x0A,  0x90,  0x8A,  0x11,  0x0F,  0xFE,  0x11,  0x04, 	/* 17D00 */
+	0x7C,  0x55,  0x4A,  0x6C,  0x57,  0xCF,  0x80,  0x2F,  0xEB,  0xAA,  0xAA,  0xA3,  0xFF,  0x8B,  0x12,  0x0F, 	/* 17D10 */
+	0xFE,  0x12,  0x02,  0x7E,  0xB9,  0x0A,  0x7C,  0xFC,  0x42,  0x7C,  0xAC,  0x4B,  0x7C,  0x22,  0x4C,  0xC2, 	/* 17D20 */
+	0x93,  0x11,  0x0F,  0xFE,  0x11,  0x01,  0xBC,  0xE4,  0x82,  0x7C,  0xFD,  0x42,  0x7C,  0x75,  0x46,  0xFC, 	/* 17D30 */
+	0xA5,  0x42,  0xAA,  0x96,  0x11,  0x0F,  0xFE,  0x78,  0x84,  0xBE,  0x79,  0x44,  0x3E,  0xB8,  0x82,  0xC8, 	/* 17D40 */
+	0xFF,  0xE1,  0xF0,  0xE4,  0xE0,  0x40,  0x97,  0x11,  0x0F,  0xFE,  0x79,  0x04,  0xFE,  0x7A,  0x47,  0x7E, 	/* 17D50 */
+	0x68,  0x8B,  0xC8,  0xFF,  0xF1,  0xF0,  0xE4,  0xE0,  0x40,  0x9A,  0x11,  0x0F,  0xFE,  0x11,  0x03,  0xC4, 	/* 17D60 */
+	0x52,  0x8F,  0xFE,  0xA9,  0x0F,  0xFC,  0xA9,  0x0F,  0xFE,  0x51,  0x0A,  0x90,  0xA2,  0x11,  0x0F,  0xFE, 	/* 17D70 */
+	0x11,  0x07,  0xDE,  0x29,  0x0F,  0xFC,  0x48,  0x47,  0xBC,  0x4A,  0x07,  0xBC,  0x4A,  0x25,  0x9E,  0xAD, 	/* 17D80 */
+	0x11,  0x0F,  0xFE,  0x4A,  0x47,  0xBC,  0x4A,  0x47,  0xBC,  0x44,  0x45,  0xF4,  0x55,  0x45,  0xF4,  0x4E, 	/* 17D90 */
+	0x45,  0x5C,  0xAF,  0x11,  0x0F,  0xFE,  0x51,  0x02,  0xF8,  0x88,  0x84,  0xFE,  0x0A,  0xA5,  0x52,  0x80, 	/* 17DA0 */
+	0xC7,  0xFC,  0x4A,  0x4F,  0xFE,  0xB0,  0x11,  0x0F,  0xFE,  0x14,  0x42,  0x7C,  0xD4,  0x42,  0x7C,  0x4F, 	/* 17DB0 */
+	0xEF,  0xAA,  0x2F,  0xEB,  0x24,  0xA9,  0x82,  0x66,  0xBF,  0x11,  0x0F,  0xFE,  0x11,  0x07,  0xFC,  0x4A, 	/* 17DC0 */
+	0x47,  0xFC,  0x52,  0x42,  0x7E,  0xFC,  0x83,  0x7E,  0xAC,  0x8A,  0x7E,  0x8D,  0x04,  0x00,  0x7C,  0x04, 	/* 17DD0 */
+	0x07,  0xFE,  0x44,  0x44,  0x40,  0x45,  0xC4,  0xE0,  0x74,  0x04,  0x42,  0x44,  0x28,  0x3E,  0x8E,  0x04, 	/* 17DE0 */
+	0x00,  0x78,  0x04,  0x03,  0xFE,  0x28,  0x43,  0xF8,  0x28,  0x02,  0x7C,  0x25,  0x04,  0x52,  0x49,  0x29, 	/* 17DF0 */
+	0x0E,  0x90,  0x04,  0x00,  0x7C,  0x04,  0x07,  0xFE,  0x44,  0x25,  0xF8,  0x44,  0x45,  0xFC,  0x50,  0x05, 	/* 17E00 */
+	0xFC,  0x90,  0x01,  0xFC,  0x94,  0x07,  0x80,  0x40,  0x3F,  0xE2,  0x44,  0x27,  0x83,  0xC2,  0x23,  0xE2, 	/* 17E10 */
+	0x20,  0x3F,  0xE4,  0x88,  0x47,  0x0B,  0x8E,  0x95,  0x07,  0x80,  0x40,  0x7F,  0xE4,  0x80,  0x5F,  0xC4, 	/* 17E20 */
+	0x80,  0x5D,  0xC5,  0x54,  0x55,  0x4A,  0xA6,  0x96,  0x06,  0x1F,  0x9A,  0x04,  0x00,  0x78,  0x04,  0x07, 	/* 17E30 */
+	0xFE,  0x48,  0x27,  0xF8,  0x48,  0x44,  0x7C,  0x6A,  0x85,  0xB0,  0x8A,  0x07,  0xFE,  0x9C,  0x04,  0x00, 	/* 17E40 */
+	0x78,  0x7F,  0xE5,  0xC8,  0x47,  0x85,  0xFC,  0x52,  0x45,  0xFC,  0x52,  0x47,  0xFE,  0x44,  0x29,  0x8C, 	/* 17E50 */
+	0x9E,  0x04,  0x00,  0x78,  0x7F,  0xE4,  0x44,  0x5F,  0xC6,  0x88,  0x6F,  0x87,  0xF0,  0x41,  0x07,  0xFE, 	/* 17E60 */
+	0x88,  0x8B,  0x04,  0x9F,  0x01,  0x07,  0x9E,  0x49,  0x07,  0xBE,  0x02,  0x8F,  0xBE,  0x22,  0x83,  0xAE, 	/* 17E70 */
+	0x4B,  0x40,  0xB4,  0x15,  0x46,  0xA6,  0xA7,  0x20,  0x03,  0xDE,  0x20,  0x87,  0xC8,  0x53,  0xF7,  0xC8, 	/* 17E80 */
+	0x51,  0x07,  0xDE,  0x69,  0x27,  0xC2,  0xA8,  0x23,  0xCC,  0xAB,  0x04,  0x00,  0x40,  0x04,  0x07,  0xF8, 	/* 17E90 */
+	0x44,  0x84,  0x48,  0x7F,  0x80,  0x40,  0x04,  0x80,  0x44,  0x07,  0xEF,  0x82,  0xB1,  0x00,  0x07,  0xF8, 	/* 17EA0 */
+	0x02,  0x87,  0xC8,  0x08,  0x87,  0xE8,  0x4A,  0x87,  0xE8,  0x0A,  0xA0,  0x96,  0x1E,  0xEE,  0x0A,  0xB9, 	/* 17EB0 */
+	0x20,  0x02,  0x7E,  0x21,  0x0F,  0x90,  0xA9,  0x0A,  0x90,  0xA9,  0x0F,  0x90,  0x31,  0x02,  0x90,  0x3F, 	/* 17EC0 */
+	0xEC,  0x80,  0xBB,  0x20,  0x82,  0x08,  0xF8,  0x8A,  0xFE,  0xAA,  0x0F,  0xA0,  0x22,  0x03,  0x20,  0x2A, 	/* 17ED0 */
+	0x03,  0xA0,  0xC5,  0xE0,  0x40,  0x8A,  0x21,  0x02,  0x10,  0x2F,  0xEF,  0xA4,  0xAA,  0x4A,  0xA8,  0xF9, 	/* 17EE0 */
+	0x83,  0x10,  0x29,  0x83,  0xA8,  0xC4,  0x40,  0x82,  0x8B,  0x21,  0x82,  0x08,  0x23,  0xEF,  0xAA,  0xAA, 	/* 17EF0 */
+	0xAA,  0xAA,  0xFB,  0x62,  0x36,  0x32,  0x22,  0xA2,  0x3A,  0x2C,  0x66,  0x8C,  0x21,  0x02,  0x10,  0x2F, 	/* 17F00 */
+	0xEF,  0x90,  0xA9,  0x0A,  0xFC,  0xF9,  0x02,  0x10,  0x37,  0xE2,  0x90,  0x39,  0x0C,  0x50,  0x93,  0x20, 	/* 17F10 */
+	0x22,  0x7A,  0x20,  0xAF,  0xBA,  0xAA,  0x2A,  0xA2,  0xFB,  0xA2,  0x0A,  0x30,  0xA2,  0x8A,  0x3C,  0xAC, 	/* 17F20 */
+	0x72,  0x95,  0x00,  0x0F,  0xFE,  0x04,  0x07,  0xFC,  0x0A,  0x03,  0x58,  0xFF,  0xE2,  0x48,  0x3F,  0x80, 	/* 17F30 */
+	0x44,  0x07,  0xEF,  0x82,  0xA3,  0x21,  0xC2,  0x04,  0x22,  0x4F,  0xA4,  0xAA,  0x2A,  0xAA,  0xFC,  0x92, 	/* 17F40 */
+	0x10,  0x31,  0x82,  0xA4,  0x3A,  0xEC,  0x72,  0xA4,  0x7F,  0xE1,  0x24,  0x49,  0x82,  0x70,  0x19,  0xCE, 	/* 17F50 */
+	0x43,  0x3F,  0x82,  0x48,  0x3F,  0x80,  0x48,  0x07,  0x4F,  0x82,  0xA9,  0x04,  0x04,  0x44,  0x7F,  0xC1, 	/* 17F60 */
+	0x00,  0xFF,  0xE0,  0x40,  0x7F,  0xC4,  0x44,  0x7F,  0xC0,  0x48,  0x07,  0xCF,  0x82,  0xAA,  0x20,  0x42, 	/* 17F70 */
+	0x24,  0x21,  0x4F,  0x84,  0xAC,  0x4A,  0xA4,  0xF8,  0x42,  0x0F,  0x37,  0x42,  0x84,  0x38,  0x4C,  0x44, 	/* 17F80 */
+	0xAB,  0x21,  0x02,  0x10,  0x23,  0xEF,  0xC2,  0xAB,  0xAA,  0xAA,  0xFA,  0xA2,  0x3A,  0x32,  0xC2,  0xA0, 	/* 17F90 */
+	0x3A,  0x2C,  0x5E,  0xAF,  0x20,  0x42,  0x08,  0x23,  0x0F,  0xA0,  0xAB,  0xEA,  0xA4,  0xFA,  0x42,  0x24, 	/* 17FA0 */
+	0x32,  0x42,  0xA4,  0x3A,  0x4C,  0x7E,  0xB0,  0x20,  0x82,  0x08,  0x20,  0x8F,  0xBE,  0xAA,  0xAA,  0xAA, 	/* 17FB0 */
+	0xFA,  0xA2,  0x3E,  0x32,  0xA2,  0xAA,  0x3A,  0xAE,  0x7E,  0xB6,  0x22,  0x42,  0x24,  0x22,  0x4F,  0xFE, 	/* 17FC0 */
+	0xAA,  0x4A,  0xA4,  0xFA,  0x42,  0x3C,  0x32,  0x42,  0xA4,  0x3A,  0x4C,  0x7C,  0x84,  0x21,  0x02,  0x10, 	/* 17FD0 */
+	0x21,  0x0F,  0xFE,  0xA9,  0x0A,  0x90,  0xF9,  0x02,  0x3C,  0x32,  0x42,  0xA4,  0x3A,  0x4C,  0x7C,  0x86, 	/* 17FE0 */
+	0x20,  0x02,  0x3C,  0xFA,  0x4A,  0xA4,  0xAB,  0xCF,  0xA4,  0xA2,  0x42,  0x3C,  0x2A,  0x43,  0xA4,  0xCA, 	/* 17FF0 */
+	0x40,  0x7E,  0x87,  0x21,  0x02,  0x10,  0x27,  0xEF,  0xC2,  0xAC,  0x2A,  0xA0,  0xFA,  0xCA,  0x30,  0x32, 	/* 18000 */
+	0x02,  0xA2,  0x3A,  0x2C,  0x9E,  0x89,  0x21,  0x02,  0x10,  0x22,  0x8F,  0xA4,  0xAF,  0xEA,  0x81,  0xFF, 	/* 18010 */
+	0xE2,  0x12,  0x31,  0x22,  0x9C,  0x39,  0x0C,  0x50,  0x8B,  0x00,  0x07,  0xFE,  0x04,  0x02,  0x7C,  0x3C, 	/* 18020 */
+	0x04,  0x7E,  0x84,  0x03,  0xF8,  0x24,  0x83,  0xF8,  0x05,  0xCF,  0xE2,  0x8D,  0x48,  0x82,  0x48,  0x25, 	/* 18030 */
+	0x0F,  0xFE,  0x84,  0x2B,  0xFA,  0x24,  0x82,  0x48,  0x3F,  0x80,  0x44,  0x07,  0xEF,  0x82,  0x8E,  0x20, 	/* 18040 */
+	0x02,  0x3E,  0x22,  0x0F,  0xBE,  0xAA,  0x8A,  0xA8,  0xFA,  0xE3,  0x2A,  0x2B,  0x23,  0xD2,  0xCA,  0x20, 	/* 18050 */
+	0x4C,  0x94,  0x20,  0x02,  0x7E,  0x24,  0x2F,  0xC2,  0xAF,  0xAA,  0xEA,  0xFE,  0xA2,  0x6A,  0x37,  0xA2, 	/* 18060 */
+	0xC2,  0x3C,  0x2C,  0x7E,  0x99,  0x21,  0x02,  0x10,  0x27,  0xCF,  0x90,  0xA9,  0x0A,  0xFE,  0xF9,  0x02, 	/* 18070 */
+	0x10,  0x37,  0xC2,  0x90,  0x39,  0x0C,  0x7E,  0x9B,  0x21,  0x02,  0x50,  0x25,  0x0F,  0xFC,  0xA9,  0x0A, 	/* 18080 */
+	0x90,  0xFF,  0xE2,  0x38,  0x2D,  0x43,  0x92,  0xC9,  0x00,  0x10,  0x9E,  0x20,  0xC2,  0x70,  0x21,  0x0F, 	/* 18090 */
+	0x90,  0xAF,  0xEA,  0x90,  0xF9,  0x02,  0x3C,  0x32,  0x42,  0xA4,  0x3A,  0x4C,  0x7C,  0x9F,  0x21,  0x02, 	/* 180A0 */
+	0x10,  0x27,  0xEF,  0xA8,  0xAA,  0x4A,  0xC2,  0xFA,  0x42,  0x14,  0x28,  0x83,  0x98,  0xCA,  0x40,  0x42, 	/* 180B0 */
+	0xA4,  0x21,  0x02,  0x10,  0x22,  0x8F,  0xC4,  0xAF,  0xEA,  0x80,  0xF8,  0x02,  0x7C,  0x34,  0x42,  0xC4, 	/* 180C0 */
+	0x3C,  0x4C,  0x7C,  0xA9,  0x07,  0x8F,  0x48,  0x26,  0x83,  0x58,  0xE4,  0xA0,  0x86,  0x04,  0x07,  0xF8, 	/* 180D0 */
+	0x44,  0x87,  0xF8,  0x04,  0x4F,  0xFA,  0xAC,  0x11,  0x01,  0x10,  0x7F,  0xC1,  0x10,  0xFF,  0xE2,  0x48, 	/* 180E0 */
+	0x7F,  0xCA,  0x4A,  0x3F,  0x80,  0x44,  0x07,  0xCF,  0x82,  0xAD,  0x20,  0x02,  0x7E,  0x21,  0x8F,  0x94, 	/* 180F0 */
+	0xAA,  0x6A,  0xFA,  0xF8,  0xA2,  0x08,  0x33,  0xE2,  0x88,  0x38,  0x8C,  0x7F,  0xAE,  0x04,  0x0F,  0xFE, 	/* 18100 */
+	0x2A,  0x84,  0xA4,  0x92,  0x42,  0x60,  0x3F,  0x82,  0x48,  0x3F,  0x80,  0x48,  0x07,  0xCF,  0x82,  0xAF, 	/* 18110 */
+	0x21,  0x02,  0x10,  0xFF,  0xCA,  0x90,  0xAF,  0xEF,  0xA0,  0x24,  0x02,  0xA6,  0x2B,  0x83,  0xA0,  0xCA, 	/* 18120 */
+	0x20,  0x1E,  0xB8,  0x24,  0xA2,  0x2A,  0xFA,  0xCA,  0x88,  0xAB,  0xEF,  0xA2,  0x23,  0xE3,  0x22,  0x2B, 	/* 18130 */
+	0xE3,  0xA2,  0xC6,  0x20,  0x26,  0xB9,  0x20,  0x02,  0x7E,  0x21,  0x4F,  0xBE,  0xAA,  0xAA,  0xAA,  0xFB, 	/* 18140 */
+	0xE2,  0x2A,  0x33,  0xE2,  0xAA,  0x3A,  0xAC,  0x66,  0xBB,  0x22,  0x82,  0x28,  0x22,  0x4F,  0xC2,  0xAB, 	/* 18150 */
+	0xCA,  0xA4,  0xFA,  0x42,  0x3C,  0x31,  0x82,  0xAA,  0x3A,  0xAC,  0x46,  0xBE,  0x02,  0x82,  0xCC,  0x24, 	/* 18160 */
+	0xAF,  0xC8,  0xAF,  0xEA,  0xC8,  0xFE,  0xA2,  0x4A,  0x2C,  0x43,  0xCC,  0xC5,  0x60,  0xC2,  0x80,  0x7F, 	/* 18170 */
+	0xE4,  0x92,  0x7F,  0xE1,  0x00,  0x3F,  0xE4,  0x82,  0xBF,  0x22,  0x92,  0x3F,  0x20,  0x92,  0x0F,  0xAF, 	/* 18180 */
+	0x0C,  0x82,  0x21,  0x02,  0x1E,  0xFA,  0x2A,  0xDC,  0xA9,  0x4A,  0xEB,  0xF8,  0x83,  0x3E,  0x28,  0x83, 	/* 18190 */
+	0xFF,  0xC4,  0x80,  0x08,  0x83,  0x7F,  0xC4,  0x00,  0x7F,  0xE5,  0x4C,  0x53,  0x07,  0x8E,  0x44,  0x0B, 	/* 181A0 */
+	0xF8,  0x24,  0x83,  0xF8,  0x04,  0x4F,  0xFA,  0x86,  0x20,  0x02,  0x3C,  0x22,  0x4F,  0xA4,  0xAB,  0xCA, 	/* 181B0 */
+	0xA4,  0xFB,  0xC2,  0x24,  0x33,  0xC2,  0x98,  0x3A,  0xAC,  0x46,  0x88,  0x21,  0xC2,  0x54,  0x25,  0x4F, 	/* 181C0 */
+	0xDC,  0xAC,  0x0A,  0xFC,  0xF9,  0x42,  0x14,  0x2F,  0xE3,  0x90,  0xEA,  0x80,  0x44,  0x89,  0x20,  0x62, 	/* 181D0 */
+	0x78,  0x22,  0xCF,  0xAA,  0xAC,  0x2A,  0xBC,  0xF8,  0x42,  0x08,  0x37,  0xE2,  0x88,  0x38,  0x8C,  0x58, 	/* 181E0 */
+	0x8A,  0x21,  0x22,  0x6A,  0x22,  0xAF,  0xAA,  0xAF,  0xAA,  0xAA,  0xFB,  0xA2,  0x6A,  0x36,  0xA2,  0xA2, 	/* 181F0 */
+	0x3A,  0x2C,  0x66,  0x8D,  0x21,  0x02,  0x18,  0x22,  0x4F,  0xC2,  0xAF,  0xDA,  0x90,  0xFF,  0xE2,  0x10, 	/* 18200 */
+	0x33,  0x42,  0xD2,  0x39,  0x2C,  0xB0,  0x91,  0x70,  0x62,  0x78,  0xF0,  0x85,  0x2E,  0x3A,  0x84,  0x7F, 	/* 18210 */
+	0x84,  0x03,  0xF8,  0x24,  0x83,  0xF8,  0x04,  0x4F,  0xFA,  0x92,  0x20,  0x22,  0x7C,  0xFA,  0x4A,  0xA4, 	/* 18220 */
+	0xAD,  0x4F,  0xF6,  0x23,  0x43,  0x74,  0x2B,  0x43,  0xDF,  0xC4,  0x80,  0x87,  0x98,  0x24,  0x02,  0x4E, 	/* 18230 */
+	0x27,  0xAF,  0xAA,  0xAA,  0xAA,  0xAA,  0xFF,  0xA2,  0x2A,  0x2A,  0xA3,  0xAA,  0xC5,  0xE0,  0x88,  0x9A, 	/* 18240 */
+	0x09,  0x0F,  0x9E,  0x09,  0x07,  0x9C,  0x09,  0x0F,  0x1E,  0x25,  0x03,  0xF8,  0x24,  0x83,  0xF8,  0x04, 	/* 18250 */
+	0x4F,  0xFA,  0x9C,  0x04,  0x0F,  0xFE,  0x92,  0x25,  0x54,  0x4F,  0x29,  0x42,  0x3F,  0x82,  0x48,  0x3F, 	/* 18260 */
+	0x80,  0x44,  0x07,  0xEF,  0x82,  0xA5,  0x22,  0x22,  0x2C,  0x22,  0x8F,  0xF8,  0xAA,  0xFA,  0xEA,  0xFF, 	/* 18270 */
+	0xA2,  0xAA,  0x32,  0xA2,  0xAA,  0x3B,  0x2C,  0x62,  0xA9,  0x20,  0x02,  0x3E,  0xFA,  0xAA,  0xBE,  0xAA, 	/* 18280 */
+	0xAF,  0xBE,  0x22,  0xA3,  0x3E,  0x2A,  0x63,  0xBE,  0xC4,  0x20,  0x86,  0xB4,  0x20,  0x02,  0x3C,  0x22, 	/* 18290 */
+	0x4F,  0xBC,  0xAA,  0x4A,  0xBC,  0xF9,  0x02,  0x3E,  0x36,  0xA2,  0xAA,  0x3D,  0x2C,  0x4C,  0xB7,  0x21, 	/* 182A0 */
+	0x02,  0x54,  0x2F,  0xEF,  0x90,  0xAF,  0xEA,  0xA8,  0xFC,  0x42,  0x7A,  0x34,  0x82,  0xF8,  0x34,  0x4C, 	/* 182B0 */
+	0x3C,  0xBB,  0x21,  0x02,  0x7C,  0x21,  0x0F,  0xFC,  0xA9,  0x0A,  0xFE,  0xFD,  0x42,  0x54,  0x37,  0xC2, 	/* 182C0 */
+	0xC4,  0x3C,  0x4C,  0x4C,  0xBF,  0x21,  0x02,  0x10,  0x2F,  0xEF,  0x82,  0xAE,  0xEA,  0xAA,  0xFE,  0xA2, 	/* 182D0 */
+	0x2E,  0x2A,  0x83,  0x48,  0xE4,  0xA0,  0x86,  0x89,  0x21,  0x12,  0x49,  0x22,  0x2F,  0xBE,  0xAA,  0xAA, 	/* 182E0 */
+	0xBE,  0xFA,  0xA2,  0x3E,  0x30,  0x82,  0xFF,  0x38,  0x8C,  0x48,  0x8B,  0x21,  0x12,  0x49,  0xFA,  0x2A, 	/* 182F0 */
+	0xBE,  0xAA,  0xAF,  0xBE,  0x22,  0xA3,  0x2A,  0x2B,  0xE3,  0xEA,  0xC4,  0xA0,  0x89,  0x8C,  0x22,  0x42, 	/* 18300 */
+	0xD4,  0x24,  0xCF,  0xE4,  0xAD,  0x4A,  0xCC,  0xFE,  0x42,  0x57,  0x35,  0xC2,  0xC4,  0x3C,  0x4C,  0x44, 	/* 18310 */
+	0x8E,  0x23,  0xC2,  0x24,  0x23,  0xCF,  0xA4,  0xAB,  0xCA,  0x90,  0xFB,  0xE2,  0x6A,  0x33,  0x62,  0xBE, 	/* 18320 */
+	0x38,  0x2C,  0x4C,  0x93,  0x21,  0x02,  0x18,  0x22,  0x4F,  0xFE,  0xA8,  0x1A,  0xFA,  0xFD,  0xA2,  0x7A, 	/* 18330 */
+	0x35,  0x42,  0xF4,  0x3D,  0xAC,  0x5A,  0x95,  0x21,  0x03,  0x10,  0x49,  0x0B,  0x7C,  0x4D,  0x47,  0xD4, 	/* 18340 */
+	0x4F,  0xC7,  0x90,  0x51,  0x44,  0x94,  0x75,  0xEC,  0x72,  0x97,  0x21,  0x02,  0x3C,  0x22,  0x4F,  0xBC, 	/* 18350 */
+	0xAA,  0x4A,  0xBC,  0xF8,  0x02,  0x7E,  0x31,  0x02,  0xBC,  0x39,  0x0C,  0x7E,  0x99,  0x27,  0xE2,  0x00, 	/* 18360 */
+	0xFB,  0xEA,  0xA2,  0xAB,  0xEF,  0xA0,  0x23,  0xF3,  0x35,  0x2B,  0xF3,  0xD5,  0xC5,  0x50,  0x93,  0x9F, 	/* 18370 */
+	0x20,  0x02,  0x7E,  0x25,  0x2F,  0xFE,  0xAD,  0x2A,  0xFE,  0xFA,  0x42,  0x3C,  0x32,  0x42,  0xBC,  0x3A, 	/* 18380 */
+	0x4C,  0x6C,  0xA0,  0x27,  0xE2,  0x00,  0x23,  0xCF,  0xA4,  0xAB,  0xCA,  0x80,  0xFF,  0xE2,  0x52,  0x37, 	/* 18390 */
+	0xE2,  0xD2,  0x3D,  0x2C,  0x7E,  0xA3,  0x22,  0x42,  0x24,  0x22,  0x7F,  0xF8,  0xAA,  0xEA,  0xA2,  0xFB, 	/* 183A0 */
+	0xC2,  0x2F,  0x32,  0xA2,  0xCA,  0x38,  0xAC,  0x36,  0xA6,  0x20,  0x02,  0x7E,  0x25,  0x2F,  0xF6,  0xAC, 	/* 183B0 */
+	0x0A,  0xCE,  0xFF,  0x22,  0x4A,  0x34,  0x42,  0xF4,  0x3C,  0xAC,  0x52,  0xA8,  0x00,  0x07,  0xF0,  0x09, 	/* 183C0 */
+	0x07,  0xF2,  0x08,  0xA1,  0x06,  0x20,  0x8F,  0xBE,  0xAA,  0xAF,  0xBE,  0x28,  0xAF,  0x7D,  0xAA,  0x20, 	/* 183D0 */
+	0x02,  0x3C,  0xFA,  0x4A,  0xBC,  0xAA,  0x4F,  0xFF,  0x22,  0x03,  0x7E,  0x2A,  0xA3,  0xCA,  0xC5,  0x20, 	/* 183E0 */
+	0x0C,  0xAE,  0x22,  0x02,  0x3E,  0x24,  0x0F,  0xBC,  0xAA,  0x4A,  0xBC,  0xFA,  0x42,  0x3C,  0x31,  0xC2, 	/* 183F0 */
+	0xE4,  0x39,  0x8C,  0x66,  0xB4,  0x22,  0x02,  0x2E,  0x27,  0xAF,  0xAA,  0xAA,  0xEA,  0xAA,  0xFF,  0xA2, 	/* 18400 */
+	0x5E,  0x35,  0xA2,  0xFA,  0x39,  0x2C,  0x66,  0xB6,  0x25,  0x42,  0x54,  0xFF,  0xEA,  0xD4,  0xAD,  0xCF, 	/* 18410 */
+	0xC0,  0x27,  0xE3,  0x10,  0x2F,  0xE3,  0xB4,  0xCD,  0x20,  0x10,  0xB8,  0x23,  0xC2,  0x24,  0x23,  0xCF, 	/* 18420 */
+	0xB4,  0xAB,  0x4A,  0xFE,  0xFC,  0x22,  0x7A,  0x36,  0xA2,  0xEA,  0x3F,  0xAC,  0x46,  0xBF,  0x27,  0xC2, 	/* 18430 */
+	0x54,  0x27,  0xCF,  0xD4,  0xAF,  0xEA,  0xD2,  0xFF,  0xE2,  0x52,  0x37,  0xE2,  0x90,  0x39,  0x2C,  0x4E, 	/* 18440 */
+	0x82,  0x22,  0x02,  0x2E,  0x2F,  0xAF,  0x9A,  0xAF,  0xCA,  0x9A,  0xFF,  0xA2,  0xDA,  0x2A,  0xA3,  0xEE, 	/* 18450 */
+	0xC9,  0x80,  0x08,  0x8D,  0xFC,  0x80,  0x08,  0x78,  0x84,  0xBE,  0x7A,  0xA0,  0x2A,  0xFF,  0xEB,  0x48, 	/* 18460 */
+	0xDC,  0xCB,  0xCA,  0x94,  0xE9,  0x79,  0x9F,  0x20,  0x02,  0x7E,  0x24,  0x2F,  0xBC,  0xAA,  0x4A,  0xBC, 	/* 18470 */
+	0xFA,  0x42,  0x3C,  0x31,  0x02,  0xFE,  0x3A,  0x4C,  0x42,  0xA2,  0x11,  0x05,  0x54,  0x2A,  0x84,  0x44, 	/* 18480 */
+	0xFF,  0xE8,  0x42,  0xBF,  0xA2,  0x48,  0x3F,  0x80,  0x48,  0x07,  0xCF,  0x82,  0xAB,  0x11,  0x07,  0xDE, 	/* 18490 */
+	0x12,  0x4F,  0xD8,  0x55,  0x49,  0x22,  0x7F,  0x84,  0x48,  0x7F,  0x80,  0x48,  0x07,  0xCF,  0x82,  0xAF, 	/* 184A0 */
+	0x12,  0x07,  0xBE,  0x12,  0x4F,  0xD4,  0x28,  0x84,  0x94,  0x1A,  0x27,  0xFC,  0x44,  0x47,  0xFC,  0x04, 	/* 184B0 */
+	0x4F,  0xFA,  0xB3,  0x29,  0x22,  0x54,  0x2F,  0xEF,  0x82,  0xAB,  0xCA,  0xA4,  0xFB,  0xC2,  0x10,  0x37, 	/* 184C0 */
+	0xC2,  0x90,  0x39,  0x0C,  0xFE,  0xBA,  0x20,  0x02,  0x3E,  0x22,  0xAF,  0xBE,  0xAA,  0xAA,  0xBE,  0xF8, 	/* 184D0 */
+	0x82,  0x34,  0x37,  0xE2,  0xAC,  0x3C,  0xAC,  0x48,  0xBB,  0x27,  0xC2,  0x54,  0x2F,  0xEF,  0x54,  0xAF, 	/* 184E0 */
+	0xEA,  0x92,  0xFF,  0xE2,  0x20,  0x37,  0xE2,  0xA4,  0x39,  0x8C,  0x64,  0xBD,  0x0F,  0x81,  0x90,  0x66, 	/* 184F0 */
+	0x01,  0x98,  0xE2,  0x60,  0x90,  0x26,  0x0F,  0xBE,  0xAA,  0xAF,  0xBE,  0x28,  0xAF,  0x7D,  0x80,  0x21, 	/* 18500 */
+	0x02,  0xFE,  0x21,  0x0F,  0xAC,  0xAD,  0x2A,  0xAC,  0xFF,  0xA2,  0x10,  0x37,  0xE2,  0x90,  0x39,  0x0C, 	/* 18510 */
+	0x90,  0x84,  0x22,  0x0F,  0xF8,  0x52,  0x8F,  0xE8,  0x25,  0x8F,  0x8A,  0x24,  0x67,  0xF8,  0x44,  0x87, 	/* 18520 */
+	0xF8,  0x04,  0x4F,  0xFA,  0x86,  0x22,  0x82,  0xFE,  0x22,  0x8F,  0xBC,  0xAA,  0x4A,  0xBC,  0xFA,  0x42, 	/* 18530 */
+	0x3C,  0x31,  0x02,  0xFE,  0x3A,  0x4C,  0x42,  0x87,  0x11,  0x0F,  0xFE,  0x20,  0x83,  0xF8,  0x20,  0x8F, 	/* 18540 */
+	0xFE,  0x24,  0x87,  0xFC,  0xA4,  0xA3,  0xF8,  0x04,  0xCF,  0xF2,  0x8B,  0x20,  0xC2,  0x70,  0x25,  0x2F, 	/* 18550 */
+	0xB4,  0xAF,  0xEA,  0x98,  0xFB,  0x42,  0x52,  0x31,  0x02,  0xAA,  0x3D,  0x2C,  0x8E,  0x90,  0x29,  0x22, 	/* 18560 */
+	0x54,  0x2F,  0xEF,  0x82,  0xAB,  0xCA,  0xA4,  0xFB,  0xC2,  0x10,  0x37,  0xE2,  0xD2,  0x3D,  0x4C,  0x50, 	/* 18570 */
+	0x92,  0x22,  0x82,  0x7C,  0x22,  0x8F,  0xFE,  0xAA,  0x8A,  0xC4,  0xFA,  0xA2,  0x28,  0x37,  0xE2,  0xA8, 	/* 18580 */
+	0x3C,  0x8C,  0x88,  0xA0,  0x20,  0xC2,  0xF0,  0x25,  0x2F,  0xB4,  0xAF,  0xEA,  0xB4,  0xFD,  0x22,  0x7D, 	/* 18590 */
+	0x35,  0x42,  0xFC,  0x3D,  0x4C,  0x7C,  0xAF,  0x23,  0xC2,  0x10,  0x27,  0xEF,  0xA4,  0xAF,  0xEA,  0xA4, 	/* 185A0 */
+	0xFF,  0xE2,  0x00,  0x37,  0xE2,  0xA8,  0x3A,  0xAC,  0x46,  0xB2,  0x04,  0x07,  0xF8,  0x44,  0x87,  0xF8, 	/* 185B0 */
+	0x04,  0x4F,  0xFA,  0x20,  0x8F,  0xBE,  0xAA,  0xAF,  0xBE,  0x28,  0xAF,  0x7D,  0xB6,  0x2F,  0x02,  0xAE, 	/* 185C0 */
+	0x2E,  0xAF,  0xAA,  0xAE,  0xAA,  0xAE,  0xFA,  0x02,  0x7C,  0x31,  0x02,  0xFC,  0x39,  0x0C,  0x7E,  0xB7, 	/* 185D0 */
+	0x29,  0x22,  0x54,  0x2F,  0xEF,  0x82,  0xAB,  0xCA,  0xA4,  0xFB,  0xC2,  0x7E,  0x34,  0xA2,  0xFE,  0x3C, 	/* 185E0 */
+	0xAC,  0x7E,  0xB9,  0x3B,  0xED,  0x0A,  0x7D,  0x45,  0x7E,  0x7C,  0x84,  0x7E,  0x8C,  0x83,  0xF8,  0x24, 	/* 185F0 */
+	0x83,  0xF8,  0x04,  0xCF,  0xF2,  0xBB,  0x22,  0x82,  0xFE,  0x21,  0x0F,  0xFE,  0xA9,  0x0A,  0xFE,  0xFC, 	/* 18600 */
+	0xA2,  0xFF,  0x24,  0xC2,  0xEA,  0x35,  0x6C,  0xC2,  0xBE,  0x23,  0x82,  0x50,  0x2F,  0xEF,  0x98,  0xAE, 	/* 18610 */
+	0x6A,  0xB8,  0xF8,  0x02,  0xFE,  0x28,  0x03,  0xBC,  0xCA,  0x41,  0x3C,  0x85,  0x27,  0xC2,  0x54,  0x27, 	/* 18620 */
+	0xCF,  0x28,  0xAE,  0xEA,  0xAA,  0xFE,  0xE2,  0xAA,  0x2E,  0xE3,  0x28,  0x3A,  0x2C,  0x9E,  0x8D,  0x20, 	/* 18630 */
+	0x42,  0xF4,  0x29,  0x4F,  0xF7,  0xA9,  0xDA,  0xF6,  0xF4,  0x42,  0xF4,  0x29,  0x42,  0xFA,  0x39,  0x2E, 	/* 18640 */
+	0x61,  0x8E,  0x22,  0x82,  0xFE,  0x22,  0x8F,  0xFE,  0xAB,  0x4A,  0xD2,  0xFF,  0xD2,  0x10,  0x32,  0x42, 	/* 18650 */
+	0xFE,  0x3A,  0x4C,  0x44,  0x8F,  0x24,  0x02,  0x7E,  0x2A,  0xAF,  0x4A,  0xAF,  0x6A,  0xB0,  0xFF,  0xE2, 	/* 18660 */
+	0xB4,  0x2F,  0x43,  0x9E,  0xC9,  0x41,  0x34,  0x91,  0x25,  0xA2,  0xEC,  0x24,  0x8F,  0xB4,  0xAF,  0xEA, 	/* 18670 */
+	0x92,  0xF9,  0x02,  0x7E,  0x33,  0x82,  0xD4,  0x39,  0x2C,  0x50,  0x95,  0x27,  0xC2,  0x10,  0x2F,  0xEF, 	/* 18680 */
+	0x92,  0xAB,  0xAA,  0x80,  0xFF,  0xE2,  0x20,  0x37,  0xE2,  0xAA,  0x3A,  0xAC,  0x86,  0x96,  0x22,  0x82, 	/* 18690 */
+	0xFE,  0x22,  0x4F,  0xBE,  0xAE,  0x8A,  0xBE,  0xFA,  0x82,  0x3E,  0x32,  0x42,  0x98,  0x3A,  0x4C,  0xC2, 	/* 186A0 */
+	0xA1,  0x0F,  0x81,  0x10,  0xFF,  0xE1,  0xA4,  0x65,  0x81,  0xB6,  0x26,  0x8F,  0xBE,  0xAA,  0xAF,  0xBE, 	/* 186B0 */
+	0x28,  0xAF,  0x7D,  0xA2,  0x04,  0x07,  0xFC,  0x0A,  0x0F,  0xFE,  0x31,  0x8D,  0xF6,  0x11,  0x0F,  0xBE, 	/* 186C0 */
+	0xAA,  0xAF,  0xBE,  0x28,  0xAF,  0x7D,  0xA3,  0x20,  0x02,  0x7E,  0xFD,  0x4A,  0xFE,  0xAE,  0xAF,  0xFE, 	/* 186D0 */
+	0x24,  0x83,  0x7E,  0x2E,  0xA3,  0x6E,  0xCB,  0xE1,  0x22,  0xA7,  0x04,  0x07,  0xFC,  0x04,  0x0F,  0xFE, 	/* 186E0 */
+	0x9F,  0xA2,  0x88,  0x4F,  0x8F,  0xBE,  0xAA,  0xAF,  0xBE,  0x28,  0xAF,  0x7D,  0xB1,  0x04,  0x03,  0xF8, 	/* 186F0 */
+	0x24,  0xC3,  0xFA,  0xFB,  0xEA,  0xAA,  0xFB,  0xE2,  0x8A,  0xF7,  0xD7,  0xFC,  0x4A,  0x4F,  0xFE,  0xB6, 	/* 18700 */
+	0xFB,  0xE5,  0x14,  0xFB,  0xE5,  0x14,  0x9A,  0x63,  0xF8,  0x20,  0x8F,  0xFE,  0xAA,  0xAF,  0xBE,  0x24, 	/* 18710 */
+	0xAF,  0xBD,  0xB9,  0x04,  0x07,  0xFC,  0x24,  0x8F,  0xFE,  0x9F,  0xA2,  0x88,  0x4F,  0x8F,  0xBE,  0xAA, 	/* 18720 */
+	0xAF,  0xBE,  0x28,  0xAF,  0x7D,  0xBB,  0x46,  0x4B,  0xF2,  0x40,  0x4A,  0xEA,  0xEE,  0xE6,  0xAC,  0xDF, 	/* 18730 */
+	0x67,  0xF8,  0x44,  0x87,  0xF8,  0x04,  0x4F,  0xFA,  0x80,  0x08,  0x00,  0x80,  0x10,  0x07,  0xFC,  0x4A, 	/* 18740 */
+	0x44,  0xA4,  0x4A,  0x44,  0xA4,  0x4A,  0x44,  0xA4,  0xFF,  0xE0,  0x00,  0x82,  0x20,  0x04,  0x7E,  0xF9, 	/* 18750 */
+	0x2A,  0x92,  0xAD,  0x2A,  0xB2,  0xA9,  0xEA,  0x93,  0xBD,  0x2E,  0x12,  0x02,  0x20,  0x4C,  0x84,  0x10, 	/* 18760 */
+	0x02,  0x3C,  0x7D,  0x45,  0x54,  0x55,  0x45,  0x54,  0x57,  0xE5,  0x64,  0x5E,  0x4F,  0x24,  0x02,  0x40, 	/* 18770 */
+	0xFE,  0x86,  0x08,  0x07,  0xFC,  0x4A,  0x44,  0xA4,  0xFF,  0xE1,  0x20,  0x24,  0x4C,  0xE8,  0x15,  0x02, 	/* 18780 */
+	0x48,  0xC4,  0x60,  0x40,  0x8C,  0x20,  0x02,  0x7C,  0x40,  0x05,  0x00,  0x9F,  0xE2,  0x08,  0x20,  0x86, 	/* 18790 */
+	0x08,  0xA0,  0x82,  0x08,  0x20,  0x82,  0x18,  0x8D,  0x28,  0x02,  0x5E,  0x40,  0x0A,  0x80,  0x25,  0xE4, 	/* 187A0 */
+	0x04,  0xC0,  0x44,  0x24,  0x44,  0x44,  0x44,  0x48,  0x44,  0x8C,  0x92,  0x24,  0x02,  0x4E,  0x5F,  0x0A, 	/* 187B0 */
+	0x40,  0x25,  0xF4,  0x84,  0xDA,  0x44,  0x44,  0x4A,  0x45,  0x34,  0x7D,  0x44,  0x0C,  0x93,  0x24,  0x02, 	/* 187C0 */
+	0x6E,  0x45,  0x0B,  0xFE,  0x24,  0x44,  0x64,  0xD6,  0x45,  0x54,  0x55,  0x46,  0x44,  0x44,  0x44,  0x4C, 	/* 187D0 */
+	0x97,  0x24,  0x02,  0x5E,  0x5E,  0x0A,  0x5E,  0x24,  0x45,  0xF4,  0x44,  0x4D,  0xF4,  0x44,  0x44,  0x74, 	/* 187E0 */
+	0x58,  0x44,  0x0C,  0x99,  0x20,  0x03,  0xFE,  0x48,  0x0B,  0xE0,  0x2A,  0xF4,  0xA4,  0x7F,  0x4C,  0x04, 	/* 187F0 */
+	0x5E,  0x45,  0x24,  0x52,  0x45,  0xEC,  0x9B,  0x28,  0x03,  0xEE,  0x4A,  0x0B,  0xF0,  0x33,  0xF5,  0xE4, 	/* 18800 */
+	0xC4,  0x45,  0xE4,  0x54,  0x47,  0xF4,  0x44,  0x44,  0x4C,  0x9D,  0x26,  0x03,  0xCE,  0x44,  0x0B,  0xF0, 	/* 18810 */
+	0x34,  0xF5,  0xF4,  0xD5,  0x45,  0xF4,  0x44,  0x45,  0xE4,  0x47,  0x45,  0xCC,  0x9E,  0x24,  0x02,  0xFE, 	/* 18820 */
+	0x45,  0x0B,  0xFF,  0x29,  0x44,  0xF4,  0x7F,  0xCC,  0x44,  0x5F,  0x45,  0x54,  0x57,  0x44,  0x4C,  0xA1, 	/* 18830 */
+	0x24,  0x02,  0xEE,  0x52,  0x09,  0xF0,  0x35,  0xE5,  0xF4,  0xD5,  0x45,  0xF4,  0x44,  0x45,  0xF4,  0x4A, 	/* 18840 */
+	0x45,  0x0C,  0xA2,  0x3F,  0x02,  0xDE,  0x7F,  0x0A,  0xDF,  0x3F,  0x45,  0x24,  0x5F,  0x4F,  0x44,  0x5F, 	/* 18850 */
+	0x45,  0x44,  0x5F,  0x45,  0x0C,  0xA3,  0x04,  0x00,  0x40,  0xFF,  0xE0,  0x80,  0x0C,  0x41,  0x44,  0x32, 	/* 18860 */
+	0x8D,  0x20,  0x11,  0x01,  0x08,  0x1C,  0x47,  0x02,  0xA8,  0x04,  0x07,  0xFC,  0x04,  0x07,  0xFC,  0x04, 	/* 18870 */
+	0x0F,  0xFE,  0x14,  0x83,  0x28,  0xD3,  0x01,  0x10,  0x1C,  0x87,  0x06,  0xAB,  0x20,  0x82,  0x08,  0xF9, 	/* 18880 */
+	0x01,  0x14,  0x22,  0x42,  0x88,  0x71,  0x2A,  0xA2,  0x24,  0x42,  0x08,  0x23,  0x02,  0xC0,  0xB0,  0x04, 	/* 18890 */
+	0x0F,  0xFE,  0x00,  0x03,  0xF8,  0x20,  0x8F,  0xFE,  0x20,  0x83,  0xF8,  0x14,  0x43,  0x28,  0xDD,  0x83, 	/* 188A0 */
+	0x06,  0xB2,  0x23,  0x02,  0x10,  0xF9,  0x01,  0x7E,  0x25,  0x22,  0xD2,  0x76,  0xAA,  0xE6,  0x24,  0x22, 	/* 188B0 */
+	0x42,  0x24,  0x22,  0x46,  0xB5,  0x20,  0x02,  0x3E,  0xFA,  0x21,  0x22,  0x22,  0x22,  0xA2,  0x73,  0xEA, 	/* 188C0 */
+	0xA2,  0x22,  0x22,  0x22,  0x22,  0x22,  0x3E,  0xB7,  0x04,  0x0F,  0xFE,  0x04,  0x07,  0xFC,  0x44,  0x47, 	/* 188D0 */
+	0xFC,  0x04,  0x00,  0x84,  0x32,  0x8D,  0x10,  0x1C,  0x83,  0x06,  0xBD,  0x20,  0xC2,  0x78,  0xF9,  0x01, 	/* 188E0 */
+	0x10,  0x21,  0x02,  0xFE,  0x71,  0x0A,  0x90,  0x21,  0x02,  0x10,  0x27,  0xC2,  0x00,  0xBE,  0x04,  0x00, 	/* 188F0 */
+	0xA0,  0x3F,  0x8C,  0x06,  0x3F,  0x80,  0x10,  0x06,  0x0F,  0xFE,  0x34,  0x4D,  0x28,  0x1D,  0x87,  0x06, 	/* 18900 */
+	0xBF,  0x21,  0x02,  0x10,  0xFA,  0x80,  0xA8,  0x14,  0x42,  0xBA,  0x70,  0x0A,  0xFC,  0x20,  0x42,  0x08, 	/* 18910 */
+	0x20,  0x82,  0x10,  0x81,  0x04,  0x07,  0xFC,  0x04,  0x0F,  0xFE,  0x00,  0x03,  0xF8,  0x20,  0x83,  0xF8, 	/* 18920 */
+	0x1A,  0x4F,  0x18,  0x1C,  0x87,  0x06,  0x82,  0x21,  0x02,  0x10,  0xFB,  0xC1,  0x14,  0x21,  0x42,  0x94, 	/* 18930 */
+	0x77,  0xEA,  0x90,  0x21,  0x82,  0x28,  0x24,  0x42,  0x82,  0x88,  0x20,  0x02,  0x3C,  0xFA,  0x42,  0xA4, 	/* 18940 */
+	0x2A,  0x45,  0xBC,  0x80,  0x0F,  0xFE,  0x14,  0x43,  0x28,  0xDD,  0x83,  0x06,  0x8B,  0x15,  0x01,  0x48, 	/* 18950 */
+	0x23,  0xE7,  0xE0,  0xA1,  0x02,  0x0A,  0x24,  0x6F,  0xFE,  0x0A,  0x43,  0x18,  0xDC,  0x83,  0x06,  0x8D, 	/* 18960 */
+	0x22,  0x02,  0x20,  0xFB,  0xE1,  0x42,  0x27,  0xA2,  0xCA,  0x74,  0xAA,  0xFA,  0x24,  0xC2,  0x40,  0x24, 	/* 18970 */
+	0x22,  0x3E,  0x92,  0x20,  0x02,  0x3C,  0xFA,  0x41,  0x24,  0x22,  0x42,  0xBC,  0x72,  0x4A,  0xA4,  0x22, 	/* 18980 */
+	0x42,  0x3C,  0x20,  0x02,  0x7E,  0x96,  0x21,  0x02,  0x10,  0xF9,  0x01,  0x7E,  0x25,  0x22,  0xD2,  0x75, 	/* 18990 */
+	0x2A,  0xFE,  0x25,  0x22,  0x52,  0x25,  0x22,  0x7E,  0x97,  0x21,  0x02,  0x10,  0xFA,  0x81,  0x4C,  0x29, 	/* 189A0 */
+	0x22,  0x60,  0x70,  0x8A,  0x32,  0x2C,  0x42,  0x08,  0x23,  0x02,  0xC0,  0x99,  0x20,  0x82,  0x10,  0xFB, 	/* 189B0 */
+	0xE1,  0x22,  0x22,  0x22,  0xA2,  0x73,  0xEA,  0xA2,  0x22,  0x22,  0x22,  0x22,  0x22,  0x3E,  0x9E,  0x04, 	/* 189C0 */
+	0x0F,  0xFE,  0x0A,  0x03,  0x18,  0xFF,  0xE2,  0x08,  0x20,  0x83,  0xF8,  0x1A,  0x4F,  0x18,  0x1C,  0x87, 	/* 189D0 */
+	0x06,  0xA2,  0x21,  0x02,  0x54,  0xFD,  0x41,  0x12,  0x2F,  0xC3,  0x10,  0x69,  0x0A,  0x7E,  0x21,  0x02, 	/* 189E0 */
+	0x10,  0x21,  0x02,  0x10,  0xA4,  0x04,  0x0F,  0xFE,  0x3F,  0x80,  0x90,  0x7F,  0xC0,  0xA8,  0x33,  0x0C, 	/* 189F0 */
+	0x60,  0x0E,  0x03,  0x24,  0xED,  0x83,  0x0C,  0xAB,  0x21,  0x02,  0x10,  0xF7,  0xE1,  0x52,  0x25,  0x42, 	/* 18A00 */
+	0xFC,  0x74,  0x4A,  0xE8,  0x25,  0x82,  0x98,  0x32,  0x42,  0xC2,  0xAE,  0x21,  0x02,  0x10,  0xFA,  0x01, 	/* 18A10 */
+	0x3E,  0x24,  0x82,  0x88,  0x72,  0xCA,  0xAA,  0x24,  0xA2,  0x08,  0x20,  0x82,  0x18,  0xB0,  0x1F,  0x81, 	/* 18A20 */
+	0x48,  0x12,  0x8F,  0xFE,  0x24,  0x82,  0x28,  0x3F,  0x00,  0x50,  0xFF,  0xE3,  0x24,  0xDD,  0x83,  0x06, 	/* 18A30 */
+	0xB1,  0x22,  0x82,  0x2C,  0xFA,  0xA1,  0x48,  0x2F,  0xE3,  0x48,  0x74,  0x8A,  0xC8,  0x25,  0x42,  0x54, 	/* 18A40 */
+	0x26,  0x22,  0x41,  0xB4,  0x21,  0x02,  0x10,  0xF7,  0xE1,  0x28,  0x27,  0xC2,  0x82,  0x7F,  0xCA,  0xA0, 	/* 18A50 */
+	0x23,  0xC2,  0x04,  0x20,  0x42,  0x18,  0xB5,  0x22,  0x02,  0x26,  0xFD,  0xC1,  0x48,  0x2C,  0x82,  0x48, 	/* 18A60 */
+	0x77,  0xFA,  0xC8,  0x24,  0x82,  0x48,  0x27,  0xE2,  0x40,  0xB7,  0x21,  0x02,  0x10,  0xFA,  0x81,  0x28, 	/* 18A70 */
+	0x24,  0x43,  0xBA,  0x70,  0x0A,  0xFC,  0x24,  0x42,  0x44,  0x24,  0x42,  0x7C,  0xBF,  0x21,  0x02,  0x10, 	/* 18A80 */
+	0xF7,  0xC1,  0x10,  0x21,  0x02,  0xFE,  0x71,  0x0A,  0x90,  0x27,  0xC2,  0x10,  0x21,  0x02,  0xFE,  0x81, 	/* 18A90 */
+	0x11,  0x47,  0xD2,  0x11,  0x0F,  0xFE,  0x11,  0x0F,  0xF4,  0x23,  0x47,  0x48,  0xA8,  0x82,  0x5A,  0x32, 	/* 18AA0 */
+	0x66,  0x42,  0x82,  0x7C,  0x22,  0x12,  0x3D,  0x26,  0x52,  0x99,  0x23,  0x02,  0xC4,  0x6F,  0xFE,  0x0A, 	/* 18AB0 */
+	0x43,  0x98,  0xCE,  0x83,  0x06,  0x83,  0x21,  0x02,  0x1C,  0xF9,  0x01,  0x10,  0x2F,  0xE2,  0x80,  0x77, 	/* 18AC0 */
+	0xEA,  0x90,  0x21,  0xC2,  0x12,  0x21,  0x02,  0x10,  0x84,  0x22,  0x02,  0x2E,  0xF4,  0x01,  0xA0,  0x23, 	/* 18AD0 */
+	0xF2,  0xC4,  0x74,  0x4A,  0xC4,  0x24,  0x42,  0x44,  0x24,  0x42,  0x4C,  0x85,  0x22,  0x0A,  0x20,  0x7F, 	/* 18AE0 */
+	0xE2,  0x20,  0x62,  0x0A,  0xFC,  0x04,  0x0F,  0xFE,  0x1A,  0x42,  0x98,  0xCE,  0x83,  0x86,  0x8F,  0x04, 	/* 18AF0 */
+	0x0F,  0xFE,  0x24,  0x83,  0xF8,  0x24,  0x87,  0xFC,  0x04,  0x0F,  0xFE,  0x34,  0x4D,  0x28,  0x1D,  0x87, 	/* 18B00 */
+	0x06,  0x94,  0x04,  0x0F,  0xFE,  0x34,  0xCD,  0x30,  0x7F,  0xE1,  0x10,  0x7F,  0xC4,  0xA4,  0x73,  0xC4, 	/* 18B10 */
+	0xE4,  0x4A,  0x44,  0xEC,  0x95,  0x22,  0x82,  0x24,  0xFA,  0x41,  0x54,  0x21,  0x02,  0xA8,  0x74,  0x4A, 	/* 18B20 */
+	0xFE,  0x34,  0x52,  0x44,  0x24,  0x42,  0x7C,  0x98,  0x04,  0x8F,  0xFE,  0x64,  0x41,  0xE8,  0x35,  0x8C, 	/* 18B30 */
+	0x46,  0x04,  0x0F,  0xFF,  0x0A,  0x23,  0x94,  0xCE,  0x83,  0x06,  0x99,  0x20,  0x02,  0x3C,  0xF9,  0x41, 	/* 18B40 */
+	0x14,  0x27,  0xE2,  0x94,  0x77,  0xCA,  0xA0,  0x23,  0xE2,  0x52,  0x29,  0x22,  0x1E,  0x9C,  0x21,  0x42, 	/* 18B50 */
+	0x12,  0xF7,  0xE1,  0x10,  0x27,  0xE2,  0xD2,  0x77,  0xEA,  0xD2,  0x27,  0xE2,  0x52,  0x25,  0x22,  0x56, 	/* 18B60 */
+	0x9D,  0x51,  0x07,  0x10,  0x1F,  0xEF,  0x10,  0x51,  0x09,  0x7C,  0x04,  0x0F,  0xFE,  0x34,  0x4D,  0x28, 	/* 18B70 */
+	0x1D,  0x86,  0x06,  0x9F,  0x41,  0x02,  0x54,  0x85,  0x24,  0xBA,  0x31,  0x0C,  0xE0,  0x04,  0x0F,  0xFE, 	/* 18B80 */
+	0x0A,  0x43,  0x98,  0xCE,  0x83,  0x86,  0xA1,  0x20,  0x02,  0x7E,  0xF5,  0x21,  0x7E,  0x25,  0x22,  0xD2, 	/* 18B90 */
+	0x77,  0xEA,  0x90,  0x27,  0xC2,  0x10,  0x21,  0x02,  0xFE,  0xA8,  0x21,  0x02,  0x20,  0xFF,  0xE1,  0x52, 	/* 18BA0 */
+	0x27,  0xE2,  0xD2,  0x77,  0xEA,  0xA8,  0x24,  0x82,  0xFE,  0x20,  0x82,  0x08,  0xB2,  0x20,  0x02,  0x7E, 	/* 18BB0 */
+	0xF9,  0x01,  0xFE,  0x29,  0x22,  0xFE,  0x7B,  0x6A,  0xB6,  0x2D,  0xA2,  0x92,  0x29,  0x22,  0x96,  0xB3, 	/* 18BC0 */
+	0x24,  0x81,  0x50,  0xFF,  0xE8,  0x02,  0xBF,  0xA2,  0x08,  0x3F,  0x80,  0x40,  0xFF,  0xE3,  0x24,  0xDD, 	/* 18BD0 */
+	0x83,  0x06,  0xB4,  0x09,  0x07,  0x9E,  0x09,  0x07,  0x9C,  0x09,  0x0F,  0x9E,  0x15,  0x0F,  0xFE,  0x1A, 	/* 18BE0 */
+	0x43,  0x18,  0xDC,  0x83,  0x06,  0xB8,  0x20,  0x02,  0x7E,  0xF5,  0x21,  0x7E,  0x25,  0x22,  0xFE,  0x71, 	/* 18BF0 */
+	0x0A,  0xFF,  0x23,  0x82,  0x54,  0x29,  0x22,  0x10,  0xB9,  0x04,  0x0F,  0xFE,  0x24,  0x83,  0xF8,  0x24, 	/* 18C00 */
+	0x87,  0xFC,  0x04,  0x0F,  0xFE,  0x54,  0xCB,  0x32,  0xDD,  0x83,  0x06,  0xBC,  0x20,  0x02,  0x3C,  0xFA, 	/* 18C10 */
+	0x41,  0x3C,  0x22,  0x42,  0xBC,  0x71,  0x0A,  0xBE,  0x26,  0xA2,  0xAA,  0x25,  0x22,  0x0C,  0xBD,  0x50, 	/* 18C20 */
+	0x47,  0xD4,  0x91,  0x47,  0xD4,  0x55,  0x45,  0xC4,  0x14,  0xCF,  0xFE,  0x0C,  0x83,  0x30,  0xDD,  0x83, 	/* 18C30 */
+	0x06,  0xBE,  0x20,  0x02,  0x7E,  0xF4,  0x21,  0x7E,  0x24,  0x82,  0xFE,  0x74,  0x8A,  0xFE,  0x26,  0x22, 	/* 18C40 */
+	0xA2,  0x2A,  0x23,  0x3E,  0x82,  0x24,  0x82,  0x48,  0xFF,  0x81,  0x48,  0x2F,  0xC2,  0xCA,  0x74,  0xAA, 	/* 18C50 */
+	0xF8,  0x24,  0x82,  0x78,  0x2C,  0x82,  0x08,  0x84,  0x21,  0x02,  0x7E,  0xF9,  0x01,  0x7C,  0x29,  0x43, 	/* 18C60 */
+	0x7E,  0x69,  0x4A,  0x7E,  0x22,  0x42,  0x64,  0x21,  0x82,  0xE4,  0x87,  0x24,  0x02,  0x7E,  0xFC,  0x41, 	/* 18C70 */
+	0x7C,  0x24,  0x42,  0xFC,  0x72,  0x0A,  0xBC,  0x24,  0x82,  0xB0,  0x26,  0x83,  0x86,  0x8A,  0x20,  0xC2, 	/* 18C80 */
+	0x70,  0xFF,  0xE1,  0x42,  0x27,  0xE2,  0xC0,  0x77,  0xEA,  0xEA,  0x27,  0xE2,  0xAA,  0x32,  0xA2,  0x26, 	/* 18C90 */
+	0x8C,  0x20,  0x02,  0x7E,  0xFD,  0x21,  0x10,  0x2F,  0xE3,  0x52,  0x6F,  0xEA,  0x52,  0x27,  0xE2,  0x10, 	/* 18CA0 */
+	0x2F,  0xE2,  0x10,  0x90,  0x27,  0xC2,  0x44,  0xF7,  0xC1,  0x44,  0x27,  0xC2,  0xA0,  0x77,  0xEA,  0xCA, 	/* 18CB0 */
+	0x37,  0x22,  0x4A,  0x23,  0xA2,  0x0C,  0x92,  0x04,  0x0F,  0xFE,  0x10,  0x01,  0x7C,  0x24,  0x46,  0xFE, 	/* 18CC0 */
+	0xA3,  0x42,  0x52,  0x1A,  0x47,  0x28,  0x19,  0x87,  0x06,  0x93,  0x22,  0x02,  0x7E,  0xF6,  0x21,  0x62, 	/* 18CD0 */
+	0x2F,  0xE2,  0xC8,  0x77,  0xFA,  0xC8,  0x25,  0xC2,  0x5A,  0x26,  0x92,  0x48,  0x9D,  0x22,  0x22,  0x92, 	/* 18CE0 */
+	0xF4,  0x41,  0x7C,  0x25,  0x43,  0x7C,  0x65,  0x4B,  0x7C,  0x21,  0x02,  0xFE,  0x21,  0x02,  0x10,  0x9E, 	/* 18CF0 */
+	0x20,  0x02,  0x7C,  0xF5,  0x41,  0x6C,  0x24,  0x42,  0xFC,  0x70,  0x0A,  0xFE,  0x2A,  0xA2,  0xAA,  0x2A, 	/* 18D00 */
+	0xA3,  0xFF,  0xA5,  0x20,  0x02,  0x7E,  0xFC,  0x01,  0x7F,  0x26,  0xA3,  0xA4,  0x6B,  0x2B,  0x04,  0x2F, 	/* 18D10 */
+	0xE2,  0x24,  0x20,  0x42,  0x0C,  0xAA,  0x28,  0x02,  0x5E,  0xF1,  0x21,  0x9E,  0x25,  0x22,  0x9E,  0x71, 	/* 18D20 */
+	0xAA,  0xD4,  0x25,  0x22,  0x59,  0x2A,  0x03,  0x1F,  0xAB,  0x40,  0xC4,  0xF8,  0xF8,  0xE2,  0xBE,  0x2A, 	/* 18D30 */
+	0x85,  0xBF,  0xEA,  0x85,  0xAF,  0x55,  0x45,  0x54,  0x69,  0x55,  0x23,  0xB6,  0x20,  0x02,  0xFE,  0xF3, 	/* 18D40 */
+	0x61,  0x5A,  0x23,  0x62,  0xDA,  0x72,  0x0A,  0xFC,  0x24,  0x42,  0x7C,  0x24,  0x42,  0x7C,  0xB8,  0x27, 	/* 18D50 */
+	0xC2,  0x54,  0xFF,  0xE1,  0x54,  0x2F,  0xE3,  0x92,  0x6F,  0xEB,  0x10,  0x2F,  0xE2,  0x64,  0x21,  0x82, 	/* 18D60 */
+	0x64,  0xBB,  0x08,  0x0F,  0xFC,  0x22,  0x07,  0x78,  0xFA,  0x86,  0xE8,  0xB5,  0xAC,  0x86,  0x18,  0x8E, 	/* 18D70 */
+	0x50,  0x3B,  0x06,  0x0C,  0x81,  0x20,  0x82,  0xE8,  0xF3,  0x41,  0x3E,  0x2C,  0x83,  0xBE,  0x6E,  0xAB, 	/* 18D80 */
+	0x3E,  0x22,  0x82,  0x2A,  0x22,  0xE2,  0xDA,  0x83,  0x04,  0x0F,  0xFE,  0x27,  0xC4,  0x44,  0x7F,  0xE4, 	/* 18D90 */
+	0x38,  0x75,  0x44,  0x92,  0x34,  0x4D,  0x28,  0x1D,  0x83,  0x06,  0x84,  0x04,  0x0F,  0xFE,  0x4A,  0x47, 	/* 18DA0 */
+	0xBC,  0x11,  0x07,  0xFC,  0x11,  0x0F,  0xFE,  0x0C,  0x4F,  0x28,  0x11,  0x83,  0x86,  0x8C,  0x2E,  0xE2, 	/* 18DB0 */
+	0xAA,  0xFE,  0xE1,  0x00,  0x27,  0xC2,  0xD4,  0x77,  0xCA,  0xD4,  0x27,  0xC2,  0x10,  0x2F,  0xE2,  0x10, 	/* 18DC0 */
+	0x8D,  0x24,  0x82,  0x50,  0xF7,  0xE1,  0xD0,  0x27,  0xC2,  0xD0,  0x77,  0xEA,  0x90,  0x2F,  0xE2,  0x34, 	/* 18DD0 */
+	0x25,  0x22,  0x10,  0x96,  0x21,  0x02,  0x7E,  0xF6,  0xE1,  0x5A,  0x17,  0xE2,  0x5A,  0x6E,  0xEB,  0x4A, 	/* 18DE0 */
+	0x28,  0x82,  0x7F,  0x21,  0x42,  0xE3,  0x9E,  0x79,  0x04,  0xFC,  0x7A,  0x84,  0x7E,  0x79,  0x0A,  0xFC, 	/* 18DF0 */
+	0x39,  0x0F,  0xFE,  0x34,  0x4D,  0x28,  0x1D,  0x87,  0x06,  0x9F,  0x44,  0x85,  0xFE,  0xE4,  0x82,  0xFC, 	/* 18E00 */
+	0x34,  0xA4,  0xFE,  0x60,  0x0F,  0xFE,  0x49,  0x44,  0x92,  0x51,  0x24,  0x30,  0xA0,  0x29,  0x22,  0x54, 	/* 18E10 */
+	0xFF,  0xE1,  0x82,  0x23,  0xC2,  0xA4,  0x73,  0xCA,  0xFE,  0x25,  0x22,  0x7E,  0x25,  0x22,  0x7E,  0xA4, 	/* 18E20 */
+	0x2F,  0x42,  0xA4,  0xFF,  0x61,  0x98,  0x2F,  0x03,  0xAE,  0x6F,  0x0B,  0x00,  0x2F,  0xE2,  0xAA,  0x2A, 	/* 18E30 */
+	0xA3,  0xFF,  0xA6,  0x27,  0xC2,  0x10,  0xFF,  0xE1,  0x92,  0x2B,  0xA3,  0x00,  0x6F,  0xEB,  0x20,  0x2F, 	/* 18E40 */
+	0xE2,  0xAA,  0x2A,  0xA2,  0x86,  0xAA,  0x22,  0x82,  0xFE,  0xF2,  0x81,  0xFE,  0x1A,  0xA2,  0xFE,  0x30, 	/* 18E50 */
+	0x86,  0xFE,  0xA6,  0xA2,  0x54,  0x24,  0xC2,  0x92,  0xAD,  0x24,  0x02,  0x5F,  0xFE,  0x81,  0x5E,  0x25, 	/* 18E60 */
+	0x22,  0xFE,  0x71,  0x2A,  0xFE,  0x2B,  0x22,  0xBE,  0x2E,  0xA2,  0x31,  0xAF,  0x44,  0x05,  0xFE,  0xEA, 	/* 18E70 */
+	0xA2,  0xAE,  0x3F,  0xA4,  0x4A,  0x5F,  0xEE,  0x4A,  0x5E,  0xE4,  0x4C,  0x45,  0x54,  0x63,  0xB2,  0x23, 	/* 18E80 */
+	0x8F,  0xA0,  0x53,  0xCF,  0x84,  0x4B,  0xC7,  0xA0,  0x4B,  0xC5,  0xA2,  0xFF,  0xE3,  0x4C,  0xD3,  0x03, 	/* 18E90 */
+	0x8E,  0xB4,  0x4E,  0xE4,  0xAA,  0xFE,  0xE1,  0xAA,  0x2E,  0xE2,  0x92,  0x5F,  0xEE,  0xD6,  0x5F,  0xE4, 	/* 18EA0 */
+	0xBA,  0x4D,  0x64,  0x96,  0xB7,  0x21,  0x02,  0x7E,  0xF5,  0x21,  0x7E,  0x15,  0xA2,  0xFF,  0x32,  0x46, 	/* 18EB0 */
+	0xDA,  0xA8,  0x92,  0x7E,  0x20,  0x82,  0x18,  0xBE,  0x00,  0x0F,  0xFE,  0x12,  0x01,  0x20,  0xFF,  0xC9, 	/* 18EC0 */
+	0x24,  0x92,  0x49,  0x24,  0x9E,  0x48,  0x04,  0x80,  0x48,  0x04,  0xBF,  0x00,  0x0F,  0xFE,  0x0A,  0x00, 	/* 18ED0 */
+	0xA0,  0x7F,  0xC4,  0xA4,  0x4A,  0x45,  0x1C,  0x60,  0x44,  0x04,  0x7F,  0xC0,  0x00,  0x81,  0x00,  0x0F, 	/* 18EE0 */
+	0xFE,  0x0A,  0x07,  0xFC,  0x4A,  0x47,  0xFC,  0x08,  0x0F,  0xFE,  0x11,  0x01,  0xA0,  0x07,  0x07,  0x8C, 	/* 18EF0 */
+	0x83,  0xFF,  0xE1,  0x10,  0x7F,  0xC5,  0x14,  0x5F,  0x40,  0x00,  0x3F,  0x82,  0x08,  0x3F,  0x82,  0x08, 	/* 18F00 */
+	0xFF,  0xE0,  0x40,  0x86,  0xFF,  0xE0,  0xA0,  0x7F,  0xC4,  0xA4,  0x7F,  0xC2,  0x80,  0x4F,  0xEA,  0xA8, 	/* 18F10 */
+	0x27,  0xC5,  0x88,  0xC3,  0x05,  0xCE,  0x87,  0xFF,  0xE0,  0xA0,  0x7F,  0xC4,  0xA4,  0x7F,  0xE2,  0x92, 	/* 18F20 */
+	0x7D,  0xE2,  0x92,  0x7D,  0xE5,  0x52,  0xFF,  0x21,  0x26,  0x88,  0x7F,  0xC1,  0x10,  0xFF,  0xE9,  0x12, 	/* 18F30 */
+	0x7F,  0x04,  0x9E,  0x7A,  0x44,  0xE4,  0xFD,  0x82,  0x88,  0x2B,  0x45,  0xC2,  0x8A,  0x00,  0x0F,  0xFE, 	/* 18F40 */
+	0x0A,  0x07,  0xFC,  0x4A,  0x4F,  0xFE,  0x2A,  0x87,  0xFE,  0x56,  0x8F,  0xFE,  0x12,  0xA1,  0x4C,  0x8B, 	/* 18F50 */
+	0x00,  0x03,  0xF8,  0x20,  0x83,  0xF8,  0x20,  0x83,  0xF8,  0x20,  0x83,  0xF8,  0x0A,  0x01,  0x22,  0x22, 	/* 18F60 */
+	0x2C,  0x1E,  0x8F,  0x27,  0xC2,  0x44,  0xFC,  0x42,  0x7C,  0x24,  0x4F,  0xFC,  0x24,  0x42,  0x7C,  0x32, 	/* 18F70 */
+	0x84,  0xA8,  0x44,  0xA8,  0x86,  0x93,  0x03,  0x87,  0xC8,  0x24,  0x44,  0x42,  0xBF,  0x82,  0x08,  0x3F, 	/* 18F80 */
+	0x82,  0x08,  0x3F,  0x80,  0xA0,  0x32,  0x2C,  0x1E,  0x96,  0x20,  0x02,  0x7C,  0xF4,  0x41,  0x7C,  0x24, 	/* 18F90 */
+	0x42,  0x7C,  0x74,  0x4A,  0xFC,  0x22,  0x82,  0x28,  0x24,  0xA2,  0x86,  0x97,  0x03,  0xEF,  0xA2,  0x0A, 	/* 18FA0 */
+	0x2E,  0xBE,  0x0A,  0x2E,  0xBE,  0xAA,  0x2A,  0xBE,  0xE9,  0x40,  0x94,  0x0A,  0x51,  0xC3,  0x98,  0x20, 	/* 18FB0 */
+	0x02,  0x7C,  0x3C,  0x42,  0x7C,  0x24,  0x42,  0x7C,  0xFC,  0x48,  0xC4,  0x8F,  0xCF,  0xA8,  0x04,  0xA1, 	/* 18FC0 */
+	0x86,  0x9A,  0x28,  0x81,  0x50,  0xFF,  0xEA,  0x0A,  0xBF,  0xA2,  0x08,  0x3F,  0x82,  0x08,  0x3F,  0x80, 	/* 18FD0 */
+	0xA0,  0x32,  0x2C,  0x1E,  0xA1,  0x00,  0x07,  0xFC,  0x14,  0x45,  0x7C,  0x54,  0x45,  0xFC,  0xB4,  0x49, 	/* 18FE0 */
+	0x7C,  0x1A,  0x8E,  0x2A,  0x04,  0xA1,  0x86,  0xA6,  0x10,  0x02,  0x9E,  0x45,  0x2B,  0xBE,  0x01,  0x2E, 	/* 18FF0 */
+	0xBE,  0xAB,  0x2F,  0x52,  0xB5,  0xEE,  0xAC,  0xAB,  0x5A,  0xA7,  0xA7,  0xFA,  0x09,  0x3E,  0xFC,  0x09, 	/* 19000 */
+	0x3E,  0xF8,  0x03,  0xF8,  0x20,  0x83,  0xF8,  0x20,  0x83,  0xFA,  0x1A,  0x2E,  0x1E,  0xA9,  0x20,  0x02, 	/* 19010 */
+	0x3E,  0x7A,  0x22,  0xBE,  0xFE,  0x22,  0x3E,  0x7A,  0x24,  0xBE,  0xF9,  0x44,  0x95,  0x4A,  0x57,  0xC3, 	/* 19020 */
+	0xAA,  0x27,  0xCF,  0xC4,  0x57,  0xC5,  0x44,  0xFF,  0xC2,  0x44,  0xFC,  0x47,  0x7C,  0x6A,  0x8A,  0xA8, 	/* 19030 */
+	0x24,  0xA2,  0x86,  0xAC,  0x20,  0x0A,  0xBE,  0xFA,  0x20,  0x22,  0xFF,  0xE0,  0x22,  0x7B,  0xE4,  0xA2, 	/* 19040 */
+	0x7B,  0xE4,  0xD4,  0x32,  0x5C,  0xC3,  0xAF,  0x28,  0x07,  0xDE,  0x29,  0x27,  0xDE,  0x29,  0x2F,  0xFE, 	/* 19050 */
+	0x55,  0x27,  0xD2,  0x55,  0xEF,  0xF4,  0x45,  0x44,  0xE6,  0xB2,  0x50,  0x0F,  0xBC,  0x52,  0x4F,  0xBC, 	/* 19060 */
+	0xAA,  0x4F,  0xBC,  0x22,  0x47,  0xA4,  0x23,  0xCF,  0x58,  0x3A,  0xAE,  0x46,  0xB3,  0x43,  0xE7,  0xE2, 	/* 19070 */
+	0x52,  0x27,  0xFE,  0xAA,  0x27,  0xFE,  0x52,  0x2F,  0xFE,  0x51,  0x47,  0xD4,  0x52,  0x57,  0xC3,  0xBA, 	/* 19080 */
+	0x12,  0x06,  0x5C,  0x4A,  0x47,  0x5C,  0x4A,  0x4F,  0xFE,  0xA0,  0xAB,  0xF8,  0x20,  0x83,  0xF8,  0x1A, 	/* 19090 */
+	0x2E,  0x1E,  0xBD,  0xF2,  0x0A,  0x7E,  0xF8,  0x0F,  0xFE,  0xAA,  0xAF,  0xFE,  0x20,  0x83,  0xF8,  0x20, 	/* 190A0 */
+	0x83,  0xF8,  0x12,  0x2E,  0x1E,  0xBF,  0x20,  0x0F,  0xDE,  0x21,  0x27,  0x9E,  0xFD,  0x2B,  0x5E,  0xFD, 	/* 190B0 */
+	0x24,  0x9E,  0x78,  0xC4,  0x94,  0x7A,  0x5C,  0x43,  0x80,  0x28,  0x0F,  0xFC,  0x2A,  0x4E,  0xFC,  0xAA, 	/* 190C0 */
+	0x4E,  0xFC,  0x2A,  0x47,  0xE4,  0xD3,  0xC7,  0x98,  0x52,  0xA7,  0xCE,  0x92,  0x08,  0x01,  0xF0,  0x22, 	/* 190D0 */
+	0x0F,  0xFC,  0x24,  0x43,  0xFC,  0x24,  0x43,  0xFC,  0x20,  0x42,  0x04,  0x20,  0x44,  0x0C,  0x9A,  0x10, 	/* 190E0 */
+	0x63,  0xB8,  0x55,  0x4F,  0xD4,  0x55,  0x47,  0xD4,  0x55,  0x47,  0xDC,  0x45,  0x44,  0x5D,  0x46,  0x38, 	/* 190F0 */
+	0x81,  0x9C,  0x12,  0x05,  0xBC,  0x52,  0x2F,  0xFE,  0x1A,  0x07,  0xF8,  0x24,  0x83,  0xF8,  0x24,  0x83, 	/* 19100 */
+	0xF8,  0x40,  0x88,  0x18,  0x9D,  0x20,  0x63,  0xD8,  0x49,  0x49,  0x14,  0x7D,  0x45,  0x5E,  0x7D,  0x45, 	/* 19110 */
+	0x55,  0x7D,  0x34,  0x79,  0x44,  0x08,  0xDE,  0xA3,  0x20,  0x03,  0xFE,  0x49,  0x29,  0x22,  0x7C,  0xC5, 	/* 19120 */
+	0x5E,  0x7E,  0x85,  0x48,  0x7F,  0xF4,  0x48,  0x44,  0x88,  0xC8,  0xA6,  0x20,  0x83,  0xC8,  0x48,  0x89, 	/* 19130 */
+	0x3E,  0x7E,  0xA5,  0x6A,  0x7F,  0xE5,  0x48,  0x7C,  0xC4,  0x4A,  0x44,  0xE8,  0xF1,  0xA7,  0x22,  0x43, 	/* 19140 */
+	0xD4,  0x49,  0x89,  0x7E,  0x7C,  0x85,  0x7E,  0x7C,  0x85,  0x48,  0x7F,  0xE4,  0x48,  0x44,  0x88,  0xC8, 	/* 19150 */
+	0xB4,  0x22,  0x07,  0xBE,  0x96,  0x4F,  0xBC,  0xAA,  0x4F,  0xFF,  0xA9,  0x0F,  0x9E,  0x8A,  0xA8,  0xCA, 	/* 19160 */
+	0x89,  0x29,  0x8C,  0xB8,  0x47,  0xE7,  0x5A,  0xA7,  0xEF,  0x90,  0xAB,  0xEF,  0xD2,  0xAF,  0xEF,  0xD6, 	/* 19170 */
+	0x8F,  0xE8,  0x92,  0x8B,  0xA9,  0x8C,  0x80,  0x1F,  0x00,  0x00,  0xFF,  0xE0,  0x00,  0x1F,  0x00,  0x00, 	/* 19180 */
+	0x1F,  0x00,  0x00,  0x3F,  0x82,  0x08,  0x20,  0x83,  0xF8,  0x82,  0x60,  0x00,  0xFE,  0xF1,  0x00,  0x10, 	/* 19190 */
+	0x71,  0x00,  0x10,  0x71,  0x00,  0x10,  0xF1,  0x09,  0x10,  0x91,  0x0F,  0x30,  0x83,  0x71,  0x00,  0x10, 	/* 191A0 */
+	0xF9,  0x00,  0x10,  0x71,  0x80,  0x14,  0x71,  0x20,  0x12,  0xF9,  0x08,  0x90,  0x89,  0x0F,  0x90,  0x88, 	/* 191B0 */
+	0x71,  0x00,  0x10,  0xF9,  0x00,  0x10,  0x7F,  0xE0,  0x10,  0x71,  0x00,  0x10,  0xF1,  0x09,  0x10,  0x91, 	/* 191C0 */
+	0x0F,  0x10,  0x8A,  0xE0,  0x00,  0xF8,  0xF2,  0x80,  0x28,  0x72,  0x80,  0xF8,  0x72,  0x80,  0x28,  0xF2, 	/* 191D0 */
+	0xA9,  0x2A,  0x92,  0x6F,  0x42,  0x8C,  0x70,  0x00,  0x7C,  0xF9,  0x00,  0x10,  0x71,  0x00,  0x10,  0x71, 	/* 191E0 */
+	0x00,  0x10,  0xF1,  0x09,  0x10,  0x9F,  0xEF,  0x00,  0x8E,  0x60,  0x80,  0x08,  0xF0,  0x80,  0xFE,  0x70, 	/* 191F0 */
+	0x80,  0x88,  0x74,  0x80,  0x48,  0xF0,  0x89,  0x08,  0x90,  0x8F,  0x18,  0x90,  0x70,  0x00,  0x7C,  0xF1, 	/* 19200 */
+	0x00,  0x10,  0x71,  0x00,  0xFE,  0x71,  0x00,  0x10,  0xF1,  0x09,  0x10,  0x91,  0x0F,  0x10,  0x93,  0x72, 	/* 19210 */
+	0x20,  0x2A,  0xFA,  0xA0,  0x2A,  0x72,  0xA0,  0x2A,  0x72,  0xA0,  0x2A,  0xF2,  0xA9,  0x2A,  0x94,  0x2F, 	/* 19220 */
+	0x42,  0x96,  0x72,  0x00,  0x20,  0xF3,  0xE0,  0x40,  0x7F,  0xE0,  0x04,  0x70,  0x80,  0x10,  0xF2,  0x09, 	/* 19230 */
+	0x42,  0x94,  0x2F,  0x3E,  0x97,  0x60,  0xC0,  0xF0,  0xF2,  0x00,  0x20,  0x72,  0x00,  0xFE,  0x72,  0x00, 	/* 19240 */
+	0x20,  0xF2,  0x09,  0x22,  0x92,  0x2F,  0x1E,  0x98,  0x70,  0x00,  0x7C,  0xF8,  0x40,  0x04,  0x78,  0x40, 	/* 19250 */
+	0x3C,  0x7A,  0x00,  0x20,  0xFA,  0x08,  0xA2,  0x8A,  0x2F,  0x9E,  0x9B,  0x73,  0x00,  0x30,  0xF3,  0x00, 	/* 19260 */
+	0x52,  0x75,  0xC0,  0xD0,  0x75,  0x00,  0x50,  0xF5,  0x09,  0x52,  0x95,  0x2F,  0x4E,  0x9D,  0x70,  0x00, 	/* 19270 */
+	0x3E,  0xF2,  0x40,  0x24,  0x72,  0x40,  0xFE,  0x70,  0x40,  0x0C,  0xF1,  0x49,  0x24,  0x9C,  0x4F,  0x0C, 	/* 19280 */
+	0x9F,  0x73,  0x80,  0x08,  0xFA,  0x80,  0x24,  0x74,  0x40,  0x92,  0x71,  0x00,  0x28,  0xF2,  0x49,  0x4C, 	/* 19290 */
+	0x9F,  0x2F,  0x02,  0xA3,  0x72,  0x00,  0x20,  0xF2,  0x00,  0xFC,  0x72,  0x40,  0x24,  0x7F,  0xE0,  0x20, 	/* 192A0 */
+	0xF3,  0x09,  0x48,  0x98,  0x4F,  0x02,  0xA5,  0x73,  0x00,  0x10,  0xF1,  0x00,  0xFE,  0x79,  0x20,  0x92, 	/* 192B0 */
+	0x79,  0x20,  0xAA,  0xFC,  0x69,  0x82,  0x98,  0x2F,  0x86,  0xAA,  0x62,  0x00,  0x20,  0xFF,  0xE0,  0x20, 	/* 192C0 */
+	0x72,  0x00,  0x3C,  0x72,  0x40,  0x24,  0xF4,  0x49,  0x44,  0x98,  0x4F,  0x18,  0xAD,  0x77,  0x80,  0x48, 	/* 192D0 */
+	0xF4,  0xA0,  0x4A,  0x78,  0x60,  0x7C,  0x70,  0x40,  0x48,  0xF2,  0x89,  0x10,  0x92,  0x8F,  0xC6,  0xB1, 	/* 192E0 */
+	0x74,  0x00,  0x40,  0xF7,  0xC0,  0x90,  0x71,  0x00,  0x10,  0x7F,  0xE0,  0x10,  0xF1,  0x09,  0x10,  0x91, 	/* 192F0 */
+	0x0F,  0x10,  0xB3,  0x70,  0x00,  0x3E,  0xFA,  0x20,  0x22,  0x73,  0xE0,  0x28,  0x72,  0x80,  0x28,  0xF2, 	/* 19300 */
+	0x89,  0x44,  0x94,  0x4F,  0x82,  0xB4,  0x70,  0x40,  0x78,  0xF4,  0x00,  0x40,  0x77,  0xE0,  0x48,  0x74, 	/* 19310 */
+	0x80,  0x58,  0xF4,  0xC9,  0x4A,  0x98,  0x8F,  0x08,  0xB6,  0x70,  0x00,  0xFE,  0xF0,  0x40,  0x04,  0x77, 	/* 19320 */
+	0x40,  0x54,  0x75,  0x40,  0x54,  0xF7,  0x49,  0x04,  0x90,  0x4F,  0x0C,  0xBA,  0x61,  0x00,  0x10,  0xF2, 	/* 19330 */
+	0x80,  0x44,  0xE9,  0x20,  0x24,  0xEC,  0x80,  0x10,  0xF6,  0x29,  0x04,  0x91,  0x8F,  0x60,  0xBB,  0x62, 	/* 19340 */
+	0x00,  0x10,  0xF7,  0xE0,  0x10,  0x71,  0x00,  0x10,  0x77,  0xC0,  0x10,  0xF1,  0x09,  0x10,  0x91,  0x0F, 	/* 19350 */
+	0xFE,  0xBC,  0x60,  0x00,  0xFE,  0xF1,  0x00,  0x10,  0x75,  0x00,  0x50,  0x75,  0xC0,  0x50,  0xF5,  0x09, 	/* 19360 */
+	0x50,  0x95,  0x0F,  0xFE,  0x81,  0x71,  0x00,  0x10,  0xF1,  0x00,  0xFE,  0x71,  0x00,  0x10,  0x71,  0x00, 	/* 19370 */
+	0x7C,  0xF4,  0x49,  0x44,  0x94,  0x4F,  0x7C,  0x86,  0x70,  0xC0,  0x78,  0xFC,  0x80,  0x48,  0x77,  0xE0, 	/* 19380 */
+	0x48,  0x74,  0x80,  0x48,  0xF4,  0xA9,  0xE6,  0x90,  0x2F,  0xFA,  0x88,  0x7F,  0xC4,  0xA4,  0x7F,  0xC0, 	/* 19390 */
+	0x00,  0x1F,  0x0F,  0xFE,  0x00,  0x03,  0xF8,  0x00,  0x03,  0xF8,  0x20,  0x83,  0xF8,  0x90,  0x72,  0x00, 	/* 193A0 */
+	0x20,  0xFB,  0xE0,  0x30,  0x75,  0x00,  0x9E,  0x71,  0x00,  0x10,  0xF1,  0xE9,  0x10,  0x91,  0x0F,  0x10, 	/* 193B0 */
+	0x91,  0x60,  0x80,  0x7E,  0xF4,  0x20,  0x42,  0x72,  0x00,  0x24,  0x73,  0x80,  0x20,  0xF2,  0x09,  0x22, 	/* 193C0 */
+	0x92,  0x2F,  0x1E,  0x92,  0x71,  0x00,  0x10,  0xF2,  0x00,  0x24,  0x74,  0xE0,  0xF2,  0x70,  0x00,  0x7C, 	/* 193D0 */
+	0xF4,  0x49,  0x44,  0x94,  0x4F,  0x7C,  0x94,  0x70,  0x00,  0x7E,  0xF9,  0x20,  0x12,  0x72,  0x20,  0x4C, 	/* 193E0 */
+	0x78,  0x00,  0x3E,  0x7A,  0x24,  0xA2,  0x4A,  0x27,  0xBE,  0x95,  0x60,  0x00,  0xFE,  0xF1,  0x40,  0x94, 	/* 193F0 */
+	0x75,  0x80,  0x50,  0x7F,  0xE0,  0x10,  0xF1,  0x09,  0x10,  0x91,  0x0F,  0x10,  0x9B,  0x77,  0xC0,  0x44, 	/* 19400 */
+	0xF4,  0x40,  0x44,  0x77,  0xC0,  0x44,  0x74,  0x40,  0x7C,  0xF4,  0x49,  0x44,  0x94,  0x4F,  0xFE,  0x9E, 	/* 19410 */
+	0x70,  0x00,  0x7E,  0xF8,  0x20,  0x7A,  0x70,  0x20,  0x7A,  0x74,  0xA0,  0x4A,  0xF7,  0xA9,  0x02,  0x90, 	/* 19420 */
+	0x2F,  0x06,  0xA0,  0x73,  0x00,  0x08,  0xF7,  0x00,  0x12,  0x71,  0xC0,  0xF8,  0x73,  0x80,  0x34,  0xF5, 	/* 19430 */
+	0x49,  0x92,  0x91,  0x0F,  0x30,  0xA2,  0x74,  0x00,  0x40,  0xF7,  0xE0,  0x82,  0x77,  0xA0,  0x4A,  0x77, 	/* 19440 */
+	0xA0,  0x4A,  0xF4,  0xA9,  0x7A,  0x90,  0x2F,  0x0C,  0xA3,  0x74,  0x00,  0x4C,  0xFF,  0x00,  0x42,  0x73, 	/* 19450 */
+	0xE0,  0x00,  0x77,  0xC0,  0x44,  0xF7,  0xC9,  0x44,  0x94,  0x4F,  0x7C,  0xA6,  0x60,  0xC0,  0x0A,  0xF8, 	/* 19460 */
+	0x80,  0xFE,  0x70,  0x80,  0xF8,  0x72,  0x80,  0x28,  0xF2,  0xA9,  0x36,  0x9C,  0x6F,  0x02,  0xA9,  0x71, 	/* 19470 */
+	0x00,  0x7C,  0xF9,  0x00,  0x10,  0x7F,  0xE0,  0x08,  0x7F,  0xE0,  0x08,  0xF4,  0x89,  0x28,  0x90,  0x8F, 	/* 19480 */
+	0x18,  0xAB,  0x71,  0x00,  0x10,  0xFF,  0xE0,  0x82,  0x71,  0x80,  0xE0,  0x72,  0x00,  0x3C,  0xFE,  0x09, 	/* 19490 */
+	0x22,  0x92,  0x2F,  0x1E,  0xAC,  0x70,  0x60,  0x78,  0xF4,  0x00,  0x40,  0x77,  0xE0,  0x40,  0x74,  0x00, 	/* 194A0 */
+	0x7E,  0xF6,  0x29,  0x62,  0x9A,  0x2F,  0x3E,  0xAD,  0x72,  0x00,  0x3C,  0xF4,  0x80,  0x10,  0x77,  0xE0, 	/* 194B0 */
+	0x40,  0x75,  0xC0,  0x54,  0xF5,  0xC9,  0x50,  0x99,  0x2F,  0x0E,  0xAE,  0x61,  0x00,  0x10,  0xF2,  0x80, 	/* 194C0 */
+	0x44,  0xEF,  0xA0,  0x10,  0xE1,  0x00,  0x7C,  0xF1,  0x09,  0x10,  0x91,  0x0F,  0x7E,  0xB0,  0x71,  0x00, 	/* 194D0 */
+	0x10,  0xFF,  0xE0,  0x10,  0x71,  0x00,  0xFC,  0x70,  0x00,  0x7C,  0xF4,  0x49,  0x44,  0x94,  0x4F,  0x7C, 	/* 194E0 */
+	0xB1,  0x70,  0xC0,  0x70,  0xF1,  0x00,  0x10,  0x7F,  0xE0,  0x10,  0x71,  0x00,  0x7C,  0xF4,  0x49,  0x44, 	/* 194F0 */
+	0x94,  0x4F,  0x7C,  0xB2,  0x38,  0x80,  0x08,  0xFF,  0xE0,  0x10,  0x71,  0x40,  0x24,  0x75,  0x80,  0x12, 	/* 19500 */
+	0x7A,  0x44,  0xC8,  0x49,  0x47,  0xE2,  0xB3,  0x74,  0x40,  0x28,  0xF7,  0xE0,  0x10,  0x71,  0x00,  0x7C, 	/* 19510 */
+	0x71,  0x00,  0x10,  0xFF,  0xE9,  0x10,  0x91,  0x0F,  0x10,  0xBC,  0x72,  0x00,  0x20,  0xFF,  0xE0,  0x28, 	/* 19520 */
+	0x72,  0xA0,  0x3A,  0x72,  0xC0,  0x48,  0xF5,  0x49,  0x94,  0x92,  0x2F,  0x41,  0x82,  0x72,  0x80,  0x28, 	/* 19530 */
+	0xFA,  0xA0,  0x6C,  0x72,  0x80,  0x28,  0x76,  0xC0,  0xAA,  0xF2,  0x89,  0x2A,  0x94,  0xAF,  0x86,  0x84, 	/* 19540 */
+	0x71,  0x00,  0x1C,  0xFF,  0x00,  0x10,  0x77,  0xC0,  0x10,  0x7F,  0xE0,  0x10,  0xF3,  0x89,  0x54,  0x99, 	/* 19550 */
+	0x2F,  0x10,  0x85,  0x71,  0x00,  0x50,  0xF5,  0x00,  0x7C,  0x79,  0x00,  0x10,  0x7F,  0xE0,  0x10,  0xF3, 	/* 19560 */
+	0x89,  0x54,  0x99,  0x2F,  0x10,  0x87,  0x61,  0x00,  0xFE,  0xF2,  0x80,  0x44,  0xEB,  0xA0,  0x00,  0xE7, 	/* 19570 */
+	0xC0,  0x20,  0xF3,  0xC9,  0x04,  0x90,  0x4F,  0x18,  0x89,  0x48,  0x42,  0x48,  0xFF,  0xE1,  0x10,  0x2C, 	/* 19580 */
+	0x87,  0xFC,  0x80,  0x21,  0xF0,  0x00,  0x03,  0xF8,  0x20,  0x83,  0xF8,  0x8C,  0x61,  0x00,  0x10,  0xFF, 	/* 19590 */
+	0xE0,  0x10,  0x71,  0x00,  0xFC,  0x70,  0x00,  0x2C,  0xF6,  0xA9,  0xA2,  0x92,  0x4F,  0x1C,  0x8D,  0x70, 	/* 195A0 */
+	0x00,  0x7E,  0xF1,  0x20,  0x32,  0x71,  0xA0,  0x22,  0x74,  0xC0,  0x20,  0xF2,  0x89,  0x6A,  0x9A,  0x2F, 	/* 195B0 */
+	0x1E,  0x91,  0x62,  0x01,  0x5E,  0xF8,  0x80,  0x48,  0x74,  0x80,  0x68,  0x75,  0xE0,  0xC8,  0xF4,  0x89, 	/* 195C0 */
+	0x48,  0x94,  0x8F,  0xBE,  0x93,  0x20,  0x6F,  0xB8,  0x23,  0xEF,  0x24,  0x22,  0x46,  0xF4,  0x00,  0x0F, 	/* 195D0 */
+	0xFE,  0x00,  0x03,  0xF8,  0x20,  0x83,  0xF8,  0x95,  0x60,  0x61,  0xDC,  0xE4,  0x40,  0x54,  0x69,  0x41, 	/* 195E0 */
+	0xD6,  0x65,  0x41,  0x54,  0xED,  0x4A,  0x7F,  0xAB,  0x0F,  0x0F,  0x98,  0xE1,  0xC0,  0x70,  0xF1,  0x00, 	/* 195F0 */
+	0xFE,  0xE3,  0x80,  0x54,  0xEF,  0xA0,  0x28,  0xF2,  0xC9,  0x44,  0x94,  0x4F,  0x98,  0x9A,  0x71,  0x00, 	/* 19600 */
+	0x54,  0xF5,  0x20,  0x92,  0x77,  0xC0,  0x44,  0x77,  0xC0,  0x44,  0xF7,  0xC9,  0x44,  0x94,  0x4F,  0x4C, 	/* 19610 */
+	0x9E,  0x70,  0x00,  0xFC,  0xF2,  0x00,  0xF8,  0x74,  0x80,  0x48,  0x7F,  0xE0,  0x00,  0xF7,  0xC9,  0x44, 	/* 19620 */
+	0x94,  0x4F,  0x7C,  0xA0,  0x60,  0xC0,  0x0A,  0xF0,  0x80,  0xFE,  0xE8,  0x80,  0xE8,  0xEA,  0xA0,  0xAA, 	/* 19630 */
+	0xEA,  0x4A,  0xA4,  0xAA,  0xAF,  0x71,  0xA1,  0x70,  0xC0,  0x0A,  0xFF,  0xE0,  0x08,  0x7A,  0xA0,  0xAA, 	/* 19640 */
+	0x7F,  0xC0,  0xA8,  0xFA,  0xC9,  0x14,  0x92,  0x2F,  0x41,  0xA3,  0x70,  0x00,  0xFE,  0xF1,  0x00,  0x10, 	/* 19650 */
+	0x75,  0x40,  0x54,  0x75,  0x40,  0xBA,  0xF1,  0x29,  0x10,  0x91,  0x0F,  0xFE,  0xA4,  0x63,  0xC0,  0xA4, 	/* 19660 */
+	0xFA,  0x40,  0xBC,  0x78,  0x00,  0xFC,  0x70,  0x40,  0x04,  0xFF,  0xE9,  0x28,  0x92,  0x4F,  0x42,  0xA5, 	/* 19670 */
+	0x75,  0x00,  0x50,  0xF7,  0xE0,  0x90,  0x71,  0x00,  0xFE,  0x71,  0x00,  0x7C,  0xF4,  0x49,  0x44,  0x94, 	/* 19680 */
+	0x4F,  0x7C,  0xA6,  0x77,  0xC0,  0x04,  0xF2,  0x80,  0x10,  0x77,  0xE0,  0x52,  0x77,  0xE0,  0x52,  0xF7, 	/* 19690 */
+	0xE9,  0x52,  0x95,  0x2F,  0x56,  0xA8,  0x74,  0x00,  0x7E,  0xF8,  0x00,  0x7E,  0x75,  0x20,  0x4A,  0x7F, 	/* 196A0 */
+	0xE0,  0xA4,  0xF9,  0x49,  0xFE,  0x90,  0x4F,  0x18,  0xAC,  0x64,  0x40,  0x24,  0xF2,  0x80,  0x7C,  0x74, 	/* 196B0 */
+	0x40,  0x44,  0x77,  0xC0,  0x28,  0xF2,  0x89,  0x2A,  0x94,  0xAF,  0x86,  0xAD,  0x61,  0x00,  0xFE,  0xF1, 	/* 196C0 */
+	0x00,  0x7C,  0x70,  0x00,  0x7E,  0x74,  0x20,  0x2A,  0xF2,  0x89,  0x28,  0x94,  0xAF,  0x8E,  0xB0,  0x64, 	/* 196D0 */
+	0x40,  0x48,  0xF7,  0xE0,  0x48,  0xEC,  0x80,  0xFC,  0xE4,  0x80,  0x48,  0xF7,  0xC9,  0x48,  0x94,  0x8F, 	/* 196E0 */
+	0x7E,  0xB2,  0x77,  0xE0,  0x52,  0xF7,  0xE0,  0x52,  0x75,  0x20,  0x7E,  0x71,  0x00,  0xFE,  0xF3,  0x89, 	/* 196F0 */
+	0x54,  0x99,  0x2F,  0x10,  0xB9,  0x62,  0x80,  0x28,  0xFE,  0xE0,  0x28,  0x72,  0x80,  0xEE,  0x72,  0x80, 	/* 19700 */
+	0x28,  0xFE,  0xE9,  0x28,  0x94,  0x8F,  0x88,  0xBC,  0x71,  0x00,  0xFE,  0xF8,  0x20,  0x7C,  0x74,  0x40, 	/* 19710 */
+	0x44,  0x77,  0xC0,  0x44,  0xF7,  0xC9,  0x44,  0x94,  0x4F,  0xFE,  0xBF,  0x60,  0x00,  0xFE,  0xF9,  0x20, 	/* 19720 */
+	0xFE,  0x69,  0x20,  0xFE,  0x68,  0x20,  0xBA,  0xFA,  0xA9,  0xAA,  0x9B,  0xAF,  0x86,  0x82,  0x71,  0x00, 	/* 19730 */
+	0x1E,  0xF1,  0x20,  0x22,  0x74,  0xC0,  0x10,  0x76,  0xE0,  0x42,  0xF7,  0x69,  0x42,  0x94,  0x2F,  0x7E, 	/* 19740 */
+	0x84,  0x71,  0x00,  0xFE,  0xF0,  0x00,  0x7C,  0x74,  0x40,  0x7C,  0x70,  0x00,  0x7C,  0xF0,  0x89,  0xFE, 	/* 19750 */
+	0x91,  0x0F,  0x30,  0x87,  0x61,  0x00,  0x54,  0xF5,  0x40,  0x10,  0x72,  0x80,  0xD6,  0x71,  0x00,  0x54, 	/* 19760 */
+	0xF5,  0x49,  0x28,  0x94,  0x4F,  0x82,  0x8B,  0x61,  0x00,  0x7E,  0xF9,  0x00,  0x7C,  0x71,  0x00,  0xFE, 	/* 19770 */
+	0x74,  0x40,  0x7C,  0xF4,  0x49,  0x7C,  0x94,  0x4F,  0x4C,  0x8C,  0xE1,  0x00,  0xFE,  0xF1,  0x00,  0xFC, 	/* 19780 */
+	0xF9,  0x40,  0xFC,  0xE9,  0x40,  0xFC,  0xF3,  0x89,  0x54,  0x99,  0x2F,  0x10,  0x8D,  0x70,  0xE0,  0xF4, 	/* 19790 */
+	0xF5,  0x20,  0x8A,  0x77,  0xC0,  0x14,  0x7F,  0xE0,  0x14,  0xF7,  0xC9,  0x10,  0x91,  0x0F,  0x30,  0x8F, 	/* 197A0 */
+	0x60,  0x01,  0xE0,  0xEB,  0xE0,  0xAA,  0xEE,  0xA0,  0xAA,  0xEE,  0x40,  0xA4,  0xEA,  0xAA,  0xEA,  0xB3, 	/* 197B0 */
+	0x2E,  0x21,  0x92,  0x71,  0x00,  0x7E,  0xF8,  0x00,  0x7C,  0x74,  0x40,  0x44,  0x77,  0xC0,  0x10,  0xF5, 	/* 197C0 */
+	0x49,  0x52,  0x99,  0x2F,  0x30,  0x96,  0x71,  0x00,  0x28,  0xF2,  0x80,  0x44,  0x7F,  0xA0,  0x00,  0x7F, 	/* 197D0 */
+	0xE0,  0xAA,  0xFF,  0xE9,  0xAA,  0x9A,  0xAF,  0x86,  0x9A,  0x71,  0x00,  0x10,  0xFF,  0xE0,  0x82,  0x77, 	/* 197E0 */
+	0xC0,  0x10,  0x71,  0x00,  0x5C,  0xF5,  0x09,  0x70,  0x95,  0x8F,  0x86,  0x9B,  0x71,  0x00,  0x36,  0xFD, 	/* 197F0 */
+	0x20,  0x52,  0x77,  0x60,  0x52,  0x75,  0x20,  0x7E,  0xF1,  0x89,  0x28,  0x94,  0x4F,  0x82,  0x9C,  0x65, 	/* 19800 */
+	0x40,  0x54,  0xFF,  0xE0,  0x54,  0x75,  0xC0,  0x40,  0x77,  0xE0,  0x10,  0xFF,  0xE9,  0x38,  0x9D,  0x6F, 	/* 19810 */
+	0x10,  0x9E,  0x77,  0xE0,  0x00,  0xFF,  0xE0,  0x42,  0x77,  0xE0,  0x40,  0x77,  0xE0,  0x6A,  0xF7,  0xE9, 	/* 19820 */
+	0x6A,  0x9A,  0xAF,  0x26,  0xA0,  0x71,  0x00,  0xFE,  0xF8,  0x20,  0x7C,  0x70,  0x00,  0x7C,  0x74,  0x40, 	/* 19830 */
+	0x7C,  0xF4,  0x49,  0x7C,  0x90,  0x0F,  0xFE,  0xA1,  0x72,  0x80,  0x28,  0xF4,  0x40,  0xFE,  0x72,  0x10, 	/* 19840 */
+	0x3C,  0x70,  0x40,  0x18,  0xFF,  0xE9,  0xAA,  0x9A,  0xAF,  0xFF,  0xA2,  0x6F,  0xE0,  0x92,  0xF7,  0xC0, 	/* 19850 */
+	0x10,  0x77,  0xC0,  0x54,  0x77,  0xC0,  0x54,  0xF7,  0xC9,  0x10,  0x9F,  0xEF,  0x10,  0xA4,  0x7E,  0xE0, 	/* 19860 */
+	0xAA,  0xFE,  0xE0,  0x00,  0x77,  0xC0,  0x00,  0x7F,  0xE0,  0x40,  0xF7,  0xC9,  0x44,  0x90,  0x4F,  0x18, 	/* 19870 */
+	0xA6,  0x61,  0x00,  0xFE,  0xF4,  0x40,  0x28,  0x7F,  0xE0,  0x92,  0x77,  0xC0,  0x54,  0xF5,  0x49,  0x5C, 	/* 19880 */
+	0x95,  0x0F,  0x10,  0xA7,  0x75,  0x00,  0x56,  0xF7,  0x80,  0x50,  0x75,  0x20,  0xEE,  0x70,  0x00,  0x7C, 	/* 19890 */
+	0xF4,  0x49,  0x7C,  0x94,  0x4F,  0x7C,  0xAB,  0x71,  0x00,  0xFE,  0xF1,  0x00,  0xFE,  0x7D,  0x60,  0xBA, 	/* 198A0 */
+	0x7F,  0xE0,  0x10,  0xF3,  0x89,  0x54,  0x99,  0x2F,  0x10,  0xAD,  0x61,  0x00,  0x28,  0xF4,  0x60,  0xB8, 	/* 198B0 */
+	0xE0,  0x00,  0xEA,  0xEA,  0xA0,  0xEA,  0xEA,  0xAA,  0xEA,  0xAA,  0x2E,  0xA6,  0xAE,  0x6A,  0x00,  0x60, 	/* 198C0 */
+	0xF3,  0xE0,  0x2C,  0x74,  0x80,  0x94,  0x7A,  0x20,  0x00,  0xF7,  0xC9,  0x44,  0x94,  0x4F,  0x7C,  0xB1, 	/* 198D0 */
+	0x72,  0x00,  0x7C,  0xF2,  0x40,  0xFE,  0x74,  0x40,  0x7C,  0x70,  0x80,  0xFE,  0xF4,  0x89,  0xFE,  0x90, 	/* 198E0 */
+	0x8F,  0x08,  0xB3,  0x71,  0x00,  0x10,  0xFF,  0xE0,  0x44,  0x72,  0x80,  0xFE,  0x70,  0x00,  0x7C,  0xF4, 	/* 198F0 */
+	0x49,  0x7C,  0x94,  0x4F,  0x7C,  0xB7,  0x70,  0x00,  0x7E,  0xFC,  0xE0,  0x72,  0x75,  0x20,  0x7E,  0x75, 	/* 19900 */
+	0x60,  0x7E,  0xF5,  0xA9,  0x96,  0x99,  0xDF,  0x65,  0xB8,  0x72,  0x00,  0x7C,  0xF2,  0x40,  0x28,  0x7F, 	/* 19910 */
+	0xE0,  0x20,  0x77,  0xC0,  0xC4,  0xF7,  0xC9,  0x44,  0x94,  0x4F,  0x7C,  0xBA,  0x71,  0x00,  0x7E,  0xFA, 	/* 19920 */
+	0x40,  0x24,  0x77,  0xE0,  0x48,  0x77,  0x20,  0x44,  0xF5,  0x89,  0x42,  0x98,  0xCF,  0xB0,  0xBE,  0x64, 	/* 19930 */
+	0x80,  0xFE,  0xF4,  0x80,  0x28,  0x72,  0x00,  0xFE,  0x72,  0x00,  0x3C,  0xF6,  0x49,  0xA4,  0x92,  0x4F, 	/* 19940 */
+	0x3C,  0x80,  0x64,  0x40,  0xFE,  0xF4,  0x40,  0x7C,  0xE4,  0x40,  0x7C,  0xE1,  0x00,  0xFE,  0xF3,  0x89, 	/* 19950 */
+	0x54,  0x99,  0x2F,  0x10,  0x81,  0x77,  0xC0,  0x44,  0xFF,  0xC0,  0x44,  0x77,  0xC0,  0x20,  0x73,  0xE0, 	/* 19960 */
+	0x4A,  0xF7,  0x29,  0xAA,  0x93,  0xAF,  0x0C,  0x82,  0x70,  0x00,  0xFE,  0xF9,  0x20,  0xFE,  0xF9,  0x20, 	/* 19970 */
+	0xFE,  0xF4,  0x40,  0x7C,  0xF4,  0x49,  0x7C,  0x94,  0x4F,  0x4C,  0x84,  0xEA,  0x8A,  0xFC,  0xA2,  0x0B, 	/* 19980 */
+	0xFE,  0xE4,  0x8A,  0xB4,  0xB0,  0x2E,  0xFC,  0xA0,  0x0A,  0xFC,  0xA8,  0x4A,  0xFC,  0x87,  0x04,  0x0F, 	/* 19990 */
+	0xFE,  0x91,  0x2B,  0xFA,  0x11,  0x07,  0xFC,  0x24,  0x87,  0xFC,  0x8E,  0x23,  0xF8,  0x20,  0x83,  0xF8, 	/* 199A0 */
+	0x8C,  0x6F,  0xE0,  0x04,  0xF7,  0x40,  0x54,  0x77,  0x40,  0x0C,  0x7F,  0xE0,  0x04,  0xF7,  0x49,  0x54, 	/* 199B0 */
+	0x97,  0x4F,  0x0C,  0x8E,  0x60,  0x80,  0x2A,  0xF1,  0xC0,  0x88,  0xE7,  0xE1,  0xC8,  0xE5,  0xC0,  0x6A, 	/* 199C0 */
+	0xE4,  0x8A,  0x48,  0xAA,  0x0F,  0x1F,  0x90,  0x72,  0x00,  0x14,  0xF2,  0x20,  0xA8,  0x73,  0x20,  0xCE, 	/* 199D0 */
+	0x70,  0x00,  0x7C,  0xF5,  0x49,  0x54,  0x95,  0x4F,  0xFE,  0x94,  0x71,  0x00,  0x1E,  0xF1,  0x00,  0x7E, 	/* 199E0 */
+	0x75,  0x00,  0x7C,  0x74,  0xA0,  0x5E,  0xF5,  0x09,  0x7E,  0x99,  0x0F,  0x1E,  0x96,  0x77,  0xE0,  0x52, 	/* 199F0 */
+	0xFF,  0xE0,  0x52,  0x77,  0xE0,  0x28,  0x74,  0xE0,  0x9C,  0xF6,  0x49,  0x18,  0x93,  0x4F,  0xC2,  0x97, 	/* 19A00 */
+	0x71,  0x00,  0xFE,  0xF4,  0x40,  0x28,  0x7F,  0xE0,  0xA2,  0x7F,  0xC0,  0x20,  0xF3,  0xC9,  0x24,  0x94, 	/* 19A10 */
+	0x4F,  0x98,  0x99,  0xE4,  0x40,  0xFE,  0xF2,  0x80,  0xFE,  0xE2,  0xA0,  0xFF,  0xE2,  0xA0,  0xFE,  0xF2, 	/* 19A20 */
+	0x89,  0x6C,  0x9A,  0xAF,  0x28,  0x9A,  0x72,  0xC0,  0x24,  0xF4,  0x20,  0xBD,  0x70,  0x00,  0x3C,  0x72, 	/* 19A30 */
+	0x40,  0x42,  0xFF,  0xD9,  0x54,  0x95,  0x4F,  0xFE,  0x9B,  0x72,  0x80,  0x7E,  0xFA,  0x80,  0x7E,  0x72, 	/* 19A40 */
+	0x80,  0xFE,  0x75,  0x40,  0x7C,  0xF5,  0x49,  0xFE,  0x94,  0x4F,  0x4C,  0x9D,  0x64,  0x40,  0xE4,  0xFA, 	/* 19A50 */
+	0x40,  0xFE,  0xEA,  0x40,  0xE4,  0xEB,  0x41,  0xEC,  0xF6,  0x49,  0xA4,  0x92,  0x4F,  0x6C,  0xA0,  0x70, 	/* 19A60 */
+	0x80,  0x1E,  0xF6,  0xA0,  0x14,  0x71,  0x80,  0xE0,  0x77,  0xE0,  0x10,  0xFF,  0xE9,  0x10,  0x95,  0x2F, 	/* 19A70 */
+	0x7E,  0xA1,  0x60,  0x60,  0xFA,  0xF9,  0x20,  0x54,  0xE2,  0x80,  0xFE,  0xE1,  0x00,  0xFE,  0xE1,  0x0A, 	/* 19A80 */
+	0x92,  0xA9,  0x2E,  0xFE,  0xA6,  0x79,  0xC1,  0x14,  0xFE,  0x75,  0x7C,  0x7A,  0x44,  0x18,  0x86,  0x67, 	/* 19A90 */
+	0xFC,  0x0F,  0x01,  0xF8,  0x10,  0x81,  0xF8,  0xA8,  0x74,  0x80,  0xFE,  0xF4,  0x80,  0x7C,  0x74,  0x40, 	/* 19AA0 */
+	0x7C,  0x74,  0x40,  0x7C,  0xF1,  0x09,  0xFE,  0x92,  0x4F,  0xC2,  0xAB,  0x71,  0x00,  0xFE,  0xF4,  0x40, 	/* 19AB0 */
+	0x28,  0x77,  0xE0,  0x52,  0x77,  0xE0,  0x52,  0xF7,  0xA9,  0x6A,  0x97,  0xAF,  0x46,  0xAC,  0x6E,  0xE0, 	/* 19AC0 */
+	0x22,  0xFA,  0xA0,  0x66,  0xEB,  0xA0,  0x32,  0xE6,  0xC1,  0x93,  0xF6,  0x89,  0x36,  0x91,  0x8F,  0xE0, 	/* 19AD0 */
+	0xB3,  0x70,  0x00,  0x7E,  0xFC,  0x00,  0x5C,  0x75,  0x40,  0x5C,  0x77,  0xE0,  0x5A,  0xF5,  0xA9,  0x7E, 	/* 19AE0 */
+	0x94,  0x0F,  0x7E,  0xB9,  0x72,  0x40,  0xFE,  0xF2,  0x40,  0x7C,  0x75,  0x40,  0x7C,  0x71,  0x00,  0xFC, 	/* 19AF0 */
+	0xF1,  0x09,  0x7C,  0x91,  0x0F,  0xFE,  0xBE,  0x77,  0xC0,  0x44,  0xFF,  0xC0,  0x44,  0x7F,  0xE0,  0xAA, 	/* 19B00 */
+	0x7F,  0xE0,  0x00,  0xFF,  0xC9,  0x48,  0x93,  0x0F,  0xCC,  0x81,  0x72,  0x40,  0xFE,  0xF2,  0x40,  0xFE, 	/* 19B10 */
+	0x75,  0x40,  0xFF,  0x75,  0x40,  0xFE,  0xF1,  0x09,  0xFE,  0x91,  0x0F,  0x10,  0x89,  0x77,  0x40,  0x1C, 	/* 19B20 */
+	0xFA,  0xA0,  0x44,  0x7B,  0xA0,  0x01,  0x77,  0xC0,  0x44,  0xF7,  0xC9,  0x44,  0x92,  0x8F,  0xFE,  0x8C, 	/* 19B30 */
+	0x70,  0xE0,  0xF4,  0xF4,  0xA0,  0x78,  0x74,  0x80,  0x7C,  0x74,  0x40,  0x7E,  0xFA,  0xA9,  0x56,  0x98, 	/* 19B40 */
+	0x2F,  0x0C,  0x8E,  0x77,  0xC0,  0x28,  0xFF,  0xF0,  0x1A,  0x72,  0x80,  0xFE,  0x75,  0xA0,  0x6E,  0xF7, 	/* 19B50 */
+	0xA9,  0x6A,  0x97,  0xAF,  0x46,  0x8F,  0x62,  0x40,  0x48,  0xFF,  0xC0,  0x5A,  0x6F,  0xE0,  0x14,  0x7F, 	/* 19B60 */
+	0xE0,  0x94,  0xFD,  0x89,  0xAA,  0x91,  0x6F,  0x62,  0x96,  0x64,  0x41,  0xDE,  0xF5,  0x41,  0xFE,  0x6D, 	/* 19B70 */
+	0x41,  0x66,  0x60,  0x00,  0x7C,  0xF4,  0x49,  0x7C,  0x94,  0x4F,  0x7C,  0x98,  0xC4,  0x81,  0xEC,  0xEA, 	/* 19B80 */
+	0xA0,  0xA8,  0xFF,  0xF0,  0x08,  0xEE,  0xA0,  0xAA,  0xEE,  0xAA,  0xA4,  0xAE,  0xCE,  0x32,  0x9A,  0x6F, 	/* 19B90 */
+	0xE0,  0x28,  0xFF,  0xE0,  0xAA,  0x7F,  0xE0,  0x44,  0x77,  0xC0,  0x44,  0xF7,  0xC9,  0x10,  0x9F,  0xEF, 	/* 19BA0 */
+	0x10,  0x9B,  0x72,  0x40,  0x7E,  0xF2,  0x40,  0x7E,  0x72,  0x40,  0x5A,  0x79,  0x10,  0x7C,  0xF4,  0x49, 	/* 19BB0 */
+	0x7C,  0x94,  0x4F,  0x7C,  0x9C,  0x64,  0x40,  0x28,  0xFF,  0xE0,  0xAA,  0xE6,  0xC0,  0xFE,  0xE0,  0x00, 	/* 19BC0 */
+	0x7C,  0xF4,  0x49,  0x7C,  0x94,  0x4F,  0x7C,  0x9F,  0x77,  0x80,  0x48,  0xF7,  0x80,  0xEE,  0x7A,  0xA0, 	/* 19BD0 */
+	0xEE,  0x71,  0x00,  0xFE,  0xF3,  0x89,  0x54,  0x99,  0x2F,  0x10,  0xA6,  0x29,  0x0F,  0xDF,  0x46,  0x2F, 	/* 19BE0 */
+	0x54,  0x54,  0xC7,  0x73,  0x0C,  0x07,  0xFE,  0x0F,  0x03,  0xFC,  0x20,  0x43,  0xFC,  0xAB,  0x73,  0xC0, 	/* 19BF0 */
+	0x48,  0xFF,  0xE0,  0x54,  0x76,  0x60,  0x58,  0x74,  0x00,  0x7E,  0xF5,  0x89,  0x7C,  0x9A,  0x4F,  0x3C, 	/* 19C00 */
+	0xAC,  0x78,  0x84,  0xBE,  0x79,  0x44,  0x3E,  0x7C,  0x8A,  0x7C,  0x3C,  0x87,  0xFE,  0x0F,  0x01,  0xF8, 	/* 19C10 */
+	0x10,  0x81,  0xF8,  0xAF,  0x6F,  0xE0,  0xAA,  0xFF,  0xE0,  0x10,  0x77,  0xC0,  0x10,  0x7F,  0xE0,  0x44, 	/* 19C20 */
+	0xFF,  0xE9,  0x10,  0x97,  0xCF,  0x10,  0xB0,  0x72,  0x40,  0xFE,  0xF1,  0x00,  0x7C,  0x71,  0x00,  0xFE, 	/* 19C30 */
+	0x74,  0xA0,  0xFF,  0xF4,  0xC9,  0xEA,  0x95,  0x6F,  0xC2,  0xB1,  0x11,  0x0F,  0xFE,  0x04,  0x07,  0xFC, 	/* 19C40 */
+	0x04,  0x06,  0x4C,  0xFF,  0xE0,  0x40,  0x64,  0xCF,  0x5E,  0x95,  0x2F,  0x5E,  0xB2,  0x61,  0x00,  0xFE, 	/* 19C50 */
+	0xF2,  0x80,  0x44,  0x7A,  0xA0,  0xFC,  0x72,  0x80,  0xFE,  0xF5,  0x29,  0xCC,  0x97,  0x4F,  0xC2,  0xB4, 	/* 19C60 */
+	0x70,  0x80,  0x3E,  0xFA,  0xA0,  0x7F,  0x71,  0x20,  0xDE,  0x75,  0x00,  0x5E,  0xF5,  0x29,  0x5E,  0x9A, 	/* 19C70 */
+	0x0F,  0x1F,  0xB7,  0x62,  0x80,  0xFE,  0xF2,  0x80,  0x7E,  0x76,  0x80,  0xBE,  0x72,  0x80,  0x7E,  0xF4, 	/* 19C80 */
+	0x49,  0x38,  0x92,  0x8F,  0xC6,  0xBD,  0x1E,  0x02,  0x9C,  0x2E,  0x43,  0xAC,  0x2A,  0x4F,  0xFF,  0x26, 	/* 19C90 */
+	0x47,  0xFE,  0x8F,  0x11,  0xF8,  0x10,  0x81,  0xF8,  0x80,  0x71,  0x00,  0xFE,  0xF9,  0x00,  0xFE,  0x7A, 	/* 19CA0 */
+	0xA0,  0xFE,  0x74,  0x40,  0x7C,  0xF4,  0x49,  0x7C,  0x92,  0x4F,  0xC2,  0x83,  0x72,  0x80,  0x7E,  0xF2, 	/* 19CB0 */
+	0x80,  0xFE,  0x75,  0x40,  0xFE,  0x74,  0x40,  0x7C,  0xF4,  0x49,  0x7C,  0x92,  0x4F,  0xC2,  0x8A,  0x45, 	/* 19CC0 */
+	0x0A,  0xE8,  0x51,  0x2F,  0xFE,  0x6E,  0xCB,  0xBA,  0x2E,  0x80,  0x80,  0x1F,  0xE6,  0x88,  0x07,  0x0F, 	/* 19CD0 */
+	0x8E,  0x8C,  0x74,  0x80,  0xFE,  0xF4,  0x80,  0x78,  0x7C,  0xA0,  0x7C,  0x76,  0x80,  0xFA,  0xF4,  0xE9, 	/* 19CE0 */
+	0x00,  0x95,  0x4F,  0xAA,  0x8E,  0x26,  0x82,  0x08,  0x7F,  0xED,  0x14,  0x57,  0x47,  0x9E,  0x57,  0x45, 	/* 19CF0 */
+	0x14,  0x77,  0xE5,  0x54,  0x55,  0x47,  0xFE,  0x90,  0x52,  0x87,  0xBC,  0xD6,  0x8F,  0xFC,  0x52,  0x8F, 	/* 19D00 */
+	0xFE,  0x00,  0x03,  0xF8,  0x00,  0x03,  0xF8,  0x20,  0x83,  0xF8,  0x92,  0x73,  0x80,  0xD0,  0xF7,  0xC0, 	/* 19D10 */
+	0x44,  0x77,  0xC0,  0x4A,  0x7E,  0xE0,  0x7C,  0xF5,  0x49,  0x7C,  0x92,  0xAF,  0xCE,  0x93,  0x71,  0x00, 	/* 19D20 */
+	0xFE,  0xFA,  0xA0,  0xEE,  0x72,  0x80,  0xFE,  0x72,  0x80,  0xFE,  0xF2,  0x29,  0xD4,  0x94,  0x8F,  0x66, 	/* 19D30 */
+	0x96,  0x6A,  0xA0,  0xAA,  0xF5,  0x80,  0xFE,  0x75,  0x80,  0xFA,  0x75,  0x60,  0xDC,  0xF5,  0x49,  0xDE, 	/* 19D40 */
+	0x95,  0xBF,  0xE9,  0x99,  0x72,  0x80,  0xFE,  0xF2,  0x80,  0xEE,  0x7A,  0xA0,  0xEE,  0x72,  0x40,  0x7E, 	/* 19D50 */
+	0xFC,  0x89,  0x7C,  0x94,  0x8F,  0x7E,  0x9A,  0x66,  0x40,  0x7E,  0xFA,  0x40,  0xFE,  0x76,  0xC0,  0xB6, 	/* 19D60 */
+	0x70,  0x00,  0x7C,  0xF4,  0x49,  0x7C,  0x94,  0x4F,  0x7C,  0xB7,  0x11,  0x01,  0x08,  0x24,  0x44,  0x44, 	/* 19D70 */
+	0x0A,  0x01,  0x10,  0x20,  0x8F,  0xFE,  0x20,  0x82,  0x08,  0x20,  0x83,  0xF8,  0xBA,  0x28,  0x02,  0x7E, 	/* 19D80 */
+	0x52,  0x41,  0x24,  0x2A,  0x44,  0x7F,  0x80,  0xC7,  0x94,  0x49,  0x44,  0xA4,  0x4C,  0x47,  0x8C,  0xBF, 	/* 19D90 */
+	0x1A,  0x8F,  0x24,  0xAD,  0x42,  0x10,  0xDA,  0x82,  0xA4,  0xFC,  0x22,  0x3D,  0xFA,  0x43,  0x24,  0x4A, 	/* 19DA0 */
+	0x48,  0x3C,  0x81,  0x22,  0x8F,  0xA4,  0xAD,  0x4F,  0x90,  0x22,  0x87,  0xA4,  0x24,  0x2F,  0xBD,  0x22, 	/* 19DB0 */
+	0x4F,  0xA4,  0x8A,  0x4F,  0xBC,  0x86,  0x00,  0x07,  0xFE,  0x00,  0x03,  0xFC,  0x20,  0x42,  0x04,  0x3F, 	/* 19DC0 */
+	0xC2,  0x08,  0x10,  0x80,  0x90,  0x01,  0x07,  0xFE,  0x88,  0x04,  0x04,  0x44,  0x7F,  0xC0,  0x00,  0xFF, 	/* 19DD0 */
+	0xE0,  0x00,  0x3F,  0x82,  0x08,  0x3F,  0x81,  0x10,  0x0A,  0x0F,  0xFE,  0x8A,  0x0A,  0x07,  0xFC,  0x4A, 	/* 19DE0 */
+	0x47,  0xFC,  0x4A,  0x4F,  0xFE,  0x00,  0x03,  0xF8,  0x20,  0x83,  0xF8,  0x11,  0x0F,  0xFE,  0x8C,  0x01, 	/* 19DF0 */
+	0x0F,  0xFE,  0x08,  0x2F,  0x40,  0x97,  0xE9,  0x5A,  0xF5,  0xA1,  0xAE,  0x52,  0x82,  0x48,  0x34,  0xAC, 	/* 19E00 */
+	0x86,  0x8E,  0x00,  0x0F,  0xFC,  0xA2,  0x4F,  0x98,  0xA2,  0x4F,  0xC2,  0x00,  0x07,  0xFC,  0x20,  0x83, 	/* 19E10 */
+	0xF8,  0x11,  0x0F,  0xFE,  0x90,  0x95,  0x2B,  0xFA,  0x95,  0x2B,  0xFA,  0x95,  0x2F,  0xFE,  0x00,  0x07, 	/* 19E20 */
+	0xFC,  0x20,  0x83,  0xF8,  0x11,  0x0F,  0xFE,  0x95,  0x00,  0x0F,  0xFE,  0x04,  0x01,  0x84,  0xE5,  0x40, 	/* 19E30 */
+	0xB8,  0x32,  0x8C,  0x68,  0x0A,  0x43,  0x22,  0xC2,  0x00,  0xC0,  0x9A,  0x00,  0x07,  0xFE,  0x51,  0x05, 	/* 19E40 */
+	0x30,  0x7D,  0xA5,  0x2C,  0x5C,  0x87,  0x1C,  0x52,  0xA5,  0xC9,  0x50,  0x8B,  0x30,  0xA1,  0x1E,  0x0E, 	/* 19E50 */
+	0x40,  0x3F,  0x82,  0x48,  0x3F,  0xA1,  0xC4,  0xE7,  0x81,  0xB0,  0x66,  0x81,  0xA4,  0x62,  0x20,  0xC0, 	/* 19E60 */
+	0xA2,  0x04,  0x02,  0x48,  0x7F,  0xC0,  0xA0,  0xFF,  0xE2,  0x08,  0x5F,  0x48,  0xCA,  0x73,  0x00,  0xE8, 	/* 19E70 */
+	0x72,  0x40,  0xC0,  0xAA,  0x04,  0x0F,  0xFE,  0x1F,  0x01,  0x10,  0xFF,  0xE8,  0x02,  0x3F,  0x80,  0xA4, 	/* 19E80 */
+	0x73,  0x80,  0xD4,  0x71,  0x20,  0x60,  0xAB,  0x03,  0xCF,  0x48,  0x2F,  0xEC,  0x92,  0x2F,  0xEF,  0x32, 	/* 19E90 */
+	0x5D,  0x46,  0x68,  0x49,  0xC4,  0x6A,  0x58,  0x9C,  0x30,  0xAC,  0x01,  0x0F,  0xD0,  0x23,  0xE6,  0x54, 	/* 19EA0 */
+	0xB7,  0xE5,  0x90,  0x9B,  0xC3,  0x64,  0x53,  0xC9,  0x24,  0x12,  0x46,  0x3C,  0xB8,  0x01,  0x00,  0x60, 	/* 19EB0 */
+	0x79,  0x40,  0x98,  0x0E,  0x0F,  0x30,  0x0C,  0x87,  0x18,  0x02,  0x80,  0xC8,  0x70,  0x80,  0x30,  0xB9, 	/* 19EC0 */
+	0x09,  0x03,  0x10,  0xD1,  0xE5,  0x12,  0x3A,  0x2F,  0x32,  0x14,  0xA3,  0x8A,  0xC8,  0x23,  0x82,  0xC8, 	/* 19ED0 */
+	0x23,  0x0C,  0xBA,  0x08,  0x83,  0x08,  0xD0,  0x85,  0xFE,  0x30,  0x8D,  0x18,  0x29,  0x8C,  0xA8,  0x1A, 	/* 19EE0 */
+	0x8E,  0xC8,  0x08,  0x83,  0x18,  0xBC,  0x0A,  0x83,  0x28,  0xD2,  0x85,  0xA8,  0x33,  0xAD,  0x2C,  0x2A, 	/* 19EF0 */
+	0x8C,  0xA8,  0x1A,  0x8E,  0xAA,  0x0B,  0xA3,  0x46,  0x82,  0x08,  0x03,  0x7E,  0xD1,  0x25,  0x92,  0x32, 	/* 19F00 */
+	0x2D,  0x4C,  0x28,  0x0C,  0xBE,  0x1A,  0x2E,  0xA2,  0x0A,  0x23,  0x3E,  0x85,  0x12,  0x82,  0x28,  0xDA, 	/* 19F10 */
+	0x85,  0x7E,  0x34,  0x8E,  0xDC,  0x35,  0xCD,  0x6A,  0x34,  0xAD,  0x49,  0x14,  0x86,  0x48,  0x89,  0x09, 	/* 19F20 */
+	0x03,  0x3E,  0xD4,  0x45,  0xA4,  0x31,  0x8D,  0x24,  0x2C,  0x2C,  0xBC,  0x1A,  0x4E,  0xA4,  0x0A,  0x43, 	/* 19F30 */
+	0x3C,  0x8A,  0x08,  0x03,  0x7F,  0xD0,  0x85,  0x50,  0x3B,  0xED,  0x22,  0x2A,  0x2C,  0xBE,  0x1A,  0x2E, 	/* 19F40 */
+	0xA2,  0x0A,  0x23,  0x3E,  0x8C,  0x09,  0x03,  0x20,  0xD7,  0xC5,  0x44,  0x3F,  0xCF,  0x44,  0x37,  0xCC, 	/* 19F50 */
+	0xA8,  0x3A,  0x8C,  0xAA,  0x0A,  0xA3,  0x46,  0x8D,  0x08,  0x03,  0x3E,  0xD2,  0xA5,  0x6A,  0x3B,  0xED, 	/* 19F60 */
+	0x2A,  0x2B,  0xEC,  0x88,  0x1B,  0xEE,  0x88,  0x08,  0x83,  0x7F,  0x8E,  0x09,  0x03,  0x26,  0xD2,  0x25, 	/* 19F70 */
+	0x76,  0x3A,  0x2D,  0x22,  0x2B,  0xEC,  0x98,  0x19,  0x8E,  0xAA,  0x0A,  0xA3,  0x46,  0x94,  0x12,  0x0E, 	/* 19F80 */
+	0xFE,  0xAA,  0xA6,  0x92,  0x7E,  0xAA,  0x8A,  0x6F,  0xE9,  0x4A,  0x37,  0xCD,  0x48,  0x17,  0xA6,  0xC6, 	/* 19F90 */
+	0x98,  0x0A,  0x43,  0x7E,  0xD3,  0xC5,  0x24,  0x3B,  0xCD,  0x24,  0x2B,  0xCC,  0x90,  0x1F,  0xEE,  0x98, 	/* 19FA0 */
+	0x0A,  0x43,  0x42,  0x9D,  0x00,  0x03,  0xF8,  0x20,  0x82,  0x08,  0x3F,  0x82,  0x08,  0x3F,  0x82,  0x08, 	/* 19FB0 */
+	0x20,  0x83,  0xF8,  0x1B,  0x06,  0x0C,  0x9E,  0x04,  0x00,  0x7C,  0x04,  0x03,  0xF8,  0x20,  0x83,  0xF8, 	/* 19FC0 */
+	0x20,  0x83,  0xF8,  0x20,  0x83,  0xF8,  0x19,  0x86,  0x06,  0xA0,  0x08,  0x01,  0xF0,  0xE2,  0x03,  0xF8, 	/* 19FD0 */
+	0x20,  0x83,  0xF8,  0x20,  0x83,  0xF8,  0x20,  0x83,  0xF8,  0x1B,  0x0E,  0x0C,  0xA1,  0x00,  0x47,  0x84, 	/* 19FE0 */
+	0x48,  0x47,  0xFE,  0x48,  0x47,  0x8C,  0x48,  0xC4,  0x94,  0x7A,  0x42,  0xC4,  0x44,  0x48,  0x0C,  0xA2, 	/* 19FF0 */
+	0x00,  0x03,  0xF8,  0x04,  0x0F,  0xFE,  0x20,  0x83,  0xF8,  0x20,  0x83,  0xF8,  0x20,  0x83,  0xF8,  0x1B, 	/* 1A000 */
+	0x0E,  0x0C,  0xA7,  0x0A,  0x01,  0x10,  0x3F,  0x8C,  0x56,  0x19,  0x03,  0xF8,  0x20,  0x83,  0xF8,  0x20, 	/* 1A010 */
+	0x83,  0xF8,  0x0B,  0x07,  0x0C,  0xA8,  0x0A,  0x63,  0x38,  0xD2,  0x23,  0xFE,  0x20,  0x83,  0xF8,  0x20, 	/* 1A020 */
+	0x83,  0xF8,  0x20,  0x83,  0xF8,  0x31,  0x8C,  0x04,  0xA9,  0x00,  0x0F,  0x7E,  0x94,  0x0F,  0x40,  0x97, 	/* 1A030 */
+	0xCF,  0x44,  0x94,  0x49,  0x64,  0xF5,  0x85,  0x48,  0x49,  0x49,  0x62,  0xAA,  0x04,  0x00,  0xA0,  0x3F, 	/* 1A040 */
+	0x8C,  0x16,  0x0E,  0x03,  0xF8,  0x20,  0x83,  0xF8,  0x20,  0x83,  0xF8,  0x10,  0xCE,  0x02,  0xAB,  0x00, 	/* 1A050 */
+	0x03,  0xF8,  0x24,  0x8F,  0xFE,  0x49,  0x07,  0xF8,  0x20,  0x83,  0xF8,  0x20,  0x83,  0xF8,  0x19,  0x86, 	/* 1A060 */
+	0x06,  0xAC,  0x04,  0x07,  0xFC,  0x04,  0x03,  0xF8,  0x04,  0x0F,  0xFE,  0x20,  0x83,  0xF8,  0x20,  0x83, 	/* 1A070 */
+	0xF8,  0x19,  0x06,  0x0C,  0xAD,  0x00,  0xC3,  0xF0,  0x22,  0x03,  0xFE,  0x22,  0x02,  0xFC,  0x28,  0x42, 	/* 1A080 */
+	0xFC,  0x48,  0x44,  0xFC,  0x8C,  0x43,  0x02,  0xAE,  0x01,  0x07,  0xD8,  0x01,  0x4F,  0xFE,  0x45,  0x07, 	/* 1A090 */
+	0xD0,  0x45,  0x07,  0xD0,  0x44,  0x87,  0xCA,  0x24,  0x6C,  0x22,  0xAF,  0x01,  0x0F,  0xFE,  0x98,  0x29, 	/* 1A0A0 */
+	0x00,  0xF7,  0xE9,  0x10,  0xF1,  0x09,  0x10,  0xF1,  0x03,  0x10,  0x49,  0x08,  0x30,  0xB0,  0x49,  0x0F, 	/* 1A0B0 */
+	0xFE,  0x49,  0x07,  0xFE,  0x20,  0x83,  0xF8,  0x20,  0x83,  0xF8,  0x20,  0x83,  0xF8,  0x19,  0x8E,  0x06, 	/* 1A0C0 */
+	0xB2,  0x12,  0x01,  0xE4,  0x53,  0x85,  0xA2,  0xE1,  0xE3,  0xF8,  0x20,  0x83,  0xF8,  0x20,  0x83,  0xF8, 	/* 1A0D0 */
+	0x10,  0xC6,  0x02,  0xB3,  0x01,  0x80,  0x14,  0xFF,  0xE0,  0x10,  0xFF,  0x00,  0x10,  0x7D,  0x04,  0x48, 	/* 1A0E0 */
+	0x7C,  0x84,  0x4A,  0x7C,  0x6C,  0x22,  0xB4,  0x04,  0x03,  0xF8,  0x24,  0x8F,  0xFE,  0x00,  0x03,  0xF8, 	/* 1A0F0 */
+	0x20,  0x83,  0xF8,  0x20,  0x83,  0xF8,  0x11,  0x86,  0x04,  0xB6,  0x00,  0xCF,  0xF0,  0x91,  0x09,  0x10, 	/* 1A100 */
+	0xFF,  0xC9,  0x04,  0xF0,  0x89,  0x08,  0xF5,  0x02,  0x60,  0x55,  0x08,  0x8E,  0xB7,  0x00,  0x07,  0xFC, 	/* 1A110 */
+	0x4A,  0x47,  0xFC,  0x20,  0x83,  0xF8,  0x20,  0x83,  0xF8,  0x20,  0x83,  0xF8,  0x11,  0x86,  0x04,  0xB8, 	/* 1A120 */
+	0x12,  0x42,  0xFE,  0xE2,  0x02,  0x12,  0x20,  0xE3,  0xFA,  0x20,  0x83,  0xF8,  0x20,  0x83,  0xF8,  0x11, 	/* 1A130 */
+	0x8E,  0x06,  0xBB,  0x11,  0x0F,  0xFC,  0x51,  0x4F,  0xFE,  0x11,  0x23,  0xFC,  0x20,  0x83,  0xF8,  0x20, 	/* 1A140 */
+	0x83,  0xF8,  0x11,  0x86,  0x06,  0xBC,  0x00,  0x87,  0x88,  0x48,  0x87,  0x8F,  0x48,  0x87,  0x88,  0x48, 	/* 1A150 */
+	0x84,  0xBE,  0x7A,  0x22,  0xA2,  0x46,  0x28,  0x3E,  0xBD,  0x01,  0x07,  0x90,  0x49,  0x04,  0xA8,  0x7A, 	/* 1A160 */
+	0x44,  0xFA,  0x78,  0x24,  0xBC,  0x7A,  0x42,  0xA4,  0x46,  0x48,  0x3C,  0xBF,  0x7B,  0xE4,  0x12,  0x51, 	/* 1A170 */
+	0x27,  0xA6,  0xCC,  0x03,  0xF8,  0x20,  0x83,  0xF8,  0x20,  0x83,  0xF8,  0x1B,  0x06,  0x0C,  0x80,  0x20, 	/* 1A180 */
+	0x0F,  0xBE,  0x2A,  0x24,  0xA2,  0x9B,  0xE3,  0xF8,  0x20,  0x83,  0xF8,  0x20,  0x83,  0xF8,  0x11,  0x0E, 	/* 1A190 */
+	0x0C,  0x81,  0x04,  0x07,  0xFC,  0x15,  0x0F,  0xFE,  0x11,  0x03,  0xF8,  0x20,  0x83,  0xF8,  0x20,  0x83, 	/* 1A1A0 */
+	0xF8,  0x10,  0xCE,  0x02,  0x82,  0x02,  0x0F,  0x3C,  0x92,  0x49,  0x68,  0xF1,  0x89,  0x2C,  0xF4,  0x39, 	/* 1A1B0 */
+	0xBC,  0x92,  0x4F,  0x24,  0x52,  0x48,  0xBC,  0x83,  0x2F,  0xC2,  0x10,  0x7F,  0xEA,  0x10,  0x27,  0xC3, 	/* 1A1C0 */
+	0xF8,  0x20,  0x83,  0xF8,  0x20,  0x83,  0xF8,  0x1B,  0x06,  0x0C,  0x84,  0x02,  0x0F,  0x20,  0x9F,  0xEF, 	/* 1A1D0 */
+	0x20,  0x97,  0xC9,  0x44,  0xFF,  0xC9,  0x44,  0xF7,  0xC2,  0x44,  0x54,  0x48,  0x4C,  0x87,  0x44,  0x02, 	/* 1A1E0 */
+	0x7E,  0x09,  0x41,  0x30,  0x24,  0xCF,  0xFA,  0x20,  0x83,  0xF8,  0x20,  0x83,  0xF8,  0x18,  0x86,  0x04, 	/* 1A1F0 */
+	0x88,  0x00,  0x0F,  0xFE,  0x0A,  0x07,  0xFC,  0x4A,  0x47,  0xFC,  0x20,  0x83,  0xF8,  0x20,  0x83,  0xF8, 	/* 1A200 */
+	0x10,  0xCE,  0x02,  0x8A,  0x00,  0x8F,  0x0A,  0x9F,  0xE9,  0x08,  0xF2,  0xA9,  0x2A,  0xFF,  0xA9,  0x24, 	/* 1A210 */
+	0xF2,  0x42,  0x2E,  0x53,  0x28,  0x22,  0x8D,  0x00,  0x87,  0xBE,  0x4A,  0x84,  0xA8,  0x7A,  0x84,  0xBE, 	/* 1A220 */
+	0x7A,  0x84,  0xA8,  0x7A,  0x82,  0xC8,  0x44,  0x88,  0xBE,  0x8E,  0x02,  0x8F,  0x24,  0x93,  0xC9,  0xE0, 	/* 1A230 */
+	0xF3,  0xC9,  0xE0,  0xF3,  0xE9,  0xD4,  0xF1,  0x42,  0x0A,  0x51,  0x68,  0x62,  0x91,  0x00,  0x0F,  0x7E, 	/* 1A240 */
+	0x94,  0x09,  0x7E,  0xF4,  0x09,  0x7E,  0xF5,  0x29,  0x5C,  0x95,  0x8F,  0x54,  0x55,  0xA8,  0xB1,  0x93, 	/* 1A250 */
+	0x00,  0x0F,  0xFE,  0x94,  0xA2,  0x54,  0xCE,  0x23,  0xFA,  0xE0,  0x83,  0xF8,  0x20,  0x83,  0xF8,  0x11, 	/* 1A260 */
+	0x8E,  0x06,  0x9A,  0x04,  0x0F,  0xFE,  0x44,  0x4A,  0xEA,  0x35,  0x8C,  0x46,  0x3F,  0x82,  0x08,  0x3F, 	/* 1A270 */
+	0x82,  0x08,  0x3F,  0x86,  0x0C,  0x9B,  0x20,  0x87,  0xBC,  0x20,  0x8F,  0xBE,  0x51,  0x4B,  0xFA,  0x20, 	/* 1A280 */
+	0x83,  0xF8,  0x20,  0x83,  0xF8,  0x19,  0x86,  0x04,  0x9C,  0x00,  0x0F,  0x7C,  0x94,  0x49,  0x7C,  0xF4, 	/* 1A290 */
+	0x49,  0x7C,  0xF2,  0x09,  0x7E,  0xFA,  0xA2,  0x52,  0x52,  0x28,  0x4C,  0x9E,  0x24,  0x81,  0x50,  0xFF, 	/* 1A2A0 */
+	0xE9,  0xF2,  0x91,  0x23,  0xF8,  0x20,  0x83,  0xF8,  0x20,  0x83,  0xF8,  0x0B,  0x07,  0x0C,  0xA0,  0x01, 	/* 1A2B0 */
+	0x07,  0x90,  0x4F,  0xE7,  0xC4,  0x4A,  0x87,  0xFE,  0x48,  0x04,  0xBC,  0x7A,  0x42,  0xA4,  0x46,  0x48, 	/* 1A2C0 */
+	0x3C,  0xA2,  0xFF,  0xEA,  0x24,  0xF9,  0x88,  0x94,  0xFE,  0x23,  0xF8,  0x20,  0x83,  0xF8,  0x20,  0x83, 	/* 1A2D0 */
+	0xF8,  0x19,  0x8E,  0x06,  0xA3,  0x04,  0x0F,  0xFE,  0x04,  0x07,  0xFC,  0x4A,  0x47,  0xFC,  0x20,  0x83, 	/* 1A2E0 */
+	0xF8,  0x20,  0x83,  0xF8,  0x10,  0xCE,  0x02,  0xA4,  0x01,  0x4F,  0x16,  0x9F,  0xAF,  0x0C,  0x91,  0x69, 	/* 1A2F0 */
+	0x62,  0xF1,  0x49,  0x1E,  0xFF,  0x42,  0x08,  0x51,  0x68,  0x62,  0xA6,  0x00,  0x6F,  0x75,  0x90,  0x49, 	/* 1A300 */
+	0xFF,  0xF1,  0x49,  0x54,  0xF5,  0xC9,  0x54,  0x95,  0x4F,  0x5A,  0x57,  0x28,  0xC1,  0xAA,  0x18,  0xC6, 	/* 1A310 */
+	0x30,  0x7B,  0xE5,  0x28,  0x94,  0x83,  0xF8,  0x20,  0x83,  0xF8,  0x20,  0x83,  0xF8,  0x11,  0x86,  0x04, 	/* 1A320 */
+	0xAD,  0x01,  0x0F,  0x7E,  0x91,  0x0F,  0x14,  0x9F,  0xEF,  0x10,  0x93,  0xC9,  0x64,  0xFB,  0xC5,  0x24, 	/* 1A330 */
+	0x4A,  0x48,  0x3C,  0xBA,  0x0D,  0x8F,  0xFC,  0xA5,  0x0A,  0xFC,  0xE5,  0x4B,  0xFE,  0xE5,  0x4B,  0xFC, 	/* 1A340 */
+	0xED,  0x46,  0xD8,  0x55,  0x68,  0x50,  0xBB,  0x02,  0x8F,  0xFE,  0xA2,  0x0E,  0xFC,  0xAA,  0x4A,  0xFC, 	/* 1A350 */
+	0xEA,  0x4A,  0x08,  0xFF,  0xE6,  0x88,  0x54,  0x88,  0x18,  0xBC,  0x04,  0x8F,  0xFE,  0x94,  0x89,  0xFC, 	/* 1A360 */
+	0xF4,  0x89,  0xFE,  0xF5,  0x49,  0x7C,  0xF5,  0x42,  0xFE,  0x54,  0x48,  0x4C,  0xBD,  0x04,  0x0F,  0xFE, 	/* 1A370 */
+	0x91,  0x27,  0xFC,  0x11,  0x0F,  0xFE,  0x20,  0x8F,  0xFE,  0x20,  0x83,  0xF8,  0x11,  0x86,  0x04,  0x84, 	/* 1A380 */
+	0x71,  0x02,  0x7C,  0xF9,  0x45,  0x54,  0xFA,  0x42,  0x56,  0x3F,  0x82,  0x08,  0x3F,  0x82,  0x08,  0x3F, 	/* 1A390 */
+	0x86,  0x0C,  0x85,  0x22,  0x0F,  0xBE,  0x26,  0x4F,  0xD4,  0x51,  0x8B,  0x66,  0x3F,  0x82,  0x08,  0x3F, 	/* 1A3A0 */
+	0x82,  0x08,  0x3F,  0x86,  0x0C,  0x87,  0x23,  0x4F,  0xFE,  0x51,  0x42,  0x5C,  0x55,  0x6B,  0xFA,  0x20, 	/* 1A3B0 */
+	0x83,  0xF8,  0x20,  0x83,  0xF8,  0x11,  0x86,  0x04,  0x88,  0x04,  0x4F,  0x28,  0x9F,  0xEF,  0x92,  0x9F, 	/* 1A3C0 */
+	0xEF,  0x92,  0x9F,  0xE9,  0x44,  0xF7,  0xC2,  0x44,  0x54,  0x48,  0x7C,  0x8A,  0x63,  0x07,  0xBC,  0xA5, 	/* 1A3D0 */
+	0x0F,  0xFC,  0x52,  0x89,  0xCE,  0x3F,  0x82,  0x08,  0x3F,  0x82,  0x08,  0x3F,  0x86,  0x0C,  0x8B,  0x00, 	/* 1A3E0 */
+	0x07,  0xFE,  0x4A,  0x87,  0xFE,  0x54,  0x85,  0x7E,  0x5F,  0x85,  0x08,  0x9F,  0x89,  0x08,  0x1F,  0x83, 	/* 1A3F0 */
+	0x9C,  0x8D,  0x03,  0x8F,  0x50,  0x9F,  0xE9,  0x58,  0xF6,  0xE9,  0x58,  0xF7,  0xE9,  0x40,  0xF5,  0x82, 	/* 1A400 */
+	0xBC,  0x52,  0x48,  0x3C,  0x8F,  0x04,  0x0F,  0xFE,  0x40,  0x07,  0xFC,  0x20,  0x83,  0xF8,  0x79,  0xC5, 	/* 1A410 */
+	0xF4,  0x79,  0xC5,  0xF4,  0x75,  0x49,  0xA6,  0x90,  0x02,  0x0F,  0x7C,  0x92,  0x4F,  0xFE,  0x92,  0x49, 	/* 1A420 */
+	0xFC,  0xF6,  0xA9,  0x95,  0xF7,  0xE2,  0x5A,  0x55,  0xA8,  0xFF,  0x93,  0x00,  0xCF,  0x0A,  0x97,  0xF9, 	/* 1A430 */
+	0x48,  0xF7,  0xA9,  0xDA,  0xF7,  0xA9,  0xD4,  0xF7,  0x43,  0x54,  0x4B,  0xB9,  0x11,  0x94,  0x1F,  0x01, 	/* 1A440 */
+	0x10,  0x1F,  0x01,  0x10,  0x1F,  0x00,  0xA0,  0x71,  0xC4,  0xA4,  0x7B,  0xC4,  0xA4,  0x7B,  0xCC,  0x66, 	/* 1A450 */
+	0x96,  0x01,  0x0F,  0xFE,  0x91,  0x09,  0xFE,  0xFA,  0xA9,  0xFE,  0xF4,  0x49,  0x7C,  0xF4,  0x42,  0x7C, 	/* 1A460 */
+	0x52,  0x48,  0x42,  0xA4,  0x04,  0x00,  0x40,  0x3F,  0x80,  0x40,  0x04,  0x0F,  0xFE,  0x09,  0x02,  0x94, 	/* 1A470 */
+	0x29,  0x24,  0x92,  0x11,  0x02,  0x30,  0xA6,  0x22,  0x02,  0x20,  0xFB,  0xE2,  0x24,  0x24,  0x4F,  0xD4, 	/* 1A480 */
+	0x51,  0x8D,  0x88,  0xD5,  0x85,  0x54,  0x52,  0x4B,  0x42,  0xA7,  0x10,  0x01,  0x3E,  0x7E,  0x21,  0x3E, 	/* 1A490 */
+	0xFE,  0x02,  0xBE,  0x2B,  0x26,  0xEA,  0x6A,  0x4A,  0xAC,  0x2B,  0x25,  0xA1,  0xAB,  0x11,  0x01,  0x10, 	/* 1A4A0 */
+	0x7F,  0xC1,  0x10,  0xFF,  0xE2,  0xA8,  0x2A,  0x86,  0xEC,  0xAA,  0xA2,  0xA8,  0x4C,  0x84,  0xC8,  0xAD, 	/* 1A4B0 */
+	0x10,  0x81,  0x08,  0x7F,  0xE1,  0x0A,  0xFF,  0xF2,  0x94,  0x2B,  0xE6,  0xD2,  0x69,  0xEA,  0x92,  0x29, 	/* 1A4C0 */
+	0x25,  0x9E,  0xB0,  0x04,  0x00,  0x40,  0x7F,  0xC0,  0x40,  0x04,  0x0F,  0xFE,  0x04,  0x02,  0x40,  0x27, 	/* 1A4D0 */
+	0xC3,  0x40,  0x4C,  0x08,  0x3E,  0xB1,  0x04,  0x00,  0x40,  0x7F,  0xC0,  0x40,  0xFF,  0xE1,  0x00,  0x08, 	/* 1A4E0 */
+	0x40,  0x88,  0x23,  0x02,  0xC0,  0x58,  0x08,  0x7F,  0xB3,  0x10,  0x41,  0x24,  0x7A,  0x41,  0x24,  0xFE, 	/* 1A4F0 */
+	0x41,  0x24,  0x52,  0xE5,  0xF4,  0x70,  0x45,  0x04,  0x4C,  0x08,  0x3F,  0xB4,  0x11,  0x01,  0x10,  0x7D, 	/* 1A500 */
+	0x01,  0x10,  0xFD,  0x81,  0x14,  0x5D,  0x25,  0x12,  0x51,  0x07,  0x10,  0x4C,  0x08,  0x3F,  0xB7,  0x10, 	/* 1A510 */
+	0x01,  0x3C,  0x7C,  0x41,  0x04,  0xFF,  0xC1,  0x20,  0x52,  0x05,  0xE2,  0x72,  0x25,  0x1E,  0x8C,  0x08, 	/* 1A520 */
+	0x3F,  0x81,  0x10,  0x81,  0x08,  0x79,  0x41,  0x2A,  0xFF,  0x51,  0x08,  0x51,  0x25,  0xE4,  0x70,  0x85, 	/* 1A530 */
+	0x30,  0x4C,  0x08,  0x3F,  0x85,  0x10,  0x01,  0x7E,  0x79,  0x21,  0x12,  0xFA,  0xC1,  0x40,  0x53,  0xE5, 	/* 1A540 */
+	0xE2,  0x72,  0x25,  0x3E,  0x8C,  0x08,  0x3F,  0x8A,  0x10,  0x81,  0x0A,  0x7B,  0xE1,  0x28,  0xFE,  0xA1, 	/* 1A550 */
+	0x2A,  0x5E,  0x45,  0x2E,  0x77,  0x25,  0x02,  0x8C,  0x08,  0x3F,  0x99,  0x11,  0x01,  0x34,  0x7D,  0x21, 	/* 1A560 */
+	0x3C,  0xFE,  0x41,  0x3C,  0x52,  0x45,  0xFC,  0x72,  0x45,  0x2C,  0x4C,  0x08,  0x3F,  0xA3,  0x20,  0x02, 	/* 1A570 */
+	0xFE,  0xF5,  0x02,  0x7E,  0x25,  0x2F,  0xFA,  0x25,  0x4B,  0x54,  0xEF,  0xAA,  0x12,  0x99,  0x08,  0x7F, 	/* 1A580 */
+	0xA8,  0x22,  0x02,  0x3E,  0xF4,  0xA2,  0xBE,  0x20,  0xAF,  0xB2,  0x23,  0xEB,  0xCA,  0xEB,  0xEA,  0x12, 	/* 1A590 */
+	0x9A,  0x48,  0x7F,  0xB3,  0x00,  0x03,  0xFC,  0x20,  0x42,  0x04,  0x3F,  0xC0,  0x40,  0x24,  0x02,  0x7C, 	/* 1A5A0 */
+	0x24,  0x03,  0x40,  0x4E,  0x08,  0x1E,  0xBA,  0x01,  0x0F,  0x10,  0x97,  0xC9,  0x10,  0xF1,  0x02,  0xFE, 	/* 1A5B0 */
+	0xA1,  0x0B,  0x10,  0xA2,  0x8A,  0x28,  0xB4,  0x4D,  0x82,  0xBE,  0x01,  0x0F,  0x10,  0x91,  0x09,  0x10, 	/* 1A5C0 */
+	0xF5,  0x02,  0x5C,  0xA5,  0x0B,  0x50,  0xA5,  0x0A,  0xD0,  0xB5,  0x0C,  0xFE,  0x82,  0x01,  0x0F,  0x10, 	/* 1A5D0 */
+	0x97,  0xE9,  0x10,  0xF1,  0x02,  0x7C,  0xA0,  0x4B,  0xA4,  0xA1,  0x8B,  0x98,  0xE6,  0x49,  0x82,  0x8B, 	/* 1A5E0 */
+	0x02,  0x8F,  0x24,  0x9F,  0xE9,  0x20,  0xF2,  0x22,  0x32,  0xA3,  0x4B,  0x34,  0xA4,  0x8A,  0x58,  0xB9, 	/* 1A5F0 */
+	0x4D,  0x22,  0x8C,  0x01,  0x0F,  0x50,  0x97,  0xC9,  0x50,  0xF5,  0x02,  0x90,  0xAF,  0xEB,  0x10,  0xA3, 	/* 1A600 */
+	0x0A,  0x28,  0xB4,  0x4D,  0x82,  0x8F,  0x04,  0x0F,  0x4E,  0x94,  0xA9,  0xFA,  0xF5,  0xA2,  0x5A,  0xA5, 	/* 1A610 */
+	0xAB,  0x5A,  0xA5,  0xAB,  0x5A,  0xE9,  0xE9,  0x60,  0x96,  0x00,  0x0F,  0x7E,  0x91,  0x09,  0x10,  0xF1, 	/* 1A620 */
+	0x02,  0x3E,  0xA3,  0x2B,  0x52,  0xA5,  0x2A,  0x92,  0xB1,  0x2C,  0x1E,  0x9A,  0x00,  0x0F,  0xFE,  0x9A, 	/* 1A630 */
+	0xA9,  0xAA,  0xFA,  0xA2,  0xFF,  0xAA,  0xAB,  0xAA,  0xAA,  0xAA,  0xAA,  0xBA,  0xAC,  0x86,  0x9B,  0x01, 	/* 1A640 */
+	0x0F,  0x10,  0x97,  0xE9,  0x54,  0xF5,  0x02,  0x50,  0xA7,  0xCB,  0x44,  0xA5,  0x4A,  0x88,  0xB9,  0x4D, 	/* 1A650 */
+	0x62,  0x9D,  0x00,  0x0F,  0x7E,  0x94,  0x09,  0x40,  0xF7,  0xC2,  0x44,  0xA4,  0x4B,  0xFC,  0xA4,  0x0A, 	/* 1A660 */
+	0xC0,  0xB4,  0x0C,  0x7E,  0x9F,  0x00,  0x0F,  0x7C,  0x94,  0x49,  0x7C,  0xF4,  0x42,  0x44,  0xA7,  0xCB, 	/* 1A670 */
+	0xD2,  0xA5,  0x4A,  0xC8,  0xB6,  0x4C,  0xC2,  0xA1,  0x01,  0x0F,  0x10,  0x9F,  0xE9,  0x28,  0xF2,  0x82, 	/* 1A680 */
+	0xAC,  0xBA,  0xAA,  0xAA,  0xAA,  0xAB,  0xA8,  0xE4,  0x88,  0x98,  0xA3,  0x01,  0x0F,  0x50,  0x97,  0xC9, 	/* 1A690 */
+	0x50,  0xF5,  0x02,  0x90,  0xAF,  0xEB,  0xA8,  0xA2,  0x8A,  0xAA,  0xB4,  0xAC,  0x86,  0xA8,  0x01,  0x0F, 	/* 1A6A0 */
+	0x7E,  0x91,  0x09,  0x28,  0xF7,  0xC2,  0x82,  0xA7,  0xEB,  0xA0,  0xA3,  0xCA,  0x84,  0xB0,  0x4C,  0x18, 	/* 1A6B0 */
+	0xAA,  0x03,  0xCF,  0x48,  0x99,  0x09,  0x7E,  0xF4,  0x02,  0x5C,  0xA5,  0x4B,  0x54,  0xA5,  0xCA,  0x90, 	/* 1A6C0 */
+	0xB9,  0x2D,  0x0E,  0xAB,  0x00,  0x0F,  0xBC,  0x22,  0x43,  0xB5,  0xC4,  0xB3,  0xFC,  0x20,  0x43,  0xFC, 	/* 1A6D0 */
+	0x14,  0x01,  0x7C,  0x2C,  0x0C,  0x3E,  0xAF,  0x02,  0x0F,  0x3C,  0x92,  0x49,  0x68,  0xF1,  0x02,  0x2C, 	/* 1A6E0 */
+	0xA4,  0x3B,  0xBC,  0xA2,  0x4A,  0xA4,  0xB2,  0x4C,  0x3C,  0xB3,  0x02,  0x8F,  0x28,  0x92,  0x89,  0xAA, 	/* 1A6F0 */
+	0xF6,  0xC2,  0x28,  0xA6,  0xCB,  0xAA,  0xA2,  0xAB,  0xA8,  0xE4,  0xA8,  0x86,  0xB5,  0x02,  0x8F,  0x24, 	/* 1A700 */
+	0x93,  0xC9,  0xE0,  0xF3,  0xC2,  0xE0,  0xA3,  0xEB,  0xD4,  0xA1,  0x4B,  0x8A,  0xE3,  0x68,  0xC2,  0xBC, 	/* 1A710 */
+	0x00,  0x0F,  0x7C,  0x94,  0x49,  0x7C,  0xF4,  0x02,  0x7E,  0xA4,  0x2B,  0xFA,  0xA6,  0xAA,  0xBA,  0xB8, 	/* 1A720 */
+	0x2D,  0x0C,  0xBF,  0x01,  0x0F,  0x10,  0x97,  0xC9,  0x10,  0xFF,  0xE2,  0x10,  0xA5,  0x0B,  0xDC,  0xA5, 	/* 1A730 */
+	0x0A,  0x50,  0xBB,  0x0D,  0x0E,  0x88,  0x01,  0x0F,  0x7E,  0x91,  0x09,  0x7C,  0xF5,  0x42,  0x54,  0xA7, 	/* 1A740 */
+	0xCB,  0xB8,  0xA3,  0x8A,  0x54,  0xB9,  0x2C,  0x10,  0x89,  0x01,  0x0F,  0x20,  0x97,  0xC9,  0x44,  0xF7, 	/* 1A750 */
+	0xC2,  0x44,  0xA7,  0xCB,  0xD2,  0xA5,  0x4A,  0xC8,  0xB7,  0x4C,  0xC2,  0x8A,  0x00,  0x0F,  0x7C,  0x92, 	/* 1A760 */
+	0x89,  0x10,  0xFF,  0xE2,  0x92,  0xAF,  0xEB,  0x92,  0xAF,  0xEB,  0x92,  0xE9,  0x28,  0x96,  0x8F,  0x01, 	/* 1A770 */
+	0x0F,  0x90,  0x95,  0x69,  0x38,  0xF5,  0x42,  0x92,  0xA3,  0x0B,  0xFC,  0xA4,  0x4A,  0x7C,  0xBC,  0x4C, 	/* 1A780 */
+	0x7C,  0x90,  0x02,  0x8F,  0x24,  0x91,  0xE9,  0xF4,  0xF0,  0xA2,  0x36,  0xAE,  0x8B,  0x3E,  0xAE,  0x8A, 	/* 1A790 */
+	0x12,  0xB2,  0xEC,  0xC2,  0x9D,  0x00,  0x0F,  0x7C,  0x95,  0x49,  0x7C,  0xF5,  0x42,  0x7C,  0xA1,  0x0B, 	/* 1A7A0 */
+	0xFE,  0xA3,  0x8A,  0x54,  0xB9,  0x2C,  0x10,  0x9E,  0x00,  0x0F,  0x7E,  0x94,  0x29,  0x7E,  0xF4,  0x82, 	/* 1A7B0 */
+	0x7F,  0xA4,  0x8B,  0xC8,  0xA7,  0xEA,  0xA2,  0xBA,  0x2D,  0x3E,  0x9F,  0x04,  0x0F,  0x4E,  0x97,  0xA9, 	/* 1A7C0 */
+	0x6A,  0xFA,  0xA2,  0xAA,  0xAF,  0xAB,  0x2A,  0xA2,  0xAA,  0x3A,  0xB4,  0xEC,  0x80,  0xAA,  0x01,  0x0F, 	/* 1A7D0 */
+	0xFE,  0x98,  0x29,  0x82,  0xF3,  0x82,  0x00,  0xA7,  0xEB,  0x10,  0xA5,  0x4A,  0x52,  0xB9,  0x2C,  0x30, 	/* 1A7E0 */
+	0xB0,  0x07,  0x0F,  0x28,  0x94,  0x49,  0xBA,  0xF0,  0x12,  0xEA,  0xAA,  0xAB,  0xF4,  0xAB,  0x4A,  0xF4, 	/* 1A7F0 */
+	0xBA,  0xAC,  0xAA,  0xB4,  0x00,  0x0F,  0x7E,  0x91,  0x49,  0x7E,  0xF5,  0x22,  0x7E,  0xA7,  0xEB,  0x90, 	/* 1A800 */
+	0xA7,  0xEA,  0x92,  0xB2,  0x2C,  0x4C,  0xB5,  0x00,  0xCF,  0x70,  0x91,  0x09,  0xFE,  0xF5,  0x42,  0x7C, 	/* 1A810 */
+	0xA5,  0x4B,  0xFC,  0xA1,  0x0A,  0x7C,  0xB1,  0x0C,  0xFE,  0x82,  0x00,  0x0F,  0x7C,  0x92,  0x89,  0xFE, 	/* 1A820 */
+	0xF3,  0x42,  0x50,  0xAB,  0x0B,  0x10,  0xAF,  0xEA,  0x38,  0xB5,  0x4C,  0x92,  0x84,  0x01,  0x0F,  0xFE, 	/* 1A830 */
+	0x94,  0x49,  0x28,  0xFF,  0xE2,  0x92,  0xA7,  0xCB,  0xD4,  0xA5,  0x4A,  0xDC,  0xB5,  0x0C,  0x10,  0x87, 	/* 1A840 */
+	0x04,  0x0F,  0xFE,  0x91,  0x2B,  0xFA,  0x11,  0x0F,  0xFE,  0x20,  0x85,  0xF4,  0x91,  0x25,  0xFC,  0x64, 	/* 1A850 */
+	0x09,  0xFE,  0x88,  0x00,  0xCF,  0x78,  0x95,  0x49,  0x52,  0xF9,  0x22,  0x20,  0xA6,  0xCB,  0xC4,  0xA6, 	/* 1A860 */
+	0xCA,  0xC4,  0xB4,  0x4C,  0x7C,  0x89,  0x02,  0x4F,  0x7E,  0x91,  0x09,  0x7C,  0xF1,  0x02,  0xFE,  0xA2, 	/* 1A870 */
+	0x0B,  0xBE,  0xA2,  0x8A,  0x48,  0xB8,  0x8D,  0x7E,  0x8A,  0x00,  0xCF,  0x78,  0x95,  0x49,  0x92,  0xF3, 	/* 1A880 */
+	0x02,  0xC8,  0xA3,  0x4B,  0xFE,  0xA1,  0x0A,  0x7E,  0xBA,  0x8C,  0x44,  0x8C,  0x01,  0x0F,  0x18,  0x92, 	/* 1A890 */
+	0x49,  0x7E,  0xFA,  0x52,  0x3C,  0xA2,  0x4B,  0xBC,  0xA4,  0x0A,  0xBE,  0xB2,  0x2C,  0x3E,  0x90,  0x01, 	/* 1A8A0 */
+	0x0F,  0xD6,  0x91,  0x09,  0xD6,  0xF2,  0x82,  0x7C,  0xAC,  0x6B,  0x7D,  0xA4,  0x4A,  0x7C,  0xB4,  0x4C, 	/* 1A8B0 */
+	0x4C,  0x95,  0x00,  0x0F,  0x7E,  0x95,  0x29,  0x7E,  0xF5,  0x22,  0xFE,  0xA5,  0x4B,  0xFF,  0xA5,  0x4A, 	/* 1A8C0 */
+	0xFE,  0xB1,  0x0C,  0x10,  0x99,  0x01,  0x47,  0xFE,  0x49,  0x07,  0xF4,  0x48,  0xAA,  0xAE,  0xA9,  0x23, 	/* 1A8D0 */
+	0xF8,  0x20,  0x83,  0xFC,  0x5A,  0x08,  0x7E,  0x9F,  0x01,  0x0F,  0xFE,  0x91,  0x09,  0x7C,  0xF1,  0x02, 	/* 1A8E0 */
+	0xFE,  0xB4,  0x4A,  0x7C,  0xA4,  0x4B,  0xFC,  0xE2,  0x48,  0xC2,  0xA0,  0x00,  0x8F,  0x7E,  0x94,  0x09, 	/* 1A8F0 */
+	0x54,  0xF7,  0xE2,  0x54,  0xA5,  0x4B,  0xDC,  0xA4,  0x0A,  0x54,  0xBA,  0xAC,  0xAA,  0xA3,  0x02,  0x8F, 	/* 1A900 */
+	0xFE,  0x92,  0x89,  0x38,  0xF1,  0x02,  0xFE,  0xA9,  0x2B,  0xFE,  0xAB,  0x6A,  0xDA,  0xB9,  0x2C,  0x96, 	/* 1A910 */
+	0xA4,  0x05,  0x4F,  0x54,  0x99,  0x49,  0x6A,  0x94,  0x2E,  0x88,  0x3A,  0x8A,  0xAE,  0xBA,  0x8A,  0xA8, 	/* 1A920 */
+	0xBD,  0x8C,  0x87,  0xB2,  0x01,  0xCF,  0x24,  0x92,  0x29,  0x7F,  0xFD,  0xA2,  0x56,  0xA7,  0xEB,  0x84, 	/* 1A930 */
+	0xA7,  0xFA,  0xA4,  0xB0,  0x4C,  0x0C,  0xB4,  0x04,  0x8F,  0xEC,  0x90,  0xA9,  0xFE,  0xFA,  0x82,  0xA8, 	/* 1A940 */
+	0xBF,  0x8A,  0x58,  0xAF,  0x8B,  0x5A,  0xE6,  0xA8,  0xC6,  0xB6,  0x00,  0x0F,  0x7E,  0x96,  0xC9,  0x54, 	/* 1A950 */
+	0xF7,  0xF2,  0x5A,  0xB5,  0x6A,  0x54,  0xA7,  0xEB,  0x96,  0xEA,  0xA1,  0x51,  0xBC,  0x02,  0x8F,  0x6A, 	/* 1A960 */
+	0x9F,  0xE9,  0x28,  0xFF,  0xE2,  0x10,  0xAF,  0xEB,  0x10,  0xAF,  0xEA,  0xA8,  0xB4,  0x4C,  0x82,  0x81, 	/* 1A970 */
+	0x07,  0x8F,  0x48,  0x97,  0x89,  0xEE,  0xFA,  0xA2,  0xEE,  0xA1,  0x0B,  0xFE,  0xA3,  0x8A,  0x54,  0xB9, 	/* 1A980 */
+	0x2C,  0x10,  0x84,  0x78,  0x84,  0xBE,  0x79,  0x44,  0x3E,  0x78,  0x84,  0xBE,  0xB8,  0x81,  0xF8,  0x10, 	/* 1A990 */
+	0x85,  0xFC,  0x62,  0x09,  0xFE,  0x85,  0x1F,  0xCF,  0x54,  0x9F,  0xC9,  0x40,  0xF7,  0xE2,  0xA2,  0xAF, 	/* 1A9A0 */
+	0xAB,  0xAA,  0xAF,  0xAA,  0x22,  0xB3,  0xAC,  0xCC,  0x87,  0x04,  0x8F,  0xFE,  0x94,  0x89,  0xFE,  0xF2, 	/* 1A9B0 */
+	0x42,  0xFE,  0xA2,  0x8B,  0x7C,  0xA4,  0x4A,  0xFC,  0xB4,  0x4C,  0x7C,  0x8A,  0x00,  0x8F,  0x7E,  0x90, 	/* 1A9C0 */
+	0x89,  0x7F,  0xF0,  0x22,  0x7E,  0xA0,  0x8B,  0xFF,  0xA7,  0x2A,  0xDA,  0xB7,  0x2C,  0x06,  0x8B,  0x01, 	/* 1A9D0 */
+	0x0F,  0xFE,  0x92,  0x89,  0xF6,  0xF5,  0xC2,  0x54,  0xAA,  0xAB,  0xFC,  0xA4,  0x4A,  0xFC,  0xB4,  0x4C, 	/* 1A9E0 */
+	0x84,  0x8D,  0x00,  0x0F,  0xEE,  0x92,  0x29,  0xEE,  0xF2,  0x22,  0xEE,  0xA4,  0x8B,  0xFE,  0xA9,  0x0A, 	/* 1A9F0 */
+	0xFC,  0xB9,  0x0C,  0xFE,  0x91,  0x06,  0x0F,  0x5E,  0x98,  0xA9,  0xFA,  0xFA,  0xA2,  0xDC,  0xAF,  0xAA, 	/* 1AA00 */
+	0x2A,  0xBF,  0xAA,  0x6E,  0xB5,  0x8C,  0x88,  0x93,  0x02,  0x4F,  0x48,  0x97,  0xF9,  0xAA,  0xFA,  0xA2, 	/* 1AA10 */
+	0x7C,  0xA4,  0x4B,  0xFC,  0xA4,  0x4A,  0xFC,  0xB2,  0x4E,  0xC2,  0x94,  0x00,  0x8F,  0x7E,  0x96,  0xA9, 	/* 1AA20 */
+	0x7E,  0xF6,  0xA2,  0x7E,  0xBD,  0x4A,  0x66,  0xA4,  0x8B,  0xBE,  0xC8,  0x81,  0x7F,  0x99,  0x77,  0x75, 	/* 1AA30 */
+	0x55,  0x57,  0x75,  0x41,  0x75,  0x52,  0x5F,  0x27,  0x53,  0xDF,  0xA5,  0x5A,  0x5F,  0xBD,  0x5C,  0x5F, 	/* 1AA40 */
+	0xA1,  0x0F,  0xEF,  0x24,  0x93,  0xC9,  0x24,  0x97,  0xCF,  0x04,  0x2F,  0xFA,  0xAA,  0xBE,  0xEA,  0xAA, 	/* 1AA50 */
+	0xBF,  0xEC,  0x22,  0xAA,  0x02,  0x8F,  0xFE,  0x92,  0x89,  0xEE,  0xFA,  0xA2,  0xEE,  0xAA,  0xAB,  0xFE, 	/* 1AA60 */
+	0xAA,  0xAA,  0xBA,  0xBA,  0xAC,  0xBA,  0xAB,  0x04,  0x01,  0xF8,  0x10,  0x81,  0xF8,  0x10,  0x91,  0xFA, 	/* 1AA70 */
+	0x10,  0xCF,  0xF8,  0x06,  0x81,  0x88,  0x60,  0x80,  0x18,  0xAC,  0x20,  0x07,  0x9E,  0x48,  0x27,  0x82, 	/* 1AA80 */
+	0x49,  0xE7,  0xA0,  0x4F,  0xEF,  0x82,  0x18,  0x22,  0x82,  0xC8,  0x21,  0x8C,  0xAF,  0x20,  0x07,  0xBE, 	/* 1AA90 */
+	0x4A,  0x07,  0xA2,  0x4B,  0x27,  0xAC,  0x4E,  0x4F,  0xAA,  0x1A,  0xA2,  0xB0,  0xCA,  0x01,  0xBE,  0xB0, 	/* 1AAA0 */
+	0x21,  0x07,  0x90,  0x49,  0x07,  0xFE,  0x49,  0x07,  0xB8,  0x4B,  0x8F,  0xD4,  0x1D,  0x42,  0xBA,  0xC9, 	/* 1AAB0 */
+	0x01,  0x90,  0xB1,  0x20,  0x07,  0xFC,  0x49,  0x47,  0x96,  0x4A,  0x27,  0xCC,  0x49,  0x0F,  0xFE,  0x19, 	/* 1AAC0 */
+	0x02,  0xB8,  0xCD,  0x61,  0x90,  0xBE,  0x24,  0x47,  0xA8,  0x4F,  0xE7,  0x90,  0x4F,  0xC7,  0x90,  0x4F, 	/* 1AAD0 */
+	0xEF,  0x90,  0x1F,  0xE2,  0x90,  0xCA,  0x81,  0xC6,  0x85,  0x20,  0x07,  0x7E,  0x55,  0x27,  0x54,  0x55, 	/* 1AAE0 */
+	0xE7,  0x74,  0x57,  0xEF,  0x54,  0x35,  0xE5,  0x54,  0x9D,  0x43,  0x5E,  0x86,  0x21,  0x87,  0x7E,  0x55, 	/* 1AAF0 */
+	0xA7,  0x7E,  0x55,  0xA7,  0xFF,  0x58,  0x0F,  0x7E,  0x34,  0x25,  0x7E,  0x92,  0x43,  0x7E,  0x88,  0x20, 	/* 1AB00 */
+	0x87,  0x7E,  0x55,  0x47,  0x7E,  0x55,  0x47,  0x5E,  0x55,  0x4F,  0x5E,  0x35,  0x05,  0x54,  0x9B,  0x23, 	/* 1AB10 */
+	0x4E,  0x8A,  0x04,  0x0F,  0xFE,  0x04,  0x07,  0xFC,  0x44,  0x47,  0xFC,  0x44,  0x47,  0xFC,  0x04,  0x0F, 	/* 1AB20 */
+	0xFE,  0x04,  0x00,  0x40,  0x8B,  0x11,  0x0F,  0xF0,  0x11,  0x07,  0xD0,  0x55,  0x07,  0xD0,  0x55,  0x07, 	/* 1AB30 */
+	0xD0,  0x11,  0x0F,  0xF2,  0x11,  0x21,  0x0E,  0x8C,  0x22,  0x0F,  0xA0,  0x22,  0x0F,  0xF8,  0xAA,  0x8F, 	/* 1AB40 */
+	0xA8,  0xAA,  0x8F,  0xA8,  0x22,  0x8F,  0xCA,  0x24,  0xA2,  0x86,  0x8D,  0xFF,  0xE8,  0x42,  0xBF,  0xA0, 	/* 1AB50 */
+	0x40,  0x7F,  0xC4,  0x44,  0x7F,  0xC4,  0x44,  0x7F,  0xC0,  0x40,  0xFF,  0xE0,  0x40,  0x92,  0x20,  0x0F, 	/* 1AB60 */
+	0xBE,  0x20,  0x8F,  0x88,  0xA8,  0x8F,  0xFE,  0xA8,  0x8F,  0x88,  0x20,  0x8F,  0xC8,  0x20,  0x82,  0x08, 	/* 1AB70 */
+	0x9B,  0x20,  0x0F,  0xBE,  0x22,  0x0F,  0xA0,  0xAB,  0xEF,  0xB2,  0xAB,  0x2F,  0xB6,  0x23,  0x0F,  0xD2, 	/* 1AB80 */
+	0x25,  0x22,  0x8E,  0x9F,  0x22,  0x0F,  0xA0,  0x22,  0x0F,  0xBE,  0xAD,  0x2F,  0xD4,  0xA9,  0x0F,  0x90, 	/* 1AB90 */
+	0x23,  0x0F,  0xA8,  0x24,  0x42,  0x82,  0xA2,  0x20,  0x0F,  0xBC,  0x20,  0x0F,  0x80,  0xAF,  0xEF,  0x90, 	/* 1ABA0 */
+	0xA9,  0x0F,  0x98,  0x22,  0x4F,  0xAC,  0x27,  0x22,  0x02,  0xA3,  0x04,  0x0F,  0xFE,  0x24,  0x83,  0xF8, 	/* 1ABB0 */
+	0x24,  0x8F,  0xFE,  0x04,  0x06,  0x0C,  0x11,  0x00,  0xA0,  0x31,  0x8C,  0x06,  0xAB,  0x21,  0x0F,  0x90, 	/* 1ABC0 */
+	0x22,  0x8F,  0xC4,  0xA9,  0x2F,  0xE4,  0xA8,  0x8F,  0x92,  0x26,  0x4F,  0x88,  0x23,  0x02,  0xC0,  0xB8, 	/* 1ABD0 */
+	0x20,  0x8F,  0x88,  0x23,  0xEF,  0xAA,  0xAA,  0xAF,  0xAA,  0xAB,  0xEF,  0xAA,  0x22,  0xAF,  0xAA,  0x23, 	/* 1ABE0 */
+	0xE2,  0x20,  0xBB,  0x20,  0x0F,  0xFE,  0x20,  0x4F,  0x84,  0xAF,  0x4F,  0xD4,  0xAD,  0x4F,  0xD4,  0x27, 	/* 1ABF0 */
+	0x4F,  0x84,  0x20,  0x42,  0x0C,  0xBC,  0x20,  0x8F,  0xA8,  0x22,  0x8F,  0xBE,  0xAC,  0x8F,  0x88,  0xAF, 	/* 1AC00 */
+	0xEF,  0x88,  0x21,  0x8F,  0x94,  0x22,  0x22,  0xC1,  0xBD,  0x20,  0x0F,  0xBE,  0x20,  0x2F,  0x94,  0xA8, 	/* 1AC10 */
+	0x8F,  0xB6,  0xA8,  0x8F,  0x88,  0x23,  0xEF,  0x88,  0x20,  0x82,  0x7F,  0xBE,  0x20,  0xCF,  0x8A,  0x20, 	/* 1AC20 */
+	0x8F,  0xFE,  0xA8,  0x8F,  0xF8,  0xAA,  0x8F,  0xA8,  0x22,  0xAF,  0xBA,  0x2C,  0x62,  0x02,  0x83,  0x21, 	/* 1AC30 */
+	0x0F,  0x10,  0x2F,  0xEF,  0xA8,  0xAC,  0x4F,  0x8A,  0xAC,  0x8F,  0xA8,  0x21,  0x0F,  0xA8,  0x24,  0x42, 	/* 1AC40 */
+	0x82,  0x85,  0x21,  0x0F,  0x9E,  0x22,  0x4F,  0xD4,  0xA8,  0x8F,  0x94,  0xAA,  0x2F,  0xC1,  0x23,  0xCF, 	/* 1AC50 */
+	0xA4,  0x22,  0x42,  0x3C,  0x89,  0x11,  0x07,  0xD4,  0x11,  0x2F,  0xFE,  0x11,  0x0F,  0xF4,  0x55,  0x47, 	/* 1AC60 */
+	0xC8,  0x54,  0x8F,  0xFA,  0x12,  0x61,  0x02,  0x8A,  0x20,  0x0F,  0xFE,  0x22,  0x0F,  0xA8,  0xAC,  0x4F, 	/* 1AC70 */
+	0xFE,  0xA9,  0x2F,  0x90,  0x27,  0xCF,  0x90,  0x21,  0x02,  0xFE,  0x8C,  0x20,  0x0F,  0xFE,  0x21,  0x0F, 	/* 1AC80 */
+	0x90,  0xAF,  0xEF,  0x92,  0xAD,  0x6F,  0xD6,  0x2F,  0xEF,  0x82,  0x28,  0x22,  0x86,  0x92,  0x20,  0x0F, 	/* 1AC90 */
+	0xFF,  0x25,  0x4F,  0x54,  0xA7,  0x4F,  0x54,  0xA7,  0x4F,  0x54,  0x25,  0x4F,  0x75,  0x2D,  0x52,  0x13, 	/* 1ACA0 */
+	0x93,  0x22,  0x0F,  0xBC,  0x24,  0x8F,  0xFC,  0xAD,  0x4F,  0xD4,  0xAF,  0xCF,  0xA8,  0x22,  0x8F,  0xAA, 	/* 1ACB0 */
+	0x24,  0xA2,  0x86,  0x94,  0x21,  0x4F,  0x92,  0x27,  0xEF,  0x90,  0xAF,  0xEF,  0xD2,  0xAF,  0xEF,  0xD2, 	/* 1ACC0 */
+	0x27,  0xEF,  0xD2,  0x25,  0x22,  0x56,  0x95,  0x27,  0xEF,  0x80,  0x22,  0xAF,  0xAA,  0xAD,  0x4F,  0xAA, 	/* 1ACD0 */
+	0xAA,  0xAF,  0x80,  0x27,  0xEF,  0x90,  0x21,  0x02,  0xFE,  0x99,  0x20,  0x0F,  0xFF,  0x25,  0x0F,  0xDE, 	/* 1ACE0 */
+	0xAF,  0xAF,  0xDA,  0xAF,  0x4F,  0xD4,  0x25,  0x4F,  0xFA,  0x2D,  0xA2,  0x11,  0x9B,  0x20,  0x0F,  0xFE, 	/* 1ACF0 */
+	0x21,  0x0F,  0x90,  0xAF,  0xEF,  0x92,  0xAF,  0xEF,  0xB6,  0x2D,  0xAF,  0x92,  0x29,  0x22,  0x96,  0x9C, 	/* 1AD00 */
+	0x22,  0xAF,  0xAA,  0x25,  0x4F,  0xAA,  0xAA,  0xAF,  0x80,  0xAF,  0xEF,  0xD2,  0x27,  0xEF,  0xD2,  0x25, 	/* 1AD10 */
+	0x22,  0x7E,  0x9D,  0x27,  0xEA,  0x52,  0xAF,  0xC7,  0x10,  0x27,  0xEF,  0xD2,  0x57,  0xE5,  0x52,  0x5F, 	/* 1AD20 */
+	0xE5,  0x10,  0x8F,  0xE0,  0x10,  0x9F,  0x20,  0x0F,  0xFE,  0x25,  0xAF,  0xB4,  0xAA,  0xAF,  0xD0,  0xAF, 	/* 1AD30 */
+	0xEF,  0x92,  0x25,  0xAF,  0xA4,  0x25,  0xA2,  0x91,  0xA6,  0x20,  0x87,  0xBC,  0x20,  0x8F,  0xBE,  0x51, 	/* 1AD40 */
+	0x48,  0xA2,  0x7F,  0xC2,  0x48,  0x3F,  0x82,  0x48,  0xFF,  0xE0,  0x40,  0xA9,  0x0A,  0x07,  0xBC,  0x0A, 	/* 1AD50 */
+	0x0F,  0xBE,  0x16,  0x0F,  0xFE,  0x24,  0x83,  0xF8,  0x24,  0x83,  0xF8,  0xFF,  0xE0,  0x40,  0xAA,  0x21, 	/* 1AD60 */
+	0x0F,  0x90,  0x22,  0x8F,  0xC4,  0xAF,  0xEF,  0x81,  0xAF,  0xEF,  0xAA,  0x2F,  0xEF,  0xAA,  0x2A,  0xA2, 	/* 1AD70 */
+	0x86,  0xAF,  0x23,  0xEF,  0xA2,  0x23,  0xEF,  0x80,  0xAF,  0xFF,  0xA2,  0xAB,  0xEF,  0xA2,  0x23,  0xEF, 	/* 1AD80 */
+	0xA2,  0x27,  0xF2,  0x02,  0xB3,  0x21,  0x0F,  0xFC,  0x21,  0x0F,  0xFE,  0xAA,  0x8F,  0xC4,  0xAB,  0xAF, 	/* 1AD90 */
+	0x91,  0x27,  0xCF,  0x90,  0x22,  0x82,  0x44,  0xB8,  0x21,  0x0F,  0xA8,  0x24,  0x4F,  0xBA,  0xA8,  0x0F, 	/* 1ADA0 */
+	0xEA,  0xAA,  0xAF,  0xEA,  0x2A,  0xAF,  0xEA,  0x2A,  0x22,  0xA6,  0xB9,  0x21,  0x0F,  0xBE,  0x26,  0x4F, 	/* 1ADB0 */
+	0xBC,  0xAA,  0x4F,  0xBC,  0xA9,  0x0F,  0x9C,  0x22,  0x4F,  0xD8,  0x22,  0x42,  0xC2,  0xBB,  0x27,  0xEF, 	/* 1ADC0 */
+	0x80,  0x23,  0xCF,  0xA4,  0xAB,  0xCF,  0x80,  0xAF,  0xEF,  0xD2,  0x27,  0xEF,  0xD2,  0x25,  0x22,  0x7E, 	/* 1ADD0 */
+	0xBE,  0x20,  0x0F,  0x7E,  0x24,  0x2F,  0x7E,  0xA5,  0x4F,  0x7E,  0xA5,  0x4F,  0x7E,  0x26,  0x8F,  0xAA, 	/* 1ADE0 */
+	0x2A,  0x42,  0x72,  0xBF,  0x2E,  0x0C,  0x4E,  0x9F,  0x2F,  0x5E,  0x9F,  0x29,  0x52,  0xFF,  0xE8,  0x42, 	/* 1ADF0 */
+	0xFF,  0xF1,  0x10,  0x20,  0xCC,  0x02,  0x82,  0x23,  0x8F,  0xA8,  0x22,  0xAF,  0xAA,  0x8C,  0x62,  0x00, 	/* 1AE00 */
+	0xFB,  0xEA,  0xA4,  0xF9,  0x4A,  0x88,  0xFD,  0x42,  0x62,  0x84,  0x21,  0x0F,  0xFE,  0x29,  0x2F,  0xFC, 	/* 1AE10 */
+	0xA9,  0x0F,  0xFC,  0xA9,  0x0F,  0xFE,  0x20,  0x0F,  0xFC,  0x24,  0x42,  0x7C,  0x85,  0x21,  0x0F,  0xFC, 	/* 1AE20 */
+	0x21,  0x0F,  0xFE,  0xA8,  0x0F,  0xFC,  0xAC,  0x4F,  0xBC,  0x26,  0xAF,  0xAC,  0x22,  0x42,  0x72,  0x86, 	/* 1AE30 */
+	0x20,  0x8F,  0x7E,  0x25,  0x8F,  0x7E,  0xA5,  0xAF,  0x7E,  0xA6,  0x8F,  0x6A,  0x27,  0xCF,  0xE8,  0x2B, 	/* 1AE40 */
+	0xA2,  0x66,  0x89,  0x21,  0x0F,  0xFE,  0x25,  0x4F,  0xFC,  0xAD,  0x4F,  0xFC,  0xAA,  0xAF,  0xFE,  0x24, 	/* 1AE50 */
+	0x8F,  0xA8,  0x20,  0x82,  0x18,  0x8C,  0x27,  0xCF,  0x10,  0x2F,  0xEF,  0x92,  0xAD,  0xAF,  0xB6,  0xA8, 	/* 1AE60 */
+	0x0F,  0xFC,  0x20,  0x4F,  0xFE,  0x20,  0x42,  0x7C,  0x8D,  0x24,  0x8F,  0xF8,  0x2A,  0xFF,  0xEA,  0xB3, 	/* 1AE70 */
+	0x2F,  0xEA,  0xBA,  0xAF,  0xE4,  0x2A,  0x4F,  0xE4,  0x2A,  0xA2,  0xB1,  0x8E,  0x27,  0xCF,  0x90,  0x27, 	/* 1AE80 */
+	0xEF,  0xB8,  0xAC,  0x4F,  0xBA,  0xAA,  0x8F,  0x7E,  0x2B,  0xAF,  0xAA,  0x2B,  0xA2,  0x86,  0x97,  0x20, 	/* 1AE90 */
+	0xAF,  0xFE,  0x24,  0x8F,  0x7A,  0xA4,  0xAF,  0x74,  0xA5,  0x4F,  0x7A,  0x29,  0x0F,  0x28,  0x2A,  0xA2, 	/* 1AEA0 */
+	0x9E,  0x9C,  0x27,  0xCF,  0x10,  0x2F,  0xEF,  0x92,  0xAB,  0xAF,  0x80,  0xAF,  0xEF,  0x60,  0x2F,  0xEF, 	/* 1AEB0 */
+	0xAA,  0x2A,  0xA2,  0x86,  0x9F,  0x7F,  0xC2,  0x48,  0x3F,  0x82,  0x48,  0x7F,  0xC1,  0x50,  0xFB,  0xE5, 	/* 1AEC0 */
+	0x14,  0x7B,  0xC5,  0x14,  0xFB,  0xE1,  0x10,  0xA1,  0x5F,  0x48,  0x48,  0xBF,  0x45,  0x5A,  0xFF,  0xE4, 	/* 1AED0 */
+	0x4A,  0xFF,  0xC4,  0x4A,  0x3F,  0x82,  0x08,  0x20,  0x83,  0xF8,  0xA2,  0x29,  0x2F,  0x54,  0x2B,  0xAF, 	/* 1AEE0 */
+	0xEC,  0xAB,  0xAF,  0xEE,  0xAB,  0xAF,  0x10,  0x2F,  0xEF,  0x38,  0x2D,  0x62,  0x10,  0xA3,  0x20,  0x0F, 	/* 1AEF0 */
+	0x7E,  0x25,  0x4F,  0x7E,  0xA5,  0xCF,  0x76,  0xA5,  0x4F,  0x48,  0x26,  0xEF,  0xE8,  0x2A,  0x82,  0x7E, 	/* 1AF00 */
+	0xA4,  0x21,  0xCF,  0x10,  0x27,  0xEF,  0x50,  0xA5,  0xCF,  0x40,  0xA7,  0xEF,  0x6A,  0x27,  0xEF,  0x6A, 	/* 1AF10 */
+	0x2A,  0xA3,  0x7F,  0x9B,  0x04,  0x00,  0x40,  0x7F,  0xC1,  0x08,  0x11,  0x0F,  0xFE,  0x04,  0x00,  0x40, 	/* 1AF20 */
+	0x7F,  0xC0,  0x40,  0x04,  0x00,  0x40,  0x9C,  0x04,  0x0F,  0xFE,  0x04,  0x03,  0xF8,  0x20,  0x87,  0xFC, 	/* 1AF30 */
+	0x11,  0x0F,  0xFE,  0x04,  0x07,  0xFC,  0x04,  0x00,  0x40,  0x9E,  0x19,  0x0E,  0x7E,  0x22,  0x42,  0x24, 	/* 1AF40 */
+	0xFF,  0xE2,  0x10,  0x21,  0x0F,  0xFE,  0x89,  0x08,  0x90,  0x89,  0x0F,  0x90,  0x9F,  0x00,  0x87,  0x88, 	/* 1AF50 */
+	0x4F,  0xE4,  0xA4,  0x79,  0x44,  0x08,  0x47,  0xE7,  0x88,  0x6F,  0xEA,  0x88,  0x28,  0x83,  0x88,  0xA3, 	/* 1AF60 */
+	0x21,  0x02,  0x7E,  0xF9,  0x08,  0xFE,  0x55,  0x2F,  0xD2,  0x27,  0xE3,  0x90,  0xE3,  0x82,  0x54,  0x49, 	/* 1AF70 */
+	0x28,  0x10,  0xA7,  0x40,  0x85,  0xE8,  0xFB,  0xEA,  0xB4,  0xAB,  0x4F,  0xBE,  0x4A,  0x8F,  0xBE,  0x4A, 	/* 1AF80 */
+	0x84,  0xA8,  0x52,  0x8A,  0xC8,  0xA8,  0x42,  0x84,  0x28,  0xF3,  0xEA,  0xB4,  0xAB,  0x4F,  0xBE,  0x4A, 	/* 1AF90 */
+	0x8F,  0xBE,  0x4A,  0x84,  0x28,  0x44,  0x88,  0x88,  0xAD,  0x0C,  0x8F,  0x88,  0x57,  0xEF,  0xE4,  0x51, 	/* 1AFA0 */
+	0x8F,  0xFE,  0xA4,  0x8F,  0xC8,  0xD7,  0xEA,  0xC8,  0xF4,  0x88,  0xC8,  0xAE,  0x44,  0x8F,  0x5E,  0x29, 	/* 1AFB0 */
+	0x4B,  0xB4,  0xA5,  0x4E,  0xBE,  0x5E,  0x84,  0x48,  0xF7,  0xE5,  0x68,  0x55,  0x88,  0x48,  0xAF,  0x26, 	/* 1AFC0 */
+	0x82,  0x08,  0xFF,  0xE5,  0x14,  0x5F,  0x4F,  0x1E,  0x2E,  0x83,  0x08,  0xCF,  0xE4,  0xA8,  0x4A,  0x88, 	/* 1AFD0 */
+	0xE8,  0xB0,  0x00,  0x03,  0xFC,  0x20,  0x02,  0xFC,  0x20,  0x03,  0xFE,  0x2A,  0x42,  0xA4,  0x49,  0x84, 	/* 1AFE0 */
+	0x88,  0x8E,  0x43,  0x02,  0xB1,  0x00,  0x07,  0xFE,  0x40,  0x07,  0xFC,  0x4A,  0x48,  0x98,  0x3C,  0x60, 	/* 1AFF0 */
+	0x10,  0x7F,  0xE1,  0x10,  0x09,  0x00,  0x30,  0xB2,  0x09,  0x03,  0xFC,  0x29,  0x43,  0xFC,  0x29,  0x47, 	/* 1B000 */
+	0xFE,  0x40,  0x07,  0xFE,  0x4C,  0x44,  0xA8,  0x4D,  0x8B,  0x86,  0xB7,  0x40,  0x02,  0x00,  0x00,  0x08, 	/* 1B010 */
+	0x00,  0x4F,  0xE0,  0x00,  0xE0,  0x02,  0x00,  0x20,  0x02,  0x00,  0x58,  0x08,  0x7F,  0xBA,  0x00,  0x04, 	/* 1B020 */
+	0xFE,  0x22,  0x20,  0x22,  0x02,  0x2E,  0x22,  0x22,  0x22,  0x42,  0x24,  0x22,  0x8C,  0x58,  0x08,  0x7F, 	/* 1B030 */
+	0xBB,  0x01,  0x04,  0x10,  0x21,  0x00,  0x10,  0x0F,  0xEE,  0x10,  0x21,  0x02,  0x10,  0x21,  0x02,  0x10, 	/* 1B040 */
+	0x58,  0x08,  0x7F,  0xBC,  0x00,  0x04,  0x30,  0x21,  0x00,  0x10,  0x01,  0x0E,  0x30,  0x22,  0x82,  0x48, 	/* 1B050 */
+	0x28,  0x43,  0x02,  0x58,  0x08,  0x7F,  0xBF,  0x01,  0x04,  0x10,  0x21,  0x00,  0x92,  0x09,  0x2E,  0x92, 	/* 1B060 */
+	0x29,  0x22,  0x92,  0x2F,  0xE2,  0x82,  0x58,  0x08,  0x7F,  0x82,  0x00,  0x04,  0xFC,  0x21,  0x00,  0x10, 	/* 1B070 */
+	0x1F,  0xEE,  0x10,  0x21,  0x02,  0x10,  0x21,  0x02,  0x30,  0x58,  0x08,  0x7F,  0x84,  0x04,  0x04,  0x40, 	/* 1B080 */
+	0x27,  0xE0,  0x80,  0x07,  0xCE,  0x08,  0x23,  0x02,  0x42,  0x28,  0x22,  0x7E,  0x58,  0x08,  0x7F,  0x85, 	/* 1B090 */
+	0x00,  0x05,  0xF8,  0x24,  0x80,  0x48,  0x04,  0x8F,  0xF8,  0x24,  0xA2,  0x4A,  0x24,  0x62,  0x42,  0x58, 	/* 1B0A0 */
+	0x08,  0x7F,  0x8E,  0x00,  0x04,  0x20,  0x2D,  0xE0,  0x92,  0x09,  0x2E,  0x92,  0x29,  0x22,  0xF2,  0x29, 	/* 1B0B0 */
+	0xC2,  0x10,  0x59,  0x08,  0x7F,  0x91,  0x00,  0x64,  0x78,  0x24,  0x00,  0x40,  0x07,  0xEE,  0x48,  0x24, 	/* 1B0C0 */
+	0x82,  0x48,  0x28,  0x83,  0x08,  0x58,  0x08,  0x7F,  0x94,  0x0F,  0xE4,  0x80,  0x28,  0x00,  0xFC,  0x08, 	/* 1B0D0 */
+	0x4E,  0xA4,  0x29,  0x83,  0x18,  0x32,  0x42,  0xC2,  0x58,  0x08,  0x7F,  0x9A,  0x41,  0x02,  0x10,  0x01, 	/* 1B0E0 */
+	0x08,  0xFE,  0x49,  0x20,  0x92,  0xEF,  0xE2,  0x10,  0x21,  0x02,  0x10,  0x59,  0x08,  0x7F,  0xA2,  0x40, 	/* 1B0F0 */
+	0x02,  0x7E,  0x01,  0x28,  0x12,  0x42,  0x20,  0x4C,  0xEF,  0xE2,  0x42,  0x24,  0x22,  0x7E,  0x58,  0x08, 	/* 1B100 */
+	0x7F,  0xA5,  0x40,  0x02,  0xFE,  0x08,  0x28,  0x82,  0x4B,  0xA0,  0xAA,  0xEA,  0xA2,  0xBA,  0x28,  0x22, 	/* 1B110 */
+	0x86,  0x58,  0x08,  0x7F,  0xA6,  0x08,  0x04,  0x8E,  0x3E,  0xA0,  0xAA,  0x0A,  0xAE,  0xAA,  0x2A,  0xA2, 	/* 1B120 */
+	0xAA,  0x2A,  0xE3,  0x60,  0x58,  0x08,  0x7F,  0xA9,  0x04,  0x08,  0x40,  0x4F,  0xE0,  0x90,  0x11,  0x0E, 	/* 1B130 */
+	0x54,  0x25,  0x22,  0x52,  0x29,  0x22,  0x30,  0x58,  0x08,  0x7F,  0xAA,  0x41,  0x02,  0x10,  0x01,  0x08, 	/* 1B140 */
+	0xFE,  0x49,  0x20,  0x92,  0xEF,  0xE2,  0x92,  0x29,  0x22,  0xFE,  0x58,  0x08,  0x7F,  0xAB,  0x01,  0x04, 	/* 1B150 */
+	0x20,  0x27,  0xC0,  0x44,  0x04,  0x4E,  0x7C,  0x24,  0x42,  0x44,  0x24,  0x42,  0x7C,  0x58,  0x08,  0x7F, 	/* 1B160 */
+	0xAD,  0x01,  0x04,  0x90,  0x29,  0x00,  0xFC,  0x11,  0x0E,  0x10,  0x2F,  0xE2,  0x28,  0x24,  0x42,  0x82, 	/* 1B170 */
+	0x58,  0x08,  0x7F,  0xAF,  0x44,  0x82,  0x48,  0x0E,  0x88,  0xA8,  0x52,  0xC0,  0x6A,  0xE2,  0x82,  0x48, 	/* 1B180 */
+	0x28,  0x83,  0x08,  0x58,  0x08,  0x7F,  0xB0,  0x02,  0x84,  0x24,  0x22,  0x01,  0xFC,  0x02,  0x0E,  0xA8, 	/* 1B190 */
+	0x2A,  0x42,  0xA4,  0x32,  0x42,  0x20,  0x58,  0x08,  0x7F,  0xB4,  0x40,  0x02,  0xFE,  0x08,  0x28,  0xBA, 	/* 1B1A0 */
+	0x4A,  0xA0,  0xAA,  0xEA,  0xA2,  0xBA,  0x28,  0x22,  0xFE,  0x58,  0x08,  0x7F,  0xB7,  0x02,  0x04,  0xA4, 	/* 1B1B0 */
+	0x26,  0x80,  0x20,  0x1F,  0xEE,  0x30,  0x26,  0x82,  0xA4,  0x32,  0x22,  0x20,  0x58,  0x08,  0x7F,  0xB8, 	/* 1B1C0 */
+	0x48,  0x42,  0x48,  0x1F,  0xC8,  0x48,  0x44,  0x81,  0xFE,  0xE4,  0x82,  0x48,  0x28,  0x83,  0x08,  0x58, 	/* 1B1D0 */
+	0x08,  0x7F,  0xB9,  0x41,  0x02,  0x10,  0x1F,  0xE8,  0x28,  0x4A,  0xC0,  0xAA,  0xEA,  0xA3,  0x2A,  0x22, 	/* 1B1E0 */
+	0x82,  0x58,  0x58,  0x08,  0x7F,  0xBA,  0x40,  0x02,  0xFE,  0x02,  0x88,  0x28,  0x4F,  0xE0,  0xAA,  0xEA, 	/* 1B1F0 */
+	0xA2,  0xCE,  0x28,  0x22,  0xFE,  0x58,  0x08,  0x7F,  0xBD,  0x02,  0x04,  0x40,  0x2F,  0xC0,  0x84,  0x0F, 	/* 1B200 */
+	0xCE,  0x80,  0x2F,  0xC2,  0x84,  0x28,  0x42,  0xFC,  0x58,  0x08,  0x7F,  0x80,  0x07,  0xC4,  0x44,  0x27, 	/* 1B210 */
+	0xC0,  0x44,  0x07,  0xCE,  0x52,  0x25,  0x42,  0x48,  0x24,  0x42,  0xE2,  0x58,  0x08,  0x7F,  0x81,  0x04, 	/* 1B220 */
+	0x44,  0x24,  0x22,  0x80,  0xFE,  0x01,  0x0E,  0x10,  0x2F,  0xE2,  0x18,  0x22,  0x42,  0xC2,  0x58,  0x08, 	/* 1B230 */
+	0x7F,  0x83,  0x05,  0x04,  0x50,  0x35,  0x40,  0xD8,  0x05,  0x0E,  0xD8,  0x35,  0x42,  0x90,  0x29,  0x23, 	/* 1B240 */
+	0x0E,  0x58,  0x08,  0x7F,  0x85,  0x40,  0xC2,  0xF0,  0x08,  0x08,  0xFE,  0x48,  0x00,  0x80,  0xEF,  0xC3, 	/* 1B250 */
+	0x44,  0x34,  0x42,  0x7C,  0x58,  0x08,  0x7F,  0x86,  0x04,  0x44,  0x28,  0x2F,  0xE0,  0x10,  0x09,  0x2E, 	/* 1B260 */
+	0x92,  0x2F,  0xE2,  0x90,  0x21,  0x02,  0x20,  0x58,  0x08,  0x7F,  0x8B,  0x41,  0x42,  0xFE,  0x01,  0x08, 	/* 1B270 */
+	0xFE,  0x49,  0x20,  0xFE,  0xE9,  0x22,  0xFE,  0x29,  0x22,  0x96,  0x58,  0x08,  0x7F,  0x8D,  0x41,  0x02, 	/* 1B280 */
+	0x54,  0x09,  0x29,  0x7E,  0x44,  0x40,  0x7C,  0xE4,  0x42,  0x7C,  0x24,  0x42,  0x4C,  0x58,  0x08,  0x7F, 	/* 1B290 */
+	0x8E,  0x40,  0x02,  0xFE,  0x02,  0x88,  0xFE,  0x4A,  0xA0,  0xCE,  0xE8,  0x22,  0xFE,  0x28,  0x22,  0xFE, 	/* 1B2A0 */
+	0x58,  0x08,  0x7F,  0x8F,  0x0F,  0x84,  0x20,  0x3F,  0xC0,  0x70,  0x0A,  0x8F,  0x26,  0x2F,  0x82,  0x2C, 	/* 1B2B0 */
+	0x22,  0x42,  0x4C,  0x58,  0x08,  0x7F,  0x90,  0x00,  0x04,  0xFE,  0x21,  0x00,  0x72,  0x09,  0xCE,  0x28, 	/* 1B2C0 */
+	0x2D,  0xC2,  0x2A,  0x2C,  0x92,  0x10,  0x58,  0x08,  0x7F,  0x91,  0x41,  0x82,  0x14,  0x0F,  0xE8,  0x10, 	/* 1B2D0 */
+	0x49,  0x20,  0x54,  0xE3,  0x82,  0xD4,  0x21,  0x22,  0x30,  0x58,  0x08,  0x7F,  0x93,  0x00,  0xC4,  0xF0, 	/* 1B2E0 */
+	0x29,  0x00,  0xFC,  0x09,  0x0E,  0xFC,  0x29,  0x02,  0xFC,  0x35,  0x42,  0x54,  0x59,  0x08,  0x7F,  0x94, 	/* 1B2F0 */
+	0x01,  0x04,  0x28,  0x24,  0x40,  0xFB,  0x01,  0x0E,  0xFE,  0x25,  0x42,  0x52,  0x29,  0x22,  0x30,  0x58, 	/* 1B300 */
+	0x08,  0x7F,  0x95,  0x40,  0x02,  0xFE,  0x05,  0x48,  0x54,  0x4A,  0x80,  0x54,  0xEF,  0xE2,  0x10,  0x21, 	/* 1B310 */
+	0x02,  0xFE,  0x58,  0x08,  0x7F,  0x96,  0x42,  0x82,  0xA8,  0x05,  0xA8,  0xDA,  0x56,  0xC0,  0x48,  0xED, 	/* 1B320 */
+	0x43,  0x54,  0x26,  0x22,  0xC2,  0x58,  0x08,  0x7F,  0x97,  0x00,  0x04,  0xFE,  0x20,  0x00,  0xFC,  0x08, 	/* 1B330 */
+	0x4E,  0xFC,  0x20,  0x02,  0x84,  0x24,  0x82,  0xFE,  0x58,  0x08,  0x7F,  0x99,  0x01,  0x04,  0xFE,  0x20, 	/* 1B340 */
+	0x00,  0x7C,  0x00,  0x0E,  0x7C,  0x20,  0x02,  0x7C,  0x24,  0x42,  0x7C,  0x58,  0x08,  0x7F,  0x9A,  0x0F, 	/* 1B350 */
+	0xC4,  0x48,  0x23,  0x00,  0xFE,  0x09,  0x2E,  0xFE,  0x29,  0x22,  0xFE,  0x29,  0x22,  0x96,  0x58,  0x08, 	/* 1B360 */
+	0x7F,  0x9D,  0x08,  0x64,  0x98,  0x3D,  0x00,  0x9E,  0x09,  0x4E,  0xD4,  0x39,  0x42,  0xA4,  0x2A,  0x43, 	/* 1B370 */
+	0xC4,  0x58,  0x08,  0x7F,  0x9E,  0x40,  0x02,  0x7C,  0x04,  0x48,  0x7C,  0x40,  0x00,  0xFE,  0xE1,  0x02, 	/* 1B380 */
+	0x7C,  0x21,  0x02,  0xFE,  0x58,  0x08,  0x7F,  0x9F,  0x01,  0x04,  0xFE,  0x21,  0x00,  0xFE,  0x09,  0x2E, 	/* 1B390 */
+	0xFE,  0x23,  0x82,  0x54,  0x29,  0x22,  0x10,  0x58,  0x08,  0x7F,  0xA0,  0x05,  0x04,  0x50,  0x27,  0xC0, 	/* 1B3A0 */
+	0x90,  0x1F,  0xEE,  0x00,  0x27,  0xC2,  0x44,  0x24,  0x43,  0x7C,  0x4C,  0x08,  0x3F,  0xA1,  0x41,  0x02, 	/* 1B3B0 */
+	0x24,  0x0F,  0xA8,  0x28,  0x44,  0xE0,  0x90,  0xE3,  0xC2,  0x64,  0x29,  0x82,  0x2C,  0x5C,  0x28,  0x7F, 	/* 1B3C0 */
+	0xA2,  0x02,  0x04,  0x3C,  0x2C,  0x80,  0x30,  0x0C,  0xCF,  0xFE,  0x22,  0x02,  0xFC,  0x22,  0x02,  0xFC, 	/* 1B3D0 */
+	0x5A,  0x08,  0x7F,  0xA3,  0x01,  0x04,  0xFE,  0x21,  0x00,  0xFE,  0x09,  0x2E,  0xFE,  0x29,  0x22,  0xFE, 	/* 1B3E0 */
+	0x21,  0x02,  0xFE,  0x59,  0x08,  0x7F,  0xA7,  0x44,  0x82,  0x44,  0x09,  0x48,  0x28,  0x44,  0x41,  0x82, 	/* 1B3F0 */
+	0xE7,  0xC2,  0x44,  0x24,  0x42,  0x7C,  0x58,  0x08,  0x7F,  0xAE,  0x02,  0x04,  0xFC,  0x22,  0x41,  0xFE, 	/* 1B400 */
+	0x02,  0x4E,  0xFC,  0x32,  0x42,  0xA8,  0x27,  0x03,  0xAC,  0x5A,  0x08,  0x7F,  0xB1,  0x00,  0x04,  0xFE, 	/* 1B410 */
+	0x29,  0x20,  0xBA,  0x09,  0x2E,  0xFE,  0x2B,  0xA2,  0xAA,  0x2B,  0xA3,  0x06,  0x58,  0x08,  0x7F,  0xB2, 	/* 1B420 */
+	0x04,  0x84,  0x50,  0x2F,  0xE1,  0x90,  0x0F,  0xCE,  0x90,  0x2F,  0xC2,  0x90,  0x29,  0x02,  0xFE,  0x58, 	/* 1B430 */
+	0x08,  0x7F,  0xB5,  0x41,  0x02,  0x7C,  0x01,  0x08,  0xFE,  0x42,  0x80,  0x4E,  0xE9,  0x02,  0x7C,  0x21, 	/* 1B440 */
+	0x02,  0xFE,  0x58,  0x08,  0x7F,  0xB6,  0x40,  0xC2,  0x70,  0x01,  0x09,  0xFE,  0x43,  0x80,  0x54,  0xEF, 	/* 1B450 */
+	0xE2,  0x24,  0x21,  0x82,  0x64,  0x58,  0x08,  0x7F,  0xB8,  0x02,  0x04,  0x3C,  0x24,  0x80,  0xFE,  0x09, 	/* 1B460 */
+	0x2E,  0xFE,  0x23,  0x02,  0x30,  0x25,  0x22,  0x8E,  0x58,  0x08,  0x7F,  0xB9,  0x41,  0x02,  0x10,  0x0F, 	/* 1B470 */
+	0xC8,  0x10,  0x5F,  0xE0,  0x44,  0xEF,  0xE2,  0x10,  0x2F,  0xC2,  0x10,  0x59,  0x08,  0x7F,  0xBC,  0x0F, 	/* 1B480 */
+	0xE4,  0x00,  0x27,  0xC0,  0x44,  0x07,  0xCE,  0xFE,  0x29,  0x22,  0xFE,  0x29,  0x22,  0xFE,  0x58,  0x08, 	/* 1B490 */
+	0x7F,  0xBE,  0x47,  0x02,  0x28,  0x04,  0x49,  0xBA,  0x40,  0x00,  0xEA,  0xEA,  0xA2,  0xF4,  0x2B,  0x42, 	/* 1B4A0 */
+	0xEA,  0x5A,  0xA8,  0x7F,  0x81,  0x00,  0x64,  0xF8,  0x28,  0x80,  0xFF,  0x08,  0x8E,  0xBE,  0x2A,  0x22, 	/* 1B4B0 */
+	0xBE,  0x32,  0x22,  0x3E,  0x58,  0x08,  0x7F,  0x82,  0x04,  0x44,  0x28,  0x2F,  0xF0,  0x30,  0x0C,  0xAE, 	/* 1B4C0 */
+	0x3C,  0x2C,  0xC2,  0x3A,  0x3C,  0x92,  0x18,  0x58,  0x08,  0x7F,  0x85,  0x0F,  0xE4,  0x82,  0x2F,  0xE0, 	/* 1B4D0 */
+	0xA8,  0x0F,  0xCE,  0x90,  0x2F,  0xC2,  0x90,  0x37,  0xE2,  0x10,  0x59,  0x08,  0x7F,  0x87,  0x0F,  0xC4, 	/* 1B4E0 */
+	0xA4,  0x2F,  0xC0,  0xA4,  0x0F,  0xCE,  0x20,  0x2F,  0xE2,  0xAA,  0x2F,  0xA2,  0x8E,  0x58,  0x08,  0x7F, 	/* 1B4F0 */
+	0x89,  0x41,  0x02,  0x1E,  0x01,  0x08,  0x7C,  0x44,  0x40,  0x7C,  0xE4,  0x42,  0x7C,  0x24,  0x42,  0x7C, 	/* 1B500 */
+	0x58,  0x68,  0x7F,  0x8A,  0x08,  0x84,  0x48,  0x3E,  0xF0,  0x90,  0x0F,  0xEE,  0xA4,  0x2B,  0xF2,  0xA4, 	/* 1B510 */
+	0x32,  0x42,  0x6C,  0x58,  0x08,  0x7F,  0x8B,  0x1F,  0xE5,  0x12,  0x3F,  0xE0,  0x94,  0x0F,  0xCE,  0x94, 	/* 1B520 */
+	0x2F,  0xC2,  0x10,  0x3F,  0xE2,  0x10,  0x59,  0x08,  0x7F,  0x8D,  0x0F,  0xC4,  0x00,  0x2F,  0xC0,  0x84, 	/* 1B530 */
+	0x0F,  0xCE,  0x80,  0x2F,  0xE3,  0xAA,  0x2F,  0xE2,  0xAA,  0x58,  0x68,  0x7F,  0x8E,  0x07,  0xC4,  0x44, 	/* 1B540 */
+	0x25,  0xC0,  0x54,  0x0F,  0xEE,  0x82,  0x2B,  0xA2,  0xAA,  0x2B,  0xA2,  0x86,  0x58,  0x08,  0x7F,  0x8F, 	/* 1B550 */
+	0x40,  0x02,  0x7C,  0x04,  0x48,  0x7C,  0x44,  0x40,  0x7C,  0xE7,  0xE2,  0xD2,  0x36,  0xA2,  0x7E,  0x58, 	/* 1B560 */
+	0xC8,  0x7F,  0x90,  0x40,  0x02,  0xEE,  0x0A,  0x28,  0xEE,  0x48,  0x00,  0xFE,  0xE8,  0xA2,  0xE4,  0x28, 	/* 1B570 */
+	0xA2,  0x92,  0x58,  0x08,  0x7F,  0x91,  0x42,  0x02,  0x7C,  0x04,  0x48,  0x7C,  0x44,  0x40,  0xFE,  0xE1, 	/* 1B580 */
+	0x02,  0x7C,  0x21,  0x02,  0xFE,  0x58,  0x08,  0x7F,  0x92,  0x44,  0x82,  0x44,  0x08,  0x29,  0xFE,  0x42, 	/* 1B590 */
+	0x80,  0xFE,  0xEA,  0xA2,  0xCE,  0x28,  0x22,  0xFE,  0x58,  0x08,  0x7F,  0x93,  0x04,  0x85,  0xFE,  0x22, 	/* 1B5A0 */
+	0x00,  0x7C,  0x04,  0x4E,  0x7C,  0x24,  0x42,  0x7C,  0x24,  0x43,  0x7C,  0x4C,  0x08,  0x3F,  0x94,  0x01, 	/* 1B5B0 */
+	0x04,  0x7C,  0x21,  0x00,  0xFE,  0x04,  0x8F,  0xFF,  0x21,  0x02,  0xFE,  0x21,  0x02,  0xFE,  0x59,  0x08, 	/* 1B5C0 */
+	0x7F,  0x95,  0x02,  0x04,  0xFC,  0x22,  0x41,  0xFE,  0x04,  0x4E,  0x7C,  0x21,  0x02,  0xFC,  0x29,  0x03, 	/* 1B5D0 */
+	0xFE,  0x51,  0x08,  0xFF,  0x96,  0x41,  0x02,  0xFE,  0x01,  0x08,  0xFE,  0x4A,  0xA0,  0xFE,  0xE9,  0x22, 	/* 1B5E0 */
+	0xFE,  0x29,  0x22,  0x96,  0x58,  0x08,  0x7F,  0x98,  0x42,  0x82,  0x7C,  0x02,  0x88,  0xFE,  0x47,  0xC0, 	/* 1B5F0 */
+	0x54,  0xE7,  0xC2,  0x54,  0x3F,  0xF2,  0x44,  0x5C,  0xC8,  0x7F,  0x99,  0x41,  0x02,  0x3E,  0x0D,  0x48, 	/* 1B600 */
+	0x38,  0x5E,  0x00,  0x7C,  0xE9,  0x03,  0xFE,  0x29,  0x42,  0xFC,  0x58,  0x08,  0x7F,  0x9C,  0x00,  0x65, 	/* 1B610 */
+	0xF8,  0x24,  0xA0,  0xB4,  0x0C,  0xAF,  0x7E,  0x24,  0xA2,  0x5C,  0x26,  0xA2,  0xC8,  0x58,  0x08,  0x7F, 	/* 1B620 */
+	0x9E,  0x40,  0xC2,  0xF0,  0x09,  0xC8,  0xFE,  0x4D,  0x00,  0xDE,  0xED,  0x83,  0x58,  0x25,  0xA2,  0xA6, 	/* 1B630 */
+	0x58,  0x08,  0x7F,  0xA0,  0x02,  0x04,  0xFC,  0x22,  0x01,  0xFE,  0x0F,  0xCE,  0x84,  0x2F,  0xC2,  0x74, 	/* 1B640 */
+	0x2A,  0x83,  0x26,  0x5B,  0x08,  0x7F,  0xA1,  0x12,  0x04,  0xDE,  0x3F,  0x20,  0x52,  0x15,  0xEF,  0x52, 	/* 1B650 */
+	0x3F,  0xE2,  0x52,  0x25,  0x22,  0x96,  0x58,  0x08,  0x7F,  0xA3,  0x02,  0x04,  0xFC,  0x2A,  0x41,  0xFE, 	/* 1B660 */
+	0x00,  0x0E,  0xF8,  0x28,  0x82,  0xFC,  0x28,  0x42,  0xFC,  0x58,  0x08,  0x7F,  0xA5,  0x00,  0x64,  0xF8, 	/* 1B670 */
+	0x29,  0x20,  0x54,  0x0F,  0xEE,  0x10,  0x2F,  0xE2,  0x10,  0x29,  0x22,  0xFE,  0x58,  0x08,  0x7F,  0xA8, 	/* 1B680 */
+	0x44,  0x82,  0xE8,  0x04,  0xF9,  0xEA,  0x45,  0x21,  0xF4,  0xE6,  0xC2,  0xB4,  0x32,  0x22,  0x61,  0x58, 	/* 1B690 */
+	0x08,  0x7F,  0xA9,  0x01,  0x04,  0xFE,  0x22,  0x80,  0xFE,  0x0B,  0xAE,  0x92,  0x2B,  0xA2,  0xAA,  0x2B, 	/* 1B6A0 */
+	0xA2,  0x86,  0x58,  0x08,  0x7F,  0xAD,  0x02,  0x85,  0xFF,  0x2A,  0xA0,  0xFE,  0x0A,  0xAE,  0xFE,  0x24, 	/* 1B6B0 */
+	0x42,  0x7C,  0x24,  0x42,  0x7C,  0x58,  0x08,  0x7F,  0xAE,  0x00,  0x84,  0xFF,  0x29,  0x40,  0xBE,  0x09, 	/* 1B6C0 */
+	0x4E,  0x94,  0x29,  0xC2,  0x80,  0x32,  0xA2,  0x4A,  0x58,  0x08,  0x7F,  0xAF,  0x4F,  0xF2,  0xA8,  0x0A, 	/* 1B6D0 */
+	0xC8,  0xF5,  0x4A,  0xE0,  0xB6,  0xEE,  0xD2,  0xB4,  0x2A,  0x42,  0xA8,  0x58,  0x08,  0x7F,  0xB2,  0x40, 	/* 1B6E0 */
+	0x02,  0xFE,  0x08,  0x28,  0xFE,  0x48,  0x80,  0xEE,  0xEB,  0xC2,  0xC8,  0x37,  0xE2,  0x08,  0x58,  0x88, 	/* 1B6F0 */
+	0x7F,  0xB5,  0x08,  0x85,  0xFE,  0x25,  0x01,  0xFC,  0x15,  0x4F,  0xFC,  0x20,  0x83,  0xFE,  0x24,  0x82, 	/* 1B700 */
+	0x28,  0x59,  0x88,  0x7F,  0xB6,  0x42,  0x02,  0xFC,  0x02,  0x09,  0xFE,  0x44,  0x80,  0xFC,  0xE4,  0x83, 	/* 1B710 */
+	0xFE,  0x25,  0x02,  0x8E,  0x58,  0x08,  0x7F,  0xB7,  0x1F,  0xF4,  0x28,  0x2F,  0xE0,  0xAA,  0x1F,  0xFE, 	/* 1B720 */
+	0x4C,  0x2F,  0xA3,  0x41,  0x24,  0x42,  0x3C,  0x58,  0x08,  0x7F,  0xB8,  0x0E,  0xE4,  0x22,  0x2E,  0xE0, 	/* 1B730 */
+	0x88,  0x0E,  0xEE,  0x48,  0x2F,  0xE2,  0x48,  0x3F,  0xF2,  0x48,  0x58,  0x48,  0x7F,  0xBA,  0x02,  0x04, 	/* 1B740 */
+	0xFC,  0x2A,  0x41,  0xFE,  0x00,  0x0E,  0xFC,  0x28,  0x42,  0xFC,  0x28,  0x42,  0xFC,  0x5C,  0x68,  0xFF, 	/* 1B750 */
+	0xBC,  0x01,  0x04,  0xFE,  0x22,  0x81,  0x7D,  0x0C,  0x6F,  0x7D,  0x24,  0x42,  0x7C,  0x25,  0x42,  0x92, 	/* 1B760 */
+	0x5B,  0x08,  0x7F,  0xBD,  0x41,  0xE2,  0x10,  0x0F,  0xE8,  0x94,  0x4F,  0xE0,  0x98,  0xEE,  0xA2,  0x9C, 	/* 1B770 */
+	0x36,  0xA2,  0x08,  0x5B,  0x08,  0x7F,  0xBF,  0x0E,  0x44,  0xBF,  0x2A,  0xA0,  0xEA,  0x09,  0xFE,  0xE4, 	/* 1B780 */
+	0x2A,  0x43,  0xBF,  0x2E,  0x42,  0x04,  0x58,  0x08,  0x7F,  0x80,  0x44,  0x82,  0xE8,  0x0A,  0xF8,  0xEA, 	/* 1B790 */
+	0x4B,  0x20,  0xEA,  0xE4,  0x43,  0xF4,  0x26,  0xA2,  0xB1,  0x5C,  0x08,  0x7F,  0x81,  0x42,  0x82,  0xFE, 	/* 1B7A0 */
+	0x02,  0x88,  0x7C,  0x45,  0x40,  0x7C,  0xE5,  0x42,  0xFE,  0x29,  0x22,  0xFA,  0x58,  0x68,  0x7F,  0x82, 	/* 1B7B0 */
+	0x48,  0x02,  0xFE,  0x14,  0xA8,  0xF2,  0x4D,  0x40,  0xFE,  0xED,  0x42,  0xFF,  0x29,  0x42,  0xB4,  0x58, 	/* 1B7C0 */
+	0x08,  0x7F,  0x83,  0x82,  0x05,  0xFE,  0x12,  0xA8,  0xCE,  0x44,  0x40,  0xFE,  0xE3,  0x02,  0xCA,  0x23, 	/* 1B7D0 */
+	0xC2,  0xCA,  0x59,  0x88,  0x7F,  0x84,  0x0F,  0xC4,  0xB4,  0x3F,  0xE0,  0x00,  0x0F,  0xCE,  0x84,  0x2F, 	/* 1B7E0 */
+	0xC2,  0x72,  0x2A,  0xC2,  0x26,  0x5B,  0x08,  0x7F,  0x87,  0x40,  0x02,  0xFE,  0x05,  0x48,  0x92,  0x4F, 	/* 1B7F0 */
+	0xE0,  0xB6,  0xED,  0xA2,  0xB6,  0x2D,  0xA2,  0x96,  0x58,  0x08,  0x7F,  0x89,  0x42,  0x02,  0x7C,  0x04, 	/* 1B800 */
+	0x48,  0x7C,  0x4F,  0xE0,  0xAA,  0xE4,  0x42,  0xFE,  0x24,  0x42,  0x7C,  0x58,  0x08,  0x7F,  0x8A,  0x47, 	/* 1B810 */
+	0xC2,  0x44,  0x07,  0xC8,  0x44,  0x4F,  0xE0,  0xB6,  0xE4,  0xA2,  0xFF,  0x23,  0xC2,  0x44,  0x59,  0x88, 	/* 1B820 */
+	0x7F,  0x8F,  0x4F,  0xE2,  0xAA,  0x0F,  0xE8,  0x48,  0x5B,  0x40,  0x5E,  0xEF,  0x42,  0x5E,  0x2F,  0x43, 	/* 1B830 */
+	0x5E,  0x5C,  0x08,  0x7F,  0x91,  0x00,  0x03,  0xF0,  0x21,  0x03,  0xF0,  0x00,  0x07,  0xF8,  0x48,  0x84, 	/* 1B840 */
+	0x88,  0x7F,  0x84,  0x00,  0x40,  0x23,  0xFE,  0xA3,  0x00,  0x0F,  0xDE,  0x25,  0x22,  0x54,  0x7D,  0x82, 	/* 1B850 */
+	0x54,  0x25,  0x27,  0xD2,  0x25,  0x22,  0x5A,  0x45,  0x48,  0xD0,  0xA6,  0x20,  0x02,  0x3C,  0xFA,  0x42, 	/* 1B860 */
+	0x28,  0xFB,  0x02,  0x38,  0x3A,  0x4E,  0x22,  0x22,  0x22,  0x3C,  0x42,  0x08,  0x20,  0xA8,  0x10,  0x01, 	/* 1B870 */
+	0xFC,  0xF1,  0x41,  0x54,  0x55,  0x85,  0x54,  0x55,  0x25,  0xD2,  0x71,  0x21,  0x5C,  0x19,  0x01,  0x10, 	/* 1B880 */
+	0xAA,  0x00,  0x0F,  0xFC,  0x4A,  0x44,  0xA8,  0x4B,  0x0F,  0xE8,  0x2A,  0x42,  0xA2,  0x4B,  0x24,  0xAC, 	/* 1B890 */
+	0x8A,  0x01,  0xA0,  0xAF,  0x48,  0x04,  0x9C,  0xFF,  0x44,  0x94,  0x49,  0x84,  0x94,  0x79,  0x24,  0x92, 	/* 1B8A0 */
+	0x49,  0x24,  0x9C,  0x49,  0x07,  0x90,  0xB1,  0x0C,  0x07,  0x1C,  0x41,  0x47,  0xF4,  0x49,  0x84,  0x94, 	/* 1B8B0 */
+	0x49,  0x24,  0x92,  0x4D,  0x27,  0x1C,  0xC1,  0x00,  0x10,  0xB5,  0x00,  0x0F,  0xDC,  0x25,  0x42,  0x54, 	/* 1B8C0 */
+	0x25,  0x84,  0x54,  0x99,  0x27,  0xD2,  0x45,  0x24,  0x5C,  0x45,  0x07,  0xD0,  0xB8,  0x0C,  0x07,  0x1E, 	/* 1B8D0 */
+	0x49,  0x24,  0x94,  0x7D,  0x84,  0x94,  0x49,  0x24,  0x92,  0x45,  0x2E,  0x5C,  0x03,  0x07,  0xD0,  0x81, 	/* 1B8E0 */
+	0x10,  0x01,  0x1E,  0xFF,  0x22,  0x14,  0x3D,  0x86,  0x5C,  0x7D,  0x2A,  0x52,  0x3D,  0x22,  0x5C,  0x25, 	/* 1B8F0 */
+	0x02,  0xD0,  0x8A,  0x10,  0x01,  0x1C,  0xFF,  0x42,  0x94,  0x25,  0x84,  0xB4,  0xAB,  0x21,  0x12,  0x19, 	/* 1B900 */
+	0x22,  0x5C,  0x41,  0x08,  0x10,  0x8E,  0x11,  0xC7,  0xD4,  0x45,  0x47,  0xD8,  0x45,  0xC7,  0xD2,  0x41, 	/* 1B910 */
+	0x25,  0x12,  0x49,  0x27,  0x5C,  0xC5,  0x00,  0x10,  0x9B,  0x1C,  0x0E,  0x1C,  0x55,  0x45,  0x34,  0x81, 	/* 1B920 */
+	0x87,  0xD4,  0x09,  0x21,  0xD1,  0xF1,  0x11,  0x1E,  0x11,  0x03,  0x10,  0xA1,  0x00,  0x07,  0xDE,  0x25, 	/* 1B930 */
+	0x2F,  0xF4,  0x25,  0x87,  0xD4,  0x21,  0x23,  0xD2,  0x65,  0x26,  0x5C,  0xA5,  0x03,  0xD0,  0xA2,  0x00, 	/* 1B940 */
+	0x07,  0xDC,  0x45,  0x44,  0x54,  0x7D,  0x80,  0x54,  0xF9,  0x21,  0x12,  0x7D,  0x21,  0x1C,  0x1D,  0x0F, 	/* 1B950 */
+	0x10,  0xA4,  0x10,  0x02,  0x9C,  0x25,  0x45,  0x54,  0x99,  0x82,  0x54,  0x41,  0x2F,  0xD2,  0x45,  0x24, 	/* 1B960 */
+	0x5C,  0x7D,  0x04,  0x10,  0xA8,  0x11,  0xCF,  0xF4,  0x45,  0x42,  0x58,  0x29,  0x4F,  0xF2,  0x01,  0x27, 	/* 1B970 */
+	0xD2,  0x45,  0xC4,  0x50,  0x7D,  0x00,  0x10,  0xAD,  0x10,  0x0F,  0xFC,  0x7D,  0x44,  0x54,  0x7D,  0x80, 	/* 1B980 */
+	0x14,  0x7D,  0x20,  0x92,  0xFD,  0x21,  0x1C,  0x11,  0x03,  0x10,  0xB5,  0x04,  0x07,  0x9C,  0x11,  0x4F, 	/* 1B990 */
+	0xF4,  0x55,  0x8F,  0xF4,  0x55,  0x25,  0x52,  0xFF,  0x21,  0x1C,  0x1D,  0x0F,  0x10,  0xB7,  0x40,  0x04, 	/* 1B9A0 */
+	0xEE,  0xAA,  0xA6,  0xEA,  0x2A,  0xC4,  0xEA,  0xA8,  0x9E,  0xC9,  0x2A,  0x92,  0xDE,  0x49,  0x88,  0x08, 	/* 1B9B0 */
+	0xBD,  0x10,  0x07,  0xDC,  0x15,  0x41,  0x94,  0xFF,  0x81,  0x14,  0x3D,  0x26,  0x52,  0xBD,  0x22,  0x5C, 	/* 1B9C0 */
+	0x25,  0x03,  0xD0,  0x82,  0x00,  0x0E,  0xFC,  0xAB,  0x4E,  0xF4,  0x01,  0x87,  0xD4,  0x01,  0x2F,  0xD2, 	/* 1B9D0 */
+	0x21,  0x23,  0xDC,  0x45,  0x01,  0x90,  0x92,  0x20,  0x07,  0xDC,  0x95,  0x45,  0x54,  0x7D,  0x82,  0x54, 	/* 1B9E0 */
+	0x59,  0x27,  0xD2,  0x95,  0x27,  0xDC,  0x25,  0x05,  0x90,  0x99,  0x00,  0x07,  0xDC,  0x45,  0x47,  0xD4, 	/* 1B9F0 */
+	0x11,  0x8F,  0xF4,  0x45,  0x27,  0xD2,  0x6D,  0x27,  0xDC,  0x45,  0x07,  0xD0,  0xAD,  0x45,  0xEF,  0xF2, 	/* 1BA00 */
+	0x29,  0x4F,  0xF8,  0xAB,  0x8C,  0xF4,  0xFF,  0x21,  0x12,  0xFF,  0x21,  0x9C,  0x27,  0x0C,  0x10,  0xB0, 	/* 1BA10 */
+	0x10,  0x05,  0x5C,  0xFF,  0x43,  0x94,  0x55,  0x89,  0x14,  0x75,  0x25,  0xF2,  0x95,  0x23,  0xFC,  0x45, 	/* 1BA20 */
+	0x08,  0x50,  0xB2,  0xFC,  0x0B,  0x5C,  0xFD,  0x40,  0x14,  0x7D,  0x85,  0x54,  0x7D,  0x25,  0x52,  0x7D, 	/* 1BA30 */
+	0x21,  0x1C,  0xFF,  0x01,  0x10,  0x89,  0x00,  0x0F,  0xFE,  0x0A,  0x00,  0xA0,  0x7F,  0xC4,  0xA4,  0x52, 	/* 1BA40 */
+	0x46,  0x1C,  0x40,  0x47,  0xFC,  0x40,  0x47,  0xFC,  0x8A,  0x00,  0x0F,  0xFE,  0x28,  0x82,  0x88,  0xFC, 	/* 1BA50 */
+	0x8B,  0x48,  0xB4,  0x8D,  0xC8,  0x84,  0x8F,  0xC8,  0x84,  0x8F,  0xD8,  0x8B,  0x11,  0x00,  0xA0,  0xFF, 	/* 1BA60 */
+	0xE0,  0xA0,  0x7F,  0xC4,  0xA4,  0x4A,  0x47,  0x3C,  0x40,  0x47,  0xFC,  0x40,  0x47,  0xFC,  0x8C,  0x01, 	/* 1BA70 */
+	0x0F,  0xD0,  0x53,  0xE5,  0x22,  0xFC,  0x2A,  0xA2,  0xA9,  0x2D,  0x92,  0x88,  0x2F,  0x82,  0x88,  0x2F, 	/* 1BA80 */
+	0x8C,  0x8D,  0x00,  0x0F,  0xBC,  0x50,  0x45,  0x04,  0xF8,  0x4A,  0xBC,  0xAA,  0x0D,  0xA0,  0x8A,  0x0F, 	/* 1BA90 */
+	0xA2,  0x8A,  0x2F,  0x9E,  0x8E,  0x00,  0x4F,  0x84,  0x50,  0x45,  0x7E,  0xF8,  0x4A,  0xA4,  0xA9,  0x4D, 	/* 1BAA0 */
+	0x94,  0x88,  0x4F,  0x84,  0x88,  0x4F,  0x8C,  0x92,  0x40,  0x02,  0xFE,  0x02,  0x88,  0x28,  0x4F,  0xE0, 	/* 1BAB0 */
+	0xAA,  0x0A,  0xA2,  0xCE,  0x48,  0x24,  0xFE,  0x88,  0x28,  0xFE,  0x94,  0x02,  0x0F,  0xA0,  0x57,  0x85, 	/* 1BAC0 */
+	0x28,  0xFA,  0xAA,  0xC6,  0xA9,  0x0D,  0xFE,  0x89,  0x0F,  0x90,  0x89,  0x0F,  0x90,  0x96,  0x01,  0x0F, 	/* 1BAD0 */
+	0x90,  0x51,  0x05,  0x7E,  0xFD,  0x2A,  0x90,  0xA9,  0x8D,  0x98,  0x8A,  0x8F,  0xAA,  0x8C,  0xAF,  0x86, 	/* 1BAE0 */
+	0x98,  0x00,  0x0F,  0xB8,  0x52,  0x85,  0x2A,  0xFC,  0x6A,  0x80,  0xAF,  0xCD,  0xA4,  0x89,  0x8F,  0x98, 	/* 1BAF0 */
+	0x8A,  0x4F,  0xC2,  0xA2,  0x02,  0x0F,  0xA0,  0x52,  0x05,  0x3E,  0xFD,  0x0A,  0xD0,  0xA9,  0xED,  0x90, 	/* 1BB00 */
+	0x89,  0xEF,  0x90,  0x89,  0x0F,  0x90,  0xA3,  0x02,  0x4F,  0xA4,  0x57,  0xE5,  0x24,  0xFA,  0x4A,  0xA4, 	/* 1BB10 */
+	0xAB,  0xCD,  0xA4,  0x8A,  0x4F,  0xA4,  0x8A,  0x4F,  0xBC,  0xA5,  0x00,  0x4F,  0x98,  0x57,  0x05,  0x10, 	/* 1BB20 */
+	0xFF,  0xEA,  0x90,  0xAB,  0x8D,  0xB4,  0x8D,  0x4F,  0x92,  0x89,  0x0F,  0x90,  0xA9,  0x01,  0x0F,  0x90, 	/* 1BB30 */
+	0x51,  0xC5,  0x24,  0xFD,  0x4A,  0x88,  0xA9,  0x0D,  0xBE,  0x8D,  0x2F,  0x92,  0x89,  0x2F,  0x9E,  0xAA, 	/* 1BB40 */
+	0x01,  0x0F,  0x9C,  0x52,  0x45,  0x44,  0xFA,  0x8A,  0x90,  0xAA,  0x8D,  0xFC,  0x8A,  0x6F,  0xA4,  0x8A, 	/* 1BB50 */
+	0x4F,  0xBC,  0xAC,  0x02,  0x2F,  0xAA,  0x52,  0xA5,  0x2A,  0xFA,  0xAA,  0xBE,  0xDF,  0xE8,  0xEA,  0x8A, 	/* 1BB60 */
+	0xAF,  0xAA,  0x8A,  0x2F,  0xC2,  0xB2,  0x00,  0x0F,  0xBC,  0x52,  0x45,  0x24,  0xFB,  0xCA,  0x80,  0xA8, 	/* 1BB70 */
+	0xCD,  0xF0,  0x89,  0x0F,  0xFC,  0x89,  0x0F,  0xFE,  0xB3,  0x00,  0x8F,  0x90,  0x56,  0x45,  0x18,  0xFA, 	/* 1BB80 */
+	0x4A,  0xFE,  0xAA,  0x2D,  0xBC,  0x8A,  0x4F,  0xBC,  0x8A,  0x4F,  0xAC,  0xB5,  0x01,  0x0F,  0x90,  0x57, 	/* 1BB90 */
+	0xC5,  0x14,  0xFF,  0xEA,  0x90,  0xAB,  0xCD,  0xC8,  0x8F,  0xEF,  0x88,  0x88,  0x8F,  0x98,  0xB7,  0x02, 	/* 1BBA0 */
+	0x8F,  0xA8,  0x53,  0xE5,  0x28,  0xF8,  0x8A,  0xFE,  0xA8,  0x0D,  0xBE,  0x8A,  0x2F,  0xA2,  0x8A,  0x2F, 	/* 1BBB0 */
+	0xBE,  0xB8,  0x01,  0x0F,  0x94,  0x57,  0xE5,  0x28,  0xFA,  0xAA,  0xCE,  0xA9,  0x0D,  0xBC,  0x8E,  0x4F, 	/* 1BBC0 */
+	0x98,  0x8A,  0x4F,  0xC2,  0x82,  0x02,  0x4F,  0xA4,  0x52,  0x45,  0x7E,  0xFA,  0x4A,  0xB6,  0xAE,  0xED, 	/* 1BBD0 */
+	0xED,  0x8B,  0x5F,  0xA4,  0x8A,  0x4F,  0xA4,  0x87,  0x00,  0x8F,  0xFF,  0x52,  0x25,  0x3E,  0xF8,  0x0A, 	/* 1BBE0 */
+	0xBE,  0xA8,  0x4D,  0x88,  0x8B,  0xFF,  0x88,  0x88,  0x8F,  0x98,  0x89,  0x00,  0x8F,  0xFE,  0x52,  0x45, 	/* 1BBF0 */
+	0x24,  0xFA,  0xAA,  0xCA,  0xA8,  0x8D,  0xFE,  0x88,  0x8F,  0x88,  0x88,  0x8F,  0x88,  0x8B,  0x02,  0x8F, 	/* 1BC00 */
+	0xA8,  0x57,  0xE5,  0x28,  0xFA,  0x8A,  0xFE,  0xA8,  0x0D,  0xBC,  0x8A,  0x4F,  0xBC,  0x8A,  0x4F,  0xBC, 	/* 1BC10 */
+	0x8D,  0x03,  0xCF,  0xA4,  0x53,  0xC5,  0x24,  0xFB,  0xCA,  0x80,  0xAF,  0xED,  0x88,  0x8A,  0xEF,  0xB8, 	/* 1BC20 */
+	0x8C,  0x8F,  0x87,  0x90,  0x02,  0x0F,  0xAE,  0x57,  0xA5,  0x2E,  0xFA,  0xAA,  0xFA,  0xD9,  0xA8,  0x9E, 	/* 1BC30 */
+	0xF9,  0xA8,  0xF2,  0xF9,  0x20,  0x26,  0x92,  0x00,  0x0F,  0xBE,  0x52,  0x25,  0x3E,  0xFA,  0x2A,  0xBE, 	/* 1BC40 */
+	0xAA,  0x8D,  0xBE,  0x8C,  0x8F,  0xBC,  0x88,  0x8F,  0xFE,  0x97,  0x03,  0xAF,  0x8C,  0x52,  0xD5,  0x16, 	/* 1BC50 */
+	0xFB,  0xEA,  0xD5,  0xA9,  0x4D,  0xFF,  0x89,  0x4F,  0x94,  0x8A,  0x5F,  0xC3,  0x9C,  0x01,  0x0F,  0xA0, 	/* 1BC60 */
+	0x57,  0xC5,  0x54,  0xFF,  0xCA,  0xD4,  0xAF,  0xCD,  0xB4,  0x8B,  0xAF,  0xDE,  0x8D,  0x2F,  0x8E,  0xA2, 	/* 1BC70 */
+	0x01,  0x0F,  0xFE,  0x51,  0x05,  0x3E,  0xFD,  0x2A,  0x9E,  0xA8,  0x0D,  0xBE,  0x8A,  0xAF,  0xAA,  0x8A, 	/* 1BC80 */
+	0xAF,  0xFF,  0xA4,  0x57,  0xE3,  0x54,  0x1F,  0xE3,  0x44,  0x52,  0xCF,  0xFE,  0x0A,  0x07,  0xFC,  0x4A, 	/* 1BC90 */
+	0x47,  0x3C,  0x40,  0x47,  0xFC,  0xAA,  0x00,  0x0F,  0xFE,  0x53,  0x65,  0x5A,  0xFB,  0x6A,  0xDA,  0xAA, 	/* 1BCA0 */
+	0x4D,  0xCA,  0x8B,  0x5F,  0xC8,  0x8B,  0x0F,  0xC0,  0xAB,  0xFB,  0x8A,  0x2A,  0xBF,  0x6D,  0x28,  0xA9, 	/* 1BCB0 */
+	0x0F,  0xFE,  0x0A,  0x07,  0xFC,  0x4A,  0x47,  0x3C,  0x40,  0x47,  0xFC,  0xAF,  0x01,  0x0F,  0xFE,  0x52, 	/* 1BCC0 */
+	0x45,  0x7E,  0xF8,  0x0A,  0xAA,  0xAA,  0xAD,  0xC3,  0x8B,  0xEF,  0xAA,  0x8A,  0xAF,  0xFF,  0xB4,  0x01, 	/* 1BCD0 */
+	0x8F,  0xFE,  0x55,  0xA5,  0x7E,  0xFD,  0xAA,  0xFF,  0xA8,  0x0D,  0xFE,  0x8A,  0x4F,  0xBC,  0x8A,  0x8F, 	/* 1BCE0 */
+	0xFE,  0xB5,  0x01,  0xCF,  0x90,  0x67,  0xE6,  0x56,  0xF7,  0x8B,  0x4C,  0xB7,  0xFD,  0x52,  0x96,  0xCF, 	/* 1BCF0 */
+	0x5A,  0x9A,  0x8F,  0x18,  0xB8,  0xF9,  0x05,  0x7E,  0x52,  0x8F,  0xC6,  0xAA,  0x8A,  0xFE,  0xAA,  0x8D, 	/* 1BD00 */
+	0xFE,  0x8B,  0x2F,  0xEC,  0x8B,  0x4F,  0xE2,  0xBA,  0x00,  0xCF,  0xF0,  0x51,  0x05,  0x7E,  0xFD,  0x4A, 	/* 1BD10 */
+	0xFC,  0xAD,  0x4D,  0xFC,  0x89,  0x0F,  0xFE,  0x8B,  0x4F,  0xCA,  0x80,  0x01,  0x0F,  0xFF,  0x6A,  0xA6, 	/* 1BD20 */
+	0xEE,  0xFA,  0x8A,  0xFE,  0xAA,  0x8D,  0xFF,  0x8B,  0x2F,  0xEC,  0x8A,  0x4F,  0xB2,  0x81,  0x6E,  0xC4, 	/* 1BD30 */
+	0xA4,  0x6E,  0xCF,  0xFE,  0xAA,  0xA3,  0x38,  0x20,  0x83,  0xF8,  0x11,  0x03,  0xF8,  0xC9,  0x63,  0x30, 	/* 1BD40 */
+	0x86,  0x00,  0xC0,  0x70,  0x7C,  0x82,  0x48,  0x15,  0x0F,  0xFE,  0x0E,  0x01,  0x50,  0x24,  0x8C,  0x46, 	/* 1BD50 */
+	0x04,  0x00,  0x40,  0x87,  0x01,  0x87,  0xE4,  0x08,  0x42,  0x48,  0x11,  0x00,  0x40,  0xFF,  0xE0,  0xE0, 	/* 1BD60 */
+	0x15,  0x02,  0x48,  0xC4,  0x60,  0x40,  0x88,  0x18,  0x0E,  0x3E,  0x2A,  0x2B,  0x22,  0x63,  0xEF,  0xA8, 	/* 1BD70 */
+	0x32,  0x86,  0xA8,  0x62,  0x4A,  0x24,  0x24,  0x22,  0x81,  0x89,  0x19,  0x0E,  0x10,  0x29,  0x0B,  0x7E, 	/* 1BD80 */
+	0x65,  0x2F,  0xD2,  0x35,  0x26,  0xFE,  0x65,  0x2A,  0x52,  0x27,  0xE2,  0x42,  0x8B,  0x1F,  0xEE,  0xAA, 	/* 1BD90 */
+	0x2F,  0xEB,  0x10,  0x67,  0xEF,  0x90,  0x2F,  0xE7,  0x48,  0x6F,  0xEA,  0x10,  0x27,  0xC2,  0x10,  0x8C, 	/* 1BDA0 */
+	0x00,  0x03,  0xFC,  0x24,  0x43,  0xFC,  0x24,  0x42,  0x44,  0x3F,  0xC0,  0x40,  0x3F,  0xC0,  0x40,  0x04, 	/* 1BDB0 */
+	0x07,  0xFE,  0x8D,  0x01,  0x83,  0xE0,  0x04,  0x0F,  0xFE,  0x24,  0x83,  0xF8,  0x24,  0x83,  0xF8,  0x04, 	/* 1BDC0 */
+	0x07,  0xFC,  0x04,  0x0F,  0xFE,  0x8E,  0x00,  0x0F,  0xFC,  0xAC,  0x8F,  0xB0,  0xA9,  0x0A,  0xFE,  0xF9, 	/* 1BDD0 */
+	0x42,  0x18,  0xF9,  0x02,  0x10,  0x39,  0x0E,  0x30,  0x8F,  0x3F,  0x82,  0x08,  0x3F,  0x82,  0x08,  0xFF, 	/* 1BDE0 */
+	0xE3,  0xF8,  0x24,  0x83,  0xF8,  0x24,  0x87,  0xFC,  0x04,  0x0F,  0xFE,  0x90,  0x21,  0x07,  0x9E,  0x22, 	/* 1BDF0 */
+	0x4F,  0x98,  0x4E,  0x47,  0xFE,  0x54,  0x85,  0xF8,  0x54,  0x85,  0xF8,  0x44,  0x0B,  0xFC,  0x91,  0x04, 	/* 1BE00 */
+	0x00,  0x40,  0x0A,  0x01,  0x10,  0x3F,  0x8C,  0x46,  0x04,  0x07,  0xFC,  0x04,  0x02,  0x48,  0x15,  0x0F, 	/* 1BE10 */
+	0xFE,  0x96,  0x20,  0x02,  0x7E,  0x51,  0x24,  0x92,  0xF9,  0x22,  0x12,  0xF9,  0x22,  0x92,  0xB1,  0x26, 	/* 1BE20 */
+	0xA2,  0x32,  0x2C,  0x4C,  0x98,  0x10,  0x01,  0x7E,  0x28,  0x84,  0x48,  0xF8,  0x81,  0x08,  0xFC,  0x81, 	/* 1BE30 */
+	0x08,  0x58,  0x83,  0x48,  0x38,  0x8C,  0x18,  0x9B,  0x21,  0x02,  0x10,  0x51,  0x04,  0xFE,  0xF1,  0x22, 	/* 1BE40 */
+	0x12,  0xF9,  0x22,  0x92,  0xB1,  0x26,  0xA2,  0x32,  0x2C,  0x4C,  0x9C,  0x0A,  0x01,  0x10,  0x2A,  0x8C, 	/* 1BE50 */
+	0x46,  0x1B,  0x0E,  0x0E,  0x3F,  0x80,  0x40,  0x7F,  0xC2,  0x48,  0x15,  0x0F,  0xFE,  0x9D,  0x20,  0x82, 	/* 1BE60 */
+	0x08,  0x50,  0x84,  0x88,  0xFF,  0xE2,  0x08,  0xF8,  0x82,  0x08,  0xA8,  0x87,  0x08,  0x38,  0x8C,  0x08, 	/* 1BE70 */
+	0x9F,  0x23,  0x83,  0x08,  0x4A,  0x88,  0x28,  0xFA,  0x82,  0x28,  0xFA,  0x42,  0x24,  0xAA,  0x47,  0x44, 	/* 1BE80 */
+	0x3C,  0x2C,  0x82,  0xA1,  0x11,  0x01,  0x08,  0x24,  0x44,  0xA4,  0x11,  0x02,  0x08,  0xDF,  0xE0,  0x40, 	/* 1BE90 */
+	0x7F,  0xC2,  0x48,  0x15,  0x0F,  0xFE,  0xA3,  0x21,  0x02,  0x10,  0x51,  0x04,  0xBE,  0xFA,  0x22,  0x52, 	/* 1BEA0 */
+	0xF8,  0xA2,  0x8A,  0xB0,  0x26,  0x82,  0x30,  0x2C,  0x0C,  0xA6,  0x20,  0x02,  0x3E,  0x52,  0x24,  0xA2, 	/* 1BEB0 */
+	0xFA,  0x22,  0x22,  0xFA,  0x22,  0x22,  0xB2,  0x26,  0xA2,  0x33,  0xEC,  0x00,  0xA7,  0x22,  0x22,  0x2A, 	/* 1BEC0 */
+	0x52,  0xA4,  0xAA,  0xFA,  0xA2,  0x2A,  0xFA,  0xA2,  0x2A,  0xB2,  0xA6,  0xAA,  0x32,  0x2C,  0x42,  0xB5, 	/* 1BED0 */
+	0x20,  0x02,  0x7E,  0x51,  0x24,  0xAA,  0xF5,  0x42,  0x14,  0xF8,  0x82,  0x88,  0xB1,  0x46,  0xA4,  0x34, 	/* 1BEE0 */
+	0x2C,  0x81,  0xB6,  0x21,  0x03,  0x54,  0x4D,  0xC8,  0x74,  0xFD,  0x42,  0x54,  0xF5,  0x42,  0x5C,  0xAD, 	/* 1BEF0 */
+	0x07,  0x42,  0x3C,  0x2C,  0x3E,  0xBC,  0x20,  0x02,  0x7C,  0x51,  0x44,  0x94,  0xF9,  0x42,  0x34,  0xF9, 	/* 1BF00 */
+	0x42,  0x9C,  0xB2,  0x66,  0xA4,  0x34,  0x4C,  0x98,  0xBF,  0x20,  0x62,  0x38,  0x52,  0x04,  0xA0,  0xFB, 	/* 1BF10 */
+	0xE2,  0x24,  0xFA,  0x42,  0xA4,  0xB2,  0x46,  0x44,  0x38,  0x4C,  0x04,  0x8D,  0x21,  0x02,  0x16,  0x57, 	/* 1BF20 */
+	0x84,  0x90,  0xF5,  0x42,  0x54,  0xF5,  0x42,  0x7C,  0xB5,  0x06,  0x92,  0x31,  0x2C,  0x0E,  0x8E,  0x21, 	/* 1BF30 */
+	0x02,  0x10,  0x51,  0xE4,  0xA2,  0xFB,  0x22,  0x52,  0xF9,  0x22,  0x2A,  0xB3,  0xA6,  0x8A,  0x30,  0x2C, 	/* 1BF40 */
+	0x0C,  0x91,  0x20,  0x03,  0x3E,  0x4A,  0x08,  0x20,  0xFB,  0xC2,  0x24,  0xFA,  0x42,  0x34,  0xAA,  0x87, 	/* 1BF50 */
+	0x48,  0x39,  0x4C,  0x62,  0x94,  0x20,  0x82,  0x08,  0x52,  0xA4,  0xAA,  0xFA,  0x92,  0x49,  0xF8,  0xA2, 	/* 1BF60 */
+	0x9A,  0xB0,  0x46,  0x88,  0x31,  0x0C,  0x60,  0x95,  0x27,  0xC2,  0x14,  0x51,  0x44,  0x94,  0xF9,  0x42, 	/* 1BF70 */
+	0x7E,  0xF9,  0x42,  0xA4,  0xB2,  0x46,  0xA4,  0x32,  0x4C,  0x7E,  0x9E,  0x21,  0x03,  0x10,  0x4A,  0x08, 	/* 1BF80 */
+	0x3E,  0xFC,  0x22,  0x3A,  0xF8,  0x22,  0x0A,  0xAB,  0x27,  0x02,  0x38,  0x2C,  0x0C,  0xA9,  0x20,  0x02, 	/* 1BF90 */
+	0x3E,  0x50,  0x04,  0xBE,  0xFA,  0x22,  0x22,  0xFB,  0xE2,  0xA0,  0xB2,  0x06,  0xC0,  0x34,  0x0C,  0x80, 	/* 1BFA0 */
+	0xAC,  0x20,  0x02,  0x3E,  0x52,  0x24,  0xA2,  0xFB,  0xE2,  0x28,  0xFA,  0x82,  0xA8,  0xB2,  0x86,  0xC4, 	/* 1BFB0 */
+	0x34,  0x4C,  0x82,  0xB4,  0x21,  0x02,  0x10,  0x52,  0x84,  0xBC,  0xF4,  0x22,  0xFC,  0xFA,  0x42,  0x24, 	/* 1BFC0 */
+	0xB2,  0x46,  0xB8,  0x32,  0x0C,  0x20,  0xB7,  0x21,  0x02,  0x10,  0x51,  0x04,  0xFE,  0xF1,  0x02,  0x10, 	/* 1BFD0 */
+	0xF9,  0x02,  0xFC,  0xB4,  0x46,  0xC4,  0x34,  0x4C,  0x7C,  0xBF,  0x20,  0x02,  0x3E,  0x52,  0xA4,  0xAA, 	/* 1BFE0 */
+	0xFE,  0xA2,  0x3E,  0xFA,  0xA2,  0xAA,  0xB2,  0xA6,  0xAA,  0x33,  0xEC,  0x20,  0x84,  0x21,  0x02,  0x50, 	/* 1BFF0 */
+	0x55,  0x04,  0xFC,  0xF9,  0x02,  0x10,  0xFF,  0xE2,  0x10,  0xB2,  0x86,  0xA8,  0x34,  0x4C,  0x82,  0x85, 	/* 1C000 */
+	0x20,  0x02,  0x7E,  0x54,  0x04,  0xC0,  0xF7,  0xC2,  0x44,  0xFC,  0x42,  0x7C,  0xB4,  0x06,  0xC0,  0x34, 	/* 1C010 */
+	0x0C,  0xFE,  0x88,  0x21,  0x02,  0x10,  0x57,  0xE4,  0xC2,  0xFA,  0x02,  0x20,  0xFA,  0x42,  0xB8,  0xB2, 	/* 1C020 */
+	0x06,  0xA2,  0x32,  0x2C,  0x1E,  0x89,  0x21,  0x02,  0x10,  0x57,  0xE4,  0x90,  0xF9,  0x42,  0x64,  0xFA, 	/* 1C030 */
+	0x82,  0x90,  0xB1,  0x86,  0x24,  0x3F,  0xAC,  0x02,  0x8B,  0x22,  0x02,  0x20,  0x53,  0xE4,  0xC2,  0xFB, 	/* 1C040 */
+	0xA2,  0x2A,  0xFA,  0xA2,  0xBA,  0xB2,  0xC6,  0xA1,  0x32,  0x1C,  0x1F,  0x90,  0x20,  0x02,  0x7F,  0x51, 	/* 1C050 */
+	0x04,  0x90,  0xF9,  0x02,  0x20,  0xFB,  0xE2,  0x52,  0xA9,  0x27,  0x12,  0x39,  0x2C,  0x1E,  0x97,  0x22, 	/* 1C060 */
+	0x42,  0x24,  0x52,  0x44,  0xFE,  0xFA,  0x42,  0x24,  0xFA,  0x42,  0xBC,  0xB2,  0x46,  0xA4,  0x32,  0x4C, 	/* 1C070 */
+	0x3C,  0x9A,  0x24,  0x02,  0xCE,  0x5A,  0xA8,  0xAA,  0xFA,  0xA2,  0xAA,  0xFA,  0xA2,  0xAA,  0xAE,  0xA7, 	/* 1C080 */
+	0x2E,  0x3A,  0x8C,  0x48,  0x9B,  0x22,  0x82,  0x28,  0x52,  0x84,  0xC4,  0xF8,  0x42,  0x02,  0xFF,  0xC2, 	/* 1C090 */
+	0x44,  0xB4,  0x46,  0x44,  0x3C,  0x4E,  0x7C,  0x9E,  0x20,  0x83,  0x0C,  0x48,  0xA8,  0x7E,  0xFC,  0x82, 	/* 1C0A0 */
+	0x4A,  0xF4,  0xA2,  0x4C,  0xB6,  0x86,  0xD4,  0x32,  0x4C,  0x42,  0xA2,  0x21,  0x02,  0x10,  0x51,  0x04, 	/* 1C0B0 */
+	0xFE,  0xF9,  0x02,  0x38,  0xF5,  0x42,  0x92,  0xB7,  0xC6,  0x10,  0x39,  0x0C,  0x10,  0xA4,  0x22,  0x02, 	/* 1C0C0 */
+	0x20,  0x53,  0xE4,  0xC2,  0xFB,  0xA2,  0x2A,  0xFA,  0xA2,  0xAA,  0xB3,  0xA6,  0x82,  0x30,  0x2C,  0x0C, 	/* 1C0D0 */
+	0xA6,  0x20,  0x02,  0x7E,  0x50,  0x84,  0x88,  0xF8,  0x82,  0x2E,  0xFA,  0x82,  0x28,  0xB2,  0x86,  0xA8, 	/* 1C0E0 */
+	0x32,  0x8C,  0x7E,  0xB1,  0x20,  0x83,  0x08,  0x4F,  0xE8,  0x40,  0x7C,  0x82,  0x48,  0xF4,  0x82,  0x48, 	/* 1C0F0 */
+	0xAD,  0x47,  0x52,  0x3D,  0xEC,  0xB2,  0xBE,  0x21,  0x02,  0x18,  0x52,  0x48,  0xFA,  0xF5,  0x02,  0x7C, 	/* 1C100 */
+	0xF5,  0x02,  0x90,  0xB7,  0xE6,  0x90,  0x31,  0x0C,  0x10,  0x80,  0x20,  0x02,  0x7C,  0x54,  0x44,  0xFC, 	/* 1C110 */
+	0xF4,  0x42,  0x7C,  0xFD,  0x22,  0x54,  0xB4,  0x86,  0xC8,  0x37,  0x4C,  0xC2,  0x83,  0x21,  0x02,  0x10, 	/* 1C120 */
+	0x57,  0xE4,  0xA8,  0xF4,  0xC2,  0xFA,  0xFA,  0x82,  0x28,  0xB2,  0x86,  0xAA,  0x34,  0xAC,  0x86,  0x85, 	/* 1C130 */
+	0x20,  0x03,  0x7E,  0x4C,  0x28,  0xFA,  0xF4,  0x22,  0x7A,  0xF6,  0xA2,  0x6A,  0xAF,  0xA7,  0x42,  0x3C, 	/* 1C140 */
+	0x2C,  0x46,  0x91,  0x21,  0x02,  0x50,  0x55,  0x04,  0xFC,  0xF9,  0x02,  0x10,  0xFF,  0xE2,  0x28,  0xB2, 	/* 1C150 */
+	0x86,  0xAA,  0x34,  0xAC,  0x86,  0x93,  0x23,  0x02,  0x10,  0x52,  0x84,  0xC4,  0xF7,  0xE2,  0x10,  0xF9, 	/* 1C160 */
+	0x02,  0x7C,  0xB1,  0x06,  0x90,  0x31,  0x0C,  0xFE,  0x95,  0x21,  0x03,  0x7E,  0x49,  0x08,  0x7C,  0xF9, 	/* 1C170 */
+	0x42,  0x7C,  0xF5,  0x02,  0x7E,  0xA9,  0x27,  0x1C,  0x3A,  0x4C,  0xC2,  0x96,  0x21,  0x02,  0x50,  0x55, 	/* 1C180 */
+	0x04,  0xFC,  0xF9,  0x02,  0x10,  0xFF,  0xE2,  0x98,  0xB3,  0x46,  0x52,  0x39,  0x0C,  0x10,  0x98,  0x21, 	/* 1C190 */
+	0x02,  0x1C,  0x52,  0x44,  0xA4,  0xF5,  0x82,  0x08,  0xF9,  0x02,  0x3E,  0xB3,  0x26,  0xD2,  0x31,  0x2C, 	/* 1C1A0 */
+	0x1E,  0x9A,  0x22,  0x83,  0x28,  0x4A,  0x88,  0xAA,  0xF6,  0xC2,  0x28,  0xF6,  0xC2,  0xAA,  0xAA,  0xA7, 	/* 1C1B0 */
+	0x28,  0x3C,  0xAC,  0x86,  0x9B,  0x20,  0xC2,  0x70,  0x51,  0x04,  0x90,  0xFF,  0xE2,  0x10,  0xF9,  0x02, 	/* 1C1C0 */
+	0x7C,  0xB4,  0x46,  0xC4,  0x34,  0x4C,  0x7C,  0x9C,  0x24,  0x02,  0x4E,  0x4A,  0x0B,  0x10,  0x3F,  0xF4, 	/* 1C1D0 */
+	0x44,  0xDF,  0x44,  0x44,  0x55,  0x44,  0xE4,  0x47,  0x45,  0x8C,  0xAD,  0x21,  0x82,  0x14,  0x51,  0xC4, 	/* 1C1E0 */
+	0xF0,  0xF9,  0xC2,  0x70,  0xF9,  0xE2,  0x74,  0xB0,  0x86,  0x9A,  0x36,  0x6C,  0x02,  0xB7,  0x21,  0x02, 	/* 1C1F0 */
+	0x54,  0x55,  0x44,  0x92,  0xF7,  0xC2,  0x44,  0xFF,  0xC2,  0x44,  0xB7,  0xC6,  0xC4,  0x34,  0x4C,  0x4C, 	/* 1C200 */
+	0xB9,  0x20,  0xC3,  0x70,  0x49,  0x08,  0x7E,  0xFB,  0x82,  0x54,  0xF9,  0x22,  0x7C,  0xA9,  0x67,  0x12, 	/* 1C210 */
+	0x3A,  0x2C,  0x4C,  0x8F,  0x21,  0x03,  0x10,  0x4F,  0xE8,  0x10,  0xFD,  0x42,  0x54,  0xFB,  0xA2,  0x12, 	/* 1C220 */
+	0xA9,  0x87,  0x18,  0x3A,  0x4C,  0x42,  0x92,  0x22,  0x02,  0x3C,  0x52,  0x44,  0xD8,  0xF9,  0x42,  0x6B, 	/* 1C230 */
+	0xF8,  0x82,  0x3E,  0xB0,  0x86,  0xFF,  0x30,  0x8C,  0x08,  0xA4,  0x20,  0x82,  0xE8,  0x5A,  0x84,  0xBE, 	/* 1C240 */
+	0xFE,  0xA2,  0xAA,  0xFE,  0xA2,  0xAA,  0xBB,  0xA6,  0xEA,  0x39,  0x2C,  0x26,  0xA9,  0x22,  0x42,  0x7E, 	/* 1C250 */
+	0x52,  0x44,  0x88,  0xF8,  0x82,  0x7E,  0xFA,  0x02,  0xA0,  0xB2,  0x06,  0x20,  0x3A,  0x0C,  0x1E,  0xAA, 	/* 1C260 */
+	0x21,  0x42,  0x12,  0x57,  0xE4,  0x90,  0xF7,  0xE2,  0x52,  0xFF,  0xE2,  0x52,  0xB7,  0xE6,  0xD2,  0x35, 	/* 1C270 */
+	0x2C,  0x56,  0xAD,  0x24,  0x43,  0x24,  0x4A,  0x88,  0x7C,  0x7C,  0x42,  0x44,  0xFF,  0xC2,  0x28,  0xAA, 	/* 1C280 */
+	0x87,  0x28,  0x3C,  0xAC,  0x86,  0xB2,  0x20,  0x42,  0x38,  0x52,  0x04,  0xBE,  0xFA,  0x42,  0x24,  0xFA, 	/* 1C290 */
+	0x42,  0x7E,  0xB0,  0x06,  0xA4,  0x32,  0x2C,  0x42,  0xB3,  0x21,  0x02,  0x7E,  0x51,  0x04,  0xBC,  0xF1, 	/* 1C2A0 */
+	0x02,  0xFE,  0xF2,  0x42,  0xFE,  0xB2,  0x46,  0x54,  0x39,  0x4C,  0x0C,  0xB8,  0x20,  0x02,  0x7E,  0x54, 	/* 1C2B0 */
+	0x24,  0xFE,  0xF4,  0x82,  0x7E,  0xFC,  0x82,  0x48,  0xB7,  0xE6,  0xA2,  0x32,  0x2C,  0x3E,  0xBA,  0x20, 	/* 1C2C0 */
+	0x82,  0xFE,  0x58,  0x28,  0x40,  0xFF,  0xE2,  0x5A,  0xF5,  0xA2,  0xBA,  0xB2,  0xE6,  0xA8,  0x34,  0xAC, 	/* 1C2D0 */
+	0x86,  0xBC,  0x20,  0x03,  0xFE,  0x4C,  0x68,  0xAA,  0x7F,  0xE2,  0x92,  0xF9,  0x22,  0xD6,  0xAD,  0x67, 	/* 1C2E0 */
+	0xFE,  0x38,  0x2C,  0x86,  0x86,  0x21,  0x03,  0x7C,  0x49,  0x08,  0xFC,  0xF1,  0x02,  0xFE,  0xF4,  0x42, 	/* 1C2F0 */
+	0x7C,  0xAC,  0x47,  0x7C,  0x3C,  0x4C,  0x4C,  0x8F,  0x20,  0x03,  0x7E,  0x4A,  0x88,  0x28,  0xFE,  0xE2, 	/* 1C300 */
+	0x42,  0xFC,  0x22,  0x42,  0xAE,  0xE7,  0x28,  0x3A,  0x8C,  0x7E,  0x90,  0x22,  0x42,  0x28,  0x57,  0xE4, 	/* 1C310 */
+	0xC8,  0xF4,  0x82,  0x7C,  0xFC,  0x82,  0x48,  0xB7,  0xC6,  0xC8,  0x34,  0x8C,  0x7E,  0x98,  0x20,  0xC2, 	/* 1C320 */
+	0x70,  0x51,  0x04,  0xFE,  0xF5,  0x42,  0xFE,  0xF5,  0x42,  0x54,  0xBF,  0xE6,  0x90,  0x31,  0x0C,  0x7E, 	/* 1C330 */
+	0x99,  0x22,  0xA2,  0x2A,  0x55,  0x44,  0xAA,  0xFA,  0xA2,  0x00,  0xFB,  0xE2,  0xAA,  0xB3,  0xE6,  0xAA, 	/* 1C340 */
+	0x32,  0xAC,  0x3E,  0x9A,  0x20,  0xC3,  0x74,  0x4B,  0x28,  0x4A,  0xF7,  0xC2,  0x14,  0xFF,  0xF2,  0x14, 	/* 1C350 */
+	0xB7,  0xC6,  0x10,  0x39,  0x0C,  0x30,  0xA0,  0x21,  0x02,  0x7E,  0x54,  0x24,  0x80,  0xFF,  0xE2,  0x10, 	/* 1C360 */
+	0xF5,  0x02,  0x5C,  0xB5,  0x06,  0xF0,  0x35,  0x8C,  0x86,  0xA2,  0x21,  0x02,  0x14,  0x57,  0xE4,  0x94, 	/* 1C370 */
+	0xF8,  0xA2,  0x76,  0xF9,  0x02,  0x7E,  0xB1,  0x46,  0x98,  0x32,  0xAC,  0x46,  0xA3,  0x20,  0x02,  0xFE, 	/* 1C380 */
+	0x55,  0x24,  0xB4,  0xF2,  0xC2,  0x52,  0xFF,  0xE2,  0x22,  0xB2,  0xA6,  0x44,  0x3A,  0xAC,  0x91,  0xA6, 	/* 1C390 */
+	0x22,  0x02,  0x7C,  0x54,  0x44,  0xFC,  0xFC,  0x42,  0x7C,  0xF9,  0x02,  0x7E,  0xB5,  0x26,  0xD2,  0x35, 	/* 1C3A0 */
+	0x6C,  0x10,  0xA8,  0x22,  0x42,  0x24,  0x57,  0xE4,  0xA4,  0xF2,  0x42,  0x7E,  0xFD,  0x22,  0x52,  0xB7, 	/* 1C3B0 */
+	0xE6,  0xD2,  0x35,  0x2C,  0x7E,  0xAB,  0x20,  0x02,  0x7C,  0x54,  0x44,  0xFC,  0xF4,  0x42,  0xFF,  0xF2, 	/* 1C3C0 */
+	0x02,  0x7E,  0xBA,  0xA6,  0xAA,  0x35,  0x2C,  0x0C,  0xAC,  0x21,  0x02,  0x7E,  0x51,  0x04,  0xFC,  0xFD, 	/* 1C3D0 */
+	0x42,  0x7C,  0xFD,  0x42,  0x7C,  0xB3,  0x86,  0xD4,  0x31,  0x2C,  0x10,  0xAE,  0x20,  0x03,  0x7E,  0x4D, 	/* 1C3E0 */
+	0x28,  0x7E,  0xFD,  0x22,  0x52,  0xF7,  0xA2,  0x6A,  0xAE,  0xA7,  0x7A,  0x3C,  0x2C,  0x7E,  0xAF,  0x22, 	/* 1C3F0 */
+	0x82,  0x28,  0x57,  0xC4,  0xA8,  0xFA,  0x82,  0x7E,  0xF8,  0x02,  0x3C,  0xB2,  0x46,  0xBC,  0x32,  0x4C, 	/* 1C400 */
+	0x3C,  0xB2,  0x20,  0x02,  0x7C,  0x50,  0x44,  0xBC,  0xF8,  0x42,  0x7E,  0xF9,  0x42,  0x58,  0xB3,  0x86, 	/* 1C410 */
+	0xD4,  0x31,  0x2C,  0x30,  0xB5,  0x22,  0x82,  0x7E,  0x52,  0x84,  0x90,  0xF9,  0x82,  0x2A,  0xFE,  0xC2, 	/* 1C420 */
+	0xA8,  0xB2,  0x86,  0x2A,  0x3A,  0xAC,  0x26,  0xBA,  0x22,  0x42,  0x7E,  0x52,  0x44,  0x90,  0xF9,  0x02, 	/* 1C430 */
+	0x7E,  0xF9,  0x02,  0x9C,  0xB1,  0x46,  0xA4,  0x32,  0x4C,  0x58,  0xBB,  0x20,  0x42,  0x76,  0x50,  0x44, 	/* 1C440 */
+	0xFF,  0xF1,  0x42,  0x14,  0xF9,  0xC2,  0x54,  0xB5,  0x46,  0x5D,  0x3E,  0x3C,  0x01,  0x84,  0x20,  0x83, 	/* 1C450 */
+	0x7E,  0x48,  0x08,  0x3C,  0xFA,  0x42,  0x24,  0xFB,  0xC2,  0x08,  0xAA,  0xC7,  0x4A,  0x38,  0xAC,  0x18, 	/* 1C460 */
+	0x8B,  0x27,  0xC2,  0x44,  0x55,  0xC4,  0xD4,  0xF5,  0x42,  0xFE,  0xF8,  0x22,  0xBA,  0xBA,  0xA6,  0xBA, 	/* 1C470 */
+	0x38,  0x2C,  0x86,  0x8D,  0x20,  0x83,  0x7E,  0x4D,  0x48,  0xFE,  0xF5,  0x42,  0x5C,  0xFC,  0x02,  0x7E, 	/* 1C480 */
+	0xAD,  0x47,  0x48,  0x39,  0x4C,  0xA2,  0x94,  0x2E,  0xE2,  0xAA,  0x5A,  0xA4,  0xEE,  0xF8,  0x02,  0x7C, 	/* 1C490 */
+	0xF8,  0x02,  0x7E,  0xB2,  0x06,  0xBC,  0x30,  0x4C,  0x18,  0x96,  0x22,  0x42,  0x7E,  0x52,  0x44,  0xBC, 	/* 1C4A0 */
+	0xFA,  0x42,  0x3C,  0xFA,  0x42,  0xFE,  0xB5,  0x46,  0x66,  0x3C,  0x0C,  0x7E,  0x9B,  0x21,  0xC3,  0x54, 	/* 1C4B0 */
+	0x49,  0x48,  0x94,  0xFF,  0x62,  0x80,  0xFD,  0xE2,  0x82,  0xAF,  0x47,  0x88,  0x39,  0x4C,  0xA2,  0x9C, 	/* 1C4C0 */
+	0x20,  0x02,  0x7E,  0x55,  0x24,  0xD2,  0xF7,  0x62,  0x40,  0xFF,  0xE2,  0x4A,  0xB7,  0xA6,  0xC4,  0x34, 	/* 1C4D0 */
+	0xAC,  0x51,  0xA0,  0x21,  0x02,  0x7C,  0x54,  0x44,  0xFC,  0xFC,  0x42,  0x7C,  0xF8,  0x02,  0x7E,  0xB1, 	/* 1C4E0 */
+	0x06,  0x7C,  0x39,  0x0C,  0xFE,  0xAC,  0x21,  0x42,  0x64,  0x52,  0x44,  0xA5,  0xF7,  0xD2,  0x2E,  0xF6, 	/* 1C4F0 */
+	0x42,  0x74,  0xAA,  0xA7,  0x2A,  0x3B,  0x2C,  0x21,  0xAE,  0x27,  0x02,  0x28,  0x54,  0x48,  0xBA,  0xF0, 	/* 1C500 */
+	0x02,  0xEA,  0xFA,  0xA2,  0xEA,  0xBB,  0x46,  0xEA,  0x3A,  0xAC,  0xAA,  0xB5,  0x20,  0x83,  0x3E,  0x5C, 	/* 1C510 */
+	0xA8,  0x7F,  0x74,  0xA2,  0xBE,  0xFE,  0x82,  0xBE,  0xB6,  0x86,  0x3E,  0x35,  0x8C,  0x8F,  0xBC,  0x20, 	/* 1C520 */
+	0x42,  0x05,  0x57,  0xF4,  0xC4,  0xF7,  0xC2,  0x45,  0xFF,  0x52,  0x55,  0xB7,  0x26,  0xC6,  0x34,  0xAC, 	/* 1C530 */
+	0x91,  0xBE,  0x21,  0xC2,  0x70,  0x51,  0x04,  0xFE,  0xFD,  0x42,  0x7C,  0xF5,  0x42,  0x7C,  0xA9,  0x07, 	/* 1C540 */
+	0x7C,  0x39,  0x0C,  0xFE,  0x8C,  0x22,  0x82,  0x7E,  0x52,  0x84,  0xFE,  0xFA,  0xA2,  0x7E,  0xFA,  0xA2, 	/* 1C550 */
+	0x7E,  0xB2,  0x86,  0x6C,  0x3A,  0xAC,  0x28,  0x94,  0x21,  0x02,  0xFE,  0x59,  0x24,  0xAA,  0xF4,  0x42, 	/* 1C560 */
+	0x14,  0xFA,  0x82,  0x44,  0xAF,  0xE7,  0x45,  0x3C,  0x4C,  0x7C,  0x96,  0x21,  0x03,  0x52,  0x4B,  0x48, 	/* 1C570 */
+	0x7C,  0xF4,  0x42,  0x7C,  0x74,  0x42,  0x7C,  0xAC,  0x47,  0x7C,  0x3A,  0x4C,  0xC2,  0x97,  0x20,  0x82, 	/* 1C580 */
+	0x14,  0x52,  0x24,  0xFF,  0xFA,  0x22,  0x3E,  0xFA,  0x22,  0x3E,  0xB4,  0x06,  0xFE,  0x32,  0x2C,  0x3E, 	/* 1C590 */
+	0x9A,  0x20,  0x42,  0x08,  0x55,  0xE4,  0xB2,  0xF9,  0xE2,  0x10,  0xFD,  0xE2,  0x52,  0xB5,  0x26,  0xDE, 	/* 1C5A0 */
+	0x36,  0x0C,  0x9F,  0xA7,  0x25,  0x43,  0x54,  0x4F,  0xC8,  0x80,  0xFF,  0xE2,  0x00,  0x7F,  0xC2,  0x44, 	/* 1C5B0 */
+	0xAF,  0xC7,  0x44,  0x3A,  0x8C,  0x7E,  0xAC,  0x20,  0x82,  0x7E,  0x50,  0x04,  0xBC,  0xFA,  0x42,  0x3C, 	/* 1C5C0 */
+	0xFF,  0xE2,  0x42,  0xB7,  0xA6,  0xEA,  0x37,  0xAC,  0x46,  0xAD,  0x24,  0xC2,  0x70,  0x54,  0x24,  0xBE, 	/* 1C5D0 */
+	0xFA,  0x42,  0xBC,  0xFA,  0x42,  0xBC,  0xBA,  0x46,  0xFE,  0x32,  0x4C,  0xC2,  0xAE,  0x21,  0x02,  0x7E, 	/* 1C5E0 */
+	0x51,  0x04,  0xFC,  0xF4,  0x42,  0x7C,  0xFC,  0x42,  0x7C,  0xB4,  0x46,  0xFE,  0x32,  0x4C,  0xC2,  0xB0, 	/* 1C5F0 */
+	0x21,  0xC2,  0x24,  0x54,  0x24,  0xBC,  0xF8,  0x02,  0x3C,  0xFA,  0x42,  0x42,  0xAF,  0xD7,  0x54,  0x35, 	/* 1C600 */
+	0x4C,  0xFE,  0xB9,  0x21,  0xC2,  0x14,  0x52,  0x24,  0xFC,  0xF0,  0x82,  0xC8,  0xF7,  0xE2,  0x48,  0xB5, 	/* 1C610 */
+	0x46,  0x62,  0x3A,  0x0C,  0x9F,  0x83,  0x24,  0x82,  0x48,  0x5F,  0xE4,  0x48,  0xF5,  0x02,  0x7E,  0xFE, 	/* 1C620 */
+	0x42,  0x7E,  0xBA,  0x46,  0xAC,  0x33,  0x2C,  0x61,  0x88,  0x24,  0x82,  0x3E,  0x50,  0x84,  0xBE,  0xFE, 	/* 1C630 */
+	0xA2,  0x3E,  0xFE,  0xA2,  0x7E,  0xB4,  0x87,  0x5E,  0x2A,  0x8D,  0x1F,  0x90,  0x20,  0x03,  0xFE,  0x53, 	/* 1C640 */
+	0x68,  0xDA,  0xF3,  0x62,  0x5A,  0xFA,  0x82,  0x4C,  0xA9,  0x37,  0x64,  0x39,  0x8C,  0x60,  0x91,  0x21, 	/* 1C650 */
+	0x02,  0x7E,  0x52,  0x44,  0xA8,  0xF7,  0xE2,  0x52,  0xF7,  0xA2,  0x52,  0xB7,  0xA6,  0xEA,  0x37,  0xAC, 	/* 1C660 */
+	0x46,  0x96,  0x04,  0x07,  0xFE,  0x49,  0x47,  0xFC,  0x5E,  0x65,  0x38,  0xBD,  0xE0,  0xA0,  0x31,  0x8D, 	/* 1C670 */
+	0xF6,  0x0A,  0x07,  0xFC,  0x97,  0x2F,  0xE2,  0xAA,  0x5F,  0xA4,  0x94,  0xFF,  0x42,  0xAA,  0xFF,  0x12, 	/* 1C680 */
+	0x10,  0xB7,  0xC6,  0x90,  0x31,  0x0C,  0xFE,  0x98,  0x22,  0x82,  0xAE,  0x5A,  0xA8,  0xBA,  0xFE,  0x42, 	/* 1C690 */
+	0x28,  0xFE,  0x22,  0xBF,  0xAB,  0x27,  0xAA,  0x2A,  0x2C,  0x26,  0x9D,  0x27,  0xC2,  0x44,  0x57,  0xC4, 	/* 1C6A0 */
+	0xC4,  0xFF,  0xE2,  0xAA,  0xFF,  0xE2,  0x00,  0xB7,  0xC6,  0xA4,  0x31,  0x8C,  0x66,  0xA1,  0x21,  0x02, 	/* 1C6B0 */
+	0x7C,  0x52,  0x84,  0xFE,  0xF4,  0x42,  0x7C,  0xFC,  0x42,  0x7C,  0xB2,  0x86,  0xA8,  0x34,  0xAC,  0x86, 	/* 1C6C0 */
+	0xA4,  0x21,  0x03,  0x7C,  0x4D,  0x48,  0x7E,  0xFD,  0x42,  0x7C,  0xF5,  0x42,  0xFE,  0xA9,  0x47,  0x24, 	/* 1C6D0 */
+	0x3B,  0x8C,  0x64,  0xA5,  0x21,  0x02,  0xFE,  0x58,  0x24,  0xBE,  0xFA,  0x82,  0x5E,  0xF5,  0x22,  0xD2, 	/* 1C6E0 */
+	0xB5,  0xE6,  0xD2,  0x35,  0x2C,  0x5E,  0xA8,  0x10,  0x4F,  0xF8,  0x55,  0x07,  0xDF,  0x55,  0x4F,  0xD4, 	/* 1C6F0 */
+	0x16,  0x41,  0xA4,  0x31,  0x8F,  0xFE,  0x15,  0x07,  0xFC,  0x83,  0x21,  0x02,  0x7C,  0x51,  0x04,  0x54, 	/* 1C700 */
+	0xFE,  0xE2,  0x44,  0xFF,  0xE2,  0x00,  0xB7,  0xE6,  0xA8,  0x32,  0xAC,  0x46,  0x87,  0x20,  0xC2,  0x70, 	/* 1C710 */
+	0x55,  0x44,  0xB8,  0xFF,  0xE2,  0x34,  0xF5,  0x22,  0xFD,  0xB5,  0x46,  0x7C,  0x3D,  0x4C,  0x7C,  0x90, 	/* 1C720 */
+	0x21,  0x02,  0x7E,  0x52,  0x84,  0xFC,  0xF4,  0x62,  0x7D,  0xFC,  0x42,  0x7C,  0xB1,  0x06,  0x54,  0x39, 	/* 1C730 */
+	0x2C,  0x30,  0x93,  0x22,  0x42,  0xF4,  0x50,  0x48,  0xEF,  0xFA,  0xA2,  0xF2,  0xF0,  0xA2,  0xF4,  0xB2, 	/* 1C740 */
+	0x46,  0xFA,  0x32,  0xAC,  0x71,  0x94,  0x2F,  0xE2,  0x28,  0x5F,  0xE8,  0xAA,  0xFF,  0xE2,  0x44,  0xF7, 	/* 1C750 */
+	0xC2,  0x44,  0xB7,  0xC6,  0x10,  0x3F,  0xEC,  0x10,  0x98,  0x21,  0x02,  0x7C,  0x52,  0x84,  0xFE,  0xF5, 	/* 1C760 */
+	0x42,  0x7C,  0xFD,  0x42,  0x7C,  0xB1,  0x06,  0xFC,  0x31,  0x0C,  0xFE,  0x99,  0x27,  0x02,  0x16,  0x56, 	/* 1C770 */
+	0x84,  0xAA,  0xFD,  0xC2,  0x82,  0xF7,  0xC2,  0x44,  0xB7,  0xC6,  0xC4,  0x32,  0x8C,  0x7E,  0x9A,  0x20, 	/* 1C780 */
+	0x03,  0x7E,  0x4A,  0x88,  0x6E,  0xFC,  0x22,  0x6E,  0xFA,  0x82,  0x7E,  0xAA,  0x07,  0x6A,  0x3A,  0x2C, 	/* 1C790 */
+	0x1E,  0xA1,  0x24,  0x82,  0xEC,  0x54,  0xA4,  0xFF,  0xF0,  0x82,  0xEA,  0xFA,  0xA2,  0xEA,  0xBA,  0x46, 	/* 1C7A0 */
+	0x54,  0x36,  0xCD,  0x92,  0xAB,  0x22,  0x82,  0x7E,  0x54,  0x84,  0xFC,  0xFC,  0x82,  0x7E,  0xF0,  0x02, 	/* 1C7B0 */
+	0xEE,  0xBA,  0xA6,  0xBA,  0x38,  0x2C,  0x86,  0xB5,  0x24,  0x82,  0xEC,  0x54,  0xA4,  0xFF,  0xF8,  0x82, 	/* 1C7C0 */
+	0xEA,  0xFA,  0xA2,  0xEA,  0xB4,  0x46,  0xEC,  0x35,  0x4C,  0xE2,  0xB6,  0x2F,  0xE2,  0xAA,  0x5F,  0xF4, 	/* 1C7D0 */
+	0x00,  0xFF,  0xE2,  0x44,  0xF7,  0xC2,  0x12,  0xB3,  0x46,  0x68,  0x3B,  0x4C,  0x62,  0xB8,  0x2F,  0xE3, 	/* 1C7E0 */
+	0xAA,  0x4F,  0xE8,  0x10,  0xF7,  0xC2,  0x10,  0xFF,  0xE2,  0x44,  0xAF,  0xE7,  0x10,  0x3F,  0xCC,  0x10, 	/* 1C7F0 */
+	0xBA,  0x25,  0x42,  0x38,  0x57,  0xE4,  0xC2,  0xFB,  0xC2,  0x24,  0xFB,  0xC2,  0x7E,  0xB5,  0x26,  0x7E, 	/* 1C800 */
+	0x3D,  0x2C,  0x7E,  0x81,  0x26,  0xA2,  0x52,  0x56,  0xA4,  0xFE,  0xFA,  0x82,  0x2A,  0xF4,  0x62,  0x90, 	/* 1C810 */
+	0xB3,  0xC6,  0xE4,  0x31,  0x8C,  0x66,  0x84,  0x20,  0x82,  0x7E,  0x50,  0x84,  0xFF,  0xF0,  0x22,  0x7C, 	/* 1C820 */
+	0xF9,  0x02,  0x7F,  0xB7,  0xA6,  0xD6,  0x37,  0x2C,  0x06,  0x91,  0x27,  0x42,  0x47,  0x57,  0x44,  0xD8, 	/* 1C830 */
+	0xFF,  0x02,  0x47,  0xFF,  0x02,  0x00,  0xB3,  0xE6,  0xAA,  0x32,  0xAC,  0x7F,  0x92,  0xFA,  0x0A,  0x3E, 	/* 1C840 */
+	0xF4,  0x09,  0xFE,  0xF5,  0xAA,  0x7E,  0xFC,  0x00,  0xA0,  0x31,  0x8D,  0xF6,  0x0A,  0x07,  0xFC,  0x93, 	/* 1C850 */
+	0x20,  0x83,  0x3E,  0x4A,  0xA8,  0xFF,  0xF0,  0x02,  0xDC,  0xF1,  0x42,  0xDE,  0xB5,  0x26,  0x5E,  0x36, 	/* 1C860 */
+	0x0C,  0x9F,  0x9A,  0x22,  0x42,  0x7E,  0x52,  0x44,  0xFE,  0xF6,  0xC2,  0x92,  0xF7,  0xC2,  0x44,  0xB7, 	/* 1C870 */
+	0xC6,  0xC4,  0x37,  0xCC,  0xC2,  0x9B,  0x21,  0x02,  0x7E,  0x55,  0x44,  0xFE,  0xFD,  0x42,  0x7F,  0xF6, 	/* 1C880 */
+	0xA2,  0x7E,  0xB6,  0xA6,  0xBE,  0x3A,  0x4D,  0x42,  0x9E,  0x25,  0x42,  0xA8,  0x55,  0x48,  0xFE,  0xFA, 	/* 1C890 */
+	0xA2,  0x92,  0xFF,  0xE2,  0x5C,  0xB7,  0x46,  0xDC,  0x37,  0x2C,  0xDA,  0xA0,  0x29,  0x23,  0x54,  0x5B, 	/* 1C8A0 */
+	0xA8,  0xEC,  0xFB,  0xA2,  0xEE,  0xFB,  0xA2,  0x10,  0xB7,  0xE6,  0xB8,  0x35,  0x4C,  0x12,  0xA2,  0x21, 	/* 1C8B0 */
+	0xC2,  0x10,  0x57,  0xE4,  0xD0,  0xF7,  0xE2,  0x50,  0xFF,  0xE2,  0x6A,  0xB7,  0xE6,  0xD4,  0x35,  0x2C, 	/* 1C8C0 */
+	0xAE,  0xAA,  0x21,  0xC2,  0x10,  0x57,  0xE4,  0xD0,  0xF5,  0xE2,  0x6A,  0xFF,  0xE2,  0x6A,  0xB7,  0xE6, 	/* 1C8D0 */
+	0xAA,  0x3A,  0xAD,  0x7F,  0xB0,  0x21,  0x02,  0x28,  0x57,  0xC4,  0x83,  0xF7,  0xE2,  0x5A,  0xFF,  0xE2, 	/* 1C8E0 */
+	0x00,  0xBF,  0xE6,  0xAA,  0x3F,  0xEC,  0xAA,  0xB5,  0x22,  0x82,  0xFE,  0x52,  0x84,  0xEE,  0xFA,  0xA2, 	/* 1C8F0 */
+	0xFE,  0xF4,  0x42,  0x7E,  0xB4,  0x86,  0xFE,  0x34,  0x8C,  0x7E,  0xB7,  0x27,  0xE2,  0x24,  0x53,  0xC4, 	/* 1C900 */
+	0xA4,  0xF7,  0xC2,  0x04,  0xFF,  0xF2,  0xAA,  0xBE,  0xE6,  0xAA,  0x3F,  0xEC,  0x22,  0xBC,  0x20,  0x02, 	/* 1C910 */
+	0xFE,  0x5A,  0xA8,  0xFE,  0xF4,  0xA2,  0xBE,  0xF5,  0x42,  0xFE,  0xB5,  0x46,  0xDE,  0x37,  0x4C,  0x5E, 	/* 1C920 */
+	0xBD,  0x2A,  0x42,  0xFE,  0x52,  0x48,  0xFE,  0xF6,  0xC2,  0xB6,  0xF7,  0xC2,  0x44,  0xB7,  0xC6,  0xC4, 	/* 1C930 */
+	0x37,  0xCC,  0xC2,  0xBE,  0x46,  0x4B,  0xFA,  0x50,  0x4F,  0xFE,  0x2A,  0xC6,  0xF6,  0xA4,  0x40,  0xA0, 	/* 1C940 */
+	0x31,  0x8F,  0xF6,  0x15,  0x07,  0xFC,  0xBF,  0xA9,  0xCF,  0xD4,  0x52,  0x6A,  0x80,  0xFF,  0xCA,  0x94, 	/* 1C950 */
+	0xFC,  0x80,  0xB4,  0x31,  0x8D,  0xF6,  0x15,  0x07,  0xFC,  0x81,  0x2E,  0xE2,  0xAA,  0x5E,  0xE8,  0xAA, 	/* 1C960 */
+	0xFF,  0xE2,  0x48,  0xFF,  0xC2,  0x48,  0xAF,  0xE7,  0x24,  0x39,  0x8C,  0x66,  0xB7,  0x00,  0x01,  0xF8, 	/* 1C970 */
+	0x10,  0x01,  0xF0,  0x10,  0x01,  0xF0,  0x10,  0x0F,  0xFE,  0x14,  0x81,  0x30,  0x1D,  0x87,  0x06,  0x80, 	/* 1C980 */
+	0xFB,  0xE8,  0xA2,  0xFB,  0xE8,  0xA2,  0xFB,  0xE8,  0x02,  0x80,  0x28,  0x02,  0x80,  0x28,  0x02,  0x80, 	/* 1C990 */
+	0x28,  0x06,  0x82,  0xFB,  0xE8,  0xA2,  0xFB,  0xE8,  0xA2,  0xFB,  0xE8,  0x02,  0x80,  0x29,  0xF2,  0x80, 	/* 1C9A0 */
+	0x28,  0x02,  0x80,  0x28,  0x06,  0x83,  0xFB,  0xE8,  0xA2,  0xFB,  0xE8,  0xA2,  0xFB,  0xE8,  0x42,  0x84, 	/* 1C9B0 */
+	0x28,  0x42,  0x8A,  0x2B,  0x1A,  0x80,  0x28,  0x06,  0x87,  0xFB,  0xE8,  0xA2,  0xFB,  0xE8,  0xA2,  0xFB, 	/* 1C9C0 */
+	0xE8,  0x02,  0xBF,  0xA8,  0x42,  0x86,  0x28,  0x52,  0x84,  0x28,  0x46,  0x89,  0xFB,  0xE8,  0xA2,  0xFB, 	/* 1C9D0 */
+	0xE8,  0xA2,  0xFB,  0xE8,  0x22,  0xBF,  0xA8,  0x62,  0x8A,  0x29,  0x22,  0xA6,  0x28,  0x06,  0x8A,  0xFB, 	/* 1C9E0 */
+	0xE8,  0xA2,  0xFB,  0xE8,  0xA2,  0xFB,  0xE8,  0x42,  0xA4,  0xAA,  0x4A,  0xA4,  0xAB,  0xFA,  0x80,  0x28, 	/* 1C9F0 */
+	0x06,  0x8B,  0xFB,  0xE8,  0xA2,  0xFB,  0xE8,  0xA2,  0xFB,  0xE8,  0x02,  0xBF,  0xA8,  0xA2,  0xBF,  0xA9, 	/* 1CA00 */
+	0x22,  0xA2,  0x28,  0x26,  0x8F,  0xFB,  0xE8,  0xA2,  0xFB,  0xE8,  0xA2,  0xFB,  0xE8,  0x02,  0xBF,  0xA8, 	/* 1CA10 */
+	0x42,  0x9F,  0x28,  0x42,  0xBF,  0xA8,  0x06,  0x91,  0xFB,  0xE8,  0xA2,  0xFB,  0xE8,  0xA2,  0xFB,  0xE8, 	/* 1CA20 */
+	0x42,  0xBF,  0xA8,  0x42,  0x8E,  0x29,  0x52,  0xA4,  0xA8,  0x46,  0x93,  0xFB,  0xE8,  0xA2,  0xFB,  0xE8, 	/* 1CA30 */
+	0xA2,  0xFB,  0xE8,  0x02,  0x9F,  0x29,  0x12,  0x9F,  0x29,  0x12,  0x9F,  0x28,  0x06,  0x94,  0xFB,  0xE8, 	/* 1CA40 */
+	0xA2,  0xFB,  0xE8,  0xA2,  0xFB,  0xE8,  0x42,  0xFF,  0xA9,  0x22,  0x8C,  0x29,  0x22,  0xA1,  0x28,  0x06, 	/* 1CA50 */
+	0x96,  0xFB,  0xE8,  0xA2,  0xFB,  0xE8,  0xA2,  0xFB,  0xE8,  0x4A,  0xBD,  0x28,  0xE2,  0x95,  0x2A,  0x4A, 	/* 1CA60 */
+	0x8C,  0x28,  0x06,  0x98,  0xFB,  0xE8,  0xA2,  0xFB,  0xE8,  0xA2,  0xFB,  0xE9,  0xF2,  0x95,  0x29,  0xF2, 	/* 1CA70 */
+	0x95,  0x29,  0xF2,  0x84,  0x28,  0x46,  0x99,  0xFB,  0xE8,  0xA2,  0xFB,  0xE8,  0xA2,  0xFB,  0xE8,  0x42, 	/* 1CA80 */
+	0xFF,  0xE8,  0x42,  0xBF,  0xAA,  0x4A,  0xA7,  0x28,  0x46,  0xA0,  0xFB,  0xE8,  0xA2,  0xFB,  0xE8,  0xA2, 	/* 1CA90 */
+	0xFB,  0xE8,  0x02,  0x9F,  0x28,  0x42,  0x9F,  0x28,  0x52,  0xBF,  0xA8,  0x06,  0xA2,  0xFB,  0xE8,  0xA2, 	/* 1CAA0 */
+	0xFB,  0xE8,  0xA2,  0xFB,  0xE8,  0xA2,  0xBF,  0xA8,  0x42,  0xBF,  0xA8,  0xA2,  0x91,  0x2A,  0x06,  0xA3, 	/* 1CAB0 */
+	0xFB,  0xE8,  0xA2,  0xFB,  0xE8,  0xA2,  0xFF,  0xE9,  0x22,  0xAC,  0x29,  0x22,  0xBF,  0x2D,  0x2A,  0x9E, 	/* 1CAC0 */
+	0x28,  0x06,  0xA4,  0xFB,  0xE8,  0xA2,  0xFB,  0xE8,  0xA2,  0xFF,  0xE8,  0xA2,  0x9F,  0x2A,  0x0A,  0xDF, 	/* 1CAD0 */
+	0x69,  0x12,  0x9F,  0x28,  0x06,  0xA5,  0xFB,  0xE8,  0xA2,  0xFB,  0xE8,  0xA2,  0xFB,  0xE9,  0x42,  0x95, 	/* 1CAE0 */
+	0x29,  0xFA,  0xB5,  0x29,  0x22,  0x95,  0xA9,  0x0A,  0xA7,  0xFB,  0xE8,  0xA2,  0xFB,  0xE8,  0xA2,  0xFB, 	/* 1CAF0 */
+	0xE8,  0xA2,  0xBF,  0xA8,  0xA2,  0xBF,  0xE8,  0x92,  0xB0,  0xA8,  0x06,  0xA8,  0xFB,  0xE8,  0xA2,  0xFB, 	/* 1CB00 */
+	0xE8,  0xA2,  0xFF,  0xE8,  0x42,  0xBF,  0xA8,  0x42,  0x9F,  0x28,  0x42,  0xBF,  0xA8,  0x06,  0xAD,  0xFB, 	/* 1CB10 */
+	0xE8,  0xA2,  0xFB,  0xE8,  0xA2,  0xFB,  0xE9,  0xF2,  0x91,  0x29,  0xF2,  0x88,  0x29,  0xF2,  0x91,  0x29, 	/* 1CB20 */
+	0xF6,  0xB2,  0xFB,  0xE8,  0xA2,  0xFB,  0xE8,  0xA2,  0xFB,  0xE8,  0xA2,  0x9F,  0x29,  0x12,  0x9F,  0x28, 	/* 1CB30 */
+	0xA2,  0x93,  0xAA,  0x06,  0xB9,  0xFB,  0xE8,  0xA2,  0xFB,  0xE8,  0xA2,  0xFB,  0xE8,  0x42,  0xBF,  0xA8, 	/* 1CB40 */
+	0xA2,  0xBF,  0x2D,  0x5A,  0x9F,  0x68,  0x3E,  0xBB,  0xFB,  0xE8,  0xA2,  0xFB,  0xE8,  0xA2,  0xFB,  0xE8, 	/* 1CB50 */
+	0xE2,  0x94,  0x2B,  0xB2,  0x91,  0x29,  0xB2,  0x91,  0x29,  0xF6,  0xBC,  0xFB,  0xE8,  0xA2,  0xFB,  0xE8, 	/* 1CB60 */
+	0xA2,  0xFB,  0xE9,  0x12,  0xFA,  0xAA,  0x46,  0xBB,  0x2A,  0x8A,  0xCF,  0x29,  0x8E,  0xBE,  0xFB,  0xE8, 	/* 1CB70 */
+	0xA2,  0xFB,  0xE8,  0xA2,  0xFB,  0xE8,  0x22,  0xFF,  0xAB,  0xAA,  0xAA,  0xAB,  0x92,  0xF3,  0xA8,  0x4A, 	/* 1CB80 */
+	0x83,  0xFB,  0xE8,  0xA2,  0xFB,  0xE8,  0xA2,  0xFF,  0xE9,  0x12,  0x9F,  0x29,  0xF2,  0x85,  0x2B,  0xFA, 	/* 1CB90 */
+	0x8A,  0x2B,  0x1E,  0x87,  0xFB,  0xE8,  0xA2,  0xFB,  0xEF,  0xBE,  0x84,  0x2B,  0xFA,  0x8A,  0x2F,  0xFE, 	/* 1CBA0 */
+	0x91,  0x29,  0xF2,  0x91,  0x29,  0xF6,  0x8A,  0xFB,  0xE8,  0xA2,  0xFB,  0xE8,  0xA2,  0xFB,  0xEA,  0xF2, 	/* 1CBB0 */
+	0xD2,  0x2A,  0xFA,  0x82,  0x2A,  0xFA,  0xA8,  0xAC,  0xFA,  0x8C,  0xFB,  0xE8,  0xA2,  0xFB,  0xEF,  0xBE, 	/* 1CBC0 */
+	0x84,  0x2B,  0xFA,  0x95,  0x29,  0xF2,  0x95,  0x29,  0xF2,  0x95,  0x2A,  0x4A,  0x8D,  0xFB,  0xE8,  0xA2, 	/* 1CBD0 */
+	0xFB,  0xE8,  0xA2,  0xFB,  0xE8,  0x52,  0x9F,  0x2B,  0xFA,  0x89,  0x29,  0xF2,  0xA9,  0x28,  0xF6,  0x94, 	/* 1CBE0 */
+	0xFB,  0xE8,  0xA2,  0xFB,  0xEF,  0xBE,  0x84,  0x29,  0xE2,  0x85,  0x2B,  0xFA,  0x80,  0xAB,  0xFA,  0xAA, 	/* 1CBF0 */
+	0xAF,  0xFE,  0x95,  0xFB,  0xE8,  0xA2,  0xFB,  0xE8,  0xA2,  0xFB,  0xEA,  0x92,  0xFD,  0xEA,  0xAA,  0xAE, 	/* 1CC00 */
+	0xAB,  0x92,  0x92,  0xAA,  0x46,  0x96,  0xFB,  0xE8,  0xA2,  0xFB,  0xE8,  0xA2,  0xFB,  0xE9,  0xFA,  0x94, 	/* 1CC10 */
+	0x29,  0xF2,  0x94,  0x29,  0xFA,  0xAA,  0xAC,  0x36,  0x98,  0xFB,  0xE8,  0xA2,  0xFB,  0xE8,  0xA2,  0xFB, 	/* 1CC20 */
+	0xEB,  0xCA,  0xA7,  0xEB,  0xCA,  0xA6,  0xA9,  0xAA,  0xBD,  0xA8,  0x06,  0x9C,  0xFB,  0xEF,  0xBE,  0x8A, 	/* 1CC30 */
+	0x2F,  0xBE,  0x91,  0x2A,  0xAA,  0x91,  0x6F,  0xFE,  0xAA,  0xAB,  0xBA,  0x8A,  0x29,  0x26,  0xA1,  0xFB, 	/* 1CC40 */
+	0xE8,  0xA2,  0xFB,  0xE8,  0xA2,  0xFB,  0xEA,  0xAA,  0xBF,  0xA9,  0x52,  0x9F,  0x29,  0x52,  0xBF,  0xA8, 	/* 1CC50 */
+	0x46,  0xA2,  0xFB,  0xEF,  0xBE,  0x8A,  0x2F,  0xBE,  0x81,  0x2B,  0xBA,  0xAA,  0xAB,  0x92,  0xA7,  0xAB, 	/* 1CC60 */
+	0x92,  0xEF,  0xAB,  0x96,  0xA5,  0xFB,  0xEF,  0xBE,  0x8A,  0x2F,  0xFE,  0x82,  0x2C,  0xFA,  0xA5,  0x28, 	/* 1CC70 */
+	0xFA,  0xE2,  0x2A,  0xFA,  0xB2,  0x2C,  0xFA,  0x9C,  0x04,  0x03,  0xF8,  0x20,  0x83,  0xF8,  0x20,  0x03, 	/* 1CC80 */
+	0xFC,  0x20,  0x43,  0xFC,  0x04,  0x0F,  0xFE,  0x04,  0x00,  0x40,  0xA1,  0x00,  0xCE,  0xF0,  0xA1,  0x0A, 	/* 1CC90 */
+	0x10,  0xC1,  0x0A,  0xFE,  0x91,  0x09,  0x10,  0xE1,  0x08,  0x10,  0x81,  0x08,  0x10,  0xA8,  0x00,  0x0E, 	/* 1CCA0 */
+	0xFE,  0xA8,  0x0A,  0xBC,  0xCA,  0x4A,  0xA4,  0xAA,  0x4A,  0xAC,  0xEA,  0x09,  0x22,  0x92,  0x2A,  0x1E, 	/* 1CCB0 */
+	0xAA,  0x00,  0x0E,  0xFE,  0xA8,  0x0A,  0x80,  0xCF,  0xCA,  0xA4,  0x9A,  0x49,  0x98,  0xE8,  0x88,  0x98, 	/* 1CCC0 */
+	0x92,  0x4A,  0xC2,  0xAE,  0x00,  0x0E,  0x7C,  0xA0,  0x0A,  0x00,  0xCF,  0xEA,  0x28,  0x92,  0x89,  0x28, 	/* 1CCD0 */
+	0xE2,  0x88,  0x48,  0x88,  0xA9,  0x06,  0xAF,  0x02,  0x0E,  0x20,  0xA2,  0x0A,  0x20,  0xCA,  0x0A,  0xBC, 	/* 1CCE0 */
+	0xAA,  0x0A,  0xA0,  0xEA,  0x08,  0xA0,  0x8A,  0x0B,  0xFE,  0xB2,  0x02,  0x0E,  0x20,  0xBF,  0xEA,  0x20, 	/* 1CCF0 */
+	0xC2,  0x0A,  0x3C,  0x92,  0x49,  0x44,  0xE4,  0x48,  0x84,  0x90,  0x4A,  0x18,  0xBB,  0x00,  0x0E,  0x7C, 	/* 1CD00 */
+	0xA4,  0x4A,  0x44,  0xC7,  0xCA,  0x44,  0x94,  0x49,  0x7C,  0x94,  0x4E,  0x44,  0x84,  0x48,  0xFE,  0xBF, 	/* 1CD10 */
+	0x00,  0x0F,  0xFE,  0xA0,  0x4A,  0xF4,  0xC9,  0x4A,  0x94,  0xA9,  0x4A,  0xF4,  0xC8,  0x48,  0x04,  0x80, 	/* 1CD20 */
+	0x48,  0x0C,  0x80,  0x01,  0x0E,  0x10,  0xAF,  0xEA,  0x82,  0xC8,  0x2A,  0x40,  0x94,  0xC9,  0x70,  0xE4, 	/* 1CD30 */
+	0x08,  0x42,  0x84,  0x28,  0x3E,  0x82,  0x01,  0x0E,  0x10,  0xAF,  0xEA,  0x94,  0xC9,  0x0A,  0xBC,  0xA8, 	/* 1CD40 */
+	0x4A,  0xA8,  0xE9,  0x89,  0x18,  0x92,  0x4A,  0xC2,  0x84,  0x04,  0x4E,  0x44,  0xA4,  0x4A,  0xBE,  0xC8, 	/* 1CD50 */
+	0x4B,  0xA4,  0xA9,  0x4A,  0x94,  0xA8,  0x4C,  0x84,  0x88,  0x48,  0x8C,  0x8B,  0x00,  0x0E,  0x7E,  0xA0, 	/* 1CD60 */
+	0x8A,  0xBE,  0xCA,  0xAA,  0xAA,  0xAB,  0x6A,  0xA2,  0xEA,  0x28,  0xA6,  0x88,  0x08,  0xFE,  0x8C,  0x00, 	/* 1CD70 */
+	0x0E,  0xFE,  0xA1,  0x0A,  0x20,  0xE7,  0xC9,  0x44,  0x94,  0x49,  0x7C,  0xE4,  0x48,  0x44,  0x84,  0x48, 	/* 1CD80 */
+	0x7C,  0x8D,  0x02,  0x0E,  0x3C,  0xA6,  0x4A,  0x98,  0xC3,  0x4A,  0xCB,  0x90,  0x89,  0x7C,  0x94,  0x8E, 	/* 1CD90 */
+	0xFE,  0x80,  0x88,  0x08,  0x8F,  0x02,  0x0E,  0x20,  0xBF,  0xEA,  0x20,  0xC7,  0xCA,  0x44,  0xAF,  0xCB, 	/* 1CDA0 */
+	0x44,  0xE7,  0xC8,  0x44,  0x84,  0x48,  0x4C,  0x90,  0x00,  0x0E,  0xF8,  0xA8,  0x8A,  0xF8,  0xC8,  0x8A, 	/* 1CDB0 */
+	0x88,  0x9F,  0x89,  0xA4,  0xE9,  0x88,  0xA8,  0x8C,  0x4B,  0x02,  0x9B,  0xE9,  0x0A,  0x96,  0xAF,  0xCC, 	/* 1CDC0 */
+	0x90,  0xA9,  0x2B,  0xCE,  0xA2,  0x0A,  0x20,  0xCF,  0xC8,  0x20,  0x82,  0x09,  0xFE,  0x9C,  0x01,  0x0E, 	/* 1CDD0 */
+	0x10,  0xAF,  0xEA,  0x54,  0xC5,  0x4A,  0x54,  0xAB,  0x4A,  0x9A,  0xF1,  0x28,  0x28,  0x84,  0x49,  0x82, 	/* 1CDE0 */
+	0x9D,  0x01,  0x0E,  0x10,  0xBF,  0xEA,  0x10,  0xCD,  0xCA,  0x54,  0xA5,  0x4A,  0xBA,  0xF1,  0x28,  0x28, 	/* 1CDF0 */
+	0x84,  0x49,  0x82,  0x9E,  0xE1,  0x0A,  0xE8,  0xA4,  0x8D,  0xFE,  0xA4,  0x8A,  0x88,  0xB2,  0x8A,  0x20, 	/* 1CE00 */
+	0xDF,  0xC8,  0x20,  0x82,  0x0B,  0xFE,  0x9F,  0x01,  0x0E,  0x10,  0xA5,  0xCA,  0x50,  0xDF,  0xEA,  0x10, 	/* 1CE10 */
+	0xA5,  0x4A,  0x56,  0xEB,  0xA9,  0x10,  0x86,  0x09,  0x80,  0xA2,  0xE1,  0x0B,  0xFE,  0xB0,  0x2D,  0xFA, 	/* 1CE20 */
+	0xA0,  0x0B,  0xFE,  0xA2,  0x8A,  0x28,  0xC4,  0x88,  0x4A,  0x88,  0xA9,  0x06,  0xA3,  0x01,  0x0E,  0xFE, 	/* 1CE30 */
+	0xA1,  0x0A,  0xFE,  0xC9,  0x2A,  0xFE,  0xA9,  0x2A,  0xFE,  0xE1,  0x09,  0xFF,  0x81,  0x08,  0x10,  0xA4, 	/* 1CE40 */
+	0x02,  0x0E,  0x30,  0xA4,  0x8A,  0x84,  0xDF,  0xAA,  0x20,  0x9F,  0xE9,  0x20,  0xEA,  0x88,  0xA4,  0x92, 	/* 1CE50 */
+	0x28,  0x60,  0xA5,  0x02,  0x0E,  0x3C,  0xA4,  0x4A,  0x88,  0xC1,  0x0A,  0xBE,  0xAA,  0x2A,  0xA2,  0xAB, 	/* 1CE60 */
+	0xEC,  0xA2,  0x8A,  0x28,  0xBE,  0xA6,  0x02,  0x0F,  0xFE,  0xA2,  0x0A,  0xFC,  0xC2,  0x0B,  0xFE,  0xA4, 	/* 1CE70 */
+	0x8B,  0xFE,  0xEC,  0x88,  0xA8,  0x90,  0x88,  0x18,  0xAA,  0xE2,  0x0A,  0x20,  0xBF,  0xCC,  0x88,  0xA5, 	/* 1CE80 */
+	0x0B,  0xFE,  0xA0,  0x0A,  0xFC,  0xC8,  0x48,  0x84,  0x88,  0x48,  0xFC,  0xAC,  0x00,  0x0F,  0xFE,  0xAA, 	/* 1CE90 */
+	0x0A,  0xBE,  0xCE,  0x2A,  0xAA,  0xAE,  0xAA,  0xA4,  0xEA,  0x48,  0xEA,  0x93,  0x28,  0x20,  0xB0,  0x02, 	/* 1CEA0 */
+	0x0E,  0x30,  0xA4,  0x8A,  0xFC,  0xD0,  0x2A,  0xFC,  0xA1,  0x0B,  0xFE,  0xA2,  0x8C,  0x4C,  0x9F,  0x48, 	/* 1CEB0 */
+	0x04,  0xB2,  0xE1,  0x8A,  0xE0,  0xA2,  0x0F,  0xFC,  0xCA,  0x8A,  0xA8,  0xBF,  0xEA,  0xA8,  0xFF,  0xC8, 	/* 1CEC0 */
+	0x20,  0x82,  0x0B,  0xFE,  0xB3,  0x02,  0x0F,  0xFE,  0xA2,  0x0B,  0xFC,  0xD2,  0x4B,  0xFC,  0xB2,  0x4B, 	/* 1CED0 */
+	0xFC,  0xE7,  0x08,  0xA8,  0xB2,  0x68,  0x20,  0xB5,  0xE1,  0x0A,  0xFC,  0xC1,  0x09,  0xFE,  0xC2,  0x8A, 	/* 1CEE0 */
+	0xCE,  0xA2,  0x0A,  0x3C,  0xAC,  0x4C,  0x38,  0x86,  0x89,  0x86,  0xB6,  0x04,  0x0E,  0x40,  0xAF,  0xEA, 	/* 1CEF0 */
+	0x82,  0xDF,  0xAA,  0xA2,  0xBF,  0xAA,  0x22,  0xAA,  0xAE,  0xFA,  0x88,  0x28,  0x0C,  0xB7,  0x02,  0x0E, 	/* 1CF00 */
+	0x3E,  0xA2,  0x2A,  0x42,  0xC8,  0xCA,  0x10,  0x96,  0xE9,  0x42,  0xE6,  0xE8,  0x42,  0x84,  0x28,  0x7E, 	/* 1CF10 */
+	0xB8,  0x01,  0x0E,  0xFC,  0xA1,  0x0B,  0xFE,  0xC2,  0x8A,  0x48,  0xB8,  0xEA,  0x10,  0xCF,  0xC8,  0x10, 	/* 1CF20 */
+	0x81,  0x09,  0xFE,  0xBA,  0xE2,  0x0A,  0x50,  0xA8,  0x8B,  0xF6,  0xC2,  0x0B,  0xFC,  0xB2,  0x4B,  0xFC, 	/* 1CF30 */
+	0xC2,  0x08,  0x50,  0x88,  0x89,  0x04,  0xBD,  0x00,  0x0E,  0x7C,  0xA4,  0x4A,  0x7C,  0xC4,  0x4B,  0xFF, 	/* 1CF40 */
+	0xA4,  0x0A,  0xFE,  0xB2,  0xAE,  0xD2,  0x82,  0x28,  0xCC,  0x85,  0x00,  0x0E,  0xFC,  0xAA,  0x4A,  0xFC, 	/* 1CF50 */
+	0xCA,  0x4A,  0xFC,  0xA2,  0x0B,  0xFE,  0xB2,  0xAD,  0x3A,  0x9C,  0xA9,  0x06,  0x86,  0x04,  0x0E,  0x7C, 	/* 1CF60 */
+	0xAC,  0x8B,  0x30,  0xCC,  0x8B,  0x16,  0xA9,  0x0A,  0xFC,  0xE9,  0x09,  0x7C,  0x81,  0x08,  0xFE,  0x88, 	/* 1CF70 */
+	0x00,  0x0E,  0xFC,  0xAA,  0x4A,  0xFC,  0xCA,  0x4A,  0xFC,  0xA0,  0x0B,  0xFE,  0xAA,  0x4C,  0x98,  0x8A, 	/* 1CF80 */
+	0x49,  0xC2,  0x8A,  0x04,  0x4E,  0x28,  0xAF,  0xEA,  0x20,  0xC6,  0x4B,  0xB4,  0xA5,  0x8B,  0xB8,  0xC5, 	/* 1CF90 */
+	0x49,  0x92,  0x81,  0x08,  0x60,  0x8B,  0x02,  0x0E,  0xFE,  0xA2,  0x0A,  0x7C,  0xC9,  0x0B,  0x7E,  0x94, 	/* 1CFA0 */
+	0x49,  0x7C,  0x94,  0x4E,  0x7C,  0x84,  0x48,  0x4C,  0x8D,  0x02,  0x0E,  0xFC,  0xA8,  0x4A,  0xFC,  0xC8, 	/* 1CFB0 */
+	0x4A,  0xFC,  0xA0,  0x0B,  0xFE,  0xE1,  0x08,  0xFC,  0x81,  0x09,  0xFE,  0x8E,  0x09,  0x0E,  0x92,  0xAF, 	/* 1CFC0 */
+	0xCA,  0x90,  0xC9,  0x2A,  0xCE,  0xB2,  0x0A,  0xFC,  0xE8,  0x48,  0xFC,  0x88,  0x48,  0xFC,  0x8F,  0x02, 	/* 1CFD0 */
+	0x0E,  0x7C,  0xB2,  0x0A,  0xBC,  0xC2,  0x4B,  0xFC,  0xAE,  0x4A,  0xBC,  0xEA,  0x48,  0xAC,  0x94,  0x0A, 	/* 1CFE0 */
+	0x3E,  0x94,  0xEF,  0xEA,  0x00,  0xAF,  0xCC,  0x84,  0xAF,  0xCA,  0x00,  0xAF,  0xEA,  0xAA,  0xEC,  0xE8, 	/* 1CFF0 */
+	0xBA,  0x89,  0x28,  0x96,  0x95,  0xEF,  0xCA,  0x84,  0xAF,  0xCA,  0x00,  0xCF,  0xCA,  0x84,  0xAF,  0xCA, 	/* 1D000 */
+	0x84,  0xEF,  0xC8,  0x84,  0x8F,  0xC9,  0x86,  0x97,  0x02,  0x0E,  0x40,  0xAF,  0xCA,  0xA4,  0xCF,  0xCA, 	/* 1D010 */
+	0xA4,  0xAF,  0xCA,  0x54,  0xE5,  0xA8,  0x5E,  0x89,  0x19,  0x0F,  0x98,  0x07,  0x8E,  0x48,  0xA8,  0x4B, 	/* 1D020 */
+	0x7A,  0xC0,  0x0A,  0x78,  0xA4,  0x8A,  0x84,  0xFF,  0xEA,  0xB5,  0x8B,  0x49,  0xFE,  0x99,  0x01,  0x0E, 	/* 1D030 */
+	0x54,  0xA9,  0x2A,  0xFC,  0xC8,  0x4A,  0xFC,  0xA8,  0x4A,  0xFC,  0xC5,  0x48,  0x92,  0x91,  0x28,  0x30, 	/* 1D040 */
+	0x9B,  0x08,  0x0E,  0xFC,  0xAA,  0x4B,  0x58,  0xC9,  0x4A,  0xFA,  0xB0,  0x1B,  0xFC,  0xA2,  0x8E,  0xA4, 	/* 1D050 */
+	0x92,  0x28,  0x60,  0x9C,  0x02,  0x0E,  0xFC,  0xA4,  0x8B,  0xFE,  0xC8,  0x4A,  0xFC,  0xA8,  0x4A,  0xFC, 	/* 1D060 */
+	0xC2,  0x0B,  0xFE,  0x82,  0x08,  0x20,  0xA0,  0xE3,  0xCB,  0xE4,  0xAA,  0x8D,  0xFC,  0xC0,  0x4A,  0xFC, 	/* 1D070 */
+	0xA0,  0x4B,  0xFC,  0xC5,  0x49,  0x4A,  0xA4,  0x2A,  0x3E,  0xA3,  0x09,  0x2E,  0x54,  0xAF,  0xEA,  0x38, 	/* 1D080 */
+	0xC5,  0x4B,  0x92,  0xA4,  0x4A,  0x7E,  0xAB,  0x4F,  0x7E,  0x84,  0x49,  0x84,  0xA7,  0x13,  0xCE,  0xA4, 	/* 1D090 */
+	0xA4,  0x2B,  0x7E,  0xC9,  0x0A,  0x6A,  0xB9,  0xCA,  0xEC,  0xE9,  0xA8,  0xAA,  0x8D,  0x89,  0x3F,  0xA8, 	/* 1D0A0 */
+	0x09,  0x0E,  0x7E,  0xB1,  0x0A,  0x9E,  0xC2,  0x4B,  0xDE,  0xA9,  0x2A,  0x9E,  0xA9,  0x2C,  0x96,  0x94, 	/* 1D0B0 */
+	0x0A,  0x3F,  0xAA,  0x02,  0x0E,  0x50,  0xA8,  0x8B,  0x76,  0xC0,  0x0B,  0xDC,  0xB5,  0x4B,  0xDC,  0xE8, 	/* 1D0C0 */
+	0x88,  0x88,  0x95,  0x4A,  0x22,  0xB0,  0x00,  0x0E,  0xFC,  0xA8,  0x4A,  0xFC,  0xC8,  0x4A,  0xFC,  0xA4, 	/* 1D0D0 */
+	0x4A,  0xAA,  0xE4,  0x49,  0xEE,  0x8D,  0x49,  0x2A,  0xB1,  0x01,  0xCE,  0xE8,  0xAA,  0x4B,  0xFA,  0xC1, 	/* 1D0E0 */
+	0x0A,  0xFC,  0xBF,  0xEA,  0x04,  0xEF,  0xC9,  0x54,  0x95,  0x2A,  0x3C,  0xB2,  0x01,  0x0E,  0x54,  0xA9, 	/* 1D0F0 */
+	0xAA,  0x30,  0xC6,  0x0B,  0xFC,  0xA9,  0x0A,  0xFC,  0xE9,  0x08,  0xFE,  0x8A,  0xA9,  0x0C,  0xB4,  0x04, 	/* 1D100 */
+	0x8F,  0xFE,  0xAA,  0x8B,  0xFE,  0xC0,  0x2A,  0xEE,  0xAA,  0x8A,  0xEE,  0xEA,  0x88,  0xEE,  0x8A,  0x88, 	/* 1D110 */
+	0xAE,  0xB6,  0x04,  0x00,  0x40,  0x3F,  0x80,  0x48,  0xFF,  0xE0,  0x48,  0x3F,  0x84,  0x44,  0x2E,  0x83, 	/* 1D120 */
+	0x50,  0xC4,  0xC0,  0xC0,  0xB7,  0x20,  0x8F,  0xBE,  0x20,  0xAF,  0xFF,  0x00,  0xA7,  0x3E,  0xF8,  0x82, 	/* 1D130 */
+	0x2A,  0xA9,  0xCA,  0xAA,  0x24,  0x96,  0x18,  0xB8,  0x20,  0x8F,  0xBE,  0x20,  0xA7,  0x7F,  0xA8,  0xAF, 	/* 1D140 */
+	0x3E,  0x04,  0x9F,  0x2A,  0x21,  0xCA,  0xAA,  0xAC,  0x96,  0x08,  0xB9,  0x21,  0x02,  0x20,  0x3F,  0xE6, 	/* 1D150 */
+	0x20,  0x62,  0x0B,  0xFC,  0x22,  0x02,  0x20,  0x3F,  0xC2,  0x20,  0x22,  0x03,  0xFE,  0xBB,  0x11,  0x01, 	/* 1D160 */
+	0x20,  0x3F,  0xE6,  0x20,  0xBF,  0xC2,  0x20,  0x3F,  0xE0,  0x00,  0x7F,  0xC1,  0x88,  0x07,  0x07,  0x8E, 	/* 1D170 */
+	0xBC,  0x21,  0x02,  0x20,  0x3F,  0xE6,  0x20,  0xBF,  0xC2,  0x20,  0x3F,  0xE0,  0x20,  0xFF,  0xF0,  0x20, 	/* 1D180 */
+	0x02,  0x00,  0x20,  0x80,  0x04,  0x01,  0x50,  0x24,  0x8C,  0xD6,  0x06,  0x01,  0x90,  0xFF,  0xE2,  0x20, 	/* 1D190 */
+	0x3F,  0xC2,  0x20,  0x22,  0x03,  0xFE,  0x81,  0x00,  0x07,  0xFE,  0x4A,  0x44,  0xBE,  0x56,  0x85,  0x68, 	/* 1D1A0 */
+	0x73,  0xE5,  0x28,  0x53,  0xE9,  0x28,  0x92,  0x81,  0x3E,  0x84,  0x21,  0x42,  0x24,  0xFF,  0xE2,  0x68, 	/* 1D1B0 */
+	0x2A,  0x83,  0x3E,  0x32,  0x85,  0x28,  0x5B,  0xEA,  0x68,  0x3E,  0x8E,  0x3E,  0x85,  0x02,  0x4F,  0xA8, 	/* 1D1C0 */
+	0x57,  0xE5,  0x48,  0xFC,  0x81,  0x7C,  0x34,  0x83,  0x48,  0x57,  0xC9,  0x48,  0x14,  0x83,  0x7E,  0x86, 	/* 1D1D0 */
+	0x22,  0x03,  0xFC,  0x64,  0x0B,  0xF8,  0x24,  0x03,  0xF8,  0x24,  0x0F,  0xFE,  0x0E,  0x03,  0x58,  0xC4, 	/* 1D1E0 */
+	0x60,  0x40,  0x87,  0x00,  0x07,  0xFE,  0x00,  0x03,  0xFC,  0x20,  0x43,  0xFC,  0x28,  0x83,  0xFE,  0x69, 	/* 1D1F0 */
+	0x04,  0xFC,  0x49,  0x08,  0xFE,  0x89,  0x42,  0x44,  0x28,  0x77,  0xEA,  0xC8,  0xA4,  0x8F,  0xFC,  0x24, 	/* 1D200 */
+	0x82,  0x48,  0x37,  0xC4,  0xC8,  0x44,  0x88,  0x7E,  0x8B,  0x21,  0x02,  0x20,  0x3F,  0xE6,  0x20,  0xBF, 	/* 1D210 */
+	0x82,  0x20,  0x3F,  0xE0,  0x00,  0x7B,  0xC4,  0xA4,  0x4E,  0x44,  0x0C,  0x8C,  0x29,  0x22,  0x94,  0x2B, 	/* 1D220 */
+	0xE3,  0xE8,  0xAA,  0x8A,  0xBE,  0xAA,  0x8A,  0xA8,  0xAB,  0xEA,  0xE8,  0xB2,  0x8C,  0x3E,  0x8D,  0x04, 	/* 1D230 */
+	0x0F,  0xFE,  0x22,  0x42,  0x28,  0xC7,  0xE5,  0xC8,  0x27,  0xC4,  0xC8,  0xFF,  0xC1,  0x48,  0x24,  0x84, 	/* 1D240 */
+	0x7E,  0x8E,  0x01,  0x27,  0xA4,  0x4B,  0xE4,  0xE8,  0x7A,  0x84,  0xBE,  0x7A,  0x84,  0xA8,  0x4B,  0xE5, 	/* 1D250 */
+	0xE8,  0x62,  0x8C,  0x3E,  0x91,  0x42,  0x4F,  0x28,  0x57,  0xE5,  0x48,  0x9C,  0x82,  0x7C,  0xFC,  0x82, 	/* 1D260 */
+	0x48,  0x77,  0xCA,  0xC8,  0x24,  0x82,  0x7E,  0x95,  0xFA,  0x48,  0xA8,  0xAB,  0xEF,  0xE8,  0xAA,  0x8F, 	/* 1D270 */
+	0xBC,  0xAA,  0x8F,  0xA8,  0xDB,  0xCF,  0xA8,  0x8A,  0x89,  0xBE,  0x96,  0x79,  0x44,  0x94,  0x7B,  0xE2, 	/* 1D280 */
+	0x68,  0xFA,  0x8A,  0xBC,  0xAA,  0x8F,  0xA8,  0x33,  0xC2,  0xA8,  0x3A,  0x8C,  0x7E,  0x99,  0x25,  0x22, 	/* 1D290 */
+	0x94,  0x7F,  0xED,  0x28,  0x7B,  0xC5,  0x28,  0x7F,  0xE0,  0x00,  0x7F,  0xC1,  0x98,  0x06,  0x07,  0x9E, 	/* 1D2A0 */
+	0x9B,  0x41,  0x47,  0x94,  0x6B,  0xEB,  0xA8,  0x2E,  0x85,  0xBC,  0x42,  0x87,  0xA8,  0x6B,  0xCB,  0xA8, 	/* 1D2B0 */
+	0x2A,  0x85,  0xBE,  0x9C,  0x21,  0x42,  0x14,  0xFB,  0xE5,  0x68,  0x52,  0x8A,  0xBE,  0x22,  0x8F,  0xA8, 	/* 1D2C0 */
+	0x33,  0xE6,  0xA8,  0xA2,  0x82,  0x3E,  0xA2,  0x22,  0x4F,  0xE8,  0xDB,  0xEA,  0xE8,  0xDA,  0x8F,  0xBC, 	/* 1D2D0 */
+	0x22,  0x8F,  0xA8,  0xAB,  0xCD,  0xA8,  0xFA,  0x88,  0xBE,  0xA3,  0x51,  0x2F,  0xA4,  0x53,  0xEF,  0xE8, 	/* 1D2E0 */
+	0xAA,  0x8F,  0xBE,  0x22,  0x8F,  0xA8,  0x23,  0xEF,  0xE8,  0x4A,  0x88,  0x3E,  0xA8,  0x00,  0x07,  0xFE, 	/* 1D2F0 */
+	0x04,  0x00,  0x40,  0x7F,  0xE6,  0x52,  0x54,  0xA4,  0x42,  0x65,  0x25,  0x4A,  0x44,  0x24,  0x46,  0xAA, 	/* 1D300 */
+	0x7F,  0xC0,  0x40,  0xFF,  0xEB,  0x5A,  0x84,  0x2B,  0x5A,  0x00,  0x03,  0xF8,  0x00,  0x83,  0xF8,  0x00, 	/* 1D310 */
+	0x83,  0xF8,  0xAB,  0x3F,  0x80,  0x40,  0xFF,  0xE8,  0x42,  0xA5,  0x29,  0x4A,  0x00,  0x0F,  0xFE,  0x06, 	/* 1D320 */
+	0x00,  0x50,  0x04,  0x80,  0x40,  0xB0,  0x3F,  0xC0,  0x40,  0xFF,  0xEB,  0x5A,  0x84,  0x23,  0x58,  0x0A, 	/* 1D330 */
+	0x03,  0x18,  0xDF,  0x60,  0x90,  0x11,  0x02,  0x60,  0xB2,  0x7F,  0xC0,  0x40,  0xFF,  0xE8,  0x42,  0xB5, 	/* 1D340 */
+	0xA0,  0x40,  0x3F,  0x80,  0x00,  0xFF,  0xE0,  0x90,  0x13,  0x87,  0xC4,  0xB6,  0x7F,  0xC0,  0x40,  0xFF, 	/* 1D350 */
+	0xE8,  0x42,  0xB5,  0xA0,  0xA0,  0x3F,  0x8C,  0x06,  0x7F,  0x80,  0x48,  0x05,  0x80,  0x40,  0xB7,  0x7F, 	/* 1D360 */
+	0xC0,  0x40,  0xFF,  0xEB,  0x5A,  0x84,  0x2B,  0x5A,  0x04,  0x07,  0xFC,  0x44,  0x47,  0xFC,  0x44,  0x47, 	/* 1D370 */
+	0xFC,  0xB9,  0x7F,  0xC0,  0x40,  0xFF,  0xE8,  0x42,  0xB5,  0xA2,  0x40,  0x3F,  0xC3,  0xE4,  0x62,  0x4B, 	/* 1D380 */
+	0xE8,  0x20,  0x21,  0xFE,  0xBB,  0x7F,  0xC0,  0x40,  0xFF,  0xEA,  0x52,  0x94,  0xAF,  0xF8,  0x44,  0x87, 	/* 1D390 */
+	0xF8,  0x44,  0x87,  0xFA,  0x04,  0x20,  0x3E,  0x80,  0x7F,  0xC0,  0x40,  0xFF,  0xE8,  0x42,  0xB5,  0xA0, 	/* 1D3A0 */
+	0x00,  0xFF,  0xE1,  0x00,  0x7F,  0xC4,  0xA4,  0x4A,  0x44,  0xAC,  0x84,  0x7F,  0xC0,  0x40,  0xFF,  0xEA, 	/* 1D3B0 */
+	0x52,  0x94,  0xA3,  0xF8,  0x60,  0xCB,  0xFA,  0x20,  0x83,  0xF8,  0x20,  0x82,  0x18,  0x86,  0x7F,  0xC0, 	/* 1D3C0 */
+	0x40,  0xFF,  0xE9,  0x4A,  0x25,  0x2F,  0x78,  0x21,  0x07,  0xFE,  0xD1,  0x03,  0x7C,  0x2C,  0x0C,  0x3E, 	/* 1D3D0 */
+	0x87,  0x7F,  0xC0,  0x40,  0xFF,  0xE8,  0x42,  0xB5,  0xA0,  0x00,  0x7F,  0xE4,  0x00,  0x7F,  0xC5,  0x48, 	/* 1D3E0 */
+	0x53,  0x0B,  0x8C,  0x88,  0x7F,  0xC0,  0x40,  0xFF,  0xE8,  0x42,  0xB5,  0xA2,  0x20,  0x9F,  0xE4,  0x20, 	/* 1D3F0 */
+	0x0F,  0xC2,  0xA4,  0x4B,  0x88,  0x20,  0x8A,  0x7F,  0xC0,  0x40,  0xFF,  0xE8,  0x42,  0xB5,  0xA7,  0xFC, 	/* 1D400 */
+	0x00,  0x07,  0xFC,  0x0A,  0x02,  0xA8,  0x1B,  0x0F,  0xFE,  0x8D,  0x7F,  0xC0,  0x40,  0xFF,  0xE8,  0x42, 	/* 1D410 */
+	0xB5,  0xA8,  0x42,  0x12,  0x03,  0xFC,  0xE4,  0x03,  0xF8,  0x24,  0x03,  0xFE,  0x8E,  0x7F,  0xC0,  0x40, 	/* 1D420 */
+	0xFF,  0xE8,  0x42,  0xB5,  0xA0,  0x40,  0x7F,  0x81,  0x20,  0xFF,  0xE3,  0x10,  0x0E,  0x07,  0x18,  0x8F, 	/* 1D430 */
+	0x7F,  0xC0,  0x40,  0xFF,  0xE8,  0x42,  0xB5,  0xA0,  0xA0,  0x7B,  0xC0,  0xA0,  0x7B,  0xC0,  0xA0,  0xF3, 	/* 1D440 */
+	0xE2,  0x20,  0x91,  0x7F,  0xC0,  0x40,  0xFF,  0xE8,  0x42,  0xB5,  0xA2,  0x10,  0x91,  0xE4,  0x10,  0x07, 	/* 1D450 */
+	0xC2,  0x44,  0x44,  0x48,  0x7C,  0x93,  0x7F,  0xC0,  0x40,  0xFF,  0xE8,  0x42,  0xB5,  0xA2,  0x08,  0x3B, 	/* 1D460 */
+	0x82,  0x08,  0x3F,  0x80,  0xA2,  0x32,  0x2C,  0x1E,  0x96,  0x7F,  0xC0,  0x40,  0xFF,  0xE8,  0x42,  0xB5, 	/* 1D470 */
+	0xA2,  0x10,  0xFF,  0xC2,  0x10,  0x73,  0x86,  0xD4,  0xA1,  0x22,  0x10,  0x99,  0x7F,  0xC0,  0x40,  0xFF, 	/* 1D480 */
+	0xEA,  0x52,  0x14,  0x8F,  0xFE,  0x15,  0x03,  0xF8,  0x24,  0x8F,  0xFE,  0x1B,  0x0E,  0x0E,  0x9C,  0x7F, 	/* 1D490 */
+	0xC0,  0x40,  0xFF,  0xE8,  0x42,  0xB5,  0xA2,  0x7C,  0xFC,  0x42,  0x7C,  0x74,  0x46,  0xFC,  0xA4,  0x42, 	/* 1D4A0 */
+	0x7C,  0x9E,  0x7F,  0xC0,  0x40,  0xFF,  0xE8,  0x42,  0xB5,  0xA0,  0x00,  0x7B,  0xC4,  0x84,  0x7B,  0xC4, 	/* 1D4B0 */
+	0x14,  0x78,  0x84,  0x36,  0xA4,  0x7F,  0xC0,  0x40,  0xFF,  0xE8,  0x42,  0xB5,  0xA3,  0xBC,  0x51,  0x4F, 	/* 1D4C0 */
+	0xF4,  0x24,  0x83,  0xF8,  0x24,  0x83,  0xF8,  0xA7,  0x7F,  0xC0,  0x40,  0xFF,  0xEA,  0x52,  0x94,  0xA7, 	/* 1D4D0 */
+	0xBE,  0x4A,  0x83,  0x56,  0xF9,  0x03,  0x7C,  0x51,  0x49,  0x6C,  0xAA,  0x7F,  0xC0,  0x40,  0xFF,  0xE8, 	/* 1D4E0 */
+	0x42,  0xB5,  0xA4,  0x00,  0x2F,  0xE8,  0x54,  0x49,  0x22,  0xFE,  0x41,  0x08,  0xFE,  0xB0,  0x7F,  0xC0, 	/* 1D4F0 */
+	0x40,  0xFF,  0xE8,  0x42,  0xB5,  0xAF,  0xD0,  0x49,  0xEF,  0xE4,  0x4A,  0x47,  0x98,  0x49,  0x45,  0xA2, 	/* 1D500 */
+	0xB2,  0x7F,  0xC0,  0x40,  0xFF,  0xEA,  0x52,  0x94,  0xA7,  0x9C,  0x4A,  0x47,  0xD8,  0x3A,  0x4A,  0x7E, 	/* 1D510 */
+	0xBA,  0x4C,  0x3C,  0xB8,  0x7F,  0xC0,  0x40,  0xFF,  0xE8,  0x42,  0xB5,  0xA2,  0x9E,  0xFD,  0x22,  0x9E, 	/* 1D520 */
+	0x7D,  0x25,  0x5E,  0xFF,  0x21,  0x26,  0xB9,  0x7F,  0xC0,  0x40,  0xFF,  0xE8,  0x42,  0xB5,  0xA7,  0x88, 	/* 1D530 */
+	0x4F,  0xC7,  0xA8,  0x47,  0xE7,  0x90,  0xCF,  0xC7,  0x90,  0xBD,  0x7F,  0xC0,  0x40,  0xFF,  0xEB,  0x5A, 	/* 1D540 */
+	0x7F,  0xCF,  0xAE,  0x35,  0x85,  0x54,  0xBF,  0xA2,  0x08,  0x3F,  0x84,  0x08,  0xBE,  0x7F,  0xC0,  0x40, 	/* 1D550 */
+	0xFF,  0xEA,  0x52,  0x94,  0xA3,  0xFC,  0xD5,  0x47,  0x7C,  0x95,  0x43,  0x7C,  0xD1,  0x06,  0x7E,  0x82, 	/* 1D560 */
+	0x7F,  0xC0,  0x40,  0xFF,  0xE8,  0x42,  0xB5,  0xA3,  0xFC,  0x28,  0x83,  0xDE,  0x2A,  0xC5,  0xBA,  0x8A, 	/* 1D570 */
+	0x07,  0xFE,  0x84,  0x7F,  0xC0,  0x40,  0xFF,  0xEA,  0x52,  0x94,  0xA7,  0xBC,  0x02,  0x4F,  0xBE,  0x02, 	/* 1D580 */
+	0xA7,  0xDE,  0x48,  0x27,  0x8C,  0x86,  0xF8,  0x82,  0x3E,  0xFC,  0xAA,  0xBF,  0xAC,  0xA0,  0x3E,  0x7C, 	/* 1D590 */
+	0x80,  0x6A,  0xFD,  0xC5,  0x6A,  0x76,  0x8C,  0x9F,  0x88,  0x7F,  0xC0,  0x40,  0xFF,  0xE8,  0x42,  0xB5, 	/* 1D5A0 */
+	0xA0,  0x00,  0xEE,  0xEA,  0xAA,  0xFF,  0xE2,  0x48,  0x55,  0x4F,  0xFE,  0x89,  0xF8,  0x62,  0x7A,  0xFD, 	/* 1D5B0 */
+	0x4A,  0xFE,  0xAB,  0x60,  0x6A,  0xFB,  0xE0,  0x1C,  0xFE,  0x45,  0x18,  0x6A,  0x4C,  0xC2,  0x92,  0x04, 	/* 1D5C0 */
+	0x07,  0xFC,  0x04,  0x03,  0xF8,  0x04,  0x0F,  0xFE,  0x10,  0x81,  0xF8,  0x10,  0x81,  0xF8,  0x10,  0x81, 	/* 1D5D0 */
+	0x18,  0x96,  0x21,  0x02,  0x7E,  0xF9,  0x01,  0x7C,  0x91,  0x05,  0xFE,  0x54,  0x42,  0x7C,  0x3C,  0x4C, 	/* 1D5E0 */
+	0x7C,  0x04,  0x40,  0x4C,  0x99,  0x21,  0xCF,  0x94,  0x22,  0x87,  0xFE,  0x20,  0xAF,  0xFF,  0x48,  0xA7, 	/* 1D5F0 */
+	0x8A,  0x4B,  0xE7,  0x88,  0x48,  0x85,  0x98,  0x9C,  0x10,  0xCF,  0xF0,  0x15,  0x47,  0x92,  0x17,  0xCF, 	/* 1D600 */
+	0xD4,  0x57,  0xE5,  0x54,  0x7F,  0xC4,  0x50,  0x45,  0x04,  0xD0,  0x9E,  0x12,  0x01,  0x20,  0xF3,  0xE1, 	/* 1D610 */
+	0x20,  0x12,  0x0F,  0x3C,  0x12,  0x01,  0x20,  0xF3,  0xE1,  0x20,  0x22,  0x04,  0x20,  0xA0,  0x24,  0x03, 	/* 1D620 */
+	0xF8,  0x44,  0x0F,  0xFE,  0x20,  0x83,  0xF8,  0x0A,  0x0F,  0xBE,  0x0A,  0x0F,  0xBE,  0x12,  0x06,  0x20, 	/* 1D630 */
+	0xA1,  0x02,  0x07,  0xFE,  0x48,  0x87,  0xFE,  0x48,  0x86,  0xAA,  0x6A,  0xA5,  0xD0,  0x45,  0xE5,  0xD0, 	/* 1D640 */
+	0x85,  0xE1,  0x90,  0xA2,  0x00,  0x0F,  0xFE,  0x04,  0x00,  0x80,  0x7F,  0xE4,  0x92,  0x4F,  0x24,  0x92, 	/* 1D650 */
+	0x4F,  0x24,  0x92,  0x49,  0x27,  0xFE,  0xA4,  0x01,  0x0F,  0xD0,  0x21,  0xE4,  0x22,  0xFF,  0xAA,  0xAA, 	/* 1D660 */
+	0xBA,  0xAA,  0xBC,  0xBA,  0x0A,  0xA2,  0xAA,  0x2F,  0x9E,  0xA6,  0x00,  0x0F,  0xBC,  0x22,  0x44,  0x3C, 	/* 1D670 */
+	0xFA,  0x4A,  0xBC,  0xBA,  0x4A,  0xBC,  0xB9,  0x8A,  0x9A,  0xAA,  0xAF,  0xC6,  0xA8,  0x7F,  0xE5,  0x4C, 	/* 1D680 */
+	0x5F,  0xE5,  0x48,  0x9D,  0x41,  0x62,  0xFF,  0xE0,  0x80,  0x7F,  0xE4,  0xF2,  0x49,  0x27,  0xFE,  0xA9, 	/* 1D690 */
+	0x11,  0x0F,  0xFE,  0x11,  0x01,  0xF0,  0x04,  0x07,  0xFC,  0x44,  0x47,  0xFC,  0x04,  0x0F,  0xFE,  0x04, 	/* 1D6A0 */
+	0x00,  0x40,  0xAB,  0x50,  0x0F,  0xFE,  0x51,  0x27,  0x2A,  0x22,  0x4F,  0x94,  0xA9,  0x8F,  0x88,  0x21, 	/* 1D6B0 */
+	0x8F,  0xA4,  0x24,  0x42,  0x82,  0xAD,  0x50,  0x0F,  0xBE,  0x51,  0x27,  0x12,  0x21,  0x2F,  0xB2,  0xA9, 	/* 1D6C0 */
+	0xAF,  0x92,  0x21,  0x2F,  0xA2,  0x22,  0x22,  0x4C,  0xB1,  0x50,  0x0F,  0xFE,  0x51,  0x27,  0x12,  0x25, 	/* 1D6D0 */
+	0x2F,  0xB2,  0xA9,  0xAF,  0x96,  0x21,  0x2F,  0xA2,  0x24,  0x22,  0x8C,  0xB4,  0x52,  0x8F,  0xA8,  0x52, 	/* 1D6E0 */
+	0x87,  0x4A,  0x2A,  0xAF,  0xAC,  0xAA,  0x8F,  0xA8,  0x22,  0x8F,  0xAA,  0x22,  0xA2,  0x26,  0xB9,  0x53, 	/* 1D6F0 */
+	0x0F,  0x90,  0x51,  0x07,  0x7E,  0x25,  0x2F,  0xD2,  0xAD,  0x2F,  0xEA,  0x24,  0x6F,  0xC2,  0x24,  0x22, 	/* 1D700 */
+	0x46,  0xBA,  0x51,  0x0F,  0x90,  0x5F,  0xE7,  0x10,  0x21,  0x0F,  0xFC,  0xA9,  0x0F,  0xB8,  0x23,  0x8F, 	/* 1D710 */
+	0xD4,  0x29,  0x22,  0x10,  0xBC,  0x50,  0x0F,  0xBC,  0x52,  0x47,  0x24,  0x23,  0xCF,  0xA4,  0xAA,  0x4F, 	/* 1D720 */
+	0xA4,  0x23,  0xCF,  0xC0,  0x20,  0x02,  0x7E,  0x81,  0x51,  0x0F,  0x90,  0x57,  0xF7,  0x52,  0x25,  0x4F, 	/* 1D730 */
+	0xFE,  0xAC,  0x2F,  0xE4,  0x25,  0x4F,  0xC8,  0x29,  0x42,  0xA2,  0x84,  0x52,  0x0F,  0xA0,  0x53,  0xE7, 	/* 1D740 */
+	0x42,  0x2B,  0xAF,  0x8A,  0xA8,  0xAF,  0xBA,  0x22,  0xCF,  0xA0,  0x22,  0x22,  0x1E,  0x85,  0x50,  0x8F, 	/* 1D750 */
+	0x88,  0x50,  0x87,  0x3E,  0x22,  0xAF,  0xAA,  0xAF,  0xFF,  0x88,  0x21,  0x8F,  0x94,  0x22,  0x22,  0x41, 	/* 1D760 */
+	0x86,  0x50,  0x0F,  0xFE,  0x51,  0x07,  0x10,  0x27,  0xEF,  0xD2,  0xAD,  0x2F,  0xDA,  0x26,  0x6F,  0xC2, 	/* 1D770 */
+	0x24,  0x22,  0x46,  0x8B,  0x51,  0x0F,  0x90,  0x57,  0xC7,  0x10,  0x21,  0x0F,  0xFE,  0xA9,  0x0F,  0x90, 	/* 1D780 */
+	0x27,  0xCF,  0x90,  0x21,  0x02,  0xFE,  0x8D,  0x51,  0x0F,  0xFE,  0x5A,  0x27,  0x20,  0x2F,  0xFF,  0xA4, 	/* 1D790 */
+	0xAA,  0x4F,  0xA4,  0x26,  0x8F,  0x98,  0x22,  0x42,  0x42,  0x8F,  0x07,  0x8F,  0xC8,  0x26,  0x83,  0x5A, 	/* 1D7A0 */
+	0xC8,  0xE1,  0x10,  0xFF,  0xE1,  0x10,  0x3F,  0x82,  0x48,  0xFF,  0xE0,  0x40,  0x90,  0x51,  0x0F,  0x90, 	/* 1D7B0 */
+	0x51,  0xC7,  0x10,  0x27,  0xEF,  0x80,  0xAF,  0xEF,  0x98,  0x21,  0x4F,  0xD2,  0x21,  0x02,  0x10,  0x98, 	/* 1D7C0 */
+	0x54,  0xAF,  0xAA,  0x52,  0xC7,  0x08,  0x23,  0xEF,  0xA2,  0xAB,  0xEF,  0xA2,  0x23,  0xEF,  0xA2,  0x22, 	/* 1D7D0 */
+	0x22,  0x26,  0x9C,  0x51,  0x0F,  0x92,  0x57,  0x47,  0x38,  0x25,  0x4F,  0x92,  0xA9,  0x0F,  0xFC,  0x24, 	/* 1D7E0 */
+	0x4F,  0xFC,  0x24,  0x42,  0x7C,  0xA0,  0x52,  0x0F,  0xA0,  0x53,  0xE7,  0x52,  0x25,  0x6F,  0xBA,  0xAF, 	/* 1D7F0 */
+	0xEF,  0x92,  0x23,  0xAF,  0xD6,  0x21,  0x22,  0x0C,  0xA3,  0x53,  0xEF,  0x94,  0x50,  0x87,  0x7E,  0x21, 	/* 1D800 */
+	0xAF,  0xAC,  0xAC,  0x8F,  0xFE,  0x21,  0x8F,  0xB4,  0x25,  0x22,  0x10,  0xA6,  0x52,  0x8F,  0xC8,  0x54, 	/* 1D810 */
+	0xA7,  0xFA,  0x25,  0xCF,  0x58,  0xB6,  0x8F,  0xC8,  0x2C,  0xCF,  0x54,  0x26,  0x22,  0x41,  0xA8,  0x50, 	/* 1D820 */
+	0x0F,  0xFC,  0x54,  0x47,  0x7C,  0x24,  0x4F,  0xFC,  0xAA,  0x0F,  0xBE,  0x25,  0x2F,  0xEA,  0x27,  0xA2, 	/* 1D830 */
+	0x0C,  0xAB,  0x52,  0x0F,  0xA0,  0x53,  0xE7,  0x42,  0x2B,  0xAF,  0xFE,  0xA8,  0x2F,  0xBA,  0x23,  0xAF, 	/* 1D840 */
+	0xEA,  0x23,  0xA2,  0x0C,  0xAD,  0x50,  0x0F,  0xFE,  0x51,  0x07,  0x7E,  0x25,  0x2F,  0xFE,  0xAD,  0x2F, 	/* 1D850 */
+	0xFE,  0x21,  0x0F,  0xB0,  0x22,  0x82,  0xC6,  0xB3,  0x52,  0x8F,  0xFE,  0x52,  0x87,  0x10,  0x22,  0x8F, 	/* 1D860 */
+	0xC4,  0xAB,  0xAF,  0x81,  0x23,  0xCF,  0xA4,  0x22,  0x42,  0x3C,  0xB4,  0x52,  0x4F,  0xFE,  0x52,  0x47, 	/* 1D870 */
+	0x7E,  0x24,  0x0F,  0x7E,  0xB6,  0xAF,  0x7E,  0x2A,  0xAF,  0xBE,  0x32,  0xA2,  0x26,  0x83,  0x54,  0x8F, 	/* 1D880 */
+	0xBE,  0x50,  0x87,  0x7E,  0x22,  0x4F,  0xD8,  0xB7,  0xEF,  0x48,  0x27,  0xEF,  0x48,  0x2B,  0x03,  0x0F, 	/* 1D890 */
+	0x86,  0x53,  0xEF,  0x94,  0x53,  0xE7,  0xAA,  0x27,  0xEF,  0x1C,  0xBE,  0x6F,  0x5D,  0x25,  0x2F,  0x4E, 	/* 1D8A0 */
+	0x2A,  0x03,  0x1F,  0x88,  0x52,  0x4F,  0xFE,  0x52,  0x47,  0x7E,  0x25,  0xAF,  0xFE,  0xA8,  0x8F,  0xFE, 	/* 1D8B0 */
+	0x24,  0x8F,  0xEA,  0x25,  0x42,  0x8A,  0x8B,  0x04,  0x03,  0xF8,  0x04,  0x8F,  0xFE,  0x20,  0x83,  0xF8, 	/* 1D8C0 */
+	0x02,  0x03,  0xFC,  0x22,  0x0F,  0xFE,  0x02,  0x00,  0x20,  0x93,  0x20,  0x8F,  0xBE,  0x20,  0xAF,  0xFF, 	/* 1D8D0 */
+	0x8A,  0x2F,  0xBE,  0x88,  0x4F,  0xBE,  0x22,  0x4F,  0xFF,  0x20,  0x42,  0x04,  0x9C,  0x20,  0x6F,  0xB8, 	/* 1D8E0 */
+	0x2B,  0x4F,  0xD2,  0x49,  0x07,  0x88,  0x13,  0x6F,  0xA2,  0x53,  0x6F,  0xE2,  0x12,  0x21,  0x3E,  0xAD, 	/* 1D8F0 */
+	0x0A,  0x00,  0xA0,  0x7B,  0xC0,  0xA0,  0x0A,  0x07,  0xBC,  0x0A,  0x00,  0xA0,  0x7B,  0xC0,  0xA0,  0x0A, 	/* 1D900 */
+	0x0F,  0xFE,  0xAE,  0x11,  0x0F,  0xFE,  0x11,  0x00,  0x00,  0x0A,  0x07,  0xBC,  0x0A,  0x07,  0xBC,  0x0A, 	/* 1D910 */
+	0x07,  0xBC,  0x0A,  0x0F,  0xFE,  0xB2,  0x04,  0x0F,  0xFE,  0x0A,  0x4F,  0x58,  0x55,  0x4B,  0x5A,  0x0A, 	/* 1D920 */
+	0x07,  0xBC,  0x0A,  0x07,  0xBC,  0x0A,  0x0F,  0xFE,  0xB3,  0x04,  0x07,  0xFC,  0x11,  0x00,  0xA0,  0xFF, 	/* 1D930 */
+	0xE0,  0x00,  0x1F,  0x81,  0x08,  0x1F,  0x81,  0x08,  0x10,  0x81,  0xF8,  0xB5,  0x22,  0x02,  0x20,  0xFB, 	/* 1D940 */
+	0xE5,  0x22,  0x24,  0x2F,  0xB2,  0x00,  0x27,  0x8A,  0x4B,  0x27,  0xC2,  0x48,  0x27,  0x8C,  0xB6,  0x20, 	/* 1D950 */
+	0x02,  0x7E,  0xFD,  0x24,  0x92,  0x49,  0x2F,  0xEC,  0x04,  0x07,  0xBE,  0x4A,  0x27,  0xA2,  0x4A,  0x27, 	/* 1D960 */
+	0xBE,  0xBB,  0x23,  0xCF,  0xA4,  0x52,  0x45,  0x3E,  0xFA,  0x20,  0x3E,  0x7A,  0x24,  0xBE,  0x7A,  0x24, 	/* 1D970 */
+	0xBE,  0x79,  0x40,  0x62,  0xBF,  0x2E,  0xED,  0xAA,  0x6E,  0xCF,  0xCA,  0x2A,  0xA4,  0xDC,  0xFF,  0xE1, 	/* 1D980 */
+	0x10,  0xFF,  0xE3,  0xF8,  0x20,  0x83,  0xF8,  0x81,  0x00,  0x0F,  0xFE,  0x08,  0x03,  0xF8,  0x20,  0x83, 	/* 1D990 */
+	0xF8,  0x20,  0x83,  0xF8,  0x20,  0x83,  0xF8,  0x10,  0xCE,  0x02,  0x82,  0x00,  0x0F,  0xFE,  0x22,  0x02, 	/* 1D9A0 */
+	0x7C,  0x24,  0x42,  0x7C,  0x24,  0x42,  0x7C,  0x24,  0x42,  0x7C,  0x22,  0x46,  0xC2,  0x83,  0x00,  0x09, 	/* 1D9B0 */
+	0xFE,  0x81,  0x09,  0xFC,  0xE4,  0x48,  0x7C,  0x84,  0x49,  0x7C,  0x94,  0x47,  0x7C,  0x06,  0x41,  0x82, 	/* 1D9C0 */
+	0x85,  0x00,  0x00,  0xFE,  0xFA,  0x02,  0x7C,  0x24,  0x42,  0x7C,  0x24,  0x42,  0xFC,  0x34,  0x4C,  0x7C, 	/* 1D9D0 */
+	0x06,  0x41,  0x82,  0x86,  0x88,  0x08,  0xFF,  0xA9,  0x0A,  0xBE,  0xAA,  0x2A,  0xBE,  0xAA,  0x2A,  0xBE, 	/* 1D9E0 */
+	0xAA,  0x2A,  0xBE,  0x89,  0x28,  0xE1,  0x88,  0x20,  0x02,  0xFE,  0x42,  0x09,  0x7C,  0x14,  0x42,  0x7C, 	/* 1D9F0 */
+	0x44,  0x49,  0x7C,  0x14,  0x42,  0x7C,  0x42,  0x48,  0xC2,  0x8C,  0x00,  0x07,  0x7E,  0x11,  0x05,  0x7C, 	/* 1DA00 */
+	0x4C,  0x4A,  0x7C,  0xA4,  0x43,  0x7C,  0x54,  0x45,  0xFC,  0xEA,  0x40,  0xC2,  0x8F,  0x20,  0x02,  0xFE, 	/* 1DA10 */
+	0xFA,  0x00,  0x7C,  0x74,  0x45,  0x7C,  0x54,  0x45,  0x7C,  0x54,  0x45,  0xFC,  0x86,  0x41,  0x82,  0x90, 	/* 1DA20 */
+	0x00,  0x0F,  0xFF,  0x11,  0x05,  0x3E,  0x22,  0x2F,  0xBE,  0x2A,  0x23,  0x3E,  0x22,  0x22,  0x3E,  0x21, 	/* 1DA30 */
+	0x26,  0x61,  0x91,  0x00,  0x00,  0x7E,  0xF9,  0x00,  0x3E,  0x02,  0x2F,  0xFE,  0x52,  0x25,  0x7E,  0x52, 	/* 1DA40 */
+	0x25,  0xBE,  0x51,  0x48,  0x62,  0x92,  0x10,  0x05,  0x3E,  0x49,  0x04,  0xBE,  0x86,  0x2F,  0xBE,  0x2A, 	/* 1DA50 */
+	0x22,  0xBE,  0x2A,  0x24,  0xBE,  0x49,  0x4B,  0x62,  0x93,  0x20,  0x02,  0x7E,  0xF9,  0x02,  0x3E,  0xAA, 	/* 1DA60 */
+	0x2A,  0xBE,  0xFA,  0x2A,  0x3E,  0x2A,  0x23,  0x3E,  0x21,  0x40,  0x62,  0x97,  0x10,  0x07,  0xFE,  0x55, 	/* 1DA70 */
+	0x05,  0xBE,  0x52,  0x27,  0xFE,  0x46,  0x26,  0x7E,  0x5A,  0x25,  0xBE,  0xA5,  0x4C,  0x62,  0x98,  0x20, 	/* 1DA80 */
+	0x03,  0x7E,  0x29,  0x04,  0x7E,  0x7A,  0x28,  0x3E,  0xFA,  0x22,  0xBE,  0x2A,  0x23,  0xBE,  0x21,  0x42, 	/* 1DA90 */
+	0x62,  0x9A,  0x00,  0x0F,  0xBE,  0x09,  0x05,  0x3E,  0x32,  0x24,  0xBE,  0xA2,  0x27,  0xBE,  0x22,  0x22, 	/* 1DAA0 */
+	0xBE,  0x31,  0x4C,  0x62,  0xA1,  0x20,  0x02,  0x7E,  0xFD,  0x02,  0x3C,  0x22,  0x4F,  0xBC,  0x02,  0x47, 	/* 1DAB0 */
+	0xBC,  0x4A,  0x44,  0xBC,  0x79,  0x40,  0x62,  0xA4,  0x00,  0x0F,  0xFE,  0x91,  0x09,  0x3E,  0xBA,  0x2A, 	/* 1DAC0 */
+	0xBE,  0xAA,  0x2B,  0xBE,  0x92,  0x29,  0x3E,  0xFD,  0x40,  0x62,  0xAC,  0x20,  0x02,  0x7E,  0xF9,  0x02, 	/* 1DAD0 */
+	0xFE,  0xB4,  0x26,  0x7E,  0xFC,  0x22,  0x7E,  0x34,  0x24,  0xFE,  0x42,  0x48,  0xC2,  0xAD,  0x00,  0x0F, 	/* 1DAE0 */
+	0xFE,  0x01,  0x07,  0xBE,  0x4A,  0x24,  0xBE,  0x7A,  0x28,  0xBE,  0x4A,  0x25,  0x3E,  0x19,  0x4E,  0x62, 	/* 1DAF0 */
+	0xB4,  0x80,  0x0F,  0xBE,  0x81,  0x07,  0xBE,  0x02,  0x27,  0xBE,  0x02,  0x2F,  0xBE,  0x22,  0x2A,  0xBE, 	/* 1DB00 */
+	0xA9,  0x42,  0x62,  0xB7,  0x20,  0x03,  0x7E,  0x4A,  0x0B,  0x7C,  0x04,  0x4F,  0x7C,  0x14,  0x42,  0x7C, 	/* 1DB10 */
+	0x7C,  0x44,  0xFC,  0x4A,  0x47,  0xC2,  0xB8,  0x07,  0xEF,  0xC8,  0x55,  0x0A,  0xBE,  0xAA,  0x25,  0x7E, 	/* 1DB20 */
+	0xFA,  0x22,  0x3E,  0x22,  0x23,  0xBE,  0xE2,  0x40,  0x42,  0xBB,  0x10,  0x05,  0x3E,  0x5D,  0x05,  0x3E, 	/* 1DB30 */
+	0xFE,  0x22,  0x3E,  0xAA,  0x2A,  0x7E,  0xAA,  0x21,  0x3E,  0x21,  0x4C,  0x62,  0xBC,  0x20,  0x02,  0x7F, 	/* 1DB40 */
+	0xF9,  0x02,  0x3E,  0xFA,  0x2A,  0xBE,  0xAA,  0x2F,  0xBE,  0x32,  0x26,  0xBE,  0xA3,  0x22,  0xC1,  0xBD, 	/* 1DB50 */
+	0x18,  0x0E,  0x7E,  0x21,  0x0F,  0xBC,  0x32,  0x46,  0xBC,  0xA6,  0x47,  0x3C,  0x56,  0x45,  0xBC,  0x51, 	/* 1DB60 */
+	0x48,  0x62,  0x86,  0x00,  0x0F,  0xFE,  0xA9,  0x0F,  0xBE,  0xAA,  0x2F,  0xBE,  0x22,  0x2F,  0xFE,  0x32, 	/* 1DB70 */
+	0x26,  0xBE,  0xA1,  0x42,  0x62,  0x8B,  0x00,  0x0F,  0xFE,  0xA9,  0x0F,  0xBE,  0xAA,  0x2A,  0xBE,  0xFA, 	/* 1DB80 */
+	0x22,  0x3E,  0xAA,  0x2A,  0xBE,  0xA5,  0x41,  0xE2,  0x8C,  0x7F,  0xE4,  0x90,  0x7B,  0xE4,  0xA2,  0x7B, 	/* 1DB90 */
+	0xE0,  0x22,  0xFF,  0xE1,  0x22,  0x5F,  0xE7,  0x14,  0x5E,  0x28,  0x3F,  0x8D,  0x10,  0x0F,  0xFE,  0x85, 	/* 1DBA0 */
+	0x07,  0xBE,  0x4A,  0x25,  0x3E,  0xB2,  0x24,  0xBE,  0xFE,  0x24,  0xBE,  0x49,  0x47,  0xA2,  0x8E,  0x00, 	/* 1DBB0 */
+	0x0F,  0xFE,  0xA9,  0x0F,  0xBE,  0x02,  0x27,  0xBE,  0x02,  0x2F,  0xFE,  0x22,  0x27,  0xBE,  0x09,  0x23, 	/* 1DBC0 */
+	0x61,  0x8F,  0x20,  0x0F,  0xFF,  0x49,  0x03,  0x3E,  0xCA,  0x27,  0xFE,  0x52,  0x26,  0xBE,  0x52,  0x2E, 	/* 1DBD0 */
+	0x7E,  0x99,  0x26,  0x21,  0x94,  0x10,  0x0F,  0xFE,  0x49,  0x03,  0x3E,  0x7E,  0x24,  0xBE,  0x72,  0x24, 	/* 1DBE0 */
+	0xBE,  0x72,  0x28,  0xBE,  0x91,  0x46,  0x62,  0x95,  0x00,  0x0F,  0xBE,  0x89,  0x0F,  0xBE,  0x8A,  0x2F, 	/* 1DBF0 */
+	0xBE,  0x52,  0x2D,  0x7E,  0xDA,  0x25,  0x3E,  0x59,  0x4E,  0x62,  0x98,  0x00,  0x07,  0xFF,  0x48,  0x87, 	/* 1DC00 */
+	0xDE,  0x65,  0x27,  0xDE,  0x65,  0x27,  0xDE,  0x59,  0x27,  0x5E,  0x51,  0xAB,  0x61,  0x9B,  0x20,  0x0F, 	/* 1DC10 */
+	0xBE,  0x21,  0x07,  0xBE,  0x4A,  0x27,  0xBE,  0x4A,  0x27,  0xBE,  0x4A,  0x2F,  0xFE,  0x51,  0x48,  0xA2, 	/* 1DC20 */
+	0x9E,  0x28,  0x0A,  0xFE,  0x71,  0x0F,  0xFE,  0x32,  0x26,  0xBE,  0xAA,  0x22,  0x3E,  0xFE,  0x22,  0x3E, 	/* 1DC30 */
+	0x51,  0x48,  0xA2,  0xA7,  0x00,  0x0F,  0xBE,  0x00,  0x8F,  0xFE,  0x86,  0x2F,  0xFE,  0xAA,  0x2B,  0xFE, 	/* 1DC40 */
+	0xEA,  0x2B,  0xFE,  0xA9,  0x43,  0xE2,  0xAB,  0x20,  0x0F,  0xFE,  0x89,  0x0B,  0xBE,  0xAA,  0x2F,  0xBE, 	/* 1DC50 */
+	0x4A,  0x27,  0xBE,  0x4A,  0x27,  0xBE,  0x01,  0x4F,  0xE2,  0xAF,  0x00,  0x0F,  0xFE,  0x89,  0x0F,  0xBE, 	/* 1DC60 */
+	0x8A,  0x2F,  0xBE,  0x52,  0x2A,  0xBE,  0x52,  0x2F,  0xBE,  0x69,  0x4A,  0xA2,  0xB0,  0x5B,  0xE5,  0x10, 	/* 1DC70 */
+	0xFF,  0xC6,  0x24,  0xAB,  0xC3,  0x62,  0xFF,  0x82,  0x48,  0x3F,  0x82,  0x48,  0xFF,  0xE0,  0x20,  0xB1, 	/* 1DC80 */
+	0x38,  0x02,  0x3F,  0xFD,  0x0A,  0x3E,  0xBA,  0x2A,  0xBE,  0xBA,  0x2A,  0xBE,  0xFE,  0x2A,  0xBE,  0x29, 	/* 1DC90 */
+	0x2F,  0xE1,  0xB3,  0x7C,  0x02,  0xBE,  0x38,  0x82,  0x9E,  0xFD,  0x20,  0x9E,  0xFF,  0x25,  0x5E,  0x7D, 	/* 1DCA0 */
+	0x25,  0x5E,  0xFD,  0x42,  0x62,  0xB4,  0x50,  0x0F,  0xFF,  0x51,  0x0F,  0xBE,  0xAA,  0x2F,  0xBE,  0x52, 	/* 1DCB0 */
+	0x27,  0xFE,  0xD2,  0x27,  0xBE,  0x51,  0x27,  0xE1,  0xA8,  0x00,  0x07,  0xF8,  0x46,  0x85,  0x88,  0x7E, 	/* 1DCC0 */
+	0x86,  0xA8,  0x6A,  0x87,  0xE8,  0x48,  0xA4,  0xAA,  0x4F,  0x6B,  0x12,  0xAA,  0xFF,  0xC0,  0x80,  0x0F, 	/* 1DCD0 */
+	0x80,  0x80,  0x7F,  0x84,  0x88,  0x7E,  0x86,  0xA8,  0x7E,  0x84,  0xAA,  0x4F,  0x6B,  0x8A,  0xAF,  0x20, 	/* 1DCE0 */
+	0x02,  0x7C,  0xFC,  0xC1,  0x74,  0x95,  0x45,  0x7C,  0x55,  0x42,  0x7C,  0x35,  0x4C,  0x9D,  0x11,  0xB2, 	/* 1DCF0 */
+	0x65,  0xB1,  0x00,  0x87,  0xC8,  0x4D,  0x47,  0x7E,  0x54,  0x17,  0xDE,  0x55,  0x27,  0xD2,  0x55,  0xE5, 	/* 1DD00 */
+	0x20,  0x5D,  0x9B,  0x47,  0xB6,  0x01,  0xE7,  0xD2,  0x4D,  0xE7,  0x52,  0x55,  0xE7,  0xD2,  0x57,  0xF7, 	/* 1DD10 */
+	0xCC,  0x55,  0x25,  0x20,  0x5D,  0x9B,  0x47,  0x83,  0x03,  0xEF,  0x94,  0x9B,  0xEE,  0xAA,  0xAB,  0xEF, 	/* 1DD20 */
+	0x80,  0xAB,  0xEF,  0x88,  0xAA,  0xAA,  0x4A,  0xBB,  0x1E,  0x8F,  0x84,  0x00,  0x0F,  0xFE,  0x52,  0x6F, 	/* 1DD30 */
+	0xBA,  0xAA,  0xAF,  0xBE,  0x02,  0xAF,  0xBE,  0x72,  0xAA,  0xCE,  0xA4,  0xE6,  0xB1,  0x86,  0x14,  0x07, 	/* 1DD40 */
+	0xFE,  0x12,  0x62,  0xBA,  0x46,  0xA4,  0xBE,  0x4A,  0xAF,  0xFE,  0x4A,  0xA4,  0xCA,  0xB4,  0xF8,  0xB5, 	/* 1DD50 */
+	0x9B,  0x00,  0x07,  0xF2,  0x19,  0xCE,  0x94,  0x29,  0x22,  0x8E,  0xFF,  0x42,  0x98,  0x49,  0x44,  0x92, 	/* 1DD60 */
+	0x88,  0xA0,  0x86,  0x9C,  0x18,  0x0E,  0x7C,  0x23,  0x6F,  0xD4,  0x75,  0x4A,  0xD2,  0x27,  0xCF,  0xD6, 	/* 1DD70 */
+	0xAD,  0x4F,  0xD6,  0xAD,  0x4F,  0x92,  0x9F,  0x04,  0x00,  0xA0,  0x15,  0x03,  0xF8,  0xD0,  0xE1,  0xF8, 	/* 1DD80 */
+	0x10,  0x81,  0xF8,  0x14,  0x41,  0x28,  0x1D,  0x87,  0x06,  0xA2,  0x20,  0x03,  0x38,  0x4A,  0x8B,  0x68, 	/* 1DD90 */
+	0x4A,  0x87,  0xA8,  0x4A,  0x87,  0xA8,  0x52,  0x84,  0xAA,  0x54,  0xAE,  0x86,  0xA9,  0x21,  0x03,  0x10, 	/* 1DDA0 */
+	0x49,  0xEB,  0x70,  0x79,  0x44,  0xD4,  0x7D,  0x44,  0x7C,  0x79,  0x04,  0x12,  0x7D,  0x24,  0x0E,  0xAB, 	/* 1DDB0 */
+	0x20,  0xC3,  0x70,  0x49,  0x0B,  0x10,  0x79,  0x04,  0xFE,  0x79,  0x04,  0x10,  0x7A,  0x84,  0x28,  0x7C, 	/* 1DDC0 */
+	0x44,  0x82,  0xAD,  0x21,  0x03,  0x10,  0x4B,  0xEB,  0x50,  0x49,  0x07,  0xFE,  0x49,  0x27,  0x92,  0x42, 	/* 1DDD0 */
+	0x27,  0xA2,  0x44,  0x2F,  0x8C,  0xAE,  0x21,  0x03,  0x10,  0x49,  0xEB,  0xEA,  0x4A,  0xC7,  0xC8,  0x48, 	/* 1DDE0 */
+	0x87,  0x88,  0x41,  0x47,  0x94,  0x42,  0x27,  0xC1,  0xAF,  0x20,  0x03,  0x3E,  0x4A,  0x0B,  0x20,  0x4B, 	/* 1DDF0 */
+	0xE7,  0xA2,  0x4A,  0x47,  0xB4,  0x52,  0x84,  0xCC,  0x55,  0x2E,  0xA1,  0xB2,  0x21,  0x03,  0x10,  0x4D, 	/* 1DE00 */
+	0x0B,  0x1F,  0x4A,  0xA7,  0xAA,  0x4C,  0x87,  0x88,  0x51,  0x44,  0x94,  0x56,  0x2E,  0xC1,  0xB4,  0x21, 	/* 1DE10 */
+	0x03,  0x10,  0x49,  0x0B,  0x58,  0x4A,  0x47,  0xBC,  0x4E,  0x27,  0xBC,  0x52,  0x44,  0xA4,  0x56,  0x4E, 	/* 1DE20 */
+	0x3C,  0xBC,  0x20,  0x03,  0x7E,  0x48,  0x2B,  0x3E,  0x48,  0x27,  0xBA,  0x4A,  0xA7,  0xAA,  0x52,  0xA4, 	/* 1DE30 */
+	0xBA,  0x54,  0x2E,  0x06,  0xBD,  0x22,  0x03,  0x20,  0x4B,  0xEB,  0xC2,  0x4B,  0xA7,  0x8A,  0x48,  0xA7, 	/* 1DE40 */
+	0xBA,  0x52,  0x44,  0xA0,  0x56,  0x2E,  0x1E,  0xBE,  0x22,  0x03,  0x20,  0x4B,  0xEB,  0x48,  0x4B,  0xE7, 	/* 1DE50 */
+	0xAA,  0x4A,  0xA7,  0xAA,  0x52,  0xA4,  0xAE,  0x54,  0x8E,  0x08,  0x83,  0x21,  0x03,  0x10,  0x4F,  0xEB, 	/* 1DE60 */
+	0x28,  0x7C,  0x44,  0xAA,  0x7A,  0x84,  0x10,  0x79,  0x04,  0x28,  0x7C,  0x44,  0x82,  0x85,  0x24,  0x43, 	/* 1DE70 */
+	0x24,  0x4A,  0x8B,  0x7E,  0x4A,  0x47,  0xA4,  0x4F,  0xF7,  0xA4,  0x52,  0x44,  0xA4,  0x54,  0x4E,  0x84, 	/* 1DE80 */
+	0x89,  0x21,  0x03,  0x10,  0x4A,  0x0B,  0x7E,  0x74,  0x25,  0x7A,  0x76,  0xA4,  0x6A,  0x7F,  0xA4,  0x42, 	/* 1DE90 */
+	0x7C,  0x24,  0x46,  0x8A,  0x11,  0x0F,  0xFE,  0x04,  0x07,  0xFC,  0x15,  0x02,  0x48,  0xDF,  0x61,  0x10, 	/* 1DEA0 */
+	0x1F,  0x41,  0x48,  0x13,  0x07,  0xCC,  0x8C,  0x20,  0x03,  0x7E,  0x4A,  0x4B,  0x3C,  0x4A,  0x47,  0xA4, 	/* 1DEB0 */
+	0x4B,  0xC7,  0xA4,  0x52,  0x44,  0xBE,  0x56,  0x4E,  0x04,  0x90,  0x3B,  0xC2,  0x24,  0x79,  0x8D,  0x27, 	/* 1DEC0 */
+	0x26,  0x0D,  0x98,  0x3F,  0xCD,  0x0B,  0x1F,  0x81,  0x4C,  0x13,  0x07,  0x8E,  0x92,  0x20,  0x63,  0x38, 	/* 1DED0 */
+	0x48,  0xCB,  0x2A,  0x7A,  0xA4,  0xC8,  0x79,  0x04,  0x7E,  0x7A,  0x44,  0x74,  0x79,  0x84,  0x64,  0x93, 	/* 1DEE0 */
+	0x22,  0x83,  0x4C,  0x4C,  0xAF,  0x48,  0x5F,  0xE7,  0x48,  0x56,  0xA7,  0xCA,  0x44,  0x45,  0x4C,  0x5D, 	/* 1DEF0 */
+	0x6E,  0xC2,  0x94,  0x20,  0xC3,  0x0A,  0x4B,  0xFB,  0x48,  0x7B,  0xE4,  0xAA,  0x7B,  0xE4,  0x2A,  0x7B, 	/* 1DF00 */
+	0xE4,  0x2A,  0x7A,  0xA4,  0x26,  0x98,  0x21,  0x03,  0x18,  0x4A,  0x4B,  0x42,  0x7B,  0xC4,  0x90,  0x7F, 	/* 1DF10 */
+	0xE4,  0x10,  0x75,  0x84,  0x54,  0x79,  0x24,  0x30,  0x9D,  0x22,  0x43,  0x7E,  0x4A,  0x4B,  0x88,  0x78, 	/* 1DF20 */
+	0x84,  0xFE,  0x79,  0x04,  0x1C,  0x79,  0x44,  0x24,  0x7C,  0x44,  0x98,  0x9E,  0x22,  0x83,  0x2E,  0x4F, 	/* 1DF30 */
+	0x4B,  0x08,  0x79,  0x64,  0xE2,  0x7A,  0x84,  0x1E,  0x77,  0x44,  0x08,  0x79,  0x64,  0x62,  0xA0,  0x22, 	/* 1DF40 */
+	0x43,  0x24,  0x4C,  0x8B,  0x7E,  0x7A,  0x44,  0xA4,  0x7B,  0x44,  0x6F,  0x7A,  0x44,  0x24,  0x7C,  0x44, 	/* 1DF50 */
+	0x84,  0xA1,  0x21,  0x03,  0x1E,  0x49,  0x2B,  0x12,  0x7A,  0x24,  0xCC,  0x79,  0x04,  0x66,  0x74,  0x24, 	/* 1DF60 */
+	0x76,  0x7C,  0x24,  0x7E,  0xA4,  0x20,  0x83,  0x2A,  0x4A,  0xCB,  0x48,  0x79,  0x44,  0xE2,  0x78,  0x84, 	/* 1DF70 */
+	0x2A,  0x7A,  0xC4,  0x48,  0x79,  0x44,  0x62,  0xA8,  0x21,  0x02,  0x7E,  0x54,  0x27,  0xBC,  0xCE,  0x47, 	/* 1DF80 */
+	0xA4,  0x4B,  0xC7,  0xA0,  0x53,  0xE4,  0xA2,  0x56,  0x2E,  0x3E,  0xAC,  0x20,  0x03,  0x2E,  0x4A,  0xAB, 	/* 1DF90 */
+	0x7A,  0x7A,  0xE4,  0xAA,  0x7F,  0xA4,  0x5E,  0x75,  0xA4,  0x7A,  0x79,  0x24,  0x26,  0xAE,  0x7C,  0x82, 	/* 1DFA0 */
+	0xB4,  0xD8,  0xB1,  0x34,  0xE5,  0x80,  0xA0,  0x35,  0x8D,  0xFE,  0x11,  0x01,  0xF4,  0x13,  0x87,  0x8E, 	/* 1DFB0 */
+	0xBD,  0x21,  0x03,  0x20,  0x4F,  0xCB,  0x54,  0x7F,  0xC4,  0xD4,  0x7F,  0xC4,  0x28,  0x7A,  0xA4,  0x2E, 	/* 1DFC0 */
+	0x7C,  0x84,  0x86,  0xBE,  0x22,  0x03,  0x7E,  0x48,  0xAB,  0x8A,  0x7A,  0xA4,  0xF2,  0x7A,  0xC4,  0x3E, 	/* 1DFD0 */
+	0x7A,  0xA4,  0x3E,  0x7E,  0xA4,  0x3E,  0x82,  0x20,  0x03,  0x3E,  0x4A,  0xAB,  0x36,  0x7A,  0x24,  0xBE, 	/* 1DFE0 */
+	0x78,  0x04,  0x3E,  0x7A,  0xA4,  0x2A,  0x7A,  0xA4,  0x7F,  0x85,  0x27,  0xC3,  0x44,  0x4F,  0xCB,  0x44, 	/* 1DFF0 */
+	0x7F,  0xE4,  0xAA,  0x7F,  0xE4,  0x00,  0x7F,  0xC4,  0x24,  0x79,  0x84,  0x66,  0x89,  0x22,  0x83,  0x7E, 	/* 1E000 */
+	0x4A,  0x8B,  0x38,  0x78,  0x04,  0xFC,  0x7D,  0x44,  0x7E,  0x79,  0x04,  0x7C,  0x79,  0x04,  0xFE,  0x8B, 	/* 1E010 */
+	0x21,  0x03,  0x7C,  0x4D,  0x4B,  0x7C,  0x79,  0x04,  0xFE,  0x7C,  0x44,  0x7C,  0x74,  0x44,  0x7C,  0x7A, 	/* 1E020 */
+	0x44,  0x42,  0x8C,  0x27,  0xE3,  0x5A,  0x4F,  0xEB,  0x48,  0x7C,  0xA4,  0xB6,  0x79,  0x44,  0x7E,  0x79, 	/* 1E030 */
+	0x44,  0x7F,  0x7A,  0x44,  0x42,  0x90,  0x21,  0x03,  0x7E,  0x49,  0x0B,  0x7E,  0x7C,  0x24,  0xBC,  0x78, 	/* 1E040 */
+	0x04,  0x3C,  0x7A,  0x44,  0x3C,  0x7A,  0x84,  0xFE,  0x91,  0x22,  0x43,  0x48,  0x4F,  0xCB,  0x5A,  0x7F, 	/* 1E050 */
+	0xE4,  0x94,  0x7F,  0xE4,  0x54,  0x75,  0x84,  0xAA,  0x79,  0x64,  0x62,  0x92,  0x21,  0x03,  0x7C,  0x49, 	/* 1E060 */
+	0x0B,  0x34,  0x7F,  0xE4,  0xA4,  0x7F,  0xE4,  0x00,  0x7F,  0xE4,  0x28,  0x7A,  0xA4,  0x46,  0x95,  0x79, 	/* 1E070 */
+	0xC4,  0x90,  0xFF,  0xE7,  0x2C,  0x15,  0xA6,  0xAE,  0x35,  0x8D,  0xF6,  0x11,  0x01,  0xF4,  0x13,  0x87, 	/* 1E080 */
+	0x8E,  0x97,  0x2E,  0xED,  0xAA,  0x6E,  0xCF,  0xCA,  0x2A,  0xA5,  0xDC,  0x06,  0x83,  0xF8,  0xD1,  0x61, 	/* 1E090 */
+	0xF0,  0x12,  0x83,  0x9C,  0x96,  0x21,  0x01,  0x20,  0xFF,  0xE0,  0x80,  0x3F,  0x82,  0x08,  0x3F,  0x82, 	/* 1E0A0 */
+	0x08,  0x3F,  0x82,  0x08,  0x20,  0x83,  0xF8,  0x97,  0x24,  0x22,  0x24,  0x27,  0xEF,  0x90,  0x2B,  0xE2, 	/* 1E0B0 */
+	0xA2,  0x2B,  0xE2,  0xBE,  0x2A,  0x24,  0xBE,  0x48,  0x18,  0x7F,  0x98,  0x51,  0x02,  0x14,  0xFF,  0xE4, 	/* 1E0C0 */
+	0x08,  0xF7,  0xA9,  0x5A,  0xF7,  0xA9,  0x0A,  0xF3,  0x49,  0xCD,  0x91,  0x3F,  0x21,  0x99,  0x01,  0xC3, 	/* 1E0D0 */
+	0xE0,  0x04,  0x0F,  0xFE,  0x0E,  0x03,  0x58,  0xC4,  0x63,  0xF8,  0x20,  0x83,  0xF8,  0x20,  0x83,  0xF8, 	/* 1E0E0 */
+	0xA5,  0x1A,  0x07,  0x3E,  0x16,  0x4F,  0xBC,  0x32,  0x45,  0xBC,  0x91,  0x07,  0x9C,  0x4A,  0x47,  0xD8, 	/* 1E0F0 */
+	0x49,  0x47,  0xE2,  0xA8,  0x7D,  0xC1,  0x14,  0xFF,  0x25,  0x5C,  0x7D,  0x49,  0xE8,  0x85,  0x6F,  0xFE, 	/* 1E100 */
+	0x14,  0x83,  0xFC,  0xD0,  0xA1,  0xF8,  0xAC,  0x00,  0x03,  0xFE,  0x22,  0x03,  0xFC,  0x22,  0x03,  0xFC, 	/* 1E110 */
+	0x22,  0x03,  0xFE,  0x00,  0x25,  0x52,  0x54,  0x28,  0x1C,  0xAD,  0x00,  0x0F,  0xFC,  0xA2,  0x4F,  0x24, 	/* 1E120 */
+	0xA2,  0x4F,  0x14,  0xA1,  0x8F,  0x88,  0x09,  0x8A,  0x94,  0x8A,  0x23,  0x41,  0xAE,  0x00,  0x08,  0xFE, 	/* 1E130 */
+	0x49,  0x04,  0xFC,  0x09,  0x00,  0xFC,  0x29,  0x04,  0xFE,  0x41,  0x29,  0x4A,  0x92,  0x22,  0x0C,  0xB3, 	/* 1E140 */
+	0x00,  0x8F,  0xA8,  0xA2,  0xEF,  0xBA,  0xA6,  0xAF,  0xAA,  0xA2,  0xAF,  0xAE,  0x0A,  0x8A,  0xA0,  0x8A, 	/* 1E150 */
+	0x23,  0x1E,  0xB4,  0xFA,  0xAA,  0x2A,  0xF2,  0xAA,  0x2A,  0xF2,  0xAA,  0x2A,  0xFA,  0xA0,  0xAA,  0xAA, 	/* 1E160 */
+	0xAA,  0xAA,  0x8C,  0xA3,  0x42,  0xBC,  0x01,  0x0F,  0x90,  0xAF,  0xEF,  0x24,  0xA2,  0x4F,  0x28,  0xA1, 	/* 1E170 */
+	0x8F,  0x90,  0x09,  0x8A,  0xA8,  0x8C,  0x43,  0x02,  0x81,  0x04,  0x4F,  0xE8,  0xA1,  0x0F,  0x2C,  0xA4, 	/* 1E180 */
+	0x2F,  0x24,  0xA2,  0x4F,  0x98,  0x08,  0x8A,  0x94,  0x8A,  0x43,  0x42,  0x84,  0x01,  0x0F,  0x90,  0xA1, 	/* 1E190 */
+	0x0F,  0xFE,  0xA1,  0x0F,  0x10,  0xA2,  0x8F,  0xA8,  0x0A,  0x8A,  0xA4,  0x95,  0x46,  0x82,  0x85,  0x00, 	/* 1E1A0 */
+	0x0F,  0xBE,  0xA2,  0x2F,  0x22,  0xA3,  0xEF,  0x28,  0xA2,  0x8F,  0xA8,  0x0A,  0x4A,  0xA4,  0x8A,  0x23, 	/* 1E1B0 */
+	0x41,  0x86,  0x00,  0x0F,  0xFE,  0xA4,  0x4F,  0x44,  0xA5,  0x4F,  0x48,  0xA4,  0x8F,  0xD4,  0x0D,  0x2A, 	/* 1E1C0 */
+	0xE0,  0x8C,  0x03,  0x7E,  0x88,  0x00,  0x4F,  0x88,  0xA3,  0x0F,  0x20,  0xA3,  0xEF,  0x24,  0xA2,  0x4F, 	/* 1E1D0 */
+	0xA4,  0x0A,  0x4A,  0xA4,  0x8A,  0x43,  0x7F,  0x90,  0x02,  0x0F,  0x90,  0xAF,  0xEF,  0x10,  0xA1,  0x0F, 	/* 1E1E0 */
+	0x10,  0xA7,  0xCF,  0x90,  0x09,  0x0A,  0x90,  0x89,  0x03,  0x7E,  0x91,  0x20,  0x0F,  0xFE,  0x49,  0x27, 	/* 1E1F0 */
+	0x0C,  0x2B,  0x4D,  0xFA,  0x12,  0x01,  0xF8,  0x12,  0x01,  0xFE,  0x52,  0xA8,  0x8C,  0x92,  0x02,  0x0F, 	/* 1E200 */
+	0xA0,  0xA3,  0xEF,  0x42,  0xA7,  0xAF,  0xAA,  0xA2,  0xAF,  0xAA,  0x0B,  0xAA,  0x82,  0x88,  0x23,  0x0C, 	/* 1E210 */
+	0x95,  0x20,  0x0F,  0xBE,  0x2A,  0x24,  0xBE,  0x98,  0x03,  0xFC,  0x24,  0x03,  0xF8,  0x24,  0x03,  0xFE, 	/* 1E220 */
+	0x4A,  0xA9,  0x0C,  0x98,  0x01,  0x0F,  0x90,  0xA2,  0x8F,  0x24,  0xA4,  0xEF,  0xF2,  0xA0,  0x2F,  0xBC, 	/* 1E230 */
+	0x0A,  0x4A,  0xA4,  0x8A,  0x43,  0x3C,  0x9B,  0x01,  0x0F,  0x90,  0xA7,  0xCF,  0x54,  0xA5,  0x4F,  0x54, 	/* 1E240 */
+	0xA7,  0xCF,  0xD0,  0x0B,  0x0A,  0xA8,  0x8C,  0x63,  0x81,  0x9D,  0x01,  0x0F,  0x90,  0xAF,  0xEF,  0x82, 	/* 1E250 */
+	0xA2,  0x2F,  0x20,  0xA2,  0x6F,  0xB8,  0x0A,  0x0A,  0xA0,  0x8A,  0x23,  0x1E,  0x9F,  0x00,  0x0F,  0xFE, 	/* 1E260 */
+	0xA5,  0xAF,  0x5A,  0xA5,  0xAF,  0x5A,  0xA6,  0xAF,  0xCE,  0x0C,  0x2A,  0xC2,  0x8F,  0xE3,  0x00,  0xA2, 	/* 1E270 */
+	0x02,  0x2F,  0x94,  0xA7,  0xEF,  0x14,  0xA1,  0x4F,  0x14,  0xA7,  0xFF,  0x94,  0x09,  0x4A,  0xA4,  0x8A, 	/* 1E280 */
+	0x43,  0x44,  0xAD,  0x01,  0x0F,  0x90,  0xAF,  0xEF,  0x10,  0xA1,  0x4F,  0x64,  0xA1,  0x8F,  0x92,  0x0A, 	/* 1E290 */
+	0x4A,  0x88,  0x89,  0x43,  0x62,  0xAE,  0x01,  0x0F,  0x90,  0xAF,  0xEF,  0x28,  0xA2,  0x4F,  0x4A,  0xAA, 	/* 1E2A0 */
+	0x8F,  0xA8,  0x09,  0x0A,  0x98,  0x8A,  0x43,  0x42,  0xB1,  0x01,  0x0F,  0x9C,  0xA2,  0x4F,  0x34,  0xA4, 	/* 1E2B0 */
+	0x8F,  0x14,  0xA2,  0x2F,  0xFD,  0x0A,  0x4A,  0xA4,  0x8A,  0x43,  0x3C,  0xB2,  0x02,  0xAF,  0xAA,  0xA2, 	/* 1E2C0 */
+	0xAF,  0x2A,  0xA2,  0xAF,  0x6E,  0xAB,  0xAF,  0xAA,  0x0A,  0xAA,  0xAA,  0x8C,  0xA3,  0x8A,  0xB8,  0x00, 	/* 1E2D0 */
+	0x0F,  0xBC,  0xA0,  0x4F,  0x7E,  0xA0,  0x4F,  0x7E,  0xA4,  0x2F,  0xFC,  0x09,  0x4A,  0x88,  0x89,  0x43, 	/* 1E2E0 */
+	0x62,  0xBB,  0x07,  0xCF,  0xC4,  0xA7,  0xCF,  0x44,  0xA7,  0xCF,  0x00,  0xA7,  0xEF,  0x90,  0x0F,  0xFA, 	/* 1E2F0 */
+	0x90,  0x89,  0x03,  0x10,  0xBF,  0x01,  0x0F,  0x94,  0xA7,  0xEF,  0x2A,  0xA2,  0x8F,  0xCE,  0xA2,  0x0F, 	/* 1E300 */
+	0xBC,  0x0E,  0x4A,  0x98,  0x8B,  0x43,  0x42,  0x81,  0x02,  0x0F,  0xFC,  0xA5,  0x4F,  0x7C,  0xA5,  0x4F, 	/* 1E310 */
+	0x7C,  0xA0,  0x0F,  0xFE,  0x0A,  0x0A,  0xBC,  0x88,  0x43,  0x18,  0x85,  0x01,  0x2F,  0x94,  0xA3,  0xEF, 	/* 1E320 */
+	0x68,  0xA2,  0x8F,  0x3E,  0xA2,  0x8F,  0xA8,  0x0B,  0xEA,  0xA8,  0x8A,  0x83,  0x3E,  0x8E,  0x01,  0x0F, 	/* 1E330 */
+	0x7C,  0xA1,  0x0F,  0x28,  0xA4,  0x6F,  0xFE,  0xA0,  0x4F,  0xF4,  0x0D,  0x4A,  0xF4,  0x88,  0x43,  0x0C, 	/* 1E340 */
+	0x8F,  0x02,  0x4F,  0xA4,  0xA7,  0xEF,  0x24,  0xA3,  0xCF,  0x24,  0xA3,  0xCF,  0xA4,  0x0F,  0xEA,  0x94, 	/* 1E350 */
+	0x8A,  0x23,  0x42,  0x92,  0xFF,  0xCA,  0x44,  0xF2,  0x8A,  0x38,  0xFD,  0x6A,  0x7C,  0xFD,  0x40,  0xD4, 	/* 1E360 */
+	0xAF,  0xCA,  0x92,  0x89,  0xE3,  0x62,  0x93,  0x01,  0x0F,  0xA8,  0xA4,  0x4F,  0xFA,  0xA1,  0x0F,  0x7C, 	/* 1E370 */
+	0xA5,  0x4F,  0xFC,  0x29,  0x0A,  0x98,  0x8A,  0x43,  0x42,  0x99,  0x07,  0xEF,  0x80,  0xA3,  0xEF,  0x22, 	/* 1E380 */
+	0xA3,  0xEF,  0x20,  0xA3,  0xFF,  0xB5,  0x0D,  0xFA,  0xD5,  0x89,  0x53,  0x13,  0xA8,  0x0A,  0x2F,  0x54, 	/* 1E390 */
+	0xA7,  0xCF,  0x54,  0xA7,  0xCF,  0x54,  0xA7,  0xCF,  0x90,  0x0F,  0xEA,  0x90,  0x89,  0x03,  0x10,  0xAB, 	/* 1E3A0 */
+	0x04,  0x0F,  0xFE,  0x91,  0x23,  0xF8,  0x11,  0x0F,  0xFE,  0x32,  0x45,  0xFA,  0x92,  0x01,  0xFC,  0x55, 	/* 1E3B0 */
+	0x48,  0x98,  0xB0,  0x0A,  0x8E,  0xFC,  0xA2,  0x0B,  0xFE,  0xE5,  0x0A,  0xF8,  0xB5,  0x6E,  0x78,  0xA5, 	/* 1E3C0 */
+	0x0A,  0x7E,  0xAA,  0xAB,  0x5C,  0xB7,  0xFB,  0xFA,  0x15,  0xF4,  0xAA,  0x2C,  0xF7,  0x3A,  0x08,  0xFB, 	/* 1E3D0 */
+	0xF0,  0xA9,  0xAB,  0xFA,  0x8A,  0x88,  0xF3,  0x71,  0xBE,  0x00,  0x0F,  0xFE,  0xA4,  0xAF,  0x7E,  0xA4, 	/* 1E3E0 */
+	0xAF,  0x7E,  0xA0,  0x8F,  0xB4,  0x08,  0xAA,  0xFE,  0x8A,  0xC3,  0x4A,  0x80,  0x09,  0x0F,  0xFE,  0x10, 	/* 1E3F0 */
+	0x81,  0xF8,  0x10,  0x8F,  0xFE,  0x32,  0x45,  0xFA,  0x92,  0x11,  0xFC,  0x2A,  0x45,  0x18,  0x82,  0x00, 	/* 1E400 */
+	0x8F,  0x94,  0xA7,  0xEF,  0x2A,  0xAF,  0xFF,  0x14,  0xA2,  0xAF,  0xF1,  0x08,  0xCA,  0xB2,  0x88,  0xC3, 	/* 1E410 */
+	0x30,  0x83,  0x00,  0x0F,  0xFE,  0xA2,  0x8F,  0x7E,  0xAA,  0xAF,  0xFE,  0xA7,  0xCF,  0x80,  0x0F,  0xEA, 	/* 1E420 */
+	0xB4,  0x8D,  0x23,  0x30,  0x85,  0x00,  0x0F,  0xFE,  0xA5,  0xCF,  0x54,  0xA5,  0xCF,  0x40,  0xA7,  0xEF, 	/* 1E430 */
+	0xEA,  0x0E,  0xAA,  0xFE,  0x8C,  0x03,  0x7E,  0x8D,  0x01,  0x0F,  0xFC,  0xA1,  0x0F,  0x54,  0xAE,  0xEF, 	/* 1E440 */
+	0x44,  0xAF,  0xEF,  0x80,  0x0F,  0xEA,  0xA8,  0x8A,  0xA3,  0x46,  0x95,  0x00,  0xCF,  0xF0,  0xA1,  0x0F, 	/* 1E450 */
+	0x7E,  0xA2,  0x8F,  0x6C,  0xAB,  0xAF,  0x80,  0x0F,  0xEA,  0xAA,  0x8B,  0xA3,  0x86,  0x97,  0x01,  0x0F, 	/* 1E460 */
+	0xA8,  0xA4,  0x4F,  0x7A,  0xA8,  0x1F,  0xEE,  0xAA,  0xAF,  0xEE,  0x0A,  0x4A,  0xB4,  0x8C,  0xA3,  0x91, 	/* 1E470 */
+	0x9A,  0x29,  0x0F,  0xDE,  0x45,  0x2F,  0x6C,  0x55,  0x47,  0xFA,  0x22,  0x03,  0xFC,  0x22,  0x03,  0xFE, 	/* 1E480 */
+	0x52,  0xA8,  0x8C,  0x9B,  0x00,  0x0F,  0x7E,  0xAA,  0xAF,  0xFE,  0xA1,  0x0F,  0x7C,  0xA2,  0x8F,  0xFE, 	/* 1E490 */
+	0x09,  0x0A,  0xFC,  0x89,  0x03,  0x10,  0x9F,  0x00,  0x0F,  0xFE,  0xA5,  0xAF,  0x74,  0xA5,  0xAF,  0xF1, 	/* 1E4A0 */
+	0xA5,  0x8F,  0xB2,  0x0D,  0xAA,  0xB4,  0x8D,  0x23,  0x10,  0xA2,  0x01,  0xCF,  0x90,  0xA7,  0xEF,  0x50, 	/* 1E4B0 */
+	0xA5,  0xFF,  0x40,  0xA7,  0xEF,  0xEA,  0x0F,  0xEA,  0xEA,  0x8A,  0xA3,  0x7F,  0xA4,  0x01,  0x0F,  0xFF, 	/* 1E4C0 */
+	0xA5,  0xAF,  0x7E,  0xA2,  0x8F,  0x7C,  0xA2,  0x8F,  0xFE,  0x09,  0x2A,  0xEC,  0x8A,  0x43,  0x72,  0xA5, 	/* 1E4D0 */
+	0x02,  0x8F,  0xEE,  0xA2,  0x8F,  0xFE,  0xA5,  0x4F,  0x7C,  0xA5,  0x4F,  0xFE,  0x0A,  0x8A,  0xFE,  0x8A, 	/* 1E4E0 */
+	0x43,  0x42,  0xA9,  0x02,  0x8F,  0xFE,  0xA2,  0x8F,  0xEE,  0xAA,  0xAF,  0xFE,  0xA2,  0x8F,  0xBE,  0x0E, 	/* 1E4F0 */
+	0x8A,  0xBE,  0x8A,  0x83,  0x3E,  0xAA,  0x06,  0xEF,  0x80,  0xA7,  0xEF,  0x56,  0xA0,  0x8F,  0x7E,  0xA5, 	/* 1E500 */
+	0x4F,  0xFE,  0x0E,  0x8A,  0xBE,  0x8A,  0x83,  0x76,  0xAB,  0x3F,  0x82,  0x40,  0x3F,  0xC2,  0xA4,  0x41, 	/* 1E510 */
+	0x87,  0xFE,  0x52,  0x87,  0xBC,  0x52,  0x87,  0xBE,  0x6A,  0xAB,  0x4C,  0xA8,  0x1F,  0x81,  0x08,  0x17, 	/* 1E520 */
+	0x81,  0x48,  0x7F,  0xE5,  0xFA,  0x50,  0xA1,  0xF8,  0x10,  0x81,  0xF8,  0x10,  0x81,  0x18,  0xAD,  0x78, 	/* 1E530 */
+	0x04,  0xBE,  0x58,  0x8F,  0xC8,  0x84,  0x87,  0xFF,  0x48,  0x87,  0x88,  0x48,  0x87,  0x88,  0x48,  0x85, 	/* 1E540 */
+	0x88,  0xB0,  0x79,  0xC4,  0x94,  0x59,  0x4F,  0xD5,  0x86,  0x37,  0xC0,  0x4F,  0xC7,  0xA4,  0x4A,  0x87, 	/* 1E550 */
+	0x98,  0x4A,  0x45,  0xC2,  0xB8,  0x78,  0x84,  0x88,  0x5F,  0xEF,  0xD0,  0x85,  0x07,  0xA4,  0x4D,  0x87, 	/* 1E560 */
+	0x92,  0x4A,  0x47,  0xC8,  0x49,  0x45,  0xE2,  0xBC,  0x79,  0x04,  0x9C,  0x5A,  0x4F,  0xD8,  0x84,  0x87, 	/* 1E570 */
+	0x94,  0x4A,  0x27,  0xFD,  0x4A,  0x47,  0xA4,  0x4A,  0x45,  0xBC,  0x80,  0x78,  0x84,  0x90,  0x5B,  0xEF, 	/* 1E580 */
+	0xEA,  0x87,  0xE7,  0xAA,  0x4B,  0xE7,  0x94,  0x4A,  0x47,  0xFF,  0x48,  0x45,  0x84,  0x84,  0x78,  0x44, 	/* 1E590 */
+	0x9F,  0x5C,  0x45,  0xAF,  0xFC,  0x98,  0x5F,  0x4E,  0x97,  0xAF,  0x4A,  0x97,  0xAB,  0x4D,  0x05,  0x8F, 	/* 1E5A0 */
+	0x8F,  0x78,  0x84,  0xBE,  0x5A,  0xAF,  0xFF,  0x87,  0xE7,  0xAA,  0x4B,  0xE7,  0x90,  0x4F,  0xF7,  0x92, 	/* 1E5B0 */
+	0x49,  0xC5,  0xB2,  0x91,  0x77,  0xE5,  0x5A,  0x77,  0xEF,  0xA0,  0x8B,  0xE7,  0x52,  0x5F,  0xE7,  0x56, 	/* 1E5C0 */
+	0x57,  0xE7,  0x1A,  0x5F,  0x65,  0x0C,  0x93,  0x78,  0x84,  0xBE,  0x59,  0x4F,  0xEE,  0x88,  0x07,  0x1E, 	/* 1E5D0 */
+	0x5D,  0x27,  0x5E,  0x55,  0x27,  0x52,  0x5B,  0x65,  0x1F,  0x94,  0x79,  0x44,  0xBE,  0x5A,  0xAF,  0xFE, 	/* 1E5E0 */
+	0x86,  0xA7,  0xFF,  0x48,  0x07,  0xBE,  0x4A,  0x27,  0xBE,  0x49,  0x45,  0xFF,  0x98,  0x02,  0x07,  0xFE, 	/* 1E5F0 */
+	0x00,  0x01,  0xF8,  0x10,  0x81,  0xF8,  0x7F,  0xE4,  0x02,  0x4F,  0x24,  0x92,  0x4F,  0x24,  0x06,  0x9E, 	/* 1E600 */
+	0x23,  0x8F,  0xA8,  0x73,  0x85,  0x00,  0x7E,  0xE0,  0xAA,  0xFE,  0xEB,  0x90,  0xAF,  0xEB,  0xB4,  0x8D, 	/* 1E610 */
+	0x29,  0x90,  0x9F,  0x00,  0x87,  0xC8,  0x41,  0x07,  0x94,  0x42,  0x47,  0x88,  0x40,  0x8F,  0xD2,  0x20, 	/* 1E620 */
+	0x22,  0x84,  0x3C,  0x8E,  0x50,  0xA2,  0x78,  0x84,  0x14,  0x7A,  0x84,  0x12,  0xFC,  0x45,  0x08,  0xFD, 	/* 1E630 */
+	0x02,  0x7C,  0xFC,  0x42,  0x58,  0x20,  0x21,  0xFE,  0xA3,  0x7C,  0x84,  0x32,  0x78,  0xC4,  0x32,  0xFC, 	/* 1E640 */
+	0xC4,  0xB0,  0x04,  0x0F,  0xFE,  0x04,  0x00,  0xF8,  0x10,  0x86,  0x30,  0xA6,  0x7C,  0x84,  0x32,  0x78, 	/* 1E650 */
+	0xC4,  0x32,  0xFC,  0xC4,  0xB0,  0x07,  0x03,  0xF8,  0x08,  0x0F,  0xFE,  0x08,  0x20,  0x7E,  0xAA,  0x7C, 	/* 1E660 */
+	0xC4,  0x32,  0x78,  0xC4,  0x32,  0xFC,  0xC4,  0xB0,  0xFF,  0xE1,  0x00,  0x3F,  0x8C,  0x90,  0x0E,  0x0F, 	/* 1E670 */
+	0x1C,  0xAB,  0x7C,  0x84,  0x32,  0x78,  0xC4,  0x32,  0xFC,  0xC4,  0xB0,  0xFF,  0xC0,  0x84,  0x31,  0x8D, 	/* 1E680 */
+	0xF8,  0x10,  0x81,  0xF8,  0xAD,  0x7C,  0xC4,  0x32,  0x78,  0xC4,  0x32,  0xF8,  0xC5,  0x30,  0xEC,  0x01, 	/* 1E690 */
+	0x26,  0x5B,  0x85,  0x20,  0x5E,  0x2E,  0x1E,  0xAE,  0x7C,  0xC4,  0x32,  0x78,  0xC4,  0x32,  0xFC,  0xC5, 	/* 1E6A0 */
+	0x30,  0x4D,  0x4F,  0xFE,  0x15,  0x02,  0x20,  0xCD,  0x83,  0x06,  0xAF,  0x7C,  0x84,  0x32,  0x78,  0xC4, 	/* 1E6B0 */
+	0x32,  0xFC,  0xC4,  0xB0,  0x3F,  0x82,  0x48,  0x3F,  0x82,  0x48,  0xFF,  0xE2,  0x18,  0xB1,  0x78,  0x84, 	/* 1E6C0 */
+	0x32,  0x70,  0xC4,  0x32,  0xFC,  0xC4,  0xB0,  0x08,  0x01,  0xFC,  0x32,  0x4D,  0xE8,  0x10,  0x20,  0xFE, 	/* 1E6D0 */
+	0xB4,  0x7C,  0xC4,  0x32,  0x78,  0xC4,  0x32,  0xFC,  0xC5,  0x30,  0x4D,  0x47,  0xF8,  0x12,  0x8F,  0xFE, 	/* 1E6E0 */
+	0x22,  0x24,  0x2C,  0xB7,  0x7C,  0x84,  0x32,  0x78,  0xC4,  0x32,  0xFC,  0xC4,  0xB0,  0x0A,  0x07,  0xFC, 	/* 1E6F0 */
+	0x4A,  0x47,  0xFC,  0x4A,  0x47,  0xFC,  0xBB,  0x7C,  0x84,  0x32,  0x78,  0xC4,  0x32,  0xFC,  0xC4,  0xB0, 	/* 1E700 */
+	0x04,  0x0F,  0xFE,  0x04,  0x07,  0xFC,  0x20,  0x83,  0xF8,  0x86,  0x78,  0x84,  0x32,  0x70,  0xC4,  0x32, 	/* 1E710 */
+	0xFC,  0xC4,  0xB0,  0x22,  0x4F,  0xA4,  0x75,  0x26,  0x98,  0xA2,  0x42,  0x7A,  0x98,  0x7C,  0x44,  0x18, 	/* 1E720 */
+	0xFE,  0x24,  0x84,  0xF5,  0x81,  0x08,  0x7F,  0xE4,  0x92,  0x7F,  0xE3,  0x08,  0x0F,  0x07,  0x0E,  0x9A, 	/* 1E730 */
+	0x7C,  0x44,  0x18,  0xFE,  0x24,  0x84,  0xF5,  0x80,  0x00,  0x37,  0xEC,  0x20,  0x37,  0xCC,  0x44,  0x37, 	/* 1E740 */
+	0xCC,  0x82,  0x9F,  0x78,  0x84,  0x32,  0xFC,  0xC5,  0x32,  0xFF,  0xC4,  0xA4,  0xFF,  0xE2,  0x08,  0x3F, 	/* 1E750 */
+	0x80,  0xCC,  0xF3,  0x01,  0x8E,  0xA2,  0x78,  0x84,  0x32,  0x74,  0xCF,  0xB2,  0x40,  0xCF,  0xFE,  0x95, 	/* 1E760 */
+	0x22,  0xE0,  0x7F,  0x8A,  0x08,  0x3F,  0x87,  0x1C,  0xA3,  0x7C,  0x84,  0x32,  0xFC,  0xC5,  0x32,  0xF8, 	/* 1E770 */
+	0xC2,  0xB0,  0x7F,  0xC5,  0x54,  0x7F,  0xC2,  0x4A,  0x37,  0x6E,  0xC2,  0xA5,  0x80,  0x2B,  0xBA,  0x91, 	/* 1E780 */
+	0x2B,  0xBA,  0x91,  0x2B,  0xBA,  0x80,  0x28,  0x02,  0x80,  0x28,  0x02,  0x80,  0x28,  0x06,  0xA7,  0x80, 	/* 1E790 */
+	0x2B,  0xBA,  0x91,  0x2B,  0xBA,  0x91,  0x2B,  0xBA,  0x84,  0x2B,  0xFA,  0x9F,  0x29,  0x52,  0x95,  0x28, 	/* 1E7A0 */
+	0x46,  0xA8,  0x80,  0x2B,  0xBA,  0x91,  0x2B,  0xBA,  0x91,  0x2B,  0xBA,  0x8A,  0x29,  0xF2,  0x8A,  0x2B, 	/* 1E7B0 */
+	0xFA,  0x8A,  0x29,  0x16,  0xA9,  0xBB,  0xA9,  0x12,  0xBB,  0xA9,  0x12,  0xBB,  0xA8,  0xB2,  0x91,  0x29, 	/* 1E7C0 */
+	0xB2,  0x91,  0x29,  0xF2,  0x8A,  0xAB,  0x1A,  0xAA,  0xBB,  0xA9,  0x12,  0xBB,  0xA8,  0x02,  0xBC,  0xA8, 	/* 1E7D0 */
+	0x0A,  0xBF,  0xEA,  0x4A,  0xBE,  0xAA,  0x5A,  0x94,  0xAB,  0xDA,  0xAE,  0xBB,  0xA9,  0x12,  0xBB,  0xA8, 	/* 1E7E0 */
+	0xF2,  0xB2,  0x29,  0xF2,  0xA9,  0x2F,  0xFA,  0xAB,  0xAF,  0xFA,  0x94,  0x6A,  0x3E,  0xAF,  0x91,  0x28, 	/* 1E7F0 */
+	0x92,  0xE2,  0x29,  0xCE,  0xCB,  0x2B,  0x4A,  0xC2,  0x2F,  0xFE,  0x21,  0x83,  0xE0,  0x20,  0x21,  0xFE, 	/* 1E800 */
+	0xB1,  0x24,  0x8F,  0x7E,  0x6D,  0xCB,  0x6A,  0xFF,  0xEA,  0x82,  0x54,  0xC6,  0xF0,  0x44,  0xC7,  0xB0, 	/* 1E810 */
+	0x44,  0x63,  0xF8,  0xB2,  0x00,  0x0F,  0xFE,  0x00,  0x03,  0xF8,  0x20,  0x8F,  0xFE,  0x8A,  0x2F,  0x3E, 	/* 1E820 */
+	0x80,  0x2B,  0xFA,  0x84,  0x28,  0x46,  0xBB,  0xE4,  0xE3,  0x52,  0xDF,  0xC2,  0xE2,  0x35,  0x2C,  0x4C, 	/* 1E830 */
+	0xFF,  0xE1,  0x10,  0x7F,  0xC4,  0xA4,  0x7F,  0x44,  0x0C,  0xBC,  0x04,  0x00,  0x80,  0x3F,  0x82,  0x48, 	/* 1E840 */
+	0x3F,  0x82,  0x48,  0x3F,  0x80,  0xA8,  0x0B,  0x41,  0x3C,  0x22,  0x2C,  0x1E,  0x81,  0x20,  0x44,  0x04, 	/* 1E850 */
+	0xF9,  0x4A,  0xA4,  0xF9,  0x4A,  0xA4,  0xF8,  0x63,  0x7C,  0x3A,  0x45,  0xE4,  0x51,  0x28,  0xFE,  0x82, 	/* 1E860 */
+	0x02,  0x00,  0xFC,  0xEA,  0x40,  0xFC,  0x0A,  0x4F,  0xA4,  0x4F,  0xC5,  0x54,  0xB5,  0xAD,  0x5E,  0x09, 	/* 1E870 */
+	0x23,  0x0E,  0x83,  0x21,  0x44,  0x12,  0xFF,  0xEA,  0x90,  0xF9,  0x4A,  0x94,  0xF8,  0x83,  0x48,  0x3B, 	/* 1E880 */
+	0x45,  0xE2,  0x52,  0x08,  0xFF,  0x84,  0x22,  0x04,  0x40,  0xEF,  0xCA,  0xA4,  0xAF,  0xCE,  0xA4,  0xAF, 	/* 1E890 */
+	0xCA,  0x64,  0xA6,  0xAE,  0xBE,  0x12,  0x16,  0x1F,  0x85,  0x20,  0x84,  0x08,  0xFB,  0xEA,  0x88,  0xF8, 	/* 1E8A0 */
+	0x8A,  0xFE,  0xF9,  0xC3,  0x6A,  0x3A,  0x85,  0xE8,  0x50,  0x18,  0xFF,  0x8D,  0x20,  0x04,  0x3E,  0xFA, 	/* 1E8B0 */
+	0x2A,  0xB6,  0xFA,  0xAA,  0xBE,  0xFA,  0xA3,  0x6E,  0x3A,  0x25,  0xE6,  0x54,  0x18,  0xFF,  0x8E,  0x20, 	/* 1E8C0 */
+	0x04,  0x7E,  0xF8,  0x8A,  0xBE,  0xFA,  0xAA,  0xBE,  0xFA,  0xE3,  0x7A,  0x3A,  0xA5,  0xEE,  0x50,  0x18, 	/* 1E8D0 */
+	0xFF,  0x8F,  0x19,  0x0E,  0x20,  0x27,  0xCF,  0xD4,  0x77,  0xCA,  0xD4,  0x27,  0xCF,  0x9A,  0x49,  0xC7, 	/* 1E8E0 */
+	0x2E,  0x2A,  0x9C,  0x4F,  0x91,  0x20,  0x84,  0x7E,  0xFA,  0x6A,  0xBA,  0xFB,  0x6A,  0xBE,  0xF8,  0x83, 	/* 1E8F0 */
+	0x7E,  0x3B,  0x65,  0xFE,  0x52,  0x38,  0xFF,  0x94,  0x02,  0x07,  0xFE,  0x48,  0x87,  0xFE,  0x5D,  0xC6, 	/* 1E900 */
+	0xAA,  0x5F,  0xC5,  0x24,  0x5F,  0xC8,  0x55,  0x89,  0x37,  0x0F,  0x98,  0x00,  0x07,  0xFE,  0x52,  0xA7, 	/* 1E910 */
+	0xFE,  0x52,  0x85,  0xF4,  0x56,  0x25,  0xFC,  0x52,  0x45,  0xFC,  0x8A,  0xA3,  0x1E,  0x9A,  0x08,  0x00, 	/* 1E920 */
+	0xF0,  0x11,  0x02,  0x20,  0x7F,  0xCA,  0x44,  0x3F,  0xC2,  0x44,  0x3F,  0xC0,  0x00,  0x4A,  0x48,  0x92, 	/* 1E930 */
+	0xAF,  0x1F,  0x06,  0x20,  0x3F,  0xC2,  0x44,  0x3F,  0xC2,  0x44,  0x3F,  0xC4,  0xA4,  0x89,  0x23,  0xFC, 	/* 1E940 */
+	0x20,  0x43,  0xFC,  0xB4,  0x21,  0x03,  0x90,  0x57,  0xEF,  0x90,  0xA9,  0x0F,  0x9C,  0xA9,  0x4F,  0x94, 	/* 1E950 */
+	0x12,  0x46,  0xA4,  0x54,  0x48,  0x98,  0x83,  0x20,  0x03,  0xFE,  0x51,  0x0F,  0xB8,  0xAD,  0x4F,  0x90, 	/* 1E960 */
+	0xAF,  0xEF,  0x90,  0x11,  0x06,  0x90,  0x51,  0x08,  0x10,  0x8E,  0x21,  0x03,  0x90,  0x51,  0x0F,  0x9E, 	/* 1E970 */
+	0xA9,  0x0F,  0x90,  0xAB,  0xCF,  0xA4,  0x12,  0x46,  0xA4,  0x52,  0x48,  0x3C,  0x91,  0x21,  0x03,  0x90, 	/* 1E980 */
+	0x53,  0xEF,  0xA2,  0xAF,  0xAF,  0xAA,  0xAA,  0xAF,  0xBC,  0x12,  0x06,  0xA0,  0x52,  0x28,  0x1E,  0x92, 	/* 1E990 */
+	0x21,  0x43,  0x94,  0x52,  0x4F,  0xBF,  0xAE,  0x4F,  0xA4,  0xAB,  0x4F,  0xAC,  0x12,  0x46,  0xA4,  0x52, 	/* 1E9A0 */
+	0x48,  0x2C,  0x93,  0x21,  0x03,  0x90,  0x53,  0xEF,  0xB0,  0xAD,  0x0F,  0x9E,  0xA9,  0x0F,  0x90,  0x11, 	/* 1E9B0 */
+	0xE6,  0x90,  0x51,  0x08,  0x10,  0x96,  0x20,  0x03,  0xFE,  0x51,  0x0F,  0x90,  0xA9,  0x0F,  0xA0,  0xAB, 	/* 1E9C0 */
+	0xEF,  0xD2,  0x11,  0x26,  0x92,  0x51,  0x28,  0x1E,  0x97,  0x20,  0x83,  0x9C,  0x52,  0x4F,  0xE8,  0xA9, 	/* 1E9D0 */
+	0x8F,  0xA4,  0xAD,  0x2F,  0x88,  0x12,  0x06,  0x98,  0x50,  0x48,  0x02,  0x9F,  0x20,  0x83,  0x88,  0x57, 	/* 1E9E0 */
+	0xEF,  0xD2,  0xA9,  0x0F,  0xFE,  0xAA,  0x4F,  0xA4,  0x17,  0x86,  0x88,  0x51,  0x48,  0x62,  0xA0,  0x20, 	/* 1E9F0 */
+	0x83,  0x9E,  0x52,  0x4F,  0xBE,  0xAA,  0x0F,  0xBC,  0xAB,  0x4F,  0xB4,  0x13,  0xC6,  0xD0,  0x55,  0x28, 	/* 1EA00 */
+	0x8E,  0xA8,  0x22,  0x03,  0xA6,  0x53,  0x8F,  0xA2,  0xA9,  0xEF,  0x80,  0xAB,  0xEF,  0xA2,  0x13,  0xE6, 	/* 1EA10 */
+	0xA2,  0x52,  0x28,  0x3E,  0xAA,  0x21,  0x03,  0x90,  0x57,  0xEF,  0x90,  0xAB,  0xCF,  0xA4,  0xAF,  0xCF, 	/* 1EA20 */
+	0xA4,  0x13,  0xC6,  0xA4,  0x52,  0x48,  0x2C,  0xAB,  0x21,  0x03,  0x90,  0x57,  0xEF,  0xA8,  0xAA,  0x4F, 	/* 1EA30 */
+	0xCA,  0xAA,  0x8F,  0xA8,  0x11,  0x06,  0xA8,  0x54,  0x48,  0x82,  0xAD,  0x21,  0x03,  0x90,  0x57,  0xCF, 	/* 1EA40 */
+	0x90,  0xA9,  0x0F,  0xFE,  0xA9,  0x0F,  0x90,  0x17,  0xC6,  0x90,  0x51,  0x08,  0xFE,  0xAE,  0x24,  0x43, 	/* 1EA50 */
+	0xA8,  0x57,  0xEF,  0x90,  0xA9,  0x0F,  0xFC,  0xA9,  0x0F,  0x90,  0x17,  0xE6,  0x90,  0x51,  0x08,  0x10, 	/* 1EA60 */
+	0xB4,  0x21,  0x43,  0x94,  0x51,  0x4F,  0xBF,  0xAA,  0x4F,  0xEE,  0xAA,  0xEF,  0xB5,  0x13,  0x56,  0xA4, 	/* 1EA70 */
+	0x52,  0x48,  0x24,  0xB9,  0x21,  0x03,  0xB4,  0x53,  0x4F,  0xD2,  0xAB,  0xCF,  0xA4,  0xAB,  0xCF,  0xA4, 	/* 1EA80 */
+	0x13,  0xC6,  0xA4,  0x52,  0x48,  0x2C,  0x80,  0x20,  0x63,  0xF8,  0x51,  0x0F,  0xE4,  0xAA,  0x8F,  0x94, 	/* 1EA90 */
+	0xAF,  0xEF,  0x92,  0x13,  0x46,  0xD2,  0x51,  0x28,  0x10,  0x86,  0x20,  0xA3,  0xFF,  0x50,  0x8F,  0xBE, 	/* 1EAA0 */
+	0xAA,  0xAF,  0xAA,  0xAB,  0xEF,  0xAA,  0x13,  0xE6,  0xAA,  0x52,  0xA8,  0x26,  0x89,  0x20,  0x03,  0xBE, 	/* 1EAB0 */
+	0x52,  0xAF,  0xBE,  0xAA,  0xAF,  0xAA,  0xAB,  0xEF,  0x88,  0x13,  0xE6,  0x88,  0x50,  0x88,  0x7E,  0x8A, 	/* 1EAC0 */
+	0x21,  0x09,  0x54,  0x45,  0x22,  0xB6,  0x41,  0x88,  0xF0,  0x72,  0x03,  0xFC,  0x22,  0x43,  0xFC,  0x3F, 	/* 1EAD0 */
+	0xC4,  0x92,  0x8F,  0x21,  0xA3,  0xE2,  0x52,  0xAF,  0xAA,  0xAF,  0xAF,  0xAA,  0xAB,  0xAF,  0xEA,  0x16, 	/* 1EAE0 */
+	0x26,  0xA2,  0x52,  0x28,  0x26,  0x91,  0x23,  0x23,  0x8C,  0x53,  0x2F,  0x90,  0xAF,  0xFF,  0x98,  0xAB, 	/* 1EAF0 */
+	0xEF,  0xAA,  0x16,  0xA6,  0xAE,  0x50,  0x88,  0x08,  0x92,  0x20,  0x03,  0xFE,  0x51,  0x4F,  0x88,  0xAB, 	/* 1EB00 */
+	0xEF,  0xAA,  0xAB,  0xEF,  0xAA,  0x13,  0xE6,  0xAA,  0x52,  0xA8,  0x26,  0x94,  0x22,  0xA3,  0xAA,  0x55, 	/* 1EB10 */
+	0x4F,  0xAA,  0xAA,  0xAF,  0x80,  0xAB,  0xEF,  0xAA,  0x13,  0xE6,  0xAA,  0x52,  0xA8,  0x3E,  0x96,  0x20, 	/* 1EB20 */
+	0x83,  0xBE,  0x50,  0x8F,  0xBC,  0xA8,  0x8F,  0xFE,  0xAA,  0x4F,  0xBC,  0x12,  0x46,  0xBC,  0x52,  0x48, 	/* 1EB30 */
+	0x2C,  0x9B,  0x20,  0x03,  0xBE,  0x52,  0xAF,  0xBE,  0xAA,  0xAF,  0xAA,  0xAB,  0xEF,  0xB6,  0x13,  0x66, 	/* 1EB40 */
+	0xBE,  0x54,  0x28,  0x86,  0xA1,  0x22,  0x83,  0xA8,  0x56,  0xEF,  0xA8,  0xAA,  0x8F,  0xEE,  0xAA,  0x8F, 	/* 1EB50 */
+	0xA8,  0x16,  0xE6,  0xC8,  0x54,  0x88,  0x88,  0xA2,  0x20,  0x83,  0x90,  0x52,  0xCF,  0xA4,  0xAB,  0xCF, 	/* 1EB60 */
+	0xA4,  0xAA,  0x4F,  0xBC,  0x11,  0x86,  0x9A,  0x52,  0xA8,  0x46,  0xA3,  0x20,  0x03,  0xBC,  0x52,  0x4F, 	/* 1EB70 */
+	0xBC,  0xAA,  0x4F,  0xBC,  0xA9,  0x0F,  0xBE,  0x12,  0xA6,  0xD2,  0x52,  0x28,  0x0C,  0xA4,  0x20,  0x03, 	/* 1EB80 */
+	0xBE,  0x52,  0x2F,  0xBE,  0xAA,  0x2F,  0xBE,  0xAA,  0x8F,  0xBA,  0x12,  0xC6,  0xAA,  0x53,  0xA8,  0x66, 	/* 1EB90 */
+	0xA8,  0x21,  0x03,  0xFE,  0x50,  0x0F,  0xBC,  0xAA,  0x4F,  0xA4,  0xAB,  0xCF,  0x88,  0x12,  0xC6,  0xAA, 	/* 1EBA0 */
+	0x54,  0xA8,  0x18,  0xB0,  0x21,  0x03,  0x90,  0x52,  0x8F,  0xFC,  0xA8,  0x2F,  0xBC,  0xA8,  0x4F,  0x88, 	/* 1EBB0 */
+	0x13,  0x46,  0xAA,  0x56,  0x28,  0x1E,  0xB1,  0x20,  0x83,  0x8E,  0x50,  0x8F,  0xBE,  0xAA,  0x8F,  0xBE, 	/* 1EBC0 */
+	0xAA,  0x8F,  0xA7,  0x12,  0xC6,  0xAC,  0x55,  0x58,  0xA3,  0xB2,  0x22,  0x43,  0xA4,  0x57,  0xAF,  0xAA, 	/* 1EBD0 */
+	0xAA,  0x1F,  0xB8,  0xAB,  0x4F,  0xB4,  0x15,  0x06,  0xD4,  0x51,  0x28,  0x62,  0xB5,  0x21,  0x07,  0xA4, 	/* 1EBE0 */
+	0x97,  0xAF,  0x90,  0xAF,  0xEF,  0x98,  0xAA,  0x4F,  0xCA,  0x13,  0x16,  0x84,  0x51,  0x88,  0x60,  0x84, 	/* 1EBF0 */
+	0x20,  0x43,  0x86,  0x53,  0xFF,  0xA4,  0xAB,  0xCF,  0xA4,  0xAB,  0xDF,  0xB6,  0x15,  0xC6,  0xD2,  0x56, 	/* 1EC00 */
+	0xB8,  0x81,  0x86,  0x21,  0x03,  0xFC,  0x51,  0x0F,  0xBC,  0xA9,  0x0F,  0xFE,  0xAA,  0x8F,  0xBC,  0x16, 	/* 1EC10 */
+	0x66,  0xBD,  0x52,  0x48,  0x3C,  0x88,  0x25,  0x43,  0xFE,  0x55,  0x4F,  0xDC,  0xAC,  0x0F,  0xFE,  0xA9, 	/* 1EC20 */
+	0x0F,  0xFE,  0x11,  0x86,  0xB4,  0x55,  0x28,  0x10,  0x89,  0x21,  0x03,  0xBC,  0x52,  0x4F,  0xBC,  0xAA, 	/* 1EC30 */
+	0x4F,  0xBC,  0xA8,  0x0F,  0xFE,  0x10,  0x86,  0xBE,  0x50,  0x88,  0x7E,  0x8A,  0x20,  0x83,  0xFE,  0x50, 	/* 1EC40 */
+	0x8F,  0xBE,  0xAB,  0xAF,  0xAE,  0xAB,  0xEF,  0x9C,  0x12,  0xA6,  0xC9,  0x50,  0x88,  0x08,  0x8C,  0x21, 	/* 1EC50 */
+	0xC3,  0x94,  0x52,  0x2F,  0xFE,  0xA9,  0x4F,  0xBE,  0xAA,  0xAF,  0xB6,  0x12,  0x26,  0xBE,  0x52,  0x28, 	/* 1EC60 */
+	0x3E,  0x8D,  0x21,  0xC3,  0xE4,  0x52,  0x4F,  0xA5,  0xAF,  0x6F,  0xAE,  0xAF,  0x4F,  0xA4,  0x12,  0xA6, 	/* 1EC70 */
+	0xAA,  0x53,  0x28,  0xA1,  0x90,  0x27,  0xE3,  0xDA,  0x57,  0xEF,  0x80,  0xAB,  0xCF,  0x80,  0xAF,  0xEF, 	/* 1EC80 */
+	0xA0,  0x13,  0xC6,  0x84,  0x50,  0x48,  0x18,  0x92,  0x22,  0x03,  0xBE,  0x56,  0x4F,  0xBC,  0xAA,  0x4F, 	/* 1EC90 */
+	0xBC,  0xA9,  0x0F,  0x9E,  0x13,  0x46,  0xC8,  0x51,  0x48,  0x62,  0x93,  0x20,  0x03,  0xBE,  0x52,  0xAF, 	/* 1ECA0 */
+	0xAA,  0xAB,  0xEF,  0xAA,  0xAB,  0xEF,  0x94,  0x12,  0xA6,  0xB0,  0x5D,  0x29,  0x0E,  0x94,  0x20,  0x43, 	/* 1ECB0 */
+	0x86,  0x53,  0xFF,  0xA4,  0xAB,  0xCF,  0xA4,  0xAB,  0xDF,  0xB6,  0x15,  0xC6,  0xCA,  0x55,  0x38,  0x81, 	/* 1ECC0 */
+	0x95,  0x20,  0x03,  0xF6,  0x55,  0x2F,  0xD2,  0xAF,  0x6F,  0xC0,  0xAF,  0xEF,  0xCA,  0x14,  0xA6,  0xF4, 	/* 1ECD0 */
+	0x54,  0xA8,  0x51,  0x9B,  0x20,  0x03,  0xBC,  0x52,  0x4F,  0xBC,  0xAA,  0x4F,  0xBC,  0xA8,  0x0F,  0xBE, 	/* 1ECE0 */
+	0x12,  0xA6,  0xAA,  0x52,  0xA8,  0x7F,  0xA1,  0x21,  0x03,  0xAE,  0x54,  0xAF,  0xEA,  0xAD,  0x2F,  0xF6, 	/* 1ECF0 */
+	0xA8,  0x0F,  0xBE,  0x12,  0xA6,  0xBE,  0x52,  0xA8,  0x3E,  0xA4,  0x20,  0x03,  0xBE,  0x54,  0x8F,  0xFE, 	/* 1ED00 */
+	0xAA,  0xAF,  0xEA,  0xA8,  0xAF,  0xEA,  0x1A,  0xA6,  0xA8,  0x5E,  0x88,  0x08,  0xA5,  0x20,  0x03,  0xFE, 	/* 1ED10 */
+	0x55,  0xAF,  0xDA,  0xAF,  0xEF,  0x88,  0xAA,  0xCF,  0xCA,  0x11,  0xC6,  0xAA,  0x54,  0x98,  0x08,  0xAD, 	/* 1ED20 */
+	0x21,  0x27,  0xBE,  0x91,  0x4F,  0xFE,  0xAA,  0x0F,  0xFC,  0xAA,  0x2F,  0x9E,  0x10,  0x06,  0xBE,  0x52, 	/* 1ED30 */
+	0x28,  0x3E,  0xAE,  0x20,  0x03,  0xBE,  0x52,  0xAF,  0xB6,  0xAA,  0x2F,  0xBE,  0xA8,  0x0F,  0xBE,  0x12, 	/* 1ED40 */
+	0xA6,  0xAA,  0x52,  0xA8,  0x7F,  0xAF,  0x20,  0x03,  0xFE,  0x51,  0x2F,  0xBE,  0xAC,  0x8F,  0xFE,  0xA9, 	/* 1ED50 */
+	0x2F,  0xDA,  0x13,  0x66,  0xDA,  0x51,  0x28,  0x6C,  0xB0,  0x20,  0x87,  0x68,  0xA1,  0xEF,  0x1A,  0xBF, 	/* 1ED60 */
+	0xAF,  0x5E,  0xB7,  0xAF,  0xFA,  0x15,  0xE6,  0xC8,  0x54,  0x88,  0x48,  0xB2,  0x20,  0x87,  0x9E,  0x23, 	/* 1ED70 */
+	0x4F,  0xC8,  0x49,  0x49,  0xE2,  0x64,  0x03,  0xF8,  0x24,  0x83,  0xF8,  0x29,  0x44,  0x4A,  0xB9,  0x20, 	/* 1ED80 */
+	0x03,  0x7E,  0x54,  0xAF,  0xFA,  0xAF,  0x4F,  0xCA,  0xAF,  0x1F,  0x88,  0x13,  0xE6,  0x88,  0x50,  0x88, 	/* 1ED90 */
+	0x7F,  0xBA,  0x21,  0x03,  0xA4,  0x57,  0xAF,  0x90,  0xAF,  0xEF,  0x98,  0xAA,  0x4F,  0xCA,  0x13,  0x56, 	/* 1EDA0 */
+	0x88,  0x53,  0x08,  0xC0,  0xBB,  0x23,  0xC7,  0xA4,  0x93,  0xCF,  0xA4,  0xAF,  0xEF,  0xAA,  0xAF,  0xEF, 	/* 1EDB0 */
+	0xA4,  0x11,  0x46,  0x98,  0x52,  0x48,  0x42,  0xBE,  0x27,  0xE3,  0x94,  0x57,  0xEF,  0xDA,  0xAF,  0xEF, 	/* 1EDC0 */
+	0x80,  0xAB,  0xEF,  0x80,  0x17,  0xF6,  0xAC,  0x54,  0xA8,  0x18,  0x86,  0x20,  0x83,  0xFE,  0x52,  0x4F, 	/* 1EDD0 */
+	0x98,  0xAF,  0xEF,  0xA4,  0xAB,  0xCF,  0xA4,  0x13,  0xC6,  0x88,  0x57,  0xE8,  0x08,  0x87,  0x20,  0x83, 	/* 1EDE0 */
+	0xBE,  0x52,  0x8F,  0xBE,  0xAA,  0xAF,  0xBF,  0xAA,  0xAF,  0xBE,  0x12,  0xA6,  0xDC,  0x56,  0xA8,  0x88, 	/* 1EDF0 */
+	0x88,  0x23,  0xE3,  0x88,  0x57,  0xFF,  0xC9,  0xAE,  0xDF,  0xDB,  0xA8,  0x0F,  0xBE,  0x10,  0x26,  0xBE, 	/* 1EE00 */
+	0x50,  0x28,  0x3E,  0x92,  0x24,  0x47,  0xA8,  0x97,  0xEF,  0xA8,  0xAF,  0xEF,  0xAA,  0xAC,  0xEF,  0xFF, 	/* 1EE10 */
+	0x12,  0x46,  0x94,  0x50,  0x48,  0x0C,  0x97,  0x20,  0x83,  0xAA,  0x57,  0xFF,  0x9C,  0xAA,  0xAF,  0xC9, 	/* 1EE20 */
+	0xAB,  0xCF,  0xAE,  0x16,  0xC6,  0x94,  0x52,  0xF8,  0x44,  0x9A,  0x20,  0x83,  0xFF,  0x50,  0x8F,  0xBE, 	/* 1EE30 */
+	0xAA,  0x2F,  0xBE,  0xA9,  0x4F,  0xFF,  0x10,  0x06,  0xBE,  0x52,  0x28,  0x3E,  0xA0,  0x20,  0x83,  0xD4, 	/* 1EE40 */
+	0x53,  0xEF,  0xC1,  0xAF,  0xEF,  0xEE,  0xAD,  0xAF,  0xFE,  0x12,  0x46,  0xBC,  0x52,  0x48,  0x3C,  0xA7, 	/* 1EE50 */
+	0x21,  0x43,  0xBE,  0x52,  0xAF,  0xBE,  0xAA,  0xAF,  0xBE,  0xA8,  0x0F,  0xFE,  0x12,  0x46,  0xBC,  0x52, 	/* 1EE60 */
+	0x88,  0x7E,  0xB6,  0x21,  0x43,  0xFE,  0x50,  0x8F,  0xBE,  0xA9,  0x8F,  0xA4,  0xAF,  0xEF,  0xA5,  0x13, 	/* 1EE70 */
+	0xC6,  0xAA,  0x53,  0x49,  0x62,  0xB8,  0x20,  0x83,  0x8E,  0x50,  0x8F,  0xBE,  0xAA,  0x8F,  0xBE,  0xAA, 	/* 1EE80 */
+	0xAF,  0xBE,  0x14,  0x06,  0xFE,  0x5A,  0xA9,  0x7F,  0xA5,  0x08,  0x03,  0xF8,  0x20,  0x83,  0xF8,  0x20, 	/* 1EE90 */
+	0x83,  0xFE,  0x20,  0x03,  0xFE,  0x01,  0x25,  0x4A,  0x4A,  0x28,  0x0C,  0xA7,  0x08,  0x03,  0xF0,  0x21, 	/* 1EEA0 */
+	0x03,  0xFE,  0x20,  0x03,  0xFE,  0x55,  0x28,  0xAC,  0x1F,  0x01,  0x10,  0x21,  0x2C,  0x0E,  0xA9,  0x42, 	/* 1EEB0 */
+	0x04,  0x7C,  0x44,  0x4F,  0x7C,  0x54,  0x45,  0x7E,  0x54,  0x05,  0x7E,  0x58,  0x24,  0xAA,  0x8A,  0x21, 	/* 1EEC0 */
+	0x0C,  0xAB,  0x00,  0x07,  0xFE,  0x44,  0x05,  0xF8,  0x50,  0x85,  0xF8,  0x5F,  0xE5,  0x00,  0x5F,  0xE5, 	/* 1EED0 */
+	0x52,  0xAA,  0xA4,  0x0C,  0xAC,  0x08,  0x03,  0xF0,  0x21,  0x03,  0xFE,  0x20,  0x03,  0xFE,  0x00,  0x21, 	/* 1EEE0 */
+	0xF2,  0x11,  0xC1,  0x10,  0x21,  0x2C,  0x0E,  0xB0,  0x01,  0x00,  0x3C,  0x72,  0x41,  0x3C,  0x12,  0x41, 	/* 1EEF0 */
+	0x3E,  0x2A,  0x02,  0x7E,  0x41,  0x68,  0x2A,  0x04,  0x20,  0x0C,  0xB3,  0x7F,  0xC4,  0x44,  0x5F,  0x45, 	/* 1EF00 */
+	0x14,  0x5F,  0x45,  0x14,  0x5F,  0xC5,  0x04,  0x5F,  0xC4,  0xAD,  0x55,  0xBA,  0x31,  0xB4,  0x04,  0x00, 	/* 1EF10 */
+	0xF8,  0xE8,  0x8A,  0xF8,  0xA8,  0x8A,  0xFC,  0xA8,  0x0A,  0xFE,  0xE0,  0x21,  0x56,  0x15,  0x22,  0x0C, 	/* 1EF20 */
+	0xB6,  0x04,  0x8F,  0xFE,  0x02,  0x01,  0x1A,  0x3F,  0x62,  0x12,  0x3F,  0x02,  0x00,  0x3F,  0xE5,  0x52, 	/* 1EF30 */
+	0x4A,  0xA8,  0x0C,  0x83,  0x41,  0x0F,  0x10,  0x91,  0x0F,  0x7C,  0x91,  0x4F,  0x94,  0x87,  0xEF,  0x90, 	/* 1EF40 */
+	0x59,  0x8A,  0xA8,  0x8A,  0x43,  0x42,  0x86,  0x21,  0x02,  0x3C,  0xFA,  0x4A,  0xBC,  0xAA,  0x42,  0x3E, 	/* 1EF50 */
+	0x32,  0x03,  0x7E,  0x59,  0x65,  0x2A,  0x44,  0x28,  0x0C,  0x87,  0x82,  0x0F,  0x7C,  0x84,  0x48,  0x7C, 	/* 1EF60 */
+	0x74,  0x42,  0x7E,  0x24,  0x0F,  0x7E,  0x20,  0x22,  0xAA,  0x2A,  0x22,  0x8C,  0x88,  0x00,  0x07,  0xFE, 	/* 1EF70 */
+	0x49,  0x04,  0xBC,  0x4A,  0x45,  0x3C,  0x53,  0xE7,  0x20,  0x53,  0xE5,  0x52,  0x9A,  0xA1,  0x0C,  0x89, 	/* 1EF80 */
+	0x01,  0x07,  0xBC,  0x52,  0x45,  0x3C,  0x52,  0x4F,  0xBE,  0x12,  0x03,  0x3E,  0x31,  0x65,  0x2A,  0x94, 	/* 1EF90 */
+	0x23,  0x0C,  0x8E,  0x01,  0x0F,  0xBC,  0x82,  0x48,  0xBC,  0xCA,  0x4B,  0x3E,  0x92,  0x0A,  0xBE,  0xC9, 	/* 1EFA0 */
+	0x68,  0x2A,  0xFC,  0x28,  0x0C,  0x92,  0x21,  0x02,  0x3C,  0x32,  0x44,  0xBC,  0xF6,  0x40,  0x3E,  0xFA, 	/* 1EFB0 */
+	0x02,  0xBE,  0x29,  0x63,  0x2A,  0x24,  0x22,  0x0C,  0x95,  0x20,  0x87,  0xBE,  0x4A,  0x27,  0xA2,  0x49, 	/* 1EFC0 */
+	0x07,  0xD2,  0x41,  0xC7,  0xD0,  0x2D,  0x05,  0x52,  0x85,  0x21,  0x8E,  0x9B,  0x1D,  0xE2,  0x52,  0xD5, 	/* 1EFD0 */
+	0x63,  0x90,  0xE4,  0xE3,  0xF8,  0x20,  0x83,  0xFC,  0x20,  0x03,  0xFE,  0x55,  0x2A,  0x4C,  0x9F,  0x19, 	/* 1EFE0 */
+	0x0E,  0x3C,  0xA2,  0x4B,  0xBC,  0xE2,  0x4A,  0x3E,  0xAA,  0x09,  0xBE,  0x89,  0x6C,  0x2A,  0x1C,  0x2E, 	/* 1EFF0 */
+	0x0C,  0xA3,  0x21,  0x02,  0x3C,  0x22,  0x4F,  0xFC,  0x22,  0x42,  0x3E,  0x22,  0x07,  0xBE,  0x49,  0x64, 	/* 1F000 */
+	0xAA,  0x7C,  0x20,  0x0C,  0xA6,  0x04,  0x03,  0xF8,  0x28,  0x8F,  0xFE,  0x15,  0x03,  0xF8,  0xE1,  0x63, 	/* 1F010 */
+	0xF0,  0x21,  0x03,  0xFE,  0x55,  0x28,  0xAC,  0xA8,  0x01,  0x0F,  0xBC,  0xAA,  0x4A,  0xBC,  0xFA,  0x0A, 	/* 1F020 */
+	0xBE,  0xAA,  0x0F,  0xBE,  0x20,  0x22,  0x56,  0x25,  0x22,  0x8C,  0xAA,  0x21,  0x02,  0x3C,  0xFA,  0x48, 	/* 1F030 */
+	0xBC,  0x0A,  0x47,  0x3E,  0x52,  0x05,  0x3E,  0x51,  0x64,  0xAA,  0x84,  0x20,  0x0C,  0xAB,  0x01,  0x00, 	/* 1F040 */
+	0x3C,  0xFA,  0x4A,  0xBC,  0xAA,  0x4F,  0xBE,  0xAA,  0x0A,  0xBE,  0xA9,  0x6F,  0xAA,  0x04,  0x20,  0x0C, 	/* 1F050 */
+	0xAC,  0x28,  0x81,  0x50,  0xFF,  0xE8,  0x82,  0x3F,  0x02,  0x10,  0x3F,  0xE2,  0x00,  0x3F,  0xC1,  0x54, 	/* 1F060 */
+	0x4A,  0x48,  0x18,  0xBB,  0x41,  0x02,  0x7C,  0x04,  0x4B,  0xFC,  0x54,  0x41,  0x7E,  0x14,  0x05,  0x7E, 	/* 1F070 */
+	0x78,  0x24,  0xAA,  0x8A,  0x29,  0x0C,  0xBE,  0x01,  0x0F,  0xFC,  0x22,  0x44,  0xBC,  0xF6,  0x45,  0x3E, 	/* 1F080 */
+	0x7A,  0x09,  0x3E,  0x11,  0x6F,  0xEA,  0x14,  0x21,  0x0C,  0xBF,  0x21,  0x02,  0x3C,  0x52,  0x44,  0xBC, 	/* 1F090 */
+	0xFE,  0x40,  0x3E,  0x7A,  0x04,  0xBE,  0x49,  0x64,  0xAA,  0x7C,  0x20,  0x0C,  0x81,  0x21,  0x02,  0x3C, 	/* 1F0A0 */
+	0xFA,  0x45,  0x3C,  0x4A,  0x49,  0x7E,  0x32,  0x01,  0x3E,  0x29,  0x62,  0x2A,  0x44,  0x28,  0x0C,  0x84, 	/* 1F0B0 */
+	0x01,  0x0F,  0xBC,  0x32,  0x44,  0xBC,  0xF6,  0x42,  0x3E,  0x22,  0x0F,  0xBE,  0x21,  0x63,  0xAA,  0xE4, 	/* 1F0C0 */
+	0x20,  0x0C,  0x86,  0x28,  0x03,  0xEE,  0x52,  0x0B,  0xE0,  0x32,  0xF5,  0xF4,  0xD0,  0x45,  0xF4,  0x4B, 	/* 1F0D0 */
+	0x45,  0x54,  0x61,  0x44,  0x6C,  0x88,  0x01,  0x0F,  0xFC,  0x4A,  0x44,  0xBC,  0x7A,  0x44,  0xBE,  0x7A, 	/* 1F0E0 */
+	0x04,  0xBE,  0x49,  0x67,  0xAA,  0xCC,  0x20,  0x8C,  0x90,  0x01,  0x0F,  0xBC,  0x22,  0x46,  0xBC,  0x6A, 	/* 1F0F0 */
+	0x46,  0xBE,  0xB6,  0x0A,  0x3E,  0x29,  0x63,  0x2A,  0xC4,  0x20,  0x0C,  0x91,  0x01,  0x0F,  0xBC,  0x8A, 	/* 1F100 */
+	0x4F,  0xBC,  0x02,  0x4F,  0xBE,  0x8A,  0x0F,  0xBE,  0x89,  0x6F,  0xAA,  0x8C,  0x29,  0x8C,  0x99,  0x01, 	/* 1F110 */
+	0x07,  0xBC,  0x4A,  0x44,  0xBC,  0x7A,  0x44,  0xBE,  0x7A,  0x04,  0xBE,  0x79,  0x62,  0xAA,  0x44,  0x28, 	/* 1F120 */
+	0x0C,  0x9C,  0x49,  0x03,  0x3C,  0xFA,  0x42,  0xBC,  0xFA,  0x4A,  0x3E,  0xFA,  0x02,  0xBE,  0x69,  0x67, 	/* 1F130 */
+	0xAA,  0xA4,  0x22,  0x0C,  0x9D,  0x31,  0x0D,  0xBC,  0x56,  0x45,  0x3C,  0xFE,  0x45,  0x7E,  0x5A,  0x07, 	/* 1F140 */
+	0x3E,  0xD1,  0x64,  0xAA,  0x4C,  0x2C,  0x4C,  0x9E,  0x39,  0x81,  0x14,  0xFF,  0xE1,  0x14,  0xF8,  0x81, 	/* 1F150 */
+	0x36,  0x34,  0x23,  0xF8,  0x20,  0x83,  0xFE,  0x4A,  0xA8,  0x0C,  0xA0,  0x51,  0x05,  0x3C,  0x7E,  0x49, 	/* 1F160 */
+	0x3C,  0x12,  0x4F,  0xFE,  0x02,  0x07,  0xBE,  0x48,  0x24,  0xD6,  0x4D,  0x27,  0xCC,  0xA1,  0x09,  0x0E, 	/* 1F170 */
+	0xFC,  0x0A,  0x4F,  0xFC,  0x2A,  0x42,  0xBE,  0xBA,  0x0A,  0xBE,  0xA8,  0x2B,  0xAA,  0xC6,  0x28,  0x4C, 	/* 1F180 */
+	0xA4,  0x41,  0x07,  0x3C,  0xA2,  0x4F,  0xBC,  0xAA,  0x4F,  0xBE,  0xAA,  0x0A,  0xBE,  0xF9,  0x68,  0xAA, 	/* 1F190 */
+	0x8C,  0x29,  0x8C,  0xAC,  0x01,  0x0F,  0xFC,  0xB6,  0x4B,  0x7C,  0xFE,  0x4B,  0x7C,  0xB6,  0x0F,  0xFE, 	/* 1F1A0 */
+	0xB6,  0x0B,  0x7E,  0xB6,  0xAA,  0xD6,  0xAF,  0x41,  0x0F,  0xFC,  0xAA,  0x4F,  0xBC,  0xAA,  0x4F,  0xBE, 	/* 1F1B0 */
+	0x32,  0x05,  0x3E,  0xF9,  0x61,  0x2A,  0x14,  0x21,  0x0C,  0xB2,  0x49,  0x04,  0xBC,  0xFE,  0x44,  0xBC, 	/* 1F1C0 */
+	0xFE,  0x40,  0x3E,  0x7A,  0x04,  0xBE,  0x79,  0x64,  0xAA,  0x4C,  0x27,  0x8C,  0xBA,  0x10,  0x81,  0x1E, 	/* 1F1D0 */
+	0xFF,  0x22,  0x9E,  0x5F,  0x25,  0x5F,  0xDD,  0x07,  0x5E,  0x49,  0x65,  0x6A,  0x64,  0x24,  0x0C,  0x87, 	/* 1F1E0 */
+	0x21,  0x0F,  0xFC,  0x22,  0x4F,  0xBC,  0xAA,  0x4F,  0xBE,  0xAA,  0x0F,  0xBE,  0x31,  0x66,  0xAA,  0xA4, 	/* 1F1F0 */
+	0x22,  0x0C,  0x89,  0x11,  0x0F,  0xFC,  0x02,  0x47,  0xBC,  0x4A,  0x47,  0xBE,  0x02,  0x07,  0xBE,  0x1D, 	/* 1F200 */
+	0x6F,  0x2A,  0x14,  0x23,  0x0C,  0x8F,  0x1A,  0x0E,  0x7C,  0x04,  0x4A,  0xFC,  0xAC,  0x00,  0x7C,  0xFC, 	/* 1F210 */
+	0x02,  0x7E,  0xF8,  0x22,  0x2A,  0x54,  0x28,  0x0C,  0x9A,  0x01,  0x0F,  0xBC,  0xAA,  0x4F,  0xBC,  0x02, 	/* 1F220 */
+	0x4F,  0xBE,  0x02,  0x0F,  0xBE,  0x41,  0x67,  0x2A,  0x94,  0x23,  0x0C,  0xA4,  0x01,  0x0F,  0xBC,  0xAA, 	/* 1F230 */
+	0x42,  0x3C,  0xFA,  0x4A,  0xBE,  0xFA,  0x0A,  0xBE,  0xF9,  0x62,  0x2A,  0xFC,  0x22,  0x0C,  0xA9,  0x7C, 	/* 1F240 */
+	0x82,  0x9F,  0xFF,  0x42,  0x8C,  0x49,  0x23,  0xF0,  0x21,  0x03,  0xFE,  0x20,  0x03,  0xFC,  0x55,  0x48, 	/* 1F250 */
+	0x98,  0xAB,  0x21,  0x0F,  0xFC,  0x22,  0x4F,  0xBC,  0xEA,  0x4B,  0xBE,  0xFA,  0x02,  0x3E,  0x71,  0x66, 	/* 1F260 */
+	0xAA,  0xA4,  0x22,  0x0C,  0xAF,  0x55,  0x42,  0xA8,  0x44,  0x4F,  0xFE,  0x91,  0x29,  0xF2,  0x11,  0x01, 	/* 1F270 */
+	0xFC,  0x10,  0x01,  0xFC,  0x55,  0x48,  0x18,  0xB2,  0x51,  0x05,  0x3C,  0xAA,  0x45,  0x3C,  0xFA,  0x40, 	/* 1F280 */
+	0x3E,  0xFA,  0x06,  0xBE,  0xB9,  0x66,  0xAA,  0xBC,  0x22,  0x8C,  0xB4,  0x21,  0x02,  0x3C,  0xFA,  0x4A, 	/* 1F290 */
+	0xBC,  0x22,  0x47,  0xBE,  0xD2,  0x07,  0xBE,  0x51,  0x67,  0xAA,  0x54,  0x27,  0xCC,  0xB8,  0x01,  0x0F, 	/* 1F2A0 */
+	0xBC,  0x2A,  0x4F,  0xBC,  0x92,  0x4F,  0xBE,  0x6A,  0x0A,  0xBE,  0x79,  0x6A,  0xAA,  0x2C,  0x2D,  0x8C, 	/* 1F2B0 */
+	0xBA,  0x21,  0x0E,  0xBC,  0x22,  0x4E,  0xBC,  0x52,  0x48,  0xBE,  0x7E,  0x04,  0xBE,  0x79,  0x64,  0xAA, 	/* 1F2C0 */
+	0x4C,  0x25,  0x8C,  0xBB,  0x79,  0x04,  0xBC,  0x5A,  0x4F,  0xFC,  0x86,  0x47,  0xBE,  0x4A,  0x07,  0xBE, 	/* 1F2D0 */
+	0x49,  0x67,  0xAA,  0x4C,  0x25,  0x8C,  0x81,  0x39,  0x02,  0xBC,  0x76,  0x48,  0x3C,  0x3A,  0x42,  0xBE, 	/* 1F2E0 */
+	0x46,  0x08,  0x3E,  0x7D,  0x65,  0x6A,  0x54,  0x2F,  0xEC,  0x82,  0x21,  0x03,  0xBC,  0x4A,  0x4B,  0x3C, 	/* 1F2F0 */
+	0x22,  0x4C,  0x3E,  0x7A,  0x0A,  0x3E,  0xF9,  0x62,  0x2A,  0xAC,  0x2F,  0x8C,  0x84,  0x19,  0x0E,  0xBC, 	/* 1F300 */
+	0xAA,  0x45,  0x7C,  0x22,  0x4D,  0x3E,  0x2A,  0x0F,  0xBE,  0x21,  0x6F,  0xAA,  0x54,  0x28,  0x0C,  0x86, 	/* 1F310 */
+	0x41,  0x07,  0xBC,  0x42,  0x47,  0xFC,  0x2A,  0x4B,  0xBE,  0xAA,  0x0B,  0xBE,  0xA9,  0x6F,  0xEA,  0x24, 	/* 1F320 */
+	0x2C,  0x0C,  0x8F,  0x21,  0x0F,  0xFC,  0x22,  0x47,  0xBC,  0x4A,  0x47,  0xBE,  0x4A,  0x07,  0xBE,  0x49, 	/* 1F330 */
+	0x6F,  0xEA,  0x32,  0x2C,  0x8C,  0x93,  0x11,  0x07,  0xFC,  0x42,  0x46,  0xBC,  0x7E,  0x46,  0xBE,  0x6A, 	/* 1F340 */
+	0x06,  0xBE,  0xB9,  0x68,  0x2A,  0x54,  0x2A,  0x8C,  0x99,  0x21,  0x0F,  0xBC,  0x51,  0x4F,  0xB4,  0x22, 	/* 1F350 */
+	0xA5,  0xF8,  0x10,  0x81,  0xFE,  0x10,  0x01,  0xFE,  0x2A,  0xA4,  0x0C,  0xA6,  0x49,  0x05,  0x3C,  0x7E, 	/* 1F360 */
+	0x4D,  0x3C,  0x7A,  0x45,  0x3E,  0x7A,  0x05,  0x3E,  0x79,  0x60,  0x2A,  0x54,  0x2A,  0x8C,  0xAD,  0x19, 	/* 1F370 */
+	0x0E,  0xBC,  0xB2,  0x4F,  0xBC,  0x72,  0x4A,  0xBE,  0x22,  0x0F,  0xBE,  0xA9,  0x6F,  0xAA,  0xAC,  0x2F, 	/* 1F380 */
+	0x8C,  0xAF,  0x21,  0x0F,  0xBC,  0xAA,  0x45,  0x3C,  0xFE,  0x44,  0xBE,  0x7A,  0x04,  0xBE,  0x79,  0x66, 	/* 1F390 */
+	0xAA,  0xA4,  0x22,  0x0C,  0xB2,  0x21,  0x2F,  0xFC,  0x51,  0x87,  0x2A,  0xAC,  0x63,  0xF8,  0x20,  0x83, 	/* 1F3A0 */
+	0xFE,  0x20,  0x03,  0xFE,  0x55,  0x28,  0xAC,  0xB8,  0x01,  0x0F,  0xBC,  0x52,  0x4F,  0xBC,  0x32,  0x4D, 	/* 1F3B0 */
+	0x3E,  0x32,  0x0F,  0xBE,  0xA9,  0x6D,  0xAA,  0xBC,  0x28,  0x8C,  0xB9,  0x02,  0x07,  0xFE,  0x4A,  0x85, 	/* 1F3C0 */
+	0x7E,  0x74,  0x85,  0xFE,  0x51,  0x05,  0xFC,  0x50,  0x05,  0xFE,  0x95,  0x2A,  0x2C,  0xBA,  0x79,  0xC4, 	/* 1F3D0 */
+	0xA4,  0x7D,  0x81,  0xBC,  0x55,  0x6F,  0xFC,  0x20,  0x83,  0xFE,  0x20,  0x03,  0xFE,  0x55,  0x2A,  0x8C, 	/* 1F3E0 */
+	0xBD,  0x1A,  0x06,  0x5C,  0x4A,  0x47,  0x5C,  0x4A,  0x4F,  0xFE,  0xA1,  0x2B,  0xF0,  0x21,  0x03,  0xFE, 	/* 1F3F0 */
+	0x55,  0x48,  0x18,  0x9A,  0xF9,  0x0A,  0xBC,  0xFA,  0x4A,  0xBC,  0xFA,  0x45,  0x3E,  0xAA,  0x04,  0x3E, 	/* 1F400 */
+	0xF9,  0x6D,  0x2A,  0x34,  0x2C,  0x8C,  0x9B,  0x51,  0x0F,  0xBC,  0x52,  0x4F,  0xBC,  0xAA,  0x4F,  0xBE, 	/* 1F410 */
+	0x52,  0x0F,  0xBE,  0x51,  0x67,  0xAA,  0x50,  0x27,  0xCC,  0x9E,  0x40,  0x4A,  0xEA,  0x40,  0x4F,  0xFE, 	/* 1F420 */
+	0x75,  0x4B,  0xFA,  0x20,  0x83,  0xF8,  0x20,  0x83,  0xFE,  0x2A,  0x44,  0x38,  0xB5,  0x08,  0x00,  0xFE, 	/* 1F430 */
+	0x08,  0x0F,  0xFC,  0x84,  0x4B,  0x14,  0x8A,  0x4E,  0x4C,  0x8A,  0x49,  0x54,  0xA4,  0xCF,  0xFC,  0xB8, 	/* 1F440 */
+	0x21,  0x03,  0xA8,  0x24,  0x4F,  0xFA,  0x89,  0x0D,  0xFC,  0xBD,  0x4A,  0xFC,  0xE9,  0x0D,  0x98,  0x8A, 	/* 1F450 */
+	0x4F,  0xC2,  0xB9,  0x20,  0x83,  0xCA,  0x23,  0xFF,  0xC8,  0x97,  0xAC,  0x4A,  0xAF,  0xA9,  0x6A,  0xAF, 	/* 1F460 */
+	0xCC,  0x4D,  0x95,  0x3F,  0xE1,  0xBD,  0x01,  0x0F,  0xBE,  0xA4,  0x8F,  0xBF,  0x8B,  0x6F,  0xAA,  0xA3, 	/* 1F470 */
+	0x6F,  0xBE,  0x00,  0x07,  0xFC,  0x4A,  0x4F,  0xFE,  0xBF,  0x02,  0x07,  0xFE,  0x49,  0x07,  0xFE,  0x49, 	/* 1F480 */
+	0x27,  0xFE,  0x51,  0x05,  0x10,  0x5D,  0xE5,  0x10,  0x95,  0x23,  0x8E,  0x81,  0x08,  0x01,  0xF8,  0x29, 	/* 1F490 */
+	0x0F,  0xFE,  0x49,  0x07,  0xFC,  0x49,  0x47,  0xFC,  0x51,  0x25,  0xDC,  0x91,  0x23,  0xEE,  0x88,  0x02, 	/* 1F4A0 */
+	0x07,  0xFE,  0x45,  0x07,  0xFE,  0x45,  0x27,  0xFE,  0x51,  0x25,  0xDC,  0x51,  0x2B,  0xEE,  0x82,  0x07, 	/* 1F4B0 */
+	0xFE,  0x8B,  0x02,  0x07,  0xFE,  0x49,  0x47,  0xFC,  0x51,  0x29,  0xCE,  0x3F,  0x40,  0xA8,  0xFF,  0xE0, 	/* 1F4C0 */
+	0xF8,  0x72,  0x60,  0x20,  0x8C,  0x04,  0x07,  0xFE,  0x49,  0x47,  0xFC,  0x51,  0x29,  0xFE,  0x28,  0x42, 	/* 1F4D0 */
+	0xFC,  0x22,  0x0F,  0xFE,  0x09,  0x87,  0x04,  0x91,  0x04,  0x07,  0xFE,  0x4A,  0x47,  0xFC,  0x49,  0x27, 	/* 1F4E0 */
+	0xFE,  0xA0,  0x43,  0xDC,  0x20,  0x43,  0xFC,  0x09,  0x27,  0x0E,  0x92,  0x11,  0x47,  0xD4,  0x53,  0xE7, 	/* 1F4F0 */
+	0xD4,  0x55,  0xC5,  0x54,  0x7D,  0xC6,  0x94,  0x7F,  0xEA,  0x88,  0x3B,  0x46,  0x64,  0x93,  0x10,  0x87, 	/* 1F500 */
+	0xFE,  0x39,  0xC5,  0x6A,  0x7F,  0xE4,  0x90,  0x7F,  0xC4,  0x94,  0x7F,  0xE5,  0xDC,  0x51,  0x2B,  0xCE, 	/* 1F510 */
+	0x95,  0x04,  0x07,  0xFE,  0x49,  0x47,  0xFC,  0x51,  0x2B,  0xFE,  0x2F,  0x42,  0x24,  0x3F,  0xC2,  0x74, 	/* 1F520 */
+	0x2A,  0xC3,  0xFC,  0x97,  0xFB,  0xE0,  0x00,  0xFB,  0xEA,  0xAA,  0x04,  0x07,  0xFE,  0x4A,  0x47,  0xFC, 	/* 1F530 */
+	0x51,  0x05,  0xDC,  0x51,  0x2B,  0xCE,  0x9D,  0x04,  0x07,  0xFE,  0x4A,  0x47,  0xFC,  0x51,  0x0B,  0xEE, 	/* 1F540 */
+	0x28,  0x43,  0xFF,  0x2A,  0x4F,  0x94,  0x28,  0x44,  0x8C,  0x9F,  0x12,  0xA7,  0xDC,  0x57,  0xE7,  0xDC, 	/* 1F550 */
+	0x56,  0xA5,  0x4C,  0x7F,  0xE6,  0xB4,  0x7B,  0x46,  0xDE,  0xA9,  0x47,  0x64,  0xA5,  0x04,  0x0F,  0xFE, 	/* 1F560 */
+	0x24,  0x82,  0x48,  0x55,  0x48,  0xA2,  0x31,  0x8C,  0x66,  0x19,  0x06,  0x60,  0x0B,  0x07,  0x0C,  0xA6, 	/* 1F570 */
+	0x04,  0x07,  0xFC,  0x04,  0x07,  0xFC,  0x04,  0x0F,  0xFE,  0x08,  0x01,  0xF8,  0x69,  0x00,  0x60,  0x1B, 	/* 1F580 */
+	0x0E,  0x0E,  0xA9,  0x21,  0x0F,  0xD0,  0x2B,  0xC6,  0x90,  0x75,  0x0A,  0x7E,  0x39,  0x02,  0x98,  0x6A, 	/* 1F590 */
+	0x49,  0x42,  0x2C,  0x0C,  0x3F,  0xAA,  0x20,  0x0F,  0xFE,  0x28,  0x86,  0x8E,  0x76,  0xAA,  0x2A,  0x3B, 	/* 1F5A0 */
+	0xE2,  0xA2,  0x68,  0x29,  0x0C,  0x2C,  0x0C,  0x3F,  0xAD,  0x22,  0x0F,  0xA0,  0x2B,  0xE6,  0xC2,  0x77, 	/* 1F5B0 */
+	0xAA,  0x2A,  0x3B,  0xC2,  0xA0,  0x6A,  0x29,  0x1E,  0x2C,  0x0C,  0x3F,  0xB8,  0x21,  0x0F,  0xD0,  0x23, 	/* 1F5C0 */
+	0xC7,  0x90,  0x21,  0x0F,  0xFE,  0x21,  0x03,  0x98,  0x6A,  0x49,  0x42,  0x2C,  0x0C,  0x3F,  0xB9,  0x22, 	/* 1F5D0 */
+	0x02,  0x3E,  0xF2,  0x22,  0x36,  0xF7,  0xA2,  0x12,  0xFF,  0xE4,  0xBA,  0xAD,  0x61,  0x12,  0x2C,  0xCC, 	/* 1F5E0 */
+	0x3F,  0xBA,  0x2F,  0xEF,  0x20,  0x24,  0x0F,  0xFE,  0x2A,  0xAF,  0xBA,  0x2A,  0xA7,  0xBA,  0xDA,  0xA3, 	/* 1F5F0 */
+	0xFE,  0x4C,  0x08,  0x3F,  0xBB,  0x02,  0x07,  0xFE,  0x48,  0x84,  0x88,  0x7F,  0xE4,  0x88,  0x5D,  0xC5, 	/* 1F600 */
+	0xDC,  0x6A,  0xAA,  0xAA,  0x88,  0x80,  0x88,  0xBC,  0x04,  0x07,  0xFE,  0x48,  0x87,  0xFE,  0x5A,  0xC6, 	/* 1F610 */
+	0xAA,  0x42,  0x04,  0x48,  0x59,  0x08,  0x64,  0x87,  0xE3,  0x82,  0xBE,  0x04,  0x07,  0xFE,  0x48,  0x87, 	/* 1F620 */
+	0xFE,  0x48,  0x86,  0xAA,  0x6A,  0xA4,  0x38,  0x5E,  0x08,  0x3C,  0xBE,  0x20,  0x1E,  0xBF,  0x02,  0x07, 	/* 1F630 */
+	0xFE,  0x48,  0x87,  0xFE,  0x5D,  0xC6,  0xAA,  0x4F,  0xC4,  0x84,  0x4F,  0xC9,  0xFE,  0x90,  0x21,  0xFE, 	/* 1F640 */
+	0x84,  0x11,  0x07,  0xFC,  0x11,  0x0F,  0xFE,  0x04,  0x03,  0xF8,  0x24,  0x83,  0xF8,  0x24,  0x83,  0xF8, 	/* 1F650 */
+	0x11,  0x8E,  0x06,  0x8C,  0x14,  0x06,  0xBC,  0x44,  0x47,  0xBC,  0xFF,  0xE9,  0x12,  0x7F,  0xC1,  0x10, 	/* 1F660 */
+	0xFF,  0xE2,  0x48,  0x3F,  0x87,  0x1C,  0x8D,  0x01,  0xC3,  0xE0,  0x04,  0x0F,  0xFE,  0x15,  0x06,  0x4C, 	/* 1F670 */
+	0x0A,  0x03,  0x58,  0xD5,  0x60,  0xE0,  0x75,  0xC0,  0x40,  0x8E,  0x1A,  0x0E,  0x3E,  0x24,  0xAF,  0x92, 	/* 1F680 */
+	0x72,  0x2A,  0x4C,  0x2A,  0x03,  0x58,  0xD6,  0xE1,  0xD0,  0x64,  0xC0,  0xC0,  0x8F,  0x19,  0x0E,  0x10, 	/* 1F690 */
+	0x21,  0x0F,  0xDE,  0x71,  0x0A,  0x90,  0x73,  0xCA,  0xE4,  0xEA,  0x47,  0x24,  0xAA,  0x46,  0x3C,  0x90, 	/* 1F6A0 */
+	0x19,  0x0E,  0xFE,  0x26,  0xCF,  0xD4,  0x76,  0xCA,  0xFC,  0x31,  0x06,  0xFE,  0xAD,  0xA7,  0x7E,  0xAC, 	/* 1F6B0 */
+	0x26,  0x46,  0x92,  0x00,  0x07,  0xF8,  0x48,  0x87,  0xF8,  0x48,  0x87,  0xF8,  0x08,  0x07,  0xF8,  0x08, 	/* 1F6C0 */
+	0x0F,  0xFC,  0x52,  0x48,  0x92,  0x94,  0x01,  0x0F,  0x90,  0xAA,  0x8F,  0xA8,  0xAC,  0x4F,  0xBE,  0x20, 	/* 1F6D0 */
+	0x1F,  0xBC,  0x20,  0x4F,  0xC4,  0x50,  0x8A,  0x88,  0x98,  0x7C,  0xA5,  0xC9,  0x74,  0x85,  0x7F,  0x7C, 	/* 1F6E0 */
+	0x81,  0x08,  0x7C,  0x81,  0x1C,  0x1D,  0x4E,  0x12,  0x56,  0x2A,  0xA1,  0x99,  0x7D,  0x45,  0x52,  0x7D, 	/* 1F6F0 */
+	0x05,  0x7E,  0x7D,  0x01,  0x18,  0x7E,  0x41,  0x42,  0xFC,  0x04,  0xA4,  0x49,  0x28,  0x92,  0x9B,  0x12, 	/* 1F700 */
+	0x42,  0xFE,  0xE1,  0x03,  0xFC,  0x24,  0xA3,  0xF8,  0x24,  0x87,  0xFC,  0x04,  0x0F,  0xFE,  0x52,  0x48, 	/* 1F710 */
+	0x92,  0x9C,  0x01,  0x0F,  0x90,  0xAD,  0x4F,  0xD4,  0xAD,  0x4F,  0xFC,  0x21,  0x0F,  0x90,  0x25,  0x2F, 	/* 1F720 */
+	0xD2,  0x55,  0x2A,  0xFE,  0x9D,  0x02,  0x8F,  0xA8,  0xAB,  0xEF,  0xAA,  0xAC,  0xAF,  0xDA,  0x22,  0xAF, 	/* 1F730 */
+	0xAA,  0x25,  0xAF,  0xFA,  0x51,  0x2A,  0xAC,  0x9E,  0x01,  0x0F,  0x90,  0xA9,  0x0F,  0x9E,  0xA9,  0x0F, 	/* 1F740 */
+	0x90,  0x23,  0xCF,  0xA4,  0x22,  0x4F,  0xE4,  0x52,  0x4A,  0xBC,  0xA0,  0x01,  0x0F,  0x90,  0xAF,  0xEF, 	/* 1F750 */
+	0x90,  0xA9,  0x0F,  0xFC,  0x20,  0x0F,  0xBC,  0x22,  0x4F,  0xE4,  0x52,  0x4A,  0xBC,  0xA5,  0x01,  0x0F, 	/* 1F760 */
+	0xFE,  0xA8,  0x0F,  0xBC,  0xAA,  0x4F,  0xA4,  0x23,  0xCF,  0x88,  0x22,  0xCF,  0xAA,  0x54,  0xAA,  0x98, 	/* 1F770 */
+	0xA8,  0x24,  0x81,  0x50,  0xFF,  0xE8,  0x02,  0x3F,  0x83,  0x58,  0x2E,  0x87,  0xFC,  0x04,  0x0F,  0xFE, 	/* 1F780 */
+	0x2A,  0x84,  0x54,  0xAF,  0x00,  0x8F,  0xFE,  0xAA,  0x4F,  0x98,  0xAF,  0xEF,  0x80,  0x23,  0xCF,  0xA4, 	/* 1F790 */
+	0x23,  0xCF,  0xA4,  0x52,  0x4A,  0xBC,  0xB4,  0x24,  0x83,  0x58,  0x55,  0xFB,  0xF2,  0x35,  0x25,  0xFA, 	/* 1F7A0 */
+	0xD5,  0xC5,  0xF4,  0x44,  0xC5,  0xF4,  0x4A,  0x25,  0x52,  0xB6,  0x7F,  0xE5,  0x4A,  0x5F,  0xE5,  0x48, 	/* 1F7B0 */
+	0x5D,  0x49,  0x62,  0x3F,  0x82,  0xD8,  0x7F,  0xC0,  0x40,  0xFF,  0xE5,  0x54,  0xB7,  0x01,  0x0F,  0xFE, 	/* 1F7C0 */
+	0xA9,  0x0F,  0xFE,  0xAD,  0xAF,  0xFE,  0x22,  0x47,  0xBC,  0x22,  0x4F,  0xFC,  0x6A,  0x49,  0x42,  0xB9, 	/* 1F7D0 */
+	0x0A,  0x02,  0xA8,  0xFF,  0xE1,  0x50,  0x24,  0x87,  0xFC,  0xC4,  0x65,  0x54,  0x55,  0x45,  0x54,  0x65, 	/* 1F7E0 */
+	0x44,  0x4C,  0xBB,  0x21,  0x0A,  0x94,  0x71,  0x2F,  0xFE,  0x21,  0x0F,  0xD4,  0xA5,  0x4E,  0xD4,  0xEC, 	/* 1F7F0 */
+	0x8E,  0xD8,  0xA6,  0x4A,  0xC2,  0xBC,  0x20,  0x8A,  0x8A,  0x77,  0xFF,  0xC8,  0x23,  0xEF,  0xAA,  0xAB, 	/* 1F800 */
+	0xEF,  0xAA,  0xFB,  0xEE,  0xAA,  0xAA,  0xA9,  0xA6,  0xBD,  0x7F,  0xC4,  0xA4,  0x7B,  0xC0,  0xA0,  0x7B, 	/* 1F810 */
+	0xC4,  0xA4,  0x7B,  0xC4,  0xA4,  0x7B,  0xC0,  0xA0,  0x08,  0x20,  0x7E,  0x87,  0x11,  0x07,  0xDE,  0x13, 	/* 1F820 */
+	0x4F,  0xC8,  0x29,  0x45,  0xA2,  0x3F,  0x82,  0xA8,  0x7B,  0xC4,  0xA4,  0x7B,  0xD0,  0x7F,  0x88,  0xA9, 	/* 1F830 */
+	0x07,  0x1E,  0xFB,  0x4A,  0xC8,  0xF9,  0x4A,  0xA2,  0x3F,  0x82,  0xA8,  0x7B,  0xC4,  0xA4,  0x7B,  0xD0, 	/* 1F840 */
+	0x7F,  0x8E,  0x5F,  0x45,  0x14,  0x5F,  0x45,  0x14,  0x5F,  0x45,  0x14,  0x7F,  0xC0,  0xA0,  0xFB,  0xE2, 	/* 1F850 */
+	0xA4,  0x4A,  0x44,  0xA4,  0x93,  0x21,  0x0F,  0x90,  0x27,  0xCF,  0x10,  0x01,  0x0F,  0xFC,  0x88,  0x4F, 	/* 1F860 */
+	0xC4,  0x4A,  0x85,  0x10,  0x3A,  0x8C,  0x46,  0x95,  0x20,  0x8F,  0xFE,  0x48,  0x87,  0xBE,  0x51,  0x43, 	/* 1F870 */
+	0x88,  0xEF,  0x61,  0x90,  0x6E,  0x01,  0x98,  0xE2,  0x60,  0xC0,  0xA0,  0xF3,  0xC8,  0x04,  0xFB,  0xC8, 	/* 1F880 */
+	0x04,  0xFF,  0xC4,  0x48,  0x77,  0x84,  0x48,  0x77,  0x84,  0x4A,  0x77,  0x6C,  0xC2,  0xA1,  0x48,  0x42, 	/* 1F890 */
+	0x48,  0x3F,  0x82,  0x48,  0x24,  0x83,  0xF8,  0x24,  0x82,  0x48,  0x3F,  0x84,  0x4A,  0x44,  0x68,  0x42, 	/* 1F8A0 */
+	0xAC,  0x20,  0x85,  0xC8,  0x44,  0x86,  0xFE,  0x46,  0xA7,  0xEA,  0x5B,  0xE7,  0xAA,  0x5A,  0xA7,  0xBF, 	/* 1F8B0 */
+	0x56,  0x19,  0x1F,  0xBB,  0x04,  0x01,  0xF0,  0x11,  0x01,  0xF0,  0x11,  0x03,  0xF8,  0x24,  0x83,  0xF8, 	/* 1F8C0 */
+	0x24,  0x8F,  0xFE,  0x11,  0x06,  0x10,  0xBE,  0x10,  0x03,  0xDE,  0x24,  0x83,  0xC8,  0x24,  0x87,  0xFF, 	/* 1F8D0 */
+	0x54,  0x87,  0xC8,  0x54,  0x8F,  0xE8,  0x28,  0x84,  0x88,  0x8A,  0x04,  0x0F,  0xFE,  0x0A,  0x4F,  0x58, 	/* 1F8E0 */
+	0x55,  0x45,  0x54,  0xA1,  0xA3,  0xF8,  0x20,  0x83,  0xF8,  0x20,  0x84,  0x08,  0x8B,  0x04,  0x0F,  0xFE, 	/* 1F8F0 */
+	0x0A,  0x0F,  0x5E,  0x55,  0x45,  0x54,  0xBF,  0xA4,  0x04,  0x7F,  0xC5,  0x54,  0x64,  0xC8,  0x44,  0x8E, 	/* 1F900 */
+	0x04,  0x0F,  0xFE,  0x0A,  0x0F,  0x5E,  0x55,  0x45,  0x54,  0xAF,  0x62,  0x94,  0x2F,  0x42,  0x94,  0x2F, 	/* 1F910 */
+	0x45,  0x9C,  0x8F,  0x04,  0x0F,  0xFE,  0x0A,  0x6F,  0x58,  0x55,  0x6F,  0xFC,  0x40,  0x47,  0xFC,  0x4A, 	/* 1F920 */
+	0x45,  0xB4,  0x4A,  0x4B,  0xF4,  0x92,  0x04,  0x02,  0x7C,  0x24,  0x0F,  0xFE,  0x49,  0x45,  0xB4,  0x64, 	/* 1F930 */
+	0xC7,  0xFC,  0x49,  0x45,  0xB4,  0x64,  0xC7,  0xFC,  0x94,  0x11,  0x05,  0xD0,  0x51,  0x0F,  0xF2,  0xAD, 	/* 1F940 */
+	0x4D,  0x58,  0x85,  0x0F,  0xD0,  0xAD,  0x0D,  0x50,  0x85,  0x2F,  0xCE,  0x9F,  0x10,  0x05,  0xDE,  0x51, 	/* 1F950 */
+	0x2F,  0xD2,  0xAD,  0xED,  0x52,  0x85,  0x2F,  0xDE,  0xAD,  0x2D,  0x52,  0x85,  0x2F,  0xFF,  0xA0,  0x10, 	/* 1F960 */
+	0x05,  0xFE,  0x50,  0xAF,  0xCA,  0xAD,  0x2D,  0x6C,  0x84,  0x0F,  0xDE,  0xAD,  0x2D,  0x52,  0x85,  0x2F, 	/* 1F970 */
+	0xDE,  0xA1,  0x10,  0x85,  0xC8,  0x51,  0x4F,  0xD4,  0xAF,  0xAD,  0x41,  0x87,  0xEF,  0xCA,  0xAC,  0xAD, 	/* 1F980 */
+	0x4C,  0x84,  0x8F,  0xC8,  0xA2,  0x10,  0x85,  0xC8,  0x51,  0x4F,  0xD4,  0xA7,  0xAE,  0xC0,  0xB7,  0xEF, 	/* 1F990 */
+	0xD2,  0xB5,  0x2E,  0xD2,  0xA5,  0xCF,  0xD0,  0xA3,  0x11,  0x05,  0xD0,  0x51,  0x0F,  0xDE,  0xAE,  0x2D, 	/* 1F9A0 */
+	0x7A,  0x86,  0xAF,  0xEA,  0xAF,  0xAD,  0x42,  0x84,  0x2F,  0xCC,  0xA6,  0x10,  0x05,  0xDE,  0x51,  0x2F, 	/* 1F9B0 */
+	0xDE,  0xAD,  0x2D,  0x52,  0x85,  0xEF,  0xD9,  0xAD,  0x6D,  0x54,  0x85,  0x2F,  0xF9,  0xA7,  0x20,  0x0F, 	/* 1F9C0 */
+	0xFE,  0x21,  0x2F,  0x12,  0x3A,  0x6E,  0x78,  0x24,  0x0F,  0xFE,  0x55,  0x47,  0xFC,  0x64,  0xC7,  0xFC, 	/* 1F9D0 */
+	0xAA,  0x20,  0x0B,  0xBC,  0xA2,  0x4F,  0xE4,  0xAB,  0xCD,  0x88,  0x8A,  0x8F,  0xAE,  0xAA,  0x8D,  0xA8, 	/* 1F9E0 */
+	0x8D,  0x8F,  0x86,  0xAC,  0x10,  0x05,  0xFE,  0x50,  0x8F,  0xFC,  0xAD,  0x4D,  0x54,  0x87,  0xFF,  0xC0, 	/* 1F9F0 */
+	0xAD,  0xED,  0x52,  0x85,  0x2F,  0xDE,  0xB2,  0x20,  0x6B,  0xB8,  0xA0,  0x8F,  0xFE,  0xAA,  0xAD,  0xBE, 	/* 1FA00 */
+	0x88,  0x8F,  0xBE,  0xAA,  0xAD,  0xBE,  0x8A,  0x2F,  0xA6,  0xB6,  0x10,  0x05,  0xFE,  0x52,  0xAF,  0xFE, 	/* 1FA10 */
+	0xAC,  0x0D,  0x5C,  0x84,  0x0F,  0xFE,  0xAD,  0x0D,  0x5E,  0x84,  0x2F,  0xCC,  0xB7,  0x23,  0xEB,  0xA2, 	/* 1FA20 */
+	0xA3,  0xEF,  0xE0,  0xAB,  0xED,  0xA8,  0x8B,  0x4F,  0xBE,  0xAA,  0xAD,  0xBE,  0x8C,  0x8F,  0xBE,  0x8D, 	/* 1FA30 */
+	0x22,  0x02,  0x3E,  0xFE,  0x08,  0xBC,  0x50,  0x4F,  0xFC,  0x4A,  0x07,  0xBC,  0x4A,  0x07,  0xBC,  0x4A, 	/* 1FA40 */
+	0x25,  0x9E,  0x95,  0x04,  0x01,  0xF0,  0xF1,  0xE1,  0xF0,  0x21,  0x0F,  0xBE,  0x50,  0x4F,  0xBC,  0x52, 	/* 1FA50 */
+	0x07,  0x3C,  0x52,  0x25,  0x1E,  0x9C,  0x1F,  0x02,  0x20,  0xFF,  0xC4,  0xA4,  0xFB,  0xC2,  0xA0,  0xFF, 	/* 1FA60 */
+	0xE2,  0xAA,  0xFB,  0x62,  0xFE,  0xE8,  0x00,  0x7E,  0x9D,  0x13,  0x8E,  0x48,  0x29,  0x02,  0xFE,  0xFA, 	/* 1FA70 */
+	0xA2,  0xFE,  0x71,  0xC6,  0xDA,  0xA5,  0x6A,  0xFE,  0x25,  0x02,  0xCE,  0xA0,  0x04,  0x00,  0xA0,  0x31, 	/* 1FA80 */
+	0x8D,  0xF6,  0x00,  0x0E,  0xEE,  0xAA,  0xAF,  0xFE,  0x4A,  0x47,  0xFC,  0x4A,  0x44,  0xAC,  0x81,  0x00, 	/* 1FA90 */
+	0x00,  0x60,  0x06,  0x00,  0x60,  0x04,  0x00,  0x40,  0x04,  0x00,  0x40,  0x00,  0x00,  0x40,  0x04,  0x00, 	/* 1FAA0 */
+	0x00,  0x83,  0x08,  0x80,  0x88,  0x08,  0x87,  0xFE,  0x11,  0x01,  0x10,  0x11,  0x01,  0x10,  0xFF,  0xC2, 	/* 1FAB0 */
+	0x20,  0x22,  0x02,  0x20,  0x84,  0x0A,  0x01,  0xE8,  0x2B,  0x82,  0xA8,  0x1A,  0x00,  0xE0,  0x0A,  0x00, 	/* 1FAC0 */
+	0xB0,  0x2A,  0x83,  0xA8,  0x2F,  0x00,  0xA0,  0x85,  0x00,  0x03,  0x02,  0x48,  0x44,  0x88,  0x31,  0x00, 	/* 1FAD0 */
+	0x20,  0x04,  0x00,  0x8C,  0x11,  0x22,  0x12,  0x40,  0xC0,  0x00,  0x86,  0x00,  0x01,  0xC0,  0x22,  0x02, 	/* 1FAE0 */
+	0x20,  0x24,  0x01,  0x84,  0x28,  0x44,  0x48,  0x43,  0x02,  0x30,  0x1C,  0xC0,  0x00,  0x88,  0x00,  0x40, 	/* 1FAF0 */
+	0x08,  0x01,  0x00,  0x10,  0x02,  0x00,  0x20,  0x02,  0x00,  0x20,  0x01,  0x00,  0x10,  0x00,  0x80,  0x04, 	/* 1FB00 */
+	0x89,  0x20,  0x01,  0x00,  0x08,  0x00,  0x80,  0x04,  0x00,  0x40,  0x04,  0x00,  0x40,  0x08,  0x00,  0x80, 	/* 1FB10 */
+	0x10,  0x02,  0x00,  0x8A,  0x00,  0x00,  0x00,  0x00,  0x00,  0x40,  0x35,  0x80,  0xE0,  0x04,  0x00,  0xE0, 	/* 1FB20 */
+	0x35,  0x80,  0x40,  0x00,  0x00,  0x00,  0x8B,  0x00,  0x00,  0x40,  0x04,  0x00,  0x40,  0x04,  0x07,  0xFC, 	/* 1FB30 */
+	0x04,  0x00,  0x40,  0x04,  0x00,  0x40,  0x00,  0x00,  0x00,  0x8C,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00, 	/* 1FB40 */
+	0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x02,  0x00,  0x20,  0x04,  0x00,  0x8D,  0x00,  0x00,  0x00, 	/* 1FB50 */
+	0x00,  0x00,  0x00,  0x00,  0x03,  0xFC,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x8E, 	/* 1FB60 */
+	0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x06,  0x00,  0x60, 	/* 1FB70 */
+	0x00,  0x00,  0x8F,  0x00,  0x10,  0x02,  0x00,  0x40,  0x08,  0x01,  0x00,  0x20,  0x04,  0x00,  0x80,  0x10, 	/* 1FB80 */
+	0x02,  0x00,  0x40,  0x08,  0x00,  0x90,  0x00,  0x00,  0xE0,  0x11,  0x02,  0x08,  0x20,  0x82,  0x08,  0x20, 	/* 1FB90 */
+	0x82,  0x08,  0x20,  0x81,  0x10,  0x0E,  0x00,  0x00,  0x91,  0x00,  0x00,  0x40,  0x04,  0x01,  0xC0,  0x04, 	/* 1FBA0 */
+	0x00,  0x40,  0x04,  0x00,  0x40,  0x04,  0x00,  0x40,  0x0E,  0x00,  0x00,  0x92,  0x00,  0x00,  0xF0,  0x10, 	/* 1FBB0 */
+	0x81,  0x08,  0x00,  0x80,  0x10,  0x02,  0x00,  0x40,  0x08,  0x01,  0x00,  0x1F,  0x80,  0x00,  0x93,  0x00, 	/* 1FBC0 */
+	0x00,  0xE0,  0x11,  0x00,  0x08,  0x01,  0x00,  0x60,  0x01,  0x00,  0x08,  0x00,  0x81,  0x10,  0x0E,  0x00, 	/* 1FBD0 */
+	0x00,  0x94,  0x00,  0x00,  0x20,  0x06,  0x00,  0xA0,  0x0A,  0x01,  0x20,  0x12,  0x02,  0x20,  0x3F,  0x80, 	/* 1FBE0 */
+	0x20,  0x07,  0x00,  0x00,  0x95,  0x00,  0x01,  0xF8,  0x10,  0x01,  0x00,  0x16,  0x01,  0x90,  0x10,  0x80, 	/* 1FBF0 */
+	0x08,  0x00,  0x81,  0x10,  0x0E,  0x00,  0x00,  0x96,  0x00,  0x00,  0xE0,  0x11,  0x02,  0x00,  0x20,  0x02, 	/* 1FC00 */
+	0xE0,  0x31,  0x02,  0x08,  0x20,  0x81,  0x10,  0x0E,  0x00,  0x00,  0x97,  0x00,  0x01,  0xF8,  0x10,  0x81, 	/* 1FC10 */
+	0x08,  0x01,  0x00,  0x10,  0x02,  0x00,  0x20,  0x04,  0x00,  0x40,  0x04,  0x00,  0x00,  0x98,  0x00,  0x00, 	/* 1FC20 */
+	0xE0,  0x11,  0x02,  0x08,  0x11,  0x00,  0xE0,  0x11,  0x02,  0x08,  0x20,  0x81,  0x10,  0x0E,  0x00,  0x00, 	/* 1FC30 */
+	0x99,  0x00,  0x00,  0xE0,  0x11,  0x02,  0x08,  0x20,  0x81,  0x18,  0x0E,  0x80,  0x08,  0x20,  0x81,  0x10, 	/* 1FC40 */
+	0x0E,  0x00,  0x00,  0x9A,  0x00,  0x00,  0x00,  0x00,  0x00,  0x40,  0x04,  0x00,  0x00,  0x00,  0x00,  0x00, 	/* 1FC50 */
+	0x04,  0x00,  0x40,  0x00,  0x00,  0x00,  0x9B,  0x00,  0x00,  0x00,  0x00,  0x00,  0x40,  0x04,  0x00,  0x00, 	/* 1FC60 */
+	0x00,  0x00,  0x00,  0x04,  0x00,  0x40,  0x08,  0x00,  0x00,  0x9C,  0x00,  0x00,  0x0C,  0x03,  0x00,  0xC0, 	/* 1FC70 */
+	0x30,  0x04,  0x00,  0x30,  0x00,  0xC0,  0x03,  0x00,  0x0C,  0x00,  0x00,  0x00,  0x9D,  0x00,  0x00,  0x00, 	/* 1FC80 */
+	0x00,  0x00,  0x00,  0x7F,  0xC0,  0x00,  0x00,  0x07,  0xFC,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x9E, 	/* 1FC90 */
+	0x00,  0x06,  0x00,  0x18,  0x00,  0x60,  0x01,  0x80,  0x04,  0x01,  0x80,  0x60,  0x18,  0x06,  0x00,  0x00, 	/* 1FCA0 */
+	0x00,  0x00,  0x9F,  0x00,  0x00,  0xF0,  0x10,  0x81,  0x08,  0x11,  0x00,  0x20,  0x02,  0x00,  0x20,  0x00, 	/* 1FCB0 */
+	0x00,  0x20,  0x02,  0x00,  0x00,  0xA0,  0x00,  0x00,  0xF0,  0x10,  0x82,  0x74,  0x49,  0xA4,  0x9A,  0x49, 	/* 1FCC0 */
+	0xA4,  0x6C,  0x20,  0x01,  0x8C,  0x07,  0x00,  0x00,  0xA1,  0x00,  0x00,  0x40,  0x04,  0x00,  0xA0,  0x0A, 	/* 1FCD0 */
+	0x01,  0x10,  0x11,  0x01,  0xF0,  0x20,  0x82,  0x08,  0x71,  0xC0,  0x00,  0xA2,  0x00,  0x03,  0xE0,  0x11, 	/* 1FCE0 */
+	0x01,  0x08,  0x11,  0x01,  0xE0,  0x11,  0x01,  0x08,  0x10,  0x81,  0x10,  0x3E,  0x00,  0x00,  0xA3,  0x00, 	/* 1FCF0 */
+	0x00,  0x74,  0x08,  0xC1,  0x04,  0x20,  0x02,  0x00,  0x20,  0x02,  0x00,  0x10,  0x40,  0x88,  0x07,  0x00, 	/* 1FD00 */
+	0x00,  0xA4,  0x00,  0x03,  0xE0,  0x11,  0x01,  0x08,  0x10,  0x81,  0x04,  0x10,  0x41,  0x08,  0x10,  0x81, 	/* 1FD10 */
+	0x10,  0x3E,  0x00,  0x00,  0xA5,  0x00,  0x03,  0xF8,  0x10,  0x41,  0x00,  0x11,  0x01,  0xF0,  0x11,  0x01, 	/* 1FD20 */
+	0x00,  0x10,  0x41,  0x04,  0x3F,  0x80,  0x00,  0xA6,  0x00,  0x03,  0xF8,  0x10,  0x41,  0x00,  0x11,  0x01, 	/* 1FD30 */
+	0xF0,  0x11,  0x01,  0x00,  0x10,  0x01,  0x00,  0x38,  0x00,  0x00,  0xA7,  0x00,  0x00,  0xE8,  0x11,  0x82, 	/* 1FD40 */
+	0x08,  0x40,  0x04,  0x00,  0x47,  0xC4,  0x08,  0x20,  0x81,  0x18,  0x0E,  0x80,  0x00,  0xA8,  0x00,  0x07, 	/* 1FD50 */
+	0x1C,  0x20,  0x82,  0x08,  0x20,  0x83,  0xF8,  0x20,  0x82,  0x08,  0x20,  0x82,  0x08,  0x71,  0xC0,  0x00, 	/* 1FD60 */
+	0xA9,  0x00,  0x00,  0xE0,  0x04,  0x00,  0x40,  0x04,  0x00,  0x40,  0x04,  0x00,  0x40,  0x04,  0x00,  0x40, 	/* 1FD70 */
+	0x0E,  0x00,  0x00,  0xAA,  0x00,  0x00,  0x70,  0x02,  0x00,  0x20,  0x02,  0x00,  0x20,  0x02,  0x00,  0x20, 	/* 1FD80 */
+	0x02,  0x00,  0x20,  0x24,  0x01,  0x80,  0xAB,  0x00,  0x03,  0xB8,  0x11,  0x01,  0x20,  0x14,  0x01,  0x80, 	/* 1FD90 */
+	0x14,  0x01,  0x20,  0x11,  0x01,  0x08,  0x39,  0xC0,  0x00,  0xAC,  0x00,  0x03,  0x80,  0x10,  0x01,  0x00, 	/* 1FDA0 */
+	0x10,  0x01,  0x00,  0x10,  0x01,  0x00,  0x10,  0x41,  0x08,  0x3F,  0x80,  0x00,  0xAD,  0x00,  0x0C,  0x06, 	/* 1FDB0 */
+	0x40,  0x46,  0x0C,  0x60,  0xC5,  0x14,  0x51,  0x44,  0xA4,  0x4A,  0x44,  0x44,  0xE4,  0xE0,  0x00,  0xAE, 	/* 1FDC0 */
+	0x00,  0x03,  0x1C,  0x18,  0x81,  0x48,  0x14,  0x81,  0x28,  0x12,  0x81,  0x18,  0x11,  0x81,  0x08,  0x38, 	/* 1FDD0 */
+	0x80,  0x00,  0xAF,  0x00,  0x00,  0xE0,  0x11,  0x02,  0x08,  0x40,  0x44,  0x04,  0x40,  0x44,  0x04,  0x20, 	/* 1FDE0 */
+	0x81,  0x10,  0x0E,  0x00,  0x00,  0xB0,  0x00,  0x03,  0xE0,  0x11,  0x01,  0x08,  0x10,  0x81,  0x10,  0x1E, 	/* 1FDF0 */
+	0x01,  0x00,  0x10,  0x01,  0x00,  0x38,  0x00,  0x00,  0xB1,  0x00,  0x00,  0xE0,  0x11,  0x02,  0x08,  0x40, 	/* 1FE00 */
+	0x44,  0x04,  0x40,  0x44,  0xC4,  0x22,  0x81,  0x10,  0x0E,  0xA0,  0x06,  0xB2,  0x00,  0x07,  0xE0,  0x21, 	/* 1FE10 */
+	0x02,  0x08,  0x21,  0x03,  0xE0,  0x22,  0x02,  0x10,  0x21,  0x02,  0x10,  0x71,  0x40,  0x08,  0xB3,  0x00, 	/* 1FE20 */
+	0x01,  0xE8,  0x21,  0x82,  0x08,  0x10,  0x00,  0xC0,  0x02,  0x00,  0x10,  0x20,  0x83,  0x08,  0x2F,  0x00, 	/* 1FE30 */
+	0x00,  0xB4,  0x00,  0x07,  0xFC,  0x44,  0x44,  0x44,  0x04,  0x00,  0x40,  0x04,  0x00,  0x40,  0x04,  0x00, 	/* 1FE40 */
+	0x40,  0x0E,  0x00,  0x00,  0xB5,  0x00,  0x07,  0x1C,  0x20,  0x82,  0x08,  0x20,  0x82,  0x08,  0x20,  0x82, 	/* 1FE50 */
+	0x08,  0x20,  0x81,  0x10,  0x0E,  0x00,  0x00,  0xB6,  0x00,  0x07,  0x1C,  0x20,  0x82,  0x08,  0x11,  0x01, 	/* 1FE60 */
+	0x10,  0x11,  0x00,  0xA0,  0x0A,  0x00,  0x40,  0x04,  0x00,  0x00,  0xB7,  0x00,  0x0E,  0xEE,  0x44,  0x44, 	/* 1FE70 */
+	0x44,  0x44,  0x42,  0xA8,  0x2A,  0x82,  0xA8,  0x11,  0x01,  0x10,  0x11,  0x00,  0x00,  0xB8,  0x00,  0x07, 	/* 1FE80 */
+	0x1C,  0x20,  0x81,  0x10,  0x0A,  0x00,  0x40,  0x04,  0x00,  0xA0,  0x11,  0x02,  0x08,  0x71,  0xC0,  0x00, 	/* 1FE90 */
+	0xB9,  0x00,  0x07,  0x1C,  0x20,  0x81,  0x10,  0x0A,  0x00,  0x40,  0x04,  0x00,  0x40,  0x04,  0x00,  0x40, 	/* 1FEA0 */
+	0x0E,  0x00,  0x00,  0xBA,  0x00,  0x01,  0xFC,  0x10,  0x82,  0x10,  0x02,  0x00,  0x40,  0x04,  0x00,  0x80, 	/* 1FEB0 */
+	0x10,  0x42,  0x04,  0x7F,  0xC0,  0x00,  0xBB,  0x03,  0xC0,  0x20,  0x02,  0x00,  0x20,  0x02,  0x00,  0x20, 	/* 1FEC0 */
+	0x02,  0x00,  0x20,  0x02,  0x00,  0x20,  0x02,  0x00,  0x3C,  0xBC,  0x80,  0x04,  0x00,  0x20,  0x01,  0x00, 	/* 1FED0 */
+	0x08,  0x00,  0x40,  0x02,  0x00,  0x10,  0x00,  0x80,  0x04,  0x00,  0x20,  0x01,  0xBD,  0x3C,  0x00,  0x40, 	/* 1FEE0 */
+	0x04,  0x00,  0x40,  0x04,  0x00,  0x40,  0x04,  0x00,  0x40,  0x04,  0x00,  0x40,  0x04,  0x03,  0xC0,  0xBE, 	/* 1FEF0 */
+	0x02,  0x00,  0x50,  0x08,  0x80,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00, 	/* 1FF00 */
+	0x00,  0x00,  0xBF,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00, 	/* 1FF10 */
+	0x00,  0x00,  0x00,  0x0F,  0xFF,  0x80,  0x08,  0x00,  0x40,  0x02,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00, 	/* 1FF20 */
+	0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x81,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x06, 	/* 1FF30 */
+	0x00,  0x90,  0x07,  0x00,  0x90,  0x11,  0x01,  0x20,  0x0D,  0x80,  0x00,  0x82,  0x00,  0x03,  0x00,  0x10, 	/* 1FF40 */
+	0x01,  0x00,  0x16,  0x01,  0x90,  0x10,  0x81,  0x08,  0x10,  0x81,  0x90,  0x16,  0x00,  0x00,  0x83,  0x00, 	/* 1FF50 */
+	0x00,  0x00,  0x00,  0x00,  0x00,  0x0E,  0x01,  0x10,  0x20,  0x02,  0x00,  0x20,  0x01,  0x10,  0x0E,  0x00, 	/* 1FF60 */
+	0x00,  0x84,  0x00,  0x00,  0x30,  0x01,  0x00,  0x10,  0x0D,  0x01,  0x30,  0x21,  0x02,  0x10,  0x21,  0x01, 	/* 1FF70 */
+	0x30,  0x0D,  0x80,  0x00,  0x85,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x0C,  0x01,  0x20,  0x21,  0x03, 	/* 1FF80 */
+	0xF0,  0x20,  0x01,  0x10,  0x0E,  0x00,  0x00,  0x86,  0x00,  0x00,  0x60,  0x09,  0x00,  0x80,  0x3E,  0x00, 	/* 1FF90 */
+	0x80,  0x08,  0x00,  0x80,  0x08,  0x00,  0x80,  0x1C,  0x00,  0x00,  0x87,  0x00,  0x00,  0x00,  0x00,  0x00, 	/* 1FFA0 */
+	0x00,  0x0E,  0x81,  0x10,  0x11,  0x00,  0xE0,  0x08,  0x01,  0xF0,  0x30,  0x80,  0xF0,  0x88,  0x00,  0x03, 	/* 1FFB0 */
+	0x00,  0x10,  0x01,  0x00,  0x16,  0x01,  0x90,  0x11,  0x01,  0x10,  0x11,  0x01,  0x10,  0x3B,  0x80,  0x00, 	/* 1FFC0 */
+	0x89,  0x00,  0x00,  0xC0,  0x04,  0x00,  0x00,  0x0C,  0x00,  0x40,  0x04,  0x00,  0x40,  0x04,  0x00,  0x40, 	/* 1FFD0 */
+	0x0E,  0x00,  0x00,  0x8A,  0x00,  0x00,  0x60,  0x02,  0x00,  0x00,  0x06,  0x00,  0x20,  0x02,  0x00,  0x20, 	/* 1FFE0 */
+	0x02,  0x00,  0x20,  0x22,  0x01,  0xC0,  0x8B,  0x00,  0x03,  0x00,  0x10,  0x01,  0x00,  0x17,  0x01,  0x20, 	/* 1FFF0 */
+	0x14,  0x01,  0xC0,  0x12,  0x01,  0x10,  0x3B,  0x80,  0x00,  0x8C,  0x00,  0x00,  0xC0,  0x04,  0x00,  0x40, 	/* 20000 */
+	0x04,  0x00,  0x40,  0x04,  0x00,  0x40,  0x04,  0x00,  0x40,  0x0E,  0x00,  0x00,  0x8D,  0x00,  0x00,  0x00, 	/* 20010 */
+	0x00,  0x00,  0x00,  0x59,  0x82,  0x64,  0x24,  0x42,  0x44,  0x24,  0x42,  0x44,  0x6E,  0xE0,  0x00,  0x8E, 	/* 20020 */
+	0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x36,  0x01,  0x90,  0x11,  0x01,  0x10,  0x11,  0x01,  0x10,  0x3B, 	/* 20030 */
+	0x80,  0x00,  0x8F,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x0E,  0x01,  0x10,  0x20,  0x82,  0x08,  0x20, 	/* 20040 */
+	0x81,  0x10,  0x0E,  0x00,  0x00,  0x90,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x36,  0x01,  0x90,  0x10, 	/* 20050 */
+	0x81,  0x08,  0x19,  0x01,  0x60,  0x10,  0x03,  0x80,  0x91,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x0D, 	/* 20060 */
+	0x81,  0x30,  0x21,  0x02,  0x10,  0x13,  0x00,  0xD0,  0x01,  0x00,  0x38,  0x92,  0x00,  0x00,  0x00,  0x00, 	/* 20070 */
+	0x00,  0x00,  0x1B,  0x00,  0xC8,  0x08,  0x00,  0x80,  0x08,  0x00,  0x80,  0x1C,  0x00,  0x00,  0x93,  0x00, 	/* 20080 */
+	0x00,  0x00,  0x00,  0x00,  0x00,  0x0E,  0x01,  0x10,  0x10,  0x00,  0xE0,  0x01,  0x01,  0x10,  0x0E,  0x00, 	/* 20090 */
+	0x00,  0x94,  0x00,  0x00,  0x80,  0x08,  0x00,  0x80,  0x3E,  0x00,  0x80,  0x08,  0x00,  0x80,  0x08,  0x00, 	/* 200A0 */
+	0x90,  0x06,  0x00,  0x00,  0x95,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x3B,  0x81,  0x10,  0x11,  0x01, 	/* 200B0 */
+	0x10,  0x11,  0x01,  0x10,  0x0E,  0x80,  0x00,  0x96,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x73,  0x82, 	/* 200C0 */
+	0x10,  0x11,  0x01,  0x20,  0x0A,  0x00,  0xC0,  0x04,  0x00,  0x00,  0x97,  0x00,  0x00,  0x00,  0x00,  0x00, 	/* 200D0 */
+	0x00,  0xEE,  0xE4,  0x44,  0x44,  0x42,  0xA8,  0x2A,  0x81,  0x10,  0x11,  0x00,  0x00,  0x98,  0x00,  0x00, 	/* 200E0 */
+	0x00,  0x00,  0x00,  0x00,  0x3B,  0x81,  0x10,  0x0A,  0x00,  0x40,  0x0A,  0x01,  0x10,  0x3B,  0x80,  0x00, 	/* 200F0 */
+	0x99,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x3B,  0x81,  0x10,  0x0A,  0x00,  0xA0,  0x04,  0x00,  0x40, 	/* 20100 */
+	0x24,  0x01,  0x80,  0x9A,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x1F,  0x02,  0x20,  0x04,  0x00,  0x40, 	/* 20110 */
+	0x08,  0x81,  0x10,  0x3F,  0x00,  0x00,  0x9B,  0x00,  0x40,  0x08,  0x00,  0x80,  0x08,  0x00,  0x80,  0x10, 	/* 20120 */
+	0x00,  0x80,  0x08,  0x00,  0x80,  0x08,  0x00,  0x80,  0x04,  0x9C,  0x02,  0x00,  0x20,  0x02,  0x00,  0x20, 	/* 20130 */
+	0x02,  0x00,  0x20,  0x02,  0x00,  0x20,  0x02,  0x00,  0x20,  0x02,  0x00,  0x20,  0x9D,  0x20,  0x01,  0x00, 	/* 20140 */
+	0x10,  0x01,  0x00,  0x10,  0x00,  0x80,  0x10,  0x01,  0x00,  0x10,  0x01,  0x00,  0x10,  0x02,  0x00,  0x9E, 	/* 20150 */
+	0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x38,  0x04,  0x40,  0x02,  0x20,  0x1C,  0x00,  0x00,  0x00,  0x00, 	/* 20160 */
+	0x00,  0x00,  0xA0,  0x00,  0x00,  0x00,  0x00,  0x00,  0x40,  0x1C,  0x02,  0x60,  0x69,  0x06,  0x80,  0x69, 	/* 20170 */
+	0x03,  0x20,  0x1C,  0x01,  0x00,  0xA1,  0x00,  0x00,  0x30,  0x04,  0x80,  0x40,  0x0C,  0x00,  0xC0,  0x7F, 	/* 20180 */
+	0x00,  0xC0,  0x38,  0x24,  0xE4,  0x33,  0x80,  0x00,  0xA2,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00, 	/* 20190 */
+	0x07,  0xFE,  0x00,  0x20,  0x02,  0x00,  0x20,  0x00,  0x00,  0x00,  0x00,  0xA3,  0xFF,  0xF0,  0x00,  0x00, 	/* 201A0 */
+	0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0xA5,  0x00, 	/* 201B0 */
+	0x07,  0x1C,  0x20,  0x81,  0x10,  0x3F,  0x80,  0xA0,  0x3F,  0x80,  0x40,  0x04,  0x00,  0x40,  0x0E,  0x00, 	/* 201C0 */
+	0x00,  0x00,  0x00,  0x00,  0x00,  0x03,  0x7A,  0x04,  's',   'h',   'i',   'n',   'o',   'n',   'o',   'm', 	/* 201D0 */
+	'e',   '_',   'f',   'o',   'n',   't',   '1',   '6',   '.',   'f',   'n',   't',   0x00,  0x00,  0x00,  0x00, 	/* 201E0 */
+	0x00,  0x00,  0x00,  0x00,  'F',   'O',   'N',   'T',   's',   'h',   'i',   'n',   'o',   'n',   'o',   'm', 	/* 201F0 */
+	'e',   '_',   'f',   'o',   'n',   't',   '1',   '6',   0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00, 	/* 20200 */
+	0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0xE3,  0x79,  0x03,  0x00,  0x01,  0x00,  0x00,  0x00, 	/* 20210 */
+	0x20,  0x00,  0x00,  0x00,  0x58,  0x00,  0x00,  0x00,  0x06,  0x00,  0x00,  0x00,  0x64,  0x00,  0x00,  0x00, 	/* 20220 */
+	0x09,  0x00,  0x00,  0x00,  0x76,  0x00,  0x00,  0x00,  0x57,  0x01,  0x00,  0x00,  0x24,  0x03,  0x00,  0x00, 	/* 20230 */
+	0x7A,  0x00,  0x00,  0x00,  0xDE,  0x12,  0x00,  0x00,  0x65,  0x1A,  0x00,  0x00,  0xC2,  0x06,  0xC3,  0x02, 	/* 20240 */
+	0xCE,  0x27,  0xCF,  0x09,  0xD0,  0x31,  0xD1,  0x11,  0xE2,  0x0E,  0xE3,  0x04,  0xE4,  0x08,  0xE5,  0x40, 	/* 20250 */
+	0xE6,  0x40,  0xE7,  0x3F,  0xE8,  0x3F,  0xE9,  0x3C,  0xEF,  0x03,  0x80,  0x0E,  0x84,  0x02,  0x86,  0x04, 	/* 20260 */
+	0x87,  0x02,  0x88,  0x14,  0x89,  0x07,  0x8A,  0x05,  0x8C,  0x01,  0x94,  0x1E,  0x95,  0x02,  0x96,  0x06, 	/* 20270 */
+	0x97,  0x06,  0x98,  0x02,  0x99,  0x05,  0x80,  0x15,  0x81,  0x3F,  0x82,  0x37,  0x83,  0x3B,  0xB8,  0x1F, 	/* 20280 */
+	0xB9,  0x13,  0xBA,  0x23,  0xBB,  0x1E,  0xBC,  0x13,  0xBD,  0x1A,  0xBE,  0x14,  0xBF,  0x1A,  0x80,  0x1A, 	/* 20290 */
+	0x81,  0x12,  0x82,  0x0F,  0x83,  0x13,  0x84,  0x14,  0x85,  0x21,  0x86,  0x24,  0x87,  0x1B,  0x88,  0x1B, 	/* 202A0 */
+	0x89,  0x1A,  0x8A,  0x17,  0x8B,  0x1C,  0x8C,  0x1A,  0x8D,  0x21,  0x8E,  0x11,  0x8F,  0x24,  0x90,  0x1E, 	/* 202B0 */
+	0x91,  0x14,  0x92,  0x16,  0x93,  0x13,  0x94,  0x0E,  0x95,  0x0F,  0x96,  0x17,  0x97,  0x0D,  0x98,  0x0E, 	/* 202C0 */
+	0x99,  0x0D,  0x9A,  0x0D,  0x9B,  0x17,  0x9C,  0x16,  0x9D,  0x0E,  0x9E,  0x0C,  0x9F,  0x12,  0xA0,  0x13, 	/* 202D0 */
+	0xA1,  0x14,  0xA2,  0x0F,  0xA3,  0x1D,  0xA4,  0x1A,  0xA5,  0x1A,  0xA6,  0x13,  0xA7,  0x12,  0xA8,  0x0F, 	/* 202E0 */
+	0xA9,  0x0A,  0xAA,  0x06,  0xAB,  0x0E,  0xAC,  0x0B,  0xAD,  0x1A,  0xAE,  0x21,  0xAF,  0x22,  0xB0,  0x1F, 	/* 202F0 */
+	0xB1,  0x19,  0xB2,  0x11,  0xB3,  0x0F,  0xB4,  0x0F,  0xB5,  0x0B,  0xB6,  0x0E,  0xB7,  0x1A,  0xB8,  0x15, 	/* 20300 */
+	0xB9,  0x1C,  0xBA,  0x14,  0xBB,  0x21,  0xBC,  0x1F,  0xBD,  0x1B,  0xBE,  0x1F,  0xBF,  0x14,  0x80,  0x16, 	/* 20310 */
+	0x81,  0x1C,  0x82,  0x1C,  0x83,  0x17,  0x84,  0x16,  0x85,  0x20,  0x86,  0x14,  0x87,  0x16,  0x88,  0x1D, 	/* 20320 */
+	0x89,  0x17,  0x8A,  0x19,  0x8B,  0x22,  0x8C,  0x11,  0x8D,  0x12,  0x8E,  0x1C,  0x8F,  0x12,  0x90,  0x0F, 	/* 20330 */
+	0x91,  0x09,  0x92,  0x12,  0x93,  0x18,  0x94,  0x14,  0x95,  0x16,  0x96,  0x1B,  0x97,  0x19,  0x98,  0x17, 	/* 20340 */
+	0x99,  0x17,  0x9A,  0x15,  0x9B,  0x18,  0x9C,  0x1F,  0x9D,  0x1F,  0x9E,  0x17,  0x9F,  0x1C,  0xA0,  0x12, 	/* 20350 */
+	0xA1,  0x17,  0xA2,  0x1A,  0xA3,  0x16,  0xA4,  0x1C,  0xA5,  0x1A,  0xA6,  0x12,  0xA7,  0x17,  0xA8,  0x1A, 	/* 20360 */
+	0xA9,  0x0D,  0xAA,  0x10,  0xAB,  0x0D,  0xAC,  0x12,  0xAD,  0x19,  0xAE,  0x1A,  0xAF,  0x10,  0xB0,  0x0D, 	/* 20370 */
+	0xB1,  0x15,  0xB2,  0x1B,  0xB3,  0x16,  0xB4,  0x14,  0xB5,  0x11,  0xB6,  0x0E,  0xB7,  0x1B,  0xB8,  0x1C, 	/* 20380 */
+	0xB9,  0x10,  0xBA,  0x13,  0xBB,  0x14,  0xBC,  0x13,  0xBD,  0x11,  0xBE,  0x0F,  0xBF,  0x16,  0x80,  0x12, 	/* 20390 */
+	0x81,  0x0A,  0x82,  0x0D,  0x83,  0x09,  0x84,  0x09,  0x85,  0x0F,  0x86,  0x0D,  0x87,  0x16,  0x88,  0x12, 	/* 203A0 */
+	0x89,  0x15,  0x8A,  0x0E,  0x8B,  0x15,  0x8C,  0x12,  0x8D,  0x0E,  0x8E,  0x09,  0x8F,  0x0F,  0x90,  0x0D, 	/* 203B0 */
+	0x91,  0x12,  0x92,  0x07,  0x93,  0x11,  0x94,  0x1D,  0x95,  0x20,  0x96,  0x18,  0x97,  0x18,  0x98,  0x0D, 	/* 203C0 */
+	0x99,  0x19,  0x9A,  0x15,  0x9B,  0x19,  0x9C,  0x13,  0x9D,  0x0D,  0x9E,  0x10,  0x9F,  0x10,  0xA0,  0x0D, 	/* 203D0 */
+	0xA1,  0x08,  0xA2,  0x14,  0xA3,  0x0F,  0xA4,  0x0D,  0xA5,  0x16,  0xA6,  0x14,  0xA7,  0x12,  0xA8,  0x16, 	/* 203E0 */
+	0xA9,  0x16,  0xAA,  0x13,  0xAB,  0x20,  0xAC,  0x15,  0xAD,  0x17,  0xAE,  0x15,  0xAF,  0x13,  0xB0,  0x13, 	/* 203F0 */
+	0xB1,  0x11,  0xB2,  0x1C,  0xB3,  0x16,  0xB4,  0x1F,  0xB5,  0x1A,  0xB6,  0x1A,  0xB7,  0x16,  0xB8,  0x19, 	/* 20400 */
+	0xB9,  0x18,  0xBA,  0x0E,  0xBC,  0x03,  0xBD,  0x17,  0xBE,  0x18,  0xBF,  0x12,  0x80,  0x16,  0x81,  0x16, 	/* 20410 */
+	0x82,  0x19,  0x83,  0x14,  0x84,  0x10,  0x85,  0x14,  0x86,  0x18,  0x87,  0x19,  0x88,  0x1E,  0x89,  0x15, 	/* 20420 */
+	0x8A,  0x12,  0x8B,  0x17,  0x8C,  0x16,  0x8D,  0x0D,  0x8E,  0x12,  0x8F,  0x15,  0x90,  0x12,  0x91,  0x14, 	/* 20430 */
+	0x92,  0x10,  0x93,  0x11,  0x94,  0x10,  0x95,  0x13,  0x96,  0x17,  0x97,  0x11,  0x98,  0x0E,  0x99,  0x0E, 	/* 20440 */
+	0x9A,  0x0D,  0x9B,  0x16,  0x9C,  0x13,  0x9D,  0x13,  0x9E,  0x0A,  0x9F,  0x0F,  0xA0,  0x0F,  0xA1,  0x19, 	/* 20450 */
+	0xA2,  0x14,  0xA3,  0x17,  0xA4,  0x10,  0xA5,  0x13,  0xA6,  0x19,  0xA7,  0x0A,  0xA8,  0x1A,  0xA9,  0x18, 	/* 20460 */
+	0xAA,  0x1B,  0xAB,  0x1C,  0xAC,  0x18,  0xAD,  0x15,  0xAE,  0x0B,  0xB0,  0x03,  0xB1,  0x12,  0xB2,  0x22, 	/* 20470 */
+	0xB3,  0x1B,  0xB4,  0x0C,  0xB5,  0x0A,  0xB6,  0x09,  0xB7,  0x13,  0xB8,  0x0C,  0xB9,  0x12,  0xBA,  0x13, 	/* 20480 */
+	0xBB,  0x12,  0xBC,  0x18,  0xBD,  0x0F,  0xBE,  0x12,  0xBF,  0x16,  0x80,  0x23,  0x81,  0x27,  0x82,  0x12, 	/* 20490 */
+	0x83,  0x0C,  0x84,  0x06,  0x85,  0x15,  0x86,  0x12,  0x87,  0x1B,  0x88,  0x0B,  0x89,  0x0F,  0x8A,  0x0E, 	/* 204A0 */
+	0x8B,  0x0B,  0x8C,  0x13,  0x8D,  0x0D,  0x8E,  0x0B,  0x8F,  0x0C,  0x90,  0x0E,  0x91,  0x12,  0x92,  0x01, 	/* 204B0 */
+	0x95,  0x01,  0x96,  0x1B,  0x97,  0x0D,  0x98,  0x09,  0x99,  0x1D,  0x9A,  0x1E,  0x9B,  0x1C,  0x9C,  0x18, 	/* 204C0 */
+	0x9D,  0x18,  0x9E,  0x12,  0x9F,  0x0E,  0xA0,  0x19,  0xA1,  0x12,  0xA2,  0x05,  0xA3,  0x11,  0xA4,  0x14, 	/* 204D0 */
+	0xA5,  0x0A,  0xA6,  0x0C,  0xA7,  0x15,  0xA8,  0x0C,  0xA9,  0x10,  0xAA,  0x05,  0xAB,  0x15,  0xAC,  0x11, 	/* 204E0 */
+	0xAD,  0x0E,  0xAE,  0x10,  0xAF,  0x13,  0xB0,  0x19,  0xB1,  0x0A,  0xB3,  0x09,  0xB4,  0x13,  0xB5,  0x11, 	/* 204F0 */
+	0xB6,  0x0D,  0xB7,  0x0F,  0xB8,  0x03,  0xB9,  0x05,  0xBA,  0x17,  0xBB,  0x19,  0xBC,  0x0A,  0xBD,  0x12, 	/* 20500 */
+	0xBE,  0x05,  0xBC,  0x3D,  0xBD,  0x1F,  0xBF,  0x05,  0xA7,  0x01,  0x80,  0x02,  0x40,  0x04,  0x20,  0x06, 	/* 20510 */
+	0x20,  0x03,  0x00,  0x03,  0x80,  0x04,  0xC0,  0x04,  0x60,  0x06,  0x20,  0x03,  0x20,  0x01,  0xC0,  0x00, 	/* 20520 */
+	0xC0,  0x04,  0x60,  0x04,  0x20,  0x02,  0x40,  0x01,  0x80,  0xA8,  0x06,  0x60,  0x06,  0x60,  0x00,  0x00, 	/* 20530 */
+	0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00, 	/* 20540 */
+	0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0xB0,  0x00,  0x00,  0x30,  0x00,  0x48, 	/* 20550 */
+	0x00,  0x48,  0x00,  0x30,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00, 	/* 20560 */
+	0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0xB1,  0x00,  0x00,  0x00,  0x00, 	/* 20570 */
+	0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x1F,  0xFC,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80, 	/* 20580 */
+	0x00,  0x80,  0x00,  0x00,  0x00,  0x00,  0x1F,  0xFE,  0x00,  0x00,  0x00,  0x00,  0xB4,  0x00,  0x80,  0x00, 	/* 20590 */
+	0x80,  0x01,  0x00,  0x02,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00, 	/* 205A0 */
+	0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0xB6,  0x00,  0x00, 	/* 205B0 */
+	0x07,  0xE0,  0x0F,  0x20,  0x1F,  0x20,  0x1F,  0x20,  0x0F,  0x20,  0x07,  0x20,  0x01,  0x20,  0x01,  0x20, 	/* 205C0 */
+	0x01,  0x20,  0x01,  0x20,  0x01,  0x20,  0x01,  0x20,  0x01,  0x20,  0x01,  0x20,  0x01,  0x20,  0x97,  0x00, 	/* 205D0 */
+	0x00,  0x00,  0x00,  0x00,  0x00,  0x10,  0x08,  0x08,  0x10,  0x04,  0x20,  0x02,  0x40,  0x01,  0x80,  0x01, 	/* 205E0 */
+	0x80,  0x02,  0x40,  0x04,  0x20,  0x08,  0x10,  0x10,  0x08,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0xB7, 	/* 205F0 */
+	0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x01,  0x80,  0x01,  0x80,  0x00,  0x00,  0x00,  0x00,  0x3F,  0xFC, 	/* 20600 */
+	0x00,  0x00,  0x00,  0x00,  0x01,  0x80,  0x01,  0x80,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00, 	/* 20610 */
+	0x91,  0x00,  0x00,  0x00,  0x80,  0x00,  0x80,  0x01,  0x40,  0x01,  0x40,  0x02,  0x20,  0x02,  0x20,  0x04, 	/* 20620 */
+	0x10,  0x07,  0xF0,  0x04,  0x10,  0x08,  0x08,  0x08,  0x08,  0x10,  0x04,  0x38,  0x0E,  0x00,  0x00,  0x00, 	/* 20630 */
+	0x00,  0x92,  0x00,  0x00,  0x3F,  0xE0,  0x08,  0x10,  0x08,  0x08,  0x08,  0x08,  0x08,  0x10,  0x0F,  0xE0, 	/* 20640 */
+	0x08,  0x10,  0x08,  0x08,  0x08,  0x04,  0x08,  0x04,  0x08,  0x08,  0x08,  0x30,  0x3F,  0xC0,  0x00,  0x00, 	/* 20650 */
+	0x00,  0x00,  0x93,  0x00,  0x00,  0x1F,  0xF8,  0x04,  0x08,  0x04,  0x04,  0x04,  0x00,  0x04,  0x00,  0x04, 	/* 20660 */
+	0x00,  0x04,  0x00,  0x04,  0x00,  0x04,  0x00,  0x04,  0x00,  0x04,  0x00,  0x04,  0x00,  0x0E,  0x00,  0x00, 	/* 20670 */
+	0x00,  0x00,  0x00,  0x94,  0x00,  0x00,  0x01,  0x00,  0x01,  0x00,  0x02,  0x80,  0x02,  0x80,  0x04,  0x40, 	/* 20680 */
+	0x04,  0x40,  0x08,  0x20,  0x08,  0x20,  0x08,  0x10,  0x10,  0x10,  0x10,  0x10,  0x20,  0x08,  0x7F,  0xFC, 	/* 20690 */
+	0x00,  0x00,  0x00,  0x00,  0x95,  0x00,  0x00,  0x3F,  0xF8,  0x08,  0x08,  0x08,  0x04,  0x08,  0x00,  0x08, 	/* 206A0 */
+	0x00,  0x08,  0x40,  0x0F,  0xC0,  0x08,  0x40,  0x08,  0x00,  0x08,  0x00,  0x08,  0x04,  0x08,  0x08,  0x3F, 	/* 206B0 */
+	0xF8,  0x00,  0x00,  0x00,  0x00,  0x96,  0x00,  0x00,  0x0F,  0xF8,  0x08,  0x10,  0x10,  0x20,  0x00,  0x40, 	/* 206C0 */
+	0x00,  0x40,  0x00,  0x80,  0x01,  0x00,  0x01,  0x00,  0x02,  0x00,  0x04,  0x00,  0x04,  0x08,  0x08,  0x08, 	/* 206D0 */
+	0x1F,  0xF8,  0x00,  0x00,  0x00,  0x00,  0x97,  0x00,  0x00,  0x38,  0x1C,  0x10,  0x08,  0x10,  0x08,  0x10, 	/* 206E0 */
+	0x08,  0x10,  0x08,  0x10,  0x08,  0x1F,  0xF8,  0x10,  0x08,  0x10,  0x08,  0x10,  0x08,  0x10,  0x08,  0x10, 	/* 206F0 */
+	0x08,  0x38,  0x1C,  0x00,  0x00,  0x00,  0x00,  0x98,  0x00,  0x00,  0x03,  0xC0,  0x0C,  0x30,  0x18,  0x18, 	/* 20700 */
+	0x10,  0x08,  0x20,  0x04,  0x24,  0x24,  0x27,  0xE4,  0x24,  0x24,  0x20,  0x04,  0x10,  0x08,  0x18,  0x18, 	/* 20710 */
+	0x0C,  0x30,  0x03,  0xC0,  0x00,  0x00,  0x00,  0x00,  0x99,  0x00,  0x00,  0x03,  0x80,  0x01,  0x00,  0x01, 	/* 20720 */
+	0x00,  0x01,  0x00,  0x01,  0x00,  0x01,  0x00,  0x01,  0x00,  0x01,  0x00,  0x01,  0x00,  0x01,  0x00,  0x01, 	/* 20730 */
+	0x00,  0x01,  0x00,  0x03,  0x80,  0x00,  0x00,  0x00,  0x00,  0x9A,  0x00,  0x00,  0x1C,  0x1C,  0x08,  0x10, 	/* 20740 */
+	0x08,  0x20,  0x08,  0x40,  0x08,  0x80,  0x09,  0x00,  0x0B,  0x00,  0x0C,  0x80,  0x08,  0x40,  0x08,  0x20, 	/* 20750 */
+	0x08,  0x10,  0x08,  0x08,  0x1C,  0x0E,  0x00,  0x00,  0x00,  0x00,  0x9B,  0x00,  0x00,  0x00,  0x80,  0x00, 	/* 20760 */
+	0x80,  0x01,  0x40,  0x01,  0x40,  0x02,  0x20,  0x02,  0x20,  0x04,  0x10,  0x04,  0x10,  0x04,  0x10,  0x08, 	/* 20770 */
+	0x08,  0x08,  0x08,  0x10,  0x04,  0x38,  0x0E,  0x00,  0x00,  0x00,  0x00,  0x9C,  0x00,  0x00,  0x60,  0x0C, 	/* 20780 */
+	0x20,  0x08,  0x30,  0x18,  0x30,  0x18,  0x28,  0x28,  0x28,  0x28,  0x24,  0x48,  0x24,  0x48,  0x24,  0x48, 	/* 20790 */
+	0x22,  0x88,  0x22,  0x88,  0x21,  0x08,  0x71,  0x1C,  0x00,  0x00,  0x00,  0x00,  0x9D,  0x00,  0x00,  0x38, 	/* 207A0 */
+	0x1C,  0x18,  0x08,  0x14,  0x08,  0x14,  0x08,  0x12,  0x08,  0x11,  0x08,  0x11,  0x08,  0x10,  0x88,  0x10, 	/* 207B0 */
+	0x48,  0x10,  0x48,  0x10,  0x28,  0x10,  0x18,  0x38,  0x08,  0x00,  0x00,  0x00,  0x00,  0x9E,  0x00,  0x00, 	/* 207C0 */
+	0x3F,  0xFC,  0x20,  0x04,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x10,  0x08,  0x1F,  0xF8,  0x10,  0x08, 	/* 207D0 */
+	0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x20,  0x04,  0x3F,  0xFC,  0x00,  0x00,  0x00,  0x00,  0x9F,  0x00, 	/* 207E0 */
+	0x00,  0x03,  0xC0,  0x0C,  0x30,  0x18,  0x18,  0x10,  0x08,  0x20,  0x04,  0x20,  0x04,  0x20,  0x04,  0x20, 	/* 207F0 */
+	0x04,  0x20,  0x04,  0x10,  0x08,  0x18,  0x18,  0x0C,  0x30,  0x03,  0xC0,  0x00,  0x00,  0x00,  0x00,  0xA0, 	/* 20800 */
+	0x00,  0x00,  0x1F,  0xF8,  0x08,  0x10,  0x08,  0x10,  0x08,  0x10,  0x08,  0x10,  0x08,  0x10,  0x08,  0x10, 	/* 20810 */
+	0x08,  0x10,  0x08,  0x10,  0x08,  0x10,  0x08,  0x10,  0x08,  0x10,  0x1C,  0x38,  0x00,  0x00,  0x00,  0x00, 	/* 20820 */
+	0xA1,  0x00,  0x00,  0x1F,  0xE0,  0x04,  0x18,  0x04,  0x04,  0x04,  0x04,  0x04,  0x04,  0x04,  0x18,  0x07, 	/* 20830 */
+	0xE0,  0x04,  0x00,  0x04,  0x00,  0x04,  0x00,  0x04,  0x00,  0x04,  0x00,  0x0E,  0x00,  0x00,  0x00,  0x00, 	/* 20840 */
+	0x00,  0xA3,  0x00,  0x00,  0x1F,  0xF0,  0x08,  0x10,  0x04,  0x08,  0x02,  0x00,  0x01,  0x00,  0x00,  0x80, 	/* 20850 */
+	0x00,  0xC0,  0x00,  0x80,  0x01,  0x00,  0x02,  0x00,  0x04,  0x08,  0x08,  0x08,  0x1F,  0xF8,  0x00,  0x00, 	/* 20860 */
+	0x00,  0x00,  0xA4,  0x00,  0x00,  0x3F,  0xF8,  0x21,  0x08,  0x41,  0x04,  0x01,  0x00,  0x01,  0x00,  0x01, 	/* 20870 */
+	0x00,  0x01,  0x00,  0x01,  0x00,  0x01,  0x00,  0x01,  0x00,  0x01,  0x00,  0x01,  0x00,  0x03,  0x80,  0x00, 	/* 20880 */
+	0x00,  0x00,  0x00,  0xA5,  0x00,  0x00,  0x0E,  0x38,  0x11,  0x44,  0x20,  0x82,  0x00,  0x80,  0x00,  0x80, 	/* 20890 */
+	0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x01,  0xC0, 	/* 208A0 */
+	0x00,  0x00,  0x00,  0x00,  0xA6,  0x00,  0x00,  0x01,  0xC0,  0x00,  0x80,  0x03,  0xE0,  0x0C,  0x98,  0x08, 	/* 208B0 */
+	0x88,  0x10,  0x84,  0x10,  0x84,  0x10,  0x84,  0x08,  0x88,  0x0C,  0x98,  0x03,  0xE0,  0x00,  0x80,  0x01, 	/* 208C0 */
+	0xC0,  0x00,  0x00,  0x00,  0x00,  0xA7,  0x00,  0x00,  0x38,  0x38,  0x10,  0x10,  0x08,  0x20,  0x04,  0x40, 	/* 208D0 */
+	0x04,  0x40,  0x02,  0x80,  0x01,  0x00,  0x02,  0x80,  0x04,  0x40,  0x04,  0x40,  0x08,  0x20,  0x10,  0x10, 	/* 208E0 */
+	0x38,  0x38,  0x00,  0x00,  0x00,  0x00,  0xA8,  0x00,  0x00,  0x03,  0x80,  0x61,  0x0C,  0x91,  0x12,  0x11, 	/* 208F0 */
+	0x10,  0x11,  0x10,  0x11,  0x10,  0x11,  0x10,  0x19,  0x30,  0x09,  0x20,  0x07,  0xC0,  0x01,  0x00,  0x01, 	/* 20900 */
+	0x00,  0x03,  0x80,  0x00,  0x00,  0x00,  0x00,  0xA9,  0x00,  0x00,  0x01,  0xC0,  0x06,  0x30,  0x0C,  0x18, 	/* 20910 */
+	0x08,  0x08,  0x10,  0x04,  0x10,  0x04,  0x10,  0x04,  0x08,  0x08,  0x0C,  0x18,  0x06,  0x30,  0x11,  0x44, 	/* 20920 */
+	0x11,  0x44,  0x1F,  0x7C,  0x00,  0x00,  0x00,  0x00,  0xB1,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00, 	/* 20930 */
+	0x00,  0x00,  0x00,  0x00,  0x08,  0x03,  0x88,  0x04,  0x50,  0x08,  0x50,  0x08,  0x60,  0x10,  0x40,  0x10, 	/* 20940 */
+	0xC0,  0x11,  0x48,  0x0E,  0x30,  0x00,  0x00,  0x00,  0x00,  0xB2,  0x00,  0x00,  0x00,  0x70,  0x00,  0x88, 	/* 20950 */
+	0x01,  0x08,  0x01,  0x08,  0x02,  0x08,  0x02,  0x10,  0x04,  0xE0,  0x04,  0x20,  0x04,  0x10,  0x08,  0x10, 	/* 20960 */
+	0x08,  0x10,  0x0A,  0x20,  0x09,  0xC0,  0x10,  0x00,  0x10,  0x00,  0xB3,  0x00,  0x00,  0x00,  0x00,  0x00, 	/* 20970 */
+	0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x0E,  0x18,  0x11,  0x20,  0x21,  0x40,  0x01,  0x80,  0x01, 	/* 20980 */
+	0x80,  0x01,  0x00,  0x02,  0x00,  0x02,  0x00,  0x04,  0x00,  0x04,  0x00,  0xB4,  0x00,  0x00,  0x01,  0x80, 	/* 20990 */
+	0x02,  0x60,  0x02,  0x10,  0x01,  0x08,  0x00,  0x80,  0x03,  0x40,  0x04,  0x40,  0x08,  0x20,  0x10,  0x20, 	/* 209A0 */
+	0x10,  0x40,  0x10,  0x40,  0x08,  0x80,  0x07,  0x00,  0x00,  0x00,  0x00,  0x00,  0xB5,  0x00,  0x00,  0x00, 	/* 209B0 */
+	0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x01,  0xE0,  0x02,  0x10,  0x02,  0x00,  0x01, 	/* 209C0 */
+	0xC0,  0x02,  0x00,  0x04,  0x00,  0x04,  0x20,  0x03,  0xC0,  0x00,  0x00,  0x00,  0x00,  0xB6,  0x02,  0x00, 	/* 209D0 */
+	0x04,  0x10,  0x04,  0x20,  0x03,  0xC0,  0x00,  0x80,  0x01,  0x00,  0x02,  0x00,  0x04,  0x00,  0x08,  0x00, 	/* 209E0 */
+	0x08,  0x00,  0x04,  0x00,  0x03,  0x00,  0x00,  0x80,  0x00,  0x40,  0x00,  0x40,  0x01,  0x80,  0xB7,  0x00, 	/* 209F0 */
+	0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x0C,  0xE0,  0x13,  0x10,  0x02, 	/* 20A00 */
+	0x10,  0x04,  0x10,  0x04,  0x10,  0x04,  0x20,  0x08,  0x20,  0x08,  0x20,  0x00,  0x40,  0x00,  0x40,  0xB8, 	/* 20A10 */
+	0x00,  0x00,  0x00,  0x60,  0x00,  0x90,  0x01,  0x08,  0x02,  0x08,  0x02,  0x08,  0x07,  0xF8,  0x04,  0x10, 	/* 20A20 */
+	0x08,  0x10,  0x08,  0x20,  0x08,  0x20,  0x08,  0x40,  0x04,  0x80,  0x03,  0x00,  0x00,  0x00,  0x00,  0x00, 	/* 20A30 */
+	0xB9,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x02,  0x00,  0x02, 	/* 20A40 */
+	0x00,  0x04,  0x00,  0x04,  0x00,  0x08,  0x00,  0x08,  0x20,  0x08,  0xC0,  0x07,  0x00,  0x00,  0x00,  0x00, 	/* 20A50 */
+	0x00,  0xBA,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x04,  0x30, 	/* 20A60 */
+	0x04,  0x48,  0x05,  0x80,  0x06,  0x00,  0x09,  0x00,  0x09,  0x00,  0x11,  0x10,  0x10,  0xE0,  0x00,  0x00, 	/* 20A70 */
+	0x00,  0x00,  0xBB,  0x00,  0x00,  0x00,  0x80,  0x00,  0x40,  0x00,  0x40,  0x00,  0x40,  0x00,  0x40,  0x00, 	/* 20A80 */
+	0x40,  0x00,  0xC0,  0x01,  0x40,  0x01,  0x40,  0x02,  0x20,  0x04,  0x20,  0x08,  0x10,  0x10,  0x08,  0x00, 	/* 20A90 */
+	0x00,  0x00,  0x00,  0xBC,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00, 	/* 20AA0 */
+	0x04,  0x20,  0x04,  0x20,  0x04,  0x20,  0x04,  0x40,  0x08,  0x40,  0x08,  0x40,  0x0C,  0xC8,  0x13,  0x30, 	/* 20AB0 */
+	0x10,  0x00,  0x20,  0x00,  0xBD,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00, 	/* 20AC0 */
+	0x00,  0x18,  0x10,  0x04,  0x10,  0x04,  0x20,  0x04,  0x20,  0x04,  0x40,  0x08,  0x80,  0x0B,  0x00,  0x1C, 	/* 20AD0 */
+	0x00,  0x00,  0x00,  0x00,  0x00,  0xBE,  0x00,  0x10,  0x00,  0xE0,  0x01,  0x00,  0x00,  0x80,  0x03,  0xE0, 	/* 20AE0 */
+	0x04,  0x00,  0x04,  0x00,  0x02,  0x00,  0x0F,  0xC0,  0x10,  0x00,  0x10,  0x00,  0x0E,  0x00,  0x01,  0x80, 	/* 20AF0 */
+	0x00,  0x40,  0x00,  0x40,  0x0F,  0x80,  0xBF,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00, 	/* 20B00 */
+	0x00,  0x00,  0x00,  0x01,  0xC0,  0x02,  0x20,  0x04,  0x10,  0x08,  0x10,  0x08,  0x10,  0x08,  0x20,  0x04, 	/* 20B10 */
+	0x40,  0x03,  0x80,  0x00,  0x00,  0x00,  0x00,  0x80,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00, 	/* 20B20 */
+	0x00,  0x00,  0x00,  0x08,  0x0F,  0xF0,  0x12,  0x40,  0x02,  0x40,  0x02,  0x40,  0x04,  0x80,  0x04,  0x80, 	/* 20B30 */
+	0x08,  0x90,  0x10,  0x60,  0x00,  0x00,  0x00,  0x00,  0x81,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00, 	/* 20B40 */
+	0x00,  0x00,  0x00,  0x00,  0x00,  0x01,  0xC0,  0x02,  0x20,  0x04,  0x10,  0x04,  0x10,  0x04,  0x10,  0x08, 	/* 20B50 */
+	0x10,  0x0A,  0x20,  0x09,  0xC0,  0x10,  0x00,  0x10,  0x00,  0x83,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00, 	/* 20B60 */
+	0x00,  0x00,  0x00,  0x00,  0x00,  0x08,  0x00,  0xF0,  0x01,  0x20,  0x02,  0x10,  0x04,  0x10,  0x04,  0x10, 	/* 20B70 */
+	0x04,  0x20,  0x02,  0x40,  0x01,  0x80,  0x00,  0x00,  0x00,  0x00,  0x84,  0x00,  0x00,  0x00,  0x00,  0x00, 	/* 20B80 */
+	0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x08,  0x0F,  0xF0,  0x11,  0x00,  0x01,  0x00,  0x02,  0x00,  0x02, 	/* 20B90 */
+	0x00,  0x04,  0x20,  0x04,  0x40,  0x03,  0x80,  0x00,  0x00,  0x00,  0x00,  0x85,  0x00,  0x00,  0x00,  0x00, 	/* 20BA0 */
+	0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x01,  0x10,  0x01,  0x08,  0x01,  0x08,  0x01,  0x10, 	/* 20BB0 */
+	0x02,  0x10,  0x02,  0x20,  0x02,  0x40,  0x01,  0x80,  0x00,  0x00,  0x00,  0x00,  0x86,  0x00,  0x00,  0x00, 	/* 20BC0 */
+	0x20,  0x00,  0x20,  0x00,  0x20,  0x00,  0x40,  0x00,  0x40,  0x01,  0xE0,  0x06,  0x90,  0x08,  0x90,  0x08, 	/* 20BD0 */
+	0x90,  0x09,  0x10,  0x09,  0x60,  0x07,  0x80,  0x02,  0x00,  0x02,  0x00,  0x02,  0x00,  0x87,  0x00,  0x00, 	/* 20BE0 */
+	0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x06,  0x10,  0x09,  0x20,  0x01,  0x40, 	/* 20BF0 */
+	0x01,  0x80,  0x01,  0x00,  0x03,  0x00,  0x05,  0x00,  0x09,  0x00,  0x10,  0x90,  0x20,  0x60,  0x88,  0x00, 	/* 20C00 */
+	0x00,  0x00,  0x20,  0x00,  0x20,  0x00,  0x40,  0x00,  0x40,  0x00,  0x40,  0x08,  0x88,  0x14,  0x88,  0x04, 	/* 20C10 */
+	0x90,  0x05,  0x10,  0x09,  0x20,  0x09,  0x40,  0x07,  0x80,  0x02,  0x00,  0x02,  0x00,  0x02,  0x00,  0x89, 	/* 20C20 */
+	0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x04,  0x10,  0x08,  0x90, 	/* 20C30 */
+	0x10,  0x88,  0x10,  0x88,  0x21,  0x08,  0x21,  0x08,  0x22,  0x90,  0x1C,  0x60,  0x00,  0x00,  0x00,  0x00, 	/* 20C40 */
+	0x81,  0x04,  0x10,  0x04,  0x10,  0x00,  0x00,  0x3F,  0xF0,  0x08,  0x10,  0x08,  0x08,  0x08,  0x00,  0x08, 	/* 20C50 */
+	0x40,  0x0F,  0xC0,  0x08,  0x40,  0x08,  0x00,  0x08,  0x08,  0x08,  0x10,  0x3F,  0xF0,  0x00,  0x00,  0x00, 	/* 20C60 */
+	0x00,  0x90,  0x00,  0x00,  0x00,  0x80,  0x00,  0x80,  0x01,  0x40,  0x01,  0x40,  0x02,  0x20,  0x02,  0x20, 	/* 20C70 */
+	0x04,  0x10,  0x07,  0xF0,  0x04,  0x10,  0x08,  0x08,  0x08,  0x08,  0x10,  0x04,  0x38,  0x0E,  0x00,  0x00, 	/* 20C80 */
+	0x00,  0x00,  0x91,  0x00,  0x00,  0x3F,  0xF0,  0x08,  0x10,  0x08,  0x08,  0x08,  0x00,  0x08,  0x00,  0x0F, 	/* 20C90 */
+	0xE0,  0x08,  0x10,  0x08,  0x08,  0x08,  0x04,  0x08,  0x04,  0x08,  0x08,  0x08,  0x30,  0x3F,  0xC0,  0x00, 	/* 20CA0 */
+	0x00,  0x00,  0x00,  0x92,  0x00,  0x00,  0x3F,  0xE0,  0x08,  0x10,  0x08,  0x08,  0x08,  0x08,  0x08,  0x10, 	/* 20CB0 */
+	0x0F,  0xE0,  0x08,  0x10,  0x08,  0x08,  0x08,  0x04,  0x08,  0x04,  0x08,  0x08,  0x08,  0x30,  0x3F,  0xC0, 	/* 20CC0 */
+	0x00,  0x00,  0x00,  0x00,  0x93,  0x00,  0x00,  0x1F,  0xF8,  0x04,  0x08,  0x04,  0x04,  0x04,  0x00,  0x04, 	/* 20CD0 */
+	0x00,  0x04,  0x00,  0x04,  0x00,  0x04,  0x00,  0x04,  0x00,  0x04,  0x00,  0x04,  0x00,  0x04,  0x00,  0x0E, 	/* 20CE0 */
+	0x00,  0x00,  0x00,  0x00,  0x00,  0x94,  0x00,  0x00,  0x0F,  0xFC,  0x02,  0x10,  0x02,  0x10,  0x02,  0x10, 	/* 20CF0 */
+	0x02,  0x10,  0x02,  0x10,  0x02,  0x10,  0x02,  0x10,  0x02,  0x10,  0x04,  0x10,  0x04,  0x10,  0x08,  0x10, 	/* 20D00 */
+	0x3F,  0xFC,  0x20,  0x04,  0x20,  0x04,  0x95,  0x00,  0x00,  0x3F,  0xF8,  0x08,  0x08,  0x08,  0x04,  0x08, 	/* 20D10 */
+	0x00,  0x08,  0x00,  0x08,  0x40,  0x0F,  0xC0,  0x08,  0x40,  0x08,  0x00,  0x08,  0x00,  0x08,  0x04,  0x08, 	/* 20D20 */
+	0x08,  0x3F,  0xF8,  0x00,  0x00,  0x00,  0x00,  0x96,  0x00,  0x00,  0x31,  0xC6,  0x48,  0x89,  0x08,  0x88, 	/* 20D30 */
+	0x08,  0x88,  0x08,  0x88,  0x04,  0x90,  0x07,  0xF0,  0x08,  0x88,  0x10,  0x84,  0x10,  0x84,  0x20,  0x82, 	/* 20D40 */
+	0x20,  0x82,  0x71,  0xC7,  0x00,  0x00,  0x00,  0x00,  0x97,  0x00,  0x00,  0x03,  0xC0,  0x0C,  0x30,  0x10, 	/* 20D50 */
+	0x18,  0x00,  0x08,  0x00,  0x08,  0x00,  0x10,  0x03,  0xE0,  0x00,  0x10,  0x00,  0x08,  0x00,  0x08,  0x10, 	/* 20D60 */
+	0x10,  0x0C,  0x30,  0x03,  0xC0,  0x00,  0x00,  0x00,  0x00,  0x98,  0x00,  0x00,  0x38,  0x1C,  0x10,  0x18, 	/* 20D70 */
+	0x10,  0x28,  0x10,  0x28,  0x10,  0x48,  0x10,  0x88,  0x10,  0x88,  0x11,  0x08,  0x12,  0x08,  0x12,  0x08, 	/* 20D80 */
+	0x14,  0x08,  0x18,  0x08,  0x10,  0x1C,  0x00,  0x00,  0x00,  0x00,  0x99,  0x06,  0x60,  0x04,  0x20,  0x3B, 	/* 20D90 */
+	0xCC,  0x10,  0x18,  0x10,  0x18,  0x10,  0x28,  0x10,  0x48,  0x10,  0x88,  0x10,  0x88,  0x11,  0x08,  0x12, 	/* 20DA0 */
+	0x08,  0x14,  0x08,  0x18,  0x08,  0x10,  0x1C,  0x00,  0x00,  0x00,  0x00,  0x9A,  0x00,  0x00,  0x1C,  0x38, 	/* 20DB0 */
+	0x08,  0x44,  0x08,  0x40,  0x08,  0x80,  0x08,  0x80,  0x09,  0x00,  0x0F,  0x00,  0x08,  0x80,  0x08,  0x40, 	/* 20DC0 */
+	0x08,  0x20,  0x08,  0x10,  0x08,  0x08,  0x1C,  0x1C,  0x00,  0x00,  0x00,  0x00,  0x9B,  0x00,  0x00,  0x0F, 	/* 20DD0 */
+	0xF8,  0x02,  0x10,  0x02,  0x10,  0x02,  0x10,  0x02,  0x10,  0x02,  0x10,  0x02,  0x10,  0x02,  0x10,  0x04, 	/* 20DE0 */
+	0x10,  0x04,  0x10,  0x08,  0x10,  0x50,  0x10,  0x60,  0x38,  0x00,  0x00,  0x00,  0x00,  0x9C,  0x00,  0x00, 	/* 20DF0 */
+	0x30,  0x0C,  0x10,  0x08,  0x18,  0x18,  0x18,  0x18,  0x14,  0x28,  0x14,  0x28,  0x12,  0x28,  0x12,  0x48, 	/* 20E00 */
+	0x22,  0x44,  0x21,  0x44,  0x21,  0x84,  0x20,  0x84,  0x78,  0x8E,  0x00,  0x00,  0x00,  0x00,  0x9D,  0x00, 	/* 20E10 */
+	0x00,  0x38,  0x1C,  0x10,  0x08,  0x10,  0x08,  0x10,  0x08,  0x10,  0x08,  0x10,  0x08,  0x1F,  0xF8,  0x10, 	/* 20E20 */
+	0x08,  0x10,  0x08,  0x10,  0x08,  0x10,  0x08,  0x10,  0x08,  0x38,  0x1C,  0x00,  0x00,  0x00,  0x00,  0x9E, 	/* 20E30 */
+	0x00,  0x00,  0x03,  0xC0,  0x0C,  0x30,  0x18,  0x18,  0x10,  0x08,  0x20,  0x04,  0x20,  0x04,  0x20,  0x04, 	/* 20E40 */
+	0x20,  0x04,  0x20,  0x04,  0x10,  0x08,  0x18,  0x18,  0x0C,  0x30,  0x03,  0xC0,  0x00,  0x00,  0x00,  0x00, 	/* 20E50 */
+	0x9F,  0x00,  0x00,  0x1F,  0xFC,  0x08,  0x08,  0x08,  0x08,  0x08,  0x08,  0x08,  0x08,  0x08,  0x08,  0x08, 	/* 20E60 */
+	0x08,  0x08,  0x08,  0x08,  0x08,  0x08,  0x08,  0x08,  0x08,  0x08,  0x08,  0x1C,  0x1C,  0x00,  0x00,  0x00, 	/* 20E70 */
+	0x00,  0xA0,  0x00,  0x00,  0x1F,  0xE0,  0x04,  0x18,  0x04,  0x04,  0x04,  0x04,  0x04,  0x04,  0x04,  0x18, 	/* 20E80 */
+	0x07,  0xE0,  0x04,  0x00,  0x04,  0x00,  0x04,  0x00,  0x04,  0x00,  0x04,  0x00,  0x0E,  0x00,  0x00,  0x00, 	/* 20E90 */
+	0x00,  0x00,  0xA1,  0x00,  0x00,  0x03,  0xC0,  0x0C,  0x28,  0x18,  0x18,  0x10,  0x08,  0x20,  0x00,  0x20, 	/* 20EA0 */
+	0x00,  0x20,  0x00,  0x20,  0x00,  0x20,  0x00,  0x10,  0x08,  0x18,  0x18,  0x0C,  0x30,  0x03,  0xC0,  0x00, 	/* 20EB0 */
+	0x00,  0x00,  0x00,  0xA2,  0x00,  0x00,  0x3F,  0xF8,  0x21,  0x08,  0x41,  0x04,  0x01,  0x00,  0x01,  0x00, 	/* 20EC0 */
+	0x01,  0x00,  0x01,  0x00,  0x01,  0x00,  0x01,  0x00,  0x01,  0x00,  0x01,  0x00,  0x01,  0x00,  0x03,  0x80, 	/* 20ED0 */
+	0x00,  0x00,  0x00,  0x00,  0xA3,  0x00,  0x00,  0x1C,  0x1C,  0x08,  0x08,  0x04,  0x10,  0x04,  0x10,  0x02, 	/* 20EE0 */
+	0x20,  0x02,  0x20,  0x01,  0x40,  0x01,  0x40,  0x00,  0x80,  0x00,  0x80,  0x01,  0x00,  0x12,  0x00,  0x0C, 	/* 20EF0 */
+	0x00,  0x00,  0x00,  0x00,  0x00,  0xA4,  0x00,  0x00,  0x01,  0xC0,  0x00,  0x80,  0x03,  0xE0,  0x0C,  0x98, 	/* 20F00 */
+	0x08,  0x88,  0x10,  0x84,  0x10,  0x84,  0x10,  0x84,  0x08,  0x88,  0x0C,  0x98,  0x03,  0xE0,  0x00,  0x80, 	/* 20F10 */
+	0x01,  0xC0,  0x00,  0x00,  0x00,  0x00,  0xA5,  0x00,  0x00,  0x38,  0x38,  0x10,  0x10,  0x08,  0x20,  0x04, 	/* 20F20 */
+	0x40,  0x04,  0x40,  0x02,  0x80,  0x01,  0x00,  0x02,  0x80,  0x04,  0x40,  0x04,  0x40,  0x08,  0x20,  0x10, 	/* 20F30 */
+	0x10,  0x38,  0x38,  0x00,  0x00,  0x00,  0x00,  0xA6,  0x00,  0x00,  0x38,  0x38,  0x10,  0x10,  0x10,  0x10, 	/* 20F40 */
+	0x10,  0x10,  0x10,  0x10,  0x10,  0x10,  0x10,  0x10,  0x10,  0x10,  0x10,  0x10,  0x10,  0x10,  0x10,  0x10, 	/* 20F50 */
+	0x10,  0x10,  0x3F,  0xFC,  0x00,  0x04,  0x00,  0x04,  0xA7,  0x00,  0x00,  0x1C,  0x38,  0x08,  0x10,  0x08, 	/* 20F60 */
+	0x10,  0x08,  0x10,  0x08,  0x10,  0x08,  0x10,  0x04,  0x30,  0x03,  0xD0,  0x00,  0x10,  0x00,  0x10,  0x00, 	/* 20F70 */
+	0x10,  0x00,  0x10,  0x00,  0x38,  0x00,  0x00,  0x00,  0x00,  0xA8,  0x00,  0x00,  0x39,  0xCE,  0x10,  0x84, 	/* 20F80 */
+	0x10,  0x84,  0x10,  0x84,  0x10,  0x84,  0x10,  0x84,  0x10,  0x84,  0x10,  0x84,  0x10,  0x84,  0x10,  0x84, 	/* 20F90 */
+	0x10,  0x84,  0x10,  0x84,  0x3F,  0xFE,  0x00,  0x00,  0x00,  0x00,  0xA9,  0x00,  0x00,  0x39,  0xCE,  0x10, 	/* 20FA0 */
+	0x84,  0x10,  0x84,  0x10,  0x84,  0x10,  0x84,  0x10,  0x84,  0x10,  0x84,  0x10,  0x84,  0x10,  0x84,  0x10, 	/* 20FB0 */
+	0x84,  0x10,  0x84,  0x10,  0x84,  0x3F,  0xFF,  0x00,  0x01,  0x00,  0x01,  0xAA,  0x00,  0x00,  0x3F,  0x00, 	/* 20FC0 */
+	0x22,  0x00,  0x42,  0x00,  0x02,  0x00,  0x02,  0x00,  0x03,  0xF0,  0x02,  0x0C,  0x02,  0x06,  0x02,  0x02, 	/* 20FD0 */
+	0x02,  0x02,  0x02,  0x06,  0x02,  0x0C,  0x07,  0xF0,  0x00,  0x00,  0x00,  0x00,  0xAB,  0x00,  0x00,  0x38, 	/* 20FE0 */
+	0x1C,  0x10,  0x08,  0x10,  0x08,  0x10,  0x08,  0x10,  0x08,  0x1E,  0x08,  0x11,  0x88,  0x10,  0xC8,  0x10, 	/* 20FF0 */
+	0x48,  0x10,  0x48,  0x10,  0xC8,  0x11,  0x88,  0x3E,  0x1C,  0x00,  0x00,  0x00,  0x00,  0xAC,  0x00,  0x00, 	/* 21000 */
+	0x1C,  0x00,  0x08,  0x00,  0x08,  0x00,  0x08,  0x00,  0x08,  0x00,  0x0F,  0xC0,  0x08,  0x30,  0x08,  0x18, 	/* 21010 */
+	0x08,  0x08,  0x08,  0x08,  0x08,  0x18,  0x08,  0x30,  0x1F,  0xC0,  0x00,  0x00,  0x00,  0x00,  0xAD,  0x00, 	/* 21020 */
+	0x00,  0x03,  0xC0,  0x0C,  0x30,  0x08,  0x18,  0x10,  0x08,  0x00,  0x0C,  0x07,  0x14,  0x08,  0xE4,  0x00, 	/* 21030 */
+	0x04,  0x00,  0x04,  0x10,  0x08,  0x08,  0x18,  0x0C,  0x30,  0x03,  0xC0,  0x00,  0x00,  0x00,  0x00,  0xAE, 	/* 21040 */
+	0x00,  0x00,  0x38,  0x70,  0x10,  0x88,  0x11,  0x04,  0x11,  0x04,  0x12,  0x02,  0x12,  0x02,  0x1E,  0x02, 	/* 21050 */
+	0x12,  0x02,  0x12,  0x02,  0x11,  0x04,  0x11,  0x04,  0x10,  0x88,  0x38,  0x70,  0x00,  0x00,  0x00,  0x00, 	/* 21060 */
+	0xAF,  0x00,  0x00,  0x03,  0xF8,  0x0C,  0x10,  0x10,  0x10,  0x10,  0x10,  0x10,  0x10,  0x0C,  0x10,  0x03, 	/* 21070 */
+	0xF0,  0x01,  0x10,  0x02,  0x10,  0x04,  0x10,  0x04,  0x10,  0x18,  0x10,  0x60,  0x38,  0x00,  0x00,  0x00, 	/* 21080 */
+	0x00,  0xB0,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x03,  0xC0,  0x04,  0x20, 	/* 21090 */
+	0x00,  0x20,  0x03,  0xA0,  0x04,  0x60,  0x08,  0x20,  0x08,  0x60,  0x08,  0xA8,  0x07,  0x18,  0x00,  0x00, 	/* 210A0 */
+	0x00,  0x00,  0xB1,  0x00,  0x00,  0x00,  0x10,  0x01,  0xE0,  0x02,  0x00,  0x04,  0x00,  0x04,  0x00,  0x0B, 	/* 210B0 */
+	0xC0,  0x0C,  0x20,  0x08,  0x10,  0x08,  0x10,  0x08,  0x10,  0x08,  0x10,  0x04,  0x20,  0x03,  0xC0,  0x00, 	/* 210C0 */
+	0x00,  0x00,  0x00,  0xB2,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x0F,  0xE0, 	/* 210D0 */
+	0x04,  0x10,  0x04,  0x10,  0x04,  0x20,  0x07,  0xE0,  0x04,  0x10,  0x04,  0x10,  0x04,  0x10,  0x0F,  0xE0, 	/* 210E0 */
+	0x00,  0x00,  0x00,  0x00,  0xB3,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x0F, 	/* 210F0 */
+	0xF0,  0x04,  0x10,  0x04,  0x10,  0x04,  0x00,  0x04,  0x00,  0x04,  0x00,  0x04,  0x00,  0x04,  0x00,  0x0E, 	/* 21100 */
+	0x00,  0x00,  0x00,  0x00,  0x00,  0xB4,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00, 	/* 21110 */
+	0x07,  0xF0,  0x02,  0x20,  0x02,  0x20,  0x02,  0x20,  0x02,  0x20,  0x02,  0x20,  0x04,  0x20,  0x04,  0x20, 	/* 21120 */
+	0x1F,  0xF8,  0x10,  0x08,  0x10,  0x08,  0xB5,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00, 	/* 21130 */
+	0x00,  0x03,  0x80,  0x04,  0x40,  0x08,  0x20,  0x08,  0x20,  0x0F,  0xE0,  0x08,  0x00,  0x08,  0x00,  0x04, 	/* 21140 */
+	0x20,  0x03,  0xC0,  0x00,  0x00,  0x00,  0x00,  0xB6,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00, 	/* 21150 */
+	0x00,  0x00,  0x19,  0xCC,  0x08,  0x88,  0x04,  0x90,  0x03,  0xE0,  0x02,  0xA0,  0x04,  0x90,  0x04,  0x90, 	/* 21160 */
+	0x08,  0x88,  0x11,  0xC4,  0x00,  0x00,  0x00,  0x00,  0xB7,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00, 	/* 21170 */
+	0x00,  0x00,  0x00,  0x03,  0xE0,  0x06,  0x10,  0x00,  0x10,  0x00,  0x20,  0x01,  0xE0,  0x00,  0x10,  0x00, 	/* 21180 */
+	0x10,  0x06,  0x10,  0x03,  0xE0,  0x00,  0x00,  0x00,  0x00,  0xB8,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00, 	/* 21190 */
+	0x00,  0x00,  0x00,  0x00,  0x0E,  0x1C,  0x04,  0x08,  0x04,  0x18,  0x04,  0x28,  0x04,  0x48,  0x05,  0x88, 	/* 211A0 */
+	0x06,  0x08,  0x04,  0x08,  0x0E,  0x1C,  0x00,  0x00,  0x00,  0x00,  0xB9,  0x00,  0x00,  0x00,  0x00,  0x03, 	/* 211B0 */
+	0x30,  0x02,  0x10,  0x01,  0xE0,  0x0E,  0x1C,  0x04,  0x08,  0x04,  0x18,  0x04,  0x28,  0x04,  0x48,  0x05, 	/* 211C0 */
+	0x88,  0x06,  0x08,  0x04,  0x08,  0x0E,  0x1C,  0x00,  0x00,  0x00,  0x00,  0xBA,  0x00,  0x00,  0x00,  0x00, 	/* 211D0 */
+	0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x0E,  0x30,  0x04,  0x50,  0x04,  0x80,  0x05,  0x00,  0x07,  0x00, 	/* 211E0 */
+	0x04,  0x80,  0x04,  0x40,  0x04,  0x20,  0x0E,  0x38,  0x00,  0x00,  0x00,  0x00,  0xBB,  0x00,  0x00,  0x00, 	/* 211F0 */
+	0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x03,  0xF8,  0x01,  0x10,  0x01,  0x10,  0x01,  0x10,  0x01, 	/* 21200 */
+	0x10,  0x01,  0x10,  0x11,  0x10,  0x12,  0x10,  0x0C,  0x38,  0x00,  0x00,  0x00,  0x00,  0xBC,  0x00,  0x00, 	/* 21210 */
+	0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x1C,  0x1C,  0x0C,  0x18,  0x0A,  0x28,  0x0A,  0x28, 	/* 21220 */
+	0x09,  0x48,  0x09,  0x48,  0x08,  0x88,  0x08,  0x88,  0x1C,  0x1C,  0x00,  0x00,  0x00,  0x00,  0xBD,  0x00, 	/* 21230 */
+	0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x0E,  0x38,  0x04,  0x10,  0x04,  0x10,  0x04, 	/* 21240 */
+	0x10,  0x07,  0xF0,  0x04,  0x10,  0x04,  0x10,  0x04,  0x10,  0x0E,  0x38,  0x00,  0x00,  0x00,  0x00,  0xBE, 	/* 21250 */
+	0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x03,  0xC0,  0x04,  0x20,  0x08,  0x10, 	/* 21260 */
+	0x08,  0x10,  0x08,  0x10,  0x08,  0x10,  0x08,  0x10,  0x04,  0x20,  0x03,  0xC0,  0x00,  0x00,  0x00,  0x00, 	/* 21270 */
+	0xBF,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x1F,  0xF0,  0x08,  0x20,  0x08, 	/* 21280 */
+	0x20,  0x08,  0x20,  0x08,  0x20,  0x08,  0x20,  0x08,  0x20,  0x08,  0x20,  0x1C,  0x70,  0x00,  0x00,  0x00, 	/* 21290 */
+	0x00,  0x80,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x0D,  0xC0,  0x06,  0x20, 	/* 212A0 */
+	0x04,  0x10,  0x04,  0x10,  0x04,  0x10,  0x04,  0x10,  0x06,  0x20,  0x05,  0xC0,  0x04,  0x00,  0x04,  0x00, 	/* 212B0 */
+	0x0E,  0x00,  0x81,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x03,  0x80,  0x04, 	/* 212C0 */
+	0x40,  0x08,  0x20,  0x08,  0x00,  0x08,  0x00,  0x08,  0x00,  0x08,  0x20,  0x04,  0x40,  0x03,  0x80,  0x00, 	/* 212D0 */
+	0x00,  0x00,  0x00,  0x82,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x1F,  0xF0, 	/* 212E0 */
+	0x11,  0x10,  0x11,  0x10,  0x01,  0x00,  0x01,  0x00,  0x01,  0x00,  0x01,  0x00,  0x01,  0x00,  0x03,  0x80, 	/* 212F0 */
+	0x00,  0x00,  0x00,  0x00,  0x83,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x0E, 	/* 21300 */
+	0x38,  0x04,  0x10,  0x04,  0x10,  0x02,  0x20,  0x02,  0x20,  0x01,  0x40,  0x01,  0x40,  0x00,  0x80,  0x01, 	/* 21310 */
+	0x00,  0x09,  0x00,  0x06,  0x00,  0x84,  0x00,  0x00,  0x01,  0x80,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80, 	/* 21320 */
+	0x00,  0x80,  0x06,  0xB0,  0x09,  0xC8,  0x10,  0x84,  0x10,  0x84,  0x10,  0x84,  0x10,  0x84,  0x09,  0xC8, 	/* 21330 */
+	0x06,  0xB0,  0x00,  0x80,  0x01,  0xC0,  0x85,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00, 	/* 21340 */
+	0x00,  0x0E,  0x38,  0x04,  0x10,  0x02,  0x20,  0x01,  0x40,  0x00,  0x80,  0x01,  0x40,  0x02,  0x20,  0x04, 	/* 21350 */
+	0x10,  0x0E,  0x38,  0x00,  0x00,  0x00,  0x00,  0x86,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00, 	/* 21360 */
+	0x00,  0x00,  0x1C,  0x70,  0x08,  0x20,  0x08,  0x20,  0x08,  0x20,  0x08,  0x20,  0x08,  0x20,  0x08,  0x20, 	/* 21370 */
+	0x08,  0x20,  0x1F,  0xF8,  0x00,  0x08,  0x00,  0x08,  0x87,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00, 	/* 21380 */
+	0x00,  0x00,  0x00,  0x0E,  0x38,  0x04,  0x10,  0x04,  0x10,  0x04,  0x10,  0x04,  0x10,  0x03,  0xF0,  0x00, 	/* 21390 */
+	0x10,  0x00,  0x10,  0x00,  0x38,  0x00,  0x00,  0x00,  0x00,  0x88,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00, 	/* 213A0 */
+	0x00,  0x00,  0x00,  0x00,  0x39,  0xCE,  0x10,  0x84,  0x10,  0x84,  0x10,  0x84,  0x10,  0x84,  0x10,  0x84, 	/* 213B0 */
+	0x10,  0x84,  0x10,  0x84,  0x3F,  0xFE,  0x00,  0x00,  0x00,  0x00,  0x89,  0x00,  0x00,  0x00,  0x00,  0x00, 	/* 213C0 */
+	0x00,  0x00,  0x00,  0x00,  0x00,  0x39,  0xCE,  0x10,  0x84,  0x10,  0x84,  0x10,  0x84,  0x10,  0x84,  0x10, 	/* 213D0 */
+	0x84,  0x10,  0x84,  0x10,  0x84,  0x3F,  0xFF,  0x00,  0x01,  0x00,  0x01,  0x8A,  0x00,  0x00,  0x00,  0x00, 	/* 213E0 */
+	0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x1F,  0x80,  0x11,  0x00,  0x11,  0x00,  0x01,  0x00,  0x01,  0xF0, 	/* 213F0 */
+	0x01,  0x0C,  0x01,  0x04,  0x01,  0x0C,  0x03,  0xF0,  0x00,  0x00,  0x00,  0x00,  0x8B,  0x00,  0x00,  0x00, 	/* 21400 */
+	0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x1C,  0x1C,  0x08,  0x08,  0x08,  0x08,  0x08,  0x08,  0x0F, 	/* 21410 */
+	0x08,  0x08,  0xC8,  0x08,  0x48,  0x08,  0xC8,  0x1F,  0x1C,  0x00,  0x00,  0x00,  0x00,  0x8C,  0x00,  0x00, 	/* 21420 */
+	0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x07,  0x00,  0x02,  0x00,  0x02,  0x00,  0x02,  0x00, 	/* 21430 */
+	0x03,  0xE0,  0x02,  0x18,  0x02,  0x08,  0x02,  0x18,  0x07,  0xE0,  0x00,  0x00,  0x00,  0x00,  0x8D,  0x00, 	/* 21440 */
+	0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x03,  0xC0,  0x04,  0x20,  0x08,  0x10,  0x03, 	/* 21450 */
+	0x30,  0x04,  0xD0,  0x00,  0x10,  0x08,  0x10,  0x04,  0x20,  0x03,  0xC0,  0x00,  0x00,  0x00,  0x00,  0x8E, 	/* 21460 */
+	0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x1C,  0x70,  0x08,  0x88,  0x09,  0x04, 	/* 21470 */
+	0x09,  0x04,  0x0F,  0x04,  0x09,  0x04,  0x09,  0x04,  0x08,  0x88,  0x1C,  0x70,  0x00,  0x00,  0x00,  0x00, 	/* 21480 */
+	0x8F,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x07,  0xF0,  0x08,  0x20,  0x08, 	/* 21490 */
+	0x20,  0x08,  0x20,  0x07,  0xE0,  0x02,  0x20,  0x04,  0x20,  0x04,  0x20,  0x18,  0x70,  0x00,  0x00,  0x00, 	/* 214A0 */
+	0x00,  0x91,  0x00,  0x00,  0x00,  0x00,  0x04,  0x40,  0x04,  0x40,  0x00,  0x00,  0x03,  0x80,  0x04,  0x40, 	/* 214B0 */
+	0x08,  0x20,  0x08,  0x20,  0x0F,  0xE0,  0x08,  0x00,  0x08,  0x00,  0x04,  0x20,  0x03,  0xC0,  0x00,  0x00, 	/* 214C0 */
+	0x00,  0x00,  0x90,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00, 	/* 214D0 */
+	0x00,  0x07,  0xE0,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00, 	/* 214E0 */
+	0x00,  0x00,  0x00,  0x95,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00, 	/* 214F0 */
+	0x00,  0x00,  0xFF,  0xFF,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00, 	/* 21500 */
+	0x00,  0x00,  0x00,  0x00,  0x98,  0x00,  0x08,  0x00,  0x10,  0x00,  0x18,  0x00,  0x18,  0x00,  0x00,  0x00, 	/* 21510 */
+	0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00, 	/* 21520 */
+	0x00,  0x00,  0x00,  0x00,  0x00,  0x99,  0x18,  0x00,  0x18,  0x00,  0x08,  0x00,  0x10,  0x00,  0x00,  0x00, 	/* 21530 */
+	0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00, 	/* 21540 */
+	0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x9C,  0x00,  0x24,  0x00,  0x48,  0x00,  0x6C,  0x00,  0x6C,  0x00, 	/* 21550 */
+	0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00, 	/* 21560 */
+	0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x9D,  0x36,  0x00,  0x36,  0x00,  0x12,  0x00,  0x24,  0x00, 	/* 21570 */
+	0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00, 	/* 21580 */
+	0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0xA0,  0x00,  0x80,  0x01,  0xC0,  0x04,  0x90,  0x0F, 	/* 21590 */
+	0xF8,  0x04,  0x90,  0x00,  0x80,  0x03,  0xE0,  0x01,  0xC0,  0x01,  0xC0,  0x01,  0xC0,  0x01,  0xC0,  0x01, 	/* 215A0 */
+	0xC0,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0xA1,  0x01,  0x00,  0x03,  0x80,  0x09,  0x20, 	/* 215B0 */
+	0x1F,  0xF0,  0x09,  0x20,  0x03,  0x80,  0x03,  0x80,  0x01,  0x00,  0x01,  0x00,  0x03,  0x80,  0x03,  0x80, 	/* 215C0 */
+	0x09,  0x20,  0x1F,  0xF0,  0x09,  0x20,  0x03,  0x80,  0x01,  0x00,  0xA5,  0x00,  0x00,  0x00,  0x00,  0x00, 	/* 215D0 */
+	0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x18,  0x18,  0x18,  0x18,  0x00,  0x00,  0x00, 	/* 215E0 */
+	0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0xA6,  0x00,  0x00,  0x00,  0x00, 	/* 215F0 */
+	0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x61,  0x86,  0x61,  0x86,  0x00,  0x00, 	/* 21600 */
+	0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0xB0,  0x00,  0x00,  0x00, 	/* 21610 */
+	0x08,  0x18,  0x10,  0x34,  0x20,  0x24,  0x20,  0x24,  0x40,  0x24,  0x80,  0x2D,  0x00,  0x1A,  0x00,  0x05, 	/* 21620 */
+	0x8C,  0x07,  0x5A,  0x0A,  0x52,  0x12,  0x52,  0x22,  0xD6,  0x41,  0x8C,  0x00,  0x00,  0xB2,  0x00,  0x00, 	/* 21630 */
+	0x08,  0x00,  0x18,  0x00,  0x30,  0x00,  0x20,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00, 	/* 21640 */
+	0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0xB3,  0x00, 	/* 21650 */
+	0x00,  0x11,  0x00,  0x33,  0x00,  0x66,  0x00,  0x44,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00, 	/* 21660 */
+	0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0xBB, 	/* 21670 */
+	0x00,  0x00,  0x00,  0x00,  0x21,  0x84,  0x11,  0x88,  0x08,  0x10,  0x04,  0x20,  0x02,  0x40,  0x31,  0x8C, 	/* 21680 */
+	0x31,  0x8C,  0x02,  0x40,  0x04,  0x20,  0x08,  0x10,  0x11,  0x88,  0x21,  0x84,  0x00,  0x00,  0x00,  0x00, 	/* 21690 */
+	0x83,  0x00,  0x00,  0x30,  0x72,  0x49,  0x8A,  0x4A,  0x06,  0x32,  0x02,  0x04,  0x02,  0x04,  0x00,  0x04, 	/* 216A0 */
+	0x00,  0x04,  0x00,  0x04,  0x00,  0x02,  0x02,  0x02,  0x04,  0x01,  0x98,  0x00,  0x60,  0x00,  0x00,  0x00, 	/* 216B0 */
+	0x00,  0xAB,  0x00,  0xC0,  0x01,  0x20,  0x01,  0x20,  0x00,  0xC0,  0x00,  0x80,  0x00,  0x80,  0x01,  0x40, 	/* 216C0 */
+	0x01,  0x40,  0x02,  0x20,  0x02,  0x20,  0x03,  0xE0,  0x04,  0x10,  0x04,  0x10,  0x0E,  0x38,  0x00,  0x00, 	/* 216D0 */
+	0x00,  0x00,  0x90,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x04,  0x00,  0x08,  0x00,  0x30, 	/* 216E0 */
+	0x00,  0xFF,  0xFF,  0x30,  0x00,  0x08,  0x00,  0x04,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00, 	/* 216F0 */
+	0x00,  0x00,  0x00,  0x91,  0x01,  0x00,  0x01,  0x00,  0x03,  0x80,  0x03,  0x80,  0x05,  0x40,  0x09,  0x20, 	/* 21700 */
+	0x01,  0x00,  0x01,  0x00,  0x01,  0x00,  0x01,  0x00,  0x01,  0x00,  0x01,  0x00,  0x01,  0x00,  0x01,  0x00, 	/* 21710 */
+	0x01,  0x00,  0x01,  0x00,  0x92,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x20,  0x00, 	/* 21720 */
+	0x10,  0x00,  0x0C,  0xFF,  0xFF,  0x00,  0x0C,  0x00,  0x10,  0x00,  0x20,  0x00,  0x00,  0x00,  0x00,  0x00, 	/* 21730 */
+	0x00,  0x00,  0x00,  0x00,  0x00,  0x93,  0x01,  0x00,  0x01,  0x00,  0x01,  0x00,  0x01,  0x00,  0x01,  0x00, 	/* 21740 */
+	0x01,  0x00,  0x01,  0x00,  0x01,  0x00,  0x01,  0x00,  0x01,  0x00,  0x09,  0x20,  0x05,  0x40,  0x03,  0x80, 	/* 21750 */
+	0x03,  0x80,  0x01,  0x00,  0x01,  0x00,  0x92,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x10,  0x00, 	/* 21760 */
+	0x08,  0xFF,  0xFC,  0x00,  0x02,  0x00,  0x01,  0x00,  0x02,  0xFF,  0xFC,  0x00,  0x08,  0x00,  0x10,  0x00, 	/* 21770 */
+	0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x94,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x08,  0x10, 	/* 21780 */
+	0x10,  0x08,  0x3F,  0xFC,  0x40,  0x02,  0x80,  0x01,  0x40,  0x02,  0x3F,  0xFC,  0x10,  0x08,  0x08,  0x10, 	/* 21790 */
+	0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x80,  0x00,  0x00,  0x20,  0x02,  0x20,  0x02,  0x10, 	/* 217A0 */
+	0x04,  0x10,  0x04,  0x0F,  0xF8,  0x08,  0x08,  0x04,  0x10,  0x04,  0x10,  0x02,  0x20,  0x02,  0x20,  0x01, 	/* 217B0 */
+	0x40,  0x01,  0x40,  0x00,  0x80,  0x00,  0x80,  0x00,  0x00,  0x82,  0x00,  0x00,  0x00,  0xC0,  0x03,  0x20, 	/* 217C0 */
+	0x04,  0x10,  0x00,  0x10,  0x00,  0x10,  0x03,  0xB0,  0x04,  0x60,  0x0C,  0x60,  0x08,  0x60,  0x18,  0x40, 	/* 217D0 */
+	0x18,  0xC0,  0x09,  0x80,  0x06,  0x00,  0x00,  0x00,  0x00,  0x00,  0x83,  0x00,  0x00,  0x00,  0x00,  0x1F, 	/* 217E0 */
+	0xF0,  0x00,  0x10,  0x00,  0x10,  0x00,  0x10,  0x00,  0x10,  0x1F,  0xF0,  0x00,  0x10,  0x00,  0x10,  0x00, 	/* 217F0 */
+	0x10,  0x00,  0x10,  0x1F,  0xF0,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x87,  0x00,  0x00,  0x7F,  0xFE, 	/* 21800 */
+	0x20,  0x04,  0x30,  0x04,  0x10,  0x08,  0x18,  0x08,  0x08,  0x10,  0x0C,  0x10,  0x04,  0x20,  0x06,  0x20, 	/* 21810 */
+	0x02,  0x40,  0x03,  0x40,  0x01,  0x80,  0x00,  0x80,  0x00,  0x00,  0x00,  0x00,  0x88,  0x00,  0x00,  0x00, 	/* 21820 */
+	0x00,  0x00,  0x00,  0x07,  0xF8,  0x08,  0x00,  0x10,  0x00,  0x10,  0x00,  0x1F,  0xF8,  0x10,  0x00,  0x10, 	/* 21830 */
+	0x00,  0x08,  0x00,  0x07,  0xF8,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x8B,  0x00,  0x00, 	/* 21840 */
+	0x00,  0x00,  0x00,  0x00,  0x1F,  0xE0,  0x00,  0x10,  0x00,  0x08,  0x00,  0x08,  0x1F,  0xF8,  0x00,  0x08, 	/* 21850 */
+	0x00,  0x08,  0x00,  0x10,  0x1F,  0xE0,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x9A,  0x00, 	/* 21860 */
+	0xFF,  0x00,  0x80,  0x00,  0x80,  0x01,  0x00,  0x01,  0x00,  0x01,  0x00,  0x01,  0x00,  0x02,  0x00,  0x02, 	/* 21870 */
+	0x00,  0x22,  0x00,  0x22,  0x00,  0x34,  0x00,  0x54,  0x00,  0x5C,  0x00,  0x08,  0x00,  0x08,  0x00,  0x9D, 	/* 21880 */
+	0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x1C,  0x38,  0x22,  0x44,  0x41,  0x80,  0x41,  0x80, 	/* 21890 */
+	0x41,  0x80,  0x41,  0x80,  0x22,  0x44,  0x1C,  0x38,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00, 	/* 218A0 */
+	0x9E,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x1C,  0x18,  0x26,  0x64,  0x42,  0x42,  0x41, 	/* 218B0 */
+	0x82,  0x41,  0x82,  0x42,  0x42,  0x26,  0x64,  0x18,  0x38,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00, 	/* 218C0 */
+	0x00,  0xA0,  0x00,  0x00,  0x00,  0x00,  0x00,  0x08,  0x00,  0x10,  0x00,  0x20,  0x00,  0x40,  0x00,  0x80, 	/* 218D0 */
+	0x01,  0x00,  0x02,  0x00,  0x04,  0x00,  0x08,  0x00,  0x10,  0x00,  0x3F,  0xFC,  0x00,  0x00,  0x00,  0x00, 	/* 218E0 */
+	0x00,  0x00,  0xA5,  0x04,  0x40,  0x04,  0x40,  0x04,  0x40,  0x04,  0x40,  0x04,  0x40,  0x04,  0x40,  0x04, 	/* 218F0 */
+	0x40,  0x04,  0x40,  0x04,  0x40,  0x04,  0x40,  0x04,  0x40,  0x04,  0x40,  0x04,  0x40,  0x04,  0x40,  0x04, 	/* 21900 */
+	0x40,  0x04,  0x40,  0xA7,  0x00,  0x00,  0x00,  0x00,  0x00,  0x80,  0x00,  0x80,  0x01,  0x40,  0x01,  0x40, 	/* 21910 */
+	0x02,  0x20,  0x02,  0x20,  0x04,  0x10,  0x04,  0x10,  0x08,  0x08,  0x08,  0x08,  0x10,  0x04,  0x10,  0x04, 	/* 21920 */
+	0x00,  0x00,  0x00,  0x00,  0xA8,  0x00,  0x00,  0x00,  0x00,  0x10,  0x04,  0x10,  0x04,  0x08,  0x08,  0x08, 	/* 21930 */
+	0x08,  0x04,  0x10,  0x04,  0x10,  0x02,  0x20,  0x02,  0x20,  0x01,  0x40,  0x01,  0x40,  0x00,  0x80,  0x00, 	/* 21940 */
+	0x80,  0x00,  0x00,  0x00,  0x00,  0xA9,  0x00,  0x00,  0x00,  0x00,  0x03,  0xC0,  0x04,  0x20,  0x08,  0x10, 	/* 21950 */
+	0x08,  0x10,  0x10,  0x08,  0x10,  0x08,  0x10,  0x08,  0x10,  0x08,  0x10,  0x08,  0x10,  0x08,  0x10,  0x08, 	/* 21960 */
+	0x10,  0x08,  0x00,  0x00,  0x00,  0x00,  0xAA,  0x00,  0x00,  0x00,  0x00,  0x10,  0x08,  0x10,  0x08,  0x10, 	/* 21970 */
+	0x08,  0x10,  0x08,  0x10,  0x08,  0x10,  0x08,  0x10,  0x08,  0x10,  0x08,  0x08,  0x10,  0x08,  0x10,  0x04, 	/* 21980 */
+	0x20,  0x03,  0xC0,  0x00,  0x00,  0x00,  0x00,  0xAB,  0x01,  0xC0,  0x02,  0x40,  0x02,  0x00,  0x02,  0x00, 	/* 21990 */
+	0x03,  0x00,  0x03,  0x00,  0x01,  0x00,  0x01,  0x80,  0x01,  0x80,  0x00,  0x80,  0x00,  0xC0,  0x00,  0xC0, 	/* 219A0 */
+	0x00,  0x40,  0x00,  0x40,  0x02,  0x40,  0x03,  0x80,  0xAC,  0x0E,  0x38,  0x12,  0x48,  0x10,  0x40,  0x10, 	/* 219B0 */
+	0x40,  0x18,  0x60,  0x18,  0x60,  0x08,  0x20,  0x0C,  0x30,  0x0C,  0x30,  0x04,  0x10,  0x06,  0x18,  0x06, 	/* 219C0 */
+	0x18,  0x02,  0x08,  0x02,  0x08,  0x12,  0x48,  0x1C,  0x70,  0xB4,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00, 	/* 219D0 */
+	0x01,  0x80,  0x01,  0x80,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00, 	/* 219E0 */
+	0x30,  0x0C,  0x30,  0x0C,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0xB5,  0x00,  0x00,  0x00,  0x00,  0x00, 	/* 219F0 */
+	0x00,  0x30,  0x0C,  0x30,  0x0C,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00, 	/* 21A00 */
+	0x00,  0x01,  0x80,  0x01,  0x80,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0xBD,  0x00,  0x00,  0x00,  0x00, 	/* 21A10 */
+	0x00,  0x00,  0x00,  0x00,  0x1C,  0x38,  0x20,  0x44,  0x40,  0x82,  0x40,  0x82,  0x41,  0x02,  0x41,  0x02, 	/* 21A20 */
+	0x22,  0x04,  0x1C,  0x38,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x92,  0x00,  0x00,  0x00, 	/* 21A30 */
+	0x00,  0x18,  0x00,  0x18,  0x00,  0x00,  0x00,  0x3F,  0xFC,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x3F, 	/* 21A40 */
+	0xFC,  0x00,  0x00,  0x00,  0x18,  0x00,  0x18,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0xA0,  0x00,  0x00, 	/* 21A50 */
+	0x00,  0x00,  0x00,  0x40,  0x00,  0x40,  0x00,  0x80,  0x3F,  0xFC,  0x00,  0x80,  0x01,  0x00,  0x01,  0x00, 	/* 21A60 */
+	0x3F,  0xFC,  0x01,  0x00,  0x02,  0x00,  0x02,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0xA1,  0x00, 	/* 21A70 */
+	0x00,  0x00,  0x00,  0x00,  0x00,  0x3F,  0xFC,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x3F,  0xFC,  0x00, 	/* 21A80 */
+	0x00,  0x00,  0x00,  0x00,  0x00,  0x3F,  0xFC,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0xA6, 	/* 21A90 */
+	0x00,  0x00,  0x00,  0x00,  0x00,  0x1C,  0x00,  0xE0,  0x07,  0x00,  0x38,  0x00,  0x07,  0x00,  0x00,  0xE0, 	/* 21AA0 */
+	0x00,  0x1C,  0x00,  0x00,  0x3F,  0xFC,  0x00,  0x00,  0x00,  0x00,  0x3F,  0xFC,  0x00,  0x00,  0x00,  0x00, 	/* 21AB0 */
+	0xA7,  0x00,  0x00,  0x00,  0x00,  0x38,  0x00,  0x07,  0x00,  0x00,  0xE0,  0x00,  0x1C,  0x00,  0xE0,  0x07, 	/* 21AC0 */
+	0x00,  0x38,  0x00,  0x00,  0x00,  0x3F,  0xFC,  0x00,  0x00,  0x00,  0x00,  0x3F,  0xFC,  0x00,  0x00,  0x00, 	/* 21AD0 */
+	0x00,  0xAA,  0x00,  0x00,  0x00,  0x88,  0x01,  0x10,  0x02,  0x20,  0x04,  0x40,  0x08,  0x80,  0x11,  0x00, 	/* 21AE0 */
+	0x22,  0x00,  0x11,  0x00,  0x08,  0x80,  0x04,  0x40,  0x02,  0x20,  0x01,  0x10,  0x00,  0x88,  0x00,  0x44, 	/* 21AF0 */
+	0x00,  0x00,  0xAB,  0x00,  0x00,  0x11,  0x00,  0x08,  0x80,  0x04,  0x40,  0x02,  0x20,  0x01,  0x10,  0x00, 	/* 21B00 */
+	0x88,  0x00,  0x44,  0x00,  0x88,  0x01,  0x10,  0x02,  0x20,  0x04,  0x40,  0x08,  0x80,  0x11,  0x00,  0x22, 	/* 21B10 */
+	0x00,  0x00,  0x00,  0x82,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x03,  0xFC,  0x0C,  0x00,  0x10,  0x00, 	/* 21B20 */
+	0x20,  0x00,  0x20,  0x00,  0x20,  0x00,  0x20,  0x00,  0x10,  0x00,  0x0C,  0x00,  0x03,  0xFC,  0x00,  0x00, 	/* 21B30 */
+	0x00,  0x00,  0x00,  0x00,  0x83,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x3F,  0xC0,  0x00,  0x30,  0x00, 	/* 21B40 */
+	0x08,  0x00,  0x04,  0x00,  0x04,  0x00,  0x04,  0x00,  0x04,  0x00,  0x08,  0x00,  0x30,  0x3F,  0xC0,  0x00, 	/* 21B50 */
+	0x00,  0x00,  0x00,  0x00,  0x00,  0x86,  0x00,  0x00,  0x00,  0x00,  0x0F,  0xFC,  0x10,  0x00,  0x20,  0x00, 	/* 21B60 */
+	0x20,  0x00,  0x20,  0x00,  0x20,  0x00,  0x10,  0x00,  0x0F,  0xFC,  0x00,  0x00,  0x00,  0x00,  0x3F,  0xFC, 	/* 21B70 */
+	0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x87,  0x00,  0x00,  0x00,  0x00,  0x3F,  0xF0,  0x00,  0x08,  0x00, 	/* 21B80 */
+	0x04,  0x00,  0x04,  0x00,  0x04,  0x00,  0x04,  0x00,  0x08,  0x3F,  0xF0,  0x00,  0x00,  0x00,  0x00,  0x3F, 	/* 21B90 */
+	0xFC,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0xA5,  0x00,  0x00,  0x00,  0x00,  0x01,  0x00,  0x01,  0x00, 	/* 21BA0 */
+	0x01,  0x00,  0x01,  0x00,  0x01,  0x00,  0x01,  0x00,  0x01,  0x00,  0x01,  0x00,  0x01,  0x00,  0x01,  0x00, 	/* 21BB0 */
+	0x3F,  0xFC,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x92,  0x07,  0xE0,  0x38,  0x1C,  0x40,  0x02,  0x00, 	/* 21BC0 */
+	0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00, 	/* 21BD0 */
+	0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x80,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00, 	/* 21BE0 */
+	0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0xFF,  0xFF,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00, 	/* 21BF0 */
+	0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x81,  0x00,  0x00,  0x00,  0x00,  0x00, 	/* 21C00 */
+	0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0xFF,  0xFF,  0xFF,  0xFF,  0x00,  0x00,  0x00, 	/* 21C10 */
+	0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x82,  0x01,  0x00,  0x01,  0x00, 	/* 21C20 */
+	0x01,  0x00,  0x01,  0x00,  0x01,  0x00,  0x01,  0x00,  0x01,  0x00,  0x01,  0x00,  0x01,  0x00,  0x01,  0x00, 	/* 21C30 */
+	0x01,  0x00,  0x01,  0x00,  0x01,  0x00,  0x01,  0x00,  0x01,  0x00,  0x01,  0x00,  0x83,  0x01,  0x80,  0x01, 	/* 21C40 */
+	0x80,  0x01,  0x80,  0x01,  0x80,  0x01,  0x80,  0x01,  0x80,  0x01,  0x80,  0x01,  0x80,  0x01,  0x80,  0x01, 	/* 21C50 */
+	0x80,  0x01,  0x80,  0x01,  0x80,  0x01,  0x80,  0x01,  0x80,  0x01,  0x80,  0x01,  0x80,  0x8C,  0x00,  0x00, 	/* 21C60 */
+	0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x01,  0xFF,  0x01,  0x00, 	/* 21C70 */
+	0x01,  0x00,  0x01,  0x00,  0x01,  0x00,  0x01,  0x00,  0x01,  0x00,  0x01,  0x00,  0x01,  0x00,  0x8F,  0x00, 	/* 21C80 */
+	0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x01,  0xFF,  0x01, 	/* 21C90 */
+	0xFF,  0x01,  0x80,  0x01,  0x80,  0x01,  0x80,  0x01,  0x80,  0x01,  0x80,  0x01,  0x80,  0x01,  0x80,  0x90, 	/* 21CA0 */
+	0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0xFF,  0x00, 	/* 21CB0 */
+	0x01,  0x00,  0x01,  0x00,  0x01,  0x00,  0x01,  0x00,  0x01,  0x00,  0x01,  0x00,  0x01,  0x00,  0x01,  0x00, 	/* 21CC0 */
+	0x93,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0xFF, 	/* 21CD0 */
+	0x80,  0xFF,  0x80,  0x01,  0x80,  0x01,  0x80,  0x01,  0x80,  0x01,  0x80,  0x01,  0x80,  0x01,  0x80,  0x01, 	/* 21CE0 */
+	0x80,  0x94,  0x01,  0x00,  0x01,  0x00,  0x01,  0x00,  0x01,  0x00,  0x01,  0x00,  0x01,  0x00,  0x01,  0x00, 	/* 21CF0 */
+	0x01,  0xFF,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00, 	/* 21D00 */
+	0x00,  0x00,  0x97,  0x01,  0x80,  0x01,  0x80,  0x01,  0x80,  0x01,  0x80,  0x01,  0x80,  0x01,  0x80,  0x01, 	/* 21D10 */
+	0x80,  0x01,  0xFF,  0x01,  0xFF,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00, 	/* 21D20 */
+	0x00,  0x00,  0x00,  0x98,  0x01,  0x00,  0x01,  0x00,  0x01,  0x00,  0x01,  0x00,  0x01,  0x00,  0x01,  0x00, 	/* 21D30 */
+	0x01,  0x00,  0xFF,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00, 	/* 21D40 */
+	0x00,  0x00,  0x00,  0x00,  0x9B,  0x01,  0x80,  0x01,  0x80,  0x01,  0x80,  0x01,  0x80,  0x01,  0x80,  0x01, 	/* 21D50 */
+	0x80,  0x01,  0x80,  0xFF,  0x80,  0xFF,  0x80,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00, 	/* 21D60 */
+	0x00,  0x00,  0x00,  0x00,  0x00,  0x9C,  0x01,  0x00,  0x01,  0x00,  0x01,  0x00,  0x01,  0x00,  0x01,  0x00, 	/* 21D70 */
+	0x01,  0x00,  0x01,  0x00,  0x01,  0xFF,  0x01,  0x00,  0x01,  0x00,  0x01,  0x00,  0x01,  0x00,  0x01,  0x00, 	/* 21D80 */
+	0x01,  0x00,  0x01,  0x00,  0x01,  0x00,  0x9D,  0x01,  0x00,  0x01,  0x00,  0x01,  0x00,  0x01,  0x00,  0x01, 	/* 21D90 */
+	0x00,  0x01,  0x00,  0x01,  0x00,  0x01,  0xFF,  0x01,  0xFF,  0x01,  0x00,  0x01,  0x00,  0x01,  0x00,  0x01, 	/* 21DA0 */
+	0x00,  0x01,  0x00,  0x01,  0x00,  0x01,  0x00,  0xA0,  0x01,  0x80,  0x01,  0x80,  0x01,  0x80,  0x01,  0x80, 	/* 21DB0 */
+	0x01,  0x80,  0x01,  0x80,  0x01,  0x80,  0x01,  0xFF,  0x01,  0x80,  0x01,  0x80,  0x01,  0x80,  0x01,  0x80, 	/* 21DC0 */
+	0x01,  0x80,  0x01,  0x80,  0x01,  0x80,  0x01,  0x80,  0xA3,  0x01,  0x80,  0x01,  0x80,  0x01,  0x80,  0x01, 	/* 21DD0 */
+	0x80,  0x01,  0x80,  0x01,  0x80,  0x01,  0x80,  0x01,  0xFF,  0x01,  0xFF,  0x01,  0x80,  0x01,  0x80,  0x01, 	/* 21DE0 */
+	0x80,  0x01,  0x80,  0x01,  0x80,  0x01,  0x80,  0x01,  0x80,  0xA4,  0x01,  0x00,  0x01,  0x00,  0x01,  0x00, 	/* 21DF0 */
+	0x01,  0x00,  0x01,  0x00,  0x01,  0x00,  0x01,  0x00,  0xFF,  0x00,  0x01,  0x00,  0x01,  0x00,  0x01,  0x00, 	/* 21E00 */
+	0x01,  0x00,  0x01,  0x00,  0x01,  0x00,  0x01,  0x00,  0x01,  0x00,  0xA5,  0x01,  0x00,  0x01,  0x00,  0x01, 	/* 21E10 */
+	0x00,  0x01,  0x00,  0x01,  0x00,  0x01,  0x00,  0x01,  0x00,  0xFF,  0x00,  0xFF,  0x00,  0x01,  0x00,  0x01, 	/* 21E20 */
+	0x00,  0x01,  0x00,  0x01,  0x00,  0x01,  0x00,  0x01,  0x00,  0x01,  0x00,  0xA8,  0x01,  0x80,  0x01,  0x80, 	/* 21E30 */
+	0x01,  0x80,  0x01,  0x80,  0x01,  0x80,  0x01,  0x80,  0x01,  0x80,  0xFF,  0x80,  0x01,  0x80,  0x01,  0x80, 	/* 21E40 */
+	0x01,  0x80,  0x01,  0x80,  0x01,  0x80,  0x01,  0x80,  0x01,  0x80,  0x01,  0x80,  0xAB,  0x01,  0x80,  0x01, 	/* 21E50 */
+	0x80,  0x01,  0x80,  0x01,  0x80,  0x01,  0x80,  0x01,  0x80,  0x01,  0x80,  0xFF,  0x80,  0xFF,  0x80,  0x01, 	/* 21E60 */
+	0x80,  0x01,  0x80,  0x01,  0x80,  0x01,  0x80,  0x01,  0x80,  0x01,  0x80,  0x01,  0x80,  0xAC,  0x00,  0x00, 	/* 21E70 */
+	0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0xFF,  0xFF,  0x01,  0x00, 	/* 21E80 */
+	0x01,  0x00,  0x01,  0x00,  0x01,  0x00,  0x01,  0x00,  0x01,  0x00,  0x01,  0x00,  0x01,  0x00,  0xAF,  0x00, 	/* 21E90 */
+	0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0xFF,  0xFF,  0xFF, 	/* 21EA0 */
+	0xFF,  0x01,  0x00,  0x01,  0x00,  0x01,  0x00,  0x01,  0x00,  0x01,  0x00,  0x01,  0x00,  0x01,  0x00,  0xB0, 	/* 21EB0 */
+	0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0xFF,  0xFF, 	/* 21EC0 */
+	0x01,  0x80,  0x01,  0x80,  0x01,  0x80,  0x01,  0x80,  0x01,  0x80,  0x01,  0x80,  0x01,  0x80,  0x01,  0x80, 	/* 21ED0 */
+	0xB3,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0xFF, 	/* 21EE0 */
+	0xFF,  0xFF,  0xFF,  0x01,  0x80,  0x01,  0x80,  0x01,  0x80,  0x01,  0x80,  0x01,  0x80,  0x01,  0x80,  0x01, 	/* 21EF0 */
+	0x80,  0xB4,  0x01,  0x00,  0x01,  0x00,  0x01,  0x00,  0x01,  0x00,  0x01,  0x00,  0x01,  0x00,  0x01,  0x00, 	/* 21F00 */
+	0xFF,  0xFF,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00, 	/* 21F10 */
+	0x00,  0x00,  0xB7,  0x01,  0x00,  0x01,  0x00,  0x01,  0x00,  0x01,  0x00,  0x01,  0x00,  0x01,  0x00,  0x01, 	/* 21F20 */
+	0x00,  0xFF,  0xFF,  0xFF,  0xFF,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00, 	/* 21F30 */
+	0x00,  0x00,  0x00,  0xB8,  0x01,  0x80,  0x01,  0x80,  0x01,  0x80,  0x01,  0x80,  0x01,  0x80,  0x01,  0x80, 	/* 21F40 */
+	0x01,  0x80,  0xFF,  0xFF,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00, 	/* 21F50 */
+	0x00,  0x00,  0x00,  0x00,  0xBB,  0x01,  0x80,  0x01,  0x80,  0x01,  0x80,  0x01,  0x80,  0x01,  0x80,  0x01, 	/* 21F60 */
+	0x80,  0x01,  0x80,  0xFF,  0xFF,  0xFF,  0xFF,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00, 	/* 21F70 */
+	0x00,  0x00,  0x00,  0x00,  0x00,  0xBC,  0x01,  0x00,  0x01,  0x00,  0x01,  0x00,  0x01,  0x00,  0x01,  0x00, 	/* 21F80 */
+	0x01,  0x00,  0x01,  0x00,  0xFF,  0xFF,  0x01,  0x00,  0x01,  0x00,  0x01,  0x00,  0x01,  0x00,  0x01,  0x00, 	/* 21F90 */
+	0x01,  0x00,  0x01,  0x00,  0x01,  0x00,  0xBF,  0x01,  0x00,  0x01,  0x00,  0x01,  0x00,  0x01,  0x00,  0x01, 	/* 21FA0 */
+	0x00,  0x01,  0x00,  0x01,  0x00,  0xFF,  0xFF,  0xFF,  0xFF,  0x01,  0x00,  0x01,  0x00,  0x01,  0x00,  0x01, 	/* 21FB0 */
+	0x00,  0x01,  0x00,  0x01,  0x00,  0x01,  0x00,  0x82,  0x01,  0x80,  0x01,  0x80,  0x01,  0x80,  0x01,  0x80, 	/* 21FC0 */
+	0x01,  0x80,  0x01,  0x80,  0x01,  0x80,  0xFF,  0xFF,  0x01,  0x80,  0x01,  0x80,  0x01,  0x80,  0x01,  0x80, 	/* 21FD0 */
+	0x01,  0x80,  0x01,  0x80,  0x01,  0x80,  0x01,  0x80,  0x8B,  0x01,  0x80,  0x01,  0x80,  0x01,  0x80,  0x01, 	/* 21FE0 */
+	0x80,  0x01,  0x80,  0x01,  0x80,  0x01,  0x80,  0xFF,  0xFF,  0xFF,  0xFF,  0x01,  0x80,  0x01,  0x80,  0x01, 	/* 21FF0 */
+	0x80,  0x01,  0x80,  0x01,  0x80,  0x01,  0x80,  0x01,  0x80,  0xA0,  0x00,  0x00,  0x7F,  0xFE,  0x7F,  0xFE, 	/* 22000 */
+	0x7F,  0xFE,  0x7F,  0xFE,  0x7F,  0xFE,  0x7F,  0xFE,  0x7F,  0xFE,  0x7F,  0xFE,  0x7F,  0xFE,  0x7F,  0xFE, 	/* 22010 */
+	0x7F,  0xFE,  0x7F,  0xFE,  0x7F,  0xFE,  0x7F,  0xFE,  0x00,  0x00,  0xA1,  0x00,  0x00,  0x7F,  0xFE,  0x40, 	/* 22020 */
+	0x02,  0x40,  0x02,  0x40,  0x02,  0x40,  0x02,  0x40,  0x02,  0x40,  0x02,  0x40,  0x02,  0x40,  0x02,  0x40, 	/* 22030 */
+	0x02,  0x40,  0x02,  0x40,  0x02,  0x40,  0x02,  0x7F,  0xFE,  0x00,  0x00,  0xB2,  0x00,  0x00,  0x01,  0x00, 	/* 22040 */
+	0x01,  0x00,  0x03,  0x80,  0x03,  0x80,  0x07,  0xC0,  0x07,  0xE0,  0x0F,  0xE0,  0x0F,  0xF0,  0x1F,  0xF0, 	/* 22050 */
+	0x1F,  0xF8,  0x3F,  0xFC,  0x3F,  0xFC,  0x7F,  0xFE,  0x00,  0x00,  0x00,  0x00,  0xB3,  0x00,  0x00,  0x01, 	/* 22060 */
+	0x00,  0x01,  0x00,  0x02,  0x80,  0x02,  0x80,  0x04,  0x40,  0x04,  0x40,  0x08,  0x20,  0x08,  0x10,  0x10, 	/* 22070 */
+	0x10,  0x10,  0x08,  0x20,  0x08,  0x20,  0x04,  0x7F,  0xFE,  0x00,  0x00,  0x00,  0x00,  0xBC,  0x00,  0x00, 	/* 22080 */
+	0x00,  0x00,  0x7F,  0xFE,  0x3F,  0xFC,  0x3F,  0xFC,  0x1F,  0xF8,  0x1F,  0xF0,  0x0F,  0xF0,  0x0F,  0xE0, 	/* 22090 */
+	0x07,  0xE0,  0x07,  0xC0,  0x03,  0x80,  0x03,  0x80,  0x01,  0x00,  0x01,  0x00,  0x00,  0x00,  0xBD,  0x00, 	/* 220A0 */
+	0x00,  0x00,  0x00,  0x7F,  0xFE,  0x20,  0x04,  0x20,  0x08,  0x10,  0x08,  0x10,  0x10,  0x08,  0x10,  0x08, 	/* 220B0 */
+	0x20,  0x04,  0x40,  0x04,  0x40,  0x02,  0x80,  0x02,  0x80,  0x01,  0x00,  0x01,  0x00,  0x00,  0x00,  0x86, 	/* 220C0 */
+	0x01,  0x80,  0x03,  0xC0,  0x07,  0xE0,  0x0F,  0xF0,  0x1F,  0xF8,  0x3F,  0xFC,  0x7F,  0xFE,  0xFF,  0xFF, 	/* 220D0 */
+	0xFF,  0xFF,  0x7F,  0xFE,  0x3F,  0xFC,  0x1F,  0xF8,  0x0F,  0xF0,  0x07,  0xE0,  0x03,  0xC0,  0x01,  0x80, 	/* 220E0 */
+	0x87,  0x01,  0x80,  0x02,  0x40,  0x04,  0x20,  0x08,  0x10,  0x10,  0x08,  0x20,  0x04,  0x40,  0x02,  0x80, 	/* 220F0 */
+	0x01,  0x80,  0x01,  0x40,  0x02,  0x20,  0x04,  0x10,  0x08,  0x08,  0x10,  0x04,  0x20,  0x02,  0x40,  0x01, 	/* 22100 */
+	0x80,  0x8B,  0x00,  0x00,  0x03,  0xC0,  0x0C,  0x30,  0x10,  0x08,  0x20,  0x04,  0x20,  0x04,  0x40,  0x02, 	/* 22110 */
+	0x40,  0x02,  0x40,  0x02,  0x40,  0x02,  0x20,  0x04,  0x20,  0x04,  0x10,  0x08,  0x0C,  0x30,  0x03,  0xC0, 	/* 22120 */
+	0x00,  0x00,  0x8E,  0x00,  0x00,  0x03,  0xC0,  0x0C,  0x30,  0x10,  0x08,  0x23,  0xC4,  0x24,  0x24,  0x48, 	/* 22130 */
+	0x12,  0x48,  0x12,  0x48,  0x12,  0x48,  0x12,  0x24,  0x24,  0x23,  0xC4,  0x10,  0x08,  0x0C,  0x30,  0x03, 	/* 22140 */
+	0xC0,  0x00,  0x00,  0x8F,  0x00,  0x00,  0x03,  0xC0,  0x0F,  0xF0,  0x1F,  0xF8,  0x3F,  0xFC,  0x3F,  0xFC, 	/* 22150 */
+	0x7F,  0xFE,  0x7F,  0xFE,  0x7F,  0xFE,  0x7F,  0xFE,  0x3F,  0xFC,  0x3F,  0xFC,  0x1F,  0xF8,  0x0F,  0xF0, 	/* 22160 */
+	0x03,  0xC0,  0x00,  0x00,  0xAF,  0x03,  0xC0,  0x0C,  0x30,  0x10,  0x08,  0x20,  0x04,  0x40,  0x02,  0x40, 	/* 22170 */
+	0x02,  0x80,  0x01,  0x80,  0x01,  0x80,  0x01,  0x80,  0x01,  0x40,  0x02,  0x40,  0x02,  0x20,  0x04,  0x10, 	/* 22180 */
+	0x08,  0x0C,  0x30,  0x03,  0xC0,  0x85,  0x00,  0x00,  0x01,  0x00,  0x01,  0x00,  0x03,  0x80,  0x03,  0x80, 	/* 22190 */
+	0x07,  0xC0,  0x7F,  0xFC,  0x3F,  0xF8,  0x1F,  0xF0,  0x0F,  0xE0,  0x0F,  0xE0,  0x1E,  0xF0,  0x1C,  0x70, 	/* 221A0 */
+	0x38,  0x38,  0x20,  0x08,  0x00,  0x00,  0x86,  0x00,  0x00,  0x01,  0x00,  0x01,  0x00,  0x02,  0x80,  0x02, 	/* 221B0 */
+	0x80,  0x04,  0x40,  0x7C,  0x7C,  0x20,  0x08,  0x10,  0x10,  0x08,  0x20,  0x08,  0x20,  0x11,  0x10,  0x12, 	/* 221C0 */
+	0x90,  0x2C,  0x68,  0x30,  0x18,  0x00,  0x00,  0x80,  0x00,  0x00,  0x03,  0xC0,  0x04,  0x20,  0x08,  0x10, 	/* 221D0 */
+	0x08,  0x10,  0x08,  0x10,  0x08,  0x10,  0x04,  0x20,  0x03,  0xC0,  0x01,  0x00,  0x1F,  0xF8,  0x01,  0x00, 	/* 221E0 */
+	0x01,  0x00,  0x01,  0x00,  0x01,  0x00,  0x01,  0x00,  0x82,  0x00,  0x00,  0x00,  0xFE,  0x00,  0x06,  0x00, 	/* 221F0 */
+	0x0A,  0x00,  0x12,  0x00,  0x22,  0x00,  0x42,  0x1E,  0x82,  0x21,  0x00,  0x40,  0x80,  0x40,  0x80,  0x40, 	/* 22200 */
+	0x80,  0x40,  0x80,  0x21,  0x00,  0x1E,  0x00,  0x00,  0x00,  0xAA,  0x00,  0x80,  0x00,  0x80,  0x00,  0xC0, 	/* 22210 */
+	0x00,  0xE0,  0x00,  0xB0,  0x00,  0x98,  0x00,  0x8C,  0x00,  0x84,  0x00,  0x84,  0x00,  0x88,  0x00,  0x90, 	/* 22220 */
+	0x00,  0x80,  0x0F,  0x80,  0x1F,  0x80,  0x1F,  0x00,  0x0E,  0x00,  0xAD,  0x04,  0x00,  0x04,  0x00,  0x04, 	/* 22230 */
+	0x00,  0x04,  0x00,  0x04,  0x00,  0x04,  0x00,  0x04,  0x00,  0x05,  0xE0,  0x06,  0x30,  0x04,  0x30,  0x04, 	/* 22240 */
+	0x30,  0x04,  0x60,  0x04,  0xC0,  0x05,  0x00,  0x06,  0x00,  0x04,  0x00,  0xAF,  0x00,  0x20,  0x04,  0x20, 	/* 22250 */
+	0x04,  0x20,  0x04,  0x3C,  0x07,  0xFC,  0x3F,  0xE0,  0x3C,  0x20,  0x04,  0x20,  0x04,  0x20,  0x04,  0x3C, 	/* 22260 */
+	0x07,  0xFC,  0x3F,  0xE0,  0x3C,  0x20,  0x04,  0x20,  0x04,  0x20,  0x04,  0x00,  0x80,  0x00,  0x00,  0x00, 	/* 22270 */
+	0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00, 	/* 22280 */
+	0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x81,  0x00,  0x00, 	/* 22290 */
+	0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00, 	/* 222A0 */
+	0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x20,  0x00,  0x10,  0x00,  0x08,  0x00,  0x08,  0x00,  0x82,  0x00, 	/* 222B0 */
+	0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00, 	/* 222C0 */
+	0x00,  0x00,  0x00,  0x00,  0x00,  0x30,  0x00,  0x48,  0x00,  0x48,  0x00,  0x30,  0x00,  0x00,  0x00,  0x83, 	/* 222D0 */
+	0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x01,  0x10,  0x01,  0x10,  0x01,  0x10,  0x02,  0x20, 	/* 222E0 */
+	0x02,  0x20,  0x04,  0x40,  0x08,  0x80,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00, 	/* 222F0 */
+	0x85,  0x00,  0x00,  0x01,  0x00,  0x01,  0x00,  0x01,  0x00,  0x01,  0xF8,  0x01,  0x08,  0x02,  0x08,  0x02, 	/* 22300 */
+	0x10,  0x04,  0x10,  0x09,  0xA0,  0x10,  0x60,  0x00,  0x10,  0x00,  0x08,  0x00,  0x08,  0x00,  0x00,  0x00, 	/* 22310 */
+	0x00,  0x86,  0x00,  0x00,  0x00,  0x02,  0x00,  0x02,  0x00,  0x04,  0x00,  0x08,  0x01,  0x90,  0x02,  0x60, 	/* 22320 */
+	0x04,  0x40,  0x04,  0xA0,  0x09,  0x00,  0x0A,  0x00,  0x0C,  0x00,  0x08,  0x00,  0x10,  0x00,  0x10,  0x00, 	/* 22330 */
+	0x00,  0x00,  0x87,  0x00,  0x00,  0x03,  0xC0,  0x0C,  0x30,  0x10,  0x08,  0x20,  0x04,  0x20,  0x04,  0x40, 	/* 22340 */
+	0x02,  0x40,  0x02,  0x40,  0x02,  0x40,  0x02,  0x20,  0x04,  0x20,  0x04,  0x10,  0x08,  0x0C,  0x30,  0x03, 	/* 22350 */
+	0xC0,  0x00,  0x00,  0x88,  0x00,  0x08,  0x00,  0x08,  0x00,  0x10,  0x00,  0x10,  0x00,  0x20,  0x00,  0x20, 	/* 22360 */
+	0x00,  0x40,  0x00,  0x80,  0x00,  0x80,  0x00,  0x40,  0x00,  0x20,  0x00,  0x20,  0x00,  0x10,  0x00,  0x10, 	/* 22370 */
+	0x00,  0x08,  0x00,  0x08,  0x89,  0x10,  0x00,  0x10,  0x00,  0x08,  0x00,  0x08,  0x00,  0x04,  0x00,  0x04, 	/* 22380 */
+	0x00,  0x02,  0x00,  0x01,  0x00,  0x01,  0x00,  0x02,  0x00,  0x04,  0x00,  0x04,  0x00,  0x08,  0x00,  0x08, 	/* 22390 */
+	0x00,  0x10,  0x00,  0x10,  0x00,  0x8A,  0x00,  0x24,  0x00,  0x24,  0x00,  0x48,  0x00,  0x48,  0x00,  0x90, 	/* 223A0 */
+	0x00,  0x90,  0x01,  0x20,  0x02,  0x40,  0x02,  0x40,  0x01,  0x20,  0x00,  0x90,  0x00,  0x90,  0x00,  0x48, 	/* 223B0 */
+	0x00,  0x48,  0x00,  0x24,  0x00,  0x24,  0x8B,  0x24,  0x00,  0x24,  0x00,  0x12,  0x00,  0x12,  0x00,  0x09, 	/* 223C0 */
+	0x00,  0x09,  0x00,  0x04,  0x80,  0x02,  0x40,  0x02,  0x40,  0x04,  0x80,  0x09,  0x00,  0x09,  0x00,  0x12, 	/* 223D0 */
+	0x00,  0x12,  0x00,  0x24,  0x00,  0x24,  0x00,  0x8C,  0x00,  0xF8,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80, 	/* 223E0 */
+	0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x00,  0x00, 	/* 223F0 */
+	0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x8D,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00, 	/* 22400 */
+	0x00,  0x00,  0x00,  0x01,  0x00,  0x01,  0x00,  0x01,  0x00,  0x01,  0x00,  0x01,  0x00,  0x01,  0x00,  0x01, 	/* 22410 */
+	0x00,  0x01,  0x00,  0x01,  0x00,  0x01,  0x00,  0x1F,  0x00,  0x8E,  0x01,  0xF8,  0x01,  0x08,  0x01,  0x78, 	/* 22420 */
+	0x01,  0x40,  0x01,  0x40,  0x01,  0x40,  0x01,  0x40,  0x01,  0x40,  0x01,  0x40,  0x01,  0x40,  0x01,  0xC0, 	/* 22430 */
+	0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x8F,  0x00,  0x00,  0x00,  0x00,  0x00, 	/* 22440 */
+	0x00,  0x00,  0x00,  0x00,  0x00,  0x03,  0x80,  0x02,  0x80,  0x02,  0x80,  0x02,  0x80,  0x02,  0x80,  0x02, 	/* 22450 */
+	0x80,  0x02,  0x80,  0x02,  0x80,  0x1E,  0x80,  0x10,  0x80,  0x1F,  0x80,  0x90,  0x00,  0xF8,  0x00,  0xF0, 	/* 22460 */
+	0x00,  0xE0,  0x00,  0xC0,  0x00,  0xC0,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80, 	/* 22470 */
+	0x00,  0x80,  0x00,  0xC0,  0x00,  0xC0,  0x00,  0xE0,  0x00,  0xF0,  0x00,  0xF8,  0x91,  0x1F,  0x00,  0x0F, 	/* 22480 */
+	0x00,  0x07,  0x00,  0x03,  0x00,  0x03,  0x00,  0x01,  0x00,  0x01,  0x00,  0x01,  0x00,  0x01,  0x00,  0x01, 	/* 22490 */
+	0x00,  0x01,  0x00,  0x03,  0x00,  0x03,  0x00,  0x07,  0x00,  0x0F,  0x00,  0x1F,  0x00,  0x92,  0x00,  0x00, 	/* 224A0 */
+	0x3F,  0xFC,  0x3F,  0xFC,  0x00,  0x00,  0x00,  0x00,  0x7F,  0xFE,  0x7F,  0xFE,  0x01,  0x80,  0x01,  0x80, 	/* 224B0 */
+	0x01,  0x80,  0x01,  0x80,  0x01,  0x80,  0x01,  0x80,  0x01,  0x80,  0x01,  0x80,  0x00,  0x00,  0x93,  0x00, 	/* 224C0 */
+	0x00,  0x00,  0x00,  0x00,  0x00,  0x3F,  0xFE,  0x3F,  0xFE,  0x3F,  0xFE,  0x00,  0x00,  0x00,  0x00,  0x00, 	/* 224D0 */
+	0x00,  0x00,  0x00,  0x3F,  0xFE,  0x3F,  0xFE,  0x3F,  0xFE,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x94, 	/* 224E0 */
+	0x00,  0x08,  0x00,  0x30,  0x00,  0xC0,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80, 	/* 224F0 */
+	0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x00,  0xC0,  0x00,  0x30,  0x00,  0x08, 	/* 22500 */
+	0x95,  0x10,  0x00,  0x0C,  0x00,  0x03,  0x00,  0x01,  0x00,  0x01,  0x00,  0x01,  0x00,  0x01,  0x00,  0x01, 	/* 22510 */
+	0x00,  0x01,  0x00,  0x01,  0x00,  0x01,  0x00,  0x01,  0x00,  0x01,  0x00,  0x03,  0x00,  0x0C,  0x00,  0x10, 	/* 22520 */
+	0x00,  0x81,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x02,  0x00,  0x02,  0xC0,  0x0F,  0x00,  0x02,  0x40, 	/* 22530 */
+	0x03,  0xE0,  0x06,  0x50,  0x0A,  0x88,  0x12,  0x88,  0x13,  0x08,  0x12,  0x10,  0x0C,  0x20,  0x00,  0xC0, 	/* 22540 */
+	0x00,  0x00,  0x82,  0x02,  0x00,  0x02,  0x00,  0x02,  0x60,  0x1F,  0x80,  0x02,  0x00,  0x02,  0x40,  0x03, 	/* 22550 */
+	0xF0,  0x04,  0x48,  0x0C,  0x44,  0x14,  0x82,  0x24,  0x82,  0x23,  0x02,  0x25,  0x04,  0x18,  0x18,  0x00, 	/* 22560 */
+	0x60,  0x00,  0x00,  0x83,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00, 	/* 22570 */
+	0x04,  0x00,  0x04,  0x10,  0x08,  0x08,  0x08,  0x08,  0x08,  0x04,  0x08,  0x04,  0x09,  0x04,  0x05,  0x00, 	/* 22580 */
+	0x02,  0x00,  0x00,  0x00,  0x84,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x10,  0x00,  0x10,  0x10,  0x10, 	/* 22590 */
+	0x08,  0x20,  0x04,  0x20,  0x04,  0x20,  0x02,  0x20,  0x02,  0x20,  0x02,  0x12,  0x02,  0x12,  0x00,  0x0C, 	/* 225A0 */
+	0x00,  0x00,  0x00,  0x00,  0x00,  0x85,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x01,  0x00,  0x00,  0xC0, 	/* 225B0 */
+	0x00,  0x00,  0x00,  0x00,  0x01,  0xE0,  0x06,  0x10,  0x00,  0x10,  0x00,  0x10,  0x00,  0x20,  0x00,  0x20, 	/* 225C0 */
+	0x00,  0x40,  0x01,  0x80,  0x00,  0x00,  0x86,  0x03,  0x00,  0x00,  0xC0,  0x00,  0x00,  0x00,  0x00,  0x03, 	/* 225D0 */
+	0xE0,  0x1C,  0x10,  0x00,  0x08,  0x00,  0x08,  0x00,  0x08,  0x00,  0x10,  0x00,  0x10,  0x00,  0x20,  0x00, 	/* 225E0 */
+	0x40,  0x01,  0x80,  0x06,  0x00,  0x00,  0x00,  0x87,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00, 	/* 225F0 */
+	0x02,  0x00,  0x01,  0x80,  0x00,  0x60,  0x00,  0x00,  0x0F,  0xE0,  0x00,  0x40,  0x00,  0x80,  0x01,  0x00, 	/* 22600 */
+	0x06,  0x80,  0x08,  0x80,  0x10,  0x80,  0x00,  0x78,  0x88,  0x02,  0x00,  0x01,  0x00,  0x00,  0xC0,  0x00, 	/* 22610 */
+	0x00,  0x0F,  0xF0,  0x00,  0x20,  0x00,  0x40,  0x00,  0x80,  0x01,  0x00,  0x03,  0x80,  0x04,  0x40,  0x08, 	/* 22620 */
+	0x40,  0x10,  0x40,  0x20,  0x20,  0x00,  0x1C,  0x00,  0x00,  0x89,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00, 	/* 22630 */
+	0x00,  0x00,  0x02,  0x00,  0x02,  0x10,  0x03,  0xC8,  0x1E,  0x08,  0x02,  0x00,  0x03,  0xE0,  0x06,  0x10, 	/* 22640 */
+	0x0A,  0x08,  0x12,  0x08,  0x12,  0x10,  0x0C,  0x60,  0x00,  0x00,  0x8A,  0x02,  0x00,  0x02,  0x00,  0x02, 	/* 22650 */
+	0x18,  0x03,  0xC4,  0x3E,  0x02,  0x02,  0x01,  0x02,  0x00,  0x03,  0xE0,  0x0E,  0x18,  0x12,  0x04,  0x22, 	/* 22660 */
+	0x04,  0x22,  0x04,  0x24,  0x08,  0x18,  0x30,  0x00,  0xC0,  0x00,  0x00,  0x8B,  0x00,  0x00,  0x04,  0x00, 	/* 22670 */
+	0x04,  0x00,  0x04,  0x10,  0x04,  0x08,  0x3F,  0x84,  0x04,  0x44,  0x08,  0x42,  0x08,  0x42,  0x08,  0x42, 	/* 22680 */
+	0x10,  0x40,  0x10,  0x40,  0x20,  0x80,  0x24,  0x80,  0x03,  0x00,  0x00,  0x00,  0x8C,  0x04,  0x00,  0x04, 	/* 22690 */
+	0x0A,  0x04,  0x0A,  0x04,  0x12,  0x04,  0x08,  0x3F,  0x84,  0x04,  0x44,  0x08,  0x42,  0x08,  0x42,  0x08, 	/* 226A0 */
+	0x42,  0x10,  0x40,  0x10,  0x40,  0x20,  0x80,  0x24,  0x80,  0x03,  0x00,  0x00,  0x00,  0x8D,  0x01,  0x00, 	/* 226B0 */
+	0x01,  0x00,  0x01,  0x70,  0x1F,  0x80,  0x00,  0x80,  0x00,  0xF8,  0x3F,  0x40,  0x00,  0x20,  0x00,  0x20, 	/* 226C0 */
+	0x07,  0xD0,  0x08,  0x30,  0x10,  0x00,  0x10,  0x00,  0x0C,  0x00,  0x03,  0xC0,  0x00,  0x00,  0x8E,  0x01, 	/* 226D0 */
+	0x04,  0x01,  0x12,  0x01,  0x7A,  0x1F,  0x88,  0x00,  0x80,  0x00,  0xF8,  0x3F,  0x40,  0x00,  0x20,  0x00, 	/* 226E0 */
+	0x20,  0x07,  0xD0,  0x08,  0x30,  0x10,  0x00,  0x10,  0x00,  0x0C,  0x00,  0x03,  0xC0,  0x00,  0x00,  0x8F, 	/* 226F0 */
+	0x00,  0x20,  0x00,  0x20,  0x00,  0x40,  0x00,  0x80,  0x01,  0x00,  0x02,  0x00,  0x04,  0x00,  0x04,  0x00, 	/* 22700 */
+	0x02,  0x00,  0x01,  0x00,  0x00,  0x80,  0x00,  0x40,  0x00,  0x40,  0x00,  0x20,  0x00,  0x20,  0x00,  0x00, 	/* 22710 */
+	0x90,  0x00,  0x20,  0x00,  0x20,  0x00,  0x44,  0x00,  0x92,  0x01,  0x0A,  0x02,  0x08,  0x04,  0x00,  0x04, 	/* 22720 */
+	0x00,  0x02,  0x00,  0x01,  0x00,  0x00,  0x80,  0x00,  0x40,  0x00,  0x40,  0x00,  0x20,  0x00,  0x20,  0x00, 	/* 22730 */
+	0x00,  0x91,  0x00,  0x10,  0x10,  0x10,  0x10,  0x10,  0x10,  0x10,  0x10,  0x1E,  0x23,  0xF0,  0x20,  0x10, 	/* 22740 */
+	0x20,  0x10,  0x20,  0x10,  0x20,  0x10,  0x28,  0x10,  0x10,  0x10,  0x10,  0x10,  0x00,  0x20,  0x00,  0xC0, 	/* 22750 */
+	0x00,  0x00,  0x92,  0x00,  0x12,  0x10,  0x19,  0x10,  0x15,  0x10,  0x14,  0x10,  0x1E,  0x23,  0xF0,  0x20, 	/* 22760 */
+	0x10,  0x20,  0x10,  0x20,  0x10,  0x20,  0x10,  0x28,  0x10,  0x10,  0x10,  0x10,  0x10,  0x00,  0x20,  0x00, 	/* 22770 */
+	0xC0,  0x00,  0x00,  0x93,  0x00,  0x00,  0x00,  0x00,  0x07,  0x00,  0x00,  0xF8,  0x00,  0x00,  0x00,  0x00, 	/* 22780 */
+	0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x10,  0x00,  0x10,  0x00,  0x10,  0x00,  0x08,  0x04,  0x07,  0xF8, 	/* 22790 */
+	0x00,  0x00,  0x00,  0x00,  0x94,  0x00,  0x00,  0x00,  0x0A,  0x07,  0x0A,  0x00,  0xFA,  0x00,  0x00,  0x00, 	/* 227A0 */
+	0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x10,  0x00,  0x10,  0x00,  0x10,  0x00,  0x08,  0x04,  0x07, 	/* 227B0 */
+	0xF8,  0x00,  0x00,  0x00,  0x00,  0x95,  0x00,  0x80,  0x00,  0x80,  0x00,  0x8C,  0x0F,  0xF0,  0x00,  0x40, 	/* 227C0 */
+	0x00,  0x20,  0x00,  0x20,  0x00,  0x10,  0x03,  0xE8,  0x04,  0x18,  0x08,  0x00,  0x08,  0x00,  0x04,  0x00, 	/* 227D0 */
+	0x03,  0x00,  0x00,  0xF0,  0x00,  0x00,  0x96,  0x01,  0x04,  0x01,  0x12,  0x01,  0x0A,  0x1F,  0xF8,  0x00, 	/* 227E0 */
+	0x80,  0x00,  0x40,  0x00,  0x40,  0x00,  0x20,  0x07,  0xD0,  0x08,  0x30,  0x10,  0x00,  0x10,  0x00,  0x08, 	/* 227F0 */
+	0x00,  0x06,  0x00,  0x01,  0xE0,  0x00,  0x00,  0x97,  0x00,  0x00,  0x08,  0x00,  0x08,  0x00,  0x08,  0x00, 	/* 22800 */
+	0x08,  0x00,  0x08,  0x00,  0x08,  0x00,  0x08,  0x00,  0x08,  0x00,  0x08,  0x00,  0x08,  0x00,  0x08,  0x08, 	/* 22810 */
+	0x08,  0x10,  0x04,  0x60,  0x03,  0x80,  0x00,  0x00,  0x98,  0x00,  0x00,  0x08,  0x00,  0x08,  0x10,  0x08, 	/* 22820 */
+	0x48,  0x08,  0x28,  0x08,  0x20,  0x08,  0x00,  0x08,  0x00,  0x08,  0x00,  0x08,  0x00,  0x08,  0x00,  0x08, 	/* 22830 */
+	0x08,  0x08,  0x10,  0x04,  0x60,  0x03,  0x80,  0x00,  0x00,  0x99,  0x00,  0x40,  0x00,  0x40,  0x00,  0x7E, 	/* 22840 */
+	0x3F,  0xC0,  0x00,  0x40,  0x00,  0x40,  0x03,  0x40,  0x04,  0xC0,  0x04,  0x40,  0x04,  0x40,  0x04,  0xC0, 	/* 22850 */
+	0x03,  0x40,  0x00,  0x40,  0x00,  0x40,  0x00,  0x80,  0x03,  0x00,  0x9A,  0x00,  0x42,  0x00,  0x49,  0x00, 	/* 22860 */
+	0x7D,  0x3F,  0xC4,  0x00,  0x40,  0x00,  0x40,  0x03,  0x40,  0x04,  0xC0,  0x04,  0x40,  0x04,  0x40,  0x04, 	/* 22870 */
+	0xC0,  0x03,  0x40,  0x00,  0x40,  0x00,  0x40,  0x00,  0x80,  0x03,  0x00,  0x9B,  0x00,  0x00,  0x00,  0x20, 	/* 22880 */
+	0x04,  0x20,  0x04,  0x20,  0x04,  0x3E,  0x07,  0xE0,  0x7C,  0x20,  0x04,  0x20,  0x04,  0x20,  0x04,  0x20, 	/* 22890 */
+	0x04,  0x40,  0x04,  0x00,  0x02,  0x00,  0x01,  0xF8,  0x00,  0x00,  0x00,  0x00,  0x9C,  0x00,  0x00,  0x00, 	/* 228A0 */
+	0x22,  0x04,  0x29,  0x04,  0x25,  0x04,  0x3C,  0x07,  0xE0,  0x7C,  0x20,  0x04,  0x20,  0x04,  0x20,  0x04, 	/* 228B0 */
+	0x20,  0x04,  0x40,  0x04,  0x00,  0x02,  0x00,  0x01,  0xF8,  0x00,  0x00,  0x00,  0x00,  0x9D,  0x00,  0x00, 	/* 228C0 */
+	0x07,  0xF0,  0x00,  0x40,  0x00,  0x80,  0x01,  0x00,  0x02,  0x00,  0x04,  0x3C,  0x3F,  0xC0,  0x00,  0x80, 	/* 228D0 */
+	0x01,  0x00,  0x02,  0x00,  0x02,  0x00,  0x02,  0x00,  0x01,  0x00,  0x00,  0xE0,  0x00,  0x00,  0x9E,  0x00, 	/* 228E0 */
+	0x04,  0x07,  0xF2,  0x00,  0x4A,  0x00,  0x88,  0x01,  0x00,  0x02,  0x00,  0x04,  0x3C,  0x3F,  0xC0,  0x00, 	/* 228F0 */
+	0x80,  0x01,  0x00,  0x02,  0x00,  0x02,  0x00,  0x02,  0x00,  0x01,  0x00,  0x00,  0xE0,  0x00,  0x00,  0x9F, 	/* 22900 */
+	0x04,  0x00,  0x04,  0x00,  0x04,  0xC0,  0x3F,  0x00,  0x04,  0x00,  0x08,  0x00,  0x08,  0x1C,  0x08,  0xE0, 	/* 22910 */
+	0x08,  0x00,  0x10,  0x00,  0x10,  0x00,  0x10,  0x00,  0x20,  0x80,  0x20,  0x80,  0x20,  0x7E,  0x00,  0x00, 	/* 22920 */
+	0xA0,  0x04,  0x00,  0x04,  0x04,  0x04,  0xD2,  0x3F,  0x0A,  0x04,  0x08,  0x08,  0x00,  0x08,  0x1C,  0x08, 	/* 22930 */
+	0xE0,  0x08,  0x00,  0x10,  0x00,  0x10,  0x00,  0x10,  0x00,  0x20,  0x80,  0x20,  0x80,  0x20,  0x7E,  0x00, 	/* 22940 */
+	0x00,  0xA1,  0x02,  0x00,  0x02,  0x00,  0x02,  0x00,  0x3F,  0xF0,  0x02,  0x00,  0x04,  0x00,  0x04,  0x00, 	/* 22950 */
+	0x04,  0xF0,  0x0B,  0x08,  0x0C,  0x04,  0x08,  0x04,  0x00,  0x04,  0x00,  0x08,  0x00,  0x30,  0x03,  0xC0, 	/* 22960 */
+	0x00,  0x00,  0xA2,  0x02,  0x04,  0x02,  0x12,  0x02,  0x0A,  0x3F,  0xF8,  0x02,  0x00,  0x04,  0x00,  0x04, 	/* 22970 */
+	0x00,  0x04,  0xF0,  0x0B,  0x08,  0x0C,  0x04,  0x08,  0x04,  0x00,  0x04,  0x00,  0x08,  0x00,  0x30,  0x03, 	/* 22980 */
+	0xC0,  0x00,  0x00,  0xA3,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00, 	/* 22990 */
+	0x00,  0x00,  0x00,  0x00,  0x01,  0xF0,  0x0E,  0x08,  0x00,  0x08,  0x00,  0x08,  0x00,  0x10,  0x00,  0x60, 	/* 229A0 */
+	0x01,  0x80,  0x00,  0x00,  0xA4,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0xE0,  0x07,  0x18,  0x78, 	/* 229B0 */
+	0x04,  0x00,  0x02,  0x00,  0x02,  0x00,  0x02,  0x00,  0x04,  0x00,  0x08,  0x00,  0x30,  0x01,  0xC0,  0x00, 	/* 229C0 */
+	0x00,  0x00,  0x00,  0x00,  0x00,  0xA5,  0x00,  0x02,  0x00,  0x09,  0x00,  0x05,  0x00,  0xE4,  0x07,  0x18, 	/* 229D0 */
+	0x78,  0x04,  0x00,  0x02,  0x00,  0x02,  0x00,  0x02,  0x00,  0x04,  0x00,  0x08,  0x00,  0x30,  0x01,  0xC0, 	/* 229E0 */
+	0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0xA6,  0x00,  0x00,  0x00,  0x0E,  0x03,  0xF0,  0x7C,  0x20,  0x00, 	/* 229F0 */
+	0x40,  0x00,  0x80,  0x00,  0x80,  0x01,  0x00,  0x01,  0x00,  0x01,  0x00,  0x01,  0x00,  0x00,  0x80,  0x00, 	/* 22A00 */
+	0x40,  0x00,  0x38,  0x00,  0x00,  0x00,  0x00,  0xA7,  0x00,  0x00,  0x00,  0x0E,  0x03,  0xF0,  0x7C,  0x22, 	/* 22A10 */
+	0x00,  0x49,  0x00,  0x85,  0x00,  0x84,  0x01,  0x00,  0x01,  0x00,  0x01,  0x00,  0x01,  0x00,  0x00,  0x80, 	/* 22A20 */
+	0x00,  0x40,  0x00,  0x38,  0x00,  0x00,  0x00,  0x00,  0xA8,  0x00,  0x00,  0x04,  0x00,  0x04,  0x00,  0x02, 	/* 22A30 */
+	0x00,  0x02,  0x00,  0x01,  0x0C,  0x01,  0x30,  0x00,  0xC0,  0x01,  0x00,  0x02,  0x00,  0x04,  0x00,  0x08, 	/* 22A40 */
+	0x00,  0x08,  0x00,  0x04,  0x00,  0x03,  0xFC,  0x00,  0x00,  0xA9,  0x00,  0x00,  0x08,  0x04,  0x08,  0x12, 	/* 22A50 */
+	0x04,  0x0A,  0x04,  0x08,  0x02,  0x18,  0x02,  0x60,  0x01,  0x80,  0x02,  0x00,  0x04,  0x00,  0x08,  0x00, 	/* 22A60 */
+	0x10,  0x00,  0x10,  0x00,  0x08,  0x00,  0x07,  0xF8,  0x00,  0x00,  0xAA,  0x04,  0x00,  0x04,  0x00,  0x07, 	/* 22A70 */
+	0x80,  0x3C,  0x18,  0x04,  0x04,  0x08,  0x22,  0x08,  0x20,  0x08,  0x20,  0x10,  0x20,  0x10,  0x20,  0x20, 	/* 22A80 */
+	0x20,  0x03,  0xE0,  0x04,  0x38,  0x04,  0x24,  0x03,  0xC0,  0x00,  0x00,  0xAB,  0x00,  0x00,  0x10,  0x00, 	/* 22A90 */
+	0x10,  0x00,  0x10,  0x38,  0x11,  0xC0,  0x20,  0x00,  0x20,  0x00,  0x20,  0x00,  0x20,  0x00,  0x20,  0x00, 	/* 22AA0 */
+	0x22,  0x00,  0x22,  0x00,  0x21,  0x80,  0x28,  0x7C,  0x10,  0x00,  0x00,  0x00,  0xAC,  0x00,  0x00,  0x00, 	/* 22AB0 */
+	0x80,  0x10,  0x80,  0x10,  0x80,  0x13,  0xF0,  0x1C,  0x88,  0x10,  0x84,  0x10,  0x82,  0x29,  0x02,  0x29, 	/* 22AC0 */
+	0x02,  0x46,  0x02,  0x44,  0x3A,  0x4A,  0x44,  0x30,  0x44,  0x00,  0x3A,  0x00,  0x00,  0xAD,  0x08,  0x00, 	/* 22AD0 */
+	0x08,  0x00,  0x08,  0x00,  0x0C,  0x70,  0x78,  0x88,  0x09,  0x04,  0x0A,  0x04,  0x0C,  0x04,  0x08,  0x04, 	/* 22AE0 */
+	0x18,  0x04,  0x18,  0x3C,  0x28,  0x44,  0x48,  0x46,  0x08,  0x38,  0x08,  0x00,  0x00,  0x00,  0xAE,  0x00, 	/* 22AF0 */
+	0x00,  0x00,  0x00,  0x01,  0xE0,  0x06,  0x90,  0x08,  0x88,  0x10,  0x84,  0x10,  0x84,  0x21,  0x02,  0x21, 	/* 22B00 */
+	0x02,  0x22,  0x04,  0x24,  0x04,  0x18,  0x08,  0x00,  0x10,  0x00,  0x60,  0x00,  0x00,  0x00,  0x00,  0xAF, 	/* 22B10 */
+	0x00,  0x10,  0x10,  0x10,  0x10,  0x10,  0x10,  0x10,  0x10,  0x1E,  0x23,  0xF0,  0x20,  0x10,  0x20,  0x10, 	/* 22B20 */
+	0x20,  0x10,  0x20,  0x10,  0x20,  0x10,  0x21,  0xF0,  0x2A,  0x1C,  0x12,  0x12,  0x11,  0xE0,  0x00,  0x00, 	/* 22B30 */
+	0xB0,  0x00,  0x10,  0x10,  0x15,  0x10,  0x15,  0x10,  0x15,  0x10,  0x1E,  0x13,  0xF0,  0x20,  0x10,  0x20, 	/* 22B40 */
+	0x10,  0x20,  0x10,  0x20,  0x10,  0x20,  0x10,  0x21,  0xF0,  0x2A,  0x1C,  0x12,  0x12,  0x11,  0xE0,  0x00, 	/* 22B50 */
+	0x00,  0xB1,  0x00,  0x16,  0x10,  0x19,  0x10,  0x19,  0x10,  0x16,  0x10,  0x1E,  0x13,  0xF0,  0x20,  0x10, 	/* 22B60 */
+	0x20,  0x10,  0x20,  0x10,  0x20,  0x10,  0x20,  0x10,  0x21,  0xF0,  0x2A,  0x1C,  0x12,  0x12,  0x11,  0xE0, 	/* 22B70 */
+	0x00,  0x00,  0xB2,  0x00,  0x00,  0x01,  0x00,  0x0F,  0x00,  0x72,  0x10,  0x04,  0x10,  0x08,  0x18,  0x10, 	/* 22B80 */
+	0x18,  0x10,  0x14,  0x20,  0x12,  0x20,  0x10,  0x20,  0x10,  0x20,  0x20,  0x10,  0x20,  0x08,  0xC0,  0x07, 	/* 22B90 */
+	0x00,  0x00,  0x00,  0xB3,  0x00,  0x00,  0x01,  0x02,  0x0F,  0x09,  0x72,  0x15,  0x04,  0x14,  0x08,  0x18, 	/* 22BA0 */
+	0x10,  0x18,  0x10,  0x14,  0x20,  0x12,  0x20,  0x10,  0x20,  0x10,  0x20,  0x20,  0x10,  0x20,  0x08,  0xC0, 	/* 22BB0 */
+	0x07,  0x00,  0x00,  0x00,  0xB4,  0x00,  0x06,  0x01,  0x09,  0x0F,  0x09,  0x72,  0x16,  0x04,  0x10,  0x08, 	/* 22BC0 */
+	0x18,  0x10,  0x18,  0x10,  0x14,  0x20,  0x12,  0x20,  0x10,  0x20,  0x10,  0x20,  0x20,  0x10,  0x20,  0x08, 	/* 22BD0 */
+	0xC0,  0x07,  0x00,  0x00,  0x00,  0xB5,  0x00,  0x00,  0x02,  0x00,  0x01,  0xC0,  0x00,  0x40,  0x00,  0x80, 	/* 22BE0 */
+	0x01,  0x00,  0x01,  0x00,  0x00,  0x88,  0x10,  0x44,  0x10,  0x42,  0x20,  0x21,  0x20,  0x21,  0x40,  0x20, 	/* 22BF0 */
+	0x04,  0x40,  0x03,  0x80,  0x00,  0x00,  0xB6,  0x00,  0x00,  0x02,  0x04,  0x01,  0xD2,  0x00,  0x4A,  0x00, 	/* 22C00 */
+	0x88,  0x01,  0x00,  0x01,  0x00,  0x00,  0x88,  0x10,  0x44,  0x10,  0x42,  0x20,  0x21,  0x20,  0x21,  0x40, 	/* 22C10 */
+	0x20,  0x04,  0x40,  0x03,  0x80,  0x00,  0x00,  0xB7,  0x00,  0x0C,  0x02,  0x12,  0x01,  0xD2,  0x00,  0x4C, 	/* 22C20 */
+	0x00,  0x80,  0x01,  0x00,  0x01,  0x00,  0x00,  0x88,  0x10,  0x44,  0x10,  0x42,  0x20,  0x21,  0x20,  0x21, 	/* 22C30 */
+	0x40,  0x20,  0x04,  0x40,  0x03,  0x80,  0x00,  0x00,  0xB8,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00, 	/* 22C40 */
+	0x00,  0x06,  0x00,  0x09,  0x00,  0x10,  0x80,  0x20,  0x40,  0x40,  0x20,  0x00,  0x18,  0x00,  0x06,  0x00, 	/* 22C50 */
+	0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0xB9,  0x00,  0x00,  0x00,  0x00,  0x00,  0x08, 	/* 22C60 */
+	0x00,  0x24,  0x06,  0x14,  0x09,  0x10,  0x10,  0x80,  0x20,  0x40,  0x40,  0x20,  0x00,  0x18,  0x00,  0x06, 	/* 22C70 */
+	0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0xBA,  0x00,  0x00,  0x00,  0x00,  0x00, 	/* 22C80 */
+	0x18,  0x00,  0x24,  0x00,  0x24,  0x06,  0x18,  0x09,  0x00,  0x10,  0x80,  0x20,  0x40,  0x40,  0x20,  0x00, 	/* 22C90 */
+	0x18,  0x00,  0x06,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0xBB,  0x00,  0x00,  0x13,  0xFC, 	/* 22CA0 */
+	0x10,  0x10,  0x10,  0x10,  0x10,  0x10,  0x20,  0x1C,  0x23,  0xF0,  0x20,  0x10,  0x20,  0x10,  0x20,  0x10, 	/* 22CB0 */
+	0x20,  0x10,  0x21,  0xF0,  0x2A,  0x1C,  0x12,  0x12,  0x11,  0xE0,  0x00,  0x00,  0xBC,  0x00,  0x02,  0x13, 	/* 22CC0 */
+	0xF9,  0x10,  0x15,  0x10,  0x14,  0x10,  0x10,  0x20,  0x1C,  0x23,  0xF0,  0x20,  0x10,  0x20,  0x10,  0x20, 	/* 22CD0 */
+	0x10,  0x20,  0x10,  0x21,  0xF0,  0x2A,  0x1C,  0x12,  0x12,  0x11,  0xE0,  0x00,  0x00,  0xBD,  0x00,  0x06, 	/* 22CE0 */
+	0x13,  0xF9,  0x10,  0x19,  0x10,  0x16,  0x10,  0x10,  0x20,  0x1C,  0x23,  0xF0,  0x20,  0x10,  0x20,  0x10, 	/* 22CF0 */
+	0x20,  0x10,  0x20,  0x10,  0x21,  0xF0,  0x2A,  0x1C,  0x12,  0x12,  0x11,  0xE0,  0x00,  0x00,  0xBE,  0x00, 	/* 22D00 */
+	0x40,  0x00,  0x40,  0x1F,  0xFC,  0x00,  0x40,  0x00,  0x40,  0x00,  0x78,  0x1F,  0xC0,  0x00,  0x40,  0x00, 	/* 22D10 */
+	0x40,  0x00,  0x40,  0x07,  0xC0,  0x08,  0x70,  0x10,  0x4C,  0x18,  0x40,  0x07,  0x80,  0x00,  0x00,  0xBF, 	/* 22D20 */
+	0x00,  0x00,  0x00,  0x00,  0x1F,  0x80,  0x00,  0x80,  0x00,  0x80,  0x01,  0x08,  0x01,  0x08,  0x01,  0x08, 	/* 22D30 */
+	0x07,  0xE8,  0x1A,  0x1C,  0x22,  0x12,  0x44,  0x10,  0x48,  0x20,  0x30,  0x20,  0x00,  0x40,  0x00,  0x00, 	/* 22D40 */
+	0x80,  0x04,  0x00,  0x04,  0x00,  0x04,  0x00,  0x3F,  0x88,  0x04,  0x04,  0x04,  0x04,  0x1C,  0x02,  0x24, 	/* 22D50 */
+	0x02,  0x24,  0x10,  0x24,  0x08,  0x28,  0x08,  0x18,  0x08,  0x08,  0x08,  0x08,  0x10,  0x07,  0xE0,  0x00, 	/* 22D60 */
+	0x00,  0x81,  0x00,  0x00,  0x00,  0x40,  0x10,  0x40,  0x10,  0x40,  0x11,  0xF0,  0x16,  0x88,  0x18,  0x84, 	/* 22D70 */
+	0x18,  0x84,  0x29,  0x02,  0x25,  0x02,  0x42,  0x02,  0x42,  0x04,  0x4D,  0x04,  0x30,  0x08,  0x00,  0x30, 	/* 22D80 */
+	0x00,  0x00,  0x82,  0x02,  0x00,  0x02,  0x00,  0x02,  0x00,  0x1F,  0xC0,  0x02,  0x00,  0x02,  0x00,  0x04, 	/* 22D90 */
+	0x60,  0x3F,  0x80,  0x04,  0x00,  0x04,  0x04,  0x04,  0x04,  0x04,  0x04,  0x02,  0x08,  0x01,  0x10,  0x00, 	/* 22DA0 */
+	0xE0,  0x00,  0x00,  0x83,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0xC0,  0x08,  0x20, 	/* 22DB0 */
+	0x08,  0x00,  0x04,  0xF0,  0x07,  0x08,  0x0C,  0x08,  0x32,  0x10,  0x02,  0x60,  0x01,  0x00,  0x01,  0x00, 	/* 22DC0 */
+	0x01,  0x00,  0x00,  0x00,  0x84,  0x00,  0x40,  0x00,  0x20,  0x10,  0x10,  0x10,  0x10,  0x08,  0x00,  0x08, 	/* 22DD0 */
+	0x7C,  0x05,  0x82,  0x0E,  0x02,  0x74,  0x02,  0x02,  0x04,  0x02,  0x38,  0x01,  0x00,  0x01,  0x00,  0x00, 	/* 22DE0 */
+	0x80,  0x00,  0x80,  0x00,  0x80,  0x85,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x80, 	/* 22DF0 */
+	0x10,  0x80,  0x11,  0xE0,  0x12,  0x90,  0x14,  0x88,  0x18,  0x88,  0x18,  0x88,  0x12,  0x90,  0x11,  0xE0, 	/* 22E00 */
+	0x00,  0x80,  0x01,  0x00,  0x02,  0x00,  0x86,  0x00,  0x00,  0x00,  0x80,  0x20,  0x40,  0x20,  0xF8,  0x23, 	/* 22E10 */
+	0x44,  0x24,  0x42,  0x28,  0x42,  0x30,  0x42,  0x30,  0x42,  0x22,  0x44,  0x21,  0x48,  0x20,  0xF0,  0x00, 	/* 22E20 */
+	0x40,  0x00,  0x80,  0x01,  0x00,  0x00,  0x00,  0x87,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00, 	/* 22E30 */
+	0x01,  0x00,  0x01,  0x00,  0x01,  0x00,  0x01,  0xE0,  0x01,  0x00,  0x01,  0x00,  0x01,  0x00,  0x0F,  0x00, 	/* 22E40 */
+	0x11,  0xC0,  0x11,  0x30,  0x0E,  0x00,  0x00,  0x00,  0x88,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x00, 	/* 22E50 */
+	0x8C,  0x00,  0xF0,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x0F,  0x80,  0x30, 	/* 22E60 */
+	0xE0,  0x20,  0x98,  0x21,  0x04,  0x1E,  0x00,  0x00,  0x00,  0x89,  0x01,  0x00,  0x00,  0x80,  0x00,  0x60, 	/* 22E70 */
+	0x08,  0x00,  0x08,  0x00,  0x08,  0x00,  0x08,  0x00,  0x08,  0xF0,  0x0B,  0x08,  0x0C,  0x04,  0x08,  0x04, 	/* 22E80 */
+	0x00,  0x08,  0x00,  0x10,  0x00,  0x60,  0x03,  0x80,  0x00,  0x00,  0x8A,  0x00,  0x20,  0x04,  0x10,  0x04, 	/* 22E90 */
+	0x10,  0x04,  0x10,  0x08,  0x10,  0x08,  0x10,  0x08,  0x10,  0x08,  0x10,  0x0A,  0x10,  0x04,  0x10,  0x00, 	/* 22EA0 */
+	0x20,  0x00,  0x20,  0x00,  0x40,  0x00,  0x80,  0x03,  0x00,  0x00,  0x00,  0x8B,  0x00,  0x00,  0x07,  0xE0, 	/* 22EB0 */
+	0x00,  0x40,  0x00,  0x80,  0x01,  0x00,  0x02,  0x00,  0x07,  0xE0,  0x0C,  0x10,  0x10,  0x08,  0x20,  0x04, 	/* 22EC0 */
+	0x00,  0x04,  0x03,  0x04,  0x04,  0x88,  0x04,  0x70,  0x03,  0xC0,  0x00,  0x00,  0x8C,  0x04,  0x00,  0x04, 	/* 22ED0 */
+	0x00,  0x04,  0x00,  0x04,  0xE0,  0x0D,  0x10,  0x76,  0x10,  0x04,  0x10,  0x04,  0x10,  0x04,  0x10,  0x0C, 	/* 22EE0 */
+	0x10,  0x0C,  0x10,  0x14,  0x11,  0x24,  0x12,  0x44,  0x0C,  0x04,  0x00,  0x00,  0x00,  0x8D,  0x00,  0x00, 	/* 22EF0 */
+	0x07,  0xE0,  0x00,  0x20,  0x00,  0x40,  0x00,  0x80,  0x01,  0x00,  0x03,  0xF0,  0x06,  0x08,  0x08,  0x04, 	/* 22F00 */
+	0x10,  0x04,  0x00,  0x04,  0x00,  0x08,  0x00,  0x10,  0x00,  0x60,  0x01,  0x80,  0x00,  0x00,  0x8E,  0x00, 	/* 22F10 */
+	0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x04,  0x00,  0x04,  0x00,  0x04,  0x00,  0x06,  0xE0,  0x1D, 	/* 22F20 */
+	0x10,  0x06,  0x08,  0x04,  0x08,  0x0C,  0x08,  0x14,  0x10,  0x04,  0x60,  0x04,  0x00,  0x04,  0x00,  0x8F, 	/* 22F30 */
+	0x08,  0x00,  0x08,  0x00,  0x08,  0x00,  0x0E,  0x00,  0x1C,  0x00,  0x68,  0xF0,  0x0B,  0x08,  0x0C,  0x04, 	/* 22F40 */
+	0x08,  0x02,  0x18,  0x02,  0x28,  0x04,  0x48,  0x04,  0x08,  0x18,  0x08,  0x60,  0x08,  0x00,  0x00,  0x00, 	/* 22F50 */
+	0x90,  0x00,  0x00,  0x0F,  0x80,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x03,  0xF0,  0x0D, 	/* 22F60 */
+	0x08,  0x11,  0x04,  0x22,  0x02,  0x42,  0x02,  0x44,  0x72,  0x48,  0x8C,  0x30,  0x8A,  0x00,  0x70,  0x00, 	/* 22F70 */
+	0x00,  0x91,  0x00,  0x00,  0x1F,  0xC0,  0x00,  0x80,  0x03,  0x00,  0x07,  0xC0,  0x08,  0x20,  0x10,  0x10, 	/* 22F80 */
+	0x06,  0x10,  0x09,  0x20,  0x09,  0x40,  0x07,  0x80,  0x04,  0x00,  0x0E,  0x70,  0x31,  0x88,  0x40,  0x1C, 	/* 22F90 */
+	0x00,  0x00,  0x92,  0x01,  0x00,  0x01,  0x00,  0x01,  0xE0,  0x1F,  0x00,  0x02,  0x00,  0x02,  0x06,  0x07, 	/* 22FA0 */
+	0x98,  0x08,  0x60,  0x10,  0xC0,  0x21,  0x40,  0x02,  0x40,  0x04,  0x40,  0x04,  0x00,  0x02,  0x00,  0x01, 	/* 22FB0 */
+	0xF8,  0x00,  0x00,  0x93,  0x00,  0x80,  0x00,  0x80,  0x01,  0x00,  0x01,  0x00,  0x02,  0x00,  0x02,  0x00, 	/* 22FC0 */
+	0x02,  0x00,  0x05,  0x80,  0x06,  0x40,  0x0C,  0x40,  0x08,  0x40,  0x10,  0x41,  0x10,  0x42,  0x20,  0x24, 	/* 22FD0 */
+	0x20,  0x18,  0x00,  0x00,  0x9B,  0x10,  0x00,  0x48,  0x00,  0x28,  0x00,  0x20,  0x00,  0x00,  0x00,  0x00, 	/* 22FE0 */
+	0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00, 	/* 22FF0 */
+	0x00,  0x00,  0x00,  0x00,  0x00,  0x9C,  0x00,  0x00,  0x60,  0x00,  0x90,  0x00,  0x90,  0x00,  0x60,  0x00, 	/* 23000 */
+	0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00, 	/* 23010 */
+	0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x9D,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x0C, 	/* 23020 */
+	0x00,  0x03,  0x00,  0x00,  0x80,  0x00,  0x40,  0x00,  0x20,  0x00,  0x70,  0x00,  0x80,  0x01,  0x00,  0x00, 	/* 23030 */
+	0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x9E,  0x00,  0x00,  0x00,  0x00,  0x00,  0x10,  0x00,  0x48, 	/* 23040 */
+	0x0C,  0x28,  0x03,  0x20,  0x00,  0x80,  0x00,  0x40,  0x00,  0x20,  0x00,  0x70,  0x00,  0x80,  0x01,  0x00, 	/* 23050 */
+	0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0xA1,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00, 	/* 23060 */
+	0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x1F,  0xF0,  0x01,  0x10,  0x01,  0x20,  0x01,  0x40,  0x01, 	/* 23070 */
+	0x00,  0x01,  0x00,  0x02,  0x00,  0x04,  0x00,  0x00,  0x00,  0xA2,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00, 	/* 23080 */
+	0x7F,  0xFC,  0x00,  0x04,  0x01,  0x04,  0x01,  0x08,  0x01,  0x10,  0x01,  0x60,  0x01,  0x00,  0x01,  0x00, 	/* 23090 */
+	0x02,  0x00,  0x02,  0x00,  0x04,  0x00,  0x18,  0x00,  0x00,  0x00,  0xA3,  0x00,  0x00,  0x00,  0x00,  0x00, 	/* 230A0 */
+	0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x10,  0x00,  0x20,  0x00,  0x40,  0x00,  0x80,  0x03,  0x80,  0x0C, 	/* 230B0 */
+	0x80,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x00,  0x00,  0xA4,  0x00,  0x00,  0x00,  0x10, 	/* 230C0 */
+	0x00,  0x10,  0x00,  0x20,  0x00,  0x40,  0x00,  0x80,  0x03,  0x80,  0x0C,  0x80,  0x30,  0x80,  0x00,  0x80, 	/* 230D0 */
+	0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x00,  0x00,  0xA5,  0x00,  0x00,  0x00, 	/* 230E0 */
+	0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x0F,  0xF8,  0x08,  0x08,  0x08, 	/* 230F0 */
+	0x08,  0x08,  0x10,  0x00,  0x10,  0x00,  0x20,  0x00,  0xC0,  0x03,  0x00,  0x00,  0x00,  0xA6,  0x00,  0x00, 	/* 23100 */
+	0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x1F,  0xFC,  0x10,  0x04,  0x10,  0x04,  0x10,  0x04,  0x10,  0x04, 	/* 23110 */
+	0x00,  0x08,  0x00,  0x08,  0x00,  0x10,  0x00,  0x20,  0x00,  0xC0,  0x03,  0x00,  0x00,  0x00,  0xA7,  0x00, 	/* 23120 */
+	0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x0F, 	/* 23130 */
+	0xE0,  0x01,  0x00,  0x01,  0x00,  0x01,  0x00,  0x01,  0x00,  0x01,  0x00,  0x1F,  0xF0,  0x00,  0x00,  0xA8, 	/* 23140 */
+	0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x1F,  0xF8,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80, 	/* 23150 */
+	0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x7F,  0xFE,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00, 	/* 23160 */
+	0xA9,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x40,  0x00,  0x40,  0x00, 	/* 23170 */
+	0x40,  0x0F,  0xF8,  0x00,  0xC0,  0x01,  0x40,  0x02,  0x40,  0x04,  0x40,  0x08,  0x40,  0x00,  0xC0,  0x00, 	/* 23180 */
+	0x00,  0xAA,  0x00,  0x00,  0x00,  0x20,  0x00,  0x20,  0x00,  0x20,  0x1F,  0xFE,  0x00,  0x20,  0x00,  0x60, 	/* 23190 */
+	0x00,  0xA0,  0x00,  0xA0,  0x01,  0x20,  0x02,  0x20,  0x04,  0x20,  0x18,  0x20,  0x00,  0x20,  0x00,  0xE0, 	/* 231A0 */
+	0x00,  0x00,  0xAB,  0x00,  0x00,  0x01,  0x00,  0x01,  0x00,  0x01,  0x00,  0x3F,  0xF8,  0x01,  0x08,  0x01, 	/* 231B0 */
+	0x08,  0x01,  0x08,  0x01,  0x08,  0x02,  0x08,  0x02,  0x08,  0x04,  0x08,  0x08,  0x08,  0x10,  0x10,  0x20, 	/* 231C0 */
+	0x60,  0x00,  0x00,  0xAC,  0x00,  0x00,  0x01,  0x02,  0x01,  0x09,  0x01,  0x05,  0x3F,  0xFC,  0x01,  0x08, 	/* 231D0 */
+	0x01,  0x08,  0x01,  0x08,  0x01,  0x08,  0x02,  0x08,  0x02,  0x08,  0x04,  0x08,  0x08,  0x08,  0x10,  0x10, 	/* 231E0 */
+	0x20,  0x60,  0x00,  0x00,  0xAD,  0x00,  0x00,  0x01,  0x00,  0x01,  0x00,  0x01,  0x18,  0x01,  0xE0,  0x1E, 	/* 231F0 */
+	0x80,  0x00,  0x80,  0x00,  0x8E,  0x00,  0xF0,  0x03,  0x40,  0x3C,  0x40,  0x00,  0x40,  0x00,  0x40,  0x00, 	/* 23200 */
+	0x20,  0x00,  0x20,  0x00,  0x20,  0xAE,  0x00,  0x00,  0x01,  0x04,  0x01,  0x12,  0x01,  0x1A,  0x01,  0xE8, 	/* 23210 */
+	0x1E,  0x80,  0x00,  0x80,  0x00,  0x8E,  0x00,  0xF0,  0x03,  0x40,  0x3C,  0x40,  0x00,  0x40,  0x00,  0x40, 	/* 23220 */
+	0x00,  0x20,  0x00,  0x20,  0x00,  0x20,  0xAF,  0x00,  0x00,  0x00,  0x80,  0x00,  0x80,  0x01,  0xFC,  0x01, 	/* 23230 */
+	0x04,  0x02,  0x08,  0x04,  0x08,  0x08,  0x10,  0x10,  0x10,  0x00,  0x20,  0x00,  0x40,  0x00,  0x80,  0x01, 	/* 23240 */
+	0x00,  0x06,  0x00,  0x18,  0x00,  0x00,  0x00,  0xB0,  0x00,  0x02,  0x01,  0x09,  0x01,  0x05,  0x03,  0xF4, 	/* 23250 */
+	0x02,  0x10,  0x04,  0x10,  0x08,  0x20,  0x10,  0x20,  0x20,  0x40,  0x00,  0x40,  0x00,  0x80,  0x01,  0x00, 	/* 23260 */
+	0x02,  0x00,  0x0C,  0x00,  0x30,  0x00,  0x00,  0x00,  0xB1,  0x00,  0x00,  0x04,  0x00,  0x04,  0x00,  0x04, 	/* 23270 */
+	0x00,  0x07,  0xFE,  0x04,  0x20,  0x08,  0x20,  0x08,  0x20,  0x10,  0x20,  0x20,  0x20,  0x00,  0x40,  0x00, 	/* 23280 */
+	0x40,  0x00,  0x80,  0x01,  0x00,  0x06,  0x00,  0x00,  0x00,  0xB2,  0x00,  0x00,  0x04,  0x02,  0x04,  0x09, 	/* 23290 */
+	0x04,  0x05,  0x07,  0xFC,  0x04,  0x20,  0x08,  0x20,  0x08,  0x20,  0x10,  0x20,  0x20,  0x20,  0x00,  0x40, 	/* 232A0 */
+	0x00,  0x40,  0x00,  0x80,  0x01,  0x00,  0x06,  0x00,  0x00,  0x00,  0xB3,  0x00,  0x00,  0x00,  0x00,  0x00, 	/* 232B0 */
+	0x00,  0x3F,  0xF8,  0x00,  0x08,  0x00,  0x08,  0x00,  0x08,  0x00,  0x08,  0x00,  0x08,  0x00,  0x08,  0x00, 	/* 232C0 */
+	0x08,  0x00,  0x08,  0x3F,  0xF8,  0x00,  0x08,  0x00,  0x00,  0x00,  0x00,  0xB4,  0x00,  0x02,  0x00,  0x09, 	/* 232D0 */
+	0x00,  0x05,  0x3F,  0xFC,  0x00,  0x08,  0x00,  0x08,  0x00,  0x08,  0x00,  0x08,  0x00,  0x08,  0x00,  0x08, 	/* 232E0 */
+	0x00,  0x08,  0x00,  0x08,  0x3F,  0xF8,  0x00,  0x08,  0x00,  0x00,  0x00,  0x00,  0xB5,  0x00,  0x00,  0x04, 	/* 232F0 */
+	0x10,  0x04,  0x10,  0x04,  0x10,  0x04,  0x10,  0x7F,  0xFE,  0x04,  0x10,  0x04,  0x10,  0x04,  0x10,  0x04, 	/* 23300 */
+	0x10,  0x04,  0x20,  0x00,  0x20,  0x00,  0x40,  0x00,  0x80,  0x03,  0x00,  0x00,  0x00,  0xB6,  0x00,  0x02, 	/* 23310 */
+	0x04,  0x19,  0x04,  0x15,  0x04,  0x14,  0x04,  0x10,  0x7F,  0xFE,  0x04,  0x10,  0x04,  0x10,  0x04,  0x10, 	/* 23320 */
+	0x04,  0x10,  0x04,  0x20,  0x00,  0x20,  0x00,  0x40,  0x00,  0x80,  0x03,  0x00,  0x00,  0x00,  0xB7,  0x00, 	/* 23330 */
+	0x00,  0x00,  0x00,  0x0C,  0x00,  0x02,  0x00,  0x00,  0x00,  0x00,  0x02,  0x18,  0x02,  0x04,  0x04,  0x00, 	/* 23340 */
+	0x04,  0x00,  0x08,  0x00,  0x10,  0x00,  0x20,  0x00,  0xC0,  0x03,  0x00,  0x1C,  0x00,  0x00,  0x00,  0xB8, 	/* 23350 */
+	0x00,  0x00,  0x00,  0x04,  0x0C,  0x12,  0x02,  0x0A,  0x00,  0x08,  0x00,  0x02,  0x18,  0x02,  0x04,  0x04, 	/* 23360 */
+	0x00,  0x04,  0x00,  0x08,  0x00,  0x10,  0x00,  0x20,  0x00,  0xC0,  0x03,  0x00,  0x1C,  0x00,  0x00,  0x00, 	/* 23370 */
+	0xB9,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x1F,  0xE0,  0x00,  0x20,  0x00,  0x20,  0x00,  0x40,  0x00, 	/* 23380 */
+	0x40,  0x00,  0x80,  0x00,  0xC0,  0x01,  0x20,  0x02,  0x10,  0x04,  0x08,  0x18,  0x04,  0x60,  0x04,  0x00, 	/* 23390 */
+	0x00,  0xBA,  0x00,  0x00,  0x00,  0x04,  0x00,  0x12,  0x1F,  0xEA,  0x00,  0x28,  0x00,  0x20,  0x00,  0x40, 	/* 233A0 */
+	0x00,  0x40,  0x00,  0x80,  0x00,  0xC0,  0x01,  0x20,  0x02,  0x10,  0x04,  0x08,  0x18,  0x04,  0x60,  0x04, 	/* 233B0 */
+	0x00,  0x00,  0xBB,  0x00,  0x00,  0x02,  0x00,  0x02,  0x00,  0x02,  0x00,  0x02,  0x1E,  0x03,  0xE2,  0x3E, 	/* 233C0 */
+	0x04,  0x02,  0x08,  0x02,  0x10,  0x02,  0x20,  0x02,  0x00,  0x02,  0x00,  0x01,  0x00,  0x00,  0xFC,  0x00, 	/* 233D0 */
+	0x00,  0x00,  0x00,  0xBC,  0x00,  0x02,  0x02,  0x09,  0x02,  0x05,  0x02,  0x04,  0x02,  0x1E,  0x03,  0xE2, 	/* 233E0 */
+	0x3E,  0x04,  0x02,  0x08,  0x02,  0x10,  0x02,  0x20,  0x02,  0x00,  0x02,  0x00,  0x01,  0x00,  0x00,  0xFC, 	/* 233F0 */
+	0x00,  0x00,  0x00,  0x00,  0xBD,  0x00,  0x00,  0x00,  0x00,  0x00,  0x04,  0x10,  0x04,  0x08,  0x04,  0x04, 	/* 23400 */
+	0x04,  0x04,  0x08,  0x04,  0x08,  0x00,  0x10,  0x00,  0x10,  0x00,  0x20,  0x00,  0x40,  0x00,  0x80,  0x03, 	/* 23410 */
+	0x00,  0x0C,  0x00,  0x00,  0x00,  0xBE,  0x00,  0x00,  0x00,  0x04,  0x00,  0x12,  0x20,  0x0A,  0x10,  0x08, 	/* 23420 */
+	0x08,  0x08,  0x08,  0x10,  0x08,  0x10,  0x00,  0x20,  0x00,  0x20,  0x00,  0x40,  0x00,  0x80,  0x01,  0x00, 	/* 23430 */
+	0x06,  0x00,  0x18,  0x00,  0x00,  0x00,  0xBF,  0x00,  0x00,  0x01,  0x00,  0x01,  0x00,  0x01,  0xFC,  0x02, 	/* 23440 */
+	0x04,  0x04,  0x08,  0x08,  0x08,  0x33,  0x10,  0x00,  0xD0,  0x00,  0x20,  0x00,  0x40,  0x00,  0x80,  0x01, 	/* 23450 */
+	0x00,  0x06,  0x00,  0x38,  0x00,  0x00,  0x00,  0x80,  0x00,  0x02,  0x01,  0x09,  0x01,  0x05,  0x01,  0xFC, 	/* 23460 */
+	0x02,  0x04,  0x04,  0x08,  0x08,  0x08,  0x33,  0x10,  0x00,  0xD0,  0x00,  0x20,  0x00,  0x40,  0x00,  0x80, 	/* 23470 */
+	0x01,  0x00,  0x06,  0x00,  0x38,  0x00,  0x00,  0x00,  0x81,  0x00,  0x00,  0x00,  0x10,  0x00,  0xE0,  0x1F, 	/* 23480 */
+	0x80,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x7F,  0xFC,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x01, 	/* 23490 */
+	0x00,  0x01,  0x00,  0x02,  0x00,  0x0C,  0x00,  0x00,  0x00,  0x82,  0x00,  0x04,  0x00,  0x12,  0x00,  0xEA, 	/* 234A0 */
+	0x1F,  0x88,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x7F,  0xFC,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80, 	/* 234B0 */
+	0x01,  0x00,  0x01,  0x00,  0x02,  0x00,  0x0C,  0x00,  0x00,  0x00,  0x83,  0x00,  0x00,  0x00,  0x00,  0x00, 	/* 234C0 */
+	0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x02,  0x00,  0x11,  0x10,  0x09,  0x10,  0x08,  0x10,  0x00, 	/* 234D0 */
+	0x20,  0x00,  0x20,  0x00,  0x40,  0x00,  0x80,  0x03,  0x00,  0x00,  0x00,  0x84,  0x00,  0x00,  0x00,  0x00, 	/* 234E0 */
+	0x02,  0x00,  0x21,  0x04,  0x11,  0x04,  0x11,  0x04,  0x10,  0x08,  0x00,  0x08,  0x00,  0x10,  0x00,  0x10, 	/* 234F0 */
+	0x00,  0x20,  0x00,  0x40,  0x00,  0x80,  0x03,  0x00,  0x0C,  0x00,  0x00,  0x00,  0x85,  0x00,  0x02,  0x00, 	/* 23500 */
+	0x09,  0x02,  0x05,  0x21,  0x04,  0x11,  0x08,  0x11,  0x08,  0x10,  0x08,  0x00,  0x10,  0x00,  0x10,  0x00, 	/* 23510 */
+	0x20,  0x00,  0x20,  0x00,  0x40,  0x00,  0x80,  0x03,  0x00,  0x0C,  0x00,  0x00,  0x00,  0x86,  0x00,  0x00, 	/* 23520 */
+	0x00,  0x00,  0x00,  0x00,  0x0F,  0xF8,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x3F,  0xFE,  0x00,  0x40, 	/* 23530 */
+	0x00,  0x40,  0x00,  0x40,  0x00,  0x80,  0x00,  0x80,  0x01,  0x00,  0x06,  0x00,  0x00,  0x00,  0x87,  0x00, 	/* 23540 */
+	0x00,  0x00,  0x04,  0x00,  0x12,  0x0F,  0xEA,  0x00,  0x08,  0x00,  0x00,  0x00,  0x00,  0x3F,  0xFE,  0x00, 	/* 23550 */
+	0x40,  0x00,  0x40,  0x00,  0x40,  0x00,  0x80,  0x00,  0x80,  0x01,  0x00,  0x06,  0x00,  0x00,  0x00,  0x88, 	/* 23560 */
+	0x00,  0x00,  0x02,  0x00,  0x02,  0x00,  0x02,  0x00,  0x02,  0x00,  0x02,  0x00,  0x02,  0x00,  0x03,  0x80, 	/* 23570 */
+	0x02,  0x60,  0x02,  0x10,  0x02,  0x08,  0x02,  0x00,  0x02,  0x00,  0x02,  0x00,  0x02,  0x00,  0x02,  0x00, 	/* 23580 */
+	0x89,  0x00,  0x00,  0x02,  0x04,  0x02,  0x12,  0x02,  0x0A,  0x02,  0x08,  0x02,  0x00,  0x02,  0x00,  0x03, 	/* 23590 */
+	0x80,  0x02,  0x60,  0x02,  0x10,  0x02,  0x08,  0x02,  0x00,  0x02,  0x00,  0x02,  0x00,  0x02,  0x00,  0x02, 	/* 235A0 */
+	0x00,  0x8A,  0x00,  0x00,  0x00,  0x40,  0x00,  0x40,  0x00,  0x40,  0x00,  0x40,  0x3F,  0xFE,  0x00,  0x40, 	/* 235B0 */
+	0x00,  0x40,  0x00,  0x40,  0x00,  0x40,  0x00,  0x40,  0x00,  0x80,  0x00,  0x80,  0x03,  0x00,  0x0C,  0x00, 	/* 235C0 */
+	0x00,  0x00,  0x8B,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x1F,  0xF8,  0x00,  0x00,  0x00, 	/* 235D0 */
+	0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x7F,  0xFE,  0x00,  0x00,  0x00,  0x00,  0x00, 	/* 235E0 */
+	0x00,  0x00,  0x00,  0x8C,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x0F,  0xF8,  0x00,  0x08,  0x00,  0x10, 	/* 235F0 */
+	0x00,  0x10,  0x06,  0x20,  0x01,  0xA0,  0x00,  0x40,  0x00,  0xA0,  0x01,  0x10,  0x02,  0x08,  0x0C,  0x04, 	/* 23600 */
+	0x30,  0x00,  0x00,  0x00,  0x8D,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x1F,  0xF8,  0x00,  0x08,  0x00, 	/* 23610 */
+	0x10,  0x00,  0x20,  0x00,  0x40,  0x01,  0xB0,  0x06,  0x8C,  0x38,  0x82,  0x00,  0x80,  0x00,  0x80,  0x00, 	/* 23620 */
+	0x80,  0x00,  0x80,  0x00,  0x00,  0x8E,  0x00,  0x00,  0x00,  0x08,  0x00,  0x08,  0x00,  0x08,  0x00,  0x08, 	/* 23630 */
+	0x00,  0x10,  0x00,  0x10,  0x00,  0x20,  0x00,  0x20,  0x00,  0x40,  0x00,  0x80,  0x01,  0x00,  0x02,  0x00, 	/* 23640 */
+	0x0C,  0x00,  0x30,  0x00,  0x00,  0x00,  0x8F,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x04,  0x40,  0x04, 	/* 23650 */
+	0x20,  0x04,  0x10,  0x04,  0x10,  0x08,  0x08,  0x08,  0x08,  0x08,  0x04,  0x10,  0x04,  0x10,  0x02,  0x20, 	/* 23660 */
+	0x02,  0x40,  0x02,  0x00,  0x00,  0x00,  0x00,  0x90,  0x00,  0x00,  0x00,  0x04,  0x00,  0x12,  0x04,  0x4A, 	/* 23670 */
+	0x04,  0x28,  0x04,  0x10,  0x04,  0x10,  0x08,  0x08,  0x08,  0x08,  0x08,  0x04,  0x10,  0x04,  0x10,  0x02, 	/* 23680 */
+	0x20,  0x02,  0x40,  0x02,  0x00,  0x00,  0x00,  0x00,  0x91,  0x00,  0x0C,  0x00,  0x12,  0x00,  0x12,  0x04, 	/* 23690 */
+	0x4C,  0x04,  0x20,  0x04,  0x10,  0x04,  0x10,  0x08,  0x08,  0x08,  0x08,  0x08,  0x04,  0x10,  0x04,  0x10, 	/* 236A0 */
+	0x02,  0x20,  0x02,  0x40,  0x02,  0x00,  0x00,  0x00,  0x00,  0x92,  0x00,  0x00,  0x10,  0x00,  0x10,  0x00, 	/* 236B0 */
+	0x10,  0x00,  0x10,  0x00,  0x10,  0x30,  0x11,  0xC0,  0x1E,  0x00,  0x10,  0x00,  0x10,  0x00,  0x10,  0x00, 	/* 236C0 */
+	0x10,  0x00,  0x08,  0x00,  0x07,  0xF8,  0x00,  0x00,  0x00,  0x00,  0x93,  0x00,  0x00,  0x10,  0x04,  0x10, 	/* 236D0 */
+	0x12,  0x10,  0x0A,  0x10,  0x08,  0x10,  0x30,  0x11,  0xC0,  0x1E,  0x00,  0x10,  0x00,  0x10,  0x00,  0x10, 	/* 236E0 */
+	0x00,  0x10,  0x00,  0x08,  0x00,  0x07,  0xF8,  0x00,  0x00,  0x00,  0x00,  0x94,  0x00,  0x00,  0x20,  0x0C, 	/* 236F0 */
+	0x20,  0x12,  0x20,  0x12,  0x20,  0x0C,  0x20,  0x60,  0x23,  0x80,  0x3C,  0x00,  0x20,  0x00,  0x20,  0x00, 	/* 23700 */
+	0x20,  0x00,  0x20,  0x00,  0x10,  0x00,  0x0F,  0xF0,  0x00,  0x00,  0x00,  0x00,  0x95,  0x00,  0x00,  0x00, 	/* 23710 */
+	0x00,  0x00,  0x00,  0x3F,  0xFC,  0x00,  0x04,  0x00,  0x04,  0x00,  0x08,  0x00,  0x08,  0x00,  0x10,  0x00, 	/* 23720 */
+	0x10,  0x00,  0x20,  0x00,  0x40,  0x00,  0x80,  0x03,  0x00,  0x0C,  0x00,  0x00,  0x00,  0x96,  0x00,  0x04, 	/* 23730 */
+	0x00,  0x12,  0x00,  0x0A,  0x3F,  0xF8,  0x00,  0x08,  0x00,  0x08,  0x00,  0x10,  0x00,  0x10,  0x00,  0x20, 	/* 23740 */
+	0x00,  0x20,  0x00,  0x40,  0x00,  0x80,  0x01,  0x00,  0x06,  0x00,  0x18,  0x00,  0x00,  0x00,  0x97,  0x00, 	/* 23750 */
+	0x00,  0x00,  0x06,  0x00,  0x09,  0x3F,  0xF9,  0x00,  0x0E,  0x00,  0x08,  0x00,  0x10,  0x00,  0x10,  0x00, 	/* 23760 */
+	0x20,  0x00,  0x20,  0x00,  0x40,  0x00,  0x80,  0x01,  0x00,  0x06,  0x00,  0x18,  0x00,  0x00,  0x00,  0x98, 	/* 23770 */
+	0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x03,  0x00,  0x04,  0x80,  0x08,  0x40,  0x10,  0x20, 	/* 23780 */
+	0x20,  0x10,  0x40,  0x08,  0x00,  0x04,  0x00,  0x02,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00, 	/* 23790 */
+	0x99,  0x00,  0x00,  0x00,  0x00,  0x00,  0x04,  0x00,  0x12,  0x03,  0x0A,  0x04,  0x88,  0x08,  0x40,  0x10, 	/* 237A0 */
+	0x20,  0x20,  0x10,  0x40,  0x08,  0x00,  0x04,  0x00,  0x02,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00, 	/* 237B0 */
+	0x00,  0x9A,  0x00,  0x00,  0x00,  0x18,  0x00,  0x24,  0x00,  0x24,  0x03,  0x18,  0x04,  0x80,  0x08,  0x40, 	/* 237C0 */
+	0x10,  0x20,  0x20,  0x10,  0x40,  0x08,  0x00,  0x04,  0x00,  0x02,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00, 	/* 237D0 */
+	0x00,  0x00,  0x9B,  0x00,  0x00,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x3F,  0xFE,  0x00,  0x80,  0x00, 	/* 237E0 */
+	0x80,  0x04,  0x90,  0x04,  0x88,  0x04,  0x84,  0x08,  0x84,  0x08,  0x82,  0x10,  0x82,  0x20,  0x80,  0x01, 	/* 237F0 */
+	0x80,  0x00,  0x00,  0x9C,  0x00,  0x00,  0x00,  0x82,  0x00,  0x89,  0x00,  0x85,  0x3F,  0xFC,  0x00,  0x80, 	/* 23800 */
+	0x00,  0x80,  0x04,  0x90,  0x04,  0x88,  0x04,  0x84,  0x08,  0x84,  0x08,  0x82,  0x10,  0x82,  0x20,  0x80, 	/* 23810 */
+	0x01,  0x80,  0x00,  0x00,  0x9D,  0x00,  0x00,  0x00,  0x86,  0x00,  0x89,  0x00,  0x89,  0x3F,  0xFE,  0x00, 	/* 23820 */
+	0x80,  0x00,  0x80,  0x04,  0x90,  0x04,  0x88,  0x04,  0x84,  0x08,  0x84,  0x08,  0x82,  0x10,  0x82,  0x20, 	/* 23830 */
+	0x80,  0x01,  0x80,  0x00,  0x00,  0x9E,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x3F,  0xFE,  0x00,  0x04, 	/* 23840 */
+	0x00,  0x04,  0x00,  0x08,  0x00,  0x10,  0x0C,  0x20,  0x03,  0x40,  0x00,  0x80,  0x00,  0x40,  0x00,  0x20, 	/* 23850 */
+	0x00,  0x20,  0x00,  0x00,  0x00,  0x00,  0x9F,  0x00,  0x00,  0x06,  0x00,  0x01,  0x80,  0x00,  0x60,  0x00, 	/* 23860 */
+	0x10,  0x00,  0x00,  0x06,  0x00,  0x01,  0x80,  0x00,  0x40,  0x00,  0x20,  0x10,  0x00,  0x0C,  0x00,  0x03, 	/* 23870 */
+	0x00,  0x00,  0xC0,  0x00,  0x20,  0x00,  0x10,  0xA0,  0x00,  0x00,  0x01,  0x00,  0x01,  0x00,  0x01,  0x00, 	/* 23880 */
+	0x01,  0x00,  0x01,  0x00,  0x02,  0x00,  0x02,  0x20,  0x02,  0x10,  0x04,  0x10,  0x04,  0x08,  0x09,  0xF8, 	/* 23890 */
+	0x3E,  0x04,  0x00,  0x04,  0x00,  0x04,  0x00,  0x00,  0xA1,  0x00,  0x00,  0x00,  0x08,  0x00,  0x08,  0x00, 	/* 238A0 */
+	0x08,  0x00,  0x08,  0x06,  0x10,  0x01,  0x90,  0x00,  0x50,  0x00,  0x20,  0x00,  0x30,  0x00,  0x48,  0x00, 	/* 238B0 */
+	0x84,  0x01,  0x00,  0x06,  0x00,  0x18,  0x00,  0x00,  0x00,  0xA2,  0x00,  0x00,  0x00,  0x00,  0x1F,  0xF0, 	/* 238C0 */
+	0x02,  0x00,  0x02,  0x00,  0x02,  0x00,  0x02,  0x00,  0x7F,  0xFC,  0x02,  0x00,  0x02,  0x00,  0x02,  0x00, 	/* 238D0 */
+	0x02,  0x00,  0x01,  0x00,  0x00,  0xF8,  0x00,  0x00,  0x00,  0x00,  0xA3,  0x00,  0x00,  0x00,  0x00,  0x00, 	/* 238E0 */
+	0x00,  0x00,  0x00,  0x00,  0x00,  0x02,  0x00,  0x02,  0x00,  0x01,  0x38,  0x01,  0xC8,  0x07,  0x10,  0x19, 	/* 238F0 */
+	0x20,  0x00,  0x80,  0x00,  0x80,  0x00,  0x40,  0x00,  0x40,  0x00,  0x40,  0xA4,  0x00,  0x00,  0x04,  0x00, 	/* 23900 */
+	0x04,  0x00,  0x02,  0x0E,  0x02,  0x72,  0x07,  0x84,  0x3A,  0x08,  0x01,  0x10,  0x01,  0x20,  0x00,  0x80, 	/* 23910 */
+	0x00,  0x80,  0x00,  0x80,  0x00,  0x40,  0x00,  0x40,  0x00,  0x40,  0x00,  0x00,  0xA5,  0x00,  0x00,  0x00, 	/* 23920 */
+	0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x0F,  0xC0,  0x00, 	/* 23930 */
+	0x40,  0x00,  0x40,  0x00,  0x40,  0x00,  0x40,  0x3F,  0xF8,  0x00,  0x00,  0x00,  0x00,  0xA6,  0x00,  0x00, 	/* 23940 */
+	0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x1F,  0xE0,  0x00,  0x20,  0x00,  0x20,  0x00,  0x20,  0x00,  0x20, 	/* 23950 */
+	0x00,  0x20,  0x00,  0x20,  0x00,  0x20,  0x7F,  0xFE,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0xA7,  0x00, 	/* 23960 */
+	0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x07,  0xF0,  0x00,  0x10,  0x00, 	/* 23970 */
+	0x10,  0x00,  0x10,  0x07,  0xF0,  0x00,  0x10,  0x00,  0x10,  0x00,  0x10,  0x07,  0xF0,  0x00,  0x00,  0xA8, 	/* 23980 */
+	0x00,  0x00,  0x00,  0x00,  0x1F,  0xF8,  0x00,  0x08,  0x00,  0x08,  0x00,  0x08,  0x00,  0x08,  0x1F,  0xF8, 	/* 23990 */
+	0x00,  0x08,  0x00,  0x08,  0x00,  0x08,  0x00,  0x08,  0x00,  0x08,  0x1F,  0xF8,  0x00,  0x08,  0x00,  0x00, 	/* 239A0 */
+	0xA9,  0x00,  0x00,  0x00,  0x00,  0x1F,  0xF8,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x3F,  0xFC,  0x00, 	/* 239B0 */
+	0x04,  0x00,  0x04,  0x00,  0x08,  0x00,  0x08,  0x00,  0x10,  0x00,  0x60,  0x01,  0x80,  0x0E,  0x00,  0x00, 	/* 239C0 */
+	0x00,  0xAA,  0x00,  0x00,  0x08,  0x10,  0x08,  0x10,  0x08,  0x10,  0x08,  0x10,  0x08,  0x10,  0x08,  0x10, 	/* 239D0 */
+	0x08,  0x10,  0x08,  0x10,  0x00,  0x10,  0x00,  0x20,  0x00,  0x20,  0x00,  0x40,  0x00,  0x80,  0x03,  0x00, 	/* 239E0 */
+	0x00,  0x00,  0xAB,  0x00,  0x00,  0x00,  0x40,  0x00,  0x40,  0x04,  0x40,  0x04,  0x40,  0x04,  0x40,  0x04, 	/* 239F0 */
+	0x41,  0x04,  0x41,  0x04,  0x42,  0x04,  0x42,  0x04,  0x44,  0x08,  0x48,  0x08,  0x50,  0x10,  0x60,  0x20, 	/* 23A00 */
+	0x00,  0x00,  0x00,  0xAC,  0x00,  0x00,  0x04,  0x00,  0x04,  0x00,  0x04,  0x00,  0x04,  0x00,  0x04,  0x00, 	/* 23A10 */
+	0x04,  0x00,  0x04,  0x00,  0x04,  0x04,  0x04,  0x04,  0x04,  0x08,  0x04,  0x10,  0x04,  0x20,  0x04,  0xC0, 	/* 23A20 */
+	0x07,  0x00,  0x00,  0x00,  0xAD,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x1F,  0xFC,  0x10,  0x04,  0x10, 	/* 23A30 */
+	0x04,  0x10,  0x04,  0x10,  0x04,  0x10,  0x04,  0x10,  0x04,  0x10,  0x04,  0x10,  0x04,  0x1F,  0xFC,  0x10, 	/* 23A40 */
+	0x04,  0x00,  0x00,  0x00,  0x00,  0xAE,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00, 	/* 23A50 */
+	0x00,  0x00,  0x0F,  0xF8,  0x08,  0x08,  0x08,  0x08,  0x08,  0x08,  0x00,  0x10,  0x00,  0x10,  0x00,  0x20, 	/* 23A60 */
+	0x00,  0x40,  0x01,  0x80,  0x00,  0x00,  0xAF,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x3F,  0xF8,  0x20, 	/* 23A70 */
+	0x08,  0x20,  0x08,  0x20,  0x08,  0x20,  0x08,  0x00,  0x08,  0x00,  0x10,  0x00,  0x10,  0x00,  0x20,  0x00, 	/* 23A80 */
+	0x40,  0x01,  0x80,  0x06,  0x00,  0x00,  0x00,  0xB0,  0x00,  0x00,  0x00,  0x40,  0x00,  0x40,  0x00,  0x40, 	/* 23A90 */
+	0x3F,  0xFC,  0x08,  0x40,  0x08,  0x40,  0x08,  0x40,  0x08,  0x40,  0x08,  0x40,  0x7F,  0xFE,  0x00,  0x40, 	/* 23AA0 */
+	0x00,  0x40,  0x00,  0x40,  0x00,  0x40,  0x00,  0x00,  0xB1,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x1F, 	/* 23AB0 */
+	0xF8,  0x00,  0x10,  0x00,  0x20,  0x01,  0x40,  0x01,  0x00,  0x01,  0x00,  0x01,  0x00,  0x01,  0x00,  0x01, 	/* 23AC0 */
+	0x00,  0x7F,  0xFC,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0xB2,  0x00,  0x00,  0x00,  0x00,  0x0F,  0xFC, 	/* 23AD0 */
+	0x00,  0x04,  0x00,  0x04,  0x00,  0x04,  0x07,  0xFC,  0x00,  0x08,  0x00,  0x08,  0x00,  0x10,  0x00,  0x20, 	/* 23AE0 */
+	0x00,  0x40,  0x01,  0x80,  0x0E,  0x00,  0x00,  0x00,  0x00,  0x00,  0xB3,  0x00,  0x00,  0x00,  0x00,  0x00, 	/* 23AF0 */
+	0x00,  0x18,  0x00,  0x04,  0x00,  0x02,  0x02,  0x00,  0x02,  0x00,  0x04,  0x00,  0x04,  0x00,  0x08,  0x00, 	/* 23B00 */
+	0x10,  0x00,  0x20,  0x00,  0xC0,  0x03,  0x00,  0x1C,  0x00,  0x00,  0x00,  0xB4,  0x00,  0x80,  0x00,  0x82, 	/* 23B10 */
+	0x00,  0x89,  0x00,  0x85,  0x1F,  0xFC,  0x10,  0x04,  0x10,  0x04,  0x10,  0x04,  0x10,  0x04,  0x00,  0x08, 	/* 23B20 */
+	0x00,  0x08,  0x00,  0x10,  0x00,  0x20,  0x00,  0xC0,  0x03,  0x00,  0x00,  0x00,  0xB5,  0x00,  0x00,  0x00, 	/* 23B30 */
+	0x00,  0x00,  0x00,  0x00,  0x00,  0x01,  0x00,  0x01,  0x00,  0x01,  0x00,  0x1F,  0xF0,  0x01,  0x10,  0x01, 	/* 23B40 */
+	0x10,  0x01,  0x10,  0x02,  0x10,  0x02,  0x10,  0x04,  0x10,  0x08,  0x60,  0x00,  0x00,  0xB6,  0x00,  0x00, 	/* 23B50 */
+	0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x02,  0x00,  0x02,  0x00,  0x02,  0x00,  0x07,  0xFC,  0x04,  0x20, 	/* 23B60 */
+	0x08,  0x20,  0x10,  0x40,  0x00,  0x40,  0x00,  0x80,  0x01,  0x00,  0x06,  0x00,  0x00,  0x00,  0xBB,  0x00, 	/* 23B70 */
+	0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x01,  0x80,  0x01, 	/* 23B80 */
+	0x80,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0xBC, 	/* 23B90 */
+	0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x40,  0x00,  0x3F,  0xFC, 	/* 23BA0 */
+	0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00, 	/* 23BB0 */
+	0xBD,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x0C,  0x00,  0x03,  0x00,  0x00, 	/* 23BC0 */
+	0x80,  0x00,  0x40,  0x00,  0x20,  0x00,  0x10,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00, 	/* 23BD0 */
+	0x00,  0xBE,  0x00,  0x00,  0x00,  0x00,  0x00,  0x20,  0x00,  0x90,  0x00,  0x50,  0x0C,  0x40,  0x03,  0x00, 	/* 23BE0 */
+	0x00,  0x80,  0x00,  0x40,  0x00,  0x20,  0x00,  0x10,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00, 	/* 23BF0 */
+	0x00,  0x00,  0x80,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00, 	/* 23C00 */
+	0x02,  0x7F,  0xFF,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00, 	/* 23C10 */
+	0x00,  0x00,  0x00,  0x81,  0x00,  0x00,  0x00,  0x00,  0x7F,  0xFF,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80, 	/* 23C20 */
+	0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80, 	/* 23C30 */
+	0x00,  0x80,  0x01,  0x80,  0x83,  0x04,  0x00,  0x04,  0x00,  0x04,  0x00,  0x04,  0x00,  0x04,  0x06,  0x04, 	/* 23C40 */
+	0x78,  0x07,  0x80,  0x7C,  0x00,  0x04,  0x00,  0x04,  0x00,  0x04,  0x00,  0x04,  0x04,  0x04,  0x04,  0x02, 	/* 23C50 */
+	0x04,  0x01,  0xFC,  0x00,  0x00,  0x87,  0x00,  0x00,  0x7F,  0xFE,  0x01,  0x00,  0x01,  0x00,  0x01,  0x00, 	/* 23C60 */
+	0x01,  0xF8,  0x01,  0x08,  0x01,  0x08,  0x02,  0x08,  0x02,  0x08,  0x02,  0x08,  0x04,  0x08,  0x04,  0x08, 	/* 23C70 */
+	0x08,  0x08,  0x10,  0x10,  0x20,  0x60,  0x88,  0x00,  0x40,  0x00,  0x40,  0x00,  0x40,  0x3F,  0xFF,  0x00, 	/* 23C80 */
+	0x40,  0x04,  0x40,  0x04,  0x40,  0x02,  0x40,  0x02,  0x80,  0x01,  0x80,  0x00,  0x80,  0x01,  0x40,  0x02, 	/* 23C90 */
+	0x20,  0x04,  0x10,  0x18,  0x0C,  0x60,  0x03,  0x89,  0x00,  0x00,  0x1F,  0xFC,  0x00,  0x00,  0x00,  0x00, 	/* 23CA0 */
+	0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x0F,  0xF8,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00, 	/* 23CB0 */
+	0x00,  0x00,  0x7F,  0xFF,  0x00,  0x00,  0x00,  0x00,  0x8A,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x00, 	/* 23CC0 */
+	0x80,  0x00,  0x80,  0x00,  0x80,  0x00,  0xFC,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x00, 	/* 23CD0 */
+	0x80,  0x00,  0x80,  0x00,  0x80,  0x7F,  0xFF,  0x00,  0x00,  0x8B,  0x00,  0x00,  0x7F,  0xFF,  0x00,  0x80, 	/* 23CE0 */
+	0x00,  0x80,  0x00,  0x80,  0x00,  0xC0,  0x00,  0xA0,  0x00,  0x90,  0x00,  0x88,  0x00,  0x88,  0x00,  0x80, 	/* 23CF0 */
+	0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x8D,  0x00,  0x00,  0x7F,  0xFF,  0x00, 	/* 23D00 */
+	0x40,  0x00,  0x40,  0x00,  0x80,  0x00,  0xC0,  0x01,  0xB0,  0x02,  0x88,  0x04,  0x84,  0x18,  0x82,  0x60, 	/* 23D10 */
+	0x81,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x8E,  0x02,  0x00,  0x02,  0x00, 	/* 23D20 */
+	0x03,  0xFC,  0x02,  0x00,  0x02,  0x00,  0x03,  0xF0,  0x00,  0x10,  0x00,  0x10,  0x7F,  0xFF,  0x00,  0x10, 	/* 23D30 */
+	0x00,  0x10,  0x00,  0x10,  0x00,  0x10,  0x00,  0x10,  0x00,  0x60,  0x01,  0x80,  0x90,  0x00,  0x00,  0x7F, 	/* 23D40 */
+	0xFF,  0x00,  0x80,  0x08,  0x80,  0x08,  0xFE,  0x08,  0x80,  0x08,  0x80,  0x0F,  0xFC,  0x00,  0x04,  0x00, 	/* 23D50 */
+	0x04,  0x00,  0x04,  0x00,  0x04,  0x00,  0x04,  0x00,  0x08,  0x00,  0x08,  0x00,  0x30,  0x91,  0x00,  0x00, 	/* 23D60 */
+	0x1F,  0xF0,  0x02,  0x10,  0x02,  0x10,  0x02,  0x10,  0x02,  0x10,  0x02,  0x10,  0x7F,  0xFE,  0x04,  0x10, 	/* 23D70 */
+	0x04,  0x10,  0x04,  0x10,  0x04,  0x10,  0x04,  0x10,  0x04,  0x10,  0x7F,  0xFF,  0x00,  0x00,  0x94,  0x00, 	/* 23D80 */
+	0x00,  0x0F,  0xF0,  0x08,  0x10,  0x08,  0x10,  0x08,  0x10,  0x0F,  0xF0,  0x08,  0x10,  0x08,  0x10,  0x08, 	/* 23D90 */
+	0x10,  0x0F,  0xF0,  0x08,  0x10,  0x08,  0x10,  0x08,  0x10,  0x08,  0x10,  0x7F,  0xFE,  0x00,  0x00,  0x95, 	/* 23DA0 */
+	0x00,  0x00,  0x3F,  0xFE,  0x00,  0x40,  0x00,  0x40,  0x00,  0x80,  0x01,  0x80,  0x02,  0xB0,  0x04,  0x8C, 	/* 23DB0 */
+	0x18,  0x82,  0x60,  0x81,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x00,  0x00,  0x3F,  0xFE,  0x00,  0x00, 	/* 23DC0 */
+	0x96,  0x00,  0x00,  0x08,  0x88,  0x08,  0x88,  0x08,  0x88,  0x08,  0x88,  0x7F,  0xFF,  0x08,  0x88,  0x08, 	/* 23DD0 */
+	0x88,  0x08,  0x88,  0x08,  0x88,  0x08,  0xF8,  0x08,  0x00,  0x08,  0x00,  0x08,  0x00,  0x0F,  0xFE,  0x00, 	/* 23DE0 */
+	0x00,  0x97,  0x08,  0x88,  0x08,  0x88,  0x08,  0x88,  0x08,  0x88,  0x08,  0x88,  0x08,  0x88,  0x7F,  0xFF, 	/* 23DF0 */
+	0x08,  0x88,  0x08,  0x88,  0x08,  0x88,  0x08,  0x88,  0x08,  0x88,  0x08,  0x88,  0x08,  0x88,  0x0F,  0xF8, 	/* 23E00 */
+	0x00,  0x00,  0x98,  0x00,  0x10,  0x00,  0xE0,  0x0F,  0x00,  0x08,  0x00,  0x08,  0x00,  0x08,  0x00,  0x0F, 	/* 23E10 */
+	0xFC,  0x08,  0x20,  0x08,  0x20,  0x08,  0x20,  0x08,  0x20,  0x08,  0x20,  0x08,  0x20,  0x08,  0x20,  0x7F, 	/* 23E20 */
+	0xFE,  0x00,  0x00,  0x99,  0x00,  0x00,  0x7F,  0xFF,  0x00,  0x80,  0x00,  0x80,  0x1F,  0xFC,  0x10,  0x84, 	/* 23E30 */
+	0x10,  0x84,  0x11,  0x44,  0x12,  0x24,  0x1C,  0x14,  0x10,  0x04,  0x10,  0x04,  0x10,  0x04,  0x10,  0x04, 	/* 23E40 */
+	0x10,  0x04,  0x10,  0x0C,  0x9E,  0x00,  0x00,  0x1F,  0xF8,  0x00,  0x10,  0x00,  0x60,  0x00,  0x82,  0x3E, 	/* 23E50 */
+	0xA2,  0x02,  0xA4,  0x04,  0x98,  0x04,  0x88,  0x08,  0x84,  0x10,  0x82,  0x20,  0x81,  0x41,  0x80,  0x00, 	/* 23E60 */
+	0x00,  0x7F,  0xFE,  0x00,  0x00,  0xA1,  0x00,  0x00,  0x7F,  0xFF,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80, 	/* 23E70 */
+	0x3F,  0xFE,  0x20,  0x82,  0x24,  0x92,  0x24,  0x92,  0x24,  0x92,  0x24,  0x92,  0x27,  0xF2,  0x24,  0x12, 	/* 23E80 */
+	0x20,  0x02,  0x20,  0x02,  0x20,  0x06,  0xA6,  0x08,  0x08,  0x04,  0x08,  0x02,  0x10,  0x02,  0x20,  0x3F, 	/* 23E90 */
+	0xFE,  0x02,  0x20,  0x02,  0x20,  0x22,  0x22,  0x12,  0x22,  0x12,  0x24,  0x0A,  0x24,  0x0A,  0x28,  0x02, 	/* 23EA0 */
+	0x20,  0x02,  0x20,  0x7F,  0xFF,  0x00,  0x00,  0xAA,  0x00,  0x80,  0x00,  0x80,  0x01,  0x40,  0x01,  0x40, 	/* 23EB0 */
+	0x02,  0x20,  0x04,  0x10,  0x08,  0x88,  0x10,  0x84,  0x20,  0x82,  0x40,  0x81,  0x00,  0x80,  0x00,  0x80, 	/* 23EC0 */
+	0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0xAD,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x3F, 	/* 23ED0 */
+	0xFE,  0x20,  0x82,  0x20,  0x82,  0x20,  0x82,  0x20,  0x82,  0x20,  0x82,  0x3F,  0xFE,  0x00,  0x80,  0x00, 	/* 23EE0 */
+	0x80,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0xB1,  0x02,  0x20,  0x02,  0x20,  0x22,  0x22, 	/* 23EF0 */
+	0x22,  0x22,  0x22,  0x22,  0x22,  0x22,  0x22,  0x22,  0x22,  0x22,  0x22,  0x22,  0x22,  0x22,  0x3E,  0x3E, 	/* 23F00 */
+	0x02,  0x20,  0x04,  0x20,  0x04,  0x20,  0x08,  0x20,  0x10,  0x20,  0xB2,  0x00,  0x80,  0x00,  0x80,  0x1F, 	/* 23F10 */
+	0xFC,  0x10,  0x84,  0x10,  0x84,  0x1F,  0xFC,  0x00,  0x80,  0x00,  0x80,  0x3F,  0xFE,  0x20,  0x82,  0x20, 	/* 23F20 */
+	0x82,  0x3F,  0xFE,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0xB6,  0x00,  0x00,  0x00,  0x00, 	/* 23F30 */
+	0x00,  0x00,  0x0C,  0x00,  0x03,  0x00,  0x00,  0x80,  0x00,  0x40,  0x00,  0x20,  0x00,  0x20,  0x00,  0x10, 	/* 23F40 */
+	0x00,  0x10,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0xB8,  0x02,  0x00,  0x02, 	/* 23F50 */
+	0x00,  0x02,  0x00,  0x02,  0x00,  0x7F,  0xF0,  0x02,  0x10,  0x02,  0x10,  0x0A,  0x10,  0x06,  0x10,  0x02, 	/* 23F60 */
+	0x10,  0x05,  0x10,  0x04,  0x90,  0x08,  0x92,  0x10,  0x12,  0x20,  0x12,  0x40,  0x0E,  0xB9,  0x00,  0x00, 	/* 23F70 */
+	0x0F,  0xF8,  0x08,  0x08,  0x0A,  0x08,  0x09,  0x08,  0x08,  0x88,  0x08,  0x88,  0x08,  0x08,  0x7F,  0xFF, 	/* 23F80 */
+	0x08,  0x08,  0x08,  0x08,  0x08,  0x08,  0x10,  0x08,  0x10,  0x08,  0x20,  0x08,  0x40,  0x18,  0xBB,  0x01, 	/* 23F90 */
+	0x00,  0x00,  0x80,  0x00,  0x80,  0x3F,  0xFE,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x1F, 	/* 23FA0 */
+	0xFC,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x7F,  0xFF,  0x00,  0x00,  0xBC, 	/* 23FB0 */
+	0x04,  0x20,  0x04,  0x20,  0x04,  0x20,  0x04,  0x20,  0x3F,  0xFC,  0x04,  0x20,  0x05,  0x20,  0x04,  0xA0, 	/* 23FC0 */
+	0x04,  0xA0,  0x7F,  0xFE,  0x04,  0x20,  0x04,  0x20,  0x04,  0x20,  0x08,  0x20,  0x08,  0x20,  0x10,  0x20, 	/* 23FD0 */
+	0xBF,  0x00,  0x40,  0x00,  0x40,  0x00,  0x40,  0x00,  0x40,  0x00,  0x40,  0x00,  0x40,  0x00,  0x40,  0x00, 	/* 23FE0 */
+	0x40,  0x00,  0x40,  0x00,  0x40,  0x00,  0x80,  0x00,  0x80,  0x01,  0x00,  0x02,  0x00,  0x0C,  0x00,  0x30, 	/* 23FF0 */
+	0x00,  0x82,  0x00,  0x00,  0x04,  0x10,  0x04,  0x10,  0x04,  0x10,  0x04,  0x10,  0x04,  0x10,  0x02,  0x20, 	/* 24000 */
+	0x02,  0x20,  0x01,  0x40,  0x01,  0x40,  0x00,  0x80,  0x01,  0x40,  0x02,  0x20,  0x04,  0x10,  0x18,  0x0C, 	/* 24010 */
+	0x60,  0x03,  0x83,  0x00,  0x00,  0x3F,  0xF0,  0x01,  0x10,  0x01,  0x10,  0x01,  0x10,  0x01,  0x10,  0x01, 	/* 24020 */
+	0x1C,  0x02,  0x04,  0x02,  0x04,  0x04,  0x04,  0x04,  0x04,  0x08,  0x04,  0x10,  0x04,  0x20,  0x08,  0x40, 	/* 24030 */
+	0x30,  0x00,  0x00,  0x85,  0x01,  0x00,  0x01,  0x00,  0x01,  0xF0,  0x02,  0x10,  0x02,  0x10,  0x04,  0x20, 	/* 24040 */
+	0x08,  0x20,  0x10,  0x40,  0x00,  0x40,  0x00,  0xC0,  0x00,  0xA0,  0x01,  0x20,  0x02,  0x10,  0x04,  0x08, 	/* 24050 */
+	0x18,  0x04,  0x60,  0x03,  0x8B,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x1F,  0xFC,  0x00, 	/* 24060 */
+	0x08,  0x00,  0x10,  0x00,  0x10,  0x00,  0x20,  0x00,  0x40,  0x08,  0x80,  0x09,  0x00,  0x0E,  0x00,  0x12, 	/* 24070 */
+	0x00,  0x21,  0x80,  0x40,  0x7F,  0x8D,  0x04,  0x00,  0x04,  0x00,  0x04,  0x00,  0x07,  0xFE,  0x08,  0x80, 	/* 24080 */
+	0x08,  0x80,  0x10,  0x80,  0x20,  0xFC,  0x40,  0x80,  0x00,  0x80,  0x00,  0x80,  0x00,  0xFC,  0x00,  0x80, 	/* 24090 */
+	0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x8E,  0x00,  0x04,  0x00,  0x38,  0x3F,  0xC0,  0x00,  0x84,  0x08, 	/* 240A0 */
+	0x84,  0x04,  0x88,  0x04,  0x90,  0x00,  0x80,  0x7F,  0xFF,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x00, 	/* 240B0 */
+	0x80,  0x00,  0x80,  0x00,  0x80,  0x01,  0x80,  0x8F,  0x00,  0x04,  0x00,  0x38,  0x7F,  0xC0,  0x01,  0x00, 	/* 240C0 */
+	0x01,  0x00,  0x01,  0x00,  0x3F,  0xF8,  0x00,  0x08,  0x00,  0x10,  0x00,  0x20,  0x08,  0x40,  0x09,  0x80, 	/* 240D0 */
+	0x1E,  0x00,  0x12,  0x00,  0x21,  0x80,  0x40,  0x7F,  0x95,  0x00,  0x04,  0x00,  0x38,  0x0F,  0xC0,  0x08, 	/* 240E0 */
+	0x40,  0x0F,  0xFF,  0x08,  0x40,  0x08,  0x40,  0x0F,  0xFF,  0x08,  0x40,  0x08,  0x40,  0x17,  0xFE,  0x14, 	/* 240F0 */
+	0x42,  0x24,  0x42,  0x44,  0x42,  0x04,  0x4C,  0x00,  0x40,  0x96,  0x00,  0x08,  0x00,  0x70,  0x1F,  0x80, 	/* 24100 */
+	0x00,  0x80,  0x00,  0x80,  0x7F,  0xFF,  0x00,  0x80,  0x04,  0x90,  0x04,  0x93,  0x7C,  0x9C,  0x04,  0x90, 	/* 24110 */
+	0x04,  0x91,  0x1C,  0x91,  0x64,  0x8F,  0x04,  0x80,  0x00,  0x80,  0x97,  0x00,  0x10,  0x0F,  0xE0,  0x00, 	/* 24120 */
+	0x80,  0x3F,  0xFE,  0x08,  0x88,  0x08,  0x88,  0x7F,  0xFF,  0x08,  0x88,  0x08,  0x88,  0x3F,  0xFE,  0x01, 	/* 24130 */
+	0xC0,  0x02,  0xA0,  0x04,  0x90,  0x18,  0x8C,  0x60,  0x83,  0x00,  0x80,  0x98,  0x00,  0x08,  0x00,  0x70, 	/* 24140 */
+	0x1F,  0x80,  0x00,  0x80,  0x7F,  0xFF,  0x00,  0x80,  0x04,  0x92,  0x7C,  0x9C,  0x04,  0x91,  0x1C,  0x91, 	/* 24150 */
+	0x65,  0xCF,  0x02,  0xA0,  0x04,  0x90,  0x18,  0x8C,  0x60,  0x83,  0x00,  0x80,  0x99,  0x00,  0x00,  0x1F, 	/* 24160 */
+	0xF8,  0x00,  0x10,  0x00,  0x60,  0x00,  0x80,  0x01,  0x00,  0x02,  0x00,  0x04,  0x00,  0x08,  0x00,  0x10, 	/* 24170 */
+	0x00,  0x10,  0x00,  0x20,  0x04,  0x20,  0x04,  0x20,  0x04,  0x1F,  0xFC,  0x00,  0x00,  0x9D,  0x00,  0x00, 	/* 24180 */
+	0x02,  0x00,  0x02,  0x00,  0x02,  0x00,  0x7F,  0xE0,  0x02,  0x20,  0x02,  0x20,  0x02,  0x20,  0x02,  0x20, 	/* 24190 */
+	0x04,  0x20,  0x04,  0x20,  0x04,  0x20,  0x08,  0x22,  0x10,  0x22,  0x20,  0x1E,  0x40,  0x00,  0x9E,  0x04, 	/* 241A0 */
+	0x00,  0x04,  0x00,  0x04,  0x00,  0x0F,  0xFE,  0x08,  0x00,  0x10,  0x00,  0x2F,  0xF0,  0x40,  0x40,  0x01, 	/* 241B0 */
+	0x80,  0x02,  0x00,  0x04,  0x00,  0x08,  0x00,  0x10,  0x00,  0x10,  0x04,  0x10,  0x04,  0x0F,  0xFC,  0x9F, 	/* 241C0 */
+	0x00,  0x80,  0x08,  0x80,  0x08,  0x80,  0x08,  0x98,  0x08,  0xE8,  0x0F,  0x88,  0x78,  0x88,  0x08,  0x88, 	/* 241D0 */
+	0x08,  0x88,  0x08,  0x88,  0x08,  0xB0,  0x08,  0x82,  0x08,  0x02,  0x04,  0x02,  0x03,  0xFE,  0x00,  0x00, 	/* 241E0 */
+	0xA2,  0x08,  0x40,  0x08,  0x40,  0x08,  0x40,  0x29,  0x40,  0x29,  0x40,  0x29,  0x40,  0x29,  0x40,  0x29, 	/* 241F0 */
+	0x40,  0x29,  0x40,  0x29,  0x40,  0x29,  0x40,  0x29,  0x41,  0x3F,  0x41,  0x00,  0x41,  0x00,  0x3F,  0x00, 	/* 24200 */
+	0x00,  0xB1,  0x01,  0x20,  0x06,  0x20,  0x38,  0x20,  0x08,  0x20,  0x08,  0x20,  0x08,  0x20,  0x7F,  0xA0, 	/* 24210 */
+	0x08,  0x20,  0x08,  0x20,  0x08,  0x20,  0x3F,  0x20,  0x21,  0x20,  0x21,  0x21,  0x21,  0x21,  0x3F,  0x21, 	/* 24220 */
+	0x00,  0x1F,  0xB3,  0x00,  0xA0,  0x07,  0x20,  0x78,  0xA0,  0x24,  0xA0,  0x15,  0x20,  0x12,  0x20,  0x3F, 	/* 24230 */
+	0xA0,  0x01,  0x20,  0x02,  0x20,  0x04,  0x20,  0x07,  0xE0,  0x7C,  0x20,  0x04,  0x20,  0x04,  0x21,  0x04, 	/* 24240 */
+	0x11,  0x0C,  0x0F,  0xBE,  0x08,  0x40,  0x08,  0x40,  0x7F,  0x40,  0x08,  0x7F,  0x3E,  0x40,  0x22,  0x80, 	/* 24250 */
+	0x22,  0xFC,  0x3F,  0x04,  0x22,  0x08,  0x22,  0x10,  0x3E,  0x20,  0x08,  0x20,  0x7F,  0xC2,  0x08,  0x42, 	/* 24260 */
+	0x08,  0x42,  0x08,  0x3E,  0x80,  0x02,  0x00,  0x07,  0xF0,  0x08,  0x20,  0x1F,  0xF8,  0x68,  0x88,  0x0F, 	/* 24270 */
+	0xF8,  0x08,  0x88,  0x0F,  0xF8,  0x00,  0x80,  0x1F,  0xFC,  0x10,  0x84,  0x1F,  0xFC,  0x10,  0x84,  0x1F, 	/* 24280 */
+	0xFD,  0x00,  0x81,  0x00,  0x7F,  0x82,  0x01,  0x10,  0x06,  0x10,  0x7C,  0x90,  0x12,  0x50,  0x22,  0x50, 	/* 24290 */
+	0x7F,  0xD0,  0x11,  0x10,  0x0A,  0x10,  0x3F,  0xD0,  0x25,  0x50,  0x3E,  0xD0,  0x20,  0x51,  0x2F,  0x51, 	/* 242A0 */
+	0x25,  0x51,  0x22,  0x4F,  0x2D,  0xC0,  0x85,  0x01,  0x00,  0x01,  0x00,  0x01,  0x00,  0x01,  0x00,  0x01, 	/* 242B0 */
+	0x00,  0x01,  0x00,  0x01,  0x00,  0x01,  0x00,  0x01,  0x00,  0x01,  0x00,  0x01,  0x00,  0x01,  0x00,  0x01, 	/* 242C0 */
+	0x00,  0x01,  0x00,  0x01,  0x00,  0x03,  0x00,  0x86,  0x00,  0x00,  0x3F,  0xFC,  0x00,  0x08,  0x00,  0x10, 	/* 242D0 */
+	0x00,  0x20,  0x00,  0xC0,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80, 	/* 242E0 */
+	0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x01,  0x80,  0x88,  0x00,  0x00,  0x1F,  0xF8,  0x00,  0x10,  0x06, 	/* 242F0 */
+	0x20,  0x01,  0x40,  0x00,  0x80,  0x7F,  0xFE,  0x00,  0x82,  0x00,  0x84,  0x00,  0x88,  0x00,  0x80,  0x00, 	/* 24300 */
+	0x80,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x01,  0x80,  0x89,  0x01,  0x00,  0x01,  0xE0,  0x02,  0x20, 	/* 24310 */
+	0x04,  0x40,  0x18,  0x80,  0x1F,  0xF8,  0x00,  0x88,  0x00,  0x88,  0x7F,  0xFF,  0x00,  0x88,  0x00,  0x88, 	/* 24320 */
+	0x1F,  0xF8,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x01,  0x80,  0x8A,  0x00,  0x80,  0x00,  0x80,  0x3F, 	/* 24330 */
+	0xFE,  0x08,  0x88,  0x04,  0x90,  0x04,  0x80,  0x1F,  0xFC,  0x00,  0x84,  0x00,  0x84,  0x7F,  0xFF,  0x00, 	/* 24340 */
+	0x84,  0x00,  0x84,  0x1F,  0xFC,  0x00,  0x80,  0x00,  0x80,  0x01,  0x80,  0x8B,  0x00,  0x80,  0x00,  0x80, 	/* 24350 */
+	0x7F,  0xFF,  0x00,  0x80,  0x0F,  0xF8,  0x08,  0x88,  0x0F,  0xF8,  0x00,  0x80,  0x1F,  0xFC,  0x00,  0x84, 	/* 24360 */
+	0x7F,  0xFF,  0x00,  0x84,  0x1F,  0xFC,  0x00,  0x80,  0x00,  0x80,  0x01,  0x80,  0x8C,  0x00,  0x00,  0x00, 	/* 24370 */
+	0x00,  0x1F,  0xFC,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00, 	/* 24380 */
+	0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x7F,  0xFF,  0x00,  0x00,  0x00,  0x00,  0x8E,  0x00,  0x00, 	/* 24390 */
+	0x1F,  0xFC,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x7F,  0xFF,  0x00,  0x80, 	/* 243A0 */
+	0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x01,  0x80,  0x91,  0x00, 	/* 243B0 */
+	0x00,  0x00,  0x00,  0x1F,  0xF8,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x7F,  0xFE,  0x01,  0x00,  0x01, 	/* 243C0 */
+	0x00,  0x02,  0x20,  0x02,  0x10,  0x04,  0x08,  0x08,  0xF8,  0x7F,  0x04,  0x00,  0x04,  0x00,  0x04,  0x92, 	/* 243D0 */
+	0x00,  0x00,  0x3F,  0xFE,  0x02,  0x00,  0x02,  0x00,  0x02,  0x00,  0x03,  0xF0,  0x04,  0x10,  0x04,  0x10, 	/* 243E0 */
+	0x04,  0x10,  0x08,  0x10,  0x0F,  0xE0,  0x00,  0x20,  0x00,  0x20,  0x00,  0x20,  0x7F,  0xFF,  0x00,  0x00, 	/* 243F0 */
+	0x94,  0x00,  0x00,  0x3F,  0xFE,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x1F,  0xF8,  0x01, 	/* 24400 */
+	0x08,  0x01,  0x08,  0x01,  0x08,  0x01,  0x08,  0x02,  0x08,  0x02,  0x08,  0x02,  0x08,  0x7F,  0xFF,  0x00, 	/* 24410 */
+	0x00,  0x95,  0x04,  0x20,  0x04,  0x20,  0x04,  0x20,  0x04,  0x20,  0x3F,  0xFC,  0x04,  0x20,  0x04,  0x20, 	/* 24420 */
+	0x04,  0x20,  0x04,  0x20,  0x7F,  0xFE,  0x04,  0x20,  0x04,  0x20,  0x04,  0x20,  0x08,  0x20,  0x08,  0x20, 	/* 24430 */
+	0x10,  0x20,  0x98,  0x00,  0x00,  0x3F,  0xFC,  0x00,  0x00,  0x00,  0x00,  0x0F,  0xF0,  0x08,  0x10,  0x08, 	/* 24440 */
+	0x10,  0x0F,  0xF0,  0x08,  0x10,  0x08,  0x10,  0x08,  0x10,  0x0F,  0xF0,  0x00,  0x00,  0x00,  0x00,  0x7F, 	/* 24450 */
+	0xFE,  0x00,  0x00,  0x99,  0x00,  0x00,  0x3F,  0xFE,  0x02,  0x00,  0x02,  0x00,  0x03,  0xF0,  0x02,  0x10, 	/* 24460 */
+	0x05,  0x90,  0x04,  0x50,  0x04,  0x10,  0x0B,  0x20,  0x08,  0xA0,  0x08,  0x20,  0x00,  0x20,  0x00,  0x20, 	/* 24470 */
+	0x7F,  0xFF,  0x00,  0x00,  0x9B,  0x04,  0x40,  0x04,  0x40,  0x14,  0x44,  0x17,  0x78,  0x14,  0x40,  0x14, 	/* 24480 */
+	0x40,  0x14,  0x42,  0x17,  0x42,  0x18,  0x3E,  0x60,  0x00,  0x0F,  0xF8,  0x00,  0x00,  0x00,  0x00,  0x00, 	/* 24490 */
+	0x00,  0x7F,  0xFF,  0x00,  0x00,  0x9C,  0x00,  0x00,  0x3F,  0xFF,  0x02,  0x20,  0x02,  0x20,  0x02,  0x20, 	/* 244A0 */
+	0x1F,  0xFC,  0x12,  0x24,  0x12,  0x24,  0x12,  0x24,  0x12,  0x24,  0x1F,  0xFC,  0x02,  0x20,  0x02,  0x20, 	/* 244B0 */
+	0x02,  0x20,  0x7F,  0xFF,  0x00,  0x00,  0x9E,  0x00,  0x00,  0x7F,  0xFF,  0x02,  0x20,  0x02,  0x20,  0x02, 	/* 244C0 */
+	0x20,  0x3E,  0x3E,  0x20,  0x02,  0x20,  0x02,  0x20,  0x02,  0x20,  0x02,  0x3E,  0x3E,  0x02,  0x20,  0x02, 	/* 244D0 */
+	0x20,  0x02,  0x20,  0x7F,  0xFF,  0x00,  0x00,  0x9F,  0x00,  0x00,  0x3F,  0xFE,  0x01,  0x00,  0x01,  0x00, 	/* 244E0 */
+	0x03,  0xC0,  0x00,  0x7E,  0x3E,  0x42,  0x22,  0x54,  0x22,  0x4C,  0x3E,  0x4C,  0x22,  0x52,  0x00,  0xA1, 	/* 244F0 */
+	0x03,  0x00,  0x00,  0x00,  0x7F,  0xFF,  0x00,  0x00,  0xA0,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00, 	/* 24500 */
+	0x80,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x7F,  0xFF,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00, 	/* 24510 */
+	0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0xA1,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80, 	/* 24520 */
+	0x7F,  0xFF,  0x08,  0x00,  0x08,  0x00,  0x08,  0x00,  0x08,  0x00,  0x08,  0x00,  0x08,  0x00,  0x08,  0x00, 	/* 24530 */
+	0x08,  0x00,  0x08,  0x00,  0x04,  0x00,  0x03,  0xFC,  0x00,  0x00,  0xA2,  0x00,  0x80,  0x00,  0x80,  0x00, 	/* 24540 */
+	0x80,  0x7F,  0xFE,  0x00,  0x00,  0x00,  0x00,  0x03,  0xE0,  0x02,  0x20,  0x02,  0x20,  0x02,  0x20,  0x02, 	/* 24550 */
+	0x20,  0x02,  0x20,  0x04,  0x22,  0x04,  0x22,  0x08,  0x22,  0x30,  0x1E,  0xA4,  0x00,  0x80,  0x00,  0x80, 	/* 24560 */
+	0x00,  0x80,  0x7F,  0xFF,  0x04,  0x20,  0x04,  0x10,  0x08,  0x28,  0x0A,  0x28,  0x12,  0x24,  0x21,  0x44, 	/* 24570 */
+	0x01,  0x40,  0x00,  0x80,  0x01,  0x40,  0x02,  0x20,  0x0C,  0x18,  0x70,  0x07,  0xA5,  0x00,  0x80,  0x00, 	/* 24580 */
+	0x80,  0x00,  0x80,  0x7F,  0xFF,  0x01,  0x00,  0x01,  0x10,  0x1A,  0x20,  0x04,  0x40,  0x02,  0x88,  0x01, 	/* 24590 */
+	0x10,  0x06,  0x20,  0x18,  0x60,  0x00,  0x90,  0x03,  0x08,  0x0C,  0x04,  0x70,  0x04,  0xA6,  0x00,  0x80, 	/* 245A0 */
+	0x00,  0x80,  0x00,  0x80,  0x7F,  0xFF,  0x02,  0x20,  0x02,  0x20,  0x0A,  0x28,  0x0A,  0x24,  0x0A,  0x24, 	/* 245B0 */
+	0x12,  0x22,  0x22,  0x22,  0x42,  0x22,  0x04,  0x20,  0x04,  0x20,  0x08,  0x20,  0x10,  0x60,  0xA8,  0x00, 	/* 245C0 */
+	0x80,  0x00,  0x80,  0x7F,  0xFF,  0x00,  0x00,  0x0F,  0xF8,  0x08,  0x08,  0x0F,  0xF8,  0x00,  0x00,  0x3F, 	/* 245D0 */
+	0xFC,  0x00,  0x08,  0x00,  0x30,  0x00,  0xC0,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x01,  0x80,  0xAB, 	/* 245E0 */
+	0x00,  0x80,  0x00,  0x80,  0x7F,  0xFF,  0x00,  0x00,  0x0F,  0xF8,  0x08,  0x08,  0x0F,  0xF8,  0x00,  0x00, 	/* 245F0 */
+	0x1F,  0xF8,  0x00,  0x20,  0x00,  0x40,  0x7F,  0xFE,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x01,  0x80, 	/* 24600 */
+	0xAC,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x7F,  0xFF,  0x00,  0x00,  0x0F,  0xF8,  0x08,  0x08,  0x08, 	/* 24610 */
+	0x08,  0x08,  0x08,  0x0F,  0xF8,  0x00,  0x80,  0x04,  0xB0,  0x08,  0x88,  0x10,  0x84,  0x60,  0x82,  0x01, 	/* 24620 */
+	0x80,  0xAD,  0x00,  0x80,  0x00,  0x80,  0x7F,  0xFF,  0x00,  0x00,  0x0F,  0xF0,  0x08,  0x10,  0x0F,  0xF0, 	/* 24630 */
+	0x00,  0x00,  0x7F,  0xFE,  0x40,  0x02,  0x4F,  0xF2,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80, 	/* 24640 */
+	0x01,  0x80,  0xAE,  0x00,  0x80,  0x00,  0x80,  0x7F,  0xFF,  0x00,  0x00,  0x0F,  0xF8,  0x08,  0x08,  0x0F, 	/* 24650 */
+	0xF8,  0x00,  0x00,  0x7F,  0xFE,  0x40,  0x02,  0x42,  0x42,  0x02,  0x40,  0x02,  0x40,  0x04,  0x41,  0x18, 	/* 24660 */
+	0x21,  0x60,  0x1F,  0xB0,  0x00,  0x80,  0x00,  0x80,  0x7F,  0xFF,  0x00,  0x00,  0x0F,  0xF0,  0x08,  0x10, 	/* 24670 */
+	0x08,  0x10,  0x0F,  0xF0,  0x08,  0x10,  0x0F,  0xF0,  0x00,  0x80,  0x04,  0xA0,  0x08,  0x98,  0x10,  0x84, 	/* 24680 */
+	0x60,  0x82,  0x01,  0x80,  0xB3,  0x01,  0x00,  0x7F,  0xFE,  0x00,  0x00,  0x0F,  0xF0,  0x08,  0x10,  0x0F, 	/* 24690 */
+	0xF0,  0x00,  0x00,  0x7F,  0xFE,  0x40,  0x12,  0x41,  0xE2,  0x1F,  0x00,  0x01,  0x00,  0x7F,  0xFE,  0x01, 	/* 246A0 */
+	0x00,  0x00,  0x82,  0x00,  0x7E,  0xB6,  0x00,  0x80,  0x7F,  0xFF,  0x00,  0x00,  0x1F,  0xFC,  0x13,  0xE4, 	/* 246B0 */
+	0x12,  0x24,  0x13,  0xE4,  0x10,  0x04,  0x1F,  0xFC,  0x04,  0x10,  0x07,  0xF0,  0x04,  0x10,  0x07,  0xF0, 	/* 246C0 */
+	0x00,  0x00,  0x7F,  0xFF,  0x00,  0x00,  0xBA,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x00, 	/* 246D0 */
+	0x80,  0x00,  0x80,  0x00,  0x80,  0x01,  0x40,  0x01,  0x40,  0x02,  0x20,  0x02,  0x20,  0x04,  0x10,  0x08, 	/* 246E0 */
+	0x08,  0x10,  0x04,  0x20,  0x02,  0x40,  0x01,  0x80,  0x04,  0x10,  0x04,  0x10,  0x04,  0x10,  0x08,  0x10, 	/* 246F0 */
+	0x08,  0x10,  0x18,  0x10,  0x1B,  0xFF,  0x28,  0x10,  0x48,  0x10,  0x08,  0x10,  0x08,  0x10,  0x08,  0x10, 	/* 24700 */
+	0x08,  0x10,  0x08,  0x10,  0x08,  0x10,  0x08,  0x10,  0x81,  0x04,  0x00,  0x04,  0x00,  0x04,  0x00,  0x09, 	/* 24710 */
+	0xFC,  0x08,  0x00,  0x10,  0x00,  0x30,  0x00,  0x50,  0x00,  0x10,  0x00,  0x10,  0x00,  0x10,  0x00,  0x10, 	/* 24720 */
+	0x00,  0x10,  0x00,  0x17,  0xFF,  0x10,  0x00,  0x10,  0x00,  0x82,  0x04,  0x40,  0x04,  0x40,  0x04,  0x40, 	/* 24730 */
+	0x08,  0x40,  0x0B,  0xFE,  0x10,  0x42,  0x10,  0x42,  0x30,  0x42,  0x50,  0x42,  0x10,  0x42,  0x10,  0x42, 	/* 24740 */
+	0x10,  0x82,  0x10,  0x82,  0x11,  0x02,  0x12,  0x04,  0x14,  0x18,  0x84,  0x00,  0x00,  0x1F,  0xFF,  0x10, 	/* 24750 */
+	0x00,  0x10,  0x40,  0x10,  0x40,  0x10,  0x40,  0x10,  0x40,  0x10,  0x40,  0x10,  0x40,  0x10,  0x40,  0x10, 	/* 24760 */
+	0xA0,  0x10,  0xA0,  0x21,  0x10,  0x22,  0x08,  0x4C,  0x04,  0x30,  0x03,  0x86,  0x02,  0x20,  0x02,  0x20, 	/* 24770 */
+	0x04,  0x20,  0x04,  0x20,  0x08,  0x20,  0x08,  0x20,  0x18,  0x30,  0x28,  0x28,  0x48,  0x24,  0x08,  0x22, 	/* 24780 */
+	0x08,  0x22,  0x08,  0x20,  0x08,  0x20,  0x08,  0x20,  0x08,  0x20,  0x08,  0x20,  0x87,  0x04,  0x80,  0x04, 	/* 24790 */
+	0x80,  0x04,  0x80,  0x08,  0x80,  0x08,  0xF0,  0x0F,  0x90,  0x10,  0x90,  0x30,  0x90,  0x50,  0x90,  0x10, 	/* 247A0 */
+	0x90,  0x10,  0x90,  0x11,  0x12,  0x11,  0x12,  0x12,  0x12,  0x14,  0x0E,  0x18,  0x00,  0x8A,  0x00,  0x80, 	/* 247B0 */
+	0x00,  0x80,  0x01,  0x40,  0x02,  0x20,  0x04,  0x10,  0x08,  0x08,  0x13,  0xE4,  0x60,  0x03,  0x00,  0x00, 	/* 247C0 */
+	0x0F,  0xF0,  0x00,  0x10,  0x00,  0x20,  0x00,  0x20,  0x00,  0x40,  0x00,  0x80,  0x01,  0x00,  0x8B,  0x00, 	/* 247D0 */
+	0x80,  0x00,  0x80,  0x01,  0x40,  0x02,  0x20,  0x04,  0x10,  0x18,  0x0C,  0x64,  0x13,  0x04,  0x10,  0x04, 	/* 247E0 */
+	0x10,  0x04,  0x10,  0x04,  0x10,  0x04,  0x10,  0x08,  0x10,  0x08,  0x10,  0x10,  0x10,  0x20,  0x10,  0x8D, 	/* 247F0 */
+	0x04,  0x00,  0x07,  0xF8,  0x04,  0x88,  0x08,  0x88,  0x08,  0x88,  0x10,  0x88,  0x10,  0x8E,  0x30,  0x82, 	/* 24800 */
+	0x50,  0x82,  0x10,  0x82,  0x10,  0x82,  0x11,  0x02,  0x11,  0x02,  0x12,  0x02,  0x14,  0x04,  0x18,  0x18, 	/* 24810 */
+	0x8E,  0x04,  0x10,  0x04,  0x10,  0x04,  0x10,  0x04,  0x10,  0x04,  0x10,  0x04,  0x10,  0x04,  0x10,  0x04, 	/* 24820 */
+	0x10,  0x06,  0x10,  0x0A,  0x18,  0x09,  0x28,  0x09,  0x28,  0x10,  0xC4,  0x10,  0x44,  0x20,  0x82,  0x41, 	/* 24830 */
+	0x01,  0x8F,  0x04,  0x20,  0x04,  0x20,  0x04,  0x20,  0x08,  0x20,  0x08,  0x20,  0x10,  0x20,  0x10,  0x40, 	/* 24840 */
+	0x30,  0x40,  0x50,  0x50,  0x10,  0x48,  0x10,  0x84,  0x10,  0x84,  0x10,  0x82,  0x11,  0x3E,  0x17,  0xC1, 	/* 24850 */
+	0x10,  0x01,  0x94,  0x04,  0x00,  0x05,  0xFC,  0x04,  0x04,  0x08,  0x08,  0x08,  0x10,  0x10,  0x20,  0x30, 	/* 24860 */
+	0x20,  0x57,  0xFF,  0x10,  0x20,  0x10,  0x20,  0x10,  0x20,  0x10,  0x20,  0x10,  0x20,  0x10,  0x20,  0x10, 	/* 24870 */
+	0x20,  0x10,  0x60,  0x95,  0x04,  0x20,  0x04,  0x20,  0x04,  0x20,  0x08,  0x20,  0x08,  0x20,  0x10,  0x20, 	/* 24880 */
+	0x17,  0xFF,  0x30,  0x20,  0x50,  0x20,  0x10,  0x20,  0x10,  0x20,  0x10,  0x20,  0x10,  0x20,  0x10,  0x20, 	/* 24890 */
+	0x13,  0xFE,  0x10,  0x00,  0x96,  0x04,  0x10,  0x04,  0x10,  0x04,  0x90,  0x08,  0x92,  0x08,  0x9E,  0x18, 	/* 248A0 */
+	0xF2,  0x1B,  0x92,  0x28,  0x92,  0x48,  0x92,  0x08,  0x92,  0x08,  0x9C,  0x08,  0x90,  0x08,  0x81,  0x08, 	/* 248B0 */
+	0x81,  0x08,  0x41,  0x08,  0x3F,  0x97,  0x04,  0x20,  0x04,  0x20,  0x04,  0x20,  0x08,  0x20,  0x0B,  0xFF, 	/* 248C0 */
+	0x10,  0x20,  0x11,  0x20,  0x31,  0x20,  0x50,  0xA0,  0x10,  0xA0,  0x10,  0x40,  0x10,  0x40,  0x10,  0xA0, 	/* 248D0 */
+	0x11,  0x10,  0x12,  0x0C,  0x1C,  0x03,  0x98,  0x02,  0x08,  0x02,  0x08,  0x02,  0x08,  0x04,  0x08,  0x05, 	/* 248E0 */
+	0xFF,  0x08,  0x08,  0x0A,  0x08,  0x19,  0x08,  0x28,  0x88,  0x48,  0x88,  0x08,  0x88,  0x08,  0x08,  0x08, 	/* 248F0 */
+	0x08,  0x08,  0x08,  0x08,  0x08,  0x08,  0x18,  0x99,  0x04,  0x20,  0x04,  0x20,  0x04,  0x20,  0x08,  0x20, 	/* 24900 */
+	0x0A,  0x22,  0x12,  0x22,  0x12,  0x22,  0x32,  0x22,  0x52,  0x22,  0x12,  0x22,  0x12,  0x22,  0x12,  0x22, 	/* 24910 */
+	0x12,  0x22,  0x12,  0x22,  0x13,  0xFE,  0x10,  0x00,  0x9D,  0x00,  0x80,  0x00,  0x80,  0x01,  0x40,  0x02, 	/* 24920 */
+	0x20,  0x04,  0x10,  0x18,  0x0C,  0x60,  0x03,  0x00,  0x00,  0x0F,  0xFC,  0x00,  0x80,  0x00,  0x80,  0x00, 	/* 24930 */
+	0x80,  0x00,  0x80,  0x00,  0x80,  0x3F,  0xFE,  0x00,  0x00,  0x9E,  0x04,  0x00,  0x07,  0xFE,  0x04,  0x42, 	/* 24940 */
+	0x08,  0x42,  0x08,  0x42,  0x11,  0x42,  0x11,  0x42,  0x31,  0x42,  0x52,  0x42,  0x14,  0x42,  0x10,  0x42, 	/* 24950 */
+	0x10,  0x82,  0x10,  0x82,  0x11,  0x02,  0x12,  0x04,  0x14,  0x18,  0x9F,  0x04,  0x04,  0x04,  0x18,  0x05, 	/* 24960 */
+	0xE0,  0x08,  0x20,  0x08,  0x20,  0x10,  0x20,  0x10,  0x20,  0x37,  0xFF,  0x50,  0x20,  0x10,  0x20,  0x10, 	/* 24970 */
+	0x20,  0x10,  0x20,  0x10,  0x20,  0x10,  0x20,  0x10,  0x20,  0x10,  0x20,  0xA3,  0x04,  0x28,  0x04,  0x24, 	/* 24980 */
+	0x04,  0x22,  0x08,  0x20,  0x08,  0x20,  0x18,  0x3F,  0x1B,  0xE0,  0x28,  0x20,  0x48,  0x10,  0x08,  0x10, 	/* 24990 */
+	0x08,  0x10,  0x08,  0x08,  0x08,  0x09,  0x08,  0x05,  0x08,  0x03,  0x08,  0x01,  0xA4,  0x00,  0x80,  0x00, 	/* 249A0 */
+	0x80,  0x01,  0x40,  0x02,  0x20,  0x04,  0x10,  0x18,  0x0C,  0x67,  0xF3,  0x00,  0x00,  0x00,  0x00,  0x3F, 	/* 249B0 */
+	0xFC,  0x00,  0x84,  0x00,  0x84,  0x00,  0x84,  0x00,  0x98,  0x00,  0x80,  0x00,  0x80,  0xA5,  0x00,  0x00, 	/* 249C0 */
+	0x10,  0x08,  0x10,  0x08,  0x10,  0x08,  0x12,  0x08,  0x11,  0x08,  0x10,  0x88,  0x10,  0x88,  0x10,  0x08, 	/* 249D0 */
+	0x10,  0x08,  0x10,  0x18,  0x11,  0x14,  0x16,  0x22,  0x18,  0x42,  0x60,  0x81,  0x03,  0x01,  0xAD,  0x04, 	/* 249E0 */
+	0x00,  0x07,  0xFC,  0x04,  0x44,  0x08,  0x44,  0x08,  0x44,  0x10,  0x44,  0x12,  0x44,  0x31,  0x44,  0x50, 	/* 249F0 */
+	0xC4,  0x10,  0x74,  0x10,  0x4F,  0x10,  0x84,  0x10,  0x84,  0x11,  0x04,  0x12,  0x08,  0x14,  0x30,  0xAE, 	/* 24A00 */
+	0x04,  0x00,  0x05,  0xFF,  0x05,  0x00,  0x09,  0x00,  0x09,  0x00,  0x11,  0xFC,  0x11,  0x84,  0x31,  0x44, 	/* 24A10 */
+	0x51,  0x48,  0x11,  0x28,  0x12,  0x30,  0x12,  0x10,  0x14,  0x28,  0x14,  0x44,  0x19,  0x82,  0x16,  0x01, 	/* 24A20 */
+	0xB0,  0x04,  0x40,  0x04,  0x80,  0x07,  0x3E,  0x0A,  0x22,  0x0A,  0x22,  0x12,  0x22,  0x12,  0x22,  0x32, 	/* 24A30 */
+	0x22,  0x52,  0x22,  0x12,  0x22,  0x12,  0x62,  0x13,  0xA2,  0x16,  0x2C,  0x10,  0x20,  0x10,  0x20,  0x10, 	/* 24A40 */
+	0x20,  0xB2,  0x04,  0x20,  0x04,  0x20,  0x04,  0x20,  0x08,  0x20,  0x0B,  0xFE,  0x1A,  0x22,  0x1A,  0x22, 	/* 24A50 */
+	0x2A,  0x22,  0x4A,  0x22,  0x0B,  0xFE,  0x08,  0x20,  0x08,  0x20,  0x08,  0x20,  0x08,  0x20,  0x08,  0x20, 	/* 24A60 */
+	0x08,  0x20,  0xB6,  0x04,  0x20,  0x05,  0x20,  0x05,  0x20,  0x09,  0x20,  0x09,  0xFE,  0x12,  0x20,  0x12, 	/* 24A70 */
+	0x20,  0x34,  0x20,  0x50,  0x20,  0x13,  0xFF,  0x10,  0x20,  0x10,  0x20,  0x10,  0x20,  0x10,  0x20,  0x10, 	/* 24A80 */
+	0x20,  0x10,  0x20,  0xB7,  0x04,  0x20,  0x04,  0x20,  0x04,  0x50,  0x08,  0x50,  0x08,  0x88,  0x11,  0x8C, 	/* 24A90 */
+	0x12,  0x8A,  0x34,  0x89,  0x50,  0x88,  0x10,  0x88,  0x10,  0x88,  0x10,  0x88,  0x11,  0x08,  0x11,  0x08, 	/* 24AA0 */
+	0x12,  0x08,  0x14,  0x08,  0xBB,  0x04,  0x04,  0x04,  0x18,  0x04,  0x60,  0x0B,  0xA0,  0x08,  0x20,  0x18, 	/* 24AB0 */
+	0x20,  0x18,  0x20,  0x2F,  0xFF,  0x48,  0x20,  0x08,  0x20,  0x08,  0x20,  0x08,  0x20,  0x08,  0x20,  0x0B, 	/* 24AC0 */
+	0xFE,  0x08,  0x00,  0x08,  0x00,  0x81,  0x00,  0x80,  0x00,  0x80,  0x01,  0x40,  0x02,  0x20,  0x04,  0x10, 	/* 24AD0 */
+	0x18,  0x8C,  0x60,  0x83,  0x00,  0x80,  0x08,  0xFC,  0x08,  0x80,  0x08,  0x80,  0x08,  0x80,  0x08,  0x80, 	/* 24AE0 */
+	0x08,  0x80,  0x7F,  0xFF,  0x00,  0x00,  0x89,  0x04,  0x20,  0x04,  0x20,  0x04,  0x20,  0x0B,  0xFF,  0x08, 	/* 24AF0 */
+	0x00,  0x10,  0x00,  0x10,  0xF0,  0x30,  0x90,  0x50,  0x90,  0x10,  0x90,  0x10,  0x90,  0x11,  0x10,  0x11, 	/* 24B00 */
+	0x10,  0x12,  0x12,  0x14,  0x12,  0x18,  0x0E,  0x8A,  0x04,  0x00,  0x05,  0xFC,  0x04,  0x24,  0x08,  0x24, 	/* 24B10 */
+	0x08,  0x24,  0x1F,  0xFF,  0x18,  0x24,  0x28,  0x24,  0x48,  0x24,  0x09,  0xFC,  0x08,  0x20,  0x08,  0x20, 	/* 24B20 */
+	0x08,  0x40,  0x08,  0x40,  0x08,  0x80,  0x09,  0x00,  0x8D,  0x04,  0x00,  0x07,  0xFE,  0x04,  0x40,  0x08, 	/* 24B30 */
+	0x40,  0x08,  0x40,  0x10,  0x40,  0x13,  0xF8,  0x30,  0x48,  0x50,  0x48,  0x10,  0x48,  0x10,  0x88,  0x10, 	/* 24B40 */
+	0x88,  0x10,  0x88,  0x10,  0x88,  0x17,  0xFF,  0x10,  0x00,  0x8E,  0x04,  0x20,  0x04,  0x20,  0x04,  0x20, 	/* 24B50 */
+	0x0F,  0xFF,  0x08,  0x20,  0x18,  0x20,  0x18,  0x20,  0x2B,  0xFC,  0x48,  0x84,  0x08,  0x48,  0x08,  0x48, 	/* 24B60 */
+	0x08,  0x30,  0x08,  0x30,  0x08,  0x48,  0x08,  0x84,  0x0B,  0x03,  0x8F,  0x04,  0x40,  0x04,  0x48,  0x04, 	/* 24B70 */
+	0x44,  0x08,  0x44,  0x08,  0x40,  0x17,  0xFF,  0x10,  0x40,  0x30,  0x40,  0x50,  0x40,  0x10,  0x60,  0x10, 	/* 24B80 */
+	0xA0,  0x10,  0x90,  0x11,  0x08,  0x12,  0x04,  0x14,  0x02,  0x18,  0x01,  0x90,  0x04,  0x88,  0x04,  0x84, 	/* 24B90 */
+	0x04,  0x84,  0x08,  0x80,  0x0F,  0xFF,  0x10,  0x84,  0x10,  0x84,  0x30,  0x48,  0x50,  0x48,  0x10,  0x50, 	/* 24BA0 */
+	0x10,  0x20,  0x10,  0x50,  0x11,  0x92,  0x16,  0x0A,  0x10,  0x06,  0x10,  0x02,  0x91,  0x08,  0x40,  0x08, 	/* 24BB0 */
+	0x40,  0x08,  0x40,  0x08,  0x40,  0x17,  0xFE,  0x10,  0xE0,  0x10,  0xE0,  0x31,  0x50,  0x51,  0x50,  0x12, 	/* 24BC0 */
+	0x48,  0x12,  0x44,  0x14,  0x42,  0x18,  0x41,  0x10,  0x40,  0x10,  0x40,  0x10,  0x40,  0x9A,  0x00,  0x80, 	/* 24BD0 */
+	0x00,  0x80,  0x01,  0x40,  0x02,  0x20,  0x04,  0x10,  0x18,  0x0C,  0x67,  0xF3,  0x00,  0x00,  0x00,  0x00, 	/* 24BE0 */
+	0x3F,  0xFE,  0x01,  0x00,  0x01,  0x20,  0x02,  0x10,  0x04,  0x68,  0x3F,  0x84,  0x00,  0x04,  0x9C,  0x04, 	/* 24BF0 */
+	0x40,  0x04,  0x40,  0x07,  0xF8,  0x08,  0x48,  0x08,  0x88,  0x10,  0x89,  0x11,  0x09,  0x32,  0x07,  0x54, 	/* 24C00 */
+	0x20,  0x10,  0x20,  0x17,  0xFF,  0x10,  0x20,  0x10,  0x20,  0x10,  0x20,  0x10,  0x20,  0x10,  0x20,  0x9D, 	/* 24C10 */
+	0x04,  0x00,  0x04,  0x00,  0x05,  0xFC,  0x08,  0x00,  0x08,  0x00,  0x10,  0x00,  0x17,  0xFF,  0x30,  0x40, 	/* 24C20 */
+	0x50,  0x40,  0x10,  0x50,  0x10,  0x88,  0x10,  0x84,  0x11,  0x04,  0x11,  0x3E,  0x17,  0xC2,  0x10,  0x02, 	/* 24C30 */
+	0xAF,  0x04,  0x20,  0x04,  0x20,  0x04,  0x40,  0x09,  0xFC,  0x09,  0x04,  0x11,  0x04,  0x11,  0x04,  0x31, 	/* 24C40 */
+	0x04,  0x51,  0xFC,  0x11,  0x04,  0x11,  0x04,  0x11,  0x04,  0x11,  0x04,  0x11,  0x04,  0x11,  0xFC,  0x10, 	/* 24C50 */
+	0x00,  0xB0,  0x04,  0x20,  0x04,  0x20,  0x04,  0x20,  0x08,  0x20,  0x0F,  0xFF,  0x10,  0x20,  0x10,  0x20, 	/* 24C60 */
+	0x30,  0x20,  0x50,  0x20,  0x11,  0xFC,  0x11,  0x04,  0x11,  0x04,  0x11,  0x04,  0x11,  0x04,  0x11,  0xFC, 	/* 24C70 */
+	0x10,  0x00,  0xB4,  0x04,  0x20,  0x04,  0x24,  0x05,  0x24,  0x08,  0xA4,  0x08,  0xA8,  0x18,  0x20,  0x1B, 	/* 24C80 */
+	0xFE,  0x28,  0x20,  0x48,  0x20,  0x08,  0x20,  0x0F,  0xFF,  0x08,  0x20,  0x08,  0x20,  0x08,  0x20,  0x08, 	/* 24C90 */
+	0x20,  0x08,  0x20,  0xB6,  0x04,  0x20,  0x04,  0x20,  0x04,  0x50,  0x08,  0x88,  0x09,  0x04,  0x12,  0xFA, 	/* 24CA0 */
+	0x14,  0x01,  0x30,  0x00,  0x53,  0xFC,  0x10,  0x44,  0x10,  0x44,  0x10,  0x44,  0x10,  0x44,  0x10,  0x58, 	/* 24CB0 */
+	0x10,  0x40,  0x10,  0x40,  0xB8,  0x04,  0x20,  0x04,  0x20,  0x04,  0x20,  0x0B,  0xFE,  0x0A,  0x22,  0x12, 	/* 24CC0 */
+	0x22,  0x12,  0x22,  0x33,  0xFE,  0x52,  0x22,  0x12,  0x22,  0x13,  0xFE,  0x10,  0x20,  0x10,  0x20,  0x10, 	/* 24CD0 */
+	0x20,  0x10,  0x20,  0x10,  0x20,  0xBA,  0x04,  0x00,  0x07,  0xFE,  0x04,  0x02,  0x08,  0x02,  0x0B,  0xFA, 	/* 24CE0 */
+	0x10,  0x02,  0x10,  0x02,  0x31,  0xF2,  0x51,  0x12,  0x11,  0x12,  0x11,  0x12,  0x11,  0xF2,  0x10,  0x02, 	/* 24CF0 */
+	0x10,  0x02,  0x10,  0x02,  0x10,  0x06,  0xBC,  0x04,  0x04,  0x05,  0x04,  0x05,  0x04,  0x09,  0x84,  0x09, 	/* 24D00 */
+	0x44,  0x11,  0x24,  0x11,  0x24,  0x31,  0x04,  0x51,  0x04,  0x11,  0x04,  0x11,  0x04,  0x11,  0x4C,  0x11, 	/* 24D10 */
+	0x8A,  0x13,  0x12,  0x1C,  0x21,  0x10,  0x41,  0xBD,  0x0A,  0x00,  0x0A,  0x00,  0x0A,  0x1E,  0x12,  0x12, 	/* 24D20 */
+	0x1F,  0xD2,  0x12,  0x52,  0x32,  0x52,  0x32,  0x52,  0x52,  0x52,  0x12,  0x52,  0x12,  0x52,  0x12,  0x52, 	/* 24D30 */
+	0x14,  0x52,  0x14,  0x5E,  0x19,  0x80,  0x10,  0x00,  0x83,  0x04,  0x00,  0x05,  0xFE,  0x05,  0x22,  0x09, 	/* 24D40 */
+	0x22,  0x09,  0x22,  0x11,  0x22,  0x11,  0x22,  0x31,  0xFE,  0x51,  0x22,  0x11,  0x22,  0x11,  0x22,  0x11, 	/* 24D50 */
+	0x22,  0x11,  0x22,  0x11,  0x22,  0x11,  0xFE,  0x10,  0x00,  0x86,  0x04,  0x00,  0x05,  0xFC,  0x05,  0x04, 	/* 24D60 */
+	0x09,  0x04,  0x09,  0x04,  0x19,  0x04,  0x19,  0xFC,  0x29,  0x04,  0x49,  0x04,  0x09,  0x04,  0x09,  0x04, 	/* 24D70 */
+	0x09,  0xFC,  0x08,  0x00,  0x08,  0x00,  0x0F,  0xFF,  0x08,  0x00,  0x87,  0x04,  0x20,  0x04,  0x20,  0x07, 	/* 24D80 */
+	0xFE,  0x0A,  0x02,  0x0A,  0x02,  0x10,  0x00,  0x13,  0xFF,  0x30,  0x20,  0x50,  0x20,  0x10,  0x20,  0x10, 	/* 24D90 */
+	0x20,  0x10,  0x20,  0x10,  0x20,  0x10,  0x20,  0x10,  0x20,  0x10,  0x60,  0x8D,  0x04,  0x20,  0x04,  0x20, 	/* 24DA0 */
+	0x04,  0x20,  0x08,  0x20,  0x0B,  0xFE,  0x18,  0x04,  0x18,  0x04,  0x29,  0x04,  0x48,  0x88,  0x08,  0x88, 	/* 24DB0 */
+	0x08,  0x88,  0x08,  0x90,  0x08,  0x90,  0x08,  0x20,  0x0F,  0xFF,  0x08,  0x00,  0x8E,  0x04,  0x04,  0x04, 	/* 24DC0 */
+	0x18,  0x05,  0xF0,  0x09,  0x10,  0x09,  0x10,  0x11,  0x10,  0x11,  0xFF,  0x31,  0x10,  0x51,  0x10,  0x11, 	/* 24DD0 */
+	0x08,  0x11,  0x08,  0x11,  0xC8,  0x16,  0x04,  0x10,  0x05,  0x17,  0xF3,  0x10,  0x01,  0x8F,  0x04,  0x40, 	/* 24DE0 */
+	0x04,  0x20,  0x04,  0x20,  0x0B,  0xFE,  0x08,  0x20,  0x10,  0x20,  0x10,  0x20,  0x30,  0x20,  0x53,  0xFE, 	/* 24DF0 */
+	0x10,  0x20,  0x10,  0x20,  0x10,  0x20,  0x10,  0x20,  0x10,  0x20,  0x17,  0xFF,  0x10,  0x00,  0x90,  0x04, 	/* 24E00 */
+	0x40,  0x04,  0x40,  0x04,  0x40,  0x0B,  0xFF,  0x08,  0x40,  0x10,  0x40,  0x10,  0x80,  0x30,  0x80,  0x51, 	/* 24E10 */
+	0xFE,  0x11,  0x20,  0x12,  0x20,  0x14,  0x20,  0x10,  0x20,  0x10,  0x20,  0x13,  0xFF,  0x10,  0x00,  0x91, 	/* 24E20 */
+	0x04,  0x40,  0x04,  0x40,  0x04,  0x40,  0x0F,  0xFF,  0x08,  0x40,  0x10,  0x40,  0x10,  0x80,  0x30,  0x80, 	/* 24E30 */
+	0x51,  0xFC,  0x11,  0x84,  0x12,  0x84,  0x14,  0x84,  0x10,  0x84,  0x10,  0x84,  0x10,  0xFC,  0x10,  0x00, 	/* 24E40 */
+	0x93,  0x08,  0x20,  0x08,  0x20,  0x08,  0x20,  0x08,  0x20,  0x17,  0xFF,  0x10,  0x70,  0x10,  0x70,  0x30, 	/* 24E50 */
+	0xA8,  0x50,  0xA8,  0x11,  0x24,  0x12,  0x22,  0x14,  0xFD,  0x10,  0x20,  0x10,  0x20,  0x10,  0x20,  0x10, 	/* 24E60 */
+	0x20,  0x95,  0x04,  0x00,  0x04,  0x00,  0x07,  0xFF,  0x08,  0x04,  0x08,  0x04,  0x13,  0xE4,  0x12,  0x24, 	/* 24E70 */
+	0x32,  0x24,  0x52,  0x24,  0x12,  0x24,  0x13,  0xE4,  0x10,  0x04,  0x10,  0x04,  0x10,  0x04,  0x10,  0x04, 	/* 24E80 */
+	0x10,  0x0C,  0x97,  0x04,  0x20,  0x04,  0x20,  0x04,  0x20,  0x0B,  0xFE,  0x0A,  0x02,  0x12,  0x82,  0x10, 	/* 24E90 */
+	0x80,  0x30,  0x84,  0x50,  0x98,  0x10,  0xE0,  0x10,  0x80,  0x10,  0x80,  0x10,  0x80,  0x10,  0x82,  0x10, 	/* 24EA0 */
+	0x42,  0x10,  0x3E,  0x99,  0x00,  0x80,  0x00,  0x80,  0x01,  0x40,  0x02,  0x20,  0x04,  0x10,  0x18,  0x0C, 	/* 24EB0 */
+	0x67,  0xFB,  0x00,  0x80,  0x00,  0x80,  0x3F,  0xFE,  0x00,  0x80,  0x04,  0x90,  0x04,  0x88,  0x08,  0x84, 	/* 24EC0 */
+	0x10,  0x84,  0x01,  0x80,  0x9A,  0x04,  0x20,  0x05,  0x20,  0x05,  0x20,  0x09,  0x20,  0x09,  0xFE,  0x12, 	/* 24ED0 */
+	0x20,  0x12,  0x20,  0x34,  0x20,  0x53,  0xFF,  0x10,  0x30,  0x10,  0x50,  0x10,  0x48,  0x10,  0x88,  0x11, 	/* 24EE0 */
+	0x04,  0x12,  0x02,  0x14,  0x01,  0x9B,  0x04,  0x90,  0x04,  0x90,  0x07,  0xFE,  0x08,  0x92,  0x08,  0x92, 	/* 24EF0 */
+	0x13,  0xFE,  0x12,  0x90,  0x32,  0x90,  0x53,  0xFF,  0x10,  0x91,  0x10,  0x91,  0x10,  0x91,  0x11,  0x12, 	/* 24F00 */
+	0x11,  0x1C,  0x12,  0x10,  0x14,  0x10,  0x9C,  0x04,  0x80,  0x04,  0x80,  0x04,  0x80,  0x08,  0xFF,  0x09, 	/* 24F10 */
+	0x20,  0x19,  0x20,  0x1A,  0x20,  0x2C,  0x3E,  0x48,  0x20,  0x08,  0x20,  0x08,  0x20,  0x08,  0x3E,  0x08, 	/* 24F20 */
+	0x20,  0x08,  0x20,  0x08,  0x20,  0x08,  0x20,  0x9D,  0x04,  0x80,  0x04,  0x80,  0x04,  0x80,  0x08,  0xFE, 	/* 24F30 */
+	0x09,  0x02,  0x11,  0x02,  0x13,  0xF2,  0x35,  0x12,  0x51,  0x12,  0x11,  0x12,  0x11,  0x12,  0x11,  0xF2, 	/* 24F40 */
+	0x10,  0x02,  0x10,  0x02,  0x10,  0x04,  0x10,  0x18,  0x9E,  0x04,  0x00,  0x05,  0xFC,  0x04,  0x00,  0x08, 	/* 24F50 */
+	0x00,  0x08,  0x00,  0x17,  0xFF,  0x10,  0x40,  0x30,  0x40,  0x57,  0xFF,  0x10,  0x88,  0x10,  0x88,  0x11, 	/* 24F60 */
+	0x10,  0x13,  0xF0,  0x10,  0x28,  0x10,  0xC4,  0x17,  0x02,  0xA9,  0x08,  0x00,  0x0B,  0xFC,  0x0A,  0x04, 	/* 24F70 */
+	0x0A,  0x04,  0x13,  0xFC,  0x12,  0x44,  0x32,  0x44,  0x33,  0xF4,  0x53,  0x54,  0x13,  0x54,  0x13,  0x54, 	/* 24F80 */
+	0x13,  0x54,  0x15,  0x75,  0x15,  0x45,  0x18,  0x43,  0x10,  0x41,  0xAF,  0x04,  0x84,  0x04,  0x44,  0x04, 	/* 24F90 */
+	0x48,  0x0B,  0xFE,  0x08,  0x20,  0x10,  0x20,  0x10,  0x20,  0x31,  0xFC,  0x50,  0x20,  0x10,  0x20,  0x10, 	/* 24FA0 */
+	0x20,  0x17,  0xFF,  0x10,  0x20,  0x10,  0x20,  0x10,  0x20,  0x10,  0x20,  0xB0,  0x04,  0x00,  0x07,  0xFF, 	/* 24FB0 */
+	0x04,  0x20,  0x08,  0x20,  0x08,  0x40,  0x11,  0xFC,  0x11,  0x04,  0x31,  0x04,  0x51,  0x04,  0x11,  0xFC, 	/* 24FC0 */
+	0x11,  0x04,  0x11,  0x04,  0x11,  0x04,  0x11,  0x04,  0x11,  0xFC,  0x10,  0x00,  0xB3,  0x04,  0x20,  0x04, 	/* 24FD0 */
+	0x20,  0x05,  0xFC,  0x08,  0x20,  0x08,  0x20,  0x18,  0x20,  0x2B,  0xFE,  0x28,  0x20,  0x48,  0x20,  0x08, 	/* 24FE0 */
+	0x20,  0x09,  0xFC,  0x08,  0x20,  0x08,  0x20,  0x08,  0x20,  0x0B,  0xFE,  0x08,  0x00,  0xB5,  0x05,  0x04, 	/* 24FF0 */
+	0x04,  0x84,  0x04,  0x88,  0x0B,  0xFE,  0x08,  0x88,  0x10,  0x88,  0x10,  0x88,  0x30,  0x88,  0x57,  0xFF, 	/* 25000 */
+	0x10,  0x88,  0x10,  0x88,  0x10,  0x88,  0x10,  0x88,  0x11,  0x08,  0x11,  0x08,  0x12,  0x08,  0xB6,  0x04, 	/* 25010 */
+	0x20,  0x04,  0x20,  0x04,  0x20,  0x0F,  0xFF,  0x08,  0x20,  0x10,  0x20,  0x10,  0x20,  0x33,  0xFE,  0x50, 	/* 25020 */
+	0x00,  0x10,  0x00,  0x11,  0xFC,  0x11,  0x04,  0x11,  0x04,  0x11,  0x04,  0x11,  0xFC,  0x10,  0x00,  0xBB, 	/* 25030 */
+	0x04,  0x90,  0x04,  0x90,  0x04,  0x92,  0x08,  0x92,  0x0C,  0x94,  0x12,  0x90,  0x12,  0x90,  0x30,  0x98, 	/* 25040 */
+	0x50,  0x94,  0x11,  0x92,  0x12,  0x91,  0x1C,  0x90,  0x11,  0x10,  0x11,  0x11,  0x12,  0x11,  0x14,  0x0F, 	/* 25050 */
+	0xBC,  0x04,  0x20,  0x04,  0x20,  0x04,  0x20,  0x0B,  0xFF,  0x08,  0x88,  0x10,  0x84,  0x11,  0x0A,  0x32, 	/* 25060 */
+	0x8A,  0x54,  0x88,  0x10,  0x50,  0x10,  0x50,  0x10,  0x20,  0x10,  0x50,  0x10,  0x88,  0x11,  0x04,  0x16, 	/* 25070 */
+	0x03,  0xBF,  0x04,  0x20,  0x04,  0x20,  0x07,  0xFF,  0x08,  0x20,  0x08,  0x20,  0x13,  0xFE,  0x12,  0x22, 	/* 25080 */
+	0x32,  0x22,  0x52,  0x22,  0x13,  0xFE,  0x10,  0xA0,  0x10,  0x40,  0x10,  0x60,  0x10,  0x90,  0x13,  0x0C, 	/* 25090 */
+	0x1C,  0x03,  0x83,  0x04,  0x00,  0x05,  0xFC,  0x05,  0x04,  0x09,  0x04,  0x09,  0x04,  0x11,  0xFC,  0x10, 	/* 250A0 */
+	0x00,  0x31,  0x24,  0x51,  0x24,  0x11,  0x24,  0x11,  0x24,  0x11,  0x24,  0x11,  0x24,  0x12,  0x25,  0x12, 	/* 250B0 */
+	0x25,  0x14,  0x03,  0x86,  0x00,  0x80,  0x00,  0x80,  0x7F,  0xFF,  0x08,  0x88,  0x08,  0x88,  0x0C,  0x8C, 	/* 250C0 */
+	0x14,  0x94,  0x12,  0x92,  0x20,  0xA0,  0x01,  0xC0,  0x02,  0xA0,  0x04,  0x90,  0x18,  0x8C,  0x60,  0x83, 	/* 250D0 */
+	0x00,  0x80,  0x00,  0x80,  0x88,  0x04,  0x40,  0x04,  0x40,  0x04,  0x78,  0x08,  0x88,  0x09,  0x90,  0x16, 	/* 250E0 */
+	0x50,  0x10,  0x20,  0x30,  0x50,  0x51,  0x9E,  0x16,  0x22,  0x10,  0x64,  0x11,  0x94,  0x10,  0x08,  0x10, 	/* 250F0 */
+	0x10,  0x10,  0x60,  0x13,  0x80,  0x8B,  0x08,  0x02,  0x0F,  0xF2,  0x09,  0x12,  0x11,  0x12,  0x11,  0x12, 	/* 25100 */
+	0x11,  0xD2,  0x32,  0x52,  0x32,  0x52,  0x53,  0x52,  0x14,  0xD2,  0x18,  0x92,  0x10,  0x82,  0x11,  0x02, 	/* 25110 */
+	0x11,  0x02,  0x12,  0x02,  0x14,  0x06,  0x8D,  0x04,  0x20,  0x04,  0x20,  0x05,  0xFE,  0x08,  0x20,  0x08, 	/* 25120 */
+	0x20,  0x10,  0x20,  0x17,  0xFF,  0x30,  0x08,  0x50,  0x08,  0x13,  0xFE,  0x11,  0x08,  0x10,  0x88,  0x10, 	/* 25130 */
+	0x88,  0x10,  0x88,  0x10,  0x08,  0x10,  0x18,  0x8F,  0x04,  0x20,  0x04,  0xA0,  0x04,  0xA0,  0x08,  0xFE, 	/* 25140 */
+	0x09,  0x20,  0x12,  0x20,  0x10,  0x20,  0x33,  0xFF,  0x50,  0x70,  0x10,  0x70,  0x10,  0xA8,  0x11,  0x28, 	/* 25150 */
+	0x12,  0x24,  0x14,  0x22,  0x10,  0x21,  0x10,  0x20,  0x91,  0x04,  0x40,  0x04,  0x40,  0x07,  0xFF,  0x08, 	/* 25160 */
+	0x40,  0x08,  0x80,  0x10,  0xFC,  0x11,  0x84,  0x31,  0x84,  0x52,  0xFC,  0x14,  0x84,  0x10,  0x84,  0x10, 	/* 25170 */
+	0xFC,  0x10,  0x84,  0x10,  0x84,  0x10,  0x84,  0x10,  0x8C,  0x96,  0x00,  0x80,  0x00,  0x80,  0x01,  0x40, 	/* 25180 */
+	0x02,  0x30,  0x0C,  0x0C,  0x37,  0xFB,  0x00,  0x00,  0x00,  0x00,  0x0F,  0xFC,  0x09,  0x24,  0x09,  0x24, 	/* 25190 */
+	0x0F,  0xFC,  0x09,  0x24,  0x09,  0x24,  0x09,  0x24,  0x09,  0x2C,  0x98,  0x04,  0x20,  0x04,  0x20,  0x07, 	/* 251A0 */
+	0xFE,  0x0A,  0x02,  0x0A,  0x0A,  0x10,  0x30,  0x13,  0xC0,  0x30,  0x40,  0x50,  0x40,  0x10,  0x7F,  0x17, 	/* 251B0 */
+	0xC0,  0x10,  0x40,  0x10,  0x40,  0x10,  0x42,  0x10,  0x22,  0x10,  0x1E,  0x9B,  0x04,  0x88,  0x04,  0x88, 	/* 251C0 */
+	0x04,  0x88,  0x08,  0x88,  0x0B,  0xFE,  0x18,  0x88,  0x18,  0x88,  0x28,  0x88,  0x48,  0x88,  0x0F,  0xFF, 	/* 251D0 */
+	0x08,  0x00,  0x08,  0x88,  0x08,  0x84,  0x09,  0x04,  0x0A,  0x02,  0x0C,  0x02,  0x9D,  0x04,  0x20,  0x04, 	/* 251E0 */
+	0x20,  0x04,  0x20,  0x0F,  0xFF,  0x08,  0xC0,  0x10,  0xA2,  0x10,  0xA2,  0x31,  0x24,  0x53,  0x24,  0x15, 	/* 251F0 */
+	0x18,  0x19,  0x10,  0x11,  0x08,  0x11,  0x08,  0x11,  0x64,  0x11,  0x82,  0x16,  0x01,  0xA0,  0x04,  0x40, 	/* 25200 */
+	0x04,  0x40,  0x07,  0xFE,  0x08,  0x40,  0x0A,  0x48,  0x11,  0x48,  0x11,  0x48,  0x31,  0x50,  0x50,  0x40, 	/* 25210 */
+	0x1F,  0xFF,  0x10,  0x60,  0x10,  0xA0,  0x10,  0x90,  0x11,  0x08,  0x12,  0x04,  0x1C,  0x02,  0xA1,  0x04, 	/* 25220 */
+	0x00,  0x04,  0x00,  0x07,  0xFF,  0x08,  0x50,  0x08,  0x50,  0x10,  0x50,  0x13,  0xFE,  0x32,  0x52,  0x52, 	/* 25230 */
+	0x52,  0x12,  0x52,  0x12,  0x52,  0x12,  0x52,  0x12,  0x52,  0x12,  0x52,  0x13,  0xFE,  0x10,  0x00,  0xAB, 	/* 25240 */
+	0x04,  0x20,  0x04,  0x20,  0x05,  0xFF,  0x05,  0x00,  0x09,  0x00,  0x10,  0xFE,  0x10,  0x40,  0x30,  0x40, 	/* 25250 */
+	0x57,  0xFF,  0x10,  0x88,  0x10,  0x88,  0x11,  0x10,  0x13,  0xF0,  0x10,  0x28,  0x10,  0xC4,  0x17,  0x02, 	/* 25260 */
+	0xAD,  0x04,  0x00,  0x05,  0xFC,  0x05,  0x04,  0x09,  0x04,  0x09,  0x04,  0x11,  0xFC,  0x11,  0x10,  0x31, 	/* 25270 */
+	0x10,  0x52,  0x08,  0x12,  0xC4,  0x14,  0x22,  0x18,  0x11,  0x11,  0x80,  0x10,  0x60,  0x10,  0x10,  0x10, 	/* 25280 */
+	0x08,  0xAE,  0x04,  0x80,  0x04,  0x80,  0x04,  0xFF,  0x09,  0x00,  0x09,  0x00,  0x12,  0xFC,  0x14,  0xA4, 	/* 25290 */
+	0x30,  0xA4,  0x57,  0xFF,  0x11,  0x24,  0x11,  0x24,  0x11,  0x24,  0x13,  0xFF,  0x12,  0x04,  0x10,  0x08, 	/* 252A0 */
+	0x10,  0x30,  0xAF,  0x04,  0x00,  0x05,  0xF8,  0x04,  0x08,  0x08,  0x08,  0x0F,  0xFF,  0x10,  0x80,  0x10, 	/* 252B0 */
+	0x80,  0x30,  0xFC,  0x51,  0x20,  0x12,  0x20,  0x17,  0xFF,  0x10,  0x20,  0x10,  0x50,  0x10,  0x88,  0x11, 	/* 252C0 */
+	0x04,  0x16,  0x03,  0xB5,  0x04,  0x00,  0x05,  0xFC,  0x04,  0x04,  0x08,  0xFC,  0x08,  0x04,  0x11,  0xFC, 	/* 252D0 */
+	0x10,  0x00,  0x37,  0xFF,  0x54,  0x01,  0x17,  0xF9,  0x10,  0x88,  0x10,  0x50,  0x10,  0x20,  0x10,  0x50, 	/* 252E0 */
+	0x11,  0x8C,  0x16,  0x03,  0xB6,  0x04,  0x00,  0x05,  0xFC,  0x05,  0x04,  0x09,  0x04,  0x09,  0x04,  0x11, 	/* 252F0 */
+	0xFC,  0x10,  0x20,  0x30,  0x20,  0x50,  0x40,  0x13,  0xFE,  0x12,  0x02,  0x12,  0x02,  0x12,  0x02,  0x12, 	/* 25300 */
+	0x02,  0x13,  0xFE,  0x10,  0x00,  0xBF,  0x04,  0x00,  0x07,  0xFF,  0x04,  0x20,  0x09,  0xFE,  0x09,  0x22, 	/* 25310 */
+	0x19,  0x22,  0x19,  0xFE,  0x29,  0x22,  0x49,  0x22,  0x09,  0xFE,  0x08,  0xA0,  0x08,  0x40,  0x08,  0x60, 	/* 25320 */
+	0x08,  0x90,  0x0B,  0x0C,  0x0C,  0x03,  0x82,  0x04,  0x06,  0x04,  0x38,  0x07,  0xC0,  0x08,  0x48,  0x08, 	/* 25330 */
+	0x88,  0x13,  0x10,  0x10,  0xA0,  0x30,  0x48,  0x50,  0x84,  0x17,  0xFE,  0x10,  0x22,  0x11,  0x28,  0x11, 	/* 25340 */
+	0x24,  0x12,  0x22,  0x14,  0x22,  0x10,  0x20,  0x83,  0x04,  0x00,  0x05,  0xFE,  0x05,  0x02,  0x09,  0x02, 	/* 25350 */
+	0x09,  0x02,  0x11,  0x02,  0x11,  0xFE,  0x30,  0x20,  0x50,  0x20,  0x11,  0x20,  0x11,  0x3E,  0x11,  0x20, 	/* 25360 */
+	0x12,  0xA0,  0x12,  0x60,  0x14,  0x30,  0x18,  0x0F,  0x84,  0x04,  0x50,  0x04,  0x94,  0x07,  0x12,  0x09, 	/* 25370 */
+	0x12,  0x09,  0x10,  0x1F,  0xFF,  0x11,  0x10,  0x31,  0x12,  0x51,  0x52,  0x11,  0x94,  0x17,  0x08,  0x11, 	/* 25380 */
+	0x1A,  0x11,  0x2A,  0x11,  0x46,  0x11,  0x86,  0x13,  0x02,  0x8A,  0x04,  0x40,  0x04,  0x50,  0x04,  0x8C, 	/* 25390 */
+	0x0B,  0xFA,  0x08,  0x90,  0x10,  0x91,  0x11,  0x0F,  0x32,  0x80,  0x54,  0xF8,  0x10,  0x88,  0x11,  0x88, 	/* 253A0 */
+	0x12,  0x50,  0x14,  0x20,  0x10,  0x50,  0x11,  0x8C,  0x16,  0x03,  0x8E,  0x08,  0x00,  0x08,  0x7C,  0x08, 	/* 253B0 */
+	0x44,  0x14,  0x44,  0x12,  0x44,  0x21,  0x7C,  0x40,  0x44,  0x08,  0x44,  0x08,  0x44,  0x08,  0x7C,  0x14, 	/* 253C0 */
+	0x44,  0x12,  0x44,  0x21,  0x44,  0x40,  0x44,  0x03,  0xFF,  0x00,  0x00,  0x90,  0x08,  0x42,  0x09,  0x92, 	/* 253D0 */
+	0x0F,  0x12,  0x11,  0x12,  0x11,  0x12,  0x1F,  0xD2,  0x31,  0x12,  0x31,  0x12,  0x53,  0x92,  0x13,  0x52, 	/* 253E0 */
+	0x15,  0x52,  0x15,  0x12,  0x19,  0x02,  0x11,  0x02,  0x11,  0x02,  0x11,  0x06,  0x91,  0x04,  0x00,  0x07, 	/* 253F0 */
+	0xFC,  0x04,  0x08,  0x08,  0xD0,  0x08,  0x20,  0x13,  0xFE,  0x12,  0x22,  0x32,  0x22,  0x53,  0xFE,  0x12, 	/* 25400 */
+	0x22,  0x12,  0x22,  0x13,  0xFE,  0x12,  0x22,  0x12,  0x22,  0x12,  0x22,  0x12,  0x26,  0x94,  0x04,  0x00, 	/* 25410 */
+	0x05,  0xFC,  0x05,  0x04,  0x09,  0x04,  0x09,  0xFC,  0x11,  0x04,  0x11,  0xFC,  0x31,  0x04,  0x51,  0x04, 	/* 25420 */
+	0x11,  0xFC,  0x10,  0x50,  0x10,  0x50,  0x10,  0x90,  0x11,  0x11,  0x12,  0x11,  0x1C,  0x0F,  0x97,  0x04, 	/* 25430 */
+	0x88,  0x04,  0x84,  0x04,  0x84,  0x09,  0x22,  0x0A,  0x22,  0x10,  0x50,  0x10,  0x50,  0x30,  0x88,  0x51, 	/* 25440 */
+	0x04,  0x13,  0xFE,  0x15,  0x05,  0x11,  0x04,  0x11,  0x04,  0x11,  0x04,  0x11,  0xFC,  0x10,  0x00,  0x98, 	/* 25450 */
+	0x04,  0x04,  0x04,  0x38,  0x07,  0xC4,  0x09,  0x22,  0x09,  0x22,  0x12,  0x01,  0x15,  0xFD,  0x30,  0x08, 	/* 25460 */
+	0x50,  0x10,  0x10,  0x20,  0x17,  0xFF,  0x10,  0x20,  0x10,  0x20,  0x10,  0x20,  0x10,  0x20,  0x10,  0x60, 	/* 25470 */
+	0x9A,  0x04,  0x00,  0x05,  0xFC,  0x05,  0x24,  0x09,  0x24,  0x09,  0xFC,  0x11,  0x24,  0x11,  0x24,  0x31, 	/* 25480 */
+	0xFC,  0x50,  0x20,  0x10,  0x20,  0x13,  0xFE,  0x10,  0x20,  0x10,  0x20,  0x10,  0x20,  0x17,  0xFF,  0x10, 	/* 25490 */
+	0x00,  0x9B,  0x04,  0x40,  0x04,  0x78,  0x04,  0x88,  0x09,  0x10,  0x09,  0x20,  0x13,  0xFE,  0x15,  0x22, 	/* 254A0 */
+	0x31,  0x22,  0x51,  0x42,  0x11,  0xFE,  0x10,  0x50,  0x10,  0x50,  0x10,  0x90,  0x11,  0x11,  0x12,  0x11, 	/* 254B0 */
+	0x1C,  0x0F,  0x9D,  0x04,  0x00,  0x05,  0xFC,  0x05,  0x04,  0x09,  0x04,  0x09,  0x04,  0x11,  0xFC,  0x10, 	/* 254C0 */
+	0x20,  0x30,  0x20,  0x57,  0xFF,  0x10,  0x70,  0x10,  0xA8,  0x11,  0x24,  0x12,  0x22,  0x14,  0x21,  0x10, 	/* 254D0 */
+	0x20,  0x10,  0x20,  0x9F,  0x04,  0x40,  0x04,  0x50,  0x04,  0x4C,  0x08,  0x9A,  0x0B,  0xE1,  0x10,  0x80, 	/* 254E0 */
+	0x10,  0x80,  0x31,  0xFE,  0x51,  0x20,  0x12,  0x20,  0x17,  0xFF,  0x10,  0x50,  0x10,  0x48,  0x10,  0x84, 	/* 254F0 */
+	0x13,  0x02,  0x1C,  0x01,  0xA1,  0x08,  0x00,  0x09,  0xF8,  0x08,  0x00,  0x0F,  0xFF,  0x10,  0x00,  0x13, 	/* 25500 */
+	0xFC,  0x30,  0x00,  0x30,  0x00,  0x53,  0xFC,  0x10,  0x00,  0x13,  0xFC,  0x12,  0x04,  0x12,  0x04,  0x12, 	/* 25510 */
+	0x04,  0x13,  0xFC,  0x10,  0x00,  0xA3,  0x04,  0x00,  0x05,  0xFC,  0x05,  0x04,  0x09,  0x04,  0x09,  0x04, 	/* 25520 */
+	0x11,  0xFC,  0x10,  0x00,  0x33,  0xFE,  0x50,  0x20,  0x10,  0x20,  0x17,  0xFF,  0x10,  0x50,  0x10,  0x48, 	/* 25530 */
+	0x10,  0x84,  0x11,  0x02,  0x12,  0x01,  0xA4,  0x05,  0x08,  0x04,  0x88,  0x04,  0x90,  0x0F,  0xFE,  0x08, 	/* 25540 */
+	0x22,  0x10,  0x22,  0x13,  0xFE,  0x32,  0x20,  0x52,  0x20,  0x13,  0xFE,  0x10,  0x62,  0x10,  0xA2,  0x11, 	/* 25550 */
+	0x22,  0x12,  0x22,  0x14,  0x2C,  0x10,  0x20,  0xA5,  0x04,  0x20,  0x04,  0x20,  0x07,  0xFF,  0x08,  0x20, 	/* 25560 */
+	0x09,  0xFC,  0x11,  0x24,  0x11,  0x24,  0x31,  0xFC,  0x51,  0x24,  0x11,  0x24,  0x11,  0xFC,  0x10,  0x20, 	/* 25570 */
+	0x17,  0xFF,  0x10,  0x20,  0x10,  0x20,  0x10,  0x20,  0xAE,  0x04,  0x40,  0x04,  0x40,  0x04,  0x7F,  0x08, 	/* 25580 */
+	0x88,  0x09,  0x88,  0x16,  0x50,  0x14,  0x30,  0x34,  0xCC,  0x57,  0x13,  0x14,  0x64,  0x15,  0x98,  0x14, 	/* 25590 */
+	0x62,  0x15,  0x84,  0x14,  0x18,  0x10,  0x60,  0x13,  0x80,  0xAF,  0x04,  0x20,  0x04,  0x20,  0x07,  0xFF, 	/* 255A0 */
+	0x0A,  0x00,  0x0A,  0x44,  0x12,  0x44,  0x12,  0x7F,  0x32,  0x84,  0x52,  0xA4,  0x13,  0x94,  0x12,  0x94, 	/* 255B0 */
+	0x12,  0x84,  0x14,  0x84,  0x14,  0x84,  0x18,  0x84,  0x10,  0x8C,  0xB3,  0x04,  0x90,  0x04,  0x90,  0x04, 	/* 255C0 */
+	0x90,  0x0F,  0x9E,  0x08,  0x90,  0x10,  0x90,  0x10,  0x90,  0x37,  0x9E,  0x50,  0x90,  0x10,  0x90,  0x13, 	/* 255D0 */
+	0x90,  0x1C,  0x9F,  0x11,  0x10,  0x11,  0x10,  0x12,  0x10,  0x14,  0x10,  0xB5,  0x04,  0x20,  0x04,  0x20, 	/* 255E0 */
+	0x07,  0xFE,  0x08,  0x20,  0x0B,  0xFE,  0x10,  0x20,  0x10,  0x20,  0x37,  0xFF,  0x50,  0xA0,  0x11,  0x24, 	/* 255F0 */
+	0x13,  0x14,  0x15,  0x18,  0x11,  0x08,  0x11,  0x04,  0x11,  0xC2,  0x16,  0x01,  0xB6,  0x09,  0x00,  0x09, 	/* 25600 */
+	0x3E,  0x09,  0x02,  0x19,  0xE2,  0x11,  0x12,  0x31,  0x12,  0x3F,  0xF4,  0x51,  0x14,  0x11,  0x14,  0x15, 	/* 25610 */
+	0x88,  0x15,  0x48,  0x15,  0x4C,  0x19,  0x14,  0x11,  0x22,  0x13,  0x42,  0x10,  0x81,  0xB8,  0x04,  0x20, 	/* 25620 */
+	0x04,  0x20,  0x07,  0xFE,  0x08,  0x20,  0x09,  0xFE,  0x10,  0x50,  0x17,  0xFF,  0x30,  0x88,  0x51,  0x24, 	/* 25630 */
+	0x16,  0x23,  0x11,  0xFC,  0x10,  0x20,  0x17,  0xFF,  0x10,  0x20,  0x10,  0x20,  0x10,  0x20,  0xBA,  0x04, 	/* 25640 */
+	0x40,  0x04,  0x40,  0x07,  0xFF,  0x08,  0xA0,  0x08,  0xD0,  0x11,  0x48,  0x13,  0xFC,  0x36,  0x4A,  0x5A, 	/* 25650 */
+	0x49,  0x13,  0xF8,  0x12,  0x48,  0x12,  0x48,  0x13,  0xF8,  0x10,  0x42,  0x10,  0x42,  0x10,  0x3E,  0xBE, 	/* 25660 */
+	0x04,  0x20,  0x04,  0x40,  0x07,  0xFC,  0x0A,  0x24,  0x0A,  0x24,  0x13,  0xFC,  0x12,  0x24,  0x32,  0x24, 	/* 25670 */
+	0x53,  0xFC,  0x10,  0x90,  0x11,  0x10,  0x17,  0xFF,  0x10,  0x10,  0x10,  0x10,  0x10,  0x10,  0x10,  0x10, 	/* 25680 */
+	0x85,  0x04,  0x20,  0x04,  0x20,  0x07,  0xFF,  0x09,  0x08,  0x09,  0x08,  0x11,  0x8C,  0x12,  0x52,  0x34, 	/* 25690 */
+	0x20,  0x50,  0x20,  0x17,  0xFF,  0x10,  0x20,  0x10,  0x20,  0x10,  0x20,  0x10,  0x20,  0x10,  0x20,  0x10, 	/* 256A0 */
+	0x20,  0x86,  0x08,  0x00,  0x0F,  0xFF,  0x08,  0x20,  0x08,  0x20,  0x13,  0xFE,  0x12,  0x22,  0x32,  0x22, 	/* 256B0 */
+	0x33,  0xFE,  0x52,  0x66,  0x12,  0xAA,  0x12,  0xAA,  0x13,  0x76,  0x12,  0x22,  0x12,  0x22,  0x12,  0x22, 	/* 256C0 */
+	0x12,  0x26,  0x89,  0x00,  0x80,  0x00,  0x80,  0x01,  0x40,  0x02,  0x20,  0x07,  0xF0,  0x18,  0x0C,  0x67, 	/* 256D0 */
+	0xF3,  0x04,  0x10,  0x07,  0xF0,  0x04,  0x10,  0x07,  0xF0,  0x08,  0x00,  0x0F,  0xF8,  0x14,  0x08,  0x27, 	/* 256E0 */
+	0xF8,  0x00,  0x00,  0x8B,  0x04,  0x00,  0x07,  0xFE,  0x06,  0x22,  0x0A,  0x22,  0x0A,  0x22,  0x13,  0xFE, 	/* 256F0 */
+	0x12,  0x22,  0x32,  0x22,  0x52,  0xFA,  0x12,  0x8A,  0x12,  0x8A,  0x12,  0xFA,  0x12,  0x02,  0x12,  0x02, 	/* 25700 */
+	0x13,  0xFE,  0x10,  0x00,  0x8D,  0x04,  0x20,  0x04,  0x20,  0x07,  0xFE,  0x09,  0x04,  0x08,  0x84,  0x10, 	/* 25710 */
+	0x88,  0x10,  0x88,  0x37,  0xFF,  0x50,  0x00,  0x10,  0x00,  0x11,  0xFC,  0x11,  0x04,  0x11,  0x04,  0x11, 	/* 25720 */
+	0x04,  0x11,  0xFC,  0x10,  0x00,  0x8F,  0x04,  0x20,  0x04,  0x3C,  0x04,  0x44,  0x08,  0x88,  0x09,  0x50, 	/* 25730 */
+	0x14,  0x30,  0x14,  0xCC,  0x37,  0x03,  0x54,  0x28,  0x14,  0x24,  0x14,  0x24,  0x17,  0xFF,  0x14,  0x30, 	/* 25740 */
+	0x10,  0x48,  0x11,  0x84,  0x16,  0x03,  0x91,  0x08,  0x00,  0x0B,  0xDE,  0x0A,  0x52,  0x0B,  0xDE,  0x12, 	/* 25750 */
+	0x52,  0x12,  0x52,  0x33,  0xDE,  0x32,  0x02,  0x52,  0x02,  0x12,  0x02,  0x12,  0x02,  0x12,  0x02,  0x12, 	/* 25760 */
+	0x02,  0x12,  0x02,  0x12,  0x02,  0x12,  0x06,  0x92,  0x08,  0x02,  0x0F,  0xFA,  0x09,  0x0A,  0x11,  0x4A, 	/* 25770 */
+	0x11,  0x2A,  0x12,  0x6A,  0x33,  0x9A,  0x3C,  0x9A,  0x50,  0x8A,  0x17,  0xEA,  0x10,  0x8A,  0x10,  0x8A, 	/* 25780 */
+	0x10,  0xB2,  0x11,  0xC2,  0x16,  0x02,  0x10,  0x06,  0x94,  0x04,  0x00,  0x07,  0xFE,  0x06,  0x02,  0x0A, 	/* 25790 */
+	0x02,  0x0B,  0xFE,  0x12,  0x10,  0x12,  0x92,  0x32,  0x92,  0x52,  0x92,  0x12,  0xFE,  0x12,  0x10,  0x12, 	/* 257A0 */
+	0x92,  0x14,  0x92,  0x14,  0x92,  0x18,  0xFE,  0x10,  0x00,  0x96,  0x04,  0x20,  0x04,  0x20,  0x05,  0xFE, 	/* 257B0 */
+	0x08,  0x20,  0x08,  0x20,  0x17,  0xFF,  0x11,  0x08,  0x30,  0x88,  0x50,  0x90,  0x17,  0xFE,  0x10,  0x20, 	/* 257C0 */
+	0x10,  0x20,  0x13,  0xFE,  0x10,  0x20,  0x10,  0x20,  0x10,  0x20,  0x99,  0x08,  0x00,  0x09,  0xF8,  0x08, 	/* 257D0 */
+	0x08,  0x14,  0x08,  0x17,  0xFF,  0x14,  0x80,  0x34,  0x80,  0x35,  0xFE,  0x55,  0x20,  0x16,  0x20,  0x17, 	/* 257E0 */
+	0xFF,  0x14,  0x30,  0x14,  0x50,  0x14,  0x88,  0x11,  0x04,  0x12,  0x03,  0x9A,  0x04,  0x20,  0x04,  0x20, 	/* 257F0 */
+	0x07,  0xFE,  0x08,  0x50,  0x08,  0x88,  0x13,  0x04,  0x10,  0x00,  0x37,  0xFF,  0x50,  0x04,  0x13,  0xE4, 	/* 25800 */
+	0x12,  0x24,  0x12,  0x24,  0x13,  0xE4,  0x10,  0x04,  0x10,  0x04,  0x10,  0x0C,  0x9F,  0x04,  0x88,  0x04, 	/* 25810 */
+	0x88,  0x04,  0x88,  0x0B,  0xFE,  0x08,  0x88,  0x10,  0x88,  0x17,  0xFF,  0x30,  0x00,  0x51,  0xFC,  0x11, 	/* 25820 */
+	0x04,  0x11,  0x04,  0x11,  0xFC,  0x11,  0x04,  0x11,  0x04,  0x11,  0xFC,  0x10,  0x00,  0xA1,  0x04,  0x00, 	/* 25830 */
+	0x05,  0xFC,  0x05,  0x04,  0x09,  0x04,  0x09,  0xFC,  0x11,  0x04,  0x11,  0x04,  0x31,  0xFC,  0x50,  0x00, 	/* 25840 */
+	0x13,  0xFE,  0x12,  0x02,  0x13,  0xFE,  0x12,  0x02,  0x12,  0x02,  0x13,  0xFE,  0x10,  0x00,  0xA3,  0x05, 	/* 25850 */
+	0x10,  0x05,  0x10,  0x05,  0x10,  0x0F,  0xFF,  0x0A,  0x12,  0x12,  0x12,  0x13,  0xE2,  0x32,  0x74,  0x52, 	/* 25860 */
+	0x54,  0x12,  0x54,  0x12,  0x48,  0x14,  0x58,  0x14,  0x54,  0x18,  0x64,  0x10,  0x42,  0x11,  0x81,  0xA4, 	/* 25870 */
+	0x04,  0x10,  0x04,  0x10,  0x07,  0xFF,  0x08,  0x10,  0x0A,  0xFC,  0x12,  0x84,  0x12,  0x84,  0x32,  0xFC, 	/* 25880 */
+	0x52,  0x84,  0x12,  0xFC,  0x12,  0x84,  0x12,  0x84,  0x12,  0xFC,  0x12,  0x00,  0x13,  0xFF,  0x10,  0x00, 	/* 25890 */
+	0xA5,  0x04,  0x20,  0x04,  0x20,  0x07,  0xFF,  0x0A,  0x51,  0x0A,  0x51,  0x12,  0x50,  0x10,  0x92,  0x31, 	/* 258A0 */
+	0x0E,  0x52,  0x00,  0x11,  0xFC,  0x10,  0x20,  0x10,  0x20,  0x10,  0x20,  0x10,  0x20,  0x17,  0xFF,  0x10, 	/* 258B0 */
+	0x00,  0xA6,  0x05,  0x24,  0x04,  0xA4,  0x04,  0xA8,  0x0F,  0xFE,  0x08,  0x50,  0x10,  0x50,  0x17,  0xFF, 	/* 258C0 */
+	0x30,  0x88,  0x51,  0x04,  0x12,  0xF2,  0x14,  0x11,  0x10,  0x10,  0x11,  0xF0,  0x11,  0x04,  0x11,  0x04, 	/* 258D0 */
+	0x10,  0xFC,  0xA8,  0x04,  0x00,  0x05,  0xFE,  0x05,  0x02,  0x09,  0x02,  0x09,  0xFE,  0x11,  0x10,  0x11, 	/* 258E0 */
+	0x10,  0x31,  0xFF,  0x51,  0x10,  0x11,  0x10,  0x12,  0xFE,  0x12,  0x82,  0x14,  0x82,  0x18,  0x82,  0x10, 	/* 258F0 */
+	0xFE,  0x10,  0x00,  0xA9,  0x04,  0x20,  0x04,  0x20,  0x07,  0xFE,  0x08,  0x20,  0x09,  0xFC,  0x10,  0x20, 	/* 25900 */
+	0x17,  0xFF,  0x30,  0x00,  0x51,  0xFC,  0x11,  0x24,  0x11,  0x24,  0x11,  0xFC,  0x11,  0x04,  0x11,  0x04, 	/* 25910 */
+	0x11,  0x04,  0x11,  0x0C,  0xAA,  0x04,  0x20,  0x04,  0x40,  0x07,  0x9C,  0x0A,  0x04,  0x0A,  0x04,  0x13, 	/* 25920 */
+	0xBC,  0x12,  0x04,  0x32,  0x04,  0x53,  0xFC,  0x10,  0x50,  0x10,  0x50,  0x10,  0x90,  0x10,  0x91,  0x11, 	/* 25930 */
+	0x11,  0x12,  0x11,  0x14,  0x0F,  0xAB,  0x04,  0x20,  0x04,  0x60,  0x04,  0x50,  0x08,  0x88,  0x09,  0x04, 	/* 25940 */
+	0x16,  0xFB,  0x10,  0x00,  0x30,  0x00,  0x53,  0xFE,  0x12,  0x52,  0x12,  0x52,  0x13,  0xFE,  0x12,  0x52, 	/* 25950 */
+	0x12,  0x52,  0x12,  0x52,  0x12,  0x56,  0xAC,  0x04,  0x20,  0x04,  0x20,  0x04,  0x3F,  0x08,  0x20,  0x09, 	/* 25960 */
+	0xFC,  0x11,  0x04,  0x11,  0x04,  0x31,  0xFC,  0x51,  0x04,  0x11,  0x04,  0x11,  0xFC,  0x10,  0x20,  0x17, 	/* 25970 */
+	0xFF,  0x10,  0x20,  0x10,  0x20,  0x10,  0x20,  0xAD,  0x04,  0x08,  0x04,  0x30,  0x05,  0xE0,  0x08,  0x20, 	/* 25980 */
+	0x0F,  0xFF,  0x10,  0x70,  0x11,  0xAC,  0x36,  0x23,  0x50,  0x60,  0x17,  0xFF,  0x10,  0x48,  0x10,  0x88, 	/* 25990 */
+	0x11,  0xD0,  0x10,  0x70,  0x11,  0x88,  0x16,  0x04,  0xB6,  0x04,  0x00,  0x05,  0xFC,  0x05,  0x04,  0x09, 	/* 259A0 */
+	0x04,  0x09,  0xFC,  0x11,  0x04,  0x11,  0x04,  0x31,  0xFC,  0x51,  0x04,  0x11,  0x04,  0x11,  0xFC,  0x10, 	/* 259B0 */
+	0x00,  0x17,  0xFF,  0x10,  0x98,  0x11,  0x04,  0x16,  0x02,  0xB9,  0x04,  0x20,  0x04,  0x20,  0x04,  0x50, 	/* 259C0 */
+	0x08,  0x88,  0x09,  0x04,  0x1B,  0xFE,  0x1C,  0x21,  0x29,  0xFC,  0x49,  0x24,  0x09,  0x24,  0x09,  0xFC, 	/* 259D0 */
+	0x08,  0x30,  0x08,  0x50,  0x08,  0x88,  0x09,  0x04,  0x0E,  0x03,  0x83,  0x08,  0x00,  0x0B,  0xFF,  0x0A, 	/* 259E0 */
+	0x00,  0x12,  0x7E,  0x12,  0x42,  0x32,  0x7E,  0x32,  0x42,  0x52,  0x7E,  0x12,  0x10,  0x13,  0xFF,  0x12, 	/* 259F0 */
+	0x24,  0x12,  0x78,  0x12,  0x14,  0x12,  0x62,  0x13,  0xFF,  0x12,  0x00,  0x87,  0x04,  0x00,  0x07,  0xDE, 	/* 25A00 */
+	0x06,  0x42,  0x0A,  0x42,  0x0A,  0x42,  0x13,  0xDE,  0x12,  0x00,  0x32,  0x7E,  0x53,  0xA4,  0x12,  0x24, 	/* 25A10 */
+	0x12,  0x14,  0x13,  0x98,  0x12,  0x08,  0x12,  0x14,  0x12,  0x22,  0x12,  0xC1,  0x88,  0x04,  0x00,  0x05, 	/* 25A20 */
+	0xFC,  0x05,  0x04,  0x09,  0xFC,  0x09,  0x04,  0x11,  0x04,  0x11,  0xFC,  0x30,  0x80,  0x51,  0xFE,  0x12, 	/* 25A30 */
+	0x22,  0x1D,  0x32,  0x11,  0x52,  0x11,  0x82,  0x11,  0xFA,  0x10,  0x02,  0x10,  0x1C,  0x89,  0x04,  0x20, 	/* 25A40 */
+	0x05,  0xFC,  0x04,  0x44,  0x08,  0x44,  0x0F,  0xFF,  0x10,  0x00,  0x11,  0xFC,  0x31,  0x04,  0x51,  0xFC, 	/* 25A50 */
+	0x10,  0x10,  0x11,  0xFE,  0x11,  0x10,  0x11,  0x10,  0x17,  0xFF,  0x10,  0x10,  0x10,  0x10,  0x8F,  0x04, 	/* 25A60 */
+	0x00,  0x07,  0xFE,  0x04,  0x00,  0x0B,  0xFC,  0x0A,  0x04,  0x12,  0x04,  0x13,  0xFC,  0x32,  0x00,  0x53, 	/* 25A70 */
+	0xFE,  0x12,  0x52,  0x16,  0x52,  0x17,  0xFE,  0x1A,  0x52,  0x12,  0x52,  0x12,  0x52,  0x12,  0x06,  0x90, 	/* 25A80 */
+	0x04,  0x20,  0x07,  0xFF,  0x04,  0x48,  0x08,  0x30,  0x08,  0xCC,  0x13,  0xFF,  0x12,  0x08,  0x32,  0x10, 	/* 25A90 */
+	0x52,  0x62,  0x13,  0x84,  0x12,  0x08,  0x12,  0x31,  0x14,  0xC2,  0x14,  0x0C,  0x18,  0x30,  0x11,  0xC0, 	/* 25AA0 */
+	0x95,  0x05,  0x10,  0x05,  0x32,  0x05,  0xDC,  0x09,  0x10,  0x09,  0x10,  0x11,  0x31,  0x11,  0xCF,  0x32, 	/* 25AB0 */
+	0x20,  0x50,  0x40,  0x11,  0xFC,  0x11,  0x04,  0x11,  0xFC,  0x11,  0x04,  0x11,  0x04,  0x11,  0xFC,  0x10, 	/* 25AC0 */
+	0x00,  0x96,  0x04,  0x40,  0x04,  0x44,  0x07,  0xFC,  0x08,  0x48,  0x08,  0x48,  0x10,  0x50,  0x17,  0xFF, 	/* 25AD0 */
+	0x30,  0x48,  0x50,  0x84,  0x10,  0xFC,  0x11,  0x84,  0x12,  0xFC,  0x14,  0x84,  0x10,  0x84,  0x10,  0xFC, 	/* 25AE0 */
+	0x10,  0x00,  0x9A,  0x09,  0x10,  0x09,  0x10,  0x09,  0x10,  0x0F,  0xDF,  0x11,  0x24,  0x11,  0x24,  0x31, 	/* 25AF0 */
+	0x44,  0x31,  0x14,  0x57,  0xD4,  0x14,  0x54,  0x14,  0x48,  0x14,  0x48,  0x17,  0xD4,  0x10,  0x24,  0x10, 	/* 25B00 */
+	0x42,  0x11,  0x81,  0x9C,  0x04,  0x20,  0x04,  0x20,  0x07,  0xFF,  0x08,  0x00,  0x09,  0xFC,  0x11,  0x04, 	/* 25B10 */
+	0x11,  0xFC,  0x30,  0x00,  0x17,  0xFF,  0x14,  0x01,  0x15,  0xFD,  0x10,  0x20,  0x10,  0x20,  0x10,  0x20, 	/* 25B20 */
+	0x10,  0x20,  0x10,  0x60,  0xA5,  0x08,  0x08,  0x0F,  0xBE,  0x08,  0x8A,  0x09,  0x0A,  0x11,  0x7F,  0x12, 	/* 25B30 */
+	0x0A,  0x37,  0x8A,  0x30,  0xBE,  0x52,  0x88,  0x12,  0xBE,  0x12,  0x88,  0x11,  0x7F,  0x11,  0x08,  0x12, 	/* 25B40 */
+	0x88,  0x14,  0x60,  0x18,  0x1F,  0xAC,  0x04,  0x80,  0x04,  0x80,  0x04,  0xFE,  0x09,  0x2A,  0x09,  0x2A, 	/* 25B50 */
+	0x12,  0xEA,  0x14,  0x5A,  0x30,  0x96,  0x51,  0x22,  0x10,  0x0C,  0x12,  0xA0,  0x12,  0x92,  0x12,  0x91, 	/* 25B60 */
+	0x14,  0x85,  0x18,  0x45,  0x10,  0x3C,  0xB2,  0x04,  0x00,  0x05,  0xFE,  0x05,  0x22,  0x09,  0x22,  0x09, 	/* 25B70 */
+	0xFE,  0x11,  0x22,  0x11,  0x22,  0x31,  0x22,  0x51,  0xFE,  0x10,  0x20,  0x10,  0x90,  0x12,  0x92,  0x12, 	/* 25B80 */
+	0x81,  0x12,  0x85,  0x14,  0x84,  0x10,  0x7C,  0xB4,  0x08,  0x02,  0x0F,  0xD2,  0x0C,  0x52,  0x14,  0x52, 	/* 25B90 */
+	0x17,  0xD2,  0x34,  0x52,  0x34,  0x52,  0x54,  0x52,  0x17,  0xD2,  0x14,  0x52,  0x14,  0x52,  0x17,  0xD2, 	/* 25BA0 */
+	0x12,  0x82,  0x12,  0x42,  0x14,  0x42,  0x18,  0x06,  0xB5,  0x04,  0x20,  0x04,  0x20,  0x04,  0x3F,  0x08, 	/* 25BB0 */
+	0x20,  0x09,  0xFC,  0x19,  0x04,  0x19,  0x04,  0x29,  0xFC,  0x49,  0x04,  0x09,  0xFC,  0x09,  0x04,  0x09, 	/* 25BC0 */
+	0x04,  0x09,  0xFC,  0x08,  0x98,  0x09,  0x04,  0x0E,  0x02,  0xB6,  0x04,  0x00,  0x07,  0xFC,  0x06,  0x24, 	/* 25BD0 */
+	0x0A,  0x24,  0x0B,  0xFC,  0x12,  0x24,  0x12,  0x24,  0x33,  0xFC,  0x50,  0x20,  0x17,  0xFE,  0x14,  0x32, 	/* 25BE0 */
+	0x14,  0x2A,  0x14,  0x36,  0x15,  0xC6,  0x14,  0x02,  0x14,  0x06,  0xB8,  0x04,  0xE0,  0x04,  0x20,  0x04, 	/* 25BF0 */
+	0x50,  0x08,  0x88,  0x0B,  0x04,  0x1D,  0xFB,  0x10,  0x00,  0x33,  0xD2,  0x52,  0x52,  0x13,  0x52,  0x12, 	/* 25C00 */
+	0xE4,  0x13,  0x64,  0x12,  0xE4,  0x12,  0x52,  0x12,  0x52,  0x12,  0xD2,  0xBD,  0x0A,  0x20,  0x09,  0x20, 	/* 25C10 */
+	0x09,  0x20,  0x0B,  0xF8,  0x10,  0x48,  0x10,  0x48,  0x10,  0xFC,  0x30,  0x84,  0x51,  0x04,  0x11,  0xFE, 	/* 25C20 */
+	0x12,  0x12,  0x15,  0x4A,  0x1A,  0xAA,  0x12,  0xA2,  0x14,  0x02,  0x10,  0x0C,  0x80,  0x04,  0x20,  0x04, 	/* 25C30 */
+	0x40,  0x07,  0xFC,  0x0A,  0x44,  0x0A,  0x44,  0x13,  0xFC,  0x12,  0x44,  0x32,  0x44,  0x53,  0xFC,  0x10, 	/* 25C40 */
+	0xA4,  0x10,  0xA4,  0x11,  0x2A,  0x11,  0x3E,  0x12,  0x21,  0x14,  0x11,  0x18,  0x0F,  0x85,  0x04,  0x24, 	/* 25C50 */
+	0x04,  0x22,  0x07,  0xFF,  0x08,  0x20,  0x0B,  0xFC,  0x12,  0x24,  0x13,  0xFC,  0x32,  0x24,  0x53,  0xFC, 	/* 25C60 */
+	0x12,  0x24,  0x10,  0x08,  0x17,  0xFF,  0x11,  0x08,  0x10,  0x88,  0x10,  0x88,  0x10,  0x18,  0x8D,  0x04, 	/* 25C70 */
+	0x20,  0x04,  0x20,  0x07,  0xFE,  0x08,  0x88,  0x08,  0x50,  0x13,  0xFE,  0x12,  0x02,  0x32,  0x22,  0x50, 	/* 25C80 */
+	0x20,  0x13,  0xFE,  0x10,  0x40,  0x10,  0x7C,  0x10,  0x44,  0x10,  0x84,  0x11,  0x04,  0x16,  0x18,  0x91, 	/* 25C90 */
+	0x05,  0x04,  0x05,  0xC4,  0x05,  0x7F,  0x0B,  0x54,  0x0A,  0xD4,  0x14,  0x94,  0x10,  0xBF,  0x31,  0x04, 	/* 25CA0 */
+	0x52,  0x24,  0x10,  0x20,  0x17,  0xFF,  0x10,  0x68,  0x10,  0xA4,  0x11,  0x22,  0x12,  0x21,  0x10,  0x20, 	/* 25CB0 */
+	0x98,  0x00,  0x80,  0x00,  0x80,  0x01,  0x40,  0x06,  0x30,  0x18,  0x8C,  0x68,  0x8B,  0x08,  0x88,  0x14, 	/* 25CC0 */
+	0x94,  0x2A,  0xAA,  0x08,  0x88,  0x14,  0x94,  0x22,  0xA2,  0x7F,  0xFF,  0x00,  0x80,  0x00,  0x80,  0x00, 	/* 25CD0 */
+	0x80,  0x99,  0x04,  0x88,  0x04,  0x88,  0x07,  0xFE,  0x08,  0x88,  0x08,  0x88,  0x13,  0xFF,  0x12,  0x00, 	/* 25CE0 */
+	0x32,  0xFE,  0x52,  0x92,  0x12,  0xFE,  0x12,  0x92,  0x12,  0x92,  0x14,  0xFE,  0x14,  0x92,  0x18,  0x92, 	/* 25CF0 */
+	0x10,  0x86,  0x9A,  0x09,  0x10,  0x09,  0x10,  0x09,  0x10,  0x1F,  0xDF,  0x10,  0x14,  0x12,  0xA4,  0x32, 	/* 25D00 */
+	0xA4,  0x34,  0x54,  0x5A,  0xB4,  0x12,  0x94,  0x11,  0x08,  0x11,  0x88,  0x12,  0x4C,  0x12,  0x14,  0x14, 	/* 25D10 */
+	0x22,  0x18,  0xC1,  0xAC,  0x04,  0x20,  0x05,  0x22,  0x05,  0x22,  0x09,  0xFE,  0x08,  0x88,  0x10,  0x90, 	/* 25D20 */
+	0x11,  0xFE,  0x31,  0x10,  0x53,  0x10,  0x15,  0xFE,  0x11,  0x10,  0x11,  0xFE,  0x11,  0x10,  0x11,  0x10, 	/* 25D30 */
+	0x11,  0xFF,  0x10,  0x00,  0xAD,  0x04,  0x20,  0x07,  0xFF,  0x06,  0x10,  0x0A,  0xFE,  0x0A,  0x12,  0x13, 	/* 25D40 */
+	0xFF,  0x12,  0x12,  0x32,  0xFE,  0x52,  0x10,  0x12,  0xFE,  0x12,  0x92,  0x14,  0xFE,  0x14,  0x92,  0x18, 	/* 25D50 */
+	0xFE,  0x10,  0x92,  0x10,  0x96,  0xB2,  0x09,  0x10,  0x09,  0x10,  0x0F,  0xD0,  0x09,  0x1F,  0x11,  0x14, 	/* 25D60 */
+	0x17,  0xE4,  0x31,  0x44,  0x31,  0x14,  0x5F,  0xF4,  0x11,  0x14,  0x11,  0xD8,  0x11,  0x48,  0x12,  0x54, 	/* 25D70 */
+	0x12,  0x54,  0x14,  0x62,  0x11,  0x81,  0xB3,  0x04,  0x20,  0x04,  0x20,  0x07,  0xFF,  0x08,  0x20,  0x0B, 	/* 25D80 */
+	0xFC,  0x12,  0x24,  0x13,  0xFC,  0x32,  0x24,  0x53,  0xFC,  0x10,  0x2E,  0x17,  0xF9,  0x10,  0x08,  0x17, 	/* 25D90 */
+	0xFE,  0x11,  0x08,  0x10,  0x88,  0x10,  0x18,  0xB4,  0x04,  0x00,  0x07,  0xFE,  0x06,  0x00,  0x0A,  0x78, 	/* 25DA0 */
+	0x0A,  0x48,  0x12,  0x48,  0x12,  0x78,  0x32,  0x00,  0x52,  0xEE,  0x12,  0xAA,  0x12,  0xAA,  0x12,  0xAA, 	/* 25DB0 */
+	0x12,  0xEE,  0x12,  0x00,  0x13,  0xFF,  0x10,  0x00,  0xB5,  0x04,  0x20,  0x07,  0xFE,  0x04,  0x20,  0x09, 	/* 25DC0 */
+	0xFC,  0x08,  0x20,  0x1F,  0xFF,  0x10,  0x00,  0x31,  0xFC,  0x51,  0x04,  0x11,  0xFC,  0x11,  0x04,  0x11, 	/* 25DD0 */
+	0xFC,  0x11,  0x04,  0x11,  0xFC,  0x10,  0x8C,  0x17,  0x03,  0xB7,  0x04,  0x80,  0x04,  0xFE,  0x05,  0x00, 	/* 25DE0 */
+	0x09,  0xF8,  0x0A,  0x88,  0x14,  0xF8,  0x10,  0x88,  0x30,  0xF8,  0x50,  0x00,  0x17,  0xFF,  0x10,  0x80, 	/* 25DF0 */
+	0x11,  0xFE,  0x16,  0x4A,  0x11,  0x92,  0x16,  0x22,  0x10,  0xCC,  0xBE,  0x08,  0x00,  0x09,  0xFF,  0x08, 	/* 25E00 */
+	0x10,  0x14,  0x20,  0x14,  0x7E,  0x15,  0x42,  0x36,  0x42,  0x54,  0x7E,  0x14,  0x42,  0x14,  0x7E,  0x15, 	/* 25E10 */
+	0x42,  0x15,  0x42,  0x13,  0x7E,  0x10,  0x14,  0x10,  0x22,  0x10,  0xC1,  0x82,  0x04,  0x20,  0x05,  0xFE, 	/* 25E20 */
+	0x05,  0x22,  0x0F,  0xFF,  0x09,  0x22,  0x11,  0xFE,  0x10,  0x20,  0x31,  0xFE,  0x51,  0x22,  0x11,  0xFE, 	/* 25E30 */
+	0x10,  0x20,  0x17,  0xFF,  0x10,  0x44,  0x10,  0xF8,  0x10,  0x34,  0x11,  0xC2,  0x85,  0x04,  0x88,  0x04, 	/* 25E40 */
+	0x88,  0x07,  0xFF,  0x08,  0x88,  0x0B,  0xFE,  0x12,  0x22,  0x12,  0x22,  0x33,  0xFE,  0x50,  0x20,  0x11, 	/* 25E50 */
+	0xFC,  0x10,  0x20,  0x11,  0xFC,  0x10,  0x20,  0x10,  0x20,  0x17,  0xFF,  0x10,  0x00,  0x89,  0x00,  0x80, 	/* 25E60 */
+	0x00,  0x80,  0x01,  0x40,  0x02,  0x20,  0x04,  0x10,  0x1B,  0xEC,  0x60,  0x03,  0x1F,  0x7C,  0x11,  0x44, 	/* 25E70 */
+	0x11,  0x44,  0x1F,  0x7C,  0x04,  0x10,  0x06,  0x18,  0x09,  0x24,  0x11,  0x42,  0x60,  0x80,  0x8A,  0x08, 	/* 25E80 */
+	0x00,  0x0F,  0xFF,  0x08,  0x90,  0x0B,  0xFC,  0x12,  0x94,  0x12,  0x94,  0x33,  0xFC,  0x30,  0x80,  0x57, 	/* 25E90 */
+	0xFF,  0x11,  0x08,  0x13,  0xF4,  0x15,  0x13,  0x19,  0xF0,  0x11,  0x04,  0x11,  0x04,  0x10,  0xFC,  0x8D, 	/* 25EA0 */
+	0x08,  0xC8,  0x0F,  0x08,  0x09,  0x08,  0x0F,  0xE8,  0x11,  0x1E,  0x17,  0xEA,  0x35,  0x2A,  0x37,  0xEA, 	/* 25EB0 */
+	0x55,  0x2A,  0x17,  0xEA,  0x11,  0x0A,  0x17,  0xCA,  0x11,  0x32,  0x11,  0xD2,  0x1E,  0x22,  0x10,  0x4C, 	/* 25EC0 */
+	0x8F,  0x04,  0x40,  0x04,  0x78,  0x04,  0x88,  0x0B,  0x10,  0x0D,  0xFE,  0x11,  0x22,  0x11,  0x22,  0x31, 	/* 25ED0 */
+	0xFE,  0x50,  0xC4,  0x17,  0x24,  0x10,  0xD8,  0x17,  0x38,  0x10,  0x54,  0x11,  0x92,  0x16,  0x11,  0x10, 	/* 25EE0 */
+	0x60,  0x91,  0x04,  0x0C,  0x05,  0xF0,  0x04,  0x40,  0x0F,  0xFF,  0x08,  0x88,  0x11,  0xFC,  0x16,  0x8B, 	/* 25EF0 */
+	0x30,  0xF8,  0x50,  0x00,  0x13,  0xFE,  0x12,  0x02,  0x12,  0xFA,  0x12,  0x8A,  0x12,  0xFA,  0x12,  0x02, 	/* 25F00 */
+	0x12,  0x06,  0x95,  0x04,  0x50,  0x06,  0x52,  0x05,  0x54,  0x08,  0x50,  0x0F,  0xFF,  0x11,  0x08,  0x10, 	/* 25F10 */
+	0x90,  0x37,  0xFE,  0x50,  0x20,  0x13,  0xFC,  0x10,  0x20,  0x17,  0xFF,  0x10,  0x50,  0x10,  0x88,  0x13, 	/* 25F20 */
+	0x04,  0x1C,  0x03,  0x96,  0x04,  0x20,  0x07,  0xFF,  0x04,  0x20,  0x0B,  0xFC,  0x08,  0x00,  0x13,  0xFC, 	/* 25F30 */
+	0x12,  0x04,  0x33,  0xFC,  0x51,  0x08,  0x10,  0x90,  0x1F,  0xFF,  0x10,  0x00,  0x13,  0xFC,  0x12,  0x04, 	/* 25F40 */
+	0x13,  0xFC,  0x10,  0x00,  0x9A,  0x04,  0x20,  0x04,  0x20,  0x07,  0xFF,  0x08,  0x50,  0x0A,  0x8A,  0x11, 	/* 25F50 */
+	0x04,  0x13,  0xFE,  0x35,  0x05,  0x51,  0xFC,  0x11,  0x04,  0x11,  0xFC,  0x10,  0x28,  0x11,  0x24,  0x12, 	/* 25F60 */
+	0x22,  0x14,  0x22,  0x10,  0x60,  0x9E,  0x08,  0x18,  0x0B,  0xE0,  0x09,  0x48,  0x0A,  0x44,  0x17,  0xF4, 	/* 25F70 */
+	0x12,  0x10,  0x32,  0x10,  0x33,  0xFC,  0x52,  0x04,  0x12,  0x04,  0x13,  0xFF,  0x14,  0x25,  0x14,  0x95, 	/* 25F80 */
+	0x1A,  0x51,  0x11,  0x42,  0x11,  0x0C,  0xA3,  0x09,  0x08,  0x09,  0x08,  0x0F,  0xDE,  0x09,  0x08,  0x17, 	/* 25F90 */
+	0xFF,  0x11,  0x08,  0x32,  0x8C,  0x32,  0x52,  0x54,  0x21,  0x19,  0xFC,  0x11,  0x04,  0x11,  0xFC,  0x11, 	/* 25FA0 */
+	0x04,  0x11,  0x04,  0x11,  0xFC,  0x10,  0x00,  0xA5,  0x04,  0x20,  0x05,  0xFC,  0x04,  0x20,  0x0B,  0xFE, 	/* 25FB0 */
+	0x08,  0x00,  0x11,  0x04,  0x17,  0xDF,  0x31,  0x04,  0x51,  0xC4,  0x16,  0x1F,  0x10,  0x00,  0x17,  0xFF, 	/* 25FC0 */
+	0x10,  0x50,  0x10,  0x91,  0x13,  0x11,  0x1C,  0x0F,  0xA7,  0x05,  0x04,  0x04,  0x88,  0x07,  0xFE,  0x0A, 	/* 25FD0 */
+	0x22,  0x0B,  0xFE,  0x12,  0x22,  0x12,  0x22,  0x33,  0xFE,  0x50,  0x00,  0x11,  0xFC,  0x11,  0x04,  0x11, 	/* 25FE0 */
+	0xFC,  0x11,  0x04,  0x11,  0x04,  0x11,  0xFC,  0x10,  0x00,  0xAD,  0x08,  0x84,  0x0F,  0xDE,  0x0A,  0x94, 	/* 25FF0 */
+	0x0A,  0x94,  0x17,  0xFF,  0x11,  0xAC,  0x32,  0xCD,  0x32,  0x97,  0x54,  0x20,  0x11,  0xFC,  0x11,  0x04, 	/* 26000 */
+	0x11,  0xFC,  0x11,  0x04,  0x11,  0x04,  0x11,  0xFC,  0x10,  0x00,  0xAE,  0x04,  0x20,  0x04,  0x20,  0x07, 	/* 26010 */
+	0xFE,  0x08,  0x88,  0x0F,  0xFF,  0x10,  0x00,  0x11,  0xFC,  0x31,  0x24,  0x51,  0xFC,  0x11,  0x24,  0x11, 	/* 26020 */
+	0xFC,  0x10,  0x20,  0x13,  0xFE,  0x10,  0x20,  0x17,  0xFF,  0x10,  0x00,  0xB5,  0x04,  0x00,  0x07,  0xFF, 	/* 26030 */
+	0x04,  0x00,  0x09,  0xFC,  0x09,  0x24,  0x11,  0xFC,  0x11,  0x24,  0x37,  0xFF,  0x50,  0x00,  0x11,  0xFC, 	/* 26040 */
+	0x11,  0x24,  0x11,  0xFC,  0x11,  0x24,  0x11,  0xFC,  0x17,  0xFF,  0x10,  0x00,  0xB9,  0x04,  0x00,  0x07, 	/* 26050 */
+	0xFF,  0x04,  0x90,  0x0B,  0xFE,  0x0A,  0x92,  0x13,  0xFE,  0x10,  0x00,  0x31,  0xFC,  0x51,  0x04,  0x11, 	/* 26060 */
+	0xFC,  0x11,  0x04,  0x11,  0xFC,  0x11,  0x04,  0x11,  0xFC,  0x10,  0x8C,  0x13,  0x02,  0xBB,  0x08,  0x08, 	/* 26070 */
+	0x0B,  0xC8,  0x0A,  0x7F,  0x12,  0x42,  0x12,  0x62,  0x13,  0xD4,  0x32,  0x14,  0x32,  0x7F,  0x52,  0x08, 	/* 26080 */
+	0x17,  0xC8,  0x16,  0x7F,  0x1A,  0x48,  0x12,  0x48,  0x13,  0xC8,  0x12,  0x48,  0x12,  0x08,  0x80,  0x09, 	/* 26090 */
+	0x08,  0x08,  0x90,  0x1B,  0xFE,  0x10,  0x20,  0x11,  0xF8,  0x30,  0x20,  0x37,  0xFF,  0x50,  0x58,  0x13, 	/* 260A0 */
+	0x94,  0x11,  0x10,  0x17,  0xFF,  0x11,  0x12,  0x11,  0xCC,  0x17,  0x0A,  0x11,  0x16,  0x13,  0x62,  0x81, 	/* 260B0 */
+	0x04,  0x88,  0x04,  0x90,  0x05,  0xFF,  0x09,  0x10,  0x0B,  0xFE,  0x15,  0x10,  0x11,  0xFE,  0x31,  0x10, 	/* 260C0 */
+	0x51,  0xFF,  0x10,  0x00,  0x13,  0xDE,  0x12,  0x52,  0x12,  0x52,  0x12,  0x72,  0x12,  0x02,  0x12,  0x06, 	/* 260D0 */
+	0x82,  0x04,  0x50,  0x05,  0xFC,  0x05,  0x54,  0x09,  0xFC,  0x09,  0x54,  0x11,  0xFC,  0x10,  0x00,  0x33, 	/* 260E0 */
+	0xFF,  0x52,  0x00,  0x12,  0xFC,  0x12,  0x00,  0x13,  0xFF,  0x12,  0xA4,  0x14,  0x98,  0x18,  0xEC,  0x13, 	/* 260F0 */
+	0x03,  0x84,  0x04,  0x20,  0x04,  0x20,  0x07,  0xFE,  0x09,  0x04,  0x08,  0x88,  0x17,  0xFF,  0x10,  0x00, 	/* 26100 */
+	0x31,  0xFC,  0x51,  0x04,  0x11,  0xFC,  0x11,  0x04,  0x11,  0xFC,  0x12,  0xA2,  0x12,  0x91,  0x14,  0x85, 	/* 26110 */
+	0x10,  0x7C,  0x89,  0x04,  0x20,  0x04,  0x20,  0x04,  0x50,  0x08,  0x88,  0x09,  0x04,  0x16,  0xFB,  0x10, 	/* 26120 */
+	0x00,  0x33,  0xDE,  0x52,  0x52,  0x12,  0x52,  0x13,  0xDE,  0x11,  0x08,  0x11,  0x08,  0x11,  0x8C,  0x12, 	/* 26130 */
+	0x52,  0x14,  0x21,  0x92,  0x04,  0x00,  0x07,  0xFE,  0x04,  0x20,  0x0F,  0xFF,  0x0C,  0x21,  0x15,  0xAD, 	/* 26140 */
+	0x14,  0x21,  0x31,  0xAC,  0x50,  0x00,  0x17,  0xFE,  0x10,  0x20,  0x13,  0xFE,  0x12,  0x52,  0x12,  0x52, 	/* 26150 */
+	0x12,  0x52,  0x12,  0x06,  0x94,  0x04,  0x20,  0x07,  0xFE,  0x04,  0x20,  0x09,  0xFC,  0x08,  0x00,  0x17, 	/* 26160 */
+	0xFF,  0x10,  0x22,  0x33,  0xF8,  0x50,  0x00,  0x17,  0xFF,  0x10,  0x04,  0x17,  0xFF,  0x14,  0xA4,  0x14, 	/* 26170 */
+	0x94,  0x17,  0x84,  0x10,  0x0C,  0x95,  0x04,  0x20,  0x04,  0x20,  0x07,  0xFF,  0x08,  0x51,  0x0F,  0xAE, 	/* 26180 */
+	0x12,  0xAA,  0x12,  0xAA,  0x35,  0xAD,  0x50,  0x00,  0x11,  0x04,  0x11,  0xFC,  0x11,  0x04,  0x11,  0xFC, 	/* 26190 */
+	0x11,  0x04,  0x12,  0x04,  0x14,  0x04,  0x96,  0x08,  0x08,  0x0F,  0xC8,  0x0D,  0x08,  0x15,  0x1F,  0x17, 	/* 261A0 */
+	0xD0,  0x34,  0x60,  0x37,  0xDF,  0x55,  0x00,  0x17,  0xC0,  0x10,  0x00,  0x13,  0xFE,  0x12,  0x52,  0x12, 	/* 261B0 */
+	0x52,  0x12,  0x52,  0x1F,  0xFF,  0x10,  0x00,  0x98,  0x04,  0x20,  0x05,  0xFC,  0x04,  0x24,  0x0B,  0xFF, 	/* 261C0 */
+	0x08,  0x24,  0x11,  0xFC,  0x10,  0x20,  0x37,  0xFF,  0x52,  0xA4,  0x12,  0x52,  0x14,  0x02,  0x13,  0xFC, 	/* 261D0 */
+	0x12,  0x94,  0x12,  0x94,  0x1F,  0xFF,  0x10,  0x00,  0x9A,  0x04,  0x88,  0x04,  0x88,  0x07,  0xFF,  0x08, 	/* 261E0 */
+	0x88,  0x0B,  0xFE,  0x12,  0x52,  0x13,  0xFE,  0x30,  0x00,  0x57,  0xFF,  0x14,  0x21,  0x14,  0x7D,  0x10, 	/* 261F0 */
+	0xC4,  0x13,  0x28,  0x10,  0x10,  0x10,  0x60,  0x13,  0x80,  0x9F,  0x05,  0x24,  0x04,  0xA8,  0x07,  0xFE, 	/* 26200 */
+	0x0A,  0x02,  0x0A,  0xFA,  0x10,  0x88,  0x10,  0xF8,  0x31,  0xFC,  0x51,  0x04,  0x11,  0xFC,  0x11,  0x04, 	/* 26210 */
+	0x11,  0xFC,  0x11,  0x04,  0x11,  0xFC,  0x10,  0xCC,  0x13,  0x02,  0xA1,  0x04,  0x00,  0x05,  0xFC,  0x05, 	/* 26220 */
+	0x24,  0x09,  0xFC,  0x09,  0x24,  0x11,  0x24,  0x11,  0xFC,  0x30,  0x00,  0x57,  0xDF,  0x15,  0x55,  0x15, 	/* 26230 */
+	0x55,  0x17,  0xDF,  0x15,  0x55,  0x15,  0x55,  0x17,  0xDF,  0x10,  0x00,  0xAA,  0x04,  0x00,  0x07,  0xFF, 	/* 26240 */
+	0x04,  0x20,  0x09,  0xFC,  0x09,  0x04,  0x11,  0xFC,  0x11,  0x04,  0x37,  0xFF,  0x54,  0xA5,  0x12,  0x92, 	/* 26250 */
+	0x12,  0x7D,  0x14,  0x89,  0x13,  0x50,  0x10,  0x30,  0x10,  0xCC,  0x17,  0x03,  0xB2,  0x08,  0x08,  0x0B, 	/* 26260 */
+	0x88,  0x08,  0x3E,  0x1F,  0xCA,  0x10,  0x0C,  0x17,  0x8C,  0x30,  0x7F,  0x30,  0x10,  0x57,  0xBE,  0x10, 	/* 26270 */
+	0x62,  0x17,  0xA2,  0x14,  0xBE,  0x14,  0xA2,  0x14,  0xA2,  0x17,  0xBE,  0x10,  0x00,  0xB7,  0x0B,  0xDF, 	/* 26280 */
+	0x08,  0x00,  0x0F,  0xDF,  0x0C,  0x51,  0x15,  0x55,  0x10,  0x20,  0x33,  0xFF,  0x32,  0x50,  0x53,  0xFE, 	/* 26290 */
+	0x12,  0x52,  0x13,  0xFE,  0x13,  0x10,  0x15,  0xFE,  0x15,  0x10,  0x19,  0xD1,  0x13,  0x0F,  0xBA,  0x0A, 	/* 262A0 */
+	0x8A,  0x0F,  0xEA,  0x0A,  0x94,  0x0B,  0x9F,  0x11,  0x34,  0x17,  0xD4,  0x35,  0x54,  0x37,  0xDF,  0x51, 	/* 262B0 */
+	0x14,  0x17,  0xD4,  0x11,  0x1F,  0x17,  0xD4,  0x12,  0x94,  0x12,  0x54,  0x14,  0x5F,  0x18,  0x00,  0xBB, 	/* 262C0 */
+	0x05,  0x24,  0x04,  0xA8,  0x07,  0xFE,  0x0A,  0x8A,  0x0A,  0xFA,  0x10,  0x00,  0x11,  0xFC,  0x31,  0x2C, 	/* 262D0 */
+	0x51,  0xB4,  0x11,  0xFC,  0x10,  0x20,  0x13,  0xFE,  0x10,  0x20,  0x17,  0xFF,  0x12,  0x92,  0x14,  0x49, 	/* 262E0 */
+	0xBC,  0x08,  0x00,  0x0B,  0xDE,  0x0A,  0x52,  0x0B,  0xDE,  0x10,  0x00,  0x17,  0xFF,  0x34,  0x08,  0x37, 	/* 262F0 */
+	0xE8,  0x54,  0x8F,  0x17,  0xF2,  0x15,  0x4A,  0x15,  0xCA,  0x15,  0xC4,  0x15,  0x6C,  0x1B,  0xD2,  0x10, 	/* 26300 */
+	0x61,  0xBF,  0x02,  0x20,  0x02,  0x20,  0x02,  0x20,  0x02,  0x20,  0x02,  0x20,  0x02,  0x20,  0x02,  0x20, 	/* 26310 */
+	0x02,  0x20,  0x02,  0x20,  0x02,  0x20,  0x02,  0x20,  0x04,  0x21,  0x04,  0x21,  0x08,  0x11,  0x10,  0x0F, 	/* 26320 */
+	0x60,  0x00,  0x80,  0x00,  0x00,  0x7F,  0xFF,  0x02,  0x20,  0x02,  0x20,  0x02,  0x20,  0x02,  0x20,  0x02, 	/* 26330 */
+	0x20,  0x02,  0x20,  0x02,  0x20,  0x02,  0x20,  0x02,  0x20,  0x04,  0x20,  0x04,  0x21,  0x08,  0x11,  0x10, 	/* 26340 */
+	0x0F,  0x60,  0x00,  0x81,  0x01,  0x00,  0x01,  0x00,  0x01,  0x40,  0x02,  0x20,  0x02,  0x18,  0x04,  0xF4, 	/* 26350 */
+	0x7F,  0x42,  0x02,  0x40,  0x02,  0x40,  0x02,  0x40,  0x04,  0x40,  0x04,  0x40,  0x08,  0x40,  0x08,  0x42, 	/* 26360 */
+	0x10,  0x22,  0x20,  0x1E,  0x83,  0x00,  0x00,  0x0F,  0xF8,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00, 	/* 26370 */
+	0x00,  0x7F,  0xFF,  0x02,  0x20,  0x02,  0x20,  0x02,  0x20,  0x02,  0x20,  0x04,  0x20,  0x04,  0x20,  0x08, 	/* 26380 */
+	0x21,  0x10,  0x11,  0x20,  0x0F,  0x84,  0x00,  0x00,  0x0F,  0xF8,  0x08,  0x08,  0x08,  0x08,  0x08,  0x08, 	/* 26390 */
+	0x08,  0x08,  0x08,  0x08,  0x0F,  0xF8,  0x02,  0x40,  0x02,  0x40,  0x02,  0x40,  0x04,  0x40,  0x04,  0x42, 	/* 263A0 */
+	0x08,  0x42,  0x10,  0x22,  0x20,  0x1E,  0x85,  0x00,  0x80,  0x00,  0x80,  0x7F,  0xFF,  0x01,  0x00,  0x01, 	/* 263B0 */
+	0x20,  0x02,  0x18,  0x04,  0x74,  0x1F,  0xA2,  0x01,  0x20,  0x01,  0x20,  0x01,  0x20,  0x02,  0x20,  0x02, 	/* 263C0 */
+	0x22,  0x04,  0x22,  0x08,  0x22,  0x30,  0x1E,  0x86,  0x02,  0x40,  0x02,  0x40,  0x02,  0x44,  0x22,  0x44, 	/* 263D0 */
+	0x12,  0x48,  0x0A,  0x50,  0x02,  0x40,  0x02,  0x40,  0x06,  0x70,  0x1A,  0x4C,  0x62,  0x42,  0x04,  0x40, 	/* 263E0 */
+	0x04,  0x40,  0x08,  0x41,  0x10,  0x21,  0x60,  0x1F,  0x87,  0x00,  0x20,  0x10,  0x28,  0x16,  0x48,  0x11, 	/* 263F0 */
+	0x48,  0x10,  0x88,  0x11,  0x48,  0x12,  0x28,  0x1C,  0x28,  0x10,  0x08,  0x1F,  0xF8,  0x02,  0x40,  0x02, 	/* 26400 */
+	0x40,  0x04,  0x40,  0x08,  0x42,  0x10,  0x22,  0x60,  0x1E,  0x88,  0x00,  0x80,  0x04,  0x80,  0x04,  0x80, 	/* 26410 */
+	0x07,  0xFC,  0x08,  0x80,  0x08,  0x80,  0x10,  0x80,  0x7F,  0xFF,  0x01,  0x20,  0x01,  0x20,  0x01,  0x20, 	/* 26420 */
+	0x02,  0x20,  0x02,  0x20,  0x04,  0x21,  0x08,  0x11,  0x30,  0x0F,  0x89,  0x00,  0x80,  0x00,  0x80,  0x08, 	/* 26430 */
+	0x88,  0x04,  0x88,  0x04,  0x90,  0x04,  0xA0,  0x00,  0x80,  0x7F,  0xFF,  0x01,  0x20,  0x01,  0x20,  0x01, 	/* 26440 */
+	0x20,  0x02,  0x20,  0x02,  0x20,  0x04,  0x21,  0x08,  0x11,  0x30,  0x0F,  0x8B,  0x01,  0x00,  0x01,  0x00, 	/* 26450 */
+	0x7F,  0xFE,  0x01,  0x00,  0x01,  0x00,  0x1F,  0xF0,  0x10,  0x10,  0x10,  0x10,  0x10,  0x10,  0x1F,  0xF0, 	/* 26460 */
+	0x02,  0x40,  0x02,  0x40,  0x02,  0x40,  0x04,  0x42,  0x18,  0x22,  0x60,  0x1E,  0x8C,  0x01,  0xE0,  0x04, 	/* 26470 */
+	0x20,  0x04,  0x20,  0x08,  0x10,  0x0F,  0xF0,  0x18,  0x18,  0x28,  0x14,  0x48,  0x13,  0x08,  0x10,  0x0F, 	/* 26480 */
+	0xF0,  0x02,  0x40,  0x02,  0x40,  0x02,  0x40,  0x04,  0x41,  0x18,  0x21,  0x60,  0x1F,  0x8D,  0x01,  0x00, 	/* 26490 */
+	0x01,  0xE0,  0x02,  0x20,  0x04,  0x40,  0x08,  0x80,  0x3F,  0xFC,  0x08,  0x84,  0x08,  0x84,  0x08,  0x84, 	/* 264A0 */
+	0x0F,  0xFC,  0x01,  0x20,  0x01,  0x20,  0x02,  0x20,  0x04,  0x21,  0x18,  0x11,  0x60,  0x0F,  0x8E,  0x00, 	/* 264B0 */
+	0x08,  0x00,  0x30,  0x3F,  0xC0,  0x01,  0x00,  0x01,  0x00,  0x1F,  0xF8,  0x11,  0x08,  0x11,  0x08,  0x11, 	/* 264C0 */
+	0x08,  0x1F,  0xF8,  0x02,  0x50,  0x02,  0x48,  0x02,  0x48,  0x04,  0x42,  0x18,  0x42,  0x60,  0x3E,  0x90, 	/* 264D0 */
+	0x10,  0x00,  0x11,  0xFC,  0x11,  0x04,  0x11,  0x04,  0x11,  0x04,  0x11,  0xFC,  0x11,  0x04,  0x11,  0x04, 	/* 264E0 */
+	0x11,  0x04,  0x11,  0xFC,  0x12,  0x40,  0x02,  0x40,  0x02,  0x40,  0x04,  0x41,  0x18,  0x41,  0x60,  0x3F, 	/* 264F0 */
+	0x92,  0x01,  0x00,  0x02,  0x00,  0x1C,  0xFC,  0x10,  0x04,  0x10,  0x04,  0x1E,  0x7C,  0x10,  0x04,  0x10, 	/* 26500 */
+	0x04,  0x10,  0x04,  0x1F,  0xFC,  0x02,  0x40,  0x02,  0x40,  0x02,  0x41,  0x04,  0x41,  0x18,  0x21,  0x60, 	/* 26510 */
+	0x1F,  0x94,  0x01,  0x00,  0x01,  0xE0,  0x02,  0x20,  0x04,  0x40,  0x18,  0x80,  0x7F,  0xF8,  0x10,  0x88, 	/* 26520 */
+	0x10,  0x88,  0x11,  0x08,  0x1F,  0xF8,  0x01,  0x50,  0x02,  0x48,  0x02,  0x48,  0x04,  0x41,  0x18,  0x21, 	/* 26530 */
+	0x60,  0x1F,  0x9A,  0x00,  0x80,  0x08,  0x88,  0x04,  0x88,  0x04,  0x90,  0x7F,  0xFE,  0x40,  0x02,  0x4F, 	/* 26540 */
+	0xF2,  0x48,  0x12,  0x08,  0x10,  0x0F,  0xF0,  0x02,  0x40,  0x02,  0x40,  0x02,  0x42,  0x04,  0x42,  0x18, 	/* 26550 */
+	0x22,  0x60,  0x1E,  0x9C,  0x04,  0x80,  0x09,  0x00,  0x33,  0xDC,  0x22,  0x44,  0x22,  0x44,  0x23,  0xC4, 	/* 26560 */
+	0x22,  0x44,  0x22,  0x44,  0x3B,  0xDC,  0x00,  0x00,  0x02,  0x40,  0x02,  0x40,  0x02,  0x42,  0x04,  0x42, 	/* 26570 */
+	0x18,  0x42,  0x60,  0x3E,  0xA2,  0x08,  0x10,  0x08,  0x10,  0x7F,  0xFF,  0x08,  0x10,  0x08,  0x10,  0x3E, 	/* 26580 */
+	0x7C,  0x22,  0x44,  0x22,  0x44,  0x22,  0x44,  0x3E,  0x7C,  0x14,  0x28,  0x14,  0x28,  0x15,  0x48,  0x26, 	/* 26590 */
+	0x49,  0x2C,  0x89,  0x41,  0x07,  0xA5,  0x03,  0x80,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80, 	/* 265A0 */
+	0x00,  0x80,  0x00,  0x80,  0x01,  0x40,  0x01,  0x40,  0x02,  0x20,  0x02,  0x20,  0x04,  0x10,  0x08,  0x08, 	/* 265B0 */
+	0x10,  0x04,  0x20,  0x02,  0x40,  0x01,  0xA8,  0x00,  0x80,  0x00,  0x80,  0x01,  0x40,  0x02,  0x20,  0x04, 	/* 265C0 */
+	0x10,  0x18,  0x0C,  0x6F,  0xFB,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x1F,  0xF8,  0x00,  0x80,  0x00, 	/* 265D0 */
+	0x80,  0x00,  0x80,  0x7F,  0xFF,  0x00,  0x00,  0xA9,  0x00,  0x00,  0x7F,  0xFF,  0x00,  0x80,  0x00,  0x80, 	/* 265E0 */
+	0x3F,  0xFE,  0x20,  0x82,  0x20,  0x82,  0x2C,  0xB2,  0x24,  0x92,  0x24,  0x92,  0x2A,  0xAA,  0x2A,  0xAA, 	/* 265F0 */
+	0x31,  0xC6,  0x20,  0x82,  0x20,  0x82,  0x20,  0x86,  0xAA,  0x00,  0x80,  0x01,  0x40,  0x02,  0x20,  0x04, 	/* 26600 */
+	0x10,  0x18,  0x0C,  0x67,  0xF3,  0x00,  0x00,  0x3E,  0x22,  0x22,  0x22,  0x2A,  0x44,  0x26,  0x88,  0x23, 	/* 26610 */
+	0x10,  0x2A,  0x88,  0x26,  0x44,  0x22,  0x22,  0x26,  0x22,  0xAB,  0x00,  0x00,  0x03,  0xE0,  0x00,  0x20, 	/* 26620 */
+	0x00,  0x20,  0x04,  0x20,  0x04,  0x20,  0x04,  0x20,  0x04,  0x20,  0x04,  0x10,  0x04,  0x10,  0x04,  0x10, 	/* 26630 */
+	0x08,  0x08,  0x08,  0x08,  0x10,  0x04,  0x20,  0x02,  0x40,  0x01,  0xAC,  0x01,  0xE0,  0x04,  0x20,  0x04, 	/* 26640 */
+	0x20,  0x04,  0x10,  0x08,  0x10,  0x08,  0x08,  0x11,  0x04,  0x21,  0x02,  0x41,  0x01,  0x01,  0x40,  0x02, 	/* 26650 */
+	0x20,  0x02,  0x10,  0x04,  0x08,  0x05,  0xF8,  0x3E,  0x04,  0x00,  0x04,  0xAD,  0x00,  0x80,  0x00,  0x80, 	/* 26660 */
+	0x00,  0x80,  0x00,  0x80,  0x7F,  0xFF,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x04,  0x20,  0x04,  0x10, 	/* 26670 */
+	0x04,  0x08,  0x08,  0x08,  0x08,  0x04,  0x10,  0x04,  0x20,  0x04,  0x00,  0x00,  0xAE,  0x00,  0xE0,  0x02, 	/* 26680 */
+	0x20,  0x02,  0x10,  0x04,  0x10,  0x0F,  0xF8,  0x11,  0x04,  0x21,  0x02,  0x42,  0x01,  0x07,  0xF8,  0x04, 	/* 26690 */
+	0x08,  0x00,  0x08,  0x00,  0x08,  0x00,  0x08,  0x00,  0x10,  0x00,  0x10,  0x00,  0x60,  0xB1,  0x04,  0x20, 	/* 266A0 */
+	0x04,  0x20,  0x04,  0x20,  0x04,  0x20,  0x3F,  0xFC,  0x04,  0x20,  0x04,  0x20,  0x04,  0x20,  0x04,  0x20, 	/* 266B0 */
+	0x7F,  0xFF,  0x00,  0x00,  0x04,  0x20,  0x04,  0x10,  0x08,  0x08,  0x10,  0x04,  0x20,  0x04,  0xB5,  0x00, 	/* 266C0 */
+	0x10,  0x00,  0xE0,  0x07,  0x00,  0x04,  0x00,  0x07,  0xFE,  0x04,  0x10,  0x04,  0x10,  0x04,  0x10,  0x04, 	/* 266D0 */
+	0x10,  0x04,  0x10,  0x7F,  0xFF,  0x00,  0x00,  0x02,  0x20,  0x04,  0x18,  0x08,  0x04,  0x30,  0x02,  0xB6, 	/* 266E0 */
+	0x04,  0x10,  0x04,  0x10,  0x3F,  0xFE,  0x04,  0x10,  0x04,  0x10,  0x07,  0xF0,  0x04,  0x10,  0x04,  0x10, 	/* 266F0 */
+	0x07,  0xF0,  0x04,  0x10,  0x04,  0x10,  0x7F,  0xFF,  0x00,  0x00,  0x02,  0x30,  0x0C,  0x0C,  0x30,  0x02, 	/* 26700 */
+	0xB7,  0x00,  0x00,  0x0F,  0xF0,  0x08,  0x10,  0x08,  0x10,  0x0F,  0xF0,  0x08,  0x10,  0x08,  0x10,  0x0F, 	/* 26710 */
+	0xF0,  0x08,  0x10,  0x08,  0x10,  0x0F,  0xF0,  0x00,  0x00,  0x7F,  0xFF,  0x04,  0x60,  0x18,  0x18,  0x60, 	/* 26720 */
+	0x04,  0xB8,  0x02,  0x20,  0x02,  0x20,  0x02,  0x20,  0x1F,  0xFC,  0x12,  0x24,  0x12,  0x24,  0x12,  0x24, 	/* 26730 */
+	0x1F,  0xFC,  0x12,  0x24,  0x12,  0x24,  0x12,  0x24,  0x7F,  0xFF,  0x00,  0x00,  0x06,  0x30,  0x18,  0x0C, 	/* 26740 */
+	0x60,  0x02,  0xBC,  0x08,  0x10,  0x04,  0x20,  0x7F,  0xFE,  0x02,  0x40,  0x1F,  0xF8,  0x02,  0x48,  0x02, 	/* 26750 */
+	0x48,  0x7F,  0xFE,  0x02,  0x48,  0x1F,  0xF8,  0x02,  0x40,  0x06,  0x60,  0x0A,  0x50,  0x12,  0x48,  0x62, 	/* 26760 */
+	0x46,  0x02,  0x40,  0x80,  0x02,  0x22,  0x7E,  0x24,  0x02,  0x39,  0x0E,  0x21,  0x72,  0x1F,  0x0F,  0xF8, 	/* 26770 */
+	0x08,  0x88,  0x0F,  0xF8,  0x08,  0x88,  0x0F,  0xF8,  0x02,  0x20,  0x1F,  0xFC,  0x02,  0x20,  0x7F,  0xFF, 	/* 26780 */
+	0x06,  0x38,  0x78,  0x06,  0x82,  0x00,  0x00,  0x3F,  0xFE,  0x20,  0x02,  0x20,  0x02,  0x20,  0x02,  0x20, 	/* 26790 */
+	0x02,  0x20,  0x02,  0x20,  0x02,  0x20,  0x02,  0x20,  0x02,  0x20,  0x02,  0x20,  0x02,  0x20,  0x02,  0x20, 	/* 267A0 */
+	0x02,  0x20,  0x02,  0x20,  0x06,  0x85,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x3F,  0xFE,  0x20,  0x82, 	/* 267B0 */
+	0x20,  0x82,  0x21,  0x42,  0x21,  0x42,  0x22,  0x22,  0x24,  0x12,  0x28,  0x0A,  0x20,  0x02,  0x20,  0x02, 	/* 267C0 */
+	0x20,  0x02,  0x20,  0x02,  0x20,  0x06,  0x86,  0x00,  0x00,  0x3F,  0xFC,  0x21,  0x04,  0x21,  0x04,  0x21, 	/* 267D0 */
+	0x04,  0x21,  0x04,  0x21,  0x04,  0x3F,  0xFC,  0x20,  0x04,  0x20,  0x04,  0x20,  0x04,  0x20,  0x04,  0x20, 	/* 267E0 */
+	0x04,  0x20,  0x04,  0x20,  0x04,  0x20,  0x0C,  0x89,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x1F,  0xFC, 	/* 267F0 */
+	0x10,  0x84,  0x10,  0x84,  0x1F,  0xFC,  0x10,  0x84,  0x10,  0x84,  0x10,  0x84,  0x7F,  0xFF,  0x10,  0x04, 	/* 26800 */
+	0x10,  0x04,  0x10,  0x04,  0x10,  0x04,  0x10,  0x0C,  0x8A,  0x00,  0x00,  0x1F,  0xFC,  0x12,  0x24,  0x12, 	/* 26810 */
+	0x24,  0x12,  0x24,  0x12,  0x24,  0x12,  0x24,  0x7F,  0xFF,  0x12,  0x24,  0x12,  0x24,  0x12,  0x24,  0x12, 	/* 26820 */
+	0x24,  0x12,  0x24,  0x12,  0x24,  0x12,  0x24,  0x12,  0x2C,  0x8C,  0x00,  0x00,  0x1E,  0x3C,  0x12,  0x24, 	/* 26830 */
+	0x12,  0x24,  0x12,  0x24,  0x12,  0x24,  0x12,  0x24,  0x7F,  0xFF,  0x12,  0x24,  0x12,  0x24,  0x12,  0x24, 	/* 26840 */
+	0x12,  0x24,  0x12,  0x44,  0x12,  0x44,  0x26,  0x84,  0x41,  0x0C,  0x8D,  0x00,  0x00,  0x3F,  0xFE,  0x00, 	/* 26850 */
+	0x80,  0x00,  0x80,  0x0F,  0xF8,  0x08,  0x88,  0x08,  0x88,  0x0F,  0xF8,  0x08,  0x88,  0x08,  0x88,  0x08, 	/* 26860 */
+	0x88,  0x7F,  0xFF,  0x08,  0x08,  0x08,  0x08,  0x08,  0x08,  0x08,  0x18,  0x8F,  0x00,  0x00,  0x3F,  0xFE, 	/* 26870 */
+	0x22,  0x22,  0x22,  0x22,  0x22,  0x22,  0x22,  0x26,  0x24,  0x1E,  0x28,  0x02,  0x33,  0xE2,  0x22,  0x22, 	/* 26880 */
+	0x22,  0x22,  0x22,  0x22,  0x23,  0xE2,  0x20,  0x02,  0x20,  0x02,  0x20,  0x06,  0x90,  0x00,  0x00,  0x3F, 	/* 26890 */
+	0xFE,  0x20,  0x02,  0x2F,  0xFA,  0x20,  0x02,  0x2F,  0xFA,  0x00,  0x00,  0x00,  0x00,  0x0F,  0xF8,  0x08, 	/* 268A0 */
+	0x08,  0x0F,  0xF8,  0x08,  0x08,  0x0F,  0xF8,  0x08,  0x08,  0x08,  0x08,  0x08,  0x18,  0x91,  0x00,  0x80, 	/* 268B0 */
+	0x00,  0x80,  0x3F,  0xFE,  0x20,  0x82,  0x3F,  0xFE,  0x20,  0x82,  0x3F,  0xFE,  0x00,  0x00,  0x1F,  0xFC, 	/* 268C0 */
+	0x10,  0x04,  0x17,  0xF4,  0x10,  0x04,  0x17,  0xF4,  0x10,  0x04,  0x10,  0x04,  0x10,  0x0C,  0x92,  0x00, 	/* 268D0 */
+	0x00,  0x3F,  0xFC,  0x20,  0x04,  0x3F,  0xFC,  0x20,  0x04,  0x3F,  0xFC,  0x00,  0x00,  0x0F,  0xF0,  0x08, 	/* 268E0 */
+	0x10,  0x0F,  0xF0,  0x08,  0x10,  0x0F,  0xF0,  0x08,  0x10,  0x08,  0x10,  0x0F,  0xF0,  0x00,  0x00,  0x93, 	/* 268F0 */
+	0x02,  0x20,  0x02,  0x20,  0x3F,  0xFE,  0x02,  0x20,  0x1F,  0xFC,  0x02,  0x20,  0x7F,  0xFF,  0x00,  0x80, 	/* 26900 */
+	0x0F,  0xF8,  0x08,  0x88,  0x0F,  0xF8,  0x08,  0x88,  0x7F,  0xFF,  0x08,  0x08,  0x08,  0x08,  0x08,  0x18, 	/* 26910 */
+	0x95,  0x00,  0x00,  0x3F,  0xFC,  0x20,  0x04,  0x2F,  0xF4,  0x20,  0x04,  0x2F,  0xF4,  0x22,  0x04,  0x07, 	/* 26920 */
+	0xC0,  0x18,  0x80,  0x7F,  0xF0,  0x11,  0x10,  0x11,  0x10,  0x1F,  0xF2,  0x02,  0x42,  0x0C,  0x42,  0x70, 	/* 26930 */
+	0x3E,  0x96,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x7F,  0xFE, 	/* 26940 */
+	0x40,  0x02,  0x40,  0x02,  0x40,  0x02,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00, 	/* 26950 */
+	0x00,  0x00,  0x97,  0x00,  0x00,  0x7F,  0xFE,  0x40,  0x02,  0x40,  0x02,  0x43,  0xE2,  0x02,  0x20,  0x02, 	/* 26960 */
+	0x20,  0x02,  0x20,  0x02,  0x20,  0x02,  0x20,  0x04,  0x20,  0x04,  0x20,  0x08,  0x20,  0x08,  0x22,  0x10, 	/* 26970 */
+	0x22,  0x20,  0x1E,  0x99,  0x00,  0x00,  0x7F,  0xFE,  0x40,  0x02,  0x44,  0x02,  0x47,  0xF2,  0x04,  0x00, 	/* 26980 */
+	0x04,  0x00,  0x07,  0xE0,  0x00,  0x20,  0x00,  0x20,  0x7F,  0xFE,  0x00,  0x20,  0x00,  0x20,  0x00,  0x20, 	/* 26990 */
+	0x00,  0x40,  0x03,  0x80,  0xA0,  0x00,  0x00,  0x7F,  0xFE,  0x40,  0x02,  0x40,  0x02,  0x3F,  0x08,  0x00, 	/* 269A0 */
+	0x08,  0x00,  0xFE,  0x7F,  0x08,  0x12,  0x88,  0x12,  0x48,  0x12,  0x48,  0x12,  0x08,  0x12,  0x08,  0x22, 	/* 269B0 */
+	0x1A,  0x21,  0x02,  0x40,  0xFE,  0xA2,  0x00,  0x00,  0x7F,  0xFE,  0x40,  0x02,  0x40,  0x02,  0x1F,  0xF8, 	/* 269C0 */
+	0x02,  0x00,  0x0D,  0x08,  0x71,  0x48,  0x12,  0xD0,  0x0C,  0xA0,  0x79,  0xA0,  0x06,  0x90,  0x0C,  0x8C, 	/* 269D0 */
+	0x70,  0x83,  0x00,  0x80,  0x03,  0x00,  0xA4,  0x00,  0x00,  0x7F,  0xFE,  0x41,  0x02,  0x43,  0xE2,  0x04, 	/* 269E0 */
+	0x40,  0x18,  0x80,  0x7F,  0xF8,  0x11,  0x08,  0x11,  0x08,  0x1F,  0xF8,  0x02,  0x40,  0x02,  0x50,  0x04, 	/* 269F0 */
+	0x48,  0x08,  0x42,  0x10,  0x22,  0x60,  0x1E,  0xA5,  0x00,  0x00,  0x7F,  0xFE,  0x40,  0x02,  0x4F,  0xF2, 	/* 26A00 */
+	0x08,  0x10,  0x08,  0x10,  0x0F,  0xF0,  0x08,  0x10,  0x08,  0x10,  0x0F,  0xF0,  0x01,  0x00,  0x7F,  0xFE, 	/* 26A10 */
+	0x00,  0x00,  0x04,  0x60,  0x18,  0x18,  0x60,  0x04,  0xA6,  0x00,  0x00,  0x7F,  0xFE,  0x40,  0x22,  0x40, 	/* 26A20 */
+	0x22,  0x3E,  0x3C,  0x00,  0x20,  0x00,  0xF8,  0x7F,  0x08,  0x14,  0x48,  0x14,  0x50,  0x14,  0x30,  0x14, 	/* 26A30 */
+	0x48,  0x15,  0x86,  0x24,  0x02,  0x22,  0x02,  0x41,  0xFE,  0xA8,  0x00,  0x00,  0x7F,  0xFE,  0x40,  0x02, 	/* 26A40 */
+	0x5F,  0xFA,  0x00,  0x00,  0x0F,  0xF0,  0x08,  0x10,  0x0F,  0xF0,  0x00,  0x00,  0x1F,  0xF8,  0x11,  0x08, 	/* 26A50 */
+	0x1F,  0xF8,  0x11,  0x08,  0x11,  0x08,  0x1F,  0xF8,  0x00,  0x00,  0xA9,  0x00,  0x00,  0x7F,  0xFE,  0x41, 	/* 26A60 */
+	0x02,  0x42,  0x02,  0x0C,  0xF0,  0x08,  0x10,  0x0F,  0x70,  0x08,  0x10,  0x0F,  0xF0,  0x04,  0x00,  0x0F, 	/* 26A70 */
+	0xFC,  0x10,  0x24,  0x64,  0x94,  0x12,  0x54,  0x12,  0x44,  0x20,  0x18,  0xAA,  0x00,  0x00,  0x7F,  0xFE, 	/* 26A80 */
+	0x44,  0x22,  0x3F,  0xFC,  0x08,  0x10,  0x0F,  0xF0,  0x08,  0x10,  0x0F,  0xF0,  0x02,  0x00,  0x7F,  0xFE, 	/* 26A90 */
+	0x09,  0x10,  0x1F,  0xF8,  0x29,  0x14,  0x49,  0x12,  0x09,  0x60,  0x01,  0x00,  0xAB,  0x00,  0x00,  0x02, 	/* 26AA0 */
+	0x00,  0x01,  0x00,  0x00,  0x80,  0x00,  0x80,  0x00,  0x00,  0x00,  0x00,  0x00,  0x20,  0x00,  0x20,  0x00, 	/* 26AB0 */
+	0x40,  0x00,  0x80,  0x00,  0x80,  0x01,  0x00,  0x02,  0x00,  0x04,  0x00,  0x00,  0x00,  0xAC,  0x01,  0x00, 	/* 26AC0 */
+	0x01,  0x00,  0x01,  0xF8,  0x02,  0x08,  0x06,  0x10,  0x19,  0xA0,  0x00,  0x40,  0x00,  0xA0,  0x03,  0x10, 	/* 26AD0 */
+	0x0D,  0x8C,  0x70,  0x43,  0x00,  0x20,  0x06,  0x00,  0x01,  0x80,  0x00,  0x60,  0x00,  0x10,  0xB0,  0x00, 	/* 26AE0 */
+	0x40,  0x20,  0x40,  0x10,  0x42,  0x10,  0x42,  0x00,  0x64,  0x0F,  0x64,  0x01,  0x68,  0x01,  0x50,  0x09, 	/* 26AF0 */
+	0x50,  0x12,  0x48,  0x12,  0x48,  0x24,  0x44,  0x24,  0x42,  0x48,  0x41,  0x50,  0x40,  0x00,  0xC0,  0xB1, 	/* 26B00 */
+	0x00,  0x00,  0x27,  0xFE,  0x10,  0x80,  0x10,  0x80,  0x00,  0x80,  0x00,  0xF8,  0x00,  0x88,  0x09,  0x08, 	/* 26B10 */
+	0x09,  0x08,  0x11,  0x08,  0x13,  0xF0,  0x22,  0x10,  0x20,  0x10,  0x40,  0x10,  0x4F,  0xFF,  0x00,  0x00, 	/* 26B20 */
+	0xB2,  0x00,  0x20,  0x20,  0x20,  0x10,  0x20,  0x10,  0x20,  0x03,  0xFE,  0x02,  0x22,  0x02,  0x22,  0x0A, 	/* 26B30 */
+	0x22,  0x0A,  0x22,  0x13,  0xFE,  0x10,  0x20,  0x20,  0x20,  0x20,  0x20,  0x40,  0x20,  0x40,  0x20,  0x00, 	/* 26B40 */
+	0x20,  0xB3,  0x00,  0x40,  0x20,  0x40,  0x10,  0x40,  0x13,  0xFC,  0x00,  0x44,  0x00,  0x44,  0x00,  0x44, 	/* 26B50 */
+	0x08,  0x44,  0x0F,  0xFF,  0x10,  0x60,  0x10,  0x50,  0x20,  0x90,  0x20,  0x88,  0x41,  0x04,  0x42,  0x02, 	/* 26B60 */
+	0x0C,  0x01,  0xB4,  0x00,  0x00,  0x23,  0xFE,  0x10,  0x88,  0x08,  0x88,  0x08,  0x88,  0x00,  0x88,  0x00, 	/* 26B70 */
+	0x88,  0x0B,  0xFF,  0x08,  0x28,  0x10,  0x28,  0x10,  0x48,  0x20,  0x88,  0x21,  0x08,  0x42,  0x08,  0x4C, 	/* 26B80 */
+	0x08,  0x00,  0x18,  0xB5,  0x00,  0x00,  0x23,  0xFC,  0x12,  0x04,  0x12,  0x04,  0x02,  0x04,  0x02,  0x04, 	/* 26B90 */
+	0x02,  0x04,  0x0B,  0xFC,  0x08,  0x90,  0x10,  0x90,  0x10,  0x90,  0x20,  0x90,  0x21,  0x11,  0x41,  0x11, 	/* 26BA0 */
+	0x42,  0x11,  0x04,  0x0F,  0xB6,  0x00,  0x40,  0x20,  0x40,  0x10,  0x40,  0x08,  0x90,  0x08,  0x88,  0x01, 	/* 26BB0 */
+	0x04,  0x01,  0x3C,  0x07,  0xC2,  0x08,  0x02,  0x09,  0xFC,  0x11,  0x04,  0x11,  0x04,  0x21,  0x04,  0x21, 	/* 26BC0 */
+	0x04,  0x41,  0xFC,  0x00,  0x00,  0xB7,  0x00,  0x40,  0x20,  0x60,  0x10,  0xA0,  0x10,  0x90,  0x11,  0x08, 	/* 26BD0 */
+	0x01,  0xFC,  0x02,  0x02,  0x04,  0x01,  0x13,  0xFC,  0x10,  0x44,  0x10,  0x44,  0x20,  0x44,  0x20,  0x58, 	/* 26BE0 */
+	0x40,  0x40,  0x40,  0x40,  0x00,  0x40,  0xBD,  0x00,  0x02,  0x2F,  0xF2,  0x12,  0x12,  0x12,  0x12,  0x02, 	/* 26BF0 */
+	0x12,  0x03,  0xD2,  0x02,  0x52,  0x12,  0x52,  0x15,  0x52,  0x14,  0x92,  0x28,  0x92,  0x21,  0x02,  0x41, 	/* 26C00 */
+	0x02,  0x42,  0x02,  0x44,  0x02,  0x18,  0x06,  0x84,  0x00,  0x40,  0x20,  0x40,  0x17,  0xFE,  0x10,  0x40, 	/* 26C10 */
+	0x13,  0xF8,  0x00,  0x48,  0x0F,  0xFF,  0x00,  0x48,  0x0B,  0xF8,  0x10,  0x80,  0x1F,  0xFF,  0x20,  0x88, 	/* 26C20 */
+	0x21,  0x10,  0x43,  0xF0,  0x40,  0xC8,  0x0F,  0x04,  0x85,  0x00,  0x00,  0x27,  0xFE,  0x14,  0x42,  0x14, 	/* 26C30 */
+	0x42,  0x07,  0xFE,  0x04,  0x42,  0x04,  0x42,  0x04,  0xF2,  0x14,  0x92,  0x14,  0x92,  0x14,  0x92,  0x24, 	/* 26C40 */
+	0xF2,  0x24,  0x02,  0x44,  0x02,  0x47,  0xFE,  0x00,  0x00,  0x86,  0x00,  0x88,  0x20,  0x88,  0x11,  0x10, 	/* 26C50 */
+	0x11,  0xFE,  0x03,  0x10,  0x03,  0x10,  0x05,  0x10,  0x01,  0xFE,  0x09,  0x10,  0x11,  0x10,  0x11,  0xFE, 	/* 26C60 */
+	0x21,  0x10,  0x21,  0x10,  0x41,  0x10,  0x41,  0xFF,  0x00,  0x00,  0x89,  0x00,  0x20,  0x20,  0x20,  0x10, 	/* 26C70 */
+	0x20,  0x17,  0xFF,  0x00,  0x00,  0x01,  0xFC,  0x01,  0x04,  0x09,  0x04,  0x09,  0x04,  0x11,  0xFC,  0x10, 	/* 26C80 */
+	0x20,  0x21,  0x28,  0x21,  0x24,  0x42,  0x22,  0x44,  0x22,  0x00,  0x60,  0x8B,  0x00,  0x00,  0x23,  0xFE, 	/* 26C90 */
+	0x12,  0x22,  0x12,  0x22,  0x02,  0xFA,  0x02,  0x22,  0x02,  0x22,  0x0B,  0xFE,  0x0A,  0x02,  0x12,  0xFA, 	/* 26CA0 */
+	0x12,  0x8A,  0x22,  0x8A,  0x22,  0xFA,  0x44,  0x02,  0x44,  0x02,  0x08,  0x06,  0x8C,  0x00,  0x20,  0x20, 	/* 26CB0 */
+	0x20,  0x13,  0xFE,  0x10,  0x20,  0x00,  0x20,  0x07,  0xFF,  0x00,  0x90,  0x08,  0x92,  0x09,  0x4E,  0x12, 	/* 26CC0 */
+	0x78,  0x14,  0x88,  0x21,  0x90,  0x26,  0x50,  0x40,  0x60,  0x41,  0x98,  0x06,  0x07,  0x8D,  0x00,  0x40, 	/* 26CD0 */
+	0x20,  0x40,  0x27,  0xFE,  0x10,  0x40,  0x13,  0xFC,  0x02,  0x44,  0x03,  0xFC,  0x02,  0x44,  0x0A,  0x44, 	/* 26CE0 */
+	0x13,  0xFC,  0x10,  0xE0,  0x21,  0x50,  0x22,  0x48,  0x44,  0x44,  0x48,  0x42,  0x00,  0x40,  0x96,  0x00, 	/* 26CF0 */
+	0x88,  0x20,  0x90,  0x11,  0xFE,  0x11,  0x20,  0x03,  0xFC,  0x05,  0x20,  0x01,  0xFC,  0x09,  0x20,  0x31, 	/* 26D00 */
+	0xFE,  0x40,  0x80,  0x00,  0x80,  0x7F,  0xFE,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x9B, 	/* 26D10 */
+	0x00,  0x20,  0x27,  0xFF,  0x12,  0x04,  0x12,  0xF4,  0x02,  0x94,  0x02,  0xF4,  0x02,  0x04,  0x0B,  0xFC, 	/* 26D20 */
+	0x08,  0x00,  0x13,  0xFC,  0x10,  0x00,  0x2F,  0xFF,  0x21,  0x28,  0x41,  0x24,  0x42,  0x22,  0x04,  0x60, 	/* 26D30 */
+	0x9C,  0x00,  0x20,  0x00,  0x20,  0x27,  0xFF,  0x21,  0x74,  0x11,  0x54,  0x11,  0x74,  0x01,  0x04,  0x01, 	/* 26D40 */
+	0xFC,  0x08,  0x0C,  0x11,  0xF0,  0x10,  0x20,  0x27,  0xFF,  0x20,  0x70,  0x41,  0xAC,  0x46,  0x23,  0x00, 	/* 26D50 */
+	0x20,  0x9D,  0x04,  0x00,  0x04,  0xBE,  0x27,  0x02,  0x14,  0x14,  0x14,  0x88,  0x03,  0x84,  0x02,  0x7F, 	/* 26D60 */
+	0x13,  0x8A,  0x15,  0x0C,  0x11,  0x28,  0x2F,  0xEE,  0x21,  0x28,  0x22,  0xA8,  0x42,  0x58,  0x44,  0x4C, 	/* 26D70 */
+	0x08,  0x83,  0xA0,  0x00,  0x00,  0x07,  0xE0,  0x04,  0x20,  0x04,  0x20,  0x04,  0x20,  0x04,  0x20,  0x04, 	/* 26D80 */
+	0x20,  0x04,  0x20,  0x04,  0x20,  0x04,  0x20,  0x04,  0x20,  0x08,  0x20,  0x08,  0x21,  0x10,  0x21,  0x20, 	/* 26D90 */
+	0x1F,  0x40,  0x00,  0xA1,  0x00,  0x00,  0x07,  0xE0,  0x04,  0x20,  0x04,  0x20,  0x04,  0x20,  0x06,  0x20, 	/* 26DA0 */
+	0x05,  0x20,  0x04,  0xA0,  0x04,  0xA0,  0x04,  0x20,  0x04,  0x20,  0x08,  0x20,  0x08,  0x22,  0x10,  0x22, 	/* 26DB0 */
+	0x20,  0x1E,  0x40,  0x00,  0xA6,  0x08,  0x00,  0x08,  0x3C,  0x08,  0x24,  0x0F,  0x24,  0x09,  0x24,  0x11, 	/* 26DC0 */
+	0x24,  0x11,  0x24,  0x2A,  0x24,  0x2A,  0x24,  0x44,  0x44,  0x04,  0x45,  0x0A,  0x85,  0x09,  0x03,  0x10, 	/* 26DD0 */
+	0x80,  0x20,  0x60,  0x40,  0x1F,  0xA7,  0x00,  0x00,  0x1F,  0xF8,  0x10,  0x08,  0x11,  0x08,  0x11,  0x08, 	/* 26DE0 */
+	0x17,  0xE8,  0x15,  0x28,  0x15,  0x28,  0x15,  0x28,  0x15,  0x28,  0x15,  0x28,  0x15,  0x48,  0x15,  0x05, 	/* 26DF0 */
+	0x21,  0x05,  0x21,  0x03,  0x41,  0x01,  0xA9,  0x00,  0x00,  0x1F,  0xF8,  0x10,  0x08,  0x10,  0x88,  0x10, 	/* 26E00 */
+	0x88,  0x17,  0xF8,  0x10,  0x88,  0x10,  0x88,  0x11,  0xC8,  0x11,  0xC8,  0x12,  0xA8,  0x12,  0xA8,  0x14, 	/* 26E10 */
+	0x95,  0x28,  0x85,  0x20,  0x83,  0x40,  0x81,  0xAA,  0x00,  0x00,  0x1F,  0xF8,  0x10,  0x08,  0x10,  0x88, 	/* 26E20 */
+	0x10,  0x88,  0x10,  0x88,  0x14,  0x88,  0x14,  0x88,  0x14,  0xE8,  0x14,  0x88,  0x14,  0x88,  0x14,  0x88, 	/* 26E30 */
+	0x14,  0x85,  0x24,  0x85,  0x3F,  0xFB,  0x40,  0x01,  0xAD,  0x04,  0x08,  0x04,  0x30,  0x09,  0xE0,  0x10, 	/* 26E40 */
+	0x20,  0x37,  0xFF,  0x50,  0x20,  0x10,  0x20,  0x13,  0xFE,  0x10,  0x00,  0x00,  0x00,  0x07,  0xE0,  0x04, 	/* 26E50 */
+	0x20,  0x04,  0x20,  0x08,  0x22,  0x10,  0x22,  0x60,  0x1E,  0xB0,  0x00,  0x00,  0x1F,  0xFC,  0x10,  0x84, 	/* 26E60 */
+	0x11,  0x04,  0x17,  0xF4,  0x14,  0x14,  0x17,  0xF4,  0x14,  0x14,  0x17,  0xF4,  0x10,  0x04,  0x17,  0xF4, 	/* 26E70 */
+	0x10,  0x84,  0x13,  0xE5,  0x20,  0x85,  0x2F,  0xFB,  0x40,  0x01,  0xB1,  0x08,  0x00,  0x29,  0x3C,  0x29, 	/* 26E80 */
+	0x24,  0x3F,  0x24,  0x00,  0x24,  0x7F,  0xA4,  0x00,  0x24,  0x3F,  0x24,  0x21,  0x24,  0x21,  0x24,  0x3F, 	/* 26E90 */
+	0x24,  0x22,  0x24,  0x12,  0x24,  0x15,  0xC5,  0x0E,  0x45,  0x70,  0x83,  0xB5,  0x20,  0x02,  0x20,  0x02, 	/* 26EA0 */
+	0x20,  0x02,  0x20,  0x02,  0x20,  0x02,  0x20,  0x02,  0x20,  0x02,  0x20,  0x02,  0x20,  0x02,  0x20,  0x02, 	/* 26EB0 */
+	0x20,  0x02,  0x20,  0x02,  0x20,  0x02,  0x20,  0x02,  0x3F,  0xFE,  0x00,  0x00,  0xB6,  0x00,  0x00,  0x00, 	/* 26EC0 */
+	0x10,  0x20,  0x12,  0x20,  0x12,  0x26,  0x22,  0x21,  0xA2,  0x20,  0x42,  0x20,  0x62,  0x20,  0x92,  0x21, 	/* 26ED0 */
+	0x12,  0x22,  0x0A,  0x24,  0x0A,  0x28,  0x02,  0x20,  0x02,  0x3F,  0xFE,  0x00,  0x00,  0xB8,  0x00,  0x00, 	/* 26EE0 */
+	0x03,  0xE0,  0x02,  0x20,  0x02,  0x20,  0x02,  0x20,  0x02,  0x20,  0x02,  0x20,  0x3E,  0x3E,  0x20,  0x02, 	/* 26EF0 */
+	0x20,  0x02,  0x20,  0x02,  0x20,  0x02,  0x20,  0x02,  0x3F,  0xFE,  0x00,  0x00,  0x00,  0x00,  0xB9,  0x00, 	/* 26F00 */
+	0x00,  0x3E,  0x3E,  0x22,  0x22,  0x22,  0x22,  0x22,  0x22,  0x22,  0x22,  0x22,  0x22,  0x22,  0x22,  0x23, 	/* 26F10 */
+	0xE2,  0x20,  0x02,  0x20,  0x02,  0x20,  0x02,  0x20,  0x02,  0x3F,  0xFE,  0x00,  0x00,  0x00,  0x00,  0xBA, 	/* 26F20 */
+	0x00,  0x80,  0x00,  0x80,  0x10,  0x84,  0x10,  0x84,  0x10,  0x84,  0x10,  0x84,  0x1F,  0xFC,  0x00,  0x80, 	/* 26F30 */
+	0x00,  0x80,  0x20,  0x82,  0x20,  0x82,  0x20,  0x82,  0x20,  0x82,  0x20,  0x82,  0x3F,  0xFE,  0x00,  0x00, 	/* 26F40 */
+	0xBD,  0x00,  0x00,  0x7F,  0xFF,  0x02,  0x00,  0x02,  0x00,  0x23,  0x8A,  0x28,  0x8A,  0x24,  0xD2,  0x22, 	/* 26F50 */
+	0xC2,  0x20,  0xA2,  0x21,  0xA2,  0x26,  0x92,  0x38,  0x8A,  0x23,  0x02,  0x20,  0x02,  0x3F,  0xFE,  0x00, 	/* 26F60 */
+	0x00,  0xBE,  0x00,  0x00,  0x0F,  0xF8,  0x00,  0x10,  0x00,  0x60,  0x20,  0x82,  0x2E,  0xFA,  0x2A,  0x8A, 	/* 26F70 */
+	0x2A,  0xAA,  0x2A,  0xAA,  0x2A,  0xB2,  0x2E,  0xD2,  0x28,  0x8A,  0x21,  0x86,  0x20,  0x02,  0x3F,  0xFE, 	/* 26F80 */
+	0x20,  0x02,  0x80,  0x00,  0x00,  0x00,  0x00,  0x3F,  0xFE,  0x00,  0x82,  0x00,  0x82,  0x00,  0x82,  0x00, 	/* 26F90 */
+	0x82,  0x00,  0x82,  0x01,  0x02,  0x01,  0x02,  0x01,  0x02,  0x02,  0x02,  0x04,  0x02,  0x08,  0x04,  0x10, 	/* 26FA0 */
+	0x18,  0x00,  0x00,  0x83,  0x00,  0x00,  0x00,  0x00,  0x3F,  0xFC,  0x00,  0x84,  0x00,  0x84,  0x00,  0x84, 	/* 26FB0 */
+	0x0C,  0x84,  0x03,  0x04,  0x01,  0x84,  0x02,  0x44,  0x02,  0x24,  0x04,  0x04,  0x08,  0x04,  0x10,  0x08, 	/* 26FC0 */
+	0x20,  0x30,  0x00,  0x00,  0x84,  0x00,  0x00,  0x7F,  0xFC,  0x00,  0x84,  0x00,  0x84,  0x10,  0x84,  0x08, 	/* 26FD0 */
+	0x84,  0x04,  0x84,  0x03,  0x04,  0x01,  0x04,  0x01,  0x84,  0x02,  0x64,  0x02,  0x1C,  0x04,  0x07,  0x08, 	/* 26FE0 */
+	0x04,  0x10,  0x08,  0x20,  0x70,  0x86,  0x03,  0xE0,  0x00,  0x20,  0x04,  0x20,  0x04,  0x10,  0x08,  0x10, 	/* 26FF0 */
+	0x08,  0x08,  0x10,  0x04,  0x2F,  0xF2,  0x41,  0x11,  0x01,  0x10,  0x01,  0x10,  0x02,  0x10,  0x02,  0x10, 	/* 27000 */
+	0x04,  0x10,  0x08,  0x10,  0x10,  0x60,  0x87,  0x10,  0x00,  0x11,  0xFE,  0x10,  0x22,  0x10,  0x22,  0x13, 	/* 27010 */
+	0x22,  0x1C,  0x22,  0x70,  0x22,  0x10,  0x22,  0x10,  0x22,  0x10,  0x22,  0x12,  0x42,  0x12,  0x42,  0x0E, 	/* 27020 */
+	0x82,  0x01,  0x02,  0x02,  0x04,  0x0C,  0x18,  0x88,  0x01,  0x02,  0x01,  0x22,  0x01,  0x22,  0x01,  0x22, 	/* 27030 */
+	0x21,  0x22,  0x11,  0x22,  0x0A,  0x22,  0x06,  0x22,  0x02,  0x22,  0x05,  0x22,  0x05,  0x22,  0x08,  0x82, 	/* 27040 */
+	0x08,  0x82,  0x10,  0x82,  0x20,  0x02,  0x40,  0x06,  0x8A,  0x00,  0x02,  0x3F,  0xA2,  0x04,  0x22,  0x04, 	/* 27050 */
+	0x22,  0x04,  0x22,  0x04,  0x22,  0x7F,  0xE2,  0x04,  0x22,  0x04,  0x22,  0x04,  0x22,  0x04,  0x22,  0x04, 	/* 27060 */
+	0x02,  0x04,  0x02,  0x04,  0x02,  0x04,  0x02,  0x04,  0x06,  0x8B,  0x00,  0x82,  0x07,  0x22,  0x7C,  0x22, 	/* 27070 */
+	0x04,  0x22,  0x04,  0x22,  0x04,  0x22,  0x7F,  0xA2,  0x04,  0x22,  0x04,  0x22,  0x04,  0x22,  0x04,  0x22, 	/* 27080 */
+	0x08,  0x22,  0x08,  0x02,  0x10,  0x02,  0x20,  0x02,  0x40,  0x06,  0x8E,  0x10,  0x02,  0x10,  0x12,  0x1F, 	/* 27090 */
+	0x92,  0x15,  0x92,  0x25,  0x92,  0x25,  0x92,  0x49,  0x92,  0x0A,  0x92,  0x12,  0x92,  0x12,  0x92,  0x24, 	/* 270A0 */
+	0x92,  0x44,  0x92,  0x08,  0x82,  0x10,  0x82,  0x20,  0x82,  0x03,  0x06,  0x91,  0x00,  0x02,  0x3F,  0xE2, 	/* 270B0 */
+	0x09,  0x22,  0x09,  0x22,  0x09,  0x22,  0x09,  0x22,  0x7F,  0xE2,  0x09,  0x22,  0x09,  0x22,  0x09,  0x22, 	/* 270C0 */
+	0x09,  0x22,  0x09,  0x02,  0x11,  0x02,  0x11,  0x02,  0x21,  0x02,  0x41,  0x06,  0x94,  0x04,  0x02,  0x04, 	/* 270D0 */
+	0x12,  0x04,  0x12,  0x3F,  0x92,  0x04,  0x92,  0x04,  0x92,  0x04,  0x92,  0x04,  0x92,  0x7F,  0xF2,  0x04, 	/* 270E0 */
+	0x12,  0x06,  0x12,  0x09,  0x02,  0x09,  0x02,  0x10,  0x82,  0x20,  0x42,  0x40,  0x06,  0x97,  0x00,  0x02, 	/* 270F0 */
+	0x7F,  0xE2,  0x08,  0x22,  0x08,  0x22,  0x08,  0x22,  0x0F,  0x22,  0x11,  0x22,  0x11,  0x22,  0x29,  0x22, 	/* 27100 */
+	0x46,  0x22,  0x02,  0x22,  0x04,  0x02,  0x04,  0x02,  0x08,  0x02,  0x10,  0x02,  0x20,  0x06,  0x9D,  0x08, 	/* 27110 */
+	0x00,  0x08,  0x00,  0x09,  0xFE,  0x7E,  0x22,  0x02,  0x22,  0x04,  0x22,  0x05,  0x22,  0x09,  0x22,  0x0E, 	/* 27120 */
+	0x22,  0x1A,  0x22,  0x29,  0x22,  0x49,  0x42,  0x08,  0x42,  0x08,  0x82,  0x09,  0x02,  0x0A,  0x0C,  0xA4, 	/* 27130 */
+	0x04,  0x02,  0x04,  0x92,  0x24,  0x92,  0x14,  0x92,  0x15,  0x12,  0x04,  0x12,  0x7F,  0xD2,  0x04,  0x12, 	/* 27140 */
+	0x04,  0x12,  0x04,  0x12,  0x7F,  0xD2,  0x04,  0x12,  0x04,  0x02,  0x04,  0x02,  0x04,  0x02,  0x04,  0x06, 	/* 27150 */
+	0xA5,  0x00,  0x02,  0x3F,  0xA2,  0x20,  0xA2,  0x20,  0xA2,  0x20,  0xA2,  0x3F,  0xA2,  0x08,  0x22,  0x08, 	/* 27160 */
+	0x22,  0x0F,  0xA2,  0x08,  0xA2,  0x08,  0xA2,  0x08,  0x82,  0x10,  0x82,  0x10,  0x82,  0x21,  0x02,  0x46, 	/* 27170 */
+	0x06,  0xA7,  0x04,  0x00,  0x04,  0x7E,  0x04,  0x12,  0x3F,  0x92,  0x04,  0x12,  0x04,  0x12,  0x04,  0x12, 	/* 27180 */
+	0x7F,  0xD2,  0x04,  0x12,  0x04,  0x12,  0x08,  0x12,  0x0A,  0x22,  0x09,  0x22,  0x13,  0x42,  0x7C,  0x82, 	/* 27190 */
+	0x00,  0x8C,  0xA9,  0x00,  0x82,  0x03,  0x22,  0x3C,  0x22,  0x04,  0x22,  0x04,  0x22,  0x04,  0x22,  0x7F, 	/* 271A0 */
+	0xA2,  0x0C,  0x22,  0x0E,  0x22,  0x15,  0x22,  0x14,  0xA2,  0x24,  0xA2,  0x44,  0x02,  0x04,  0x02,  0x04, 	/* 271B0 */
+	0x02,  0x04,  0x06,  0xAA,  0x00,  0x02,  0x3F,  0x92,  0x2A,  0x92,  0x2A,  0x92,  0x2A,  0x92,  0x2A,  0x92, 	/* 271C0 */
+	0x2A,  0x92,  0x7F,  0xD2,  0x2A,  0x92,  0x2A,  0x92,  0x2A,  0x92,  0x2A,  0x82,  0x2A,  0x82,  0x2A,  0x82, 	/* 271D0 */
+	0x2A,  0x82,  0x21,  0x86,  0xAE,  0x00,  0x82,  0x03,  0x12,  0x3C,  0x12,  0x04,  0x12,  0x04,  0x12,  0x04, 	/* 271E0 */
+	0x12,  0x7F,  0xD2,  0x04,  0x12,  0x04,  0x12,  0x04,  0x12,  0x1F,  0x92,  0x10,  0x82,  0x10,  0x82,  0x10, 	/* 271F0 */
+	0x82,  0x1F,  0x82,  0x00,  0x06,  0xB0,  0x00,  0x02,  0x7F,  0xE2,  0x08,  0x22,  0x0A,  0x22,  0x11,  0x22, 	/* 27200 */
+	0x13,  0x22,  0x7C,  0xA2,  0x04,  0xA2,  0x04,  0x22,  0x3F,  0xA2,  0x04,  0x22,  0x04,  0x02,  0x04,  0x02, 	/* 27210 */
+	0x07,  0x82,  0x78,  0x02,  0x00,  0x06,  0xB3,  0x04,  0x02,  0x04,  0x12,  0x7F,  0xD2,  0x0A,  0x12,  0x11, 	/* 27220 */
+	0x12,  0x20,  0x92,  0x5F,  0x52,  0x00,  0x12,  0x7F,  0xD2,  0x08,  0x12,  0x08,  0x12,  0x1F,  0x02,  0x11, 	/* 27230 */
+	0x02,  0x01,  0x02,  0x01,  0x02,  0x06,  0x06,  0xB6,  0x02,  0x02,  0x12,  0x12,  0x12,  0x12,  0x1F,  0xD2, 	/* 27240 */
+	0x22,  0x12,  0x22,  0x12,  0x7F,  0xF2,  0x02,  0x12,  0x1F,  0xD2,  0x12,  0x52,  0x12,  0x52,  0x12,  0x52, 	/* 27250 */
+	0x12,  0x42,  0x13,  0x82,  0x12,  0x02,  0x02,  0x06,  0xB7,  0x00,  0x02,  0x3F,  0x92,  0x20,  0x92,  0x20, 	/* 27260 */
+	0x92,  0x3F,  0x92,  0x24,  0x12,  0x24,  0x12,  0x3F,  0x92,  0x34,  0x92,  0x34,  0x92,  0x54,  0x92,  0x54, 	/* 27270 */
+	0x92,  0x94,  0x82,  0x15,  0x82,  0x14,  0x02,  0x04,  0x06,  0xB8,  0x08,  0x88,  0x04,  0x88,  0x04,  0x90, 	/* 27280 */
+	0x1F,  0xFE,  0x00,  0x80,  0x01,  0x40,  0x7F,  0xFF,  0x02,  0x20,  0x04,  0x10,  0x1F,  0xFC,  0x61,  0x13, 	/* 27290 */
+	0x01,  0x10,  0x02,  0x10,  0x02,  0x10,  0x04,  0x10,  0x18,  0x60,  0xB9,  0x02,  0x02,  0x02,  0x22,  0x34, 	/* 272A0 */
+	0x22,  0x0C,  0x22,  0x0A,  0x22,  0x11,  0x22,  0x25,  0x22,  0x44,  0x22,  0x7F,  0xA2,  0x04,  0x22,  0x0E, 	/* 272B0 */
+	0x22,  0x15,  0x02,  0x24,  0x82,  0x44,  0x02,  0x04,  0x02,  0x04,  0x06,  0xBA,  0x04,  0x02,  0x04,  0x12, 	/* 272C0 */
+	0x7F,  0xD2,  0x04,  0x12,  0x04,  0x12,  0x3F,  0x92,  0x24,  0x92,  0x24,  0x92,  0x25,  0x92,  0x2E,  0x12, 	/* 272D0 */
+	0x0D,  0x12,  0x14,  0x92,  0x14,  0x82,  0x24,  0x02,  0x44,  0x02,  0x04,  0x06,  0xBB,  0x04,  0x02,  0x04, 	/* 272E0 */
+	0x22,  0x7F,  0xE2,  0x04,  0x22,  0x04,  0x22,  0x39,  0x22,  0x0A,  0x22,  0x06,  0x22,  0x04,  0xA2,  0x08, 	/* 272F0 */
+	0xA2,  0x11,  0x22,  0x23,  0x02,  0x04,  0x82,  0x08,  0x42,  0x10,  0x42,  0x60,  0x06,  0x83,  0x11,  0x02, 	/* 27300 */
+	0x0A,  0x12,  0x7F,  0x92,  0x04,  0x92,  0x04,  0x92,  0x3F,  0x92,  0x24,  0x12,  0x24,  0x12,  0x3F,  0xD2, 	/* 27310 */
+	0x04,  0x52,  0x0C,  0x52,  0x0C,  0x42,  0x14,  0x42,  0x25,  0x82,  0x44,  0x02,  0x04,  0x06,  0x84,  0x00, 	/* 27320 */
+	0x02,  0x7F,  0x92,  0x00,  0x12,  0x12,  0x52,  0x12,  0x52,  0x6D,  0x92,  0x24,  0x92,  0x12,  0x52,  0x00, 	/* 27330 */
+	0x12,  0x7F,  0xD2,  0x04,  0x12,  0x04,  0x02,  0x04,  0x02,  0x05,  0x82,  0x1E,  0x02,  0x60,  0x06,  0x87, 	/* 27340 */
+	0x00,  0x02,  0x3F,  0x22,  0x21,  0x22,  0x21,  0x22,  0x3F,  0x22,  0x21,  0x22,  0x21,  0x22,  0x21,  0x22, 	/* 27350 */
+	0x3F,  0x22,  0x21,  0x22,  0x21,  0x22,  0x3F,  0x22,  0x12,  0x22,  0x11,  0x02,  0x21,  0x02,  0x40,  0x06, 	/* 27360 */
+	0x8A,  0x08,  0x02,  0x49,  0x22,  0x29,  0x22,  0x2A,  0x22,  0x08,  0x22,  0x3F,  0x22,  0x21,  0x22,  0x21, 	/* 27370 */
+	0x22,  0x3F,  0x22,  0x21,  0x22,  0x21,  0x22,  0x3F,  0x22,  0x21,  0x02,  0x21,  0x02,  0x21,  0x02,  0x23, 	/* 27380 */
+	0x06,  0x8B,  0x04,  0x04,  0x04,  0x24,  0x7F,  0xE4,  0x04,  0x24,  0x04,  0x24,  0x3F,  0xA4,  0x20,  0xA4, 	/* 27390 */
+	0x20,  0xA4,  0x20,  0xA4,  0x3F,  0xA4,  0x0A,  0x04,  0x0A,  0x04,  0x0A,  0x0C,  0x12,  0x01,  0x21,  0x01, 	/* 273A0 */
+	0x40,  0xFF,  0x8C,  0x04,  0x02,  0x04,  0x12,  0x7F,  0xD2,  0x04,  0x12,  0x04,  0x12,  0x3F,  0x92,  0x24, 	/* 273B0 */
+	0x92,  0x24,  0x92,  0x24,  0x92,  0x3F,  0x92,  0x0C,  0x12,  0x0E,  0x02,  0x15,  0x02,  0x24,  0x82,  0x44, 	/* 273C0 */
+	0x02,  0x04,  0x06,  0x8D,  0x08,  0x10,  0x04,  0x10,  0x04,  0x20,  0x7F,  0xFF,  0x00,  0x00,  0x3E,  0x44, 	/* 273D0 */
+	0x22,  0x44,  0x22,  0x44,  0x3E,  0x44,  0x22,  0x44,  0x22,  0x44,  0x3E,  0x44,  0x22,  0x44,  0x22,  0x04, 	/* 273E0 */
+	0x22,  0x04,  0x26,  0x0C,  0x8F,  0x21,  0x00,  0x11,  0x7E,  0x12,  0x12,  0x7F,  0x92,  0x12,  0x12,  0x12, 	/* 273F0 */
+	0x12,  0x12,  0x52,  0x7F,  0xB2,  0x12,  0x12,  0x12,  0x1A,  0x12,  0x16,  0x12,  0x23,  0x12,  0x22,  0x22, 	/* 27400 */
+	0x42,  0x22,  0x82,  0x43,  0x0C,  0x94,  0x00,  0x02,  0x1F,  0x92,  0x10,  0x92,  0x1F,  0x92,  0x10,  0x92, 	/* 27410 */
+	0x10,  0x92,  0x1F,  0x92,  0x08,  0x12,  0x0F,  0xD2,  0x15,  0x52,  0x25,  0x52,  0x49,  0x42,  0x12,  0x42, 	/* 27420 */
+	0x24,  0x42,  0x08,  0x42,  0x01,  0x86,  0x96,  0x04,  0x02,  0x04,  0x12,  0x3F,  0xD2,  0x10,  0x92,  0x08, 	/* 27430 */
+	0x92,  0x09,  0x12,  0x09,  0x12,  0x7F,  0xF2,  0x00,  0x12,  0x00,  0x12,  0x1F,  0x92,  0x10,  0x92,  0x10, 	/* 27440 */
+	0x82,  0x10,  0x82,  0x1F,  0x82,  0x00,  0x06,  0x9B,  0x00,  0x02,  0x3F,  0xD2,  0x20,  0x52,  0x31,  0x52, 	/* 27450 */
+	0x2A,  0x52,  0x20,  0x52,  0x3F,  0xD2,  0x24,  0x52,  0x35,  0x52,  0x35,  0x52,  0x35,  0x52,  0x3F,  0x42, 	/* 27460 */
+	0x31,  0x42,  0x20,  0x42,  0x20,  0x42,  0x20,  0xC6,  0x9E,  0x04,  0x02,  0x04,  0x12,  0x7F,  0xD2,  0x04, 	/* 27470 */
+	0x12,  0x0A,  0x12,  0x31,  0x12,  0x00,  0x12,  0x7F,  0xF2,  0x00,  0x92,  0x3C,  0x92,  0x24,  0x92,  0x24, 	/* 27480 */
+	0x82,  0x3C,  0x82,  0x00,  0x82,  0x00,  0x82,  0x01,  0x86,  0xA3,  0x04,  0x02,  0x04,  0x12,  0x0A,  0x12, 	/* 27490 */
+	0x09,  0x12,  0x10,  0x92,  0x3F,  0x52,  0x44,  0x12,  0x3F,  0x92,  0x24,  0x92,  0x24,  0x92,  0x3F,  0x92, 	/* 274A0 */
+	0x06,  0x12,  0x05,  0x02,  0x08,  0x82,  0x10,  0x82,  0x60,  0x06,  0xA4,  0x04,  0x02,  0x04,  0x12,  0x7F, 	/* 274B0 */
+	0xF2,  0x11,  0x12,  0x0A,  0x12,  0x06,  0x12,  0x19,  0x92,  0x70,  0xF2,  0x10,  0x92,  0x1F,  0x92,  0x10, 	/* 274C0 */
+	0x92,  0x1F,  0x82,  0x10,  0x82,  0x20,  0x82,  0x20,  0x82,  0x40,  0x86,  0xA5,  0x00,  0x02,  0x3F,  0x12, 	/* 274D0 */
+	0x01,  0x12,  0x3F,  0x12,  0x01,  0x12,  0x01,  0x12,  0x7F,  0xD2,  0x04,  0x12,  0x44,  0x92,  0x27,  0x12, 	/* 274E0 */
+	0x26,  0x12,  0x0D,  0x02,  0x14,  0x82,  0x64,  0x42,  0x04,  0x02,  0x0C,  0x06,  0xA9,  0x01,  0x02,  0x3E, 	/* 274F0 */
+	0x12,  0x04,  0x12,  0x7F,  0xD2,  0x04,  0x12,  0x15,  0x52,  0x75,  0x92,  0x15,  0x12,  0x35,  0x52,  0x54, 	/* 27500 */
+	0xD2,  0x0E,  0x12,  0x0D,  0x02,  0x14,  0x82,  0x24,  0x42,  0x44,  0x02,  0x04,  0x06,  0xAA,  0x04,  0x10, 	/* 27510 */
+	0x02,  0x20,  0x7F,  0xFF,  0x11,  0x04,  0x1D,  0x24,  0x13,  0x24,  0x1D,  0x24,  0x13,  0x24,  0x11,  0x24, 	/* 27520 */
+	0x13,  0x0C,  0x00,  0x00,  0x7F,  0xFE,  0x01,  0x02,  0x02,  0x02,  0x0C,  0x02,  0x70,  0x0C,  0xAF,  0x00, 	/* 27530 */
+	0x02,  0x7F,  0xD2,  0x00,  0x12,  0x1F,  0x12,  0x11,  0x12,  0x11,  0x12,  0x1F,  0x12,  0x00,  0x12,  0x3F, 	/* 27540 */
+	0x92,  0x24,  0x92,  0x24,  0x92,  0x3F,  0x92,  0x24,  0x82,  0x24,  0x82,  0x3F,  0x82,  0x00,  0x06,  0xB0, 	/* 27550 */
+	0x01,  0x02,  0x1E,  0x12,  0x04,  0x12,  0x3F,  0xD2,  0x14,  0x92,  0x14,  0x92,  0x7F,  0xF2,  0x14,  0x92, 	/* 27560 */
+	0x14,  0x92,  0x3F,  0xD2,  0x0E,  0x12,  0x0D,  0x12,  0x14,  0x82,  0x24,  0x42,  0x44,  0x02,  0x04,  0x06, 	/* 27570 */
+	0xB1,  0x04,  0x00,  0x04,  0x7E,  0x0A,  0x12,  0x11,  0x12,  0x3F,  0x92,  0x44,  0x52,  0x04,  0x12,  0x3F, 	/* 27580 */
+	0xB2,  0x24,  0x92,  0x24,  0x9A,  0x3F,  0x96,  0x04,  0x13,  0x0A,  0x12,  0x11,  0x22,  0x21,  0x42,  0x40, 	/* 27590 */
+	0x8C,  0xB2,  0x04,  0x02,  0x7F,  0xD2,  0x40,  0x52,  0x44,  0x52,  0x3F,  0x92,  0x04,  0x12,  0x3F,  0x92, 	/* 275A0 */
+	0x04,  0x12,  0x7F,  0xD2,  0x00,  0x12,  0x1F,  0x92,  0x10,  0x92,  0x10,  0x82,  0x10,  0x82,  0x1F,  0x82, 	/* 275B0 */
+	0x00,  0x06,  0xB3,  0x11,  0x02,  0x11,  0x12,  0x7F,  0xD2,  0x11,  0x12,  0x04,  0x12,  0x04,  0x12,  0x0A, 	/* 275C0 */
+	0x12,  0x11,  0x12,  0x3F,  0x92,  0x40,  0x52,  0x00,  0x12,  0x3F,  0x82,  0x20,  0x82,  0x20,  0x82,  0x3F, 	/* 275D0 */
+	0x82,  0x00,  0x06,  0xB4,  0x04,  0x02,  0x24,  0x92,  0x24,  0x92,  0x3F,  0x92,  0x00,  0x12,  0x7F,  0xD2, 	/* 275E0 */
+	0x00,  0x12,  0x3F,  0x92,  0x20,  0x92,  0x20,  0x92,  0x3F,  0x92,  0x11,  0x02,  0x09,  0x02,  0x0A,  0xC2, 	/* 275F0 */
+	0x0F,  0x02,  0x70,  0x06,  0xB5,  0x02,  0x02,  0x02,  0x12,  0x05,  0x12,  0x08,  0x92,  0x1F,  0x52,  0x20, 	/* 27600 */
+	0x32,  0x5F,  0x92,  0x10,  0x92,  0x1F,  0x92,  0x10,  0x92,  0x1F,  0x92,  0x10,  0x12,  0x2F,  0x82,  0x28, 	/* 27610 */
+	0x82,  0x4F,  0x82,  0x00,  0x06,  0xBD,  0x00,  0x02,  0x7F,  0xF2,  0x09,  0x12,  0x3F,  0xD2,  0x29,  0x52, 	/* 27620 */
+	0x29,  0x52,  0x3F,  0xD2,  0x00,  0x12,  0x3F,  0xD2,  0x00,  0x12,  0x7F,  0xF2,  0x12,  0x92,  0x12,  0x42, 	/* 27630 */
+	0x22,  0x42,  0x42,  0x02,  0x06,  0x06,  0xBF,  0x12,  0x82,  0x24,  0x92,  0x6D,  0x12,  0x12,  0x92,  0x3F, 	/* 27640 */
+	0x92,  0x24,  0x92,  0x3F,  0x92,  0x24,  0x92,  0x3F,  0x92,  0x04,  0x12,  0x7F,  0xD2,  0x0E,  0x02,  0x15, 	/* 27650 */
+	0x02,  0x24,  0x82,  0x44,  0x42,  0x04,  0x06,  0x83,  0x04,  0x02,  0x3F,  0x92,  0x04,  0x92,  0x7F,  0xF2, 	/* 27660 */
+	0x04,  0x92,  0x3F,  0x92,  0x04,  0x12,  0x1F,  0x12,  0x7F,  0xD2,  0x24,  0x92,  0x3F,  0x92,  0x24,  0x92, 	/* 27670 */
+	0x3F,  0x82,  0x00,  0x02,  0x7F,  0xC2,  0x00,  0x06,  0x87,  0x04,  0x02,  0x07,  0x92,  0x04,  0x12,  0x3F, 	/* 27680 */
+	0xD2,  0x25,  0x52,  0x3E,  0x12,  0x24,  0x92,  0x23,  0x92,  0x3F,  0xD2,  0x26,  0x12,  0x3A,  0x52,  0x25, 	/* 27690 */
+	0x42,  0x3B,  0x82,  0x25,  0x42,  0x59,  0x22,  0x06,  0x06,  0x88,  0x00,  0x08,  0x1F,  0x08,  0x11,  0x7F, 	/* 276A0 */
+	0x11,  0x22,  0x1F,  0x14,  0x10,  0xFF,  0x1F,  0x08,  0x29,  0x7F,  0x29,  0x08,  0x4F,  0x08,  0x00,  0x00, 	/* 276B0 */
+	0x7F,  0xFE,  0x00,  0x82,  0x03,  0x02,  0x0C,  0x02,  0x70,  0x1C,  0x89,  0x08,  0x02,  0x33,  0xC2,  0x21, 	/* 276C0 */
+	0x52,  0x29,  0x52,  0x3A,  0x52,  0x65,  0xD2,  0x04,  0x12,  0x0B,  0x12,  0x10,  0xD2,  0x7F,  0x12,  0x04, 	/* 276D0 */
+	0x12,  0x7F,  0xD2,  0x04,  0x82,  0x25,  0x02,  0x17,  0x82,  0x78,  0x06,  0x8D,  0x04,  0x02,  0x04,  0x12, 	/* 276E0 */
+	0x0A,  0x12,  0x11,  0x12,  0x20,  0x92,  0x5F,  0x52,  0x00,  0x12,  0x3B,  0x92,  0x2A,  0x92,  0x2A,  0x92, 	/* 276F0 */
+	0x3B,  0x92,  0x11,  0x12,  0x19,  0x82,  0x26,  0x42,  0x22,  0x02,  0x44,  0x06,  0x91,  0x04,  0x02,  0x04, 	/* 27700 */
+	0x12,  0x7F,  0xF2,  0x0A,  0x52,  0x75,  0x92,  0x35,  0x52,  0x35,  0x52,  0x55,  0xB2,  0x00,  0x12,  0x10, 	/* 27710 */
+	0x92,  0x1F,  0x92,  0x10,  0x82,  0x1F,  0x82,  0x10,  0x82,  0x20,  0x82,  0x40,  0x86,  0x92,  0x04,  0x00, 	/* 27720 */
+	0x04,  0x7E,  0x0A,  0x12,  0x11,  0x12,  0x20,  0x92,  0x5F,  0x12,  0x00,  0x32,  0x3B,  0xB2,  0x2A,  0xD2, 	/* 27730 */
+	0x2A,  0x92,  0x3B,  0x92,  0x11,  0x12,  0x19,  0xA2,  0x26,  0x62,  0x22,  0x42,  0x44,  0x8C,  0x94,  0x04, 	/* 27740 */
+	0x00,  0x04,  0x7E,  0x0A,  0x12,  0x11,  0x12,  0x20,  0x92,  0x5F,  0x12,  0x00,  0x52,  0x3B,  0xB2,  0x2A, 	/* 27750 */
+	0x92,  0x2A,  0x9A,  0x3B,  0x97,  0x11,  0x12,  0x19,  0xA2,  0x26,  0x62,  0x22,  0x42,  0x44,  0x8C,  0x9B, 	/* 27760 */
+	0x01,  0x00,  0x01,  0x00,  0x01,  0x00,  0x01,  0x00,  0x7F,  0xFC,  0x01,  0x04,  0x01,  0x04,  0x01,  0x04, 	/* 27770 */
+	0x02,  0x04,  0x02,  0x04,  0x02,  0x04,  0x04,  0x04,  0x04,  0x04,  0x08,  0x04,  0x10,  0x08,  0x20,  0x30, 	/* 27780 */
+	0x9F,  0x00,  0x20,  0x00,  0x20,  0x00,  0x20,  0x7E,  0x20,  0x09,  0xFE,  0x08,  0x22,  0x08,  0x22,  0x08, 	/* 27790 */
+	0x22,  0x08,  0x22,  0x08,  0x22,  0x0E,  0x42,  0x18,  0x42,  0x60,  0x42,  0x00,  0x82,  0x01,  0x04,  0x02, 	/* 277A0 */
+	0x18,  0xA0,  0x08,  0x00,  0x08,  0x00,  0x08,  0x3E,  0x08,  0x22,  0x7F,  0xA2,  0x08,  0xA2,  0x08,  0xA2, 	/* 277B0 */
+	0x08,  0xA2,  0x08,  0xA2,  0x08,  0xA2,  0x08,  0xA2,  0x08,  0xA2,  0x10,  0xA2,  0x10,  0xBE,  0x20,  0x80, 	/* 277C0 */
+	0x43,  0x00,  0xA3,  0x00,  0x80,  0x04,  0x90,  0x04,  0x88,  0x08,  0x84,  0x10,  0x94,  0x21,  0xA2,  0x00, 	/* 277D0 */
+	0xC2,  0x07,  0x40,  0x78,  0x40,  0x00,  0x40,  0x1F,  0xFC,  0x00,  0x84,  0x01,  0x04,  0x02,  0x04,  0x0C, 	/* 277E0 */
+	0x04,  0x30,  0x18,  0xA9,  0x00,  0x20,  0x3E,  0x20,  0x22,  0x20,  0x22,  0x20,  0x23,  0xFE,  0x3E,  0x22, 	/* 277F0 */
+	0x22,  0x22,  0x22,  0x22,  0x3E,  0x22,  0x22,  0x22,  0x22,  0x42,  0x23,  0x42,  0x26,  0x42,  0x38,  0x82, 	/* 27800 */
+	0x61,  0x04,  0x02,  0x18,  0xAA,  0x04,  0x00,  0x04,  0x00,  0x7F,  0xFC,  0x09,  0x44,  0x09,  0x44,  0x11, 	/* 27810 */
+	0x28,  0x3E,  0x10,  0x05,  0x68,  0x18,  0x86,  0x60,  0x80,  0x1F,  0xF8,  0x00,  0x88,  0x01,  0x08,  0x02, 	/* 27820 */
+	0x08,  0x0C,  0x08,  0x30,  0x30,  0xAB,  0x04,  0x10,  0x04,  0x10,  0x04,  0x10,  0x3F,  0x90,  0x04,  0x7E, 	/* 27830 */
+	0x04,  0x12,  0x04,  0x12,  0x04,  0x12,  0x7F,  0x92,  0x04,  0x12,  0x04,  0x12,  0x0A,  0x22,  0x09,  0x22, 	/* 27840 */
+	0x13,  0x22,  0x7C,  0xC2,  0x00,  0x8C,  0xAC,  0x08,  0x10,  0x08,  0x10,  0x08,  0x10,  0x1F,  0x90,  0x10, 	/* 27850 */
+	0xFE,  0x20,  0x92,  0x3E,  0x92,  0x52,  0x92,  0x12,  0x92,  0x12,  0x92,  0x12,  0x92,  0x1E,  0xA2,  0x00, 	/* 27860 */
+	0xA2,  0x00,  0xA2,  0x01,  0x42,  0x06,  0x8C,  0xAD,  0x00,  0x10,  0x7F,  0x90,  0x08,  0x90,  0x08,  0x90, 	/* 27870 */
+	0x08,  0xFE,  0x10,  0x92,  0x20,  0x92,  0x43,  0x12,  0x00,  0x12,  0x3F,  0x12,  0x21,  0x12,  0x21,  0x22, 	/* 27880 */
+	0x21,  0x22,  0x21,  0x22,  0x3F,  0x42,  0x00,  0x8C,  0xB1,  0x00,  0x10,  0x1F,  0xD0,  0x10,  0x10,  0x10, 	/* 27890 */
+	0x10,  0x1F,  0xFE,  0x14,  0x12,  0x14,  0x12,  0x17,  0x92,  0x14,  0x92,  0x14,  0x92,  0x14,  0x92,  0x14, 	/* 278A0 */
+	0x92,  0x28,  0xA2,  0x28,  0xA2,  0x51,  0x42,  0x06,  0x8C,  0xB4,  0x11,  0x04,  0x08,  0x84,  0x08,  0x88, 	/* 278B0 */
+	0x08,  0x90,  0x7F,  0xFE,  0x40,  0x02,  0x41,  0x02,  0x01,  0x00,  0x3F,  0xF8,  0x01,  0x08,  0x01,  0x08, 	/* 278C0 */
+	0x02,  0x08,  0x02,  0x08,  0x04,  0x08,  0x18,  0x08,  0x60,  0x30,  0xB5,  0x04,  0x90,  0x04,  0x88,  0x08, 	/* 278D0 */
+	0x88,  0x3F,  0xFE,  0x00,  0x80,  0x01,  0x40,  0x7F,  0xFF,  0x02,  0x20,  0x04,  0x90,  0x18,  0x8C,  0x6F, 	/* 278E0 */
+	0xF3,  0x01,  0x10,  0x01,  0x10,  0x02,  0x10,  0x0C,  0x10,  0x30,  0x60,  0xB9,  0x04,  0x10,  0x04,  0x10, 	/* 278F0 */
+	0x04,  0x10,  0x7F,  0x90,  0x12,  0x7E,  0x11,  0x12,  0x11,  0x12,  0x29,  0x92,  0x2A,  0x12,  0x46,  0x12, 	/* 27900 */
+	0x02,  0x22,  0x05,  0x22,  0x09,  0x42,  0x10,  0x42,  0x20,  0x82,  0x41,  0x0C,  0xBC,  0x08,  0x10,  0x08, 	/* 27910 */
+	0x10,  0x08,  0x10,  0x7F,  0x90,  0x08,  0xFE,  0x08,  0x12,  0x08,  0x12,  0x3F,  0x12,  0x00,  0x12,  0x00, 	/* 27920 */
+	0x12,  0x3F,  0x12,  0x21,  0x22,  0x21,  0x22,  0x21,  0x42,  0x3F,  0x82,  0x01,  0x0C,  0xBE,  0x04,  0x10, 	/* 27930 */
+	0x04,  0x10,  0x04,  0x10,  0x7F,  0xFE,  0x08,  0x12,  0x0A,  0x12,  0x72,  0x12,  0x14,  0x92,  0x0C,  0x92, 	/* 27940 */
+	0x09,  0x12,  0x11,  0x22,  0x22,  0x22,  0x05,  0x22,  0x08,  0xC2,  0x10,  0x82,  0x61,  0x0C,  0x81,  0x00, 	/* 27950 */
+	0x10,  0x7F,  0x90,  0x00,  0x10,  0x15,  0x10,  0x15,  0x7E,  0x2A,  0x12,  0x6A,  0x12,  0x15,  0x12,  0x15, 	/* 27960 */
+	0x12,  0x00,  0x12,  0x7F,  0x12,  0x08,  0x22,  0x08,  0x22,  0x0B,  0x22,  0x1C,  0x42,  0x60,  0x8C,  0x83, 	/* 27970 */
+	0x04,  0x10,  0x04,  0x10,  0x3F,  0x10,  0x04,  0x10,  0x04,  0x7E,  0x7F,  0x92,  0x40,  0x92,  0x5E,  0x92, 	/* 27980 */
+	0x02,  0x12,  0x04,  0x12,  0x07,  0xA2,  0x7C,  0x22,  0x04,  0x22,  0x04,  0x42,  0x04,  0x82,  0x0D,  0x0C, 	/* 27990 */
+	0x85,  0x04,  0x10,  0x04,  0x10,  0x7F,  0xD0,  0x04,  0x10,  0x04,  0xFE,  0x3F,  0x92,  0x24,  0x92,  0x24, 	/* 279A0 */
+	0x92,  0x3F,  0x92,  0x0C,  0x12,  0x0E,  0x12,  0x15,  0x22,  0x14,  0xA2,  0x24,  0x42,  0x44,  0x82,  0x05, 	/* 279B0 */
+	0x0C,  0x87,  0x00,  0x00,  0x1F,  0xF0,  0x06,  0x40,  0x01,  0x80,  0x1F,  0xF8,  0x11,  0x08,  0x1F,  0xF8, 	/* 279C0 */
+	0x11,  0x08,  0x11,  0x08,  0x1F,  0xF8,  0x01,  0x00,  0x7F,  0xFC,  0x01,  0x04,  0x02,  0x04,  0x0C,  0x04, 	/* 279D0 */
+	0x70,  0x38,  0x89,  0x08,  0x10,  0x08,  0x10,  0x1E,  0x10,  0x12,  0x10,  0x24,  0x10,  0x7F,  0xFE,  0x24, 	/* 279E0 */
+	0x92,  0x24,  0x92,  0x24,  0x92,  0x3F,  0x92,  0x0A,  0x22,  0x0A,  0x22,  0x12,  0x44,  0x12,  0x99,  0x21, 	/* 279F0 */
+	0x01,  0x40,  0xFF,  0x8D,  0x04,  0x10,  0x04,  0x10,  0x04,  0x10,  0x7F,  0x90,  0x00,  0x7E,  0x1F,  0x12, 	/* 27A00 */
+	0x11,  0x12,  0x11,  0x12,  0x11,  0x12,  0x1F,  0x12,  0x04,  0x22,  0x16,  0x22,  0x15,  0x22,  0x25,  0x42, 	/* 27A10 */
+	0x44,  0x82,  0x0D,  0x0C,  0x92,  0x12,  0x10,  0x12,  0x10,  0x7F,  0x10,  0x12,  0x10,  0x12,  0xFE,  0x1E, 	/* 27A20 */
+	0x12,  0x08,  0x12,  0x3F,  0x12,  0x29,  0x12,  0x29,  0x12,  0x3F,  0x12,  0x08,  0x22,  0x7F,  0xA2,  0x08, 	/* 27A30 */
+	0x42,  0x08,  0x82,  0x09,  0x1C,  0x95,  0x01,  0x90,  0x1E,  0x10,  0x04,  0x10,  0x7F,  0xD0,  0x04,  0x7E, 	/* 27A40 */
+	0x1F,  0x92,  0x14,  0x92,  0x1F,  0x92,  0x14,  0x92,  0x14,  0x92,  0x1F,  0x92,  0x04,  0x12,  0x3F,  0x22, 	/* 27A50 */
+	0x05,  0xA2,  0x0E,  0x42,  0x70,  0x8C,  0x97,  0x00,  0x00,  0x1F,  0xF8,  0x10,  0x08,  0x1F,  0xF8,  0x10, 	/* 27A60 */
+	0x08,  0x1F,  0xF8,  0x00,  0x10,  0x1F,  0x10,  0x11,  0xFE,  0x1F,  0x12,  0x11,  0x12,  0x1F,  0x22,  0x11, 	/* 27A70 */
+	0xA2,  0x1F,  0x42,  0x70,  0x82,  0x01,  0x0C,  0x98,  0x11,  0x10,  0x11,  0x10,  0x7F,  0x90,  0x11,  0x10, 	/* 27A80 */
+	0x1F,  0x7E,  0x11,  0x12,  0x1F,  0x12,  0x11,  0x12,  0x7F,  0x92,  0x2A,  0x12,  0x2A,  0x12,  0x2A,  0xA2, 	/* 27A90 */
+	0x31,  0xA2,  0x20,  0x22,  0x3F,  0x42,  0x00,  0x8C,  0x99,  0x00,  0x40,  0x3F,  0x40,  0x02,  0x7F,  0x14, 	/* 27AA0 */
+	0x84,  0x09,  0x44,  0x08,  0x28,  0x7F,  0x10,  0x0A,  0x6C,  0x0B,  0xA3,  0x1C,  0x20,  0x19,  0xFC,  0x28, 	/* 27AB0 */
+	0x24,  0x28,  0x24,  0x48,  0x44,  0x08,  0x84,  0x19,  0x18,  0x9D,  0x00,  0x20,  0x3D,  0x24,  0x24,  0xA8, 	/* 27AC0 */
+	0x24,  0x20,  0x25,  0xFE,  0x3C,  0x20,  0x24,  0x30,  0x27,  0xFF,  0x24,  0x48,  0x3C,  0xA4,  0x25,  0xFE, 	/* 27AD0 */
+	0x26,  0x25,  0x24,  0x24,  0x24,  0x44,  0x24,  0x84,  0x4D,  0x18,  0x9E,  0x04,  0x10,  0x15,  0x54,  0x15, 	/* 27AE0 */
+	0x54,  0x2A,  0x28,  0x11,  0x44,  0x20,  0x80,  0x7F,  0xFE,  0x41,  0x02,  0x41,  0x02,  0x3F,  0xF8,  0x01, 	/* 27AF0 */
+	0x08,  0x01,  0x08,  0x02,  0x08,  0x04,  0x08,  0x18,  0x08,  0x60,  0x30,  0x9F,  0x02,  0x20,  0x7F,  0xFF, 	/* 27B00 */
+	0x02,  0x20,  0x0F,  0xF8,  0x08,  0x08,  0x0F,  0xF8,  0x08,  0x08,  0x0F,  0xF8,  0x01,  0x00,  0x7F,  0xFF, 	/* 27B10 */
+	0x04,  0x90,  0x1F,  0xFC,  0x61,  0x13,  0x02,  0x10,  0x0C,  0x10,  0x30,  0x60,  0xA0,  0x00,  0x10,  0x7F, 	/* 27B20 */
+	0x90,  0x2A,  0x90,  0x4C,  0x90,  0x19,  0xFE,  0x6A,  0x92,  0x0C,  0x92,  0x0A,  0x12,  0x11,  0x12,  0x64, 	/* 27B30 */
+	0x92,  0x0A,  0x12,  0x34,  0x92,  0x09,  0x22,  0x32,  0x22,  0x0C,  0x42,  0x70,  0x8C,  0xA2,  0x04,  0x10, 	/* 27B40 */
+	0x3F,  0x10,  0x04,  0x10,  0x7F,  0xFC,  0x15,  0x14,  0x15,  0xD4,  0x3F,  0x24,  0x44,  0xB4,  0x07,  0x4D, 	/* 27B50 */
+	0x79,  0x85,  0x01,  0x03,  0x3F,  0xF8,  0x01,  0x08,  0x02,  0x08,  0x0C,  0x08,  0x30,  0x30,  0xA3,  0x04, 	/* 27B60 */
+	0x10,  0x3F,  0x10,  0x04,  0x10,  0x3F,  0x10,  0x04,  0x7E,  0x7F,  0x92,  0x00,  0x12,  0x1F,  0x12,  0x11, 	/* 27B70 */
+	0x12,  0x1F,  0x12,  0x11,  0x12,  0x1F,  0x12,  0x11,  0x22,  0x1F,  0x22,  0x19,  0x42,  0x60,  0x8C,  0xA4, 	/* 27B80 */
+	0x11,  0x10,  0x11,  0x10,  0x7F,  0xD0,  0x11,  0x10,  0x00,  0x7E,  0x3F,  0x92,  0x24,  0x92,  0x24,  0x92, 	/* 27B90 */
+	0x3F,  0x92,  0x04,  0x12,  0x3F,  0x92,  0x04,  0x22,  0x3F,  0xA2,  0x04,  0x22,  0x07,  0x42,  0x78,  0x8C, 	/* 27BA0 */
+	0xA6,  0x12,  0x90,  0x24,  0x90,  0x6D,  0x10,  0x12,  0x90,  0x3F,  0xFE,  0x24,  0x92,  0x3F,  0x92,  0x24, 	/* 27BB0 */
+	0x92,  0x3F,  0x92,  0x04,  0x12,  0x7F,  0xD2,  0x0D,  0x12,  0x14,  0xA2,  0x24,  0x22,  0x44,  0x42,  0x04, 	/* 27BC0 */
+	0x8C,  0xA7,  0x10,  0x10,  0x10,  0x10,  0x1F,  0x90,  0x24,  0x10,  0x24,  0x7E,  0x5F,  0x92,  0x09,  0x12, 	/* 27BD0 */
+	0x12,  0x12,  0x3F,  0x92,  0x52,  0x12,  0x1F,  0x22,  0x12,  0x22,  0x1F,  0x22,  0x12,  0x42,  0x1F,  0xC2, 	/* 27BE0 */
+	0x00,  0x8C,  0xB2,  0x01,  0x10,  0x3E,  0x10,  0x04,  0x10,  0x7F,  0x90,  0x04,  0x7E,  0x3F,  0x12,  0x25, 	/* 27BF0 */
+	0x12,  0x3F,  0x12,  0x25,  0x12,  0x3F,  0x22,  0x1E,  0x22,  0x07,  0x4C,  0x78,  0x00,  0x12,  0x24,  0x21, 	/* 27C00 */
+	0x12,  0x41,  0x11,  0xB3,  0x02,  0x10,  0x3C,  0x10,  0x08,  0x10,  0x7F,  0x90,  0x08,  0x7E,  0x3F,  0x12, 	/* 27C10 */
+	0x3B,  0x12,  0x2D,  0x12,  0x3F,  0x12,  0x08,  0x12,  0x3F,  0x12,  0x08,  0x12,  0x7F,  0xA2,  0x35,  0x22, 	/* 27C20 */
+	0x2A,  0x42,  0x4A,  0x8C,  0xB5,  0x00,  0x08,  0x3F,  0xC8,  0x25,  0x08,  0x3F,  0xC8,  0x25,  0x7E,  0x2F, 	/* 27C30 */
+	0x8A,  0x2A,  0x8A,  0x2F,  0x8A,  0x2A,  0x8A,  0x2F,  0x8A,  0x22,  0x0A,  0x3F,  0xD2,  0x35,  0x52,  0x5E, 	/* 27C40 */
+	0xE2,  0x10,  0x42,  0x10,  0xCC,  0xB8,  0x09,  0x10,  0x7F,  0xD0,  0x09,  0x10,  0x3B,  0x90,  0x2A,  0xFE, 	/* 27C50 */
+	0x3B,  0x92,  0x12,  0x12,  0x14,  0x12,  0x3F,  0x92,  0x64,  0x12,  0x3F,  0x12,  0x24,  0x12,  0x3F,  0x22, 	/* 27C60 */
+	0x24,  0x22,  0x3F,  0xC2,  0x00,  0x8C,  0xB9,  0x08,  0x00,  0x08,  0x00,  0x0F,  0xFE,  0x08,  0x02,  0x10, 	/* 27C70 */
+	0x02,  0x10,  0x02,  0x20,  0x02,  0x40,  0x02,  0x00,  0x02,  0x00,  0x02,  0x00,  0x02,  0x00,  0x02,  0x00, 	/* 27C80 */
+	0x02,  0x00,  0x02,  0x00,  0x04,  0x00,  0x38,  0xBA,  0x04,  0x00,  0x04,  0x00,  0x04,  0x00,  0x07,  0xFE, 	/* 27C90 */
+	0x08,  0x02,  0x08,  0x02,  0x10,  0x02,  0x23,  0x02,  0x40,  0x82,  0x00,  0x42,  0x00,  0x42,  0x00,  0x02, 	/* 27CA0 */
+	0x00,  0x02,  0x00,  0x02,  0x00,  0x04,  0x00,  0x18,  0xBE,  0x08,  0x00,  0x08,  0x00,  0x08,  0x00,  0x0F, 	/* 27CB0 */
+	0xFE,  0x09,  0x02,  0x11,  0x02,  0x11,  0x02,  0x21,  0x02,  0x42,  0x42,  0x02,  0x22,  0x02,  0x22,  0x04, 	/* 27CC0 */
+	0xF2,  0x1F,  0x12,  0x00,  0x02,  0x00,  0x04,  0x00,  0x38,  0xBF,  0x08,  0x00,  0x08,  0x00,  0x08,  0x00, 	/* 27CD0 */
+	0x0F,  0xFC,  0x12,  0x24,  0x12,  0x24,  0x22,  0x24,  0x44,  0x44,  0x04,  0x44,  0x08,  0x44,  0x10,  0x84, 	/* 27CE0 */
+	0x20,  0x84,  0x01,  0x04,  0x02,  0x04,  0x04,  0x08,  0x00,  0x30,  0x81,  0x08,  0x00,  0x08,  0x00,  0x0F, 	/* 27CF0 */
+	0xFC,  0x08,  0x84,  0x18,  0x84,  0x14,  0x84,  0x24,  0x84,  0x42,  0x84,  0x01,  0x04,  0x01,  0x84,  0x01, 	/* 27D00 */
+	0x64,  0x02,  0x1C,  0x04,  0x07,  0x18,  0x04,  0x60,  0x08,  0x00,  0x70,  0x82,  0x08,  0x00,  0x08,  0x00, 	/* 27D10 */
+	0x08,  0x00,  0x0F,  0xFE,  0x14,  0x02,  0x14,  0x02,  0x24,  0x22,  0x44,  0xC2,  0x07,  0x02,  0x04,  0x02, 	/* 27D20 */
+	0x04,  0x12,  0x04,  0x12,  0x03,  0xF2,  0x00,  0x02,  0x00,  0x04,  0x00,  0x18,  0x85,  0x04,  0x00,  0x04, 	/* 27D30 */
+	0x00,  0x07,  0xFC,  0x08,  0x04,  0x08,  0x04,  0x1F,  0xE4,  0x20,  0x24,  0x40,  0x24,  0x00,  0x24,  0x0F, 	/* 27D40 */
+	0xE8,  0x08,  0x30,  0x08,  0x00,  0x08,  0x00,  0x08,  0x02,  0x04,  0x02,  0x03,  0xFE,  0x86,  0x08,  0x00, 	/* 27D50 */
+	0x08,  0x00,  0x0F,  0xFE,  0x09,  0x22,  0x11,  0x22,  0x11,  0x22,  0x21,  0x22,  0x4E,  0x22,  0x03,  0x22, 	/* 27D60 */
+	0x04,  0xC2,  0x18,  0x62,  0x60,  0x92,  0x01,  0x02,  0x06,  0x02,  0x18,  0x04,  0x00,  0x18,  0x88,  0x08, 	/* 27D70 */
+	0x00,  0x08,  0x00,  0x0F,  0xFE,  0x08,  0x02,  0x10,  0x22,  0x12,  0x22,  0x29,  0x4A,  0x48,  0xCA,  0x08, 	/* 27D80 */
+	0xCA,  0x08,  0xAA,  0x09,  0x2A,  0x0A,  0x0A,  0x0F,  0xFA,  0x00,  0x02,  0x00,  0x04,  0x00,  0x18,  0x8D, 	/* 27D90 */
+	0x08,  0x00,  0x08,  0x00,  0x0F,  0xFE,  0x08,  0x42,  0x11,  0x22,  0x1F,  0xFA,  0x21,  0x02,  0x5F,  0xF2, 	/* 27DA0 */
+	0x11,  0x12,  0x1F,  0xF2,  0x11,  0x12,  0x1F,  0xF2,  0x11,  0x12,  0x11,  0x12,  0x11,  0x34,  0x00,  0x18, 	/* 27DB0 */
+	0x8F,  0x08,  0x20,  0x08,  0x20,  0x7F,  0x3E,  0x14,  0x22,  0x12,  0x42,  0x21,  0x7A,  0x7E,  0xCA,  0x00, 	/* 27DC0 */
+	0x4A,  0x7F,  0x7A,  0x10,  0x42,  0x10,  0x42,  0x3E,  0x4C,  0x22,  0x40,  0x02,  0x41,  0x02,  0x21,  0x0C, 	/* 27DD0 */
+	0x1F,  0x90,  0x08,  0x00,  0x08,  0x00,  0x0F,  0xFE,  0x10,  0x02,  0x1F,  0xF2,  0x20,  0x02,  0x4F,  0xE2, 	/* 27DE0 */
+	0x08,  0x22,  0x0F,  0xE2,  0x00,  0x02,  0x1F,  0xF2,  0x11,  0x12,  0x1F,  0xF2,  0x11,  0x12,  0x1F,  0xF4, 	/* 27DF0 */
+	0x00,  0x18,  0x95,  0x08,  0x00,  0x08,  0x00,  0x08,  0x00,  0x08,  0x04,  0x08,  0x08,  0x08,  0x10,  0x08, 	/* 27E00 */
+	0x60,  0x09,  0x80,  0x0E,  0x00,  0x38,  0x00,  0x08,  0x00,  0x08,  0x00,  0x08,  0x02,  0x08,  0x02,  0x04, 	/* 27E10 */
+	0x02,  0x03,  0xFE,  0x96,  0x02,  0x40,  0x02,  0x40,  0x02,  0x42,  0x04,  0x42,  0x04,  0x44,  0x08,  0x44, 	/* 27E20 */
+	0x08,  0x48,  0x18,  0x50,  0x28,  0x60,  0x48,  0x40,  0x08,  0x40,  0x08,  0x40,  0x08,  0x41,  0x08,  0x41, 	/* 27E30 */
+	0x08,  0x21,  0x08,  0x1F,  0x97,  0x04,  0x40,  0x04,  0x40,  0x04,  0x40,  0x04,  0x44,  0x04,  0x44,  0x7C, 	/* 27E40 */
+	0x48,  0x04,  0x50,  0x04,  0x60,  0x04,  0x40,  0x04,  0x40,  0x0C,  0x40,  0x14,  0x42,  0x64,  0x42,  0x04, 	/* 27E50 */
+	0x22,  0x04,  0x1E,  0x04,  0x00,  0x99,  0x00,  0x20,  0x1F,  0x20,  0x11,  0x20,  0x1F,  0x22,  0x11,  0x24, 	/* 27E60 */
+	0x11,  0x38,  0x1F,  0x20,  0x00,  0x20,  0x7F,  0xA0,  0x14,  0x22,  0x14,  0x22,  0x17,  0xA2,  0x1C,  0x1E, 	/* 27E70 */
+	0x24,  0x00,  0x23,  0x00,  0x40,  0xFF,  0x9A,  0x00,  0x00,  0x3F,  0xFE,  0x20,  0x00,  0x20,  0x00,  0x20, 	/* 27E80 */
+	0x00,  0x20,  0x00,  0x20,  0x00,  0x20,  0x00,  0x20,  0x00,  0x20,  0x00,  0x20,  0x00,  0x20,  0x00,  0x20, 	/* 27E90 */
+	0x00,  0x20,  0x00,  0x3F,  0xFE,  0x00,  0x00,  0x9D,  0x00,  0x00,  0x3F,  0xFE,  0x20,  0x00,  0x20,  0x40, 	/* 27EA0 */
+	0x20,  0x40,  0x27,  0xFC,  0x24,  0x44,  0x24,  0x44,  0x24,  0x44,  0x24,  0x44,  0x24,  0x58,  0x24,  0x40, 	/* 27EB0 */
+	0x20,  0x40,  0x20,  0x40,  0x3F,  0xFF,  0x00,  0x00,  0xA0,  0x00,  0x00,  0x3F,  0xFE,  0x20,  0x08,  0x20, 	/* 27EC0 */
+	0x70,  0x27,  0x80,  0x24,  0x00,  0x27,  0xFC,  0x24,  0x20,  0x24,  0x20,  0x24,  0x20,  0x24,  0x20,  0x28, 	/* 27ED0 */
+	0x20,  0x28,  0x20,  0x30,  0x20,  0x3F,  0xFE,  0x00,  0x00,  0xA1,  0x00,  0x00,  0x3F,  0xFE,  0x20,  0x00, 	/* 27EE0 */
+	0x20,  0x00,  0x2F,  0xF8,  0x20,  0x80,  0x20,  0x80,  0x27,  0xF0,  0x20,  0x80,  0x20,  0x80,  0x20,  0x80, 	/* 27EF0 */
+	0x2F,  0xFC,  0x20,  0x00,  0x20,  0x00,  0x3F,  0xFE,  0x00,  0x00,  0xA3,  0x00,  0x00,  0x3F,  0xFE,  0x20, 	/* 27F00 */
+	0x00,  0x27,  0xFC,  0x24,  0x44,  0x24,  0x44,  0x27,  0xFC,  0x24,  0x44,  0x24,  0x44,  0x27,  0xFC,  0x20, 	/* 27F10 */
+	0x40,  0x20,  0x40,  0x20,  0x40,  0x20,  0x40,  0x3F,  0xFF,  0x00,  0x00,  0xAA,  0x00,  0x00,  0x3F,  0xFE, 	/* 27F20 */
+	0x21,  0x20,  0x21,  0x20,  0x2F,  0x3C,  0x21,  0x20,  0x21,  0x20,  0x2F,  0x3C,  0x21,  0x20,  0x23,  0xA0, 	/* 27F30 */
+	0x2D,  0x3E,  0x22,  0x20,  0x22,  0x20,  0x24,  0x00,  0x3F,  0xFE,  0x00,  0x00,  0xAF,  0x00,  0x00,  0x3F, 	/* 27F40 */
+	0xFF,  0x28,  0x00,  0x24,  0x88,  0x20,  0x90,  0x31,  0xFE,  0x29,  0x20,  0x23,  0xFC,  0x21,  0x20,  0x25, 	/* 27F50 */
+	0xFC,  0x29,  0x20,  0x29,  0x20,  0x31,  0xFE,  0x20,  0x00,  0x3F,  0xFF,  0x20,  0x00,  0xB1,  0x00,  0x00, 	/* 27F60 */
+	0x3F,  0xFF,  0x20,  0x40,  0x23,  0xFC,  0x22,  0x44,  0x23,  0xFC,  0x20,  0x40,  0x2F,  0xFF,  0x21,  0x08, 	/* 27F70 */
+	0x21,  0xF8,  0x21,  0x08,  0x21,  0xF8,  0x21,  0x98,  0x26,  0x04,  0x3F,  0xFF,  0x20,  0x00,  0xB3,  0x00, 	/* 27F80 */
+	0x00,  0x3F,  0xFF,  0x20,  0x40,  0x20,  0xA0,  0x21,  0x10,  0x27,  0xEC,  0x38,  0x03,  0x27,  0xBC,  0x24, 	/* 27F90 */
+	0xA4,  0x27,  0xBC,  0x22,  0x08,  0x23,  0x0C,  0x24,  0x92,  0x28,  0x20,  0x3F,  0xFF,  0x20,  0x00,  0xB8, 	/* 27FA0 */
+	0x00,  0x00,  0x7F,  0xFF,  0x10,  0x00,  0x10,  0x00,  0x10,  0x00,  0x10,  0x00,  0x10,  0x00,  0x10,  0x00, 	/* 27FB0 */
+	0x10,  0x00,  0x10,  0x00,  0x10,  0x00,  0x10,  0x00,  0x10,  0x00,  0x08,  0x00,  0x07,  0xFE,  0x00,  0x00, 	/* 27FC0 */
+	0xB9,  0x00,  0x00,  0x00,  0x00,  0x7F,  0xFF,  0x42,  0x20,  0x42,  0x20,  0x42,  0x20,  0x42,  0x20,  0x44, 	/* 27FD0 */
+	0x20,  0x44,  0x22,  0x48,  0x22,  0x50,  0x1E,  0x40,  0x00,  0x40,  0x00,  0x7F,  0xFF,  0x00,  0x00,  0x00, 	/* 27FE0 */
+	0x00,  0xBA,  0x00,  0x00,  0x3F,  0xFE,  0x20,  0x08,  0x20,  0x08,  0x20,  0x08,  0x20,  0x10,  0x2E,  0x10, 	/* 27FF0 */
+	0x21,  0xA0,  0x20,  0x40,  0x20,  0xA0,  0x21,  0x10,  0x22,  0x08,  0x24,  0x08,  0x28,  0x00,  0x3F,  0xFF, 	/* 28000 */
+	0x00,  0x00,  0xBB,  0x00,  0x00,  0x3F,  0xFE,  0x21,  0x00,  0x21,  0x00,  0x23,  0xFC,  0x24,  0x40,  0x28, 	/* 28010 */
+	0x40,  0x3F,  0xFE,  0x20,  0xA0,  0x20,  0x90,  0x21,  0x08,  0x22,  0x04,  0x24,  0x04,  0x28,  0x00,  0x3F, 	/* 28020 */
+	0xFE,  0x00,  0x00,  0xBF,  0x00,  0x00,  0x3F,  0xFE,  0x20,  0x00,  0x22,  0x10,  0x3F,  0xFE,  0x22,  0x90, 	/* 28030 */
+	0x20,  0x80,  0x3F,  0xFE,  0x21,  0x00,  0x23,  0xF8,  0x26,  0x08,  0x3A,  0x08,  0x23,  0xF8,  0x20,  0x00, 	/* 28040 */
+	0x3F,  0xFE,  0x00,  0x00,  0x80,  0x00,  0x00,  0x7F,  0xFF,  0x20,  0x00,  0x23,  0xF0,  0x22,  0x10,  0x22, 	/* 28050 */
+	0x10,  0x23,  0xF0,  0x20,  0x00,  0x2F,  0x3C,  0x29,  0x24,  0x29,  0x24,  0x29,  0x24,  0x2F,  0x3C,  0x20, 	/* 28060 */
+	0x00,  0x3F,  0xFF,  0x00,  0x00,  0x81,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80, 	/* 28070 */
+	0x00,  0x80,  0x7F,  0xFF,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80, 	/* 28080 */
+	0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x83,  0x00,  0x08,  0x00,  0x30,  0x1F,  0xC0,  0x00,  0x80,  0x00, 	/* 28090 */
+	0x80,  0x00,  0x80,  0x00,  0x80,  0x7F,  0xFF,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x00, 	/* 280A0 */
+	0x80,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x85,  0x08,  0x88,  0x08,  0x88,  0x08,  0x88,  0x08,  0x88, 	/* 280B0 */
+	0x08,  0x88,  0x08,  0x88,  0x7F,  0xFF,  0x08,  0x88,  0x08,  0x88,  0x08,  0x88,  0x08,  0x88,  0x08,  0x88, 	/* 280C0 */
+	0x10,  0x88,  0x10,  0x88,  0x20,  0x88,  0x40,  0x88,  0x86,  0x02,  0x00,  0x02,  0x00,  0x7F,  0xE0,  0x02, 	/* 280D0 */
+	0x20,  0x02,  0x20,  0x04,  0x20,  0x08,  0x22,  0x11,  0x12,  0x61,  0x0E,  0x01,  0x00,  0x7F,  0xFE,  0x01, 	/* 280E0 */
+	0x00,  0x01,  0x00,  0x01,  0x00,  0x01,  0x00,  0x01,  0x00,  0x87,  0x00,  0x10,  0x00,  0x90,  0x03,  0x10, 	/* 280F0 */
+	0x3C,  0x10,  0x04,  0x10,  0x04,  0x10,  0x04,  0x10,  0x7F,  0xFF,  0x04,  0x10,  0x04,  0x10,  0x04,  0x10, 	/* 28100 */
+	0x04,  0x10,  0x08,  0x10,  0x08,  0x10,  0x10,  0x10,  0x20,  0x10,  0x88,  0x04,  0x00,  0x04,  0x00,  0x07, 	/* 28110 */
+	0xFC,  0x08,  0x80,  0x08,  0x80,  0x10,  0x80,  0x20,  0x80,  0x00,  0x80,  0x7F,  0xFF,  0x00,  0x80,  0x00, 	/* 28120 */
+	0x80,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x89,  0x00,  0x80,  0x00,  0x80, 	/* 28130 */
+	0x1F,  0xFC,  0x00,  0x80,  0x00,  0x80,  0x04,  0x88,  0x04,  0x08,  0x04,  0x08,  0x7F,  0xFF,  0x04,  0x08, 	/* 28140 */
+	0x04,  0x08,  0x04,  0x08,  0x08,  0x08,  0x08,  0x08,  0x10,  0x08,  0x20,  0x08,  0x8A,  0x00,  0x80,  0x00, 	/* 28150 */
+	0x84,  0x10,  0x84,  0x08,  0x88,  0x04,  0x90,  0x04,  0x80,  0x3F,  0xFE,  0x00,  0x80,  0x00,  0x80,  0x00, 	/* 28160 */
+	0x80,  0x7F,  0xFF,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x8D,  0x00,  0x02, 	/* 28170 */
+	0x7F,  0x82,  0x00,  0x82,  0x00,  0x82,  0x00,  0x82,  0x00,  0x82,  0x00,  0x82,  0x3F,  0xFE,  0x20,  0x80, 	/* 28180 */
+	0x20,  0x80,  0x20,  0x80,  0x20,  0x80,  0x20,  0x80,  0x20,  0x80,  0x20,  0xFF,  0x20,  0x00,  0x91,  0x00, 	/* 28190 */
+	0x80,  0x01,  0x00,  0x0F,  0xFC,  0x08,  0x84,  0x08,  0x84,  0x0F,  0xFC,  0x08,  0x84,  0x08,  0x84,  0x0F, 	/* 281A0 */
+	0xFC,  0x02,  0x40,  0x04,  0x40,  0x7F,  0xFF,  0x00,  0x40,  0x00,  0x40,  0x00,  0x40,  0x00,  0x40,  0x92, 	/* 281B0 */
+	0x00,  0x80,  0x00,  0x80,  0x3F,  0xFE,  0x04,  0x10,  0x04,  0x10,  0x06,  0x18,  0x09,  0x24,  0x10,  0xC2, 	/* 281C0 */
+	0x20,  0x80,  0x7F,  0xFF,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80, 	/* 281D0 */
+	0x93,  0x00,  0x80,  0x00,  0x80,  0x00,  0xFC,  0x00,  0x80,  0x0F,  0xF8,  0x08,  0x08,  0x08,  0x08,  0x0F, 	/* 281E0 */
+	0xF8,  0x08,  0x08,  0x08,  0x08,  0x0F,  0xF8,  0x00,  0x80,  0x7F,  0xFF,  0x00,  0x80,  0x00,  0x80,  0x00, 	/* 281F0 */
+	0x80,  0x94,  0x10,  0x40,  0x10,  0x40,  0x13,  0xFC,  0x10,  0x44,  0x10,  0x44,  0x7C,  0x84,  0x11,  0x18, 	/* 28200 */
+	0x12,  0x08,  0x12,  0x08,  0x1F,  0xFF,  0x12,  0x49,  0x12,  0x49,  0x12,  0x49,  0x14,  0x49,  0x14,  0x51, 	/* 28210 */
+	0x19,  0xA6,  0x97,  0x00,  0x80,  0x00,  0x80,  0x7F,  0xFF,  0x00,  0x80,  0x00,  0x80,  0x1F,  0xFC,  0x12, 	/* 28220 */
+	0x24,  0x11,  0x44,  0x17,  0xF4,  0x10,  0x84,  0x10,  0x84,  0x1F,  0xFC,  0x10,  0x84,  0x10,  0x84,  0x10, 	/* 28230 */
+	0x84,  0x10,  0x8C,  0x98,  0x09,  0x08,  0x04,  0x88,  0x04,  0x90,  0x0F,  0xFC,  0x08,  0x84,  0x08,  0x84, 	/* 28240 */
+	0x0F,  0xFC,  0x08,  0x84,  0x08,  0x84,  0x0F,  0xFC,  0x00,  0x80,  0x00,  0x80,  0x7F,  0xFF,  0x00,  0x80, 	/* 28250 */
+	0x00,  0x80,  0x00,  0x80,  0x9A,  0x10,  0x28,  0x10,  0x24,  0x17,  0xFF,  0x10,  0x20,  0x11,  0xFE,  0x11, 	/* 28260 */
+	0x22,  0x7D,  0xFE,  0x11,  0x22,  0x11,  0xFE,  0x10,  0x08,  0x17,  0xFF,  0x11,  0x08,  0x10,  0x88,  0x10, 	/* 28270 */
+	0x88,  0x10,  0x08,  0x10,  0x18,  0x9C,  0x02,  0x00,  0x02,  0x00,  0x02,  0x00,  0x02,  0x00,  0x02,  0x00, 	/* 28280 */
+	0x03,  0x80,  0x02,  0x40,  0x02,  0x20,  0x02,  0x10,  0x02,  0x08,  0x02,  0x00,  0x02,  0x00,  0x02,  0x00, 	/* 28290 */
+	0x02,  0x00,  0x02,  0x00,  0x02,  0x00,  0x9E,  0x00,  0x80,  0x00,  0x80,  0x7F,  0xFF,  0x00,  0x80,  0x00, 	/* 282A0 */
+	0x80,  0x00,  0x80,  0x00,  0xC0,  0x00,  0xB0,  0x00,  0x88,  0x00,  0x84,  0x00,  0x80,  0x00,  0x80,  0x00, 	/* 282B0 */
+	0x80,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0xA0,  0x01,  0x00,  0x01,  0x00,  0x01,  0x00,  0x01,  0x00, 	/* 282C0 */
+	0x01,  0xFF,  0x01,  0x00,  0x01,  0x00,  0x01,  0x00,  0x01,  0x00,  0x1F,  0xF8,  0x10,  0x08,  0x10,  0x08, 	/* 282D0 */
+	0x10,  0x08,  0x10,  0x08,  0x1F,  0xF8,  0x00,  0x00,  0xA6,  0x04,  0x10,  0x04,  0x10,  0x3F,  0x90,  0x04, 	/* 282E0 */
+	0x10,  0x04,  0x10,  0x04,  0x18,  0x7F,  0xD4,  0x04,  0x12,  0x04,  0x12,  0x3F,  0x90,  0x04,  0x10,  0x04, 	/* 282F0 */
+	0x10,  0x05,  0xD0,  0x0E,  0x10,  0x70,  0x10,  0x00,  0x10,  0xA9,  0x00,  0x00,  0x0F,  0xF0,  0x08,  0x10, 	/* 28300 */
+	0x08,  0x10,  0x08,  0x10,  0x08,  0x10,  0x08,  0x10,  0x08,  0x10,  0x08,  0x10,  0x08,  0x10,  0x08,  0x10, 	/* 28310 */
+	0x08,  0xE0,  0x08,  0x00,  0x08,  0x00,  0x08,  0x00,  0x08,  0x00,  0xAE,  0x00,  0x08,  0x00,  0x70,  0x1F, 	/* 28320 */
+	0x80,  0x10,  0x00,  0x10,  0x00,  0x1F,  0xFF,  0x10,  0x00,  0x13,  0xF8,  0x12,  0x08,  0x12,  0x08,  0x12, 	/* 28330 */
+	0x08,  0x12,  0x38,  0x22,  0x02,  0x22,  0x02,  0x41,  0x02,  0x00,  0xFE,  0xAF,  0x02,  0x00,  0x0C,  0x00, 	/* 28340 */
+	0x30,  0x7C,  0x22,  0x44,  0x22,  0x44,  0x22,  0x44,  0x22,  0x44,  0x22,  0x44,  0x22,  0x44,  0x22,  0x44, 	/* 28350 */
+	0x3E,  0x44,  0x62,  0x44,  0x04,  0x58,  0x04,  0x40,  0x08,  0x40,  0x10,  0x40,  0xB0,  0x01,  0x00,  0x06, 	/* 28360 */
+	0x00,  0x38,  0x7E,  0x20,  0x42,  0x20,  0x42,  0x20,  0x42,  0x3F,  0x42,  0x20,  0x42,  0x20,  0x42,  0x20, 	/* 28370 */
+	0x42,  0x20,  0x42,  0x3F,  0x5C,  0x00,  0x40,  0x00,  0x40,  0x00,  0x40,  0x00,  0x40,  0xB1,  0x04,  0x00, 	/* 28380 */
+	0x07,  0xF0,  0x08,  0x20,  0x10,  0x40,  0x3F,  0xFE,  0x50,  0x00,  0x10,  0x00,  0x13,  0xF8,  0x12,  0x08, 	/* 28390 */
+	0x12,  0x08,  0x12,  0x08,  0x12,  0x30,  0x22,  0x02,  0x22,  0x02,  0x41,  0x02,  0x00,  0xFE,  0xB3,  0x00, 	/* 283A0 */
+	0x00,  0x1F,  0xBE,  0x10,  0xA2,  0x10,  0xA2,  0x1F,  0xA2,  0x10,  0xA2,  0x10,  0xA2,  0x10,  0xA2,  0x1F, 	/* 283B0 */
+	0xA2,  0x14,  0x22,  0x12,  0x22,  0x11,  0x22,  0x16,  0xAC,  0x18,  0xA0,  0x60,  0x20,  0x00,  0x20,  0xB4, 	/* 283C0 */
+	0x04,  0x00,  0x04,  0x3E,  0x3F,  0xA2,  0x04,  0x22,  0x04,  0x22,  0x04,  0x22,  0x04,  0x22,  0x7F,  0xE2, 	/* 283D0 */
+	0x08,  0x22,  0x0A,  0x22,  0x09,  0x22,  0x11,  0x22,  0x13,  0xAC,  0x7C,  0xA0,  0x00,  0xA0,  0x00,  0x20, 	/* 283E0 */
+	0xB5,  0x02,  0x00,  0x04,  0x00,  0x18,  0x3E,  0x11,  0x22,  0x11,  0x22,  0x11,  0x22,  0x19,  0x32,  0x15, 	/* 283F0 */
+	0x2A,  0x15,  0x2A,  0x11,  0x22,  0x11,  0x22,  0x1F,  0x22,  0x62,  0x2C,  0x02,  0x20,  0x04,  0x20,  0x08, 	/* 28400 */
+	0x20,  0xB7,  0x04,  0x90,  0x04,  0x88,  0x08,  0x88,  0x3F,  0xFE,  0x00,  0x80,  0x01,  0x40,  0x7F,  0xFF, 	/* 28410 */
+	0x02,  0x20,  0x04,  0x10,  0x1F,  0xFC,  0x64,  0x13,  0x04,  0x10,  0x04,  0x60,  0x04,  0x04,  0x02,  0x04, 	/* 28420 */
+	0x01,  0xFC,  0xB8,  0x10,  0x00,  0x10,  0x3E,  0x1F,  0xA2,  0x14,  0x22,  0x24,  0x22,  0x44,  0x22,  0x7F, 	/* 28430 */
+	0xE2,  0x04,  0x22,  0x24,  0x22,  0x27,  0xA2,  0x24,  0x22,  0x24,  0x22,  0x27,  0xBC,  0x3C,  0x20,  0x60, 	/* 28440 */
+	0x20,  0x00,  0x20,  0xBB,  0x04,  0x00,  0x0A,  0x3E,  0x09,  0x22,  0x10,  0xA2,  0x24,  0xA2,  0x4A,  0x22, 	/* 28450 */
+	0x09,  0x22,  0x10,  0xA2,  0x10,  0xA2,  0x3F,  0x22,  0x51,  0x22,  0x11,  0x22,  0x11,  0x2C,  0x11,  0x20, 	/* 28460 */
+	0x1F,  0x20,  0x00,  0x20,  0xBF,  0x04,  0x00,  0x0B,  0xDE,  0x32,  0x52,  0x2A,  0x52,  0x2B,  0xD2,  0x2A, 	/* 28470 */
+	0x52,  0x2A,  0x52,  0x2B,  0xD2,  0x2A,  0x12,  0x2B,  0x12,  0x3A,  0x92,  0x6A,  0x52,  0x0B,  0xDC,  0x16, 	/* 28480 */
+	0x30,  0x10,  0x10,  0x20,  0x10,  0x82,  0x00,  0x00,  0x1F,  0xFE,  0x10,  0x00,  0x10,  0x00,  0x10,  0x00, 	/* 28490 */
+	0x10,  0x00,  0x10,  0x00,  0x10,  0x00,  0x10,  0x00,  0x10,  0x00,  0x10,  0x00,  0x10,  0x00,  0x20,  0x00, 	/* 284A0 */
+	0x20,  0x00,  0x40,  0x00,  0x00,  0x00,  0x84,  0x00,  0x00,  0x1F,  0xFF,  0x10,  0x00,  0x10,  0x00,  0x13, 	/* 284B0 */
+	0xF8,  0x12,  0x08,  0x12,  0x08,  0x12,  0x08,  0x12,  0x08,  0x12,  0x08,  0x12,  0x30,  0x12,  0x02,  0x22, 	/* 284C0 */
+	0x02,  0x21,  0x02,  0x40,  0xFE,  0x00,  0x00,  0x96,  0x00,  0x00,  0x1F,  0xFF,  0x10,  0x04,  0x12,  0x84, 	/* 284D0 */
+	0x12,  0x48,  0x12,  0x12,  0x1F,  0xE2,  0x12,  0x04,  0x12,  0x09,  0x13,  0x11,  0x15,  0x22,  0x15,  0x04, 	/* 284E0 */
+	0x25,  0x08,  0x29,  0x31,  0x49,  0x01,  0x10,  0xFF,  0x98,  0x00,  0x00,  0x1F,  0xFF,  0x10,  0x00,  0x13, 	/* 284F0 */
+	0xFC,  0x12,  0x44,  0x13,  0xFC,  0x12,  0x44,  0x12,  0x44,  0x13,  0xFC,  0x10,  0x40,  0x10,  0x40,  0x17, 	/* 28500 */
+	0xFE,  0x20,  0x40,  0x20,  0x40,  0x5F,  0xFF,  0x00,  0x00,  0x9A,  0x00,  0x00,  0x1F,  0xFE,  0x10,  0x00, 	/* 28510 */
+	0x13,  0xF8,  0x12,  0x08,  0x13,  0xF8,  0x12,  0x08,  0x13,  0xF8,  0x10,  0x00,  0x17,  0xF8,  0x10,  0x20, 	/* 28520 */
+	0x10,  0x40,  0x2F,  0xFF,  0x20,  0x40,  0x40,  0x40,  0x00,  0xC0,  0x9F,  0x00,  0x00,  0x1F,  0xFF,  0x10, 	/* 28530 */
+	0x40,  0x10,  0x80,  0x13,  0xF8,  0x12,  0x08,  0x13,  0xF8,  0x12,  0x08,  0x12,  0x08,  0x13,  0xF8,  0x10, 	/* 28540 */
+	0x40,  0x12,  0x48,  0x22,  0x44,  0x24,  0x42,  0x48,  0x42,  0x00,  0xC0,  0xA0,  0x00,  0x00,  0x1F,  0xFF, 	/* 28550 */
+	0x10,  0x00,  0x17,  0xC2,  0x14,  0x52,  0x14,  0x52,  0x17,  0xD2,  0x14,  0x52,  0x14,  0x52,  0x17,  0xD2, 	/* 28560 */
+	0x14,  0x52,  0x14,  0x52,  0x27,  0xC2,  0x22,  0x82,  0x44,  0x42,  0x08,  0x06,  0xA5,  0x00,  0x00,  0x1F, 	/* 28570 */
+	0xFF,  0x14,  0x50,  0x12,  0x50,  0x12,  0x90,  0x1F,  0xDF,  0x11,  0x21,  0x15,  0x6A,  0x15,  0x48,  0x15, 	/* 28580 */
+	0x48,  0x15,  0x48,  0x17,  0xD4,  0x22,  0x14,  0x22,  0x24,  0x44,  0x42,  0x08,  0x81,  0xA6,  0x00,  0x00, 	/* 28590 */
+	0x1F,  0xFF,  0x10,  0x00,  0x1F,  0xFF,  0x10,  0x40,  0x13,  0xFC,  0x12,  0x04,  0x13,  0xFC,  0x12,  0x04, 	/* 285A0 */
+	0x13,  0xFC,  0x10,  0x40,  0x10,  0xFC,  0x23,  0x88,  0x2C,  0x70,  0x40,  0xD8,  0x1F,  0x07,  0xA8,  0x00, 	/* 285B0 */
+	0x00,  0x1F,  0xFF,  0x10,  0x00,  0x10,  0x04,  0x1F,  0xC4,  0x10,  0x04,  0x17,  0xFF,  0x14,  0x84,  0x14, 	/* 285C0 */
+	0xC4,  0x17,  0xA4,  0x10,  0x24,  0x14,  0x84,  0x22,  0x84,  0x23,  0x64,  0x43,  0x84,  0x1C,  0x0C,  0xA9, 	/* 285D0 */
+	0x00,  0x00,  0x1F,  0xFF,  0x10,  0x00,  0x17,  0xBE,  0x14,  0xA8,  0x14,  0xA8,  0x17,  0xA8,  0x14,  0xA8, 	/* 285E0 */
+	0x14,  0xFF,  0x17,  0x88,  0x14,  0x18,  0x15,  0x18,  0x24,  0xA8,  0x25,  0xA9,  0x46,  0x49,  0x18,  0x87, 	/* 285F0 */
+	0xAD,  0x00,  0x00,  0x3F,  0xFF,  0x20,  0x00,  0x2F,  0x8A,  0x28,  0x89,  0x2F,  0x88,  0x28,  0xFF,  0x2F, 	/* 28600 */
+	0x88,  0x20,  0x08,  0x2F,  0x8C,  0x28,  0x94,  0x2F,  0x94,  0x28,  0x94,  0x2F,  0xA2,  0x48,  0xC2,  0x49, 	/* 28610 */
+	0x81,  0xAE,  0x00,  0x00,  0x1F,  0xFF,  0x10,  0x02,  0x14,  0x84,  0x14,  0x98,  0x1F,  0xF0,  0x14,  0x9F, 	/* 28620 */
+	0x17,  0x92,  0x14,  0x92,  0x17,  0x92,  0x14,  0x92,  0x14,  0x92,  0x3F,  0xE2,  0x25,  0x22,  0x48,  0xC2, 	/* 28630 */
+	0x10,  0x82,  0xB0,  0x00,  0x00,  0x3F,  0xFF,  0x21,  0x08,  0x25,  0x48,  0x25,  0x48,  0x29,  0x2F,  0x21, 	/* 28640 */
+	0x12,  0x2F,  0xD2,  0x28,  0x52,  0x2B,  0xEA,  0x2A,  0xCA,  0x2A,  0xC4,  0x2B,  0xC4,  0x28,  0x4A,  0x48, 	/* 28650 */
+	0x52,  0x08,  0xE1,  0xB3,  0x08,  0x84,  0x04,  0x48,  0x1F,  0xFF,  0x10,  0x10,  0x17,  0xD0,  0x11,  0x10, 	/* 28660 */
+	0x1F,  0xDF,  0x14,  0xA4,  0x17,  0xA4,  0x14,  0xD4,  0x17,  0x94,  0x14,  0x88,  0x24,  0xC8,  0x27,  0x94, 	/* 28670 */
+	0x5C,  0xA2,  0x00,  0xC1,  0xB6,  0x01,  0x00,  0x01,  0x00,  0x01,  0x00,  0x01,  0x00,  0x01,  0x00,  0x01, 	/* 28680 */
+	0x00,  0x01,  0x00,  0x02,  0x00,  0x02,  0x20,  0x02,  0x10,  0x02,  0x08,  0x04,  0x08,  0x04,  0x3C,  0x09, 	/* 28690 */
+	0xC4,  0x7E,  0x02,  0x00,  0x02,  0xBB,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x1F,  0xFC,  0x00,  0x80, 	/* 286A0 */
+	0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x7F,  0xFF,  0x01,  0x00,  0x01,  0x20,  0x02,  0x10,  0x02,  0x08, 	/* 286B0 */
+	0x04,  0xF8,  0x3F,  0x04,  0x00,  0x04,  0x82,  0x01,  0x00,  0x01,  0x60,  0x02,  0x18,  0x1F,  0xE4,  0x01, 	/* 286C0 */
+	0x00,  0x7F,  0xFF,  0x02,  0x20,  0x04,  0x50,  0x19,  0x8C,  0x6E,  0x23,  0x00,  0x40,  0x01,  0x88,  0x1E, 	/* 286D0 */
+	0x10,  0x00,  0x60,  0x01,  0x80,  0x1E,  0x00,  0x83,  0x01,  0x40,  0x02,  0x30,  0x1F,  0xE8,  0x08,  0x08, 	/* 286E0 */
+	0x0C,  0x8C,  0x12,  0x92,  0x7D,  0x7D,  0x02,  0x20,  0x04,  0x90,  0x19,  0x1C,  0x66,  0x23,  0x18,  0xC8, 	/* 286F0 */
+	0x03,  0x10,  0x1C,  0x60,  0x01,  0x80,  0x1E,  0x00,  0x88,  0x00,  0x00,  0x00,  0x00,  0x3F,  0xFC,  0x04, 	/* 28700 */
+	0x04,  0x04,  0x04,  0x04,  0x08,  0x02,  0x08,  0x02,  0x10,  0x01,  0x10,  0x00,  0xA0,  0x00,  0xC0,  0x01, 	/* 28710 */
+	0x40,  0x02,  0x20,  0x04,  0x10,  0x18,  0x0C,  0x60,  0x03,  0x89,  0x00,  0x00,  0x00,  0x00,  0x3F,  0xF8, 	/* 28720 */
+	0x09,  0x08,  0x08,  0x88,  0x04,  0x90,  0x04,  0x90,  0x02,  0x20,  0x02,  0x20,  0x01,  0x40,  0x00,  0x80, 	/* 28730 */
+	0x01,  0x40,  0x02,  0x20,  0x04,  0x10,  0x18,  0x0C,  0x60,  0x03,  0x8A,  0x00,  0x00,  0x3F,  0xE0,  0x04, 	/* 28740 */
+	0x20,  0x04,  0x40,  0x04,  0x40,  0x06,  0xF0,  0x06,  0x10,  0x05,  0x10,  0x05,  0x10,  0x08,  0xA0,  0x08, 	/* 28750 */
+	0x60,  0x08,  0x40,  0x10,  0xA0,  0x11,  0x10,  0x22,  0x08,  0x4C,  0x06,  0x8B,  0x01,  0x00,  0x01,  0x00, 	/* 28760 */
+	0x01,  0x00,  0x7F,  0xFF,  0x01,  0x00,  0x01,  0x00,  0x03,  0xF0,  0x02,  0x10,  0x03,  0x10,  0x05,  0x20, 	/* 28770 */
+	0x04,  0xA0,  0x08,  0x40,  0x10,  0xA0,  0x21,  0x10,  0x46,  0x0C,  0x18,  0x03,  0x8C,  0x00,  0x00,  0x7F, 	/* 28780 */
+	0xFC,  0x02,  0x04,  0x02,  0x44,  0x42,  0x44,  0x22,  0x44,  0x12,  0x44,  0x0C,  0x28,  0x04,  0x28,  0x06, 	/* 28790 */
+	0x10,  0x0A,  0x10,  0x09,  0x28,  0x11,  0x48,  0x10,  0x84,  0x23,  0x02,  0x4C,  0x01,  0x8D,  0x00,  0x00, 	/* 287A0 */
+	0x1F,  0xFE,  0x10,  0x00,  0x10,  0x00,  0x10,  0x00,  0x1F,  0xF8,  0x12,  0x08,  0x12,  0x08,  0x11,  0x10, 	/* 287B0 */
+	0x11,  0x10,  0x10,  0xA0,  0x10,  0x40,  0x10,  0xA0,  0x21,  0x10,  0x26,  0x0C,  0x58,  0x03,  0x8E,  0x04, 	/* 287C0 */
+	0x00,  0x04,  0x00,  0x27,  0xFC,  0x24,  0x84,  0x24,  0x84,  0x24,  0x84,  0x24,  0x84,  0x24,  0x48,  0x24, 	/* 287D0 */
+	0x48,  0x24,  0x30,  0x26,  0x30,  0x3C,  0x28,  0xC4,  0x48,  0x04,  0x84,  0x05,  0x02,  0x04,  0x01,  0x94, 	/* 287E0 */
+	0x04,  0x00,  0x04,  0x00,  0x04,  0xFC,  0x07,  0x44,  0x04,  0x44,  0x04,  0x24,  0x7F,  0xA4,  0x04,  0x28, 	/* 287F0 */
+	0x04,  0x28,  0x15,  0x18,  0x15,  0x10,  0x24,  0x98,  0x24,  0xA8,  0x44,  0x44,  0x04,  0x82,  0x0D,  0x01, 	/* 28800 */
+	0x96,  0x00,  0x00,  0x7F,  0x80,  0x11,  0x7E,  0x11,  0x22,  0x11,  0x22,  0x1F,  0x22,  0x11,  0x22,  0x11, 	/* 28810 */
+	0x14,  0x1F,  0x14,  0x11,  0x18,  0x11,  0x08,  0x11,  0x14,  0x1F,  0x24,  0x61,  0x42,  0x01,  0x82,  0x01, 	/* 28820 */
+	0x01,  0x97,  0x00,  0x08,  0x00,  0x70,  0x7F,  0x88,  0x12,  0x08,  0x09,  0x10,  0x09,  0x20,  0x7F,  0xFE, 	/* 28830 */
+	0x40,  0x02,  0x5F,  0xF2,  0x04,  0x10,  0x02,  0x20,  0x01,  0x40,  0x00,  0x80,  0x03,  0x60,  0x0C,  0x18, 	/* 28840 */
+	0x70,  0x06,  0x99,  0x04,  0x00,  0x04,  0xFC,  0x0A,  0x04,  0x09,  0x04,  0x10,  0x84,  0x3F,  0x24,  0x44, 	/* 28850 */
+	0x24,  0x04,  0x28,  0x7F,  0xA8,  0x04,  0x18,  0x15,  0x10,  0x14,  0x98,  0x24,  0xA8,  0x24,  0x44,  0x44, 	/* 28860 */
+	0x82,  0x0D,  0x01,  0x9B,  0x08,  0x00,  0x0A,  0xFF,  0x4A,  0x80,  0x2A,  0x80,  0x2C,  0x80,  0x08,  0xFC, 	/* 28870 */
+	0x7F,  0xA4,  0x08,  0xA4,  0x08,  0xA4,  0x0E,  0x94,  0x78,  0x98,  0x08,  0x88,  0x11,  0x14,  0x11,  0x24, 	/* 28880 */
+	0x22,  0x42,  0x45,  0x81,  0x9F,  0x01,  0x00,  0x05,  0x00,  0x19,  0x78,  0x11,  0x08,  0x11,  0x08,  0x1D, 	/* 28890 */
+	0x78,  0x11,  0x08,  0x11,  0x08,  0x1F,  0xF8,  0x01,  0x00,  0x7F,  0xF8,  0x08,  0x10,  0x06,  0x20,  0x01, 	/* 288A0 */
+	0xC0,  0x0E,  0x38,  0x70,  0x07,  0xA1,  0x08,  0x00,  0x0F,  0x7C,  0x08,  0x04,  0x7F,  0xA4,  0x40,  0xA4, 	/* 288B0 */
+	0x3F,  0x24,  0x05,  0x24,  0x2C,  0xA4,  0x4A,  0x14,  0x1F,  0x98,  0x31,  0x48,  0x5F,  0x18,  0x11,  0x14, 	/* 288C0 */
+	0x1F,  0x24,  0x11,  0xC2,  0x1F,  0x01,  0xA2,  0x09,  0x48,  0x05,  0x50,  0x7F,  0xFF,  0x02,  0x20,  0x1F, 	/* 288D0 */
+	0xFC,  0x00,  0x80,  0x0F,  0xF8,  0x00,  0x80,  0x7F,  0xFF,  0x11,  0x00,  0x1F,  0x7C,  0x11,  0x24,  0x1F, 	/* 288E0 */
+	0x14,  0x11,  0x08,  0x7F,  0x34,  0x01,  0xC3,  0xA3,  0x00,  0x00,  0x00,  0x00,  0x3F,  0xFC,  0x20,  0x04, 	/* 288F0 */
+	0x20,  0x04,  0x20,  0x04,  0x20,  0x04,  0x20,  0x04,  0x20,  0x04,  0x20,  0x04,  0x20,  0x04,  0x20,  0x04, 	/* 28900 */
+	0x20,  0x04,  0x3F,  0xFC,  0x20,  0x04,  0x00,  0x00,  0xA4,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x7F, 	/* 28910 */
+	0xFF,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x0F,  0xF8,  0x08,  0x08,  0x08,  0x08,  0x08, 	/* 28920 */
+	0x08,  0x08,  0x08,  0x08,  0x08,  0x0F,  0xF8,  0x00,  0x00,  0xA5,  0x04,  0x00,  0x04,  0x00,  0x04,  0x00, 	/* 28930 */
+	0x0F,  0xFE,  0x08,  0x02,  0x10,  0x02,  0x27,  0xE2,  0x44,  0x22,  0x04,  0x22,  0x04,  0x22,  0x04,  0x22, 	/* 28940 */
+	0x07,  0xE2,  0x00,  0x02,  0x00,  0x02,  0x00,  0x04,  0x00,  0x18,  0xA8,  0x00,  0x00,  0x01,  0xFE,  0x3E, 	/* 28950 */
+	0x22,  0x22,  0x22,  0x22,  0x22,  0x22,  0x22,  0x22,  0x22,  0x22,  0x22,  0x22,  0x22,  0x22,  0x42,  0x22, 	/* 28960 */
+	0x42,  0x3E,  0x42,  0x00,  0x82,  0x01,  0x02,  0x02,  0x04,  0x04,  0x18,  0xA9,  0x00,  0x00,  0x3E,  0x7E, 	/* 28970 */
+	0x22,  0x42,  0x22,  0x42,  0x22,  0x42,  0x22,  0x42,  0x22,  0x42,  0x22,  0x42,  0x22,  0x42,  0x22,  0x42, 	/* 28980 */
+	0x22,  0x42,  0x3E,  0x5C,  0x00,  0x40,  0x00,  0x40,  0x00,  0x40,  0x00,  0x40,  0xAA,  0x00,  0x00,  0x00, 	/* 28990 */
+	0x00,  0x1F,  0xF8,  0x10,  0x08,  0x10,  0x08,  0x10,  0x08,  0x10,  0x08,  0x10,  0x08,  0x10,  0x08,  0x1F, 	/* 289A0 */
+	0xF8,  0x00,  0x00,  0x04,  0x20,  0x04,  0x10,  0x08,  0x08,  0x10,  0x04,  0x20,  0x04,  0xAB,  0x00,  0x04, 	/* 289B0 */
+	0x00,  0x04,  0x3E,  0x44,  0x22,  0x44,  0x22,  0x44,  0x22,  0x44,  0x22,  0x44,  0x22,  0x44,  0x22,  0x44, 	/* 289C0 */
+	0x22,  0x44,  0x22,  0x47,  0x3E,  0x7C,  0x03,  0xC4,  0x00,  0x04,  0x00,  0x04,  0x00,  0x04,  0xAC,  0x00, 	/* 289D0 */
+	0x00,  0x7F,  0xFE,  0x01,  0x02,  0x01,  0x02,  0x02,  0x02,  0x02,  0x02,  0x04,  0x02,  0x18,  0x0C,  0x60, 	/* 289E0 */
+	0x00,  0x0F,  0xFC,  0x08,  0x04,  0x08,  0x04,  0x08,  0x04,  0x08,  0x04,  0x0F,  0xFC,  0x00,  0x00,  0xAD, 	/* 289F0 */
+	0x00,  0xF8,  0x00,  0x08,  0x7C,  0x08,  0x44,  0x08,  0x44,  0x88,  0x44,  0x88,  0x44,  0x88,  0x44,  0x88, 	/* 28A00 */
+	0x44,  0x88,  0x44,  0x88,  0x44,  0x88,  0x7D,  0x08,  0x01,  0x04,  0x02,  0x04,  0x04,  0x02,  0x08,  0x01, 	/* 28A10 */
+	0xAE,  0x00,  0x00,  0x03,  0xFF,  0x7C,  0x10,  0x44,  0x10,  0x44,  0x10,  0x44,  0x10,  0x44,  0x10,  0x44, 	/* 28A20 */
+	0x10,  0x44,  0x10,  0x44,  0x10,  0x44,  0x10,  0x7C,  0x10,  0x00,  0x10,  0x00,  0x10,  0x00,  0x10,  0x00, 	/* 28A30 */
+	0x30,  0xAF,  0x00,  0x00,  0x00,  0x00,  0x7F,  0xFF,  0x00,  0x08,  0x00,  0x08,  0x0F,  0xC8,  0x08,  0x48, 	/* 28A40 */
+	0x08,  0x48,  0x08,  0x48,  0x08,  0x48,  0x0F,  0xC8,  0x00,  0x08,  0x00,  0x08,  0x00,  0x08,  0x00,  0x08, 	/* 28A50 */
+	0x00,  0x18,  0xB0,  0x01,  0x00,  0x01,  0x00,  0x02,  0x20,  0x02,  0x10,  0x04,  0x08,  0x08,  0xFC,  0x7F, 	/* 28A60 */
+	0x04,  0x00,  0x02,  0x00,  0x02,  0x1F,  0xF8,  0x10,  0x08,  0x10,  0x08,  0x10,  0x08,  0x10,  0x08,  0x1F, 	/* 28A70 */
+	0xF8,  0x00,  0x00,  0xB1,  0x00,  0x80,  0x00,  0x80,  0x7C,  0x80,  0x44,  0x84,  0x44,  0x88,  0x44,  0x90, 	/* 28A80 */
+	0x44,  0xA0,  0x44,  0xC0,  0x47,  0x80,  0x44,  0x80,  0x44,  0x80,  0x44,  0x80,  0x7C,  0x82,  0x00,  0x82, 	/* 28A90 */
+	0x00,  0x42,  0x00,  0x3E,  0xB2,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x1F,  0xFC,  0x10,  0x84,  0x10, 	/* 28AA0 */
+	0x84,  0x10,  0x84,  0x10,  0x84,  0x1F,  0xFC,  0x00,  0x80,  0x04,  0x80,  0x03,  0x00,  0x01,  0x80,  0x02, 	/* 28AB0 */
+	0x60,  0x0C,  0x18,  0x30,  0x07,  0xB3,  0x01,  0x00,  0x01,  0x00,  0x01,  0x00,  0x7F,  0xFE,  0x02,  0x00, 	/* 28AC0 */
+	0x02,  0x00,  0x02,  0x00,  0x04,  0x00,  0x07,  0xF8,  0x0C,  0x08,  0x14,  0x08,  0x24,  0x08,  0x44,  0x08, 	/* 28AD0 */
+	0x04,  0x08,  0x07,  0xF8,  0x00,  0x00,  0xB6,  0x00,  0x10,  0x00,  0x10,  0x3E,  0x10,  0x22,  0x10,  0x22, 	/* 28AE0 */
+	0x10,  0x22,  0x10,  0x23,  0xFF,  0x22,  0x10,  0x22,  0x10,  0x22,  0x10,  0x22,  0x10,  0x3E,  0x10,  0x00, 	/* 28AF0 */
+	0x10,  0x00,  0x10,  0x00,  0x10,  0x00,  0x10,  0xB7,  0x00,  0x00,  0x0F,  0xF0,  0x08,  0x10,  0x08,  0x10, 	/* 28B00 */
+	0x08,  0x10,  0x0F,  0xF0,  0x00,  0x00,  0x7F,  0xFF,  0x04,  0x00,  0x04,  0x00,  0x07,  0xF0,  0x08,  0x10, 	/* 28B10 */
+	0x00,  0x10,  0x00,  0x10,  0x00,  0x20,  0x00,  0xC0,  0xB8,  0x00,  0x00,  0x7F,  0xFC,  0x00,  0x04,  0x00, 	/* 28B20 */
+	0x04,  0x3F,  0xE4,  0x00,  0x04,  0x00,  0x04,  0x1F,  0xC4,  0x10,  0x44,  0x10,  0x44,  0x10,  0x44,  0x1F, 	/* 28B30 */
+	0xC4,  0x00,  0x04,  0x00,  0x04,  0x00,  0x08,  0x00,  0x30,  0xBA,  0x00,  0xE0,  0x00,  0x20,  0x7C,  0x20, 	/* 28B40 */
+	0x44,  0x20,  0x44,  0x20,  0x44,  0x20,  0x44,  0x20,  0x44,  0x30,  0x44,  0x30,  0x44,  0x50,  0x44,  0x50, 	/* 28B50 */
+	0x7C,  0x88,  0x00,  0x88,  0x01,  0x04,  0x06,  0x02,  0x18,  0x01,  0x81,  0x00,  0x00,  0x01,  0xFC,  0x7C, 	/* 28B60 */
+	0x20,  0x44,  0x20,  0x44,  0x20,  0x44,  0x20,  0x44,  0x20,  0x47,  0xFF,  0x44,  0x20,  0x44,  0x20,  0x44, 	/* 28B70 */
+	0x20,  0x7C,  0x20,  0x00,  0x20,  0x00,  0x20,  0x00,  0x20,  0x00,  0x60,  0x83,  0x00,  0x80,  0x00,  0x80, 	/* 28B80 */
+	0x78,  0x80,  0x49,  0xFF,  0x49,  0x00,  0x49,  0x00,  0x4A,  0xFC,  0x4C,  0x08,  0x48,  0x10,  0x48,  0x20, 	/* 28B90 */
+	0x48,  0x40,  0x78,  0x80,  0x01,  0x02,  0x01,  0x02,  0x01,  0x02,  0x00,  0xFE,  0x84,  0x02,  0x00,  0x02, 	/* 28BA0 */
+	0x00,  0x07,  0xF8,  0x04,  0x10,  0x0A,  0x20,  0x11,  0x40,  0x20,  0xC0,  0x03,  0x20,  0x04,  0x10,  0x18, 	/* 28BB0 */
+	0x0C,  0x6F,  0xFB,  0x08,  0x08,  0x08,  0x08,  0x08,  0x08,  0x0F,  0xF8,  0x00,  0x00,  0x88,  0x00,  0x80, 	/* 28BC0 */
+	0x00,  0x80,  0x01,  0x40,  0x02,  0x20,  0x04,  0x10,  0x18,  0x0C,  0x67,  0xF3,  0x00,  0x00,  0x00,  0x00, 	/* 28BD0 */
+	0x0F,  0xF8,  0x08,  0x08,  0x08,  0x08,  0x08,  0x08,  0x08,  0x08,  0x0F,  0xF8,  0x00,  0x00,  0x89,  0x00, 	/* 28BE0 */
+	0x80,  0x00,  0x80,  0x00,  0x80,  0x7F,  0xFF,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x1F,  0xFC,  0x00, 	/* 28BF0 */
+	0x00,  0x00,  0x00,  0x0F,  0xF8,  0x08,  0x08,  0x08,  0x08,  0x08,  0x08,  0x0F,  0xF8,  0x00,  0x00,  0x8A, 	/* 28C00 */
+	0x00,  0x00,  0x07,  0xF0,  0x04,  0x10,  0x04,  0x10,  0x04,  0x10,  0x04,  0x10,  0x07,  0xF0,  0x00,  0x80, 	/* 28C10 */
+	0x1F,  0xFC,  0x10,  0x84,  0x10,  0x84,  0x10,  0x84,  0x10,  0x84,  0x10,  0x98,  0x10,  0x80,  0x00,  0x80, 	/* 28C20 */
+	0x8B,  0x00,  0x08,  0x00,  0x08,  0x7C,  0x08,  0x44,  0x08,  0x47,  0xFF,  0x44,  0x08,  0x45,  0x08,  0x44, 	/* 28C30 */
+	0x88,  0x44,  0x48,  0x44,  0x48,  0x44,  0x08,  0x7C,  0x08,  0x00,  0x08,  0x00,  0x08,  0x00,  0x08,  0x00, 	/* 28C40 */
+	0x18,  0x8C,  0x00,  0x00,  0x3F,  0xFE,  0x20,  0x02,  0x20,  0x02,  0x2F,  0xFA,  0x20,  0x02,  0x20,  0x02, 	/* 28C50 */
+	0x27,  0xF2,  0x24,  0x12,  0x24,  0x12,  0x24,  0x12,  0x27,  0xF2,  0x20,  0x02,  0x20,  0x02,  0x20,  0x02, 	/* 28C60 */
+	0x20,  0x06,  0x8D,  0x01,  0x00,  0x01,  0x00,  0x01,  0xF8,  0x02,  0x08,  0x04,  0x10,  0x0A,  0x20,  0x11, 	/* 28C70 */
+	0x40,  0x20,  0x80,  0x01,  0x00,  0x07,  0xFE,  0x1A,  0x02,  0x62,  0x02,  0x02,  0x02,  0x02,  0x02,  0x03, 	/* 28C80 */
+	0xFE,  0x00,  0x00,  0x8E,  0x00,  0x04,  0x00,  0x38,  0x0F,  0xC0,  0x08,  0x00,  0x08,  0x00,  0x0F,  0xFF, 	/* 28C90 */
+	0x08,  0x00,  0x08,  0x00,  0x08,  0x00,  0x0B,  0xFC,  0x0A,  0x04,  0x12,  0x04,  0x12,  0x04,  0x22,  0x04, 	/* 28CA0 */
+	0x43,  0xFC,  0x00,  0x00,  0x8F,  0x00,  0x80,  0x00,  0x80,  0x7F,  0xFF,  0x00,  0x80,  0x1F,  0xF8,  0x10, 	/* 28CB0 */
+	0x88,  0x10,  0x88,  0x10,  0x88,  0x1F,  0xF8,  0x04,  0x80,  0x02,  0x80,  0x01,  0x00,  0x01,  0x80,  0x02, 	/* 28CC0 */
+	0x60,  0x0C,  0x18,  0x70,  0x06,  0x90,  0x00,  0x20,  0x00,  0x20,  0x7C,  0x20,  0x44,  0x20,  0x44,  0x20, 	/* 28CD0 */
+	0x44,  0x20,  0x47,  0xFE,  0x44,  0x20,  0x44,  0x20,  0x44,  0x20,  0x44,  0x20,  0x7C,  0x20,  0x00,  0x20, 	/* 28CE0 */
+	0x00,  0x20,  0x0F,  0xFF,  0x00,  0x00,  0x91,  0x01,  0x00,  0x01,  0x00,  0x02,  0x00,  0x04,  0x00,  0x3F, 	/* 28CF0 */
+	0xFE,  0x20,  0x02,  0x20,  0x02,  0x27,  0xF2,  0x24,  0x12,  0x24,  0x12,  0x24,  0x12,  0x27,  0xF2,  0x20, 	/* 28D00 */
+	0x02,  0x20,  0x02,  0x20,  0x02,  0x20,  0x06,  0x9B,  0x00,  0x00,  0x1F,  0xF8,  0x01,  0x08,  0x01,  0x08, 	/* 28D10 */
+	0x7F,  0xFF,  0x01,  0x08,  0x01,  0x08,  0x1F,  0xF8,  0x02,  0x00,  0x02,  0x00,  0x07,  0xFC,  0x0C,  0x04, 	/* 28D20 */
+	0x14,  0x04,  0x24,  0x04,  0x47,  0xFC,  0x00,  0x00,  0x9D,  0x00,  0x80,  0x00,  0x80,  0x7F,  0xFF,  0x04, 	/* 28D30 */
+	0x10,  0x02,  0x20,  0x01,  0x40,  0x00,  0x80,  0x03,  0x60,  0x0C,  0x18,  0x70,  0x07,  0x0F,  0xF8,  0x08, 	/* 28D40 */
+	0x08,  0x08,  0x08,  0x08,  0x08,  0x0F,  0xF8,  0x00,  0x00,  0x9F,  0x00,  0x20,  0x00,  0x20,  0x7C,  0x50, 	/* 28D50 */
+	0x44,  0x50,  0x44,  0x88,  0x45,  0x04,  0x46,  0xFA,  0x44,  0x01,  0x44,  0x00,  0x45,  0xFC,  0x44,  0x04, 	/* 28D60 */
+	0x7C,  0x08,  0x00,  0x08,  0x00,  0x10,  0x00,  0x10,  0x00,  0x20,  0xA0,  0x00,  0x20,  0x00,  0x28,  0x3E, 	/* 28D70 */
+	0x24,  0x22,  0x24,  0x22,  0x20,  0x23,  0xFF,  0x22,  0x20,  0x22,  0x20,  0x22,  0x20,  0x22,  0x50,  0x3E, 	/* 28D80 */
+	0x50,  0x00,  0x88,  0x00,  0x88,  0x01,  0x04,  0x06,  0x02,  0x18,  0x01,  0xA6,  0x00,  0x00,  0x7F,  0xFF, 	/* 28D90 */
+	0x00,  0x40,  0x00,  0xE0,  0x01,  0x98,  0x06,  0x84,  0x18,  0x82,  0x60,  0x81,  0x00,  0x80,  0x0F,  0xF8, 	/* 28DA0 */
+	0x08,  0x08,  0x08,  0x08,  0x08,  0x08,  0x08,  0x08,  0x0F,  0xF8,  0x00,  0x00,  0xA9,  0x00,  0x78,  0x00, 	/* 28DB0 */
+	0x08,  0x78,  0x88,  0x48,  0x88,  0x48,  0x84,  0x49,  0x04,  0x49,  0xFE,  0x4A,  0x25,  0x4C,  0x24,  0x48, 	/* 28DC0 */
+	0x24,  0x48,  0x24,  0x78,  0x44,  0x00,  0x44,  0x00,  0x84,  0x01,  0x04,  0x02,  0x18,  0xAB,  0x00,  0x80, 	/* 28DD0 */
+	0x00,  0x80,  0x01,  0x40,  0x02,  0x20,  0x07,  0xF0,  0x18,  0x0C,  0x60,  0x03,  0x0F,  0xF0,  0x00,  0x10, 	/* 28DE0 */
+	0x00,  0x20,  0x00,  0x40,  0x0F,  0xF8,  0x08,  0x08,  0x08,  0x08,  0x0F,  0xF8,  0x00,  0x00,  0xAC,  0x00, 	/* 28DF0 */
+	0x04,  0x00,  0x18,  0x7C,  0xE0,  0x44,  0x80,  0x44,  0x80,  0x44,  0xFF,  0x44,  0x88,  0x44,  0x88,  0x44, 	/* 28E00 */
+	0x88,  0x44,  0x88,  0x44,  0x88,  0x7D,  0x08,  0x01,  0x08,  0x02,  0x08,  0x04,  0x08,  0x00,  0x08,  0xAD, 	/* 28E10 */
+	0x00,  0x20,  0x00,  0x20,  0x7C,  0x20,  0x47,  0xFF,  0x44,  0x00,  0x44,  0x00,  0x44,  0xF8,  0x44,  0x88, 	/* 28E20 */
+	0x44,  0x88,  0x44,  0x88,  0x44,  0x88,  0x7C,  0x88,  0x00,  0x89,  0x01,  0x09,  0x02,  0x07,  0x04,  0x00, 	/* 28E30 */
+	0xAE,  0x00,  0x20,  0x00,  0x20,  0x7C,  0x40,  0x44,  0x50,  0x44,  0x4C,  0x44,  0x9A,  0x47,  0xE9,  0x44, 	/* 28E40 */
+	0x48,  0x44,  0x48,  0x44,  0x48,  0x44,  0x48,  0x7C,  0x88,  0x00,  0x88,  0x01,  0x09,  0x02,  0x09,  0x04, 	/* 28E50 */
+	0x07,  0xB6,  0x00,  0x20,  0x00,  0x20,  0x78,  0x20,  0x4B,  0xFE,  0x4A,  0x22,  0x4A,  0x22,  0x4A,  0x22, 	/* 28E60 */
+	0x4A,  0x22,  0x4A,  0x52,  0x4A,  0x52,  0x4A,  0x8A,  0x7B,  0x06,  0x02,  0x02,  0x02,  0x02,  0x02,  0x02, 	/* 28E70 */
+	0x02,  0x06,  0xB8,  0x00,  0x00,  0x01,  0xF8,  0x7C,  0x88,  0x44,  0x90,  0x44,  0x90,  0x44,  0xBC,  0x44, 	/* 28E80 */
+	0xC4,  0x44,  0xC4,  0x44,  0xA4,  0x45,  0x28,  0x7D,  0x28,  0x01,  0x10,  0x02,  0x28,  0x02,  0x44,  0x04, 	/* 28E90 */
+	0x82,  0x09,  0x01,  0xB9,  0x00,  0x80,  0x00,  0x80,  0x7C,  0x80,  0x44,  0xFE,  0x45,  0x02,  0x45,  0x24, 	/* 28EA0 */
+	0x46,  0x28,  0x44,  0x20,  0x44,  0x20,  0x44,  0x20,  0x44,  0x50,  0x7C,  0x50,  0x00,  0x88,  0x01,  0x04, 	/* 28EB0 */
+	0x06,  0x02,  0x18,  0x01,  0xBB,  0x01,  0x00,  0x01,  0x00,  0x01,  0x00,  0x79,  0xFE,  0x49,  0x4A,  0x49, 	/* 28EC0 */
+	0x4A,  0x4A,  0x4A,  0x4A,  0x4A,  0x4C,  0x8A,  0x48,  0x92,  0x49,  0x12,  0x4A,  0x22,  0x78,  0x22,  0x00, 	/* 28ED0 */
+	0x42,  0x00,  0x84,  0x00,  0x18,  0xBC,  0x00,  0x08,  0x03,  0xE8,  0x78,  0x28,  0x48,  0x48,  0x48,  0x88, 	/* 28EE0 */
+	0x48,  0x88,  0x48,  0xA8,  0x48,  0xC8,  0x49,  0x88,  0x4E,  0x88,  0x48,  0x88,  0x78,  0x88,  0x00,  0x88, 	/* 28EF0 */
+	0x00,  0x89,  0x00,  0x89,  0x01,  0x87,  0xBD,  0x00,  0x20,  0x01,  0x20,  0x79,  0x20,  0x49,  0x20,  0x4B, 	/* 28F00 */
+	0xFE,  0x4A,  0x20,  0x4C,  0x20,  0x48,  0x20,  0x48,  0x20,  0x4F,  0xFF,  0x48,  0x20,  0x78,  0x20,  0x00, 	/* 28F10 */
+	0x20,  0x00,  0x20,  0x00,  0x20,  0x00,  0x20,  0xBE,  0x00,  0x00,  0x3F,  0xFC,  0x01,  0x00,  0x01,  0x00, 	/* 28F20 */
+	0x1F,  0xF0,  0x02,  0x10,  0x02,  0x10,  0x02,  0x10,  0x7F,  0xFE,  0x00,  0x00,  0x0F,  0xF8,  0x08,  0x08, 	/* 28F30 */
+	0x08,  0x08,  0x08,  0x08,  0x0F,  0xF8,  0x00,  0x00,  0x80,  0x00,  0x00,  0x03,  0xFE,  0x78,  0x88,  0x48, 	/* 28F40 */
+	0x88,  0x48,  0x88,  0x48,  0x88,  0x48,  0x88,  0x4F,  0xFF,  0x48,  0x28,  0x48,  0x28,  0x78,  0x48,  0x00, 	/* 28F50 */
+	0x88,  0x01,  0x08,  0x02,  0x08,  0x04,  0x08,  0x00,  0x18,  0x82,  0x00,  0x00,  0x0F,  0xF8,  0x08,  0x08, 	/* 28F60 */
+	0x08,  0x08,  0x08,  0x08,  0x0F,  0xF8,  0x00,  0x80,  0x00,  0x80,  0x01,  0x00,  0x1F,  0xFC,  0x10,  0x04, 	/* 28F70 */
+	0x10,  0x04,  0x10,  0x04,  0x10,  0x04,  0x1F,  0xFC,  0x00,  0x00,  0x86,  0x00,  0x00,  0x0F,  0xF8,  0x08, 	/* 28F80 */
+	0x08,  0x08,  0x08,  0x08,  0x08,  0x08,  0x08,  0x0F,  0xF8,  0x00,  0x80,  0x00,  0x80,  0x7F,  0xFF,  0x01, 	/* 28F90 */
+	0xC0,  0x02,  0xA0,  0x04,  0x90,  0x18,  0x8C,  0x60,  0x83,  0x00,  0x80,  0x88,  0x00,  0x00,  0x0F,  0xF8, 	/* 28FA0 */
+	0x08,  0x08,  0x08,  0x08,  0x08,  0x08,  0x0F,  0xF8,  0x00,  0x00,  0x00,  0x00,  0x1F,  0xFC,  0x00,  0x80, 	/* 28FB0 */
+	0x00,  0x80,  0x0F,  0xF8,  0x00,  0x80,  0x00,  0x80,  0x7F,  0xFE,  0x00,  0x00,  0x89,  0x00,  0x00,  0x03, 	/* 28FC0 */
+	0xF8,  0x12,  0x08,  0x12,  0x08,  0x12,  0x08,  0x13,  0xF8,  0x10,  0x00,  0x10,  0x00,  0x1F,  0xF8,  0x00, 	/* 28FD0 */
+	0x08,  0x00,  0x08,  0x7F,  0xFF,  0x00,  0x00,  0x02,  0x10,  0x0C,  0x08,  0x30,  0x04,  0x8A,  0x00,  0x80, 	/* 28FE0 */
+	0x08,  0x80,  0x08,  0x80,  0x0F,  0xFC,  0x10,  0x80,  0x10,  0x80,  0x20,  0x80,  0x7F,  0xFF,  0x00,  0x00, 	/* 28FF0 */
+	0x00,  0x00,  0x0F,  0xF8,  0x08,  0x08,  0x08,  0x08,  0x08,  0x08,  0x0F,  0xF8,  0x00,  0x00,  0x8E,  0x00, 	/* 29000 */
+	0x00,  0x01,  0xFC,  0x7D,  0x04,  0x45,  0x04,  0x45,  0x04,  0x45,  0x04,  0x45,  0xFC,  0x45,  0x20,  0x45, 	/* 29010 */
+	0x20,  0x45,  0x20,  0x7D,  0x10,  0x02,  0x10,  0x02,  0x08,  0x04,  0x04,  0x08,  0x02,  0x10,  0x01,  0x91, 	/* 29020 */
+	0x00,  0x10,  0x00,  0x60,  0x1F,  0x80,  0x00,  0x80,  0x00,  0x80,  0x7F,  0xFF,  0x01,  0x40,  0x02,  0x20, 	/* 29030 */
+	0x04,  0x10,  0x18,  0x0C,  0x6F,  0xFB,  0x08,  0x08,  0x08,  0x08,  0x08,  0x08,  0x0F,  0xF8,  0x00,  0x00, 	/* 29040 */
+	0x9F,  0x00,  0x20,  0x00,  0x20,  0x00,  0x20,  0x7F,  0xFF,  0x48,  0x20,  0x48,  0x20,  0x48,  0x48,  0x4B, 	/* 29050 */
+	0x88,  0x48,  0x50,  0x48,  0x60,  0x48,  0x20,  0x48,  0x48,  0x78,  0x84,  0x01,  0x3C,  0x07,  0xC2,  0x00, 	/* 29060 */
+	0x02,  0xA8,  0x00,  0x00,  0x1F,  0xFE,  0x10,  0x42,  0x10,  0x42,  0x17,  0xFA,  0x10,  0x42,  0x10,  0x42, 	/* 29070 */
+	0x1F,  0xFE,  0x10,  0x02,  0x13,  0xF2,  0x12,  0x12,  0x12,  0x12,  0x12,  0x12,  0x23,  0xF2,  0x20,  0x02, 	/* 29080 */
+	0x40,  0x06,  0xAA,  0x00,  0x00,  0x01,  0xFC,  0x7D,  0x04,  0x45,  0x04,  0x45,  0x04,  0x45,  0x04,  0x45, 	/* 29090 */
+	0x04,  0x45,  0xFC,  0x44,  0x50,  0x44,  0x50,  0x7C,  0x50,  0x00,  0x90,  0x00,  0x90,  0x01,  0x11,  0x02, 	/* 290A0 */
+	0x11,  0x04,  0x0F,  0xB0,  0x04,  0x40,  0x04,  0x42,  0x14,  0x4C,  0x17,  0xF0,  0x14,  0x40,  0x14,  0x40, 	/* 290B0 */
+	0x14,  0x42,  0x17,  0x42,  0x1C,  0x3E,  0x60,  0x00,  0x0F,  0xF8,  0x08,  0x08,  0x08,  0x08,  0x08,  0x08, 	/* 290C0 */
+	0x0F,  0xF8,  0x00,  0x00,  0xB1,  0x00,  0x04,  0x00,  0x18,  0x7B,  0xE8,  0x4A,  0x08,  0x4A,  0x48,  0x4A, 	/* 290D0 */
+	0x48,  0x4A,  0x48,  0x4A,  0x48,  0x4A,  0x48,  0x4A,  0x48,  0x4A,  0x64,  0x7A,  0x54,  0x04,  0x54,  0x04, 	/* 290E0 */
+	0x5A,  0x0B,  0xEA,  0x10,  0x09,  0xB3,  0x00,  0x20,  0x00,  0x20,  0x78,  0x20,  0x4B,  0xFE,  0x48,  0x20, 	/* 290F0 */
+	0x48,  0x20,  0x48,  0x20,  0x4F,  0xFF,  0x48,  0x70,  0x48,  0x70,  0x48,  0xA8,  0x79,  0x24,  0x02,  0x22, 	/* 29100 */
+	0x04,  0x21,  0x00,  0x20,  0x00,  0x20,  0xB5,  0x00,  0x00,  0x07,  0xFF,  0x78,  0x04,  0x48,  0x04,  0x49, 	/* 29110 */
+	0xE4,  0x49,  0x24,  0x49,  0x24,  0x49,  0x24,  0x49,  0x24,  0x49,  0xE4,  0x48,  0x04,  0x48,  0x04,  0x78, 	/* 29120 */
+	0x04,  0x00,  0x04,  0x00,  0x04,  0x00,  0x0C,  0xB6,  0x01,  0x00,  0x01,  0x3E,  0x79,  0x02,  0x4F,  0xC2, 	/* 29130 */
+	0x49,  0x52,  0x49,  0x52,  0x49,  0x52,  0x4A,  0x52,  0x4A,  0x54,  0x4F,  0xD4,  0x48,  0x88,  0x78,  0xCC, 	/* 29140 */
+	0x01,  0x14,  0x02,  0x22,  0x0C,  0x42,  0x00,  0x81,  0xB7,  0x00,  0x00,  0x01,  0xFE,  0x3D,  0x22,  0x25, 	/* 29150 */
+	0x22,  0x25,  0x22,  0x25,  0xFE,  0x25,  0x22,  0x25,  0x22,  0x25,  0x22,  0x25,  0xFE,  0x24,  0x20,  0x3C, 	/* 29160 */
+	0x20,  0x00,  0x20,  0x00,  0x20,  0x00,  0x20,  0x00,  0x20,  0xBB,  0x00,  0x20,  0x00,  0x20,  0x3D,  0xFE, 	/* 29170 */
+	0x25,  0x22,  0x25,  0x22,  0x25,  0x22,  0x25,  0xFE,  0x25,  0x22,  0x25,  0x22,  0x25,  0x22,  0x25,  0xFE, 	/* 29180 */
+	0x3C,  0x20,  0x00,  0x20,  0x00,  0x20,  0x00,  0x20,  0x00,  0x20,  0xBC,  0x00,  0x06,  0x00,  0x38,  0x7D, 	/* 29190 */
+	0xE0,  0x44,  0x22,  0x45,  0x22,  0x44,  0xA4,  0x44,  0xA8,  0x44,  0x20,  0x47,  0xFF,  0x44,  0x20,  0x44, 	/* 291A0 */
+	0x20,  0x7C,  0x20,  0x00,  0x20,  0x00,  0x20,  0x00,  0x20,  0x00,  0x60,  0xBD,  0x00,  0x80,  0x00,  0x80, 	/* 291B0 */
+	0x01,  0x40,  0x02,  0x20,  0x04,  0x10,  0x1B,  0xEC,  0x60,  0x03,  0x00,  0x00,  0x1E,  0x7C,  0x12,  0x44, 	/* 291C0 */
+	0x12,  0x44,  0x12,  0x44,  0x12,  0x44,  0x1E,  0x58,  0x00,  0x40,  0x00,  0x40,  0x80,  0x00,  0x00,  0x00, 	/* 291D0 */
+	0xFC,  0x7C,  0x84,  0x44,  0x84,  0x44,  0x84,  0x44,  0xFC,  0x44,  0x84,  0x44,  0x84,  0x44,  0x84,  0x44, 	/* 291E0 */
+	0xFC,  0x7C,  0x84,  0x00,  0x84,  0x00,  0x84,  0x00,  0x84,  0x07,  0xFF,  0x00,  0x00,  0x84,  0x00,  0x20, 	/* 291F0 */
+	0x02,  0x22,  0x7A,  0x22,  0x4A,  0x22,  0x4A,  0x22,  0x4A,  0x22,  0x4B,  0xFE,  0x48,  0x20,  0x48,  0x20, 	/* 29200 */
+	0x4A,  0x22,  0x4A,  0x22,  0x7A,  0x22,  0x02,  0x22,  0x02,  0x22,  0x03,  0xFE,  0x00,  0x00,  0x86,  0x01, 	/* 29210 */
+	0x00,  0x01,  0x00,  0x79,  0xFE,  0x49,  0x02,  0x4A,  0x02,  0x4B,  0xF2,  0x4D,  0x12,  0x49,  0x12,  0x49, 	/* 29220 */
+	0x12,  0x49,  0xF2,  0x49,  0x04,  0x79,  0x18,  0x01,  0x01,  0x01,  0x01,  0x00,  0x81,  0x00,  0x7F,  0x8B, 	/* 29230 */
+	0x00,  0x80,  0x00,  0x80,  0x7C,  0x80,  0x44,  0xFF,  0x45,  0x20,  0x45,  0x20,  0x46,  0x20,  0x44,  0x3E, 	/* 29240 */
+	0x44,  0x20,  0x44,  0x20,  0x44,  0x20,  0x7C,  0x3E,  0x00,  0x20,  0x00,  0x20,  0x00,  0x20,  0x00,  0x20, 	/* 29250 */
+	0x8C,  0x01,  0x00,  0x06,  0x00,  0x3C,  0x7E,  0x04,  0x42,  0x04,  0x42,  0x04,  0x42,  0x7F,  0xC2,  0x0C, 	/* 29260 */
+	0x42,  0x0E,  0x42,  0x15,  0x42,  0x14,  0xC2,  0x24,  0x42,  0x44,  0x7E,  0x04,  0x00,  0x04,  0x00,  0x04, 	/* 29270 */
+	0x00,  0x8E,  0x08,  0x10,  0x0F,  0x10,  0x09,  0x10,  0x12,  0x10,  0x32,  0x28,  0x4C,  0x44,  0x04,  0x82, 	/* 29280 */
+	0x0B,  0x00,  0x10,  0xC0,  0x20,  0x3F,  0x40,  0x00,  0x0F,  0xF8,  0x08,  0x08,  0x08,  0x08,  0x0F,  0xF8, 	/* 29290 */
+	0x00,  0x00,  0x8F,  0x00,  0x40,  0x00,  0x20,  0x00,  0x20,  0x78,  0x00,  0x49,  0xE2,  0x48,  0x22,  0x48, 	/* 292A0 */
+	0x34,  0x4F,  0xB4,  0x48,  0xB8,  0x49,  0x28,  0x49,  0x28,  0x7A,  0x24,  0x04,  0x22,  0x18,  0x21,  0x00, 	/* 292B0 */
+	0x20,  0x00,  0x60,  0x90,  0x00,  0x84,  0x00,  0x84,  0x78,  0x84,  0x48,  0x84,  0x49,  0x7F,  0x49,  0x04, 	/* 292C0 */
+	0x4B,  0x04,  0x4D,  0x44,  0x49,  0x24,  0x49,  0x24,  0x49,  0x04,  0x79,  0x04,  0x01,  0x04,  0x01,  0x04, 	/* 292D0 */
+	0x01,  0x04,  0x01,  0x0C,  0x92,  0x00,  0x00,  0x3E,  0x7C,  0x22,  0x44,  0x22,  0x44,  0x22,  0x44,  0x3E, 	/* 292E0 */
+	0x7C,  0x00,  0x00,  0x07,  0xE0,  0x04,  0x20,  0x04,  0x20,  0x04,  0x20,  0x04,  0x22,  0x04,  0x22,  0x08, 	/* 292F0 */
+	0x22,  0x10,  0x1E,  0x60,  0x00,  0xA2,  0x00,  0x00,  0x1F,  0x3E,  0x11,  0x22,  0x11,  0x22,  0x1F,  0x3E, 	/* 29300 */
+	0x00,  0x00,  0x0F,  0xFC,  0x00,  0x00,  0x7F,  0xFF,  0x01,  0x00,  0x01,  0x00,  0x03,  0xF8,  0x02,  0x08, 	/* 29310 */
+	0x00,  0x08,  0x00,  0x10,  0x00,  0xE0,  0xA4,  0x00,  0x20,  0x00,  0x20,  0x7B,  0xFF,  0x4A,  0x01,  0x4A, 	/* 29320 */
+	0x09,  0x48,  0x30,  0x4B,  0xC0,  0x48,  0x40,  0x48,  0x40,  0x48,  0x7F,  0x4F,  0xC0,  0x78,  0x40,  0x00, 	/* 29330 */
+	0x40,  0x00,  0x42,  0x00,  0x22,  0x00,  0x1E,  0xA5,  0x00,  0x00,  0x07,  0xFF,  0x00,  0x40,  0x7C,  0x50, 	/* 29340 */
+	0x44,  0x8C,  0x45,  0x1A,  0x47,  0xE1,  0x44,  0x00,  0x44,  0x20,  0x44,  0x20,  0x45,  0xFE,  0x7C,  0x20, 	/* 29350 */
+	0x00,  0x20,  0x00,  0x20,  0x07,  0xFF,  0x00,  0x00,  0xA8,  0x00,  0x80,  0x00,  0x80,  0x79,  0xFF,  0x01, 	/* 29360 */
+	0x22,  0x02,  0x24,  0x00,  0x30,  0x0C,  0x48,  0x31,  0x84,  0x46,  0x03,  0x00,  0x00,  0x0F,  0xF8,  0x08, 	/* 29370 */
+	0x08,  0x08,  0x08,  0x08,  0x08,  0x0F,  0xF8,  0x00,  0x00,  0xAB,  0x00,  0x00,  0x1F,  0x7E,  0x11,  0x42, 	/* 29380 */
+	0x11,  0x42,  0x11,  0x42,  0x11,  0x42,  0x11,  0x42,  0x1F,  0x7E,  0x18,  0x00,  0x18,  0x24,  0x14,  0x22, 	/* 29390 */
+	0x14,  0x41,  0x12,  0x81,  0x21,  0x00,  0x20,  0xC0,  0x40,  0x3F,  0xAC,  0x00,  0x20,  0x00,  0x20,  0x78, 	/* 293A0 */
+	0x20,  0x4F,  0xFF,  0x48,  0x88,  0x48,  0x84,  0x49,  0x02,  0x4A,  0x8A,  0x48,  0x88,  0x48,  0x50,  0x48, 	/* 293B0 */
+	0x50,  0x78,  0x20,  0x00,  0x50,  0x00,  0x88,  0x03,  0x04,  0x0C,  0x03,  0xAF,  0x00,  0x40,  0x00,  0x40, 	/* 293C0 */
+	0x78,  0xF8,  0x48,  0x88,  0x49,  0x88,  0x49,  0x50,  0x4A,  0x20,  0x48,  0x50,  0x48,  0x8C,  0x49,  0x03, 	/* 293D0 */
+	0x4F,  0xFC,  0x79,  0x04,  0x01,  0x04,  0x01,  0x04,  0x01,  0xFC,  0x00,  0x00,  0xB2,  0x01,  0x04,  0x00, 	/* 293E0 */
+	0x84,  0x00,  0x48,  0x3E,  0x50,  0x23,  0xFE,  0x22,  0x20,  0x22,  0x20,  0x22,  0x20,  0x23,  0xFF,  0x22, 	/* 293F0 */
+	0x20,  0x22,  0x50,  0x3E,  0x50,  0x00,  0x88,  0x01,  0x04,  0x06,  0x02,  0x18,  0x01,  0xB3,  0x00,  0x20, 	/* 29400 */
+	0x00,  0x20,  0x7C,  0x20,  0x47,  0xFF,  0x44,  0x40,  0x44,  0x48,  0x44,  0x90,  0x47,  0x90,  0x44,  0x64, 	/* 29410 */
+	0x44,  0x44,  0x44,  0x88,  0x7F,  0x10,  0x00,  0x28,  0x00,  0x44,  0x01,  0x82,  0x06,  0x02,  0xB8,  0x00, 	/* 29420 */
+	0x24,  0x00,  0x22,  0x00,  0x22,  0x1F,  0xFF,  0x10,  0x20,  0x10,  0x20,  0x1F,  0xE2,  0x10,  0x12,  0x10, 	/* 29430 */
+	0x12,  0x17,  0xD4,  0x14,  0x54,  0x14,  0x48,  0x17,  0xD9,  0x20,  0x25,  0x20,  0x43,  0x40,  0x81,  0xBC, 	/* 29440 */
+	0x00,  0x00,  0x0F,  0xF8,  0x08,  0x08,  0x08,  0xF8,  0x08,  0x88,  0x08,  0x88,  0x08,  0x88,  0x3F,  0xFE, 	/* 29450 */
+	0x20,  0x02,  0x23,  0xE2,  0x22,  0x22,  0x22,  0x22,  0x22,  0x22,  0x23,  0xE2,  0x20,  0x02,  0x20,  0x06, 	/* 29460 */
+	0xBD,  0x00,  0x00,  0x03,  0xFE,  0x7A,  0x22,  0x4A,  0x22,  0x4A,  0x22,  0x4A,  0x22,  0x4B,  0xFE,  0x4A, 	/* 29470 */
+	0x22,  0x4A,  0x22,  0x4A,  0x52,  0x4A,  0x52,  0x7A,  0x8A,  0x03,  0x06,  0x02,  0x02,  0x03,  0xFE,  0x00, 	/* 29480 */
+	0x00,  0xBE,  0x00,  0x40,  0x00,  0x44,  0x03,  0xFC,  0x7C,  0x48,  0x44,  0x48,  0x44,  0x50,  0x47,  0xFF, 	/* 29490 */
+	0x44,  0x20,  0x44,  0x40,  0x44,  0x44,  0x44,  0xC8,  0x45,  0x70,  0x7E,  0x40,  0x04,  0x42,  0x00,  0x22, 	/* 294A0 */
+	0x00,  0x1E,  0x80,  0x00,  0x80,  0x00,  0x80,  0x7F,  0xFF,  0x00,  0x00,  0x0F,  0xF8,  0x08,  0x08,  0x08, 	/* 294B0 */
+	0x08,  0x08,  0x08,  0x0F,  0xFA,  0x01,  0x82,  0x0E,  0x84,  0x72,  0x48,  0x02,  0x30,  0x03,  0x90,  0x0E, 	/* 294C0 */
+	0x0C,  0x30,  0x03,  0x81,  0x00,  0x00,  0x07,  0xF0,  0x04,  0x10,  0x04,  0x10,  0x04,  0x10,  0x04,  0x10, 	/* 294D0 */
+	0x07,  0xF0,  0x00,  0x00,  0x00,  0x00,  0x3F,  0x7E,  0x21,  0x42,  0x21,  0x42,  0x21,  0x42,  0x21,  0x42, 	/* 294E0 */
+	0x3F,  0x7E,  0x00,  0x00,  0x82,  0x00,  0x00,  0x07,  0xFF,  0x78,  0x50,  0x48,  0x50,  0x48,  0x50,  0x4B, 	/* 294F0 */
+	0xFE,  0x4A,  0x52,  0x4A,  0x52,  0x4A,  0x56,  0x4A,  0x96,  0x4A,  0x8E,  0x7B,  0x02,  0x02,  0x02,  0x02, 	/* 29500 */
+	0x02,  0x03,  0xFE,  0x00,  0x00,  0x84,  0x00,  0x88,  0x00,  0x88,  0x78,  0x88,  0x4B,  0xFE,  0x48,  0x88, 	/* 29510 */
+	0x48,  0x88,  0x48,  0x88,  0x48,  0x88,  0x48,  0x88,  0x4F,  0xFF,  0x48,  0x00,  0x78,  0x00,  0x00,  0x88, 	/* 29520 */
+	0x01,  0x04,  0x02,  0x02,  0x0C,  0x02,  0x87,  0x00,  0x20,  0x00,  0x20,  0x7D,  0xFC,  0x44,  0x20,  0x44, 	/* 29530 */
+	0x20,  0x44,  0x20,  0x47,  0xFE,  0x44,  0x00,  0x44,  0x20,  0x44,  0x20,  0x47,  0xFE,  0x7C,  0x20,  0x00, 	/* 29540 */
+	0x20,  0x00,  0x20,  0x07,  0xFF,  0x00,  0x00,  0x88,  0x00,  0x20,  0x00,  0x20,  0x78,  0x50,  0x48,  0x50, 	/* 29550 */
+	0x48,  0x88,  0x49,  0x04,  0x4A,  0x02,  0x4D,  0xFD,  0x48,  0x00,  0x48,  0x00,  0x49,  0xFC,  0x79,  0x04, 	/* 29560 */
+	0x01,  0x04,  0x01,  0x04,  0x01,  0xFC,  0x00,  0x00,  0x89,  0x02,  0x20,  0x02,  0x28,  0x1F,  0xE4,  0x02, 	/* 29570 */
+	0x24,  0x02,  0x20,  0x7F,  0xFF,  0x00,  0x24,  0x00,  0x24,  0x1F,  0x24,  0x11,  0x28,  0x11,  0x18,  0x11, 	/* 29580 */
+	0x10,  0x1F,  0x2A,  0x00,  0x4A,  0x00,  0x86,  0x03,  0x02,  0x98,  0x00,  0x80,  0x00,  0x9E,  0x79,  0x00, 	/* 29590 */
+	0x49,  0x00,  0x4A,  0x40,  0x4C,  0x40,  0x48,  0xBF,  0x48,  0x84,  0x49,  0x04,  0x4B,  0x04,  0x4D,  0x04, 	/* 295A0 */
+	0x79,  0x04,  0x01,  0x04,  0x01,  0x04,  0x01,  0x04,  0x01,  0x0C,  0xA1,  0x00,  0x00,  0x0F,  0xF8,  0x08, 	/* 295B0 */
+	0x08,  0x08,  0x08,  0x0F,  0xF8,  0x00,  0x00,  0x1F,  0xFC,  0x10,  0x04,  0x1F,  0xFC,  0x10,  0x04,  0x1F, 	/* 295C0 */
+	0xFC,  0x10,  0x04,  0x1F,  0xFC,  0x02,  0x30,  0x0C,  0x0C,  0x30,  0x02,  0xA2,  0x00,  0x00,  0x03,  0xFE, 	/* 295D0 */
+	0x78,  0x20,  0x48,  0x20,  0x49,  0xFC,  0x48,  0x20,  0x48,  0x20,  0x4F,  0xFF,  0x48,  0x88,  0x48,  0x88, 	/* 295E0 */
+	0x4F,  0xFF,  0x78,  0x88,  0x00,  0x88,  0x01,  0x08,  0x01,  0x08,  0x02,  0x08,  0xA5,  0x00,  0x00,  0x7F, 	/* 295F0 */
+	0xFF,  0x00,  0x08,  0x0F,  0x88,  0x08,  0x88,  0x08,  0x88,  0x0F,  0x98,  0x00,  0x00,  0x7F,  0xFF,  0x00, 	/* 29600 */
+	0x08,  0x0F,  0x88,  0x08,  0x88,  0x08,  0x88,  0x0F,  0x88,  0x00,  0x08,  0x00,  0x18,  0xA6,  0x00,  0x30, 	/* 29610 */
+	0x00,  0xD4,  0x7B,  0x92,  0x48,  0x92,  0x48,  0x90,  0x4F,  0xFF,  0x48,  0x90,  0x48,  0x92,  0x48,  0x92, 	/* 29620 */
+	0x48,  0xD4,  0x4B,  0x8C,  0x78,  0x88,  0x00,  0x95,  0x00,  0xA5,  0x00,  0xC3,  0x01,  0x81,  0xA8,  0x00, 	/* 29630 */
+	0x10,  0x00,  0x92,  0x00,  0x52,  0x3E,  0x54,  0x22,  0x10,  0x22,  0xFE,  0x22,  0x82,  0x22,  0x82,  0x22, 	/* 29640 */
+	0xFE,  0x22,  0x82,  0x22,  0x82,  0x3E,  0xFE,  0x00,  0x82,  0x00,  0x82,  0x00,  0x82,  0x00,  0x86,  0xA9, 	/* 29650 */
+	0x00,  0x00,  0x01,  0xFC,  0x7D,  0x24,  0x45,  0x24,  0x45,  0xFC,  0x45,  0x24,  0x45,  0x24,  0x45,  0x24, 	/* 29660 */
+	0x45,  0xFC,  0x44,  0x20,  0x7C,  0x20,  0x03,  0xFE,  0x00,  0x20,  0x00,  0x20,  0x07,  0xFF,  0x00,  0x00, 	/* 29670 */
+	0xAD,  0x00,  0x00,  0x3E,  0x7C,  0x22,  0x44,  0x22,  0x44,  0x22,  0x44,  0x3E,  0x7C,  0x00,  0x90,  0x00, 	/* 29680 */
+	0x88,  0x00,  0x88,  0x7F,  0xFF,  0x00,  0x80,  0x01,  0x40,  0x02,  0x20,  0x04,  0x10,  0x18,  0x0C,  0x60, 	/* 29690 */
+	0x03,  0xAE,  0x00,  0x40,  0x00,  0x44,  0x7B,  0xFC,  0x48,  0x48,  0x48,  0x50,  0x4F,  0xFF,  0x48,  0x20, 	/* 296A0 */
+	0x48,  0x7C,  0x48,  0x88,  0x4B,  0x10,  0x4C,  0x20,  0x7B,  0xFF,  0x00,  0x20,  0x00,  0x20,  0x00,  0x20, 	/* 296B0 */
+	0x00,  0x60,  0xB2,  0x08,  0x04,  0x08,  0xF8,  0x7E,  0x80,  0x08,  0x80,  0x08,  0xFF,  0x0E,  0x88,  0x78, 	/* 296C0 */
+	0x88,  0x09,  0x08,  0x09,  0x08,  0x1A,  0x08,  0x00,  0x08,  0x1F,  0xF8,  0x10,  0x08,  0x10,  0x08,  0x1F, 	/* 296D0 */
+	0xF8,  0x00,  0x00,  0xBA,  0x00,  0x28,  0x00,  0x24,  0x07,  0xFF,  0x78,  0x20,  0x48,  0x20,  0x4B,  0xFC, 	/* 296E0 */
+	0x4A,  0x24,  0x4A,  0x24,  0x4B,  0xFC,  0x4A,  0x24,  0x4A,  0x24,  0x4B,  0xFC,  0x7A,  0x24,  0x02,  0x24, 	/* 296F0 */
+	0x02,  0x24,  0x02,  0x2C,  0xBD,  0x00,  0x00,  0x07,  0xFF,  0x78,  0x20,  0x49,  0xFC,  0x49,  0x24,  0x49, 	/* 29700 */
+	0x24,  0x49,  0xFC,  0x49,  0x24,  0x49,  0x24,  0x49,  0xFC,  0x79,  0x20,  0x00,  0xA0,  0x00,  0x40,  0x00, 	/* 29710 */
+	0xA0,  0x03,  0x18,  0x0C,  0x07,  0x84,  0x00,  0x00,  0x00,  0x7E,  0x3E,  0x42,  0x22,  0x42,  0x22,  0x42, 	/* 29720 */
+	0x22,  0x7E,  0x22,  0x42,  0x22,  0x42,  0x22,  0x7E,  0x22,  0x42,  0x22,  0x42,  0x3E,  0x42,  0x00,  0x7E, 	/* 29730 */
+	0x00,  0x24,  0x00,  0xC2,  0x03,  0x01,  0x86,  0x00,  0x40,  0x00,  0x50,  0x00,  0x8C,  0x7B,  0xFA,  0x48, 	/* 29740 */
+	0x90,  0x48,  0x91,  0x49,  0x0F,  0x4A,  0x40,  0x4C,  0x78,  0x48,  0x88,  0x49,  0x08,  0x7E,  0xD0,  0x48, 	/* 29750 */
+	0x20,  0x00,  0xD0,  0x03,  0x0C,  0x0C,  0x03,  0x87,  0x00,  0x00,  0x1F,  0xFE,  0x10,  0x00,  0x1F,  0xFC, 	/* 29760 */
+	0x10,  0x00,  0x1F,  0xFF,  0x12,  0x84,  0x12,  0x58,  0x32,  0x20,  0x23,  0x98,  0x5C,  0x07,  0x0F,  0xF8, 	/* 29770 */
+	0x08,  0x08,  0x08,  0x08,  0x0F,  0xF8,  0x00,  0x00,  0x8F,  0x00,  0x04,  0x00,  0xC8,  0x78,  0x30,  0x48, 	/* 29780 */
+	0x68,  0x4B,  0xA4,  0x48,  0x40,  0x4F,  0xFF,  0x48,  0x40,  0x48,  0xA0,  0x49,  0xFC,  0x4B,  0x24,  0x7D, 	/* 29790 */
+	0x24,  0x09,  0x24,  0x01,  0x38,  0x01,  0x20,  0x00,  0x20,  0x90,  0x00,  0x80,  0x00,  0x80,  0x1F,  0xFF, 	/* 297A0 */
+	0x10,  0x40,  0x17,  0xFC,  0x10,  0x44,  0x1F,  0xFF,  0x10,  0x44,  0x10,  0x44,  0x17,  0xFC,  0x10,  0x00, 	/* 297B0 */
+	0x17,  0xFC,  0x24,  0x04,  0x24,  0x04,  0x47,  0xFC,  0x00,  0x00,  0x94,  0x00,  0x00,  0x07,  0xFE,  0x78, 	/* 297C0 */
+	0x40,  0x48,  0x40,  0x4B,  0xF8,  0x48,  0x88,  0x48,  0x88,  0x48,  0x88,  0x4F,  0xFF,  0x48,  0x00,  0x49, 	/* 297D0 */
+	0xFC,  0x79,  0x04,  0x01,  0x04,  0x01,  0x04,  0x01,  0xFC,  0x00,  0x00,  0x96,  0x00,  0x00,  0x07,  0xFF, 	/* 297E0 */
+	0x78,  0x48,  0x48,  0x48,  0x48,  0x48,  0x4B,  0xFE,  0x4A,  0x4A,  0x4A,  0x4A,  0x4A,  0x4A,  0x4B,  0xFE, 	/* 297F0 */
+	0x48,  0x48,  0x78,  0x48,  0x48,  0x48,  0x00,  0x48,  0x07,  0xFF,  0x00,  0x00,  0xAE,  0x08,  0x20,  0x08, 	/* 29800 */
+	0x40,  0x1F,  0xFE,  0x10,  0x40,  0x3F,  0xFC,  0x50,  0x40,  0x1F,  0xFC,  0x10,  0x40,  0x1F,  0xFE,  0x00, 	/* 29810 */
+	0x00,  0x1F,  0xF8,  0x10,  0x08,  0x10,  0x08,  0x10,  0x08,  0x1F,  0xF8,  0x00,  0x00,  0xAF,  0x00,  0x44, 	/* 29820 */
+	0x00,  0x44,  0x3C,  0x48,  0x24,  0xFF,  0x24,  0x88,  0x25,  0x88,  0x26,  0x88,  0x24,  0xFE,  0x24,  0x88, 	/* 29830 */
+	0x24,  0x88,  0x24,  0xFE,  0x3C,  0x88,  0x00,  0x88,  0x00,  0x88,  0x00,  0xFF,  0x00,  0x00,  0xB1,  0x00, 	/* 29840 */
+	0x00,  0x00,  0xFC,  0x00,  0x84,  0x7C,  0x84,  0x44,  0xFC,  0x44,  0x84,  0x44,  0x84,  0x44,  0xFC,  0x44, 	/* 29850 */
+	0x00,  0x45,  0xFE,  0x7D,  0x02,  0x01,  0xFE,  0x01,  0x02,  0x01,  0x02,  0x01,  0xFE,  0x00,  0x00,  0xB3, 	/* 29860 */
+	0x00,  0x00,  0x03,  0xFF,  0x78,  0x00,  0x49,  0xFE,  0x49,  0x02,  0x49,  0x02,  0x49,  0xFE,  0x49,  0x10, 	/* 29870 */
+	0x49,  0x10,  0x49,  0xFF,  0x49,  0x10,  0x7A,  0x18,  0x02,  0x28,  0x04,  0x44,  0x09,  0x82,  0x06,  0x01, 	/* 29880 */
+	0xB8,  0x00,  0x20,  0x00,  0x20,  0x00,  0x50,  0x78,  0x88,  0x49,  0x04,  0x4E,  0xFB,  0x48,  0x00,  0x49, 	/* 29890 */
+	0xF8,  0x48,  0x08,  0x48,  0x10,  0x48,  0x20,  0x7A,  0x94,  0x02,  0x92,  0x04,  0x85,  0x08,  0x85,  0x00, 	/* 298A0 */
+	0x7C,  0xB9,  0x01,  0x08,  0x01,  0x08,  0x79,  0x08,  0x4F,  0xF4,  0x49,  0x14,  0x49,  0x14,  0x49,  0xE2, 	/* 298B0 */
+	0x49,  0x72,  0x49,  0x49,  0x49,  0x48,  0x4A,  0x40,  0x7A,  0x50,  0x02,  0x48,  0x04,  0x44,  0x08,  0x42, 	/* 298C0 */
+	0x11,  0x82,  0xBE,  0x00,  0x04,  0x00,  0x18,  0x79,  0xE0,  0x48,  0x20,  0x4B,  0xFE,  0x49,  0x24,  0x49, 	/* 298D0 */
+	0x24,  0x49,  0x24,  0x4F,  0xFF,  0x49,  0x24,  0x49,  0x24,  0x7B,  0xFE,  0x00,  0x20,  0x00,  0x20,  0x07, 	/* 298E0 */
+	0xFF,  0x00,  0x00,  0x80,  0x00,  0x00,  0x03,  0xFF,  0x7A,  0x10,  0x4A,  0x10,  0x4A,  0xFE,  0x4A,  0x10, 	/* 298F0 */
+	0x4A,  0x10,  0x4B,  0xFF,  0x4A,  0x00,  0x4A,  0x10,  0x7A,  0x10,  0x04,  0xFE,  0x04,  0x10,  0x08,  0x10, 	/* 29900 */
+	0x13,  0xFF,  0x00,  0x00,  0x84,  0x00,  0x00,  0x07,  0xFF,  0x78,  0x40,  0x48,  0xC2,  0x49,  0x22,  0x4E, 	/* 29910 */
+	0x24,  0x48,  0x68,  0x48,  0x90,  0x49,  0x18,  0x4E,  0x38,  0x78,  0x54,  0x48,  0x92,  0x03,  0x11,  0x0C, 	/* 29920 */
+	0x10,  0x00,  0x10,  0x00,  0x60,  0x85,  0x00,  0x20,  0x00,  0x20,  0x78,  0x3E,  0x48,  0x20,  0x49,  0xFC, 	/* 29930 */
+	0x49,  0x04,  0x49,  0x04,  0x49,  0xFC,  0x49,  0x04,  0x49,  0x04,  0x49,  0xFC,  0x78,  0x20,  0x07,  0xFF, 	/* 29940 */
+	0x00,  0x20,  0x00,  0x20,  0x00,  0x20,  0x86,  0x00,  0x80,  0x00,  0x80,  0x7F,  0xFF,  0x04,  0x10,  0x02, 	/* 29950 */
+	0x20,  0x3F,  0xFE,  0x22,  0x22,  0x22,  0x26,  0x24,  0x1E,  0x2B,  0xE2,  0x32,  0x22,  0x22,  0x22,  0x23, 	/* 29960 */
+	0xE2,  0x20,  0x02,  0x20,  0x02,  0x20,  0x06,  0x8C,  0x00,  0x20,  0x00,  0x20,  0x7B,  0xFE,  0x4A,  0x52, 	/* 29970 */
+	0x4A,  0x52,  0x48,  0x50,  0x48,  0x92,  0x49,  0x0E,  0x4A,  0x00,  0x49,  0xFC,  0x48,  0x20,  0x78,  0x20, 	/* 29980 */
+	0x00,  0x20,  0x00,  0x20,  0x07,  0xFE,  0x00,  0x00,  0x8F,  0x00,  0x00,  0x7E,  0x7E,  0x42,  0x42,  0x7E, 	/* 29990 */
+	0x7E,  0x42,  0x42,  0x42,  0x42,  0x7E,  0x7E,  0x40,  0x02,  0x40,  0x02,  0x47,  0xE2,  0x44,  0x22,  0x44, 	/* 299A0 */
+	0x22,  0x44,  0x22,  0x47,  0xE2,  0x40,  0x02,  0x40,  0x06,  0x93,  0x00,  0x10,  0x7F,  0x90,  0x00,  0x1F, 	/* 299B0 */
+	0x1F,  0x24,  0x11,  0x24,  0x11,  0x54,  0x1F,  0x08,  0x10,  0x34,  0x20,  0xC2,  0x20,  0x01,  0x4F,  0xF8, 	/* 299C0 */
+	0x08,  0x08,  0x08,  0x08,  0x08,  0x08,  0x0F,  0xF8,  0x00,  0x00,  0x96,  0x00,  0x20,  0x00,  0x24,  0x79, 	/* 299D0 */
+	0x24,  0x49,  0x28,  0x49,  0x50,  0x4A,  0x48,  0x48,  0x84,  0x49,  0x04,  0x4A,  0x20,  0x49,  0x24,  0x49, 	/* 299E0 */
+	0x24,  0x79,  0x38,  0x02,  0x50,  0x00,  0x88,  0x03,  0x04,  0x0C,  0x03,  0x97,  0x00,  0x40,  0x00,  0x7C, 	/* 299F0 */
+	0x78,  0x84,  0x48,  0x84,  0x49,  0x04,  0x4A,  0x38,  0x48,  0x20,  0x48,  0x40,  0x49,  0x8E,  0x49,  0x02, 	/* 29A00 */
+	0x49,  0x02,  0x79,  0xDE,  0x01,  0x02,  0x01,  0x02,  0x01,  0xFE,  0x00,  0x00,  0x9C,  0x00,  0x00,  0x03, 	/* 29A10 */
+	0xFE,  0x78,  0x44,  0x49,  0x94,  0x48,  0x88,  0x49,  0x54,  0x4A,  0x24,  0x48,  0x40,  0x4B,  0xFE,  0x48, 	/* 29A20 */
+	0x42,  0x4A,  0x54,  0x79,  0x94,  0x00,  0x88,  0x01,  0x54,  0x02,  0x22,  0x0C,  0x41,  0x9D,  0x00,  0x20, 	/* 29A30 */
+	0x00,  0xC0,  0x7B,  0x9E,  0x48,  0x92,  0x48,  0x92,  0x4F,  0xF2,  0x48,  0x92,  0x48,  0x92,  0x49,  0xD2, 	/* 29A40 */
+	0x49,  0xD2,  0x4A,  0xBE,  0x7A,  0x90,  0x04,  0x88,  0x00,  0x84,  0x00,  0x80,  0x00,  0x80,  0xA3,  0x01, 	/* 29A50 */
+	0x00,  0x01,  0x1E,  0x79,  0xF2,  0x4A,  0x92,  0x4C,  0x92,  0x4F,  0xF2,  0x48,  0x92,  0x48,  0x92,  0x4A, 	/* 29A60 */
+	0xF2,  0x4A,  0x92,  0x4A,  0x92,  0x7A,  0xB2,  0x02,  0xDC,  0x03,  0x10,  0x0C,  0x10,  0x00,  0x10,  0xBB, 	/* 29A70 */
+	0x01,  0x00,  0x7F,  0xFE,  0x08,  0x20,  0x04,  0x40,  0x7F,  0xFE,  0x41,  0x02,  0x5F,  0xFA,  0x11,  0x08, 	/* 29A80 */
+	0x11,  0x08,  0x11,  0x30,  0x01,  0x00,  0x1F,  0xF8,  0x10,  0x08,  0x10,  0x08,  0x1F,  0xF8,  0x00,  0x00, 	/* 29A90 */
+	0xBC,  0x00,  0x20,  0x00,  0x20,  0x7B,  0xFE,  0x48,  0x88,  0x48,  0x48,  0x48,  0x50,  0x4B,  0xFF,  0x4A, 	/* 29AA0 */
+	0x21,  0x4A,  0x21,  0x49,  0xFE,  0x49,  0x22,  0x79,  0x22,  0x01,  0x22,  0x01,  0x2C,  0x00,  0x20,  0x00, 	/* 29AB0 */
+	0x20,  0xBE,  0x00,  0x48,  0x01,  0x88,  0x07,  0x0A,  0x79,  0x0A,  0x49,  0x2A,  0x4F,  0xEC,  0x49,  0x28, 	/* 29AC0 */
+	0x49,  0x28,  0x4B,  0xA8,  0x4B,  0x4C,  0x4B,  0x14,  0x7D,  0x14,  0x05,  0x14,  0x09,  0x22,  0x01,  0x42, 	/* 29AD0 */
+	0x01,  0x81,  0x80,  0x00,  0x20,  0x00,  0x20,  0x7B,  0xFE,  0x4A,  0x42,  0x48,  0x78,  0x48,  0x88,  0x49, 	/* 29AE0 */
+	0x50,  0x4A,  0x30,  0x48,  0x48,  0x49,  0x84,  0x4F,  0xFF,  0x79,  0x04,  0x01,  0x04,  0x01,  0x04,  0x01, 	/* 29AF0 */
+	0xFC,  0x00,  0x00,  0x83,  0x00,  0x20,  0x00,  0x20,  0x07,  0xFF,  0x78,  0x20,  0x48,  0x20,  0x4B,  0xFE, 	/* 29B00 */
+	0x4A,  0x8A,  0x4A,  0x4A,  0x4A,  0x52,  0x4A,  0xFA,  0x4A,  0x22,  0x7A,  0x22,  0x02,  0xFA,  0x02,  0x22, 	/* 29B10 */
+	0x02,  0x22,  0x02,  0x26,  0x84,  0x04,  0x08,  0x02,  0x10,  0x3F,  0xFE,  0x00,  0x80,  0x1F,  0xFC,  0x00, 	/* 29B20 */
+	0x80,  0x3F,  0xFE,  0x08,  0x88,  0x04,  0x90,  0x7F,  0xFF,  0x00,  0x00,  0x0F,  0xF8,  0x08,  0x08,  0x08, 	/* 29B30 */
+	0x08,  0x0F,  0xF8,  0x00,  0x00,  0x87,  0x00,  0x82,  0x78,  0x8A,  0x4F,  0xFA,  0x48,  0x8A,  0x4B,  0xEA, 	/* 29B40 */
+	0x4A,  0xAA,  0x4A,  0xAA,  0x4A,  0xAA,  0x4B,  0xEA,  0x48,  0x8A,  0x49,  0xCA,  0x79,  0xA2,  0x02,  0x92, 	/* 29B50 */
+	0x04,  0x82,  0x08,  0x82,  0x00,  0x86,  0x89,  0x00,  0x80,  0x00,  0xBC,  0x78,  0x84,  0x49,  0x04,  0x49, 	/* 29B60 */
+	0xFF,  0x4B,  0x20,  0x4B,  0x20,  0x4D,  0x7E,  0x49,  0x50,  0x49,  0x90,  0x49,  0xFF,  0x79,  0x28,  0x01, 	/* 29B70 */
+	0x28,  0x01,  0x44,  0x01,  0x82,  0x01,  0x01,  0x8A,  0x00,  0x14,  0x00,  0x12,  0x78,  0x12,  0x4B,  0xFF, 	/* 29B80 */
+	0x4A,  0x10,  0x4B,  0xF0,  0x4A,  0x12,  0x4A,  0xF2,  0x4A,  0xB4,  0x4A,  0xAC,  0x4A,  0xA8,  0x7A,  0xE9, 	/* 29B90 */
+	0x04,  0x15,  0x04,  0x25,  0x08,  0x43,  0x10,  0x01,  0x8B,  0x01,  0x24,  0x01,  0x24,  0x7F,  0xFF,  0x49, 	/* 29BA0 */
+	0x24,  0x49,  0x24,  0x49,  0x3C,  0x49,  0x00,  0x49,  0xFE,  0x48,  0x20,  0x4F,  0xFF,  0x78,  0x70,  0x00, 	/* 29BB0 */
+	0xA8,  0x01,  0x24,  0x06,  0x23,  0x00,  0x20,  0x00,  0x20,  0x98,  0x00,  0x20,  0x02,  0x22,  0x7A,  0x22, 	/* 29BC0 */
+	0x4A,  0x22,  0x4B,  0xFE,  0x48,  0x00,  0x4F,  0xFF,  0x48,  0x20,  0x48,  0x40,  0x4B,  0xFE,  0x4A,  0x92, 	/* 29BD0 */
+	0x7A,  0x92,  0x02,  0x92,  0x02,  0x92,  0x02,  0x92,  0x02,  0x06,  0x99,  0x00,  0x40,  0x00,  0xFC,  0x78, 	/* 29BE0 */
+	0x88,  0x49,  0xF8,  0x48,  0x10,  0x4F,  0xFF,  0x48,  0x40,  0x48,  0xAA,  0x4B,  0x2C,  0x48,  0x58,  0x48, 	/* 29BF0 */
+	0x94,  0x7B,  0x34,  0x00,  0x52,  0x01,  0x91,  0x06,  0x10,  0x00,  0x60,  0x9A,  0x00,  0x80,  0x00,  0xF8, 	/* 29C00 */
+	0x79,  0x10,  0x4A,  0x20,  0x4F,  0xFC,  0x4A,  0xA4,  0x4A,  0xA4,  0x4A,  0xAC,  0x4A,  0x9C,  0x4B,  0x04, 	/* 29C10 */
+	0x7A,  0x24,  0x4F,  0xFF,  0x00,  0x20,  0x00,  0x50,  0x01,  0x8C,  0x0E,  0x03,  0x9C,  0x01,  0x00,  0x7F, 	/* 29C20 */
+	0xFE,  0x01,  0x00,  0x3F,  0xFC,  0x00,  0x00,  0x1F,  0xF8,  0x10,  0x08,  0x1F,  0xF8,  0x08,  0x10,  0x04, 	/* 29C30 */
+	0x20,  0xFF,  0xFF,  0x00,  0x00,  0x1F,  0xF8,  0x10,  0x08,  0x1F,  0xF8,  0x00,  0x00,  0x9D,  0x00,  0x00, 	/* 29C40 */
+	0x01,  0xF8,  0x79,  0x08,  0x49,  0x08,  0x49,  0xF8,  0x49,  0x08,  0x49,  0x08,  0x49,  0xF8,  0x48,  0x40, 	/* 29C50 */
+	0x48,  0xFE,  0x79,  0x12,  0x03,  0xE2,  0x05,  0x02,  0x01,  0x12,  0x00,  0xF2,  0x00,  0x0C,  0x9E,  0x01, 	/* 29C60 */
+	0x00,  0x01,  0x1E,  0x7B,  0xD2,  0x4A,  0x52,  0x4A,  0x52,  0x4B,  0xD2,  0x4A,  0x52,  0x4A,  0x52,  0x4B, 	/* 29C70 */
+	0xD2,  0x4A,  0x12,  0x4A,  0x12,  0x7B,  0xDC,  0x02,  0x10,  0x02,  0x10,  0x03,  0xD0,  0x02,  0x10,  0x9F, 	/* 29C80 */
+	0x00,  0x00,  0x03,  0xFE,  0x7A,  0x22,  0x4B,  0xFE,  0x4A,  0x22,  0x4A,  0x22,  0x4B,  0xFE,  0x48,  0x00, 	/* 29C90 */
+	0x49,  0xFC,  0x49,  0x04,  0x79,  0xFC,  0x01,  0x04,  0x01,  0xFC,  0x01,  0x04,  0x01,  0x04,  0x01,  0x0C, 	/* 29CA0 */
+	0xA7,  0x00,  0x20,  0x00,  0x20,  0x7B,  0xFF,  0x4A,  0x01,  0x4A,  0x01,  0x49,  0xFE,  0x48,  0x00,  0x48, 	/* 29CB0 */
+	0xFC,  0x48,  0x84,  0x48,  0xFC,  0x48,  0x84,  0x78,  0x84,  0x00,  0xFC,  0x00,  0x00,  0x07,  0xFF,  0x00, 	/* 29CC0 */
+	0x00,  0xA8,  0x00,  0x20,  0x00,  0x20,  0x7B,  0xFF,  0x48,  0x00,  0x48,  0xFC,  0x48,  0x84,  0x48,  0xFC, 	/* 29CD0 */
+	0x48,  0x00,  0x4B,  0xFF,  0x4A,  0x01,  0x4A,  0x49,  0x78,  0x48,  0x00,  0x48,  0x00,  0x89,  0x03,  0x09, 	/* 29CE0 */
+	0x0C,  0x07,  0xA9,  0x00,  0x20,  0x00,  0x20,  0x78,  0x50,  0x48,  0x88,  0x49,  0xFC,  0x4A,  0x02,  0x4F, 	/* 29CF0 */
+	0xD3,  0x4E,  0x52,  0x4B,  0x52,  0x4A,  0xE4,  0x4A,  0x64,  0x7B,  0x64,  0x02,  0xD2,  0x02,  0x52,  0x02, 	/* 29D00 */
+	0x52,  0x02,  0xD2,  0xAA,  0x00,  0x80,  0x00,  0x80,  0x3F,  0xFE,  0x00,  0x80,  0x1E,  0xBC,  0x12,  0xA4, 	/* 29D10 */
+	0x12,  0xA4,  0x1E,  0xBC,  0x00,  0x80,  0x7F,  0xFF,  0x04,  0x84,  0x04,  0x44,  0x04,  0x28,  0x04,  0x90, 	/* 29D20 */
+	0x07,  0x0C,  0x38,  0x03,  0xAB,  0x01,  0x00,  0x01,  0x3E,  0x7F,  0xCA,  0x49,  0x0A,  0x49,  0x0A,  0x4F, 	/* 29D30 */
+	0xCA,  0x49,  0x12,  0x49,  0xD2,  0x4E,  0x2C,  0x48,  0x40,  0x7F,  0xFF,  0x48,  0x40,  0x00,  0xA0,  0x01, 	/* 29D40 */
+	0x10,  0x06,  0x0C,  0x18,  0x03,  0xAC,  0x00,  0x38,  0x1F,  0xC0,  0x01,  0x00,  0x7F,  0xFE,  0x02,  0x20, 	/* 29D50 */
+	0x07,  0xF0,  0x1A,  0x2C,  0x63,  0xE2,  0x00,  0x00,  0x1F,  0xFC,  0x10,  0x04,  0x13,  0xE4,  0x12,  0x24, 	/* 29D60 */
+	0x13,  0xE4,  0x10,  0x04,  0x10,  0x0C,  0xAE,  0x00,  0x00,  0x1F,  0x7C,  0x11,  0x44,  0x1F,  0x7C,  0x00, 	/* 29D70 */
+	0x00,  0x0F,  0xF8,  0x08,  0x88,  0x08,  0x88,  0x0F,  0xF8,  0x08,  0x88,  0x0F,  0xF8,  0x00,  0x80,  0x7F, 	/* 29D80 */
+	0xFF,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0xB0,  0x00,  0x20,  0x00,  0x20,  0x7C,  0x50,  0x44,  0x88, 	/* 29D90 */
+	0x45,  0x24,  0x46,  0xFB,  0x44,  0x88,  0x44,  0xF8,  0x44,  0x88,  0x44,  0x8A,  0x44,  0xFA,  0x7C,  0xA4, 	/* 29DA0 */
+	0x00,  0x90,  0x00,  0x88,  0x00,  0xE4,  0x07,  0x03,  0xB6,  0x12,  0x08,  0x09,  0x08,  0x09,  0x10,  0x7F, 	/* 29DB0 */
+	0xFE,  0x40,  0x02,  0x4F,  0xF2,  0x08,  0x10,  0x08,  0x10,  0x0F,  0xF0,  0x01,  0x00,  0x02,  0x00,  0x1F, 	/* 29DC0 */
+	0xF8,  0x10,  0x08,  0x10,  0x08,  0x10,  0x08,  0x1F,  0xF8,  0x84,  0x00,  0x00,  0x07,  0xFF,  0x00,  0x40, 	/* 29DD0 */
+	0x79,  0xFC,  0x49,  0x04,  0x49,  0xFC,  0x49,  0x04,  0x49,  0xFC,  0x49,  0x04,  0x49,  0xFC,  0x48,  0x20, 	/* 29DE0 */
+	0x78,  0xFC,  0x07,  0x48,  0x00,  0x30,  0x00,  0xD8,  0x0F,  0x07,  0x85,  0x00,  0x20,  0x00,  0x40,  0x79, 	/* 29DF0 */
+	0xFC,  0x49,  0x04,  0x49,  0xFC,  0x49,  0x04,  0x49,  0xFC,  0x49,  0x04,  0x49,  0x04,  0x49,  0xFC,  0x78, 	/* 29E00 */
+	0x28,  0x00,  0x24,  0x0F,  0xFF,  0x00,  0x50,  0x01,  0x8C,  0x0E,  0x03,  0x87,  0x00,  0x80,  0x00,  0x80, 	/* 29E10 */
+	0x3F,  0xFE,  0x04,  0x88,  0x04,  0x88,  0x0A,  0x94,  0x10,  0xA2,  0x7F,  0xFF,  0x00,  0x00,  0x1F,  0xFC, 	/* 29E20 */
+	0x13,  0xE4,  0x12,  0x24,  0x13,  0xE4,  0x10,  0x04,  0x1F,  0xFC,  0x00,  0x00,  0x94,  0x01,  0x04,  0x01, 	/* 29E30 */
+	0xF8,  0x79,  0x02,  0x48,  0xFE,  0x4A,  0x00,  0x4A,  0xFC,  0x4A,  0x84,  0x4A,  0xFC,  0x4A,  0x84,  0x4A, 	/* 29E40 */
+	0xFC,  0x4A,  0x84,  0x7A,  0xFC,  0x02,  0x00,  0x03,  0xFF,  0x01,  0x8C,  0x0E,  0x02,  0x9A,  0x00,  0x20, 	/* 29E50 */
+	0x00,  0x40,  0x79,  0xF8,  0x49,  0x08,  0x49,  0x08,  0x49,  0x08,  0x49,  0xF8,  0x49,  0x00,  0x49,  0xFF, 	/* 29E60 */
+	0x49,  0x00,  0x79,  0xFE,  0x00,  0x92,  0x06,  0x4A,  0x05,  0x42,  0x05,  0x04,  0x08,  0x18,  0x9C,  0x00, 	/* 29E70 */
+	0x40,  0x00,  0x44,  0x7B,  0xF8,  0x48,  0x50,  0x4F,  0xFF,  0x48,  0x84,  0x49,  0xF8,  0x4E,  0x81,  0x48, 	/* 29E80 */
+	0x7F,  0x48,  0x00,  0x79,  0xFC,  0x01,  0x04,  0x01,  0xFC,  0x01,  0x04,  0x01,  0xFC,  0x00,  0x00,  0x9F, 	/* 29E90 */
+	0x00,  0x84,  0x00,  0x48,  0x7B,  0xFE,  0x48,  0x20,  0x48,  0x20,  0x49,  0xFC,  0x48,  0x20,  0x4F,  0xFF, 	/* 29EA0 */
+	0x48,  0x80,  0x48,  0x80,  0x79,  0xFE,  0x02,  0x10,  0x04,  0x10,  0x08,  0x10,  0x03,  0xFF,  0x00,  0x00, 	/* 29EB0 */
+	0xA3,  0x00,  0x00,  0x3E,  0xFE,  0x22,  0x02,  0x22,  0x02,  0x3E,  0xFE,  0x00,  0x02,  0x7F,  0x02,  0x55, 	/* 29EC0 */
+	0x7A,  0x55,  0x4A,  0x55,  0x4A,  0x7F,  0x4A,  0x55,  0x7A,  0x55,  0x02,  0x55,  0x02,  0x55,  0x02,  0x43, 	/* 29ED0 */
+	0x0C,  0xA4,  0x00,  0x20,  0x02,  0x22,  0x7A,  0x22,  0x4B,  0xFE,  0x48,  0x40,  0x48,  0x80,  0x4F,  0xFF, 	/* 29EE0 */
+	0x48,  0x20,  0x49,  0xFC,  0x49,  0x24,  0x49,  0x24,  0x79,  0xFC,  0x00,  0x28,  0x00,  0x24,  0x00,  0xFE, 	/* 29EF0 */
+	0x07,  0x01,  0xB7,  0x01,  0x10,  0x01,  0x10,  0x7B,  0xD0,  0x49,  0x1F,  0x49,  0x24,  0x4F,  0xE4,  0x49, 	/* 29F00 */
+	0x04,  0x49,  0x14,  0x4F,  0xF4,  0x49,  0x14,  0x49,  0xC8,  0x79,  0x48,  0x02,  0x54,  0x04,  0x54,  0x08, 	/* 29F10 */
+	0x62,  0x01,  0x81,  0xB9,  0x00,  0x10,  0x02,  0x10,  0x71,  0xFF,  0x51,  0x10,  0x54,  0x7E,  0x52,  0x52, 	/* 29F20 */
+	0x52,  0x52,  0x50,  0x7E,  0x5F,  0x52,  0x51,  0x52,  0x51,  0x7E,  0x71,  0x10,  0x02,  0xFF,  0x02,  0x90, 	/* 29F30 */
+	0x04,  0x70,  0x08,  0x1F,  0xBD,  0x01,  0x08,  0x01,  0x08,  0x7F,  0xE8,  0x51,  0x1F,  0x57,  0xD1,  0x55, 	/* 29F40 */
+	0x6A,  0x55,  0x48,  0x55,  0x48,  0x57,  0xC8,  0x51,  0x08,  0x53,  0x94,  0x73,  0x54,  0x05,  0x14,  0x09, 	/* 29F50 */
+	0x22,  0x01,  0x42,  0x01,  0x81,  0xBE,  0x01,  0x10,  0x01,  0x10,  0x79,  0x10,  0x4F,  0xDF,  0x4A,  0x20, 	/* 29F60 */
+	0x4A,  0x50,  0x4B,  0xDE,  0x4A,  0x68,  0x4A,  0x48,  0x4A,  0x7F,  0x4A,  0x48,  0x7A,  0x48,  0x02,  0x54, 	/* 29F70 */
+	0x04,  0x54,  0x04,  0x62,  0x09,  0x81,  0x86,  0x00,  0x88,  0x00,  0x88,  0x7F,  0xFF,  0x48,  0x88,  0x4B, 	/* 29F80 */
+	0xFE,  0x4A,  0x22,  0x4A,  0x22,  0x4B,  0xFE,  0x48,  0x20,  0x4B,  0xFC,  0x48,  0x20,  0x7F,  0xFF,  0x48, 	/* 29F90 */
+	0x50,  0x00,  0x88,  0x01,  0x04,  0x06,  0x03,  0x89,  0x00,  0x80,  0x00,  0x80,  0x7F,  0xFF,  0x00,  0x80, 	/* 29FA0 */
+	0x1F,  0xFC,  0x00,  0x00,  0x0F,  0xF8,  0x08,  0x08,  0x0F,  0xF8,  0x02,  0x20,  0x7F,  0xFF,  0x08,  0x00, 	/* 29FB0 */
+	0x3F,  0x7C,  0x09,  0x44,  0x11,  0x7C,  0x66,  0x00,  0x94,  0x00,  0x00,  0x03,  0xFF,  0x7A,  0x00,  0x4A, 	/* 29FC0 */
+	0x7C,  0x4A,  0x44,  0x4A,  0x44,  0x4A,  0x7C,  0x4A,  0x00,  0x4A,  0xEE,  0x4A,  0xAA,  0x4A,  0xAA,  0x7A, 	/* 29FD0 */
+	0xAA,  0x02,  0xEE,  0x02,  0x00,  0x03,  0xFF,  0x00,  0x00,  0x96,  0x00,  0x40,  0x03,  0xFE,  0x78,  0x40, 	/* 29FE0 */
+	0x4B,  0xFC,  0x48,  0x40,  0x4F,  0xFF,  0x48,  0x00,  0x49,  0xF8,  0x49,  0x08,  0x49,  0xF8,  0x49,  0x08, 	/* 29FF0 */
+	0x79,  0xF8,  0x01,  0x08,  0x01,  0xF8,  0x00,  0x8C,  0x07,  0x02,  0x97,  0x11,  0x10,  0x09,  0x20,  0x7F, 	/* 2A000 */
+	0xFE,  0x40,  0x02,  0x4F,  0xF2,  0x08,  0x10,  0x2F,  0xF0,  0x20,  0x18,  0x3F,  0xE0,  0x20,  0x02,  0x1F, 	/* 2A010 */
+	0xFE,  0x08,  0x10,  0x0F,  0xF0,  0x08,  0x10,  0x0F,  0xF0,  0x00,  0x00,  0x98,  0x00,  0x20,  0x00,  0x3E, 	/* 2A020 */
+	0x78,  0x20,  0x4B,  0xFF,  0x4A,  0x42,  0x4A,  0x7C,  0x4B,  0xC0,  0x4A,  0x42,  0x4A,  0x3E,  0x4A,  0x28, 	/* 2A030 */
+	0x7B,  0x2A,  0x44,  0xAA,  0x04,  0xAC,  0x08,  0x28,  0x13,  0xFF,  0x00,  0x00,  0x9B,  0x00,  0x20,  0x00, 	/* 2A040 */
+	0x20,  0x77,  0xFF,  0x54,  0x88,  0x54,  0x88,  0x57,  0xFF,  0x54,  0x88,  0x54,  0xAC,  0x56,  0xAC,  0x56, 	/* 2A050 */
+	0xAC,  0x76,  0xAD,  0x0A,  0xAD,  0x0A,  0xAB,  0x14,  0xC8,  0x20,  0x88,  0x00,  0x88,  0xA9,  0x00,  0x88, 	/* 2A060 */
+	0x00,  0x88,  0x7F,  0xFF,  0x48,  0x88,  0x4B,  0xFE,  0x49,  0x24,  0x49,  0x24,  0x4F,  0xFF,  0x49,  0x24, 	/* 2A070 */
+	0x49,  0x24,  0x4B,  0xFE,  0x78,  0x20,  0x00,  0x20,  0x07,  0xFF,  0x00,  0x20,  0x00,  0x20,  0xAF,  0x00, 	/* 2A080 */
+	0x20,  0x03,  0xFE,  0x78,  0x22,  0x4F,  0xFF,  0x48,  0x22,  0x4B,  0xFE,  0x48,  0x20,  0x4A,  0xAA,  0x4A, 	/* 2A090 */
+	0xAA,  0x4B,  0xAE,  0x4A,  0x22,  0x7B,  0xFE,  0x02,  0x22,  0x03,  0xAE,  0x04,  0xAA,  0x08,  0xAA,  0xB1, 	/* 2A0A0 */
+	0x00,  0x00,  0x03,  0xFE,  0x7A,  0x02,  0x4B,  0xFE,  0x4A,  0x04,  0x4A,  0xF8,  0x4A,  0x10,  0x4A,  0xFE, 	/* 2A0B0 */
+	0x4A,  0x92,  0x4A,  0xFE,  0x7A,  0x10,  0x03,  0xFF,  0x05,  0x15,  0x05,  0x1B,  0x09,  0xE1,  0x11,  0x03, 	/* 2A0C0 */
+	0xB2,  0x00,  0x80,  0x00,  0x9E,  0x7F,  0xF2,  0x48,  0x92,  0x4B,  0xD2,  0x4A,  0x5E,  0x4A,  0x52,  0x4B, 	/* 2A0D0 */
+	0xD2,  0x4A,  0x52,  0x4A,  0x5E,  0x4B,  0xD2,  0x78,  0x92,  0x07,  0xF2,  0x00,  0x92,  0x00,  0xA2,  0x00, 	/* 2A0E0 */
+	0xC6,  0xB4,  0x00,  0x90,  0x02,  0x92,  0x7A,  0xFC,  0x4A,  0x90,  0x4A,  0xF1,  0x4F,  0x4F,  0x48,  0xF0, 	/* 2A0F0 */
+	0x49,  0x20,  0x4B,  0xFE,  0x49,  0x22,  0x49,  0xFE,  0x79,  0x22,  0x01,  0xFE,  0x01,  0x02,  0x02,  0x02, 	/* 2A100 */
+	0x04,  0x06,  0xB6,  0x04,  0x82,  0x04,  0x84,  0x74,  0x98,  0x5F,  0xF0,  0x54,  0x90,  0x54,  0x9F,  0x57, 	/* 2A110 */
+	0x92,  0x54,  0x92,  0x57,  0x92,  0x54,  0x92,  0x54,  0x92,  0x5F,  0xF2,  0x75,  0x22,  0x04,  0xA2,  0x08, 	/* 2A120 */
+	0x42,  0x10,  0x82,  0xB8,  0x00,  0x80,  0x00,  0x80,  0x79,  0xFF,  0x4B,  0x54,  0x4D,  0x54,  0x49,  0x54, 	/* 2A130 */
+	0x49,  0x54,  0x4F,  0xFF,  0x49,  0x54,  0x49,  0x54,  0x49,  0x54,  0x7F,  0xFF,  0x00,  0x00,  0x02,  0x94, 	/* 2A140 */
+	0x04,  0x4A,  0x08,  0x49,  0x82,  0x01,  0x08,  0x00,  0x90,  0x7F,  0xFF,  0x48,  0xA0,  0x4B,  0xFC,  0x4A, 	/* 2A150 */
+	0xA4,  0x4B,  0x1C,  0x4B,  0xFC,  0x4A,  0x04,  0x4B,  0xFC,  0x78,  0x10,  0x0F,  0xFF,  0x02,  0x10,  0x01, 	/* 2A160 */
+	0x10,  0x01,  0x10,  0x00,  0x30,  0x8C,  0x01,  0x04,  0x00,  0x88,  0x7B,  0xFE,  0x4A,  0x22,  0x4B,  0xFE, 	/* 2A170 */
+	0x4A,  0x22,  0x4A,  0x22,  0x4B,  0xFE,  0x48,  0x00,  0x49,  0xFC,  0x79,  0x04,  0x01,  0xFC,  0x01,  0x04, 	/* 2A180 */
+	0x01,  0x04,  0x01,  0xFC,  0x00,  0x00,  0x8E,  0x00,  0x20,  0x00,  0x20,  0x07,  0xFF,  0x78,  0x20,  0x49, 	/* 2A190 */
+	0xFC,  0x48,  0x00,  0x4B,  0xFE,  0x4A,  0x02,  0x4A,  0xFA,  0x48,  0x00,  0x49,  0xFC,  0x79,  0x04,  0x01, 	/* 2A1A0 */
+	0xFC,  0x00,  0x88,  0x0F,  0xFF,  0x00,  0x00,  0x90,  0x00,  0x00,  0x3E,  0x7C,  0x22,  0x44,  0x22,  0x44, 	/* 2A1B0 */
+	0x3E,  0x7C,  0x00,  0x00,  0x1F,  0xF8,  0x01,  0x00,  0x01,  0x00,  0x7F,  0xFF,  0x00,  0x00,  0x3E,  0x7C, 	/* 2A1C0 */
+	0x22,  0x44,  0x22,  0x44,  0x3E,  0x7C,  0x00,  0x00,  0x9B,  0x00,  0x20,  0x01,  0x20,  0x79,  0x3E,  0x49, 	/* 2A1D0 */
+	0x20,  0x49,  0x20,  0x4F,  0xFF,  0x4A,  0x22,  0x4A,  0xAA,  0x4A,  0x72,  0x4B,  0xFE,  0x4A,  0x22,  0x7A, 	/* 2A1E0 */
+	0x72,  0x02,  0xAA,  0x03,  0x22,  0x03,  0xFE,  0x00,  0x00,  0xA4,  0x00,  0x88,  0x00,  0x88,  0x07,  0xFF, 	/* 2A1F0 */
+	0x78,  0x88,  0x49,  0xDC,  0x4A,  0xAA,  0x4C,  0x89,  0x48,  0x88,  0x49,  0xFC,  0x48,  0x00,  0x4B,  0xFE, 	/* 2A200 */
+	0x48,  0x20,  0x79,  0x24,  0x02,  0x22,  0x04,  0x22,  0x00,  0x60,  0xA8,  0x00,  0x00,  0x1F,  0x7C,  0x11, 	/* 2A210 */
+	0x44,  0x11,  0x44,  0x1F,  0x7C,  0x00,  0x80,  0x00,  0x80,  0x7F,  0xFF,  0x01,  0x40,  0x06,  0x30,  0x18, 	/* 2A220 */
+	0x0C,  0x7F,  0x7F,  0x11,  0x44,  0x11,  0x44,  0x1F,  0x7C,  0x00,  0x00,  0xAA,  0x00,  0x00,  0x00,  0xF8, 	/* 2A230 */
+	0x00,  0x88,  0x78,  0x88,  0x48,  0xF8,  0x4B,  0xDE,  0x4A,  0x52,  0x4A,  0x52,  0x4B,  0xDE,  0x48,  0x20, 	/* 2A240 */
+	0x4F,  0xFF,  0x78,  0x70,  0x00,  0xA8,  0x01,  0x24,  0x06,  0x23,  0x00,  0x20,  0xAB,  0x00,  0x20,  0x00, 	/* 2A250 */
+	0x20,  0x7B,  0xFE,  0x48,  0x88,  0x48,  0x50,  0x4F,  0xFF,  0x48,  0x00,  0x49,  0xFC,  0x49,  0x04,  0x49, 	/* 2A260 */
+	0xFC,  0x49,  0x04,  0x79,  0xFC,  0x04,  0xA0,  0x04,  0x92,  0x08,  0x85,  0x00,  0x7C,  0xAC,  0x01,  0x08, 	/* 2A270 */
+	0x01,  0x08,  0x79,  0xEF,  0x4A,  0x94,  0x4A,  0x52,  0x4C,  0x20,  0x4B,  0xFE,  0x49,  0x24,  0x49,  0x24, 	/* 2A280 */
+	0x49,  0xA6,  0x7A,  0xAA,  0x02,  0x69,  0x04,  0x30,  0x00,  0x20,  0x0F,  0xFF,  0x00,  0x00,  0xB4,  0x00, 	/* 2A290 */
+	0x20,  0x03,  0xFE,  0x78,  0x20,  0x48,  0x88,  0x4F,  0xFF,  0x48,  0x88,  0x48,  0x00,  0x49,  0xFC,  0x49, 	/* 2A2A0 */
+	0x04,  0x49,  0xFC,  0x79,  0x04,  0x01,  0xFC,  0x01,  0x04,  0x01,  0xFC,  0x01,  0x8C,  0x06,  0x02,  0xB8, 	/* 2A2B0 */
+	0x01,  0x00,  0x01,  0x7F,  0x71,  0x04,  0x51,  0xE8,  0x5F,  0x1E,  0x51,  0x52,  0x55,  0x52,  0x55,  0x5E, 	/* 2A2C0 */
+	0x55,  0x52,  0x57,  0xDE,  0x51,  0x12,  0x71,  0x12,  0x01,  0x5E,  0x00,  0xD4,  0x00,  0x22,  0x00,  0xC1, 	/* 2A2D0 */
+	0xBA,  0x01,  0x02,  0x01,  0x1C,  0x77,  0xF0,  0x54,  0x50,  0x52,  0x50,  0x52,  0x9F,  0x5F,  0xF2,  0x51, 	/* 2A2E0 */
+	0x12,  0x51,  0x12,  0x57,  0xF2,  0x51,  0x92,  0x73,  0x52,  0x55,  0x22,  0x09,  0x22,  0x01,  0x42,  0x01, 	/* 2A2F0 */
+	0x02,  0x80,  0x00,  0x20,  0x07,  0xFF,  0x7C,  0xA1,  0x4C,  0x91,  0x4A,  0x8A,  0x4A,  0x79,  0x4C,  0x01, 	/* 2A300 */
+	0x4B,  0xFE,  0x4A,  0x92,  0x4B,  0xFE,  0x78,  0x00,  0x07,  0xFF,  0x00,  0x20,  0x00,  0x20,  0x00,  0x20, 	/* 2A310 */
+	0x00,  0x60,  0x86,  0x00,  0x88,  0x07,  0xFF,  0x78,  0x88,  0x48,  0x20,  0x4F,  0xFF,  0x48,  0x00,  0x49, 	/* 2A320 */
+	0xF8,  0x49,  0x08,  0x49,  0xF8,  0x48,  0x00,  0x4B,  0xFE,  0x7A,  0x02,  0x02,  0xFA,  0x02,  0x8A,  0x02, 	/* 2A330 */
+	0xFA,  0x02,  0x06,  0x87,  0x01,  0x08,  0x01,  0x08,  0x77,  0xFE,  0x51,  0x08,  0x51,  0x08,  0x51,  0x08, 	/* 2A340 */
+	0x5F,  0xFF,  0x52,  0x94,  0x52,  0x94,  0x5A,  0xD6,  0x7A,  0xB5,  0x0A,  0xB5,  0x12,  0x94,  0x04,  0xA4, 	/* 2A350 */
+	0x04,  0xA4,  0x09,  0xCC,  0x8A,  0x00,  0x20,  0x00,  0xF8,  0x78,  0x88,  0x48,  0xF8,  0x48,  0x88,  0x48, 	/* 2A360 */
+	0xF8,  0x48,  0x88,  0x4B,  0xFE,  0x4A,  0x22,  0x4B,  0xFE,  0x7A,  0x22,  0x03,  0xFE,  0x00,  0x00,  0x0F, 	/* 2A370 */
+	0xFF,  0x00,  0x88,  0x01,  0x08,  0x8F,  0x00,  0x20,  0x03,  0xFE,  0x78,  0x20,  0x4F,  0xFF,  0x4C,  0x01, 	/* 2A380 */
+	0x4D,  0xFD,  0x49,  0x24,  0x49,  0xFC,  0x49,  0x24,  0x49,  0xFC,  0x78,  0x00,  0x07,  0xFF,  0x01,  0x22, 	/* 2A390 */
+	0x01,  0xBC,  0x02,  0x60,  0x0C,  0x1F,  0x94,  0x00,  0x20,  0x03,  0xFE,  0x78,  0x20,  0x4F,  0xFF,  0x4C, 	/* 2A3A0 */
+	0x01,  0x4D,  0xFD,  0x49,  0x24,  0x49,  0xFC,  0x49,  0x24,  0x49,  0xFC,  0x78,  0x46,  0x07,  0xFD,  0x01, 	/* 2A3B0 */
+	0x20,  0x01,  0xBC,  0x02,  0x60,  0x0C,  0x1F,  0xA0,  0x01,  0x02,  0x06,  0xFA,  0x74,  0x2A,  0x55,  0x2A, 	/* 2A3C0 */
+	0x57,  0x4A,  0x54,  0x9A,  0x51,  0x4A,  0x52,  0x2A,  0x55,  0xDA,  0x50,  0x8A,  0x53,  0xFA,  0x70,  0xA2, 	/* 2A3D0 */
+	0x04,  0xC2,  0x02,  0xB2,  0x01,  0xC2,  0x06,  0x06,  0xA2,  0x01,  0x00,  0x7F,  0xFC,  0x11,  0x10,  0x1F, 	/* 2A3E0 */
+	0xF0,  0x01,  0x00,  0x7F,  0xFE,  0x44,  0x22,  0x1A,  0x5E,  0x6F,  0xF8,  0x02,  0x40,  0x3F,  0xF8,  0x02, 	/* 2A3F0 */
+	0x40,  0x7F,  0xFE,  0x04,  0x88,  0x78,  0x70,  0x0E,  0x0E,  0xA5,  0x00,  0x88,  0x00,  0x88,  0x07,  0xFF, 	/* 2A400 */
+	0x78,  0x88,  0x48,  0xF8,  0x49,  0x04,  0x4F,  0x75,  0x49,  0x56,  0x49,  0x54,  0x49,  0x54,  0x4B,  0x75, 	/* 2A410 */
+	0x7D,  0x03,  0x00,  0x00,  0x02,  0x94,  0x04,  0x4A,  0x08,  0x49,  0xAE,  0x11,  0xE0,  0x10,  0x0E,  0x65, 	/* 2A420 */
+	0xEA,  0x29,  0x2A,  0x11,  0xEC,  0x1D,  0x0A,  0x65,  0xE9,  0x09,  0x09,  0x11,  0xEE,  0x21,  0x08,  0x7F, 	/* 2A430 */
+	0xFC,  0x20,  0x04,  0x27,  0xE4,  0x24,  0x24,  0x27,  0xE4,  0x20,  0x0C,  0xB4,  0x0F,  0x3C,  0x09,  0x24, 	/* 2A440 */
+	0x0F,  0x3C,  0x00,  0x00,  0x1F,  0xFF,  0x10,  0x00,  0x17,  0x90,  0x12,  0x10,  0x1F,  0xDF,  0x14,  0xA4, 	/* 2A450 */
+	0x17,  0xB4,  0x14,  0xD8,  0x27,  0x88,  0x24,  0x94,  0x47,  0xA2,  0x18,  0xC1,  0xB6,  0x00,  0x00,  0x03, 	/* 2A460 */
+	0xDE,  0x02,  0x52,  0x7B,  0xDE,  0x4A,  0x52,  0x4B,  0xDE,  0x4A,  0x52,  0x4B,  0xDE,  0x49,  0x4A,  0x4E, 	/* 2A470 */
+	0x31,  0x48,  0x40,  0x7F,  0xFF,  0x00,  0x88,  0x03,  0xD0,  0x00,  0x78,  0x07,  0x84,  0xBC,  0x00,  0x0C, 	/* 2A480 */
+	0x03,  0xF4,  0x79,  0x22,  0x4A,  0x11,  0x4F,  0xFE,  0x4A,  0x52,  0x4B,  0xFE,  0x48,  0x00,  0x4B,  0xE2, 	/* 2A490 */
+	0x4A,  0x3F,  0x4B,  0xE2,  0x7A,  0x32,  0x03,  0xEA,  0x02,  0x0A,  0x03,  0xE2,  0x02,  0x06,  0x80,  0x01, 	/* 2A4A0 */
+	0x08,  0x01,  0x7F,  0x7F,  0xC8,  0x51,  0x3E,  0x57,  0xAA,  0x55,  0xBE,  0x55,  0xAA,  0x57,  0xBE,  0x55, 	/* 2A4B0 */
+	0x92,  0x55,  0xFD,  0x57,  0x84,  0x71,  0x7F,  0x0F,  0xA4,  0x01,  0x14,  0x01,  0x04,  0x01,  0x0C,  0x81, 	/* 2A4C0 */
+	0x00,  0x00,  0x03,  0xFE,  0x78,  0x88,  0x48,  0xF8,  0x48,  0x88,  0x48,  0xFE,  0x4B,  0x88,  0x48,  0x08, 	/* 2A4D0 */
+	0x4F,  0xFF,  0x4A,  0x52,  0x4B,  0xDE,  0x7A,  0x52,  0x03,  0xDE,  0x02,  0x53,  0x0F,  0xFE,  0x00,  0x42, 	/* 2A4E0 */
+	0x82,  0x1F,  0x7C,  0x11,  0x44,  0x1F,  0x7C,  0x00,  0x00,  0x7F,  0xFF,  0x01,  0x00,  0x0F,  0xF8,  0x08, 	/* 2A4F0 */
+	0x08,  0x0F,  0xF8,  0x08,  0x08,  0x0F,  0xF8,  0x10,  0x04,  0x3F,  0x7E,  0x51,  0x45,  0x1F,  0x7C,  0x00, 	/* 2A500 */
+	0x00,  0x83,  0x01,  0x12,  0x01,  0x12,  0x7F,  0xE4,  0x54,  0xBF,  0x54,  0xE4,  0x54,  0xA4,  0x5B,  0x64, 	/* 2A510 */
+	0x5A,  0x3F,  0x51,  0x24,  0x5F,  0xE4,  0x51,  0x3F,  0x73,  0xA4,  0x03,  0x64,  0x05,  0x24,  0x09,  0x3F, 	/* 2A520 */
+	0x01,  0x00,  0x88,  0x00,  0x90,  0x07,  0xFF,  0x78,  0x90,  0x49,  0x08,  0x4B,  0xC8,  0x49,  0x3E,  0x4F, 	/* 2A530 */
+	0xEA,  0x4A,  0x5A,  0x4D,  0x6E,  0x4B,  0x8A,  0x79,  0xD3,  0x06,  0x21,  0x0F,  0xFE,  0x00,  0x98,  0x0F, 	/* 2A540 */
+	0xF4,  0x00,  0x02,  0x8E,  0x00,  0x1C,  0x07,  0x94,  0x74,  0xA2,  0x54,  0xFF,  0x54,  0xAB,  0x57,  0xBD, 	/* 2A550 */
+	0x54,  0xA9,  0x54,  0xBF,  0x57,  0x80,  0x54,  0x9E,  0x54,  0x92,  0x77,  0x9E,  0x03,  0x12,  0x02,  0x92, 	/* 2A560 */
+	0x04,  0x9E,  0x08,  0x00,  0x91,  0x00,  0x00,  0x07,  0xFE,  0x04,  0x02,  0x77,  0xFE,  0x57,  0xAE,  0x55, 	/* 2A570 */
+	0xE7,  0x55,  0xFE,  0x55,  0x4A,  0x55,  0xFE,  0x54,  0x40,  0x54,  0xFE,  0x75,  0xAA,  0x0A,  0xFA,  0x08, 	/* 2A580 */
+	0x2A,  0x11,  0xF6,  0x20,  0x0C,  0x93,  0x01,  0x00,  0x01,  0xFF,  0x77,  0x09,  0x51,  0xC9,  0x57,  0x11, 	/* 2A590 */
+	0x51,  0xE3,  0x57,  0x3C,  0x51,  0x20,  0x5F,  0xFF,  0x54,  0x92,  0x75,  0x6A,  0x07,  0xFE,  0x04,  0x92, 	/* 2A5A0 */
+	0x05,  0x6A,  0x07,  0xFE,  0x00,  0x00,  0x97,  0x00,  0x00,  0x3F,  0xFE,  0x20,  0x02,  0x20,  0x02,  0x20, 	/* 2A5B0 */
+	0x02,  0x20,  0x02,  0x20,  0x02,  0x20,  0x02,  0x20,  0x02,  0x20,  0x02,  0x20,  0x02,  0x20,  0x02,  0x20, 	/* 2A5C0 */
+	0x02,  0x20,  0x02,  0x3F,  0xFE,  0x20,  0x02,  0x98,  0x00,  0x00,  0x3F,  0xFE,  0x20,  0x02,  0x20,  0x02, 	/* 2A5D0 */
+	0x27,  0xE2,  0x24,  0x22,  0x24,  0x22,  0x27,  0xE2,  0x24,  0x02,  0x24,  0x02,  0x24,  0x12,  0x24,  0x12, 	/* 2A5E0 */
+	0x23,  0xF2,  0x20,  0x02,  0x20,  0x02,  0x20,  0x06,  0x9A,  0x00,  0x00,  0x3F,  0xFE,  0x20,  0x02,  0x20, 	/* 2A5F0 */
+	0x82,  0x20,  0x82,  0x20,  0x82,  0x20,  0x82,  0x21,  0x42,  0x21,  0x42,  0x22,  0x22,  0x24,  0x12,  0x28, 	/* 2A600 */
+	0x0A,  0x30,  0x06,  0x20,  0x02,  0x3F,  0xFE,  0x00,  0x00,  0x9B,  0x00,  0x00,  0x00,  0x00,  0x7F,  0xFE, 	/* 2A610 */
+	0x44,  0x42,  0x44,  0x42,  0x44,  0x42,  0x44,  0x42,  0x44,  0x46,  0x48,  0x46,  0x48,  0x3E,  0x50,  0x02, 	/* 2A620 */
+	0x60,  0x02,  0x40,  0x02,  0x7F,  0xFE,  0x00,  0x00,  0x00,  0x00,  0x9E,  0x00,  0x00,  0x3F,  0xFE,  0x20, 	/* 2A630 */
+	0x02,  0x20,  0x02,  0x20,  0x02,  0x23,  0xE2,  0x22,  0x22,  0x22,  0x22,  0x22,  0x22,  0x22,  0x22,  0x23, 	/* 2A640 */
+	0xE2,  0x20,  0x02,  0x20,  0x02,  0x20,  0x02,  0x3F,  0xFE,  0x00,  0x00,  0xA0,  0x00,  0x00,  0x3F,  0xFE, 	/* 2A650 */
+	0x20,  0x02,  0x20,  0x82,  0x20,  0x82,  0x20,  0x82,  0x3F,  0xFE,  0x21,  0x42,  0x21,  0x42,  0x22,  0x22, 	/* 2A660 */
+	0x22,  0x22,  0x24,  0x12,  0x28,  0x0A,  0x20,  0x02,  0x3F,  0xFE,  0x00,  0x00,  0xA3,  0x00,  0x00,  0x3F, 	/* 2A670 */
+	0xFE,  0x20,  0x22,  0x20,  0x22,  0x20,  0x22,  0x2F,  0xFE,  0x20,  0x22,  0x24,  0x22,  0x22,  0x22,  0x22, 	/* 2A680 */
+	0x22,  0x20,  0x22,  0x20,  0x22,  0x20,  0x62,  0x20,  0x02,  0x3F,  0xFE,  0x00,  0x00,  0xAE,  0x00,  0x00, 	/* 2A690 */
+	0x3F,  0xFE,  0x22,  0x82,  0x22,  0x82,  0x24,  0x92,  0x24,  0x92,  0x2C,  0xA2,  0x34,  0xC2,  0x24,  0x82, 	/* 2A6A0 */
+	0x24,  0x82,  0x24,  0x8A,  0x24,  0x8A,  0x24,  0x7A,  0x24,  0x02,  0x3F,  0xFE,  0x20,  0x02,  0xB0,  0x00, 	/* 2A6B0 */
+	0x00,  0x3F,  0xFE,  0x20,  0x82,  0x20,  0x82,  0x20,  0x82,  0x3F,  0xFE,  0x21,  0xC2,  0x21,  0xC2,  0x22, 	/* 2A6C0 */
+	0xA2,  0x22,  0xA2,  0x24,  0x92,  0x28,  0x8A,  0x30,  0x86,  0x20,  0x82,  0x3F,  0xFE,  0x00,  0x00,  0xB2, 	/* 2A6D0 */
+	0x00,  0x00,  0x3F,  0xFE,  0x20,  0x02,  0x22,  0x22,  0x22,  0x22,  0x2F,  0xFA,  0x22,  0x22,  0x22,  0x22, 	/* 2A6E0 */
+	0x22,  0x22,  0x3F,  0xFE,  0x22,  0x22,  0x22,  0x22,  0x24,  0x22,  0x28,  0x22,  0x3F,  0xFE,  0x00,  0x00, 	/* 2A6F0 */
+	0xB3,  0x00,  0x00,  0x3F,  0xFE,  0x20,  0x02,  0x21,  0x0A,  0x28,  0x8A,  0x24,  0x92,  0x24,  0x12,  0x20, 	/* 2A700 */
+	0x22,  0x2E,  0x42,  0x21,  0x82,  0x21,  0x42,  0x26,  0x22,  0x38,  0x12,  0x20,  0x02,  0x3F,  0xFE,  0x00, 	/* 2A710 */
+	0x00,  0xB9,  0x00,  0x00,  0x3F,  0xFE,  0x20,  0x82,  0x21,  0x42,  0x22,  0x22,  0x24,  0x12,  0x3B,  0xEE, 	/* 2A720 */
+	0x20,  0x02,  0x2F,  0xF2,  0x21,  0x12,  0x21,  0x12,  0x21,  0x62,  0x21,  0x02,  0x21,  0x02,  0x3F,  0xFE, 	/* 2A730 */
+	0x20,  0x02,  0xBA,  0x00,  0x00,  0x3F,  0xFE,  0x20,  0x82,  0x20,  0x82,  0x20,  0x82,  0x3F,  0xFE,  0x20, 	/* 2A740 */
+	0x82,  0x20,  0x82,  0x27,  0xF2,  0x24,  0x12,  0x24,  0x12,  0x24,  0x12,  0x27,  0xF2,  0x20,  0x02,  0x3F, 	/* 2A750 */
+	0xFE,  0x00,  0x00,  0xBD,  0x00,  0x00,  0x3F,  0xFE,  0x20,  0x02,  0x2F,  0xFA,  0x20,  0x82,  0x20,  0x82, 	/* 2A760 */
+	0x20,  0x82,  0x27,  0xF2,  0x20,  0x82,  0x20,  0xA2,  0x20,  0x92,  0x20,  0x92,  0x2F,  0xFA,  0x20,  0x02, 	/* 2A770 */
+	0x3F,  0xFE,  0x00,  0x00,  0xBF,  0x00,  0x00,  0x3F,  0xFE,  0x20,  0x82,  0x20,  0x82,  0x3F,  0xFE,  0x21, 	/* 2A780 */
+	0x02,  0x23,  0xF2,  0x22,  0x12,  0x27,  0xF2,  0x2A,  0x12,  0x33,  0xF2,  0x22,  0x12,  0x22,  0x12,  0x22, 	/* 2A790 */
+	0x32,  0x3F,  0xFE,  0x20,  0x02,  0x80,  0x00,  0x00,  0x3F,  0xFE,  0x21,  0x22,  0x26,  0x26,  0x38,  0x9E, 	/* 2A7A0 */
+	0x20,  0x82,  0x3F,  0xFE,  0x21,  0x02,  0x21,  0xF2,  0x21,  0x12,  0x22,  0x12,  0x24,  0x12,  0x38,  0x62, 	/* 2A7B0 */
+	0x20,  0x02,  0x3F,  0xFE,  0x20,  0x02,  0x83,  0x00,  0x00,  0x3F,  0xFE,  0x20,  0x92,  0x20,  0x8A,  0x3F, 	/* 2A7C0 */
+	0xFE,  0x20,  0x82,  0x2F,  0xFA,  0x28,  0x8A,  0x2F,  0xFA,  0x28,  0x8A,  0x2F,  0xFA,  0x28,  0x8A,  0x28, 	/* 2A7D0 */
+	0x9A,  0x20,  0x02,  0x3F,  0xFE,  0x00,  0x00,  0x84,  0x00,  0x00,  0x3F,  0xFE,  0x20,  0x02,  0x2F,  0xFA, 	/* 2A7E0 */
+	0x20,  0x82,  0x2F,  0xF2,  0x21,  0x12,  0x3F,  0xFE,  0x20,  0x02,  0x27,  0xF2,  0x24,  0x12,  0x24,  0x12, 	/* 2A7F0 */
+	0x27,  0xF2,  0x20,  0x02,  0x3F,  0xFE,  0x20,  0x02,  0x88,  0x00,  0x00,  0x3F,  0xFE,  0x22,  0xA2,  0x24, 	/* 2A800 */
+	0x92,  0x2F,  0xFA,  0x21,  0x22,  0x3F,  0xFE,  0x22,  0x12,  0x27,  0xFA,  0x2A,  0x26,  0x32,  0x62,  0x22, 	/* 2A810 */
+	0x0A,  0x21,  0xFA,  0x20,  0x02,  0x3F,  0xFE,  0x20,  0x02,  0x89,  0x00,  0x00,  0x3F,  0xFE,  0x20,  0x82, 	/* 2A820 */
+	0x20,  0x82,  0x27,  0xFA,  0x20,  0x82,  0x3F,  0xFE,  0x24,  0x12,  0x22,  0x22,  0x2F,  0xFA,  0x20,  0x82, 	/* 2A830 */
+	0x3F,  0xFE,  0x20,  0x82,  0x20,  0x82,  0x3F,  0xFE,  0x20,  0x02,  0x8B,  0x00,  0x00,  0x3F,  0xFE,  0x20, 	/* 2A840 */
+	0x52,  0x20,  0x4A,  0x3F,  0xFE,  0x20,  0x42,  0x2F,  0x4A,  0x29,  0x4A,  0x2F,  0x52,  0x20,  0x22,  0x23, 	/* 2A850 */
+	0x6A,  0x3C,  0x9A,  0x21,  0x0A,  0x20,  0x02,  0x3F,  0xFE,  0x20,  0x02,  0x8D,  0x00,  0x00,  0x3F,  0xFE, 	/* 2A860 */
+	0x21,  0x02,  0x27,  0xF2,  0x21,  0x12,  0x3F,  0xFE,  0x24,  0x12,  0x27,  0xF2,  0x20,  0x42,  0x2F,  0xFA, 	/* 2A870 */
+	0x28,  0x42,  0x2F,  0xFE,  0x20,  0x42,  0x20,  0x42,  0x3F,  0xFE,  0x20,  0x02,  0x8F,  0x00,  0x00,  0x3F, 	/* 2A880 */
+	0xFE,  0x24,  0x92,  0x22,  0xA2,  0x2F,  0xFA,  0x21,  0x42,  0x3F,  0xFE,  0x22,  0x22,  0x27,  0xF2,  0x38, 	/* 2A890 */
+	0x2E,  0x27,  0xE2,  0x24,  0x12,  0x23,  0xF2,  0x20,  0x02,  0x3F,  0xFE,  0x00,  0x00,  0x92,  0x00,  0x00, 	/* 2A8A0 */
+	0x3F,  0xFE,  0x20,  0x82,  0x27,  0xF2,  0x20,  0x82,  0x3F,  0xFE,  0x20,  0x02,  0x27,  0xF2,  0x24,  0x12, 	/* 2A8B0 */
+	0x27,  0xF2,  0x23,  0x4A,  0x25,  0x32,  0x39,  0x1E,  0x21,  0x02,  0x3F,  0xFE,  0x20,  0x02,  0x93,  0x00, 	/* 2A8C0 */
+	0x00,  0x3F,  0xFE,  0x20,  0x02,  0x27,  0xF2,  0x24,  0x12,  0x2F,  0xFA,  0x28,  0x0A,  0x2F,  0xFA,  0x28, 	/* 2A8D0 */
+	0x0A,  0x2F,  0xFA,  0x28,  0x0A,  0x2F,  0xFA,  0x22,  0x32,  0x2C,  0x0A,  0x3F,  0xFE,  0x20,  0x02,  0x96, 	/* 2A8E0 */
+	0x00,  0x00,  0x3F,  0xFE,  0x20,  0x02,  0x27,  0xF2,  0x24,  0x12,  0x27,  0xF2,  0x20,  0x82,  0x3F,  0xFE, 	/* 2A8F0 */
+	0x28,  0x0A,  0x2B,  0xEA,  0x2A,  0x2A,  0x2B,  0xEA,  0x2F,  0xFA,  0x20,  0x02,  0x3F,  0xFE,  0x20,  0x02, 	/* 2A900 */
+	0x98,  0x00,  0x00,  0x3F,  0xFE,  0x20,  0x82,  0x3F,  0xFE,  0x20,  0x82,  0x27,  0xF2,  0x24,  0x92,  0x27, 	/* 2A910 */
+	0xF2,  0x24,  0x9A,  0x3F,  0xF6,  0x20,  0x22,  0x3F,  0xFE,  0x22,  0x22,  0x20,  0x62,  0x3F,  0xFE,  0x20, 	/* 2A920 */
+	0x02,  0x9C,  0x00,  0x00,  0x3F,  0xFE,  0x20,  0x02,  0x2F,  0xFA,  0x29,  0x4A,  0x3F,  0xFE,  0x20,  0x02, 	/* 2A930 */
+	0x27,  0xF2,  0x24,  0x12,  0x27,  0xF2,  0x21,  0x8A,  0x26,  0x52,  0x3B,  0xA2,  0x26,  0x1A,  0x3F,  0xFE, 	/* 2A940 */
+	0x00,  0x02,  0x9F,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x1F, 	/* 2A950 */
+	0xFC,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x7F, 	/* 2A960 */
+	0xFF,  0x00,  0x00,  0xA6,  0x08,  0x00,  0x08,  0xE0,  0x08,  0x20,  0x08,  0x20,  0x08,  0x20,  0x7E,  0x20, 	/* 2A970 */
+	0x08,  0x20,  0x08,  0x20,  0x08,  0x30,  0x08,  0x50,  0x0E,  0x50,  0x18,  0x88,  0x60,  0x88,  0x01,  0x04, 	/* 2A980 */
+	0x02,  0x02,  0x0C,  0x01,  0xA7,  0x00,  0x00,  0x1F,  0xFE,  0x10,  0x00,  0x10,  0x40,  0x10,  0x40,  0x10, 	/* 2A990 */
+	0x40,  0x10,  0x40,  0x17,  0xFE,  0x10,  0x40,  0x10,  0x40,  0x10,  0x40,  0x20,  0x40,  0x20,  0x40,  0x5F, 	/* 2A9A0 */
+	0xFF,  0x00,  0x00,  0x00,  0x00,  0xA8,  0x01,  0x00,  0x01,  0x00,  0x01,  0x00,  0x7F,  0xFF,  0x02,  0x20, 	/* 2A9B0 */
+	0x02,  0x20,  0x0C,  0x20,  0x0C,  0x20,  0x0B,  0xFE,  0x18,  0x20,  0x28,  0x20,  0x48,  0x20,  0x08,  0x20, 	/* 2A9C0 */
+	0x08,  0x20,  0x0F,  0xFF,  0x08,  0x00,  0xAD,  0x00,  0x80,  0x00,  0x80,  0x1F,  0xFC,  0x00,  0x80,  0x00, 	/* 2A9D0 */
+	0x80,  0x00,  0x80,  0x3F,  0xFE,  0x00,  0x00,  0x00,  0x80,  0x00,  0x80,  0x1F,  0xFC,  0x00,  0x80,  0x00, 	/* 2A9E0 */
+	0x80,  0x00,  0x80,  0x7F,  0xFF,  0x00,  0x00,  0xB0,  0x08,  0x10,  0x08,  0x90,  0x08,  0x90,  0x08,  0x92, 	/* 2A9F0 */
+	0x7E,  0x9E,  0x08,  0xF2,  0x0B,  0x92,  0x08,  0x92,  0x08,  0x92,  0x08,  0x92,  0x0A,  0x9C,  0x0C,  0x90, 	/* 2AA00 */
+	0x10,  0x80,  0x60,  0x81,  0x00,  0x41,  0x00,  0x3F,  0xB7,  0x00,  0x00,  0x0B,  0xFF,  0x08,  0x20,  0x08, 	/* 2AA10 */
+	0x20,  0x08,  0x20,  0x7E,  0x30,  0x08,  0x28,  0x08,  0x24,  0x08,  0x22,  0x08,  0x20,  0x0E,  0x20,  0x18, 	/* 2AA20 */
+	0x20,  0x60,  0x20,  0x00,  0x20,  0x00,  0x20,  0x00,  0x20,  0xB8,  0x00,  0x20,  0x10,  0x20,  0x10,  0x20, 	/* 2AA30 */
+	0x10,  0x20,  0x10,  0x20,  0x7D,  0x22,  0x11,  0x22,  0x11,  0x22,  0x11,  0x22,  0x11,  0x22,  0x15,  0x22, 	/* 2AA40 */
+	0x19,  0x22,  0x61,  0x22,  0x01,  0x22,  0x01,  0xFE,  0x00,  0x00,  0xBB,  0x10,  0x04,  0x10,  0x18,  0x10, 	/* 2AA50 */
+	0xE0,  0x10,  0x80,  0x7C,  0x80,  0x10,  0xFF,  0x10,  0x88,  0x10,  0x88,  0x10,  0x88,  0x14,  0x88,  0x18, 	/* 2AA60 */
+	0x88,  0x61,  0x08,  0x01,  0x08,  0x02,  0x08,  0x04,  0x08,  0x00,  0x08,  0x80,  0x00,  0x20,  0x10,  0x20, 	/* 2AA70 */
+	0x10,  0x20,  0x11,  0x20,  0x11,  0x20,  0x7D,  0x20,  0x11,  0x3E,  0x11,  0x20,  0x11,  0x20,  0x11,  0x20, 	/* 2AA80 */
+	0x15,  0x20,  0x19,  0x20,  0x61,  0x20,  0x01,  0x20,  0x0F,  0xFF,  0x00,  0x00,  0x82,  0x08,  0x00,  0x09, 	/* 2AA90 */
+	0xFF,  0x09,  0x00,  0x09,  0x00,  0x7F,  0x00,  0x09,  0xFC,  0x09,  0x44,  0x09,  0x44,  0x09,  0x44,  0x09, 	/* 2AAA0 */
+	0x28,  0x0E,  0x28,  0x1A,  0x10,  0x62,  0x18,  0x04,  0x24,  0x08,  0xC2,  0x03,  0x01,  0x87,  0x00,  0x40, 	/* 2AAB0 */
+	0x08,  0x40,  0x08,  0x40,  0x08,  0xFE,  0x7E,  0x82,  0x09,  0x02,  0x0A,  0xC2,  0x08,  0x22,  0x08,  0x02, 	/* 2AAC0 */
+	0x08,  0x0A,  0x0E,  0x12,  0x18,  0x62,  0x61,  0x82,  0x00,  0x02,  0x00,  0x04,  0x00,  0x38,  0x8A,  0x08, 	/* 2AAD0 */
+	0x20,  0x08,  0x20,  0x08,  0x20,  0x0B,  0xFF,  0x7E,  0x20,  0x08,  0x20,  0x08,  0x20,  0x08,  0x3C,  0x08, 	/* 2AAE0 */
+	0x44,  0x08,  0x44,  0x0E,  0x44,  0x18,  0x84,  0x60,  0x84,  0x01,  0x04,  0x02,  0x04,  0x04,  0x18,  0x8E, 	/* 2AAF0 */
+	0x00,  0x80,  0x10,  0x80,  0x10,  0x80,  0x10,  0xFE,  0x10,  0x82,  0x7D,  0x24,  0x11,  0x28,  0x12,  0x20, 	/* 2AB00 */
+	0x10,  0x20,  0x10,  0x30,  0x14,  0x50,  0x18,  0x48,  0x60,  0x88,  0x01,  0x04,  0x02,  0x02,  0x0C,  0x01, 	/* 2AB10 */
+	0x8F,  0x00,  0x00,  0x13,  0xFF,  0x10,  0x10,  0x10,  0x10,  0x10,  0x20,  0x7C,  0x20,  0x10,  0x68,  0x10, 	/* 2AB20 */
+	0xA4,  0x11,  0x22,  0x12,  0x21,  0x10,  0x20,  0x1C,  0x20,  0x60,  0x20,  0x00,  0x20,  0x00,  0x20,  0x00, 	/* 2AB30 */
+	0x20,  0x90,  0x00,  0x80,  0x00,  0x80,  0x08,  0x88,  0x08,  0x88,  0x08,  0x88,  0x08,  0x88,  0x0C,  0x94, 	/* 2AB40 */
+	0x12,  0x92,  0x12,  0xA2,  0x20,  0x80,  0x0F,  0xFC,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x7F,  0xFF, 	/* 2AB50 */
+	0x00,  0x00,  0x91,  0x08,  0x20,  0x08,  0x20,  0x08,  0x20,  0x0B,  0xFF,  0x7E,  0x00,  0x08,  0x00,  0x08, 	/* 2AB60 */
+	0xF0,  0x08,  0x90,  0x08,  0x90,  0x08,  0x90,  0x0E,  0x90,  0x18,  0x90,  0x61,  0x10,  0x01,  0x12,  0x02, 	/* 2AB70 */
+	0x12,  0x04,  0x0E,  0xA1,  0x00,  0x20,  0x10,  0x20,  0x10,  0x20,  0x13,  0xFF,  0x12,  0x22,  0x7E,  0x24, 	/* 2AB80 */
+	0x12,  0x20,  0x13,  0xFC,  0x12,  0x84,  0x12,  0x88,  0x16,  0x48,  0x1A,  0x30,  0x64,  0x30,  0x04,  0x48, 	/* 2AB90 */
+	0x09,  0x84,  0x16,  0x03,  0xA4,  0x00,  0x20,  0x08,  0x20,  0x08,  0x20,  0x09,  0xFE,  0x09,  0x22,  0x7F, 	/* 2ABA0 */
+	0x22,  0x09,  0xFE,  0x09,  0x22,  0x09,  0x22,  0x09,  0x22,  0x09,  0xFE,  0x0E,  0x20,  0x18,  0x20,  0x60, 	/* 2ABB0 */
+	0x20,  0x00,  0x20,  0x00,  0x20,  0xA6,  0x10,  0x00,  0x11,  0xFC,  0x11,  0x04,  0x11,  0x04,  0x7D,  0x04, 	/* 2ABC0 */
+	0x11,  0x04,  0x11,  0xFC,  0x11,  0x04,  0x11,  0x04,  0x17,  0x04,  0x19,  0x04,  0x61,  0xFC,  0x00,  0x00, 	/* 2ABD0 */
+	0x00,  0x00,  0x0F,  0xFF,  0x00,  0x00,  0xA9,  0x10,  0x84,  0x10,  0x84,  0x10,  0x84,  0x17,  0xFF,  0x10, 	/* 2ABE0 */
+	0x84,  0x7C,  0x84,  0x10,  0x84,  0x10,  0x84,  0x10,  0x84,  0x10,  0xFC,  0x14,  0x84,  0x18,  0x84,  0x60, 	/* 2ABF0 */
+	0x84,  0x00,  0x84,  0x00,  0xFC,  0x00,  0x00,  0xAA,  0x00,  0x00,  0x13,  0xFE,  0x10,  0x24,  0x11,  0x24, 	/* 2AC00 */
+	0x10,  0xA4,  0x7C,  0xA8,  0x10,  0xA0,  0x10,  0x20,  0x17,  0xFF,  0x10,  0x20,  0x10,  0x20,  0x16,  0x20, 	/* 2AC10 */
+	0x18,  0x20,  0x60,  0x20,  0x00,  0x20,  0x00,  0x20,  0xBF,  0x00,  0x44,  0x10,  0x44,  0x10,  0x84,  0x10, 	/* 2AC20 */
+	0x84,  0x11,  0x7F,  0x7D,  0x04,  0x13,  0x04,  0x15,  0x44,  0x11,  0x24,  0x11,  0x24,  0x15,  0x04,  0x19, 	/* 2AC30 */
+	0x04,  0x61,  0x04,  0x01,  0x04,  0x01,  0x04,  0x01,  0x0C,  0x82,  0x00,  0x18,  0x00,  0xE0,  0x1F,  0x80, 	/* 2AC40 */
+	0x00,  0x80,  0x3F,  0xFE,  0x08,  0x88,  0x08,  0x88,  0x7F,  0xFF,  0x08,  0x88,  0x08,  0x88,  0x08,  0x88, 	/* 2AC50 */
+	0x3F,  0xFE,  0x00,  0x80,  0x00,  0x80,  0x7F,  0xFF,  0x00,  0x00,  0x88,  0x04,  0x28,  0x04,  0x24,  0x08, 	/* 2AC60 */
+	0x24,  0x0B,  0xFF,  0x18,  0x20,  0x28,  0x10,  0x48,  0x10,  0x08,  0x09,  0x08,  0x85,  0x08,  0x83,  0x00, 	/* 2AC70 */
+	0x80,  0x1F,  0xFC,  0x00,  0x80,  0x00,  0x80,  0x7F,  0xFF,  0x00,  0x00,  0x89,  0x00,  0x40,  0x08,  0x40, 	/* 2AC80 */
+	0x08,  0x7E,  0x08,  0x82,  0x7E,  0x82,  0x09,  0xF2,  0x0A,  0x92,  0x08,  0x92,  0x08,  0x92,  0x08,  0xF2, 	/* 2AC90 */
+	0x0E,  0x84,  0x18,  0x98,  0x60,  0x80,  0x00,  0x81,  0x00,  0x81,  0x00,  0x7E,  0x8B,  0x00,  0x04,  0x7F, 	/* 2ACA0 */
+	0xA4,  0x12,  0x24,  0x12,  0x24,  0x12,  0x24,  0x7F,  0xE4,  0x12,  0x24,  0x12,  0x24,  0x12,  0x04,  0x22, 	/* 2ACB0 */
+	0x8C,  0x40,  0x80,  0x1F,  0xF8,  0x00,  0x80,  0x00,  0x80,  0x7F,  0xFE,  0x00,  0x00,  0x93,  0x10,  0x20, 	/* 2ACC0 */
+	0x10,  0x20,  0x10,  0x20,  0x17,  0xFF,  0x10,  0x40,  0x7C,  0x48,  0x10,  0x48,  0x11,  0x90,  0x10,  0x54, 	/* 2ACD0 */
+	0x10,  0x24,  0x14,  0x48,  0x19,  0x90,  0x60,  0x30,  0x00,  0x48,  0x01,  0x84,  0x06,  0x02,  0xA0,  0x10, 	/* 2ACE0 */
+	0x00,  0x11,  0xFC,  0x11,  0x04,  0x11,  0x04,  0x11,  0xFC,  0x7F,  0x04,  0x11,  0x04,  0x11,  0xFC,  0x11, 	/* 2ACF0 */
+	0x22,  0x11,  0x22,  0x15,  0x14,  0x19,  0x18,  0x61,  0x08,  0x01,  0x64,  0x01,  0x82,  0x06,  0x01,  0xA2, 	/* 2AD00 */
+	0x00,  0x04,  0x10,  0x38,  0x11,  0xC0,  0x11,  0x00,  0x11,  0x00,  0x7D,  0xFF,  0x11,  0x00,  0x11,  0x00, 	/* 2AD10 */
+	0x11,  0xFC,  0x13,  0x84,  0x15,  0x84,  0x1A,  0x84,  0x62,  0x84,  0x04,  0x84,  0x08,  0xFC,  0x00,  0x00, 	/* 2AD20 */
+	0xA3,  0x08,  0x00,  0x09,  0xFE,  0x08,  0x00,  0x08,  0x00,  0x7E,  0xFC,  0x08,  0x84,  0x08,  0x84,  0x08, 	/* 2AD30 */
+	0xFC,  0x08,  0x84,  0x08,  0x84,  0x0E,  0x84,  0x18,  0xFC,  0x60,  0x00,  0x00,  0x00,  0x07,  0xFF,  0x00, 	/* 2AD40 */
+	0x00,  0xA4,  0x00,  0x00,  0x17,  0xFF,  0x10,  0x40,  0x10,  0x50,  0x10,  0x4C,  0x7C,  0x9A,  0x13,  0xE1, 	/* 2AD50 */
+	0x10,  0x00,  0x10,  0x20,  0x10,  0x20,  0x15,  0xFC,  0x18,  0x20,  0x60,  0x20,  0x00,  0x20,  0x07,  0xFF, 	/* 2AD60 */
+	0x00,  0x00,  0xAA,  0x01,  0x04,  0x10,  0x84,  0x10,  0x88,  0x13,  0xFE,  0x10,  0x88,  0x7C,  0x88,  0x10, 	/* 2AD70 */
+	0x88,  0x10,  0x88,  0x17,  0xFF,  0x10,  0x88,  0x10,  0x88,  0x1C,  0x88,  0x71,  0x08,  0x01,  0x08,  0x02, 	/* 2AD80 */
+	0x08,  0x04,  0x08,  0xB0,  0x00,  0x20,  0x10,  0x20,  0x10,  0x3E,  0x10,  0x20,  0x10,  0x20,  0x7F,  0xFF, 	/* 2AD90 */
+	0x10,  0x00,  0x10,  0x00,  0x13,  0xFF,  0x10,  0x20,  0x14,  0x30,  0x18,  0x2C,  0x60,  0x22,  0x00,  0x20, 	/* 2ADA0 */
+	0x00,  0x20,  0x00,  0x20,  0xB3,  0x00,  0x80,  0x10,  0xBE,  0x11,  0x00,  0x11,  0x00,  0x12,  0x00,  0x7C, 	/* 2ADB0 */
+	0xFF,  0x10,  0x84,  0x11,  0x04,  0x13,  0x04,  0x15,  0x04,  0x11,  0x04,  0x1D,  0x04,  0x61,  0x04,  0x01, 	/* 2ADC0 */
+	0x04,  0x01,  0x04,  0x01,  0x0C,  0x80,  0x00,  0x08,  0x00,  0x70,  0x1F,  0x80,  0x00,  0x80,  0x7F,  0xFF, 	/* 2ADD0 */
+	0x00,  0x80,  0x04,  0x92,  0x3C,  0x9C,  0x04,  0x90,  0x0C,  0x91,  0x34,  0x8F,  0x00,  0x80,  0x1F,  0xFC, 	/* 2ADE0 */
+	0x00,  0x80,  0x7F,  0xFF,  0x00,  0x00,  0x83,  0x00,  0x20,  0x10,  0x28,  0x10,  0x44,  0x10,  0x8C,  0x13, 	/* 2ADF0 */
+	0xF2,  0x7C,  0x82,  0x10,  0x80,  0x10,  0xFE,  0x11,  0x20,  0x12,  0x20,  0x13,  0xFF,  0x1C,  0x20,  0x70, 	/* 2AE00 */
+	0x50,  0x00,  0x88,  0x03,  0x04,  0x0C,  0x03,  0x86,  0x00,  0x40,  0x10,  0x7C,  0x10,  0x88,  0x11,  0x10, 	/* 2AE10 */
+	0x13,  0xFE,  0x7D,  0x12,  0x11,  0x12,  0x11,  0xFE,  0x11,  0x12,  0x11,  0x12,  0x15,  0xFE,  0x19,  0x02, 	/* 2AE20 */
+	0x61,  0x02,  0x02,  0x02,  0x02,  0x02,  0x04,  0x06,  0x8B,  0x08,  0x00,  0x09,  0xFC,  0x09,  0x24,  0x09, 	/* 2AE30 */
+	0x24,  0x09,  0xFC,  0x7F,  0x24,  0x09,  0x24,  0x09,  0xFC,  0x08,  0x20,  0x08,  0x20,  0x0D,  0xFE,  0x18, 	/* 2AE40 */
+	0x20,  0x60,  0x20,  0x00,  0x20,  0x07,  0xFF,  0x00,  0x00,  0x8E,  0x10,  0x14,  0x10,  0x12,  0x10,  0x12, 	/* 2AE50 */
+	0x13,  0xFF,  0x7E,  0x10,  0x12,  0x12,  0x13,  0xD2,  0x12,  0x52,  0x12,  0x4C,  0x16,  0x4C,  0x1A,  0x48, 	/* 2AE60 */
+	0x62,  0x58,  0x04,  0x55,  0x05,  0xA5,  0x08,  0x43,  0x10,  0x01,  0x92,  0x00,  0x04,  0x10,  0x38,  0x13, 	/* 2AE70 */
+	0xC4,  0x10,  0x22,  0x11,  0x11,  0x7D,  0x11,  0x12,  0x00,  0x10,  0x08,  0x13,  0xFF,  0x10,  0x08,  0x14, 	/* 2AE80 */
+	0x88,  0x18,  0x48,  0x60,  0x48,  0x00,  0x08,  0x00,  0x08,  0x00,  0x18,  0x93,  0x10,  0x10,  0x10,  0x20, 	/* 2AE90 */
+	0x10,  0xD2,  0x13,  0x8C,  0x10,  0x48,  0x7C,  0x30,  0x10,  0x60,  0x13,  0x88,  0x10,  0x08,  0x11,  0xFF, 	/* 2AEA0 */
+	0x12,  0x08,  0x1D,  0x08,  0x60,  0x88,  0x00,  0x88,  0x00,  0x08,  0x00,  0x18,  0x94,  0x00,  0x24,  0x10, 	/* 2AEB0 */
+	0x22,  0x13,  0xFF,  0x10,  0x20,  0x10,  0x20,  0x7D,  0xFE,  0x11,  0x22,  0x11,  0x22,  0x11,  0xFE,  0x11, 	/* 2AEC0 */
+	0x22,  0x15,  0x22,  0x19,  0xFE,  0x61,  0x22,  0x01,  0x22,  0x01,  0x22,  0x01,  0x26,  0x96,  0x00,  0x88, 	/* 2AED0 */
+	0x10,  0x88,  0x17,  0xFF,  0x10,  0x88,  0x10,  0x88,  0x7C,  0x50,  0x10,  0x50,  0x10,  0x52,  0x10,  0x92, 	/* 2AEE0 */
+	0x10,  0x94,  0x15,  0x98,  0x1A,  0x90,  0x60,  0x90,  0x00,  0x91,  0x00,  0x91,  0x00,  0x8F,  0x9C,  0x04, 	/* 2AEF0 */
+	0x10,  0x04,  0x10,  0x7F,  0xFF,  0x0C,  0x18,  0x0E,  0x38,  0x15,  0x54,  0x24,  0x92,  0x44,  0x11,  0x04, 	/* 2AF00 */
+	0x10,  0x00,  0x80,  0x00,  0x80,  0x1F,  0xFC,  0x00,  0x80,  0x00,  0x80,  0x7F,  0xFF,  0x00,  0x00,  0x9F, 	/* 2AF10 */
+	0x10,  0x10,  0x10,  0x14,  0x10,  0x12,  0x13,  0xFF,  0x10,  0x10,  0x7F,  0xD2,  0x12,  0x52,  0x12,  0x52, 	/* 2AF20 */
+	0x12,  0x54,  0x13,  0xCC,  0x12,  0x4C,  0x16,  0x28,  0x18,  0xCD,  0x63,  0x15,  0x0C,  0x23,  0x00,  0x41, 	/* 2AF30 */
+	0xA0,  0x00,  0x20,  0x10,  0x40,  0x11,  0xFC,  0x11,  0x04,  0x11,  0xFC,  0x7D,  0x00,  0x11,  0xFC,  0x11, 	/* 2AF40 */
+	0x04,  0x11,  0x04,  0x11,  0xFC,  0x14,  0x20,  0x1B,  0xFF,  0x60,  0x20,  0x00,  0x20,  0x00,  0x20,  0x00, 	/* 2AF50 */
+	0x20,  0xA3,  0x10,  0x20,  0x10,  0x20,  0x13,  0xFE,  0x11,  0x08,  0x11,  0x08,  0x7D,  0x8C,  0x12,  0x52, 	/* 2AF60 */
+	0x14,  0x60,  0x10,  0x00,  0x10,  0x20,  0x17,  0xFF,  0x18,  0x20,  0x60,  0x20,  0x00,  0x20,  0x00,  0x20, 	/* 2AF70 */
+	0x00,  0x20,  0xB4,  0x00,  0x10,  0x10,  0x10,  0x13,  0xFF,  0x10,  0x10,  0x10,  0x7C,  0x7C,  0x44,  0x11, 	/* 2AF80 */
+	0x44,  0x11,  0x7C,  0x11,  0x44,  0x11,  0x7C,  0x13,  0x44,  0x1D,  0x44,  0x71,  0x7C,  0x01,  0x00,  0x01, 	/* 2AF90 */
+	0xFF,  0x00,  0x00,  0xB7,  0x08,  0x20,  0x08,  0x20,  0x3F,  0x20,  0x08,  0x20,  0x08,  0xFC,  0x7F,  0xA4, 	/* 2AFA0 */
+	0x22,  0x24,  0x14,  0xA4,  0x7F,  0x64,  0x08,  0x24,  0x08,  0x24,  0x3F,  0x54,  0x08,  0x54,  0x08,  0x85, 	/* 2AFB0 */
+	0x09,  0x05,  0x0A,  0x03,  0xB9,  0x00,  0x20,  0x10,  0x20,  0x13,  0xFE,  0x11,  0x04,  0x10,  0x84,  0x7C, 	/* 2AFC0 */
+	0x88,  0x10,  0x88,  0x17,  0xFF,  0x10,  0x00,  0x10,  0x00,  0x17,  0xFC,  0x19,  0x04,  0x61,  0x04,  0x01, 	/* 2AFD0 */
+	0x04,  0x01,  0xFC,  0x00,  0x00,  0xBA,  0x04,  0x10,  0x04,  0x10,  0x3F,  0xFE,  0x04,  0x10,  0x07,  0xF0, 	/* 2AFE0 */
+	0x04,  0x10,  0x07,  0xF0,  0x04,  0x10,  0x7F,  0xFF,  0x04,  0x90,  0x08,  0x88,  0x17,  0xF4,  0x60,  0x83, 	/* 2AFF0 */
+	0x00,  0x80,  0x3F,  0xFE,  0x00,  0x00,  0xBC,  0x00,  0x20,  0x10,  0x20,  0x13,  0xFE,  0x10,  0x30,  0x10, 	/* 2B000 */
+	0x48,  0x7D,  0x84,  0x10,  0x00,  0x13,  0xFF,  0x10,  0x04,  0x11,  0xE4,  0x11,  0x24,  0x15,  0x24,  0x19, 	/* 2B010 */
+	0xE4,  0x60,  0x04,  0x00,  0x04,  0x00,  0x0C,  0x80,  0x00,  0x00,  0x13,  0xFE,  0x12,  0x02,  0x12,  0x02, 	/* 2B020 */
+	0x13,  0xFE,  0x7E,  0x10,  0x12,  0x92,  0x12,  0x92,  0x12,  0x92,  0x12,  0xFE,  0x16,  0x10,  0x1A,  0x92, 	/* 2B030 */
+	0x64,  0x92,  0x04,  0x92,  0x08,  0xFE,  0x10,  0x00,  0x82,  0x11,  0x10,  0x09,  0x10,  0x09,  0x20,  0x7F, 	/* 2B040 */
+	0xFE,  0x40,  0x02,  0x4F,  0xF2,  0x08,  0x10,  0x08,  0x10,  0x0F,  0xF0,  0x01,  0x00,  0x01,  0x00,  0x1F, 	/* 2B050 */
+	0xF8,  0x01,  0x00,  0x01,  0x00,  0x7F,  0xFE,  0x00,  0x00,  0x85,  0x00,  0x00,  0x3F,  0xFC,  0x24,  0x24, 	/* 2B060 */
+	0x24,  0x24,  0x3F,  0x14,  0x21,  0x18,  0x3F,  0x08,  0x24,  0x14,  0x24,  0x62,  0x3F,  0x81,  0x00,  0x80, 	/* 2B070 */
+	0x1F,  0xFC,  0x00,  0x80,  0x00,  0x80,  0x7F,  0xFF,  0x00,  0x00,  0x86,  0x00,  0x44,  0x08,  0x44,  0x08, 	/* 2B080 */
+	0x88,  0x08,  0xFF,  0x09,  0x88,  0x7E,  0x88,  0x08,  0x88,  0x08,  0xFE,  0x08,  0x88,  0x08,  0x88,  0x08, 	/* 2B090 */
+	0xFE,  0x0E,  0x88,  0x18,  0x88,  0x60,  0x88,  0x00,  0xFF,  0x00,  0x00,  0x8A,  0x00,  0x00,  0x3F,  0xFE, 	/* 2B0A0 */
+	0x02,  0x20,  0x0E,  0x38,  0x08,  0x08,  0x08,  0x08,  0x0E,  0x38,  0x02,  0x20,  0x7F,  0xFF,  0x00,  0x80, 	/* 2B0B0 */
+	0x00,  0x80,  0x1F,  0xFC,  0x00,  0x80,  0x00,  0x80,  0x7F,  0xFF,  0x00,  0x00,  0x8B,  0x10,  0x00,  0x13, 	/* 2B0C0 */
+	0xDE,  0x12,  0x52,  0x12,  0x52,  0x7E,  0x52,  0x13,  0xDE,  0x12,  0x52,  0x12,  0x52,  0x12,  0x52,  0x17, 	/* 2B0D0 */
+	0xDE,  0x1A,  0x52,  0x62,  0x52,  0x02,  0x52,  0x02,  0x52,  0x04,  0x62,  0x08,  0xC6,  0x95,  0x00,  0x40, 	/* 2B0E0 */
+	0x3C,  0x40,  0x27,  0xFE,  0x28,  0x40,  0x30,  0xFC,  0x28,  0x84,  0x25,  0xFC,  0x25,  0x84,  0x3A,  0xFC, 	/* 2B0F0 */
+	0x24,  0x84,  0x20,  0x8C,  0x20,  0x80,  0x1F,  0xFC,  0x00,  0x80,  0x7F,  0xFF,  0x00,  0x00,  0x99,  0x00, 	/* 2B100 */
+	0x00,  0x17,  0xFF,  0x10,  0x50,  0x10,  0x50,  0x11,  0xFE,  0x7D,  0x52,  0x11,  0x52,  0x11,  0x52,  0x11, 	/* 2B110 */
+	0xFE,  0x10,  0x20,  0x14,  0x20,  0x1B,  0xFE,  0x60,  0x20,  0x00,  0x20,  0x07,  0xFF,  0x00,  0x00,  0x9D, 	/* 2B120 */
+	0x00,  0x00,  0x10,  0xF8,  0x10,  0x88,  0x10,  0x88,  0x10,  0xB8,  0x7E,  0xA8,  0x10,  0xA8,  0x13,  0xFE, 	/* 2B130 */
+	0x12,  0x02,  0x12,  0x7A,  0x12,  0x4A,  0x1E,  0x4A,  0x72,  0x4A,  0x02,  0x7A,  0x02,  0x02,  0x02,  0x06, 	/* 2B140 */
+	0xA1,  0x04,  0x00,  0x05,  0xFC,  0x09,  0x04,  0x11,  0x04,  0x31,  0xFC,  0x50,  0x20,  0x17,  0xFF,  0x10, 	/* 2B150 */
+	0x70,  0x11,  0xAC,  0x16,  0x23,  0x00,  0xA0,  0x1F,  0xFC,  0x00,  0x80,  0x00,  0x80,  0x7F,  0xFF,  0x00, 	/* 2B160 */
+	0x00,  0xA4,  0x00,  0x00,  0x10,  0xFC,  0x10,  0x84,  0x10,  0xFC,  0x10,  0x84,  0x7C,  0x84,  0x10,  0xFC, 	/* 2B170 */
+	0x10,  0x00,  0x17,  0xFF,  0x10,  0x20,  0x11,  0x20,  0x1D,  0x3E,  0x71,  0x20,  0x02,  0xA0,  0x04,  0x60, 	/* 2B180 */
+	0x18,  0x1F,  0xAA,  0x00,  0x84,  0x10,  0x84,  0x13,  0xFF,  0x10,  0x84,  0x10,  0xFC,  0x7C,  0x84,  0x10, 	/* 2B190 */
+	0xFC,  0x10,  0x84,  0x10,  0x84,  0x17,  0xFF,  0x12,  0x50,  0x16,  0x52,  0x1A,  0x8E,  0x63,  0x00,  0x03, 	/* 2B1A0 */
+	0xFF,  0x00,  0x00,  0xAF,  0x00,  0x80,  0x0F,  0xF8,  0x00,  0x80,  0x3F,  0xFE,  0x00,  0x00,  0x04,  0x10, 	/* 2B1B0 */
+	0x3F,  0x7E,  0x04,  0x10,  0x07,  0x10,  0x78,  0xFF,  0x00,  0x00,  0x7F,  0xFE,  0x02,  0x20,  0x04,  0x21, 	/* 2B1C0 */
+	0x18,  0x21,  0x60,  0x1F,  0xB0,  0x10,  0x00,  0x13,  0xFF,  0x12,  0x00,  0x12,  0xFC,  0x12,  0x84,  0x7E, 	/* 2B1D0 */
+	0xFC,  0x12,  0x84,  0x12,  0xFC,  0x12,  0x20,  0x13,  0xFF,  0x16,  0x48,  0x1A,  0xD0,  0x62,  0x38,  0x02, 	/* 2B1E0 */
+	0xC4,  0x03,  0xFF,  0x02,  0x00,  0xB1,  0x08,  0x00,  0x08,  0x7E,  0x3F,  0x42,  0x08,  0x42,  0x08,  0x4C, 	/* 2B1F0 */
+	0x7F,  0x40,  0x22,  0x7E,  0x12,  0x62,  0x14,  0x62,  0x7F,  0xD4,  0x08,  0x54,  0x08,  0x48,  0x3F,  0x48, 	/* 2B200 */
+	0x08,  0x54,  0x08,  0x62,  0x08,  0x41,  0xB4,  0x00,  0x00,  0x10,  0xFC,  0x10,  0x84,  0x10,  0xFC,  0x10, 	/* 2B210 */
+	0x84,  0x7E,  0xFC,  0x10,  0x00,  0x17,  0xFF,  0x10,  0x80,  0x10,  0xFE,  0x15,  0x4A,  0x1A,  0x4A,  0x10, 	/* 2B220 */
+	0x92,  0x61,  0x12,  0x02,  0x22,  0x00,  0x4C,  0xB5,  0x10,  0x20,  0x10,  0x24,  0x11,  0xFC,  0x10,  0x24, 	/* 2B230 */
+	0x7C,  0x28,  0x10,  0x30,  0x13,  0xFF,  0x10,  0x20,  0x10,  0xFC,  0x12,  0x84,  0x1D,  0x84,  0x12,  0xFC, 	/* 2B240 */
+	0x64,  0x84,  0x00,  0x84,  0x00,  0xFC,  0x00,  0x00,  0xBA,  0x00,  0x00,  0x11,  0xFE,  0x11,  0x22,  0x11, 	/* 2B250 */
+	0x22,  0x11,  0xFE,  0x7D,  0x22,  0x11,  0x22,  0x11,  0xFE,  0x10,  0x50,  0x10,  0x88,  0x15,  0x4C,  0x1A, 	/* 2B260 */
+	0x4B,  0x60,  0x48,  0x00,  0x88,  0x01,  0x08,  0x02,  0x08,  0xBD,  0x10,  0x00,  0x11,  0xFE,  0x11,  0x52, 	/* 2B270 */
+	0x11,  0x52,  0x11,  0xFE,  0x7E,  0x00,  0x11,  0xFF,  0x10,  0x20,  0x10,  0x20,  0x11,  0x20,  0x17,  0x3E, 	/* 2B280 */
+	0x19,  0x20,  0x61,  0x20,  0x01,  0x20,  0x01,  0xFF,  0x00,  0x00,  0x80,  0x10,  0x00,  0x13,  0xFE,  0x12, 	/* 2B290 */
+	0x02,  0x12,  0x02,  0x7F,  0xFE,  0x12,  0x84,  0x12,  0x48,  0x13,  0xFE,  0x12,  0x48,  0x16,  0x48,  0x1B, 	/* 2B2A0 */
+	0xFF,  0x62,  0x48,  0x04,  0x48,  0x04,  0x88,  0x08,  0x88,  0x11,  0x08,  0x81,  0x00,  0x00,  0x0F,  0xF8, 	/* 2B2B0 */
+	0x08,  0x88,  0x0F,  0xF8,  0x08,  0x88,  0x08,  0x88,  0x0F,  0xFA,  0x30,  0x0C,  0x08,  0x10,  0x03,  0x40, 	/* 2B2C0 */
+	0x0C,  0xB8,  0x30,  0x86,  0x07,  0xF8,  0x00,  0x80,  0x7F,  0xFF,  0x00,  0x00,  0x8A,  0x00,  0x20,  0x10, 	/* 2B2D0 */
+	0x40,  0x11,  0xFC,  0x11,  0x24,  0x11,  0x24,  0x7F,  0xFC,  0x11,  0x24,  0x11,  0x24,  0x11,  0xFC,  0x10, 	/* 2B2E0 */
+	0x54,  0x16,  0x54,  0x18,  0x9A,  0x60,  0x9F,  0x01,  0x10,  0x06,  0x11,  0x18,  0x0F,  0x8B,  0x08,  0x10, 	/* 2B2F0 */
+	0x2A,  0x54,  0x2A,  0x54,  0x28,  0x50,  0x4C,  0x98,  0x12,  0x24,  0x20,  0x40,  0x7F,  0xFE,  0x40,  0x02, 	/* 2B300 */
+	0x41,  0x02,  0x01,  0x00,  0x1F,  0xF8,  0x01,  0x00,  0x01,  0x00,  0x7F,  0xFE,  0x00,  0x00,  0x91,  0x11, 	/* 2B310 */
+	0x00,  0x0A,  0x3E,  0x7F,  0xA2,  0x04,  0x3E,  0x25,  0x22,  0x25,  0x3E,  0x25,  0x22,  0x3F,  0x22,  0x04, 	/* 2B320 */
+	0x22,  0x08,  0x46,  0x10,  0x80,  0x2F,  0xF8,  0x00,  0x80,  0x00,  0x80,  0x7F,  0xFF,  0x00,  0x00,  0x92, 	/* 2B330 */
+	0x10,  0x10,  0x10,  0x10,  0x13,  0xFE,  0x12,  0x90,  0x12,  0x90,  0x7E,  0x90,  0x12,  0xFF,  0x13,  0x84, 	/* 2B340 */
+	0x12,  0x84,  0x12,  0xFF,  0x16,  0x84,  0x1A,  0xC4,  0x63,  0xA4,  0x00,  0x24,  0x00,  0x04,  0x00,  0x0C, 	/* 2B350 */
+	0x94,  0x00,  0x88,  0x10,  0x88,  0x17,  0xFF,  0x10,  0x88,  0x10,  0x20,  0x7C,  0x20,  0x10,  0x50,  0x10, 	/* 2B360 */
+	0x88,  0x11,  0xFC,  0x16,  0x03,  0x10,  0x00,  0x1D,  0xFC,  0x71,  0x04,  0x01,  0x04,  0x01,  0xFC,  0x00, 	/* 2B370 */
+	0x00,  0x97,  0x00,  0x20,  0x18,  0x20,  0x04,  0x50,  0x61,  0x8C,  0x16,  0xFB,  0x00,  0x20,  0x0F,  0xFF, 	/* 2B380 */
+	0x11,  0x28,  0x21,  0x24,  0x42,  0x62,  0x00,  0x80,  0x0F,  0xF8,  0x00,  0x80,  0x00,  0x80,  0x7F,  0xFF, 	/* 2B390 */
+	0x00,  0x00,  0x98,  0x00,  0x20,  0x10,  0x20,  0x11,  0xFF,  0x11,  0x10,  0x11,  0xFE,  0x7D,  0x12,  0x11, 	/* 2B3A0 */
+	0xFF,  0x11,  0x12,  0x11,  0x12,  0x11,  0xFE,  0x15,  0x00,  0x1A,  0xFE,  0x62,  0x82,  0x04,  0x82,  0x08, 	/* 2B3B0 */
+	0xFE,  0x00,  0x00,  0x99,  0x10,  0x20,  0x10,  0x20,  0x13,  0xFF,  0x10,  0x00,  0x7C,  0xF8,  0x10,  0x88, 	/* 2B3C0 */
+	0x10,  0xF8,  0x10,  0x00,  0x13,  0xFE,  0x12,  0x02,  0x1E,  0xFA,  0x72,  0x8A,  0x02,  0x8A,  0x02,  0xFA, 	/* 2B3D0 */
+	0x02,  0x02,  0x02,  0x06,  0x9A,  0x00,  0x00,  0x13,  0xFE,  0x12,  0x02,  0x12,  0x02,  0x13,  0xFC,  0x7C, 	/* 2B3E0 */
+	0x40,  0x10,  0x84,  0x11,  0x54,  0x16,  0x74,  0x10,  0xA8,  0x11,  0x28,  0x1E,  0x64,  0x70,  0xA2,  0x03, 	/* 2B3F0 */
+	0x21,  0x0C,  0x20,  0x00,  0xC0,  0x9E,  0x01,  0x00,  0x01,  0x00,  0x7F,  0xFE,  0x44,  0x42,  0x5F,  0xFA, 	/* 2B400 */
+	0x04,  0x40,  0x1F,  0xF8,  0x04,  0x40,  0x7F,  0xFE,  0x04,  0x40,  0x09,  0x20,  0x1F,  0xF8,  0x61,  0x06, 	/* 2B410 */
+	0x01,  0x00,  0x7F,  0xFE,  0x00,  0x00,  0xA2,  0x10,  0x20,  0x10,  0x40,  0x11,  0xFC,  0x11,  0x04,  0x11, 	/* 2B420 */
+	0x04,  0x7D,  0xFC,  0x11,  0x00,  0x11,  0x00,  0x11,  0xFF,  0x11,  0x00,  0x15,  0xFE,  0x18,  0x2A,  0x62, 	/* 2B430 */
+	0x96,  0x02,  0x52,  0x04,  0x42,  0x08,  0x0C,  0xA9,  0x01,  0x00,  0x11,  0x00,  0x11,  0xFE,  0x12,  0x00, 	/* 2B440 */
+	0x13,  0xF8,  0x7D,  0x08,  0x15,  0x08,  0x11,  0xF8,  0x10,  0x00,  0x13,  0xFC,  0x16,  0x94,  0x1A,  0x94, 	/* 2B450 */
+	0x62,  0x94,  0x02,  0x94,  0x0F,  0xFF,  0x00,  0x00,  0xAB,  0x00,  0x20,  0x10,  0x20,  0x13,  0xFF,  0x10, 	/* 2B460 */
+	0x20,  0x10,  0xFC,  0x7E,  0x84,  0x10,  0xFC,  0x10,  0x84,  0x10,  0xFC,  0x10,  0x84,  0x10,  0xFC,  0x14, 	/* 2B470 */
+	0x00,  0x1B,  0xFF,  0x60,  0x48,  0x01,  0x84,  0x06,  0x02,  0xB0,  0x00,  0x80,  0x10,  0xFF,  0x09,  0x00, 	/* 2B480 */
+	0x02,  0xFC,  0x24,  0xA4,  0x10,  0x94,  0x03,  0xFF,  0x09,  0x24,  0x11,  0x14,  0x21,  0xFF,  0x40,  0x04, 	/* 2B490 */
+	0x00,  0x98,  0x1F,  0xFC,  0x00,  0x80,  0x7F,  0xFF,  0x00,  0x00,  0xB2,  0x10,  0x40,  0x10,  0x7E,  0x10, 	/* 2B4A0 */
+	0x80,  0x11,  0xFC,  0x7E,  0x84,  0x10,  0xFC,  0x10,  0x84,  0x10,  0xFC,  0x10,  0x00,  0x13,  0xFF,  0x1C, 	/* 2B4B0 */
+	0x80,  0x71,  0xFE,  0x02,  0x4A,  0x04,  0x92,  0x01,  0x22,  0x00,  0x4C,  0xB5,  0x00,  0x80,  0x00,  0x80, 	/* 2B4C0 */
+	0x1F,  0xFF,  0x11,  0x20,  0x1F,  0xFC,  0x11,  0x24,  0x1F,  0xFC,  0x14,  0x20,  0x17,  0xA4,  0x24,  0x3A, 	/* 2B4D0 */
+	0x27,  0xA2,  0x5C,  0x9E,  0x0F,  0xF8,  0x00,  0x80,  0x7F,  0xFF,  0x00,  0x00,  0xB9,  0x04,  0x04,  0x7F, 	/* 2B4E0 */
+	0xB8,  0x04,  0x20,  0x3F,  0x20,  0x25,  0x3F,  0x3F,  0x24,  0x25,  0x24,  0x3F,  0x24,  0x04,  0x24,  0x7F, 	/* 2B4F0 */
+	0xC4,  0x04,  0x04,  0x00,  0x80,  0x1F,  0xFC,  0x00,  0x80,  0x7F,  0xFF,  0x00,  0x00,  0xBE,  0x04,  0x10, 	/* 2B500 */
+	0x7F,  0x90,  0x1E,  0x10,  0x12,  0xFC,  0x1E,  0x14,  0x00,  0x54,  0x3E,  0x24,  0x05,  0x34,  0x1E,  0x55, 	/* 2B510 */
+	0x64,  0x8B,  0x0C,  0x81,  0x1F,  0xF8,  0x00,  0x80,  0x00,  0x80,  0x7F,  0xFF,  0x00,  0x00,  0x83,  0x00, 	/* 2B520 */
+	0x20,  0x10,  0x20,  0x17,  0xFE,  0x11,  0x08,  0x10,  0x90,  0x7F,  0xFF,  0x10,  0x00,  0x11,  0xFC,  0x11, 	/* 2B530 */
+	0x04,  0x11,  0xFC,  0x15,  0x04,  0x19,  0xFC,  0x60,  0x50,  0x00,  0x91,  0x03,  0x11,  0x0C,  0x0F,  0x85, 	/* 2B540 */
+	0x00,  0x00,  0x3F,  0x7E,  0x29,  0x02,  0x3F,  0x14,  0x29,  0x08,  0x3F,  0x7F,  0x08,  0x0A,  0x3F,  0x0C, 	/* 2B550 */
+	0x08,  0x08,  0x0F,  0x08,  0x70,  0x98,  0x00,  0x80,  0x1F,  0xFC,  0x00,  0x80,  0x7F,  0xFF,  0x00,  0x00, 	/* 2B560 */
+	0x93,  0x02,  0x20,  0x7F,  0xFF,  0x02,  0x20,  0x0F,  0xF8,  0x08,  0x08,  0x0F,  0xF8,  0x08,  0x08,  0x0F, 	/* 2B570 */
+	0xF8,  0x01,  0x00,  0x7F,  0xFF,  0x02,  0xA0,  0x0F,  0xF8,  0x70,  0x87,  0x00,  0x80,  0x3F,  0xFE,  0x00, 	/* 2B580 */
+	0x00,  0x97,  0x01,  0x04,  0x10,  0x88,  0x13,  0xFE,  0x12,  0x22,  0x12,  0x22,  0x7F,  0xFE,  0x12,  0x22, 	/* 2B590 */
+	0x13,  0xFE,  0x10,  0x00,  0x11,  0xFC,  0x15,  0x04,  0x19,  0xFC,  0x61,  0x04,  0x01,  0x04,  0x01,  0xFC, 	/* 2B5A0 */
+	0x00,  0x00,  0x9C,  0x00,  0x84,  0x3C,  0x48,  0x27,  0xFF,  0x28,  0x40,  0x30,  0xAA,  0x2B,  0x5C,  0x24, 	/* 2B5B0 */
+	0xB8,  0x27,  0x54,  0x24,  0x92,  0x3B,  0x11,  0x20,  0x30,  0x20,  0x80,  0x0F,  0xF8,  0x00,  0x80,  0x7F, 	/* 2B5C0 */
+	0xFF,  0x00,  0x00,  0x9F,  0x10,  0x20,  0x10,  0x3E,  0x10,  0x20,  0x11,  0xFF,  0x11,  0x42,  0x7D,  0x48, 	/* 2B5D0 */
+	0x11,  0x70,  0x11,  0xC2,  0x11,  0x3E,  0x11,  0x00,  0x15,  0xAA,  0x1A,  0xAA,  0x62,  0xEE,  0x04,  0x28, 	/* 2B5E0 */
+	0x0B,  0xFF,  0x00,  0x00,  0xA8,  0x00,  0x00,  0x0F,  0xF8,  0x08,  0x88,  0x0F,  0xF8,  0x08,  0x88,  0x0F, 	/* 2B5F0 */
+	0xF8,  0x00,  0x80,  0x1F,  0xFC,  0x00,  0x80,  0x7F,  0xFE,  0x12,  0x24,  0x61,  0x92,  0x1F,  0xF8,  0x00, 	/* 2B600 */
+	0x80,  0x7F,  0xFF,  0x00,  0x00,  0xAB,  0x10,  0xBC,  0x10,  0x84,  0x11,  0xFC,  0x12,  0x52,  0x15,  0xFD, 	/* 2B610 */
+	0x7D,  0x54,  0x11,  0x9C,  0x11,  0xFC,  0x11,  0x04,  0x11,  0xFC,  0x14,  0x08,  0x1B,  0xFF,  0x60,  0x88, 	/* 2B620 */
+	0x00,  0x48,  0x00,  0x08,  0x00,  0x18,  0xAE,  0x00,  0x20,  0x3D,  0xFF,  0x24,  0x40,  0x28,  0xFE,  0x31, 	/* 2B630 */
+	0x10,  0x2A,  0xFF,  0x24,  0x44,  0x24,  0x7C,  0x24,  0x44,  0x38,  0x7C,  0x20,  0x4C,  0x20,  0x80,  0x0F, 	/* 2B640 */
+	0xF8,  0x00,  0x80,  0x7F,  0xFF,  0x00,  0x00,  0xB3,  0x00,  0x20,  0x13,  0xFE,  0x10,  0x20,  0x10,  0x88, 	/* 2B650 */
+	0x17,  0xFF,  0x7C,  0x88,  0x10,  0x00,  0x11,  0xFC,  0x11,  0x04,  0x11,  0xFC,  0x15,  0x04,  0x19,  0xFC, 	/* 2B660 */
+	0x61,  0x04,  0x01,  0xFC,  0x01,  0x8C,  0x06,  0x02,  0xB8,  0x10,  0x88,  0x10,  0x88,  0x17,  0xFF,  0x10, 	/* 2B670 */
+	0xA8,  0x10,  0x24,  0x7D,  0xFC,  0x10,  0x28,  0x17,  0xFF,  0x10,  0x28,  0x10,  0x44,  0x14,  0xFC,  0x19, 	/* 2B680 */
+	0x84,  0x66,  0xFC,  0x00,  0x84,  0x00,  0xFC,  0x00,  0x00,  0xB9,  0x10,  0x00,  0x13,  0xDE,  0x12,  0x52, 	/* 2B690 */
+	0x13,  0xDE,  0x12,  0x52,  0x7E,  0x52,  0x13,  0xDE,  0x12,  0x02,  0x12,  0xFA,  0x12,  0x8A,  0x16,  0xFA, 	/* 2B6A0 */
+	0x1A,  0x8A,  0x62,  0x8A,  0x02,  0xFA,  0x02,  0x02,  0x02,  0x06,  0xBA,  0x10,  0x20,  0x10,  0x40,  0x11, 	/* 2B6B0 */
+	0xFE,  0x11,  0x12,  0x11,  0xEA,  0x7D,  0xB2,  0x11,  0xFE,  0x11,  0x72,  0x11,  0xAA,  0x11,  0x26,  0x14, 	/* 2B6C0 */
+	0x20,  0x1B,  0xFF,  0x60,  0x30,  0x00,  0x48,  0x01,  0x84,  0x06,  0x03,  0xBB,  0x10,  0x20,  0x13,  0xFE, 	/* 2B6D0 */
+	0x11,  0x24,  0x11,  0x24,  0x11,  0xA6,  0x7D,  0x6A,  0x12,  0x30,  0x17,  0xFF,  0x10,  0x00,  0x11,  0xFE, 	/* 2B6E0 */
+	0x15,  0x7A,  0x19,  0x4A,  0x61,  0x7A,  0x01,  0x02,  0x01,  0xFE,  0x00,  0x00,  0xBE,  0x04,  0x00,  0x39, 	/* 2B6F0 */
+	0x7C,  0x26,  0x44,  0x1C,  0x7C,  0x76,  0x44,  0x09,  0x7E,  0x33,  0x52,  0x05,  0x54,  0x19,  0x48,  0x62, 	/* 2B700 */
+	0x74,  0x0C,  0xC3,  0x00,  0x80,  0x1F,  0xFC,  0x00,  0x80,  0x7F,  0xFF,  0x00,  0x00,  0x81,  0x00,  0x08, 	/* 2B710 */
+	0x1F,  0x08,  0x11,  0x7F,  0x11,  0x22,  0x1F,  0x14,  0x10,  0x7F,  0x2F,  0x08,  0x29,  0x7F,  0x49,  0x08, 	/* 2B720 */
+	0x0F,  0x08,  0x00,  0x88,  0x1F,  0xFC,  0x00,  0x80,  0x00,  0x80,  0x7F,  0xFF,  0x00,  0x00,  0x85,  0x00, 	/* 2B730 */
+	0x80,  0x7F,  0xFF,  0x08,  0x24,  0x0A,  0x48,  0x74,  0xFE,  0x15,  0x90,  0x08,  0xFE,  0x0E,  0x90,  0x72, 	/* 2B740 */
+	0xFE,  0x04,  0x90,  0x08,  0xFF,  0x30,  0x80,  0x1F,  0xFC,  0x00,  0x80,  0x7F,  0xFF,  0x00,  0x00,  0x87, 	/* 2B750 */
+	0x00,  0x20,  0x13,  0xFF,  0x10,  0x00,  0x11,  0xFE,  0x11,  0x7A,  0x7D,  0x4A,  0x11,  0x7A,  0x11,  0x02, 	/* 2B760 */
+	0x11,  0xFE,  0x10,  0x84,  0x14,  0xFC,  0x18,  0x84,  0x60,  0xFC,  0x00,  0x84,  0x07,  0xFF,  0x00,  0x00, 	/* 2B770 */
+	0x8A,  0x00,  0x20,  0x10,  0x20,  0x13,  0xFE,  0x10,  0x20,  0x11,  0xFC,  0x7F,  0x54,  0x11,  0x54,  0x11, 	/* 2B780 */
+	0xFC,  0x10,  0x20,  0x13,  0xFF,  0x14,  0x44,  0x18,  0xA8,  0x61,  0x90,  0x06,  0x88,  0x00,  0xE4,  0x03, 	/* 2B790 */
+	0x83,  0x8C,  0x00,  0x20,  0x10,  0x20,  0x13,  0xFF,  0x10,  0x48,  0x10,  0x84,  0x7F,  0x4B,  0x11,  0xFE, 	/* 2B7A0 */
+	0x10,  0x48,  0x11,  0xFE,  0x10,  0x48,  0x13,  0xFF,  0x1C,  0x62,  0x70,  0x94,  0x07,  0x88,  0x00,  0xE4, 	/* 2B7B0 */
+	0x03,  0x83,  0x91,  0x04,  0x00,  0x07,  0xFC,  0x04,  0x24,  0x7F,  0xA4,  0x44,  0xA4,  0x25,  0x14,  0x4A, 	/* 2B7C0 */
+	0x98,  0x11,  0x08,  0x7F,  0x94,  0x11,  0x22,  0x1F,  0x41,  0x00,  0x80,  0x1F,  0xFC,  0x00,  0x80,  0x7F, 	/* 2B7D0 */
+	0xFF,  0x00,  0x00,  0x93,  0x00,  0x00,  0x1F,  0xFF,  0x14,  0x8C,  0x17,  0x8A,  0x10,  0x7F,  0x17,  0x88, 	/* 2B7E0 */
+	0x14,  0x88,  0x17,  0x94,  0x14,  0x94,  0x27,  0xA2,  0x24,  0xC1,  0x40,  0x80,  0x0F,  0xFC,  0x00,  0x80, 	/* 2B7F0 */
+	0x7F,  0xFF,  0x00,  0x00,  0x95,  0x00,  0x20,  0x17,  0xFF,  0x10,  0x00,  0x11,  0xFC,  0x11,  0x04,  0x7D, 	/* 2B800 */
+	0xFC,  0x10,  0x00,  0x13,  0xFF,  0x12,  0x01,  0x12,  0xFD,  0x10,  0x22,  0x14,  0xD4,  0x1B,  0x38,  0x60, 	/* 2B810 */
+	0xD4,  0x07,  0x13,  0x00,  0x30,  0x97,  0x10,  0x20,  0x11,  0xFC,  0x10,  0x24,  0x17,  0xFF,  0x7C,  0x24, 	/* 2B820 */
+	0x11,  0xFC,  0x10,  0x20,  0x17,  0xFF,  0x12,  0x92,  0x12,  0x49,  0x1C,  0x00,  0x73,  0xFE,  0x02,  0x92, 	/* 2B830 */
+	0x02,  0x92,  0x0F,  0xFF,  0x00,  0x00,  0x98,  0x00,  0x00,  0x07,  0xF0,  0x04,  0x90,  0x07,  0xF0,  0x04, 	/* 2B840 */
+	0x90,  0x07,  0xF0,  0x3E,  0x3E,  0x2A,  0x2A,  0x3E,  0x3E,  0x2A,  0x2A,  0x3E,  0xBE,  0x00,  0x80,  0x1F, 	/* 2B850 */
+	0xFE,  0x00,  0x80,  0x7F,  0xFF,  0x00,  0x00,  0x99,  0x10,  0x10,  0x10,  0x10,  0x13,  0xFF,  0x12,  0x48, 	/* 2B860 */
+	0x7E,  0xFE,  0x12,  0x48,  0x12,  0x78,  0x13,  0xFF,  0x12,  0x10,  0x16,  0xFE,  0x1A,  0x92,  0x64,  0xFE, 	/* 2B870 */
+	0x04,  0x92,  0x08,  0xFE,  0x10,  0xC6,  0x07,  0x01,  0x9C,  0x11,  0xFC,  0x11,  0x04,  0x11,  0xFC,  0x11, 	/* 2B880 */
+	0x04,  0x13,  0xFE,  0x7C,  0x20,  0x17,  0xFF,  0x14,  0x21,  0x15,  0xAD,  0x10,  0x20,  0x1D,  0xFC,  0x60, 	/* 2B890 */
+	0x00,  0x07,  0xFF,  0x00,  0x58,  0x00,  0x8C,  0x03,  0xF2,  0x9E,  0x10,  0x10,  0x13,  0xFF,  0x10,  0x00, 	/* 2B8A0 */
+	0x11,  0xFE,  0x7D,  0x4A,  0x11,  0xFE,  0x10,  0x00,  0x13,  0xAE,  0x10,  0x20,  0x13,  0xBE,  0x1C,  0x52, 	/* 2B8B0 */
+	0x70,  0x8C,  0x07,  0x88,  0x00,  0x84,  0x00,  0xF2,  0x03,  0x01,  0x9F,  0x04,  0x20,  0x3F,  0xBF,  0x11, 	/* 2B8C0 */
+	0x20,  0x7F,  0xFE,  0x00,  0x02,  0x1F,  0x3E,  0x11,  0x20,  0x1F,  0x3E,  0x11,  0x3E,  0x1F,  0x21,  0x11, 	/* 2B8D0 */
+	0x9F,  0x00,  0x80,  0x1F,  0xF8,  0x00,  0x80,  0x7F,  0xFF,  0x00,  0x00,  0xA4,  0x00,  0x20,  0x13,  0xFF, 	/* 2B8E0 */
+	0x10,  0x00,  0x11,  0xCE,  0x11,  0x4A,  0x7D,  0xCE,  0x10,  0x48,  0x11,  0xFE,  0x10,  0x48,  0x11,  0xFE, 	/* 2B8F0 */
+	0x14,  0x48,  0x1B,  0xFF,  0x60,  0x51,  0x03,  0x8A,  0x00,  0xE4,  0x01,  0x83,  0xA5,  0x10,  0x00,  0x13, 	/* 2B900 */
+	0xFE,  0x12,  0x00,  0x12,  0xFC,  0x7E,  0xAC,  0x12,  0xF4,  0x12,  0xA4,  0x13,  0xFE,  0x12,  0x20,  0x17, 	/* 2B910 */
+	0xFF,  0x1A,  0xCA,  0x65,  0x25,  0x05,  0xFC,  0x08,  0x20,  0x07,  0xFF,  0x00,  0x00,  0xAB,  0x00,  0x80, 	/* 2B920 */
+	0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x7F,  0xFF,  0x00,  0x80,  0x00,  0x80, 	/* 2B930 */
+	0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x3F,  0xFE,  0x00,  0x00,  0xAC,  0x00, 	/* 2B940 */
+	0x04,  0x00,  0x18,  0x00,  0xE0,  0x1F,  0x80,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x7F, 	/* 2B950 */
+	0xFF,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x1F,  0xFC,  0x00,  0x00,  0xAE, 	/* 2B960 */
+	0x04,  0x20,  0x04,  0x10,  0x04,  0x10,  0x24,  0x10,  0x24,  0x10,  0x17,  0xFF,  0x14,  0x10,  0x04,  0x10, 	/* 2B970 */
+	0x0C,  0x10,  0x14,  0x10,  0x14,  0x10,  0x24,  0x10,  0x44,  0x10,  0x05,  0xFE,  0x04,  0x00,  0x04,  0x00, 	/* 2B980 */
+	0xAF,  0x02,  0x10,  0x12,  0x10,  0x12,  0x10,  0x12,  0x10,  0x12,  0x10,  0x1F,  0xFF,  0x02,  0x10,  0x02, 	/* 2B990 */
+	0x10,  0x3E,  0x10,  0x12,  0x10,  0x12,  0x10,  0x12,  0x10,  0x22,  0x10,  0x22,  0x10,  0x42,  0xFE,  0x02, 	/* 2B9A0 */
+	0x00,  0xB0,  0x00,  0x80,  0x00,  0x80,  0x7F,  0xFF,  0x00,  0x80,  0x00,  0x80,  0x3F,  0xFE,  0x00,  0x00, 	/* 2B9B0 */
+	0x1F,  0xFC,  0x10,  0x84,  0x10,  0x84,  0x1F,  0xFC,  0x10,  0x00,  0x10,  0x00,  0x20,  0x00,  0x20,  0x00, 	/* 2B9C0 */
+	0x40,  0x00,  0xB1,  0x01,  0x00,  0x01,  0x00,  0x7F,  0xFE,  0x01,  0x00,  0x01,  0x00,  0x1F,  0xF8,  0x00, 	/* 2B9D0 */
+	0x00,  0x7F,  0xFE,  0x40,  0x02,  0x48,  0x22,  0x08,  0xC0,  0x0F,  0x00,  0x08,  0x00,  0x08,  0x08,  0x04, 	/* 2B9E0 */
+	0x08,  0x03,  0xF8,  0xB2,  0x00,  0x80,  0x00,  0x80,  0x7F,  0xFF,  0x00,  0x80,  0x00,  0x80,  0x1F,  0xFC, 	/* 2B9F0 */
+	0x00,  0x00,  0x7F,  0xFF,  0x40,  0x01,  0x42,  0x21,  0x02,  0x20,  0x02,  0x20,  0x04,  0x20,  0x08,  0x21, 	/* 2BA00 */
+	0x10,  0x21,  0x60,  0x1F,  0xB7,  0x01,  0x00,  0x01,  0x00,  0x7F,  0xFE,  0x01,  0x00,  0x1F,  0xF8,  0x00, 	/* 2BA10 */
+	0x00,  0x7F,  0xFE,  0x42,  0x42,  0x5F,  0xFA,  0x12,  0x48,  0x12,  0x48,  0x1F,  0xF8,  0x02,  0x40,  0x02, 	/* 2BA20 */
+	0x40,  0x7F,  0xFE,  0x00,  0x00,  0xB9,  0x00,  0x80,  0x7F,  0xFE,  0x00,  0x80,  0x1F,  0xF8,  0x00,  0x00, 	/* 2BA30 */
+	0x7F,  0xFE,  0x40,  0x02,  0x5F,  0xFA,  0x00,  0x00,  0x0F,  0xF0,  0x08,  0x10,  0x0F,  0xF0,  0x04,  0x20, 	/* 2BA40 */
+	0x02,  0x40,  0x7F,  0xFE,  0x00,  0x00,  0xBA,  0x00,  0x80,  0x00,  0x80,  0x7F,  0xFE,  0x00,  0x80,  0x1F, 	/* 2BA50 */
+	0xF8,  0x00,  0x00,  0x7F,  0xFE,  0x42,  0x42,  0x5E,  0x7A,  0x10,  0x08,  0x10,  0x08,  0x1E,  0x78,  0x02, 	/* 2BA60 */
+	0x40,  0x02,  0x40,  0x7F,  0xFE,  0x00,  0x00,  0xBB,  0x00,  0x00,  0x13,  0xFF,  0x10,  0x12,  0x10,  0x90, 	/* 2BA70 */
+	0x10,  0x9E,  0x7D,  0x70,  0x12,  0x1F,  0x14,  0x00,  0x11,  0xFC,  0x11,  0x04,  0x11,  0xFC,  0x1D,  0x04, 	/* 2BA80 */
+	0x71,  0xFC,  0x01,  0x04,  0x01,  0x04,  0x01,  0x0C,  0xBC,  0x00,  0x80,  0x7F,  0xFE,  0x00,  0x80,  0x1F, 	/* 2BA90 */
+	0xF8,  0x00,  0x00,  0x7F,  0xFE,  0x40,  0x02,  0x5F,  0xFA,  0x02,  0x40,  0x1E,  0x78,  0x10,  0x08,  0x10, 	/* 2BAA0 */
+	0x08,  0x1E,  0x78,  0x02,  0x40,  0x7F,  0xFF,  0x00,  0x00,  0xBD,  0x00,  0x80,  0x3F,  0xFE,  0x00,  0x80, 	/* 2BAB0 */
+	0x0F,  0xF8,  0x00,  0x00,  0x7F,  0xFE,  0x00,  0x02,  0x0F,  0xF2,  0x00,  0x80,  0x7F,  0xFF,  0x00,  0x08, 	/* 2BAC0 */
+	0x1F,  0xFF,  0x12,  0x88,  0x12,  0x48,  0x1E,  0x08,  0x00,  0x18,  0x82,  0x02,  0x00,  0x02,  0x00,  0x02, 	/* 2BAD0 */
+	0x00,  0x07,  0xF0,  0x04,  0x10,  0x0A,  0x10,  0x0A,  0x20,  0x11,  0x20,  0x21,  0x40,  0x00,  0x80,  0x00, 	/* 2BAE0 */
+	0x80,  0x01,  0x40,  0x02,  0x20,  0x04,  0x10,  0x18,  0x0C,  0x60,  0x03,  0x89,  0x00,  0x80,  0x00,  0x80, 	/* 2BAF0 */
+	0x7F,  0xFF,  0x02,  0x20,  0x12,  0x28,  0x12,  0x24,  0x12,  0x24,  0x24,  0x62,  0x4A,  0x02,  0x03,  0xF0, 	/* 2BB00 */
+	0x04,  0x20,  0x0A,  0x40,  0x31,  0x80,  0x01,  0xC0,  0x0E,  0x30,  0x70,  0x0F,  0x8A,  0x02,  0x00,  0x12, 	/* 2BB10 */
+	0x00,  0x12,  0x00,  0x0B,  0xF0,  0x0A,  0x10,  0x04,  0x10,  0x0C,  0x20,  0x12,  0x20,  0x22,  0x40,  0x01, 	/* 2BB20 */
+	0x80,  0x00,  0x80,  0x01,  0x40,  0x02,  0x20,  0x04,  0x10,  0x18,  0x0C,  0x60,  0x03,  0x8F,  0x00,  0x00, 	/* 2BB30 */
+	0x3F,  0xFE,  0x00,  0x80,  0x0F,  0xF8,  0x08,  0x08,  0x0F,  0xF8,  0x08,  0x08,  0x0F,  0xF8,  0x08,  0x08, 	/* 2BB40 */
+	0x0F,  0xF8,  0x02,  0x00,  0x07,  0xF8,  0x0A,  0x20,  0x31,  0xC0,  0x06,  0x70,  0x78,  0x0E,  0x90,  0x02, 	/* 2BB50 */
+	0x00,  0x07,  0xE0,  0x18,  0x40,  0x7F,  0xFE,  0x20,  0xC2,  0x23,  0x22,  0x0F,  0xF8,  0x08,  0x08,  0x0F, 	/* 2BB60 */
+	0xF8,  0x08,  0x08,  0x0F,  0xF8,  0x00,  0x80,  0x03,  0xF8,  0x3D,  0x10,  0x01,  0xE0,  0x7E,  0x1F,  0x95, 	/* 2BB70 */
+	0x01,  0x00,  0x01,  0x00,  0x01,  0xFC,  0x01,  0x04,  0x02,  0x04,  0x02,  0x04,  0x04,  0x08,  0x0A,  0x08, 	/* 2BB80 */
+	0x11,  0x90,  0x00,  0x50,  0x00,  0x20,  0x00,  0x40,  0x00,  0x80,  0x03,  0x00,  0x0C,  0x00,  0x30,  0x00, 	/* 2BB90 */
+	0x96,  0x04,  0x20,  0x04,  0x20,  0x07,  0xA0,  0x08,  0xA0,  0x08,  0xA0,  0x10,  0xA0,  0x19,  0x30,  0x25, 	/* 2BBA0 */
+	0x2C,  0x43,  0x22,  0x02,  0x21,  0x02,  0x20,  0x04,  0x20,  0x04,  0x20,  0x08,  0x20,  0x10,  0x20,  0x20, 	/* 2BBB0 */
+	0x20,  0x98,  0x04,  0x00,  0x04,  0x3E,  0x07,  0xA2,  0x08,  0xA2,  0x08,  0xA2,  0x10,  0xA2,  0x19,  0x22, 	/* 2BBC0 */
+	0x25,  0x22,  0x43,  0x22,  0x02,  0x22,  0x02,  0x22,  0x04,  0x22,  0x04,  0x2C,  0x08,  0x20,  0x10,  0x20, 	/* 2BBD0 */
+	0x20,  0x20,  0x99,  0x00,  0x00,  0x1F,  0xF8,  0x10,  0x08,  0x10,  0x08,  0x1F,  0xF8,  0x11,  0x08,  0x11, 	/* 2BBE0 */
+	0xE8,  0x11,  0x28,  0x12,  0x28,  0x13,  0x28,  0x14,  0xC8,  0x18,  0x48,  0x10,  0x85,  0x21,  0x05,  0x22, 	/* 2BBF0 */
+	0x03,  0x44,  0x01,  0x9A,  0x01,  0x00,  0x01,  0xF0,  0x02,  0x10,  0x04,  0x20,  0x0A,  0x40,  0x31,  0x80, 	/* 2BC00 */
+	0x01,  0x20,  0x02,  0x3E,  0x0C,  0x42,  0x30,  0x84,  0x03,  0x48,  0x0C,  0x30,  0x00,  0x20,  0x00,  0xC0, 	/* 2BC10 */
+	0x03,  0x00,  0x3C,  0x00,  0x9B,  0x00,  0x00,  0x0F,  0xF0,  0x00,  0x10,  0x0F,  0xF0,  0x00,  0x10,  0x00, 	/* 2BC20 */
+	0x10,  0x7F,  0xFF,  0x01,  0x00,  0x03,  0xF8,  0x0C,  0x08,  0x33,  0x10,  0x00,  0xA0,  0x00,  0x40,  0x01, 	/* 2BC30 */
+	0x80,  0x06,  0x00,  0x38,  0x00,  0x9C,  0x00,  0x80,  0x00,  0x80,  0x7F,  0xFF,  0x02,  0x40,  0x02,  0x40, 	/* 2BC40 */
+	0x04,  0x7C,  0x04,  0x44,  0x08,  0xC4,  0x18,  0xA8,  0x29,  0x98,  0x4A,  0x50,  0x08,  0x20,  0x08,  0x20, 	/* 2BC50 */
+	0x08,  0x50,  0x09,  0x8C,  0x0E,  0x03,  0xA2,  0x04,  0x20,  0x04,  0x20,  0x7F,  0xFE,  0x04,  0x20,  0x1F, 	/* 2BC60 */
+	0xF8,  0x12,  0x48,  0x1F,  0xF8,  0x00,  0x00,  0x7F,  0xFE,  0x41,  0x02,  0x43,  0xF2,  0x0E,  0x20,  0x31, 	/* 2BC70 */
+	0x40,  0x01,  0x80,  0x06,  0x00,  0x38,  0x00,  0xA5,  0x00,  0x08,  0x3F,  0x8E,  0x24,  0x92,  0x24,  0xA4, 	/* 2BC80 */
+	0x3F,  0xD4,  0x24,  0x88,  0x24,  0x90,  0x3F,  0xA4,  0x04,  0x47,  0x7F,  0xC9,  0x0E,  0x12,  0x0D,  0x2A, 	/* 2BC90 */
+	0x14,  0x84,  0x24,  0x88,  0x44,  0x10,  0x04,  0x60,  0xA7,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x00, 	/* 2BCA0 */
+	0x80,  0x00,  0x80,  0x7F,  0xFF,  0x00,  0x80,  0x00,  0x80,  0x01,  0x40,  0x01,  0x40,  0x02,  0x20,  0x02, 	/* 2BCB0 */
+	0x20,  0x04,  0x10,  0x08,  0x08,  0x10,  0x04,  0x60,  0x03,  0xA9,  0x00,  0x00,  0x7F,  0xFF,  0x00,  0x80, 	/* 2BCC0 */
+	0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x3F,  0xFC,  0x00,  0x80,  0x00,  0x80,  0x01,  0x40,  0x01,  0x40, 	/* 2BCD0 */
+	0x02,  0x20,  0x04,  0x10,  0x08,  0x08,  0x10,  0x04,  0x60,  0x03,  0xAA,  0x00,  0x80,  0x00,  0x80,  0x00, 	/* 2BCE0 */
+	0x80,  0x00,  0x80,  0x00,  0x80,  0x7F,  0xFF,  0x01,  0x40,  0x01,  0x40,  0x01,  0x20,  0x02,  0x20,  0x02, 	/* 2BCF0 */
+	0x10,  0x05,  0x10,  0x04,  0x88,  0x08,  0x44,  0x10,  0x42,  0x60,  0x01,  0xAB,  0x00,  0x80,  0x00,  0x80, 	/* 2BD00 */
+	0x00,  0x80,  0x00,  0x80,  0x1F,  0xFC,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x7F,  0xFF,  0x00,  0x80, 	/* 2BD10 */
+	0x01,  0x40,  0x01,  0x40,  0x02,  0x20,  0x04,  0x10,  0x18,  0x0C,  0x60,  0x03,  0xAC,  0x00,  0x80,  0x00, 	/* 2BD20 */
+	0x80,  0x00,  0x80,  0x1F,  0xF8,  0x00,  0x88,  0x00,  0x88,  0x00,  0x88,  0x00,  0x88,  0x7F,  0xFF,  0x00, 	/* 2BD30 */
+	0x80,  0x00,  0xC0,  0x01,  0x40,  0x02,  0x20,  0x04,  0x10,  0x18,  0x0C,  0x60,  0x03,  0xAD,  0x00,  0x10, 	/* 2BD40 */
+	0x00,  0x60,  0x1F,  0x80,  0x01,  0x00,  0x01,  0x00,  0x01,  0x00,  0x01,  0x00,  0x7F,  0xFE,  0x01,  0x80, 	/* 2BD50 */
+	0x01,  0x80,  0x01,  0x40,  0x02,  0x40,  0x02,  0x20,  0x04,  0x10,  0x18,  0x0C,  0x60,  0x03,  0xAE,  0x00, 	/* 2BD60 */
+	0x80,  0x00,  0x80,  0x00,  0x80,  0x1F,  0xFC,  0x10,  0x84,  0x10,  0x84,  0x10,  0x84,  0x10,  0x84,  0x7F, 	/* 2BD70 */
+	0xFF,  0x00,  0x80,  0x01,  0x40,  0x01,  0x40,  0x02,  0x20,  0x04,  0x10,  0x18,  0x0C,  0x60,  0x03,  0xB1, 	/* 2BD80 */
+	0x00,  0x80,  0x08,  0x80,  0x08,  0x80,  0x08,  0x80,  0x0F,  0xFC,  0x10,  0x80,  0x10,  0x80,  0x20,  0x80, 	/* 2BD90 */
+	0x7F,  0xFF,  0x00,  0x80,  0x01,  0x40,  0x01,  0x40,  0x02,  0x20,  0x04,  0x10,  0x18,  0x0C,  0x60,  0x03, 	/* 2BDA0 */
+	0xB2,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x7F,  0xFF,  0x00,  0x80,  0x01,  0x40,  0x02,  0x20,  0x04, 	/* 2BDB0 */
+	0x10,  0x18,  0x8C,  0x60,  0x83,  0x00,  0x80,  0x3F,  0xFE,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x00, 	/* 2BDC0 */
+	0x80,  0xB7,  0x00,  0x80,  0x00,  0x80,  0x7F,  0xFF,  0x00,  0x80,  0x3F,  0xFC,  0x00,  0x84,  0x1F,  0xFC, 	/* 2BDD0 */
+	0x10,  0x80,  0x10,  0x80,  0x1F,  0xFE,  0x01,  0x42,  0x01,  0x42,  0x02,  0x2C,  0x04,  0x10,  0x18,  0x0C, 	/* 2BDE0 */
+	0x60,  0x03,  0xB8,  0x00,  0x80,  0x00,  0x80,  0x7F,  0xFF,  0x01,  0x40,  0x02,  0x20,  0x04,  0x10,  0x1B, 	/* 2BDF0 */
+	0xEC,  0x60,  0x03,  0x00,  0x00,  0x1F,  0xFC,  0x02,  0x00,  0x07,  0xF0,  0x04,  0x10,  0x00,  0x10,  0x00, 	/* 2BE00 */
+	0x10,  0x00,  0x60,  0xBE,  0x00,  0x80,  0x00,  0x80,  0x7F,  0xFF,  0x00,  0x80,  0x08,  0x88,  0x08,  0x88, 	/* 2BE10 */
+	0x08,  0x88,  0x14,  0x94,  0x12,  0x94,  0x20,  0xA2,  0x41,  0x41,  0x01,  0x40,  0x02,  0x20,  0x04,  0x10, 	/* 2BE20 */
+	0x18,  0x0C,  0x60,  0x03,  0x84,  0x00,  0x80,  0x00,  0x80,  0x7F,  0xFF,  0x01,  0x40,  0x02,  0x20,  0x04, 	/* 2BE30 */
+	0x90,  0x1F,  0xFC,  0x68,  0x93,  0x08,  0x90,  0x0F,  0xF0,  0x08,  0x90,  0x08,  0x90,  0x0F,  0xF0,  0x00, 	/* 2BE40 */
+	0x82,  0x00,  0x82,  0x00,  0x7E,  0x87,  0x00,  0x80,  0x00,  0x80,  0x3F,  0xFE,  0x01,  0x40,  0x02,  0x20, 	/* 2BE50 */
+	0x0C,  0x18,  0x00,  0x00,  0x7F,  0xFF,  0x00,  0x08,  0x0F,  0xC8,  0x08,  0x48,  0x08,  0x48,  0x0F,  0xC8, 	/* 2BE60 */
+	0x00,  0x08,  0x00,  0x08,  0x00,  0x18,  0x88,  0x00,  0x80,  0x00,  0x80,  0x3F,  0xFE,  0x01,  0x40,  0x02, 	/* 2BE70 */
+	0x20,  0x04,  0x10,  0x1B,  0xEC,  0x60,  0x03,  0x00,  0x00,  0x3F,  0xFE,  0x00,  0x80,  0x02,  0xA0,  0x04, 	/* 2BE80 */
+	0x98,  0x18,  0x84,  0x60,  0x82,  0x01,  0x80,  0x89,  0x00,  0x80,  0x00,  0x80,  0x1F,  0xFC,  0x00,  0x80, 	/* 2BE90 */
+	0x0F,  0xF8,  0x01,  0x40,  0x7F,  0xFF,  0x02,  0x20,  0x04,  0x90,  0x18,  0x8C,  0x67,  0xF3,  0x00,  0x80, 	/* 2BEA0 */
+	0x1F,  0xFC,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x8E,  0x00,  0x80,  0x00,  0x80,  0x7F,  0xFF,  0x01, 	/* 2BEB0 */
+	0x40,  0x02,  0xA0,  0x0C,  0x98,  0x77,  0xF7,  0x00,  0x80,  0x00,  0x80,  0x7F,  0xFF,  0x00,  0x80,  0x1F, 	/* 2BEC0 */
+	0xFC,  0x00,  0x80,  0x00,  0x80,  0x7F,  0xFF,  0x00,  0x00,  0x8F,  0x00,  0x80,  0x00,  0x80,  0x3F,  0xFE, 	/* 2BED0 */
+	0x00,  0x80,  0x1F,  0xFC,  0x01,  0x40,  0x7F,  0xFF,  0x02,  0x20,  0x04,  0x10,  0x1B,  0xEC,  0x60,  0x83, 	/* 2BEE0 */
+	0x1F,  0xFC,  0x01,  0x40,  0x02,  0x20,  0x0C,  0x18,  0x30,  0x06,  0x90,  0x02,  0x00,  0x03,  0xE0,  0x04, 	/* 2BEF0 */
+	0x40,  0x18,  0x80,  0x7F,  0xFC,  0x11,  0x44,  0x11,  0x44,  0x12,  0x44,  0x14,  0x3C,  0x10,  0x84,  0x00, 	/* 2BF00 */
+	0x80,  0x7F,  0xFF,  0x01,  0x40,  0x02,  0x20,  0x0C,  0x18,  0x70,  0x07,  0x91,  0x04,  0x00,  0x04,  0x00, 	/* 2BF10 */
+	0x3F,  0xBE,  0x04,  0x12,  0x3F,  0x92,  0x04,  0x12,  0x05,  0xA2,  0x0E,  0x22,  0x70,  0x4C,  0x00,  0x80, 	/* 2BF20 */
+	0x00,  0x80,  0x7F,  0xFF,  0x01,  0x40,  0x02,  0x20,  0x0C,  0x18,  0x70,  0x06,  0x94,  0x00,  0x80,  0x00, 	/* 2BF30 */
+	0x80,  0x7F,  0xFF,  0x01,  0x40,  0x02,  0x20,  0x04,  0x90,  0x18,  0x8C,  0x67,  0xFB,  0x00,  0x80,  0x04, 	/* 2BF40 */
+	0x90,  0x04,  0x90,  0x7F,  0xFF,  0x04,  0x10,  0x08,  0x10,  0x08,  0x10,  0x10,  0x10,  0x95,  0x00,  0x80, 	/* 2BF50 */
+	0x00,  0x80,  0x7F,  0xFF,  0x01,  0x20,  0x09,  0x28,  0x09,  0x24,  0x09,  0x22,  0x12,  0x22,  0x24,  0x60, 	/* 2BF60 */
+	0x00,  0x80,  0x00,  0x80,  0x7F,  0xFF,  0x01,  0x40,  0x02,  0x20,  0x0C,  0x18,  0x70,  0x07,  0x97,  0x00, 	/* 2BF70 */
+	0x80,  0x00,  0x80,  0x7F,  0xFF,  0x01,  0x40,  0x02,  0x20,  0x0F,  0xF8,  0x72,  0x07,  0x03,  0xF0,  0x02, 	/* 2BF80 */
+	0x00,  0x03,  0xF0,  0x02,  0x00,  0x7F,  0xFF,  0x02,  0x20,  0x02,  0x18,  0x04,  0xF4,  0x3F,  0x02,  0x98, 	/* 2BF90 */
+	0x24,  0x20,  0x24,  0x20,  0x24,  0x20,  0x3F,  0xFF,  0x04,  0x20,  0x7C,  0x20,  0x14,  0x20,  0x15,  0xFE, 	/* 2BFA0 */
+	0x24,  0x00,  0x44,  0x80,  0x00,  0x80,  0x7F,  0xFF,  0x01,  0x40,  0x02,  0x20,  0x0C,  0x18,  0x70,  0x07, 	/* 2BFB0 */
+	0x9A,  0x00,  0x04,  0x00,  0x38,  0x3F,  0xC8,  0x08,  0x44,  0x09,  0x22,  0x11,  0x02,  0x2E,  0x20,  0x42, 	/* 2BFC0 */
+	0x48,  0x01,  0x84,  0x1F,  0xFA,  0x00,  0x80,  0x7F,  0xFF,  0x01,  0x40,  0x02,  0x20,  0x0C,  0x18,  0x70, 	/* 2BFD0 */
+	0x07,  0xA0,  0x0B,  0xF8,  0x08,  0x08,  0x0F,  0xF8,  0x11,  0x24,  0x2F,  0xFE,  0x49,  0x2D,  0x0A,  0x1C, 	/* 2BFE0 */
+	0x0C,  0x04,  0x0F,  0xFC,  0x08,  0x04,  0x0F,  0xFC,  0x00,  0x80,  0x7F,  0xFF,  0x01,  0x20,  0x06,  0x18, 	/* 2BFF0 */
+	0x78,  0x07,  0xA2,  0x00,  0x80,  0x00,  0x80,  0x7F,  0xFF,  0x02,  0x20,  0x04,  0x90,  0x1F,  0xFC,  0x60, 	/* 2C000 */
+	0x93,  0x00,  0xA0,  0x7F,  0xFF,  0x01,  0x10,  0x07,  0xF8,  0x1C,  0x08,  0x67,  0xF8,  0x04,  0x08,  0x07, 	/* 2C010 */
+	0xF8,  0x00,  0x00,  0xA5,  0x01,  0x00,  0x02,  0x00,  0x1F,  0xFC,  0x10,  0x84,  0x14,  0x94,  0x12,  0xA4, 	/* 2C020 */
+	0x1F,  0xFC,  0x11,  0xC4,  0x12,  0xA4,  0x14,  0x9C,  0x18,  0x84,  0x11,  0x04,  0x7F,  0xFF,  0x01,  0x40, 	/* 2C030 */
+	0x06,  0x30,  0x78,  0x0E,  0xA7,  0x00,  0x80,  0x01,  0x00,  0x1F,  0xFC,  0x10,  0x24,  0x13,  0xC4,  0x14, 	/* 2C040 */
+	0x94,  0x12,  0xA4,  0x1F,  0xFC,  0x11,  0xC4,  0x12,  0xA4,  0x14,  0x94,  0x00,  0x80,  0x7F,  0xFF,  0x01, 	/* 2C050 */
+	0x40,  0x06,  0x30,  0x78,  0x0F,  0xA8,  0x04,  0x0C,  0x25,  0xF2,  0x15,  0x22,  0x14,  0xA4,  0x04,  0x88, 	/* 2C060 */
+	0x0F,  0xFF,  0x14,  0x44,  0x64,  0x24,  0x04,  0x24,  0x04,  0x8C,  0x00,  0x80,  0x7F,  0xFF,  0x01,  0x40, 	/* 2C070 */
+	0x02,  0x20,  0x0C,  0x18,  0x70,  0x07,  0xA9,  0x00,  0x80,  0x00,  0x80,  0x7F,  0xFF,  0x01,  0x40,  0x06, 	/* 2C080 */
+	0x30,  0x1F,  0xFC,  0x70,  0x03,  0x11,  0xF0,  0x11,  0x10,  0x11,  0xF0,  0x17,  0xBC,  0x14,  0xA4,  0x17, 	/* 2C090 */
+	0xBC,  0x10,  0x00,  0x1F,  0xFE,  0x00,  0x00,  0xAA,  0x00,  0x80,  0x7F,  0xFF,  0x01,  0x40,  0x06,  0x30, 	/* 2C0A0 */
+	0x1A,  0x4C,  0x67,  0xFB,  0x0C,  0x40,  0x37,  0xF8,  0x04,  0x40,  0x07,  0xF8,  0x00,  0x10,  0x7F,  0xFF, 	/* 2C0B0 */
+	0x04,  0x10,  0x02,  0x10,  0x02,  0x10,  0x00,  0x30,  0xAC,  0x24,  0x10,  0x24,  0x3E,  0x25,  0xCA,  0x3C, 	/* 2C0C0 */
+	0x2C,  0x05,  0xF0,  0x7C,  0x04,  0x25,  0xFF,  0x24,  0x44,  0x24,  0x24,  0x44,  0x8C,  0x00,  0x80,  0x7F, 	/* 2C0D0 */
+	0xFF,  0x01,  0x40,  0x02,  0x20,  0x0C,  0x18,  0x70,  0x07,  0xAE,  0x00,  0x80,  0x7F,  0xFF,  0x02,  0x20, 	/* 2C0E0 */
+	0x0D,  0x58,  0x77,  0xF7,  0x0C,  0x40,  0x17,  0xF0,  0x04,  0x40,  0x07,  0xFC,  0x04,  0x00,  0x1F,  0xFC, 	/* 2C0F0 */
+	0x10,  0x84,  0x1F,  0xFC,  0x10,  0x84,  0x1F,  0xFC,  0x10,  0x04,  0xB3,  0x01,  0x00,  0x01,  0x00,  0x01, 	/* 2C100 */
+	0x00,  0x01,  0x00,  0xFF,  0xFF,  0x02,  0x10,  0x02,  0x10,  0x02,  0x10,  0x04,  0x20,  0x04,  0x20,  0x1F, 	/* 2C110 */
+	0x40,  0x10,  0xC0,  0x01,  0x20,  0x02,  0x10,  0x0C,  0x08,  0x30,  0x04,  0xB4,  0x08,  0x00,  0x08,  0x00, 	/* 2C120 */
+	0x08,  0xFC,  0x08,  0x04,  0x7F,  0x44,  0x09,  0x44,  0x09,  0x44,  0x11,  0x44,  0x12,  0x28,  0x22,  0x28, 	/* 2C130 */
+	0x7C,  0x18,  0x06,  0x10,  0x0A,  0x28,  0x10,  0x44,  0x60,  0x82,  0x03,  0x01,  0xB8,  0x08,  0x00,  0x08, 	/* 2C140 */
+	0xFE,  0x08,  0x10,  0x08,  0x10,  0x7F,  0x10,  0x11,  0x10,  0x11,  0x10,  0x11,  0xFF,  0x22,  0x10,  0x7A, 	/* 2C150 */
+	0x10,  0x46,  0x10,  0x05,  0x10,  0x09,  0x10,  0x10,  0x10,  0x60,  0x10,  0x00,  0x10,  0xBD,  0x08,  0x00, 	/* 2C160 */
+	0x08,  0x7E,  0x08,  0x02,  0x08,  0x04,  0x7F,  0x08,  0x12,  0x08,  0x12,  0x10,  0x13,  0xFF,  0x12,  0x10, 	/* 2C170 */
+	0x22,  0x10,  0x3C,  0x10,  0x26,  0x10,  0x09,  0x10,  0x10,  0x10,  0x60,  0x10,  0x00,  0x30,  0x81,  0x08, 	/* 2C180 */
+	0x40,  0x08,  0x40,  0x08,  0x40,  0x08,  0x7E,  0x7E,  0x42,  0x12,  0x82,  0x12,  0x82,  0x13,  0x42,  0x22, 	/* 2C190 */
+	0x22,  0x22,  0x22,  0x7C,  0x22,  0x46,  0x02,  0x05,  0x02,  0x18,  0x82,  0x60,  0x04,  0x00,  0x18,  0x82, 	/* 2C1A0 */
+	0x08,  0x00,  0x08,  0x00,  0x08,  0x00,  0x08,  0x7E,  0x7F,  0x42,  0x12,  0x42,  0x12,  0x42,  0x12,  0x42, 	/* 2C1B0 */
+	0x22,  0x42,  0x24,  0x42,  0x7C,  0x42,  0x44,  0x42,  0x0A,  0x7E,  0x11,  0x00,  0x60,  0x00,  0x00,  0x00, 	/* 2C1C0 */
+	0x83,  0x08,  0x00,  0x08,  0xFC,  0x08,  0x04,  0x08,  0x04,  0x7E,  0x04,  0x12,  0x04,  0x12,  0xFC,  0x12, 	/* 2C1D0 */
+	0x80,  0x22,  0x80,  0x24,  0x80,  0x7C,  0x80,  0x46,  0x80,  0x0A,  0x82,  0x10,  0x42,  0x60,  0x3E,  0x00, 	/* 2C1E0 */
+	0x00,  0x84,  0x00,  0x80,  0x00,  0x80,  0x7F,  0xFF,  0x08,  0x00,  0x08,  0x00,  0x08,  0x00,  0x07,  0xFC, 	/* 2C1F0 */
+	0x01,  0x00,  0x01,  0x00,  0x7F,  0xFF,  0x02,  0x10,  0x04,  0x10,  0x0F,  0xA0,  0x00,  0xE0,  0x03,  0x18, 	/* 2C200 */
+	0x3C,  0x04,  0x8A,  0x08,  0x04,  0x08,  0x18,  0x08,  0xF0,  0x08,  0x10,  0x7F,  0x10,  0x12,  0x10,  0x12, 	/* 2C210 */
+	0x10,  0x13,  0xFF,  0x22,  0x10,  0x24,  0x10,  0x7C,  0x10,  0x46,  0x10,  0x0A,  0x10,  0x10,  0x10,  0x60, 	/* 2C220 */
+	0xFE,  0x00,  0x00,  0x8D,  0x08,  0x00,  0x08,  0xFF,  0x08,  0x24,  0x08,  0x24,  0x7E,  0x24,  0x12,  0x24, 	/* 2C230 */
+	0x13,  0xFF,  0x12,  0x24,  0x22,  0x24,  0x24,  0x24,  0x7C,  0x24,  0x46,  0x24,  0x0A,  0x44,  0x11,  0x44, 	/* 2C240 */
+	0x60,  0x84,  0x01,  0x04,  0x93,  0x08,  0x10,  0x08,  0x10,  0x09,  0xFF,  0x08,  0x10,  0x7F,  0x10,  0x12, 	/* 2C250 */
+	0x10,  0x12,  0xFC,  0x12,  0x44,  0x22,  0x44,  0x24,  0x28,  0x7C,  0x28,  0x06,  0x10,  0x09,  0x28,  0x10, 	/* 2C260 */
+	0x44,  0x60,  0x82,  0x03,  0x01,  0x96,  0x08,  0x04,  0x08,  0x18,  0x08,  0xF0,  0x08,  0x10,  0x7F,  0x10, 	/* 2C270 */
+	0x12,  0x10,  0x13,  0xFF,  0x12,  0x10,  0x22,  0x10,  0x22,  0x10,  0x7C,  0x28,  0x44,  0x28,  0x0A,  0x44, 	/* 2C280 */
+	0x12,  0x84,  0x61,  0x02,  0x02,  0x01,  0x99,  0x08,  0x10,  0x08,  0x10,  0x08,  0x10,  0x08,  0x58,  0x7E, 	/* 2C290 */
+	0x54,  0x12,  0x52,  0x12,  0x92,  0x12,  0x91,  0x23,  0x15,  0x22,  0x14,  0x7C,  0x38,  0x46,  0x08,  0x09, 	/* 2C2A0 */
+	0x10,  0x10,  0x20,  0x60,  0xC0,  0x03,  0x00,  0x9B,  0x00,  0x80,  0x10,  0x84,  0x10,  0x84,  0x10,  0x84, 	/* 2C2B0 */
+	0x1F,  0xFC,  0x00,  0x00,  0x7F,  0xFF,  0x00,  0x00,  0x02,  0x00,  0x7F,  0xFF,  0x02,  0x10,  0x04,  0x10, 	/* 2C2C0 */
+	0x1F,  0x20,  0x01,  0xC0,  0x06,  0x30,  0x38,  0x0C,  0x9D,  0x04,  0x20,  0x24,  0x20,  0x24,  0x20,  0x24, 	/* 2C2D0 */
+	0x20,  0x27,  0xFF,  0x3C,  0x44,  0x04,  0x44,  0x04,  0x44,  0x7C,  0x44,  0x14,  0x88,  0x15,  0xE8,  0x14, 	/* 2C2E0 */
+	0x10,  0x24,  0x28,  0x24,  0x44,  0x45,  0x82,  0x06,  0x02,  0xA3,  0x08,  0x88,  0x08,  0x88,  0x08,  0x88, 	/* 2C2F0 */
+	0x08,  0x88,  0x7F,  0x89,  0x12,  0x89,  0x12,  0xFA,  0x12,  0x8C,  0x22,  0x88,  0x24,  0x88,  0x7C,  0x88, 	/* 2C300 */
+	0x46,  0x88,  0x0A,  0x88,  0x10,  0xB9,  0x60,  0xC9,  0x03,  0x07,  0xA5,  0x00,  0x04,  0x00,  0x38,  0x1F, 	/* 2C310 */
+	0xC4,  0x00,  0x84,  0x08,  0x48,  0x04,  0x48,  0x05,  0x10,  0x01,  0x00,  0x7F,  0xFF,  0x02,  0x10,  0x02, 	/* 2C320 */
+	0x10,  0x04,  0x20,  0x0F,  0xC0,  0x00,  0xB0,  0x03,  0x08,  0x3C,  0x04,  0xA8,  0x08,  0x20,  0x08,  0x20, 	/* 2C330 */
+	0x08,  0x20,  0x09,  0xFF,  0x7E,  0x40,  0x12,  0x40,  0x12,  0x40,  0x12,  0x7C,  0x22,  0x44,  0x24,  0x44, 	/* 2C340 */
+	0x7C,  0x44,  0x46,  0x44,  0x0A,  0x84,  0x10,  0x84,  0x61,  0x04,  0x02,  0x18,  0xAC,  0x08,  0x00,  0x09, 	/* 2C350 */
+	0xFF,  0x08,  0x10,  0x08,  0x10,  0x7E,  0x10,  0x12,  0x20,  0x12,  0x20,  0x12,  0x7E,  0x22,  0x42,  0x24, 	/* 2C360 */
+	0xC2,  0x7D,  0x42,  0x06,  0x42,  0x0A,  0x42,  0x10,  0x42,  0x60,  0x7E,  0x00,  0x00,  0xB2,  0x08,  0x00, 	/* 2C370 */
+	0x08,  0xFC,  0x08,  0x84,  0x08,  0x84,  0x7E,  0x84,  0x12,  0x84,  0x12,  0xFC,  0x12,  0x84,  0x22,  0x84, 	/* 2C380 */
+	0x24,  0x84,  0x7C,  0x84,  0x46,  0xFC,  0x0A,  0x00,  0x10,  0x00,  0x63,  0xFF,  0x00,  0x00,  0xB9,  0x08, 	/* 2C390 */
+	0x10,  0x08,  0x10,  0x08,  0x10,  0x08,  0xFE,  0x7F,  0x10,  0x12,  0x10,  0x12,  0x10,  0x13,  0xFF,  0x22, 	/* 2C3A0 */
+	0x38,  0x24,  0x38,  0x7C,  0x54,  0x04,  0x54,  0x0A,  0x92,  0x11,  0x11,  0x60,  0x10,  0x00,  0x10,  0xBB, 	/* 2C3B0 */
+	0x00,  0x80,  0x00,  0x80,  0x3F,  0xFF,  0x00,  0x80,  0x0F,  0xFC,  0x00,  0x84,  0x7F,  0xFF,  0x00,  0x84, 	/* 2C3C0 */
+	0x0F,  0xFC,  0x00,  0x80,  0x7F,  0xFF,  0x01,  0x10,  0x02,  0x10,  0x0F,  0xE0,  0x01,  0x98,  0x1E,  0x04, 	/* 2C3D0 */
+	0xBE,  0x00,  0x80,  0x00,  0x80,  0x3F,  0xFE,  0x04,  0x10,  0x02,  0x10,  0x02,  0x20,  0x7F,  0xFF,  0x00, 	/* 2C3E0 */
+	0x00,  0x01,  0x00,  0x7F,  0xFF,  0x01,  0x10,  0x02,  0x10,  0x0F,  0x20,  0x00,  0xE0,  0x03,  0x18,  0x3C, 	/* 2C3F0 */
+	0x04,  0x86,  0x08,  0x00,  0x08,  0x7E,  0x08,  0x42,  0x08,  0x52,  0x7F,  0x4A,  0x12,  0x4A,  0x12,  0x42, 	/* 2C400 */
+	0x13,  0xFF,  0x22,  0x82,  0x24,  0xA2,  0x7C,  0x92,  0x46,  0x92,  0x0B,  0xFF,  0x10,  0x02,  0x60,  0x04, 	/* 2C410 */
+	0x00,  0x18,  0x89,  0x08,  0x10,  0x08,  0x10,  0x08,  0x10,  0x09,  0xFF,  0x7F,  0x10,  0x12,  0x10,  0x12, 	/* 2C420 */
+	0xFE,  0x12,  0x92,  0x22,  0x92,  0x3C,  0x92,  0x44,  0x92,  0x06,  0x92,  0x0A,  0x9C,  0x10,  0x10,  0x60, 	/* 2C430 */
+	0x10,  0x00,  0x10,  0x8B,  0x08,  0x10,  0x08,  0x10,  0x08,  0x10,  0x08,  0x24,  0x7F,  0x22,  0x12,  0x42, 	/* 2C440 */
+	0x12,  0x4F,  0x13,  0xF1,  0x22,  0x01,  0x3C,  0x00,  0x44,  0x7E,  0x06,  0x42,  0x0A,  0x42,  0x10,  0x42, 	/* 2C450 */
+	0x60,  0x7E,  0x00,  0x00,  0x90,  0x08,  0x00,  0x08,  0xFC,  0x08,  0x84,  0x08,  0x84,  0x7F,  0x84,  0x12, 	/* 2C460 */
+	0xFC,  0x12,  0x84,  0x12,  0x84,  0x22,  0x84,  0x24,  0x84,  0x7C,  0xFC,  0x06,  0x84,  0x0A,  0x84,  0x10, 	/* 2C470 */
+	0x84,  0x67,  0xFF,  0x00,  0x00,  0x91,  0x08,  0x20,  0x08,  0x20,  0x08,  0x20,  0x08,  0x20,  0x7F,  0xFF, 	/* 2C480 */
+	0x12,  0x20,  0x12,  0x20,  0x12,  0x20,  0x22,  0x20,  0x22,  0xFC,  0x7C,  0x84,  0x04,  0x84,  0x0A,  0x84, 	/* 2C490 */
+	0x12,  0x84,  0x60,  0xFC,  0x00,  0x00,  0x93,  0x08,  0x10,  0x08,  0x90,  0x08,  0x90,  0x08,  0x90,  0x7E, 	/* 2C4A0 */
+	0xFE,  0x12,  0x90,  0x13,  0x10,  0x12,  0x10,  0x22,  0x10,  0x24,  0xFE,  0x7C,  0x10,  0x06,  0x10,  0x0A, 	/* 2C4B0 */
+	0x10,  0x10,  0x10,  0x63,  0xFF,  0x00,  0x00,  0x94,  0x00,  0x18,  0x1F,  0xE0,  0x00,  0x80,  0x7F,  0xFF, 	/* 2C4C0 */
+	0x01,  0xC0,  0x02,  0xA0,  0x0C,  0x98,  0x70,  0x87,  0x01,  0x00,  0x7F,  0xFF,  0x02,  0x10,  0x02,  0x10, 	/* 2C4D0 */
+	0x07,  0xA0,  0x08,  0x40,  0x01,  0xB0,  0x3E,  0x0C,  0x99,  0x10,  0x42,  0x10,  0x44,  0x10,  0x78,  0x10, 	/* 2C4E0 */
+	0x88,  0x7E,  0x88,  0x13,  0x88,  0x12,  0x88,  0x12,  0xFF,  0x22,  0x88,  0x24,  0x88,  0x7C,  0x88,  0x46, 	/* 2C4F0 */
+	0x88,  0x0A,  0x88,  0x10,  0x88,  0x60,  0xBF,  0x00,  0x80,  0x9A,  0x08,  0x28,  0x08,  0x28,  0x08,  0x2A, 	/* 2C500 */
+	0x09,  0x2A,  0x7E,  0xAA,  0x12,  0xAC,  0x12,  0xAC,  0x12,  0x28,  0x22,  0x2C,  0x24,  0x6A,  0x7C,  0xC9, 	/* 2C510 */
+	0x47,  0x48,  0x0A,  0x48,  0x10,  0x89,  0x61,  0x09,  0x06,  0x07,  0x9C,  0x04,  0x10,  0x02,  0x20,  0x3F, 	/* 2C520 */
+	0xFE,  0x00,  0x80,  0x1F,  0xFC,  0x00,  0x80,  0x00,  0x80,  0x7F,  0xFF,  0x01,  0x00,  0x3F,  0xFE,  0x02, 	/* 2C530 */
+	0x20,  0x04,  0x20,  0x0F,  0xC0,  0x01,  0x60,  0x06,  0x10,  0x38,  0x08,  0xA5,  0x08,  0x20,  0x08,  0x24, 	/* 2C540 */
+	0x09,  0xFC,  0x08,  0x28,  0x7E,  0x28,  0x12,  0x30,  0x13,  0xFF,  0x12,  0x20,  0x22,  0x40,  0x24,  0xC4, 	/* 2C550 */
+	0x7D,  0x58,  0x46,  0x60,  0x0A,  0x40,  0x10,  0x42,  0x60,  0x42,  0x00,  0x3E,  0xA6,  0x01,  0x00,  0x01, 	/* 2C560 */
+	0x00,  0x3F,  0xFC,  0x02,  0x20,  0x04,  0x40,  0x0F,  0x80,  0x02,  0x70,  0x3C,  0x08,  0x04,  0x10,  0x7F, 	/* 2C570 */
+	0xFF,  0x09,  0x24,  0x09,  0x24,  0x3D,  0xF4,  0x06,  0x18,  0x0B,  0x2C,  0x70,  0xC2,  0xA8,  0x08,  0x10, 	/* 2C580 */
+	0x08,  0x10,  0x09,  0xFF,  0x08,  0x10,  0x7E,  0xFE,  0x12,  0x12,  0x12,  0xFE,  0x12,  0x90,  0x22,  0x90, 	/* 2C590 */
+	0x7C,  0xFF,  0x44,  0x11,  0x06,  0x29,  0x0A,  0x2A,  0x10,  0x44,  0x61,  0x82,  0x06,  0x01,  0xAA,  0x08, 	/* 2C5A0 */
+	0x00,  0x09,  0xFF,  0x08,  0x20,  0x08,  0x28,  0x7E,  0x24,  0x12,  0x4E,  0x13,  0xF1,  0x12,  0x00,  0x22, 	/* 2C5B0 */
+	0x10,  0x7C,  0x10,  0x44,  0xFE,  0x06,  0x10,  0x0A,  0x10,  0x10,  0x10,  0x63,  0xFF,  0x00,  0x00,  0xAB, 	/* 2C5C0 */
+	0x08,  0x00,  0x08,  0xFF,  0x08,  0x88,  0x08,  0x88,  0x7F,  0x88,  0x12,  0xFE,  0x12,  0x82,  0x12,  0x82, 	/* 2C5D0 */
+	0x22,  0x82,  0x24,  0xFE,  0x7C,  0x88,  0x06,  0x88,  0x0A,  0x88,  0x12,  0x88,  0x60,  0xFF,  0x00,  0x80, 	/* 2C5E0 */
+	0xB6,  0x08,  0x10,  0x08,  0x10,  0x08,  0x28,  0x08,  0x28,  0x7E,  0x44,  0x12,  0x82,  0x13,  0x01,  0x12, 	/* 2C5F0 */
+	0x7C,  0x22,  0x00,  0x24,  0x00,  0x7C,  0xFE,  0x46,  0x82,  0x0A,  0x82,  0x10,  0x82,  0x60,  0xFE,  0x00, 	/* 2C600 */
+	0x00,  0xBB,  0x08,  0x00,  0x08,  0xFE,  0x08,  0x82,  0x08,  0x92,  0x7E,  0x92,  0x12,  0xFE,  0x12,  0x92, 	/* 2C610 */
+	0x12,  0x92,  0x22,  0xAA,  0x24,  0xAA,  0x7C,  0xAA,  0x06,  0xC6,  0x0A,  0x82,  0x10,  0x82,  0x60,  0xFE, 	/* 2C620 */
+	0x00,  0x00,  0xBF,  0x01,  0x00,  0x21,  0x00,  0x11,  0xFE,  0x12,  0x44,  0x02,  0x48,  0x0C,  0x60,  0x31, 	/* 2C630 */
+	0x98,  0x4E,  0x06,  0x01,  0x00,  0x7F,  0xFF,  0x02,  0x10,  0x04,  0x10,  0x1F,  0xA0,  0x00,  0xE0,  0x03, 	/* 2C640 */
+	0x18,  0x3C,  0x04,  0x81,  0x00,  0x28,  0x00,  0x24,  0x00,  0x24,  0x1F,  0xFF,  0x10,  0x20,  0x1F,  0xA0, 	/* 2C650 */
+	0x12,  0x22,  0x12,  0x22,  0x1F,  0xD4,  0x14,  0x94,  0x14,  0x98,  0x1F,  0x08,  0x11,  0x9A,  0x22,  0xA6, 	/* 2C660 */
+	0x2C,  0x42,  0x40,  0x82,  0x83,  0x08,  0x10,  0x08,  0x10,  0x08,  0x10,  0x08,  0xFE,  0x7F,  0x10,  0x12, 	/* 2C670 */
+	0x10,  0x12,  0x10,  0x13,  0xFF,  0x22,  0x10,  0x7C,  0x10,  0x44,  0xFE,  0x06,  0x10,  0x0A,  0x10,  0x10, 	/* 2C680 */
+	0x10,  0x61,  0xFF,  0x00,  0x00,  0x89,  0x08,  0x10,  0x08,  0x10,  0x08,  0xFE,  0x08,  0x92,  0x7E,  0xFE, 	/* 2C690 */
+	0x12,  0x92,  0x12,  0x92,  0x12,  0xFE,  0x22,  0x00,  0x25,  0xFF,  0x7C,  0x20,  0x46,  0x7C,  0x0A,  0x44, 	/* 2C6A0 */
+	0x10,  0x04,  0x60,  0x04,  0x00,  0x18,  0x91,  0x00,  0x10,  0x18,  0x10,  0x04,  0x94,  0x60,  0x92,  0x11, 	/* 2C6B0 */
+	0x11,  0x02,  0x34,  0x08,  0x08,  0x30,  0x30,  0x41,  0xC0,  0x01,  0x00,  0x7F,  0xFF,  0x02,  0x20,  0x04, 	/* 2C6C0 */
+	0x20,  0x0F,  0xC0,  0x01,  0xB0,  0x3E,  0x0C,  0x98,  0x08,  0x20,  0x08,  0x20,  0x08,  0xFC,  0x08,  0x84, 	/* 2C6D0 */
+	0x7F,  0x84,  0x12,  0xFC,  0x12,  0x84,  0x12,  0x84,  0x22,  0xFE,  0x7C,  0x92,  0x44,  0x94,  0x06,  0x88, 	/* 2C6E0 */
+	0x0A,  0x88,  0x10,  0xA4,  0x60,  0xC2,  0x03,  0x01,  0x9A,  0x08,  0x00,  0x08,  0xFE,  0x08,  0x92,  0x08, 	/* 2C6F0 */
+	0x92,  0x7E,  0xFE,  0x12,  0x92,  0x12,  0x92,  0x12,  0xFE,  0x22,  0x20,  0x24,  0x20,  0x7C,  0xFE,  0x46, 	/* 2C700 */
+	0x22,  0x0A,  0x22,  0x10,  0x42,  0x60,  0x82,  0x03,  0x0C,  0x9C,  0x10,  0x00,  0x13,  0xEF,  0x10,  0xA9, 	/* 2C710 */
+	0x10,  0xA9,  0x7E,  0xAA,  0x15,  0xEC,  0x14,  0xAA,  0x14,  0xAA,  0x24,  0xA9,  0x25,  0xE9,  0x78,  0xA9, 	/* 2C720 */
+	0x0C,  0xA9,  0x0B,  0x2E,  0x11,  0x28,  0x62,  0x28,  0x04,  0x68,  0x9F,  0x08,  0x00,  0x08,  0xFE,  0x08, 	/* 2C730 */
+	0x82,  0x08,  0x82,  0x7E,  0xFE,  0x12,  0x00,  0x12,  0xFE,  0x12,  0x82,  0x22,  0x82,  0x24,  0xFE,  0x7C, 	/* 2C740 */
+	0x82,  0x46,  0x82,  0x0A,  0xFE,  0x10,  0x82,  0x60,  0x82,  0x00,  0x86,  0xA0,  0x08,  0x00,  0x08,  0xFF, 	/* 2C750 */
+	0x08,  0x80,  0x08,  0x80,  0x7F,  0xBE,  0x12,  0x80,  0x12,  0x80,  0x12,  0xFF,  0x22,  0xAA,  0x3C,  0xAA, 	/* 2C760 */
+	0x44,  0xAA,  0x07,  0x2C,  0x09,  0x24,  0x12,  0x34,  0x64,  0x62,  0x00,  0x81,  0xA5,  0x08,  0x28,  0x08, 	/* 2C770 */
+	0x4C,  0x09,  0xCA,  0x08,  0x4A,  0x7E,  0x48,  0x13,  0xFF,  0x12,  0x48,  0x12,  0x4A,  0x22,  0x4A,  0x24, 	/* 2C780 */
+	0x6C,  0x7D,  0xC4,  0x46,  0x4D,  0x0A,  0x55,  0x10,  0x63,  0x60,  0x43,  0x00,  0xC1,  0xA9,  0x08,  0x20, 	/* 2C790 */
+	0x08,  0x3C,  0x08,  0x48,  0x08,  0x48,  0x7E,  0x90,  0x13,  0xFE,  0x12,  0x92,  0x12,  0x92,  0x22,  0x92, 	/* 2C7A0 */
+	0x24,  0xFE,  0x7C,  0x28,  0x46,  0x28,  0x0A,  0x28,  0x10,  0x49,  0x60,  0x89,  0x03,  0x07,  0xAF,  0x08, 	/* 2C7B0 */
+	0x00,  0x08,  0xBC,  0x08,  0xA4,  0x08,  0xA4,  0x7E,  0xA4,  0x12,  0xBC,  0x12,  0x80,  0x12,  0x80,  0x22, 	/* 2C7C0 */
+	0xFC,  0x24,  0x04,  0x7C,  0x04,  0x05,  0xFF,  0x0A,  0x00,  0x12,  0x24,  0x60,  0x42,  0x01,  0x81,  0xB5, 	/* 2C7D0 */
+	0x08,  0x00,  0x0B,  0xFF,  0x09,  0x20,  0x09,  0x20,  0x7D,  0x3E,  0x15,  0xEA,  0x15,  0x2A,  0x15,  0x2A, 	/* 2C7E0 */
+	0x25,  0x2A,  0x25,  0xEA,  0x79,  0x24,  0x09,  0x24,  0x0D,  0xEA,  0x17,  0x32,  0x60,  0x21,  0x00,  0x20, 	/* 2C7F0 */
+	0xB6,  0x00,  0x00,  0x7F,  0x80,  0x11,  0xFE,  0x1F,  0x42,  0x11,  0x24,  0x1F,  0x28,  0x11,  0x18,  0x1F, 	/* 2C800 */
+	0x24,  0x71,  0xC3,  0x01,  0x00,  0x7F,  0xFF,  0x02,  0x20,  0x04,  0x20,  0x0F,  0xC0,  0x01,  0xB0,  0x3E, 	/* 2C810 */
+	0x08,  0xBC,  0x08,  0x00,  0x08,  0x7C,  0x08,  0x44,  0x08,  0x44,  0x7E,  0x7C,  0x12,  0x44,  0x12,  0x7C, 	/* 2C820 */
+	0x12,  0x00,  0x22,  0xFE,  0x24,  0x82,  0x7C,  0x82,  0x06,  0xFE,  0x0A,  0x82,  0x10,  0x82,  0x60,  0xFE, 	/* 2C830 */
+	0x00,  0x00,  0x80,  0x08,  0x00,  0x09,  0xDF,  0x09,  0x42,  0x09,  0x42,  0x7F,  0x7A,  0x15,  0xAA,  0x15, 	/* 2C840 */
+	0xAA,  0x15,  0x6A,  0x25,  0x6A,  0x25,  0x6A,  0x79,  0x7A,  0x0D,  0x42,  0x09,  0xC2,  0x11,  0x02,  0x61, 	/* 2C850 */
+	0x02,  0x01,  0x06,  0x81,  0x00,  0x80,  0x0F,  0xF8,  0x08,  0x88,  0x7F,  0xFF,  0x08,  0x88,  0x0F,  0xF8, 	/* 2C860 */
+	0x00,  0x80,  0x1F,  0xFC,  0x10,  0x84,  0x1F,  0xFC,  0x00,  0x80,  0x7F,  0xFF,  0x02,  0x10,  0x0F,  0xE0, 	/* 2C870 */
+	0x01,  0xB0,  0x1E,  0x0C,  0x86,  0x00,  0x20,  0x19,  0xFE,  0x05,  0x24,  0x61,  0xFC,  0x11,  0x48,  0x05, 	/* 2C880 */
+	0x28,  0x0A,  0x30,  0x12,  0xC8,  0x65,  0x06,  0x01,  0x00,  0x7F,  0xFF,  0x02,  0x10,  0x0F,  0x20,  0x00, 	/* 2C890 */
+	0xC0,  0x03,  0x30,  0x3C,  0x08,  0x89,  0x08,  0x10,  0x08,  0x10,  0x09,  0xFF,  0x09,  0x01,  0x7F,  0x01, 	/* 2C8A0 */
+	0x12,  0x80,  0x12,  0xEE,  0x12,  0xAA,  0x25,  0x2A,  0x25,  0x2A,  0x7E,  0xAA,  0x04,  0x4E,  0x08,  0x48, 	/* 2C8B0 */
+	0x10,  0x89,  0x61,  0x09,  0x02,  0x07,  0x9A,  0x08,  0x06,  0x08,  0xF8,  0x08,  0x88,  0x08,  0x88,  0x7E, 	/* 2C8C0 */
+	0xFF,  0x12,  0x88,  0x12,  0x88,  0x12,  0xE5,  0x23,  0x83,  0x24,  0xFD,  0x7C,  0x84,  0x46,  0xFC,  0x0A, 	/* 2C8D0 */
+	0x84,  0x10,  0x84,  0x60,  0xFC,  0x00,  0x00,  0xA2,  0x08,  0x10,  0x08,  0x20,  0x08,  0xFE,  0x08,  0x92, 	/* 2C8E0 */
+	0x7E,  0x92,  0x12,  0xFE,  0x12,  0x92,  0x12,  0x92,  0x22,  0xFE,  0x24,  0x28,  0x7C,  0x48,  0x07,  0xFF, 	/* 2C8F0 */
+	0x0A,  0x08,  0x10,  0x08,  0x60,  0x08,  0x00,  0x08,  0xA6,  0x08,  0x00,  0x08,  0xFC,  0x08,  0x04,  0x08, 	/* 2C900 */
+	0xFC,  0x7E,  0x04,  0x12,  0xFC,  0x12,  0x00,  0x13,  0xFF,  0x23,  0x11,  0x25,  0x11,  0x7C,  0xFE,  0x06, 	/* 2C910 */
+	0x92,  0x0A,  0x92,  0x10,  0x9C,  0x60,  0x90,  0x00,  0x10,  0xAA,  0x04,  0x10,  0x04,  0x10,  0x7F,  0xFF, 	/* 2C920 */
+	0x0E,  0x18,  0x0D,  0x34,  0x14,  0xD4,  0x24,  0x92,  0x44,  0x11,  0x01,  0x00,  0x7F,  0xFF,  0x02,  0x20, 	/* 2C930 */
+	0x04,  0x20,  0x0F,  0x40,  0x00,  0xC0,  0x03,  0x30,  0x3C,  0x08,  0xAC,  0x08,  0x02,  0x08,  0x0C,  0x08, 	/* 2C940 */
+	0xF0,  0x08,  0x04,  0x7F,  0x52,  0x12,  0x49,  0x12,  0x89,  0x12,  0x04,  0x22,  0xF8,  0x24,  0x10,  0x7C, 	/* 2C950 */
+	0x10,  0x47,  0xFF,  0x0A,  0x10,  0x10,  0x10,  0x61,  0xFE,  0x00,  0x00,  0xBF,  0x08,  0x00,  0x09,  0xFF, 	/* 2C960 */
+	0x08,  0x12,  0x08,  0x9E,  0x7E,  0xD0,  0x12,  0xB0,  0x13,  0x1F,  0x12,  0x00,  0x22,  0xFC,  0x7C,  0x84, 	/* 2C970 */
+	0x44,  0xFC,  0x06,  0x84,  0x0A,  0xFC,  0x12,  0x84,  0x60,  0x84,  0x00,  0x8C,  0x92,  0x08,  0x44,  0x08, 	/* 2C980 */
+	0x44,  0x09,  0xFF,  0x08,  0x44,  0x7F,  0x7C,  0x12,  0x44,  0x12,  0x44,  0x12,  0x7C,  0x22,  0x10,  0x23, 	/* 2C990 */
+	0xFF,  0x7C,  0x38,  0x06,  0x34,  0x0A,  0x54,  0x10,  0x92,  0x63,  0x11,  0x00,  0x10,  0x9A,  0x08,  0x00, 	/* 2C9A0 */
+	0x08,  0xFF,  0x08,  0x91,  0x08,  0x91,  0x7E,  0xFF,  0x12,  0x80,  0x12,  0xBE,  0x12,  0xA2,  0x22,  0xA2, 	/* 2C9B0 */
+	0x24,  0xBE,  0x7C,  0xA2,  0x46,  0xBE,  0x09,  0x22,  0x11,  0x22,  0x62,  0x3E,  0x00,  0x00,  0x9B,  0x08, 	/* 2C9C0 */
+	0x04,  0x08,  0x1A,  0x09,  0xE2,  0x08,  0x24,  0x7E,  0x94,  0x12,  0x58,  0x13,  0xFE,  0x12,  0x40,  0x23, 	/* 2C9D0 */
+	0xFF,  0x24,  0x40,  0x7C,  0x7C,  0x46,  0xA4,  0x0A,  0x98,  0x11,  0x10,  0x62,  0x6C,  0x01,  0x83,  0xBC, 	/* 2C9E0 */
+	0x08,  0x00,  0x08,  0xFC,  0x08,  0xA4,  0x08,  0xA4,  0x7E,  0xB4,  0x12,  0xD4,  0x12,  0x8C,  0x12,  0xFC, 	/* 2C9F0 */
+	0x22,  0x00,  0x24,  0xFE,  0x7C,  0xAA,  0x46,  0xAA,  0x0A,  0xAA,  0x10,  0xAA,  0x63,  0xFF,  0x00,  0x00, 	/* 2CA00 */
+	0xBD,  0x08,  0x00,  0x08,  0xFE,  0x08,  0x90,  0x08,  0x90,  0x7E,  0xFC,  0x12,  0x90,  0x12,  0x90,  0x12, 	/* 2CA10 */
+	0xFC,  0x22,  0x90,  0x24,  0x90,  0x7C,  0xFE,  0x46,  0x2A,  0x0B,  0x56,  0x11,  0x52,  0x62,  0x02,  0x00, 	/* 2CA20 */
+	0x0C,  0xBE,  0x08,  0x48,  0x08,  0x48,  0x08,  0xFE,  0x08,  0x48,  0x7E,  0xFE,  0x12,  0x48,  0x13,  0xFF, 	/* 2CA30 */
+	0x12,  0x10,  0x22,  0xFE,  0x24,  0x92,  0x7C,  0xFE,  0x46,  0x92,  0x0B,  0xFF,  0x10,  0x82,  0x60,  0x82, 	/* 2CA40 */
+	0x00,  0x86,  0x81,  0x08,  0x20,  0x08,  0x20,  0x09,  0xFE,  0x09,  0x02,  0x7E,  0x00,  0x13,  0xFC,  0x12, 	/* 2CA50 */
+	0x40,  0x12,  0xA2,  0x25,  0x2A,  0x24,  0x5C,  0x78,  0x94,  0x0D,  0x34,  0x14,  0x52,  0x20,  0x91,  0x43, 	/* 2CA60 */
+	0x10,  0x00,  0x60,  0x82,  0x08,  0x10,  0x08,  0x50,  0x08,  0xD6,  0x08,  0x92,  0x7E,  0x92,  0x12,  0xD6, 	/* 2CA70 */
+	0x12,  0x92,  0x12,  0x92,  0x22,  0xFE,  0x24,  0x10,  0x7D,  0xFE,  0x46,  0x44,  0x0A,  0x28,  0x10,  0x30, 	/* 2CA80 */
+	0x60,  0xCC,  0x03,  0x03,  0x89,  0x10,  0x08,  0x10,  0x08,  0x10,  0xFF,  0x12,  0x90,  0x7D,  0x90,  0x25, 	/* 2CA90 */
+	0xBF,  0x24,  0xA8,  0x24,  0xC8,  0x25,  0x88,  0x4A,  0xFF,  0x78,  0x88,  0x0C,  0x98,  0x09,  0x14,  0x11, 	/* 2CAA0 */
+	0x24,  0x62,  0x42,  0x04,  0x81,  0x8B,  0x10,  0x00,  0x11,  0xFE,  0x10,  0x22,  0x10,  0x22,  0x7D,  0xEE, 	/* 2CAB0 */
+	0x15,  0x08,  0x15,  0x08,  0x25,  0xEE,  0x24,  0x66,  0x24,  0xAA,  0x79,  0x32,  0x4C,  0x66,  0x0A,  0xAA, 	/* 2CAC0 */
+	0x11,  0x32,  0x60,  0x44,  0x01,  0x98,  0x8C,  0x11,  0x04,  0x10,  0x88,  0x13,  0xFF,  0x10,  0x50,  0x7F, 	/* 2CAD0 */
+	0xFC,  0x12,  0x54,  0x12,  0x54,  0x13,  0xFF,  0x22,  0x54,  0x24,  0x54,  0x7D,  0xFC,  0x06,  0x58,  0x0A, 	/* 2CAE0 */
+	0xD4,  0x11,  0x52,  0x62,  0x51,  0x00,  0x50,  0x90,  0x10,  0x08,  0x13,  0xE8,  0x12,  0xA8,  0x12,  0xA8, 	/* 2CAF0 */
+	0x7F,  0xFF,  0x2A,  0xAA,  0x2A,  0xAA,  0x2B,  0xEA,  0x28,  0x8A,  0x4B,  0xF2,  0x70,  0xBC,  0x48,  0xA4, 	/* 2CB00 */
+	0x14,  0xA6,  0x25,  0x2A,  0x42,  0x31,  0x04,  0xC1,  0x96,  0x08,  0x00,  0x09,  0xFF,  0x08,  0x28,  0x08, 	/* 2CB10 */
+	0xFE,  0x7E,  0xAA,  0x12,  0xAA,  0x12,  0xFE,  0x12,  0x00,  0x22,  0xFE,  0x24,  0x00,  0x7D,  0xFF,  0x46, 	/* 2CB20 */
+	0x10,  0x0A,  0x94,  0x10,  0x92,  0x61,  0x12,  0x00,  0x30,  0x97,  0x08,  0x00,  0x09,  0xFF,  0x09,  0x00, 	/* 2CB30 */
+	0x09,  0x7C,  0x7F,  0x44,  0x15,  0x44,  0x15,  0x7C,  0x15,  0x00,  0x25,  0xEE,  0x25,  0xAA,  0x79,  0xAA, 	/* 2CB40 */
+	0x4D,  0xAA,  0x0B,  0xEE,  0x11,  0x00,  0x61,  0xFF,  0x01,  0x00,  0xA1,  0x08,  0x20,  0x08,  0x20,  0x0B, 	/* 2CB50 */
+	0xFF,  0x08,  0x84,  0x7E,  0x48,  0x13,  0xFE,  0x13,  0x22,  0x13,  0x22,  0x23,  0xFE,  0x25,  0x22,  0x7D, 	/* 2CB60 */
+	0x7A,  0x45,  0x4A,  0x09,  0x4A,  0x11,  0x7A,  0x61,  0x02,  0x01,  0x06,  0xA3,  0x08,  0x00,  0x09,  0xFF, 	/* 2CB70 */
+	0x08,  0x10,  0x08,  0x50,  0x7E,  0x5E,  0x12,  0x50,  0x12,  0x50,  0x13,  0xFF,  0x22,  0x80,  0x24,  0xFF, 	/* 2CB80 */
+	0x7C,  0x80,  0x46,  0xFE,  0x0A,  0x0A,  0x11,  0x56,  0x61,  0x52,  0x02,  0x0C,  0xA6,  0x08,  0x92,  0x08, 	/* 2CB90 */
+	0x52,  0x08,  0x54,  0x09,  0xFF,  0x7F,  0x01,  0x13,  0x7D,  0x12,  0x44,  0x12,  0x44,  0x22,  0x7C,  0x24, 	/* 2CBA0 */
+	0x10,  0x7C,  0xFE,  0x46,  0x92,  0x0A,  0x92,  0x10,  0x92,  0x60,  0x9C,  0x00,  0x10,  0xA9,  0x11,  0x10, 	/* 2CBB0 */
+	0x11,  0x10,  0x17,  0xD0,  0x11,  0x1F,  0x7F,  0xD4,  0x15,  0x64,  0x15,  0x54,  0x15,  0x54,  0x27,  0xD4, 	/* 2CBC0 */
+	0x25,  0x18,  0x79,  0x88,  0x0B,  0x54,  0x13,  0x14,  0x25,  0x22,  0x41,  0x42,  0x01,  0x81,  0xBA,  0x10, 	/* 2CBD0 */
+	0x00,  0x11,  0xDE,  0x11,  0x52,  0x11,  0xDE,  0x7F,  0x52,  0x15,  0x52,  0x15,  0xDE,  0x15,  0x02,  0x25, 	/* 2CBE0 */
+	0x7A,  0x25,  0x4A,  0x79,  0x7A,  0x0D,  0x4A,  0x09,  0x7A,  0x11,  0x4A,  0x61,  0x9A,  0x01,  0x06,  0xBB, 	/* 2CBF0 */
+	0x10,  0x00,  0x11,  0xDE,  0x11,  0x52,  0x11,  0xDE,  0x7F,  0x52,  0x15,  0x52,  0x15,  0xDE,  0x15,  0x22, 	/* 2CC00 */
+	0x25,  0x22,  0x25,  0xFA,  0x79,  0x32,  0x4D,  0x6A,  0x09,  0xA6,  0x11,  0x22,  0x61,  0x22,  0x01,  0x06, 	/* 2CC10 */
+	0x89,  0x08,  0x10,  0x09,  0xFF,  0x08,  0x10,  0x08,  0xFE,  0x7E,  0x00,  0x12,  0xFE,  0x12,  0x82,  0x12, 	/* 2CC20 */
+	0xFE,  0x22,  0x44,  0x24,  0x28,  0x7D,  0xFF,  0x06,  0x00,  0x0A,  0xFE,  0x10,  0x82,  0x60,  0xFE,  0x00, 	/* 2CC30 */
+	0x00,  0x8B,  0x08,  0x00,  0x09,  0xEF,  0x09,  0x29,  0x09,  0xEF,  0x7E,  0x00,  0x12,  0xFE,  0x12,  0x92, 	/* 2CC40 */
+	0x12,  0xFE,  0x22,  0x92,  0x24,  0x92,  0x7C,  0xFE,  0x46,  0x10,  0x0B,  0xFF,  0x10,  0x10,  0x60,  0x10, 	/* 2CC50 */
+	0x00,  0x10,  0x8C,  0x08,  0x0C,  0x08,  0xF0,  0x08,  0x10,  0x09,  0xFF,  0x7E,  0x48,  0x12,  0xFC,  0x13, 	/* 2CC60 */
+	0x4B,  0x12,  0x78,  0x22,  0x00,  0x25,  0xFE,  0x7D,  0x02,  0x47,  0x7A,  0x0B,  0x4A,  0x11,  0x7A,  0x61, 	/* 2CC70 */
+	0x02,  0x01,  0x06,  0x96,  0x00,  0x10,  0x1F,  0x10,  0x11,  0xFE,  0x11,  0x44,  0x1F,  0x28,  0x10,  0xFF, 	/* 2CC80 */
+	0x1F,  0x10,  0x29,  0xFE,  0x29,  0x10,  0x4F,  0x10,  0x01,  0x00,  0x7F,  0xFF,  0x04,  0x20,  0x0F,  0xC0, 	/* 2CC90 */
+	0x01,  0xB0,  0x3E,  0x0C,  0xA2,  0x08,  0x10,  0x08,  0x10,  0x09,  0xFF,  0x08,  0x44,  0x7F,  0xAA,  0x12, 	/* 2CCA0 */
+	0x29,  0x12,  0xFE,  0x12,  0x28,  0x22,  0xFE,  0x24,  0x28,  0x7D,  0xFF,  0x46,  0x28,  0x0A,  0x4A,  0x11, 	/* 2CCB0 */
+	0xC4,  0x60,  0x72,  0x01,  0x81,  0xAA,  0x08,  0x20,  0x09,  0xFE,  0x09,  0x02,  0x09,  0xFC,  0x7E,  0xA4, 	/* 2CCC0 */
+	0x14,  0xA8,  0x15,  0x30,  0x14,  0xFC,  0x27,  0x84,  0x24,  0xFC,  0x78,  0x84,  0x0C,  0xFC,  0x0A,  0x84, 	/* 2CCD0 */
+	0x10,  0xFC,  0x60,  0xC4,  0x03,  0x02,  0xAC,  0x08,  0x00,  0x08,  0xFE,  0x08,  0x10,  0x09,  0xFF,  0x7F, 	/* 2CCE0 */
+	0x11,  0x13,  0x77,  0x13,  0x11,  0x12,  0x76,  0x12,  0x00,  0x24,  0xFF,  0x7C,  0x10,  0x06,  0xFE,  0x0A, 	/* 2CCF0 */
+	0xAA,  0x10,  0xAA,  0x60,  0xAA,  0x00,  0x86,  0xB0,  0x00,  0x00,  0x3E,  0x7C,  0x22,  0x44,  0x3E,  0x7C, 	/* 2CD00 */
+	0x22,  0x44,  0x3E,  0x7C,  0x22,  0x44,  0x3E,  0x7C,  0x13,  0x24,  0x21,  0x42,  0x7F,  0xFF,  0x02,  0x20, 	/* 2CD10 */
+	0x04,  0x40,  0x0F,  0xC0,  0x03,  0x60,  0x3C,  0x18,  0xB2,  0x01,  0x00,  0x7D,  0x1F,  0x55,  0x15,  0x55, 	/* 2CD20 */
+	0x15,  0x7F,  0xFF,  0x55,  0x55,  0x55,  0x55,  0x7D,  0x5F,  0x12,  0x44,  0x7E,  0x5F,  0x17,  0x85,  0x14, 	/* 2CD30 */
+	0xC5,  0x24,  0xA9,  0x25,  0x09,  0x46,  0x11,  0x18,  0x26,  0xB6,  0x08,  0x20,  0x08,  0xFC,  0x08,  0x84, 	/* 2CD40 */
+	0x08,  0xFC,  0x7E,  0x84,  0x12,  0xFC,  0x12,  0x84,  0x13,  0xFE,  0x25,  0x22,  0x7D,  0xFE,  0x45,  0x22, 	/* 2CD50 */
+	0x09,  0xFE,  0x08,  0x00,  0x13,  0xFF,  0x60,  0x88,  0x01,  0x08,  0xBE,  0x11,  0x00,  0x11,  0x3F,  0x17, 	/* 2CD60 */
+	0xE9,  0x11,  0x09,  0x7F,  0xD6,  0x15,  0x60,  0x15,  0x5E,  0x25,  0x52,  0x27,  0xDE,  0x79,  0x12,  0x4B, 	/* 2CD70 */
+	0x9E,  0x0B,  0x52,  0x15,  0x3E,  0x25,  0x0C,  0x49,  0x12,  0x01,  0x61,  0x80,  0x10,  0x00,  0x13,  0xFE, 	/* 2CD80 */
+	0x10,  0x10,  0x13,  0xFF,  0x7E,  0x11,  0x17,  0x9D,  0x16,  0xD6,  0x24,  0x00,  0x25,  0x3E,  0x7F,  0xE2, 	/* 2CD90 */
+	0x49,  0x3E,  0x0B,  0xA2,  0x17,  0x7E,  0x65,  0x22,  0x09,  0x3E,  0x01,  0x00,  0x83,  0x08,  0x20,  0x0B, 	/* 2CDA0 */
+	0xFF,  0x08,  0x00,  0x09,  0xFE,  0x7F,  0x32,  0x13,  0xFE,  0x12,  0x48,  0x15,  0xFE,  0x24,  0x48,  0x25, 	/* 2CDB0 */
+	0xFE,  0x7C,  0x48,  0x07,  0xFF,  0x08,  0xD0,  0x13,  0x4A,  0x60,  0x74,  0x01,  0xC3,  0x85,  0x11,  0x28, 	/* 2CDC0 */
+	0x11,  0x2A,  0x12,  0xD9,  0x12,  0x49,  0x7C,  0x88,  0x17,  0xFF,  0x15,  0x48,  0x17,  0x6A,  0x25,  0x4A, 	/* 2CDD0 */
+	0x27,  0x6A,  0x79,  0x44,  0x0F,  0x64,  0x15,  0x5D,  0x21,  0xEB,  0x47,  0x13,  0x00,  0x21,  0x90,  0x00, 	/* 2CDE0 */
+	0x00,  0x1F,  0xF8,  0x00,  0x08,  0x00,  0x10,  0x00,  0x20,  0x00,  0x40,  0x00,  0x80,  0x00,  0x80,  0x7F, 	/* 2CDF0 */
+	0xFF,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x01,  0x80,  0x91, 	/* 2CE00 */
+	0x00,  0x00,  0x1F,  0xF8,  0x00,  0x10,  0x00,  0x20,  0x00,  0x40,  0x00,  0x80,  0x00,  0x82,  0x00,  0x9C, 	/* 2CE10 */
+	0x03,  0xE0,  0x7C,  0x80,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x01,  0x80, 	/* 2CE20 */
+	0x94,  0x00,  0x20,  0x3F,  0xA0,  0x01,  0x20,  0x02,  0x20,  0x04,  0x20,  0x04,  0x20,  0x04,  0xA0,  0x07, 	/* 2CE30 */
+	0x20,  0x0C,  0x20,  0x74,  0x20,  0x04,  0x20,  0x04,  0x20,  0x04,  0x21,  0x04,  0x21,  0x04,  0x1F,  0x0C, 	/* 2CE40 */
+	0x00,  0x95,  0x00,  0x00,  0x3F,  0xF8,  0x01,  0x08,  0x01,  0x08,  0x02,  0x1E,  0x04,  0x02,  0x18,  0x02, 	/* 2CE50 */
+	0x67,  0xF2,  0x00,  0x2C,  0x00,  0x40,  0x00,  0x80,  0x7F,  0xFF,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80, 	/* 2CE60 */
+	0x01,  0x80,  0x97,  0x00,  0x80,  0x00,  0x80,  0x7F,  0xFE,  0x40,  0x02,  0x40,  0x02,  0x0F,  0xF0,  0x00, 	/* 2CE70 */
+	0x20,  0x00,  0xC0,  0x00,  0x80,  0x7F,  0xFF,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x00, 	/* 2CE80 */
+	0x80,  0x01,  0x80,  0x98,  0x01,  0x00,  0x01,  0x00,  0x01,  0x00,  0x7F,  0xFF,  0x02,  0x00,  0x04,  0x00, 	/* 2CE90 */
+	0x15,  0xFC,  0x18,  0x08,  0x10,  0x10,  0x30,  0x20,  0x57,  0xFF,  0x10,  0x20,  0x10,  0x20,  0x10,  0x20, 	/* 2CEA0 */
+	0x10,  0x20,  0x10,  0x60,  0x9A,  0x00,  0x08,  0x00,  0x70,  0x1F,  0x80,  0x10,  0x84,  0x10,  0x42,  0x20, 	/* 2CEB0 */
+	0x41,  0x4F,  0xF8,  0x00,  0x10,  0x00,  0x20,  0x00,  0x40,  0x7F,  0xFF,  0x00,  0x80,  0x00,  0x80,  0x00, 	/* 2CEC0 */
+	0x80,  0x00,  0x80,  0x01,  0x80,  0x9B,  0x00,  0x80,  0x00,  0x80,  0x3F,  0xFC,  0x00,  0x80,  0x00,  0x80, 	/* 2CED0 */
+	0x7F,  0xFE,  0x40,  0x02,  0x40,  0x02,  0x0F,  0xF0,  0x00,  0x60,  0x00,  0x80,  0x7F,  0xFE,  0x00,  0x80, 	/* 2CEE0 */
+	0x00,  0x80,  0x00,  0x80,  0x01,  0x80,  0x9C,  0x00,  0x40,  0x7F,  0x40,  0x02,  0x40,  0x04,  0x7F,  0x08, 	/* 2CEF0 */
+	0x44,  0x08,  0x44,  0x0B,  0x84,  0x0C,  0x84,  0x19,  0x28,  0x68,  0x28,  0x08,  0x10,  0x08,  0x18,  0x08, 	/* 2CF00 */
+	0x28,  0x08,  0x44,  0x08,  0x82,  0x19,  0x01,  0x9D,  0x00,  0x80,  0x00,  0x84,  0x1F,  0xFC,  0x00,  0x88, 	/* 2CF10 */
+	0x00,  0x90,  0x7F,  0xFF,  0x00,  0xC0,  0x03,  0x00,  0x0F,  0xF0,  0x70,  0x20,  0x00,  0x40,  0x3F,  0xFE, 	/* 2CF20 */
+	0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x01,  0x80,  0x9F,  0x00,  0x00,  0x1F,  0xF8,  0x00,  0x10,  0x00, 	/* 2CF30 */
+	0x60,  0x00,  0x80,  0x7F,  0xFF,  0x00,  0x80,  0x00,  0x80,  0x01,  0x80,  0x00,  0x00,  0x1F,  0xFC,  0x12, 	/* 2CF40 */
+	0x24,  0x12,  0x24,  0x12,  0x24,  0x7F,  0xFF,  0x00,  0x00,  0xA3,  0x00,  0x08,  0x00,  0x30,  0x1F,  0xC0, 	/* 2CF50 */
+	0x00,  0x80,  0x7F,  0xFF,  0x01,  0xC0,  0x02,  0xA0,  0x0C,  0x98,  0x70,  0x87,  0x07,  0xF0,  0x00,  0x40, 	/* 2CF60 */
+	0x00,  0x80,  0x7F,  0xFF,  0x00,  0x80,  0x00,  0x80,  0x01,  0x80,  0xA4,  0x00,  0x02,  0x7E,  0x0C,  0x03, 	/* 2CF70 */
+	0xF4,  0x05,  0x04,  0x09,  0x24,  0x09,  0x24,  0x0B,  0x24,  0x0D,  0x24,  0x79,  0x24,  0x09,  0x24,  0x09, 	/* 2CF80 */
+	0x24,  0x09,  0x34,  0x0A,  0x2A,  0x0A,  0x3A,  0x0D,  0xC6,  0x18,  0x01,  0xA5,  0x04,  0x00,  0x04,  0x00, 	/* 2CF90 */
+	0x7F,  0xFE,  0x08,  0xA2,  0x09,  0x24,  0x11,  0x14,  0x3E,  0x18,  0x05,  0x64,  0x18,  0x03,  0x67,  0xF0, 	/* 2CFA0 */
+	0x00,  0x60,  0x00,  0x80,  0x7F,  0xFF,  0x00,  0x80,  0x00,  0x80,  0x01,  0x80,  0xA6,  0x11,  0x08,  0x08, 	/* 2CFB0 */
+	0x88,  0x08,  0x90,  0x7F,  0xFE,  0x40,  0x02,  0x40,  0x02,  0x1F,  0xF0,  0x00,  0x20,  0x00,  0xC0,  0x01, 	/* 2CFC0 */
+	0x00,  0x7F,  0xFE,  0x01,  0x00,  0x01,  0x00,  0x01,  0x00,  0x01,  0x00,  0x03,  0x00,  0xA9,  0x00,  0x20, 	/* 2CFD0 */
+	0x7E,  0x20,  0x02,  0x20,  0x07,  0xFF,  0x08,  0x20,  0x08,  0x28,  0x09,  0xC8,  0x0E,  0x52,  0x78,  0x32, 	/* 2CFE0 */
+	0x08,  0x24,  0x08,  0x44,  0x09,  0x88,  0x08,  0x10,  0x08,  0x28,  0x08,  0xC4,  0x1B,  0x02,  0xAB,  0x00, 	/* 2CFF0 */
+	0x04,  0x7E,  0x18,  0x03,  0xE0,  0x04,  0x20,  0x08,  0x44,  0x09,  0xC8,  0x08,  0x30,  0x0C,  0x28,  0x18, 	/* 2D000 */
+	0x44,  0x6B,  0xFA,  0x08,  0x21,  0x08,  0xA8,  0x08,  0xA4,  0x09,  0x22,  0x0A,  0x22,  0x18,  0x20,  0xB0, 	/* 2D010 */
+	0x08,  0x10,  0x08,  0x10,  0x7F,  0x90,  0x00,  0x10,  0x3E,  0xFC,  0x22,  0x14,  0x3E,  0x14,  0x00,  0x94, 	/* 2D020 */
+	0x7F,  0x54,  0x02,  0x24,  0x04,  0x24,  0x07,  0x34,  0x7C,  0x55,  0x04,  0x55,  0x04,  0x83,  0x0D,  0x01, 	/* 2D030 */
+	0xB1,  0x00,  0x00,  0x1F,  0xFE,  0x10,  0x02,  0x1F,  0xFE,  0x10,  0x00,  0x13,  0xF0,  0x10,  0x20,  0x1F, 	/* 2D040 */
+	0xFE,  0x10,  0x20,  0x10,  0x60,  0x17,  0xBE,  0x11,  0x04,  0x3F,  0xFF,  0x22,  0x08,  0x42,  0x08,  0x06, 	/* 2D050 */
+	0x18,  0xB3,  0x08,  0x08,  0x04,  0x10,  0x7F,  0xFF,  0x04,  0x10,  0x19,  0x64,  0x0A,  0x28,  0x05,  0x14, 	/* 2D060 */
+	0x3E,  0xFA,  0x00,  0x00,  0x0F,  0xF8,  0x00,  0x60,  0x00,  0x80,  0x7F,  0xFF,  0x00,  0x80,  0x00,  0x80, 	/* 2D070 */
+	0x01,  0x80,  0xB5,  0x08,  0x02,  0x33,  0x8C,  0x2A,  0xF2,  0x2A,  0xA9,  0x2A,  0xA9,  0x3B,  0xA1,  0x3B, 	/* 2D080 */
+	0xC0,  0x2B,  0xBE,  0x2A,  0x84,  0x2A,  0x88,  0x3A,  0xFF,  0x6B,  0x88,  0x12,  0x08,  0x12,  0x08,  0x22, 	/* 2D090 */
+	0x08,  0x42,  0x18,  0xB8,  0x04,  0x00,  0x1A,  0xB8,  0x11,  0x08,  0x1E,  0xB8,  0x12,  0x88,  0x1D,  0x38, 	/* 2D0A0 */
+	0x12,  0x88,  0x7F,  0xFE,  0x40,  0x02,  0x4F,  0xF2,  0x00,  0x40,  0x00,  0x80,  0x7F,  0xFE,  0x00,  0x80, 	/* 2D0B0 */
+	0x00,  0x80,  0x01,  0x80,  0xBA,  0x00,  0x00,  0x7D,  0xFE,  0x04,  0x10,  0x0B,  0xFF,  0x1A,  0x11,  0x12, 	/* 2D0C0 */
+	0xDD,  0x12,  0x11,  0x14,  0xDD,  0x18,  0x00,  0x77,  0xFF,  0x10,  0x20,  0x11,  0xFE,  0x11,  0x52,  0x11, 	/* 2D0D0 */
+	0x52,  0x11,  0x52,  0x31,  0x06,  0x80,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x01,  0x00,  0x01,  0x00, 	/* 2D0E0 */
+	0x01,  0x00,  0x7F,  0xFE,  0x40,  0x02,  0x40,  0x02,  0x40,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00, 	/* 2D0F0 */
+	0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x83,  0x01,  0x00,  0x01,  0x00,  0x7F,  0xFE,  0x40,  0x02,  0x48, 	/* 2D100 */
+	0x02,  0x48,  0x00,  0x08,  0x10,  0x08,  0x20,  0x08,  0xC0,  0x0F,  0x00,  0x08,  0x00,  0x08,  0x02,  0x08, 	/* 2D110 */
+	0x02,  0x04,  0x02,  0x03,  0xFE,  0x00,  0x00,  0x85,  0x01,  0x00,  0x01,  0x00,  0x7F,  0xFE,  0x40,  0x02, 	/* 2D120 */
+	0x40,  0x12,  0x40,  0x62,  0x1F,  0x80,  0x02,  0x00,  0x02,  0x0E,  0x03,  0xF0,  0x7E,  0x00,  0x02,  0x00, 	/* 2D130 */
+	0x02,  0x00,  0x02,  0x04,  0x01,  0x04,  0x00,  0xFC,  0x87,  0x01,  0x00,  0x01,  0x00,  0x7F,  0xFE,  0x40, 	/* 2D140 */
+	0x02,  0x40,  0x02,  0x0F,  0xF0,  0x01,  0x00,  0x01,  0x00,  0x01,  0x00,  0x7F,  0xFE,  0x01,  0x00,  0x01, 	/* 2D150 */
+	0x00,  0x01,  0x00,  0x01,  0x00,  0x01,  0x00,  0x03,  0x00,  0x88,  0x01,  0x00,  0x01,  0x00,  0x7F,  0xFE, 	/* 2D160 */
+	0x40,  0x02,  0x40,  0x22,  0x00,  0x20,  0x00,  0x20,  0x7F,  0xFE,  0x00,  0x20,  0x08,  0x20,  0x04,  0x20, 	/* 2D170 */
+	0x04,  0x20,  0x00,  0x20,  0x00,  0x20,  0x00,  0x20,  0x00,  0x60,  0x89,  0x01,  0x00,  0x01,  0x00,  0x7F, 	/* 2D180 */
+	0xFE,  0x42,  0x02,  0x42,  0x02,  0x02,  0x00,  0x02,  0x00,  0x7F,  0xFE,  0x04,  0x40,  0x04,  0x40,  0x08, 	/* 2D190 */
+	0x40,  0x0E,  0x40,  0x01,  0x80,  0x02,  0x60,  0x0C,  0x10,  0x30,  0x08,  0x8B,  0x01,  0x00,  0x01,  0x00, 	/* 2D1A0 */
+	0x7F,  0xFE,  0x40,  0x02,  0x41,  0x02,  0x01,  0x00,  0x01,  0x00,  0x7F,  0xFE,  0x01,  0x00,  0x03,  0x80, 	/* 2D1B0 */
+	0x05,  0x40,  0x09,  0x20,  0x11,  0x18,  0x61,  0x06,  0x01,  0x00,  0x01,  0x00,  0x8C,  0x01,  0x00,  0x01, 	/* 2D1C0 */
+	0x00,  0x7F,  0xFE,  0x40,  0x02,  0x40,  0x02,  0x1F,  0xF8,  0x00,  0x00,  0x00,  0x00,  0x7F,  0xFE,  0x02, 	/* 2D1D0 */
+	0x40,  0x02,  0x40,  0x02,  0x40,  0x04,  0x42,  0x08,  0x42,  0x10,  0x22,  0x60,  0x1E,  0x8D,  0x01,  0x00, 	/* 2D1E0 */
+	0x01,  0x00,  0x01,  0x00,  0x7F,  0xFE,  0x40,  0x02,  0x41,  0x02,  0x41,  0x02,  0x01,  0x00,  0x7F,  0xFE, 	/* 2D1F0 */
+	0x00,  0x00,  0x04,  0x20,  0x04,  0x10,  0x08,  0x08,  0x08,  0x08,  0x10,  0x04,  0x20,  0x04,  0x8F,  0x01, 	/* 2D200 */
+	0x00,  0x01,  0x00,  0x7F,  0xFE,  0x40,  0x02,  0x42,  0x02,  0x02,  0x00,  0x7F,  0xFE,  0x02,  0x00,  0x02, 	/* 2D210 */
+	0x40,  0x04,  0x40,  0x04,  0x80,  0x08,  0x90,  0x11,  0x08,  0x22,  0x38,  0x4F,  0xC4,  0x00,  0x04,  0x95, 	/* 2D220 */
+	0x01,  0x00,  0x01,  0x00,  0x7F,  0xFE,  0x40,  0x02,  0x40,  0x02,  0x00,  0x00,  0x7F,  0xFE,  0x01,  0x00, 	/* 2D230 */
+	0x02,  0x00,  0x04,  0x00,  0x0F,  0xF8,  0x18,  0x08,  0x68,  0x08,  0x08,  0x08,  0x0F,  0xF8,  0x00,  0x00, 	/* 2D240 */
+	0x97,  0x01,  0x00,  0x01,  0x00,  0x7F,  0xFE,  0x40,  0x02,  0x40,  0x02,  0x4F,  0xF2,  0x00,  0x00,  0x00, 	/* 2D250 */
+	0x00,  0x7F,  0xFE,  0x01,  0x00,  0x11,  0x10,  0x11,  0x08,  0x21,  0x04,  0x41,  0x04,  0x01,  0x00,  0x03, 	/* 2D260 */
+	0x00,  0x98,  0x01,  0x00,  0x01,  0x00,  0x7F,  0xFE,  0x40,  0x02,  0x4F,  0xF2,  0x08,  0x10,  0x08,  0x10, 	/* 2D270 */
+	0x0F,  0xF0,  0x08,  0x00,  0x08,  0x00,  0x0F,  0xF8,  0x08,  0x08,  0x08,  0x08,  0x08,  0x08,  0x0F,  0xF8, 	/* 2D280 */
+	0x00,  0x00,  0x99,  0x01,  0x00,  0x01,  0x00,  0x7F,  0xFE,  0x41,  0x02,  0x41,  0x02,  0x01,  0x00,  0x1F, 	/* 2D290 */
+	0xF8,  0x11,  0x08,  0x11,  0x08,  0x11,  0x08,  0x1F,  0xF8,  0x11,  0x08,  0x11,  0x08,  0x11,  0x08,  0x1F, 	/* 2D2A0 */
+	0xF8,  0x00,  0x00,  0x9A,  0x01,  0x00,  0x01,  0x00,  0x7F,  0xFE,  0x40,  0x02,  0x40,  0x02,  0x1F,  0xF8, 	/* 2D2B0 */
+	0x01,  0x00,  0x01,  0x00,  0x09,  0x00,  0x09,  0xF8,  0x09,  0x00,  0x09,  0x00,  0x15,  0x00,  0x13,  0x00, 	/* 2D2C0 */
+	0x21,  0x80,  0x40,  0x7E,  0x9B,  0x00,  0x80,  0x00,  0x80,  0x7F,  0xFE,  0x48,  0x02,  0x48,  0x02,  0x08, 	/* 2D2D0 */
+	0x00,  0x0F,  0x7C,  0x11,  0x44,  0x12,  0x44,  0x2A,  0x44,  0x46,  0x44,  0x04,  0x58,  0x04,  0x40,  0x08, 	/* 2D2E0 */
+	0x42,  0x10,  0x42,  0x60,  0x3E,  0x9C,  0x01,  0x00,  0x01,  0x00,  0x7F,  0xFC,  0x40,  0x04,  0x40,  0x04, 	/* 2D2F0 */
+	0x0F,  0xE0,  0x08,  0x20,  0x08,  0x20,  0x0F,  0xE0,  0x08,  0x20,  0x08,  0x20,  0x0F,  0xE0,  0x08,  0x20, 	/* 2D300 */
+	0x08,  0x20,  0x7F,  0xFE,  0x00,  0x00,  0x9D,  0x01,  0x00,  0x01,  0x00,  0x7F,  0xFE,  0x40,  0x02,  0x40, 	/* 2D310 */
+	0x02,  0x5F,  0xFA,  0x01,  0x00,  0x01,  0x00,  0x01,  0x00,  0x1F,  0xF8,  0x01,  0x00,  0x01,  0x10,  0x01, 	/* 2D320 */
+	0x08,  0x01,  0x08,  0x7F,  0xFE,  0x00,  0x00,  0x9F,  0x01,  0x00,  0x01,  0x00,  0x7F,  0xFE,  0x40,  0x02, 	/* 2D330 */
+	0x41,  0x02,  0x3F,  0xF8,  0x01,  0x00,  0x01,  0x00,  0x1F,  0xF0,  0x01,  0x00,  0x01,  0x00,  0x7F,  0xFE, 	/* 2D340 */
+	0x02,  0x40,  0x04,  0x20,  0x18,  0x18,  0x60,  0x06,  0xA2,  0x01,  0x00,  0x01,  0x00,  0x7F,  0xFE,  0x42, 	/* 2D350 */
+	0x02,  0x43,  0xE2,  0x04,  0x20,  0x0A,  0x40,  0x31,  0x80,  0x02,  0x40,  0x04,  0x20,  0x1F,  0xF8,  0x68, 	/* 2D360 */
+	0x16,  0x08,  0x10,  0x08,  0x10,  0x0F,  0xF0,  0x00,  0x00,  0xA3,  0x01,  0x00,  0x01,  0x00,  0x7F,  0xFE, 	/* 2D370 */
+	0x40,  0x02,  0x5F,  0xFA,  0x00,  0x00,  0x0F,  0xF0,  0x08,  0x10,  0x08,  0x10,  0x0F,  0xF0,  0x08,  0x10, 	/* 2D380 */
+	0x08,  0x10,  0x0F,  0xF0,  0x00,  0x00,  0x7F,  0xFE,  0x00,  0x00,  0xA4,  0x01,  0x00,  0x01,  0x00,  0x7F, 	/* 2D390 */
+	0xFE,  0x40,  0x02,  0x40,  0x02,  0x3F,  0xFC,  0x02,  0x40,  0x04,  0x30,  0x3F,  0xC8,  0x01,  0x04,  0x01, 	/* 2D3A0 */
+	0x00,  0x1F,  0xF8,  0x01,  0x00,  0x01,  0x00,  0x7F,  0xFF,  0x00,  0x00,  0xA5,  0x01,  0x00,  0x01,  0x00, 	/* 2D3B0 */
+	0x7F,  0xFE,  0x42,  0x02,  0x42,  0x02,  0x7F,  0xFC,  0x02,  0x00,  0x04,  0x00,  0x07,  0xF0,  0x0C,  0x10, 	/* 2D3C0 */
+	0x17,  0xF0,  0x24,  0x10,  0x47,  0xF0,  0x04,  0x10,  0x04,  0x10,  0x04,  0x30,  0xA6,  0x01,  0x00,  0x01, 	/* 2D3D0 */
+	0x00,  0x7F,  0xFE,  0x40,  0x02,  0x5F,  0xFA,  0x50,  0x80,  0x10,  0x80,  0x1F,  0xF8,  0x10,  0x08,  0x10, 	/* 2D3E0 */
+	0x08,  0x1F,  0xF8,  0x10,  0x80,  0x10,  0x80,  0x10,  0x80,  0x1F,  0xFC,  0x00,  0x00,  0xAE,  0x01,  0x00, 	/* 2D3F0 */
+	0x01,  0x00,  0x7F,  0xFE,  0x40,  0x02,  0x4F,  0xF2,  0x08,  0x10,  0x08,  0x10,  0x0F,  0xF0,  0x01,  0x00, 	/* 2D400 */
+	0x02,  0x00,  0x1F,  0xF8,  0x10,  0x08,  0x10,  0x08,  0x10,  0x08,  0x1F,  0xF8,  0x00,  0x00,  0xB0,  0x01, 	/* 2D410 */
+	0x00,  0x01,  0x00,  0x7F,  0xFE,  0x40,  0x02,  0x41,  0x02,  0x3F,  0xF8,  0x08,  0x20,  0x04,  0x40,  0x7F, 	/* 2D420 */
+	0xFE,  0x01,  0x00,  0x01,  0x00,  0x3F,  0xFC,  0x01,  0x00,  0x01,  0x00,  0x01,  0x00,  0x01,  0x00,  0xB3, 	/* 2D430 */
+	0x01,  0x00,  0x01,  0x00,  0x7F,  0xFE,  0x41,  0x02,  0x41,  0x02,  0x3F,  0xFC,  0x01,  0x00,  0x1F,  0xF8, 	/* 2D440 */
+	0x01,  0x00,  0x7F,  0xFE,  0x00,  0x00,  0x1F,  0xF8,  0x10,  0x08,  0x10,  0x08,  0x1F,  0xF8,  0x00,  0x00, 	/* 2D450 */
+	0xB4,  0x01,  0x00,  0x01,  0x00,  0x7F,  0xFE,  0x40,  0x02,  0x4F,  0xF2,  0x08,  0x10,  0x0F,  0xF0,  0x08, 	/* 2D460 */
+	0x10,  0x0F,  0xF0,  0x01,  0x00,  0x7F,  0xFE,  0x02,  0x20,  0x04,  0x20,  0x0F,  0xC0,  0x03,  0x30,  0x3C, 	/* 2D470 */
+	0x08,  0xB5,  0x01,  0x00,  0x01,  0x00,  0x7F,  0xFE,  0x41,  0x02,  0x49,  0x22,  0x05,  0x20,  0x05,  0x40, 	/* 2D480 */
+	0x1F,  0xF0,  0x10,  0x10,  0x10,  0x10,  0x1F,  0xF0,  0x10,  0x10,  0x1F,  0xF0,  0x10,  0x10,  0x10,  0x10, 	/* 2D490 */
+	0x10,  0x30,  0xB6,  0x01,  0x00,  0x01,  0x00,  0x7F,  0xFE,  0x40,  0x02,  0x40,  0x02,  0x1F,  0xF0,  0x02, 	/* 2D4A0 */
+	0x04,  0x0D,  0x44,  0x31,  0xC8,  0x02,  0xB0,  0x0C,  0xA0,  0x31,  0x90,  0x02,  0x88,  0x0C,  0x84,  0x70, 	/* 2D4B0 */
+	0x82,  0x03,  0x00,  0xB8,  0x01,  0x00,  0x01,  0x00,  0x7F,  0xFE,  0x40,  0x02,  0x40,  0x02,  0x1F,  0xFC, 	/* 2D4C0 */
+	0x10,  0x00,  0x17,  0xF8,  0x10,  0x00,  0x1F,  0xFE,  0x14,  0x88,  0x14,  0x50,  0x24,  0x20,  0x24,  0x10, 	/* 2D4D0 */
+	0x47,  0x8C,  0x1C,  0x03,  0xB9,  0x01,  0x00,  0x01,  0x00,  0x7F,  0xFE,  0x44,  0x42,  0x44,  0x22,  0x09, 	/* 2D4E0 */
+	0x10,  0x11,  0x90,  0x22,  0x40,  0x04,  0x20,  0x18,  0x18,  0x6F,  0xF6,  0x08,  0x10,  0x08,  0x10,  0x08, 	/* 2D4F0 */
+	0x10,  0x0F,  0xF0,  0x00,  0x00,  0xBF,  0x01,  0x00,  0x01,  0x00,  0x7F,  0xFE,  0x40,  0x02,  0x44,  0x02, 	/* 2D500 */
+	0x07,  0xFC,  0x08,  0x40,  0x08,  0x80,  0x13,  0xF8,  0x32,  0x08,  0x52,  0x08,  0x13,  0xF8,  0x12,  0x08, 	/* 2D510 */
+	0x12,  0x08,  0x13,  0xF8,  0x10,  0x00,  0x82,  0x01,  0x00,  0x01,  0x00,  0x7F,  0xFE,  0x48,  0x02,  0x48, 	/* 2D520 */
+	0x02,  0x0F,  0x00,  0x08,  0xFC,  0x08,  0x44,  0x7F,  0xC4,  0x08,  0x28,  0x1A,  0x28,  0x1A,  0x10,  0x29, 	/* 2D530 */
+	0x10,  0x49,  0x28,  0x08,  0x44,  0x19,  0x83,  0x83,  0x01,  0x00,  0x01,  0x00,  0x7F,  0xFE,  0x41,  0x02, 	/* 2D540 */
+	0x43,  0xE2,  0x04,  0x40,  0x18,  0x80,  0x7F,  0xF8,  0x11,  0x08,  0x11,  0x08,  0x1F,  0xF8,  0x02,  0xA0, 	/* 2D550 */
+	0x02,  0x90,  0x04,  0x8A,  0x18,  0x82,  0x60,  0x7E,  0x84,  0x01,  0x00,  0x01,  0x00,  0x7F,  0xFE,  0x41, 	/* 2D560 */
+	0x02,  0x5F,  0xFA,  0x01,  0x80,  0x02,  0x40,  0x0C,  0x30,  0x7F,  0xFE,  0x00,  0x10,  0x1F,  0x90,  0x10, 	/* 2D570 */
+	0x90,  0x10,  0x90,  0x1F,  0x90,  0x00,  0x10,  0x00,  0x30,  0x85,  0x01,  0x00,  0x01,  0x00,  0x7F,  0xFE, 	/* 2D580 */
+	0x40,  0x02,  0x5F,  0xFA,  0x01,  0x00,  0x1F,  0xF8,  0x11,  0x08,  0x11,  0x08,  0x1F,  0xF8,  0x11,  0x08, 	/* 2D590 */
+	0x11,  0x08,  0x1F,  0xF8,  0x04,  0x20,  0x18,  0x18,  0x60,  0x04,  0x86,  0x01,  0x00,  0x01,  0x00,  0x7F, 	/* 2D5A0 */
+	0xFE,  0x41,  0x02,  0x44,  0xA2,  0x14,  0xA0,  0x14,  0x48,  0x24,  0x94,  0x43,  0x12,  0x1D,  0xF2,  0x01, 	/* 2D5B0 */
+	0x00,  0x21,  0x08,  0x21,  0x08,  0x21,  0x08,  0x3F,  0xF8,  0x00,  0x00,  0x87,  0x01,  0x00,  0x01,  0x00, 	/* 2D5C0 */
+	0x7F,  0xFE,  0x40,  0x02,  0x40,  0x22,  0x3E,  0x22,  0x00,  0x3C,  0x00,  0x20,  0x7F,  0xF8,  0x14,  0x88, 	/* 2D5D0 */
+	0x14,  0x50,  0x14,  0x20,  0x14,  0xD2,  0x17,  0x0E,  0x22,  0x02,  0x41,  0xFE,  0x89,  0x01,  0x00,  0x01, 	/* 2D5E0 */
+	0x00,  0x7F,  0xFE,  0x44,  0x02,  0x44,  0x22,  0x08,  0x40,  0x1F,  0xFC,  0x10,  0x80,  0x30,  0x80,  0x5F, 	/* 2D5F0 */
+	0xF8,  0x10,  0x80,  0x1F,  0xF8,  0x10,  0x80,  0x10,  0x80,  0x1F,  0xFE,  0x10,  0x00,  0x8C,  0x01,  0x00, 	/* 2D600 */
+	0x01,  0x00,  0x7F,  0xFE,  0x40,  0x02,  0x5F,  0xFA,  0x00,  0x00,  0x0F,  0xF0,  0x08,  0x10,  0x0F,  0xF0, 	/* 2D610 */
+	0x00,  0x00,  0x1F,  0xF8,  0x11,  0x08,  0x1F,  0xF8,  0x11,  0x08,  0x1F,  0xF8,  0x00,  0x00,  0x90,  0x01, 	/* 2D620 */
+	0x00,  0x01,  0x00,  0x7F,  0xFE,  0x40,  0x02,  0x44,  0x22,  0x24,  0x20,  0x25,  0xFC,  0x24,  0x20,  0x3C, 	/* 2D630 */
+	0x20,  0x07,  0xFF,  0x04,  0x70,  0x7C,  0xA8,  0x25,  0x24,  0x26,  0x23,  0x44,  0x20,  0x04,  0x60,  0x92, 	/* 2D640 */
+	0x01,  0x00,  0x01,  0x00,  0x7F,  0xFE,  0x40,  0x02,  0x44,  0x42,  0x1F,  0xF8,  0x04,  0x40,  0x1F,  0xF8, 	/* 2D650 */
+	0x04,  0x40,  0x7F,  0xFE,  0x04,  0x20,  0x19,  0x98,  0x60,  0x46,  0x0F,  0x00,  0x00,  0xE0,  0x00,  0x10, 	/* 2D660 */
+	0x93,  0x01,  0x00,  0x01,  0x00,  0x7F,  0xFE,  0x40,  0x02,  0x4F,  0xF2,  0x09,  0x10,  0x0F,  0xF0,  0x09, 	/* 2D670 */
+	0x10,  0x0F,  0xF0,  0x01,  0x00,  0x3F,  0xFC,  0x21,  0x44,  0x21,  0x34,  0x3F,  0xCC,  0x20,  0x04,  0x20, 	/* 2D680 */
+	0x0C,  0x94,  0x00,  0x80,  0x00,  0x80,  0x3F,  0xFE,  0x20,  0x02,  0x27,  0xF2,  0x04,  0x10,  0x07,  0xF0, 	/* 2D690 */
+	0x04,  0x10,  0x07,  0xF0,  0x00,  0x00,  0x7F,  0xFF,  0x04,  0x80,  0x04,  0xFC,  0x0C,  0x80,  0x13,  0x80, 	/* 2D6A0 */
+	0x60,  0xFF,  0x9B,  0x01,  0x00,  0x01,  0x00,  0x7F,  0xFE,  0x44,  0x22,  0x5F,  0xFA,  0x04,  0x20,  0x0F, 	/* 2D6B0 */
+	0xF0,  0x08,  0x10,  0x0F,  0xF0,  0x08,  0x10,  0x0F,  0xF0,  0x08,  0x10,  0x0F,  0xF2,  0x02,  0x42,  0x0C, 	/* 2D6C0 */
+	0x42,  0x70,  0x3E,  0x9D,  0x01,  0x00,  0x01,  0x00,  0x7F,  0xFE,  0x40,  0x02,  0x49,  0xFA,  0x08,  0x08, 	/* 2D6D0 */
+	0x49,  0xF8,  0x28,  0x08,  0x29,  0xF8,  0x0F,  0xFE,  0x1C,  0x02,  0x2D,  0xFA,  0x48,  0x90,  0x08,  0x60, 	/* 2D6E0 */
+	0x08,  0xD8,  0x0F,  0x06,  0x9E,  0x00,  0x80,  0x00,  0x80,  0x7F,  0xFE,  0x44,  0x22,  0x5F,  0xFA,  0x04, 	/* 2D6F0 */
+	0x20,  0x0F,  0xF0,  0x08,  0x10,  0x0F,  0xF0,  0x08,  0x10,  0x0F,  0xF0,  0x00,  0x80,  0x7F,  0xFE,  0x01, 	/* 2D700 */
+	0x40,  0x06,  0x30,  0x78,  0x0F,  0x9F,  0x01,  0x00,  0x01,  0x00,  0x7F,  0xFE,  0x44,  0x02,  0x4F,  0xFE, 	/* 2D710 */
+	0x11,  0x48,  0x6A,  0x30,  0x04,  0x50,  0x19,  0x88,  0x67,  0xE6,  0x00,  0x00,  0x3F,  0xFC,  0x05,  0x60, 	/* 2D720 */
+	0x19,  0x18,  0x61,  0x04,  0x03,  0x00,  0xA1,  0x01,  0x00,  0x01,  0x00,  0x7F,  0xFE,  0x40,  0x02,  0x5F, 	/* 2D730 */
+	0xFA,  0x01,  0x00,  0x0F,  0xF0,  0x08,  0x10,  0x0F,  0xF0,  0x08,  0x10,  0x7F,  0xFE,  0x04,  0x10,  0x1F, 	/* 2D740 */
+	0xFC,  0x61,  0x13,  0x06,  0x10,  0x18,  0x60,  0xA2,  0x01,  0x00,  0x01,  0x00,  0x7F,  0xFE,  0x40,  0x02, 	/* 2D750 */
+	0x64,  0xFA,  0x24,  0x08,  0x25,  0xFE,  0x3C,  0x08,  0x07,  0xFE,  0x06,  0x02,  0x7D,  0xF8,  0x24,  0x88, 	/* 2D760 */
+	0x24,  0x50,  0x24,  0x20,  0x44,  0xD8,  0x07,  0x07,  0xA4,  0x01,  0x00,  0x01,  0x00,  0x7F,  0xFE,  0x44, 	/* 2D770 */
+	0x02,  0x45,  0xFC,  0x24,  0x40,  0x27,  0xF8,  0x24,  0x88,  0x3C,  0x88,  0x07,  0xFF,  0x04,  0x00,  0x7D, 	/* 2D780 */
+	0xFC,  0x25,  0x04,  0x25,  0x04,  0x45,  0xFC,  0x04,  0x00,  0xA5,  0x00,  0x80,  0x00,  0x80,  0x7F,  0xFE, 	/* 2D790 */
+	0x40,  0x02,  0x5E,  0xFA,  0x0A,  0x28,  0x36,  0xD8,  0x0A,  0xA8,  0x33,  0x48,  0x06,  0x60,  0x19,  0x98, 	/* 2D7A0 */
+	0x6E,  0x47,  0x01,  0x90,  0x1E,  0x60,  0x01,  0x80,  0x1E,  0x00,  0xA6,  0x00,  0x80,  0x7F,  0xFE,  0x40, 	/* 2D7B0 */
+	0x02,  0x47,  0xFA,  0x04,  0x88,  0x3F,  0xFE,  0x11,  0x10,  0x1F,  0xF8,  0x08,  0x08,  0x0F,  0xF8,  0x08, 	/* 2D7C0 */
+	0x08,  0x0F,  0xF8,  0x08,  0x08,  0x0F,  0xF8,  0x06,  0x18,  0x38,  0x06,  0xA7,  0x01,  0x00,  0x01,  0x00, 	/* 2D7D0 */
+	0x7F,  0xFE,  0x45,  0x02,  0x54,  0x8A,  0x12,  0x24,  0x21,  0xE2,  0x5F,  0xFA,  0x12,  0x48,  0x1F,  0xF8, 	/* 2D7E0 */
+	0x00,  0x00,  0x7F,  0xFE,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x01,  0x80,  0xA8,  0x00,  0x80,  0x00, 	/* 2D7F0 */
+	0x80,  0x3F,  0xFE,  0x22,  0x22,  0x2F,  0xFA,  0x02,  0x20,  0x0F,  0xF8,  0x02,  0x20,  0x7F,  0xFF,  0x04, 	/* 2D800 */
+	0x90,  0x18,  0x8C,  0x6F,  0xFB,  0x02,  0xA0,  0x0C,  0x98,  0x70,  0x87,  0x00,  0x80,  0xA9,  0x01,  0x00, 	/* 2D810 */
+	0x01,  0x00,  0x3F,  0xFE,  0x20,  0x32,  0x2F,  0xCA,  0x04,  0x88,  0x02,  0x90,  0x7F,  0xFF,  0x02,  0xA0, 	/* 2D820 */
+	0x04,  0x90,  0x1F,  0xFC,  0x68,  0x8B,  0x0F,  0xF8,  0x08,  0x88,  0x0F,  0xF8,  0x00,  0x00,  0xAB,  0x01, 	/* 2D830 */
+	0x00,  0x01,  0x00,  0x7F,  0xFE,  0x41,  0x02,  0x4E,  0x72,  0x08,  0x10,  0x0E,  0x70,  0x08,  0x10,  0x0F, 	/* 2D840 */
+	0xF0,  0x04,  0x00,  0x0F,  0xFC,  0x10,  0x24,  0x64,  0x94,  0x12,  0x54,  0x12,  0x44,  0x20,  0x18,  0xAE, 	/* 2D850 */
+	0x01,  0x00,  0x7F,  0xFE,  0x41,  0x02,  0x01,  0x00,  0x7F,  0xFE,  0x22,  0x44,  0x14,  0x28,  0x1F,  0xF8, 	/* 2D860 */
+	0x68,  0x16,  0x0F,  0xF0,  0x08,  0x10,  0x0F,  0xF0,  0x05,  0x60,  0x19,  0x18,  0x61,  0x04,  0x03,  0x00, 	/* 2D870 */
+	0xB0,  0x01,  0x00,  0x7F,  0xFE,  0x40,  0x02,  0x5F,  0xFA,  0x12,  0x48,  0x1F,  0xF8,  0x00,  0x00,  0x7F, 	/* 2D880 */
+	0xFE,  0x00,  0x00,  0x1F,  0xF8,  0x10,  0x08,  0x1F,  0xFC,  0x02,  0x84,  0x0E,  0x68,  0x73,  0x98,  0x0E, 	/* 2D890 */
+	0x07,  0xB3,  0x01,  0x00,  0x7F,  0xFE,  0x40,  0x42,  0x3E,  0x7E,  0x08,  0x90,  0x3E,  0x54,  0x08,  0x92, 	/* 2D8A0 */
+	0x1F,  0xF2,  0x68,  0x10,  0x0F,  0xF0,  0x08,  0x10,  0x0F,  0xF0,  0x08,  0x10,  0x0F,  0xF0,  0x06,  0x30, 	/* 2D8B0 */
+	0x38,  0x0C,  0xB5,  0x01,  0x00,  0x7F,  0xFE,  0x48,  0x42,  0x7F,  0x7A,  0x22,  0x40,  0x14,  0x7C,  0x7F, 	/* 2D8C0 */
+	0x84,  0x00,  0x7C,  0x3E,  0x40,  0x22,  0x7C,  0x3E,  0x40,  0x22,  0x7C,  0x3E,  0x40,  0x22,  0x7C,  0x22, 	/* 2D8D0 */
+	0x42,  0x26,  0x3E,  0xB6,  0x01,  0x00,  0x7F,  0xFE,  0x40,  0x42,  0x3E,  0x7C,  0x08,  0x90,  0x3E,  0x7C, 	/* 2D8E0 */
+	0x08,  0x92,  0x1F,  0xFE,  0x68,  0x10,  0x0F,  0xF0,  0x08,  0x10,  0x0F,  0xF0,  0x08,  0x10,  0x0F,  0xF0, 	/* 2D8F0 */
+	0x06,  0x30,  0x38,  0x0C,  0xB8,  0x00,  0x10,  0x00,  0x10,  0x00,  0x10,  0x00,  0x10,  0x3F,  0xFF,  0x00, 	/* 2D900 */
+	0x10,  0x00,  0x10,  0x08,  0x10,  0x04,  0x10,  0x02,  0x10,  0x02,  0x10,  0x00,  0x10,  0x00,  0x10,  0x00, 	/* 2D910 */
+	0x10,  0x00,  0x10,  0x00,  0x30,  0xBA,  0x00,  0x80,  0x00,  0x80,  0x1F,  0xFC,  0x00,  0x80,  0x00,  0x80, 	/* 2D920 */
+	0x00,  0x80,  0x7F,  0xFF,  0x00,  0x10,  0x00,  0x10,  0x3F,  0xFE,  0x08,  0x10,  0x04,  0x10,  0x02,  0x10, 	/* 2D930 */
+	0x02,  0x10,  0x00,  0x10,  0x00,  0x30,  0xBE,  0x04,  0x04,  0x04,  0x04,  0x04,  0x04,  0x7F,  0xC4,  0x01, 	/* 2D940 */
+	0x7F,  0x01,  0x04,  0x11,  0x04,  0x0A,  0x44,  0x06,  0x24,  0x02,  0x14,  0x05,  0x14,  0x09,  0x04,  0x08, 	/* 2D950 */
+	0x84,  0x10,  0x84,  0x20,  0x04,  0x40,  0x0C,  0xBF,  0x01,  0x00,  0x01,  0x00,  0x3F,  0xFE,  0x01,  0x00, 	/* 2D960 */
+	0x1F,  0xF8,  0x01,  0x00,  0x7F,  0xFE,  0x02,  0x10,  0x02,  0x10,  0x7F,  0xFF,  0x04,  0x10,  0x05,  0x10, 	/* 2D970 */
+	0x08,  0x90,  0x10,  0x90,  0x20,  0x10,  0x00,  0x30,  0x81,  0x04,  0x04,  0x04,  0x04,  0x3F,  0x84,  0x04, 	/* 2D980 */
+	0x04,  0x04,  0x7F,  0x04,  0x04,  0x7F,  0x84,  0x04,  0x44,  0x04,  0x24,  0x3F,  0xA4,  0x04,  0x24,  0x04, 	/* 2D990 */
+	0x04,  0x05,  0x84,  0x0E,  0x04,  0x70,  0x04,  0x00,  0x0C,  0x82,  0x00,  0x80,  0x7F,  0xFE,  0x00,  0x80, 	/* 2D9A0 */
+	0x1F,  0xF8,  0x10,  0x88,  0x1F,  0xF8,  0x10,  0x88,  0x10,  0x88,  0x1F,  0xF8,  0x00,  0x20,  0x7F,  0xFF, 	/* 2D9B0 */
+	0x04,  0x20,  0x02,  0x20,  0x02,  0x20,  0x00,  0x20,  0x00,  0x60,  0x84,  0x02,  0x04,  0x04,  0x04,  0x1F, 	/* 2D9C0 */
+	0x04,  0x11,  0x04,  0x11,  0xFF,  0x1F,  0x04,  0x11,  0x04,  0x1F,  0x64,  0x11,  0x94,  0x1F,  0x14,  0x71, 	/* 2D9D0 */
+	0x04,  0x03,  0x04,  0x05,  0x04,  0x19,  0x04,  0x61,  0x04,  0x03,  0x0C,  0x85,  0x04,  0x04,  0x04,  0x04, 	/* 2D9E0 */
+	0x7F,  0xC4,  0x04,  0x04,  0x04,  0x7F,  0x3F,  0x04,  0x21,  0x04,  0x21,  0x44,  0x3F,  0x24,  0x0A,  0x24, 	/* 2D9F0 */
+	0x0A,  0x04,  0x0A,  0x04,  0x12,  0x05,  0x12,  0x0D,  0x21,  0x01,  0x40,  0xFF,  0x86,  0x08,  0x04,  0x08, 	/* 2DA00 */
+	0x38,  0x4B,  0xC2,  0x28,  0x22,  0x29,  0x14,  0x28,  0x94,  0x08,  0x88,  0x08,  0x08,  0x1B,  0xFF,  0x29, 	/* 2DA10 */
+	0x08,  0x28,  0x88,  0x48,  0x88,  0x08,  0x08,  0x08,  0x08,  0x08,  0x08,  0x08,  0x18,  0x87,  0x04,  0x20, 	/* 2DA20 */
+	0x24,  0x3C,  0x24,  0x44,  0x24,  0xA8,  0x25,  0x50,  0x3C,  0x20,  0x04,  0xC0,  0x07,  0x08,  0x7C,  0x08, 	/* 2DA30 */
+	0x27,  0xFF,  0x24,  0x08,  0x24,  0x88,  0x24,  0x48,  0x24,  0x48,  0x44,  0x08,  0x04,  0x18,  0x88,  0x00, 	/* 2DA40 */
+	0x80,  0x7F,  0xFF,  0x00,  0x80,  0x0F,  0xF8,  0x08,  0x88,  0x0F,  0xF8,  0x08,  0x88,  0x0F,  0xF8,  0x00, 	/* 2DA50 */
+	0x88,  0x01,  0xF4,  0x3E,  0x02,  0x00,  0x08,  0x7F,  0xFF,  0x04,  0x08,  0x02,  0x08,  0x00,  0x18,  0x89, 	/* 2DA60 */
+	0x00,  0x04,  0x3F,  0x84,  0x20,  0x84,  0x20,  0x84,  0x3F,  0x84,  0x20,  0x7F,  0x2F,  0x04,  0x20,  0x04, 	/* 2DA70 */
+	0x20,  0x24,  0x3F,  0x94,  0x22,  0x14,  0x2B,  0x04,  0x2A,  0x84,  0x2A,  0x84,  0x52,  0x04,  0x06,  0x0C, 	/* 2DA80 */
+	0x8A,  0x08,  0x10,  0x04,  0x20,  0x7F,  0xFE,  0x02,  0x40,  0x1F,  0xF8,  0x12,  0x48,  0x14,  0x48,  0x1F, 	/* 2DA90 */
+	0xF8,  0x10,  0x08,  0x1F,  0xF8,  0x00,  0x20,  0x7F,  0xFE,  0x08,  0x20,  0x04,  0x20,  0x04,  0x20,  0x00, 	/* 2DAA0 */
+	0x60,  0x8B,  0x00,  0x00,  0x0F,  0xF0,  0x00,  0x10,  0x07,  0xF0,  0x00,  0x10,  0x0F,  0xF0,  0x00,  0x3E, 	/* 2DAB0 */
+	0x3F,  0xA2,  0x04,  0x22,  0x07,  0xBE,  0x38,  0x10,  0x7F,  0xFF,  0x04,  0x10,  0x02,  0x10,  0x02,  0x10, 	/* 2DAC0 */
+	0x00,  0x30,  0x8D,  0x0A,  0x04,  0x4A,  0x84,  0x2B,  0x04,  0x0A,  0x04,  0x7F,  0xFF,  0x00,  0x04,  0x11, 	/* 2DAD0 */
+	0x04,  0x0A,  0x44,  0x7F,  0xA4,  0x04,  0x24,  0x04,  0x04,  0x3F,  0x84,  0x04,  0x04,  0x07,  0x84,  0x0C, 	/* 2DAE0 */
+	0x04,  0x70,  0x0C,  0x8E,  0x00,  0x88,  0x27,  0xFF,  0x10,  0x40,  0x11,  0xFC,  0x01,  0x04,  0x79,  0xFC, 	/* 2DAF0 */
+	0x09,  0x04,  0x09,  0xFC,  0x09,  0x04,  0x17,  0x04,  0x21,  0xFF,  0x40,  0x08,  0x7F,  0xFF,  0x04,  0x08, 	/* 2DB00 */
+	0x02,  0x08,  0x00,  0x18,  0x8F,  0x01,  0x00,  0x01,  0x00,  0x01,  0x00,  0x01,  0x00,  0x01,  0x00,  0x09, 	/* 2DB10 */
+	0x20,  0x09,  0x10,  0x09,  0x08,  0x11,  0x08,  0x11,  0x04,  0x21,  0x04,  0x41,  0x04,  0x01,  0x00,  0x01, 	/* 2DB20 */
+	0x00,  0x01,  0x00,  0x03,  0x00,  0x91,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x04,  0x90,  0x04,  0x88, 	/* 2DB30 */
+	0x08,  0x84,  0x08,  0x84,  0x10,  0x8A,  0x20,  0x8A,  0x40,  0x90,  0x01,  0x90,  0x00,  0x20,  0x00,  0x40, 	/* 2DB40 */
+	0x01,  0x80,  0x06,  0x00,  0x38,  0x00,  0x93,  0x08,  0x00,  0x08,  0x00,  0x08,  0x00,  0x0F,  0xFF,  0x10, 	/* 2DB50 */
+	0x80,  0x10,  0x80,  0x20,  0x80,  0x44,  0x90,  0x04,  0x88,  0x04,  0x84,  0x08,  0x84,  0x08,  0x82,  0x10, 	/* 2DB60 */
+	0x82,  0x20,  0x82,  0x00,  0x80,  0x01,  0x80,  0x96,  0x00,  0x80,  0x00,  0x80,  0x02,  0xA0,  0x04,  0x98, 	/* 2DB70 */
+	0x08,  0x84,  0x30,  0x82,  0x00,  0x80,  0x01,  0x80,  0x00,  0x00,  0x00,  0x80,  0x7F,  0xFF,  0x00,  0x80, 	/* 2DB80 */
+	0x01,  0x40,  0x02,  0x20,  0x0C,  0x18,  0x70,  0x07,  0x9A,  0x00,  0x80,  0x10,  0x88,  0x08,  0x88,  0x04, 	/* 2DB90 */
+	0x90,  0x04,  0xA0,  0x3F,  0xFE,  0x20,  0x02,  0x20,  0x02,  0x27,  0xF2,  0x24,  0x12,  0x24,  0x12,  0x24, 	/* 2DBA0 */
+	0x12,  0x27,  0xF2,  0x20,  0x02,  0x20,  0x02,  0x20,  0x06,  0xA0,  0x11,  0x08,  0x11,  0x08,  0x7F,  0x88, 	/* 2DBB0 */
+	0x11,  0x2C,  0x1F,  0x2A,  0x11,  0x2A,  0x1F,  0x49,  0x11,  0x09,  0x7F,  0xC8,  0x2A,  0x1A,  0x2A,  0x82, 	/* 2DBC0 */
+	0x29,  0x84,  0x30,  0x04,  0x20,  0x08,  0x3F,  0xB0,  0x00,  0xC0,  0xA2,  0x00,  0x80,  0x00,  0x80,  0x00, 	/* 2DBD0 */
+	0x80,  0x00,  0x80,  0x3F,  0xFF,  0x00,  0x80,  0x00,  0xC0,  0x00,  0xA0,  0x00,  0xA0,  0x01,  0x20,  0x01, 	/* 2DBE0 */
+	0x20,  0x02,  0x20,  0x02,  0x21,  0x04,  0x21,  0x18,  0x11,  0x60,  0x0F,  0xA4,  0x01,  0x00,  0x01,  0x10, 	/* 2DBF0 */
+	0x01,  0x08,  0x01,  0x08,  0x7F,  0xFF,  0x01,  0x00,  0x01,  0x00,  0x01,  0x80,  0x01,  0x40,  0x01,  0x40, 	/* 2DC00 */
+	0x01,  0x40,  0x02,  0x40,  0x02,  0x42,  0x04,  0x42,  0x18,  0x42,  0x60,  0x3E,  0xA8,  0x08,  0x08,  0x0A, 	/* 2DC10 */
+	0x08,  0x09,  0x08,  0x08,  0x12,  0x7F,  0xD2,  0x08,  0x24,  0x08,  0x45,  0x0C,  0x89,  0x0A,  0x12,  0x0A, 	/* 2DC20 */
+	0x22,  0x0A,  0x44,  0x12,  0x08,  0x12,  0x10,  0x12,  0x21,  0x21,  0x01,  0x40,  0xFF,  0xAD,  0x01,  0x00, 	/* 2DC30 */
+	0x01,  0x00,  0x3F,  0xF8,  0x01,  0x00,  0x09,  0x10,  0x08,  0x10,  0x7F,  0xFE,  0x08,  0x10,  0x08,  0x10, 	/* 2DC40 */
+	0x00,  0x00,  0x7F,  0xFE,  0x02,  0x40,  0x02,  0x40,  0x04,  0x42,  0x08,  0x42,  0x30,  0x3E,  0xB1,  0x04, 	/* 2DC50 */
+	0x14,  0x04,  0x12,  0x04,  0x12,  0x7F,  0x90,  0x00,  0x7F,  0x3F,  0x10,  0x21,  0x10,  0x21,  0x18,  0x3F, 	/* 2DC60 */
+	0x18,  0x04,  0x28,  0x15,  0x28,  0x14,  0xA8,  0x14,  0xA8,  0x24,  0x49,  0x44,  0x49,  0x0C,  0x87,  0xB8, 	/* 2DC70 */
+	0x00,  0x00,  0x0F,  0xFE,  0x08,  0x02,  0x08,  0x02,  0x08,  0x02,  0x0F,  0xFE,  0x08,  0x00,  0x08,  0x00, 	/* 2DC80 */
+	0x08,  0x00,  0x08,  0x00,  0x08,  0x00,  0x08,  0x00,  0x10,  0x00,  0x10,  0x00,  0x20,  0x00,  0x40,  0x00, 	/* 2DC90 */
+	0xB9,  0x00,  0x00,  0x1F,  0xFC,  0x00,  0x84,  0x00,  0x84,  0x00,  0x84,  0x7F,  0xFF,  0x00,  0x84,  0x00, 	/* 2DCA0 */
+	0x84,  0x00,  0x84,  0x1F,  0xFC,  0x00,  0x80,  0x00,  0x80,  0x01,  0x00,  0x02,  0x00,  0x0C,  0x00,  0x30, 	/* 2DCB0 */
+	0x00,  0xBA,  0x00,  0x00,  0x07,  0xFC,  0x04,  0x04,  0x04,  0x04,  0x04,  0x04,  0x04,  0x04,  0x07,  0xFC, 	/* 2DCC0 */
+	0x04,  0x80,  0x04,  0x80,  0x04,  0x80,  0x08,  0x40,  0x08,  0x40,  0x08,  0x20,  0x10,  0x10,  0x20,  0x0C, 	/* 2DCD0 */
+	0x40,  0x03,  0xBB,  0x00,  0x00,  0x1F,  0xFC,  0x10,  0x04,  0x10,  0x04,  0x1F,  0xFC,  0x11,  0x00,  0x11, 	/* 2DCE0 */
+	0x00,  0x11,  0x00,  0x1F,  0xF0,  0x11,  0x10,  0x11,  0x10,  0x11,  0x12,  0x22,  0x12,  0x22,  0x12,  0x44, 	/* 2DCF0 */
+	0x0E,  0x08,  0x00,  0xBC,  0x00,  0x00,  0x1F,  0xFE,  0x10,  0x02,  0x10,  0x02,  0x10,  0x02,  0x1F,  0xFE, 	/* 2DD00 */
+	0x12,  0x02,  0x12,  0x00,  0x12,  0x04,  0x12,  0x38,  0x13,  0xC0,  0x12,  0x00,  0x22,  0x02,  0x22,  0x02, 	/* 2DD10 */
+	0x41,  0x02,  0x00,  0xFE,  0xBD,  0x00,  0x00,  0x0F,  0xFC,  0x08,  0x04,  0x08,  0x04,  0x08,  0x04,  0x0F, 	/* 2DD20 */
+	0xFC,  0x08,  0x80,  0x08,  0x40,  0x0B,  0x20,  0x10,  0x90,  0x10,  0x4C,  0x20,  0x03,  0x47,  0x00,  0x00, 	/* 2DD30 */
+	0xC0,  0x00,  0x20,  0x00,  0x10,  0xBE,  0x00,  0x00,  0x1F,  0xFC,  0x10,  0x04,  0x10,  0x04,  0x1F,  0xFC, 	/* 2DD40 */
+	0x10,  0x10,  0x10,  0xE0,  0x17,  0x80,  0x10,  0x9C,  0x1F,  0xE0,  0x10,  0x80,  0x10,  0xFE,  0x1F,  0x80, 	/* 2DD50 */
+	0x20,  0x82,  0x20,  0x82,  0x40,  0x7E,  0xBF,  0x00,  0x00,  0x1F,  0xFC,  0x10,  0x04,  0x10,  0x04,  0x1F, 	/* 2DD60 */
+	0xFC,  0x10,  0x40,  0x10,  0x40,  0x10,  0x44,  0x1F,  0x64,  0x11,  0x68,  0x11,  0x50,  0x12,  0x50,  0x22, 	/* 2DD70 */
+	0x48,  0x24,  0x44,  0x48,  0x43,  0x00,  0xC0,  0x80,  0x00,  0x00,  0x1F,  0xFC,  0x10,  0x04,  0x10,  0x04, 	/* 2DD80 */
+	0x1F,  0xFC,  0x10,  0x00,  0x10,  0x00,  0x1F,  0xFE,  0x10,  0x02,  0x13,  0xF2,  0x12,  0x12,  0x12,  0x12, 	/* 2DD90 */
+	0x13,  0xF2,  0x20,  0x02,  0x20,  0x04,  0x40,  0x18,  0x81,  0x00,  0x00,  0x1F,  0xFE,  0x10,  0x02,  0x10, 	/* 2DDA0 */
+	0x02,  0x1F,  0xFE,  0x10,  0x00,  0x12,  0x10,  0x12,  0x10,  0x12,  0x12,  0x13,  0xD4,  0x12,  0x18,  0x12, 	/* 2DDB0 */
+	0x10,  0x22,  0x10,  0x22,  0xD1,  0x47,  0x11,  0x18,  0x0F,  0x85,  0x00,  0x00,  0x1F,  0xFC,  0x10,  0x04, 	/* 2DDC0 */
+	0x10,  0x04,  0x1F,  0xFC,  0x10,  0x40,  0x10,  0x40,  0x1F,  0xFF,  0x10,  0x40,  0x10,  0x40,  0x17,  0xFC, 	/* 2DDD0 */
+	0x14,  0x04,  0x24,  0x04,  0x24,  0x04,  0x47,  0xFC,  0x00,  0x00,  0x86,  0x00,  0x00,  0x1F,  0xFE,  0x10, 	/* 2DDE0 */
+	0x02,  0x10,  0x02,  0x1F,  0xFE,  0x10,  0x00,  0x10,  0x20,  0x14,  0x22,  0x17,  0xFE,  0x14,  0x22,  0x14, 	/* 2DDF0 */
+	0x22,  0x14,  0x22,  0x25,  0xFA,  0x24,  0x02,  0x47,  0xFE,  0x00,  0x00,  0x88,  0x00,  0x00,  0x1F,  0xFC, 	/* 2DE00 */
+	0x10,  0x04,  0x10,  0x04,  0x1F,  0xFC,  0x10,  0x80,  0x14,  0x88,  0x14,  0x88,  0x14,  0x88,  0x17,  0xF8, 	/* 2DE10 */
+	0x10,  0x80,  0x18,  0x84,  0x28,  0x84,  0x28,  0x84,  0x4F,  0xFC,  0x00,  0x00,  0x8A,  0x00,  0x00,  0x1F, 	/* 2DE20 */
+	0xFE,  0x10,  0x02,  0x10,  0x02,  0x1F,  0xFE,  0x10,  0x40,  0x10,  0x40,  0x17,  0xFE,  0x14,  0x42,  0x14, 	/* 2DE30 */
+	0x42,  0x14,  0x42,  0x17,  0xFE,  0x24,  0x42,  0x24,  0x42,  0x47,  0xFE,  0x00,  0x00,  0x8B,  0x00,  0x00, 	/* 2DE40 */
+	0x1F,  0xFC,  0x10,  0x04,  0x10,  0x04,  0x1F,  0xFC,  0x10,  0x00,  0x1F,  0xFE,  0x10,  0xB0,  0x13,  0x0C, 	/* 2DE50 */
+	0x1F,  0xFA,  0x10,  0x40,  0x17,  0xFC,  0x20,  0x40,  0x20,  0x40,  0x5F,  0xFF,  0x00,  0x00,  0x8D,  0x00, 	/* 2DE60 */
+	0x00,  0x1F,  0xFC,  0x10,  0x04,  0x10,  0x04,  0x1F,  0xFC,  0x10,  0x04,  0x10,  0x00,  0x1F,  0xFE,  0x12, 	/* 2DE70 */
+	0x20,  0x13,  0xA2,  0x12,  0xA4,  0x14,  0xB8,  0x3B,  0x20,  0x21,  0x22,  0x46,  0x22,  0x18,  0x1E,  0x8E, 	/* 2DE80 */
+	0x00,  0x00,  0x1F,  0xFE,  0x10,  0x02,  0x10,  0x02,  0x1F,  0xFE,  0x10,  0x40,  0x14,  0x48,  0x12,  0x48, 	/* 2DE90 */
+	0x12,  0x50,  0x1F,  0xFE,  0x10,  0xE0,  0x11,  0x50,  0x26,  0x4C,  0x38,  0x43,  0x40,  0x40,  0x00,  0x40, 	/* 2DEA0 */
+	0x8F,  0x00,  0x00,  0x1F,  0xFE,  0x10,  0x02,  0x10,  0x02,  0x1F,  0xFE,  0x12,  0x08,  0x11,  0x10,  0x17, 	/* 2DEB0 */
+	0xFE,  0x11,  0x10,  0x11,  0x10,  0x1F,  0xFF,  0x11,  0x10,  0x21,  0x10,  0x22,  0x10,  0x42,  0x10,  0x04, 	/* 2DEC0 */
+	0x10,  0x90,  0x00,  0x00,  0x1F,  0xFE,  0x10,  0x02,  0x10,  0x02,  0x1F,  0xFE,  0x12,  0x10,  0x12,  0xFF, 	/* 2DED0 */
+	0x15,  0x10,  0x19,  0x10,  0x12,  0xFC,  0x12,  0x44,  0x16,  0x28,  0x2A,  0x10,  0x22,  0x28,  0x42,  0x44, 	/* 2DEE0 */
+	0x03,  0x83,  0x91,  0x00,  0x00,  0x1F,  0xFC,  0x10,  0x04,  0x10,  0x04,  0x1F,  0xFC,  0x10,  0x40,  0x12, 	/* 2DEF0 */
+	0x48,  0x11,  0x50,  0x17,  0xF8,  0x14,  0x08,  0x17,  0xF8,  0x14,  0x08,  0x27,  0xF8,  0x24,  0x08,  0x44, 	/* 2DF00 */
+	0x08,  0x04,  0x18,  0x93,  0x00,  0x00,  0x1F,  0xFE,  0x10,  0x02,  0x10,  0x02,  0x1F,  0xFE,  0x10,  0x00, 	/* 2DF10 */
+	0x17,  0xFC,  0x14,  0x04,  0x17,  0xFC,  0x14,  0x04,  0x17,  0xFC,  0x14,  0x04,  0x27,  0xFC,  0x21,  0x10, 	/* 2DF20 */
+	0x46,  0x0C,  0x18,  0x02,  0x95,  0x00,  0x00,  0x1F,  0xFE,  0x10,  0x02,  0x10,  0x02,  0x1F,  0xFE,  0x11, 	/* 2DF30 */
+	0x10,  0x11,  0x10,  0x17,  0xFE,  0x11,  0x10,  0x11,  0x10,  0x1F,  0xFF,  0x12,  0x84,  0x12,  0x48,  0x22, 	/* 2DF40 */
+	0x30,  0x23,  0x8C,  0x4C,  0x03,  0x9E,  0x00,  0x00,  0x1F,  0xFC,  0x10,  0x04,  0x1F,  0xFC,  0x10,  0x0E, 	/* 2DF50 */
+	0x17,  0xF0,  0x10,  0x40,  0x17,  0xFC,  0x14,  0x44,  0x17,  0xFC,  0x10,  0x40,  0x1F,  0xFE,  0x28,  0x52, 	/* 2DF60 */
+	0x28,  0x6A,  0x4B,  0x8A,  0x08,  0x06,  0xA0,  0x00,  0x00,  0x1F,  0xFE,  0x10,  0x02,  0x10,  0x02,  0x1F, 	/* 2DF70 */
+	0xFE,  0x10,  0x48,  0x13,  0xFC,  0x10,  0x50,  0x1F,  0xFF,  0x10,  0x40,  0x11,  0xFC,  0x13,  0x04,  0x2D, 	/* 2DF80 */
+	0xFC,  0x21,  0x04,  0x41,  0xFC,  0x00,  0x00,  0xA1,  0x00,  0x00,  0x1F,  0xFE,  0x10,  0x02,  0x10,  0x02, 	/* 2DF90 */
+	0x1F,  0xFE,  0x12,  0x48,  0x11,  0x50,  0x1F,  0xFF,  0x13,  0x58,  0x1C,  0x46,  0x11,  0x40,  0x1F,  0xFF, 	/* 2DFA0 */
+	0x22,  0x10,  0x27,  0xE0,  0x41,  0x98,  0x1E,  0x04,  0xA4,  0x00,  0x00,  0x1F,  0xFE,  0x10,  0x02,  0x1F, 	/* 2DFB0 */
+	0xFE,  0x11,  0x10,  0x17,  0xFC,  0x14,  0x44,  0x17,  0xFC,  0x14,  0x44,  0x17,  0xFC,  0x10,  0x00,  0x13, 	/* 2DFC0 */
+	0xF8,  0x22,  0x08,  0x23,  0xF8,  0x42,  0x08,  0x03,  0xF8,  0xA5,  0x00,  0x00,  0x1F,  0xFE,  0x10,  0x02, 	/* 2DFD0 */
+	0x1F,  0xFE,  0x12,  0x40,  0x12,  0x7E,  0x14,  0x84,  0x19,  0xFC,  0x12,  0x84,  0x12,  0xFC,  0x14,  0x20, 	/* 2DFE0 */
+	0x1C,  0x7C,  0x25,  0xC8,  0x24,  0x30,  0x44,  0x4C,  0x07,  0x83,  0xAC,  0x00,  0x00,  0x1F,  0xFE,  0x10, 	/* 2DFF0 */
+	0x02,  0x1F,  0xFE,  0x17,  0x5C,  0x10,  0x40,  0x17,  0xFC,  0x14,  0xA4,  0x17,  0xFC,  0x11,  0x00,  0x13, 	/* 2E000 */
+	0xFE,  0x16,  0x4A,  0x2B,  0xFA,  0x20,  0x52,  0x4F,  0xEA,  0x00,  0x0C,  0xAE,  0x01,  0x00,  0x01,  0x00, 	/* 2E010 */
+	0x01,  0x00,  0x21,  0x04,  0x21,  0x04,  0x21,  0x04,  0x21,  0x04,  0x21,  0x04,  0x21,  0x04,  0x3F,  0xFC, 	/* 2E020 */
+	0x01,  0x00,  0x01,  0x00,  0x02,  0x00,  0x04,  0x00,  0x18,  0x00,  0x60,  0x00,  0xAF,  0x00,  0x80,  0x00, 	/* 2E030 */
+	0x83,  0x00,  0xFC,  0x7F,  0x80,  0x00,  0x80,  0x00,  0x80,  0x08,  0x88,  0x08,  0x88,  0x08,  0x88,  0x08, 	/* 2E040 */
+	0x88,  0x08,  0x88,  0x0F,  0xF8,  0x00,  0x80,  0x00,  0x82,  0x00,  0x42,  0x00,  0x3E,  0xB1,  0x00,  0x80, 	/* 2E050 */
+	0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x20,  0x82,  0x20,  0x82,  0x20,  0x82,  0x20,  0x82, 	/* 2E060 */
+	0x20,  0x82,  0x20,  0x82,  0x20,  0x82,  0x20,  0x82,  0x20,  0x82,  0x3F,  0xFE,  0x00,  0x00,  0xB6,  0x01, 	/* 2E070 */
+	0x00,  0x21,  0x04,  0x21,  0x04,  0x21,  0x04,  0x3F,  0xFC,  0x00,  0x00,  0x00,  0x00,  0x7F,  0xFE,  0x00, 	/* 2E080 */
+	0x82,  0x00,  0x82,  0x01,  0x02,  0x01,  0x02,  0x02,  0x02,  0x04,  0x02,  0x18,  0x04,  0x60,  0x18,  0xB9, 	/* 2E090 */
+	0x10,  0x40,  0x10,  0x40,  0x10,  0x40,  0x10,  0xFF,  0x54,  0x80,  0x55,  0x00,  0x57,  0xFC,  0x54,  0x08, 	/* 2E0A0 */
+	0x54,  0x10,  0x54,  0x20,  0x54,  0x40,  0x54,  0x80,  0x7D,  0x02,  0x01,  0x02,  0x00,  0x82,  0x00,  0x7E, 	/* 2E0B0 */
+	0x8C,  0x00,  0x80,  0x20,  0x82,  0x20,  0x82,  0x3F,  0xFE,  0x00,  0x00,  0x3F,  0xE0,  0x02,  0x20,  0x02, 	/* 2E0C0 */
+	0x20,  0x03,  0xF8,  0x05,  0x08,  0x05,  0x10,  0x08,  0xA0,  0x10,  0x40,  0x20,  0xA0,  0x43,  0x18,  0x1C, 	/* 2E0D0 */
+	0x07,  0x90,  0x10,  0x20,  0x10,  0x20,  0x13,  0xFF,  0x54,  0x20,  0x54,  0x20,  0x54,  0x20,  0x57,  0xFC, 	/* 2E0E0 */
+	0x54,  0x84,  0x54,  0x88,  0x54,  0x48,  0x54,  0x50,  0x7C,  0x30,  0x00,  0x30,  0x00,  0x48,  0x01,  0x84, 	/* 2E0F0 */
+	0x06,  0x03,  0x91,  0x00,  0x80,  0x20,  0x82,  0x20,  0x82,  0x3F,  0xFE,  0x00,  0x80,  0x01,  0x40,  0x02, 	/* 2E100 */
+	0x20,  0x07,  0xF0,  0x18,  0x0C,  0x60,  0x03,  0x0F,  0xF0,  0x00,  0x10,  0x00,  0x20,  0x00,  0x20,  0x00, 	/* 2E110 */
+	0x40,  0x00,  0x80,  0x94,  0x03,  0xE0,  0x00,  0x20,  0x04,  0x10,  0x08,  0x08,  0x1F,  0xF4,  0x61,  0x13, 	/* 2E120 */
+	0x01,  0x10,  0x02,  0x10,  0x0C,  0x10,  0x30,  0x60,  0x00,  0x80,  0x20,  0x82,  0x20,  0x82,  0x20,  0x82, 	/* 2E130 */
+	0x3F,  0xFE,  0x00,  0x00,  0xA1,  0x00,  0x00,  0x3F,  0xFE,  0x20,  0x22,  0x24,  0x22,  0x22,  0x22,  0x22, 	/* 2E140 */
+	0x42,  0x3F,  0xFE,  0x20,  0x82,  0x24,  0x92,  0x24,  0x92,  0x24,  0x92,  0x24,  0x92,  0x27,  0xF2,  0x20, 	/* 2E150 */
+	0x02,  0x20,  0x02,  0x20,  0x06,  0xA8,  0x10,  0x00,  0x10,  0xFC,  0x10,  0x84,  0x54,  0x84,  0x54,  0x84, 	/* 2E160 */
+	0x54,  0xFC,  0x54,  0x84,  0x54,  0x84,  0x54,  0x84,  0x54,  0xFC,  0x54,  0x84,  0x7C,  0x84,  0x00,  0x84, 	/* 2E170 */
+	0x00,  0x84,  0x07,  0xFF,  0x00,  0x00,  0xA9,  0x00,  0x80,  0x10,  0x84,  0x10,  0x84,  0x10,  0x84,  0x1F, 	/* 2E180 */
+	0xFC,  0x00,  0x00,  0x00,  0x00,  0x7F,  0xFF,  0x02,  0x00,  0x04,  0x00,  0x0F,  0xF8,  0x14,  0x08,  0x64, 	/* 2E190 */
+	0x08,  0x04,  0x08,  0x07,  0xF8,  0x00,  0x00,  0xAB,  0x10,  0x20,  0x10,  0x20,  0x10,  0x20,  0x54,  0x20, 	/* 2E1A0 */
+	0x55,  0xFE,  0x55,  0x22,  0x55,  0x22,  0x55,  0x22,  0x55,  0x22,  0x55,  0xFE,  0x55,  0x22,  0x55,  0x22, 	/* 2E1B0 */
+	0x7D,  0x22,  0x01,  0x22,  0x01,  0xFE,  0x00,  0x00,  0xAC,  0x10,  0x00,  0x11,  0xFE,  0x11,  0x22,  0x55, 	/* 2E1C0 */
+	0x22,  0x55,  0x22,  0x55,  0xFE,  0x55,  0x22,  0x55,  0x22,  0x55,  0x22,  0x55,  0xFE,  0x54,  0x20,  0x7C, 	/* 2E1D0 */
+	0x20,  0x00,  0x20,  0x00,  0x20,  0x00,  0x20,  0x00,  0x20,  0xB1,  0x04,  0x48,  0x04,  0x44,  0x08,  0x44, 	/* 2E1E0 */
+	0x0F,  0xFF,  0x10,  0x20,  0x30,  0x20,  0x50,  0x12,  0x10,  0x0A,  0x10,  0x86,  0x10,  0x82,  0x20,  0x84, 	/* 2E1F0 */
+	0x20,  0x84,  0x20,  0x84,  0x20,  0x84,  0x3F,  0xFC,  0x00,  0x00,  0xB3,  0x00,  0x10,  0x00,  0x60,  0x07, 	/* 2E200 */
+	0x80,  0x04,  0x00,  0x07,  0xFC,  0x04,  0x10,  0x04,  0x10,  0x04,  0x10,  0x7F,  0xFF,  0x00,  0x80,  0x10, 	/* 2E210 */
+	0x84,  0x10,  0x84,  0x10,  0x84,  0x10,  0x84,  0x1F,  0xFC,  0x00,  0x00,  0xB6,  0x10,  0x10,  0x10,  0x10, 	/* 2E220 */
+	0x10,  0x20,  0x52,  0xFE,  0x52,  0x82,  0x52,  0x82,  0x52,  0x82,  0x52,  0x82,  0x52,  0xFE,  0x52,  0x82, 	/* 2E230 */
+	0x52,  0x82,  0x52,  0x82,  0x7E,  0x82,  0x00,  0x82,  0x00,  0xFE,  0x00,  0x00,  0xB7,  0x10,  0x00,  0x11, 	/* 2E240 */
+	0xFE,  0x11,  0x02,  0x11,  0x02,  0x55,  0x02,  0x55,  0xFE,  0x55,  0x10,  0x55,  0x10,  0x55,  0xFF,  0x55, 	/* 2E250 */
+	0x10,  0x55,  0x10,  0x55,  0x08,  0x7D,  0x08,  0x01,  0x65,  0x01,  0x83,  0x06,  0x01,  0xB8,  0x00,  0x80, 	/* 2E260 */
+	0x10,  0x84,  0x10,  0x84,  0x1F,  0xFC,  0x00,  0x00,  0x1F,  0xFF,  0x10,  0x00,  0x17,  0xFC,  0x10,  0x40, 	/* 2E270 */
+	0x10,  0x40,  0x1F,  0xFF,  0x10,  0x40,  0x20,  0x40,  0x20,  0x40,  0x40,  0x40,  0x00,  0x40,  0xBB,  0x10, 	/* 2E280 */
+	0x04,  0x10,  0x18,  0x55,  0xF0,  0x55,  0x10,  0x55,  0x10,  0x55,  0x10,  0x55,  0xFF,  0x55,  0x10,  0x55, 	/* 2E290 */
+	0x10,  0x55,  0x08,  0x55,  0x08,  0x7D,  0xE8,  0x07,  0x05,  0x00,  0x05,  0x07,  0xF3,  0x00,  0x01,  0xBC, 	/* 2E2A0 */
+	0x10,  0x00,  0x11,  0xFE,  0x10,  0x20,  0x54,  0xA8,  0x54,  0xA8,  0x54,  0xA4,  0x55,  0x24,  0x54,  0x20, 	/* 2E2B0 */
+	0x57,  0xFF,  0x54,  0x20,  0x54,  0x20,  0x7C,  0x20,  0x00,  0x20,  0x00,  0x20,  0x00,  0x20,  0x00,  0x20, 	/* 2E2C0 */
+	0xBE,  0x10,  0x20,  0x10,  0x20,  0x10,  0x20,  0x10,  0x20,  0x54,  0x3F,  0x54,  0x20,  0x54,  0x20,  0x54, 	/* 2E2D0 */
+	0x20,  0x54,  0x20,  0x55,  0xFC,  0x55,  0x04,  0x55,  0x04,  0x7D,  0x04,  0x01,  0x04,  0x01,  0xFC,  0x00, 	/* 2E2E0 */
+	0x00,  0x85,  0x10,  0x20,  0x10,  0x20,  0x10,  0x48,  0x54,  0x8C,  0x57,  0xF2,  0x54,  0x89,  0x54,  0x88, 	/* 2E2F0 */
+	0x54,  0x88,  0x57,  0xFF,  0x54,  0x88,  0x54,  0x88,  0x7C,  0x88,  0x01,  0x08,  0x01,  0x08,  0x02,  0x08, 	/* 2E300 */
+	0x04,  0x08,  0x87,  0x00,  0x80,  0x20,  0x82,  0x20,  0x82,  0x3F,  0xFE,  0x00,  0x80,  0x00,  0x80,  0x01, 	/* 2E310 */
+	0x40,  0x06,  0x30,  0x1B,  0xEC,  0x60,  0x03,  0x00,  0x00,  0x0F,  0xF8,  0x08,  0x08,  0x08,  0x08,  0x0F, 	/* 2E320 */
+	0xF8,  0x00,  0x00,  0x99,  0x10,  0x20,  0x10,  0x20,  0x11,  0xFE,  0x10,  0x20,  0x54,  0x20,  0x54,  0x20, 	/* 2E330 */
+	0x57,  0xFF,  0x54,  0x04,  0x54,  0x04,  0x57,  0xFF,  0x55,  0x04,  0x54,  0x84,  0x7C,  0x44,  0x00,  0x44, 	/* 2E340 */
+	0x00,  0x04,  0x00,  0x0C,  0xA0,  0x10,  0x20,  0x10,  0x20,  0x10,  0x3E,  0x54,  0x20,  0x54,  0x20,  0x57, 	/* 2E350 */
+	0xFF,  0x54,  0x00,  0x54,  0x00,  0x57,  0xFF,  0x54,  0x20,  0x54,  0x20,  0x54,  0x38,  0x7C,  0x26,  0x00, 	/* 2E360 */
+	0x20,  0x00,  0x20,  0x00,  0x20,  0xA1,  0x10,  0x10,  0x10,  0x10,  0x11,  0xFE,  0x54,  0x10,  0x54,  0x92, 	/* 2E370 */
+	0x54,  0x52,  0x54,  0x54,  0x54,  0x10,  0x57,  0xFF,  0x54,  0x10,  0x54,  0x10,  0x7C,  0x28,  0x44,  0x28, 	/* 2E380 */
+	0x00,  0x44,  0x00,  0x82,  0x03,  0x01,  0xA8,  0x10,  0x50,  0x10,  0x94,  0x13,  0x92,  0x54,  0x92,  0x54, 	/* 2E390 */
+	0x90,  0x57,  0xFF,  0x54,  0x90,  0x54,  0x92,  0x54,  0xD2,  0x55,  0x94,  0x56,  0x88,  0x7C,  0x9A,  0x44, 	/* 2E3A0 */
+	0xAA,  0x40,  0xC6,  0x00,  0x86,  0x03,  0x02,  0xA9,  0x00,  0x80,  0x20,  0x82,  0x20,  0x82,  0x3F,  0xFE, 	/* 2E3B0 */
+	0x02,  0x00,  0x0C,  0x28,  0x38,  0x24,  0x08,  0x24,  0x7F,  0xFF,  0x08,  0x20,  0x09,  0x24,  0x0E,  0x18, 	/* 2E3C0 */
+	0x78,  0x12,  0x08,  0x2A,  0x08,  0xC6,  0x1B,  0x02,  0xAA,  0x10,  0x88,  0x10,  0x88,  0x10,  0x84,  0x55, 	/* 2E3D0 */
+	0x24,  0x55,  0x24,  0x56,  0x50,  0x54,  0x48,  0x54,  0x84,  0x55,  0x02,  0x56,  0x01,  0x55,  0xFC,  0x7D, 	/* 2E3E0 */
+	0x04,  0x01,  0x04,  0x01,  0x04,  0x01,  0xFC,  0x00,  0x00,  0xAD,  0x10,  0x28,  0x11,  0x24,  0x11,  0x22, 	/* 2E3F0 */
+	0x12,  0x22,  0x54,  0x20,  0x55,  0xFC,  0x55,  0x04,  0x55,  0x04,  0x55,  0xFC,  0x55,  0x04,  0x55,  0x04, 	/* 2E400 */
+	0x55,  0xFC,  0x7D,  0x04,  0x01,  0x04,  0x01,  0x04,  0x01,  0x0C,  0xAF,  0x20,  0x82,  0x20,  0x82,  0x3F, 	/* 2E410 */
+	0xFE,  0x01,  0x00,  0x01,  0xF0,  0x06,  0x20,  0x3B,  0x40,  0x01,  0xC0,  0x06,  0x38,  0x78,  0x87,  0x0F, 	/* 2E420 */
+	0xF8,  0x00,  0x80,  0x0F,  0xF8,  0x00,  0x80,  0x7F,  0xFF,  0x00,  0x80,  0xB0,  0x00,  0x20,  0x10,  0x3C, 	/* 2E430 */
+	0x10,  0x44,  0x54,  0x88,  0x57,  0x50,  0x54,  0x20,  0x54,  0xD0,  0x57,  0x0C,  0x54,  0x23,  0x55,  0xFC, 	/* 2E440 */
+	0x54,  0x20,  0x7D,  0xFC,  0x00,  0x20,  0x07,  0xFF,  0x00,  0x20,  0x00,  0x20,  0xB6,  0x01,  0x00,  0x02, 	/* 2E450 */
+	0x00,  0x0F,  0xF0,  0x08,  0x10,  0x0F,  0xF0,  0x08,  0x10,  0x0F,  0xF0,  0x08,  0x00,  0x0F,  0xFF,  0x08, 	/* 2E460 */
+	0x00,  0x0F,  0xFE,  0x02,  0x02,  0x22,  0x22,  0x22,  0x22,  0x3F,  0xE2,  0x00,  0x1C,  0xBA,  0x10,  0x00, 	/* 2E470 */
+	0x13,  0xFF,  0x10,  0x20,  0x55,  0xFC,  0x55,  0x24,  0x55,  0x24,  0x55,  0xFC,  0x55,  0x24,  0x55,  0x24, 	/* 2E480 */
+	0x55,  0xFC,  0x54,  0x20,  0x7C,  0xA0,  0x00,  0x60,  0x00,  0x90,  0x03,  0x0C,  0x0C,  0x03,  0xBB,  0x00, 	/* 2E490 */
+	0x40,  0x10,  0x50,  0x10,  0x8C,  0x13,  0xFA,  0x54,  0x50,  0x54,  0x51,  0x54,  0x9F,  0x55,  0x40,  0x56, 	/* 2E4A0 */
+	0x78,  0x54,  0x48,  0x54,  0x88,  0x57,  0x50,  0x7C,  0x20,  0x44,  0x50,  0x41,  0x8C,  0x06,  0x03,  0xBD, 	/* 2E4B0 */
+	0x00,  0x20,  0x10,  0x20,  0x13,  0xFF,  0x54,  0x20,  0x55,  0x24,  0x55,  0x24,  0x55,  0x24,  0x55,  0xA6, 	/* 2E4C0 */
+	0x56,  0x69,  0x56,  0x30,  0x54,  0x50,  0x7C,  0x50,  0x00,  0x88,  0x01,  0x04,  0x02,  0x02,  0x0C,  0x01, 	/* 2E4D0 */
+	0x87,  0x21,  0x04,  0x21,  0x04,  0x3F,  0xFC,  0x21,  0x04,  0x01,  0x00,  0x7F,  0xFE,  0x40,  0x02,  0x4F, 	/* 2E4E0 */
+	0xF2,  0x00,  0x00,  0x00,  0x00,  0x7F,  0xFE,  0x04,  0x90,  0x18,  0x8C,  0x60,  0x82,  0x00,  0x80,  0x01, 	/* 2E4F0 */
+	0x80,  0x8B,  0x00,  0x80,  0x20,  0x82,  0x20,  0x82,  0x3F,  0xFE,  0x00,  0x00,  0x3F,  0xFE,  0x08,  0x88, 	/* 2E500 */
+	0x08,  0x88,  0x7F,  0xFF,  0x08,  0x88,  0x08,  0x88,  0x3F,  0xFE,  0x00,  0x80,  0x7F,  0xFF,  0x00,  0x80, 	/* 2E510 */
+	0x00,  0x80,  0x8E,  0x00,  0x20,  0x10,  0x20,  0x13,  0xFE,  0x54,  0x50,  0x54,  0x88,  0x55,  0x04,  0x54, 	/* 2E520 */
+	0x00,  0x57,  0xFF,  0x54,  0x04,  0x55,  0xE4,  0x55,  0x24,  0x55,  0x24,  0x7D,  0xE4,  0x00,  0x04,  0x00, 	/* 2E530 */
+	0x04,  0x00,  0x0C,  0x91,  0x00,  0x80,  0x20,  0x82,  0x20,  0x82,  0x3F,  0xFE,  0x00,  0x00,  0x1F,  0xF8, 	/* 2E540 */
+	0x10,  0x08,  0x1F,  0xF8,  0x10,  0x08,  0x1F,  0xF8,  0x10,  0x40,  0x10,  0x44,  0x1F,  0x58,  0x10,  0x62, 	/* 2E550 */
+	0x1F,  0x42,  0x70,  0x3E,  0x94,  0x00,  0x80,  0x20,  0x82,  0x20,  0x82,  0x3F,  0xFE,  0x08,  0x20,  0x08, 	/* 2E560 */
+	0x40,  0x1F,  0xFE,  0x30,  0x80,  0x50,  0x80,  0x1F,  0xFC,  0x10,  0x80,  0x1F,  0xFC,  0x10,  0x80,  0x10, 	/* 2E570 */
+	0x80,  0x1F,  0xFF,  0x00,  0x00,  0x95,  0x10,  0x00,  0x11,  0xFF,  0x11,  0x10,  0x55,  0x10,  0x55,  0x7E, 	/* 2E580 */
+	0x55,  0x10,  0x55,  0x10,  0x55,  0xFF,  0x55,  0x10,  0x55,  0x10,  0x7D,  0xFE,  0x02,  0x10,  0x02,  0x10, 	/* 2E590 */
+	0x04,  0x10,  0x09,  0xFF,  0x00,  0x00,  0x96,  0x10,  0x84,  0x10,  0x84,  0x1F,  0xFC,  0x00,  0x00,  0x1F, 	/* 2E5A0 */
+	0xFF,  0x10,  0x40,  0x17,  0xFC,  0x10,  0x40,  0x10,  0x40,  0x1F,  0xFE,  0x10,  0x40,  0x17,  0xFC,  0x20, 	/* 2E5B0 */
+	0x40,  0x20,  0x40,  0x5F,  0xFF,  0x00,  0x00,  0x97,  0x00,  0x80,  0x20,  0x82,  0x20,  0x82,  0x3F,  0xFE, 	/* 2E5C0 */
+	0x00,  0x00,  0x3F,  0xFE,  0x24,  0x12,  0x22,  0x22,  0x3F,  0xFE,  0x20,  0x82,  0x24,  0x92,  0x24,  0x92, 	/* 2E5D0 */
+	0x24,  0x92,  0x27,  0xF2,  0x20,  0x02,  0x20,  0x06,  0x98,  0x10,  0x20,  0x10,  0x20,  0x10,  0x50,  0x10, 	/* 2E5E0 */
+	0x48,  0x54,  0x84,  0x55,  0xFA,  0x56,  0x01,  0x54,  0x00,  0x55,  0xFE,  0x55,  0x52,  0x55,  0x52,  0x55, 	/* 2E5F0 */
+	0xFE,  0x7D,  0x52,  0x01,  0x52,  0x01,  0x52,  0x01,  0x06,  0x99,  0x00,  0x80,  0x20,  0x82,  0x20,  0x82, 	/* 2E600 */
+	0x3F,  0xFE,  0x00,  0x80,  0x01,  0x40,  0x06,  0x30,  0x1B,  0xEC,  0x60,  0x03,  0x1F,  0xFC,  0x12,  0x24, 	/* 2E610 */
+	0x12,  0x24,  0x1F,  0xFC,  0x12,  0x24,  0x12,  0x24,  0x12,  0x2C,  0x9A,  0x10,  0x20,  0x10,  0x20,  0x13, 	/* 2E620 */
+	0xFE,  0x10,  0x20,  0x57,  0xFF,  0x54,  0x88,  0x54,  0x89,  0x55,  0x27,  0x56,  0x20,  0x54,  0x7C,  0x54, 	/* 2E630 */
+	0x84,  0x57,  0x48,  0x7C,  0x30,  0x00,  0x70,  0x01,  0x8C,  0x0E,  0x03,  0x9B,  0x10,  0x00,  0x11,  0xFE, 	/* 2E640 */
+	0x11,  0x02,  0x55,  0x02,  0x55,  0xFE,  0x55,  0x10,  0x55,  0x92,  0x55,  0x92,  0x55,  0x92,  0x55,  0xFE, 	/* 2E650 */
+	0x55,  0x10,  0x7D,  0x90,  0x02,  0x92,  0x02,  0x92,  0x04,  0xFE,  0x08,  0x00,  0x9F,  0x00,  0x80,  0x20, 	/* 2E660 */
+	0x82,  0x20,  0x82,  0x3F,  0xFE,  0x00,  0x80,  0x01,  0x40,  0x06,  0x30,  0x1F,  0xFC,  0x60,  0x83,  0x00, 	/* 2E670 */
+	0x80,  0x7F,  0xFF,  0x00,  0x80,  0x08,  0x88,  0x04,  0x90,  0x3F,  0xFE,  0x00,  0x00,  0xA2,  0x10,  0x04, 	/* 2E680 */
+	0x10,  0x18,  0x13,  0xE4,  0x10,  0x92,  0x55,  0x12,  0x57,  0xFC,  0x54,  0x24,  0x54,  0x24,  0x57,  0xFF, 	/* 2E690 */
+	0x54,  0x24,  0x54,  0x24,  0x55,  0xFC,  0x7C,  0x20,  0x00,  0x20,  0x00,  0x20,  0x00,  0x60,  0xA9,  0x00, 	/* 2E6A0 */
+	0x80,  0x10,  0x82,  0x10,  0x82,  0x1F,  0xFE,  0x00,  0x00,  0x1F,  0x3E,  0x11,  0x22,  0x11,  0x22,  0x1F, 	/* 2E6B0 */
+	0x3E,  0x11,  0x22,  0x11,  0x22,  0x1F,  0x3E,  0x11,  0x22,  0x21,  0x42,  0x21,  0x42,  0x43,  0x86,  0x8B, 	/* 2E6C0 */
+	0x10,  0x00,  0x11,  0xFE,  0x11,  0x12,  0x55,  0x12,  0x55,  0xFE,  0x55,  0x00,  0x55,  0x7E,  0x55,  0x42, 	/* 2E6D0 */
+	0x55,  0x42,  0x55,  0x7E,  0x55,  0x42,  0x7D,  0x7E,  0x02,  0x42,  0x02,  0x42,  0x04,  0x7E,  0x08,  0x00, 	/* 2E6E0 */
+	0x8C,  0x00,  0x80,  0x20,  0x82,  0x20,  0x82,  0x3F,  0xFE,  0x00,  0x40,  0x22,  0x40,  0x22,  0x7F,  0x7F, 	/* 2E6F0 */
+	0x42,  0x22,  0x94,  0x23,  0x10,  0x3E,  0x10,  0x22,  0x28,  0x22,  0x28,  0x22,  0x44,  0x3E,  0x82,  0x03, 	/* 2E700 */
+	0x01,  0x8E,  0x10,  0x00,  0x11,  0xFC,  0x11,  0x24,  0x55,  0x24,  0x55,  0xFC,  0x55,  0x24,  0x55,  0x24, 	/* 2E710 */
+	0x55,  0xFC,  0x54,  0x20,  0x57,  0xFE,  0x56,  0x22,  0x7E,  0x2A,  0x02,  0x7A,  0x03,  0x86,  0x02,  0x02, 	/* 2E720 */
+	0x02,  0x06,  0x90,  0x11,  0x08,  0x11,  0x08,  0x1F,  0xF8,  0x00,  0x00,  0x1F,  0xF8,  0x10,  0x28,  0x1F, 	/* 2E730 */
+	0xC8,  0x11,  0x08,  0x17,  0xE8,  0x15,  0x28,  0x15,  0x28,  0x17,  0xE8,  0x11,  0x44,  0x21,  0x25,  0x2F, 	/* 2E740 */
+	0xD3,  0x40,  0x11,  0x92,  0x00,  0x00,  0x0F,  0xF0,  0x08,  0x10,  0x08,  0x10,  0x0F,  0xF0,  0x00,  0x00, 	/* 2E750 */
+	0x7E,  0x7E,  0x42,  0x42,  0x42,  0x42,  0x7E,  0x7E,  0x01,  0x00,  0x21,  0x04,  0x21,  0x04,  0x21,  0x04, 	/* 2E760 */
+	0x3F,  0xFC,  0x00,  0x00,  0x9C,  0x00,  0x80,  0x10,  0x82,  0x10,  0x82,  0x1F,  0xFE,  0x00,  0x80,  0x3F, 	/* 2E770 */
+	0xFE,  0x04,  0x10,  0x02,  0x20,  0x7F,  0xFF,  0x00,  0x04,  0x0F,  0xC4,  0x08,  0x44,  0x08,  0x44,  0x0F, 	/* 2E780 */
+	0xC4,  0x00,  0x04,  0x00,  0x0C,  0xA9,  0x21,  0x04,  0x21,  0x04,  0x3F,  0xFC,  0x01,  0x00,  0x7F,  0xFF, 	/* 2E790 */
+	0x00,  0x00,  0x07,  0xE0,  0x04,  0x20,  0x07,  0xE0,  0x00,  0x00,  0x3F,  0xFC,  0x20,  0x04,  0x27,  0xE4, 	/* 2E7A0 */
+	0x24,  0x24,  0x27,  0xE4,  0x20,  0x0C,  0xAC,  0x00,  0x80,  0x20,  0x82,  0x20,  0x82,  0x3F,  0xFE,  0x01, 	/* 2E7B0 */
+	0x00,  0x0F,  0xF8,  0x08,  0x88,  0x0F,  0xF8,  0x08,  0x88,  0x08,  0x88,  0x0F,  0xFC,  0x01,  0x44,  0x01, 	/* 2E7C0 */
+	0x4A,  0x02,  0x5F,  0x0C,  0x21,  0x70,  0x1F,  0xAF,  0x10,  0x84,  0x10,  0x48,  0x13,  0xFE,  0x54,  0x20, 	/* 2E7D0 */
+	0x54,  0x20,  0x55,  0xFC,  0x54,  0x20,  0x54,  0x20,  0x57,  0xFF,  0x54,  0x80,  0x54,  0x80,  0x7D,  0xFE, 	/* 2E7E0 */
+	0x42,  0x10,  0x44,  0x10,  0x01,  0xFF,  0x00,  0x00,  0xB3,  0x20,  0x82,  0x20,  0x82,  0x3F,  0xFE,  0x04, 	/* 2E7F0 */
+	0x10,  0x02,  0x20,  0x3F,  0xFC,  0x00,  0x80,  0x1F,  0xF8,  0x00,  0x80,  0x7F,  0xFF,  0x02,  0x00,  0x07, 	/* 2E800 */
+	0xFC,  0x08,  0x40,  0x10,  0x40,  0x6F,  0xFF,  0x00,  0x00,  0xB6,  0x10,  0x00,  0x13,  0xFE,  0x10,  0x42, 	/* 2E810 */
+	0x54,  0x42,  0x54,  0x42,  0x55,  0xDE,  0x55,  0x10,  0x55,  0x10,  0x55,  0xDE,  0x55,  0x4A,  0x56,  0x52, 	/* 2E820 */
+	0x54,  0xC6,  0x7D,  0x4A,  0x02,  0x52,  0x00,  0x42,  0x01,  0x8C,  0x82,  0x10,  0x20,  0x10,  0x20,  0x11, 	/* 2E830 */
+	0xFE,  0x54,  0x84,  0x54,  0x48,  0x57,  0xFF,  0x54,  0x00,  0x54,  0xFC,  0x54,  0x84,  0x54,  0xFC,  0x54, 	/* 2E840 */
+	0x84,  0x7C,  0xFC,  0x00,  0x20,  0x07,  0xFF,  0x00,  0x20,  0x00,  0x20,  0x84,  0x00,  0x80,  0x20,  0x82, 	/* 2E850 */
+	0x20,  0x82,  0x3F,  0xFE,  0x04,  0x02,  0x7F,  0xC4,  0x04,  0x38,  0x3F,  0xA0,  0x24,  0xBF,  0x3F,  0xA4, 	/* 2E860 */
+	0x24,  0xA4,  0x3F,  0xA4,  0x04,  0x24,  0x7F,  0xC4,  0x04,  0x44,  0x04,  0x84,  0x87,  0x10,  0x00,  0x11, 	/* 2E870 */
+	0xFF,  0x11,  0x00,  0x55,  0x3C,  0x55,  0x24,  0x55,  0x24,  0x55,  0x3C,  0x55,  0x00,  0x55,  0xEE,  0x55, 	/* 2E880 */
+	0xAA,  0x55,  0xAA,  0x55,  0xAA,  0x7D,  0xEE,  0x01,  0x00,  0x01,  0xFF,  0x00,  0x00,  0x8B,  0x10,  0x20, 	/* 2E890 */
+	0x10,  0x40,  0x11,  0xF8,  0x55,  0x08,  0x55,  0xF8,  0x55,  0x08,  0x55,  0xF8,  0x55,  0x00,  0x55,  0xFF, 	/* 2E8A0 */
+	0x55,  0x00,  0x55,  0xFE,  0x7C,  0x52,  0x03,  0x2A,  0x02,  0xAA,  0x04,  0x82,  0x08,  0x0C,  0x8C,  0x20, 	/* 2E8B0 */
+	0x82,  0x20,  0x82,  0x3F,  0xFE,  0x01,  0x00,  0x0F,  0xF8,  0x08,  0x08,  0x0F,  0xF8,  0x08,  0x08,  0x0F, 	/* 2E8C0 */
+	0xF8,  0x08,  0x00,  0x0F,  0xFF,  0x08,  0x00,  0x0F,  0xFE,  0x24,  0x92,  0x22,  0x4A,  0x40,  0x0C,  0x90, 	/* 2E8D0 */
+	0x21,  0x02,  0x21,  0x02,  0x3F,  0xFE,  0x00,  0x80,  0x3C,  0xF8,  0x25,  0x88,  0x2B,  0x50,  0x30,  0x70, 	/* 2E8E0 */
+	0x29,  0x8C,  0x26,  0x7B,  0x24,  0xA0,  0x25,  0xFE,  0x3A,  0x20,  0x20,  0xFC,  0x20,  0x20,  0x27,  0xFF, 	/* 2E8F0 */
+	0x9D,  0x11,  0xD2,  0x10,  0x54,  0x11,  0x49,  0x54,  0x8A,  0x54,  0xFC,  0x55,  0x02,  0x56,  0x01,  0x54, 	/* 2E900 */
+	0xFC,  0x54,  0x84,  0x54,  0x84,  0x54,  0xFC,  0x7C,  0x84,  0x00,  0x44,  0x00,  0x48,  0x07,  0xFF,  0x00, 	/* 2E910 */
+	0x00,  0xA2,  0x10,  0x20,  0x10,  0xFC,  0x10,  0x20,  0x57,  0xFE,  0x54,  0x00,  0x54,  0x84,  0x55,  0xFF, 	/* 2E920 */
+	0x54,  0x84,  0x54,  0xE4,  0x57,  0x9F,  0x54,  0x00,  0x7D,  0xFF,  0x00,  0x48,  0x00,  0x49,  0x01,  0x89, 	/* 2E930 */
+	0x06,  0x07,  0xAC,  0x10,  0x84,  0x10,  0x48,  0x11,  0xFE,  0x54,  0x20,  0x54,  0xFC,  0x54,  0x20,  0x57, 	/* 2E940 */
+	0xFF,  0x54,  0x54,  0x55,  0x92,  0x54,  0x90,  0x57,  0xFF,  0x7C,  0x8A,  0x00,  0xE4,  0x07,  0x85,  0x00, 	/* 2E950 */
+	0x8B,  0x01,  0x91,  0xAE,  0x10,  0x20,  0x10,  0x20,  0x10,  0x50,  0x54,  0x88,  0x55,  0x04,  0x56,  0xFA, 	/* 2E960 */
+	0x54,  0x01,  0x57,  0xDE,  0x56,  0x52,  0x56,  0x52,  0x57,  0xDE,  0x55,  0x08,  0x7D,  0x08,  0x01,  0x8C, 	/* 2E970 */
+	0x02,  0x52,  0x04,  0x22,  0xB7,  0x20,  0x82,  0x20,  0x82,  0x3F,  0xFE,  0x00,  0x00,  0x26,  0x7E,  0x38, 	/* 2E980 */
+	0x04,  0x21,  0x38,  0x1F,  0x08,  0x10,  0xFF,  0x1F,  0x12,  0x24,  0x50,  0x7F,  0xDE,  0x04,  0x50,  0x0A, 	/* 2E990 */
+	0x70,  0x12,  0x98,  0x61,  0x07,  0xBA,  0x10,  0x84,  0x10,  0x84,  0x1F,  0xFC,  0x14,  0x04,  0x0C,  0xFF, 	/* 2E9A0 */
+	0x0A,  0x10,  0x11,  0x20,  0x3E,  0x7E,  0x40,  0x42,  0x3F,  0x7E,  0x09,  0x42,  0x09,  0x7E,  0x09,  0x42, 	/* 2E9B0 */
+	0x0E,  0x7E,  0x08,  0x26,  0x09,  0xC1,  0xBC,  0x10,  0x60,  0x11,  0xA6,  0x11,  0x3A,  0x55,  0x22,  0x55, 	/* 2E9C0 */
+	0xA6,  0x55,  0x3A,  0x55,  0x0A,  0x55,  0xAE,  0x55,  0x2A,  0x55,  0x2A,  0x55,  0x2A,  0x57,  0xFF,  0x7C, 	/* 2E9D0 */
+	0x00,  0x00,  0x88,  0x03,  0x06,  0x0C,  0x01,  0xBD,  0x20,  0x82,  0x20,  0x82,  0x3F,  0xFE,  0x00,  0x00, 	/* 2E9E0 */
+	0x4B,  0xCA,  0x28,  0x09,  0x17,  0xE8,  0x30,  0x3F,  0x4B,  0xC8,  0x08,  0x08,  0x1B,  0xCC,  0x28,  0x0C, 	/* 2E9F0 */
+	0x4B,  0xD4,  0x0A,  0x52,  0x6B,  0xE2,  0x10,  0x41,  0x89,  0x10,  0x78,  0x10,  0x90,  0x13,  0xFE,  0x55, 	/* 2EA00 */
+	0x02,  0x55,  0xFE,  0x54,  0x99,  0x54,  0xEE,  0x54,  0x89,  0x55,  0xF7,  0x54,  0x38,  0x55,  0xFE,  0x7D, 	/* 2EA10 */
+	0x12,  0x01,  0xFE,  0x00,  0x34,  0x00,  0xD1,  0x07,  0x0F,  0x8C,  0x10,  0x42,  0x10,  0x42,  0x1F,  0xFE, 	/* 2EA20 */
+	0x05,  0x08,  0x1F,  0xFF,  0x17,  0x90,  0x12,  0x10,  0x1F,  0xDF,  0x14,  0xA4,  0x17,  0xA4,  0x14,  0xD4, 	/* 2EA30 */
+	0x17,  0x88,  0x14,  0x88,  0x27,  0x94,  0x2C,  0xA2,  0x40,  0xC1,  0x8D,  0x20,  0x82,  0x20,  0x82,  0x3F, 	/* 2EA40 */
+	0xFE,  0x02,  0x10,  0x3C,  0x20,  0x08,  0xFE,  0x7F,  0x92,  0x1C,  0xFE,  0x2A,  0x92,  0x49,  0xFE,  0x7F, 	/* 2EA50 */
+	0x34,  0x14,  0x34,  0x34,  0x5A,  0x08,  0x5F,  0x14,  0x91,  0x63,  0x0F,  0x92,  0x11,  0xC4,  0x10,  0x04, 	/* 2EA60 */
+	0x6F,  0xFA,  0x28,  0x0A,  0x11,  0xC4,  0x28,  0x0A,  0x7D,  0xDF,  0x10,  0x04,  0x59,  0xD6,  0x55,  0x55, 	/* 2EA70 */
+	0x11,  0xE4,  0x00,  0x80,  0x20,  0x82,  0x20,  0x82,  0x3F,  0xFE,  0x00,  0x00,  0x93,  0x20,  0x82,  0x20, 	/* 2EA80 */
+	0x82,  0x3F,  0xFE,  0x26,  0x00,  0x38,  0xFF,  0x21,  0x10,  0x5F,  0x7E,  0x52,  0x42,  0x5E,  0x7E,  0x52, 	/* 2EA90 */
+	0x42,  0x5E,  0x7E,  0x52,  0x42,  0x5E,  0x7E,  0x7F,  0x14,  0x22,  0x62,  0x41,  0x81,  0x96,  0x08,  0x42, 	/* 2EAA0 */
+	0x0F,  0xFE,  0x00,  0x00,  0x07,  0xBC,  0x04,  0xA4,  0x1F,  0xFF,  0x10,  0x10,  0x17,  0xD0,  0x11,  0x1F, 	/* 2EAB0 */
+	0x1F,  0xE4,  0x14,  0xA4,  0x17,  0xD4,  0x14,  0x88,  0x27,  0x94,  0x2C,  0xA2,  0x40,  0xC1,  0x9B,  0x04, 	/* 2EAC0 */
+	0x21,  0x04,  0x21,  0x08,  0x42,  0x08,  0x42,  0x10,  0x84,  0x10,  0x84,  0x21,  0x08,  0x42,  0x10,  0x42, 	/* 2EAD0 */
+	0x10,  0x21,  0x08,  0x10,  0x84,  0x10,  0x84,  0x08,  0x42,  0x08,  0x42,  0x04,  0x21,  0x04,  0x21,  0x9D, 	/* 2EAE0 */
+	0x00,  0x04,  0x10,  0x04,  0x10,  0x84,  0x10,  0x84,  0x10,  0x84,  0x10,  0x84,  0x10,  0x84,  0x10,  0x84, 	/* 2EAF0 */
+	0x10,  0x84,  0x10,  0x84,  0x10,  0x84,  0x10,  0x84,  0x20,  0x04,  0x20,  0x04,  0x40,  0x04,  0x00,  0x04, 	/* 2EB00 */
+	0x9E,  0x08,  0x04,  0x08,  0x84,  0x08,  0x84,  0x08,  0x84,  0x08,  0x84,  0x2C,  0xA4,  0x2A,  0x94,  0x2A, 	/* 2EB10 */
+	0x94,  0x2A,  0x94,  0x48,  0x84,  0x08,  0x84,  0x10,  0x84,  0x10,  0x84,  0x10,  0x84,  0x20,  0x04,  0x40, 	/* 2EB20 */
+	0x04,  0xA1,  0x00,  0x00,  0x20,  0x92,  0x10,  0x92,  0x11,  0x24,  0x01,  0x24,  0x02,  0x48,  0x04,  0x90, 	/* 2EB30 */
+	0x7C,  0x90,  0x0A,  0x48,  0x09,  0x24,  0x09,  0x24,  0x08,  0x92,  0x14,  0x92,  0x12,  0x00,  0x21,  0x80, 	/* 2EB40 */
+	0x40,  0x7F,  0xA3,  0x09,  0x08,  0x04,  0x88,  0x04,  0x90,  0x0F,  0xF8,  0x08,  0x88,  0x0F,  0xF8,  0x08, 	/* 2EB50 */
+	0x88,  0x08,  0x88,  0x0F,  0xF8,  0x00,  0x80,  0x7F,  0xFE,  0x01,  0xC0,  0x02,  0xA0,  0x0C,  0x98,  0x30, 	/* 2EB60 */
+	0x86,  0x00,  0x80,  0xA5,  0x00,  0x00,  0x00,  0x00,  0x3F,  0xFE,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80, 	/* 2EB70 */
+	0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x7F,  0xFF, 	/* 2EB80 */
+	0x00,  0x00,  0x00,  0x00,  0xA6,  0x01,  0x00,  0x01,  0x00,  0x01,  0x00,  0x7F,  0xFE,  0x01,  0x00,  0x02, 	/* 2EB90 */
+	0x00,  0x02,  0x00,  0x02,  0x00,  0x07,  0xFC,  0x04,  0x40,  0x08,  0x40,  0x10,  0x40,  0x20,  0x40,  0x40, 	/* 2EBA0 */
+	0x40,  0x1F,  0xFF,  0x00,  0x00,  0xA7,  0x00,  0x00,  0x03,  0xFF,  0x7E,  0x20,  0x08,  0x20,  0x08,  0x40, 	/* 2EBB0 */
+	0x08,  0x40,  0x08,  0xFC,  0x08,  0x84,  0x08,  0x04,  0x0E,  0x04,  0x18,  0x04,  0x60,  0x04,  0x00,  0x04, 	/* 2EBC0 */
+	0x00,  0x04,  0x00,  0x08,  0x00,  0x70,  0xA8,  0x00,  0x00,  0x3F,  0xFC,  0x20,  0x00,  0x20,  0x00,  0x20, 	/* 2EBD0 */
+	0x00,  0x3F,  0xF0,  0x20,  0x10,  0x20,  0x10,  0x20,  0x10,  0x3F,  0xF0,  0x20,  0x00,  0x20,  0x00,  0x20, 	/* 2EBE0 */
+	0x00,  0x20,  0x00,  0x3F,  0xFC,  0x00,  0x00,  0xAB,  0x00,  0x00,  0x3F,  0xFE,  0x00,  0x80,  0x08,  0x88, 	/* 2EBF0 */
+	0x08,  0x88,  0x08,  0x88,  0x08,  0x88,  0x0C,  0x8C,  0x14,  0x94,  0x12,  0x92,  0x22,  0xA2,  0x40,  0xC0, 	/* 2EC00 */
+	0x00,  0x80,  0x00,  0x80,  0x7F,  0xFF,  0x00,  0x00,  0xAE,  0x04,  0x10,  0x02,  0x20,  0x1F,  0xFE,  0x00, 	/* 2EC10 */
+	0x80,  0x00,  0x80,  0x0F,  0xF8,  0x00,  0x80,  0x00,  0x80,  0x7F,  0xFF,  0x04,  0x00,  0x07,  0xFC,  0x08, 	/* 2EC20 */
+	0x40,  0x08,  0x40,  0x10,  0x40,  0x2F,  0xFF,  0x40,  0x00,  0xB1,  0x00,  0x00,  0x3F,  0xF8,  0x00,  0x08, 	/* 2EC30 */
+	0x00,  0x08,  0x00,  0x08,  0x00,  0x08,  0x1F,  0xF8,  0x10,  0x00,  0x10,  0x00,  0x10,  0x00,  0x10,  0x00, 	/* 2EC40 */
+	0x10,  0x04,  0x10,  0x04,  0x08,  0x04,  0x07,  0xFC,  0x00,  0x00,  0xB2,  0x00,  0x00,  0x7F,  0xFC,  0x00, 	/* 2EC50 */
+	0x04,  0x20,  0x04,  0x20,  0x04,  0x20,  0x04,  0x3F,  0xFC,  0x20,  0x00,  0x20,  0x00,  0x20,  0x00,  0x20, 	/* 2EC60 */
+	0x00,  0x20,  0x02,  0x20,  0x02,  0x10,  0x02,  0x0F,  0xFE,  0x00,  0x00,  0xB3,  0x00,  0x00,  0x3F,  0xF8, 	/* 2EC70 */
+	0x20,  0x08,  0x20,  0x08,  0x20,  0x08,  0x20,  0x08,  0x3F,  0xF8,  0x20,  0x00,  0x20,  0x00,  0x20,  0x00, 	/* 2EC80 */
+	0x20,  0x00,  0x20,  0x00,  0x20,  0x02,  0x10,  0x02,  0x0F,  0xFE,  0x00,  0x00,  0xB4,  0x00,  0x00,  0x3F, 	/* 2EC90 */
+	0xF8,  0x21,  0x08,  0x21,  0x08,  0x21,  0x08,  0x21,  0x08,  0x21,  0x08,  0x3F,  0xF8,  0x20,  0x00,  0x20, 	/* 2ECA0 */
+	0x00,  0x20,  0x00,  0x20,  0x02,  0x20,  0x02,  0x10,  0x02,  0x0F,  0xFE,  0x00,  0x00,  0xB5,  0x00,  0x08, 	/* 2ECB0 */
+	0x00,  0x30,  0x1F,  0xC0,  0x10,  0x00,  0x1F,  0xFF,  0x10,  0x00,  0x17,  0xFC,  0x14,  0x44,  0x14,  0x44, 	/* 2ECC0 */
+	0x14,  0x44,  0x17,  0xFC,  0x14,  0x00,  0x24,  0x02,  0x24,  0x02,  0x42,  0x02,  0x01,  0xFE,  0xB7,  0x02, 	/* 2ECD0 */
+	0x20,  0x02,  0x20,  0x1F,  0xFC,  0x02,  0x20,  0x02,  0x20,  0x7F,  0xFF,  0x02,  0x20,  0x04,  0x10,  0x0F, 	/* 2ECE0 */
+	0xF8,  0x10,  0x14,  0x60,  0x13,  0x07,  0xF0,  0x04,  0x00,  0x04,  0x04,  0x04,  0x04,  0x03,  0xFC,  0xBB, 	/* 2ECF0 */
+	0x08,  0x88,  0x04,  0x88,  0x04,  0x90,  0x1F,  0xFE,  0x00,  0x80,  0x01,  0x40,  0x7F,  0xFF,  0x02,  0x20, 	/* 2ED00 */
+	0x07,  0xF0,  0x18,  0x1C,  0x60,  0x13,  0x07,  0xF0,  0x04,  0x00,  0x04,  0x08,  0x04,  0x08,  0x03,  0xF8, 	/* 2ED10 */
+	0xBD,  0x00,  0x00,  0x3E,  0x7C,  0x02,  0x04,  0x3E,  0x7C,  0x20,  0x40,  0x21,  0x42,  0x1F,  0x3E,  0x00, 	/* 2ED20 */
+	0x00,  0x02,  0x20,  0x1F,  0xFC,  0x02,  0x20,  0x02,  0x20,  0x7F,  0xFF,  0x02,  0x60,  0x0C,  0x18,  0x30, 	/* 2ED30 */
+	0x04,  0xBE,  0x01,  0x00,  0x01,  0x00,  0x01,  0x00,  0x01,  0x00,  0x3F,  0xFC,  0x21,  0x04,  0x21,  0x04, 	/* 2ED40 */
+	0x21,  0x04,  0x21,  0x04,  0x21,  0x04,  0x21,  0x04,  0x21,  0x18,  0x21,  0x00,  0x01,  0x00,  0x01,  0x00, 	/* 2ED50 */
+	0x01,  0x00,  0x82,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x7F,  0xFF,  0x00,  0x80,  0x00,  0x80,  0x1F, 	/* 2ED60 */
+	0xFC,  0x10,  0x84,  0x10,  0x84,  0x10,  0x84,  0x10,  0x84,  0x10,  0x84,  0x10,  0x98,  0x00,  0x80,  0x00, 	/* 2ED70 */
+	0x80,  0x00,  0x80,  0x83,  0x01,  0x00,  0x01,  0x00,  0x01,  0x00,  0x7F,  0xFF,  0x02,  0x40,  0x02,  0x40, 	/* 2ED80 */
+	0x04,  0x40,  0x07,  0xFC,  0x0C,  0x44,  0x14,  0x44,  0x24,  0x44,  0x44,  0x44,  0x04,  0x44,  0x04,  0x58, 	/* 2ED90 */
+	0x00,  0x40,  0x00,  0x40,  0x86,  0x10,  0x00,  0x10,  0x7C,  0x10,  0x44,  0x7E,  0x44,  0x52,  0x44,  0x52, 	/* 2EDA0 */
+	0x64,  0x52,  0x54,  0x52,  0x54,  0x52,  0x54,  0x52,  0x44,  0x56,  0x44,  0x50,  0x44,  0x10,  0x84,  0x10, 	/* 2EDB0 */
+	0x85,  0x11,  0x05,  0x12,  0x03,  0x8B,  0x00,  0x04,  0x00,  0x38,  0x1F,  0xC0,  0x10,  0x40,  0x1F,  0xFF, 	/* 2EDC0 */
+	0x10,  0x40,  0x10,  0x22,  0x1E,  0x1A,  0x70,  0x86,  0x00,  0x80,  0x1F,  0xFC,  0x10,  0x84,  0x10,  0x84, 	/* 2EDD0 */
+	0x10,  0x84,  0x10,  0x98,  0x00,  0x80,  0x8C,  0x06,  0x04,  0x01,  0x98,  0x00,  0x60,  0x03,  0xB0,  0x3C, 	/* 2EDE0 */
+	0x88,  0x01,  0x00,  0x7F,  0xFF,  0x02,  0x40,  0x04,  0x40,  0x0F,  0xFE,  0x14,  0x42,  0x24,  0x42,  0x44, 	/* 2EDF0 */
+	0x42,  0x04,  0x42,  0x04,  0x4C,  0x00,  0x40,  0x91,  0x04,  0x00,  0x04,  0x00,  0x7F,  0xFE,  0x09,  0x22, 	/* 2EE00 */
+	0x09,  0x22,  0x11,  0x14,  0x3E,  0x08,  0x04,  0x94,  0x18,  0xE3,  0x60,  0x80,  0x1F,  0xFC,  0x10,  0x84, 	/* 2EE10 */
+	0x10,  0x84,  0x10,  0x84,  0x10,  0x98,  0x00,  0x80,  0x96,  0x10,  0x20,  0x10,  0x20,  0x10,  0x20,  0x7E, 	/* 2EE20 */
+	0x20,  0x52,  0x3F,  0x52,  0x20,  0x52,  0x20,  0x52,  0x20,  0x52,  0xFC,  0x52,  0x84,  0x56,  0x84,  0x50, 	/* 2EE30 */
+	0x84,  0x10,  0x84,  0x10,  0x84,  0x10,  0xFC,  0x10,  0x00,  0x99,  0x10,  0x10,  0x10,  0x50,  0x10,  0x50, 	/* 2EE40 */
+	0x7E,  0x7E,  0x52,  0x90,  0x52,  0x90,  0x53,  0x10,  0x53,  0xFF,  0x52,  0x10,  0x52,  0x10,  0x56,  0x28, 	/* 2EE50 */
+	0x50,  0x28,  0x10,  0x44,  0x10,  0x84,  0x11,  0x02,  0x12,  0x01,  0x9A,  0x00,  0x00,  0x1F,  0xF8,  0x00, 	/* 2EE60 */
+	0x08,  0x7F,  0xFF,  0x00,  0x08,  0x1F,  0xF8,  0x00,  0x00,  0x7F,  0xFE,  0x41,  0x02,  0x41,  0x02,  0x1F, 	/* 2EE70 */
+	0xF8,  0x11,  0x08,  0x11,  0x08,  0x11,  0x08,  0x11,  0x30,  0x01,  0x00,  0x9B,  0x01,  0x00,  0x02,  0x00, 	/* 2EE80 */
+	0x1F,  0xF8,  0x10,  0x08,  0x1F,  0xF8,  0x10,  0x08,  0x10,  0x08,  0x1F,  0xF8,  0x01,  0x00,  0x3F,  0xFC, 	/* 2EE90 */
+	0x21,  0x04,  0x21,  0x04,  0x21,  0x04,  0x21,  0x18,  0x21,  0x00,  0x01,  0x00,  0x9D,  0x00,  0x80,  0x00, 	/* 2EEA0 */
+	0x80,  0x3F,  0xFE,  0x08,  0x10,  0x04,  0x10,  0x04,  0x20,  0x7F,  0xFE,  0x40,  0x82,  0x40,  0x82,  0x0F, 	/* 2EEB0 */
+	0xF8,  0x08,  0x88,  0x08,  0x88,  0x08,  0x88,  0x08,  0xB0,  0x08,  0x80,  0x00,  0x80,  0xA5,  0x08,  0x10, 	/* 2EEC0 */
+	0x10,  0x10,  0x3E,  0x10,  0x22,  0xFE,  0x22,  0x92,  0x22,  0x92,  0x3E,  0x92,  0x20,  0x92,  0x20,  0x92, 	/* 2EED0 */
+	0x3E,  0x92,  0x22,  0x92,  0x22,  0x9C,  0x22,  0x90,  0x3E,  0x90,  0x00,  0x10,  0x00,  0x10,  0xAB,  0x04, 	/* 2EEE0 */
+	0x00,  0x09,  0xFF,  0x3E,  0x10,  0x22,  0x10,  0x22,  0xFE,  0x22,  0x92,  0x3E,  0x92,  0x20,  0x92,  0x20, 	/* 2EEF0 */
+	0x92,  0x3E,  0x92,  0x22,  0x92,  0x22,  0x92,  0x22,  0x9C,  0x3E,  0x90,  0x00,  0x10,  0x00,  0x10,  0xAD, 	/* 2EF00 */
+	0x00,  0x40,  0x00,  0x40,  0x1F,  0xFF,  0x11,  0x10,  0x11,  0x10,  0x1F,  0xFE,  0x11,  0x10,  0x11,  0x10, 	/* 2EF10 */
+	0x11,  0xF0,  0x10,  0x40,  0x17,  0xFC,  0x14,  0x44,  0x24,  0x44,  0x24,  0x44,  0x44,  0x58,  0x00,  0x40, 	/* 2EF20 */
+	0xAF,  0x08,  0x88,  0x08,  0x88,  0x7F,  0xFF,  0x08,  0x88,  0x08,  0x88,  0x0F,  0xF8,  0x00,  0x00,  0x7F, 	/* 2EF30 */
+	0xFE,  0x40,  0x82,  0x4F,  0xFA,  0x08,  0x88,  0x08,  0x88,  0x08,  0x88,  0x08,  0xB0,  0x08,  0x80,  0x00, 	/* 2EF40 */
+	0x80,  0xB0,  0x08,  0x00,  0x09,  0xFC,  0x08,  0x04,  0x28,  0xFC,  0x28,  0x04,  0x29,  0xFC,  0x28,  0x00, 	/* 2EF50 */
+	0x2B,  0xFF,  0x2A,  0x21,  0x4A,  0x21,  0x09,  0xFC,  0x09,  0x24,  0x09,  0x24,  0x11,  0x24,  0x11,  0x2C, 	/* 2EF60 */
+	0x20,  0x20,  0xB3,  0x10,  0x00,  0x10,  0x7E,  0x10,  0x40,  0x7E,  0x7C,  0x52,  0x40,  0x52,  0x7C,  0x52, 	/* 2EF70 */
+	0x40,  0x52,  0x40,  0x53,  0xFF,  0x52,  0x52,  0x56,  0x54,  0x50,  0x48,  0x10,  0x48,  0x10,  0x74,  0x10, 	/* 2EF80 */
+	0xC2,  0x11,  0x01,  0xB6,  0x0A,  0xA0,  0x0A,  0xA0,  0x7F,  0xFF,  0x0A,  0xA0,  0x0A,  0xA4,  0x13,  0x9C, 	/* 2EF90 */
+	0x20,  0x00,  0x7F,  0xFE,  0x41,  0x02,  0x41,  0x02,  0x1F,  0xF8,  0x11,  0x08,  0x11,  0x08,  0x11,  0x30, 	/* 2EFA0 */
+	0x11,  0x00,  0x01,  0x00,  0xB7,  0x10,  0x24,  0x10,  0x24,  0x10,  0x48,  0x7E,  0x7F,  0x52,  0xC8,  0x52, 	/* 2EFB0 */
+	0xC8,  0x53,  0x48,  0x52,  0x7E,  0x52,  0x48,  0x52,  0x48,  0x56,  0x7E,  0x50,  0x48,  0x10,  0x48,  0x10, 	/* 2EFC0 */
+	0x48,  0x10,  0x7F,  0x10,  0x00,  0xB8,  0x11,  0x08,  0x09,  0x08,  0x09,  0x10,  0x7F,  0xFE,  0x40,  0x02, 	/* 2EFD0 */
+	0x4F,  0xF2,  0x48,  0x12,  0x08,  0x10,  0x0F,  0xF0,  0x01,  0x00,  0x1F,  0xF8,  0x11,  0x08,  0x11,  0x08, 	/* 2EFE0 */
+	0x11,  0x08,  0x11,  0x30,  0x01,  0x00,  0xBD,  0x10,  0x00,  0x11,  0xFE,  0x11,  0x02,  0x7F,  0xFE,  0x53, 	/* 2EFF0 */
+	0x02,  0x53,  0xFE,  0x52,  0x00,  0x52,  0xFC,  0x52,  0x84,  0x52,  0xFC,  0x5C,  0x84,  0x50,  0xFC,  0x50, 	/* 2F000 */
+	0x84,  0x10,  0x84,  0x10,  0xFC,  0x10,  0x00,  0x80,  0x10,  0x20,  0x10,  0x20,  0x10,  0x3F,  0x7E,  0x20, 	/* 2F010 */
+	0x52,  0xFC,  0x52,  0x84,  0x52,  0x84,  0x52,  0xFC,  0x52,  0x84,  0x52,  0xFC,  0x56,  0x84,  0x50,  0x84, 	/* 2F020 */
+	0x10,  0xFC,  0x10,  0x48,  0x10,  0x84,  0x13,  0x02,  0x83,  0x10,  0x20,  0x11,  0xFC,  0x10,  0x44,  0x7C, 	/* 2F030 */
+	0x44,  0x57,  0xFF,  0x54,  0x00,  0x54,  0xFC,  0x54,  0x84,  0x54,  0xFC,  0x54,  0x08,  0x5D,  0xFE,  0x10, 	/* 2F040 */
+	0x88,  0x10,  0x88,  0x13,  0xFF,  0x10,  0x08,  0x10,  0x08,  0x84,  0x10,  0x00,  0x11,  0xFE,  0x11,  0x02, 	/* 2F050 */
+	0x7D,  0x02,  0x55,  0xFE,  0x55,  0x00,  0x55,  0xFF,  0x55,  0x28,  0x55,  0x44,  0x55,  0xFA,  0x5D,  0x10, 	/* 2F060 */
+	0x52,  0xFE,  0x12,  0x10,  0x14,  0x10,  0x19,  0xFF,  0x10,  0x00,  0x85,  0x10,  0x00,  0x11,  0xFE,  0x10, 	/* 2F070 */
+	0x00,  0x7E,  0xFC,  0x52,  0x84,  0x52,  0x84,  0x52,  0xFC,  0x52,  0x00,  0x53,  0xFE,  0x53,  0x22,  0x53, 	/* 2F080 */
+	0x22,  0x57,  0xFE,  0x51,  0x22,  0x11,  0x22,  0x11,  0xFE,  0x10,  0x00,  0x87,  0x04,  0x04,  0x3F,  0x04, 	/* 2F090 */
+	0x04,  0x7F,  0x7F,  0x84,  0x04,  0x24,  0x3F,  0x14,  0x04,  0x14,  0x07,  0x84,  0x79,  0x0C,  0x01,  0x00, 	/* 2F0A0 */
+	0x1F,  0xFC,  0x11,  0x04,  0x11,  0x04,  0x11,  0x18,  0x11,  0x00,  0x01,  0x00,  0x8C,  0x10,  0x00,  0x10, 	/* 2F0B0 */
+	0xFC,  0x10,  0x84,  0x7E,  0xFC,  0x52,  0x84,  0x52,  0xFC,  0x52,  0x92,  0x52,  0x52,  0x52,  0x54,  0x53, 	/* 2F0C0 */
+	0xFF,  0x56,  0x48,  0x50,  0x48,  0x50,  0x48,  0x10,  0x89,  0x11,  0x09,  0x16,  0x07,  0x8E,  0x10,  0x00, 	/* 2F0D0 */
+	0x11,  0xFF,  0x11,  0x01,  0x7D,  0x7D,  0x54,  0x44,  0x54,  0x44,  0x54,  0x7C,  0x54,  0x44,  0x54,  0x44, 	/* 2F0E0 */
+	0x54,  0x7C,  0x5C,  0x10,  0x53,  0xFF,  0x10,  0x00,  0x10,  0x44,  0x10,  0x82,  0x13,  0x02,  0x94,  0x10, 	/* 2F0F0 */
+	0x00,  0x10,  0xFE,  0x10,  0x82,  0x7C,  0xFE,  0x54,  0x82,  0x54,  0xFE,  0x54,  0x00,  0x55,  0xFF,  0x55, 	/* 2F100 */
+	0x29,  0x55,  0xFF,  0x5C,  0x00,  0x51,  0xFE,  0x10,  0x64,  0x10,  0x18,  0x10,  0x6C,  0x13,  0x83,  0x95, 	/* 2F110 */
+	0x02,  0x10,  0x7F,  0xFF,  0x02,  0x10,  0x07,  0xF8,  0x04,  0x08,  0x07,  0xF8,  0x04,  0x08,  0x07,  0xF8, 	/* 2F120 */
+	0x01,  0x00,  0x7F,  0xFF,  0x04,  0x90,  0x0F,  0xFC,  0x14,  0x8B,  0x64,  0x88,  0x04,  0xB0,  0x00,  0x80, 	/* 2F130 */
+	0x97,  0x10,  0x00,  0x11,  0xFE,  0x11,  0x1A,  0x7D,  0x16,  0x55,  0xFE,  0x55,  0x12,  0x55,  0x76,  0x55, 	/* 2F140 */
+	0x56,  0x55,  0x76,  0x55,  0x1A,  0x5D,  0xEA,  0x11,  0x1E,  0x11,  0x26,  0x11,  0x42,  0x11,  0xFE,  0x10, 	/* 2F150 */
+	0x00,  0x9F,  0x10,  0x88,  0x10,  0x8C,  0x13,  0xFA,  0x7D,  0x2A,  0x54,  0xA8,  0x54,  0xC8,  0x57,  0xFF, 	/* 2F160 */
+	0x54,  0x08,  0x55,  0xEA,  0x55,  0x2A,  0x5D,  0xEA,  0x51,  0x24,  0x11,  0x25,  0x11,  0xEB,  0x10,  0x13, 	/* 2F170 */
+	0x10,  0x21,  0xA1,  0x10,  0x04,  0x10,  0x18,  0x11,  0xE4,  0x7D,  0x24,  0x54,  0xA8,  0x57,  0xFF,  0x54, 	/* 2F180 */
+	0x70,  0x54,  0xA8,  0x55,  0x24,  0x57,  0xFE,  0x5D,  0x25,  0x51,  0xFC,  0x11,  0x24,  0x11,  0x24,  0x11, 	/* 2F190 */
+	0xFC,  0x10,  0x00,  0xA2,  0x10,  0x20,  0x13,  0xFE,  0x10,  0x88,  0x7C,  0x50,  0x57,  0xFF,  0x54,  0x00, 	/* 2F1A0 */
+	0x55,  0xFC,  0x55,  0x24,  0x55,  0xFC,  0x55,  0x24,  0x5D,  0xFC,  0x10,  0x20,  0x11,  0xFE,  0x10,  0x20, 	/* 2F1B0 */
+	0x17,  0xFF,  0x10,  0x00,  0xA3,  0x04,  0x10,  0x25,  0x10,  0x16,  0x1F,  0x3F,  0xA2,  0x24,  0xB2,  0x2E, 	/* 2F1C0 */
+	0xCC,  0x35,  0x84,  0x24,  0x9A,  0x25,  0xE1,  0x00,  0x80,  0x0F,  0xFC,  0x08,  0x84,  0x08,  0x84,  0x08, 	/* 2F1D0 */
+	0x98,  0x08,  0x80,  0x00,  0x80,  0xA4,  0x08,  0x20,  0x2A,  0x20,  0x49,  0x3F,  0x7F,  0x44,  0x41,  0x64, 	/* 2F1E0 */
+	0x5D,  0x94,  0x55,  0x08,  0x5D,  0x14,  0x43,  0x62,  0x00,  0x81,  0x1F,  0xFC,  0x10,  0x84,  0x10,  0x84, 	/* 2F1F0 */
+	0x10,  0x84,  0x10,  0x98,  0x00,  0x80,  0xB2,  0x00,  0x00,  0x1F,  0xFC,  0x00,  0x80,  0x00,  0x80,  0x00, 	/* 2F200 */
+	0x80,  0x00,  0x80,  0x00,  0x80,  0x7F,  0xFF,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x00, 	/* 2F210 */
+	0x80,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0xB3,  0x00,  0x00,  0x1F,  0xFC,  0x00,  0x80,  0x08,  0x88, 	/* 2F220 */
+	0x04,  0x88,  0x04,  0x90,  0x04,  0xA0,  0x00,  0x80,  0x7F,  0xFF,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80, 	/* 2F230 */
+	0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0xB4,  0x04,  0x00,  0x04,  0x00,  0x0F,  0xFE,  0x08, 	/* 2F240 */
+	0x40,  0x10,  0x40,  0x20,  0x40,  0x4F,  0xFC,  0x08,  0x40,  0x08,  0x40,  0x08,  0x40,  0x08,  0x40,  0x7F, 	/* 2F250 */
+	0xFF,  0x00,  0x40,  0x00,  0x40,  0x00,  0x40,  0x00,  0x40,  0xB5,  0x00,  0x00,  0x3E,  0x3E,  0x08,  0x08, 	/* 2F260 */
+	0x08,  0x08,  0x08,  0x08,  0x08,  0x08,  0x08,  0x08,  0x7F,  0x7F,  0x08,  0x08,  0x08,  0x08,  0x08,  0x08, 	/* 2F270 */
+	0x08,  0x08,  0x08,  0x08,  0x08,  0x08,  0x08,  0x08,  0x08,  0x08,  0xB6,  0x08,  0x10,  0x04,  0x10,  0x04, 	/* 2F280 */
+	0x20,  0x3F,  0xFC,  0x04,  0x20,  0x04,  0x20,  0x04,  0x20,  0x04,  0x20,  0x7F,  0xFF,  0x04,  0x20,  0x04, 	/* 2F290 */
+	0x20,  0x04,  0x20,  0x08,  0x20,  0x08,  0x20,  0x10,  0x20,  0x20,  0x20,  0xB8,  0x00,  0x80,  0x00,  0x80, 	/* 2F2A0 */
+	0x1F,  0xFC,  0x00,  0x80,  0x00,  0x80,  0x7F,  0xFF,  0x04,  0x10,  0x02,  0x10,  0x02,  0x20,  0x3F,  0xFE, 	/* 2F2B0 */
+	0x00,  0x80,  0x00,  0x80,  0x1F,  0xFC,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0xB9,  0x08,  0x10,  0x08, 	/* 2F2C0 */
+	0x10,  0x7F,  0x28,  0x08,  0x28,  0x3E,  0x44,  0x22,  0x82,  0x23,  0x7D,  0x3E,  0x10,  0x22,  0x10,  0x22, 	/* 2F2D0 */
+	0x10,  0x3F,  0xFF,  0x08,  0x10,  0x7F,  0x10,  0x08,  0x10,  0x08,  0x10,  0x08,  0x10,  0xBA,  0x00,  0x80, 	/* 2F2E0 */
+	0x00,  0x80,  0x00,  0x80,  0x01,  0x00,  0x01,  0x10,  0x02,  0x10,  0x1C,  0x20,  0x02,  0x20,  0x01,  0x40, 	/* 2F2F0 */
+	0x01,  0x80,  0x00,  0x90,  0x01,  0x08,  0x02,  0x04,  0x04,  0x7C,  0x7F,  0x82,  0x00,  0x02,  0xBB,  0x04, 	/* 2F300 */
+	0x00,  0x04,  0x7E,  0x04,  0x02,  0x08,  0x02,  0x09,  0x02,  0x71,  0x02,  0x11,  0x02,  0x0A,  0x02,  0x06, 	/* 2F310 */
+	0x02,  0x04,  0x02,  0x05,  0x02,  0x08,  0x82,  0x08,  0x82,  0x7F,  0x42,  0x00,  0x44,  0x00,  0x18,  0xBC, 	/* 2F320 */
+	0x04,  0x20,  0x04,  0x20,  0x04,  0x20,  0x08,  0x20,  0x0A,  0xFE,  0x12,  0x22,  0x62,  0x22,  0x14,  0x22, 	/* 2F330 */
+	0x0C,  0x22,  0x06,  0x22,  0x0A,  0x22,  0x09,  0x42,  0x13,  0x42,  0x1C,  0x82,  0x61,  0x04,  0x02,  0x18, 	/* 2F340 */
+	0xBD,  0x00,  0x80,  0x24,  0x92,  0x24,  0x92,  0x24,  0x92,  0x25,  0x96,  0x39,  0xE6,  0x2E,  0x9A,  0x22, 	/* 2F350 */
+	0x8A,  0x24,  0x92,  0x26,  0x9A,  0x2A,  0xAA,  0x2F,  0xBE,  0x39,  0xE6,  0x21,  0x86,  0x3F,  0xFE,  0x20, 	/* 2F360 */
+	0x02,  0xBE,  0x08,  0x90,  0x08,  0x90,  0x32,  0xE4,  0x0A,  0x94,  0x04,  0x88,  0x0A,  0x94,  0x0E,  0x9C, 	/* 2F370 */
+	0x31,  0xF2,  0x00,  0x88,  0x7F,  0xFF,  0x04,  0x40,  0x06,  0x44,  0x09,  0x28,  0x08,  0x32,  0x10,  0xCA, 	/* 2F380 */
+	0x23,  0x06,  0xBF,  0x00,  0x80,  0x00,  0x80,  0x1F,  0xFE,  0x10,  0x00,  0x10,  0x00,  0x10,  0x00,  0x10, 	/* 2F390 */
+	0x00,  0x10,  0x00,  0x10,  0x00,  0x10,  0x00,  0x10,  0x00,  0x10,  0x00,  0x20,  0x00,  0x20,  0x00,  0x40, 	/* 2F3A0 */
+	0x00,  0x00,  0x00,  0x81,  0x00,  0x40,  0x00,  0x40,  0x1F,  0xFF,  0x10,  0x00,  0x10,  0x00,  0x10,  0x00, 	/* 2F3B0 */
+	0x17,  0xFE,  0x10,  0x20,  0x10,  0x20,  0x10,  0x20,  0x10,  0x20,  0x10,  0x20,  0x20,  0x20,  0x20,  0x20, 	/* 2F3C0 */
+	0x40,  0x20,  0x00,  0x60,  0x83,  0x00,  0x40,  0x00,  0x40,  0x00,  0x40,  0x1F,  0xFF,  0x10,  0x00,  0x10, 	/* 2F3D0 */
+	0x80,  0x10,  0x80,  0x10,  0x80,  0x10,  0x80,  0x10,  0x80,  0x11,  0x10,  0x11,  0x08,  0x11,  0x04,  0x22, 	/* 2F3E0 */
+	0x7C,  0x2F,  0x82,  0x40,  0x02,  0x84,  0x00,  0x40,  0x00,  0x40,  0x1F,  0xFF,  0x10,  0x00,  0x10,  0x40, 	/* 2F3F0 */
+	0x10,  0x40,  0x10,  0x40,  0x10,  0x40,  0x17,  0xFC,  0x10,  0x40,  0x10,  0x40,  0x10,  0x40,  0x20,  0x40, 	/* 2F400 */
+	0x20,  0x40,  0x5F,  0xFF,  0x00,  0x00,  0x87,  0x00,  0x40,  0x00,  0x40,  0x1F,  0xFF,  0x10,  0x00,  0x12, 	/* 2F410 */
+	0x20,  0x12,  0x20,  0x12,  0x22,  0x12,  0x24,  0x13,  0xB8,  0x12,  0x20,  0x12,  0x20,  0x12,  0x20,  0x22, 	/* 2F420 */
+	0x22,  0x22,  0x62,  0x43,  0xA2,  0x0E,  0x1E,  0x8A,  0x00,  0x40,  0x00,  0x40,  0x1F,  0xFF,  0x10,  0x40, 	/* 2F430 */
+	0x10,  0x40,  0x10,  0x40,  0x1F,  0xFF,  0x10,  0xE0,  0x10,  0xE0,  0x11,  0x50,  0x11,  0x50,  0x12,  0x48, 	/* 2F440 */
+	0x24,  0x44,  0x28,  0x42,  0x40,  0x40,  0x00,  0x40,  0x8F,  0x00,  0x40,  0x00,  0x40,  0x1F,  0xFF,  0x10, 	/* 2F450 */
+	0x00,  0x17,  0xF8,  0x10,  0x10,  0x11,  0xA0,  0x10,  0x40,  0x1F,  0xFE,  0x10,  0x44,  0x10,  0x48,  0x10, 	/* 2F460 */
+	0x50,  0x20,  0x40,  0x20,  0x40,  0x40,  0x40,  0x00,  0xC0,  0x95,  0x00,  0x40,  0x00,  0x40,  0x1F,  0xFF, 	/* 2F470 */
+	0x10,  0x04,  0x10,  0x18,  0x13,  0xE0,  0x12,  0x20,  0x12,  0x20,  0x13,  0xFF,  0x12,  0x10,  0x12,  0x10, 	/* 2F480 */
+	0x13,  0x88,  0x2C,  0x08,  0x20,  0x05,  0x47,  0xE3,  0x00,  0x01,  0x96,  0x00,  0x80,  0x00,  0x80,  0x1F, 	/* 2F490 */
+	0xFF,  0x12,  0x00,  0x12,  0x00,  0x13,  0xFC,  0x14,  0x04,  0x17,  0xE4,  0x18,  0x24,  0x10,  0x24,  0x17, 	/* 2F4A0 */
+	0xE4,  0x14,  0x18,  0x24,  0x02,  0x24,  0x02,  0x42,  0x02,  0x01,  0xFE,  0x97,  0x00,  0x40,  0x00,  0x40, 	/* 2F4B0 */
+	0x1F,  0xFF,  0x10,  0x00,  0x10,  0x40,  0x10,  0x40,  0x10,  0x7E,  0x10,  0x40,  0x10,  0x40,  0x10,  0x40, 	/* 2F4C0 */
+	0x17,  0xFC,  0x14,  0x04,  0x14,  0x04,  0x24,  0x04,  0x27,  0xFC,  0x40,  0x00,  0x9A,  0x00,  0x80,  0x00, 	/* 2F4D0 */
+	0x80,  0x1F,  0xFF,  0x10,  0x40,  0x17,  0xFC,  0x10,  0x44,  0x10,  0x44,  0x1F,  0xFF,  0x10,  0x44,  0x17, 	/* 2F4E0 */
+	0xFC,  0x10,  0x40,  0x10,  0x40,  0x20,  0xA0,  0x21,  0x10,  0x46,  0x0C,  0x18,  0x03,  0x9C,  0x00,  0x40, 	/* 2F4F0 */
+	0x00,  0x40,  0x1F,  0xFE,  0x10,  0x00,  0x11,  0x08,  0x11,  0x08,  0x11,  0xFF,  0x12,  0x08,  0x12,  0x88, 	/* 2F500 */
+	0x16,  0x48,  0x1A,  0x48,  0x12,  0x08,  0x22,  0x08,  0x22,  0x08,  0x42,  0x08,  0x02,  0x18,  0xA0,  0x00, 	/* 2F510 */
+	0x40,  0x00,  0x40,  0x1F,  0xFF,  0x10,  0x00,  0x12,  0x08,  0x11,  0x10,  0x17,  0xFE,  0x10,  0x40,  0x10, 	/* 2F520 */
+	0x40,  0x13,  0xFC,  0x10,  0x40,  0x10,  0x40,  0x2F,  0xFF,  0x20,  0x40,  0x40,  0x40,  0x00,  0x40,  0xA6, 	/* 2F530 */
+	0x00,  0x40,  0x00,  0x40,  0x1F,  0xFE,  0x11,  0x10,  0x11,  0x10,  0x1F,  0xFE,  0x11,  0x10,  0x11,  0xF0, 	/* 2F540 */
+	0x10,  0x00,  0x17,  0xF8,  0x11,  0x08,  0x10,  0x90,  0x10,  0x60,  0x20,  0xA0,  0x23,  0x18,  0x5C,  0x06, 	/* 2F550 */
+	0xA7,  0x00,  0x80,  0x00,  0x80,  0x1F,  0xFF,  0x10,  0x00,  0x12,  0x48,  0x12,  0x48,  0x12,  0x48,  0x15, 	/* 2F560 */
+	0x54,  0x15,  0x54,  0x18,  0xE2,  0x17,  0xFC,  0x20,  0x40,  0x20,  0x40,  0x40,  0x40,  0x1F,  0xFF,  0x00, 	/* 2F570 */
+	0x00,  0xAB,  0x00,  0x40,  0x1F,  0xFF,  0x10,  0x40,  0x10,  0x40,  0x1F,  0xFE,  0x10,  0x40,  0x17,  0xFC, 	/* 2F580 */
+	0x14,  0x44,  0x17,  0xFC,  0x14,  0x44,  0x14,  0x44,  0x27,  0xFC,  0x20,  0x40,  0x3F,  0xFF,  0x40,  0x40, 	/* 2F590 */
+	0x00,  0x40,  0xAD,  0x00,  0x40,  0x00,  0x40,  0x1F,  0xFF,  0x10,  0x00,  0x10,  0x02,  0x1F,  0x7C,  0x11, 	/* 2F5A0 */
+	0x08,  0x12,  0x08,  0x17,  0x7F,  0x11,  0x08,  0x15,  0x08,  0x15,  0x08,  0x22,  0x3E,  0x25,  0x00,  0x48, 	/* 2F5B0 */
+	0xC0,  0x10,  0x3F,  0xB5,  0x00,  0x80,  0x00,  0x80,  0x1F,  0xFE,  0x10,  0x40,  0x1F,  0xFE,  0x10,  0xA0, 	/* 2F5C0 */
+	0x11,  0x10,  0x13,  0xFC,  0x1E,  0x4B,  0x12,  0x48,  0x13,  0xF8,  0x12,  0x48,  0x22,  0x48,  0x23,  0xFA, 	/* 2F5D0 */
+	0x40,  0x42,  0x00,  0x3E,  0xB6,  0x00,  0x80,  0x00,  0x80,  0x1F,  0xFE,  0x10,  0x00,  0x11,  0x10,  0x11, 	/* 2F5E0 */
+	0x10,  0x1F,  0xFF,  0x11,  0x10,  0x11,  0x10,  0x11,  0x10,  0x11,  0xF0,  0x20,  0x00,  0x2A,  0x48,  0x49, 	/* 2F5F0 */
+	0x24,  0x11,  0x22,  0x20,  0x02,  0xB7,  0x00,  0x40,  0x00,  0x40,  0x1F,  0xFF,  0x10,  0x40,  0x17,  0xFC, 	/* 2F600 */
+	0x10,  0x44,  0x1F,  0xFF,  0x10,  0x44,  0x17,  0xFC,  0x14,  0x42,  0x12,  0x44,  0x12,  0xE8,  0x21,  0x50, 	/* 2F610 */
+	0x26,  0x4C,  0x58,  0x43,  0x00,  0xC0,  0xB8,  0x00,  0x80,  0x1F,  0xFF,  0x10,  0x40,  0x17,  0xFC,  0x10, 	/* 2F620 */
+	0x44,  0x1F,  0xFF,  0x10,  0x44,  0x17,  0xFC,  0x10,  0x40,  0x17,  0xFC,  0x14,  0x44,  0x17,  0xFC,  0x24, 	/* 2F630 */
+	0x44,  0x27,  0xFC,  0x44,  0x44,  0x04,  0x4C,  0x81,  0x00,  0x40,  0x00,  0x40,  0x1F,  0xFF,  0x10,  0x00, 	/* 2F640 */
+	0x17,  0xC2,  0x14,  0x52,  0x14,  0x52,  0x17,  0xD2,  0x14,  0x52,  0x17,  0xD2,  0x14,  0x52,  0x14,  0x52, 	/* 2F650 */
+	0x27,  0xD2,  0x22,  0x82,  0x44,  0x42,  0x08,  0x06,  0x82,  0x00,  0x40,  0x00,  0x40,  0x1F,  0xFF,  0x12, 	/* 2F660 */
+	0x00,  0x12,  0x00,  0x12,  0x3E,  0x1F,  0xE2,  0x12,  0x22,  0x13,  0x3E,  0x16,  0xA2,  0x16,  0xA2,  0x1A, 	/* 2F670 */
+	0x3E,  0x2A,  0x22,  0x22,  0x22,  0x42,  0x3E,  0x02,  0x00,  0x83,  0x00,  0x80,  0x00,  0x80,  0x1F,  0xFF, 	/* 2F680 */
+	0x10,  0x20,  0x17,  0x94,  0x10,  0x99,  0x15,  0x0A,  0x12,  0x04,  0x17,  0xFB,  0x18,  0x90,  0x10,  0x90, 	/* 2F690 */
+	0x17,  0xFF,  0x20,  0x90,  0x21,  0x11,  0x46,  0x11,  0x18,  0x0F,  0x88,  0x00,  0x40,  0x00,  0x40,  0x1F, 	/* 2F6A0 */
+	0xFF,  0x10,  0x00,  0x1F,  0xFF,  0x10,  0x40,  0x13,  0xF8,  0x12,  0x08,  0x13,  0xF8,  0x12,  0x08,  0x13, 	/* 2F6B0 */
+	0xF8,  0x10,  0x80,  0x21,  0xF0,  0x27,  0x10,  0x40,  0xE0,  0x1F,  0x1F,  0x89,  0x00,  0x80,  0x1F,  0xFF, 	/* 2F6C0 */
+	0x12,  0x08,  0x11,  0x10,  0x1F,  0xFE,  0x11,  0x20,  0x17,  0xFC,  0x11,  0x24,  0x1F,  0xFF,  0x11,  0x24, 	/* 2F6D0 */
+	0x17,  0xFC,  0x13,  0x30,  0x25,  0x28,  0x29,  0x24,  0x51,  0x22,  0x01,  0x20,  0x8A,  0x00,  0x40,  0x00, 	/* 2F6E0 */
+	0x40,  0x1F,  0xFF,  0x11,  0x00,  0x11,  0x1E,  0x17,  0xD2,  0x14,  0x54,  0x17,  0xD8,  0x14,  0x54,  0x17, 	/* 2F6F0 */
+	0xD2,  0x14,  0x11,  0x15,  0x11,  0x24,  0x99,  0x27,  0xD6,  0x58,  0x30,  0x00,  0x10,  0x8F,  0x00,  0x40, 	/* 2F700 */
+	0x00,  0x40,  0x1F,  0xFF,  0x12,  0x00,  0x17,  0xBC,  0x14,  0xA4,  0x17,  0xA5,  0x14,  0xA3,  0x14,  0xC0, 	/* 2F710 */
+	0x17,  0xBC,  0x10,  0x04,  0x14,  0xA4,  0x27,  0x18,  0x24,  0x18,  0x44,  0xA4,  0x03,  0xC3,  0x90,  0x00, 	/* 2F720 */
+	0x40,  0x00,  0x40,  0x1F,  0xFF,  0x12,  0x00,  0x17,  0xFE,  0x14,  0xA4,  0x17,  0xA4,  0x14,  0xA4,  0x14, 	/* 2F730 */
+	0xBF,  0x17,  0x88,  0x10,  0x08,  0x14,  0x8C,  0x27,  0x14,  0x24,  0x15,  0x44,  0xA5,  0x03,  0xC3,  0x93, 	/* 2F740 */
+	0x00,  0x80,  0x00,  0x80,  0x1F,  0xFF,  0x11,  0x00,  0x1F,  0xFE,  0x10,  0x12,  0x17,  0x94,  0x14,  0x98, 	/* 2F750 */
+	0x17,  0x94,  0x10,  0x12,  0x17,  0x92,  0x11,  0x12,  0x21,  0xD2,  0x2F,  0x1C,  0x41,  0x10,  0x03,  0x10, 	/* 2F760 */
+	0x96,  0x00,  0x40,  0x00,  0x40,  0x1F,  0xFF,  0x10,  0x00,  0x1F,  0xBE,  0x12,  0x8A,  0x15,  0x96,  0x12, 	/* 2F770 */
+	0xCA,  0x14,  0xA2,  0x13,  0x58,  0x1C,  0x97,  0x13,  0x20,  0x20,  0xC4,  0x23,  0x18,  0x40,  0x60,  0x07, 	/* 2F780 */
+	0x80,  0x9A,  0x00,  0x40,  0x00,  0x40,  0x1F,  0xFF,  0x11,  0x00,  0x1F,  0xE4,  0x11,  0x04,  0x17,  0xFF, 	/* 2F790 */
+	0x10,  0x04,  0x17,  0xC4,  0x14,  0xA4,  0x17,  0xA4,  0x10,  0x84,  0x24,  0x84,  0x23,  0x04,  0x43,  0xC4, 	/* 2F7A0 */
+	0x1C,  0x0C,  0x9B,  0x00,  0x40,  0x00,  0x40,  0x1F,  0xFF,  0x10,  0x00,  0x13,  0xFC,  0x12,  0x44,  0x13, 	/* 2F7B0 */
+	0xFC,  0x12,  0x44,  0x13,  0xFC,  0x10,  0x40,  0x1F,  0xFF,  0x11,  0x12,  0x26,  0x4E,  0x3B,  0xF8,  0x40, 	/* 2F7C0 */
+	0x40,  0x1F,  0xFF,  0x9D,  0x00,  0x40,  0x00,  0x40,  0x1F,  0xFF,  0x10,  0x00,  0x14,  0x86,  0x1F,  0xF8, 	/* 2F7D0 */
+	0x14,  0xA0,  0x17,  0xBF,  0x14,  0xA4,  0x17,  0xA4,  0x14,  0xA4,  0x14,  0xA4,  0x2F,  0xE4,  0x25,  0x24, 	/* 2F7E0 */
+	0x48,  0xC4,  0x10,  0x84,  0x9F,  0x00,  0x40,  0x3F,  0xFF,  0x22,  0x00,  0x22,  0x3E,  0x3F,  0xE2,  0x22, 	/* 2F7F0 */
+	0x22,  0x2F,  0xA2,  0x28,  0xBE,  0x2F,  0xA2,  0x28,  0xA2,  0x2F,  0xBE,  0x22,  0x22,  0x3F,  0xE2,  0x42, 	/* 2F800 */
+	0x22,  0x42,  0x42,  0x02,  0x86,  0xA0,  0x00,  0x80,  0x00,  0x80,  0x1F,  0xFF,  0x12,  0x10,  0x1A,  0x50, 	/* 2F810 */
+	0x16,  0x90,  0x12,  0x1F,  0x1F,  0xE4,  0x18,  0x54,  0x1F,  0x54,  0x1D,  0x54,  0x1D,  0x48,  0x2F,  0x48, 	/* 2F820 */
+	0x28,  0x54,  0x48,  0x62,  0x08,  0xC1,  0xA1,  0x00,  0x40,  0x00,  0x40,  0x1F,  0xFF,  0x11,  0x00,  0x12, 	/* 2F830 */
+	0x00,  0x17,  0xFF,  0x1A,  0x94,  0x12,  0x94,  0x1F,  0xFF,  0x12,  0x94,  0x12,  0x94,  0x17,  0xFF,  0x20, 	/* 2F840 */
+	0x00,  0x25,  0x24,  0x48,  0x92,  0x10,  0x91,  0xA2,  0x00,  0x40,  0x00,  0x40,  0x1F,  0xFF,  0x10,  0x14, 	/* 2F850 */
+	0x13,  0xD8,  0x14,  0x8A,  0x13,  0x04,  0x17,  0xBA,  0x18,  0xA9,  0x17,  0xAA,  0x14,  0x46,  0x17,  0xBC, 	/* 2F860 */
+	0x20,  0xA4,  0x20,  0x98,  0x41,  0x2C,  0x06,  0xC3,  0xA3,  0x00,  0x80,  0x00,  0x80,  0x1F,  0xFF,  0x11, 	/* 2F870 */
+	0x10,  0x1F,  0xFE,  0x11,  0x10,  0x11,  0xF0,  0x1F,  0xFF,  0x10,  0x40,  0x17,  0xFC,  0x14,  0x44,  0x17, 	/* 2F880 */
+	0xFC,  0x24,  0x44,  0x27,  0xFC,  0x43,  0x0C,  0x1C,  0x02,  0xA8,  0x00,  0x40,  0x00,  0x40,  0x1F,  0xFF, 	/* 2F890 */
+	0x12,  0x00,  0x13,  0xFE,  0x14,  0x92,  0x19,  0x12,  0x17,  0xE6,  0x15,  0x58,  0x17,  0xE8,  0x15,  0x7E, 	/* 2F8A0 */
+	0x17,  0xC8,  0x24,  0x48,  0x28,  0x7F,  0x48,  0x48,  0x10,  0xC8,  0xA9,  0x00,  0x80,  0x1F,  0xFF,  0x10, 	/* 2F8B0 */
+	0x40,  0x1F,  0xFE,  0x15,  0xF4,  0x15,  0x14,  0x15,  0xF4,  0x14,  0x04,  0x17,  0xFC,  0x10,  0x0C,  0x17, 	/* 2F8C0 */
+	0xF0,  0x10,  0x40,  0x3F,  0xFF,  0x21,  0x50,  0x46,  0x4C,  0x18,  0x43,  0xAC,  0x00,  0x40,  0x1F,  0xFF, 	/* 2F8D0 */
+	0x10,  0x7C,  0x10,  0x40,  0x17,  0xFF,  0x14,  0x9A,  0x17,  0xE0,  0x14,  0x82,  0x15,  0xFE,  0x15,  0x24, 	/* 2F8E0 */
+	0x15,  0xFC,  0x15,  0x24,  0x2B,  0xFE,  0x32,  0x52,  0x4F,  0xFF,  0x00,  0x00,  0xB0,  0x00,  0x40,  0x00, 	/* 2F8F0 */
+	0x40,  0x1F,  0xFF,  0x10,  0x10,  0x1F,  0xD0,  0x15,  0x7F,  0x15,  0x10,  0x17,  0x7E,  0x15,  0x6A,  0x15, 	/* 2F900 */
+	0x6A,  0x17,  0x7E,  0x15,  0x30,  0x25,  0x6A,  0x27,  0x61,  0x5D,  0xA5,  0x01,  0x1C,  0xB1,  0x00,  0x40, 	/* 2F910 */
+	0x1F,  0xFF,  0x15,  0x48,  0x1A,  0x8A,  0x15,  0x54,  0x10,  0x1F,  0x17,  0xB4,  0x14,  0x94,  0x17,  0x9F, 	/* 2F920 */
+	0x10,  0x14,  0x1F,  0xD4,  0x1A,  0x5F,  0x2F,  0xD4,  0x28,  0x14,  0x48,  0x5F,  0x07,  0xC0,  0xB3,  0x00, 	/* 2F930 */
+	0x40,  0x3F,  0xFF,  0x20,  0x08,  0x3F,  0x88,  0x24,  0xFF,  0x27,  0x88,  0x24,  0xBE,  0x27,  0xAA,  0x24, 	/* 2F940 */
+	0xBE,  0x27,  0x80,  0x38,  0xFF,  0x2E,  0x98,  0x24,  0xB5,  0x2E,  0xB1,  0x44,  0xD2,  0x0E,  0x8E,  0xB4, 	/* 2F950 */
+	0x00,  0x00,  0x7C,  0x00,  0x04,  0x00,  0x08,  0x00,  0x08,  0x00,  0x10,  0x00,  0x3C,  0x00,  0x04,  0x00, 	/* 2F960 */
+	0x04,  0x00,  0x44,  0x00,  0x28,  0x00,  0x18,  0x00,  0x08,  0x00,  0x16,  0x00,  0x21,  0x80,  0x40,  0x7F, 	/* 2F970 */
+	0xB6,  0x00,  0x04,  0x7C,  0x18,  0x05,  0xF0,  0x08,  0x10,  0x08,  0x10,  0x10,  0x90,  0x3C,  0x9E,  0x04, 	/* 2F980 */
+	0x90,  0x24,  0x90,  0x14,  0x90,  0x14,  0x90,  0x08,  0x90,  0x0F,  0xFF,  0x12,  0x00,  0x21,  0x80,  0x40, 	/* 2F990 */
+	0x7F,  0xB7,  0x00,  0x08,  0x7C,  0x30,  0x05,  0xE0,  0x08,  0x20,  0x08,  0x20,  0x10,  0x20,  0x3F,  0xFE, 	/* 2F9A0 */
+	0x04,  0x20,  0x24,  0x20,  0x24,  0x20,  0x14,  0x20,  0x08,  0x20,  0x0D,  0xFC,  0x12,  0x00,  0x21,  0x80, 	/* 2F9B0 */
+	0x40,  0x7F,  0xB8,  0x00,  0x20,  0x7C,  0x20,  0x04,  0x20,  0x09,  0xFE,  0x09,  0x22,  0x11,  0x22,  0x3D, 	/* 2F9C0 */
+	0x22,  0x05,  0xFE,  0x05,  0x22,  0x45,  0x22,  0x29,  0x22,  0x19,  0xFE,  0x08,  0x00,  0x16,  0x00,  0x21, 	/* 2F9D0 */
+	0x80,  0x40,  0x7F,  0xBA,  0x00,  0x20,  0x7D,  0xFC,  0x04,  0x24,  0x08,  0x24,  0x13,  0xFF,  0x20,  0x24, 	/* 2F9E0 */
+	0x3D,  0xFC,  0x04,  0x20,  0x45,  0xFC,  0x24,  0x20,  0x18,  0x20,  0x0B,  0xFE,  0x14,  0x20,  0x13,  0x20, 	/* 2F9F0 */
+	0x20,  0xC0,  0x40,  0x3F,  0xBB,  0x00,  0x00,  0x3D,  0xFE,  0x05,  0x02,  0x09,  0x02,  0x09,  0x7A,  0x11, 	/* 2FA00 */
+	0x4A,  0x3D,  0x4A,  0x05,  0x4A,  0x05,  0x7A,  0x25,  0x02,  0x15,  0x02,  0x09,  0xFE,  0x0C,  0x00,  0x13, 	/* 2FA10 */
+	0x00,  0x20,  0xE0,  0x40,  0x1F,  0xBC,  0x00,  0x00,  0x7D,  0xFF,  0x04,  0x28,  0x08,  0x28,  0x08,  0xFE, 	/* 2FA20 */
+	0x10,  0xAA,  0x3C,  0xAA,  0x04,  0xAA,  0x24,  0xAE,  0x14,  0xC2,  0x1C,  0x82,  0x08,  0x82,  0x0C,  0xFE, 	/* 2FA30 */
+	0x12,  0x00,  0x21,  0x80,  0x40,  0x7F,  0xBE,  0x04,  0x10,  0x04,  0x10,  0x04,  0x10,  0x04,  0x10,  0x04, 	/* 2FA40 */
+	0x10,  0x04,  0x10,  0x7F,  0xFF,  0x04,  0x10,  0x04,  0x10,  0x04,  0x10,  0x04,  0x10,  0x08,  0x10,  0x08, 	/* 2FA50 */
+	0x10,  0x10,  0x10,  0x20,  0x10,  0x40,  0x10,  0xBF,  0x04,  0x10,  0x04,  0x10,  0x04,  0x10,  0x04,  0x10, 	/* 2FA60 */
+	0x7F,  0xFF,  0x04,  0x10,  0x04,  0x10,  0x04,  0x10,  0x04,  0x10,  0x04,  0x10,  0x04,  0x10,  0x04,  0x10, 	/* 2FA70 */
+	0x04,  0x10,  0x04,  0x10,  0x07,  0xF0,  0x00,  0x00,  0x81,  0x01,  0x00,  0x01,  0x20,  0x02,  0x10,  0x02, 	/* 2FA80 */
+	0x38,  0x07,  0xC4,  0x3C,  0x04,  0x02,  0x10,  0x02,  0x10,  0x7F,  0xFF,  0x02,  0x10,  0x02,  0x10,  0x02, 	/* 2FA90 */
+	0x10,  0x04,  0x10,  0x04,  0x10,  0x08,  0x10,  0x10,  0x10,  0x83,  0x00,  0x80,  0x00,  0x80,  0x7F,  0xFF, 	/* 2FAA0 */
+	0x01,  0x20,  0x01,  0x18,  0x02,  0x6C,  0x1F,  0x92,  0x02,  0x10,  0x02,  0x10,  0x7F,  0xFF,  0x02,  0x10, 	/* 2FAB0 */
+	0x02,  0x10,  0x04,  0x10,  0x04,  0x10,  0x08,  0x10,  0x10,  0x10,  0x84,  0x00,  0x00,  0x1F,  0xFC,  0x00, 	/* 2FAC0 */
+	0x80,  0x00,  0x80,  0x0F,  0xF8,  0x00,  0x80,  0x00,  0x80,  0x7F,  0xFF,  0x04,  0x10,  0x04,  0x10,  0x7F, 	/* 2FAD0 */
+	0xFF,  0x04,  0x10,  0x04,  0x10,  0x08,  0x10,  0x08,  0x10,  0x10,  0x10,  0x89,  0x24,  0x20,  0x24,  0x20, 	/* 2FAE0 */
+	0x24,  0x20,  0x3F,  0xFF,  0x04,  0x20,  0x7C,  0x20,  0x24,  0x20,  0x25,  0xFE,  0x44,  0x00,  0x02,  0x10, 	/* 2FAF0 */
+	0x7F,  0xFF,  0x02,  0x10,  0x02,  0x10,  0x04,  0x10,  0x08,  0x10,  0x10,  0x10,  0x8A,  0x24,  0xA0,  0x14, 	/* 2FB00 */
+	0xA0,  0x15,  0x3F,  0x3F,  0xA4,  0x24,  0xD4,  0x2E,  0x94,  0x35,  0x88,  0x24,  0x94,  0x25,  0xA2,  0x20, 	/* 2FB10 */
+	0x41,  0x04,  0x20,  0x7F,  0xFF,  0x04,  0x20,  0x04,  0x20,  0x08,  0x20,  0x10,  0x20,  0x8B,  0x01,  0x10, 	/* 2FB20 */
+	0x01,  0x08,  0x01,  0x08,  0x01,  0x00,  0x7F,  0xFF,  0x01,  0x00,  0x01,  0x00,  0x01,  0x00,  0x00,  0x80, 	/* 2FB30 */
+	0x00,  0x80,  0x00,  0x40,  0x00,  0x40,  0x00,  0x22,  0x00,  0x12,  0x00,  0x0A,  0x00,  0x06,  0x8C,  0x00, 	/* 2FB40 */
+	0x48,  0x00,  0x44,  0x00,  0x44,  0x00,  0x40,  0x7F,  0xFF,  0x00,  0x20,  0x00,  0x20,  0x00,  0x20,  0x00, 	/* 2FB50 */
+	0x20,  0x00,  0x10,  0x7F,  0x90,  0x00,  0x10,  0x00,  0x0A,  0x00,  0x0A,  0x00,  0x06,  0x00,  0x02,  0x8D, 	/* 2FB60 */
+	0x00,  0x48,  0x00,  0x44,  0x00,  0x44,  0x00,  0x40,  0x7F,  0xFF,  0x00,  0x20,  0x00,  0x20,  0x00,  0x20, 	/* 2FB70 */
+	0x3F,  0xA0,  0x00,  0x10,  0x00,  0x10,  0x00,  0x10,  0x00,  0x0A,  0x7F,  0xCA,  0x00,  0x06,  0x00,  0x02, 	/* 2FB80 */
+	0x8F,  0x00,  0x20,  0x00,  0x28,  0x00,  0x24,  0x00,  0x24,  0x7F,  0xFF,  0x00,  0x20,  0x00,  0x20,  0x3F, 	/* 2FB90 */
+	0xA0,  0x04,  0x10,  0x04,  0x10,  0x04,  0x10,  0x04,  0x08,  0x05,  0xC9,  0x0E,  0x05,  0x70,  0x03,  0x00, 	/* 2FBA0 */
+	0x01,  0x90,  0x00,  0x48,  0x3F,  0x44,  0x00,  0x44,  0x00,  0x40,  0x7F,  0xFF,  0x00,  0x20,  0x00,  0x20, 	/* 2FBB0 */
+	0x3F,  0x20,  0x00,  0x20,  0x00,  0x10,  0x00,  0x10,  0x01,  0x90,  0x0E,  0x0A,  0x70,  0x0A,  0x00,  0x06, 	/* 2FBC0 */
+	0x00,  0x02,  0x91,  0x02,  0x0C,  0x22,  0x0A,  0x14,  0x0A,  0x08,  0x08,  0x15,  0xFF,  0x22,  0x08,  0x48, 	/* 2FBD0 */
+	0x08,  0x0B,  0xF8,  0x7E,  0x48,  0x08,  0x48,  0x1C,  0x48,  0x1A,  0x54,  0x28,  0x65,  0x4B,  0x83,  0x08, 	/* 2FBE0 */
+	0x03,  0x08,  0x01,  0x93,  0x00,  0x00,  0x3F,  0xF0,  0x00,  0x10,  0x00,  0x10,  0x00,  0x10,  0x1F,  0xF0, 	/* 2FBF0 */
+	0x10,  0x00,  0x10,  0x00,  0x10,  0x00,  0x1F,  0xF8,  0x00,  0x08,  0x00,  0x08,  0x00,  0x08,  0x00,  0x08, 	/* 2FC00 */
+	0x00,  0x10,  0x00,  0xE0,  0x94,  0x00,  0x00,  0x7F,  0xF8,  0x01,  0x08,  0x01,  0x08,  0x01,  0x08,  0x3F, 	/* 2FC10 */
+	0xF8,  0x21,  0x00,  0x21,  0x00,  0x3F,  0xFC,  0x01,  0x04,  0x01,  0x04,  0x01,  0x04,  0x01,  0x04,  0x01, 	/* 2FC20 */
+	0x08,  0x01,  0x30,  0x01,  0x00,  0x95,  0x00,  0x04,  0x7F,  0x84,  0x00,  0x84,  0x00,  0x84,  0x00,  0x84, 	/* 2FC30 */
+	0x3F,  0x84,  0x20,  0x04,  0x20,  0x04,  0x20,  0x04,  0x3F,  0x84,  0x00,  0x84,  0x00,  0x84,  0x00,  0x84, 	/* 2FC40 */
+	0x00,  0x84,  0x01,  0x04,  0x0E,  0x04,  0x96,  0x00,  0x00,  0x1F,  0xF8,  0x00,  0x08,  0x00,  0x08,  0x0F, 	/* 2FC50 */
+	0xF8,  0x08,  0x00,  0x08,  0x00,  0x0F,  0xFC,  0x00,  0x04,  0x00,  0x04,  0x00,  0x04,  0x00,  0x08,  0x00, 	/* 2FC60 */
+	0x70,  0x00,  0x00,  0x7F,  0xFF,  0x00,  0x00,  0x97,  0x02,  0x40,  0x02,  0x40,  0x7F,  0xFC,  0x02,  0x44, 	/* 2FC70 */
+	0x02,  0x44,  0x3F,  0xFC,  0x22,  0x40,  0x22,  0x40,  0x3F,  0xFE,  0x02,  0x42,  0x02,  0x42,  0x04,  0x42, 	/* 2FC80 */
+	0x04,  0x42,  0x08,  0x4C,  0x10,  0x40,  0x20,  0x40,  0x98,  0x00,  0x10,  0x7E,  0x10,  0x02,  0x10,  0x02, 	/* 2FC90 */
+	0x10,  0x02,  0x10,  0x3E,  0x10,  0x20,  0x20,  0x20,  0x20,  0x20,  0x20,  0x3E,  0x28,  0x02,  0x24,  0x02, 	/* 2FCA0 */
+	0x44,  0x02,  0x42,  0x02,  0x5E,  0x05,  0xE2,  0x38,  0x02,  0x9B,  0x00,  0x10,  0x7E,  0x90,  0x02,  0x90, 	/* 2FCB0 */
+	0x02,  0x92,  0x02,  0x9E,  0x3E,  0xF2,  0x21,  0x92,  0x20,  0x92,  0x3E,  0x92,  0x02,  0x9C,  0x02,  0x90, 	/* 2FCC0 */
+	0x02,  0x80,  0x02,  0x81,  0x02,  0x81,  0x04,  0x41,  0x18,  0x3F,  0x9F,  0x08,  0x20,  0x04,  0x20,  0x04, 	/* 2FCD0 */
+	0x40,  0x3F,  0xF8,  0x01,  0x08,  0x01,  0x08,  0x3F,  0xF8,  0x21,  0x00,  0x21,  0x00,  0x3F,  0xFC,  0x23, 	/* 2FCE0 */
+	0x04,  0x03,  0x04,  0x05,  0x04,  0x19,  0x08,  0x61,  0x30,  0x01,  0x00,  0xA5,  0x00,  0x40,  0x7C,  0x40, 	/* 2FCF0 */
+	0x04,  0x40,  0x04,  0xFF,  0x04,  0x90,  0x3D,  0x10,  0x22,  0x10,  0x20,  0x18,  0x20,  0x54,  0x3C,  0x54, 	/* 2FD00 */
+	0x04,  0x92,  0x04,  0x92,  0x05,  0x12,  0x04,  0x10,  0x08,  0x10,  0x30,  0x30,  0xA6,  0x00,  0x20,  0x7C, 	/* 2FD10 */
+	0x20,  0x04,  0x20,  0x07,  0xFF,  0x04,  0x20,  0x3C,  0x20,  0x20,  0x48,  0x21,  0x88,  0x20,  0x50,  0x3C, 	/* 2FD20 */
+	0x50,  0x04,  0x20,  0x04,  0x28,  0x04,  0x44,  0x04,  0x9C,  0x0B,  0xE2,  0x30,  0x02,  0xA7,  0x00,  0x02, 	/* 2FD30 */
+	0x78,  0x1C,  0x09,  0xE4,  0x09,  0x04,  0x09,  0x24,  0x79,  0x24,  0x41,  0x24,  0x41,  0x24,  0x41,  0x24, 	/* 2FD40 */
+	0x79,  0x24,  0x09,  0x24,  0x09,  0x34,  0x09,  0x2C,  0x0A,  0x3A,  0x12,  0xC6,  0x64,  0x01,  0xA9,  0x04, 	/* 2FD50 */
+	0x00,  0x04,  0x00,  0x7F,  0xFE,  0x09,  0x22,  0x11,  0x14,  0x3E,  0x08,  0x05,  0x94,  0x18,  0x63,  0x6F, 	/* 2FD60 */
+	0xF0,  0x00,  0x10,  0x0F,  0xF0,  0x08,  0x00,  0x0F,  0xF8,  0x00,  0x08,  0x00,  0x08,  0x00,  0x70,  0xAD, 	/* 2FD70 */
+	0x00,  0x00,  0x7F,  0xFF,  0x04,  0x84,  0x04,  0x84,  0x04,  0xFC,  0x3C,  0x84,  0x20,  0x84,  0x20,  0x84, 	/* 2FD80 */
+	0x20,  0xFC,  0x3C,  0x84,  0x04,  0x84,  0x04,  0x86,  0x04,  0xFC,  0x07,  0x84,  0x08,  0x04,  0x30,  0x04, 	/* 2FD90 */
+	0xAF,  0x00,  0x80,  0x00,  0x80,  0x7F,  0xFF,  0x02,  0x40,  0x0A,  0x58,  0x12,  0x44,  0x64,  0x42,  0x00, 	/* 2FDA0 */
+	0x00,  0x1F,  0xF8,  0x00,  0x08,  0x0F,  0xF8,  0x08,  0x00,  0x0F,  0xFC,  0x00,  0x04,  0x00,  0x04,  0x00, 	/* 2FDB0 */
+	0x78,  0xB1,  0x00,  0x00,  0x3F,  0x7E,  0x01,  0x02,  0x01,  0x02,  0x1F,  0x3E,  0x10,  0x20,  0x10,  0x20, 	/* 2FDC0 */
+	0x1F,  0x3E,  0x01,  0x02,  0x31,  0x62,  0x09,  0x12,  0x07,  0x0E,  0x19,  0x32,  0x61,  0xC2,  0x02,  0x04, 	/* 2FDD0 */
+	0x0C,  0x18,  0xB5,  0x00,  0x00,  0x7C,  0xFE,  0x04,  0x80,  0x04,  0xFC,  0x04,  0x80,  0x7C,  0xFC,  0x40, 	/* 2FDE0 */
+	0x80,  0x40,  0x80,  0x7F,  0xFF,  0x04,  0xA2,  0x04,  0xA4,  0x04,  0x90,  0x04,  0x88,  0x08,  0xA4,  0x10, 	/* 2FDF0 */
+	0xC2,  0x63,  0x01,  0xB7,  0x00,  0x40,  0x7C,  0x50,  0x04,  0x8C,  0x07,  0xFA,  0x04,  0x21,  0x3C,  0x20, 	/* 2FE00 */
+	0x21,  0xFC,  0x21,  0x24,  0x3D,  0x24,  0x05,  0x24,  0x05,  0xFC,  0x04,  0x24,  0x04,  0x22,  0x04,  0x3E, 	/* 2FE10 */
+	0x0B,  0xC1,  0x30,  0x01,  0xB8,  0x00,  0x00,  0x7B,  0xDE,  0x0A,  0x52,  0x0A,  0x52,  0x0A,  0x52,  0x7B, 	/* 2FE20 */
+	0xDE,  0x42,  0x52,  0x42,  0x52,  0x42,  0x52,  0x7B,  0xDE,  0x0A,  0x52,  0x0A,  0x52,  0x0A,  0x52,  0x0A, 	/* 2FE30 */
+	0x52,  0x12,  0x62,  0x64,  0xC6,  0xBC,  0x00,  0x00,  0x78,  0x1E,  0x0F,  0xE2,  0x08,  0x82,  0x09,  0x02, 	/* 2FE40 */
+	0x3B,  0xDE,  0x22,  0x50,  0x22,  0x50,  0x3A,  0x5E,  0x0B,  0xC2,  0x0A,  0x42,  0x0A,  0x42,  0x0A,  0x42, 	/* 2FE50 */
+	0x0B,  0xC2,  0x10,  0x04,  0x60,  0x18,  0xBE,  0x02,  0x44,  0x7D,  0x24,  0x05,  0x28,  0x05,  0xFC,  0x05, 	/* 2FE60 */
+	0x24,  0x3D,  0x24,  0x21,  0xFC,  0x21,  0x24,  0x21,  0x24,  0x3D,  0xFC,  0x04,  0x20,  0x04,  0x20,  0x07, 	/* 2FE70 */
+	0xFF,  0x04,  0x20,  0x08,  0x20,  0x30,  0x20,  0x81,  0x00,  0x00,  0x7F,  0xFF,  0x04,  0x04,  0x04,  0xF4, 	/* 2FE80 */
+	0x04,  0x94,  0x3C,  0x94,  0x20,  0xF4,  0x20,  0x0C,  0x3D,  0xFF,  0x04,  0x04,  0x04,  0xF4,  0x04,  0x94, 	/* 2FE90 */
+	0x04,  0x94,  0x04,  0xF4,  0x08,  0x04,  0x30,  0x0C,  0x88,  0x00,  0x00,  0x7F,  0xDE,  0x06,  0x52,  0x07, 	/* 2FEA0 */
+	0xDE,  0x04,  0x00,  0x3D,  0xFC,  0x21,  0x24,  0x21,  0x24,  0x21,  0xFC,  0x3D,  0x24,  0x05,  0xFC,  0x04, 	/* 2FEB0 */
+	0x20,  0x07,  0xFF,  0x04,  0x20,  0x08,  0x20,  0x30,  0x20,  0x8A,  0x00,  0x00,  0x7F,  0xFF,  0x04,  0x00, 	/* 2FEC0 */
+	0x05,  0xFC,  0x05,  0x24,  0x3D,  0xFC,  0x21,  0x24,  0x23,  0xFE,  0x3C,  0x00,  0x05,  0xFC,  0x05,  0x24, 	/* 2FED0 */
+	0x05,  0xFC,  0x05,  0x24,  0x05,  0xFC,  0x08,  0x00,  0x33,  0xFF,  0x8C,  0x00,  0x00,  0x7F,  0xFF,  0x09, 	/* 2FEE0 */
+	0x24,  0x0A,  0x22,  0x0F,  0xFF,  0x7B,  0x76,  0x42,  0xAA,  0x42,  0xEE,  0x43,  0x76,  0x7A,  0x22,  0x0B, 	/* 2FEF0 */
+	0x66,  0x0A,  0xBA,  0x0A,  0xEE,  0x0B,  0x76,  0x12,  0x22,  0x62,  0x26,  0x8E,  0x11,  0x84,  0x17,  0xE4, 	/* 2FF00 */
+	0x68,  0x1A,  0x13,  0xC4,  0x28,  0x0A,  0x7F,  0xDF,  0x12,  0x44,  0x3B,  0xD6,  0x54,  0x25,  0x1F,  0xF4, 	/* 2FF10 */
+	0x00,  0x10,  0x0F,  0xF0,  0x08,  0x00,  0x0F,  0xF8,  0x00,  0x08,  0x00,  0x70,  0x91,  0x02,  0x00,  0x02, 	/* 2FF20 */
+	0x00,  0x02,  0x00,  0x02,  0x00,  0x03,  0xF0,  0x04,  0x10,  0x04,  0x10,  0x04,  0x10,  0x04,  0x10,  0x08, 	/* 2FF30 */
+	0x20,  0x0F,  0xE0,  0x00,  0x20,  0x00,  0x20,  0x00,  0x20,  0x7F,  0xFF,  0x00,  0x00,  0x93,  0x01,  0x00, 	/* 2FF40 */
+	0x11,  0x08,  0x09,  0x08,  0x05,  0x10,  0x05,  0x20,  0x01,  0x00,  0x3F,  0xFC,  0x00,  0x04,  0x00,  0x04, 	/* 2FF50 */
+	0x00,  0x04,  0x1F,  0xFC,  0x00,  0x04,  0x00,  0x04,  0x00,  0x04,  0x3F,  0xFC,  0x00,  0x00,  0x96,  0x02, 	/* 2FF60 */
+	0x00,  0x03,  0xF8,  0x04,  0x10,  0x0F,  0xF0,  0x00,  0x20,  0x7F,  0xFF,  0x01,  0x00,  0x06,  0xA4,  0x38, 	/* 2FF70 */
+	0xA8,  0x03,  0x58,  0x0C,  0x50,  0x30,  0xC8,  0x03,  0x44,  0x0C,  0x42,  0x70,  0x41,  0x01,  0x80,  0x97, 	/* 2FF80 */
+	0x08,  0x10,  0x08,  0x10,  0x7F,  0xFE,  0x08,  0x10,  0x3E,  0x7C,  0x08,  0x10,  0x0E,  0xFE,  0x78,  0x10, 	/* 2FF90 */
+	0x08,  0x10,  0x1F,  0xF8,  0x00,  0x08,  0x00,  0x08,  0x7F,  0xFF,  0x00,  0x08,  0x1F,  0xF8,  0x00,  0x00, 	/* 2FFA0 */
+	0x99,  0x02,  0x00,  0x03,  0xF8,  0x04,  0x10,  0x0F,  0xF0,  0x00,  0x20,  0x7F,  0xFF,  0x00,  0x00,  0x7F, 	/* 2FFB0 */
+	0xFE,  0x48,  0x8A,  0x4F,  0xFA,  0x08,  0x88,  0x0F,  0xF8,  0x7F,  0xFF,  0x02,  0xA0,  0x0C,  0x98,  0x70, 	/* 2FFC0 */
+	0x87,  0x9C,  0x02,  0x00,  0x03,  0xF8,  0x04,  0x10,  0x0F,  0xF0,  0x00,  0x20,  0x7F,  0xFF,  0x08,  0x14, 	/* 2FFD0 */
+	0x2A,  0x22,  0x7F,  0x7D,  0x1C,  0x94,  0x2A,  0x24,  0x48,  0x4C,  0x04,  0x20,  0x7F,  0xFF,  0x04,  0x20, 	/* 2FFE0 */
+	0x18,  0x20,  0x9D,  0x02,  0x00,  0x03,  0xF8,  0x04,  0x10,  0x0F,  0xF0,  0x00,  0x20,  0x7F,  0xFF,  0x08, 	/* 2FFF0 */
+	0x10,  0x2A,  0x64,  0x7F,  0x1A,  0x1C,  0xFD,  0x2A,  0x2A,  0x48,  0xC9,  0x02,  0x10,  0x7F,  0xFF,  0x02, 	/* 30000 */
+	0x10,  0x04,  0x10,  0xA1,  0x00,  0x20,  0x00,  0x20,  0x00,  0x40,  0x00,  0x80,  0x03,  0x00,  0x0C,  0x10, 	/* 30010 */
+	0x00,  0x20,  0x00,  0x40,  0x00,  0x80,  0x03,  0x08,  0x0C,  0x10,  0x00,  0x20,  0x00,  0x40,  0x00,  0x80, 	/* 30020 */
+	0x03,  0x00,  0x1C,  0x00,  0xA2,  0x00,  0x04,  0x3F,  0xC4,  0x09,  0x08,  0x09,  0x08,  0x09,  0x12,  0x09, 	/* 30030 */
+	0x22,  0x7F,  0xC4,  0x09,  0x04,  0x09,  0x09,  0x09,  0x11,  0x09,  0x22,  0x11,  0x02,  0x11,  0x04,  0x11, 	/* 30040 */
+	0x08,  0x21,  0x10,  0x41,  0x20,  0xA6,  0x00,  0x80,  0x00,  0x80,  0x7F,  0xFE,  0x04,  0x10,  0x02,  0x20, 	/* 30050 */
+	0x1F,  0xFE,  0x10,  0x10,  0x10,  0x60,  0x11,  0x88,  0x1E,  0x10,  0x10,  0x60,  0x11,  0x84,  0x2E,  0x08, 	/* 30060 */
+	0x20,  0x30,  0x41,  0xC0,  0x0E,  0x00,  0xA9,  0x01,  0x08,  0x06,  0x08,  0x78,  0x90,  0x10,  0x90,  0x49, 	/* 30070 */
+	0x24,  0x29,  0x44,  0x22,  0x08,  0x08,  0x08,  0x7F,  0x92,  0x08,  0x22,  0x0C,  0x44,  0x1A,  0x04,  0x19, 	/* 30080 */
+	0x08,  0x28,  0x10,  0x48,  0x20,  0x08,  0xC0,  0xAA,  0x04,  0x08,  0x07,  0x88,  0x04,  0x10,  0x3F,  0xD0, 	/* 30090 */
+	0x24,  0xA4,  0x27,  0x04,  0x3C,  0x08,  0x24,  0x90,  0x23,  0xA2,  0x20,  0x02,  0x25,  0x04,  0x25,  0x08, 	/* 300A0 */
+	0x25,  0x30,  0x29,  0x01,  0x48,  0x81,  0x10,  0x7F,  0xAB,  0x00,  0x04,  0x3F,  0xC4,  0x24,  0x48,  0x24, 	/* 300B0 */
+	0x48,  0x2F,  0x52,  0x24,  0x62,  0x24,  0x44,  0x3F,  0xC4,  0x20,  0x49,  0x2F,  0x51,  0x29,  0x42,  0x29, 	/* 300C0 */
+	0x42,  0x2F,  0x44,  0x20,  0x48,  0x20,  0x50,  0x40,  0xE0,  0xAC,  0x10,  0x84,  0x10,  0x84,  0x10,  0x88, 	/* 300D0 */
+	0x7F,  0xF8,  0x10,  0x92,  0x10,  0xA2,  0x39,  0xC4,  0x35,  0xA4,  0x52,  0x89,  0x52,  0x91,  0x14,  0xA2, 	/* 300E0 */
+	0x10,  0x82,  0x10,  0x84,  0x10,  0x88,  0x10,  0x90,  0x10,  0xA0,  0xAD,  0x04,  0x04,  0x04,  0x04,  0x7F, 	/* 300F0 */
+	0xC8,  0x04,  0x12,  0x04,  0x22,  0x3F,  0x84,  0x00,  0x04,  0x3F,  0x88,  0x20,  0x91,  0x20,  0xA1,  0x3F, 	/* 30100 */
+	0x82,  0x11,  0x02,  0x0A,  0x04,  0x09,  0xC8,  0x1E,  0x10,  0x70,  0x60,  0xB0,  0x04,  0x08,  0x04,  0x08, 	/* 30110 */
+	0x7F,  0xD0,  0x11,  0x10,  0x0A,  0x24,  0x7F,  0xC4,  0x00,  0x08,  0x3F,  0x88,  0x20,  0x92,  0x3F,  0xA2, 	/* 30120 */
+	0x20,  0xC4,  0x3F,  0x84,  0x04,  0x08,  0x7F,  0xD0,  0x04,  0x20,  0x04,  0x40,  0xB1,  0x00,  0x04,  0x1F, 	/* 30130 */
+	0x84,  0x10,  0x88,  0x1F,  0x88,  0x10,  0x92,  0x1F,  0xA2,  0x04,  0x04,  0x7F,  0xC4,  0x00,  0x09,  0x1F, 	/* 30140 */
+	0x91,  0x10,  0x82,  0x1F,  0x82,  0x04,  0x04,  0x24,  0x84,  0x44,  0x48,  0x0C,  0x10,  0xB3,  0x00,  0x40, 	/* 30150 */
+	0x00,  0x40,  0x00,  0x80,  0x01,  0x00,  0x02,  0x10,  0x04,  0x20,  0x18,  0x40,  0x00,  0x80,  0x01,  0x80, 	/* 30160 */
+	0x02,  0x80,  0x0C,  0x80,  0x30,  0x80,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0xB7,  0x08, 	/* 30170 */
+	0x20,  0x08,  0x20,  0x10,  0x20,  0x13,  0xFF,  0x24,  0x40,  0x44,  0x40,  0x08,  0x40,  0x08,  0x7C,  0x18, 	/* 30180 */
+	0x44,  0x28,  0x44,  0x48,  0x44,  0x08,  0x84,  0x08,  0x84,  0x09,  0x04,  0x0A,  0x04,  0x0C,  0x18,  0xB9, 	/* 30190 */
+	0x08,  0x00,  0x08,  0xF8,  0x10,  0x88,  0x10,  0x89,  0x24,  0x89,  0x44,  0x89,  0x09,  0x07,  0x0A,  0x00, 	/* 301A0 */
+	0x17,  0xFC,  0x30,  0x84,  0x50,  0x88,  0x10,  0x50,  0x10,  0x60,  0x10,  0x50,  0x11,  0x8C,  0x16,  0x03, 	/* 301B0 */
+	0xBC,  0x08,  0x20,  0x08,  0x20,  0x10,  0x20,  0x11,  0xFF,  0x25,  0x22,  0x45,  0x24,  0x09,  0x20,  0x09, 	/* 301C0 */
+	0xFC,  0x11,  0x44,  0x31,  0x44,  0x51,  0x48,  0x11,  0x28,  0x12,  0x10,  0x12,  0x28,  0x14,  0xC4,  0x13, 	/* 301D0 */
+	0x03,  0xBF,  0x08,  0x90,  0x08,  0x90,  0x13,  0xFE,  0x10,  0x92,  0x24,  0x92,  0x47,  0xFE,  0x0A,  0x90, 	/* 301E0 */
+	0x0A,  0x90,  0x13,  0xFE,  0x30,  0x92,  0x50,  0x92,  0x10,  0x92,  0x10,  0x92,  0x11,  0x1C,  0x12,  0x10, 	/* 301F0 */
+	0x14,  0x10,  0x80,  0x08,  0x40,  0x08,  0x20,  0x10,  0x20,  0x13,  0xFE,  0x24,  0x20,  0x44,  0x20,  0x08, 	/* 30200 */
+	0x20,  0x08,  0x20,  0x11,  0xFC,  0x30,  0x20,  0x50,  0x20,  0x10,  0x20,  0x10,  0x20,  0x10,  0x20,  0x13, 	/* 30210 */
+	0xFF,  0x10,  0x00,  0x81,  0x04,  0x00,  0x07,  0xFE,  0x08,  0x20,  0x08,  0x20,  0x10,  0x20,  0x25,  0x20, 	/* 30220 */
+	0x45,  0x20,  0x09,  0x3E,  0x09,  0x20,  0x19,  0x20,  0x29,  0x20,  0x49,  0x20,  0x09,  0x20,  0x09,  0x20, 	/* 30230 */
+	0x0F,  0xFF,  0x08,  0x00,  0x82,  0x08,  0x00,  0x09,  0xFC,  0x11,  0x04,  0x11,  0x04,  0x25,  0x04,  0x45, 	/* 30240 */
+	0xFC,  0x09,  0x04,  0x09,  0x04,  0x11,  0x04,  0x31,  0xFC,  0x51,  0x04,  0x11,  0x04,  0x11,  0x04,  0x11, 	/* 30250 */
+	0x04,  0x17,  0xFF,  0x10,  0x00,  0x83,  0x08,  0x20,  0x09,  0x20,  0x11,  0x20,  0x11,  0x20,  0x25,  0xFE, 	/* 30260 */
+	0x46,  0x20,  0x0A,  0x20,  0x0C,  0x20,  0x10,  0x20,  0x31,  0xFC,  0x50,  0x20,  0x10,  0x20,  0x10,  0x20, 	/* 30270 */
+	0x10,  0x20,  0x17,  0xFF,  0x10,  0x00,  0x84,  0x08,  0x00,  0x0B,  0xFC,  0x11,  0x04,  0x10,  0x88,  0x24, 	/* 30280 */
+	0x50,  0x44,  0x30,  0x08,  0xCC,  0x0F,  0x03,  0x10,  0x20,  0x10,  0x20,  0x33,  0xFE,  0x50,  0x20,  0x10, 	/* 30290 */
+	0x20,  0x10,  0x20,  0x17,  0xFF,  0x10,  0x00,  0x85,  0x04,  0x20,  0x04,  0x20,  0x09,  0xFE,  0x08,  0x20, 	/* 302A0 */
+	0x12,  0x20,  0x22,  0x20,  0x05,  0xFF,  0x04,  0x04,  0x08,  0x04,  0x1B,  0xFF,  0x28,  0x84,  0x48,  0x44, 	/* 302B0 */
+	0x08,  0x44,  0x08,  0x04,  0x08,  0x04,  0x08,  0x0C,  0x87,  0x08,  0x80,  0x08,  0x80,  0x10,  0xFE,  0x14, 	/* 302C0 */
+	0x82,  0x25,  0x02,  0x49,  0xF2,  0x0B,  0x12,  0x15,  0x12,  0x11,  0xF2,  0x31,  0x12,  0x51,  0x12,  0x11, 	/* 302D0 */
+	0x12,  0x11,  0xF2,  0x10,  0x02,  0x10,  0x04,  0x10,  0x18,  0x88,  0x08,  0x00,  0x09,  0xFC,  0x11,  0x04, 	/* 302E0 */
+	0x11,  0x04,  0x25,  0xFC,  0x45,  0x04,  0x09,  0x04,  0x09,  0xFC,  0x11,  0x22,  0x31,  0x24,  0x51,  0x18, 	/* 302F0 */
+	0x11,  0x10,  0x11,  0x08,  0x11,  0x64,  0x11,  0x82,  0x16,  0x01,  0x8A,  0x08,  0x00,  0x0B,  0xFE,  0x12, 	/* 30300 */
+	0x02,  0x12,  0x02,  0x26,  0xFA,  0x46,  0x8A,  0x0A,  0x8A,  0x0A,  0x8A,  0x1A,  0x8A,  0x2A,  0x8A,  0x4A, 	/* 30310 */
+	0xFA,  0x0A,  0x02,  0x0A,  0x02,  0x0A,  0x02,  0x0B,  0xFE,  0x08,  0x00,  0x8B,  0x08,  0x20,  0x08,  0x20, 	/* 30320 */
+	0x13,  0xFC,  0x10,  0x24,  0x24,  0x24,  0x47,  0xFF,  0x08,  0x24,  0x08,  0x24,  0x13,  0xFC,  0x10,  0x20, 	/* 30330 */
+	0x33,  0xFC,  0x50,  0x20,  0x10,  0x20,  0x17,  0xFF,  0x10,  0x20,  0x10,  0x20,  0x8C,  0x08,  0x40,  0x08, 	/* 30340 */
+	0x48,  0x10,  0x88,  0x13,  0x10,  0x24,  0xD0,  0x44,  0x24,  0x08,  0x42,  0x0B,  0xFD,  0x10,  0x41,  0x10, 	/* 30350 */
+	0xFC,  0x31,  0x88,  0x56,  0x48,  0x10,  0x30,  0x10,  0x70,  0x11,  0x8C,  0x16,  0x03,  0x90,  0x08,  0x20, 	/* 30360 */
+	0x08,  0x20,  0x10,  0x50,  0x10,  0x50,  0x24,  0x88,  0x45,  0x04,  0x0A,  0xFA,  0x0C,  0x21,  0x10,  0x20, 	/* 30370 */
+	0x37,  0xFE,  0x50,  0x20,  0x11,  0x28,  0x11,  0x24,  0x12,  0x22,  0x14,  0x22,  0x10,  0x60,  0x91,  0x08, 	/* 30380 */
+	0x00,  0x0B,  0xFE,  0x10,  0x00,  0x11,  0x24,  0x25,  0x24,  0x46,  0x48,  0x0A,  0xD8,  0x09,  0x24,  0x19, 	/* 30390 */
+	0x24,  0x18,  0x00,  0x29,  0xFC,  0x48,  0x20,  0x08,  0x20,  0x08,  0x20,  0x0F,  0xFF,  0x08,  0x00,  0x92, 	/* 303A0 */
+	0x08,  0x20,  0x08,  0x20,  0x11,  0xFE,  0x10,  0x20,  0x24,  0x20,  0x47,  0xFF,  0x08,  0x20,  0x08,  0x20, 	/* 303B0 */
+	0x11,  0x20,  0x11,  0x3E,  0x31,  0x20,  0x51,  0xA0,  0x11,  0x60,  0x12,  0x20,  0x12,  0x18,  0x14,  0x07, 	/* 303C0 */
+	0x93,  0x09,  0x04,  0x08,  0x84,  0x10,  0x88,  0x10,  0x10,  0x27,  0xFE,  0x48,  0x20,  0x08,  0x20,  0x11, 	/* 303D0 */
+	0x20,  0x11,  0x3E,  0x31,  0x20,  0x51,  0x20,  0x11,  0x20,  0x12,  0xA0,  0x12,  0x60,  0x14,  0x30,  0x18, 	/* 303E0 */
+	0x0F,  0x97,  0x08,  0x00,  0x09,  0xFC,  0x11,  0x04,  0x11,  0xFC,  0x25,  0x04,  0x45,  0x04,  0x09,  0xFC, 	/* 303F0 */
+	0x08,  0x00,  0x17,  0xFF,  0x30,  0x08,  0x57,  0xFF,  0x11,  0x08,  0x10,  0x88,  0x10,  0x88,  0x10,  0x08, 	/* 30400 */
+	0x10,  0x18,  0x98,  0x08,  0x48,  0x08,  0x48,  0x10,  0x48,  0x13,  0xCF,  0x24,  0x48,  0x44,  0x48,  0x08, 	/* 30410 */
+	0x48,  0x0B,  0xCF,  0x10,  0x48,  0x30,  0x48,  0x51,  0xC8,  0x16,  0x4F,  0x10,  0x88,  0x10,  0x88,  0x11, 	/* 30420 */
+	0x08,  0x12,  0x08,  0x99,  0x08,  0x10,  0x08,  0x90,  0x10,  0x90,  0x10,  0x9E,  0x24,  0x90,  0x44,  0x90, 	/* 30430 */
+	0x0B,  0xFF,  0x08,  0x10,  0x10,  0x90,  0x30,  0x90,  0x50,  0x9E,  0x10,  0x90,  0x11,  0x50,  0x11,  0x30, 	/* 30440 */
+	0x12,  0x18,  0x14,  0x07,  0x9E,  0x08,  0x84,  0x08,  0x84,  0x10,  0x84,  0x10,  0xC6,  0x25,  0x4A,  0x45, 	/* 30450 */
+	0x29,  0x0A,  0x10,  0x08,  0x10,  0x10,  0x90,  0x30,  0x90,  0x50,  0x9E,  0x10,  0x90,  0x11,  0x50,  0x11, 	/* 30460 */
+	0x30,  0x12,  0x18,  0x14,  0x07,  0xA0,  0x08,  0x20,  0x08,  0x20,  0x13,  0xFF,  0x10,  0x20,  0x25,  0x24, 	/* 30470 */
+	0x45,  0x24,  0x09,  0x26,  0x0A,  0xAA,  0x12,  0x69,  0x34,  0x30,  0x50,  0x70,  0x10,  0xA8,  0x11,  0x24, 	/* 30480 */
+	0x12,  0x22,  0x14,  0x21,  0x10,  0x20,  0xA1,  0x0A,  0x00,  0x0A,  0x1E,  0x13,  0xF2,  0x12,  0x92,  0x24, 	/* 30490 */
+	0x92,  0x44,  0x92,  0x0B,  0xF2,  0x08,  0x92,  0x12,  0x92,  0x32,  0xF2,  0x52,  0x92,  0x12,  0x92,  0x12, 	/* 304A0 */
+	0xFC,  0x13,  0x90,  0x1C,  0x10,  0x10,  0x10,  0xA8,  0x08,  0x20,  0x08,  0x40,  0x11,  0xFC,  0x11,  0x04, 	/* 304B0 */
+	0x25,  0xFC,  0x45,  0x04,  0x09,  0x04,  0x09,  0xFC,  0x10,  0x00,  0x33,  0xFE,  0x50,  0x20,  0x11,  0xFC, 	/* 304C0 */
+	0x10,  0x20,  0x10,  0x20,  0x17,  0xFF,  0x10,  0x00,  0xA9,  0x08,  0x80,  0x08,  0x80,  0x10,  0xFF,  0x15, 	/* 304D0 */
+	0x00,  0x25,  0xFC,  0x46,  0x84,  0x08,  0xFC,  0x08,  0x84,  0x18,  0xFC,  0x28,  0x20,  0x48,  0x7C,  0x08, 	/* 304E0 */
+	0x84,  0x09,  0x68,  0x08,  0x10,  0x08,  0x6C,  0x0B,  0x83,  0xAA,  0x08,  0x04,  0x08,  0x18,  0x11,  0xF0, 	/* 304F0 */
+	0x11,  0x10,  0x25,  0xFF,  0x45,  0x10,  0x09,  0x7C,  0x09,  0x44,  0x11,  0x44,  0x31,  0x7C,  0x52,  0x44, 	/* 30500 */
+	0x12,  0x7C,  0x12,  0x44,  0x14,  0x44,  0x18,  0x7C,  0x10,  0x00,  0xAD,  0x08,  0x10,  0x08,  0x3E,  0x10, 	/* 30510 */
+	0x62,  0x11,  0x94,  0x24,  0x48,  0x44,  0x30,  0x09,  0xC0,  0x0E,  0xFE,  0x10,  0xA0,  0x31,  0x20,  0x57, 	/* 30520 */
+	0xFF,  0x10,  0x20,  0x12,  0x22,  0x12,  0x22,  0x13,  0xFE,  0x10,  0x00,  0xAE,  0x09,  0x08,  0x0D,  0x48, 	/* 30530 */
+	0x15,  0x48,  0x15,  0x4F,  0x27,  0xCA,  0x4C,  0x52,  0x08,  0x12,  0x17,  0xE2,  0x12,  0x8A,  0x32,  0x8A, 	/* 30540 */
+	0x52,  0x84,  0x12,  0xA4,  0x12,  0xCC,  0x14,  0x92,  0x18,  0x22,  0x10,  0x41,  0xB3,  0x08,  0x40,  0x08, 	/* 30550 */
+	0x40,  0x17,  0xFF,  0x10,  0x40,  0x27,  0xFC,  0x46,  0x94,  0x0A,  0x94,  0x0A,  0x94,  0x13,  0xFC,  0x30, 	/* 30560 */
+	0x40,  0x50,  0x24,  0x12,  0xA2,  0x12,  0x81,  0x14,  0x89,  0x18,  0x88,  0x10,  0x78,  0xB4,  0x09,  0x10, 	/* 30570 */
+	0x0D,  0x50,  0x15,  0x50,  0x15,  0x5F,  0x27,  0xE4,  0x48,  0x24,  0x08,  0x44,  0x17,  0xD4,  0x11,  0x14, 	/* 30580 */
+	0x31,  0x14,  0x57,  0xC8,  0x11,  0x08,  0x11,  0x4C,  0x11,  0x94,  0x16,  0x22,  0x10,  0x41,  0xB9,  0x09, 	/* 30590 */
+	0x08,  0x09,  0x08,  0x0F,  0xE8,  0x11,  0x8F,  0x15,  0x54,  0x26,  0x54,  0x0B,  0xA4,  0x08,  0x14,  0x13, 	/* 305A0 */
+	0xD4,  0x32,  0x54,  0x53,  0xC8,  0x12,  0x48,  0x13,  0xCC,  0x12,  0x54,  0x12,  0x62,  0x12,  0xC1,  0xBC, 	/* 305B0 */
+	0x09,  0x08,  0x0A,  0x08,  0x17,  0xC8,  0x14,  0x4F,  0x27,  0xD4,  0x4C,  0x64,  0x0F,  0xD4,  0x11,  0x14, 	/* 305C0 */
+	0x1F,  0xF4,  0x32,  0x14,  0x53,  0x88,  0x12,  0x88,  0x12,  0x94,  0x14,  0x94,  0x18,  0xA2,  0x11,  0xC1, 	/* 305D0 */
+	0xBD,  0x09,  0x10,  0x0D,  0x50,  0x15,  0x50,  0x17,  0xDF,  0x21,  0x24,  0x49,  0x24,  0x0A,  0xD4,  0x16, 	/* 305E0 */
+	0x94,  0x11,  0x54,  0x37,  0xD4,  0x51,  0x28,  0x15,  0x88,  0x15,  0x4C,  0x15,  0x14,  0x19,  0x22,  0x11, 	/* 305F0 */
+	0x41,  0x83,  0x02,  0x00,  0x01,  0x00,  0x00,  0x80,  0x00,  0x40,  0x02,  0x40,  0x02,  0x00,  0x12,  0x08, 	/* 30600 */
+	0x12,  0x04,  0x12,  0x02,  0x12,  0x02,  0x22,  0x09,  0x22,  0x09,  0x42,  0x08,  0x01,  0x08,  0x00,  0xF8, 	/* 30610 */
+	0x00,  0x00,  0x85,  0x01,  0x00,  0x00,  0x88,  0x00,  0x48,  0x02,  0x48,  0x02,  0x10,  0x02,  0x10,  0x12, 	/* 30620 */
+	0x24,  0x12,  0x22,  0x12,  0x42,  0x22,  0x81,  0x23,  0x01,  0x42,  0x04,  0x02,  0x04,  0x05,  0x04,  0x18, 	/* 30630 */
+	0xFC,  0x60,  0x00,  0x8C,  0x00,  0x00,  0x1F,  0xF0,  0x00,  0x10,  0x00,  0x10,  0x1F,  0xF0,  0x10,  0x00, 	/* 30640 */
+	0x10,  0x08,  0x10,  0x08,  0x0F,  0xF8,  0x00,  0x80,  0x12,  0x44,  0x12,  0x22,  0x12,  0x21,  0x22,  0x09, 	/* 30650 */
+	0x41,  0x08,  0x00,  0xF8,  0x8D,  0x00,  0x00,  0x3F,  0xF8,  0x00,  0x88,  0x18,  0x88,  0x05,  0x08,  0x02, 	/* 30660 */
+	0x08,  0x05,  0x08,  0x18,  0x88,  0x60,  0x30,  0x04,  0x80,  0x04,  0x40,  0x14,  0x48,  0x14,  0x04,  0x24, 	/* 30670 */
+	0x12,  0x42,  0x12,  0x01,  0xF0,  0x96,  0x08,  0x08,  0x08,  0x08,  0x08,  0x08,  0x09,  0xFF,  0x0C,  0x08, 	/* 30680 */
+	0x2A,  0x08,  0x2A,  0x08,  0x28,  0x88,  0x28,  0x48,  0x48,  0x48,  0x08,  0x08,  0x08,  0x08,  0x08,  0x08, 	/* 30690 */
+	0x08,  0x08,  0x08,  0x08,  0x08,  0x18,  0x97,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x7F,  0xFF,  0x00, 	/* 306A0 */
+	0x80,  0x00,  0x80,  0x00,  0x80,  0x1F,  0xFC,  0x00,  0x80,  0x02,  0x40,  0x12,  0x24,  0x12,  0x22,  0x12, 	/* 306B0 */
+	0x01,  0x22,  0x09,  0x41,  0x08,  0x00,  0xF8,  0x98,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x7F,  0xFF, 	/* 306C0 */
+	0x04,  0x00,  0x04,  0x00,  0x04,  0x00,  0x04,  0x00,  0x03,  0xFC,  0x00,  0x80,  0x12,  0x40,  0x12,  0x24, 	/* 306D0 */
+	0x12,  0x22,  0x22,  0x09,  0x42,  0x09,  0x01,  0xF8,  0x99,  0x08,  0x20,  0x08,  0x20,  0x08,  0x20,  0x0B, 	/* 306E0 */
+	0xFF,  0x08,  0x80,  0x2C,  0x80,  0x2A,  0x80,  0x2A,  0x80,  0x28,  0x80,  0x48,  0x80,  0x08,  0x80,  0x08, 	/* 306F0 */
+	0x80,  0x08,  0x80,  0x08,  0x40,  0x08,  0x3E,  0x08,  0x00,  0x9C,  0x00,  0x40,  0x00,  0x40,  0x1F,  0xFF, 	/* 30700 */
+	0x10,  0x80,  0x10,  0x40,  0x10,  0x20,  0x10,  0x90,  0x10,  0x90,  0x14,  0x84,  0x14,  0x82,  0x14,  0x81, 	/* 30710 */
+	0x24,  0x81,  0x28,  0x81,  0x28,  0x84,  0x50,  0x44,  0x00,  0x3C,  0x9D,  0x00,  0x08,  0x00,  0x70,  0x1F, 	/* 30720 */
+	0x80,  0x00,  0x80,  0x00,  0x80,  0x7F,  0xFF,  0x01,  0x40,  0x02,  0x20,  0x0D,  0x18,  0x71,  0x07,  0x01, 	/* 30730 */
+	0x48,  0x09,  0x24,  0x09,  0x12,  0x11,  0x12,  0x21,  0x00,  0x03,  0x00,  0xA0,  0x01,  0x00,  0x01,  0x00, 	/* 30740 */
+	0x1F,  0xF8,  0x11,  0x08,  0x11,  0x08,  0x11,  0x08,  0x1F,  0xF8,  0x01,  0x00,  0x01,  0x00,  0x01,  0x40, 	/* 30750 */
+	0x12,  0x24,  0x12,  0x22,  0x22,  0x21,  0x22,  0x09,  0x41,  0x08,  0x00,  0xF8,  0xA4,  0x08,  0x80,  0x08, 	/* 30760 */
+	0x80,  0x08,  0xFE,  0x08,  0x90,  0x0D,  0x10,  0x2A,  0x10,  0x2A,  0x10,  0x2B,  0xFF,  0x28,  0x10,  0x48, 	/* 30770 */
+	0x10,  0x08,  0x10,  0x08,  0x10,  0x08,  0x10,  0x08,  0x10,  0x08,  0x10,  0x08,  0x10,  0xAB,  0x08,  0x20, 	/* 30780 */
+	0x08,  0x20,  0x08,  0x20,  0x09,  0xFC,  0x2C,  0x24,  0x2A,  0x24,  0x2A,  0x24,  0x28,  0x24,  0x4B,  0xFF, 	/* 30790 */
+	0x08,  0x20,  0x08,  0x50,  0x08,  0x50,  0x08,  0x88,  0x08,  0x88,  0x09,  0x04,  0x0A,  0x02,  0xB0,  0x08, 	/* 307A0 */
+	0x40,  0x08,  0x40,  0x09,  0xF8,  0x08,  0x48,  0x2C,  0x48,  0x2A,  0x89,  0x28,  0x89,  0x29,  0x27,  0x4A, 	/* 307B0 */
+	0x20,  0x08,  0x20,  0x0B,  0xFF,  0x08,  0x20,  0x08,  0x20,  0x08,  0x20,  0x08,  0x20,  0x08,  0x20,  0xB1, 	/* 307C0 */
+	0x08,  0x20,  0x08,  0x20,  0x08,  0x20,  0x09,  0xFF,  0x09,  0x21,  0x2D,  0x21,  0x2A,  0x20,  0x2A,  0x30, 	/* 307D0 */
+	0x28,  0x30,  0x48,  0x30,  0x08,  0x50,  0x08,  0x50,  0x08,  0x90,  0x09,  0x11,  0x0A,  0x09,  0x0C,  0x07, 	/* 307E0 */
+	0xB5,  0x00,  0x80,  0x00,  0x80,  0x01,  0x40,  0x02,  0x20,  0x04,  0x10,  0x1B,  0xEC,  0x60,  0x03,  0x0F, 	/* 307F0 */
+	0xF0,  0x00,  0x20,  0x00,  0x40,  0x12,  0x80,  0x12,  0x48,  0x12,  0x24,  0x22,  0x2A,  0x41,  0x0A,  0x00, 	/* 30800 */
+	0xF8,  0xB8,  0x08,  0x00,  0x09,  0xFC,  0x08,  0x44,  0x08,  0x44,  0x08,  0x44,  0x2C,  0x44,  0x2A,  0x44, 	/* 30810 */
+	0x2B,  0xFF,  0x28,  0x44,  0x48,  0x44,  0x08,  0x44,  0x08,  0x44,  0x08,  0x44,  0x08,  0x44,  0x0B,  0xFF, 	/* 30820 */
+	0x08,  0x00,  0xBB,  0x08,  0x04,  0x08,  0x18,  0x08,  0xE0,  0x08,  0x80,  0x0C,  0x80,  0x2A,  0xFF,  0x2A, 	/* 30830 */
+	0x88,  0x28,  0x88,  0x28,  0x88,  0x48,  0x88,  0x08,  0x88,  0x08,  0x88,  0x09,  0x08,  0x09,  0x08,  0x0A, 	/* 30840 */
+	0x08,  0x08,  0x08,  0xBD,  0x02,  0x00,  0x02,  0x00,  0x07,  0xFE,  0x18,  0x92,  0x61,  0x12,  0x06,  0x22, 	/* 30850 */
+	0x18,  0x42,  0x01,  0x82,  0x06,  0x04,  0x18,  0x98,  0x00,  0x40,  0x12,  0x42,  0x12,  0x01,  0x22,  0x09, 	/* 30860 */
+	0x42,  0x08,  0x01,  0xF8,  0xBF,  0x01,  0xE0,  0x04,  0x20,  0x04,  0x10,  0x08,  0x08,  0x1F,  0xF4,  0x62, 	/* 30870 */
+	0x13,  0x02,  0x10,  0x04,  0x10,  0x08,  0x10,  0x30,  0xE0,  0x00,  0x40,  0x12,  0x24,  0x12,  0x22,  0x22, 	/* 30880 */
+	0x09,  0x41,  0x09,  0x00,  0xF8,  0x8E,  0x04,  0x00,  0x04,  0x00,  0x0F,  0xFE,  0x09,  0x00,  0x11,  0x00, 	/* 30890 */
+	0x21,  0xF8,  0x41,  0x00,  0x01,  0x00,  0x01,  0xF8,  0x01,  0x00,  0x01,  0x40,  0x12,  0x24,  0x12,  0x22, 	/* 308A0 */
+	0x22,  0x09,  0x41,  0x09,  0x00,  0xF8,  0x8F,  0x08,  0x10,  0x08,  0x10,  0x08,  0x10,  0x08,  0xFE,  0x2C, 	/* 308B0 */
+	0x92,  0x2A,  0x92,  0x2A,  0x92,  0x28,  0x92,  0x48,  0x92,  0x0B,  0xFF,  0x08,  0x10,  0x08,  0x28,  0x08, 	/* 308C0 */
+	0x28,  0x08,  0x44,  0x08,  0x82,  0x0B,  0x01,  0x90,  0x08,  0x40,  0x08,  0x40,  0x08,  0x40,  0x08,  0xFE, 	/* 308D0 */
+	0x2C,  0x82,  0x2B,  0x02,  0x2A,  0xF2,  0x28,  0x92,  0x48,  0x92,  0x08,  0x92,  0x08,  0x92,  0x08,  0xF2, 	/* 308E0 */
+	0x08,  0x02,  0x08,  0x02,  0x08,  0x04,  0x08,  0x18,  0x92,  0x04,  0x00,  0x04,  0x00,  0x7F,  0xFE,  0x09, 	/* 308F0 */
+	0x22,  0x09,  0x14,  0x12,  0x08,  0x3E,  0x14,  0x05,  0x62,  0x18,  0x81,  0x60,  0x40,  0x00,  0x20,  0x12, 	/* 30900 */
+	0x24,  0x12,  0x02,  0x22,  0x09,  0x41,  0x09,  0x00,  0xF8,  0x95,  0x08,  0x10,  0x08,  0x10,  0x08,  0x20, 	/* 30910 */
+	0x08,  0xFE,  0x0C,  0x82,  0x2A,  0x82,  0x2A,  0x82,  0x28,  0x82,  0x28,  0xFE,  0x48,  0x82,  0x08,  0x82, 	/* 30920 */
+	0x08,  0x82,  0x08,  0x82,  0x08,  0x82,  0x08,  0xFE,  0x08,  0x00,  0x96,  0x08,  0x40,  0x08,  0x40,  0x08, 	/* 30930 */
+	0x40,  0x0B,  0xFF,  0x08,  0x40,  0x0C,  0x50,  0x2A,  0x90,  0x28,  0xFE,  0x29,  0x92,  0x49,  0x92,  0x0A, 	/* 30940 */
+	0x92,  0x08,  0x92,  0x08,  0x92,  0x08,  0x9C,  0x08,  0x10,  0x08,  0x10,  0x99,  0x08,  0x20,  0x08,  0x20, 	/* 30950 */
+	0x08,  0x20,  0x08,  0x20,  0x0B,  0xFF,  0x2C,  0x20,  0x2A,  0x20,  0x2A,  0x20,  0x48,  0x20,  0x09,  0xFC, 	/* 30960 */
+	0x09,  0x04,  0x09,  0x04,  0x09,  0x04,  0x09,  0x04,  0x09,  0xFC,  0x08,  0x00,  0x9B,  0x08,  0x00,  0x08, 	/* 30970 */
+	0xFC,  0x08,  0x84,  0x08,  0x84,  0x2C,  0x84,  0x2A,  0xFC,  0x2A,  0x84,  0x28,  0x84,  0x48,  0x84,  0x08, 	/* 30980 */
+	0x84,  0x08,  0xFC,  0x08,  0x00,  0x08,  0x00,  0x08,  0x00,  0x0B,  0xFF,  0x08,  0x00,  0x9C,  0x08,  0x20, 	/* 30990 */
+	0x08,  0x20,  0x08,  0x50,  0x08,  0x88,  0x0D,  0x04,  0x2A,  0xFE,  0x2A,  0x01,  0x28,  0x00,  0x29,  0xFC, 	/* 309A0 */
+	0x48,  0x44,  0x08,  0x44,  0x08,  0x44,  0x08,  0x44,  0x08,  0x58,  0x08,  0x40,  0x08,  0x40,  0x9D,  0x00, 	/* 309B0 */
+	0x00,  0x1F,  0xFC,  0x10,  0x84,  0x10,  0x84,  0x1F,  0xFC,  0x10,  0x84,  0x10,  0x84,  0x10,  0x84,  0x1F, 	/* 309C0 */
+	0xFC,  0x00,  0x80,  0x12,  0x40,  0x12,  0x24,  0x12,  0x22,  0x22,  0x09,  0x41,  0x09,  0x00,  0xF8,  0xA0, 	/* 309D0 */
+	0x01,  0x00,  0x01,  0x60,  0x02,  0x18,  0x04,  0xF4,  0x7F,  0x02,  0x00,  0x00,  0x0F,  0xF8,  0x08,  0x08, 	/* 309E0 */
+	0x08,  0x08,  0x0F,  0xF8,  0x00,  0x80,  0x12,  0x44,  0x12,  0x42,  0x22,  0x09,  0x41,  0x09,  0x00,  0xF8, 	/* 309F0 */
+	0xA1,  0x08,  0x20,  0x08,  0x20,  0x08,  0x20,  0x08,  0x28,  0x2C,  0x44,  0x2A,  0x44,  0x2A,  0x8E,  0x2B, 	/* 30A00 */
+	0xF2,  0x48,  0x02,  0x08,  0x00,  0x09,  0xFC,  0x09,  0x04,  0x09,  0x04,  0x09,  0x04,  0x09,  0xFC,  0x08, 	/* 30A10 */
+	0x00,  0xA5,  0x01,  0x00,  0x03,  0xE0,  0x04,  0x40,  0x08,  0x80,  0x3F,  0xF8,  0x00,  0x08,  0x00,  0x08, 	/* 30A20 */
+	0x0F,  0xF8,  0x00,  0x08,  0x1F,  0xF8,  0x00,  0x80,  0x12,  0x44,  0x12,  0x42,  0x22,  0x49,  0x42,  0x09, 	/* 30A30 */
+	0x01,  0xF8,  0xA6,  0x08,  0x00,  0x0B,  0xFE,  0x08,  0x20,  0x08,  0x28,  0x2C,  0xA4,  0x2A,  0xA4,  0x29, 	/* 30A40 */
+	0x22,  0x2A,  0x20,  0x4B,  0xFF,  0x08,  0x20,  0x08,  0x20,  0x08,  0x20,  0x08,  0x20,  0x08,  0x20,  0x08, 	/* 30A50 */
+	0x20,  0x08,  0x20,  0xA7,  0x08,  0x20,  0x08,  0xA0,  0x08,  0xA0,  0x08,  0xA0,  0x09,  0xFE,  0x2D,  0x20, 	/* 30A60 */
+	0x2B,  0x20,  0x2A,  0x20,  0x48,  0x20,  0x09,  0xFC,  0x08,  0x20,  0x08,  0x20,  0x08,  0x20,  0x08,  0x20, 	/* 30A70 */
+	0x0B,  0xFF,  0x08,  0x00,  0xA8,  0x08,  0x00,  0x0F,  0x7E,  0x09,  0x42,  0x11,  0x42,  0x32,  0x4C,  0x4A, 	/* 30A80 */
+	0x40,  0x04,  0x41,  0x08,  0x21,  0x10,  0x1F,  0x61,  0x00,  0x04,  0x80,  0x14,  0x44,  0x14,  0x42,  0x24, 	/* 30A90 */
+	0x09,  0x42,  0x09,  0x01,  0xF8,  0xA9,  0x08,  0x00,  0x09,  0xFE,  0x09,  0x02,  0x09,  0x02,  0x0D,  0xFE, 	/* 30AA0 */
+	0x2B,  0x00,  0x29,  0x40,  0x29,  0x44,  0x49,  0x48,  0x09,  0x70,  0x09,  0x40,  0x09,  0x40,  0x0A,  0x41, 	/* 30AB0 */
+	0x0A,  0x41,  0x0C,  0x21,  0x08,  0x1F,  0xAA,  0x08,  0x00,  0x0B,  0xFC,  0x08,  0x88,  0x08,  0x48,  0x08, 	/* 30AC0 */
+	0x50,  0x2C,  0x20,  0x2A,  0x50,  0x2A,  0x8C,  0x2B,  0x23,  0x48,  0x20,  0x09,  0xFC,  0x08,  0x20,  0x08, 	/* 30AD0 */
+	0x20,  0x08,  0x20,  0x0B,  0xFE,  0x08,  0x00,  0xAB,  0x10,  0x90,  0x10,  0x90,  0x17,  0xFE,  0x10,  0x92, 	/* 30AE0 */
+	0x30,  0x92,  0x3B,  0xFE,  0x36,  0x90,  0x52,  0x90,  0x53,  0xFE,  0x10,  0x92,  0x10,  0x92,  0x10,  0x92, 	/* 30AF0 */
+	0x10,  0x92,  0x11,  0x1C,  0x11,  0x10,  0x12,  0x10,  0xAF,  0x08,  0x20,  0x08,  0x20,  0x08,  0x20,  0x09, 	/* 30B00 */
+	0xFC,  0x2C,  0x20,  0x2A,  0x20,  0x2A,  0x20,  0x28,  0x20,  0x4B,  0xFF,  0x08,  0x20,  0x08,  0x20,  0x08, 	/* 30B10 */
+	0x48,  0x08,  0x44,  0x08,  0xBC,  0x0B,  0xC2,  0x08,  0x02,  0xB1,  0x04,  0x00,  0x04,  0x00,  0x0F,  0xFC, 	/* 30B20 */
+	0x09,  0x24,  0x11,  0x24,  0x2F,  0x44,  0x44,  0xE4,  0x08,  0x94,  0x01,  0x08,  0x02,  0x30,  0x00,  0x80, 	/* 30B30 */
+	0x12,  0x44,  0x12,  0x42,  0x22,  0x09,  0x42,  0x09,  0x01,  0xF8,  0xBA,  0x08,  0x40,  0x08,  0x20,  0x08, 	/* 30B40 */
+	0x10,  0x08,  0x00,  0x0C,  0xE0,  0x2A,  0x22,  0x28,  0x22,  0x2B,  0xB4,  0x28,  0xB4,  0x48,  0xA8,  0x09, 	/* 30B50 */
+	0x28,  0x09,  0x24,  0x0A,  0x24,  0x0C,  0x22,  0x08,  0x21,  0x08,  0x60,  0x81,  0x04,  0x04,  0x04,  0x38, 	/* 30B60 */
+	0x0B,  0xE0,  0x08,  0x20,  0x10,  0x20,  0x37,  0xFF,  0x50,  0x20,  0x10,  0x20,  0x10,  0x20,  0x13,  0xFE, 	/* 30B70 */
+	0x10,  0x40,  0x12,  0x24,  0x12,  0x22,  0x22,  0x09,  0x41,  0x09,  0x00,  0xF8,  0x82,  0x08,  0x80,  0x08, 	/* 30B80 */
+	0x80,  0x08,  0xFE,  0x08,  0x82,  0x29,  0x02,  0x2D,  0xF2,  0x2A,  0x92,  0x2A,  0x92,  0x48,  0xF2,  0x08, 	/* 30B90 */
+	0x92,  0x08,  0x92,  0x08,  0x92,  0x08,  0xF2,  0x08,  0x02,  0x08,  0x04,  0x08,  0x18,  0x83,  0x08,  0x10, 	/* 30BA0 */
+	0x08,  0x10,  0x09,  0xFE,  0x08,  0x10,  0x2C,  0x10,  0x2A,  0x10,  0x2B,  0xFF,  0x28,  0x04,  0x48,  0x04, 	/* 30BB0 */
+	0x09,  0xFF,  0x08,  0x04,  0x08,  0x84,  0x08,  0x44,  0x08,  0x44,  0x08,  0x04,  0x08,  0x0C,  0x86,  0x08, 	/* 30BC0 */
+	0x00,  0x0B,  0xFF,  0x08,  0x40,  0x08,  0x40,  0x0C,  0x7C,  0x2A,  0x64,  0x2A,  0x94,  0x28,  0x94,  0x48, 	/* 30BD0 */
+	0xC4,  0x08,  0xA8,  0x09,  0x28,  0x09,  0x08,  0x08,  0x08,  0x08,  0x08,  0x0B,  0xFF,  0x08,  0x00,  0x8A, 	/* 30BE0 */
+	0x08,  0x40,  0x08,  0x40,  0x09,  0xFC,  0x08,  0x44,  0x2C,  0x44,  0x2A,  0x84,  0x2B,  0x18,  0x28,  0x00, 	/* 30BF0 */
+	0x49,  0x08,  0x0F,  0xFF,  0x09,  0x29,  0x09,  0x29,  0x09,  0x29,  0x0A,  0x31,  0x0C,  0x21,  0x08,  0xC6, 	/* 30C00 */
+	0x8B,  0x00,  0x80,  0x00,  0x80,  0x7F,  0xFF,  0x01,  0x20,  0x09,  0x28,  0x09,  0x24,  0x11,  0x24,  0x22, 	/* 30C10 */
+	0x22,  0x42,  0x62,  0x04,  0x00,  0x00,  0x80,  0x12,  0x44,  0x12,  0x42,  0x22,  0x09,  0x41,  0x09,  0x00, 	/* 30C20 */
+	0xF8,  0x8D,  0x08,  0x20,  0x08,  0x24,  0x09,  0x24,  0x08,  0xA4,  0x2C,  0xA8,  0x2A,  0x20,  0x2A,  0x20, 	/* 30C30 */
+	0x2B,  0xFF,  0x48,  0x50,  0x08,  0x50,  0x08,  0x50,  0x08,  0x90,  0x08,  0x90,  0x09,  0x11,  0x0A,  0x11, 	/* 30C40 */
+	0x0C,  0x0F,  0x90,  0x00,  0x00,  0x7F,  0xF8,  0x11,  0x08,  0x11,  0x08,  0x11,  0x48,  0x15,  0x28,  0x19, 	/* 30C50 */
+	0x2A,  0x62,  0x0A,  0x04,  0x06,  0x01,  0x00,  0x04,  0x80,  0x14,  0x48,  0x14,  0x44,  0x24,  0x12,  0x42, 	/* 30C60 */
+	0x12,  0x01,  0xF0,  0x92,  0x08,  0x00,  0x09,  0xFE,  0x08,  0x00,  0x08,  0x00,  0x2C,  0xFC,  0x2A,  0x84, 	/* 30C70 */
+	0x2A,  0x84,  0x48,  0xFC,  0x08,  0x84,  0x08,  0x84,  0x08,  0x84,  0x08,  0xFC,  0x08,  0x00,  0x08,  0x00, 	/* 30C80 */
+	0x0B,  0xFF,  0x08,  0x00,  0x95,  0x04,  0x00,  0x04,  0x00,  0x7F,  0xFE,  0x09,  0x22,  0x09,  0x22,  0x11, 	/* 30C90 */
+	0x22,  0x3E,  0x22,  0x05,  0x3E,  0x18,  0x22,  0x61,  0x00,  0x00,  0x80,  0x12,  0x44,  0x12,  0x42,  0x22, 	/* 30CA0 */
+	0x09,  0x42,  0x09,  0x01,  0xF8,  0x99,  0x04,  0x08,  0x02,  0x10,  0x02,  0x20,  0x3F,  0xFE,  0x00,  0x80, 	/* 30CB0 */
+	0x00,  0x80,  0x1F,  0xFC,  0x00,  0x80,  0x00,  0x80,  0x7F,  0xFF,  0x00,  0x40,  0x12,  0x24,  0x12,  0x22, 	/* 30CC0 */
+	0x22,  0x09,  0x41,  0x09,  0x00,  0xF8,  0x9A,  0x00,  0x80,  0x00,  0x80,  0x1F,  0xFC,  0x00,  0x80,  0x00, 	/* 30CD0 */
+	0x80,  0x3F,  0xFE,  0x00,  0x80,  0x1F,  0xFC,  0x00,  0x80,  0x00,  0x80,  0x7F,  0xFF,  0x00,  0x40,  0x12, 	/* 30CE0 */
+	0x22,  0x12,  0x29,  0x22,  0x09,  0x41,  0xF8,  0x9F,  0x08,  0x80,  0x08,  0x80,  0x08,  0xFE,  0x08,  0x82, 	/* 30CF0 */
+	0x2D,  0x12,  0x2D,  0x12,  0x2A,  0x9A,  0x29,  0x6A,  0x49,  0x2A,  0x09,  0x5A,  0x09,  0x8A,  0x09,  0x0A, 	/* 30D00 */
+	0x09,  0xFA,  0x08,  0x02,  0x08,  0x04,  0x08,  0x18,  0xA0,  0x08,  0x20,  0x08,  0x20,  0x08,  0x20,  0x0B, 	/* 30D10 */
+	0xFF,  0x08,  0x40,  0x0C,  0x48,  0x2A,  0xC8,  0x2A,  0x88,  0x28,  0xBE,  0x49,  0x88,  0x0A,  0x88,  0x0C, 	/* 30D20 */
+	0x88,  0x08,  0x88,  0x08,  0x88,  0x08,  0xFF,  0x08,  0x80,  0xA2,  0x08,  0x00,  0x09,  0xFF,  0x09,  0x00, 	/* 30D30 */
+	0x09,  0x10,  0x2D,  0x12,  0x2B,  0x52,  0x29,  0x54,  0x29,  0x54,  0x49,  0x50,  0x09,  0x90,  0x09,  0x18, 	/* 30D40 */
+	0x09,  0x28,  0x0A,  0x24,  0x0A,  0x44,  0x0D,  0x82,  0x0E,  0x01,  0xA3,  0x00,  0x80,  0x00,  0x80,  0x79, 	/* 30D50 */
+	0xFE,  0x01,  0x22,  0x02,  0x24,  0x04,  0x20,  0x00,  0x50,  0x18,  0x88,  0x63,  0x04,  0x0C,  0x43,  0x00, 	/* 30D60 */
+	0x20,  0x12,  0x24,  0x12,  0x02,  0x22,  0x09,  0x41,  0x09,  0x00,  0xF8,  0xA4,  0x08,  0x20,  0x08,  0x20, 	/* 30D70 */
+	0x08,  0x40,  0x08,  0x80,  0x2D,  0xFC,  0x2B,  0x54,  0x29,  0x54,  0x29,  0x54,  0x49,  0x54,  0x09,  0x54, 	/* 30D80 */
+	0x09,  0x54,  0x09,  0x54,  0x09,  0x54,  0x09,  0x54,  0x0B,  0xFF,  0x08,  0x00,  0xA5,  0x00,  0x00,  0x7F, 	/* 30D90 */
+	0xA0,  0x12,  0x10,  0x12,  0x08,  0x12,  0x28,  0x1E,  0x20,  0x12,  0x20,  0x12,  0x24,  0x1E,  0xA2,  0x12, 	/* 30DA0 */
+	0xA1,  0x12,  0xA1,  0x12,  0xA0,  0x1F,  0x22,  0x72,  0x22,  0x02,  0x1E,  0x02,  0x00,  0xA8,  0x08,  0x00, 	/* 30DB0 */
+	0x08,  0xFC,  0x08,  0x84,  0x08,  0x84,  0x2C,  0xFC,  0x2A,  0x84,  0x2A,  0x84,  0x28,  0xFC,  0x48,  0xC2, 	/* 30DC0 */
+	0x08,  0xA2,  0x08,  0xA4,  0x08,  0x98,  0x08,  0x88,  0x08,  0xA4,  0x08,  0xC2,  0x0B,  0x01,  0xA9,  0x00, 	/* 30DD0 */
+	0x00,  0x1F,  0xFC,  0x10,  0x84,  0x10,  0x84,  0x1F,  0xFC,  0x11,  0x44,  0x12,  0x34,  0x1C,  0x0C,  0x1F, 	/* 30DE0 */
+	0xFC,  0x00,  0x80,  0x12,  0x40,  0x12,  0x24,  0x12,  0x22,  0x22,  0x09,  0x41,  0x09,  0x00,  0xF8,  0xAA, 	/* 30DF0 */
+	0x08,  0x40,  0x08,  0x40,  0x08,  0x7C,  0x08,  0x84,  0x2C,  0xC8,  0x2B,  0x28,  0x2A,  0x10,  0x28,  0x28, 	/* 30E00 */
+	0x48,  0x44,  0x08,  0x82,  0x09,  0xFD,  0x0A,  0x84,  0x08,  0x84,  0x08,  0x84,  0x08,  0xFC,  0x08,  0x00, 	/* 30E10 */
+	0xAB,  0x08,  0x00,  0x09,  0xFE,  0x09,  0x02,  0x09,  0x02,  0x2D,  0xFE,  0x2B,  0x02,  0x29,  0x02,  0x29, 	/* 30E20 */
+	0x7A,  0x49,  0x4A,  0x09,  0x4A,  0x09,  0x4A,  0x09,  0x7A,  0x09,  0x02,  0x09,  0x02,  0x09,  0x02,  0x09, 	/* 30E30 */
+	0x06,  0xAC,  0x08,  0x08,  0x08,  0x30,  0x09,  0xE0,  0x0C,  0x20,  0x2A,  0x20,  0x28,  0x20,  0x2B,  0xFF, 	/* 30E40 */
+	0x28,  0x20,  0x48,  0x20,  0x08,  0x20,  0x09,  0xFC,  0x09,  0x04,  0x09,  0x04,  0x09,  0x04,  0x09,  0xFC, 	/* 30E50 */
+	0x08,  0x00,  0xAD,  0x02,  0x20,  0x02,  0x20,  0x1F,  0xFC,  0x02,  0x20,  0x02,  0x20,  0x02,  0x20,  0x7F, 	/* 30E60 */
+	0xFF,  0x04,  0x10,  0x09,  0x08,  0x11,  0x04,  0x61,  0x03,  0x09,  0x48,  0x09,  0x24,  0x11,  0x24,  0x21, 	/* 30E70 */
+	0x00,  0x03,  0x00,  0xAF,  0x01,  0x00,  0x02,  0x00,  0x0F,  0xF0,  0x08,  0x10,  0x0F,  0xF0,  0x08,  0x10, 	/* 30E80 */
+	0x08,  0x10,  0x0F,  0xF0,  0x08,  0x10,  0x08,  0x10,  0x0F,  0xF0,  0x24,  0x84,  0x24,  0x42,  0x24,  0x49, 	/* 30E90 */
+	0x42,  0x09,  0x01,  0xF8,  0xB0,  0x08,  0x20,  0x08,  0x20,  0x08,  0x50,  0x08,  0x50,  0x0C,  0x88,  0x2A, 	/* 30EA0 */
+	0x84,  0x29,  0x02,  0x2A,  0xFD,  0x4C,  0x00,  0x08,  0x00,  0x08,  0xFC,  0x08,  0x84,  0x08,  0x84,  0x08, 	/* 30EB0 */
+	0x84,  0x08,  0xFC,  0x08,  0x00,  0xB5,  0x00,  0x80,  0x00,  0x80,  0x7F,  0xFF,  0x00,  0x80,  0x1F,  0xFC, 	/* 30EC0 */
+	0x10,  0x84,  0x10,  0x84,  0x1F,  0xFC,  0x10,  0x84,  0x1F,  0xFC,  0x00,  0x40,  0x12,  0x24,  0x12,  0x22, 	/* 30ED0 */
+	0x22,  0x09,  0x41,  0x09,  0x00,  0xF8,  0xB7,  0x04,  0x20,  0x04,  0x20,  0x08,  0x20,  0x17,  0xFF,  0x30, 	/* 30EE0 */
+	0x70,  0x50,  0xA8,  0x11,  0x24,  0x12,  0x22,  0x14,  0x21,  0x10,  0x20,  0x00,  0x80,  0x12,  0x44,  0x12, 	/* 30EF0 */
+	0x42,  0x22,  0x09,  0x42,  0x09,  0x01,  0xF8,  0x81,  0x08,  0x00,  0x08,  0xFE,  0x08,  0x82,  0x08,  0x82, 	/* 30F00 */
+	0x2C,  0xFE,  0x2A,  0x00,  0x2A,  0xFE,  0x28,  0x82,  0x48,  0x82,  0x08,  0xFE,  0x08,  0x82,  0x08,  0x82, 	/* 30F10 */
+	0x08,  0xFE,  0x08,  0x82,  0x08,  0x82,  0x08,  0x86,  0x83,  0x08,  0x00,  0x0B,  0xFE,  0x0A,  0x22,  0x0A, 	/* 30F20 */
+	0x22,  0x2E,  0x22,  0x2B,  0xFE,  0x2A,  0x22,  0x2A,  0x72,  0x4A,  0x72,  0x0A,  0xAA,  0x0A,  0xAA,  0x0B, 	/* 30F30 */
+	0x26,  0x0A,  0x22,  0x0A,  0x02,  0x0B,  0xFE,  0x08,  0x00,  0x84,  0x08,  0x10,  0x08,  0x54,  0x08,  0x52, 	/* 30F40 */
+	0x08,  0x92,  0x2D,  0x10,  0x2A,  0xFE,  0x2A,  0x82,  0x28,  0x82,  0x48,  0xFE,  0x08,  0x82,  0x08,  0x82, 	/* 30F50 */
+	0x08,  0xFE,  0x08,  0x82,  0x08,  0x82,  0x08,  0x82,  0x08,  0x86,  0x89,  0x00,  0x08,  0x00,  0x70,  0x3F, 	/* 30F60 */
+	0x88,  0x08,  0x88,  0x04,  0x90,  0x7F,  0xFF,  0x02,  0xA0,  0x04,  0x90,  0x18,  0x8C,  0x60,  0x83,  0x02, 	/* 30F70 */
+	0x40,  0x12,  0x24,  0x12,  0x22,  0x22,  0x09,  0x41,  0x09,  0x00,  0xF8,  0x8B,  0x08,  0x20,  0x08,  0x20, 	/* 30F80 */
+	0x0B,  0xFF,  0x08,  0x88,  0x2C,  0x88,  0x2A,  0x50,  0x28,  0x20,  0x28,  0x50,  0x49,  0x8C,  0x0E,  0x03, 	/* 30F90 */
+	0x09,  0xFC,  0x09,  0x04,  0x09,  0x04,  0x09,  0x04,  0x09,  0xFC,  0x08,  0x00,  0x8C,  0x08,  0x84,  0x08, 	/* 30FA0 */
+	0x48,  0x0B,  0xFE,  0x08,  0x22,  0x2C,  0x22,  0x2B,  0xFE,  0x29,  0x20,  0x29,  0x20,  0x49,  0xFE,  0x08, 	/* 30FB0 */
+	0x22,  0x08,  0x62,  0x08,  0xA2,  0x09,  0x22,  0x0E,  0x3C,  0x08,  0x20,  0x08,  0x20,  0x8D,  0x08,  0x00, 	/* 30FC0 */
+	0x09,  0xFC,  0x09,  0x04,  0x09,  0xFC,  0x2D,  0x04,  0x2B,  0x04,  0x29,  0xFC,  0x28,  0x00,  0x4B,  0xFE, 	/* 30FD0 */
+	0x08,  0x20,  0x08,  0x20,  0x0F,  0xFF,  0x08,  0x20,  0x08,  0x20,  0x08,  0x20,  0x08,  0x20,  0x92,  0x08, 	/* 30FE0 */
+	0x00,  0x08,  0xFC,  0x08,  0x84,  0x08,  0x84,  0x2C,  0xFC,  0x2A,  0x00,  0x29,  0xFE,  0x29,  0x22,  0x49, 	/* 30FF0 */
+	0x22,  0x09,  0x22,  0x09,  0xFE,  0x09,  0x00,  0x09,  0x01,  0x09,  0x01,  0x08,  0xFF,  0x08,  0x00,  0x94, 	/* 31000 */
+	0x09,  0x00,  0x09,  0x00,  0x09,  0xFE,  0x09,  0x00,  0x2A,  0x00,  0x2A,  0xFC,  0x2C,  0xA4,  0x2C,  0xA4, 	/* 31010 */
+	0x4B,  0xFF,  0x09,  0x24,  0x09,  0x24,  0x09,  0x24,  0x0B,  0xFF,  0x0A,  0x04,  0x08,  0x08,  0x08,  0x30, 	/* 31020 */
+	0x96,  0x08,  0x10,  0x08,  0x10,  0x0B,  0xFF,  0x08,  0x10,  0x0C,  0x10,  0x2B,  0xFF,  0x29,  0x01,  0x29, 	/* 31030 */
+	0x01,  0x48,  0xFE,  0x08,  0x04,  0x08,  0x08,  0x0B,  0xFF,  0x08,  0x10,  0x08,  0x10,  0x08,  0x10,  0x08, 	/* 31040 */
+	0x30,  0x97,  0x08,  0x40,  0x08,  0x7C,  0x08,  0x48,  0x08,  0x88,  0x2D,  0x10,  0x2B,  0xFE,  0x29,  0x22, 	/* 31050 */
+	0x29,  0x22,  0x49,  0x42,  0x09,  0xFE,  0x08,  0x50,  0x08,  0x50,  0x08,  0x90,  0x08,  0x91,  0x09,  0x11, 	/* 31060 */
+	0x0A,  0x0F,  0x9A,  0x08,  0x20,  0x08,  0x20,  0x0B,  0xFF,  0x08,  0x20,  0x2D,  0xFC,  0x2B,  0x24,  0x2B, 	/* 31070 */
+	0x24,  0x29,  0x24,  0x49,  0xFC,  0x08,  0x70,  0x08,  0x68,  0x08,  0xA4,  0x09,  0x22,  0x0A,  0x21,  0x0C, 	/* 31080 */
+	0x20,  0x08,  0x20,  0x9B,  0x08,  0x40,  0x08,  0x50,  0x08,  0x8C,  0x0B,  0xFA,  0x08,  0x50,  0x2C,  0x51, 	/* 31090 */
+	0x2A,  0x8F,  0x2B,  0x20,  0x48,  0x78,  0x08,  0x88,  0x0B,  0x50,  0x08,  0x30,  0x08,  0x20,  0x08,  0xD0, 	/* 310A0 */
+	0x0B,  0x0C,  0x0C,  0x03,  0x9F,  0x08,  0x00,  0x0B,  0xFE,  0x08,  0x20,  0x08,  0x20,  0x2D,  0xF8,  0x2A, 	/* 310B0 */
+	0x48,  0x2A,  0x48,  0x28,  0x48,  0x4B,  0xFF,  0x08,  0x00,  0x09,  0xFC,  0x09,  0x04,  0x09,  0x04,  0x09, 	/* 310C0 */
+	0x04,  0x09,  0xFC,  0x08,  0x00,  0xA0,  0x04,  0x20,  0x04,  0x20,  0x08,  0x7F,  0x0A,  0x44,  0x12,  0xC4, 	/* 310D0 */
+	0x33,  0x28,  0x52,  0x10,  0x12,  0x28,  0x10,  0x44,  0x11,  0x83,  0x04,  0x80,  0x14,  0x44,  0x14,  0x42, 	/* 310E0 */
+	0x24,  0x09,  0x42,  0x09,  0x01,  0xF8,  0xA3,  0x01,  0x00,  0x01,  0x00,  0x3F,  0xF8,  0x21,  0x08,  0x3F, 	/* 310F0 */
+	0xF8,  0x01,  0x00,  0x3F,  0xF8,  0x21,  0x08,  0x3F,  0xF8,  0x01,  0x00,  0x01,  0x00,  0x14,  0x88,  0x14, 	/* 31100 */
+	0x84,  0x24,  0x12,  0x42,  0x12,  0x01,  0xF0,  0xA6,  0x08,  0x84,  0x08,  0x44,  0x08,  0x48,  0x08,  0xFC, 	/* 31110 */
+	0x2C,  0x84,  0x2A,  0x84,  0x2A,  0x84,  0x28,  0x84,  0x48,  0xFC,  0x08,  0x50,  0x08,  0x50,  0x08,  0x50, 	/* 31120 */
+	0x08,  0x90,  0x08,  0x92,  0x09,  0x12,  0x0A,  0x0E,  0xA7,  0x10,  0x22,  0x10,  0xC2,  0x13,  0x92,  0x10, 	/* 31130 */
+	0x92,  0x18,  0x92,  0x37,  0xF2,  0x34,  0x92,  0x30,  0x92,  0x51,  0xD2,  0x51,  0xB2,  0x12,  0x92,  0x12, 	/* 31140 */
+	0x82,  0x14,  0x82,  0x10,  0x82,  0x10,  0x82,  0x10,  0x86,  0xA9,  0x08,  0x42,  0x09,  0x22,  0x08,  0xA4, 	/* 31150 */
+	0x08,  0xA4,  0x2C,  0x88,  0x2A,  0x00,  0x2B,  0x0A,  0x29,  0x0A,  0x49,  0xCA,  0x09,  0x32,  0x09,  0x12, 	/* 31160 */
+	0x09,  0x2A,  0x09,  0x4A,  0x09,  0x82,  0x09,  0xFE,  0x08,  0x00,  0xAA,  0x00,  0x00,  0x3F,  0xFE,  0x02, 	/* 31170 */
+	0x40,  0x02,  0x40,  0x1F,  0xF8,  0x12,  0x48,  0x12,  0x48,  0x1F,  0xF8,  0x02,  0x40,  0x7F,  0xFE,  0x00, 	/* 31180 */
+	0x80,  0x12,  0x48,  0x12,  0x44,  0x22,  0x12,  0x42,  0x12,  0x01,  0xF0,  0xB2,  0x02,  0x20,  0x02,  0x20, 	/* 31190 */
+	0x7E,  0x3F,  0x02,  0x20,  0x3E,  0x3E,  0x02,  0x20,  0x0E,  0x20,  0x72,  0x3F,  0x02,  0x20,  0x04,  0x20, 	/* 311A0 */
+	0x08,  0x80,  0x12,  0x48,  0x12,  0x44,  0x22,  0x0A,  0x41,  0x0A,  0x00,  0xF8,  0xB3,  0x00,  0x80,  0x7F, 	/* 311B0 */
+	0xFF,  0x00,  0x80,  0x07,  0xF8,  0x24,  0x08,  0x27,  0xF8,  0x24,  0x08,  0x27,  0xF8,  0x24,  0x08,  0x27, 	/* 311C0 */
+	0xF8,  0x3F,  0xFF,  0x02,  0x80,  0x12,  0x44,  0x12,  0x52,  0x22,  0x11,  0x41,  0xF1,  0xB4,  0x08,  0x20, 	/* 311D0 */
+	0x08,  0x20,  0x0B,  0xFE,  0x08,  0x00,  0x2C,  0x88,  0x2A,  0x88,  0x2A,  0xCC,  0x29,  0x32,  0x4A,  0x20, 	/* 311E0 */
+	0x08,  0x20,  0x0B,  0xFF,  0x08,  0x20,  0x08,  0x20,  0x08,  0x20,  0x08,  0x20,  0x08,  0x20,  0xB5,  0x08, 	/* 311F0 */
+	0x00,  0x08,  0xFE,  0x08,  0x80,  0x08,  0xFC,  0x2C,  0x80,  0x2A,  0xFC,  0x2A,  0x80,  0x28,  0x80,  0x4B, 	/* 31200 */
+	0xFF,  0x08,  0xA2,  0x08,  0x92,  0x08,  0x94,  0x08,  0x88,  0x08,  0x84,  0x08,  0xE2,  0x0B,  0x01,  0xB6, 	/* 31210 */
+	0x00,  0x00,  0x7E,  0x7E,  0x42,  0x42,  0x7E,  0x7E,  0x42,  0x42,  0x42,  0x42,  0x7E,  0x7E,  0x41,  0x02, 	/* 31220 */
+	0x42,  0x82,  0x42,  0x92,  0x4A,  0x0A,  0x4A,  0x2A,  0x4A,  0x22,  0x51,  0xE2,  0x40,  0x02,  0x40,  0x06, 	/* 31230 */
+	0xB8,  0x08,  0x04,  0x08,  0x18,  0x09,  0xE0,  0x08,  0x20,  0x2D,  0xFF,  0x2A,  0x70,  0x28,  0xAC,  0x2B, 	/* 31240 */
+	0x23,  0x48,  0x20,  0x09,  0xFC,  0x08,  0x10,  0x08,  0x20,  0x0B,  0xFF,  0x08,  0x20,  0x08,  0x20,  0x08, 	/* 31250 */
+	0x60,  0xBC,  0x08,  0x20,  0x08,  0x20,  0x08,  0x3F,  0x08,  0x20,  0x2C,  0xFC,  0x2A,  0x84,  0x2A,  0x84, 	/* 31260 */
+	0x28,  0xFC,  0x48,  0x84,  0x08,  0x84,  0x08,  0xFC,  0x08,  0x20,  0x0B,  0xFF,  0x08,  0x20,  0x08,  0x20, 	/* 31270 */
+	0x08,  0x20,  0xBD,  0x08,  0x20,  0x08,  0x20,  0x0B,  0xFF,  0x08,  0x20,  0x2D,  0xFC,  0x2A,  0x24,  0x2B, 	/* 31280 */
+	0xFF,  0x28,  0x24,  0x49,  0xFC,  0x08,  0x20,  0x0B,  0xFF,  0x08,  0x48,  0x08,  0x88,  0x09,  0xF0,  0x08, 	/* 31290 */
+	0x68,  0x0B,  0x84,  0x85,  0x08,  0x20,  0x08,  0x20,  0x0B,  0xFE,  0x08,  0x20,  0x0D,  0xFC,  0x2A,  0x20, 	/* 312A0 */
+	0x2B,  0xFF,  0x28,  0x00,  0x28,  0xFC,  0x48,  0x84,  0x08,  0xFC,  0x08,  0x84,  0x08,  0xFC,  0x08,  0x84, 	/* 312B0 */
+	0x08,  0x84,  0x08,  0x8C,  0x86,  0x08,  0x00,  0x09,  0xFE,  0x09,  0x22,  0x09,  0x22,  0x29,  0x7A,  0x2D, 	/* 312C0 */
+	0x22,  0x2B,  0x22,  0x29,  0xFE,  0x49,  0x22,  0x09,  0x7A,  0x09,  0x4A,  0x09,  0x4A,  0x09,  0x7A,  0x09, 	/* 312D0 */
+	0x02,  0x09,  0x02,  0x0A,  0x06,  0x87,  0x08,  0x20,  0x08,  0x20,  0x0B,  0xFF,  0x08,  0x00,  0x0C,  0xFC, 	/* 312E0 */
+	0x2A,  0x84,  0x2A,  0xFC,  0x28,  0x00,  0x49,  0xFC,  0x08,  0x08,  0x08,  0x10,  0x0B,  0xFF,  0x08,  0x10, 	/* 312F0 */
+	0x08,  0x10,  0x08,  0x10,  0x08,  0x30,  0x91,  0x00,  0x48,  0x00,  0x44,  0x7F,  0xFF,  0x00,  0x40,  0x1F, 	/* 31300 */
+	0x44,  0x11,  0x24,  0x11,  0x28,  0x1F,  0x12,  0x07,  0xAA,  0x78,  0x46,  0x02,  0x82,  0x12,  0x44,  0x12, 	/* 31310 */
+	0x42,  0x22,  0x09,  0x41,  0x09,  0x00,  0xF8,  0x93,  0x08,  0xA8,  0x08,  0xA4,  0x09,  0x24,  0x0B,  0xFE, 	/* 31320 */
+	0x28,  0x20,  0x2C,  0x50,  0x2B,  0xFF,  0x28,  0x48,  0x48,  0x84,  0x09,  0xFA,  0x0A,  0x89,  0x08,  0x88, 	/* 31330 */
+	0x08,  0xB0,  0x08,  0x84,  0x08,  0x84,  0x08,  0x7C,  0x98,  0x08,  0x00,  0x09,  0xFE,  0x09,  0x0A,  0x09, 	/* 31340 */
+	0x4A,  0x29,  0x32,  0x2D,  0xFE,  0x2B,  0x22,  0x29,  0x22,  0x49,  0xFE,  0x09,  0x42,  0x09,  0x42,  0x09, 	/* 31350 */
+	0x42,  0x09,  0x3A,  0x09,  0x02,  0x09,  0x02,  0x09,  0x06,  0x9A,  0x08,  0x80,  0x08,  0x80,  0x08,  0xFE, 	/* 31360 */
+	0x08,  0xAA,  0x2D,  0x2A,  0x2A,  0x4A,  0x2A,  0x92,  0x28,  0x22,  0x48,  0x4C,  0x08,  0x20,  0x08,  0x90, 	/* 31370 */
+	0x0A,  0x94,  0x0A,  0x82,  0x0A,  0x89,  0x0C,  0x89,  0x08,  0x78,  0x9C,  0x08,  0x48,  0x08,  0x48,  0x09, 	/* 31380 */
+	0xFE,  0x08,  0x48,  0x0C,  0x48,  0x2A,  0x48,  0x2B,  0xFF,  0x28,  0x00,  0x48,  0xFC,  0x08,  0x84,  0x08, 	/* 31390 */
+	0x84,  0x08,  0xFC,  0x08,  0x84,  0x08,  0x84,  0x08,  0xFC,  0x08,  0x00,  0x9F,  0x08,  0x40,  0x08,  0x48, 	/* 313A0 */
+	0x08,  0x48,  0x08,  0x90,  0x0C,  0xFE,  0x2A,  0x90,  0x2B,  0x90,  0x28,  0xFE,  0x48,  0x90,  0x08,  0x90, 	/* 313B0 */
+	0x08,  0xFE,  0x08,  0x90,  0x08,  0x90,  0x08,  0x90,  0x08,  0xFF,  0x08,  0x80,  0xA0,  0x01,  0x00,  0x7F, 	/* 313C0 */
+	0xFE,  0x01,  0x00,  0x1F,  0xF8,  0x11,  0x08,  0x1F,  0xF8,  0x11,  0x08,  0x1F,  0xF8,  0x01,  0x18,  0x01, 	/* 313D0 */
+	0xF4,  0x7E,  0x82,  0x10,  0x44,  0x12,  0x42,  0x22,  0x09,  0x42,  0x09,  0x01,  0xF8,  0xA1,  0x00,  0x00, 	/* 313E0 */
+	0x7F,  0xFF,  0x02,  0x20,  0x02,  0x20,  0x1E,  0x3C,  0x10,  0x04,  0x10,  0x04,  0x1E,  0x3C,  0x02,  0x20, 	/* 313F0 */
+	0x7F,  0xFF,  0x00,  0x80,  0x12,  0x44,  0x12,  0x42,  0x22,  0x09,  0x41,  0x09,  0x00,  0xF8,  0xA3,  0x08, 	/* 31400 */
+	0x80,  0x28,  0x80,  0x3E,  0xFE,  0x29,  0x2A,  0x4A,  0x2A,  0x08,  0x4A,  0x0E,  0x92,  0x79,  0x12,  0x08, 	/* 31410 */
+	0x22,  0x08,  0x4C,  0x08,  0xC0,  0x12,  0x20,  0x12,  0x22,  0x12,  0x09,  0x21,  0x09,  0x40,  0xF8,  0xA7, 	/* 31420 */
+	0x08,  0x00,  0x08,  0xFC,  0x08,  0x84,  0x08,  0x84,  0x2C,  0xFC,  0x2A,  0x84,  0x2A,  0x84,  0x28,  0xFC, 	/* 31430 */
+	0x48,  0x84,  0x08,  0x84,  0x08,  0xFC,  0x08,  0x84,  0x0B,  0xFF,  0x08,  0x28,  0x08,  0xC4,  0x0B,  0x02, 	/* 31440 */
+	0xA8,  0x08,  0x20,  0x08,  0x28,  0x08,  0x44,  0x09,  0xFA,  0x0C,  0x20,  0x2B,  0xFF,  0x28,  0x48,  0x28, 	/* 31450 */
+	0x84,  0x4B,  0x12,  0x08,  0x61,  0x09,  0x88,  0x08,  0x32,  0x09,  0xC4,  0x08,  0x18,  0x08,  0x60,  0x0B, 	/* 31460 */
+	0x80,  0xB0,  0x08,  0x20,  0x08,  0x20,  0x09,  0xFF,  0x08,  0x40,  0x2C,  0x7E,  0x2A,  0x90,  0x29,  0xFF, 	/* 31470 */
+	0x2A,  0x00,  0x48,  0xFE,  0x08,  0x82,  0x08,  0xFE,  0x08,  0x82,  0x08,  0xFE,  0x08,  0x82,  0x08,  0x82, 	/* 31480 */
+	0x08,  0x86,  0xB1,  0x08,  0x92,  0x08,  0x92,  0x0B,  0x6C,  0x09,  0x24,  0x2C,  0x92,  0x2A,  0x92,  0x2A, 	/* 31490 */
+	0x20,  0x29,  0xFE,  0x49,  0x0A,  0x09,  0x4A,  0x09,  0x32,  0x09,  0x2A,  0x09,  0x4A,  0x09,  0x82,  0x09, 	/* 314A0 */
+	0xFE,  0x08,  0x00,  0xB3,  0x04,  0x00,  0x04,  0x7E,  0x7F,  0xC2,  0x04,  0x7E,  0x0C,  0x42,  0x0E,  0x42, 	/* 314B0 */
+	0x15,  0x7E,  0x24,  0x42,  0x44,  0x42,  0x04,  0xFE,  0x02,  0x40,  0x12,  0x24,  0x12,  0x22,  0x22,  0x09, 	/* 314C0 */
+	0x41,  0x09,  0x00,  0xF8,  0xB4,  0x08,  0x20,  0x09,  0x22,  0x09,  0x22,  0x09,  0x22,  0x0D,  0xFE,  0x2A, 	/* 314D0 */
+	0x00,  0x2B,  0xFF,  0x28,  0x20,  0x48,  0x40,  0x09,  0xFE,  0x09,  0x52,  0x09,  0x52,  0x09,  0x52,  0x09, 	/* 314E0 */
+	0x52,  0x09,  0x52,  0x09,  0x06,  0xB6,  0x08,  0x20,  0x08,  0x40,  0x09,  0xFC,  0x09,  0x04,  0x2D,  0xFC, 	/* 314F0 */
+	0x2B,  0x04,  0x29,  0x04,  0x29,  0xFC,  0x48,  0x00,  0x0B,  0xFE,  0x08,  0x20,  0x09,  0xFC,  0x08,  0x20, 	/* 31500 */
+	0x08,  0x20,  0x0F,  0xFF,  0x08,  0x00,  0xB7,  0x00,  0x80,  0x3F,  0xFE,  0x00,  0x80,  0x1F,  0xFC,  0x01, 	/* 31510 */
+	0x40,  0x7F,  0xFF,  0x02,  0x20,  0x0F,  0xF8,  0x74,  0x17,  0x07,  0xF0,  0x04,  0x10,  0x17,  0xF0,  0x12, 	/* 31520 */
+	0x42,  0x22,  0x21,  0x42,  0x09,  0x01,  0xF8,  0xB9,  0x04,  0x10,  0x04,  0x10,  0x7F,  0xFF,  0x04,  0x10, 	/* 31530 */
+	0x01,  0x00,  0x7F,  0xFE,  0x02,  0x00,  0x07,  0xF8,  0x1C,  0x08,  0x64,  0x08,  0x07,  0xF8,  0x12,  0x44, 	/* 31540 */
+	0x12,  0x22,  0x22,  0x29,  0x42,  0x09,  0x01,  0xF8,  0xBA,  0x08,  0x00,  0x09,  0xFC,  0x09,  0x04,  0x09, 	/* 31550 */
+	0xFC,  0x2D,  0x04,  0x2B,  0x04,  0x29,  0xFC,  0x28,  0xA0,  0x48,  0xA0,  0x09,  0xFE,  0x0A,  0x20,  0x0B, 	/* 31560 */
+	0xFC,  0x08,  0x20,  0x08,  0x20,  0x0F,  0xFF,  0x08,  0x00,  0xBB,  0x10,  0x02,  0x13,  0xD2,  0x12,  0x52, 	/* 31570 */
+	0x12,  0x52,  0x33,  0xD2,  0x3A,  0x52,  0x36,  0x52,  0x52,  0x52,  0x53,  0xD2,  0x12,  0x52,  0x12,  0x52, 	/* 31580 */
+	0x13,  0xD2,  0x11,  0x42,  0x11,  0x22,  0x12,  0x02,  0x14,  0x06,  0x80,  0x10,  0x48,  0x11,  0x88,  0x17, 	/* 31590 */
+	0x08,  0x11,  0x0A,  0x19,  0x2A,  0x37,  0xEC,  0x31,  0x2C,  0x31,  0x48,  0x53,  0x88,  0x13,  0x54,  0x15, 	/* 315A0 */
+	0x54,  0x15,  0x14,  0x19,  0x24,  0x11,  0x22,  0x11,  0x22,  0x11,  0x41,  0x81,  0x01,  0x10,  0x06,  0x10, 	/* 315B0 */
+	0x3C,  0x12,  0x04,  0x52,  0x7F,  0x54,  0x04,  0xA8,  0x0E,  0x28,  0x15,  0x44,  0x24,  0x82,  0x45,  0x01, 	/* 315C0 */
+	0x14,  0x80,  0x14,  0x48,  0x14,  0x44,  0x24,  0x12,  0x42,  0x12,  0x01,  0xF0,  0x83,  0x08,  0x20,  0x08, 	/* 315D0 */
+	0x20,  0x0B,  0xFF,  0x0A,  0x01,  0x2A,  0xFD,  0x2C,  0x00,  0x2A,  0xFC,  0x28,  0x84,  0x48,  0x84,  0x08, 	/* 315E0 */
+	0xFC,  0x08,  0x84,  0x08,  0x84,  0x08,  0xFC,  0x08,  0x00,  0x0B,  0xFF,  0x08,  0x00,  0x86,  0x09,  0x00, 	/* 315F0 */
+	0x08,  0xBE,  0x10,  0x80,  0x26,  0x00,  0x45,  0x7F,  0x09,  0x04,  0x10,  0x44,  0x30,  0x84,  0x50,  0x84, 	/* 31600 */
+	0x11,  0x04,  0x12,  0x8C,  0x00,  0x40,  0x12,  0x42,  0x12,  0x09,  0x22,  0x09,  0x41,  0xF8,  0x88,  0x00, 	/* 31610 */
+	0x80,  0x01,  0x40,  0x02,  0x20,  0x0F,  0xF8,  0x70,  0x07,  0x1F,  0x04,  0x11,  0x24,  0x1F,  0x24,  0x11, 	/* 31620 */
+	0x24,  0x1F,  0x24,  0x11,  0x04,  0x13,  0x8C,  0x02,  0x44,  0x12,  0x42,  0x22,  0x11,  0x41,  0xF1,  0x89, 	/* 31630 */
+	0x08,  0x20,  0x08,  0x20,  0x08,  0x50,  0x08,  0x48,  0x0C,  0x84,  0x2B,  0x7A,  0x2A,  0x01,  0x29,  0xE2, 	/* 31640 */
+	0x49,  0x2A,  0x09,  0xEA,  0x09,  0x2A,  0x09,  0xEA,  0x09,  0x2A,  0x09,  0x22,  0x09,  0x22,  0x09,  0x66, 	/* 31650 */
+	0x8D,  0x00,  0x20,  0x3F,  0x20,  0x21,  0x3F,  0x21,  0x24,  0x3F,  0x54,  0x28,  0x94,  0x3F,  0x08,  0x24, 	/* 31660 */
+	0x08,  0x22,  0x94,  0x39,  0xA2,  0x60,  0xC1,  0x12,  0x24,  0x12,  0x22,  0x22,  0x09,  0x42,  0x09,  0x01, 	/* 31670 */
+	0xF8,  0x8E,  0x08,  0x40,  0x08,  0x40,  0x08,  0xFF,  0x08,  0x80,  0x2D,  0xFC,  0x2A,  0x84,  0x2A,  0xFC, 	/* 31680 */
+	0x28,  0x84,  0x48,  0xFC,  0x08,  0x20,  0x08,  0x7C,  0x08,  0x88,  0x0B,  0x50,  0x08,  0x30,  0x08,  0xCC, 	/* 31690 */
+	0x0F,  0x03,  0x8F,  0x00,  0x80,  0x3F,  0xFE,  0x04,  0x10,  0x02,  0x20,  0x7F,  0xFF,  0x00,  0x00,  0x07, 	/* 316A0 */
+	0xF8,  0x04,  0x08,  0x07,  0xF8,  0x04,  0x08,  0x07,  0xF8,  0x12,  0x80,  0x12,  0x42,  0x22,  0x49,  0x42, 	/* 316B0 */
+	0x09,  0x01,  0xF8,  0x95,  0x08,  0x00,  0x0B,  0xDE,  0x0A,  0x52,  0x0A,  0x52,  0x0B,  0xDE,  0x2C,  0x00, 	/* 316C0 */
+	0x2B,  0xFC,  0x28,  0x00,  0x4B,  0xFF,  0x08,  0x40,  0x08,  0x40,  0x08,  0xFC,  0x08,  0x84,  0x08,  0x04, 	/* 316D0 */
+	0x08,  0x04,  0x08,  0x18,  0x9A,  0x00,  0x00,  0x1F,  0xF0,  0x11,  0x10,  0x1F,  0xF0,  0x11,  0x10,  0x1F, 	/* 316E0 */
+	0xF0,  0x01,  0x00,  0x7F,  0xFC,  0x41,  0x34,  0x41,  0xEC,  0x5E,  0x04,  0x40,  0x8C,  0x14,  0x40,  0x14, 	/* 316F0 */
+	0x54,  0x24,  0x12,  0x43,  0xF2,  0x9B,  0x00,  0x3C,  0x1F,  0xC8,  0x11,  0x08,  0x08,  0x90,  0x7F,  0xFE, 	/* 31700 */
+	0x44,  0x82,  0x54,  0x48,  0x14,  0x14,  0x23,  0xF2,  0x42,  0x02,  0x07,  0xE0,  0x0C,  0x20,  0x33,  0x40, 	/* 31710 */
+	0x01,  0x80,  0x06,  0x70,  0x78,  0x0E,  0x9F,  0x00,  0x48,  0x00,  0x44,  0x1F,  0xFF,  0x10,  0x40,  0x1F, 	/* 31720 */
+	0xA4,  0x10,  0x24,  0x17,  0x98,  0x14,  0x90,  0x17,  0xAA,  0x20,  0x46,  0x40,  0x82,  0x12,  0x44,  0x12, 	/* 31730 */
+	0x42,  0x22,  0x09,  0x41,  0x09,  0x00,  0xF8,  0xA1,  0x08,  0x80,  0x08,  0x80,  0x08,  0xFE,  0x09,  0x4A, 	/* 31740 */
+	0x2B,  0x4A,  0x2C,  0xD2,  0x29,  0x32,  0x2A,  0x2A,  0x48,  0x42,  0x08,  0x0C,  0x08,  0xA0,  0x0A,  0x90, 	/* 31750 */
+	0x0A,  0x92,  0x0A,  0x85,  0x0C,  0x45,  0x08,  0x3C,  0xA7,  0x08,  0x20,  0x08,  0x40,  0x09,  0xFC,  0x09, 	/* 31760 */
+	0x24,  0x0D,  0x24,  0x2B,  0xFC,  0x2B,  0x24,  0x29,  0x24,  0x29,  0xFC,  0x48,  0x54,  0x08,  0x54,  0x08, 	/* 31770 */
+	0x5A,  0x08,  0x9E,  0x08,  0x91,  0x09,  0x11,  0x0A,  0x0F,  0xA8,  0x08,  0x00,  0x08,  0x78,  0x7F,  0x49, 	/* 31780 */
+	0x08,  0x49,  0x3E,  0x47,  0x00,  0x80,  0x7F,  0xFC,  0x41,  0x44,  0x00,  0x28,  0x3E,  0x10,  0x00,  0x6C, 	/* 31790 */
+	0x12,  0x83,  0x12,  0x44,  0x22,  0x4A,  0x42,  0x09,  0x01,  0xF8,  0xAC,  0x21,  0x00,  0x11,  0x3E,  0x12, 	/* 317A0 */
+	0x22,  0x7F,  0xE2,  0x04,  0x3E,  0x24,  0xA2,  0x24,  0xBE,  0x3F,  0xA2,  0x08,  0x22,  0x10,  0x46,  0x20, 	/* 317B0 */
+	0x80,  0x12,  0x40,  0x12,  0x42,  0x22,  0x09,  0x41,  0x09,  0x00,  0xF8,  0xB4,  0x08,  0x20,  0x08,  0x20, 	/* 317C0 */
+	0x08,  0x50,  0x08,  0x48,  0x08,  0xF4,  0x2D,  0x02,  0x2B,  0xFD,  0x29,  0x04,  0x49,  0xFC,  0x09,  0x04, 	/* 317D0 */
+	0x09,  0xFC,  0x09,  0x00,  0x0A,  0xFE,  0x0A,  0x82,  0x0C,  0xFE,  0x08,  0x00,  0xBC,  0x08,  0x8C,  0x08, 	/* 317E0 */
+	0xF0,  0x08,  0x81,  0x08,  0x7F,  0x2D,  0x00,  0x2B,  0x7E,  0x2B,  0x42,  0x29,  0x7E,  0x49,  0x42,  0x09, 	/* 317F0 */
+	0x7E,  0x09,  0x42,  0x09,  0x7E,  0x09,  0x00,  0x09,  0xFF,  0x08,  0x66,  0x0B,  0x81,  0xBD,  0x08,  0x24, 	/* 31800 */
+	0x08,  0x22,  0x0B,  0xFF,  0x08,  0x20,  0x2D,  0xFC,  0x2B,  0x24,  0x29,  0xFC,  0x29,  0x24,  0x49,  0xFC, 	/* 31810 */
+	0x09,  0x24,  0x08,  0x08,  0x0B,  0xFF,  0x09,  0x08,  0x08,  0x88,  0x08,  0x88,  0x08,  0x18,  0xBE,  0x08, 	/* 31820 */
+	0x40,  0x08,  0x40,  0x08,  0xFE,  0x08,  0x80,  0x09,  0x78,  0x2C,  0x00,  0x2B,  0xFC,  0x28,  0x44,  0x4A, 	/* 31830 */
+	0x54,  0x09,  0x64,  0x08,  0x44,  0x0B,  0xF5,  0x08,  0xE5,  0x09,  0x53,  0x0A,  0x4B,  0x08,  0x41,  0xBF, 	/* 31840 */
+	0x00,  0x00,  0x1F,  0xFF,  0x10,  0x40,  0x13,  0xFC,  0x12,  0x04,  0x13,  0xFC,  0x12,  0x04,  0x13,  0xFC, 	/* 31850 */
+	0x22,  0x48,  0x24,  0x44,  0x48,  0xC2,  0x02,  0x40,  0x12,  0x22,  0x12,  0x09,  0x22,  0x09,  0x41,  0xF8, 	/* 31860 */
+	0x82,  0x10,  0x00,  0x0B,  0xFC,  0x08,  0x88,  0x40,  0x50,  0x23,  0xFE,  0x22,  0x22,  0x03,  0xFE,  0x0A, 	/* 31870 */
+	0x22,  0x13,  0xFE,  0x22,  0x22,  0x40,  0x26,  0x12,  0x44,  0x12,  0x22,  0x22,  0x29,  0x41,  0x09,  0x00, 	/* 31880 */
+	0xF8,  0x84,  0x08,  0x00,  0x0B,  0xFF,  0x08,  0x48,  0x08,  0x48,  0x0D,  0xFE,  0x2B,  0x4A,  0x29,  0x4A, 	/* 31890 */
+	0x29,  0xFE,  0x48,  0x20,  0x0F,  0xFF,  0x08,  0x70,  0x08,  0xA8,  0x09,  0x24,  0x0E,  0x23,  0x08,  0x20, 	/* 318A0 */
+	0x08,  0x20,  0x87,  0x02,  0x00,  0x1C,  0x78,  0x10,  0x49,  0x1E,  0x49,  0x12,  0x87,  0x1F,  0x00,  0x12, 	/* 318B0 */
+	0xFC,  0x1E,  0x24,  0x10,  0x28,  0x1E,  0x10,  0x22,  0x6C,  0x47,  0x83,  0x12,  0x44,  0x12,  0x22,  0x22, 	/* 318C0 */
+	0x09,  0x41,  0xF8,  0x88,  0x04,  0x08,  0x02,  0x10,  0x7F,  0xFF,  0x08,  0x20,  0x0A,  0x28,  0x32,  0xC8, 	/* 318D0 */
+	0x0C,  0x30,  0x05,  0x14,  0x09,  0x24,  0x7E,  0xFA,  0x00,  0x82,  0x12,  0x44,  0x12,  0x42,  0x22,  0x09, 	/* 318E0 */
+	0x41,  0x09,  0x00,  0xF8,  0x8A,  0x08,  0x44,  0x09,  0x98,  0x08,  0x48,  0x0B,  0xFF,  0x08,  0x48,  0x2D, 	/* 318F0 */
+	0xFE,  0x2A,  0x4A,  0x2B,  0xFF,  0x28,  0x4A,  0x49,  0xFE,  0x08,  0x48,  0x08,  0xCC,  0x09,  0x4A,  0x0A, 	/* 31900 */
+	0x49,  0x08,  0x48,  0x08,  0x48,  0x8B,  0x08,  0x20,  0x0A,  0x26,  0x11,  0x38,  0x7F,  0xA1,  0x11,  0x9F, 	/* 31910 */
+	0x1F,  0x20,  0x11,  0x26,  0x1F,  0x38,  0x11,  0x21,  0x13,  0x1F,  0x00,  0x80,  0x12,  0x44,  0x12,  0x42, 	/* 31920 */
+	0x22,  0x09,  0x41,  0x09,  0x00,  0xF8,  0x8C,  0x08,  0x88,  0x08,  0x88,  0x0B,  0xFF,  0x08,  0x88,  0x28, 	/* 31930 */
+	0x20,  0x2D,  0xFF,  0x2A,  0x80,  0x2A,  0x80,  0x48,  0x7C,  0x08,  0x00,  0x09,  0x24,  0x09,  0x24,  0x09, 	/* 31940 */
+	0x24,  0x09,  0x25,  0x0A,  0x25,  0x0C,  0x03,  0x8D,  0x08,  0x00,  0x08,  0xFC,  0x08,  0xA4,  0x08,  0xA4, 	/* 31950 */
+	0x28,  0xB4,  0x2C,  0xD4,  0x2A,  0x8C,  0x28,  0xFC,  0x48,  0x00,  0x09,  0xFE,  0x09,  0x4A,  0x09,  0x4A, 	/* 31960 */
+	0x09,  0x4A,  0x09,  0x4A,  0x0B,  0xFF,  0x08,  0x00,  0x8E,  0x08,  0x20,  0x08,  0x20,  0x0B,  0xFF,  0x08, 	/* 31970 */
+	0x20,  0x08,  0xFC,  0x2C,  0x84,  0x2A,  0xFC,  0x2A,  0x84,  0x28,  0xFC,  0x48,  0x84,  0x08,  0xFC,  0x08, 	/* 31980 */
+	0x00,  0x0B,  0xFF,  0x08,  0x48,  0x08,  0x84,  0x0B,  0x02,  0x93,  0x08,  0x00,  0x0B,  0xFF,  0x08,  0x48, 	/* 31990 */
+	0x09,  0xFE,  0x0D,  0x4A,  0x2B,  0x4A,  0x2B,  0xFE,  0x28,  0x00,  0x29,  0xFE,  0x48,  0x00,  0x0B,  0xFF, 	/* 319A0 */
+	0x08,  0x10,  0x08,  0x94,  0x09,  0x12,  0x0A,  0x11,  0x08,  0x30,  0x95,  0x02,  0x20,  0x7F,  0xFF,  0x02, 	/* 319B0 */
+	0x20,  0x0F,  0xF8,  0x08,  0x08,  0x0F,  0xF8,  0x08,  0x08,  0x0F,  0xF8,  0x01,  0x00,  0x7F,  0xFF,  0x04, 	/* 319C0 */
+	0x10,  0x19,  0x0C,  0x65,  0x4B,  0x09,  0x24,  0x11,  0x24,  0x03,  0x00,  0x98,  0x08,  0x20,  0x08,  0x20, 	/* 319D0 */
+	0x08,  0x50,  0x09,  0xFC,  0x09,  0x04,  0x2A,  0x8A,  0x2F,  0x7D,  0x28,  0x50,  0x49,  0x8C,  0x0E,  0x23, 	/* 319E0 */
+	0x08,  0x48,  0x09,  0x92,  0x08,  0x64,  0x09,  0x88,  0x08,  0x30,  0x0B,  0xC0,  0x99,  0x04,  0x04,  0x7F, 	/* 319F0 */
+	0xF8,  0x04,  0x20,  0x3F,  0xA0,  0x24,  0xBF,  0x3F,  0xA4,  0x24,  0xA4,  0x3F,  0xA4,  0x04,  0x44,  0x7F, 	/* 31A00 */
+	0x84,  0x04,  0x84,  0x12,  0x44,  0x12,  0x42,  0x22,  0x09,  0x41,  0x09,  0x00,  0xF8,  0x9A,  0x11,  0x02, 	/* 31A10 */
+	0x11,  0x04,  0x17,  0xF8,  0x11,  0x10,  0x17,  0xD0,  0x3D,  0x5F,  0x35,  0x52,  0x37,  0xD2,  0x55,  0x52, 	/* 31A20 */
+	0x15,  0x52,  0x17,  0xD2,  0x11,  0x12,  0x1F,  0xF2,  0x11,  0x12,  0x11,  0x22,  0x11,  0x02,  0x9D,  0x00, 	/* 31A30 */
+	0x00,  0x3F,  0xFE,  0x22,  0x10,  0x3F,  0xFE,  0x21,  0x10,  0x3F,  0xFC,  0x22,  0x00,  0x27,  0xF8,  0x2A, 	/* 31A40 */
+	0x08,  0x33,  0xF8,  0x20,  0x00,  0x3F,  0xFE,  0x12,  0x40,  0x12,  0x22,  0x22,  0x09,  0x41,  0xF9,  0x9F, 	/* 31A50 */
+	0x10,  0x48,  0x17,  0x88,  0x11,  0x08,  0x17,  0xE8,  0x39,  0x1E,  0x37,  0xCA,  0x35,  0x4A,  0x37,  0xCA, 	/* 31A60 */
+	0x55,  0x4A,  0x17,  0xCA,  0x11,  0x0A,  0x17,  0xCA,  0x11,  0x12,  0x11,  0xD2,  0x16,  0x22,  0x10,  0x4C, 	/* 31A70 */
+	0xA2,  0x08,  0x00,  0x08,  0xFC,  0x08,  0x84,  0x08,  0xFC,  0x2C,  0x84,  0x2A,  0xFC,  0x28,  0x00,  0x2B, 	/* 31A80 */
+	0xFE,  0x4A,  0x4A,  0x0B,  0xFE,  0x08,  0x00,  0x0B,  0xFC,  0x08,  0xC8,  0x08,  0x30,  0x08,  0xCC,  0x0B, 	/* 31A90 */
+	0x03,  0xA3,  0x08,  0x00,  0x08,  0xFE,  0x08,  0x92,  0x0B,  0xFF,  0x09,  0x24,  0x2D,  0xFC,  0x2A,  0x00, 	/* 31AA0 */
+	0x2B,  0xFC,  0x49,  0x04,  0x09,  0xFC,  0x09,  0x04,  0x09,  0xFC,  0x09,  0x04,  0x09,  0xFC,  0x08,  0x4C, 	/* 31AB0 */
+	0x0B,  0x83,  0xA5,  0x08,  0x08,  0x09,  0x28,  0x08,  0xA8,  0x08,  0xBE,  0x0A,  0x48,  0x2D,  0x08,  0x2D, 	/* 31AC0 */
+	0x7F,  0x28,  0x08,  0x2B,  0xBE,  0x48,  0xA2,  0x08,  0xA2,  0x08,  0xA2,  0x08,  0xBE,  0x09,  0x40,  0x0A, 	/* 31AD0 */
+	0x30,  0x0C,  0x0F,  0xA7,  0x08,  0x10,  0x7F,  0xFE,  0x08,  0x10,  0x7E,  0xFE,  0x08,  0x10,  0x7F,  0xFE, 	/* 31AE0 */
+	0x08,  0x10,  0x1F,  0xF8,  0x00,  0x08,  0x0F,  0xF8,  0x00,  0x08,  0x3F,  0xF8,  0x14,  0x84,  0x14,  0x52, 	/* 31AF0 */
+	0x24,  0x12,  0x43,  0xF0,  0xA8,  0x10,  0x00,  0x13,  0xFF,  0x12,  0x44,  0x12,  0x54,  0x33,  0xD4,  0x3A, 	/* 31B00 */
+	0x54,  0x36,  0x54,  0x33,  0xFF,  0x53,  0x04,  0x12,  0x8C,  0x12,  0x8C,  0x12,  0x4C,  0x12,  0xD4,  0x13, 	/* 31B10 */
+	0x55,  0x1C,  0x25,  0x10,  0x43,  0xAB,  0x08,  0x84,  0x08,  0x84,  0x11,  0x4A,  0x25,  0x29,  0x46,  0x10, 	/* 31B20 */
+	0x08,  0x90,  0x18,  0x9E,  0x28,  0x90,  0x49,  0x50,  0x0A,  0x30,  0x0C,  0x8F,  0x12,  0x44,  0x12,  0x42, 	/* 31B30 */
+	0x22,  0x09,  0x41,  0x09,  0x00,  0xF8,  0xAE,  0x00,  0x80,  0x00,  0xFC,  0x00,  0x80,  0x1F,  0xFF,  0x10, 	/* 31B40 */
+	0x9A,  0x1F,  0xE0,  0x10,  0x82,  0x17,  0xFE,  0x14,  0x48,  0x17,  0xF8,  0x14,  0x48,  0x17,  0xF8,  0x2A, 	/* 31B50 */
+	0x44,  0x2A,  0x2A,  0x52,  0x09,  0x21,  0xF9,  0xAF,  0x08,  0x80,  0x08,  0xFF,  0x09,  0x00,  0x0A,  0xFC, 	/* 31B60 */
+	0x2C,  0x84,  0x2A,  0xFC,  0x28,  0x84,  0x28,  0xFC,  0x48,  0x00,  0x0B,  0xFF,  0x08,  0x80,  0x09,  0xFE, 	/* 31B70 */
+	0x0A,  0x4A,  0x08,  0x92,  0x09,  0x22,  0x08,  0x4C,  0xB0,  0x00,  0x04,  0x3F,  0x84,  0x20,  0x84,  0x3F, 	/* 31B80 */
+	0x84,  0x20,  0x7F,  0x2F,  0x04,  0x20,  0x24,  0x3F,  0x94,  0x22,  0x14,  0x2A,  0x84,  0x56,  0x84,  0x05, 	/* 31B90 */
+	0x0C,  0x14,  0x80,  0x14,  0x92,  0x24,  0x11,  0x43,  0xF1,  0xB1,  0x08,  0x20,  0x08,  0x20,  0x0B,  0xFF, 	/* 31BA0 */
+	0x08,  0x20,  0x09,  0xFC,  0x2D,  0x24,  0x2B,  0xFC,  0x2B,  0x24,  0x29,  0xFC,  0x48,  0x24,  0x0B,  0xFE, 	/* 31BB0 */
+	0x08,  0x09,  0x0F,  0xFF,  0x09,  0x08,  0x08,  0x88,  0x08,  0x18,  0xB3,  0x10,  0x00,  0x13,  0xFE,  0x12, 	/* 31BC0 */
+	0x92,  0x12,  0x92,  0x33,  0xEA,  0x3A,  0x2A,  0x37,  0xE4,  0x32,  0x8A,  0x52,  0x91,  0x13,  0xE0,  0x10, 	/* 31BD0 */
+	0x20,  0x13,  0xFE,  0x10,  0x20,  0x10,  0x20,  0x17,  0xFF,  0x10,  0x00,  0xB4,  0x08,  0x00,  0x0B,  0xFF, 	/* 31BE0 */
+	0x08,  0xA5,  0x09,  0x29,  0x2C,  0x63,  0x2A,  0xA5,  0x29,  0x29,  0x28,  0x63,  0x48,  0x10,  0x08,  0xFE, 	/* 31BF0 */
+	0x08,  0x82,  0x08,  0xFE,  0x08,  0x82,  0x08,  0x82,  0x08,  0xFE,  0x08,  0x00,  0xB5,  0x10,  0x10,  0x13, 	/* 31C00 */
+	0xFF,  0x12,  0x10,  0x12,  0xFE,  0x3A,  0x12,  0x37,  0xFF,  0x32,  0x12,  0x52,  0xFE,  0x52,  0x10,  0x12, 	/* 31C10 */
+	0xFE,  0x12,  0x92,  0x12,  0xFE,  0x14,  0x92,  0x14,  0xFE,  0x18,  0x92,  0x10,  0x96,  0xB6,  0x00,  0x40, 	/* 31C20 */
+	0x1F,  0xFF,  0x11,  0x10,  0x1F,  0xFE,  0x11,  0x12,  0x1F,  0xFE,  0x10,  0x00,  0x1F,  0xFF,  0x15,  0x44, 	/* 31C30 */
+	0x15,  0x2A,  0x19,  0xF9,  0x12,  0x11,  0x2D,  0xA0,  0x20,  0xE0,  0x43,  0x18,  0x1C,  0x07,  0xB7,  0x10, 	/* 31C40 */
+	0x20,  0x10,  0x20,  0x13,  0xFF,  0x12,  0x20,  0x33,  0xFC,  0x3A,  0x24,  0x37,  0xFF,  0x32,  0x24,  0x53, 	/* 31C50 */
+	0xFC,  0x13,  0x22,  0x12,  0xB2,  0x12,  0xAC,  0x14,  0x68,  0x14,  0xA4,  0x1B,  0x23,  0x10,  0x60,  0xBE, 	/* 31C60 */
+	0x12,  0x20,  0x11,  0x20,  0x15,  0x3F,  0x26,  0x52,  0x09,  0x54,  0x10,  0x90,  0x3F,  0x18,  0x51,  0x28, 	/* 31C70 */
+	0x11,  0x24,  0x1F,  0x42,  0x00,  0x81,  0x12,  0x44,  0x12,  0x42,  0x22,  0x09,  0x41,  0x09,  0x00,  0xF8, 	/* 31C80 */
+	0x82,  0x00,  0x00,  0x7F,  0xFE,  0x01,  0x00,  0x0F,  0xE0,  0x08,  0x20,  0x0F,  0xE0,  0x08,  0x20,  0x7F, 	/* 31C90 */
+	0xFE,  0x45,  0x02,  0x54,  0xAA,  0x23,  0xE4,  0x44,  0x22,  0x0F,  0x40,  0x30,  0xC0,  0x07,  0x30,  0x78, 	/* 31CA0 */
+	0x0E,  0x87,  0x02,  0x44,  0x0C,  0x44,  0x79,  0xFF,  0x08,  0x44,  0x7F,  0x44,  0x08,  0x7C,  0x3E,  0x44, 	/* 31CB0 */
+	0x22,  0x44,  0x22,  0x44,  0x3E,  0x7C,  0x04,  0x80,  0x14,  0x44,  0x14,  0x42,  0x24,  0x09,  0x42,  0x09, 	/* 31CC0 */
+	0x01,  0xF8,  0x8A,  0x04,  0x48,  0x05,  0xFE,  0x08,  0x48,  0x0B,  0xFF,  0x12,  0xFE,  0x32,  0x92,  0x52, 	/* 31CD0 */
+	0xFE,  0x12,  0x92,  0x12,  0xFE,  0x14,  0x92,  0x18,  0x96,  0x02,  0x40,  0x12,  0x22,  0x12,  0x09,  0x21, 	/* 31CE0 */
+	0x09,  0x40,  0xF8,  0x8E,  0x09,  0x04,  0x08,  0x88,  0x0B,  0xFE,  0x0A,  0x22,  0x2E,  0x22,  0x2F,  0xFE, 	/* 31CF0 */
+	0x2A,  0x22,  0x2B,  0xFE,  0x48,  0x00,  0x09,  0xFC,  0x09,  0x04,  0x09,  0xFC,  0x09,  0x04,  0x09,  0x04, 	/* 31D00 */
+	0x09,  0xFC,  0x08,  0x00,  0x90,  0x08,  0x92,  0x08,  0x52,  0x08,  0x54,  0x09,  0xFF,  0x2C,  0x38,  0x2A, 	/* 31D10 */
+	0x54,  0x2B,  0x93,  0x28,  0x90,  0x48,  0x84,  0x08,  0xFF,  0x09,  0x54,  0x0B,  0x54,  0x0C,  0xBF,  0x08, 	/* 31D20 */
+	0x84,  0x09,  0x04,  0x0A,  0x04,  0x91,  0x00,  0x00,  0x23,  0xFC,  0x12,  0x20,  0x03,  0xF8,  0x02,  0x20, 	/* 31D30 */
+	0x0B,  0xF8,  0x0A,  0x20,  0x13,  0xFE,  0x24,  0x92,  0x44,  0x4A,  0x08,  0x8C,  0x02,  0x40,  0x12,  0x42, 	/* 31D40 */
+	0x22,  0x09,  0x42,  0x09,  0x01,  0xF8,  0x94,  0x08,  0x44,  0x08,  0x48,  0x08,  0xFF,  0x08,  0x90,  0x2D, 	/* 31D50 */
+	0x90,  0x2A,  0xFE,  0x28,  0x90,  0x28,  0xFE,  0x48,  0x90,  0x08,  0x90,  0x08,  0xFF,  0x08,  0x00,  0x08, 	/* 31D60 */
+	0x84,  0x08,  0xD2,  0x09,  0x29,  0x0A,  0x29,  0x96,  0x04,  0x14,  0x04,  0x12,  0x7F,  0x92,  0x15,  0x7F, 	/* 31D70 */
+	0x15,  0x10,  0x1E,  0xA8,  0x24,  0xA8,  0x4E,  0x24,  0x15,  0x42,  0x24,  0x81,  0x44,  0x80,  0x12,  0x44, 	/* 31D80 */
+	0x12,  0x42,  0x22,  0x09,  0x41,  0x09,  0x00,  0xF8,  0x99,  0x00,  0x80,  0x3F,  0xFE,  0x00,  0x80,  0x0F, 	/* 31D90 */
+	0xF8,  0x00,  0x00,  0x0F,  0xF8,  0x08,  0x08,  0x0F,  0xF8,  0x02,  0x20,  0x7F,  0xFF,  0x08,  0x08,  0x0F, 	/* 31DA0 */
+	0xF8,  0x12,  0x40,  0x12,  0x2A,  0x21,  0x09,  0x40,  0xF9,  0x9A,  0x08,  0x00,  0x0B,  0xDE,  0x0A,  0x52, 	/* 31DB0 */
+	0x0B,  0xDE,  0x28,  0x00,  0x2D,  0xFC,  0x2B,  0x24,  0x29,  0xFC,  0x49,  0x24,  0x09,  0x24,  0x09,  0xFC, 	/* 31DC0 */
+	0x08,  0x20,  0x0F,  0xFF,  0x08,  0x20,  0x08,  0x20,  0x08,  0x20,  0xA4,  0x08,  0x20,  0x0B,  0xFE,  0x08, 	/* 31DD0 */
+	0x20,  0x08,  0x88,  0x0F,  0xFF,  0x28,  0x88,  0x2C,  0x00,  0x2B,  0xFC,  0x49,  0x04,  0x09,  0xFC,  0x09, 	/* 31DE0 */
+	0x04,  0x09,  0xFC,  0x09,  0x04,  0x09,  0xFC,  0x09,  0x8C,  0x0E,  0x02,  0xA7,  0x08,  0x20,  0x08,  0x20, 	/* 31DF0 */
+	0x0B,  0xFE,  0x08,  0x88,  0x2F,  0xFF,  0x28,  0x00,  0x2D,  0xFC,  0x2B,  0x24,  0x49,  0xFC,  0x09,  0x24, 	/* 31E00 */
+	0x09,  0xFC,  0x08,  0x20,  0x09,  0xFC,  0x08,  0x20,  0x0F,  0xFF,  0x08,  0x00,  0xA9,  0x01,  0x08,  0x06, 	/* 31E10 */
+	0x10,  0x38,  0x7C,  0x08,  0x44,  0x7F,  0xFC,  0x08,  0x44,  0x08,  0x44,  0x3F,  0x7C,  0x21,  0x44,  0x21, 	/* 31E20 */
+	0x44,  0x3F,  0x7C,  0x02,  0x80,  0x12,  0x42,  0x12,  0x49,  0x22,  0x09,  0x41,  0xF8,  0xAB,  0x10,  0x00, 	/* 31E30 */
+	0x13,  0xDE,  0x12,  0x52,  0x13,  0xDE,  0x32,  0x52,  0x3B,  0xDE,  0x36,  0x02,  0x32,  0x22,  0x53,  0xFE, 	/* 31E40 */
+	0x12,  0x8A,  0x12,  0x52,  0x12,  0x22,  0x12,  0x52,  0x12,  0x8A,  0x12,  0x02,  0x12,  0x06,  0xAC,  0x08, 	/* 31E50 */
+	0x00,  0x09,  0xFC,  0x09,  0x04,  0x09,  0xFC,  0x09,  0x04,  0x2D,  0xFC,  0x2A,  0x20,  0x2B,  0xFF,  0x48, 	/* 31E60 */
+	0x00,  0x09,  0xFC,  0x09,  0x04,  0x09,  0xFC,  0x08,  0xA8,  0x09,  0x24,  0x0A,  0x22,  0x08,  0x60,  0xAE, 	/* 31E70 */
+	0x09,  0x00,  0x09,  0x00,  0x0B,  0xFF,  0x0D,  0x54,  0x29,  0x54,  0x2D,  0x54,  0x2B,  0xFF,  0x29,  0x54, 	/* 31E80 */
+	0x49,  0x54,  0x09,  0x54,  0x0F,  0xFF,  0x08,  0x00,  0x0A,  0x04,  0x0A,  0x92,  0x0C,  0x49,  0x08,  0x49, 	/* 31E90 */
+	0xB2,  0x01,  0x00,  0x7F,  0xFE,  0x41,  0x02,  0x5F,  0xFA,  0x01,  0x00,  0x0F,  0xF0,  0x01,  0x00,  0x7F, 	/* 31EA0 */
+	0xFE,  0x00,  0x00,  0x1F,  0xF8,  0x12,  0x48,  0x1F,  0xF8,  0x24,  0x88,  0x24,  0x44,  0x44,  0x12,  0x03, 	/* 31EB0 */
+	0xF2,  0xB6,  0x10,  0x40,  0x10,  0x40,  0x17,  0xFC,  0x11,  0x08,  0x30,  0x90,  0x37,  0xFF,  0x38,  0x00, 	/* 31EC0 */
+	0x55,  0xFC,  0x51,  0x04,  0x11,  0xFC,  0x11,  0x04,  0x11,  0xFC,  0x12,  0xA0,  0x12,  0x92,  0x14,  0x89, 	/* 31ED0 */
+	0x10,  0x78,  0xBA,  0x08,  0x20,  0x08,  0x78,  0x08,  0x90,  0x0B,  0xFF,  0x29,  0x2A,  0x2D,  0x46,  0x2B, 	/* 31EE0 */
+	0xBC,  0x29,  0x00,  0x49,  0xFF,  0x09,  0x00,  0x09,  0x3C,  0x09,  0x00,  0x0A,  0x7E,  0x0A,  0x42,  0x0C, 	/* 31EF0 */
+	0x7E,  0x08,  0x00,  0xBE,  0x08,  0x14,  0x08,  0x12,  0x09,  0xFF,  0x09,  0x10,  0x29,  0xF2,  0x2D,  0x0A, 	/* 31F00 */
+	0x2B,  0xEC,  0x29,  0xA4,  0x4A,  0xED,  0x0A,  0x93,  0x0C,  0x21,  0x09,  0x50,  0x09,  0x52,  0x0A,  0x45, 	/* 31F10 */
+	0x0C,  0x45,  0x08,  0x3C,  0x83,  0x12,  0x10,  0x7F,  0x90,  0x12,  0x10,  0x3F,  0x7E,  0x25,  0x12,  0x3F, 	/* 31F20 */
+	0x12,  0x04,  0x12,  0x3F,  0x12,  0x04,  0x22,  0x07,  0x22,  0x78,  0x42,  0x04,  0x8C,  0x14,  0x40,  0x14, 	/* 31F30 */
+	0x4A,  0x22,  0x09,  0x41,  0xF9,  0x86,  0x08,  0x00,  0x08,  0xF8,  0x08,  0x88,  0x08,  0x88,  0x0C,  0xF8, 	/* 31F40 */
+	0x2B,  0xDE,  0x2A,  0x52,  0x2A,  0x52,  0x4B,  0xDE,  0x08,  0x20,  0x0B,  0xFF,  0x08,  0x70,  0x08,  0xA8, 	/* 31F50 */
+	0x09,  0x24,  0x0A,  0x23,  0x08,  0x20,  0x87,  0x04,  0x00,  0x39,  0x7C,  0x26,  0x44,  0x1C,  0x7C,  0x76, 	/* 31F60 */
+	0x44,  0x09,  0x7E,  0x33,  0x52,  0x05,  0x54,  0x19,  0x48,  0x62,  0x74,  0x0C,  0xC3,  0x12,  0x84,  0x12, 	/* 31F70 */
+	0x42,  0x22,  0x09,  0x41,  0x09,  0x00,  0xF8,  0x88,  0x10,  0x80,  0x10,  0xFF,  0x11,  0x29,  0x12,  0x49, 	/* 31F80 */
+	0x37,  0xE9,  0x3A,  0xB3,  0x36,  0xA4,  0x33,  0xE4,  0x52,  0xB4,  0x12,  0xBF,  0x13,  0xE4,  0x12,  0x24, 	/* 31F90 */
+	0x12,  0x3F,  0x12,  0x24,  0x12,  0x24,  0x14,  0x64,  0x89,  0x00,  0x80,  0x00,  0x80,  0x1F,  0xFF,  0x12, 	/* 31FA0 */
+	0x48,  0x12,  0xFE,  0x15,  0x90,  0x16,  0xFC,  0x1C,  0x90,  0x14,  0xFC,  0x14,  0x90,  0x14,  0xFF,  0x15, 	/* 31FB0 */
+	0x40,  0x25,  0x22,  0x29,  0x29,  0x51,  0x09,  0x00,  0xF8,  0x8A,  0x08,  0x20,  0x08,  0x40,  0x09,  0xFE, 	/* 31FC0 */
+	0x09,  0x1A,  0x29,  0x62,  0x2D,  0xAA,  0x2B,  0xFE,  0x29,  0x6A,  0x49,  0xA6,  0x09,  0x22,  0x08,  0x20, 	/* 31FD0 */
+	0x0B,  0xFF,  0x08,  0x20,  0x08,  0x50,  0x09,  0x8C,  0x0E,  0x03,  0x8B,  0x10,  0x04,  0x13,  0xE4,  0x7D, 	/* 31FE0 */
+	0x5F,  0x10,  0x84,  0x13,  0xE4,  0x38,  0xAE,  0x35,  0xCE,  0x52,  0x95,  0x54,  0xA4,  0x11,  0x84,  0x00, 	/* 31FF0 */
+	0x80,  0x12,  0x44,  0x12,  0x42,  0x22,  0x09,  0x42,  0x09,  0x01,  0xF8,  0x8C,  0x08,  0x00,  0x09,  0xFE, 	/* 32000 */
+	0x09,  0x52,  0x09,  0xFE,  0x28,  0x20,  0x2D,  0xFE,  0x2A,  0x20,  0x2B,  0xFF,  0x48,  0x84,  0x08,  0x48, 	/* 32010 */
+	0x09,  0xFE,  0x08,  0x20,  0x09,  0xFE,  0x08,  0x20,  0x08,  0x20,  0x08,  0x20,  0x8D,  0x08,  0x10,  0x0B, 	/* 32020 */
+	0xFF,  0x08,  0x82,  0x08,  0xBA,  0x2C,  0xAA,  0x2A,  0xBA,  0x2A,  0x82,  0x28,  0xFE,  0x48,  0x04,  0x09, 	/* 32030 */
+	0xF8,  0x08,  0x10,  0x0B,  0xFF,  0x08,  0x38,  0x08,  0xD4,  0x0B,  0x13,  0x08,  0x10,  0x90,  0x08,  0x20, 	/* 32040 */
+	0x08,  0x20,  0x0B,  0xFF,  0x08,  0x20,  0x29,  0xFC,  0x2D,  0x54,  0x2D,  0x54,  0x2B,  0xFC,  0x48,  0x20, 	/* 32050 */
+	0x0B,  0xFF,  0x08,  0x44,  0x08,  0xA4,  0x09,  0x98,  0x0A,  0x88,  0x08,  0xE4,  0x09,  0x83,  0xA3,  0x20, 	/* 32060 */
+	0x88,  0x17,  0xFF,  0x10,  0x88,  0x00,  0xF8,  0x40,  0x20,  0x23,  0xFE,  0x0A,  0xAA,  0x0A,  0xAA,  0x12, 	/* 32070 */
+	0xEE,  0x23,  0x32,  0x42,  0x26,  0x12,  0x40,  0x12,  0x22,  0x22,  0x09,  0x41,  0x09,  0x00,  0xF8,  0xA6, 	/* 32080 */
+	0x10,  0x00,  0x13,  0xFE,  0x10,  0x20,  0x13,  0xFF,  0x3A,  0x21,  0x37,  0xAD,  0x32,  0x21,  0x31,  0xAC, 	/* 32090 */
+	0x50,  0x00,  0x17,  0xFF,  0x10,  0x40,  0x13,  0xFE,  0x12,  0x52,  0x12,  0x52,  0x12,  0x52,  0x12,  0x06, 	/* 320A0 */
+	0xB2,  0x11,  0x10,  0x15,  0x50,  0x25,  0x5F,  0x4F,  0xE4,  0x08,  0x24,  0x17,  0xD4,  0x31,  0x0C,  0x57, 	/* 320B0 */
+	0xC8,  0x11,  0x14,  0x17,  0xE2,  0x12,  0x41,  0x15,  0x08,  0x14,  0x84,  0x24,  0x92,  0x44,  0x12,  0x03, 	/* 320C0 */
+	0xF0,  0xB4,  0x10,  0x88,  0x10,  0x8C,  0x13,  0xEA,  0x10,  0x8A,  0x38,  0x88,  0x37,  0xFF,  0x31,  0x48, 	/* 320D0 */
+	0x37,  0x6A,  0x51,  0x4A,  0x17,  0x6A,  0x11,  0x44,  0x17,  0x6C,  0x11,  0x4D,  0x11,  0xF5,  0x17,  0x23, 	/* 320E0 */
+	0x10,  0x41,  0xB6,  0x11,  0x00,  0x11,  0x3E,  0x11,  0x0A,  0x17,  0xEA,  0x39,  0x12,  0x37,  0xE4,  0x35, 	/* 320F0 */
+	0x7E,  0x55,  0x62,  0x57,  0xFE,  0x11,  0x22,  0x13,  0xBE,  0x13,  0x62,  0x15,  0x3E,  0x19,  0x14,  0x11, 	/* 32100 */
+	0x22,  0x11,  0xC1,  0xB7,  0x08,  0x20,  0x0B,  0xFF,  0x08,  0x00,  0x09,  0xFE,  0x29,  0x52,  0x2D,  0xFE, 	/* 32110 */
+	0x2A,  0x20,  0x2B,  0xAE,  0x48,  0x20,  0x0B,  0xAE,  0x08,  0x52,  0x09,  0x94,  0x0E,  0x88,  0x08,  0x84, 	/* 32120 */
+	0x08,  0xE2,  0x0B,  0x01,  0xB8,  0x00,  0x06,  0x5E,  0x78,  0x52,  0x10,  0x5E,  0x14,  0x52,  0x68,  0x5E, 	/* 32130 */
+	0x14,  0x52,  0xFE,  0x7F,  0x91,  0x0C,  0x54,  0x2A,  0x52,  0x2A,  0x92,  0x48,  0x40,  0x12,  0x42,  0x12, 	/* 32140 */
+	0x01,  0x22,  0x09,  0x41,  0xF8,  0xBA,  0x12,  0x48,  0x12,  0x4C,  0x13,  0xAA,  0x14,  0x9A,  0x38,  0x08, 	/* 32150 */
+	0x37,  0xFF,  0x31,  0x48,  0x37,  0x6A,  0x51,  0x4A,  0x17,  0x6A,  0x11,  0x44,  0x17,  0x6C,  0x11,  0x4D, 	/* 32160 */
+	0x11,  0xF5,  0x17,  0x23,  0x10,  0x41,  0xBC,  0x08,  0x00,  0x0B,  0xDE,  0x0A,  0x52,  0x0B,  0xDE,  0x2E, 	/* 32170 */
+	0x52,  0x2B,  0xDE,  0x2A,  0x52,  0x2B,  0xDE,  0x48,  0x90,  0x09,  0xFE,  0x0B,  0x20,  0x0D,  0xFC,  0x09, 	/* 32180 */
+	0xFC,  0x09,  0x20,  0x09,  0xFF,  0x08,  0x00,  0xBD,  0x08,  0x88,  0x0B,  0xFF,  0x08,  0x88,  0x0B,  0xDE, 	/* 32190 */
+	0x2A,  0x52,  0x2B,  0xDE,  0x2C,  0x48,  0x2A,  0x90,  0x49,  0xFE,  0x0B,  0x10,  0x09,  0xFC,  0x09,  0x10, 	/* 321A0 */
+	0x09,  0xFC,  0x09,  0x10,  0x09,  0xFF,  0x08,  0x00,  0xBE,  0x08,  0x00,  0x0B,  0xFE,  0x08,  0x88,  0x08, 	/* 321B0 */
+	0xF8,  0x28,  0x88,  0x2C,  0xFE,  0x2B,  0x88,  0x28,  0x08,  0x4F,  0xFF,  0x0A,  0x52,  0x0B,  0xDE,  0x0A, 	/* 321C0 */
+	0x52,  0x0B,  0xDE,  0x0A,  0x53,  0x0F,  0xFE,  0x08,  0x42,  0xBF,  0x08,  0x10,  0x7F,  0x10,  0x08,  0x9F, 	/* 321D0 */
+	0x3E,  0x69,  0x00,  0x0A,  0x7F,  0x48,  0x41,  0x94,  0x3E,  0x22,  0x00,  0xC1,  0x3E,  0x10,  0x22,  0x08, 	/* 321E0 */
+	0x3E,  0xAA,  0x22,  0xA1,  0x15,  0x25,  0x1E,  0x24,  0x60,  0x1C,  0x80,  0x13,  0xC4,  0x10,  0x04,  0x6B, 	/* 321F0 */
+	0xFA,  0x10,  0x04,  0x2B,  0xCA,  0x7C,  0x3F,  0x17,  0xC5,  0x30,  0x14,  0x3B,  0xD6,  0x56,  0x65,  0x13, 	/* 32200 */
+	0xC4,  0x02,  0x40,  0x12,  0x22,  0x12,  0x09,  0x21,  0x09,  0x40,  0xF8,  0x88,  0x01,  0x10,  0x01,  0x08, 	/* 32210 */
+	0x01,  0x08,  0x01,  0x00,  0x7F,  0xFF,  0x01,  0x00,  0x01,  0x08,  0x01,  0x08,  0x00,  0x90,  0x00,  0xA0, 	/* 32220 */
+	0x00,  0x40,  0x00,  0xC0,  0x01,  0x22,  0x06,  0x12,  0x78,  0x0A,  0x00,  0x06,  0x89,  0x00,  0x48,  0x00, 	/* 32230 */
+	0x44,  0x00,  0x44,  0x00,  0x40,  0x1F,  0xFF,  0x10,  0x40,  0x10,  0x44,  0x10,  0x44,  0x10,  0x28,  0x10, 	/* 32240 */
+	0x28,  0x10,  0x30,  0x13,  0x10,  0x1C,  0x29,  0x70,  0x45,  0x01,  0x83,  0x0E,  0x01,  0x8A,  0x00,  0x48, 	/* 32250 */
+	0x00,  0x44,  0x00,  0x44,  0x1F,  0xFF,  0x10,  0x40,  0x10,  0x40,  0x10,  0x42,  0x10,  0x42,  0x10,  0x24, 	/* 32260 */
+	0x10,  0x24,  0x10,  0x38,  0x10,  0x10,  0x10,  0x6A,  0x21,  0x8A,  0x26,  0x06,  0x40,  0x02,  0x8C,  0x00, 	/* 32270 */
+	0x24,  0x00,  0x22,  0x00,  0x22,  0x00,  0x20,  0x1F,  0xFF,  0x10,  0x20,  0x10,  0x20,  0x10,  0x24,  0x17, 	/* 32280 */
+	0xA4,  0x10,  0x18,  0x10,  0x10,  0x10,  0x28,  0x10,  0x49,  0x21,  0x85,  0x26,  0x03,  0x40,  0x01,  0x8D, 	/* 32290 */
+	0x00,  0x24,  0x00,  0x22,  0x00,  0x22,  0x00,  0x20,  0x1F,  0xFF,  0x10,  0x20,  0x10,  0x20,  0x14,  0x24, 	/* 322A0 */
+	0x12,  0x24,  0x11,  0x18,  0x11,  0x10,  0x10,  0x28,  0x10,  0x49,  0x21,  0x85,  0x26,  0x03,  0x40,  0x01, 	/* 322B0 */
+	0x8E,  0x00,  0x48,  0x00,  0x44,  0x00,  0x44,  0x7F,  0xFF,  0x00,  0x40,  0x04,  0x44,  0x04,  0x44,  0x04, 	/* 322C0 */
+	0x24,  0x7F,  0xA8,  0x04,  0x28,  0x04,  0x10,  0x08,  0x10,  0x08,  0x2A,  0x10,  0x4A,  0x21,  0x86,  0x06, 	/* 322D0 */
+	0x02,  0x90,  0x00,  0x24,  0x00,  0x22,  0x00,  0x22,  0x1F,  0xFF,  0x10,  0x20,  0x10,  0x20,  0x10,  0x24, 	/* 322E0 */
+	0x1F,  0x24,  0x11,  0x14,  0x11,  0x14,  0x11,  0x18,  0x11,  0x18,  0x11,  0x29,  0x26,  0x45,  0x20,  0x83, 	/* 322F0 */
+	0x40,  0x01,  0x91,  0x01,  0x40,  0x02,  0x50,  0x0C,  0x48,  0x34,  0x44,  0x04,  0x40,  0x04,  0x40,  0x7F, 	/* 32300 */
+	0xFF,  0x04,  0x24,  0x04,  0x24,  0x07,  0x28,  0x0C,  0x18,  0x74,  0x10,  0x04,  0x29,  0x04,  0x45,  0x05, 	/* 32310 */
+	0x83,  0x0C,  0x01,  0x92,  0x00,  0x48,  0x00,  0x44,  0x00,  0x44,  0x7F,  0xFF,  0x00,  0x40,  0x09,  0x44, 	/* 32320 */
+	0x09,  0x44,  0x09,  0x28,  0x7F,  0xE8,  0x09,  0x30,  0x09,  0x10,  0x11,  0x30,  0x11,  0x2A,  0x21,  0x4A, 	/* 32330 */
+	0x40,  0x86,  0x01,  0x02,  0x94,  0x04,  0x80,  0x04,  0x40,  0x7F,  0xFE,  0x02,  0x10,  0x01,  0x20,  0x00, 	/* 32340 */
+	0xC2,  0x07,  0x32,  0x38,  0x0E,  0x04,  0x40,  0x04,  0x20,  0x7F,  0xFF,  0x02,  0x10,  0x01,  0x20,  0x00, 	/* 32350 */
+	0xC2,  0x07,  0x32,  0x38,  0x0E,  0x96,  0x00,  0x48,  0x00,  0x44,  0x00,  0x44,  0x7F,  0xFF,  0x00,  0x40, 	/* 32360 */
+	0x00,  0x44,  0x1F,  0x44,  0x11,  0x44,  0x11,  0x28,  0x11,  0x28,  0x1F,  0x28,  0x00,  0x92,  0x03,  0x32, 	/* 32370 */
+	0x0C,  0x4A,  0x71,  0x86,  0x06,  0x02,  0x9A,  0x00,  0x28,  0x00,  0x24,  0x00,  0x24,  0x1F,  0xFF,  0x11, 	/* 32380 */
+	0x20,  0x11,  0x22,  0x11,  0xE2,  0x11,  0x12,  0x1F,  0xF4,  0x11,  0x14,  0x15,  0x88,  0x15,  0x48,  0x19, 	/* 32390 */
+	0x5A,  0x21,  0x26,  0x23,  0x46,  0x40,  0x82,  0x9B,  0x00,  0x00,  0x7F,  0xFE,  0x01,  0x00,  0x0F,  0xF0, 	/* 323A0 */
+	0x08,  0x10,  0x0F,  0xF0,  0x08,  0x10,  0x0F,  0xF0,  0x08,  0x10,  0x0F,  0xF0,  0x01,  0x04,  0x7F,  0xFF, 	/* 323B0 */
+	0x00,  0x90,  0x00,  0x62,  0x03,  0x9A,  0x3C,  0x06,  0x9D,  0x00,  0x24,  0x3E,  0x22,  0x22,  0x22,  0x22, 	/* 323C0 */
+	0x20,  0x3E,  0x3F,  0x23,  0xE0,  0x22,  0x22,  0x22,  0x22,  0x3E,  0x12,  0x22,  0x14,  0x22,  0x14,  0x3E, 	/* 323D0 */
+	0x08,  0x14,  0x19,  0x12,  0x25,  0x22,  0x43,  0x40,  0x81,  0x9E,  0x00,  0x00,  0x7F,  0xFE,  0x01,  0x00, 	/* 323E0 */
+	0x0F,  0xF0,  0x08,  0x10,  0x0F,  0xF0,  0x08,  0x10,  0x7F,  0xFE,  0x42,  0x22,  0x42,  0x12,  0x3F,  0xFC, 	/* 323F0 */
+	0x01,  0x10,  0x00,  0xA0,  0x00,  0xC2,  0x03,  0x32,  0x3C,  0x0E,  0x9F,  0x04,  0x20,  0x04,  0x28,  0x7F, 	/* 32400 */
+	0xA4,  0x04,  0x20,  0x04,  0x27,  0x3F,  0xF8,  0x21,  0x24,  0x3F,  0x24,  0x21,  0x24,  0x21,  0x28,  0x3F, 	/* 32410 */
+	0x18,  0x04,  0x12,  0x7F,  0xAA,  0x04,  0x2A,  0x04,  0x46,  0x04,  0x82,  0xA1,  0x11,  0x14,  0x11,  0x12, 	/* 32420 */
+	0x7F,  0xD2,  0x11,  0x10,  0x1F,  0x17,  0x11,  0xF8,  0x1F,  0x12,  0x11,  0x12,  0x11,  0x12,  0x7F,  0xD4, 	/* 32430 */
+	0x2A,  0x0C,  0x2A,  0x08,  0x33,  0x95,  0x20,  0x25,  0x3F,  0xC3,  0x00,  0x81,  0xA6,  0x08,  0x90,  0x24, 	/* 32440 */
+	0x94,  0x15,  0x12,  0x12,  0x12,  0x3F,  0x9F,  0x24,  0xF0,  0x24,  0x92,  0x3F,  0x92,  0x24,  0x92,  0x3F, 	/* 32450 */
+	0x94,  0x04,  0x0C,  0x04,  0x08,  0x7F,  0xCD,  0x04,  0x15,  0x04,  0x23,  0x04,  0x41,  0xAA,  0x02,  0x10, 	/* 32460 */
+	0x02,  0x14,  0x3F,  0xD2,  0x02,  0x12,  0x02,  0x10,  0x7F,  0xFF,  0x08,  0x90,  0x09,  0x12,  0x1F,  0xD2, 	/* 32470 */
+	0x32,  0x14,  0x5F,  0xCC,  0x12,  0x08,  0x1F,  0xCD,  0x12,  0x15,  0x1F,  0xE3,  0x00,  0x41,  0xAE,  0x00, 	/* 32480 */
+	0x14,  0x7F,  0x92,  0x2A,  0x92,  0x4C,  0x90,  0x19,  0x9F,  0x2A,  0xF0,  0x4C,  0x92,  0x0C,  0x12,  0x12, 	/* 32490 */
+	0x12,  0x25,  0x8C,  0x5A,  0x0C,  0x04,  0x08,  0x39,  0x15,  0x02,  0x25,  0x0C,  0x43,  0x70,  0x81,  0xAF, 	/* 324A0 */
+	0x08,  0x18,  0x0F,  0x14,  0x08,  0x14,  0x3F,  0xD3,  0x28,  0x9C,  0x2E,  0x72,  0x38,  0x92,  0x27,  0x92, 	/* 324B0 */
+	0x2A,  0x14,  0x2A,  0x94,  0x2B,  0x08,  0x3A,  0x08,  0x2A,  0x95,  0x2B,  0x25,  0x4C,  0x43,  0x30,  0x01, 	/* 324C0 */
+	0xB0,  0x00,  0x14,  0x7B,  0xD2,  0x4A,  0x52,  0x7B,  0xD0,  0x00,  0x1F,  0x3F,  0xF0,  0x24,  0x92,  0x3F, 	/* 324D0 */
+	0x92,  0x24,  0x94,  0x24,  0x94,  0x3F,  0x88,  0x04,  0x08,  0x7F,  0x95,  0x04,  0x23,  0x04,  0x43,  0x04, 	/* 324E0 */
+	0x81,  0xB2,  0x02,  0x14,  0x03,  0xD2,  0x02,  0x12,  0x1F,  0xF0,  0x12,  0x3F,  0x1F,  0xD0,  0x12,  0x12, 	/* 324F0 */
+	0x11,  0xD2,  0x1F,  0xD2,  0x10,  0x14,  0x17,  0xCC,  0x14,  0x48,  0x27,  0xCD,  0x22,  0x95,  0x41,  0xE3, 	/* 32500 */
+	0x0E,  0x41,  0xB3,  0x00,  0x14,  0x7B,  0xD2,  0x29,  0x52,  0x5A,  0xD0,  0x29,  0x57,  0x4A,  0x78,  0x11, 	/* 32510 */
+	0x12,  0x12,  0x12,  0x3F,  0x94,  0x64,  0x14,  0x3F,  0x88,  0x24,  0x09,  0x3F,  0x95,  0x24,  0x25,  0x3F, 	/* 32520 */
+	0xC3,  0x00,  0x81,  0xB4,  0x02,  0x18,  0x1F,  0xD4,  0x02,  0x14,  0x7F,  0xFF,  0x00,  0x10,  0x1F,  0xD2, 	/* 32530 */
+	0x12,  0x52,  0x1F,  0xD2,  0x12,  0x54,  0x1F,  0xCC,  0x09,  0x08,  0x3F,  0xE8,  0x09,  0x15,  0x7F,  0xE5, 	/* 32540 */
+	0x09,  0x43,  0x30,  0x81,  0xB8,  0x00,  0x00,  0x7F,  0xFE,  0x00,  0x00,  0x00,  0x00,  0x1F,  0xFC,  0x10, 	/* 32550 */
+	0x04,  0x10,  0x04,  0x10,  0x04,  0x1F,  0xFC,  0x10,  0x00,  0x10,  0x00,  0x10,  0x00,  0x10,  0x00,  0x20, 	/* 32560 */
+	0x00,  0x20,  0x00,  0x40,  0x00,  0xBB,  0x00,  0x00,  0x3F,  0xFF,  0x00,  0x00,  0x1F,  0xFC,  0x10,  0x04, 	/* 32570 */
+	0x10,  0x04,  0x1F,  0xFC,  0x10,  0x40,  0x10,  0x40,  0x1F,  0xFF,  0x10,  0x40,  0x10,  0xC0,  0x20,  0xA0, 	/* 32580 */
+	0x21,  0x10,  0x46,  0x08,  0x18,  0x06,  0xBF,  0x00,  0x00,  0x7F,  0xFE,  0x00,  0x00,  0x1F,  0xF8,  0x10, 	/* 32590 */
+	0x08,  0x10,  0x08,  0x1F,  0xF8,  0x10,  0x80,  0x10,  0x80,  0x1F,  0xFE,  0x11,  0x00,  0x11,  0xF8,  0x21, 	/* 325A0 */
+	0x08,  0x22,  0x08,  0x44,  0x08,  0x18,  0x30,  0x80,  0x00,  0x02,  0x3F,  0x8C,  0x00,  0x70,  0x00,  0x40, 	/* 325B0 */
+	0x1F,  0x40,  0x11,  0x7F,  0x11,  0x44,  0x11,  0x44,  0x1F,  0x44,  0x10,  0x44,  0x10,  0x44,  0x10,  0x84, 	/* 325C0 */
+	0x10,  0x84,  0x21,  0x04,  0x22,  0x04,  0x40,  0x04,  0x81,  0x00,  0x00,  0x7F,  0xFF,  0x00,  0x00,  0x1F, 	/* 325D0 */
+	0xFC,  0x10,  0x04,  0x10,  0x04,  0x1F,  0xFC,  0x10,  0x00,  0x1F,  0xFC,  0x19,  0x24,  0x19,  0x24,  0x1F, 	/* 325E0 */
+	0xFC,  0x29,  0x24,  0x29,  0x24,  0x49,  0x24,  0x09,  0x2C,  0x87,  0x00,  0x00,  0x7F,  0xFF,  0x00,  0x00, 	/* 325F0 */
+	0x1F,  0xFC,  0x10,  0x04,  0x10,  0x04,  0x1F,  0xFC,  0x10,  0x00,  0x1F,  0xBE,  0x10,  0x82,  0x18,  0xA2, 	/* 32600 */
+	0x14,  0x92,  0x22,  0x86,  0x2C,  0x9A,  0x50,  0xA2,  0x01,  0x86,  0x88,  0x00,  0x00,  0x3F,  0xFF,  0x00, 	/* 32610 */
+	0x00,  0x1F,  0xFE,  0x10,  0x02,  0x1F,  0xFE,  0x10,  0x00,  0x13,  0xF8,  0x12,  0x08,  0x13,  0xF8,  0x17, 	/* 32620 */
+	0xFC,  0x14,  0x44,  0x27,  0xFC,  0x24,  0x01,  0x44,  0x01,  0x03,  0xFF,  0x89,  0x00,  0x00,  0x3F,  0xFF, 	/* 32630 */
+	0x00,  0x00,  0x1F,  0xFE,  0x10,  0x02,  0x1F,  0xFE,  0x10,  0x90,  0x10,  0x90,  0x17,  0x9E,  0x10,  0x90, 	/* 32640 */
+	0x17,  0x9E,  0x10,  0x90,  0x23,  0x90,  0x2D,  0x1F,  0x41,  0x10,  0x02,  0x10,  0x8B,  0x00,  0x08,  0x00, 	/* 32650 */
+	0x30,  0x0F,  0xC0,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x3F,  0xFE,  0x00,  0x80,  0x00,  0x80,  0x00, 	/* 32660 */
+	0x80,  0x7F,  0xFF,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x01,  0x80,  0x8D,  0x00,  0x40, 	/* 32670 */
+	0x00,  0x40,  0x00,  0x40,  0x00,  0x40,  0x7F,  0xFE,  0x00,  0x40,  0x00,  0x48,  0x00,  0x50,  0x00,  0x60, 	/* 32680 */
+	0x00,  0xC0,  0x01,  0x40,  0x06,  0x40,  0x18,  0x40,  0x60,  0x40,  0x00,  0x40,  0x00,  0xC0,  0x8E,  0x08, 	/* 32690 */
+	0x40,  0x08,  0x40,  0x08,  0x40,  0x08,  0x40,  0x7F,  0x40,  0x08,  0x40,  0x08,  0x40,  0x08,  0x40,  0x0B, 	/* 326A0 */
+	0x40,  0x1C,  0x40,  0x68,  0x40,  0x08,  0x41,  0x08,  0x41,  0x08,  0x21,  0x08,  0x1F,  0x18,  0x00,  0x93, 	/* 326B0 */
+	0x08,  0x00,  0x08,  0x00,  0x09,  0xFF,  0x08,  0x08,  0x7E,  0x08,  0x08,  0x08,  0x08,  0x08,  0x08,  0x08, 	/* 326C0 */
+	0x08,  0x08,  0x0E,  0x08,  0x78,  0x08,  0x08,  0x08,  0x08,  0x08,  0x08,  0x08,  0x08,  0x08,  0x18,  0x18, 	/* 326D0 */
+	0x95,  0x08,  0x20,  0x08,  0x20,  0x08,  0x20,  0x08,  0x20,  0x7E,  0x20,  0x08,  0x20,  0x08,  0x40,  0x08, 	/* 326E0 */
+	0x40,  0x0E,  0x50,  0x78,  0x48,  0x08,  0x88,  0x08,  0x84,  0x08,  0x84,  0x09,  0x3E,  0x0F,  0xC2,  0x18, 	/* 326F0 */
+	0x02,  0x98,  0x08,  0x04,  0x08,  0x18,  0x09,  0xE0,  0x08,  0x40,  0x7E,  0x40,  0x08,  0x40,  0x08,  0x4F, 	/* 32700 */
+	0x0B,  0xF0,  0x0E,  0x40,  0x78,  0x40,  0x08,  0x40,  0x08,  0x40,  0x08,  0x40,  0x08,  0x42,  0x08,  0x22, 	/* 32710 */
+	0x18,  0x1E,  0x9B,  0x08,  0x00,  0x08,  0x00,  0x09,  0xFE,  0x08,  0x20,  0x7E,  0x20,  0x08,  0x20,  0x08, 	/* 32720 */
+	0x20,  0x08,  0x20,  0x0E,  0x20,  0x18,  0x20,  0x68,  0x20,  0x08,  0x20,  0x08,  0x20,  0x0B,  0xFF,  0x08, 	/* 32730 */
+	0x00,  0x18,  0x00,  0x9E,  0x08,  0x00,  0x08,  0xFE,  0x08,  0x10,  0x08,  0x10,  0x7E,  0x10,  0x08,  0x10, 	/* 32740 */
+	0x08,  0x10,  0x09,  0xFF,  0x0E,  0x10,  0x18,  0x10,  0x68,  0x10,  0x08,  0x10,  0x08,  0x10,  0x08,  0x10, 	/* 32750 */
+	0x08,  0x10,  0x18,  0x10,  0xA0,  0x10,  0x00,  0x13,  0xFC,  0x10,  0x04,  0x11,  0x04,  0x7D,  0x44,  0x11, 	/* 32760 */
+	0x24,  0x10,  0xA8,  0x10,  0x88,  0x1C,  0x48,  0x70,  0x50,  0x10,  0x30,  0x10,  0x30,  0x10,  0x48,  0x10, 	/* 32770 */
+	0x84,  0x13,  0x02,  0x3C,  0x01,  0xA3,  0x10,  0x00,  0x11,  0xFE,  0x11,  0x02,  0x11,  0x02,  0x7D,  0x02, 	/* 32780 */
+	0x11,  0x02,  0x11,  0x02,  0x11,  0x02,  0x11,  0x02,  0x1D,  0x02,  0x71,  0x02,  0x11,  0x02,  0x11,  0x02, 	/* 32790 */
+	0x11,  0x02,  0x11,  0xFE,  0x30,  0x00,  0xA8,  0x10,  0x00,  0x13,  0xFC,  0x10,  0x44,  0x10,  0x44,  0x7C, 	/* 327A0 */
+	0x44,  0x10,  0x44,  0x11,  0x44,  0x10,  0xC4,  0x1C,  0x44,  0x70,  0x64,  0x10,  0x5C,  0x10,  0x87,  0x10, 	/* 327B0 */
+	0x84,  0x11,  0x04,  0x12,  0x08,  0x34,  0x30,  0xAE,  0x10,  0x78,  0x10,  0x08,  0x10,  0x48,  0x10,  0x44, 	/* 327C0 */
+	0x7C,  0x84,  0x10,  0x82,  0x11,  0x01,  0x13,  0xFC,  0x1C,  0x44,  0x70,  0x44,  0x10,  0x44,  0x10,  0x44, 	/* 327D0 */
+	0x10,  0x84,  0x10,  0x84,  0x11,  0x04,  0x32,  0x18,  0xB1,  0x10,  0x00,  0x13,  0xF8,  0x10,  0x88,  0x10, 	/* 327E0 */
+	0x88,  0x7E,  0x90,  0x10,  0x90,  0x10,  0xBC,  0x10,  0xC4,  0x11,  0x44,  0x1D,  0x24,  0x71,  0x28,  0x11, 	/* 327F0 */
+	0x10,  0x12,  0x18,  0x12,  0x24,  0x14,  0xC2,  0x3B,  0x01,  0xB6,  0x10,  0x20,  0x10,  0x20,  0x10,  0x20, 	/* 32800 */
+	0x11,  0xFC,  0x7C,  0x20,  0x10,  0x20,  0x10,  0x20,  0x10,  0x20,  0x1B,  0xFF,  0x70,  0x50,  0x10,  0x50, 	/* 32810 */
+	0x10,  0x88,  0x10,  0x88,  0x11,  0x04,  0x12,  0x02,  0x34,  0x01,  0xB9,  0x12,  0x20,  0x12,  0x20,  0x12, 	/* 32820 */
+	0x20,  0x12,  0x20,  0x7E,  0x24,  0x12,  0x24,  0x13,  0xE8,  0x12,  0x30,  0x1E,  0x20,  0x72,  0x20,  0x12, 	/* 32830 */
+	0x20,  0x12,  0x20,  0x12,  0x21,  0x12,  0xE1,  0x13,  0x1F,  0x3C,  0x00,  0xBC,  0x10,  0x00,  0x11,  0xFF, 	/* 32840 */
+	0x11,  0x00,  0x11,  0x00,  0x7D,  0x7C,  0x11,  0x44,  0x11,  0x44,  0x11,  0x44,  0x1D,  0x44,  0x71,  0x58, 	/* 32850 */
+	0x11,  0x40,  0x11,  0x42,  0x12,  0x42,  0x12,  0x42,  0x14,  0x22,  0x30,  0x1E,  0xBE,  0x10,  0x48,  0x10, 	/* 32860 */
+	0x44,  0x10,  0x44,  0x10,  0x40,  0x7F,  0xFF,  0x10,  0x40,  0x10,  0x44,  0x10,  0x44,  0x1C,  0x48,  0x70, 	/* 32870 */
+	0x28,  0x10,  0x30,  0x10,  0x22,  0x10,  0x52,  0x11,  0x8A,  0x16,  0x06,  0x30,  0x02,  0xBF,  0x00,  0x00, 	/* 32880 */
+	0x0F,  0xF0,  0x00,  0x20,  0x00,  0x40,  0x00,  0x92,  0x78,  0x92,  0x0F,  0xF4,  0x08,  0x88,  0x0F,  0xF8, 	/* 32890 */
+	0x08,  0x88,  0x10,  0x84,  0x1F,  0xFC,  0x20,  0x82,  0x40,  0x81,  0x00,  0x80,  0x01,  0x80,  0x80,  0x10, 	/* 328A0 */
+	0x20,  0x10,  0x20,  0x10,  0x20,  0x13,  0xFF,  0x7C,  0x20,  0x10,  0x20,  0x10,  0x20,  0x13,  0xFC,  0x10, 	/* 328B0 */
+	0x84,  0x1C,  0x88,  0x70,  0x48,  0x10,  0x30,  0x10,  0x30,  0x10,  0x48,  0x11,  0x84,  0x36,  0x03,  0x82, 	/* 328C0 */
+	0x10,  0x00,  0x13,  0xFE,  0x10,  0x20,  0x10,  0x20,  0x7C,  0x20,  0x10,  0x20,  0x10,  0x20,  0x11,  0xFC, 	/* 328D0 */
+	0x1C,  0x20,  0x70,  0x20,  0x10,  0x20,  0x10,  0x20,  0x10,  0x20,  0x10,  0x20,  0x17,  0xFF,  0x30,  0x00, 	/* 328E0 */
+	0x83,  0x08,  0x20,  0x08,  0x20,  0x0B,  0xFF,  0x08,  0x20,  0x7E,  0x20,  0x08,  0x20,  0x08,  0x30,  0x08, 	/* 328F0 */
+	0x28,  0x0E,  0x24,  0x78,  0x24,  0x08,  0x20,  0x08,  0x20,  0x08,  0x20,  0x08,  0x20,  0x08,  0x20,  0x18, 	/* 32900 */
+	0x20,  0x84,  0x10,  0x20,  0x10,  0x20,  0x10,  0x20,  0x11,  0x28,  0x7D,  0x24,  0x11,  0x24,  0x12,  0x22, 	/* 32910 */
+	0x14,  0x22,  0x10,  0x25,  0x1C,  0x64,  0x70,  0x08,  0x10,  0x08,  0x10,  0x10,  0x10,  0x20,  0x10,  0xC0, 	/* 32920 */
+	0x33,  0x00,  0x89,  0x10,  0x40,  0x10,  0x40,  0x10,  0x40,  0x13,  0xFC,  0x7C,  0x44,  0x10,  0x44,  0x10, 	/* 32930 */
+	0x44,  0x10,  0x44,  0x1F,  0xFF,  0x70,  0x40,  0x10,  0x60,  0x10,  0xA0,  0x10,  0x90,  0x11,  0x08,  0x12, 	/* 32940 */
+	0x04,  0x34,  0x02,  0x8A,  0x10,  0x00,  0x11,  0xFC,  0x11,  0x24,  0x11,  0x24,  0x7D,  0x24,  0x11,  0x24, 	/* 32950 */
+	0x11,  0x24,  0x11,  0xFC,  0x1D,  0x00,  0x71,  0x00,  0x11,  0x00,  0x11,  0x02,  0x11,  0x02,  0x10,  0x82, 	/* 32960 */
+	0x10,  0x7E,  0x30,  0x00,  0x91,  0x10,  0x40,  0x10,  0x80,  0x13,  0x3E,  0x12,  0x22,  0x7E,  0x22,  0x12, 	/* 32970 */
+	0x22,  0x12,  0x22,  0x12,  0x22,  0x1E,  0x22,  0x72,  0x22,  0x12,  0x62,  0x13,  0xA2,  0x16,  0x2C,  0x10, 	/* 32980 */
+	0x20,  0x10,  0x20,  0x30,  0x20,  0x92,  0x10,  0x00,  0x11,  0xFC,  0x10,  0x04,  0x10,  0xC8,  0x7C,  0x30, 	/* 32990 */
+	0x10,  0x10,  0x17,  0xFF,  0x10,  0x22,  0x1C,  0x24,  0x70,  0x28,  0x10,  0x20,  0x10,  0x20,  0x10,  0x20, 	/* 329A0 */
+	0x10,  0x20,  0x10,  0x20,  0x30,  0x60,  0x93,  0x10,  0x04,  0x10,  0x18,  0x11,  0xE8,  0x11,  0x08,  0x7D, 	/* 329B0 */
+	0x28,  0x11,  0x28,  0x11,  0x28,  0x11,  0x28,  0x11,  0x28,  0x1D,  0x28,  0x71,  0x28,  0x11,  0x28,  0x12, 	/* 329C0 */
+	0x24,  0x12,  0x24,  0x14,  0x22,  0x38,  0x01,  0x94,  0x10,  0x00,  0x17,  0xFF,  0x10,  0x20,  0x10,  0x20, 	/* 329D0 */
+	0x7C,  0x20,  0x10,  0x40,  0x10,  0x50,  0x10,  0xC8,  0x1C,  0xC4,  0x71,  0x42,  0x12,  0x42,  0x14,  0x40, 	/* 329E0 */
+	0x10,  0x40,  0x10,  0x40,  0x10,  0x40,  0x30,  0x40,  0x95,  0x10,  0x00,  0x10,  0xF8,  0x10,  0x88,  0x10, 	/* 329F0 */
+	0x88,  0x7C,  0x89,  0x11,  0x09,  0x11,  0x07,  0x12,  0x00,  0x1D,  0xF8,  0x70,  0x88,  0x10,  0x88,  0x10, 	/* 32A00 */
+	0x50,  0x10,  0x20,  0x10,  0x50,  0x10,  0x8C,  0x33,  0x03,  0x96,  0x08,  0x04,  0x08,  0x44,  0x08,  0x24, 	/* 32A10 */
+	0x08,  0x24,  0x7E,  0x04,  0x08,  0x04,  0x08,  0x84,  0x08,  0x44,  0x0E,  0x44,  0x18,  0x07,  0x68,  0x3C, 	/* 32A20 */
+	0x09,  0xC4,  0x08,  0x04,  0x08,  0x04,  0x08,  0x04,  0x18,  0x04,  0x97,  0x10,  0x20,  0x10,  0x20,  0x10, 	/* 32A30 */
+	0x20,  0x13,  0xFF,  0x7C,  0x00,  0x10,  0x00,  0x10,  0xF0,  0x10,  0x90,  0x1C,  0x90,  0x70,  0x90,  0x10, 	/* 32A40 */
+	0x90,  0x10,  0x90,  0x11,  0x10,  0x11,  0x12,  0x12,  0x12,  0x34,  0x0E,  0x98,  0x08,  0x04,  0x08,  0x18, 	/* 32A50 */
+	0x08,  0xE0,  0x08,  0x80,  0x7E,  0x80,  0x08,  0xFF,  0x08,  0x88,  0x08,  0x88,  0x0E,  0x88,  0x78,  0x88, 	/* 32A60 */
+	0x08,  0x88,  0x08,  0x88,  0x09,  0x08,  0x09,  0x08,  0x0A,  0x08,  0x18,  0x08,  0x9B,  0x12,  0x10,  0x12, 	/* 32A70 */
+	0x10,  0x12,  0x10,  0x12,  0x7E,  0x7F,  0x92,  0x12,  0x92,  0x12,  0x92,  0x12,  0x92,  0x1A,  0x92,  0x72, 	/* 32A80 */
+	0xA2,  0x12,  0xA2,  0x12,  0xC2,  0x14,  0x8C,  0x14,  0x81,  0x18,  0x41,  0x30,  0x3F,  0x9C,  0x10,  0x40, 	/* 32A90 */
+	0x10,  0x40,  0x10,  0x40,  0x13,  0xFF,  0x7C,  0x40,  0x10,  0x40,  0x10,  0xFC,  0x10,  0x84,  0x1C,  0xC4, 	/* 32AA0 */
+	0x70,  0xA8,  0x11,  0x28,  0x11,  0x10,  0x12,  0x30,  0x14,  0x48,  0x10,  0x84,  0x33,  0x02,  0x9E,  0x10, 	/* 32AB0 */
+	0x00,  0x10,  0xFE,  0x10,  0x82,  0x10,  0x82,  0x7E,  0x82,  0x10,  0x82,  0x10,  0xFE,  0x10,  0xA0,  0x10, 	/* 32AC0 */
+	0xA0,  0x1C,  0x90,  0x70,  0x90,  0x11,  0x08,  0x11,  0x08,  0x12,  0x04,  0x14,  0x02,  0x38,  0x01,  0xAB, 	/* 32AD0 */
+	0x10,  0x10,  0x10,  0x10,  0x10,  0x10,  0x11,  0xFF,  0x7D,  0x11,  0x11,  0x12,  0x11,  0x10,  0x11,  0xFC, 	/* 32AE0 */
+	0x1D,  0x44,  0x71,  0x44,  0x11,  0x28,  0x12,  0x28,  0x12,  0x10,  0x14,  0x28,  0x18,  0xC4,  0x33,  0x03, 	/* 32AF0 */
+	0xAC,  0x10,  0x40,  0x10,  0x40,  0x10,  0x40,  0x10,  0x50,  0x7C,  0x88,  0x10,  0x84,  0x11,  0x1C,  0x13, 	/* 32B00 */
+	0xE2,  0x1C,  0x02,  0x70,  0x00,  0x11,  0xFC,  0x11,  0x04,  0x11,  0x04,  0x11,  0x04,  0x11,  0xFC,  0x30, 	/* 32B10 */
+	0x00,  0xB1,  0x10,  0x80,  0x10,  0x80,  0x10,  0xFE,  0x10,  0x82,  0x7D,  0x02,  0x11,  0xF2,  0x11,  0x12, 	/* 32B20 */
+	0x12,  0x12,  0x1C,  0x12,  0x71,  0xF2,  0x11,  0x04,  0x11,  0x18,  0x11,  0x01,  0x11,  0x01,  0x10,  0x81, 	/* 32B30 */
+	0x30,  0x7F,  0xB5,  0x10,  0x04,  0x10,  0x18,  0x11,  0xF0,  0x11,  0x10,  0x7D,  0x10,  0x11,  0x10,  0x11, 	/* 32B40 */
+	0xFF,  0x11,  0x10,  0x1D,  0x10,  0x71,  0x10,  0x11,  0x08,  0x11,  0xCA,  0x17,  0x0A,  0x10,  0x06,  0x17, 	/* 32B50 */
+	0xF6,  0x30,  0x02,  0xB9,  0x10,  0x20,  0x10,  0x20,  0x10,  0x20,  0x17,  0xFF,  0x7C,  0x20,  0x10,  0x20, 	/* 32B60 */
+	0x10,  0x20,  0x13,  0xFE,  0x1C,  0x70,  0x70,  0x70,  0x10,  0xA8,  0x10,  0xA8,  0x11,  0x24,  0x12,  0x22, 	/* 32B70 */
+	0x14,  0x21,  0x30,  0x20,  0xBB,  0x10,  0x20,  0x10,  0x20,  0x10,  0x20,  0x11,  0xFE,  0x7D,  0x22,  0x11, 	/* 32B80 */
+	0x22,  0x11,  0x22,  0x11,  0xFE,  0x1D,  0x22,  0x71,  0x22,  0x11,  0xFE,  0x10,  0x20,  0x10,  0x20,  0x10, 	/* 32B90 */
+	0x20,  0x10,  0x20,  0x30,  0x20,  0xBC,  0x10,  0x00,  0x11,  0xFE,  0x11,  0x22,  0x11,  0x22,  0x7D,  0x22, 	/* 32BA0 */
+	0x11,  0xFE,  0x11,  0x22,  0x11,  0x22,  0x11,  0x22,  0x1D,  0xFE,  0x70,  0x20,  0x10,  0x20,  0x10,  0x20, 	/* 32BB0 */
+	0x10,  0x20,  0x10,  0x20,  0x30,  0x20,  0xBD,  0x10,  0x20,  0x10,  0x20,  0x10,  0x20,  0x10,  0x20,  0x7D, 	/* 32BC0 */
+	0xFE,  0x11,  0x22,  0x11,  0x22,  0x11,  0x22,  0x11,  0x22,  0x1D,  0xFE,  0x71,  0x22,  0x11,  0x22,  0x11, 	/* 32BD0 */
+	0x22,  0x11,  0x22,  0x11,  0xFE,  0x30,  0x00,  0x82,  0x10,  0x50,  0x10,  0x50,  0x13,  0xFE,  0x10,  0x52, 	/* 32BE0 */
+	0x7C,  0x52,  0x13,  0xFE,  0x12,  0x50,  0x12,  0x50,  0x1B,  0xFE,  0x70,  0x52,  0x10,  0x52,  0x10,  0x92, 	/* 32BF0 */
+	0x10,  0x92,  0x11,  0x1C,  0x12,  0x10,  0x34,  0x10,  0x85,  0x10,  0x00,  0x11,  0xFC,  0x11,  0x04,  0x11, 	/* 32C00 */
+	0x04,  0x7D,  0x04,  0x11,  0x04,  0x11,  0xFC,  0x11,  0x04,  0x1D,  0x04,  0x71,  0x04,  0x11,  0x04,  0x11, 	/* 32C10 */
+	0xFC,  0x10,  0x00,  0x10,  0x00,  0x17,  0xFF,  0x30,  0x00,  0x86,  0x10,  0x02,  0x10,  0x0C,  0x10,  0xF0, 	/* 32C20 */
+	0x10,  0x80,  0x7C,  0x80,  0x10,  0xFF,  0x10,  0x88,  0x10,  0x88,  0x1C,  0xB8,  0x70,  0x8E,  0x10,  0x89, 	/* 32C30 */
+	0x10,  0x88,  0x11,  0x08,  0x11,  0x08,  0x12,  0x08,  0x30,  0x08,  0x87,  0x10,  0x00,  0x11,  0xFC,  0x11, 	/* 32C40 */
+	0x04,  0x11,  0x44,  0x7D,  0x24,  0x11,  0x24,  0x11,  0x04,  0x17,  0xFF,  0x12,  0x04,  0x1E,  0x44,  0x72, 	/* 32C50 */
+	0x24,  0x12,  0x24,  0x13,  0xFF,  0x10,  0x04,  0x10,  0x08,  0x30,  0x30,  0x88,  0x08,  0x20,  0x08,  0x20, 	/* 32C60 */
+	0x08,  0x20,  0x08,  0x20,  0x7E,  0x3F,  0x08,  0x20,  0x08,  0x20,  0x08,  0x20,  0x0E,  0x20,  0x19,  0xFC, 	/* 32C70 */
+	0x69,  0x04,  0x09,  0x04,  0x09,  0x04,  0x09,  0x04,  0x09,  0xFC,  0x18,  0x00,  0x89,  0x10,  0x20,  0x10, 	/* 32C80 */
+	0x20,  0x10,  0x20,  0x13,  0xFE,  0x7C,  0x00,  0x10,  0x08,  0x11,  0x08,  0x11,  0x08,  0x1C,  0x88,  0x70, 	/* 32C90 */
+	0x88,  0x10,  0x90,  0x10,  0x90,  0x10,  0x10,  0x10,  0x20,  0x17,  0xFF,  0x30,  0x00,  0x8A,  0x10,  0x84, 	/* 32CA0 */
+	0x10,  0x84,  0x10,  0x84,  0x11,  0x04,  0x7D,  0x7F,  0x13,  0x04,  0x13,  0x04,  0x15,  0x44,  0x11,  0x24, 	/* 32CB0 */
+	0x1D,  0x24,  0x71,  0x04,  0x11,  0x04,  0x11,  0x04,  0x11,  0x04,  0x11,  0x04,  0x31,  0x0C,  0x8C,  0x10, 	/* 32CC0 */
+	0x20,  0x10,  0xA8,  0x10,  0xA4,  0x11,  0x22,  0x7E,  0x22,  0x11,  0xFC,  0x10,  0x20,  0x10,  0x20,  0x1C, 	/* 32CD0 */
+	0x20,  0x73,  0xFF,  0x10,  0x20,  0x10,  0x20,  0x10,  0x20,  0x10,  0x20,  0x10,  0x20,  0x30,  0x20,  0x8D, 	/* 32CE0 */
+	0x08,  0x10,  0x08,  0x10,  0x08,  0x20,  0x08,  0xFE,  0x7E,  0x82,  0x08,  0x82,  0x08,  0x82,  0x0A,  0x82, 	/* 32CF0 */
+	0x0C,  0xFE,  0x18,  0x82,  0x68,  0x82,  0x08,  0x82,  0x08,  0x82,  0x08,  0x82,  0x08,  0xFE,  0x18,  0x00, 	/* 32D00 */
+	0x8F,  0x04,  0x00,  0x04,  0x00,  0x7F,  0x7E,  0x09,  0x22,  0x11,  0x14,  0x3E,  0x08,  0x05,  0x34,  0x19, 	/* 32D10 */
+	0xC3,  0x60,  0x10,  0x0F,  0xE0,  0x00,  0x80,  0x1F,  0xFC,  0x00,  0x80,  0x7F,  0xFF,  0x00,  0x80,  0x01, 	/* 32D20 */
+	0x80,  0x90,  0x08,  0x00,  0x08,  0xFC,  0x08,  0x84,  0x08,  0x84,  0x7E,  0x84,  0x08,  0xFC,  0x08,  0x00, 	/* 32D30 */
+	0x08,  0x00,  0x09,  0xFE,  0x0E,  0x22,  0x78,  0x22,  0x08,  0x22,  0x08,  0x42,  0x08,  0x42,  0x08,  0x82, 	/* 32D40 */
+	0x19,  0x0C,  0x91,  0x10,  0x84,  0x10,  0x84,  0x10,  0x84,  0x13,  0xFF,  0x7C,  0x84,  0x10,  0x84,  0x10, 	/* 32D50 */
+	0x84,  0x10,  0x84,  0x1C,  0xFC,  0x70,  0x84,  0x10,  0x84,  0x10,  0x84,  0x10,  0x84,  0x10,  0x84,  0x10, 	/* 32D60 */
+	0xFC,  0x30,  0x00,  0x92,  0x08,  0x00,  0x08,  0xFE,  0x08,  0x80,  0x08,  0x80,  0x7E,  0x80,  0x08,  0xFC, 	/* 32D70 */
+	0x08,  0x84,  0x08,  0x84,  0x08,  0x84,  0x0E,  0xFC,  0x78,  0x80,  0x08,  0x80,  0x08,  0x80,  0x08,  0x80, 	/* 32D80 */
+	0x08,  0xFF,  0x18,  0x00,  0x93,  0x10,  0x00,  0x13,  0xFF,  0x10,  0x40,  0x10,  0x40,  0x7C,  0x40,  0x10, 	/* 32D90 */
+	0x40,  0x10,  0x80,  0x10,  0xFE,  0x11,  0x82,  0x1D,  0x82,  0x72,  0x82,  0x14,  0x82,  0x10,  0x82,  0x10, 	/* 32DA0 */
+	0x82,  0x10,  0xFE,  0x30,  0x00,  0x94,  0x10,  0x48,  0x10,  0x44,  0x10,  0x44,  0x13,  0xFF,  0x7C,  0x40, 	/* 32DB0 */
+	0x10,  0x44,  0x10,  0x44,  0x10,  0x44,  0x1C,  0xA8,  0x70,  0xA8,  0x11,  0x10,  0x11,  0x10,  0x12,  0x28, 	/* 32DC0 */
+	0x14,  0x44,  0x10,  0x82,  0x31,  0x01,  0x97,  0x10,  0x88,  0x10,  0x88,  0x10,  0x88,  0x10,  0x88,  0x7D, 	/* 32DD0 */
+	0x3E,  0x11,  0x4A,  0x16,  0x4A,  0x11,  0x4A,  0x1C,  0x8A,  0x70,  0x8A,  0x11,  0x92,  0x11,  0x52,  0x12, 	/* 32DE0 */
+	0x52,  0x1F,  0xA2,  0x10,  0x42,  0x30,  0x8C,  0x98,  0x10,  0x80,  0x10,  0x80,  0x10,  0x80,  0x10,  0xFE, 	/* 32DF0 */
+	0x7D,  0x02,  0x11,  0x02,  0x12,  0xF2,  0x14,  0x92,  0x10,  0x92,  0x1C,  0x92,  0x70,  0x92,  0x10,  0xF2, 	/* 32E00 */
+	0x10,  0x02,  0x10,  0x02,  0x10,  0x04,  0x30,  0x18,  0x99,  0x10,  0x20,  0x10,  0x20,  0x11,  0x22,  0x11, 	/* 32E10 */
+	0x22,  0x7D,  0x22,  0x11,  0x22,  0x11,  0xFE,  0x11,  0x22,  0x1C,  0x20,  0x70,  0x20,  0x11,  0x22,  0x11, 	/* 32E20 */
+	0x22,  0x11,  0x22,  0x11,  0x22,  0x11,  0xFE,  0x31,  0x02,  0x9B,  0x10,  0x00,  0x17,  0xFE,  0x10,  0x42, 	/* 32E30 */
+	0x10,  0x42,  0x7C,  0x42,  0x10,  0x82,  0x10,  0x82,  0x11,  0x0C,  0x1E,  0x00,  0x75,  0xFC,  0x11,  0x04, 	/* 32E40 */
+	0x11,  0x04,  0x11,  0x04,  0x11,  0x04,  0x11,  0xFC,  0x30,  0x00,  0x9C,  0x02,  0x00,  0x0D,  0xFF,  0x78, 	/* 32E50 */
+	0x10,  0x08,  0x10,  0x08,  0xFE,  0x7E,  0x10,  0x08,  0x10,  0x08,  0xFE,  0x0E,  0x10,  0x18,  0x10,  0x68, 	/* 32E60 */
+	0x10,  0x09,  0xFF,  0x10,  0x10,  0x10,  0x10,  0x20,  0x10,  0x40,  0x10,  0x9D,  0x10,  0x00,  0x13,  0xFF, 	/* 32E70 */
+	0x10,  0x20,  0x10,  0x20,  0x7D,  0xFE,  0x10,  0x20,  0x10,  0x20,  0x11,  0xFE,  0x1C,  0x20,  0x70,  0x20, 	/* 32E80 */
+	0x10,  0x20,  0x13,  0xFF,  0x10,  0x20,  0x10,  0x20,  0x10,  0x20,  0x30,  0x20,  0xA0,  0x11,  0x00,  0x11, 	/* 32E90 */
+	0x1C,  0x11,  0x14,  0x11,  0x14,  0x7F,  0xD4,  0x12,  0x54,  0x12,  0x54,  0x15,  0x54,  0x14,  0x94,  0x18, 	/* 32EA0 */
+	0xA4,  0x71,  0xA5,  0x11,  0x45,  0x12,  0x43,  0x14,  0x20,  0x18,  0x18,  0x30,  0x07,  0xA1,  0x10,  0x10, 	/* 32EB0 */
+	0x10,  0x10,  0x10,  0x10,  0x11,  0xFF,  0x7D,  0x00,  0x11,  0x10,  0x11,  0x10,  0x11,  0x10,  0x11,  0x10, 	/* 32EC0 */
+	0x1D,  0x10,  0x71,  0x24,  0x12,  0x24,  0x12,  0x42,  0x12,  0x5E,  0x15,  0xE1,  0x38,  0x01,  0xAC,  0x10, 	/* 32ED0 */
+	0x04,  0x10,  0x18,  0x11,  0xE0,  0x10,  0x20,  0x7C,  0x20,  0x10,  0x20,  0x13,  0xFF,  0x10,  0x20,  0x1C, 	/* 32EE0 */
+	0x20,  0x70,  0x20,  0x11,  0xFC,  0x11,  0x04,  0x11,  0x04,  0x11,  0x04,  0x11,  0xFC,  0x30,  0x00,  0xAD, 	/* 32EF0 */
+	0x10,  0x10,  0x10,  0x14,  0x10,  0x12,  0x10,  0x12,  0x7F,  0xFF,  0x10,  0x10,  0x10,  0x10,  0x13,  0xF0, 	/* 32F00 */
+	0x1C,  0x88,  0x70,  0x88,  0x10,  0x88,  0x10,  0xA8,  0x10,  0xC5,  0x13,  0x05,  0x10,  0x03,  0x30,  0x01, 	/* 32F10 */
+	0xAE,  0x10,  0x20,  0x10,  0x20,  0x10,  0x20,  0x13,  0xFF,  0x7C,  0x20,  0x10,  0x20,  0x10,  0x20,  0x11, 	/* 32F20 */
+	0xFE,  0x1C,  0x00,  0x70,  0x00,  0x11,  0xFC,  0x11,  0x04,  0x11,  0x04,  0x11,  0x04,  0x11,  0xFC,  0x30, 	/* 32F30 */
+	0x00,  0xAF,  0x10,  0x00,  0x13,  0xFC,  0x10,  0x08,  0x10,  0x10,  0x7C,  0x22,  0x13,  0xA2,  0x10,  0xB4, 	/* 32F40 */
+	0x10,  0xB4,  0x1D,  0x28,  0x71,  0x24,  0x12,  0x22,  0x14,  0x21,  0x10,  0x60,  0x10,  0x00,  0x17,  0xFF, 	/* 32F50 */
+	0x30,  0x00,  0xB1,  0x10,  0x88,  0x10,  0x88,  0x10,  0x88,  0x10,  0x88,  0x7B,  0xFE,  0x10,  0x88,  0x10, 	/* 32F60 */
+	0x88,  0x10,  0x88,  0x1C,  0x88,  0x70,  0x88,  0x17,  0xFF,  0x10,  0x00,  0x10,  0x88,  0x10,  0x84,  0x11, 	/* 32F70 */
+	0x02,  0x32,  0x02,  0xB3,  0x08,  0x88,  0x04,  0x88,  0x04,  0x90,  0x3F,  0xFE,  0x01,  0x40,  0x7F,  0xFF, 	/* 32F80 */
+	0x02,  0x20,  0x04,  0x50,  0x1B,  0x8C,  0x60,  0x83,  0x0F,  0xFC,  0x00,  0x80,  0x7F,  0xFF,  0x00,  0x80, 	/* 32F90 */
+	0x00,  0x80,  0x01,  0x80,  0xB5,  0x10,  0x20,  0x10,  0x20,  0x10,  0x20,  0x13,  0xFF,  0x7C,  0x40,  0x10, 	/* 32FA0 */
+	0x40,  0x10,  0x7E,  0x10,  0x84,  0x1D,  0x88,  0x71,  0x08,  0x13,  0x7F,  0x15,  0x08,  0x11,  0x08,  0x11, 	/* 32FB0 */
+	0x08,  0x11,  0x08,  0x31,  0x18,  0xB6,  0x10,  0x92,  0x10,  0x92,  0x13,  0x6C,  0x11,  0x24,  0x7C,  0x92, 	/* 32FC0 */
+	0x10,  0x92,  0x10,  0x20,  0x10,  0x3E,  0x1C,  0x42,  0x70,  0x84,  0x11,  0x44,  0x16,  0x28,  0x10,  0x10, 	/* 32FD0 */
+	0x10,  0x20,  0x10,  0xC0,  0x33,  0x00,  0xB7,  0x10,  0x40,  0x10,  0x44,  0x13,  0xFC,  0x10,  0x48,  0x7C, 	/* 32FE0 */
+	0x50,  0x17,  0xFF,  0x10,  0x20,  0x10,  0x40,  0x1C,  0xFC,  0x71,  0x40,  0x16,  0x40,  0x10,  0x7C,  0x10, 	/* 32FF0 */
+	0x44,  0x10,  0x04,  0x10,  0x04,  0x30,  0x18,  0xBE,  0x10,  0x20,  0x10,  0x20,  0x10,  0x50,  0x10,  0x50, 	/* 33000 */
+	0x7C,  0x88,  0x11,  0x04,  0x12,  0xFA,  0x14,  0x01,  0x1C,  0x00,  0x71,  0xFC,  0x11,  0x04,  0x11,  0x04, 	/* 33010 */
+	0x11,  0x04,  0x11,  0x04,  0x11,  0xFC,  0x30,  0x00,  0xBF,  0x00,  0x80,  0x01,  0x40,  0x02,  0x20,  0x07, 	/* 33020 */
+	0xF0,  0x18,  0x0C,  0x6F,  0xFB,  0x08,  0x08,  0x0F,  0xF8,  0x00,  0x10,  0x0F,  0xE0,  0x00,  0x80,  0x1F, 	/* 33030 */
+	0xFC,  0x00,  0x80,  0x7F,  0xFF,  0x00,  0x80,  0x01,  0x80,  0x81,  0x08,  0x20,  0x08,  0x20,  0x09,  0xFE, 	/* 33040 */
+	0x08,  0x20,  0x7E,  0x20,  0x08,  0x20,  0x0B,  0xFF,  0x08,  0x04,  0x08,  0x04,  0x0F,  0xFF,  0x78,  0x84, 	/* 33050 */
+	0x08,  0x44,  0x08,  0x44,  0x08,  0x04,  0x08,  0x04,  0x18,  0x0C,  0x82,  0x10,  0x20,  0x10,  0x20,  0x11, 	/* 33060 */
+	0xFC,  0x7C,  0x20,  0x10,  0x20,  0x10,  0x20,  0x13,  0xFE,  0x10,  0x00,  0x1C,  0x20,  0x70,  0x20,  0x11, 	/* 33070 */
+	0xFC,  0x10,  0x20,  0x10,  0x20,  0x10,  0x20,  0x17,  0xFF,  0x30,  0x00,  0x87,  0x08,  0x80,  0x08,  0x86, 	/* 33080 */
+	0x08,  0xF8,  0x08,  0x80,  0x7F,  0x81,  0x08,  0x81,  0x08,  0x7F,  0x08,  0x00,  0x0E,  0xFE,  0x78,  0x82, 	/* 33090 */
+	0x08,  0x82,  0x08,  0xFE,  0x08,  0x82,  0x08,  0x82,  0x08,  0xFE,  0x18,  0x00,  0x88,  0x04,  0x00,  0x07, 	/* 330A0 */
+	0x7E,  0x7C,  0x12,  0x07,  0x12,  0x3C,  0x12,  0x05,  0xA2,  0x0E,  0x42,  0x74,  0x8C,  0x00,  0x10,  0x07, 	/* 330B0 */
+	0xE0,  0x00,  0x80,  0x1F,  0xFC,  0x00,  0x80,  0x7F,  0xFF,  0x00,  0x80,  0x01,  0x80,  0x89,  0x10,  0x40, 	/* 330C0 */
+	0x10,  0x40,  0x13,  0xFE,  0x12,  0x02,  0x7E,  0x42,  0x10,  0x40,  0x10,  0x40,  0x13,  0xFF,  0x1C,  0x88, 	/* 330D0 */
+	0x70,  0x88,  0x11,  0x10,  0x13,  0xD0,  0x10,  0x20,  0x10,  0x50,  0x11,  0x88,  0x36,  0x04,  0x8C,  0x10, 	/* 330E0 */
+	0x40,  0x10,  0x40,  0x10,  0x7C,  0x10,  0x84,  0x7C,  0x88,  0x11,  0x50,  0x12,  0x20,  0x10,  0x50,  0x19, 	/* 330F0 */
+	0x8C,  0x76,  0x03,  0x11,  0xFC,  0x11,  0x04,  0x11,  0x04,  0x11,  0x04,  0x11,  0xFC,  0x30,  0x00,  0x91, 	/* 33100 */
+	0x10,  0x50,  0x10,  0x50,  0x12,  0x54,  0x11,  0x54,  0x7D,  0x54,  0x11,  0x58,  0x10,  0x50,  0x10,  0x50, 	/* 33110 */
+	0x1C,  0xD8,  0x71,  0x54,  0x16,  0x52,  0x10,  0x50,  0x10,  0x91,  0x10,  0x91,  0x11,  0x0F,  0x32,  0x00, 	/* 33120 */
+	0x99,  0x09,  0x04,  0x04,  0x84,  0x04,  0x88,  0x7F,  0xFF,  0x02,  0x20,  0x04,  0x30,  0x18,  0xCC,  0x6F, 	/* 33130 */
+	0x83,  0x00,  0x80,  0x1F,  0xFC,  0x00,  0x80,  0x00,  0x80,  0x3F,  0xFE,  0x00,  0x80,  0x00,  0x80,  0x01, 	/* 33140 */
+	0x80,  0x9F,  0x10,  0x20,  0x10,  0x20,  0x13,  0xFE,  0x10,  0x20,  0x7E,  0x24,  0x11,  0x24,  0x10,  0xA4, 	/* 33150 */
+	0x10,  0xA8,  0x1F,  0xFF,  0x70,  0x20,  0x10,  0x50,  0x10,  0x50,  0x10,  0x88,  0x11,  0x04,  0x12,  0x02, 	/* 33160 */
+	0x34,  0x01,  0xA7,  0x10,  0x00,  0x17,  0xFE,  0x10,  0x42,  0x10,  0xC6,  0x7C,  0xC6,  0x11,  0x4A,  0x12, 	/* 33170 */
+	0x52,  0x14,  0x62,  0x1C,  0xC6,  0x70,  0xC6,  0x11,  0x4A,  0x12,  0x52,  0x14,  0x62,  0x10,  0x42,  0x10, 	/* 33180 */
+	0x42,  0x30,  0xC6,  0xA8,  0x10,  0x40,  0x10,  0x50,  0x10,  0x48,  0x7C,  0x84,  0x13,  0xFA,  0x10,  0x82, 	/* 33190 */
+	0x10,  0x80,  0x11,  0xFE,  0x15,  0x20,  0x1A,  0x20,  0x73,  0xFF,  0x10,  0x50,  0x10,  0x50,  0x10,  0x88, 	/* 331A0 */
+	0x11,  0x04,  0x36,  0x02,  0xAB,  0x10,  0x20,  0x11,  0x24,  0x11,  0x24,  0x11,  0x24,  0x7D,  0x24,  0x11, 	/* 331B0 */
+	0x2C,  0x11,  0xAA,  0x12,  0x72,  0x12,  0x21,  0x1C,  0x20,  0x71,  0xFC,  0x10,  0x20,  0x10,  0x20,  0x10, 	/* 331C0 */
+	0x20,  0x17,  0xFF,  0x30,  0x00,  0xAF,  0x10,  0x00,  0x13,  0xFF,  0x12,  0x00,  0x12,  0x00,  0x7E,  0xFC, 	/* 331D0 */
+	0x12,  0x00,  0x12,  0x00,  0x13,  0xFF,  0x1E,  0x92,  0x72,  0x92,  0x12,  0x94,  0x12,  0x88,  0x14,  0x88, 	/* 331E0 */
+	0x14,  0xA4,  0x18,  0xC2,  0x33,  0x01,  0xBA,  0x10,  0x02,  0x17,  0xCC,  0x10,  0xB8,  0x10,  0x88,  0x7C, 	/* 331F0 */
+	0x88,  0x11,  0x08,  0x13,  0xFF,  0x10,  0x48,  0x1E,  0x48,  0x71,  0x48,  0x11,  0x88,  0x10,  0x88,  0x11, 	/* 33200 */
+	0xBF,  0x11,  0x40,  0x12,  0x30,  0x34,  0x0F,  0xBD,  0x10,  0x40,  0x10,  0x78,  0x10,  0x88,  0x7D,  0x10, 	/* 33210 */
+	0x12,  0x20,  0x15,  0xFC,  0x11,  0x24,  0x11,  0x24,  0x1D,  0x24,  0x71,  0xFC,  0x10,  0x50,  0x10,  0x50, 	/* 33220 */
+	0x10,  0x90,  0x11,  0x11,  0x12,  0x11,  0x34,  0x0F,  0xBE,  0x10,  0x20,  0x10,  0x20,  0x17,  0xFF,  0x10, 	/* 33230 */
+	0x20,  0x7D,  0x24,  0x11,  0x24,  0x11,  0x24,  0x11,  0xAA,  0x1E,  0x6A,  0x72,  0x31,  0x14,  0x50,  0x10, 	/* 33240 */
+	0x50,  0x10,  0x88,  0x11,  0x04,  0x12,  0x02,  0x34,  0x01,  0xBF,  0x10,  0x04,  0x10,  0x18,  0x11,  0xE0, 	/* 33250 */
+	0x7C,  0x20,  0x17,  0xFF,  0x10,  0x20,  0x11,  0xFC,  0x11,  0x24,  0x1D,  0x24,  0x71,  0xFC,  0x11,  0x24, 	/* 33260 */
+	0x11,  0x24,  0x11,  0xFC,  0x10,  0x20,  0x10,  0x20,  0x30,  0x20,  0x89,  0x10,  0x00,  0x11,  0xFE,  0x11, 	/* 33270 */
+	0x02,  0x11,  0x02,  0x7D,  0x02,  0x11,  0x02,  0x11,  0xFE,  0x10,  0x20,  0x14,  0x20,  0x19,  0x20,  0x71, 	/* 33280 */
+	0x3E,  0x11,  0x20,  0x12,  0xA0,  0x12,  0x60,  0x14,  0x30,  0x38,  0x0F,  0x8C,  0x10,  0x02,  0x17,  0xD2, 	/* 33290 */
+	0x14,  0x52,  0x14,  0x52,  0x7C,  0x52,  0x17,  0xD2,  0x11,  0x12,  0x11,  0x12,  0x11,  0xD2,  0x1D,  0x52, 	/* 332A0 */
+	0x72,  0x52,  0x12,  0x42,  0x12,  0x42,  0x14,  0x42,  0x18,  0x42,  0x31,  0x86,  0x8D,  0x10,  0x00,  0x11, 	/* 332B0 */
+	0xFC,  0x11,  0x04,  0x11,  0xFC,  0x7D,  0x04,  0x11,  0x04,  0x11,  0xFC,  0x10,  0x00,  0x1B,  0xFE,  0x70, 	/* 332C0 */
+	0x20,  0x10,  0x20,  0x17,  0xFF,  0x10,  0x20,  0x10,  0x20,  0x10,  0x20,  0x30,  0x20,  0x8F,  0x10,  0x00, 	/* 332D0 */
+	0x11,  0xFC,  0x11,  0x04,  0x11,  0x04,  0x7D,  0xFC,  0x11,  0x04,  0x11,  0x04,  0x11,  0xFC,  0x1C,  0x20, 	/* 332E0 */
+	0x70,  0x20,  0x13,  0xFE,  0x10,  0x20,  0x10,  0x20,  0x10,  0x20,  0x17,  0xFF,  0x30,  0x00,  0x90,  0x10, 	/* 332F0 */
+	0x00,  0x11,  0xFC,  0x11,  0x04,  0x11,  0x04,  0x7D,  0xFC,  0x10,  0x00,  0x11,  0xFC,  0x11,  0x04,  0x1D, 	/* 33300 */
+	0x04,  0x71,  0xFC,  0x11,  0x04,  0x11,  0x04,  0x11,  0xFC,  0x11,  0x04,  0x11,  0x04,  0x31,  0x0C,  0x95, 	/* 33310 */
+	0x10,  0x28,  0x10,  0x24,  0x13,  0xFF,  0x10,  0x20,  0x7C,  0x20,  0x11,  0xFE,  0x11,  0x22,  0x11,  0x22, 	/* 33320 */
+	0x1D,  0xFE,  0x71,  0x22,  0x11,  0x22,  0x11,  0xFE,  0x11,  0x22,  0x11,  0x22,  0x11,  0x22,  0x31,  0x26, 	/* 33330 */
+	0x97,  0x10,  0x20,  0x11,  0x20,  0x11,  0x3E,  0x11,  0x20,  0x7D,  0x20,  0x17,  0xFF,  0x10,  0x20,  0x10, 	/* 33340 */
+	0xA8,  0x1C,  0xA4,  0x71,  0x22,  0x12,  0x2A,  0x14,  0x68,  0x10,  0x10,  0x10,  0x20,  0x10,  0xC0,  0x33, 	/* 33350 */
+	0x00,  0x9C,  0x10,  0x20,  0x10,  0x20,  0x11,  0xFC,  0x11,  0x24,  0x7D,  0x24,  0x11,  0xFC,  0x11,  0x24, 	/* 33360 */
+	0x11,  0x24,  0x1D,  0xFC,  0x70,  0x20,  0x13,  0xFC,  0x10,  0x88,  0x10,  0x50,  0x10,  0x20,  0x10,  0xD8, 	/* 33370 */
+	0x37,  0x07,  0xA7,  0x10,  0x20,  0x10,  0x20,  0x13,  0xFE,  0x10,  0x20,  0x7D,  0xFC,  0x10,  0x50,  0x17, 	/* 33380 */
+	0xFF,  0x10,  0x88,  0x1D,  0x24,  0x76,  0x23,  0x11,  0xFC,  0x10,  0x20,  0x13,  0xFE,  0x10,  0x20,  0x10, 	/* 33390 */
+	0x20,  0x30,  0x20,  0xA8,  0x10,  0x20,  0x10,  0x20,  0x10,  0x50,  0x7C,  0x88,  0x11,  0x24,  0x16,  0x23, 	/* 333A0 */
+	0x11,  0xFC,  0x10,  0x20,  0x1C,  0x20,  0x73,  0xFF,  0x10,  0x00,  0x11,  0xFC,  0x11,  0x04,  0x11,  0x04, 	/* 333B0 */
+	0x11,  0xFC,  0x30,  0x00,  0xA9,  0x10,  0x00,  0x13,  0xFF,  0x10,  0x00,  0x11,  0xFE,  0x7D,  0x02,  0x11, 	/* 333C0 */
+	0x02,  0x11,  0xFE,  0x11,  0x10,  0x1D,  0x10,  0x71,  0xFF,  0x11,  0x10,  0x12,  0x28,  0x12,  0x28,  0x14, 	/* 333D0 */
+	0x44,  0x18,  0x82,  0x33,  0x01,  0xAB,  0x10,  0x00,  0x13,  0xDE,  0x12,  0x52,  0x13,  0xDE,  0x7E,  0x52, 	/* 333E0 */
+	0x12,  0x52,  0x13,  0xDE,  0x12,  0x02,  0x1E,  0x02,  0x72,  0x02,  0x12,  0x02,  0x12,  0x02,  0x12,  0x02, 	/* 333F0 */
+	0x12,  0x02,  0x12,  0x02,  0x32,  0x06,  0xAE,  0x10,  0x00,  0x13,  0xFE,  0x12,  0x02,  0x12,  0x02,  0x7F, 	/* 33400 */
+	0xFE,  0x12,  0x20,  0x12,  0x20,  0x13,  0xFF,  0x1E,  0x20,  0x72,  0x20,  0x12,  0xFC,  0x12,  0x84,  0x14, 	/* 33410 */
+	0x84,  0x14,  0x84,  0x18,  0xFC,  0x30,  0x00,  0xB2,  0x11,  0x24,  0x10,  0xA4,  0x10,  0xA8,  0x13,  0xFE, 	/* 33420 */
+	0x7C,  0x20,  0x10,  0x50,  0x13,  0xFF,  0x10,  0x50,  0x1C,  0x88,  0x71,  0xF4,  0x16,  0x13,  0x10,  0x10, 	/* 33430 */
+	0x11,  0xF0,  0x11,  0x04,  0x11,  0x04,  0x30,  0xFC,  0xB6,  0x10,  0x04,  0x10,  0x18,  0x13,  0xE0,  0x10, 	/* 33440 */
+	0x20,  0x7F,  0xFE,  0x11,  0x24,  0x11,  0x24,  0x17,  0xFF,  0x19,  0x24,  0x71,  0x24,  0x11,  0x24,  0x13, 	/* 33450 */
+	0xFE,  0x10,  0x20,  0x10,  0x20,  0x17,  0xFF,  0x30,  0x00,  0xB7,  0x10,  0x20,  0x10,  0x20,  0x13,  0xFF, 	/* 33460 */
+	0x10,  0x20,  0x7D,  0xFC,  0x10,  0x24,  0x13,  0xFF,  0x10,  0x24,  0x1D,  0xFC,  0x70,  0x20,  0x11,  0x20, 	/* 33470 */
+	0x11,  0x3E,  0x11,  0xA0,  0x12,  0x60,  0x14,  0x30,  0x38,  0x0F,  0xBA,  0x10,  0x20,  0x10,  0x20,  0x13, 	/* 33480 */
+	0xFF,  0x10,  0x30,  0x7C,  0x50,  0x10,  0x88,  0x11,  0x04,  0x12,  0xFA,  0x1C,  0x01,  0x70,  0x00,  0x13, 	/* 33490 */
+	0xFE,  0x10,  0xA0,  0x10,  0xA8,  0x11,  0x24,  0x12,  0x22,  0x30,  0x60,  0xBB,  0x10,  0x20,  0x10,  0x20, 	/* 334A0 */
+	0x10,  0x50,  0x7D,  0x8C,  0x16,  0xFB,  0x10,  0x00,  0x11,  0xFC,  0x10,  0x08,  0x1C,  0x10,  0x70,  0x50, 	/* 334B0 */
+	0x12,  0x20,  0x12,  0xA4,  0x12,  0xA2,  0x14,  0x89,  0x18,  0x49,  0x30,  0x38,  0x80,  0x10,  0x48,  0x10, 	/* 334C0 */
+	0x88,  0x13,  0x08,  0x12,  0x1F,  0x7E,  0x11,  0x13,  0xFA,  0x12,  0x5C,  0x12,  0x68,  0x1E,  0x48,  0x72, 	/* 334D0 */
+	0x48,  0x12,  0x54,  0x12,  0x54,  0x12,  0x54,  0x12,  0x62,  0x14,  0x62,  0x30,  0x41,  0x83,  0x10,  0x00, 	/* 334E0 */
+	0x11,  0xF8,  0x10,  0x08,  0x10,  0xF8,  0x7C,  0x08,  0x11,  0xF8,  0x10,  0x00,  0x13,  0xFE,  0x1E,  0x22, 	/* 334F0 */
+	0x73,  0xFC,  0x11,  0x24,  0x11,  0x24,  0x11,  0x24,  0x11,  0x38,  0x11,  0x20,  0x30,  0x20,  0x88,  0x10, 	/* 33500 */
+	0x04,  0x10,  0x18,  0x13,  0xE4,  0x11,  0x24,  0x7C,  0x88,  0x13,  0xFE,  0x12,  0x02,  0x12,  0x02,  0x13, 	/* 33510 */
+	0xF8,  0x1C,  0x88,  0x70,  0x48,  0x10,  0x50,  0x10,  0x20,  0x10,  0x50,  0x11,  0x8C,  0x36,  0x03,  0x89, 	/* 33520 */
+	0x10,  0x20,  0x10,  0x20,  0x10,  0x3E,  0x10,  0x20,  0x7D,  0xFC,  0x11,  0x04,  0x11,  0x04,  0x11,  0xFC, 	/* 33530 */
+	0x1D,  0x04,  0x71,  0x04,  0x11,  0xFC,  0x10,  0x20,  0x17,  0xFF,  0x10,  0x20,  0x10,  0x20,  0x30,  0x20, 	/* 33540 */
+	0x8C,  0x11,  0x10,  0x09,  0x10,  0x09,  0x20,  0x7F,  0xFE,  0x40,  0x02,  0x4F,  0xF2,  0x08,  0x10,  0x0F, 	/* 33550 */
+	0xF0,  0x00,  0x18,  0x0F,  0xE0,  0x00,  0x80,  0x3F,  0xFC,  0x00,  0x80,  0x7F,  0xFE,  0x00,  0x80,  0x01, 	/* 33560 */
+	0x80,  0x8E,  0x10,  0x20,  0x10,  0x20,  0x13,  0xFE,  0x10,  0x30,  0x7C,  0x48,  0x11,  0x84,  0x10,  0x00, 	/* 33570 */
+	0x17,  0xFF,  0x1C,  0x04,  0x71,  0xE4,  0x11,  0x24,  0x11,  0x24,  0x11,  0xE4,  0x10,  0x04,  0x10,  0x04, 	/* 33580 */
+	0x30,  0x0C,  0x8F,  0x11,  0x00,  0x11,  0x00,  0x11,  0xFE,  0x11,  0x02,  0x7E,  0x82,  0x12,  0xFA,  0x15, 	/* 33590 */
+	0x42,  0x12,  0x42,  0x1F,  0xFE,  0x70,  0x42,  0x11,  0x4A,  0x11,  0x4A,  0x11,  0xFA,  0x10,  0x02,  0x10, 	/* 335A0 */
+	0x04,  0x30,  0x18,  0x92,  0x10,  0x48,  0x10,  0x48,  0x10,  0x48,  0x13,  0xCF,  0x7C,  0x48,  0x10,  0x48, 	/* 335B0 */
+	0x10,  0x48,  0x13,  0xCF,  0x1C,  0x48,  0x70,  0x48,  0x11,  0xC8,  0x16,  0x4F,  0x10,  0x88,  0x10,  0x88, 	/* 335C0 */
+	0x11,  0x08,  0x32,  0x08,  0x96,  0x10,  0x20,  0x10,  0x20,  0x17,  0xFF,  0x10,  0x90,  0x7C,  0x90,  0x10, 	/* 335D0 */
+	0x9C,  0x11,  0x24,  0x11,  0x34,  0x1F,  0x2C,  0x73,  0x44,  0x15,  0xA8,  0x11,  0x18,  0x11,  0x18,  0x11, 	/* 335E0 */
+	0x24,  0x11,  0x42,  0x31,  0x81,  0x98,  0x10,  0x00,  0x13,  0xFE,  0x12,  0x02,  0x12,  0x02,  0x7F,  0xFE, 	/* 335F0 */
+	0x12,  0x10,  0x12,  0x92,  0x12,  0x92,  0x1E,  0x92,  0x72,  0xFE,  0x12,  0x10,  0x12,  0x92,  0x14,  0x92, 	/* 33600 */
+	0x14,  0x92,  0x18,  0xFE,  0x30,  0x00,  0x9B,  0x10,  0x84,  0x10,  0x84,  0x13,  0xE4,  0x10,  0x84,  0x7C, 	/* 33610 */
+	0x84,  0x10,  0x84,  0x17,  0xF6,  0x10,  0x85,  0x1C,  0x85,  0x73,  0xE4,  0x10,  0x84,  0x10,  0x84,  0x10, 	/* 33620 */
+	0xB4,  0x11,  0xC4,  0x16,  0x04,  0x30,  0x04,  0x9F,  0x10,  0x20,  0x10,  0x20,  0x13,  0xFE,  0x12,  0x02, 	/* 33630 */
+	0x7E,  0x02,  0x11,  0xFC,  0x10,  0x20,  0x10,  0x20,  0x1D,  0x20,  0x71,  0x3E,  0x11,  0x20,  0x11,  0x20, 	/* 33640 */
+	0x11,  0x20,  0x12,  0xA0,  0x12,  0x60,  0x34,  0x1F,  0xA0,  0x10,  0x20,  0x10,  0x20,  0x10,  0x20,  0x17, 	/* 33650 */
+	0xFF,  0x7C,  0x00,  0x11,  0xFC,  0x11,  0x04,  0x11,  0x04,  0x1D,  0xFC,  0x70,  0x20,  0x11,  0x28,  0x11, 	/* 33660 */
+	0x24,  0x11,  0x22,  0x12,  0x22,  0x14,  0x20,  0x30,  0x60,  0xA1,  0x10,  0x06,  0x10,  0x38,  0x13,  0xC2, 	/* 33670 */
+	0x12,  0x42,  0x7D,  0x24,  0x11,  0x24,  0x11,  0x28,  0x10,  0x20,  0x1C,  0x20,  0x73,  0xFF,  0x10,  0x70, 	/* 33680 */
+	0x10,  0xA8,  0x11,  0x24,  0x16,  0x22,  0x10,  0x21,  0x30,  0x20,  0xA2,  0x10,  0x00,  0x13,  0xFE,  0x12, 	/* 33690 */
+	0x52,  0x12,  0x52,  0x7C,  0x90,  0x10,  0x92,  0x11,  0x0E,  0x12,  0x20,  0x10,  0x20,  0x1F,  0xFF,  0x70, 	/* 336A0 */
+	0x68,  0x10,  0xA4,  0x11,  0x22,  0x12,  0x21,  0x10,  0x20,  0x30,  0x20,  0xA3,  0x14,  0x02,  0x1F,  0x12, 	/* 336B0 */
+	0x24,  0x12,  0x7F,  0x92,  0x04,  0x12,  0x3F,  0x92,  0x24,  0x82,  0x25,  0x82,  0x20,  0x16,  0x07,  0xE0, 	/* 336C0 */
+	0x00,  0x80,  0x1F,  0xFC,  0x00,  0x80,  0x7F,  0xFF,  0x00,  0x80,  0x01,  0x80,  0xA5,  0x10,  0x20,  0x10, 	/* 336D0 */
+	0x20,  0x13,  0xFE,  0x11,  0x08,  0x7C,  0x88,  0x10,  0x90,  0x17,  0xFF,  0x10,  0x40,  0x10,  0x40,  0x1F, 	/* 336E0 */
+	0xFF,  0x70,  0x88,  0x10,  0x88,  0x13,  0xD0,  0x10,  0x30,  0x10,  0xCC,  0x37,  0x02,  0xA7,  0x10,  0x20, 	/* 336F0 */
+	0x10,  0x20,  0x13,  0xFE,  0x12,  0x52,  0x7E,  0x50,  0x10,  0x52,  0x10,  0x8E,  0x11,  0x00,  0x1E,  0x00, 	/* 33700 */
+	0x71,  0xFE,  0x10,  0x20,  0x10,  0x20,  0x10,  0x20,  0x10,  0x20,  0x13,  0xFF,  0x30,  0x00,  0xA8,  0x08, 	/* 33710 */
+	0x88,  0x08,  0x88,  0x09,  0x10,  0x09,  0xFE,  0x7F,  0x10,  0x09,  0x10,  0x09,  0x10,  0x09,  0xFE,  0x0D, 	/* 33720 */
+	0x10,  0x19,  0x10,  0x69,  0xFE,  0x09,  0x10,  0x09,  0x10,  0x09,  0x10,  0x09,  0xFF,  0x18,  0x00,  0xA9, 	/* 33730 */
+	0x10,  0x20,  0x10,  0x20,  0x17,  0xFF,  0x10,  0x50,  0x7C,  0xA8,  0x11,  0x24,  0x13,  0xFE,  0x15,  0x25, 	/* 33740 */
+	0x11,  0x24,  0x1D,  0xFC,  0x71,  0x24,  0x11,  0x24,  0x11,  0xFC,  0x10,  0x21,  0x10,  0x21,  0x30,  0x1F, 	/* 33750 */
+	0xAA,  0x10,  0x88,  0x10,  0x88,  0x13,  0xFE,  0x10,  0x88,  0x7C,  0x88,  0x10,  0x88,  0x17,  0xFF,  0x10, 	/* 33760 */
+	0x00,  0x1D,  0xFC,  0x71,  0x04,  0x11,  0x04,  0x11,  0xFC,  0x11,  0x04,  0x11,  0x04,  0x11,  0xFC,  0x30, 	/* 33770 */
+	0x00,  0xAB,  0x10,  0x00,  0x17,  0xFF,  0x12,  0x40,  0x12,  0x40,  0x7E,  0x7E,  0x13,  0xC2,  0x12,  0x52, 	/* 33780 */
+	0x12,  0x54,  0x1F,  0xD4,  0x72,  0x4C,  0x12,  0x48,  0x12,  0x4C,  0x13,  0xD4,  0x16,  0x54,  0x10,  0x62, 	/* 33790 */
+	0x30,  0x41,  0xAC,  0x11,  0x00,  0x11,  0x00,  0x11,  0x00,  0x11,  0xFE,  0x7E,  0x02,  0x12,  0x4A,  0x15, 	/* 337A0 */
+	0x52,  0x11,  0x42,  0x1B,  0xFE,  0x70,  0x42,  0x10,  0xE2,  0x10,  0xD2,  0x11,  0x4A,  0x12,  0x42,  0x10, 	/* 337B0 */
+	0x44,  0x30,  0x18,  0xB2,  0x10,  0x00,  0x11,  0xF8,  0x11,  0x08,  0x11,  0xF8,  0x7D,  0x08,  0x11,  0x08, 	/* 337C0 */
+	0x11,  0xF8,  0x10,  0x80,  0x1C,  0xFE,  0x71,  0x02,  0x13,  0x32,  0x15,  0xC2,  0x11,  0x02,  0x11,  0x12, 	/* 337D0 */
+	0x10,  0xF2,  0x30,  0x0C,  0xB4,  0x10,  0x00,  0x13,  0xFE,  0x12,  0x02,  0x12,  0x02,  0x7F,  0xFE,  0x12, 	/* 337E0 */
+	0x22,  0x12,  0x22,  0x12,  0xFA,  0x1E,  0x22,  0x72,  0x32,  0x12,  0x2A,  0x12,  0x22,  0x13,  0xFE,  0x12, 	/* 337F0 */
+	0x02,  0x13,  0xFE,  0x30,  0x00,  0xB5,  0x10,  0x20,  0x10,  0x20,  0x10,  0x50,  0x10,  0x88,  0x7D,  0x04, 	/* 33800 */
+	0x12,  0xFA,  0x14,  0x01,  0x10,  0x00,  0x1F,  0xDE,  0x72,  0x52,  0x12,  0x52,  0x12,  0x52,  0x13,  0xD2, 	/* 33810 */
+	0x10,  0x1C,  0x10,  0x10,  0x30,  0x10,  0xBB,  0x10,  0x00,  0x13,  0xFC,  0x10,  0x84,  0x10,  0x48,  0x7C, 	/* 33820 */
+	0x30,  0x10,  0xCC,  0x13,  0x23,  0x10,  0x20,  0x1D,  0xFC,  0x71,  0x24,  0x11,  0x24,  0x11,  0xFC,  0x10, 	/* 33830 */
+	0x20,  0x10,  0x2C,  0x10,  0x7A,  0x37,  0x81,  0xBE,  0x10,  0x40,  0x10,  0x7C,  0x10,  0x88,  0x11,  0xF8, 	/* 33840 */
+	0x7C,  0x10,  0x13,  0xFF,  0x10,  0x40,  0x10,  0xAA,  0x1B,  0x2A,  0x70,  0x5C,  0x10,  0x94,  0x13,  0x34, 	/* 33850 */
+	0x10,  0x52,  0x10,  0x91,  0x13,  0x10,  0x30,  0x60,  0x80,  0x10,  0x20,  0x10,  0x20,  0x17,  0xFF,  0x10, 	/* 33860 */
+	0x20,  0x7D,  0xFC,  0x11,  0x24,  0x11,  0xAC,  0x11,  0x74,  0x1D,  0x24,  0x71,  0xFC,  0x10,  0x70,  0x10, 	/* 33870 */
+	0xA8,  0x11,  0x24,  0x16,  0x23,  0x10,  0x20,  0x30,  0x20,  0x83,  0x11,  0x04,  0x10,  0x84,  0x10,  0x88, 	/* 33880 */
+	0x17,  0xFF,  0x7C,  0x00,  0x13,  0xC2,  0x12,  0x52,  0x12,  0x52,  0x1F,  0xD2,  0x72,  0x52,  0x12,  0x52, 	/* 33890 */
+	0x13,  0xD2,  0x12,  0x42,  0x12,  0x42,  0x12,  0x42,  0x32,  0xC6,  0x84,  0x10,  0x20,  0x10,  0x20,  0x10, 	/* 338A0 */
+	0x50,  0x7C,  0x88,  0x11,  0xF6,  0x12,  0x01,  0x17,  0xD2,  0x12,  0x52,  0x1F,  0x52,  0x72,  0xE4,  0x12, 	/* 338B0 */
+	0x64,  0x13,  0x64,  0x12,  0xD2,  0x12,  0x52,  0x12,  0x52,  0x32,  0xD2,  0x86,  0x10,  0x10,  0x11,  0xD4, 	/* 338C0 */
+	0x10,  0x58,  0x12,  0x4A,  0x7D,  0x8C,  0x10,  0x84,  0x11,  0x02,  0x13,  0xFD,  0x1C,  0x20,  0x70,  0x20, 	/* 338D0 */
+	0x17,  0xFF,  0x10,  0x20,  0x10,  0x30,  0x10,  0x48,  0x11,  0x84,  0x36,  0x03,  0x89,  0x10,  0x00,  0x11, 	/* 338E0 */
+	0xFC,  0x10,  0xC8,  0x10,  0x30,  0x7F,  0xFF,  0x10,  0x32,  0x10,  0x54,  0x11,  0x90,  0x1E,  0x30,  0x70, 	/* 338F0 */
+	0x20,  0x13,  0xFF,  0x10,  0x70,  0x10,  0xA8,  0x11,  0x24,  0x16,  0x23,  0x30,  0x20,  0x8F,  0x10,  0x88, 	/* 33900 */
+	0x10,  0x88,  0x13,  0xFF,  0x10,  0x88,  0x7C,  0x88,  0x10,  0x00,  0x11,  0xFE,  0x11,  0x22,  0x1D,  0x22, 	/* 33910 */
+	0x71,  0x22,  0x11,  0xFE,  0x11,  0x22,  0x11,  0x22,  0x11,  0x22,  0x11,  0xFE,  0x31,  0x02,  0x90,  0x10, 	/* 33920 */
+	0x00,  0x10,  0xFC,  0x10,  0x84,  0x10,  0xFC,  0x7C,  0x84,  0x10,  0x84,  0x10,  0xFC,  0x10,  0x00,  0x13, 	/* 33930 */
+	0xFF,  0x1C,  0x20,  0x71,  0x20,  0x11,  0x3E,  0x11,  0xA0,  0x11,  0x60,  0x12,  0x30,  0x34,  0x0F,  0x92, 	/* 33940 */
+	0x10,  0x04,  0x10,  0x38,  0x11,  0xE0,  0x10,  0x20,  0x7C,  0x20,  0x13,  0xFF,  0x10,  0x20,  0x10,  0xA0, 	/* 33950 */
+	0x1F,  0x2E,  0x72,  0x22,  0x12,  0x22,  0x13,  0xAE,  0x12,  0x22,  0x12,  0x22,  0x13,  0xFE,  0x30,  0x00, 	/* 33960 */
+	0x96,  0x10,  0x00,  0x11,  0xFC,  0x11,  0x04,  0x11,  0x04,  0x7D,  0xFC,  0x10,  0x00,  0x17,  0xFF,  0x11, 	/* 33970 */
+	0x04,  0x1D,  0xFC,  0x71,  0x04,  0x11,  0xFC,  0x11,  0x07,  0x11,  0xFC,  0x17,  0x04,  0x10,  0x04,  0x30, 	/* 33980 */
+	0x04,  0x9A,  0x10,  0x00,  0x11,  0xF8,  0x11,  0x08,  0x11,  0xF8,  0x7D,  0x08,  0x11,  0x08,  0x11,  0xF8, 	/* 33990 */
+	0x10,  0x00,  0x1B,  0xFF,  0x70,  0x40,  0x11,  0xFE,  0x16,  0x52,  0x10,  0x92,  0x13,  0x22,  0x10,  0x44, 	/* 339A0 */
+	0x31,  0x98,  0x9B,  0x10,  0x40,  0x10,  0x7C,  0x10,  0x88,  0x7D,  0x10,  0x13,  0xFE,  0x16,  0x52,  0x12, 	/* 339B0 */
+	0x52,  0x12,  0x52,  0x1E,  0x8E,  0x73,  0x22,  0x12,  0x22,  0x17,  0xFF,  0x10,  0x60,  0x10,  0x90,  0x11, 	/* 339C0 */
+	0x0C,  0x36,  0x03,  0xA1,  0x10,  0x00,  0x13,  0xFE,  0x12,  0x02,  0x12,  0x02,  0x7F,  0xFE,  0x12,  0x00, 	/* 339D0 */
+	0x13,  0xFE,  0x12,  0x28,  0x16,  0x44,  0x1B,  0xFA,  0x72,  0x22,  0x15,  0xFC,  0x14,  0x20,  0x18,  0x20, 	/* 339E0 */
+	0x17,  0xFF,  0x30,  0x00,  0xA3,  0x10,  0x20,  0x11,  0x22,  0x11,  0x22,  0x11,  0x22,  0x7D,  0xFE,  0x10, 	/* 339F0 */
+	0x00,  0x13,  0xFF,  0x10,  0x20,  0x1C,  0x40,  0x73,  0xFE,  0x12,  0x52,  0x12,  0x52,  0x12,  0x52,  0x12, 	/* 33A00 */
+	0x52,  0x12,  0x52,  0x32,  0x06,  0xA9,  0x11,  0x10,  0x11,  0x10,  0x11,  0x12,  0x11,  0xDC,  0x7D,  0x10, 	/* 33A10 */
+	0x11,  0x11,  0x11,  0xCF,  0x17,  0x20,  0x18,  0x40,  0x71,  0xFC,  0x11,  0x04,  0x11,  0xFC,  0x11,  0x04, 	/* 33A20 */
+	0x11,  0x04,  0x11,  0xFC,  0x30,  0x00,  0xAE,  0x10,  0x00,  0x13,  0xFE,  0x12,  0x22,  0x12,  0x22,  0x7D, 	/* 33A30 */
+	0xFE,  0x10,  0x20,  0x11,  0xFC,  0x11,  0x24,  0x1D,  0xFC,  0x71,  0x24,  0x11,  0x24,  0x11,  0xFC,  0x10, 	/* 33A40 */
+	0x20,  0x17,  0xFF,  0x10,  0x20,  0x30,  0x20,  0xB4,  0x10,  0x0C,  0x13,  0xF0,  0x11,  0x44,  0x7C,  0xA4, 	/* 33A50 */
+	0x10,  0xA8,  0x13,  0xFE,  0x10,  0x40,  0x13,  0xFF,  0x1C,  0x40,  0x70,  0xFC,  0x11,  0x84,  0x16,  0xC8, 	/* 33A60 */
+	0x10,  0x30,  0x10,  0x50,  0x11,  0x8C,  0x36,  0x03,  0xB6,  0x10,  0x00,  0x17,  0xFE,  0x12,  0x52,  0x12, 	/* 33A70 */
+	0x52,  0x7E,  0x54,  0x13,  0xD8,  0x12,  0x54,  0x12,  0x52,  0x1B,  0xD2,  0x72,  0x51,  0x12,  0x51,  0x12, 	/* 33A80 */
+	0x59,  0x13,  0xD6,  0x16,  0x50,  0x10,  0x50,  0x30,  0x50,  0xBA,  0x10,  0x06,  0x10,  0x18,  0x13,  0xE2, 	/* 33A90 */
+	0x11,  0x22,  0x7C,  0x94,  0x10,  0x94,  0x11,  0xFE,  0x10,  0x20,  0x10,  0x20,  0x1F,  0xFF,  0x70,  0x20, 	/* 33AA0 */
+	0x11,  0x22,  0x11,  0x22,  0x11,  0x22,  0x11,  0xFE,  0x31,  0x02,  0x86,  0x10,  0x88,  0x10,  0x88,  0x13, 	/* 33AB0 */
+	0xFE,  0x10,  0x88,  0x7D,  0xFE,  0x10,  0x88,  0x17,  0xFF,  0x10,  0x20,  0x1D,  0xFC,  0x71,  0x24,  0x11, 	/* 33AC0 */
+	0xFC,  0x11,  0x24,  0x17,  0xFF,  0x11,  0x04,  0x11,  0x04,  0x31,  0x0C,  0x8D,  0x10,  0x00,  0x13,  0xFC, 	/* 33AD0 */
+	0x12,  0x04,  0x12,  0x04,  0x7F,  0xFC,  0x10,  0x00,  0x13,  0xFC,  0x12,  0x04,  0x1F,  0xFC,  0x72,  0x04, 	/* 33AE0 */
+	0x13,  0xFC,  0x12,  0x04,  0x13,  0xFC,  0x10,  0x88,  0x13,  0x04,  0x3C,  0x02,  0x8F,  0x10,  0x24,  0x10, 	/* 33AF0 */
+	0x22,  0x13,  0xFF,  0x10,  0x20,  0x7D,  0xFC,  0x11,  0x24,  0x11,  0xFC,  0x11,  0x24,  0x1D,  0xFC,  0x71, 	/* 33B00 */
+	0x24,  0x11,  0x2C,  0x10,  0x08,  0x17,  0xFF,  0x11,  0x08,  0x10,  0x88,  0x30,  0x18,  0x93,  0x11,  0x04, 	/* 33B10 */
+	0x10,  0x88,  0x13,  0xFE,  0x10,  0x20,  0x7C,  0x20,  0x11,  0xFC,  0x10,  0x20,  0x1F,  0xFF,  0x10,  0x40, 	/* 33B20 */
+	0x70,  0x40,  0x10,  0xFE,  0x11,  0x10,  0x12,  0x10,  0x1C,  0x10,  0x11,  0xFF,  0x30,  0x00,  0x96,  0x10, 	/* 33B30 */
+	0x20,  0x10,  0x7C,  0x10,  0xC4,  0x13,  0x28,  0x7C,  0x90,  0x10,  0x60,  0x11,  0x80,  0x16,  0xFC,  0x19, 	/* 33B40 */
+	0x20,  0x72,  0x20,  0x17,  0xFF,  0x10,  0x20,  0x12,  0x24,  0x12,  0x24,  0x13,  0xFC,  0x30,  0x00,  0x97, 	/* 33B50 */
+	0x10,  0x20,  0x10,  0x40,  0x11,  0xF8,  0x11,  0x08,  0x7D,  0xF8,  0x11,  0x08,  0x11,  0xF8,  0x11,  0x00, 	/* 33B60 */
+	0x1D,  0xFF,  0x71,  0x00,  0x11,  0xFE,  0x10,  0x82,  0x14,  0x92,  0x14,  0x92,  0x17,  0xF2,  0x30,  0x0C, 	/* 33B70 */
+	0x9C,  0x10,  0x20,  0x10,  0x60,  0x11,  0xAE,  0x11,  0x22,  0x7D,  0x22,  0x11,  0xAE,  0x11,  0x22,  0x11, 	/* 33B80 */
+	0x22,  0x1D,  0xFE,  0x70,  0x20,  0x13,  0xFE,  0x10,  0x84,  0x10,  0x48,  0x10,  0x30,  0x10,  0xCC,  0x37, 	/* 33B90 */
+	0x03,  0xA6,  0x10,  0x00,  0x17,  0xDE,  0x10,  0x42,  0x7C,  0x42,  0x13,  0xDE,  0x12,  0x10,  0x12,  0x10, 	/* 33BA0 */
+	0x13,  0xDE,  0x1C,  0xC6,  0x71,  0x4A,  0x12,  0x52,  0x10,  0xC6,  0x11,  0x4A,  0x12,  0x52,  0x10,  0x82, 	/* 33BB0 */
+	0x33,  0x0C,  0xA8,  0x10,  0x00,  0x11,  0xFC,  0x11,  0x04,  0x11,  0xFC,  0x7D,  0x04,  0x11,  0xFC,  0x10, 	/* 33BC0 */
+	0x00,  0x13,  0xDE,  0x1C,  0xC6,  0x71,  0x4A,  0x16,  0x72,  0x10,  0xC6,  0x11,  0x4A,  0x16,  0x72,  0x10, 	/* 33BD0 */
+	0x42,  0x30,  0xC6,  0xAC,  0x10,  0x80,  0x11,  0x1C,  0x13,  0xD4,  0x12,  0x55,  0x7B,  0x55,  0x12,  0xE3, 	/* 33BE0 */
+	0x12,  0x40,  0x17,  0xFE,  0x1A,  0x52,  0x73,  0x52,  0x12,  0xCA,  0x12,  0xCC,  0x12,  0x44,  0x14,  0x4C, 	/* 33BF0 */
+	0x14,  0x52,  0x38,  0xE1,  0xAD,  0x10,  0x88,  0x10,  0x88,  0x17,  0xFF,  0x10,  0x88,  0x7C,  0x20,  0x10, 	/* 33C00 */
+	0x20,  0x10,  0x50,  0x10,  0x88,  0x11,  0xFC,  0x1E,  0x03,  0x70,  0x00,  0x11,  0xFC,  0x11,  0x04,  0x11, 	/* 33C10 */
+	0x04,  0x11,  0xFC,  0x30,  0x00,  0xB4,  0x00,  0x80,  0x3F,  0xFE,  0x22,  0x22,  0x2F,  0xFA,  0x02,  0x20, 	/* 33C20 */
+	0x0F,  0xF8,  0x02,  0x20,  0x7F,  0xFF,  0x04,  0x30,  0x1B,  0xCC,  0x60,  0x83,  0x0F,  0xF8,  0x00,  0x80, 	/* 33C30 */
+	0x7F,  0xFF,  0x00,  0x80,  0x01,  0x80,  0xB6,  0x10,  0x20,  0x10,  0x20,  0x10,  0x50,  0x7C,  0x88,  0x11, 	/* 33C40 */
+	0xFC,  0x12,  0x02,  0x15,  0xFD,  0x11,  0x04,  0x1D,  0xFC,  0x71,  0x04,  0x11,  0xFC,  0x11,  0x00,  0x12, 	/* 33C50 */
+	0xFE,  0x12,  0x82,  0x14,  0xFE,  0x30,  0x00,  0xBA,  0x10,  0x88,  0x10,  0x90,  0x11,  0xFE,  0x13,  0x10, 	/* 33C60 */
+	0x7D,  0xFC,  0x11,  0x10,  0x11,  0xFC,  0x11,  0x10,  0x1D,  0xFE,  0x70,  0x00,  0x17,  0xF8,  0x10,  0x48, 	/* 33C70 */
+	0x10,  0x4E,  0x10,  0x82,  0x11,  0x02,  0x36,  0x0C,  0xBE,  0x10,  0x40,  0x10,  0x40,  0x13,  0xFE,  0x12, 	/* 33C80 */
+	0x92,  0x7E,  0x92,  0x10,  0x91,  0x11,  0x0F,  0x12,  0x80,  0x1C,  0xFF,  0x71,  0x20,  0x11,  0x3E,  0x12, 	/* 33C90 */
+	0x20,  0x14,  0x3E,  0x10,  0x20,  0x10,  0x20,  0x30,  0x20,  0x82,  0x10,  0x00,  0x13,  0xFE,  0x10,  0x88, 	/* 33CA0 */
+	0x10,  0xF8,  0x7C,  0x88,  0x10,  0xF8,  0x10,  0x88,  0x10,  0xFE,  0x1F,  0x08,  0x70,  0x04,  0x11,  0x88, 	/* 33CB0 */
+	0x10,  0x50,  0x10,  0x00,  0x10,  0x58,  0x11,  0x84,  0x36,  0x02,  0x8E,  0x10,  0x00,  0x13,  0xDE,  0x11, 	/* 33CC0 */
+	0x4A,  0x12,  0x52,  0x7C,  0xC6,  0x11,  0x4A,  0x16,  0x72,  0x10,  0x56,  0x1C,  0x88,  0x71,  0x24,  0x16, 	/* 33CD0 */
+	0x4B,  0x11,  0x90,  0x10,  0x64,  0x13,  0x88,  0x10,  0x30,  0x33,  0xC0,  0x98,  0x10,  0x20,  0x10,  0x20, 	/* 33CE0 */
+	0x13,  0xFF,  0x10,  0x88,  0x7C,  0x50,  0x13,  0xFE,  0x12,  0x22,  0x12,  0x22,  0x1F,  0xFE,  0x72,  0x22, 	/* 33CF0 */
+	0x12,  0xFA,  0x12,  0x8A,  0x12,  0x8A,  0x12,  0xFA,  0x12,  0x02,  0x32,  0x06,  0xA7,  0x10,  0x20,  0x11, 	/* 33D00 */
+	0x22,  0x11,  0x22,  0x11,  0xFE,  0x7C,  0x88,  0x10,  0x90,  0x11,  0xFE,  0x13,  0x10,  0x1D,  0x10,  0x71, 	/* 33D10 */
+	0xFE,  0x11,  0x10,  0x11,  0xFE,  0x11,  0x10,  0x11,  0x10,  0x11,  0xFF,  0x30,  0x00,  0xA9,  0x00,  0x80, 	/* 33D20 */
+	0x00,  0x80,  0x1F,  0xFE,  0x11,  0x08,  0x1F,  0xFE,  0x13,  0x1C,  0x15,  0xAA,  0x19,  0x49,  0x11,  0x18, 	/* 33D30 */
+	0x13,  0xE0,  0x10,  0x40,  0x17,  0xFE,  0x20,  0x40,  0x3F,  0xFF,  0x40,  0x40,  0x00,  0xC0,  0xAF,  0x04, 	/* 33D40 */
+	0x10,  0x3F,  0x10,  0x04,  0x7C,  0x7F,  0x94,  0x12,  0x54,  0x7F,  0x24,  0x04,  0x55,  0x3F,  0x95,  0x04, 	/* 33D50 */
+	0x33,  0x07,  0xC0,  0x00,  0x80,  0x1F,  0xFC,  0x00,  0x80,  0x7F,  0xFF,  0x00,  0x80,  0x01,  0x80,  0xB6, 	/* 33D60 */
+	0x10,  0x28,  0x10,  0x24,  0x13,  0xFF,  0x10,  0x20,  0x7D,  0xFC,  0x11,  0x24,  0x11,  0xFC,  0x11,  0x24, 	/* 33D70 */
+	0x1D,  0xFC,  0x71,  0x24,  0x11,  0x24,  0x10,  0x08,  0x17,  0xFF,  0x11,  0x08,  0x10,  0x88,  0x30,  0x18, 	/* 33D80 */
+	0xB8,  0x10,  0x48,  0x10,  0x48,  0x13,  0xFF,  0x10,  0x48,  0x7C,  0x48,  0x10,  0xFC,  0x10,  0x84,  0x10, 	/* 33D90 */
+	0xFC,  0x10,  0x84,  0x1C,  0xFC,  0x70,  0x20,  0x13,  0xFF,  0x10,  0x20,  0x10,  0x50,  0x10,  0x8C,  0x33, 	/* 33DA0 */
+	0x03,  0xBA,  0x10,  0x00,  0x17,  0xFE,  0x12,  0x52,  0x11,  0x4A,  0x7C,  0xC6,  0x11,  0x4A,  0x16,  0x72, 	/* 33DB0 */
+	0x10,  0xC6,  0x1C,  0x20,  0x71,  0xFC,  0x11,  0x04,  0x11,  0xFC,  0x11,  0x04,  0x11,  0x04,  0x11,  0xFC, 	/* 33DC0 */
+	0x30,  0x00,  0x83,  0x08,  0x3C,  0x7F,  0xA5,  0x29,  0x25,  0x3F,  0x43,  0x29,  0xFC,  0x3F,  0x24,  0x08, 	/* 33DD0 */
+	0x18,  0x7F,  0xA4,  0x08,  0x53,  0x07,  0xE0,  0x00,  0x80,  0x1F,  0xFC,  0x00,  0x80,  0x7F,  0xFF,  0x00, 	/* 33DE0 */
+	0x80,  0x01,  0x80,  0x88,  0x10,  0x88,  0x12,  0xAA,  0x12,  0xAA,  0x14,  0x8C,  0x7D,  0x54,  0x11,  0x22, 	/* 33DF0 */
+	0x12,  0x01,  0x17,  0xFE,  0x1C,  0x02,  0x74,  0x42,  0x13,  0xFC,  0x10,  0x44,  0x10,  0x44,  0x10,  0x84, 	/* 33E00 */
+	0x11,  0x04,  0x36,  0x18,  0x92,  0x12,  0x90,  0x12,  0x90,  0x17,  0xD0,  0x12,  0x9F,  0x7A,  0x94,  0x17, 	/* 33E10 */
+	0xF4,  0x10,  0x24,  0x13,  0xD4,  0x1E,  0x54,  0x73,  0xD4,  0x12,  0x48,  0x13,  0xCC,  0x12,  0x54,  0x12, 	/* 33E20 */
+	0x52,  0x12,  0x62,  0x32,  0xC1,  0x93,  0x10,  0x20,  0x10,  0xF8,  0x10,  0x20,  0x13,  0xFE,  0x7C,  0x00, 	/* 33E30 */
+	0x10,  0x84,  0x13,  0xFF,  0x10,  0x84,  0x1C,  0xE4,  0x73,  0x9F,  0x10,  0x00,  0x13,  0xFF,  0x10,  0x48, 	/* 33E40 */
+	0x10,  0x49,  0x10,  0x89,  0x37,  0x07,  0x95,  0x12,  0x42,  0x12,  0x44,  0x17,  0xF8,  0x12,  0x50,  0x7A, 	/* 33E50 */
+	0x50,  0x13,  0xDF,  0x12,  0x52,  0x12,  0x52,  0x1B,  0xD2,  0x72,  0x52,  0x12,  0x52,  0x17,  0xF2,  0x10, 	/* 33E60 */
+	0x92,  0x12,  0x62,  0x12,  0x42,  0x34,  0x02,  0x9A,  0x11,  0x08,  0x11,  0x0A,  0x11,  0xC9,  0x11,  0x7F, 	/* 33E70 */
+	0x7D,  0x48,  0x12,  0xC8,  0x12,  0x4C,  0x15,  0x94,  0x10,  0x92,  0x19,  0x22,  0x72,  0x41,  0x14,  0x00, 	/* 33E80 */
+	0x11,  0x52,  0x11,  0x52,  0x12,  0x49,  0x34,  0x49,  0x9E,  0x10,  0x20,  0x10,  0x20,  0x13,  0xFE,  0x10, 	/* 33E90 */
+	0x88,  0x7F,  0xFF,  0x10,  0x00,  0x11,  0xFC,  0x11,  0x24,  0x11,  0xFC,  0x1D,  0x24,  0x71,  0xFC,  0x10, 	/* 33EA0 */
+	0x20,  0x11,  0xFC,  0x10,  0x20,  0x17,  0xFF,  0x30,  0x00,  0xA4,  0x11,  0x08,  0x11,  0x08,  0x17,  0xE8, 	/* 33EB0 */
+	0x11,  0x8F,  0x7D,  0x54,  0x12,  0x54,  0x17,  0xA4,  0x10,  0x14,  0x13,  0xD4,  0x1E,  0x54,  0x73,  0xC8, 	/* 33EC0 */
+	0x12,  0x48,  0x13,  0xCC,  0x12,  0x54,  0x12,  0x62,  0x32,  0xC1,  0xA5,  0x10,  0x12,  0x13,  0xD4,  0x10, 	/* 33ED0 */
+	0x59,  0x10,  0x8A,  0x7C,  0x8C,  0x11,  0x04,  0x13,  0xBA,  0x14,  0xA9,  0x10,  0xAA,  0x77,  0xC6,  0x14, 	/* 33EE0 */
+	0x7C,  0x17,  0xA4,  0x10,  0xA8,  0x10,  0x98,  0x10,  0xA4,  0x33,  0x43,  0xA9,  0x10,  0x20,  0x10,  0x20, 	/* 33EF0 */
+	0x13,  0xFF,  0x10,  0x50,  0x7D,  0x4A,  0x10,  0x84,  0x11,  0xFE,  0x13,  0x05,  0x1D,  0xFC,  0x71,  0x04, 	/* 33F00 */
+	0x11,  0xFC,  0x10,  0x28,  0x10,  0xA4,  0x11,  0x22,  0x12,  0x22,  0x30,  0x60,  0xAB,  0x10,  0x80,  0x10, 	/* 33F10 */
+	0x80,  0x11,  0xFF,  0x13,  0x54,  0x7D,  0x54,  0x11,  0x54,  0x13,  0xFF,  0x11,  0x54,  0x11,  0x54,  0x1D, 	/* 33F20 */
+	0x54,  0x73,  0xFF,  0x10,  0x00,  0x11,  0x04,  0x11,  0x92,  0x12,  0x49,  0x34,  0x49,  0xAD,  0x10,  0x0C, 	/* 33F30 */
+	0x11,  0xF0,  0x11,  0x24,  0x7C,  0xA8,  0x17,  0xFF,  0x10,  0x70,  0x10,  0xA8,  0x11,  0x24,  0x1F,  0xFE, 	/* 33F40 */
+	0x71,  0x25,  0x11,  0x24,  0x11,  0xFC,  0x11,  0x24,  0x11,  0x24,  0x11,  0xFC,  0x30,  0x00,  0xAE,  0x10, 	/* 33F50 */
+	0x00,  0x11,  0xFC,  0x11,  0x04,  0x11,  0xFC,  0x7D,  0x04,  0x11,  0xFC,  0x10,  0x00,  0x17,  0xFF,  0x1E, 	/* 33F60 */
+	0x40,  0x73,  0xFE,  0x12,  0x52,  0x13,  0xD4,  0x12,  0x6C,  0x13,  0xCA,  0x16,  0x71,  0x30,  0x40,  0xB0, 	/* 33F70 */
+	0x10,  0x00,  0x13,  0xDE,  0x10,  0x42,  0x13,  0xDE,  0x7E,  0x10,  0x12,  0x31,  0x11,  0xEF,  0x10,  0x00, 	/* 33F80 */
+	0x1C,  0x88,  0x73,  0xFE,  0x10,  0x88,  0x10,  0x88,  0x17,  0xFF,  0x10,  0x88,  0x11,  0x04,  0x36,  0x02, 	/* 33F90 */
+	0xB2,  0x10,  0x50,  0x12,  0x52,  0x11,  0x54,  0x10,  0x50,  0x7F,  0xFF,  0x10,  0x88,  0x10,  0x50,  0x13, 	/* 33FA0 */
+	0xFE,  0x1C,  0x20,  0x71,  0xFC,  0x10,  0x20,  0x13,  0xFF,  0x10,  0x50,  0x10,  0x88,  0x13,  0x04,  0x3C, 	/* 33FB0 */
+	0x03,  0xB9,  0x12,  0x44,  0x11,  0x24,  0x11,  0x28,  0x17,  0xFE,  0x7C,  0x02,  0x15,  0xFA,  0x11,  0x08, 	/* 33FC0 */
+	0x11,  0xF8,  0x1D,  0x08,  0x71,  0xF8,  0x11,  0x08,  0x11,  0xF8,  0x10,  0x50,  0x10,  0x91,  0x13,  0x11, 	/* 33FD0 */
+	0x3C,  0x0F,  0xBB,  0x10,  0x10,  0x12,  0x10,  0x11,  0x7C,  0x11,  0x10,  0x7C,  0xFF,  0x12,  0x44,  0x12, 	/* 33FE0 */
+	0x28,  0x10,  0xFF,  0x17,  0x10,  0x19,  0x7E,  0x71,  0x10,  0x11,  0x7E,  0x11,  0x10,  0x12,  0x90,  0x14, 	/* 33FF0 */
+	0x60,  0x38,  0x1F,  0xBC,  0x10,  0x14,  0x10,  0x12,  0x13,  0xFF,  0x12,  0x10,  0x7B,  0xF2,  0x12,  0x0A, 	/* 34000 */
+	0x12,  0xEC,  0x12,  0xAC,  0x1E,  0xF5,  0x72,  0x23,  0x14,  0xD1,  0x11,  0x08,  0x11,  0x4A,  0x12,  0x41, 	/* 34010 */
+	0x14,  0x45,  0x30,  0x3C,  0x81,  0x10,  0x40,  0x10,  0x40,  0x17,  0xFF,  0x11,  0x12,  0x7D,  0x14,  0x11, 	/* 34020 */
+	0x3F,  0x16,  0xE4,  0x12,  0xA4,  0x19,  0x3E,  0x71,  0xA4,  0x12,  0xA4,  0x17,  0xBE,  0x10,  0xA4,  0x11, 	/* 34030 */
+	0x24,  0x11,  0x3F,  0x32,  0x20,  0x82,  0x10,  0x00,  0x11,  0xFE,  0x10,  0x20,  0x13,  0xFF,  0x7E,  0x21, 	/* 34040 */
+	0x13,  0xAD,  0x12,  0x21,  0x11,  0xAC,  0x1C,  0x00,  0x71,  0xFE,  0x11,  0x22,  0x11,  0xFE,  0x11,  0x22, 	/* 34050 */
+	0x11,  0x22,  0x11,  0xFE,  0x30,  0x00,  0x85,  0x10,  0x20,  0x13,  0xFF,  0x10,  0x00,  0x11,  0xFE,  0x7D, 	/* 34060 */
+	0x7A,  0x11,  0x4A,  0x11,  0x7A,  0x11,  0x02,  0x1D,  0xFE,  0x70,  0x84,  0x10,  0xFC,  0x10,  0x84,  0x10, 	/* 34070 */
+	0xFC,  0x10,  0x00,  0x17,  0xFF,  0x30,  0x00,  0x87,  0x10,  0x00,  0x13,  0xFE,  0x12,  0x92,  0x13,  0xFE, 	/* 34080 */
+	0x7C,  0x20,  0x11,  0xFC,  0x10,  0x20,  0x17,  0xFF,  0x1D,  0x08,  0x70,  0x90,  0x13,  0xFE,  0x10,  0x20, 	/* 34090 */
+	0x13,  0xFE,  0x10,  0x20,  0x10,  0x20,  0x30,  0x20,  0x8D,  0x10,  0x00,  0x10,  0xF8,  0x10,  0x88,  0x10, 	/* 340A0 */
+	0x88,  0x7C,  0xF8,  0x13,  0xDE,  0x12,  0x52,  0x12,  0x52,  0x1F,  0xDE,  0x70,  0x20,  0x17,  0xFE,  0x10, 	/* 340B0 */
+	0x70,  0x10,  0xA8,  0x11,  0x24,  0x16,  0x22,  0x30,  0x20,  0x92,  0x10,  0x20,  0x10,  0x20,  0x10,  0x50, 	/* 340C0 */
+	0x7D,  0xAC,  0x17,  0xFF,  0x11,  0x54,  0x11,  0x24,  0x11,  0x54,  0x1D,  0xFC,  0x70,  0x20,  0x13,  0xFE, 	/* 340D0 */
+	0x12,  0x22,  0x12,  0x5A,  0x13,  0xF6,  0x12,  0x02,  0x32,  0x06,  0x94,  0x10,  0x40,  0x10,  0xF8,  0x11, 	/* 340E0 */
+	0x10,  0x13,  0xFF,  0x7E,  0x48,  0x12,  0x47,  0x12,  0xBC,  0x13,  0x00,  0x1F,  0xFF,  0x72,  0x00,  0x12, 	/* 340F0 */
+	0x7C,  0x12,  0x00,  0x14,  0xFE,  0x14,  0x82,  0x18,  0xFE,  0x30,  0x00,  0x98,  0x00,  0x08,  0x1F,  0x7E, 	/* 34100 */
+	0x11,  0x24,  0x1F,  0x28,  0x10,  0xFF,  0x1F,  0x08,  0x29,  0x7E,  0x2F,  0x08,  0x40,  0x28,  0x07,  0xC0, 	/* 34110 */
+	0x00,  0x80,  0x1F,  0xFC,  0x00,  0x80,  0x7F,  0xFF,  0x00,  0x80,  0x01,  0x80,  0x9A,  0x10,  0x20,  0x10, 	/* 34120 */
+	0x3E,  0x10,  0x20,  0x13,  0xFF,  0x7E,  0x4A,  0x13,  0xF0,  0x12,  0x44,  0x12,  0x3C,  0x1F,  0xFF,  0x72, 	/* 34130 */
+	0x62,  0x13,  0xB4,  0x12,  0x58,  0x15,  0xB4,  0x14,  0x52,  0x1B,  0x91,  0x30,  0x30,  0xA0,  0x10,  0x20, 	/* 34140 */
+	0x10,  0x20,  0x17,  0xFF,  0x10,  0x51,  0x7F,  0xAE,  0x12,  0xAA,  0x12,  0xAA,  0x15,  0xAD,  0x18,  0x00, 	/* 34150 */
+	0x71,  0x04,  0x11,  0xFC,  0x11,  0x04,  0x11,  0xFC,  0x11,  0x04,  0x12,  0x04,  0x34,  0x04,  0xA1,  0x10, 	/* 34160 */
+	0x20,  0x17,  0xFF,  0x10,  0x20,  0x13,  0xFE,  0x7D,  0x04,  0x11,  0xFC,  0x10,  0x00,  0x17,  0xFF,  0x14, 	/* 34170 */
+	0x01,  0x1F,  0xFE,  0x70,  0x98,  0x13,  0xF4,  0x10,  0x20,  0x11,  0xFC,  0x10,  0x20,  0x37,  0xFF,  0xA2, 	/* 34180 */
+	0x10,  0x00,  0x13,  0xDE,  0x10,  0x42,  0x13,  0xDE,  0x7C,  0x42,  0x13,  0xDE,  0x10,  0x88,  0x10,  0x90, 	/* 34190 */
+	0x1D,  0xFE,  0x73,  0x20,  0x15,  0xFC,  0x11,  0x20,  0x11,  0xFC,  0x11,  0x20,  0x11,  0xFF,  0x30,  0x00, 	/* 341A0 */
+	0xA3,  0x10,  0x20,  0x13,  0xFE,  0x10,  0x20,  0x11,  0xFC,  0x7C,  0x00,  0x17,  0xFF,  0x10,  0x02,  0x11, 	/* 341B0 */
+	0xFC,  0x18,  0x20,  0x77,  0xFF,  0x10,  0x04,  0x13,  0xFF,  0x12,  0x64,  0x12,  0x54,  0x13,  0xC4,  0x30, 	/* 341C0 */
+	0x0C,  0xA6,  0x10,  0x20,  0x10,  0x20,  0x13,  0xFF,  0x12,  0x81,  0x7E,  0xFF,  0x11,  0x52,  0x16,  0xCC, 	/* 341D0 */
+	0x11,  0x94,  0x1D,  0x22,  0x72,  0xFD,  0x14,  0x00,  0x13,  0xFE,  0x10,  0xA4,  0x11,  0x22,  0x16,  0x21, 	/* 341E0 */
+	0x30,  0x60,  0xA7,  0x02,  0x80,  0x1C,  0xDC,  0x10,  0x84,  0x1C,  0xDC,  0x10,  0x44,  0x1D,  0x5C,  0x11, 	/* 341F0 */
+	0x44,  0x7F,  0xFF,  0x08,  0x28,  0x13,  0xC4,  0x20,  0x82,  0x4F,  0xF9,  0x00,  0x80,  0x3F,  0xFE,  0x00, 	/* 34200 */
+	0x80,  0x01,  0x80,  0xAC,  0x12,  0x00,  0x12,  0x7E,  0x13,  0x82,  0x12,  0x14,  0x7A,  0x48,  0x11,  0xFF, 	/* 34210 */
+	0x12,  0x09,  0x13,  0xCA,  0x15,  0x28,  0x79,  0x2E,  0x17,  0xE8,  0x11,  0x28,  0x11,  0xB8,  0x12,  0x68, 	/* 34220 */
+	0x14,  0x44,  0x38,  0x83,  0xAF,  0x10,  0x20,  0x13,  0xFF,  0x12,  0x01,  0x11,  0xFE,  0x7C,  0xA4,  0x11, 	/* 34230 */
+	0x28,  0x16,  0x70,  0x10,  0xFC,  0x19,  0x84,  0x76,  0xFC,  0x10,  0x84,  0x10,  0xFC,  0x10,  0x84,  0x10, 	/* 34240 */
+	0xFC,  0x10,  0xC4,  0x33,  0x02,  0xB1,  0x10,  0x00,  0x13,  0xDE,  0x12,  0x52,  0x13,  0xDE,  0x7E,  0x52, 	/* 34250 */
+	0x13,  0xDE,  0x12,  0x22,  0x12,  0x3A,  0x1E,  0x4A,  0x72,  0xB2,  0x12,  0x4A,  0x12,  0xFE,  0x13,  0x4A, 	/* 34260 */
+	0x12,  0x4A,  0x12,  0x7A,  0x32,  0x06,  0xB2,  0x11,  0x60,  0x11,  0x2E,  0x13,  0xEA,  0x14,  0x9A,  0x7B, 	/* 34270 */
+	0xEA,  0x12,  0xAC,  0x13,  0x6C,  0x12,  0x2A,  0x1B,  0xE9,  0x72,  0x29,  0x13,  0xE9,  0x10,  0x89,  0x17, 	/* 34280 */
+	0xFE,  0x11,  0x48,  0x12,  0x28,  0x34,  0x08,  0xB4,  0x10,  0x10,  0x10,  0x10,  0x13,  0xFF,  0x12,  0x48, 	/* 34290 */
+	0x7F,  0xFE,  0x12,  0x48,  0x12,  0x78,  0x13,  0xFF,  0x1E,  0x10,  0x72,  0xFE,  0x12,  0x92,  0x12,  0xFE, 	/* 342A0 */
+	0x12,  0x92,  0x12,  0xFE,  0x14,  0x66,  0x31,  0x81,  0xB6,  0x11,  0x08,  0x11,  0x08,  0x11,  0xEF,  0x12, 	/* 342B0 */
+	0x94,  0x7C,  0x22,  0x10,  0x88,  0x17,  0xFF,  0x10,  0x00,  0x13,  0xD2,  0x1E,  0x52,  0x73,  0xD2,  0x12, 	/* 342C0 */
+	0x52,  0x13,  0xD2,  0x12,  0x52,  0x12,  0x42,  0x32,  0xC6,  0xBA,  0x10,  0x00,  0x13,  0xFE,  0x12,  0x52, 	/* 342D0 */
+	0x13,  0xFE,  0x7C,  0x90,  0x11,  0x52,  0x17,  0xBC,  0x10,  0x10,  0x1F,  0xD1,  0x72,  0x4F,  0x13,  0xD0, 	/* 342E0 */
+	0x12,  0x52,  0x13,  0xDC,  0x12,  0x50,  0x12,  0x51,  0x32,  0xCF,  0xBD,  0x11,  0x22,  0x11,  0x42,  0x12, 	/* 342F0 */
+	0xFD,  0x12,  0xCD,  0x7D,  0x7A,  0x11,  0x4A,  0x13,  0x4E,  0x12,  0xFD,  0x1B,  0xAF,  0x70,  0x20,  0x13, 	/* 34300 */
+	0xFF,  0x10,  0x68,  0x10,  0xA4,  0x11,  0x22,  0x16,  0x21,  0x30,  0x20,  0xBE,  0x10,  0x00,  0x13,  0xFF, 	/* 34310 */
+	0x10,  0x20,  0x10,  0xFC,  0x7C,  0x84,  0x10,  0xFC,  0x10,  0x84,  0x13,  0xFF,  0x1E,  0x55,  0x71,  0x4A, 	/* 34320 */
+	0x12,  0x7D,  0x14,  0x89,  0x13,  0x50,  0x10,  0x30,  0x10,  0xCC,  0x37,  0x03,  0x80,  0x08,  0x48,  0x3F, 	/* 34330 */
+	0x7F,  0x08,  0x8C,  0x1D,  0x5A,  0x2B,  0x69,  0x48,  0x88,  0x0B,  0x48,  0x7F,  0xFF,  0x02,  0x30,  0x0F, 	/* 34340 */
+	0xCC,  0x70,  0x83,  0x0F,  0xF8,  0x00,  0x80,  0x7F,  0xFF,  0x00,  0x80,  0x01,  0x80,  0x85,  0x10,  0x84, 	/* 34350 */
+	0x13,  0xFF,  0x10,  0x84,  0x13,  0xFF,  0x7C,  0x84,  0x11,  0x4A,  0x12,  0x31,  0x11,  0xFC,  0x1D,  0x04, 	/* 34360 */
+	0x71,  0xFC,  0x11,  0x04,  0x11,  0xFC,  0x11,  0x04,  0x11,  0xFC,  0x10,  0xCC,  0x37,  0x03,  0x98,  0x10, 	/* 34370 */
+	0x20,  0x13,  0xFF,  0x10,  0x00,  0x11,  0xCE,  0x7D,  0x4A,  0x11,  0xCE,  0x10,  0x48,  0x11,  0xFE,  0x1C, 	/* 34380 */
+	0x48,  0x71,  0xFE,  0x10,  0x48,  0x13,  0xFF,  0x10,  0xD2,  0x17,  0x8C,  0x10,  0xE4,  0x33,  0x83,  0x9C, 	/* 34390 */
+	0x11,  0x12,  0x11,  0x12,  0x11,  0xFE,  0x10,  0x88,  0x7D,  0xFE,  0x13,  0x10,  0x11,  0xFE,  0x11,  0x10, 	/* 343A0 */
+	0x1D,  0xFE,  0x71,  0x10,  0x13,  0xFF,  0x12,  0x52,  0x12,  0xFE,  0x13,  0x52,  0x12,  0x72,  0x32,  0x06, 	/* 343B0 */
+	0x9D,  0x10,  0x00,  0x13,  0xFE,  0x10,  0x88,  0x7C,  0xF8,  0x10,  0x88,  0x10,  0xFE,  0x13,  0x88,  0x10, 	/* 343C0 */
+	0x08,  0x1F,  0xFF,  0x72,  0x52,  0x13,  0xDE,  0x12,  0x52,  0x13,  0xDE,  0x12,  0x53,  0x17,  0xFE,  0x30, 	/* 343D0 */
+	0x42,  0xA3,  0x08,  0x84,  0x0B,  0xF4,  0x74,  0x1A,  0x15,  0xEA,  0x0A,  0x05,  0x7F,  0xFF,  0x09,  0x24, 	/* 343E0 */
+	0x2D,  0xF6,  0x2A,  0x15,  0x49,  0xE4,  0x00,  0x80,  0x1F,  0xFC,  0x00,  0x80,  0x7F,  0xFF,  0x00,  0x80, 	/* 343F0 */
+	0x01,  0x80,  0xA4,  0x12,  0x88,  0x1F,  0xEA,  0x12,  0x92,  0x13,  0x9F,  0x79,  0x34,  0x17,  0xD4,  0x15, 	/* 34400 */
+	0x54,  0x17,  0xDF,  0x19,  0x14,  0x77,  0xF4,  0x11,  0x1F,  0x1F,  0xF4,  0x12,  0x94,  0x12,  0x54,  0x14, 	/* 34410 */
+	0x5F,  0x38,  0x00,  0xAA,  0x10,  0x40,  0x11,  0xDC,  0x11,  0x24,  0x11,  0xDC,  0x7D,  0x24,  0x11,  0xDC, 	/* 34420 */
+	0x17,  0xFF,  0x14,  0x01,  0x1D,  0xFD,  0x71,  0x04,  0x11,  0xFC,  0x11,  0x04,  0x11,  0xFC,  0x10,  0x50, 	/* 34430 */
+	0x11,  0x91,  0x36,  0x0F,  0xAB,  0x13,  0xDE,  0x12,  0x52,  0x13,  0xDE,  0x12,  0x52,  0x7F,  0xDE,  0x12, 	/* 34440 */
+	0x52,  0x13,  0xFE,  0x13,  0x10,  0x1D,  0xFC,  0x71,  0x10,  0x11,  0xFC,  0x11,  0x10,  0x13,  0xFE,  0x10, 	/* 34450 */
+	0xC8,  0x10,  0x30,  0x37,  0xCF,  0xAC,  0x10,  0x08,  0x13,  0xEF,  0x12,  0x90,  0x13,  0xEF,  0x7E,  0x40, 	/* 34460 */
+	0x13,  0xDF,  0x12,  0x95,  0x13,  0xFF,  0x1D,  0x04,  0x71,  0xF4,  0x11,  0x7C,  0x11,  0x04,  0x11,  0xFC, 	/* 34470 */
+	0x10,  0x51,  0x11,  0x91,  0x36,  0x0F,  0xAF,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x7F,  0xFF,  0x00, 	/* 34480 */
+	0x80,  0x00,  0x80,  0x1F,  0xF0,  0x04,  0x10,  0x04,  0x10,  0x02,  0x20,  0x01,  0x40,  0x00,  0x80,  0x01, 	/* 34490 */
+	0x40,  0x02,  0x20,  0x0C,  0x18,  0x70,  0x07,  0xB4,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x00,  0xFF, 	/* 344A0 */
+	0x00,  0x80,  0x00,  0x80,  0x3F,  0xF8,  0x04,  0x08,  0x02,  0x10,  0x02,  0x10,  0x01,  0x20,  0x00,  0xC0, 	/* 344B0 */
+	0x00,  0xC0,  0x03,  0x20,  0x0C,  0x18,  0x70,  0x07,  0xB5,  0x04,  0x00,  0x04,  0x00,  0x04,  0x00,  0x07, 	/* 344C0 */
+	0xFF,  0x08,  0x10,  0x08,  0x10,  0x12,  0x10,  0x22,  0x10,  0x41,  0x20,  0x01,  0x20,  0x00,  0xC0,  0x00, 	/* 344D0 */
+	0xC0,  0x01,  0x20,  0x02,  0x10,  0x0C,  0x0C,  0x70,  0x03,  0xB6,  0x02,  0x40,  0x02,  0x40,  0x12,  0x40, 	/* 344E0 */
+	0x12,  0x7F,  0x12,  0x44,  0x12,  0x84,  0x12,  0xC4,  0x13,  0x44,  0x12,  0x48,  0x12,  0x28,  0x1E,  0x10, 	/* 344F0 */
+	0x62,  0x18,  0x02,  0x28,  0x02,  0x44,  0x03,  0x82,  0x02,  0x01,  0xB7,  0x00,  0x40,  0x7F,  0x40,  0x08, 	/* 34500 */
+	0x40,  0x08,  0x7F,  0x10,  0x44,  0x10,  0x84,  0x3E,  0xC4,  0x23,  0x44,  0x02,  0x28,  0x02,  0x28,  0x02, 	/* 34510 */
+	0x10,  0x02,  0x18,  0x04,  0x28,  0x04,  0x44,  0x04,  0x82,  0x1B,  0x01,  0xB8,  0x04,  0x40,  0x04,  0x40, 	/* 34520 */
+	0x04,  0x40,  0x0A,  0x7F,  0x0A,  0x44,  0x12,  0x84,  0x12,  0x84,  0x33,  0x24,  0x52,  0x28,  0x12,  0x38, 	/* 34530 */
+	0x12,  0x10,  0x12,  0x18,  0x12,  0x28,  0x10,  0x44,  0x11,  0x82,  0x16,  0x01,  0xB9,  0x00,  0x40,  0x00, 	/* 34540 */
+	0x40,  0x7E,  0x40,  0x02,  0x7F,  0x02,  0x44,  0x02,  0x44,  0x7E,  0xA4,  0x42,  0xA4,  0x41,  0x28,  0x40, 	/* 34550 */
+	0x28,  0x40,  0x10,  0x42,  0x18,  0x42,  0x28,  0x3E,  0x44,  0x00,  0x82,  0x03,  0x01,  0xBB,  0x00,  0x40, 	/* 34560 */
+	0x00,  0x40,  0x00,  0x40,  0x7E,  0x7F,  0x08,  0x84,  0x08,  0x84,  0x09,  0x44,  0x0A,  0x44,  0x08,  0x28, 	/* 34570 */
+	0x08,  0x28,  0x0E,  0x10,  0x18,  0x30,  0x60,  0x48,  0x00,  0x84,  0x01,  0x02,  0x06,  0x01,  0xBE,  0x08, 	/* 34580 */
+	0x20,  0x08,  0x20,  0x08,  0x20,  0x7F,  0xA0,  0x08,  0x7F,  0x08,  0x44,  0x0F,  0x44,  0x09,  0xA4,  0x09, 	/* 34590 */
+	0x24,  0x09,  0x14,  0x09,  0x18,  0x11,  0x08,  0x11,  0x14,  0x21,  0x24,  0x41,  0xC2,  0x06,  0x01,  0xBF, 	/* 345A0 */
+	0x00,  0x20,  0x00,  0x20,  0x7F,  0xA0,  0x04,  0x3F,  0x04,  0x44,  0x04,  0x44,  0x14,  0xC4,  0x17,  0x44, 	/* 345B0 */
+	0x14,  0x28,  0x14,  0x28,  0x14,  0x10,  0x15,  0x90,  0x16,  0x28,  0x18,  0x44,  0x61,  0x82,  0x06,  0x01, 	/* 345C0 */
+	0x85,  0x08,  0x40,  0x08,  0x40,  0x08,  0x40,  0x7F,  0x7F,  0x08,  0x44,  0x08,  0x84,  0x08,  0xC4,  0x09, 	/* 345D0 */
+	0x44,  0x3E,  0x28,  0x22,  0x28,  0x22,  0x10,  0x22,  0x18,  0x22,  0x28,  0x3E,  0xC4,  0x03,  0x02,  0x00, 	/* 345E0 */
+	0x01,  0x88,  0x08,  0x20,  0x08,  0x20,  0x08,  0x20,  0x7F,  0xBF,  0x12,  0x44,  0x11,  0x44,  0x23,  0x44, 	/* 345F0 */
+	0x2A,  0xA4,  0x4A,  0xA8,  0x04,  0x38,  0x06,  0x10,  0x09,  0x18,  0x11,  0x28,  0x20,  0x44,  0x41,  0x82, 	/* 34600 */
+	0x06,  0x01,  0x8D,  0x04,  0x10,  0x04,  0x10,  0x0A,  0x1F,  0x0A,  0x10,  0x11,  0x10,  0x3F,  0xFC,  0x44, 	/* 34610 */
+	0x04,  0x04,  0x24,  0x7F,  0xA4,  0x04,  0x24,  0x15,  0x18,  0x14,  0x88,  0x24,  0x98,  0x44,  0x24,  0x04, 	/* 34620 */
+	0x42,  0x0D,  0x81,  0x8F,  0x10,  0x20,  0x10,  0x20,  0x1F,  0xA0,  0x20,  0x3F,  0x3F,  0x24,  0x55,  0x44, 	/* 34630 */
+	0x15,  0x44,  0x15,  0xA4,  0x7F,  0xA4,  0x25,  0x18,  0x25,  0x18,  0x25,  0x08,  0x3F,  0x94,  0x01,  0x24, 	/* 34640 */
+	0x02,  0x42,  0x0C,  0x81,  0x91,  0x05,  0x20,  0x04,  0xA0,  0x04,  0x20,  0x7F,  0xBF,  0x04,  0x24,  0x44, 	/* 34650 */
+	0xA4,  0x25,  0x44,  0x25,  0x44,  0x0E,  0xA4,  0x0E,  0x28,  0x15,  0x18,  0x15,  0x10,  0x24,  0xA8,  0x44, 	/* 34660 */
+	0x44,  0x04,  0x82,  0x0D,  0x01,  0x95,  0x04,  0x20,  0x04,  0x20,  0x7F,  0xA0,  0x04,  0x3F,  0x04,  0x44, 	/* 34670 */
+	0x3F,  0x44,  0x25,  0x44,  0x25,  0xA4,  0x3F,  0x28,  0x04,  0x38,  0x0E,  0x10,  0x15,  0x18,  0x24,  0x28, 	/* 34680 */
+	0x44,  0x44,  0x05,  0x82,  0x06,  0x01,  0x96,  0x04,  0x20,  0x04,  0x20,  0x3F,  0x20,  0x04,  0x3F,  0x7F, 	/* 34690 */
+	0xC4,  0x04,  0x44,  0x04,  0x44,  0x7F,  0xA4,  0x08,  0x28,  0x0F,  0x38,  0x09,  0x10,  0x09,  0x18,  0x11, 	/* 346A0 */
+	0x28,  0x11,  0x44,  0x21,  0x82,  0x46,  0x01,  0x97,  0x00,  0x40,  0x3E,  0x40,  0x22,  0x40,  0x22,  0x7F, 	/* 346B0 */
+	0x3E,  0x44,  0x22,  0x44,  0x22,  0xC4,  0x3E,  0xA4,  0x23,  0x28,  0x22,  0x28,  0x22,  0x10,  0x3E,  0x18, 	/* 346C0 */
+	0x14,  0x28,  0x12,  0x44,  0x22,  0x82,  0x41,  0x01,  0x98,  0x04,  0x20,  0x04,  0x20,  0x0A,  0x20,  0x0A, 	/* 346D0 */
+	0x3F,  0x11,  0x44,  0x3F,  0xC4,  0x44,  0x44,  0x04,  0xA4,  0x7F,  0xA4,  0x04,  0x14,  0x15,  0x18,  0x14, 	/* 346E0 */
+	0x88,  0x24,  0x98,  0x44,  0x24,  0x04,  0x42,  0x0D,  0x81,  0x99,  0x04,  0x20,  0x04,  0xA0,  0x3F,  0xA0, 	/* 346F0 */
+	0x04,  0xA0,  0x05,  0x3F,  0x7F,  0xE2,  0x02,  0x22,  0x3F,  0x62,  0x09,  0x54,  0x12,  0x94,  0x64,  0x08, 	/* 34700 */
+	0x07,  0x88,  0x7C,  0x14,  0x04,  0x24,  0x04,  0xC2,  0x0F,  0x01,  0x9D,  0x08,  0x10,  0x08,  0x10,  0x2A, 	/* 34710 */
+	0x10,  0x29,  0x1F,  0x49,  0x14,  0x08,  0x24,  0x7F,  0xA4,  0x48,  0xD4,  0x6A,  0x94,  0x6A,  0x94,  0x6A, 	/* 34720 */
+	0x88,  0x6A,  0x88,  0x48,  0x94,  0x48,  0xA2,  0x48,  0xC2,  0x41,  0x81,  0x9E,  0x08,  0x20,  0x08,  0x20, 	/* 34730 */
+	0x2A,  0x20,  0x29,  0x3F,  0x49,  0x24,  0x08,  0x44,  0x7F,  0x44,  0x41,  0xA4,  0x5D,  0x24,  0x55,  0x28, 	/* 34740 */
+	0x55,  0x18,  0x55,  0x10,  0x5D,  0x28,  0x41,  0x44,  0x41,  0x82,  0x43,  0x01,  0xA2,  0x00,  0x20,  0x3F, 	/* 34750 */
+	0xA0,  0x04,  0x20,  0x04,  0x3F,  0x7F,  0xA4,  0x11,  0x44,  0x11,  0x64,  0x1F,  0xA4,  0x11,  0x14,  0x1F, 	/* 34760 */
+	0x14,  0x11,  0x18,  0x11,  0x88,  0x1F,  0x14,  0x71,  0x24,  0x01,  0x42,  0x01,  0x81,  0xA3,  0x12,  0x20, 	/* 34770 */
+	0x12,  0x20,  0x7F,  0x20,  0x12,  0x3F,  0x12,  0x24,  0x7F,  0xC4,  0x00,  0x44,  0x3E,  0xA4,  0x22,  0x24, 	/* 34780 */
+	0x3E,  0x28,  0x22,  0x18,  0x3E,  0x10,  0x22,  0x28,  0x22,  0x44,  0x22,  0x82,  0x27,  0x01,  0xA6,  0x04, 	/* 34790 */
+	0x20,  0x04,  0x20,  0x7F,  0xA0,  0x00,  0x3F,  0x1F,  0x24,  0x11,  0x44,  0x1F,  0x44,  0x00,  0xA4,  0x3F, 	/* 347A0 */
+	0x24,  0x02,  0x14,  0x04,  0x18,  0x07,  0x88,  0x7C,  0x14,  0x04,  0x24,  0x04,  0x42,  0x0D,  0x81,  0xAC, 	/* 347B0 */
+	0x12,  0x20,  0x12,  0x20,  0x7F,  0xA0,  0x12,  0x3F,  0x12,  0x24,  0x10,  0x44,  0x1F,  0xC4,  0x21,  0x24, 	/* 347C0 */
+	0x3D,  0x28,  0x65,  0x18,  0x25,  0x10,  0x25,  0x28,  0x3D,  0x28,  0x01,  0x44,  0x02,  0x82,  0x0D,  0x01, 	/* 347D0 */
+	0xB0,  0x04,  0xA0,  0x24,  0xA0,  0x15,  0x20,  0x15,  0x3F,  0x7F,  0xA4,  0x0E,  0x44,  0x15,  0xA4,  0x24, 	/* 347E0 */
+	0xA4,  0x44,  0x14,  0x7F,  0x98,  0x09,  0x08,  0x11,  0x18,  0x3E,  0x14,  0x06,  0x24,  0x19,  0x42,  0x60, 	/* 347F0 */
+	0x81,  0xB2,  0x08,  0x10,  0x08,  0x10,  0x7F,  0x9F,  0x00,  0x10,  0x3E,  0x10,  0x22,  0xFC,  0x3E,  0x44, 	/* 34800 */
+	0x00,  0x44,  0x7F,  0x44,  0x41,  0x28,  0x5D,  0x28,  0x55,  0x10,  0x55,  0x18,  0x5D,  0x24,  0x41,  0x42, 	/* 34810 */
+	0x43,  0x81,  0xB4,  0x04,  0x20,  0x7F,  0xA0,  0x04,  0x3F,  0x3F,  0x64,  0x25,  0x54,  0x3F,  0x94,  0x0E, 	/* 34820 */
+	0x08,  0x15,  0x34,  0x64,  0xC2,  0x04,  0x01,  0x1F,  0xFC,  0x00,  0x80,  0x08,  0xF8,  0x08,  0x80,  0x7F, 	/* 34830 */
+	0xFF,  0x00,  0x00,  0xB5,  0x04,  0x10,  0x04,  0x10,  0x7F,  0xD0,  0x11,  0x1F,  0x0A,  0x24,  0x3F,  0xA4, 	/* 34840 */
+	0x24,  0xD4,  0x24,  0x94,  0x3F,  0x94,  0x24,  0x88,  0x2E,  0x88,  0x2A,  0x94,  0x2A,  0x94,  0x2E,  0xA2, 	/* 34850 */
+	0x20,  0xC2,  0x21,  0x81,  0xB7,  0x0A,  0x20,  0x09,  0x20,  0x7F,  0xA0,  0x08,  0x3F,  0x3F,  0x44,  0x29, 	/* 34860 */
+	0x44,  0x3F,  0xA4,  0x29,  0x24,  0x3F,  0x24,  0x08,  0x18,  0x7F,  0x88,  0x08,  0x18,  0x0E,  0x14,  0x12, 	/* 34870 */
+	0x24,  0x22,  0x42,  0x4D,  0x81,  0xB8,  0x04,  0x10,  0x1F,  0x90,  0x14,  0x90,  0x7F,  0xDF,  0x14,  0xA4, 	/* 34880 */
+	0x1F,  0xA4,  0x04,  0x24,  0x1F,  0xD4,  0x14,  0x94,  0x1F,  0x98,  0x04,  0x08,  0x7F,  0xC8,  0x09,  0x14, 	/* 34890 */
+	0x1E,  0x24,  0x05,  0x42,  0x38,  0x81,  0x82,  0x04,  0x10,  0x04,  0x10,  0x0A,  0x10,  0x11,  0x1F,  0x20, 	/* 348A0 */
+	0xA4,  0x5F,  0x24,  0x00,  0x24,  0x3B,  0xD4,  0x2A,  0x94,  0x2A,  0x98,  0x3B,  0x88,  0x11,  0x08,  0x19, 	/* 348B0 */
+	0x94,  0x15,  0x64,  0x22,  0x42,  0x44,  0x81,  0x83,  0x08,  0x20,  0x2A,  0x20,  0x49,  0x3F,  0x3F,  0x44, 	/* 348C0 */
+	0x29,  0xA8,  0x2D,  0x10,  0x3B,  0x2C,  0x29,  0xC3,  0x2B,  0x00,  0x7F,  0xFF,  0x04,  0x40,  0x0F,  0x4C, 	/* 348D0 */
+	0x71,  0x70,  0x0A,  0x42,  0x0C,  0x42,  0x70,  0x3E,  0x87,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x7F, 	/* 348E0 */
+	0xFF,  0x04,  0x10,  0x04,  0x10,  0x04,  0x10,  0x02,  0x20,  0x02,  0x20,  0x01,  0x40,  0x00,  0x80,  0x00, 	/* 348F0 */
+	0x80,  0x01,  0x40,  0x02,  0x20,  0x0C,  0x18,  0x70,  0x07,  0x88,  0x00,  0x80,  0x00,  0x80,  0x7F,  0xFF, 	/* 34900 */
+	0x02,  0x10,  0x01,  0x20,  0x00,  0xC0,  0x03,  0x60,  0x0C,  0x18,  0x70,  0x07,  0x0F,  0xF0,  0x00,  0x60, 	/* 34910 */
+	0x00,  0x80,  0x7F,  0xFF,  0x00,  0x80,  0x00,  0x80,  0x01,  0x80,  0x89,  0x00,  0x80,  0x00,  0x80,  0x7F, 	/* 34920 */
+	0xFF,  0x02,  0x10,  0x01,  0x20,  0x00,  0xC0,  0x03,  0x30,  0x0C,  0x0C,  0x77,  0xFB,  0x04,  0x08,  0x04, 	/* 34930 */
+	0x08,  0x07,  0xF8,  0x04,  0x08,  0x08,  0x08,  0x08,  0x08,  0x10,  0x08,  0x8C,  0x08,  0x08,  0x08,  0xEC, 	/* 34940 */
+	0x08,  0x0A,  0x7F,  0x0A,  0x05,  0xFF,  0x24,  0x28,  0x14,  0x28,  0x14,  0xA8,  0x08,  0xB8,  0x0C,  0xA4, 	/* 34950 */
+	0x14,  0xA4,  0x12,  0xA4,  0x12,  0xAD,  0x20,  0xB3,  0x41,  0xC3,  0x00,  0x01,  0x8E,  0x00,  0x80,  0x00, 	/* 34960 */
+	0x80,  0x7F,  0xFF,  0x04,  0x10,  0x02,  0x20,  0x01,  0xC0,  0x03,  0x60,  0x0C,  0x18,  0x7B,  0xEF,  0x08, 	/* 34970 */
+	0x08,  0x0F,  0xF8,  0x08,  0x88,  0x0A,  0xC8,  0x12,  0xA8,  0x14,  0xA8,  0x21,  0x88,  0x90,  0x02,  0x20, 	/* 34980 */
+	0x02,  0x20,  0x7E,  0x3F,  0x02,  0x20,  0x3E,  0x3E,  0x02,  0x20,  0x7C,  0x3F,  0x04,  0xA0,  0x08,  0x80, 	/* 34990 */
+	0x7F,  0xFF,  0x02,  0x20,  0x02,  0x20,  0x01,  0x40,  0x01,  0xC0,  0x06,  0x30,  0x38,  0x0E,  0x91,  0x01, 	/* 349A0 */
+	0x00,  0x7D,  0x3F,  0x11,  0x08,  0x17,  0xE8,  0x10,  0x48,  0x12,  0x48,  0x7D,  0x48,  0x11,  0x7E,  0x11, 	/* 349B0 */
+	0x88,  0x10,  0x88,  0x10,  0x88,  0x15,  0x48,  0x1A,  0x48,  0x64,  0x08,  0x08,  0x7F,  0x00,  0x00,  0x97, 	/* 349C0 */
+	0x00,  0x10,  0x00,  0x10,  0x0C,  0x10,  0x03,  0x10,  0x00,  0x10,  0x00,  0x10,  0x18,  0x10,  0x06,  0x10, 	/* 349D0 */
+	0x00,  0x10,  0x00,  0x10,  0x00,  0x1F,  0x03,  0xF0,  0x7C,  0x10,  0x00,  0x10,  0x00,  0x10,  0x00,  0x10, 	/* 349E0 */
+	0x99,  0x08,  0x04,  0x49,  0x44,  0x29,  0x24,  0x2A,  0x14,  0x0C,  0x14,  0x7F,  0x84,  0x08,  0x44,  0x0C, 	/* 349F0 */
+	0x24,  0x1A,  0x24,  0x19,  0x07,  0x29,  0x3C,  0x28,  0xC4,  0x48,  0x04,  0x08,  0x04,  0x08,  0x04,  0x08, 	/* 34A00 */
+	0x04,  0x9B,  0x08,  0x04,  0x0E,  0x44,  0x12,  0x24,  0x24,  0x24,  0x7F,  0x04,  0x25,  0x84,  0x25,  0x44, 	/* 34A10 */
+	0x3F,  0x44,  0x25,  0x04,  0x25,  0x07,  0x3F,  0x1C,  0x21,  0xE4,  0x21,  0x04,  0x21,  0x04,  0x21,  0x04, 	/* 34A20 */
+	0x43,  0x04,  0x9C,  0x04,  0x04,  0x04,  0x44,  0x0A,  0x24,  0x09,  0x24,  0x11,  0x04,  0x3F,  0x44,  0x44, 	/* 34A30 */
+	0x24,  0x04,  0x24,  0x7F,  0x84,  0x04,  0x07,  0x16,  0x3C,  0x15,  0xC4,  0x25,  0x04,  0x44,  0x84,  0x04, 	/* 34A40 */
+	0x04,  0x0C,  0x04,  0x9F,  0x11,  0x04,  0x11,  0x04,  0x7F,  0xA4,  0x11,  0x14,  0x1F,  0x14,  0x11,  0x04, 	/* 34A50 */
+	0x1F,  0x44,  0x11,  0x24,  0x11,  0x24,  0x7F,  0xC4,  0x2A,  0x07,  0x2A,  0x9C,  0x33,  0xE4,  0x20,  0x04, 	/* 34A60 */
+	0x3F,  0xC4,  0x00,  0x04,  0xA1,  0x08,  0x10,  0x08,  0x10,  0x7F,  0x28,  0x08,  0x28,  0x3E,  0x44,  0x22, 	/* 34A70 */
+	0xCA,  0x23,  0x29,  0x3E,  0x28,  0x22,  0x88,  0x22,  0x48,  0x3E,  0x48,  0x08,  0x0F,  0x7F,  0x38,  0x09, 	/* 34A80 */
+	0xC8,  0x08,  0x08,  0x08,  0x08,  0xA4,  0x00,  0x08,  0x00,  0x30,  0x0F,  0xC0,  0x08,  0x00,  0x08,  0x00, 	/* 34A90 */
+	0x08,  0x00,  0x0F,  0xFF,  0x08,  0x20,  0x08,  0x20,  0x08,  0x20,  0x08,  0x20,  0x10,  0x20,  0x10,  0x20, 	/* 34AA0 */
+	0x20,  0x20,  0x40,  0x20,  0x00,  0x20,  0xA5,  0x00,  0x10,  0x00,  0x60,  0x0F,  0x80,  0x08,  0x00,  0x08, 	/* 34AB0 */
+	0x00,  0x0F,  0xFF,  0x08,  0x40,  0x08,  0x40,  0x0F,  0x40,  0x08,  0xF0,  0x10,  0x4C,  0x10,  0x42,  0x20, 	/* 34AC0 */
+	0x40,  0x40,  0x40,  0x00,  0x40,  0x00,  0x40,  0xA7,  0x02,  0x40,  0x04,  0x20,  0x1C,  0x38,  0x62,  0x46, 	/* 34AD0 */
+	0x01,  0x80,  0x02,  0x60,  0x0C,  0x18,  0x70,  0x67,  0x0F,  0x80,  0x08,  0x00,  0x0F,  0xFE,  0x08,  0x40, 	/* 34AE0 */
+	0x10,  0x40,  0x20,  0x40,  0x40,  0x40,  0x00,  0x40,  0xAB,  0x00,  0x04,  0x7F,  0x98,  0x08,  0x60,  0x08, 	/* 34AF0 */
+	0x40,  0x08,  0x40,  0x10,  0x7F,  0x1E,  0x44,  0x12,  0x44,  0x32,  0x44,  0x32,  0x44,  0x52,  0x44,  0x12, 	/* 34B00 */
+	0x44,  0x1E,  0x84,  0x00,  0x84,  0x01,  0x04,  0x00,  0x04,  0xAC,  0x04,  0x02,  0x04,  0x0C,  0x7F,  0xF0, 	/* 34B10 */
+	0x04,  0x20,  0x3F,  0xA0,  0x24,  0xBF,  0x24,  0xA4,  0x3F,  0xA4,  0x24,  0xA4,  0x24,  0xA4,  0x3F,  0xA4, 	/* 34B20 */
+	0x04,  0x24,  0x7F,  0xC4,  0x04,  0x44,  0x04,  0x84,  0x04,  0x04,  0xAD,  0x04,  0x02,  0x44,  0x0C,  0x65, 	/* 34B30 */
+	0x70,  0x55,  0x40,  0x56,  0x40,  0x44,  0x40,  0x7F,  0x7F,  0x44,  0x44,  0x4E,  0x44,  0x4D,  0x44,  0x55, 	/* 34B40 */
+	0x44,  0x64,  0x44,  0x44,  0x84,  0x44,  0x84,  0x7F,  0x04,  0x00,  0x04,  0xAF,  0x11,  0x02,  0x11,  0x0C, 	/* 34B50 */
+	0x7F,  0xF0,  0x11,  0x20,  0x11,  0x20,  0x1F,  0x3F,  0x11,  0x24,  0x11,  0x24,  0x1F,  0x24,  0x11,  0x24, 	/* 34B60 */
+	0x11,  0x24,  0x7F,  0xE4,  0x12,  0x44,  0x11,  0x44,  0x21,  0x84,  0x40,  0x04,  0xB0,  0x04,  0x02,  0x04, 	/* 34B70 */
+	0x0C,  0x7F,  0x70,  0x22,  0x40,  0x12,  0x40,  0x14,  0x7F,  0x7F,  0xC4,  0x08,  0x44,  0x08,  0x44,  0x7F, 	/* 34B80 */
+	0x44,  0x0C,  0x44,  0x1A,  0x44,  0x19,  0x84,  0x28,  0x84,  0x49,  0x04,  0x08,  0x04,  0xB7,  0x09,  0x02, 	/* 34B90 */
+	0x52,  0x04,  0x56,  0xB8,  0x49,  0x20,  0x56,  0xA0,  0x5F,  0xBF,  0x40,  0x24,  0x7F,  0xA4,  0x49,  0x24, 	/* 34BA0 */
+	0x56,  0xA4,  0x49,  0x24,  0x56,  0xA4,  0x5F,  0xA4,  0x40,  0x24,  0x7F,  0xC4,  0x00,  0x84,  0xB9,  0x00, 	/* 34BB0 */
+	0x80,  0x00,  0x80,  0x00,  0x80,  0x7F,  0xFF,  0x01,  0x00,  0x01,  0x00,  0x01,  0x00,  0x01,  0xF8,  0x01, 	/* 34BC0 */
+	0x08,  0x01,  0x08,  0x02,  0x08,  0x02,  0x08,  0x04,  0x08,  0x04,  0x08,  0x08,  0x08,  0x10,  0x70,  0xBC, 	/* 34BD0 */
+	0x10,  0x10,  0x10,  0x10,  0x10,  0x10,  0x7F,  0x28,  0x10,  0x28,  0x10,  0x44,  0x1E,  0x64,  0x12,  0xA2, 	/* 34BE0 */
+	0x13,  0x11,  0x12,  0x10,  0x12,  0x40,  0x12,  0x20,  0x22,  0x10,  0x22,  0x10,  0x42,  0x08,  0x0C,  0x08, 	/* 34BF0 */
+	0xBD,  0x08,  0x20,  0x08,  0x20,  0x08,  0x20,  0x7F,  0x7F,  0x10,  0x48,  0x10,  0x88,  0x1F,  0x4E,  0x12, 	/* 34C00 */
+	0x7A,  0x13,  0xCA,  0x12,  0x4A,  0x12,  0x4C,  0x12,  0x48,  0x22,  0x48,  0x22,  0x41,  0x42,  0x21,  0x0C, 	/* 34C10 */
+	0x1F,  0x81,  0x01,  0x00,  0x01,  0x00,  0x3F,  0xFC,  0x08,  0x20,  0x04,  0x40,  0x7F,  0xFE,  0x41,  0x02, 	/* 34C20 */
+	0x41,  0x02,  0x3F,  0xFC,  0x02,  0x00,  0x03,  0xF0,  0x02,  0x10,  0x04,  0x10,  0x04,  0x10,  0x18,  0x10, 	/* 34C30 */
+	0x60,  0x60,  0x83,  0x08,  0x20,  0x08,  0x20,  0x08,  0x20,  0x7F,  0x7F,  0x10,  0x40,  0x10,  0x80,  0x1F, 	/* 34C40 */
+	0x7C,  0x12,  0x54,  0x12,  0x54,  0x12,  0x54,  0x13,  0xFF,  0x22,  0x44,  0x22,  0x44,  0x42,  0x44,  0x02, 	/* 34C50 */
+	0x44,  0x0C,  0x4C,  0x84,  0x08,  0x40,  0x08,  0x40,  0x08,  0x40,  0x7E,  0xFF,  0x10,  0x82,  0x11,  0x0C, 	/* 34C60 */
+	0x1E,  0xF0,  0x12,  0x20,  0x12,  0xFC,  0x12,  0x20,  0x12,  0x20,  0x23,  0xFE,  0x22,  0x20,  0x42,  0x21, 	/* 34C70 */
+	0x02,  0x11,  0x0C,  0x0F,  0x85,  0x08,  0x40,  0x08,  0x40,  0x08,  0x40,  0x7F,  0x7F,  0x08,  0x90,  0x08, 	/* 34C80 */
+	0x92,  0x09,  0x22,  0x0F,  0x34,  0x09,  0x74,  0x09,  0xA8,  0x09,  0x28,  0x11,  0x24,  0x11,  0x24,  0x21, 	/* 34C90 */
+	0x22,  0x41,  0x21,  0x06,  0x20,  0x86,  0x08,  0x20,  0x08,  0x20,  0x08,  0x20,  0x7F,  0x7F,  0x10,  0x50, 	/* 34CA0 */
+	0x10,  0x90,  0x1E,  0xFF,  0x13,  0x10,  0x12,  0x10,  0x12,  0xFE,  0x12,  0x92,  0x22,  0x92,  0x22,  0x92, 	/* 34CB0 */
+	0x42,  0x9C,  0x02,  0x10,  0x0C,  0x10,  0x8B,  0x08,  0x40,  0x08,  0x40,  0x08,  0x7F,  0x7F,  0x80,  0x10, 	/* 34CC0 */
+	0x80,  0x11,  0x7E,  0x1E,  0x12,  0x12,  0x14,  0x12,  0x50,  0x12,  0x50,  0x12,  0x5E,  0x12,  0x50,  0x22, 	/* 34CD0 */
+	0x50,  0x22,  0xB0,  0x42,  0x98,  0x0D,  0x07,  0x8C,  0x08,  0x40,  0x08,  0x40,  0x08,  0x40,  0x7E,  0xFF, 	/* 34CE0 */
+	0x10,  0x80,  0x11,  0x50,  0x1E,  0x50,  0x12,  0x7E,  0x12,  0x90,  0x13,  0x10,  0x12,  0x7E,  0x12,  0x10, 	/* 34CF0 */
+	0x22,  0x10,  0x42,  0x10,  0x03,  0xFF,  0x0C,  0x00,  0x8F,  0x08,  0x40,  0x08,  0x40,  0x08,  0x7F,  0x7F, 	/* 34D00 */
+	0x50,  0x10,  0x90,  0x10,  0xBE,  0x1F,  0x28,  0x12,  0x48,  0x12,  0x88,  0x12,  0xFF,  0x12,  0x08,  0x12, 	/* 34D10 */
+	0x14,  0x22,  0x14,  0x22,  0x24,  0x42,  0x42,  0x0C,  0x81,  0x92,  0x08,  0x40,  0x08,  0x40,  0x08,  0x40, 	/* 34D20 */
+	0x7E,  0xFF,  0x10,  0x90,  0x11,  0x10,  0x1E,  0xFF,  0x12,  0x24,  0x12,  0xFA,  0x12,  0x45,  0x12,  0x54, 	/* 34D30 */
+	0x12,  0x54,  0x22,  0x54,  0x42,  0x55,  0x02,  0x85,  0x0D,  0x03,  0x97,  0x08,  0x40,  0x08,  0x40,  0x08, 	/* 34D40 */
+	0x7F,  0x7E,  0x80,  0x11,  0x44,  0x13,  0xFF,  0x10,  0x44,  0x1E,  0x7C,  0x12,  0x44,  0x12,  0x7C,  0x12, 	/* 34D50 */
+	0x44,  0x13,  0xFF,  0x22,  0x08,  0x22,  0x24,  0x42,  0x42,  0x0D,  0x82,  0x99,  0x08,  0x04,  0x08,  0x18, 	/* 34D60 */
+	0x09,  0xF2,  0x7E,  0x92,  0x10,  0x54,  0x11,  0xFF,  0x1E,  0x38,  0x12,  0x54,  0x12,  0x92,  0x13,  0xFF, 	/* 34D70 */
+	0x12,  0x92,  0x22,  0xFE,  0x22,  0x92,  0x42,  0x92,  0x02,  0xFE,  0x0C,  0x00,  0x9B,  0x08,  0x20,  0x08, 	/* 34D80 */
+	0x20,  0x08,  0x7F,  0x7F,  0x82,  0x10,  0xFC,  0x10,  0x92,  0x1E,  0x54,  0x13,  0xFF,  0x12,  0x54,  0x12, 	/* 34D90 */
+	0x92,  0x13,  0xFF,  0x22,  0x92,  0x22,  0xFE,  0x42,  0x92,  0x02,  0xFE,  0x0C,  0x00,  0xA0,  0x00,  0x00, 	/* 34DA0 */
+	0x1F,  0xFC,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x7F,  0xFF,  0x00,  0x80,  0x00,  0xC0, 	/* 34DB0 */
+	0x01,  0x40,  0x01,  0x40,  0x02,  0x40,  0x04,  0x41,  0x08,  0x41,  0x10,  0x21,  0x60,  0x1F,  0xA1,  0x00, 	/* 34DC0 */
+	0x00,  0x1F,  0xF8,  0x04,  0x20,  0x04,  0x20,  0x04,  0x20,  0x04,  0x20,  0x04,  0x20,  0x07,  0xFF,  0x00, 	/* 34DD0 */
+	0x40,  0x00,  0x60,  0x00,  0xA0,  0x01,  0x20,  0x02,  0x21,  0x04,  0x21,  0x18,  0x11,  0x60,  0x0F,  0xA2, 	/* 34DE0 */
+	0x00,  0x00,  0x3E,  0xFE,  0x22,  0x48,  0x22,  0x48,  0x3E,  0x48,  0x22,  0x48,  0x22,  0x48,  0x3F,  0xFF, 	/* 34DF0 */
+	0x20,  0x18,  0x24,  0x18,  0x22,  0x18,  0x22,  0x28,  0x2D,  0x28,  0x31,  0x49,  0x60,  0x89,  0x03,  0x07, 	/* 34E00 */
+	0xA5,  0x00,  0x00,  0x0F,  0xF8,  0x08,  0x08,  0x08,  0x08,  0x08,  0x08,  0x08,  0x08,  0x08,  0x08,  0x0F, 	/* 34E10 */
+	0xF8,  0x08,  0x08,  0x08,  0x08,  0x08,  0x08,  0x08,  0x08,  0x08,  0x08,  0x08,  0x08,  0x0F,  0xF8,  0x00, 	/* 34E20 */
+	0x00,  0xA6,  0x00,  0x00,  0x0F,  0xF0,  0x08,  0x10,  0x08,  0x10,  0x08,  0x10,  0x08,  0x10,  0x0F,  0xF0, 	/* 34E30 */
+	0x08,  0x10,  0x08,  0x10,  0x08,  0x10,  0x08,  0x10,  0x0F,  0xF0,  0x00,  0x00,  0x00,  0x00,  0x7F,  0xFE, 	/* 34E40 */
+	0x00,  0x00,  0xA7,  0x20,  0x00,  0x23,  0xFC,  0x22,  0x04,  0x22,  0x04,  0x22,  0x04,  0x22,  0x04,  0x22, 	/* 34E50 */
+	0x04,  0x23,  0xFC,  0x22,  0x04,  0x22,  0x04,  0x22,  0x04,  0x22,  0x04,  0x22,  0x04,  0x22,  0x04,  0x23, 	/* 34E60 */
+	0xFC,  0x20,  0x00,  0xA8,  0x10,  0x00,  0x10,  0x0C,  0x10,  0xF0,  0x1F,  0x00,  0x10,  0x02,  0x10,  0x02, 	/* 34E70 */
+	0x0F,  0xFE,  0x00,  0x00,  0x0F,  0xF8,  0x08,  0x08,  0x08,  0x08,  0x0F,  0xF8,  0x08,  0x08,  0x08,  0x08, 	/* 34E80 */
+	0x0F,  0xF8,  0x00,  0x00,  0xA9,  0x00,  0x00,  0x0F,  0xF8,  0x08,  0x08,  0x08,  0x08,  0x0F,  0xF8,  0x08, 	/* 34E90 */
+	0x08,  0x08,  0x08,  0x0F,  0xF8,  0x00,  0x80,  0x00,  0x80,  0x7F,  0xFF,  0x00,  0x80,  0x00,  0x80,  0x00, 	/* 34EA0 */
+	0x80,  0x00,  0x80,  0x00,  0x80,  0xAC,  0x04,  0x00,  0x04,  0x00,  0x07,  0xFE,  0x08,  0x02,  0x08,  0x02, 	/* 34EB0 */
+	0x17,  0xE2,  0x24,  0x22,  0x44,  0x22,  0x07,  0xE2,  0x04,  0x22,  0x04,  0x22,  0x04,  0x22,  0x07,  0xE2, 	/* 34EC0 */
+	0x00,  0x02,  0x00,  0x04,  0x00,  0x18,  0xAD,  0x08,  0x00,  0x08,  0x7C,  0x08,  0x44,  0x08,  0x44,  0x7F, 	/* 34ED0 */
+	0x44,  0x09,  0x44,  0x09,  0x7C,  0x09,  0x44,  0x09,  0x44,  0x09,  0x44,  0x09,  0x44,  0x09,  0x7C,  0x11, 	/* 34EE0 */
+	0x00,  0x11,  0x01,  0x20,  0x81,  0x40,  0x7F,  0xB1,  0x00,  0x00,  0x0F,  0xF8,  0x08,  0x08,  0x08,  0x08, 	/* 34EF0 */
+	0x0F,  0xF8,  0x08,  0x08,  0x08,  0x08,  0x0F,  0xF8,  0x00,  0x00,  0x1F,  0xFC,  0x00,  0x80,  0x00,  0x80, 	/* 34F00 */
+	0x7F,  0xFF,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0xBA,  0x00,  0x00,  0x7D,  0xFE,  0x44,  0x20,  0x44, 	/* 34F10 */
+	0x20,  0x44,  0x20,  0x44,  0x20,  0x7C,  0x20,  0x45,  0xFE,  0x44,  0x20,  0x44,  0x20,  0x44,  0x20,  0x44, 	/* 34F20 */
+	0x20,  0x7C,  0x20,  0x00,  0x20,  0x07,  0xFF,  0x00,  0x00,  0xBB,  0x00,  0x00,  0x0F,  0xF8,  0x08,  0x08, 	/* 34F30 */
+	0x0F,  0xF8,  0x08,  0x08,  0x0F,  0xF8,  0x00,  0x80,  0x00,  0x80,  0x7F,  0xFF,  0x04,  0x10,  0x02,  0x20, 	/* 34F40 */
+	0x01,  0x40,  0x00,  0x80,  0x03,  0x60,  0x0C,  0x18,  0x70,  0x07,  0x82,  0x00,  0x00,  0x0F,  0xF8,  0x08, 	/* 34F50 */
+	0x08,  0x0F,  0xF8,  0x08,  0x08,  0x08,  0x08,  0x0F,  0xF8,  0x02,  0x00,  0x3C,  0x7E,  0x20,  0x42,  0x20, 	/* 34F60 */
+	0x42,  0x23,  0x42,  0x2C,  0x42,  0x70,  0x4C,  0x00,  0x40,  0x00,  0x40,  0x83,  0x00,  0x00,  0x0F,  0xFC, 	/* 34F70 */
+	0x08,  0x04,  0x0F,  0xFC,  0x08,  0x04,  0x0F,  0xFC,  0x00,  0x00,  0x1F,  0xFF,  0x10,  0x40,  0x10,  0x40, 	/* 34F80 */
+	0x10,  0x40,  0x10,  0x40,  0x20,  0xA0,  0x21,  0x10,  0x46,  0x0C,  0x18,  0x03,  0x86,  0x00,  0x00,  0x1F, 	/* 34F90 */
+	0xF8,  0x10,  0x08,  0x10,  0x08,  0x1F,  0xF8,  0x10,  0x08,  0x10,  0x08,  0x1F,  0xF8,  0x10,  0x40,  0x10, 	/* 34FA0 */
+	0x40,  0x10,  0x4C,  0x1F,  0x70,  0x10,  0x40,  0x10,  0x42,  0x1F,  0x42,  0x70,  0x3E,  0x87,  0x00,  0x00, 	/* 34FB0 */
+	0x0F,  0xFC,  0x08,  0x04,  0x0F,  0xFC,  0x08,  0x04,  0x08,  0x04,  0x0F,  0xFC,  0x01,  0x10,  0x0E,  0x10, 	/* 34FC0 */
+	0x02,  0x10,  0x02,  0x10,  0x7F,  0xFF,  0x02,  0x10,  0x04,  0x10,  0x04,  0x10,  0x08,  0x10,  0x8A,  0x00, 	/* 34FD0 */
+	0x00,  0x0F,  0xF8,  0x08,  0x08,  0x0F,  0xF8,  0x08,  0x08,  0x08,  0x08,  0x0F,  0xF8,  0x00,  0x00,  0x7F, 	/* 34FE0 */
+	0xFF,  0x00,  0x80,  0x00,  0x80,  0x1F,  0xFC,  0x01,  0x20,  0x02,  0x10,  0x0C,  0x0C,  0x70,  0x03,  0x8C, 	/* 34FF0 */
+	0x00,  0x00,  0x0F,  0xF0,  0x08,  0x10,  0x08,  0x10,  0x0F,  0xF0,  0x08,  0x10,  0x0F,  0xF0,  0x00,  0x00, 	/* 35000 */
+	0x3F,  0xFC,  0x20,  0x04,  0x20,  0x04,  0x3F,  0xFC,  0x20,  0x04,  0x20,  0x04,  0x3F,  0xFC,  0x00,  0x00, 	/* 35010 */
+	0x8E,  0x00,  0x00,  0x3E,  0x7E,  0x22,  0x42,  0x22,  0x42,  0x22,  0x42,  0x22,  0x7E,  0x3E,  0x42,  0x22, 	/* 35020 */
+	0x42,  0x22,  0x42,  0x22,  0x7E,  0x22,  0x42,  0x3E,  0x42,  0x00,  0x82,  0x00,  0x82,  0x01,  0x02,  0x02, 	/* 35030 */
+	0x06,  0x8F,  0x00,  0x10,  0x00,  0x60,  0x0F,  0xC0,  0x08,  0x40,  0x0F,  0xFE,  0x08,  0x40,  0x08,  0x22, 	/* 35040 */
+	0x0F,  0x12,  0x70,  0x0E,  0x0F,  0xFA,  0x08,  0x08,  0x08,  0x08,  0x0F,  0xF8,  0x08,  0x08,  0x0F,  0xF8, 	/* 35050 */
+	0x00,  0x00,  0x93,  0x00,  0x00,  0x0F,  0xF0,  0x08,  0x10,  0x08,  0x10,  0x0F,  0xF0,  0x08,  0x10,  0x08, 	/* 35060 */
+	0x10,  0x0F,  0xF0,  0x02,  0x00,  0x07,  0xFC,  0x18,  0x94,  0x61,  0x14,  0x06,  0x24,  0x18,  0x44,  0x01, 	/* 35070 */
+	0x88,  0x00,  0x30,  0x94,  0x02,  0x20,  0x02,  0x20,  0x1F,  0xFC,  0x02,  0x20,  0x02,  0x20,  0x02,  0x20, 	/* 35080 */
+	0x7F,  0xFF,  0x00,  0x00,  0x0F,  0xF8,  0x08,  0x08,  0x08,  0x08,  0x0F,  0xF8,  0x08,  0x08,  0x08,  0x08, 	/* 35090 */
+	0x0F,  0xF8,  0x00,  0x00,  0x9C,  0x00,  0x00,  0x0F,  0xF8,  0x08,  0x08,  0x0F,  0xF8,  0x08,  0x08,  0x08, 	/* 350A0 */
+	0x08,  0x0F,  0xF8,  0x00,  0x00,  0x7F,  0xFF,  0x02,  0x00,  0x07,  0xFE,  0x18,  0x92,  0x61,  0x12,  0x06, 	/* 350B0 */
+	0x22,  0x18,  0x42,  0x01,  0x8C,  0x9F,  0x00,  0x00,  0x0F,  0xF8,  0x08,  0x08,  0x0F,  0xF8,  0x08,  0x08, 	/* 350C0 */
+	0x08,  0x08,  0x0F,  0xF8,  0x04,  0x80,  0x04,  0x80,  0x0F,  0xFC,  0x10,  0x80,  0x2F,  0xFC,  0x00,  0x80, 	/* 350D0 */
+	0x00,  0x80,  0x7F,  0xFF,  0x00,  0x00,  0xA0,  0x00,  0x20,  0x00,  0x20,  0x78,  0x20,  0x49,  0xFC,  0x49, 	/* 350E0 */
+	0x24,  0x49,  0x24,  0x79,  0x24,  0x49,  0x24,  0x4F,  0xFF,  0x48,  0x20,  0x48,  0x50,  0x78,  0x50,  0x48, 	/* 350F0 */
+	0x88,  0x01,  0x04,  0x02,  0x02,  0x0C,  0x01,  0xA5,  0x00,  0x80,  0x00,  0x80,  0x3F,  0xFE,  0x00,  0x80, 	/* 35100 */
+	0x1F,  0xFC,  0x01,  0x40,  0x7F,  0xFF,  0x02,  0x20,  0x04,  0x10,  0x1F,  0xFC,  0x64,  0x13,  0x07,  0xF0, 	/* 35110 */
+	0x04,  0x10,  0x04,  0x10,  0x07,  0xF0,  0x00,  0x00,  0xA7,  0x00,  0x20,  0x00,  0x20,  0x7C,  0x20,  0x47, 	/* 35120 */
+	0xFE,  0x44,  0x20,  0x44,  0x20,  0x44,  0x20,  0x7F,  0xFF,  0x44,  0x70,  0x44,  0x70,  0x44,  0xA8,  0x44, 	/* 35130 */
+	0xA4,  0x7D,  0x22,  0x42,  0x21,  0x04,  0x20,  0x00,  0x20,  0xA8,  0x00,  0x40,  0x00,  0x40,  0x3E,  0x40, 	/* 35140 */
+	0x22,  0x7F,  0x22,  0x50,  0x22,  0x90,  0x22,  0x90,  0x3F,  0x1E,  0x22,  0x10,  0x22,  0x10,  0x22,  0x10, 	/* 35150 */
+	0x22,  0x1E,  0x3E,  0x10,  0x00,  0x10,  0x00,  0x10,  0x00,  0x10,  0xAD,  0x00,  0x00,  0x03,  0xFE,  0x7C, 	/* 35160 */
+	0x22,  0x44,  0x22,  0x44,  0x42,  0x44,  0x42,  0x44,  0x82,  0x7D,  0x0C,  0x46,  0x00,  0x44,  0xFE,  0x44, 	/* 35170 */
+	0x82,  0x44,  0x82,  0x7C,  0x82,  0x00,  0x82,  0x00,  0xFE,  0x00,  0x00,  0xAF,  0x00,  0x00,  0x07,  0xF8, 	/* 35180 */
+	0x04,  0x08,  0x07,  0xF8,  0x04,  0x08,  0x04,  0x08,  0x07,  0xF8,  0x00,  0x00,  0x7F,  0xFF,  0x04,  0x80, 	/* 35190 */
+	0x04,  0x80,  0x04,  0xFC,  0x0A,  0x80,  0x09,  0x80,  0x10,  0x60,  0x20,  0x1F,  0xB4,  0x00,  0x00,  0x0F, 	/* 351A0 */
+	0xFC,  0x08,  0x04,  0x0F,  0xFC,  0x08,  0x04,  0x08,  0x04,  0x0F,  0xFC,  0x03,  0x00,  0x1C,  0x3E,  0x11, 	/* 351B0 */
+	0x22,  0x11,  0x22,  0x11,  0x22,  0x1F,  0x22,  0x72,  0x3C,  0x02,  0x20,  0x0C,  0x20,  0xB5,  0x00,  0x00, 	/* 351C0 */
+	0x01,  0xFE,  0x79,  0x02,  0x49,  0x02,  0x49,  0x02,  0x49,  0xFE,  0x49,  0x00,  0x79,  0x40,  0x49,  0x42, 	/* 351D0 */
+	0x49,  0x4C,  0x49,  0x70,  0x4A,  0x40,  0x7A,  0x41,  0x04,  0x41,  0x08,  0x21,  0x00,  0x1F,  0xB6,  0x00, 	/* 351E0 */
+	0x00,  0x3F,  0x00,  0x00,  0x7E,  0x00,  0x42,  0x3C,  0x42,  0x04,  0xC2,  0x04,  0xFE,  0x77,  0x42,  0x16, 	/* 351F0 */
+	0x42,  0x16,  0x42,  0x15,  0x42,  0x25,  0x7E,  0x24,  0x80,  0x44,  0x60,  0x04,  0x1F,  0x0C,  0x00,  0xBC, 	/* 35200 */
+	0x00,  0x00,  0x0F,  0xF8,  0x08,  0x08,  0x08,  0x08,  0x0F,  0xF8,  0x08,  0x10,  0x10,  0x10,  0x17,  0xE8, 	/* 35210 */
+	0x24,  0x28,  0x27,  0xE4,  0x44,  0x22,  0x04,  0x20,  0x07,  0xE0,  0x00,  0x00,  0x7F,  0xFE,  0x00,  0x00, 	/* 35220 */
+	0xBF,  0x00,  0x10,  0x00,  0x10,  0x78,  0x10,  0x49,  0xFF,  0x49,  0x00,  0x49,  0x10,  0x49,  0x10,  0x79, 	/* 35230 */
+	0x10,  0x49,  0x10,  0x49,  0x10,  0x49,  0x14,  0x4A,  0x22,  0x7A,  0x22,  0x04,  0x4F,  0x09,  0xF1,  0x00, 	/* 35240 */
+	0x01,  0x81,  0x00,  0x00,  0x1F,  0xF8,  0x10,  0x08,  0x1F,  0xF8,  0x10,  0x08,  0x1F,  0xF8,  0x00,  0x00, 	/* 35250 */
+	0x12,  0x44,  0x0A,  0x44,  0x0A,  0x48,  0x02,  0x60,  0x1A,  0x58,  0x62,  0x46,  0x04,  0x41,  0x18,  0x41, 	/* 35260 */
+	0x60,  0x3F,  0x82,  0x00,  0x20,  0x00,  0x20,  0x7D,  0xFE,  0x44,  0x20,  0x44,  0x20,  0x44,  0x20,  0x47, 	/* 35270 */
+	0xFF,  0x7C,  0x04,  0x44,  0x04,  0x47,  0xFF,  0x45,  0x04,  0x44,  0x84,  0x7C,  0x84,  0x00,  0x04,  0x00, 	/* 35280 */
+	0x04,  0x00,  0x0C,  0x83,  0x00,  0x00,  0x1F,  0xF8,  0x10,  0x08,  0x1F,  0xF8,  0x10,  0x08,  0x1F,  0xF8, 	/* 35290 */
+	0x08,  0x88,  0x04,  0x90,  0x04,  0xA0,  0x7F,  0xFF,  0x02,  0x40,  0x02,  0x40,  0x02,  0x40,  0x04,  0x42, 	/* 352A0 */
+	0x18,  0x22,  0x60,  0x1E,  0x84,  0x00,  0x20,  0x00,  0x22,  0x7E,  0x22,  0x45,  0x24,  0x44,  0xA4,  0x44, 	/* 352B0 */
+	0xA8,  0x44,  0x20,  0x7F,  0xFF,  0x44,  0x48,  0x44,  0x48,  0x44,  0x48,  0x44,  0x48,  0x7C,  0x88,  0x00, 	/* 352C0 */
+	0x89,  0x03,  0x09,  0x0C,  0x07,  0x89,  0x00,  0x00,  0x3F,  0xFE,  0x04,  0x10,  0x05,  0x14,  0x09,  0xA6, 	/* 352D0 */
+	0x3E,  0x79,  0x00,  0x00,  0x7F,  0xFF,  0x00,  0x00,  0x0F,  0xF8,  0x08,  0x08,  0x0F,  0xF8,  0x08,  0x08, 	/* 352E0 */
+	0x08,  0x08,  0x0F,  0xF8,  0x00,  0x00,  0x8B,  0x00,  0x00,  0x3F,  0xFE,  0x02,  0x20,  0x12,  0x24,  0x0A, 	/* 352F0 */
+	0x24,  0x0A,  0x28,  0x02,  0x20,  0x7F,  0xFF,  0x00,  0x00,  0x0F,  0xF8,  0x08,  0x08,  0x0F,  0xF8,  0x08, 	/* 35300 */
+	0x08,  0x08,  0x08,  0x0F,  0xF8,  0x00,  0x00,  0x8F,  0x00,  0x00,  0x0F,  0xF8,  0x08,  0x08,  0x0F,  0xF8, 	/* 35310 */
+	0x08,  0x08,  0x0F,  0xF8,  0x00,  0x80,  0x3F,  0xFE,  0x20,  0x02,  0x21,  0x02,  0x7F,  0xFF,  0x02,  0x10, 	/* 35320 */
+	0x07,  0x10,  0x00,  0xE0,  0x03,  0x98,  0x3C,  0x04,  0x92,  0x00,  0x00,  0x07,  0xFF,  0x78,  0x50,  0x48, 	/* 35330 */
+	0x50,  0x48,  0x50,  0x4B,  0xFE,  0x4A,  0x52,  0x7A,  0x52,  0x4A,  0x52,  0x4A,  0x52,  0x4A,  0x9E,  0x4B, 	/* 35340 */
+	0x02,  0x7A,  0x02,  0x02,  0x02,  0x03,  0xFE,  0x00,  0x00,  0x9D,  0x00,  0x80,  0x1F,  0xFC,  0x00,  0x84, 	/* 35350 */
+	0x7F,  0xFF,  0x00,  0x84,  0x1F,  0xFC,  0x00,  0x80,  0x1F,  0xFC,  0x00,  0x80,  0x7F,  0xFF,  0x08,  0x08, 	/* 35360 */
+	0x0F,  0xF8,  0x08,  0x08,  0x0F,  0xF8,  0x00,  0x00,  0x7F,  0xFF,  0x9E,  0x00,  0x04,  0x01,  0xC8,  0x78, 	/* 35370 */
+	0x30,  0x48,  0x68,  0x4B,  0x84,  0x48,  0x40,  0x4F,  0xFF,  0x78,  0xA0,  0x49,  0x20,  0x4B,  0xFC,  0x4D, 	/* 35380 */
+	0x24,  0x49,  0x24,  0x79,  0x24,  0x01,  0x38,  0x01,  0x20,  0x00,  0x20,  0x9F,  0x00,  0x00,  0x1F,  0xFC, 	/* 35390 */
+	0x10,  0x04,  0x1F,  0xFC,  0x10,  0x04,  0x1F,  0xFC,  0x00,  0x50,  0x00,  0x48,  0x1F,  0xFE,  0x10,  0x44, 	/* 353A0 */
+	0x1F,  0x24,  0x11,  0x28,  0x11,  0x10,  0x21,  0x29,  0x2E,  0x45,  0x41,  0x83,  0xA2,  0x08,  0x04,  0x08, 	/* 353B0 */
+	0x78,  0x7F,  0x40,  0x08,  0x40,  0x08,  0x7F,  0x0E,  0x48,  0x78,  0x88,  0x08,  0x88,  0x19,  0x08,  0x0F, 	/* 353C0 */
+	0xF8,  0x08,  0x08,  0x0F,  0xF8,  0x08,  0x08,  0x08,  0x08,  0x0F,  0xF8,  0x00,  0x00,  0xA4,  0x00,  0x00, 	/* 353D0 */
+	0x03,  0xFE,  0x78,  0x40,  0x48,  0x40,  0x4B,  0xF8,  0x48,  0x88,  0x48,  0x88,  0x78,  0x88,  0x4F,  0xFF, 	/* 353E0 */
+	0x48,  0x00,  0x49,  0xFC,  0x49,  0x04,  0x79,  0x04,  0x01,  0x04,  0x01,  0xFC,  0x00,  0x00,  0xA6,  0x00, 	/* 353F0 */
+	0x80,  0x00,  0x80,  0x78,  0xFF,  0x49,  0x00,  0x49,  0x00,  0x4A,  0xFC,  0x4C,  0xA4,  0x78,  0xA4,  0x4F, 	/* 35400 */
+	0xFF,  0x49,  0x24,  0x49,  0x24,  0x49,  0x24,  0x7B,  0xFF,  0x02,  0x04,  0x00,  0x08,  0x00,  0x30,  0xA7, 	/* 35410 */
+	0x00,  0x20,  0x00,  0xA0,  0x3C,  0xA0,  0x25,  0xFE,  0x25,  0x20,  0x26,  0x20,  0x24,  0x20,  0x3F,  0xFF, 	/* 35420 */
+	0x24,  0x20,  0x24,  0x00,  0x25,  0xFC,  0x25,  0x04,  0x3D,  0x04,  0x01,  0x04,  0x01,  0xFC,  0x00,  0x00, 	/* 35430 */
+	0xA8,  0x00,  0x00,  0x0F,  0xF8,  0x08,  0x08,  0x0F,  0xF8,  0x08,  0x08,  0x0F,  0xF8,  0x00,  0x00,  0x1F, 	/* 35440 */
+	0xFE,  0x10,  0x00,  0x17,  0xFC,  0x10,  0x00,  0x1F,  0xFF,  0x22,  0x44,  0x22,  0x28,  0x43,  0x98,  0x0E, 	/* 35450 */
+	0x07,  0xA9,  0x00,  0x40,  0x7C,  0x78,  0x44,  0x88,  0x45,  0x10,  0x46,  0x20,  0x45,  0xFC,  0x7D,  0x24, 	/* 35460 */
+	0x45,  0x24,  0x45,  0x24,  0x45,  0xFC,  0x44,  0x50,  0x7C,  0x50,  0x00,  0x90,  0x01,  0x11,  0x02,  0x11, 	/* 35470 */
+	0x04,  0x0F,  0xAE,  0x10,  0x10,  0x08,  0x10,  0x04,  0x20,  0x3F,  0xFC,  0x12,  0x48,  0x0A,  0x48,  0x0A, 	/* 35480 */
+	0x50,  0x7F,  0xFF,  0x00,  0x00,  0x0F,  0xF0,  0x08,  0x10,  0x0F,  0xF0,  0x08,  0x10,  0x08,  0x10,  0x0F, 	/* 35490 */
+	0xF0,  0x00,  0x00,  0xAF,  0x00,  0x00,  0x0F,  0xF8,  0x08,  0x08,  0x0F,  0xF8,  0x08,  0x08,  0x0F,  0xF8, 	/* 354A0 */
+	0x00,  0x80,  0x7F,  0xFF,  0x00,  0x00,  0x0F,  0xF8,  0x08,  0x08,  0x0F,  0xF8,  0x02,  0xB0,  0x0C,  0x8C, 	/* 354B0 */
+	0x30,  0x82,  0x01,  0x80,  0xB0,  0x01,  0x02,  0x01,  0x0C,  0x79,  0x30,  0x4F,  0xE0,  0x49,  0x20,  0x49, 	/* 354C0 */
+	0x3F,  0x49,  0xA4,  0x7B,  0x64,  0x4B,  0x24,  0x4D,  0x24,  0x49,  0x24,  0x49,  0x24,  0x79,  0x44,  0x01, 	/* 354D0 */
+	0x44,  0x01,  0x84,  0x01,  0x04,  0xB4,  0x00,  0x20,  0x00,  0x20,  0x3D,  0xFE,  0x24,  0x20,  0x25,  0xFC, 	/* 354E0 */
+	0x24,  0x20,  0x3F,  0xFF,  0x24,  0x00,  0x24,  0xFC,  0x24,  0x84,  0x24,  0xFC,  0x3C,  0x84,  0x00,  0xFC, 	/* 354F0 */
+	0x00,  0x84,  0x00,  0x84,  0x00,  0x8C,  0xB6,  0x00,  0x00,  0x0F,  0xF0,  0x08,  0x10,  0x08,  0x10,  0x0F, 	/* 35500 */
+	0xF0,  0x08,  0x10,  0x08,  0x10,  0x0F,  0xF0,  0x00,  0x00,  0x7E,  0x7E,  0x42,  0x42,  0x42,  0x42,  0x7E, 	/* 35510 */
+	0x7E,  0x42,  0x42,  0x7E,  0x7E,  0x00,  0x00,  0xBA,  0x10,  0x00,  0x1F,  0xBE,  0x14,  0x22,  0x24,  0x22, 	/* 35520 */
+	0x7F,  0xE2,  0x06,  0x22,  0x05,  0x3E,  0x08,  0x80,  0x10,  0x00,  0x6F,  0xF8,  0x08,  0x08,  0x0F,  0xF8, 	/* 35530 */
+	0x08,  0x08,  0x08,  0x08,  0x0F,  0xF8,  0x00,  0x00,  0x81,  0x00,  0x20,  0x00,  0x20,  0x79,  0xFC,  0x48, 	/* 35540 */
+	0x20,  0x48,  0xA8,  0x48,  0x88,  0x4F,  0xFF,  0x78,  0x88,  0x48,  0x88,  0x48,  0x00,  0x4B,  0xFE,  0x48, 	/* 35550 */
+	0x90,  0x78,  0x90,  0x01,  0x11,  0x02,  0x11,  0x0C,  0x0F,  0x83,  0x00,  0x00,  0x1F,  0xF8,  0x10,  0x08, 	/* 35560 */
+	0x1F,  0xF8,  0x10,  0x08,  0x1F,  0xF8,  0x00,  0x40,  0x02,  0x40,  0x3E,  0x7E,  0x02,  0x40,  0x3E,  0x7E, 	/* 35570 */
+	0x02,  0x40,  0x0E,  0x7F,  0x74,  0x40,  0x08,  0x40,  0x10,  0x40,  0x84,  0x00,  0x20,  0x00,  0x20,  0x7B, 	/* 35580 */
+	0xFF,  0x4A,  0x01,  0x4A,  0xFD,  0x48,  0x00,  0x48,  0xFC,  0x78,  0x84,  0x48,  0x84,  0x48,  0xFC,  0x48, 	/* 35590 */
+	0x84,  0x48,  0x84,  0x78,  0xFC,  0x00,  0x00,  0x03,  0xFF,  0x00,  0x00,  0x87,  0x00,  0x00,  0x03,  0xDE, 	/* 355A0 */
+	0x7A,  0x42,  0x4A,  0x42,  0x4A,  0x42,  0x4B,  0xDE,  0x4A,  0x00,  0x7A,  0x3E,  0x4B,  0xE2,  0x4A,  0x14, 	/* 355B0 */
+	0x4A,  0x14,  0x4A,  0x08,  0x7B,  0xC8,  0x02,  0x14,  0x02,  0x22,  0x02,  0x41,  0x88,  0x0F,  0xF8,  0x08, 	/* 355C0 */
+	0x08,  0x0F,  0xF8,  0x08,  0x08,  0x7F,  0xFE,  0x40,  0x82,  0x5F,  0xFC,  0x00,  0x80,  0x0F,  0xF8,  0x08, 	/* 355D0 */
+	0x88,  0x0F,  0xF8,  0x08,  0x88,  0x0F,  0xF8,  0x00,  0x80,  0x7F,  0xFF,  0x00,  0x80,  0x89,  0x00,  0x00, 	/* 355E0 */
+	0x03,  0xFE,  0x7A,  0x02,  0x4A,  0x22,  0x49,  0xFC,  0x48,  0x20,  0x49,  0xFC,  0x79,  0x24,  0x49,  0xFC, 	/* 355F0 */
+	0x49,  0x24,  0x49,  0x24,  0x49,  0xFC,  0x78,  0x20,  0x07,  0xFF,  0x00,  0x20,  0x00,  0x20,  0x8E,  0x00, 	/* 35600 */
+	0x88,  0x00,  0x88,  0x7B,  0xFF,  0x48,  0x88,  0x48,  0x88,  0x48,  0x20,  0x49,  0xFC,  0x79,  0x24,  0x49, 	/* 35610 */
+	0x24,  0x49,  0x24,  0x4F,  0xFF,  0x48,  0x20,  0x78,  0x50,  0x00,  0x88,  0x03,  0x04,  0x0C,  0x03,  0x91, 	/* 35620 */
+	0x00,  0x00,  0x0F,  0xF8,  0x08,  0x08,  0x0F,  0xF8,  0x08,  0x0A,  0x0F,  0xFA,  0x00,  0x84,  0x1F,  0xF8, 	/* 35630 */
+	0x00,  0x90,  0x7F,  0xFF,  0x01,  0x00,  0x07,  0xF8,  0x1C,  0x08,  0x67,  0xF8,  0x04,  0x08,  0x07,  0xF8, 	/* 35640 */
+	0x96,  0x00,  0x04,  0x00,  0x1A,  0x3D,  0xE2,  0x24,  0x24,  0x24,  0x94,  0x24,  0x58,  0x25,  0xFE,  0x3C, 	/* 35650 */
+	0x40,  0x27,  0xFF,  0x24,  0x40,  0x24,  0x7C,  0x24,  0xA4,  0x3C,  0x98,  0x01,  0x10,  0x02,  0x6C,  0x01, 	/* 35660 */
+	0x83,  0x97,  0x00,  0x20,  0x00,  0x20,  0x7F,  0xFE,  0x44,  0x88,  0x44,  0x48,  0x44,  0x50,  0x47,  0xFF, 	/* 35670 */
+	0x7C,  0x00,  0x44,  0xFC,  0x44,  0x84,  0x44,  0x84,  0x44,  0xFC,  0x7C,  0x84,  0x00,  0x84,  0x00,  0xFC, 	/* 35680 */
+	0x00,  0x00,  0x98,  0x00,  0x00,  0x01,  0xF8,  0x79,  0x08,  0x49,  0xF8,  0x49,  0x08,  0x49,  0x08,  0x49, 	/* 35690 */
+	0xF8,  0x78,  0x00,  0x4F,  0xFF,  0x48,  0x80,  0x49,  0xFE,  0x4E,  0x52,  0x78,  0x92,  0x03,  0x22,  0x00, 	/* 356A0 */
+	0x42,  0x01,  0x9C,  0x9D,  0x00,  0x00,  0x03,  0xFF,  0x7A,  0x01,  0x4A,  0xFD,  0x48,  0x84,  0x48,  0x84, 	/* 356B0 */
+	0x48,  0xFC,  0x78,  0x84,  0x48,  0x84,  0x48,  0xFC,  0x48,  0x20,  0x4B,  0xFF,  0x78,  0x00,  0x00,  0x48, 	/* 356C0 */
+	0x01,  0x84,  0x06,  0x02,  0xA2,  0x10,  0x00,  0x10,  0xF8,  0x10,  0x88,  0x7E,  0xF8,  0x52,  0x88,  0x52, 	/* 356D0 */
+	0x88,  0x7E,  0xF8,  0x52,  0x00,  0x53,  0xFF,  0x52,  0x40,  0x7E,  0xFE,  0x13,  0x4A,  0x10,  0x92,  0x13, 	/* 356E0 */
+	0x22,  0x10,  0x42,  0x11,  0x8C,  0xA6,  0x00,  0x00,  0x1F,  0xFF,  0x11,  0x08,  0x11,  0x08,  0x1F,  0xFF, 	/* 356F0 */
+	0x13,  0x9C,  0x15,  0x6A,  0x19,  0x49,  0x11,  0x08,  0x17,  0xFC,  0x14,  0x04,  0x17,  0xFC,  0x24,  0x04, 	/* 35700 */
+	0x24,  0x04,  0x47,  0xFC,  0x00,  0x00,  0xAB,  0x04,  0x02,  0x7F,  0xCC,  0x04,  0x30,  0x3F,  0xA0,  0x24, 	/* 35710 */
+	0xBF,  0x3F,  0xA4,  0x24,  0xA4,  0x7F,  0xC4,  0x04,  0x44,  0x04,  0x84,  0x0F,  0xF8,  0x08,  0x08,  0x0F, 	/* 35720 */
+	0xF8,  0x08,  0x08,  0x0F,  0xF8,  0x00,  0x00,  0xAE,  0x02,  0x20,  0x7F,  0xFF,  0x02,  0x20,  0x0F,  0xF8, 	/* 35730 */
+	0x08,  0x08,  0x0F,  0xF8,  0x08,  0x08,  0x0F,  0xF8,  0x01,  0x00,  0x7F,  0xFF,  0x02,  0x10,  0x1F,  0xFC, 	/* 35740 */
+	0x64,  0x13,  0x07,  0xF0,  0x04,  0x10,  0x07,  0xF0,  0xB4,  0x00,  0x00,  0x0F,  0xF8,  0x08,  0x08,  0x0F, 	/* 35750 */
+	0xF8,  0x08,  0x08,  0x0F,  0xF8,  0x02,  0x20,  0x1F,  0xFC,  0x02,  0x20,  0x7F,  0xFF,  0x04,  0x88,  0x18, 	/* 35760 */
+	0x96,  0x65,  0xE1,  0x06,  0xB0,  0x38,  0x8E,  0x01,  0x80,  0xB8,  0x00,  0x20,  0x00,  0x20,  0x7B,  0xFF, 	/* 35770 */
+	0x48,  0x50,  0x4A,  0x8A,  0x49,  0x04,  0x4B,  0xFE,  0x7D,  0x05,  0x49,  0xFC,  0x49,  0x04,  0x49,  0xFC, 	/* 35780 */
+	0x49,  0x20,  0x79,  0x24,  0x02,  0x22,  0x04,  0x22,  0x00,  0x60,  0xB9,  0x10,  0x00,  0x09,  0xFC,  0x09, 	/* 35790 */
+	0x04,  0x01,  0xFC,  0x21,  0x04,  0x11,  0xFC,  0x10,  0x90,  0x01,  0xFE,  0x7B,  0x20,  0x0D,  0xFC,  0x09, 	/* 357A0 */
+	0x20,  0x09,  0xFC,  0x15,  0x20,  0x13,  0xFE,  0x21,  0x80,  0x40,  0x7F,  0xBC,  0x08,  0x20,  0x2A,  0x20, 	/* 357B0 */
+	0x49,  0x3F,  0x7F,  0x44,  0x49,  0x64,  0x5D,  0x98,  0x6B,  0x18,  0x49,  0x24,  0x4B,  0x43,  0x1F,  0xF8, 	/* 357C0 */
+	0x10,  0x08,  0x1F,  0xF8,  0x10,  0x08,  0x10,  0x08,  0x1F,  0xF8,  0x00,  0x00,  0xBE,  0x01,  0x08,  0x01, 	/* 357D0 */
+	0x08,  0x7F,  0xE8,  0x48,  0x0F,  0x4B,  0xD2,  0x4A,  0x52,  0x4B,  0xE2,  0x78,  0x0A,  0x4F,  0xCA,  0x48, 	/* 357E0 */
+	0x8C,  0x49,  0x04,  0x49,  0xCC,  0x7F,  0x0C,  0x01,  0x12,  0x01,  0x22,  0x03,  0x41,  0x81,  0x08,  0x00, 	/* 357F0 */
+	0x3F,  0x7E,  0x21,  0x48,  0x3F,  0x48,  0x21,  0xFF,  0x3F,  0x18,  0x26,  0x28,  0x3D,  0x49,  0x6F,  0xFF, 	/* 35800 */
+	0x08,  0x08,  0x0F,  0xF8,  0x08,  0x08,  0x0F,  0xF8,  0x00,  0x00,  0x7F,  0xFF,  0x00,  0x00,  0x84,  0x00, 	/* 35810 */
+	0x88,  0x00,  0x88,  0x7B,  0xFF,  0x48,  0x88,  0x4B,  0xFE,  0x49,  0x24,  0x49,  0x24,  0x7F,  0xFF,  0x49, 	/* 35820 */
+	0x24,  0x49,  0x24,  0x4B,  0xFE,  0x48,  0x20,  0x78,  0x20,  0x07,  0xFF,  0x00,  0x20,  0x00,  0x20,  0x87, 	/* 35830 */
+	0x00,  0x00,  0x0F,  0xF0,  0x08,  0x10,  0x0F,  0xF0,  0x08,  0x10,  0x3F,  0xFC,  0x01,  0x00,  0x7F,  0xFE, 	/* 35840 */
+	0x5D,  0x7A,  0x41,  0x02,  0x1F,  0xF8,  0x00,  0x00,  0x7F,  0xFE,  0x02,  0x20,  0x04,  0xD8,  0x3F,  0x04, 	/* 35850 */
+	0x89,  0x00,  0x20,  0x01,  0xFC,  0x78,  0x20,  0x4B,  0xFE,  0x48,  0x00,  0x48,  0x84,  0x7B,  0xFF,  0x48, 	/* 35860 */
+	0x84,  0x48,  0xE4,  0x4F,  0x1F,  0x48,  0x00,  0x7B,  0xFF,  0x00,  0x48,  0x00,  0x89,  0x03,  0x09,  0x0C, 	/* 35870 */
+	0x07,  0x96,  0x00,  0x0C,  0x03,  0xF4,  0x79,  0x44,  0x48,  0xA8,  0x4F,  0xFF,  0x4C,  0xA5,  0x4A,  0x8A, 	/* 35880 */
+	0x7A,  0x79,  0x4C,  0x41,  0x48,  0x7C,  0x48,  0x84,  0x49,  0x68,  0x7E,  0x10,  0x00,  0x70,  0x01,  0x8C, 	/* 35890 */
+	0x0E,  0x03,  0x99,  0x00,  0x00,  0x07,  0xFE,  0x04,  0x92,  0x7F,  0xFE,  0x48,  0x42,  0x4B,  0xFC,  0x48, 	/* 358A0 */
+	0x48,  0x7F,  0xFF,  0x48,  0x60,  0x49,  0xFC,  0x4B,  0x04,  0x4D,  0xFC,  0x79,  0x04,  0x01,  0x04,  0x01, 	/* 358B0 */
+	0xFC,  0x00,  0x00,  0x9A,  0x00,  0x88,  0x07,  0xFF,  0x78,  0x88,  0x4B,  0xFE,  0x4A,  0x02,  0x4A,  0xFA, 	/* 358C0 */
+	0x48,  0x00,  0x7F,  0xFF,  0x48,  0x40,  0x48,  0xAA,  0x4B,  0x5A,  0x48,  0x94,  0x7B,  0x34,  0x00,  0xD2, 	/* 358D0 */
+	0x07,  0x11,  0x00,  0x60,  0x9C,  0x00,  0x00,  0x03,  0xDE,  0x78,  0x42,  0x4B,  0xDE,  0x48,  0x42,  0x4B, 	/* 358E0 */
+	0xDE,  0x48,  0x88,  0x78,  0x90,  0x49,  0xFE,  0x4B,  0x10,  0x4D,  0xFC,  0x49,  0x10,  0x79,  0xFC,  0x01, 	/* 358F0 */
+	0x10,  0x01,  0xFF,  0x00,  0x00,  0x9D,  0x00,  0xFC,  0x3C,  0x84,  0x24,  0xFC,  0x24,  0x84,  0x24,  0xFC, 	/* 35900 */
+	0x24,  0x48,  0x3D,  0xFE,  0x24,  0x48,  0x27,  0xFF,  0x24,  0x48,  0x24,  0xA4,  0x25,  0xAB,  0x3E,  0x70, 	/* 35910 */
+	0x00,  0xA8,  0x01,  0x26,  0x00,  0x60,  0xA0,  0x00,  0x20,  0x00,  0x20,  0x7B,  0xFF,  0x4A,  0x48,  0x4B, 	/* 35920 */
+	0xFF,  0x4A,  0x48,  0x7A,  0x78,  0x4B,  0xFF,  0x4A,  0x10,  0x4A,  0xFE,  0x4A,  0x92,  0x7C,  0xFE,  0x04, 	/* 35930 */
+	0x92,  0x08,  0xFE,  0x10,  0x66,  0x03,  0x81,  0xA6,  0x01,  0x04,  0x00,  0x88,  0x7B,  0xFE,  0x48,  0x20, 	/* 35940 */
+	0x49,  0xFC,  0x48,  0x20,  0x4F,  0xFF,  0x78,  0x44,  0x4B,  0x8A,  0x48,  0x88,  0x4F,  0xFF,  0x49,  0xCA, 	/* 35950 */
+	0x7A,  0xA4,  0x05,  0xD5,  0x00,  0x4B,  0x01,  0x91,  0xA9,  0x0F,  0xF8,  0x08,  0x08,  0x0F,  0xF8,  0x08, 	/* 35960 */
+	0x08,  0x0F,  0xF8,  0x00,  0x80,  0x7F,  0xFF,  0x09,  0x48,  0x0F,  0x78,  0x02,  0x20,  0x0F,  0xF8,  0x02, 	/* 35970 */
+	0x20,  0x7F,  0xFF,  0x0C,  0x48,  0x77,  0x30,  0x0C,  0x0E,  0xB0,  0x00,  0x00,  0x3F,  0xFC,  0x20,  0x04, 	/* 35980 */
+	0x20,  0x04,  0x20,  0x04,  0x20,  0x04,  0x20,  0x04,  0x3F,  0xC4,  0x20,  0x04,  0x20,  0x04,  0x20,  0x04, 	/* 35990 */
+	0x20,  0x04,  0x20,  0x04,  0x20,  0x04,  0x3F,  0xFC,  0x00,  0x00,  0xB2,  0x02,  0x20,  0x02,  0x20,  0x02, 	/* 359A0 */
+	0x20,  0x02,  0x20,  0x3F,  0xFE,  0x22,  0x22,  0x22,  0x22,  0x22,  0x22,  0x22,  0x22,  0x3F,  0xFE,  0x22, 	/* 359B0 */
+	0x22,  0x22,  0x22,  0x22,  0x22,  0x22,  0x22,  0x3F,  0xFE,  0x00,  0x00,  0xB3,  0x01,  0x00,  0x01,  0x00, 	/* 359C0 */
+	0x1F,  0xF8,  0x11,  0x08,  0x11,  0x08,  0x1F,  0xF8,  0x11,  0x08,  0x11,  0x08,  0x11,  0x0C,  0x1F,  0xF8, 	/* 359D0 */
+	0x01,  0x10,  0x00,  0xE0,  0x01,  0x82,  0x0E,  0x42,  0x70,  0x32,  0x00,  0x0E,  0xB4,  0x00,  0x00,  0x7F, 	/* 359E0 */
+	0xFF,  0x00,  0x80,  0x1F,  0xF8,  0x10,  0x88,  0x10,  0x88,  0x1F,  0xF8,  0x10,  0x88,  0x10,  0x88,  0x1F, 	/* 359F0 */
+	0xF8,  0x04,  0x80,  0x02,  0x80,  0x01,  0x00,  0x02,  0xC0,  0x0C,  0x38,  0x70,  0x07,  0xB5,  0x01,  0x00, 	/* 35A00 */
+	0x01,  0x10,  0x01,  0x08,  0x1F,  0xFC,  0x11,  0x04,  0x11,  0x04,  0x1F,  0xE4,  0x11,  0x04,  0x11,  0x04, 	/* 35A10 */
+	0x1F,  0xFC,  0x01,  0x10,  0x00,  0xA0,  0x00,  0xC1,  0x07,  0x21,  0x78,  0x19,  0x00,  0x07,  0xB7,  0x00, 	/* 35A20 */
+	0x00,  0x0F,  0xF8,  0x08,  0x08,  0x0F,  0xF8,  0x08,  0x08,  0x08,  0x08,  0x0F,  0xF8,  0x02,  0x00,  0x07, 	/* 35A30 */
+	0xFC,  0x08,  0x84,  0x18,  0xC4,  0x69,  0x24,  0x0A,  0x04,  0x0F,  0xF4,  0x00,  0x04,  0x00,  0x18,  0xB8, 	/* 35A40 */
+	0x00,  0x80,  0x1F,  0xFC,  0x00,  0x84,  0x7F,  0xFF,  0x00,  0x84,  0x1F,  0xFC,  0x00,  0x80,  0x1F,  0xFC, 	/* 35A50 */
+	0x00,  0x80,  0x7F,  0xFF,  0x0F,  0xF8,  0x08,  0x08,  0x0F,  0xF8,  0x08,  0x08,  0x0F,  0xF8,  0x00,  0x00, 	/* 35A60 */
+	0xB9,  0x02,  0x40,  0x02,  0x40,  0x7F,  0xFE,  0x02,  0x40,  0x3F,  0xFC,  0x22,  0x44,  0x3F,  0xFC,  0x22, 	/* 35A70 */
+	0x44,  0x3F,  0xFC,  0x00,  0x00,  0x0F,  0xF0,  0x08,  0x10,  0x0F,  0xF0,  0x08,  0x10,  0x0F,  0xF0,  0x00, 	/* 35A80 */
+	0x00,  0xBC,  0x00,  0x00,  0x0F,  0xF8,  0x08,  0x08,  0x0F,  0xF8,  0x08,  0x08,  0x0F,  0xF8,  0x00,  0x00, 	/* 35A90 */
+	0x3F,  0xFE,  0x22,  0x22,  0x3F,  0xFE,  0x00,  0x00,  0x3F,  0xF8,  0x06,  0x20,  0x01,  0xC0,  0x07,  0x38, 	/* 35AA0 */
+	0x78,  0x07,  0xBD,  0x08,  0x10,  0x04,  0x20,  0x3F,  0xFC,  0x21,  0x04,  0x21,  0x04,  0x3F,  0xFC,  0x21, 	/* 35AB0 */
+	0x04,  0x3F,  0xFC,  0x00,  0x00,  0x0F,  0xF0,  0x08,  0x10,  0x0F,  0xF0,  0x08,  0x10,  0x08,  0x10,  0x0F, 	/* 35AC0 */
+	0xF0,  0x00,  0x00,  0xBE,  0x07,  0xF0,  0x00,  0x10,  0x08,  0x08,  0x1F,  0xFC,  0x30,  0x96,  0x54,  0x95, 	/* 35AD0 */
+	0x12,  0xA4,  0x1F,  0xFC,  0x00,  0x00,  0x0F,  0xF8,  0x08,  0x08,  0x0F,  0xF8,  0x08,  0x08,  0x08,  0x08, 	/* 35AE0 */
+	0x0F,  0xF8,  0x00,  0x00,  0xBF,  0x04,  0x10,  0x04,  0x10,  0x3F,  0x7E,  0x04,  0x10,  0x04,  0x10,  0x7F, 	/* 35AF0 */
+	0xFF,  0x0A,  0x28,  0x11,  0x44,  0x20,  0x82,  0x4F,  0xF1,  0x08,  0x10,  0x08,  0x10,  0x0F,  0xF0,  0x08, 	/* 35B00 */
+	0x10,  0x08,  0x10,  0x0F,  0xF0,  0x80,  0x00,  0x00,  0x0F,  0xF8,  0x08,  0x08,  0x0F,  0xF8,  0x08,  0x08, 	/* 35B10 */
+	0x0F,  0xF8,  0x00,  0x00,  0x7F,  0xFF,  0x11,  0x00,  0x1F,  0x7C,  0x11,  0x44,  0x1F,  0x28,  0x11,  0x18, 	/* 35B20 */
+	0x1F,  0x24,  0x61,  0xC2,  0x01,  0x01,  0x83,  0x00,  0x80,  0x00,  0x80,  0x01,  0x40,  0x06,  0x30,  0x18, 	/* 35B30 */
+	0x0C,  0x7F,  0xFF,  0x14,  0x94,  0x12,  0xA4,  0x1F,  0xFC,  0x00,  0x00,  0x0F,  0xF8,  0x08,  0x08,  0x0F, 	/* 35B40 */
+	0xF8,  0x08,  0x08,  0x0F,  0xF8,  0x00,  0x00,  0x88,  0x00,  0x00,  0x0F,  0xF8,  0x08,  0x08,  0x08,  0x08, 	/* 35B50 */
+	0x08,  0x08,  0x0F,  0xF8,  0x08,  0x08,  0x08,  0x08,  0x08,  0x08,  0x0F,  0xF8,  0x08,  0x08,  0x08,  0x08, 	/* 35B60 */
+	0x10,  0x08,  0x10,  0x08,  0x20,  0x08,  0x40,  0x38,  0x89,  0x01,  0x00,  0x01,  0x00,  0x7F,  0xFF,  0x02, 	/* 35B70 */
+	0x00,  0x02,  0x00,  0x07,  0xF8,  0x0C,  0x08,  0x0C,  0x08,  0x17,  0xF8,  0x24,  0x08,  0x44,  0x08,  0x07, 	/* 35B80 */
+	0xF8,  0x04,  0x08,  0x04,  0x08,  0x04,  0x08,  0x04,  0x18,  0x8B,  0x00,  0x00,  0x1F,  0x3E,  0x11,  0x22, 	/* 35B90 */
+	0x11,  0x22,  0x11,  0x22,  0x1F,  0x3E,  0x11,  0x22,  0x11,  0x22,  0x11,  0x22,  0x1F,  0x3E,  0x11,  0x22, 	/* 35BA0 */
+	0x11,  0x22,  0x11,  0x22,  0x21,  0x42,  0x21,  0x42,  0x43,  0x86,  0x8D,  0x00,  0x00,  0x3E,  0xFE,  0x22, 	/* 35BB0 */
+	0x82,  0x22,  0x82,  0x22,  0x8C,  0x3E,  0x80,  0x22,  0x80,  0x22,  0xFE,  0x22,  0xA2,  0x3E,  0xA4,  0x22, 	/* 35BC0 */
+	0x94,  0x22,  0x98,  0x22,  0x88,  0x22,  0x94,  0x22,  0xA2,  0x46,  0xC1,  0x8F,  0x00,  0x10,  0x3E,  0x10, 	/* 35BD0 */
+	0x22,  0x92,  0x22,  0x92,  0x22,  0x92,  0x3E,  0x92,  0x22,  0xFE,  0x22,  0x10,  0x22,  0x10,  0x3E,  0x92, 	/* 35BE0 */
+	0x22,  0x92,  0x22,  0x92,  0x22,  0x92,  0x22,  0x92,  0x22,  0xFE,  0x46,  0x00,  0x94,  0x21,  0x00,  0x11, 	/* 35BF0 */
+	0x3E,  0x12,  0x22,  0x7F,  0xA2,  0x04,  0x22,  0x04,  0x3E,  0x25,  0x22,  0x25,  0x22,  0x25,  0x22,  0x25, 	/* 35C00 */
+	0x3E,  0x3F,  0x22,  0x25,  0x22,  0x08,  0x42,  0x08,  0x42,  0x10,  0x82,  0x21,  0x06,  0x95,  0x00,  0x84, 	/* 35C10 */
+	0x3E,  0x44,  0x22,  0x48,  0x22,  0x10,  0x22,  0xFE,  0x3E,  0x10,  0x22,  0x10,  0x22,  0x10,  0x23,  0xFF, 	/* 35C20 */
+	0x3E,  0x10,  0x22,  0x28,  0x22,  0x28,  0x22,  0x44,  0x22,  0x44,  0x22,  0x82,  0x47,  0x01,  0x96,  0x00, 	/* 35C30 */
+	0x10,  0x3E,  0x10,  0x22,  0xFC,  0x22,  0x84,  0x22,  0x84,  0x3E,  0xFC,  0x22,  0x84,  0x22,  0x84,  0x22, 	/* 35C40 */
+	0xFE,  0x3E,  0x92,  0x22,  0x94,  0x22,  0x88,  0x22,  0x88,  0x22,  0xB4,  0x22,  0xC2,  0x47,  0x01,  0x97, 	/* 35C50 */
+	0x08,  0x00,  0x08,  0x3E,  0x3F,  0x22,  0x21,  0x22,  0x21,  0x22,  0x3F,  0x3E,  0x21,  0x22,  0x21,  0x22, 	/* 35C60 */
+	0x3F,  0x22,  0x20,  0x3E,  0x24,  0x22,  0x22,  0x22,  0x22,  0x42,  0x2D,  0x42,  0x30,  0x82,  0x61,  0x06, 	/* 35C70 */
+	0x9B,  0x08,  0x00,  0x08,  0x3E,  0x7F,  0xA2,  0x10,  0x3E,  0x10,  0x22,  0x10,  0x3E,  0x10,  0x22,  0x0F, 	/* 35C80 */
+	0x42,  0x00,  0x84,  0x3F,  0xFE,  0x00,  0x80,  0x1F,  0xFC,  0x00,  0x80,  0x00,  0x80,  0x7F,  0xFF,  0x00, 	/* 35C90 */
+	0x00,  0x9D,  0x08,  0x00,  0x08,  0x3E,  0x7F,  0xA2,  0x08,  0x22,  0x3F,  0x22,  0x21,  0x3E,  0x21,  0x22, 	/* 35CA0 */
+	0x3F,  0x22,  0x21,  0x22,  0x21,  0x3E,  0x3F,  0x22,  0x08,  0x22,  0x7F,  0xA2,  0x08,  0x42,  0x08,  0x42, 	/* 35CB0 */
+	0x08,  0x86,  0x9E,  0x04,  0x10,  0x3F,  0xFE,  0x04,  0x10,  0x07,  0xF0,  0x04,  0x10,  0x07,  0xF0,  0x04, 	/* 35CC0 */
+	0x10,  0x7F,  0xFF,  0x08,  0x08,  0x17,  0xF4,  0x24,  0x12,  0x47,  0xF1,  0x04,  0x10,  0x07,  0xF0,  0x04, 	/* 35CD0 */
+	0x10,  0x04,  0x30,  0x9F,  0x11,  0x00,  0x11,  0x3E,  0x7F,  0xE2,  0x11,  0x22,  0x11,  0x22,  0x1F,  0x3E, 	/* 35CE0 */
+	0x11,  0x22,  0x11,  0x22,  0x1F,  0x22,  0x11,  0x3E,  0x11,  0x22,  0x7F,  0xE2,  0x12,  0x22,  0x11,  0x42, 	/* 35CF0 */
+	0x21,  0x42,  0x40,  0x86,  0xA6,  0x00,  0x48,  0x3D,  0xFF,  0x24,  0x48,  0x25,  0xFE,  0x25,  0x02,  0x3D, 	/* 35D00 */
+	0x7A,  0x24,  0x00,  0x27,  0xFF,  0x24,  0x40,  0x3C,  0xAA,  0x27,  0x5A,  0x24,  0x94,  0x27,  0x34,  0x24, 	/* 35D10 */
+	0x52,  0x25,  0x91,  0x4C,  0x60,  0xA7,  0x00,  0x88,  0x3C,  0x88,  0x27,  0xFF,  0x25,  0x28,  0x24,  0xCF, 	/* 35D20 */
+	0x3F,  0xF1,  0x24,  0x0F,  0x25,  0xE8,  0x25,  0x2E,  0x3D,  0xE8,  0x25,  0x2E,  0x25,  0xE8,  0x25,  0x2E, 	/* 35D30 */
+	0x25,  0x29,  0x25,  0x29,  0x4D,  0x67,  0xA8,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x7F, 	/* 35D40 */
+	0xFF,  0x01,  0xC0,  0x01,  0xC0,  0x02,  0xA0,  0x02,  0xA0,  0x04,  0x90,  0x08,  0x88,  0x10,  0x84,  0x20, 	/* 35D50 */
+	0x82,  0x40,  0x81,  0x00,  0x80,  0x00,  0x80,  0xAA,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x1F,  0xFC, 	/* 35D60 */
+	0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x7F,  0xFF,  0x01,  0xC0,  0x02,  0xA0,  0x04,  0x90,  0x18,  0x8C, 	/* 35D70 */
+	0x60,  0x83,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0xAB,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x7F, 	/* 35D80 */
+	0xFF,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x1F,  0xFC,  0x00,  0x80,  0x01,  0xC0,  0x02,  0xA0,  0x04, 	/* 35D90 */
+	0x90,  0x18,  0x8C,  0x60,  0x83,  0x00,  0x80,  0x00,  0x80,  0xAC,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80, 	/* 35DA0 */
+	0x00,  0x80,  0x7F,  0xFF,  0x01,  0xC0,  0x02,  0xA0,  0x02,  0xA0,  0x04,  0x90,  0x08,  0x88,  0x10,  0x84, 	/* 35DB0 */
+	0x27,  0xF2,  0x40,  0x81,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0xAD,  0x08,  0x40,  0x08,  0x40,  0x08, 	/* 35DC0 */
+	0x40,  0x7F,  0x40,  0x08,  0x40,  0x08,  0x40,  0x1C,  0x40,  0x1A,  0x40,  0x19,  0x40,  0x28,  0x40,  0x28, 	/* 35DD0 */
+	0x40,  0x48,  0x42,  0x08,  0x42,  0x08,  0x22,  0x08,  0x1E,  0x08,  0x00,  0xAE,  0x00,  0x88,  0x00,  0x84, 	/* 35DE0 */
+	0x00,  0x84,  0x7F,  0xFF,  0x00,  0x80,  0x00,  0x80,  0x04,  0x90,  0x04,  0x90,  0x04,  0x90,  0x04,  0x90, 	/* 35DF0 */
+	0x04,  0x90,  0x08,  0x90,  0x08,  0x91,  0x10,  0x91,  0x20,  0x8F,  0x00,  0x80,  0xB1,  0x00,  0x80,  0x04, 	/* 35E00 */
+	0x80,  0x04,  0x80,  0x0F,  0xFC,  0x08,  0x80,  0x10,  0x80,  0x20,  0x80,  0x7F,  0xFF,  0x01,  0xC0,  0x02, 	/* 35E10 */
+	0xA0,  0x04,  0x90,  0x18,  0x8C,  0x60,  0x83,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0xB4,  0x08,  0x20, 	/* 35E20 */
+	0x08,  0x20,  0x08,  0x20,  0x7F,  0x20,  0x08,  0x20,  0x08,  0x30,  0x1C,  0x28,  0x1A,  0x24,  0x19,  0x22, 	/* 35E30 */
+	0x29,  0x22,  0x28,  0x20,  0x48,  0x20,  0x08,  0x20,  0x08,  0x20,  0x08,  0x20,  0x08,  0x20,  0xB6,  0x00, 	/* 35E40 */
+	0x00,  0x3F,  0xF0,  0x01,  0x10,  0x01,  0x10,  0x02,  0x3E,  0x04,  0x02,  0x08,  0x02,  0x30,  0x8C,  0x00, 	/* 35E50 */
+	0x80,  0x7F,  0xFF,  0x01,  0xC0,  0x02,  0xA0,  0x0C,  0x98,  0x70,  0x87,  0x00,  0x80,  0x00,  0x80,  0xB7, 	/* 35E60 */
+	0x08,  0x00,  0x09,  0xFE,  0x08,  0x22,  0x7F,  0x22,  0x08,  0x22,  0x08,  0x22,  0x1C,  0x22,  0x1A,  0x22, 	/* 35E70 */
+	0x1A,  0x22,  0x28,  0x42,  0x28,  0x42,  0x48,  0x42,  0x08,  0x82,  0x08,  0x82,  0x09,  0x02,  0x0A,  0x0C, 	/* 35E80 */
+	0xB8,  0x08,  0x20,  0x08,  0x20,  0x08,  0x20,  0x7F,  0x20,  0x09,  0xFE,  0x08,  0x22,  0x1C,  0x22,  0x1A, 	/* 35E90 */
+	0x22,  0x1A,  0x22,  0x28,  0x42,  0x28,  0x42,  0x48,  0x42,  0x08,  0x82,  0x08,  0x82,  0x09,  0x02,  0x0A, 	/* 35EA0 */
+	0x0C,  0xBA,  0x08,  0x00,  0x08,  0x78,  0x08,  0x48,  0x7F,  0x48,  0x08,  0x48,  0x08,  0x48,  0x1C,  0x48, 	/* 35EB0 */
+	0x1A,  0x48,  0x1A,  0x48,  0x28,  0x48,  0x28,  0x88,  0x48,  0x88,  0x09,  0x08,  0x09,  0x09,  0x0A,  0x09, 	/* 35EC0 */
+	0x0C,  0x07,  0xBD,  0x08,  0x00,  0x0B,  0xFF,  0x08,  0x20,  0x7E,  0x20,  0x08,  0x20,  0x08,  0x40,  0x1C, 	/* 35ED0 */
+	0x7C,  0x1A,  0x84,  0x1A,  0x84,  0x28,  0x04,  0x28,  0x04,  0x48,  0x04,  0x08,  0x04,  0x08,  0x04,  0x08, 	/* 35EE0 */
+	0x08,  0x08,  0x30,  0xBF,  0x00,  0x80,  0x00,  0x80,  0x7F,  0xFF,  0x00,  0x80,  0x00,  0x80,  0x1F,  0xFC, 	/* 35EF0 */
+	0x10,  0x84,  0x10,  0x84,  0x11,  0xC4,  0x11,  0xC4,  0x12,  0xB8,  0x04,  0x90,  0x18,  0x8C,  0x60,  0x83, 	/* 35F00 */
+	0x00,  0x80,  0x00,  0x80,  0x81,  0x08,  0x00,  0x08,  0x70,  0x08,  0x10,  0x7F,  0x10,  0x08,  0x10,  0x08, 	/* 35F10 */
+	0x10,  0x1C,  0x10,  0x1A,  0x10,  0x19,  0x18,  0x28,  0x28,  0x28,  0x28,  0x48,  0x48,  0x08,  0x44,  0x08, 	/* 35F20 */
+	0x84,  0x09,  0x02,  0x0A,  0x01,  0x86,  0x08,  0x00,  0x08,  0xFE,  0x08,  0x10,  0x7E,  0x10,  0x08,  0x10, 	/* 35F30 */
+	0x08,  0x10,  0x18,  0x10,  0x1D,  0xFF,  0x1A,  0x10,  0x2A,  0x10,  0x28,  0x10,  0x48,  0x10,  0x08,  0x10, 	/* 35F40 */
+	0x08,  0x10,  0x08,  0x10,  0x08,  0x10,  0x89,  0x08,  0x08,  0x08,  0x08,  0x08,  0x10,  0x7F,  0x90,  0x08, 	/* 35F50 */
+	0x24,  0x08,  0x44,  0x1C,  0x08,  0x1A,  0x08,  0x19,  0x12,  0x29,  0x22,  0x28,  0x44,  0x48,  0x04,  0x08, 	/* 35F60 */
+	0x08,  0x08,  0x10,  0x08,  0x20,  0x08,  0xC0,  0x8E,  0x00,  0x80,  0x00,  0x80,  0x7F,  0xFF,  0x01,  0xC0, 	/* 35F70 */
+	0x02,  0xA0,  0x0C,  0x98,  0x70,  0x87,  0x00,  0x80,  0x0F,  0xF0,  0x00,  0x20,  0x00,  0xC0,  0x7F,  0xFF, 	/* 35F80 */
+	0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x01,  0x80,  0x8F,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x7F, 	/* 35F90 */
+	0xFF,  0x01,  0xC0,  0x02,  0xA0,  0x04,  0x90,  0x18,  0x8C,  0x60,  0x83,  0x0F,  0xF8,  0x08,  0x08,  0x08, 	/* 35FA0 */
+	0x08,  0x08,  0x08,  0x08,  0x08,  0x0F,  0xF8,  0x00,  0x00,  0x90,  0x08,  0x08,  0x08,  0x08,  0x08,  0x08, 	/* 35FB0 */
+	0x7F,  0xFF,  0x08,  0x08,  0x08,  0x18,  0x1C,  0x18,  0x1A,  0x28,  0x19,  0x28,  0x29,  0x48,  0x28,  0x48, 	/* 35FC0 */
+	0x48,  0x88,  0x09,  0x08,  0x08,  0x08,  0x08,  0x08,  0x08,  0x18,  0x91,  0x08,  0x04,  0x08,  0x04,  0x08, 	/* 35FD0 */
+	0x04,  0x7F,  0xFF,  0x08,  0x04,  0x08,  0x04,  0x1C,  0x84,  0x1A,  0x44,  0x19,  0x24,  0x29,  0x24,  0x28, 	/* 35FE0 */
+	0x04,  0x48,  0x04,  0x08,  0x04,  0x08,  0x04,  0x08,  0x04,  0x08,  0x0C,  0x93,  0x08,  0x40,  0x08,  0x40, 	/* 35FF0 */
+	0x08,  0x40,  0x7F,  0x7E,  0x08,  0x82,  0x08,  0x82,  0x19,  0x02,  0x1C,  0x42,  0x1A,  0x22,  0x2A,  0x22, 	/* 36000 */
+	0x2A,  0x02,  0x48,  0x02,  0x08,  0x02,  0x08,  0x02,  0x08,  0x04,  0x08,  0x18,  0x96,  0x08,  0x10,  0x08, 	/* 36010 */
+	0x10,  0x08,  0x10,  0x7F,  0xFF,  0x08,  0x10,  0x08,  0x90,  0x18,  0x90,  0x1C,  0x50,  0x1A,  0x50,  0x2A, 	/* 36020 */
+	0x20,  0x28,  0x20,  0x48,  0x30,  0x08,  0x50,  0x08,  0x88,  0x09,  0x04,  0x0A,  0x03,  0x99,  0x08,  0x24, 	/* 36030 */
+	0x08,  0x22,  0x08,  0x22,  0x7F,  0x20,  0x09,  0xFF,  0x08,  0x20,  0x1C,  0x20,  0x1A,  0x20,  0x1A,  0x10, 	/* 36040 */
+	0x28,  0x10,  0x28,  0x10,  0x48,  0x08,  0x08,  0x09,  0x08,  0x05,  0x08,  0x03,  0x08,  0x01,  0x9C,  0x08, 	/* 36050 */
+	0x10,  0x08,  0x10,  0x08,  0x10,  0x7F,  0x10,  0x08,  0x10,  0x08,  0xFE,  0x1C,  0x10,  0x1A,  0x10,  0x19, 	/* 36060 */
+	0x10,  0x29,  0x10,  0x28,  0x10,  0x48,  0x10,  0x08,  0x10,  0x09,  0xFF,  0x08,  0x00,  0x08,  0x00,  0x9E, 	/* 36070 */
+	0x08,  0x00,  0x08,  0xFE,  0x08,  0x02,  0x7F,  0x02,  0x08,  0x02,  0x08,  0x02,  0x1C,  0xFE,  0x1A,  0x80, 	/* 36080 */
+	0x1A,  0x80,  0x28,  0x80,  0x28,  0x80,  0x48,  0x81,  0x08,  0x81,  0x08,  0x41,  0x08,  0x3F,  0x08,  0x00, 	/* 36090 */
+	0x9F,  0x00,  0x80,  0x00,  0x80,  0x7F,  0xFF,  0x00,  0x80,  0x00,  0x80,  0x1F,  0xFC,  0x10,  0x84,  0x10, 	/* 360A0 */
+	0x84,  0x10,  0x84,  0x1F,  0xFC,  0x01,  0xC0,  0x02,  0xA0,  0x04,  0x90,  0x18,  0x8C,  0x60,  0x83,  0x00, 	/* 360B0 */
+	0x80,  0xA0,  0x08,  0x00,  0x08,  0x00,  0x09,  0xFE,  0x7E,  0x10,  0x08,  0x10,  0x08,  0x10,  0x1C,  0x10, 	/* 360C0 */
+	0x1A,  0x10,  0x1A,  0x10,  0x28,  0x10,  0x28,  0x10,  0x48,  0x10,  0x08,  0x10,  0x0B,  0xFF,  0x08,  0x00, 	/* 360D0 */
+	0x08,  0x00,  0xA1,  0x00,  0x80,  0x00,  0x80,  0x01,  0xF8,  0x02,  0x10,  0x0D,  0x20,  0x30,  0xC0,  0x03, 	/* 360E0 */
+	0x20,  0x0C,  0x98,  0x70,  0x87,  0x1F,  0xFC,  0x01,  0xC0,  0x02,  0xA0,  0x04,  0x90,  0x18,  0x8C,  0x60, 	/* 360F0 */
+	0x83,  0x00,  0x80,  0xA2,  0x00,  0x80,  0x00,  0x80,  0x7F,  0xFF,  0x01,  0xC0,  0x02,  0xA0,  0x04,  0x90, 	/* 36100 */
+	0x18,  0x8C,  0x60,  0x83,  0x00,  0x80,  0x00,  0x00,  0x1F,  0xFC,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80, 	/* 36110 */
+	0x7F,  0xFF,  0x00,  0x00,  0xA3,  0x08,  0x10,  0x08,  0x10,  0x08,  0x10,  0x7F,  0x10,  0x08,  0x10,  0x08, 	/* 36120 */
+	0x92,  0x1C,  0x92,  0x1A,  0x92,  0x1A,  0x92,  0x28,  0x92,  0x28,  0x92,  0x48,  0x92,  0x08,  0x92,  0x08, 	/* 36130 */
+	0x92,  0x08,  0xFE,  0x08,  0x00,  0xA4,  0x08,  0x00,  0x0B,  0xFF,  0x08,  0x40,  0x7F,  0x40,  0x08,  0x40, 	/* 36140 */
+	0x08,  0x7C,  0x1C,  0x44,  0x1A,  0x44,  0x1A,  0x44,  0x28,  0x44,  0x28,  0x44,  0x48,  0x84,  0x08,  0x84, 	/* 36150 */
+	0x08,  0x84,  0x09,  0x04,  0x0A,  0x18,  0xA5,  0x00,  0x80,  0x00,  0x80,  0x3F,  0xFE,  0x00,  0x88,  0x08, 	/* 36160 */
+	0x88,  0x04,  0x90,  0x04,  0xA0,  0x7F,  0xFF,  0x00,  0x80,  0x01,  0xC0,  0x02,  0xA0,  0x04,  0x90,  0x18, 	/* 36170 */
+	0x8C,  0x60,  0x83,  0x00,  0x80,  0x00,  0x80,  0xAA,  0x08,  0x20,  0x08,  0x20,  0x08,  0x20,  0x7E,  0x28, 	/* 36180 */
+	0x08,  0xA4,  0x08,  0xA2,  0x18,  0xA2,  0x1D,  0x21,  0x1A,  0x25,  0x2A,  0x24,  0x28,  0x68,  0x48,  0x08, 	/* 36190 */
+	0x08,  0x10,  0x08,  0x20,  0x08,  0xC0,  0x0B,  0x00,  0xAD,  0x08,  0x20,  0x08,  0x20,  0x08,  0x20,  0x7F, 	/* 361A0 */
+	0xFF,  0x08,  0x00,  0x08,  0x00,  0x1C,  0x78,  0x1A,  0x48,  0x19,  0x48,  0x29,  0x48,  0x28,  0x48,  0x48, 	/* 361B0 */
+	0x48,  0x08,  0x89,  0x08,  0x89,  0x09,  0x07,  0x0A,  0x00,  0xAF,  0x08,  0x00,  0x09,  0xFF,  0x08,  0x10, 	/* 361C0 */
+	0x7F,  0x10,  0x08,  0x10,  0x08,  0x20,  0x1C,  0x28,  0x1A,  0x64,  0x1A,  0x64,  0x28,  0xA2,  0x29,  0x22, 	/* 361D0 */
+	0x48,  0x20,  0x08,  0x20,  0x08,  0x20,  0x08,  0x20,  0x08,  0x20,  0xB0,  0x00,  0x80,  0x00,  0x80,  0x00, 	/* 361E0 */
+	0x80,  0x7F,  0xFF,  0x01,  0xC0,  0x02,  0xA0,  0x04,  0x90,  0x18,  0x8C,  0x60,  0x83,  0x00,  0x80,  0x00, 	/* 361F0 */
+	0x80,  0x00,  0x00,  0x14,  0x44,  0x12,  0x22,  0x21,  0x11,  0x41,  0x11,  0xB1,  0x00,  0x80,  0x00,  0x80, 	/* 36200 */
+	0x7F,  0xFF,  0x00,  0x80,  0x1F,  0xFC,  0x10,  0x84,  0x10,  0x84,  0x1F,  0xFC,  0x10,  0x84,  0x1F,  0xFC, 	/* 36210 */
+	0x01,  0xC0,  0x02,  0xA0,  0x04,  0x90,  0x18,  0x8C,  0x60,  0x83,  0x00,  0x80,  0xB2,  0x00,  0x00,  0x0F, 	/* 36220 */
+	0xF8,  0x08,  0x08,  0x08,  0x08,  0x0F,  0xF8,  0x08,  0x08,  0x08,  0x08,  0x0F,  0xF8,  0x00,  0x80,  0x7F, 	/* 36230 */
+	0xFF,  0x02,  0xA0,  0x04,  0x90,  0x18,  0x8C,  0x60,  0x83,  0x00,  0x80,  0x00,  0x80,  0xB3,  0x00,  0x80, 	/* 36240 */
+	0x00,  0x80,  0x7F,  0xFF,  0x01,  0xC0,  0x02,  0xA0,  0x04,  0x90,  0x18,  0x8C,  0x60,  0x83,  0x0F,  0xF8, 	/* 36250 */
+	0x08,  0x08,  0x08,  0x08,  0x0F,  0xF8,  0x08,  0x08,  0x08,  0x08,  0x0F,  0xF8,  0x00,  0x00,  0xB5,  0x08, 	/* 36260 */
+	0x40,  0x08,  0x40,  0x08,  0x40,  0x7E,  0x7E,  0x08,  0x90,  0x08,  0x90,  0x1D,  0x10,  0x1A,  0x10,  0x1B, 	/* 36270 */
+	0xFF,  0x28,  0x10,  0x28,  0x10,  0x48,  0x10,  0x08,  0x10,  0x08,  0x10,  0x08,  0x10,  0x08,  0x10,  0xB7, 	/* 36280 */
+	0x08,  0x00,  0x09,  0xFC,  0x09,  0x24,  0x7F,  0x24,  0x09,  0x24,  0x09,  0x24,  0x1D,  0x24,  0x1B,  0xFC, 	/* 36290 */
+	0x1B,  0x00,  0x29,  0x00,  0x29,  0x00,  0x49,  0x02,  0x09,  0x02,  0x08,  0x82,  0x08,  0x7E,  0x08,  0x00, 	/* 362A0 */
+	0xBC,  0x08,  0x00,  0x09,  0xFE,  0x08,  0x04,  0x7E,  0xC8,  0x08,  0x30,  0x08,  0x10,  0x1B,  0xFF,  0x1C, 	/* 362B0 */
+	0x12,  0x1A,  0x14,  0x2A,  0x10,  0x28,  0x10,  0x48,  0x10,  0x08,  0x10,  0x08,  0x10,  0x08,  0x10,  0x08, 	/* 362C0 */
+	0x30,  0xBE,  0x08,  0x38,  0x08,  0x08,  0x08,  0x48,  0x7F,  0x48,  0x08,  0x44,  0x08,  0x54,  0x1C,  0x92, 	/* 362D0 */
+	0x1A,  0x92,  0x19,  0x11,  0x2A,  0x20,  0x28,  0x28,  0x48,  0x24,  0x08,  0x44,  0x08,  0x7A,  0x0B,  0xC2, 	/* 362E0 */
+	0x08,  0x02,  0xBF,  0x08,  0x00,  0x08,  0xFF,  0x08,  0x80,  0x7F,  0x80,  0x08,  0x80,  0x08,  0xFE,  0x0C, 	/* 362F0 */
+	0xA2,  0x1A,  0xA2,  0x1A,  0xA4,  0x18,  0x94,  0x28,  0x98,  0x28,  0x88,  0x48,  0x94,  0x09,  0x24,  0x09, 	/* 36300 */
+	0x42,  0x0A,  0x81,  0x85,  0x08,  0x00,  0x09,  0xFF,  0x08,  0x44,  0x7F,  0x44,  0x08,  0x44,  0x08,  0x44, 	/* 36310 */
+	0x19,  0xFF,  0x1C,  0x44,  0x1A,  0x44,  0x2A,  0x44,  0x28,  0x44,  0x48,  0x44,  0x08,  0x84,  0x08,  0x84, 	/* 36320 */
+	0x09,  0x04,  0x0A,  0x04,  0x87,  0x09,  0x10,  0x09,  0x10,  0x09,  0x10,  0x7F,  0x10,  0x09,  0x12,  0x09, 	/* 36330 */
+	0x12,  0x1D,  0xF4,  0x1B,  0x18,  0x1B,  0x10,  0x29,  0x10,  0x29,  0x10,  0x49,  0x10,  0x09,  0x11,  0x09, 	/* 36340 */
+	0x51,  0x09,  0x8F,  0x0E,  0x00,  0x89,  0x08,  0x00,  0x09,  0xFE,  0x08,  0x20,  0x7F,  0x20,  0x08,  0x20, 	/* 36350 */
+	0x08,  0x20,  0x1C,  0x20,  0x1A,  0xFC,  0x1A,  0x20,  0x28,  0x20,  0x28,  0x20,  0x48,  0x20,  0x08,  0x20, 	/* 36360 */
+	0x08,  0x20,  0x0B,  0xFF,  0x08,  0x00,  0x8B,  0x08,  0x20,  0x08,  0x20,  0x08,  0x20,  0x7F,  0xFF,  0x08, 	/* 36370 */
+	0x40,  0x08,  0x40,  0x1C,  0x40,  0x1A,  0x7C,  0x19,  0x44,  0x28,  0x44,  0x28,  0x44,  0x48,  0x44,  0x08, 	/* 36380 */
+	0x84,  0x08,  0x84,  0x09,  0x04,  0x0A,  0x18,  0x8C,  0x08,  0x78,  0x08,  0x08,  0x08,  0x48,  0x7E,  0x84, 	/* 36390 */
+	0x08,  0x84,  0x09,  0x02,  0x1A,  0x01,  0x1C,  0xFC,  0x1A,  0x24,  0x2A,  0x24,  0x28,  0x24,  0x48,  0x24, 	/* 363A0 */
+	0x08,  0x44,  0x08,  0x44,  0x08,  0x84,  0x09,  0x18,  0x90,  0x08,  0x04,  0x08,  0x18,  0x08,  0xE0,  0x7F, 	/* 363B0 */
+	0x80,  0x08,  0x80,  0x08,  0xFF,  0x1C,  0x88,  0x1A,  0x88,  0x1A,  0x88,  0x28,  0x88,  0x28,  0x88,  0x48, 	/* 363C0 */
+	0x88,  0x09,  0x08,  0x09,  0x08,  0x0A,  0x08,  0x08,  0x08,  0x95,  0x08,  0x20,  0x08,  0x20,  0x08,  0x20, 	/* 363D0 */
+	0x7F,  0xFE,  0x09,  0x22,  0x09,  0x22,  0x1C,  0x20,  0x1A,  0x30,  0x1A,  0x30,  0x28,  0x50,  0x28,  0x50, 	/* 363E0 */
+	0x48,  0x50,  0x08,  0x90,  0x08,  0x91,  0x09,  0x11,  0x0A,  0x0F,  0x97,  0x08,  0x10,  0x08,  0x10,  0x08, 	/* 363F0 */
+	0x10,  0x7F,  0xFF,  0x08,  0x10,  0x08,  0x10,  0x1C,  0x38,  0x1A,  0x38,  0x19,  0x54,  0x28,  0x54,  0x28, 	/* 36400 */
+	0x92,  0x49,  0x11,  0x08,  0x10,  0x08,  0x10,  0x08,  0x10,  0x08,  0x10,  0x9A,  0x08,  0x40,  0x08,  0x40, 	/* 36410 */
+	0x08,  0x40,  0x08,  0x40,  0x7F,  0xFF,  0x08,  0x84,  0x08,  0xC4,  0x1D,  0x44,  0x1A,  0x28,  0x19,  0x28, 	/* 36420 */
+	0x29,  0x10,  0x28,  0x10,  0x48,  0x28,  0x08,  0x44,  0x08,  0x82,  0x0B,  0x01,  0x9C,  0x00,  0x00,  0x1F, 	/* 36430 */
+	0xF8,  0x11,  0x08,  0x11,  0x08,  0x1F,  0xF8,  0x11,  0x08,  0x11,  0x08,  0x1F,  0xF8,  0x01,  0x00,  0x7F, 	/* 36440 */
+	0xFE,  0x03,  0x80,  0x05,  0x40,  0x09,  0x20,  0x11,  0x18,  0x61,  0x06,  0x01,  0x00,  0x9D,  0x08,  0x10, 	/* 36450 */
+	0x08,  0x10,  0x08,  0x10,  0x7F,  0xFF,  0x08,  0x10,  0x08,  0x10,  0x1D,  0xFC,  0x1C,  0x44,  0x1A,  0x44, 	/* 36460 */
+	0x2A,  0x28,  0x2A,  0x28,  0x48,  0x10,  0x08,  0x28,  0x08,  0x44,  0x08,  0x82,  0x0B,  0x01,  0xA0,  0x08, 	/* 36470 */
+	0x20,  0x08,  0x20,  0x09,  0xF8,  0x7E,  0x28,  0x08,  0x28,  0x0C,  0x49,  0x1A,  0x49,  0x1A,  0x87,  0x19, 	/* 36480 */
+	0x20,  0x28,  0x20,  0x2B,  0xFE,  0x48,  0x20,  0x08,  0x20,  0x08,  0x20,  0x08,  0x20,  0x08,  0x20,  0xA1, 	/* 36490 */
+	0x08,  0x24,  0x08,  0x44,  0x09,  0xC4,  0x7E,  0x44,  0x08,  0x44,  0x08,  0x44,  0x19,  0xFF,  0x1C,  0x44, 	/* 364A0 */
+	0x1A,  0x44,  0x2A,  0x44,  0x28,  0x44,  0x48,  0x44,  0x08,  0x84,  0x08,  0x84,  0x09,  0x04,  0x0A,  0x04, 	/* 364B0 */
+	0xA2,  0x08,  0x00,  0x09,  0xFE,  0x09,  0x00,  0x7F,  0x04,  0x09,  0x04,  0x09,  0x44,  0x1D,  0x28,  0x1B, 	/* 364C0 */
+	0x18,  0x1B,  0x08,  0x29,  0x14,  0x29,  0x24,  0x49,  0x44,  0x09,  0x80,  0x09,  0x00,  0x09,  0xFF,  0x08, 	/* 364D0 */
+	0x00,  0xA6,  0x08,  0x00,  0x09,  0xFF,  0x08,  0x00,  0x7F,  0x00,  0x08,  0xFE,  0x08,  0x82,  0x1C,  0x82, 	/* 364E0 */
+	0x1A,  0x82,  0x1A,  0xFE,  0x28,  0x80,  0x28,  0x80,  0x48,  0x80,  0x08,  0x80,  0x09,  0x00,  0x09,  0x00, 	/* 364F0 */
+	0x0A,  0x00,  0xA9,  0x00,  0x80,  0x00,  0x80,  0x7F,  0xFF,  0x01,  0xC0,  0x06,  0xB0,  0x18,  0x8C,  0x60, 	/* 36500 */
+	0x83,  0x02,  0xE0,  0x02,  0x20,  0x04,  0x90,  0x18,  0x8C,  0x61,  0x03,  0x01,  0x40,  0x02,  0x30,  0x04, 	/* 36510 */
+	0xE8,  0x3F,  0x04,  0xAF,  0x08,  0x20,  0x08,  0x20,  0x08,  0x20,  0x7F,  0x20,  0x09,  0xFE,  0x08,  0x20, 	/* 36520 */
+	0x1C,  0x20,  0x1A,  0x20,  0x1A,  0xFC,  0x28,  0x84,  0x28,  0x84,  0x48,  0x84,  0x08,  0x84,  0x08,  0x84, 	/* 36530 */
+	0x08,  0xFC,  0x08,  0x00,  0xB3,  0x08,  0x00,  0x08,  0x7E,  0x08,  0x42,  0x7F,  0x42,  0x08,  0x42,  0x08, 	/* 36540 */
+	0x42,  0x1C,  0x42,  0x1A,  0x42,  0x19,  0x7E,  0x28,  0x00,  0x28,  0x00,  0x48,  0x44,  0x08,  0x42,  0x08, 	/* 36550 */
+	0x82,  0x09,  0x01,  0x0A,  0x01,  0xB4,  0x08,  0x00,  0x08,  0xFC,  0x08,  0x84,  0x7F,  0x84,  0x08,  0x84, 	/* 36560 */
+	0x08,  0xFC,  0x1C,  0x00,  0x1A,  0x00,  0x19,  0xFE,  0x28,  0x22,  0x28,  0x22,  0x48,  0x22,  0x08,  0x42, 	/* 36570 */
+	0x08,  0x42,  0x08,  0x82,  0x09,  0x0C,  0xB6,  0x08,  0x00,  0x08,  0x7C,  0x7F,  0x44,  0x09,  0x44,  0x09, 	/* 36580 */
+	0x44,  0x11,  0x44,  0x11,  0x7C,  0x26,  0x00,  0x41,  0x00,  0x01,  0x00,  0x7F,  0xFE,  0x03,  0x40,  0x05, 	/* 36590 */
+	0x20,  0x19,  0x18,  0x61,  0x06,  0x01,  0x00,  0xB7,  0x11,  0x00,  0x11,  0x00,  0x11,  0x1E,  0x7D,  0x12, 	/* 365A0 */
+	0x17,  0xD2,  0x11,  0x52,  0x39,  0x52,  0x39,  0x52,  0x35,  0x52,  0x51,  0x52,  0x51,  0x52,  0x12,  0x52, 	/* 365B0 */
+	0x12,  0x52,  0x14,  0x5E,  0x18,  0x40,  0x11,  0x80,  0xB8,  0x08,  0x80,  0x08,  0x80,  0x08,  0x80,  0x7E, 	/* 365C0 */
+	0xFE,  0x09,  0x02,  0x09,  0x02,  0x1A,  0xF2,  0x1C,  0x92,  0x1A,  0x92,  0x2A,  0x92,  0x28,  0x92,  0x48, 	/* 365D0 */
+	0xF2,  0x08,  0x02,  0x08,  0x02,  0x08,  0x04,  0x08,  0x18,  0xB9,  0x08,  0x40,  0x08,  0x40,  0x08,  0x7E, 	/* 365E0 */
+	0x7E,  0x42,  0x08,  0x82,  0x08,  0xF2,  0x19,  0x92,  0x1C,  0x92,  0x1A,  0x92,  0x2A,  0xF2,  0x28,  0x84, 	/* 365F0 */
+	0x48,  0x98,  0x08,  0x80,  0x08,  0x81,  0x08,  0x81,  0x08,  0x7F,  0x81,  0x08,  0x10,  0x08,  0x10,  0x08, 	/* 36600 */
+	0x10,  0x7F,  0xFF,  0x09,  0x01,  0x09,  0x41,  0x1C,  0x40,  0x1A,  0x44,  0x1A,  0x58,  0x28,  0x60,  0x28, 	/* 36610 */
+	0x40,  0x48,  0x40,  0x08,  0x40,  0x08,  0x42,  0x08,  0x22,  0x08,  0x1E,  0x84,  0x08,  0x00,  0x0B,  0xFF, 	/* 36620 */
+	0x08,  0x20,  0x7E,  0x20,  0x08,  0x20,  0x09,  0xFE,  0x1D,  0x22,  0x1B,  0x22,  0x19,  0x32,  0x29,  0x52, 	/* 36630 */
+	0x29,  0x4A,  0x49,  0x86,  0x09,  0x02,  0x09,  0x02,  0x09,  0x02,  0x09,  0x06,  0x86,  0x08,  0x20,  0x08, 	/* 36640 */
+	0x20,  0x08,  0x20,  0x7F,  0xFE,  0x08,  0x00,  0x08,  0x84,  0x1C,  0x84,  0x1A,  0x44,  0x1A,  0x44,  0x28, 	/* 36650 */
+	0x48,  0x28,  0x48,  0x48,  0x48,  0x08,  0x10,  0x08,  0x10,  0x0B,  0xFF,  0x08,  0x00,  0x8A,  0x08,  0x40, 	/* 36660 */
+	0x08,  0x40,  0x08,  0x7C,  0x7E,  0x44,  0x08,  0xC8,  0x09,  0x28,  0x1C,  0x10,  0x1A,  0x28,  0x18,  0xC4, 	/* 36670 */
+	0x2B,  0x03,  0x28,  0x60,  0x48,  0x10,  0x08,  0x00,  0x08,  0xE0,  0x08,  0x18,  0x08,  0x04,  0x8E,  0x08, 	/* 36680 */
+	0x44,  0x08,  0x44,  0x08,  0x44,  0x7E,  0x84,  0x08,  0xFF,  0x09,  0x84,  0x1D,  0x84,  0x1A,  0xA4,  0x18, 	/* 36690 */
+	0x94,  0x28,  0x94,  0x28,  0x84,  0x48,  0x84,  0x08,  0x84,  0x08,  0x84,  0x08,  0x84,  0x08,  0x8C,  0x8F, 	/* 366A0 */
+	0x08,  0x10,  0x08,  0x10,  0x08,  0x20,  0x7F,  0xFE,  0x08,  0x82,  0x08,  0x82,  0x1C,  0x82,  0x1A,  0x82, 	/* 366B0 */
+	0x1A,  0xFE,  0x28,  0x82,  0x28,  0x82,  0x48,  0x82,  0x08,  0x82,  0x08,  0x82,  0x08,  0xFE,  0x08,  0x00, 	/* 366C0 */
+	0x90,  0x04,  0x10,  0x04,  0x10,  0x3F,  0xFF,  0x04,  0x10,  0x04,  0x10,  0x07,  0xF0,  0x04,  0x10,  0x04, 	/* 366D0 */
+	0x10,  0x07,  0xF0,  0x00,  0x80,  0x7F,  0xFF,  0x01,  0xA0,  0x02,  0x90,  0x0C,  0x8C,  0x70,  0x83,  0x00, 	/* 366E0 */
+	0x80,  0x91,  0x08,  0x44,  0x08,  0x44,  0x08,  0x44,  0x7F,  0x44,  0x09,  0xFF,  0x08,  0x44,  0x1C,  0x44, 	/* 366F0 */
+	0x1A,  0x44,  0x19,  0x44,  0x29,  0x7C,  0x28,  0x44,  0x48,  0x44,  0x08,  0x44,  0x08,  0x44,  0x08,  0x7C, 	/* 36700 */
+	0x08,  0x00,  0x93,  0x00,  0x40,  0x18,  0x40,  0x05,  0xF8,  0x60,  0x48,  0x10,  0x48,  0x00,  0x48,  0x04, 	/* 36710 */
+	0x8A,  0x19,  0x0A,  0x62,  0x06,  0x00,  0x80,  0x7F,  0xFF,  0x02,  0xA0,  0x04,  0x90,  0x18,  0x8C,  0x60, 	/* 36720 */
+	0x83,  0x00,  0x80,  0x94,  0x00,  0x00,  0x1F,  0xF8,  0x06,  0x20,  0x01,  0x40,  0x3F,  0xFE,  0x01,  0x44, 	/* 36730 */
+	0x02,  0x48,  0x0C,  0x40,  0x30,  0xC0,  0x00,  0x80,  0x7F,  0xFF,  0x02,  0xA0,  0x04,  0x90,  0x18,  0x8C, 	/* 36740 */
+	0x60,  0x83,  0x00,  0x80,  0x98,  0x08,  0x00,  0x09,  0xFE,  0x08,  0x20,  0x7F,  0x20,  0x08,  0x20,  0x08, 	/* 36750 */
+	0x40,  0x1C,  0x40,  0x1A,  0xFC,  0x18,  0x84,  0x29,  0x84,  0x2A,  0x84,  0x48,  0x84,  0x08,  0x84,  0x08, 	/* 36760 */
+	0x84,  0x08,  0xFC,  0x08,  0x00,  0x9A,  0x08,  0x10,  0x08,  0x10,  0x08,  0x10,  0x7F,  0x10,  0x08,  0xFE, 	/* 36770 */
+	0x08,  0x92,  0x1C,  0x92,  0x1A,  0x92,  0x1A,  0x92,  0x29,  0xFE,  0x29,  0x92,  0x48,  0x92,  0x08,  0x92, 	/* 36780 */
+	0x08,  0x92,  0x08,  0xFE,  0x08,  0x00,  0x9D,  0x08,  0x02,  0x08,  0x0C,  0x08,  0xF0,  0x7F,  0x80,  0x08, 	/* 36790 */
+	0x80,  0x08,  0xFF,  0x1C,  0x88,  0x1A,  0x88,  0x1A,  0x88,  0x28,  0xB8,  0x28,  0x8C,  0x48,  0x8A,  0x09, 	/* 367A0 */
+	0x09,  0x09,  0x08,  0x0A,  0x08,  0x08,  0x08,  0x9E,  0x08,  0x40,  0x08,  0x40,  0x08,  0x40,  0x7F,  0x7F, 	/* 367B0 */
+	0x08,  0x90,  0x08,  0x90,  0x1D,  0x10,  0x1A,  0x1E,  0x1A,  0x10,  0x28,  0x10,  0x28,  0x10,  0x48,  0x1E, 	/* 367C0 */
+	0x08,  0x10,  0x08,  0x10,  0x08,  0x10,  0x08,  0x10,  0xA2,  0x08,  0x04,  0x08,  0x18,  0x08,  0xF0,  0x7F, 	/* 367D0 */
+	0x90,  0x08,  0x90,  0x08,  0x90,  0x1C,  0xFF,  0x1A,  0x88,  0x1A,  0x88,  0x28,  0x88,  0x28,  0x88,  0x48, 	/* 367E0 */
+	0xE4,  0x0B,  0x85,  0x08,  0x05,  0x0B,  0xF3,  0x08,  0x01,  0xA4,  0x08,  0x00,  0x08,  0xFC,  0x08,  0x84, 	/* 367F0 */
+	0x7F,  0x84,  0x08,  0x84,  0x08,  0xFC,  0x1C,  0x84,  0x1A,  0x84,  0x1A,  0x84,  0x28,  0xFC,  0x28,  0x84, 	/* 36800 */
+	0x48,  0x84,  0x08,  0x84,  0x08,  0x84,  0x0B,  0xFF,  0x08,  0x00,  0xA7,  0x08,  0x04,  0x08,  0x18,  0x08, 	/* 36810 */
+	0xE4,  0x7E,  0x84,  0x08,  0xA4,  0x08,  0xA4,  0x1C,  0xA4,  0x1A,  0xA4,  0x1A,  0xA4,  0x28,  0xA4,  0x28, 	/* 36820 */
+	0xA4,  0x48,  0xB4,  0x08,  0xAC,  0x09,  0x3A,  0x09,  0xEA,  0x0A,  0x05,  0xA9,  0x08,  0x00,  0x09,  0xFF, 	/* 36830 */
+	0x09,  0x10,  0x7F,  0x10,  0x09,  0x1C,  0x09,  0x24,  0x1D,  0x24,  0x1B,  0x48,  0x19,  0x88,  0x29,  0x14, 	/* 36840 */
+	0x29,  0x14,  0x49,  0x22,  0x09,  0x42,  0x09,  0x80,  0x09,  0xFF,  0x08,  0x00,  0xAC,  0x00,  0x80,  0x00, 	/* 36850 */
+	0x80,  0x7F,  0xFF,  0x00,  0x80,  0x00,  0x80,  0x1F,  0xFC,  0x14,  0x94,  0x12,  0xA4,  0x12,  0x84,  0x1F, 	/* 36860 */
+	0xFC,  0x01,  0xC0,  0x02,  0xA0,  0x04,  0x90,  0x18,  0x8C,  0x60,  0x83,  0x00,  0x80,  0xAE,  0x08,  0x10, 	/* 36870 */
+	0x08,  0x10,  0x08,  0x92,  0x7F,  0x92,  0x08,  0x92,  0x08,  0x92,  0x1C,  0xFE,  0x1A,  0x10,  0x1A,  0x10, 	/* 36880 */
+	0x28,  0x92,  0x28,  0x92,  0x48,  0x92,  0x08,  0x92,  0x08,  0x92,  0x08,  0xFE,  0x08,  0x00,  0xAF,  0x08, 	/* 36890 */
+	0x00,  0x09,  0xFF,  0x08,  0x04,  0x7F,  0x04,  0x08,  0xF4,  0x08,  0x94,  0x1C,  0x94,  0x1A,  0x94,  0x1A, 	/* 368A0 */
+	0x94,  0x28,  0xF4,  0x28,  0x04,  0x48,  0x04,  0x08,  0x04,  0x08,  0x04,  0x08,  0x04,  0x08,  0x0C,  0xB1, 	/* 368B0 */
+	0x08,  0x40,  0x08,  0x20,  0x08,  0x20,  0x7E,  0x00,  0x09,  0xFE,  0x08,  0x20,  0x1C,  0x20,  0x1A,  0x20, 	/* 368C0 */
+	0x1A,  0x20,  0x29,  0xFC,  0x28,  0x20,  0x48,  0x20,  0x08,  0x20,  0x08,  0x20,  0x0B,  0xFF,  0x08,  0x00, 	/* 368D0 */
+	0xB3,  0x08,  0x20,  0x08,  0x40,  0x09,  0x9E,  0x7D,  0x52,  0x09,  0x52,  0x0D,  0x52,  0x1B,  0x52,  0x1B, 	/* 368E0 */
+	0x52,  0x29,  0x52,  0x29,  0x52,  0x49,  0x52,  0x0B,  0xD2,  0x0C,  0x5C,  0x08,  0x90,  0x08,  0x90,  0x09, 	/* 368F0 */
+	0x10,  0xB4,  0x04,  0x40,  0x14,  0x44,  0x17,  0xC8,  0x14,  0x70,  0x14,  0x42,  0x17,  0xC2,  0x1C,  0x3E, 	/* 36900 */
+	0x60,  0x80,  0x00,  0x80,  0x7F,  0xFF,  0x01,  0xC0,  0x02,  0xA0,  0x04,  0x90,  0x18,  0x8C,  0x60,  0x83, 	/* 36910 */
+	0x00,  0x80,  0xB5,  0x08,  0x00,  0x09,  0xFE,  0x09,  0x52,  0x7F,  0x52,  0x09,  0x52,  0x09,  0x52,  0x1D, 	/* 36920 */
+	0x52,  0x1B,  0xFF,  0x19,  0x52,  0x29,  0x52,  0x29,  0x52,  0x49,  0x52,  0x09,  0x52,  0x09,  0x52,  0x09, 	/* 36930 */
+	0x52,  0x09,  0x06,  0xBB,  0x00,  0x80,  0x00,  0x80,  0x7F,  0xFF,  0x01,  0xC0,  0x02,  0xA0,  0x04,  0x90, 	/* 36940 */
+	0x18,  0x8C,  0x6F,  0xFB,  0x08,  0x08,  0x0F,  0xF8,  0x08,  0x08,  0x0F,  0xF8,  0x08,  0x08,  0x08,  0x08, 	/* 36950 */
+	0x7F,  0xFF,  0x00,  0x00,  0xBE,  0x08,  0x00,  0x09,  0xFE,  0x08,  0x10,  0x7F,  0x10,  0x08,  0x10,  0x08, 	/* 36960 */
+	0x90,  0x1C,  0x90,  0x1A,  0x9E,  0x1A,  0x90,  0x28,  0x90,  0x28,  0x90,  0x48,  0x90,  0x08,  0x90,  0x08, 	/* 36970 */
+	0x90,  0x0B,  0xFF,  0x08,  0x00,  0xBF,  0x08,  0x20,  0x08,  0x20,  0x08,  0x20,  0x7F,  0xFF,  0x08,  0x20, 	/* 36980 */
+	0x08,  0x20,  0x19,  0xFE,  0x1D,  0x22,  0x1B,  0x22,  0x29,  0x22,  0x29,  0x22,  0x49,  0x22,  0x09,  0x2C, 	/* 36990 */
+	0x09,  0x20,  0x08,  0x20,  0x08,  0x20,  0x82,  0x08,  0x00,  0x08,  0xFC,  0x08,  0x84,  0x7E,  0xA4,  0x08, 	/* 369A0 */
+	0x94,  0x08,  0x94,  0x1C,  0x84,  0x1B,  0xFF,  0x19,  0x04,  0x29,  0x24,  0x29,  0x14,  0x49,  0x14,  0x09, 	/* 369B0 */
+	0xFE,  0x08,  0x04,  0x08,  0x08,  0x08,  0x30,  0x83,  0x08,  0x04,  0x08,  0x18,  0x08,  0xE0,  0x7E,  0x80, 	/* 369C0 */
+	0x08,  0xFF,  0x08,  0x90,  0x1C,  0x90,  0x1A,  0x9E,  0x1A,  0x92,  0x28,  0x92,  0x28,  0x92,  0x49,  0x22, 	/* 369D0 */
+	0x09,  0x22,  0x0A,  0x42,  0x0C,  0x82,  0x08,  0x0C,  0x84,  0x22,  0x08,  0x11,  0x08,  0x08,  0x90,  0x08, 	/* 369E0 */
+	0xA0,  0x7F,  0xFE,  0x40,  0x02,  0x41,  0x02,  0x01,  0x00,  0x7F,  0xFE,  0x03,  0x80,  0x05,  0x40,  0x09, 	/* 369F0 */
+	0x20,  0x11,  0x18,  0x61,  0x06,  0x01,  0x00,  0x01,  0x00,  0x93,  0x08,  0x20,  0x08,  0x30,  0x08,  0x50, 	/* 36A00 */
+	0x7F,  0x48,  0x08,  0x84,  0x09,  0x02,  0x1A,  0xFD,  0x1C,  0x20,  0x1A,  0x20,  0x2A,  0x20,  0x29,  0xFC, 	/* 36A10 */
+	0x48,  0x20,  0x08,  0x20,  0x08,  0x20,  0x0B,  0xFF,  0x08,  0x00,  0x96,  0x08,  0x00,  0x0B,  0xFE,  0x08, 	/* 36A20 */
+	0x50,  0x7E,  0x50,  0x09,  0xFE,  0x09,  0x52,  0x1D,  0x52,  0x1B,  0x52,  0x19,  0x52,  0x29,  0x8E,  0x29, 	/* 36A30 */
+	0x02,  0x49,  0x02,  0x09,  0x02,  0x09,  0x02,  0x09,  0xFE,  0x08,  0x00,  0x97,  0x00,  0x00,  0x7F,  0xFF, 	/* 36A40 */
+	0x02,  0x20,  0x02,  0x20,  0x1F,  0xFC,  0x12,  0x24,  0x12,  0x24,  0x1F,  0xFC,  0x00,  0x80,  0x7F,  0xFF, 	/* 36A50 */
+	0x02,  0xA0,  0x04,  0x90,  0x18,  0x8C,  0x60,  0x83,  0x00,  0x80,  0x00,  0x80,  0x9E,  0x00,  0x00,  0x3E, 	/* 36A60 */
+	0x3E,  0x08,  0x08,  0x08,  0x08,  0x7F,  0x7F,  0x08,  0x08,  0x08,  0x08,  0x08,  0x88,  0x00,  0x80,  0x7F, 	/* 36A70 */
+	0xFF,  0x01,  0xC0,  0x02,  0xA0,  0x04,  0x90,  0x18,  0x8C,  0x60,  0x83,  0x00,  0x80,  0xA1,  0x08,  0x10, 	/* 36A80 */
+	0x08,  0x10,  0x08,  0x10,  0x7F,  0xFF,  0x08,  0x44,  0x08,  0x44,  0x1C,  0x42,  0x1A,  0xA5,  0x19,  0x25, 	/* 36A90 */
+	0x29,  0x28,  0x28,  0x10,  0x48,  0x10,  0x08,  0x28,  0x08,  0x44,  0x08,  0x82,  0x0B,  0x01,  0xA2,  0x08, 	/* 36AA0 */
+	0x00,  0x0B,  0xFF,  0x08,  0x20,  0x7E,  0x20,  0x08,  0x40,  0x08,  0xFC,  0x1C,  0x84,  0x1A,  0x84,  0x1A, 	/* 36AB0 */
+	0x84,  0x28,  0xFC,  0x28,  0x84,  0x48,  0x84,  0x08,  0x84,  0x08,  0x84,  0x08,  0xFC,  0x08,  0x00,  0xA9, 	/* 36AC0 */
+	0x08,  0x00,  0x09,  0xEE,  0x08,  0x22,  0x7E,  0x66,  0x08,  0x66,  0x08,  0xAA,  0x1C,  0xAA,  0x1B,  0x32, 	/* 36AD0 */
+	0x2A,  0x66,  0x28,  0x66,  0x48,  0xAA,  0x08,  0xAA,  0x09,  0x32,  0x0A,  0x22,  0x08,  0x22,  0x08,  0x66, 	/* 36AE0 */
+	0xAA,  0x08,  0x10,  0x08,  0x90,  0x08,  0x90,  0x7E,  0x90,  0x09,  0xFE,  0x09,  0x10,  0x1D,  0x10,  0x1A, 	/* 36AF0 */
+	0x10,  0x1B,  0xFF,  0x28,  0x30,  0x28,  0x58,  0x48,  0x58,  0x08,  0x94,  0x09,  0x12,  0x0A,  0x11,  0x08, 	/* 36B00 */
+	0x10,  0xAB,  0x08,  0x20,  0x08,  0x20,  0x09,  0xFF,  0x7E,  0x20,  0x08,  0x20,  0x08,  0x7E,  0x1C,  0x42, 	/* 36B10 */
+	0x1A,  0x84,  0x18,  0x88,  0x29,  0xFF,  0x2A,  0x88,  0x48,  0x88,  0x08,  0x88,  0x08,  0x88,  0x08,  0x88, 	/* 36B20 */
+	0x08,  0x98,  0xB2,  0x08,  0x20,  0x08,  0x22,  0x09,  0xFE,  0x7E,  0x24,  0x08,  0x28,  0x0B,  0xFF,  0x1C, 	/* 36B30 */
+	0x20,  0x1A,  0x40,  0x18,  0xFC,  0x29,  0x40,  0x2A,  0x40,  0x48,  0x7C,  0x08,  0x04,  0x08,  0x04,  0x08, 	/* 36B40 */
+	0x04,  0x08,  0x18,  0xB4,  0x08,  0x40,  0x08,  0x40,  0x08,  0x7F,  0x7E,  0x80,  0x09,  0x00,  0x0A,  0xFE, 	/* 36B50 */
+	0x18,  0x92,  0x1C,  0x92,  0x1A,  0x92,  0x2A,  0x92,  0x29,  0xFF,  0x48,  0x82,  0x08,  0x82,  0x08,  0x82, 	/* 36B60 */
+	0x08,  0x82,  0x08,  0x86,  0xB8,  0x08,  0x20,  0x08,  0x20,  0x08,  0x20,  0x7F,  0xFF,  0x08,  0x20,  0x08, 	/* 36B70 */
+	0x28,  0x19,  0xC8,  0x1C,  0x52,  0x1A,  0x24,  0x28,  0x24,  0x28,  0x48,  0x49,  0x90,  0x08,  0x28,  0x08, 	/* 36B80 */
+	0x44,  0x08,  0x82,  0x0B,  0x02,  0xB9,  0x08,  0x00,  0x08,  0xFC,  0x08,  0x84,  0x7F,  0x84,  0x08,  0x84, 	/* 36B90 */
+	0x08,  0xFC,  0x1C,  0x84,  0x1A,  0x84,  0x1A,  0xFE,  0x2A,  0xA2,  0x28,  0x94,  0x48,  0x98,  0x08,  0x88, 	/* 36BA0 */
+	0x08,  0xA4,  0x08,  0xC2,  0x0B,  0x01,  0xBC,  0x08,  0x40,  0x08,  0x40,  0x08,  0x7C,  0x7F,  0x84,  0x08, 	/* 36BB0 */
+	0xC8,  0x08,  0xA8,  0x1D,  0x30,  0x1A,  0x28,  0x1A,  0x44,  0x28,  0x82,  0x29,  0xFD,  0x4A,  0x84,  0x08, 	/* 36BC0 */
+	0x84,  0x08,  0x84,  0x08,  0xFC,  0x08,  0x00,  0xBD,  0x04,  0x20,  0x04,  0x28,  0x3F,  0xA4,  0x04,  0x24, 	/* 36BD0 */
+	0x04,  0x20,  0x7F,  0xFF,  0x00,  0x20,  0x04,  0x24,  0x04,  0x24,  0x7F,  0xD4,  0x0C,  0x18,  0x0E,  0x18, 	/* 36BE0 */
+	0x15,  0x2A,  0x24,  0xAA,  0x44,  0x46,  0x04,  0x82,  0x80,  0x04,  0x08,  0x04,  0x08,  0x0F,  0x7E,  0x09, 	/* 36BF0 */
+	0x48,  0x11,  0x48,  0x6A,  0x48,  0x04,  0xFF,  0x18,  0x08,  0x60,  0x88,  0x00,  0x80,  0x7F,  0xFF,  0x02, 	/* 36C00 */
+	0xA0,  0x04,  0x90,  0x18,  0x8C,  0x60,  0x83,  0x00,  0x80,  0x81,  0x08,  0x40,  0x08,  0x5E,  0x08,  0x40, 	/* 36C10 */
+	0x7E,  0x80,  0x08,  0x80,  0x09,  0x20,  0x1C,  0x3F,  0x1A,  0x44,  0x18,  0x44,  0x28,  0x84,  0x29,  0x84, 	/* 36C20 */
+	0x4A,  0x84,  0x08,  0x84,  0x08,  0x84,  0x08,  0x84,  0x08,  0x8C,  0x82,  0x08,  0x20,  0x08,  0x20,  0x09, 	/* 36C30 */
+	0xFC,  0x7E,  0x20,  0x08,  0x20,  0x08,  0x20,  0x1D,  0xFF,  0x1A,  0x00,  0x1A,  0x20,  0x28,  0x20,  0x29, 	/* 36C40 */
+	0xFC,  0x48,  0x20,  0x08,  0x20,  0x08,  0x20,  0x0B,  0xFF,  0x08,  0x00,  0x83,  0x08,  0x48,  0x08,  0x48, 	/* 36C50 */
+	0x08,  0x4A,  0x7E,  0x4A,  0x09,  0x4C,  0x08,  0xC8,  0x1C,  0x48,  0x1A,  0x48,  0x1A,  0xCC,  0x29,  0x4A, 	/* 36C60 */
+	0x2A,  0x49,  0x48,  0x49,  0x08,  0x88,  0x08,  0x89,  0x09,  0x09,  0x0A,  0x07,  0x86,  0x08,  0x00,  0x09, 	/* 36C70 */
+	0xFF,  0x09,  0x00,  0x7F,  0xFE,  0x09,  0x10,  0x09,  0x10,  0x1D,  0x10,  0x1B,  0x7C,  0x19,  0x10,  0x29, 	/* 36C80 */
+	0x10,  0x29,  0x10,  0x49,  0xFE,  0x09,  0x00,  0x09,  0x00,  0x09,  0xFF,  0x08,  0x00,  0x88,  0x00,  0x80, 	/* 36C90 */
+	0x00,  0x80,  0x7F,  0xFE,  0x41,  0x02,  0x5F,  0xFA,  0x02,  0x20,  0x0E,  0x20,  0x01,  0xC0,  0x06,  0x38, 	/* 36CA0 */
+	0x18,  0x84,  0x7F,  0xFF,  0x01,  0xC0,  0x02,  0xA0,  0x0C,  0x98,  0x70,  0x86,  0x00,  0x80,  0x8D,  0x08, 	/* 36CB0 */
+	0x20,  0x08,  0x20,  0x09,  0xFF,  0x7E,  0x30,  0x08,  0x48,  0x08,  0xFC,  0x19,  0x02,  0x1C,  0x01,  0x1B, 	/* 36CC0 */
+	0xFE,  0x2A,  0x40,  0x28,  0x40,  0x48,  0xFC,  0x08,  0x84,  0x08,  0x04,  0x08,  0x04,  0x08,  0x18,  0x8E, 	/* 36CD0 */
+	0x08,  0x00,  0x0B,  0xFF,  0x08,  0x20,  0x7E,  0x20,  0x08,  0x48,  0x08,  0x84,  0x1D,  0xFA,  0x1A,  0x00, 	/* 36CE0 */
+	0x1A,  0x20,  0x28,  0x20,  0x29,  0xFC,  0x48,  0x20,  0x08,  0x20,  0x08,  0x20,  0x0B,  0xFF,  0x08,  0x00, 	/* 36CF0 */
+	0x90,  0x08,  0x00,  0x09,  0xFE,  0x09,  0x02,  0x7F,  0x02,  0x09,  0xFE,  0x09,  0x02,  0x1D,  0x02,  0x1B, 	/* 36D00 */
+	0x7A,  0x19,  0x4A,  0x29,  0x4A,  0x29,  0x4A,  0x49,  0x7A,  0x09,  0x02,  0x09,  0x02,  0x09,  0x02,  0x09, 	/* 36D10 */
+	0x06,  0x91,  0x00,  0x00,  0x0F,  0xF0,  0x02,  0x20,  0x01,  0xC0,  0x06,  0x30,  0x7F,  0x7E,  0x12,  0x24, 	/* 36D20 */
+	0x0C,  0x98,  0x72,  0xE7,  0x00,  0x80,  0x7F,  0xFF,  0x02,  0xA0,  0x04,  0x90,  0x18,  0x8C,  0x60,  0x83, 	/* 36D30 */
+	0x00,  0x80,  0x93,  0x08,  0x00,  0x09,  0xFE,  0x08,  0x00,  0x7E,  0x00,  0x08,  0xFC,  0x08,  0x84,  0x1C, 	/* 36D40 */
+	0x84,  0x1A,  0xFC,  0x1A,  0x84,  0x28,  0x84,  0x28,  0x84,  0x48,  0xFC,  0x08,  0x00,  0x08,  0x00,  0x0B, 	/* 36D50 */
+	0xFF,  0x08,  0x00,  0x94,  0x08,  0x20,  0x08,  0x20,  0x08,  0x20,  0x7F,  0xFF,  0x08,  0x20,  0x08,  0x20, 	/* 36D60 */
+	0x1C,  0x20,  0x1B,  0xFE,  0x1A,  0x00,  0x28,  0x00,  0x28,  0xFC,  0x48,  0x84,  0x08,  0x84,  0x08,  0x84, 	/* 36D70 */
+	0x08,  0xFC,  0x08,  0x00,  0x99,  0x08,  0x20,  0x08,  0x28,  0x08,  0x44,  0x7E,  0x8E,  0x09,  0xF1,  0x08, 	/* 36D80 */
+	0x00,  0x1C,  0x50,  0x1A,  0x50,  0x18,  0xFE,  0x29,  0x10,  0x28,  0x10,  0x4B,  0xFF,  0x08,  0x10,  0x08, 	/* 36D90 */
+	0x10,  0x08,  0x10,  0x08,  0x10,  0x9C,  0x08,  0x22,  0x09,  0x12,  0x08,  0x92,  0x7E,  0x94,  0x08,  0x84, 	/* 36DA0 */
+	0x08,  0x08,  0x1C,  0x20,  0x1A,  0x20,  0x19,  0xFF,  0x28,  0x24,  0x28,  0x44,  0x48,  0x48,  0x08,  0xF8, 	/* 36DB0 */
+	0x08,  0x28,  0x08,  0xC4,  0x0B,  0x02,  0x9D,  0x11,  0x04,  0x11,  0x04,  0x11,  0x04,  0x7D,  0xC4,  0x11, 	/* 36DC0 */
+	0x5E,  0x11,  0x54,  0x32,  0x54,  0x3A,  0x54,  0x35,  0x54,  0x50,  0x94,  0x50,  0xBF,  0x10,  0x84,  0x11, 	/* 36DD0 */
+	0x04,  0x11,  0x04,  0x12,  0x04,  0x14,  0x04,  0x9F,  0x08,  0x14,  0x08,  0x12,  0x08,  0x12,  0x7F,  0x1E, 	/* 36DE0 */
+	0x08,  0xF0,  0x08,  0x1E,  0x1C,  0xF0,  0x1A,  0x1F,  0x19,  0xF4,  0x29,  0x14,  0x28,  0x08,  0x48,  0x18, 	/* 36DF0 */
+	0x08,  0x29,  0x08,  0xC5,  0x0B,  0x03,  0x08,  0x01,  0xA3,  0x08,  0x10,  0x09,  0x12,  0x08,  0x92,  0x7E, 	/* 36E00 */
+	0x94,  0x08,  0x98,  0x08,  0x10,  0x1D,  0xFE,  0x1A,  0x02,  0x1A,  0x02,  0x28,  0x02,  0x28,  0xFE,  0x48, 	/* 36E10 */
+	0x02,  0x08,  0x02,  0x08,  0x02,  0x09,  0xFE,  0x08,  0x00,  0xA7,  0x08,  0x20,  0x08,  0x20,  0x08,  0x50, 	/* 36E20 */
+	0x7E,  0x48,  0x08,  0x84,  0x09,  0x02,  0x1A,  0xFD,  0x1C,  0x00,  0x1A,  0x00,  0x2B,  0xFF,  0x28,  0x20, 	/* 36E30 */
+	0x48,  0x28,  0x08,  0x44,  0x08,  0x9C,  0x0B,  0xE2,  0x08,  0x02,  0xB4,  0x08,  0x04,  0x08,  0x18,  0x09, 	/* 36E40 */
+	0xE4,  0x7E,  0xA2,  0x08,  0x92,  0x09,  0x11,  0x1C,  0xFD,  0x1A,  0x04,  0x1A,  0x08,  0x28,  0x10,  0x29, 	/* 36E50 */
+	0xFF,  0x48,  0x10,  0x08,  0x10,  0x08,  0x10,  0x08,  0x10,  0x08,  0x30,  0xB6,  0x08,  0x00,  0x09,  0xFC, 	/* 36E60 */
+	0x08,  0x08,  0x7E,  0x50,  0x08,  0x20,  0x09,  0xFE,  0x1D,  0x22,  0x1B,  0x22,  0x29,  0xFE,  0x29,  0x22, 	/* 36E70 */
+	0x49,  0x22,  0x09,  0xFE,  0x09,  0x22,  0x09,  0x22,  0x09,  0x22,  0x09,  0x06,  0xB7,  0x08,  0x40,  0x08, 	/* 36E80 */
+	0x78,  0x08,  0x48,  0x7E,  0x90,  0x09,  0xFE,  0x08,  0x92,  0x1C,  0x92,  0x1A,  0xFE,  0x1A,  0x92,  0x28, 	/* 36E90 */
+	0x92,  0x28,  0xFE,  0x48,  0x82,  0x08,  0x82,  0x09,  0x02,  0x09,  0x02,  0x0A,  0x06,  0xBE,  0x08,  0x00, 	/* 36EA0 */
+	0x08,  0xFC,  0x08,  0x24,  0x7E,  0x24,  0x09,  0xFF,  0x08,  0x24,  0x1C,  0x24,  0x1A,  0xFC,  0x1A,  0x40, 	/* 36EB0 */
+	0x28,  0x40,  0x28,  0xFE,  0x48,  0xC2,  0x09,  0x42,  0x0A,  0x42,  0x08,  0x7E,  0x08,  0x00,  0xBF,  0x08, 	/* 36EC0 */
+	0x00,  0x08,  0xFC,  0x08,  0x84,  0x7E,  0xFC,  0x08,  0x84,  0x08,  0x84,  0x1C,  0xFC,  0x1A,  0x00,  0x1A, 	/* 36ED0 */
+	0xFE,  0x28,  0x10,  0x28,  0x10,  0x4B,  0xFF,  0x08,  0x10,  0x08,  0x10,  0x08,  0x10,  0x08,  0x10,  0x81, 	/* 36EE0 */
+	0x00,  0x00,  0x37,  0xF8,  0x08,  0x48,  0x02,  0x4A,  0x62,  0x49,  0x14,  0x89,  0x01,  0x08,  0x0A,  0x30, 	/* 36EF0 */
+	0x30,  0x80,  0x40,  0x80,  0x7F,  0xFF,  0x02,  0xA0,  0x04,  0x90,  0x18,  0x8C,  0x60,  0x83,  0x00,  0x80, 	/* 36F00 */
+	0x83,  0x08,  0x02,  0x08,  0x0C,  0x0B,  0xF8,  0x7E,  0x48,  0x08,  0x88,  0x09,  0x08,  0x19,  0xFF,  0x1C, 	/* 36F10 */
+	0x48,  0x2A,  0x48,  0x2A,  0x48,  0x49,  0x48,  0x08,  0xC8,  0x08,  0xBE,  0x09,  0x40,  0x09,  0x30,  0x0A, 	/* 36F20 */
+	0x0F,  0x85,  0x08,  0x40,  0x08,  0x40,  0x08,  0x7F,  0x7E,  0x80,  0x08,  0x80,  0x09,  0xFC,  0x1C,  0xA4, 	/* 36F30 */
+	0x1A,  0xA4,  0x18,  0xA4,  0x2B,  0xFF,  0x29,  0x24,  0x49,  0x24,  0x0B,  0xFF,  0x0A,  0x04,  0x08,  0x08, 	/* 36F40 */
+	0x08,  0x30,  0x8D,  0x08,  0x10,  0x08,  0x20,  0x08,  0xFC,  0x7E,  0x84,  0x08,  0x84,  0x08,  0xFC,  0x1C, 	/* 36F50 */
+	0x84,  0x1A,  0x84,  0x1A,  0xFC,  0x28,  0x20,  0x28,  0x27,  0x48,  0x38,  0x0B,  0xE0,  0x08,  0x21,  0x08, 	/* 36F60 */
+	0x21,  0x08,  0x1F,  0x8F,  0x08,  0x10,  0x08,  0x90,  0x08,  0x90,  0x7E,  0xFE,  0x08,  0x90,  0x09,  0x10, 	/* 36F70 */
+	0x1C,  0x10,  0x1B,  0xFF,  0x1A,  0x10,  0x28,  0x00,  0x28,  0xFE,  0x48,  0x82,  0x08,  0x82,  0x08,  0x82, 	/* 36F80 */
+	0x08,  0xFE,  0x08,  0x00,  0x93,  0x08,  0x20,  0x08,  0x20,  0x09,  0xFE,  0x7E,  0x08,  0x08,  0x88,  0x08, 	/* 36F90 */
+	0x48,  0x1C,  0x50,  0x1B,  0xFF,  0x1A,  0x20,  0x28,  0x20,  0x28,  0x20,  0x49,  0xFE,  0x08,  0x20,  0x08, 	/* 36FA0 */
+	0x20,  0x08,  0x20,  0x08,  0x20,  0x94,  0x08,  0x04,  0x08,  0x18,  0x08,  0xE0,  0x7E,  0x80,  0x08,  0xFF, 	/* 36FB0 */
+	0x08,  0x80,  0x1C,  0xFE,  0x1A,  0xD2,  0x1A,  0xD2,  0x28,  0xD2,  0x28,  0xFE,  0x49,  0x40,  0x09,  0x40, 	/* 36FC0 */
+	0x0A,  0x41,  0x0C,  0x21,  0x08,  0x1F,  0x97,  0x08,  0x00,  0x0B,  0xFF,  0x08,  0x20,  0x7D,  0xFC,  0x09, 	/* 36FD0 */
+	0x24,  0x09,  0x24,  0x1D,  0xFC,  0x1B,  0x24,  0x1B,  0x24,  0x29,  0xFC,  0x28,  0xA0,  0x48,  0x60,  0x08, 	/* 36FE0 */
+	0x20,  0x08,  0x50,  0x08,  0x8C,  0x0B,  0x03,  0x9B,  0x08,  0x00,  0x0B,  0xEF,  0x08,  0xA9,  0x7E,  0xAA, 	/* 36FF0 */
+	0x08,  0xAA,  0x0B,  0xEC,  0x1C,  0xAA,  0x1A,  0xA9,  0x28,  0xA9,  0x2B,  0xE9,  0x48,  0xA9,  0x08,  0xA9, 	/* 37000 */
+	0x09,  0x2E,  0x09,  0x28,  0x0A,  0x28,  0x08,  0xC8,  0x9D,  0x04,  0x40,  0x04,  0x40,  0x04,  0x7F,  0x08, 	/* 37010 */
+	0x84,  0x09,  0x24,  0x12,  0x28,  0x12,  0x10,  0x32,  0x6C,  0x53,  0x93,  0x12,  0x10,  0x13,  0xFF,  0x12, 	/* 37020 */
+	0x38,  0x12,  0x54,  0x10,  0x92,  0x11,  0x11,  0x10,  0x10,  0x9F,  0x01,  0x00,  0x1F,  0xF8,  0x10,  0x08, 	/* 37030 */
+	0x1F,  0xF8,  0x10,  0x08,  0x1F,  0xFF,  0x10,  0x00,  0x1F,  0xFE,  0x00,  0x02,  0x00,  0x82,  0x00,  0x8C, 	/* 37040 */
+	0x7F,  0xFF,  0x02,  0xA0,  0x0C,  0x98,  0x70,  0x87,  0x00,  0x80,  0xA0,  0x08,  0x00,  0x08,  0xFC,  0x08, 	/* 37050 */
+	0x84,  0x7F,  0x84,  0x08,  0x84,  0x08,  0x84,  0x1C,  0xFC,  0x1A,  0x20,  0x19,  0x20,  0x28,  0x40,  0x29, 	/* 37060 */
+	0xFE,  0x49,  0x02,  0x09,  0x02,  0x09,  0x02,  0x09,  0xFE,  0x08,  0x00,  0xA2,  0x08,  0x10,  0x08,  0x92, 	/* 37070 */
+	0x08,  0x52,  0x7F,  0x54,  0x08,  0x10,  0x08,  0x7E,  0x1C,  0x42,  0x1A,  0x42,  0x19,  0x7E,  0x29,  0x42, 	/* 37080 */
+	0x28,  0x42,  0x48,  0x7E,  0x08,  0x42,  0x08,  0x42,  0x08,  0x42,  0x08,  0x46,  0xA6,  0x04,  0x08,  0x04, 	/* 37090 */
+	0x08,  0x7F,  0xFF,  0x0E,  0x0C,  0x0D,  0x1C,  0x14,  0xAA,  0x24,  0x49,  0x44,  0x88,  0x01,  0xF8,  0x02, 	/* 370A0 */
+	0x08,  0x0D,  0x10,  0x30,  0xA0,  0x00,  0x40,  0x01,  0x80,  0x06,  0x00,  0x38,  0x00,  0xA7,  0x08,  0x00, 	/* 370B0 */
+	0x09,  0xFE,  0x08,  0x20,  0x7F,  0x20,  0x08,  0xF8,  0x08,  0x48,  0x1C,  0x48,  0x1A,  0x48,  0x1B,  0xFF, 	/* 370C0 */
+	0x28,  0x00,  0x28,  0xFC,  0x48,  0x84,  0x08,  0x84,  0x08,  0x84,  0x08,  0xFC,  0x08,  0x00,  0xA8,  0x03, 	/* 370D0 */
+	0x02,  0x3C,  0x22,  0x04,  0x22,  0x7F,  0xA2,  0x04,  0x22,  0x0E,  0x22,  0x15,  0x22,  0x64,  0x02,  0x04, 	/* 370E0 */
+	0x86,  0x04,  0x80,  0x7F,  0xFF,  0x01,  0xC0,  0x02,  0xA0,  0x0C,  0x98,  0x70,  0x87,  0x00,  0x80,  0xAD, 	/* 370F0 */
+	0x08,  0x20,  0x08,  0x28,  0x08,  0x44,  0x7F,  0xFA,  0x08,  0x48,  0x08,  0x49,  0x1C,  0x87,  0x1B,  0x40, 	/* 37100 */
+	0x1A,  0x78,  0x28,  0x88,  0x29,  0x88,  0x4A,  0x50,  0x08,  0x20,  0x08,  0x50,  0x09,  0x8C,  0x0E,  0x03, 	/* 37110 */
+	0xAF,  0x08,  0x84,  0x08,  0x48,  0x09,  0xFE,  0x7E,  0x22,  0x08,  0x22,  0x09,  0xFE,  0x1D,  0x20,  0x1B, 	/* 37120 */
+	0x20,  0x19,  0xFE,  0x28,  0x22,  0x28,  0x62,  0x48,  0xA2,  0x09,  0x22,  0x0E,  0x2C,  0x08,  0x20,  0x08, 	/* 37130 */
+	0x20,  0xB0,  0x08,  0x10,  0x08,  0x14,  0x08,  0x12,  0x7F,  0xFF,  0x08,  0x10,  0x09,  0x52,  0x19,  0x52, 	/* 37140 */
+	0x1D,  0x52,  0x1B,  0xF4,  0x29,  0x54,  0x29,  0x4C,  0x49,  0x48,  0x0A,  0x5A,  0x0A,  0x26,  0x0C,  0x46, 	/* 37150 */
+	0x08,  0x82,  0xB1,  0x08,  0x00,  0x09,  0xFE,  0x09,  0x02,  0x7F,  0x22,  0x09,  0x22,  0x09,  0xFE,  0x1D, 	/* 37160 */
+	0x22,  0x1B,  0x72,  0x19,  0x72,  0x29,  0xAA,  0x29,  0xAA,  0x49,  0x26,  0x09,  0x22,  0x09,  0x02,  0x09, 	/* 37170 */
+	0xFE,  0x08,  0x00,  0xB3,  0x08,  0x10,  0x08,  0x10,  0x09,  0xFF,  0x7E,  0x20,  0x08,  0x2C,  0x08,  0x4A, 	/* 37180 */
+	0x1D,  0xF1,  0x1A,  0x00,  0x1A,  0xA4,  0x28,  0xA4,  0x28,  0xA4,  0x48,  0xA4,  0x08,  0xA4,  0x09,  0x25, 	/* 37190 */
+	0x09,  0x05,  0x0A,  0x03,  0xB5,  0x08,  0x10,  0x08,  0x10,  0x7F,  0xFF,  0x0C,  0x38,  0x1A,  0x34,  0x19, 	/* 371A0 */
+	0x52,  0x28,  0x91,  0x49,  0x10,  0x00,  0x00,  0x07,  0xF0,  0x04,  0x10,  0x05,  0x10,  0x04,  0x92,  0x08, 	/* 371B0 */
+	0x92,  0x10,  0x12,  0x60,  0x0E,  0xB6,  0x08,  0x00,  0x09,  0xFE,  0x09,  0x02,  0x7F,  0x02,  0x09,  0xFE, 	/* 371C0 */
+	0x09,  0x04,  0x1D,  0x18,  0x1B,  0xE0,  0x19,  0x20,  0x29,  0xFE,  0x29,  0x20,  0x49,  0xFF,  0x0A,  0x20, 	/* 371D0 */
+	0x0A,  0x21,  0x0C,  0x21,  0x08,  0x1F,  0xB9,  0x08,  0x04,  0x08,  0x18,  0x08,  0xE0,  0x7E,  0x80,  0x08, 	/* 371E0 */
+	0xFE,  0x08,  0x88,  0x1C,  0x88,  0x1A,  0x88,  0x18,  0x88,  0x28,  0x88,  0x2B,  0xFF,  0x48,  0x00,  0x08, 	/* 371F0 */
+	0x88,  0x08,  0x84,  0x09,  0x02,  0x0A,  0x02,  0xBA,  0x04,  0x10,  0x04,  0x10,  0x7F,  0xFF,  0x0E,  0x38, 	/* 37200 */
+	0x0D,  0x34,  0x14,  0x52,  0x24,  0x91,  0x04,  0x10,  0x00,  0x00,  0x7F,  0xFF,  0x00,  0x80,  0x00,  0xE0, 	/* 37210 */
+	0x00,  0x98,  0x00,  0x84,  0x00,  0x80,  0x00,  0x80,  0xBC,  0x08,  0x20,  0x08,  0x20,  0x09,  0xFE,  0x7E, 	/* 37220 */
+	0x20,  0x08,  0xFC,  0x08,  0x20,  0x1D,  0xFF,  0x1A,  0x40,  0x18,  0x44,  0x29,  0xFF,  0x28,  0x44,  0x48, 	/* 37230 */
+	0xA4,  0x08,  0x94,  0x09,  0x14,  0x0A,  0x04,  0x08,  0x0C,  0x84,  0x00,  0x80,  0x7F,  0xFF,  0x01,  0x30, 	/* 37240 */
+	0x02,  0x0C,  0x1F,  0xFA,  0x08,  0x88,  0x7F,  0xFF,  0x08,  0x88,  0x0F,  0xF8,  0x00,  0x80,  0x7F,  0xFF, 	/* 37250 */
+	0x02,  0xA0,  0x04,  0x90,  0x18,  0x8C,  0x60,  0x83,  0x00,  0x80,  0x86,  0x08,  0x10,  0x08,  0x10,  0x08, 	/* 37260 */
+	0x28,  0x7F,  0x44,  0x08,  0x82,  0x09,  0x7D,  0x1C,  0x00,  0x1A,  0x00,  0x19,  0xFE,  0x28,  0xAA,  0x28, 	/* 37270 */
+	0xAA,  0x48,  0xFE,  0x08,  0xAA,  0x08,  0xAA,  0x08,  0xAA,  0x08,  0x86,  0x89,  0x08,  0x10,  0x08,  0x20, 	/* 37280 */
+	0x08,  0xFC,  0x7E,  0x84,  0x08,  0xFC,  0x08,  0x84,  0x1C,  0x84,  0x1A,  0xFC,  0x1A,  0x20,  0x29,  0xFE, 	/* 37290 */
+	0x29,  0x22,  0x49,  0x22,  0x09,  0x22,  0x09,  0x2C,  0x08,  0x20,  0x08,  0x20,  0x8A,  0x04,  0x10,  0x3F, 	/* 372A0 */
+	0xFE,  0x04,  0x10,  0x07,  0xF0,  0x04,  0x10,  0x07,  0xF0,  0x04,  0x10,  0x7F,  0xFF,  0x04,  0x90,  0x08, 	/* 372B0 */
+	0x88,  0x17,  0xF4,  0x61,  0xC3,  0x02,  0xA0,  0x0C,  0x98,  0x30,  0x86,  0x00,  0x80,  0x8B,  0x08,  0x44, 	/* 372C0 */
+	0x08,  0x44,  0x09,  0xFF,  0x7F,  0x44,  0x08,  0x44,  0x08,  0x7C,  0x1C,  0x44,  0x1A,  0x44,  0x19,  0x7C, 	/* 372D0 */
+	0x28,  0x44,  0x28,  0x44,  0x4B,  0xFF,  0x08,  0x08,  0x08,  0x44,  0x08,  0x82,  0x0B,  0x02,  0x8D,  0x08, 	/* 372E0 */
+	0x00,  0x08,  0xFC,  0x08,  0x84,  0x7F,  0x84,  0x08,  0xFC,  0x08,  0x84,  0x1C,  0x84,  0x1A,  0xFC,  0x1A, 	/* 372F0 */
+	0x00,  0x29,  0x10,  0x29,  0x12,  0x49,  0xDC,  0x09,  0x10,  0x09,  0x11,  0x09,  0xD1,  0x0B,  0x0F,  0x92, 	/* 37300 */
+	0x08,  0x20,  0x08,  0x20,  0x0B,  0xFE,  0x7E,  0x20,  0x09,  0xFC,  0x08,  0x50,  0x1F,  0xFF,  0x1A,  0x88, 	/* 37310 */
+	0x19,  0x24,  0x2A,  0x23,  0x29,  0xFC,  0x48,  0x20,  0x0B,  0xFE,  0x08,  0x20,  0x08,  0x20,  0x08,  0x20, 	/* 37320 */
+	0x94,  0x08,  0x06,  0x08,  0xF8,  0x08,  0x90,  0x7F,  0x90,  0x08,  0xFF,  0x08,  0x88,  0x1C,  0x88,  0x1A, 	/* 37330 */
+	0xE5,  0x1B,  0x83,  0x28,  0xFD,  0x28,  0x84,  0x48,  0xFC,  0x08,  0x84,  0x08,  0x84,  0x08,  0xFC,  0x08, 	/* 37340 */
+	0x00,  0x95,  0x08,  0x10,  0x08,  0x10,  0x09,  0xFF,  0x7F,  0x01,  0x09,  0x01,  0x08,  0xFE,  0x1C,  0x00, 	/* 37350 */
+	0x1A,  0x00,  0x19,  0xFF,  0x28,  0x10,  0x28,  0x54,  0x48,  0x52,  0x08,  0x92,  0x09,  0x11,  0x08,  0x10, 	/* 37360 */
+	0x08,  0x30,  0x97,  0x00,  0x80,  0x3F,  0xFE,  0x00,  0x80,  0x1F,  0xFC,  0x11,  0xC4,  0x16,  0xB4,  0x38, 	/* 37370 */
+	0x8E,  0x00,  0x80,  0x7F,  0xFF,  0x00,  0x80,  0x1F,  0xFC,  0x11,  0xC4,  0x12,  0xAC,  0x0C,  0x98,  0x70, 	/* 37380 */
+	0x87,  0x00,  0x80,  0x98,  0x08,  0x10,  0x08,  0x10,  0x7F,  0x7F,  0x08,  0x10,  0x08,  0x10,  0x3F,  0x7E, 	/* 37390 */
+	0x29,  0x52,  0x29,  0x52,  0x2B,  0x56,  0x28,  0x50,  0x1C,  0x38,  0x1A,  0x34,  0x29,  0x52,  0x48,  0x91, 	/* 373A0 */
+	0x08,  0x10,  0x08,  0x10,  0x9A,  0x10,  0x00,  0x13,  0xDE,  0x12,  0x52,  0x7E,  0x52,  0x12,  0x52,  0x13, 	/* 373B0 */
+	0xDE,  0x3A,  0x52,  0x36,  0x52,  0x32,  0x52,  0x53,  0xDE,  0x52,  0x52,  0x12,  0x52,  0x12,  0x52,  0x12, 	/* 373C0 */
+	0x52,  0x14,  0x62,  0x18,  0xC6,  0x9F,  0x08,  0x20,  0x08,  0x20,  0x0B,  0xFF,  0x7E,  0x20,  0x09,  0xFC, 	/* 373D0 */
+	0x09,  0x24,  0x1D,  0xFC,  0x1B,  0x24,  0x1B,  0x24,  0x29,  0xFC,  0x28,  0x70,  0x48,  0x68,  0x08,  0xA4, 	/* 373E0 */
+	0x09,  0x22,  0x0A,  0x21,  0x08,  0x20,  0xA0,  0x08,  0x88,  0x04,  0x88,  0x04,  0x90,  0x3F,  0xFE,  0x20, 	/* 373F0 */
+	0x02,  0x27,  0xF2,  0x04,  0x10,  0x04,  0x10,  0x07,  0xF0,  0x00,  0x80,  0x7F,  0xFF,  0x02,  0xA0,  0x04, 	/* 37400 */
+	0x90,  0x18,  0x8C,  0x60,  0x83,  0x00,  0x80,  0xA1,  0x08,  0x00,  0x09,  0xFE,  0x09,  0x02,  0x7F,  0x8A, 	/* 37410 */
+	0x09,  0x4A,  0x09,  0x52,  0x1D,  0xFE,  0x1B,  0x22,  0x2B,  0x22,  0x29,  0xAA,  0x49,  0xAA,  0x09,  0xAA, 	/* 37420 */
+	0x09,  0xFA,  0x09,  0x02,  0x09,  0x02,  0x09,  0x06,  0xA3,  0x08,  0x20,  0x08,  0x20,  0x09,  0xFC,  0x7E, 	/* 37430 */
+	0x24,  0x09,  0xFF,  0x08,  0x24,  0x1C,  0x24,  0x1B,  0xFC,  0x18,  0x22,  0x2A,  0x32,  0x29,  0x34,  0x49, 	/* 37440 */
+	0x68,  0x09,  0xA4,  0x0E,  0x22,  0x08,  0x21,  0x08,  0x60,  0xA7,  0x08,  0x28,  0x08,  0x24,  0x08,  0x3E, 	/* 37450 */
+	0x7F,  0xD0,  0x08,  0x16,  0x08,  0x18,  0x1C,  0x65,  0x1B,  0xA3,  0x1A,  0x29,  0x28,  0x24,  0x28,  0x1E, 	/* 37460 */
+	0x4B,  0xF0,  0x08,  0x14,  0x08,  0x19,  0x08,  0x67,  0x0B,  0x81,  0xAE,  0x00,  0x80,  0x00,  0x80,  0x1F, 	/* 37470 */
+	0xFC,  0x01,  0xC0,  0x02,  0xA0,  0x04,  0x90,  0x18,  0x8C,  0x04,  0x90,  0x04,  0x10,  0x7F,  0xFF,  0x0C, 	/* 37480 */
+	0x10,  0x0E,  0x38,  0x15,  0x34,  0x24,  0x52,  0x44,  0x91,  0x04,  0x10,  0xAF,  0x08,  0x20,  0x08,  0x20, 	/* 37490 */
+	0x08,  0x50,  0x7E,  0x88,  0x09,  0x04,  0x0A,  0xFA,  0x1C,  0x01,  0x1A,  0xFC,  0x1A,  0x08,  0x28,  0x10, 	/* 374A0 */
+	0x28,  0x20,  0x49,  0x50,  0x09,  0x52,  0x0A,  0x45,  0x0C,  0x45,  0x08,  0x3C,  0xB2,  0x08,  0x20,  0x08, 	/* 374B0 */
+	0x20,  0x09,  0xFF,  0x7E,  0x20,  0x09,  0xFC,  0x08,  0x24,  0x19,  0xFF,  0x1C,  0x24,  0x1B,  0xFC,  0x28, 	/* 374C0 */
+	0x20,  0x2B,  0xFF,  0x48,  0x48,  0x08,  0x88,  0x09,  0xF0,  0x08,  0x28,  0x09,  0xC4,  0xB9,  0x08,  0x20, 	/* 374D0 */
+	0x08,  0x20,  0x08,  0x3E,  0x7F,  0x20,  0x08,  0x20,  0x08,  0xFC,  0x1C,  0x84,  0x1A,  0xFC,  0x1A,  0x84, 	/* 374E0 */
+	0x28,  0x84,  0x28,  0xFC,  0x48,  0x20,  0x0B,  0xFF,  0x08,  0x20,  0x08,  0x20,  0x08,  0x20,  0xBA,  0x08, 	/* 374F0 */
+	0x20,  0x08,  0x20,  0x0B,  0xFE,  0x7E,  0x02,  0x0A,  0x02,  0x08,  0xFA,  0x1C,  0x88,  0x1A,  0x88,  0x1A, 	/* 37500 */
+	0xF8,  0x28,  0x80,  0x28,  0x80,  0x48,  0xFC,  0x08,  0x84,  0x08,  0x84,  0x08,  0xFC,  0x08,  0x00,  0x80, 	/* 37510 */
+	0x08,  0x10,  0x08,  0x10,  0x09,  0xFF,  0x7F,  0x01,  0x09,  0x41,  0x08,  0x4E,  0x1C,  0xFA,  0x1A,  0x9A, 	/* 37520 */
+	0x1A,  0x9A,  0x29,  0x2A,  0x2A,  0xAA,  0x48,  0x4C,  0x08,  0x48,  0x08,  0x89,  0x09,  0x09,  0x0A,  0x07, 	/* 37530 */
+	0x81,  0x08,  0x10,  0x08,  0x10,  0x09,  0xFF,  0x7E,  0x00,  0x08,  0x7C,  0x08,  0x44,  0x1C,  0x7C,  0x1A, 	/* 37540 */
+	0x00,  0x19,  0xFC,  0x28,  0x08,  0x28,  0x10,  0x49,  0xFF,  0x08,  0x10,  0x08,  0x10,  0x08,  0x10,  0x08, 	/* 37550 */
+	0x30,  0x84,  0x08,  0x10,  0x08,  0x10,  0x08,  0xFE,  0x7F,  0x44,  0x08,  0x24,  0x08,  0x28,  0x1D,  0xFF, 	/* 37560 */
+	0x1A,  0x20,  0x18,  0x20,  0x29,  0xFF,  0x28,  0x24,  0x48,  0x44,  0x08,  0xE8,  0x08,  0x18,  0x08,  0x64, 	/* 37570 */
+	0x09,  0x82,  0x85,  0x08,  0x20,  0x08,  0x20,  0x09,  0xFE,  0x7E,  0x20,  0x08,  0x50,  0x08,  0x48,  0x1C, 	/* 37580 */
+	0x84,  0x1B,  0xFF,  0x1A,  0x04,  0x29,  0xE4,  0x29,  0x24,  0x49,  0x24,  0x09,  0xE4,  0x08,  0x04,  0x08, 	/* 37590 */
+	0x04,  0x08,  0x0C,  0x88,  0x08,  0x40,  0x08,  0x40,  0x08,  0x7E,  0x7E,  0x82,  0x08,  0xA2,  0x09,  0x2A, 	/* 375A0 */
+	0x18,  0xB2,  0x1D,  0xFA,  0x1A,  0x22,  0x28,  0x72,  0x28,  0x6A,  0x48,  0xA6,  0x09,  0x22,  0x08,  0x22, 	/* 375B0 */
+	0x08,  0x04,  0x08,  0x18,  0x8B,  0x08,  0x10,  0x08,  0x10,  0x09,  0xFF,  0x7F,  0x00,  0x08,  0x00,  0x08, 	/* 375C0 */
+	0x7C,  0x1C,  0x44,  0x1A,  0x44,  0x19,  0x44,  0x28,  0x7C,  0x28,  0x10,  0x48,  0x94,  0x08,  0x92,  0x09, 	/* 375D0 */
+	0x11,  0x0A,  0x11,  0x08,  0x30,  0x8C,  0x08,  0x10,  0x08,  0x10,  0x09,  0xFF,  0x7F,  0x29,  0x09,  0x29, 	/* 375E0 */
+	0x08,  0x4A,  0x1C,  0x46,  0x1A,  0x80,  0x19,  0x00,  0x28,  0xFE,  0x28,  0x10,  0x48,  0x10,  0x08,  0x10, 	/* 375F0 */
+	0x08,  0x10,  0x09,  0xFF,  0x08,  0x00,  0x8D,  0x08,  0x10,  0x08,  0x10,  0x08,  0xFF,  0x7F,  0x10,  0x08, 	/* 37600 */
+	0x7C,  0x09,  0x44,  0x1D,  0x44,  0x1B,  0x7C,  0x1B,  0x44,  0x29,  0x7C,  0x29,  0x44,  0x49,  0x44,  0x09, 	/* 37610 */
+	0x7C,  0x09,  0x00,  0x09,  0xFF,  0x08,  0x00,  0x8E,  0x08,  0x44,  0x08,  0x44,  0x08,  0x88,  0x7E,  0xFE, 	/* 37620 */
+	0x09,  0x88,  0x09,  0x88,  0x1C,  0x88,  0x1A,  0xFE,  0x1A,  0x88,  0x28,  0x88,  0x28,  0xFE,  0x48,  0x88, 	/* 37630 */
+	0x08,  0x88,  0x08,  0x88,  0x08,  0xFF,  0x08,  0x00,  0x8F,  0x08,  0x00,  0x09,  0xFF,  0x08,  0x28,  0x7E, 	/* 37640 */
+	0x28,  0x08,  0x28,  0x08,  0xEE,  0x1C,  0x82,  0x1A,  0x82,  0x1A,  0x82,  0x28,  0xEE,  0x28,  0x28,  0x48, 	/* 37650 */
+	0x28,  0x08,  0x28,  0x08,  0x28,  0x09,  0xFF,  0x08,  0x00,  0x92,  0x10,  0x80,  0x10,  0x9E,  0x10,  0x82, 	/* 37660 */
+	0x7E,  0xF2,  0x10,  0x92,  0x10,  0x92,  0x38,  0x8A,  0x37,  0xEA,  0x30,  0x8C,  0x52,  0xC4,  0x52,  0xA4, 	/* 37670 */
+	0x12,  0xAC,  0x12,  0x8A,  0x14,  0x92,  0x10,  0xA1,  0x11,  0xC1,  0x99,  0x08,  0x00,  0x08,  0xFC,  0x08, 	/* 37680 */
+	0x84,  0x7E,  0x84,  0x08,  0xFC,  0x08,  0x84,  0x1C,  0x84,  0x1A,  0xFC,  0x1A,  0x00,  0x29,  0xFE,  0x29, 	/* 37690 */
+	0x02,  0x49,  0x02,  0x09,  0xFE,  0x09,  0x02,  0x09,  0xFE,  0x08,  0x00,  0x9A,  0x10,  0x00,  0x13,  0xDE, 	/* 376A0 */
+	0x12,  0x52,  0x7F,  0xDE,  0x12,  0x52,  0x13,  0xDE,  0x3A,  0x02,  0x36,  0x02,  0x32,  0x02,  0x52,  0x02, 	/* 376B0 */
+	0x52,  0x02,  0x12,  0x02,  0x12,  0x02,  0x12,  0x02,  0x12,  0x02,  0x12,  0x06,  0x9B,  0x08,  0x88,  0x08, 	/* 376C0 */
+	0x88,  0x0B,  0xFF,  0x7E,  0x88,  0x08,  0x88,  0x08,  0x50,  0x1C,  0x50,  0x1A,  0x92,  0x18,  0x94,  0x29, 	/* 376D0 */
+	0x98,  0x2A,  0x90,  0x48,  0x90,  0x08,  0x90,  0x08,  0x91,  0x08,  0x91,  0x08,  0x8F,  0x9C,  0x08,  0x20, 	/* 376E0 */
+	0x08,  0x20,  0x08,  0x50,  0x7E,  0x88,  0x09,  0x04,  0x0B,  0xFE,  0x18,  0x21,  0x1D,  0xFC,  0x1B,  0x24, 	/* 376F0 */
+	0x29,  0x24,  0x29,  0xFC,  0x48,  0x30,  0x08,  0x30,  0x08,  0x48,  0x09,  0x84,  0x0E,  0x02,  0xA1,  0x10, 	/* 37700 */
+	0x02,  0x17,  0xF2,  0x10,  0x8A,  0x7C,  0x8A,  0x11,  0x4A,  0x11,  0x6A,  0x37,  0xAA,  0x38,  0x8A,  0x34, 	/* 37710 */
+	0x8A,  0x53,  0xEA,  0x50,  0x8A,  0x10,  0x82,  0x10,  0xE2,  0x11,  0x82,  0x16,  0x02,  0x10,  0x06,  0xA2, 	/* 37720 */
+	0x10,  0x00,  0x13,  0xFE,  0x12,  0x02,  0x7F,  0xFE,  0x12,  0x22,  0x12,  0x22,  0x3A,  0x22,  0x36,  0xFA, 	/* 37730 */
+	0x32,  0x22,  0x52,  0x32,  0x52,  0x2A,  0x12,  0x22,  0x13,  0xFE,  0x12,  0x02,  0x13,  0xFE,  0x10,  0x00, 	/* 37740 */
+	0xA3,  0x08,  0x50,  0x08,  0x50,  0x08,  0x50,  0x7F,  0xFE,  0x09,  0x52,  0x09,  0x52,  0x1D,  0x52,  0x1B, 	/* 37750 */
+	0xFE,  0x29,  0x52,  0x29,  0x52,  0x49,  0x52,  0x0B,  0xFF,  0x08,  0x00,  0x08,  0x48,  0x08,  0x84,  0x0B, 	/* 37760 */
+	0x02,  0xA5,  0x12,  0x00,  0x12,  0x00,  0x12,  0x1E,  0x7B,  0xD2,  0x15,  0x12,  0x15,  0x12,  0x39,  0x12, 	/* 37770 */
+	0x37,  0xF2,  0x31,  0x12,  0x51,  0x12,  0x51,  0x92,  0x11,  0x92,  0x12,  0x52,  0x12,  0x52,  0x14,  0x1E, 	/* 37780 */
+	0x18,  0x00,  0xA6,  0x08,  0x20,  0x08,  0xA8,  0x09,  0x24,  0x7E,  0xFA,  0x08,  0x20,  0x08,  0x50,  0x1D, 	/* 37790 */
+	0xFF,  0x1A,  0x48,  0x18,  0xA4,  0x29,  0x22,  0x2B,  0xFD,  0x48,  0x24,  0x08,  0x44,  0x08,  0x44,  0x08, 	/* 377A0 */
+	0x84,  0x09,  0x18,  0xA8,  0x08,  0x20,  0x08,  0x20,  0x09,  0xFF,  0x7F,  0x00,  0x09,  0x24,  0x09,  0x24, 	/* 377B0 */
+	0x1D,  0x3F,  0x1B,  0x44,  0x29,  0x64,  0x29,  0xD4,  0x49,  0x54,  0x09,  0x44,  0x0A,  0x44,  0x0A,  0x44, 	/* 377C0 */
+	0x0C,  0x44,  0x08,  0x4C,  0xAA,  0x08,  0x84,  0x08,  0x44,  0x08,  0x48,  0x7E,  0x00,  0x09,  0xFE,  0x0C, 	/* 377D0 */
+	0x48,  0x1A,  0x4A,  0x18,  0x4A,  0x19,  0x4A,  0x28,  0xCC,  0x28,  0xCC,  0x48,  0x48,  0x08,  0x48,  0x08, 	/* 377E0 */
+	0x48,  0x0B,  0xFF,  0x08,  0x00,  0xB0,  0x08,  0x00,  0x0B,  0xFF,  0x09,  0x29,  0x7F,  0x2A,  0x09,  0x2A, 	/* 377F0 */
+	0x09,  0xEC,  0x1D,  0x2A,  0x1B,  0x2A,  0x29,  0xE9,  0x29,  0x29,  0x49,  0x29,  0x09,  0x39,  0x09,  0xEE, 	/* 37800 */
+	0x0B,  0x28,  0x08,  0x28,  0x08,  0x28,  0xB4,  0x10,  0x40,  0x10,  0xBC,  0x13,  0x24,  0x7E,  0x24,  0x12, 	/* 37810 */
+	0x25,  0x13,  0xA5,  0x3A,  0x43,  0x36,  0x80,  0x33,  0xFC,  0x52,  0x24,  0x52,  0x24,  0x13,  0x98,  0x16, 	/* 37820 */
+	0x08,  0x12,  0x14,  0x12,  0x22,  0x12,  0xC1,  0xB6,  0x08,  0x8A,  0x08,  0xEA,  0x08,  0x92,  0x7E,  0xAA, 	/* 37830 */
+	0x08,  0xC2,  0x08,  0xFE,  0x1C,  0x48,  0x1A,  0x89,  0x19,  0x27,  0x2A,  0x3C,  0x28,  0x44,  0x48,  0xA8, 	/* 37840 */
+	0x09,  0x18,  0x08,  0x30,  0x08,  0xCC,  0x0B,  0x03,  0xB9,  0x08,  0x44,  0x08,  0x44,  0x09,  0xFF,  0x7F, 	/* 37850 */
+	0x44,  0x08,  0x7C,  0x08,  0x44,  0x1C,  0x7C,  0x1A,  0x44,  0x18,  0x44,  0x2B,  0xFF,  0x29,  0x28,  0x49, 	/* 37860 */
+	0x28,  0x09,  0x4F,  0x09,  0x80,  0x09,  0xFF,  0x08,  0x00,  0xBD,  0x08,  0x20,  0x08,  0x3E,  0x08,  0x44, 	/* 37870 */
+	0x7E,  0xF8,  0x08,  0x08,  0x09,  0xFF,  0x1C,  0x22,  0x1A,  0x52,  0x19,  0x94,  0x28,  0x28,  0x28,  0x4C, 	/* 37880 */
+	0x49,  0x9C,  0x08,  0x2A,  0x08,  0x49,  0x09,  0x88,  0x08,  0x30,  0xBF,  0x08,  0x20,  0x08,  0x20,  0x0B, 	/* 37890 */
+	0xFE,  0x7E,  0x20,  0x09,  0xFC,  0x08,  0x50,  0x1B,  0xFF,  0x1C,  0x48,  0x1A,  0x84,  0x29,  0xFA,  0x2A, 	/* 378A0 */
+	0x89,  0x4C,  0xF8,  0x08,  0x88,  0x08,  0x88,  0x08,  0xF8,  0x08,  0x00,  0x8A,  0x08,  0x00,  0x08,  0x7C, 	/* 378B0 */
+	0x08,  0x44,  0x7F,  0x7C,  0x08,  0x44,  0x08,  0x44,  0x1C,  0x7C,  0x1A,  0x00,  0x19,  0xFF,  0x28,  0x40, 	/* 378C0 */
+	0x28,  0xFE,  0x49,  0x2A,  0x0A,  0x4A,  0x08,  0x92,  0x08,  0x22,  0x08,  0x4C,  0x93,  0x10,  0x00,  0x13, 	/* 378D0 */
+	0xFC,  0x12,  0x0C,  0x7E,  0x34,  0x13,  0xC4,  0x12,  0x44,  0x3B,  0xF4,  0x37,  0x54,  0x33,  0x54,  0x53, 	/* 378E0 */
+	0xF4,  0x52,  0x44,  0x12,  0x64,  0x14,  0x55,  0x14,  0x75,  0x1B,  0x8B,  0x10,  0x01,  0x94,  0x10,  0x80, 	/* 378F0 */
+	0x10,  0xBE,  0x13,  0xEA,  0x7C,  0x8A,  0x10,  0x8A,  0x13,  0xEA,  0x38,  0x92,  0x34,  0xD2,  0x53,  0xA2, 	/* 37900 */
+	0x50,  0xAC,  0x10,  0x20,  0x17,  0xFF,  0x10,  0x20,  0x10,  0x50,  0x11,  0x8C,  0x16,  0x03,  0x95,  0x08, 	/* 37910 */
+	0x20,  0x08,  0x20,  0x09,  0xFF,  0x7E,  0x40,  0x08,  0x7E,  0x08,  0x90,  0x1D,  0x7F,  0x1A,  0x00,  0x1A, 	/* 37920 */
+	0xFC,  0x28,  0x84,  0x28,  0xFC,  0x48,  0x84,  0x08,  0xFC,  0x08,  0x84,  0x08,  0x84,  0x08,  0x8C,  0x99, 	/* 37930 */
+	0x10,  0x04,  0x13,  0xE4,  0x10,  0x24,  0x7D,  0x5F,  0x10,  0x84,  0x18,  0x84,  0x37,  0xEE,  0x34,  0xAE, 	/* 37940 */
+	0x31,  0xD5,  0x51,  0x95,  0x52,  0xA4,  0x12,  0x84,  0x14,  0x84,  0x10,  0x84,  0x10,  0x84,  0x11,  0x84, 	/* 37950 */
+	0x9A,  0x04,  0x08,  0x04,  0x08,  0x7F,  0xFF,  0x0C,  0x1C,  0x16,  0x2A,  0x15,  0x29,  0x24,  0x48,  0x44, 	/* 37960 */
+	0x08,  0x00,  0x00,  0x3F,  0xFE,  0x08,  0x84,  0x08,  0x80,  0x0C,  0xFC,  0x12,  0x80,  0x21,  0xC0,  0x40, 	/* 37970 */
+	0x3F,  0x9C,  0x10,  0x80,  0x10,  0x9E,  0x10,  0x92,  0x7C,  0x92,  0x17,  0xF2,  0x10,  0x9E,  0x38,  0x92, 	/* 37980 */
+	0x34,  0x92,  0x33,  0xD2,  0x52,  0x5E,  0x52,  0x52,  0x12,  0x52,  0x13,  0xD2,  0x10,  0x22,  0x10,  0x22, 	/* 37990 */
+	0x10,  0x46,  0x9D,  0x08,  0x10,  0x08,  0x10,  0x09,  0xFF,  0x7E,  0x10,  0x08,  0x10,  0x08,  0xFE,  0x1C, 	/* 379A0 */
+	0x96,  0x1A,  0xDA,  0x2A,  0xB2,  0x28,  0xFE,  0x48,  0x18,  0x08,  0x34,  0x08,  0x52,  0x08,  0x91,  0x09, 	/* 379B0 */
+	0x10,  0x08,  0x10,  0x9E,  0x08,  0x00,  0x09,  0xFF,  0x09,  0x29,  0x7F,  0x29,  0x09,  0xFF,  0x08,  0x10, 	/* 379C0 */
+	0x1C,  0x10,  0x1B,  0xFF,  0x2A,  0x20,  0x28,  0x20,  0x48,  0x3C,  0x08,  0x24,  0x08,  0x44,  0x08,  0x44, 	/* 379D0 */
+	0x08,  0x84,  0x09,  0x18,  0xA0,  0x08,  0x20,  0x08,  0x20,  0x0B,  0xFF,  0x7C,  0x20,  0x08,  0x20,  0x09, 	/* 379E0 */
+	0xFE,  0x19,  0x8A,  0x1D,  0x52,  0x1B,  0xFA,  0x29,  0x22,  0x29,  0x22,  0x49,  0xFA,  0x09,  0x22,  0x09, 	/* 379F0 */
+	0x22,  0x09,  0x22,  0x09,  0x26,  0xA1,  0x08,  0x30,  0x08,  0x10,  0x08,  0x28,  0x7E,  0x44,  0x08,  0xFA, 	/* 37A00 */
+	0x09,  0x01,  0x1B,  0xEA,  0x1D,  0x2A,  0x2B,  0xAA,  0x29,  0x74,  0x49,  0x34,  0x09,  0xB4,  0x09,  0x6A, 	/* 37A10 */
+	0x09,  0x2A,  0x09,  0x2A,  0x09,  0x2A,  0xA2,  0x08,  0x84,  0x08,  0x44,  0x08,  0x48,  0x0B,  0xFF,  0x7E, 	/* 37A20 */
+	0x48,  0x08,  0x48,  0x09,  0xFE,  0x1D,  0x4A,  0x1B,  0x4A,  0x29,  0x8E,  0x29,  0x02,  0x49,  0xFE,  0x09, 	/* 37A30 */
+	0x02,  0x09,  0x02,  0x09,  0xFE,  0x08,  0x00,  0xAA,  0x08,  0xA4,  0x08,  0xA4,  0x0B,  0xFF,  0x7E,  0xA4, 	/* 37A40 */
+	0x08,  0xA4,  0x08,  0xBC,  0x1C,  0x80,  0x1A,  0xFE,  0x28,  0x20,  0x2B,  0xFF,  0x48,  0x70,  0x08,  0x68, 	/* 37A50 */
+	0x08,  0xA4,  0x09,  0x22,  0x0A,  0x21,  0x08,  0x20,  0xAB,  0x08,  0x00,  0x08,  0xFE,  0x08,  0x82,  0x7E, 	/* 37A60 */
+	0x82,  0x08,  0xFE,  0x08,  0x00,  0x1D,  0xFF,  0x1A,  0x82,  0x1A,  0xFE,  0x28,  0x82,  0x28,  0xFE,  0x48, 	/* 37A70 */
+	0x82,  0x08,  0x83,  0x08,  0xFE,  0x0B,  0x82,  0x08,  0x02,  0xAD,  0x01,  0x20,  0x09,  0x24,  0x05,  0x28, 	/* 37A80 */
+	0x7F,  0xFF,  0x04,  0x08,  0x02,  0x10,  0x3F,  0xFF,  0x00,  0x80,  0x1F,  0xFE,  0x00,  0x80,  0x7F,  0xFF, 	/* 37A90 */
+	0x02,  0xA0,  0x04,  0x90,  0x18,  0x8C,  0x60,  0x83,  0x00,  0x80,  0xAE,  0x08,  0x20,  0x08,  0x24,  0x08, 	/* 37AA0 */
+	0xFE,  0x7F,  0x24,  0x08,  0x28,  0x08,  0x30,  0x1D,  0xFF,  0x1A,  0x24,  0x1A,  0x42,  0x28,  0xFE,  0x29, 	/* 37AB0 */
+	0x42,  0x48,  0x7E,  0x08,  0x42,  0x08,  0x42,  0x08,  0x7E,  0x08,  0x00,  0xAF,  0x08,  0x04,  0x08,  0x18, 	/* 37AC0 */
+	0x09,  0xF0,  0x7F,  0x10,  0x09,  0xFF,  0x09,  0x10,  0x1D,  0x7E,  0x1B,  0x42,  0x1B,  0x42,  0x29,  0x7E, 	/* 37AD0 */
+	0x29,  0x42,  0x49,  0x7E,  0x0A,  0x42,  0x0A,  0x42,  0x0C,  0x7E,  0x08,  0x00,  0xB3,  0x08,  0x44,  0x08, 	/* 37AE0 */
+	0x44,  0x09,  0xFF,  0x7E,  0x44,  0x08,  0x7C,  0x08,  0x44,  0x1C,  0x44,  0x1A,  0x7C,  0x1A,  0x10,  0x29, 	/* 37AF0 */
+	0xFF,  0x28,  0x38,  0x48,  0x34,  0x08,  0x54,  0x08,  0x92,  0x09,  0x11,  0x08,  0x10,  0xB4,  0x08,  0x20, 	/* 37B00 */
+	0x08,  0x20,  0x09,  0xFF,  0x7E,  0x84,  0x08,  0x44,  0x08,  0x48,  0x1D,  0xFF,  0x1B,  0x11,  0x19,  0x11, 	/* 37B10 */
+	0x28,  0xFE,  0x28,  0x92,  0x48,  0x92,  0x08,  0x92,  0x08,  0x9C,  0x08,  0x10,  0x08,  0x10,  0xB5,  0x10, 	/* 37B20 */
+	0x00,  0x13,  0xFE,  0x10,  0x40,  0x7E,  0x40,  0x10,  0xE0,  0x10,  0x3E,  0x1B,  0xA2,  0x36,  0xAA,  0x32, 	/* 37B30 */
+	0xA4,  0x53,  0xA4,  0x52,  0xAA,  0x10,  0x31,  0x10,  0xC0,  0x10,  0x00,  0x17,  0xFF,  0x10,  0x00,  0xB7, 	/* 37B40 */
+	0x09,  0x10,  0x09,  0x10,  0x09,  0x12,  0x7F,  0xDC,  0x09,  0x11,  0x09,  0x31,  0x19,  0xCF,  0x1F,  0x20, 	/* 37B50 */
+	0x1A,  0x40,  0x29,  0xFC,  0x29,  0x04,  0x49,  0x04,  0x09,  0xFC,  0x09,  0x04,  0x09,  0xFC,  0x08,  0x00, 	/* 37B60 */
+	0xB8,  0x10,  0x28,  0x10,  0x48,  0x13,  0x88,  0x7C,  0x8A,  0x10,  0x9A,  0x10,  0x9A,  0x3B,  0xFC,  0x34, 	/* 37B70 */
+	0xA8,  0x30,  0xC8,  0x51,  0xAC,  0x51,  0x8C,  0x12,  0x94,  0x12,  0x94,  0x14,  0x92,  0x10,  0xA2,  0x10, 	/* 37B80 */
+	0xC1,  0xB9,  0x08,  0x00,  0x09,  0xFC,  0x08,  0x84,  0x7E,  0x84,  0x08,  0xF6,  0x0C,  0xD2,  0x1A,  0xA2, 	/* 37B90 */
+	0x19,  0x52,  0x1A,  0x8C,  0x28,  0x00,  0x29,  0xFE,  0x49,  0x4A,  0x09,  0x4A,  0x09,  0x4A,  0x0B,  0xFF, 	/* 37BA0 */
+	0x08,  0x00,  0xBC,  0x08,  0x10,  0x08,  0x92,  0x08,  0x54,  0x7F,  0xFF,  0x08,  0x38,  0x08,  0x54,  0x1C, 	/* 37BB0 */
+	0x92,  0x1A,  0x11,  0x1A,  0x20,  0x29,  0xFF,  0x29,  0x24,  0x48,  0x44,  0x08,  0xE8,  0x08,  0x18,  0x08, 	/* 37BC0 */
+	0x64,  0x09,  0x82,  0xBD,  0x00,  0x40,  0x20,  0x82,  0x13,  0xE2,  0x0A,  0x24,  0x0A,  0x28,  0x03,  0xE0, 	/* 37BD0 */
+	0x02,  0x28,  0x0E,  0x26,  0x33,  0xE1,  0x00,  0x80,  0x7F,  0xFF,  0x01,  0xC0,  0x02,  0xA0,  0x0C,  0x98, 	/* 37BE0 */
+	0x70,  0x87,  0x00,  0x80,  0xBE,  0x08,  0x10,  0x08,  0x10,  0x08,  0xFC,  0x7F,  0x84,  0x08,  0xFC,  0x08, 	/* 37BF0 */
+	0x84,  0x1C,  0x84,  0x1A,  0xFC,  0x1A,  0x12,  0x29,  0xD2,  0x28,  0x5C,  0x48,  0x94,  0x09,  0x12,  0x0A, 	/* 37C00 */
+	0x11,  0x08,  0x10,  0x08,  0x30,  0x81,  0x08,  0x10,  0x08,  0x10,  0x09,  0xFF,  0x7F,  0x01,  0x09,  0x01, 	/* 37C10 */
+	0x08,  0xFE,  0x1C,  0x28,  0x1A,  0x44,  0x1B,  0xFA,  0x28,  0x10,  0x28,  0x10,  0x48,  0xFE,  0x08,  0x10, 	/* 37C20 */
+	0x08,  0x10,  0x0B,  0xFF,  0x08,  0x00,  0x82,  0x10,  0x00,  0x13,  0xFF,  0x12,  0x44,  0x12,  0x54,  0x7F, 	/* 37C30 */
+	0xD4,  0x12,  0x54,  0x12,  0x54,  0x3B,  0xFF,  0x37,  0x04,  0x32,  0x8C,  0x52,  0x8C,  0x12,  0x4C,  0x12, 	/* 37C40 */
+	0xD4,  0x13,  0x55,  0x1C,  0x25,  0x10,  0x43,  0x8A,  0x09,  0x08,  0x09,  0x08,  0x09,  0x08,  0x7F,  0xFE, 	/* 37C50 */
+	0x08,  0x6A,  0x08,  0xAA,  0x1C,  0xBE,  0x1D,  0x2A,  0x19,  0xAA,  0x2B,  0x6A,  0x2D,  0x3E,  0x49,  0x08, 	/* 37C60 */
+	0x09,  0x08,  0x09,  0x08,  0x09,  0x08,  0x09,  0x08,  0x8E,  0x08,  0x00,  0x0B,  0xFF,  0x08,  0x20,  0x7E, 	/* 37C70 */
+	0xFC,  0x08,  0x84,  0x08,  0xFC,  0x1C,  0x84,  0x1A,  0xFC,  0x1A,  0x84,  0x29,  0xFC,  0x28,  0x20,  0x48, 	/* 37C80 */
+	0x7C,  0x09,  0xC8,  0x08,  0x30,  0x08,  0xCC,  0x0B,  0x03,  0x91,  0x08,  0x24,  0x08,  0x22,  0x0B,  0xFF, 	/* 37C90 */
+	0x7E,  0x20,  0x09,  0xFC,  0x09,  0x24,  0x1D,  0xFC,  0x1B,  0x24,  0x29,  0xFC,  0x29,  0x24,  0x48,  0x08, 	/* 37CA0 */
+	0x0B,  0xFF,  0x08,  0x88,  0x08,  0x48,  0x08,  0x08,  0x08,  0x18,  0x94,  0x10,  0x80,  0x10,  0x9E,  0x13, 	/* 37CB0 */
+	0xD2,  0x7E,  0x52,  0x12,  0x54,  0x13,  0xD8,  0x3A,  0x54,  0x36,  0x52,  0x33,  0xD2,  0x52,  0x11,  0x52, 	/* 37CC0 */
+	0x91,  0x12,  0x59,  0x12,  0xD6,  0x13,  0x30,  0x16,  0x30,  0x10,  0x10,  0x95,  0x08,  0x10,  0x08,  0x10, 	/* 37CD0 */
+	0x09,  0xFF,  0x7F,  0x09,  0x09,  0x45,  0x08,  0x52,  0x18,  0x92,  0x1C,  0x28,  0x1A,  0x44,  0x28,  0x82, 	/* 37CE0 */
+	0x29,  0x01,  0x4A,  0xFE,  0x08,  0x82,  0x08,  0x82,  0x08,  0xFE,  0x08,  0x00,  0x9B,  0x08,  0x20,  0x09, 	/* 37CF0 */
+	0xFE,  0x08,  0x20,  0x7F,  0xFC,  0x08,  0x50,  0x0D,  0xFF,  0x1A,  0x88,  0x19,  0x14,  0x1A,  0xE2,  0x2C, 	/* 37D00 */
+	0x21,  0x2B,  0xFE,  0x48,  0x70,  0x08,  0xA8,  0x09,  0x24,  0x0A,  0x22,  0x08,  0x20,  0x9C,  0x08,  0x20, 	/* 37D10 */
+	0x08,  0x20,  0x0B,  0xFF,  0x7E,  0x84,  0x08,  0x48,  0x09,  0xFE,  0x19,  0x02,  0x1D,  0x22,  0x2A,  0x20, 	/* 37D20 */
+	0x2B,  0xFF,  0x48,  0x40,  0x08,  0x7C,  0x08,  0x44,  0x08,  0x84,  0x09,  0x04,  0x0A,  0x18,  0xA0,  0x08, 	/* 37D30 */
+	0x00,  0x09,  0xFF,  0x09,  0x01,  0x7F,  0x7D,  0x08,  0x44,  0x08,  0x44,  0x1C,  0x7C,  0x1A,  0x44,  0x1A, 	/* 37D40 */
+	0x44,  0x28,  0x7C,  0x28,  0x10,  0x4B,  0xFF,  0x08,  0x00,  0x08,  0x24,  0x08,  0xC2,  0x0B,  0x01,  0xA7, 	/* 37D50 */
+	0x08,  0x00,  0x09,  0xFF,  0x09,  0x14,  0x7F,  0x14,  0x09,  0x77,  0x09,  0x14,  0x1D,  0x74,  0x1B,  0x17, 	/* 37D60 */
+	0x29,  0x3C,  0x29,  0xD4,  0x49,  0x27,  0x09,  0x24,  0x09,  0x44,  0x09,  0x00,  0x09,  0xFF,  0x08,  0x00, 	/* 37D70 */
+	0xAE,  0x04,  0x10,  0x15,  0x52,  0x16,  0x54,  0x26,  0x98,  0x09,  0x24,  0x30,  0xC0,  0x7F,  0xFE,  0x40, 	/* 37D80 */
+	0x02,  0x40,  0x82,  0x00,  0x80,  0x7F,  0xFE,  0x01,  0xC0,  0x02,  0xA0,  0x0C,  0x98,  0x70,  0x87,  0x00, 	/* 37D90 */
+	0x80,  0xB1,  0x08,  0x20,  0x08,  0x20,  0x0B,  0xFF,  0x7E,  0x00,  0x08,  0xFC,  0x08,  0x84,  0x1B,  0xFF, 	/* 37DA0 */
+	0x1C,  0x84,  0x1A,  0xFC,  0x2A,  0x32,  0x28,  0xD2,  0x4B,  0x8C,  0x08,  0x88,  0x08,  0x84,  0x08,  0xE2, 	/* 37DB0 */
+	0x0B,  0x81,  0xB2,  0x08,  0x00,  0x08,  0xFC,  0x08,  0xA4,  0x7F,  0xA4,  0x08,  0xB4,  0x08,  0xCC,  0x1C, 	/* 37DC0 */
+	0xC4,  0x1A,  0xFC,  0x1A,  0x00,  0x29,  0xFE,  0x29,  0x52,  0x49,  0x52,  0x09,  0x52,  0x09,  0x52,  0x0B, 	/* 37DD0 */
+	0xFF,  0x08,  0x00,  0xB4,  0x08,  0x40,  0x08,  0x5F,  0x09,  0x85,  0x7F,  0x05,  0x09,  0x45,  0x09,  0x29, 	/* 37DE0 */
+	0x1D,  0xD1,  0x1B,  0x26,  0x1A,  0x00,  0x28,  0xFE,  0x28,  0x92,  0x48,  0xFE,  0x08,  0x92,  0x08,  0x92, 	/* 37DF0 */
+	0x08,  0xFE,  0x08,  0x00,  0xBB,  0x08,  0x00,  0x08,  0xFC,  0x08,  0x84,  0x7E,  0xFC,  0x08,  0x84,  0x08, 	/* 37E00 */
+	0xFC,  0x1C,  0x00,  0x1B,  0xFE,  0x2A,  0xAA,  0x28,  0xAA,  0x49,  0x76,  0x0A,  0x66,  0x08,  0xAA,  0x09, 	/* 37E10 */
+	0x32,  0x08,  0x22,  0x08,  0x66,  0xBE,  0x08,  0x00,  0x08,  0xFC,  0x08,  0x84,  0x7E,  0xBC,  0x08,  0xA4, 	/* 37E20 */
+	0x08,  0xA4,  0x1B,  0xFF,  0x1A,  0x01,  0x2C,  0xFC,  0x2A,  0x84,  0x48,  0xFC,  0x08,  0x84,  0x08,  0xFC, 	/* 37E30 */
+	0x08,  0x84,  0x08,  0x84,  0x08,  0x8C,  0xBF,  0x10,  0x20,  0x11,  0x22,  0x11,  0x22,  0x7D,  0xFE,  0x10, 	/* 37E40 */
+	0x00,  0x13,  0xFE,  0x38,  0x00,  0x35,  0xFC,  0x35,  0x04,  0x51,  0x04,  0x51,  0xFC,  0x10,  0x88,  0x10, 	/* 37E50 */
+	0x48,  0x10,  0x50,  0x17,  0xFF,  0x10,  0x00,  0x81,  0x08,  0x20,  0x08,  0x20,  0x0B,  0xFF,  0x7E,  0x00, 	/* 37E60 */
+	0x08,  0xFC,  0x08,  0x84,  0x1C,  0xFC,  0x1A,  0x00,  0x1B,  0xFE,  0x29,  0x02,  0x29,  0x7A,  0x49,  0x4A, 	/* 37E70 */
+	0x09,  0x4A,  0x09,  0x7A,  0x09,  0x02,  0x09,  0x06,  0x83,  0x04,  0x00,  0x1F,  0x3C,  0x19,  0x24,  0x15, 	/* 37E80 */
+	0x25,  0x17,  0x43,  0x79,  0xFC,  0x15,  0x24,  0x25,  0x18,  0x43,  0x64,  0x00,  0x82,  0x7F,  0xFF,  0x02, 	/* 37E90 */
+	0xA0,  0x04,  0x90,  0x18,  0x8C,  0x60,  0x83,  0x00,  0x80,  0x87,  0x08,  0x82,  0x08,  0xFC,  0x08,  0x81, 	/* 37EA0 */
+	0x7F,  0x7F,  0x08,  0x00,  0x09,  0x7C,  0x1D,  0x44,  0x1B,  0x7C,  0x19,  0x44,  0x29,  0x7C,  0x29,  0x44, 	/* 37EB0 */
+	0x49,  0x7C,  0x09,  0x00,  0x09,  0xFF,  0x08,  0xCC,  0x0B,  0x02,  0x8A,  0x11,  0x00,  0x0A,  0x3E,  0x7F, 	/* 37EC0 */
+	0xA2,  0x04,  0x3E,  0x24,  0xA2,  0x24,  0xBE,  0x3F,  0xA2,  0x04,  0x22,  0x08,  0x46,  0x10,  0x80,  0x7F, 	/* 37ED0 */
+	0xFF,  0x01,  0xC0,  0x02,  0xA0,  0x0C,  0x98,  0x70,  0x87,  0x00,  0x80,  0x8B,  0x08,  0x48,  0x08,  0x48, 	/* 37EE0 */
+	0x09,  0xFF,  0x7E,  0x48,  0x09,  0xFE,  0x08,  0x48,  0x1B,  0xFF,  0x1C,  0x20,  0x1B,  0xFC,  0x29,  0x24, 	/* 37EF0 */
+	0x29,  0xFC,  0x49,  0x24,  0x0F,  0xFF,  0x09,  0x04,  0x09,  0x04,  0x09,  0x0C,  0x8C,  0x10,  0x08,  0x11, 	/* 37F00 */
+	0x10,  0x10,  0xBE,  0x7E,  0xA2,  0x10,  0x22,  0x10,  0x3E,  0x18,  0x20,  0x37,  0xA0,  0x34,  0xBE,  0x50, 	/* 37F10 */
+	0xA2,  0x50,  0xA2,  0x10,  0xA2,  0x10,  0xBE,  0x11,  0x60,  0x12,  0x30,  0x14,  0x0F,  0x8D,  0x08,  0x20, 	/* 37F20 */
+	0x08,  0x20,  0x08,  0x50,  0x7E,  0x88,  0x09,  0xFC,  0x0A,  0x02,  0x1C,  0xFD,  0x1A,  0x84,  0x1A,  0xFC, 	/* 37F30 */
+	0x28,  0x84,  0x28,  0xFC,  0x49,  0x00,  0x09,  0xFC,  0x0A,  0x84,  0x0C,  0xFC,  0x08,  0x00,  0x8E,  0x08, 	/* 37F40 */
+	0x88,  0x08,  0x50,  0x09,  0xFE,  0x7E,  0x20,  0x08,  0x20,  0x09,  0xFC,  0x1C,  0x20,  0x1A,  0x20,  0x1B, 	/* 37F50 */
+	0xFF,  0x28,  0x40,  0x28,  0x40,  0x48,  0xFE,  0x09,  0x10,  0x0A,  0x10,  0x09,  0xFF,  0x08,  0x00,  0x90, 	/* 37F60 */
+	0x08,  0x20,  0x08,  0x40,  0x09,  0xFC,  0x7F,  0x24,  0x09,  0x24,  0x09,  0xFC,  0x1D,  0x24,  0x1B,  0x24, 	/* 37F70 */
+	0x19,  0xFE,  0x28,  0x52,  0x28,  0x52,  0x48,  0x55,  0x08,  0x9F,  0x08,  0x91,  0x09,  0x11,  0x0A,  0x0F, 	/* 37F80 */
+	0x93,  0x08,  0x00,  0x08,  0xFE,  0x08,  0x10,  0x7E,  0x10,  0x09,  0xFF,  0x08,  0x00,  0x1C,  0xFE,  0x1A, 	/* 37F90 */
+	0x82,  0x1A,  0xFE,  0x28,  0x82,  0x28,  0xFE,  0x48,  0x82,  0x08,  0xFE,  0x08,  0x24,  0x08,  0xC2,  0x0B, 	/* 37FA0 */
+	0x01,  0x98,  0x08,  0x84,  0x08,  0x48,  0x09,  0xFE,  0x7E,  0x10,  0x09,  0xFC,  0x08,  0x10,  0x1C,  0x10, 	/* 37FB0 */
+	0x1B,  0xFF,  0x1A,  0x12,  0x28,  0x9C,  0x28,  0x58,  0x48,  0x74,  0x08,  0x92,  0x0B,  0x11,  0x08,  0x10, 	/* 37FC0 */
+	0x08,  0x30,  0x99,  0x08,  0x10,  0x08,  0x10,  0x0B,  0xFF,  0x7E,  0x10,  0x08,  0xFC,  0x08,  0x84,  0x1C, 	/* 37FD0 */
+	0xFC,  0x1A,  0x84,  0x1A,  0xFC,  0x28,  0x84,  0x28,  0xFC,  0x48,  0x00,  0x09,  0xFF,  0x08,  0x48,  0x08, 	/* 37FE0 */
+	0x86,  0x0B,  0x01,  0x9D,  0x08,  0x20,  0x08,  0x40,  0x08,  0xFC,  0x7F,  0x84,  0x08,  0xFC,  0x08,  0x84, 	/* 37FF0 */
+	0x1C,  0xFC,  0x1A,  0x80,  0x1A,  0xFF,  0x28,  0x80,  0x28,  0xFE,  0x4A,  0x42,  0x0A,  0x4A,  0x0B,  0xFA, 	/* 38000 */
+	0x08,  0x02,  0x08,  0x0C,  0x9E,  0x08,  0x20,  0x08,  0x20,  0x09,  0xFC,  0x7E,  0x88,  0x08,  0x50,  0x0B, 	/* 38010 */
+	0xFF,  0x1C,  0x00,  0x1B,  0xFC,  0x1B,  0x24,  0x29,  0x24,  0x29,  0xFC,  0x49,  0x24,  0x09,  0xFC,  0x08, 	/* 38020 */
+	0x21,  0x08,  0x21,  0x08,  0x1F,  0xA7,  0x04,  0x02,  0x04,  0x0C,  0x7F,  0xB0,  0x25,  0x20,  0x3F,  0x3F, 	/* 38030 */
+	0x25,  0x24,  0x3F,  0x24,  0x04,  0x24,  0x7F,  0xC4,  0x04,  0x84,  0x00,  0x80,  0x7F,  0xFF,  0x02,  0xA0, 	/* 38040 */
+	0x0C,  0x98,  0x70,  0x87,  0x00,  0x80,  0xA8,  0x10,  0x80,  0x10,  0x9E,  0x17,  0xF2,  0x7C,  0x12,  0x13, 	/* 38050 */
+	0xD4,  0x12,  0x54,  0x3B,  0xD8,  0x34,  0x14,  0x33,  0xD4,  0x50,  0x52,  0x50,  0x92,  0x10,  0xF2,  0x17, 	/* 38060 */
+	0x92,  0x10,  0x9C,  0x10,  0x90,  0x11,  0x90,  0xAB,  0x08,  0x20,  0x08,  0x20,  0x0B,  0xFF,  0x7E,  0x20, 	/* 38070 */
+	0x09,  0xFC,  0x09,  0x24,  0x1D,  0xFC,  0x1B,  0x24,  0x29,  0xFC,  0x28,  0x22,  0x4B,  0xFD,  0x08,  0x08, 	/* 38080 */
+	0x0B,  0xFF,  0x08,  0x88,  0x08,  0x48,  0x08,  0x18,  0xAD,  0x08,  0x08,  0x08,  0x0A,  0x08,  0x09,  0x7F, 	/* 38090 */
+	0xFF,  0x09,  0x08,  0x09,  0x48,  0x1D,  0x7A,  0x1B,  0x4A,  0x29,  0xFA,  0x29,  0x4A,  0x49,  0x6C,  0x09, 	/* 380A0 */
+	0xD4,  0x0A,  0xD5,  0x0B,  0x4B,  0x0C,  0xD3,  0x08,  0x21,  0xB2,  0x11,  0x02,  0x11,  0xC2,  0x11,  0x52, 	/* 380B0 */
+	0x7A,  0x8A,  0x17,  0xEA,  0x12,  0xA2,  0x3A,  0xB2,  0x37,  0xEA,  0x32,  0xAA,  0x52,  0xA2,  0x53,  0xE3, 	/* 380C0 */
+	0x12,  0x2E,  0x12,  0x32,  0x12,  0x22,  0x12,  0x22,  0x14,  0x62,  0xB9,  0x08,  0x20,  0x08,  0x40,  0x08, 	/* 380D0 */
+	0xFC,  0x7E,  0x84,  0x08,  0xFC,  0x0C,  0x84,  0x1A,  0xFC,  0x18,  0x00,  0x1B,  0xAE,  0x28,  0x20,  0x2B, 	/* 380E0 */
+	0xAE,  0x48,  0x20,  0x0F,  0xFF,  0x08,  0x20,  0x08,  0x20,  0x08,  0x20,  0xBB,  0x08,  0x80,  0x08,  0x9E, 	/* 380F0 */
+	0x0B,  0xF2,  0x7E,  0x92,  0x08,  0x9E,  0x08,  0x92,  0x1B,  0xF2,  0x1C,  0x9E,  0x2A,  0x92,  0x28,  0xD2, 	/* 38100 */
+	0x49,  0x5E,  0x09,  0x2C,  0x0A,  0x0C,  0x0A,  0x15,  0x0C,  0x25,  0x08,  0xC3,  0xBD,  0x08,  0x48,  0x08, 	/* 38110 */
+	0x48,  0x09,  0xFF,  0x7E,  0x48,  0x09,  0xFE,  0x09,  0x4A,  0x1D,  0xFE,  0x1B,  0x4A,  0x19,  0xFE,  0x28, 	/* 38120 */
+	0x00,  0x28,  0xFC,  0x48,  0x84,  0x08,  0xFC,  0x08,  0x84,  0x08,  0xFC,  0x08,  0x00,  0xBF,  0x08,  0x44, 	/* 38130 */
+	0x08,  0x44,  0x09,  0xFF,  0x7E,  0x44,  0x08,  0x7C,  0x08,  0x10,  0x1C,  0xFE,  0x1A,  0x92,  0x1A,  0xFE, 	/* 38140 */
+	0x28,  0x10,  0x28,  0xFE,  0x48,  0x10,  0x08,  0xFE,  0x08,  0x10,  0x0B,  0xFF,  0x08,  0x00,  0x82,  0x08, 	/* 38150 */
+	0x44,  0x08,  0x84,  0x0B,  0xE5,  0x75,  0x3A,  0x15,  0x2A,  0x09,  0xE4,  0x09,  0x24,  0x15,  0x2A,  0x7B, 	/* 38160 */
+	0xFD,  0x00,  0x80,  0x7F,  0xFF,  0x02,  0xA0,  0x04,  0x90,  0x18,  0x8C,  0x60,  0x83,  0x00,  0x80,  0x85, 	/* 38170 */
+	0x11,  0x22,  0x11,  0x22,  0x11,  0x22,  0x7E,  0x55,  0x12,  0x49,  0x10,  0x80,  0x38,  0x88,  0x35,  0x08, 	/* 38180 */
+	0x31,  0x28,  0x53,  0x2E,  0x55,  0x28,  0x11,  0x28,  0x11,  0x28,  0x11,  0x58,  0x11,  0x48,  0x11,  0x87, 	/* 38190 */
+	0x8A,  0x08,  0x44,  0x09,  0x44,  0x7E,  0x9F,  0x09,  0x44,  0x1C,  0x0E,  0x1A,  0x4E,  0x29,  0x95,  0x48, 	/* 381A0 */
+	0xA5,  0x09,  0x44,  0x0A,  0x84,  0x00,  0x80,  0x7F,  0xFF,  0x01,  0x40,  0x02,  0x20,  0x0C,  0x18,  0x70, 	/* 381B0 */
+	0x07,  0x8B,  0x10,  0x00,  0x12,  0x7C,  0x11,  0x04,  0x7D,  0x28,  0x10,  0x10,  0x10,  0x7E,  0x38,  0x52, 	/* 381C0 */
+	0x37,  0x7E,  0x35,  0x52,  0x51,  0x7E,  0x51,  0x52,  0x11,  0x52,  0x11,  0x52,  0x12,  0xC6,  0x14,  0x60, 	/* 381D0 */
+	0x18,  0x1F,  0x8C,  0x08,  0x00,  0x08,  0xFC,  0x08,  0xA4,  0x7F,  0xFF,  0x09,  0x28,  0x09,  0xF8,  0x1C, 	/* 381E0 */
+	0x00,  0x1B,  0xFC,  0x1B,  0x04,  0x29,  0xFC,  0x29,  0x04,  0x49,  0xFC,  0x09,  0x04,  0x09,  0xFC,  0x08, 	/* 381F0 */
+	0x8C,  0x0B,  0x02,  0x92,  0x08,  0x10,  0x08,  0x10,  0x09,  0xFF,  0x7F,  0x25,  0x09,  0x15,  0x0C,  0xA8, 	/* 38200 */
+	0x1A,  0xAA,  0x19,  0x31,  0x2A,  0x62,  0x29,  0x9E,  0x48,  0x10,  0x09,  0x11,  0x09,  0x11,  0x09,  0x11, 	/* 38210 */
+	0x09,  0xFF,  0x08,  0x00,  0x93,  0x08,  0x20,  0x09,  0xFC,  0x09,  0x24,  0x7F,  0xFF,  0x09,  0x24,  0x09, 	/* 38220 */
+	0xFC,  0x1C,  0x20,  0x1B,  0xFC,  0x19,  0x24,  0x29,  0xFC,  0x28,  0x40,  0x4B,  0xFF,  0x08,  0x48,  0x09, 	/* 38230 */
+	0xC8,  0x08,  0x38,  0x09,  0xC4,  0x94,  0x08,  0x49,  0x09,  0xB6,  0x08,  0x92,  0x7F,  0x49,  0x08,  0xFE, 	/* 38240 */
+	0x08,  0x92,  0x1C,  0xFE,  0x1A,  0x92,  0x1A,  0xFE,  0x28,  0x10,  0x29,  0xFF,  0x48,  0x38,  0x08,  0x54, 	/* 38250 */
+	0x08,  0x92,  0x0B,  0x11,  0x08,  0x10,  0x97,  0x08,  0x00,  0x08,  0xFE,  0x08,  0x10,  0x7F,  0xFF,  0x09, 	/* 38260 */
+	0x11,  0x09,  0xDD,  0x19,  0x11,  0x1C,  0xDC,  0x1A,  0x00,  0x28,  0xFC,  0x28,  0x00,  0x49,  0xFF,  0x08, 	/* 38270 */
+	0x20,  0x08,  0x3C,  0x08,  0x44,  0x08,  0x0C,  0x99,  0x08,  0x00,  0x09,  0xFF,  0x08,  0x28,  0x7F,  0xFE, 	/* 38280 */
+	0x08,  0xAA,  0x08,  0xAA,  0x1C,  0xFE,  0x1A,  0x00,  0x1A,  0xFC,  0x28,  0x00,  0x2B,  0xFF,  0x48,  0x50, 	/* 38290 */
+	0x08,  0x54,  0x08,  0x92,  0x09,  0x11,  0x08,  0x30,  0x9B,  0x08,  0x00,  0x0B,  0xDE,  0x08,  0xC6,  0x7F, 	/* 382A0 */
+	0x5A,  0x08,  0xC6,  0x09,  0x5A,  0x1C,  0x62,  0x1A,  0x30,  0x18,  0x48,  0x28,  0x94,  0x2B,  0x23,  0x48, 	/* 382B0 */
+	0xC8,  0x08,  0x32,  0x09,  0xC4,  0x08,  0x18,  0x09,  0xE0,  0x9E,  0x08,  0x00,  0x09,  0xFF,  0x09,  0x00, 	/* 382C0 */
+	0x7F,  0x3C,  0x09,  0x24,  0x09,  0x24,  0x1D,  0x3C,  0x1B,  0x00,  0x19,  0xEE,  0x29,  0xAA,  0x29,  0xAA, 	/* 382D0 */
+	0x49,  0xAA,  0x09,  0xEE,  0x09,  0x00,  0x09,  0xFF,  0x08,  0x00,  0x9F,  0x08,  0x20,  0x08,  0x20,  0x09, 	/* 382E0 */
+	0xFE,  0x7E,  0x88,  0x08,  0x50,  0x0B,  0xFF,  0x1C,  0x00,  0x1B,  0xFC,  0x19,  0x04,  0x29,  0xFC,  0x29, 	/* 382F0 */
+	0x04,  0x49,  0xFC,  0x08,  0x20,  0x0B,  0xFF,  0x08,  0x20,  0x08,  0x20,  0xA1,  0x08,  0x48,  0x08,  0x48, 	/* 38300 */
+	0x0B,  0xFF,  0x7E,  0x48,  0x08,  0x48,  0x08,  0xFC,  0x1C,  0x84,  0x1A,  0xFC,  0x1A,  0x84,  0x28,  0xFC, 	/* 38310 */
+	0x28,  0x20,  0x4B,  0xFF,  0x08,  0x20,  0x08,  0x50,  0x08,  0x8C,  0x0B,  0x03,  0xA2,  0x08,  0x20,  0x08, 	/* 38320 */
+	0x40,  0x08,  0xFC,  0x7E,  0x84,  0x08,  0xFC,  0x08,  0x84,  0x1C,  0xFC,  0x1A,  0x80,  0x1A,  0xFF,  0x28, 	/* 38330 */
+	0x80,  0x28,  0xFE,  0x48,  0x2A,  0x09,  0x96,  0x09,  0x52,  0x0A,  0x42,  0x08,  0x0C,  0xA3,  0x08,  0x84, 	/* 38340 */
+	0x08,  0x48,  0x09,  0xFE,  0x7E,  0x10,  0x08,  0xFC,  0x08,  0x10,  0x1B,  0xFF,  0x1C,  0x20,  0x1A,  0x18, 	/* 38350 */
+	0x28,  0x72,  0x28,  0x1A,  0x49,  0xDC,  0x08,  0x54,  0x08,  0x92,  0x0B,  0x11,  0x08,  0x30,  0xA9,  0x08, 	/* 38360 */
+	0x80,  0x08,  0x80,  0x08,  0xFE,  0x7F,  0x20,  0x09,  0x20,  0x0B,  0xFF,  0x18,  0x48,  0x1C,  0x50,  0x1A, 	/* 38370 */
+	0xFE,  0x28,  0x90,  0x29,  0xFE,  0x4A,  0x90,  0x08,  0xFE,  0x08,  0x90,  0x08,  0xFF,  0x08,  0x00,  0xAA, 	/* 38380 */
+	0x08,  0x88,  0x08,  0x88,  0x0B,  0xFE,  0x7E,  0x88,  0x08,  0x88,  0x0B,  0xFF,  0x1C,  0x20,  0x1B,  0xFC, 	/* 38390 */
+	0x19,  0x24,  0x29,  0xFC,  0x29,  0x24,  0x49,  0x24,  0x09,  0xFC,  0x08,  0x90,  0x09,  0x0C,  0x0E,  0x02, 	/* 383A0 */
+	0xAB,  0x10,  0x00,  0x13,  0xC0,  0x12,  0xBE,  0x7E,  0x92,  0x13,  0xD2,  0x12,  0x4C,  0x1B,  0xC8,  0x36, 	/* 383B0 */
+	0x94,  0x32,  0xA2,  0x33,  0xC1,  0x50,  0x20,  0x11,  0xFC,  0x10,  0x20,  0x10,  0x20,  0x17,  0xFF,  0x10, 	/* 383C0 */
+	0x00,  0xAE,  0x08,  0x00,  0x0B,  0xFF,  0x08,  0x50,  0x7E,  0x50,  0x09,  0xFE,  0x09,  0x52,  0x1D,  0x52, 	/* 383D0 */
+	0x1B,  0xFE,  0x29,  0x00,  0x28,  0x22,  0x48,  0xA2,  0x08,  0xA4,  0x09,  0x30,  0x08,  0x48,  0x09,  0x84, 	/* 383E0 */
+	0x0E,  0x02,  0xB5,  0x08,  0x44,  0x08,  0x48,  0x08,  0xFF,  0x7E,  0x90,  0x09,  0x90,  0x08,  0xFE,  0x18, 	/* 383F0 */
+	0x90,  0x1C,  0x90,  0x1A,  0xFE,  0x2A,  0x90,  0x28,  0x90,  0x48,  0xFF,  0x08,  0x00,  0x09,  0x52,  0x09, 	/* 38400 */
+	0x29,  0x0A,  0x29,  0xB6,  0x08,  0x00,  0x08,  0xFC,  0x08,  0x84,  0x7E,  0xFC,  0x08,  0x84,  0x08,  0xFC, 	/* 38410 */
+	0x1B,  0xFF,  0x1D,  0x20,  0x2B,  0xFE,  0x29,  0x2A,  0x49,  0xEA,  0x09,  0x24,  0x09,  0x24,  0x09,  0xEA, 	/* 38420 */
+	0x0B,  0x31,  0x08,  0x20,  0xB8,  0x08,  0x28,  0x08,  0xAA,  0x08,  0x6C,  0x7F,  0x28,  0x09,  0xFF,  0x08, 	/* 38430 */
+	0x44,  0x1C,  0x28,  0x1A,  0xFE,  0x29,  0x10,  0x28,  0x7C,  0x48,  0x10,  0x09,  0xFF,  0x08,  0x10,  0x08, 	/* 38440 */
+	0x28,  0x08,  0xC4,  0x0B,  0x03,  0xB9,  0x10,  0x84,  0x10,  0x84,  0x13,  0xE4,  0x7C,  0x84,  0x17,  0xFF, 	/* 38450 */
+	0x10,  0x04,  0x3B,  0xC4,  0x36,  0x64,  0x36,  0x54,  0x53,  0xD4,  0x50,  0x44,  0x12,  0x44,  0x11,  0xB4, 	/* 38460 */
+	0x11,  0xC4,  0x17,  0x04,  0x10,  0x0C,  0xBA,  0x08,  0x48,  0x08,  0x48,  0x0B,  0xFF,  0x7C,  0x48,  0x0B, 	/* 38470 */
+	0xFE,  0x08,  0xA4,  0x1C,  0xA4,  0x1B,  0xFF,  0x18,  0xA4,  0x28,  0xA4,  0x2B,  0xFE,  0x48,  0x20,  0x0B, 	/* 38480 */
+	0xFF,  0x08,  0x20,  0x08,  0x20,  0x08,  0x20,  0xBD,  0x08,  0x84,  0x08,  0x48,  0x09,  0xFF,  0x7E,  0x50, 	/* 38490 */
+	0x09,  0xFC,  0x09,  0x54,  0x1D,  0x9C,  0x1B,  0x04,  0x1B,  0xFC,  0x29,  0x04,  0x29,  0xFC,  0x48,  0x08, 	/* 384A0 */
+	0x0B,  0xFF,  0x08,  0x88,  0x08,  0x48,  0x08,  0x18,  0x84,  0x10,  0x08,  0x13,  0xE8,  0x11,  0x08,  0x7D, 	/* 384B0 */
+	0x0F,  0x17,  0xF2,  0x12,  0x52,  0x3A,  0x6A,  0x37,  0xCA,  0x32,  0x4A,  0x52,  0x4C,  0x53,  0xC4,  0x12, 	/* 384C0 */
+	0x44,  0x12,  0x4A,  0x13,  0xD2,  0x16,  0x61,  0x10,  0x41,  0x87,  0x08,  0x08,  0x09,  0xF0,  0x08,  0x20, 	/* 384D0 */
+	0x7E,  0x3C,  0x09,  0xE0,  0x08,  0x3C,  0x1D,  0xE2,  0x1A,  0x1E,  0x28,  0x44,  0x2B,  0xB8,  0x49,  0xCF, 	/* 384E0 */
+	0x0F,  0x38,  0x09,  0xCF,  0x0F,  0x38,  0x09,  0x29,  0x08,  0xE7,  0x88,  0x08,  0x20,  0x08,  0xFC,  0x08, 	/* 384F0 */
+	0x20,  0x7F,  0xFE,  0x08,  0x00,  0x0C,  0x44,  0x1B,  0xFF,  0x1A,  0x44,  0x28,  0x64,  0x29,  0x9F,  0x48, 	/* 38500 */
+	0x00,  0x0B,  0xFF,  0x08,  0x48,  0x08,  0x49,  0x08,  0x89,  0x0B,  0x07,  0x8B,  0x08,  0x0C,  0x09,  0xF0, 	/* 38510 */
+	0x08,  0x20,  0x7F,  0xFF,  0x08,  0x48,  0x08,  0xFC,  0x19,  0x4B,  0x1C,  0x78,  0x2A,  0x00,  0x2B,  0xFE, 	/* 38520 */
+	0x49,  0x02,  0x09,  0x7A,  0x09,  0x4A,  0x09,  0x7A,  0x09,  0x02,  0x09,  0x06,  0x98,  0x08,  0x00,  0x08, 	/* 38530 */
+	0xFC,  0x08,  0x48,  0x7E,  0x30,  0x09,  0xFE,  0x08,  0x54,  0x18,  0x90,  0x1D,  0x30,  0x1B,  0xFE,  0x29, 	/* 38540 */
+	0x52,  0x29,  0x56,  0x49,  0x9E,  0x09,  0x7A,  0x09,  0x4A,  0x09,  0x7A,  0x09,  0x06,  0x99,  0x08,  0xEA, 	/* 38550 */
+	0x08,  0x2C,  0x09,  0x29,  0x7E,  0xC6,  0x08,  0x44,  0x08,  0xFA,  0x1D,  0x01,  0x1A,  0xFC,  0x1A,  0x84, 	/* 38560 */
+	0x28,  0x84,  0x28,  0xFC,  0x48,  0x84,  0x08,  0x44,  0x08,  0x48,  0x0B,  0xFF,  0x08,  0x00,  0x9F,  0x08, 	/* 38570 */
+	0xA4,  0x08,  0xA4,  0x0B,  0x78,  0x7C,  0xA4,  0x08,  0xAA,  0x09,  0x7D,  0x1B,  0xE4,  0x1C,  0x22,  0x1B, 	/* 38580 */
+	0xFF,  0x28,  0x94,  0x28,  0x94,  0x48,  0xC8,  0x09,  0x29,  0x09,  0x15,  0x0A,  0x23,  0x0C,  0x41,  0xA1, 	/* 38590 */
+	0x08,  0x40,  0x08,  0x70,  0x08,  0x90,  0x7F,  0x20,  0x09,  0xFC,  0x09,  0x24,  0x1D,  0x24,  0x1B,  0xFC, 	/* 385A0 */
+	0x1A,  0x22,  0x28,  0xC4,  0x2B,  0x28,  0x48,  0xD8,  0x0B,  0x34,  0x08,  0xD2,  0x0B,  0x11,  0x08,  0x60, 	/* 385B0 */
+	0xA2,  0x10,  0x10,  0x13,  0x90,  0x12,  0xFF,  0x7E,  0x90,  0x13,  0x3E,  0x13,  0x48,  0x3A,  0xBF,  0x36, 	/* 385C0 */
+	0x80,  0x32,  0xBE,  0x52,  0xA2,  0x52,  0xBE,  0x13,  0xA2,  0x12,  0x3E,  0x12,  0x22,  0x12,  0x22,  0x12, 	/* 385D0 */
+	0x26,  0xA6,  0x08,  0x10,  0x08,  0xFE,  0x08,  0x44,  0x7F,  0x28,  0x09,  0xFF,  0x08,  0x00,  0x1C,  0xFE, 	/* 385E0 */
+	0x1A,  0x92,  0x1A,  0xFE,  0x28,  0x92,  0x28,  0xFE,  0x48,  0x10,  0x08,  0xFE,  0x08,  0x10,  0x0B,  0xFF, 	/* 385F0 */
+	0x08,  0x00,  0xB2,  0x08,  0x10,  0x09,  0xFF,  0x08,  0x10,  0x7E,  0xFE,  0x08,  0x00,  0x08,  0xFE,  0x1C, 	/* 38600 */
+	0x82,  0x1A,  0xFE,  0x1A,  0x44,  0x28,  0x28,  0x29,  0xFF,  0x48,  0x00,  0x08,  0xFE,  0x08,  0x82,  0x08, 	/* 38610 */
+	0xFE,  0x08,  0x00,  0xB8,  0x08,  0x00,  0x08,  0xFC,  0x08,  0x84,  0x7F,  0x84,  0x08,  0xFC,  0x08,  0x84, 	/* 38620 */
+	0x1C,  0xFC,  0x1A,  0x00,  0x28,  0x00,  0x2B,  0xDF,  0x4A,  0x51,  0x0B,  0xDF,  0x0A,  0x51,  0x0A,  0x51, 	/* 38630 */
+	0x0B,  0xDF,  0x08,  0x00,  0xBF,  0x08,  0x00,  0x0B,  0xFF,  0x08,  0x00,  0x7F,  0xFC,  0x09,  0x24,  0x19, 	/* 38640 */
+	0xFC,  0x1D,  0x24,  0x1B,  0xFF,  0x2A,  0x00,  0x29,  0xFC,  0x49,  0x24,  0x09,  0xFC,  0x09,  0x24,  0x09, 	/* 38650 */
+	0xFC,  0x08,  0x00,  0x0B,  0xFF,  0x80,  0x08,  0x20,  0x0B,  0xFF,  0x08,  0x00,  0x7F,  0xFE,  0x09,  0x7A, 	/* 38660 */
+	0x09,  0x4A,  0x1D,  0x7A,  0x1B,  0x02,  0x1B,  0xFE,  0x28,  0x84,  0x28,  0xFC,  0x48,  0x84,  0x08,  0xFC, 	/* 38670 */
+	0x08,  0x84,  0x0B,  0xFF,  0x08,  0x00,  0x84,  0x10,  0x88,  0x11,  0x08,  0x13,  0xC8,  0x7E,  0x4F,  0x13, 	/* 38680 */
+	0xD2,  0x12,  0x52,  0x33,  0xEA,  0x39,  0x0A,  0x37,  0xEA,  0x51,  0x0C,  0x51,  0xC4,  0x11,  0x44,  0x12, 	/* 38690 */
+	0x4E,  0x12,  0x4A,  0x14,  0x52,  0x11,  0xA1,  0x8D,  0x08,  0x20,  0x08,  0x20,  0x09,  0xFE,  0x7E,  0x84, 	/* 386A0 */
+	0x08,  0x48,  0x0B,  0xFF,  0x1C,  0x00,  0x1A,  0xFC,  0x1A,  0x84,  0x28,  0xFC,  0x28,  0x84,  0x48,  0xFC, 	/* 386B0 */
+	0x09,  0x50,  0x09,  0x4A,  0x0A,  0x45,  0x08,  0x3C,  0x8E,  0x08,  0x20,  0x08,  0x20,  0x08,  0x50,  0x7E, 	/* 386C0 */
+	0xA8,  0x09,  0xFC,  0x1B,  0x57,  0x1D,  0x24,  0x19,  0x54,  0x29,  0xFC,  0x28,  0x20,  0x4B,  0xFE,  0x0A, 	/* 386D0 */
+	0x22,  0x0A,  0x52,  0x0B,  0xEA,  0x0A,  0x02,  0x0A,  0x06,  0x90,  0x08,  0x40,  0x08,  0x78,  0x08,  0x90, 	/* 386E0 */
+	0x7F,  0xFF,  0x09,  0x2A,  0x09,  0xC6,  0x1D,  0x3C,  0x1B,  0x00,  0x29,  0xFF,  0x29,  0x00,  0x49,  0x7C, 	/* 386F0 */
+	0x09,  0x00,  0x0A,  0x7E,  0x0A,  0x42,  0x0C,  0x7E,  0x08,  0x00,  0x97,  0x00,  0x08,  0x1F,  0x08,  0x11, 	/* 38700 */
+	0x7E,  0x11,  0x22,  0x1F,  0x14,  0x10,  0x7F,  0x2F,  0x08,  0x29,  0x7E,  0x49,  0x08,  0x0F,  0x08,  0x00, 	/* 38710 */
+	0x80,  0x7F,  0xFF,  0x02,  0xA0,  0x0C,  0x98,  0x70,  0x87,  0x00,  0x80,  0x9C,  0x08,  0x20,  0x08,  0x30, 	/* 38720 */
+	0x08,  0x48,  0x7E,  0xF4,  0x0B,  0x03,  0x09,  0xFE,  0x1D,  0xA6,  0x1B,  0x6A,  0x19,  0xFE,  0x28,  0x00, 	/* 38730 */
+	0x28,  0xFC,  0x48,  0x84,  0x08,  0xFC,  0x08,  0x84,  0x08,  0xFC,  0x08,  0x00,  0xA0,  0x12,  0x10,  0x7F, 	/* 38740 */
+	0x90,  0x12,  0x3F,  0x1F,  0x24,  0x21,  0x44,  0x5D,  0x94,  0x15,  0x08,  0x1D,  0x34,  0x01,  0x42,  0x06, 	/* 38750 */
+	0x81,  0x00,  0x80,  0x7F,  0xFF,  0x02,  0xA0,  0x0C,  0x98,  0x70,  0x87,  0x00,  0x80,  0xA2,  0x08,  0x10, 	/* 38760 */
+	0x08,  0x30,  0x08,  0x28,  0x7F,  0x48,  0x08,  0x84,  0x09,  0xFA,  0x1C,  0x01,  0x1B,  0xDE,  0x29,  0x52, 	/* 38770 */
+	0x29,  0x52,  0x49,  0xDE,  0x08,  0x88,  0x08,  0x88,  0x08,  0xCC,  0x09,  0x32,  0x0A,  0x22,  0xA3,  0x08, 	/* 38780 */
+	0x20,  0x08,  0x20,  0x0B,  0xFF,  0x7E,  0xA4,  0x08,  0xA6,  0x08,  0xE5,  0x1D,  0x28,  0x1B,  0xFF,  0x28, 	/* 38790 */
+	0x00,  0x29,  0xFE,  0x49,  0x7A,  0x09,  0x4A,  0x09,  0x7A,  0x09,  0x02,  0x09,  0xFE,  0x08,  0x00,  0xAA, 	/* 387A0 */
+	0x08,  0x10,  0x09,  0x21,  0x08,  0xBA,  0x7E,  0xAA,  0x08,  0x2C,  0x08,  0x78,  0x1C,  0xAC,  0x1A,  0xAA, 	/* 387B0 */
+	0x2B,  0x39,  0x28,  0x10,  0x49,  0xFF,  0x08,  0x38,  0x08,  0x54,  0x08,  0x92,  0x09,  0x11,  0x08,  0x10, 	/* 387C0 */
+	0xAC,  0x08,  0x48,  0x09,  0xFF,  0x08,  0x48,  0x7F,  0xFE,  0x09,  0x02,  0x19,  0x7A,  0x1C,  0x00,  0x1B, 	/* 387D0 */
+	0xFF,  0x2A,  0x40,  0x28,  0xAA,  0x4B,  0x6A,  0x08,  0x94,  0x0B,  0x34,  0x08,  0x52,  0x09,  0x91,  0x08, 	/* 387E0 */
+	0x30,  0xAE,  0x08,  0x20,  0x09,  0xFE,  0x08,  0x20,  0x7E,  0xFC,  0x08,  0x00,  0x09,  0xFF,  0x1C,  0x02, 	/* 387F0 */
+	0x1A,  0xF8,  0x18,  0x20,  0x2B,  0xFF,  0x28,  0x04,  0x4B,  0xFF,  0x09,  0x64,  0x09,  0x54,  0x09,  0xC4, 	/* 38800 */
+	0x08,  0x0C,  0xB3,  0x08,  0x20,  0x09,  0xFF,  0x09,  0x01,  0x7E,  0xFE,  0x08,  0xA4,  0x08,  0xA8,  0x19, 	/* 38810 */
+	0x30,  0x1C,  0xFC,  0x2B,  0x84,  0x2A,  0xFC,  0x48,  0x84,  0x08,  0xFC,  0x08,  0x84,  0x08,  0xFC,  0x08, 	/* 38820 */
+	0xCC,  0x0B,  0x02,  0xB8,  0x08,  0x20,  0x08,  0x20,  0x0B,  0xFF,  0x7E,  0x21,  0x09,  0x55,  0x19,  0x4A, 	/* 38830 */
+	0x1A,  0x39,  0x1D,  0xFD,  0x29,  0x54,  0x29,  0xFC,  0x48,  0x00,  0x0B,  0xFF,  0x08,  0x20,  0x08,  0x20, 	/* 38840 */
+	0x08,  0x20,  0x08,  0x60,  0xBB,  0x08,  0x04,  0x09,  0xE4,  0x09,  0x44,  0x7F,  0x4F,  0x09,  0xE8,  0x09, 	/* 38850 */
+	0x30,  0x1D,  0xE0,  0x1B,  0x5F,  0x29,  0x40,  0x29,  0xF0,  0x48,  0x00,  0x09,  0xFE,  0x09,  0x52,  0x09, 	/* 38860 */
+	0x52,  0x0B,  0xFF,  0x08,  0x00,  0x81,  0x08,  0x10,  0x08,  0x10,  0x09,  0xFF,  0x7F,  0x25,  0x09,  0x95, 	/* 38870 */
+	0x08,  0xAA,  0x19,  0x31,  0x1A,  0x62,  0x29,  0x9E,  0x28,  0x10,  0x48,  0xFE,  0x08,  0x92,  0x08,  0xFE, 	/* 38880 */
+	0x08,  0x14,  0x08,  0x3E,  0x0B,  0xC1,  0x82,  0x08,  0x00,  0x0B,  0xDE,  0x09,  0x4A,  0x7E,  0xD6,  0x09, 	/* 38890 */
+	0x4A,  0x0A,  0x52,  0x18,  0x48,  0x1C,  0x50,  0x2A,  0xFE,  0x29,  0x90,  0x4A,  0xFE,  0x08,  0x90,  0x08, 	/* 388A0 */
+	0xFE,  0x08,  0x90,  0x08,  0xFF,  0x08,  0x00,  0x83,  0x10,  0x00,  0x13,  0xFF,  0x12,  0x20,  0x7E,  0xFC, 	/* 388B0 */
+	0x12,  0xA4,  0x12,  0xFC,  0x3A,  0x20,  0x37,  0xFF,  0x32,  0x84,  0x52,  0xFC,  0x12,  0x84,  0x12,  0xFC, 	/* 388C0 */
+	0x12,  0x44,  0x13,  0x82,  0x13,  0xFF,  0x10,  0x00,  0x91,  0x08,  0x00,  0x08,  0xFC,  0x08,  0xA4,  0x7E, 	/* 388D0 */
+	0xFC,  0x08,  0xA4,  0x18,  0xA4,  0x1C,  0xFC,  0x1A,  0x00,  0x2B,  0xFF,  0x2A,  0xB5,  0x4A,  0xB5,  0x0B, 	/* 388E0 */
+	0xFF,  0x0A,  0xB5,  0x0A,  0xB5,  0x0B,  0xFF,  0x08,  0x00,  0x93,  0x08,  0x10,  0x08,  0x3C,  0x08,  0x48, 	/* 388F0 */
+	0x7F,  0xFE,  0x08,  0x92,  0x08,  0xFE,  0x1C,  0x92,  0x1A,  0xFE,  0x18,  0xAA,  0x29,  0x15,  0x28,  0xFE, 	/* 38900 */
+	0x48,  0x82,  0x08,  0xFE,  0x08,  0x82,  0x08,  0xFE,  0x08,  0x00,  0x9A,  0x10,  0x00,  0x13,  0xDE,  0x12, 	/* 38910 */
+	0x52,  0x7F,  0xDE,  0x12,  0x52,  0x13,  0xDE,  0x3A,  0x02,  0x36,  0xFA,  0x52,  0x8A,  0x52,  0xFA,  0x12, 	/* 38920 */
+	0x42,  0x12,  0xFA,  0x12,  0x8A,  0x12,  0xFA,  0x12,  0x02,  0x12,  0x06,  0x9B,  0x11,  0x10,  0x11,  0x10, 	/* 38930 */
+	0x11,  0xDF,  0x7A,  0xA8,  0x12,  0x44,  0x14,  0x00,  0x33,  0xDE,  0x3A,  0x52,  0x37,  0xD2,  0x52,  0x52, 	/* 38940 */
+	0x53,  0xD2,  0x12,  0x12,  0x12,  0x92,  0x13,  0xDC,  0x16,  0x50,  0x10,  0x50,  0x9E,  0x11,  0x08,  0x11, 	/* 38950 */
+	0x0E,  0x11,  0x12,  0x7E,  0x5C,  0x12,  0x84,  0x19,  0x7F,  0x35,  0x10,  0x32,  0xAA,  0x3F,  0xCA,  0x51, 	/* 38960 */
+	0x14,  0x55,  0x2C,  0x15,  0x4E,  0x15,  0x56,  0x15,  0x65,  0x19,  0x04,  0x11,  0x18,  0x9F,  0x08,  0x92, 	/* 38970 */
+	0x08,  0xA2,  0x08,  0xBA,  0x7F,  0x6D,  0x09,  0x6D,  0x08,  0xBA,  0x1C,  0xAA,  0x1B,  0x7D,  0x29,  0xD7, 	/* 38980 */
+	0x28,  0x10,  0x49,  0xFF,  0x08,  0x38,  0x08,  0x54,  0x08,  0x92,  0x09,  0x11,  0x08,  0x10,  0xA8,  0x10, 	/* 38990 */
+	0x20,  0x10,  0x3C,  0x10,  0x20,  0x13,  0xFE,  0x7E,  0x44,  0x13,  0xF8,  0x12,  0x42,  0x3A,  0xFE,  0x36, 	/* 389A0 */
+	0xA4,  0x32,  0xFC,  0x52,  0xA4,  0x54,  0xFC,  0x15,  0xFE,  0x19,  0x52,  0x17,  0xFF,  0x10,  0x00,  0xAA, 	/* 389B0 */
+	0x08,  0x00,  0x09,  0xFF,  0x09,  0x12,  0x7F,  0x6C,  0x09,  0x24,  0x0D,  0xFF,  0x1D,  0x34,  0x1B,  0x6E, 	/* 389C0 */
+	0x29,  0xB5,  0x29,  0x24,  0x49,  0x48,  0x0A,  0x4F,  0x0A,  0x48,  0x0C,  0x48,  0x09,  0xFF,  0x08,  0x00, 	/* 389D0 */
+	0xBA,  0x08,  0x00,  0x09,  0xFE,  0x08,  0x10,  0x7F,  0xFF,  0x09,  0x11,  0x09,  0xDD,  0x1D,  0x11,  0x1A, 	/* 389E0 */
+	0xDC,  0x28,  0x10,  0x28,  0x00,  0x49,  0xFF,  0x09,  0x6D,  0x09,  0x6D,  0x09,  0x6D,  0x09,  0xFF,  0x08, 	/* 389F0 */
+	0x00,  0xBB,  0x10,  0x00,  0x13,  0xDE,  0x12,  0x52,  0x7F,  0xDE,  0x12,  0x52,  0x13,  0xDE,  0x3A,  0x52, 	/* 38A00 */
+	0x37,  0xDE,  0x35,  0x54,  0x52,  0x22,  0x50,  0x40,  0x17,  0xFF,  0x10,  0x88,  0x11,  0xF0,  0x10,  0xD8, 	/* 38A10 */
+	0x17,  0x04,  0x84,  0x10,  0x00,  0x13,  0xDE,  0x12,  0x52,  0x7F,  0xDE,  0x12,  0x52,  0x13,  0xDE,  0x3A, 	/* 38A20 */
+	0x22,  0x37,  0xFE,  0x52,  0xAA,  0x52,  0xFA,  0x12,  0xAA,  0x12,  0xFA,  0x12,  0x72,  0x12,  0xAA,  0x13, 	/* 38A30 */
+	0x22,  0x12,  0x26,  0x85,  0x08,  0x20,  0x08,  0x76,  0x08,  0xA2,  0x7E,  0xF6,  0x08,  0xAA,  0x08,  0xEE, 	/* 38A40 */
+	0x1D,  0xFF,  0x1A,  0xCC,  0x19,  0x72,  0x2A,  0x11,  0x28,  0xFE,  0x48,  0x10,  0x09,  0xFF,  0x08,  0x10, 	/* 38A50 */
+	0x08,  0x10,  0x08,  0x30,  0x8A,  0x08,  0x48,  0x0B,  0xFF,  0x08,  0x48,  0x7F,  0xEF,  0x09,  0x29,  0x09, 	/* 38A60 */
+	0xEF,  0x1C,  0x48,  0x1A,  0x90,  0x29,  0xFF,  0x2A,  0x90,  0x48,  0xFE,  0x08,  0x90,  0x08,  0xFE,  0x08, 	/* 38A70 */
+	0x90,  0x08,  0xFF,  0x08,  0x00,  0x92,  0x10,  0x04,  0x13,  0xC4,  0x68,  0x1A,  0x17,  0xE4,  0x28,  0x0A, 	/* 38A80 */
+	0x7F,  0xDF,  0x10,  0x04,  0x3B,  0xD6,  0x56,  0x65,  0x13,  0xC4,  0x00,  0x80,  0x7F,  0xFF,  0x02,  0xA0, 	/* 38A90 */
+	0x0C,  0x98,  0x70,  0x87,  0x00,  0x80,  0x96,  0x13,  0xE8,  0x12,  0x8F,  0x13,  0xD0,  0x7E,  0x6E,  0x13, 	/* 38AA0 */
+	0xDF,  0x12,  0x95,  0x3B,  0xFF,  0x35,  0x04,  0x31,  0xFC,  0x51,  0x04,  0x51,  0xFC,  0x11,  0x04,  0x11, 	/* 38AB0 */
+	0xFC,  0x10,  0x51,  0x11,  0x91,  0x16,  0x0F,  0x9D,  0x12,  0x48,  0x7D,  0xBF,  0x12,  0x4C,  0x39,  0x9A, 	/* 38AC0 */
+	0x56,  0x69,  0x3F,  0xFC,  0x24,  0x44,  0x3F,  0xFC,  0x1E,  0x08,  0x12,  0xFF,  0x1E,  0x08,  0x12,  0x88, 	/* 38AD0 */
+	0x1E,  0x48,  0x14,  0x08,  0x1A,  0x08,  0x61,  0x18,  0x9F,  0x11,  0x40,  0x11,  0x5E,  0x17,  0xF2,  0x79, 	/* 38AE0 */
+	0x52,  0x13,  0xFE,  0x1A,  0xB2,  0x37,  0xFE,  0x31,  0x52,  0x53,  0xF2,  0x56,  0x9E,  0x13,  0xCC,  0x12, 	/* 38AF0 */
+	0x8C,  0x13,  0xD4,  0x12,  0x95,  0x13,  0xE5,  0x10,  0x43,  0xA0,  0x04,  0x00,  0x04,  0x00,  0x04,  0x00, 	/* 38B00 */
+	0x08,  0x00,  0x0F,  0xFF,  0x10,  0x82,  0x10,  0x84,  0x20,  0x88,  0x40,  0x80,  0x01,  0x40,  0x01,  0x40, 	/* 38B10 */
+	0x02,  0x20,  0x02,  0x10,  0x04,  0x08,  0x18,  0x04,  0x60,  0x03,  0xA1,  0x01,  0x00,  0x01,  0x00,  0x21, 	/* 38B20 */
+	0x00,  0x21,  0x00,  0x11,  0xFF,  0x11,  0x21,  0x02,  0x22,  0x02,  0x24,  0x14,  0x20,  0x10,  0x20,  0x20, 	/* 38B30 */
+	0x50,  0x20,  0x50,  0x40,  0x88,  0x41,  0x04,  0x46,  0x02,  0x18,  0x01,  0xA3,  0x02,  0x20,  0x04,  0x20, 	/* 38B40 */
+	0x38,  0x20,  0x20,  0x3F,  0x20,  0x42,  0x3F,  0x54,  0x24,  0x90,  0x25,  0x10,  0x24,  0x10,  0x24,  0x18, 	/* 38B50 */
+	0x24,  0x28,  0x24,  0x28,  0x24,  0x24,  0x24,  0x44,  0x44,  0x82,  0x07,  0x01,  0xA7,  0x00,  0x20,  0x3F, 	/* 38B60 */
+	0xA0,  0x21,  0x20,  0x21,  0x3F,  0x31,  0x51,  0x2A,  0x52,  0x26,  0x94,  0x22,  0x10,  0x26,  0x10,  0x25, 	/* 38B70 */
+	0x30,  0x29,  0x28,  0x29,  0x28,  0x30,  0x44,  0x3F,  0xC4,  0x00,  0x82,  0x01,  0x01,  0xB2,  0x0A,  0x20, 	/* 38B80 */
+	0x0A,  0x20,  0x09,  0x20,  0x11,  0x3F,  0x15,  0x52,  0x24,  0x54,  0x0A,  0x98,  0x0A,  0x10,  0x11,  0x10, 	/* 38B90 */
+	0x20,  0x90,  0x5F,  0x28,  0x11,  0x28,  0x11,  0x24,  0x11,  0x44,  0x1F,  0x82,  0x01,  0x01,  0xB7,  0x01, 	/* 38BA0 */
+	0x20,  0x32,  0x20,  0x0C,  0x20,  0x1A,  0x3F,  0x65,  0x41,  0x04,  0x52,  0x7F,  0x94,  0x08,  0x10,  0x18, 	/* 38BB0 */
+	0x10,  0x3F,  0x10,  0x69,  0x28,  0x29,  0x28,  0x29,  0x24,  0x2A,  0x44,  0x08,  0x82,  0x09,  0x01,  0xB8, 	/* 38BC0 */
+	0x08,  0x20,  0x0A,  0x20,  0x09,  0x20,  0x12,  0xFF,  0x7C,  0x41,  0x08,  0x92,  0x0F,  0x94,  0x14,  0x10, 	/* 38BD0 */
+	0x24,  0x10,  0x7F,  0x90,  0x04,  0x28,  0x06,  0x28,  0x09,  0x24,  0x09,  0x44,  0x10,  0x82,  0x21,  0x01, 	/* 38BE0 */
+	0xB9,  0x04,  0x20,  0x04,  0x20,  0x3F,  0x20,  0x04,  0x3F,  0x0A,  0x41,  0x31,  0x52,  0x00,  0x94,  0x7F, 	/* 38BF0 */
+	0x90,  0x01,  0x10,  0x3D,  0x10,  0x25,  0x28,  0x25,  0x28,  0x3D,  0x24,  0x01,  0x44,  0x01,  0x42,  0x03, 	/* 38C00 */
+	0x81,  0xBA,  0x11,  0x20,  0x11,  0x20,  0x7F,  0xA0,  0x11,  0x3F,  0x11,  0x22,  0x1F,  0x54,  0x11,  0x50, 	/* 38C10 */
+	0x11,  0x90,  0x1F,  0x10,  0x11,  0x10,  0x11,  0x18,  0x7F,  0xA8,  0x12,  0x24,  0x11,  0x44,  0x20,  0x82, 	/* 38C20 */
+	0x43,  0x01,  0xBD,  0x08,  0x40,  0x08,  0x40,  0x14,  0x40,  0x12,  0x7F,  0x21,  0x42,  0x7E,  0x94,  0x08, 	/* 38C30 */
+	0x90,  0x09,  0x10,  0x7F,  0x10,  0x08,  0x18,  0x4A,  0x18,  0x2C,  0x28,  0x29,  0x24,  0x0E,  0x44,  0x18, 	/* 38C40 */
+	0x82,  0x63,  0x01,  0xBE,  0x08,  0x20,  0x08,  0x20,  0x7F,  0x20,  0x08,  0x3F,  0x08,  0x42,  0x3F,  0x54, 	/* 38C50 */
+	0x00,  0x90,  0x3F,  0x10,  0x00,  0x10,  0x7F,  0x90,  0x08,  0x28,  0x2A,  0x28,  0x29,  0x24,  0x49,  0x44, 	/* 38C60 */
+	0x08,  0x82,  0x19,  0x01,  0x83,  0x00,  0xA0,  0x03,  0x20,  0x3C,  0x20,  0x04,  0x7F,  0x04,  0x42,  0x7F, 	/* 38C70 */
+	0x54,  0x04,  0x90,  0x0C,  0x10,  0x35,  0x90,  0x24,  0x98,  0x24,  0x98,  0x35,  0xA8,  0x24,  0xA4,  0x24, 	/* 38C80 */
+	0xC4,  0x3F,  0xC2,  0x00,  0x81,  0x87,  0x00,  0x20,  0x3E,  0x20,  0x22,  0x20,  0x3E,  0x7F,  0x22,  0x42, 	/* 38C90 */
+	0x22,  0x54,  0x3E,  0x90,  0x08,  0x10,  0x1F,  0x10,  0x29,  0x18,  0x6D,  0x18,  0x2B,  0x28,  0x31,  0x24, 	/* 38CA0 */
+	0x3D,  0x44,  0x02,  0x42,  0x0C,  0x81,  0x89,  0x09,  0x10,  0x12,  0x10,  0x7F,  0xD0,  0x0A,  0x1F,  0x3F, 	/* 38CB0 */
+	0xA1,  0x0A,  0xAA,  0x7F,  0xCC,  0x0A,  0x88,  0x3F,  0x88,  0x0A,  0x08,  0x1B,  0x0C,  0x1A,  0x94,  0x2A, 	/* 38CC0 */
+	0x94,  0x4A,  0x22,  0x0A,  0x42,  0x0A,  0x81,  0x8C,  0x00,  0x40,  0x7F,  0xC0,  0x02,  0x40,  0x3A,  0x7F, 	/* 38CD0 */
+	0x2A,  0x52,  0x2A,  0x54,  0x3A,  0x90,  0x06,  0x90,  0x7F,  0x10,  0x02,  0x10,  0x3A,  0x28,  0x2A,  0x28, 	/* 38CE0 */
+	0x2A,  0x44,  0x3A,  0x44,  0x02,  0x82,  0x07,  0x01,  0x8E,  0x12,  0x20,  0x7F,  0xA0,  0x12,  0x20,  0x10, 	/* 38CF0 */
+	0x3F,  0x3F,  0x22,  0x29,  0x54,  0x29,  0x50,  0x3F,  0x90,  0x08,  0x10,  0x3F,  0x10,  0x08,  0x18,  0x7F, 	/* 38D00 */
+	0xA8,  0x0C,  0x24,  0x12,  0x44,  0x20,  0x82,  0x41,  0x01,  0x90,  0x00,  0x10,  0x3F,  0x90,  0x20,  0x10, 	/* 38D10 */
+	0x2F,  0x1F,  0x29,  0x21,  0x29,  0x2A,  0x2F,  0x48,  0x20,  0x08,  0x3D,  0xC8,  0x35,  0x48,  0x35,  0x54, 	/* 38D20 */
+	0x35,  0x54,  0x3D,  0xD4,  0x20,  0x22,  0x3F,  0xC2,  0x00,  0x81,  0x93,  0x10,  0x20,  0x10,  0x20,  0x1F, 	/* 38D30 */
+	0xA0,  0x24,  0x3F,  0x44,  0x21,  0x7F,  0xD2,  0x09,  0x54,  0x12,  0x90,  0x1F,  0x90,  0x32,  0x10,  0x5F, 	/* 38D40 */
+	0x28,  0x12,  0x28,  0x1F,  0x24,  0x12,  0x44,  0x1F,  0x82,  0x01,  0x01,  0x94,  0x04,  0x10,  0x07,  0x10, 	/* 38D50 */
+	0x04,  0x10,  0x3F,  0xBF,  0x25,  0x21,  0x3E,  0xAA,  0x24,  0xCC,  0x23,  0x88,  0x24,  0x08,  0x35,  0x48, 	/* 38D60 */
+	0x35,  0x4C,  0x3D,  0xD4,  0x25,  0x14,  0x25,  0xA2,  0x46,  0x42,  0x18,  0x81,  0x99,  0x04,  0x10,  0x0A, 	/* 38D70 */
+	0x10,  0x11,  0x10,  0x6E,  0xDF,  0x00,  0x11,  0x1F,  0x2A,  0x11,  0x2A,  0x1F,  0x48,  0x00,  0x08,  0x7F, 	/* 38D80 */
+	0x88,  0x19,  0x8C,  0x6E,  0x94,  0x19,  0x94,  0x6E,  0xA2,  0x08,  0xC2,  0x19,  0x81,  0x9B,  0x04,  0x10, 	/* 38D90 */
+	0x04,  0x10,  0x0A,  0x10,  0x09,  0x1F,  0x10,  0xA1,  0x3E,  0xAA,  0x40,  0x4C,  0x3B,  0x88,  0x2A,  0x88, 	/* 38DA0 */
+	0x2A,  0x88,  0x3B,  0x8C,  0x11,  0x14,  0x11,  0x94,  0x1A,  0x62,  0x26,  0x42,  0x44,  0x81,  0x9F,  0x14, 	/* 38DB0 */
+	0x10,  0x15,  0x90,  0x26,  0x90,  0x24,  0x9F,  0x35,  0xB1,  0x26,  0xAA,  0x2A,  0xEC,  0x3B,  0x88,  0x2A, 	/* 38DC0 */
+	0x88,  0x2A,  0x88,  0x2A,  0x94,  0x7F,  0xD4,  0x00,  0x14,  0x0A,  0x22,  0x11,  0x42,  0x60,  0x81,  0xA1, 	/* 38DD0 */
+	0x11,  0x10,  0x7F,  0xD0,  0x11,  0x10,  0x3B,  0x9F,  0x2A,  0xA1,  0x3B,  0xAA,  0x10,  0x4C,  0x12,  0x88, 	/* 38DE0 */
+	0x3F,  0x88,  0x64,  0x08,  0x3F,  0x8C,  0x24,  0x14,  0x3F,  0x94,  0x24,  0x22,  0x3F,  0xC2,  0x00,  0x81, 	/* 38DF0 */
+	0xA2,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x08,  0x80,  0x08,  0x80,  0x08,  0xFC,  0x08, 	/* 38E00 */
+	0x80,  0x08,  0x80,  0x08,  0x80,  0x08,  0x80,  0x08,  0x80,  0x08,  0x80,  0x08,  0x80,  0x7F,  0xFF,  0x00, 	/* 38E10 */
+	0x00,  0xA3,  0x00,  0x00,  0x3F,  0xFE,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x08,  0x80, 	/* 38E20 */
+	0x08,  0xFC,  0x08,  0x80,  0x08,  0x80,  0x08,  0x80,  0x08,  0x80,  0x08,  0x80,  0x08,  0x80,  0x7F,  0xFF, 	/* 38E30 */
+	0x00,  0x00,  0xA4,  0x04,  0x40,  0x04,  0x40,  0x04,  0x40,  0x24,  0x40,  0x24,  0x44,  0x24,  0x44,  0x27, 	/* 38E40 */
+	0xC8,  0x24,  0x50,  0x24,  0x60,  0x24,  0x40,  0x24,  0x40,  0x24,  0x42,  0x24,  0xC2,  0x27,  0x42,  0x3C, 	/* 38E50 */
+	0x3E,  0x60,  0x00,  0xA6,  0x00,  0x24,  0x1F,  0xA2,  0x00,  0x22,  0x00,  0x20,  0x7F,  0xFF,  0x02,  0x20, 	/* 38E60 */
+	0x02,  0x20,  0x12,  0x20,  0x13,  0xE0,  0x12,  0x10,  0x12,  0x10,  0x12,  0x10,  0x13,  0xCA,  0x1E,  0x0A, 	/* 38E70 */
+	0x70,  0x06,  0x00,  0x02,  0xA9,  0x00,  0x80,  0x08,  0x80,  0x08,  0xFC,  0x08,  0x80,  0x08,  0x80,  0x7F, 	/* 38E80 */
+	0xFF,  0x00,  0x80,  0x04,  0x90,  0x04,  0x88,  0x08,  0x84,  0x10,  0x8A,  0x21,  0x92,  0x00,  0x20,  0x00, 	/* 38E90 */
+	0xC0,  0x03,  0x00,  0x1C,  0x00,  0xAA,  0x00,  0x00,  0x7F,  0xFF,  0x00,  0x40,  0x00,  0x80,  0x03,  0xF0, 	/* 38EA0 */
+	0x0C,  0x8C,  0x70,  0x82,  0x00,  0x80,  0x1F,  0xFC,  0x00,  0x80,  0x08,  0x80,  0x08,  0xF8,  0x08,  0x80, 	/* 38EB0 */
+	0x08,  0x80,  0x7F,  0xFF,  0x00,  0x00,  0xAF,  0x00,  0x80,  0x08,  0x80,  0x08,  0xFC,  0x08,  0x80,  0x08, 	/* 38EC0 */
+	0x80,  0x7F,  0xFF,  0x14,  0x94,  0x12,  0xA4,  0x10,  0x84,  0x1F,  0xFC,  0x11,  0xC4,  0x12,  0xA4,  0x14, 	/* 38ED0 */
+	0x94,  0x10,  0x84,  0x1F,  0xFC,  0x00,  0x00,  0xB3,  0x00,  0x80,  0x08,  0x80,  0x08,  0xFE,  0x08,  0x80, 	/* 38EE0 */
+	0x7F,  0xFF,  0x00,  0x24,  0x00,  0x22,  0x1F,  0xFE,  0x10,  0x20,  0x17,  0xD2,  0x11,  0x14,  0x15,  0x88, 	/* 38EF0 */
+	0x15,  0x4D,  0x29,  0x15,  0x23,  0x23,  0x40,  0xC1,  0xB4,  0x00,  0x00,  0x1F,  0xFF,  0x11,  0x08,  0x11, 	/* 38F00 */
+	0x08,  0x1F,  0xFF,  0x13,  0x8C,  0x15,  0x5A,  0x19,  0x29,  0x11,  0x08,  0x11,  0x48,  0x12,  0x40,  0x12, 	/* 38F10 */
+	0x7E,  0x22,  0x40,  0x22,  0x40,  0x5F,  0xFF,  0x00,  0x00,  0xB8,  0x04,  0x00,  0x08,  0x7C,  0x3E,  0x04, 	/* 38F20 */
+	0x22,  0xFF,  0x3E,  0x04,  0x20,  0x7C,  0x3E,  0x00,  0x22,  0xFF,  0x3E,  0x91,  0x08,  0x91,  0x28,  0x7E, 	/* 38F30 */
+	0x2E,  0x52,  0x28,  0x52,  0x2E,  0x5C,  0x38,  0x50,  0x60,  0x10,  0xB9,  0x00,  0x00,  0x7F,  0xFF,  0x01, 	/* 38F40 */
+	0x00,  0x01,  0x00,  0x01,  0x00,  0x01,  0xF8,  0x02,  0x08,  0x02,  0x08,  0x05,  0x90,  0x08,  0x50,  0x10, 	/* 38F50 */
+	0x20,  0x00,  0x20,  0x00,  0x40,  0x00,  0x80,  0x03,  0x00,  0x0C,  0x00,  0xBB,  0x00,  0x00,  0x7F,  0xFF, 	/* 38F60 */
+	0x08,  0x40,  0x08,  0x40,  0x0F,  0x44,  0x09,  0x44,  0x11,  0x48,  0x11,  0x50,  0x2A,  0x60,  0x46,  0x40, 	/* 38F70 */
+	0x04,  0x40,  0x04,  0x40,  0x08,  0x42,  0x10,  0x42,  0x20,  0x3E,  0x40,  0x00,  0xBF,  0x00,  0x20,  0x7F, 	/* 38F80 */
+	0x20,  0x10,  0x3E,  0x10,  0x22,  0x10,  0x42,  0x1E,  0x42,  0x12,  0x8C,  0x22,  0x00,  0x33,  0xFC,  0x4C, 	/* 38F90 */
+	0x44,  0x04,  0x44,  0x08,  0x28,  0x08,  0x10,  0x10,  0x28,  0x20,  0xC4,  0x43,  0x03,  0x80,  0x00,  0x04, 	/* 38FA0 */
+	0x7F,  0x18,  0x10,  0xF0,  0x10,  0x10,  0x10,  0x10,  0x1E,  0x10,  0x13,  0xFF,  0x22,  0x10,  0x32,  0x10, 	/* 38FB0 */
+	0x4C,  0x28,  0x04,  0x28,  0x08,  0x28,  0x08,  0x44,  0x10,  0x44,  0x20,  0x82,  0x41,  0x01,  0x83,  0x00, 	/* 38FC0 */
+	0x10,  0x7F,  0x10,  0x10,  0x10,  0x10,  0xFE,  0x10,  0x92,  0x1E,  0x92,  0x12,  0x92,  0x22,  0x92,  0x33, 	/* 38FD0 */
+	0xFF,  0x4C,  0x10,  0x04,  0x18,  0x08,  0x28,  0x08,  0x24,  0x10,  0x44,  0x21,  0x82,  0x46,  0x01,  0x84, 	/* 38FE0 */
+	0x00,  0x10,  0x7F,  0x10,  0x10,  0x28,  0x10,  0x28,  0x10,  0x44,  0x1E,  0x8A,  0x13,  0x11,  0x22,  0x20, 	/* 38FF0 */
+	0x32,  0xC4,  0x4C,  0x08,  0x04,  0x31,  0x09,  0xC2,  0x08,  0x04,  0x10,  0x18,  0x20,  0x60,  0x41,  0x80, 	/* 39000 */
+	0x86,  0x00,  0x20,  0x7F,  0x20,  0x10,  0x20,  0x10,  0x48,  0x1E,  0x44,  0x12,  0x44,  0x12,  0x9E,  0x33, 	/* 39010 */
+	0xE2,  0x2A,  0x02,  0x44,  0xFC,  0x04,  0x84,  0x08,  0x84,  0x08,  0x84,  0x10,  0x84,  0x20,  0xFC,  0x40, 	/* 39020 */
+	0x00,  0x89,  0x00,  0x40,  0x7F,  0x40,  0x10,  0x7E,  0x10,  0x42,  0x10,  0x82,  0x1E,  0xF2,  0x13,  0x92, 	/* 39030 */
+	0x22,  0x92,  0x32,  0xF2,  0x4C,  0x92,  0x04,  0x92,  0x08,  0xF2,  0x08,  0x02,  0x10,  0x02,  0x20,  0x04, 	/* 39040 */
+	0x40,  0x18,  0x8A,  0x00,  0x10,  0x7F,  0x50,  0x10,  0x50,  0x10,  0x7E,  0x1E,  0x90,  0x12,  0x90,  0x13, 	/* 39050 */
+	0x10,  0x33,  0xFF,  0x2A,  0x38,  0x44,  0x38,  0x04,  0x54,  0x04,  0x54,  0x08,  0x92,  0x09,  0x11,  0x10, 	/* 39060 */
+	0x10,  0x20,  0x10,  0x8B,  0x00,  0x20,  0x7F,  0x24,  0x10,  0x22,  0x10,  0x22,  0x11,  0xFF,  0x1E,  0x20, 	/* 39070 */
+	0x12,  0xFE,  0x22,  0x20,  0x32,  0x20,  0x4D,  0xFF,  0x04,  0x12,  0x08,  0x0C,  0x08,  0x19,  0x10,  0x25, 	/* 39080 */
+	0x20,  0xC3,  0x43,  0x01,  0x8D,  0x00,  0x02,  0x7F,  0x0C,  0x10,  0xF4,  0x10,  0xA2,  0x10,  0x91,  0x1F, 	/* 39090 */
+	0x11,  0x12,  0xFE,  0x22,  0x04,  0x32,  0x08,  0x4C,  0x10,  0x05,  0xFF,  0x08,  0x10,  0x08,  0x10,  0x10, 	/* 390A0 */
+	0x10,  0x20,  0x10,  0x40,  0x30,  0x95,  0x00,  0x20,  0x7F,  0x20,  0x11,  0xFE,  0x10,  0x84,  0x10,  0x44, 	/* 390B0 */
+	0x1E,  0x48,  0x12,  0x48,  0x23,  0xFF,  0x32,  0x00,  0x4C,  0x00,  0x04,  0xFC,  0x08,  0x84,  0x08,  0x84, 	/* 390C0 */
+	0x10,  0x84,  0x20,  0xFC,  0x40,  0x00,  0x96,  0x00,  0x08,  0x7F,  0x08,  0x08,  0xFF,  0x08,  0x08,  0x08, 	/* 390D0 */
+	0x3E,  0x1E,  0xA2,  0x12,  0xA2,  0x12,  0xBE,  0x2A,  0xA2,  0x44,  0xBE,  0x04,  0xA2,  0x08,  0xA2,  0x08, 	/* 390E0 */
+	0xBE,  0x10,  0x80,  0x20,  0xFF,  0x40,  0x00,  0x98,  0x00,  0x28,  0x7F,  0x24,  0x10,  0x3E,  0x11,  0xE0, 	/* 390F0 */
+	0x10,  0x14,  0x1E,  0x39,  0x13,  0xC7,  0x22,  0x21,  0x32,  0x28,  0x4C,  0x24,  0x04,  0x3E,  0x0B,  0xD0, 	/* 39100 */
+	0x08,  0x14,  0x10,  0x19,  0x20,  0x67,  0x43,  0x81,  0x9E,  0x00,  0x00,  0x7F,  0xFE,  0x10,  0x82,  0x10, 	/* 39110 */
+	0x82,  0x10,  0xFE,  0x1E,  0x00,  0x12,  0xFE,  0x22,  0x82,  0x32,  0xFE,  0x4C,  0x82,  0x04,  0xFE,  0x08, 	/* 39120 */
+	0x82,  0x08,  0xFE,  0x10,  0x24,  0x20,  0xC2,  0x43,  0x01,  0xA4,  0x00,  0x40,  0x7F,  0x7E,  0x10,  0x80, 	/* 39130 */
+	0x11,  0x7C,  0x10,  0x44,  0x1E,  0x7C,  0x12,  0x44,  0x22,  0x7C,  0x32,  0x00,  0x4D,  0xFF,  0x04,  0x40, 	/* 39140 */
+	0x08,  0xFE,  0x09,  0x4A,  0x10,  0x92,  0x21,  0x22,  0x40,  0x4C,  0xAA,  0x00,  0x10,  0x7F,  0xFF,  0x10, 	/* 39150 */
+	0x10,  0x10,  0xFE,  0x10,  0x00,  0x1E,  0xFF,  0x12,  0x81,  0x22,  0xFD,  0x32,  0x00,  0x4C,  0xFE,  0x04, 	/* 39160 */
+	0x82,  0x08,  0xFE,  0x08,  0x44,  0x10,  0x28,  0x21,  0xFF,  0x40,  0x00,  0xAB,  0x00,  0x00,  0x7F,  0xEF, 	/* 39170 */
+	0x11,  0x29,  0x11,  0xEF,  0x10,  0x00,  0x1E,  0xFE,  0x12,  0x92,  0x22,  0xFE,  0x32,  0x92,  0x4C,  0x92, 	/* 39180 */
+	0x04,  0xFE,  0x08,  0x10,  0x09,  0xFF,  0x10,  0x10,  0x20,  0x10,  0x40,  0x10,  0xAF,  0x00,  0x10,  0x7F, 	/* 39190 */
+	0xFF,  0x11,  0x01,  0x10,  0xFE,  0x10,  0x12,  0x1E,  0x54,  0x13,  0x98,  0x22,  0x7E,  0x32,  0xC2,  0x4D, 	/* 391A0 */
+	0x7E,  0x04,  0x42,  0x08,  0x7E,  0x08,  0x42,  0x10,  0x7E,  0x20,  0x26,  0x41,  0xC1,  0xB1,  0x00,  0x88, 	/* 391B0 */
+	0x7E,  0x8C,  0x13,  0xEA,  0x10,  0x8A,  0x10,  0x88,  0x1F,  0xFF,  0x15,  0x48,  0x27,  0x6A,  0x25,  0x4A, 	/* 391C0 */
+	0x5B,  0x6A,  0x09,  0x44,  0x0B,  0x6C,  0x11,  0x4D,  0x11,  0xF5,  0x27,  0x23,  0x40,  0x41,  0xB2,  0x01, 	/* 391D0 */
+	0x28,  0x7F,  0x2C,  0x11,  0xAA,  0x12,  0x5A,  0x12,  0x88,  0x1F,  0xFF,  0x15,  0x48,  0x27,  0x6A,  0x25, 	/* 391E0 */
+	0x4A,  0x5B,  0x6A,  0x09,  0x44,  0x0B,  0x6C,  0x11,  0x4D,  0x11,  0xF5,  0x27,  0x23,  0x40,  0x41,  0xB3, 	/* 391F0 */
+	0x00,  0x00,  0x07,  0xE0,  0x04,  0x20,  0x04,  0x22,  0x04,  0x22,  0x08,  0x22,  0x10,  0x1E,  0x20,  0x00, 	/* 39200 */
+	0x0F,  0xF0,  0x02,  0x10,  0x02,  0x20,  0x01,  0x40,  0x00,  0x80,  0x03,  0x60,  0x0C,  0x18,  0x70,  0x07, 	/* 39210 */
+	0xB4,  0x00,  0x00,  0x3F,  0xBC,  0x21,  0x24,  0x21,  0x24,  0x32,  0x25,  0x2A,  0x45,  0x26,  0x83,  0x22, 	/* 39220 */
+	0xFC,  0x26,  0x44,  0x25,  0x44,  0x29,  0x28,  0x29,  0x28,  0x30,  0x10,  0x3F,  0xA8,  0x00,  0xC4,  0x03, 	/* 39230 */
+	0x03,  0xB5,  0x02,  0x00,  0x04,  0xF8,  0x38,  0x88,  0x20,  0x88,  0x20,  0x8A,  0x3C,  0x8A,  0x21,  0x06, 	/* 39240 */
+	0x22,  0x00,  0x3D,  0xF8,  0x20,  0x88,  0x20,  0x88,  0x3E,  0x50,  0x60,  0x20,  0x20,  0x50,  0x21,  0x8C, 	/* 39250 */
+	0x26,  0x03,  0xB7,  0x02,  0x00,  0x1C,  0x3C,  0x10,  0x24,  0x1F,  0x24,  0x11,  0x25,  0x1F,  0x25,  0x11, 	/* 39260 */
+	0x43,  0x11,  0x80,  0x1F,  0x7C,  0x10,  0x24,  0x1F,  0x24,  0x21,  0x14,  0x21,  0x08,  0x41,  0x14,  0x02, 	/* 39270 */
+	0x62,  0x0D,  0x81,  0xBA,  0x02,  0x00,  0x22,  0xF8,  0x14,  0x88,  0x08,  0x88,  0x14,  0x8A,  0x62,  0x8A, 	/* 39280 */
+	0x09,  0x06,  0x0A,  0x00,  0x7F,  0xF8,  0x08,  0x48,  0x1C,  0x48,  0x1A,  0x28,  0x2A,  0x10,  0x48,  0x28, 	/* 39290 */
+	0x08,  0xC4,  0x0B,  0x03,  0xBB,  0x08,  0x00,  0x08,  0x3C,  0x7F,  0x24,  0x08,  0x24,  0x08,  0x25,  0x3E, 	/* 392A0 */
+	0x45,  0x00,  0x83,  0x7F,  0xFC,  0x40,  0x84,  0x5E,  0xA4,  0x12,  0x24,  0x12,  0x18,  0x12,  0x88,  0x13, 	/* 392B0 */
+	0x14,  0x22,  0x62,  0x41,  0x81,  0xBC,  0x08,  0x00,  0x08,  0x3C,  0x7F,  0xA4,  0x08,  0x24,  0x3F,  0x25, 	/* 392C0 */
+	0x00,  0x45,  0x7F,  0x83,  0x40,  0x80,  0x3F,  0x7E,  0x00,  0x22,  0x1E,  0x24,  0x12,  0x14,  0x12,  0x88, 	/* 392D0 */
+	0x13,  0x14,  0x22,  0x62,  0x41,  0x81,  0xBF,  0x00,  0x00,  0x3F,  0x3C,  0x21,  0x24,  0x21,  0x24,  0x3F, 	/* 392E0 */
+	0x25,  0x2A,  0x25,  0x2A,  0x23,  0x3F,  0x40,  0x2A,  0xFC,  0x2A,  0x24,  0x3F,  0x94,  0x20,  0x18,  0x2A, 	/* 392F0 */
+	0x08,  0x49,  0x14,  0x11,  0x22,  0x20,  0xC1,  0x80,  0x08,  0x00,  0x33,  0x3C,  0x21,  0x24,  0x21,  0x25, 	/* 39300 */
+	0x3B,  0x25,  0x21,  0x43,  0x21,  0x80,  0x3F,  0xFC,  0x04,  0x04,  0x04,  0x24,  0x3F,  0x24,  0x04,  0x18, 	/* 39310 */
+	0x04,  0x18,  0x07,  0x24,  0x1C,  0xC2,  0x63,  0x01,  0x85,  0x04,  0x00,  0x04,  0x3C,  0x3F,  0xA4,  0x11, 	/* 39320 */
+	0x24,  0x0A,  0x25,  0x7F,  0xA5,  0x08,  0x43,  0x14,  0x80,  0x25,  0x7C,  0x0B,  0x24,  0x13,  0x24,  0x26, 	/* 39330 */
+	0x94,  0x0A,  0x48,  0x12,  0x14,  0x22,  0x62,  0x0D,  0x81,  0x86,  0x00,  0x00,  0x3F,  0xBC,  0x20,  0x24, 	/* 39340 */
+	0x27,  0x24,  0x25,  0x25,  0x25,  0x45,  0x27,  0x83,  0x20,  0x00,  0x3D,  0xFE,  0x35,  0x52,  0x35,  0x52, 	/* 39350 */
+	0x35,  0x4C,  0x3D,  0xCC,  0x20,  0x14,  0x3F,  0xA2,  0x00,  0xC1,  0x8B,  0x00,  0x00,  0x0F,  0xF8,  0x08, 	/* 39360 */
+	0x88,  0x08,  0x88,  0x08,  0x88,  0x08,  0x88,  0x7F,  0xFF,  0x08,  0x88,  0x08,  0x88,  0x08,  0x88,  0x08, 	/* 39370 */
+	0x88,  0x08,  0x88,  0x1F,  0xFF,  0x10,  0x08,  0x00,  0x10,  0x00,  0x60,  0x8D,  0x00,  0x00,  0x07,  0xF8, 	/* 39380 */
+	0x04,  0x08,  0x05,  0x08,  0x04,  0x88,  0x04,  0x88,  0x04,  0x08,  0x7F,  0xFF,  0x09,  0x08,  0x08,  0x88, 	/* 39390 */
+	0x08,  0x48,  0x08,  0x48,  0x1F,  0xFE,  0x10,  0x10,  0x00,  0x10,  0x00,  0x60,  0x8E,  0x08,  0x00,  0x08, 	/* 393A0 */
+	0x00,  0x0F,  0xFE,  0x10,  0x00,  0x17,  0xF8,  0x24,  0x88,  0x44,  0x88,  0x04,  0x88,  0x7F,  0xFF,  0x08, 	/* 393B0 */
+	0x88,  0x08,  0x88,  0x08,  0x88,  0x1F,  0xFC,  0x10,  0x08,  0x00,  0x10,  0x00,  0x60,  0x92,  0x00,  0x80, 	/* 393C0 */
+	0x1F,  0xFC,  0x00,  0x80,  0x0F,  0xF8,  0x00,  0x80,  0x7F,  0xFF,  0x00,  0x00,  0x07,  0xF8,  0x04,  0x88, 	/* 393D0 */
+	0x04,  0x88,  0x7F,  0xFF,  0x08,  0x88,  0x08,  0x88,  0x1F,  0xFE,  0x10,  0x10,  0x00,  0x60,  0x93,  0x10, 	/* 393E0 */
+	0x10,  0x10,  0x10,  0x3F,  0xFF,  0x20,  0x28,  0x5F,  0x24,  0x11,  0x4E,  0x19,  0xF1,  0x15,  0x00,  0x7F, 	/* 393F0 */
+	0x54,  0x29,  0x54,  0x25,  0x54,  0x25,  0x54,  0x7F,  0x54,  0x42,  0x55,  0x02,  0x95,  0x0D,  0x03,  0x94, 	/* 39400 */
+	0x10,  0x40,  0x10,  0x40,  0x10,  0x40,  0x10,  0x44,  0x10,  0x44,  0x10,  0x48,  0x1F,  0x50,  0x10,  0x60, 	/* 39410 */
+	0x10,  0x40,  0x10,  0x40,  0x10,  0x40,  0x10,  0x40,  0x11,  0x40,  0x16,  0x41,  0x18,  0x21,  0x60,  0x1F, 	/* 39420 */
+	0x98,  0x00,  0x00,  0x1F,  0xF8,  0x11,  0x08,  0x11,  0x08,  0x1F,  0xF8,  0x11,  0x08,  0x11,  0x08,  0x1F, 	/* 39430 */
+	0xF8,  0x00,  0x00,  0x10,  0x44,  0x10,  0x48,  0x1F,  0x70,  0x10,  0x40,  0x10,  0x42,  0x1F,  0x42,  0x70, 	/* 39440 */
+	0x3E,  0x9B,  0x00,  0x10,  0x00,  0x60,  0x1F,  0x80,  0x01,  0x00,  0x01,  0x00,  0x01,  0x1C,  0x03,  0xE0, 	/* 39450 */
+	0x3D,  0x00,  0x01,  0x00,  0x01,  0x0F,  0x07,  0xF0,  0x79,  0x00,  0x01,  0x00,  0x01,  0x02,  0x00,  0x82, 	/* 39460 */
+	0x00,  0x7E,  0x9F,  0x00,  0x80,  0x02,  0x90,  0x04,  0x8C,  0x18,  0x82,  0x61,  0x91,  0x00,  0x60,  0x03, 	/* 39470 */
+	0x80,  0x7C,  0x18,  0x07,  0xE0,  0x00,  0x80,  0x00,  0xF8,  0x1F,  0x80,  0x00,  0xFE,  0x3F,  0x81,  0x00, 	/* 39480 */
+	0x81,  0x00,  0x7F,  0xAB,  0x01,  0x00,  0x7F,  0xFE,  0x00,  0x00,  0x0F,  0xF0,  0x08,  0x10,  0x0F,  0xF0, 	/* 39490 */
+	0x00,  0x00,  0x7F,  0xFE,  0x40,  0x22,  0x4F,  0xC2,  0x01,  0x00,  0x01,  0xF8,  0x3F,  0x00,  0x01,  0xFD, 	/* 394A0 */
+	0x7F,  0x01,  0x00,  0xFF,  0xAC,  0x02,  0x10,  0x0C,  0x14,  0x78,  0x12,  0x09,  0xFF,  0x08,  0x10,  0x0F, 	/* 394B0 */
+	0x92,  0x78,  0x52,  0x08,  0x5C,  0x08,  0x18,  0x0F,  0x34,  0x78,  0x52,  0x09,  0x91,  0x08,  0x10,  0x08, 	/* 394C0 */
+	0x31,  0x04,  0x01,  0x03,  0xFF,  0xAF,  0x02,  0x10,  0x0C,  0x52,  0x78,  0x52,  0x08,  0xAC,  0x08,  0x28, 	/* 394D0 */
+	0x0F,  0x44,  0x78,  0x82,  0x08,  0x10,  0x08,  0x52,  0x0F,  0x52,  0x78,  0xAC,  0x08,  0x28,  0x08,  0x44, 	/* 394E0 */
+	0x08,  0x83,  0x04,  0x01,  0x03,  0xFF,  0xB3,  0x00,  0x20,  0x0F,  0xC0,  0x02,  0x00,  0x03,  0xF0,  0x3E, 	/* 394F0 */
+	0x00,  0x03,  0xF4,  0x3E,  0x04,  0x01,  0xFC,  0x02,  0x08,  0x3C,  0x70,  0x0F,  0x1C,  0x78,  0x70,  0x0F, 	/* 39500 */
+	0x1E,  0x78,  0xF1,  0x08,  0x91,  0x07,  0x8F,  0x88,  0x04,  0x02,  0x7F,  0xC4,  0x2E,  0xB8,  0x2A,  0x90, 	/* 39510 */
+	0x2E,  0x90,  0x20,  0x9E,  0x3F,  0xF0,  0x00,  0x10,  0x1F,  0x10,  0x11,  0x1F,  0x1F,  0xF0,  0x11,  0x10, 	/* 39520 */
+	0x1F,  0x10,  0x00,  0x11,  0x7F,  0xD1,  0x00,  0x0F,  0x8F,  0x00,  0x08,  0x00,  0x70,  0x0F,  0xC0,  0x08, 	/* 39530 */
+	0x40,  0x08,  0x40,  0x08,  0x40,  0x08,  0x5E,  0x0F,  0xE0,  0x08,  0x40,  0x08,  0x20,  0x08,  0x20,  0x08, 	/* 39540 */
+	0x10,  0x08,  0x09,  0x0B,  0x85,  0x1C,  0x03,  0x60,  0x01,  0x91,  0x00,  0x00,  0x1F,  0xFC,  0x10,  0x04, 	/* 39550 */
+	0x10,  0x04,  0x10,  0x04,  0x1F,  0xFC,  0x10,  0x80,  0x10,  0x80,  0x1F,  0xFF,  0x10,  0x40,  0x10,  0x40, 	/* 39560 */
+	0x10,  0x20,  0x10,  0x20,  0x13,  0x12,  0x1C,  0x0A,  0x60,  0x06,  0x93,  0x08,  0x00,  0x08,  0xFE,  0x08, 	/* 39570 */
+	0x82,  0x3F,  0x82,  0x20,  0x82,  0x20,  0xFE,  0x20,  0x88,  0x20,  0x88,  0x20,  0xFF,  0x20,  0x88,  0x22, 	/* 39580 */
+	0x88,  0x22,  0x88,  0x1E,  0x85,  0x00,  0xB5,  0x00,  0xC3,  0x03,  0x01,  0x94,  0x08,  0x00,  0x08,  0x00, 	/* 39590 */
+	0x0F,  0xFE,  0x10,  0x00,  0x17,  0xF8,  0x20,  0x00,  0x40,  0x00,  0x1F,  0xF8,  0x00,  0x08,  0x00,  0x08, 	/* 395A0 */
+	0x00,  0x08,  0x00,  0x08,  0x00,  0x05,  0x00,  0x05,  0x00,  0x03,  0x00,  0x01,  0x97,  0x08,  0x00,  0x08, 	/* 395B0 */
+	0x00,  0x0F,  0xFE,  0x10,  0x00,  0x17,  0xF8,  0x20,  0x00,  0x40,  0x00,  0x1F,  0xF8,  0x00,  0x48,  0x0C, 	/* 395C0 */
+	0x48,  0x02,  0x88,  0x01,  0x88,  0x02,  0x45,  0x04,  0x25,  0x18,  0x03,  0x60,  0x01,  0x9B,  0x08,  0x00, 	/* 395D0 */
+	0x08,  0x00,  0x0F,  0xFE,  0x10,  0x00,  0x17,  0xF8,  0x20,  0x00,  0x5F,  0xF8,  0x03,  0xC8,  0x08,  0x48, 	/* 395E0 */
+	0x08,  0x28,  0x17,  0xD8,  0x22,  0x58,  0x42,  0x45,  0x04,  0x45,  0x08,  0x43,  0x11,  0x81,  0xA3,  0x08, 	/* 395F0 */
+	0x00,  0x08,  0x00,  0x0F,  0xFE,  0x10,  0x00,  0x1F,  0xF8,  0x20,  0x00,  0x5F,  0xF8,  0x02,  0x08,  0x12, 	/* 39600 */
+	0x48,  0x0A,  0x88,  0x7F,  0xF8,  0x07,  0x08,  0x0A,  0x85,  0x12,  0x45,  0x22,  0x23,  0x02,  0x01,  0xA4, 	/* 39610 */
+	0x08,  0x00,  0x08,  0x00,  0x0F,  0xFE,  0x10,  0x00,  0x17,  0xF8,  0x20,  0x00,  0x5F,  0xF8,  0x00,  0x08, 	/* 39620 */
+	0x3F,  0xE8,  0x22,  0x28,  0x3F,  0xE8,  0x22,  0x28,  0x25,  0x25,  0x28,  0xA5,  0x3F,  0xE3,  0x00,  0x01, 	/* 39630 */
+	0xB4,  0x00,  0x80,  0x00,  0x80,  0x00,  0x84,  0x00,  0x84,  0x00,  0x88,  0x7E,  0xD0,  0x02,  0xE0,  0x02, 	/* 39640 */
+	0xC0,  0x04,  0xA0,  0x04,  0xA0,  0x08,  0x90,  0x10,  0x88,  0x20,  0x84,  0x40,  0x83,  0x00,  0x80,  0x01, 	/* 39650 */
+	0x80,  0xB7,  0x00,  0x80,  0x00,  0x80,  0x10,  0x82,  0x08,  0x82,  0x04,  0x84,  0x00,  0xC8,  0x7E,  0xD0, 	/* 39660 */
+	0x02,  0xA0,  0x04,  0xA0,  0x04,  0x90,  0x08,  0x88,  0x10,  0x84,  0x20,  0x82,  0x40,  0x81,  0x00,  0x80, 	/* 39670 */
+	0x01,  0x80,  0xB8,  0x03,  0x00,  0x00,  0x80,  0x00,  0x40,  0x07,  0x80,  0x00,  0x84,  0x00,  0x84,  0x3E, 	/* 39680 */
+	0xC8,  0x02,  0xD0,  0x02,  0xA0,  0x04,  0xA0,  0x04,  0x90,  0x08,  0x88,  0x10,  0x84,  0x60,  0x83,  0x00, 	/* 39690 */
+	0x80,  0x01,  0x80,  0xBE,  0x10,  0x00,  0x09,  0xFC,  0x09,  0x04,  0x01,  0x04,  0x41,  0x04,  0x21,  0x04, 	/* 396A0 */
+	0x21,  0x04,  0x01,  0x04,  0x05,  0x18,  0x05,  0x00,  0x09,  0x00,  0x09,  0x00,  0x11,  0x01,  0x10,  0x81, 	/* 396B0 */
+	0x20,  0x7F,  0x20,  0x00,  0x80,  0x10,  0x00,  0x08,  0x00,  0x0B,  0xFF,  0x00,  0x10,  0x00,  0x10,  0x40, 	/* 396C0 */
+	0x10,  0x20,  0x10,  0x20,  0x10,  0x08,  0x10,  0x08,  0x10,  0x10,  0x10,  0x10,  0x10,  0x20,  0x10,  0x20, 	/* 396D0 */
+	0x10,  0x40,  0x10,  0x40,  0x30,  0x81,  0x10,  0x20,  0x08,  0x20,  0x08,  0x20,  0x00,  0x20,  0x00,  0x20, 	/* 396E0 */
+	0x40,  0x20,  0x27,  0xFF,  0x20,  0x20,  0x08,  0x20,  0x08,  0x20,  0x10,  0x20,  0x10,  0x20,  0x20,  0x20, 	/* 396F0 */
+	0x20,  0x20,  0x40,  0x20,  0x40,  0x20,  0x82,  0x00,  0x90,  0x00,  0x88,  0x00,  0x88,  0x7F,  0xFF,  0x00, 	/* 39700 */
+	0x80,  0x10,  0x84,  0x08,  0xC4,  0x04,  0xC4,  0x04,  0xA8,  0x00,  0xA8,  0x01,  0x90,  0x02,  0x88,  0x04, 	/* 39710 */
+	0x84,  0x18,  0x82,  0x60,  0x81,  0x01,  0x80,  0x8E,  0x10,  0x00,  0x09,  0xF8,  0x09,  0x08,  0x01,  0x08, 	/* 39720 */
+	0x41,  0x08,  0x21,  0x88,  0x21,  0x48,  0x05,  0x48,  0x05,  0x28,  0x09,  0x28,  0x09,  0x08,  0x11,  0x08, 	/* 39730 */
+	0x12,  0x08,  0x22,  0x09,  0x24,  0x09,  0x28,  0x07,  0x90,  0x10,  0x20,  0x08,  0x20,  0x08,  0x20,  0x00, 	/* 39740 */
+	0x3E,  0x40,  0x42,  0x20,  0x42,  0x20,  0x82,  0x01,  0x44,  0x0A,  0x24,  0x08,  0x18,  0x10,  0x08,  0x10, 	/* 39750 */
+	0x10,  0x20,  0x20,  0x20,  0x40,  0x41,  0x80,  0x46,  0x00,  0x95,  0x10,  0x20,  0x08,  0x20,  0x08,  0x20, 	/* 39760 */
+	0x00,  0x20,  0x02,  0x22,  0x42,  0x22,  0x22,  0x22,  0x22,  0x22,  0x0A,  0x22,  0x0A,  0x22,  0x12,  0x22, 	/* 39770 */
+	0x12,  0x22,  0x22,  0x22,  0x22,  0x22,  0x43,  0xFE,  0x40,  0x00,  0x97,  0x10,  0x00,  0x0B,  0xFE,  0x08, 	/* 39780 */
+	0x20,  0x00,  0x20,  0x00,  0x20,  0x40,  0x20,  0x20,  0x20,  0x27,  0xFF,  0x08,  0x20,  0x08,  0x20,  0x10, 	/* 39790 */
+	0x20,  0x10,  0x20,  0x20,  0x20,  0x20,  0x20,  0x40,  0x20,  0x40,  0x20,  0x9A,  0x10,  0x00,  0x0B,  0xFC, 	/* 397A0 */
+	0x08,  0x40,  0x00,  0x40,  0x00,  0x40,  0x4F,  0xFF,  0x20,  0x80,  0x20,  0x80,  0x08,  0x80,  0x09,  0xFC, 	/* 397B0 */
+	0x11,  0x04,  0x10,  0x04,  0x20,  0x04,  0x20,  0x04,  0x40,  0x08,  0x40,  0x30,  0x9D,  0x10,  0x40,  0x08, 	/* 397C0 */
+	0x40,  0x08,  0x40,  0x00,  0x40,  0x4F,  0xFF,  0x20,  0x88,  0x20,  0x88,  0x00,  0x88,  0x09,  0x08,  0x09, 	/* 397D0 */
+	0x10,  0x13,  0xD0,  0x12,  0x20,  0x20,  0x50,  0x20,  0x88,  0x43,  0x04,  0x4C,  0x02,  0x9E,  0x00,  0x00, 	/* 397E0 */
+	0x1F,  0xFC,  0x00,  0x80,  0x00,  0x80,  0x7F,  0xFF,  0x00,  0x00,  0x00,  0x80,  0x00,  0x84,  0x3E,  0xC4, 	/* 397F0 */
+	0x02,  0xC8,  0x04,  0xB0,  0x04,  0x90,  0x08,  0x8C,  0x10,  0x83,  0x60,  0x80,  0x01,  0x80,  0x9F,  0x10, 	/* 39800 */
+	0x00,  0x08,  0x00,  0x0B,  0xFC,  0x00,  0x20,  0x40,  0x20,  0x20,  0x20,  0x20,  0x20,  0x00,  0x20,  0x08, 	/* 39810 */
+	0x20,  0x08,  0x20,  0x10,  0x20,  0x10,  0x20,  0x20,  0x20,  0x2F,  0xFE,  0x40,  0x00,  0x40,  0x00,  0xA0, 	/* 39820 */
+	0x10,  0x10,  0x08,  0x90,  0x08,  0x90,  0x00,  0x92,  0x00,  0x9E,  0x40,  0xF2,  0x27,  0x92,  0x20,  0x92, 	/* 39830 */
+	0x08,  0x92,  0x08,  0x92,  0x10,  0x9C,  0x10,  0x90,  0x20,  0x80,  0x20,  0x81,  0x40,  0x41,  0x40,  0x3F, 	/* 39840 */
+	0xA2,  0x10,  0x20,  0x08,  0x20,  0x08,  0x20,  0x00,  0x20,  0x00,  0x20,  0x40,  0x20,  0x23,  0xFE,  0x20, 	/* 39850 */
+	0x20,  0x08,  0x20,  0x08,  0x20,  0x10,  0x20,  0x10,  0x20,  0x20,  0x20,  0x20,  0x20,  0x47,  0xFF,  0x40, 	/* 39860 */
+	0x00,  0xA8,  0x10,  0x00,  0x0B,  0xFC,  0x0A,  0x04,  0x02,  0x04,  0x02,  0x04,  0x42,  0x04,  0x22,  0x04, 	/* 39870 */
+	0x23,  0xFC,  0x0A,  0x04,  0x0A,  0x04,  0x12,  0x04,  0x12,  0x04,  0x22,  0x04,  0x22,  0x04,  0x43,  0xFC, 	/* 39880 */
+	0x40,  0x00,  0xAA,  0x10,  0x00,  0x0B,  0xFE,  0x08,  0x20,  0x00,  0x20,  0x00,  0x20,  0x40,  0x20,  0x20, 	/* 39890 */
+	0x20,  0x21,  0xFC,  0x08,  0x20,  0x08,  0x20,  0x10,  0x20,  0x10,  0x20,  0x20,  0x20,  0x20,  0x20,  0x47, 	/* 398A0 */
+	0xFF,  0x40,  0x00,  0xB0,  0x10,  0x40,  0x08,  0x40,  0x08,  0x40,  0x00,  0x40,  0x00,  0x40,  0x4F,  0xFF, 	/* 398B0 */
+	0x20,  0x60,  0x20,  0xA0,  0x08,  0xA0,  0x08,  0x90,  0x11,  0x10,  0x11,  0x88,  0x21,  0x48,  0x22,  0x44, 	/* 398C0 */
+	0x44,  0x02,  0x48,  0x01,  0xB2,  0x10,  0x00,  0x0B,  0xF8,  0x08,  0x88,  0x00,  0x88,  0x40,  0x90,  0x20, 	/* 398D0 */
+	0x9C,  0x20,  0x84,  0x00,  0xC4,  0x09,  0x48,  0x09,  0x28,  0x11,  0x30,  0x11,  0x10,  0x22,  0x28,  0x22, 	/* 398E0 */
+	0x44,  0x44,  0x82,  0x4B,  0x01,  0xB3,  0x10,  0x00,  0x09,  0xFE,  0x09,  0x00,  0x01,  0x00,  0x01,  0x00, 	/* 398F0 */
+	0x41,  0xFC,  0x21,  0x44,  0x21,  0x44,  0x09,  0x48,  0x09,  0x28,  0x11,  0x30,  0x12,  0x10,  0x22,  0x28, 	/* 39900 */
+	0x24,  0x44,  0x49,  0x82,  0x46,  0x01,  0xBA,  0x10,  0x40,  0x08,  0x40,  0x08,  0x40,  0x07,  0xFC,  0x40, 	/* 39910 */
+	0x44,  0x20,  0x44,  0x20,  0x44,  0x00,  0x44,  0x0F,  0xFF,  0x08,  0x40,  0x10,  0xA0,  0x10,  0xA0,  0x21, 	/* 39920 */
+	0x10,  0x22,  0x08,  0x44,  0x04,  0x48,  0x03,  0xBD,  0x11,  0x00,  0x09,  0x00,  0x09,  0xFE,  0x02,  0x00, 	/* 39930 */
+	0x02,  0xF8,  0x44,  0x00,  0x20,  0x00,  0x27,  0xF8,  0x00,  0x08,  0x08,  0x08,  0x10,  0x08,  0x10,  0x08, 	/* 39940 */
+	0x20,  0x05,  0x20,  0x05,  0x40,  0x03,  0x40,  0x01,  0xBE,  0x10,  0x78,  0x08,  0x08,  0x08,  0x88,  0x00, 	/* 39950 */
+	0x88,  0x00,  0x84,  0x41,  0x04,  0x22,  0x02,  0x25,  0xFD,  0x00,  0x24,  0x08,  0x24,  0x10,  0x24,  0x10, 	/* 39960 */
+	0x44,  0x20,  0x44,  0x20,  0x84,  0x41,  0x04,  0x42,  0x18,  0x81,  0x10,  0x80,  0x08,  0x40,  0x08,  0x20, 	/* 39970 */
+	0x00,  0x20,  0x40,  0x80,  0x20,  0x80,  0x20,  0x80,  0x00,  0x88,  0x0A,  0x84,  0x0A,  0x82,  0x12,  0x81, 	/* 39980 */
+	0x14,  0x81,  0x24,  0x84,  0x28,  0x84,  0x40,  0x44,  0x40,  0x3C,  0x82,  0x10,  0x04,  0x08,  0x18,  0x09, 	/* 39990 */
+	0xE0,  0x01,  0x00,  0x01,  0x00,  0x41,  0x00,  0x21,  0xFF,  0x21,  0x08,  0x09,  0x08,  0x09,  0x08,  0x11, 	/* 399A0 */
+	0x08,  0x11,  0x08,  0x22,  0x08,  0x22,  0x08,  0x44,  0x08,  0x40,  0x08,  0x83,  0x10,  0x04,  0x08,  0x18, 	/* 399B0 */
+	0x0B,  0xE0,  0x00,  0x20,  0x00,  0x20,  0x40,  0x20,  0x27,  0xFF,  0x20,  0x20,  0x08,  0x30,  0x08,  0x50, 	/* 399C0 */
+	0x10,  0x50,  0x10,  0x88,  0x20,  0x88,  0x21,  0x04,  0x42,  0x02,  0x44,  0x01,  0x88,  0x10,  0x40,  0x08, 	/* 399D0 */
+	0x40,  0x08,  0x40,  0x07,  0xFE,  0x04,  0x42,  0x44,  0x42,  0x24,  0x42,  0x20,  0x60,  0x08,  0x60,  0x08, 	/* 399E0 */
+	0xA0,  0x10,  0xA0,  0x11,  0x20,  0x21,  0x20,  0x22,  0x21,  0x44,  0x11,  0x48,  0x0F,  0x8C,  0x10,  0x40, 	/* 399F0 */
+	0x08,  0x44,  0x08,  0x58,  0x07,  0xE0,  0x00,  0x40,  0x42,  0x44,  0x22,  0x44,  0x22,  0x44,  0x0A,  0x44, 	/* 39A00 */
+	0x0A,  0x44,  0x13,  0xFC,  0x10,  0x40,  0x20,  0x40,  0x20,  0x42,  0x40,  0x22,  0x40,  0x1E,  0x8D,  0x10, 	/* 39A10 */
+	0x00,  0x0B,  0xFE,  0x08,  0x80,  0x00,  0x80,  0x00,  0x80,  0x40,  0xF8,  0x20,  0x88,  0x20,  0x88,  0x09, 	/* 39A20 */
+	0x08,  0x09,  0x08,  0x11,  0xF0,  0x10,  0x10,  0x20,  0x10,  0x20,  0x10,  0x4F,  0xFF,  0x40,  0x00,  0x90, 	/* 39A30 */
+	0x10,  0x20,  0x08,  0x20,  0x08,  0x20,  0x00,  0x20,  0x07,  0xFF,  0x40,  0x30,  0x20,  0x70,  0x20,  0x68, 	/* 39A40 */
+	0x08,  0xA8,  0x08,  0xA4,  0x11,  0x24,  0x12,  0x22,  0x24,  0x21,  0x20,  0x20,  0x40,  0x20,  0x40,  0x20, 	/* 39A50 */
+	0x92,  0x10,  0x80,  0x08,  0x80,  0x08,  0xFC,  0x00,  0x84,  0x01,  0x04,  0x41,  0x04,  0x22,  0x18,  0x20, 	/* 39A60 */
+	0x00,  0x0B,  0xF8,  0x08,  0x88,  0x10,  0x88,  0x10,  0x50,  0x20,  0x20,  0x20,  0x50,  0x41,  0x8C,  0x46, 	/* 39A70 */
+	0x03,  0x93,  0x00,  0x80,  0x00,  0x84,  0x3E,  0xC8,  0x02,  0xD0,  0x04,  0xA0,  0x08,  0x90,  0x10,  0x8C, 	/* 39A80 */
+	0x61,  0x83,  0x0F,  0xF8,  0x08,  0x08,  0x08,  0x08,  0x0F,  0xF8,  0x08,  0x08,  0x08,  0x08,  0x0F,  0xF8, 	/* 39A90 */
+	0x00,  0x00,  0x96,  0x10,  0x20,  0x08,  0x20,  0x08,  0x20,  0x03,  0xFE,  0x42,  0x22,  0x22,  0x22,  0x22, 	/* 39AA0 */
+	0x22,  0x02,  0x22,  0x0B,  0xFE,  0x08,  0x20,  0x10,  0x20,  0x10,  0x20,  0x20,  0x20,  0x20,  0x20,  0x40, 	/* 39AB0 */
+	0x20,  0x40,  0x20,  0x99,  0x10,  0x20,  0x08,  0x20,  0x08,  0x20,  0x01,  0x28,  0x41,  0x24,  0x21,  0x22, 	/* 39AC0 */
+	0x22,  0x22,  0x02,  0x21,  0x0C,  0x25,  0x08,  0x64,  0x10,  0x08,  0x10,  0x10,  0x20,  0x20,  0x20,  0x40, 	/* 39AD0 */
+	0x41,  0x80,  0x4E,  0x00,  0x9A,  0x10,  0x20,  0x08,  0x20,  0x08,  0x20,  0x00,  0x20,  0x01,  0x20,  0x41, 	/* 39AE0 */
+	0x20,  0x21,  0x3E,  0x21,  0x20,  0x09,  0x20,  0x09,  0x20,  0x11,  0x20,  0x11,  0x20,  0x21,  0x20,  0x21, 	/* 39AF0 */
+	0x20,  0x4F,  0xFF,  0x40,  0x00,  0x9B,  0x10,  0x40,  0x08,  0x40,  0x08,  0x40,  0x0F,  0xFF,  0x00,  0x40, 	/* 39B00 */
+	0x40,  0x40,  0x23,  0xFC,  0x22,  0x44,  0x0A,  0x44,  0x0A,  0x44,  0x12,  0x44,  0x12,  0x44,  0x22,  0x58, 	/* 39B10 */
+	0x20,  0x40,  0x40,  0x40,  0x40,  0x40,  0xA1,  0x10,  0x00,  0x09,  0xF0,  0x09,  0x10,  0x01,  0x12,  0x01, 	/* 39B20 */
+	0x12,  0x41,  0x12,  0x22,  0x0E,  0x24,  0x00,  0x03,  0xF8,  0x08,  0x88,  0x10,  0x90,  0x10,  0x50,  0x20, 	/* 39B30 */
+	0x20,  0x20,  0x50,  0x41,  0x8C,  0x46,  0x03,  0xA2,  0x10,  0x00,  0x09,  0xFC,  0x09,  0x04,  0x01,  0x04, 	/* 39B40 */
+	0x41,  0x04,  0x21,  0x04,  0x21,  0xFC,  0x01,  0x20,  0x09,  0x20,  0x09,  0x20,  0x11,  0x10,  0x12,  0x10, 	/* 39B50 */
+	0x22,  0x08,  0x24,  0x04,  0x48,  0x02,  0x50,  0x01,  0xAB,  0x10,  0x20,  0x08,  0x20,  0x08,  0x20,  0x07, 	/* 39B60 */
+	0xFF,  0x00,  0x20,  0x40,  0x20,  0x20,  0x20,  0x23,  0xFE,  0x08,  0x70,  0x08,  0x70,  0x10,  0xA8,  0x10, 	/* 39B70 */
+	0xA8,  0x21,  0x24,  0x22,  0x22,  0x44,  0x21,  0x40,  0x20,  0xAE,  0x10,  0x00,  0x08,  0xFC,  0x08,  0x84, 	/* 39B80 */
+	0x00,  0x84,  0x00,  0x84,  0x40,  0xFC,  0x20,  0x84,  0x20,  0x84,  0x08,  0x84,  0x08,  0xFC,  0x10,  0x84, 	/* 39B90 */
+	0x10,  0x84,  0x20,  0x84,  0x20,  0x84,  0x47,  0xFF,  0x40,  0x00,  0xB1,  0x10,  0x20,  0x08,  0x20,  0x08, 	/* 39BA0 */
+	0x20,  0x07,  0xFF,  0x04,  0x01,  0x44,  0x01,  0x20,  0x80,  0x20,  0x84,  0x08,  0x98,  0x08,  0xE0,  0x10, 	/* 39BB0 */
+	0x80,  0x10,  0x80,  0x20,  0x82,  0x20,  0x82,  0x40,  0x42,  0x40,  0x3E,  0xB3,  0x10,  0x00,  0x0B,  0xFF, 	/* 39BC0 */
+	0x08,  0x04,  0x00,  0x04,  0x43,  0xE4,  0x22,  0x24,  0x22,  0x24,  0x02,  0x24,  0x0A,  0x24,  0x0B,  0xE4, 	/* 39BD0 */
+	0x10,  0x04,  0x10,  0x04,  0x20,  0x04,  0x20,  0x04,  0x40,  0x04,  0x40,  0x0C,  0xB8,  0x10,  0x90,  0x08, 	/* 39BE0 */
+	0x90,  0x0B,  0xFC,  0x00,  0x94,  0x40,  0x94,  0x23,  0xFC,  0x22,  0x90,  0x02,  0x90,  0x0B,  0xFE,  0x08, 	/* 39BF0 */
+	0x92,  0x10,  0x92,  0x10,  0x92,  0x21,  0x12,  0x21,  0x1C,  0x42,  0x10,  0x44,  0x10,  0xB9,  0x10,  0x20, 	/* 39C00 */
+	0x08,  0x20,  0x08,  0x20,  0x00,  0x20,  0x43,  0xFE,  0x22,  0x22,  0x22,  0x22,  0x02,  0x22,  0x0A,  0x22, 	/* 39C10 */
+	0x0B,  0xFE,  0x12,  0x22,  0x12,  0x22,  0x22,  0x22,  0x22,  0x22,  0x43,  0xFE,  0x40,  0x00,  0xBA,  0x10, 	/* 39C20 */
+	0x00,  0x0B,  0xFE,  0x0A,  0x22,  0x02,  0x22,  0x42,  0x22,  0x22,  0x22,  0x22,  0x22,  0x03,  0xFE,  0x0A, 	/* 39C30 */
+	0x22,  0x0A,  0x22,  0x12,  0x22,  0x12,  0x22,  0x22,  0x22,  0x22,  0x22,  0x43,  0xFE,  0x40,  0x00,  0xBB, 	/* 39C40 */
+	0x10,  0x40,  0x08,  0x40,  0x08,  0x40,  0x00,  0x90,  0x00,  0x88,  0x41,  0x04,  0x21,  0x3C,  0x27,  0xC2, 	/* 39C50 */
+	0x08,  0x02,  0x09,  0xFC,  0x11,  0x04,  0x11,  0x04,  0x21,  0x04,  0x21,  0x04,  0x41,  0xFC,  0x40,  0x00, 	/* 39C60 */
+	0xBC,  0x10,  0x00,  0x0B,  0xFE,  0x08,  0x22,  0x00,  0x22,  0x40,  0x42,  0x20,  0x42,  0x20,  0x82,  0x01, 	/* 39C70 */
+	0x0C,  0x0A,  0x00,  0x09,  0xFE,  0x11,  0x02,  0x11,  0x02,  0x21,  0x02,  0x21,  0x02,  0x41,  0xFE,  0x40, 	/* 39C80 */
+	0x00,  0xBD,  0x10,  0x20,  0x08,  0x20,  0x08,  0x20,  0x00,  0x20,  0x07,  0xFF,  0x40,  0x20,  0x20,  0x20, 	/* 39C90 */
+	0x20,  0x20,  0x08,  0x20,  0x09,  0xFC,  0x11,  0x04,  0x11,  0x04,  0x21,  0x04,  0x21,  0x04,  0x41,  0xFC, 	/* 39CA0 */
+	0x40,  0x00,  0xBE,  0x10,  0x20,  0x08,  0x20,  0x08,  0x20,  0x00,  0x20,  0x00,  0x3F,  0x40,  0x20,  0x20, 	/* 39CB0 */
+	0x20,  0x20,  0x20,  0x08,  0x20,  0x09,  0xFC,  0x11,  0x04,  0x11,  0x04,  0x21,  0x04,  0x21,  0x04,  0x41, 	/* 39CC0 */
+	0xFC,  0x40,  0x00,  0xBF,  0x10,  0x78,  0x08,  0x08,  0x08,  0x88,  0x00,  0x88,  0x40,  0x84,  0x21,  0x04, 	/* 39CD0 */
+	0x21,  0x02,  0x02,  0x01,  0x0D,  0xFC,  0x09,  0x04,  0x11,  0x04,  0x11,  0x04,  0x21,  0x04,  0x21,  0x04, 	/* 39CE0 */
+	0x41,  0xFC,  0x40,  0x00,  0x81,  0x10,  0x00,  0x0B,  0xFC,  0x0A,  0x04,  0x02,  0x04,  0x42,  0x04,  0x22, 	/* 39CF0 */
+	0x04,  0x23,  0xFC,  0x00,  0x90,  0x08,  0x90,  0x08,  0x90,  0x10,  0x90,  0x11,  0x10,  0x21,  0x10,  0x22, 	/* 39D00 */
+	0x11,  0x44,  0x11,  0x48,  0x0F,  0x84,  0x10,  0x00,  0x0A,  0x48,  0x0A,  0x48,  0x02,  0x48,  0x02,  0x48, 	/* 39D10 */
+	0x4F,  0xFF,  0x22,  0x48,  0x22,  0x48,  0x0A,  0x48,  0x0A,  0x48,  0x12,  0x78,  0x12,  0x00,  0x22,  0x00, 	/* 39D20 */
+	0x22,  0x00,  0x43,  0xFE,  0x40,  0x00,  0x85,  0x20,  0x00,  0x17,  0xFE,  0x14,  0x42,  0x04,  0x42,  0x04, 	/* 39D30 */
+	0x42,  0x44,  0x42,  0x24,  0x42,  0x24,  0x62,  0x0C,  0xA2,  0x0C,  0xA2,  0x14,  0x92,  0x15,  0x12,  0x26, 	/* 39D40 */
+	0x0A,  0x24,  0x02,  0x47,  0xFE,  0x40,  0x00,  0x89,  0x00,  0x40,  0x00,  0x80,  0x0F,  0xF8,  0x08,  0x08, 	/* 39D50 */
+	0x08,  0x08,  0x0F,  0xF8,  0x08,  0x08,  0x08,  0x08,  0x0F,  0xFA,  0x00,  0x82,  0x3E,  0xC4,  0x02,  0xA8, 	/* 39D60 */
+	0x04,  0x90,  0x18,  0x8C,  0x60,  0x83,  0x01,  0x80,  0x8A,  0x10,  0x40,  0x08,  0x40,  0x08,  0x80,  0x03, 	/* 39D70 */
+	0xFC,  0x02,  0x04,  0x42,  0x04,  0x22,  0x04,  0x22,  0x04,  0x0B,  0xFC,  0x0A,  0x04,  0x12,  0x04,  0x12, 	/* 39D80 */
+	0x04,  0x22,  0x04,  0x22,  0x04,  0x43,  0xFC,  0x40,  0x00,  0x8C,  0x10,  0x80,  0x08,  0x40,  0x08,  0x20, 	/* 39D90 */
+	0x00,  0xA4,  0x40,  0x84,  0x20,  0x84,  0x20,  0x88,  0x02,  0x8C,  0x0A,  0x92,  0x0A,  0x91,  0x14,  0xA1, 	/* 39DA0 */
+	0x14,  0xC0,  0x28,  0x82,  0x21,  0x42,  0x42,  0x3E,  0x4C,  0x00,  0x93,  0x10,  0x08,  0x0F,  0x88,  0x08, 	/* 39DB0 */
+	0x88,  0x00,  0x88,  0x00,  0x88,  0x47,  0x88,  0x24,  0x08,  0x24,  0x08,  0x0F,  0x90,  0x08,  0x90,  0x10, 	/* 39DC0 */
+	0x94,  0x10,  0x92,  0x20,  0x92,  0x20,  0xA6,  0x41,  0x79,  0x46,  0x01,  0x95,  0x10,  0x20,  0x08,  0x20, 	/* 39DD0 */
+	0x08,  0x20,  0x03,  0xFE,  0x40,  0x20,  0x20,  0x20,  0x20,  0x20,  0x07,  0xFF,  0x08,  0x40,  0x08,  0x40, 	/* 39DE0 */
+	0x10,  0x48,  0x10,  0x84,  0x20,  0x9C,  0x27,  0xE2,  0x40,  0x02,  0x40,  0x02,  0x97,  0x20,  0x00,  0x10, 	/* 39DF0 */
+	0x00,  0x17,  0xFE,  0x04,  0x92,  0x04,  0x92,  0x44,  0x92,  0x24,  0x92,  0x24,  0x96,  0x0D,  0x16,  0x0D, 	/* 39E00 */
+	0x0E,  0x16,  0x02,  0x14,  0x02,  0x24,  0x02,  0x24,  0x02,  0x47,  0xFE,  0x40,  0x00,  0x99,  0x10,  0x00, 	/* 39E10 */
+	0x0B,  0xFE,  0x08,  0x20,  0x01,  0x28,  0x01,  0x24,  0x41,  0x22,  0x22,  0x22,  0x20,  0x20,  0x07,  0xFF, 	/* 39E20 */
+	0x08,  0x20,  0x10,  0x20,  0x10,  0x20,  0x20,  0x20,  0x20,  0x20,  0x40,  0x20,  0x40,  0x20,  0x9B,  0x10, 	/* 39E30 */
+	0x02,  0x08,  0x0C,  0x0B,  0xF0,  0x00,  0x40,  0x00,  0x40,  0x40,  0x40,  0x27,  0xFC,  0x20,  0x04,  0x08, 	/* 39E40 */
+	0x08,  0x08,  0x08,  0x10,  0x10,  0x12,  0x20,  0x22,  0xC0,  0x23,  0x00,  0x44,  0xC0,  0x48,  0x3F,  0x9D, 	/* 39E50 */
+	0x10,  0x04,  0x08,  0x18,  0x09,  0xE0,  0x01,  0x00,  0x01,  0x00,  0x41,  0xFF,  0x21,  0x08,  0x21,  0x08, 	/* 39E60 */
+	0x09,  0x38,  0x09,  0x0C,  0x11,  0x0A,  0x11,  0x09,  0x22,  0x08,  0x22,  0x08,  0x44,  0x08,  0x40,  0x08, 	/* 39E70 */
+	0xA1,  0x11,  0x00,  0x09,  0x00,  0x09,  0xFE,  0x01,  0x02,  0x42,  0x02,  0x23,  0xF2,  0x22,  0x12,  0x04, 	/* 39E80 */
+	0x12,  0x00,  0x12,  0x0B,  0xF2,  0x12,  0x04,  0x12,  0x18,  0x22,  0x00,  0x22,  0x01,  0x41,  0x01,  0x40, 	/* 39E90 */
+	0xFF,  0xA2,  0x10,  0x20,  0x08,  0x20,  0x08,  0x20,  0x03,  0xFE,  0x42,  0x22,  0x22,  0x24,  0x22,  0x20, 	/* 39EA0 */
+	0x03,  0xFC,  0x0A,  0x04,  0x0A,  0x88,  0x12,  0x88,  0x12,  0x50,  0x22,  0x20,  0x24,  0x50,  0x44,  0x8C, 	/* 39EB0 */
+	0x4B,  0x03,  0xA3,  0x10,  0x20,  0x10,  0x20,  0x08,  0x20,  0x0B,  0xFE,  0x40,  0x08,  0x41,  0x08,  0x21, 	/* 39EC0 */
+	0x08,  0x20,  0x88,  0x00,  0x88,  0x08,  0x88,  0x10,  0x90,  0x10,  0x90,  0x20,  0x90,  0x20,  0x20,  0x47, 	/* 39ED0 */
+	0xFF,  0x40,  0x00,  0xA5,  0x10,  0x00,  0x09,  0xFE,  0x09,  0x02,  0x01,  0x02,  0x41,  0x02,  0x21,  0xFE, 	/* 39EE0 */
+	0x21,  0x00,  0x01,  0x40,  0x09,  0x44,  0x09,  0x48,  0x12,  0x70,  0x12,  0x40,  0x24,  0x40,  0x24,  0x42, 	/* 39EF0 */
+	0x48,  0x22,  0x40,  0x1E,  0xA8,  0x10,  0x40,  0x08,  0x20,  0x08,  0x20,  0x00,  0x00,  0x03,  0xFE,  0x40, 	/* 39F00 */
+	0x20,  0x20,  0x20,  0x20,  0x20,  0x08,  0x20,  0x09,  0xFC,  0x10,  0x20,  0x10,  0x20,  0x20,  0x20,  0x20, 	/* 39F10 */
+	0x20,  0x47,  0xFF,  0x40,  0x00,  0xAA,  0x10,  0x00,  0x09,  0xFC,  0x09,  0x04,  0x01,  0x04,  0x01,  0x04, 	/* 39F20 */
+	0x41,  0xFC,  0x21,  0x04,  0x21,  0x04,  0x09,  0x04,  0x09,  0xFC,  0x11,  0x04,  0x11,  0x04,  0x21,  0x04, 	/* 39F30 */
+	0x21,  0x04,  0x41,  0xFC,  0x40,  0x00,  0xAF,  0x10,  0x00,  0x0B,  0xFC,  0x0A,  0x04,  0x02,  0x04,  0x02, 	/* 39F40 */
+	0x04,  0x43,  0xFC,  0x22,  0x10,  0x22,  0x10,  0x0B,  0xFF,  0x0A,  0x10,  0x12,  0x10,  0x12,  0x08,  0x22, 	/* 39F50 */
+	0x09,  0x22,  0xC5,  0x43,  0x03,  0x4C,  0x01,  0xB0,  0x00,  0x80,  0x00,  0x80,  0x3F,  0xFE,  0x00,  0x80, 	/* 39F60 */
+	0x1F,  0xFC,  0x01,  0x40,  0x02,  0x20,  0x7F,  0xFF,  0x08,  0x90,  0x10,  0x8C,  0x6C,  0xCB,  0x03,  0xD0, 	/* 39F70 */
+	0x02,  0xA0,  0x0C,  0x90,  0x30,  0x8C,  0x01,  0x80,  0xB1,  0x10,  0x40,  0x08,  0x40,  0x08,  0x40,  0x03, 	/* 39F80 */
+	0xFC,  0x02,  0x44,  0x42,  0x44,  0x22,  0x44,  0x22,  0x44,  0x0F,  0xFF,  0x08,  0x40,  0x10,  0x60,  0x10, 	/* 39F90 */
+	0xA0,  0x20,  0x90,  0x21,  0x08,  0x42,  0x04,  0x4C,  0x03,  0xB3,  0x10,  0xC0,  0x08,  0x20,  0x08,  0x10, 	/* 39FA0 */
+	0x00,  0x00,  0x41,  0xE2,  0x20,  0x22,  0x20,  0x24,  0x07,  0xB4,  0x00,  0xB8,  0x00,  0xB0,  0x11,  0x28, 	/* 39FB0 */
+	0x11,  0x28,  0x22,  0x24,  0x24,  0x22,  0x48,  0x21,  0x40,  0x60,  0x8B,  0x11,  0x04,  0x08,  0x84,  0x08, 	/* 39FC0 */
+	0x88,  0x0B,  0xFE,  0x40,  0x20,  0x20,  0x20,  0x20,  0x20,  0x21,  0xFC,  0x08,  0x20,  0x08,  0x20,  0x10, 	/* 39FD0 */
+	0x20,  0x17,  0xFF,  0x20,  0x20,  0x20,  0x20,  0x40,  0x20,  0x40,  0x20,  0x8C,  0x20,  0x02,  0x17,  0xF2, 	/* 39FE0 */
+	0x11,  0x12,  0x01,  0x12,  0x01,  0x12,  0x43,  0xD2,  0x22,  0x52,  0x22,  0x52,  0x05,  0x52,  0x10,  0x92, 	/* 39FF0 */
+	0x10,  0x92,  0x21,  0x02,  0x21,  0x02,  0x22,  0x02,  0x44,  0x02,  0x48,  0x06,  0x92,  0x10,  0x00,  0x0F, 	/* 3A000 */
+	0xFF,  0x08,  0x50,  0x00,  0x50,  0x00,  0x50,  0x43,  0xFE,  0x22,  0x52,  0x2A,  0x52,  0x0A,  0x52,  0x0A, 	/* 3A010 */
+	0x96,  0x12,  0x8E,  0x13,  0x02,  0x22,  0x02,  0x22,  0x02,  0x43,  0xFE,  0x40,  0x00,  0x97,  0x10,  0x20, 	/* 3A020 */
+	0x09,  0x20,  0x09,  0x20,  0x01,  0xFE,  0x41,  0x20,  0x22,  0x20,  0x24,  0x20,  0x07,  0xFF,  0x00,  0x50, 	/* 3A030 */
+	0x08,  0x50,  0x10,  0x50,  0x10,  0x90,  0x20,  0x90,  0x21,  0x11,  0x42,  0x09,  0x44,  0x07,  0x99,  0x10, 	/* 3A040 */
+	0x20,  0x09,  0x20,  0x09,  0x20,  0x01,  0xFE,  0x01,  0x20,  0x42,  0x20,  0x24,  0x20,  0x27,  0xFF,  0x00, 	/* 3A050 */
+	0x70,  0x08,  0x70,  0x10,  0xA8,  0x11,  0x24,  0x22,  0x22,  0x24,  0x21,  0x40,  0x20,  0x40,  0x20,  0x9B, 	/* 3A060 */
+	0x10,  0x80,  0x08,  0x80,  0x08,  0xF8,  0x01,  0x08,  0x41,  0x88,  0x22,  0x50,  0x24,  0x20,  0x00,  0x50, 	/* 3A070 */
+	0x08,  0x88,  0x09,  0x04,  0x13,  0xFB,  0x15,  0x08,  0x21,  0x08,  0x21,  0x08,  0x41,  0xF8,  0x40,  0x00, 	/* 3A080 */
+	0x9E,  0x10,  0x00,  0x0B,  0xFE,  0x0A,  0x02,  0x02,  0x02,  0x43,  0xFE,  0x22,  0x02,  0x22,  0x02,  0x02, 	/* 3A090 */
+	0xFA,  0x0A,  0x8A,  0x0A,  0x8A,  0x12,  0x8A,  0x12,  0xFA,  0x22,  0x02,  0x22,  0x02,  0x42,  0x02,  0x42, 	/* 3A0A0 */
+	0x06,  0x9F,  0x10,  0x40,  0x08,  0x40,  0x0F,  0xFF,  0x00,  0x40,  0x07,  0xFC,  0x40,  0x44,  0x23,  0xFC, 	/* 3A0B0 */
+	0x22,  0x40,  0x0A,  0x40,  0x0B,  0xFE,  0x10,  0x42,  0x10,  0x62,  0x20,  0xAC,  0x21,  0x10,  0x42,  0x0C, 	/* 3A0C0 */
+	0x4C,  0x03,  0xA5,  0x10,  0x40,  0x08,  0x40,  0x0B,  0xFC,  0x00,  0x44,  0x00,  0x44,  0x4F,  0xFF,  0x20, 	/* 3A0D0 */
+	0x44,  0x23,  0xFC,  0x08,  0x40,  0x08,  0x40,  0x13,  0xFC,  0x10,  0x40,  0x20,  0x40,  0x2F,  0xFF,  0x40, 	/* 3A0E0 */
+	0x40,  0x40,  0x40,  0xA9,  0x10,  0x40,  0x08,  0x40,  0x0B,  0xFC,  0x0A,  0x44,  0x42,  0x44,  0x23,  0xFC, 	/* 3A0F0 */
+	0x22,  0x44,  0x22,  0x44,  0x0B,  0xFE,  0x08,  0x44,  0x10,  0x48,  0x10,  0x30,  0x20,  0x20,  0x20,  0xD1, 	/* 3A100 */
+	0x4F,  0x0D,  0x40,  0x03,  0xAA,  0x10,  0x88,  0x08,  0x88,  0x08,  0x88,  0x0B,  0xFE,  0x40,  0x88,  0x20, 	/* 3A110 */
+	0x88,  0x20,  0x88,  0x20,  0x88,  0x08,  0x88,  0x0F,  0xFF,  0x10,  0x00,  0x10,  0x90,  0x20,  0x88,  0x21, 	/* 3A120 */
+	0x08,  0x42,  0x04,  0x44,  0x04,  0xAB,  0x10,  0x40,  0x08,  0x40,  0x08,  0x80,  0x03,  0xFC,  0x02,  0xA4, 	/* 3A130 */
+	0x42,  0xA4,  0x22,  0xA4,  0x22,  0xA4,  0x0A,  0xA4,  0x0A,  0xA4,  0x12,  0xA4,  0x12,  0xA4,  0x22,  0xA4, 	/* 3A140 */
+	0x2F,  0xFF,  0x40,  0x00,  0x40,  0x00,  0xB2,  0x11,  0x02,  0x09,  0x22,  0x09,  0x22,  0x01,  0x22,  0x41, 	/* 3A150 */
+	0x22,  0x25,  0xB2,  0x25,  0x6A,  0x05,  0x6A,  0x09,  0x22,  0x01,  0x22,  0x11,  0x22,  0x11,  0x22,  0x22, 	/* 3A160 */
+	0x22,  0x22,  0x22,  0x44,  0x02,  0x48,  0x02,  0xB3,  0x21,  0x00,  0x11,  0x00,  0x11,  0x1E,  0x01,  0x12, 	/* 3A170 */
+	0x0F,  0xD2,  0x42,  0x52,  0x22,  0x52,  0x22,  0x52,  0x04,  0x52,  0x14,  0x92,  0x1F,  0x92,  0x20,  0xD2, 	/* 3A180 */
+	0x21,  0x52,  0x22,  0x1E,  0x4C,  0x00,  0x40,  0x00,  0xB5,  0x11,  0x00,  0x09,  0x00,  0x09,  0xFE,  0x01, 	/* 3A190 */
+	0x02,  0x02,  0x02,  0x43,  0xF2,  0x25,  0x12,  0x21,  0x12,  0x09,  0xF2,  0x09,  0x12,  0x11,  0x12,  0x11, 	/* 3A1A0 */
+	0x12,  0x21,  0xF2,  0x20,  0x02,  0x40,  0x04,  0x40,  0x18,  0xB6,  0x11,  0x00,  0x09,  0x00,  0x09,  0xFE, 	/* 3A1B0 */
+	0x01,  0x02,  0x02,  0x02,  0x42,  0x22,  0x24,  0x2A,  0x23,  0xAA,  0x0A,  0x4A,  0x0A,  0x6A,  0x12,  0x9A, 	/* 3A1C0 */
+	0x13,  0x0A,  0x23,  0xFA,  0x20,  0x02,  0x40,  0x04,  0x40,  0x18,  0xB8,  0x10,  0x20,  0x08,  0x24,  0x0A, 	/* 3A1D0 */
+	0x24,  0x01,  0x24,  0x01,  0x28,  0x41,  0x20,  0x20,  0x20,  0x27,  0xFF,  0x08,  0x90,  0x08,  0x90,  0x10, 	/* 3A1E0 */
+	0x90,  0x10,  0x90,  0x20,  0x90,  0x21,  0x11,  0x42,  0x11,  0x4C,  0x0F,  0xBB,  0x10,  0x04,  0x08,  0x18, 	/* 3A1F0 */
+	0x09,  0xE0,  0x00,  0x20,  0x00,  0x20,  0x40,  0x20,  0x27,  0xFF,  0x20,  0x20,  0x08,  0x20,  0x08,  0x20, 	/* 3A200 */
+	0x11,  0xFC,  0x11,  0x04,  0x21,  0x04,  0x21,  0x04,  0x41,  0xFC,  0x40,  0x00,  0xBD,  0x10,  0x20,  0x08, 	/* 3A210 */
+	0x20,  0x08,  0x50,  0x00,  0x50,  0x00,  0x88,  0x41,  0x04,  0x22,  0xFA,  0x24,  0x01,  0x00,  0x00,  0x09, 	/* 3A220 */
+	0xFC,  0x11,  0x04,  0x11,  0x04,  0x21,  0x04,  0x21,  0x04,  0x41,  0xFC,  0x40,  0x00,  0xBE,  0x10,  0x08, 	/* 3A230 */
+	0x08,  0x30,  0x0B,  0xC0,  0x02,  0x04,  0x42,  0x18,  0x22,  0x60,  0x22,  0x44,  0x02,  0x44,  0x0A,  0x68, 	/* 3A240 */
+	0x0A,  0x60,  0x12,  0x50,  0x12,  0x50,  0x24,  0x48,  0x24,  0x44,  0x48,  0x42,  0x40,  0x40,  0x81,  0x10, 	/* 3A250 */
+	0x20,  0x08,  0x20,  0x0F,  0xFF,  0x00,  0x50,  0x00,  0x48,  0x40,  0x84,  0x23,  0xFA,  0x20,  0x02,  0x09, 	/* 3A260 */
+	0x48,  0x09,  0x48,  0x11,  0x48,  0x11,  0x48,  0x22,  0x48,  0x22,  0x49,  0x44,  0x09,  0x48,  0x07,  0x84, 	/* 3A270 */
+	0x10,  0x40,  0x08,  0x78,  0x08,  0x88,  0x01,  0x10,  0x40,  0x20,  0x23,  0xFC,  0x20,  0x24,  0x00,  0x24, 	/* 3A280 */
+	0x0F,  0xFF,  0x08,  0x24,  0x10,  0x24,  0x13,  0xFC,  0x20,  0x20,  0x20,  0x20,  0x40,  0x20,  0x40,  0x60, 	/* 3A290 */
+	0x85,  0x10,  0x48,  0x08,  0x44,  0x08,  0x7C,  0x03,  0xC0,  0x40,  0x40,  0x20,  0x7C,  0x23,  0xC0,  0x00, 	/* 3A2A0 */
+	0x20,  0x08,  0x3E,  0x0B,  0xE4,  0x10,  0x24,  0x10,  0x18,  0x20,  0x12,  0x20,  0x6A,  0x43,  0x86,  0x40, 	/* 3A2B0 */
+	0x02,  0x99,  0x22,  0x02,  0x12,  0x0C,  0x12,  0x30,  0x02,  0x20,  0x0F,  0xA0,  0x42,  0x3F,  0x22,  0x24, 	/* 3A2C0 */
+	0x22,  0x24,  0x13,  0xA4,  0x1E,  0x24,  0x12,  0x24,  0x22,  0x24,  0x22,  0x44,  0x22,  0x44,  0x42,  0x84, 	/* 3A2D0 */
+	0x46,  0x04,  0x9A,  0x10,  0x40,  0x08,  0x90,  0x09,  0x0C,  0x07,  0xFA,  0x00,  0x90,  0x40,  0x91,  0x21, 	/* 3A2E0 */
+	0x0F,  0x26,  0x40,  0x08,  0x78,  0x08,  0x88,  0x11,  0x88,  0x16,  0x50,  0x20,  0x20,  0x20,  0x50,  0x41, 	/* 3A2F0 */
+	0x8C,  0x46,  0x03,  0x9C,  0x10,  0x08,  0x10,  0x30,  0x09,  0xC0,  0x09,  0x00,  0x41,  0x00,  0x41,  0xFE, 	/* 3A300 */
+	0x21,  0x10,  0x21,  0x10,  0x09,  0x10,  0x09,  0x10,  0x0F,  0xFF,  0x10,  0x00,  0x11,  0x10,  0x21,  0x08, 	/* 3A310 */
+	0x22,  0x04,  0x44,  0x04,  0xA3,  0x20,  0x40,  0x10,  0x40,  0x17,  0xFE,  0x04,  0x02,  0x04,  0x02,  0x41, 	/* 3A320 */
+	0xF8,  0x20,  0x00,  0x20,  0x00,  0x0F,  0xFE,  0x08,  0x90,  0x10,  0x90,  0x10,  0x90,  0x21,  0x10,  0x21, 	/* 3A330 */
+	0x12,  0x42,  0x12,  0x44,  0x0E,  0xA4,  0x10,  0x40,  0x08,  0x40,  0x0F,  0xFE,  0x04,  0x02,  0x04,  0x42, 	/* 3A340 */
+	0x40,  0x40,  0x27,  0xFF,  0x20,  0x40,  0x00,  0x80,  0x10,  0xA0,  0x11,  0x20,  0x21,  0x48,  0x22,  0x44, 	/* 3A350 */
+	0x24,  0x9C,  0x4B,  0xE2,  0x40,  0x02,  0xA6,  0x10,  0x24,  0x08,  0x22,  0x0F,  0xFF,  0x00,  0x20,  0x40, 	/* 3A360 */
+	0x20,  0x23,  0xFE,  0x22,  0x22,  0x02,  0x22,  0x0B,  0xFE,  0x0A,  0x22,  0x12,  0x22,  0x13,  0xFE,  0x22, 	/* 3A370 */
+	0x22,  0x22,  0x22,  0x42,  0x22,  0x42,  0x26,  0xA9,  0x10,  0x20,  0x09,  0x20,  0x09,  0x20,  0x01,  0xFE, 	/* 3A380 */
+	0x02,  0x20,  0x42,  0x20,  0x24,  0x20,  0x27,  0xFF,  0x00,  0x00,  0x08,  0x00,  0x11,  0xFC,  0x11,  0x04, 	/* 3A390 */
+	0x21,  0x04,  0x21,  0x04,  0x41,  0xFC,  0x40,  0x00,  0xAA,  0x10,  0x20,  0x08,  0x20,  0x09,  0xFC,  0x01, 	/* 3A3A0 */
+	0x04,  0x41,  0x04,  0x21,  0xFC,  0x21,  0x04,  0x01,  0x04,  0x09,  0xFC,  0x09,  0x22,  0x11,  0x22,  0x11, 	/* 3A3B0 */
+	0x14,  0x21,  0x18,  0x21,  0x48,  0x41,  0x84,  0x46,  0x03,  0xAC,  0x10,  0x00,  0x0B,  0xFC,  0x0A,  0x24, 	/* 3A3C0 */
+	0x02,  0x24,  0x43,  0xFC,  0x22,  0x24,  0x22,  0x24,  0x02,  0x24,  0x0B,  0xFC,  0x08,  0x20,  0x10,  0x20, 	/* 3A3D0 */
+	0x17,  0xFE,  0x20,  0x20,  0x20,  0x20,  0x4F,  0xFF,  0x40,  0x00,  0xAE,  0x10,  0x08,  0x08,  0x30,  0x0F, 	/* 3A3E0 */
+	0xC4,  0x02,  0x44,  0x01,  0x28,  0x41,  0x28,  0x23,  0xFC,  0x20,  0x08,  0x08,  0x10,  0x08,  0x20,  0x17, 	/* 3A3F0 */
+	0xFF,  0x10,  0x20,  0x20,  0x20,  0x20,  0x20,  0x40,  0x20,  0x40,  0x60,  0xB4,  0x10,  0x88,  0x08,  0x84, 	/* 3A400 */
+	0x09,  0x04,  0x01,  0x22,  0x42,  0x22,  0x20,  0x50,  0x20,  0x50,  0x00,  0x88,  0x09,  0x04,  0x0B,  0xFE, 	/* 3A410 */
+	0x15,  0x05,  0x11,  0x04,  0x21,  0x04,  0x21,  0x04,  0x41,  0xFC,  0x40,  0x00,  0xB7,  0x10,  0x80,  0x08, 	/* 3A420 */
+	0x80,  0x08,  0xFE,  0x01,  0x00,  0x41,  0x00,  0x23,  0xFC,  0x24,  0xA4,  0x00,  0xA4,  0x0F,  0xFF,  0x09, 	/* 3A430 */
+	0x24,  0x11,  0x24,  0x11,  0x24,  0x23,  0xFF,  0x22,  0x04,  0x40,  0x08,  0x40,  0x30,  0xB8,  0x10,  0x00, 	/* 3A440 */
+	0x09,  0xF8,  0x08,  0x08,  0x01,  0xF8,  0x40,  0x08,  0x21,  0xF8,  0x20,  0x00,  0x07,  0xFE,  0x04,  0x02, 	/* 3A450 */
+	0x0F,  0xFA,  0x10,  0x88,  0x10,  0x50,  0x20,  0x20,  0x20,  0x50,  0x41,  0x8C,  0x46,  0x03,  0xB9,  0x10, 	/* 3A460 */
+	0x20,  0x08,  0x20,  0x0F,  0xFF,  0x00,  0x20,  0x01,  0x24,  0x41,  0x24,  0x21,  0x24,  0x21,  0xA6,  0x0A, 	/* 3A470 */
+	0x69,  0x0C,  0x31,  0x10,  0x50,  0x10,  0x48,  0x20,  0x88,  0x21,  0x04,  0x42,  0x02,  0x44,  0x01,  0x85, 	/* 3A480 */
+	0x10,  0x00,  0x09,  0xFC,  0x09,  0x04,  0x01,  0x04,  0x01,  0xFC,  0x41,  0x04,  0x21,  0x04,  0x21,  0xFC, 	/* 3A490 */
+	0x08,  0x20,  0x08,  0x20,  0x13,  0xFE,  0x10,  0x20,  0x20,  0x20,  0x20,  0x20,  0x47,  0xFF,  0x40,  0x00, 	/* 3A4A0 */
+	0x88,  0x10,  0x20,  0x0A,  0x22,  0x09,  0x22,  0x00,  0xA4,  0x40,  0xA8,  0x21,  0xFC,  0x21,  0x04,  0x01, 	/* 3A4B0 */
+	0x04,  0x09,  0xFC,  0x09,  0x04,  0x11,  0x04,  0x11,  0xFC,  0x21,  0x04,  0x21,  0x04,  0x41,  0x04,  0x41, 	/* 3A4C0 */
+	0x0C,  0x8C,  0x10,  0x00,  0x0B,  0xFC,  0x08,  0x08,  0x00,  0xD0,  0x40,  0x20,  0x23,  0xFE,  0x22,  0x22, 	/* 3A4D0 */
+	0x02,  0x22,  0x0B,  0xFE,  0x0A,  0x22,  0x12,  0x22,  0x13,  0xFE,  0x22,  0x22,  0x22,  0x22,  0x42,  0x22, 	/* 3A4E0 */
+	0x42,  0x26,  0x8E,  0x20,  0x02,  0x1F,  0x8C,  0x11,  0x78,  0x02,  0x08,  0x02,  0x08,  0x44,  0x48,  0x27, 	/* 3A4F0 */
+	0x4E,  0x21,  0x48,  0x05,  0x48,  0x15,  0x48,  0x15,  0x48,  0x12,  0x48,  0x22,  0x7F,  0x25,  0x00,  0x48, 	/* 3A500 */
+	0xC0,  0x50,  0x3F,  0x93,  0x10,  0x00,  0x0B,  0xFC,  0x0A,  0x04,  0x02,  0x04,  0x03,  0xFC,  0x40,  0x00, 	/* 3A510 */
+	0x23,  0xFC,  0x22,  0x04,  0x0A,  0x04,  0x0B,  0xFC,  0x12,  0x04,  0x12,  0x04,  0x23,  0xFC,  0x22,  0x04, 	/* 3A520 */
+	0x42,  0x04,  0x42,  0x0C,  0x95,  0x11,  0x04,  0x08,  0x88,  0x0B,  0xFE,  0x00,  0x22,  0x00,  0x22,  0x43, 	/* 3A530 */
+	0xFE,  0x22,  0x20,  0x22,  0x20,  0x0B,  0xFE,  0x08,  0x62,  0x10,  0x62,  0x10,  0xA2,  0x21,  0x22,  0x22, 	/* 3A540 */
+	0x2C,  0x44,  0x20,  0x40,  0x20,  0x99,  0x10,  0x00,  0x0B,  0xFF,  0x08,  0x00,  0x03,  0xFE,  0x42,  0x02, 	/* 3A550 */
+	0x22,  0x02,  0x23,  0xFE,  0x02,  0x20,  0x0A,  0x20,  0x0B,  0xFF,  0x12,  0x20,  0x12,  0x30,  0x24,  0x50, 	/* 3A560 */
+	0x24,  0x48,  0x48,  0x84,  0x43,  0x03,  0x9B,  0x10,  0x40,  0x08,  0x40,  0x0F,  0xFE,  0x00,  0x40,  0x03, 	/* 3A570 */
+	0xFC,  0x40,  0x40,  0x27,  0xFF,  0x20,  0x80,  0x08,  0x88,  0x0F,  0xFF,  0x11,  0x08,  0x11,  0x48,  0x22, 	/* 3A580 */
+	0x28,  0x24,  0x28,  0x48,  0x08,  0x40,  0x18,  0x9C,  0x10,  0x20,  0x08,  0x20,  0x0F,  0xFF,  0x00,  0x20, 	/* 3A590 */
+	0x40,  0x20,  0x23,  0xFE,  0x20,  0x00,  0x03,  0xFE,  0x0A,  0x02,  0x0A,  0x92,  0x10,  0x90,  0x10,  0x90, 	/* 3A5A0 */
+	0x20,  0x90,  0x21,  0x11,  0x42,  0x11,  0x44,  0x0F,  0xAF,  0x10,  0x00,  0x0B,  0xFE,  0x0A,  0x10,  0x02, 	/* 3A5B0 */
+	0x10,  0x42,  0xFE,  0x22,  0x10,  0x22,  0x10,  0x03,  0xFF,  0x0A,  0x10,  0x0A,  0x10,  0x12,  0xFE,  0x12, 	/* 3A5C0 */
+	0x10,  0x24,  0x10,  0x24,  0x10,  0x4B,  0xFF,  0x40,  0x00,  0xB2,  0x10,  0x20,  0x08,  0x20,  0x0F,  0xFF, 	/* 3A5D0 */
+	0x00,  0x90,  0x40,  0x90,  0x21,  0x1C,  0x21,  0x24,  0x03,  0x34,  0x0D,  0x6C,  0x09,  0x54,  0x11,  0x88, 	/* 3A5E0 */
+	0x11,  0x18,  0x21,  0x14,  0x21,  0x24,  0x41,  0x42,  0x41,  0x81,  0xB5,  0x10,  0x00,  0x0F,  0xFF,  0x08, 	/* 3A5F0 */
+	0x80,  0x00,  0x80,  0x00,  0xE0,  0x44,  0x26,  0x26,  0x2A,  0x25,  0x3A,  0x05,  0x72,  0x0C,  0xAA,  0x17, 	/* 3A600 */
+	0x2A,  0x14,  0x26,  0x24,  0xC2,  0x24,  0x02,  0x47,  0xFE,  0x40,  0x00,  0xB8,  0x10,  0x00,  0x0B,  0xFE, 	/* 3A610 */
+	0x0A,  0x02,  0x02,  0x22,  0x02,  0x22,  0x43,  0xFE,  0x22,  0x22,  0x22,  0x22,  0x0A,  0xFA,  0x0A,  0x8A, 	/* 3A620 */
+	0x12,  0x8A,  0x12,  0xFA,  0x22,  0x02,  0x22,  0x02,  0x43,  0xFE,  0x40,  0x00,  0xBC,  0x10,  0x20,  0x08, 	/* 3A630 */
+	0x20,  0x0F,  0xFF,  0x00,  0x00,  0x40,  0x00,  0x21,  0xFC,  0x21,  0x04,  0x01,  0x04,  0x09,  0x04,  0x09, 	/* 3A640 */
+	0xFC,  0x10,  0x20,  0x11,  0x28,  0x21,  0x24,  0x22,  0x22,  0x44,  0x22,  0x40,  0x60,  0x80,  0x10,  0x20, 	/* 3A650 */
+	0x08,  0x20,  0x0B,  0xFF,  0x02,  0x01,  0x42,  0x01,  0x21,  0xFE,  0x20,  0x20,  0x00,  0x20,  0x09,  0x20, 	/* 3A660 */
+	0x09,  0x3E,  0x11,  0x20,  0x11,  0x20,  0x22,  0xA0,  0x22,  0x60,  0x44,  0x30,  0x48,  0x0F,  0x85,  0x21, 	/* 3A670 */
+	0x02,  0x11,  0x0C,  0x11,  0x30,  0x0F,  0xE0,  0x01,  0x20,  0x41,  0x3F,  0x23,  0x24,  0x23,  0xA4,  0x05, 	/* 3A680 */
+	0x64,  0x15,  0x24,  0x19,  0x24,  0x21,  0x24,  0x21,  0x44,  0x21,  0x44,  0x41,  0x84,  0x41,  0x04,  0x86, 	/* 3A690 */
+	0x10,  0x04,  0x09,  0x98,  0x08,  0x60,  0x03,  0x98,  0x40,  0x44,  0x2F,  0xFF,  0x20,  0x80,  0x00,  0xFC, 	/* 3A6A0 */
+	0x09,  0x84,  0x0A,  0xFC,  0x14,  0x84,  0x10,  0xFC,  0x20,  0x84,  0x20,  0x84,  0x40,  0x84,  0x40,  0x8C, 	/* 3A6B0 */
+	0x87,  0x11,  0x08,  0x09,  0x08,  0x0F,  0xFE,  0x01,  0x08,  0x01,  0x08,  0x41,  0xF8,  0x21,  0x08,  0x21, 	/* 3A6C0 */
+	0x08,  0x09,  0xF8,  0x09,  0x08,  0x11,  0x08,  0x17,  0xFF,  0x20,  0x00,  0x20,  0x88,  0x43,  0x04,  0x4C, 	/* 3A6D0 */
+	0x02,  0x8B,  0x11,  0x08,  0x09,  0x08,  0x09,  0x08,  0x07,  0xFF,  0x41,  0x08,  0x21,  0x08,  0x23,  0x9C, 	/* 3A6E0 */
+	0x03,  0x5C,  0x05,  0x2A,  0x05,  0x2A,  0x19,  0x49,  0x11,  0x08,  0x21,  0x08,  0x21,  0x08,  0x41,  0x08, 	/* 3A6F0 */
+	0x41,  0x08,  0x8C,  0x10,  0x20,  0x08,  0xA8,  0x08,  0xA4,  0x01,  0x22,  0x02,  0x22,  0x40,  0x20,  0x23, 	/* 3A700 */
+	0xFE,  0x22,  0x02,  0x0A,  0x02,  0x0A,  0xFA,  0x12,  0x8A,  0x12,  0x8A,  0x22,  0xFA,  0x22,  0x02,  0x42, 	/* 3A710 */
+	0x02,  0x42,  0x06,  0x91,  0x11,  0x00,  0x09,  0x3E,  0x09,  0x02,  0x01,  0xE2,  0x41,  0x12,  0x21,  0x12, 	/* 3A720 */
+	0x21,  0x12,  0x0F,  0xF2,  0x01,  0x0A,  0x11,  0x0C,  0x15,  0x44,  0x25,  0x2C,  0x25,  0x2A,  0x29,  0x12, 	/* 3A730 */
+	0x51,  0x21,  0x43,  0x41,  0x92,  0x10,  0x20,  0x08,  0x20,  0x0B,  0xFF,  0x00,  0x20,  0x01,  0xFC,  0x40, 	/* 3A740 */
+	0x24,  0x27,  0xFF,  0x20,  0x24,  0x09,  0xFC,  0x08,  0x40,  0x13,  0xFF,  0x10,  0x48,  0x20,  0x88,  0x21, 	/* 3A750 */
+	0xF0,  0x40,  0x48,  0x47,  0x84,  0x95,  0x10,  0x20,  0x08,  0x20,  0x0B,  0xFE,  0x00,  0x20,  0x00,  0x20, 	/* 3A760 */
+	0x47,  0xFF,  0x20,  0x90,  0x20,  0x92,  0x09,  0x0E,  0x0A,  0x20,  0x10,  0x20,  0x11,  0xFC,  0x20,  0x20, 	/* 3A770 */
+	0x20,  0x20,  0x47,  0xFF,  0x40,  0x00,  0x98,  0x11,  0x00,  0x09,  0x00,  0x09,  0xFE,  0x02,  0x82,  0x02, 	/* 3A780 */
+	0x82,  0x45,  0xFA,  0x21,  0x42,  0x22,  0x42,  0x0B,  0xFE,  0x08,  0x42,  0x12,  0x4A,  0x12,  0x4A,  0x23, 	/* 3A790 */
+	0xFA,  0x20,  0x02,  0x40,  0x04,  0x40,  0x18,  0x99,  0x10,  0x20,  0x08,  0x20,  0x0B,  0xFE,  0x02,  0x02, 	/* 3A7A0 */
+	0x02,  0x02,  0x40,  0xF8,  0x20,  0x00,  0x20,  0x00,  0x0B,  0xFF,  0x08,  0x20,  0x10,  0xA8,  0x10,  0xA4, 	/* 3A7B0 */
+	0x21,  0x22,  0x22,  0x22,  0x44,  0x20,  0x40,  0x60,  0x9E,  0x22,  0x3C,  0x12,  0x04,  0x12,  0x24,  0x0F, 	/* 3A7C0 */
+	0xA4,  0x42,  0x24,  0x22,  0x24,  0x27,  0x42,  0x07,  0x52,  0x16,  0x91,  0x1A,  0x10,  0x2A,  0x18,  0x22, 	/* 3A7D0 */
+	0x24,  0x22,  0x24,  0x22,  0x4E,  0x42,  0xF2,  0x42,  0x02,  0xA1,  0x10,  0x40,  0x09,  0x44,  0x09,  0x44, 	/* 3A7E0 */
+	0x0A,  0x48,  0x44,  0xA0,  0x20,  0x90,  0x21,  0x08,  0x26,  0x46,  0x08,  0x40,  0x09,  0x44,  0x11,  0x44, 	/* 3A7F0 */
+	0x12,  0xA8,  0x24,  0xA0,  0x21,  0x10,  0x42,  0x0C,  0x4C,  0x03,  0xA4,  0x21,  0x08,  0x11,  0x08,  0x11, 	/* 3A800 */
+	0x08,  0x0F,  0xD4,  0x02,  0x14,  0x42,  0x22,  0x23,  0xA2,  0x22,  0xD1,  0x0A,  0x88,  0x0A,  0x88,  0x12, 	/* 3A810 */
+	0x80,  0x14,  0xA0,  0x24,  0x90,  0x24,  0x88,  0x48,  0x84,  0x43,  0x04,  0xA6,  0x10,  0x20,  0x08,  0x20, 	/* 3A820 */
+	0x08,  0x50,  0x00,  0x50,  0x00,  0x88,  0x41,  0x04,  0x26,  0xFB,  0x20,  0x20,  0x00,  0x20,  0x0F,  0xFF, 	/* 3A830 */
+	0x10,  0x20,  0x11,  0x24,  0x20,  0xA4,  0x20,  0xA8,  0x47,  0xFE,  0x40,  0x00,  0xA8,  0x10,  0x06,  0x08, 	/* 3A840 */
+	0x38,  0x0B,  0xC4,  0x01,  0x22,  0x01,  0x22,  0x42,  0x02,  0x25,  0xFC,  0x20,  0x24,  0x08,  0x24,  0x0F, 	/* 3A850 */
+	0xFF,  0x10,  0x24,  0x13,  0xFC,  0x20,  0x20,  0x20,  0x20,  0x40,  0x20,  0x40,  0x60,  0xAA,  0x10,  0x20, 	/* 3A860 */
+	0x08,  0x20,  0x08,  0x50,  0x00,  0x88,  0x01,  0x04,  0x46,  0xFB,  0x20,  0x00,  0x20,  0x00,  0x0B,  0xFE, 	/* 3A870 */
+	0x0A,  0x52,  0x12,  0x52,  0x13,  0xFE,  0x22,  0x52,  0x22,  0x52,  0x42,  0x52,  0x42,  0x06,  0xAB,  0x10, 	/* 3A880 */
+	0x04,  0x08,  0x18,  0x0B,  0xE2,  0x42,  0x42,  0x21,  0x24,  0x21,  0x28,  0x00,  0x0C,  0x01,  0xF0,  0x08, 	/* 3A890 */
+	0x20,  0x08,  0x20,  0x17,  0xFF,  0x10,  0x20,  0x20,  0x20,  0x20,  0x20,  0x43,  0xFE,  0x40,  0x00,  0xAC, 	/* 3A8A0 */
+	0x10,  0x20,  0x08,  0x20,  0x0B,  0xFE,  0x00,  0x84,  0x00,  0x84,  0x40,  0xC6,  0x21,  0x2A,  0x21,  0x11, 	/* 3A8B0 */
+	0x0A,  0x20,  0x08,  0x20,  0x17,  0xFF,  0x10,  0x20,  0x20,  0x20,  0x20,  0x20,  0x40,  0x20,  0x40,  0x20, 	/* 3A8C0 */
+	0xAE,  0x10,  0x44,  0x08,  0x44,  0x08,  0x88,  0x01,  0xFF,  0x03,  0x10,  0x45,  0x10,  0x21,  0x10,  0x21, 	/* 3A8D0 */
+	0xFE,  0x09,  0x10,  0x09,  0x10,  0x11,  0xFE,  0x11,  0x10,  0x21,  0x10,  0x21,  0x10,  0x41,  0xFF,  0x40, 	/* 3A8E0 */
+	0x00,  0xB1,  0x10,  0x00,  0x0B,  0xFF,  0x0A,  0x51,  0x02,  0x51,  0x40,  0x92,  0x20,  0x8E,  0x23,  0x20, 	/* 3A8F0 */
+	0x00,  0x20,  0x07,  0xFF,  0x08,  0x20,  0x08,  0x70,  0x10,  0xA8,  0x11,  0x24,  0x26,  0x23,  0x20,  0x20, 	/* 3A900 */
+	0x40,  0x20,  0xB3,  0x10,  0x20,  0x08,  0x20,  0x0F,  0xFE,  0x00,  0x00,  0x41,  0xF8,  0x21,  0x08,  0x21, 	/* 3A910 */
+	0xF8,  0x00,  0x00,  0x0B,  0xFC,  0x08,  0x10,  0x10,  0x20,  0x17,  0xFF,  0x20,  0x20,  0x20,  0x20,  0x40, 	/* 3A920 */
+	0x20,  0x40,  0x60,  0xB5,  0x12,  0x02,  0x0A,  0x52,  0x0A,  0x52,  0x02,  0x52,  0x43,  0xDE,  0x22,  0x02, 	/* 3A930 */
+	0x22,  0x02,  0x03,  0xFE,  0x0A,  0x02,  0x0A,  0x02,  0x13,  0xDE,  0x12,  0x52,  0x22,  0x52,  0x24,  0x52, 	/* 3A940 */
+	0x44,  0x52,  0x48,  0x52,  0xB7,  0x10,  0x00,  0x0B,  0xF8,  0x0A,  0x08,  0x02,  0x08,  0x03,  0xF8,  0x42, 	/* 3A950 */
+	0x08,  0x22,  0x08,  0x23,  0xF8,  0x0A,  0x20,  0x0A,  0x24,  0x12,  0x28,  0x13,  0xF0,  0x22,  0x20,  0x22, 	/* 3A960 */
+	0x22,  0x43,  0xA2,  0x4E,  0x1E,  0xB9,  0x10,  0x40,  0x08,  0x40,  0x0F,  0xFF,  0x00,  0xA0,  0x01,  0x50, 	/* 3A970 */
+	0x42,  0x48,  0x27,  0xFC,  0x2A,  0x4A,  0x02,  0x49,  0x13,  0xF8,  0x12,  0x48,  0x12,  0x48,  0x23,  0xF8, 	/* 3A980 */
+	0x20,  0x42,  0x40,  0x42,  0x40,  0x3E,  0xBA,  0x10,  0x50,  0x08,  0x48,  0x08,  0x7E,  0x07,  0xC4,  0x00, 	/* 3A990 */
+	0x28,  0x40,  0x30,  0x20,  0xCD,  0x27,  0x13,  0x08,  0x48,  0x08,  0x5E,  0x17,  0xE4,  0x10,  0x28,  0x20, 	/* 3A9A0 */
+	0x10,  0x20,  0x69,  0x43,  0x87,  0x40,  0x01,  0xBB,  0x10,  0x08,  0x08,  0x30,  0x0B,  0xC0,  0x00,  0x40, 	/* 3A9B0 */
+	0x40,  0x40,  0x2F,  0xFF,  0x20,  0xA0,  0x01,  0x10,  0x0A,  0x8C,  0x0C,  0x83,  0x10,  0xC8,  0x14,  0xA4, 	/* 3A9C0 */
+	0x24,  0x92,  0x24,  0x92,  0x48,  0x80,  0x41,  0x80,  0x85,  0x10,  0x20,  0x08,  0x20,  0x0B,  0xFE,  0x00, 	/* 3A9D0 */
+	0x20,  0x01,  0xFC,  0x40,  0x20,  0x27,  0xFF,  0x20,  0x00,  0x09,  0xFC,  0x09,  0x04,  0x11,  0xFC,  0x11, 	/* 3A9E0 */
+	0x04,  0x21,  0xFC,  0x21,  0x04,  0x41,  0x04,  0x41,  0x0C,  0x87,  0x10,  0x00,  0x09,  0xF8,  0x09,  0x08, 	/* 3A9F0 */
+	0x01,  0xF8,  0x41,  0x08,  0x21,  0x08,  0x21,  0xF8,  0x00,  0x40,  0x08,  0xFE,  0x09,  0x12,  0x13,  0x22, 	/* 3AA00 */
+	0x15,  0xC2,  0x21,  0x0A,  0x20,  0xFA,  0x40,  0x04,  0x40,  0x18,  0x88,  0x10,  0x20,  0x08,  0x20,  0x0F, 	/* 3AA10 */
+	0xFF,  0x01,  0x08,  0x40,  0x90,  0x20,  0x60,  0x20,  0xD0,  0x01,  0x0C,  0x0F,  0x0B,  0x09,  0xF8,  0x09, 	/* 3AA20 */
+	0x08,  0x11,  0xF8,  0x11,  0x08,  0x21,  0x08,  0x22,  0x08,  0x44,  0x08,  0x89,  0x10,  0x20,  0x09,  0x20, 	/* 3AA30 */
+	0x09,  0x3E,  0x01,  0x20,  0x41,  0x20,  0x27,  0xFF,  0x20,  0x28,  0x01,  0x24,  0x09,  0x24,  0x11,  0x22, 	/* 3AA40 */
+	0x12,  0x2A,  0x14,  0x68,  0x20,  0x10,  0x20,  0x20,  0x40,  0xC0,  0x47,  0x00,  0x8A,  0x12,  0x02,  0x0A, 	/* 3AA50 */
+	0x22,  0x0B,  0x2A,  0x02,  0xAA,  0x02,  0xB2,  0x42,  0x22,  0x23,  0xFE,  0x22,  0x22,  0x0A,  0x72,  0x0A, 	/* 3AA60 */
+	0x72,  0x12,  0xAA,  0x13,  0x26,  0x24,  0x22,  0x24,  0x22,  0x48,  0x22,  0x50,  0x02,  0x8B,  0x20,  0x20, 	/* 3AA70 */
+	0x10,  0x20,  0x11,  0x20,  0x01,  0x3E,  0x41,  0x20,  0x21,  0x20,  0x21,  0x20,  0x07,  0xFF,  0x08,  0x00, 	/* 3AA80 */
+	0x0A,  0x04,  0x11,  0x08,  0x10,  0x90,  0x20,  0x00,  0x20,  0x98,  0x43,  0x06,  0x4C,  0x01,  0x93,  0x10, 	/* 3AA90 */
+	0x04,  0x08,  0x18,  0x0B,  0xE2,  0x00,  0x42,  0x42,  0x24,  0x21,  0x28,  0x21,  0x00,  0x00,  0x20,  0x09, 	/* 3AAA0 */
+	0xFC,  0x08,  0x20,  0x10,  0x20,  0x17,  0xFF,  0x20,  0x50,  0x20,  0x88,  0x41,  0x04,  0x46,  0x03,  0x95, 	/* 3AAB0 */
+	0x20,  0x42,  0x14,  0x52,  0x12,  0x92,  0x02,  0x12,  0x0F,  0xF2,  0x41,  0x12,  0x21,  0x12,  0x2F,  0xF2, 	/* 3AAC0 */
+	0x01,  0x12,  0x11,  0x92,  0x11,  0x52,  0x22,  0x32,  0x22,  0x22,  0x24,  0x02,  0x48,  0x02,  0x40,  0x06, 	/* 3AAD0 */
+	0x99,  0x10,  0x40,  0x08,  0x78,  0x08,  0x90,  0x03,  0x20,  0x0F,  0xFE,  0x42,  0x52,  0x22,  0x52,  0x22, 	/* 3AAE0 */
+	0x56,  0x0A,  0x8E,  0x0B,  0x02,  0x12,  0x22,  0x17,  0xFF,  0x20,  0x50,  0x20,  0x88,  0x43,  0x04,  0x4C, 	/* 3AAF0 */
+	0x03,  0x9A,  0x10,  0x40,  0x08,  0x44,  0x0B,  0xFC,  0x00,  0x48,  0x00,  0x50,  0x47,  0xFF,  0x20,  0x20, 	/* 3AB00 */
+	0x20,  0x40,  0x09,  0xF8,  0x0B,  0x08,  0x15,  0x08,  0x11,  0xF8,  0x21,  0x08,  0x21,  0x08,  0x41,  0xF8, 	/* 3AB10 */
+	0x40,  0x00,  0x9B,  0x10,  0x14,  0x08,  0x12,  0x08,  0x12,  0x03,  0xFF,  0x42,  0x10,  0x23,  0xF2,  0x22, 	/* 3AB20 */
+	0x12,  0x03,  0xD2,  0x0B,  0x54,  0x0B,  0x5C,  0x13,  0x48,  0x13,  0xD8,  0x25,  0x25,  0x24,  0x45,  0x48, 	/* 3AB30 */
+	0x83,  0x51,  0x01,  0x9D,  0x10,  0xE0,  0x08,  0x20,  0x08,  0x50,  0x00,  0x88,  0x01,  0xF4,  0x46,  0x03, 	/* 3AB40 */
+	0x23,  0xCA,  0x22,  0x4A,  0x0B,  0x4A,  0x0A,  0xD4,  0x12,  0x54,  0x13,  0x54,  0x22,  0xCA,  0x22,  0x4A, 	/* 3AB50 */
+	0x42,  0x4A,  0x42,  0xCA,  0x9F,  0x10,  0x20,  0x08,  0x20,  0x0B,  0xFF,  0x00,  0x00,  0x01,  0xFC,  0x41, 	/* 3AB60 */
+	0x04,  0x21,  0xFC,  0x20,  0x00,  0x0B,  0xFF,  0x0A,  0x01,  0x13,  0xFD,  0x10,  0x20,  0x20,  0x20,  0x20, 	/* 3AB70 */
+	0x20,  0x40,  0x20,  0x40,  0x60,  0xA0,  0x00,  0x00,  0x19,  0xFE,  0x05,  0x00,  0x31,  0xFC,  0x09,  0x04, 	/* 3AB80 */
+	0x01,  0x04,  0x05,  0xFC,  0x19,  0x00,  0x61,  0xFE,  0x00,  0x80,  0x7F,  0xFF,  0x01,  0xC0,  0x02,  0xA0, 	/* 3AB90 */
+	0x0C,  0x98,  0x70,  0x87,  0x00,  0x80,  0xA1,  0x10,  0x20,  0x08,  0x20,  0x0B,  0xFF,  0x0A,  0x44,  0x42, 	/* 3ABA0 */
+	0x44,  0x23,  0xFF,  0x22,  0x44,  0x22,  0x7C,  0x0A,  0x00,  0x0B,  0xFC,  0x12,  0x44,  0x12,  0x48,  0x24, 	/* 3ABB0 */
+	0x28,  0x24,  0x30,  0x48,  0xCC,  0x53,  0x03,  0xA3,  0x10,  0x20,  0x08,  0x20,  0x0F,  0xFF,  0x00,  0x70, 	/* 3ABC0 */
+	0x00,  0xA8,  0x41,  0x24,  0x22,  0x22,  0x25,  0xFD,  0x09,  0x04,  0x09,  0xFC,  0x11,  0x04,  0x11,  0xFC, 	/* 3ABD0 */
+	0x21,  0x04,  0x21,  0x04,  0x47,  0xFF,  0x40,  0x00,  0xA4,  0x11,  0x08,  0x0F,  0xC8,  0x09,  0x08,  0x01, 	/* 3ABE0 */
+	0x08,  0x0F,  0xFE,  0x48,  0x2A,  0x28,  0x2A,  0x27,  0xCA,  0x08,  0x8A,  0x09,  0x0A,  0x11,  0xEA,  0x1F, 	/* 3ABF0 */
+	0x12,  0x21,  0x12,  0x21,  0x12,  0x41,  0x22,  0x43,  0x4C,  0xA5,  0x10,  0x00,  0x13,  0xFE,  0x0A,  0x02, 	/* 3AC00 */
+	0x4A,  0x02,  0x43,  0xFE,  0x22,  0x00,  0x23,  0xFE,  0x02,  0x28,  0x0A,  0x44,  0x0B,  0xFA,  0x12,  0x22, 	/* 3AC10 */
+	0x15,  0xFC,  0x24,  0x20,  0x28,  0x20,  0x57,  0xFF,  0x40,  0x00,  0xA6,  0x10,  0x00,  0x09,  0xF8,  0x09, 	/* 3AC20 */
+	0x08,  0x01,  0x08,  0x01,  0x78,  0x41,  0x48,  0x21,  0x48,  0x23,  0xFE,  0x0A,  0x02,  0x0A,  0xF2,  0x12, 	/* 3AC30 */
+	0x92,  0x12,  0x92,  0x22,  0xF2,  0x22,  0x02,  0x42,  0x02,  0x42,  0x06,  0xA9,  0x10,  0x00,  0x09,  0xFC, 	/* 3AC40 */
+	0x09,  0x04,  0x01,  0xFC,  0x41,  0x04,  0x21,  0x04,  0x21,  0xFC,  0x00,  0x00,  0x08,  0x00,  0x0B,  0xFE, 	/* 3AC50 */
+	0x12,  0x52,  0x12,  0x52,  0x22,  0x52,  0x22,  0x52,  0x4F,  0xFF,  0x40,  0x00,  0xAB,  0x11,  0x24,  0x09, 	/* 3AC60 */
+	0x24,  0x0F,  0xFF,  0x01,  0x24,  0x01,  0x24,  0x41,  0x3C,  0x21,  0x00,  0x21,  0xFE,  0x08,  0x20,  0x08, 	/* 3AC70 */
+	0x20,  0x17,  0xFF,  0x10,  0x70,  0x20,  0xA8,  0x23,  0x24,  0x4C,  0x23,  0x40,  0x20,  0xAC,  0x20,  0x02, 	/* 3AC80 */
+	0x17,  0xD2,  0x14,  0x52,  0x04,  0x52,  0x44,  0x52,  0x27,  0xD2,  0x24,  0x52,  0x04,  0x52,  0x17,  0xD2, 	/* 3AC90 */
+	0x14,  0x52,  0x14,  0x52,  0x27,  0xD2,  0x22,  0x92,  0x42,  0x42,  0x44,  0x42,  0x48,  0x06,  0xAD,  0x10, 	/* 3ACA0 */
+	0x00,  0x0B,  0xFE,  0x0A,  0x22,  0x03,  0xFE,  0x02,  0x22,  0x42,  0x22,  0x23,  0xFE,  0x20,  0x00,  0x09, 	/* 3ACB0 */
+	0xFC,  0x09,  0x04,  0x11,  0xFC,  0x11,  0x04,  0x21,  0xFC,  0x21,  0x04,  0x41,  0x04,  0x41,  0x0C,  0xAE, 	/* 3ACC0 */
+	0x10,  0x88,  0x08,  0x88,  0x0F,  0xFF,  0x00,  0x88,  0x00,  0x88,  0x40,  0x00,  0x27,  0xFF,  0x20,  0x04, 	/* 3ACD0 */
+	0x09,  0xE4,  0x09,  0x24,  0x11,  0x24,  0x11,  0x24,  0x21,  0xE4,  0x20,  0x04,  0x40,  0x04,  0x40,  0x0C, 	/* 3ACE0 */
+	0xAF,  0x10,  0x88,  0x08,  0x88,  0x0B,  0xFE,  0x00,  0x88,  0x00,  0x88,  0x47,  0xFF,  0x20,  0x88,  0x21, 	/* 3ACF0 */
+	0x04,  0x09,  0xFC,  0x0A,  0x0A,  0x14,  0x09,  0x11,  0xF8,  0x21,  0x00,  0x21,  0x04,  0x41,  0x04,  0x40, 	/* 3AD00 */
+	0xFC,  0xB8,  0x21,  0x08,  0x11,  0x08,  0x11,  0x08,  0x0F,  0xEF,  0x01,  0x10,  0x41,  0x10,  0x21,  0x3E, 	/* 3AD10 */
+	0x21,  0xC2,  0x09,  0x44,  0x09,  0x44,  0x12,  0x7F,  0x12,  0x44,  0x22,  0x44,  0x24,  0x44,  0x48,  0x44, 	/* 3AD20 */
+	0x41,  0x8C,  0xBA,  0x20,  0x08,  0x17,  0x88,  0x14,  0x88,  0x04,  0xAA,  0x07,  0xAA,  0x44,  0xA9,  0x24, 	/* 3AD30 */
+	0xA9,  0x24,  0xC8,  0x0F,  0x8A,  0x0C,  0x9A,  0x14,  0x84,  0x14,  0x84,  0x27,  0x88,  0x20,  0x10,  0x40, 	/* 3AD40 */
+	0x60,  0x41,  0x80,  0xBE,  0x10,  0x00,  0x0B,  0xFF,  0x0A,  0x21,  0x02,  0x21,  0x07,  0xFE,  0x40,  0x20, 	/* 3AD50 */
+	0x21,  0xFE,  0x21,  0x22,  0x09,  0xFE,  0x09,  0x22,  0x11,  0x22,  0x11,  0xFE,  0x20,  0x20,  0x27,  0xFF, 	/* 3AD60 */
+	0x40,  0x20,  0x40,  0x20,  0x83,  0x10,  0x40,  0x09,  0xBF,  0x0F,  0x08,  0x01,  0x08,  0x01,  0x3E,  0x47, 	/* 3AD70 */
+	0x88,  0x21,  0x08,  0x21,  0x3E,  0x09,  0x08,  0x09,  0xC8,  0x17,  0x08,  0x11,  0x7F,  0x22,  0x08,  0x22, 	/* 3AD80 */
+	0x08,  0x44,  0x08,  0x48,  0x08,  0x8A,  0x10,  0x20,  0x08,  0x20,  0x0B,  0xFE,  0x00,  0x20,  0x41,  0xFC, 	/* 3AD90 */
+	0x20,  0x50,  0x27,  0xFF,  0x00,  0x88,  0x09,  0x04,  0x0B,  0xFE,  0x14,  0x21,  0x11,  0xFE,  0x20,  0x20, 	/* 3ADA0 */
+	0x20,  0x50,  0x41,  0x8C,  0x46,  0x03,  0x8D,  0x10,  0x20,  0x0A,  0x22,  0x0A,  0x22,  0x02,  0x22,  0x03, 	/* 3ADB0 */
+	0xFE,  0x40,  0x00,  0x2F,  0xFF,  0x20,  0x40,  0x08,  0x80,  0x0B,  0xFE,  0x12,  0x52,  0x12,  0x52,  0x22, 	/* 3ADC0 */
+	0x52,  0x22,  0x52,  0x42,  0x52,  0x42,  0x06,  0x8E,  0x10,  0x00,  0x0F,  0xFF,  0x08,  0x40,  0x00,  0x40, 	/* 3ADD0 */
+	0x00,  0x80,  0x47,  0xFE,  0x24,  0x92,  0x24,  0x92,  0x0C,  0xF2,  0x0C,  0x92,  0x14,  0x92,  0x14,  0xF2, 	/* 3ADE0 */
+	0x24,  0x92,  0x24,  0x92,  0x47,  0xFE,  0x40,  0x00,  0x96,  0x21,  0x00,  0x11,  0x1E,  0x11,  0x12,  0x01, 	/* 3ADF0 */
+	0x12,  0x0F,  0xF2,  0x41,  0x1E,  0x21,  0x12,  0x21,  0x12,  0x07,  0xD2,  0x14,  0x5E,  0x14,  0x52,  0x24, 	/* 3AE00 */
+	0x52,  0x27,  0xD2,  0x20,  0x12,  0x40,  0x22,  0x40,  0x46,  0x98,  0x21,  0x00,  0x11,  0x3E,  0x11,  0x22, 	/* 3AE10 */
+	0x01,  0x22,  0x0F,  0xE2,  0x41,  0x3E,  0x21,  0x22,  0x23,  0xA2,  0x03,  0x62,  0x15,  0x7E,  0x15,  0x22, 	/* 3AE20 */
+	0x19,  0x22,  0x21,  0x22,  0x21,  0x22,  0x41,  0x3E,  0x41,  0x00,  0x9B,  0x10,  0x84,  0x0B,  0xFF,  0x08, 	/* 3AE30 */
+	0x84,  0x00,  0x84,  0x40,  0xFC,  0x20,  0x84,  0x20,  0xFC,  0x00,  0x84,  0x08,  0x84,  0x0F,  0xFF,  0x12, 	/* 3AE40 */
+	0x50,  0x12,  0x52,  0x22,  0x8E,  0x23,  0x00,  0x43,  0xFF,  0x40,  0x00,  0x9F,  0x10,  0x20,  0x08,  0x40, 	/* 3AE50 */
+	0x09,  0xFC,  0x01,  0x04,  0x01,  0xFC,  0x41,  0x04,  0x21,  0x04,  0x21,  0xFC,  0x08,  0x00,  0x0B,  0xFE, 	/* 3AE60 */
+	0x10,  0x20,  0x11,  0xFC,  0x20,  0x20,  0x20,  0x20,  0x4F,  0xFF,  0x40,  0x00,  0xA7,  0x10,  0x00,  0x0B, 	/* 3AE70 */
+	0xFC,  0x08,  0xC8,  0x00,  0x30,  0x41,  0xFC,  0x21,  0x24,  0x21,  0xFC,  0x01,  0x24,  0x09,  0x24,  0x09, 	/* 3AE80 */
+	0xFC,  0x10,  0x20,  0x17,  0xFE,  0x20,  0x22,  0x20,  0x42,  0x41,  0x82,  0x46,  0x0C,  0xAB,  0x20,  0x90, 	/* 3AE90 */
+	0x13,  0x10,  0x1E,  0x12,  0x02,  0x12,  0x02,  0x32,  0x4F,  0xB4,  0x22,  0x34,  0x22,  0x50,  0x07,  0x10, 	/* 3AEA0 */
+	0x16,  0x98,  0x2A,  0x28,  0x2A,  0x28,  0x32,  0x24,  0x42,  0x44,  0x42,  0x82,  0x43,  0x01,  0xAE,  0x10, 	/* 3AEB0 */
+	0x00,  0x0F,  0xFF,  0x08,  0x50,  0x00,  0x50,  0x03,  0xFE,  0x42,  0x52,  0x22,  0x52,  0x22,  0x52,  0x0B, 	/* 3AEC0 */
+	0xFE,  0x08,  0x20,  0x10,  0x20,  0x11,  0xFC,  0x20,  0x20,  0x20,  0x20,  0x4F,  0xFF,  0x40,  0x00,  0xAF, 	/* 3AED0 */
+	0x10,  0x00,  0x09,  0xFC,  0x09,  0x04,  0x01,  0xFC,  0x01,  0x04,  0x41,  0x04,  0x21,  0xFC,  0x20,  0x00, 	/* 3AEE0 */
+	0x0F,  0xFF,  0x08,  0x80,  0x09,  0xFE,  0x12,  0x4A,  0x14,  0x8A,  0x21,  0x12,  0x22,  0x22,  0x40,  0x4C, 	/* 3AEF0 */
+	0xB2,  0x10,  0x04,  0x08,  0x18,  0x0B,  0xE4,  0x01,  0x12,  0x01,  0x11,  0x42,  0x01,  0x25,  0xFE,  0x20, 	/* 3AF00 */
+	0x40,  0x0F,  0xFF,  0x08,  0x40,  0x10,  0xFC,  0x10,  0xA4,  0x21,  0x18,  0x22,  0x30,  0x44,  0xCC,  0x43, 	/* 3AF10 */
+	0x03,  0xB6,  0x10,  0x20,  0x08,  0x40,  0x09,  0xFC,  0x01,  0x04,  0x01,  0xFC,  0x41,  0x04,  0x21,  0x04, 	/* 3AF20 */
+	0x21,  0xFC,  0x08,  0x22,  0x08,  0x32,  0x17,  0xB4,  0x10,  0xA8,  0x21,  0x24,  0x22,  0x23,  0x44,  0x20, 	/* 3AF30 */
+	0x40,  0x60,  0xBE,  0x10,  0x20,  0x08,  0x20,  0x0F,  0xFF,  0x00,  0x90,  0x42,  0x94,  0x22,  0x92,  0x24, 	/* 3AF40 */
+	0xB2,  0x01,  0x00,  0x0B,  0xF8,  0x08,  0x08,  0x13,  0xF8,  0x12,  0x00,  0x23,  0xFC,  0x20,  0x04,  0x40, 	/* 3AF50 */
+	0x04,  0x40,  0x38,  0xBF,  0x10,  0x00,  0x0B,  0xFC,  0x0A,  0x04,  0x02,  0x04,  0x03,  0xFC,  0x42,  0x04, 	/* 3AF60 */
+	0x22,  0x04,  0x23,  0xFC,  0x08,  0x00,  0x08,  0x92,  0x14,  0x92,  0x12,  0x94,  0x22,  0x94,  0x20,  0x90, 	/* 3AF70 */
+	0x4F,  0xFF,  0x40,  0x00,  0x80,  0x00,  0x88,  0x10,  0x88,  0x0B,  0xFE,  0x08,  0x88,  0x00,  0x88,  0x47, 	/* 3AF80 */
+	0xFF,  0x20,  0x20,  0x23,  0xFE,  0x0A,  0x22,  0x0A,  0xAA,  0x12,  0xAA,  0x12,  0xAA,  0x22,  0xFA,  0x22, 	/* 3AF90 */
+	0x8A,  0x42,  0x02,  0x42,  0x06,  0x82,  0x21,  0x02,  0x11,  0x12,  0x1F,  0xF2,  0x01,  0x12,  0x07,  0xD2, 	/* 3AFA0 */
+	0x05,  0x52,  0x45,  0x52,  0x25,  0x52,  0x27,  0xD2,  0x01,  0x12,  0x13,  0x92,  0x13,  0x42,  0x25,  0x22, 	/* 3AFB0 */
+	0x25,  0x02,  0x49,  0x02,  0x41,  0x06,  0x8C,  0x11,  0xD0,  0x08,  0x54,  0x0A,  0x59,  0x01,  0x8A,  0x40, 	/* 3AFC0 */
+	0x84,  0x21,  0x02,  0x23,  0xFD,  0x04,  0x90,  0x00,  0x90,  0x08,  0x90,  0x17,  0xFF,  0x10,  0x90,  0x20, 	/* 3AFD0 */
+	0x90,  0x21,  0x11,  0x42,  0x11,  0x44,  0x0F,  0x8F,  0x10,  0x20,  0x08,  0x20,  0x0B,  0xFF,  0x02,  0x20, 	/* 3AFE0 */
+	0x03,  0xFC,  0x42,  0x24,  0x23,  0xFF,  0x22,  0x24,  0x0A,  0x24,  0x0B,  0xFC,  0x12,  0x20,  0x15,  0xFC, 	/* 3AFF0 */
+	0x25,  0x04,  0x29,  0x04,  0x51,  0xFC,  0x40,  0x00,  0x90,  0x10,  0x00,  0x0B,  0xFE,  0x0A,  0x10,  0x02, 	/* 3B000 */
+	0x20,  0x42,  0xFC,  0x22,  0x84,  0x22,  0x84,  0x02,  0xFC,  0x0A,  0x84,  0x0A,  0xFC,  0x12,  0x20,  0x12, 	/* 3B010 */
+	0xA8,  0x24,  0xA4,  0x25,  0x22,  0x4A,  0x22,  0x40,  0x60,  0x96,  0x10,  0x88,  0x08,  0x90,  0x49,  0xFE, 	/* 3B020 */
+	0x23,  0x20,  0x23,  0xFC,  0x05,  0x20,  0x05,  0xFC,  0x09,  0x20,  0x11,  0x20,  0x21,  0xFE,  0x00,  0x80, 	/* 3B030 */
+	0x00,  0x80,  0x7F,  0xFF,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x98,  0x10,  0x40,  0x08,  0x40,  0x0B, 	/* 3B040 */
+	0xFC,  0x00,  0x40,  0x00,  0x40,  0x47,  0xFE,  0x20,  0x50,  0x20,  0x88,  0x09,  0x34,  0x0F,  0xC2,  0x10, 	/* 3B050 */
+	0x00,  0x17,  0xFC,  0x24,  0xA4,  0x24,  0xA4,  0x5F,  0xFF,  0x40,  0x00,  0x9C,  0x10,  0x40,  0x0B,  0xBE, 	/* 3B060 */
+	0x0A,  0x0A,  0x02,  0x8A,  0x02,  0x52,  0x42,  0x52,  0x23,  0xEC,  0x26,  0x40,  0x01,  0xFC,  0x09,  0x24, 	/* 3B070 */
+	0x09,  0x24,  0x11,  0xFC,  0x11,  0x24,  0x21,  0x24,  0x21,  0xFC,  0x40,  0x00,  0x9D,  0x10,  0x88,  0x08, 	/* 3B080 */
+	0x88,  0x0B,  0xFE,  0x00,  0x88,  0x03,  0xFE,  0x40,  0x88,  0x27,  0xFF,  0x20,  0x20,  0x09,  0xFC,  0x09, 	/* 3B090 */
+	0x24,  0x11,  0xFC,  0x11,  0x24,  0x27,  0xFF,  0x21,  0x04,  0x41,  0x04,  0x41,  0x0C,  0x9F,  0x20,  0x00, 	/* 3B0A0 */
+	0x17,  0xFF,  0x14,  0x01,  0x05,  0xFD,  0x01,  0x04,  0x41,  0x04,  0x21,  0xFC,  0x21,  0x04,  0x09,  0x04, 	/* 3B0B0 */
+	0x09,  0xFC,  0x10,  0x20,  0x17,  0xFF,  0x20,  0x00,  0x20,  0x88,  0x43,  0x06,  0x4C,  0x01,  0xA2,  0x12, 	/* 3B0C0 */
+	0x04,  0x09,  0x08,  0x09,  0x08,  0x0F,  0xFF,  0x40,  0x90,  0x21,  0x08,  0x21,  0x08,  0x02,  0x04,  0x04, 	/* 3B0D0 */
+	0x02,  0x1B,  0xFD,  0x12,  0xA4,  0x12,  0xA4,  0x22,  0xA4,  0x22,  0xA4,  0x4F,  0xFF,  0x40,  0x00,  0xA5, 	/* 3B0E0 */
+	0x10,  0x44,  0x08,  0x42,  0x0F,  0xFF,  0x00,  0x40,  0x03,  0xFC,  0x42,  0x44,  0x23,  0xFC,  0x22,  0x44, 	/* 3B0F0 */
+	0x0B,  0xFC,  0x0A,  0x44,  0x10,  0x08,  0x17,  0xFF,  0x21,  0x08,  0x20,  0x88,  0x40,  0x88,  0x40,  0x18, 	/* 3B100 */
+	0xAA,  0x10,  0x04,  0x08,  0x38,  0x0B,  0xC8,  0x01,  0x24,  0x01,  0x22,  0x42,  0x02,  0x24,  0x4A,  0x21, 	/* 3B110 */
+	0x90,  0x08,  0xA8,  0x08,  0x46,  0x13,  0xF9,  0x10,  0x20,  0x27,  0xFF,  0x20,  0x50,  0x41,  0x8C,  0x46, 	/* 3B120 */
+	0x03,  0xAF,  0x24,  0x40,  0x12,  0x5E,  0x12,  0x92,  0x0F,  0xF2,  0x01,  0x12,  0x41,  0x1E,  0x25,  0x52, 	/* 3B130 */
+	0x25,  0x52,  0x05,  0x52,  0x15,  0x5E,  0x17,  0xD2,  0x21,  0x12,  0x21,  0x12,  0x22,  0x22,  0x44,  0x22, 	/* 3B140 */
+	0x40,  0x46,  0xB2,  0x10,  0xA0,  0x08,  0xA0,  0x0B,  0x2C,  0x02,  0x24,  0x02,  0x24,  0x43,  0xAC,  0x22, 	/* 3B150 */
+	0x24,  0x22,  0x24,  0x0B,  0xAC,  0x08,  0x20,  0x17,  0xFC,  0x11,  0x08,  0x20,  0x90,  0x20,  0x60,  0x41, 	/* 3B160 */
+	0x98,  0x46,  0x07,  0xB6,  0x10,  0x20,  0x08,  0x20,  0x0B,  0xFE,  0x02,  0x02,  0x42,  0x92,  0x20,  0x88, 	/* 3B170 */
+	0x20,  0xA4,  0x01,  0x24,  0x0A,  0x50,  0x08,  0x88,  0x11,  0x04,  0x13,  0xFE,  0x25,  0x05,  0x21,  0x04, 	/* 3B180 */
+	0x41,  0xFC,  0x40,  0x00,  0xB7,  0x20,  0x00,  0x17,  0xFE,  0x14,  0x02,  0x07,  0xFE,  0x04,  0x42,  0x44, 	/* 3B190 */
+	0x8A,  0x27,  0x4A,  0x24,  0x52,  0x0C,  0xB2,  0x0F,  0x2A,  0x14,  0x6A,  0x14,  0xA6,  0x27,  0x22,  0x24, 	/* 3B1A0 */
+	0x62,  0x47,  0xFE,  0x44,  0x02,  0xBA,  0x20,  0x00,  0x1F,  0xBE,  0x10,  0x82,  0x00,  0x82,  0x47,  0x9E, 	/* 3B1B0 */
+	0x24,  0x10,  0x24,  0x10,  0x07,  0x9E,  0x10,  0x82,  0x18,  0xA2,  0x14,  0x92,  0x21,  0x86,  0x26,  0x9A, 	/* 3B1C0 */
+	0x28,  0xA2,  0x41,  0x04,  0x46,  0x18,  0xBD,  0x10,  0x00,  0x0B,  0xFF,  0x0A,  0x00,  0x02,  0xFE,  0x02, 	/* 3B1D0 */
+	0x00,  0x43,  0xFF,  0x22,  0xA2,  0x22,  0x94,  0x04,  0xEC,  0x1B,  0x03,  0x10,  0x04,  0x17,  0xFF,  0x21, 	/* 3B1E0 */
+	0x04,  0x20,  0x84,  0x40,  0x84,  0x40,  0x0C,  0x82,  0x10,  0x20,  0x08,  0x20,  0x0B,  0xFF,  0x01,  0x04, 	/* 3B1F0 */
+	0x00,  0x88,  0x47,  0xFF,  0x24,  0x01,  0x24,  0x21,  0x00,  0x20,  0x17,  0xFF,  0x10,  0x40,  0x20,  0x7C, 	/* 3B200 */
+	0x20,  0x44,  0x20,  0x84,  0x43,  0x04,  0x4C,  0x18,  0x84,  0x10,  0x20,  0x08,  0x20,  0x08,  0x50,  0x00, 	/* 3B210 */
+	0x88,  0x01,  0x74,  0x42,  0x02,  0x25,  0xFD,  0x21,  0x04,  0x09,  0xFC,  0x09,  0x04,  0x11,  0xFC,  0x12, 	/* 3B220 */
+	0x00,  0x22,  0xFE,  0x24,  0x82,  0x48,  0xFE,  0x40,  0x00,  0x85,  0x10,  0x0C,  0x08,  0x0A,  0x08,  0x08, 	/* 3B230 */
+	0x03,  0xFF,  0x42,  0x08,  0x23,  0xFA,  0x22,  0x4A,  0x03,  0x5A,  0x0A,  0xEA,  0x0A,  0xCC,  0x12,  0x44, 	/* 3B240 */
+	0x12,  0xAC,  0x24,  0x95,  0x25,  0x15,  0x46,  0x23,  0x48,  0x41,  0x89,  0x10,  0x00,  0x09,  0xFC,  0x09, 	/* 3B250 */
+	0x04,  0x01,  0xFC,  0x01,  0x04,  0x41,  0xFC,  0x22,  0x24,  0x21,  0x24,  0x09,  0x28,  0x0F,  0xFF,  0x10, 	/* 3B260 */
+	0x90,  0x10,  0x90,  0x20,  0x90,  0x21,  0x11,  0x46,  0x11,  0x58,  0x0F,  0x8B,  0x21,  0x04,  0x10,  0x84, 	/* 3B270 */
+	0x10,  0x88,  0x07,  0xFF,  0x00,  0x84,  0x40,  0x84,  0x21,  0x08,  0x21,  0x48,  0x0E,  0x72,  0x09,  0x4A, 	/* 3B280 */
+	0x10,  0x84,  0x10,  0x84,  0x21,  0x4A,  0x22,  0x52,  0x4F,  0xFF,  0x40,  0x21,  0x8C,  0x11,  0x20,  0x09, 	/* 3B290 */
+	0x20,  0x09,  0x7F,  0x02,  0x44,  0x02,  0xA4,  0x45,  0x18,  0x2D,  0x18,  0x25,  0x24,  0x05,  0xC3,  0x15, 	/* 3B2A0 */
+	0x10,  0x25,  0xFF,  0x25,  0x18,  0x25,  0x34,  0x44,  0x52,  0x44,  0x91,  0x44,  0x10,  0x91,  0x10,  0x00, 	/* 3B2B0 */
+	0x09,  0xF8,  0x09,  0x08,  0x01,  0x38,  0x01,  0x28,  0x47,  0xFE,  0x24,  0x02,  0x25,  0xFA,  0x01,  0x08, 	/* 3B2C0 */
+	0x09,  0xF8,  0x11,  0x08,  0x11,  0xF8,  0x21,  0x08,  0x21,  0x08,  0x41,  0x08,  0x41,  0x18,  0x93,  0x10, 	/* 3B2D0 */
+	0x20,  0x08,  0x20,  0x0B,  0xFF,  0x02,  0x01,  0x02,  0x21,  0x43,  0xFE,  0x20,  0x84,  0x20,  0x48,  0x0F, 	/* 3B2E0 */
+	0xFF,  0x08,  0x20,  0x10,  0x20,  0x13,  0xFE,  0x20,  0x20,  0x20,  0x20,  0x40,  0x20,  0x40,  0x20,  0x94, 	/* 3B2F0 */
+	0x10,  0x02,  0x08,  0x1C,  0x0B,  0xE8,  0x00,  0x44,  0x02,  0x22,  0x42,  0x22,  0x24,  0x00,  0x20,  0x40, 	/* 3B300 */
+	0x0B,  0x9E,  0x0A,  0x02,  0x12,  0x02,  0x13,  0xDE,  0x22,  0x02,  0x22,  0x02,  0x43,  0xFE,  0x40,  0x00, 	/* 3B310 */
+	0x95,  0x00,  0x20,  0x3C,  0xA8,  0x25,  0x24,  0x27,  0xFE,  0x24,  0x20,  0x3C,  0x50,  0x27,  0xFF,  0x24, 	/* 3B320 */
+	0x88,  0x24,  0xA4,  0x3D,  0x26,  0x26,  0xB5,  0x24,  0xB8,  0x24,  0x68,  0x24,  0xA4,  0x27,  0x22,  0x4C, 	/* 3B330 */
+	0x60,  0x9D,  0x10,  0x40,  0x08,  0x40,  0x0B,  0xFE,  0x01,  0x08,  0x40,  0x90,  0x27,  0xFF,  0x20,  0x00, 	/* 3B340 */
+	0x03,  0xFC,  0x0A,  0x44,  0x0A,  0x44,  0x13,  0xFC,  0x12,  0x44,  0x23,  0xFC,  0x22,  0x41,  0x40,  0x41, 	/* 3B350 */
+	0x40,  0x3F,  0x9E,  0x11,  0x24,  0x09,  0x24,  0x0F,  0xFF,  0x01,  0x24,  0x41,  0x24,  0x21,  0xFC,  0x20, 	/* 3B360 */
+	0x00,  0x07,  0xFF,  0x04,  0x21,  0x0C,  0x21,  0x11,  0xFE,  0x11,  0x22,  0x21,  0x22,  0x21,  0x2C,  0x41, 	/* 3B370 */
+	0x20,  0x40,  0x20,  0xAC,  0x10,  0x00,  0x0F,  0xFF,  0x08,  0x00,  0x03,  0xFE,  0x02,  0x02,  0x43,  0xFE, 	/* 3B380 */
+	0x22,  0x00,  0x22,  0xFC,  0x0A,  0x84,  0x0A,  0xFC,  0x12,  0x00,  0x13,  0xFE,  0x25,  0x22,  0x25,  0xFE, 	/* 3B390 */
+	0x49,  0x01,  0x40,  0xFF,  0xAF,  0x11,  0x54,  0x09,  0x54,  0x0F,  0xFF,  0x01,  0x54,  0x01,  0x55,  0x41, 	/* 3B3A0 */
+	0x73,  0x22,  0x01,  0x27,  0xFE,  0x0A,  0x22,  0x0A,  0x22,  0x11,  0xFC,  0x11,  0x24,  0x21,  0x24,  0x21, 	/* 3B3B0 */
+	0x38,  0x41,  0x20,  0x40,  0x20,  0xB2,  0x10,  0x20,  0x08,  0x58,  0x0B,  0xF4,  0x00,  0x84,  0x01,  0x4A, 	/* 3B3C0 */
+	0x47,  0xBD,  0x20,  0x20,  0x27,  0xFF,  0x08,  0x50,  0x08,  0x98,  0x13,  0x64,  0x1D,  0x8B,  0x20,  0x32, 	/* 3B3D0 */
+	0x21,  0xCC,  0x40,  0x30,  0x43,  0xC0,  0xB4,  0x10,  0x20,  0x08,  0x20,  0x0F,  0xFF,  0x01,  0x04,  0x40, 	/* 3B3E0 */
+	0x88,  0x23,  0xFE,  0x22,  0x22,  0x02,  0x22,  0x0B,  0xFE,  0x0A,  0x22,  0x12,  0xFA,  0x12,  0x8A,  0x22, 	/* 3B3F0 */
+	0x8A,  0x22,  0xFA,  0x42,  0x02,  0x42,  0x06,  0xB7,  0x10,  0x40,  0x08,  0x40,  0x08,  0x7F,  0x00,  0x40, 	/* 3B400 */
+	0x00,  0x40,  0x47,  0xFE,  0x24,  0x8A,  0x24,  0x4A,  0x0D,  0x92,  0x0C,  0x5A,  0x16,  0x26,  0x15,  0x52, 	/* 3B410 */
+	0x24,  0x8A,  0x25,  0x2A,  0x47,  0xFE,  0x40,  0x00,  0xB8,  0x20,  0x10,  0x17,  0x90,  0x10,  0x10,  0x1F, 	/* 3B420 */
+	0xFE,  0x00,  0x28,  0x47,  0xC8,  0x20,  0x08,  0x20,  0x7F,  0x07,  0x88,  0x10,  0x08,  0x17,  0x88,  0x24, 	/* 3B430 */
+	0x88,  0x24,  0x88,  0x44,  0x88,  0x47,  0x88,  0x40,  0x08,  0xBE,  0x10,  0x20,  0x08,  0x20,  0x0F,  0xFF, 	/* 3B440 */
+	0x00,  0x48,  0x01,  0x86,  0x46,  0x01,  0x21,  0xFC,  0x21,  0x04,  0x09,  0x04,  0x09,  0xFE,  0x10,  0xA2, 	/* 3B450 */
+	0x11,  0x24,  0x27,  0x18,  0x21,  0x28,  0x41,  0xC4,  0x47,  0x03,  0xBF,  0x10,  0x88,  0x08,  0x88,  0x0F, 	/* 3B460 */
+	0xFF,  0x00,  0x88,  0x00,  0x88,  0x40,  0xF8,  0x20,  0x20,  0x23,  0xFE,  0x0A,  0x22,  0x0B,  0xBA,  0x12, 	/* 3B470 */
+	0xAA,  0x12,  0xAA,  0x23,  0x76,  0x23,  0x32,  0x42,  0x22,  0x42,  0x26,  0x81,  0x10,  0x40,  0x08,  0x40, 	/* 3B480 */
+	0x08,  0xF8,  0x01,  0x10,  0x06,  0x20,  0x41,  0xFC,  0x21,  0x24,  0x21,  0x24,  0x09,  0xFC,  0x09,  0x24, 	/* 3B490 */
+	0x11,  0x24,  0x11,  0xFC,  0x22,  0x00,  0x22,  0x92,  0x44,  0x49,  0x48,  0x49,  0x82,  0x10,  0x00,  0x0F, 	/* 3B4A0 */
+	0xFF,  0x08,  0x90,  0x0B,  0xFC,  0x42,  0x94,  0x22,  0x94,  0x23,  0xFC,  0x00,  0x00,  0x09,  0xFC,  0x08, 	/* 3B4B0 */
+	0x00,  0x17,  0xFF,  0x11,  0x28,  0x21,  0x24,  0x22,  0x22,  0x44,  0x22,  0x40,  0x60,  0x86,  0x10,  0x20, 	/* 3B4C0 */
+	0x08,  0x20,  0x0F,  0xFF,  0x08,  0x70,  0x41,  0xAC,  0x26,  0x23,  0x20,  0x20,  0x00,  0x50,  0x09,  0xAC, 	/* 3B4D0 */
+	0x0E,  0x23,  0x11,  0x24,  0x10,  0xA8,  0x20,  0xF0,  0x21,  0xAC,  0x46,  0x23,  0x40,  0x60,  0x89,  0x20, 	/* 3B4E0 */
+	0x20,  0x10,  0x20,  0x17,  0xFF,  0x04,  0x90,  0x44,  0x90,  0x27,  0xFE,  0x24,  0x92,  0x04,  0x92,  0x07, 	/* 3B4F0 */
+	0xFE,  0x15,  0x10,  0x15,  0x10,  0x25,  0xF2,  0x29,  0x1C,  0x29,  0x10,  0x51,  0xD1,  0x46,  0x0F,  0x8F, 	/* 3B500 */
+	0x10,  0x00,  0x0B,  0xFE,  0x0A,  0x02,  0x02,  0x02,  0x43,  0xFE,  0x22,  0x00,  0x23,  0xFF,  0x02,  0x20, 	/* 3B510 */
+	0x0B,  0xFE,  0x0B,  0xB2,  0x15,  0x6A,  0x15,  0x22,  0x25,  0xB2,  0x29,  0x6A,  0x51,  0x22,  0x41,  0x26, 	/* 3B520 */
+	0x91,  0x22,  0x00,  0x12,  0x3E,  0x17,  0x84,  0x04,  0xA4,  0x44,  0xA4,  0x27,  0xA4,  0x24,  0xA4,  0x04, 	/* 3B530 */
+	0xFF,  0x07,  0x88,  0x14,  0x0C,  0x17,  0x8C,  0x24,  0x14,  0x24,  0x14,  0x27,  0xA5,  0x44,  0x45,  0x44, 	/* 3B540 */
+	0x83,  0x93,  0x10,  0x20,  0x08,  0x20,  0x0F,  0xFF,  0x00,  0x10,  0x01,  0xD4,  0x41,  0x24,  0x21,  0x54, 	/* 3B550 */
+	0x21,  0x84,  0x09,  0xFC,  0x08,  0x20,  0x13,  0xFE,  0x12,  0x42,  0x22,  0x92,  0x23,  0xEA,  0x42,  0x02, 	/* 3B560 */
+	0x42,  0x06,  0x94,  0x10,  0x20,  0x08,  0x20,  0x0F,  0xFF,  0x04,  0x01,  0x07,  0xFE,  0x40,  0x20,  0x23, 	/* 3B570 */
+	0xFE,  0x22,  0x22,  0x02,  0x22,  0x13,  0xFE,  0x12,  0x22,  0x22,  0x22,  0x23,  0xFE,  0x20,  0x8C,  0x41, 	/* 3B580 */
+	0x02,  0x46,  0x01,  0x95,  0x10,  0x50,  0x08,  0x50,  0x0F,  0xFF,  0x00,  0x50,  0x43,  0xFE,  0x22,  0x52, 	/* 3B590 */
+	0x23,  0xFE,  0x02,  0x52,  0x0B,  0xFE,  0x08,  0x00,  0x11,  0xFC,  0x11,  0x04,  0x21,  0xFC,  0x21,  0x04, 	/* 3B5A0 */
+	0x41,  0xFC,  0x40,  0x00,  0xA0,  0x10,  0x88,  0x08,  0x88,  0x0F,  0xFF,  0x00,  0x88,  0x40,  0x88,  0x21, 	/* 3B5B0 */
+	0xFC,  0x21,  0x04,  0x01,  0xFC,  0x09,  0x04,  0x09,  0xFC,  0x10,  0x20,  0x17,  0xFF,  0x20,  0x20,  0x20, 	/* 3B5C0 */
+	0x50,  0x41,  0x8C,  0x46,  0x03,  0xA2,  0x10,  0x88,  0x08,  0x88,  0x0F,  0xFF,  0x00,  0x88,  0x40,  0x00, 	/* 3B5D0 */
+	0x23,  0xFE,  0x22,  0x22,  0x02,  0x22,  0x0B,  0xFE,  0x08,  0x20,  0x13,  0xFC,  0x10,  0x20,  0x27,  0xFF, 	/* 3B5E0 */
+	0x20,  0x50,  0x41,  0x8C,  0x46,  0x03,  0xA3,  0x20,  0x10,  0x14,  0x10,  0x13,  0xFF,  0x02,  0x10,  0x40, 	/* 3B5F0 */
+	0xFE,  0x20,  0x92,  0x20,  0x92,  0x0E,  0xFE,  0x02,  0x92,  0x12,  0x92,  0x12,  0xFE,  0x22,  0x10,  0x23, 	/* 3B600 */
+	0xFF,  0x25,  0x10,  0x48,  0xD0,  0x50,  0x3F,  0xAB,  0x10,  0x00,  0x09,  0xF8,  0x09,  0x08,  0x01,  0xF8, 	/* 3B610 */
+	0x41,  0x08,  0x21,  0xF8,  0x20,  0x00,  0x0B,  0xFE,  0x0A,  0x52,  0x0B,  0xFE,  0x10,  0x00,  0x17,  0xFC, 	/* 3B620 */
+	0x20,  0x88,  0x20,  0x70,  0x41,  0x98,  0x4E,  0x07,  0xAC,  0x10,  0x20,  0x0B,  0xFE,  0x08,  0x20,  0x01, 	/* 3B630 */
+	0xFC,  0x00,  0x20,  0x47,  0xFF,  0x20,  0x00,  0x21,  0xFC,  0x09,  0x04,  0x09,  0xFC,  0x11,  0x04,  0x11, 	/* 3B640 */
+	0xFC,  0x21,  0x04,  0x21,  0xFC,  0x40,  0x98,  0x47,  0x06,  0xB1,  0x21,  0x10,  0x11,  0x10,  0x1F,  0xF0, 	/* 3B650 */
+	0x01,  0x1F,  0x07,  0xE2,  0x45,  0x6C,  0x25,  0x48,  0x25,  0x48,  0x07,  0xC8,  0x11,  0x0C,  0x13,  0x8C, 	/* 3B660 */
+	0x23,  0x54,  0x25,  0x54,  0x49,  0x22,  0x41,  0x42,  0x41,  0x81,  0xB2,  0x20,  0x00,  0x1F,  0x3E,  0x11, 	/* 3B670 */
+	0x20,  0x01,  0x3C,  0x01,  0x20,  0x47,  0x3C,  0x24,  0x20,  0x24,  0x20,  0x04,  0xFF,  0x17,  0x32,  0x11, 	/* 3B680 */
+	0x32,  0x21,  0x2C,  0x21,  0x28,  0x41,  0x24,  0x42,  0x32,  0x4C,  0xC1,  0xB8,  0x21,  0x02,  0x11,  0x0C, 	/* 3B690 */
+	0x1F,  0xF0,  0x01,  0x10,  0x47,  0xD0,  0x25,  0x5F,  0x25,  0x54,  0x07,  0xD4,  0x05,  0x54,  0x15,  0x54, 	/* 3B6A0 */
+	0x17,  0xD4,  0x21,  0x24,  0x2F,  0xE4,  0x21,  0x44,  0x41,  0x04,  0x41,  0x04,  0xBE,  0x11,  0x04,  0x08, 	/* 3B6B0 */
+	0x88,  0x0B,  0xFE,  0x00,  0x20,  0x01,  0xFC,  0x40,  0x20,  0x27,  0xFF,  0x20,  0x40,  0x08,  0x22,  0x0B, 	/* 3B6C0 */
+	0xE2,  0x10,  0x34,  0x17,  0xA8,  0x20,  0xA4,  0x21,  0x22,  0x46,  0x21,  0x40,  0x60,  0xBF,  0x04,  0x20, 	/* 3B6D0 */
+	0x24,  0x7E,  0x25,  0x94,  0x3C,  0x58,  0x04,  0x60,  0x7D,  0x84,  0x17,  0xFF,  0x14,  0x44,  0x24,  0x24, 	/* 3B6E0 */
+	0x44,  0x2C,  0x00,  0x88,  0x3E,  0xD0,  0x04,  0xA0,  0x18,  0x98,  0x60,  0x87,  0x01,  0x80,  0x81,  0x20, 	/* 3B6F0 */
+	0x00,  0x20,  0xFF,  0x26,  0x10,  0x38,  0x20,  0x21,  0x7E,  0x21,  0x42,  0x1F,  0x42,  0x04,  0x7E,  0x04, 	/* 3B700 */
+	0xC2,  0x75,  0x7E,  0x16,  0x42,  0x16,  0x42,  0x25,  0x7E,  0x24,  0xA4,  0x44,  0x42,  0x0D,  0x81,  0x85, 	/* 3B710 */
+	0x21,  0x00,  0x11,  0x00,  0x11,  0xFE,  0x01,  0x40,  0x42,  0x40,  0x23,  0xFF,  0x24,  0x88,  0x01,  0x10, 	/* 3B720 */
+	0x03,  0xFE,  0x0D,  0x10,  0x11,  0xFC,  0x11,  0x10,  0x21,  0xFC,  0x21,  0x10,  0x41,  0xFF,  0x40,  0x00, 	/* 3B730 */
+	0x94,  0x21,  0x00,  0x17,  0xDE,  0x11,  0x0A,  0x07,  0xCA,  0x01,  0x12,  0x41,  0xA2,  0x26,  0x4C,  0x20, 	/* 3B740 */
+	0x20,  0x09,  0xC8,  0x08,  0x58,  0x10,  0x26,  0x17,  0xFD,  0x21,  0x28,  0x21,  0x24,  0x42,  0x22,  0x44, 	/* 3B750 */
+	0x20,  0x98,  0x10,  0x04,  0x08,  0x18,  0x0B,  0xE0,  0x01,  0x24,  0x00,  0xA8,  0x47,  0xFF,  0x20,  0x70, 	/* 3B760 */
+	0x20,  0xA8,  0x01,  0x24,  0x0B,  0xFE,  0x15,  0x25,  0x11,  0xFC,  0x21,  0x24,  0x21,  0x24,  0x41,  0xFC, 	/* 3B770 */
+	0x40,  0x00,  0x9B,  0x20,  0x84,  0x17,  0xFE,  0x12,  0x94,  0x02,  0x94,  0x07,  0xFF,  0x41,  0x8C,  0x21, 	/* 3B780 */
+	0xCD,  0x22,  0x97,  0x04,  0x20,  0x11,  0xFC,  0x11,  0x04,  0x21,  0xFC,  0x21,  0x04,  0x21,  0x04,  0x41, 	/* 3B790 */
+	0xFC,  0x40,  0x00,  0x9C,  0x11,  0x04,  0x09,  0x04,  0x0F,  0xDF,  0x01,  0x04,  0x07,  0xDF,  0x41,  0x04, 	/* 3B7A0 */
+	0x22,  0x8A,  0x24,  0x51,  0x08,  0x00,  0x09,  0xFC,  0x11,  0x04,  0x11,  0xFC,  0x21,  0x04,  0x21,  0x04, 	/* 3B7B0 */
+	0x41,  0xFC,  0x40,  0x00,  0x9F,  0x10,  0x40,  0x08,  0x80,  0x0B,  0x38,  0x02,  0x08,  0x43,  0xB8,  0x22, 	/* 3B7C0 */
+	0x08,  0x22,  0x08,  0x03,  0xF8,  0x08,  0x80,  0x08,  0xFE,  0x11,  0x02,  0x16,  0x12,  0x23,  0x4A,  0x22, 	/* 3B7D0 */
+	0xA2,  0x44,  0x82,  0x48,  0x0C,  0xA4,  0x10,  0x00,  0x0B,  0xDE,  0x0A,  0x52,  0x03,  0xDE,  0x02,  0x52, 	/* 3B7E0 */
+	0x43,  0xDE,  0x22,  0x02,  0x26,  0xFA,  0x0A,  0x22,  0x0A,  0x22,  0x12,  0xFA,  0x12,  0x22,  0x22,  0x22, 	/* 3B7F0 */
+	0x22,  0xFA,  0x42,  0x02,  0x42,  0x06,  0xA6,  0x10,  0x20,  0x08,  0x20,  0x0F,  0xFF,  0x00,  0x88,  0x02, 	/* 3B800 */
+	0x8A,  0x41,  0x04,  0x23,  0xFE,  0x25,  0x05,  0x01,  0xFC,  0x09,  0x04,  0x11,  0xFC,  0x10,  0x20,  0x21, 	/* 3B810 */
+	0x24,  0x22,  0x22,  0x44,  0x21,  0x40,  0x60,  0xAD,  0x10,  0x00,  0x0F,  0xFF,  0x08,  0x50,  0x03,  0xFE, 	/* 3B820 */
+	0x02,  0x52,  0x43,  0xFE,  0x20,  0x00,  0x21,  0xFC,  0x09,  0x04,  0x09,  0xFC,  0x11,  0x04,  0x11,  0xFC, 	/* 3B830 */
+	0x20,  0x20,  0x27,  0xFF,  0x40,  0x20,  0x40,  0x20,  0xAE,  0x21,  0x00,  0x11,  0x1E,  0x1F,  0xF2,  0x01, 	/* 3B840 */
+	0x12,  0x47,  0xD2,  0x24,  0x5E,  0x24,  0x52,  0x07,  0xD2,  0x04,  0x52,  0x14,  0x5E,  0x17,  0xD2,  0x21, 	/* 3B850 */
+	0x12,  0x2F,  0xF2,  0x21,  0x12,  0x41,  0x22,  0x41,  0x46,  0xAF,  0x10,  0x00,  0x09,  0xFC,  0x08,  0x04, 	/* 3B860 */
+	0x03,  0xFF,  0x00,  0x04,  0x41,  0xFC,  0x20,  0x00,  0x23,  0xDE,  0x08,  0x92,  0x08,  0xFE,  0x13,  0x04, 	/* 3B870 */
+	0x17,  0xFF,  0x20,  0x84,  0x20,  0x44,  0x40,  0x44,  0x40,  0x0C,  0xB0,  0x10,  0x20,  0x09,  0xFC,  0x09, 	/* 3B880 */
+	0x24,  0x01,  0xFC,  0x40,  0x20,  0x27,  0xFF,  0x20,  0x00,  0x01,  0xFC,  0x09,  0x04,  0x09,  0xFC,  0x11, 	/* 3B890 */
+	0x04,  0x11,  0xFC,  0x21,  0x04,  0x21,  0xFC,  0x40,  0x8C,  0x47,  0x03,  0xB4,  0x24,  0x10,  0x12,  0x92, 	/* 3B8A0 */
+	0x12,  0xFE,  0x01,  0x14,  0x01,  0x14,  0x43,  0x18,  0x25,  0xFF,  0x29,  0x14,  0x03,  0x22,  0x13,  0x7E, 	/* 3B8B0 */
+	0x15,  0xA2,  0x19,  0x3E,  0x21,  0x22,  0x21,  0x22,  0x41,  0x3E,  0x46,  0x00,  0xB8,  0x10,  0x88,  0x08, 	/* 3B8C0 */
+	0x88,  0x0F,  0xFF,  0x00,  0x88,  0x02,  0xAA,  0x42,  0xAA,  0x24,  0xAB,  0x20,  0x00,  0x09,  0xFC,  0x09, 	/* 3B8D0 */
+	0x04,  0x11,  0xFC,  0x11,  0x04,  0x21,  0xFC,  0x21,  0x04,  0x41,  0x04,  0x42,  0x0C,  0xBA,  0x10,  0x00, 	/* 3B8E0 */
+	0x0B,  0xFE,  0x0A,  0x02,  0x03,  0xFE,  0x02,  0x00,  0x42,  0xFC,  0x22,  0x08,  0x23,  0xFE,  0x0A,  0x10, 	/* 3B8F0 */
+	0x0A,  0x30,  0x13,  0xEF,  0x12,  0x42,  0x24,  0xE4,  0x27,  0x9F,  0x48,  0x84,  0x51,  0x8C,  0xBC,  0x10, 	/* 3B900 */
+	0x20,  0x08,  0x20,  0x0B,  0xFE,  0x00,  0x88,  0x07,  0xFF,  0x40,  0x00,  0x21,  0xFC,  0x21,  0x24,  0x09, 	/* 3B910 */
+	0xFC,  0x09,  0x24,  0x11,  0xFC,  0x10,  0x20,  0x23,  0xFE,  0x20,  0x20,  0x47,  0xFF,  0x40,  0x00,  0x80, 	/* 3B920 */
+	0x20,  0x00,  0x17,  0xFE,  0x11,  0x4A,  0x05,  0x6A,  0x05,  0x6A,  0x4A,  0x52,  0x22,  0x52,  0x25,  0xAC, 	/* 3B930 */
+	0x00,  0x00,  0x08,  0x84,  0x12,  0xF7,  0x12,  0x94,  0x22,  0x94,  0x22,  0xD4,  0x43,  0xBF,  0x4E,  0x00, 	/* 3B940 */
+	0x81,  0x10,  0x10,  0x08,  0x90,  0x08,  0x9E,  0x00,  0x90,  0x00,  0x90,  0x43,  0xFF,  0x20,  0x00,  0x20, 	/* 3B950 */
+	0x84,  0x0A,  0x94,  0x0A,  0x94,  0x12,  0xF7,  0x12,  0x94,  0x22,  0x94,  0x22,  0xD4,  0x43,  0xBF,  0x46, 	/* 3B960 */
+	0x00,  0x82,  0x21,  0x08,  0x15,  0x48,  0x15,  0x48,  0x05,  0x5F,  0x07,  0xD4,  0x40,  0x24,  0x27,  0xC4, 	/* 3B970 */
+	0x20,  0x14,  0x07,  0xD4,  0x11,  0x14,  0x17,  0xC8,  0x21,  0x08,  0x21,  0x54,  0x21,  0x94,  0x46,  0x22, 	/* 3B980 */
+	0x40,  0x41,  0x84,  0x11,  0xD2,  0x08,  0x54,  0x0A,  0x89,  0x02,  0x8A,  0x01,  0x04,  0x43,  0xFE,  0x24, 	/* 3B990 */
+	0x01,  0x21,  0xF8,  0x09,  0x08,  0x09,  0x08,  0x11,  0xF8,  0x11,  0x08,  0x20,  0x88,  0x20,  0x90,  0x4F, 	/* 3B9A0 */
+	0xFF,  0x40,  0x00,  0x86,  0x10,  0x20,  0x09,  0xFC,  0x08,  0x20,  0x03,  0xFE,  0x00,  0x00,  0x40,  0x84, 	/* 3B9B0 */
+	0x23,  0xDF,  0x20,  0x84,  0x08,  0xE4,  0x0B,  0x1F,  0x10,  0x00,  0x17,  0xFF,  0x20,  0x90,  0x20,  0x91, 	/* 3B9C0 */
+	0x43,  0x11,  0x4C,  0x0F,  0x8E,  0x10,  0x84,  0x08,  0x84,  0x0F,  0xF4,  0x00,  0x88,  0x03,  0xE8,  0x40, 	/* 3B9D0 */
+	0x12,  0x23,  0xE2,  0x22,  0x24,  0x0B,  0xE4,  0x08,  0x09,  0x12,  0x21,  0x11,  0x22,  0x21,  0x52,  0x20, 	/* 3B9E0 */
+	0xE4,  0x47,  0x08,  0x40,  0x10,  0x91,  0x10,  0x00,  0x0F,  0xFF,  0x08,  0x50,  0x03,  0xDE,  0x02,  0x52, 	/* 3B9F0 */
+	0x42,  0x52,  0x23,  0xDE,  0x20,  0x50,  0x0B,  0xFE,  0x0A,  0x22,  0x12,  0x22,  0x13,  0xFE,  0x22,  0x22, 	/* 3BA00 */
+	0x22,  0x22,  0x43,  0xFE,  0x40,  0x00,  0x97,  0x10,  0x00,  0x0B,  0xDE,  0x0A,  0x52,  0x03,  0xDE,  0x42, 	/* 3BA10 */
+	0x52,  0x22,  0x52,  0x23,  0xDE,  0x02,  0x02,  0x0A,  0xFA,  0x0A,  0x8A,  0x12,  0xFA,  0x12,  0x8A,  0x22, 	/* 3BA20 */
+	0x8A,  0x22,  0xFA,  0x42,  0x02,  0x42,  0x06,  0xA1,  0x10,  0x00,  0x08,  0xF8,  0x08,  0x88,  0x00,  0x88, 	/* 3BA30 */
+	0x00,  0xF8,  0x43,  0xDE,  0x22,  0x52,  0x22,  0x52,  0x0B,  0xDE,  0x08,  0x20,  0x17,  0xFF,  0x10,  0xA8, 	/* 3BA40 */
+	0x21,  0x24,  0x22,  0x22,  0x44,  0x21,  0x40,  0x20,  0xA3,  0x22,  0x08,  0x12,  0x08,  0x1F,  0xD4,  0x02, 	/* 3BA50 */
+	0x14,  0x07,  0xA2,  0x44,  0xC1,  0x24,  0xBE,  0x27,  0x88,  0x0C,  0x88,  0x0C,  0x88,  0x17,  0xFF,  0x12, 	/* 3BA60 */
+	0x08,  0x2F,  0xC8,  0x22,  0x08,  0x42,  0x08,  0x42,  0x08,  0xA4,  0x10,  0x00,  0x09,  0xFE,  0x09,  0x52, 	/* 3BA70 */
+	0x01,  0xFE,  0x00,  0x20,  0x43,  0xFE,  0x20,  0x20,  0x27,  0xFF,  0x08,  0x88,  0x08,  0x50,  0x17,  0xFF, 	/* 3BA80 */
+	0x10,  0x20,  0x21,  0xFC,  0x20,  0x20,  0x40,  0x20,  0x40,  0x20,  0xAA,  0x10,  0x00,  0x0B,  0xFE,  0x08, 	/* 3BA90 */
+	0x20,  0x07,  0xFF,  0x04,  0x21,  0x45,  0xAD,  0x24,  0x21,  0x21,  0xAC,  0x08,  0x50,  0x09,  0x8C,  0x16, 	/* 3BAA0 */
+	0x73,  0x10,  0x00,  0x23,  0xFE,  0x20,  0x22,  0x40,  0x2C,  0x40,  0x20,  0xB1,  0x20,  0x00,  0x17,  0xDC, 	/* 3BAB0 */
+	0x14,  0x54,  0x04,  0x55,  0x47,  0xD5,  0x25,  0x53,  0x25,  0x60,  0x07,  0xC0,  0x05,  0x7E,  0x15,  0x52, 	/* 3BAC0 */
+	0x17,  0xEA,  0x24,  0x0C,  0x29,  0x84,  0x29,  0x4C,  0x52,  0x12,  0x44,  0x61,  0xB3,  0x10,  0x20,  0x08, 	/* 3BAD0 */
+	0x40,  0x0B,  0xFE,  0x02,  0x12,  0x02,  0xE2,  0x42,  0xAA,  0x22,  0x72,  0x23,  0xFE,  0x0A,  0x6A,  0x0B, 	/* 3BAE0 */
+	0xA6,  0x10,  0x20,  0x17,  0xFF,  0x20,  0x50,  0x20,  0x88,  0x43,  0x04,  0x4C,  0x03,  0xB9,  0x10,  0x40, 	/* 3BAF0 */
+	0x08,  0xF8,  0x09,  0x10,  0x07,  0xFF,  0x02,  0x29,  0x42,  0xC7,  0x23,  0x7C,  0x22,  0x00,  0x0B,  0xFF, 	/* 3BB00 */
+	0x0A,  0x00,  0x12,  0x7C,  0x12,  0x00,  0x24,  0xFE,  0x24,  0x82,  0x48,  0xFE,  0x40,  0x00,  0x80,  0x21, 	/* 3BB10 */
+	0x10,  0x12,  0x10,  0x17,  0x90,  0x04,  0x9F,  0x07,  0x94,  0x44,  0xA4,  0x27,  0xA4,  0x21,  0x54,  0x0F, 	/* 3BB20 */
+	0xD4,  0x12,  0x18,  0x13,  0x88,  0x12,  0x88,  0x24,  0x94,  0x24,  0x94,  0x4B,  0x22,  0x50,  0x41,  0x81, 	/* 3BB30 */
+	0x10,  0x00,  0x0F,  0xFC,  0x0C,  0xA4,  0x04,  0xA4,  0x47,  0xFC,  0x21,  0x00,  0x21,  0xFE,  0x01,  0x42, 	/* 3BB40 */
+	0x0B,  0xFA,  0x0B,  0x4A,  0x15,  0xFA,  0x10,  0x62,  0x20,  0x52,  0x20,  0xFA,  0x47,  0x0A,  0x40,  0x0C, 	/* 3BB50 */
+	0x82,  0x10,  0x10,  0x08,  0x10,  0x0B,  0xFF,  0x02,  0x24,  0x02,  0x48,  0x43,  0xFF,  0x22,  0x28,  0x22, 	/* 3BB60 */
+	0xFE,  0x0A,  0x2A,  0x0B,  0xFF,  0x12,  0x2A,  0x12,  0xFE,  0x24,  0x6C,  0x24,  0xAA,  0x49,  0x29,  0x40, 	/* 3BB70 */
+	0x28,  0x83,  0x10,  0x50,  0x0B,  0xFE,  0x0A,  0x52,  0x03,  0xFE,  0x42,  0x52,  0x23,  0xFE,  0x20,  0x00, 	/* 3BB80 */
+	0x03,  0xFF,  0x0A,  0x00,  0x0A,  0xFE,  0x12,  0x00,  0x13,  0xFF,  0x24,  0xA2,  0x24,  0x94,  0x48,  0xCC, 	/* 3BB90 */
+	0x53,  0x03,  0x86,  0x10,  0x20,  0x09,  0xFE,  0x08,  0x20,  0x00,  0x88,  0x07,  0xFF,  0x40,  0x88,  0x20, 	/* 3BBA0 */
+	0x00,  0x21,  0xFC,  0x09,  0x04,  0x09,  0xFC,  0x11,  0x04,  0x11,  0xFC,  0x21,  0x04,  0x21,  0xFC,  0x40, 	/* 3BBB0 */
+	0xCC,  0x47,  0x02,  0x94,  0x10,  0x00,  0x0B,  0xFF,  0x09,  0x24,  0x02,  0x22,  0x07,  0xFF,  0x4A,  0x66, 	/* 3BBC0 */
+	0x23,  0xBA,  0x22,  0xAA,  0x0B,  0x76,  0x0A,  0x22,  0x12,  0x66,  0x13,  0xBA,  0x22,  0xAA,  0x23,  0x76, 	/* 3BBD0 */
+	0x42,  0x22,  0x42,  0x26,  0x95,  0x10,  0x00,  0x09,  0xFE,  0x09,  0x02,  0x01,  0xFE,  0x01,  0x02,  0x41, 	/* 3BBE0 */
+	0xFE,  0x20,  0x84,  0x20,  0x84,  0x0B,  0x5A,  0x08,  0x84,  0x11,  0x4A,  0x13,  0xFF,  0x20,  0x21,  0x22, 	/* 3BBF0 */
+	0x92,  0x42,  0x49,  0x44,  0x49,  0x98,  0x10,  0x20,  0x08,  0x20,  0x0F,  0xFF,  0x04,  0xA1,  0x06,  0x8A, 	/* 3BC00 */
+	0x42,  0x79,  0x24,  0x01,  0x23,  0xFE,  0x0A,  0x92,  0x0B,  0xFE,  0x10,  0x00,  0x17,  0xFF,  0x20,  0x20, 	/* 3BC10 */
+	0x20,  0x20,  0x40,  0x20,  0x40,  0x60,  0x9B,  0x10,  0x50,  0x0F,  0xFF,  0x08,  0x50,  0x03,  0xFE,  0x02, 	/* 3BC20 */
+	0x02,  0x42,  0xFA,  0x20,  0x00,  0x27,  0xFF,  0x08,  0x42,  0x08,  0xAC,  0x13,  0x28,  0x10,  0xD4,  0x23, 	/* 3BC30 */
+	0x34,  0x20,  0xD2,  0x47,  0x11,  0x40,  0x60,  0x9F,  0x10,  0x20,  0x08,  0x20,  0x0F,  0xFF,  0x00,  0x51, 	/* 3BC40 */
+	0x07,  0xAE,  0x42,  0xAA,  0x22,  0xAA,  0x25,  0xAD,  0x00,  0x20,  0x09,  0x04,  0x11,  0xFC,  0x11,  0x04, 	/* 3BC50 */
+	0x21,  0xFC,  0x21,  0x04,  0x42,  0x04,  0x44,  0x04,  0xA0,  0x10,  0x20,  0x0F,  0xFF,  0x08,  0x00,  0x01, 	/* 3BC60 */
+	0xFC,  0x41,  0x04,  0x21,  0xFC,  0x20,  0x00,  0x03,  0xFF,  0x0A,  0x01,  0x0A,  0xFD,  0x10,  0x22,  0x10, 	/* 3BC70 */
+	0xD4,  0x23,  0x38,  0x20,  0xD4,  0x47,  0x13,  0x40,  0x30,  0xA1,  0x20,  0x00,  0x13,  0xFC,  0x10,  0x40, 	/* 3BC80 */
+	0x07,  0xFE,  0x44,  0x42,  0x25,  0xDA,  0x24,  0x42,  0x01,  0xD8,  0x08,  0x00,  0x0F,  0xFF,  0x10,  0x40, 	/* 3BC90 */
+	0x13,  0xFE,  0x22,  0x52,  0x22,  0x52,  0x42,  0x52,  0x42,  0x06,  0xA4,  0x10,  0x20,  0x0B,  0xFE,  0x08, 	/* 3BCA0 */
+	0x20,  0x01,  0xFC,  0x00,  0x00,  0x47,  0xFF,  0x20,  0x02,  0x21,  0xF8,  0x08,  0x20,  0x0F,  0xFF,  0x10, 	/* 3BCB0 */
+	0x04,  0x13,  0xFF,  0x22,  0x64,  0x22,  0x54,  0x43,  0xC4,  0x40,  0x0C,  0xAB,  0x20,  0x10,  0x17,  0xD0, 	/* 3BCC0 */
+	0x15,  0x10,  0x07,  0xDF,  0x04,  0x60,  0x47,  0xC0,  0x25,  0x1E,  0x25,  0x00,  0x0F,  0xC0,  0x08,  0x00, 	/* 3BCD0 */
+	0x13,  0xFC,  0x12,  0x94,  0x22,  0x94,  0x22,  0x94,  0x4F,  0xFF,  0x40,  0x00,  0xAC,  0x10,  0x20,  0x08, 	/* 3BCE0 */
+	0x3E,  0x08,  0x20,  0x07,  0xFF,  0x04,  0x01,  0x45,  0xFD,  0x21,  0x24,  0x22,  0x52,  0x09,  0xFC,  0x0B, 	/* 3BCF0 */
+	0x06,  0x15,  0xFD,  0x11,  0x04,  0x21,  0xFC,  0x21,  0x04,  0x41,  0xFC,  0x40,  0x00,  0xAE,  0x21,  0x28, 	/* 3BD00 */
+	0x11,  0xA9,  0x11,  0x6A,  0x02,  0x28,  0x03,  0xFF,  0x46,  0x44,  0x26,  0x28,  0x2B,  0xFF,  0x02,  0x10, 	/* 3BD10 */
+	0x12,  0xFE,  0x12,  0x10,  0x23,  0xFF,  0x22,  0x18,  0x22,  0x24,  0x42,  0xC2,  0x43,  0x01,  0xAF,  0x10, 	/* 3BD20 */
+	0x00,  0x0F,  0xDF,  0x08,  0x41,  0x03,  0xCF,  0x40,  0x41,  0x27,  0xDF,  0x20,  0x88,  0x00,  0x90,  0x09, 	/* 3BD30 */
+	0xFE,  0x0B,  0x20,  0x15,  0xFC,  0x11,  0x20,  0x21,  0xFC,  0x21,  0x20,  0x41,  0xFF,  0x40,  0x00,  0xB1, 	/* 3BD40 */
+	0x10,  0x20,  0x0B,  0xFE,  0x0A,  0x02,  0x01,  0xFE,  0x00,  0xA4,  0x41,  0x28,  0x22,  0x70,  0x21,  0xFC, 	/* 3BD50 */
+	0x07,  0x04,  0x11,  0xFC,  0x11,  0x04,  0x21,  0xFC,  0x21,  0x04,  0x21,  0xFC,  0x40,  0xCC,  0x47,  0x02, 	/* 3BD60 */
+	0xB3,  0x21,  0x08,  0x15,  0x28,  0x17,  0xFE,  0x05,  0x28,  0x01,  0x08,  0x4F,  0xFF,  0x22,  0x94,  0x22, 	/* 3BD70 */
+	0xD5,  0x04,  0xA7,  0x0B,  0xFC,  0x12,  0x04,  0x13,  0xFC,  0x22,  0x04,  0x22,  0x04,  0x43,  0xFC,  0x40, 	/* 3BD80 */
+	0x00,  0xB6,  0x20,  0x00,  0x17,  0xBE,  0x14,  0xA2,  0x07,  0xBE,  0x04,  0xA2,  0x47,  0xBE,  0x24,  0x0A, 	/* 3BD90 */
+	0x24,  0xF2,  0x04,  0x22,  0x0D,  0xFE,  0x14,  0x22,  0x14,  0xFA,  0x24,  0x8A,  0x24,  0x8A,  0x44,  0xFA, 	/* 3BDA0 */
+	0x44,  0x06,  0xBA,  0x20,  0x14,  0x17,  0x92,  0x14,  0x97,  0x04,  0xF8,  0x07,  0x8A,  0x44,  0x9D,  0x24, 	/* 3BDB0 */
+	0xE3,  0x27,  0x95,  0x04,  0x92,  0x14,  0x8F,  0x17,  0xF8,  0x20,  0x0A,  0x25,  0x0C,  0x24,  0xB5,  0x48, 	/* 3BDC0 */
+	0xC3,  0x50,  0x01,  0xBE,  0x10,  0x20,  0x08,  0x3E,  0x08,  0x20,  0x03,  0xFF,  0x02,  0x5A,  0x43,  0xE2, 	/* 3BDD0 */
+	0x22,  0x7E,  0x22,  0xFC,  0x0A,  0xA4,  0x0A,  0xFC,  0x12,  0xA4,  0x12,  0xFC,  0x23,  0x52,  0x25,  0x51, 	/* 3BDE0 */
+	0x46,  0x45,  0x48,  0x3C,  0x81,  0x10,  0x88,  0x08,  0x50,  0x0B,  0xFE,  0x00,  0x20,  0x01,  0xFC,  0x40, 	/* 3BDF0 */
+	0x20,  0x27,  0xFF,  0x20,  0xA8,  0x09,  0xFC,  0x0B,  0x0A,  0x15,  0xF9,  0x11,  0x08,  0x21,  0xFA,  0x21, 	/* 3BE00 */
+	0x24,  0x41,  0xD8,  0x47,  0x07,  0x89,  0x10,  0x20,  0x08,  0x20,  0x0F,  0xFF,  0x04,  0x41,  0x05,  0x9D, 	/* 3BE10 */
+	0x41,  0x04,  0x21,  0xDC,  0x21,  0x04,  0x09,  0xFC,  0x08,  0x80,  0x11,  0xFE,  0x16,  0x12,  0x23,  0x4A, 	/* 3BE20 */
+	0x22,  0xAA,  0x44,  0xA2,  0x40,  0x0C,  0x8B,  0x10,  0x20,  0x08,  0x20,  0x0F,  0xFF,  0x04,  0x0D,  0x07, 	/* 3BE30 */
+	0xF1,  0x41,  0x24,  0x20,  0xA8,  0x27,  0xFF,  0x00,  0xA8,  0x09,  0x24,  0x17,  0xFF,  0x12,  0x22,  0x23, 	/* 3BE40 */
+	0xFE,  0x22,  0x22,  0x43,  0xFE,  0x40,  0x00,  0x8F,  0x21,  0x02,  0x16,  0x7A,  0x14,  0x2A,  0x05,  0x2A, 	/* 3BE50 */
+	0x07,  0x4A,  0x44,  0x9A,  0x21,  0x4A,  0x22,  0x2A,  0x05,  0xDA,  0x10,  0x8A,  0x13,  0xEA,  0x24,  0xA2, 	/* 3BE60 */
+	0x22,  0xC2,  0x22,  0xE2,  0x41,  0x82,  0x46,  0x06,  0x91,  0x10,  0x00,  0x09,  0xFC,  0x09,  0x04,  0x01, 	/* 3BE70 */
+	0xFC,  0x01,  0x04,  0x41,  0xFC,  0x20,  0x88,  0x23,  0xFE,  0x08,  0x88,  0x0F,  0xFF,  0x11,  0x24,  0x13, 	/* 3BE80 */
+	0x2A,  0x24,  0xF1,  0x20,  0xA8,  0x43,  0x26,  0x40,  0x60,  0x95,  0x21,  0x00,  0x11,  0x7F,  0x15,  0x08, 	/* 3BE90 */
+	0x05,  0xD0,  0x45,  0x3E,  0x25,  0x22,  0x2F,  0xE2,  0x01,  0x3E,  0x05,  0xA2,  0x15,  0x7E,  0x15,  0x22, 	/* 3BEA0 */
+	0x2B,  0xA2,  0x20,  0xBE,  0x21,  0x14,  0x42,  0x22,  0x4C,  0xC1,  0x98,  0x10,  0x20,  0x08,  0x3E,  0x08, 	/* 3BEB0 */
+	0x20,  0x03,  0xFF,  0x02,  0x5A,  0x43,  0xE2,  0x22,  0xFE,  0x22,  0xA4,  0x0A,  0xFC,  0x0A,  0xA4,  0x12, 	/* 3BEC0 */
+	0xFC,  0x12,  0x00,  0x22,  0xFE,  0x24,  0xAA,  0x47,  0xFF,  0x48,  0x00,  0x9A,  0x22,  0x08,  0x12,  0x08, 	/* 3BED0 */
+	0x1F,  0xD4,  0x02,  0x14,  0x07,  0xA2,  0x44,  0xC1,  0x24,  0xFE,  0x27,  0x92,  0x04,  0xB6,  0x14,  0xDA, 	/* 3BEE0 */
+	0x17,  0x92,  0x22,  0x36,  0x3F,  0xB6,  0x22,  0x5A,  0x42,  0x12,  0x42,  0x36,  0x9B,  0x20,  0x20,  0x17, 	/* 3BEF0 */
+	0xFF,  0x12,  0x00,  0x01,  0xFE,  0x40,  0x00,  0x21,  0xFC,  0x21,  0x04,  0x01,  0xFC,  0x10,  0x40,  0x17, 	/* 3BF00 */
+	0x4E,  0x15,  0xFA,  0x27,  0x6A,  0x25,  0xAE,  0x27,  0xCA,  0x45,  0x6B,  0x49,  0x91,  0x9D,  0x10,  0x00, 	/* 3BF10 */
+	0x0B,  0xFF,  0x0A,  0x22,  0x02,  0xCC,  0x02,  0x44,  0x43,  0xFF,  0x22,  0x44,  0x22,  0xEE,  0x0B,  0x55, 	/* 3BF20 */
+	0x0A,  0x54,  0x12,  0x90,  0x14,  0x9E,  0x24,  0x90,  0x28,  0x90,  0x43,  0xFF,  0x40,  0x00,  0x9E,  0x22, 	/* 3BF30 */
+	0x10,  0x12,  0x1C,  0x1F,  0xA4,  0x02,  0x48,  0x4F,  0xBE,  0x22,  0x0A,  0x3F,  0xCA,  0x00,  0x7F,  0x07, 	/* 3BF40 */
+	0x8A,  0x14,  0x8A,  0x17,  0xBE,  0x24,  0x88,  0x27,  0x88,  0x24,  0x88,  0x44,  0x88,  0x45,  0x98,  0x9F, 	/* 3BF50 */
+	0x10,  0x88,  0x0F,  0xFF,  0x08,  0xA8,  0x01,  0xFC,  0x00,  0x24,  0x47,  0xFF,  0x20,  0x24,  0x21,  0xFC, 	/* 3BF60 */
+	0x08,  0x20,  0x0A,  0xAA,  0x12,  0xAA,  0x13,  0xFE,  0x22,  0x22,  0x23,  0xAE,  0x42,  0xAA,  0x44,  0xAA, 	/* 3BF70 */
+	0xA6,  0x20,  0x12,  0x1F,  0xD2,  0x12,  0x7E,  0x02,  0x14,  0x05,  0x54,  0x49,  0x98,  0x23,  0xFF,  0x25, 	/* 3BF80 */
+	0x10,  0x09,  0x7C,  0x03,  0xA4,  0x13,  0xA4,  0x15,  0x7C,  0x29,  0x64,  0x21,  0x24,  0x41,  0x3C,  0x46, 	/* 3BF90 */
+	0x00,  0xA7,  0x21,  0x10,  0x11,  0x10,  0x1F,  0xFF,  0x04,  0x50,  0x02,  0x9E,  0x4F,  0xE2,  0x20,  0x1E, 	/* 3BFA0 */
+	0x27,  0xD0,  0x04,  0x5F,  0x17,  0xD0,  0x14,  0x5F,  0x27,  0xD0,  0x24,  0x5F,  0x24,  0x50,  0x44,  0x51, 	/* 3BFB0 */
+	0x44,  0xCF,  0xAC,  0x21,  0x00,  0x11,  0x3F,  0x11,  0x04,  0x0F,  0xE8,  0x41,  0x1E,  0x27,  0xD2,  0x25, 	/* 3BFC0 */
+	0x52,  0x05,  0x5E,  0x15,  0x52,  0x17,  0xDE,  0x11,  0x12,  0x23,  0x92,  0x23,  0x5E,  0x25,  0x14,  0x49, 	/* 3BFD0 */
+	0x22,  0x41,  0x41,  0xB0,  0x20,  0x00,  0x1F,  0xFF,  0x12,  0x54,  0x02,  0x52,  0x02,  0xFF,  0x4F,  0xB6, 	/* 3BFE0 */
+	0x28,  0xB6,  0x28,  0xDA,  0x08,  0xB6,  0x0E,  0x92,  0x12,  0xB6,  0x12,  0xB6,  0x22,  0xDA,  0x22,  0xB6, 	/* 3BFF0 */
+	0x42,  0x92,  0x4C,  0x96,  0xB2,  0x21,  0x08,  0x11,  0x08,  0x12,  0x88,  0x04,  0x5F,  0x4B,  0x94,  0x20, 	/* 3C000 */
+	0x24,  0x2F,  0xC4,  0x0B,  0x54,  0x0B,  0x54,  0x1F,  0xD4,  0x10,  0x08,  0x24,  0x88,  0x24,  0x94,  0x26, 	/* 3C010 */
+	0xD4,  0x49,  0x22,  0x52,  0x41,  0xBE,  0x20,  0x00,  0x17,  0xBE,  0x14,  0xA2,  0x07,  0xBE,  0x04,  0xA2, 	/* 3C020 */
+	0x47,  0xBE,  0x24,  0x42,  0x25,  0xFA,  0x0C,  0x42,  0x0D,  0xFA,  0x15,  0xDA,  0x15,  0x6A,  0x25,  0xFA, 	/* 3C030 */
+	0x24,  0xD2,  0x45,  0x4A,  0x44,  0x46,  0x8C,  0x20,  0x88,  0x17,  0xFF,  0x10,  0x88,  0x03,  0xDE,  0x02, 	/* 3C040 */
+	0x52,  0x43,  0xDE,  0x20,  0x88,  0x20,  0x90,  0x09,  0xFE,  0x0B,  0x20,  0x15,  0xFC,  0x11,  0x20,  0x21, 	/* 3C050 */
+	0xFC,  0x21,  0x20,  0x41,  0xFE,  0x40,  0x00,  0x91,  0x27,  0xBE,  0x10,  0x00,  0x17,  0x9E,  0x04,  0x92, 	/* 3C060 */
+	0x45,  0x96,  0x20,  0x20,  0x27,  0xFF,  0x04,  0x50,  0x07,  0xFE,  0x0C,  0x52,  0x17,  0xFE,  0x15,  0x12, 	/* 3C070 */
+	0x25,  0xFC,  0x29,  0x10,  0x49,  0xD1,  0x53,  0x0F,  0x98,  0x12,  0x8A,  0x0A,  0x8A,  0x0F,  0xF4,  0x02, 	/* 3C080 */
+	0x9F,  0x47,  0xD4,  0x25,  0x74,  0x25,  0x54,  0x07,  0xDF,  0x01,  0x14,  0x17,  0xD4,  0x11,  0x1F,  0x2F, 	/* 3C090 */
+	0xF4,  0x22,  0x94,  0x22,  0x54,  0x44,  0x1F,  0x48,  0x00,  0xA3,  0x22,  0x22,  0x12,  0xFA,  0x1D,  0x05, 	/* 3C0A0 */
+	0x02,  0x72,  0x45,  0x05,  0x2F,  0x7F,  0x22,  0x52,  0x0B,  0x7B,  0x0A,  0x02,  0x03,  0xF8,  0x10,  0x08, 	/* 3C0B0 */
+	0x13,  0xF8,  0x22,  0x00,  0x23,  0xFC,  0x40,  0x04,  0x40,  0x38,  0xAB,  0x00,  0x80,  0x00,  0x80,  0x00, 	/* 3C0C0 */
+	0x84,  0x00,  0x84,  0x08,  0x84,  0x08,  0x88,  0x08,  0x88,  0x08,  0x90,  0x10,  0x80,  0x21,  0x40,  0x01, 	/* 3C0D0 */
+	0x40,  0x02,  0x20,  0x02,  0x10,  0x04,  0x08,  0x18,  0x04,  0x60,  0x03,  0xAF,  0x04,  0x00,  0x04,  0x00, 	/* 3C0E0 */
+	0x04,  0xFF,  0x04,  0x88,  0x14,  0x88,  0x15,  0x08,  0x15,  0x08,  0x24,  0x08,  0x04,  0x08,  0x06,  0x08, 	/* 3C0F0 */
+	0x09,  0x08,  0x09,  0x08,  0x10,  0x88,  0x10,  0x88,  0x20,  0x08,  0x40,  0x18,  0xB0,  0x00,  0x00,  0x1F, 	/* 3C100 */
+	0xFE,  0x10,  0x00,  0x10,  0x40,  0x10,  0x44,  0x12,  0x44,  0x12,  0x44,  0x12,  0x48,  0x14,  0x50,  0x14, 	/* 3C110 */
+	0x40,  0x10,  0xA0,  0x10,  0xA0,  0x21,  0x10,  0x22,  0x08,  0x4C,  0x04,  0x30,  0x03,  0xB8,  0x02,  0x00, 	/* 3C120 */
+	0x03,  0xF0,  0x04,  0x20,  0x18,  0x40,  0x00,  0xC0,  0x03,  0x20,  0x0C,  0x18,  0x70,  0x87,  0x04,  0x88, 	/* 3C130 */
+	0x04,  0x88,  0x08,  0x90,  0x11,  0x40,  0x02,  0x20,  0x04,  0x10,  0x18,  0x0C,  0x60,  0x03,  0xBC,  0x08, 	/* 3C140 */
+	0x40,  0x08,  0x40,  0x08,  0x40,  0x0A,  0x7E,  0x2A,  0x42,  0x2A,  0x82,  0x2C,  0x82,  0x29,  0x22,  0x48, 	/* 3C150 */
+	0x12,  0x08,  0x12,  0x0C,  0x02,  0x0A,  0x02,  0x11,  0x02,  0x11,  0x02,  0x20,  0x04,  0x40,  0x18,  0xBD, 	/* 3C160 */
+	0x08,  0x42,  0x08,  0x42,  0x10,  0x84,  0x21,  0x08,  0x10,  0x84,  0x08,  0x42,  0x08,  0x42,  0x00,  0x84, 	/* 3C170 */
+	0x08,  0x84,  0x08,  0x88,  0x09,  0x50,  0x11,  0x40,  0x02,  0x20,  0x04,  0x10,  0x08,  0x0C,  0x70,  0x03, 	/* 3C180 */
+	0x89,  0x08,  0x00,  0x08,  0xFF,  0x08,  0x00,  0x09,  0x00,  0x29,  0x7E,  0x2A,  0x42,  0x2A,  0x42,  0x28, 	/* 3C190 */
+	0x7E,  0x48,  0x40,  0x08,  0x40,  0x0C,  0x40,  0x0A,  0x40,  0x11,  0x80,  0x10,  0x80,  0x21,  0x00,  0x42, 	/* 3C1A0 */
+	0x00,  0x8A,  0x08,  0x40,  0x08,  0x40,  0x08,  0x40,  0x0A,  0x7F,  0x2A,  0x42,  0x2A,  0x94,  0x2C,  0x90, 	/* 3C1B0 */
+	0x29,  0x10,  0x48,  0x10,  0x0C,  0x18,  0x0A,  0x28,  0x09,  0x28,  0x11,  0x24,  0x10,  0x44,  0x20,  0x82, 	/* 3C1C0 */
+	0x41,  0x01,  0x8E,  0x01,  0x00,  0x09,  0x10,  0x09,  0x10,  0x11,  0x20,  0x22,  0x80,  0x04,  0x40,  0x18, 	/* 3C1D0 */
+	0x30,  0x61,  0x0C,  0x01,  0x10,  0x09,  0x10,  0x09,  0x20,  0x12,  0x80,  0x22,  0x40,  0x04,  0x20,  0x18, 	/* 3C1E0 */
+	0x18,  0x60,  0x06,  0x92,  0x08,  0x10,  0x08,  0x10,  0x08,  0x10,  0x0A,  0x54,  0x2A,  0x52,  0x2C,  0x52, 	/* 3C1F0 */
+	0x2C,  0x91,  0x28,  0x91,  0x49,  0x14,  0x08,  0x14,  0x0C,  0x34,  0x0A,  0x08,  0x11,  0x08,  0x11,  0x10, 	/* 3C200 */
+	0x20,  0x60,  0x41,  0x80,  0x99,  0x00,  0x40,  0x00,  0xFC,  0x03,  0x08,  0x3C,  0x90,  0x02,  0x60,  0x01, 	/* 3C210 */
+	0x80,  0x0E,  0x00,  0x70,  0x00,  0x00,  0x84,  0x08,  0x84,  0x08,  0x88,  0x09,  0x50,  0x11,  0x40,  0x22, 	/* 3C220 */
+	0x20,  0x0C,  0x18,  0x70,  0x07,  0xAC,  0x08,  0x00,  0x08,  0xFF,  0x08,  0x80,  0x0A,  0x80,  0x0A,  0x80, 	/* 3C230 */
+	0x2C,  0xFE,  0x2C,  0x82,  0x28,  0x82,  0x48,  0x82,  0x08,  0xFE,  0x0C,  0x80,  0x0A,  0x80,  0x11,  0x80, 	/* 3C240 */
+	0x10,  0x80,  0x20,  0xFF,  0x40,  0x00,  0xAD,  0x00,  0x80,  0x10,  0x84,  0x10,  0x84,  0x1F,  0xFC,  0x00, 	/* 3C250 */
+	0x00,  0x1F,  0xFF,  0x10,  0x00,  0x10,  0x44,  0x12,  0x44,  0x12,  0x48,  0x12,  0x50,  0x14,  0x40,  0x20, 	/* 3C260 */
+	0xA0,  0x21,  0x10,  0x46,  0x0C,  0x18,  0x03,  0xAE,  0x08,  0x40,  0x08,  0x40,  0x08,  0x7E,  0x0A,  0x42, 	/* 3C270 */
+	0x2A,  0x82,  0x2C,  0xF2,  0x2D,  0x92,  0x28,  0x92,  0x48,  0x92,  0x08,  0xF2,  0x0C,  0x84,  0x0A,  0x98, 	/* 3C280 */
+	0x12,  0x81,  0x10,  0x81,  0x20,  0x41,  0x40,  0x3F,  0xAF,  0x08,  0x00,  0x09,  0xFE,  0x09,  0x02,  0x0B, 	/* 3C290 */
+	0x02,  0x2B,  0x02,  0x2D,  0x7A,  0x2D,  0x4A,  0x29,  0x4A,  0x49,  0x4A,  0x09,  0x4A,  0x0D,  0x7A,  0x0D, 	/* 3C2A0 */
+	0x02,  0x13,  0x02,  0x13,  0x02,  0x21,  0x02,  0x41,  0x06,  0xB3,  0x08,  0x00,  0x09,  0xFF,  0x08,  0x10, 	/* 3C2B0 */
+	0x0A,  0x10,  0x0A,  0xFE,  0x2C,  0x92,  0x2C,  0x92,  0x28,  0x9A,  0x48,  0xAA,  0x08,  0xA6,  0x0C,  0xC2, 	/* 3C2C0 */
+	0x0A,  0x82,  0x12,  0x82,  0x11,  0x82,  0x20,  0x82,  0x40,  0x86,  0xB8,  0x08,  0x40,  0x08,  0x40,  0x08, 	/* 3C2D0 */
+	0x40,  0x0A,  0x7F,  0x0A,  0x50,  0x2C,  0x90,  0x2C,  0x90,  0x29,  0x1E,  0x28,  0x10,  0x48,  0x10,  0x0C, 	/* 3C2E0 */
+	0x10,  0x0A,  0x1E,  0x11,  0x10,  0x10,  0x10,  0x20,  0x10,  0x40,  0x10,  0xB9,  0x00,  0x80,  0x00,  0x80, 	/* 3C2F0 */
+	0x00,  0x80,  0x00,  0xFE,  0x00,  0x80,  0x00,  0x80,  0x0F,  0xF8,  0x08,  0x08,  0x08,  0x08,  0x08,  0x08, 	/* 3C300 */
+	0x0F,  0xF8,  0x00,  0x00,  0x10,  0x08,  0x12,  0x44,  0x21,  0x22,  0x41,  0x22,  0xBA,  0x10,  0x80,  0x08, 	/* 3C310 */
+	0x80,  0x08,  0x80,  0x3F,  0xF8,  0x01,  0x08,  0x01,  0x10,  0x03,  0xFC,  0x02,  0x04,  0x04,  0x04,  0x0F, 	/* 3C320 */
+	0xFF,  0x08,  0x01,  0x14,  0x91,  0x32,  0x49,  0x49,  0x29,  0x09,  0x21,  0x08,  0x06,  0x88,  0x00,  0x04, 	/* 3C330 */
+	0x7F,  0xA4,  0x08,  0x24,  0x08,  0x24,  0x0F,  0x24,  0x11,  0x24,  0x12,  0x24,  0x2A,  0x24,  0x44,  0x24, 	/* 3C340 */
+	0x08,  0x04,  0x10,  0x04,  0x20,  0x0C,  0x10,  0x00,  0x14,  0x44,  0x22,  0x22,  0x42,  0x21,  0x8B,  0x08, 	/* 3C350 */
+	0x40,  0x08,  0x40,  0x08,  0x40,  0x1F,  0xFE,  0x10,  0xE0,  0x30,  0xE0,  0x51,  0x50,  0x12,  0x48,  0x14, 	/* 3C360 */
+	0x44,  0x18,  0x42,  0x10,  0x40,  0x00,  0x00,  0x10,  0x04,  0x12,  0x22,  0x21,  0x11,  0x41,  0x11,  0x8F, 	/* 3C370 */
+	0x00,  0x80,  0x01,  0x00,  0x1F,  0xF0,  0x10,  0x10,  0x10,  0x10,  0x10,  0x10,  0x1F,  0xF0,  0x10,  0x00, 	/* 3C380 */
+	0x1F,  0xFF,  0x10,  0x00,  0x1F,  0xFE,  0x00,  0x22,  0x29,  0x12,  0x24,  0x92,  0x24,  0x84,  0x40,  0x18, 	/* 3C390 */
+	0x99,  0x08,  0x20,  0x08,  0x20,  0x08,  0x7C,  0x0A,  0x44,  0x2A,  0xA8,  0x2D,  0x10,  0x28,  0x28,  0x48, 	/* 3C3A0 */
+	0x44,  0x08,  0x83,  0x0D,  0xFC,  0x16,  0x84,  0x12,  0x84,  0x12,  0x84,  0x20,  0x84,  0x20,  0xFC,  0x40, 	/* 3C3B0 */
+	0x00,  0x9D,  0x00,  0x00,  0x1F,  0xF0,  0x00,  0x20,  0x00,  0xC4,  0x3E,  0x84,  0x02,  0xC8,  0x04,  0xA0, 	/* 3C3C0 */
+	0x18,  0x98,  0x60,  0x87,  0x01,  0x80,  0x00,  0x00,  0x7F,  0xFF,  0x10,  0x00,  0x12,  0x22,  0x21,  0x11, 	/* 3C3D0 */
+	0x41,  0x11,  0x9F,  0x08,  0x00,  0x09,  0xFE,  0x09,  0x02,  0x0B,  0x22,  0x0B,  0x22,  0x2D,  0xFE,  0x2D, 	/* 3C3E0 */
+	0x22,  0x29,  0x22,  0x49,  0x32,  0x09,  0x52,  0x0D,  0x4A,  0x0B,  0x86,  0x13,  0x02,  0x11,  0x02,  0x21, 	/* 3C3F0 */
+	0xFE,  0x40,  0x00,  0xB1,  0x08,  0x00,  0x09,  0xFE,  0x09,  0x2A,  0x0B,  0x2A,  0x2B,  0x2A,  0x2D,  0x4E, 	/* 3C400 */
+	0x2D,  0x42,  0x29,  0x82,  0x49,  0x7A,  0x09,  0x4A,  0x0D,  0x4A,  0x0D,  0x4A,  0x13,  0x7A,  0x13,  0x02, 	/* 3C410 */
+	0x21,  0x02,  0x41,  0x06,  0xB9,  0x00,  0x80,  0x00,  0x80,  0x7F,  0xFF,  0x00,  0x00,  0x07,  0xF0,  0x04, 	/* 3C420 */
+	0x10,  0x07,  0xF0,  0x00,  0x00,  0x3F,  0xFC,  0x00,  0x30,  0x00,  0xC0,  0x00,  0x80,  0x11,  0x88,  0x12, 	/* 3C430 */
+	0x24,  0x21,  0x12,  0x41,  0x12,  0xBD,  0x08,  0x20,  0x08,  0x3C,  0x08,  0x44,  0x0A,  0xC8,  0x0B,  0x30, 	/* 3C440 */
+	0x2A,  0x28,  0x2C,  0xC4,  0x2B,  0x13,  0x28,  0x10,  0x48,  0xFE,  0x0C,  0x10,  0x0A,  0xFE,  0x12,  0x10, 	/* 3C450 */
+	0x11,  0xFF,  0x20,  0x10,  0x40,  0x10,  0x89,  0x00,  0x00,  0x3F,  0xFE,  0x00,  0x80,  0x08,  0x80,  0x08, 	/* 3C460 */
+	0xFC,  0x08,  0x80,  0x08,  0x80,  0x7F,  0xFF,  0x04,  0x00,  0x07,  0xFC,  0x04,  0x00,  0x07,  0xFE,  0x29, 	/* 3C470 */
+	0x22,  0x24,  0x92,  0x24,  0x82,  0x40,  0x0C,  0x94,  0x08,  0x20,  0x08,  0x20,  0x08,  0x3C,  0x0A,  0x44, 	/* 3C480 */
+	0x2A,  0x48,  0x2A,  0x88,  0x2C,  0x10,  0x29,  0x3E,  0x49,  0x22,  0x0D,  0x22,  0x15,  0x22,  0x13,  0x3E, 	/* 3C490 */
+	0x13,  0x22,  0x21,  0x22,  0x21,  0x3E,  0x41,  0x22,  0x99,  0x08,  0x20,  0x08,  0x20,  0x09,  0xFE,  0x0A, 	/* 3C4A0 */
+	0x84,  0x2A,  0x44,  0x2C,  0x48,  0x28,  0x48,  0x4B,  0xFF,  0x08,  0x00,  0x08,  0x00,  0x14,  0xFC,  0x12, 	/* 3C4B0 */
+	0x84,  0x12,  0x84,  0x20,  0x84,  0x20,  0xFC,  0x40,  0x00,  0x9A,  0x04,  0x10,  0x04,  0x10,  0x7F,  0xFF, 	/* 3C4C0 */
+	0x04,  0x10,  0x0E,  0x38,  0x15,  0x54,  0x24,  0x92,  0x44,  0x11,  0x00,  0x80,  0x08,  0x88,  0x08,  0x88, 	/* 3C4D0 */
+	0x10,  0x90,  0x21,  0x40,  0x02,  0x20,  0x0C,  0x18,  0x70,  0x07,  0x9C,  0x08,  0x00,  0x08,  0xFE,  0x08, 	/* 3C4E0 */
+	0x82,  0x0A,  0x82,  0x2A,  0xFE,  0x2A,  0x82,  0x2C,  0x82,  0x28,  0xFE,  0x48,  0x00,  0x08,  0x88,  0x0C, 	/* 3C4F0 */
+	0x8A,  0x0A,  0xEC,  0x12,  0x88,  0x10,  0x89,  0x20,  0xE9,  0x41,  0x87,  0xA1,  0x08,  0x00,  0x08,  0x00, 	/* 3C500 */
+	0x0F,  0xFE,  0x19,  0x48,  0x19,  0x48,  0x29,  0x48,  0x7F,  0xFE,  0x09,  0x48,  0x09,  0x48,  0x09,  0x48, 	/* 3C510 */
+	0x7F,  0xFF,  0x00,  0x00,  0x12,  0x48,  0x12,  0x24,  0x21,  0x12,  0x41,  0x12,  0xA6,  0x04,  0x40,  0x04, 	/* 3C520 */
+	0x80,  0x0F,  0xFC,  0x08,  0x80,  0x18,  0x80,  0x2F,  0xF8,  0x48,  0x80,  0x0F,  0xF8,  0x08,  0x80,  0x08, 	/* 3C530 */
+	0x80,  0x0F,  0xFC,  0x00,  0x00,  0x10,  0x08,  0x12,  0x44,  0x21,  0x22,  0x41,  0x22,  0xB6,  0x04,  0x10, 	/* 3C540 */
+	0x04,  0x14,  0x0F,  0x92,  0x08,  0x92,  0x11,  0xFF,  0x25,  0x10,  0x52,  0x28,  0x0A,  0x28,  0x04,  0x44, 	/* 3C550 */
+	0x18,  0x82,  0x63,  0x01,  0x00,  0x00,  0x12,  0x48,  0x11,  0x24,  0x21,  0x22,  0x40,  0x02,  0xBC,  0x08, 	/* 3C560 */
+	0x10,  0x08,  0x10,  0x08,  0xFE,  0x0A,  0x10,  0x2A,  0x54,  0x2A,  0x44,  0x2D,  0xFF,  0x28,  0x44,  0x48, 	/* 3C570 */
+	0x44,  0x08,  0x00,  0x0D,  0xFF,  0x0A,  0x28,  0x12,  0x28,  0x10,  0x49,  0x20,  0x89,  0x41,  0x07,  0x89, 	/* 3C580 */
+	0x08,  0x10,  0x08,  0x10,  0x09,  0xFF,  0x0A,  0x10,  0x2A,  0xFE,  0x2C,  0x92,  0x28,  0xFE,  0x28,  0x92, 	/* 3C590 */
+	0x48,  0x92,  0x08,  0xFE,  0x0C,  0x38,  0x0A,  0x54,  0x11,  0x52,  0x10,  0x91,  0x21,  0x10,  0x40,  0x10, 	/* 3C5A0 */
+	0x8C,  0x08,  0x20,  0x08,  0x40,  0x08,  0xFC,  0x0A,  0x84,  0x0A,  0xFC,  0x2A,  0x84,  0x2C,  0x84,  0x28, 	/* 3C5B0 */
+	0xFC,  0x28,  0x00,  0x49,  0xFE,  0x0C,  0x20,  0x0A,  0xFC,  0x12,  0x20,  0x10,  0x20,  0x23,  0xFF,  0x40, 	/* 3C5C0 */
+	0x00,  0x8E,  0x04,  0x08,  0x02,  0x10,  0x7F,  0xFF,  0x00,  0x00,  0x1F,  0x22,  0x11,  0x22,  0x1F,  0x22, 	/* 3C5D0 */
+	0x11,  0x22,  0x1F,  0x22,  0x11,  0x02,  0x11,  0x02,  0x13,  0x06,  0x00,  0x00,  0x12,  0x24,  0x21,  0x12, 	/* 3C5E0 */
+	0x41,  0x11,  0x95,  0x00,  0x00,  0x3F,  0xBE,  0x22,  0x22,  0x2A,  0x22,  0x2B,  0xA2,  0x28,  0xA2,  0x28, 	/* 3C5F0 */
+	0xBE,  0x2B,  0xA0,  0x2A,  0x21,  0x22,  0x21,  0x3F,  0x9F,  0x00,  0x00,  0x10,  0x00,  0x12,  0x44,  0x21, 	/* 3C600 */
+	0x22,  0x41,  0x21,  0x96,  0x08,  0x04,  0x08,  0x18,  0x09,  0xE4,  0x08,  0x52,  0x0A,  0x49,  0x2A,  0x89, 	/* 3C610 */
+	0x2D,  0xFC,  0x2C,  0x40,  0x29,  0xFF,  0x48,  0x40,  0x0C,  0x7C,  0x0A,  0xA4,  0x12,  0x98,  0x11,  0x10, 	/* 3C620 */
+	0x22,  0x6C,  0x41,  0x83,  0x99,  0x08,  0x00,  0x0B,  0xFE,  0x08,  0x50,  0x0A,  0x50,  0x2B,  0xFC,  0x2B, 	/* 3C630 */
+	0x54,  0x2D,  0x54,  0x29,  0x54,  0x49,  0xFC,  0x08,  0x20,  0x0C,  0x20,  0x14,  0xFC,  0x12,  0x20,  0x12, 	/* 3C640 */
+	0x20,  0x23,  0xFF,  0x40,  0x00,  0xA2,  0x08,  0x10,  0x2A,  0x54,  0x2A,  0x54,  0x4C,  0x98,  0x12,  0x24, 	/* 3C650 */
+	0x20,  0x40,  0x7F,  0xFE,  0x40,  0x02,  0x40,  0x02,  0x3F,  0xF8,  0x02,  0x08,  0x02,  0x08,  0x3F,  0xE8, 	/* 3C660 */
+	0x02,  0x09,  0x02,  0x05,  0x02,  0x03,  0xA4,  0x08,  0x44,  0x08,  0x44,  0x09,  0xFF,  0x0A,  0x44,  0x2A, 	/* 3C670 */
+	0x7C,  0x2A,  0x44,  0x2C,  0x44,  0x28,  0x7C,  0x48,  0x10,  0x09,  0xFF,  0x0C,  0x38,  0x0A,  0x34,  0x11, 	/* 3C680 */
+	0x54,  0x10,  0x92,  0x21,  0x11,  0x40,  0x10,  0xA5,  0x08,  0x20,  0x08,  0x38,  0x08,  0x48,  0x0A,  0x90, 	/* 3C690 */
+	0x0B,  0xFE,  0x2A,  0xAA,  0x2C,  0xAA,  0x28,  0xAA,  0x28,  0xCE,  0x48,  0x92,  0x0C,  0x10,  0x0B,  0xFF, 	/* 3C6A0 */
+	0x12,  0x28,  0x10,  0x44,  0x20,  0x82,  0x43,  0x01,  0xA6,  0x00,  0x80,  0x3C,  0x80,  0x24,  0xFE,  0x25, 	/* 3C6B0 */
+	0x02,  0x25,  0x02,  0x3E,  0xF2,  0x24,  0x92,  0x24,  0x92,  0x24,  0xF2,  0x24,  0x02,  0x3C,  0x02,  0x00, 	/* 3C6C0 */
+	0x0C,  0x10,  0x00,  0x12,  0x24,  0x21,  0x12,  0x41,  0x11,  0xA7,  0x00,  0x00,  0x3F,  0xFE,  0x22,  0x22, 	/* 3C6D0 */
+	0x22,  0x22,  0x22,  0x42,  0x3E,  0x8C,  0x23,  0x00,  0x22,  0xFE,  0x22,  0x82,  0x22,  0x82,  0x3E,  0x82, 	/* 3C6E0 */
+	0x00,  0xFE,  0x10,  0x00,  0x12,  0x24,  0x21,  0x12,  0x41,  0x11,  0xA9,  0x08,  0x00,  0x09,  0xFF,  0x08, 	/* 3C6F0 */
+	0x10,  0x0A,  0x20,  0x2A,  0xFE,  0x2A,  0x82,  0x2C,  0x82,  0x48,  0xFE,  0x08,  0x82,  0x0C,  0xFE,  0x14, 	/* 3C700 */
+	0x82,  0x12,  0x82,  0x12,  0xFE,  0x20,  0x24,  0x20,  0xC2,  0x43,  0x01,  0xAC,  0x08,  0x00,  0x08,  0xF8, 	/* 3C710 */
+	0x08,  0x88,  0x0A,  0xF8,  0x2A,  0x88,  0x2C,  0x88,  0x2C,  0xF8,  0x28,  0x00,  0x4B,  0xFF,  0x08,  0x40, 	/* 3C720 */
+	0x0C,  0xFE,  0x0B,  0x2A,  0x12,  0x4A,  0x10,  0x92,  0x21,  0x22,  0x40,  0x0C,  0xAE,  0x00,  0x82,  0x00, 	/* 3C730 */
+	0x82,  0x1F,  0xFC,  0x00,  0x88,  0x00,  0xB0,  0x7F,  0xFF,  0x01,  0x00,  0x07,  0xF8,  0x1C,  0x08,  0x67, 	/* 3C740 */
+	0xF8,  0x04,  0x08,  0x07,  0xF8,  0x10,  0x08,  0x12,  0x44,  0x21,  0x22,  0x41,  0x22,  0xBD,  0x08,  0x00, 	/* 3C750 */
+	0x0B,  0xFF,  0x08,  0x00,  0x0A,  0xFE,  0x2A,  0x82,  0x2A,  0x82,  0x2C,  0xFE,  0x48,  0x80,  0x08,  0xFF, 	/* 3C760 */
+	0x0C,  0x91,  0x0A,  0x99,  0x13,  0x55,  0x11,  0x33,  0x12,  0x55,  0x24,  0x99,  0x40,  0x33,  0x84,  0x08, 	/* 3C770 */
+	0x20,  0x08,  0x40,  0x08,  0xFE,  0x0A,  0x82,  0x2A,  0xFE,  0x2A,  0x82,  0x2C,  0xFE,  0x28,  0x82,  0x48, 	/* 3C780 */
+	0x82,  0x08,  0xFE,  0x0C,  0x10,  0x0A,  0xA8,  0x12,  0xAA,  0x11,  0x21,  0x22,  0x25,  0x40,  0x1C,  0x88, 	/* 3C790 */
+	0x00,  0x00,  0x27,  0xDE,  0x25,  0x12,  0x25,  0x12,  0x27,  0xD2,  0x24,  0x52,  0x24,  0x5E,  0x27,  0xD0, 	/* 3C7A0 */
+	0x25,  0x11,  0x25,  0x11,  0x27,  0xCF,  0x40,  0x00,  0x10,  0x04,  0x12,  0x22,  0x21,  0x11,  0x41,  0x11, 	/* 3C7B0 */
+	0x8A,  0x08,  0x40,  0x12,  0x44,  0x7F,  0x78,  0x00,  0xC2,  0x3E,  0x42,  0x22,  0x3E,  0x3E,  0x00,  0x22, 	/* 3C7C0 */
+	0x44,  0x3E,  0x78,  0x22,  0x42,  0x22,  0x42,  0x26,  0x3E,  0x10,  0x08,  0x14,  0x44,  0x22,  0x22,  0x42, 	/* 3C7D0 */
+	0x22,  0x8F,  0x00,  0x18,  0x0F,  0xE0,  0x00,  0x80,  0x7F,  0xFF,  0x00,  0x80,  0x0F,  0xF8,  0x0C,  0x98, 	/* 3C7E0 */
+	0x0A,  0xA8,  0x0A,  0xC8,  0x0F,  0xF8,  0x00,  0x80,  0x1F,  0xFC,  0x00,  0x80,  0x7F,  0xFF,  0x12,  0x24, 	/* 3C7F0 */
+	0x21,  0x12,  0x94,  0x08,  0x10,  0x08,  0x10,  0x09,  0xFF,  0x09,  0x01,  0x0B,  0x49,  0x2A,  0x44,  0x2C, 	/* 3C800 */
+	0x92,  0x29,  0x12,  0x48,  0x28,  0x08,  0x44,  0x0C,  0x82,  0x0B,  0xFD,  0x12,  0x84,  0x10,  0x84,  0x20, 	/* 3C810 */
+	0xFC,  0x40,  0x84,  0x95,  0x08,  0x00,  0x08,  0xFE,  0x08,  0x10,  0x0A,  0x10,  0x2B,  0xFF,  0x2A,  0x00, 	/* 3C820 */
+	0x2C,  0x7E,  0x28,  0x42,  0x48,  0x7E,  0x08,  0x42,  0x0C,  0x7E,  0x0A,  0x42,  0x12,  0x7E,  0x10,  0x24, 	/* 3C830 */
+	0x20,  0xC2,  0x43,  0x01,  0x99,  0x00,  0x00,  0x3F,  0xBE,  0x24,  0x22,  0x24,  0x22,  0x2F,  0x22,  0x29, 	/* 3C840 */
+	0x22,  0x29,  0x3E,  0x2F,  0x20,  0x24,  0x20,  0x24,  0x21,  0x3F,  0xA1,  0x00,  0x1F,  0x14,  0x44,  0x12, 	/* 3C850 */
+	0x22,  0x21,  0x11,  0x41,  0x11,  0x9F,  0x04,  0x10,  0x7F,  0x90,  0x1E,  0x10,  0x12,  0xFC,  0x1E,  0x14, 	/* 3C860 */
+	0x00,  0x94,  0x3E,  0x54,  0x05,  0x24,  0x0E,  0x25,  0x74,  0x55,  0x04,  0x93,  0x0D,  0x01,  0x10,  0x04, 	/* 3C870 */
+	0x14,  0x42,  0x22,  0x21,  0x42,  0x21,  0xA8,  0x00,  0x04,  0x1F,  0x84,  0x10,  0x84,  0x1F,  0xFF,  0x10, 	/* 3C880 */
+	0x04,  0x1F,  0xA4,  0x10,  0x14,  0x2F,  0x94,  0x2B,  0x04,  0x52,  0x8C,  0x06,  0x00,  0x00,  0x88,  0x04, 	/* 3C890 */
+	0x90,  0x19,  0x40,  0x06,  0x30,  0x78,  0x0F,  0xAC,  0x04,  0x10,  0x04,  0x10,  0x3F,  0x1F,  0x04,  0x24, 	/* 3C8A0 */
+	0x3F,  0x24,  0x04,  0x54,  0x7F,  0x94,  0x08,  0x08,  0x0F,  0x08,  0x11,  0x14,  0x21,  0x22,  0x46,  0xC1, 	/* 3C8B0 */
+	0x10,  0x00,  0x14,  0x44,  0x22,  0x22,  0x42,  0x21,  0xB1,  0x04,  0x10,  0x04,  0x10,  0x3F,  0x90,  0x04, 	/* 3C8C0 */
+	0x7C,  0x7F,  0x94,  0x12,  0x14,  0x25,  0x74,  0x5F,  0x94,  0x04,  0x2C,  0x07,  0xC5,  0x78,  0x83,  0x00, 	/* 3C8D0 */
+	0x00,  0x14,  0x88,  0x12,  0x44,  0x21,  0x22,  0x41,  0x22,  0xB9,  0x00,  0x80,  0x3F,  0xFE,  0x00,  0x80, 	/* 3C8E0 */
+	0x0F,  0xF8,  0x00,  0x00,  0x0F,  0xF8,  0x08,  0x08,  0x0F,  0xF8,  0x02,  0x20,  0x7F,  0xFF,  0x00,  0x00, 	/* 3C8F0 */
+	0x0F,  0xF8,  0x08,  0x08,  0x0F,  0xFC,  0x12,  0x22,  0x61,  0x11,  0xBE,  0x08,  0x88,  0x08,  0x8C,  0x0B, 	/* 3C900 */
+	0xEA,  0x0A,  0x2A,  0x2D,  0x28,  0x2D,  0x48,  0x2F,  0xFF,  0x28,  0x0A,  0x49,  0xEA,  0x09,  0x2A,  0x0D, 	/* 3C910 */
+	0x2C,  0x0B,  0xE5,  0x11,  0x2D,  0x11,  0x2B,  0x21,  0xF3,  0x40,  0x21,  0x83,  0x09,  0x08,  0x09,  0x0A, 	/* 3C920 */
+	0x09,  0xC9,  0x09,  0x7F,  0x29,  0x48,  0x2A,  0xC8,  0x2E,  0x8C,  0x29,  0x94,  0x49,  0x12,  0x0A,  0x22, 	/* 3C930 */
+	0x0C,  0x41,  0x0A,  0x00,  0x13,  0x52,  0x11,  0x52,  0x22,  0x49,  0x44,  0x49,  0x88,  0x09,  0xD4,  0x08, 	/* 3C940 */
+	0x54,  0x0A,  0x49,  0x09,  0x8A,  0x2C,  0x84,  0x2D,  0xFA,  0x2A,  0x01,  0x4D,  0xFC,  0x09,  0x04,  0x09, 	/* 3C950 */
+	0x04,  0x0D,  0xFC,  0x14,  0x88,  0x12,  0x48,  0x10,  0x50,  0x23,  0xFF,  0x40,  0x00,  0x89,  0x10,  0x88, 	/* 3C960 */
+	0x10,  0x88,  0x17,  0xE8,  0x10,  0x1F,  0x35,  0xD2,  0x35,  0x6A,  0x39,  0x4A,  0x51,  0xCA,  0x50,  0x0A, 	/* 3C970 */
+	0x13,  0xE4,  0x18,  0x44,  0x14,  0xEC,  0x17,  0x8C,  0x24,  0x92,  0x20,  0xA2,  0x41,  0xC1,  0x8E,  0x08, 	/* 3C980 */
+	0x10,  0x08,  0x10,  0x09,  0xFF,  0x0A,  0x28,  0x2A,  0xAA,  0x2C,  0x44,  0x2C,  0xFE,  0x29,  0x45,  0x4A, 	/* 3C990 */
+	0x7C,  0x08,  0x44,  0x0C,  0x7C,  0x0A,  0x90,  0x12,  0x94,  0x11,  0x12,  0x22,  0x11,  0x40,  0x30,  0x90, 	/* 3C9A0 */
+	0x08,  0x92,  0x08,  0x52,  0x08,  0x54,  0x0B,  0xFF,  0x2A,  0x38,  0x2A,  0x54,  0x2D,  0x93,  0x28,  0x90, 	/* 3C9B0 */
+	0x48,  0x84,  0x08,  0xDF,  0x0D,  0x54,  0x0B,  0x54,  0x12,  0xBF,  0x10,  0x84,  0x21,  0x04,  0x42,  0x04, 	/* 3C9C0 */
+	0x92,  0x08,  0x10,  0x08,  0xFC,  0x08,  0x10,  0x0B,  0xFF,  0x2A,  0x44,  0x2C,  0x44,  0x2D,  0xEF,  0x28, 	/* 3C9D0 */
+	0x44,  0x48,  0x64,  0x09,  0x9F,  0x0C,  0x00,  0x0B,  0xFF,  0x12,  0x48,  0x10,  0x49,  0x20,  0x89,  0x43, 	/* 3C9E0 */
+	0x07,  0x94,  0x08,  0x04,  0x08,  0x18,  0x09,  0xE4,  0x0A,  0xA4,  0x2A,  0x68,  0x2B,  0xFF,  0x2C,  0x68, 	/* 3C9F0 */
+	0x28,  0xA4,  0x49,  0xFE,  0x0A,  0xA5,  0x0C,  0xA4,  0x0A,  0xFC,  0x12,  0xA4,  0x10,  0xA4,  0x20,  0xFC, 	/* 3CA00 */
+	0x40,  0x00,  0x95,  0x02,  0x20,  0x02,  0x20,  0x7F,  0xFF,  0x02,  0x20,  0x0B,  0xE8,  0x08,  0x0A,  0x7B, 	/* 3CA10 */
+	0xEA,  0x0A,  0x2C,  0x0A,  0x28,  0x1A,  0x29,  0x6B,  0xE9,  0x08,  0x07,  0x00,  0x00,  0x12,  0x24,  0x21, 	/* 3CA20 */
+	0x12,  0x41,  0x11,  0x97,  0x10,  0x00,  0x13,  0xDE,  0x12,  0x52,  0x13,  0xDE,  0x16,  0x52,  0x36,  0x52, 	/* 3CA30 */
+	0x3B,  0xDE,  0x32,  0x02,  0x52,  0x7A,  0x52,  0x4A,  0x12,  0x7A,  0x1A,  0x4A,  0x16,  0x7A,  0x22,  0x4A, 	/* 3CA40 */
+	0x22,  0x9A,  0x42,  0x06,  0x9F,  0x08,  0x10,  0x2A,  0x54,  0x2A,  0x54,  0x54,  0xA8,  0x22,  0x44,  0x7F, 	/* 3CA50 */
+	0xFE,  0x40,  0x02,  0x4F,  0xF2,  0x08,  0x10,  0x0F,  0xF0,  0x01,  0x00,  0x1F,  0xF8,  0x10,  0x08,  0x10, 	/* 3CA60 */
+	0x08,  0x1F,  0xF8,  0x00,  0x00,  0xA0,  0x08,  0x10,  0x08,  0x20,  0x08,  0xFE,  0x0A,  0x8A,  0x2A,  0xF6, 	/* 3CA70 */
+	0x2C,  0xDA,  0x2C,  0xFE,  0x28,  0x92,  0x48,  0xBA,  0x08,  0xD6,  0x0C,  0x10,  0x0B,  0xFF,  0x12,  0x10, 	/* 3CA80 */
+	0x10,  0x28,  0x20,  0xC4,  0x43,  0x03,  0xA5,  0x08,  0x00,  0x08,  0x78,  0x08,  0x48,  0x0A,  0x48,  0x2A, 	/* 3CA90 */
+	0x78,  0x2B,  0xDE,  0x2D,  0x52,  0x29,  0x52,  0x49,  0xDE,  0x0C,  0x20,  0x15,  0xFE,  0x12,  0x70,  0x12, 	/* 3CAA0 */
+	0xA8,  0x21,  0x24,  0x22,  0x22,  0x40,  0x20,  0xA6,  0x11,  0x00,  0x11,  0xDE,  0x11,  0x02,  0x15,  0xD4, 	/* 3CAB0 */
+	0x16,  0x48,  0x35,  0x54,  0x38,  0xA2,  0x51,  0x25,  0x56,  0xA4,  0x10,  0xA8,  0x1B,  0xFF,  0x14,  0x70, 	/* 3CAC0 */
+	0x14,  0xA8,  0x21,  0x24,  0x22,  0x23,  0x40,  0x20,  0xA7,  0x12,  0x3C,  0x11,  0x24,  0x11,  0x24,  0x14, 	/* 3CAD0 */
+	0x42,  0x16,  0xFD,  0x35,  0x22,  0x39,  0xD2,  0x38,  0x2C,  0x57,  0x4C,  0x51,  0x1A,  0x11,  0x2A,  0x19, 	/* 3CAE0 */
+	0x49,  0x15,  0x88,  0x22,  0xB0,  0x22,  0x60,  0x44,  0x1F,  0xAC,  0x10,  0x80,  0x11,  0x1C,  0x13,  0xD4, 	/* 3CAF0 */
+	0x16,  0x55,  0x37,  0xD5,  0x3A,  0x63,  0x3A,  0x40,  0x53,  0xFE,  0x50,  0x92,  0x10,  0x92,  0x13,  0xD4, 	/* 3CB00 */
+	0x18,  0x8C,  0x14,  0xC8,  0x21,  0x94,  0x26,  0x22,  0x40,  0x41,  0xAD,  0x08,  0x00,  0x09,  0xFE,  0x09, 	/* 3CB10 */
+	0x52,  0x09,  0x52,  0x2B,  0xFE,  0x2A,  0x80,  0x2C,  0xFE,  0x29,  0x22,  0x49,  0xFA,  0x0A,  0xAA,  0x08, 	/* 3CB20 */
+	0xFA,  0x14,  0x32,  0x12,  0x2A,  0x20,  0x3A,  0x21,  0xC6,  0x40,  0x0C,  0xAE,  0x10,  0x04,  0x13,  0xC4, 	/* 3CB30 */
+	0x34,  0x0D,  0x37,  0xED,  0x38,  0x0E,  0x53,  0xD4,  0x18,  0x06,  0x17,  0xCA,  0x22,  0x4A,  0x23,  0xD1, 	/* 3CB40 */
+	0x40,  0x20,  0x3F,  0xF8,  0x06,  0x30,  0x01,  0xC0,  0x07,  0x30,  0x78,  0x0F,  0xB5,  0x12,  0x10,  0x11, 	/* 3CB50 */
+	0x10,  0x11,  0x7E,  0x14,  0x10,  0x16,  0xFF,  0x35,  0x44,  0x39,  0x28,  0x30,  0x7E,  0x57,  0x10,  0x51, 	/* 3CB60 */
+	0x7E,  0x11,  0x10,  0x19,  0xFF,  0x15,  0x10,  0x22,  0x90,  0x24,  0x60,  0x48,  0x1F,  0xB9,  0x00,  0x00, 	/* 3CB70 */
+	0x7F,  0x7F,  0x08,  0x08,  0x11,  0x11,  0x6A,  0x6A,  0x16,  0x16,  0x6D,  0x6D,  0x15,  0x15,  0x64,  0x64, 	/* 3CB80 */
+	0x18,  0x98,  0x00,  0x80,  0x08,  0x88,  0x09,  0x50,  0x12,  0x20,  0x0C,  0x18,  0x70,  0x07,  0xBB,  0x08, 	/* 3CB90 */
+	0x04,  0x08,  0xF8,  0x08,  0x20,  0x0B,  0xFF,  0x0A,  0x20,  0x2A,  0xFC,  0x2C,  0xAC,  0x28,  0xEC,  0x28, 	/* 3CBA0 */
+	0xB4,  0x48,  0xFC,  0x0C,  0x20,  0x0A,  0xFE,  0x12,  0x20,  0x13,  0xFF,  0x21,  0x52,  0x42,  0x29,  0xBC, 	/* 3CBB0 */
+	0x08,  0x10,  0x08,  0xFE,  0x08,  0x12,  0x0B,  0xFF,  0x2A,  0x12,  0x2C,  0xFE,  0x2C,  0x10,  0x29,  0xFF, 	/* 3CBC0 */
+	0x48,  0xAA,  0x09,  0x15,  0x0C,  0x00,  0x0A,  0xFE,  0x12,  0xAA,  0x10,  0xAA,  0x23,  0xFF,  0x40,  0x00, 	/* 3CBD0 */
+	0xBF,  0x08,  0x00,  0x09,  0xFE,  0x08,  0x22,  0x08,  0xEE,  0x0A,  0x22,  0x2B,  0xFE,  0x2C,  0x44,  0x28, 	/* 3CBE0 */
+	0x88,  0x29,  0xFE,  0x4A,  0x90,  0x0C,  0xFC,  0x0A,  0x90,  0x12,  0xFC,  0x10,  0x90,  0x20,  0xFF,  0x40, 	/* 3CBF0 */
+	0x00,  0x86,  0x08,  0xFC,  0x08,  0x84,  0x08,  0xFC,  0x0A,  0x84,  0x2A,  0xFC,  0x2A,  0x48,  0x2D,  0xFE, 	/* 3CC00 */
+	0x28,  0x48,  0x4B,  0xFF,  0x08,  0x48,  0x14,  0xA4,  0x13,  0xAB,  0x12,  0x70,  0x20,  0xA8,  0x23,  0x26, 	/* 3CC10 */
+	0x40,  0x60,  0x8D,  0x08,  0x92,  0x08,  0xA2,  0x08,  0xBA,  0x09,  0x2C,  0x0B,  0x6D,  0x2A,  0xBA,  0x2C, 	/* 3CC20 */
+	0xAA,  0x29,  0x7D,  0x49,  0xD7,  0x08,  0x10,  0x09,  0xFF,  0x0C,  0x38,  0x12,  0x54,  0x10,  0x93,  0x21, 	/* 3CC30 */
+	0x10,  0x40,  0x10,  0x90,  0x08,  0x10,  0x08,  0x1E,  0x08,  0x10,  0x09,  0xFF,  0x0B,  0x3A,  0x2B,  0xE2, 	/* 3CC40 */
+	0x2D,  0x7E,  0x29,  0x54,  0x29,  0x7C,  0x49,  0x54,  0x0D,  0x7C,  0x0B,  0x00,  0x12,  0xFE,  0x12,  0xAA, 	/* 3CC50 */
+	0x25,  0xFF,  0x40,  0x00,  0x9B,  0x10,  0x00,  0x13,  0xDE,  0x12,  0x52,  0x13,  0xDE,  0x16,  0x52,  0x37, 	/* 3CC60 */
+	0xDE,  0x3A,  0x22,  0x33,  0xFE,  0x52,  0x22,  0x52,  0xFA,  0x1A,  0xEA,  0x16,  0xBA,  0x12,  0xFA,  0x22, 	/* 3CC70 */
+	0x72,  0x22,  0xAA,  0x42,  0x26,  0xA8,  0x0B,  0xEE,  0x32,  0x22,  0x3F,  0xEE,  0x23,  0x62,  0x3B,  0xEE, 	/* 3CC80 */
+	0x22,  0x26,  0x7F,  0xFF,  0x44,  0x11,  0x3F,  0x7E,  0x16,  0x34,  0x25,  0x52,  0x7F,  0xFF,  0x0C,  0x98, 	/* 3CC90 */
+	0x73,  0x67,  0x06,  0x30,  0x38,  0x0E,  0xAA,  0x00,  0x08,  0x00,  0x70,  0x1F,  0x80,  0x10,  0x10,  0x11, 	/* 3CCA0 */
+	0x10,  0x11,  0x10,  0x11,  0x10,  0x11,  0x10,  0x11,  0x10,  0x11,  0x10,  0x11,  0x10,  0x11,  0x08,  0x11, 	/* 3CCB0 */
+	0x08,  0x21,  0x04,  0x21,  0x04,  0x41,  0x02,  0xAC,  0x01,  0x00,  0x02,  0x00,  0x3C,  0x7E,  0x22,  0x52, 	/* 3CCC0 */
+	0x2A,  0x52,  0x2A,  0x52,  0x2A,  0x7E,  0x2A,  0x40,  0x2A,  0x40,  0x2A,  0x40,  0x29,  0x42,  0x29,  0x22, 	/* 3CCD0 */
+	0x28,  0x9E,  0x48,  0x40,  0x48,  0x30,  0x88,  0x0F,  0xAD,  0x00,  0x08,  0x00,  0x70,  0x1F,  0x84,  0x08, 	/* 3CCE0 */
+	0x42,  0x08,  0x42,  0x17,  0xF8,  0x20,  0x88,  0x00,  0x88,  0x7F,  0xFF,  0x00,  0x88,  0x00,  0x88,  0x0F, 	/* 3CCF0 */
+	0xF8,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x01,  0x80,  0xB0,  0x00,  0x08,  0x00,  0x70,  0x1F,  0x84, 	/* 3CD00 */
+	0x08,  0x42,  0x08,  0x42,  0x17,  0xFC,  0x21,  0x00,  0x01,  0x00,  0x7F,  0xFF,  0x01,  0x00,  0x03,  0xF8, 	/* 3CD10 */
+	0x06,  0x10,  0x19,  0xA0,  0x60,  0xE0,  0x03,  0x18,  0x1C,  0x07,  0xB2,  0x00,  0x10,  0x00,  0xE0,  0x3F, 	/* 3CD20 */
+	0x08,  0x10,  0x84,  0x10,  0x82,  0x27,  0xE2,  0x44,  0x20,  0x07,  0xF8,  0x04,  0x08,  0x04,  0x08,  0x0F, 	/* 3CD30 */
+	0xFE,  0x08,  0x12,  0x12,  0x4A,  0x29,  0x2A,  0x49,  0x22,  0x10,  0x0C,  0xB5,  0x00,  0x0C,  0x7F,  0xF0, 	/* 3CD40 */
+	0x11,  0x04,  0x08,  0x88,  0x3F,  0xFE,  0x22,  0x22,  0x3F,  0xFE,  0x00,  0x04,  0x3F,  0x04,  0x21,  0x7F, 	/* 3CD50 */
+	0x3F,  0x04,  0x21,  0x24,  0x3F,  0x14,  0x22,  0x04,  0x3D,  0x04,  0x60,  0x8C,  0xB6,  0x02,  0x20,  0x02, 	/* 3CD60 */
+	0x10,  0x04,  0x08,  0x04,  0x04,  0x08,  0x04,  0x14,  0x12,  0x64,  0x10,  0x02,  0x10,  0x02,  0x20,  0x01, 	/* 3CD70 */
+	0x20,  0x01,  0x40,  0x00,  0x80,  0x01,  0x40,  0x02,  0x20,  0x0C,  0x18,  0x70,  0x07,  0xBA,  0x02,  0x20, 	/* 3CD80 */
+	0x0C,  0x18,  0x32,  0x26,  0x01,  0xC0,  0x07,  0x60,  0x78,  0x1F,  0x00,  0x00,  0x7F,  0xFE,  0x11,  0x22, 	/* 3CD90 */
+	0x1F,  0x24,  0x11,  0x28,  0x1F,  0x24,  0x11,  0x22,  0x1F,  0x32,  0x71,  0x2C,  0x01,  0x20,  0xBB,  0x00, 	/* 3CDA0 */
+	0x10,  0x1C,  0x20,  0x03,  0x40,  0x00,  0xC0,  0x01,  0x30,  0x06,  0x08,  0x18,  0x04,  0x60,  0x10,  0x04, 	/* 3CDB0 */
+	0x10,  0x04,  0x20,  0x02,  0x20,  0x01,  0x40,  0x00,  0x80,  0x03,  0x60,  0x0C,  0x18,  0x70,  0x07,  0xBC, 	/* 3CDC0 */
+	0x02,  0x00,  0x02,  0x7C,  0x34,  0x44,  0x0C,  0x44,  0x0C,  0x44,  0x12,  0x7C,  0x21,  0x44,  0x40,  0x44, 	/* 3CDD0 */
+	0x02,  0x44,  0x02,  0x7C,  0x34,  0x44,  0x0C,  0x44,  0x0C,  0x44,  0x12,  0x44,  0x23,  0xFF,  0x40,  0x00, 	/* 3CDE0 */
+	0xBD,  0x00,  0x80,  0x00,  0x80,  0x7F,  0xFF,  0x02,  0x82,  0x1A,  0x9A,  0x04,  0x84,  0x3A,  0xBA,  0x00, 	/* 3CDF0 */
+	0x80,  0x1A,  0x9A,  0x04,  0x84,  0x0D,  0x4C,  0x33,  0x72,  0x02,  0x20,  0x04,  0x10,  0x18,  0x0C,  0x60, 	/* 3CE00 */
+	0x03,  0xBE,  0x00,  0x00,  0x7F,  0xFF,  0x08,  0x88,  0x10,  0x84,  0x7F,  0xFF,  0x20,  0x82,  0x2A,  0xAA, 	/* 3CE10 */
+	0x24,  0x92,  0x3A,  0xEA,  0x20,  0x82,  0x22,  0x8A,  0x3A,  0xEA,  0x24,  0x92,  0x2A,  0xAA,  0x30,  0xC2, 	/* 3CE20 */
+	0x20,  0x86,  0xBF,  0x00,  0x08,  0x04,  0x08,  0x04,  0x08,  0x04,  0x08,  0x04,  0x08,  0x07,  0xF8,  0x00, 	/* 3CE30 */
+	0x08,  0x00,  0x08,  0x3F,  0xF8,  0x02,  0x08,  0x02,  0x08,  0x02,  0x08,  0x04,  0x08,  0x04,  0x08,  0x08, 	/* 3CE40 */
+	0x08,  0x10,  0x08,  0x80,  0x04,  0x20,  0x24,  0x20,  0x24,  0x20,  0x24,  0x20,  0x27,  0xFF,  0x3C,  0x20, 	/* 3CE50 */
+	0x04,  0x70,  0x04,  0x70,  0x7C,  0xA8,  0x24,  0xA8,  0x25,  0x24,  0x26,  0x22,  0x24,  0x21,  0x44,  0x20, 	/* 3CE60 */
+	0x04,  0x20,  0x04,  0x20,  0x86,  0x04,  0x20,  0x04,  0x20,  0x25,  0xFF,  0x24,  0xA4,  0x24,  0xA4,  0x3D, 	/* 3CE70 */
+	0x6A,  0x07,  0xFF,  0x04,  0x00,  0x7D,  0xFE,  0x25,  0x02,  0x25,  0x7A,  0x25,  0x4A,  0x25,  0x7A,  0x45, 	/* 3CE80 */
+	0x02,  0x05,  0xFE,  0x04,  0x00,  0x87,  0x08,  0x40,  0x08,  0x40,  0x08,  0x40,  0x08,  0x40,  0x0F,  0xFE, 	/* 3CE90 */
+	0x08,  0x00,  0x08,  0x00,  0x08,  0x00,  0x0F,  0xF0,  0x08,  0x10,  0x08,  0x10,  0x10,  0x10,  0x10,  0x10, 	/* 3CEA0 */
+	0x20,  0x10,  0x40,  0x10,  0x00,  0x10,  0x88,  0x12,  0x00,  0x12,  0x7F,  0x12,  0x40,  0x12,  0x40,  0x12, 	/* 3CEB0 */
+	0x40,  0x1F,  0xFE,  0x10,  0x62,  0x10,  0x62,  0x1E,  0x52,  0x12,  0x54,  0x12,  0x54,  0x12,  0x48,  0x12, 	/* 3CEC0 */
+	0x4C,  0x22,  0x94,  0x22,  0xA2,  0x43,  0x41,  0x8B,  0x24,  0x28,  0x24,  0x24,  0x24,  0x1E,  0x25,  0xF0, 	/* 3CED0 */
+	0x24,  0x14,  0x3E,  0x19,  0x20,  0x67,  0x21,  0xA9,  0x3C,  0x24,  0x24,  0x3F,  0x25,  0xD2,  0x24,  0x14, 	/* 3CEE0 */
+	0x24,  0x19,  0x24,  0x65,  0x25,  0x83,  0x44,  0x01,  0x8C,  0x12,  0x10,  0x12,  0x20,  0x12,  0xFE,  0x12, 	/* 3CEF0 */
+	0x92,  0x12,  0x92,  0x1F,  0xFE,  0x10,  0x92,  0x10,  0x92,  0x10,  0xFE,  0x1E,  0x24,  0x12,  0x44,  0x13, 	/* 3CF00 */
+	0xFF,  0x12,  0x04,  0x22,  0x04,  0x22,  0x04,  0x42,  0x04,  0x92,  0x24,  0x94,  0x24,  0x94,  0x25,  0xFF, 	/* 3CF10 */
+	0x24,  0x94,  0x24,  0x94,  0x3E,  0x9C,  0x20,  0x80,  0x20,  0xFE,  0x3C,  0x20,  0x27,  0xFF,  0x24,  0x70, 	/* 3CF20 */
+	0x24,  0x68,  0x24,  0xA4,  0x25,  0x22,  0x26,  0x21,  0x44,  0x20,  0x98,  0x24,  0x10,  0x25,  0xFF,  0x24, 	/* 3CF30 */
+	0x10,  0x24,  0xFE,  0x24,  0x00,  0x3F,  0xFF,  0x21,  0x29,  0x21,  0xFF,  0x3C,  0x82,  0x24,  0xFE,  0x24, 	/* 3CF40 */
+	0x82,  0x24,  0xFE,  0x24,  0x82,  0x24,  0xFE,  0x24,  0x46,  0x45,  0x81,  0x99,  0x00,  0x00,  0x07,  0xFC, 	/* 3CF50 */
+	0x04,  0x10,  0x04,  0x10,  0x04,  0x10,  0x04,  0x10,  0x04,  0x10,  0x7F,  0xFF,  0x00,  0x50,  0x00,  0x90, 	/* 3CF60 */
+	0x01,  0x10,  0x02,  0x10,  0x04,  0x10,  0x18,  0x10,  0x60,  0x10,  0x00,  0x30,  0x9B,  0x00,  0x80,  0x04, 	/* 3CF70 */
+	0x80,  0x04,  0x80,  0x04,  0x80,  0x0F,  0xFC,  0x08,  0x80,  0x10,  0x80,  0x20,  0x80,  0x00,  0x80,  0x7F, 	/* 3CF80 */
+	0xFF,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x9D,  0x04,  0x40, 	/* 3CF90 */
+	0x14,  0x40,  0x14,  0x40,  0x14,  0x44,  0x1F,  0x44,  0x24,  0x48,  0x24,  0x50,  0x44,  0x60,  0x07,  0x40, 	/* 3CFA0 */
+	0x0C,  0x40,  0x74,  0x40,  0x04,  0x40,  0x04,  0x42,  0x04,  0x42,  0x04,  0x22,  0x04,  0x1E,  0x9F,  0x01, 	/* 3CFB0 */
+	0x00,  0x01,  0x20,  0x02,  0x18,  0x3F,  0xF4,  0x00,  0x82,  0x08,  0x80,  0x08,  0x80,  0x0F,  0xF8,  0x10, 	/* 3CFC0 */
+	0x80,  0x20,  0x80,  0x00,  0x80,  0x7F,  0xFF,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0xA1, 	/* 3CFD0 */
+	0x04,  0x10,  0x14,  0x10,  0x14,  0x10,  0x14,  0x10,  0x1F,  0x10,  0x14,  0xFE,  0x24,  0x10,  0x44,  0x10, 	/* 3CFE0 */
+	0x04,  0x10,  0x07,  0x10,  0x3C,  0x10,  0x04,  0x10,  0x04,  0x10,  0x04,  0x10,  0x05,  0xFF,  0x04,  0x00, 	/* 3CFF0 */
+	0xA2,  0x01,  0x00,  0x01,  0x00,  0x7F,  0xFE,  0x40,  0x02,  0x49,  0x02,  0x09,  0x00,  0x09,  0x00,  0x1F, 	/* 3D000 */
+	0xFC,  0x11,  0x00,  0x21,  0x00,  0x01,  0x00,  0x7F,  0xFE,  0x01,  0x00,  0x01,  0x00,  0x01,  0x00,  0x01, 	/* 3D010 */
+	0x00,  0xA7,  0x04,  0x40,  0x14,  0x40,  0x14,  0x40,  0x14,  0x7F,  0x1F,  0x44,  0x24,  0x44,  0x44,  0x84, 	/* 3D020 */
+	0x04,  0x84,  0x07,  0x28,  0x1C,  0x28,  0x64,  0x10,  0x04,  0x10,  0x04,  0x28,  0x04,  0x44,  0x04,  0x82, 	/* 3D030 */
+	0x05,  0x01,  0xA9,  0x04,  0x40,  0x14,  0x40,  0x14,  0x40,  0x14,  0x7E,  0x1F,  0xAA,  0x24,  0xAA,  0x24, 	/* 3D040 */
+	0xAA,  0x45,  0x2A,  0x05,  0x4A,  0x06,  0x52,  0x3C,  0x92,  0x05,  0x22,  0x04,  0x22,  0x04,  0x42,  0x04, 	/* 3D050 */
+	0x04,  0x04,  0x18,  0xB2,  0x04,  0x10,  0x14,  0x90,  0x14,  0x90,  0x14,  0x90,  0x1E,  0xFE,  0x24,  0x90, 	/* 3D060 */
+	0x25,  0x10,  0x45,  0x10,  0x06,  0x10,  0x0D,  0xFE,  0x34,  0x10,  0x04,  0x10,  0x04,  0x10,  0x04,  0x10, 	/* 3D070 */
+	0x07,  0xFF,  0x04,  0x00,  0xB4,  0x08,  0x02,  0x28,  0x0C,  0x28,  0xF8,  0x28,  0x88,  0x3E,  0x88,  0x28, 	/* 3D080 */
+	0x88,  0x48,  0xFF,  0x08,  0x88,  0x0E,  0x88,  0x18,  0x88,  0x68,  0x84,  0x08,  0xE5,  0x0B,  0x05,  0x08, 	/* 3D090 */
+	0x03,  0x0B,  0xFB,  0x08,  0x01,  0xB9,  0x04,  0x10,  0x24,  0x10,  0x25,  0xFE,  0x24,  0x10,  0x3F,  0x10, 	/* 3D0A0 */
+	0x24,  0x10,  0x27,  0xFF,  0x44,  0x04,  0x06,  0x04,  0x1D,  0xFF,  0x64,  0x44,  0x04,  0x24,  0x04,  0x24, 	/* 3D0B0 */
+	0x04,  0x04,  0x04,  0x04,  0x04,  0x0C,  0xBD,  0x01,  0x00,  0x01,  0x00,  0x3F,  0xFC,  0x06,  0x60,  0x03, 	/* 3D0C0 */
+	0x80,  0x7F,  0xFE,  0x42,  0x42,  0x44,  0x32,  0x1F,  0xE8,  0x09,  0x00,  0x0F,  0xF0,  0x11,  0x00,  0x21, 	/* 3D0D0 */
+	0x00,  0x7F,  0xFE,  0x01,  0x00,  0x01,  0x00,  0xBE,  0x08,  0x00,  0x0B,  0xFF,  0x28,  0x20,  0x28,  0x20, 	/* 3D0E0 */
+	0x3E,  0xFC,  0x28,  0x44,  0x48,  0x44,  0x08,  0x44,  0x0B,  0xFF,  0x0C,  0x00,  0x18,  0xFC,  0x68,  0x84, 	/* 3D0F0 */
+	0x08,  0x84,  0x08,  0x84,  0x08,  0xFC,  0x08,  0x00,  0x80,  0x00,  0x00,  0x1F,  0xFE,  0x10,  0x02,  0x10, 	/* 3D100 */
+	0x02,  0x1F,  0xFE,  0x10,  0x40,  0x17,  0x5C,  0x10,  0x40,  0x17,  0x5C,  0x10,  0x00,  0x12,  0x40,  0x13, 	/* 3D110 */
+	0xFC,  0x24,  0x40,  0x2F,  0xFF,  0x40,  0x40,  0x00,  0x40,  0x81,  0x01,  0x04,  0x3E,  0x24,  0x04,  0x24, 	/* 3D120 */
+	0x04,  0x24,  0x7F,  0xA4,  0x0E,  0x24,  0x15,  0x04,  0x24,  0x04,  0x44,  0x8C,  0x04,  0x80,  0x07,  0xF8, 	/* 3D130 */
+	0x08,  0x80,  0x10,  0x80,  0x7F,  0xFF,  0x00,  0x80,  0x00,  0x80,  0x82,  0x01,  0x20,  0x3E,  0x20,  0x04, 	/* 3D140 */
+	0x3E,  0x7F,  0x4A,  0x04,  0x8A,  0x0E,  0x12,  0x15,  0x22,  0x24,  0x42,  0x04,  0x0C,  0x08,  0x80,  0x0F, 	/* 3D150 */
+	0xFC,  0x08,  0x80,  0x10,  0x80,  0x7F,  0xFF,  0x00,  0x80,  0x00,  0x80,  0x87,  0x04,  0x80,  0x04,  0x80, 	/* 3D160 */
+	0x0F,  0xF8,  0x10,  0x80,  0x00,  0x80,  0x7F,  0xFF,  0x00,  0x80,  0x28,  0xA8,  0x28,  0x28,  0x3E,  0x3E, 	/* 3D170 */
+	0x48,  0x48,  0x08,  0x08,  0x0F,  0xFF,  0x78,  0x08,  0x08,  0x08,  0x08,  0x08,  0x92,  0x08,  0x20,  0x28, 	/* 3D180 */
+	0x20,  0x2B,  0xFF,  0x28,  0x00,  0x3E,  0xFC,  0x28,  0x84,  0x48,  0xFC,  0x08,  0x00,  0x0F,  0xFE,  0x19, 	/* 3D190 */
+	0x02,  0x69,  0x7A,  0x09,  0x4A,  0x09,  0x4A,  0x09,  0x7A,  0x09,  0x02,  0x09,  0x06,  0x96,  0x08,  0x10, 	/* 3D1A0 */
+	0x2A,  0x54,  0x2A,  0x54,  0x4C,  0x98,  0x12,  0x24,  0x20,  0x40,  0x7F,  0xFE,  0x40,  0x82,  0x48,  0x82, 	/* 3D1B0 */
+	0x0F,  0xF8,  0x10,  0x80,  0x20,  0x80,  0x7F,  0xFF,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0xA0,  0x08, 	/* 3D1C0 */
+	0x84,  0x08,  0x48,  0x29,  0xFE,  0x28,  0x20,  0x3E,  0xFC,  0x28,  0x20,  0x2B,  0xFF,  0x48,  0x24,  0x09, 	/* 3D1D0 */
+	0xCA,  0x0C,  0x48,  0x1B,  0xFF,  0x68,  0x4A,  0x08,  0x64,  0x0B,  0xCD,  0x08,  0x73,  0x08,  0xC1,  0xA2, 	/* 3D1E0 */
+	0x08,  0x20,  0x0B,  0xFF,  0x28,  0x20,  0x29,  0xFC,  0x3E,  0x00,  0x2B,  0xFE,  0x4A,  0x52,  0x0B,  0xFE, 	/* 3D1F0 */
+	0x0D,  0x04,  0x19,  0xFC,  0x69,  0x04,  0x09,  0xFC,  0x09,  0x04,  0x09,  0xFC,  0x08,  0xCC,  0x0F,  0x03, 	/* 3D200 */
+	0xA7,  0x08,  0x84,  0x28,  0x48,  0x29,  0xFE,  0x28,  0x20,  0x3E,  0xFC,  0x28,  0x20,  0x4B,  0xFF,  0x08, 	/* 3D210 */
+	0x24,  0x0D,  0xCA,  0x18,  0x88,  0x6B,  0xFF,  0x09,  0x4A,  0x0B,  0x24,  0x0D,  0xC5,  0x08,  0x4B,  0x08, 	/* 3D220 */
+	0xD1,  0xAC,  0x00,  0x80,  0x00,  0x90,  0x00,  0x88,  0x00,  0x84,  0x00,  0x84,  0x7F,  0xFF,  0x00,  0x80, 	/* 3D230 */
+	0x00,  0x80,  0x01,  0x40,  0x01,  0x40,  0x02,  0x20,  0x02,  0x20,  0x04,  0x10,  0x08,  0x08,  0x10,  0x04, 	/* 3D240 */
+	0x60,  0x03,  0xAF,  0x04,  0x00,  0x44,  0xFC,  0x28,  0x84,  0x10,  0x84,  0x10,  0x84,  0x28,  0x84,  0x48, 	/* 3D250 */
+	0x84,  0x0C,  0x84,  0x14,  0x98,  0x14,  0x80,  0x24,  0x80,  0x44,  0x80,  0x04,  0x81,  0x04,  0x81,  0x34, 	/* 3D260 */
+	0x7F,  0x08,  0x00,  0xB2,  0x04,  0x08,  0x44,  0x08,  0x28,  0x08,  0x10,  0x08,  0x13,  0xFF,  0x28,  0x18, 	/* 3D270 */
+	0x48,  0x18,  0x08,  0x28,  0x18,  0x28,  0x18,  0x48,  0x28,  0x48,  0x48,  0x88,  0x09,  0x08,  0x0A,  0x08, 	/* 3D280 */
+	0x68,  0x08,  0x10,  0x18,  0xB6,  0x04,  0x20,  0x04,  0x24,  0x24,  0x22,  0x24,  0x22,  0x14,  0x20,  0x17, 	/* 3D290 */
+	0xFF,  0x04,  0x20,  0x04,  0x20,  0x0C,  0x50,  0x14,  0x50,  0x14,  0x50,  0x24,  0x88,  0x44,  0x88,  0x05, 	/* 3D2A0 */
+	0x04,  0x06,  0x02,  0x04,  0x01,  0xB9,  0x04,  0x48,  0x44,  0x44,  0x28,  0x44,  0x10,  0x40,  0x17,  0xFF, 	/* 3D2B0 */
+	0x28,  0x40,  0x48,  0x40,  0x08,  0x60,  0x18,  0xA0,  0x18,  0xA0,  0x28,  0xA0,  0x48,  0xA0,  0x09,  0x21, 	/* 3D2C0 */
+	0x09,  0x21,  0x1A,  0x11,  0x74,  0x0F,  0x82,  0x04,  0x00,  0x45,  0xFE,  0x28,  0x20,  0x10,  0x20,  0x10, 	/* 3D2D0 */
+	0x20,  0x28,  0x20,  0x48,  0x20,  0x09,  0xFC,  0x18,  0x20,  0x18,  0x20,  0x28,  0x20,  0x48,  0x20,  0x08, 	/* 3D2E0 */
+	0x20,  0x08,  0x20,  0x6F,  0xFF,  0x10,  0x00,  0x83,  0x04,  0x00,  0x45,  0xF8,  0x28,  0x88,  0x10,  0x88, 	/* 3D2F0 */
+	0x10,  0x88,  0x28,  0x88,  0x48,  0x88,  0x0B,  0xFF,  0x18,  0x88,  0x18,  0x88,  0x28,  0x88,  0x48,  0x88, 	/* 3D300 */
+	0x08,  0x88,  0x08,  0x88,  0x6F,  0xFF,  0x10,  0x00,  0x84,  0x04,  0x20,  0x44,  0x20,  0x28,  0x22,  0x11, 	/* 3D310 */
+	0x22,  0x11,  0x22,  0x29,  0x24,  0x49,  0x24,  0x09,  0x20,  0x1A,  0x30,  0x18,  0x30,  0x28,  0x50,  0x48, 	/* 3D320 */
+	0x48,  0x08,  0x88,  0x08,  0x84,  0x69,  0x02,  0x16,  0x01,  0x86,  0x04,  0x20,  0x44,  0x20,  0x28,  0x20, 	/* 3D330 */
+	0x10,  0x20,  0x13,  0xFE,  0x2A,  0x22,  0x4A,  0x22,  0x0A,  0x22,  0x1A,  0x22,  0x1B,  0xFE,  0x28,  0x20, 	/* 3D340 */
+	0x48,  0x20,  0x08,  0x20,  0x08,  0x20,  0x68,  0x20,  0x10,  0x20,  0x8E,  0x04,  0x00,  0x45,  0xFE,  0x29, 	/* 3D350 */
+	0x22,  0x11,  0x22,  0x11,  0x22,  0x29,  0xFE,  0x49,  0x22,  0x09,  0x22,  0x19,  0x22,  0x19,  0xFE,  0x28, 	/* 3D360 */
+	0x20,  0x48,  0x20,  0x08,  0x20,  0x08,  0x20,  0x68,  0x20,  0x10,  0x20,  0x90,  0x04,  0x02,  0x44,  0x0C, 	/* 3D370 */
+	0x29,  0xF4,  0x11,  0x04,  0x11,  0x24,  0x29,  0x24,  0x49,  0x24,  0x09,  0x24,  0x19,  0x24,  0x29,  0x24, 	/* 3D380 */
+	0x49,  0x34,  0x09,  0x34,  0x09,  0x2A,  0x0A,  0x3A,  0x6A,  0xC6,  0x14,  0x01,  0x92,  0x04,  0x90,  0x44, 	/* 3D390 */
+	0x90,  0x2B,  0xFE,  0x10,  0x92,  0x10,  0x92,  0x2B,  0xFE,  0x4A,  0x90,  0x0A,  0x90,  0x1B,  0xFE,  0x18, 	/* 3D3A0 */
+	0x92,  0x28,  0x92,  0x48,  0x92,  0x09,  0x12,  0x09,  0x1C,  0x6A,  0x10,  0x14,  0x10,  0x97,  0x04,  0x80, 	/* 3D3B0 */
+	0x44,  0x80,  0x28,  0x80,  0x11,  0xFE,  0x29,  0x02,  0x4A,  0x02,  0x04,  0xF2,  0x0C,  0x92,  0x14,  0x92, 	/* 3D3C0 */
+	0x24,  0x92,  0x44,  0x92,  0x04,  0xF2,  0x04,  0x02,  0x08,  0x02,  0x68,  0x04,  0x10,  0x18,  0x99,  0x04, 	/* 3D3D0 */
+	0x00,  0x44,  0xFC,  0x28,  0x84,  0x10,  0x84,  0x10,  0x84,  0x28,  0xFC,  0x48,  0x84,  0x08,  0x84,  0x18, 	/* 3D3E0 */
+	0x84,  0x18,  0xFC,  0x28,  0x84,  0x48,  0x84,  0x08,  0x84,  0x08,  0x84,  0x6B,  0xFF,  0x10,  0x00,  0x9B, 	/* 3D3F0 */
+	0x04,  0x20,  0x44,  0x20,  0x28,  0x20,  0x10,  0x40,  0x11,  0xFC,  0x29,  0x04,  0x49,  0x04,  0x09,  0x04, 	/* 3D400 */
+	0x19,  0x04,  0x19,  0xFC,  0x29,  0x04,  0x49,  0x04,  0x09,  0x04,  0x09,  0x04,  0x69,  0xFC,  0x10,  0x00, 	/* 3D410 */
+	0xA0,  0x04,  0x00,  0x44,  0xFC,  0x28,  0x84,  0x10,  0x84,  0x10,  0xFC,  0x28,  0x84,  0x48,  0x84,  0x08, 	/* 3D420 */
+	0x84,  0x18,  0xFE,  0x18,  0xA2,  0x28,  0x94,  0x48,  0x94,  0x08,  0x88,  0x08,  0x84,  0x68,  0xE2,  0x13, 	/* 3D430 */
+	0x81,  0xA1,  0x04,  0x20,  0x44,  0x20,  0x28,  0x20,  0x13,  0xFF,  0x10,  0x88,  0x28,  0x84,  0x49,  0x04, 	/* 3D440 */
+	0x09,  0x8A,  0x1A,  0x8A,  0x18,  0x50,  0x28,  0x50,  0x48,  0x20,  0x08,  0x50,  0x08,  0x88,  0x69,  0x04, 	/* 3D450 */
+	0x16,  0x03,  0xA2,  0x04,  0x40,  0x44,  0x40,  0x28,  0xF8,  0x10,  0x88,  0x11,  0x88,  0x29,  0x50,  0x4A, 	/* 3D460 */
+	0x20,  0x08,  0x50,  0x19,  0x8C,  0x1E,  0x03,  0x29,  0xFC,  0x49,  0x04,  0x09,  0x04,  0x09,  0x04,  0x69, 	/* 3D470 */
+	0xFC,  0x10,  0x00,  0xA9,  0x04,  0x20,  0x44,  0x20,  0x2B,  0xFF,  0x12,  0x01,  0x12,  0x01,  0x28,  0x08, 	/* 3D480 */
+	0x48,  0x08,  0x0B,  0xFF,  0x18,  0x08,  0x18,  0x88,  0x28,  0x48,  0x48,  0x48,  0x08,  0x08,  0x08,  0x08, 	/* 3D490 */
+	0x68,  0x08,  0x10,  0x18,  0xAC,  0x04,  0x20,  0x44,  0x20,  0x28,  0x20,  0x13,  0xFC,  0x12,  0x24,  0x2A, 	/* 3D4A0 */
+	0x24,  0x4A,  0x24,  0x0A,  0x24,  0x1B,  0xFC,  0x18,  0x20,  0x28,  0x20,  0x48,  0x28,  0x08,  0x24,  0x08, 	/* 3D4B0 */
+	0x3E,  0x17,  0xC2,  0x60,  0x02,  0xAD,  0x04,  0x20,  0x44,  0x20,  0x2B,  0xFE,  0x10,  0x20,  0x32,  0x24, 	/* 3D4C0 */
+	0x51,  0x24,  0x08,  0xA4,  0x08,  0xA8,  0x1F,  0xFF,  0x18,  0x20,  0x28,  0x50,  0x48,  0x50,  0x08,  0x88, 	/* 3D4D0 */
+	0x09,  0x04,  0x6A,  0x02,  0x14,  0x01,  0xB7,  0x04,  0x00,  0x45,  0xFC,  0x29,  0x04,  0x11,  0x04,  0x11, 	/* 3D4E0 */
+	0xFC,  0x28,  0x00,  0x49,  0xFC,  0x09,  0x04,  0x19,  0x04,  0x19,  0xFC,  0x29,  0x04,  0x49,  0x04,  0x09, 	/* 3D4F0 */
+	0xFC,  0x09,  0x04,  0x69,  0x04,  0x11,  0x0C,  0xB8,  0x04,  0x00,  0x47,  0xFC,  0x29,  0x24,  0x11,  0x24, 	/* 3D500 */
+	0x11,  0xFC,  0x29,  0x24,  0x49,  0x24,  0x09,  0x24,  0x19,  0xFC,  0x18,  0x20,  0x28,  0x20,  0x4B,  0xFE, 	/* 3D510 */
+	0x08,  0x20,  0x08,  0x20,  0x6F,  0xFF,  0x10,  0x00,  0xB9,  0x04,  0x20,  0x44,  0x20,  0x2F,  0xFF,  0x10, 	/* 3D520 */
+	0x20,  0x11,  0x24,  0x29,  0x24,  0x49,  0x24,  0x09,  0xAA,  0x1A,  0xAA,  0x1A,  0x51,  0x2C,  0x50,  0x48, 	/* 3D530 */
+	0x88,  0x08,  0x88,  0x09,  0x04,  0x6A,  0x02,  0x14,  0x01,  0xBC,  0x04,  0x20,  0x44,  0x20,  0x29,  0xF8, 	/* 3D540 */
+	0x11,  0x08,  0x11,  0x08,  0x29,  0xF8,  0x49,  0x08,  0x09,  0x08,  0x19,  0xFA,  0x19,  0x22,  0x29,  0x24, 	/* 3D550 */
+	0x49,  0x10,  0x09,  0x08,  0x09,  0x64,  0x69,  0x82,  0x16,  0x01,  0xBD,  0x04,  0x00,  0x45,  0xFC,  0x29, 	/* 3D560 */
+	0x04,  0x11,  0x04,  0x11,  0x04,  0x29,  0xFC,  0x49,  0x04,  0x09,  0x04,  0x19,  0xFC,  0x19,  0x04,  0x29, 	/* 3D570 */
+	0x04,  0x49,  0x04,  0x09,  0xFC,  0x08,  0x88,  0x69,  0x04,  0x16,  0x02,  0x8A,  0x04,  0x20,  0x44,  0x40, 	/* 3D580 */
+	0x29,  0x9E,  0x11,  0x02,  0x11,  0x02,  0x29,  0xCE,  0x49,  0x02,  0x09,  0x02,  0x19,  0xFE,  0x18,  0x50, 	/* 3D590 */
+	0x28,  0x50,  0x48,  0x50,  0x08,  0x90,  0x08,  0x91,  0x69,  0x11,  0x12,  0x0F,  0x96,  0x04,  0x00,  0x45, 	/* 3D5A0 */
+	0xFC,  0x29,  0x04,  0x11,  0x04,  0x11,  0xFC,  0x29,  0x04,  0x49,  0xFC,  0x08,  0x00,  0x1B,  0xFE,  0x1A, 	/* 3D5B0 */
+	0x02,  0x2A,  0x02,  0x4B,  0xFE,  0x0A,  0x02,  0x0A,  0x02,  0x6B,  0xFE,  0x10,  0x00,  0x97,  0x04,  0x20, 	/* 3D5C0 */
+	0x44,  0x20,  0x2B,  0xFE,  0x10,  0x30,  0x10,  0x48,  0x29,  0x84,  0x48,  0x00,  0x0F,  0xFF,  0x18,  0x04, 	/* 3D5D0 */
+	0x19,  0xE4,  0x29,  0x24,  0x49,  0x24,  0x09,  0xE4,  0x08,  0x04,  0x68,  0x04,  0x10,  0x0C,  0x9B,  0x04, 	/* 3D5E0 */
+	0x00,  0x45,  0xFC,  0x28,  0x08,  0x10,  0x10,  0x10,  0x20,  0x2F,  0xFF,  0x48,  0x20,  0x08,  0x20,  0x18, 	/* 3D5F0 */
+	0x60,  0x18,  0x00,  0x2B,  0xFE,  0x4A,  0x52,  0x0A,  0x52,  0x0A,  0x52,  0x6F,  0xFF,  0x10,  0x00,  0x9C, 	/* 3D600 */
+	0x04,  0x20,  0x44,  0x20,  0x2B,  0xFE,  0x10,  0x20,  0x11,  0xFC,  0x28,  0x20,  0x4F,  0xFF,  0x08,  0x00, 	/* 3D610 */
+	0x19,  0xFC,  0x19,  0x24,  0x29,  0x24,  0x49,  0xFC,  0x09,  0x04,  0x09,  0x04,  0x69,  0x04,  0x11,  0x0C, 	/* 3D620 */
+	0x9D,  0x04,  0x20,  0x44,  0x20,  0x2B,  0xFE,  0x10,  0x88,  0x10,  0x88,  0x28,  0xCC,  0x49,  0x12,  0x0A, 	/* 3D630 */
+	0x20,  0x18,  0x20,  0x1F,  0xFF,  0x28,  0x20,  0x48,  0x20,  0x08,  0x20,  0x08,  0x20,  0x68,  0x20,  0x10, 	/* 3D640 */
+	0x20,  0x9F,  0x04,  0x44,  0x46,  0x24,  0x29,  0x28,  0x11,  0x10,  0x11,  0xFC,  0x29,  0x24,  0x49,  0x24, 	/* 3D650 */
+	0x09,  0xFC,  0x19,  0x24,  0x19,  0x24,  0x29,  0xFC,  0x49,  0x24,  0x09,  0x24,  0x0A,  0x25,  0x6A,  0x25, 	/* 3D660 */
+	0x14,  0x23,  0xA5,  0x04,  0x00,  0x45,  0xFC,  0x29,  0x24,  0x11,  0x24,  0x11,  0xFC,  0x29,  0x24,  0x49, 	/* 3D670 */
+	0x24,  0x09,  0xFC,  0x18,  0x00,  0x1F,  0xFF,  0x29,  0x44,  0x49,  0x44,  0x09,  0x28,  0x09,  0x10,  0x69, 	/* 3D680 */
+	0xCC,  0x17,  0x03,  0xA9,  0x04,  0x00,  0x45,  0xFC,  0x29,  0x04,  0x11,  0xFC,  0x11,  0x04,  0x29,  0x04, 	/* 3D690 */
+	0x49,  0xFC,  0x08,  0x20,  0x19,  0x20,  0x19,  0xFE,  0x2A,  0x20,  0x4D,  0xFC,  0x08,  0x20,  0x08,  0x20, 	/* 3D6A0 */
+	0x6F,  0xFF,  0x10,  0x00,  0xAA,  0x04,  0x20,  0x44,  0x24,  0x29,  0xFE,  0x10,  0x24,  0x10,  0x24,  0x28, 	/* 3D6B0 */
+	0x28,  0x4B,  0xFF,  0x08,  0x20,  0x18,  0xFC,  0x19,  0x84,  0x2A,  0x84,  0x48,  0xFC,  0x08,  0x84,  0x08, 	/* 3D6C0 */
+	0x84,  0x68,  0xFC,  0x10,  0x00,  0xAB,  0x04,  0x88,  0x44,  0x88,  0x2F,  0xFF,  0x10,  0x88,  0x10,  0x88, 	/* 3D6D0 */
+	0x28,  0x00,  0x4B,  0xFE,  0x0A,  0x22,  0x1A,  0x22,  0x1A,  0x22,  0x2B,  0xFE,  0x4A,  0x22,  0x0A,  0x22, 	/* 3D6E0 */
+	0x0A,  0x22,  0x6B,  0xFE,  0x10,  0x00,  0xAE,  0x04,  0x08,  0x04,  0x08,  0x7F,  0xCA,  0x04,  0x09,  0x04, 	/* 3D6F0 */
+	0x09,  0x3F,  0xFF,  0x32,  0x88,  0x2A,  0x88,  0x2C,  0x88,  0x3F,  0x94,  0x24,  0x94,  0x3F,  0x94,  0x24, 	/* 3D700 */
+	0xA4,  0x24,  0xA2,  0x24,  0xC2,  0x21,  0x81,  0xAF,  0x04,  0x20,  0x45,  0x22,  0x29,  0x22,  0x11,  0x22, 	/* 3D710 */
+	0x11,  0xFE,  0x28,  0x00,  0x4B,  0xFF,  0x08,  0x20,  0x18,  0x40,  0x19,  0xFE,  0x29,  0x52,  0x49,  0x52, 	/* 3D720 */
+	0x09,  0x52,  0x09,  0x52,  0x69,  0x52,  0x11,  0x06,  0xB4,  0x44,  0x80,  0x24,  0xBC,  0x14,  0x84,  0x19, 	/* 3D730 */
+	0x04,  0x11,  0xFF,  0x1B,  0x20,  0x2D,  0x20,  0x49,  0x7E,  0x19,  0x90,  0x19,  0x10,  0x29,  0xFF,  0x49, 	/* 3D740 */
+	0x18,  0x09,  0x28,  0x09,  0x24,  0x69,  0x42,  0x11,  0x81,  0xB6,  0x05,  0x04,  0x44,  0x84,  0x28,  0x88, 	/* 3D750 */
+	0x13,  0xFF,  0x10,  0x50,  0x28,  0x50,  0x49,  0xFE,  0x09,  0x52,  0x19,  0x52,  0x19,  0x9E,  0x29,  0x02, 	/* 3D760 */
+	0x49,  0xFE,  0x09,  0x02,  0x09,  0x02,  0x69,  0xFE,  0x11,  0x02,  0xB7,  0x21,  0x10,  0x11,  0x14,  0x12, 	/* 3D770 */
+	0x12,  0x7F,  0xD2,  0x0A,  0x10,  0x0A,  0x7F,  0x3F,  0x90,  0x2A,  0x90,  0x2A,  0x90,  0x2B,  0x90,  0x30, 	/* 3D780 */
+	0xA8,  0x20,  0xA8,  0x3F,  0xA4,  0x20,  0xC4,  0x3F,  0xC2,  0x20,  0x81,  0xBE,  0x04,  0x00,  0x44,  0xFC, 	/* 3D790 */
+	0x28,  0x84,  0x10,  0xBC,  0x10,  0xA4,  0x28,  0xA4,  0x4B,  0xFF,  0x0A,  0x01,  0x1A,  0xFD,  0x18,  0x84, 	/* 3D7A0 */
+	0x28,  0xFC,  0x48,  0x84,  0x08,  0xFC,  0x08,  0x84,  0x68,  0x84,  0x10,  0x8C,  0xBF,  0x08,  0x20,  0x48, 	/* 3D7B0 */
+	0x20,  0x29,  0xFC,  0x10,  0x20,  0x17,  0xFF,  0x28,  0x00,  0x49,  0xFC,  0x09,  0x04,  0x19,  0x04,  0x19, 	/* 3D7C0 */
+	0xFC,  0x28,  0xA2,  0x49,  0x92,  0x0E,  0x94,  0x08,  0x88,  0x68,  0xE4,  0x13,  0x03,  0x84,  0x08,  0x08, 	/* 3D7D0 */
+	0x4B,  0xCC,  0x28,  0x0A,  0x17,  0xEA,  0x10,  0x08,  0x2B,  0xFF,  0x48,  0x08,  0x0B,  0xC8,  0x18,  0x08, 	/* 3D7E0 */
+	0x18,  0x0C,  0x2B,  0xD4,  0x4A,  0x54,  0x0A,  0x54,  0x0A,  0x62,  0x6B,  0xC2,  0x10,  0x81,  0x85,  0x09, 	/* 3D7F0 */
+	0x00,  0x4A,  0x7F,  0x2B,  0x88,  0x32,  0x88,  0x12,  0xBE,  0x12,  0xAA,  0x33,  0xAA,  0x4A,  0x2A,  0x1B, 	/* 3D800 */
+	0xAA,  0x1A,  0xAA,  0x2A,  0xAA,  0x4A,  0xAA,  0x0B,  0xAE,  0x0A,  0xA8,  0x6A,  0x08,  0x10,  0x08,  0x8E, 	/* 3D810 */
+	0x04,  0x10,  0x24,  0x3E,  0x25,  0xCA,  0x3C,  0x2C,  0x05,  0xF0,  0x7C,  0x04,  0x17,  0xFF,  0x14,  0x84, 	/* 3D820 */
+	0x24,  0x44,  0x44,  0x9C,  0x00,  0x88,  0x7F,  0xFF,  0x01,  0x40,  0x02,  0x20,  0x0C,  0x18,  0x70,  0x07, 	/* 3D830 */
+	0x8F,  0x04,  0x88,  0x44,  0x88,  0x2B,  0xFF,  0x10,  0x88,  0x10,  0x00,  0x29,  0xFC,  0x49,  0x04,  0x09, 	/* 3D840 */
+	0xFC,  0x19,  0x04,  0x19,  0xFC,  0x28,  0x20,  0x4F,  0xFF,  0x08,  0x20,  0x08,  0x50,  0x69,  0x8C,  0x16, 	/* 3D850 */
+	0x03,  0x97,  0x10,  0x00,  0x17,  0xFF,  0x56,  0x28,  0x25,  0x28,  0x25,  0x5F,  0x57,  0xFA,  0x14,  0x8C, 	/* 3D860 */
+	0x16,  0xA8,  0x36,  0xA8,  0x36,  0xA8,  0x56,  0xAC,  0x17,  0xF4,  0x14,  0x94,  0x19,  0x14,  0x11,  0x22, 	/* 3D870 */
+	0x62,  0x41,  0xA3,  0x11,  0x10,  0x49,  0x14,  0x2A,  0x12,  0x3F,  0x12,  0x29,  0x10,  0x3F,  0xFF,  0x29, 	/* 3D880 */
+	0x10,  0x3F,  0x10,  0x00,  0x10,  0x7F,  0xA8,  0x00,  0x28,  0x3F,  0x28,  0x21,  0x44,  0x21,  0x44,  0x3F, 	/* 3D890 */
+	0x82,  0x01,  0x01,  0xA8,  0x04,  0x00,  0x47,  0xFE,  0x2A,  0x52,  0x12,  0x52,  0x13,  0xFE,  0x28,  0x80, 	/* 3D8A0 */
+	0x48,  0xFE,  0x09,  0x42,  0x1B,  0xF2,  0x1D,  0x52,  0x29,  0x52,  0x49,  0xF2,  0x08,  0x52,  0x08,  0x6A, 	/* 3D8B0 */
+	0x6B,  0x84,  0x10,  0x18,  0xAA,  0x04,  0x20,  0x44,  0x50,  0x28,  0x88,  0x11,  0xFC,  0x16,  0x03,  0x2B, 	/* 3D8C0 */
+	0xFE,  0x4B,  0x26,  0x0A,  0xAA,  0x1B,  0xFE,  0x18,  0x00,  0x29,  0xFC,  0x49,  0x04,  0x09,  0xFC,  0x09, 	/* 3D8D0 */
+	0x04,  0x69,  0xFC,  0x10,  0x00,  0xB0,  0x04,  0x20,  0x44,  0x20,  0x2B,  0xFF,  0x12,  0x21,  0x10,  0x91, 	/* 3D8E0 */
+	0x2A,  0x8A,  0x4C,  0x79,  0x08,  0x01,  0x1B,  0xFE,  0x1A,  0x52,  0x2B,  0xFE,  0x48,  0x00,  0x0B,  0xFF, 	/* 3D8F0 */
+	0x08,  0x20,  0x68,  0x20,  0x10,  0x60,  0xB2,  0x04,  0x48,  0x47,  0xFF,  0x28,  0x48,  0x10,  0x90,  0x11, 	/* 3D900 */
+	0xFE,  0x29,  0x10,  0x4B,  0xFC,  0x19,  0x10,  0x15,  0xFC,  0x25,  0x10,  0x47,  0xFE,  0x04,  0x88,  0x04, 	/* 3D910 */
+	0x50,  0x08,  0x20,  0x28,  0xD8,  0x13,  0x06,  0xB5,  0x09,  0x24,  0x4A,  0x48,  0x29,  0x24,  0x13,  0xFC, 	/* 3D920 */
+	0x12,  0x54,  0x2A,  0x24,  0x4A,  0xD4,  0x0B,  0xFC,  0x18,  0x00,  0x1B,  0x34,  0x2A,  0xAC,  0x4B,  0x34, 	/* 3D930 */
+	0x0A,  0xAD,  0x0A,  0x25,  0x6B,  0xBB,  0x16,  0x61,  0xB8,  0x3B,  0x90,  0x2A,  0x94,  0x3B,  0x92,  0x00, 	/* 3D940 */
+	0x12,  0x3F,  0x10,  0x25,  0xFF,  0x3F,  0x10,  0x25,  0x10,  0x3F,  0x10,  0x00,  0x18,  0x7F,  0xA8,  0x00, 	/* 3D950 */
+	0x28,  0x3F,  0x44,  0x21,  0x44,  0x3F,  0x82,  0x01,  0x01,  0xBA,  0x11,  0x00,  0x51,  0x3E,  0x2F,  0xCA, 	/* 3D960 */
+	0x21,  0x12,  0x31,  0x26,  0x57,  0xC0,  0x15,  0x7E,  0x15,  0x62,  0x15,  0x7E,  0x37,  0xE2,  0x31,  0xBE, 	/* 3D970 */
+	0x53,  0x62,  0x13,  0x3E,  0x15,  0x14,  0x19,  0x22,  0x61,  0x41,  0xBB,  0x04,  0x08,  0x07,  0x8C,  0x04, 	/* 3D980 */
+	0x0A,  0x3F,  0xEA,  0x27,  0x48,  0x3C,  0x3F,  0x2F,  0xC8,  0x28,  0x88,  0x2F,  0x88,  0x20,  0x0C,  0x3F, 	/* 3D990 */
+	0xD4,  0x35,  0x54,  0x39,  0xD4,  0x57,  0x52,  0x52,  0x62,  0x12,  0xC1,  0x84,  0x00,  0x80,  0x00,  0x80, 	/* 3D9A0 */
+	0x00,  0x80,  0x7F,  0xFE,  0x00,  0x80,  0x00,  0x80,  0x01,  0x10,  0x0E,  0x10,  0x01,  0x20,  0x01,  0x40, 	/* 3D9B0 */
+	0x00,  0x80,  0x01,  0x10,  0x02,  0x08,  0x04,  0x7C,  0x3F,  0x82,  0x00,  0x02,  0x87,  0x00,  0x80,  0x00, 	/* 3D9C0 */
+	0x80,  0x3F,  0xFE,  0x10,  0x84,  0x0B,  0x28,  0x05,  0x40,  0x00,  0x90,  0x0D,  0x2C,  0x33,  0xF2,  0x00, 	/* 3D9D0 */
+	0x90,  0x7F,  0xFF,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x89,  0x00,  0x00, 	/* 3D9E0 */
+	0x3F,  0xFE,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x1F,  0xFC,  0x00,  0x80, 	/* 3D9F0 */
+	0x00,  0x80,  0x00,  0x90,  0x00,  0x88,  0x00,  0x88,  0x00,  0x80,  0x7F,  0xFF,  0x00,  0x00,  0x8B,  0x00, 	/* 3DA00 */
+	0x00,  0x3F,  0xFE,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x1F,  0xFC,  0x00, 	/* 3DA10 */
+	0x80,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x7F,  0xFF,  0x00,  0x00,  0x96, 	/* 3DA20 */
+	0x00,  0x40,  0x00,  0x40,  0x7C,  0x78,  0x10,  0x88,  0x10,  0x88,  0x11,  0x08,  0x12,  0x10,  0x7C,  0x10, 	/* 3DA30 */
+	0x10,  0x20,  0x10,  0x20,  0x10,  0x50,  0x12,  0x48,  0x1C,  0x84,  0x71,  0x04,  0x02,  0x02,  0x0C,  0x02, 	/* 3DA40 */
+	0xA9,  0x00,  0x00,  0x00,  0xFC,  0x7E,  0x00,  0x10,  0x00,  0x10,  0x00,  0x10,  0x00,  0x13,  0xFF,  0x7C, 	/* 3DA50 */
+	0x48,  0x10,  0x48,  0x10,  0x48,  0x10,  0x48,  0x16,  0x48,  0x18,  0x88,  0x60,  0x89,  0x01,  0x07,  0x02, 	/* 3DA60 */
+	0x00,  0xB2,  0x00,  0x20,  0x7E,  0x20,  0x10,  0x50,  0x10,  0x48,  0x10,  0x84,  0x11,  0xFA,  0x7E,  0x01, 	/* 3DA70 */
+	0x10,  0x00,  0x11,  0xFC,  0x10,  0x44,  0x14,  0x44,  0x18,  0x44,  0x60,  0x44,  0x00,  0x58,  0x00,  0x40, 	/* 3DA80 */
+	0x00,  0x40,  0xB3,  0x00,  0x90,  0x00,  0x94,  0x7C,  0x92,  0x11,  0x12,  0x11,  0x10,  0x13,  0x1F,  0x15, 	/* 3DA90 */
+	0xF0,  0x79,  0x10,  0x11,  0x10,  0x11,  0x08,  0x11,  0x08,  0x15,  0x08,  0x19,  0x05,  0x61,  0x05,  0x01, 	/* 3DAA0 */
+	0x03,  0x01,  0x01,  0xBB,  0x00,  0x20,  0x00,  0x20,  0x7C,  0x20,  0x11,  0xFF,  0x11,  0x22,  0x11,  0x24, 	/* 3DAB0 */
+	0x7D,  0x20,  0x11,  0xFC,  0x11,  0x04,  0x11,  0x44,  0x17,  0x48,  0x19,  0x30,  0x62,  0x30,  0x02,  0x48, 	/* 3DAC0 */
+	0x04,  0x84,  0x0B,  0x03,  0x80,  0x00,  0x20,  0x00,  0x20,  0x7C,  0x40,  0x11,  0xFC,  0x11,  0x04,  0x11, 	/* 3DAD0 */
+	0x04,  0x11,  0x04,  0x7D,  0x04,  0x11,  0xFC,  0x11,  0x04,  0x11,  0x04,  0x17,  0x04,  0x19,  0x04,  0x61, 	/* 3DAE0 */
+	0x04,  0x01,  0xFC,  0x00,  0x00,  0x82,  0x00,  0x00,  0x7F,  0xFF,  0x10,  0x04,  0x10,  0x04,  0x11,  0xE4, 	/* 3DAF0 */
+	0x11,  0x24,  0x7D,  0x24,  0x11,  0x24,  0x11,  0x24,  0x11,  0x24,  0x11,  0xE4,  0x10,  0x04,  0x1C,  0x04, 	/* 3DB00 */
+	0x70,  0x04,  0x00,  0x04,  0x00,  0x0C,  0x88,  0x01,  0x00,  0x01,  0x00,  0x7D,  0x00,  0x11,  0x1E,  0x17, 	/* 3DB10 */
+	0xD2,  0x11,  0x52,  0x11,  0x52,  0x7D,  0x52,  0x11,  0x52,  0x11,  0x52,  0x16,  0x52,  0x1A,  0x52,  0x62, 	/* 3DB20 */
+	0x52,  0x04,  0x5E,  0x08,  0x52,  0x01,  0x80,  0x8A,  0x00,  0x00,  0x7D,  0xFC,  0x11,  0x54,  0x11,  0x54, 	/* 3DB30 */
+	0x11,  0x54,  0x11,  0x54,  0x7D,  0x54,  0x17,  0xFF,  0x11,  0x54,  0x11,  0x54,  0x11,  0x54,  0x11,  0x54, 	/* 3DB40 */
+	0x1D,  0x54,  0x71,  0x54,  0x01,  0x54,  0x01,  0x0C,  0x8D,  0x00,  0x20,  0x00,  0x20,  0x7E,  0x50,  0x10, 	/* 3DB50 */
+	0x50,  0x10,  0x88,  0x11,  0x14,  0x12,  0x22,  0x7C,  0x45,  0x11,  0x88,  0x10,  0x10,  0x10,  0x62,  0x11, 	/* 3DB60 */
+	0x84,  0x1E,  0x08,  0x70,  0x10,  0x00,  0x60,  0x01,  0x80,  0x8E,  0x00,  0x40,  0x00,  0x40,  0x7C,  0x40, 	/* 3DB70 */
+	0x10,  0xFF,  0x10,  0x90,  0x11,  0x10,  0x12,  0x10,  0x7C,  0x14,  0x10,  0x94,  0x10,  0x92,  0x10,  0x92, 	/* 3DB80 */
+	0x10,  0x92,  0x1D,  0x12,  0x72,  0x10,  0x00,  0x10,  0x00,  0x30,  0x9E,  0x00,  0x40,  0x00,  0x40,  0x7C, 	/* 3DB90 */
+	0xFC,  0x10,  0x84,  0x11,  0x48,  0x12,  0x30,  0x10,  0x30,  0x7C,  0x48,  0x11,  0x84,  0x16,  0x03,  0x11, 	/* 3DBA0 */
+	0xFC,  0x15,  0x04,  0x19,  0x04,  0x61,  0x04,  0x01,  0xFC,  0x00,  0x00,  0xA0,  0x00,  0x20,  0x00,  0xA0, 	/* 3DBB0 */
+	0x7C,  0xA0,  0x10,  0xFE,  0x11,  0x20,  0x12,  0x20,  0x7C,  0x20,  0x13,  0xFF,  0x10,  0x70,  0x10,  0x70, 	/* 3DBC0 */
+	0x10,  0xA8,  0x1D,  0x24,  0x72,  0x22,  0x04,  0x21,  0x00,  0x20,  0x00,  0x20,  0xA5,  0x00,  0x00,  0x03, 	/* 3DBD0 */
+	0xFF,  0x7C,  0x84,  0x10,  0x84,  0x10,  0xFC,  0x10,  0x84,  0x7C,  0x84,  0x10,  0x84,  0x10,  0xFC,  0x10, 	/* 3DBE0 */
+	0x84,  0x14,  0x84,  0x18,  0x87,  0x60,  0xFC,  0x03,  0x84,  0x00,  0x04,  0x00,  0x04,  0xAA,  0x00,  0x20, 	/* 3DBF0 */
+	0x7C,  0x20,  0x11,  0xFC,  0x10,  0x20,  0x10,  0x20,  0x10,  0x20,  0x7F,  0xFF,  0x10,  0x00,  0x10,  0x20, 	/* 3DC00 */
+	0x10,  0x20,  0x11,  0xFC,  0x1C,  0x20,  0x60,  0x20,  0x00,  0x20,  0x07,  0xFF,  0x00,  0x00,  0xAD,  0x00, 	/* 3DC10 */
+	0x40,  0x7C,  0x7F,  0x12,  0x48,  0x12,  0x48,  0x12,  0x48,  0x12,  0x48,  0x7E,  0x48,  0x12,  0x7E,  0x12, 	/* 3DC20 */
+	0x48,  0x12,  0x48,  0x10,  0x48,  0x14,  0x48,  0x18,  0x88,  0x10,  0x88,  0x61,  0x3F,  0x02,  0x00,  0xAE, 	/* 3DC30 */
+	0x00,  0x00,  0x03,  0xFC,  0x7E,  0x04,  0x12,  0x04,  0x12,  0xFC,  0x12,  0x24,  0x7E,  0x24,  0x12,  0xFC, 	/* 3DC40 */
+	0x12,  0xAC,  0x12,  0xAC,  0x16,  0xAC,  0x1A,  0xBC,  0x62,  0xA5,  0x04,  0x25,  0x04,  0x23,  0x08,  0x01, 	/* 3DC50 */
+	0xB1,  0x00,  0x42,  0x02,  0x22,  0x7D,  0x22,  0x11,  0x24,  0x11,  0x04,  0x10,  0x48,  0x10,  0x40,  0x7C, 	/* 3DC60 */
+	0x40,  0x17,  0xFF,  0x10,  0x88,  0x10,  0x88,  0x15,  0xE8,  0x19,  0x10,  0x60,  0x28,  0x00,  0xC4,  0x07, 	/* 3DC70 */
+	0x02,  0xB8,  0x00,  0x00,  0x03,  0xFF,  0x7C,  0x20,  0x10,  0x20,  0x11,  0xFC,  0x10,  0x44,  0x7C,  0x44, 	/* 3DC80 */
+	0x10,  0x44,  0x13,  0xFF,  0x10,  0x00,  0x14,  0xFC,  0x18,  0x84,  0x60,  0x84,  0x00,  0x84,  0x00,  0xFC, 	/* 3DC90 */
+	0x00,  0x00,  0xBE,  0x00,  0x00,  0x01,  0xFC,  0x7D,  0x04,  0x11,  0x04,  0x11,  0xFC,  0x11,  0x04,  0x7D, 	/* 3DCA0 */
+	0xFC,  0x11,  0x04,  0x11,  0x04,  0x11,  0xFC,  0x10,  0x50,  0x1C,  0x50,  0x60,  0x90,  0x01,  0x11,  0x06, 	/* 3DCB0 */
+	0x11,  0x18,  0x0F,  0x83,  0x00,  0x24,  0x00,  0x22,  0x7C,  0x22,  0x13,  0xFF,  0x10,  0x20,  0x12,  0x22, 	/* 3DCC0 */
+	0x11,  0x32,  0x7C,  0xB4,  0x10,  0xB4,  0x10,  0x28,  0x12,  0x68,  0x14,  0xA4,  0x19,  0x22,  0x66,  0x21, 	/* 3DCD0 */
+	0x00,  0x20,  0x00,  0x60,  0x85,  0x00,  0x20,  0x00,  0x20,  0x7E,  0xFC,  0x08,  0x84,  0x08,  0x84,  0x08, 	/* 3DCE0 */
+	0xFC,  0x08,  0x84,  0x7E,  0x84,  0x08,  0xFE,  0x08,  0x92,  0x08,  0x94,  0x0E,  0x88,  0x18,  0x88,  0x60, 	/* 3DCF0 */
+	0xA4,  0x00,  0xC2,  0x03,  0x01,  0x86,  0x00,  0x00,  0x01,  0xFE,  0x7F,  0x22,  0x11,  0x22,  0x11,  0xFE, 	/* 3DD00 */
+	0x11,  0x22,  0x7D,  0x22,  0x11,  0x22,  0x11,  0xFE,  0x10,  0x20,  0x14,  0x20,  0x19,  0xFE,  0x60,  0x20, 	/* 3DD10 */
+	0x00,  0x20,  0x07,  0xFF,  0x00,  0x00,  0x89,  0x00,  0x20,  0x7C,  0x20,  0x13,  0xFF,  0x10,  0x20,  0x10, 	/* 3DD20 */
+	0x58,  0x10,  0x8C,  0x7D,  0xF2,  0x10,  0x00,  0x10,  0xA4,  0x10,  0xA4,  0x12,  0xA4,  0x1C,  0xA4,  0x70, 	/* 3DD30 */
+	0xA4,  0x01,  0x25,  0x01,  0x05,  0x02,  0x03,  0xA2,  0x00,  0x00,  0x7F,  0xFF,  0x10,  0x40,  0x10,  0x44, 	/* 3DD40 */
+	0x10,  0xA4,  0x13,  0x24,  0x7C,  0x28,  0x10,  0x58,  0x10,  0x98,  0x13,  0x34,  0x10,  0x34,  0x1C,  0x52, 	/* 3DD50 */
+	0x70,  0x91,  0x03,  0x10,  0x00,  0x10,  0x00,  0x60,  0xA5,  0x00,  0x20,  0x00,  0x3E,  0x7C,  0x20,  0x11, 	/* 3DD60 */
+	0xFF,  0x11,  0x02,  0x11,  0x20,  0x7D,  0x3C,  0x11,  0xE0,  0x11,  0x22,  0x11,  0x1E,  0x15,  0x48,  0x1A, 	/* 3DD70 */
+	0x48,  0x62,  0x48,  0x04,  0x89,  0x09,  0x09,  0x02,  0x07,  0xB2,  0x00,  0x48,  0x00,  0x48,  0x7C,  0x48, 	/* 3DD80 */
+	0x13,  0xCF,  0x10,  0x48,  0x10,  0x48,  0x7C,  0x48,  0x13,  0xCF,  0x10,  0x48,  0x10,  0x48,  0x14,  0x48, 	/* 3DD90 */
+	0x19,  0xCF,  0x66,  0x88,  0x00,  0x88,  0x01,  0x08,  0x02,  0x08,  0xB3,  0x00,  0x88,  0x7C,  0x88,  0x10, 	/* 3DDA0 */
+	0x88,  0x13,  0xFF,  0x10,  0x88,  0x10,  0x88,  0x7D,  0xDC,  0x11,  0xBC,  0x12,  0xAA,  0x12,  0xAA,  0x14, 	/* 3DDB0 */
+	0xC9,  0x10,  0x88,  0x1C,  0x88,  0x60,  0x88,  0x00,  0x88,  0x00,  0x88,  0xB4,  0x00,  0x00,  0x7F,  0x7E, 	/* 3DDC0 */
+	0x08,  0x08,  0x3E,  0x7E,  0x08,  0x08,  0x0B,  0x88,  0x1C,  0xBF,  0x61,  0x40,  0x02,  0x20,  0x0C,  0x18, 	/* 3DDD0 */
+	0x73,  0xE7,  0x00,  0x00,  0x0F,  0xF0,  0x00,  0x20,  0x00,  0x40,  0x00,  0x80,  0xB5,  0x00,  0x00,  0x7F, 	/* 3DDE0 */
+	0x7E,  0x08,  0x10,  0x08,  0x10,  0x3E,  0x7C,  0x08,  0x10,  0x08,  0x10,  0x0F,  0xFE,  0x70,  0x40,  0x10, 	/* 3DDF0 */
+	0x40,  0x10,  0x4C,  0x1F,  0x70,  0x10,  0x40,  0x10,  0x42,  0x1F,  0x42,  0x70,  0x3E,  0xB6,  0x00,  0x00, 	/* 3DE00 */
+	0x7F,  0x7F,  0x08,  0x08,  0x3E,  0x3E,  0x08,  0x08,  0x0F,  0x7F,  0x70,  0x00,  0x1F,  0xF8,  0x10,  0x88, 	/* 3DE10 */
+	0x10,  0x88,  0x10,  0x88,  0x1F,  0xF8,  0x10,  0x00,  0x10,  0x02,  0x08,  0x02,  0x07,  0xFE,  0xBA,  0x01, 	/* 3DE20 */
+	0x10,  0x00,  0x90,  0x7C,  0x90,  0x10,  0x7E,  0x12,  0x10,  0x11,  0x10,  0x11,  0x10,  0x7C,  0xFF,  0x10, 	/* 3DE30 */
+	0x10,  0x11,  0x10,  0x11,  0x18,  0x15,  0x24,  0x1A,  0x24,  0x62,  0x4E,  0x04,  0xF2,  0x04,  0x02,  0xBF, 	/* 3DE40 */
+	0x00,  0x00,  0x03,  0xFE,  0x7E,  0x02,  0x12,  0x20,  0x13,  0xFE,  0x10,  0x20,  0x11,  0xFC,  0x7D,  0x24, 	/* 3DE50 */
+	0x11,  0xFC,  0x11,  0x24,  0x11,  0x24,  0x15,  0xFC,  0x18,  0x20,  0x63,  0xFF,  0x00,  0x20,  0x00,  0x20, 	/* 3DE60 */
+	0x81,  0x00,  0x00,  0x03,  0xFE,  0x7E,  0x02,  0x12,  0xFA,  0x12,  0x02,  0x12,  0xFA,  0x7A,  0x02,  0x10, 	/* 3DE70 */
+	0x00,  0x11,  0xFC,  0x11,  0x04,  0x15,  0xFC,  0x19,  0x04,  0x61,  0xFC,  0x01,  0x04,  0x01,  0xFC,  0x00, 	/* 3DE80 */
+	0x00,  0x95,  0x00,  0x00,  0x03,  0xDE,  0x7E,  0x42,  0x12,  0x42,  0x12,  0x42,  0x13,  0xDE,  0x7E,  0x00, 	/* 3DE90 */
+	0x12,  0x3E,  0x13,  0xD2,  0x12,  0x12,  0x12,  0x14,  0x1E,  0x08,  0x73,  0xCC,  0x02,  0x14,  0x02,  0x22, 	/* 3DEA0 */
+	0x02,  0x41,  0x99,  0x00,  0x92,  0x7C,  0x92,  0x13,  0x6C,  0x11,  0x24,  0x10,  0x92,  0x10,  0x20,  0x7C, 	/* 3DEB0 */
+	0x40,  0x13,  0xFE,  0x12,  0x12,  0x12,  0xD2,  0x16,  0x22,  0x1A,  0x32,  0x62,  0x4A,  0x02,  0x82,  0x03, 	/* 3DEC0 */
+	0xFE,  0x00,  0x00,  0x9A,  0x01,  0x00,  0x01,  0x1E,  0x7D,  0x12,  0x17,  0xF2,  0x11,  0x12,  0x11,  0x1E, 	/* 3DED0 */
+	0x11,  0x12,  0x7F,  0xD2,  0x12,  0x52,  0x12,  0x5E,  0x12,  0x52,  0x12,  0x52,  0x17,  0xD2,  0x1A,  0x22, 	/* 3DEE0 */
+	0x60,  0x22,  0x00,  0x46,  0x9B,  0x00,  0x88,  0x00,  0x88,  0x7F,  0xFF,  0x10,  0x88,  0x10,  0xA8,  0x10, 	/* 3DEF0 */
+	0x20,  0x11,  0xFC,  0x7D,  0x24,  0x11,  0x24,  0x11,  0x24,  0x17,  0xFF,  0x10,  0x30,  0x1C,  0x48,  0x70, 	/* 3DF00 */
+	0x84,  0x03,  0x02,  0x0C,  0x01,  0x9C,  0x00,  0x60,  0x00,  0x20,  0x7C,  0x50,  0x10,  0x88,  0x11,  0xF4, 	/* 3DF10 */
+	0x16,  0x03,  0x13,  0xCA,  0x7E,  0x4A,  0x13,  0x4A,  0x12,  0xD4,  0x12,  0x54,  0x17,  0x54,  0x1A,  0xCA, 	/* 3DF20 */
+	0x62,  0x4A,  0x02,  0x4A,  0x02,  0xCA,  0x9E,  0x00,  0x20,  0x01,  0x22,  0x7D,  0x22,  0x11,  0x22,  0x11, 	/* 3DF30 */
+	0xFE,  0x10,  0x00,  0x13,  0xFF,  0x7C,  0x20,  0x10,  0x40,  0x11,  0xFE,  0x11,  0x4A,  0x11,  0x4A,  0x1D, 	/* 3DF40 */
+	0x4A,  0x71,  0x4A,  0x01,  0x4A,  0x01,  0x06,  0x9F,  0x00,  0x00,  0x7F,  0x7F,  0x08,  0x08,  0x08,  0x08, 	/* 3DF50 */
+	0x3E,  0x3E,  0x08,  0x08,  0x08,  0x08,  0x0F,  0x7F,  0x70,  0x00,  0x03,  0x20,  0x00,  0xA0,  0x12,  0x44, 	/* 3DF60 */
+	0x12,  0x42,  0x22,  0x89,  0x43,  0x09,  0x0D,  0xF8,  0xA0,  0x00,  0x40,  0x7F,  0xBE,  0x12,  0x0A,  0x12, 	/* 3DF70 */
+	0x8A,  0x12,  0x52,  0x12,  0x52,  0x7B,  0xA2,  0x16,  0x4C,  0x10,  0x00,  0x11,  0xFE,  0x11,  0x22,  0x15, 	/* 3DF80 */
+	0xFE,  0x19,  0x22,  0x61,  0x22,  0x01,  0xFE,  0x00,  0x00,  0xA3,  0x00,  0x20,  0x7C,  0xA8,  0x10,  0xA4, 	/* 3DF90 */
+	0x11,  0x22,  0x13,  0xFE,  0x11,  0x04,  0x7D,  0x04,  0x11,  0xFC,  0x11,  0x04,  0x11,  0xFC,  0x15,  0x04, 	/* 3DFA0 */
+	0x19,  0x04,  0x61,  0xFC,  0x00,  0x48,  0x01,  0x84,  0x06,  0x02,  0xA4,  0x00,  0x10,  0x00,  0x1E,  0x7C, 	/* 3DFB0 */
+	0x62,  0x13,  0x94,  0x10,  0x48,  0x10,  0x30,  0x7C,  0xC0,  0x13,  0x7E,  0x10,  0xD0,  0x11,  0x10,  0x17, 	/* 3DFC0 */
+	0xFF,  0x18,  0x10,  0x61,  0x12,  0x01,  0x12,  0x01,  0xFE,  0x00,  0x00,  0xA9,  0x04,  0x10,  0x15,  0x54, 	/* 3DFD0 */
+	0x15,  0x54,  0x26,  0x98,  0x09,  0x24,  0x10,  0x40,  0x3F,  0xFE,  0x20,  0x02,  0x20,  0x02,  0x1F,  0xFC, 	/* 3DFE0 */
+	0x00,  0x80,  0x0F,  0xF8,  0x00,  0x90,  0x00,  0x88,  0x7F,  0xFF,  0x00,  0x00,  0xAA,  0x00,  0x00,  0x01, 	/* 3DFF0 */
+	0xFE,  0x7D,  0x20,  0x11,  0x20,  0x11,  0xFC,  0x11,  0x20,  0x11,  0xFC,  0x7D,  0x20,  0x11,  0x20,  0x11, 	/* 3E000 */
+	0xFE,  0x10,  0x12,  0x14,  0x4A,  0x1B,  0x2A,  0x62,  0xA2,  0x04,  0x82,  0x08,  0x0C,  0xAF,  0x00,  0x80, 	/* 3E010 */
+	0x7C,  0x9E,  0x13,  0xD2,  0x12,  0x52,  0x12,  0x54,  0x13,  0xD8,  0x7E,  0x54,  0x12,  0x54,  0x13,  0xD2, 	/* 3E020 */
+	0x12,  0x12,  0x12,  0x92,  0x1E,  0x52,  0x72,  0x5C,  0x03,  0xB0,  0x06,  0x30,  0x00,  0x10,  0xB0,  0x00, 	/* 3E030 */
+	0x20,  0x00,  0x40,  0x7D,  0xFC,  0x11,  0x24,  0x11,  0x24,  0x11,  0xFC,  0x11,  0x24,  0x7D,  0x24,  0x11, 	/* 3E040 */
+	0xFC,  0x10,  0x52,  0x14,  0x52,  0x18,  0x55,  0x60,  0x9F,  0x01,  0x10,  0x02,  0x11,  0x0C,  0x0F,  0xB3, 	/* 3E050 */
+	0x01,  0x04,  0x00,  0x88,  0x7F,  0xFE,  0x10,  0x20,  0x10,  0x20,  0x11,  0xFC,  0x7C,  0x20,  0x10,  0x20, 	/* 3E060 */
+	0x13,  0xFF,  0x10,  0x80,  0x10,  0x80,  0x1D,  0x7E,  0x72,  0x10,  0x04,  0x10,  0x09,  0xFF,  0x00,  0x00, 	/* 3E070 */
+	0xB6,  0x00,  0x04,  0x00,  0x38,  0x7D,  0xC4,  0x11,  0x22,  0x11,  0x21,  0x11,  0x01,  0x12,  0xFE,  0x7C, 	/* 3E080 */
+	0x20,  0x10,  0x20,  0x17,  0xFF,  0x10,  0x20,  0x16,  0x22,  0x1A,  0x22,  0x62,  0x22,  0x03,  0xFE,  0x00, 	/* 3E090 */
+	0x00,  0xBE,  0x00,  0x88,  0x00,  0x88,  0x7F,  0xFF,  0x10,  0x88,  0x10,  0x00,  0x11,  0xFC,  0x11,  0x24, 	/* 3E0A0 */
+	0x7D,  0x24,  0x11,  0xFC,  0x10,  0x20,  0x11,  0xFC,  0x14,  0x20,  0x19,  0xFC,  0x60,  0x20,  0x07,  0xFF, 	/* 3E0B0 */
+	0x00,  0x00,  0x83,  0x00,  0x20,  0x00,  0x20,  0x7F,  0xFF,  0x10,  0x10,  0x11,  0xD4,  0x11,  0x24,  0x7D, 	/* 3E0C0 */
+	0x54,  0x11,  0x8C,  0x11,  0xFC,  0x10,  0x20,  0x13,  0xFE,  0x1E,  0x32,  0x72,  0x4A,  0x03,  0xF6,  0x02, 	/* 3E0D0 */
+	0x02,  0x02,  0x06,  0x8B,  0x00,  0x20,  0x00,  0x20,  0x7F,  0xFE,  0x10,  0x84,  0x10,  0x48,  0x13,  0xFF, 	/* 3E0E0 */
+	0x7C,  0x00,  0x10,  0xFC,  0x10,  0x84,  0x10,  0xFC,  0x14,  0x84,  0x18,  0xFC,  0x60,  0x20,  0x07,  0xFF, 	/* 3E0F0 */
+	0x00,  0x20,  0x00,  0x20,  0x9E,  0x00,  0x50,  0x02,  0x52,  0x7D,  0x54,  0x10,  0x50,  0x13,  0xFF,  0x10, 	/* 3E100 */
+	0x88,  0x7C,  0x50,  0x13,  0xFE,  0x10,  0x20,  0x11,  0xFC,  0x14,  0x20,  0x1B,  0xFF,  0x60,  0x50,  0x00, 	/* 3E110 */
+	0x88,  0x03,  0x04,  0x0C,  0x03,  0xA2,  0x00,  0x00,  0x07,  0xFF,  0x7C,  0x50,  0x11,  0xDC,  0x11,  0x54, 	/* 3E120 */
+	0x11,  0x54,  0x7D,  0xDC,  0x10,  0x50,  0x11,  0xFE,  0x11,  0x22,  0x15,  0x22,  0x19,  0xFE,  0x61,  0x22, 	/* 3E130 */
+	0x01,  0x22,  0x01,  0xFE,  0x00,  0x00,  0xA7,  0x00,  0x08,  0x1F,  0x08,  0x11,  0x7F,  0x11,  0x22,  0x1F, 	/* 3E140 */
+	0x14,  0x10,  0x7F,  0x2F,  0x08,  0x29,  0x7F,  0x4F,  0x08,  0x00,  0x08,  0x1F,  0xFC,  0x00,  0x80,  0x1F, 	/* 3E150 */
+	0xFC,  0x00,  0x88,  0x7F,  0xFF,  0x00,  0x00,  0xB0,  0x00,  0x00,  0x01,  0xFC,  0x7F,  0x54,  0x11,  0x54, 	/* 3E160 */
+	0x11,  0xFC,  0x10,  0x00,  0x17,  0xFF,  0x7C,  0x00,  0x11,  0xFC,  0x11,  0x04,  0x11,  0xFC,  0x14,  0xE2, 	/* 3E170 */
+	0x19,  0x54,  0x76,  0x4C,  0x00,  0x43,  0x00,  0x40,  0xBD,  0x00,  0x00,  0x7F,  0xFF,  0x10,  0x84,  0x3F, 	/* 3E180 */
+	0xFE,  0x6A,  0xAB,  0x24,  0x92,  0x2A,  0xAA,  0x24,  0x92,  0x2A,  0xAE,  0x00,  0x00,  0x3F,  0xFE,  0x00, 	/* 3E190 */
+	0x80,  0x1F,  0xFC,  0x00,  0x90,  0x7F,  0xFF,  0x00,  0x00,  0x8A,  0x00,  0x20,  0x00,  0x78,  0x7D,  0x90, 	/* 3E1A0 */
+	0x13,  0xFE,  0x12,  0x22,  0x12,  0xD2,  0x7D,  0xFC,  0x11,  0x04,  0x11,  0xFC,  0x11,  0x04,  0x15,  0xFC, 	/* 3E1B0 */
+	0x18,  0x40,  0x61,  0xFC,  0x06,  0x88,  0x00,  0x70,  0x07,  0x8F,  0x8F,  0x00,  0x90,  0x00,  0x90,  0x7F, 	/* 3E1C0 */
+	0xFF,  0x12,  0x50,  0x11,  0x9E,  0x17,  0xE2,  0x10,  0x1E,  0x7F,  0xD0,  0x12,  0x5E,  0x13,  0xD0,  0x12, 	/* 3E1D0 */
+	0x5E,  0x17,  0xD0,  0x1A,  0x5E,  0x62,  0x50,  0x02,  0x51,  0x02,  0xCF,  0x94,  0x00,  0x00,  0x03,  0xDE, 	/* 3E1E0 */
+	0x7E,  0x52,  0x13,  0xDE,  0x12,  0x52,  0x13,  0xDE,  0x7E,  0x52,  0x13,  0xDE,  0x11,  0x54,  0x12,  0x22, 	/* 3E1F0 */
+	0x14,  0x40,  0x1B,  0xFF,  0x60,  0x88,  0x01,  0xD0,  0x00,  0x78,  0x07,  0x86,  0x9C,  0x00,  0x08,  0x00, 	/* 3E200 */
+	0x70,  0x1F,  0x80,  0x10,  0x10,  0x11,  0x10,  0x11,  0x10,  0x11,  0x10,  0x11,  0x10,  0x11,  0x10,  0x11, 	/* 3E210 */
+	0x08,  0x11,  0x48,  0x11,  0x28,  0x11,  0x28,  0x21,  0xF4,  0x2E,  0x14,  0x40,  0x12,  0xA0,  0x08,  0x04, 	/* 3E220 */
+	0x08,  0x18,  0x7F,  0xE4,  0x08,  0x84,  0x14,  0xA4,  0x12,  0xA4,  0x3D,  0xA4,  0x40,  0xA4,  0x00,  0xA4, 	/* 3E230 */
+	0x7F,  0xA4,  0x10,  0xA4,  0x1E,  0xB4,  0x12,  0xAA,  0x02,  0xAA,  0x02,  0xF6,  0x1D,  0x05,  0xA2,  0x00, 	/* 3E240 */
+	0x02,  0x7F,  0x0C,  0x14,  0x74,  0x7F,  0x54,  0x55,  0x54,  0x55,  0x54,  0x7F,  0x54,  0x00,  0x54,  0x3E, 	/* 3E250 */
+	0x54,  0x00,  0x54,  0x7F,  0x54,  0x08,  0x54,  0x2A,  0x55,  0x2A,  0x9D,  0x48,  0xE3,  0x19,  0x01,  0xA3, 	/* 3E260 */
+	0x10,  0x24,  0x13,  0xC4,  0x7E,  0x3F,  0x2A,  0xAA,  0x2A,  0xAA,  0x2A,  0xAA,  0x7E,  0xBF,  0x12,  0xA4, 	/* 3E270 */
+	0x12,  0xA4,  0x1E,  0xBF,  0x72,  0xA4,  0x12,  0xE4,  0x12,  0xA4,  0x24,  0xA4,  0x27,  0xD4,  0x48,  0x0C, 	/* 3E280 */
+	0xA6,  0x00,  0x00,  0x3F,  0xFE,  0x02,  0x00,  0x02,  0x00,  0x02,  0x00,  0x03,  0xF0,  0x02,  0x10,  0x02, 	/* 3E290 */
+	0x10,  0x03,  0x10,  0x02,  0x90,  0x04,  0x90,  0x04,  0x10,  0x04,  0x10,  0x05,  0xD2,  0x0E,  0x12,  0x70, 	/* 3E2A0 */
+	0x0E,  0xA7,  0x00,  0x10,  0x7F,  0x10,  0x10,  0x10,  0x10,  0x10,  0x10,  0x10,  0x1E,  0xFF,  0x12,  0x10, 	/* 3E2B0 */
+	0x12,  0x10,  0x1A,  0x10,  0x16,  0x10,  0x16,  0x10,  0x12,  0x10,  0x12,  0x10,  0x16,  0x01,  0x19,  0x01, 	/* 3E2C0 */
+	0x60,  0xFF,  0xA9,  0x00,  0x04,  0x7F,  0x18,  0x10,  0xF0,  0x10,  0x10,  0x10,  0x10,  0x1E,  0x10,  0x12, 	/* 3E2D0 */
+	0x10,  0x12,  0xFF,  0x1A,  0x10,  0x16,  0x10,  0x16,  0x10,  0x12,  0x10,  0x12,  0x10,  0x16,  0x11,  0x19, 	/* 3E2E0 */
+	0x01,  0x60,  0xFF,  0xAE,  0x02,  0xE0,  0x02,  0x20,  0x04,  0x90,  0x18,  0x8C,  0x61,  0x43,  0x02,  0x30, 	/* 3E2F0 */
+	0x0F,  0xC8,  0x00,  0x00,  0x7F,  0xFF,  0x04,  0x00,  0x07,  0xF0,  0x05,  0x10,  0x04,  0x90,  0x08,  0x11, 	/* 3E300 */
+	0x0F,  0xD1,  0x78,  0x0F,  0xB0,  0x00,  0x3C,  0x7F,  0x04,  0x10,  0x24,  0x10,  0x24,  0x10,  0x42,  0x1E, 	/* 3E310 */
+	0x42,  0x12,  0xFD,  0x13,  0x24,  0x1A,  0x24,  0x16,  0x24,  0x16,  0x24,  0x12,  0x44,  0x12,  0x84,  0x16, 	/* 3E320 */
+	0x19,  0x19,  0x01,  0x60,  0xFF,  0xB1,  0x00,  0x04,  0x7F,  0x18,  0x11,  0xE0,  0x10,  0x40,  0x10,  0x40, 	/* 3E330 */
+	0x1E,  0x7C,  0x13,  0xC0,  0x12,  0x40,  0x1A,  0x7E,  0x17,  0xC0,  0x16,  0x44,  0x12,  0x44,  0x12,  0x3C, 	/* 3E340 */
+	0x16,  0x01,  0x19,  0x01,  0x60,  0xFF,  0xB2,  0x00,  0x20,  0x7F,  0x24,  0x10,  0x38,  0x11,  0xE0,  0x10, 	/* 3E350 */
+	0x20,  0x1E,  0xA4,  0x12,  0xA4,  0x12,  0xA4,  0x1A,  0xFC,  0x16,  0x20,  0x16,  0x22,  0x12,  0x22,  0x12, 	/* 3E360 */
+	0x1E,  0x16,  0x01,  0x19,  0x01,  0x60,  0xFF,  0xB6,  0x21,  0x00,  0x11,  0xFF,  0x12,  0x20,  0x14,  0x20, 	/* 3E370 */
+	0x7F,  0xA0,  0x12,  0x3C,  0x12,  0x24,  0x12,  0x24,  0x7F,  0xB4,  0x12,  0x2C,  0x12,  0x2C,  0x12,  0x24, 	/* 3E380 */
+	0x12,  0x24,  0x22,  0x25,  0x22,  0x35,  0x42,  0xC3,  0xB7,  0x00,  0x40,  0x3C,  0x7E,  0x00,  0x52,  0x00, 	/* 3E390 */
+	0x94,  0x05,  0x10,  0x18,  0x28,  0x60,  0xC4,  0x03,  0x03,  0x7F,  0xFF,  0x04,  0x00,  0x07,  0xF0,  0x05, 	/* 3E3A0 */
+	0x10,  0x04,  0x90,  0x08,  0x11,  0x0F,  0xD1,  0x78,  0x0F,  0xB8,  0x00,  0x00,  0x7F,  0xFE,  0x10,  0x10, 	/* 3E3B0 */
+	0x10,  0x20,  0x10,  0x7C,  0x1E,  0x44,  0x12,  0x44,  0x12,  0x44,  0x1A,  0x7C,  0x16,  0x44,  0x16,  0x44, 	/* 3E3C0 */
+	0x12,  0x44,  0x12,  0x7C,  0x16,  0x01,  0x19,  0x01,  0x60,  0xFF,  0x83,  0x02,  0x10,  0x3C,  0x12,  0x08, 	/* 3E3D0 */
+	0x52,  0x7F,  0x54,  0x0C,  0x50,  0x1A,  0x98,  0x29,  0x28,  0x48,  0x44,  0x08,  0x82,  0x7F,  0xFF,  0x04, 	/* 3E3E0 */
+	0x00,  0x07,  0xF0,  0x05,  0x10,  0x08,  0x91,  0x0F,  0xD1,  0x7C,  0x0F,  0x84,  0x00,  0x00,  0x7F,  0xFF, 	/* 3E3F0 */
+	0x0A,  0x20,  0x0A,  0x20,  0x3F,  0xA0,  0x2A,  0xBC,  0x2A,  0xA4,  0x3F,  0xA4,  0x04,  0x34,  0x04,  0x2C, 	/* 3E400 */
+	0x3F,  0xAC,  0x04,  0x24,  0x04,  0x24,  0x07,  0xA5,  0x0C,  0x3D,  0x70,  0xC3,  0x85,  0x00,  0x00,  0x7D, 	/* 3E410 */
+	0xFE,  0x21,  0x00,  0x21,  0x7C,  0x21,  0x54,  0x3D,  0x7C,  0x25,  0x54,  0x25,  0x7C,  0x35,  0x10,  0x2D, 	/* 3E420 */
+	0x7C,  0x2D,  0x10,  0x26,  0x10,  0x24,  0xFE,  0x24,  0x01,  0x3A,  0x01,  0x61,  0xFF,  0x8C,  0x00,  0x00, 	/* 3E430 */
+	0x7F,  0xFF,  0x40,  0x20,  0x4E,  0x20,  0x4A,  0x20,  0x4A,  0x3C,  0x4E,  0x24,  0x40,  0x24,  0x5F,  0xA4, 	/* 3E440 */
+	0x56,  0xB4,  0x56,  0xAC,  0x56,  0xA4,  0x5F,  0xA4,  0x40,  0x25,  0x7F,  0xB5,  0x00,  0xC3,  0x8D,  0x04, 	/* 3E450 */
+	0x10,  0x7F,  0xFF,  0x04,  0x10,  0x1F,  0xFC,  0x12,  0x24,  0x1F,  0xFC,  0x00,  0x00,  0x7F,  0xFE,  0x40, 	/* 3E460 */
+	0x02,  0x5F,  0xFA,  0x02,  0x00,  0x03,  0xF0,  0x02,  0x90,  0x04,  0x51,  0x07,  0xD1,  0x7C,  0x0F,  0x8E, 	/* 3E470 */
+	0x04,  0x00,  0x7F,  0xFF,  0x04,  0x20,  0x3F,  0x20,  0x25,  0x20,  0x3F,  0x3C,  0x25,  0x24,  0x3F,  0x24, 	/* 3E480 */
+	0x04,  0xB4,  0x7F,  0xAC,  0x02,  0x64,  0x7F,  0xA4,  0x22,  0x24,  0x12,  0x25,  0x12,  0x35,  0x06,  0xC3, 	/* 3E490 */
+	0x91,  0x22,  0x00,  0x14,  0xFF,  0x7F,  0x20,  0x49,  0x20,  0x49,  0x20,  0x7F,  0x3C,  0x49,  0x24,  0x7F, 	/* 3E4A0 */
+	0x24,  0x00,  0x34,  0x3E,  0x2C,  0x22,  0x24,  0x3E,  0x24,  0x22,  0x24,  0x22,  0x25,  0x3E,  0x75,  0x01, 	/* 3E4B0 */
+	0x83,  0x93,  0x00,  0x08,  0x1F,  0x7F,  0x11,  0x22,  0x1F,  0x14,  0x10,  0xFF,  0x1F,  0x08,  0x19,  0x7F, 	/* 3E4C0 */
+	0x29,  0x08,  0x4F,  0x08,  0x00,  0x08,  0x7F,  0xFF,  0x02,  0x00,  0x03,  0xF0,  0x04,  0x91,  0x07,  0xD1, 	/* 3E4D0 */
+	0x7C,  0x0F,  0x95,  0x00,  0x80,  0x7F,  0xFF,  0x08,  0x44,  0x0A,  0x48,  0x72,  0xFE,  0x15,  0x90,  0x0E, 	/* 3E4E0 */
+	0xFE,  0x72,  0x90,  0x04,  0xFF,  0x08,  0x00,  0x7F,  0xFF,  0x02,  0x00,  0x03,  0xF8,  0x04,  0x89,  0x07, 	/* 3E4F0 */
+	0xE9,  0x78,  0x07,  0x98,  0x04,  0x10,  0x04,  0x10,  0x04,  0x10,  0x04,  0x10,  0x7F,  0xFF,  0x04,  0x10, 	/* 3E500 */
+	0x04,  0x10,  0x04,  0x10,  0x04,  0x10,  0x07,  0xF0,  0x04,  0x10,  0x04,  0x10,  0x04,  0x10,  0x04,  0x10, 	/* 3E510 */
+	0x07,  0xF0,  0x00,  0x00,  0x9A,  0x04,  0x10,  0x1F,  0xFE,  0x04,  0x10,  0x04,  0x10,  0x07,  0xF0,  0x04, 	/* 3E520 */
+	0x10,  0x07,  0xF0,  0x04,  0x10,  0x04,  0x10,  0x7F,  0xFF,  0x11,  0x40,  0x12,  0x44,  0x1C,  0x3C,  0x10, 	/* 3E530 */
+	0x00,  0x1F,  0xFE,  0x00,  0x00,  0x9C,  0x01,  0x44,  0x06,  0x44,  0x38,  0x44,  0x08,  0x44,  0x09,  0xFF, 	/* 3E540 */
+	0x08,  0x44,  0x7F,  0x44,  0x08,  0x44,  0x08,  0x44,  0x08,  0x7C,  0x3E,  0x44,  0x22,  0x44,  0x22,  0x44, 	/* 3E550 */
+	0x22,  0x44,  0x3E,  0x7C,  0x00,  0x00,  0x9E,  0x21,  0x08,  0x11,  0x08,  0x11,  0x10,  0x7F,  0xFE,  0x40, 	/* 3E560 */
+	0x02,  0x4F,  0xF2,  0x08,  0x10,  0x0F,  0xF0,  0x00,  0x00,  0x08,  0x10,  0x7F,  0xFF,  0x08,  0x10,  0x0F, 	/* 3E570 */
+	0xF0,  0x08,  0x10,  0x0F,  0xF0,  0x00,  0x00,  0x9F,  0x00,  0x80,  0x08,  0x80,  0x08,  0x80,  0x08,  0x80, 	/* 3E580 */
+	0x0F,  0xFE,  0x10,  0x80,  0x10,  0x80,  0x20,  0x80,  0x40,  0x80,  0x1F,  0xFC,  0x00,  0x80,  0x00,  0x80, 	/* 3E590 */
+	0x00,  0x80,  0x00,  0x80,  0x7F,  0xFF,  0x00,  0x00,  0xA3,  0x00,  0x80,  0x00,  0x80,  0x3F,  0xFE,  0x04, 	/* 3E5A0 */
+	0x10,  0x02,  0x10,  0x02,  0x20,  0x1F,  0xFF,  0x12,  0x40,  0x12,  0x40,  0x17,  0xFC,  0x14,  0x40,  0x18, 	/* 3E5B0 */
+	0x40,  0x27,  0xFC,  0x20,  0x40,  0x40,  0x40,  0x1F,  0xFF,  0xA5,  0x08,  0x00,  0x09,  0xFC,  0x29,  0x24, 	/* 3E5C0 */
+	0x29,  0x24,  0x3F,  0xFC,  0x29,  0x24,  0x49,  0x24,  0x09,  0xFC,  0x3E,  0x20,  0x0B,  0xFE,  0x08,  0x22, 	/* 3E5D0 */
+	0x08,  0x42,  0x0E,  0x42,  0x70,  0x82,  0x01,  0x02,  0x06,  0x0C,  0xA6,  0x00,  0x08,  0x7F,  0xA8,  0x04, 	/* 3E5E0 */
+	0x28,  0x04,  0x28,  0x3F,  0x7F,  0x25,  0x48,  0x3F,  0x88,  0x25,  0x08,  0x25,  0x7E,  0x3F,  0x08,  0x14, 	/* 3E5F0 */
+	0x08,  0x28,  0x08,  0x0C,  0xFF,  0x12,  0x00,  0x21,  0x80,  0x40,  0x7F,  0xA8,  0x00,  0x00,  0x1F,  0xFC, 	/* 3E600 */
+	0x10,  0x84,  0x10,  0x84,  0x10,  0x84,  0x1F,  0xFC,  0x10,  0x84,  0x10,  0x84,  0x10,  0x84,  0x1F,  0xFC, 	/* 3E610 */
+	0x10,  0x84,  0x10,  0x84,  0x10,  0x84,  0x20,  0x84,  0x20,  0x84,  0x40,  0x8C,  0xAB,  0x00,  0x88,  0x00, 	/* 3E620 */
+	0x84,  0x7F,  0xFF,  0x00,  0x80,  0x00,  0x80,  0x1F,  0xFC,  0x10,  0x84,  0x10,  0x84,  0x1F,  0xFC,  0x10, 	/* 3E630 */
+	0x84,  0x10,  0x84,  0x1F,  0xFC,  0x10,  0x84,  0x10,  0x84,  0x10,  0x84,  0x10,  0x8C,  0xAC,  0x00,  0x00, 	/* 3E640 */
+	0x1F,  0xF8,  0x00,  0x10,  0x06,  0x60,  0x01,  0x80,  0x3F,  0xFC,  0x21,  0x04,  0x21,  0x04,  0x3F,  0xFC, 	/* 3E650 */
+	0x21,  0x04,  0x21,  0x04,  0x3F,  0xFC,  0x21,  0x04,  0x21,  0x04,  0x21,  0x04,  0x21,  0x0C,  0xB0,  0x00, 	/* 3E660 */
+	0x00,  0x3F,  0xFE,  0x20,  0x82,  0x20,  0x82,  0x20,  0x82,  0x20,  0x82,  0x20,  0x82,  0x3F,  0xFE,  0x20, 	/* 3E670 */
+	0x82,  0x20,  0x82,  0x20,  0x82,  0x20,  0x82,  0x20,  0x82,  0x20,  0x82,  0x3F,  0xFE,  0x00,  0x00,  0xB1, 	/* 3E680 */
+	0x01,  0x00,  0x01,  0x00,  0x01,  0x00,  0x01,  0x00,  0x3F,  0xFC,  0x21,  0x04,  0x21,  0x04,  0x21,  0x04, 	/* 3E690 */
+	0x3F,  0xFC,  0x21,  0x04,  0x21,  0x04,  0x21,  0x04,  0x21,  0x04,  0x21,  0x04,  0x3F,  0xFC,  0x00,  0x00, 	/* 3E6A0 */
+	0xB2,  0x00,  0x00,  0x1F,  0xFC,  0x10,  0x84,  0x10,  0x84,  0x10,  0x84,  0x1F,  0xFC,  0x10,  0x84,  0x10, 	/* 3E6B0 */
+	0x84,  0x10,  0x84,  0x1F,  0xFC,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x00, 	/* 3E6C0 */
+	0x80,  0xB3,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x1F,  0xFC,  0x10,  0x84,  0x10,  0x84,  0x10,  0x84, 	/* 3E6D0 */
+	0x1F,  0xFC,  0x10,  0x84,  0x10,  0x84,  0x1F,  0xFC,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80, 	/* 3E6E0 */
+	0x00,  0x80,  0xB7,  0x00,  0x00,  0x1F,  0xF8,  0x11,  0x08,  0x11,  0x08,  0x1F,  0xF8,  0x11,  0x08,  0x11, 	/* 3E6F0 */
+	0x08,  0x1F,  0xF8,  0x01,  0x00,  0x01,  0x00,  0x3F,  0xFC,  0x01,  0x04,  0x02,  0x04,  0x04,  0x04,  0x18, 	/* 3E700 */
+	0x04,  0x60,  0x18,  0xB8,  0x04,  0x00,  0x04,  0x00,  0x07,  0xFE,  0x08,  0x02,  0x0F,  0xF2,  0x19,  0x12, 	/* 3E710 */
+	0x29,  0x12,  0x49,  0x12,  0x0F,  0xF2,  0x09,  0x12,  0x09,  0x12,  0x09,  0x12,  0x0F,  0xF2,  0x00,  0x02, 	/* 3E720 */
+	0x00,  0x04,  0x00,  0x38,  0xBA,  0x00,  0x00,  0x3F,  0x80,  0x24,  0xFF,  0x24,  0x88,  0x24,  0x88,  0x3F, 	/* 3E730 */
+	0x88,  0x24,  0x88,  0x24,  0x88,  0x24,  0x88,  0x24,  0x88,  0x3F,  0x88,  0x00,  0x08,  0x00,  0x08,  0x00, 	/* 3E740 */
+	0x08,  0x00,  0x08,  0x00,  0x18,  0xBB,  0x00,  0x00,  0x7F,  0xFF,  0x00,  0x80,  0x00,  0x80,  0x27,  0xF2, 	/* 3E750 */
+	0x24,  0x92,  0x24,  0x92,  0x24,  0x92,  0x27,  0xF2,  0x24,  0x92,  0x24,  0x92,  0x24,  0x92,  0x27,  0xF2, 	/* 3E760 */
+	0x20,  0x02,  0x3F,  0xFE,  0x00,  0x00,  0xBC,  0x00,  0x00,  0x1F,  0xFC,  0x10,  0x84,  0x10,  0x84,  0x1F, 	/* 3E770 */
+	0xFC,  0x10,  0x84,  0x10,  0x84,  0x1F,  0xFC,  0x00,  0x00,  0x00,  0x00,  0x7F,  0xFF,  0x00,  0x80,  0x00, 	/* 3E780 */
+	0x80,  0x00,  0x80,  0x00,  0x80,  0x01,  0x80,  0x84,  0x04,  0x04,  0x42,  0x04,  0x21,  0x08,  0x11,  0x08, 	/* 3E790 */
+	0x10,  0x10,  0x00,  0x20,  0x3F,  0xF8,  0x21,  0x08,  0x21,  0x08,  0x21,  0x08,  0x3F,  0xF8,  0x21,  0x08, 	/* 3E7A0 */
+	0x21,  0x08,  0x21,  0x08,  0x3F,  0xF8,  0x00,  0x00,  0x86,  0x08,  0x10,  0x08,  0x10,  0x08,  0x10,  0x7F, 	/* 3E7B0 */
+	0x90,  0x00,  0x10,  0x00,  0x10,  0x3F,  0x10,  0x29,  0x10,  0x29,  0x10,  0x29,  0x24,  0x3F,  0x24,  0x29, 	/* 3E7C0 */
+	0x22,  0x29,  0x42,  0x29,  0x4E,  0x3F,  0xF1,  0x00,  0x01,  0x89,  0x00,  0x20,  0x00,  0x20,  0x7C,  0x20, 	/* 3E7D0 */
+	0x55,  0xFE,  0x54,  0x20,  0x54,  0x20,  0x54,  0x20,  0x7F,  0xFF,  0x54,  0x20,  0x54,  0x30,  0x54,  0x50, 	/* 3E7E0 */
+	0x54,  0x48,  0x7C,  0x88,  0x01,  0x04,  0x02,  0x02,  0x0C,  0x01,  0x8A,  0x00,  0x48,  0x00,  0x48,  0x7C, 	/* 3E7F0 */
+	0x48,  0x55,  0xFE,  0x54,  0x48,  0x54,  0x48,  0x54,  0x48,  0x7C,  0x48,  0x54,  0x48,  0x57,  0xFF,  0x54, 	/* 3E800 */
+	0x48,  0x54,  0x88,  0x7C,  0x88,  0x01,  0x08,  0x02,  0x08,  0x04,  0x08,  0x8B,  0x00,  0x40,  0x00,  0x40, 	/* 3E810 */
+	0x7E,  0x40,  0x52,  0x7F,  0x52,  0x44,  0x52,  0x84,  0x52,  0xC4,  0x7F,  0x44,  0x52,  0x48,  0x52,  0x28, 	/* 3E820 */
+	0x52,  0x10,  0x52,  0x18,  0x7E,  0x28,  0x00,  0x44,  0x01,  0x82,  0x06,  0x01,  0x8C,  0x00,  0x00,  0x1F, 	/* 3E830 */
+	0xFC,  0x10,  0x84,  0x10,  0x84,  0x1F,  0xFC,  0x10,  0x84,  0x10,  0x84,  0x1F,  0xFC,  0x01,  0x40,  0x06, 	/* 3E840 */
+	0x30,  0x1A,  0x1C,  0x62,  0x13,  0x04,  0x10,  0x04,  0x10,  0x08,  0x10,  0x10,  0x10,  0x8D,  0x00,  0x20, 	/* 3E850 */
+	0x00,  0x20,  0x7C,  0x50,  0x54,  0x50,  0x54,  0x88,  0x55,  0x8C,  0x56,  0x8A,  0x7C,  0x89,  0x54,  0x88, 	/* 3E860 */
+	0x54,  0x88,  0x54,  0x88,  0x54,  0x88,  0x7D,  0x08,  0x01,  0x08,  0x02,  0x08,  0x04,  0x08,  0x8F,  0x00, 	/* 3E870 */
+	0x00,  0x1F,  0xF8,  0x10,  0x88,  0x10,  0x88,  0x1F,  0xF8,  0x10,  0x88,  0x10,  0x88,  0x1F,  0xF8,  0x00, 	/* 3E880 */
+	0x00,  0x7F,  0xFF,  0x09,  0x04,  0x08,  0x88,  0x08,  0x50,  0x0B,  0x20,  0x0C,  0x18,  0x30,  0x07,  0x91, 	/* 3E890 */
+	0x08,  0x00,  0x08,  0xFE,  0x08,  0x92,  0x0A,  0x92,  0x0A,  0x92,  0x2A,  0x92,  0x2C,  0x92,  0x28,  0xFE, 	/* 3E8A0 */
+	0x28,  0x92,  0x48,  0x92,  0x0C,  0x92,  0x0A,  0x92,  0x11,  0x92,  0x10,  0x92,  0x20,  0xFE,  0x40,  0x00, 	/* 3E8B0 */
+	0x94,  0x00,  0x20,  0x7C,  0x22,  0x55,  0x22,  0x54,  0xA4,  0x54,  0xA8,  0x54,  0x20,  0x7D,  0xFE,  0x54, 	/* 3E8C0 */
+	0x20,  0x54,  0x20,  0x54,  0x20,  0x57,  0xFF,  0x54,  0x20,  0x7C,  0x20,  0x00,  0x20,  0x00,  0x20,  0x00, 	/* 3E8D0 */
+	0x20,  0x99,  0x06,  0x00,  0x38,  0xFE,  0x20,  0x12,  0x24,  0x12,  0x22,  0x12,  0x26,  0x22,  0x39,  0x42, 	/* 3E8E0 */
+	0x60,  0x8C,  0x1F,  0xF8,  0x11,  0x08,  0x11,  0x08,  0x1F,  0xF8,  0x11,  0x08,  0x11,  0x08,  0x1F,  0xF8, 	/* 3E8F0 */
+	0x00,  0x00,  0x9A,  0x01,  0x00,  0x01,  0x20,  0x02,  0x18,  0x1F,  0xF4,  0x01,  0x00,  0x7F,  0xFF,  0x02, 	/* 3E900 */
+	0x20,  0x04,  0x10,  0x1F,  0xFC,  0x68,  0x8B,  0x08,  0x88,  0x0F,  0xF8,  0x08,  0x88,  0x08,  0x88,  0x0F, 	/* 3E910 */
+	0xF8,  0x00,  0x00,  0x9B,  0x00,  0x20,  0x00,  0x20,  0x7C,  0x50,  0x54,  0x48,  0x54,  0x84,  0x55,  0x12, 	/* 3E920 */
+	0x56,  0x21,  0x7C,  0x40,  0x55,  0x88,  0x54,  0x10,  0x54,  0x62,  0x55,  0x84,  0x7C,  0x08,  0x00,  0x10, 	/* 3E930 */
+	0x00,  0x60,  0x03,  0x80,  0x9C,  0x00,  0x80,  0x00,  0x80,  0x7F,  0xFF,  0x02,  0x40,  0x02,  0x50,  0x1C, 	/* 3E940 */
+	0x88,  0x03,  0x3C,  0x7F,  0xC4,  0x00,  0x02,  0x1F,  0xFA,  0x10,  0x88,  0x1F,  0xF8,  0x10,  0x88,  0x10, 	/* 3E950 */
+	0x88,  0x1F,  0xF8,  0x00,  0x00,  0x9D,  0x08,  0x20,  0x08,  0x20,  0x08,  0x3C,  0x7F,  0xA4,  0x00,  0x24, 	/* 3E960 */
+	0x3F,  0x44,  0x29,  0x44,  0x29,  0x88,  0x29,  0x08,  0x3F,  0x08,  0x29,  0x14,  0x29,  0x14,  0x29,  0x22, 	/* 3E970 */
+	0x3F,  0x42,  0x00,  0x81,  0x01,  0x01,  0xA0,  0x00,  0x80,  0x01,  0x00,  0x0F,  0xF0,  0x08,  0x10,  0x0F, 	/* 3E980 */
+	0xF0,  0x08,  0x10,  0x08,  0x10,  0x0F,  0xF0,  0x00,  0x00,  0x3F,  0xFC,  0x20,  0x84,  0x3F,  0xFC,  0x20, 	/* 3E990 */
+	0x84,  0x20,  0x84,  0x3F,  0xFC,  0x00,  0x00,  0xA2,  0x00,  0x00,  0x1F,  0xFC,  0x10,  0x84,  0x1F,  0xFC, 	/* 3E9A0 */
+	0x10,  0x84,  0x1F,  0xFC,  0x08,  0x88,  0x08,  0x88,  0x7F,  0xFF,  0x08,  0x88,  0x08,  0x88,  0x3F,  0xFE, 	/* 3E9B0 */
+	0x00,  0x80,  0x1F,  0xFC,  0x00,  0x80,  0x00,  0x80,  0xA4,  0x00,  0x20,  0x00,  0x20,  0x7D,  0xFC,  0x54, 	/* 3E9C0 */
+	0x20,  0x54,  0x20,  0x54,  0x20,  0x57,  0xFF,  0x7C,  0x08,  0x54,  0x08,  0x57,  0xFF,  0x54,  0x08,  0x54, 	/* 3E9D0 */
+	0x88,  0x7C,  0x48,  0x00,  0x48,  0x00,  0x08,  0x00,  0x18,  0xA5,  0x00,  0x40,  0x00,  0x40,  0x7C,  0x7C, 	/* 3E9E0 */
+	0x54,  0x84,  0x54,  0x88,  0x55,  0x50,  0x56,  0x30,  0x7C,  0x48,  0x54,  0x84,  0x55,  0x02,  0x56,  0xFD, 	/* 3E9F0 */
+	0x54,  0x84,  0x54,  0x84,  0x7C,  0x84,  0x00,  0xFC,  0x00,  0x00,  0xA6,  0x00,  0x20,  0x00,  0x20,  0x7D, 	/* 3EA00 */
+	0xFC,  0x54,  0x20,  0x54,  0x20,  0x54,  0x20,  0x57,  0xFF,  0x7C,  0x20,  0x54,  0x20,  0x54,  0x20,  0x55, 	/* 3EA10 */
+	0xFC,  0x54,  0x20,  0x7C,  0x20,  0x44,  0x20,  0x03,  0xFF,  0x00,  0x00,  0xA7,  0x00,  0x00,  0x1F,  0xFC, 	/* 3EA20 */
+	0x10,  0x84,  0x1F,  0xFC,  0x10,  0x84,  0x1F,  0xFC,  0x01,  0x00,  0x03,  0xF8,  0x0E,  0x10,  0x31,  0xE0, 	/* 3EA30 */
+	0x06,  0x1C,  0x7F,  0xFB,  0x08,  0x08,  0x08,  0x08,  0x0F,  0xF8,  0x00,  0x00,  0xA9,  0x00,  0x20,  0x00, 	/* 3EA40 */
+	0x20,  0x7C,  0x20,  0x57,  0xFF,  0x54,  0x20,  0x54,  0x22,  0x54,  0x52,  0x7C,  0x54,  0x54,  0x94,  0x55, 	/* 3EA50 */
+	0x98,  0x56,  0x90,  0x54,  0x88,  0x7C,  0x88,  0x00,  0xB4,  0x00,  0xC2,  0x03,  0x01,  0xAA,  0x00,  0x08, 	/* 3EA60 */
+	0x00,  0x70,  0x1F,  0x84,  0x08,  0x88,  0x04,  0x90,  0x7F,  0xFF,  0x02,  0xA0,  0x04,  0x90,  0x18,  0x8C, 	/* 3EA70 */
+	0x6F,  0xFB,  0x08,  0x88,  0x0F,  0xF8,  0x08,  0x88,  0x08,  0x88,  0x0F,  0xF8,  0x00,  0x00,  0xAB,  0x00, 	/* 3EA80 */
+	0x80,  0x1F,  0xFC,  0x00,  0x84,  0x7F,  0xFF,  0x00,  0x84,  0x1F,  0xFC,  0x00,  0x80,  0x1F,  0xFE,  0x00, 	/* 3EA90 */
+	0x80,  0x7F,  0xFF,  0x08,  0x88,  0x0F,  0xF8,  0x08,  0x88,  0x0F,  0xF8,  0x7F,  0xFF,  0x00,  0x00,  0xAD, 	/* 3EAA0 */
+	0x00,  0x10,  0x00,  0x10,  0x7C,  0x28,  0x54,  0x28,  0x54,  0x44,  0x54,  0x82,  0x55,  0x7D,  0x7E,  0x10, 	/* 3EAB0 */
+	0x54,  0x10,  0x55,  0xFF,  0x54,  0x10,  0x54,  0x94,  0x7C,  0x92,  0x01,  0x11,  0x02,  0x10,  0x00,  0x30, 	/* 3EAC0 */
+	0xB0,  0x00,  0x00,  0x1F,  0xFC,  0x10,  0x84,  0x10,  0x84,  0x1F,  0xFC,  0x10,  0x84,  0x10,  0x84,  0x1F, 	/* 3EAD0 */
+	0xFC,  0x02,  0x20,  0x1F,  0xFC,  0x02,  0x20,  0x02,  0x20,  0x7F,  0xFF,  0x02,  0x30,  0x0C,  0x0C,  0x30, 	/* 3EAE0 */
+	0x02,  0xB3,  0x00,  0x00,  0x1F,  0xF8,  0x11,  0x08,  0x1F,  0xF8,  0x11,  0x08,  0x1F,  0xF8,  0x00,  0x00, 	/* 3EAF0 */
+	0x7F,  0xFE,  0x40,  0x02,  0x4F,  0xF2,  0x08,  0x10,  0x0F,  0xF0,  0x08,  0x10,  0x0F,  0xF0,  0x08,  0x10, 	/* 3EB00 */
+	0x7F,  0xFE,  0xB4,  0x00,  0x20,  0x7C,  0x20,  0x55,  0xFE,  0x54,  0x20,  0x54,  0xFC,  0x54,  0x20,  0x7F, 	/* 3EB10 */
+	0xFF,  0x54,  0x40,  0x54,  0x44,  0x57,  0xFF,  0x54,  0x84,  0x7C,  0x84,  0x01,  0x44,  0x02,  0x44,  0x04, 	/* 3EB20 */
+	0x04,  0x00,  0x0C,  0xB6,  0x11,  0x10,  0x09,  0x10,  0x09,  0x20,  0x7F,  0xFE,  0x40,  0x02,  0x4F,  0xE2, 	/* 3EB30 */
+	0x08,  0x20,  0x0F,  0xE0,  0x00,  0x00,  0x3F,  0xF8,  0x21,  0x08,  0x3F,  0xF8,  0x21,  0x08,  0x21,  0x08, 	/* 3EB40 */
+	0x3F,  0xF8,  0x00,  0x00,  0xB7,  0x00,  0x00,  0x03,  0xDE,  0x7C,  0x42,  0x55,  0x4A,  0x54,  0x84,  0x54, 	/* 3EB50 */
+	0xC6,  0x55,  0x4A,  0x7E,  0x10,  0x54,  0x00,  0x57,  0xFE,  0x54,  0x52,  0x55,  0x4A,  0x7C,  0x84,  0x01, 	/* 3EB60 */
+	0x4C,  0x02,  0x52,  0x0C,  0x21,  0xB8,  0x00,  0x20,  0x00,  0x20,  0x7F,  0xFE,  0x54,  0x30,  0x54,  0x48, 	/* 3EB70 */
+	0x55,  0x84,  0x54,  0x00,  0x7F,  0xFF,  0x54,  0x04,  0x55,  0xE4,  0x55,  0x24,  0x55,  0x24,  0x7D,  0x24, 	/* 3EB80 */
+	0x01,  0xE4,  0x00,  0x04,  0x00,  0x0C,  0xBF,  0x08,  0x90,  0x0A,  0x94,  0x32,  0xE4,  0x0C,  0x98,  0x04, 	/* 3EB90 */
+	0x88,  0x0A,  0x94,  0x3E,  0xBE,  0x01,  0x52,  0x7F,  0xFF,  0x1F,  0x48,  0x15,  0x48,  0x1F,  0x30,  0x15, 	/* 3EBA0 */
+	0x12,  0x15,  0x2A,  0x1F,  0x46,  0x01,  0x82,  0x82,  0x0F,  0xF8,  0x08,  0x88,  0x0F,  0xF8,  0x08,  0x88, 	/* 3EBB0 */
+	0x3F,  0xFE,  0x0C,  0x18,  0x03,  0x60,  0x1C,  0x1C,  0x7F,  0xFF,  0x20,  0x02,  0x27,  0xF2,  0x04,  0x10, 	/* 3EBC0 */
+	0x07,  0xF0,  0x04,  0x10,  0x7F,  0xFF,  0x00,  0x00,  0x86,  0x00,  0x00,  0x7D,  0xFF,  0x04,  0x92,  0x04, 	/* 3EBD0 */
+	0xFE,  0x3C,  0x92,  0x20,  0xFE,  0x20,  0x00,  0x3D,  0xFF,  0x04,  0xFE,  0x14,  0x92,  0x7C,  0xFE,  0x14, 	/* 3EBE0 */
+	0x92,  0x1C,  0xFE,  0x64,  0x00,  0x0B,  0xFF,  0x30,  0x00,  0x87,  0x00,  0x20,  0x03,  0xFE,  0x7C,  0x20, 	/* 3EBF0 */
+	0x54,  0xFC,  0x54,  0x00,  0x57,  0xFF,  0x54,  0x02,  0x7C,  0xF8,  0x54,  0x20,  0x57,  0xFF,  0x54,  0x04, 	/* 3EC00 */
+	0x55,  0xFF,  0x7D,  0x64,  0x01,  0x54,  0x01,  0xC4,  0x00,  0x0C,  0x89,  0x07,  0xF0,  0x04,  0x90,  0x07, 	/* 3EC10 */
+	0xF0,  0x04,  0x90,  0x3F,  0xFE,  0x2A,  0x2A,  0x3E,  0x3E,  0x2A,  0x2A,  0x3E,  0xBE,  0x00,  0x80,  0x3F, 	/* 3EC20 */
+	0xFE,  0x21,  0x02,  0x03,  0xF8,  0x0D,  0x10,  0x00,  0xA0,  0x7F,  0xFF,  0x8A,  0x07,  0xF0,  0x04,  0x90, 	/* 3EC30 */
+	0x07,  0xF0,  0x04,  0x90,  0x3F,  0xFE,  0x29,  0x52,  0x3F,  0x7E,  0x29,  0x52,  0x7F,  0xFF,  0x40,  0x01, 	/* 3EC40 */
+	0x47,  0xF1,  0x04,  0x10,  0x07,  0xF0,  0x04,  0x10,  0x7F,  0xFF,  0x00,  0x00,  0x8B,  0x00,  0x00,  0x7F, 	/* 3EC50 */
+	0xFE,  0x00,  0x82,  0x00,  0x84,  0x00,  0x88,  0x08,  0x80,  0x08,  0x80,  0x08,  0xFC,  0x08,  0x80,  0x08, 	/* 3EC60 */
+	0x80,  0x08,  0x80,  0x08,  0x80,  0x14,  0x80,  0x12,  0x80,  0x21,  0x80,  0x40,  0x7F,  0x8E,  0x00,  0x10, 	/* 3EC70 */
+	0x3F,  0x10,  0x01,  0xFF,  0x02,  0x10,  0x04,  0x10,  0x14,  0xFE,  0x14,  0x92,  0x17,  0x92,  0x14,  0xFE, 	/* 3EC80 */
+	0x14,  0x10,  0x14,  0x38,  0x14,  0x54,  0x17,  0x92,  0x1D,  0x11,  0x60,  0x10,  0x00,  0x10,  0x8F,  0x00, 	/* 3EC90 */
+	0x10,  0x3F,  0x10,  0x01,  0xFF,  0x02,  0x10,  0x04,  0x28,  0x14,  0x46,  0x14,  0xFD,  0x17,  0x00,  0x14, 	/* 3ECA0 */
+	0x54,  0x14,  0x54,  0x14,  0x54,  0x14,  0x54,  0x17,  0x54,  0x1C,  0x95,  0x60,  0x85,  0x01,  0x03,  0x91, 	/* 3ECB0 */
+	0x20,  0x00,  0x22,  0x7E,  0x3C,  0x24,  0x21,  0x18,  0x21,  0x08,  0x1F,  0xFF,  0x10,  0x12,  0x1F,  0x14, 	/* 3ECC0 */
+	0x24,  0x50,  0x44,  0x5E,  0x3F,  0xD0,  0x04,  0x50,  0x0A,  0x70,  0x09,  0x90,  0x10,  0x8C,  0x21,  0x03, 	/* 3ECD0 */
+	0x94,  0x00,  0x40,  0x00,  0x40,  0x0F,  0xFF,  0x48,  0x00,  0x28,  0x00,  0x28,  0x00,  0x0B,  0xFF,  0x08, 	/* 3ECE0 */
+	0x20,  0x18,  0x20,  0x28,  0x20,  0x48,  0x20,  0x10,  0x20,  0x10,  0x20,  0x20,  0x20,  0x40,  0x20,  0x00, 	/* 3ECF0 */
+	0x60,  0x9A,  0x00,  0x40,  0x00,  0x40,  0x0F,  0xFF,  0x48,  0x40,  0x28,  0x40,  0x28,  0x78,  0x08,  0x88, 	/* 3ED00 */
+	0x08,  0x88,  0x19,  0x10,  0x2A,  0x10,  0x48,  0x20,  0x10,  0x30,  0x10,  0x48,  0x20,  0x84,  0x43,  0x02, 	/* 3ED10 */
+	0x0C,  0x02,  0x9D,  0x00,  0x40,  0x00,  0x40,  0x0F,  0xFF,  0x48,  0x00,  0x28,  0x20,  0x28,  0x20,  0x08, 	/* 3ED20 */
+	0x20,  0x0A,  0x22,  0x1A,  0x22,  0x2A,  0x22,  0x4A,  0x22,  0x12,  0x22,  0x12,  0x22,  0x22,  0x22,  0x43, 	/* 3ED30 */
+	0xFE,  0x00,  0x00,  0xA3,  0x00,  0x40,  0x00,  0x40,  0x0F,  0xFF,  0x48,  0x00,  0x28,  0x48,  0x28,  0x44, 	/* 3ED40 */
+	0x08,  0x44,  0x0F,  0xFF,  0x18,  0x40,  0x28,  0x40,  0x48,  0x60,  0x10,  0xA0,  0x10,  0xA1,  0x21,  0x21, 	/* 3ED50 */
+	0x46,  0x21,  0x18,  0x1F,  0xA5,  0x00,  0x40,  0x00,  0x40,  0x0F,  0xFF,  0x48,  0x20,  0x28,  0x20,  0x28, 	/* 3ED60 */
+	0x50,  0x08,  0x88,  0x09,  0x04,  0x1E,  0x8B,  0x28,  0x88,  0x48,  0x88,  0x10,  0x88,  0x11,  0x08,  0x21, 	/* 3ED70 */
+	0x08,  0x42,  0x08,  0x04,  0x08,  0xAB,  0x00,  0x40,  0x00,  0x40,  0x0F,  0xFF,  0x48,  0x00,  0x29,  0xF0, 	/* 3ED80 */
+	0x29,  0x12,  0x09,  0x12,  0x09,  0x0E,  0x1A,  0x00,  0x2F,  0xF8,  0x48,  0x88,  0x10,  0x90,  0x10,  0x60, 	/* 3ED90 */
+	0x20,  0x50,  0x41,  0x88,  0x0E,  0x06,  0xB1,  0x00,  0x40,  0x00,  0x40,  0x0F,  0xFF,  0x48,  0x80,  0x28, 	/* 3EDA0 */
+	0x80,  0x29,  0xFC,  0x09,  0x04,  0x0B,  0xE4,  0x1D,  0x24,  0x29,  0x24,  0x49,  0xE4,  0x11,  0x08,  0x11, 	/* 3EDB0 */
+	0x30,  0x21,  0x02,  0x41,  0x02,  0x00,  0xFE,  0xB2,  0x00,  0x40,  0x00,  0x40,  0x0F,  0xFF,  0x48,  0x20, 	/* 3EDC0 */
+	0x28,  0x20,  0x2B,  0xFE,  0x0A,  0x22,  0x0A,  0x24,  0x1B,  0xF8,  0x2A,  0x88,  0x4A,  0x88,  0x12,  0x50, 	/* 3EDD0 */
+	0x14,  0x20,  0x24,  0x50,  0x49,  0x8C,  0x16,  0x03,  0xB3,  0x00,  0x40,  0x00,  0x40,  0x0F,  0xFF,  0x48, 	/* 3EDE0 */
+	0x00,  0x29,  0x08,  0x29,  0x08,  0x0F,  0xFF,  0x09,  0x08,  0x19,  0x08,  0x29,  0x08,  0x49,  0xF8,  0x11, 	/* 3EDF0 */
+	0x08,  0x11,  0x08,  0x21,  0x08,  0x41,  0xF8,  0x00,  0x00,  0xB5,  0x00,  0x40,  0x00,  0x40,  0x0F,  0xFF, 	/* 3EE00 */
+	0x48,  0x00,  0x28,  0x90,  0x28,  0x90,  0x0A,  0x92,  0x0A,  0x92,  0x1A,  0xF4,  0x2A,  0x98,  0x4A,  0x90, 	/* 3EE10 */
+	0x12,  0x90,  0x12,  0x90,  0x22,  0xF1,  0x43,  0x11,  0x0C,  0x0F,  0xB8,  0x00,  0x40,  0x00,  0x40,  0x0F, 	/* 3EE20 */
+	0xFF,  0x48,  0x00,  0x28,  0x00,  0x29,  0xF8,  0x09,  0x08,  0x09,  0x08,  0x19,  0xF8,  0x29,  0x08,  0x49, 	/* 3EE30 */
+	0x08,  0x11,  0x08,  0x11,  0xF8,  0x20,  0x00,  0x5F,  0xFF,  0x00,  0x00,  0xB9,  0x00,  0x40,  0x00,  0x40, 	/* 3EE40 */
+	0x0F,  0xFF,  0x08,  0x40,  0x48,  0x60,  0x28,  0x90,  0x29,  0x0C,  0x0E,  0x23,  0x18,  0xC8,  0x2B,  0x10, 	/* 3EE50 */
+	0x48,  0x20,  0x10,  0xC4,  0x13,  0x08,  0x20,  0x30,  0x40,  0xC0,  0x07,  0x00,  0xBC,  0x00,  0x40,  0x00, 	/* 3EE60 */
+	0x40,  0x0F,  0xFF,  0x48,  0x80,  0x28,  0xF8,  0x29,  0x08,  0x0E,  0xD0,  0x08,  0x60,  0x18,  0x90,  0x29, 	/* 3EE70 */
+	0x0C,  0x4E,  0x63,  0x10,  0x10,  0x10,  0x00,  0x21,  0xE0,  0x40,  0x18,  0x00,  0x04,  0xBD,  0x00,  0x80, 	/* 3EE80 */
+	0x00,  0x80,  0x0F,  0xFF,  0x48,  0x00,  0x28,  0x00,  0x29,  0xF8,  0x09,  0x08,  0x09,  0x08,  0x19,  0xF8, 	/* 3EE90 */
+	0x29,  0x08,  0x49,  0x08,  0x11,  0xF8,  0x11,  0x08,  0x21,  0x08,  0x5F,  0xFF,  0x00,  0x00,  0xBE,  0x00, 	/* 3EEA0 */
+	0x20,  0x00,  0x20,  0x0F,  0xFF,  0x48,  0x80,  0x28,  0x80,  0x29,  0xFE,  0x09,  0x20,  0x0A,  0x20,  0x18, 	/* 3EEB0 */
+	0x20,  0x2F,  0xFF,  0x48,  0x30,  0x10,  0x50,  0x10,  0x48,  0x20,  0x84,  0x43,  0x02,  0x0C,  0x01,  0x82, 	/* 3EEC0 */
+	0x00,  0x40,  0x00,  0x40,  0x0F,  0xFF,  0x49,  0x00,  0x29,  0x00,  0x29,  0x1E,  0x0F,  0xD2,  0x09,  0x52, 	/* 3EED0 */
+	0x19,  0x52,  0x29,  0x52,  0x49,  0x52,  0x12,  0x52,  0x12,  0x52,  0x24,  0x5E,  0x48,  0x40,  0x11,  0x80, 	/* 3EEE0 */
+	0x83,  0x00,  0x40,  0x00,  0x40,  0x0F,  0xFF,  0x48,  0x20,  0x28,  0x20,  0x2F,  0xFF,  0x08,  0x40,  0x08, 	/* 3EEF0 */
+	0x40,  0x18,  0x90,  0x2B,  0x10,  0x48,  0xA0,  0x10,  0x48,  0x10,  0x84,  0x21,  0x3C,  0x4F,  0xC2,  0x00, 	/* 3EF00 */
+	0x02,  0x85,  0x00,  0x40,  0x00,  0x40,  0x0F,  0xFF,  0x48,  0x00,  0x28,  0x00,  0x2F,  0xFF,  0x08,  0x20, 	/* 3EF10 */
+	0x08,  0x20,  0x1B,  0xFE,  0x2A,  0x22,  0x4A,  0x62,  0x12,  0x52,  0x12,  0x8A,  0x23,  0x0A,  0x42,  0x02, 	/* 3EF20 */
+	0x02,  0x06,  0x87,  0x00,  0x40,  0x00,  0x40,  0x0F,  0xFF,  0x48,  0x00,  0x28,  0x00,  0x2F,  0xFE,  0x08, 	/* 3EF30 */
+	0x20,  0x08,  0x20,  0x19,  0x20,  0x29,  0x3C,  0x49,  0x20,  0x11,  0x20,  0x11,  0x20,  0x21,  0x20,  0x5F, 	/* 3EF40 */
+	0xFF,  0x00,  0x00,  0x8A,  0x00,  0x40,  0x00,  0x40,  0x0F,  0xFF,  0x48,  0x20,  0x28,  0x20,  0x28,  0x50, 	/* 3EF50 */
+	0x09,  0x8C,  0x0E,  0x03,  0x1B,  0xFE,  0x28,  0x20,  0x48,  0x20,  0x13,  0xFE,  0x10,  0x20,  0x20,  0x20, 	/* 3EF60 */
+	0x4F,  0xFF,  0x00,  0x00,  0x8D,  0x00,  0x40,  0x00,  0x40,  0x0F,  0xFF,  0x48,  0x40,  0x2F,  0xFF,  0x28, 	/* 3EF70 */
+	0x40,  0x0F,  0xFC,  0x08,  0x44,  0x1B,  0xFC,  0x2A,  0x40,  0x4B,  0xFE,  0x10,  0x42,  0x10,  0xAC,  0x21, 	/* 3EF80 */
+	0x10,  0x46,  0x0C,  0x18,  0x03,  0x92,  0x00,  0x40,  0x00,  0x40,  0x0F,  0xFF,  0x49,  0x08,  0x28,  0x88, 	/* 3EF90 */
+	0x28,  0x90,  0x0F,  0xFE,  0x08,  0x20,  0x18,  0x20,  0x2B,  0xFC,  0x48,  0x20,  0x10,  0x20,  0x17,  0xFF, 	/* 3EFA0 */
+	0x20,  0x20,  0x40,  0x20,  0x00,  0x20,  0x94,  0x00,  0x20,  0x00,  0x20,  0x0F,  0xFF,  0x08,  0x20,  0x49, 	/* 3EFB0 */
+	0xFC,  0x28,  0x20,  0x28,  0x20,  0x0F,  0xFF,  0x08,  0x04,  0x18,  0x04,  0x2B,  0xFF,  0x49,  0x04,  0x10, 	/* 3EFC0 */
+	0x84,  0x10,  0x84,  0x20,  0x04,  0x40,  0x0C,  0x95,  0x00,  0x40,  0x00,  0x40,  0x0F,  0xFF,  0x48,  0x00, 	/* 3EFD0 */
+	0x29,  0xF8,  0x29,  0x08,  0x09,  0x08,  0x09,  0xF8,  0x19,  0x08,  0x29,  0x08,  0x49,  0xFA,  0x09,  0x44, 	/* 3EFE0 */
+	0x11,  0x28,  0x11,  0x10,  0x23,  0xCC,  0x4C,  0x03,  0x98,  0x00,  0x40,  0x00,  0x40,  0x0F,  0xFF,  0x48, 	/* 3EFF0 */
+	0x00,  0x2F,  0xFE,  0x28,  0x00,  0x0B,  0xFC,  0x0A,  0x04,  0x1A,  0x04,  0x2A,  0x04,  0x4B,  0xFC,  0x11, 	/* 3F000 */
+	0x08,  0x10,  0x88,  0x20,  0x90,  0x5F,  0xFF,  0x00,  0x00,  0x99,  0x00,  0x40,  0x00,  0x40,  0x0F,  0xFF, 	/* 3F010 */
+	0x48,  0x00,  0x2F,  0xFE,  0x29,  0x24,  0x0A,  0x48,  0x0C,  0x90,  0x1A,  0x48,  0x29,  0x24,  0x48,  0x00, 	/* 3F020 */
+	0x13,  0xFE,  0x10,  0x20,  0x20,  0x20,  0x4F,  0xFF,  0x00,  0x00,  0x9B,  0x00,  0x40,  0x00,  0x40,  0x0F, 	/* 3F030 */
+	0xFF,  0x48,  0x00,  0x2B,  0xFC,  0x28,  0x88,  0x08,  0x50,  0x0B,  0xFE,  0x1A,  0x22,  0x2B,  0xFE,  0x4A, 	/* 3F040 */
+	0x22,  0x12,  0x22,  0x13,  0xFE,  0x22,  0x22,  0x42,  0x22,  0x02,  0x26,  0x9E,  0x00,  0x40,  0x00,  0x40, 	/* 3F050 */
+	0x0F,  0xFF,  0x48,  0x00,  0x2F,  0xFE,  0x28,  0x20,  0x08,  0x70,  0x09,  0xAC,  0x1E,  0x22,  0x28,  0x20, 	/* 3F060 */
+	0x48,  0x20,  0x13,  0xFC,  0x12,  0x04,  0x22,  0x04,  0x43,  0xFC,  0x00,  0x00,  0xA2,  0x00,  0x40,  0x00, 	/* 3F070 */
+	0x40,  0x0F,  0xFF,  0x48,  0x00,  0x28,  0x42,  0x2F,  0x92,  0x09,  0x12,  0x09,  0x12,  0x1F,  0xD2,  0x29, 	/* 3F080 */
+	0x12,  0x4B,  0x92,  0x13,  0x52,  0x15,  0x12,  0x29,  0x02,  0x41,  0x02,  0x01,  0x06,  0xA3,  0x00,  0x80, 	/* 3F090 */
+	0x00,  0x80,  0x0F,  0xFF,  0x48,  0x40,  0x28,  0x40,  0x2F,  0xFE,  0x08,  0x40,  0x08,  0x40,  0x1B,  0xFC, 	/* 3F0A0 */
+	0x28,  0x80,  0x48,  0x40,  0x11,  0x24,  0x15,  0x22,  0x25,  0x09,  0x49,  0x09,  0x10,  0xF8,  0xA9,  0x00, 	/* 3F0B0 */
+	0x40,  0x00,  0x40,  0x0F,  0xFF,  0x48,  0x40,  0x2B,  0xFC,  0x2A,  0x44,  0x0B,  0xFC,  0x0A,  0x44,  0x1B, 	/* 3F0C0 */
+	0xFC,  0x28,  0x40,  0x4F,  0xF8,  0x11,  0x08,  0x10,  0x90,  0x20,  0x60,  0x41,  0x98,  0x1E,  0x07,  0xB0, 	/* 3F0D0 */
+	0x00,  0x40,  0x00,  0x40,  0x0F,  0xFF,  0x48,  0x24,  0x29,  0x24,  0x29,  0x28,  0x0A,  0x20,  0x08,  0x50, 	/* 3F0E0 */
+	0x18,  0x88,  0x2B,  0x26,  0x48,  0x24,  0x11,  0x24,  0x11,  0x28,  0x22,  0x50,  0x41,  0x88,  0x06,  0x07, 	/* 3F0F0 */
+	0xB2,  0x00,  0x20,  0x00,  0x20,  0x0F,  0xFF,  0x48,  0x00,  0x28,  0x88,  0x28,  0x88,  0x0F,  0xFF,  0x08, 	/* 3F100 */
+	0x88,  0x1A,  0xAA,  0x2A,  0xAA,  0x4A,  0xAA,  0x12,  0xAA,  0x12,  0xAA,  0x24,  0xAB,  0x48,  0xA8,  0x00, 	/* 3F110 */
+	0x88,  0xB3,  0x00,  0x40,  0x00,  0x40,  0x0F,  0xFF,  0x48,  0x00,  0x29,  0x08,  0x29,  0x08,  0x0F,  0xFF, 	/* 3F120 */
+	0x09,  0x08,  0x19,  0x08,  0x2B,  0x9C,  0x4B,  0x5C,  0x15,  0x2A,  0x15,  0x2A,  0x29,  0x49,  0x41,  0x08, 	/* 3F130 */
+	0x01,  0x08,  0xB4,  0x00,  0x40,  0x00,  0x40,  0x0F,  0xFF,  0x4A,  0x00,  0x2A,  0x00,  0x2B,  0xDE,  0x2D, 	/* 3F140 */
+	0x12,  0x0D,  0x12,  0x19,  0x12,  0x2F,  0xF2,  0x49,  0x12,  0x12,  0x92,  0x12,  0x92,  0x24,  0x5E,  0x44, 	/* 3F150 */
+	0x00,  0x08,  0x00,  0xBA,  0x00,  0x20,  0x00,  0x20,  0x0F,  0xFF,  0x48,  0x20,  0x28,  0x40,  0x2B,  0xFC, 	/* 3F160 */
+	0x0A,  0x44,  0x0B,  0xFC,  0x1A,  0x44,  0x2B,  0xFC,  0x48,  0x90,  0x11,  0x10,  0x1F,  0xFF,  0x20,  0x10, 	/* 3F170 */
+	0x40,  0x10,  0x00,  0x10,  0xBC,  0x00,  0x40,  0x00,  0x40,  0x0F,  0xFF,  0x48,  0x00,  0x2B,  0xFE,  0x2A, 	/* 3F180 */
+	0x22,  0x0A,  0x22,  0x0B,  0xFE,  0x1A,  0x22,  0x2A,  0xFA,  0x4A,  0x8A,  0x12,  0x8A,  0x12,  0xFA,  0x22, 	/* 3F190 */
+	0x02,  0x43,  0xFE,  0x00,  0x00,  0xBE,  0x00,  0x40,  0x00,  0x40,  0x0F,  0xFF,  0x48,  0x00,  0x2B,  0xBF, 	/* 3F1A0 */
+	0x2A,  0x82,  0x0A,  0x82,  0x0B,  0x3A,  0x1A,  0xAA,  0x2A,  0xAA,  0x4A,  0xAA,  0x12,  0xBA,  0x13,  0x82, 	/* 3F1B0 */
+	0x22,  0x02,  0x42,  0x02,  0x02,  0x06,  0xBF,  0x00,  0x80,  0x00,  0x80,  0x0F,  0xFF,  0x48,  0x04,  0x29, 	/* 3F1C0 */
+	0xF8,  0x28,  0x20,  0x0F,  0xFF,  0x09,  0xAC,  0x1E,  0x23,  0x28,  0x60,  0x4F,  0xFF,  0x18,  0x88,  0x11, 	/* 3F1D0 */
+	0xC8,  0x20,  0x30,  0x40,  0xC8,  0x07,  0x04,  0x81,  0x00,  0x40,  0x00,  0x40,  0x0F,  0xFF,  0x48,  0x20, 	/* 3F1E0 */
+	0x28,  0x20,  0x2F,  0xFE,  0x09,  0x08,  0x09,  0x08,  0x19,  0x8C,  0x2A,  0x52,  0x4C,  0x20,  0x17,  0xFF, 	/* 3F1F0 */
+	0x10,  0x20,  0x20,  0x20,  0x40,  0x20,  0x00,  0x20,  0x89,  0x00,  0x40,  0x00,  0x40,  0x0F,  0xFF,  0x48, 	/* 3F200 */
+	0x20,  0x28,  0x50,  0x29,  0x8C,  0x0E,  0x03,  0x09,  0xFC,  0x18,  0x0A,  0x2B,  0xCA,  0x4B,  0x52,  0x12, 	/* 3F210 */
+	0xD4,  0x13,  0x54,  0x22,  0xCA,  0x42,  0x4A,  0x02,  0xCA,  0x8B,  0x00,  0x40,  0x00,  0x40,  0x0F,  0xFF, 	/* 3F220 */
+	0x48,  0x00,  0x2B,  0xFC,  0x2A,  0x14,  0x0B,  0xE4,  0x0A,  0x44,  0x1B,  0xF4,  0x2B,  0x54,  0x4B,  0x54, 	/* 3F230 */
+	0x13,  0xF4,  0x12,  0x55,  0x24,  0x73,  0x47,  0x8B,  0x08,  0x09,  0x8D,  0x00,  0x40,  0x00,  0x40,  0x0F, 	/* 3F240 */
+	0xFF,  0x48,  0x00,  0x29,  0xF8,  0x29,  0x08,  0x09,  0xF8,  0x09,  0x08,  0x19,  0xF8,  0x28,  0x00,  0x4F, 	/* 3F250 */
+	0xFF,  0x11,  0x00,  0x13,  0xFE,  0x24,  0x92,  0x49,  0x22,  0x02,  0x4C,  0x9F,  0x00,  0x40,  0x00,  0x40, 	/* 3F260 */
+	0x0F,  0xFF,  0x48,  0x00,  0x2B,  0xF8,  0x2A,  0x48,  0x0A,  0x48,  0x0A,  0xA8,  0x1B,  0xF8,  0x28,  0x00, 	/* 3F270 */
+	0x4F,  0xFC,  0x14,  0xA4,  0x14,  0xA4,  0x24,  0xA4,  0x5F,  0xFF,  0x00,  0x00,  0xA0,  0x00,  0x40,  0x00, 	/* 3F280 */
+	0x40,  0x0F,  0xFF,  0x48,  0x00,  0x2B,  0xAE,  0x28,  0x20,  0x0B,  0xDE,  0x08,  0x88,  0x19,  0x04,  0x2B, 	/* 3F290 */
+	0xFE,  0x4D,  0x05,  0x11,  0xFC,  0x11,  0x04,  0x21,  0xFC,  0x41,  0x04,  0x01,  0x0C,  0xA1,  0x00,  0x40, 	/* 3F2A0 */
+	0x00,  0x40,  0x0F,  0xFF,  0x48,  0x20,  0x28,  0x50,  0x28,  0xF8,  0x09,  0x04,  0x0B,  0xFA,  0x1D,  0x09, 	/* 3F2B0 */
+	0x29,  0xF8,  0x49,  0x08,  0x13,  0xF8,  0x12,  0x00,  0x25,  0xFC,  0x49,  0x04,  0x11,  0xFC,  0xA2,  0x00, 	/* 3F2C0 */
+	0x40,  0x00,  0x40,  0x0F,  0xFF,  0x49,  0x00,  0x2A,  0x1C,  0x2B,  0xD5,  0x0A,  0x55,  0x0B,  0x53,  0x1A, 	/* 3F2D0 */
+	0xE0,  0x2B,  0xFE,  0x4E,  0x52,  0x12,  0x54,  0x13,  0x4C,  0x25,  0x54,  0x44,  0x62,  0x08,  0xC1,  0xA4, 	/* 3F2E0 */
+	0x00,  0x40,  0x00,  0x40,  0x0F,  0xFF,  0x48,  0x40,  0x2B,  0x9F,  0x2A,  0x09,  0x0A,  0x89,  0x0A,  0xD1, 	/* 3F2F0 */
+	0x1F,  0x26,  0x28,  0x00,  0x4B,  0xFE,  0x12,  0x22,  0x13,  0xFE,  0x22,  0x22,  0x43,  0xFE,  0x00,  0x00, 	/* 3F300 */
+	0xA7,  0x00,  0x40,  0x00,  0x40,  0x4F,  0xFF,  0x28,  0x3C,  0x28,  0x20,  0x0B,  0xFF,  0x0A,  0x9A,  0x0B, 	/* 3F310 */
+	0xE4,  0x1A,  0x7C,  0x2A,  0x00,  0x4A,  0xFC,  0x14,  0x80,  0x17,  0xFE,  0x28,  0x80,  0x50,  0xFE,  0x00, 	/* 3F320 */
+	0x00,  0xB0,  0x00,  0x40,  0x00,  0x40,  0x0F,  0xFF,  0x48,  0x00,  0x2B,  0xFC,  0x2A,  0x44,  0x0B,  0xFC, 	/* 3F330 */
+	0x0A,  0x44,  0x1B,  0xFC,  0x28,  0xD0,  0x4B,  0x28,  0x10,  0xC4,  0x17,  0xFA,  0x23,  0x50,  0x4C,  0x4C, 	/* 3F340 */
+	0x00,  0x42,  0xB4,  0x00,  0x40,  0x00,  0x40,  0x0F,  0xFF,  0x48,  0x20,  0x2B,  0xFE,  0x28,  0x88,  0x0F, 	/* 3F350 */
+	0xFF,  0x08,  0x00,  0x19,  0xFC,  0x29,  0x04,  0x49,  0xFC,  0x11,  0x04,  0x11,  0xFC,  0x20,  0x20,  0x4F, 	/* 3F360 */
+	0xFF,  0x00,  0x20,  0xBB,  0x00,  0x40,  0x0F,  0xFF,  0x48,  0x20,  0x2B,  0xFC,  0x2A,  0x24,  0x0F,  0xFF, 	/* 3F370 */
+	0x0A,  0x24,  0x1B,  0xFC,  0x28,  0x20,  0x4B,  0xFC,  0x12,  0x24,  0x1F,  0xFF,  0x10,  0x88,  0x23,  0x10, 	/* 3F380 */
+	0x40,  0xF0,  0x0F,  0x0C,  0x82,  0x00,  0x40,  0x00,  0x40,  0x0F,  0xFF,  0x48,  0x40,  0x2F,  0xFE,  0x2A, 	/* 3F390 */
+	0x94,  0x09,  0x08,  0x0B,  0xFC,  0x1D,  0x0A,  0x29,  0xF9,  0x49,  0x08,  0x09,  0xF8,  0x11,  0x58,  0x12, 	/* 3F3A0 */
+	0x44,  0x2C,  0x42,  0x40,  0xC0,  0x86,  0x00,  0x20,  0x00,  0x20,  0x0F,  0xFF,  0x48,  0x88,  0x2A,  0xAA, 	/* 3F3B0 */
+	0x2C,  0xAC,  0x09,  0x52,  0x0A,  0x20,  0x1F,  0xFF,  0x2C,  0x01,  0x4C,  0x41,  0x13,  0xFC,  0x10,  0x44, 	/* 3F3C0 */
+	0x20,  0x84,  0x41,  0x04,  0x06,  0x38,  0x87,  0x00,  0x80,  0x00,  0x80,  0x0F,  0xFF,  0x48,  0x00,  0x2B, 	/* 3F3D0 */
+	0xDE,  0x3A,  0x52,  0x0B,  0xDE,  0x0A,  0x52,  0x1B,  0xDE,  0x2A,  0x7A,  0x4A,  0x4A,  0x12,  0x7A,  0x12, 	/* 3F3E0 */
+	0x4A,  0x22,  0x7A,  0x42,  0x4A,  0x02,  0x06,  0x88,  0x00,  0x40,  0x00,  0x40,  0x0F,  0xFF,  0x48,  0x12, 	/* 3F3F0 */
+	0x2F,  0xD4,  0x28,  0x49,  0x0A,  0x86,  0x09,  0xDE,  0x1A,  0x55,  0x2C,  0x56,  0x4B,  0xE0,  0x12,  0x3E, 	/* 3F400 */
+	0x13,  0xD4,  0x20,  0x48,  0x40,  0x94,  0x07,  0x23,  0x8C,  0x00,  0x40,  0x00,  0x40,  0x0F,  0xFE,  0x48, 	/* 3F410 */
+	0x00,  0x29,  0xF8,  0x29,  0x08,  0x09,  0xF8,  0x08,  0x00,  0x1F,  0x9E,  0x2C,  0x92,  0x4F,  0xDE,  0x10, 	/* 3F420 */
+	0x40,  0x14,  0x44,  0x24,  0x44,  0x47,  0xFC,  0x00,  0x00,  0x92,  0x00,  0x40,  0x0F,  0xFF,  0x08,  0x20, 	/* 3F430 */
+	0x48,  0x50,  0x29,  0xFC,  0x2E,  0x03,  0x0B,  0xD2,  0x0A,  0x52,  0x1B,  0xD2,  0x2A,  0x52,  0x4B,  0xD2, 	/* 3F440 */
+	0x12,  0x46,  0x11,  0x40,  0x29,  0x24,  0x49,  0x0A,  0x10,  0xF9,  0x96,  0x00,  0x80,  0x00,  0x80,  0x0F, 	/* 3F450 */
+	0xFF,  0x48,  0x08,  0x2B,  0xFE,  0x2A,  0x62,  0x0A,  0x52,  0x0B,  0xD4,  0x1A,  0x7F,  0x2A,  0x08,  0x4B, 	/* 3F460 */
+	0xC8,  0x0E,  0x7F,  0x16,  0x48,  0x2A,  0x48,  0x53,  0xC8,  0x02,  0x48,  0x98,  0x00,  0x40,  0x00,  0x40, 	/* 3F470 */
+	0x0F,  0xFF,  0x48,  0x90,  0x2F,  0xFE,  0x28,  0x90,  0x0B,  0xFC,  0x0A,  0x44,  0x1B,  0xFC,  0x2A,  0x44, 	/* 3F480 */
+	0x4B,  0xFC,  0x10,  0x40,  0x17,  0xFE,  0x24,  0x52,  0x47,  0xEA,  0x04,  0x06,  0x9C,  0x00,  0x40,  0x00, 	/* 3F490 */
+	0x40,  0x1F,  0xFF,  0x10,  0x00,  0x57,  0xDC,  0x34,  0x54,  0x17,  0xD5,  0x15,  0x13,  0x37,  0xE1,  0x35, 	/* 3F4A0 */
+	0x5E,  0x55,  0x4A,  0x17,  0xEA,  0x28,  0x04,  0x29,  0x44,  0x52,  0x2A,  0x04,  0x31,  0xA1,  0x00,  0x20, 	/* 3F4B0 */
+	0x00,  0x20,  0x0F,  0xFF,  0x48,  0x00,  0x2A,  0xBE,  0x2B,  0x14,  0x0A,  0x48,  0x09,  0xC8,  0x1A,  0x3F, 	/* 3F4C0 */
+	0x2B,  0xCA,  0x4D,  0x28,  0x17,  0xEE,  0x11,  0x28,  0x22,  0xB8,  0x44,  0xA8,  0x08,  0x47,  0xA2,  0x00, 	/* 3F4D0 */
+	0x20,  0x00,  0x20,  0x0F,  0xFF,  0x48,  0x88,  0x2B,  0xFE,  0x28,  0x20,  0x09,  0xFC,  0x08,  0x20,  0x1F, 	/* 3F4E0 */
+	0xFF,  0x29,  0x08,  0x4B,  0xFC,  0x15,  0x0B,  0x19,  0xFA,  0x21,  0x24,  0x41,  0xD8,  0x07,  0x07,  0xA7, 	/* 3F4F0 */
+	0x00,  0x20,  0x00,  0x20,  0x0F,  0xFF,  0x48,  0x00,  0x2B,  0xFF,  0x2A,  0xEE,  0x0A,  0x44,  0x0B,  0xFF, 	/* 3F500 */
+	0x1A,  0xEE,  0x2B,  0x55,  0x4A,  0x44,  0x12,  0x90,  0x14,  0x9E,  0x24,  0x90,  0x4B,  0xFF,  0x00,  0x00, 	/* 3F510 */
+	0xA8,  0x00,  0x20,  0x0F,  0xFF,  0x08,  0x00,  0x4B,  0xFE,  0x28,  0x20,  0x2F,  0xFF,  0x0C,  0x21,  0x0D, 	/* 3F520 */
+	0xAD,  0x18,  0x88,  0x29,  0x10,  0x4B,  0xFE,  0x15,  0x10,  0x11,  0xFE,  0x21,  0x10,  0x41,  0xFE,  0x00, 	/* 3F530 */
+	0x00,  0xA9,  0x00,  0x20,  0x00,  0x20,  0x0F,  0xFF,  0x49,  0x00,  0x29,  0x3F,  0x2F,  0xC9,  0x09,  0x13, 	/* 3F540 */
+	0x0F,  0xFE,  0x1D,  0x52,  0x2F,  0xDE,  0x49,  0x12,  0x13,  0x9E,  0x13,  0x52,  0x25,  0x5E,  0x49,  0x12, 	/* 3F550 */
+	0x01,  0x61,  0xAA,  0x00,  0x20,  0x00,  0x20,  0x0F,  0xFF,  0x48,  0x48,  0x29,  0xBE,  0x2F,  0x08,  0x09, 	/* 3F560 */
+	0x3E,  0x09,  0x08,  0x1F,  0xFF,  0x29,  0x92,  0x4B,  0x5E,  0x13,  0x52,  0x15,  0x1E,  0x21,  0x12,  0x41, 	/* 3F570 */
+	0x1E,  0x01,  0x61,  0xAC,  0x00,  0x20,  0x00,  0x20,  0x0F,  0xFF,  0x49,  0x02,  0x29,  0xCA,  0x2A,  0x44, 	/* 3F580 */
+	0x0A,  0x9F,  0x0F,  0xE4,  0x1A,  0xA4,  0x2B,  0xFE,  0x4A,  0xA4,  0x13,  0xE4,  0x10,  0xBF,  0x26,  0x54, 	/* 3F590 */
+	0x45,  0x44,  0x09,  0x04,  0xB0,  0x00,  0x40,  0x00,  0x40,  0x0F,  0xFF,  0x4A,  0xA0,  0x2D,  0x4A,  0x2A, 	/* 3F5A0 */
+	0xAA,  0x08,  0x1F,  0x0B,  0xF4,  0x1A,  0x54,  0x2B,  0xDF,  0x48,  0x14,  0x17,  0xDF,  0x15,  0x54,  0x27, 	/* 3F5B0 */
+	0xD4,  0x44,  0x3F,  0x03,  0xE0,  0xB2,  0x00,  0x40,  0x00,  0x40,  0x0F,  0xFF,  0x4A,  0x40,  0x2B,  0xBF, 	/* 3F5C0 */
+	0x2A,  0x24,  0x0B,  0xE8,  0x0D,  0x5E,  0x1D,  0xD2,  0x2D,  0x5E,  0x4D,  0xD2,  0x15,  0x5E,  0x15,  0xD2, 	/* 3F5D0 */
+	0x27,  0xFE,  0x42,  0x52,  0x0C,  0x21,  0xB6,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x0F,  0x48,  0x01, 	/* 3F5E0 */
+	0x48,  0x01,  0x50,  0x12,  0x22,  0x0A,  0x22,  0x04,  0x14,  0x08,  0x08,  0x10,  0x04,  0x60,  0x03,  0x00, 	/* 3F5F0 */
+	0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0xB8,  0x0F,  0x48,  0x01,  0x48,  0x01,  0x50,  0x12,  0x22, 	/* 3F600 */
+	0x0A,  0x22,  0x04,  0x14,  0x0F,  0xF8,  0x10,  0x84,  0x60,  0x83,  0x00,  0x80,  0x7F,  0xFE,  0x00,  0x80, 	/* 3F610 */
+	0x01,  0x40,  0x02,  0x20,  0x0C,  0x18,  0x30,  0x06,  0xBA,  0x0F,  0x24,  0x01,  0x24,  0x01,  0x18,  0x12, 	/* 3F620 */
+	0x11,  0x0A,  0x09,  0x04,  0x0A,  0x0F,  0xFC,  0x12,  0x22,  0x62,  0x21,  0x02,  0x20,  0x7F,  0xFF,  0x02, 	/* 3F630 */
+	0x20,  0x02,  0x20,  0x04,  0x21,  0x18,  0x21,  0x60,  0x1F,  0xBB,  0x00,  0x20,  0x0F,  0x24,  0x01,  0x18, 	/* 3F640 */
+	0x22,  0x11,  0x14,  0x0A,  0x0F,  0xFC,  0x10,  0x02,  0x67,  0xF9,  0x04,  0x08,  0x04,  0x08,  0x07,  0xF8, 	/* 3F650 */
+	0x02,  0x10,  0x01,  0x10,  0x01,  0x20,  0x3F,  0xFF,  0x00,  0x00,  0xBC,  0x0F,  0x48,  0x01,  0x4A,  0x12, 	/* 3F660 */
+	0x32,  0x0C,  0x14,  0x18,  0x0C,  0x6E,  0x7B,  0x02,  0x48,  0x02,  0x49,  0x1E,  0x47,  0x10,  0xFC,  0x11, 	/* 3F670 */
+	0x44,  0x1E,  0x28,  0x02,  0x28,  0x02,  0x10,  0x04,  0x6C,  0x19,  0x83,  0xBD,  0x01,  0x00,  0x01,  0x00, 	/* 3F680 */
+	0x02,  0x00,  0x1F,  0xF8,  0x10,  0x08,  0x10,  0x08,  0x10,  0x08,  0x10,  0x08,  0x1F,  0xF8,  0x10,  0x08, 	/* 3F690 */
+	0x10,  0x08,  0x10,  0x08,  0x10,  0x08,  0x10,  0x08,  0x1F,  0xF8,  0x00,  0x00,  0xBE,  0x00,  0x00,  0x7F, 	/* 3F6A0 */
+	0xFE,  0x01,  0x00,  0x01,  0x00,  0x02,  0x00,  0x1F,  0xF8,  0x10,  0x08,  0x10,  0x08,  0x10,  0x08,  0x1F, 	/* 3F6B0 */
+	0xF8,  0x10,  0x08,  0x10,  0x08,  0x10,  0x08,  0x10,  0x08,  0x1F,  0xF8,  0x00,  0x00,  0x80,  0x01,  0x00, 	/* 3F6C0 */
+	0x02,  0x00,  0x1F,  0xF8,  0x10,  0x08,  0x10,  0x08,  0x1F,  0xF8,  0x10,  0x08,  0x10,  0x08,  0x1F,  0xF8, 	/* 3F6D0 */
+	0x00,  0x00,  0x10,  0x0C,  0x10,  0xF0,  0x1F,  0x00,  0x10,  0x02,  0x10,  0x02,  0x0F,  0xFE,  0x83,  0x00, 	/* 3F6E0 */
+	0x40,  0x00,  0x80,  0x0F,  0xFC,  0x08,  0x04,  0x08,  0x04,  0x0F,  0xFC,  0x08,  0x04,  0x08,  0x04,  0x0F, 	/* 3F6F0 */
+	0xFC,  0x01,  0x20,  0x01,  0x20,  0x02,  0x20,  0x02,  0x20,  0x04,  0x21,  0x18,  0x21,  0x60,  0x1F,  0x84, 	/* 3F700 */
+	0x08,  0x40,  0x08,  0x40,  0x10,  0x40,  0x3E,  0x7E,  0x22,  0x42,  0x22,  0x82,  0x22,  0xC2,  0x23,  0x22, 	/* 3F710 */
+	0x3E,  0x12,  0x22,  0x12,  0x22,  0x02,  0x22,  0x02,  0x22,  0x02,  0x3E,  0x02,  0x00,  0x04,  0x00,  0x18, 	/* 3F720 */
+	0x86,  0x10,  0x20,  0x10,  0x26,  0x1F,  0xB8,  0x10,  0x20,  0x10,  0x21,  0x13,  0x21,  0x1C,  0x9F,  0x61, 	/* 3F730 */
+	0x00,  0x0F,  0xF8,  0x08,  0x08,  0x08,  0x08,  0x0F,  0xF8,  0x08,  0x08,  0x08,  0x08,  0x0F,  0xF8,  0x00, 	/* 3F740 */
+	0x00,  0x87,  0x00,  0x80,  0x01,  0x00,  0x0F,  0xF8,  0x08,  0x08,  0x0F,  0xF8,  0x08,  0x08,  0x0F,  0xF8, 	/* 3F750 */
+	0x00,  0x00,  0x3F,  0xFE,  0x00,  0x80,  0x00,  0x80,  0x1F,  0xFC,  0x00,  0x80,  0x00,  0x80,  0x7F,  0xFF, 	/* 3F760 */
+	0x00,  0x00,  0x88,  0x10,  0x00,  0x10,  0xFF,  0x20,  0x80,  0x7C,  0x80,  0x44,  0x80,  0x44,  0xFC,  0x44, 	/* 3F770 */
+	0x84,  0x7C,  0xA4,  0x44,  0xA4,  0x44,  0xA8,  0x45,  0x18,  0x7D,  0x10,  0x02,  0x28,  0x04,  0x44,  0x09, 	/* 3F780 */
+	0x82,  0x06,  0x01,  0x8B,  0x00,  0x80,  0x01,  0x00,  0x0F,  0xF8,  0x08,  0x08,  0x0F,  0xF8,  0x08,  0x08, 	/* 3F790 */
+	0x0F,  0xF8,  0x00,  0x80,  0x7F,  0xFF,  0x01,  0x40,  0x02,  0xA0,  0x0C,  0x98,  0x70,  0x87,  0x0F,  0xF8, 	/* 3F7A0 */
+	0x00,  0x80,  0x00,  0x80,  0x8E,  0x08,  0x10,  0x08,  0x10,  0x13,  0xFF,  0x7C,  0x48,  0x44,  0x44,  0x44, 	/* 3F7B0 */
+	0x84,  0x44,  0x8A,  0x7D,  0x4A,  0x44,  0x48,  0x44,  0x50,  0x44,  0x30,  0x44,  0x30,  0x7C,  0x48,  0x00, 	/* 3F7C0 */
+	0x84,  0x03,  0x02,  0x0C,  0x01,  0x90,  0x00,  0x80,  0x01,  0x00,  0x0F,  0xF8,  0x08,  0x08,  0x0F,  0xF8, 	/* 3F7D0 */
+	0x08,  0x08,  0x0F,  0xF8,  0x00,  0x00,  0x1E,  0xBC,  0x00,  0x80,  0x1E,  0xBC,  0x00,  0x80,  0x7F,  0xFF, 	/* 3F7E0 */
+	0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x93,  0x10,  0x10,  0x10,  0x90,  0x20,  0x90,  0x7C,  0xFE,  0x45, 	/* 3F7F0 */
+	0x10,  0x46,  0x10,  0x44,  0x10,  0x7F,  0xFF,  0x44,  0x00,  0x44,  0x00,  0x44,  0xFC,  0x44,  0x84,  0x7C, 	/* 3F800 */
+	0x84,  0x00,  0x84,  0x00,  0xFC,  0x00,  0x00,  0x96,  0x10,  0x10,  0x10,  0x10,  0x21,  0xFF,  0x7D,  0x01, 	/* 3F810 */
+	0x45,  0x01,  0x44,  0xFE,  0x44,  0x00,  0x7C,  0x00,  0x47,  0xFF,  0x44,  0x48,  0x44,  0x48,  0x44,  0x48, 	/* 3F820 */
+	0x7C,  0x48,  0x00,  0x89,  0x03,  0x09,  0x0C,  0x07,  0x99,  0x08,  0x04,  0x08,  0x78,  0x7F,  0x40,  0x08, 	/* 3F830 */
+	0x7F,  0x1C,  0x48,  0x1A,  0x48,  0x28,  0x88,  0x49,  0x08,  0x09,  0x00,  0x1F,  0xF8,  0x10,  0x08,  0x1F, 	/* 3F840 */
+	0xF8,  0x10,  0x08,  0x10,  0x08,  0x1F,  0xF8,  0x00,  0x00,  0x9A,  0x10,  0x20,  0x12,  0x22,  0x22,  0x22, 	/* 3F850 */
+	0x7B,  0xFE,  0x48,  0x00,  0x4F,  0xFF,  0x48,  0x00,  0x79,  0xFC,  0x49,  0x04,  0x49,  0x04,  0x49,  0xFC, 	/* 3F860 */
+	0x48,  0x88,  0x78,  0x48,  0x00,  0x50,  0x07,  0xFF,  0x00,  0x00,  0xAE,  0x00,  0x80,  0x00,  0x80,  0x00, 	/* 3F870 */
+	0x80,  0x1F,  0xFE,  0x10,  0x82,  0x10,  0x84,  0x10,  0x80,  0x1F,  0xF8,  0x12,  0x10,  0x12,  0x10,  0x11, 	/* 3F880 */
+	0x20,  0x10,  0xC0,  0x20,  0xC0,  0x21,  0x20,  0x46,  0x18,  0x18,  0x06,  0xB0,  0x04,  0x20,  0x04,  0x20, 	/* 3F890 */
+	0x3F,  0xFE,  0x25,  0x42,  0x24,  0x82,  0x25,  0x7A,  0x3E,  0x4A,  0x22,  0x4A,  0x2A,  0x7A,  0x24,  0x42, 	/* 3F8A0 */
+	0x24,  0x44,  0x2A,  0x58,  0x29,  0x40,  0x51,  0x41,  0x20,  0x21,  0x40,  0x1F,  0xB4,  0x08,  0x08,  0x0A, 	/* 3F8B0 */
+	0x08,  0x11,  0x08,  0x7E,  0xFF,  0x14,  0x49,  0x15,  0x4A,  0x27,  0x48,  0x48,  0x7E,  0x0E,  0x52,  0x12, 	/* 3F8C0 */
+	0x52,  0x34,  0x54,  0x4C,  0x4C,  0x0A,  0x88,  0x12,  0x94,  0x21,  0x22,  0x40,  0x41,  0xB7,  0x08,  0x10, 	/* 3F8D0 */
+	0x08,  0x10,  0x7F,  0x10,  0x08,  0xFF,  0x3E,  0x92,  0x00,  0x94,  0x3E,  0x90,  0x22,  0xFC,  0x22,  0xA4, 	/* 3F8E0 */
+	0x3E,  0xA4,  0x24,  0x94,  0x14,  0x98,  0x1A,  0x88,  0x0D,  0x14,  0x12,  0x62,  0x61,  0x81,  0xB8,  0x00, 	/* 3F8F0 */
+	0x08,  0x7F,  0x08,  0x41,  0x08,  0x49,  0x7F,  0x3E,  0x49,  0x08,  0x4A,  0x3F,  0x48,  0x29,  0x7E,  0x3F, 	/* 3F900 */
+	0x52,  0x29,  0x52,  0x3F,  0x54,  0x08,  0x4C,  0x7F,  0x88,  0x08,  0x94,  0x09,  0x22,  0x08,  0x41,  0xB9, 	/* 3F910 */
+	0x04,  0x00,  0x04,  0xFF,  0x3F,  0x81,  0x26,  0x91,  0x24,  0x7E,  0x24,  0x10,  0x3E,  0x7E,  0x22,  0x52, 	/* 3F920 */
+	0x2A,  0x7E,  0x24,  0x52,  0x24,  0x52,  0x2A,  0x7E,  0x29,  0x10,  0x51,  0xFF,  0x20,  0x10,  0x40,  0x10, 	/* 3F930 */
+	0xBA,  0x10,  0x08,  0x1F,  0x08,  0x21,  0x08,  0x55,  0x7F,  0x55,  0x49,  0x7D,  0x4A,  0x11,  0x48,  0x26, 	/* 3F940 */
+	0x7E,  0x10,  0x52,  0x1F,  0x52,  0x21,  0x54,  0x55,  0x4C,  0x55,  0x88,  0x7D,  0x94,  0x11,  0x22,  0x26, 	/* 3F950 */
+	0x41,  0xBF,  0x00,  0x00,  0x00,  0x00,  0x1F,  0xFC,  0x12,  0x24,  0x12,  0x24,  0x12,  0x24,  0x12,  0x24, 	/* 3F960 */
+	0x12,  0x24,  0x12,  0x24,  0x12,  0x24,  0x12,  0x24,  0x12,  0x24,  0x12,  0x24,  0x7F,  0xFF,  0x00,  0x00, 	/* 3F970 */
+	0x00,  0x00,  0x82,  0x00,  0x00,  0x1F,  0xFC,  0x00,  0x80,  0x00,  0x80,  0x7F,  0xFF,  0x00,  0x80,  0x00, 	/* 3F980 */
+	0x80,  0x00,  0x80,  0x01,  0x80,  0x00,  0x00,  0x1F,  0xFC,  0x12,  0x24,  0x12,  0x24,  0x12,  0x24,  0x7F, 	/* 3F990 */
+	0xFF,  0x00,  0x00,  0x83,  0x00,  0x00,  0x3F,  0xFE,  0x00,  0x40,  0x00,  0x80,  0x03,  0xB8,  0x0C,  0x86, 	/* 3F9A0 */
+	0x70,  0x81,  0x00,  0x80,  0x00,  0x80,  0x00,  0x00,  0x1F,  0xFC,  0x12,  0x24,  0x12,  0x24,  0x12,  0x24, 	/* 3F9B0 */
+	0x7F,  0xFF,  0x00,  0x00,  0x86,  0x02,  0xF0,  0x02,  0x10,  0x04,  0x08,  0x18,  0x04,  0x6F,  0xFB,  0x00, 	/* 3F9C0 */
+	0x88,  0x01,  0x08,  0x06,  0x08,  0x38,  0x30,  0x00,  0x00,  0x1F,  0xFC,  0x12,  0x24,  0x12,  0x24,  0x12, 	/* 3F9D0 */
+	0x24,  0x7F,  0xFF,  0x00,  0x00,  0x88,  0x00,  0x00,  0x3F,  0xF8,  0x04,  0x08,  0x04,  0x08,  0x07,  0xEE, 	/* 3F9E0 */
+	0x0A,  0x22,  0x09,  0x42,  0x10,  0x82,  0x23,  0x5C,  0x4C,  0x30,  0x1F,  0xFC,  0x12,  0x24,  0x12,  0x24, 	/* 3F9F0 */
+	0x12,  0x24,  0x7F,  0xFF,  0x00,  0x00,  0x8A,  0x08,  0x10,  0x04,  0x10,  0x02,  0x20,  0x02,  0x40,  0x7F, 	/* 3FA00 */
+	0xFF,  0x04,  0x10,  0x04,  0x10,  0x08,  0x08,  0x10,  0x04,  0x2F,  0xFA,  0x49,  0x48,  0x09,  0x48,  0x09, 	/* 3FA10 */
+	0x48,  0x09,  0x48,  0x7F,  0xFE,  0x00,  0x00,  0x8D,  0x00,  0x80,  0x00,  0x80,  0x0F,  0xF8,  0x00,  0x80, 	/* 3FA20 */
+	0x00,  0x80,  0x7F,  0xFF,  0x01,  0x20,  0x01,  0x18,  0x02,  0x74,  0x1F,  0x82,  0x00,  0x00,  0x1F,  0xFC, 	/* 3FA30 */
+	0x12,  0x24,  0x12,  0x24,  0x7F,  0xFF,  0x00,  0x00,  0x92,  0x00,  0x80,  0x00,  0x80,  0x01,  0x40,  0x06, 	/* 3FA40 */
+	0x30,  0x18,  0x0C,  0x67,  0xF3,  0x00,  0x00,  0x0F,  0xF8,  0x08,  0x08,  0x0F,  0xF8,  0x00,  0x00,  0x1F, 	/* 3FA50 */
+	0xFC,  0x12,  0x24,  0x12,  0x24,  0x7F,  0xFF,  0x00,  0x00,  0x96,  0x04,  0x10,  0x02,  0x10,  0x02,  0x20, 	/* 3FA60 */
+	0x3F,  0xFE,  0x00,  0x80,  0x00,  0x80,  0x1F,  0xFC,  0x00,  0x80,  0x00,  0x80,  0x7F,  0xFF,  0x00,  0x00, 	/* 3FA70 */
+	0x1F,  0xFC,  0x12,  0x24,  0x12,  0x24,  0x7F,  0xFF,  0x00,  0x00,  0x97,  0x00,  0x80,  0x10,  0x80,  0x08, 	/* 3FA80 */
+	0xFE,  0x09,  0x22,  0x01,  0x24,  0x02,  0x60,  0x08,  0x50,  0x10,  0x8C,  0x21,  0x03,  0x22,  0x00,  0x1F, 	/* 3FA90 */
+	0xFC,  0x12,  0x24,  0x12,  0x24,  0x12,  0x24,  0x7F,  0xFF,  0x00,  0x00,  0x9B,  0x00,  0x28,  0x00,  0x24, 	/* 3FAA0 */
+	0x1F,  0xFE,  0x10,  0x20,  0x1F,  0x24,  0x11,  0x18,  0x11,  0x12,  0x21,  0x2A,  0x26,  0xC6,  0x40,  0x02, 	/* 3FAB0 */
+	0x1F,  0xF8,  0x12,  0x48,  0x12,  0x48,  0x12,  0x48,  0x7F,  0xFE,  0x00,  0x00,  0x9C,  0x08,  0x40,  0x04, 	/* 3FAC0 */
+	0x40,  0x44,  0xFF,  0x20,  0x92,  0x21,  0x14,  0x0A,  0x10,  0x08,  0x28,  0x10,  0xC4,  0x23,  0x03,  0x40, 	/* 3FAD0 */
+	0x00,  0x1F,  0xFC,  0x12,  0x24,  0x12,  0x24,  0x12,  0x24,  0x7F,  0xFF,  0x00,  0x00,  0x9E,  0x01,  0x10, 	/* 3FAE0 */
+	0x7F,  0xFE,  0x00,  0x48,  0x01,  0xF2,  0x1E,  0x1E,  0x01,  0x02,  0x7F,  0xFF,  0x00,  0x48,  0x01,  0xF2, 	/* 3FAF0 */
+	0x3E,  0x0E,  0x00,  0x02,  0x1F,  0xFC,  0x12,  0x24,  0x12,  0x24,  0x7F,  0xFF,  0x00,  0x00,  0x9F,  0x00, 	/* 3FB00 */
+	0x00,  0x3E,  0x7E,  0x22,  0x42,  0x22,  0x7E,  0x3E,  0x42,  0x22,  0x7E,  0x22,  0x42,  0x3E,  0x42,  0x22, 	/* 3FB10 */
+	0x82,  0x01,  0x06,  0x1F,  0xFC,  0x12,  0x24,  0x12,  0x24,  0x12,  0x24,  0x7F,  0xFF,  0x00,  0x00,  0xA1, 	/* 3FB20 */
+	0x00,  0x80,  0x1F,  0xFC,  0x00,  0x84,  0x7F,  0xFF,  0x00,  0x84,  0x1F,  0xFC,  0x00,  0x80,  0x7F,  0xFF, 	/* 3FB30 */
+	0x12,  0x24,  0x11,  0x12,  0x20,  0x01,  0x5F,  0xFC,  0x12,  0x24,  0x12,  0x24,  0x7F,  0xFF,  0x00,  0x00, 	/* 3FB40 */
+	0xA3,  0x00,  0x20,  0x3F,  0x20,  0x24,  0x20,  0x24,  0x3F,  0x3F,  0x40,  0x21,  0x40,  0x3F,  0xBE,  0x24, 	/* 3FB50 */
+	0x00,  0x3F,  0x00,  0x00,  0x00,  0x1F,  0xFC,  0x12,  0x24,  0x12,  0x24,  0x12,  0x24,  0x7F,  0xFF,  0x00, 	/* 3FB60 */
+	0x00,  0xA4,  0x04,  0x00,  0x1F,  0x3C,  0x19,  0x25,  0x15,  0x23,  0x17,  0x40,  0x79,  0xFE,  0x15,  0x14, 	/* 3FB70 */
+	0x15,  0x08,  0x11,  0x14,  0x23,  0x63,  0x40,  0x00,  0x1F,  0xFC,  0x12,  0x24,  0x12,  0x24,  0x7F,  0xFF, 	/* 3FB80 */
+	0x00,  0x00,  0xA5,  0x04,  0x00,  0x38,  0x8E,  0x20,  0xA2,  0x38,  0xAE,  0x27,  0xC2,  0x22,  0xC2,  0x3A, 	/* 3FB90 */
+	0xAE,  0x24,  0x92,  0x21,  0x82,  0x20,  0x02,  0x1F,  0xFC,  0x12,  0x44,  0x12,  0x44,  0x12,  0x44,  0x7F, 	/* 3FBA0 */
+	0xFF,  0x00,  0x00,  0xA7,  0x00,  0x80,  0x00,  0xF8,  0x00,  0x80,  0x1F,  0xFF,  0x11,  0x72,  0x1F,  0x84, 	/* 3FBB0 */
+	0x13,  0xFC,  0x12,  0x48,  0x13,  0xF8,  0x12,  0x48,  0x13,  0xF8,  0x10,  0x00,  0x27,  0xFC,  0x24,  0xA4, 	/* 3FBC0 */
+	0x5F,  0xFF,  0x00,  0x00,  0xAA,  0x10,  0x00,  0x08,  0xF8,  0x08,  0x88,  0x40,  0xF8,  0x20,  0x88,  0x27, 	/* 3FBD0 */
+	0xFF,  0x00,  0x80,  0x11,  0xFE,  0x22,  0x52,  0x24,  0x92,  0x41,  0x2C,  0x1F,  0xFC,  0x12,  0x24,  0x12, 	/* 3FBE0 */
+	0x24,  0x7F,  0xFF,  0x00,  0x00,  0xAE,  0x00,  0x00,  0x1F,  0xF8,  0x10,  0x08,  0x10,  0x08,  0x10,  0x08, 	/* 3FBF0 */
+	0x1F,  0xF8,  0x10,  0x08,  0x10,  0x08,  0x10,  0x08,  0x1F,  0xF8,  0x10,  0x08,  0x10,  0x08,  0x10,  0x08, 	/* 3FC00 */
+	0x10,  0x08,  0x1F,  0xF8,  0x00,  0x00,  0xB2,  0x00,  0x80,  0x00,  0x80,  0x7F,  0xFF,  0x10,  0x00,  0x10, 	/* 3FC10 */
+	0x00,  0x0F,  0xFC,  0x00,  0x00,  0x0F,  0xF8,  0x08,  0x08,  0x0F,  0xF8,  0x08,  0x08,  0x0F,  0xF8,  0x08, 	/* 3FC20 */
+	0x08,  0x08,  0x08,  0x0F,  0xF8,  0x00,  0x00,  0xB4,  0x00,  0x80,  0x00,  0x80,  0x7F,  0xFF,  0x00,  0x80, 	/* 3FC30 */
+	0x07,  0xF8,  0x24,  0x08,  0x24,  0x08,  0x27,  0xF8,  0x24,  0x08,  0x27,  0xF8,  0x24,  0x08,  0x24,  0x08, 	/* 3FC40 */
+	0x27,  0xF8,  0x20,  0x00,  0x3F,  0xFF,  0x00,  0x00,  0xB8,  0x08,  0x00,  0x08,  0xFE,  0x08,  0x82,  0x7F, 	/* 3FC50 */
+	0x82,  0x08,  0x82,  0x08,  0xFE,  0x1C,  0x82,  0x1A,  0x82,  0x19,  0x82,  0x28,  0xFE,  0x28,  0x82,  0x48, 	/* 3FC60 */
+	0x82,  0x08,  0x82,  0x08,  0x82,  0x08,  0xFE,  0x08,  0x00,  0xBB,  0x00,  0x78,  0x78,  0x08,  0x48,  0x88, 	/* 3FC70 */
+	0x48,  0x84,  0x49,  0x04,  0x7B,  0xFE,  0x4C,  0x41,  0x48,  0x40,  0x48,  0x40,  0x78,  0xFC,  0x48,  0x84, 	/* 3FC80 */
+	0x48,  0x04,  0x48,  0x04,  0x78,  0x04,  0x00,  0x04,  0x00,  0x18,  0xBE,  0x00,  0x04,  0x00,  0x38,  0x1F, 	/* 3FC90 */
+	0xC0,  0x10,  0x40,  0x1F,  0xFF,  0x10,  0x40,  0x13,  0xF8,  0x12,  0x08,  0x12,  0x08,  0x13,  0xF8,  0x12, 	/* 3FCA0 */
+	0x08,  0x13,  0xF8,  0x22,  0x08,  0x22,  0x08,  0x43,  0xF8,  0x00,  0x00,  0x81,  0x00,  0x80,  0x00,  0x90, 	/* 3FCB0 */
+	0x04,  0x8C,  0x18,  0x92,  0x61,  0xA1,  0x00,  0xC0,  0x0F,  0xF8,  0x78,  0x08,  0x08,  0x08,  0x0F,  0xF8, 	/* 3FCC0 */
+	0x08,  0x08,  0x0F,  0xF8,  0x08,  0x08,  0x08,  0x08,  0x0F,  0xF8,  0x00,  0x00,  0x84,  0x00,  0x00,  0x7B, 	/* 3FCD0 */
+	0xFF,  0x48,  0x20,  0x48,  0x20,  0x49,  0x20,  0x79,  0x3E,  0x49,  0x22,  0x49,  0x22,  0x49,  0x22,  0x79, 	/* 3FCE0 */
+	0x22,  0x49,  0xFE,  0x48,  0x02,  0x48,  0x02,  0x78,  0x02,  0x00,  0x04,  0x00,  0x18,  0x87,  0x00,  0x20, 	/* 3FCF0 */
+	0x78,  0x20,  0x48,  0x20,  0x48,  0xA4,  0x48,  0xA2,  0x78,  0xA2,  0x49,  0x21,  0x4A,  0x25,  0x4C,  0x24, 	/* 3FD00 */
+	0x78,  0x68,  0x48,  0x08,  0x48,  0x10,  0x48,  0x20,  0x78,  0x40,  0x01,  0x80,  0x06,  0x00,  0x88,  0x00, 	/* 3FD10 */
+	0x20,  0x78,  0x20,  0x48,  0x20,  0x4B,  0xFE,  0x4A,  0x22,  0x7A,  0x22,  0x4A,  0x22,  0x48,  0x30,  0x78, 	/* 3FD20 */
+	0x30,  0x48,  0x50,  0x48,  0x50,  0x48,  0x50,  0x78,  0x90,  0x01,  0x11,  0x02,  0x11,  0x04,  0x0F,  0x89, 	/* 3FD30 */
+	0x00,  0x00,  0x1F,  0xFE,  0x10,  0x42,  0x10,  0x42,  0x1F,  0xFE,  0x10,  0x00,  0x13,  0xFC,  0x12,  0x04, 	/* 3FD40 */
+	0x12,  0x04,  0x13,  0xFC,  0x12,  0x04,  0x13,  0xFC,  0x22,  0x04,  0x22,  0x04,  0x43,  0xFC,  0x00,  0x00, 	/* 3FD50 */
+	0x8B,  0x00,  0x08,  0x00,  0x70,  0x0F,  0x80,  0x00,  0x80,  0x1F,  0xFC,  0x01,  0x00,  0x7F,  0xFF,  0x02, 	/* 3FD60 */
+	0x00,  0x07,  0xF8,  0x0A,  0x08,  0x13,  0xF8,  0x22,  0x08,  0x03,  0xF8,  0x02,  0x08,  0x03,  0xF8,  0x00, 	/* 3FD70 */
+	0x00,  0x8C,  0x00,  0x00,  0x07,  0xF8,  0x24,  0x08,  0x24,  0x08,  0x27,  0xF8,  0x24,  0x08,  0x27,  0xF8, 	/* 3FD80 */
+	0x24,  0x08,  0x24,  0x08,  0x27,  0xF8,  0x20,  0x00,  0x3F,  0xFF,  0x04,  0xB0,  0x18,  0x8C,  0x60,  0x82, 	/* 3FD90 */
+	0x00,  0x80,  0x9B,  0x00,  0x20,  0x78,  0x20,  0x48,  0x20,  0x4B,  0xFE,  0x48,  0x20,  0x78,  0x20,  0x48, 	/* 3FDA0 */
+	0x20,  0x4F,  0xFF,  0x48,  0x70,  0x78,  0x70,  0x48,  0xA8,  0x48,  0xA4,  0x49,  0x22,  0x7A,  0x21,  0x04, 	/* 3FDB0 */
+	0x20,  0x00,  0x20,  0x9E,  0x08,  0x30,  0x0F,  0xC4,  0x08,  0x04,  0x07,  0xFC,  0x20,  0x00,  0x27,  0xF8, 	/* 3FDC0 */
+	0x24,  0x08,  0x27,  0xF8,  0x24,  0x08,  0x27,  0xF8,  0x24,  0x08,  0x27,  0xF8,  0x20,  0x00,  0x3F,  0xFF, 	/* 3FDD0 */
+	0x06,  0x18,  0x78,  0x06,  0x9F,  0x01,  0x00,  0x01,  0x00,  0x3F,  0xFC,  0x01,  0x00,  0x0F,  0xF0,  0x08, 	/* 3FDE0 */
+	0x10,  0x0F,  0xF0,  0x08,  0x10,  0x0F,  0xF0,  0x08,  0x10,  0x0F,  0xF0,  0x00,  0x00,  0x7F,  0xFE,  0x04, 	/* 3FDF0 */
+	0x60,  0x18,  0x18,  0x60,  0x04,  0xA0,  0x00,  0x00,  0x79,  0xFC,  0x49,  0x04,  0x49,  0x04,  0x49,  0x04, 	/* 3FE00 */
+	0x79,  0xFC,  0x49,  0x10,  0x49,  0x10,  0x79,  0xFF,  0x49,  0x10,  0x49,  0x10,  0x49,  0x08,  0x49,  0x0A, 	/* 3FE10 */
+	0x79,  0x6A,  0x01,  0x86,  0x06,  0x02,  0xA4,  0x00,  0x00,  0x79,  0xFE,  0x49,  0x02,  0x49,  0x02,  0x49, 	/* 3FE20 */
+	0x02,  0x79,  0xFE,  0x49,  0x00,  0x49,  0x40,  0x79,  0x44,  0x49,  0x48,  0x49,  0x70,  0x49,  0x40,  0x7A, 	/* 3FE30 */
+	0x41,  0x02,  0x41,  0x04,  0x3F,  0x08,  0x00,  0xA5,  0x04,  0x20,  0x14,  0x22,  0x17,  0xBC,  0x14,  0x20, 	/* 3FE40 */
+	0x14,  0x21,  0x15,  0xA1,  0x1E,  0x1F,  0x70,  0x00,  0x0F,  0xF8,  0x08,  0x08,  0x0F,  0xF8,  0x08,  0x08, 	/* 3FE50 */
+	0x0F,  0xF8,  0x08,  0x08,  0x0F,  0xF8,  0x00,  0x00,  0xA6,  0x00,  0x88,  0x78,  0x88,  0x48,  0x88,  0x4A, 	/* 3FE60 */
+	0x88,  0x4A,  0x88,  0x7A,  0x89,  0x4A,  0xEA,  0x4A,  0x8C,  0x4A,  0x88,  0x7A,  0x88,  0x4A,  0x88,  0x4A, 	/* 3FE70 */
+	0x88,  0x4A,  0x88,  0x7A,  0xE9,  0x03,  0x89,  0x0C,  0x07,  0xA9,  0x00,  0x20,  0x78,  0x20,  0x48,  0x20, 	/* 3FE80 */
+	0x4B,  0xFF,  0x48,  0x20,  0x78,  0x20,  0x48,  0x24,  0x49,  0xC4,  0x48,  0x48,  0x78,  0x28,  0x48,  0x30, 	/* 3FE90 */
+	0x48,  0x28,  0x48,  0x44,  0x79,  0x9E,  0x07,  0xE2,  0x00,  0x02,  0xB7,  0x04,  0x90,  0x04,  0x88,  0x08, 	/* 3FEA0 */
+	0x84,  0x17,  0xFC,  0x00,  0x80,  0x01,  0x40,  0x7F,  0xFF,  0x02,  0x20,  0x07,  0xF0,  0x1C,  0x1C,  0x67, 	/* 3FEB0 */
+	0xF3,  0x04,  0x10,  0x07,  0xF0,  0x04,  0x10,  0x07,  0xF0,  0x00,  0x00,  0xB8,  0x00,  0x40,  0x78,  0x50, 	/* 3FEC0 */
+	0x48,  0x88,  0x49,  0x34,  0x4B,  0xC2,  0x78,  0x20,  0x49,  0x20,  0x49,  0x20,  0x4B,  0xFE,  0x7C,  0x20, 	/* 3FED0 */
+	0x48,  0x20,  0x4F,  0xFF,  0x48,  0x20,  0x78,  0x20,  0x00,  0x20,  0x00,  0x20,  0xBA,  0x00,  0x90,  0x78, 	/* 3FEE0 */
+	0x90,  0x48,  0x90,  0x4C,  0x94,  0x4A,  0x94,  0x7A,  0x98,  0x4A,  0x90,  0x48,  0x90,  0x79,  0x98,  0x4A, 	/* 3FEF0 */
+	0x94,  0x4C,  0x92,  0x48,  0x90,  0x79,  0x11,  0x01,  0x11,  0x02,  0x0F,  0x04,  0x00,  0xBC,  0x00,  0x00, 	/* 3FF00 */
+	0x3C,  0xFC,  0x24,  0x84,  0x24,  0x84,  0x24,  0xFC,  0x3C,  0x84,  0x24,  0x84,  0x24,  0xFE,  0x3C,  0x92, 	/* 3FF10 */
+	0x24,  0x94,  0x24,  0x94,  0x24,  0x88,  0x3C,  0x88,  0x00,  0xB4,  0x00,  0xC2,  0x03,  0x81,  0x80,  0x04, 	/* 3FF20 */
+	0x10,  0x02,  0x20,  0x3F,  0xFE,  0x00,  0x80,  0x1F,  0xFC,  0x00,  0x80,  0x7F,  0xFF,  0x04,  0x00,  0x07, 	/* 3FF30 */
+	0xF8,  0x0C,  0x08,  0x0F,  0xF8,  0x14,  0x08,  0x27,  0xF8,  0x44,  0x08,  0x07,  0xF8,  0x00,  0x00,  0x87, 	/* 3FF40 */
+	0x01,  0x04,  0x78,  0x84,  0x48,  0x48,  0x4B,  0xFE,  0x48,  0x22,  0x78,  0x22,  0x4B,  0xFE,  0x4A,  0x20, 	/* 3FF50 */
+	0x4A,  0x20,  0x7B,  0xFE,  0x48,  0x62,  0x48,  0xA2,  0x49,  0x22,  0x7A,  0x2C,  0x04,  0x20,  0x00,  0x20, 	/* 3FF60 */
+	0x9A,  0x00,  0x00,  0x7B,  0xFF,  0x4A,  0x00,  0x4A,  0x10,  0x7A,  0xFE,  0x4A,  0x10,  0x4A,  0x10,  0x4B, 	/* 3FF70 */
+	0xFF,  0x7A,  0x00,  0x4A,  0x10,  0x4A,  0xFE,  0x4A,  0x10,  0x7C,  0x10,  0x04,  0x10,  0x09,  0xFF,  0x00, 	/* 3FF80 */
+	0x00,  0x9B,  0x00,  0x20,  0x78,  0x20,  0x4B,  0xFE,  0x48,  0x20,  0x49,  0xFC,  0x78,  0x20,  0x4F,  0xFF, 	/* 3FF90 */
+	0x48,  0x00,  0x49,  0xFC,  0x79,  0x24,  0x49,  0x24,  0x49,  0xFC,  0x49,  0x04,  0x79,  0x04,  0x01,  0x04, 	/* 3FFA0 */
+	0x01,  0x0C,  0xA1,  0x00,  0x08,  0x00,  0x30,  0x7B,  0xE0,  0x48,  0x20,  0x4B,  0xFE,  0x79,  0x24,  0x49, 	/* 3FFB0 */
+	0x24,  0x49,  0x24,  0x7F,  0xFF,  0x49,  0x24,  0x49,  0x24,  0x4B,  0xFE,  0x78,  0x20,  0x00,  0x20,  0x07, 	/* 3FFC0 */
+	0xFF,  0x00,  0x00,  0xA3,  0x04,  0x00,  0x07,  0xFC,  0x04,  0x44,  0x7F,  0xA4,  0x16,  0x18,  0x15,  0x28, 	/* 3FFD0 */
+	0x25,  0x44,  0x4C,  0x83,  0x0F,  0xF8,  0x08,  0x08,  0x0F,  0xF8,  0x08,  0x08,  0x0F,  0xF8,  0x08,  0x08, 	/* 3FFE0 */
+	0x0F,  0xF8,  0x00,  0x00,  0xA5,  0x00,  0x20,  0x78,  0x40,  0x4B,  0xFE,  0x4A,  0x22,  0x4A,  0x22,  0x7B, 	/* 3FFF0 */
+	0xFE,  0x4A,  0x22,  0x4A,  0x42,  0x4B,  0xFE,  0x78,  0x80,  0x49,  0x10,  0x4F,  0xFF,  0x48,  0x10,  0x78, 	/* 40000 */
+	0x10,  0x00,  0x10,  0x00,  0x10,  0xA6,  0x00,  0x20,  0x7C,  0x20,  0x45,  0xFC,  0x44,  0x20,  0x44,  0x20, 	/* 40010 */
+	0x7F,  0xFF,  0x44,  0x88,  0x44,  0x88,  0x7D,  0x27,  0x46,  0x20,  0x44,  0x20,  0x45,  0xFC,  0x7C,  0x20, 	/* 40020 */
+	0x00,  0x20,  0x07,  0xFF,  0x00,  0x00,  0xA8,  0x00,  0x20,  0x3C,  0x40,  0x25,  0x8E,  0x25,  0x02,  0x25, 	/* 40030 */
+	0x02,  0x3D,  0xDE,  0x25,  0x02,  0x25,  0x02,  0x3D,  0xFE,  0x24,  0x50,  0x24,  0x50,  0x24,  0x90,  0x3C, 	/* 40040 */
+	0x90,  0x01,  0x11,  0x02,  0x11,  0x04,  0x0F,  0xAB,  0x00,  0x20,  0x78,  0x20,  0x4F,  0xFF,  0x48,  0x20, 	/* 40050 */
+	0x49,  0xFC,  0x78,  0x24,  0x4F,  0xFF,  0x48,  0x24,  0x49,  0xFC,  0x78,  0x20,  0x49,  0x20,  0x49,  0x3E, 	/* 40060 */
+	0x49,  0xA0,  0x7A,  0x60,  0x04,  0x30,  0x08,  0x0F,  0xB9,  0x00,  0x20,  0x78,  0x24,  0x49,  0xFE,  0x48, 	/* 40070 */
+	0x24,  0x48,  0x28,  0x78,  0x30,  0x4B,  0xFF,  0x48,  0x48,  0x48,  0x84,  0x79,  0xFC,  0x4E,  0x84,  0x48, 	/* 40080 */
+	0xFC,  0x48,  0x84,  0x78,  0x84,  0x00,  0xFC,  0x00,  0x00,  0xBE,  0x01,  0x00,  0x1F,  0xFC,  0x12,  0x24, 	/* 40090 */
+	0x12,  0x24,  0x1F,  0xFC,  0x00,  0x80,  0x0F,  0xF8,  0x00,  0x80,  0x7F,  0xFF,  0x04,  0x10,  0x02,  0x20, 	/* 400A0 */
+	0x1F,  0xFC,  0x00,  0x80,  0x3F,  0xFE,  0x00,  0x80,  0x00,  0x80,  0xBF,  0x01,  0x00,  0x01,  0xF8,  0x01, 	/* 400B0 */
+	0x00,  0x7F,  0xFE,  0x40,  0x02,  0x47,  0xEA,  0x11,  0x84,  0x66,  0x62,  0x1F,  0xF8,  0x68,  0x17,  0x0F, 	/* 400C0 */
+	0xF0,  0x08,  0x10,  0x0F,  0xF0,  0x08,  0x10,  0x0F,  0xF0,  0x00,  0x00,  0x8B,  0x01,  0x04,  0x79,  0xF8, 	/* 400D0 */
+	0x49,  0x02,  0x48,  0xFE,  0x4A,  0x00,  0x7A,  0xFC,  0x4A,  0x84,  0x4A,  0xFC,  0x4A,  0x84,  0x7A,  0xFC, 	/* 400E0 */
+	0x4A,  0x84,  0x4A,  0xFC,  0x4A,  0x00,  0x7B,  0xFF,  0x01,  0x8C,  0x0E,  0x03,  0x8E,  0x00,  0x20,  0x78, 	/* 400F0 */
+	0x20,  0x4B,  0xFE,  0x4A,  0x22,  0x4A,  0x3A,  0x79,  0xE0,  0x48,  0x20,  0x49,  0xFC,  0x48,  0x20,  0x7F, 	/* 40100 */
+	0xFF,  0x48,  0x20,  0x49,  0xFC,  0x49,  0x04,  0x79,  0x04,  0x01,  0xFC,  0x00,  0x00,  0x91,  0x00,  0x00, 	/* 40110 */
+	0x7F,  0xFE,  0x4C,  0x02,  0x4D,  0xFA,  0x49,  0x08,  0x79,  0x08,  0x49,  0xF8,  0x49,  0x08,  0x49,  0x08, 	/* 40120 */
+	0x79,  0xF8,  0x48,  0x20,  0x4F,  0xFF,  0x48,  0x00,  0x78,  0x88,  0x01,  0x04,  0x06,  0x02,  0x9E,  0x00, 	/* 40130 */
+	0x88,  0x78,  0x88,  0x4F,  0xFF,  0x48,  0x88,  0x48,  0x88,  0x78,  0xF8,  0x48,  0x20,  0x4B,  0xFE,  0x4A, 	/* 40140 */
+	0x22,  0x7B,  0xBA,  0x4A,  0xAA,  0x4A,  0xAA,  0x4B,  0x76,  0x7B,  0x32,  0x02,  0x22,  0x02,  0x26,  0xA0, 	/* 40150 */
+	0x01,  0x24,  0x78,  0xA4,  0x48,  0xA8,  0x4B,  0xFF,  0x7A,  0x01,  0x4A,  0xFD,  0x48,  0x84,  0x48,  0x84, 	/* 40160 */
+	0x78,  0xFC,  0x48,  0x20,  0x48,  0x20,  0x49,  0xFE,  0x78,  0x20,  0x00,  0x20,  0x07,  0xFF,  0x00,  0x00, 	/* 40170 */
+	0xA5,  0x24,  0x90,  0x15,  0x1F,  0x3F,  0xA4,  0x24,  0xB4,  0x2E,  0xC8,  0x35,  0x94,  0x24,  0xA2,  0x25, 	/* 40180 */
+	0xC1,  0x0F,  0xF8,  0x08,  0x08,  0x0F,  0xF8,  0x08,  0x08,  0x0F,  0xF8,  0x08,  0x08,  0x0F,  0xF8,  0x00, 	/* 40190 */
+	0x00,  0xAC,  0x00,  0x04,  0x78,  0x18,  0x4B,  0xE4,  0x49,  0x44,  0x48,  0xA8,  0x7B,  0xFE,  0x4A,  0x8A, 	/* 401A0 */
+	0x4A,  0x8A,  0x79,  0xC8,  0x49,  0x7E,  0x49,  0x68,  0x4A,  0xE8,  0x7C,  0xA8,  0x48,  0xFF,  0x01,  0x08, 	/* 401B0 */
+	0x02,  0x08,  0xAD,  0x00,  0x20,  0x78,  0x20,  0x4F,  0xFF,  0x48,  0x50,  0x4A,  0x8A,  0x79,  0x04,  0x4B, 	/* 401C0 */
+	0xFE,  0x4D,  0x05,  0x79,  0xFC,  0x49,  0x04,  0x49,  0xFC,  0x48,  0x28,  0x79,  0x24,  0x4A,  0x22,  0x04, 	/* 401D0 */
+	0x22,  0x00,  0x60,  0xB0,  0x00,  0x08,  0x7B,  0xC8,  0x48,  0x88,  0x48,  0x9F,  0x4F,  0xD4,  0x7A,  0x64, 	/* 401E0 */
+	0x4A,  0x54,  0x4B,  0xD4,  0x7A,  0x54,  0x4B,  0xC8,  0x4A,  0x48,  0x4A,  0x48,  0x7B,  0xD4,  0x0E,  0x54, 	/* 401F0 */
+	0x00,  0x62,  0x00,  0x41,  0xB3,  0x00,  0x20,  0x7B,  0xFE,  0x48,  0x88,  0x48,  0x50,  0x4F,  0xFF,  0x78, 	/* 40200 */
+	0x00,  0x49,  0xFC,  0x49,  0x24,  0x79,  0xFC,  0x49,  0x24,  0x49,  0xFC,  0x48,  0x20,  0x79,  0xFC,  0x48, 	/* 40210 */
+	0x20,  0x07,  0xFF,  0x00,  0x00,  0xB6,  0x00,  0x20,  0x79,  0xFC,  0x49,  0x24,  0x49,  0xFC,  0x48,  0x20, 	/* 40220 */
+	0x7F,  0xFF,  0x48,  0x00,  0x49,  0xFC,  0x49,  0x04,  0x79,  0xFC,  0x49,  0x04,  0x49,  0xFC,  0x49,  0x04, 	/* 40230 */
+	0x79,  0xFC,  0x00,  0xCC,  0x07,  0x03,  0xB9,  0x00,  0x0C,  0x7B,  0xF2,  0x4A,  0x44,  0x49,  0x28,  0x4F, 	/* 40240 */
+	0xFF,  0x7C,  0x21,  0x48,  0x94,  0x4A,  0x92,  0x4A,  0x45,  0x7C,  0x3D,  0x48,  0x40,  0x48,  0xFC,  0x4B, 	/* 40250 */
+	0x48,  0x78,  0x30,  0x00,  0xCC,  0x0F,  0x03,  0xBB,  0x00,  0x20,  0x78,  0x7C,  0x49,  0x88,  0x4F,  0xFF, 	/* 40260 */
+	0x49,  0x2A,  0x79,  0x46,  0x49,  0xBC,  0x49,  0x00,  0x49,  0xFF,  0x79,  0x00,  0x49,  0x3C,  0x49,  0x00, 	/* 40270 */
+	0x4A,  0x7E,  0x7A,  0x42,  0x04,  0x7E,  0x00,  0x00,  0xBC,  0x00,  0x20,  0x78,  0x20,  0x48,  0x50,  0x48, 	/* 40280 */
+	0x88,  0x49,  0x04,  0x7A,  0xFA,  0x4C,  0x01,  0x4B,  0xDE,  0x4A,  0x52,  0x7A,  0x52,  0x4B,  0xDE,  0x49, 	/* 40290 */
+	0x08,  0x49,  0x08,  0x79,  0x8C,  0x02,  0x52,  0x04,  0x22,  0xBD,  0x08,  0x08,  0x7F,  0xFF,  0x08,  0x08, 	/* 402A0 */
+	0x7F,  0x7E,  0x22,  0x24,  0x3E,  0x18,  0x23,  0x94,  0x1C,  0x62,  0x6F,  0xF9,  0x08,  0x08,  0x0F,  0xF8, 	/* 402B0 */
+	0x08,  0x08,  0x0F,  0xF8,  0x08,  0x08,  0x0F,  0xF8,  0x00,  0x00,  0xBF,  0x1F,  0x3E,  0x11,  0x22,  0x1F, 	/* 402C0 */
+	0x3E,  0x11,  0x22,  0x1F,  0x3E,  0x11,  0x22,  0x1F,  0x3E,  0x04,  0x20,  0x0F,  0xFE,  0x18,  0x40,  0x6F, 	/* 402D0 */
+	0xFC,  0x08,  0x40,  0x0F,  0xFC,  0x08,  0x40,  0x0F,  0xFF,  0x00,  0x00,  0x87,  0x00,  0x48,  0x7B,  0xFF, 	/* 402E0 */
+	0x48,  0x48,  0x4B,  0xFF,  0x4A,  0x01,  0x7A,  0xFD,  0x48,  0x00,  0x4B,  0xFF,  0x48,  0x42,  0x78,  0xAC, 	/* 402F0 */
+	0x4B,  0x58,  0x48,  0x94,  0x4B,  0x34,  0x78,  0xD2,  0x03,  0x11,  0x00,  0x60,  0x8D,  0x1F,  0x3E,  0x11, 	/* 40300 */
+	0x22,  0x1F,  0x3E,  0x11,  0x22,  0x1F,  0x3E,  0x11,  0x22,  0x1F,  0xFF,  0x08,  0x40,  0x1F,  0xFC,  0x68, 	/* 40310 */
+	0x40,  0x0F,  0xFC,  0x08,  0x40,  0x3F,  0xFE,  0x06,  0x18,  0x01,  0xE0,  0x3E,  0x1F,  0x97,  0x00,  0x80, 	/* 40320 */
+	0x0F,  0xFC,  0x00,  0x80,  0x13,  0xF0,  0x12,  0x10,  0x13,  0xF0,  0x1F,  0xFE,  0x08,  0x08,  0x7F,  0x7F, 	/* 40330 */
+	0x08,  0x08,  0x5E,  0x5E,  0x52,  0x52,  0x5E,  0x5E,  0x52,  0x52,  0x7F,  0x7F,  0x00,  0x00,  0x9A,  0x00, 	/* 40340 */
+	0x00,  0x77,  0xFE,  0x54,  0x02,  0x57,  0xFE,  0x75,  0xE7,  0x54,  0x20,  0x55,  0xFE,  0x55,  0x4A,  0x75, 	/* 40350 */
+	0xFE,  0x54,  0x40,  0x54,  0xFE,  0x75,  0xAA,  0x0A,  0xFA,  0x08,  0x2A,  0x11,  0xF6,  0x00,  0x0C,  0x9B, 	/* 40360 */
+	0x00,  0x00,  0x1F,  0xF8,  0x00,  0x10,  0x03,  0x20,  0x00,  0xC0,  0x00,  0x40,  0x3F,  0xFE,  0x00,  0x42, 	/* 40370 */
+	0x00,  0xC4,  0x01,  0x48,  0x02,  0x40,  0x04,  0x40,  0x18,  0x40,  0x60,  0x40,  0x00,  0x40,  0x00,  0xC0, 	/* 40380 */
+	0x9C,  0x00,  0x10,  0x3F,  0x10,  0x01,  0x28,  0x1A,  0x28,  0x04,  0x44,  0x7F,  0x42,  0x05,  0xBD,  0x0D, 	/* 40390 */
+	0x00,  0x0E,  0x00,  0x14,  0xFC,  0x14,  0x04,  0x24,  0x04,  0x44,  0x08,  0x04,  0x08,  0x04,  0x10,  0x0C, 	/* 403A0 */
+	0x10,  0xA2,  0x04,  0x00,  0x04,  0x00,  0x07,  0xFE,  0x08,  0x80,  0x08,  0x80,  0x10,  0x80,  0x20,  0x80, 	/* 403B0 */
+	0x7F,  0xFF,  0x01,  0x40,  0x01,  0x40,  0x02,  0x20,  0x02,  0x20,  0x04,  0x10,  0x08,  0x08,  0x10,  0x04, 	/* 403C0 */
+	0x60,  0x03,  0xA3,  0x01,  0x00,  0x01,  0x20,  0x02,  0x18,  0x04,  0x74,  0x3F,  0x82,  0x04,  0x00,  0x04, 	/* 403D0 */
+	0x00,  0x0F,  0xFC,  0x08,  0x80,  0x10,  0x80,  0x7F,  0xFF,  0x01,  0x40,  0x02,  0x20,  0x04,  0x10,  0x18, 	/* 403E0 */
+	0x0C,  0x60,  0x03,  0xA5,  0x10,  0x00,  0x10,  0x00,  0x10,  0x00,  0x1F,  0xFE,  0x24,  0x42,  0x24,  0x42, 	/* 403F0 */
+	0x44,  0x42,  0x04,  0x42,  0x7F,  0xC2,  0x04,  0x42,  0x0A,  0x42,  0x09,  0x42,  0x11,  0x7E,  0x10,  0x80, 	/* 40400 */
+	0x20,  0x80,  0x40,  0x00,  0xA7,  0x10,  0x02,  0x11,  0xF2,  0x10,  0x12,  0x3F,  0x12,  0x28,  0x12,  0x48, 	/* 40410 */
+	0xF2,  0x08,  0x82,  0x7F,  0x82,  0x08,  0x82,  0x08,  0xF2,  0x0C,  0x12,  0x12,  0x12,  0x12,  0x12,  0x21, 	/* 40420 */
+	0x12,  0x40,  0x22,  0x00,  0xC2,  0xA9,  0x10,  0x00,  0x10,  0xFE,  0x10,  0x80,  0x1F,  0x80,  0x28,  0x80, 	/* 40430 */
+	0x28,  0xFC,  0x48,  0x84,  0x08,  0x84,  0x7F,  0x84,  0x08,  0xFC,  0x14,  0x80,  0x12,  0x80,  0x12,  0x80, 	/* 40440 */
+	0x22,  0x80,  0x20,  0xFF,  0x40,  0x00,  0xAD,  0x00,  0x00,  0x11,  0xFE,  0x10,  0x00,  0x1F,  0x00,  0x28, 	/* 40450 */
+	0xFC,  0x28,  0x84,  0x48,  0x84,  0x08,  0x84,  0x7F,  0xFC,  0x08,  0x04,  0x08,  0x84,  0x14,  0x48,  0x12, 	/* 40460 */
+	0x48,  0x22,  0x10,  0x21,  0xFE,  0x40,  0x00,  0xAE,  0x10,  0x04,  0x10,  0x18,  0x1E,  0xF0,  0x28,  0x10, 	/* 40470 */
+	0x29,  0xFF,  0x48,  0x38,  0x08,  0x54,  0x7F,  0x93,  0x08,  0x30,  0x08,  0x20,  0x0D,  0xFF,  0x12,  0x24, 	/* 40480 */
+	0x12,  0x44,  0x22,  0x78,  0x40,  0x24,  0x01,  0xC2,  0xAF,  0x10,  0x0C,  0x11,  0xF0,  0x10,  0x20,  0x3F, 	/* 40490 */
+	0xFF,  0x28,  0x48,  0x48,  0xFC,  0x09,  0x4B,  0x7E,  0x78,  0x08,  0x00,  0x09,  0xFE,  0x15,  0x02,  0x13, 	/* 404A0 */
+	0x7A,  0x23,  0x4A,  0x21,  0x7A,  0x41,  0x02,  0x01,  0x06,  0xB3,  0x00,  0x00,  0x3F,  0xFF,  0x01,  0x00, 	/* 404B0 */
+	0x01,  0x00,  0x01,  0x00,  0x02,  0x00,  0x02,  0x00,  0x07,  0xFC,  0x04,  0x04,  0x0C,  0x04,  0x0C,  0x04, 	/* 404C0 */
+	0x14,  0x04,  0x24,  0x04,  0x44,  0x04,  0x07,  0xFC,  0x00,  0x00,  0xBC,  0x00,  0x00,  0x7E,  0xFE,  0x08, 	/* 404D0 */
+	0x10,  0x08,  0x10,  0x08,  0x10,  0x10,  0x10,  0x1E,  0x10,  0x12,  0x10,  0x32,  0x10,  0x52,  0x10,  0x12, 	/* 404E0 */
+	0x10,  0x12,  0x10,  0x1E,  0x10,  0x00,  0x10,  0x01,  0xFF,  0x00,  0x00,  0x82,  0x00,  0x10,  0x7F,  0x10, 	/* 404F0 */
+	0x08,  0x10,  0x08,  0x58,  0x08,  0x54,  0x08,  0x52,  0x1E,  0x92,  0x12,  0x91,  0x33,  0x15,  0x32,  0x14, 	/* 40500 */
+	0x52,  0x38,  0x12,  0x08,  0x1E,  0x10,  0x00,  0x20,  0x00,  0xC0,  0x03,  0x00,  0x8C,  0x01,  0x00,  0x7F, 	/* 40510 */
+	0x7E,  0x11,  0x12,  0x11,  0x52,  0x11,  0x92,  0x17,  0x12,  0x3D,  0x12,  0x25,  0x12,  0x65,  0x12,  0x25, 	/* 40520 */
+	0x52,  0x25,  0x52,  0x24,  0xE2,  0x3C,  0x22,  0x00,  0x42,  0x01,  0x82,  0x06,  0x0C,  0x92,  0x00,  0x88, 	/* 40530 */
+	0x7F,  0x88,  0x08,  0x88,  0x08,  0x88,  0x08,  0x89,  0x10,  0x89,  0x1E,  0xFA,  0x12,  0x8C,  0x32,  0x88, 	/* 40540 */
+	0x52,  0x88,  0x12,  0x88,  0x12,  0x88,  0x1E,  0x88,  0x00,  0xB9,  0x00,  0xC9,  0x03,  0x07,  0x94,  0x00, 	/* 40550 */
+	0x00,  0x7F,  0xFE,  0x08,  0x44,  0x08,  0x44,  0x08,  0x44,  0x08,  0x44,  0x10,  0x44,  0x1F,  0xFF,  0x12, 	/* 40560 */
+	0x44,  0x32,  0x44,  0x52,  0x44,  0x12,  0x44,  0x12,  0x44,  0x1E,  0x84,  0x00,  0x84,  0x01,  0x04,  0x95, 	/* 40570 */
+	0x00,  0x40,  0x7F,  0x40,  0x09,  0xF8,  0x08,  0x48,  0x08,  0x48,  0x08,  0x49,  0x1E,  0x89,  0x13,  0x27, 	/* 40580 */
+	0x32,  0x20,  0x32,  0x20,  0x53,  0xFE,  0x12,  0x20,  0x1E,  0x20,  0x00,  0x20,  0x00,  0x20,  0x00,  0x20, 	/* 40590 */
+	0xA0,  0x00,  0x00,  0x7F,  0x7C,  0x08,  0x44,  0x08,  0x44,  0x08,  0x44,  0x10,  0x7C,  0x1E,  0x44,  0x12, 	/* 405A0 */
+	0x44,  0x32,  0x44,  0x52,  0x7C,  0x12,  0x44,  0x12,  0x44,  0x1E,  0x44,  0x00,  0x44,  0x01,  0xFF,  0x00, 	/* 405B0 */
+	0x00,  0xA5,  0x00,  0x04,  0x7F,  0x18,  0x08,  0xF0,  0x08,  0x90,  0x08,  0x90,  0x08,  0x90,  0x1E,  0xFF, 	/* 405C0 */
+	0x12,  0x90,  0x32,  0x90,  0x32,  0x88,  0x52,  0x88,  0x12,  0xC8,  0x1F,  0x84,  0x02,  0x05,  0x01,  0xF3, 	/* 405D0 */
+	0x00,  0x01,  0xA6,  0x04,  0x20,  0x04,  0x22,  0x14,  0x24,  0x17,  0xB8,  0x14,  0x20,  0x14,  0x21,  0x17, 	/* 405E0 */
+	0xA1,  0x1C,  0x1F,  0x30,  0x00,  0x7F,  0xFF,  0x02,  0x00,  0x07,  0xFC,  0x0C,  0x04,  0x14,  0x04,  0x67, 	/* 405F0 */
+	0xFC,  0x00,  0x00,  0xA7,  0x00,  0x20,  0x7F,  0x20,  0x08,  0x20,  0x08,  0x20,  0x08,  0x3E,  0x08,  0x20, 	/* 40600 */
+	0x1E,  0x20,  0x12,  0x20,  0x32,  0x20,  0x32,  0xFC,  0x52,  0x84,  0x12,  0x84,  0x1E,  0x84,  0x00,  0x84, 	/* 40610 */
+	0x00,  0xFC,  0x00,  0x00,  0xB2,  0x00,  0x40,  0x7F,  0x40,  0x08,  0x7E,  0x08,  0x42,  0x08,  0x82,  0x10, 	/* 40620 */
+	0xFA,  0x1F,  0x0A,  0x32,  0x0A,  0x32,  0x7A,  0x52,  0x42,  0x12,  0x4C,  0x12,  0x40,  0x12,  0x40,  0x1E, 	/* 40630 */
+	0x42,  0x00,  0x22,  0x00,  0x1E,  0xB4,  0x00,  0x10,  0x7F,  0x10,  0x08,  0x10,  0x08,  0xFF,  0x08,  0x92, 	/* 40640 */
+	0x10,  0x94,  0x1E,  0x90,  0x32,  0xFE,  0x32,  0xC4,  0x52,  0xC4,  0x12,  0xA4,  0x12,  0xA8,  0x1E,  0x90, 	/* 40650 */
+	0x01,  0x18,  0x01,  0x24,  0x02,  0x43,  0xBA,  0x00,  0x00,  0x7F,  0xFF,  0x08,  0x80,  0x08,  0x80,  0x08, 	/* 40660 */
+	0xFF,  0x08,  0x90,  0x1E,  0x90,  0x12,  0x9E,  0x32,  0x92,  0x32,  0x92,  0x52,  0x92,  0x12,  0xA2,  0x1F, 	/* 40670 */
+	0x22,  0x01,  0x22,  0x02,  0x42,  0x04,  0x8C,  0xBF,  0x00,  0x08,  0x7F,  0x08,  0x08,  0x08,  0x08,  0x7F, 	/* 40680 */
+	0x08,  0x40,  0x10,  0x48,  0x1E,  0x48,  0x32,  0x48,  0x32,  0x48,  0x52,  0x48,  0x12,  0x54,  0x12,  0x92, 	/* 40690 */
+	0x1E,  0x92,  0x12,  0xAF,  0x11,  0x71,  0x02,  0x01,  0x85,  0x00,  0x10,  0x7F,  0x10,  0x08,  0xFE,  0x08, 	/* 406A0 */
+	0x10,  0x08,  0x10,  0x10,  0x10,  0x1F,  0xFF,  0x12,  0x00,  0x32,  0x10,  0x52,  0x10,  0x12,  0xFE,  0x12, 	/* 406B0 */
+	0x10,  0x1E,  0x10,  0x00,  0x10,  0x03,  0xFF,  0x00,  0x00,  0x9D,  0x00,  0x10,  0x7F,  0x92,  0x08,  0x52, 	/* 406C0 */
+	0x08,  0x54,  0x08,  0x10,  0x10,  0x7E,  0x1E,  0x42,  0x32,  0x42,  0x32,  0x7E,  0x52,  0x42,  0x12,  0x42, 	/* 406D0 */
+	0x12,  0x7E,  0x12,  0x42,  0x1E,  0x42,  0x00,  0x42,  0x00,  0x46,  0xAB,  0x00,  0x20,  0x7E,  0x20,  0x09, 	/* 406E0 */
+	0xFF,  0x08,  0x20,  0x08,  0x58,  0x10,  0x8C,  0x1F,  0xF2,  0x32,  0x00,  0x32,  0xA4,  0x52,  0xA4,  0x12, 	/* 406F0 */
+	0xA4,  0x12,  0xA4,  0x1E,  0xA4,  0x01,  0x25,  0x01,  0x05,  0x02,  0x03,  0xAC,  0x00,  0x00,  0x7F,  0xFF, 	/* 40700 */
+	0x08,  0x10,  0x08,  0xFE,  0x08,  0x92,  0x10,  0x92,  0x1E,  0xFE,  0x12,  0x92,  0x32,  0x92,  0x52,  0xFE, 	/* 40710 */
+	0x12,  0x50,  0x12,  0x20,  0x1E,  0x20,  0x00,  0x50,  0x01,  0x8C,  0x06,  0x03,  0xAF,  0x00,  0x00,  0x7F, 	/* 40720 */
+	0xFE,  0x08,  0x42,  0x08,  0x42,  0x08,  0x7E,  0x10,  0x42,  0x1E,  0x42,  0x32,  0x7E,  0x32,  0x42,  0x52, 	/* 40730 */
+	0x42,  0x12,  0x7E,  0x12,  0x28,  0x1E,  0x28,  0x00,  0x49,  0x00,  0x89,  0x03,  0x07,  0xB2,  0x00,  0x44, 	/* 40740 */
+	0x7F,  0x44,  0x04,  0x42,  0x04,  0x52,  0x08,  0x92,  0x09,  0x28,  0x1E,  0x28,  0x12,  0x44,  0x32,  0x82, 	/* 40750 */
+	0x53,  0x7D,  0x12,  0x44,  0x12,  0x44,  0x1E,  0x44,  0x00,  0x44,  0x00,  0x7C,  0x00,  0x00,  0xB4,  0x00, 	/* 40760 */
+	0x48,  0x7F,  0x48,  0x09,  0xFF,  0x08,  0x48,  0x08,  0x48,  0x10,  0x28,  0x1E,  0x29,  0x12,  0x49,  0x32, 	/* 40770 */
+	0x4A,  0x52,  0xCC,  0x13,  0x48,  0x12,  0x48,  0x1E,  0x48,  0x00,  0x49,  0x00,  0x49,  0x00,  0x47,  0xBC, 	/* 40780 */
+	0x00,  0x00,  0x7F,  0xEE,  0x08,  0xAA,  0x08,  0xAA,  0x08,  0xAA,  0x10,  0xEE,  0x1E,  0xAA,  0x12,  0xAA, 	/* 40790 */
+	0x32,  0xAA,  0x52,  0xEE,  0x12,  0xAA,  0x12,  0xAA,  0x1E,  0xAA,  0x01,  0x32,  0x01,  0x22,  0x02,  0x66, 	/* 407A0 */
+	0x81,  0x04,  0x10,  0x04,  0x10,  0x3F,  0xFE,  0x04,  0x10,  0x07,  0xF0,  0x04,  0x10,  0x07,  0xF0,  0x04, 	/* 407B0 */
+	0x10,  0x7F,  0xFF,  0x04,  0x10,  0x0F,  0xF8,  0x11,  0x04,  0x63,  0xF3,  0x0E,  0x10,  0x33,  0xF0,  0x02, 	/* 407C0 */
+	0x10,  0x86,  0x10,  0x20,  0x08,  0x20,  0x49,  0xFF,  0x21,  0x22,  0x21,  0xFC,  0x09,  0x44,  0x12,  0x68, 	/* 407D0 */
+	0x22,  0x38,  0x44,  0x4C,  0x09,  0x83,  0x7F,  0xFE,  0x02,  0x00,  0x07,  0xFC,  0x1C,  0x04,  0x67,  0xFC, 	/* 407E0 */
+	0x00,  0x00,  0x87,  0x00,  0x10,  0x7F,  0x10,  0x09,  0xFE,  0x09,  0x02,  0x09,  0x02,  0x10,  0xFC,  0x1E, 	/* 407F0 */
+	0x10,  0x32,  0x10,  0x32,  0x50,  0x52,  0x5E,  0x12,  0x50,  0x12,  0x50,  0x1E,  0xD0,  0x00,  0xB0,  0x01, 	/* 40800 */
+	0x18,  0x02,  0x07,  0x8C,  0x00,  0x20,  0x7F,  0x3C,  0x08,  0x44,  0x08,  0x48,  0x08,  0xF8,  0x10,  0x08, 	/* 40810 */
+	0x1F,  0xFF,  0x12,  0x10,  0x32,  0x92,  0x52,  0x5A,  0x12,  0x5C,  0x12,  0x34,  0x1E,  0xD2,  0x03,  0x11, 	/* 40820 */
+	0x00,  0x10,  0x00,  0x30,  0x8D,  0x00,  0x00,  0x7F,  0x7C,  0x08,  0x44,  0x08,  0x7C,  0x08,  0x44,  0x10, 	/* 40830 */
+	0x44,  0x1E,  0x7C,  0x32,  0x00,  0x33,  0xFE,  0x52,  0x04,  0x13,  0xFF,  0x12,  0x84,  0x1E,  0x44,  0x00, 	/* 40840 */
+	0x44,  0x00,  0x04,  0x00,  0x0C,  0x8E,  0x00,  0x10,  0x7F,  0x10,  0x08,  0xFF,  0x08,  0x00,  0x08,  0x44, 	/* 40850 */
+	0x10,  0x44,  0x1E,  0x64,  0x12,  0x8A,  0x33,  0x10,  0x52,  0x10,  0x13,  0xFF,  0x12,  0x10,  0x1E,  0x10, 	/* 40860 */
+	0x00,  0x10,  0x00,  0x10,  0x00,  0x10,  0x91,  0x00,  0x10,  0x3F,  0x20,  0x08,  0xFE,  0x08,  0x92,  0x08, 	/* 40870 */
+	0x92,  0x08,  0xFE,  0x1E,  0x92,  0x12,  0x92,  0x32,  0xFE,  0x52,  0x28,  0x12,  0x48,  0x13,  0xFF,  0x1E, 	/* 40880 */
+	0x08,  0x00,  0x08,  0x00,  0x08,  0x00,  0x08,  0x93,  0x00,  0x24,  0x00,  0x24,  0x7F,  0x48,  0x08,  0xFF, 	/* 40890 */
+	0x08,  0x88,  0x09,  0x88,  0x10,  0x88,  0x1E,  0xFE,  0x32,  0x88,  0x32,  0x88,  0x52,  0xFE,  0x12,  0x88, 	/* 408A0 */
+	0x12,  0x88,  0x1E,  0x88,  0x00,  0xFF,  0x00,  0x00,  0x95,  0x00,  0x20,  0x7F,  0x20,  0x08,  0xFE,  0x08, 	/* 408B0 */
+	0x50,  0x08,  0x88,  0x09,  0x04,  0x1E,  0x00,  0x13,  0xFF,  0x32,  0x04,  0x32,  0xE4,  0x52,  0xA4,  0x12, 	/* 408C0 */
+	0xA4,  0x12,  0xA4,  0x1E,  0xE4,  0x00,  0x04,  0x00,  0x0C,  0x97,  0x00,  0x10,  0x7F,  0x10,  0x09,  0xFF, 	/* 408D0 */
+	0x09,  0x01,  0x09,  0x41,  0x10,  0x4E,  0x1E,  0xFA,  0x32,  0x9A,  0x32,  0x9A,  0x53,  0x2A,  0x12,  0xAA, 	/* 408E0 */
+	0x12,  0x4C,  0x1E,  0x48,  0x00,  0x89,  0x01,  0x09,  0x06,  0x07,  0x9A,  0x00,  0x20,  0x7F,  0x20,  0x09, 	/* 408F0 */
+	0xFE,  0x08,  0x84,  0x08,  0x44,  0x10,  0x48,  0x1E,  0x48,  0x13,  0xFF,  0x32,  0x00,  0x52,  0x00,  0x12, 	/* 40900 */
+	0xFC,  0x12,  0x84,  0x1E,  0x84,  0x00,  0x84,  0x00,  0xFC,  0x00,  0x00,  0xA3,  0x00,  0x00,  0x7F,  0xFC, 	/* 40910 */
+	0x08,  0x84,  0x08,  0xFC,  0x08,  0x84,  0x10,  0x84,  0x1E,  0xFC,  0x12,  0x40,  0x32,  0x7E,  0x52,  0x92, 	/* 40920 */
+	0x13,  0x9A,  0x12,  0xAA,  0x1E,  0xC2,  0x00,  0xFA,  0x00,  0x02,  0x00,  0x0C,  0xA7,  0x00,  0x10,  0x7E, 	/* 40930 */
+	0x20,  0x08,  0xFC,  0x08,  0x84,  0x7E,  0x84,  0x08,  0xFC,  0x08,  0x84,  0x0E,  0x84,  0x70,  0xFC,  0x00, 	/* 40940 */
+	0x00,  0x7F,  0xFF,  0x01,  0x00,  0x07,  0xF8,  0x1C,  0x08,  0x64,  0x08,  0x07,  0xF8,  0xA9,  0x00,  0x00, 	/* 40950 */
+	0x7F,  0xFF,  0x04,  0x10,  0x04,  0x20,  0x08,  0x7E,  0x08,  0x42,  0x1F,  0x42,  0x11,  0x7E,  0x31,  0x42, 	/* 40960 */
+	0x51,  0x7E,  0x11,  0x42,  0x11,  0x42,  0x1F,  0x7E,  0x00,  0x24,  0x00,  0xC2,  0x03,  0x01,  0xAA,  0x00, 	/* 40970 */
+	0x44,  0x7F,  0x44,  0x09,  0xFF,  0x08,  0x44,  0x08,  0x7C,  0x10,  0x44,  0x1E,  0x7C,  0x12,  0x44,  0x32, 	/* 40980 */
+	0x44,  0x53,  0xFF,  0x12,  0xA8,  0x12,  0xAA,  0x1E,  0xC6,  0x00,  0x80,  0x00,  0xFF,  0x00,  0x00,  0xAF, 	/* 40990 */
+	0x00,  0x92,  0x7E,  0x92,  0x09,  0x24,  0x0B,  0x6C,  0x08,  0x92,  0x10,  0x92,  0x1E,  0x40,  0x12,  0xFE, 	/* 409A0 */
+	0x32,  0x8A,  0x52,  0xEA,  0x12,  0x92,  0x12,  0xAA,  0x1E,  0xC6,  0x00,  0x82,  0x00,  0xFE,  0x00,  0x00, 	/* 409B0 */
+	0xB5,  0x00,  0x10,  0x7F,  0x10,  0x08,  0x1F,  0x08,  0x10,  0x08,  0x7E,  0x10,  0x42,  0x1E,  0x42,  0x12, 	/* 409C0 */
+	0x7E,  0x32,  0x42,  0x52,  0x7E,  0x12,  0x42,  0x12,  0x42,  0x1E,  0x7E,  0x00,  0x24,  0x00,  0xC2,  0x03, 	/* 409D0 */
+	0x01,  0xBA,  0x00,  0x20,  0x7F,  0x20,  0x09,  0xFF,  0x09,  0x21,  0x09,  0x25,  0x08,  0x48,  0x1E,  0x7F, 	/* 409E0 */
+	0x12,  0xC8,  0x33,  0x48,  0x32,  0x7E,  0x52,  0x48,  0x12,  0x7E,  0x12,  0x48,  0x1E,  0x48,  0x00,  0x7F, 	/* 409F0 */
+	0x00,  0x00,  0xBC,  0x00,  0x00,  0x7F,  0xFF,  0x08,  0x90,  0x08,  0x90,  0x08,  0xFE,  0x10,  0x90,  0x1E, 	/* 40A00 */
+	0xFE,  0x12,  0x90,  0x32,  0x90,  0x52,  0xFE,  0x12,  0x0A,  0x13,  0xA6,  0x1F,  0x56,  0x01,  0x52,  0x02, 	/* 40A10 */
+	0x02,  0x00,  0x0C,  0xBE,  0x00,  0x00,  0x7F,  0xFE,  0x08,  0x82,  0x08,  0x82,  0x08,  0xFE,  0x10,  0xA8, 	/* 40A20 */
+	0x1E,  0xA8,  0x12,  0xFE,  0x32,  0xA8,  0x52,  0xA8,  0x12,  0xFF,  0x13,  0x52,  0x1F,  0x54,  0x02,  0x48, 	/* 40A30 */
+	0x04,  0x66,  0x01,  0x81,  0x81,  0x00,  0x84,  0x00,  0x44,  0x7E,  0x48,  0x13,  0xFF,  0x10,  0x88,  0x10, 	/* 40A40 */
+	0x88,  0x12,  0xA8,  0x3D,  0x32,  0x24,  0xAA,  0x64,  0xCC,  0x24,  0x44,  0x24,  0x88,  0x24,  0xCC,  0x3D, 	/* 40A50 */
+	0x32,  0x07,  0xFF,  0x00,  0x11,  0x85,  0x00,  0x10,  0x7F,  0x10,  0x09,  0xFF,  0x08,  0x44,  0x08,  0x28, 	/* 40A60 */
+	0x10,  0xFF,  0x1E,  0x81,  0x12,  0x91,  0x32,  0x10,  0x53,  0xFF,  0x12,  0x20,  0x12,  0x3C,  0x1E,  0x24, 	/* 40A70 */
+	0x00,  0x44,  0x00,  0x84,  0x03,  0x18,  0x86,  0x00,  0x00,  0x7F,  0x7C,  0x08,  0x44,  0x08,  0x5C,  0x08, 	/* 40A80 */
+	0x54,  0x10,  0x54,  0x1E,  0xFF,  0x12,  0x81,  0x32,  0xFD,  0x52,  0x44,  0x12,  0x7C,  0x12,  0x44,  0x1E, 	/* 40A90 */
+	0x7C,  0x00,  0x44,  0x00,  0x44,  0x00,  0x4C,  0x8A,  0x00,  0x00,  0x1F,  0xFE,  0x01,  0x00,  0x02,  0x00, 	/* 40AA0 */
+	0x07,  0xF8,  0x1A,  0x08,  0x02,  0x08,  0x03,  0xF8,  0x00,  0x00,  0x7F,  0xFF,  0x08,  0x10,  0x1F,  0x3E, 	/* 40AB0 */
+	0x31,  0x62,  0x51,  0xA2,  0x1F,  0x3E,  0x00,  0x00,  0x8B,  0x00,  0x42,  0x7F,  0x24,  0x09,  0xFF,  0x08, 	/* 40AC0 */
+	0x10,  0x08,  0xFE,  0x10,  0x10,  0x1E,  0x10,  0x13,  0xFF,  0x32,  0x20,  0x52,  0x20,  0x12,  0x7E,  0x12, 	/* 40AD0 */
+	0x88,  0x1F,  0x08,  0x02,  0x08,  0x00,  0xFF,  0x00,  0x00,  0x90,  0x04,  0x00,  0x1F,  0x3C,  0x11,  0x25, 	/* 40AE0 */
+	0x15,  0x47,  0x7F,  0x80,  0x11,  0x7C,  0x15,  0x24,  0x15,  0x18,  0x23,  0x24,  0x40,  0x43,  0x7F,  0xFF, 	/* 40AF0 */
+	0x02,  0x00,  0x07,  0xFC,  0x1C,  0x04,  0x67,  0xFC,  0x00,  0x00,  0x91,  0x00,  0x10,  0x7F,  0x92,  0x08, 	/* 40B00 */
+	0x92,  0x08,  0xFE,  0x08,  0x00,  0x11,  0xFF,  0x1E,  0x00,  0x12,  0xFE,  0x32,  0x82,  0x52,  0x82,  0x12, 	/* 40B10 */
+	0xFE,  0x12,  0x44,  0x1E,  0x24,  0x00,  0x28,  0x01,  0xFF,  0x00,  0x00,  0x94,  0x00,  0x84,  0x7F,  0xE4, 	/* 40B20 */
+	0x08,  0xBF,  0x09,  0xB4,  0x09,  0x54,  0x10,  0x54,  0x1E,  0xBF,  0x13,  0x04,  0x32,  0x04,  0x52,  0x10, 	/* 40B30 */
+	0x13,  0xFF,  0x12,  0x38,  0x1E,  0x54,  0x00,  0x92,  0x03,  0x11,  0x00,  0x10,  0x9A,  0x00,  0x20,  0x7F, 	/* 40B40 */
+	0x20,  0x09,  0xFF,  0x08,  0x20,  0x08,  0xFC,  0x10,  0xA4,  0x1E,  0xFC,  0x12,  0xA4,  0x32,  0xFC,  0x52, 	/* 40B50 */
+	0x22,  0x13,  0xFD,  0x12,  0x08,  0x1F,  0xFF,  0x00,  0x88,  0x00,  0x48,  0x00,  0x18,  0xA7,  0x00,  0x20, 	/* 40B60 */
+	0x7F,  0xFE,  0x08,  0x20,  0x08,  0xFC,  0x08,  0x20,  0x11,  0xFF,  0x1E,  0x00,  0x12,  0xFC,  0x32,  0x84, 	/* 40B70 */
+	0x52,  0xFC,  0x12,  0x84,  0x12,  0xFC,  0x1E,  0x84,  0x00,  0xFC,  0x00,  0xCC,  0x07,  0x02,  0xA8,  0x00, 	/* 40B80 */
+	0x40,  0x00,  0x40,  0x1F,  0xFE,  0x11,  0x08,  0x1F,  0xFE,  0x13,  0x88,  0x15,  0x5C,  0x19,  0x2A,  0x11, 	/* 40B90 */
+	0x09,  0x1F,  0xFE,  0x10,  0x80,  0x13,  0xF8,  0x26,  0x08,  0x3A,  0x08,  0x43,  0xF8,  0x00,  0x00,  0xAC, 	/* 40BA0 */
+	0x04,  0x00,  0x7F,  0xBC,  0x04,  0x24,  0x3F,  0x25,  0x00,  0x43,  0x3F,  0xFD,  0x25,  0x24,  0x3F,  0x18, 	/* 40BB0 */
+	0x20,  0x24,  0x40,  0xC3,  0x3F,  0xFE,  0x02,  0x00,  0x07,  0xF8,  0x1C,  0x08,  0x67,  0xF8,  0x00,  0x00, 	/* 40BC0 */
+	0xAF,  0x00,  0xA4,  0x7E,  0xA4,  0x13,  0x78,  0x10,  0xA4,  0x10,  0xAA,  0x11,  0x7D,  0x27,  0xE4,  0x3C, 	/* 40BD0 */
+	0x22,  0x27,  0xFF,  0x64,  0x94,  0x24,  0x94,  0x24,  0xC8,  0x3D,  0x29,  0x01,  0x15,  0x02,  0x23,  0x04, 	/* 40BE0 */
+	0x41,  0xB4,  0x00,  0xEA,  0x7F,  0x2C,  0x09,  0x29,  0x08,  0xC6,  0x08,  0x44,  0x10,  0xFE,  0x1F,  0x01, 	/* 40BF0 */
+	0x12,  0x7C,  0x32,  0x44,  0x52,  0x44,  0x12,  0x7C,  0x12,  0x00,  0x1E,  0x44,  0x00,  0x28,  0x03,  0xFF, 	/* 40C00 */
+	0x00,  0x00,  0xBD,  0x00,  0x10,  0x7F,  0x7E,  0x08,  0x10,  0x09,  0xFF,  0x08,  0x00,  0x10,  0x44,  0x1F, 	/* 40C10 */
+	0xFF,  0x12,  0x44,  0x32,  0x74,  0x53,  0xCF,  0x12,  0x00,  0x13,  0xFF,  0x1E,  0x48,  0x00,  0x49,  0x00, 	/* 40C20 */
+	0x89,  0x03,  0x07,  0x81,  0x00,  0x48,  0x7F,  0x50,  0x08,  0xFF,  0x09,  0x90,  0x0A,  0x90,  0x10,  0xFE, 	/* 40C30 */
+	0x1E,  0x90,  0x32,  0x90,  0x32,  0xFE,  0x52,  0x90,  0x12,  0x90,  0x12,  0xFF,  0x1E,  0x04,  0x01,  0x52, 	/* 40C40 */
+	0x01,  0x29,  0x02,  0x29,  0x87,  0x00,  0x20,  0x7E,  0x40,  0x11,  0xFE,  0x11,  0x0A,  0x11,  0x72,  0x11, 	/* 40C50 */
+	0xAA,  0x3D,  0x72,  0x25,  0xFE,  0x65,  0x72,  0x25,  0xAA,  0x24,  0x20,  0x27,  0xFF,  0x3C,  0x30,  0x00, 	/* 40C60 */
+	0x48,  0x01,  0x84,  0x06,  0x03,  0x8E,  0x00,  0x44,  0x7F,  0x44,  0x09,  0xFF,  0x08,  0x44,  0x08,  0xEE, 	/* 40C70 */
+	0x11,  0x55,  0x1E,  0x44,  0x12,  0x44,  0x33,  0xFF,  0x52,  0x12,  0x12,  0x90,  0x12,  0x9E,  0x1E,  0xD0, 	/* 40C80 */
+	0x00,  0xB0,  0x01,  0x18,  0x02,  0x07,  0x91,  0x01,  0x12,  0x00,  0x92,  0x7E,  0x94,  0x09,  0xFF,  0x09, 	/* 40C90 */
+	0x01,  0x09,  0x7D,  0x10,  0x44,  0x1E,  0x7C,  0x12,  0x00,  0x32,  0xFE,  0x52,  0x92,  0x12,  0x92,  0x12, 	/* 40CA0 */
+	0xFE,  0x1E,  0x92,  0x00,  0xFE,  0x00,  0x00,  0x92,  0x00,  0x42,  0x7E,  0x24,  0x09,  0xFE,  0x08,  0x10, 	/* 40CB0 */
+	0x08,  0xFE,  0x10,  0x10,  0x1F,  0xFF,  0x12,  0x24,  0x32,  0xCA,  0x52,  0x48,  0x13,  0xFF,  0x12,  0x4A, 	/* 40CC0 */
+	0x12,  0x6A,  0x1F,  0xC5,  0x00,  0x4B,  0x00,  0xD1,  0x99,  0x02,  0x00,  0x7E,  0x7E,  0x13,  0x82,  0x12, 	/* 40CD0 */
+	0x14,  0x12,  0x48,  0x11,  0xFF,  0x3A,  0x09,  0x2B,  0xCA,  0x2D,  0x28,  0x69,  0x2E,  0x2F,  0xE8,  0x29, 	/* 40CE0 */
+	0x28,  0x29,  0xA8,  0x39,  0x78,  0x02,  0x48,  0x04,  0x87,  0xA6,  0x00,  0x10,  0x7E,  0x10,  0x11,  0xFF, 	/* 40CF0 */
+	0x11,  0x24,  0x11,  0x7E,  0x11,  0x24,  0x3D,  0x3C,  0x25,  0xFF,  0x65,  0x10,  0x25,  0x7E,  0x25,  0x52, 	/* 40D00 */
+	0x25,  0x7E,  0x3E,  0x52,  0x02,  0x7E,  0x04,  0x62,  0x01,  0x81,  0xAA,  0x00,  0x00,  0x7F,  0xFF,  0x11, 	/* 40D10 */
+	0x24,  0x11,  0xFF,  0x11,  0x24,  0x11,  0x7E,  0x3D,  0x52,  0x25,  0x7E,  0x65,  0x52,  0x25,  0x7E,  0x25, 	/* 40D20 */
+	0x10,  0x25,  0xFF,  0x3E,  0x95,  0x02,  0x9B,  0x04,  0xE1,  0x00,  0x83,  0xAB,  0x00,  0x8A,  0x7E,  0x92, 	/* 40D30 */
+	0x08,  0xBA,  0x09,  0x6D,  0x0B,  0x6D,  0x10,  0xBA,  0x1E,  0xAA,  0x13,  0x7D,  0x33,  0x97,  0x52,  0x10, 	/* 40D40 */
+	0x13,  0xFF,  0x12,  0x38,  0x1E,  0x54,  0x00,  0x92,  0x03,  0x11,  0x00,  0x10,  0xAC,  0x09,  0x24,  0x08, 	/* 40D50 */
+	0xC4,  0x7F,  0x3F,  0x09,  0x24,  0x1C,  0xCE,  0x2B,  0x35,  0x48,  0x04,  0x00,  0x80,  0x7F,  0xFF,  0x02, 	/* 40D60 */
+	0x10,  0x1F,  0xEC,  0x61,  0x03,  0x07,  0xF8,  0x3A,  0x08,  0x03,  0xF8,  0x00,  0x00,  0xBA,  0x00,  0x00, 	/* 40D70 */
+	0x00,  0x00,  0x1F,  0xFC,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x7F,  0xFF,  0x00,  0x80,  0x04,  0x90, 	/* 40D80 */
+	0x04,  0x88,  0x08,  0x84,  0x08,  0x84,  0x10,  0x82,  0x20,  0x82,  0x40,  0x80,  0x01,  0x80,  0xBC,  0x08, 	/* 40D90 */
+	0x40,  0x08,  0x40,  0x08,  0x40,  0x7E,  0x40,  0x02,  0x40,  0x04,  0x40,  0x04,  0x40,  0x08,  0x40,  0x0C, 	/* 40DA0 */
+	0x40,  0x1A,  0x40,  0x29,  0x40,  0x48,  0x42,  0x08,  0x42,  0x08,  0x42,  0x08,  0x3E,  0x08,  0x00,  0xBE, 	/* 40DB0 */
+	0x08,  0x10,  0x08,  0x10,  0x08,  0x10,  0x7E,  0x10,  0x02,  0x10,  0x04,  0xFE,  0x04,  0x10,  0x08,  0x10, 	/* 40DC0 */
+	0x0C,  0x10,  0x1A,  0x10,  0x29,  0x10,  0x48,  0x10,  0x08,  0x10,  0x08,  0x10,  0x09,  0xFF,  0x08,  0x00, 	/* 40DD0 */
+	0x80,  0x00,  0x00,  0x3E,  0x7E,  0x00,  0x42,  0x00,  0x42,  0x00,  0x42,  0x7F,  0x42,  0x08,  0x42,  0x0A, 	/* 40DE0 */
+	0x7E,  0x2A,  0x40,  0x2A,  0x40,  0x2A,  0x40,  0x2A,  0x40,  0x2A,  0x41,  0x48,  0x41,  0x08,  0x3F,  0x08, 	/* 40DF0 */
+	0x00,  0x81,  0x08,  0x00,  0x08,  0x3E,  0x08,  0x22,  0x7F,  0x22,  0x01,  0x24,  0x02,  0x24,  0x04,  0x28, 	/* 40E00 */
+	0x0C,  0x24,  0x1A,  0x22,  0x29,  0x22,  0x48,  0xA1,  0x08,  0x31,  0x08,  0x29,  0x08,  0x26,  0x08,  0x20, 	/* 40E10 */
+	0x08,  0x20,  0x87,  0x08,  0x04,  0x08,  0x18,  0x08,  0xF0,  0x7E,  0x90,  0x02,  0x90,  0x04,  0x90,  0x04, 	/* 40E20 */
+	0x90,  0x08,  0xFF,  0x1C,  0x90,  0x2A,  0x88,  0x49,  0x88,  0x08,  0x88,  0x08,  0x84,  0x08,  0xB5,  0x08, 	/* 40E30 */
+	0xC3,  0x0B,  0x01,  0x88,  0x08,  0x04,  0x08,  0x18,  0x08,  0xE0,  0x7E,  0x80,  0x02,  0x80,  0x04,  0xFF, 	/* 40E40 */
+	0x04,  0x88,  0x08,  0x88,  0x1C,  0x88,  0x2A,  0x88,  0x49,  0x88,  0x08,  0x88,  0x09,  0x08,  0x09,  0x08, 	/* 40E50 */
+	0x0A,  0x08,  0x08,  0x08,  0x89,  0x08,  0x10,  0x08,  0x10,  0x08,  0x10,  0x7E,  0x90,  0x02,  0x90,  0x04, 	/* 40E60 */
+	0x9E,  0x04,  0x90,  0x08,  0x90,  0x0C,  0x90,  0x1A,  0x90,  0x29,  0x90,  0x48,  0x90,  0x08,  0x90,  0x08, 	/* 40E70 */
+	0x90,  0x0B,  0xFF,  0x08,  0x00,  0x90,  0x08,  0x20,  0x08,  0x20,  0x08,  0x20,  0x7F,  0xFF,  0x02,  0x20, 	/* 40E80 */
+	0x04,  0x20,  0x04,  0x20,  0x08,  0x40,  0x1C,  0x7E,  0x2A,  0xC2,  0x48,  0xC2,  0x09,  0x42,  0x0A,  0x42, 	/* 40E90 */
+	0x08,  0x42,  0x08,  0x7E,  0x08,  0x00,  0x93,  0x00,  0x24,  0x3E,  0x22,  0x00,  0x22,  0x01,  0xFF,  0x00, 	/* 40EA0 */
+	0x20,  0x7F,  0x20,  0x08,  0x32,  0x0A,  0x32,  0x2A,  0x54,  0x2A,  0x54,  0x2A,  0x48,  0x2A,  0x88,  0x29, 	/* 40EB0 */
+	0x14,  0x4A,  0x24,  0x08,  0x42,  0x08,  0x81,  0x95,  0x00,  0x20,  0x3F,  0x10,  0x00,  0x08,  0x00,  0x0A, 	/* 40EC0 */
+	0x00,  0x22,  0x7F,  0x22,  0x08,  0xA4,  0x08,  0xA4,  0x2A,  0xA8,  0x2A,  0xAA,  0x2B,  0x31,  0x2A,  0x21, 	/* 40ED0 */
+	0x2A,  0x60,  0x48,  0xA2,  0x09,  0x22,  0x0A,  0x1E,  0x96,  0x08,  0x00,  0x08,  0xFC,  0x08,  0x84,  0x7E, 	/* 40EE0 */
+	0x84,  0x02,  0x84,  0x04,  0xFC,  0x04,  0x84,  0x08,  0x84,  0x1C,  0x84,  0x2A,  0xFC,  0x49,  0x84,  0x08, 	/* 40EF0 */
+	0x84,  0x08,  0x84,  0x08,  0x84,  0x09,  0xFF,  0x08,  0x00,  0x97,  0x00,  0x04,  0x3E,  0x18,  0x00,  0xF0, 	/* 40F00 */
+	0x00,  0x90,  0x00,  0x90,  0x7F,  0x90,  0x08,  0xFF,  0x0A,  0x90,  0x2A,  0x90,  0x2A,  0x88,  0x2A,  0x88, 	/* 40F10 */
+	0x28,  0xE8,  0x2B,  0x85,  0x48,  0x05,  0x0B,  0xF3,  0x08,  0x01,  0x9A,  0x00,  0x20,  0x3E,  0x20,  0x00, 	/* 40F20 */
+	0x20,  0x00,  0x7F,  0x00,  0x50,  0x7F,  0x50,  0x08,  0x90,  0x0B,  0x1E,  0x2A,  0x10,  0x2A,  0x10,  0x2A, 	/* 40F30 */
+	0x10,  0x2A,  0x1E,  0x2A,  0x10,  0x48,  0x10,  0x08,  0x10,  0x08,  0x10,  0x9D,  0x08,  0x00,  0x08,  0xFE, 	/* 40F40 */
+	0x08,  0x82,  0x7E,  0x82,  0x02,  0x82,  0x04,  0x82,  0x04,  0xFE,  0x08,  0x28,  0x1C,  0x28,  0x2A,  0x28, 	/* 40F50 */
+	0x49,  0x28,  0x08,  0x48,  0x08,  0x48,  0x08,  0x89,  0x08,  0x89,  0x09,  0x07,  0x9E,  0x08,  0x10,  0x08, 	/* 40F60 */
+	0x10,  0x08,  0x10,  0x7F,  0xFE,  0x02,  0x92,  0x04,  0x92,  0x04,  0xFE,  0x08,  0x92,  0x1C,  0x92,  0x2A, 	/* 40F70 */
+	0x92,  0x49,  0xFE,  0x09,  0x10,  0x08,  0x10,  0x08,  0x10,  0x08,  0x10,  0x08,  0x10,  0x9F,  0x01,  0x00, 	/* 40F80 */
+	0x11,  0x08,  0x11,  0x08,  0x1F,  0xF8,  0x41,  0x02,  0x41,  0x02,  0x7F,  0xFE,  0x40,  0x02,  0x0F,  0xF0, 	/* 40F90 */
+	0x00,  0x00,  0x7F,  0xFE,  0x01,  0x00,  0x05,  0x30,  0x19,  0x0C,  0x61,  0x02,  0x03,  0x00,  0xA0,  0x00, 	/* 40FA0 */
+	0x00,  0x3D,  0xFE,  0x00,  0x02,  0x00,  0x02,  0x00,  0xFA,  0x7F,  0x02,  0x08,  0x02,  0x0A,  0xF2,  0x2A, 	/* 40FB0 */
+	0x92,  0x2A,  0x92,  0x2A,  0x92,  0x2A,  0xF2,  0x2A,  0x02,  0x48,  0x02,  0x08,  0x02,  0x08,  0x0C,  0xA2, 	/* 40FC0 */
+	0x08,  0x40,  0x08,  0x40,  0x08,  0x40,  0x7E,  0x7F,  0x02,  0x90,  0x04,  0x90,  0x05,  0x10,  0x08,  0x58, 	/* 40FD0 */
+	0x1C,  0x54,  0x2A,  0x54,  0x49,  0x52,  0x08,  0x92,  0x09,  0x12,  0x08,  0x10,  0x08,  0x10,  0x08,  0x30, 	/* 40FE0 */
+	0xA5,  0x08,  0x84,  0x08,  0x44,  0x08,  0x48,  0x7E,  0xFE,  0x02,  0x10,  0x04,  0x10,  0x04,  0x10,  0x08, 	/* 40FF0 */
+	0xFE,  0x1C,  0x10,  0x2A,  0x10,  0x49,  0x10,  0x09,  0xFF,  0x08,  0x10,  0x08,  0x10,  0x08,  0x10,  0x08, 	/* 41000 */
+	0x10,  0xA8,  0x00,  0x00,  0x7F,  0xFF,  0x02,  0x20,  0x1F,  0xFC,  0x12,  0x24,  0x12,  0x24,  0x1F,  0xFC, 	/* 41010 */
+	0x00,  0x00,  0x0F,  0xF8,  0x00,  0x00,  0x7F,  0xFF,  0x00,  0x80,  0x04,  0xB0,  0x18,  0x8C,  0x60,  0x82, 	/* 41020 */
+	0x01,  0x80,  0xAD,  0x04,  0x00,  0x07,  0xFC,  0x08,  0x84,  0x15,  0x28,  0x73,  0x10,  0x0A,  0x68,  0x04, 	/* 41030 */
+	0x84,  0x1B,  0xF3,  0x60,  0x00,  0x00,  0x00,  0x7F,  0xFF,  0x00,  0x80,  0x04,  0xB0,  0x18,  0x8C,  0x60, 	/* 41040 */
+	0x82,  0x01,  0x80,  0xB7,  0x10,  0x20,  0x10,  0x20,  0x13,  0xFE,  0x7C,  0x20,  0x05,  0xFC,  0x08,  0x20, 	/* 41050 */
+	0x0B,  0xFE,  0x10,  0x48,  0x18,  0x48,  0x37,  0xFF,  0x54,  0x88,  0x10,  0xC8,  0x11,  0x48,  0x12,  0x08, 	/* 41060 */
+	0x14,  0x08,  0x10,  0x18,  0xBA,  0x00,  0x44,  0x3E,  0x44,  0x01,  0xFF,  0x00,  0x44,  0x00,  0x44,  0x7F, 	/* 41070 */
+	0x7C,  0x08,  0x44,  0x08,  0x44,  0x2A,  0x7C,  0x2A,  0x44,  0x2A,  0x44,  0x2B,  0xFF,  0x2A,  0x00,  0x48, 	/* 41080 */
+	0x48,  0x08,  0x84,  0x0B,  0x02,  0xBF,  0x00,  0x20,  0x3C,  0x7C,  0x00,  0x48,  0x00,  0x88,  0x01,  0xF0, 	/* 41090 */
+	0x7C,  0x10,  0x0B,  0xFF,  0x08,  0x12,  0x2B,  0x12,  0x2A,  0x9C,  0x2A,  0x98,  0x2A,  0x34,  0x2A,  0x54, 	/* 410A0 */
+	0x48,  0x92,  0x0B,  0x11,  0x08,  0x30,  0x80,  0x00,  0x80,  0x7F,  0xFF,  0x08,  0x08,  0x0B,  0xE8,  0x0A, 	/* 410B0 */
+	0x28,  0x0B,  0xE8,  0x08,  0x08,  0x0F,  0xF8,  0x00,  0x00,  0x1F,  0xF8,  0x00,  0x00,  0x7F,  0xFF,  0x00, 	/* 410C0 */
+	0x80,  0x0C,  0x9C,  0x70,  0x83,  0x01,  0x80,  0x81,  0x04,  0x10,  0x04,  0x10,  0x7F,  0xFF,  0x0C,  0x38, 	/* 410D0 */
+	0x0E,  0x34,  0x15,  0x54,  0x24,  0x92,  0x44,  0x11,  0x0F,  0xF8,  0x00,  0x00,  0x7F,  0xFF,  0x00,  0x80, 	/* 410E0 */
+	0x04,  0xB0,  0x18,  0x8C,  0x60,  0x82,  0x01,  0x80,  0x84,  0x08,  0x00,  0x08,  0xFC,  0x08,  0x04,  0x7E, 	/* 410F0 */
+	0xFC,  0x02,  0x04,  0x04,  0x04,  0x05,  0xFF,  0x08,  0x12,  0x1C,  0x92,  0x2A,  0x5C,  0x49,  0x38,  0x08, 	/* 41100 */
+	0x34,  0x08,  0xD2,  0x0B,  0x11,  0x08,  0x10,  0x08,  0x30,  0x85,  0x09,  0x22,  0x08,  0x92,  0x08,  0x94, 	/* 41110 */
+	0x7E,  0xFE,  0x02,  0x92,  0x04,  0x92,  0x04,  0xFE,  0x08,  0x92,  0x1C,  0xFE,  0x2A,  0x10,  0x49,  0x10, 	/* 41120 */
+	0x09,  0xFF,  0x08,  0x10,  0x08,  0x10,  0x08,  0x10,  0x08,  0x10,  0x8A,  0x00,  0x80,  0x7B,  0xFE,  0x00, 	/* 41130 */
+	0x8A,  0x00,  0x8A,  0x03,  0xEA,  0x7C,  0x8A,  0x10,  0xF2,  0x17,  0x92,  0x54,  0xAC,  0x54,  0x20,  0x57, 	/* 41140 */
+	0xFF,  0x54,  0x60,  0x54,  0x50,  0x50,  0x88,  0x11,  0x04,  0x16,  0x03,  0x8D,  0x08,  0x00,  0x08,  0xFC, 	/* 41150 */
+	0x08,  0x84,  0x7E,  0xBC,  0x02,  0xA4,  0x04,  0xA4,  0x04,  0xA4,  0x09,  0xFE,  0x1D,  0x02,  0x2B,  0x7A, 	/* 41160 */
+	0x49,  0x4A,  0x09,  0x4A,  0x09,  0x7A,  0x09,  0x02,  0x09,  0x02,  0x09,  0x06,  0x8E,  0x08,  0x10,  0x08, 	/* 41170 */
+	0x10,  0x08,  0x1F,  0x7E,  0x10,  0x02,  0xFC,  0x04,  0x84,  0x04,  0x84,  0x08,  0xFC,  0x1C,  0x84,  0x2A, 	/* 41180 */
+	0xFC,  0x49,  0x84,  0x08,  0x84,  0x08,  0xFC,  0x08,  0x58,  0x08,  0x84,  0x0B,  0x02,  0x8F,  0x08,  0x00, 	/* 41190 */
+	0x08,  0xFE,  0x08,  0x00,  0x7E,  0x7C,  0x02,  0x44,  0x04,  0x44,  0x04,  0x7C,  0x08,  0x00,  0x1C,  0xFE, 	/* 411A0 */
+	0x2A,  0x92,  0x49,  0x92,  0x08,  0xFE,  0x08,  0x92,  0x08,  0x92,  0x08,  0xFE,  0x08,  0x00,  0x9D,  0x00, 	/* 411B0 */
+	0x00,  0x3E,  0xFE,  0x00,  0x92,  0x00,  0xFE,  0x00,  0x92,  0x7E,  0xFE,  0x08,  0x48,  0x0A,  0x49,  0x2A, 	/* 411C0 */
+	0x87,  0x2B,  0x20,  0x2A,  0x3C,  0x2A,  0x44,  0x2B,  0xA8,  0x48,  0x10,  0x08,  0x6C,  0x09,  0x83,  0xA6, 	/* 411D0 */
+	0x12,  0x00,  0x13,  0xDE,  0x2D,  0x12,  0x4F,  0xF2,  0x11,  0x12,  0x35,  0xD2,  0x55,  0x12,  0x15,  0xDC, 	/* 411E0 */
+	0x16,  0x10,  0x17,  0xF8,  0x00,  0x00,  0x3F,  0xFF,  0x02,  0xB0,  0x0C,  0x8C,  0x30,  0x82,  0x01,  0x80, 	/* 411F0 */
+	0xA7,  0x00,  0x10,  0x3F,  0xFF,  0x00,  0x10,  0x00,  0xFE,  0x00,  0x00,  0x7E,  0xFE,  0x08,  0x82,  0x08, 	/* 41200 */
+	0xFE,  0x2A,  0x44,  0x2A,  0x28,  0x2B,  0xFF,  0x2A,  0x00,  0x2A,  0xFE,  0x48,  0x82,  0x08,  0xFE,  0x08, 	/* 41210 */
+	0x00,  0xAA,  0x00,  0x00,  0x3D,  0xEF,  0x01,  0x29,  0x01,  0xEF,  0x00,  0x00,  0x7E,  0xFE,  0x08,  0x92, 	/* 41220 */
+	0x0A,  0xFE,  0x2A,  0x92,  0x2A,  0x92,  0x2A,  0xFE,  0x2A,  0x10,  0x2B,  0xFF,  0x48,  0x10,  0x08,  0x10, 	/* 41230 */
+	0x08,  0x10,  0xAE,  0x00,  0x48,  0x3D,  0xFE,  0x01,  0x4A,  0x01,  0xFE,  0x01,  0x4A,  0x7F,  0xFE,  0x08, 	/* 41240 */
+	0x00,  0x09,  0xFF,  0x2A,  0x00,  0x2A,  0xFC,  0x2A,  0x84,  0x2A,  0xFC,  0x2A,  0x48,  0x28,  0x30,  0x4B, 	/* 41250 */
+	0xFF,  0x08,  0x00,  0xB0,  0x10,  0x00,  0x13,  0xFF,  0x11,  0x24,  0x7E,  0x22,  0x07,  0xFF,  0x0A,  0x22, 	/* 41260 */
+	0x0B,  0x76,  0x12,  0xAA,  0x13,  0x76,  0x3A,  0x22,  0x57,  0x76,  0x12,  0xAA,  0x13,  0x76,  0x12,  0x22, 	/* 41270 */
+	0x12,  0x22,  0x12,  0x06,  0xB3,  0x00,  0x10,  0x3D,  0xFF,  0x00,  0x00,  0x00,  0xEE,  0x00,  0xAA,  0x7F, 	/* 41280 */
+	0xEE,  0x08,  0x28,  0x08,  0xFE,  0x2A,  0x28,  0x2A,  0xFE,  0x2A,  0x28,  0x2B,  0xFF,  0x2A,  0xD2,  0x4B, 	/* 41290 */
+	0x4C,  0x08,  0x74,  0x09,  0x83,  0xB9,  0x00,  0x04,  0x00,  0x38,  0x3F,  0xC0,  0x00,  0x80,  0x0F,  0xF8, 	/* 412A0 */
+	0x08,  0x88,  0x08,  0x88,  0x0F,  0xF8,  0x00,  0x80,  0x3F,  0xFE,  0x20,  0x82,  0x20,  0xA2,  0x20,  0xF2, 	/* 412B0 */
+	0x2F,  0x0A,  0x20,  0x02,  0x20,  0x06,  0xBA,  0x00,  0x00,  0x0F,  0xF8,  0x08,  0x88,  0x08,  0x88,  0x0F, 	/* 412C0 */
+	0xF8,  0x08,  0x88,  0x08,  0x88,  0x0F,  0xF8,  0x00,  0x80,  0x3F,  0xFE,  0x20,  0x82,  0x20,  0xA2,  0x20, 	/* 412D0 */
+	0xF2,  0x2F,  0x0A,  0x20,  0x02,  0x20,  0x06,  0xBD,  0x00,  0x80,  0x01,  0x40,  0x02,  0x20,  0x04,  0x90, 	/* 412E0 */
+	0x1F,  0xFC,  0x69,  0x4B,  0x08,  0x88,  0x0B,  0x68,  0x0F,  0xF8,  0x01,  0x00,  0x1F,  0xFC,  0x11,  0x44, 	/* 412F0 */
+	0x11,  0x24,  0x12,  0xD4,  0x1F,  0x04,  0x10,  0x0C,  0xBE,  0x00,  0x08,  0x00,  0x70,  0x1F,  0x80,  0x00, 	/* 41300 */
+	0x80,  0x00,  0x80,  0x00,  0x80,  0x7F,  0xFF,  0x00,  0x80,  0x01,  0xC0,  0x02,  0xA0,  0x04,  0x90,  0x18, 	/* 41310 */
+	0x8C,  0x60,  0x83,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0xBF,  0x00,  0x18,  0x00,  0xE0,  0x3F,  0x80, 	/* 41320 */
+	0x00,  0x80,  0x7F,  0xFF,  0x01,  0xC0,  0x02,  0xA0,  0x04,  0x90,  0x18,  0x8C,  0x60,  0x83,  0x02,  0x40, 	/* 41330 */
+	0x02,  0x40,  0x02,  0x40,  0x04,  0x42,  0x18,  0x22,  0x60,  0x1E,  0x80,  0x00,  0x08,  0x00,  0x70,  0x1F, 	/* 41340 */
+	0x80,  0x00,  0x80,  0x7F,  0xFF,  0x01,  0xC0,  0x02,  0xA0,  0x0C,  0x98,  0x70,  0x87,  0x1F,  0xF0,  0x01, 	/* 41350 */
+	0x10,  0x01,  0x1C,  0x01,  0x04,  0x02,  0x04,  0x0C,  0x04,  0x30,  0x18,  0x81,  0x01,  0x10,  0x06,  0x10, 	/* 41360 */
+	0x3C,  0x10,  0x04,  0x10,  0x04,  0x10,  0x04,  0x10,  0x7F,  0x90,  0x06,  0x20,  0x0D,  0x28,  0x0C,  0xA4, 	/* 41370 */
+	0x14,  0xA4,  0x14,  0x42,  0x24,  0x5E,  0x45,  0xE2,  0x04,  0x01,  0x04,  0x01,  0x89,  0x00,  0x08,  0x1F, 	/* 41380 */
+	0xF0,  0x00,  0x80,  0x7F,  0xFF,  0x00,  0x80,  0x1F,  0xFC,  0x00,  0x84,  0x7F,  0xFF,  0x00,  0x84,  0x1F, 	/* 41390 */
+	0xFC,  0x01,  0xC0,  0x02,  0xA0,  0x04,  0x90,  0x18,  0x8C,  0x60,  0x83,  0x00,  0x80,  0x8B,  0x02,  0x20, 	/* 413A0 */
+	0x0C,  0x20,  0x78,  0x24,  0x08,  0xA4,  0x08,  0xA4,  0x08,  0xA8,  0x7E,  0xA8,  0x08,  0xA0,  0x09,  0x20, 	/* 413B0 */
+	0x1C,  0x50,  0x1A,  0x50,  0x2A,  0x88,  0x28,  0x88,  0x49,  0x04,  0x0A,  0x02,  0x0C,  0x01,  0x91,  0x01, 	/* 413C0 */
+	0x04,  0x06,  0x44,  0x3C,  0x24,  0x04,  0x14,  0x04,  0x14,  0x04,  0x84,  0x7F,  0x44,  0x04,  0x24,  0x0E, 	/* 413D0 */
+	0x24,  0x0D,  0x07,  0x14,  0xBC,  0x15,  0xC4,  0x24,  0x04,  0x44,  0x04,  0x04,  0x04,  0x04,  0x04,  0x92, 	/* 413E0 */
+	0x02,  0x20,  0x0C,  0x20,  0x78,  0x20,  0x08,  0xA8,  0x08,  0xA4,  0x08,  0xA4,  0x7E,  0xA2,  0x09,  0x22, 	/* 413F0 */
+	0x0C,  0x26,  0x1A,  0x24,  0x19,  0x68,  0x28,  0x08,  0x28,  0x10,  0x48,  0x20,  0x08,  0xC0,  0x0B,  0x00, 	/* 41400 */
+	0x95,  0x02,  0x88,  0x0C,  0x88,  0x78,  0x88,  0x08,  0x88,  0x08,  0x8A,  0x08,  0x8A,  0x7E,  0xEC,  0x08, 	/* 41410 */
+	0x8C,  0x0C,  0x88,  0x1A,  0x88,  0x1A,  0x88,  0x28,  0x88,  0x28,  0x89,  0x48,  0x89,  0x08,  0xE9,  0x0B, 	/* 41420 */
+	0x87,  0x98,  0x01,  0x20,  0x06,  0x10,  0x38,  0x10,  0x08,  0x54,  0x08,  0x44,  0x7F,  0x44,  0x08,  0x48, 	/* 41430 */
+	0x09,  0x4A,  0x1D,  0x51,  0x1B,  0x51,  0x29,  0x61,  0x2A,  0xC0,  0x49,  0x42,  0x0A,  0x22,  0x0C,  0x1E, 	/* 41440 */
+	0x08,  0x00,  0x9F,  0x02,  0x00,  0x0C,  0xFC,  0x78,  0x84,  0x08,  0x84,  0x08,  0x84,  0x7E,  0xFC,  0x08, 	/* 41450 */
+	0x84,  0x08,  0x84,  0x1C,  0x84,  0x1A,  0xFC,  0x2A,  0x84,  0x28,  0x84,  0x48,  0x84,  0x08,  0x84,  0x0B, 	/* 41460 */
+	0xFF,  0x08,  0x00,  0xA1,  0x02,  0x24,  0x0C,  0x22,  0x78,  0x22,  0x09,  0xFF,  0x08,  0x20,  0x7E,  0x20, 	/* 41470 */
+	0x08,  0x32,  0x08,  0x32,  0x1C,  0x54,  0x1A,  0x54,  0x2A,  0x48,  0x28,  0x88,  0x49,  0x14,  0x0A,  0x24, 	/* 41480 */
+	0x08,  0x42,  0x08,  0x81,  0xA3,  0x02,  0x10,  0x0C,  0x10,  0x78,  0x10,  0x09,  0xFF,  0x08,  0x10,  0x7F, 	/* 41490 */
+	0x10,  0x08,  0x10,  0x09,  0xFE,  0x1C,  0x38,  0x1A,  0x38,  0x29,  0x54,  0x28,  0x54,  0x48,  0x92,  0x09, 	/* 414A0 */
+	0x11,  0x08,  0x10,  0x08,  0x10,  0xA4,  0x02,  0x00,  0x0D,  0xFE,  0x78,  0x24,  0x09,  0x24,  0x08,  0xA4, 	/* 414B0 */
+	0x08,  0xA8,  0x7E,  0xA0,  0x08,  0x20,  0x0B,  0xFF,  0x1C,  0x20,  0x1A,  0x20,  0x2A,  0x20,  0x28,  0x20, 	/* 414C0 */
+	0x48,  0x20,  0x08,  0x20,  0x08,  0x20,  0xA6,  0x00,  0x80,  0x3F,  0xFE,  0x00,  0x80,  0x1F,  0xFC,  0x01, 	/* 414D0 */
+	0x40,  0x7F,  0xFF,  0x02,  0x10,  0x0C,  0x6C,  0x77,  0x83,  0x00,  0x80,  0x3F,  0xFE,  0x01,  0xC0,  0x02, 	/* 414E0 */
+	0xA0,  0x0C,  0x98,  0x30,  0x86,  0x00,  0x80,  0xA7,  0x02,  0x10,  0x0C,  0x10,  0x78,  0x10,  0x08,  0xFE, 	/* 414F0 */
+	0x08,  0x92,  0x08,  0x92,  0x7E,  0x92,  0x08,  0x92,  0x0D,  0xFF,  0x1A,  0x10,  0x1A,  0x10,  0x28,  0x28, 	/* 41500 */
+	0x28,  0x28,  0x48,  0x44,  0x09,  0x82,  0x0E,  0x01,  0xA9,  0x02,  0x10,  0x0C,  0x50,  0x78,  0x50,  0x08, 	/* 41510 */
+	0xFE,  0x08,  0x90,  0x7F,  0x10,  0x08,  0x10,  0x09,  0xFF,  0x1C,  0x10,  0x1A,  0x10,  0x29,  0x30,  0x28, 	/* 41520 */
+	0x28,  0x48,  0x48,  0x08,  0x84,  0x09,  0x02,  0x0A,  0x01,  0xAC,  0x02,  0x00,  0x0D,  0xFF,  0x78,  0x80, 	/* 41530 */
+	0x08,  0x80,  0x08,  0x80,  0x08,  0xFE,  0x7F,  0x82,  0x08,  0x82,  0x08,  0x82,  0x1C,  0xFE,  0x1A,  0x80, 	/* 41540 */
+	0x29,  0x80,  0x28,  0x80,  0x48,  0x80,  0x09,  0xFF,  0x08,  0x00,  0xB0,  0x02,  0x40,  0x0C,  0x40,  0x78, 	/* 41550 */
+	0x40,  0x08,  0x7F,  0x08,  0x90,  0x7E,  0x90,  0x09,  0x10,  0x18,  0x18,  0x1C,  0x54,  0x1A,  0x54,  0x2A, 	/* 41560 */
+	0x52,  0x28,  0x92,  0x49,  0x12,  0x08,  0x10,  0x08,  0x10,  0x08,  0x30,  0xBB,  0x01,  0x20,  0x06,  0x3E, 	/* 41570 */
+	0x38,  0x44,  0x08,  0x84,  0x09,  0x68,  0x7E,  0x10,  0x08,  0x20,  0x08,  0xC8,  0x1C,  0x0F,  0x1A,  0x11, 	/* 41580 */
+	0x29,  0x22,  0x28,  0xDA,  0x48,  0x04,  0x08,  0x08,  0x08,  0x30,  0x09,  0xC0,  0x80,  0x02,  0x04,  0x0C, 	/* 41590 */
+	0x64,  0x78,  0x18,  0x09,  0xE4,  0x08,  0x20,  0x7F,  0xFF,  0x08,  0x50,  0x1C,  0x50,  0x1A,  0xFE,  0x18, 	/* 415A0 */
+	0xD2,  0x29,  0x52,  0x2A,  0x52,  0x48,  0x52,  0x08,  0x5C,  0x08,  0x50,  0x08,  0x10,  0x88,  0x02,  0x00, 	/* 415B0 */
+	0x0C,  0xFC,  0x78,  0x84,  0x08,  0xFC,  0x08,  0x84,  0x08,  0x84,  0x7E,  0xFC,  0x08,  0x00,  0x09,  0xFE, 	/* 415C0 */
+	0x1C,  0x20,  0x1A,  0x20,  0x2B,  0xFF,  0x28,  0x20,  0x48,  0x20,  0x08,  0x20,  0x08,  0x20,  0x8B,  0x02, 	/* 415D0 */
+	0x00,  0x0C,  0xFC,  0x78,  0x84,  0x08,  0x84,  0x08,  0x84,  0x7F,  0xFC,  0x08,  0x00,  0x08,  0x00,  0x1C, 	/* 415E0 */
+	0xFE,  0x1A,  0x10,  0x2A,  0x10,  0x28,  0xFC,  0x48,  0x10,  0x08,  0x10,  0x09,  0xFF,  0x08,  0x00,  0x8D, 	/* 415F0 */
+	0x02,  0x10,  0x0C,  0x54,  0x78,  0x52,  0x08,  0x92,  0x09,  0x11,  0x7F,  0xFC,  0x08,  0x84,  0x08,  0x84, 	/* 41600 */
+	0x1C,  0xFC,  0x1A,  0x84,  0x2A,  0x84,  0x28,  0xFC,  0x48,  0x84,  0x08,  0x84,  0x08,  0x84,  0x08,  0x8C, 	/* 41610 */
+	0x8E,  0x02,  0x04,  0x0C,  0x84,  0x38,  0x48,  0x08,  0x50,  0x08,  0xFC,  0x7F,  0x84,  0x08,  0x84,  0x08, 	/* 41620 */
+	0x84,  0x1C,  0xFC,  0x1A,  0x28,  0x29,  0x28,  0x28,  0x28,  0x48,  0x48,  0x08,  0x49,  0x08,  0x89,  0x09, 	/* 41630 */
+	0x07,  0x94,  0x02,  0x20,  0x0C,  0x20,  0x78,  0x50,  0x08,  0x8C,  0x0B,  0xFB,  0x08,  0x00,  0x7F,  0xF8, 	/* 41640 */
+	0x08,  0x08,  0x1C,  0x10,  0x1A,  0x10,  0x2A,  0xA0,  0x29,  0x94,  0x49,  0x92,  0x0A,  0x8A,  0x0C,  0x8A, 	/* 41650 */
+	0x08,  0x78,  0x97,  0x02,  0x10,  0x0C,  0x20,  0x79,  0xFC,  0x09,  0x24,  0x09,  0x24,  0x7F,  0xFC,  0x09, 	/* 41660 */
+	0x24,  0x09,  0x24,  0x1D,  0xFC,  0x1A,  0x48,  0x28,  0x88,  0x2B,  0xFF,  0x48,  0x08,  0x08,  0x08,  0x08, 	/* 41670 */
+	0x08,  0x08,  0x08,  0x98,  0x02,  0x44,  0x0C,  0x44,  0x79,  0xFF,  0x08,  0x44,  0x08,  0x44,  0x08,  0x7C, 	/* 41680 */
+	0x7E,  0x44,  0x08,  0x44,  0x0C,  0x7C,  0x1A,  0x44,  0x1A,  0x44,  0x2B,  0xFF,  0x28,  0x00,  0x48,  0x48, 	/* 41690 */
+	0x08,  0x84,  0x0B,  0x02,  0x99,  0x02,  0x08,  0x0C,  0x08,  0x79,  0xFF,  0x08,  0x08,  0x08,  0x3E,  0x08, 	/* 416A0 */
+	0xA2,  0x7F,  0xA2,  0x08,  0xBE,  0x0C,  0xA2,  0x1A,  0xBE,  0x1A,  0xA2,  0x28,  0xA2,  0x28,  0xBE,  0x48, 	/* 416B0 */
+	0x80,  0x08,  0xFF,  0x08,  0x00,  0x9A,  0x02,  0x44,  0x0C,  0x44,  0x78,  0x88,  0x08,  0xFE,  0x09,  0x88, 	/* 416C0 */
+	0x0A,  0x88,  0x7E,  0x88,  0x08,  0xFE,  0x1C,  0x88,  0x1A,  0x88,  0x2A,  0xFE,  0x28,  0x88,  0x48,  0x88, 	/* 416D0 */
+	0x08,  0x88,  0x08,  0xFF,  0x08,  0x00,  0x9C,  0x02,  0x20,  0x0C,  0x20,  0x79,  0xFE,  0x08,  0x20,  0x0B, 	/* 416E0 */
+	0xFF,  0x7E,  0x50,  0x08,  0x52,  0x1C,  0x8E,  0x1B,  0x40,  0x2A,  0x78,  0x28,  0x88,  0x4B,  0x50,  0x08, 	/* 416F0 */
+	0x20,  0x08,  0x50,  0x09,  0x8C,  0x0E,  0x03,  0x9F,  0x00,  0x80,  0x7F,  0xFF,  0x08,  0x08,  0x0B,  0xE8, 	/* 41700 */
+	0x0A,  0x28,  0x0B,  0xE8,  0x08,  0x08,  0x0F,  0xF8,  0x00,  0x1C,  0x1F,  0xE0,  0x00,  0x80,  0x7F,  0xFF, 	/* 41710 */
+	0x02,  0xC0,  0x0C,  0xB0,  0x70,  0x8F,  0x00,  0x80,  0xA0,  0x02,  0x00,  0x0C,  0xFE,  0x78,  0x92,  0x08, 	/* 41720 */
+	0x92,  0x08,  0xFE,  0x08,  0x92,  0x7E,  0x92,  0x08,  0xFE,  0x0C,  0x92,  0x1A,  0xBA,  0x1A,  0xAA,  0x28, 	/* 41730 */
+	0xAA,  0x28,  0xBA,  0x49,  0x02,  0x09,  0x02,  0x0A,  0x06,  0xAE,  0x02,  0x04,  0x0C,  0x18,  0x79,  0xE0, 	/* 41740 */
+	0x08,  0x20,  0x0B,  0xFF,  0x08,  0x20,  0x7F,  0xFC,  0x09,  0x24,  0x1D,  0xFC,  0x1B,  0x24,  0x29,  0xFC, 	/* 41750 */
+	0x28,  0x20,  0x49,  0xFE,  0x08,  0x20,  0x0F,  0xFF,  0x08,  0x00,  0xB1,  0x02,  0x04,  0x0C,  0x18,  0x79, 	/* 41760 */
+	0xE4,  0x08,  0x92,  0x08,  0x92,  0x09,  0x01,  0x7F,  0x11,  0x08,  0xFE,  0x0C,  0x92,  0x1A,  0xFE,  0x1A, 	/* 41770 */
+	0x92,  0x28,  0x92,  0x29,  0xFF,  0x48,  0x82,  0x08,  0x82,  0x08,  0x86,  0xB2,  0x02,  0x04,  0x0C,  0x18, 	/* 41780 */
+	0x38,  0xE0,  0x08,  0x02,  0x08,  0xA2,  0x7F,  0x54,  0x08,  0x54,  0x08,  0x08,  0x1C,  0xBE,  0x1A,  0xA2, 	/* 41790 */
+	0x2A,  0xA2,  0x28,  0xBE,  0x48,  0xA2,  0x08,  0xA2,  0x08,  0xBE,  0x08,  0x80,  0xB7,  0x02,  0x00,  0x0C, 	/* 417A0 */
+	0xFE,  0x78,  0x92,  0x08,  0xFE,  0x08,  0x92,  0x7E,  0xFE,  0x08,  0x48,  0x0C,  0x49,  0x1A,  0x87,  0x1B, 	/* 417B0 */
+	0x20,  0x28,  0x3C,  0x28,  0x44,  0x49,  0xA8,  0x08,  0x10,  0x08,  0x6C,  0x09,  0x83,  0xBB,  0x02,  0x04, 	/* 417C0 */
+	0x0C,  0x18,  0x79,  0xE4,  0x08,  0x92,  0x08,  0x92,  0x08,  0x81,  0x7F,  0x21,  0x08,  0x20,  0x08,  0xCE, 	/* 417D0 */
+	0x1C,  0x82,  0x1A,  0x82,  0x2A,  0xEE,  0x28,  0x82,  0x48,  0x82,  0x08,  0xFE,  0x08,  0x00,  0xBC,  0x02, 	/* 417E0 */
+	0x20,  0x0C,  0x20,  0x79,  0xFE,  0x09,  0x02,  0x09,  0x00,  0x09,  0xFC,  0x7E,  0x44,  0x08,  0x64,  0x19, 	/* 417F0 */
+	0xA8,  0x1C,  0x58,  0x1A,  0x94,  0x2B,  0x34,  0x28,  0x52,  0x49,  0x91,  0x08,  0x10,  0x08,  0x60,  0xBD, 	/* 41800 */
+	0x02,  0x24,  0x0C,  0x22,  0x79,  0xFF,  0x08,  0x30,  0x08,  0x51,  0x7E,  0x9F,  0x09,  0x44,  0x18,  0x78, 	/* 41810 */
+	0x1C,  0x42,  0x2A,  0x3E,  0x2A,  0x00,  0x48,  0xFE,  0x08,  0x82,  0x08,  0xFE,  0x08,  0x82,  0x08,  0xFE, 	/* 41820 */
+	0xBE,  0x01,  0x00,  0x7F,  0xFE,  0x04,  0x10,  0x07,  0xF0,  0x3F,  0xFE,  0x20,  0x02,  0x27,  0xF2,  0x24, 	/* 41830 */
+	0x12,  0x27,  0xF6,  0x00,  0x18,  0x1F,  0xE0,  0x00,  0x80,  0x7F,  0xFF,  0x06,  0xB0,  0x78,  0x8F,  0x00, 	/* 41840 */
+	0x80,  0xBF,  0x02,  0x10,  0x0C,  0x10,  0x79,  0xFF,  0x08,  0x00,  0x08,  0xFC,  0x7E,  0x84,  0x08,  0xFC, 	/* 41850 */
+	0x18,  0x00,  0x1D,  0xFE,  0x1B,  0x02,  0x29,  0x7A,  0x29,  0x4A,  0x49,  0x4A,  0x09,  0x7A,  0x09,  0x02, 	/* 41860 */
+	0x09,  0x06,  0x80,  0x08,  0x00,  0x08,  0x3C,  0x7F,  0x24,  0x08,  0x25,  0x3E,  0x25,  0x00,  0x43,  0x7F, 	/* 41870 */
+	0x80,  0x45,  0xFC,  0x79,  0x24,  0x08,  0x24,  0x7F,  0x14,  0x0C,  0x18,  0x1A,  0x08,  0x29,  0x14,  0x48, 	/* 41880 */
+	0x62,  0x09,  0x81,  0x82,  0x02,  0x10,  0x0C,  0x10,  0x79,  0xFF,  0x08,  0x10,  0x08,  0xFE,  0x7E,  0x92, 	/* 41890 */
+	0x08,  0xFE,  0x08,  0x92,  0x1C,  0x92,  0x1A,  0xFE,  0x2A,  0x20,  0x28,  0x10,  0x49,  0x52,  0x09,  0x41, 	/* 418A0 */
+	0x0A,  0x45,  0x08,  0x3C,  0x83,  0x02,  0x10,  0x0C,  0x10,  0x79,  0xFF,  0x09,  0x01,  0x09,  0x49,  0x08, 	/* 418B0 */
+	0x44,  0x7E,  0x92,  0x09,  0x12,  0x0C,  0x28,  0x1A,  0x44,  0x1A,  0xFE,  0x29,  0x45,  0x28,  0x44,  0x48, 	/* 418C0 */
+	0x44,  0x08,  0x7C,  0x08,  0x00,  0x86,  0x02,  0x10,  0x0C,  0x20,  0x78,  0xFC,  0x08,  0x84,  0x08,  0xFC, 	/* 418D0 */
+	0x7E,  0x84,  0x08,  0xFC,  0x0C,  0x10,  0x1A,  0x54,  0x19,  0x9B,  0x28,  0x34,  0x29,  0xC9,  0x48,  0x32, 	/* 418E0 */
+	0x08,  0xCC,  0x08,  0x30,  0x0B,  0xC0,  0x89,  0x02,  0x00,  0x0D,  0xFE,  0x79,  0x02,  0x09,  0xFE,  0x09, 	/* 418F0 */
+	0x00,  0x09,  0xD6,  0x7F,  0x10,  0x09,  0xD6,  0x0D,  0x00,  0x1B,  0x50,  0x19,  0x7E,  0x29,  0x50,  0x2A, 	/* 41900 */
+	0x90,  0x4B,  0xFF,  0x0C,  0x10,  0x08,  0x10,  0x8D,  0x02,  0x20,  0x0D,  0xFE,  0x78,  0x20,  0x09,  0xFC, 	/* 41910 */
+	0x08,  0x20,  0x7F,  0xFF,  0x08,  0x00,  0x08,  0xFC,  0x1C,  0x84,  0x1A,  0xFC,  0x2A,  0x84,  0x28,  0xFC, 	/* 41920 */
+	0x48,  0x84,  0x08,  0xFC,  0x08,  0x4C,  0x09,  0x82,  0x8E,  0x20,  0x00,  0x22,  0xFF,  0x3C,  0x10,  0x20, 	/* 41930 */
+	0x20,  0x21,  0x7E,  0x1F,  0x42,  0x00,  0x42,  0x03,  0x7E,  0x3C,  0x42,  0x04,  0x7E,  0x7F,  0xC2,  0x0E, 	/* 41940 */
+	0x42,  0x15,  0x7E,  0x24,  0xA4,  0x44,  0x42,  0x05,  0x81,  0x8F,  0x04,  0x04,  0x08,  0x38,  0x7B,  0xC2, 	/* 41950 */
+	0x09,  0x22,  0x08,  0xA4,  0x09,  0xFC,  0x7E,  0x04,  0x08,  0xFC,  0x1C,  0x04,  0x1A,  0xFC,  0x1A,  0x20, 	/* 41960 */
+	0x29,  0x54,  0x29,  0x52,  0x49,  0x55,  0x0A,  0x45,  0x08,  0x3C,  0x90,  0x02,  0x40,  0x0C,  0x78,  0x38, 	/* 41970 */
+	0x90,  0x09,  0xFC,  0x0A,  0xA4,  0x08,  0xFC,  0x7F,  0xA4,  0x0C,  0xFC,  0x1A,  0x20,  0x19,  0xFE,  0x29, 	/* 41980 */
+	0x22,  0x29,  0xFE,  0x49,  0x22,  0x09,  0xFE,  0x08,  0x21,  0x08,  0x1F,  0x97,  0x02,  0x10,  0x0C,  0x10, 	/* 41990 */
+	0x79,  0xFF,  0x08,  0x10,  0x08,  0xFE,  0x08,  0x92,  0x7E,  0xFE,  0x08,  0x92,  0x0C,  0xFE,  0x1A,  0x12, 	/* 419A0 */
+	0x1B,  0xFD,  0x28,  0x10,  0x28,  0xAA,  0x48,  0xA9,  0x09,  0x25,  0x08,  0x1C,  0xA1,  0x02,  0x10,  0x0C, 	/* 419B0 */
+	0x10,  0x79,  0xFF,  0x08,  0x94,  0x08,  0x94,  0x09,  0x5A,  0x7E,  0x11,  0x0B,  0xFF,  0x08,  0x00,  0x1D, 	/* 419C0 */
+	0xFE,  0x1B,  0x7A,  0x2B,  0x4A,  0x29,  0x7A,  0x49,  0x02,  0x09,  0xFE,  0x08,  0x00,  0xA2,  0x02,  0x20, 	/* 419D0 */
+	0x0C,  0xBE,  0x78,  0xA0,  0x0B,  0xFF,  0x08,  0x0A,  0x7E,  0x09,  0x09,  0xFF,  0x09,  0x08,  0x1D,  0xF9, 	/* 419E0 */
+	0x1B,  0x35,  0x29,  0x6E,  0x29,  0xB6,  0x49,  0x25,  0x0A,  0xCD,  0x0A,  0x13,  0x0C,  0x21,  0xA3,  0x02, 	/* 419F0 */
+	0x20,  0x0C,  0x20,  0x7B,  0xFF,  0x08,  0x48,  0x08,  0x84,  0x09,  0x4A,  0x7E,  0xFD,  0x08,  0x48,  0x1D, 	/* 41A00 */
+	0xFE,  0x1A,  0x48,  0x2B,  0xFF,  0x28,  0x52,  0x48,  0xD4,  0x0B,  0x48,  0x08,  0x64,  0x0B,  0x83,  0xA9, 	/* 41A10 */
+	0x02,  0x04,  0x0D,  0xF8,  0x78,  0xA4,  0x09,  0x12,  0x09,  0xFE,  0x7E,  0x20,  0x09,  0xFF,  0x08,  0x00, 	/* 41A20 */
+	0x1C,  0xFC,  0x1A,  0x04,  0x2B,  0xFE,  0x28,  0x04,  0x48,  0xFC,  0x09,  0x52,  0x09,  0x45,  0x0A,  0x3C, 	/* 41A30 */
+	0xAB,  0x02,  0x44,  0x05,  0xFF,  0x78,  0x48,  0x08,  0xFE,  0x08,  0x90,  0x09,  0xFE,  0x7E,  0x90,  0x08, 	/* 41A40 */
+	0xFE,  0x1C,  0x90,  0x1A,  0xFE,  0x2A,  0x00,  0x29,  0xFE,  0x48,  0x48,  0x08,  0x30,  0x08,  0x4C,  0x0B, 	/* 41A50 */
+	0x83,  0xB0,  0x02,  0x10,  0x0D,  0xFF,  0x78,  0x00,  0x08,  0xEE,  0x08,  0xAA,  0x08,  0xEE,  0x7F,  0x28, 	/* 41A60 */
+	0x08,  0xFE,  0x08,  0x28,  0x1C,  0xFE,  0x1A,  0x28,  0x2B,  0xFF,  0x28,  0x6A,  0x49,  0xA4,  0x08,  0x32, 	/* 41A70 */
+	0x09,  0xC1,  0xB4,  0x01,  0x00,  0x01,  0x00,  0x01,  0x00,  0x7F,  0xFE,  0x40,  0x02,  0x40,  0x02,  0x43, 	/* 41A80 */
+	0xE2,  0x00,  0x20,  0x04,  0x20,  0x04,  0x20,  0x04,  0x20,  0x08,  0x10,  0x08,  0x10,  0x10,  0x08,  0x20, 	/* 41A90 */
+	0x04,  0x40,  0x02,  0xB6,  0x01,  0x00,  0x01,  0x00,  0x7F,  0xFE,  0x44,  0x42,  0x44,  0x42,  0x04,  0x44, 	/* 41AA0 */
+	0x08,  0x3C,  0x11,  0x00,  0x21,  0x00,  0x1F,  0xE0,  0x01,  0x20,  0x02,  0x20,  0x02,  0x22,  0x04,  0x22, 	/* 41AB0 */
+	0x08,  0x22,  0x30,  0x1E,  0xB9,  0x00,  0x80,  0x00,  0x80,  0x7F,  0xFE,  0x42,  0x42,  0x44,  0x46,  0x18, 	/* 41AC0 */
+	0x3C,  0x60,  0x00,  0x0F,  0xF8,  0x00,  0x08,  0x0F,  0xF8,  0x08,  0x00,  0x0F,  0xFC,  0x00,  0x04,  0x00, 	/* 41AD0 */
+	0x04,  0x00,  0x04,  0x00,  0x38,  0xBA,  0x01,  0x00,  0x01,  0x00,  0x7F,  0xFE,  0x44,  0x42,  0x44,  0x42, 	/* 41AE0 */
+	0x04,  0x44,  0x08,  0x44,  0x10,  0x3C,  0x20,  0x00,  0x1F,  0xF8,  0x01,  0x00,  0x01,  0x00,  0x01,  0x00, 	/* 41AF0 */
+	0x01,  0x00,  0x7F,  0xFE,  0x00,  0x00,  0xBD,  0x01,  0x00,  0x01,  0x00,  0x7F,  0xFE,  0x42,  0x22,  0x44, 	/* 41B00 */
+	0x26,  0x18,  0x1C,  0x60,  0x00,  0x04,  0x20,  0x3F,  0xFE,  0x04,  0x20,  0x04,  0x20,  0x7F,  0xFF,  0x04, 	/* 41B10 */
+	0x20,  0x08,  0x20,  0x10,  0x20,  0x20,  0x20,  0xBF,  0x01,  0x00,  0x01,  0x00,  0x7F,  0xFE,  0x42,  0x42, 	/* 41B20 */
+	0x44,  0x46,  0x18,  0x3C,  0x60,  0x00,  0x3F,  0xFC,  0x04,  0x20,  0x04,  0x20,  0x7F,  0xFE,  0x00,  0xA0, 	/* 41B30 */
+	0x03,  0x20,  0x0C,  0x20,  0x70,  0x20,  0x00,  0x60,  0x81,  0x01,  0x00,  0x01,  0x00,  0x7F,  0xFE,  0x44, 	/* 41B40 */
+	0x42,  0x44,  0x42,  0x04,  0x44,  0x09,  0x3C,  0x11,  0x00,  0x21,  0x00,  0x7F,  0xFF,  0x01,  0x80,  0x01, 	/* 41B50 */
+	0x40,  0x02,  0x20,  0x04,  0x10,  0x18,  0x0C,  0x60,  0x03,  0x83,  0x01,  0x00,  0x01,  0x00,  0x7F,  0xFE, 	/* 41B60 */
+	0x42,  0x42,  0x42,  0x42,  0x04,  0x44,  0x18,  0x3C,  0x70,  0x00,  0x11,  0xFC,  0x1E,  0x44,  0x70,  0x44, 	/* 41B70 */
+	0x10,  0x44,  0x12,  0x84,  0x0E,  0x84,  0x01,  0x04,  0x06,  0x18,  0x84,  0x01,  0x00,  0x01,  0x00,  0x7F, 	/* 41B80 */
+	0xFE,  0x42,  0x42,  0x44,  0x42,  0x18,  0x44,  0x62,  0x3C,  0x02,  0x00,  0x07,  0xFE,  0x19,  0x00,  0x61, 	/* 41B90 */
+	0xFC,  0x01,  0x00,  0x01,  0xFC,  0x01,  0x00,  0x01,  0x00,  0x01,  0x00,  0x88,  0x01,  0x00,  0x01,  0x00, 	/* 41BA0 */
+	0x7F,  0xFE,  0x42,  0x42,  0x42,  0x44,  0x0C,  0x3C,  0x70,  0x10,  0x08,  0x10,  0x09,  0x7E,  0x09,  0x12, 	/* 41BB0 */
+	0x72,  0x12,  0x0C,  0x12,  0x0A,  0x22,  0x17,  0x22,  0x79,  0x42,  0x00,  0x8C,  0x92,  0x01,  0x00,  0x7F, 	/* 41BC0 */
+	0xFE,  0x42,  0x42,  0x42,  0x46,  0x04,  0x7C,  0x18,  0x00,  0x7F,  0xFE,  0x02,  0x40,  0x04,  0x30,  0x1F, 	/* 41BD0 */
+	0xE8,  0x01,  0x04,  0x1F,  0xF8,  0x01,  0x00,  0x01,  0x00,  0x7F,  0xFE,  0x00,  0x00,  0x93,  0x01,  0x00, 	/* 41BE0 */
+	0x01,  0x00,  0x7F,  0xFE,  0x44,  0x42,  0x44,  0x42,  0x09,  0x3E,  0x11,  0x00,  0x62,  0x60,  0x04,  0x18, 	/* 41BF0 */
+	0x1F,  0xE4,  0x01,  0x02,  0x12,  0x88,  0x12,  0x44,  0x22,  0x4A,  0x42,  0x0A,  0x01,  0xF8,  0x95,  0x01, 	/* 41C00 */
+	0x00,  0x01,  0x00,  0x7F,  0xFE,  0x42,  0x42,  0x44,  0x46,  0x18,  0x3C,  0x60,  0x00,  0x22,  0x44,  0x12, 	/* 41C10 */
+	0x48,  0x12,  0x50,  0x06,  0x40,  0x1A,  0x70,  0x62,  0x4C,  0x04,  0x41,  0x18,  0x41,  0x60,  0x3F,  0x96, 	/* 41C20 */
+	0x00,  0x80,  0x00,  0x80,  0x7F,  0xFE,  0x42,  0x42,  0x44,  0x46,  0x18,  0xBC,  0x68,  0x80,  0x0F,  0xF8, 	/* 41C30 */
+	0x10,  0x80,  0x20,  0x80,  0x7F,  0xFF,  0x00,  0x80,  0x0F,  0xF8,  0x08,  0x08,  0x0F,  0xF8,  0x00,  0x00, 	/* 41C40 */
+	0x97,  0x01,  0x00,  0x01,  0x00,  0x7F,  0xFE,  0x42,  0x42,  0x44,  0x46,  0x19,  0x3C,  0x62,  0x00,  0x3F, 	/* 41C50 */
+	0xFC,  0x21,  0x04,  0x25,  0xE4,  0x22,  0x44,  0x25,  0x84,  0x23,  0x44,  0x2C,  0x24,  0x3F,  0xFC,  0x20, 	/* 41C60 */
+	0x04,  0x98,  0x01,  0x00,  0x01,  0x00,  0x7F,  0xFE,  0x42,  0x42,  0x4C,  0x44,  0x70,  0x3C,  0x1F,  0xF8, 	/* 41C70 */
+	0x01,  0x08,  0x7F,  0xFF,  0x02,  0x08,  0x3F,  0xF8,  0x04,  0x00,  0x1F,  0xF8,  0x68,  0x08,  0x0F,  0xF8, 	/* 41C80 */
+	0x00,  0x00,  0x9F,  0x01,  0x00,  0x01,  0x00,  0x7F,  0xFE,  0x42,  0x42,  0x4C,  0x7C,  0x30,  0x00,  0x1F, 	/* 41C90 */
+	0xFC,  0x10,  0x04,  0x1F,  0xFC,  0x14,  0x48,  0x14,  0x48,  0x17,  0xF8,  0x28,  0x44,  0x28,  0x44,  0x4F, 	/* 41CA0 */
+	0xFC,  0x00,  0x00,  0xA9,  0x01,  0x00,  0x01,  0x00,  0x7F,  0xFE,  0x42,  0x42,  0x44,  0x46,  0x18,  0x3C, 	/* 41CB0 */
+	0x6F,  0xF0,  0x08,  0x10,  0x09,  0xF0,  0x09,  0x10,  0x3F,  0xFC,  0x20,  0x04,  0x27,  0xE4,  0x24,  0x24, 	/* 41CC0 */
+	0x27,  0xE4,  0x20,  0x0C,  0xAA,  0x01,  0x00,  0x01,  0x00,  0x7F,  0xFE,  0x42,  0x42,  0x44,  0x46,  0x38, 	/* 41CD0 */
+	0x3C,  0x00,  0x20,  0x31,  0xFC,  0x08,  0x20,  0x63,  0xFE,  0x10,  0x20,  0x00,  0x20,  0x09,  0xFC,  0x10, 	/* 41CE0 */
+	0x20,  0x27,  0xFF,  0x40,  0x00,  0xAE,  0x01,  0x00,  0x01,  0x00,  0x7F,  0xFE,  0x44,  0x42,  0x18,  0x7E, 	/* 41CF0 */
+	0x64,  0x00,  0x1F,  0x7C,  0x11,  0x04,  0x1F,  0x7C,  0x11,  0x40,  0x1F,  0x7C,  0x11,  0x04,  0x7F,  0x04, 	/* 41D00 */
+	0x05,  0x04,  0x19,  0x04,  0x63,  0x18,  0xAF,  0x01,  0x00,  0x7F,  0xFE,  0x44,  0x42,  0x04,  0x46,  0x18, 	/* 41D10 */
+	0x3C,  0x64,  0x20,  0x02,  0x40,  0x3F,  0xFE,  0x01,  0x00,  0x1F,  0xFC,  0x01,  0x00,  0x7F,  0xFF,  0x00, 	/* 41D20 */
+	0x00,  0x24,  0x48,  0x22,  0x24,  0x42,  0x22,  0xB0,  0x01,  0x00,  0x7F,  0xFE,  0x42,  0x42,  0x0C,  0x46, 	/* 41D30 */
+	0x71,  0x3C,  0x03,  0xF0,  0x3C,  0xA0,  0x03,  0xC0,  0x06,  0x00,  0x7B,  0xF8,  0x04,  0x80,  0x7F,  0xFF, 	/* 41D40 */
+	0x00,  0x80,  0x10,  0x84,  0x1F,  0xFC,  0x00,  0x00,  0xB6,  0x00,  0x80,  0x7F,  0xFE,  0x44,  0x22,  0x18, 	/* 41D50 */
+	0x9E,  0x6F,  0xF8,  0x08,  0x88,  0x7F,  0xFF,  0x08,  0x88,  0x0F,  0xF8,  0x04,  0x90,  0x07,  0xF0,  0x01, 	/* 41D60 */
+	0x00,  0x7F,  0xFF,  0x06,  0x10,  0x03,  0xE0,  0x3C,  0x18,  0xBA,  0x01,  0x00,  0x01,  0x00,  0x7F,  0xFE, 	/* 41D70 */
+	0x42,  0x42,  0x4C,  0x7E,  0x30,  0x00,  0x08,  0xFC,  0x3E,  0x84,  0x08,  0xFC,  0x08,  0x84,  0x7F,  0xFC, 	/* 41D80 */
+	0x08,  0x84,  0x14,  0xFC,  0x12,  0x29,  0x20,  0xC9,  0x43,  0x07,  0xBF,  0x01,  0x00,  0x7F,  0xFE,  0x42, 	/* 41D90 */
+	0x22,  0x0C,  0x1F,  0x70,  0x40,  0x3C,  0xFC,  0x27,  0x48,  0x24,  0x30,  0x2B,  0xFC,  0x28,  0xA3,  0x25, 	/* 41DA0 */
+	0xFC,  0x26,  0x20,  0x24,  0xF8,  0x2C,  0x20,  0x23,  0xFE,  0x20,  0x00,  0x83,  0x01,  0x00,  0x7F,  0xFE, 	/* 41DB0 */
+	0x49,  0x22,  0x17,  0xDE,  0x61,  0x00,  0x7F,  0xFE,  0x09,  0x10,  0x0F,  0xF0,  0x09,  0x10,  0x1F,  0xF8, 	/* 41DC0 */
+	0x11,  0x08,  0x1F,  0xF8,  0x11,  0x08,  0x1F,  0xFA,  0x01,  0x02,  0x00,  0xFE,  0x84,  0x00,  0x80,  0x7F, 	/* 41DD0 */
+	0xFE,  0x42,  0x42,  0x1C,  0x3E,  0x61,  0x00,  0x3C,  0xF8,  0x20,  0x08,  0x3E,  0xF8,  0x20,  0x08,  0x3F, 	/* 41DE0 */
+	0xF8,  0x11,  0x10,  0x1D,  0xD0,  0x11,  0x0A,  0x1D,  0xCA,  0x11,  0x36,  0x7B,  0xC2,  0x85,  0x00,  0x80, 	/* 41DF0 */
+	0x7F,  0xFE,  0x42,  0x42,  0x1C,  0x24,  0x64,  0x1C,  0x1F,  0x20,  0x11,  0x3F,  0x1F,  0x24,  0x11,  0x44, 	/* 41E00 */
+	0x1F,  0xA4,  0x08,  0x24,  0x7F,  0x98,  0x08,  0x08,  0x0F,  0x14,  0x11,  0x22,  0x26,  0xC1,  0x87,  0x00, 	/* 41E10 */
+	0x80,  0x7F,  0xFE,  0x42,  0x42,  0x0C,  0x3F,  0x70,  0x80,  0x7F,  0xFF,  0x00,  0x80,  0x3F,  0xFE,  0x22, 	/* 41E20 */
+	0x22,  0x3F,  0xFE,  0x08,  0x08,  0x0F,  0xF8,  0x08,  0x08,  0x0F,  0xF8,  0x06,  0x18,  0x78,  0x06,  0x88, 	/* 41E30 */
+	0x00,  0x80,  0x7F,  0xFE,  0x48,  0x92,  0x17,  0xEF,  0x60,  0x80,  0x7F,  0xFF,  0x11,  0x44,  0x1F,  0x7C, 	/* 41E40 */
+	0x01,  0x40,  0x3F,  0x7E,  0x21,  0x42,  0x3F,  0x7E,  0x21,  0x42,  0x3F,  0x7E,  0x01,  0x01,  0x00,  0xFF, 	/* 41E50 */
+	0x8A,  0x01,  0x00,  0x7F,  0xFE,  0x42,  0x42,  0x0C,  0x7F,  0x70,  0x10,  0x02,  0x1E,  0x3D,  0x10,  0x49, 	/* 41E60 */
+	0x7C,  0x2A,  0x54,  0x28,  0x6C,  0x7F,  0x44,  0x1C,  0xFE,  0x1A,  0x92,  0x29,  0xAA,  0x48,  0xF6,  0x08, 	/* 41E70 */
+	0x86,  0x8B,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x3F,  0xFE,  0x00,  0x10,  0x08,  0x10,  0x08,  0x10, 	/* 41E80 */
+	0x04,  0x10,  0x04,  0x10,  0x04,  0x20,  0x02,  0x20,  0x02,  0x20,  0x02,  0x40,  0x00,  0x40,  0x7F,  0xFF, 	/* 41E90 */
+	0x00,  0x00,  0x8D,  0x08,  0x10,  0x08,  0x10,  0x08,  0x10,  0x7F,  0x90,  0x02,  0x10,  0x22,  0x10,  0x13, 	/* 41EA0 */
+	0xFF,  0x12,  0x10,  0x14,  0x10,  0x14,  0x10,  0x14,  0x10,  0x0B,  0x10,  0x0C,  0x10,  0x70,  0x10,  0x00, 	/* 41EB0 */
+	0x10,  0x00,  0x10,  0x8F,  0x08,  0x02,  0x08,  0x0C,  0x08,  0xF0,  0x7F,  0x10,  0x02,  0x10,  0x22,  0x10, 	/* 41EC0 */
+	0x12,  0x10,  0x13,  0xFF,  0x14,  0x10,  0x14,  0x10,  0x14,  0x10,  0x0B,  0x10,  0x0C,  0x10,  0x70,  0x10, 	/* 41ED0 */
+	0x00,  0x10,  0x00,  0x10,  0x92,  0x00,  0x80,  0x00,  0x80,  0x1F,  0xFC,  0x04,  0x10,  0x02,  0x10,  0x02, 	/* 41EE0 */
+	0x20,  0x7F,  0xFF,  0x00,  0x08,  0x0F,  0xC8,  0x08,  0x48,  0x08,  0x48,  0x08,  0x48,  0x0F,  0xC8,  0x00, 	/* 41EF0 */
+	0x08,  0x00,  0x08,  0x00,  0x18,  0x93,  0x08,  0x02,  0x08,  0x0C,  0x08,  0xF0,  0x7E,  0x20,  0x00,  0x20, 	/* 41F00 */
+	0x44,  0x3E,  0x25,  0xE0,  0x24,  0x20,  0x24,  0x20,  0x28,  0x3F,  0x09,  0xE0,  0x16,  0x20,  0x18,  0x20, 	/* 41F10 */
+	0x60,  0x21,  0x00,  0x21,  0x00,  0x1F,  0x95,  0x08,  0x78,  0x08,  0x08,  0x08,  0x48,  0x7E,  0x48,  0x00, 	/* 41F20 */
+	0x84,  0x44,  0x84,  0x27,  0x02,  0x24,  0xFD,  0x24,  0x24,  0x28,  0x24,  0x08,  0x24,  0x16,  0x24,  0x18, 	/* 41F30 */
+	0x44,  0x60,  0x44,  0x00,  0x84,  0x01,  0x18,  0x99,  0x08,  0x20,  0x08,  0x20,  0x08,  0x20,  0x7F,  0x20, 	/* 41F40 */
+	0x02,  0x3F,  0x22,  0x20,  0x12,  0x20,  0x12,  0x20,  0x14,  0x20,  0x14,  0xFC,  0x14,  0x84,  0x0B,  0x84, 	/* 41F50 */
+	0x0C,  0x84,  0x70,  0x84,  0x00,  0xFC,  0x00,  0x00,  0x9A,  0x08,  0x10,  0x08,  0x10,  0x08,  0xFF,  0x7F, 	/* 41F60 */
+	0x81,  0x02,  0x81,  0x22,  0x00,  0x13,  0xFF,  0x12,  0x10,  0x12,  0x10,  0x14,  0x10,  0x14,  0x10,  0x0B, 	/* 41F70 */
+	0x10,  0x0C,  0x10,  0x70,  0x10,  0x00,  0x10,  0x00,  0x30,  0x9C,  0x00,  0x80,  0x00,  0x80,  0x1F,  0xFC, 	/* 41F80 */
+	0x04,  0x10,  0x02,  0x20,  0x7F,  0xFF,  0x00,  0x00,  0x0F,  0xF8,  0x08,  0x88,  0x08,  0x88,  0x0F,  0xF8, 	/* 41F90 */
+	0x08,  0x88,  0x08,  0x88,  0x0F,  0xFA,  0x00,  0x82,  0x00,  0x7E,  0x9D,  0x08,  0x10,  0x08,  0x10,  0x08, 	/* 41FA0 */
+	0x10,  0x7F,  0xFE,  0x02,  0x04,  0x22,  0x84,  0x12,  0x84,  0x12,  0x44,  0x12,  0x44,  0x14,  0x48,  0x14, 	/* 41FB0 */
+	0x48,  0x0B,  0x48,  0x0C,  0x50,  0x70,  0x10,  0x01,  0xFF,  0x00,  0x00,  0x9F,  0x00,  0x80,  0x00,  0x80, 	/* 41FC0 */
+	0x1F,  0xFC,  0x04,  0x10,  0x02,  0x20,  0x7F,  0xFF,  0x00,  0x00,  0x0F,  0xF8,  0x08,  0x08,  0x0F,  0xF8, 	/* 41FD0 */
+	0x08,  0x08,  0x0F,  0xF8,  0x01,  0x21,  0x02,  0x21,  0x0C,  0x21,  0x70,  0x1F,  0xA0,  0x00,  0x80,  0x00, 	/* 41FE0 */
+	0x80,  0x3F,  0xFE,  0x04,  0x10,  0x02,  0x20,  0x7F,  0xFF,  0x00,  0x00,  0x0F,  0xF8,  0x08,  0x08,  0x0F, 	/* 41FF0 */
+	0xF8,  0x08,  0x08,  0x0F,  0xF8,  0x00,  0x80,  0x7F,  0xFF,  0x00,  0x80,  0x00,  0x80,  0xA1,  0x08,  0x00, 	/* 42000 */
+	0x09,  0xFF,  0x08,  0x10,  0x7F,  0x10,  0x02,  0x20,  0x22,  0x7E,  0x12,  0x42,  0x12,  0x42,  0x12,  0x42, 	/* 42010 */
+	0x14,  0x42,  0x14,  0x7E,  0x0B,  0x42,  0x0C,  0x42,  0x70,  0x42,  0x00,  0x7E,  0x00,  0x00,  0xA2,  0x08, 	/* 42020 */
+	0x20,  0x08,  0x28,  0x08,  0x24,  0x7F,  0x4E,  0x02,  0xF1,  0x22,  0x40,  0x12,  0x40,  0x12,  0x7E,  0x12, 	/* 42030 */
+	0x90,  0x15,  0x10,  0x14,  0xFF,  0x0B,  0x10,  0x0C,  0x18,  0x70,  0x24,  0x00,  0xC2,  0x03,  0x01,  0xA3, 	/* 42040 */
+	0x08,  0x20,  0x08,  0x28,  0x08,  0x44,  0x7F,  0xFA,  0x00,  0x48,  0x24,  0x49,  0x24,  0xA7,  0x15,  0x20, 	/* 42050 */
+	0x14,  0x7C,  0x14,  0x44,  0x08,  0x88,  0x0F,  0x50,  0x18,  0x20,  0x60,  0x50,  0x01,  0x8C,  0x06,  0x03, 	/* 42060 */
+	0xA5,  0x00,  0x80,  0x3F,  0xFE,  0x04,  0x10,  0x02,  0x20,  0x7F,  0xFF,  0x00,  0x00,  0x0F,  0xF8,  0x08, 	/* 42070 */
+	0x88,  0x0F,  0xF8,  0x08,  0x88,  0x0F,  0xF8,  0x00,  0x80,  0x1F,  0xFC,  0x00,  0x80,  0x7F,  0xFF,  0x00, 	/* 42080 */
+	0x00,  0xA6,  0x08,  0x10,  0x08,  0x10,  0x09,  0xFF,  0x7F,  0x10,  0x02,  0x10,  0x22,  0xFE,  0x12,  0x92, 	/* 42090 */
+	0x12,  0x92,  0x14,  0x92,  0x14,  0xFE,  0x08,  0x38,  0x0E,  0x54,  0x18,  0x92,  0x63,  0x11,  0x00,  0x10, 	/* 420A0 */
+	0x00,  0x10,  0xAA,  0x00,  0x00,  0x3F,  0x7C,  0x24,  0x04,  0x3F,  0x44,  0x21,  0x28,  0x3F,  0x28,  0x24, 	/* 420B0 */
+	0x10,  0x3F,  0x28,  0x20,  0xC6,  0x00,  0x80,  0x3F,  0xFE,  0x04,  0x10,  0x02,  0x10,  0x02,  0x20,  0x7F, 	/* 420C0 */
+	0xFF,  0x00,  0x00,  0xAD,  0x08,  0x00,  0x08,  0xFC,  0x08,  0x84,  0x7E,  0xFC,  0x00,  0x84,  0x44,  0x84, 	/* 420D0 */
+	0x24,  0xFC,  0x24,  0x40,  0x24,  0x7E,  0x28,  0x92,  0x09,  0x9A,  0x16,  0xAA,  0x18,  0xC2,  0x60,  0xFA, 	/* 420E0 */
+	0x00,  0x02,  0x00,  0x0C,  0xAF,  0x00,  0x10,  0x08,  0x92,  0x08,  0x92,  0x08,  0x92,  0x08,  0xFE,  0x7F, 	/* 420F0 */
+	0x00,  0x05,  0xFF,  0x44,  0x20,  0x24,  0x40,  0x29,  0xFE,  0x29,  0x4A,  0x0B,  0x4A,  0x0D,  0x4A,  0x71, 	/* 42100 */
+	0x4A,  0x01,  0x4A,  0x01,  0x06,  0xB0,  0x08,  0x00,  0x09,  0xFF,  0x09,  0x00,  0x7F,  0x7E,  0x01,  0x52, 	/* 42110 */
+	0x45,  0x52,  0x25,  0x7E,  0x25,  0x52,  0x25,  0x7E,  0x29,  0x10,  0x09,  0x10,  0x15,  0xFE,  0x1A,  0x10, 	/* 42120 */
+	0x62,  0x10,  0x05,  0xFF,  0x00,  0x00,  0xB6,  0x04,  0x10,  0x04,  0x10,  0x3F,  0xFE,  0x11,  0x44,  0x0A, 	/* 42130 */
+	0x28,  0x7F,  0xFF,  0x00,  0x00,  0x1F,  0x7C,  0x11,  0x44,  0x11,  0x44,  0x1F,  0x7C,  0x0A,  0x28,  0x0A, 	/* 42140 */
+	0x28,  0x12,  0xA9,  0x23,  0x49,  0x42,  0x87,  0xB8,  0x08,  0x10,  0x3F,  0x7E,  0x12,  0x24,  0x12,  0x24, 	/* 42150 */
+	0x7F,  0xFF,  0x00,  0x00,  0x3E,  0x7C,  0x22,  0x44,  0x3E,  0x7C,  0x22,  0x44,  0x3E,  0x7C,  0x14,  0x28, 	/* 42160 */
+	0x15,  0x28,  0x16,  0x49,  0x2C,  0x89,  0x43,  0x07,  0xB9,  0x08,  0x20,  0x08,  0x20,  0x08,  0x20,  0x0F, 	/* 42170 */
+	0xFF,  0x14,  0x48,  0x14,  0x48,  0x24,  0x88,  0x44,  0x08,  0x04,  0x08,  0x04,  0x08,  0x04,  0x08,  0x04, 	/* 42180 */
+	0x08,  0x04,  0x08,  0x04,  0x08,  0x04,  0x08,  0x04,  0x18,  0xBA,  0x08,  0x10,  0x08,  0x10,  0x08,  0x10, 	/* 42190 */
+	0x0F,  0xBF,  0x14,  0x28,  0x12,  0x24,  0x22,  0x44,  0x40,  0x00,  0x00,  0x00,  0x1F,  0xF8,  0x00,  0x00, 	/* 421A0 */
+	0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x7F,  0xFF,  0x00,  0x00,  0xBF,  0x08,  0x20,  0x08,  0x20,  0x1F, 	/* 421B0 */
+	0xBF,  0x24,  0x48,  0x42,  0x84,  0x00,  0x00,  0x1F,  0xFC,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x7F, 	/* 421C0 */
+	0xFF,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x82,  0x08,  0x20,  0x08,  0x20, 	/* 421D0 */
+	0x1F,  0x7F,  0x14,  0x48,  0x22,  0x84,  0x41,  0x00,  0x01,  0x00,  0x7F,  0xF8,  0x01,  0x08,  0x01,  0x08, 	/* 421E0 */
+	0x19,  0x08,  0x06,  0x08,  0x03,  0x08,  0x04,  0x89,  0x18,  0x49,  0x60,  0x07,  0x84,  0x08,  0x20,  0x08, 	/* 421F0 */
+	0x20,  0x1F,  0x7F,  0x14,  0x50,  0x22,  0x88,  0x40,  0x00,  0x1F,  0xFE,  0x02,  0x10,  0x02,  0x10,  0x02, 	/* 42200 */
+	0x10,  0x7F,  0xFF,  0x02,  0x10,  0x04,  0x10,  0x04,  0x10,  0x08,  0x10,  0x10,  0x10,  0x86,  0x08,  0x20, 	/* 42210 */
+	0x08,  0x20,  0x1F,  0x7F,  0x14,  0x48,  0x22,  0x84,  0x42,  0x04,  0x1F,  0xFC,  0x10,  0x84,  0x10,  0x84, 	/* 42220 */
+	0x10,  0x84,  0x1F,  0xFC,  0x10,  0x00,  0x10,  0x02,  0x10,  0x02,  0x08,  0x02,  0x07,  0xFE,  0x88,  0x08, 	/* 42230 */
+	0x20,  0x08,  0x20,  0x1F,  0xBF,  0x14,  0x50,  0x22,  0x88,  0x40,  0x00,  0x3F,  0xF0,  0x02,  0x20,  0x02, 	/* 42240 */
+	0x78,  0x03,  0x08,  0x04,  0x90,  0x04,  0x60,  0x08,  0x60,  0x11,  0x90,  0x26,  0x0C,  0x58,  0x03,  0x8A, 	/* 42250 */
+	0x08,  0x20,  0x08,  0x20,  0x1F,  0x7F,  0x14,  0x50,  0x22,  0x88,  0x40,  0x06,  0x00,  0x78,  0x0F,  0x88, 	/* 42260 */
+	0x08,  0x08,  0x08,  0x88,  0x08,  0x88,  0x08,  0x88,  0x08,  0x84,  0x10,  0x84,  0x20,  0x82,  0x40,  0x01, 	/* 42270 */
+	0x8B,  0x08,  0x20,  0x08,  0x20,  0x1F,  0x7F,  0x14,  0x50,  0x22,  0x88,  0x40,  0x00,  0x1F,  0xFC,  0x00, 	/* 42280 */
+	0x84,  0x7F,  0xFF,  0x00,  0x84,  0x00,  0x84,  0x1F,  0xFC,  0x00,  0x80,  0x01,  0x00,  0x06,  0x00,  0x18, 	/* 42290 */
+	0x00,  0x8F,  0x08,  0x20,  0x08,  0x20,  0x1F,  0x7F,  0x14,  0x50,  0x22,  0x88,  0x44,  0x00,  0x04,  0x00, 	/* 422A0 */
+	0x07,  0xFE,  0x09,  0x12,  0x11,  0x12,  0x22,  0x22,  0x44,  0x22,  0x08,  0x42,  0x10,  0x82,  0x01,  0x04, 	/* 422B0 */
+	0x00,  0x18,  0x91,  0x08,  0x20,  0x08,  0x20,  0x0F,  0x7F,  0x14,  0x48,  0x22,  0x84,  0x40,  0x10,  0x00, 	/* 422C0 */
+	0x60,  0x1F,  0x80,  0x00,  0x80,  0x00,  0x80,  0x7F,  0xFF,  0x01,  0x40,  0x02,  0x20,  0x04,  0x10,  0x18, 	/* 422D0 */
+	0x0C,  0x60,  0x03,  0x98,  0x08,  0x20,  0x08,  0x20,  0x1F,  0x7F,  0x14,  0x50,  0x22,  0x88,  0x43,  0x08, 	/* 422E0 */
+	0x01,  0x00,  0x01,  0xFE,  0x01,  0x00,  0x01,  0x00,  0x1F,  0xF8,  0x10,  0x08,  0x10,  0x08,  0x10,  0x08, 	/* 422F0 */
+	0x1F,  0xF8,  0x00,  0x00,  0x99,  0x08,  0x20,  0x08,  0x20,  0x1F,  0x7F,  0x14,  0x48,  0x22,  0x84,  0x42, 	/* 42300 */
+	0x04,  0x08,  0x80,  0x08,  0x80,  0x1F,  0xFC,  0x10,  0x80,  0x20,  0x80,  0x0F,  0xFC,  0x00,  0x80,  0x00, 	/* 42310 */
+	0x80,  0x7F,  0xFF,  0x00,  0x00,  0x9B,  0x10,  0x20,  0x10,  0x20,  0x1F,  0xBF,  0x14,  0x50,  0x22,  0x88, 	/* 42320 */
+	0x23,  0x08,  0x41,  0x00,  0x1F,  0xF8,  0x11,  0x08,  0x11,  0x08,  0x1F,  0xF8,  0x11,  0x08,  0x11,  0x08, 	/* 42330 */
+	0x11,  0x08,  0x1F,  0xF8,  0x00,  0x00,  0x9E,  0x08,  0x20,  0x08,  0x20,  0x1F,  0x7F,  0x14,  0x48,  0x22, 	/* 42340 */
+	0x84,  0x41,  0x00,  0x01,  0x10,  0x02,  0x08,  0x04,  0xFC,  0x7F,  0x02,  0x00,  0x02,  0x1F,  0xF8,  0x10, 	/* 42350 */
+	0x08,  0x10,  0x08,  0x1F,  0xF8,  0x00,  0x00,  0xA0,  0x08,  0x10,  0x08,  0x10,  0x1F,  0xBF,  0x24,  0x28, 	/* 42360 */
+	0x42,  0x44,  0x02,  0x84,  0x00,  0x80,  0x3F,  0xFE,  0x00,  0x08,  0x08,  0x08,  0x04,  0x10,  0x02,  0x10, 	/* 42370 */
+	0x02,  0x20,  0x00,  0x40,  0x7F,  0xFF,  0x00,  0x00,  0xA5,  0x08,  0x20,  0x08,  0x20,  0x0F,  0xBF,  0x14, 	/* 42380 */
+	0x48,  0x22,  0x44,  0x40,  0x80,  0x7F,  0xFC,  0x00,  0x04,  0x1F,  0xF4,  0x00,  0x04,  0x0F,  0xE4,  0x08, 	/* 42390 */
+	0x24,  0x08,  0x24,  0x0F,  0xE4,  0x00,  0x04,  0x00,  0x38,  0xA6,  0x08,  0x20,  0x08,  0x20,  0x1F,  0x7F, 	/* 423A0 */
+	0x14,  0x50,  0x22,  0x88,  0x45,  0x00,  0x04,  0x08,  0x08,  0x08,  0x0B,  0xFF,  0x18,  0x08,  0x29,  0x08, 	/* 423B0 */
+	0x48,  0x88,  0x08,  0x88,  0x08,  0x08,  0x08,  0x08,  0x08,  0x18,  0xA8,  0x08,  0x20,  0x08,  0x20,  0x1F, 	/* 423C0 */
+	0x7F,  0x14,  0x48,  0x22,  0x84,  0x42,  0x84,  0x00,  0x80,  0x7F,  0xFF,  0x01,  0xC0,  0x02,  0xA0,  0x04, 	/* 423D0 */
+	0x90,  0x18,  0x8C,  0x67,  0xF3,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0xAC,  0x10,  0x20,  0x10,  0x20, 	/* 423E0 */
+	0x1F,  0xBF,  0x24,  0x50,  0x42,  0x88,  0x3F,  0xFC,  0x00,  0x84,  0x00,  0x84,  0x1F,  0xFC,  0x10,  0x80, 	/* 423F0 */
+	0x1F,  0xFE,  0x01,  0x82,  0x02,  0x82,  0x0C,  0x84,  0x70,  0x98,  0x00,  0x80,  0xB3,  0x08,  0x20,  0x08, 	/* 42400 */
+	0x20,  0x1F,  0x7F,  0x14,  0x50,  0x22,  0x88,  0x44,  0x08,  0x04,  0x00,  0x3F,  0xBE,  0x04,  0xA2,  0x04, 	/* 42410 */
+	0xA2,  0x04,  0xA2,  0x08,  0xA2,  0x08,  0xA2,  0x10,  0xA2,  0x21,  0x3E,  0x46,  0x00,  0xB5,  0x08,  0x20, 	/* 42420 */
+	0x08,  0x20,  0x1F,  0x7F,  0x14,  0x48,  0x22,  0x84,  0x42,  0x04,  0x08,  0x00,  0x04,  0xFC,  0x44,  0x84, 	/* 42430 */
+	0x20,  0x84,  0x20,  0x84,  0x08,  0x98,  0x08,  0x81,  0x10,  0x81,  0x20,  0x81,  0x40,  0x7F,  0xB6,  0x08, 	/* 42440 */
+	0x20,  0x08,  0x20,  0x1F,  0x7F,  0x14,  0x48,  0x22,  0x84,  0x42,  0x04,  0x04,  0x00,  0x07,  0xF8,  0x08, 	/* 42450 */
+	0x80,  0x10,  0x80,  0x7F,  0xFF,  0x01,  0x40,  0x02,  0x20,  0x04,  0x10,  0x18,  0x0C,  0x60,  0x03,  0xB9, 	/* 42460 */
+	0x08,  0x20,  0x08,  0x20,  0x1F,  0xBF,  0x14,  0x48,  0x22,  0x84,  0x42,  0x04,  0x08,  0x88,  0x08,  0x88, 	/* 42470 */
+	0x7F,  0xFF,  0x08,  0x88,  0x08,  0x88,  0x08,  0xF8,  0x08,  0x00,  0x08,  0x00,  0x0F,  0xFE,  0x00,  0x00, 	/* 42480 */
+	0x85,  0x08,  0x20,  0x08,  0x20,  0x1F,  0x7F,  0x14,  0x48,  0x22,  0x84,  0x44,  0x80,  0x07,  0xF8,  0x08, 	/* 42490 */
+	0x80,  0x10,  0x80,  0x7F,  0xFF,  0x02,  0x40,  0x02,  0x40,  0x02,  0x40,  0x04,  0x42,  0x18,  0x42,  0x60, 	/* 424A0 */
+	0x3E,  0x86,  0x10,  0x20,  0x10,  0x20,  0x1F,  0x7E,  0x28,  0x90,  0x44,  0x88,  0x1F,  0xF8,  0x00,  0x88, 	/* 424B0 */
+	0x7F,  0xFF,  0x00,  0x88,  0x1F,  0xF8,  0x00,  0x80,  0x1F,  0xF8,  0x00,  0x80,  0x7F,  0xFE,  0x00,  0x80, 	/* 424C0 */
+	0x00,  0x80,  0x88,  0x08,  0x20,  0x08,  0x20,  0x0F,  0x7F,  0x14,  0x50,  0x22,  0x88,  0x40,  0x34,  0x0F, 	/* 424D0 */
+	0xC0,  0x00,  0x80,  0x7F,  0xFF,  0x00,  0x80,  0x00,  0x80,  0x0F,  0xF8,  0x08,  0x08,  0x08,  0x08,  0x0F, 	/* 424E0 */
+	0xF8,  0x00,  0x00,  0x89,  0x10,  0x20,  0x10,  0x20,  0x1F,  0x7F,  0x28,  0x88,  0x44,  0x84,  0x1F,  0xFC, 	/* 424F0 */
+	0x00,  0x80,  0x00,  0x80,  0x3F,  0xFE,  0x00,  0x10,  0x00,  0x10,  0x7F,  0xFF,  0x04,  0x10,  0x02,  0x10, 	/* 42500 */
+	0x02,  0x10,  0x00,  0x30,  0x8B,  0x10,  0x20,  0x10,  0x20,  0x1F,  0x3F,  0x24,  0x48,  0x22,  0x44,  0x40, 	/* 42510 */
+	0xA0,  0x1E,  0x20,  0x12,  0xFE,  0x12,  0x22,  0x1E,  0x22,  0x12,  0x22,  0x12,  0x22,  0x1E,  0x42,  0x22, 	/* 42520 */
+	0x42,  0x22,  0x82,  0x47,  0x0C,  0x8C,  0x08,  0x20,  0x08,  0x20,  0x1F,  0x7F,  0x14,  0x48,  0x22,  0x84, 	/* 42530 */
+	0x40,  0x80,  0x01,  0x40,  0x06,  0x30,  0x18,  0x0C,  0x6F,  0xFB,  0x00,  0x80,  0x0F,  0xF8,  0x00,  0x80, 	/* 42540 */
+	0x00,  0x80,  0x3F,  0xFE,  0x00,  0x00,  0x8D,  0x08,  0x20,  0x08,  0x20,  0x1F,  0x7F,  0x14,  0x48,  0x22, 	/* 42550 */
+	0x84,  0x4A,  0x04,  0x08,  0x00,  0x1F,  0xFE,  0x10,  0x02,  0x27,  0xE2,  0x44,  0x22,  0x07,  0xE2,  0x04, 	/* 42560 */
+	0x22,  0x04,  0x22,  0x07,  0xE2,  0x00,  0x0C,  0x8F,  0x08,  0x10,  0x08,  0x10,  0x1F,  0xBF,  0x14,  0x28, 	/* 42570 */
+	0x22,  0x44,  0x44,  0x48,  0x04,  0x44,  0x08,  0x44,  0x13,  0xFF,  0x30,  0x20,  0x50,  0x22,  0x10,  0x14, 	/* 42580 */
+	0x10,  0x18,  0x10,  0x69,  0x13,  0x85,  0x10,  0x03,  0x90,  0x08,  0x20,  0x08,  0x20,  0x1F,  0x7F,  0x14, 	/* 42590 */
+	0x48,  0x22,  0x84,  0x5F,  0xFE,  0x10,  0x00,  0x17,  0xFE,  0x10,  0x40,  0x13,  0xFC,  0x10,  0x40,  0x10, 	/* 425A0 */
+	0x40,  0x17,  0xFE,  0x10,  0x00,  0x1F,  0xFF,  0x00,  0x00,  0x91,  0x10,  0x20,  0x10,  0x20,  0x1F,  0x7F, 	/* 425B0 */
+	0x24,  0x48,  0x22,  0x84,  0x42,  0x04,  0x00,  0x00,  0x3E,  0x7C,  0x08,  0x44,  0x08,  0x64,  0x08,  0x54, 	/* 425C0 */
+	0x08,  0x54,  0x0E,  0x84,  0x18,  0x85,  0x61,  0x05,  0x02,  0x03,  0x92,  0x10,  0x20,  0x10,  0x20,  0x3F, 	/* 425D0 */
+	0x7E,  0x28,  0x90,  0x45,  0x08,  0x3F,  0xFC,  0x20,  0x04,  0x2F,  0xF4,  0x20,  0x04,  0x27,  0xE4,  0x24, 	/* 425E0 */
+	0x24,  0x24,  0x24,  0x27,  0xE4,  0x20,  0x04,  0x20,  0x04,  0x20,  0x0C,  0x94,  0x08,  0x20,  0x08,  0x20, 	/* 425F0 */
+	0x0F,  0x3F,  0x14,  0x50,  0x22,  0x88,  0x41,  0x40,  0x02,  0x20,  0x04,  0x10,  0x1F,  0xFC,  0x60,  0x03, 	/* 42600 */
+	0x00,  0x00,  0x0F,  0xF8,  0x08,  0x08,  0x08,  0x08,  0x0F,  0xF8,  0x00,  0x00,  0x96,  0x08,  0x10,  0x08, 	/* 42610 */
+	0x10,  0x1F,  0xBF,  0x14,  0x28,  0x22,  0x44,  0x40,  0x80,  0x7F,  0xFF,  0x00,  0x80,  0x1F,  0xFC,  0x10, 	/* 42620 */
+	0x84,  0x11,  0xC4,  0x12,  0xAC,  0x04,  0x90,  0x18,  0x8C,  0x60,  0x83,  0x00,  0x80,  0x9D,  0x08,  0x20, 	/* 42630 */
+	0x08,  0x20,  0x1F,  0x7F,  0x14,  0x88,  0x21,  0x04,  0x43,  0xF0,  0x0C,  0x20,  0x37,  0xFC,  0x00,  0x84, 	/* 42640 */
+	0x7F,  0xFF,  0x00,  0x84,  0x00,  0x84,  0x1F,  0xFC,  0x00,  0x80,  0x00,  0x80,  0x01,  0x80,  0xA5,  0x08, 	/* 42650 */
+	0x20,  0x08,  0x20,  0x1F,  0x7F,  0x14,  0x48,  0x22,  0x84,  0x4F,  0xF8,  0x08,  0x08,  0x08,  0x08,  0x0F, 	/* 42660 */
+	0xF8,  0x00,  0x80,  0x01,  0x00,  0x1F,  0xFC,  0x10,  0x04,  0x10,  0x04,  0x1F,  0xFC,  0x00,  0x00,  0xA7, 	/* 42670 */
+	0x08,  0x20,  0x08,  0x20,  0x1F,  0x7F,  0x14,  0x50,  0x22,  0x88,  0x4F,  0xF8,  0x08,  0x08,  0x0F,  0xF8, 	/* 42680 */
+	0x08,  0x08,  0x0F,  0xF8,  0x08,  0x08,  0x0F,  0xF8,  0x01,  0x21,  0x02,  0x21,  0x0C,  0x21,  0x70,  0x1F, 	/* 42690 */
+	0xAC,  0x08,  0x20,  0x08,  0x20,  0x1F,  0x7F,  0x14,  0x48,  0x22,  0xA4,  0x40,  0x28,  0x00,  0x24,  0x1F, 	/* 426A0 */
+	0xFF,  0x10,  0x20,  0x10,  0x24,  0x1F,  0x24,  0x11,  0x18,  0x11,  0x11,  0x21,  0x29,  0x26,  0x47,  0x40, 	/* 426B0 */
+	0x81,  0xAE,  0x08,  0x20,  0x08,  0x20,  0x1F,  0x7F,  0x14,  0x48,  0x22,  0x84,  0x40,  0x00,  0x3F,  0xFE, 	/* 426C0 */
+	0x08,  0x88,  0x08,  0x88,  0x08,  0x88,  0x0C,  0x8C,  0x12,  0x92,  0x20,  0xA0,  0x00,  0x80,  0x7F,  0xFF, 	/* 426D0 */
+	0x00,  0x00,  0xB0,  0x08,  0x10,  0x08,  0x10,  0x1F,  0xBF,  0x14,  0x28,  0x22,  0x44,  0x44,  0x40,  0x04, 	/* 426E0 */
+	0x40,  0x08,  0x7F,  0x18,  0xA0,  0x29,  0x20,  0x4A,  0x3E,  0x08,  0x20,  0x08,  0x20,  0x08,  0x3E,  0x08, 	/* 426F0 */
+	0x20,  0x08,  0x20,  0xB1,  0x08,  0x20,  0x08,  0x20,  0x1F,  0x7F,  0x14,  0x48,  0x22,  0x84,  0x44,  0x20, 	/* 42700 */
+	0x04,  0x20,  0x09,  0x3F,  0x09,  0x44,  0x19,  0x64,  0x29,  0xA4,  0x49,  0x14,  0x09,  0x08,  0x09,  0x14, 	/* 42710 */
+	0x08,  0x62,  0x09,  0x81,  0xB4,  0x08,  0x20,  0x08,  0x20,  0x1F,  0x7F,  0x14,  0x48,  0x22,  0x84,  0x40, 	/* 42720 */
+	0x80,  0x3F,  0xFE,  0x08,  0x88,  0x08,  0x88,  0x08,  0x88,  0x15,  0x54,  0x13,  0x62,  0x22,  0x20,  0x04, 	/* 42730 */
+	0x10,  0x18,  0x0C,  0x60,  0x03,  0xB5,  0x08,  0x20,  0x08,  0x20,  0x1F,  0x7F,  0x14,  0x50,  0x22,  0x88, 	/* 42740 */
+	0x40,  0x02,  0x7E,  0x0C,  0x05,  0xF0,  0x08,  0x10,  0x1C,  0x9E,  0x04,  0x90,  0x24,  0x90,  0x14,  0x90, 	/* 42750 */
+	0x08,  0xFE,  0x16,  0x00,  0x61,  0xFF,  0xBA,  0x08,  0x20,  0x08,  0x20,  0x1F,  0x7F,  0x14,  0x48,  0x22, 	/* 42760 */
+	0x84,  0x7F,  0xFE,  0x20,  0x00,  0x27,  0xFC,  0x20,  0x40,  0x23,  0xF8,  0x20,  0x50,  0x20,  0x48,  0x2F, 	/* 42770 */
+	0xFE,  0x20,  0x00,  0x3F,  0xFE,  0x00,  0x00,  0x86,  0x10,  0x20,  0x10,  0x20,  0x3F,  0x7F,  0x28,  0x90, 	/* 42780 */
+	0x44,  0x88,  0x1F,  0xFC,  0x10,  0x84,  0x11,  0x44,  0x16,  0x34,  0x00,  0x0C,  0x10,  0x44,  0x1E,  0x48, 	/* 42790 */
+	0x10,  0x70,  0x10,  0x42,  0x1F,  0x42,  0x70,  0x3E,  0x87,  0x10,  0x20,  0x10,  0x20,  0x3F,  0xBF,  0x24, 	/* 427A0 */
+	0x50,  0x42,  0x88,  0x3F,  0xFC,  0x21,  0x04,  0x21,  0x04,  0x3F,  0xFC,  0x21,  0x04,  0x27,  0xE4,  0x24, 	/* 427B0 */
+	0x24,  0x27,  0xE4,  0x20,  0x04,  0x3F,  0xFC,  0x00,  0x00,  0x8B,  0x08,  0x20,  0x08,  0x20,  0x1F,  0x7F, 	/* 427C0 */
+	0x24,  0x90,  0x42,  0x08,  0x00,  0x90,  0x3F,  0xFE,  0x00,  0x48,  0x00,  0xF2,  0x1F,  0x0E,  0x00,  0x90, 	/* 427D0 */
+	0x7F,  0xFF,  0x00,  0x4C,  0x00,  0xF1,  0x3F,  0x19,  0x00,  0x07,  0x8D,  0x08,  0x20,  0x08,  0x20,  0x1F, 	/* 427E0 */
+	0x7F,  0x14,  0x50,  0x2A,  0x88,  0x49,  0xFF,  0x09,  0x10,  0x7F,  0x10,  0x09,  0x7E,  0x09,  0x52,  0x0F, 	/* 427F0 */
+	0x52,  0x79,  0x56,  0x09,  0x10,  0x09,  0x10,  0x09,  0xFF,  0x18,  0x00,  0x8F,  0x08,  0x20,  0x08,  0x20, 	/* 42800 */
+	0x1F,  0x7F,  0x24,  0x48,  0x42,  0x9C,  0x1F,  0xE8,  0x08,  0x84,  0x08,  0x42,  0x17,  0xFC,  0x00,  0x84, 	/* 42810 */
+	0x7F,  0xFF,  0x00,  0x84,  0x0F,  0xFC,  0x00,  0x80,  0x00,  0x80,  0x01,  0x80,  0x92,  0x10,  0x20,  0x1F, 	/* 42820 */
+	0x3F,  0x24,  0x48,  0x42,  0x84,  0x0F,  0xF0,  0x00,  0x10,  0x1F,  0xFC,  0x00,  0x10,  0x0F,  0xF0,  0x00, 	/* 42830 */
+	0x00,  0x3F,  0xFE,  0x20,  0x82,  0x2F,  0xFA,  0x08,  0x88,  0x08,  0xB0,  0x00,  0x80,  0x94,  0x10,  0x40, 	/* 42840 */
+	0x10,  0x40,  0x1F,  0x7E,  0x28,  0x90,  0x25,  0x28,  0x40,  0x20,  0x30,  0x40,  0x09,  0xFC,  0x01,  0x04, 	/* 42850 */
+	0x61,  0x04,  0x11,  0xFC,  0x01,  0x04,  0x09,  0x04,  0x11,  0x04,  0x21,  0xFC,  0x40,  0x00,  0x95,  0x08, 	/* 42860 */
+	0x20,  0x08,  0x20,  0x1F,  0xBF,  0x14,  0x48,  0x22,  0x84,  0x44,  0x10,  0x3F,  0xFE,  0x04,  0x10,  0x07, 	/* 42870 */
+	0xF0,  0x04,  0x10,  0x07,  0xF0,  0x04,  0x10,  0x7F,  0xFF,  0x02,  0x30,  0x0C,  0x0C,  0x30,  0x02,  0x97, 	/* 42880 */
+	0x10,  0x20,  0x10,  0x20,  0x1F,  0x7F,  0x24,  0x90,  0x22,  0x08,  0x4F,  0xF8,  0x08,  0x08,  0x0F,  0xF8, 	/* 42890 */
+	0x08,  0x08,  0x0F,  0xF8,  0x08,  0x08,  0x0F,  0xF8,  0x02,  0x20,  0x7F,  0xFF,  0x04,  0x20,  0x08,  0x20, 	/* 428A0 */
+	0x98,  0x10,  0x20,  0x10,  0x20,  0x3F,  0x7F,  0x24,  0x48,  0x42,  0x84,  0x3F,  0xFE,  0x20,  0x22,  0x23, 	/* 428B0 */
+	0xC2,  0x20,  0x82,  0x3F,  0xFE,  0x21,  0xC2,  0x26,  0xB2,  0x38,  0x8E,  0x20,  0x82,  0x3F,  0xFE,  0x00, 	/* 428C0 */
+	0x00,  0x99,  0x10,  0x20,  0x10,  0x20,  0x3F,  0x7F,  0x24,  0x48,  0x42,  0x84,  0x3E,  0x7E,  0x22,  0x42, 	/* 428D0 */
+	0x22,  0x44,  0x3E,  0x7E,  0x22,  0x52,  0x22,  0x52,  0x3E,  0x4C,  0x22,  0x44,  0x22,  0x4C,  0x22,  0x52, 	/* 428E0 */
+	0x46,  0x61,  0x9A,  0x08,  0x20,  0x08,  0x20,  0x1F,  0x3F,  0x14,  0x48,  0x22,  0x84,  0x44,  0x02,  0x06, 	/* 428F0 */
+	0x12,  0x09,  0x12,  0x1F,  0x92,  0x20,  0x52,  0x5F,  0xB2,  0x10,  0x92,  0x10,  0x92,  0x10,  0x82,  0x1F, 	/* 42900 */
+	0x82,  0x00,  0x06,  0x9C,  0x10,  0x20,  0x10,  0x20,  0x3F,  0x7F,  0x24,  0x50,  0x42,  0x88,  0x3F,  0xFE, 	/* 42910 */
+	0x21,  0x42,  0x22,  0x46,  0x0C,  0x3C,  0x70,  0x00,  0x1F,  0xF8,  0x01,  0x00,  0x01,  0x00,  0x01,  0x00, 	/* 42920 */
+	0x7F,  0xFE,  0x00,  0x00,  0x9D,  0x08,  0x20,  0x08,  0x20,  0x1F,  0x7F,  0x14,  0x48,  0x22,  0x84,  0x42, 	/* 42930 */
+	0x00,  0x08,  0x44,  0x08,  0x44,  0x7E,  0xFF,  0x08,  0x44,  0x08,  0x44,  0x0E,  0x7C,  0x78,  0x44,  0x08, 	/* 42940 */
+	0x44,  0x08,  0x7C,  0x18,  0x00,  0x9F,  0x08,  0x20,  0x08,  0x20,  0x1F,  0x7F,  0x14,  0x48,  0x22,  0x84, 	/* 42950 */
+	0x4F,  0xF8,  0x08,  0x08,  0x0F,  0xF8,  0x08,  0x08,  0x0F,  0xF8,  0x08,  0x20,  0x08,  0x22,  0x0F,  0xBC, 	/* 42960 */
+	0x08,  0x21,  0x0F,  0xA1,  0x78,  0x1F,  0xA1,  0x08,  0x10,  0x08,  0x10,  0x1F,  0xBF,  0x24,  0x48,  0x42, 	/* 42970 */
+	0x84,  0x7F,  0xFE,  0x40,  0x02,  0x4F,  0xF2,  0x08,  0x10,  0x08,  0x10,  0x0F,  0xF0,  0x08,  0x00,  0x0F, 	/* 42980 */
+	0xF8,  0x08,  0x08,  0x08,  0x08,  0x0F,  0xF8,  0xAA,  0x10,  0x10,  0x10,  0x10,  0x1F,  0xBF,  0x22,  0x50, 	/* 42990 */
+	0x29,  0x08,  0x44,  0x88,  0x04,  0x90,  0x0F,  0xF8,  0x08,  0x88,  0x0F,  0xF8,  0x08,  0x88,  0x0F,  0xF8, 	/* 429A0 */
+	0x00,  0x80,  0x7F,  0xFF,  0x00,  0x80,  0x00,  0x80,  0xAD,  0x10,  0x20,  0x10,  0x20,  0x3F,  0x7F,  0x24, 	/* 429B0 */
+	0x50,  0x44,  0x88,  0x02,  0x10,  0x7F,  0xFF,  0x00,  0x00,  0x1F,  0x24,  0x11,  0x24,  0x1F,  0x24,  0x11, 	/* 429C0 */
+	0x24,  0x1F,  0x24,  0x11,  0x24,  0x11,  0x24,  0x13,  0x0C,  0xB1,  0x08,  0x20,  0x08,  0x20,  0x1F,  0x7F, 	/* 429D0 */
+	0x14,  0x48,  0x22,  0x84,  0x44,  0x00,  0x04,  0x7E,  0x7F,  0x42,  0x0C,  0x42,  0x0E,  0x7E,  0x15,  0x42, 	/* 429E0 */
+	0x24,  0xFE,  0x24,  0x42,  0x44,  0x42,  0x04,  0x7E,  0x04,  0x00,  0xB4,  0x08,  0x20,  0x08,  0x20,  0x1F, 	/* 429F0 */
+	0x7F,  0x14,  0x48,  0x22,  0x94,  0x40,  0x14,  0x1F,  0xFF,  0x10,  0x10,  0x17,  0xD2,  0x10,  0x12,  0x17, 	/* 42A00 */
+	0xD4,  0x14,  0x4C,  0x14,  0x49,  0x27,  0xD5,  0x20,  0x23,  0x40,  0x41,  0xB8,  0x08,  0x20,  0x08,  0x20, 	/* 42A10 */
+	0x1F,  0x7F,  0x14,  0x50,  0x22,  0x88,  0x5F,  0xFC,  0x00,  0x88,  0x00,  0x90,  0x7F,  0xFF,  0x00,  0x80, 	/* 42A20 */
+	0x07,  0xF8,  0x1C,  0x08,  0x67,  0xF8,  0x04,  0x08,  0x04,  0x08,  0x07,  0xF8,  0x80,  0x10,  0x40,  0x10, 	/* 42A30 */
+	0x40,  0x3F,  0x7E,  0x28,  0xA0,  0x45,  0x10,  0x00,  0x00,  0x3F,  0x7C,  0x21,  0x44,  0x3F,  0x44,  0x21, 	/* 42A40 */
+	0x44,  0x3F,  0x44,  0x24,  0x44,  0x22,  0x44,  0x3D,  0x58,  0x61,  0x40,  0x00,  0x40,  0x81,  0x08,  0x20, 	/* 42A50 */
+	0x08,  0x20,  0x1F,  0x7F,  0x14,  0x50,  0x22,  0x88,  0x4F,  0xF8,  0x08,  0x08,  0x0F,  0xF8,  0x08,  0x08, 	/* 42A60 */
+	0x0F,  0xF8,  0x3F,  0xFE,  0x00,  0x80,  0x1F,  0xFC,  0x00,  0x80,  0x7F,  0xFF,  0x00,  0x00,  0x84,  0x08, 	/* 42A70 */
+	0x20,  0x08,  0x20,  0x1F,  0xFF,  0x14,  0x50,  0x22,  0x88,  0x44,  0x00,  0x3F,  0xBE,  0x04,  0x22,  0x1F, 	/* 42A80 */
+	0xA2,  0x14,  0xA2,  0x1F,  0xA2,  0x14,  0xAC,  0x1F,  0xA0,  0x04,  0x21,  0x3F,  0xA1,  0x04,  0x1F,  0x86, 	/* 42A90 */
+	0x08,  0x20,  0x1F,  0x7F,  0x14,  0x48,  0x22,  0x84,  0x43,  0xF0,  0x04,  0x10,  0x0F,  0xE0,  0x00,  0x20, 	/* 42AA0 */
+	0x7F,  0xFF,  0x03,  0x04,  0x3C,  0x98,  0x03,  0x50,  0x3C,  0xA8,  0x03,  0x24,  0x7C,  0x23,  0x00,  0xC0, 	/* 42AB0 */
+	0x87,  0x10,  0x20,  0x1F,  0x3F,  0x24,  0x48,  0x42,  0x84,  0x7F,  0xFF,  0x00,  0x00,  0x1F,  0xFC,  0x10, 	/* 42AC0 */
+	0x04,  0x1F,  0xFC,  0x10,  0x00,  0x1F,  0xFC,  0x19,  0x24,  0x2F,  0xFC,  0x29,  0x24,  0x49,  0x24,  0x08, 	/* 42AD0 */
+	0x0C,  0x89,  0x10,  0x20,  0x10,  0x20,  0x3F,  0x7F,  0x24,  0x90,  0x42,  0x08,  0x3F,  0x7C,  0x08,  0x44, 	/* 42AE0 */
+	0x08,  0x64,  0x0F,  0x55,  0x70,  0x93,  0x00,  0x80,  0x7F,  0xFE,  0x01,  0xC0,  0x0E,  0xB8,  0x70,  0x87, 	/* 42AF0 */
+	0x00,  0x80,  0x8B,  0x08,  0x20,  0x08,  0x20,  0x1F,  0x7F,  0x24,  0x48,  0x42,  0x84,  0x3F,  0xFE,  0x20, 	/* 42B00 */
+	0x80,  0x2F,  0xFC,  0x24,  0x90,  0x24,  0x90,  0x2A,  0xA8,  0x31,  0x44,  0x22,  0x30,  0x2C,  0x0C,  0x3F, 	/* 42B10 */
+	0xFE,  0x20,  0x00,  0x8C,  0x08,  0x20,  0x08,  0x20,  0x1F,  0x7F,  0x14,  0x48,  0x22,  0x84,  0x44,  0x00, 	/* 42B20 */
+	0x04,  0xF8,  0x08,  0x08,  0x13,  0xFF,  0x30,  0x80,  0x50,  0xFC,  0x11,  0x10,  0x13,  0xFF,  0x10,  0x28, 	/* 42B30 */
+	0x10,  0xC4,  0x13,  0x03,  0x8F,  0x08,  0x20,  0x08,  0x20,  0x1F,  0x7F,  0x14,  0x48,  0x22,  0x84,  0x40, 	/* 42B40 */
+	0x20,  0x11,  0x20,  0x11,  0x3F,  0x7F,  0xA1,  0x11,  0x4A,  0x11,  0x88,  0x1F,  0x18,  0x11,  0x14,  0x11, 	/* 42B50 */
+	0x24,  0x1F,  0x42,  0x01,  0x81,  0x9D,  0x08,  0x20,  0x08,  0x20,  0x1F,  0x7F,  0x14,  0x90,  0x22,  0x28, 	/* 42B60 */
+	0x5F,  0xFC,  0x02,  0x20,  0x1F,  0xFC,  0x02,  0x20,  0x7F,  0xFF,  0x08,  0x88,  0x0F,  0xF8,  0x08,  0x88, 	/* 42B70 */
+	0x7F,  0xFF,  0x08,  0x08,  0x08,  0x18,  0xA0,  0x10,  0x40,  0x1F,  0x7F,  0x24,  0x50,  0x22,  0x88,  0x44, 	/* 42B80 */
+	0x40,  0x04,  0x7F,  0x0C,  0xA4,  0x0F,  0x18,  0x14,  0x34,  0x35,  0xC3,  0x54,  0x10,  0x15,  0xFF,  0x14, 	/* 42B90 */
+	0x38,  0x14,  0x54,  0x11,  0x93,  0x10,  0x10,  0xA4,  0x08,  0x10,  0x08,  0x10,  0x0F,  0xBF,  0x14,  0x48, 	/* 42BA0 */
+	0x22,  0x84,  0x4F,  0xFC,  0x08,  0x80,  0x0F,  0xF8,  0x08,  0x80,  0x0F,  0xF8,  0x08,  0x80,  0x0F,  0xFE, 	/* 42BB0 */
+	0x24,  0x92,  0x22,  0x4A,  0x22,  0x42,  0x40,  0x0C,  0xA5,  0x10,  0x20,  0x10,  0x20,  0x3F,  0x7F,  0x24, 	/* 42BC0 */
+	0x50,  0x42,  0x88,  0x3F,  0xFE,  0x02,  0x20,  0x1F,  0xFC,  0x12,  0x24,  0x1F,  0xFC,  0x00,  0x80,  0x7F, 	/* 42BD0 */
+	0xFF,  0x02,  0xA0,  0x0C,  0x98,  0x70,  0x87,  0x00,  0x80,  0xA6,  0x08,  0x20,  0x08,  0x20,  0x1F,  0x7F, 	/* 42BE0 */
+	0x24,  0x48,  0x42,  0x84,  0x0F,  0xFC,  0x09,  0x24,  0x08,  0xC4,  0x09,  0x24,  0x0F,  0xFC,  0x00,  0x00, 	/* 42BF0 */
+	0x08,  0x22,  0x0F,  0xBC,  0x08,  0x21,  0x0F,  0xA1,  0x78,  0x1F,  0xA9,  0x08,  0x20,  0x08,  0x20,  0x1F, 	/* 42C00 */
+	0x7F,  0x24,  0x50,  0x42,  0x88,  0x08,  0x00,  0x3E,  0xFF,  0x22,  0x10,  0x22,  0x7E,  0x3E,  0x52,  0x20, 	/* 42C10 */
+	0x52,  0x3E,  0x52,  0x22,  0x52,  0x22,  0x56,  0x3E,  0x10,  0x00,  0x10,  0xAD,  0x10,  0x20,  0x1F,  0xBF, 	/* 42C20 */
+	0x14,  0x48,  0x22,  0x84,  0x40,  0x80,  0x1F,  0xFC,  0x02,  0x20,  0x7F,  0xFF,  0x00,  0x00,  0x0F,  0xF8, 	/* 42C30 */
+	0x08,  0x88,  0x0F,  0xF8,  0x08,  0x88,  0x0F,  0xFA,  0x00,  0x82,  0x00,  0x7E,  0xB3,  0x10,  0x20,  0x1F, 	/* 42C40 */
+	0x3F,  0x24,  0x50,  0x42,  0x88,  0x1F,  0xFC,  0x10,  0x84,  0x1F,  0xFC,  0x10,  0x84,  0x1F,  0xFC,  0x7F, 	/* 42C50 */
+	0xFF,  0x04,  0x90,  0x3F,  0xFE,  0x00,  0x80,  0x1F,  0xFC,  0x00,  0x80,  0x00,  0x80,  0xB6,  0x10,  0x20, 	/* 42C60 */
+	0x10,  0x20,  0x3F,  0x7F,  0x24,  0x48,  0x42,  0x84,  0x3F,  0xFE,  0x00,  0x80,  0x08,  0xF8,  0x08,  0x80, 	/* 42C70 */
+	0x7F,  0xFF,  0x08,  0x00,  0x0F,  0xFC,  0x08,  0x00,  0x2F,  0xFE,  0x24,  0x92,  0x42,  0x5C,  0xB7,  0x10, 	/* 42C80 */
+	0x20,  0x1F,  0x3F,  0x24,  0x48,  0x42,  0xA4,  0x10,  0x7C,  0x09,  0xC8,  0x08,  0x30,  0x20,  0x6C,  0x13, 	/* 42C90 */
+	0x93,  0x79,  0xFC,  0x08,  0x10,  0x08,  0xFC,  0x08,  0x10,  0x1F,  0xFF,  0x22,  0x10,  0x41,  0xFF,  0x80, 	/* 42CA0 */
+	0x10,  0x20,  0x1F,  0x3F,  0x14,  0x48,  0x22,  0x84,  0x5F,  0xFE,  0x00,  0x80,  0x0F,  0xF8,  0x00,  0x80, 	/* 42CB0 */
+	0x7F,  0xFF,  0x08,  0x08,  0x0F,  0xE8,  0x0B,  0xF8,  0x08,  0x08,  0x0F,  0xF8,  0x06,  0x18,  0x38,  0x06, 	/* 42CC0 */
+	0x87,  0x08,  0x20,  0x08,  0x20,  0x1F,  0x7F,  0x14,  0x48,  0x22,  0xA4,  0x48,  0x20,  0x08,  0x7E,  0x7F, 	/* 42CD0 */
+	0x40,  0x10,  0xA0,  0x1E,  0x3E,  0x12,  0x48,  0x12,  0x08,  0x22,  0xFF,  0x22,  0x14,  0x42,  0x22,  0x0C, 	/* 42CE0 */
+	0xC1,  0x8D,  0x10,  0x20,  0x1F,  0x3F,  0x24,  0x50,  0x42,  0x88,  0x1F,  0xFC,  0x10,  0x84,  0x7F,  0xFF, 	/* 42CF0 */
+	0x10,  0x84,  0x1F,  0xFC,  0x08,  0x88,  0x0F,  0xF8,  0x01,  0x00,  0x7F,  0xFF,  0x06,  0x10,  0x01,  0xF0, 	/* 42D00 */
+	0x3E,  0x0C,  0x91,  0x10,  0x20,  0x10,  0x20,  0x3F,  0x7F,  0x24,  0x50,  0x42,  0x88,  0x3F,  0xFE,  0x00, 	/* 42D10 */
+	0x00,  0x0F,  0xF8,  0x08,  0x08,  0x7F,  0xFF,  0x08,  0x08,  0x0F,  0xFA,  0x02,  0x44,  0x0C,  0x28,  0x77, 	/* 42D20 */
+	0x98,  0x0C,  0x07,  0x92,  0x10,  0x20,  0x1F,  0x3F,  0x24,  0x44,  0x4F,  0xF8,  0x08,  0x08,  0x0F,  0xE8, 	/* 42D30 */
+	0x0B,  0xF8,  0x08,  0x08,  0x0F,  0xF8,  0x01,  0x00,  0x7F,  0xFF,  0x05,  0x10,  0x1A,  0x8C,  0x64,  0xA3, 	/* 42D40 */
+	0x19,  0x10,  0x07,  0xE8,  0x93,  0x08,  0x20,  0x08,  0x20,  0x1F,  0x7F,  0x14,  0x50,  0x22,  0x8C,  0x5F, 	/* 42D50 */
+	0xC4,  0x12,  0x48,  0x17,  0x4A,  0x12,  0x54,  0x1F,  0xC5,  0x12,  0x49,  0x17,  0x52,  0x15,  0x42,  0x27, 	/* 42D60 */
+	0x44,  0x20,  0x48,  0x40,  0xD0,  0x94,  0x10,  0x20,  0x10,  0x20,  0x3F,  0x7F,  0x24,  0x48,  0x42,  0x88, 	/* 42D70 */
+	0x3F,  0xFE,  0x00,  0x00,  0x1F,  0xFC,  0x04,  0x08,  0x7F,  0xFF,  0x04,  0x08,  0x1F,  0xFC,  0x02,  0x42, 	/* 42D80 */
+	0x0C,  0x24,  0x77,  0x98,  0x0C,  0x07,  0x97,  0x10,  0x20,  0x1F,  0x3F,  0x24,  0x48,  0x42,  0x84,  0x18, 	/* 42D90 */
+	0xFC,  0x04,  0x24,  0x31,  0x26,  0x09,  0x45,  0x1A,  0x44,  0x60,  0x98,  0x00,  0x80,  0x7F,  0xFF,  0x02, 	/* 42DA0 */
+	0xA0,  0x0C,  0x9C,  0x70,  0x83,  0x00,  0x80,  0x9F,  0x10,  0x20,  0x1F,  0x3F,  0x24,  0x48,  0x42,  0x84, 	/* 42DB0 */
+	0x7F,  0xFF,  0x02,  0x20,  0x1F,  0xFC,  0x12,  0x24,  0x1F,  0xFC,  0x08,  0x08,  0x0F,  0xF8,  0x08,  0x08, 	/* 42DC0 */
+	0x0F,  0xF8,  0x00,  0x80,  0x7F,  0xFF,  0x00,  0x80,  0xA1,  0x10,  0x20,  0x1F,  0xBF,  0x24,  0x50,  0x42, 	/* 42DD0 */
+	0x88,  0x3F,  0x7E,  0x21,  0x42,  0x3F,  0x7E,  0x21,  0x42,  0x3F,  0x7E,  0x20,  0x02,  0x27,  0xE2,  0x24, 	/* 42DE0 */
+	0x22,  0x27,  0xE2,  0x24,  0x22,  0x27,  0xE2,  0x20,  0x06,  0xA3,  0x10,  0x20,  0x1F,  0x7F,  0x24,  0x48, 	/* 42DF0 */
+	0x42,  0x84,  0x0F,  0xF8,  0x08,  0x88,  0x0F,  0xF8,  0x00,  0x80,  0x7F,  0xFF,  0x0F,  0xF8,  0x08,  0x08, 	/* 42E00 */
+	0x0F,  0xF8,  0x08,  0x08,  0x0F,  0xF8,  0x06,  0x18,  0x38,  0x06,  0xA7,  0x10,  0x20,  0x1F,  0x3F,  0x24, 	/* 42E10 */
+	0x48,  0x42,  0xA4,  0x3F,  0xFE,  0x02,  0x20,  0x03,  0xE0,  0x7F,  0xFF,  0x00,  0x80,  0x0F,  0xF8,  0x08, 	/* 42E20 */
+	0x88,  0x0F,  0xF8,  0x08,  0x88,  0x0F,  0xF8,  0x06,  0x18,  0x38,  0x06,  0xAA,  0x10,  0x20,  0x1F,  0x3F, 	/* 42E30 */
+	0x24,  0x48,  0x42,  0x84,  0x1F,  0x3E,  0x12,  0x24,  0x7F,  0x7F,  0x06,  0x8C,  0x1B,  0x35,  0x62,  0xC7, 	/* 42E40 */
+	0x0F,  0xF8,  0x08,  0x08,  0x0F,  0xF8,  0x08,  0x08,  0x0F,  0xF8,  0x00,  0x00,  0xAB,  0x10,  0x20,  0x1F, 	/* 42E50 */
+	0x7F,  0x24,  0x48,  0x42,  0x84,  0x1F,  0xFC,  0x00,  0x84,  0x7F,  0xFF,  0x00,  0x84,  0x1F,  0xFC,  0x04, 	/* 42E60 */
+	0x90,  0x14,  0x94,  0x1F,  0xFC,  0x10,  0x84,  0x1C,  0xBC,  0x24,  0xA4,  0x44,  0xA4,  0xB7,  0x10,  0x20, 	/* 42E70 */
+	0x1F,  0x7F,  0x24,  0x90,  0x43,  0xE8,  0x04,  0x40,  0x1F,  0xFF,  0x71,  0x11,  0x12,  0xEA,  0x1F,  0xFE, 	/* 42E80 */
+	0x10,  0x00,  0x13,  0xF8,  0x10,  0x00,  0x27,  0xFC,  0x24,  0x04,  0x47,  0xFC,  0x00,  0x00,  0xB8,  0x10, 	/* 42E90 */
+	0x20,  0x10,  0x20,  0x3F,  0x7F,  0x28,  0x50,  0x44,  0x88,  0x12,  0x08,  0x7F,  0xFF,  0x12,  0x4A,  0x1E, 	/* 42EA0 */
+	0x48,  0x12,  0x7E,  0x1E,  0x52,  0x12,  0x52,  0x7F,  0xCC,  0x12,  0x8C,  0x21,  0x12,  0x42,  0x61,  0xBD, 	/* 42EB0 */
+	0x10,  0x20,  0x10,  0x20,  0x3F,  0x7F,  0x28,  0x48,  0x44,  0x84,  0x01,  0x40,  0x02,  0x30,  0x0F,  0xEC, 	/* 42EC0 */
+	0x70,  0x03,  0x1F,  0x7C,  0x11,  0x44,  0x1F,  0x7C,  0x04,  0x10,  0x06,  0x18,  0x09,  0x24,  0x30,  0x44, 	/* 42ED0 */
+	0xBE,  0x10,  0x20,  0x1F,  0xBF,  0x28,  0x50,  0x44,  0x88,  0x1F,  0xFE,  0x12,  0x10,  0x11,  0x20,  0x1F, 	/* 42EE0 */
+	0xFE,  0x11,  0x24,  0x1F,  0xFF,  0x11,  0x24,  0x17,  0xFC,  0x23,  0x30,  0x25,  0x2C,  0x59,  0x23,  0x01, 	/* 42EF0 */
+	0x20,  0xBF,  0x10,  0x20,  0x10,  0x20,  0x1F,  0x7F,  0x24,  0x90,  0x42,  0x24,  0x27,  0xFF,  0x10,  0x20, 	/* 42F00 */
+	0x11,  0xFC,  0x41,  0x24,  0x21,  0xFC,  0x21,  0x24,  0x09,  0xFC,  0x08,  0x08,  0x17,  0xFF,  0x21,  0x08, 	/* 42F10 */
+	0x40,  0x98,  0x80,  0x10,  0x20,  0x10,  0x20,  0x3F,  0x7F,  0x24,  0x88,  0x52,  0x20,  0x11,  0xDE,  0x11, 	/* 42F20 */
+	0x0A,  0x7D,  0x4A,  0x11,  0xB2,  0x16,  0x26,  0x19,  0xFC,  0x71,  0x24,  0x11,  0xFC,  0x11,  0x24,  0x11, 	/* 42F30 */
+	0xFC,  0x30,  0x00,  0x83,  0x10,  0x20,  0x1F,  0x3F,  0x24,  0x50,  0x42,  0x88,  0x3F,  0x90,  0x24,  0x1F, 	/* 42F40 */
+	0x3F,  0x20,  0x21,  0x40,  0x3F,  0x1E,  0x24,  0x00,  0x3F,  0x80,  0x1F,  0xFC,  0x12,  0x24,  0x12,  0x24, 	/* 42F50 */
+	0x7F,  0xFF,  0x00,  0x00,  0x8C,  0x10,  0x20,  0x1F,  0x7F,  0x24,  0x88,  0x5F,  0xFC,  0x00,  0x80,  0x0F, 	/* 42F60 */
+	0xF8,  0x00,  0x00,  0x7F,  0xFF,  0x00,  0x82,  0x0F,  0xF8,  0x00,  0x00,  0x7F,  0xFF,  0x00,  0x04,  0x1F, 	/* 42F70 */
+	0x7F,  0x11,  0x24,  0x1F,  0x0C,  0x8D,  0x10,  0x20,  0x1F,  0xBF,  0x24,  0x48,  0x42,  0x84,  0x08,  0x24, 	/* 42F80 */
+	0x3E,  0xFF,  0x08,  0x24,  0x3E,  0x24,  0x08,  0xFF,  0x7F,  0x00,  0x08,  0x7E,  0x1C,  0x42,  0x1A,  0x7E, 	/* 42F90 */
+	0x29,  0x42,  0x48,  0x7E,  0x08,  0x00,  0x8F,  0x10,  0x20,  0x1F,  0x3F,  0x24,  0x50,  0x42,  0x88,  0x08, 	/* 42FA0 */
+	0x40,  0x08,  0xFF,  0x7F,  0x24,  0x10,  0xFF,  0x10,  0x24,  0x1E,  0x3C,  0x12,  0x24,  0x12,  0x3C,  0x22, 	/* 42FB0 */
+	0x24,  0x22,  0xFF,  0x42,  0x24,  0x0C,  0xC2,  0x90,  0x10,  0x10,  0x1F,  0xBF,  0x24,  0x28,  0x42,  0x44, 	/* 42FC0 */
+	0x00,  0x54,  0x3C,  0x92,  0x25,  0x7E,  0x24,  0x28,  0x3D,  0xFF,  0x24,  0x48,  0x24,  0x94,  0x3D,  0x57, 	/* 42FD0 */
+	0x24,  0x38,  0x24,  0x54,  0x25,  0x93,  0x4C,  0x30,  0x94,  0x10,  0x20,  0x1F,  0x3F,  0x24,  0x50,  0x42, 	/* 42FE0 */
+	0x88,  0x1F,  0x10,  0x15,  0x1F,  0x7F,  0xA4,  0x15,  0x24,  0x1F,  0x44,  0x15,  0x94,  0x1F,  0x14,  0x7F, 	/* 42FF0 */
+	0xC8,  0x0A,  0x0C,  0x32,  0x14,  0x0E,  0x62,  0x71,  0x81,  0x96,  0x10,  0x20,  0x1F,  0x3F,  0x24,  0x50, 	/* 43000 */
+	0x42,  0x94,  0x3F,  0xD2,  0x02,  0x10,  0x7F,  0xFF,  0x09,  0x10,  0x39,  0xD2,  0x09,  0x12,  0x39,  0xDC, 	/* 43010 */
+	0x09,  0x0C,  0x39,  0xC8,  0x09,  0x15,  0x0F,  0xA3,  0x70,  0x41,  0x98,  0x10,  0x10,  0x1F,  0xBF,  0x24, 	/* 43020 */
+	0x28,  0x42,  0x44,  0x00,  0x54,  0x3C,  0x92,  0x25,  0x7E,  0x24,  0x28,  0x3D,  0xFF,  0x24,  0x54,  0x24, 	/* 43030 */
+	0x92,  0x3D,  0x69,  0x24,  0x14,  0x25,  0xFE,  0x24,  0x54,  0x4D,  0x92,  0x9F,  0x10,  0x20,  0x1F,  0x3F, 	/* 43040 */
+	0x24,  0x48,  0x42,  0x84,  0x08,  0x00,  0x7F,  0x7F,  0x08,  0x09,  0x3F,  0x1F,  0x29,  0x62,  0x29,  0x3E, 	/* 43050 */
+	0x3F,  0x22,  0x0C,  0x3E,  0x1A,  0x22,  0x29,  0x3E,  0x48,  0x32,  0x08,  0xC1,  0xA0,  0x10,  0x20,  0x1F, 	/* 43060 */
+	0x3F,  0x28,  0x48,  0x44,  0x84,  0x04,  0x20,  0x3F,  0xBE,  0x11,  0x20,  0x7F,  0xFE,  0x00,  0x02,  0x1F, 	/* 43070 */
+	0x3E,  0x11,  0x20,  0x1F,  0x3E,  0x11,  0x20,  0x1F,  0x3E,  0x11,  0x21,  0x13,  0x1F,  0xA4,  0x10,  0x20, 	/* 43080 */
+	0x1F,  0x3F,  0x24,  0x50,  0x4A,  0x94,  0x08,  0x92,  0x15,  0x50,  0x7F,  0xFF,  0x09,  0x10,  0x39,  0xD2, 	/* 43090 */
+	0x09,  0x12,  0x39,  0xDC,  0x09,  0x0C,  0x39,  0xC8,  0x09,  0x15,  0x0F,  0xA3,  0x70,  0x41,  0xA5,  0x10, 	/* 430A0 */
+	0x10,  0x1F,  0x1F,  0x24,  0xA8,  0x41,  0x44,  0x02,  0x20,  0x0F,  0xF8,  0x70,  0x07,  0x3D,  0xDE,  0x25, 	/* 430B0 */
+	0x52,  0x3D,  0xDE,  0x00,  0x00,  0x1F,  0xFC,  0x12,  0x24,  0x1F,  0xFC,  0x12,  0x24,  0x12,  0x2C,  0xAC, 	/* 430C0 */
+	0x10,  0x20,  0x1F,  0x3F,  0x24,  0x48,  0x42,  0x84,  0x04,  0x12,  0x7F,  0x94,  0x0A,  0x3F,  0x25,  0x64, 	/* 430D0 */
+	0x2B,  0x24,  0x3F,  0x3E,  0x04,  0x24,  0x7F,  0xBE,  0x4A,  0xA4,  0x5D,  0xA4,  0x40,  0xBF,  0x41,  0x80, 	/* 430E0 */
+	0xB3,  0x00,  0x80,  0x10,  0x88,  0x08,  0x88,  0x04,  0x90,  0x04,  0xA0,  0x00,  0x80,  0x7F,  0xFF,  0x01, 	/* 430F0 */
+	0xC0,  0x02,  0xA0,  0x02,  0xA0,  0x04,  0x90,  0x08,  0x88,  0x10,  0x84,  0x20,  0x82,  0x00,  0x80,  0x00, 	/* 43100 */
+	0x80,  0xB5,  0x08,  0x10,  0x09,  0x10,  0x49,  0x10,  0x2A,  0x10,  0x28,  0x10,  0x08,  0x10,  0x7F,  0xFF, 	/* 43110 */
+	0x08,  0x10,  0x1C,  0x10,  0x1A,  0x10,  0x29,  0x10,  0x28,  0x10,  0x48,  0x10,  0x08,  0x10,  0x08,  0x10, 	/* 43120 */
+	0x08,  0x10,  0xBE,  0x08,  0x00,  0x08,  0xFE,  0x4A,  0x12,  0x2A,  0x12,  0x2C,  0x92,  0x08,  0x52,  0x7F, 	/* 43130 */
+	0x32,  0x08,  0x12,  0x1C,  0x12,  0x1A,  0x32,  0x29,  0x2A,  0x28,  0x2A,  0x48,  0x42,  0x08,  0x42,  0x08, 	/* 43140 */
+	0x84,  0x09,  0x18,  0x81,  0x08,  0x04,  0x0A,  0x18,  0x4A,  0xF0,  0x2A,  0x10,  0x2C,  0x10,  0x08,  0x10, 	/* 43150 */
+	0x7F,  0x10,  0x09,  0xFF,  0x1C,  0x10,  0x1A,  0x10,  0x29,  0x10,  0x28,  0x10,  0x48,  0x10,  0x08,  0x10, 	/* 43160 */
+	0x08,  0x10,  0x08,  0x10,  0x82,  0x01,  0x00,  0x03,  0xF0,  0x0C,  0x20,  0x30,  0x40,  0x00,  0xA0,  0x03, 	/* 43170 */
+	0x10,  0x0C,  0x8C,  0x78,  0x93,  0x04,  0x90,  0x04,  0xA0,  0x7F,  0xFF,  0x02,  0xA0,  0x04,  0x90,  0x18, 	/* 43180 */
+	0x8C,  0x60,  0x83,  0x00,  0x80,  0x83,  0x08,  0x90,  0x0A,  0x90,  0x4A,  0x90,  0x2A,  0x92,  0x2C,  0x92, 	/* 43190 */
+	0x08,  0xF2,  0x7E,  0x94,  0x08,  0x98,  0x1C,  0x90,  0x1A,  0x90,  0x2A,  0x90,  0x28,  0x90,  0x48,  0x90, 	/* 431A0 */
+	0x08,  0xB1,  0x08,  0xD1,  0x0B,  0x0F,  0x89,  0x08,  0x48,  0x4A,  0x48,  0x2A,  0x48,  0x2A,  0x48,  0x2C, 	/* 431B0 */
+	0x84,  0x08,  0x84,  0x7F,  0x02,  0x0A,  0xFD,  0x1C,  0x24,  0x1A,  0x24,  0x2A,  0x24,  0x2A,  0x24,  0x48, 	/* 431C0 */
+	0x44,  0x08,  0x44,  0x08,  0x88,  0x09,  0x30,  0x8B,  0x08,  0x20,  0x09,  0x20,  0x49,  0xFC,  0x2A,  0x24, 	/* 431D0 */
+	0x2A,  0x24,  0x08,  0x25,  0x7F,  0x45,  0x08,  0x93,  0x1C,  0x10,  0x1A,  0x10,  0x2B,  0xFE,  0x28,  0x10, 	/* 431E0 */
+	0x48,  0x10,  0x08,  0x10,  0x08,  0x10,  0x08,  0x10,  0x8D,  0x08,  0x04,  0x0A,  0x18,  0x4A,  0xE0,  0x2C, 	/* 431F0 */
+	0x20,  0x28,  0x20,  0x08,  0x3E,  0x7F,  0xE0,  0x08,  0x20,  0x1C,  0x20,  0x1A,  0x3E,  0x2B,  0xE0,  0x28, 	/* 43200 */
+	0x20,  0x48,  0x21,  0x08,  0x21,  0x08,  0x1F,  0x08,  0x00,  0x90,  0x08,  0x00,  0x09,  0xFF,  0x4A,  0x00, 	/* 43210 */
+	0x2A,  0x00,  0x2C,  0x7E,  0x08,  0x42,  0x7F,  0x42,  0x08,  0x42,  0x1C,  0x7E,  0x1A,  0x40,  0x2A,  0x40, 	/* 43220 */
+	0x28,  0x40,  0x48,  0x80,  0x08,  0x80,  0x09,  0x00,  0x0A,  0x00,  0x92,  0x08,  0x20,  0x0A,  0x20,  0x4A, 	/* 43230 */
+	0x20,  0x2B,  0xFE,  0x2C,  0x00,  0x08,  0x84,  0x7F,  0x84,  0x08,  0x84,  0x1C,  0x44,  0x1A,  0x48,  0x2A, 	/* 43240 */
+	0x48,  0x28,  0x48,  0x48,  0x50,  0x08,  0x10,  0x09,  0xFF,  0x08,  0x00,  0x95,  0x08,  0x10,  0x4A,  0x10, 	/* 43250 */
+	0x2A,  0x20,  0x2C,  0xFE,  0x28,  0x82,  0x08,  0x82,  0x7F,  0x82,  0x08,  0x82,  0x1C,  0xFE,  0x1A,  0x82, 	/* 43260 */
+	0x2A,  0x82,  0x28,  0x82,  0x48,  0x82,  0x08,  0x82,  0x08,  0xFE,  0x08,  0x00,  0x97,  0x08,  0x00,  0x4A, 	/* 43270 */
+	0xFC,  0x2A,  0x84,  0x2C,  0x84,  0x08,  0x84,  0x7F,  0xFC,  0x08,  0x84,  0x08,  0x84,  0x1C,  0x84,  0x1A, 	/* 43280 */
+	0xFC,  0x2A,  0x84,  0x28,  0x84,  0x48,  0x84,  0x08,  0x84,  0x0B,  0xFF,  0x08,  0x00,  0x98,  0x08,  0x20, 	/* 43290 */
+	0x4A,  0x20,  0x2A,  0x20,  0x2C,  0x20,  0x28,  0x3F,  0x08,  0x20,  0x7F,  0x20,  0x08,  0x20,  0x1C,  0x20, 	/* 432A0 */
+	0x1A,  0xFC,  0x29,  0x84,  0x28,  0x84,  0x48,  0x84,  0x08,  0x84,  0x08,  0xFC,  0x08,  0x00,  0x9B,  0x00, 	/* 432B0 */
+	0x80,  0x1F,  0xFC,  0x00,  0x84,  0x7F,  0xFF,  0x00,  0x84,  0x1F,  0xFC,  0x00,  0x80,  0x14,  0x94,  0x12, 	/* 432C0 */
+	0xA4,  0x1F,  0xFC,  0x10,  0x84,  0x11,  0xC4,  0x12,  0xA4,  0x2C,  0x9C,  0x20,  0x84,  0x40,  0x84,  0x9F, 	/* 432D0 */
+	0x00,  0x00,  0x7F,  0xFF,  0x02,  0x20,  0x1F,  0xFC,  0x12,  0x24,  0x12,  0x24,  0x1F,  0xFC,  0x08,  0x88, 	/* 432E0 */
+	0x04,  0x88,  0x02,  0x90,  0x7F,  0xFF,  0x01,  0xC0,  0x02,  0xA0,  0x0C,  0x98,  0x70,  0x86,  0x00,  0x80, 	/* 432F0 */
+	0xA1,  0x08,  0x00,  0x08,  0xFE,  0x4A,  0x82,  0x2A,  0x82,  0x2C,  0xFE,  0x08,  0x82,  0x7F,  0x82,  0x08, 	/* 43300 */
+	0xBA,  0x1C,  0xAA,  0x1A,  0xAA,  0x2A,  0xAA,  0x28,  0xBA,  0x48,  0x82,  0x08,  0x82,  0x08,  0x82,  0x08, 	/* 43310 */
+	0x86,  0xA2,  0x00,  0x80,  0x00,  0x80,  0x79,  0xFE,  0x01,  0x22,  0x02,  0x24,  0x08,  0x50,  0x10,  0x88, 	/* 43320 */
+	0x61,  0x04,  0x0A,  0x8B,  0x04,  0x88,  0x04,  0x90,  0x7F,  0xFF,  0x02,  0xA0,  0x04,  0x90,  0x18,  0x8C, 	/* 43330 */
+	0x60,  0x83,  0xA4,  0x00,  0x80,  0x01,  0x00,  0x1F,  0xFC,  0x14,  0x94,  0x12,  0xA4,  0x1F,  0xFC,  0x11, 	/* 43340 */
+	0xC4,  0x12,  0xA4,  0x14,  0x94,  0x1F,  0xFC,  0x00,  0x00,  0x7F,  0xFF,  0x02,  0x00,  0x07,  0xF8,  0x04, 	/* 43350 */
+	0x08,  0x00,  0x30,  0xA5,  0x00,  0x00,  0x78,  0x9E,  0x0C,  0xA2,  0x0A,  0xA2,  0x0A,  0xC2,  0x38,  0x8E, 	/* 43360 */
+	0x27,  0xF8,  0x20,  0x88,  0x39,  0xCE,  0x09,  0xC2,  0x0A,  0xA2,  0x0A,  0xA2,  0x0C,  0x92,  0x08,  0x82, 	/* 43370 */
+	0x10,  0x84,  0x60,  0x18,  0xA7,  0x08,  0x10,  0x4A,  0x10,  0x2A,  0x10,  0x2C,  0xFF,  0x28,  0x80,  0x08, 	/* 43380 */
+	0x90,  0x7E,  0x90,  0x08,  0x90,  0x1C,  0xFE,  0x1A,  0x90,  0x2A,  0x90,  0x28,  0x90,  0x49,  0x10,  0x09, 	/* 43390 */
+	0x10,  0x0A,  0xFF,  0x08,  0x00,  0xA8,  0x08,  0x00,  0x09,  0xFF,  0x4A,  0x20,  0x2A,  0x20,  0x2C,  0x40, 	/* 433A0 */
+	0x08,  0xFE,  0x7E,  0x82,  0x08,  0x82,  0x1C,  0x82,  0x1A,  0xFE,  0x2A,  0x82,  0x28,  0x82,  0x48,  0x82, 	/* 433B0 */
+	0x08,  0x82,  0x08,  0xFE,  0x08,  0x00,  0xAB,  0x08,  0x00,  0x09,  0xFF,  0x4A,  0x10,  0x2A,  0x10,  0x2C, 	/* 433C0 */
+	0x20,  0x08,  0xFE,  0x7E,  0xAA,  0x08,  0xAA,  0x1C,  0xAA,  0x1A,  0xAA,  0x2A,  0xAA,  0x28,  0xAA,  0x48, 	/* 433D0 */
+	0xAA,  0x08,  0xAA,  0x08,  0xAA,  0x08,  0x86,  0xAD,  0x08,  0x20,  0x0A,  0x20,  0x4A,  0x50,  0x2A,  0x50, 	/* 433E0 */
+	0x2C,  0x88,  0x08,  0x84,  0x7F,  0x7A,  0x0A,  0x01,  0x18,  0x00,  0x1C,  0x00,  0x2A,  0xFC,  0x2A,  0x84, 	/* 433F0 */
+	0x48,  0x84,  0x08,  0x84,  0x08,  0xFC,  0x08,  0x00,  0xAE,  0x08,  0x20,  0x0A,  0x20,  0x4A,  0xFC,  0x2C, 	/* 43400 */
+	0x84,  0x2C,  0x84,  0x08,  0xFC,  0x7F,  0x84,  0x08,  0x84,  0x1C,  0xFE,  0x1A,  0xA2,  0x2A,  0xA4,  0x28, 	/* 43410 */
+	0x94,  0x48,  0x88,  0x08,  0x84,  0x08,  0xE2,  0x0B,  0x01,  0xB1,  0x08,  0x00,  0x05,  0xF8,  0x40,  0x48, 	/* 43420 */
+	0x22,  0x4A,  0x02,  0x49,  0x0C,  0x89,  0x11,  0x08,  0x22,  0xB0,  0x48,  0x88,  0x04,  0x90,  0x7F,  0xFF, 	/* 43430 */
+	0x02,  0xA0,  0x04,  0x90,  0x18,  0x8C,  0x60,  0x83,  0x00,  0x80,  0xB2,  0x02,  0x00,  0x03,  0xC0,  0x0A, 	/* 43440 */
+	0x3C,  0x1F,  0x84,  0x71,  0x28,  0x0A,  0x10,  0x0C,  0x6C,  0x71,  0x83,  0x08,  0x88,  0x04,  0x90,  0x7F, 	/* 43450 */
+	0xFF,  0x02,  0xA0,  0x04,  0x90,  0x18,  0x8C,  0x60,  0x83,  0x00,  0x80,  0xB3,  0x08,  0x00,  0x09,  0xFF, 	/* 43460 */
+	0x4A,  0x10,  0x2A,  0x10,  0x2C,  0xFE,  0x08,  0x92,  0x7E,  0xFE,  0x08,  0x92,  0x1C,  0x92,  0x1A,  0xFE, 	/* 43470 */
+	0x2A,  0x10,  0x28,  0x50,  0x48,  0x20,  0x08,  0x50,  0x09,  0x8C,  0x0E,  0x03,  0xB9,  0x08,  0x10,  0x0A, 	/* 43480 */
+	0x10,  0x4A,  0xFE,  0x2C,  0x44,  0x28,  0x44,  0x08,  0x44,  0x7E,  0xAA,  0x08,  0xAA,  0x19,  0x10,  0x18, 	/* 43490 */
+	0x10,  0x2B,  0xFF,  0x28,  0x10,  0x48,  0x10,  0x08,  0x10,  0x08,  0x10,  0x08,  0x10,  0xBD,  0x08,  0x10, 	/* 434A0 */
+	0x0A,  0x10,  0x4A,  0xFE,  0x2C,  0x82,  0x2C,  0x82,  0x08,  0xFC,  0x7F,  0x00,  0x08,  0x00,  0x19,  0xFE, 	/* 434B0 */
+	0x1C,  0x10,  0x2A,  0x94,  0x28,  0x92,  0x48,  0x91,  0x09,  0x11,  0x0A,  0x10,  0x08,  0x30,  0xBE,  0x08, 	/* 434C0 */
+	0x20,  0x4A,  0x20,  0x2B,  0xFE,  0x2A,  0x20,  0x2C,  0xFC,  0x08,  0x20,  0x7F,  0xFF,  0x08,  0x00,  0x1C, 	/* 434D0 */
+	0xFC,  0x1A,  0x84,  0x2A,  0xFC,  0x28,  0x84,  0x48,  0xFC,  0x08,  0x84,  0x08,  0x84,  0x08,  0x8C,  0x80, 	/* 434E0 */
+	0x08,  0x48,  0x0A,  0x48,  0x4B,  0xFF,  0x2C,  0x48,  0x28,  0x48,  0x08,  0x20,  0x7F,  0x2A,  0x08,  0x4A, 	/* 434F0 */
+	0x1C,  0x4A,  0x1A,  0xCC,  0x29,  0x48,  0x28,  0x48,  0x48,  0x49,  0x08,  0x49,  0x08,  0x49,  0x08,  0x47, 	/* 43500 */
+	0x82,  0x08,  0x44,  0x0A,  0x44,  0x4B,  0xFF,  0x2C,  0x44,  0x28,  0x7C,  0x08,  0x44,  0x7F,  0x7C,  0x08, 	/* 43510 */
+	0x44,  0x1C,  0x44,  0x1B,  0xFF,  0x28,  0xA8,  0x28,  0xAA,  0x48,  0xC6,  0x08,  0x80,  0x08,  0xFF,  0x08, 	/* 43520 */
+	0x00,  0x85,  0x08,  0x00,  0x0A,  0xFE,  0x4A,  0x04,  0x2C,  0x38,  0x28,  0x10,  0x09,  0xFF,  0x7E,  0x32, 	/* 43530 */
+	0x08,  0x54,  0x1D,  0x90,  0x1A,  0x30,  0x2B,  0xFF,  0x28,  0x38,  0x48,  0x54,  0x08,  0x92,  0x0B,  0x11, 	/* 43540 */
+	0x08,  0x10,  0x8A,  0x10,  0x80,  0x14,  0x9E,  0x54,  0x92,  0x34,  0x92,  0x3B,  0xF2,  0x10,  0x9E,  0x7C, 	/* 43550 */
+	0x92,  0x10,  0x92,  0x1B,  0xD2,  0x36,  0x5E,  0x32,  0x52,  0x52,  0x52,  0x53,  0xD2,  0x10,  0x22,  0x10, 	/* 43560 */
+	0x22,  0x10,  0x46,  0x8E,  0x08,  0x00,  0x49,  0xFF,  0x2B,  0x00,  0x2D,  0x7E,  0x09,  0x52,  0x7F,  0x52, 	/* 43570 */
+	0x09,  0x7E,  0x19,  0x52,  0x1D,  0x52,  0x2B,  0x7E,  0x29,  0x10,  0x49,  0x7E,  0x09,  0x10,  0x0A,  0x10, 	/* 43580 */
+	0x0B,  0xFF,  0x0C,  0x00,  0x92,  0x08,  0x48,  0x0A,  0x48,  0x4B,  0xFF,  0x2C,  0x48,  0x28,  0x00,  0x09, 	/* 43590 */
+	0xFF,  0x7F,  0x00,  0x09,  0x7E,  0x1D,  0x52,  0x1B,  0x7E,  0x29,  0x52,  0x29,  0x52,  0x49,  0x7E,  0x0A, 	/* 435A0 */
+	0x52,  0x0C,  0x52,  0x08,  0x56,  0x96,  0x08,  0x20,  0x0A,  0x20,  0x4B,  0xFF,  0x2D,  0x10,  0x29,  0x7E, 	/* 435B0 */
+	0x09,  0x12,  0x7F,  0xFF,  0x09,  0x12,  0x19,  0x12,  0x1D,  0x7E,  0x2B,  0x00,  0x29,  0x7E,  0x4A,  0x42, 	/* 435C0 */
+	0x0A,  0x42,  0x0C,  0x7E,  0x08,  0x00,  0x98,  0x08,  0x10,  0x0A,  0x10,  0x4A,  0xFF,  0x2C,  0x81,  0x28, 	/* 435D0 */
+	0x81,  0x08,  0x7E,  0x7F,  0x22,  0x08,  0x52,  0x1D,  0x9C,  0x1A,  0x2C,  0x2A,  0x4A,  0x29,  0x9A,  0x48, 	/* 435E0 */
+	0x29,  0x08,  0x48,  0x09,  0x88,  0x08,  0x30,  0x9C,  0x00,  0x40,  0x00,  0x40,  0x1F,  0xFF,  0x11,  0x08, 	/* 435F0 */
+	0x1F,  0xFF,  0x11,  0x08,  0x15,  0xAA,  0x15,  0xAA,  0x19,  0x6B,  0x12,  0x44,  0x11,  0x48,  0x1F,  0xFF, 	/* 43600 */
+	0x21,  0x50,  0x26,  0x4C,  0x58,  0x43,  0x00,  0x40,  0x9E,  0x08,  0x88,  0x04,  0x90,  0x7F,  0xFF,  0x02, 	/* 43610 */
+	0xA0,  0x04,  0x90,  0x1F,  0xFC,  0x68,  0x8B,  0x0F,  0xF8,  0x08,  0x88,  0x0F,  0xF8,  0x02,  0x20,  0x3F, 	/* 43620 */
+	0xFE,  0x02,  0x20,  0x7F,  0xFF,  0x06,  0x18,  0x38,  0x04,  0x9F,  0x08,  0x48,  0x0A,  0x48,  0x4B,  0xFF, 	/* 43630 */
+	0x2C,  0x48,  0x29,  0xFE,  0x09,  0x4A,  0x7F,  0xFE,  0x09,  0x4A,  0x1D,  0xFE,  0x1A,  0x00,  0x1A,  0xFC, 	/* 43640 */
+	0x28,  0x84,  0x28,  0xFC,  0x48,  0x84,  0x08,  0xFC,  0x08,  0x00,  0xA0,  0x08,  0x10,  0x0A,  0x10,  0x4B, 	/* 43650 */
+	0xFF,  0x2D,  0x10,  0x29,  0x7E,  0x09,  0x12,  0x7F,  0xFF,  0x09,  0x12,  0x09,  0x7E,  0x1D,  0x91,  0x1B, 	/* 43660 */
+	0x5A,  0x29,  0x74,  0x2A,  0x54,  0x4B,  0x92,  0x0C,  0x11,  0x08,  0x30,  0xA2,  0x08,  0x48,  0x0A,  0x48, 	/* 43670 */
+	0x4B,  0xFF,  0x2C,  0x48,  0x28,  0x48,  0x08,  0xFC,  0x7E,  0x84,  0x08,  0xFC,  0x18,  0x84,  0x1C,  0xFC, 	/* 43680 */
+	0x2A,  0x20,  0x2B,  0xFF,  0x48,  0x30,  0x08,  0x48,  0x09,  0x84,  0x0E,  0x03,  0xA7,  0x08,  0x00,  0x4A, 	/* 43690 */
+	0xFC,  0x2A,  0x84,  0x2C,  0xFC,  0x08,  0x84,  0x7F,  0xFF,  0x08,  0x00,  0x08,  0xFC,  0x1C,  0xA4,  0x1A, 	/* 436A0 */
+	0xFC,  0x2A,  0xA4,  0x28,  0xFC,  0x48,  0x20,  0x09,  0xFE,  0x08,  0x20,  0x0F,  0xFF,  0xAF,  0x08,  0x00, 	/* 436B0 */
+	0x0A,  0xFE,  0x4A,  0x10,  0x2D,  0xFF,  0x29,  0x11,  0x09,  0xDD,  0x7F,  0x11,  0x08,  0xDC,  0x1C,  0x00, 	/* 436C0 */
+	0x1B,  0xFF,  0x28,  0x20,  0x29,  0xFE,  0x49,  0x4A,  0x09,  0x4A,  0x09,  0x4A,  0x09,  0x06,  0xB2,  0x08, 	/* 436D0 */
+	0x00,  0x0B,  0xFF,  0x4B,  0x24,  0x2D,  0xFF,  0x29,  0x24,  0x09,  0x7E,  0x7F,  0x52,  0x09,  0x7E,  0x1D, 	/* 436E0 */
+	0x52,  0x1B,  0x7E,  0x29,  0x10,  0x29,  0xFF,  0x4A,  0x99,  0x0A,  0x95,  0x0C,  0xFB,  0x08,  0x83,  0xB4, 	/* 436F0 */
+	0x38,  0x00,  0x08,  0xFF,  0x08,  0x33,  0x08,  0xDD,  0x14,  0x33,  0x14,  0xDD,  0x22,  0x14,  0x48,  0x28, 	/* 43700 */
+	0x2A,  0x7F,  0x1C,  0xC8,  0x08,  0x7E,  0x7F,  0x48,  0x1C,  0x7E,  0x2A,  0x48,  0x49,  0x7F,  0x08,  0x00, 	/* 43710 */
+	0xB6,  0x08,  0x00,  0x2A,  0xFF,  0x2A,  0x33,  0x3E,  0xDD,  0x08,  0x33,  0x2A,  0xDD,  0x2A,  0x14,  0x3E, 	/* 43720 */
+	0x28,  0x08,  0x7F,  0x2A,  0xC8,  0x1C,  0x7E,  0x7F,  0x48,  0x1C,  0x7E,  0x2A,  0x48,  0x49,  0x7F,  0x08, 	/* 43730 */
+	0x00,  0xB8,  0x01,  0x00,  0x01,  0x00,  0x01,  0x20,  0x02,  0x20,  0x1C,  0x40,  0x06,  0x80,  0x01,  0x20, 	/* 43740 */
+	0x02,  0x18,  0x7F,  0xF4,  0x01,  0x02,  0x09,  0x20,  0x09,  0x10,  0x09,  0x10,  0x11,  0x08,  0x21,  0x08, 	/* 43750 */
+	0x01,  0x00,  0xBA,  0x08,  0x40,  0x08,  0x40,  0x12,  0x40,  0x62,  0x40,  0x14,  0x40,  0x08,  0x40,  0x0C, 	/* 43760 */
+	0x40,  0x12,  0x40,  0x7D,  0x40,  0x09,  0x40,  0x28,  0x40,  0x2A,  0x40,  0x29,  0x41,  0x29,  0x21,  0x48, 	/* 43770 */
+	0x1F,  0x08,  0x00,  0xBB,  0x00,  0x0C,  0x00,  0xF0,  0x7F,  0x00,  0x02,  0x20,  0x02,  0x40,  0x1C,  0x40, 	/* 43780 */
+	0x02,  0x80,  0x01,  0x20,  0x02,  0x18,  0x7F,  0xF4,  0x01,  0x02,  0x05,  0x20,  0x09,  0x18,  0x11,  0x04, 	/* 43790 */
+	0x61,  0x02,  0x01,  0x00,  0xBE,  0x08,  0x08,  0x08,  0x48,  0x0A,  0x48,  0x72,  0x48,  0x14,  0x48,  0x08, 	/* 437A0 */
+	0x48,  0x0C,  0x48,  0x12,  0x48,  0x7D,  0x48,  0x08,  0x4F,  0x2C,  0x78,  0x2B,  0xC8,  0x2A,  0x08,  0x2A, 	/* 437B0 */
+	0x08,  0x48,  0x08,  0x08,  0x08,  0x80,  0x08,  0x00,  0x08,  0x7E,  0x0A,  0x02,  0x72,  0x02,  0x14,  0x02, 	/* 437C0 */
+	0x08,  0x02,  0x0C,  0x7E,  0x12,  0x40,  0x7D,  0x40,  0x09,  0x40,  0x28,  0x40,  0x2A,  0x40,  0x29,  0x41, 	/* 437D0 */
+	0x29,  0x21,  0x48,  0x1F,  0x08,  0x00,  0x82,  0x08,  0x04,  0x08,  0x04,  0x0A,  0x04,  0x72,  0x04,  0x14, 	/* 437E0 */
+	0xFF,  0x08,  0x04,  0x0C,  0x04,  0x12,  0x44,  0x7D,  0x24,  0x09,  0x24,  0x28,  0x04,  0x2A,  0x04,  0x29, 	/* 437F0 */
+	0x04,  0x29,  0x04,  0x48,  0x04,  0x08,  0x0C,  0x84,  0x08,  0x40,  0x08,  0x40,  0x0A,  0x40,  0x72,  0x7E, 	/* 43800 */
+	0x14,  0x82,  0x08,  0x82,  0x0D,  0x02,  0x12,  0x42,  0x7D,  0x22,  0x09,  0x12,  0x28,  0x12,  0x2A,  0x02, 	/* 43810 */
+	0x29,  0x02,  0x29,  0x02,  0x48,  0x04,  0x08,  0x18,  0x85,  0x08,  0x00,  0x08,  0x00,  0x0A,  0xFE,  0x72, 	/* 43820 */
+	0x10,  0x14,  0x10,  0x08,  0x10,  0x0C,  0x10,  0x12,  0x10,  0x7D,  0x10,  0x09,  0x10,  0x2C,  0x10,  0x2A, 	/* 43830 */
+	0x10,  0x2A,  0x10,  0x2B,  0xFF,  0x48,  0x00,  0x08,  0x00,  0x86,  0x08,  0x00,  0x08,  0xFE,  0x0A,  0x10, 	/* 43840 */
+	0x72,  0x10,  0x14,  0x10,  0x08,  0x10,  0x0C,  0x10,  0x12,  0xFF,  0x7D,  0x10,  0x09,  0x10,  0x28,  0x10, 	/* 43850 */
+	0x2A,  0x10,  0x29,  0x10,  0x29,  0x10,  0x48,  0x10,  0x08,  0x30,  0x8A,  0x00,  0x80,  0x00,  0x80,  0x7F, 	/* 43860 */
+	0xFF,  0x02,  0x10,  0x01,  0x20,  0x00,  0xC0,  0x07,  0x38,  0x78,  0x87,  0x01,  0x20,  0x0E,  0x50,  0x01, 	/* 43870 */
+	0x8C,  0x7F,  0xFA,  0x02,  0xB1,  0x0C,  0x8C,  0x30,  0x82,  0x00,  0x80,  0x8B,  0x08,  0x10,  0x08,  0x10, 	/* 43880 */
+	0x0A,  0x10,  0x73,  0xFF,  0x14,  0x44,  0x08,  0x44,  0x0C,  0x44,  0x12,  0x28,  0x7D,  0x28,  0x09,  0x10, 	/* 43890 */
+	0x28,  0x10,  0x2A,  0x18,  0x29,  0x28,  0x29,  0x44,  0x48,  0x82,  0x0B,  0x01,  0x8D,  0x08,  0x10,  0x08, 	/* 438A0 */
+	0x10,  0x0A,  0x10,  0x72,  0xFE,  0x14,  0x92,  0x08,  0x92,  0x0C,  0x92,  0x12,  0xAA,  0x7D,  0xAA,  0x09, 	/* 438B0 */
+	0xAA,  0x2C,  0xC6,  0x2A,  0x82,  0x2A,  0x82,  0x2A,  0x82,  0x48,  0x82,  0x08,  0x86,  0x90,  0x08,  0x00, 	/* 438C0 */
+	0x09,  0xFC,  0x0A,  0x24,  0x72,  0x24,  0x14,  0x24,  0x08,  0x24,  0x0A,  0x24,  0x12,  0xFE,  0x7F,  0x44, 	/* 438D0 */
+	0x09,  0x44,  0x2C,  0x44,  0x2A,  0x44,  0x2A,  0x44,  0x2A,  0x44,  0x49,  0xFF,  0x08,  0x00,  0x94,  0x08, 	/* 438E0 */
+	0x10,  0x08,  0x13,  0x12,  0x1C,  0x63,  0xF0,  0x14,  0x10,  0x08,  0x52,  0x0C,  0x52,  0x12,  0x52,  0x7D, 	/* 438F0 */
+	0x52,  0x09,  0x52,  0x28,  0x7E,  0x2A,  0x10,  0x29,  0x10,  0x29,  0x11,  0x48,  0x11,  0x08,  0x0F,  0x95, 	/* 43900 */
+	0x08,  0x88,  0x08,  0x88,  0x0A,  0x88,  0x72,  0x88,  0x14,  0x88,  0x08,  0x89,  0x0C,  0xEA,  0x12,  0x8C, 	/* 43910 */
+	0x7D,  0x88,  0x09,  0x88,  0x2C,  0x88,  0x2A,  0x88,  0x2A,  0x88,  0x2A,  0xB9,  0x48,  0xC9,  0x0B,  0x07, 	/* 43920 */
+	0x97,  0x08,  0x10,  0x08,  0x10,  0x0A,  0x10,  0x72,  0x54,  0x14,  0x52,  0x08,  0x52,  0x0A,  0x51,  0x12, 	/* 43930 */
+	0x95,  0x7F,  0x14,  0x09,  0x34,  0x28,  0x08,  0x2A,  0x08,  0x29,  0x10,  0x29,  0x20,  0x48,  0xC0,  0x0B, 	/* 43940 */
+	0x00,  0x98,  0x08,  0x20,  0x08,  0x20,  0x0A,  0x20,  0x73,  0xFF,  0x14,  0x20,  0x08,  0x28,  0x0C,  0x28, 	/* 43950 */
+	0x12,  0x28,  0x7D,  0x48,  0x08,  0x48,  0x2C,  0x50,  0x2A,  0x94,  0x2A,  0x92,  0x29,  0x2E,  0x48,  0xF1, 	/* 43960 */
+	0x08,  0x01,  0x99,  0x08,  0x02,  0x08,  0x0C,  0x0A,  0x78,  0x72,  0x48,  0x14,  0x48,  0x08,  0x48,  0x0C, 	/* 43970 */
+	0x48,  0x12,  0x7F,  0x7D,  0x48,  0x09,  0x48,  0x28,  0x48,  0x2A,  0x44,  0x29,  0x44,  0x29,  0x55,  0x48, 	/* 43980 */
+	0x63,  0x09,  0x81,  0x9A,  0x08,  0x00,  0x09,  0xFC,  0x0A,  0x44,  0x72,  0x48,  0x14,  0x48,  0x08,  0x5E, 	/* 43990 */
+	0x0C,  0x62,  0x12,  0x62,  0x7D,  0x54,  0x08,  0x54,  0x2C,  0x98,  0x2A,  0x88,  0x2A,  0x94,  0x29,  0x24, 	/* 439A0 */
+	0x4A,  0x42,  0x08,  0x81,  0x9B,  0x08,  0x48,  0x08,  0x48,  0x0A,  0x48,  0x72,  0x48,  0x14,  0x84,  0x08, 	/* 439B0 */
+	0x84,  0x0B,  0x02,  0x12,  0xFD,  0x7F,  0x24,  0x09,  0x24,  0x2C,  0x24,  0x2A,  0x24,  0x29,  0x44,  0x29, 	/* 439C0 */
+	0x44,  0x48,  0x88,  0x09,  0x30,  0x9C,  0x08,  0x00,  0x08,  0x00,  0x0A,  0x7E,  0x72,  0x00,  0x14,  0x00, 	/* 439D0 */
+	0x08,  0x00,  0x0A,  0xFF,  0x12,  0x10,  0x7F,  0x10,  0x09,  0x10,  0x28,  0x28,  0x2A,  0x24,  0x29,  0x24, 	/* 439E0 */
+	0x29,  0x4E,  0x48,  0xF2,  0x08,  0x02,  0xA0,  0x00,  0x80,  0x3F,  0xFE,  0x00,  0x80,  0x0F,  0xF8,  0x00, 	/* 439F0 */
+	0x80,  0x7F,  0xFF,  0x00,  0x80,  0x03,  0x20,  0x0C,  0x58,  0x03,  0x84,  0x3F,  0xFA,  0x00,  0x80,  0x04, 	/* 43A00 */
+	0xB0,  0x18,  0x8C,  0x60,  0x82,  0x00,  0x80,  0xA1,  0x08,  0x10,  0x08,  0x10,  0x0A,  0x10,  0x73,  0xFF, 	/* 43A10 */
+	0x14,  0x20,  0x08,  0x20,  0x0A,  0x20,  0x12,  0x3C,  0x7F,  0x24,  0x09,  0x24,  0x2C,  0x24,  0x2A,  0x44, 	/* 43A20 */
+	0x29,  0x44,  0x29,  0x44,  0x48,  0x84,  0x09,  0x18,  0xA2,  0x01,  0x00,  0x01,  0x00,  0x7F,  0xFE,  0x01, 	/* 43A30 */
+	0x00,  0x01,  0x00,  0x7F,  0xFE,  0x42,  0x22,  0x4C,  0x42,  0x02,  0xB0,  0x01,  0x0C,  0x7F,  0xF2,  0x01, 	/* 43A40 */
+	0x00,  0x09,  0x30,  0x11,  0x08,  0x61,  0x04,  0x01,  0x00,  0xAB,  0x04,  0x20,  0x14,  0x22,  0x17,  0xA4, 	/* 43A50 */
+	0x14,  0x38,  0x14,  0x21,  0x17,  0xA1,  0x1C,  0x9F,  0x60,  0x80,  0x0F,  0x10,  0x02,  0x60,  0x01,  0x8C, 	/* 43A60 */
+	0x7F,  0xF6,  0x02,  0xB1,  0x0C,  0x8C,  0x30,  0x82,  0x00,  0x80,  0xAC,  0x08,  0x10,  0x08,  0x10,  0x0A, 	/* 43A70 */
+	0x10,  0x72,  0x10,  0x14,  0xFE,  0x08,  0x92,  0x0C,  0x92,  0x12,  0x92,  0x7D,  0x92,  0x08,  0xFE,  0x2C, 	/* 43A80 */
+	0x92,  0x2A,  0x92,  0x2A,  0x92,  0x2A,  0x92,  0x48,  0xFE,  0x08,  0x00,  0xAE,  0x04,  0x20,  0x04,  0x20, 	/* 43A90 */
+	0x7F,  0xA0,  0x0E,  0x20,  0x15,  0x20,  0x24,  0x21,  0x44,  0xA1,  0x04,  0x9F,  0x0F,  0x20,  0x02,  0x50, 	/* 43AA0 */
+	0x01,  0x8C,  0x7F,  0xFA,  0x02,  0xB1,  0x0C,  0x8C,  0x30,  0x82,  0x00,  0x80,  0xAF,  0x00,  0x00,  0x1F, 	/* 43AB0 */
+	0xFC,  0x10,  0x84,  0x1F,  0xFC,  0x10,  0x84,  0x10,  0x84,  0x1F,  0xFC,  0x01,  0x90,  0x0E,  0x28,  0x01, 	/* 43AC0 */
+	0x44,  0x7F,  0xFA,  0x00,  0x80,  0x04,  0xB0,  0x18,  0x8C,  0x60,  0x82,  0x00,  0x80,  0xB0,  0x08,  0x00, 	/* 43AD0 */
+	0x08,  0xFE,  0x0A,  0x92,  0x72,  0x92,  0x14,  0x92,  0x08,  0x92,  0x0C,  0x92,  0x12,  0xFE,  0x7D,  0x92, 	/* 43AE0 */
+	0x08,  0x92,  0x2C,  0x92,  0x2A,  0x92,  0x2A,  0x92,  0x2A,  0x92,  0x48,  0xFE,  0x08,  0x00,  0xB2,  0x08, 	/* 43AF0 */
+	0x54,  0x08,  0x54,  0x0A,  0x54,  0x72,  0x54,  0x14,  0xFF,  0x08,  0x54,  0x0C,  0x54,  0x12,  0x54,  0x7D, 	/* 43B00 */
+	0x54,  0x09,  0x54,  0x28,  0x5C,  0x2A,  0x40,  0x29,  0x40,  0x29,  0x40,  0x48,  0x7F,  0x08,  0x00,  0xB3, 	/* 43B10 */
+	0x08,  0x10,  0x08,  0x10,  0x0A,  0x10,  0x72,  0xFE,  0x14,  0x92,  0x08,  0x92,  0x0C,  0x92,  0x12,  0xFE, 	/* 43B20 */
+	0x7D,  0x92,  0x09,  0x92,  0x28,  0xFE,  0x2A,  0x10,  0x29,  0x10,  0x29,  0x10,  0x48,  0x10,  0x08,  0x10, 	/* 43B30 */
+	0xB5,  0x08,  0x10,  0x08,  0x10,  0x0A,  0xFE,  0x72,  0x82,  0x14,  0x82,  0x08,  0x00,  0x0C,  0xFF,  0x12, 	/* 43B40 */
+	0x10,  0x7D,  0x10,  0x09,  0x10,  0x28,  0x10,  0x2A,  0x10,  0x29,  0x10,  0x29,  0x10,  0x48,  0x10,  0x08, 	/* 43B50 */
+	0x30,  0xB9,  0x08,  0x00,  0x08,  0xFE,  0x0A,  0x22,  0x72,  0x22,  0x14,  0x22,  0x08,  0x42,  0x0A,  0x42, 	/* 43B60 */
+	0x12,  0x8C,  0x7F,  0x00,  0x09,  0x7E,  0x2C,  0x42,  0x2A,  0x42,  0x29,  0x42,  0x29,  0x42,  0x48,  0x7E, 	/* 43B70 */
+	0x08,  0x00,  0xBA,  0x08,  0x44,  0x08,  0x44,  0x0A,  0x44,  0x73,  0xFF,  0x14,  0x44,  0x08,  0x44,  0x0C, 	/* 43B80 */
+	0x44,  0x12,  0x44,  0x7D,  0x7C,  0x09,  0x44,  0x28,  0x44,  0x2A,  0x44,  0x29,  0x44,  0x29,  0x44,  0x48, 	/* 43B90 */
+	0x7C,  0x08,  0x00,  0xBF,  0x08,  0x10,  0x08,  0x10,  0x0A,  0x10,  0x72,  0x24,  0x14,  0x22,  0x08,  0x4E, 	/* 43BA0 */
+	0x0B,  0xF1,  0x12,  0x01,  0x7F,  0x00,  0x09,  0x7E,  0x28,  0x42,  0x2A,  0x42,  0x29,  0x42,  0x29,  0x42, 	/* 43BB0 */
+	0x48,  0x7E,  0x08,  0x00,  0x82,  0x08,  0x20,  0x08,  0x20,  0x12,  0x3C,  0x62,  0x44,  0x14,  0x48,  0x08, 	/* 43BC0 */
+	0xA8,  0x0D,  0x18,  0x12,  0x24,  0x7D,  0x42,  0x09,  0x81,  0x28,  0x38,  0x2A,  0x04,  0x29,  0x00,  0x29, 	/* 43BD0 */
+	0x70,  0x48,  0x0C,  0x08,  0x02,  0x83,  0x08,  0x10,  0x08,  0x10,  0x0A,  0x10,  0x73,  0xFF,  0x14,  0x10, 	/* 43BE0 */
+	0x08,  0x10,  0x0A,  0x24,  0x12,  0xC4,  0x7F,  0x28,  0x09,  0x28,  0x2C,  0x10,  0x2A,  0x14,  0x2A,  0x22, 	/* 43BF0 */
+	0x28,  0x4E,  0x49,  0xF1,  0x08,  0x01,  0x84,  0x08,  0x00,  0x08,  0x7C,  0x0A,  0x44,  0x72,  0x44,  0x14, 	/* 43C00 */
+	0x44,  0x08,  0x7C,  0x0C,  0x44,  0x12,  0x44,  0x7D,  0x44,  0x09,  0x7C,  0x28,  0x44,  0x2A,  0x44,  0x29, 	/* 43C10 */
+	0x44,  0x29,  0x44,  0x49,  0xFF,  0x08,  0x00,  0x85,  0x08,  0x00,  0x08,  0xFE,  0x0A,  0x82,  0x72,  0x82, 	/* 43C20 */
+	0x14,  0x82,  0x08,  0xBA,  0x0C,  0xAA,  0x12,  0xAA,  0x7E,  0xAA,  0x09,  0xAA,  0x2C,  0xBA,  0x2A,  0x82, 	/* 43C30 */
+	0x2A,  0x82,  0x28,  0x82,  0x48,  0x82,  0x08,  0x86,  0x86,  0x08,  0x10,  0x08,  0x54,  0x0A,  0x52,  0x72, 	/* 43C40 */
+	0x92,  0x14,  0x10,  0x08,  0xFE,  0x0C,  0x10,  0x12,  0x10,  0x7D,  0x10,  0x09,  0xFF,  0x28,  0x10,  0x2A, 	/* 43C50 */
+	0x10,  0x29,  0x10,  0x29,  0x10,  0x48,  0x10,  0x08,  0x10,  0x8B,  0x08,  0x10,  0x08,  0x10,  0x0A,  0x10, 	/* 43C60 */
+	0x72,  0xFF,  0x14,  0x90,  0x08,  0x90,  0x0C,  0x90,  0x12,  0x90,  0x7D,  0x90,  0x08,  0x98,  0x2C,  0xA4, 	/* 43C70 */
+	0x2A,  0xA4,  0x2A,  0xA2,  0x29,  0x4E,  0x4A,  0xF1,  0x08,  0x01,  0x8C,  0x08,  0x00,  0x08,  0xFC,  0x0A, 	/* 43C80 */
+	0x44,  0x72,  0x24,  0x14,  0x28,  0x08,  0x18,  0x0C,  0x24,  0x12,  0xC3,  0x7D,  0x10,  0x09,  0x10,  0x28, 	/* 43C90 */
+	0xFE,  0x2A,  0x10,  0x29,  0x10,  0x29,  0x10,  0x49,  0xFF,  0x08,  0x00,  0x8E,  0x08,  0x40,  0x08,  0x5E, 	/* 43CA0 */
+	0x0A,  0x80,  0x72,  0x80,  0x15,  0x00,  0x08,  0x40,  0x0C,  0x7F,  0x12,  0x84,  0x7E,  0x84,  0x09,  0x84, 	/* 43CB0 */
+	0x28,  0x84,  0x2C,  0x84,  0x2A,  0x84,  0x2A,  0x84,  0x48,  0x84,  0x08,  0x8C,  0x8F,  0x08,  0x20,  0x08, 	/* 43CC0 */
+	0x20,  0x0A,  0xFC,  0x72,  0xA4,  0x14,  0xA4,  0x08,  0xFC,  0x0C,  0xA4,  0x12,  0xA4,  0x7D,  0xFC,  0x09, 	/* 43CD0 */
+	0x12,  0x28,  0x14,  0x2A,  0x08,  0x29,  0x19,  0x29,  0x65,  0x49,  0x83,  0x08,  0x01,  0x90,  0x08,  0x10, 	/* 43CE0 */
+	0x08,  0x10,  0x12,  0x10,  0x65,  0xFF,  0x14,  0x10,  0x08,  0x10,  0x0C,  0x10,  0x12,  0xFE,  0x7D,  0x00, 	/* 43CF0 */
+	0x09,  0x00,  0x28,  0x7E,  0x2A,  0x42,  0x29,  0x42,  0x29,  0x42,  0x48,  0x7E,  0x08,  0x00,  0x96,  0x08, 	/* 43D00 */
+	0x10,  0x08,  0x12,  0x0A,  0x92,  0x72,  0x54,  0x14,  0x54,  0x08,  0x10,  0x0C,  0x10,  0x12,  0xFF,  0x7D, 	/* 43D10 */
+	0x28,  0x08,  0x28,  0x28,  0x28,  0x2A,  0x28,  0x29,  0x48,  0x29,  0x49,  0x48,  0x89,  0x09,  0x07,  0x9B, 	/* 43D20 */
+	0x04,  0x40,  0x04,  0x40,  0x04,  0xFF,  0x09,  0x44,  0x0A,  0x28,  0x14,  0x10,  0x14,  0x6C,  0x37,  0x93, 	/* 43D30 */
+	0x54,  0x28,  0x14,  0xEC,  0x14,  0x12,  0x15,  0xFF,  0x14,  0x58,  0x14,  0x96,  0x13,  0x11,  0x10,  0x10, 	/* 43D40 */
+	0x9E,  0x08,  0x10,  0x08,  0x10,  0x0A,  0x10,  0x73,  0xFF,  0x14,  0x48,  0x08,  0x44,  0x0C,  0x44,  0x12, 	/* 43D50 */
+	0x8A,  0x7D,  0x4A,  0x09,  0x28,  0x2C,  0x30,  0x2A,  0x10,  0x2A,  0x30,  0x2A,  0x48,  0x48,  0x84,  0x09, 	/* 43D60 */
+	0x03,  0xA1,  0x08,  0x20,  0x08,  0x20,  0x12,  0x7C,  0x64,  0x44,  0x14,  0xC8,  0x09,  0x28,  0x0C,  0x10, 	/* 43D70 */
+	0x12,  0x28,  0x7D,  0x44,  0x08,  0x82,  0x2D,  0xFD,  0x2A,  0x84,  0x2A,  0x84,  0x2A,  0x84,  0x48,  0xFC, 	/* 43D80 */
+	0x08,  0x00,  0xA2,  0x08,  0x40,  0x08,  0x40,  0x0A,  0x40,  0x72,  0x7E,  0x16,  0x82,  0x08,  0x82,  0x0B, 	/* 43D90 */
+	0x7A,  0x12,  0x4A,  0x7F,  0x4A,  0x09,  0x7A,  0x28,  0x4A,  0x2A,  0x4A,  0x29,  0x7A,  0x29,  0x02,  0x48, 	/* 43DA0 */
+	0x04,  0x08,  0x18,  0xA3,  0x08,  0x44,  0x08,  0x24,  0x0A,  0x28,  0x72,  0xFF,  0x14,  0x24,  0x08,  0x24, 	/* 43DB0 */
+	0x0C,  0x24,  0x12,  0x24,  0x7D,  0xFF,  0x09,  0x24,  0x28,  0x24,  0x2A,  0x24,  0x29,  0x24,  0x29,  0x44, 	/* 43DC0 */
+	0x48,  0x44,  0x08,  0x84,  0xA6,  0x08,  0x10,  0x08,  0x10,  0x0A,  0x28,  0x72,  0x28,  0x14,  0x44,  0x08, 	/* 43DD0 */
+	0x82,  0x0D,  0x7D,  0x12,  0x00,  0x7D,  0x00,  0x09,  0x7C,  0x28,  0x44,  0x2A,  0x44,  0x29,  0x44,  0x29, 	/* 43DE0 */
+	0x44,  0x48,  0x7C,  0x08,  0x00,  0xA8,  0x08,  0x08,  0x08,  0x0C,  0x0A,  0x0A,  0x72,  0x0A,  0x15,  0xFF, 	/* 43DF0 */
+	0x08,  0x08,  0x0C,  0x28,  0x12,  0x2A,  0x7D,  0xFA,  0x08,  0x2A,  0x2C,  0x24,  0x2A,  0x45,  0x2A,  0x4D, 	/* 43E00 */
+	0x2A,  0x93,  0x48,  0x23,  0x08,  0xC1,  0xAE,  0x08,  0x00,  0x08,  0x3E,  0x7F,  0xA2,  0x09,  0x22,  0x11, 	/* 43E10 */
+	0x22,  0x3E,  0x22,  0x05,  0xBE,  0x18,  0x80,  0x67,  0x10,  0x02,  0x60,  0x01,  0x8C,  0x7F,  0xF6,  0x02, 	/* 43E20 */
+	0xB1,  0x0C,  0x8C,  0x30,  0x82,  0x00,  0x80,  0xB1,  0x08,  0x20,  0x08,  0x20,  0x0B,  0xFE,  0x72,  0x20, 	/* 43E30 */
+	0x14,  0x48,  0x08,  0x9C,  0x0D,  0xE2,  0x12,  0x2A,  0x7D,  0x28,  0x08,  0x28,  0x2C,  0x48,  0x2A,  0x48, 	/* 43E40 */
+	0x2A,  0x88,  0x2A,  0x89,  0x49,  0x09,  0x0A,  0x07,  0xB2,  0x08,  0x10,  0x08,  0x10,  0x0A,  0x14,  0x72, 	/* 43E50 */
+	0xE4,  0x14,  0x28,  0x08,  0x10,  0x0C,  0x18,  0x12,  0x24,  0x7D,  0xFA,  0x09,  0x12,  0x08,  0x10,  0x2A, 	/* 43E60 */
+	0x54,  0x29,  0x54,  0x29,  0x52,  0x48,  0x92,  0x08,  0x10,  0xB3,  0x08,  0x20,  0x08,  0x20,  0x0A,  0x3E, 	/* 43E70 */
+	0x72,  0x42,  0x14,  0xA4,  0x09,  0x18,  0x0C,  0x24,  0x12,  0x43,  0x7D,  0x88,  0x08,  0x7E,  0x2C,  0x48, 	/* 43E80 */
+	0x2A,  0x48,  0x2B,  0xFF,  0x2A,  0x08,  0x48,  0x08,  0x08,  0x08,  0xB5,  0x08,  0x10,  0x08,  0x10,  0x0A, 	/* 43E90 */
+	0x28,  0x72,  0x28,  0x14,  0x44,  0x08,  0x82,  0x0D,  0x7D,  0x12,  0x00,  0x7E,  0x00,  0x09,  0xFE,  0x2C, 	/* 43EA0 */
+	0x20,  0x2A,  0x28,  0x2A,  0x44,  0x2A,  0x5C,  0x49,  0xE2,  0x08,  0x02,  0xB6,  0x08,  0x20,  0x08,  0x3C, 	/* 43EB0 */
+	0x0A,  0x48,  0x72,  0x48,  0x14,  0x90,  0x09,  0xFE,  0x0C,  0x92,  0x12,  0x92,  0x7D,  0x92,  0x08,  0xFE, 	/* 43EC0 */
+	0x2C,  0x80,  0x2A,  0x80,  0x2A,  0x81,  0x2A,  0x41,  0x48,  0x3F,  0x08,  0x00,  0xB9,  0x08,  0x00,  0x08, 	/* 43ED0 */
+	0x7E,  0x0A,  0x42,  0x72,  0x42,  0x14,  0x7E,  0x08,  0x00,  0x0A,  0x7E,  0x12,  0x42,  0x7F,  0x42,  0x09, 	/* 43EE0 */
+	0x7E,  0x2C,  0x42,  0x2A,  0x42,  0x2A,  0x7E,  0x29,  0x42,  0x48,  0x42,  0x08,  0x46,  0xBD,  0x08,  0x00, 	/* 43EF0 */
+	0x08,  0x7E,  0x0A,  0x42,  0x72,  0x42,  0x14,  0x42,  0x08,  0x7E,  0x0C,  0x10,  0x12,  0x10,  0x7D,  0x20, 	/* 43F00 */
+	0x09,  0x7E,  0x28,  0x42,  0x2A,  0x42,  0x29,  0x42,  0x29,  0x42,  0x48,  0x7E,  0x08,  0x00,  0x89,  0x08, 	/* 43F10 */
+	0x04,  0x08,  0x18,  0x0A,  0xF0,  0x72,  0x10,  0x15,  0xFF,  0x08,  0x38,  0x08,  0x54,  0x12,  0x92,  0x7F, 	/* 43F20 */
+	0x11,  0x09,  0xF8,  0x28,  0x28,  0x2A,  0x2E,  0x29,  0x22,  0x29,  0x42,  0x48,  0x82,  0x09,  0x0C,  0x8F, 	/* 43F30 */
+	0x08,  0x04,  0x08,  0x18,  0x0A,  0xE8,  0x72,  0x24,  0x14,  0x92,  0x08,  0x92,  0x09,  0x00,  0x14,  0x20, 	/* 43F40 */
+	0x7F,  0xFF,  0x08,  0x24,  0x28,  0x44,  0x2C,  0xE8,  0x2A,  0x98,  0x2A,  0x24,  0x48,  0x42,  0x09,  0x82, 	/* 43F50 */
+	0x93,  0x08,  0x00,  0x09,  0xFE,  0x0A,  0x00,  0x72,  0x54,  0x14,  0x54,  0x08,  0xA8,  0x0C,  0xA8,  0x12, 	/* 43F60 */
+	0x54,  0x7D,  0x54,  0x08,  0x00,  0x2C,  0xFE,  0x2A,  0x10,  0x2A,  0x10,  0x28,  0x10,  0x49,  0xFF,  0x08, 	/* 43F70 */
+	0x00,  0x99,  0x08,  0x88,  0x08,  0xCA,  0x0A,  0xAA,  0x72,  0xAC,  0x14,  0x88,  0x08,  0xFF,  0x0C,  0x88, 	/* 43F80 */
+	0x12,  0x9C,  0x7D,  0x9C,  0x08,  0xAA,  0x2C,  0xAA,  0x2A,  0xC9,  0x2A,  0x88,  0x2A,  0x88,  0x48,  0xFF, 	/* 43F90 */
+	0x08,  0x80,  0x9A,  0x08,  0x10,  0x08,  0x10,  0x0B,  0xFF,  0x72,  0x10,  0x14,  0x10,  0x08,  0xFE,  0x0C, 	/* 43FA0 */
+	0x00,  0x12,  0xFF,  0x7D,  0x81,  0x09,  0xA9,  0x28,  0x28,  0x2A,  0x28,  0x29,  0x48,  0x29,  0x49,  0x48, 	/* 43FB0 */
+	0x89,  0x09,  0x07,  0x9B,  0x08,  0x00,  0x08,  0xFE,  0x0A,  0x12,  0x72,  0x12,  0x14,  0xD2,  0x08,  0x32, 	/* 43FC0 */
+	0x0C,  0x2A,  0x12,  0x42,  0x7E,  0x8C,  0x09,  0x10,  0x2C,  0x08,  0x2A,  0xA8,  0x2A,  0xA2,  0x28,  0xA5, 	/* 43FD0 */
+	0x49,  0x25,  0x08,  0x1C,  0x9C,  0x08,  0x10,  0x08,  0x10,  0x0A,  0xFF,  0x72,  0x81,  0x14,  0x81,  0x08, 	/* 43FE0 */
+	0xFE,  0x0C,  0x00,  0x12,  0x00,  0x7D,  0xFF,  0x08,  0x10,  0x2C,  0x14,  0x2A,  0x52,  0x2A,  0x52,  0x2A, 	/* 43FF0 */
+	0x91,  0x49,  0x10,  0x08,  0x30,  0x9F,  0x08,  0x00,  0x09,  0xFF,  0x0A,  0x00,  0x72,  0xFE,  0x14,  0x82, 	/* 44000 */
+	0x08,  0x82,  0x0C,  0xFE,  0x12,  0x90,  0x7D,  0x90,  0x08,  0xFF,  0x2C,  0x90,  0x2A,  0x98,  0x2B,  0x28, 	/* 44010 */
+	0x29,  0x24,  0x4A,  0x42,  0x08,  0x81,  0xA2,  0x08,  0x00,  0x08,  0xFE,  0x0A,  0x82,  0x72,  0x92,  0x14, 	/* 44020 */
+	0xFE,  0x08,  0x92,  0x0C,  0x92,  0x12,  0xFE,  0x7D,  0x92,  0x08,  0xBA,  0x28,  0xAA,  0x2C,  0xAA,  0x2A, 	/* 44030 */
+	0xBA,  0x2A,  0x82,  0x49,  0x02,  0x0A,  0x06,  0xA3,  0x08,  0x10,  0x08,  0x54,  0x0A,  0x92,  0x72,  0xFE, 	/* 44040 */
+	0x14,  0x10,  0x04,  0x28,  0x0D,  0xFF,  0x12,  0x28,  0x7D,  0x44,  0x08,  0xFE,  0x2D,  0x09,  0x2A,  0x08, 	/* 44050 */
+	0x2A,  0x78,  0x2A,  0x44,  0x48,  0x44,  0x08,  0x3C,  0xAB,  0x08,  0x28,  0x08,  0x24,  0x0A,  0x2E,  0x73, 	/* 44060 */
+	0xF2,  0x14,  0x14,  0x08,  0x18,  0x08,  0x65,  0x15,  0xAB,  0x7E,  0x24,  0x08,  0x2F,  0x2D,  0xF2,  0x2A, 	/* 44070 */
+	0x14,  0x2A,  0x18,  0x28,  0x65,  0x49,  0x83,  0x08,  0x01,  0xAC,  0x08,  0x04,  0x08,  0x18,  0x0B,  0xE2, 	/* 44080 */
+	0x72,  0x92,  0x14,  0x54,  0x09,  0xFE,  0x0D,  0x02,  0x13,  0x02,  0x7D,  0xFC,  0x09,  0x44,  0x2C,  0x44, 	/* 44090 */
+	0x2A,  0x28,  0x2A,  0x10,  0x2A,  0x30,  0x48,  0x4C,  0x09,  0x83,  0xAD,  0x08,  0x20,  0x08,  0x24,  0x0A, 	/* 440A0 */
+	0x24,  0x72,  0x48,  0x14,  0x7F,  0x08,  0xC8,  0x0B,  0x48,  0x12,  0x7E,  0x7F,  0x48,  0x09,  0x48,  0x2C, 	/* 440B0 */
+	0x7E,  0x2A,  0x48,  0x29,  0x48,  0x29,  0x48,  0x48,  0x7F,  0x08,  0x40,  0xAE,  0x00,  0x10,  0x3F,  0x90, 	/* 440C0 */
+	0x00,  0x3F,  0x1F,  0x44,  0x11,  0xA4,  0x1F,  0x18,  0x10,  0x18,  0x21,  0x64,  0x41,  0x23,  0x0E,  0x50, 	/* 440D0 */
+	0x01,  0x8C,  0x7F,  0xFA,  0x02,  0xB1,  0x0C,  0x8C,  0x30,  0x82,  0x00,  0x80,  0xAF,  0x08,  0x40,  0x08, 	/* 440E0 */
+	0x40,  0x0A,  0xFE,  0x72,  0x82,  0x15,  0x42,  0x08,  0x7A,  0x0C,  0xA2,  0x12,  0x22,  0x7D,  0xFE,  0x08, 	/* 440F0 */
+	0x22,  0x2C,  0xAA,  0x2A,  0xAA,  0x2A,  0xFA,  0x2A,  0x02,  0x48,  0x04,  0x08,  0x18,  0xB0,  0x08,  0x10, 	/* 44100 */
+	0x08,  0x10,  0x0A,  0xFF,  0x72,  0x81,  0x14,  0x81,  0x08,  0x7C,  0x0C,  0x44,  0x12,  0x44,  0x7D,  0x7C, 	/* 44110 */
+	0x09,  0x40,  0x28,  0x40,  0x2A,  0x7E,  0x29,  0x42,  0x29,  0x42,  0x48,  0x7E,  0x08,  0x00,  0xB1,  0x08, 	/* 44120 */
+	0x00,  0x08,  0xFE,  0x0A,  0x82,  0x72,  0xCA,  0x14,  0xAA,  0x08,  0x92,  0x0C,  0xFE,  0x12,  0x92,  0x7E, 	/* 44130 */
+	0x92,  0x09,  0xD6,  0x0C,  0xD6,  0x2A,  0xFE,  0x2A,  0x82,  0x2A,  0x82,  0x48,  0x82,  0x08,  0x86,  0xB2, 	/* 44140 */
+	0x08,  0x00,  0x09,  0xFE,  0x0B,  0x02,  0x73,  0x46,  0x15,  0x2A,  0x09,  0xFE,  0x0D,  0x12,  0x13,  0x12, 	/* 44150 */
+	0x7F,  0xFE,  0x0B,  0x22,  0x29,  0x22,  0x2D,  0x22,  0x2B,  0x1E,  0x2B,  0x02,  0x49,  0x02,  0x09,  0x06, 	/* 44160 */
+	0xB4,  0x08,  0x00,  0x09,  0xFE,  0x0A,  0x22,  0x72,  0xAA,  0x14,  0x44,  0x08,  0xAA,  0x0D,  0x11,  0x12, 	/* 44170 */
+	0x00,  0x7D,  0xFE,  0x08,  0x22,  0x2C,  0xAA,  0x2A,  0xCC,  0x2A,  0x44,  0x28,  0xAC,  0x49,  0x12,  0x0A, 	/* 44180 */
+	0x21,  0xB5,  0x08,  0x04,  0x08,  0x18,  0x0A,  0xE8,  0x72,  0x24,  0x14,  0x92,  0x08,  0x92,  0x0D,  0x00, 	/* 44190 */
+	0x12,  0x10,  0x7D,  0x10,  0x09,  0xFF,  0x2C,  0x38,  0x2A,  0x34,  0x2A,  0x52,  0x2A,  0x91,  0x49,  0x10, 	/* 441A0 */
+	0x08,  0x10,  0xB8,  0x08,  0x10,  0x08,  0x10,  0x0A,  0x28,  0x72,  0x44,  0x14,  0x82,  0x09,  0x79,  0x0C, 	/* 441B0 */
+	0x00,  0x12,  0x00,  0x7D,  0xFE,  0x08,  0xAA,  0x2C,  0xAA,  0x2A,  0xFE,  0x2A,  0xAA,  0x2A,  0xAA,  0x48, 	/* 441C0 */
+	0xAA,  0x08,  0x86,  0xBA,  0x08,  0x10,  0x08,  0x10,  0x0B,  0xFE,  0x72,  0x10,  0x14,  0x28,  0x08,  0xC4, 	/* 441D0 */
+	0x0D,  0x00,  0x12,  0xFF,  0x7D,  0x04,  0x09,  0x74,  0x28,  0x54,  0x2A,  0x54,  0x29,  0x74,  0x29,  0x04, 	/* 441E0 */
+	0x48,  0x04,  0x08,  0x0C,  0xBB,  0x08,  0x10,  0x08,  0x10,  0x0A,  0xFF,  0x72,  0x81,  0x14,  0x81,  0x08, 	/* 441F0 */
+	0xFE,  0x0C,  0x10,  0x12,  0x10,  0x7D,  0x50,  0x08,  0x5E,  0x2C,  0x50,  0x2A,  0x50,  0x2A,  0x50,  0x2A, 	/* 44200 */
+	0xB0,  0x48,  0x98,  0x09,  0x07,  0xBD,  0x08,  0x10,  0x08,  0x10,  0x0A,  0x1F,  0x72,  0x10,  0x14,  0x7E, 	/* 44210 */
+	0x08,  0x42,  0x0C,  0x7E,  0x12,  0x42,  0x7D,  0x42,  0x09,  0x7E,  0x28,  0x10,  0x2A,  0x10,  0x29,  0xFF, 	/* 44220 */
+	0x29,  0x10,  0x48,  0x10,  0x08,  0x10,  0xBE,  0x08,  0x20,  0x08,  0x20,  0x0B,  0xFC,  0x72,  0x20,  0x17, 	/* 44230 */
+	0xFF,  0x08,  0x50,  0x0A,  0x52,  0x12,  0x8E,  0x7F,  0x40,  0x0A,  0x7C,  0x2C,  0x88,  0x2B,  0x50,  0x2A, 	/* 44240 */
+	0x20,  0x2A,  0x50,  0x49,  0x8C,  0x0A,  0x03,  0xBF,  0x08,  0x10,  0x08,  0x20,  0x0A,  0x7C,  0x72,  0x44, 	/* 44250 */
+	0x14,  0x7C,  0x08,  0x44,  0x0C,  0x44,  0x12,  0x7C,  0x7D,  0x10,  0x08,  0xFE,  0x2C,  0x92,  0x2A,  0x92, 	/* 44260 */
+	0x2A,  0x92,  0x2A,  0x9C,  0x48,  0x10,  0x08,  0x10,  0x87,  0x08,  0x49,  0x08,  0x49,  0x0A,  0x92,  0x73, 	/* 44270 */
+	0x24,  0x14,  0x92,  0x08,  0x49,  0x0A,  0x00,  0x12,  0xFE,  0x7F,  0x92,  0x09,  0x92,  0x28,  0x92,  0x2C, 	/* 44280 */
+	0xFE,  0x2A,  0x92,  0x2A,  0x92,  0x48,  0xFE,  0x08,  0x00,  0x8A,  0x00,  0x00,  0x3F,  0xFC,  0x24,  0x44, 	/* 44290 */
+	0x3F,  0x24,  0x21,  0x28,  0x3F,  0x10,  0x24,  0x28,  0x3F,  0xC6,  0x01,  0x20,  0x0E,  0x50,  0x01,  0x8C, 	/* 442A0 */
+	0x7F,  0xFA,  0x05,  0x30,  0x19,  0x0C,  0x61,  0x02,  0x01,  0x00,  0x8B,  0x08,  0x28,  0x08,  0x28,  0x0A, 	/* 442B0 */
+	0x28,  0x72,  0xEE,  0x14,  0x28,  0x08,  0x28,  0x0C,  0x28,  0x12,  0xEE,  0x7D,  0x28,  0x08,  0x28,  0x2C, 	/* 442C0 */
+	0x68,  0x2B,  0xAF,  0x2A,  0x48,  0x2A,  0x48,  0x48,  0x88,  0x09,  0x08,  0x8F,  0x08,  0x3C,  0x08,  0x04, 	/* 442D0 */
+	0x0A,  0x44,  0x72,  0x52,  0x14,  0x92,  0x09,  0x29,  0x0C,  0x44,  0x12,  0xFC,  0x7D,  0x12,  0x08,  0x08, 	/* 442E0 */
+	0x2C,  0xA8,  0x2A,  0xAA,  0x2A,  0xA1,  0x29,  0x25,  0x4A,  0x25,  0x08,  0x1C,  0x91,  0x08,  0x00,  0x08, 	/* 442F0 */
+	0xFC,  0x0A,  0x04,  0x72,  0xFC,  0x14,  0x04,  0x08,  0x04,  0x0D,  0xFF,  0x12,  0x10,  0x7D,  0x92,  0x09, 	/* 44300 */
+	0x52,  0x2C,  0x5C,  0x2A,  0x38,  0x2A,  0x54,  0x28,  0x92,  0x4B,  0x11,  0x08,  0x30,  0x92,  0x08,  0x20, 	/* 44310 */
+	0x08,  0x24,  0x0A,  0xFC,  0x72,  0x28,  0x14,  0x28,  0x08,  0x30,  0x0D,  0xFF,  0x12,  0x20,  0x7D,  0x7C, 	/* 44320 */
+	0x08,  0x44,  0x2C,  0xC4,  0x2B,  0x7C,  0x2A,  0x44,  0x2A,  0x44,  0x48,  0x7C,  0x08,  0x00,  0x95,  0x08, 	/* 44330 */
+	0x10,  0x08,  0x10,  0x0B,  0xFF,  0x72,  0x44,  0x14,  0x28,  0x08,  0x10,  0x0C,  0x6C,  0x12,  0xC7,  0x7D, 	/* 44340 */
+	0x44,  0x08,  0x7C,  0x2C,  0x44,  0x2A,  0x7C,  0x2A,  0x84,  0x28,  0x84,  0x49,  0x04,  0x0A,  0x04,  0x98, 	/* 44350 */
+	0x08,  0x08,  0x08,  0x0A,  0x0A,  0x09,  0x72,  0xFF,  0x14,  0x88,  0x08,  0xF8,  0x0C,  0x8A,  0x12,  0x8A, 	/* 44360 */
+	0x7D,  0xFA,  0x08,  0xDA,  0x2C,  0xDC,  0x2A,  0xF5,  0x2A,  0x8D,  0x29,  0x13,  0x49,  0x23,  0x0A,  0x41, 	/* 44370 */
+	0x9A,  0x08,  0x10,  0x08,  0x20,  0x0A,  0xFC,  0x72,  0x84,  0x14,  0xFC,  0x08,  0x84,  0x0C,  0x84,  0x12, 	/* 44380 */
+	0xFC,  0x7D,  0x10,  0x08,  0x12,  0x2D,  0xFC,  0x2A,  0x58,  0x2A,  0x54,  0x2A,  0x92,  0x49,  0x11,  0x08, 	/* 44390 */
+	0x30,  0x9C,  0x08,  0x06,  0x10,  0xF8,  0x3E,  0x10,  0x22,  0x10,  0x22,  0x64,  0x3E,  0x28,  0x22,  0x14, 	/* 443A0 */
+	0x22,  0x22,  0x3E,  0xFE,  0x08,  0x11,  0x7F,  0x14,  0x49,  0x54,  0x49,  0x52,  0x49,  0x52,  0x4B,  0x92, 	/* 443B0 */
+	0x08,  0x10,  0x9D,  0x08,  0x00,  0x08,  0xFC,  0x0A,  0x84,  0x72,  0x84,  0x14,  0xFC,  0x08,  0x00,  0x0D, 	/* 443C0 */
+	0xFF,  0x12,  0x84,  0x7D,  0xFC,  0x08,  0x84,  0x28,  0xFC,  0x2C,  0x84,  0x2A,  0x87,  0x2A,  0xFC,  0x4B, 	/* 443D0 */
+	0x84,  0x08,  0x04,  0x9E,  0x08,  0x20,  0x09,  0xDC,  0x0B,  0x14,  0x73,  0x15,  0x15,  0xD5,  0x19,  0x27, 	/* 443E0 */
+	0x09,  0x40,  0x15,  0xFE,  0x7F,  0x12,  0x09,  0x12,  0x2D,  0x14,  0x2D,  0xC8,  0x2B,  0x0C,  0x29,  0x14, 	/* 443F0 */
+	0x49,  0x22,  0x09,  0x41,  0xA0,  0x08,  0x10,  0x08,  0x10,  0x0A,  0xFE,  0x72,  0x44,  0x14,  0x24,  0x08, 	/* 44400 */
+	0x28,  0x0D,  0xFF,  0x13,  0x11,  0x7D,  0x11,  0x08,  0xFE,  0x2C,  0x92,  0x2A,  0x92,  0x2A,  0x92,  0x2A, 	/* 44410 */
+	0x9C,  0x48,  0x10,  0x08,  0x10,  0xA1,  0x08,  0x00,  0x08,  0xFE,  0x0A,  0x82,  0x72,  0xFE,  0x14,  0x88, 	/* 44420 */
+	0x08,  0xFF,  0x0C,  0x88,  0x12,  0x85,  0x7E,  0xE3,  0x09,  0x01,  0x2C,  0xFE,  0x2A,  0x82,  0x2A,  0xFE, 	/* 44430 */
+	0x2A,  0x82,  0x48,  0xFE,  0x08,  0x00,  0xA4,  0x08,  0x94,  0x08,  0x94,  0x0B,  0xFF,  0x72,  0x94,  0x14, 	/* 44440 */
+	0x94,  0x08,  0x9C,  0x0C,  0x80,  0x12,  0xFE,  0x7D,  0x10,  0x09,  0xFF,  0x0C,  0x10,  0x2A,  0x38,  0x2A, 	/* 44450 */
+	0x54,  0x28,  0x92,  0x4B,  0x11,  0x08,  0x10,  0xA8,  0x08,  0x00,  0x09,  0xFF,  0x0A,  0x00,  0x72,  0xFE, 	/* 44460 */
+	0x14,  0x82,  0x08,  0x82,  0x0C,  0xFE,  0x12,  0x80,  0x7D,  0xFF,  0x08,  0xD5,  0x2C,  0xD5,  0x2A,  0xFF, 	/* 44470 */
+	0x29,  0x55,  0x29,  0x55,  0x4A,  0x55,  0x08,  0x43,  0xA9,  0x08,  0x04,  0x08,  0x1A,  0x0B,  0xE2,  0x72, 	/* 44480 */
+	0x24,  0x14,  0x94,  0x08,  0x58,  0x0D,  0xFE,  0x12,  0x40,  0x7D,  0xFF,  0x08,  0x40,  0x2C,  0x7C,  0x2A, 	/* 44490 */
+	0xA4,  0x2A,  0x98,  0x2B,  0x10,  0x48,  0x6C,  0x09,  0x83,  0xAC,  0x08,  0x00,  0x09,  0xFF,  0x0A,  0x20, 	/* 444A0 */
+	0x72,  0x40,  0x15,  0xFE,  0x09,  0x4A,  0x0D,  0x4A,  0x13,  0x7A,  0x7D,  0x4A,  0x09,  0x4A,  0x29,  0x7A, 	/* 444B0 */
+	0x2D,  0x4A,  0x2B,  0x4A,  0x49,  0x4A,  0x09,  0xFE,  0x09,  0x02,  0xAF,  0x08,  0x10,  0x08,  0xFC,  0x0A, 	/* 444C0 */
+	0x24,  0x72,  0x24,  0x17,  0xFF,  0x08,  0x00,  0x0A,  0x7E,  0x12,  0x42,  0x7F,  0x7E,  0x09,  0x08,  0x2C, 	/* 444D0 */
+	0x7E,  0x2A,  0x48,  0x2A,  0x48,  0x29,  0xFF,  0x48,  0x08,  0x08,  0x08,  0xB2,  0x10,  0x08,  0x13,  0x88, 	/* 444E0 */
+	0x16,  0x88,  0x66,  0xAA,  0x2B,  0xAA,  0x12,  0xA9,  0x1A,  0xA9,  0x26,  0xC8,  0x7B,  0x8A,  0x12,  0x9A, 	/* 444F0 */
+	0x32,  0x84,  0x3A,  0x84,  0x37,  0x88,  0x54,  0x10,  0x10,  0x20,  0x10,  0x40,  0xB4,  0x08,  0x10,  0x08, 	/* 44500 */
+	0x10,  0x13,  0xFF,  0x72,  0x10,  0x14,  0xFE,  0x08,  0x92,  0x0C,  0xFE,  0x12,  0x92,  0x7D,  0x92,  0x08, 	/* 44510 */
+	0xFE,  0x2C,  0x38,  0x2A,  0x54,  0x2A,  0x54,  0x2A,  0x92,  0x49,  0x11,  0x08,  0x10,  0xBB,  0x10,  0x10, 	/* 44520 */
+	0x13,  0xF0,  0x14,  0x90,  0x64,  0x9F,  0x19,  0x54,  0x11,  0x24,  0x17,  0xE4,  0x28,  0x94,  0x7C,  0x94, 	/* 44530 */
+	0x13,  0xD4,  0x38,  0x88,  0x34,  0xA8,  0x34,  0xD4,  0x53,  0x14,  0x10,  0x22,  0x10,  0x41,  0x81,  0x08, 	/* 44540 */
+	0x00,  0x08,  0xF8,  0x0A,  0x08,  0x72,  0xF8,  0x14,  0x08,  0x09,  0xFF,  0x0A,  0x20,  0x12,  0x52,  0x7F, 	/* 44550 */
+	0x94,  0x09,  0x38,  0x2C,  0x58,  0x2A,  0xB4,  0x2A,  0x52,  0x2B,  0x91,  0x48,  0x10,  0x08,  0x60,  0x84, 	/* 44560 */
+	0x08,  0x00,  0x08,  0xFC,  0x0A,  0x94,  0x72,  0xFC,  0x14,  0x94,  0x08,  0x94,  0x0A,  0xFC,  0x12,  0x10, 	/* 44570 */
+	0x7F,  0xFE,  0x09,  0x92,  0x2C,  0xFE,  0x2A,  0x92,  0x2A,  0x92,  0x4A,  0xFE,  0x48,  0x11,  0x08,  0x0F, 	/* 44580 */
+	0x85,  0x08,  0x0C,  0x08,  0x0A,  0x0A,  0x08,  0x73,  0xFF,  0x15,  0x08,  0x09,  0xF8,  0x0D,  0x0A,  0x13, 	/* 44590 */
+	0x2A,  0x7F,  0xFA,  0x09,  0x5A,  0x2D,  0x54,  0x2B,  0xE4,  0x2B,  0x35,  0x49,  0x4B,  0x09,  0x13,  0x0A, 	/* 445A0 */
+	0x21,  0x89,  0x08,  0x00,  0x08,  0xFF,  0x0A,  0x44,  0x72,  0x44,  0x14,  0x44,  0x08,  0xAA,  0x0D,  0xDD, 	/* 445B0 */
+	0x12,  0x00,  0x7D,  0xFF,  0x08,  0x00,  0x2C,  0xFE,  0x2A,  0x82,  0x2A,  0xFE,  0x2A,  0x82,  0x48,  0xFE, 	/* 445C0 */
+	0x08,  0x00,  0x8A,  0x08,  0x58,  0x08,  0x48,  0x0A,  0x48,  0x72,  0xBC,  0x14,  0x84,  0x09,  0x7A,  0x0E, 	/* 445D0 */
+	0x09,  0x14,  0x84,  0x7E,  0x84,  0x09,  0xFE,  0x2B,  0x55,  0x2D,  0x54,  0x2D,  0x54,  0x29,  0x54,  0x4B, 	/* 445E0 */
+	0xFF,  0x08,  0x00,  0x8B,  0x09,  0x08,  0x08,  0x90,  0x10,  0xBE,  0x64,  0x22,  0x16,  0x22,  0x19,  0x3E, 	/* 445F0 */
+	0x09,  0x20,  0x14,  0x20,  0x7F,  0xBE,  0x08,  0xA2,  0x2C,  0xA2,  0x2A,  0xA2,  0x2A,  0xBE,  0x29,  0x40, 	/* 44600 */
+	0x4A,  0x30,  0x0C,  0x0F,  0x92,  0x08,  0x84,  0x08,  0x48,  0x0A,  0xFE,  0x72,  0x20,  0x14,  0x20,  0x09, 	/* 44610 */
+	0xFC,  0x0C,  0x20,  0x12,  0x20,  0x7F,  0xFE,  0x0A,  0x40,  0x28,  0x80,  0x2C,  0xFE,  0x2B,  0x10,  0x2A, 	/* 44620 */
+	0x10,  0x49,  0xFF,  0x08,  0x00,  0x9B,  0x08,  0x14,  0x08,  0x12,  0x0B,  0xFF,  0x72,  0x10,  0x14,  0xFE, 	/* 44630 */
+	0x08,  0x92,  0x0C,  0xFE,  0x12,  0x92,  0x7D,  0xFE,  0x09,  0x04,  0x2C,  0xFF,  0x2A,  0x44,  0x2A,  0x24, 	/* 44640 */
+	0x2A,  0x24,  0x48,  0x04,  0x08,  0x0C,  0x9E,  0x08,  0x10,  0x08,  0x10,  0x0A,  0xFF,  0x72,  0x00,  0x14, 	/* 44650 */
+	0x7C,  0x08,  0x44,  0x0C,  0x7C,  0x12,  0x00,  0x7D,  0xFE,  0x09,  0x82,  0x2C,  0xBA,  0x2A,  0xAA,  0x2A, 	/* 44660 */
+	0xAA,  0x2A,  0xBA,  0x48,  0x82,  0x08,  0x86,  0x9F,  0x08,  0x00,  0x08,  0xFF,  0x0A,  0x80,  0x72,  0xBE, 	/* 44670 */
+	0x14,  0x80,  0x08,  0xFF,  0x08,  0xB2,  0x14,  0xAC,  0x7D,  0x24,  0x0A,  0x63,  0x2C,  0x04,  0x2A,  0xFF, 	/* 44680 */
+	0x2A,  0x44,  0x2A,  0x24,  0x48,  0x24,  0x08,  0x0C,  0xA1,  0x08,  0x10,  0x08,  0x10,  0x0A,  0xFF,  0x72, 	/* 44690 */
+	0x81,  0x14,  0x90,  0x09,  0xFF,  0x0C,  0x44,  0x12,  0x28,  0x7D,  0xFF,  0x09,  0x10,  0x28,  0x10,  0x2A, 	/* 446A0 */
+	0xFE,  0x29,  0x10,  0x29,  0x10,  0x48,  0x10,  0x08,  0x10,  0xA2,  0x00,  0x20,  0x3C,  0xA8,  0x25,  0x24, 	/* 446B0 */
+	0x25,  0xFE,  0x24,  0x50,  0x3F,  0xFF,  0x24,  0x48,  0x24,  0xA4,  0x25,  0x2A,  0x3E,  0xD1,  0x24,  0x2C, 	/* 446C0 */
+	0x25,  0xFA,  0x24,  0x20,  0x24,  0xAC,  0x27,  0x22,  0x4C,  0x20,  0xA3,  0x00,  0x02,  0x1E,  0xFC,  0x52, 	/* 446D0 */
+	0x10,  0x5E,  0x14,  0x52,  0xE4,  0x5E,  0x28,  0x52,  0x10,  0x52,  0x24,  0x5E,  0xFE,  0x40,  0x11,  0x7F, 	/* 446E0 */
+	0x98,  0x08,  0x54,  0x2A,  0x52,  0x29,  0x52,  0x49,  0x90,  0x08,  0x10,  0xA6,  0x08,  0x22,  0x08,  0x52, 	/* 446F0 */
+	0x0A,  0x54,  0x72,  0x94,  0x14,  0xFF,  0x09,  0x08,  0x0C,  0x48,  0x14,  0x68,  0x7A,  0xA8,  0x08,  0xAE, 	/* 44700 */
+	0x2D,  0x28,  0x2B,  0x28,  0x29,  0x58,  0x29,  0x48,  0x49,  0x84,  0x09,  0x03,  0xAB,  0x08,  0x10,  0x08, 	/* 44710 */
+	0x1E,  0x0A,  0x22,  0x72,  0x54,  0x15,  0x08,  0x09,  0x14,  0x0C,  0x63,  0x13,  0x88,  0x7E,  0xBE,  0x0A, 	/* 44720 */
+	0x88,  0x28,  0xBE,  0x2C,  0x88,  0x2A,  0xFF,  0x49,  0x48,  0x09,  0x30,  0x0A,  0x0F,  0xAE,  0x08,  0x10, 	/* 44730 */
+	0x08,  0x10,  0x0A,  0xFE,  0x72,  0x82,  0x14,  0xC2,  0x08,  0x7E,  0x0A,  0x48,  0x12,  0x90,  0x7F,  0xBE, 	/* 44740 */
+	0x09,  0xA2,  0x28,  0xA2,  0x2C,  0xBE,  0x2A,  0xA2,  0x4A,  0xA2,  0x08,  0xBE,  0x08,  0x80,  0xB1,  0x08, 	/* 44750 */
+	0x92,  0x08,  0x92,  0x10,  0x92,  0x75,  0x35,  0x15,  0x2D,  0x0A,  0x48,  0x08,  0x00,  0x14,  0x88,  0x7E, 	/* 44760 */
+	0xA8,  0x09,  0x2E,  0x2B,  0x28,  0x2D,  0x28,  0x2D,  0x28,  0x4D,  0x58,  0x09,  0x48,  0x09,  0x87,  0xB2, 	/* 44770 */
+	0x08,  0x00,  0x08,  0xFE,  0x0A,  0x92,  0x72,  0xFE,  0x14,  0x92,  0x08,  0xFE,  0x0C,  0x10,  0x12,  0x24, 	/* 44780 */
+	0x7D,  0xE8,  0x08,  0x12,  0x2D,  0xFD,  0x2A,  0x50,  0x2A,  0x54,  0x2A,  0x92,  0x49,  0x11,  0x08,  0x10, 	/* 44790 */
+	0xB5,  0x08,  0x00,  0x08,  0x7C,  0x0A,  0x44,  0x72,  0x7C,  0x14,  0x44,  0x08,  0x7C,  0x0C,  0x00,  0x12, 	/* 447A0 */
+	0xFF,  0x7D,  0xA9,  0x08,  0xFF,  0x2C,  0x00,  0x2A,  0xFE,  0x2A,  0x24,  0x2A,  0x18,  0x48,  0x6C,  0x09, 	/* 447B0 */
+	0x83,  0xB7,  0x08,  0x10,  0x08,  0xFE,  0x0A,  0x92,  0x73,  0xFF,  0x14,  0x92,  0x08,  0xFE,  0x0C,  0x10, 	/* 447C0 */
+	0x12,  0xFE,  0x7D,  0x92,  0x08,  0xFE,  0x2C,  0x20,  0x2B,  0xFF,  0x2A,  0x44,  0x2A,  0xF8,  0x48,  0x2C, 	/* 447D0 */
+	0x09,  0xC2,  0xB9,  0x08,  0x00,  0x08,  0xFF,  0x0A,  0x28,  0x72,  0xFE,  0x14,  0xAA,  0x08,  0xAA,  0x0A, 	/* 447E0 */
+	0xFE,  0x12,  0x00,  0x7F,  0x7E,  0x09,  0x00,  0x2C,  0xFF,  0x2A,  0x50,  0x2A,  0x54,  0x2A,  0x92,  0x49, 	/* 447F0 */
+	0x11,  0x08,  0x30,  0xBA,  0x08,  0x08,  0x08,  0x88,  0x10,  0x7F,  0x64,  0x48,  0x14,  0x3E,  0x09,  0x2A, 	/* 44800 */
+	0x08,  0xAA,  0x14,  0xBE,  0x7E,  0x2A,  0x09,  0xAA,  0x2C,  0xBE,  0x2A,  0x88,  0x2A,  0xFF,  0x28,  0x88, 	/* 44810 */
+	0x49,  0x48,  0x0A,  0x3F,  0xBB,  0x00,  0x80,  0x1F,  0xFF,  0x11,  0x08,  0x1F,  0xFF,  0x11,  0x08,  0x15, 	/* 44820 */
+	0xAA,  0x15,  0xAA,  0x19,  0x4B,  0x11,  0x48,  0x10,  0x90,  0x13,  0x28,  0x10,  0xC6,  0x2F,  0xFD,  0x20, 	/* 44830 */
+	0x50,  0x43,  0x4C,  0x0C,  0x42,  0xBD,  0x08,  0x10,  0x08,  0x20,  0x0A,  0xFE,  0x72,  0x92,  0x14,  0xDE, 	/* 44840 */
+	0x08,  0xA6,  0x0C,  0xEA,  0x12,  0x92,  0x7D,  0xAA,  0x08,  0xC6,  0x2C,  0xFE,  0x2A,  0x90,  0x2A,  0xAA, 	/* 44850 */
+	0x28,  0xA1,  0x49,  0x25,  0x08,  0x1C,  0xBE,  0x08,  0x10,  0x09,  0xFF,  0x0A,  0x10,  0x72,  0xFE,  0x14, 	/* 44860 */
+	0x10,  0x09,  0xFF,  0x0C,  0x00,  0x12,  0x7C,  0x7D,  0x44,  0x09,  0x7C,  0x28,  0x44,  0x2A,  0x7C,  0x29, 	/* 44870 */
+	0x44,  0x29,  0x7C,  0x48,  0x4C,  0x09,  0x82,  0x81,  0x10,  0x20,  0x1F,  0xA0,  0x10,  0x3F,  0x3F,  0x24, 	/* 44880 */
+	0x55,  0x64,  0x1F,  0x98,  0x25,  0x08,  0x3F,  0x94,  0x20,  0xE3,  0x03,  0x20,  0x0E,  0x50,  0x01,  0x8C, 	/* 44890 */
+	0x7F,  0xFA,  0x04,  0xB0,  0x18,  0x8C,  0x60,  0x82,  0x83,  0x08,  0x10,  0x08,  0x92,  0x0A,  0x92,  0x72, 	/* 448A0 */
+	0xFE,  0x14,  0x00,  0x08,  0xEE,  0x0C,  0xAA,  0x12,  0xAA,  0x7E,  0xEE,  0x09,  0xAA,  0x2C,  0xAA,  0x2A, 	/* 448B0 */
+	0xEE,  0x2A,  0xAA,  0x2A,  0xAA,  0x48,  0xAA,  0x09,  0x36,  0x86,  0x08,  0x00,  0x09,  0xFE,  0x0A,  0x66, 	/* 448C0 */
+	0x72,  0xAA,  0x14,  0x66,  0x09,  0xBA,  0x0C,  0x26,  0x12,  0x30,  0x7E,  0x4C,  0x09,  0x93,  0x2C,  0xE4, 	/* 448D0 */
+	0x2A,  0x18,  0x2A,  0x62,  0x2A,  0x04,  0x48,  0x18,  0x08,  0xE0,  0x8A,  0x08,  0x88,  0x08,  0x8C,  0x0B, 	/* 448E0 */
+	0xEA,  0x72,  0x8A,  0x14,  0x88,  0x0B,  0xFF,  0x09,  0x48,  0x15,  0x4A,  0x7F,  0x5A,  0x09,  0x6A,  0x2D, 	/* 448F0 */
+	0x4C,  0x2B,  0x44,  0x29,  0x4D,  0x29,  0xF5,  0x4F,  0x23,  0x08,  0x41,  0x8B,  0x04,  0x00,  0x7F,  0xBC, 	/* 44900 */
+	0x04,  0x25,  0x3F,  0x25,  0x25,  0x43,  0x3F,  0xFC,  0x25,  0x24,  0x3F,  0x18,  0x04,  0xA4,  0x7F,  0xA3, 	/* 44910 */
+	0x07,  0x50,  0x01,  0x8C,  0x7F,  0xFA,  0x05,  0x21,  0x19,  0x18,  0x61,  0x04,  0x8D,  0x08,  0x10,  0x08, 	/* 44920 */
+	0xFC,  0x0A,  0x14,  0x73,  0xFF,  0x14,  0x14,  0x08,  0xFC,  0x0C,  0x12,  0x14,  0x92,  0x7E,  0xD6,  0x0A, 	/* 44930 */
+	0xBA,  0x2C,  0xFE,  0x2A,  0x92,  0x2A,  0xBA,  0x29,  0x56,  0x49,  0x92,  0x0A,  0x12,  0x94,  0x10,  0x88, 	/* 44940 */
+	0x10,  0x8C,  0x17,  0xFA,  0x66,  0x2A,  0x29,  0x28,  0x11,  0x48,  0x1B,  0xFF,  0x24,  0x0A,  0x7D,  0xEA, 	/* 44950 */
+	0x15,  0x2A,  0x39,  0xE4,  0x35,  0x2C,  0x35,  0x2D,  0x51,  0xF5,  0x10,  0x13,  0x10,  0x21,  0x95,  0x08, 	/* 44960 */
+	0x82,  0x08,  0x44,  0x0A,  0xFF,  0x72,  0x10,  0x14,  0x7E,  0x08,  0x10,  0x0D,  0xFF,  0x12,  0x92,  0x7D, 	/* 44970 */
+	0x54,  0x09,  0xFF,  0x28,  0x00,  0x2A,  0x7E,  0x29,  0x42,  0x29,  0x42,  0x48,  0x7E,  0x08,  0x00,  0x96, 	/* 44980 */
+	0x09,  0x48,  0x09,  0x48,  0x13,  0xE8,  0x65,  0x4F,  0x15,  0x52,  0x0B,  0xF2,  0x08,  0x2A,  0x15,  0xEA, 	/* 44990 */
+	0x7F,  0x2A,  0x09,  0xE4,  0x2D,  0x24,  0x2B,  0xE4,  0x2B,  0x2A,  0x29,  0x2A,  0x49,  0x32,  0x09,  0x61, 	/* 449A0 */
+	0x99,  0x08,  0x02,  0x08,  0xFC,  0x0A,  0x92,  0x72,  0x54,  0x05,  0xFF,  0x08,  0x38,  0x0C,  0x54,  0x12, 	/* 449B0 */
+	0x92,  0x7D,  0xFF,  0x08,  0x92,  0x2C,  0x92,  0x2A,  0xFE,  0x2A,  0x92,  0x2A,  0x92,  0x48,  0xFE,  0x08, 	/* 449C0 */
+	0x00,  0x9A,  0x08,  0x10,  0x08,  0x10,  0x0B,  0xFF,  0x72,  0x28,  0x14,  0xAA,  0x08,  0x44,  0x0C,  0xFE, 	/* 449D0 */
+	0x13,  0x45,  0x7E,  0x7C,  0x08,  0x44,  0x2C,  0x7C,  0x2A,  0x10,  0x2A,  0x94,  0x28,  0x92,  0x49,  0x11, 	/* 449E0 */
+	0x08,  0x30,  0x9D,  0x08,  0x00,  0x09,  0xEE,  0x13,  0x2A,  0x65,  0xEE,  0x15,  0x2A,  0x09,  0xEE,  0x09, 	/* 449F0 */
+	0x02,  0x15,  0x7A,  0x7F,  0x4A,  0x09,  0x7A,  0x2D,  0x4A,  0x2B,  0x7A,  0x2B,  0x4A,  0x29,  0x4A,  0x49, 	/* 44A00 */
+	0x5A,  0x09,  0x06,  0x9E,  0x08,  0x10,  0x08,  0x7C,  0x0A,  0x10,  0x72,  0xFE,  0x14,  0x00,  0x08,  0x44, 	/* 44A10 */
+	0x0D,  0xFF,  0x12,  0x44,  0x7D,  0x74,  0x09,  0xCF,  0x2C,  0x00,  0x2B,  0xFF,  0x2A,  0x48,  0x2A,  0x49, 	/* 44A20 */
+	0x48,  0x89,  0x09,  0x07,  0xA6,  0x08,  0x00,  0x0B,  0xDE,  0x10,  0x52,  0x74,  0x52,  0x14,  0x5E,  0x09, 	/* 44A30 */
+	0xC8,  0x0D,  0x3E,  0x15,  0x2A,  0x7F,  0xEA,  0x08,  0x6A,  0x0C,  0x7E,  0x2A,  0x4C,  0x2A,  0x4A,  0x28, 	/* 44A40 */
+	0x4A,  0x48,  0x8F,  0x0B,  0x71,  0xA7,  0x08,  0x00,  0x08,  0xFE,  0x0A,  0x10,  0x73,  0xFF,  0x15,  0x11, 	/* 44A50 */
+	0x09,  0xDD,  0x0D,  0x11,  0x12,  0xDC,  0x7D,  0x00,  0x08,  0xFE,  0x2C,  0x00,  0x2B,  0xFF,  0x2A,  0x20, 	/* 44A60 */
+	0x2A,  0x48,  0x49,  0xFC,  0x08,  0x02,  0xA9,  0x08,  0x00,  0x09,  0xFE,  0x09,  0x52,  0x73,  0x52,  0x15, 	/* 44A70 */
+	0xDE,  0x08,  0x50,  0x0C,  0x50,  0x13,  0xDE,  0x7D,  0x52,  0x09,  0x52,  0x2D,  0xDE,  0x2B,  0x52,  0x2B, 	/* 44A80 */
+	0x52,  0x29,  0xDE,  0x48,  0x41,  0x08,  0x3F,  0xAA,  0x08,  0x10,  0x08,  0x10,  0x0A,  0x28,  0x72,  0xFC, 	/* 44A90 */
+	0x17,  0x03,  0x09,  0xFE,  0x0D,  0xA6,  0x13,  0x6A,  0x7D,  0xFE,  0x08,  0x00,  0x2C,  0xFC,  0x2A,  0x84, 	/* 44AA0 */
+	0x2A,  0xFC,  0x2A,  0x84,  0x48,  0xFC,  0x08,  0x00,  0xAD,  0x04,  0x20,  0x7F,  0xFF,  0x04,  0x20,  0x00, 	/* 44AB0 */
+	0x00,  0x3F,  0xFE,  0x24,  0x92,  0x38,  0x92,  0x2A,  0xFE,  0x24,  0xD6,  0x2A,  0xD6,  0x3F,  0xFE,  0x24, 	/* 44AC0 */
+	0x9A,  0x2E,  0x96,  0x2D,  0x9E,  0x34,  0xE2,  0x24,  0x86,  0xB0,  0x08,  0x00,  0x08,  0x7C,  0x0A,  0x44, 	/* 44AD0 */
+	0x72,  0x44,  0x14,  0x7C,  0x09,  0xEF,  0x0D,  0x29,  0x13,  0x29,  0x7D,  0xEF,  0x08,  0x10,  0x2D,  0xFF, 	/* 44AE0 */
+	0x2A,  0x38,  0x2A,  0x54,  0x2A,  0x92,  0x49,  0x11,  0x08,  0x10,  0xB9,  0x08,  0x00,  0x09,  0xFE,  0x09, 	/* 44AF0 */
+	0x2A,  0x73,  0xFE,  0x14,  0x10,  0x08,  0xFE,  0x0C,  0x10,  0x13,  0xFF,  0x7D,  0x44,  0x08,  0x28,  0x2A, 	/* 44B00 */
+	0xFF,  0x29,  0x10,  0x29,  0xFE,  0x29,  0x10,  0x48,  0x10,  0x08,  0x10,  0xBB,  0x08,  0x00,  0x08,  0xFE, 	/* 44B10 */
+	0x0A,  0x10,  0x73,  0xFF,  0x15,  0x11,  0x09,  0xDD,  0x08,  0x11,  0x14,  0xDC,  0x7E,  0x00,  0x0B,  0xFF, 	/* 44B20 */
+	0x28,  0x20,  0x2D,  0xFE,  0x2B,  0x4A,  0x2B,  0x4A,  0x49,  0x4A,  0x09,  0x06,  0xBC,  0x08,  0x24,  0x09, 	/* 44B30 */
+	0x5A,  0x09,  0x24,  0x75,  0x5A,  0x15,  0xED,  0x09,  0x00,  0x0D,  0xFF,  0x13,  0x24,  0x7D,  0x24,  0x09, 	/* 44B40 */
+	0x5A,  0x2D,  0x24,  0x2B,  0x5A,  0x2B,  0xED,  0x29,  0x00,  0x49,  0xFF,  0x08,  0x00,  0xBD,  0x08,  0x20, 	/* 44B50 */
+	0x09,  0xFF,  0x0B,  0x01,  0x72,  0xFE,  0x14,  0xA4,  0x08,  0xA8,  0x0D,  0x30,  0x12,  0x7C,  0x7E,  0xC4, 	/* 44B60 */
+	0x09,  0x7C,  0x28,  0x44,  0x2C,  0x7C,  0x2A,  0x44,  0x2A,  0x7C,  0x48,  0x66,  0x0B,  0x81,  0xBF,  0x08, 	/* 44B70 */
+	0x04,  0x09,  0xF4,  0x0B,  0x47,  0x75,  0x48,  0x15,  0xF0,  0x09,  0x10,  0x0D,  0xF7,  0x13,  0x40,  0x7D, 	/* 44B80 */
+	0xF0,  0x08,  0x00,  0x2C,  0xFE,  0x2A,  0xAA,  0x2A,  0xAA,  0x2A,  0xAA,  0x49,  0xFF,  0x08,  0x00,  0x82, 	/* 44B90 */
+	0x10,  0x20,  0x1F,  0xBF,  0x22,  0x48,  0x47,  0xF0,  0x04,  0x10,  0x07,  0xF0,  0x04,  0x10,  0x07,  0xF0, 	/* 44BA0 */
+	0x04,  0x10,  0x7F,  0xFF,  0x04,  0xB0,  0x1B,  0x4C,  0x61,  0xB3,  0x1F,  0xEC,  0x04,  0xB0,  0x18,  0x88, 	/* 44BB0 */
+	0x83,  0x08,  0x10,  0x08,  0x10,  0x0B,  0xFF,  0x74,  0x28,  0x17,  0xD7,  0x09,  0x56,  0x09,  0x55,  0x16, 	/* 44BC0 */
+	0xD5,  0x7C,  0x00,  0x0A,  0x82,  0x28,  0xFE,  0x2C,  0x82,  0x2A,  0xFE,  0x29,  0x02,  0x49,  0x02,  0x0A, 	/* 44BD0 */
+	0x02,  0x88,  0x08,  0x80,  0x08,  0xBF,  0x08,  0x84,  0x77,  0xE8,  0x14,  0x9E,  0x18,  0x92,  0x0B,  0xD2, 	/* 44BE0 */
+	0x14,  0x1E,  0x7E,  0x12,  0x09,  0xDE,  0x2D,  0x52,  0x2D,  0x52,  0x2B,  0x5E,  0x29,  0xC4,  0x48,  0x12, 	/* 44BF0 */
+	0x08,  0x21,  0x89,  0x08,  0x44,  0x09,  0xFF,  0x0A,  0x44,  0x73,  0xFF,  0x14,  0x44,  0x08,  0xAA,  0x0D, 	/* 44C00 */
+	0x01,  0x12,  0xFC,  0x7D,  0x84,  0x08,  0xFC,  0x2C,  0x84,  0x2A,  0xFC,  0x2A,  0x84,  0x28,  0xFC,  0x48, 	/* 44C10 */
+	0xCC,  0x0B,  0x02,  0x8C,  0x08,  0x10,  0x09,  0xFF,  0x0A,  0x10,  0x72,  0xFE,  0x14,  0x00,  0x08,  0xFF, 	/* 44C20 */
+	0x0C,  0xA5,  0x12,  0xFF,  0x7D,  0x42,  0x09,  0x7E,  0x28,  0x42,  0x2A,  0x7E,  0x29,  0x42,  0x29,  0x7E, 	/* 44C30 */
+	0x48,  0x26,  0x09,  0xC1,  0x8E,  0x10,  0x88,  0x10,  0x8A,  0x13,  0xE9,  0x68,  0x89,  0x28,  0x88,  0x17, 	/* 44C40 */
+	0xFF,  0x11,  0x48,  0x2B,  0x6A,  0x7D,  0x4A,  0x13,  0x6A,  0x31,  0x44,  0x3B,  0x64,  0x35,  0x5D,  0x55, 	/* 44C50 */
+	0xEB,  0x17,  0x13,  0x10,  0x21,  0x8F,  0x08,  0x10,  0x08,  0xFF,  0x0A,  0x80,  0x74,  0xFE,  0x14,  0xD2, 	/* 44C60 */
+	0x08,  0xFE,  0x0C,  0xD2,  0x12,  0xFE,  0x7E,  0x90,  0x0A,  0xFF,  0x2C,  0xA8,  0x2A,  0xD7,  0x2B,  0x10, 	/* 44C70 */
+	0x49,  0x7C,  0x0A,  0x10,  0x09,  0xFF,  0x90,  0x08,  0x80,  0x08,  0xBF,  0x10,  0x84,  0x67,  0xE8,  0x15, 	/* 44C80 */
+	0x5E,  0x19,  0x52,  0x0A,  0x32,  0x15,  0x5E,  0x7D,  0x52,  0x08,  0x9E,  0x28,  0x92,  0x2D,  0x52,  0x2D, 	/* 44C90 */
+	0x5E,  0x2A,  0x14,  0x48,  0x22,  0x08,  0xC1,  0x92,  0x08,  0x00,  0x09,  0xFF,  0x0B,  0x00,  0x75,  0x7E, 	/* 44CA0 */
+	0x15,  0x52,  0x09,  0x7E,  0x0D,  0x52,  0x13,  0x7E,  0x7D,  0x10,  0x09,  0xFF,  0x2D,  0x6A,  0x2B,  0x91, 	/* 44CB0 */
+	0x2A,  0x7E,  0x2A,  0x10,  0x4D,  0xFF,  0x08,  0x00,  0x93,  0x08,  0x00,  0x09,  0xEF,  0x09,  0x29,  0x75, 	/* 44CC0 */
+	0xEF,  0x15,  0x29,  0x19,  0xEF,  0x09,  0x29,  0x15,  0xEF,  0x7E,  0xAA,  0x09,  0x11,  0x2C,  0x20,  0x2B, 	/* 44CD0 */
+	0xFF,  0x2A,  0x44,  0x28,  0xE8,  0x48,  0x3C,  0x09,  0xC2,  0x94,  0x08,  0x78,  0x08,  0x90,  0x09,  0xFE, 	/* 44CE0 */
+	0x76,  0x82,  0x14,  0xFE,  0x08,  0x88,  0x0C,  0xEE,  0x12,  0x89,  0x7F,  0xEF,  0x0A,  0x00,  0x28,  0xFE, 	/* 44CF0 */
+	0x2C,  0x92,  0x2A,  0xFE,  0x2A,  0x2A,  0x48,  0x49,  0x0B,  0x87,  0x96,  0x11,  0x28,  0x11,  0x2A,  0x12, 	/* 44D00 */
+	0xD9,  0x6A,  0x49,  0x2C,  0x88,  0x13,  0xFF,  0x11,  0x48,  0x2B,  0x6A,  0x7D,  0x4A,  0x13,  0x6A,  0x31, 	/* 44D10 */
+	0x44,  0x3B,  0x64,  0x35,  0x5D,  0x55,  0xEB,  0x17,  0x13,  0x10,  0x21,  0x9B,  0x00,  0x80,  0x1F,  0xFC, 	/* 44D20 */
+	0x00,  0x80,  0x7F,  0xFF,  0x04,  0x90,  0x3F,  0xFE,  0x09,  0x10,  0x0F,  0xFC,  0x00,  0x20,  0x5F,  0x68, 	/* 44D30 */
+	0x51,  0x12,  0x5F,  0x74,  0x51,  0x0A,  0x7F,  0xFF,  0x25,  0x2A,  0x44,  0xC9,  0x9C,  0x09,  0xE8,  0x09, 	/* 44D40 */
+	0x4F,  0x0B,  0xF0,  0x73,  0x2E,  0x15,  0xFF,  0x09,  0x55,  0x0D,  0xFF,  0x12,  0x42,  0x7D,  0x7E,  0x08, 	/* 44D50 */
+	0x42,  0x2C,  0x7E,  0x2A,  0x42,  0x2A,  0x7E,  0x2A,  0x29,  0x48,  0xC9,  0x0B,  0x07,  0xB6,  0x08,  0x00, 	/* 44D60 */
+	0x08,  0x00,  0x08,  0x00,  0x0F,  0xFC,  0x10,  0x80,  0x10,  0x80,  0x20,  0x80,  0x40,  0x80,  0x7F,  0xFF, 	/* 44D70 */
+	0x00,  0x80,  0x10,  0x84,  0x10,  0x84,  0x10,  0x84,  0x10,  0x84,  0x1F,  0xFC,  0x00,  0x00,  0xB8,  0x10, 	/* 44D80 */
+	0x00,  0x10,  0xFE,  0x1F,  0x10,  0x28,  0x10,  0x28,  0x10,  0x48,  0x10,  0x7F,  0x90,  0x08,  0x10,  0x08, 	/* 44D90 */
+	0x10,  0x29,  0x10,  0x29,  0x10,  0x29,  0x10,  0x29,  0x10,  0x3F,  0x10,  0x01,  0xFF,  0x00,  0x00,  0xBA, 	/* 44DA0 */
+	0x10,  0x20,  0x10,  0x20,  0x1E,  0x20,  0x28,  0xFC,  0x28,  0x24,  0x48,  0x24,  0x7F,  0x24,  0x08,  0x24, 	/* 44DB0 */
+	0x09,  0xFF,  0x2A,  0x30,  0x2A,  0x30,  0x2A,  0x28,  0x2A,  0x48,  0x3E,  0x44,  0x00,  0x82,  0x01,  0x01, 	/* 44DC0 */
+	0x85,  0x10,  0x10,  0x10,  0x1E,  0x3E,  0x10,  0x28,  0xFF,  0x48,  0x92,  0x08,  0x9C,  0x7F,  0xF1,  0x08, 	/* 44DD0 */
+	0x8F,  0x08,  0x84,  0x2A,  0xF8,  0x2A,  0xAA,  0x2A,  0x9C,  0x2A,  0xFF,  0x3F,  0x08,  0x22,  0x08,  0x00, 	/* 44DE0 */
+	0x18,  0x8C,  0x00,  0x00,  0x3F,  0x7E,  0x21,  0x42,  0x3D,  0x7A,  0x2F,  0x5E,  0x21,  0x42,  0x3F,  0x7E, 	/* 44DF0 */
+	0x12,  0x24,  0x29,  0x42,  0x0F,  0xFC,  0x10,  0x80,  0x7F,  0xFF,  0x00,  0x80,  0x10,  0x84,  0x1F,  0xFC, 	/* 44E00 */
+	0x00,  0x00,  0x8D,  0x07,  0xF0,  0x04,  0x90,  0x07,  0xF0,  0x04,  0x90,  0x3F,  0xFE,  0x29,  0x52,  0x3F, 	/* 44E10 */
+	0x7E,  0x29,  0x52,  0x3F,  0x7E,  0x08,  0x00,  0x0F,  0xF8,  0x10,  0x80,  0x7F,  0xFF,  0x10,  0x84,  0x1F, 	/* 44E20 */
+	0xFC,  0x00,  0x00,  0x8E,  0x10,  0x00,  0x10,  0xFC,  0x1E,  0x84,  0x28,  0xFC,  0x28,  0x84,  0x49,  0xFE, 	/* 44E30 */
+	0x7E,  0x10,  0x0B,  0xFF,  0x0A,  0xDD,  0x08,  0x10,  0x2A,  0xFE,  0x2A,  0x00,  0x2B,  0xFF,  0x3E,  0x28, 	/* 44E40 */
+	0x00,  0x5C,  0x01,  0xE2,  0x90,  0x10,  0x44,  0x11,  0xFF,  0x1E,  0x44,  0x28,  0xEE,  0x28,  0xAA,  0x48, 	/* 44E50 */
+	0xEE,  0x7F,  0x24,  0x08,  0x48,  0x08,  0x7E,  0x2A,  0xC8,  0x2B,  0x7E,  0x2A,  0x48,  0x2A,  0x7E,  0x3E, 	/* 44E60 */
+	0x48,  0x00,  0x7F,  0x00,  0x00,  0x91,  0x00,  0x00,  0x3F,  0xFE,  0x22,  0x12,  0x22,  0x12,  0x22,  0x12, 	/* 44E70 */
+	0x3A,  0xD2,  0x24,  0x22,  0x26,  0x32,  0x26,  0x32,  0x25,  0x2A,  0x29,  0x4A,  0x28,  0x42,  0x30,  0x82, 	/* 44E80 */
+	0x20,  0x02,  0x20,  0x02,  0x20,  0x06,  0x94,  0x00,  0x00,  0x3F,  0xFE,  0x24,  0x22,  0x22,  0x22,  0x22, 	/* 44E90 */
+	0x42,  0x3F,  0xFE,  0x21,  0x02,  0x21,  0x02,  0x3F,  0xFA,  0x22,  0x02,  0x22,  0x02,  0x22,  0x02,  0x22, 	/* 44EA0 */
+	0x02,  0x21,  0xF2,  0x20,  0x02,  0x20,  0x06,  0x95,  0x00,  0x00,  0x7F,  0xFE,  0x42,  0x42,  0x42,  0x42, 	/* 44EB0 */
+	0x04,  0x44,  0x18,  0x3C,  0x60,  0x00,  0x00,  0x00,  0x1F,  0xF8,  0x00,  0x80,  0x00,  0x80,  0x7F,  0xFF, 	/* 44EC0 */
+	0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x98,  0x00,  0x00,  0x3F,  0xFE,  0x22,  0x22,  0x22, 	/* 44ED0 */
+	0x22,  0x3F,  0xFE,  0x00,  0x00,  0x00,  0x00,  0x7F,  0xFF,  0x00,  0x40,  0x01,  0xA0,  0x02,  0x90,  0x0C, 	/* 44EE0 */
+	0x8C,  0x70,  0x83,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x9F,  0x00,  0x00,  0x3F,  0xFE,  0x22,  0x22, 	/* 44EF0 */
+	0x22,  0x22,  0x3F,  0xFE,  0x00,  0x80,  0x00,  0x80,  0x7F,  0xFF,  0x00,  0x80,  0x00,  0x80,  0x0F,  0xF8, 	/* 44F00 */
+	0x08,  0x08,  0x08,  0x08,  0x08,  0x08,  0x0F,  0xF8,  0x00,  0x00,  0xA0,  0x00,  0x00,  0x3F,  0xFE,  0x22, 	/* 44F10 */
+	0x22,  0x22,  0x22,  0x3F,  0xFE,  0x00,  0x00,  0x1F,  0xFC,  0x10,  0x04,  0x1F,  0xFC,  0x10,  0x40,  0x10, 	/* 44F20 */
+	0x40,  0x1F,  0xFF,  0x10,  0x20,  0x11,  0x92,  0x1E,  0x0A,  0x70,  0x06,  0xA7,  0x00,  0x00,  0x3F,  0xFE, 	/* 44F30 */
+	0x22,  0x22,  0x22,  0x22,  0x3F,  0xFE,  0x00,  0x00,  0x04,  0x10,  0x04,  0x10,  0x7F,  0xFF,  0x04,  0x10, 	/* 44F40 */
+	0x0E,  0x38,  0x0D,  0x34,  0x15,  0x52,  0x24,  0x91,  0x45,  0x10,  0x04,  0x10,  0xA8,  0x00,  0x00,  0x3F, 	/* 44F50 */
+	0xFE,  0x22,  0x22,  0x22,  0x22,  0x3F,  0xFE,  0x01,  0x00,  0x7F,  0xFF,  0x02,  0x20,  0x04,  0x90,  0x1F, 	/* 44F60 */
+	0xFC,  0x68,  0x8B,  0x0F,  0xF8,  0x08,  0x88,  0x0F,  0xF9,  0x00,  0x81,  0x00,  0x7F,  0xA9,  0x00,  0x00, 	/* 44F70 */
+	0x3F,  0xFE,  0x22,  0x22,  0x3F,  0xFE,  0x00,  0x80,  0x00,  0xFC,  0x00,  0x80,  0x0F,  0xF8,  0x08,  0x08, 	/* 44F80 */
+	0x0F,  0xF8,  0x08,  0x08,  0x0F,  0xF8,  0x00,  0x80,  0x7F,  0xFF,  0x00,  0x80,  0x00,  0x80,  0xAA,  0x00, 	/* 44F90 */
+	0x00,  0x3F,  0xFE,  0x22,  0x22,  0x22,  0x22,  0x3F,  0xFE,  0x00,  0x20,  0x02,  0x20,  0x3E,  0x3E,  0x02, 	/* 44FA0 */
+	0x20,  0x3E,  0x3E,  0x02,  0x20,  0x0E,  0x20,  0x74,  0x3F,  0x04,  0x20,  0x08,  0x20,  0x10,  0x20,  0xAB, 	/* 44FB0 */
+	0x00,  0x00,  0x3F,  0xFE,  0x22,  0x22,  0x22,  0x22,  0x3F,  0xFE,  0x02,  0x10,  0x1F,  0x90,  0x02,  0x10, 	/* 44FC0 */
+	0x02,  0x18,  0x7F,  0xD4,  0x02,  0x12,  0x1F,  0x91,  0x02,  0x10,  0x03,  0xD0,  0x7C,  0x10,  0x00,  0x10, 	/* 44FD0 */
+	0xAE,  0x00,  0x00,  0x3F,  0xFC,  0x22,  0x44,  0x3F,  0xFC,  0x00,  0x80,  0x7F,  0xFF,  0x00,  0x80,  0x27, 	/* 44FE0 */
+	0xF0,  0x24,  0x10,  0x27,  0xF0,  0x24,  0x10,  0x27,  0xF0,  0x24,  0x10,  0x27,  0xF0,  0x3F,  0xFF,  0x00, 	/* 44FF0 */
+	0x00,  0xB0,  0x00,  0x00,  0x3F,  0xFC,  0x22,  0x44,  0x22,  0x44,  0x3F,  0xFC,  0x00,  0x02,  0x3F,  0x22, 	/* 45000 */
+	0x00,  0x22,  0x7F,  0xA2,  0x00,  0x22,  0x3F,  0x22,  0x00,  0x22,  0x3F,  0x02,  0x21,  0x02,  0x3F,  0x02, 	/* 45010 */
+	0x00,  0x06,  0xB2,  0x00,  0x00,  0x1F,  0xFC,  0x12,  0x24,  0x1F,  0xFC,  0x00,  0x88,  0x1F,  0xFC,  0x00, 	/* 45020 */
+	0x90,  0x7F,  0xFF,  0x01,  0x80,  0x07,  0xF8,  0x0C,  0x08,  0x37,  0xF8,  0x04,  0x08,  0x04,  0x08,  0x07, 	/* 45030 */
+	0xF8,  0x00,  0x00,  0xB5,  0x00,  0x00,  0x3F,  0xFE,  0x22,  0x22,  0x3F,  0xFE,  0x00,  0x00,  0x0F,  0xFC, 	/* 45040 */
+	0x08,  0x80,  0x0F,  0xF0,  0x08,  0x80,  0x0F,  0xF0,  0x08,  0x80,  0x0F,  0xFE,  0x10,  0x92,  0x14,  0x4A, 	/* 45050 */
+	0x22,  0x4A,  0x42,  0x1C,  0xB7,  0x00,  0x00,  0x3F,  0xFE,  0x22,  0x22,  0x3F,  0xFE,  0x0C,  0x20,  0x13, 	/* 45060 */
+	0x26,  0x7E,  0xB8,  0x00,  0x20,  0x3F,  0x21,  0x21,  0x1F,  0x3F,  0x00,  0x21,  0x26,  0x3F,  0x38,  0x21, 	/* 45070 */
+	0x20,  0x21,  0x21,  0x23,  0x1F,  0xB8,  0x00,  0x00,  0x3F,  0xFE,  0x22,  0x42,  0x22,  0x42,  0x3F,  0xFE, 	/* 45080 */
+	0x00,  0x04,  0x3F,  0x04,  0x00,  0xFF,  0x7F,  0x04,  0x00,  0x44,  0x3F,  0x24,  0x00,  0x24,  0x3F,  0x04, 	/* 45090 */
+	0x21,  0x04,  0x3F,  0x04,  0x00,  0x0C,  0xB9,  0x00,  0x00,  0x3F,  0xFE,  0x22,  0x22,  0x22,  0x22,  0x3F, 	/* 450A0 */
+	0xFE,  0x08,  0x48,  0x08,  0x50,  0x08,  0xFF,  0x2D,  0x90,  0x2A,  0xFE,  0x28,  0x90,  0x48,  0xFE,  0x08, 	/* 450B0 */
+	0x90,  0x08,  0x90,  0x08,  0xFF,  0x08,  0x00,  0x82,  0x00,  0x00,  0x3F,  0xFE,  0x22,  0x22,  0x3F,  0xFE, 	/* 450C0 */
+	0x08,  0x00,  0x08,  0x7E,  0x72,  0x42,  0x14,  0x7E,  0x0C,  0x00,  0x12,  0x7E,  0x7D,  0x42,  0x08,  0x7E, 	/* 450D0 */
+	0x2A,  0x42,  0x29,  0x7E,  0x49,  0x42,  0x08,  0x46,  0x83,  0x00,  0x00,  0x3F,  0xFE,  0x22,  0x22,  0x3F, 	/* 450E0 */
+	0xFE,  0x04,  0x10,  0x7F,  0xFF,  0x0F,  0xF8,  0x08,  0x08,  0x0F,  0xF8,  0x01,  0x00,  0x7F,  0xFF,  0x04, 	/* 450F0 */
+	0x90,  0x1F,  0xFC,  0x68,  0x8B,  0x08,  0xB0,  0x00,  0x80,  0x85,  0x00,  0x00,  0x3F,  0xFE,  0x22,  0x22, 	/* 45100 */
+	0x22,  0x22,  0x3F,  0xFE,  0x08,  0x24,  0x08,  0x28,  0x72,  0x7F,  0x14,  0xC8,  0x0A,  0x7E,  0x7D,  0x48, 	/* 45110 */
+	0x08,  0x7E,  0x2A,  0x48,  0x29,  0x48,  0x49,  0x7F,  0x08,  0x40,  0x86,  0x00,  0x00,  0x3F,  0xFE,  0x22, 	/* 45120 */
+	0x22,  0x3F,  0xFE,  0x08,  0x24,  0x11,  0x38,  0x7F,  0xA2,  0x11,  0x1E,  0x1F,  0x20,  0x11,  0x24,  0x1F, 	/* 45130 */
+	0x38,  0x11,  0x22,  0x13,  0x1E,  0x20,  0x04,  0x22,  0x22,  0x41,  0x11,  0x87,  0x00,  0x00,  0x3F,  0xFE, 	/* 45140 */
+	0x22,  0x22,  0x3F,  0xFE,  0x12,  0x08,  0x7F,  0x08,  0x12,  0x7E,  0x1E,  0x14,  0x08,  0x22,  0x3F,  0xFF, 	/* 45150 */
+	0x29,  0x02,  0x3F,  0x3A,  0x08,  0x2A,  0x7F,  0xBA,  0x08,  0x02,  0x08,  0x06,  0x88,  0x00,  0x00,  0x3F, 	/* 45160 */
+	0xFE,  0x22,  0x22,  0x3F,  0xFE,  0x12,  0x00,  0x7F,  0x7E,  0x12,  0x48,  0x1E,  0x7C,  0x08,  0x48,  0x3F, 	/* 45170 */
+	0x7C,  0x29,  0x48,  0x3F,  0x7E,  0x08,  0x12,  0x7F,  0xCA,  0x08,  0xAA,  0x09,  0x26,  0x8A,  0x04,  0x10, 	/* 45180 */
+	0x02,  0x10,  0x02,  0x20,  0x3F,  0xFE,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x1F,  0xFC,  0x00,  0x80, 	/* 45190 */
+	0x00,  0x80,  0x00,  0x80,  0x7F,  0xFF,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x8C,  0x04, 	/* 451A0 */
+	0x10,  0x02,  0x10,  0x02,  0x20,  0x3F,  0xFE,  0x00,  0x80,  0x1F,  0xFC,  0x00,  0x80,  0x00,  0x80,  0x7F, 	/* 451B0 */
+	0xFF,  0x01,  0x20,  0x01,  0x20,  0x01,  0x20,  0x02,  0x20,  0x04,  0x21,  0x18,  0x21,  0x60,  0x1F,  0x8E, 	/* 451C0 */
+	0x04,  0x10,  0x02,  0x10,  0x02,  0x20,  0x3F,  0xFF,  0x00,  0x80,  0x0F,  0xFC,  0x00,  0x80,  0x00,  0x80, 	/* 451D0 */
+	0x1F,  0xFE,  0x00,  0x80,  0x00,  0x80,  0x3F,  0xFF,  0x01,  0x40,  0x02,  0x20,  0x0C,  0x18,  0x70,  0x07, 	/* 451E0 */
+	0x94,  0x04,  0x10,  0x02,  0x10,  0x02,  0x20,  0x3F,  0xFE,  0x00,  0x80,  0x00,  0x80,  0x1F,  0xFC,  0x00, 	/* 451F0 */
+	0x80,  0x00,  0x80,  0x00,  0x80,  0x7F,  0xFF,  0x00,  0x00,  0x10,  0x04,  0x12,  0x22,  0x21,  0x11,  0x41, 	/* 45200 */
+	0x11,  0x9A,  0x02,  0x10,  0x22,  0x10,  0x12,  0x28,  0x14,  0x28,  0x7F,  0x44,  0x08,  0xBA,  0x09,  0x01, 	/* 45210 */
+	0x3E,  0x00,  0x08,  0xFE,  0x0E,  0x22,  0x78,  0x22,  0x08,  0x22,  0x10,  0x2C,  0x10,  0x20,  0x20,  0x20, 	/* 45220 */
+	0x40,  0x20,  0x9D,  0x02,  0x02,  0x22,  0x0C,  0x12,  0x78,  0x14,  0x48,  0x7F,  0x48,  0x08,  0x48,  0x08, 	/* 45230 */
+	0x7F,  0x3E,  0x48,  0x08,  0x48,  0x0F,  0x48,  0x78,  0x48,  0x08,  0x64,  0x11,  0x85,  0x10,  0x05,  0x21, 	/* 45240 */
+	0xF3,  0x40,  0x01,  0x9E,  0x04,  0x08,  0x02,  0x10,  0x3F,  0xFE,  0x00,  0x80,  0x1F,  0xFC,  0x00,  0x80, 	/* 45250 */
+	0x00,  0x80,  0x7F,  0xFF,  0x04,  0x00,  0x0F,  0xF8,  0x08,  0x88,  0x0F,  0xFF,  0x10,  0x88,  0x20,  0x88, 	/* 45260 */
+	0x5F,  0xFF,  0x00,  0x00,  0xA3,  0x00,  0x00,  0x1F,  0xF8,  0x01,  0x08,  0x7F,  0xFF,  0x02,  0x08,  0x1F, 	/* 45270 */
+	0xF8,  0x07,  0xFC,  0x1C,  0x04,  0x67,  0xFC,  0x02,  0x20,  0x1F,  0xFC,  0x00,  0x80,  0x0F,  0xF8,  0x00, 	/* 45280 */
+	0x80,  0x7F,  0xFF,  0x00,  0x80,  0xA4,  0x00,  0x22,  0x3F,  0x12,  0x09,  0x14,  0x09,  0x7F,  0x7F,  0x88, 	/* 45290 */
+	0x09,  0x08,  0x09,  0x08,  0x3F,  0x3E,  0x08,  0x08,  0x10,  0x08,  0x1F,  0x08,  0x31,  0xFF,  0x31,  0x08, 	/* 452A0 */
+	0x51,  0x08,  0x1F,  0x08,  0x00,  0x08,  0xA8,  0x04,  0x10,  0x02,  0x20,  0x3F,  0xFE,  0x00,  0x80,  0x1F, 	/* 452B0 */
+	0xFC,  0x00,  0x80,  0x7F,  0xFF,  0x10,  0x80,  0x08,  0xFE,  0x09,  0x24,  0x42,  0x28,  0x20,  0x30,  0x24, 	/* 452C0 */
+	0x50,  0x08,  0x88,  0x11,  0x04,  0x66,  0x03,  0xA9,  0x04,  0x10,  0x02,  0x20,  0x3F,  0xFE,  0x00,  0x80, 	/* 452D0 */
+	0x1F,  0xFC,  0x00,  0x80,  0x7F,  0xFF,  0x03,  0x28,  0x3C,  0x24,  0x04,  0x20,  0x7F,  0xFF,  0x04,  0x12, 	/* 452E0 */
+	0x07,  0x94,  0x7C,  0x09,  0x04,  0x35,  0x0C,  0xC3,  0xAE,  0x04,  0x10,  0x02,  0x20,  0x3F,  0xFE,  0x00, 	/* 452F0 */
+	0x80,  0x1F,  0xFC,  0x00,  0x80,  0x7F,  0xFF,  0x12,  0x24,  0x20,  0x02,  0x1F,  0xFC,  0x00,  0x80,  0x1F, 	/* 45300 */
+	0xFC,  0x00,  0x80,  0x7F,  0xFF,  0x03,  0x30,  0x7C,  0x0F,  0xAF,  0x02,  0x00,  0x22,  0xFC,  0x12,  0x84, 	/* 45310 */
+	0x14,  0xFC,  0x7F,  0x84,  0x08,  0x84,  0x08,  0xFC,  0x3E,  0x40,  0x08,  0x7E,  0x0F,  0x52,  0x78,  0x9A, 	/* 45320 */
+	0x09,  0xAA,  0x12,  0xC2,  0x10,  0xFA,  0x20,  0x02,  0x40,  0x0C,  0xB2,  0x02,  0x10,  0x3F,  0xFE,  0x00, 	/* 45330 */
+	0x80,  0x1F,  0xFE,  0x00,  0x80,  0x7F,  0xFF,  0x01,  0x00,  0x3E,  0x24,  0x04,  0x22,  0x7F,  0xFF,  0x15, 	/* 45340 */
+	0x20,  0x3E,  0x92,  0x48,  0x14,  0x1E,  0x09,  0x12,  0x35,  0x04,  0xC3,  0xB6,  0x04,  0x20,  0x27,  0xFF, 	/* 45350 */
+	0x15,  0x7A,  0x19,  0x4A,  0x7F,  0x7A,  0x09,  0x02,  0x09,  0xFE,  0x3E,  0x00,  0x08,  0xFC,  0x0E,  0x84, 	/* 45360 */
+	0x78,  0xFC,  0x08,  0x84,  0x10,  0xFC,  0x10,  0x00,  0x23,  0xFF,  0x40,  0x00,  0xB8,  0x00,  0x80,  0x1F, 	/* 45370 */
+	0xFF,  0x10,  0x00,  0x0F,  0xFC,  0x00,  0x00,  0x0F,  0xF8,  0x08,  0x08,  0x0F,  0xF8,  0x01,  0x40,  0x3C, 	/* 45380 */
+	0x9C,  0x27,  0xF4,  0x3C,  0x94,  0x25,  0xDC,  0x3C,  0x95,  0x27,  0xF5,  0x4C,  0xA3,  0xB9,  0x02,  0x20, 	/* 45390 */
+	0x3F,  0xFE,  0x00,  0x80,  0x1F,  0xFC,  0x00,  0x80,  0x7F,  0xFF,  0x11,  0x24,  0x24,  0x12,  0x02,  0x20, 	/* 453A0 */
+	0x3F,  0xFE,  0x00,  0x80,  0x1F,  0xFC,  0x00,  0x80,  0x7F,  0xFF,  0x03,  0x30,  0x7C,  0x0F,  0xBD,  0x00, 	/* 453B0 */
+	0x00,  0x3F,  0x7E,  0x01,  0x02,  0x01,  0x02,  0x11,  0x22,  0x09,  0x12,  0x09,  0x12,  0x01,  0x02,  0x03, 	/* 453C0 */
+	0x06,  0x05,  0x0A,  0x19,  0x32,  0x61,  0xC2,  0x01,  0x02,  0x01,  0x02,  0x01,  0x02,  0x03,  0x06,  0x81, 	/* 453D0 */
+	0x05,  0xF0,  0x04,  0x10,  0x08,  0x88,  0x10,  0x84,  0x61,  0x63,  0x02,  0x18,  0x3F,  0xE4,  0x00,  0x00, 	/* 453E0 */
+	0x3F,  0xFC,  0x11,  0x24,  0x09,  0x14,  0x03,  0x0C,  0x0D,  0x34,  0x31,  0xC4,  0x01,  0x04,  0x03,  0x0C, 	/* 453F0 */
+	0x85,  0x08,  0x00,  0x0B,  0xFE,  0x08,  0x22,  0x7E,  0x66,  0x08,  0x66,  0x08,  0xAA,  0x7F,  0x32,  0x22, 	/* 45400 */
+	0x26,  0x22,  0x66,  0x14,  0x6A,  0x14,  0xB2,  0x09,  0x22,  0x0C,  0x22,  0x12,  0x66,  0x21,  0x80,  0x40, 	/* 45410 */
+	0x7F,  0x86,  0x00,  0x00,  0x7F,  0x7E,  0x09,  0x12,  0x73,  0x66,  0x0D,  0x1A,  0x71,  0x62,  0x01,  0x06, 	/* 45420 */
+	0x3F,  0xE0,  0x01,  0x22,  0x06,  0x22,  0x38,  0x9E,  0x00,  0x80,  0x7F,  0xFF,  0x00,  0x80,  0x00,  0x80, 	/* 45430 */
+	0x00,  0x80,  0x8A,  0x10,  0x00,  0x11,  0xFE,  0x10,  0x22,  0x7E,  0x22,  0x04,  0x66,  0x44,  0x66,  0x24, 	/* 45440 */
+	0xAA,  0x25,  0x32,  0x24,  0x22,  0x28,  0x66,  0x08,  0x66,  0x10,  0xAA,  0x0D,  0x32,  0x70,  0x22,  0x00, 	/* 45450 */
+	0x22,  0x00,  0x66,  0x8C,  0x00,  0x00,  0x7F,  0xFE,  0x11,  0x22,  0x09,  0x12,  0x03,  0x06,  0x05,  0x0A, 	/* 45460 */
+	0x19,  0x32,  0x03,  0x86,  0x00,  0x80,  0x1F,  0xFC,  0x04,  0x10,  0x02,  0x10,  0x02,  0x20,  0x02,  0x20, 	/* 45470 */
+	0x7F,  0xFF,  0x00,  0x00,  0x92,  0x00,  0x00,  0x7F,  0xFE,  0x21,  0x42,  0x11,  0x22,  0x13,  0x26,  0x05, 	/* 45480 */
+	0x1A,  0x19,  0x62,  0x60,  0x86,  0x01,  0x00,  0x0F,  0xF8,  0x08,  0x08,  0x0F,  0xF8,  0x08,  0x08,  0x08, 	/* 45490 */
+	0x08,  0x0F,  0xF8,  0x00,  0x00,  0x94,  0x04,  0x00,  0x27,  0xFE,  0x14,  0x22,  0x18,  0x22,  0x7F,  0x32, 	/* 454A0 */
+	0x08,  0xAA,  0x08,  0xAA,  0x3E,  0x22,  0x08,  0x22,  0x0F,  0x66,  0x78,  0x66,  0x08,  0xAA,  0x11,  0x32, 	/* 454B0 */
+	0x12,  0x22,  0x20,  0x22,  0x40,  0x66,  0x95,  0x00,  0x80,  0x01,  0x40,  0x02,  0x20,  0x0C,  0x18,  0x77, 	/* 454C0 */
+	0xF7,  0x00,  0x00,  0x0F,  0xF8,  0x08,  0x08,  0x0F,  0xF8,  0x00,  0x00,  0x7F,  0x7E,  0x09,  0x12,  0x33, 	/* 454D0 */
+	0x66,  0x0D,  0x1A,  0x31,  0x62,  0x03,  0x06,  0xA0,  0x00,  0x00,  0x7F,  0xFE,  0x11,  0x22,  0x0B,  0x16, 	/* 454E0 */
+	0x0D,  0x1A,  0x73,  0x66,  0x00,  0x80,  0x1F,  0xFC,  0x04,  0x10,  0x06,  0x30,  0x09,  0xA8,  0x10,  0xC4, 	/* 454F0 */
+	0x7F,  0xFF,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0xA1,  0x02,  0x20,  0x7E,  0x3F,  0x02,  0x20,  0x3E, 	/* 45500 */
+	0x3E,  0x02,  0x20,  0x7E,  0x3F,  0x04,  0x20,  0x08,  0x20,  0x7F,  0x7E,  0x03,  0x06,  0x0D,  0x1A,  0x71, 	/* 45510 */
+	0x62,  0x03,  0x06,  0x0D,  0x1A,  0x71,  0x62,  0x03,  0x06,  0xA6,  0x02,  0x10,  0x7F,  0xFF,  0x00,  0x04, 	/* 45520 */
+	0x1F,  0x24,  0x19,  0x24,  0x17,  0x24,  0x19,  0x24,  0x17,  0x24,  0x11,  0x0C,  0x00,  0x00,  0x7F,  0x7E, 	/* 45530 */
+	0x09,  0x12,  0x33,  0x66,  0x0D,  0x1A,  0x31,  0x62,  0x03,  0x06,  0xA9,  0x00,  0x00,  0x7F,  0xEE,  0x00, 	/* 45540 */
+	0x22,  0x3F,  0x22,  0x21,  0x26,  0x21,  0x66,  0x3F,  0x6A,  0x20,  0xB2,  0x3F,  0x22,  0x35,  0x66,  0x35, 	/* 45550 */
+	0x66,  0x35,  0xAA,  0x5F,  0x2A,  0x55,  0x32,  0x15,  0x22,  0x13,  0x66,  0xAB,  0x00,  0x00,  0x7F,  0xBE, 	/* 45560 */
+	0x08,  0x80,  0x4C,  0x80,  0x2A,  0x80,  0x19,  0x80,  0x6E,  0xFF,  0x19,  0x94,  0x08,  0x14,  0x3F,  0x14, 	/* 45570 */
+	0x21,  0x14,  0x3F,  0x14,  0x21,  0x14,  0x21,  0x25,  0x3F,  0x25,  0x00,  0x43,  0xB0,  0x08,  0x10,  0x08, 	/* 45580 */
+	0x10,  0x7F,  0x28,  0x08,  0x44,  0x3E,  0x82,  0x23,  0xFF,  0x22,  0x22,  0x3F,  0x32,  0x22,  0xAA,  0x22, 	/* 45590 */
+	0xAA,  0x3E,  0x22,  0x08,  0x66,  0x7F,  0xAA,  0x09,  0x32,  0x08,  0x22,  0x08,  0x66,  0xB3,  0x00,  0x00, 	/* 455A0 */
+	0x3F,  0xBC,  0x24,  0x24,  0x27,  0xA5,  0x2A,  0x43,  0x3F,  0xBC,  0x25,  0x14,  0x28,  0x88,  0x3F,  0x94, 	/* 455B0 */
+	0x00,  0x23,  0x7F,  0x7E,  0x09,  0x12,  0x33,  0x66,  0x0D,  0x1A,  0x31,  0x62,  0x03,  0x06,  0xB9,  0x08, 	/* 455C0 */
+	0x00,  0x08,  0xEE,  0x3E,  0x22,  0x08,  0x66,  0x7F,  0x66,  0x12,  0xAA,  0x3F,  0x32,  0x12,  0x66,  0x1A, 	/* 455D0 */
+	0x66,  0x67,  0xAA,  0x00,  0xB2,  0x7F,  0x22,  0x14,  0x66,  0x14,  0x01,  0x24,  0x01,  0x43,  0xFF,  0xBB, 	/* 455E0 */
+	0x02,  0x00,  0x0D,  0xFE,  0x7A,  0x22,  0x2A,  0x22,  0x1C,  0x22,  0x7F,  0x32,  0x0C,  0xAA,  0x1A,  0xAA, 	/* 455F0 */
+	0x29,  0x22,  0x7E,  0x66,  0x2A,  0xAA,  0x3F,  0x32,  0x2A,  0x22,  0x2A,  0x22,  0x3E,  0x22,  0x22,  0x66, 	/* 45600 */
+	0xBC,  0x00,  0x00,  0x7F,  0xFE,  0x11,  0x22,  0x0B,  0x16,  0x0D,  0x1A,  0x31,  0x62,  0x03,  0x06,  0x0F, 	/* 45610 */
+	0xF8,  0x08,  0x88,  0x0F,  0xF8,  0x08,  0x88,  0x1F,  0xFC,  0x02,  0x20,  0x7F,  0xFF,  0x04,  0x18,  0x18, 	/* 45620 */
+	0x04,  0x80,  0x08,  0x00,  0x09,  0xFE,  0x4A,  0x22,  0x2A,  0xEE,  0x2C,  0x22,  0x09,  0xFE,  0x7E,  0x48, 	/* 45630 */
+	0x14,  0x90,  0x14,  0xFE,  0x15,  0x90,  0x15,  0xFE,  0x16,  0x90,  0x14,  0xFE,  0x24,  0x90,  0x20,  0xFF, 	/* 45640 */
+	0x40,  0x80,  0x81,  0x00,  0x80,  0x00,  0x84,  0x1F,  0xFC,  0x00,  0x88,  0x00,  0x90,  0x00,  0xA0,  0x7F, 	/* 45650 */
+	0xFF,  0x00,  0xC0,  0x00,  0x80,  0x03,  0x08,  0x0E,  0x30,  0x73,  0xC0,  0x02,  0x00,  0x02,  0x04,  0x01, 	/* 45660 */
+	0x04,  0x00,  0xFC,  0x83,  0x00,  0x80,  0x00,  0x84,  0x1F,  0xFC,  0x00,  0x88,  0x00,  0x90,  0x7F,  0xFF, 	/* 45670 */
+	0x00,  0x40,  0x00,  0x80,  0x03,  0xFC,  0x0E,  0x00,  0x72,  0x00,  0x03,  0xF8,  0x02,  0x08,  0x00,  0x08, 	/* 45680 */
+	0x00,  0x08,  0x00,  0x30,  0x84,  0x02,  0x08,  0x1F,  0xF0,  0x02,  0x20,  0x7F,  0xFF,  0x01,  0x00,  0x07, 	/* 45690 */
+	0xF8,  0x79,  0x02,  0x00,  0xFE,  0x00,  0x10,  0x1F,  0xE0,  0x01,  0x00,  0x01,  0xF8,  0x3F,  0x00,  0x01, 	/* 456A0 */
+	0xFD,  0x7F,  0x01,  0x00,  0xFF,  0x85,  0x00,  0x80,  0x00,  0x84,  0x1F,  0xF8,  0x00,  0x90,  0x00,  0xA0, 	/* 456B0 */
+	0x00,  0xC0,  0x7F,  0xFF,  0x01,  0x00,  0x03,  0xF8,  0x06,  0x08,  0x1A,  0x08,  0x63,  0xF8,  0x02,  0x08, 	/* 456C0 */
+	0x02,  0x08,  0x03,  0xF8,  0x00,  0x00,  0x86,  0x00,  0x88,  0x0F,  0xFC,  0x00,  0x90,  0x00,  0xA0,  0x7F, 	/* 456D0 */
+	0xFF,  0x03,  0x08,  0x0F,  0xF2,  0x72,  0x02,  0x01,  0xFE,  0x00,  0x00,  0x0F,  0xFC,  0x08,  0x04,  0x0F, 	/* 456E0 */
+	0xFC,  0x08,  0x04,  0x0F,  0xFC,  0x00,  0x00,  0x8B,  0x01,  0x08,  0x1F,  0xF0,  0x01,  0x20,  0x7F,  0xFF, 	/* 456F0 */
+	0x01,  0x08,  0x0F,  0xF0,  0x72,  0x04,  0x01,  0xFC,  0x3F,  0xFE,  0x02,  0x30,  0x0F,  0xE8,  0x00,  0x80, 	/* 45700 */
+	0x1F,  0xFC,  0x00,  0x80,  0x7F,  0xFF,  0x00,  0x00,  0x8C,  0x00,  0x00,  0x7F,  0xFE,  0x01,  0x00,  0x01, 	/* 45710 */
+	0x00,  0x02,  0x00,  0x3F,  0xFC,  0x22,  0x44,  0x22,  0x44,  0x22,  0x44,  0x22,  0x44,  0x22,  0x44,  0x22, 	/* 45720 */
+	0x44,  0x22,  0x44,  0x22,  0x44,  0x22,  0x44,  0x20,  0x0C,  0x90,  0x00,  0x04,  0x7F,  0xC4,  0x04,  0x04, 	/* 45730 */
+	0x04,  0x04,  0x08,  0x7F,  0x3F,  0x84,  0x2A,  0x84,  0x2A,  0xA4,  0x2A,  0x94,  0x2A,  0x94,  0x2A,  0x84, 	/* 45740 */
+	0x2A,  0x84,  0x2A,  0x84,  0x2A,  0x84,  0x2A,  0x84,  0x21,  0x8C,  0x92,  0x00,  0x80,  0x00,  0x86,  0x3F, 	/* 45750 */
+	0xF8,  0x00,  0x80,  0x00,  0x80,  0x1F,  0xFC,  0x00,  0x80,  0x00,  0x80,  0x7F,  0xFF,  0x01,  0xC0,  0x02, 	/* 45760 */
+	0xA0,  0x04,  0x90,  0x18,  0x8C,  0x60,  0x83,  0x00,  0x80,  0x00,  0x80,  0x95,  0x08,  0x24,  0x08,  0x24, 	/* 45770 */
+	0x7F,  0x24,  0x08,  0xFF,  0x08,  0x24,  0x3E,  0x24,  0x08,  0x24,  0x08,  0x24,  0x7F,  0x24,  0x08,  0xFF, 	/* 45780 */
+	0x1C,  0x24,  0x1A,  0x24,  0x29,  0x24,  0x48,  0x44,  0x08,  0x44,  0x08,  0x84,  0x97,  0x08,  0x04,  0x08, 	/* 45790 */
+	0x18,  0x7F,  0xE0,  0x08,  0x20,  0x08,  0x20,  0x3E,  0x2E,  0x08,  0xF0,  0x7F,  0x20,  0x08,  0x20,  0x1C, 	/* 457A0 */
+	0x2F,  0x1B,  0xF0,  0x29,  0x20,  0x48,  0x20,  0x08,  0x22,  0x08,  0x22,  0x08,  0x1E,  0x98,  0x08,  0x00, 	/* 457B0 */
+	0x0B,  0x7E,  0x7C,  0x00,  0x08,  0x00,  0x08,  0x00,  0x3E,  0x00,  0x08,  0xFF,  0x08,  0x10,  0x7F,  0x10, 	/* 457C0 */
+	0x08,  0x10,  0x1C,  0x28,  0x1A,  0x24,  0x29,  0x24,  0x48,  0x4E,  0x09,  0xF2,  0x08,  0x02,  0x99,  0x08, 	/* 457D0 */
+	0x00,  0x0B,  0x7E,  0x7C,  0x4A,  0x08,  0x4A,  0x08,  0x4A,  0x3E,  0x4A,  0x08,  0x4A,  0x08,  0x7E,  0x7F, 	/* 457E0 */
+	0x40,  0x08,  0x40,  0x1C,  0x40,  0x1A,  0x40,  0x29,  0x41,  0x48,  0x41,  0x08,  0x3F,  0x08,  0x00,  0x9C, 	/* 457F0 */
+	0x08,  0x00,  0x0B,  0x7C,  0x7C,  0x44,  0x08,  0x44,  0x08,  0x44,  0x3E,  0x44,  0x08,  0x7C,  0x08,  0x40, 	/* 45800 */
+	0x7F,  0xC0,  0x08,  0x7E,  0x1C,  0x42,  0x1A,  0x42,  0x29,  0x42,  0x48,  0x42,  0x08,  0x7E,  0x08,  0x00, 	/* 45810 */
+	0xA1,  0x08,  0x08,  0x0F,  0xE8,  0x79,  0x28,  0x09,  0x28,  0x09,  0x3E,  0x3D,  0xEA,  0x09,  0x2A,  0x09, 	/* 45820 */
+	0x2A,  0x7F,  0xEA,  0x09,  0x2A,  0x1D,  0x2A,  0x1B,  0x32,  0x29,  0xD2,  0x4B,  0x12,  0x08,  0x22,  0x08, 	/* 45830 */
+	0x4C,  0xA8,  0x08,  0x00,  0x0B,  0xFF,  0x7C,  0x80,  0x08,  0xBE,  0x08,  0x80,  0x3E,  0xFE,  0x08,  0xA9, 	/* 45840 */
+	0x08,  0xAA,  0x7F,  0xB4,  0x08,  0xE3,  0x1C,  0x84,  0x1A,  0xFF,  0x29,  0x44,  0x49,  0x24,  0x0A,  0x04, 	/* 45850 */
+	0x08,  0x0C,  0xB3,  0x00,  0x00,  0x7F,  0xFF,  0x04,  0x10,  0x04,  0x10,  0x07,  0xF0,  0x04,  0x10,  0x04, 	/* 45860 */
+	0x10,  0x04,  0x10,  0x07,  0xF0,  0x04,  0x10,  0x04,  0x10,  0x04,  0x1F,  0x07,  0xF0,  0x78,  0x10,  0x00, 	/* 45870 */
+	0x10,  0x00,  0x10,  0xB6,  0x00,  0x00,  0x7F,  0xBE,  0x11,  0x22,  0x11,  0x24,  0x11,  0x24,  0x1F,  0x28, 	/* 45880 */
+	0x11,  0x24,  0x11,  0x22,  0x1F,  0x22,  0x11,  0x21,  0x11,  0x31,  0x11,  0xA9,  0x1F,  0x26,  0x71,  0x20, 	/* 45890 */
+	0x01,  0x20,  0x01,  0x20,  0xBB,  0x00,  0x08,  0x7F,  0x08,  0x12,  0x08,  0x12,  0x08,  0x12,  0x48,  0x1E, 	/* 458A0 */
+	0x4F,  0x12,  0x48,  0x12,  0x48,  0x1E,  0x48,  0x12,  0x48,  0x12,  0x48,  0x13,  0x48,  0x1E,  0x48,  0x62, 	/* 458B0 */
+	0x48,  0x03,  0xFF,  0x02,  0x00,  0xBD,  0x00,  0x10,  0x7F,  0x90,  0x12,  0x10,  0x12,  0xFF,  0x12,  0x91, 	/* 458C0 */
+	0x1E,  0x91,  0x12,  0x90,  0x12,  0x18,  0x1E,  0x18,  0x12,  0x18,  0x12,  0x28,  0x13,  0x28,  0x1E,  0x28, 	/* 458D0 */
+	0x72,  0x49,  0x02,  0x89,  0x03,  0x07,  0xBF,  0x00,  0x10,  0x7F,  0x10,  0x12,  0x12,  0x12,  0x52,  0x1E, 	/* 458E0 */
+	0x52,  0x12,  0x54,  0x12,  0x54,  0x12,  0x90,  0x1E,  0x98,  0x12,  0x28,  0x12,  0x28,  0x13,  0x28,  0x1E, 	/* 458F0 */
+	0x44,  0x62,  0x44,  0x02,  0x82,  0x03,  0x01,  0x86,  0x00,  0x10,  0x7F,  0x90,  0x12,  0x28,  0x12,  0x44, 	/* 45900 */
+	0x12,  0x82,  0x1F,  0x7D,  0x12,  0x00,  0x12,  0x00,  0x1E,  0xFE,  0x12,  0x22,  0x12,  0x22,  0x12,  0x22, 	/* 45910 */
+	0x1E,  0x22,  0x62,  0x2C,  0x02,  0x20,  0x02,  0x20,  0x8A,  0x00,  0x20,  0x7F,  0x20,  0x12,  0xCE,  0x12, 	/* 45920 */
+	0xAA,  0x12,  0xAA,  0x1E,  0xAA,  0x12,  0xAA,  0x12,  0xAA,  0x1E,  0xAA,  0x12,  0xAA,  0x12,  0xAA,  0x13, 	/* 45930 */
+	0xEA,  0x1E,  0x2C,  0x62,  0x48,  0x02,  0x48,  0x02,  0x88,  0x92,  0x00,  0x04,  0x7F,  0x18,  0x12,  0xF0, 	/* 45940 */
+	0x12,  0x10,  0x12,  0x10,  0x1E,  0x10,  0x13,  0xFF,  0x12,  0x10,  0x1E,  0x10,  0x12,  0x10,  0x12,  0xFE, 	/* 45950 */
+	0x12,  0x82,  0x1E,  0x82,  0x62,  0x82,  0x02,  0xFE,  0x02,  0x00,  0x96,  0x00,  0x00,  0x7F,  0xFE,  0x11, 	/* 45960 */
+	0x22,  0x1F,  0x22,  0x11,  0x22,  0x1F,  0x22,  0x11,  0x22,  0x1F,  0x3E,  0x71,  0x00,  0x01,  0x00,  0x3F, 	/* 45970 */
+	0xFE,  0x00,  0x80,  0x1F,  0xF8,  0x00,  0x80,  0x7F,  0xFF,  0x00,  0x00,  0x98,  0x00,  0x10,  0x7F,  0x10, 	/* 45980 */
+	0x12,  0xFE,  0x12,  0x92,  0x1E,  0xFE,  0x12,  0x92,  0x12,  0x92,  0x12,  0xFE,  0x1E,  0x00,  0x13,  0xFF, 	/* 45990 */
+	0x12,  0x20,  0x13,  0x3C,  0x1E,  0x04,  0x62,  0x04,  0x02,  0x04,  0x02,  0x18,  0x9A,  0x00,  0x00,  0x7F, 	/* 459A0 */
+	0xFC,  0x11,  0x24,  0x1F,  0x24,  0x11,  0x18,  0x1F,  0x10,  0x11,  0xAC,  0x1F,  0x43,  0x71,  0x10,  0x00, 	/* 459B0 */
+	0x60,  0x0B,  0x82,  0x10,  0xDC,  0x62,  0xA0,  0x0C,  0x98,  0x70,  0x87,  0x00,  0x80,  0x9E,  0x00,  0x00, 	/* 459C0 */
+	0x7E,  0x7E,  0x42,  0x42,  0x7E,  0x7E,  0x42,  0x42,  0x7E,  0x7E,  0x40,  0x02,  0x5F,  0xFA,  0x44,  0x22, 	/* 459D0 */
+	0x47,  0xE2,  0x44,  0x22,  0x47,  0xE2,  0x44,  0x22,  0x47,  0xE2,  0x5C,  0x22,  0x40,  0x26,  0x9F,  0x10, 	/* 459E0 */
+	0x00,  0x1F,  0xBE,  0x24,  0x22,  0x7F,  0xE2,  0x0A,  0x22,  0x09,  0x22,  0x11,  0x3E,  0x20,  0x00,  0x7F, 	/* 459F0 */
+	0xFF,  0x04,  0x10,  0x07,  0xF0,  0x04,  0x10,  0x07,  0xF0,  0x04,  0x1F,  0x7F,  0xF0,  0x00,  0x10,  0xA1, 	/* 45A00 */
+	0x00,  0x1C,  0x7F,  0x24,  0x12,  0x24,  0x12,  0x52,  0x12,  0x92,  0x1F,  0x19,  0x12,  0x24,  0x12,  0x2C, 	/* 45A10 */
+	0x1E,  0xF2,  0x12,  0x12,  0x12,  0x08,  0x13,  0xA8,  0x1E,  0xA2,  0x72,  0xA5,  0x03,  0x25,  0x02,  0x1C, 	/* 45A20 */
+	0xA2,  0x00,  0x10,  0x7F,  0x10,  0x12,  0xFF,  0x12,  0x81,  0x12,  0x81,  0x1E,  0x7E,  0x12,  0x10,  0x12, 	/* 45A30 */
+	0x10,  0x1E,  0x50,  0x12,  0x5E,  0x12,  0x50,  0x12,  0x50,  0x1E,  0xD0,  0x62,  0xB0,  0x03,  0x18,  0x02, 	/* 45A40 */
+	0x07,  0xA8,  0x00,  0x44,  0x7E,  0x44,  0x25,  0x99,  0x24,  0xAA,  0x3C,  0x44,  0x24,  0x44,  0x24,  0xAA, 	/* 45A50 */
+	0x25,  0xDD,  0x3C,  0x00,  0x24,  0x48,  0x24,  0x48,  0x27,  0xFF,  0x3C,  0x48,  0x64,  0x48,  0x04,  0x88, 	/* 45A60 */
+	0x05,  0x08,  0xAF,  0x00,  0x44,  0x7E,  0x44,  0x25,  0xBA,  0x24,  0xAA,  0x24,  0x44,  0x3C,  0x44,  0x24, 	/* 45A70 */
+	0xAA,  0x25,  0xFF,  0x3C,  0x00,  0x25,  0x2A,  0x25,  0x2A,  0x25,  0xEA,  0x3D,  0x2E,  0x65,  0x4A,  0x04, 	/* 45A80 */
+	0x48,  0x04,  0x88,  0xB0,  0x00,  0x08,  0x7E,  0x10,  0x24,  0xFE,  0x24,  0x92,  0x24,  0xDE,  0x3C,  0xAA, 	/* 45A90 */
+	0x24,  0xD2,  0x24,  0x9A,  0x3C,  0xA6,  0x24,  0xC2,  0x24,  0xFE,  0x26,  0x90,  0x3C,  0xAA,  0x65,  0x21, 	/* 45AA0 */
+	0x06,  0x25,  0x04,  0x1C,  0xB2,  0x04,  0x3C,  0x7F,  0xA4,  0x04,  0x25,  0x3F,  0x43,  0x00,  0x7C,  0x1F, 	/* 45AB0 */
+	0xA4,  0x15,  0x18,  0x1F,  0x24,  0x20,  0x43,  0x5F,  0xFF,  0x04,  0x10,  0x07,  0xF0,  0x04,  0x10,  0x07, 	/* 45AC0 */
+	0xFF,  0x7C,  0x10,  0x00,  0x10,  0xB3,  0x10,  0x88,  0x11,  0x54,  0x2B,  0xFE,  0x49,  0x20,  0x11,  0x3C, 	/* 45AD0 */
+	0x31,  0xA0,  0x52,  0x7F,  0x14,  0x00,  0x7F,  0xFF,  0x04,  0x10,  0x07,  0xF0,  0x04,  0x10,  0x07,  0xF0, 	/* 45AE0 */
+	0x04,  0x1F,  0x7F,  0xF0,  0x00,  0x10,  0xB4,  0x00,  0x20,  0x7F,  0x20,  0x25,  0xFE,  0x24,  0x20,  0x3C, 	/* 45AF0 */
+	0x20,  0x25,  0xFC,  0x25,  0x54,  0x25,  0x54,  0x3D,  0x54,  0x25,  0xFC,  0x24,  0x20,  0x25,  0x50,  0x3D, 	/* 45B00 */
+	0x52,  0x65,  0x45,  0x06,  0x45,  0x04,  0x3C,  0xB6,  0x00,  0x00,  0x3F,  0xFC,  0x04,  0x20,  0x07,  0xE0, 	/* 45B10 */
+	0x04,  0x20,  0x07,  0xF8,  0x3C,  0x20,  0x00,  0x20,  0x7F,  0xFF,  0x11,  0x22,  0x1F,  0x3E,  0x11,  0x22, 	/* 45B20 */
+	0x1F,  0x3E,  0x11,  0xA3,  0x7F,  0x7E,  0x01,  0x02,  0xB7,  0x00,  0x88,  0x7E,  0x8C,  0x27,  0xFA,  0x26, 	/* 45B30 */
+	0x2A,  0x25,  0x28,  0x3D,  0x48,  0x27,  0xFF,  0x24,  0x0A,  0x3D,  0xEA,  0x25,  0x2A,  0x25,  0xE4,  0x27, 	/* 45B40 */
+	0x2C,  0x3D,  0x2C,  0x65,  0xF5,  0x04,  0x13,  0x04,  0x21,  0xB9,  0x00,  0x10,  0x7E,  0x10,  0x25,  0xFF, 	/* 45B50 */
+	0x25,  0x11,  0x3D,  0xA9,  0x24,  0xA2,  0x25,  0x1D,  0x24,  0xFE,  0x3C,  0xAA,  0x24,  0xFE,  0x24,  0x00, 	/* 45B60 */
+	0x25,  0xFF,  0x3C,  0x10,  0x64,  0x10,  0x04,  0x10,  0x04,  0x30,  0xBD,  0x00,  0x10,  0x7E,  0x10,  0x13, 	/* 45B70 */
+	0xFF,  0x1E,  0x10,  0x12,  0xFE,  0x1E,  0xAA,  0x12,  0xAA,  0x7E,  0xFE,  0x02,  0x00,  0x7B,  0xFF,  0x12, 	/* 45B80 */
+	0x10,  0x3A,  0x28,  0x12,  0xAA,  0x1A,  0xA1,  0x63,  0x25,  0x02,  0x1C,  0xBE,  0x04,  0x20,  0x3F,  0xBF, 	/* 45B90 */
+	0x0A,  0x20,  0x7F,  0xFE,  0x11,  0x02,  0x1F,  0x3E,  0x11,  0x20,  0x1F,  0x3E,  0x11,  0x20,  0x13,  0x21, 	/* 45BA0 */
+	0x7F,  0xFF,  0x04,  0x08,  0x07,  0xF8,  0x04,  0x0E,  0x7F,  0xF8,  0x00,  0x08,  0xBF,  0x00,  0x80,  0x00, 	/* 45BB0 */
+	0x80,  0x1F,  0xFC,  0x00,  0x84,  0x7F,  0xFF,  0x00,  0x84,  0x00,  0x84,  0x1F,  0xFC,  0x00,  0x80,  0x1F, 	/* 45BC0 */
+	0xFC,  0x00,  0x80,  0x00,  0x80,  0x7F,  0xFF,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x84,  0x20,  0x10, 	/* 45BD0 */
+	0x22,  0x10,  0x3C,  0xFE,  0x20,  0x12,  0x23,  0xFF,  0x1E,  0x12,  0x10,  0xFE,  0x1F,  0x10,  0x24,  0x10, 	/* 45BE0 */
+	0x44,  0xFE,  0x3F,  0x10,  0x0C,  0x10,  0x0A,  0xFF,  0x11,  0x10,  0x21,  0x10,  0x40,  0x10,  0x85,  0x00, 	/* 45BF0 */
+	0x80,  0x1F,  0xFC,  0x00,  0x84,  0x7F,  0xFF,  0x00,  0x84,  0x1F,  0xFC,  0x02,  0xA0,  0x12,  0xA4,  0x1E, 	/* 45C00 */
+	0xBC,  0x10,  0x84,  0x1F,  0xFC,  0x10,  0x84,  0x1E,  0xBC,  0x12,  0xA4,  0x22,  0xA4,  0x40,  0x84,  0x86, 	/* 45C10 */
+	0x00,  0x10,  0x1F,  0x10,  0x10,  0xFE,  0x1E,  0x12,  0x11,  0xFF,  0x1E,  0x12,  0x10,  0xFE,  0x10,  0x10, 	/* 45C20 */
+	0x7F,  0x10,  0x10,  0xFE,  0x14,  0x10,  0x12,  0x10,  0x12,  0xFF,  0x1D,  0x10,  0x61,  0x10,  0x00,  0x10, 	/* 45C30 */
+	0x87,  0x00,  0x10,  0x3F,  0xDF,  0x0F,  0x24,  0x09,  0x54,  0x0F,  0x08,  0x10,  0x96,  0x2F,  0xF8,  0x00, 	/* 45C40 */
+	0x88,  0x3F,  0xFF,  0x00,  0x88,  0x0F,  0xF8,  0x00,  0x80,  0x1F,  0xFC,  0x00,  0x80,  0x7F,  0xFF,  0x00, 	/* 45C50 */
+	0x80,  0x89,  0x00,  0x80,  0x00,  0x80,  0x3F,  0xFE,  0x20,  0x82,  0x20,  0x82,  0x21,  0x42,  0x21,  0x22, 	/* 45C60 */
+	0x22,  0x92,  0x24,  0x92,  0x28,  0x82,  0x21,  0x42,  0x21,  0x22,  0x22,  0x12,  0x24,  0x12,  0x28,  0x02, 	/* 45C70 */
+	0x20,  0x06,  0x8B,  0x00,  0x20,  0x3E,  0x20,  0x22,  0x20,  0x22,  0x20,  0x23,  0xFE,  0x3E,  0x22,  0x22, 	/* 45C80 */
+	0x22,  0x22,  0x22,  0x22,  0x22,  0x3E,  0x22,  0x22,  0x22,  0x22,  0x22,  0x22,  0x42,  0x22,  0x42,  0x22, 	/* 45C90 */
+	0x84,  0x47,  0x18,  0x8C,  0x00,  0x00,  0x3E,  0x78,  0x22,  0x48,  0x22,  0x48,  0x22,  0x48,  0x3E,  0x48, 	/* 45CA0 */
+	0x22,  0x48,  0x22,  0x48,  0x22,  0x48,  0x3E,  0x48,  0x22,  0x48,  0x22,  0x48,  0x22,  0x88,  0x22,  0x89, 	/* 45CB0 */
+	0x23,  0x09,  0x46,  0x07,  0x93,  0x00,  0x80,  0x00,  0x80,  0x1F,  0xFF,  0x10,  0x00,  0x10,  0x00,  0x0F, 	/* 45CC0 */
+	0xFC,  0x00,  0x00,  0x0F,  0xF8,  0x08,  0x08,  0x0F,  0xF8,  0x08,  0x08,  0x0F,  0xF8,  0x08,  0x08,  0x08, 	/* 45CD0 */
+	0x08,  0x08,  0x08,  0x08,  0x18,  0x96,  0x10,  0x84,  0x08,  0x84,  0x04,  0x88,  0x04,  0x90,  0x00,  0x80, 	/* 45CE0 */
+	0x0F,  0xF8,  0x08,  0x08,  0x08,  0x08,  0x0F,  0xF8,  0x08,  0x08,  0x08,  0x08,  0x0F,  0xF8,  0x08,  0x08, 	/* 45CF0 */
+	0x08,  0x08,  0x08,  0x08,  0x08,  0x18,  0x98,  0x00,  0x08,  0x3E,  0x08,  0x22,  0x08,  0x22,  0x08,  0x23, 	/* 45D00 */
+	0xFF,  0x3E,  0x08,  0x22,  0x08,  0x22,  0x88,  0x22,  0x48,  0x3E,  0x48,  0x22,  0x08,  0x22,  0x08,  0x22, 	/* 45D10 */
+	0x08,  0x22,  0x08,  0x22,  0x08,  0x46,  0x18,  0x9A,  0x00,  0x10,  0x3E,  0x10,  0x22,  0x10,  0x22,  0x10, 	/* 45D20 */
+	0x22,  0x10,  0x3E,  0xFE,  0x22,  0x10,  0x22,  0x10,  0x22,  0x10,  0x3E,  0x10,  0x22,  0x10,  0x22,  0x10, 	/* 45D30 */
+	0x22,  0x10,  0x22,  0x10,  0x23,  0xFF,  0x46,  0x00,  0x9B,  0x00,  0x00,  0x3E,  0x00,  0x22,  0xFE,  0x22, 	/* 45D40 */
+	0x10,  0x22,  0x10,  0x3E,  0x10,  0x22,  0x10,  0x22,  0x10,  0x22,  0x10,  0x3E,  0x10,  0x22,  0x10,  0x22, 	/* 45D50 */
+	0x10,  0x22,  0x10,  0x22,  0x10,  0x23,  0xFF,  0x46,  0x00,  0x9D,  0x00,  0x00,  0x3E,  0xFE,  0x22,  0x10, 	/* 45D60 */
+	0x22,  0x10,  0x22,  0x10,  0x3E,  0x10,  0x22,  0x10,  0x23,  0xFF,  0x22,  0x10,  0x3E,  0x10,  0x22,  0x10, 	/* 45D70 */
+	0x22,  0x10,  0x22,  0x10,  0x22,  0x10,  0x22,  0x10,  0x46,  0x10,  0xA1,  0x00,  0x00,  0x3C,  0xF0,  0x24, 	/* 45D80 */
+	0x90,  0x24,  0x92,  0x24,  0x92,  0x3C,  0x8E,  0x25,  0x00,  0x27,  0xF8,  0x24,  0x88,  0x3C,  0x88,  0x24, 	/* 45D90 */
+	0x50,  0x24,  0x50,  0x24,  0x20,  0x24,  0x50,  0x25,  0x8C,  0x4E,  0x03,  0xA2,  0x00,  0x10,  0x3E,  0x10, 	/* 45DA0 */
+	0x22,  0x10,  0x23,  0xFF,  0x22,  0x10,  0x3E,  0x10,  0x22,  0xFC,  0x22,  0x44,  0x22,  0x44,  0x3E,  0x28, 	/* 45DB0 */
+	0x22,  0x28,  0x22,  0x10,  0x22,  0x30,  0x22,  0x48,  0x22,  0x84,  0x47,  0x03,  0xA5,  0x00,  0x00,  0x3E, 	/* 45DC0 */
+	0xFC,  0x22,  0xA4,  0x22,  0xA4,  0x22,  0xA4,  0x3E,  0xA4,  0x22,  0xA4,  0x22,  0xFC,  0x22,  0x80,  0x3E, 	/* 45DD0 */
+	0x80,  0x22,  0x80,  0x22,  0x80,  0x22,  0x82,  0x22,  0x82,  0x22,  0x7E,  0x46,  0x00,  0xA9,  0x00,  0x00, 	/* 45DE0 */
+	0x7F,  0xFF,  0x00,  0x00,  0x1F,  0xFC,  0x10,  0x04,  0x10,  0x04,  0x1F,  0xFC,  0x10,  0x00,  0x17,  0xF8, 	/* 45DF0 */
+	0x14,  0x08,  0x17,  0xF8,  0x24,  0x08,  0x27,  0xF8,  0x44,  0x08,  0x04,  0x08,  0x04,  0x18,  0xAA,  0x00, 	/* 45E00 */
+	0x10,  0x3E,  0x10,  0x22,  0x10,  0x23,  0xFF,  0x22,  0x20,  0x3E,  0x20,  0x22,  0x20,  0x22,  0x3C,  0x22, 	/* 45E10 */
+	0x24,  0x3E,  0x24,  0x22,  0x24,  0x22,  0x24,  0x22,  0x44,  0x22,  0x44,  0x22,  0x84,  0x47,  0x18,  0xAC, 	/* 45E20 */
+	0x00,  0x24,  0x3E,  0x22,  0x22,  0x22,  0x22,  0x20,  0x23,  0xFF,  0x3E,  0x20,  0x22,  0x20,  0x22,  0x30, 	/* 45E30 */
+	0x22,  0x30,  0x3E,  0x50,  0x22,  0x50,  0x22,  0x50,  0x22,  0x91,  0x22,  0x91,  0x23,  0x0F,  0x46,  0x00, 	/* 45E40 */
+	0xAD,  0x00,  0xE0,  0x3C,  0x20,  0x24,  0x20,  0x25,  0xFE,  0x25,  0x22,  0x3D,  0x22,  0x25,  0x22,  0x25, 	/* 45E50 */
+	0x52,  0x25,  0x52,  0x3D,  0x4A,  0x25,  0x86,  0x25,  0x02,  0x25,  0x02,  0x25,  0x02,  0x25,  0x02,  0x4D, 	/* 45E60 */
+	0x06,  0xAF,  0x00,  0x80,  0x08,  0x80,  0x08,  0xFC,  0x08,  0x80,  0x7F,  0xFF,  0x00,  0x00,  0x0F,  0xF0, 	/* 45E70 */
+	0x08,  0x10,  0x08,  0x10,  0x0F,  0xF0,  0x08,  0x10,  0x08,  0x10,  0x0F,  0xF0,  0x08,  0x10,  0x08,  0x10, 	/* 45E80 */
+	0x08,  0x30,  0xB1,  0x00,  0x20,  0x3E,  0x20,  0x22,  0x20,  0x23,  0xFF,  0x22,  0x20,  0x3E,  0x28,  0x22, 	/* 45E90 */
+	0x28,  0x22,  0x48,  0x22,  0x48,  0x3E,  0x48,  0x22,  0x90,  0x22,  0x94,  0x23,  0x12,  0x22,  0x26,  0x22, 	/* 45EA0 */
+	0xF9,  0x46,  0x01,  0xB2,  0x00,  0x80,  0x00,  0x80,  0x7F,  0xFF,  0x02,  0x20,  0x04,  0x18,  0x0F,  0xE4, 	/* 45EB0 */
+	0x70,  0x02,  0x0F,  0xF8,  0x08,  0x08,  0x08,  0x08,  0x0F,  0xF8,  0x08,  0x08,  0x0F,  0xF8,  0x08,  0x08, 	/* 45EC0 */
+	0x08,  0x08,  0x08,  0x18,  0xB4,  0x00,  0x08,  0x0F,  0x30,  0x00,  0xC0,  0x07,  0x30,  0x3A,  0x08,  0x7F, 	/* 45ED0 */
+	0xFE,  0x02,  0x00,  0x04,  0x00,  0x07,  0xF8,  0x0C,  0x08,  0x17,  0xF8,  0x24,  0x08,  0x47,  0xF8,  0x04, 	/* 45EE0 */
+	0x08,  0x04,  0x08,  0x04,  0x18,  0xBA,  0x00,  0x20,  0x3C,  0x20,  0x24,  0x20,  0x27,  0xFF,  0x24,  0x20, 	/* 45EF0 */
+	0x3C,  0x20,  0x25,  0xFE,  0x25,  0x22,  0x25,  0x22,  0x3D,  0x22,  0x25,  0x22,  0x25,  0x22,  0x25,  0x2C, 	/* 45F00 */
+	0x24,  0x20,  0x24,  0x20,  0x4C,  0x20,  0x83,  0x00,  0x00,  0x3F,  0xFC,  0x21,  0x04,  0x21,  0x04,  0x3F, 	/* 45F10 */
+	0xFC,  0x21,  0x04,  0x3F,  0xFC,  0x00,  0x00,  0x1F,  0xF8,  0x10,  0x08,  0x1F,  0xF8,  0x10,  0x08,  0x1F, 	/* 45F20 */
+	0xF8,  0x10,  0x08,  0x10,  0x08,  0x10,  0x18,  0x84,  0x00,  0x80,  0x00,  0x80,  0x3F,  0xFE,  0x20,  0x82, 	/* 45F30 */
+	0x3F,  0xFE,  0x20,  0x82,  0x3F,  0xFE,  0x00,  0x00,  0x0F,  0xF8,  0x08,  0x08,  0x0F,  0xF8,  0x08,  0x08, 	/* 45F40 */
+	0x0F,  0xF8,  0x08,  0x08,  0x08,  0x08,  0x08,  0x18,  0x86,  0x00,  0x00,  0x3E,  0x7C,  0x22,  0x44,  0x22, 	/* 45F50 */
+	0x44,  0x22,  0x44,  0x3E,  0x44,  0x22,  0x7C,  0x22,  0x44,  0x22,  0x44,  0x3E,  0x44,  0x22,  0x44,  0x22, 	/* 45F60 */
+	0x7C,  0x22,  0x00,  0x22,  0x00,  0x23,  0xFF,  0x46,  0x00,  0x8C,  0x02,  0x40,  0x02,  0x46,  0x7E,  0x78, 	/* 45F70 */
+	0x02,  0x40,  0x02,  0x41,  0x0E,  0x41,  0x72,  0x3F,  0x02,  0x00,  0x0F,  0xF0,  0x08,  0x10,  0x0F,  0xF0, 	/* 45F80 */
+	0x08,  0x10,  0x0F,  0xF0,  0x08,  0x10,  0x08,  0x10,  0x08,  0x30,  0x8E,  0x00,  0x20,  0x3E,  0x20,  0x22, 	/* 45F90 */
+	0x20,  0x22,  0x48,  0x22,  0x44,  0x3E,  0x8E,  0x23,  0xF2,  0x22,  0x01,  0x22,  0x01,  0x3E,  0xFC,  0x22, 	/* 45FA0 */
+	0x84,  0x22,  0x84,  0x22,  0x84,  0x22,  0x84,  0x22,  0xFC,  0x46,  0x00,  0x96,  0x00,  0x20,  0x3C,  0xA8, 	/* 45FB0 */
+	0x24,  0xA4,  0x25,  0x24,  0x24,  0x20,  0x3D,  0xFE,  0x24,  0x20,  0x24,  0x20,  0x24,  0x20,  0x3F,  0xFF, 	/* 45FC0 */
+	0x24,  0x20,  0x24,  0x20,  0x24,  0x20,  0x24,  0x20,  0x24,  0x20,  0x4C,  0x20,  0x99,  0x00,  0x40,  0x3E, 	/* 45FD0 */
+	0x40,  0x22,  0x40,  0x22,  0x7F,  0x22,  0x90,  0x3E,  0x90,  0x23,  0x10,  0x22,  0x1E,  0x22,  0x10,  0x3E, 	/* 45FE0 */
+	0x10,  0x22,  0x10,  0x22,  0x1E,  0x22,  0x10,  0x22,  0x10,  0x22,  0x10,  0x46,  0x10,  0x9A,  0x00,  0x00, 	/* 45FF0 */
+	0x3D,  0xFE,  0x24,  0x10,  0x24,  0x10,  0x24,  0x20,  0x3C,  0x20,  0x24,  0x68,  0x24,  0xA4,  0x25,  0x22, 	/* 46000 */
+	0x3E,  0x21,  0x24,  0x20,  0x24,  0x20,  0x24,  0x20,  0x24,  0x00,  0x27,  0xFF,  0x4C,  0x00,  0x9B,  0x00, 	/* 46010 */
+	0x00,  0x3E,  0xFE,  0x22,  0x92,  0x22,  0x92,  0x22,  0x92,  0x3E,  0xFE,  0x22,  0x92,  0x22,  0x92,  0x22, 	/* 46020 */
+	0x92,  0x3E,  0xFE,  0x22,  0x10,  0x22,  0x10,  0x22,  0x10,  0x22,  0x10,  0x22,  0x10,  0x46,  0x10,  0x9D, 	/* 46030 */
+	0x00,  0x02,  0x3E,  0x0C,  0x22,  0x78,  0x22,  0x48,  0x22,  0x48,  0x3E,  0x48,  0x22,  0x7F,  0x22,  0x48, 	/* 46040 */
+	0x22,  0x48,  0x3E,  0x48,  0x22,  0x44,  0x22,  0x75,  0x23,  0xC5,  0x22,  0x03,  0x23,  0xF3,  0x46,  0x01, 	/* 46050 */
+	0x9E,  0x00,  0x40,  0x3E,  0x40,  0x22,  0x7E,  0x22,  0x42,  0x22,  0x42,  0x3E,  0xF2,  0x22,  0x92,  0x23, 	/* 46060 */
+	0x12,  0x22,  0x12,  0x3E,  0xF2,  0x22,  0x8C,  0x22,  0x80,  0x22,  0x80,  0x22,  0x81,  0x22,  0x41,  0x46, 	/* 46070 */
+	0x3F,  0xA1,  0x04,  0x00,  0x04,  0x3E,  0x04,  0x22,  0x7F,  0xE2,  0x04,  0x22,  0x04,  0x3E,  0x04,  0x22, 	/* 46080 */
+	0x04,  0x22,  0x1F,  0x22,  0x11,  0x3E,  0x11,  0x22,  0x11,  0x22,  0x11,  0x22,  0x1F,  0x42,  0x00,  0x42, 	/* 46090 */
+	0x00,  0x86,  0xA4,  0x10,  0x84,  0x10,  0x84,  0x17,  0x24,  0x11,  0x44,  0x10,  0x84,  0x11,  0x34,  0x1F, 	/* 460A0 */
+	0xEC,  0x10,  0x04,  0x13,  0xE4,  0x12,  0x24,  0x13,  0xE4,  0x12,  0x24,  0x13,  0xE4,  0x22,  0x25,  0x22, 	/* 460B0 */
+	0x25,  0x42,  0x63,  0xA5,  0x00,  0x00,  0x7F,  0xFF,  0x00,  0x82,  0x08,  0xF4,  0x08,  0x80,  0x16,  0x80, 	/* 460C0 */
+	0x21,  0xFF,  0x40,  0x00,  0x0F,  0xF8,  0x08,  0x08,  0x0F,  0xF8,  0x08,  0x08,  0x0F,  0xF8,  0x08,  0x08, 	/* 460D0 */
+	0x08,  0x08,  0x08,  0x18,  0xAF,  0x00,  0x20,  0x3C,  0x20,  0x27,  0xFF,  0x24,  0x50,  0x24,  0x88,  0x3D, 	/* 460E0 */
+	0x04,  0x26,  0xFA,  0x24,  0x01,  0x27,  0xFC,  0x3C,  0x40,  0x24,  0x40,  0x24,  0xFC,  0x24,  0x84,  0x24, 	/* 460F0 */
+	0x04,  0x24,  0x04,  0x4C,  0x18,  0xB1,  0x00,  0x20,  0x3C,  0x20,  0x25,  0x24,  0x24,  0xA4,  0x24,  0xA4, 	/* 46100 */
+	0x3C,  0xA8,  0x24,  0x20,  0x27,  0xFF,  0x24,  0x50,  0x3C,  0x50,  0x24,  0x50,  0x24,  0x50,  0x24,  0x90, 	/* 46110 */
+	0x24,  0x92,  0x25,  0x0A,  0x4E,  0x06,  0xB4,  0x00,  0x00,  0x3D,  0xFE,  0x25,  0x02,  0x25,  0x02,  0x25, 	/* 46120 */
+	0xFE,  0x3D,  0x02,  0x25,  0x02,  0x25,  0x7A,  0x25,  0x4A,  0x3D,  0x4A,  0x25,  0x4A,  0x25,  0x7A,  0x25, 	/* 46130 */
+	0x02,  0x25,  0x02,  0x25,  0x02,  0x4D,  0x06,  0xB8,  0x00,  0x80,  0x3C,  0x80,  0x24,  0x80,  0x24,  0xFE, 	/* 46140 */
+	0x25,  0x12,  0x3D,  0x92,  0x27,  0x6A,  0x25,  0x2A,  0x25,  0x5A,  0x3D,  0x5A,  0x25,  0x8A,  0x25,  0x0A, 	/* 46150 */
+	0x25,  0xFA,  0x24,  0x02,  0x24,  0x04,  0x4C,  0x18,  0xBC,  0x00,  0x84,  0x3C,  0x44,  0x24,  0x48,  0x24, 	/* 46160 */
+	0x00,  0x25,  0xFE,  0x3C,  0x48,  0x24,  0x48,  0x24,  0x48,  0x27,  0xFF,  0x3C,  0x48,  0x24,  0x48,  0x24, 	/* 46170 */
+	0x48,  0x24,  0x88,  0x24,  0x88,  0x25,  0x08,  0x4E,  0x08,  0xBD,  0x08,  0x20,  0x08,  0x20,  0x12,  0x26, 	/* 46180 */
+	0x11,  0x38,  0x7E,  0xA0,  0x00,  0xA1,  0x3F,  0x21,  0x21,  0x1F,  0x21,  0x20,  0x3F,  0x20,  0x21,  0x26, 	/* 46190 */
+	0x21,  0x38,  0x3F,  0x20,  0x21,  0x21,  0x21,  0x21,  0x23,  0x1F,  0x82,  0x00,  0x80,  0x3E,  0x84,  0x22, 	/* 461A0 */
+	0x98,  0x22,  0xE0,  0x22,  0x82,  0x3E,  0x82,  0x22,  0x7E,  0x22,  0x00,  0x22,  0xFC,  0x3E,  0x84,  0x22, 	/* 461B0 */
+	0x84,  0x22,  0xFC,  0x22,  0x84,  0x22,  0x84,  0x22,  0xFC,  0x46,  0x00,  0x85,  0x00,  0x80,  0x0F,  0xF0, 	/* 461C0 */
+	0x03,  0x10,  0x1C,  0x60,  0x08,  0x10,  0x7F,  0xFE,  0x11,  0x22,  0x66,  0xCC,  0x0F,  0xF8,  0x08,  0x08, 	/* 461D0 */
+	0x0F,  0xF8,  0x08,  0x08,  0x0F,  0xF8,  0x08,  0x08,  0x08,  0x08,  0x08,  0x18,  0x86,  0x00,  0x40,  0x3C, 	/* 461E0 */
+	0x78,  0x24,  0x90,  0x25,  0x20,  0x27,  0xFF,  0x3D,  0x00,  0x25,  0x00,  0x25,  0x7C,  0x25,  0x44,  0x3D, 	/* 461F0 */
+	0x44,  0x25,  0x44,  0x25,  0x58,  0x25,  0x42,  0x26,  0x42,  0x24,  0x42,  0x4C,  0x3E,  0x87,  0x00,  0x40, 	/* 46200 */
+	0x3C,  0x40,  0x25,  0xFC,  0x24,  0x44,  0x24,  0x44,  0x3C,  0x44,  0x24,  0x98,  0x25,  0x00,  0x25,  0x08, 	/* 46210 */
+	0x3F,  0xFE,  0x25,  0x4A,  0x25,  0x4A,  0x25,  0x4A,  0x25,  0x52,  0x26,  0x62,  0x4C,  0xCC,  0x88,  0x00, 	/* 46220 */
+	0x04,  0x3C,  0x18,  0x24,  0xE2,  0x24,  0x84,  0x24,  0xB8,  0x3C,  0xA2,  0x24,  0xA2,  0x24,  0xB4,  0x24, 	/* 46230 */
+	0xB4,  0x3C,  0xB8,  0x24,  0xA8,  0x24,  0xA8,  0x25,  0x24,  0x25,  0x24,  0x26,  0x22,  0x4C,  0x21,  0x89, 	/* 46240 */
+	0x00,  0x20,  0x3C,  0x10,  0x24,  0x08,  0x24,  0x00,  0x24,  0xF0,  0x3C,  0x11,  0x24,  0x19,  0x25,  0xDA, 	/* 46250 */
+	0x24,  0x5A,  0x3C,  0x54,  0x24,  0x94,  0x24,  0x92,  0x25,  0x12,  0x26,  0x11,  0x24,  0x10,  0x4C,  0x30, 	/* 46260 */
+	0x8A,  0x00,  0x80,  0x00,  0x80,  0x3D,  0x5E,  0x01,  0x40,  0x3A,  0x2E,  0x04,  0x10,  0x1F,  0xFC,  0x64, 	/* 46270 */
+	0x13,  0x04,  0x10,  0x07,  0xF0,  0x04,  0x10,  0x04,  0x10,  0x07,  0xF0,  0x04,  0x10,  0x04,  0x10,  0x04, 	/* 46280 */
+	0x30,  0x9A,  0x00,  0x80,  0x3C,  0x9E,  0x24,  0x92,  0x27,  0xF2,  0x24,  0x92,  0x3C,  0x92,  0x24,  0x92, 	/* 46290 */
+	0x27,  0xF2,  0x24,  0x92,  0x3C,  0x92,  0x24,  0xD2,  0x25,  0x52,  0x25,  0x7C,  0x27,  0xB0,  0x24,  0x30, 	/* 462A0 */
+	0x4C,  0x10,  0x9B,  0x00,  0x00,  0x3D,  0xFE,  0x24,  0x00,  0x25,  0x24,  0x25,  0x24,  0x3E,  0x48,  0x26, 	/* 462B0 */
+	0x48,  0x25,  0x24,  0x25,  0x24,  0x3C,  0x00,  0x25,  0xFE,  0x24,  0x20,  0x24,  0x20,  0x24,  0x20,  0x27, 	/* 462C0 */
+	0xFF,  0x4C,  0x00,  0xA3,  0x00,  0x00,  0x1F,  0xFE,  0x10,  0x00,  0x17,  0xFC,  0x10,  0x00,  0x1F,  0xFE, 	/* 462D0 */
+	0x22,  0x24,  0x23,  0x98,  0x5C,  0x07,  0x0F,  0xF8,  0x08,  0x08,  0x0F,  0xF8,  0x08,  0x08,  0x0F,  0xF8, 	/* 462E0 */
+	0x08,  0x08,  0x08,  0x18,  0xA9,  0x04,  0x80,  0x04,  0x80,  0x04,  0xFF,  0x09,  0x88,  0x09,  0x50,  0x16, 	/* 462F0 */
+	0x30,  0x14,  0xCC,  0x37,  0x03,  0x54,  0xFC,  0x14,  0x84,  0x14,  0xFC,  0x14,  0x84,  0x14,  0xFC,  0x14, 	/* 46300 */
+	0x84,  0x10,  0x84,  0x10,  0x8C,  0xAF,  0x00,  0x24,  0x3C,  0x22,  0x27,  0xFF,  0x24,  0x20,  0x24,  0x20, 	/* 46310 */
+	0x3D,  0xFE,  0x25,  0x22,  0x25,  0x22,  0x25,  0xFE,  0x3D,  0x22,  0x25,  0x22,  0x25,  0xFE,  0x25,  0x22, 	/* 46320 */
+	0x25,  0x22,  0x25,  0x22,  0x4D,  0x26,  0xB1,  0x00,  0x44,  0x1E,  0x24,  0x12,  0x28,  0x12,  0x7E,  0x12, 	/* 46330 */
+	0x42,  0x1E,  0x42,  0x12,  0x42,  0x12,  0x42,  0x12,  0x7E,  0x1E,  0x28,  0x12,  0x28,  0x12,  0x28,  0x12, 	/* 46340 */
+	0x48,  0x22,  0x49,  0x22,  0x89,  0x47,  0x07,  0xB3,  0x00,  0x22,  0x3D,  0x12,  0x24,  0x92,  0x24,  0x94, 	/* 46350 */
+	0x24,  0x84,  0x3C,  0x08,  0x24,  0x86,  0x24,  0xCA,  0x24,  0xAA,  0x3C,  0x92,  0x24,  0x9A,  0x24,  0xAA, 	/* 46360 */
+	0x24,  0xA6,  0x24,  0xC2,  0x24,  0xFE,  0x4C,  0x00,  0xB9,  0x00,  0x00,  0x3C,  0xFE,  0x24,  0x80,  0x24, 	/* 46370 */
+	0xFC,  0x24,  0x80,  0x3C,  0xFC,  0x24,  0x80,  0x24,  0x80,  0x27,  0xFF,  0x3C,  0xA2,  0x24,  0x94,  0x24, 	/* 46380 */
+	0x98,  0x24,  0x88,  0x24,  0xA4,  0x24,  0xC2,  0x4F,  0x01,  0xBE,  0x00,  0x20,  0x3C,  0x40,  0x25,  0xFC, 	/* 46390 */
+	0x25,  0x24,  0x25,  0x24,  0x3D,  0xFC,  0x25,  0x24,  0x25,  0x24,  0x25,  0xFC,  0x3C,  0x50,  0x24,  0x90, 	/* 463A0 */
+	0x27,  0xFF,  0x24,  0x10,  0x24,  0x10,  0x24,  0x10,  0x4C,  0x10,  0x86,  0x00,  0x50,  0x3C,  0x50,  0x24, 	/* 463B0 */
+	0x50,  0x25,  0xFC,  0x25,  0x54,  0x3D,  0x54,  0x25,  0x54,  0x25,  0xFC,  0x25,  0x54,  0x3D,  0x54,  0x25, 	/* 463C0 */
+	0x54,  0x27,  0xFF,  0x24,  0x00,  0x24,  0x58,  0x25,  0x84,  0x4E,  0x02,  0x8B,  0x00,  0x20,  0x3C,  0x20, 	/* 463D0 */
+	0x27,  0xFF,  0x24,  0x90,  0x24,  0x90,  0x3C,  0x9E,  0x25,  0x12,  0x25,  0x32,  0x27,  0x2A,  0x3D,  0x64, 	/* 463E0 */
+	0x25,  0x94,  0x25,  0x08,  0x25,  0x18,  0x25,  0x24,  0x25,  0x42,  0x4D,  0x81,  0x8E,  0x00,  0x00,  0x7F, 	/* 463F0 */
+	0xFC,  0x48,  0x44,  0x7E,  0x24,  0x42,  0x28,  0x7E,  0x18,  0x48,  0x64,  0x7F,  0x83,  0x40,  0x00,  0x0F, 	/* 46400 */
+	0xF0,  0x08,  0x10,  0x0F,  0xF0,  0x08,  0x10,  0x0F,  0xF0,  0x08,  0x10,  0x08,  0x30,  0x90,  0x00,  0x80, 	/* 46410 */
+	0x00,  0x80,  0x1F,  0xFF,  0x11,  0x08,  0x12,  0xFF,  0x16,  0x88,  0x1A,  0x48,  0x12,  0x18,  0x10,  0x40, 	/* 46420 */
+	0x17,  0xFC,  0x14,  0xA4,  0x15,  0x54,  0x24,  0x44,  0x24,  0xA4,  0x45,  0x14,  0x04,  0x0C,  0x91,  0x00, 	/* 46430 */
+	0x10,  0x3C,  0x10,  0x25,  0xFF,  0x25,  0x20,  0x25,  0x24,  0x3D,  0x24,  0x25,  0x7F,  0x25,  0x44,  0x25, 	/* 46440 */
+	0xE4,  0x3D,  0x54,  0x25,  0x54,  0x25,  0x44,  0x25,  0x44,  0x25,  0x44,  0x26,  0x44,  0x4C,  0x4C,  0x93, 	/* 46450 */
+	0x00,  0x28,  0x3C,  0x28,  0x24,  0x28,  0x25,  0xEF,  0x24,  0x28,  0x3C,  0x28,  0x24,  0x28,  0x25,  0xEF, 	/* 46460 */
+	0x24,  0x28,  0x3C,  0x28,  0x24,  0xE8,  0x27,  0x2F,  0x24,  0x48,  0x24,  0x48,  0x24,  0x88,  0x4D,  0x08, 	/* 46470 */
+	0x94,  0x00,  0x20,  0x3C,  0x20,  0x27,  0xFE,  0x26,  0x52,  0x26,  0x52,  0x3C,  0x50,  0x24,  0x9E,  0x25, 	/* 46480 */
+	0x00,  0x26,  0x00,  0x3D,  0xFC,  0x24,  0x20,  0x24,  0x20,  0x24,  0x20,  0x24,  0x20,  0x27,  0xFF,  0x4C, 	/* 46490 */
+	0x00,  0x95,  0x00,  0x10,  0x3C,  0x10,  0x25,  0xFF,  0x25,  0x01,  0x25,  0x41,  0x3C,  0x4E,  0x24,  0xFA, 	/* 464A0 */
+	0x24,  0x9A,  0x24,  0x9A,  0x3D,  0x2A,  0x26,  0xAA,  0x24,  0x4C,  0x24,  0x48,  0x24,  0x89,  0x25,  0x09, 	/* 464B0 */
+	0x4E,  0x07,  0x9F,  0x00,  0x20,  0x3C,  0x20,  0x27,  0xFF,  0x26,  0x01,  0x26,  0x01,  0x3D,  0xFE,  0x24, 	/* 464C0 */
+	0x20,  0x24,  0x4C,  0x25,  0xFA,  0x3C,  0x20,  0x24,  0x20,  0x25,  0xFE,  0x24,  0x20,  0x24,  0x20,  0x27, 	/* 464D0 */
+	0xFF,  0x4C,  0x00,  0xA5,  0x00,  0x00,  0x3C,  0xFC,  0x24,  0x84,  0x24,  0xFC,  0x24,  0x84,  0x3C,  0x84, 	/* 464E0 */
+	0x24,  0xFC,  0x24,  0x10,  0x24,  0x90,  0x3C,  0xFE,  0x25,  0x10,  0x26,  0xFE,  0x24,  0x10,  0x24,  0x10, 	/* 464F0 */
+	0x27,  0xFF,  0x4C,  0x00,  0xA6,  0x00,  0x92,  0x3C,  0x92,  0x27,  0x6C,  0x25,  0x24,  0x24,  0x92,  0x3C, 	/* 46500 */
+	0x92,  0x24,  0x20,  0x25,  0xFE,  0x25,  0x0A,  0x3D,  0xCA,  0x25,  0x32,  0x25,  0x12,  0x25,  0x2A,  0x25, 	/* 46510 */
+	0x42,  0x25,  0xFE,  0x4C,  0x00,  0xAB,  0x00,  0x04,  0x3C,  0x18,  0x25,  0xE0,  0x24,  0x20,  0x27,  0xFF, 	/* 46520 */
+	0x3C,  0x20,  0x25,  0xFC,  0x25,  0x24,  0x25,  0xFC,  0x3D,  0x24,  0x25,  0xFC,  0x24,  0x20,  0x25,  0xFC, 	/* 46530 */
+	0x24,  0x20,  0x27,  0xFF,  0x4C,  0x00,  0xAE,  0x00,  0x00,  0x3C,  0xFE,  0x24,  0x92,  0x24,  0x92,  0x24, 	/* 46540 */
+	0xFE,  0x3C,  0x92,  0x24,  0x92,  0x24,  0x92,  0x24,  0xFE,  0x3C,  0x00,  0x25,  0x50,  0x25,  0x48,  0x25, 	/* 46550 */
+	0x4A,  0x26,  0x41,  0x24,  0x45,  0x4C,  0x3C,  0xB0,  0x00,  0x00,  0x3F,  0xFE,  0x24,  0x50,  0x24,  0x50, 	/* 46560 */
+	0x25,  0xFC,  0x3D,  0x54,  0x25,  0x54,  0x25,  0xFC,  0x24,  0x20,  0x3F,  0xFF,  0x24,  0x48,  0x24,  0x88, 	/* 46570 */
+	0x25,  0xD0,  0x24,  0x30,  0x24,  0x48,  0x4D,  0x84,  0xB1,  0x00,  0x10,  0x38,  0x10,  0x2F,  0xFE,  0x28, 	/* 46580 */
+	0x92,  0x29,  0x7F,  0x39,  0x12,  0x2A,  0x12,  0x2B,  0xFE,  0x28,  0x90,  0x3A,  0xFE,  0x2A,  0x90,  0x29, 	/* 46590 */
+	0xFF,  0x29,  0x10,  0x2A,  0x90,  0x2C,  0x60,  0x58,  0x1F,  0xB4,  0x00,  0x20,  0x3C,  0x60,  0x25,  0xAC, 	/* 465A0 */
+	0x25,  0x24,  0x25,  0x24,  0x3D,  0xAC,  0x25,  0x24,  0x25,  0x24,  0x25,  0xFC,  0x3C,  0x20,  0x24,  0x50, 	/* 465B0 */
+	0x24,  0x50,  0x24,  0x88,  0x24,  0x84,  0x25,  0x02,  0x4E,  0x01,  0xB8,  0x00,  0x00,  0x3C,  0xFC,  0x24, 	/* 465C0 */
+	0x84,  0x24,  0xFC,  0x24,  0x84,  0x3C,  0x84,  0x24,  0xFC,  0x24,  0x00,  0x27,  0xFF,  0x3C,  0x80,  0x25, 	/* 465D0 */
+	0xFE,  0x26,  0x52,  0x24,  0x92,  0x25,  0x22,  0x24,  0x42,  0x4C,  0x8C,  0xB9,  0x00,  0x40,  0x3E,  0x40, 	/* 465E0 */
+	0x22,  0x7F,  0x22,  0x80,  0x22,  0xFC,  0x3F,  0x44,  0x22,  0x7C,  0x22,  0x44,  0x22,  0x7C,  0x3E,  0x20, 	/* 465F0 */
+	0x22,  0x7C,  0x22,  0xC4,  0x23,  0x28,  0x22,  0x18,  0x22,  0x64,  0x47,  0x83,  0xBA,  0x00,  0x10,  0x3C, 	/* 46600 */
+	0x20,  0x24,  0xFC,  0x24,  0x84,  0x24,  0xFC,  0x3C,  0x84,  0x24,  0x84,  0x24,  0xFC,  0x24,  0x22,  0x3C, 	/* 46610 */
+	0x22,  0x27,  0xF4,  0x24,  0xA8,  0x25,  0x24,  0x26,  0x22,  0x24,  0x21,  0x4C,  0x60,  0xBF,  0x00,  0x00, 	/* 46620 */
+	0x3C,  0x3E,  0x25,  0x22,  0x24,  0xA2,  0x24,  0xBE,  0x3C,  0x22,  0x24,  0x22,  0x27,  0xBE,  0x24,  0xA9, 	/* 46630 */
+	0x3C,  0xAA,  0x24,  0xA4,  0x24,  0xA4,  0x25,  0xB2,  0x25,  0x61,  0x26,  0x30,  0x4C,  0x0F,  0x80,  0x00, 	/* 46640 */
+	0x20,  0x3C,  0x20,  0x25,  0xFE,  0x24,  0x84,  0x24,  0x48,  0x3F,  0xFF,  0x26,  0x01,  0x26,  0x21,  0x24, 	/* 46650 */
+	0x20,  0x3F,  0xFF,  0x24,  0x40,  0x24,  0x7C,  0x24,  0x44,  0x24,  0x84,  0x25,  0x04,  0x4E,  0x18,  0x82, 	/* 46660 */
+	0x08,  0x20,  0x7F,  0x3F,  0x10,  0x40,  0x1E,  0xBE,  0x13,  0x29,  0x12,  0x26,  0x22,  0x34,  0x4C,  0xE2, 	/* 46670 */
+	0x00,  0x01,  0x0F,  0xF8,  0x08,  0x08,  0x0F,  0xF8,  0x08,  0x08,  0x0F,  0xF8,  0x08,  0x08,  0x08,  0x18, 	/* 46680 */
+	0x83,  0x00,  0x00,  0x3C,  0xFC,  0x24,  0xA4,  0x24,  0xA4,  0x24,  0xB4,  0x3C,  0xAC,  0x24,  0xC4,  0x24, 	/* 46690 */
+	0xFC,  0x24,  0x00,  0x3D,  0xFE,  0x25,  0x52,  0x25,  0x52,  0x25,  0x52,  0x25,  0x52,  0x27,  0xFF,  0x4C, 	/* 466A0 */
+	0x00,  0x88,  0x00,  0x00,  0x3F,  0xFF,  0x24,  0x00,  0x24,  0xFC,  0x24,  0x84,  0x3C,  0xFC,  0x24,  0x00, 	/* 466B0 */
+	0x25,  0xFE,  0x25,  0x52,  0x3D,  0x52,  0x25,  0x9E,  0x25,  0xFA,  0x25,  0x22,  0x25,  0x22,  0x25,  0x22, 	/* 466C0 */
+	0x4D,  0x06,  0x8A,  0x00,  0x24,  0x3C,  0x22,  0x27,  0xFF,  0x24,  0x20,  0x25,  0xFC,  0x3D,  0x24,  0x25, 	/* 466D0 */
+	0xFC,  0x25,  0x24,  0x25,  0xFC,  0x3D,  0x24,  0x24,  0x08,  0x27,  0xFF,  0x24,  0x88,  0x24,  0x48,  0x24, 	/* 466E0 */
+	0x08,  0x4C,  0x18,  0x8F,  0x00,  0x80,  0x7F,  0xFE,  0x08,  0x10,  0x0F,  0xF0,  0x00,  0x00,  0x7F,  0xFE, 	/* 466F0 */
+	0x48,  0x12,  0x4F,  0xF2,  0x00,  0x00,  0x0F,  0xF0,  0x08,  0x10,  0x0F,  0xF0,  0x08,  0x10,  0x0F,  0xF0, 	/* 46700 */
+	0x08,  0x10,  0x08,  0x30,  0x93,  0x00,  0x80,  0x3C,  0xFE,  0x25,  0x00,  0x25,  0xFC,  0x26,  0x84,  0x3C, 	/* 46710 */
+	0xFC,  0x24,  0x84,  0x24,  0xFC,  0x24,  0x00,  0x3F,  0xFF,  0x24,  0x40,  0x24,  0xFE,  0x27,  0x4A,  0x24, 	/* 46720 */
+	0x92,  0x25,  0x22,  0x4C,  0x4C,  0x95,  0x00,  0x00,  0x3B,  0xFE,  0x2A,  0x22,  0x2A,  0x2A,  0x2B,  0xFE, 	/* 46730 */
+	0x3A,  0x22,  0x2B,  0xEA,  0x2B,  0x6A,  0x2B,  0x52,  0x3B,  0xD2,  0x2A,  0x76,  0x2B,  0xAE,  0x2A,  0x46, 	/* 46740 */
+	0x2A,  0x82,  0x4B,  0xFE,  0x58,  0x00,  0x9A,  0x00,  0x80,  0x00,  0xFC,  0x00,  0x80,  0x1F,  0xFF,  0x11, 	/* 46750 */
+	0x1A,  0x1F,  0xE0,  0x10,  0x82,  0x17,  0xFE,  0x14,  0x44,  0x17,  0xFC,  0x12,  0x08,  0x13,  0xF8,  0x22, 	/* 46760 */
+	0x08,  0x23,  0xF8,  0x42,  0x08,  0x02,  0x18,  0x9C,  0x00,  0x48,  0x3C,  0x48,  0x27,  0xFF,  0x24,  0x48, 	/* 46770 */
+	0x24,  0x48,  0x3C,  0xFC,  0x24,  0x84,  0x24,  0xFC,  0x24,  0x84,  0x3C,  0xFC,  0x24,  0x20,  0x27,  0xFF, 	/* 46780 */
+	0x24,  0x20,  0x24,  0x50,  0x25,  0x8C,  0x4E,  0x03,  0x9D,  0x00,  0x20,  0x3C,  0x20,  0x27,  0xFF,  0x24, 	/* 46790 */
+	0x70,  0x24,  0xAC,  0x3F,  0x23,  0x24,  0x50,  0x24,  0x8C,  0x27,  0x23,  0x3D,  0x24,  0x24,  0xA8,  0x24, 	/* 467A0 */
+	0xF0,  0x25,  0xAC,  0x26,  0x23,  0x24,  0x20,  0x4C,  0x60,  0xA0,  0x00,  0x00,  0x3F,  0xDE,  0x24,  0xC6, 	/* 467B0 */
+	0x27,  0x5A,  0x24,  0xC6,  0x3F,  0x5A,  0x24,  0x62,  0x24,  0x50,  0x24,  0x8C,  0x3F,  0x23,  0x24,  0x48, 	/* 467C0 */
+	0x25,  0x92,  0x24,  0x64,  0x25,  0x88,  0x24,  0x30,  0x4D,  0xC0,  0xA3,  0x00,  0x10,  0x3C,  0x10,  0x25, 	/* 467D0 */
+	0xFF,  0x25,  0x29,  0x24,  0x4A,  0x3D,  0x86,  0x25,  0xFF,  0x24,  0x28,  0x24,  0x46,  0x3D,  0xFD,  0x24, 	/* 467E0 */
+	0x10,  0x24,  0xFE,  0x24,  0x10,  0x24,  0x10,  0x27,  0xFF,  0x4C,  0x00,  0xA4,  0x00,  0x00,  0x3C,  0xFE, 	/* 467F0 */
+	0x24,  0x10,  0x25,  0xFF,  0x25,  0x11,  0x3D,  0xDD,  0x25,  0x11,  0x24,  0xDC,  0x24,  0x00,  0x3C,  0xFC, 	/* 46800 */
+	0x24,  0x04,  0x27,  0xFF,  0x24,  0x04,  0x24,  0x04,  0x24,  0xFC,  0x4C,  0x00,  0xA8,  0x00,  0x84,  0x3C, 	/* 46810 */
+	0x84,  0x27,  0xE4,  0x24,  0x88,  0x24,  0x88,  0x3F,  0xF2,  0x24,  0x02,  0x25,  0xE4,  0x25,  0x24,  0x3D, 	/* 46820 */
+	0xE9,  0x26,  0x31,  0x25,  0x22,  0x25,  0x42,  0x24,  0xE4,  0x27,  0x08,  0x4C,  0x30,  0xA9,  0x00,  0x0C, 	/* 46830 */
+	0x3C,  0x0A,  0x24,  0x08,  0x27,  0xFF,  0x24,  0x08,  0x3D,  0xE8,  0x24,  0x08,  0x27,  0xF8,  0x25,  0x28, 	/* 46840 */
+	0x3D,  0xE8,  0x25,  0x24,  0x25,  0xE4,  0x25,  0x25,  0x25,  0xE5,  0x24,  0xA3,  0x4F,  0x11,  0xB0,  0x00, 	/* 46850 */
+	0x0C,  0x3D,  0xF0,  0x25,  0x24,  0x24,  0xA8,  0x27,  0xFF,  0x3C,  0x70,  0x24,  0xA8,  0x25,  0x24,  0x27, 	/* 46860 */
+	0xFE,  0x3D,  0x25,  0x25,  0x24,  0x25,  0xFC,  0x25,  0x24,  0x25,  0x24,  0x25,  0xFC,  0x4C,  0x00,  0xB3, 	/* 46870 */
+	0x01,  0x02,  0x3C,  0x84,  0x27,  0xFE,  0x24,  0x20,  0x25,  0xFC,  0x3C,  0x20,  0x27,  0xFF,  0x25,  0x24, 	/* 46880 */
+	0x24,  0xA8,  0x3F,  0xFF,  0x24,  0x00,  0x25,  0xFC,  0x25,  0x04,  0x25,  0x04,  0x25,  0xFC,  0x4C,  0x00, 	/* 46890 */
+	0xB5,  0x00,  0x88,  0x3C,  0x88,  0x27,  0xFF,  0x24,  0x88,  0x24,  0x20,  0x3F,  0xFE,  0x24,  0x84,  0x24, 	/* 468A0 */
+	0x84,  0x25,  0x4C,  0x3E,  0x52,  0x24,  0x20,  0x27,  0xFF,  0x24,  0x20,  0x24,  0x20,  0x24,  0x20,  0x4C, 	/* 468B0 */
+	0x20,  0xB8,  0x00,  0x10,  0x3D,  0x7F,  0x24,  0x90,  0x24,  0xBE,  0x26,  0x48,  0x3D,  0x3F,  0x25,  0x00, 	/* 468C0 */
+	0x24,  0x3E,  0x27,  0xA2,  0x3C,  0xBE,  0x24,  0xA2,  0x24,  0xBE,  0x24,  0xA2,  0x25,  0x66,  0x26,  0x20, 	/* 468D0 */
+	0x4C,  0x1F,  0xBA,  0x00,  0x40,  0x1F,  0xFF,  0x11,  0x48,  0x12,  0xFE,  0x17,  0x90,  0x1A,  0xFE,  0x12, 	/* 468E0 */
+	0x90,  0x12,  0xFF,  0x10,  0x00,  0x13,  0xFC,  0x12,  0x04,  0x13,  0xFC,  0x22,  0x04,  0x23,  0xFC,  0x42, 	/* 468F0 */
+	0x04,  0x02,  0x0C,  0xBD,  0x00,  0x20,  0x3C,  0x7C,  0x25,  0x88,  0x27,  0xFF,  0x25,  0x29,  0x3D,  0xC7, 	/* 46900 */
+	0x25,  0x7C,  0x25,  0x00,  0x25,  0xFF,  0x3D,  0x00,  0x25,  0x7E,  0x25,  0x00,  0x25,  0x7E,  0x25,  0x42, 	/* 46910 */
+	0x26,  0x7E,  0x4C,  0x00,  0xBE,  0x00,  0x20,  0x3C,  0x50,  0x24,  0x88,  0x25,  0x74,  0x26,  0x03,  0x3D, 	/* 46920 */
+	0xFE,  0x25,  0xA6,  0x25,  0x6A,  0x25,  0xFE,  0x3C,  0x00,  0x24,  0xFC,  0x24,  0x84,  0x24,  0xFC,  0x24, 	/* 46930 */
+	0x84,  0x24,  0xFC,  0x4C,  0x00,  0xBF,  0x00,  0x50,  0x3D,  0xFE,  0x25,  0x52,  0x25,  0xFE,  0x25,  0x52, 	/* 46940 */
+	0x3D,  0xFE,  0x24,  0x00,  0x25,  0xFE,  0x25,  0x00,  0x3D,  0x7E,  0x25,  0x00,  0x25,  0xFF,  0x25,  0x52, 	/* 46950 */
+	0x25,  0x4C,  0x26,  0x64,  0x4D,  0x83,  0x80,  0x00,  0x00,  0x3F,  0x3C,  0x21,  0x24,  0x3F,  0x25,  0x2A, 	/* 46960 */
+	0x43,  0x3F,  0xBC,  0x2A,  0x24,  0x5F,  0x98,  0x11,  0x24,  0x2F,  0xFB,  0x08,  0x08,  0x0F,  0xF8,  0x08, 	/* 46970 */
+	0x08,  0x0F,  0xF8,  0x08,  0x08,  0x08,  0x18,  0x82,  0x00,  0x10,  0x1F,  0xFE,  0x11,  0x44,  0x1F,  0x28, 	/* 46980 */
+	0x10,  0xFF,  0x1F,  0x10,  0x29,  0x7E,  0x2F,  0x10,  0x40,  0x10,  0x0F,  0xF8,  0x08,  0x08,  0x0F,  0xF8, 	/* 46990 */
+	0x08,  0x08,  0x0F,  0xF8,  0x08,  0x08,  0x08,  0x18,  0x86,  0x00,  0x20,  0x3C,  0x20,  0x27,  0xFE,  0x24, 	/* 469A0 */
+	0x84,  0x24,  0x48,  0x3F,  0xFF,  0x24,  0x00,  0x24,  0xFC,  0x24,  0x84,  0x3C,  0xFC,  0x24,  0x84,  0x24, 	/* 469B0 */
+	0xFC,  0x25,  0x20,  0x25,  0x56,  0x26,  0x45,  0x4C,  0x3C,  0x88,  0x00,  0x48,  0x3F,  0xFF,  0x24,  0x48, 	/* 469C0 */
+	0x24,  0xFC,  0x24,  0x84,  0x3C,  0xFC,  0x24,  0x84,  0x24,  0xFC,  0x24,  0x40,  0x3C,  0xFE,  0x25,  0x92, 	/* 469D0 */
+	0x26,  0x9A,  0x24,  0xA6,  0x24,  0xFA,  0x24,  0x02,  0x4C,  0x0C,  0x89,  0x00,  0x20,  0x3C,  0x20,  0x24, 	/* 469E0 */
+	0x50,  0x24,  0x88,  0x25,  0x04,  0x3E,  0xFA,  0x24,  0x01,  0x27,  0xDE,  0x26,  0x52,  0x3E,  0x52,  0x27, 	/* 469F0 */
+	0xDE,  0x24,  0x84,  0x24,  0x84,  0x24,  0xC6,  0x25,  0x29,  0x4E,  0x10,  0x8D,  0x00,  0x20,  0x3C,  0x20, 	/* 46A00 */
+	0x27,  0xFF,  0x24,  0x51,  0x27,  0xAE,  0x3D,  0xAA,  0x26,  0xAA,  0x25,  0xAD,  0x24,  0x00,  0x3C,  0x82, 	/* 46A10 */
+	0x24,  0xFE,  0x24,  0x82,  0x24,  0xFE,  0x24,  0x82,  0x24,  0x82,  0x4D,  0x02,  0x91,  0x00,  0x00,  0x3D, 	/* 46A20 */
+	0xFE,  0x24,  0x10,  0x25,  0xFF,  0x25,  0x11,  0x3D,  0xDD,  0x25,  0x11,  0x24,  0xDC,  0x24,  0x00,  0x3F, 	/* 46A30 */
+	0xFF,  0x24,  0x20,  0x24,  0xFE,  0x24,  0xAA,  0x24,  0xAA,  0x24,  0xAA,  0x4C,  0x86,  0x93,  0x00,  0x88, 	/* 46A40 */
+	0x3B,  0xFF,  0x28,  0x88,  0x28,  0x8A,  0x28,  0x09,  0x3B,  0xFF,  0x2A,  0x08,  0x2A,  0xFA,  0x3A,  0xAA, 	/* 46A50 */
+	0x2A,  0xFA,  0x2A,  0x94,  0x2A,  0xF4,  0x2A,  0xA5,  0x2A,  0xFB,  0x2C,  0x13,  0x58,  0x21,  0x98,  0x00, 	/* 46A60 */
+	0x92,  0x3B,  0x24,  0x28,  0x92,  0x2B,  0xFC,  0x2A,  0x54,  0x3A,  0x24,  0x2A,  0xD4,  0x2B,  0xFC,  0x28, 	/* 46A70 */
+	0x00,  0x3B,  0x34,  0x2A,  0xAC,  0x2B,  0x34,  0x2A,  0xAC,  0x2A,  0x25,  0x2B,  0xB5,  0x5E,  0x43,  0x99, 	/* 46A80 */
+	0x00,  0x48,  0x3C,  0x48,  0x27,  0xFF,  0x24,  0x48,  0x24,  0x78,  0x3C,  0x84,  0x27,  0xF5,  0x24,  0xD6, 	/* 46A90 */
+	0x24,  0xD4,  0x3C,  0xD4,  0x25,  0xF5,  0x26,  0x83,  0x24,  0x00,  0x25,  0x52,  0x25,  0x49,  0x4E,  0x49, 	/* 46AA0 */
+	0x9A,  0x00,  0x10,  0x3C,  0x1E,  0x24,  0x10,  0x25,  0xFF,  0x25,  0x39,  0x3D,  0xE2,  0x25,  0x7E,  0x25, 	/* 46AB0 */
+	0x54,  0x25,  0x7C,  0x3D,  0x54,  0x25,  0x7C,  0x25,  0x00,  0x25,  0xFE,  0x26,  0xAA,  0x25,  0xFF,  0x4C, 	/* 46AC0 */
+	0x00,  0x9F,  0x00,  0x48,  0x3B,  0xFF,  0x28,  0x48,  0x28,  0x4A,  0x2A,  0x09,  0x3A,  0xFF,  0x2A,  0x88, 	/* 46AD0 */
+	0x2B,  0xF8,  0x28,  0xA8,  0x3B,  0xF4,  0x2A,  0x94,  0x2A,  0xF5,  0x2D,  0xA5,  0x29,  0xFB,  0x4A,  0x0B, 	/* 46AE0 */
+	0x5C,  0x31,  0xA0,  0x10,  0x04,  0x13,  0xC4,  0x68,  0x1A,  0x17,  0xE4,  0x28,  0x0A,  0x7F,  0xDF,  0x12, 	/* 46AF0 */
+	0x44,  0x5B,  0xD5,  0x54,  0x15,  0x10,  0x84,  0x1F,  0xFC,  0x11,  0x44,  0x16,  0xB4,  0x11,  0x44,  0x16, 	/* 46B00 */
+	0x34,  0x10,  0x0C,  0xA3,  0x00,  0x00,  0x3F,  0xFE,  0x20,  0x80,  0x20,  0x80,  0x20,  0x80,  0x3F,  0xF8, 	/* 46B10 */
+	0x20,  0x08,  0x20,  0x08,  0x20,  0x08,  0x3F,  0xF8,  0x20,  0x80,  0x20,  0x80,  0x20,  0x80,  0x20,  0x80, 	/* 46B20 */
+	0x3F,  0xFE,  0x00,  0x00,  0xA5,  0x00,  0x10,  0x3F,  0x90,  0x24,  0x10,  0x24,  0x10,  0x24,  0x10,  0x3F, 	/* 46B30 */
+	0x10,  0x21,  0x10,  0x21,  0x28,  0x21,  0x28,  0x3F,  0x28,  0x24,  0x28,  0x24,  0x44,  0x24,  0x44,  0x3F, 	/* 46B40 */
+	0x84,  0x01,  0x02,  0x02,  0x01,  0xA7,  0x00,  0x14,  0x00,  0x12,  0x20,  0x12,  0x2F,  0xFF,  0x28,  0x10, 	/* 46B50 */
+	0x3B,  0xF2,  0x2A,  0x92,  0x0A,  0x92,  0x7B,  0xEC,  0x2A,  0x2C,  0x2B,  0xE8,  0x2A,  0x89,  0x52,  0x95, 	/* 46B60 */
+	0x13,  0xF5,  0x20,  0x23,  0x40,  0x41,  0xA8,  0x00,  0x40,  0x7E,  0x40,  0x48,  0xFE,  0x48,  0x80,  0x49, 	/* 46B70 */
+	0xF8,  0x7E,  0x88,  0x42,  0x88,  0x42,  0xF8,  0x7E,  0x00,  0x48,  0x00,  0x4B,  0xDE,  0x4A,  0x52,  0x4A, 	/* 46B80 */
+	0x52,  0x7E,  0x52,  0x03,  0xDE,  0x00,  0x00,  0xAA,  0x01,  0x00,  0x01,  0x00,  0x02,  0x00,  0x1F,  0xFC, 	/* 46B90 */
+	0x10,  0x04,  0x10,  0x04,  0x10,  0x04,  0x1F,  0xFC,  0x10,  0x04,  0x10,  0x04,  0x1F,  0xFC,  0x10,  0x04, 	/* 46BA0 */
+	0x10,  0x04,  0x10,  0x04,  0x1F,  0xFC,  0x00,  0x00,  0xAD,  0x00,  0x80,  0x01,  0x00,  0x0F,  0xF8,  0x08, 	/* 46BB0 */
+	0x08,  0x0F,  0xF8,  0x08,  0x08,  0x0F,  0xF8,  0x08,  0x08,  0x08,  0x08,  0x0F,  0xF8,  0x00,  0x80,  0x7F, 	/* 46BC0 */
+	0xFF,  0x01,  0x40,  0x02,  0x20,  0x0C,  0x18,  0x70,  0x07,  0xB3,  0x00,  0x00,  0x7F,  0xFF,  0x01,  0x20, 	/* 46BD0 */
+	0x01,  0x10,  0x02,  0x08,  0x04,  0x78,  0x1F,  0x84,  0x00,  0x04,  0x00,  0x80,  0x00,  0x80,  0x1F,  0xFC, 	/* 46BE0 */
+	0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x7F,  0xFF,  0x00,  0x00,  0xB4,  0x00,  0x40,  0x7F,  0x40,  0x08, 	/* 46BF0 */
+	0x40,  0x08,  0x7F,  0x14,  0x44,  0x12,  0x84,  0x26,  0xA4,  0x79,  0x24,  0x09,  0x28,  0x08,  0x18,  0x3E, 	/* 46C00 */
+	0x10,  0x08,  0x18,  0x0B,  0x28,  0x0C,  0x44,  0x70,  0x82,  0x03,  0x01,  0xBA,  0x00,  0x80,  0x3F,  0xFE, 	/* 46C10 */
+	0x00,  0x80,  0x1F,  0xFC,  0x07,  0xF0,  0x04,  0x10,  0x3F,  0xFE,  0x20,  0x02,  0x3F,  0xFA,  0x02,  0x20, 	/* 46C20 */
+	0x0F,  0xD0,  0x00,  0x88,  0x1F,  0xFC,  0x00,  0x80,  0x7F,  0xFF,  0x00,  0x00,  0xBB,  0x00,  0x10,  0x7F, 	/* 46C30 */
+	0x10,  0x08,  0xFF,  0x08,  0x10,  0x14,  0xFE,  0x12,  0x28,  0x7D,  0xFF,  0x08,  0x24,  0x08,  0x4A,  0x3E, 	/* 46C40 */
+	0xF1,  0x09,  0x10,  0x08,  0xFF,  0x0E,  0x38,  0x18,  0x54,  0x60,  0x92,  0x00,  0x10,  0xBC,  0x00,  0x80, 	/* 46C50 */
+	0x03,  0x00,  0x1C,  0x7C,  0x10,  0x04,  0x10,  0x04,  0x10,  0x04,  0x10,  0x04,  0x10,  0x04,  0x1E,  0x7C, 	/* 46C60 */
+	0x10,  0x04,  0x10,  0x04,  0x10,  0x04,  0x10,  0x04,  0x10,  0x04,  0x1F,  0xFC,  0x00,  0x00,  0xBE,  0x02, 	/* 46C70 */
+	0x80,  0x02,  0x80,  0x1C,  0xBC,  0x10,  0x84,  0x10,  0x84,  0x1E,  0xBC,  0x10,  0x84,  0x10,  0x84,  0x10, 	/* 46C80 */
+	0x84,  0x1E,  0xBC,  0x00,  0x80,  0x01,  0x40,  0x02,  0x20,  0x04,  0x10,  0x18,  0x0C,  0x60,  0x03,  0x81, 	/* 46C90 */
+	0x01,  0x00,  0x0E,  0x3C,  0x08,  0x04,  0x08,  0x04,  0x0F,  0x3C,  0x08,  0x04,  0x08,  0x04,  0x0F,  0xFC, 	/* 46CA0 */
+	0x02,  0x10,  0x02,  0x10,  0x7F,  0xFF,  0x02,  0x10,  0x02,  0x10,  0x02,  0x10,  0x04,  0x10,  0x18,  0x10, 	/* 46CB0 */
+	0x82,  0x00,  0x80,  0x00,  0x80,  0x3F,  0xFE,  0x00,  0x80,  0x1F,  0xFC,  0x01,  0x40,  0x7F,  0xFF,  0x02, 	/* 46CC0 */
+	0x20,  0x04,  0x90,  0x19,  0x0C,  0x6E,  0x7B,  0x08,  0x08,  0x0F,  0x38,  0x08,  0x08,  0x0F,  0xF8,  0x00, 	/* 46CD0 */
+	0x00,  0x85,  0x01,  0x00,  0x1E,  0x3C,  0x10,  0x04,  0x1F,  0x3C,  0x10,  0x04,  0x1F,  0xFC,  0x00,  0x00, 	/* 46CE0 */
+	0x1F,  0xFC,  0x1F,  0xFC,  0x10,  0x84,  0x1F,  0xFC,  0x00,  0x80,  0x7F,  0xFE,  0x01,  0x02,  0x06,  0x02, 	/* 46CF0 */
+	0x38,  0x0C,  0x87,  0x01,  0x00,  0x05,  0x00,  0x05,  0xDC,  0x19,  0x04,  0x11,  0x04,  0x1D,  0xDC,  0x10, 	/* 46D00 */
+	0x44,  0x10,  0x44,  0x1D,  0x5C,  0x11,  0x44,  0x11,  0x44,  0x11,  0x44,  0x7F,  0xFF,  0x04,  0x30,  0x18, 	/* 46D10 */
+	0x0C,  0x60,  0x02,  0x88,  0x04,  0x00,  0x08,  0x00,  0x37,  0xFE,  0x24,  0x12,  0x27,  0xF2,  0x3C,  0x1E, 	/* 46D20 */
+	0x25,  0xD2,  0x25,  0x52,  0x3D,  0x5E,  0x25,  0xD2,  0x25,  0x52,  0x24,  0x12,  0x7F,  0xFF,  0x04,  0x30, 	/* 46D30 */
+	0x18,  0x0C,  0x60,  0x02,  0x89,  0x02,  0x80,  0x1C,  0xDC,  0x10,  0x84,  0x1C,  0xDC,  0x10,  0x44,  0x1D, 	/* 46D40 */
+	0x5C,  0x11,  0x44,  0x7F,  0xFF,  0x08,  0x88,  0x10,  0x84,  0x27,  0xF2,  0x40,  0x81,  0x00,  0x80,  0x3F, 	/* 46D50 */
+	0xFE,  0x00,  0x80,  0x00,  0x80,  0x8A,  0x04,  0x10,  0x7F,  0xFF,  0x04,  0x10,  0x08,  0x20,  0x1F,  0xFC, 	/* 46D60 */
+	0x68,  0x40,  0x0F,  0xF0,  0x08,  0x40,  0x0F,  0xFC,  0x01,  0x00,  0x1E,  0x3C,  0x10,  0x04,  0x1F,  0x3C, 	/* 46D70 */
+	0x10,  0x04,  0x1F,  0xFC,  0x00,  0x00,  0x8C,  0x00,  0x18,  0x00,  0xE0,  0x1F,  0x80,  0x00,  0x80,  0x00, 	/* 46D80 */
+	0x80,  0x00,  0x80,  0x7F,  0xFF,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x0F,  0xF8,  0x08,  0x08,  0x08, 	/* 46D90 */
+	0x08,  0x08,  0x08,  0x0F,  0xF8,  0x00,  0x00,  0x8D,  0x00,  0x80,  0x00,  0x80,  0x01,  0x40,  0x02,  0x20, 	/* 46DA0 */
+	0x04,  0x10,  0x1F,  0xFC,  0x60,  0x83,  0x00,  0x80,  0x3F,  0xFE,  0x00,  0x80,  0x00,  0x80,  0x0F,  0xF8, 	/* 46DB0 */
+	0x08,  0x08,  0x08,  0x08,  0x0F,  0xF8,  0x00,  0x00,  0x8E,  0x00,  0x80,  0x00,  0x80,  0x01,  0x40,  0x02, 	/* 46DC0 */
+	0x20,  0x04,  0x90,  0x18,  0x8C,  0x6F,  0xFB,  0x00,  0x80,  0x00,  0x80,  0x7F,  0xFF,  0x00,  0x00,  0x0F, 	/* 46DD0 */
+	0xF8,  0x08,  0x08,  0x08,  0x08,  0x0F,  0xF8,  0x00,  0x00,  0x90,  0x02,  0x02,  0x04,  0x0C,  0x78,  0xF0, 	/* 46DE0 */
+	0x08,  0x90,  0x08,  0x90,  0x08,  0x90,  0x7F,  0x90,  0x08,  0xFF,  0x08,  0x90,  0x3E,  0x88,  0x22,  0x88, 	/* 46DF0 */
+	0x22,  0x88,  0x22,  0x85,  0x3E,  0x85,  0x00,  0xE3,  0x01,  0x81,  0x92,  0x08,  0x00,  0x08,  0xFC,  0x14, 	/* 46E00 */
+	0x04,  0x12,  0x48,  0x21,  0x30,  0x7E,  0x10,  0x09,  0xFF,  0x08,  0x12,  0x7F,  0x14,  0x08,  0x18,  0x08, 	/* 46E10 */
+	0x10,  0x3E,  0x10,  0x22,  0x10,  0x22,  0x10,  0x3E,  0x10,  0x00,  0x30,  0x96,  0x08,  0x14,  0x08,  0x12, 	/* 46E20 */
+	0x15,  0xFF,  0x22,  0x10,  0x7F,  0x10,  0x08,  0xFE,  0x08,  0x92,  0x7F,  0x92,  0x08,  0xFE,  0x08,  0x92, 	/* 46E30 */
+	0x3E,  0x92,  0x22,  0xFE,  0x22,  0x92,  0x22,  0x92,  0x3E,  0x92,  0x00,  0x96,  0x97,  0x08,  0x14,  0x08, 	/* 46E40 */
+	0x12,  0x15,  0xFF,  0x12,  0x10,  0x29,  0x10,  0x48,  0xFE,  0x3E,  0x92,  0x08,  0x92,  0x08,  0xFE,  0x7F, 	/* 46E50 */
+	0x92,  0x00,  0x92,  0x3E,  0xFE,  0x22,  0x92,  0x22,  0x92,  0x3E,  0x92,  0x00,  0x96,  0x98,  0x08,  0x10, 	/* 46E60 */
+	0x08,  0x10,  0x15,  0xFF,  0x13,  0x01,  0x21,  0x01,  0x5E,  0x7C,  0x08,  0x44,  0x08,  0x44,  0x7F,  0x7C, 	/* 46E70 */
+	0x08,  0x40,  0x3E,  0x40,  0x22,  0x7E,  0x22,  0x42,  0x22,  0x42,  0x3E,  0x7E,  0x00,  0x00,  0x9B,  0x08, 	/* 46E80 */
+	0x04,  0x08,  0x04,  0x0F,  0x04,  0x09,  0x04,  0x11,  0x7F,  0x11,  0x44,  0x2A,  0x44,  0x46,  0x44,  0x02, 	/* 46E90 */
+	0x44,  0x04,  0x44,  0x05,  0xFF,  0x08,  0x04,  0x08,  0x04,  0x10,  0x04,  0x20,  0x04,  0x40,  0x04,  0x9C, 	/* 46EA0 */
+	0x00,  0x10,  0x00,  0xE4,  0x7F,  0x04,  0x11,  0x08,  0x08,  0x90,  0x7F,  0xFE,  0x44,  0x02,  0x44,  0x0A, 	/* 46EB0 */
+	0x0F,  0xFE,  0x09,  0x48,  0x11,  0x48,  0x6A,  0x48,  0x07,  0xFF,  0x04,  0x08,  0x18,  0x08,  0x60,  0x08, 	/* 46EC0 */
+	0x9E,  0x08,  0x00,  0x08,  0x00,  0x1F,  0xFE,  0x19,  0x48,  0x29,  0x48,  0x7F,  0xFF,  0x09,  0x48,  0x09, 	/* 46ED0 */
+	0x48,  0x7F,  0xFF,  0x08,  0x08,  0x0F,  0xFE,  0x11,  0x48,  0x6A,  0x48,  0x05,  0xFF,  0x18,  0x08,  0x60, 	/* 46EE0 */
+	0x08,  0x9F,  0x00,  0x40,  0x00,  0x80,  0x07,  0xF8,  0x04,  0x08,  0x05,  0x08,  0x04,  0x88,  0x04,  0x88, 	/* 46EF0 */
+	0x04,  0x08,  0x7F,  0xFF,  0x04,  0x08,  0x05,  0x08,  0x04,  0x88,  0x08,  0x88,  0x08,  0x88,  0x10,  0x08, 	/* 46F00 */
+	0x20,  0x18,  0xA9,  0x04,  0x38,  0x08,  0x08,  0x1E,  0x48,  0x12,  0x48,  0x12,  0x44,  0x1A,  0x84,  0x16, 	/* 46F10 */
+	0xA2,  0x17,  0x21,  0x1A,  0x20,  0x72,  0x20,  0x1A,  0x48,  0x16,  0x48,  0x16,  0x44,  0x22,  0x9C,  0x23, 	/* 46F20 */
+	0xE2,  0x46,  0x02,  0xAA,  0x02,  0x10,  0x04,  0x10,  0x1F,  0x10,  0x11,  0xFF,  0x19,  0x00,  0x15,  0x3C, 	/* 46F30 */
+	0x15,  0x24,  0x13,  0xA4,  0x1D,  0x24,  0x71,  0x24,  0x19,  0x24,  0x15,  0x24,  0x15,  0x24,  0x21,  0x45, 	/* 46F40 */
+	0x21,  0x45,  0x43,  0x83,  0xAB,  0x04,  0x20,  0x08,  0x20,  0x1E,  0x20,  0x13,  0xFF,  0x12,  0x20,  0x1A, 	/* 46F50 */
+	0x20,  0x16,  0x20,  0x17,  0x3C,  0x1A,  0x24,  0x72,  0x24,  0x1A,  0x44,  0x16,  0x44,  0x16,  0x44,  0x22, 	/* 46F60 */
+	0x84,  0x23,  0x04,  0x46,  0x18,  0xAC,  0x04,  0x00,  0x08,  0x78,  0x1F,  0x48,  0x11,  0x48,  0x19,  0x4A, 	/* 46F70 */
+	0x15,  0x4A,  0x15,  0x86,  0x13,  0xFC,  0x1D,  0x44,  0x71,  0x44,  0x19,  0x28,  0x15,  0x28,  0x15,  0x10, 	/* 46F80 */
+	0x21,  0x28,  0x21,  0x44,  0x43,  0x83,  0xAE,  0x04,  0x00,  0x08,  0xFF,  0x1E,  0x00,  0x12,  0x00,  0x12, 	/* 46F90 */
+	0x7E,  0x1A,  0x42,  0x16,  0x42,  0x17,  0x42,  0x1A,  0x7E,  0x72,  0x40,  0x1A,  0x40,  0x16,  0x40,  0x16, 	/* 46FA0 */
+	0x40,  0x22,  0x80,  0x22,  0x80,  0x47,  0x00,  0xB3,  0x04,  0x10,  0x08,  0x10,  0x1E,  0x10,  0x12,  0x10, 	/* 46FB0 */
+	0x12,  0xFE,  0x1A,  0x92,  0x16,  0x92,  0x16,  0x92,  0x1A,  0x92,  0x72,  0xFE,  0x1A,  0x92,  0x16,  0x92, 	/* 46FC0 */
+	0x16,  0x92,  0x22,  0x92,  0x22,  0xFE,  0x46,  0x00,  0xB5,  0x04,  0x10,  0x08,  0x10,  0x1F,  0x10,  0x11, 	/* 46FD0 */
+	0xFF,  0x19,  0xA1,  0x15,  0xA1,  0x15,  0x20,  0x13,  0xA4,  0x1D,  0x24,  0x71,  0x28,  0x19,  0x30,  0x15, 	/* 46FE0 */
+	0x20,  0x15,  0x21,  0x21,  0x21,  0x21,  0x11,  0x43,  0x0F,  0xB6,  0x04,  0x10,  0x08,  0x10,  0x1F,  0x20, 	/* 46FF0 */
+	0x11,  0x7E,  0x19,  0x42,  0x15,  0x42,  0x15,  0x42,  0x13,  0xC2,  0x1D,  0x7E,  0x71,  0x42,  0x19,  0x42, 	/* 47000 */
+	0x15,  0x42,  0x15,  0x42,  0x21,  0x42,  0x21,  0x7E,  0x43,  0x00,  0xB7,  0x04,  0x10,  0x08,  0x10,  0x1F, 	/* 47010 */
+	0x10,  0x11,  0xFF,  0x19,  0x08,  0x15,  0x08,  0x15,  0x10,  0x7F,  0x74,  0x11,  0x14,  0x19,  0x08,  0x15, 	/* 47020 */
+	0x08,  0x15,  0x14,  0x15,  0x12,  0x21,  0x2E,  0x21,  0xF1,  0x43,  0x01,  0xB8,  0x04,  0x00,  0x09,  0xFF, 	/* 47030 */
+	0x1E,  0x04,  0x12,  0x04,  0x12,  0xF4,  0x1A,  0x94,  0x16,  0x94,  0x17,  0x94,  0x1A,  0x94,  0x72,  0x94, 	/* 47040 */
+	0x1A,  0xF4,  0x16,  0x04,  0x16,  0x04,  0x22,  0x04,  0x22,  0x04,  0x46,  0x0C,  0xB9,  0x04,  0x3C,  0x08, 	/* 47050 */
+	0x04,  0x1F,  0x24,  0x11,  0x24,  0x19,  0x24,  0x15,  0x44,  0x15,  0x42,  0x13,  0x82,  0x1D,  0x7D,  0x71, 	/* 47060 */
+	0x44,  0x19,  0x44,  0x15,  0x44,  0x15,  0x44,  0x21,  0x44,  0x21,  0x7C,  0x43,  0x00,  0x80,  0x04,  0x04, 	/* 47070 */
+	0x08,  0x18,  0x1E,  0xE4,  0x12,  0xA2,  0x12,  0x92,  0x1B,  0x11,  0x16,  0xFD,  0x16,  0x04,  0x1A,  0x08, 	/* 47080 */
+	0x72,  0x10,  0x1B,  0xFF,  0x16,  0x10,  0x16,  0x10,  0x22,  0x10,  0x22,  0x10,  0x46,  0x30,  0x87,  0x04, 	/* 47090 */
+	0x02,  0x09,  0xCC,  0x1E,  0x78,  0x12,  0x48,  0x12,  0x88,  0x1A,  0x88,  0x17,  0xFF,  0x16,  0x48,  0x1B, 	/* 470A0 */
+	0x48,  0x73,  0x48,  0x1A,  0xC8,  0x16,  0x48,  0x16,  0xFF,  0x22,  0xA0,  0x23,  0x18,  0x46,  0x07,  0x98, 	/* 470B0 */
+	0x04,  0x10,  0x08,  0x30,  0x1E,  0xD6,  0x12,  0x92,  0x12,  0x92,  0x1A,  0xD6,  0x16,  0x92,  0x16,  0x92, 	/* 470C0 */
+	0x1A,  0xD6,  0x72,  0x10,  0x1B,  0xFC,  0x16,  0x44,  0x16,  0x28,  0x22,  0x30,  0x22,  0xCC,  0x47,  0x03, 	/* 470D0 */
+	0x99,  0x04,  0x10,  0x08,  0x30,  0x1E,  0x28,  0x12,  0x44,  0x12,  0xFE,  0x1B,  0x01,  0x16,  0x7C,  0x17, 	/* 470E0 */
+	0x44,  0x1A,  0x7C,  0x72,  0x44,  0x1A,  0x7C,  0x16,  0x40,  0x16,  0xBE,  0x22,  0xA2,  0x23,  0x3E,  0x46, 	/* 470F0 */
+	0x00,  0x9A,  0x04,  0x28,  0x08,  0x28,  0x1E,  0xFF,  0x12,  0x28,  0x12,  0xFE,  0x1A,  0xAA,  0x16,  0xFE, 	/* 47100 */
+	0x17,  0xAA,  0x1A,  0xFE,  0x72,  0x00,  0x1A,  0x7E,  0x16,  0x42,  0x16,  0x7E,  0x22,  0x42,  0x22,  0x7E, 	/* 47110 */
+	0x46,  0x00,  0x9D,  0x04,  0x00,  0x08,  0xFE,  0x1E,  0x10,  0x13,  0xFF,  0x13,  0x11,  0x1B,  0xDD,  0x17, 	/* 47120 */
+	0x11,  0x16,  0xCC,  0x1A,  0x00,  0x72,  0xFC,  0x1A,  0x04,  0x17,  0xFF,  0x16,  0x04,  0x22,  0x04,  0x22, 	/* 47130 */
+	0xFC,  0x46,  0x00,  0x9F,  0x04,  0x10,  0x08,  0xFE,  0x1E,  0x44,  0x12,  0x28,  0x13,  0xFF,  0x1A,  0x00, 	/* 47140 */
+	0x16,  0xFE,  0x16,  0x92,  0x1A,  0xFE,  0x72,  0x92,  0x1A,  0xFE,  0x16,  0x10,  0x16,  0xFE,  0x22,  0x10, 	/* 47150 */
+	0x23,  0xFF,  0x46,  0x00,  0xA2,  0x04,  0x10,  0x08,  0x10,  0x1F,  0xFF,  0x12,  0x94,  0x12,  0xD6,  0x1B, 	/* 47160 */
+	0x39,  0x16,  0x10,  0x17,  0xFF,  0x1A,  0x00,  0x72,  0xFE,  0x1A,  0xBA,  0x16,  0xAA,  0x16,  0xBA,  0x22, 	/* 47170 */
+	0x82,  0x22,  0xFE,  0x46,  0x00,  0xA4,  0x04,  0x82,  0x08,  0x44,  0x1F,  0xFF,  0x12,  0x10,  0x12,  0xFE, 	/* 47180 */
+	0x1A,  0x10,  0x16,  0xFF,  0x16,  0x24,  0x1A,  0xCA,  0x72,  0x48,  0x1B,  0xFF,  0x16,  0x4A,  0x16,  0x64, 	/* 47190 */
+	0x23,  0xC5,  0x22,  0x4B,  0x46,  0xD1,  0xA6,  0x04,  0x04,  0x08,  0xF4,  0x1E,  0xA4,  0x12,  0xA7,  0x12, 	/* 471A0 */
+	0xF8,  0x1A,  0x90,  0x16,  0xF0,  0x17,  0xAF,  0x1A,  0xF0,  0x72,  0x00,  0x1A,  0xFE,  0x16,  0xAA,  0x16, 	/* 471B0 */
+	0xAA,  0x22,  0xAA,  0x23,  0xFF,  0x46,  0x00,  0xA8,  0x04,  0x48,  0x09,  0xFF,  0x1E,  0x48,  0x12,  0xFE, 	/* 471C0 */
+	0x12,  0x82,  0x1A,  0x7A,  0x16,  0x00,  0x17,  0xFF,  0x1A,  0x42,  0x72,  0xAA,  0x1B,  0x5C,  0x16,  0x94, 	/* 471D0 */
+	0x17,  0x32,  0x22,  0x51,  0x22,  0x90,  0x46,  0x60,  0xAA,  0x04,  0x20,  0x08,  0x78,  0x1E,  0x90,  0x13, 	/* 471E0 */
+	0xFE,  0x12,  0x92,  0x1A,  0xFE,  0x16,  0x92,  0x17,  0xFE,  0x1A,  0xAA,  0x73,  0x15,  0x1A,  0xFE,  0x16, 	/* 471F0 */
+	0x82,  0x16,  0xFE,  0x22,  0x82,  0x22,  0xFE,  0x46,  0x00,  0xAB,  0x04,  0x10,  0x08,  0x1E,  0x1E,  0x10, 	/* 47200 */
+	0x12,  0xFF,  0x12,  0x9A,  0x1A,  0xF1,  0x16,  0xBF,  0x17,  0xAA,  0x1A,  0xBE,  0x72,  0xAA,  0x1A,  0xBE, 	/* 47210 */
+	0x16,  0x80,  0x16,  0xFE,  0x23,  0x6A,  0x22,  0xFF,  0x46,  0x00,  0xAE,  0x00,  0x00,  0x0F,  0xF8,  0x08, 	/* 47220 */
+	0x08,  0x08,  0x08,  0x0F,  0xF8,  0x08,  0x08,  0x08,  0x08,  0x08,  0x08,  0x0F,  0xFA,  0x08,  0x84,  0x08, 	/* 47230 */
+	0x48,  0x08,  0x50,  0x08,  0x20,  0x0B,  0x10,  0x0C,  0x0C,  0x30,  0x03,  0xAF,  0x01,  0x00,  0x01,  0x00, 	/* 47240 */
+	0x0F,  0xF0,  0x08,  0x10,  0x08,  0x10,  0x0F,  0xF0,  0x08,  0x10,  0x08,  0x10,  0x0F,  0xF4,  0x09,  0x04, 	/* 47250 */
+	0x08,  0x88,  0x08,  0x50,  0x08,  0x20,  0x0B,  0x10,  0x0C,  0x0C,  0x70,  0x03,  0xB1,  0x12,  0x00,  0x12, 	/* 47260 */
+	0x7C,  0x7F,  0xC4,  0x12,  0x44,  0x1E,  0x7C,  0x08,  0x44,  0x3F,  0x44,  0x29,  0x7C,  0x3F,  0x52,  0x08, 	/* 47270 */
+	0x52,  0x3F,  0x4C,  0x08,  0x48,  0x7F,  0xC4,  0x14,  0x54,  0x22,  0x62,  0x41,  0x81,  0xB2,  0x02,  0x00, 	/* 47280 */
+	0x03,  0xF0,  0x04,  0x20,  0x08,  0x40,  0x10,  0x80,  0x7F,  0xF8,  0x11,  0x08,  0x11,  0x08,  0x11,  0x08, 	/* 47290 */
+	0x1F,  0xF8,  0x10,  0x00,  0x10,  0x00,  0x10,  0x02,  0x10,  0x02,  0x10,  0x02,  0x0F,  0xFE,  0xB6,  0x0A, 	/* 472A0 */
+	0x10,  0x3F,  0x9E,  0x2A,  0xA4,  0x3F,  0xA4,  0x2A,  0xC8,  0x3F,  0xFE,  0x00,  0x4A,  0x7F,  0xCA,  0x00, 	/* 472B0 */
+	0x4A,  0x3F,  0x7E,  0x21,  0x40,  0x3F,  0x40,  0x12,  0x40,  0x0C,  0x41,  0x7F,  0xA1,  0x00,  0x1F,  0xB7, 	/* 472C0 */
+	0x56,  0x88,  0x56,  0x8E,  0x7F,  0x92,  0x56,  0xA4,  0x7F,  0xFE,  0x56,  0xAA,  0x7F,  0xAA,  0x00,  0x2A, 	/* 472D0 */
+	0x7F,  0xAA,  0x00,  0x3E,  0x3F,  0x20,  0x21,  0x20,  0x3F,  0x20,  0x12,  0x21,  0x7F,  0xA1,  0x00,  0x1F, 	/* 472E0 */
+	0xB8,  0x08,  0x10,  0x08,  0x10,  0x08,  0x10,  0x29,  0x52,  0x29,  0x52,  0x29,  0x52,  0x29,  0x52,  0x29, 	/* 472F0 */
+	0x52,  0x29,  0x52,  0x3F,  0x7E,  0x08,  0x10,  0x08,  0x10,  0x10,  0x10,  0x10,  0x10,  0x20,  0x10,  0x40, 	/* 47300 */
+	0x10,  0xBE,  0x04,  0x10,  0x04,  0x10,  0x7F,  0xFF,  0x04,  0x10,  0x04,  0x10,  0x00,  0x00,  0x04,  0x10, 	/* 47310 */
+	0x04,  0x10,  0x04,  0x10,  0x02,  0x20,  0x02,  0x20,  0x01,  0x40,  0x00,  0x80,  0x03,  0x60,  0x0C,  0x18, 	/* 47320 */
+	0x70,  0x07,  0x8B,  0x02,  0x10,  0x02,  0x10,  0x7F,  0xFF,  0x02,  0x10,  0x02,  0x10,  0x00,  0x00,  0x1F, 	/* 47330 */
+	0xFC,  0x00,  0x80,  0x00,  0x80,  0x7F,  0xFF,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x00, 	/* 47340 */
+	0x80,  0x01,  0x80,  0x8D,  0x04,  0x20,  0x04,  0x20,  0x7F,  0xFF,  0x04,  0x20,  0x0C,  0x20,  0x08,  0x00, 	/* 47350 */
+	0x0F,  0xFC,  0x10,  0x04,  0x10,  0x04,  0x22,  0x04,  0x41,  0x04,  0x00,  0x84,  0x00,  0x84,  0x00,  0x04, 	/* 47360 */
+	0x00,  0x04,  0x00,  0x38,  0x92,  0x04,  0x10,  0x04,  0x10,  0x7F,  0xFF,  0x04,  0x10,  0x04,  0x90,  0x00, 	/* 47370 */
+	0x80,  0x00,  0x80,  0x7F,  0xFF,  0x08,  0x00,  0x08,  0x00,  0x08,  0x00,  0x08,  0x00,  0x08,  0x00,  0x04, 	/* 47380 */
+	0x00,  0x03,  0xFE,  0x00,  0x00,  0x99,  0x04,  0x08,  0x04,  0x08,  0x7F,  0xFF,  0x04,  0x08,  0x04,  0x88, 	/* 47390 */
+	0x00,  0x80,  0x1F,  0xFC,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x7F,  0xFF,  0x01,  0x40,  0x02,  0x20, 	/* 473A0 */
+	0x04,  0x10,  0x18,  0x0C,  0x60,  0x03,  0x9D,  0x04,  0x10,  0x04,  0x10,  0x7F,  0xFF,  0x04,  0x10,  0x04, 	/* 473B0 */
+	0x90,  0x00,  0x80,  0x1F,  0xFC,  0x00,  0x08,  0x00,  0x10,  0x00,  0x20,  0x08,  0x40,  0x09,  0x80,  0x0E, 	/* 473C0 */
+	0x00,  0x09,  0x00,  0x10,  0xE0,  0x20,  0x1F,  0x9F,  0x04,  0x08,  0x04,  0x08,  0x7F,  0xFF,  0x04,  0x08, 	/* 473D0 */
+	0x03,  0xF0,  0x02,  0x10,  0x02,  0x12,  0x04,  0x12,  0x18,  0x0E,  0x07,  0xF0,  0x02,  0x10,  0x01,  0x20, 	/* 473E0 */
+	0x00,  0xC0,  0x01,  0xC0,  0x0E,  0x30,  0x70,  0x0F,  0xA5,  0x04,  0x10,  0x04,  0x10,  0x7F,  0xFF,  0x04, 	/* 473F0 */
+	0x10,  0x04,  0x90,  0x00,  0x80,  0x01,  0x40,  0x02,  0x20,  0x04,  0x10,  0x1A,  0x1C,  0x62,  0x13,  0x02, 	/* 47400 */
+	0x10,  0x02,  0x10,  0x04,  0x10,  0x04,  0x10,  0x08,  0x10,  0xA6,  0x02,  0x10,  0x02,  0x10,  0x7F,  0xFF, 	/* 47410 */
+	0x02,  0x10,  0x00,  0x00,  0x3F,  0xFE,  0x00,  0x00,  0x0F,  0xFC,  0x08,  0x04,  0x08,  0x04,  0x0F,  0xFC, 	/* 47420 */
+	0x08,  0x00,  0x10,  0x00,  0x10,  0x00,  0x20,  0x00,  0x40,  0x00,  0xAB,  0x04,  0x10,  0x04,  0x10,  0x7F, 	/* 47430 */
+	0xFF,  0x04,  0x10,  0x00,  0x00,  0x0F,  0xF8,  0x00,  0x00,  0x00,  0x00,  0x7F,  0xFF,  0x01,  0x20,  0x01, 	/* 47440 */
+	0x20,  0x01,  0x20,  0x02,  0x22,  0x04,  0x22,  0x18,  0x22,  0x60,  0x1E,  0xAC,  0x04,  0x20,  0x04,  0x20, 	/* 47450 */
+	0x7F,  0xFF,  0x04,  0x20,  0x03,  0xF0,  0x00,  0x10,  0x02,  0x10,  0x04,  0x08,  0x18,  0x04,  0x67,  0xF3, 	/* 47460 */
+	0x01,  0x10,  0x01,  0x10,  0x02,  0x10,  0x02,  0x10,  0x04,  0x10,  0x08,  0x60,  0xAD,  0x02,  0x10,  0x02, 	/* 47470 */
+	0x10,  0x7F,  0xFF,  0x02,  0x10,  0x00,  0x00,  0x1F,  0xFC,  0x10,  0x84,  0x10,  0x84,  0x10,  0x84,  0x1F, 	/* 47480 */
+	0xFC,  0x10,  0x00,  0x10,  0x00,  0x10,  0x00,  0x10,  0x02,  0x08,  0x02,  0x07,  0xFE,  0xAF,  0x04,  0x10, 	/* 47490 */
+	0x04,  0x10,  0x7F,  0xFF,  0x04,  0x10,  0x04,  0x10,  0x00,  0x80,  0x00,  0x40,  0x02,  0x20,  0x02,  0x20, 	/* 474A0 */
+	0x12,  0x04,  0x12,  0x02,  0x12,  0x01,  0x22,  0x09,  0x22,  0x08,  0x41,  0x08,  0x00,  0xF8,  0xB1,  0x04, 	/* 474B0 */
+	0x20,  0x04,  0x20,  0x7F,  0xFE,  0x04,  0x20,  0x06,  0x20,  0x02,  0x40,  0x04,  0x44,  0x04,  0x44,  0x08, 	/* 474C0 */
+	0x48,  0x18,  0x50,  0x28,  0x60,  0x48,  0x40,  0x08,  0x40,  0x08,  0x41,  0x08,  0x41,  0x08,  0x3F,  0xB3, 	/* 474D0 */
+	0x04,  0x10,  0x04,  0x10,  0x7F,  0xFF,  0x04,  0x10,  0x04,  0x90,  0x00,  0x80,  0x3F,  0xFE,  0x01,  0x00, 	/* 474E0 */
+	0x01,  0x00,  0x01,  0xF8,  0x01,  0x08,  0x02,  0x08,  0x02,  0x08,  0x04,  0x08,  0x18,  0x08,  0x60,  0x30, 	/* 474F0 */
+	0xB8,  0x02,  0x10,  0x02,  0x10,  0x7F,  0xFF,  0x02,  0x10,  0x02,  0x10,  0x00,  0x00,  0x1F,  0xFC,  0x00, 	/* 47500 */
+	0x00,  0x00,  0x00,  0x7F,  0xFF,  0x01,  0x00,  0x01,  0x20,  0x02,  0x10,  0x04,  0xF8,  0x3F,  0x04,  0x00, 	/* 47510 */
+	0x04,  0xB9,  0x02,  0x10,  0x02,  0x10,  0x7F,  0xFF,  0x02,  0x10,  0x00,  0x20,  0x07,  0xC0,  0x04,  0x00, 	/* 47520 */
+	0x04,  0x00,  0x07,  0xFF,  0x04,  0x20,  0x04,  0x20,  0x08,  0x20,  0x08,  0x20,  0x10,  0x20,  0x20,  0x20, 	/* 47530 */
+	0x00,  0x20,  0xBB,  0x04,  0x00,  0x07,  0xFE,  0x08,  0x82,  0x18,  0x8A,  0x68,  0x8A,  0x0F,  0xFA,  0x02, 	/* 47540 */
+	0x02,  0x0C,  0x06,  0x32,  0x00,  0x03,  0xFE,  0x04,  0x82,  0x1C,  0x8A,  0x64,  0x8A,  0x07,  0xFA,  0x03, 	/* 47550 */
+	0x02,  0x1C,  0x0C,  0xBD,  0x02,  0x20,  0x02,  0x20,  0x7F,  0xFF,  0x02,  0x20,  0x00,  0x00,  0x1F,  0xFC, 	/* 47560 */
+	0x04,  0x20,  0x04,  0x20,  0x04,  0x20,  0x7F,  0xFF,  0x00,  0x60,  0x00,  0xA0,  0x03,  0x20,  0x0C,  0x20, 	/* 47570 */
+	0x70,  0x20,  0x00,  0x60,  0x85,  0x02,  0x10,  0x02,  0x10,  0x7F,  0xFF,  0x02,  0x10,  0x02,  0x12,  0x01, 	/* 47580 */
+	0x02,  0x31,  0x22,  0x09,  0x22,  0x06,  0x22,  0x02,  0x22,  0x05,  0x22,  0x05,  0x22,  0x08,  0x82,  0x10, 	/* 47590 */
+	0x82,  0x20,  0x82,  0x40,  0x06,  0x91,  0x02,  0x10,  0x02,  0x10,  0x7F,  0xFF,  0x02,  0x10,  0x02,  0x10, 	/* 475A0 */
+	0x08,  0x00,  0x0F,  0xBE,  0x08,  0xA2,  0x10,  0xA2,  0x19,  0x22,  0x25,  0x22,  0x42,  0x2C,  0x02,  0x20, 	/* 475B0 */
+	0x04,  0x21,  0x08,  0x11,  0x30,  0x0F,  0x92,  0x04,  0x20,  0x04,  0x20,  0x7F,  0xFF,  0x04,  0x20,  0x05, 	/* 475C0 */
+	0x20,  0x01,  0x00,  0x1F,  0xF8,  0x11,  0x08,  0x11,  0x08,  0x1F,  0xF8,  0x11,  0x08,  0x11,  0x08,  0x7F, 	/* 475D0 */
+	0xFF,  0x10,  0x08,  0x10,  0x08,  0x10,  0x18,  0x93,  0x04,  0x10,  0x04,  0x10,  0x7F,  0xFF,  0x04,  0x90, 	/* 475E0 */
+	0x04,  0x90,  0x01,  0x40,  0x06,  0x20,  0x1B,  0xF8,  0x60,  0x07,  0x00,  0x00,  0x1F,  0xF8,  0x01,  0x08, 	/* 475F0 */
+	0x01,  0x08,  0x01,  0x30,  0x01,  0x00,  0x01,  0x00,  0x94,  0x04,  0x10,  0x04,  0x10,  0x7F,  0xFF,  0x04, 	/* 47600 */
+	0x10,  0x01,  0x00,  0x01,  0x20,  0x02,  0x18,  0x04,  0xF4,  0x7F,  0x02,  0x00,  0x00,  0x0F,  0xF8,  0x08, 	/* 47610 */
+	0x08,  0x08,  0x08,  0x08,  0x08,  0x0F,  0xF8,  0x00,  0x00,  0x97,  0x04,  0x10,  0x04,  0x10,  0x7F,  0xFF, 	/* 47620 */
+	0x04,  0x10,  0x04,  0x10,  0x00,  0x00,  0x1F,  0xFC,  0x10,  0x84,  0x10,  0x84,  0x10,  0x84,  0x1F,  0xFC, 	/* 47630 */
+	0x10,  0x84,  0x10,  0x84,  0x10,  0x84,  0x1F,  0xFC,  0x00,  0x00,  0x99,  0x04,  0x10,  0x04,  0x10,  0x7F, 	/* 47640 */
+	0xFF,  0x04,  0x10,  0x04,  0x10,  0x00,  0x80,  0x00,  0x80,  0x3F,  0xFE,  0x00,  0x08,  0x04,  0x08,  0x02, 	/* 47650 */
+	0x08,  0x02,  0x10,  0x02,  0x10,  0x00,  0x20,  0x7F,  0xFF,  0x00,  0x00,  0x9B,  0x02,  0x10,  0x02,  0x10, 	/* 47660 */
+	0x7F,  0xFF,  0x02,  0x10,  0x02,  0x10,  0x00,  0x00,  0x7F,  0xFE,  0x00,  0x08,  0x0F,  0xC8,  0x08,  0x48, 	/* 47670 */
+	0x08,  0x48,  0x08,  0x48,  0x0F,  0xC8,  0x00,  0x08,  0x00,  0x08,  0x00,  0x18,  0x9C,  0x04,  0x10,  0x04, 	/* 47680 */
+	0x10,  0x7F,  0xFF,  0x04,  0x10,  0x04,  0x10,  0x00,  0x00,  0x0F,  0xF8,  0x08,  0x08,  0x08,  0x08,  0x0F, 	/* 47690 */
+	0xF8,  0x08,  0x08,  0x0F,  0xF8,  0x08,  0x08,  0x08,  0x08,  0x0F,  0xF8,  0x00,  0x00,  0x9E,  0x02,  0x10, 	/* 476A0 */
+	0x02,  0x10,  0x7F,  0xFF,  0x02,  0x10,  0x04,  0x00,  0x07,  0xFC,  0x08,  0x04,  0x0F,  0xE4,  0x18,  0x24, 	/* 476B0 */
+	0x28,  0x24,  0x4F,  0xE4,  0x08,  0x08,  0x08,  0x32,  0x08,  0x02,  0x08,  0x02,  0x07,  0xFE,  0x9F,  0x02, 	/* 476C0 */
+	0x10,  0x02,  0x10,  0x7F,  0xFF,  0x02,  0x10,  0x0A,  0x10,  0x08,  0x00,  0x0F,  0xFE,  0x10,  0x02,  0x17, 	/* 476D0 */
+	0xE2,  0x24,  0x22,  0x44,  0x22,  0x04,  0x22,  0x07,  0xE2,  0x00,  0x02,  0x00,  0x02,  0x00,  0x0C,  0xA1, 	/* 476E0 */
+	0x04,  0x10,  0x04,  0x10,  0x7F,  0xFF,  0x04,  0x10,  0x04,  0x10,  0x00,  0x00,  0x08,  0x08,  0x09,  0x08, 	/* 476F0 */
+	0x08,  0x88,  0x08,  0x48,  0x08,  0x48,  0x08,  0x08,  0x08,  0x0C,  0x0E,  0x14,  0x18,  0x62,  0x61,  0x81, 	/* 47700 */
+	0xA3,  0x02,  0x10,  0x02,  0x10,  0x7F,  0xFF,  0x02,  0x10,  0x00,  0x00,  0x1F,  0xFE,  0x10,  0x00,  0x10, 	/* 47710 */
+	0x00,  0x1F,  0xFC,  0x10,  0x04,  0x10,  0x04,  0x1F,  0xFC,  0x10,  0x00,  0x10,  0x00,  0x1F,  0xFF,  0x00, 	/* 47720 */
+	0x00,  0xA5,  0x08,  0x10,  0x08,  0x10,  0x7F,  0xFE,  0x08,  0x10,  0x09,  0x10,  0x01,  0x00,  0x01,  0x00, 	/* 47730 */
+	0x7F,  0xFE,  0x02,  0x00,  0x04,  0x00,  0x07,  0xF8,  0x0C,  0x08,  0x14,  0x08,  0x24,  0x08,  0x47,  0xF8, 	/* 47740 */
+	0x00,  0x00,  0xA6,  0x04,  0x10,  0x04,  0x10,  0x7F,  0xFF,  0x04,  0x10,  0x04,  0x90,  0x00,  0x80,  0x7F, 	/* 47750 */
+	0xFF,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x0F,  0xF8,  0x08,  0x08,  0x08,  0x08,  0x08,  0x08,  0x0F, 	/* 47760 */
+	0xF8,  0x00,  0x00,  0xA7,  0x08,  0x10,  0x08,  0x10,  0x7F,  0xFF,  0x08,  0x90,  0x00,  0x80,  0x3F,  0xFE, 	/* 47770 */
+	0x20,  0x02,  0x20,  0x02,  0x00,  0x00,  0x7F,  0xFF,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80, 	/* 47780 */
+	0x00,  0x80,  0x01,  0x80,  0xAB,  0x04,  0x10,  0x04,  0x10,  0x7F,  0xFF,  0x04,  0x10,  0x04,  0x90,  0x00, 	/* 47790 */
+	0x80,  0x00,  0x80,  0x00,  0xFE,  0x00,  0x80,  0x00,  0x80,  0x1F,  0xF8,  0x10,  0x08,  0x10,  0x08,  0x10, 	/* 477A0 */
+	0x08,  0x1F,  0xF8,  0x00,  0x00,  0xB1,  0x04,  0x10,  0x04,  0x10,  0x7F,  0xFF,  0x04,  0x10,  0x04,  0x90, 	/* 477B0 */
+	0x00,  0x80,  0x1F,  0xFC,  0x10,  0x84,  0x10,  0x84,  0x10,  0x84,  0x7F,  0xFF,  0x01,  0x40,  0x02,  0x20, 	/* 477C0 */
+	0x04,  0x10,  0x18,  0x0C,  0x60,  0x03,  0xB3,  0x02,  0x10,  0x02,  0x10,  0x7F,  0xFF,  0x02,  0x10,  0x01, 	/* 477D0 */
+	0x00,  0x01,  0xF8,  0x06,  0x10,  0x39,  0x20,  0x00,  0xC0,  0x03,  0x20,  0x0D,  0x98,  0x70,  0x47,  0x00, 	/* 477E0 */
+	0x00,  0x00,  0x30,  0x01,  0xC0,  0x0E,  0x00,  0xB4,  0x04,  0x10,  0x04,  0x10,  0x7F,  0xFF,  0x04,  0x10, 	/* 477F0 */
+	0x00,  0x00,  0x0F,  0xF8,  0x08,  0x08,  0x08,  0x08,  0x0F,  0xF8,  0x08,  0x08,  0x08,  0x08,  0x0F,  0xF8, 	/* 47800 */
+	0x08,  0x08,  0x08,  0x08,  0x7F,  0xFF,  0x00,  0x00,  0xB9,  0x02,  0x10,  0x02,  0x10,  0x7F,  0xFF,  0x02, 	/* 47810 */
+	0x10,  0x00,  0x00,  0x3F,  0xFE,  0x00,  0x90,  0x04,  0x90,  0x04,  0x88,  0x08,  0x88,  0x00,  0x80,  0x7F, 	/* 47820 */
+	0xFF,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0xBA,  0x04,  0x20,  0x04,  0x20,  0x7F,  0xFF, 	/* 47830 */
+	0x04,  0x20,  0x00,  0x00,  0x0F,  0xF8,  0x09,  0x08,  0x08,  0x88,  0x08,  0x88,  0x7F,  0xFF,  0x11,  0x08, 	/* 47840 */
+	0x10,  0x88,  0x10,  0x88,  0x1F,  0xFE,  0x00,  0x10,  0x00,  0xE0,  0xBB,  0x02,  0x10,  0x02,  0x10,  0x7F, 	/* 47850 */
+	0xFF,  0x02,  0x10,  0x02,  0x10,  0x04,  0x08,  0x04,  0x08,  0x09,  0xFF,  0x08,  0x08,  0x19,  0x08,  0x28, 	/* 47860 */
+	0x88,  0x48,  0x88,  0x08,  0x08,  0x08,  0x08,  0x08,  0x08,  0x08,  0x18,  0x82,  0x04,  0x20,  0x04,  0x20, 	/* 47870 */
+	0x7F,  0xFF,  0x04,  0x20,  0x04,  0xA8,  0x00,  0x84,  0x1F,  0xFE,  0x10,  0x80,  0x10,  0x84,  0x10,  0x48, 	/* 47880 */
+	0x10,  0x50,  0x10,  0x20,  0x10,  0x62,  0x21,  0x92,  0x2E,  0x0A,  0x40,  0x06,  0x83,  0x04,  0x20,  0x04, 	/* 47890 */
+	0x20,  0x7F,  0xFF,  0x04,  0x20,  0x04,  0x20,  0x10,  0x00,  0x08,  0xFE,  0x08,  0x82,  0x40,  0x82,  0x20, 	/* 478A0 */
+	0x82,  0x20,  0x82,  0x04,  0x8C,  0x08,  0x80,  0x10,  0x81,  0x20,  0x81,  0x40,  0x7F,  0x84,  0x04,  0x20, 	/* 478B0 */
+	0x04,  0x20,  0x7F,  0xFE,  0x04,  0x20,  0x04,  0x20,  0x08,  0x00,  0x08,  0x7C,  0x7F,  0x44,  0x09,  0x44, 	/* 478C0 */
+	0x09,  0x44,  0x09,  0x44,  0x09,  0x44,  0x11,  0x44,  0x11,  0x7C,  0x21,  0x00,  0x46,  0x00,  0x85,  0x02, 	/* 478D0 */
+	0x10,  0x02,  0x10,  0x7F,  0xFF,  0x02,  0x10,  0x0F,  0xF8,  0x00,  0x10,  0x03,  0x20,  0x00,  0xC0,  0x7F, 	/* 478E0 */
+	0xFE,  0x00,  0xC4,  0x01,  0x48,  0x02,  0x40,  0x04,  0x40,  0x18,  0x40,  0x60,  0x40,  0x00,  0xC0,  0x86, 	/* 478F0 */
+	0x04,  0x20,  0x04,  0x20,  0x7F,  0xFF,  0x04,  0x20,  0x01,  0x00,  0x02,  0x3E,  0x1C,  0x22,  0x11,  0x22, 	/* 47900 */
+	0x11,  0x22,  0x11,  0x22,  0x11,  0x22,  0x1F,  0x22,  0x61,  0x2C,  0x02,  0x20,  0x0C,  0x20,  0x30,  0x20, 	/* 47910 */
+	0x89,  0x04,  0x10,  0x04,  0x10,  0x7F,  0xFF,  0x04,  0x10,  0x04,  0x90,  0x00,  0x80,  0x3F,  0xFE,  0x00, 	/* 47920 */
+	0x80,  0x00,  0x80,  0x1F,  0xFC,  0x01,  0xC0,  0x02,  0xA0,  0x04,  0x90,  0x18,  0x8C,  0x60,  0x83,  0x00, 	/* 47930 */
+	0x80,  0x8E,  0x02,  0x10,  0x02,  0x10,  0x7F,  0xFF,  0x02,  0x10,  0x00,  0x00,  0x1F,  0xF8,  0x04,  0x10, 	/* 47940 */
+	0x03,  0x20,  0x00,  0xC0,  0x07,  0xB8,  0x78,  0x87,  0x0F,  0xF8,  0x00,  0x80,  0x00,  0x80,  0x7F,  0xFE, 	/* 47950 */
+	0x00,  0x00,  0x96,  0x04,  0x10,  0x04,  0x10,  0x7F,  0xFF,  0x04,  0x10,  0x01,  0x00,  0x03,  0xF0,  0x0C, 	/* 47960 */
+	0x10,  0x33,  0x20,  0x00,  0xC0,  0x03,  0x20,  0x0C,  0x18,  0x7F,  0xFF,  0x08,  0x08,  0x08,  0x08,  0x0F, 	/* 47970 */
+	0xF8,  0x00,  0x00,  0x97,  0x04,  0x10,  0x04,  0x10,  0x7F,  0xFF,  0x04,  0x10,  0x01,  0x00,  0x03,  0xF0, 	/* 47980 */
+	0x04,  0x10,  0x0E,  0x20,  0x31,  0x40,  0x00,  0x80,  0x03,  0xFC,  0x0E,  0x04,  0x72,  0x04,  0x02,  0x04, 	/* 47990 */
+	0x03,  0xFC,  0x00,  0x00,  0x98,  0x04,  0x20,  0x04,  0x20,  0x7F,  0xFF,  0x04,  0x20,  0x0F,  0xF8,  0x00, 	/* 479A0 */
+	0x88,  0x01,  0x08,  0x02,  0x08,  0x0C,  0x30,  0x00,  0x00,  0x7F,  0x7E,  0x09,  0x12,  0x09,  0x12,  0x11, 	/* 479B0 */
+	0x22,  0x21,  0x42,  0x46,  0x8C,  0x9C,  0x04,  0x20,  0x04,  0x20,  0x7F,  0xFE,  0x04,  0x20,  0x00,  0x00, 	/* 479C0 */
+	0x7F,  0xFE,  0x02,  0x40,  0x02,  0x40,  0x3F,  0xFC,  0x22,  0x44,  0x22,  0x44,  0x24,  0x3C,  0x28,  0x04, 	/* 479D0 */
+	0x30,  0x04,  0x3F,  0xFC,  0x00,  0x00,  0xA3,  0x02,  0x10,  0x02,  0x10,  0x7F,  0xFF,  0x02,  0x10,  0x00, 	/* 479E0 */
+	0x00,  0x13,  0xF8,  0x12,  0x08,  0x12,  0x08,  0x13,  0xF8,  0x10,  0x00,  0x1F,  0xF8,  0x01,  0x08,  0x7F, 	/* 479F0 */
+	0xFF,  0x02,  0x40,  0x0C,  0x30,  0x70,  0x0E,  0xA8,  0x02,  0x10,  0x02,  0x10,  0x7F,  0xFF,  0x02,  0x10, 	/* 47A00 */
+	0x02,  0x90,  0x10,  0x80,  0x08,  0xFE,  0x08,  0xA2,  0x01,  0x24,  0x01,  0x20,  0x0A,  0x30,  0x08,  0x28, 	/* 47A10 */
+	0x10,  0x48,  0x20,  0x84,  0x43,  0x02,  0x0C,  0x01,  0xAB,  0x02,  0x20,  0x02,  0x20,  0x7F,  0xFF,  0x02, 	/* 47A20 */
+	0x20,  0x10,  0x10,  0x08,  0x10,  0x08,  0xFF,  0x40,  0x80,  0x20,  0x80,  0x20,  0x80,  0x04,  0x80,  0x04, 	/* 47A30 */
+	0x80,  0x08,  0x80,  0x10,  0x40,  0x20,  0x3E,  0x40,  0x00,  0xAF,  0x02,  0x10,  0x02,  0x10,  0x7F,  0xFF, 	/* 47A40 */
+	0x02,  0x10,  0x0A,  0x08,  0x08,  0x24,  0x08,  0x24,  0x10,  0x20,  0x17,  0xFF,  0x30,  0x50,  0x50,  0x50, 	/* 47A50 */
+	0x10,  0x88,  0x10,  0x88,  0x11,  0x04,  0x12,  0x02,  0x14,  0x01,  0xB1,  0x02,  0x10,  0x02,  0x10,  0x7F, 	/* 47A60 */
+	0xFF,  0x02,  0x10,  0x04,  0x80,  0x04,  0x80,  0x07,  0xFC,  0x08,  0x80,  0x10,  0x80,  0x7F,  0xFF,  0x02, 	/* 47A70 */
+	0xA0,  0x04,  0x90,  0x18,  0x8C,  0x60,  0x83,  0x00,  0x80,  0x00,  0x80,  0xB2,  0x02,  0x10,  0x02,  0x10, 	/* 47A80 */
+	0x7F,  0xFF,  0x02,  0x10,  0x02,  0x10,  0x04,  0x08,  0x04,  0x08,  0x05,  0x0A,  0x39,  0x72,  0x0A,  0x14, 	/* 47A90 */
+	0x04,  0x08,  0x06,  0x0C,  0x0A,  0x14,  0x11,  0x22,  0x7F,  0xFE,  0x01,  0x02,  0xB4,  0x04,  0x10,  0x04, 	/* 47AA0 */
+	0x10,  0x7F,  0xFF,  0x04,  0x10,  0x00,  0x00,  0x3F,  0xFE,  0x20,  0x02,  0x20,  0x02,  0x27,  0xF2,  0x24, 	/* 47AB0 */
+	0x12,  0x24,  0x12,  0x27,  0xF2,  0x20,  0x02,  0x20,  0x02,  0x3F,  0xFE,  0x00,  0x00,  0xB5,  0x04,  0x10, 	/* 47AC0 */
+	0x04,  0x10,  0x7F,  0xFF,  0x04,  0x10,  0x00,  0x00,  0x3F,  0xFE,  0x20,  0x82,  0x20,  0x82,  0x2F,  0xFA, 	/* 47AD0 */
+	0x20,  0x82,  0x21,  0x42,  0x26,  0x32,  0x38,  0x0E,  0x20,  0x02,  0x3F,  0xFE,  0x00,  0x00,  0xB6,  0x04, 	/* 47AE0 */
+	0x10,  0x04,  0x10,  0x7F,  0xFF,  0x04,  0x90,  0x04,  0x90,  0x01,  0x40,  0x02,  0x20,  0x04,  0x10,  0x18, 	/* 47AF0 */
+	0x8C,  0x6F,  0xFB,  0x00,  0x80,  0x02,  0xA0,  0x04,  0x98,  0x08,  0x84,  0x30,  0x82,  0x00,  0x80,  0xB8, 	/* 47B00 */
+	0x04,  0x10,  0x04,  0x10,  0x7F,  0xFF,  0x04,  0x10,  0x00,  0x00,  0x7F,  0xFF,  0x04,  0x10,  0x04,  0x10, 	/* 47B10 */
+	0x07,  0xF0,  0x04,  0x10,  0x07,  0xF0,  0x04,  0x10,  0x04,  0x1E,  0x07,  0xF0,  0x7C,  0x10,  0x00,  0x10, 	/* 47B20 */
+	0xB9,  0x04,  0x20,  0x04,  0x20,  0x7F,  0xFF,  0x04,  0x20,  0x04,  0x20,  0x04,  0x00,  0x04,  0x3E,  0x7F, 	/* 47B30 */
+	0xA2,  0x09,  0x22,  0x09,  0x22,  0x11,  0x22,  0x3E,  0x22,  0x23,  0x22,  0x04,  0xBE,  0x18,  0x80,  0x60, 	/* 47B40 */
+	0x00,  0x80,  0x02,  0x10,  0x02,  0x10,  0x7F,  0xFF,  0x02,  0x10,  0x08,  0x00,  0x0F,  0xFC,  0x08,  0x04, 	/* 47B50 */
+	0x10,  0x04,  0x17,  0xE4,  0x24,  0x24,  0x47,  0xE4,  0x04,  0x24,  0x04,  0x24,  0x07,  0xE4,  0x00,  0x04, 	/* 47B60 */
+	0x00,  0x38,  0x85,  0x04,  0x10,  0x04,  0x10,  0x7F,  0xFF,  0x04,  0x10,  0x04,  0x90,  0x00,  0x80,  0x01, 	/* 47B70 */
+	0x40,  0x06,  0x30,  0x1B,  0xEC,  0x60,  0x03,  0x00,  0x00,  0x0F,  0xF8,  0x08,  0x08,  0x08,  0x08,  0x0F, 	/* 47B80 */
+	0xF8,  0x00,  0x00,  0x89,  0x02,  0x10,  0x02,  0x10,  0x7F,  0xFF,  0x02,  0x10,  0x00,  0x00,  0x0F,  0xF8, 	/* 47B90 */
+	0x08,  0x08,  0x0F,  0xF8,  0x08,  0x08,  0x0F,  0xF8,  0x00,  0x80,  0x00,  0x80,  0x7F,  0xFF,  0x00,  0x80, 	/* 47BA0 */
+	0x00,  0x80,  0x00,  0x80,  0x8A,  0x02,  0x10,  0x02,  0x10,  0x7F,  0xFF,  0x02,  0x10,  0x00,  0x02,  0x3F, 	/* 47BB0 */
+	0xD2,  0x09,  0x12,  0x09,  0x12,  0x09,  0x12,  0x7F,  0xF2,  0x09,  0x12,  0x09,  0x12,  0x09,  0x12,  0x09, 	/* 47BC0 */
+	0x02,  0x11,  0x02,  0x21,  0x06,  0x8F,  0x02,  0x20,  0x02,  0x20,  0x7F,  0xFF,  0x02,  0x20,  0x02,  0x20, 	/* 47BD0 */
+	0x04,  0x04,  0x04,  0x18,  0x09,  0xF0,  0x08,  0x10,  0x18,  0x10,  0x2B,  0xFF,  0x48,  0x10,  0x08,  0x10, 	/* 47BE0 */
+	0x08,  0x10,  0x09,  0xFE,  0x08,  0x00,  0x90,  0x04,  0x10,  0x04,  0x10,  0x7F,  0xFF,  0x05,  0x10,  0x01, 	/* 47BF0 */
+	0x00,  0x7F,  0xFF,  0x02,  0x00,  0x04,  0x00,  0x07,  0xF8,  0x08,  0x10,  0x18,  0x20,  0x2F,  0xFF,  0x48, 	/* 47C00 */
+	0x20,  0x08,  0x20,  0x08,  0x20,  0x08,  0x60,  0x92,  0x04,  0x20,  0x04,  0x20,  0x7F,  0xFE,  0x04,  0x20, 	/* 47C10 */
+	0x01,  0x00,  0x7F,  0xFE,  0x08,  0x00,  0x08,  0x00,  0x07,  0xF0,  0x00,  0x00,  0x09,  0x10,  0x09,  0x10, 	/* 47C20 */
+	0x09,  0x12,  0x11,  0x12,  0x21,  0x12,  0x40,  0x0E,  0x98,  0x02,  0x10,  0x02,  0x10,  0x7F,  0xFF,  0x02, 	/* 47C30 */
+	0x10,  0x00,  0x00,  0x04,  0x10,  0x24,  0x10,  0x14,  0x10,  0x17,  0xFF,  0x04,  0x10,  0x0C,  0x10,  0x34, 	/* 47C40 */
+	0x10,  0x44,  0x10,  0x04,  0x10,  0x05,  0xFE,  0x04,  0x00,  0xB3,  0x04,  0x10,  0x04,  0x10,  0x7F,  0xFF, 	/* 47C50 */
+	0x04,  0x10,  0x00,  0x00,  0x3F,  0xFE,  0x00,  0x00,  0x0F,  0xF8,  0x08,  0x08,  0x08,  0x08,  0x0F,  0xF8, 	/* 47C60 */
+	0x04,  0x10,  0x02,  0x10,  0x02,  0x20,  0x7F,  0xFF,  0x00,  0x00,  0xB5,  0x02,  0x10,  0x02,  0x10,  0x7F, 	/* 47C70 */
+	0xFF,  0x02,  0x10,  0x00,  0x00,  0x3F,  0xFC,  0x00,  0x84,  0x0F,  0x04,  0x03,  0x84,  0x0C,  0x58,  0x30, 	/* 47C80 */
+	0x80,  0x12,  0x44,  0x12,  0x42,  0x22,  0x09,  0x41,  0x09,  0x00,  0xF8,  0xB7,  0x02,  0x10,  0x02,  0x10, 	/* 47C90 */
+	0x7F,  0xFF,  0x02,  0x10,  0x02,  0x10,  0x04,  0x00,  0x07,  0xFF,  0x08,  0x04,  0x09,  0xE4,  0x19,  0x24, 	/* 47CA0 */
+	0x29,  0x24,  0x49,  0x24,  0x09,  0xE4,  0x08,  0x04,  0x08,  0x04,  0x08,  0x0C,  0xBB,  0x02,  0x10,  0x02, 	/* 47CB0 */
+	0x10,  0x7F,  0xFF,  0x02,  0x10,  0x04,  0x00,  0x24,  0x10,  0x18,  0x12,  0x08,  0x92,  0x14,  0x94,  0x24, 	/* 47CC0 */
+	0x90,  0x0D,  0x10,  0x14,  0x28,  0x24,  0x28,  0x04,  0x44,  0x05,  0x82,  0x1E,  0x01,  0xBC,  0x04,  0x10, 	/* 47CD0 */
+	0x04,  0x10,  0x7F,  0xFF,  0x04,  0x90,  0x04,  0x90,  0x01,  0x40,  0x06,  0x30,  0x18,  0x0C,  0x67,  0xF3, 	/* 47CE0 */
+	0x00,  0x80,  0x00,  0x80,  0x7F,  0xFF,  0x04,  0xB0,  0x18,  0x8C,  0x60,  0x82,  0x01,  0x80,  0x85,  0x02, 	/* 47CF0 */
+	0x10,  0x02,  0x10,  0x7F,  0xFF,  0x02,  0x10,  0x04,  0x00,  0x04,  0x20,  0x04,  0x20,  0x0B,  0xFF,  0x08, 	/* 47D00 */
+	0x04,  0x19,  0x04,  0x28,  0x84,  0x48,  0x88,  0x08,  0x88,  0x08,  0x10,  0x0F,  0xFF,  0x08,  0x00,  0x87, 	/* 47D10 */
+	0x04,  0x20,  0x04,  0x20,  0x7F,  0xFF,  0x04,  0x20,  0x00,  0x10,  0x1F,  0x10,  0x11,  0xFE,  0x11,  0x12, 	/* 47D20 */
+	0x1F,  0x12,  0x11,  0x12,  0x1F,  0x12,  0x11,  0x22,  0x11,  0xA2,  0x1E,  0x42,  0x60,  0x8C,  0x01,  0x00, 	/* 47D30 */
+	0x89,  0x02,  0x10,  0x02,  0x10,  0x7F,  0xFF,  0x02,  0x10,  0x00,  0x82,  0x03,  0x22,  0x3C,  0x22,  0x04, 	/* 47D40 */
+	0x22,  0x04,  0x22,  0x7F,  0xE2,  0x0E,  0x22,  0x0D,  0x22,  0x14,  0xA2,  0x24,  0x02,  0x44,  0x02,  0x04, 	/* 47D50 */
+	0x06,  0x8A,  0x02,  0x10,  0x02,  0x10,  0x7F,  0xFF,  0x02,  0x10,  0x02,  0x00,  0x22,  0x10,  0x22,  0x10, 	/* 47D60 */
+	0x3E,  0x10,  0x03,  0xFF,  0x02,  0x10,  0x7E,  0x10,  0x12,  0x10,  0x12,  0x10,  0x12,  0x10,  0x22,  0xFE, 	/* 47D70 */
+	0x42,  0x00,  0x8E,  0x02,  0x20,  0x02,  0x20,  0x7F,  0xFF,  0x02,  0x20,  0x10,  0x00,  0x08,  0x20,  0x08, 	/* 47D80 */
+	0x24,  0x41,  0x22,  0x21,  0x22,  0x21,  0x21,  0x0A,  0x25,  0x0C,  0x64,  0x10,  0x08,  0x10,  0x10,  0x20, 	/* 47D90 */
+	0x60,  0x43,  0x80,  0x93,  0x02,  0x20,  0x02,  0x20,  0x7F,  0xFF,  0x0A,  0x20,  0x08,  0x00,  0x0F,  0xFF, 	/* 47DA0 */
+	0x10,  0x00,  0x17,  0xFC,  0x24,  0x84,  0x04,  0x44,  0x7F,  0xFF,  0x08,  0x84,  0x08,  0x44,  0x0F,  0xFF, 	/* 47DB0 */
+	0x00,  0x08,  0x00,  0x30,  0x96,  0x02,  0x10,  0x02,  0x10,  0x7F,  0xFF,  0x02,  0x10,  0x00,  0x00,  0x1F, 	/* 47DC0 */
+	0xFC,  0x04,  0x44,  0x08,  0x88,  0x11,  0x10,  0x08,  0x88,  0x04,  0x44,  0x1F,  0xFC,  0x00,  0x80,  0x00, 	/* 47DD0 */
+	0x80,  0x7F,  0xFF,  0x00,  0x00,  0x9A,  0x04,  0x10,  0x04,  0x10,  0x7F,  0xFF,  0x04,  0x10,  0x00,  0x0C, 	/* 47DE0 */
+	0x7D,  0xF0,  0x08,  0x20,  0x11,  0x20,  0x3D,  0x3C,  0x05,  0x20,  0x25,  0x20,  0x19,  0x20,  0x09,  0xFE, 	/* 47DF0 */
+	0x14,  0x00,  0x23,  0x00,  0x40,  0xFF,  0x9E,  0x04,  0x10,  0x04,  0x10,  0x7F,  0xFF,  0x04,  0x10,  0x00, 	/* 47E00 */
+	0x80,  0x7F,  0xFE,  0x40,  0x02,  0x4F,  0xF2,  0x00,  0x00,  0x00,  0x00,  0x7F,  0xFE,  0x02,  0x40,  0x02, 	/* 47E10 */
+	0x40,  0x04,  0x42,  0x18,  0x42,  0x60,  0x3E,  0x9F,  0x04,  0x10,  0x04,  0x10,  0x7F,  0xFF,  0x04,  0x90, 	/* 47E20 */
+	0x01,  0x40,  0x02,  0x30,  0x0D,  0xEC,  0x70,  0x03,  0x1F,  0xF8,  0x00,  0x20,  0x00,  0x40,  0x0F,  0xFC, 	/* 47E30 */
+	0x08,  0x04,  0x08,  0x04,  0x0F,  0xFC,  0x00,  0x00,  0xA0,  0x02,  0x10,  0x02,  0x10,  0x7F,  0xFF,  0x02, 	/* 47E40 */
+	0x10,  0x00,  0x30,  0x0F,  0xC0,  0x00,  0x80,  0x7F,  0xFF,  0x02,  0xA0,  0x0C,  0x98,  0x77,  0xF7,  0x00, 	/* 47E50 */
+	0x90,  0x00,  0x9C,  0x01,  0x04,  0x06,  0x04,  0x18,  0x18,  0xA2,  0x04,  0x08,  0x04,  0x08,  0x7F,  0xFF, 	/* 47E60 */
+	0x04,  0x88,  0x00,  0x80,  0x00,  0x80,  0x3F,  0xFE,  0x08,  0x88,  0x08,  0x88,  0x08,  0x94,  0x15,  0x54, 	/* 47E70 */
+	0x13,  0x62,  0x22,  0x20,  0x04,  0x10,  0x18,  0x0C,  0x60,  0x03,  0xA8,  0x02,  0x10,  0x02,  0x10,  0x7F, 	/* 47E80 */
+	0xFF,  0x02,  0x10,  0x00,  0x80,  0x0F,  0xF8,  0x08,  0x08,  0x0F,  0xF8,  0x08,  0x08,  0x08,  0x08,  0x0F, 	/* 47E90 */
+	0xFA,  0x08,  0x44,  0x08,  0x28,  0x09,  0x90,  0x0E,  0x0C,  0x30,  0x03,  0xAA,  0x02,  0x10,  0x02,  0x10, 	/* 47EA0 */
+	0x7F,  0xFF,  0x02,  0x10,  0x01,  0x20,  0x06,  0x24,  0x3C,  0x22,  0x04,  0x20,  0x7F,  0xFF,  0x04,  0x10, 	/* 47EB0 */
+	0x05,  0x14,  0x0E,  0x08,  0x74,  0x19,  0x04,  0x65,  0x05,  0x83,  0x0C,  0x01,  0xAB,  0x02,  0x20,  0x02, 	/* 47EC0 */
+	0x20,  0x7F,  0xFF,  0x02,  0x20,  0x02,  0x20,  0x0F,  0xF8,  0x08,  0x08,  0x0F,  0xF8,  0x08,  0x08,  0x0F, 	/* 47ED0 */
+	0xF8,  0x00,  0x80,  0x7F,  0xFF,  0x01,  0x40,  0x02,  0x20,  0x0C,  0x18,  0x70,  0x07,  0xB1,  0x02,  0x10, 	/* 47EE0 */
+	0x02,  0x10,  0x7F,  0xFF,  0x02,  0x10,  0x00,  0x80,  0x3F,  0xFE,  0x08,  0x88,  0x04,  0x90,  0x04,  0x80, 	/* 47EF0 */
+	0x7F,  0xFF,  0x01,  0xC0,  0x02,  0xA0,  0x04,  0x90,  0x18,  0x8C,  0x60,  0x83,  0x00,  0x80,  0xB5,  0x04, 	/* 47F00 */
+	0x10,  0x04,  0x10,  0x7F,  0xFF,  0x04,  0x10,  0x00,  0x80,  0x01,  0x00,  0x1F,  0xFC,  0x10,  0x84,  0x10, 	/* 47F10 */
+	0x84,  0x1F,  0xFC,  0x01,  0x40,  0x02,  0x50,  0x02,  0x49,  0x04,  0x49,  0x18,  0x41,  0x60,  0x3F,  0xBD, 	/* 47F20 */
+	0x04,  0x10,  0x04,  0x10,  0x7F,  0xFF,  0x04,  0x10,  0x01,  0x00,  0x3F,  0xFE,  0x01,  0x40,  0x02,  0x20, 	/* 47F30 */
+	0x0C,  0x18,  0x74,  0x17,  0x04,  0x10,  0x3F,  0xFE,  0x04,  0x10,  0x08,  0x10,  0x10,  0x10,  0x20,  0x10, 	/* 47F40 */
+	0x81,  0x04,  0x10,  0x7F,  0xFF,  0x04,  0x10,  0x00,  0x80,  0x3F,  0xFE,  0x00,  0x80,  0x1F,  0xFC,  0x00, 	/* 47F50 */
+	0x80,  0x7F,  0xFF,  0x00,  0x00,  0x0F,  0xF8,  0x08,  0x88,  0x08,  0x88,  0x0F,  0xF8,  0x08,  0x08,  0x08, 	/* 47F60 */
+	0x18,  0x85,  0x02,  0x10,  0x02,  0x10,  0x7F,  0xFF,  0x02,  0x10,  0x00,  0x80,  0x3F,  0xFE,  0x20,  0x02, 	/* 47F70 */
+	0x27,  0xF2,  0x04,  0x10,  0x07,  0xF0,  0x04,  0x00,  0x07,  0xF8,  0x04,  0x08,  0x04,  0x08,  0x07,  0xF8, 	/* 47F80 */
+	0x00,  0x00,  0x8A,  0x04,  0x20,  0x04,  0x20,  0x7F,  0xFF,  0x04,  0x20,  0x08,  0x00,  0x0F,  0xFE,  0x19, 	/* 47F90 */
+	0x02,  0x15,  0x22,  0x25,  0x42,  0x7F,  0xFA,  0x03,  0x82,  0x05,  0x42,  0x09,  0x22,  0x31,  0x12,  0x01, 	/* 47FA0 */
+	0x04,  0x00,  0x18,  0x8C,  0x04,  0x20,  0x04,  0x20,  0x7F,  0xFF,  0x04,  0x20,  0x3F,  0xFE,  0x20,  0x12, 	/* 47FB0 */
+	0x20,  0xE2,  0x27,  0x82,  0x20,  0x82,  0x3F,  0xFE,  0x22,  0xA2,  0x24,  0x92,  0x28,  0x8A,  0x20,  0x82, 	/* 47FC0 */
+	0x3F,  0xFE,  0x20,  0x02,  0x8E,  0x02,  0x10,  0x02,  0x10,  0x7F,  0xFF,  0x02,  0x10,  0x00,  0x00,  0x0F, 	/* 47FD0 */
+	0xF8,  0x08,  0x08,  0x0F,  0xF8,  0x08,  0x08,  0x0F,  0xF8,  0x08,  0x20,  0x08,  0x22,  0x0F,  0xBC,  0x08, 	/* 47FE0 */
+	0x21,  0x0F,  0xA1,  0x70,  0x1F,  0x93,  0x02,  0x20,  0x02,  0x20,  0x7F,  0xFF,  0x02,  0x20,  0x0F,  0xF8, 	/* 47FF0 */
+	0x08,  0x88,  0x0F,  0xF8,  0x08,  0x88,  0x0F,  0xF8,  0x00,  0x80,  0x7F,  0xFF,  0x02,  0xA0,  0x04,  0x90, 	/* 48000 */
+	0x18,  0x8C,  0x60,  0x83,  0x00,  0x80,  0x96,  0x04,  0x20,  0x04,  0x20,  0x7F,  0xFE,  0x04,  0x20,  0x0F, 	/* 48010 */
+	0xF0,  0x08,  0x10,  0x0F,  0xF0,  0x08,  0x10,  0x0F,  0xF0,  0x00,  0x00,  0x3F,  0xFC,  0x20,  0x04,  0x3F, 	/* 48020 */
+	0xFC,  0x20,  0x04,  0x3F,  0xFC,  0x00,  0x00,  0x98,  0x04,  0x20,  0x04,  0x20,  0x7F,  0xFF,  0x04,  0x20, 	/* 48030 */
+	0x08,  0x78,  0x08,  0x08,  0x08,  0x48,  0x7E,  0x44,  0x08,  0x84,  0x18,  0xA2,  0x1D,  0x21,  0x2A,  0x28, 	/* 48040 */
+	0x2A,  0x44,  0x48,  0x84,  0x09,  0xFE,  0x08,  0x02,  0x9C,  0x02,  0x10,  0x02,  0x10,  0x7F,  0xFF,  0x02, 	/* 48050 */
+	0x10,  0x02,  0x18,  0x1F,  0xE4,  0x00,  0x84,  0x08,  0x48,  0x04,  0x50,  0x00,  0x80,  0x7F,  0xFF,  0x01, 	/* 48060 */
+	0xC0,  0x02,  0xA0,  0x0C,  0x98,  0x70,  0x87,  0x00,  0x80,  0x9F,  0x04,  0x10,  0x04,  0x10,  0x7F,  0xFF, 	/* 48070 */
+	0x05,  0x10,  0x01,  0xF0,  0x02,  0x20,  0x04,  0x40,  0x1F,  0xF8,  0x08,  0x88,  0x08,  0x88,  0x0F,  0xF8, 	/* 48080 */
+	0x02,  0x50,  0x02,  0x48,  0x04,  0x4A,  0x18,  0x22,  0x60,  0x1E,  0xA0,  0x04,  0x20,  0x04,  0x20,  0x7F, 	/* 48090 */
+	0xFF,  0x04,  0x20,  0x10,  0x10,  0x08,  0x10,  0x09,  0xFF,  0x41,  0x12,  0x21,  0x10,  0x21,  0xFC,  0x05, 	/* 480A0 */
+	0x44,  0x09,  0x44,  0x0A,  0x28,  0x12,  0x10,  0x24,  0x6C,  0x41,  0x83,  0xA9,  0x04,  0x10,  0x04,  0x10, 	/* 480B0 */
+	0x7F,  0xFF,  0x04,  0x10,  0x00,  0x80,  0x3F,  0xFE,  0x04,  0x10,  0x02,  0x10,  0x02,  0x20,  0x7F,  0xFF, 	/* 480C0 */
+	0x00,  0x00,  0x0F,  0xF8,  0x08,  0x08,  0x08,  0x08,  0x0F,  0xF8,  0x00,  0x00,  0xAB,  0x02,  0x10,  0x7F, 	/* 480D0 */
+	0xFF,  0x02,  0x10,  0x00,  0x00,  0x3F,  0xFE,  0x00,  0x80,  0x0F,  0xF8,  0x08,  0x88,  0x0F,  0xF8,  0x00, 	/* 480E0 */
+	0x80,  0x1F,  0xFC,  0x00,  0x80,  0x0F,  0xF8,  0x00,  0x80,  0x7F,  0xFF,  0x00,  0x00,  0xAF,  0x04,  0x10, 	/* 480F0 */
+	0x04,  0x10,  0x7F,  0xFF,  0x04,  0x10,  0x1F,  0xFC,  0x08,  0x88,  0x08,  0x88,  0x7F,  0xFF,  0x08,  0x88, 	/* 48100 */
+	0x08,  0x88,  0x1F,  0xFC,  0x00,  0x80,  0x00,  0x80,  0x3F,  0xFE,  0x00,  0x80,  0x00,  0x80,  0xB0,  0x02, 	/* 48110 */
+	0x20,  0x02,  0x20,  0x7F,  0xFF,  0x02,  0x20,  0x00,  0x02,  0x7C,  0x0C,  0x05,  0xF0,  0x09,  0x28,  0x11, 	/* 48120 */
+	0x28,  0x13,  0x28,  0x1D,  0x28,  0x71,  0x34,  0x11,  0x2C,  0x12,  0x3A,  0x13,  0xCA,  0x34,  0x01,  0xB1, 	/* 48130 */
+	0x04,  0x10,  0x7F,  0xFF,  0x04,  0x90,  0x00,  0x80,  0x1F,  0xFC,  0x00,  0x80,  0x7F,  0xFF,  0x02,  0x20, 	/* 48140 */
+	0x05,  0x22,  0x19,  0x1E,  0x63,  0xF0,  0x06,  0x10,  0x39,  0x20,  0x00,  0xC0,  0x07,  0x30,  0x78,  0x0E, 	/* 48150 */
+	0xB2,  0x02,  0x10,  0x02,  0x10,  0x7F,  0xFF,  0x02,  0x10,  0x00,  0x00,  0x02,  0x20,  0x3E,  0x3E,  0x02, 	/* 48160 */
+	0x20,  0x02,  0x20,  0x3E,  0x3E,  0x03,  0x20,  0x0E,  0x20,  0x72,  0x3F,  0x04,  0x20,  0x18,  0x20,  0x60, 	/* 48170 */
+	0x20,  0xB4,  0x04,  0x10,  0x04,  0x10,  0x7F,  0xFF,  0x04,  0x10,  0x01,  0x00,  0x7F,  0xFF,  0x02,  0x20, 	/* 48180 */
+	0x04,  0x90,  0x1F,  0xFC,  0x68,  0x8B,  0x0F,  0xF8,  0x08,  0x88,  0x08,  0x88,  0x0F,  0xF9,  0x00,  0x81, 	/* 48190 */
+	0x00,  0x7F,  0xB7,  0x04,  0x20,  0x7F,  0xFE,  0x04,  0x20,  0x0F,  0xF0,  0x00,  0x10,  0x3F,  0xFC,  0x00, 	/* 481A0 */
+	0x10,  0x0F,  0xF0,  0x00,  0x00,  0x7F,  0xFE,  0x41,  0x02,  0x5F,  0xFA,  0x11,  0x08,  0x11,  0x08,  0x11, 	/* 481B0 */
+	0x30,  0x01,  0x00,  0xBB,  0x02,  0x20,  0x02,  0x20,  0x7F,  0xFF,  0x02,  0x20,  0x00,  0x00,  0x04,  0x10, 	/* 481C0 */
+	0x04,  0x10,  0x7F,  0xFF,  0x04,  0x10,  0x0E,  0x38,  0x0D,  0x34,  0x14,  0xD2,  0x24,  0x51,  0x44,  0x90, 	/* 481D0 */
+	0x04,  0x10,  0x04,  0x10,  0xBD,  0x04,  0x20,  0x04,  0x20,  0x7F,  0xFF,  0x04,  0x20,  0x00,  0x00,  0x04, 	/* 481E0 */
+	0x00,  0x07,  0xFE,  0x04,  0x22,  0x04,  0x22,  0x7F,  0xD4,  0x04,  0x14,  0x15,  0x08,  0x14,  0x88,  0x24, 	/* 481F0 */
+	0x94,  0x44,  0x22,  0x0C,  0xC1,  0x83,  0x04,  0x10,  0x04,  0x10,  0x7F,  0xFF,  0x04,  0x90,  0x00,  0x80, 	/* 48200 */
+	0x3F,  0xFE,  0x04,  0x10,  0x04,  0x10,  0x0A,  0x28,  0x09,  0xA4,  0x10,  0xC0,  0x7F,  0xFF,  0x00,  0x80, 	/* 48210 */
+	0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x84,  0x02,  0x20,  0x02,  0x20,  0x7F,  0xFF,  0x0A,  0x20,  0x08, 	/* 48220 */
+	0x00,  0x0F,  0xFE,  0x12,  0x02,  0x13,  0xF2,  0x24,  0x82,  0x4F,  0xFA,  0x10,  0x82,  0x08,  0x92,  0x08, 	/* 48230 */
+	0x92,  0x0F,  0xF2,  0x00,  0x04,  0x00,  0x18,  0x87,  0x02,  0x10,  0x02,  0x10,  0x7F,  0xFF,  0x02,  0x10, 	/* 48240 */
+	0x07,  0xF8,  0x04,  0x00,  0x07,  0xF0,  0x04,  0x00,  0x07,  0xF0,  0x04,  0x00,  0x7F,  0xFF,  0x04,  0x84, 	/* 48250 */
+	0x04,  0x48,  0x05,  0xB0,  0x0E,  0x0C,  0x30,  0x03,  0x8B,  0x04,  0x10,  0x7F,  0xFF,  0x04,  0x10,  0x00, 	/* 48260 */
+	0x80,  0x3F,  0xFE,  0x00,  0x80,  0x0F,  0xF8,  0x00,  0x88,  0x7F,  0xFF,  0x00,  0x88,  0x0F,  0xF8,  0x01, 	/* 48270 */
+	0x00,  0x7F,  0xFF,  0x02,  0x10,  0x01,  0xE0,  0x1E,  0x18,  0x8C,  0x02,  0x10,  0x02,  0x10,  0x7F,  0xFF, 	/* 48280 */
+	0x02,  0x10,  0x00,  0x00,  0x3E,  0x7E,  0x22,  0x42,  0x22,  0x42,  0x3E,  0x7E,  0x22,  0x42,  0x22,  0x42, 	/* 48290 */
+	0x22,  0x7E,  0x3E,  0x42,  0x00,  0x42,  0x00,  0x82,  0x01,  0x06,  0x8D,  0x04,  0x20,  0x04,  0x20,  0x7F, 	/* 482A0 */
+	0xFF,  0x04,  0x20,  0x10,  0x00,  0x0B,  0xFE,  0x08,  0x28,  0x00,  0xA4,  0x40,  0xA4,  0x21,  0x20,  0x27, 	/* 482B0 */
+	0xFF,  0x08,  0x20,  0x08,  0x20,  0x10,  0x20,  0x20,  0x20,  0x40,  0x20,  0x8E,  0x02,  0x10,  0x7F,  0xFF, 	/* 482C0 */
+	0x02,  0x10,  0x00,  0x38,  0x1F,  0xC0,  0x00,  0x80,  0x7F,  0xFF,  0x02,  0xA0,  0x0C,  0x98,  0x30,  0x86, 	/* 482D0 */
+	0x7F,  0xFF,  0x02,  0x20,  0x04,  0x20,  0x1F,  0xC0,  0x03,  0x30,  0x3C,  0x0C,  0x93,  0x04,  0x10,  0x04, 	/* 482E0 */
+	0x10,  0x7F,  0xFF,  0x04,  0x10,  0x00,  0x80,  0x3F,  0xFE,  0x20,  0x02,  0x27,  0xF2,  0x04,  0x10,  0x07, 	/* 482F0 */
+	0xF0,  0x04,  0x10,  0x07,  0xF0,  0x04,  0x10,  0x04,  0x10,  0x7F,  0xFF,  0x00,  0x00,  0xA0,  0x02,  0x10, 	/* 48300 */
+	0x02,  0x10,  0x7F,  0xFF,  0x02,  0x10,  0x00,  0x00,  0x1F,  0x3E,  0x11,  0x22,  0x11,  0x22,  0x1D,  0x3A, 	/* 48310 */
+	0x13,  0x26,  0x11,  0x22,  0x1D,  0x3A,  0x13,  0x26,  0x11,  0x22,  0x21,  0x42,  0x43,  0x86,  0xA2,  0x04, 	/* 48320 */
+	0x20,  0x04,  0x20,  0x7F,  0xFF,  0x04,  0x20,  0x10,  0x80,  0x08,  0x80,  0x08,  0xFE,  0x01,  0x02,  0x41, 	/* 48330 */
+	0xF2,  0x22,  0x12,  0x24,  0x12,  0x09,  0xF4,  0x09,  0x18,  0x11,  0x01,  0x21,  0x01,  0x40,  0xFF,  0xA9, 	/* 48340 */
+	0x02,  0x10,  0x02,  0x10,  0x7F,  0xFF,  0x02,  0x10,  0x02,  0x00,  0x0C,  0x10,  0x38,  0x12,  0x08,  0x52, 	/* 48350 */
+	0x7F,  0x54,  0x08,  0x50,  0x1C,  0x90,  0x1A,  0x28,  0x2A,  0x28,  0x48,  0x44,  0x08,  0x82,  0x09,  0x01, 	/* 48360 */
+	0xAA,  0x02,  0x20,  0x02,  0x20,  0x7F,  0xFF,  0x02,  0x20,  0x01,  0x00,  0x06,  0x24,  0x3C,  0x14,  0x04, 	/* 48370 */
+	0x14,  0x7F,  0x44,  0x0E,  0x24,  0x0D,  0x24,  0x14,  0x87,  0x24,  0x1C,  0x44,  0xE4,  0x04,  0x04,  0x04, 	/* 48380 */
+	0x04,  0xAC,  0x02,  0x10,  0x02,  0x10,  0x7F,  0xFF,  0x02,  0x10,  0x0F,  0xF8,  0x08,  0x88,  0x0F,  0xF8, 	/* 48390 */
+	0x08,  0x88,  0x0F,  0xF8,  0x00,  0x80,  0x3F,  0xFE,  0x20,  0xA2,  0x20,  0x92,  0x20,  0xEA,  0x2F,  0x0A, 	/* 483A0 */
+	0x20,  0x06,  0xB1,  0x08,  0x20,  0x08,  0x20,  0x7F,  0xFE,  0x08,  0x20,  0x01,  0x00,  0x7F,  0xFE,  0x40, 	/* 483B0 */
+	0x02,  0x5F,  0xFA,  0x00,  0x00,  0x0F,  0xF0,  0x08,  0x10,  0x0F,  0xF0,  0x08,  0x10,  0x0F,  0xF0,  0x00, 	/* 483C0 */
+	0x00,  0x7F,  0xFE,  0xB5,  0x02,  0x10,  0x02,  0x10,  0x7F,  0xFF,  0x02,  0x10,  0x0F,  0xF8,  0x08,  0x08, 	/* 483D0 */
+	0x08,  0xF8,  0x08,  0x88,  0x08,  0x88,  0x3F,  0xFE,  0x20,  0x02,  0x23,  0xE2,  0x22,  0x22,  0x22,  0x22, 	/* 483E0 */
+	0x23,  0xE2,  0x20,  0x06,  0xB8,  0x04,  0x10,  0x04,  0x10,  0x7F,  0xFF,  0x04,  0x10,  0x02,  0x80,  0x1C, 	/* 483F0 */
+	0xBC,  0x10,  0x84,  0x1E,  0xBC,  0x10,  0x84,  0x10,  0x84,  0x1F,  0xFC,  0x00,  0x80,  0x01,  0x40,  0x02, 	/* 48400 */
+	0x20,  0x0C,  0x18,  0x70,  0x07,  0xBC,  0x02,  0x10,  0x7F,  0xFF,  0x02,  0x10,  0x02,  0x10,  0x1F,  0x7C, 	/* 48410 */
+	0x11,  0x44,  0x1F,  0x7C,  0x00,  0x00,  0x0F,  0xF8,  0x00,  0x00,  0x7F,  0xFF,  0x02,  0x00,  0x07,  0xF8, 	/* 48420 */
+	0x04,  0x08,  0x00,  0x08,  0x00,  0x30,  0xBD,  0x02,  0x20,  0x02,  0x20,  0x7F,  0xFF,  0x02,  0xA0,  0x10, 	/* 48430 */
+	0x80,  0x08,  0xFC,  0x08,  0x88,  0x41,  0x50,  0x22,  0x20,  0x20,  0xD8,  0x09,  0x04,  0x0F,  0xFF,  0x11, 	/* 48440 */
+	0x04,  0x11,  0x04,  0x21,  0xFC,  0x20,  0x00,  0x86,  0x02,  0x10,  0x02,  0x10,  0x7F,  0xFF,  0x02,  0x10, 	/* 48450 */
+	0x00,  0x00,  0x04,  0xFC,  0x04,  0x84,  0x08,  0x84,  0x08,  0xFC,  0x18,  0x10,  0x2B,  0xFF,  0x48,  0x58, 	/* 48460 */
+	0x08,  0x94,  0x09,  0x12,  0x0A,  0x11,  0x08,  0x10,  0x89,  0x02,  0x10,  0x7F,  0xFF,  0x02,  0x10,  0x04, 	/* 48470 */
+	0x90,  0x3F,  0xFE,  0x04,  0x90,  0x04,  0xF0,  0x04,  0x00,  0x07,  0xFC,  0x00,  0x80,  0x7F,  0xFF,  0x01, 	/* 48480 */
+	0xC0,  0x02,  0xA0,  0x0C,  0x98,  0x70,  0x87,  0x00,  0x80,  0x8E,  0x04,  0x10,  0x04,  0x10,  0x7F,  0xFF, 	/* 48490 */
+	0x04,  0x10,  0x08,  0x20,  0x09,  0xFC,  0x10,  0x24,  0x27,  0xFF,  0x44,  0x24,  0x09,  0xFC,  0x10,  0x20, 	/* 484A0 */
+	0x31,  0xFE,  0x50,  0x20,  0x17,  0xFF,  0x10,  0x20,  0x10,  0x20,  0x97,  0x04,  0x10,  0x04,  0x10,  0x7F, 	/* 484B0 */
+	0xFE,  0x04,  0x90,  0x00,  0x90,  0x1F,  0xF8,  0x00,  0xA0,  0x7F,  0xFE,  0x00,  0x80,  0x07,  0xF8,  0x0C, 	/* 484C0 */
+	0x08,  0x37,  0xF8,  0x04,  0x08,  0x04,  0x08,  0x07,  0xF8,  0x00,  0x00,  0x9B,  0x04,  0x20,  0x04,  0x20, 	/* 484D0 */
+	0x7F,  0xFE,  0x04,  0x20,  0x0F,  0xF0,  0x08,  0x10,  0x0F,  0xF0,  0x08,  0x10,  0x0F,  0xF0,  0x02,  0x00, 	/* 484E0 */
+	0x07,  0xFE,  0x1C,  0x62,  0x67,  0x82,  0x04,  0x12,  0x03,  0xF2,  0x00,  0x0C,  0xA1,  0x04,  0x20,  0x7F, 	/* 484F0 */
+	0xFF,  0x04,  0x20,  0x08,  0x00,  0x0F,  0xFE,  0x08,  0xA2,  0x1F,  0xFA,  0x20,  0x82,  0x4F,  0xF2,  0x08, 	/* 48500 */
+	0x92,  0x0F,  0xF2,  0x08,  0x92,  0x0F,  0xF2,  0x08,  0x92,  0x08,  0x34,  0x00,  0x18,  0xA2,  0x02,  0x20, 	/* 48510 */
+	0x02,  0x20,  0x7F,  0xFF,  0x02,  0x20,  0x00,  0x80,  0x3F,  0xFE,  0x01,  0x40,  0x02,  0x20,  0x0D,  0x18, 	/* 48520 */
+	0x70,  0x87,  0x00,  0x00,  0x1F,  0xFC,  0x12,  0x24,  0x12,  0x24,  0x7F,  0xFF,  0x00,  0x00,  0xA3,  0x02, 	/* 48530 */
+	0x10,  0x7F,  0xFF,  0x02,  0x18,  0x0F,  0xE0,  0x00,  0x80,  0x7F,  0xFF,  0x00,  0x80,  0x0F,  0xF8,  0x08, 	/* 48540 */
+	0x88,  0x0F,  0xF8,  0x08,  0x88,  0x0F,  0xF8,  0x00,  0x80,  0x1F,  0xFC,  0x00,  0x80,  0x7F,  0xFF,  0xA6, 	/* 48550 */
+	0x02,  0x10,  0x7F,  0xFF,  0x02,  0x10,  0x01,  0x00,  0x0F,  0xF8,  0x02,  0x08,  0x7F,  0xFF,  0x00,  0x00, 	/* 48560 */
+	0x07,  0xF8,  0x04,  0x08,  0x07,  0xF8,  0x00,  0x40,  0x0F,  0xFC,  0x08,  0x40,  0x7F,  0xFF,  0x00,  0x40, 	/* 48570 */
+	0xA9,  0x02,  0x10,  0x02,  0x10,  0x7F,  0xFF,  0x02,  0x10,  0x08,  0x00,  0x10,  0x7E,  0x3E,  0x4A,  0x22, 	/* 48580 */
+	0x4A,  0x22,  0x4A,  0x3E,  0x4A,  0x22,  0x7E,  0x22,  0x40,  0x22,  0x40,  0x3E,  0x41,  0x00,  0x41,  0x00, 	/* 48590 */
+	0x3F,  0xAB,  0x04,  0x20,  0x04,  0x20,  0x7F,  0xFF,  0x04,  0x20,  0x08,  0x00,  0x08,  0x3E,  0x7F,  0xA2, 	/* 485A0 */
+	0x08,  0x22,  0x08,  0x3E,  0x08,  0x22,  0x3E,  0x22,  0x22,  0x3E,  0x22,  0x22,  0x22,  0x22,  0x3E,  0x42, 	/* 485B0 */
+	0x00,  0x86,  0xAC,  0x04,  0x10,  0x04,  0x10,  0x7F,  0xFF,  0x04,  0x10,  0x7F,  0xFF,  0x02,  0x22,  0x07, 	/* 485C0 */
+	0xA4,  0x38,  0xB8,  0x05,  0x20,  0x06,  0x22,  0x3A,  0x1E,  0x02,  0x10,  0x7F,  0xFF,  0x02,  0x10,  0x04, 	/* 485D0 */
+	0x10,  0x18,  0x10,  0xAD,  0x02,  0x10,  0x02,  0x10,  0x7F,  0xFF,  0x02,  0x10,  0x00,  0x00,  0x3F,  0x7E, 	/* 485E0 */
+	0x21,  0x02,  0x21,  0x02,  0x3F,  0x7E,  0x20,  0x00,  0x20,  0xFE,  0x3F,  0x44,  0x20,  0x28,  0x3F,  0x10, 	/* 485F0 */
+	0x20,  0x6C,  0x21,  0x83,  0xAE,  0x02,  0x10,  0x02,  0x10,  0x7F,  0xFF,  0x02,  0x10,  0x03,  0x00,  0x02, 	/* 48600 */
+	0x7C,  0x1C,  0x45,  0x10,  0x45,  0x1E,  0x83,  0x11,  0x00,  0x1E,  0xFC,  0x10,  0x44,  0x10,  0x28,  0x1E, 	/* 48610 */
+	0x30,  0x70,  0xCC,  0x13,  0x03,  0xAF,  0x02,  0x10,  0x02,  0x10,  0x7F,  0xFF,  0x02,  0x10,  0x08,  0x20, 	/* 48620 */
+	0x0A,  0x20,  0x72,  0x3E,  0x14,  0x42,  0x08,  0x42,  0x12,  0xA2,  0x7F,  0x12,  0x09,  0x12,  0x2A,  0x02, 	/* 48630 */
+	0x29,  0x02,  0x49,  0x02,  0x08,  0x0C,  0xB1,  0x02,  0x20,  0x02,  0x20,  0x7F,  0xFF,  0x02,  0x20,  0x04, 	/* 48640 */
+	0x00,  0x07,  0xFC,  0x09,  0x24,  0x17,  0xA4,  0x22,  0x74,  0x04,  0x44,  0x08,  0x98,  0x12,  0x40,  0x12, 	/* 48650 */
+	0x42,  0x22,  0x09,  0x41,  0x09,  0x00,  0xF8,  0xB5,  0x02,  0x20,  0x02,  0x20,  0x7F,  0xFF,  0x02,  0x20, 	/* 48660 */
+	0x0F,  0x48,  0x21,  0x52,  0x12,  0x24,  0x0C,  0x18,  0x17,  0xFC,  0x60,  0x83,  0x00,  0x80,  0x3F,  0xFE, 	/* 48670 */
+	0x01,  0x40,  0x02,  0x20,  0x0C,  0x18,  0x30,  0x06,  0xB7,  0x02,  0x10,  0x7F,  0xFF,  0x02,  0x10,  0x00, 	/* 48680 */
+	0x00,  0x3F,  0xFE,  0x20,  0x82,  0x2F,  0xFA,  0x00,  0x80,  0x0F,  0xF8,  0x08,  0x88,  0x0F,  0xF8,  0x08, 	/* 48690 */
+	0x88,  0x0F,  0xF8,  0x00,  0x80,  0x7F,  0xFF,  0x00,  0x80,  0xB9,  0x02,  0x10,  0x02,  0x10,  0x7F,  0xFF, 	/* 486A0 */
+	0x02,  0x10,  0x08,  0x20,  0x08,  0x3F,  0x7E,  0x48,  0x10,  0xAA,  0x11,  0x2E,  0x1E,  0x3A,  0x12,  0xEA, 	/* 486B0 */
+	0x12,  0x2E,  0x12,  0x28,  0x22,  0x21,  0x22,  0x21,  0x4C,  0x1F,  0xBA,  0x02,  0x20,  0x7F,  0xFE,  0x02, 	/* 486C0 */
+	0x20,  0x0F,  0xF8,  0x08,  0x08,  0x0F,  0xF8,  0x00,  0x00,  0x7F,  0xFE,  0x04,  0x10,  0x07,  0xF0,  0x04, 	/* 486D0 */
+	0x10,  0x07,  0xF0,  0x04,  0x1C,  0x07,  0xF0,  0x38,  0x10,  0x00,  0x10,  0x82,  0x04,  0x10,  0x04,  0x10, 	/* 486E0 */
+	0x7F,  0xFF,  0x04,  0x10,  0x00,  0x80,  0x3F,  0xFE,  0x04,  0x10,  0x02,  0x20,  0x3F,  0xFE,  0x20,  0x82, 	/* 486F0 */
+	0x20,  0x80,  0x1F,  0xFC,  0x10,  0x84,  0x10,  0x84,  0x10,  0x98,  0x00,  0x80,  0x84,  0x04,  0x20,  0x04, 	/* 48700 */
+	0x20,  0x7F,  0xFF,  0x04,  0x20,  0x00,  0x00,  0x7F,  0xFE,  0x40,  0x02,  0x1F,  0x04,  0x00,  0x7F,  0x7F, 	/* 48710 */
+	0xA4,  0x0A,  0x14,  0x0A,  0x14,  0x12,  0x04,  0x12,  0x0D,  0x22,  0x01,  0x41,  0xFF,  0x8B,  0x04,  0x20, 	/* 48720 */
+	0x04,  0x20,  0x7F,  0xFF,  0x04,  0x24,  0x08,  0x18,  0x09,  0xE2,  0x49,  0x12,  0x28,  0x94,  0x28,  0x88, 	/* 48730 */
+	0x08,  0x08,  0x1B,  0xFF,  0x28,  0x88,  0x48,  0x48,  0x08,  0x48,  0x08,  0x08,  0x08,  0x18,  0x90,  0x04, 	/* 48740 */
+	0x20,  0x04,  0x20,  0x7F,  0xFE,  0x04,  0xA0,  0x01,  0x00,  0x0F,  0xF8,  0x08,  0x88,  0x0F,  0xF8,  0x08, 	/* 48750 */
+	0x88,  0x08,  0x88,  0x0F,  0xF8,  0x01,  0x48,  0x02,  0x54,  0x04,  0x5E,  0x18,  0x42,  0x60,  0x3E,  0x94, 	/* 48760 */
+	0x04,  0x10,  0x04,  0x10,  0x7F,  0xFE,  0x04,  0x10,  0x00,  0x20,  0x3D,  0xFC,  0x24,  0x20,  0x24,  0x20, 	/* 48770 */
+	0x27,  0xFF,  0x3C,  0x08,  0x25,  0xFE,  0x24,  0x88,  0x24,  0x48,  0x3C,  0x48,  0x00,  0x08,  0x00,  0x18, 	/* 48780 */
+	0x99,  0x02,  0x20,  0x7F,  0xFF,  0x02,  0x20,  0x3F,  0xFE,  0x20,  0x02,  0x27,  0xF2,  0x00,  0x00,  0x7F, 	/* 48790 */
+	0xFE,  0x01,  0x04,  0x06,  0xA4,  0x39,  0x68,  0x06,  0xD0,  0x39,  0x48,  0x06,  0x44,  0x78,  0x43,  0x01, 	/* 487A0 */
+	0x80,  0x9C,  0x04,  0x20,  0x04,  0x20,  0x7F,  0xFF,  0x04,  0x20,  0x00,  0x00,  0x1F,  0x3E,  0x00,  0x00, 	/* 487B0 */
+	0x00,  0x00,  0x7F,  0xFF,  0x04,  0x08,  0x15,  0x2A,  0x15,  0x2A,  0x14,  0xA9,  0x24,  0xC9,  0x44,  0x88, 	/* 487C0 */
+	0x0C,  0x18,  0x9F,  0x02,  0x10,  0x02,  0x10,  0x7F,  0xFF,  0x02,  0x10,  0x08,  0x20,  0x08,  0x20,  0x7F, 	/* 487D0 */
+	0x3E,  0x02,  0x42,  0x22,  0xFA,  0x12,  0x4A,  0x14,  0x4A,  0x14,  0x4A,  0x0B,  0x7A,  0x1C,  0x02,  0x60, 	/* 487E0 */
+	0x02,  0x00,  0x0C,  0xA1,  0x02,  0x10,  0x7F,  0xFF,  0x02,  0x10,  0x00,  0x80,  0x3F,  0xFE,  0x04,  0x10, 	/* 487F0 */
+	0x02,  0x20,  0x3F,  0xFE,  0x20,  0x82,  0x00,  0x80,  0x7F,  0xFF,  0x01,  0x00,  0x01,  0xF8,  0x02,  0x08, 	/* 48800 */
+	0x0C,  0x08,  0x30,  0x30,  0xAD,  0x02,  0x10,  0x7F,  0xFF,  0x02,  0x10,  0x04,  0x00,  0x07,  0xFE,  0x08, 	/* 48810 */
+	0x82,  0x14,  0x92,  0x27,  0xF2,  0x01,  0x0C,  0x1E,  0x00,  0x07,  0xFE,  0x08,  0x82,  0x14,  0x92,  0x07, 	/* 48820 */
+	0xF2,  0x03,  0x02,  0x1C,  0x0C,  0xB2,  0x02,  0x20,  0x02,  0x20,  0x7F,  0xFF,  0x02,  0x28,  0x18,  0x24, 	/* 48830 */
+	0x07,  0xFE,  0x00,  0x20,  0x61,  0xFC,  0x11,  0x24,  0x01,  0xFC,  0x09,  0x24,  0x09,  0xFC,  0x11,  0x24, 	/* 48840 */
+	0x11,  0x24,  0x21,  0x24,  0x41,  0x2C,  0xB8,  0x02,  0x10,  0x7F,  0xFF,  0x02,  0x10,  0x00,  0x00,  0x0F, 	/* 48850 */
+	0xF4,  0x00,  0x24,  0x3E,  0x48,  0x02,  0xB0,  0x04,  0x90,  0x18,  0x8C,  0x61,  0x83,  0x00,  0x00,  0x7F, 	/* 48860 */
+	0xFF,  0x12,  0x24,  0x31,  0x12,  0x41,  0x11,  0xB9,  0x02,  0x20,  0x7F,  0xFF,  0x02,  0x20,  0x01,  0x10, 	/* 48870 */
+	0x06,  0x60,  0x3F,  0xFE,  0x01,  0x40,  0x1F,  0xFC,  0x01,  0x44,  0x7F,  0xFF,  0x01,  0x44,  0x1F,  0xFC, 	/* 48880 */
+	0x05,  0x50,  0x19,  0x4C,  0x61,  0x43,  0x01,  0x40,  0xBB,  0x02,  0x10,  0x7F,  0xFF,  0x02,  0x10,  0x00, 	/* 48890 */
+	0x00,  0x3F,  0x7E,  0x01,  0x02,  0x01,  0x02,  0x1F,  0x3E,  0x10,  0x20,  0x1F,  0x3E,  0x09,  0x12,  0x33, 	/* 488A0 */
+	0x66,  0x05,  0x0A,  0x19,  0x32,  0x01,  0x02,  0x0E,  0x1C,  0xBC,  0x04,  0x08,  0x7F,  0xFF,  0x04,  0x88, 	/* 488B0 */
+	0x05,  0x48,  0x02,  0x20,  0x07,  0xF0,  0x18,  0x0C,  0x67,  0xF3,  0x04,  0x10,  0x07,  0xF0,  0x04,  0x10, 	/* 488C0 */
+	0x07,  0xF0,  0x08,  0x00,  0x0F,  0xF8,  0x14,  0x08,  0x27,  0xF8,  0xBF,  0x04,  0x10,  0x7F,  0xFF,  0x04, 	/* 488D0 */
+	0x10,  0x00,  0x80,  0x3F,  0xFE,  0x00,  0x00,  0x07,  0xF0,  0x04,  0x10,  0x07,  0xF0,  0x00,  0x00,  0x3F, 	/* 488E0 */
+	0xFE,  0x20,  0x02,  0x27,  0xF2,  0x24,  0x12,  0x27,  0xF2,  0x20,  0x06,  0x81,  0x02,  0x10,  0x7F,  0xFF, 	/* 488F0 */
+	0x02,  0x10,  0x00,  0x80,  0x1F,  0xFC,  0x00,  0x80,  0x0F,  0xF8,  0x01,  0x40,  0x3F,  0xFE,  0x04,  0x30, 	/* 48900 */
+	0x1B,  0xCC,  0x60,  0x83,  0x1F,  0xFC,  0x06,  0xB0,  0x38,  0x8E,  0x00,  0x80,  0x84,  0x04,  0x08,  0x04, 	/* 48910 */
+	0x08,  0x7F,  0xFF,  0x04,  0x88,  0x3F,  0xFF,  0x01,  0x90,  0x07,  0x28,  0x01,  0xCC,  0x7F,  0xF2,  0x00, 	/* 48920 */
+	0x01,  0x0F,  0xFC,  0x08,  0x44,  0x0F,  0xFC,  0x08,  0x44,  0x0F,  0xFC,  0x00,  0x00,  0x86,  0x02,  0x10, 	/* 48930 */
+	0x02,  0x10,  0x7F,  0xFF,  0x02,  0x10,  0x00,  0x40,  0x1F,  0xFF,  0x11,  0x10,  0x1F,  0xFE,  0x11,  0x10, 	/* 48940 */
+	0x11,  0xF0,  0x10,  0x40,  0x17,  0xFE,  0x24,  0x42,  0x24,  0x42,  0x44,  0x4C,  0x00,  0x40,  0x89,  0x04, 	/* 48950 */
+	0x10,  0x7F,  0xFF,  0x04,  0x90,  0x00,  0x80,  0x3F,  0xFE,  0x22,  0x22,  0x22,  0x92,  0x04,  0x88,  0x09, 	/* 48960 */
+	0x48,  0x06,  0x30,  0x18,  0x0C,  0x6F,  0xFB,  0x08,  0x08,  0x08,  0x08,  0x0F,  0xF8,  0x00,  0x00,  0x8A, 	/* 48970 */
+	0x02,  0x20,  0x02,  0x20,  0x7F,  0xFF,  0x02,  0x20,  0x05,  0xE0,  0x09,  0x18,  0x71,  0x47,  0x02,  0x30, 	/* 48980 */
+	0x1F,  0xC8,  0x00,  0x00,  0x7F,  0x7E,  0x09,  0x12,  0x33,  0x66,  0x0D,  0x1A,  0x31,  0x62,  0x03,  0x06, 	/* 48990 */
+	0x8B,  0x04,  0x10,  0x04,  0x10,  0x7F,  0xFF,  0x04,  0x90,  0x1F,  0xFC,  0x00,  0x80,  0x7F,  0xFF,  0x02, 	/* 489A0 */
+	0x20,  0x04,  0x18,  0x3F,  0xF4,  0x00,  0x02,  0x1F,  0xF8,  0x12,  0x48,  0x12,  0x48,  0x7F,  0xFF,  0x00, 	/* 489B0 */
+	0x00,  0x8D,  0x04,  0x10,  0x7F,  0xFF,  0x04,  0x90,  0x00,  0x88,  0x1F,  0xFC,  0x00,  0xA0,  0x7F,  0xFF, 	/* 489C0 */
+	0x02,  0x18,  0x0F,  0xE0,  0x74,  0x02,  0x0F,  0xFE,  0x08,  0x08,  0x0F,  0xF8,  0x08,  0x08,  0x0F,  0xF8, 	/* 489D0 */
+	0x00,  0x00,  0x90,  0x02,  0x10,  0x7F,  0xFF,  0x02,  0x10,  0x1F,  0xFE,  0x10,  0x00,  0x17,  0xFC,  0x10, 	/* 489E0 */
+	0x00,  0x1F,  0xFF,  0x12,  0x24,  0x13,  0x98,  0x1C,  0x07,  0x10,  0x08,  0x2F,  0xFF,  0x21,  0x08,  0x40, 	/* 489F0 */
+	0x88,  0x00,  0x18,  0x91,  0x04,  0x10,  0x7F,  0xFF,  0x04,  0x10,  0x00,  0x80,  0x3F,  0xFE,  0x00,  0x00, 	/* 48A00 */
+	0x07,  0xF0,  0x04,  0x10,  0x7F,  0xFF,  0x04,  0x10,  0x07,  0xF0,  0x01,  0x44,  0x06,  0x28,  0x7C,  0x10, 	/* 48A10 */
+	0x07,  0x8C,  0x1C,  0x03,  0x96,  0x04,  0x08,  0x7F,  0xFF,  0x04,  0x88,  0x01,  0x00,  0x0F,  0xF8,  0x08, 	/* 48A20 */
+	0x28,  0x0B,  0x28,  0x08,  0xC8,  0x08,  0xA8,  0x0B,  0x08,  0x0F,  0xF8,  0x08,  0x22,  0x0F,  0xBC,  0x08, 	/* 48A30 */
+	0x21,  0x0F,  0xA1,  0x78,  0x1F,  0x99,  0x02,  0x10,  0x02,  0x10,  0x7F,  0xFF,  0x02,  0x10,  0x00,  0x40, 	/* 48A40 */
+	0x1F,  0xFF,  0x11,  0x24,  0x11,  0x24,  0x11,  0xAA,  0x12,  0x71,  0x14,  0x20,  0x13,  0xFE,  0x20,  0x20, 	/* 48A50 */
+	0x20,  0x20,  0x4F,  0xFF,  0x00,  0x00,  0x9A,  0x02,  0x10,  0x02,  0x10,  0x7F,  0xFF,  0x02,  0x10,  0x08, 	/* 48A60 */
+	0x20,  0x08,  0x3F,  0x08,  0x44,  0x14,  0xA8,  0x15,  0x10,  0x34,  0x6C,  0x55,  0x93,  0x14,  0x64,  0x14, 	/* 48A70 */
+	0x1A,  0x14,  0xE4,  0x10,  0x18,  0x11,  0xE0,  0xAC,  0x02,  0x20,  0x7F,  0xFF,  0x02,  0x20,  0x00,  0x20, 	/* 48A80 */
+	0x20,  0x7C,  0x13,  0xC8,  0x10,  0x30,  0x00,  0xCC,  0x03,  0x23,  0x79,  0xFE,  0x08,  0x20,  0x08,  0xFC, 	/* 48A90 */
+	0x08,  0x20,  0x17,  0xFF,  0x23,  0x20,  0x40,  0xFF,  0xAE,  0x04,  0x10,  0x7F,  0xFF,  0x04,  0x10,  0x00, 	/* 48AA0 */
+	0x20,  0x13,  0xFE,  0x08,  0x20,  0x09,  0xFC,  0x01,  0x24,  0x01,  0xFC,  0x79,  0x24,  0x09,  0xFC,  0x08, 	/* 48AB0 */
+	0x20,  0x0B,  0xFE,  0x14,  0x20,  0x23,  0x20,  0x40,  0xFF,  0xB4,  0x04,  0x10,  0x7F,  0xFF,  0x04,  0x90, 	/* 48AC0 */
+	0x3F,  0xFE,  0x00,  0x80,  0x0F,  0xF8,  0x08,  0x88,  0x0F,  0xF8,  0x08,  0x88,  0x0F,  0xF8,  0x00,  0x84, 	/* 48AD0 */
+	0x3F,  0xFA,  0x00,  0x10,  0x7F,  0xFF,  0x02,  0x10,  0x00,  0x30,  0xBC,  0x02,  0x10,  0x7F,  0xFF,  0x02, 	/* 48AE0 */
+	0x10,  0x3F,  0x7E,  0x09,  0x12,  0x33,  0x66,  0x0D,  0x9A,  0x31,  0x46,  0x02,  0x20,  0x0C,  0x98,  0x73, 	/* 48AF0 */
+	0x27,  0x0C,  0xC8,  0x03,  0x10,  0x0C,  0x60,  0x01,  0x80,  0x1E,  0x00,  0xBF,  0x04,  0x10,  0x04,  0x10, 	/* 48B00 */
+	0x7F,  0xFF,  0x04,  0x90,  0x00,  0x80,  0x3F,  0xFE,  0x20,  0x02,  0x2B,  0xFE,  0x08,  0x40,  0x11,  0xFC, 	/* 48B10 */
+	0x31,  0x04,  0x51,  0xFC,  0x11,  0x04,  0x11,  0x04,  0x11,  0xFC,  0x10,  0x00,  0x80,  0x02,  0x10,  0x02, 	/* 48B20 */
+	0x10,  0x7F,  0xFF,  0x02,  0x10,  0x08,  0x00,  0x7F,  0xBC,  0x21,  0x24,  0x11,  0x28,  0x12,  0x38,  0x7F, 	/* 48B30 */
+	0xA4,  0x00,  0x22,  0x3F,  0x22,  0x21,  0x22,  0x21,  0x3C,  0x3F,  0x20,  0x00,  0x20,  0x86,  0x04,  0x20, 	/* 48B40 */
+	0x04,  0x20,  0x7F,  0xFF,  0x04,  0x20,  0x10,  0x20,  0x09,  0xFC,  0x08,  0x20,  0x47,  0xFF,  0x20,  0x88, 	/* 48B50 */
+	0x21,  0x0F,  0x0E,  0x40,  0x08,  0xF8,  0x13,  0x88,  0x10,  0x70,  0x20,  0xD8,  0x47,  0x07,  0x91,  0x02, 	/* 48B60 */
+	0x10,  0x02,  0x10,  0x7F,  0xFF,  0x02,  0x10,  0x0F,  0xFC,  0x09,  0x24,  0x09,  0x24,  0x0F,  0xFC,  0x00, 	/* 48B70 */
+	0x28,  0x1F,  0xFF,  0x10,  0x24,  0x16,  0x28,  0x11,  0x12,  0x10,  0x2A,  0x20,  0xC6,  0x43,  0x02,  0x93, 	/* 48B80 */
+	0x04,  0x20,  0x7F,  0xFE,  0x04,  0x20,  0x0F,  0xF0,  0x08,  0x10,  0x0F,  0xF0,  0x08,  0x10,  0x3F,  0xFC, 	/* 48B90 */
+	0x22,  0x24,  0x3F,  0xFC,  0x00,  0x00,  0x1F,  0xF8,  0x06,  0x20,  0x01,  0xC0,  0x06,  0x30,  0x78,  0x0F, 	/* 48BA0 */
+	0x94,  0x02,  0x20,  0x7F,  0xFF,  0x12,  0x20,  0x1F,  0xFE,  0x10,  0x02,  0x3F,  0xFA,  0x27,  0xE2,  0x44, 	/* 48BB0 */
+	0x22,  0x07,  0xE2,  0x00,  0x02,  0x1F,  0xF2,  0x11,  0x12,  0x1F,  0xF2,  0x11,  0x12,  0x1F,  0xF4,  0x00, 	/* 48BC0 */
+	0x18,  0x95,  0x02,  0x20,  0x7F,  0xFF,  0x02,  0x20,  0x09,  0x48,  0x7F,  0xFF,  0x09,  0x4A,  0x11,  0xC6, 	/* 48BD0 */
+	0x20,  0x00,  0x3F,  0xFE,  0x20,  0x82,  0x2F,  0xFA,  0x08,  0x88,  0x08,  0x88,  0x08,  0xB0,  0x00,  0x80, 	/* 48BE0 */
+	0x00,  0x80,  0x97,  0x02,  0x10,  0x02,  0x10,  0x7F,  0xFF,  0x02,  0x10,  0x00,  0x40,  0x1F,  0xFF,  0x11, 	/* 48BF0 */
+	0x08,  0x11,  0x08,  0x1F,  0xFF,  0x11,  0x08,  0x11,  0x08,  0x11,  0xF8,  0x20,  0x00,  0x25,  0x24,  0x48, 	/* 48C00 */
+	0x92,  0x10,  0x91,  0x98,  0x04,  0x10,  0x7F,  0xFF,  0x04,  0x90,  0x01,  0x20,  0x07,  0xF8,  0x05,  0x14, 	/* 48C10 */
+	0x1E,  0xBA,  0x00,  0x80,  0x7F,  0xFF,  0x02,  0x60,  0x0D,  0x98,  0x76,  0x27,  0x00,  0xC8,  0x0F,  0x30, 	/* 48C20 */
+	0x00,  0xC0,  0x1F,  0x00,  0x9A,  0x04,  0x20,  0x04,  0x20,  0x7F,  0xFF,  0x04,  0x20,  0x00,  0x04,  0x3F, 	/* 48C30 */
+	0x84,  0x20,  0x84,  0x3F,  0xFF,  0x20,  0x04,  0x2F,  0x44,  0x20,  0x24,  0x3F,  0xA4,  0x2B,  0x04,  0x2A, 	/* 48C40 */
+	0x84,  0x52,  0x84,  0x06,  0x0C,  0x9F,  0x02,  0x10,  0x02,  0x10,  0x7F,  0xFF,  0x02,  0x10,  0x08,  0x40, 	/* 48C50 */
+	0x08,  0x7E,  0x7E,  0x40,  0x10,  0xA0,  0x11,  0x3E,  0x1E,  0x48,  0x12,  0x08,  0x12,  0xFF,  0x12,  0x08, 	/* 48C60 */
+	0x22,  0x14,  0x22,  0x62,  0x4D,  0x81,  0xA1,  0x02,  0x10,  0x7F,  0xFF,  0x02,  0x10,  0x04,  0x00,  0x0F, 	/* 48C70 */
+	0x7E,  0x19,  0x24,  0x66,  0x18,  0x14,  0x28,  0x1B,  0xC4,  0x60,  0x03,  0x1F,  0xFC,  0x00,  0x80,  0x04, 	/* 48C80 */
+	0x98,  0x18,  0x86,  0x60,  0x81,  0x01,  0x80,  0xA6,  0x04,  0x10,  0x7F,  0xFF,  0x04,  0x90,  0x01,  0x00, 	/* 48C90 */
+	0x07,  0xF8,  0x04,  0x08,  0x07,  0xF8,  0x04,  0x08,  0x07,  0xF8,  0x04,  0x00,  0x07,  0xFF,  0x04,  0x00, 	/* 48CA0 */
+	0x17,  0xFE,  0x14,  0x92,  0x22,  0x4A,  0x40,  0x0C,  0xAC,  0x02,  0x10,  0x02,  0x10,  0x7F,  0xFF,  0x02, 	/* 48CB0 */
+	0x10,  0x00,  0x00,  0x7E,  0xFF,  0x04,  0x28,  0x08,  0x44,  0x28,  0xFE,  0x2E,  0x01,  0x28,  0x54,  0x28, 	/* 48CC0 */
+	0x54,  0x28,  0x54,  0x2E,  0x95,  0x38,  0x95,  0x61,  0x03,  0xAD,  0x02,  0x10,  0x7F,  0xFF,  0x02,  0x10, 	/* 48CD0 */
+	0x02,  0x20,  0x3C,  0x30,  0x24,  0x48,  0x28,  0xF4,  0x33,  0x03,  0x28,  0xF8,  0x24,  0x10,  0x25,  0xFC, 	/* 48CE0 */
+	0x24,  0x00,  0x3B,  0xFE,  0x20,  0x48,  0x20,  0x94,  0x21,  0xE2,  0xB5,  0x02,  0x10,  0x02,  0x10,  0x7F, 	/* 48CF0 */
+	0xFF,  0x02,  0x14,  0x00,  0x12,  0x1F,  0xFF,  0x10,  0x10,  0x17,  0xF2,  0x14,  0x92,  0x17,  0xF4,  0x14, 	/* 48D00 */
+	0x2C,  0x17,  0xE8,  0x14,  0x95,  0x27,  0xF5,  0x20,  0x23,  0x40,  0x41,  0xBD,  0x04,  0x20,  0x04,  0x20, 	/* 48D10 */
+	0x7F,  0xFF,  0x04,  0x20,  0x08,  0x00,  0x49,  0x20,  0x29,  0x3E,  0x2A,  0x24,  0x7F,  0x44,  0x49,  0x54, 	/* 48D20 */
+	0x49,  0x98,  0x5D,  0x08,  0x6B,  0x14,  0x49,  0x24,  0x49,  0x42,  0x4B,  0x81,  0x80,  0x02,  0x20,  0x02, 	/* 48D30 */
+	0x20,  0x7F,  0xFF,  0x02,  0x20,  0x08,  0x10,  0x7F,  0x7F,  0x08,  0x10,  0x3F,  0x7E,  0x29,  0x52,  0x29, 	/* 48D40 */
+	0x52,  0x2B,  0x56,  0x1C,  0x38,  0x1A,  0x34,  0x29,  0x52,  0x48,  0x91,  0x08,  0x10,  0x81,  0x02,  0x10, 	/* 48D50 */
+	0x7F,  0xFF,  0x02,  0x10,  0x0F,  0xF8,  0x00,  0x08,  0x1F,  0xFE,  0x00,  0x08,  0x07,  0xF8,  0x3F,  0x7E, 	/* 48D60 */
+	0x08,  0x42,  0x7F,  0x7E,  0x00,  0x08,  0x7F,  0xFF,  0x04,  0x08,  0x02,  0x08,  0x00,  0x18,  0x83,  0x02, 	/* 48D70 */
+	0x10,  0x7F,  0xFF,  0x02,  0x10,  0x00,  0x08,  0x1F,  0xF0,  0x08,  0x88,  0x04,  0x90,  0x7F,  0xFF,  0x02, 	/* 48D80 */
+	0xA0,  0x04,  0x90,  0x1F,  0xFC,  0x68,  0x8B,  0x0F,  0xF8,  0x08,  0x88,  0x0F,  0xF8,  0x00,  0x00,  0x88, 	/* 48D90 */
+	0x02,  0x10,  0x7F,  0xFF,  0x02,  0x10,  0x00,  0x00,  0x3F,  0xFE,  0x02,  0x20,  0x1F,  0xFC,  0x12,  0x24, 	/* 48DA0 */
+	0x1F,  0xFC,  0x08,  0x08,  0x0F,  0xF8,  0x08,  0x08,  0x0F,  0xF8,  0x00,  0x80,  0x7F,  0xFF,  0x00,  0x80, 	/* 48DB0 */
+	0x89,  0x02,  0x20,  0x02,  0x20,  0x7F,  0xFF,  0x0A,  0x20,  0x08,  0x40,  0x1F,  0xFC,  0x28,  0x40,  0x4F, 	/* 48DC0 */
+	0xF8,  0x08,  0x40,  0x0F,  0xF8,  0x08,  0x40,  0x0F,  0xFC,  0x10,  0x08,  0x12,  0x44,  0x21,  0x22,  0x41, 	/* 48DD0 */
+	0x22,  0x8A,  0x04,  0x10,  0x04,  0x10,  0x7F,  0xFF,  0x04,  0x90,  0x04,  0x50,  0x12,  0x40,  0x12,  0x04, 	/* 48DE0 */
+	0x12,  0x12,  0x21,  0xF2,  0x04,  0x08,  0x02,  0x04,  0x0A,  0x14,  0x28,  0x91,  0x28,  0xB1,  0x49,  0x52, 	/* 48DF0 */
+	0x07,  0x0E,  0x8B,  0x04,  0x20,  0x7F,  0xFF,  0x04,  0x20,  0x00,  0x80,  0x04,  0x80,  0x04,  0xF8,  0x04, 	/* 48E00 */
+	0x80,  0x04,  0x80,  0x7F,  0xFE,  0x00,  0x00,  0x04,  0x08,  0x17,  0x2E,  0x14,  0x28,  0x14,  0x28,  0x1F, 	/* 48E10 */
+	0xA8,  0x70,  0xFF,  0x8E,  0x02,  0x20,  0x7F,  0xFF,  0x02,  0x20,  0x0F,  0xF8,  0x00,  0x80,  0x7F,  0xFF, 	/* 48E20 */
+	0x02,  0x20,  0x07,  0xF0,  0x1A,  0x2C,  0x63,  0xE3,  0x00,  0x00,  0x1F,  0xFC,  0x13,  0xE4,  0x12,  0x24, 	/* 48E30 */
+	0x13,  0xE4,  0x10,  0x0C,  0x95,  0x04,  0x20,  0x04,  0x20,  0x7F,  0xFF,  0x04,  0x20,  0x44,  0x78,  0x29, 	/* 48E40 */
+	0x08,  0x11,  0xFC,  0x32,  0x52,  0x4B,  0xFD,  0x1D,  0x54,  0x19,  0x5C,  0x29,  0x84,  0x49,  0xFC,  0x09, 	/* 48E50 */
+	0x04,  0x69,  0xFC,  0x10,  0x00,  0x97,  0x04,  0x20,  0x04,  0x20,  0x7F,  0xFF,  0x04,  0x20,  0x00,  0x20, 	/* 48E60 */
+	0x3E,  0x3C,  0x22,  0x24,  0x22,  0x68,  0x3E,  0x98,  0x08,  0x24,  0x2E,  0x42,  0x29,  0xFD,  0x28,  0x44, 	/* 48E70 */
+	0x2E,  0x44,  0x38,  0x7C,  0x60,  0x00,  0x98,  0x02,  0x10,  0x7F,  0xFF,  0x02,  0x10,  0x00,  0x80,  0x0F, 	/* 48E80 */
+	0xF8,  0x00,  0x80,  0x7F,  0xFF,  0x08,  0x10,  0x3E,  0x7C,  0x0B,  0x10,  0x7C,  0xFF,  0x00,  0x00,  0x3F, 	/* 48E90 */
+	0xFE,  0x02,  0x20,  0x0C,  0x21,  0x70,  0x1F,  0x9A,  0x02,  0x10,  0x7F,  0xFF,  0x02,  0x10,  0x07,  0xF0, 	/* 48EA0 */
+	0x04,  0x10,  0x3F,  0xFE,  0x22,  0x22,  0x3E,  0x3E,  0x00,  0x00,  0x0F,  0xF8,  0x00,  0x00,  0x7F,  0xFF, 	/* 48EB0 */
+	0x02,  0x00,  0x07,  0xF8,  0x04,  0x08,  0x00,  0x30,  0xA3,  0x02,  0x10,  0x7F,  0xFF,  0x02,  0x10,  0x00, 	/* 48EC0 */
+	0x18,  0x0F,  0xE0,  0x11,  0x08,  0x08,  0x90,  0x3F,  0xFE,  0x24,  0x0A,  0x27,  0x0A,  0x09,  0x7C,  0x11, 	/* 48ED0 */
+	0x48,  0x2A,  0x48,  0x05,  0xFF,  0x18,  0x08,  0x60,  0x08,  0xA8,  0x02,  0x10,  0x3F,  0xFF,  0x02,  0x10, 	/* 48EE0 */
+	0x00,  0x00,  0x1F,  0xFF,  0x14,  0x90,  0x13,  0x10,  0x1F,  0xDF,  0x12,  0x2A,  0x1A,  0xAC,  0x1A,  0xC8, 	/* 48EF0 */
+	0x1A,  0x8C,  0x2F,  0x94,  0x22,  0x92,  0x44,  0x22,  0x08,  0x41,  0xA9,  0x02,  0x10,  0x7F,  0xFF,  0x02, 	/* 48F00 */
+	0x10,  0x10,  0xFC,  0x08,  0x84,  0x08,  0xFC,  0x40,  0x84,  0x20,  0xFC,  0x20,  0x00,  0x03,  0xFF,  0x08, 	/* 48F10 */
+	0x80,  0x11,  0xFE,  0x12,  0x4A,  0x24,  0x92,  0x21,  0x22,  0x40,  0x0C,  0xAA,  0x02,  0x20,  0x02,  0x20, 	/* 48F20 */
+	0x7F,  0xFF,  0x0A,  0x20,  0x08,  0x00,  0x1F,  0xFE,  0x29,  0x48,  0x49,  0x48,  0x7F,  0xFF,  0x09,  0x48, 	/* 48F30 */
+	0x09,  0x48,  0x7F,  0xFF,  0x10,  0x00,  0x14,  0x44,  0x22,  0x22,  0x42,  0x21,  0xAD,  0x02,  0x10,  0x7F, 	/* 48F40 */
+	0xFF,  0x02,  0x10,  0x00,  0x80,  0x1F,  0xFC,  0x00,  0x84,  0x7F,  0xFF,  0x00,  0x84,  0x1F,  0xFC,  0x04, 	/* 48F50 */
+	0x90,  0x14,  0x94,  0x1F,  0xFC,  0x10,  0x84,  0x1C,  0x9C,  0x24,  0x94,  0x44,  0x94,  0xB7,  0x02,  0x10, 	/* 48F60 */
+	0x7F,  0xFF,  0x02,  0x10,  0x00,  0x00,  0x3E,  0xFF,  0x02,  0x10,  0x14,  0x20,  0x08,  0x7E,  0x7F,  0x42, 	/* 48F70 */
+	0x09,  0x7E,  0x0A,  0x42,  0x0C,  0x7E,  0x08,  0x42,  0x08,  0x7E,  0x08,  0x26,  0x19,  0xC1,  0xBE,  0x02, 	/* 48F80 */
+	0x20,  0x7F,  0xFF,  0x02,  0x20,  0x1F,  0xFC,  0x00,  0x80,  0x3F,  0xFE,  0x20,  0x82,  0x2E,  0xBA,  0x27, 	/* 48F90 */
+	0x9C,  0x00,  0x00,  0x1F,  0xFC,  0x10,  0x84,  0x1F,  0xFC,  0x10,  0x84,  0x1F,  0xFC,  0x00,  0x00,  0x80, 	/* 48FA0 */
+	0x04,  0x20,  0x04,  0x20,  0x7F,  0xFF,  0x04,  0x20,  0x11,  0xF8,  0x09,  0x48,  0x09,  0x68,  0x41,  0x98, 	/* 48FB0 */
+	0x21,  0xF8,  0x28,  0x00,  0x0B,  0xFE,  0x12,  0x92,  0x12,  0x92,  0x22,  0x92,  0x2F,  0xFF,  0x40,  0x00, 	/* 48FC0 */
+	0x84,  0x04,  0x20,  0x7F,  0xFF,  0x04,  0x28,  0x10,  0x24,  0x0B,  0xFF,  0x08,  0x20,  0x41,  0xFC,  0x21, 	/* 48FD0 */
+	0x24,  0x21,  0xFC,  0x01,  0x24,  0x11,  0xFC,  0x10,  0x08,  0x27,  0xFF,  0x21,  0x08,  0x40,  0x88,  0x40, 	/* 48FE0 */
+	0x18,  0x87,  0x04,  0x20,  0x04,  0x20,  0x7F,  0xFF,  0x04,  0x20,  0x11,  0x10,  0x15,  0x50,  0x25,  0x5F, 	/* 48FF0 */
+	0x4F,  0xE4,  0x08,  0x24,  0x17,  0xD4,  0x30,  0x14,  0x53,  0xA8,  0x12,  0xC8,  0x14,  0x94,  0x18,  0x22, 	/* 49000 */
+	0x10,  0xC1,  0x88,  0x04,  0x10,  0x7F,  0xFF,  0x05,  0x50,  0x03,  0xE0,  0x04,  0x10,  0x1F,  0xFC,  0x74, 	/* 49010 */
+	0x97,  0x12,  0xA4,  0x1F,  0xFC,  0x00,  0x00,  0x0F,  0xF8,  0x08,  0x08,  0x0F,  0xF8,  0x08,  0x08,  0x0F, 	/* 49020 */
+	0xF8,  0x00,  0x00,  0x8A,  0x02,  0x10,  0x7F,  0xFF,  0x02,  0x10,  0x04,  0x12,  0x0F,  0x02,  0x12,  0x12, 	/* 49030 */
+	0x7F,  0x92,  0x24,  0x92,  0x3F,  0x92,  0x24,  0x92,  0x24,  0x92,  0x3F,  0x82,  0x0A,  0x42,  0x25,  0x42, 	/* 49040 */
+	0x25,  0x02,  0x40,  0x06,  0x90,  0x02,  0x10,  0x7F,  0xFF,  0x02,  0x10,  0x02,  0x10,  0x0C,  0xFE,  0x78, 	/* 49050 */
+	0x10,  0x08,  0x10,  0x09,  0xFF,  0x7E,  0x48,  0x08,  0xAF,  0x1D,  0x20,  0x1A,  0x7C,  0x29,  0xC8,  0x48, 	/* 49060 */
+	0x30,  0x08,  0xCC,  0x0B,  0x03,  0x91,  0x04,  0x10,  0x7F,  0xFF,  0x04,  0x10,  0x3F,  0xFE,  0x08,  0x88, 	/* 49070 */
+	0x0F,  0xF8,  0x08,  0x88,  0x0F,  0xF8,  0x3F,  0xFE,  0x00,  0x00,  0x0F,  0xF8,  0x08,  0x88,  0x0F,  0xF8, 	/* 49080 */
+	0x08,  0x88,  0x7F,  0xFF,  0x00,  0x00,  0x94,  0x04,  0x10,  0x7F,  0xFF,  0x04,  0x90,  0x3F,  0xFE,  0x04, 	/* 49090 */
+	0x88,  0x0C,  0x98,  0x12,  0xA4,  0x7F,  0xFF,  0x00,  0x00,  0x1F,  0xF8,  0x13,  0xC8,  0x12,  0x48,  0x13, 	/* 490A0 */
+	0xC8,  0x10,  0x08,  0x1F,  0xF8,  0x10,  0x08,  0x97,  0x04,  0x10,  0x7F,  0xFF,  0x04,  0x10,  0x3F,  0xFE, 	/* 490B0 */
+	0x20,  0x82,  0x27,  0xF2,  0x20,  0x82,  0x3F,  0xFE,  0x24,  0x22,  0x27,  0xE2,  0x23,  0x92,  0x25,  0x62, 	/* 490C0 */
+	0x39,  0x32,  0x21,  0x0E,  0x3F,  0xFE,  0x00,  0x00,  0x99,  0x04,  0x20,  0x04,  0x20,  0x7F,  0xFF,  0x04, 	/* 490D0 */
+	0x20,  0x10,  0x24,  0x10,  0x48,  0x1F,  0x7F,  0x28,  0xC8,  0x48,  0x48,  0x7F,  0x7E,  0x08,  0x48,  0x0C, 	/* 490E0 */
+	0x7E,  0x12,  0x48,  0x11,  0x48,  0x21,  0x7F,  0x40,  0x40,  0x9B,  0x02,  0x20,  0x7F,  0xFF,  0x02,  0x20, 	/* 490F0 */
+	0x08,  0x10,  0x10,  0x10,  0x3E,  0xFE,  0x22,  0x44,  0x22,  0x24,  0x3E,  0x28,  0x21,  0xFF,  0x20,  0x10, 	/* 49100 */
+	0x3E,  0x10,  0x22,  0xFE,  0x22,  0x10,  0x3E,  0x10,  0x00,  0x10,  0x9C,  0x02,  0x20,  0x7F,  0xFF,  0x02, 	/* 49110 */
+	0x20,  0x00,  0x10,  0x1F,  0x10,  0x11,  0xFE,  0x11,  0x44,  0x1F,  0x24,  0x10,  0x28,  0x10,  0xFF,  0x2F, 	/* 49120 */
+	0x10,  0x29,  0x10,  0x49,  0xFE,  0x09,  0x10,  0x0F,  0x10,  0x00,  0x10,  0xA4,  0x04,  0x20,  0x04,  0x20, 	/* 49130 */
+	0x7F,  0xFF,  0x04,  0x20,  0x00,  0x28,  0x7E,  0xEE,  0x08,  0x28,  0x08,  0x28,  0x1E,  0xEE,  0x12,  0x28, 	/* 49140 */
+	0x34,  0x28,  0x4C,  0xEE,  0x08,  0x28,  0x10,  0x28,  0x21,  0xFF,  0x40,  0x00,  0xA6,  0x04,  0x08,  0x7F, 	/* 49150 */
+	0xFE,  0x04,  0x08,  0x00,  0x40,  0x1F,  0xFE,  0x11,  0x20,  0x1F,  0xFC,  0x11,  0x24,  0x1F,  0xFC,  0x12, 	/* 49160 */
+	0x00,  0x13,  0xFF,  0x12,  0x00,  0x23,  0xFE,  0x28,  0x92,  0x4A,  0x4A,  0x11,  0x0C,  0xA8,  0x02,  0x20, 	/* 49170 */
+	0x7F,  0xFF,  0x02,  0x20,  0x1F,  0xFC,  0x11,  0x24,  0x1F,  0xFC,  0x00,  0x00,  0x7F,  0xFE,  0x40,  0x02, 	/* 49180 */
+	0x5F,  0xFA,  0x04,  0x40,  0x0F,  0x48,  0x31,  0x70,  0x0A,  0x42,  0x0C,  0x42,  0x70,  0x3E,  0xA9,  0x04, 	/* 49190 */
+	0x20,  0x7F,  0xFF,  0x04,  0x20,  0x00,  0x10,  0x3D,  0xFE,  0x24,  0x84,  0x24,  0x48,  0x2B,  0xFF,  0x32, 	/* 491A0 */
+	0x90,  0x2A,  0xFE,  0x26,  0x90,  0x27,  0x7E,  0x3A,  0x10,  0x24,  0x10,  0x25,  0xFF,  0x28,  0x00,  0xAA, 	/* 491B0 */
+	0x04,  0x20,  0x04,  0x20,  0x7F,  0xFF,  0x04,  0x20,  0x04,  0x04,  0x3F,  0xB8,  0x11,  0x20,  0x0A,  0x20, 	/* 491C0 */
+	0x7F,  0xBF,  0x04,  0x24,  0x7F,  0xA4,  0x0E,  0x24,  0x15,  0x44,  0x24,  0x44,  0x44,  0x84,  0x04,  0x04, 	/* 491D0 */
+	0xAB,  0x04,  0x10,  0x3F,  0xFE,  0x04,  0x18,  0x1F,  0xE0,  0x00,  0x80,  0x7F,  0xFF,  0x08,  0x88,  0x0F, 	/* 491E0 */
+	0xF8,  0x08,  0x88,  0x0F,  0xF8,  0x00,  0x80,  0x1F,  0xFC,  0x00,  0x80,  0x7F,  0xFF,  0x0A,  0x44,  0x31, 	/* 491F0 */
+	0x22,  0xAC,  0x02,  0x10,  0x7F,  0xFF,  0x02,  0x10,  0x00,  0x82,  0x33,  0xF2,  0x0A,  0x14,  0x07,  0xF8, 	/* 49200 */
+	0x0A,  0x16,  0x33,  0xF1,  0x00,  0x80,  0x7F,  0xFF,  0x02,  0xA0,  0x04,  0x90,  0x18,  0x8C,  0x60,  0x83, 	/* 49210 */
+	0x00,  0x80,  0xAE,  0x04,  0x20,  0x7F,  0xFF,  0x04,  0x20,  0x24,  0xA0,  0x15,  0x20,  0x7F,  0xBF,  0x16, 	/* 49220 */
+	0x24,  0x25,  0x44,  0x44,  0xA4,  0x08,  0x14,  0x7F,  0xD4,  0x09,  0x08,  0x19,  0x0C,  0x06,  0x14,  0x19, 	/* 49230 */
+	0x22,  0x60,  0xC1,  0xAF,  0x04,  0x10,  0x7F,  0xFF,  0x04,  0x10,  0x1F,  0xFC,  0x12,  0x24,  0x1F,  0xFC, 	/* 49240 */
+	0x00,  0x88,  0x1F,  0xFE,  0x00,  0xA0,  0x7F,  0xFF,  0x03,  0xF8,  0x04,  0x08,  0x1F,  0xF8,  0x64,  0x08, 	/* 49250 */
+	0x07,  0xF8,  0x00,  0x00,  0xB9,  0x02,  0x10,  0x7F,  0xFF,  0x02,  0x90,  0x3F,  0xFE,  0x00,  0x80,  0x1F, 	/* 49260 */
+	0xFC,  0x07,  0xF0,  0x04,  0x10,  0x3F,  0xFE,  0x20,  0x02,  0x2F,  0xFC,  0x02,  0x30,  0x0F,  0xE8,  0x00, 	/* 49270 */
+	0x80,  0x7F,  0xFF,  0x00,  0x00,  0xBA,  0x02,  0x10,  0x7F,  0xFF,  0x02,  0x10,  0x00,  0x80,  0x7F,  0xFF, 	/* 49280 */
+	0x02,  0x22,  0x7D,  0x5C,  0x14,  0x94,  0x2C,  0x92,  0x48,  0x89,  0x08,  0x08,  0x0F,  0xF8,  0x08,  0x08, 	/* 49290 */
+	0x0F,  0xF8,  0x10,  0x08,  0x20,  0x08,  0x81,  0x04,  0x10,  0x7F,  0xFF,  0x04,  0x90,  0x3F,  0xFE,  0x04, 	/* 492A0 */
+	0x10,  0x07,  0xF0,  0x00,  0x00,  0x3F,  0xFE,  0x22,  0x22,  0x23,  0xE6,  0x00,  0x80,  0x7F,  0xFF,  0x02, 	/* 492B0 */
+	0xA0,  0x0C,  0x98,  0x70,  0x87,  0x00,  0x80,  0x89,  0x02,  0x10,  0x7F,  0xFF,  0x02,  0x10,  0x08,  0x24, 	/* 492C0 */
+	0x0A,  0x7E,  0x3C,  0x24,  0x08,  0x24,  0x3E,  0xFF,  0x08,  0x00,  0x7F,  0x7E,  0x08,  0x42,  0x1C,  0x7E, 	/* 492D0 */
+	0x1A,  0x42,  0x2A,  0x42,  0x48,  0x7E,  0x08,  0x00,  0x8D,  0x02,  0x10,  0x7F,  0xFF,  0x02,  0x10,  0x3F, 	/* 492E0 */
+	0x90,  0x24,  0x3F,  0x3F,  0x20,  0x21,  0x40,  0x3F,  0xBE,  0x24,  0x00,  0x3F,  0x80,  0x00,  0x00,  0x1F, 	/* 492F0 */
+	0xFC,  0x12,  0x24,  0x12,  0x24,  0x7F,  0xFF,  0x00,  0x00,  0x8F,  0x04,  0x20,  0x04,  0x20,  0x7F,  0xFF, 	/* 49300 */
+	0x04,  0x24,  0x00,  0x12,  0x2F,  0xFF,  0x28,  0x10,  0x2B,  0xD2,  0x3A,  0x92,  0x0B,  0xD4,  0x7A,  0x4C, 	/* 49310 */
+	0x2B,  0xC8,  0x2A,  0x95,  0x4B,  0xF7,  0x10,  0x23,  0x20,  0x41,  0x90,  0x02,  0x10,  0x7F,  0xFF,  0x02, 	/* 49320 */
+	0x10,  0x08,  0x10,  0x15,  0x20,  0x62,  0xFE,  0x14,  0x82,  0x08,  0xFE,  0x74,  0x82,  0x04,  0xFE,  0x1A, 	/* 49330 */
+	0x28,  0x62,  0x28,  0x06,  0x28,  0x1A,  0x49,  0x62,  0x89,  0x0D,  0x07,  0x95,  0x02,  0x10,  0x02,  0x10, 	/* 49340 */
+	0x7F,  0xFF,  0x02,  0x10,  0x0A,  0x00,  0x3C,  0xFC,  0x08,  0xA4,  0x3E,  0xFC,  0x08,  0xA4,  0x7F,  0xFC, 	/* 49350 */
+	0x08,  0x20,  0x1D,  0xFE,  0x1B,  0x2A,  0x2B,  0x36,  0x49,  0xC2,  0x09,  0x06,  0x9C,  0x02,  0x20,  0x7F, 	/* 49360 */
+	0xFF,  0x02,  0x20,  0x06,  0x20,  0x38,  0x3E,  0x08,  0x52,  0x7F,  0x92,  0x1C,  0x22,  0x2A,  0x82,  0x4B, 	/* 49370 */
+	0x4C,  0x0C,  0xB0,  0x74,  0x8F,  0x03,  0xD0,  0x06,  0xB0,  0x38,  0x8E,  0x01,  0x80,  0x9D,  0x02,  0x20, 	/* 49380 */
+	0x7F,  0xFF,  0x02,  0x20,  0x04,  0x10,  0x3F,  0x10,  0x04,  0x7C,  0x7F,  0x94,  0x15,  0x54,  0x2F,  0xB4, 	/* 49390 */
+	0x44,  0x14,  0x07,  0x2D,  0x38,  0xC3,  0x00,  0x00,  0x7F,  0xFF,  0x04,  0x30,  0x1F,  0xC8,  0xA4,  0x02, 	/* 493A0 */
+	0x20,  0x7F,  0xFE,  0x02,  0x20,  0x00,  0x20,  0x3D,  0x24,  0x24,  0xA8,  0x25,  0xFC,  0x3C,  0x50,  0x25, 	/* 493B0 */
+	0xFE,  0x24,  0xA8,  0x3D,  0x24,  0x26,  0xAA,  0x24,  0x70,  0x24,  0xA8,  0x25,  0x26,  0x4C,  0x60,  0xA5, 	/* 493C0 */
+	0x04,  0x10,  0x7F,  0xFF,  0x04,  0x90,  0x11,  0x04,  0x13,  0xC4,  0x6A,  0x5A,  0x33,  0xCC,  0x12,  0x44, 	/* 493D0 */
+	0x2A,  0x4A,  0x77,  0xDD,  0x00,  0x80,  0x7F,  0xFF,  0x02,  0xA0,  0x0C,  0x98,  0x70,  0x87,  0x00,  0x80, 	/* 493E0 */
+	0xA9,  0x04,  0x10,  0x04,  0x10,  0x7F,  0xFF,  0x04,  0x0C,  0x13,  0xF0,  0x09,  0x24,  0x08,  0xA8,  0x47, 	/* 493F0 */
+	0xFF,  0x20,  0x68,  0x20,  0xA4,  0x01,  0xFE,  0x0B,  0x25,  0x09,  0xFC,  0x11,  0x24,  0x21,  0xFC,  0x41, 	/* 49400 */
+	0x04,  0xAA,  0x02,  0x20,  0x7F,  0xFF,  0x02,  0x20,  0x04,  0x10,  0x1F,  0x90,  0x14,  0x9F,  0x7F,  0xD4, 	/* 49410 */
+	0x14,  0xA4,  0x3F,  0xA4,  0x24,  0xD4,  0x3F,  0x88,  0x04,  0x08,  0x7F,  0x94,  0x09,  0x14,  0x0E,  0x22, 	/* 49420 */
+	0x31,  0x41,  0xB7,  0x04,  0x20,  0x04,  0x20,  0x7F,  0xFF,  0x04,  0x20,  0x3E,  0x12,  0x00,  0x7E,  0x7F, 	/* 49430 */
+	0x14,  0x00,  0x18,  0x3F,  0xFF,  0x00,  0x10,  0x3E,  0x7E,  0x01,  0xA2,  0x3E,  0x3E,  0x22,  0x22,  0x3E, 	/* 49440 */
+	0x3E,  0x00,  0x00,  0xB9,  0x02,  0x10,  0x7F,  0xFF,  0x02,  0x10,  0x00,  0x00,  0x3E,  0xFC,  0x00,  0x84, 	/* 49450 */
+	0x7F,  0xFC,  0x00,  0x84,  0x3E,  0xFC,  0x00,  0x40,  0x3E,  0xFE,  0x01,  0x92,  0x3E,  0x9A,  0x22,  0xA2, 	/* 49460 */
+	0x3E,  0xFA,  0x00,  0x0C,  0xBA,  0x02,  0x10,  0x7F,  0xFF,  0x02,  0x10,  0x3F,  0x3E,  0x21,  0x22,  0x3F, 	/* 49470 */
+	0x3E,  0x21,  0x22,  0x3F,  0x3E,  0x22,  0x42,  0x27,  0xFA,  0x2C,  0x42,  0x37,  0xF2,  0x27,  0xF2,  0x24, 	/* 49480 */
+	0x42,  0x27,  0xFA,  0x20,  0x06,  0xBB,  0x04,  0x20,  0x04,  0x20,  0x7F,  0xFF,  0x04,  0x20,  0x10,  0xF8, 	/* 49490 */
+	0x08,  0x88,  0x48,  0xF8,  0x23,  0xDE,  0x22,  0x52,  0x03,  0xDE,  0x08,  0x20,  0x17,  0xFF,  0x10,  0x70, 	/* 494A0 */
+	0x21,  0xAC,  0x26,  0x23,  0x40,  0x20,  0xBE,  0x02,  0x20,  0x7F,  0xFF,  0x02,  0x20,  0x08,  0x00,  0x7F, 	/* 494B0 */
+	0xFF,  0x08,  0x11,  0x08,  0x23,  0x3F,  0xFE,  0x29,  0x42,  0x29,  0x7E,  0x3F,  0x42,  0x0C,  0x7E,  0x1A, 	/* 494C0 */
+	0x42,  0x29,  0x7E,  0x48,  0x22,  0x09,  0xC1,  0x82,  0x02,  0x10,  0x7F,  0xFF,  0x02,  0x90,  0x09,  0x48, 	/* 494D0 */
+	0x09,  0x14,  0x14,  0xF4,  0x0A,  0x2A,  0x28,  0xA9,  0x29,  0xA5,  0x47,  0x1C,  0x00,  0x80,  0x7F,  0xFF, 	/* 494E0 */
+	0x02,  0xA0,  0x0C,  0x98,  0x70,  0x87,  0x00,  0x80,  0x86,  0x04,  0x10,  0x7F,  0xFF,  0x04,  0xF8,  0x00, 	/* 494F0 */
+	0x80,  0x1F,  0xFF,  0x10,  0xB2,  0x17,  0xC4,  0x13,  0xFC,  0x12,  0x48,  0x13,  0xF8,  0x12,  0x48,  0x13, 	/* 49500 */
+	0xF8,  0x20,  0x00,  0x27,  0xFC,  0x44,  0xA4,  0x1F,  0xFF,  0x87,  0x04,  0x20,  0x7F,  0xFF,  0x04,  0x20, 	/* 49510 */
+	0x10,  0x04,  0x1E,  0x18,  0x24,  0xF0,  0x7F,  0x10,  0x29,  0xFF,  0x3F,  0x18,  0x29,  0x38,  0x29,  0x34, 	/* 49520 */
+	0x3F,  0x54,  0x15,  0x92,  0x2A,  0x91,  0x2A,  0x10,  0x40,  0x10,  0x8A,  0x02,  0x20,  0x02,  0x20,  0x7F, 	/* 49530 */
+	0xFF,  0x0A,  0x20,  0x08,  0x00,  0x10,  0xFC,  0x72,  0xA4,  0x0C,  0xB4,  0x08,  0xCC,  0x12,  0xFC,  0x7D, 	/* 49540 */
+	0x00,  0x08,  0xFE,  0x2C,  0xAA,  0x2A,  0xAA,  0x4B,  0xFF,  0x08,  0x00,  0x8B,  0x02,  0x10,  0x7F,  0xFF, 	/* 49550 */
+	0x02,  0x10,  0x04,  0x00,  0x14,  0xFF,  0x17,  0x08,  0x14,  0x10,  0x7F,  0xFE,  0x04,  0x42,  0x15,  0x7E, 	/* 49560 */
+	0x15,  0x42,  0x2E,  0x7E,  0x42,  0x42,  0x04,  0x7E,  0x08,  0x22,  0x30,  0xC1,  0x93,  0x02,  0x20,  0x7F, 	/* 49570 */
+	0xFF,  0x02,  0x20,  0x00,  0x20,  0x06,  0x3C,  0x38,  0x48,  0x08,  0x90,  0x09,  0xFE,  0x7E,  0x92,  0x08, 	/* 49580 */
+	0xFE,  0x1C,  0x92,  0x1A,  0x92,  0x2A,  0xFE,  0x49,  0x04,  0x09,  0x52,  0x0A,  0x29,  0x96,  0x02,  0x10, 	/* 49590 */
+	0x7F,  0xFF,  0x02,  0x10,  0x08,  0x08,  0x3F,  0x7F,  0x21,  0x22,  0x3F,  0x14,  0x20,  0x7F,  0x3F,  0x08, 	/* 495A0 */
+	0x21,  0x7E,  0x3F,  0x08,  0x00,  0x80,  0x7F,  0xFF,  0x02,  0xA0,  0x0C,  0x98,  0x70,  0x87,  0x97,  0x02, 	/* 495B0 */
+	0x10,  0x7F,  0xFF,  0x02,  0x10,  0x1F,  0x7E,  0x11,  0x24,  0x1F,  0x18,  0x10,  0xFF,  0x3F,  0x08,  0x51, 	/* 495C0 */
+	0x7E,  0x1F,  0x08,  0x00,  0x80,  0x7F,  0xFF,  0x02,  0xA0,  0x0C,  0x98,  0x70,  0x87,  0x00,  0x80,  0x9A, 	/* 495D0 */
+	0x04,  0x20,  0x7F,  0xFF,  0x04,  0x20,  0x10,  0x00,  0x1E,  0x22,  0x24,  0x14,  0x7F,  0x7F,  0x29,  0x08, 	/* 495E0 */
+	0x3F,  0x08,  0x29,  0x3E,  0x29,  0x08,  0x3F,  0x08,  0x01,  0x7F,  0x34,  0x88,  0x2A,  0x08,  0x40,  0x08, 	/* 495F0 */
+	0xA2,  0x04,  0x20,  0x7F,  0xFF,  0x04,  0x20,  0x04,  0x20,  0x3F,  0xBF,  0x11,  0x20,  0x7F,  0xFE,  0x00, 	/* 49600 */
+	0x02,  0x1F,  0x3E,  0x11,  0x20,  0x1F,  0x3E,  0x11,  0x20,  0x1F,  0x3E,  0x11,  0x20,  0x11,  0x21,  0x13, 	/* 49610 */
+	0x1F,  0xAD,  0x04,  0x20,  0x7F,  0xFF,  0x04,  0x20,  0x3E,  0x7E,  0x22,  0x42,  0x3E,  0x7E,  0x3E,  0x7E, 	/* 49620 */
+	0x20,  0x82,  0x2F,  0xFA,  0x24,  0x92,  0x27,  0xF2,  0x24,  0x92,  0x27,  0xF2,  0x22,  0xA2,  0x24,  0x92, 	/* 49630 */
+	0x20,  0x06,  0xAF,  0x02,  0x10,  0x7F,  0xFF,  0x02,  0x10,  0x18,  0xF8,  0x04,  0x88,  0x60,  0xF8,  0x10, 	/* 49640 */
+	0x88,  0x07,  0xFF,  0x10,  0x80,  0x21,  0xFE,  0x22,  0x52,  0x40,  0xA6,  0x1F,  0xFC,  0x12,  0x24,  0x7F, 	/* 49650 */
+	0xFF,  0x00,  0x00,  0xB0,  0x02,  0x20,  0x7F,  0xFF,  0x02,  0x20,  0x08,  0x7C,  0x08,  0x44,  0x32,  0x7C, 	/* 49660 */
+	0x14,  0x44,  0x08,  0xFE,  0x12,  0xAA,  0x7F,  0xFE,  0x09,  0x00,  0x2C,  0xFC,  0x2A,  0x24,  0x2A,  0x18, 	/* 49670 */
+	0x48,  0x64,  0x09,  0x83,  0xBF,  0x04,  0x20,  0x7F,  0xFF,  0x04,  0x20,  0x1F,  0xFC,  0x12,  0x44,  0x1F, 	/* 49680 */
+	0xFC,  0x08,  0x22,  0x32,  0x24,  0x14,  0x7F,  0x0A,  0xC8,  0x7F,  0x7E,  0x08,  0x48,  0x2A,  0x7E,  0x29, 	/* 49690 */
+	0x48,  0x49,  0x7F,  0x08,  0x00,  0x8D,  0x00,  0x80,  0x00,  0x80,  0x00,  0xFC,  0x00,  0x80,  0x00,  0x80, 	/* 496A0 */
+	0x1F,  0xFF,  0x10,  0x02,  0x10,  0x84,  0x10,  0x8E,  0x10,  0xF0,  0x1F,  0x80,  0x10,  0x80,  0x20,  0x80, 	/* 496B0 */
+	0x20,  0x81,  0x40,  0x41,  0x00,  0x3F,  0x8E,  0x00,  0x80,  0x00,  0xF8,  0x00,  0x80,  0x1F,  0xFE,  0x11, 	/* 496C0 */
+	0x04,  0x11,  0x18,  0x11,  0xE0,  0x1F,  0x00,  0x11,  0x04,  0x10,  0xFC,  0x11,  0x20,  0x11,  0x20,  0x21, 	/* 496D0 */
+	0x20,  0x22,  0x22,  0x44,  0x12,  0x18,  0x0E,  0x90,  0x00,  0x40,  0x00,  0x7E,  0x00,  0x40,  0x1F,  0xFE, 	/* 496E0 */
+	0x11,  0x04,  0x11,  0xF8,  0x1F,  0x02,  0x11,  0xFE,  0x10,  0x00,  0x17,  0xFC,  0x14,  0x00,  0x17,  0xFC, 	/* 496F0 */
+	0x24,  0x00,  0x24,  0x00,  0x47,  0xFE,  0x04,  0x00,  0x94,  0x00,  0x80,  0x00,  0xFC,  0x00,  0x80,  0x1F, 	/* 49700 */
+	0xFF,  0x11,  0x02,  0x11,  0xF8,  0x1F,  0x00,  0x11,  0x02,  0x10,  0xFE,  0x10,  0x40,  0x1F,  0xFF,  0x11, 	/* 49710 */
+	0x08,  0x20,  0x90,  0x20,  0x60,  0x41,  0x98,  0x1E,  0x07,  0x95,  0x00,  0x80,  0x00,  0xFC,  0x00,  0x80, 	/* 49720 */
+	0x1F,  0xFF,  0x10,  0x91,  0x10,  0xE2,  0x17,  0x88,  0x10,  0xF8,  0x14,  0x00,  0x17,  0xBC,  0x14,  0xA4, 	/* 49730 */
+	0x19,  0x24,  0x35,  0x25,  0x23,  0x47,  0x44,  0x80,  0x18,  0x7F,  0x9A,  0x00,  0x80,  0x00,  0xFE,  0x00, 	/* 49740 */
+	0x80,  0x1F,  0xFF,  0x11,  0x02,  0x11,  0x34,  0x1F,  0xC0,  0x11,  0x02,  0x10,  0xFE,  0x11,  0x20,  0x19, 	/* 49750 */
+	0x24,  0x15,  0x24,  0x25,  0x28,  0x21,  0x20,  0x5F,  0xFF,  0x00,  0x00,  0x9C,  0x00,  0x80,  0x00,  0xFE, 	/* 49760 */
+	0x00,  0x80,  0x1F,  0xFF,  0x10,  0x9A,  0x1F,  0xE0,  0x10,  0x82,  0x17,  0xFE,  0x14,  0x48,  0x17,  0xF8, 	/* 49770 */
+	0x14,  0x48,  0x17,  0xF8,  0x2F,  0xFE,  0x20,  0x82,  0x43,  0x02,  0x0C,  0x0C,  0x9E,  0x00,  0x80,  0x00, 	/* 49780 */
+	0xFC,  0x00,  0x80,  0x1F,  0xFF,  0x11,  0x1A,  0x1F,  0xE0,  0x11,  0x02,  0x10,  0xFE,  0x12,  0x84,  0x12, 	/* 49790 */
+	0xFC,  0x12,  0x00,  0x13,  0xF8,  0x20,  0x08,  0x2F,  0xFF,  0x43,  0x18,  0x1C,  0x06,  0x9F,  0x00,  0x08, 	/* 497A0 */
+	0x3E,  0x0E,  0x22,  0x08,  0x22,  0x7F,  0x22,  0x42,  0x3E,  0x48,  0x00,  0x4E,  0x7F,  0x78,  0x10,  0x49, 	/* 497B0 */
+	0x10,  0x47,  0x3E,  0x54,  0x22,  0x54,  0x02,  0x54,  0x02,  0x95,  0x04,  0xA5,  0x19,  0x43,  0xA7,  0x04, 	/* 497C0 */
+	0x00,  0x07,  0xBE,  0x04,  0x08,  0x3F,  0xC8,  0x25,  0x88,  0x3E,  0x7F,  0x23,  0xD0,  0x24,  0x90,  0x2F, 	/* 497D0 */
+	0xD0,  0x39,  0x1E,  0x2F,  0xC2,  0x29,  0x02,  0x2F,  0xC2,  0x29,  0x02,  0x4F,  0xC4,  0x00,  0x18,  0xAB, 	/* 497E0 */
+	0x01,  0x00,  0x01,  0x00,  0x01,  0x00,  0x1F,  0xF8,  0x11,  0x08,  0x11,  0x08,  0x11,  0x08,  0x11,  0x08, 	/* 497F0 */
+	0x1F,  0xF8,  0x01,  0x00,  0x01,  0x10,  0x01,  0x08,  0x01,  0x3C,  0x07,  0xC4,  0x78,  0x02,  0x00,  0x02, 	/* 49800 */
+	0xB1,  0x00,  0x00,  0x7F,  0xF8,  0x00,  0x28,  0x00,  0xC8,  0x3F,  0x08,  0x02,  0x08,  0x1F,  0xC8,  0x12, 	/* 49810 */
+	0x48,  0x12,  0x48,  0x12,  0x48,  0x1F,  0xC8,  0x02,  0x08,  0x02,  0x45,  0x03,  0xE5,  0x7C,  0x13,  0x00, 	/* 49820 */
+	0x01,  0xB9,  0x08,  0x00,  0x08,  0x00,  0x08,  0xFE,  0x3F,  0x10,  0x29,  0x10,  0x29,  0x10,  0x29,  0x10, 	/* 49830 */
+	0x29,  0x10,  0x3F,  0x10,  0x08,  0x10,  0x0A,  0x10,  0x09,  0x10,  0x09,  0x10,  0x0F,  0xFF,  0x70,  0x80, 	/* 49840 */
+	0x00,  0x80,  0xBB,  0x08,  0x08,  0x08,  0x08,  0x08,  0x08,  0x3F,  0x08,  0x29,  0xFF,  0x29,  0x20,  0x29, 	/* 49850 */
+	0x20,  0x29,  0x20,  0x3F,  0x20,  0x08,  0x20,  0x08,  0x20,  0x0A,  0x20,  0x09,  0x20,  0x0F,  0x20,  0x78, 	/* 49860 */
+	0x9E,  0x00,  0x80,  0x8A,  0x08,  0x10,  0x08,  0x10,  0x08,  0x10,  0x3F,  0xFF,  0x29,  0x44,  0x29,  0x44, 	/* 49870 */
+	0x29,  0x44,  0x29,  0x44,  0x3F,  0x28,  0x08,  0x28,  0x0C,  0x10,  0x0A,  0x10,  0x0A,  0x28,  0x0D,  0x48, 	/* 49880 */
+	0x70,  0x84,  0x01,  0x02,  0x8B,  0x08,  0x30,  0x08,  0x10,  0x08,  0x10,  0x08,  0xFE,  0x3E,  0x92,  0x2A, 	/* 49890 */
+	0x92,  0x2A,  0x92,  0x2A,  0xAA,  0x3E,  0xAA,  0x08,  0xA6,  0x08,  0xC2,  0x0C,  0x82,  0x0A,  0x82,  0x0E, 	/* 498A0 */
+	0x82,  0x71,  0x82,  0x00,  0x86,  0x8C,  0x08,  0x10,  0x08,  0x10,  0x08,  0x10,  0x08,  0x7E,  0x3F,  0x10, 	/* 498B0 */
+	0x29,  0x10,  0x29,  0x10,  0x29,  0x7E,  0x3F,  0x10,  0x08,  0x10,  0x0A,  0x10,  0x09,  0xFF,  0x09,  0x10, 	/* 498C0 */
+	0x0E,  0x90,  0x70,  0x90,  0x00,  0x90,  0x93,  0x08,  0x02,  0x08,  0xFA,  0x08,  0x0A,  0x08,  0x0A,  0x3F, 	/* 498D0 */
+	0x0A,  0x29,  0x7A,  0x29,  0x42,  0x29,  0x42,  0x3F,  0x42,  0x08,  0x7A,  0x08,  0x0A,  0x0A,  0x0A,  0x09, 	/* 498E0 */
+	0x0A,  0x0E,  0x8A,  0x70,  0x92,  0x00,  0x62,  0x95,  0x00,  0x00,  0x7F,  0xFE,  0x01,  0x00,  0x01,  0x00, 	/* 498F0 */
+	0x3F,  0xFC,  0x01,  0x80,  0x02,  0x40,  0x0D,  0x30,  0x71,  0x0E,  0x1F,  0xF0,  0x11,  0x10,  0x11,  0x10, 	/* 49900 */
+	0x1F,  0xF0,  0x01,  0x18,  0x01,  0xF4,  0x7E,  0x02,  0xA3,  0x08,  0x78,  0x08,  0x08,  0x08,  0x48,  0x08, 	/* 49910 */
+	0x48,  0x3F,  0x44,  0x29,  0x84,  0x29,  0xA2,  0x29,  0x21,  0x3F,  0x20,  0x08,  0x20,  0x0C,  0x28,  0x0A, 	/* 49920 */
+	0x44,  0x0A,  0x44,  0x0F,  0x4E,  0x71,  0xF2,  0x01,  0x02,  0xA4,  0x00,  0x00,  0x3F,  0xFC,  0x04,  0x88, 	/* 49930 */
+	0x22,  0x50,  0x11,  0x20,  0x10,  0xC0,  0x01,  0xA0,  0x06,  0x98,  0x78,  0x87,  0x0F,  0xF8,  0x08,  0x88, 	/* 49940 */
+	0x08,  0x88,  0x0F,  0xF8,  0x00,  0x8C,  0x00,  0xFA,  0x7F,  0x01,  0xA9,  0x00,  0x80,  0x20,  0x82,  0x20, 	/* 49950 */
+	0x82,  0x3F,  0xFE,  0x01,  0x00,  0x02,  0x00,  0x7F,  0xFF,  0x00,  0x80,  0x0F,  0xF8,  0x08,  0x88,  0x08, 	/* 49960 */
+	0x88,  0x0F,  0xF8,  0x00,  0x88,  0x00,  0x84,  0x00,  0xFA,  0x7F,  0x02,  0xAA,  0x08,  0x04,  0x08,  0x24, 	/* 49970 */
+	0x08,  0x14,  0x08,  0x14,  0x3F,  0x04,  0x29,  0x04,  0x29,  0x44,  0x29,  0x24,  0x3F,  0x24,  0x08,  0x07, 	/* 49980 */
+	0x0A,  0x1C,  0x09,  0x64,  0x09,  0x04,  0x0F,  0x84,  0x70,  0x84,  0x00,  0x84,  0xAB,  0x08,  0x20,  0x08, 	/* 49990 */
+	0x20,  0x08,  0x3E,  0x3F,  0x42,  0x29,  0x42,  0x29,  0xF2,  0x29,  0x52,  0x29,  0x52,  0x3F,  0x52,  0x08, 	/* 499A0 */
+	0x72,  0x0C,  0x44,  0x0A,  0x58,  0x0A,  0x40,  0x0F,  0x41,  0x71,  0x41,  0x00,  0x3F,  0xAF,  0x08,  0x02, 	/* 499B0 */
+	0x08,  0x0C,  0x08,  0x70,  0x08,  0x40,  0x3F,  0x40,  0x29,  0x40,  0x29,  0x7F,  0x29,  0x44,  0x3F,  0x44, 	/* 499C0 */
+	0x08,  0x44,  0x0C,  0x44,  0x0A,  0x44,  0x0A,  0x44,  0x0F,  0x44,  0x71,  0xFF,  0x01,  0x00,  0xB0,  0x08, 	/* 499D0 */
+	0x10,  0x08,  0x10,  0x08,  0x10,  0x08,  0x10,  0x3F,  0x7E,  0x29,  0x52,  0x29,  0x52,  0x29,  0x52,  0x3F, 	/* 499E0 */
+	0x52,  0x08,  0x7E,  0x0C,  0x52,  0x0A,  0x52,  0x0A,  0x52,  0x0F,  0x52,  0x71,  0x7E,  0x00,  0x00,  0xB6, 	/* 499F0 */
+	0x08,  0x44,  0x08,  0x44,  0x08,  0x44,  0x08,  0x44,  0x3F,  0xFF,  0x29,  0x44,  0x29,  0x44,  0x29,  0x44, 	/* 49A00 */
+	0x3F,  0x44,  0x08,  0x7C,  0x0A,  0x44,  0x09,  0x44,  0x09,  0x44,  0x0F,  0x44,  0x70,  0xFC,  0x00,  0x80, 	/* 49A10 */
+	0x84,  0x08,  0x10,  0x08,  0x10,  0x08,  0x10,  0x08,  0x10,  0x3F,  0xFF,  0x29,  0x10,  0x29,  0x10,  0x29, 	/* 49A20 */
+	0x10,  0x3F,  0x10,  0x08,  0x7E,  0x0C,  0x42,  0x0A,  0x42,  0x0A,  0x42,  0x0F,  0x42,  0x71,  0x7E,  0x00, 	/* 49A30 */
+	0x00,  0x86,  0x08,  0x00,  0x08,  0x7C,  0x08,  0x44,  0x08,  0x44,  0x3F,  0x44,  0x29,  0x7C,  0x29,  0x44, 	/* 49A40 */
+	0x29,  0x44,  0x3F,  0x44,  0x08,  0x44,  0x0C,  0x7C,  0x0A,  0x44,  0x0A,  0x44,  0x0F,  0x44,  0x71,  0xFF, 	/* 49A50 */
+	0x01,  0x00,  0x87,  0x04,  0x10,  0x04,  0x10,  0x04,  0x10,  0x3F,  0x7F,  0x25,  0x41,  0x25,  0x41,  0x25, 	/* 49A60 */
+	0x20,  0x25,  0x24,  0x3F,  0x24,  0x04,  0x28,  0x06,  0x30,  0x05,  0x20,  0x05,  0x20,  0x0F,  0xA1,  0x70, 	/* 49A70 */
+	0xA1,  0x00,  0x1F,  0x89,  0x08,  0x10,  0x08,  0x10,  0x08,  0x28,  0x08,  0x44,  0x3F,  0x82,  0x29,  0x7D, 	/* 49A80 */
+	0x29,  0x00,  0x29,  0x00,  0x3F,  0x7E,  0x08,  0x12,  0x0A,  0x12,  0x09,  0x12,  0x09,  0x12,  0x0F,  0x9C, 	/* 49A90 */
+	0x70,  0x90,  0x00,  0x90,  0x8B,  0x00,  0x00,  0x7F,  0xFF,  0x00,  0x82,  0x08,  0x80,  0x08,  0xFC,  0x0C, 	/* 49AA0 */
+	0x80,  0x13,  0x80,  0x20,  0xFF,  0x40,  0x80,  0x0F,  0xF8,  0x08,  0x88,  0x08,  0x88,  0x0F,  0xF8,  0x00, 	/* 49AB0 */
+	0x8C,  0x00,  0xFA,  0x7F,  0x01,  0x8D,  0x02,  0x08,  0x11,  0x08,  0x09,  0x10,  0x08,  0x20,  0x7F,  0xFE, 	/* 49AC0 */
+	0x41,  0x02,  0x41,  0x02,  0x1F,  0xF8,  0x11,  0x08,  0x11,  0x08,  0x11,  0x08,  0x1F,  0xF8,  0x01,  0x10, 	/* 49AD0 */
+	0x01,  0x0C,  0x01,  0xF2,  0x7E,  0x01,  0x8E,  0x08,  0x00,  0x08,  0xFF,  0x08,  0x80,  0x3E,  0x80,  0x2A, 	/* 49AE0 */
+	0xFF,  0x2A,  0x90,  0x2A,  0x90,  0x2A,  0x9E,  0x3E,  0x92,  0x08,  0x92,  0x0C,  0x92,  0x0A,  0x92,  0x0F, 	/* 49AF0 */
+	0x22,  0x19,  0x22,  0x62,  0x42,  0x04,  0x8C,  0x94,  0x08,  0x00,  0x08,  0x7E,  0x08,  0x42,  0x08,  0x42, 	/* 49B00 */
+	0x3F,  0x42,  0x29,  0x7A,  0x29,  0x6A,  0x29,  0x6A,  0x3F,  0x6A,  0x08,  0x6A,  0x0C,  0x7A,  0x0A,  0x42, 	/* 49B10 */
+	0x0A,  0x42,  0x0F,  0x42,  0x71,  0x7E,  0x01,  0x00,  0x99,  0x08,  0x10,  0x08,  0x10,  0x08,  0x7E,  0x3F, 	/* 49B20 */
+	0x10,  0x29,  0x10,  0x29,  0x10,  0x29,  0xFF,  0x29,  0x00,  0x3F,  0x10,  0x08,  0x10,  0x0C,  0xFE,  0x0A, 	/* 49B30 */
+	0x10,  0x0E,  0x10,  0x19,  0x10,  0x61,  0xFF,  0x00,  0x00,  0x9B,  0x08,  0x08,  0x08,  0x28,  0x08,  0x28, 	/* 49B40 */
+	0x08,  0x28,  0x3F,  0x7E,  0x29,  0x48,  0x29,  0x88,  0x29,  0x08,  0x3F,  0xFF,  0x08,  0x08,  0x0C,  0x1C, 	/* 49B50 */
+	0x0A,  0x1C,  0x0A,  0x2A,  0x0F,  0x49,  0x71,  0x88,  0x01,  0x08,  0x9E,  0x08,  0x02,  0x08,  0x0C,  0x08, 	/* 49B60 */
+	0x70,  0x08,  0x10,  0x3F,  0x10,  0x29,  0xFF,  0x29,  0x10,  0x29,  0x10,  0x3F,  0x10,  0x08,  0x7E,  0x0C, 	/* 49B70 */
+	0x42,  0x0A,  0x42,  0x0A,  0x42,  0x0F,  0x42,  0x71,  0x7E,  0x01,  0x00,  0x9F,  0x08,  0x10,  0x08,  0x10, 	/* 49B80 */
+	0x08,  0x10,  0x09,  0xFF,  0x3F,  0x24,  0x29,  0x22,  0x29,  0x42,  0x29,  0xA5,  0x3F,  0x24,  0x08,  0x14, 	/* 49B90 */
+	0x0C,  0x18,  0x0A,  0x08,  0x0A,  0x14,  0x0F,  0x24,  0x71,  0x42,  0x01,  0x81,  0xA4,  0x08,  0x10,  0x08, 	/* 49BA0 */
+	0x10,  0x08,  0x28,  0x3F,  0x28,  0x29,  0x24,  0x29,  0x42,  0x29,  0x7D,  0x29,  0x80,  0x3F,  0x00,  0x08, 	/* 49BB0 */
+	0x7C,  0x0C,  0x44,  0x0A,  0x44,  0x0A,  0x44,  0x0F,  0x44,  0x71,  0x7C,  0x00,  0x00,  0xA9,  0x00,  0x00, 	/* 49BC0 */
+	0x7E,  0xF8,  0x08,  0x88,  0x08,  0xC8,  0x08,  0xA8,  0x0E,  0xA9,  0x19,  0x09,  0x62,  0x87,  0x00,  0x80, 	/* 49BD0 */
+	0x0F,  0xF8,  0x08,  0x88,  0x08,  0x88,  0x0F,  0xF8,  0x00,  0x84,  0x00,  0xFA,  0x7F,  0x02,  0xAC,  0x02, 	/* 49BE0 */
+	0x10,  0x02,  0x10,  0x3F,  0xFE,  0x02,  0x10,  0x02,  0x10,  0x7F,  0xFF,  0x04,  0x10,  0x08,  0x88,  0x1F, 	/* 49BF0 */
+	0xFC,  0x68,  0x8B,  0x08,  0x88,  0x0F,  0xF8,  0x00,  0x90,  0x00,  0x88,  0x00,  0xF4,  0x3F,  0x02,  0xAD, 	/* 49C00 */
+	0x08,  0x00,  0x09,  0xFF,  0x08,  0x10,  0x08,  0x10,  0x3F,  0x2C,  0x29,  0x46,  0x29,  0xF9,  0x29,  0x00, 	/* 49C10 */
+	0x3F,  0x10,  0x08,  0x10,  0x0A,  0x7E,  0x09,  0x10,  0x0B,  0x10,  0x1C,  0x90,  0x60,  0xFF,  0x00,  0x80, 	/* 49C20 */
+	0xAE,  0x00,  0x80,  0x00,  0x80,  0x7F,  0xFF,  0x02,  0x20,  0x12,  0x28,  0x12,  0x24,  0x24,  0xA2,  0x48, 	/* 49C30 */
+	0x82,  0x1F,  0xF8,  0x10,  0x88,  0x10,  0x88,  0x1F,  0xF8,  0x00,  0x88,  0x00,  0x84,  0x01,  0xFE,  0x7E, 	/* 49C40 */
+	0x02,  0xAF,  0x08,  0x22,  0x08,  0x22,  0x08,  0xFE,  0x08,  0x24,  0x3F,  0x24,  0x29,  0x28,  0x29,  0xFF, 	/* 49C50 */
+	0x29,  0x10,  0x3F,  0x20,  0x08,  0x64,  0x0C,  0xA8,  0x0B,  0x30,  0x0A,  0x20,  0x0F,  0x22,  0x71,  0x22, 	/* 49C60 */
+	0x00,  0x1E,  0xB8,  0x08,  0x10,  0x08,  0x92,  0x08,  0x52,  0x08,  0x54,  0x3F,  0x10,  0x29,  0x7E,  0x29, 	/* 49C70 */
+	0x42,  0x29,  0x42,  0x3F,  0x7E,  0x28,  0x42,  0x0C,  0x42,  0x0A,  0x7E,  0x09,  0x42,  0x0F,  0x42,  0x71, 	/* 49C80 */
+	0x42,  0x00,  0x46,  0xB9,  0x08,  0x00,  0x09,  0xFE,  0x08,  0x44,  0x08,  0x28,  0x3F,  0x10,  0x29,  0xFE, 	/* 49C90 */
+	0x29,  0x92,  0x29,  0x92,  0x3F,  0xFE,  0x08,  0x92,  0x0C,  0x92,  0x0A,  0xFE,  0x0A,  0x92,  0x0F,  0x92, 	/* 49CA0 */
+	0x71,  0x92,  0x00,  0x96,  0xBB,  0x08,  0x58,  0x08,  0x48,  0x08,  0x44,  0x08,  0x84,  0x3E,  0xFE,  0x2B, 	/* 49CB0 */
+	0x85,  0x2A,  0x84,  0x2A,  0x84,  0x3E,  0xFC,  0x08,  0x28,  0x0C,  0x28,  0x0A,  0x28,  0x0A,  0x48,  0x0F, 	/* 49CC0 */
+	0x49,  0x71,  0x89,  0x01,  0x07,  0xBE,  0x08,  0x28,  0x08,  0x48,  0x09,  0xCC,  0x3E,  0x4A,  0x2A,  0x4A, 	/* 49CD0 */
+	0x2B,  0xFF,  0x2A,  0x48,  0x2A,  0x4A,  0x3E,  0x4A,  0x08,  0x64,  0x0D,  0xC4,  0x0A,  0x4C,  0x0A,  0x4D, 	/* 49CE0 */
+	0x1F,  0x53,  0x61,  0x63,  0x00,  0xC1,  0x80,  0x00,  0x00,  0x3F,  0xFE,  0x22,  0x22,  0x22,  0x22,  0x3F, 	/* 49CF0 */
+	0xFE,  0x08,  0x00,  0x0F,  0xFE,  0x11,  0x02,  0x2F,  0xE2,  0x49,  0x22,  0x09,  0x22,  0x0F,  0xE2,  0x01, 	/* 49D00 */
+	0x12,  0x01,  0xEA,  0x3F,  0x04,  0x00,  0x18,  0x82,  0x08,  0x20,  0x08,  0x3C,  0x08,  0x44,  0x3E,  0xA8, 	/* 49D10 */
+	0x2B,  0x10,  0x2A,  0x28,  0x2A,  0xD4,  0x2B,  0x13,  0x3F,  0xFE,  0x08,  0x10,  0x0C,  0xFC,  0x0A,  0x10, 	/* 49D20 */
+	0x0B,  0xFF,  0x0E,  0x10,  0x71,  0x10,  0x01,  0x10,  0x83,  0x00,  0x00,  0x1F,  0xFE,  0x10,  0x00,  0x17, 	/* 49D30 */
+	0xFC,  0x10,  0x00,  0x1F,  0xFF,  0x12,  0x44,  0x23,  0xA8,  0x2E,  0x18,  0x40,  0x87,  0x0F,  0xF8,  0x08, 	/* 49D40 */
+	0x88,  0x0F,  0xF8,  0x00,  0x8C,  0x00,  0xFA,  0x3F,  0x81,  0x86,  0x08,  0x00,  0x08,  0x7E,  0x08,  0x42, 	/* 49D50 */
+	0x08,  0x42,  0x3F,  0x7E,  0x29,  0x42,  0x29,  0x42,  0x29,  0x7E,  0x3F,  0x42,  0x08,  0x42,  0x0C,  0x7E, 	/* 49D60 */
+	0x0A,  0x18,  0x0A,  0x28,  0x0F,  0x29,  0x71,  0x49,  0x00,  0x87,  0x88,  0x08,  0x00,  0x08,  0x5E,  0x08, 	/* 49D70 */
+	0x52,  0x08,  0x52,  0x3F,  0x52,  0x29,  0x5E,  0x29,  0x40,  0x29,  0x40,  0x3F,  0x7E,  0x08,  0x02,  0x0C, 	/* 49D80 */
+	0x12,  0x0A,  0xFF,  0x0A,  0x10,  0x0F,  0x28,  0x71,  0x44,  0x00,  0x83,  0x89,  0x08,  0x04,  0x08,  0x18, 	/* 49D90 */
+	0x08,  0xE4,  0x08,  0x52,  0x3F,  0x49,  0x29,  0x89,  0x29,  0x00,  0x29,  0x7C,  0x3F,  0x04,  0x08,  0x08, 	/* 49DA0 */
+	0x0C,  0x10,  0x0B,  0xFF,  0x0A,  0x10,  0x0D,  0x10,  0x71,  0x10,  0x00,  0x30,  0x8A,  0x08,  0x12,  0x08, 	/* 49DB0 */
+	0x62,  0x09,  0xCA,  0x08,  0x4A,  0x3E,  0x4A,  0x2B,  0xFA,  0x2A,  0x4A,  0x2A,  0x4A,  0x3E,  0xEA,  0x08, 	/* 49DC0 */
+	0xDA,  0x0D,  0x4A,  0x0D,  0x4A,  0x0A,  0x42,  0x0E,  0x42,  0x72,  0x42,  0x00,  0x46,  0x8D,  0x08,  0x10, 	/* 49DD0 */
+	0x08,  0x10,  0x08,  0x28,  0x08,  0x28,  0x3F,  0x44,  0x29,  0x82,  0x29,  0x7D,  0x29,  0x10,  0x3F,  0x10, 	/* 49DE0 */
+	0x09,  0xFF,  0x0C,  0x10,  0x0A,  0x54,  0x0A,  0x54,  0x0F,  0x92,  0x71,  0x12,  0x00,  0x30,  0x91,  0x00, 	/* 49DF0 */
+	0x02,  0x7D,  0xFC,  0x08,  0x10,  0x10,  0x9E,  0x3C,  0x90,  0x04,  0x90,  0x15,  0xFE,  0x0E,  0x00,  0x11, 	/* 49E00 */
+	0xFF,  0x60,  0x80,  0x0F,  0xF8,  0x08,  0x88,  0x0F,  0xF8,  0x00,  0x84,  0x00,  0xFE,  0x7F,  0x01,  0x92, 	/* 49E10 */
+	0x08,  0x01,  0x0B,  0xC6,  0x08,  0x5C,  0x3E,  0x44,  0x2A,  0x84,  0x2A,  0x94,  0x2B,  0xD7,  0x2A,  0x54, 	/* 49E20 */
+	0x3E,  0x54,  0x09,  0x54,  0x0D,  0x54,  0x0A,  0x94,  0x0A,  0x9F,  0x0E,  0xC0,  0x71,  0x30,  0x02,  0x0F, 	/* 49E30 */
+	0x98,  0x11,  0x00,  0x11,  0x00,  0x11,  0x1E,  0x13,  0xF2,  0x7C,  0x92,  0x54,  0x92,  0x54,  0x92,  0x57, 	/* 49E40 */
+	0xF2,  0x7C,  0x92,  0x10,  0x92,  0x18,  0x92,  0x15,  0x52,  0x15,  0x5E,  0x1A,  0x20,  0x64,  0x20,  0x08, 	/* 49E50 */
+	0x00,  0x9A,  0x02,  0x20,  0x7E,  0x3F,  0x02,  0x20,  0x3E,  0x3E,  0x03,  0x20,  0x0E,  0x3F,  0x74,  0x20, 	/* 49E60 */
+	0x08,  0xA0,  0x10,  0x80,  0x0F,  0xF8,  0x08,  0x88,  0x08,  0x88,  0x0F,  0xF8,  0x00,  0x84,  0x00,  0xFA, 	/* 49E70 */
+	0x7F,  0x01,  0x9C,  0x01,  0x00,  0x01,  0x00,  0x7F,  0xFE,  0x41,  0x02,  0x44,  0xA2,  0x24,  0x48,  0x25, 	/* 49E80 */
+	0x94,  0x46,  0x12,  0x1B,  0xF2,  0x61,  0x00,  0x1F,  0xF0,  0x11,  0x10,  0x1F,  0xF0,  0x01,  0x18,  0x01, 	/* 49E90 */
+	0xF4,  0x7E,  0x02,  0xA5,  0x08,  0x42,  0x08,  0x4C,  0x08,  0x48,  0x08,  0x48,  0x3F,  0xF8,  0x2A,  0x4F, 	/* 49EA0 */
+	0x2A,  0xCA,  0x2A,  0xEA,  0x3E,  0xDA,  0x09,  0x4A,  0x0D,  0x4A,  0x0A,  0x4A,  0x0A,  0x52,  0x0F,  0x52, 	/* 49EB0 */
+	0x71,  0x62,  0x00,  0x42,  0xA9,  0x08,  0x00,  0x08,  0xFE,  0x08,  0x82,  0x08,  0x92,  0x3E,  0xFE,  0x2A, 	/* 49EC0 */
+	0x92,  0x2A,  0x92,  0x2A,  0xFE,  0x3E,  0x92,  0x08,  0xBA,  0x0C,  0xAA,  0x0A,  0xAA,  0x0A,  0xBA,  0x0F, 	/* 49ED0 */
+	0x02,  0x71,  0x02,  0x02,  0x06,  0xB4,  0x08,  0x00,  0x08,  0x7C,  0x08,  0x44,  0x3F,  0x44,  0x29,  0x7C, 	/* 49EE0 */
+	0x29,  0x44,  0x29,  0x44,  0x29,  0x7C,  0x3F,  0x20,  0x08,  0x7E,  0x0C,  0xAA,  0x0A,  0x2A,  0x0A,  0x52, 	/* 49EF0 */
+	0x0F,  0x92,  0x79,  0x22,  0x00,  0x4C,  0xB7,  0x08,  0x54,  0x08,  0x52,  0x08,  0x92,  0x09,  0x7E,  0x3E, 	/* 49F00 */
+	0x10,  0x2A,  0x28,  0x2A,  0xFF,  0x2A,  0x28,  0x3E,  0x44,  0x08,  0xFA,  0x0D,  0x49,  0x0A,  0x48,  0x0A, 	/* 49F10 */
+	0x78,  0x0F,  0x42,  0x71,  0x42,  0x00,  0x3E,  0xBB,  0x08,  0x10,  0x08,  0x10,  0x08,  0xFF,  0x08,  0x10, 	/* 49F20 */
+	0x3F,  0x7E,  0x29,  0x10,  0x29,  0xFF,  0x29,  0x00,  0x3F,  0x7E,  0x08,  0x52,  0x0C,  0x52,  0x0A,  0x7E, 	/* 49F30 */
+	0x0A,  0x42,  0x0F,  0x42,  0x71,  0x42,  0x00,  0x46,  0xBF,  0x08,  0x10,  0x08,  0x10,  0x09,  0xFF,  0x09, 	/* 49F40 */
+	0x01,  0x3F,  0x41,  0x2A,  0x40,  0x2A,  0x6E,  0x2A,  0xAA,  0x3E,  0xAA,  0x08,  0xAA,  0x0D,  0x6A,  0x0A, 	/* 49F50 */
+	0x4E,  0x0A,  0x48,  0x0D,  0x49,  0x71,  0x89,  0x01,  0x07,  0x89,  0x08,  0x22,  0x08,  0x92,  0x08,  0x54, 	/* 49F60 */
+	0x08,  0x7E,  0x3F,  0x52,  0x29,  0x52,  0x29,  0x7E,  0x29,  0x52,  0x3F,  0x52,  0x08,  0x7E,  0x0C,  0x10, 	/* 49F70 */
+	0x0A,  0x10,  0x09,  0xFF,  0x0F,  0x10,  0x70,  0x90,  0x00,  0x10,  0x8B,  0x08,  0x42,  0x09,  0x22,  0x08, 	/* 49F80 */
+	0xA4,  0x08,  0x88,  0x3E,  0xFC,  0x2A,  0xA4,  0x2A,  0xA4,  0x2A,  0xFC,  0x3E,  0xA4,  0x08,  0xA4,  0x0C, 	/* 49F90 */
+	0xFC,  0x0A,  0xA4,  0x0A,  0xA4,  0x0D,  0x25,  0x71,  0x25,  0x02,  0x23,  0x8C,  0x08,  0x22,  0x08,  0x42, 	/* 49FA0 */
+	0x09,  0xD2,  0x08,  0x4A,  0x3E,  0x4A,  0x2B,  0xE2,  0x2A,  0x52,  0x2A,  0x4A,  0x3E,  0xEA,  0x08,  0xD3, 	/* 49FB0 */
+	0x0D,  0x46,  0x0A,  0x5A,  0x0A,  0x42,  0x0F,  0x42,  0x71,  0x42,  0x00,  0x42,  0x8E,  0x08,  0x00,  0x08, 	/* 49FC0 */
+	0x7C,  0x08,  0x44,  0x08,  0x7C,  0x3F,  0x44,  0x29,  0x44,  0x29,  0x7C,  0x29,  0x20,  0x3F,  0x7E,  0x08, 	/* 49FD0 */
+	0xD2,  0x0D,  0x52,  0x0A,  0x5A,  0x0A,  0x66,  0x0F,  0x7A,  0x71,  0x02,  0x00,  0x0C,  0x93,  0x08,  0x70, 	/* 49FE0 */
+	0x08,  0x10,  0x08,  0x28,  0x08,  0x44,  0x3E,  0xFA,  0x2B,  0x01,  0x2A,  0xEA,  0x2A,  0xAA,  0x3E,  0xAA, 	/* 49FF0 */
+	0x08,  0xF4,  0x0C,  0xB4,  0x0A,  0xB4,  0x0A,  0xEA,  0x0F,  0xAA,  0x71,  0xAA,  0x00,  0xAA,  0x95,  0x08, 	/* 4A000 */
+	0x10,  0x08,  0x10,  0x14,  0x10,  0x12,  0xFE,  0x29,  0x92,  0x7E,  0x92,  0x22,  0x92,  0x3E,  0x92,  0x22, 	/* 4A010 */
+	0xFE,  0x22,  0x10,  0x3E,  0x18,  0x28,  0x14,  0x24,  0x12,  0x2E,  0x1E,  0x32,  0x71,  0x61,  0x81,  0x97, 	/* 4A020 */
+	0x08,  0x10,  0x08,  0x20,  0x08,  0x7C,  0x08,  0x44,  0x3F,  0x7C,  0x29,  0x44,  0x29,  0x44,  0x29,  0x7C, 	/* 4A030 */
+	0x3F,  0x00,  0x08,  0xFF,  0x0C,  0x10,  0x0A,  0x7E,  0x0A,  0x10,  0x0F,  0x10,  0x71,  0xFF,  0x00,  0x00, 	/* 4A040 */
+	0x99,  0x08,  0x00,  0x09,  0xFF,  0x08,  0x00,  0x3E,  0xFC,  0x2A,  0x84,  0x2A,  0x84,  0x2A,  0xFC,  0x2A, 	/* 4A050 */
+	0x80,  0x3E,  0xFE,  0x08,  0xAA,  0x09,  0xAA,  0x0D,  0xFE,  0x0A,  0xAA,  0x0E,  0xAA,  0x72,  0xAA,  0x00, 	/* 4A060 */
+	0x86,  0x9F,  0x08,  0x00,  0x08,  0xFF,  0x08,  0x91,  0x08,  0xFF,  0x3F,  0x91,  0x29,  0x91,  0x29,  0xFF, 	/* 4A070 */
+	0x29,  0x00,  0x3F,  0x7E,  0x08,  0x42,  0x0C,  0x7E,  0x0A,  0x42,  0x0A,  0x7E,  0x0F,  0x42,  0x71,  0x42, 	/* 4A080 */
+	0x00,  0x46,  0xA0,  0x08,  0x00,  0x09,  0xFF,  0x08,  0x00,  0x08,  0x7C,  0x3F,  0x44,  0x29,  0x7C,  0x29, 	/* 4A090 */
+	0x00,  0x29,  0x00,  0x3F,  0xFE,  0x08,  0x92,  0x0C,  0x92,  0x0A,  0xFE,  0x0A,  0x92,  0x0F,  0x92,  0x71, 	/* 4A0A0 */
+	0xFE,  0x01,  0x00,  0xA3,  0x08,  0x88,  0x08,  0x88,  0x08,  0x88,  0x0B,  0xEF,  0x3E,  0x90,  0x2A,  0xA0, 	/* 4A0B0 */
+	0x2A,  0x9F,  0x2A,  0xE2,  0x3E,  0xA4,  0x08,  0xA4,  0x0C,  0xBF,  0x0A,  0xA4,  0x0B,  0x24,  0x0D,  0x24, 	/* 4A0C0 */
+	0x72,  0x24,  0x00,  0xCC,  0xA6,  0x08,  0x00,  0x08,  0xEE,  0x08,  0xA2,  0x08,  0xA2,  0x3E,  0xA2,  0x2A, 	/* 4A0D0 */
+	0xEE,  0x2A,  0x80,  0x2A,  0x9E,  0x3E,  0xEA,  0x08,  0x8A,  0x08,  0x8A,  0x0C,  0xE4,  0x0A,  0x84,  0x0E, 	/* 4A0E0 */
+	0x8A,  0x72,  0x92,  0x01,  0xA1,  0xA8,  0x00,  0x00,  0x7F,  0xF8,  0x02,  0x08,  0x02,  0x08,  0x7F,  0xE5, 	/* 4A0F0 */
+	0x04,  0x05,  0x18,  0x03,  0x60,  0x11,  0x08,  0x10,  0x3E,  0x7C,  0x2A,  0x54,  0x2A,  0x54,  0x3E,  0x7C, 	/* 4A100 */
+	0x0A,  0x14,  0x0D,  0x1A,  0x70,  0xE1,  0xAA,  0x08,  0x00,  0x08,  0xFC,  0x08,  0x84,  0x3E,  0xFC,  0x2A, 	/* 4A110 */
+	0x84,  0x2A,  0x84,  0x2A,  0xFC,  0x2A,  0x00,  0x3F,  0xFF,  0x08,  0x40,  0x08,  0xFE,  0x0D,  0x2A,  0x0A, 	/* 4A120 */
+	0x4A,  0x0D,  0x92,  0x71,  0x22,  0x00,  0x4C,  0xAE,  0x08,  0x40,  0x08,  0x40,  0x08,  0x7F,  0x08,  0x80, 	/* 4A130 */
+	0x3F,  0x7C,  0x29,  0x44,  0x29,  0x7C,  0x29,  0x44,  0x3F,  0x7C,  0x08,  0x20,  0x0C,  0x7C,  0x0A,  0xC4, 	/* 4A140 */
+	0x0B,  0x28,  0x0D,  0x18,  0x71,  0x64,  0x01,  0x83,  0xB4,  0x08,  0x40,  0x08,  0x4E,  0x08,  0x4A,  0x08, 	/* 4A150 */
+	0x4A,  0x3F,  0xFA,  0x2A,  0x4E,  0x2A,  0x4A,  0x2A,  0x4A,  0x3E,  0xEA,  0x08,  0xAE,  0x08,  0xAA,  0x0C, 	/* 4A160 */
+	0xAA,  0x0A,  0xEA,  0x1E,  0x12,  0x71,  0x12,  0x01,  0x26,  0xB6,  0x08,  0x54,  0x08,  0x54,  0x09,  0xFF, 	/* 4A170 */
+	0x3E,  0x54,  0x2A,  0x54,  0x2A,  0x5C,  0x2A,  0x40,  0x2A,  0x7E,  0x3E,  0x10,  0x09,  0xFF,  0x0C,  0x18, 	/* 4A180 */
+	0x0A,  0x34,  0x0A,  0x52,  0x0F,  0x91,  0x71,  0x10,  0x01,  0x10,  0xB8,  0x08,  0x00,  0x08,  0x7C,  0x08, 	/* 4A190 */
+	0x44,  0x08,  0x5C,  0x3F,  0x54,  0x29,  0x54,  0x29,  0x54,  0x29,  0xFE,  0x3F,  0x82,  0x08,  0xBA,  0x0C, 	/* 4A1A0 */
+	0xAA,  0x0A,  0xAA,  0x0A,  0xBA,  0x0F,  0x82,  0x71,  0x82,  0x00,  0x86,  0xBF,  0x08,  0x00,  0x08,  0xFE, 	/* 4A1B0 */
+	0x08,  0x92,  0x08,  0xFE,  0x3E,  0x92,  0x2A,  0x92,  0x2A,  0xFE,  0x2A,  0x10,  0x3E,  0xFE,  0x08,  0x92, 	/* 4A1C0 */
+	0x0C,  0xFE,  0x0A,  0x92,  0x0A,  0x92,  0x0F,  0xFE,  0x71,  0x11,  0x01,  0x0F,  0x82,  0x08,  0x40,  0x08, 	/* 4A1D0 */
+	0x4E,  0x08,  0xEA,  0x08,  0xAA,  0x3E,  0xAA,  0x2A,  0xEC,  0x2A,  0xAC,  0x2A,  0xAA,  0x3E,  0xEA,  0x08, 	/* 4A1E0 */
+	0x9A,  0x0C,  0xDA,  0x0C,  0xAA,  0x0A,  0xAE,  0x0E,  0xD8,  0x73,  0x18,  0x00,  0x08,  0x8D,  0x00,  0x10, 	/* 4A1F0 */
+	0x7F,  0x10,  0x00,  0x10,  0x3E,  0x7E,  0x22,  0x52,  0x3E,  0x52,  0x00,  0x52,  0x7F,  0x52,  0x55,  0x7E, 	/* 4A200 */
+	0x55,  0x10,  0x63,  0x10,  0x5D,  0x14,  0x49,  0x12,  0x49,  0x1E,  0x49,  0xE1,  0x4B,  0x01,  0x9F,  0x08, 	/* 4A210 */
+	0x00,  0x09,  0xFF,  0x09,  0x01,  0x08,  0x7D,  0x3F,  0x44,  0x29,  0x44,  0x29,  0x7C,  0x29,  0x44,  0x3F, 	/* 4A220 */
+	0x44,  0x08,  0x7C,  0x0C,  0x10,  0x0B,  0xFF,  0x0A,  0x00,  0x0D,  0x44,  0x71,  0x42,  0x00,  0x82,  0xA2, 	/* 4A230 */
+	0x08,  0x10,  0x2A,  0x54,  0x2A,  0x54,  0x54,  0xA8,  0x22,  0x44,  0x40,  0x80,  0x7F,  0xFE,  0x40,  0x02, 	/* 4A240 */
+	0x41,  0x02,  0x1F,  0xF8,  0x11,  0x08,  0x11,  0x08,  0x1F,  0xF8,  0x01,  0x08,  0x01,  0xFC,  0x7F,  0x02, 	/* 4A250 */
+	0xAB,  0x04,  0x10,  0x3F,  0x90,  0x04,  0x1F,  0x7F,  0xA2,  0x0A,  0x22,  0x2B,  0x54,  0x4A,  0x88,  0x12, 	/* 4A260 */
+	0x14,  0x26,  0x63,  0x00,  0x80,  0x0F,  0xF8,  0x08,  0x88,  0x0F,  0xF8,  0x00,  0x84,  0x00,  0xFE,  0x7F, 	/* 4A270 */
+	0x01,  0xAF,  0x04,  0x10,  0x04,  0x10,  0x3F,  0xBF,  0x04,  0x24,  0x7F,  0xD4,  0x04,  0x14,  0x0F,  0x88, 	/* 4A280 */
+	0x10,  0x94,  0x23,  0x62,  0x00,  0x81,  0x0F,  0xF8,  0x08,  0x88,  0x0F,  0xF8,  0x00,  0x84,  0x00,  0xFE, 	/* 4A290 */
+	0x7F,  0x01,  0xB3,  0x08,  0x92,  0x08,  0x52,  0x08,  0x54,  0x09,  0xFF,  0x3F,  0x01,  0x2B,  0x7D,  0x2A, 	/* 4A2A0 */
+	0x44,  0x2A,  0x44,  0x3E,  0x7C,  0x08,  0x10,  0x0C,  0x10,  0x0A,  0xFE,  0x0A,  0x10,  0x0F,  0x10,  0x71, 	/* 4A2B0 */
+	0xFF,  0x00,  0x00,  0xBA,  0x08,  0x00,  0x08,  0xFE,  0x08,  0x92,  0x3E,  0xFE,  0x2A,  0x92,  0x2A,  0xFE, 	/* 4A2C0 */
+	0x2A,  0x10,  0x2A,  0x24,  0x3E,  0xE8,  0x08,  0x18,  0x0C,  0x26,  0x0B,  0xFD,  0x0A,  0x94,  0x0E,  0x92, 	/* 4A2D0 */
+	0x71,  0x12,  0x00,  0x10,  0xBB,  0x08,  0x10,  0x08,  0x7E,  0x08,  0x52,  0x08,  0xFF,  0x3F,  0x52,  0x29, 	/* 4A2E0 */
+	0x7E,  0x29,  0x10,  0x29,  0x7E,  0x3F,  0x52,  0x08,  0x7E,  0x0C,  0x10,  0x0A,  0xFF,  0x0A,  0x24,  0x0F, 	/* 4A2F0 */
+	0x68,  0x71,  0x1C,  0x00,  0xE2,  0xBD,  0x00,  0x80,  0x01,  0xF8,  0x07,  0x10,  0x38,  0xA0,  0x01,  0xC0, 	/* 4A300 */
+	0x07,  0x38,  0x78,  0xC7,  0x00,  0x20,  0x0B,  0xD0,  0x08,  0x30,  0x3E,  0x7C,  0x2A,  0x54,  0x3E,  0x7C, 	/* 4A310 */
+	0x0A,  0x14,  0x0F,  0x1E,  0x70,  0xE1,  0x80,  0x08,  0x08,  0x08,  0x08,  0x08,  0xFF,  0x08,  0x08,  0x3F, 	/* 4A320 */
+	0x52,  0x29,  0xB5,  0x29,  0x0C,  0x29,  0x4A,  0x3F,  0x95,  0x08,  0x7E,  0x0C,  0x08,  0x0A,  0xFF,  0x09, 	/* 4A330 */
+	0x08,  0x0F,  0x08,  0x70,  0x88,  0x00,  0x08,  0x84,  0x04,  0x10,  0x3F,  0x10,  0x04,  0x7C,  0x7F,  0x94, 	/* 4A340 */
+	0x11,  0x74,  0x7F,  0xA4,  0x04,  0x54,  0x3F,  0x95,  0x04,  0x83,  0x00,  0x80,  0x1F,  0xF8,  0x10,  0x88, 	/* 4A350 */
+	0x1F,  0xF8,  0x00,  0x84,  0x00,  0xFE,  0x7F,  0x01,  0x86,  0x08,  0x24,  0x08,  0x24,  0x09,  0xFF,  0x08, 	/* 4A360 */
+	0x24,  0x3F,  0x24,  0x29,  0x7E,  0x29,  0x42,  0x29,  0x7E,  0x3F,  0x42,  0x08,  0x7E,  0x0C,  0x10,  0x0B, 	/* 4A370 */
+	0xFF,  0x0A,  0x18,  0x0F,  0x24,  0x71,  0x42,  0x01,  0x81,  0x87,  0x02,  0x20,  0x7F,  0xFF,  0x02,  0x20, 	/* 4A380 */
+	0x0F,  0xF8,  0x08,  0x08,  0x0F,  0xF8,  0x08,  0x08,  0x0F,  0xF8,  0x01,  0x00,  0x7F,  0xFF,  0x04,  0x90, 	/* 4A390 */
+	0x1F,  0xFC,  0x64,  0x93,  0x07,  0xF0,  0x00,  0x8C,  0x3F,  0xF2,  0x8B,  0x08,  0x02,  0x08,  0x7C,  0x08, 	/* 4A3A0 */
+	0x92,  0x08,  0x54,  0x3F,  0xFF,  0x29,  0x38,  0x29,  0x54,  0x29,  0x92,  0x3F,  0x11,  0x08,  0x20,  0x0C, 	/* 4A3B0 */
+	0x10,  0x0A,  0xAA,  0x0A,  0xA9,  0x0E,  0xA1,  0x71,  0x25,  0x00,  0x1C,  0x90,  0x08,  0x92,  0x08,  0x52, 	/* 4A3C0 */
+	0x08,  0x54,  0x09,  0xFF,  0x3F,  0x01,  0x2B,  0x7D,  0x2A,  0x44,  0x2A,  0x44,  0x3E,  0x7C,  0x08,  0x10, 	/* 4A3D0 */
+	0x0C,  0xFE,  0x0A,  0x92,  0x0A,  0x92,  0x0F,  0x9C,  0x71,  0x10,  0x00,  0x10,  0x92,  0x08,  0x24,  0x08, 	/* 4A3E0 */
+	0x24,  0x09,  0xFF,  0x08,  0x24,  0x3E,  0x10,  0x2A,  0xFF,  0x2A,  0x18,  0x2A,  0x24,  0x3E,  0xC3,  0x08, 	/* 4A3F0 */
+	0x24,  0x0C,  0x24,  0x0B,  0xFF,  0x0A,  0x24,  0x0D,  0x24,  0x71,  0x44,  0x00,  0x84,  0xA0,  0x08,  0x02, 	/* 4A400 */
+	0x08,  0x0C,  0x09,  0xF0,  0x08,  0x92,  0x3E,  0x54,  0x2A,  0xFF,  0x2A,  0x34,  0x2A,  0x52,  0x3E,  0x91, 	/* 4A410 */
+	0x09,  0xFE,  0x0C,  0x92,  0x0A,  0xFE,  0x0A,  0x92,  0x0F,  0x92,  0x71,  0xFE,  0x00,  0x80,  0xAF,  0x08, 	/* 4A420 */
+	0x10,  0x08,  0x7C,  0x08,  0x10,  0x08,  0xFE,  0x3E,  0x00,  0x2A,  0x44,  0x2B,  0xFF,  0x2A,  0x44,  0x3E, 	/* 4A430 */
+	0x74,  0x09,  0x9F,  0x0C,  0x00,  0x0A,  0xFF,  0x0A,  0x28,  0x0F,  0x29,  0x71,  0x49,  0x01,  0x87,  0xB2, 	/* 4A440 */
+	0x00,  0x80,  0x0F,  0xF8,  0x08,  0x88,  0x08,  0x88,  0x0F,  0xF8,  0x00,  0x90,  0x00,  0xFC,  0x3F,  0x02, 	/* 4A450 */
+	0x08,  0x10,  0x3E,  0x7C,  0x2A,  0x54,  0x2A,  0x54,  0x3E,  0x7C,  0x09,  0x14,  0x0E,  0x9A,  0x70,  0xE1, 	/* 4A460 */
+	0xB6,  0x08,  0x00,  0x09,  0xF0,  0x08,  0xAF,  0x08,  0xE9,  0x3E,  0xA9,  0x2A,  0xE9,  0x2A,  0xAF,  0x2B, 	/* 4A470 */
+	0xE0,  0x3E,  0x22,  0x08,  0xFC,  0x0C,  0x10,  0x0A,  0x7C,  0x0A,  0x10,  0x0D,  0x10,  0x71,  0xFF,  0x00, 	/* 4A480 */
+	0x00,  0xB7,  0x08,  0x92,  0x08,  0x52,  0x08,  0x54,  0x09,  0xFF,  0x3F,  0x01,  0x2B,  0x7D,  0x2A,  0x44, 	/* 4A490 */
+	0x2A,  0x7C,  0x3E,  0x00,  0x08,  0xFE,  0x0C,  0x92,  0x0A,  0xFE,  0x0A,  0x92,  0x0F,  0x92,  0x71,  0xFE, 	/* 4A4A0 */
+	0x00,  0x00,  0xB9,  0x10,  0x00,  0x1E,  0xFE,  0x24,  0x22,  0x7F,  0x46,  0x29,  0xA8,  0x3F,  0x3E,  0x29, 	/* 4A4B0 */
+	0x48,  0x3F,  0xFF,  0x21,  0x08,  0x43,  0x08,  0x1F,  0xF0,  0x11,  0x10,  0x1F,  0xF0,  0x01,  0x08,  0x01, 	/* 4A4C0 */
+	0xFC,  0x7E,  0x02,  0xBB,  0x08,  0x44,  0x08,  0x28,  0x08,  0xFE,  0x08,  0x10,  0x3E,  0xFE,  0x2A,  0x10, 	/* 4A4D0 */
+	0x2B,  0xFF,  0x2A,  0x2C,  0x3F,  0xCA,  0x08,  0x48,  0x0D,  0xFF,  0x0A,  0x4A,  0x0A,  0x6A,  0x0F,  0xC5, 	/* 4A4E0 */
+	0x79,  0x4B,  0x00,  0xD1,  0xBE,  0x08,  0x20,  0x08,  0x3C,  0x08,  0x48,  0x09,  0xFF,  0x3E,  0x94,  0x2A, 	/* 4A4F0 */
+	0xE3,  0x2A,  0x9C,  0x2A,  0x80,  0x3E,  0xFF,  0x08,  0x80,  0x0C,  0x9C,  0x0A,  0x80,  0x0A,  0xBE,  0x0D, 	/* 4A500 */
+	0x22,  0x71,  0x3E,  0x02,  0x00,  0x85,  0x08,  0x00,  0x08,  0xFE,  0x08,  0xAA,  0x3E,  0xAA,  0x2A,  0xEE, 	/* 4A510 */
+	0x2A,  0x28,  0x2A,  0x68,  0x2A,  0xAE,  0x3E,  0xAA,  0x08,  0xAA,  0x0C,  0xEE,  0x0A,  0xAA,  0x0A,  0xAA, 	/* 4A520 */
+	0x0F,  0xEE,  0x71,  0x21,  0x00,  0x1F,  0x8D,  0x10,  0x08,  0x11,  0xC8,  0x11,  0x48,  0x11,  0xCF,  0x7D, 	/* 4A530 */
+	0x55,  0x55,  0x56,  0x55,  0xE4,  0x54,  0x84,  0x7D,  0xE4,  0x11,  0x24,  0x1B,  0x64,  0x15,  0xAA,  0x15, 	/* 4A540 */
+	0x2A,  0x1E,  0xF2,  0x62,  0x22,  0x00,  0xC1,  0x8E,  0x08,  0x24,  0x08,  0x24,  0x09,  0xFF,  0x08,  0x24, 	/* 4A550 */
+	0x3E,  0x10,  0x2A,  0xFF,  0x2A,  0x18,  0x2A,  0x64,  0x3F,  0x93,  0x08,  0x3C,  0x0C,  0x54,  0x0A,  0x44, 	/* 4A560 */
+	0x0B,  0xFF,  0x0D,  0x44,  0x71,  0x44,  0x00,  0x84,  0x8F,  0x08,  0x40,  0x08,  0x7F,  0x08,  0xA5,  0x09, 	/* 4A570 */
+	0x45,  0x3F,  0xF5,  0x2B,  0x59,  0x2B,  0x53,  0x2B,  0xF0,  0x3F,  0x5A,  0x09,  0x5F,  0x09,  0xFA,  0x0D, 	/* 4A580 */
+	0x12,  0x0B,  0x1F,  0x0D,  0x12,  0x71,  0x12,  0x02,  0x32,  0x91,  0x08,  0x44,  0x08,  0x55,  0x09,  0x55, 	/* 4A590 */
+	0x09,  0x6A,  0x3E,  0xA9,  0x2B,  0x10,  0x2B,  0xFF,  0x2B,  0x01,  0x3E,  0x10,  0x09,  0xFF,  0x0C,  0x10, 	/* 4A5A0 */
+	0x0A,  0x38,  0x0A,  0x54,  0x0D,  0x92,  0x71,  0x11,  0x00,  0x10,  0x95,  0x08,  0x00,  0x08,  0xFE,  0x08, 	/* 4A5B0 */
+	0x08,  0x08,  0xFF,  0x3E,  0x89,  0x2A,  0xED,  0x2A,  0x89,  0x2A,  0x6C,  0x2A,  0x00,  0x3F,  0xFF,  0x08, 	/* 4A5C0 */
+	0x10,  0x0C,  0xFE,  0x0A,  0xAA,  0x0E,  0xAA,  0x71,  0xAA,  0x00,  0x86,  0x96,  0x08,  0x24,  0x08,  0xFF, 	/* 4A5D0 */
+	0x08,  0x24,  0x08,  0x48,  0x3E,  0x7F,  0x2A,  0xC8,  0x2B,  0x7E,  0x2A,  0x48,  0x3E,  0x7E,  0x08,  0x48, 	/* 4A5E0 */
+	0x0C,  0x7F,  0x0A,  0x00,  0x0A,  0xFE,  0x0F,  0x24,  0x71,  0x18,  0x00,  0xE7,  0xA1,  0x02,  0x00,  0x03, 	/* 4A5F0 */
+	0xF0,  0x04,  0x20,  0x7F,  0xFF,  0x03,  0x08,  0x1C,  0xB0,  0x03,  0x50,  0x1C,  0xCC,  0x03,  0x43,  0x3C, 	/* 4A600 */
+	0xC0,  0x08,  0x10,  0x3E,  0x7C,  0x2A,  0x54,  0x3E,  0x7C,  0x0B,  0x16,  0x7E,  0xFD,  0xA2,  0x00,  0x80, 	/* 4A610 */
+	0x3F,  0xFE,  0x01,  0x00,  0x1F,  0xFC,  0x02,  0x20,  0x7F,  0xFF,  0x04,  0x10,  0x1F,  0xFC,  0x64,  0x13, 	/* 4A620 */
+	0x07,  0xF0,  0x08,  0x10,  0x3E,  0x7C,  0x2A,  0x54,  0x3E,  0x7C,  0x0B,  0x16,  0x7E,  0xFD,  0xA3,  0x08, 	/* 4A630 */
+	0x00,  0x08,  0xFF,  0x08,  0xA4,  0x08,  0xFF,  0x3E,  0xA4,  0x2A,  0xBE,  0x2A,  0xAA,  0x2A,  0xBE,  0x3E, 	/* 4A640 */
+	0xAA,  0x08,  0xBE,  0x0C,  0x88,  0x0A,  0xFF,  0x0A,  0xCB,  0x1D,  0x5D,  0x61,  0x41,  0x02,  0x43,  0xA7, 	/* 4A650 */
+	0x01,  0x00,  0x7F,  0xFE,  0x01,  0x00,  0x1F,  0xF8,  0x00,  0x00,  0x7F,  0xFE,  0x42,  0x02,  0x0F,  0xF8, 	/* 4A660 */
+	0x74,  0x08,  0x07,  0xF8,  0x08,  0x10,  0x3F,  0x7C,  0x29,  0x54,  0x3F,  0x7C,  0x0B,  0x16,  0x7C,  0xF9, 	/* 4A670 */
+	0xB1,  0x00,  0x80,  0x07,  0xF0,  0x04,  0x90,  0x07,  0xF0,  0x00,  0x88,  0x1F,  0xF4,  0x3E,  0x7C,  0x2A, 	/* 4A680 */
+	0x54,  0x3E,  0x7C,  0x0B,  0x16,  0x7E,  0xFD,  0x00,  0x00,  0x1F,  0xFC,  0x12,  0x44,  0x7F,  0xFF,  0x00, 	/* 4A690 */
+	0x00,  0xB6,  0x00,  0x00,  0x3F,  0x7E,  0x12,  0x24,  0x7F,  0xFF,  0x0A,  0x14,  0x13,  0x25,  0x6F,  0xF3, 	/* 4A6A0 */
+	0x0F,  0xF0,  0x08,  0x10,  0x0F,  0xF0,  0x08,  0x10,  0x3E,  0x7C,  0x2A,  0x54,  0x3E,  0x7C,  0x0B,  0x16, 	/* 4A6B0 */
+	0x7E,  0xFD,  0xB9,  0x00,  0x80,  0x3F,  0xFC,  0x00,  0x80,  0x0F,  0xF8,  0x08,  0x88,  0x7F,  0xFE,  0x42, 	/* 4A6C0 */
+	0x02,  0x0F,  0xF8,  0x34,  0x08,  0x07,  0xF8,  0x08,  0x10,  0x3E,  0x7C,  0x2A,  0x54,  0x3E,  0x7C,  0x09, 	/* 4A6D0 */
+	0x16,  0x7E,  0xFD,  0xBB,  0x11,  0x04,  0x13,  0xE4,  0x68,  0x1A,  0x13,  0xC4,  0x28,  0x0A,  0x7F,  0xDF, 	/* 4A6E0 */
+	0x10,  0x04,  0x57,  0xD5,  0x56,  0x55,  0x13,  0xC4,  0x00,  0x80,  0x1F,  0xF8,  0x10,  0x88,  0x1F,  0xF8, 	/* 4A6F0 */
+	0x00,  0x86,  0x7F,  0xF9,  0x80,  0x01,  0x00,  0x01,  0x00,  0x02,  0x00,  0x1F,  0xFC,  0x12,  0x44,  0x12, 	/* 4A700 */
+	0x44,  0x12,  0x44,  0x12,  0x44,  0x12,  0x44,  0x12,  0x44,  0x12,  0x44,  0x12,  0x44,  0x12,  0x44,  0x7F, 	/* 4A710 */
+	0xFF,  0x00,  0x00,  0x00,  0x00,  0x82,  0x04,  0x00,  0x04,  0xFE,  0x08,  0x12,  0x3F,  0x92,  0x2A,  0x92, 	/* 4A720 */
+	0x2A,  0xD2,  0x2A,  0xB2,  0x2A,  0x92,  0x2A,  0x9A,  0x2A,  0x96,  0x2A,  0xE3,  0x2B,  0x22,  0x3C,  0x42, 	/* 4A730 */
+	0x60,  0x82,  0x01,  0x02,  0x02,  0x0C,  0x84,  0x04,  0x00,  0x04,  0x7E,  0x08,  0x12,  0x3F,  0x92,  0x2A, 	/* 4A740 */
+	0x92,  0x2A,  0x92,  0x2A,  0x92,  0x2A,  0xFF,  0x2A,  0x92,  0x2A,  0x92,  0x2A,  0xD2,  0x2B,  0x12,  0x3C, 	/* 4A750 */
+	0x12,  0x60,  0x12,  0x00,  0xFF,  0x00,  0x00,  0x86,  0x00,  0x80,  0x01,  0x00,  0x1F,  0xFC,  0x12,  0x24, 	/* 4A760 */
+	0x12,  0x24,  0x7F,  0xFF,  0x00,  0x20,  0x04,  0x44,  0x09,  0x84,  0x36,  0xA8,  0x00,  0x90,  0x04,  0x88, 	/* 4A770 */
+	0x08,  0x84,  0x10,  0x83,  0x60,  0x80,  0x00,  0x80,  0x8C,  0x04,  0x00,  0x04,  0xFE,  0x08,  0x00,  0x08, 	/* 4A780 */
+	0x00,  0x12,  0x00,  0x22,  0x00,  0x05,  0xFF,  0x04,  0x08,  0x08,  0x08,  0x18,  0x08,  0x28,  0x08,  0x48, 	/* 4A790 */
+	0x08,  0x08,  0x08,  0x08,  0x08,  0x08,  0x08,  0x08,  0x18,  0x8D,  0x08,  0x00,  0x08,  0x9E,  0x10,  0x40, 	/* 4A7A0 */
+	0x14,  0x40,  0x24,  0x00,  0x49,  0x3F,  0x08,  0x84,  0x10,  0x84,  0x10,  0x04,  0x30,  0x44,  0x50,  0x84, 	/* 4A7B0 */
+	0x10,  0x84,  0x11,  0x04,  0x11,  0x04,  0x12,  0x04,  0x12,  0x0C,  0x92,  0x08,  0x80,  0x08,  0x9F,  0x10, 	/* 4A7C0 */
+	0x80,  0x17,  0xF0,  0x24,  0x80,  0x44,  0x9F,  0x08,  0x84,  0x0F,  0x24,  0x11,  0x44,  0x30,  0xC4,  0x50, 	/* 4A7D0 */
+	0x84,  0x10,  0xC4,  0x11,  0x24,  0x12,  0x64,  0x17,  0x94,  0x10,  0x0C,  0x93,  0x08,  0x80,  0x08,  0xDE, 	/* 4A7E0 */
+	0x10,  0xA0,  0x14,  0xA0,  0x24,  0x80,  0x47,  0xFF,  0x08,  0x84,  0x08,  0xC4,  0x12,  0xA4,  0x32,  0xA4, 	/* 4A7F0 */
+	0x52,  0x94,  0x12,  0x94,  0x12,  0x94,  0x14,  0x84,  0x10,  0x84,  0x10,  0x8C,  0x97,  0x09,  0x00,  0x09, 	/* 4A800 */
+	0x1E,  0x17,  0xE0,  0x11,  0x00,  0x21,  0x00,  0x49,  0x00,  0x0F,  0xFF,  0x11,  0x04,  0x11,  0x04,  0x37, 	/* 4A810 */
+	0xE4,  0x51,  0x04,  0x11,  0x04,  0x11,  0x64,  0x13,  0x84,  0x1C,  0x04,  0x10,  0x0C,  0x99,  0x08,  0x00, 	/* 4A820 */
+	0x0F,  0xEE,  0x10,  0x80,  0x10,  0x80,  0x27,  0xC0,  0x49,  0x5F,  0x09,  0x44,  0x11,  0x44,  0x17,  0xF4, 	/* 4A830 */
+	0x30,  0x04,  0x53,  0xE4,  0x12,  0x24,  0x12,  0x24,  0x12,  0x24,  0x13,  0xE4,  0x10,  0x0C,  0x9B,  0x09, 	/* 4A840 */
+	0x00,  0x0B,  0xEE,  0x11,  0x20,  0x11,  0x20,  0x27,  0xF0,  0x44,  0x00,  0x0B,  0xFF,  0x0A,  0x24,  0x13, 	/* 4A850 */
+	0xE4,  0x30,  0x44,  0x57,  0xF4,  0x11,  0x44,  0x11,  0x44,  0x17,  0xF4,  0x10,  0x44,  0x10,  0x4C,  0x9D, 	/* 4A860 */
+	0x08,  0x60,  0x0B,  0x9E,  0x10,  0x80,  0x17,  0xF0,  0x20,  0x80,  0x4B,  0xE0,  0x0A,  0xBF,  0x13,  0xE4, 	/* 4A870 */
+	0x12,  0xA4,  0x33,  0xE4,  0x50,  0x84,  0x13,  0xE4,  0x10,  0x84,  0x10,  0xF4,  0x17,  0x04,  0x10,  0x0C, 	/* 4A880 */
+	0x9E,  0x08,  0x80,  0x0B,  0xEE,  0x11,  0x20,  0x17,  0xF0,  0x20,  0x00,  0x4B,  0xFF,  0x0A,  0x24,  0x13, 	/* 4A890 */
+	0xE4,  0x10,  0x04,  0x37,  0xF4,  0x50,  0x84,  0x13,  0xE4,  0x12,  0xA4,  0x12,  0xA4,  0x12,  0xE4,  0x10, 	/* 4A8A0 */
+	0x8C,  0xA1,  0x09,  0x00,  0x09,  0xDE,  0x12,  0x40,  0x14,  0x80,  0x23,  0xE0,  0x4A,  0xBF,  0x0B,  0xE4, 	/* 4A8B0 */
+	0x12,  0xA4,  0x12,  0xA4,  0x33,  0xE4,  0x50,  0x84,  0x17,  0xF4,  0x10,  0xC4,  0x11,  0x24,  0x12,  0x24, 	/* 4A8C0 */
+	0x14,  0x0C,  0xA2,  0x17,  0x70,  0x15,  0x5E,  0x27,  0x70,  0x25,  0x50,  0x4F,  0x70,  0x0D,  0x5F,  0x17, 	/* 4A8D0 */
+	0x74,  0x12,  0x44,  0x37,  0xF4,  0x5C,  0x84,  0x17,  0xE4,  0x14,  0x84,  0x17,  0xE4,  0x14,  0x84,  0x17, 	/* 4A8E0 */
+	0xF4,  0x10,  0x0C,  0xA3,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x7F,  0xFF,  0x01,  0x80, 	/* 4A8F0 */
+	0x02,  0x84,  0x02,  0x44,  0x04,  0x48,  0x1C,  0x30,  0x64,  0x20,  0x04,  0x10,  0x04,  0x08,  0x05,  0xC4, 	/* 4A900 */
+	0x0E,  0x02,  0x30,  0x01,  0xA8,  0x00,  0x80,  0x00,  0x80,  0x3F,  0xFE,  0x00,  0x80,  0x00,  0x80,  0x1F, 	/* 4A910 */
+	0xFC,  0x00,  0x80,  0x00,  0x80,  0x7F,  0xFF,  0x02,  0x84,  0x0C,  0x48,  0x74,  0x50,  0x04,  0x20,  0x04, 	/* 4A920 */
+	0x10,  0x07,  0x0C,  0x38,  0x03,  0xAB,  0x08,  0x08,  0x08,  0x08,  0x08,  0x10,  0x7E,  0x20,  0x02,  0xC4, 	/* 4A930 */
+	0x04,  0x04,  0x04,  0x08,  0x09,  0x10,  0x1A,  0x22,  0x2C,  0xC2,  0x4A,  0x04,  0x09,  0x04,  0x08,  0x08, 	/* 4A940 */
+	0x08,  0x10,  0x08,  0x60,  0x09,  0x80,  0xB0,  0x00,  0x80,  0x00,  0x80,  0x3F,  0xFE,  0x00,  0x00,  0x0F, 	/* 4A950 */
+	0xF8,  0x08,  0x08,  0x7F,  0xFF,  0x08,  0x08,  0x0F,  0xFC,  0x02,  0x84,  0x06,  0x88,  0x1A,  0x50,  0x62, 	/* 4A960 */
+	0x20,  0x02,  0x10,  0x03,  0x8C,  0x1C,  0x03,  0xB2,  0x08,  0x70,  0x08,  0x10,  0x08,  0x10,  0x7E,  0x10, 	/* 4A970 */
+	0x02,  0xFE,  0x04,  0x92,  0x04,  0x92,  0x0A,  0x92,  0x1A,  0xAA,  0x2C,  0xAA,  0x4A,  0xC6,  0x09,  0x82, 	/* 4A980 */
+	0x08,  0x82,  0x08,  0x82,  0x08,  0x82,  0x08,  0x86,  0xB5,  0x08,  0x00,  0x08,  0x7E,  0x08,  0x42,  0x7E, 	/* 4A990 */
+	0x42,  0x02,  0x42,  0x04,  0x42,  0x08,  0x42,  0x09,  0x7E,  0x1A,  0x42,  0x2C,  0x42,  0x4A,  0x42,  0x09, 	/* 4A9A0 */
+	0x42,  0x08,  0x42,  0x08,  0x42,  0x08,  0x7E,  0x08,  0x00,  0xB7,  0x00,  0x80,  0x00,  0x80,  0x7F,  0xFF, 	/* 4A9B0 */
+	0x00,  0x80,  0x0F,  0xF8,  0x08,  0x88,  0x08,  0x88,  0x08,  0x88,  0x0F,  0xFC,  0x02,  0x84,  0x06,  0x48, 	/* 4A9C0 */
+	0x1A,  0x50,  0x62,  0x20,  0x02,  0x10,  0x03,  0x8C,  0x1C,  0x03,  0xBD,  0x08,  0x02,  0x08,  0x0C,  0x08, 	/* 4A9D0 */
+	0xF0,  0x7E,  0x10,  0x02,  0x10,  0x04,  0x10,  0x08,  0x10,  0x09,  0xFF,  0x1A,  0x10,  0x2C,  0x10,  0x4A, 	/* 4A9E0 */
+	0x10,  0x09,  0x10,  0x08,  0x10,  0x08,  0x10,  0x08,  0xFE,  0x08,  0x00,  0xBE,  0x00,  0x80,  0x01,  0x40, 	/* 4A9F0 */
+	0x02,  0x20,  0x0C,  0x18,  0x77,  0xE7,  0x00,  0x00,  0x1F,  0xF8,  0x00,  0x10,  0x00,  0xA0,  0x00,  0x80, 	/* 4AA00 */
+	0x7F,  0xFF,  0x02,  0x44,  0x0C,  0x28,  0x74,  0x10,  0x07,  0x8C,  0x3C,  0x03,  0xBF,  0x08,  0x10,  0x08, 	/* 4AA10 */
+	0x10,  0x08,  0x28,  0x7E,  0x28,  0x02,  0x44,  0x05,  0x82,  0x05,  0x7D,  0x09,  0x00,  0x1E,  0x00,  0x2A, 	/* 4AA20 */
+	0x7C,  0x49,  0x04,  0x08,  0x04,  0x08,  0x08,  0x08,  0x08,  0x08,  0x10,  0x08,  0x20,  0x81,  0x00,  0x80, 	/* 4AA30 */
+	0x00,  0x80,  0x1F,  0xFC,  0x00,  0x80,  0x7F,  0xFF,  0x00,  0x00,  0x0F,  0xF8,  0x08,  0x08,  0x08,  0x08, 	/* 4AA40 */
+	0x0F,  0xFA,  0x01,  0x42,  0x06,  0x24,  0x1C,  0x28,  0x64,  0x10,  0x07,  0x8C,  0x1C,  0x03,  0x82,  0x08, 	/* 4AA50 */
+	0x20,  0x08,  0x20,  0x08,  0x20,  0x7E,  0xFC,  0x02,  0x24,  0x04,  0x24,  0x04,  0x24,  0x0A,  0x24,  0x1B, 	/* 4AA60 */
+	0xFF,  0x2C,  0x20,  0x4A,  0x30,  0x09,  0x50,  0x08,  0x48,  0x08,  0x84,  0x09,  0x02,  0x0A,  0x01,  0x88, 	/* 4AA70 */
+	0x04,  0x00,  0x04,  0x3E,  0x7F,  0xA2,  0x04,  0xA2,  0x08,  0xA2,  0x08,  0xA2,  0x13,  0x3E,  0x20,  0x80, 	/* 4AA80 */
+	0x00,  0x80,  0x7F,  0xFF,  0x02,  0x84,  0x0C,  0x48,  0x74,  0x30,  0x04,  0x10,  0x07,  0x8C,  0x3C,  0x03, 	/* 4AA90 */
+	0x8B,  0x04,  0x28,  0x04,  0x24,  0x0B,  0xFE,  0x18,  0x20,  0x28,  0x20,  0x48,  0x12,  0x08,  0x0A,  0x08, 	/* 4AAA0 */
+	0x86,  0x00,  0x82,  0x7F,  0xFF,  0x02,  0x88,  0x04,  0x48,  0x1C,  0x30,  0x64,  0x90,  0x07,  0x0C,  0x38, 	/* 4AAB0 */
+	0x03,  0x8D,  0x08,  0x40,  0x08,  0x40,  0x08,  0x7E,  0x7E,  0x82,  0x02,  0x82,  0x04,  0xF2,  0x05,  0x92, 	/* 4AAC0 */
+	0x08,  0x92,  0x1A,  0x92,  0x2C,  0xF2,  0x4A,  0x8C,  0x08,  0x80,  0x08,  0x80,  0x08,  0x81,  0x08,  0x41, 	/* 4AAD0 */
+	0x08,  0x3F,  0x92,  0x08,  0x00,  0x08,  0x7C,  0x08,  0x44,  0x7E,  0x44,  0x02,  0x44,  0x04,  0x44,  0x04, 	/* 4AAE0 */
+	0x7C,  0x09,  0x44,  0x1A,  0x44,  0x2C,  0x44,  0x4A,  0x44,  0x09,  0x7C,  0x08,  0x00,  0x08,  0x00,  0x09, 	/* 4AAF0 */
+	0xFF,  0x08,  0x00,  0x96,  0x08,  0x10,  0x08,  0x10,  0x08,  0x10,  0x7E,  0x10,  0x02,  0xFE,  0x04,  0x92, 	/* 4AB00 */
+	0x04,  0x92,  0x09,  0x92,  0x1E,  0x92,  0x2A,  0xFE,  0x49,  0x92,  0x08,  0x92,  0x08,  0x92,  0x08,  0x92, 	/* 4AB10 */
+	0x08,  0xFE,  0x08,  0x00,  0x97,  0x08,  0x10,  0x08,  0x10,  0x08,  0x28,  0x7E,  0x28,  0x02,  0x44,  0x04, 	/* 4AB20 */
+	0x8A,  0x05,  0x11,  0x08,  0x20,  0x1A,  0xC4,  0x2C,  0x08,  0x4A,  0x30,  0x08,  0xC2,  0x08,  0x04,  0x08, 	/* 4AB30 */
+	0x18,  0x08,  0x60,  0x09,  0x80,  0x99,  0x08,  0x10,  0x08,  0x10,  0x08,  0x20,  0x7E,  0x7E,  0x02,  0x42, 	/* 4AB40 */
+	0x04,  0x42,  0x08,  0x42,  0x09,  0x42,  0x1A,  0x7E,  0x2C,  0x42,  0x4A,  0x42,  0x09,  0x42,  0x08,  0x42, 	/* 4AB50 */
+	0x08,  0x42,  0x08,  0x7E,  0x08,  0x00,  0x9E,  0x00,  0x80,  0x00,  0x80,  0x7F,  0xFF,  0x02,  0xF0,  0x04, 	/* 4AB60 */
+	0x10,  0x18,  0x0C,  0x6F,  0xFB,  0x08,  0x08,  0x08,  0x08,  0x0F,  0xFA,  0x01,  0x42,  0x06,  0x44,  0x1C, 	/* 4AB70 */
+	0x28,  0x64,  0x10,  0x07,  0x8C,  0x1C,  0x03,  0xA2,  0x08,  0x10,  0x08,  0x10,  0x08,  0x54,  0x7E,  0x52, 	/* 4AB80 */
+	0x02,  0x92,  0x04,  0x10,  0x04,  0xFE,  0x08,  0x10,  0x1A,  0x10,  0x2C,  0x10,  0x4B,  0xFF,  0x09,  0x10, 	/* 4AB90 */
+	0x08,  0x10,  0x08,  0x10,  0x08,  0x10,  0x08,  0x10,  0xA4,  0x00,  0x80,  0x7F,  0xFF,  0x00,  0x00,  0x1F, 	/* 4ABA0 */
+	0xF8,  0x03,  0x20,  0x00,  0xC0,  0x7F,  0xFE,  0x01,  0x44,  0x06,  0x48,  0x38,  0xC0,  0x00,  0x84,  0x03, 	/* 4ABB0 */
+	0x44,  0x0C,  0x28,  0x74,  0x10,  0x07,  0x8C,  0x3C,  0x03,  0xAB,  0x08,  0x10,  0x08,  0x10,  0x08,  0x10, 	/* 4ABC0 */
+	0x7E,  0xFE,  0x02,  0x92,  0x04,  0x94,  0x05,  0x90,  0x0A,  0xFC,  0x1C,  0xC4,  0x2A,  0xA4,  0x49,  0xA8, 	/* 4ABD0 */
+	0x08,  0x98,  0x09,  0x18,  0x09,  0x24,  0x0A,  0x42,  0x09,  0x81,  0xAE,  0x08,  0x40,  0x08,  0x40,  0x08, 	/* 4ABE0 */
+	0x40,  0x7E,  0x7F,  0x02,  0x88,  0x04,  0x88,  0x05,  0x08,  0x08,  0x2C,  0x1A,  0x2A,  0x2C,  0x2A,  0x4A, 	/* 4ABF0 */
+	0x49,  0x08,  0x49,  0x08,  0x88,  0x08,  0x08,  0x08,  0x08,  0x08,  0x18,  0xB0,  0x00,  0x00,  0x0F,  0xF8, 	/* 4AC00 */
+	0x08,  0x88,  0x08,  0x48,  0x7F,  0xFF,  0x11,  0x08,  0x10,  0x88,  0x1F,  0xFE,  0x00,  0x08,  0x00,  0xB0, 	/* 4AC10 */
+	0x7F,  0xFF,  0x01,  0x44,  0x06,  0x28,  0x7C,  0x10,  0x07,  0x8C,  0x38,  0x03,  0xB1,  0x10,  0x48,  0x10, 	/* 4AC20 */
+	0x4A,  0x10,  0x49,  0x7C,  0x89,  0x04,  0x88,  0x09,  0xFF,  0x0A,  0x88,  0x10,  0x88,  0x34,  0x88,  0x58, 	/* 4AC30 */
+	0x94,  0x14,  0x94,  0x12,  0x94,  0x10,  0xA4,  0x10,  0xA2,  0x10,  0xC2,  0x10,  0x81,  0xB4,  0x08,  0x10, 	/* 4AC40 */
+	0x08,  0x10,  0x09,  0xFF,  0x7E,  0x28,  0x02,  0x24,  0x04,  0x42,  0x05,  0xFD,  0x09,  0x00,  0x1E,  0xFE, 	/* 4AC50 */
+	0x2A,  0x10,  0x49,  0x10,  0x09,  0x3E,  0x08,  0x22,  0x08,  0x02,  0x08,  0x02,  0x08,  0x0C,  0xB5,  0x10, 	/* 4AC60 */
+	0x42,  0x10,  0x4C,  0x10,  0x78,  0x7C,  0x88,  0x04,  0x88,  0x09,  0x88,  0x0A,  0x88,  0x10,  0xFF,  0x1A, 	/* 4AC70 */
+	0x88,  0x34,  0x88,  0x52,  0x88,  0x10,  0x88,  0x10,  0x88,  0x10,  0x88,  0x10,  0xBF,  0x10,  0x80,  0xB7, 	/* 4AC80 */
+	0x08,  0x10,  0x08,  0x10,  0x08,  0x30,  0x7E,  0x28,  0x02,  0x48,  0x04,  0x44,  0x04,  0x84,  0x0A,  0xFA, 	/* 4AC90 */
+	0x1B,  0x01,  0x2C,  0x00,  0x4A,  0xFC,  0x09,  0x84,  0x08,  0x84,  0x08,  0x84,  0x08,  0xFC,  0x08,  0x00, 	/* 4ACA0 */
+	0xBF,  0x08,  0x10,  0x08,  0x10,  0x08,  0xFE,  0x7E,  0x10,  0x02,  0x10,  0x04,  0x10,  0x04,  0xFF,  0x09, 	/* 4ACB0 */
+	0x00,  0x1A,  0x10,  0x2C,  0x10,  0x4A,  0xFE,  0x08,  0x10,  0x08,  0x10,  0x08,  0x10,  0x09,  0xFF,  0x08, 	/* 4ACC0 */
+	0x00,  0x81,  0x04,  0x20,  0x04,  0x24,  0x3F,  0xA2,  0x04,  0x22,  0x04,  0x20,  0x7F,  0xFF,  0x04,  0x20, 	/* 4ACD0 */
+	0x7F,  0xA2,  0x08,  0x12,  0x14,  0x94,  0x35,  0x14,  0x52,  0x08,  0x11,  0x1A,  0x14,  0xA6,  0x18,  0x46, 	/* 4ACE0 */
+	0x30,  0x82,  0x82,  0x00,  0x02,  0x3F,  0xD2,  0x04,  0x12,  0x07,  0x92,  0x08,  0x92,  0x35,  0x12,  0x02, 	/* 4ACF0 */
+	0x12,  0x0C,  0x02,  0x70,  0x86,  0x00,  0x80,  0x7F,  0xFF,  0x01,  0x88,  0x06,  0x50,  0x7C,  0x20,  0x07, 	/* 4AD00 */
+	0x18,  0x18,  0x07,  0x83,  0x08,  0x10,  0x08,  0x10,  0x08,  0x1E,  0x7E,  0x10,  0x02,  0x10,  0x04,  0xFF, 	/* 4AD10 */
+	0x04,  0x00,  0x09,  0x00,  0x1A,  0xFF,  0x2C,  0x10,  0x4A,  0x10,  0x09,  0x1C,  0x08,  0x12,  0x08,  0x10, 	/* 4AD20 */
+	0x08,  0x10,  0x08,  0x10,  0x84,  0x10,  0x40,  0x10,  0x5E,  0x10,  0x80,  0x7C,  0x80,  0x05,  0x00,  0x08, 	/* 4AD30 */
+	0x40,  0x08,  0x7F,  0x12,  0x84,  0x34,  0x84,  0x59,  0x84,  0x16,  0x84,  0x14,  0x84,  0x10,  0x84,  0x10, 	/* 4AD40 */
+	0x84,  0x10,  0x84,  0x10,  0x8C,  0x85,  0x04,  0x20,  0x24,  0x20,  0x17,  0xFE,  0x14,  0x20,  0x04,  0x20, 	/* 4AD50 */
+	0x1C,  0x20,  0x65,  0xFC,  0x04,  0x80,  0x00,  0x80,  0x7F,  0xFF,  0x02,  0x48,  0x0C,  0x48,  0x74,  0x30, 	/* 4AD60 */
+	0x04,  0x10,  0x07,  0x8C,  0x38,  0x03,  0x8F,  0x00,  0x80,  0x3F,  0xFE,  0x00,  0x00,  0x0F,  0xF8,  0x08, 	/* 4AD70 */
+	0x88,  0x0F,  0xF8,  0x08,  0x88,  0x0F,  0xF8,  0x00,  0x80,  0x1F,  0xFC,  0x00,  0x80,  0x7F,  0xFF,  0x02, 	/* 4AD80 */
+	0x42,  0x7C,  0x24,  0x07,  0x98,  0x1C,  0x07,  0x94,  0x00,  0x80,  0x00,  0x80,  0x7F,  0xFF,  0x01,  0x44, 	/* 4AD90 */
+	0x0E,  0x28,  0x74,  0x10,  0x07,  0x8C,  0x3C,  0x03,  0x00,  0x00,  0x3F,  0xFE,  0x22,  0x22,  0x24,  0x3E, 	/* 4ADA0 */
+	0x3B,  0xE2,  0x22,  0x22,  0x23,  0xE2,  0x20,  0x06,  0x95,  0x08,  0x48,  0x08,  0x44,  0x08,  0x44,  0x7E, 	/* 4ADB0 */
+	0x92,  0x02,  0x92,  0x04,  0x28,  0x05,  0x28,  0x09,  0x44,  0x1E,  0x82,  0x2A,  0x7D,  0x49,  0x44,  0x08, 	/* 4ADC0 */
+	0x44,  0x08,  0x44,  0x08,  0x44,  0x08,  0x7C,  0x08,  0x00,  0x98,  0x00,  0x90,  0x00,  0x88,  0x7F,  0xFF, 	/* 4ADD0 */
+	0x10,  0x84,  0x08,  0xC8,  0x09,  0xA0,  0x06,  0x98,  0x38,  0x87,  0x01,  0x80,  0x00,  0x80,  0x7F,  0xFF, 	/* 4ADE0 */
+	0x01,  0x44,  0x0E,  0x28,  0x74,  0x10,  0x07,  0x8C,  0x3C,  0x03,  0x99,  0x08,  0x00,  0x08,  0xFC,  0x08, 	/* 4ADF0 */
+	0x24,  0x7E,  0x24,  0x03,  0xFF,  0x04,  0x24,  0x04,  0x24,  0x08,  0xFC,  0x1A,  0x40,  0x2C,  0x40,  0x4A, 	/* 4AE00 */
+	0xFE,  0x08,  0xC2,  0x09,  0x42,  0x0A,  0x42,  0x08,  0x7E,  0x08,  0x00,  0x9C,  0x08,  0x14,  0x08,  0x12, 	/* 4AE10 */
+	0x09,  0xFF,  0x7E,  0x10,  0x02,  0x10,  0x04,  0xFE,  0x04,  0x92,  0x09,  0x92,  0x1A,  0xFE,  0x2C,  0x92, 	/* 4AE20 */
+	0x4A,  0x92,  0x09,  0xFE,  0x08,  0x92,  0x08,  0x92,  0x08,  0x92,  0x08,  0x86,  0x9D,  0x22,  0x10,  0x22, 	/* 4AE30 */
+	0x10,  0x3F,  0xFF,  0x02,  0x10,  0x7E,  0x10,  0x12,  0x10,  0x12,  0xFE,  0x22,  0x80,  0x00,  0x80,  0x7F, 	/* 4AE40 */
+	0xFF,  0x01,  0x84,  0x06,  0x48,  0x7C,  0x30,  0x04,  0x10,  0x07,  0x8C,  0x3C,  0x03,  0x9F,  0x30,  0x20, 	/* 4AE50 */
+	0x08,  0xA8,  0x00,  0xA4,  0x61,  0x22,  0x12,  0x2A,  0x00,  0x68,  0x0C,  0x10,  0x30,  0x60,  0x43,  0x80, 	/* 4AE60 */
+	0x00,  0x80,  0x7F,  0xFF,  0x02,  0x88,  0x0C,  0x50,  0x74,  0x20,  0x07,  0x18,  0x38,  0x07,  0xA1,  0x08, 	/* 4AE70 */
+	0x00,  0x08,  0xFE,  0x08,  0x92,  0x7E,  0x92,  0x02,  0xFE,  0x04,  0x92,  0x08,  0x92,  0x09,  0xFE,  0x1A, 	/* 4AE80 */
+	0x10,  0x2C,  0x10,  0x4A,  0xFE,  0x09,  0x10,  0x08,  0x10,  0x08,  0x10,  0x0B,  0xFF,  0x08,  0x00,  0xA8, 	/* 4AE90 */
+	0x08,  0x08,  0x08,  0x10,  0x08,  0xFE,  0x7E,  0x92,  0x02,  0x92,  0x04,  0xFE,  0x04,  0x92,  0x08,  0x92, 	/* 4AEA0 */
+	0x1A,  0xFE,  0x2C,  0x28,  0x4A,  0x48,  0x09,  0xFF,  0x08,  0x08,  0x08,  0x08,  0x08,  0x08,  0x08,  0x08, 	/* 4AEB0 */
+	0xB2,  0x08,  0x00,  0x0B,  0xFF,  0x08,  0x10,  0x7E,  0x10,  0x03,  0xFE,  0x05,  0x12,  0x05,  0x12,  0x09, 	/* 4AEC0 */
+	0xDE,  0x1B,  0x56,  0x2D,  0x56,  0x4B,  0x56,  0x09,  0xBA,  0x09,  0x12,  0x09,  0x12,  0x09,  0x12,  0x09, 	/* 4AED0 */
+	0x16,  0xB3,  0x11,  0x08,  0x09,  0x10,  0x7F,  0xFE,  0x40,  0x02,  0x4F,  0xF2,  0x08,  0x10,  0x08,  0x10, 	/* 4AEE0 */
+	0x0F,  0xF0,  0x01,  0x00,  0x7F,  0xFE,  0x02,  0x84,  0x04,  0x88,  0x1C,  0x50,  0x64,  0x20,  0x07,  0x18, 	/* 4AEF0 */
+	0x38,  0x06,  0xB4,  0x02,  0x20,  0x02,  0x20,  0x7E,  0x3F,  0x02,  0x20,  0x3E,  0x3E,  0x03,  0x20,  0x7C, 	/* 4AF00 */
+	0x3F,  0x04,  0x20,  0x08,  0xA0,  0x00,  0x80,  0x7F,  0xFF,  0x02,  0x84,  0x0C,  0x48,  0x74,  0x30,  0x07, 	/* 4AF10 */
+	0x98,  0x3C,  0x07,  0xB8,  0x08,  0x00,  0x08,  0xFE,  0x08,  0x92,  0x7E,  0x92,  0x02,  0xFE,  0x04,  0x92, 	/* 4AF20 */
+	0x04,  0x92,  0x0A,  0xFE,  0x1A,  0x10,  0x2D,  0xFF,  0x4A,  0x38,  0x09,  0x54,  0x08,  0x92,  0x0B,  0x11, 	/* 4AF30 */
+	0x08,  0x10,  0x08,  0x10,  0xB9,  0x00,  0x80,  0x7F,  0xFF,  0x00,  0x00,  0x0F,  0xF8,  0x08,  0x88,  0x0F, 	/* 4AF40 */
+	0xF8,  0x08,  0x88,  0x0F,  0xF8,  0x00,  0x80,  0x7F,  0xFF,  0x09,  0x48,  0x32,  0x44,  0x0C,  0x2B,  0x74, 	/* 4AF50 */
+	0x10,  0x07,  0xCC,  0x1C,  0x03,  0xBC,  0x08,  0x00,  0x08,  0xFC,  0x08,  0x84,  0x7E,  0x84,  0x02,  0xFC, 	/* 4AF60 */
+	0x04,  0x84,  0x04,  0x84,  0x0A,  0xFC,  0x1A,  0x40,  0x2C,  0x7E,  0x4A,  0xAA,  0x09,  0x2A,  0x08,  0x52, 	/* 4AF70 */
+	0x08,  0x92,  0x08,  0x22,  0x08,  0x4C,  0xBD,  0x14,  0x04,  0x1F,  0xA4,  0x24,  0x24,  0x3F,  0xA4,  0x44, 	/* 4AF80 */
+	0x24,  0x3F,  0xA4,  0x24,  0xA4,  0x25,  0x8C,  0x04,  0x80,  0x7F,  0xFF,  0x02,  0x88,  0x0C,  0x50,  0x74, 	/* 4AF90 */
+	0x20,  0x04,  0x10,  0x0F,  0x0C,  0x30,  0x03,  0xBE,  0x10,  0x00,  0x10,  0xFE,  0x10,  0x82,  0x7C,  0x82, 	/* 4AFA0 */
+	0x04,  0xFE,  0x08,  0x90,  0x0A,  0x90,  0x12,  0xFF,  0x1C,  0x90,  0x34,  0x90,  0x52,  0xFE,  0x10,  0xC2, 	/* 4AFB0 */
+	0x11,  0x42,  0x11,  0x42,  0x12,  0x7E,  0x10,  0x00,  0x82,  0x10,  0x44,  0x10,  0x44,  0x11,  0xF4,  0x7C, 	/* 4AFC0 */
+	0x44,  0x04,  0x44,  0x08,  0x44,  0x0B,  0xFE,  0x10,  0x05,  0x14,  0x45,  0x38,  0x44,  0x55,  0xF4,  0x10, 	/* 4AFD0 */
+	0x44,  0x10,  0x5C,  0x10,  0x64,  0x13,  0x84,  0x10,  0x04,  0x84,  0x08,  0x10,  0x08,  0x10,  0x09,  0xFF, 	/* 4AFE0 */
+	0x7E,  0x10,  0x02,  0xFE,  0x04,  0x12,  0x05,  0xFF,  0x0A,  0x12,  0x1A,  0xFE,  0x2C,  0x10,  0x4B,  0xFF, 	/* 4AFF0 */
+	0x0A,  0x24,  0x08,  0x44,  0x08,  0x78,  0x08,  0x1C,  0x09,  0xE2,  0x87,  0x08,  0x40,  0x08,  0x40,  0x08, 	/* 4B000 */
+	0x7F,  0x7E,  0x80,  0x03,  0x7C,  0x04,  0x44,  0x04,  0x7C,  0x09,  0x44,  0x0A,  0x7C,  0x1C,  0x20,  0x2A, 	/* 4B010 */
+	0x7C,  0x48,  0xC4,  0x0B,  0x28,  0x08,  0x18,  0x08,  0x64,  0x09,  0x83,  0x8A,  0x08,  0x00,  0x09,  0xFF, 	/* 4B020 */
+	0x08,  0x00,  0x7E,  0xFE,  0x02,  0x82,  0x04,  0x82,  0x0A,  0xFE,  0x0A,  0x80,  0x1C,  0xFE,  0x2B,  0xAA, 	/* 4B030 */
+	0x49,  0xAA,  0x0A,  0xFE,  0x0A,  0xAA,  0x0C,  0xAA,  0x08,  0xAA,  0x08,  0x86,  0x8C,  0x08,  0x00,  0x09, 	/* 4B040 */
+	0xFF,  0x09,  0x01,  0x7F,  0x11,  0x02,  0xFE,  0x04,  0x10,  0x04,  0xFE,  0x0A,  0x92,  0x1A,  0xFE,  0x2C, 	/* 4B050 */
+	0x92,  0x4A,  0x92,  0x09,  0xFE,  0x08,  0x10,  0x09,  0xFF,  0x08,  0x10,  0x08,  0x10,  0x90,  0x08,  0x00, 	/* 4B060 */
+	0x08,  0xFC,  0x08,  0x84,  0x7E,  0xFC,  0x02,  0x84,  0x04,  0x84,  0x04,  0xFC,  0x0A,  0x20,  0x1A,  0x3E, 	/* 4B070 */
+	0x2C,  0x4A,  0x4A,  0xD2,  0x0B,  0x62,  0x08,  0x4A,  0x08,  0x3A,  0x08,  0x02,  0x08,  0x0C,  0x92,  0x00, 	/* 4B080 */
+	0x80,  0x00,  0x80,  0x7F,  0xFF,  0x04,  0xFC,  0x04,  0x84,  0x08,  0xFC,  0x18,  0x20,  0x2B,  0xFF,  0x48, 	/* 4B090 */
+	0xEC,  0x0B,  0x23,  0x08,  0x20,  0x02,  0x88,  0x04,  0x50,  0x7C,  0x20,  0x07,  0x98,  0x1C,  0x07,  0x93, 	/* 4B0A0 */
+	0x10,  0x40,  0x10,  0x7E,  0x10,  0x62,  0x7C,  0xA2,  0x04,  0xA2,  0x09,  0xBE,  0x09,  0x88,  0x16,  0x88, 	/* 4B0B0 */
+	0x34,  0xFF,  0x58,  0x9C,  0x14,  0x9C,  0x12,  0xAA,  0x10,  0xCA,  0x10,  0x89,  0x10,  0x88,  0x10,  0x88, 	/* 4B0C0 */
+	0x9D,  0x09,  0x22,  0x08,  0x92,  0x08,  0x94,  0x7E,  0xFC,  0x02,  0xA4,  0x04,  0xA4,  0x04,  0xFC,  0x0A, 	/* 4B0D0 */
+	0xA4,  0x1A,  0xA4,  0x2C,  0xFC,  0x4A,  0x20,  0x08,  0x20,  0x0B,  0xFF,  0x08,  0x20,  0x08,  0x20,  0x08, 	/* 4B0E0 */
+	0x20,  0x9E,  0x08,  0x00,  0x08,  0xFC,  0x08,  0xA4,  0x7E,  0xA4,  0x02,  0xB4,  0x04,  0xCC,  0x04,  0x84, 	/* 4B0F0 */
+	0x0A,  0xFC,  0x1A,  0x00,  0x2D,  0xFE,  0x4B,  0x4A,  0x09,  0x4A,  0x09,  0x4A,  0x09,  0x4A,  0x0B,  0xFF, 	/* 4B100 */
+	0x08,  0x00,  0xA5,  0x08,  0x00,  0x08,  0xFF,  0x08,  0x80,  0x7E,  0xBE,  0x02,  0x80,  0x04,  0xFF,  0x04, 	/* 4B110 */
+	0xA9,  0x08,  0xAA,  0x1A,  0xA4,  0x2C,  0xBA,  0x4A,  0xE5,  0x09,  0x04,  0x09,  0xFF,  0x0A,  0x44,  0x0C, 	/* 4B120 */
+	0x24,  0x08,  0x0C,  0xAA,  0x10,  0x00,  0x11,  0x3E,  0x10,  0xA2,  0x7C,  0xA2,  0x06,  0x3E,  0x09,  0x22, 	/* 4B130 */
+	0x09,  0x22,  0x14,  0x3E,  0x37,  0xA9,  0x58,  0xAA,  0x14,  0xA4,  0x10,  0xA4,  0x10,  0xB2,  0x11,  0x41, 	/* 4B140 */
+	0x12,  0x30,  0x14,  0x0F,  0xAB,  0x08,  0x02,  0x08,  0x1C,  0x08,  0xE8,  0x7E,  0x8E,  0x02,  0x88,  0x04, 	/* 4B150 */
+	0xBF,  0x04,  0xAA,  0x0A,  0xAC,  0x1A,  0xB9,  0x2C,  0xA7,  0x4A,  0xAC,  0x08,  0xAC,  0x09,  0x4C,  0x09, 	/* 4B160 */
+	0x55,  0x0A,  0x55,  0x08,  0xA3,  0xB6,  0x08,  0x00,  0x0B,  0xEF,  0x08,  0xA5,  0x7F,  0x7B,  0x02,  0xA5, 	/* 4B170 */
+	0x05,  0x29,  0x04,  0x63,  0x08,  0x10,  0x1A,  0x20,  0x2C,  0xFE,  0x4A,  0x82,  0x08,  0x82,  0x08,  0xFE, 	/* 4B180 */
+	0x08,  0x82,  0x08,  0xFE,  0x08,  0x00,  0xB8,  0x08,  0x10,  0x08,  0xFE,  0x08,  0x92,  0x7F,  0xFF,  0x02, 	/* 4B190 */
+	0x92,  0x04,  0xFE,  0x04,  0x10,  0x0A,  0xFE,  0x1A,  0x92,  0x2C,  0xFE,  0x4A,  0x10,  0x09,  0xFF,  0x08, 	/* 4B1A0 */
+	0x44,  0x08,  0xE8,  0x08,  0x3C,  0x09,  0xC2,  0xBB,  0x01,  0x00,  0x7F,  0xFF,  0x04,  0x10,  0x1F,  0x10, 	/* 4B1B0 */
+	0x04,  0x7C,  0x7F,  0x94,  0x15,  0x35,  0x25,  0x95,  0x5E,  0x2B,  0x07,  0xA9,  0x7C,  0x40,  0x01,  0x84, 	/* 4B1C0 */
+	0x0E,  0x48,  0x74,  0x30,  0x07,  0x98,  0x1C,  0x07,  0x81,  0x10,  0x08,  0x13,  0xCC,  0x10,  0x52,  0x7C, 	/* 4B1D0 */
+	0x7D,  0x04,  0x49,  0x09,  0xC8,  0x09,  0x3E,  0x11,  0x2A,  0x35,  0x2A,  0x59,  0xEA,  0x14,  0x7E,  0x12, 	/* 4B1E0 */
+	0x4C,  0x10,  0x4A,  0x10,  0x4A,  0x10,  0x8F,  0x13,  0x71,  0x83,  0x00,  0x80,  0x7F,  0xFF,  0x00,  0x00, 	/* 4B1F0 */
+	0x06,  0x7C,  0x38,  0x44,  0x20,  0x7C,  0x3E,  0x10,  0x21,  0xFF,  0x20,  0x7C,  0x3D,  0x93,  0x20,  0x10, 	/* 4B200 */
+	0x01,  0x44,  0x0E,  0x28,  0x74,  0x10,  0x07,  0x0C,  0x78,  0x03,  0x84,  0x00,  0x80,  0x00,  0x80,  0x7F, 	/* 4B210 */
+	0xFF,  0x11,  0x44,  0x1F,  0x7C,  0x02,  0x20,  0x0F,  0xF8,  0x02,  0x20,  0x0F,  0xF8,  0x02,  0x20,  0x7F, 	/* 4B220 */
+	0xFF,  0x03,  0x44,  0x0C,  0x28,  0x74,  0x10,  0x07,  0x8C,  0x1C,  0x03,  0x8C,  0x08,  0x00,  0x08,  0xEE, 	/* 4B230 */
+	0x08,  0xAA,  0x7E,  0xEE,  0x02,  0x00,  0x04,  0xFC,  0x04,  0xA4,  0x0A,  0xA4,  0x1A,  0xFC,  0x2C,  0xA4, 	/* 4B240 */
+	0x4A,  0xFC,  0x08,  0x20,  0x0B,  0xFF,  0x08,  0x20,  0x08,  0x20,  0x08,  0x20,  0x8D,  0x08,  0x24,  0x08, 	/* 4B250 */
+	0x28,  0x08,  0x7F,  0x7E,  0x48,  0x02,  0xFE,  0x05,  0x48,  0x04,  0x7E,  0x0A,  0x48,  0x1C,  0x7F,  0x2A, 	/* 4B260 */
+	0x10,  0x49,  0xFF,  0x09,  0x38,  0x08,  0x54,  0x09,  0x93,  0x08,  0x10,  0x08,  0x10,  0x96,  0x10,  0x20, 	/* 4B270 */
+	0x10,  0x40,  0x11,  0xFC,  0x7D,  0x24,  0x05,  0xAC,  0x09,  0x74,  0x09,  0xFC,  0x15,  0x24,  0x15,  0x74, 	/* 4B280 */
+	0x39,  0xAC,  0x55,  0x24,  0x13,  0xFF,  0x10,  0x20,  0x10,  0x50,  0x11,  0x88,  0x16,  0x06,  0x9E,  0x00, 	/* 4B290 */
+	0x08,  0x1F,  0xFF,  0x10,  0xA2,  0x1F,  0x94,  0x10,  0x7F,  0x1F,  0x08,  0x29,  0x7F,  0x29,  0x08,  0x4F, 	/* 4B2A0 */
+	0x88,  0x00,  0x80,  0x7F,  0xFF,  0x02,  0x44,  0x0C,  0x28,  0x74,  0x10,  0x07,  0x8C,  0x38,  0x03,  0x9F, 	/* 4B2B0 */
+	0x10,  0x88,  0x10,  0x88,  0x13,  0xFF,  0x7C,  0x88,  0x05,  0xDC,  0x09,  0xAA,  0x0A,  0x89,  0x16,  0x88, 	/* 4B2C0 */
+	0x18,  0xFC,  0x34,  0x00,  0x53,  0xFF,  0x10,  0xA8,  0x10,  0xA4,  0x11,  0x22,  0x12,  0x22,  0x10,  0x60, 	/* 4B2D0 */
+	0xA0,  0x08,  0x92,  0x08,  0x52,  0x08,  0x54,  0x7F,  0xFF,  0x03,  0x01,  0x05,  0x7D,  0x04,  0x44,  0x0A, 	/* 4B2E0 */
+	0x7C,  0x1A,  0x00,  0x2C,  0xFE,  0x4A,  0x92,  0x08,  0x92,  0x08,  0xFE,  0x08,  0x92,  0x08,  0xFE,  0x08, 	/* 4B2F0 */
+	0x00,  0xA4,  0x10,  0x04,  0x11,  0xF4,  0x11,  0x44,  0x7D,  0x4F,  0x05,  0xE8,  0x09,  0x30,  0x09,  0xE0, 	/* 4B300 */
+	0x13,  0x4F,  0x1D,  0x40,  0x35,  0xF0,  0x52,  0x00,  0x10,  0xFE,  0x10,  0xAA,  0x10,  0xAA,  0x13,  0xFF, 	/* 4B310 */
+	0x10,  0x00,  0xA6,  0x08,  0x00,  0x08,  0xFE,  0x08,  0x10,  0x7D,  0xFF,  0x05,  0x11,  0x05,  0xDD,  0x09, 	/* 4B320 */
+	0x11,  0x08,  0xDC,  0x1A,  0x00,  0x2D,  0xFF,  0x4A,  0x20,  0x09,  0xFE,  0x09,  0x4A,  0x09,  0x4A,  0x09, 	/* 4B330 */
+	0x4A,  0x09,  0x06,  0xAA,  0x10,  0x88,  0x13,  0xFF,  0x10,  0x88,  0x7C,  0x00,  0x05,  0xFE,  0x09,  0x52, 	/* 4B340 */
+	0x11,  0xFE,  0x14,  0x14,  0x38,  0x12,  0x55,  0xFF,  0x13,  0x10,  0x11,  0x12,  0x11,  0xD4,  0x11,  0x09, 	/* 4B350 */
+	0x12,  0x35,  0x14,  0xC3,  0xAD,  0x10,  0x80,  0x10,  0xBF,  0x10,  0x84,  0x7F,  0xE8,  0x04,  0x9E,  0x08, 	/* 4B360 */
+	0x92,  0x0B,  0xD2,  0x10,  0x1E,  0x14,  0x12,  0x3B,  0xDE,  0x56,  0x52,  0x12,  0x52,  0x12,  0x5E,  0x13, 	/* 4B370 */
+	0xCC,  0x10,  0x12,  0x10,  0x61,  0xAF,  0x10,  0x80,  0x10,  0x9E,  0x13,  0xF2,  0x7E,  0x52,  0x05,  0x5E, 	/* 4B380 */
+	0x09,  0x92,  0x0B,  0xF2,  0x10,  0x9E,  0x34,  0x92,  0x5B,  0xF2,  0x14,  0x9E,  0x11,  0xCC,  0x12,  0xB4, 	/* 4B390 */
+	0x14,  0x95,  0x10,  0xA5,  0x10,  0xC3,  0xB2,  0x04,  0x40,  0x3F,  0x7E,  0x12,  0x40,  0x7F,  0xFC,  0x11, 	/* 4B3A0 */
+	0x04,  0x1F,  0x7C,  0x11,  0x40,  0x1F,  0x7C,  0x11,  0x42,  0x13,  0x3E,  0x11,  0x00,  0x7F,  0xFF,  0x02, 	/* 4B3B0 */
+	0x84,  0x7C,  0x48,  0x07,  0x30,  0x38,  0x0E,  0xB4,  0x10,  0x00,  0x13,  0xDE,  0x12,  0x52,  0x7F,  0xDE, 	/* 4B3C0 */
+	0x06,  0x52,  0x0B,  0xDE,  0x0A,  0x22,  0x12,  0xFA,  0x36,  0x22,  0x5A,  0xFA,  0x16,  0xEA,  0x12,  0xBA, 	/* 4B3D0 */
+	0x12,  0xFA,  0x12,  0x72,  0x12,  0xAA,  0x12,  0x26,  0xB7,  0x08,  0x30,  0x08,  0xDE,  0x08,  0x9A,  0x7E, 	/* 4B3E0 */
+	0xEE,  0x02,  0xAA,  0x05,  0xFF,  0x04,  0x44,  0x0A,  0x8A,  0x1B,  0x71,  0x2C,  0x10,  0x4A,  0xFE,  0x08, 	/* 4B3F0 */
+	0x10,  0x09,  0xFF,  0x08,  0x10,  0x08,  0x10,  0x08,  0x30,  0xBE,  0x00,  0x00,  0x7F,  0xFF,  0x02,  0x20, 	/* 4B400 */
+	0x02,  0x20,  0x02,  0x20,  0x3F,  0xFE,  0x22,  0x22,  0x22,  0x22,  0x22,  0x22,  0x22,  0x22,  0x22,  0x22, 	/* 4B410 */
+	0x23,  0xE2,  0x20,  0x02,  0x20,  0x02,  0x20,  0x02,  0x20,  0x02,  0xBF,  0x00,  0x00,  0x7F,  0xFF,  0x02, 	/* 4B420 */
+	0x20,  0x02,  0x20,  0x02,  0x20,  0x3F,  0xFE,  0x22,  0x22,  0x22,  0x22,  0x22,  0x22,  0x24,  0x22,  0x24, 	/* 4B430 */
+	0x1E,  0x28,  0x02,  0x30,  0x02,  0x20,  0x02,  0x3F,  0xFE,  0x00,  0x00,  0x81,  0x00,  0x00,  0x7F,  0xFE, 	/* 4B440 */
+	0x02,  0x40,  0x02,  0x40,  0x1F,  0xF8,  0x12,  0x48,  0x12,  0x48,  0x1F,  0xF8,  0x01,  0x00,  0x7F,  0xFF, 	/* 4B450 */
+	0x02,  0x20,  0x04,  0x20,  0x0F,  0x40,  0x00,  0xE0,  0x03,  0x18,  0x3C,  0x04,  0x83,  0x00,  0x00,  0x7F, 	/* 4B460 */
+	0xFF,  0x02,  0x20,  0x1F,  0xFC,  0x12,  0x24,  0x13,  0xE4,  0x00,  0x00,  0x0F,  0xF8,  0x08,  0x08,  0x0F, 	/* 4B470 */
+	0xF8,  0x08,  0x08,  0x0F,  0xF8,  0x00,  0x80,  0x7F,  0xFF,  0x00,  0x80,  0x00,  0x80,  0x86,  0x00,  0x00, 	/* 4B480 */
+	0x7F,  0xFF,  0x02,  0x40,  0x3F,  0xFC,  0x22,  0x44,  0x3F,  0xFC,  0x08,  0x80,  0x10,  0xFE,  0x25,  0x84, 	/* 4B490 */
+	0x46,  0xFC,  0x08,  0x20,  0x18,  0x7C,  0x2B,  0xC8,  0x48,  0x30,  0x08,  0xCC,  0x0B,  0x03,  0x87,  0x00, 	/* 4B4A0 */
+	0x00,  0x7F,  0xFF,  0x02,  0x20,  0x3F,  0xFE,  0x22,  0x22,  0x3F,  0xFE,  0x11,  0x00,  0x7F,  0xBE,  0x11, 	/* 4B4B0 */
+	0x22,  0x1F,  0x22,  0x04,  0x3E,  0x3F,  0xA2,  0x24,  0xBE,  0x7F,  0xE2,  0x04,  0x22,  0x04,  0x46,  0x88, 	/* 4B4C0 */
+	0x00,  0x00,  0x7F,  0xFF,  0x02,  0x20,  0x3F,  0xFE,  0x22,  0x22,  0x23,  0xE2,  0x08,  0x10,  0x1F,  0x1F, 	/* 4B4D0 */
+	0x11,  0x24,  0x1F,  0x64,  0x11,  0x14,  0x7F,  0xD8,  0x08,  0x0C,  0x0F,  0x14,  0x11,  0x62,  0x26,  0x81, 	/* 4B4E0 */
+	0x8A,  0x00,  0x00,  0x7F,  0xFF,  0x02,  0x20,  0x3F,  0xFE,  0x22,  0x22,  0x23,  0xE2,  0x14,  0x00,  0x7F, 	/* 4B4F0 */
+	0x7F,  0x14,  0x48,  0x1C,  0x7E,  0x3E,  0x48,  0x2A,  0x7F,  0x3E,  0x09,  0x08,  0xD5,  0x7E,  0xA9,  0x09, 	/* 4B500 */
+	0x06,  0x8B,  0x00,  0x00,  0x07,  0xF8,  0x04,  0x08,  0x04,  0x08,  0x07,  0xF8,  0x04,  0x08,  0x04,  0x08, 	/* 4B510 */
+	0x07,  0xF8,  0x04,  0x08,  0x04,  0x08,  0x07,  0xF8,  0x01,  0x20,  0x01,  0x20,  0x02,  0x21,  0x0C,  0x21, 	/* 4B520 */
+	0x70,  0x1F,  0x8F,  0x08,  0x00,  0x08,  0xFC,  0x08,  0x84,  0x3F,  0x84,  0x08,  0xFC,  0x08,  0x84,  0x08, 	/* 4B530 */
+	0x84,  0x7F,  0xFC,  0x08,  0x84,  0x0C,  0x84,  0x14,  0xFC,  0x12,  0x50,  0x12,  0x50,  0x20,  0x91,  0x21, 	/* 4B540 */
+	0x09,  0x46,  0x07,  0x93,  0x00,  0x0C,  0x00,  0x70,  0x1F,  0x88,  0x08,  0x44,  0x08,  0x44,  0x17,  0xFA, 	/* 4B550 */
+	0x14,  0x0A,  0x27,  0xF8,  0x04,  0x08,  0x07,  0xF8,  0x04,  0x08,  0x07,  0xF8,  0x01,  0x20,  0x02,  0x21, 	/* 4B560 */
+	0x0C,  0x21,  0x70,  0x1F,  0x96,  0x08,  0x00,  0x08,  0xFC,  0x08,  0x84,  0x7E,  0x84,  0x02,  0xFC,  0x04, 	/* 4B570 */
+	0x84,  0x04,  0x84,  0x08,  0xFC,  0x0C,  0x84,  0x1A,  0x84,  0x29,  0xFC,  0x48,  0x28,  0x08,  0x28,  0x08, 	/* 4B580 */
+	0x49,  0x08,  0x89,  0x09,  0x07,  0x97,  0x00,  0x00,  0x7F,  0x7E,  0x01,  0x42,  0x01,  0x42,  0x7F,  0x7E, 	/* 4B590 */
+	0x01,  0x42,  0x3D,  0x42,  0x25,  0x7E,  0x25,  0x42,  0x25,  0x42,  0x3D,  0x7E,  0x01,  0x28,  0x01,  0x28, 	/* 4B5A0 */
+	0x01,  0x29,  0x01,  0x49,  0x06,  0x87,  0x98,  0x10,  0x00,  0x10,  0xFC,  0x10,  0x84,  0x1F,  0x84,  0x10, 	/* 4B5B0 */
+	0xFC,  0x10,  0x84,  0x10,  0x84,  0x10,  0xFC,  0x7E,  0x84,  0x42,  0x84,  0x42,  0xFC,  0x42,  0x28,  0x7E, 	/* 4B5C0 */
+	0x28,  0x00,  0x49,  0x01,  0x89,  0x06,  0x07,  0x9A,  0x11,  0x08,  0x08,  0x88,  0x08,  0x90,  0x7F,  0xFE, 	/* 4B5D0 */
+	0x40,  0x02,  0x4F,  0xF2,  0x08,  0x10,  0x0F,  0xF0,  0x08,  0x10,  0x0F,  0xF0,  0x08,  0x10,  0x0F,  0xF0, 	/* 4B5E0 */
+	0x02,  0x40,  0x04,  0x41,  0x18,  0x41,  0x60,  0x3F,  0xA1,  0x00,  0x00,  0x7F,  0x7E,  0x08,  0x42,  0x08, 	/* 4B5F0 */
+	0x42,  0x2A,  0x7E,  0x2A,  0x42,  0x2A,  0x42,  0x2D,  0x7E,  0x59,  0x42,  0x48,  0x42,  0x08,  0x7E,  0x0F, 	/* 4B600 */
+	0x28,  0x18,  0x28,  0x60,  0x49,  0x01,  0x89,  0x06,  0x07,  0xA6,  0x04,  0x00,  0x04,  0x3E,  0x0A,  0x22, 	/* 4B610 */
+	0x09,  0x22,  0x10,  0xBE,  0x3F,  0x62,  0x40,  0x22,  0x3A,  0xBE,  0x2A,  0xA2,  0x3A,  0xA2,  0x2D,  0x3E, 	/* 4B620 */
+	0x2D,  0x18,  0x3D,  0x28,  0x2A,  0xA9,  0x2A,  0xC9,  0x2A,  0x87,  0xA7,  0x3F,  0x90,  0x24,  0x1F,  0x3F, 	/* 4B630 */
+	0x20,  0x21,  0x40,  0x3F,  0x3E,  0x24,  0x00,  0x3F,  0xF8,  0x08,  0x08,  0x0F,  0xF8,  0x08,  0x08,  0x0F, 	/* 4B640 */
+	0xF8,  0x08,  0x08,  0x0F,  0xF8,  0x02,  0x21,  0x0C,  0x21,  0x70,  0x1F,  0xA9,  0x08,  0x00,  0x09,  0x7E, 	/* 4B650 */
+	0x3F,  0x42,  0x0A,  0x42,  0x0A,  0x7E,  0x0C,  0x42,  0x7F,  0xC2,  0x0A,  0x7E,  0x11,  0x42,  0x1F,  0x42, 	/* 4B660 */
+	0x31,  0x7E,  0x5F,  0x18,  0x11,  0x28,  0x11,  0x29,  0x1F,  0x49,  0x01,  0x87,  0xAA,  0x08,  0x00,  0x08, 	/* 4B670 */
+	0x7E,  0x7F,  0x42,  0x22,  0x42,  0x12,  0x7E,  0x14,  0x42,  0x7F,  0x42,  0x08,  0x7E,  0x08,  0x42,  0x7F, 	/* 4B680 */
+	0x42,  0x1C,  0x7E,  0x1A,  0x28,  0x29,  0x28,  0x48,  0x49,  0x08,  0x89,  0x0B,  0x07,  0xAC,  0x08,  0x00, 	/* 4B690 */
+	0x29,  0x7E,  0x29,  0x42,  0x3F,  0x42,  0x00,  0x7E,  0x7F,  0xC2,  0x00,  0x42,  0x3F,  0x7E,  0x21,  0x42, 	/* 4B6A0 */
+	0x3F,  0x42,  0x02,  0x7E,  0x22,  0x28,  0x14,  0x28,  0x13,  0x49,  0x1C,  0x89,  0x61,  0x07,  0xAF,  0x12, 	/* 4B6B0 */
+	0x00,  0x3F,  0xBE,  0x12,  0x22,  0x3F,  0xA2,  0x12,  0x3E,  0x7F,  0xE2,  0x04,  0x22,  0x1F,  0x3E,  0x15, 	/* 4B6C0 */
+	0x22,  0x1F,  0x22,  0x15,  0x3E,  0x15,  0x14,  0x7F,  0xD4,  0x11,  0x25,  0x11,  0x45,  0x13,  0x83,  0xB2, 	/* 4B6D0 */
+	0x12,  0x00,  0x12,  0x7E,  0x7F,  0xC2,  0x12,  0x42,  0x1E,  0x7E,  0x00,  0x42,  0x3F,  0x42,  0x25,  0x7E, 	/* 4B6E0 */
+	0x3F,  0x42,  0x04,  0x42,  0x3F,  0x7E,  0x04,  0x18,  0x3F,  0x28,  0x04,  0x29,  0x07,  0x49,  0x79,  0x87, 	/* 4B6F0 */
+	0xB3,  0x10,  0x00,  0x10,  0x7E,  0x3F,  0x42,  0x28,  0x42,  0x48,  0x7E,  0x7F,  0xC2,  0x12,  0x42,  0x14, 	/* 4B700 */
+	0x7E,  0x3F,  0x42,  0x64,  0x42,  0x3F,  0x7E,  0x24,  0x28,  0x3F,  0x28,  0x24,  0x49,  0x3F,  0x89,  0x21, 	/* 4B710 */
+	0x07,  0xBA,  0x05,  0x5C,  0x18,  0x84,  0x1D,  0x5C,  0x10,  0x84,  0x1D,  0x5C,  0x10,  0x04,  0x3F,  0xFE, 	/* 4B720 */
+	0x24,  0x12,  0x27,  0xF2,  0x04,  0x10,  0x07,  0xF0,  0x04,  0x10,  0x07,  0xF0,  0x01,  0x21,  0x06,  0x21, 	/* 4B730 */
+	0x78,  0x1F,  0xBD,  0x00,  0x10,  0x3F,  0x9F,  0x24,  0x20,  0x3F,  0x5E,  0x21,  0x00,  0x3F,  0x7F,  0x24, 	/* 4B740 */
+	0x55,  0x3F,  0xFF,  0x08,  0x08,  0x0F,  0xF8,  0x08,  0x08,  0x0F,  0xF8,  0x08,  0x08,  0x0F,  0xF9,  0x06, 	/* 4B750 */
+	0x21,  0x78,  0x3F,  0xBF,  0x04,  0x00,  0x7F,  0xBE,  0x04,  0x22,  0x3F,  0xA2,  0x00,  0x3E,  0x7F,  0xA2, 	/* 4B760 */
+	0x52,  0xA2,  0x7F,  0xBE,  0x21,  0x22,  0x3F,  0x22,  0x21,  0x3E,  0x3F,  0x14,  0x21,  0x14,  0x3F,  0x25, 	/* 4B770 */
+	0x11,  0x45,  0x60,  0x83,  0x80,  0x11,  0x00,  0x7F,  0xFE,  0x11,  0x22,  0x3B,  0xA2,  0x2A,  0xBE,  0x3B, 	/* 4B780 */
+	0xA2,  0x10,  0x22,  0x12,  0x3E,  0x1F,  0xA2,  0x24,  0x22,  0x7F,  0x3E,  0x24,  0x14,  0x3F,  0x14,  0x24, 	/* 4B790 */
+	0x25,  0x3F,  0xC5,  0x00,  0x83,  0x92,  0x02,  0x00,  0x03,  0xE0,  0x04,  0x20,  0x18,  0x40,  0x7F,  0xFC, 	/* 4B7A0 */
+	0x10,  0x84,  0x10,  0x84,  0x1F,  0xFC,  0x10,  0x84,  0x10,  0x84,  0x1F,  0xFC,  0x10,  0x04,  0x10,  0x04, 	/* 4B7B0 */
+	0x20,  0x04,  0x20,  0x04,  0x40,  0x0C,  0x9A,  0x08,  0x02,  0x0E,  0x0C,  0x12,  0x78,  0x24,  0x44,  0x7E, 	/* 4B7C0 */
+	0x54,  0x2A,  0x54,  0x2A,  0x54,  0x3E,  0x54,  0x2A,  0x54,  0x2A,  0x54,  0x3E,  0x54,  0x22,  0x5A,  0x22, 	/* 4B7D0 */
+	0x56,  0x22,  0x7A,  0x22,  0x82,  0x47,  0x01,  0x9C,  0x04,  0x20,  0x14,  0x22,  0x17,  0xA4,  0x14,  0x38, 	/* 4B7E0 */
+	0x14,  0x21,  0x1F,  0xA1,  0x71,  0x1F,  0x03,  0xE0,  0x0C,  0x40,  0x3F,  0xFC,  0x08,  0x44,  0x0F,  0xFC, 	/* 4B7F0 */
+	0x08,  0x44,  0x0F,  0xFC,  0x10,  0x04,  0x20,  0x0C,  0x9D,  0x08,  0x02,  0x0E,  0x0C,  0x12,  0x78,  0x24, 	/* 4B800 */
+	0x48,  0x7F,  0x48,  0x29,  0x48,  0x29,  0x7F,  0x3F,  0x48,  0x29,  0x48,  0x29,  0x48,  0x3F,  0x48,  0x21, 	/* 4B810 */
+	0x65,  0x21,  0xC5,  0x21,  0x03,  0x21,  0xF3,  0x43,  0x01,  0xA3,  0x08,  0x00,  0x0E,  0xFE,  0x12,  0x12, 	/* 4B820 */
+	0x24,  0x12,  0x7F,  0x22,  0x29,  0x4C,  0x29,  0x90,  0x3F,  0x50,  0x29,  0x7E,  0x29,  0x90,  0x3F,  0x10, 	/* 4B830 */
+	0x21,  0xFF,  0x21,  0x10,  0x21,  0x10,  0x21,  0x10,  0x43,  0x10,  0xA6,  0x08,  0x10,  0x0F,  0x10,  0x12, 	/* 4B840 */
+	0x10,  0x24,  0x7E,  0x5F,  0x52,  0x15,  0x52,  0x15,  0x52,  0x1F,  0x52,  0x15,  0x7E,  0x15,  0x10,  0x1F, 	/* 4B850 */
+	0x10,  0x11,  0x14,  0x11,  0x12,  0x21,  0x1E,  0x21,  0xF1,  0x43,  0x01,  0xA7,  0x08,  0x44,  0x0E,  0x24, 	/* 4B860 */
+	0x12,  0x28,  0x24,  0xFF,  0x7F,  0x10,  0x29,  0x10,  0x29,  0x10,  0x3F,  0x7E,  0x29,  0x10,  0x29,  0x10, 	/* 4B870 */
+	0x3F,  0x10,  0x21,  0xFF,  0x21,  0x10,  0x21,  0x10,  0x21,  0x10,  0x43,  0x10,  0xB4,  0x08,  0x20,  0x0E, 	/* 4B880 */
+	0x3F,  0x12,  0x40,  0x24,  0xBC,  0x7F,  0x24,  0x29,  0x3C,  0x29,  0x24,  0x3F,  0x3C,  0x29,  0x00,  0x29, 	/* 4B890 */
+	0xFF,  0x3F,  0x20,  0x21,  0x7E,  0x21,  0xAA,  0x21,  0x4A,  0x21,  0x92,  0x43,  0x24,  0xB8,  0x08,  0x00, 	/* 4B8A0 */
+	0x0E,  0xFE,  0x12,  0xAA,  0x24,  0xAA,  0x7E,  0xFE,  0x2A,  0x40,  0x2A,  0x7E,  0x3E,  0xA2,  0x2B,  0xFA, 	/* 4B8B0 */
+	0x2A,  0xAA,  0x3E,  0xFA,  0x22,  0x32,  0x22,  0x2A,  0x23,  0xFA,  0x22,  0x06,  0x46,  0x0C,  0x80,  0x00, 	/* 4B8C0 */
+	0x00,  0x07,  0xF0,  0x00,  0x00,  0x7F,  0xFF,  0x00,  0x00,  0x0F,  0xF8,  0x00,  0x00,  0x00,  0x00,  0x0F, 	/* 4B8D0 */
+	0xF8,  0x00,  0x00,  0x0F,  0xF8,  0x08,  0x08,  0x08,  0x08,  0x08,  0x08,  0x0F,  0xF8,  0x00,  0x00,  0x82, 	/* 4B8E0 */
+	0x00,  0x00,  0x1E,  0x00,  0x00,  0xFF,  0x7F,  0x88,  0x00,  0x08,  0x3F,  0x08,  0x00,  0x08,  0x00,  0x08, 	/* 4B8F0 */
+	0x3F,  0x08,  0x00,  0x08,  0x3F,  0x08,  0x21,  0x08,  0x21,  0x08,  0x21,  0x08,  0x3F,  0x08,  0x00,  0x18, 	/* 4B900 */
+	0x83,  0x00,  0x10,  0x3F,  0x10,  0x00,  0x10,  0x7F,  0x90,  0x00,  0x10,  0x3F,  0x18,  0x00,  0x14,  0x00, 	/* 4B910 */
+	0x12,  0x3F,  0x11,  0x00,  0x11,  0x3F,  0x10,  0x21,  0x10,  0x21,  0x10,  0x21,  0x10,  0x3F,  0x10,  0x00, 	/* 4B920 */
+	0x10,  0x88,  0x00,  0x10,  0x3F,  0x10,  0x00,  0x10,  0x7F,  0x90,  0x00,  0x10,  0x3F,  0x10,  0x00,  0xFF, 	/* 4B930 */
+	0x00,  0x10,  0x3F,  0x10,  0x00,  0x10,  0x3F,  0x10,  0x21,  0x10,  0x21,  0x10,  0x21,  0x10,  0x3F,  0x10, 	/* 4B940 */
+	0x00,  0x10,  0x8A,  0x00,  0x00,  0x3E,  0xF8,  0x00,  0x48,  0x7F,  0x48,  0x00,  0x48,  0x3E,  0x48,  0x00, 	/* 4B950 */
+	0x48,  0x3E,  0x78,  0x01,  0xC8,  0x00,  0x48,  0x3E,  0x48,  0x22,  0x48,  0x22,  0x89,  0x22,  0x85,  0x3F, 	/* 4B960 */
+	0x05,  0x02,  0x03,  0x8C,  0x00,  0x00,  0x3E,  0x00,  0x00,  0xFE,  0x7F,  0x10,  0x00,  0x10,  0x3E,  0x10, 	/* 4B970 */
+	0x00,  0x10,  0x00,  0x10,  0x3E,  0x10,  0x00,  0x10,  0x3E,  0x10,  0x22,  0x10,  0x22,  0x10,  0x22,  0x10, 	/* 4B980 */
+	0x3F,  0xFF,  0x00,  0x00,  0x8E,  0x00,  0x04,  0x3E,  0x04,  0x00,  0x04,  0x7F,  0x04,  0x00,  0xFF,  0x3E, 	/* 4B990 */
+	0x04,  0x00,  0x04,  0x00,  0x84,  0x3E,  0x44,  0x00,  0x44,  0x3E,  0x04,  0x22,  0x04,  0x22,  0x04,  0x22, 	/* 4B9A0 */
+	0x04,  0x3E,  0x04,  0x00,  0x0C,  0x90,  0x00,  0x00,  0x3E,  0xFE,  0x00,  0x10,  0x7F,  0x10,  0x00,  0x10, 	/* 4B9B0 */
+	0x3E,  0x10,  0x00,  0x10,  0x01,  0xFF,  0x3E,  0x10,  0x00,  0x10,  0x3E,  0x10,  0x22,  0x10,  0x22,  0x10, 	/* 4B9C0 */
+	0x22,  0x10,  0x3E,  0x10,  0x00,  0x10,  0x93,  0x00,  0x02,  0x3E,  0x42,  0x00,  0x52,  0x7F,  0x52,  0x00, 	/* 4B9D0 */
+	0x52,  0x3E,  0x52,  0x00,  0x52,  0x00,  0x52,  0x3E,  0x52,  0x00,  0x52,  0x3E,  0x52,  0x22,  0x52,  0x22, 	/* 4B9E0 */
+	0x52,  0x22,  0x82,  0x3E,  0x82,  0x01,  0x02,  0x96,  0x00,  0x20,  0x3E,  0x20,  0x00,  0x20,  0x7F,  0x7F, 	/* 4B9F0 */
+	0x00,  0x40,  0x3E,  0x40,  0x00,  0xBE,  0x01,  0x04,  0x3E,  0x08,  0x00,  0x10,  0x3E,  0x20,  0x22,  0x20, 	/* 4BA00 */
+	0x22,  0x40,  0x22,  0x41,  0x3E,  0x41,  0x00,  0x3F,  0x97,  0x00,  0x04,  0x3E,  0x18,  0x00,  0xE0,  0x7F, 	/* 4BA10 */
+	0x20,  0x00,  0x20,  0x3E,  0x20,  0x00,  0x27,  0x01,  0xF8,  0x3E,  0x20,  0x00,  0x20,  0x3E,  0x20,  0x22, 	/* 4BA20 */
+	0x20,  0x22,  0x22,  0x22,  0x22,  0x3E,  0x1E,  0x00,  0x00,  0x98,  0x00,  0x00,  0x3E,  0x7E,  0x00,  0x02, 	/* 4BA30 */
+	0x7F,  0x82,  0x00,  0x02,  0x3F,  0x02,  0x00,  0x7E,  0x3F,  0x40,  0x00,  0x40,  0x00,  0x40,  0x3F,  0x40, 	/* 4BA40 */
+	0x21,  0x40,  0x21,  0x41,  0x21,  0x21,  0x3F,  0x1F,  0x00,  0x00,  0x9B,  0x00,  0x50,  0x3E,  0x50,  0x00, 	/* 4BA50 */
+	0x50,  0x7F,  0x92,  0x00,  0x92,  0x3D,  0x94,  0x02,  0x94,  0x00,  0x98,  0x3C,  0xB0,  0x00,  0x90,  0x3E, 	/* 4BA60 */
+	0x90,  0x22,  0x91,  0x22,  0x91,  0x22,  0x91,  0x3E,  0x8F,  0x00,  0x80,  0x9D,  0x00,  0x00,  0x3E,  0x7E, 	/* 4BA70 */
+	0x00,  0x44,  0x7F,  0x44,  0x00,  0x44,  0x3E,  0x44,  0x00,  0x44,  0x01,  0xFF,  0x3E,  0x0C,  0x00,  0x14, 	/* 4BA80 */
+	0x3E,  0x14,  0x22,  0x24,  0x22,  0x44,  0x22,  0x84,  0x3F,  0x04,  0x00,  0x0C,  0x9F,  0x00,  0x38,  0x3E, 	/* 4BA90 */
+	0x08,  0x00,  0x48,  0x7F,  0x48,  0x00,  0x44,  0x3E,  0x84,  0x00,  0xA2,  0x01,  0x21,  0x3E,  0x20,  0x00, 	/* 4BAA0 */
+	0x30,  0x3E,  0x28,  0x22,  0x48,  0x22,  0x44,  0x22,  0x8C,  0x3F,  0xF2,  0x00,  0x02,  0xA3,  0x00,  0x20, 	/* 4BAB0 */
+	0x3E,  0x20,  0x00,  0x20,  0x7F,  0xFC,  0x00,  0x24,  0x3E,  0x24,  0x00,  0x24,  0x00,  0x24,  0x3F,  0xFF, 	/* 4BAC0 */
+	0x00,  0x20,  0x3E,  0x30,  0x22,  0x30,  0x22,  0x48,  0x22,  0x44,  0x3E,  0x82,  0x03,  0x01,  0xA5,  0x00, 	/* 4BAD0 */
+	0x30,  0x3C,  0x10,  0x00,  0x10,  0x7F,  0xFE,  0x00,  0x92,  0x3E,  0x92,  0x00,  0x92,  0x00,  0xAA,  0x3E, 	/* 4BAE0 */
+	0xAA,  0x00,  0xA6,  0x3E,  0xC2,  0x22,  0x82,  0x22,  0x82,  0x22,  0x82,  0x3E,  0x82,  0x00,  0x86,  0xAA, 	/* 4BAF0 */
+	0x00,  0x10,  0x3E,  0x10,  0x00,  0x10,  0x7F,  0xFF,  0x00,  0x20,  0x3E,  0x20,  0x00,  0x20,  0x3E,  0x3E, 	/* 4BB00 */
+	0x00,  0x22,  0x00,  0x22,  0x3E,  0x22,  0x22,  0x42,  0x22,  0x42,  0x22,  0x82,  0x3F,  0x04,  0x02,  0x18, 	/* 4BB10 */
+	0xAD,  0x00,  0x00,  0x3E,  0x7C,  0x00,  0x44,  0x7F,  0x44,  0x00,  0x45,  0x3E,  0x85,  0x01,  0x03,  0x3E, 	/* 4BB20 */
+	0x00,  0x01,  0xFC,  0x00,  0x44,  0x3E,  0x48,  0x22,  0x28,  0x22,  0x10,  0x22,  0x28,  0x3E,  0xC4,  0x03, 	/* 4BB30 */
+	0x03,  0xB1,  0x00,  0x40,  0x3E,  0x40,  0x00,  0x40,  0x7F,  0x7E,  0x00,  0x90,  0x3E,  0x90,  0x01,  0x10, 	/* 4BB40 */
+	0x3E,  0x10,  0x03,  0xFF,  0x00,  0x10,  0x3E,  0x10,  0x22,  0x10,  0x22,  0x10,  0x22,  0x10,  0x3E,  0x10, 	/* 4BB50 */
+	0x00,  0x10,  0xB3,  0x00,  0x00,  0x3E,  0x7E,  0x00,  0x42,  0x7F,  0x42,  0x00,  0x42,  0x3E,  0x42,  0x00, 	/* 4BB60 */
+	0x7E,  0x00,  0x50,  0x3E,  0x50,  0x00,  0x50,  0x3E,  0x48,  0x22,  0x48,  0x22,  0x84,  0x22,  0x84,  0x3E, 	/* 4BB70 */
+	0x82,  0x01,  0x01,  0xB4,  0x00,  0x04,  0x3E,  0x18,  0x00,  0xE0,  0x7F,  0x80,  0x00,  0x80,  0x3E,  0xFF, 	/* 4BB80 */
+	0x00,  0x88,  0x00,  0x88,  0x3E,  0x88,  0x00,  0xB8,  0x3E,  0x8E,  0x22,  0x89,  0x22,  0x88,  0x22,  0x88, 	/* 4BB90 */
+	0x3F,  0x08,  0x02,  0x08,  0xB6,  0x00,  0x00,  0x3D,  0xFF,  0x00,  0x04,  0x7F,  0x04,  0x00,  0x04,  0x3E, 	/* 4BBA0 */
+	0xF4,  0x00,  0x94,  0x00,  0x94,  0x3E,  0x94,  0x00,  0x94,  0x3E,  0xF4,  0x22,  0x04,  0x22,  0x04,  0x22, 	/* 4BBB0 */
+	0x04,  0x3E,  0x04,  0x00,  0x0C,  0xBA,  0x00,  0x10,  0x3E,  0x10,  0x00,  0x28,  0x7F,  0x28,  0x00,  0x44, 	/* 4BBC0 */
+	0x3E,  0x92,  0x01,  0x21,  0x00,  0xC4,  0x3E,  0x08,  0x00,  0x30,  0x3E,  0xC2,  0x22,  0x04,  0x22,  0x08, 	/* 4BBD0 */
+	0x22,  0x30,  0x3E,  0xC0,  0x03,  0x00,  0xBB,  0x00,  0x20,  0x3E,  0x10,  0x00,  0x10,  0x7F,  0xFE,  0x00, 	/* 4BBE0 */
+	0x10,  0x3E,  0x10,  0x00,  0x10,  0x00,  0x10,  0x3E,  0xFE,  0x00,  0x10,  0x3E,  0x10,  0x22,  0x10,  0x22, 	/* 4BBF0 */
+	0x10,  0x22,  0x10,  0x3F,  0xFF,  0x00,  0x00,  0xBC,  0x00,  0x00,  0x3E,  0xFE,  0x00,  0x10,  0x7F,  0x10, 	/* 4BC00 */
+	0x00,  0x10,  0x3E,  0x90,  0x00,  0x90,  0x00,  0x9E,  0x3E,  0x90,  0x00,  0x90,  0x3E,  0x90,  0x22,  0x90, 	/* 4BC10 */
+	0x22,  0x90,  0x22,  0x90,  0x3F,  0xFF,  0x00,  0x00,  0x81,  0x00,  0x10,  0x3E,  0x10,  0x00,  0x10,  0x7F, 	/* 4BC20 */
+	0x10,  0x01,  0xFF,  0x3E,  0x10,  0x00,  0x10,  0x00,  0x10,  0x3E,  0x10,  0x00,  0xFC,  0x3E,  0x84,  0x22, 	/* 4BC30 */
+	0x84,  0x22,  0x84,  0x22,  0x84,  0x3E,  0xFC,  0x00,  0x00,  0x86,  0x00,  0x02,  0x3C,  0x0C,  0x00,  0x78, 	/* 4BC40 */
+	0x7F,  0x48,  0x00,  0x48,  0x3E,  0x48,  0x00,  0x7F,  0x00,  0x48,  0x3E,  0x48,  0x00,  0x44,  0x3E,  0x44, 	/* 4BC50 */
+	0x22,  0x75,  0x22,  0xC5,  0x22,  0x03,  0x3E,  0xFB,  0x00,  0x01,  0x88,  0x00,  0x00,  0x3F,  0xFE,  0x22, 	/* 4BC60 */
+	0x22,  0x22,  0x22,  0x3F,  0xFE,  0x00,  0x00,  0x0F,  0xF8,  0x00,  0x00,  0x7F,  0xFF,  0x00,  0x00,  0x0F, 	/* 4BC70 */
+	0xF8,  0x00,  0x00,  0x0F,  0xF8,  0x08,  0x08,  0x0F,  0xF8,  0x00,  0x00,  0x90,  0x00,  0x40,  0x3E,  0x40, 	/* 4BC80 */
+	0x00,  0x40,  0x7F,  0x7F,  0x00,  0x90,  0x3E,  0x90,  0x01,  0x10,  0x00,  0x1E,  0x3E,  0x10,  0x00,  0x10, 	/* 4BC90 */
+	0x3E,  0x10,  0x22,  0x1E,  0x22,  0x10,  0x22,  0x10,  0x3E,  0x10,  0x00,  0x10,  0x91,  0x00,  0x10,  0x3E, 	/* 4BCA0 */
+	0x10,  0x00,  0x10,  0x7F,  0xFF,  0x00,  0x81,  0x3E,  0x81,  0x00,  0x40,  0x00,  0x44,  0x3E,  0x48,  0x00, 	/* 4BCB0 */
+	0x70,  0x3E,  0x40,  0x22,  0x40,  0x22,  0x40,  0x22,  0x42,  0x3E,  0x22,  0x00,  0x1E,  0x92,  0x00,  0x10, 	/* 4BCC0 */
+	0x3E,  0x10,  0x00,  0x10,  0x7F,  0x24,  0x00,  0x22,  0x3E,  0x4E,  0x01,  0xF1,  0x00,  0x01,  0x3E,  0x00, 	/* 4BCD0 */
+	0x00,  0x7E,  0x3E,  0x42,  0x22,  0x42,  0x22,  0x42,  0x22,  0x42,  0x3E,  0x7E,  0x00,  0x00,  0x94,  0x00, 	/* 4BCE0 */
+	0x00,  0x3D,  0xFE,  0x00,  0x22,  0x7F,  0x22,  0x00,  0x22,  0x3E,  0x42,  0x00,  0x42,  0x3E,  0x8C,  0x01, 	/* 4BCF0 */
+	0x00,  0x00,  0x7E,  0x3E,  0x42,  0x22,  0x42,  0x22,  0x42,  0x22,  0x42,  0x3E,  0x7E,  0x00,  0x00,  0x95, 	/* 4BD00 */
+	0x00,  0x00,  0x3E,  0xFE,  0x00,  0x12,  0x7F,  0x92,  0x00,  0x94,  0x3E,  0x54,  0x00,  0x58,  0x00,  0x50, 	/* 4BD10 */
+	0x3F,  0xFF,  0x00,  0x10,  0x3E,  0x10,  0x22,  0x10,  0x22,  0x10,  0x22,  0x10,  0x3E,  0x10,  0x00,  0x10, 	/* 4BD20 */
+	0x9B,  0x00,  0x00,  0x3E,  0x7C,  0x00,  0x44,  0x7F,  0x44,  0x00,  0x44,  0x3E,  0x7C,  0x00,  0x44,  0x00, 	/* 4BD30 */
+	0x44,  0x3E,  0x44,  0x00,  0x44,  0x3E,  0x7C,  0x22,  0x44,  0x22,  0x44,  0x22,  0x44,  0x3F,  0xFF,  0x00, 	/* 4BD40 */
+	0x00,  0x9E,  0x00,  0x00,  0x3E,  0xFE,  0x00,  0x02,  0x7F,  0x02,  0x00,  0xFA,  0x3E,  0x02,  0x00,  0x02, 	/* 4BD50 */
+	0x00,  0xF2,  0x3E,  0x92,  0x00,  0x92,  0x3E,  0x92,  0x22,  0xF2,  0x22,  0x02,  0x22,  0x02,  0x3E,  0x02, 	/* 4BD60 */
+	0x00,  0x0C,  0xA0,  0x00,  0x40,  0x3C,  0x20,  0x00,  0x10,  0x7E,  0x02,  0x00,  0xE2,  0x3C,  0x22,  0x00, 	/* 4BD70 */
+	0x34,  0x03,  0xF4,  0x3C,  0x68,  0x00,  0x68,  0x3C,  0xA4,  0x24,  0xA4,  0x25,  0x22,  0x26,  0x21,  0x3C, 	/* 4BD80 */
+	0x20,  0x00,  0x60,  0xA2,  0x00,  0x20,  0x3E,  0x20,  0x00,  0x3E,  0x7F,  0x42,  0x00,  0x82,  0x3F,  0xF2, 	/* 4BD90 */
+	0x00,  0x92,  0x00,  0x92,  0x3E,  0xF2,  0x00,  0x92,  0x3E,  0x92,  0x22,  0xF2,  0x22,  0x02,  0x22,  0x02, 	/* 4BDA0 */
+	0x3E,  0x04,  0x00,  0x18,  0xA3,  0x00,  0x40,  0x3E,  0x46,  0x00,  0x78,  0x7F,  0x40,  0x00,  0x41,  0x3E, 	/* 4BDB0 */
+	0x41,  0x00,  0x3F,  0x00,  0x00,  0x3E,  0x7E,  0x00,  0x42,  0x3E,  0x42,  0x22,  0x7E,  0x22,  0x42,  0x22, 	/* 4BDC0 */
+	0x42,  0x3E,  0x7E,  0x00,  0x00,  0xA6,  0x00,  0x08,  0x3E,  0x0C,  0x00,  0x0A,  0x7F,  0x08,  0x00,  0xFF, 	/* 4BDD0 */
+	0x3E,  0x08,  0x00,  0x08,  0x01,  0xF8,  0x3E,  0x48,  0x00,  0x48,  0x3E,  0x48,  0x22,  0x54,  0x22,  0x65, 	/* 4BDE0 */
+	0x23,  0x85,  0x3E,  0x03,  0x00,  0x01,  0xA9,  0x00,  0x10,  0x3E,  0x10,  0x00,  0xFE,  0x7F,  0x10,  0x00, 	/* 4BDF0 */
+	0x10,  0x3E,  0x10,  0x01,  0xFF,  0x00,  0x04,  0x3E,  0x04,  0x01,  0xFF,  0x3E,  0x84,  0x22,  0x44,  0x22, 	/* 4BE00 */
+	0x44,  0x22,  0x04,  0x3E,  0x04,  0x00,  0x0C,  0xAB,  0x00,  0x10,  0x3E,  0x10,  0x01,  0xFF,  0x7F,  0x01, 	/* 4BE10 */
+	0x01,  0x05,  0x3E,  0x18,  0x01,  0xE0,  0x00,  0x20,  0x3E,  0x20,  0x00,  0x3F,  0x3F,  0xE0,  0x22,  0x20, 	/* 4BE20 */
+	0x22,  0x20,  0x22,  0x21,  0x3E,  0x11,  0x00,  0x0F,  0xAC,  0x00,  0x02,  0x3E,  0x0C,  0x00,  0xF0,  0x7F, 	/* 4BE30 */
+	0x80,  0x00,  0x80,  0x3E,  0xFF,  0x00,  0x80,  0x00,  0x80,  0x3E,  0xBE,  0x00,  0xA2,  0x3E,  0xA2,  0x22, 	/* 4BE40 */
+	0xA2,  0x23,  0x22,  0x22,  0x22,  0x3E,  0x3E,  0x00,  0x00,  0xAD,  0x00,  0x20,  0x3C,  0x3C,  0x00,  0x48, 	/* 4BE50 */
+	0x7E,  0x90,  0x01,  0xFF,  0x3C,  0x80,  0x00,  0x80,  0x00,  0xBC,  0x3C,  0xA4,  0x00,  0xA4,  0x3C,  0xA4, 	/* 4BE60 */
+	0x24,  0xAC,  0x25,  0x20,  0x25,  0x21,  0x3E,  0x21,  0x00,  0x1F,  0xAE,  0x00,  0x10,  0x3E,  0x10,  0x00, 	/* 4BE70 */
+	0x28,  0x7F,  0x44,  0x00,  0x82,  0x3F,  0x01,  0x00,  0xFE,  0x00,  0x10,  0x3E,  0x10,  0x00,  0x10,  0x3E, 	/* 4BE80 */
+	0xFE,  0x22,  0x10,  0x22,  0x10,  0x22,  0x10,  0x3F,  0xFF,  0x00,  0x00,  0xB0,  0x00,  0x20,  0x3E,  0x20, 	/* 4BE90 */
+	0x00,  0x20,  0x7F,  0xFF,  0x00,  0x20,  0x3E,  0x20,  0x00,  0x20,  0x01,  0xFE,  0x3E,  0x00,  0x00,  0x00, 	/* 4BEA0 */
+	0x3E,  0xFC,  0x22,  0x84,  0x22,  0x84,  0x22,  0x84,  0x3E,  0xFC,  0x00,  0x00,  0xB1,  0x00,  0x04,  0x3E, 	/* 4BEB0 */
+	0x18,  0x00,  0xF0,  0x7F,  0x10,  0x00,  0x10,  0x3E,  0x10,  0x01,  0xFF,  0x3E,  0x10,  0x00,  0x10,  0x00, 	/* 4BEC0 */
+	0x10,  0x3E,  0xFE,  0x22,  0x82,  0x22,  0x82,  0x22,  0x82,  0x3E,  0xFE,  0x00,  0x00,  0xB2,  0x00,  0x10, 	/* 4BED0 */
+	0x3E,  0x10,  0x00,  0x10,  0x7F,  0xFF,  0x00,  0x10,  0x3E,  0x14,  0x00,  0xE4,  0x00,  0x28,  0x3E,  0x1A, 	/* 4BEE0 */
+	0x00,  0x12,  0x3E,  0x24,  0x22,  0x44,  0x22,  0x88,  0x22,  0x14,  0x3E,  0x62,  0x01,  0x82,  0xB3,  0x00, 	/* 4BEF0 */
+	0x84,  0x3E,  0x44,  0x00,  0x48,  0x7F,  0xFE,  0x00,  0x10,  0x3E,  0x10,  0x00,  0x10,  0x00,  0xFE,  0x3E, 	/* 4BF00 */
+	0x10,  0x00,  0x10,  0x3E,  0x10,  0x23,  0xFF,  0x22,  0x10,  0x22,  0x10,  0x3E,  0x10,  0x00,  0x10,  0xBC, 	/* 4BF10 */
+	0x00,  0x40,  0x3E,  0x40,  0x01,  0xFF,  0x7E,  0x48,  0x00,  0x4A,  0x3E,  0x5A,  0x00,  0x5A,  0x00,  0x5C, 	/* 4BF20 */
+	0x3E,  0x68,  0x00,  0x48,  0x3E,  0x8C,  0x22,  0x94,  0x23,  0x14,  0x22,  0x14,  0x3E,  0x22,  0x00,  0x41, 	/* 4BF30 */
+	0x82,  0x00,  0x50,  0x3C,  0x50,  0x00,  0x52,  0x7E,  0x52,  0x01,  0x54,  0x3D,  0x54,  0x00,  0x50,  0x00, 	/* 4BF40 */
+	0x58,  0x3C,  0xD4,  0x01,  0x52,  0x3E,  0x50,  0x24,  0x50,  0x24,  0x91,  0x24,  0x91,  0x3D,  0x0F,  0x06, 	/* 4BF50 */
+	0x00,  0x84,  0x00,  0x10,  0x3E,  0x12,  0x00,  0xFC,  0x7F,  0x10,  0x00,  0x10,  0x3E,  0xFE,  0x00,  0x10, 	/* 4BF60 */
+	0x00,  0x10,  0x3F,  0xFF,  0x00,  0x38,  0x3E,  0x34,  0x22,  0x54,  0x22,  0x52,  0x22,  0x91,  0x3F,  0x10, 	/* 4BF70 */
+	0x00,  0x10,  0x85,  0x00,  0x10,  0x3E,  0x50,  0x00,  0x50,  0x7F,  0x7E,  0x00,  0x90,  0x3E,  0x90,  0x01, 	/* 4BF80 */
+	0x10,  0x01,  0xFF,  0x3E,  0x38,  0x00,  0x38,  0x3E,  0x54,  0x22,  0x54,  0x22,  0x92,  0x23,  0x11,  0x3E, 	/* 4BF90 */
+	0x10,  0x00,  0x10,  0x87,  0x00,  0x10,  0x3E,  0x10,  0x00,  0xFF,  0x7F,  0x28,  0x00,  0x24,  0x3E,  0x42, 	/* 4BFA0 */
+	0x00,  0xFD,  0x01,  0x00,  0x3E,  0xFF,  0x00,  0x10,  0x3E,  0x10,  0x22,  0x3E,  0x22,  0x22,  0x22,  0x02, 	/* 4BFB0 */
+	0x3E,  0x02,  0x00,  0x0C,  0x89,  0x11,  0x08,  0x08,  0x90,  0x7F,  0xFF,  0x08,  0x10,  0x0B,  0xD0,  0x08, 	/* 4BFC0 */
+	0x08,  0x1F,  0xFC,  0x10,  0x02,  0x27,  0xE1,  0x40,  0x00,  0x07,  0xE0,  0x00,  0x00,  0x0F,  0xF0,  0x08, 	/* 4BFD0 */
+	0x10,  0x0F,  0xF0,  0x08,  0x10,  0x8C,  0x00,  0x10,  0x3E,  0x10,  0x00,  0x10,  0x7F,  0xFF,  0x00,  0x10, 	/* 4BFE0 */
+	0x3E,  0x10,  0x00,  0x10,  0x00,  0xFE,  0x3E,  0x10,  0x00,  0x08,  0x3E,  0xA8,  0x22,  0xA2,  0x22,  0xA1, 	/* 4BFF0 */
+	0x22,  0xA5,  0x3F,  0x24,  0x02,  0x1C,  0x8D,  0x00,  0x00,  0x3E,  0xFE,  0x00,  0x12,  0x7F,  0x52,  0x00, 	/* 4C000 */
+	0x22,  0x3E,  0x32,  0x00,  0x52,  0x01,  0x8C,  0x3E,  0x20,  0x00,  0x10,  0x3E,  0x28,  0x22,  0xAA,  0x22, 	/* 4C010 */
+	0xA1,  0x22,  0xA5,  0x3F,  0x25,  0x02,  0x1C,  0x91,  0x02,  0x40,  0x3D,  0x7F,  0x01,  0xC8,  0x7E,  0x88, 	/* 4C020 */
+	0x00,  0x88,  0x3D,  0x88,  0x01,  0x48,  0x02,  0x7E,  0x3C,  0x48,  0x00,  0xC8,  0x3D,  0x48,  0x26,  0x48, 	/* 4C030 */
+	0x24,  0x48,  0x24,  0x48,  0x3C,  0xBF,  0x03,  0x00,  0x93,  0x08,  0x0C,  0x7E,  0xF0,  0x08,  0x80,  0x0C, 	/* 4C040 */
+	0xFF,  0x78,  0x88,  0x09,  0x08,  0x1B,  0xE8,  0x00,  0x00,  0x7F,  0xFF,  0x00,  0x00,  0x07,  0xF0,  0x00, 	/* 4C050 */
+	0x00,  0x0F,  0xF8,  0x08,  0x08,  0x0F,  0xF8,  0x00,  0x00,  0x95,  0x00,  0x01,  0x3D,  0xC6,  0x00,  0x5C, 	/* 4C060 */
+	0x7E,  0x44,  0x00,  0x84,  0x3D,  0x14,  0x03,  0xD7,  0x00,  0x54,  0x3C,  0x54,  0x02,  0x54,  0x3D,  0x54, 	/* 4C070 */
+	0x24,  0x94,  0x24,  0xFF,  0x25,  0x20,  0x3E,  0x18,  0x04,  0x07,  0x98,  0x00,  0x02,  0x3C,  0x1C,  0x00, 	/* 4C080 */
+	0xF0,  0x7E,  0x10,  0x01,  0xFF,  0x3E,  0x38,  0x00,  0x54,  0x3E,  0x92,  0x01,  0x11,  0x00,  0xF8,  0x3E, 	/* 4C090 */
+	0x28,  0x22,  0x2E,  0x22,  0x22,  0x22,  0x42,  0x3E,  0x42,  0x00,  0x8C,  0x9A,  0x00,  0x10,  0x3E,  0x54, 	/* 4C0A0 */
+	0x00,  0x52,  0x7F,  0x92,  0x00,  0x91,  0x3D,  0x7F,  0x00,  0x42,  0x00,  0x42,  0x3E,  0x7E,  0x00,  0x42, 	/* 4C0B0 */
+	0x3E,  0x42,  0x22,  0x7E,  0x22,  0x42,  0x22,  0x42,  0x3E,  0x42,  0x00,  0x46,  0x9E,  0x00,  0x00,  0x3E, 	/* 4C0C0 */
+	0xFE,  0x00,  0x10,  0x7F,  0x10,  0x00,  0xFC,  0x3E,  0x24,  0x00,  0x24,  0x3E,  0x24,  0x01,  0xFF,  0x00, 	/* 4C0D0 */
+	0x00,  0x3E,  0x7E,  0x22,  0x42,  0x22,  0x42,  0x22,  0x42,  0x3E,  0x7E,  0x00,  0x00,  0xA0,  0x00,  0x08, 	/* 4C0E0 */
+	0x3E,  0x0A,  0x00,  0x09,  0x7F,  0xFF,  0x00,  0x88,  0x3E,  0x88,  0x00,  0xEA,  0x00,  0xAA,  0x3E,  0xAA, 	/* 4C0F0 */
+	0x00,  0xAC,  0x3E,  0xA4,  0x22,  0xA4,  0x22,  0xED,  0x22,  0x95,  0x3F,  0x23,  0x02,  0x41,  0xA1,  0x00, 	/* 4C100 */
+	0x14,  0x3C,  0x12,  0x00,  0x10,  0x7F,  0xFF,  0x00,  0x10,  0x3D,  0x52,  0x01,  0x52,  0x01,  0x52,  0x3F, 	/* 4C110 */
+	0xF4,  0x01,  0x4C,  0x3D,  0x48,  0x25,  0x48,  0x25,  0x55,  0x26,  0x25,  0x3C,  0x43,  0x00,  0x01,  0xA3, 	/* 4C120 */
+	0x00,  0x00,  0x3C,  0x00,  0x01,  0xFE,  0x7E,  0x20,  0x00,  0xA4,  0x3C,  0xA4,  0x00,  0xA4,  0x00,  0xA4, 	/* 4C130 */
+	0x3D,  0x6A,  0x01,  0x6A,  0x3E,  0x31,  0x24,  0x20,  0x24,  0x20,  0x24,  0x20,  0x3D,  0xFF,  0x00,  0x00, 	/* 4C140 */
+	0xA4,  0x00,  0x00,  0x3E,  0xBC,  0x00,  0xA4,  0x7F,  0xA4,  0x00,  0xA4,  0x3E,  0xBC,  0x00,  0x80,  0x00, 	/* 4C150 */
+	0x80,  0x3E,  0xFC,  0x00,  0x04,  0x3E,  0x04,  0x23,  0xFF,  0x22,  0x08,  0x22,  0x44,  0x3E,  0x42,  0x00, 	/* 4C160 */
+	0x82,  0xA5,  0x00,  0x10,  0x3E,  0x50,  0x00,  0x50,  0x7F,  0x7E,  0x00,  0x90,  0x3D,  0x10,  0x00,  0x10, 	/* 4C170 */
+	0x01,  0xFF,  0x3E,  0x10,  0x00,  0x00,  0x3E,  0x7E,  0x22,  0x42,  0x22,  0x42,  0x22,  0x42,  0x3E,  0x7E, 	/* 4C180 */
+	0x00,  0x00,  0xA6,  0x00,  0x00,  0x3E,  0xFE,  0x00,  0x04,  0x7F,  0x68,  0x00,  0x10,  0x3E,  0xFE,  0x00, 	/* 4C190 */
+	0x92,  0x00,  0x92,  0x3E,  0xFE,  0x00,  0x92,  0x3E,  0x92,  0x22,  0xFE,  0x22,  0x92,  0x22,  0x92,  0x3E, 	/* 4C1A0 */
+	0x92,  0x00,  0x96,  0xA8,  0x00,  0x40,  0x3C,  0x40,  0x00,  0xFE,  0x7E,  0x80,  0x01,  0x00,  0x3E,  0xFC, 	/* 4C1B0 */
+	0x00,  0xA4,  0x00,  0x94,  0x3F,  0xFF,  0x01,  0x04,  0x3D,  0x44,  0x25,  0x24,  0x25,  0xFF,  0x24,  0x04, 	/* 4C1C0 */
+	0x3C,  0x08,  0x00,  0x30,  0xAC,  0x00,  0x84,  0x1C,  0x44,  0x00,  0x44,  0x7F,  0x28,  0x00,  0xFC,  0x3E, 	/* 4C1D0 */
+	0x84,  0x00,  0x84,  0x3E,  0x84,  0x00,  0xFC,  0x00,  0x28,  0x3E,  0x28,  0x22,  0x28,  0x22,  0x48,  0x22, 	/* 4C1E0 */
+	0x49,  0x3E,  0x89,  0x01,  0x07,  0xAD,  0x00,  0x10,  0x3E,  0x10,  0x01,  0xFF,  0x7E,  0x10,  0x00,  0x10, 	/* 4C1F0 */
+	0x3E,  0xFE,  0x00,  0x00,  0x00,  0xFF,  0x3E,  0x81,  0x00,  0xA9,  0x3E,  0x28,  0x22,  0x28,  0x22,  0x48, 	/* 4C200 */
+	0x22,  0x49,  0x3E,  0x89,  0x03,  0x07,  0xB0,  0x00,  0x24,  0x3E,  0x24,  0x00,  0x48,  0x7F,  0x7F,  0x00, 	/* 4C210 */
+	0xC8,  0x3E,  0xC8,  0x01,  0x48,  0x00,  0x7E,  0x3E,  0x48,  0x00,  0x48,  0x3E,  0x7E,  0x22,  0x48,  0x22, 	/* 4C220 */
+	0x48,  0x22,  0x48,  0x3E,  0x7F,  0x00,  0x00,  0xB2,  0x00,  0x00,  0x3E,  0xFE,  0x00,  0x92,  0x7F,  0x92, 	/* 4C230 */
+	0x00,  0xFE,  0x3E,  0x92,  0x00,  0x92,  0x00,  0xFE,  0x3E,  0x10,  0x01,  0xFF,  0x3E,  0x38,  0x22,  0x54, 	/* 4C240 */
+	0x22,  0x54,  0x22,  0x92,  0x3F,  0x11,  0x00,  0x10,  0xB9,  0x00,  0x48,  0x3C,  0x48,  0x00,  0x48,  0x7F, 	/* 4C250 */
+	0xCF,  0x00,  0x48,  0x3C,  0x48,  0x00,  0x48,  0x01,  0xCF,  0x3C,  0x48,  0x00,  0x48,  0x3C,  0xC8,  0x27, 	/* 4C260 */
+	0x4F,  0x24,  0x48,  0x24,  0x88,  0x3C,  0x88,  0x01,  0x08,  0xBC,  0x00,  0x20,  0x3C,  0x20,  0x01,  0xFE, 	/* 4C270 */
+	0x7F,  0x02,  0x01,  0x02,  0x3C,  0xFC,  0x00,  0x84,  0x00,  0x84,  0x3C,  0xFC,  0x00,  0x84,  0x3C,  0x84, 	/* 4C280 */
+	0x24,  0xFC,  0x24,  0x84,  0x24,  0x84,  0x3F,  0xFF,  0x00,  0x00,  0xBF,  0x00,  0x00,  0x3E,  0xFE,  0x00, 	/* 4C290 */
+	0x92,  0x7F,  0x92,  0x00,  0xFE,  0x3E,  0x92,  0x00,  0x92,  0x00,  0xFE,  0x3E,  0x82,  0x00,  0xBA,  0x3E, 	/* 4C2A0 */
+	0xAA,  0x22,  0xAA,  0x22,  0xBA,  0x23,  0x02,  0x3F,  0x02,  0x02,  0x06,  0x82,  0x00,  0x20,  0x3E,  0x20, 	/* 4C2B0 */
+	0x00,  0x3E,  0x7F,  0x42,  0x00,  0x42,  0x3E,  0x82,  0x01,  0x0C,  0x00,  0x20,  0x3E,  0x20,  0x00,  0xCE, 	/* 4C2C0 */
+	0x3E,  0x82,  0x22,  0xEE,  0x22,  0x82,  0x22,  0x82,  0x3E,  0xFE,  0x00,  0x00,  0x84,  0x00,  0x10,  0x3E, 	/* 4C2D0 */
+	0x10,  0x00,  0xFF,  0x7F,  0x00,  0x00,  0x7C,  0x3E,  0x44,  0x00,  0x7C,  0x00,  0x00,  0x3E,  0xFC,  0x00, 	/* 4C2E0 */
+	0x08,  0x3E,  0x10,  0x23,  0xFF,  0x22,  0x10,  0x22,  0x10,  0x3E,  0x10,  0x00,  0x30,  0x87,  0x00,  0x10, 	/* 4C2F0 */
+	0x3E,  0x52,  0x00,  0x52,  0x7F,  0x54,  0x00,  0xA8,  0x3E,  0x28,  0x00,  0x44,  0x3E,  0x92,  0x00,  0x11, 	/* 4C300 */
+	0x00,  0x52,  0x3E,  0x52,  0x22,  0x9C,  0x22,  0x28,  0x22,  0x44,  0x3E,  0x82,  0x03,  0x01,  0x8B,  0x00, 	/* 4C310 */
+	0x10,  0x3E,  0x10,  0x00,  0xFE,  0x7F,  0x10,  0x00,  0xFE,  0x3E,  0x10,  0x01,  0xFF,  0x00,  0x00,  0x3E, 	/* 4C320 */
+	0x7C,  0x00,  0x44,  0x3E,  0x7C,  0x22,  0x44,  0x22,  0x7C,  0x22,  0x44,  0x3E,  0x44,  0x00,  0x4C,  0x8C, 	/* 4C330 */
+	0x00,  0x10,  0x3C,  0x10,  0x01,  0xFF,  0x7F,  0x10,  0x00,  0xFC,  0x3E,  0x94,  0x00,  0x94,  0x00,  0xFC, 	/* 4C340 */
+	0x3E,  0x94,  0x00,  0x94,  0x3E,  0xFC,  0x22,  0x38,  0x22,  0x54,  0x22,  0x92,  0x3F,  0x11,  0x22,  0x10, 	/* 4C350 */
+	0x8D,  0x00,  0x04,  0x3C,  0x18,  0x01,  0xE4,  0x7E,  0x92,  0x00,  0x91,  0x3D,  0xFD,  0x02,  0x24,  0x00, 	/* 4C360 */
+	0x24,  0x3D,  0xFF,  0x00,  0x24,  0x3C,  0x24,  0x24,  0xFC,  0x24,  0x20,  0x24,  0x20,  0x3C,  0x20,  0x00, 	/* 4C370 */
+	0x60,  0x8F,  0x00,  0x00,  0x3F,  0xFF,  0x01,  0x20,  0x7F,  0x20,  0x01,  0x3E,  0x3D,  0xF2,  0x01,  0x32, 	/* 4C380 */
+	0x01,  0x2A,  0x3D,  0xEA,  0x01,  0x2C,  0x3D,  0x24,  0x25,  0x24,  0x25,  0xEA,  0x27,  0x32,  0x3C,  0x21, 	/* 4C390 */
+	0x00,  0x20,  0x92,  0x00,  0x10,  0x3E,  0x10,  0x01,  0xFF,  0x7F,  0x00,  0x00,  0x00,  0x3E,  0x7C,  0x00, 	/* 4C3A0 */
+	0x44,  0x00,  0x44,  0x3E,  0x44,  0x00,  0x7C,  0x3E,  0x10,  0x22,  0x58,  0x22,  0x54,  0x22,  0x92,  0x3F, 	/* 4C3B0 */
+	0x12,  0x00,  0x30,  0x96,  0x00,  0x20,  0x3C,  0x20,  0x00,  0x50,  0x7E,  0x50,  0x00,  0x88,  0x3D,  0xFC, 	/* 4C3C0 */
+	0x02,  0x02,  0x00,  0x01,  0x3D,  0xFC,  0x01,  0x54,  0x3D,  0x54,  0x25,  0xFC,  0x25,  0x54,  0x25,  0x54, 	/* 4C3D0 */
+	0x3D,  0x54,  0x25,  0x0C,  0x9A,  0x00,  0x10,  0x3C,  0x10,  0x01,  0xFF,  0x7F,  0x01,  0x01,  0x01,  0x3C, 	/* 4C3E0 */
+	0xFE,  0x00,  0x10,  0x00,  0x10,  0x3C,  0x90,  0x00,  0x9E,  0x3C,  0x90,  0x24,  0x90,  0x24,  0x90,  0x25, 	/* 4C3F0 */
+	0x50,  0x3D,  0x30,  0x02,  0x0F,  0x9B,  0x00,  0x10,  0x3E,  0x30,  0x00,  0xD6,  0x7F,  0x92,  0x00,  0x92, 	/* 4C400 */
+	0x3E,  0xD6,  0x00,  0x92,  0x00,  0x92,  0x3E,  0xFE,  0x00,  0x10,  0x3E,  0x18,  0x22,  0x28,  0x22,  0x24, 	/* 4C410 */
+	0x22,  0x44,  0x3E,  0x82,  0x01,  0x01,  0x9C,  0x00,  0x54,  0x3E,  0x54,  0x01,  0xFF,  0x7F,  0x54,  0x00, 	/* 4C420 */
+	0x54,  0x3E,  0x5C,  0x00,  0x40,  0x00,  0x7F,  0x3E,  0x10,  0x00,  0xFF,  0x3E,  0x38,  0x22,  0x34,  0x22, 	/* 4C430 */
+	0x52,  0x22,  0x91,  0x3F,  0x10,  0x22,  0x10,  0x9E,  0x00,  0x00,  0x3D,  0xFF,  0x00,  0x00,  0x7E,  0xFC, 	/* 4C440 */
+	0x00,  0x84,  0x3C,  0x84,  0x00,  0xFC,  0x00,  0x80,  0x3C,  0xFE,  0x01,  0xAA,  0x3D,  0xAA,  0x26,  0xFE, 	/* 4C450 */
+	0x24,  0xAA,  0x24,  0xAA,  0x3C,  0xAA,  0x00,  0x86,  0xA0,  0x00,  0x10,  0x3E,  0x10,  0x00,  0xFF,  0x7F, 	/* 4C460 */
+	0x81,  0x00,  0x81,  0x3E,  0x7E,  0x00,  0x00,  0x00,  0x7E,  0x3E,  0x42,  0x00,  0x42,  0x3E,  0x7E,  0x22, 	/* 4C470 */
+	0x42,  0x22,  0x7E,  0x22,  0x00,  0x3F,  0xFF,  0x00,  0x00,  0xA1,  0x00,  0x58,  0x3C,  0x48,  0x00,  0x44, 	/* 4C480 */
+	0x7E,  0xFC,  0x00,  0xA2,  0x3D,  0x21,  0x02,  0x7C,  0x00,  0x44,  0x3C,  0x04,  0x00,  0x08,  0x3C,  0x30, 	/* 4C490 */
+	0x24,  0xFE,  0x24,  0xAA,  0x24,  0xAA,  0x3F,  0xFF,  0x00,  0x00,  0xA2,  0x00,  0x00,  0x1E,  0xFF,  0x00, 	/* 4C4A0 */
+	0x81,  0x7E,  0x91,  0x01,  0xFE,  0x3E,  0x10,  0x00,  0xFE,  0x00,  0x92,  0x3E,  0xFE,  0x00,  0x92,  0x3E, 	/* 4C4B0 */
+	0x92,  0x22,  0xFE,  0x22,  0x10,  0x23,  0xFF,  0x3E,  0x10,  0x00,  0x10,  0xA4,  0x00,  0x00,  0x3E,  0xEE, 	/* 4C4C0 */
+	0x00,  0xAA,  0x7F,  0xAA,  0x00,  0xEE,  0x3E,  0x00,  0x00,  0xFE,  0x00,  0x00,  0x3F,  0xFF,  0x00,  0x20, 	/* 4C4D0 */
+	0x00,  0x20,  0x3E,  0x7C,  0x22,  0x44,  0x22,  0x04,  0x3E,  0x04,  0x00,  0x18,  0xA6,  0x00,  0x10,  0x3E, 	/* 4C4E0 */
+	0x10,  0x00,  0xFF,  0x7F,  0x44,  0x00,  0x24,  0x3E,  0x28,  0x01,  0xFF,  0x01,  0x11,  0x3F,  0x11,  0x00, 	/* 4C4F0 */
+	0xFE,  0x3E,  0x92,  0x22,  0x92,  0x22,  0x92,  0x22,  0x9C,  0x3E,  0x10,  0x00,  0x10,  0xA7,  0x00,  0x88, 	/* 4C500 */
+	0x3C,  0x89,  0x00,  0xEA,  0x7E,  0x8C,  0x00,  0x89,  0x3C,  0x89,  0x00,  0xE7,  0x03,  0x10,  0x3C,  0x20, 	/* 4C510 */
+	0x00,  0xFC,  0x3C,  0x84,  0x24,  0x84,  0x24,  0xFC,  0x24,  0x84,  0x3C,  0xFC,  0x00,  0x00,  0xAB,  0x00, 	/* 4C520 */
+	0x10,  0x3C,  0x10,  0x01,  0xFF,  0x7E,  0x10,  0x00,  0xFE,  0x3C,  0x92,  0x00,  0xD6,  0x00,  0xBA,  0x3C, 	/* 4C530 */
+	0x92,  0x00,  0xFE,  0x3C,  0x38,  0x24,  0x58,  0x24,  0x94,  0x25,  0x12,  0x3E,  0x11,  0x00,  0x10,  0xAD, 	/* 4C540 */
+	0x00,  0x10,  0x3C,  0x30,  0x00,  0x28,  0x7E,  0x44,  0x00,  0xFE,  0x3D,  0x01,  0x03,  0xE2,  0x01,  0x2A, 	/* 4C550 */
+	0x3D,  0x2A,  0x01,  0xEA,  0x3D,  0x2A,  0x25,  0x2A,  0x25,  0xE2,  0x25,  0x22,  0x3D,  0x22,  0x01,  0x66, 	/* 4C560 */
+	0xAE,  0x00,  0x10,  0x3F,  0x10,  0x00,  0x9F,  0x7F,  0xAA,  0x00,  0x48,  0x3E,  0x08,  0x00,  0x54,  0x00, 	/* 4C570 */
+	0x94,  0x3F,  0x22,  0x00,  0x41,  0x3E,  0xFE,  0x22,  0x42,  0x22,  0x42,  0x22,  0x42,  0x3E,  0x7E,  0x00, 	/* 4C580 */
+	0x00,  0xB1,  0x00,  0x20,  0x3E,  0xFC,  0x00,  0x24,  0x7F,  0x24,  0x01,  0xFF,  0x3E,  0x00,  0x00,  0x7E, 	/* 4C590 */
+	0x00,  0x42,  0x3E,  0x7E,  0x00,  0x08,  0x3E,  0x7E,  0x22,  0x48,  0x22,  0x48,  0x23,  0xFF,  0x3E,  0x08, 	/* 4C5A0 */
+	0x00,  0x08,  0xB3,  0x00,  0x20,  0x3C,  0x20,  0x01,  0xFE,  0x7E,  0x84,  0x00,  0x44,  0x3C,  0x48,  0x03, 	/* 4C5B0 */
+	0xFF,  0x00,  0x00,  0x3C,  0xFC,  0x00,  0x84,  0x3C,  0x84,  0x24,  0xFC,  0x24,  0x84,  0x24,  0x84,  0x3C, 	/* 4C5C0 */
+	0xFC,  0x00,  0x00,  0xB7,  0x00,  0x00,  0x3D,  0xFC,  0x01,  0x04,  0x7F,  0x1C,  0x01,  0xE4,  0x3D,  0x24, 	/* 4C5D0 */
+	0x01,  0xFC,  0x01,  0xAC,  0x3D,  0xAC,  0x01,  0xFC,  0x3D,  0x24,  0x25,  0x35,  0x25,  0x2B,  0x26,  0x3B, 	/* 4C5E0 */
+	0x3E,  0xC5,  0x04,  0x01,  0xB8,  0x00,  0x20,  0x3E,  0x24,  0x00,  0xFC,  0x7F,  0x24,  0x00,  0x28,  0x3E, 	/* 4C5F0 */
+	0x28,  0x01,  0xFF,  0x00,  0x20,  0x3E,  0x7C,  0x00,  0x44,  0x3E,  0xC4,  0x23,  0x7C,  0x22,  0x44,  0x22, 	/* 4C600 */
+	0x44,  0x3E,  0x7C,  0x00,  0x00,  0xBA,  0x00,  0x10,  0x3C,  0x10,  0x01,  0xFF,  0x7E,  0x44,  0x00,  0x28, 	/* 4C610 */
+	0x3C,  0xFF,  0x00,  0x84,  0x00,  0x88,  0x3C,  0xB2,  0x00,  0x84,  0x3C,  0x88,  0x24,  0xB1,  0x25,  0x02, 	/* 4C620 */
+	0x25,  0x0C,  0x3E,  0x30,  0x24,  0xC0,  0xBE,  0x00,  0x44,  0x3E,  0x44,  0x01,  0xFF,  0x7F,  0x44,  0x00, 	/* 4C630 */
+	0x54,  0x3E,  0x10,  0x00,  0x10,  0x01,  0xFF,  0x3E,  0x20,  0x00,  0x20,  0x3E,  0x7E,  0x22,  0xA2,  0x23, 	/* 4C640 */
+	0x22,  0x22,  0x22,  0x3E,  0x3E,  0x00,  0x00,  0x80,  0x00,  0x44,  0x3E,  0x44,  0x00,  0xFF,  0x7F,  0x44, 	/* 4C650 */
+	0x00,  0x7C,  0x3E,  0x44,  0x00,  0x44,  0x00,  0x7C,  0x3E,  0x10,  0x01,  0xFF,  0x3E,  0x38,  0x22,  0x38, 	/* 4C660 */
+	0x22,  0x54,  0x22,  0x92,  0x3F,  0x11,  0x02,  0x10,  0x81,  0x00,  0x00,  0x3C,  0xFC,  0x00,  0x84,  0x7F, 	/* 4C670 */
+	0xFC,  0x00,  0x84,  0x3E,  0x84,  0x00,  0xFC,  0x00,  0x40,  0x3E,  0x7E,  0x00,  0xCA,  0x3E,  0xD2,  0x23, 	/* 4C680 */
+	0x62,  0x22,  0x4A,  0x22,  0x3A,  0x3E,  0x02,  0x00,  0x0C,  0x82,  0x00,  0x00,  0x3E,  0xFE,  0x00,  0x92, 	/* 4C690 */
+	0x7F,  0xFE,  0x00,  0x92,  0x3E,  0x92,  0x00,  0xFE,  0x00,  0x00,  0x3E,  0x7E,  0x00,  0x42,  0x3E,  0x7E, 	/* 4C6A0 */
+	0x22,  0x42,  0x22,  0x7E,  0x22,  0x42,  0x3E,  0x42,  0x22,  0x46,  0x84,  0x01,  0x44,  0x3C,  0xA8,  0x27, 	/* 4C6B0 */
+	0xFE,  0x24,  0x50,  0x27,  0xFF,  0x3C,  0x88,  0x25,  0x74,  0x26,  0x02,  0x27,  0xFD,  0x3C,  0x00,  0x24, 	/* 4C6C0 */
+	0xF8,  0x24,  0x00,  0x25,  0xFC,  0x25,  0x04,  0x25,  0xFC,  0x4C,  0x00,  0x87,  0x00,  0x80,  0x7F,  0xFE, 	/* 4C6D0 */
+	0x42,  0x22,  0x5F,  0xFA,  0x02,  0x20,  0x0F,  0xF8,  0x02,  0x20,  0x7F,  0xFF,  0x05,  0xD0,  0x08,  0x08, 	/* 4C6E0 */
+	0x17,  0xF4,  0x60,  0x03,  0x0F,  0xF8,  0x08,  0x08,  0x0F,  0xF8,  0x00,  0x00,  0x8C,  0x00,  0x00,  0x3D, 	/* 4C6F0 */
+	0xFF,  0x00,  0x04,  0x7E,  0xF4,  0x00,  0x94,  0x3E,  0x94,  0x00,  0xF4,  0x00,  0x0C,  0x3E,  0xFF,  0x00, 	/* 4C700 */
+	0x04,  0x3E,  0xF4,  0x22,  0x94,  0x22,  0x94,  0x22,  0xF4,  0x3E,  0x04,  0x00,  0x0C,  0x8E,  0x00,  0x08, 	/* 4C710 */
+	0x3C,  0x4A,  0x00,  0x2A,  0x7F,  0x2A,  0x00,  0x8C,  0x3C,  0xFF,  0x00,  0x08,  0x03,  0x9C,  0x3C,  0x9C, 	/* 4C720 */
+	0x00,  0xAA,  0x3C,  0xAA,  0x24,  0xC9,  0x25,  0x48,  0x25,  0x28,  0x3E,  0x18,  0x00,  0x07,  0x90,  0x00, 	/* 4C730 */
+	0x20,  0x3C,  0x10,  0x00,  0x50,  0x7E,  0x48,  0x01,  0x52,  0x3D,  0x51,  0x02,  0x65,  0x00,  0x44,  0x3D, 	/* 4C740 */
+	0xBC,  0x00,  0x00,  0x3C,  0xFE,  0x24,  0xAA,  0x24,  0xAA,  0x24,  0xAA,  0x3D,  0xFF,  0x00,  0x00,  0x94, 	/* 4C750 */
+	0x00,  0x10,  0x3E,  0x1E,  0x00,  0x10,  0x7E,  0xFF,  0x00,  0xA6,  0x3E,  0xB8,  0x00,  0xE0,  0x00,  0xA2, 	/* 4C760 */
+	0x3E,  0x9E,  0x00,  0x80,  0x3E,  0xBE,  0x22,  0xA0,  0x23,  0x7F,  0x23,  0x20,  0x3E,  0x3F,  0x00,  0x00, 	/* 4C770 */
+	0x96,  0x00,  0x00,  0x3E,  0xFE,  0x00,  0x92,  0x7F,  0xFE,  0x00,  0x92,  0x3E,  0xFE,  0x00,  0x48,  0x00, 	/* 4C780 */
+	0x49,  0x3E,  0x87,  0x01,  0x20,  0x3E,  0x3C,  0x22,  0xC4,  0x23,  0x28,  0x22,  0x30,  0x3E,  0xCC,  0x03, 	/* 4C790 */
+	0x03,  0x97,  0x00,  0x10,  0x3E,  0x10,  0x01,  0xFF,  0x7E,  0x44,  0x00,  0x28,  0x3F,  0xFF,  0x01,  0x01, 	/* 4C7A0 */
+	0x01,  0x21,  0x3E,  0x20,  0x01,  0xFF,  0x3E,  0x20,  0x22,  0x3C,  0x22,  0x24,  0x22,  0x44,  0x3E,  0x84, 	/* 4C7B0 */
+	0x03,  0x18,  0x99,  0x01,  0x04,  0x3C,  0x88,  0x03,  0xFF,  0x7E,  0x50,  0x01,  0xFC,  0x3C,  0x54,  0x00, 	/* 4C7C0 */
+	0x54,  0x03,  0xFF,  0x3C,  0x54,  0x01,  0xFC,  0x3C,  0x50,  0x24,  0xD8,  0x24,  0xD4,  0x25,  0x52,  0x3E, 	/* 4C7D0 */
+	0x51,  0x24,  0x50,  0x9A,  0x00,  0x58,  0x3E,  0x48,  0x00,  0x44,  0x7E,  0xFC,  0x00,  0x82,  0x3F,  0x59, 	/* 4C7E0 */
+	0x00,  0x48,  0x00,  0x84,  0x3E,  0x82,  0x01,  0x01,  0x3E,  0xFE,  0x22,  0xAA,  0x22,  0xAA,  0x22,  0xAA, 	/* 4C7F0 */
+	0x3F,  0xFF,  0x00,  0x00,  0x9B,  0x00,  0x48,  0x3C,  0x48,  0x01,  0xFF,  0x7E,  0x48,  0x00,  0xFE,  0x3C, 	/* 4C800 */
+	0x48,  0x03,  0xFF,  0x00,  0x10,  0x3C,  0xFE,  0x00,  0x92,  0x3C,  0xFE,  0x24,  0x92,  0x27,  0xFF,  0x24, 	/* 4C810 */
+	0x82,  0x3C,  0x82,  0x00,  0x86,  0x9D,  0x00,  0x42,  0x3C,  0x82,  0x01,  0xE2,  0x7F,  0x22,  0x01,  0x3F, 	/* 4C820 */
+	0x3D,  0xE2,  0x01,  0x22,  0x01,  0xF2,  0x3D,  0x2A,  0x01,  0x2A,  0x3F,  0xE2,  0x24,  0x62,  0x24,  0xA2, 	/* 4C830 */
+	0x25,  0x22,  0x3E,  0x22,  0x00,  0x66,  0xA0,  0x00,  0x10,  0x3C,  0x1E,  0x00,  0x22,  0x7E,  0x54,  0x01, 	/* 4C840 */
+	0xA8,  0x3C,  0x10,  0x00,  0x60,  0x01,  0xFE,  0x3C,  0x50,  0x00,  0x90,  0x3D,  0xFF,  0x24,  0x10,  0x24, 	/* 4C850 */
+	0x92,  0x24,  0x92,  0x3C,  0xFE,  0x00,  0x00,  0xA1,  0x00,  0x04,  0x3C,  0x18,  0x00,  0xE2,  0x7E,  0x92, 	/* 4C860 */
+	0x00,  0x54,  0x3C,  0x48,  0x00,  0x00,  0x00,  0xFE,  0x3C,  0x10,  0x00,  0x10,  0x3F,  0xFF,  0x24,  0x10, 	/* 4C870 */
+	0x24,  0x92,  0x24,  0x92,  0x3C,  0xFE,  0x00,  0x00,  0xA6,  0x04,  0x00,  0x7F,  0xBC,  0x04,  0x25,  0x3F, 	/* 4C880 */
+	0x43,  0x15,  0xFD,  0x1F,  0x24,  0x20,  0x18,  0x20,  0x64,  0x47,  0xF3,  0x00,  0x00,  0x7F,  0xFF,  0x00, 	/* 4C890 */
+	0x00,  0x0F,  0xF8,  0x08,  0x08,  0x0F,  0xF8,  0x00,  0x00,  0xA8,  0x00,  0x24,  0x3E,  0x24,  0x00,  0xFF, 	/* 4C8A0 */
+	0x7F,  0x24,  0x00,  0x24,  0x3E,  0x7E,  0x00,  0x42,  0x00,  0x7E,  0x3E,  0x42,  0x00,  0x7E,  0x3E,  0x10, 	/* 4C8B0 */
+	0x23,  0xFF,  0x22,  0x18,  0x22,  0x24,  0x3E,  0xC2,  0x03,  0x01,  0xAB,  0x00,  0x10,  0x3C,  0x10,  0x01, 	/* 4C8C0 */
+	0xFF,  0x7F,  0x44,  0x00,  0x28,  0x3E,  0xFE,  0x00,  0x92,  0x00,  0x92,  0x3E,  0xFE,  0x00,  0x92,  0x3E, 	/* 4C8D0 */
+	0xBA,  0x22,  0xAA,  0x22,  0xAA,  0x22,  0xBA,  0x3E,  0x82,  0x00,  0x86,  0xAC,  0x00,  0x00,  0x3F,  0xFE, 	/* 4C8E0 */
+	0x01,  0x32,  0x7C,  0xAA,  0x00,  0x66,  0x3C,  0xAA,  0x03,  0x76,  0x00,  0x50,  0x3C,  0x9C,  0x03,  0x23, 	/* 4C8F0 */
+	0x3C,  0x48,  0x25,  0x92,  0x24,  0x64,  0x25,  0x88,  0x3C,  0x30,  0x25,  0xC0,  0xB3,  0x00,  0x00,  0x3D, 	/* 4C900 */
+	0xFF,  0x01,  0x00,  0x7F,  0x7C,  0x01,  0x44,  0x3D,  0x44,  0x01,  0x7C,  0x01,  0x00,  0x3D,  0xEE,  0x01, 	/* 4C910 */
+	0xAA,  0x3D,  0xAA,  0x25,  0xAA,  0x25,  0xEE,  0x25,  0x00,  0x3D,  0xFF,  0x00,  0x00,  0xB9,  0x00,  0x44, 	/* 4C920 */
+	0x3E,  0x44,  0x01,  0xFF,  0x7E,  0x44,  0x00,  0xFE,  0x3E,  0x92,  0x00,  0x92,  0x00,  0xFE,  0x3E,  0x10, 	/* 4C930 */
+	0x00,  0xFE,  0x3E,  0x10,  0x22,  0xFE,  0x22,  0x10,  0x22,  0x10,  0x3F,  0xFF,  0x00,  0x00,  0xBE,  0x00, 	/* 4C940 */
+	0x00,  0x3E,  0x7C,  0x00,  0x44,  0x7F,  0x7C,  0x00,  0x44,  0x3E,  0x7C,  0x00,  0x00,  0x01,  0xFF,  0x3F, 	/* 4C950 */
+	0x29,  0x01,  0xFF,  0x00,  0x00,  0x3F,  0xFE,  0x22,  0x44,  0x22,  0x38,  0x3E,  0x6C,  0x01,  0x83,  0x81, 	/* 4C960 */
+	0x00,  0x48,  0x3C,  0x48,  0x03,  0xFF,  0x7E,  0x48,  0x01,  0xFE,  0x3C,  0xA4,  0x00,  0xA4,  0x03,  0xFF, 	/* 4C970 */
+	0x3C,  0xA4,  0x00,  0xA4,  0x3D,  0xFE,  0x24,  0x20,  0x27,  0xFF,  0x24,  0x20,  0x3C,  0x20,  0x00,  0x20, 	/* 4C980 */
+	0x89,  0x01,  0xEA,  0x3C,  0x2C,  0x00,  0xC9,  0x7E,  0x46,  0x00,  0x84,  0x3D,  0x7A,  0x02,  0x01,  0x00, 	/* 4C990 */
+	0xFC,  0x3C,  0x84,  0x00,  0x84,  0x3C,  0xFC,  0x24,  0x88,  0x24,  0x48,  0x24,  0x50,  0x3F,  0xFF,  0x00, 	/* 4C9A0 */
+	0x00,  0x8C,  0x00,  0x04,  0x3D,  0xF8,  0x00,  0xA2,  0x7E,  0x92,  0x01,  0xF9,  0x3E,  0x89,  0x00,  0x88, 	/* 4C9B0 */
+	0x00,  0xFC,  0x3C,  0x84,  0x01,  0x04,  0x3D,  0xFE,  0x25,  0x12,  0x26,  0xCA,  0x24,  0xAA,  0x3C,  0xA2, 	/* 4C9C0 */
+	0x01,  0x0C,  0x8E,  0x00,  0x00,  0x3D,  0xFC,  0x00,  0x48,  0x7E,  0x30,  0x03,  0xFE,  0x3C,  0x54,  0x00, 	/* 4C9D0 */
+	0x90,  0x01,  0x30,  0x3F,  0xFE,  0x01,  0x52,  0x3D,  0x56,  0x25,  0x8E,  0x25,  0x7A,  0x25,  0x4A,  0x3D, 	/* 4C9E0 */
+	0x7A,  0x01,  0x06,  0x8F,  0x00,  0x52,  0x3C,  0x52,  0x01,  0xBC,  0x7E,  0xD2,  0x00,  0x55,  0x3C,  0xBF, 	/* 4C9F0 */
+	0x01,  0xF4,  0x00,  0x12,  0x3D,  0xFF,  0x00,  0x94,  0x3C,  0x94,  0x24,  0xC8,  0x25,  0x29,  0x26,  0x15, 	/* 4CA00 */
+	0x3C,  0x23,  0x00,  0x41,  0x96,  0x00,  0x22,  0x3D,  0xEF,  0x00,  0xAA,  0x7E,  0xAA,  0x01,  0xFF,  0x3C, 	/* 4CA10 */
+	0x66,  0x00,  0xAA,  0x01,  0x33,  0x3C,  0xFC,  0x00,  0x84,  0x3C,  0x84,  0x24,  0xFC,  0x24,  0x84,  0x24, 	/* 4CA20 */
+	0x84,  0x3C,  0xFC,  0x00,  0x00,  0x98,  0x00,  0x88,  0x3C,  0x8C,  0x03,  0xFA,  0x7D,  0x2A,  0x00,  0xA8, 	/* 4CA30 */
+	0x3C,  0xA8,  0x03,  0xFF,  0x00,  0x08,  0x3D,  0xEA,  0x01,  0x2A,  0x3D,  0xEC,  0x25,  0x24,  0x25,  0x2D, 	/* 4CA40 */
+	0x25,  0xEB,  0x3C,  0x13,  0x00,  0x21,  0x9A,  0x00,  0x00,  0x3D,  0xFF,  0x00,  0x28,  0x7E,  0xFE,  0x00, 	/* 4CA50 */
+	0xAA,  0x3E,  0xFE,  0x00,  0x00,  0x00,  0x7C,  0x3E,  0x44,  0x00,  0x7C,  0x3E,  0x44,  0x22,  0x7C,  0x22, 	/* 4CA60 */
+	0x10,  0x23,  0xFF,  0x3E,  0x10,  0x00,  0x10,  0x9B,  0x00,  0x84,  0x3C,  0x84,  0x01,  0xFF,  0x7E,  0x84, 	/* 4CA70 */
+	0x01,  0xFF,  0x3C,  0x84,  0x01,  0x4A,  0x02,  0x31,  0x3C,  0xFC,  0x00,  0x84,  0x3C,  0x84,  0x24,  0xFC, 	/* 4CA80 */
+	0x24,  0x84,  0x24,  0x84,  0x3C,  0xFC,  0x00,  0x00,  0x9C,  0x00,  0x84,  0x3C,  0x44,  0x00,  0x48,  0x7F, 	/* 4CA90 */
+	0xFE,  0x00,  0x4A,  0x3D,  0x4A,  0x00,  0xCC,  0x03,  0xFF,  0x3C,  0x00,  0x00,  0xFC,  0x3C,  0x84,  0x24, 	/* 4CAA0 */
+	0xFC,  0x24,  0x84,  0x24,  0x84,  0x3C,  0xFC,  0x00,  0x00,  0x9F,  0x00,  0x00,  0x3C,  0x7C,  0x00,  0x44, 	/* 4CAB0 */
+	0x7E,  0x44,  0x00,  0x7C,  0x3D,  0xEF,  0x01,  0x29,  0x01,  0x29,  0x3D,  0xEF,  0x00,  0x10,  0x3D,  0xFF, 	/* 4CAC0 */
+	0x24,  0x38,  0x24,  0x54,  0x24,  0x92,  0x3D,  0x11,  0x00,  0x10,  0xA6,  0x12,  0x20,  0x7F,  0xA0,  0x12, 	/* 4CAD0 */
+	0x7F,  0x1F,  0xC4,  0x3D,  0x28,  0x55,  0x10,  0x1D,  0x6C,  0x07,  0x83,  0x00,  0x00,  0x7F,  0xFE,  0x00, 	/* 4CAE0 */
+	0x00,  0x07,  0xE0,  0x00,  0x00,  0x0F,  0xF0,  0x08,  0x10,  0x0F,  0xF0,  0xAB,  0x00,  0x20,  0x3C,  0x7C, 	/* 4CAF0 */
+	0x00,  0x88,  0x7F,  0xFF,  0x01,  0x25,  0x3D,  0xC3,  0x01,  0x3C,  0x01,  0x00,  0x3D,  0xFF,  0x01,  0x00, 	/* 4CB00 */
+	0x01,  0x3C,  0x3D,  0x00,  0x25,  0x7E,  0x25,  0x42,  0x3E,  0x7E,  0x04,  0x00,  0xAC,  0x1F,  0x10,  0x11, 	/* 4CB10 */
+	0xFE,  0x1F,  0x44,  0x10,  0xFF,  0x2F,  0x10,  0x29,  0xFE,  0x4F,  0x10,  0x00,  0x80,  0x7F,  0xFF,  0x00, 	/* 4CB20 */
+	0x00,  0x0F,  0xF8,  0x00,  0x00,  0x0F,  0xF8,  0x08,  0x08,  0x0F,  0xF8,  0x00,  0x00,  0xAF,  0x00,  0x00, 	/* 4CB30 */
+	0x3E,  0xFE,  0x00,  0xAA,  0x7F,  0xFE,  0x00,  0x10,  0x3E,  0xFE,  0x00,  0x10,  0x01,  0xFF,  0x3E,  0x44, 	/* 4CB40 */
+	0x00,  0x28,  0x3F,  0xFF,  0x22,  0x10,  0x22,  0xFE,  0x22,  0x10,  0x3E,  0x10,  0x00,  0x10,  0xB0,  0x00, 	/* 4CB50 */
+	0x44,  0x3C,  0x28,  0x00,  0xFE,  0x7E,  0x10,  0x00,  0xFC,  0x3C,  0x10,  0x03,  0xFF,  0x00,  0x2C,  0x3D, 	/* 4CB60 */
+	0xCA,  0x00,  0x48,  0x3D,  0xFF,  0x24,  0x4A,  0x24,  0x6A,  0x25,  0xC5,  0x3C,  0x4B,  0x00,  0xD1,  0xB1, 	/* 4CB70 */
+	0x04,  0x20,  0x3F,  0xFE,  0x00,  0x80,  0x1F,  0xFC,  0x00,  0x80,  0x7F,  0xFF,  0x00,  0x80,  0x1C,  0x9C, 	/* 4CB80 */
+	0x00,  0x80,  0x7E,  0xBF,  0x1C,  0x9C,  0x00,  0x80,  0x3E,  0xBE,  0x22,  0xA2,  0x3E,  0xBE,  0x00,  0x80, 	/* 4CB90 */
+	0xB2,  0x00,  0x10,  0x3C,  0x10,  0x01,  0xFF,  0x7E,  0x44,  0x00,  0xAA,  0x3D,  0x29,  0x00,  0xFE,  0x00, 	/* 4CBA0 */
+	0x28,  0x3C,  0xFE,  0x00,  0x28,  0x3D,  0xFF,  0x24,  0x2A,  0x24,  0x4A,  0x25,  0xC4,  0x3C,  0x72,  0x01, 	/* 4CBB0 */
+	0x81,  0xB4,  0x00,  0x08,  0x3D,  0x3E,  0x00,  0xAA,  0x7E,  0xBE,  0x00,  0x08,  0x3E,  0x7F,  0x01,  0x00, 	/* 4CBC0 */
+	0x01,  0x3E,  0x3C,  0x22,  0x03,  0xBE,  0x3C,  0xA0,  0x24,  0xBE,  0x24,  0xA2,  0x25,  0x7E,  0x3E,  0x20, 	/* 4CBD0 */
+	0x04,  0x1F,  0xB7,  0x00,  0x48,  0x3E,  0xFE,  0x00,  0x48,  0x7F,  0x7E,  0x00,  0x90,  0x3E,  0xFC,  0x01, 	/* 4CBE0 */
+	0x90,  0x00,  0xFC,  0x3E,  0x90,  0x00,  0xFE,  0x3E,  0x00,  0x23,  0xFC,  0x22,  0xC8,  0x22,  0x30,  0x3E, 	/* 4CBF0 */
+	0x68,  0x03,  0x87,  0xBD,  0x05,  0x00,  0x19,  0xDC,  0x11,  0x04,  0x1D,  0xDC,  0x1C,  0x5C,  0x11,  0x44, 	/* 4CC00 */
+	0x7F,  0xFF,  0x04,  0x90,  0x0F,  0xF8,  0x10,  0x04,  0x67,  0xF3,  0x00,  0x00,  0x0F,  0xF8,  0x08,  0x08, 	/* 4CC10 */
+	0x0F,  0xF8,  0x00,  0x00,  0x80,  0x00,  0x10,  0x3D,  0xFF,  0x00,  0x10,  0x7E,  0xFC,  0x00,  0x00,  0x3D, 	/* 4CC20 */
+	0xFE,  0x01,  0x4A,  0x01,  0xFE,  0x3C,  0x84,  0x00,  0xFC,  0x3C,  0x84,  0x24,  0xFC,  0x24,  0x84,  0x24, 	/* 4CC30 */
+	0xFC,  0x3C,  0x44,  0x01,  0x82,  0x83,  0x00,  0x44,  0x3D,  0xEF,  0x00,  0x44,  0x7F,  0xEF,  0x00,  0x44, 	/* 4CC40 */
+	0x3E,  0xAA,  0x01,  0x01,  0x00,  0x7C,  0x3E,  0x44,  0x00,  0x7C,  0x00,  0x44,  0x3E,  0x7C,  0x22,  0x44, 	/* 4CC50 */
+	0x22,  0x7C,  0x3E,  0x24,  0x22,  0xC2,  0x8A,  0x10,  0x04,  0x11,  0xC4,  0x68,  0x1A,  0x13,  0xE4,  0x28, 	/* 4CC60 */
+	0x0A,  0x7D,  0xDF,  0x14,  0x05,  0x31,  0xD4,  0x39,  0x56,  0x55,  0xE5,  0x12,  0x04,  0x07,  0xFC,  0x1A, 	/* 4CC70 */
+	0x10,  0x61,  0xE0,  0x07,  0x30,  0x78,  0x0F,  0x8C,  0x00,  0x48,  0x3C,  0x48,  0x01,  0xFF,  0x7E,  0x48, 	/* 4CC80 */
+	0x00,  0x78,  0x3C,  0x85,  0x03,  0xF5,  0x00,  0xD6,  0x3C,  0xD4,  0x01,  0xD5,  0x3E,  0xF5,  0x24,  0x83, 	/* 4CC90 */
+	0x24,  0x00,  0x25,  0x52,  0x3D,  0x49,  0x02,  0x49,  0x8E,  0x12,  0x05,  0x12,  0xE5,  0x24,  0x0A,  0x3F, 	/* 4CCA0 */
+	0xEF,  0x68,  0x1A,  0x29,  0xEA,  0x28,  0x0A,  0x3C,  0x0F,  0x29,  0xEA,  0x28,  0x0A,  0x3D,  0xEF,  0x29, 	/* 4CCB0 */
+	0x2A,  0x29,  0x2A,  0x29,  0x2A,  0x3D,  0xEF,  0x00,  0x00,  0x90,  0x12,  0x24,  0x3F,  0xBF,  0x64,  0xC8, 	/* 4CCC0 */
+	0x3F,  0x7E,  0x24,  0x48,  0x3F,  0x7E,  0x24,  0x48,  0x7F,  0xFF,  0x00,  0x00,  0x0F,  0xF8,  0x00,  0x00, 	/* 4CCD0 */
+	0x0F,  0xF8,  0x00,  0x00,  0x0F,  0xF8,  0x08,  0x08,  0x0F,  0xF8,  0x92,  0x00,  0x20,  0x3C,  0x78,  0x00, 	/* 4CCE0 */
+	0x90,  0x7F,  0xFC,  0x00,  0x84,  0x3C,  0xFD,  0x00,  0x89,  0x01,  0xE7,  0x3C,  0x78,  0x00,  0x90,  0x3D, 	/* 4CCF0 */
+	0xFE,  0x24,  0x92,  0x24,  0xFE,  0x24,  0x35,  0x3C,  0xD1,  0x03,  0x0F,  0x93,  0x00,  0x10,  0x3D,  0xFF, 	/* 4CD00 */
+	0x00,  0x00,  0x7E,  0xEE,  0x00,  0xAA,  0x3C,  0xEE,  0x00,  0x28,  0x00,  0xFE,  0x3C,  0x28,  0x00,  0xFE, 	/* 4CD10 */
+	0x3C,  0x28,  0x25,  0xFF,  0x24,  0x32,  0x25,  0xCC,  0x3C,  0x64,  0x01,  0xC3,  0x96,  0x01,  0x28,  0x39, 	/* 4CD20 */
+	0x2A,  0x02,  0xD9,  0x7E,  0x49,  0x00,  0x88,  0x3B,  0xFF,  0x01,  0x48,  0x03,  0x6A,  0x39,  0x4A,  0x03, 	/* 4CD30 */
+	0x6A,  0x39,  0x44,  0x2B,  0x64,  0x29,  0x5D,  0x29,  0xEB,  0x3F,  0x13,  0x00,  0x21,  0x99,  0x00,  0x48, 	/* 4CD40 */
+	0x3D,  0xFF,  0x00,  0x48,  0x7E,  0xEE,  0x00,  0xAA,  0x3C,  0xEE,  0x00,  0x44,  0x00,  0x48,  0x3C,  0xFE, 	/* 4CD50 */
+	0x01,  0x90,  0x3E,  0xFC,  0x24,  0x90,  0x24,  0xFC,  0x24,  0x90,  0x3C,  0xFF,  0x00,  0x00,  0x9A,  0x01, 	/* 4CD60 */
+	0x4A,  0x3D,  0xEF,  0x02,  0x52,  0x7F,  0xFF,  0x01,  0x4A,  0x3D,  0x6A,  0x02,  0x53,  0x00,  0xFC,  0x3C, 	/* 4CD70 */
+	0x84,  0x00,  0xFC,  0x3C,  0x84,  0x24,  0xFC,  0x24,  0x84,  0x24,  0xFC,  0x3C,  0x44,  0x01,  0x82,  0xB7, 	/* 4CD80 */
+	0x04,  0x10,  0x04,  0x08,  0x08,  0x08,  0x08,  0x84,  0x10,  0x84,  0x21,  0x40,  0x02,  0x20,  0x04,  0x10, 	/* 4CD90 */
+	0x18,  0x0C,  0x6F,  0xFB,  0x08,  0x08,  0x08,  0x08,  0x08,  0x08,  0x08,  0x08,  0x0F,  0xF8,  0x00,  0x00, 	/* 4CDA0 */
+	0xBA,  0x12,  0x00,  0x12,  0x3E,  0x11,  0x24,  0x20,  0xA4,  0x48,  0x24,  0x08,  0x24,  0x14,  0x24,  0x12, 	/* 4CDB0 */
+	0xFF,  0x21,  0x0C,  0x40,  0x94,  0x3E,  0x14,  0x22,  0x24,  0x22,  0x44,  0x22,  0x84,  0x3F,  0x04,  0x00, 	/* 4CDC0 */
+	0x0C,  0xBF,  0x02,  0x28,  0x3C,  0x24,  0x2A,  0x24,  0x2A,  0x42,  0x41,  0x92,  0x09,  0x18,  0x0A,  0x28, 	/* 4CDD0 */
+	0x34,  0x24,  0x0A,  0x42,  0x7D,  0x81,  0x09,  0x7C,  0x7F,  0x44,  0x18,  0x44,  0x14,  0x44,  0x22,  0x7C, 	/* 4CDE0 */
+	0x40,  0x00,  0x81,  0x08,  0x28,  0x08,  0x24,  0x7F,  0x24,  0x41,  0x42,  0x49,  0x92,  0x3E,  0x18,  0x08, 	/* 4CDF0 */
+	0x28,  0x3E,  0x24,  0x08,  0x42,  0x7E,  0x81,  0x09,  0x7C,  0x3E,  0x44,  0x22,  0x44,  0x22,  0x44,  0x3E, 	/* 4CE00 */
+	0x7C,  0x00,  0x00,  0x86,  0x00,  0x00,  0x3F,  0xFE,  0x00,  0x00,  0x00,  0x00,  0x0F,  0xF8,  0x08,  0x08, 	/* 4CE10 */
+	0x08,  0x08,  0x08,  0x08,  0x0F,  0xF8,  0x00,  0x00,  0x04,  0x10,  0x02,  0x10,  0x02,  0x20,  0x00,  0x40, 	/* 4CE20 */
+	0x7F,  0xFF,  0x00,  0x00,  0x88,  0x00,  0x80,  0x10,  0x84,  0x10,  0x84,  0x1F,  0xFC,  0x00,  0x00,  0x7F, 	/* 4CE30 */
+	0xFF,  0x00,  0x00,  0x0F,  0xF8,  0x08,  0x08,  0x08,  0x08,  0x0F,  0xF8,  0x04,  0x10,  0x02,  0x10,  0x02, 	/* 4CE40 */
+	0x20,  0x7F,  0xFF,  0x00,  0x00,  0x8A,  0x02,  0x20,  0x1F,  0xFC,  0x12,  0x24,  0x1F,  0xFC,  0x12,  0x24, 	/* 4CE50 */
+	0x1F,  0xFC,  0x00,  0x00,  0x7F,  0xFF,  0x00,  0x00,  0x0F,  0xF8,  0x08,  0x08,  0x0F,  0xF8,  0x04,  0x10, 	/* 4CE60 */
+	0x02,  0x20,  0x7F,  0xFF,  0x00,  0x00,  0x8C,  0x00,  0x10,  0x7F,  0x10,  0x00,  0xFF,  0x00,  0x81,  0x3E, 	/* 4CE70 */
+	0xA0,  0x22,  0x3E,  0x22,  0x5A,  0x3E,  0x5A,  0x00,  0xDA,  0x22,  0xAA,  0x23,  0x2A,  0x14,  0x2C,  0x16, 	/* 4CE80 */
+	0x48,  0x18,  0x49,  0x60,  0x89,  0x01,  0x07,  0x8E,  0x00,  0x00,  0x3F,  0x7E,  0x24,  0x22,  0x3F,  0x14, 	/* 4CE90 */
+	0x21,  0x18,  0x3F,  0x64,  0x24,  0x02,  0x3F,  0xFD,  0x00,  0x00,  0x0F,  0xF8,  0x08,  0x08,  0x0F,  0xF8, 	/* 4CEA0 */
+	0x04,  0x10,  0x02,  0x20,  0x7F,  0xFF,  0x00,  0x00,  0x90,  0x04,  0x90,  0x2E,  0xBA,  0x24,  0x92,  0x2E, 	/* 4CEB0 */
+	0xBA,  0x24,  0x92,  0x2E,  0xBA,  0x3F,  0xFE,  0x00,  0x00,  0x3F,  0xFE,  0x00,  0x00,  0x0F,  0xF8,  0x08, 	/* 4CEC0 */
+	0x08,  0x0F,  0xF8,  0x04,  0x10,  0x7F,  0xFF,  0x00,  0x00,  0x95,  0x00,  0x00,  0x7F,  0xFF,  0x00,  0x80, 	/* 4CED0 */
+	0x01,  0x20,  0x02,  0x22,  0x06,  0x24,  0x19,  0x18,  0x61,  0x90,  0x02,  0x88,  0x0C,  0x48,  0x70,  0xC4, 	/* 4CEE0 */
+	0x01,  0x44,  0x02,  0x42,  0x0C,  0x41,  0x70,  0x40,  0x01,  0x80,  0x9A,  0x00,  0x00,  0x3D,  0xFF,  0x24, 	/* 4CEF0 */
+	0x40,  0x24,  0x22,  0x24,  0x62,  0x3C,  0x54,  0x24,  0x94,  0x25,  0x28,  0x24,  0x4C,  0x3C,  0x9C,  0x25, 	/* 4CF00 */
+	0x1A,  0x24,  0x2A,  0x24,  0x49,  0x24,  0x88,  0x25,  0x08,  0x4C,  0x30,  0xA1,  0x02,  0x00,  0x03,  0xE0, 	/* 4CF10 */
+	0x04,  0x40,  0x18,  0x80,  0x7F,  0xF8,  0x10,  0x88,  0x10,  0x88,  0x1F,  0xF8,  0x02,  0x02,  0x05,  0x44, 	/* 4CF20 */
+	0x39,  0xD8,  0x06,  0xA0,  0x39,  0x90,  0x06,  0x8C,  0x78,  0x83,  0x01,  0x80,  0xA2,  0x04,  0x90,  0x08, 	/* 4CF30 */
+	0x88,  0x1F,  0xFC,  0x01,  0x40,  0x7F,  0xFF,  0x02,  0x20,  0x04,  0x10,  0x1F,  0xEC,  0x61,  0x07,  0x06, 	/* 4CF40 */
+	0x88,  0x19,  0xD0,  0x06,  0x60,  0x18,  0xD8,  0x03,  0x44,  0x3C,  0x42,  0x01,  0x80,  0xAA,  0x00,  0x80, 	/* 4CF50 */
+	0x7F,  0xFF,  0x00,  0x00,  0x07,  0xF8,  0x04,  0x08,  0x07,  0xF8,  0x00,  0x00,  0x3F,  0xFE,  0x20,  0x02, 	/* 4CF60 */
+	0x2F,  0xFA,  0x1C,  0x84,  0x03,  0x68,  0x3C,  0xD0,  0x03,  0x4C,  0x3C,  0x43,  0x00,  0xC0,  0xAB,  0x00, 	/* 4CF70 */
+	0x20,  0x3E,  0x38,  0x02,  0x48,  0x14,  0x90,  0x09,  0xFE,  0x08,  0x92,  0x7E,  0x92,  0x0A,  0xFE,  0x0C, 	/* 4CF80 */
+	0x62,  0x08,  0xA2,  0x0B,  0x54,  0x08,  0xB8,  0x0B,  0x54,  0x08,  0x92,  0x0B,  0x11,  0x18,  0x30,  0xAC, 	/* 4CF90 */
+	0x00,  0x20,  0x7F,  0x22,  0x08,  0xFE,  0x11,  0x24,  0x31,  0x24,  0x4A,  0x28,  0x0D,  0xFF,  0x16,  0x14, 	/* 4CFA0 */
+	0x26,  0x22,  0x4D,  0x7E,  0x0C,  0xC2,  0x15,  0x7E,  0x24,  0x42,  0x44,  0x42,  0x04,  0x7E,  0x18,  0x00, 	/* 4CFB0 */
+	0xB8,  0x00,  0x20,  0x00,  0xC0,  0x1F,  0x84,  0x04,  0x58,  0x02,  0x60,  0x03,  0x80,  0x3C,  0x40,  0x00, 	/* 4CFC0 */
+	0xA0,  0x01,  0x20,  0x06,  0x50,  0x38,  0x90,  0x01,  0x10,  0x06,  0x10,  0x38,  0x20,  0x00,  0x20,  0x00, 	/* 4CFD0 */
+	0xC0,  0xB9,  0x04,  0x40,  0x18,  0x40,  0x65,  0x40,  0x12,  0x7E,  0x0C,  0x82,  0x18,  0x82,  0x65,  0x02, 	/* 4CFE0 */
+	0x04,  0x22,  0x0A,  0x12,  0x12,  0x12,  0x66,  0x02,  0x0A,  0x02,  0x12,  0x02,  0x62,  0x02,  0x04,  0x04, 	/* 4CFF0 */
+	0x18,  0x18,  0xBA,  0x04,  0x04,  0x18,  0x04,  0x65,  0x04,  0x12,  0x04,  0x0C,  0xFF,  0x18,  0x0C,  0x64, 	/* 4D000 */
+	0x0C,  0x04,  0x14,  0x0A,  0x14,  0x12,  0x24,  0x66,  0x24,  0x0A,  0x44,  0x12,  0x84,  0x62,  0x04,  0x02, 	/* 4D010 */
+	0x04,  0x0C,  0x0C,  0xBC,  0x04,  0x48,  0x18,  0x48,  0x65,  0x48,  0x12,  0x48,  0x0C,  0x49,  0x18,  0x49, 	/* 4D020 */
+	0x64,  0x7A,  0x04,  0x4C,  0x0A,  0x48,  0x12,  0x48,  0x66,  0x48,  0x0A,  0x48,  0x12,  0x48,  0x62,  0x49, 	/* 4D030 */
+	0x02,  0x69,  0x0D,  0x87,  0x82,  0x04,  0x00,  0x18,  0xFE,  0x65,  0x22,  0x12,  0x22,  0x0C,  0x22,  0x18, 	/* 4D040 */
+	0x42,  0x64,  0x42,  0x04,  0x8C,  0x0B,  0x00,  0x12,  0x7E,  0x66,  0x42,  0x0A,  0x42,  0x12,  0x42,  0x62, 	/* 4D050 */
+	0x42,  0x02,  0x7E,  0x0C,  0x00,  0x85,  0x04,  0x48,  0x18,  0x48,  0x65,  0x48,  0x12,  0x88,  0x0C,  0xFF, 	/* 4D060 */
+	0x19,  0x88,  0x66,  0x88,  0x04,  0x9C,  0x0A,  0x9C,  0x12,  0xAA,  0x66,  0xAA,  0x0A,  0xC9,  0x12,  0x88, 	/* 4D070 */
+	0x62,  0x88,  0x02,  0x88,  0x0C,  0x88,  0x89,  0x04,  0x20,  0x18,  0x20,  0x65,  0x3C,  0x12,  0x44,  0x0C, 	/* 4D080 */
+	0xA8,  0x19,  0x28,  0x64,  0x10,  0x04,  0x28,  0x0A,  0x44,  0x12,  0x82,  0x67,  0x7D,  0x0A,  0x44,  0x12, 	/* 4D090 */
+	0x44,  0x62,  0x44,  0x02,  0x7C,  0x0C,  0x00,  0x8A,  0x04,  0x00,  0x19,  0xFF,  0x65,  0x10,  0x12,  0x10, 	/* 4D0A0 */
+	0x0C,  0x20,  0x18,  0x7E,  0x64,  0x42,  0x04,  0x42,  0x0A,  0x42,  0x12,  0x7E,  0x66,  0x42,  0x0A,  0x42, 	/* 4D0B0 */
+	0x12,  0x42,  0x62,  0x42,  0x02,  0x7E,  0x0C,  0x00,  0x8C,  0x04,  0x10,  0x08,  0x20,  0x15,  0xFE,  0x62, 	/* 4D0C0 */
+	0x82,  0x14,  0x82,  0x08,  0xFE,  0x14,  0x82,  0x64,  0x82,  0x0A,  0xFE,  0x12,  0x28,  0x66,  0x28,  0x0A, 	/* 4D0D0 */
+	0x28,  0x12,  0x48,  0x62,  0x49,  0x04,  0x89,  0x19,  0x07,  0x8D,  0x04,  0x00,  0x18,  0xFE,  0x65,  0x92, 	/* 4D0E0 */
+	0x12,  0x92,  0x0C,  0xFE,  0x18,  0x92,  0x64,  0x92,  0x04,  0xFE,  0x0A,  0x10,  0x12,  0x10,  0x66,  0xFE, 	/* 4D0F0 */
+	0x0A,  0x10,  0x12,  0x10,  0x62,  0x10,  0x03,  0xFF,  0x0C,  0x00,  0x8E,  0x04,  0x10,  0x08,  0x20,  0x15, 	/* 4D100 */
+	0xCC,  0x62,  0x84,  0x14,  0x84,  0x08,  0xEC,  0x14,  0x84,  0x64,  0x84,  0x0A,  0xFC,  0x12,  0x28,  0x66, 	/* 4D110 */
+	0x28,  0x0A,  0x28,  0x12,  0x48,  0x62,  0x49,  0x02,  0x89,  0x0D,  0x07,  0x94,  0x04,  0x10,  0x18,  0x20, 	/* 4D120 */
+	0x65,  0xFE,  0x12,  0x8A,  0x0C,  0xEA,  0x18,  0x92,  0x64,  0xAA,  0x04,  0xC2,  0x0A,  0xFE,  0x12,  0x00, 	/* 4D130 */
+	0x66,  0x88,  0x0A,  0xE9,  0x12,  0x8E,  0x62,  0x88,  0x02,  0xE9,  0x0D,  0x87,  0x98,  0x04,  0x48,  0x18, 	/* 4D140 */
+	0x48,  0x65,  0xFF,  0x12,  0x48,  0x0C,  0x48,  0x18,  0xFC,  0x64,  0x84,  0x04,  0xFC,  0x0A,  0x84,  0x12, 	/* 4D150 */
+	0xFC,  0x66,  0x10,  0x0B,  0xFF,  0x12,  0x10,  0x62,  0x28,  0x02,  0x44,  0x0D,  0x83,  0x9D,  0x00,  0x00, 	/* 4D160 */
+	0x0F,  0xF8,  0x08,  0x08,  0x08,  0x08,  0x08,  0x08,  0x0F,  0xF8,  0x08,  0x08,  0x08,  0x08,  0x08,  0x08, 	/* 4D170 */
+	0x0F,  0xF8,  0x08,  0x08,  0x08,  0x08,  0x0F,  0xF8,  0x02,  0x30,  0x0C,  0x08,  0x30,  0x04,  0x9E,  0x01, 	/* 4D180 */
+	0x00,  0x01,  0x00,  0x01,  0xF8,  0x01,  0x00,  0x1F,  0xF0,  0x10,  0x10,  0x10,  0x10,  0x1F,  0xF0,  0x10, 	/* 4D190 */
+	0x10,  0x1F,  0xF0,  0x10,  0x10,  0x10,  0x10,  0x1F,  0xF0,  0x04,  0x60,  0x18,  0x18,  0x60,  0x04,  0xA0, 	/* 4D1A0 */
+	0x02,  0x00,  0x03,  0xF0,  0x04,  0x20,  0x08,  0x40,  0x1F,  0xF8,  0x28,  0x08,  0x08,  0x08,  0x0F,  0xF8, 	/* 4D1B0 */
+	0x08,  0x08,  0x0F,  0xF8,  0x08,  0x08,  0x08,  0x08,  0x0F,  0xF8,  0x02,  0x30,  0x0C,  0x08,  0x30,  0x04, 	/* 4D1C0 */
+	0xA1,  0x00,  0x08,  0x3E,  0x08,  0x22,  0x08,  0x22,  0x08,  0x3F,  0xFF,  0x22,  0x08,  0x22,  0x18,  0x3E, 	/* 4D1D0 */
+	0x18,  0x22,  0x28,  0x22,  0x28,  0x22,  0x48,  0x3E,  0x88,  0x15,  0x08,  0x12,  0x08,  0x22,  0x08,  0x40, 	/* 4D1E0 */
+	0x18,  0xA2,  0x00,  0x00,  0x1F,  0xF8,  0x00,  0x80,  0x7F,  0xFE,  0x00,  0x00,  0x0F,  0xF0,  0x08,  0x10, 	/* 4D1F0 */
+	0x0F,  0xF0,  0x08,  0x10,  0x0F,  0xF0,  0x08,  0x10,  0x08,  0x10,  0x0F,  0xF0,  0x02,  0x60,  0x0C,  0x18, 	/* 4D200 */
+	0x30,  0x04,  0xA7,  0x02,  0x20,  0x04,  0x10,  0x1F,  0xF8,  0x61,  0x17,  0x02,  0x10,  0x0C,  0x60,  0x30, 	/* 4D210 */
+	0x00,  0x0F,  0xF8,  0x08,  0x08,  0x0F,  0xF8,  0x08,  0x08,  0x0F,  0xF8,  0x08,  0x08,  0x0F,  0xF8,  0x04, 	/* 4D220 */
+	0x18,  0x38,  0x06,  0xA8,  0x02,  0x40,  0x04,  0x44,  0x0C,  0x78,  0x14,  0x40,  0x64,  0x42,  0x04,  0x3E, 	/* 4D230 */
+	0x0F,  0xF8,  0x08,  0x08,  0x0F,  0xF8,  0x08,  0x08,  0x0F,  0xF8,  0x08,  0x08,  0x08,  0x08,  0x0F,  0xF8, 	/* 4D240 */
+	0x0C,  0x18,  0x30,  0x04,  0xA9,  0x00,  0x00,  0x3E,  0x7F,  0x22,  0x40,  0x22,  0x40,  0x3E,  0x40,  0x22, 	/* 4D250 */
+	0x7E,  0x22,  0x62,  0x22,  0x62,  0x3E,  0x52,  0x22,  0x54,  0x22,  0x4C,  0x3E,  0x48,  0x14,  0x94,  0x12, 	/* 4D260 */
+	0x94,  0x21,  0x22,  0x41,  0x41,  0xAA,  0x00,  0x80,  0x01,  0x40,  0x06,  0x30,  0x1B,  0xEC,  0x60,  0x03, 	/* 4D270 */
+	0x0F,  0xF8,  0x00,  0x20,  0x0F,  0xF8,  0x08,  0x08,  0x0F,  0xF8,  0x08,  0x08,  0x0F,  0xF8,  0x08,  0x08, 	/* 4D280 */
+	0x0F,  0xF8,  0x06,  0x30,  0x38,  0x0C,  0xAB,  0x00,  0x00,  0x0F,  0xF8,  0x08,  0x88,  0x7F,  0xFF,  0x11, 	/* 4D290 */
+	0x10,  0x1F,  0xF0,  0x00,  0x00,  0x0F,  0xF8,  0x08,  0x08,  0x0F,  0xF8,  0x08,  0x08,  0x0F,  0xF8,  0x08, 	/* 4D2A0 */
+	0x08,  0x0F,  0xF8,  0x04,  0x18,  0x38,  0x06,  0xAC,  0x00,  0x80,  0x1F,  0xFE,  0x00,  0x80,  0x0F,  0xFC, 	/* 4D2B0 */
+	0x00,  0x80,  0x7F,  0xFF,  0x00,  0x00,  0x07,  0xF8,  0x04,  0x08,  0x07,  0xF8,  0x04,  0x08,  0x07,  0xF8, 	/* 4D2C0 */
+	0x04,  0x08,  0x07,  0xF8,  0x02,  0x30,  0x1C,  0x0E,  0xAD,  0x00,  0x04,  0x00,  0x38,  0x1F,  0xC0,  0x10, 	/* 4D2D0 */
+	0x40,  0x1F,  0xFF,  0x10,  0x40,  0x13,  0xFC,  0x12,  0x04,  0x13,  0xFC,  0x12,  0x04,  0x13,  0xFC,  0x12, 	/* 4D2E0 */
+	0x04,  0x23,  0xFC,  0x20,  0x90,  0x43,  0x0C,  0x0C,  0x02,  0xAE,  0x00,  0x14,  0x00,  0x12,  0x00,  0x12, 	/* 4D2F0 */
+	0x7F,  0xFF,  0x00,  0x10,  0x1F,  0xD0,  0x10,  0x50,  0x1F,  0xD0,  0x10,  0x48,  0x1F,  0xC8,  0x10,  0x48, 	/* 4D300 */
+	0x10,  0x48,  0x1F,  0xC5,  0x04,  0x85,  0x18,  0x43,  0x60,  0x21,  0xAF,  0x00,  0x10,  0x3E,  0x10,  0x22, 	/* 4D310 */
+	0xFE,  0x22,  0x82,  0x3E,  0x82,  0x22,  0x00,  0x22,  0xFF,  0x3E,  0x10,  0x22,  0x10,  0x22,  0x10,  0x22, 	/* 4D320 */
+	0x10,  0x3E,  0x10,  0x14,  0x10,  0x12,  0x10,  0x22,  0x10,  0x40,  0x30,  0xB0,  0x09,  0x10,  0x7F,  0xFF, 	/* 4D330 */
+	0x09,  0x10,  0x09,  0xF0,  0x08,  0x00,  0x0F,  0xFC,  0x00,  0x00,  0x0F,  0xF8,  0x08,  0x08,  0x0F,  0xF8, 	/* 4D340 */
+	0x08,  0x08,  0x0F,  0xF8,  0x08,  0x08,  0x0F,  0xF8,  0x06,  0x30,  0x38,  0x0C,  0xB2,  0x04,  0x20,  0x14, 	/* 4D350 */
+	0x26,  0x17,  0xB8,  0x14,  0x21,  0x14,  0x21,  0x17,  0x9F,  0x78,  0x00,  0x0F,  0xF8,  0x08,  0x08,  0x0F, 	/* 4D360 */
+	0xF8,  0x08,  0x08,  0x0F,  0xF8,  0x08,  0x08,  0x0F,  0xF8,  0x06,  0x18,  0x38,  0x06,  0xB3,  0x00,  0x14, 	/* 4D370 */
+	0x00,  0x12,  0x00,  0x12,  0x7F,  0xFF,  0x00,  0x10,  0x1F,  0xD0,  0x00,  0x10,  0x7F,  0xF0,  0x10,  0x48, 	/* 4D380 */
+	0x1F,  0xC8,  0x10,  0x48,  0x1F,  0xC8,  0x10,  0x45,  0x1F,  0xC5,  0x0C,  0xC3,  0x70,  0x21,  0xB4,  0x00, 	/* 4D390 */
+	0x80,  0x0F,  0xF0,  0x08,  0x90,  0x0F,  0xF0,  0x00,  0x80,  0x7F,  0xFE,  0x00,  0x00,  0x0F,  0xF0,  0x08, 	/* 4D3A0 */
+	0x10,  0x0F,  0xF0,  0x08,  0x10,  0x0F,  0xF0,  0x08,  0x10,  0x0F,  0xF0,  0x06,  0x18,  0x38,  0x04,  0xB6, 	/* 4D3B0 */
+	0x00,  0x02,  0x3E,  0x0C,  0x22,  0xF0,  0x22,  0x10,  0x3E,  0x10,  0x22,  0x10,  0x22,  0xFC,  0x3E,  0x04, 	/* 4D3C0 */
+	0x22,  0x04,  0x22,  0x08,  0x22,  0x08,  0x3E,  0x90,  0x14,  0xA0,  0x12,  0xC0,  0x21,  0x30,  0x42,  0x0F, 	/* 4D3D0 */
+	0xB7,  0x00,  0x00,  0x3F,  0xFE,  0x22,  0x22,  0x22,  0x22,  0x3F,  0xFE,  0x00,  0x00,  0x0F,  0xF8,  0x08, 	/* 4D3E0 */
+	0x08,  0x0F,  0xF8,  0x08,  0x08,  0x0F,  0xF8,  0x08,  0x08,  0x0F,  0xF8,  0x02,  0x30,  0x0C,  0x0C,  0x30, 	/* 4D3F0 */
+	0x02,  0xB8,  0x04,  0x48,  0x04,  0x44,  0x0B,  0xFF,  0x18,  0x20,  0x28,  0x12,  0x48,  0x0A,  0x0F,  0xFE, 	/* 4D400 */
+	0x08,  0x08,  0x0F,  0xF8,  0x08,  0x08,  0x0F,  0xF8,  0x08,  0x08,  0x0F,  0xF8,  0x02,  0x30,  0x0C,  0x0C, 	/* 4D410 */
+	0x30,  0x02,  0xBB,  0x02,  0x20,  0x3F,  0xFC,  0x02,  0x24,  0x3F,  0xFC,  0x22,  0x20,  0x3F,  0xFE,  0x04, 	/* 4D420 */
+	0x22,  0x0F,  0xFC,  0x38,  0x08,  0x0F,  0xF8,  0x08,  0x08,  0x0F,  0xF8,  0x08,  0x08,  0x0F,  0xF8,  0x06, 	/* 4D430 */
+	0x38,  0x38,  0x06,  0xBC,  0x00,  0x10,  0x3E,  0x10,  0x22,  0x10,  0x22,  0x10,  0x3E,  0x1F,  0x22,  0x10, 	/* 4D440 */
+	0x22,  0x10,  0x3E,  0x10,  0x22,  0x10,  0x22,  0x7E,  0x22,  0x42,  0x3E,  0x42,  0x14,  0x42,  0x12,  0x42, 	/* 4D450 */
+	0x22,  0x7E,  0x40,  0x00,  0xBD,  0x00,  0x10,  0x3E,  0x10,  0x22,  0x10,  0x22,  0x24,  0x3E,  0x22,  0x22, 	/* 4D460 */
+	0x4F,  0x23,  0xF1,  0x3E,  0x00,  0x22,  0x00,  0x22,  0x7E,  0x22,  0x42,  0x3E,  0x42,  0x14,  0x42,  0x12, 	/* 4D470 */
+	0x42,  0x22,  0x7E,  0x40,  0x00,  0xBF,  0x01,  0x00,  0x1E,  0x7E,  0x10,  0x12,  0x12,  0x12,  0x11,  0x22, 	/* 4D480 */
+	0x1F,  0x42,  0x71,  0x8C,  0x0F,  0xF8,  0x08,  0x08,  0x0F,  0xF8,  0x08,  0x08,  0x0F,  0xF8,  0x08,  0x08, 	/* 4D490 */
+	0x0F,  0xF8,  0x06,  0x18,  0x38,  0x06,  0x80,  0x08,  0x00,  0x08,  0x7E,  0x7F,  0x42,  0x09,  0x42,  0x09, 	/* 4D4A0 */
+	0x42,  0x11,  0x7E,  0x26,  0x00,  0x4F,  0xF8,  0x08,  0x08,  0x0F,  0xF8,  0x08,  0x08,  0x0F,  0xF8,  0x08, 	/* 4D4B0 */
+	0x08,  0x0F,  0xF8,  0x06,  0x18,  0x38,  0x06,  0x81,  0x00,  0x80,  0x0F,  0xF8,  0x00,  0x80,  0x04,  0x10, 	/* 4D4C0 */
+	0x7F,  0xFF,  0x04,  0x10,  0x00,  0x00,  0x0F,  0xF8,  0x08,  0x08,  0x0F,  0xF8,  0x08,  0x08,  0x0F,  0xF8, 	/* 4D4D0 */
+	0x08,  0x08,  0x0F,  0xF8,  0x06,  0x18,  0x38,  0x06,  0x82,  0x00,  0x20,  0x3E,  0x20,  0x22,  0x3C,  0x22, 	/* 4D4E0 */
+	0x44,  0x3E,  0x48,  0x22,  0xA8,  0x23,  0x10,  0x22,  0x28,  0x3E,  0x44,  0x22,  0x82,  0x23,  0x7D,  0x3E, 	/* 4D4F0 */
+	0x44,  0x14,  0x44,  0x12,  0x44,  0x22,  0x7C,  0x40,  0x00,  0x83,  0x04,  0x18,  0x09,  0xE0,  0x10,  0x20, 	/* 4D500 */
+	0x77,  0xFF,  0x10,  0x20,  0x13,  0xFC,  0x10,  0x00,  0x1F,  0xF0,  0x08,  0x10,  0x0F,  0xF0,  0x08,  0x10, 	/* 4D510 */
+	0x0F,  0xF0,  0x08,  0x10,  0x0F,  0xF0,  0x04,  0x30,  0x38,  0x0C,  0x84,  0x00,  0x10,  0x3E,  0x10,  0x23, 	/* 4D520 */
+	0xFF,  0x22,  0x10,  0x3E,  0x20,  0x22,  0x3E,  0x22,  0x62,  0x3E,  0x62,  0x22,  0xBE,  0x23,  0x22,  0x22, 	/* 4D530 */
+	0x22,  0x3E,  0x3E,  0x14,  0x22,  0x12,  0x22,  0x22,  0x22,  0x40,  0x26,  0x87,  0x20,  0x80,  0x18,  0xFE, 	/* 4D540 */
+	0x01,  0x22,  0x06,  0x24,  0x18,  0xD0,  0x63,  0x0C,  0x0F,  0xFA,  0x08,  0x08,  0x0F,  0xF8,  0x08,  0x08, 	/* 4D550 */
+	0x0F,  0xF8,  0x08,  0x08,  0x0F,  0xF8,  0x02,  0x30,  0x0C,  0x08,  0x30,  0x04,  0x88,  0x00,  0x00,  0x7F, 	/* 4D560 */
+	0xFF,  0x02,  0x20,  0x3F,  0xFE,  0x22,  0x22,  0x3F,  0xFE,  0x00,  0x00,  0x0F,  0xF8,  0x08,  0x08,  0x0F, 	/* 4D570 */
+	0xF8,  0x08,  0x08,  0x0F,  0xF8,  0x08,  0x08,  0x0F,  0xF8,  0x06,  0x18,  0x38,  0x06,  0x8A,  0x00,  0x10, 	/* 4D580 */
+	0x3E,  0x14,  0x22,  0x12,  0x22,  0x12,  0x3F,  0xFF,  0x22,  0x10,  0x22,  0x52,  0x3E,  0x52,  0x23,  0xF2, 	/* 4D590 */
+	0x22,  0x4C,  0x22,  0x4C,  0x3E,  0x48,  0x14,  0x55,  0x12,  0x15,  0x22,  0x23,  0x41,  0x41,  0x8D,  0x00, 	/* 4D5A0 */
+	0x08,  0x3E,  0x08,  0x22,  0x08,  0x22,  0xFF,  0x3E,  0x80,  0x22,  0x88,  0x22,  0x88,  0x3E,  0x88,  0x22, 	/* 4D5B0 */
+	0xBE,  0x22,  0x88,  0x22,  0x88,  0x3E,  0x88,  0x15,  0x08,  0x12,  0x08,  0x22,  0xFF,  0x40,  0x00,  0x8E, 	/* 4D5C0 */
+	0x00,  0x28,  0x3E,  0x24,  0x22,  0x20,  0x22,  0x2E,  0x3E,  0xF0,  0x22,  0x2E,  0x22,  0xF0,  0x3E,  0x17, 	/* 4D5D0 */
+	0x22,  0x18,  0x23,  0xF4,  0x22,  0x14,  0x3E,  0x08,  0x14,  0x1A,  0x12,  0x66,  0x23,  0x86,  0x40,  0x02, 	/* 4D5E0 */
+	0x91,  0x00,  0x00,  0x3E,  0xFF,  0x22,  0x80,  0x22,  0x80,  0x3E,  0xBC,  0x22,  0x80,  0x22,  0x80,  0x3E, 	/* 4D5F0 */
+	0xFE,  0x22,  0xB0,  0x22,  0xB2,  0x22,  0xAA,  0x3E,  0xAC,  0x18,  0xA4,  0x15,  0x24,  0x21,  0x32,  0x42, 	/* 4D600 */
+	0xC1,  0x93,  0x01,  0x00,  0x7F,  0xFE,  0x40,  0x02,  0x5F,  0xFA,  0x05,  0x10,  0x19,  0x68,  0x63,  0x86, 	/* 4D610 */
+	0x0F,  0xF0,  0x78,  0x10,  0x0F,  0xF0,  0x08,  0x10,  0x0F,  0xF0,  0x08,  0x10,  0x0F,  0xF0,  0x06,  0x18, 	/* 4D620 */
+	0x78,  0x06,  0x9A,  0x00,  0x80,  0x7F,  0xFF,  0x08,  0x88,  0x0C,  0x8C,  0x15,  0xD2,  0x22,  0xA0,  0x04, 	/* 4D630 */
+	0x90,  0x1F,  0xFC,  0x68,  0x0B,  0x0F,  0xF8,  0x08,  0x08,  0x0F,  0xF8,  0x08,  0x08,  0x0F,  0xF8,  0x06, 	/* 4D640 */
+	0x18,  0x38,  0x06,  0x9B,  0x04,  0x10,  0x3F,  0x7E,  0x04,  0x10,  0x7F,  0xFF,  0x0A,  0x28,  0x11,  0x44, 	/* 4D650 */
+	0x6F,  0xFB,  0x08,  0x08,  0x0F,  0xF8,  0x08,  0x08,  0x0F,  0xF8,  0x08,  0x08,  0x0F,  0xF8,  0x02,  0x30, 	/* 4D660 */
+	0x0C,  0x0C,  0x30,  0x02,  0x9C,  0x00,  0x00,  0x3E,  0xFC,  0x22,  0x84,  0x22,  0x84,  0x3E,  0xFC,  0x22, 	/* 4D670 */
+	0x84,  0x22,  0x84,  0x3E,  0xFC,  0x22,  0x40,  0x22,  0xFE,  0x23,  0x2A,  0x3E,  0x4A,  0x14,  0x92,  0x12, 	/* 4D680 */
+	0x22,  0x22,  0x42,  0x40,  0x0C,  0x9E,  0x11,  0x10,  0x09,  0x20,  0x7F,  0xFE,  0x40,  0x02,  0x47,  0xE2, 	/* 4D690 */
+	0x04,  0x20,  0x0F,  0xF0,  0x08,  0x10,  0x0F,  0xF0,  0x08,  0x10,  0x0F,  0xF0,  0x08,  0x10,  0x08,  0x10, 	/* 4D6A0 */
+	0x0F,  0xF0,  0x06,  0x30,  0x38,  0x0C,  0xA0,  0x00,  0x20,  0x3E,  0x20,  0x23,  0xFE,  0x22,  0x84,  0x22, 	/* 4D6B0 */
+	0x44,  0x3E,  0x48,  0x22,  0x48,  0x23,  0xFF,  0x3E,  0x00,  0x22,  0x00,  0x22,  0xFC,  0x3E,  0x84,  0x14, 	/* 4D6C0 */
+	0x84,  0x12,  0x84,  0x22,  0xFC,  0x40,  0x00,  0xA2,  0x00,  0x00,  0x3F,  0xFC,  0x24,  0x44,  0x3F,  0x28, 	/* 4D6D0 */
+	0x21,  0x10,  0x3F,  0x28,  0x24,  0xC6,  0x3F,  0xF0,  0x08,  0x10,  0x0F,  0xF0,  0x08,  0x10,  0x0F,  0xF0, 	/* 4D6E0 */
+	0x08,  0x10,  0x0F,  0xF0,  0x06,  0x30,  0x38,  0x0C,  0xA3,  0x00,  0x80,  0x7F,  0xFF,  0x00,  0x80,  0x1F, 	/* 4D6F0 */
+	0xFC,  0x00,  0x00,  0x3F,  0xFE,  0x22,  0x22,  0x3F,  0xFE,  0x08,  0x08,  0x0F,  0xF8,  0x08,  0x08,  0x0F, 	/* 4D700 */
+	0xF8,  0x08,  0x08,  0x0F,  0xF8,  0x06,  0x18,  0x38,  0x06,  0xA4,  0x00,  0x28,  0x3E,  0x24,  0x22,  0x2E, 	/* 4D710 */
+	0x22,  0xF2,  0x3E,  0x14,  0x22,  0x18,  0x22,  0x65,  0x3F,  0xAB,  0x22,  0x24,  0x22,  0x2F,  0x22,  0xF2, 	/* 4D720 */
+	0x3E,  0x14,  0x14,  0x18,  0x12,  0x65,  0x23,  0x83,  0x40,  0x01,  0xA6,  0x00,  0x08,  0x3D,  0xEC,  0x24, 	/* 4D730 */
+	0x0A,  0x24,  0x0A,  0x3F,  0xFF,  0x24,  0x48,  0x24,  0x48,  0x25,  0x48,  0x3D,  0x78,  0x25,  0x48,  0x25, 	/* 4D740 */
+	0x48,  0x3D,  0x44,  0x19,  0x75,  0x15,  0xC5,  0x27,  0x03,  0x40,  0x01,  0xAA,  0x02,  0x04,  0x3C,  0x78, 	/* 4D750 */
+	0x20,  0x40,  0x3F,  0x7F,  0x24,  0x48,  0x24,  0x88,  0x4F,  0xF8,  0x08,  0x10,  0x0F,  0xF0,  0x08,  0x10, 	/* 4D760 */
+	0x0F,  0xF0,  0x08,  0x10,  0x0F,  0xF0,  0x02,  0x60,  0x0C,  0x18,  0x30,  0x04,  0xAD,  0x00,  0x22,  0x3E, 	/* 4D770 */
+	0x22,  0x22,  0xFC,  0x22,  0x24,  0x3E,  0x28,  0x22,  0x28,  0x23,  0xFF,  0x3E,  0x20,  0x22,  0x7C,  0x22, 	/* 4D780 */
+	0xC4,  0x23,  0x44,  0x3E,  0x7C,  0x14,  0x44,  0x12,  0x44,  0x22,  0x7C,  0x40,  0x00,  0xBA,  0x00,  0x12, 	/* 4D790 */
+	0x3E,  0xEC,  0x22,  0x28,  0x23,  0xFF,  0x3E,  0x28,  0x22,  0xFE,  0x22,  0x2A,  0x3F,  0xFF,  0x22,  0x2A, 	/* 4D7A0 */
+	0x22,  0xFE,  0x22,  0x28,  0x3E,  0x2C,  0x14,  0x6C,  0x12,  0xAA,  0x23,  0x29,  0x40,  0x28,  0xBB,  0x00, 	/* 4D7B0 */
+	0x24,  0x3C,  0x22,  0x27,  0xFF,  0x24,  0x20,  0x3D,  0xFC,  0x25,  0x24,  0x25,  0xFC,  0x25,  0x24,  0x3D, 	/* 4D7C0 */
+	0xFC,  0x25,  0x24,  0x24,  0x08,  0x3F,  0xFF,  0x14,  0x88,  0x12,  0x48,  0x22,  0x08,  0x40,  0x18,  0xBC, 	/* 4D7D0 */
+	0x00,  0x48,  0x3C,  0x48,  0x25,  0xFE,  0x24,  0x48,  0x3D,  0xFE,  0x24,  0x48,  0x27,  0xFF,  0x24,  0x20, 	/* 4D7E0 */
+	0x3C,  0xFC,  0x24,  0xA4,  0x24,  0xFC,  0x3C,  0xA4,  0x1B,  0xFF,  0x14,  0x84,  0x24,  0x84,  0x40,  0x8C, 	/* 4D7F0 */
+	0xBD,  0x01,  0x00,  0x7F,  0xFE,  0x44,  0x22,  0x5F,  0xFA,  0x04,  0x20,  0x1F,  0xF8,  0x04,  0x20,  0x7F, 	/* 4D800 */
+	0xFF,  0x04,  0x20,  0x1F,  0xF8,  0x68,  0x16,  0x0F,  0xF0,  0x08,  0x10,  0x0F,  0xF0,  0x06,  0x30,  0x38, 	/* 4D810 */
+	0x0C,  0x84,  0x04,  0x10,  0x1F,  0x10,  0x04,  0x7C,  0x7F,  0x94,  0x0A,  0x34,  0x3F,  0x94,  0x04,  0x2D, 	/* 4D820 */
+	0x1F,  0x43,  0x04,  0x81,  0x0F,  0xF8,  0x08,  0x08,  0x0F,  0xF8,  0x08,  0x08,  0x0F,  0xF8,  0x06,  0x18, 	/* 4D830 */
+	0x38,  0x06,  0x85,  0x04,  0x20,  0x3F,  0x20,  0x04,  0x3F,  0x7F,  0x64,  0x04,  0xB4,  0x0F,  0x08,  0x11, 	/* 4D840 */
+	0x34,  0x2F,  0xFB,  0x48,  0x08,  0x0F,  0xF8,  0x08,  0x08,  0x0F,  0xF8,  0x08,  0x08,  0x0F,  0xF8,  0x06, 	/* 4D850 */
+	0x30,  0x38,  0x0E,  0x87,  0x04,  0xEA,  0x04,  0x09,  0x7F,  0xFF,  0x12,  0x28,  0x0A,  0xB4,  0x0C,  0xA5, 	/* 4D860 */
+	0x12,  0xF3,  0x6F,  0xF9,  0x08,  0x08,  0x0F,  0xF8,  0x08,  0x08,  0x0F,  0xF8,  0x08,  0x08,  0x0F,  0xF8, 	/* 4D870 */
+	0x04,  0x10,  0x38,  0x0E,  0x88,  0x00,  0x42,  0x3E,  0x24,  0x22,  0xFF,  0x22,  0x91,  0x22,  0x91,  0x3E, 	/* 4D880 */
+	0xFF,  0x22,  0x91,  0x22,  0xFF,  0x3E,  0x00,  0x22,  0x7E,  0x22,  0x42,  0x3E,  0x7E,  0x14,  0x42,  0x12, 	/* 4D890 */
+	0x42,  0x22,  0x7E,  0x40,  0x00,  0x8A,  0x14,  0x28,  0x1F,  0x3E,  0x24,  0x48,  0x7F,  0xFF,  0x0A,  0x14, 	/* 4D8A0 */
+	0x0A,  0x95,  0x13,  0x23,  0x6F,  0xF8,  0x08,  0x08,  0x0F,  0xF8,  0x08,  0x08,  0x0F,  0xF8,  0x08,  0x08, 	/* 4D8B0 */
+	0x0F,  0xF8,  0x06,  0x18,  0x38,  0x06,  0x8B,  0x00,  0x00,  0x1F,  0xFE,  0x12,  0x48,  0x12,  0xFE,  0x15, 	/* 4D8C0 */
+	0x90,  0x1E,  0xFC,  0x14,  0x90,  0x17,  0xFF,  0x12,  0x08,  0x13,  0xF8,  0x12,  0x08,  0x13,  0xF8,  0x22, 	/* 4D8D0 */
+	0x08,  0x23,  0xF8,  0x43,  0x18,  0x1C,  0x06,  0x8D,  0x00,  0x20,  0x3E,  0x7C,  0x22,  0x88,  0x23,  0xFF, 	/* 4D8E0 */
+	0x3E,  0x95,  0x22,  0xE3,  0x22,  0x9C,  0x3E,  0x80,  0x22,  0xFF,  0x22,  0x80,  0x22,  0x9C,  0x3E,  0x80, 	/* 4D8F0 */
+	0x15,  0x3E,  0x13,  0x22,  0x22,  0x3E,  0x40,  0x00,  0x8F,  0x00,  0x80,  0x3F,  0xFF,  0x10,  0x00,  0x0F, 	/* 4D900 */
+	0xFC,  0x04,  0x08,  0x07,  0xF8,  0x04,  0x08,  0x07,  0xF8,  0x00,  0x00,  0x3D,  0xDE,  0x25,  0x52,  0x3D, 	/* 4D910 */
+	0xDA,  0x25,  0x56,  0x3D,  0xD2,  0x24,  0x92,  0x4D,  0x63,  0x90,  0x00,  0x10,  0x3E,  0xFE,  0x22,  0x12, 	/* 4D920 */
+	0x23,  0xFF,  0x3E,  0x12,  0x22,  0xFE,  0x22,  0x10,  0x3F,  0xFF,  0x22,  0xAA,  0x23,  0x15,  0x22,  0x00, 	/* 4D930 */
+	0x3E,  0xFE,  0x14,  0xAA,  0x12,  0xAA,  0x23,  0xFF,  0x40,  0x00,  0x93,  0x00,  0x08,  0x3C,  0x0A,  0x24, 	/* 4D940 */
+	0x09,  0x26,  0xFF,  0x3E,  0x88,  0x26,  0xFA,  0x27,  0xAA,  0x3C,  0xFA,  0x24,  0x9A,  0x27,  0xFA,  0x26, 	/* 4D950 */
+	0xAC,  0x3E,  0xA5,  0x1A,  0xF5,  0x14,  0x8B,  0x21,  0x13,  0x42,  0x21,  0x94,  0x00,  0x00,  0x07,  0xF0, 	/* 4D960 */
+	0x04,  0x10,  0x07,  0xF0,  0x04,  0x10,  0x07,  0xF0,  0x02,  0x30,  0x0C,  0x08,  0x3F,  0x7E,  0x21,  0x42, 	/* 4D970 */
+	0x3D,  0x7A,  0x2F,  0x5E,  0x21,  0x42,  0x3F,  0x7E,  0x12,  0x26,  0x61,  0xC1,  0x96,  0x00,  0x10,  0x3E, 	/* 4D980 */
+	0xFF,  0x22,  0x10,  0x22,  0x7E,  0x3E,  0x00,  0x22,  0xFF,  0x22,  0xA5,  0x3E,  0xFF,  0x22,  0x42,  0x22, 	/* 4D990 */
+	0x7E,  0x22,  0x42,  0x3E,  0x7E,  0x14,  0x42,  0x12,  0x7E,  0x22,  0x62,  0x41,  0x81,  0xA4,  0x00,  0x80, 	/* 4D9A0 */
+	0x00,  0x80,  0x0F,  0xF8,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x7F,  0xFF,  0x01,  0x20,  0x09,  0x28, 	/* 4D9B0 */
+	0x09,  0x24,  0x09,  0x24,  0x11,  0x22,  0x22,  0x22,  0x02,  0x20,  0x04,  0x20,  0x08,  0x60,  0xA6,  0x04, 	/* 4D9C0 */
+	0x20,  0x04,  0x20,  0x3F,  0xA0,  0x04,  0x3F,  0x04,  0x44,  0x04,  0x44,  0x7F,  0x84,  0x0A,  0x24,  0x0A, 	/* 4D9D0 */
+	0x28,  0x2B,  0x28,  0x2A,  0x98,  0x2A,  0x98,  0x4A,  0x94,  0x12,  0x24,  0x12,  0x42,  0x26,  0x81,  0xA7, 	/* 4D9E0 */
+	0x04,  0x00,  0x04,  0x7E,  0x3F,  0x42,  0x04,  0x42,  0x04,  0x42,  0x04,  0x7E,  0x7F,  0xC0,  0x0A,  0x40, 	/* 4D9F0 */
+	0x0A,  0x7E,  0x2B,  0x52,  0x2A,  0xD4,  0x2A,  0xCC,  0x4A,  0xC8,  0x12,  0x54,  0x12,  0x62,  0x26,  0x41, 	/* 4DA00 */
+	0xAB,  0x04,  0x10,  0x04,  0x10,  0x3F,  0x7E,  0x04,  0x10,  0x04,  0x10,  0x04,  0x10,  0x7F,  0xFF,  0x0A, 	/* 4DA10 */
+	0x28,  0x0B,  0x2C,  0x2A,  0xAC,  0x2A,  0xEA,  0x2A,  0x6A,  0x4A,  0xAA,  0x12,  0x48,  0x12,  0x48,  0x26, 	/* 4DA20 */
+	0x98,  0xAD,  0x04,  0x10,  0x04,  0x12,  0x3F,  0x7E,  0x04,  0x14,  0x04,  0x14,  0x04,  0x18,  0x7F,  0xFF, 	/* 4DA30 */
+	0x0A,  0x14,  0x0A,  0x22,  0x2B,  0x7E,  0x2A,  0xA2,  0x2A,  0xBE,  0x4A,  0xA2,  0x12,  0x22,  0x12,  0x3E, 	/* 4DA40 */
+	0x26,  0x00,  0xB0,  0x00,  0x80,  0x00,  0x80,  0x1F,  0xFC,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x7F, 	/* 4DA50 */
+	0xFF,  0x00,  0x80,  0x08,  0x80,  0x08,  0x80,  0x08,  0xFC,  0x08,  0x80,  0x14,  0x80,  0x12,  0x80,  0x21, 	/* 4DA60 */
+	0xC0,  0x40,  0x3E,  0xB1,  0x00,  0x80,  0x00,  0x80,  0x1F,  0xFC,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80, 	/* 4DA70 */
+	0x7F,  0xFE,  0x08,  0x08,  0x04,  0x10,  0x04,  0x20,  0x00,  0x40,  0x11,  0x80,  0x1A,  0x00,  0x16,  0x00, 	/* 4DA80 */
+	0x21,  0xC0,  0x40,  0x3F,  0xB3,  0x04,  0x04,  0x04,  0x04,  0x3F,  0x24,  0x04,  0x24,  0x04,  0x24,  0x04, 	/* 4DA90 */
+	0x24,  0x7F,  0xA4,  0x04,  0x24,  0x14,  0x24,  0x17,  0x27,  0x14,  0x3C,  0x1C,  0xC4,  0x14,  0x04,  0x22, 	/* 4DAA0 */
+	0x04,  0x21,  0x80,  0x40,  0x7F,  0xB4,  0x04,  0x10,  0x04,  0x10,  0x3F,  0x90,  0x04,  0x10,  0x04,  0x10, 	/* 4DAB0 */
+	0x04,  0x18,  0x7F,  0xD4,  0x04,  0x12,  0x14,  0x12,  0x17,  0x90,  0x14,  0x10,  0x1C,  0x10,  0x14,  0x10, 	/* 4DAC0 */
+	0x23,  0x10,  0x20,  0xE0,  0x40,  0x1F,  0xB7,  0x04,  0x00,  0x04,  0x3E,  0x3F,  0x82,  0x04,  0x02,  0x04, 	/* 4DAD0 */
+	0x02,  0x04,  0x02,  0x7F,  0xFE,  0x04,  0x20,  0x14,  0x20,  0x17,  0xA0,  0x14,  0x21,  0x1C,  0x11,  0x14, 	/* 4DAE0 */
+	0x0F,  0x26,  0x00,  0x21,  0xC0,  0x40,  0x3F,  0x81,  0x04,  0x10,  0x04,  0x10,  0x3F,  0x28,  0x04,  0x28, 	/* 4DAF0 */
+	0x04,  0x44,  0x04,  0x8A,  0x7F,  0x31,  0x04,  0xC4,  0x14,  0x08,  0x17,  0x32,  0x14,  0xC4,  0x1C,  0x08, 	/* 4DB00 */
+	0x14,  0x30,  0x22,  0xC0,  0x21,  0x80,  0x40,  0x7F,  0x85,  0x04,  0x00,  0x04,  0xFE,  0x3F,  0x22,  0x04, 	/* 4DB10 */
+	0x22,  0x04,  0x22,  0x04,  0x42,  0x7F,  0x4C,  0x04,  0x80,  0x14,  0x7E,  0x17,  0x42,  0x14,  0x42,  0x1C, 	/* 4DB20 */
+	0x42,  0x14,  0x7E,  0x22,  0x00,  0x21,  0x80,  0x40,  0x7F,  0x8A,  0x04,  0x14,  0x04,  0x12,  0x04,  0x10, 	/* 4DB30 */
+	0x1F,  0x7F,  0x04,  0x50,  0x04,  0x52,  0x3F,  0xD2,  0x04,  0x52,  0x14,  0x54,  0x17,  0x4C,  0x14,  0x69, 	/* 4DB40 */
+	0x15,  0x95,  0x1C,  0x23,  0x24,  0xC1,  0x23,  0x00,  0x40,  0xFF,  0x99,  0x04,  0x10,  0x04,  0x54,  0x3F, 	/* 4DB50 */
+	0x52,  0x04,  0x92,  0x04,  0x7C,  0x04,  0x44,  0x7F,  0xC4,  0x04,  0x7C,  0x14,  0x44,  0x17,  0x44,  0x14, 	/* 4DB60 */
+	0x7C,  0x1C,  0x44,  0x14,  0x44,  0x22,  0x4C,  0x21,  0x80,  0x40,  0x7F,  0xA3,  0x08,  0x00,  0x09,  0xFE, 	/* 4DB70 */
+	0x08,  0xA0,  0x3E,  0xBE,  0x08,  0xE2,  0x08,  0xAA,  0x7F,  0xAA,  0x08,  0xEC,  0x28,  0xA4,  0x2E,  0xA4, 	/* 4DB80 */
+	0x28,  0xEA,  0x3B,  0x32,  0x28,  0x21,  0x24,  0x20,  0x23,  0x00,  0x40,  0xFF,  0xA8,  0x04,  0x40,  0x04, 	/* 4DB90 */
+	0x7E,  0x04,  0xA2,  0x3F,  0xAA,  0x04,  0xFA,  0x04,  0x22,  0x7F,  0x8C,  0x04,  0x40,  0x14,  0x7E,  0x17, 	/* 4DBA0 */
+	0xA2,  0x14,  0xAA,  0x15,  0xFA,  0x1C,  0x22,  0x24,  0xCC,  0x23,  0x00,  0x40,  0xFF,  0xB3,  0x00,  0x00, 	/* 4DBB0 */
+	0x0F,  0xF8,  0x08,  0x08,  0x08,  0x08,  0x08,  0x08,  0x08,  0x08,  0x0F,  0xF8,  0x00,  0x80,  0x10,  0x80, 	/* 4DBC0 */
+	0x10,  0x80,  0x10,  0xFC,  0x18,  0x80,  0x14,  0x80,  0x23,  0x80,  0x20,  0xC0,  0x40,  0x3F,  0xBA,  0x00, 	/* 4DBD0 */
+	0x10,  0x3E,  0x10,  0x22,  0x10,  0x22,  0xFE,  0x22,  0x10,  0x3E,  0x10,  0x08,  0x10,  0x08,  0x10,  0x29, 	/* 4DBE0 */
+	0xFF,  0x2E,  0x10,  0x28,  0x28,  0x28,  0x28,  0x28,  0x44,  0x2E,  0x44,  0x38,  0x82,  0x61,  0x01,  0xBE, 	/* 4DBF0 */
+	0x00,  0x10,  0x3E,  0x10,  0x22,  0x10,  0x22,  0x10,  0x22,  0x90,  0x3E,  0x90,  0x08,  0x9E,  0x08,  0x90, 	/* 4DC00 */
+	0x28,  0x90,  0x2E,  0x90,  0x28,  0x90,  0x28,  0x90,  0x28,  0x90,  0x2E,  0x90,  0x3B,  0xFF,  0x60,  0x00, 	/* 4DC10 */
+	0x82,  0x00,  0x10,  0x3E,  0x10,  0x22,  0x10,  0x23,  0xFF,  0x22,  0x10,  0x3E,  0x10,  0x08,  0xFC,  0x08, 	/* 4DC20 */
+	0x44,  0x28,  0x44,  0x2E,  0x24,  0x28,  0x28,  0x28,  0x10,  0x28,  0x18,  0x2E,  0x24,  0x38,  0xC2,  0x63, 	/* 4DC30 */
+	0x01,  0x8B,  0x00,  0x28,  0x3E,  0x24,  0x22,  0x24,  0x23,  0xFF,  0x22,  0x20,  0x3E,  0x22,  0x08,  0x22, 	/* 4DC40 */
+	0x08,  0x32,  0x28,  0x54,  0x2E,  0x54,  0x28,  0x48,  0x28,  0x88,  0x28,  0x94,  0x2F,  0x14,  0x3A,  0x22, 	/* 4DC50 */
+	0x60,  0x41,  0x8C,  0x00,  0x10,  0x3E,  0x50,  0x22,  0x50,  0x22,  0x50,  0x22,  0xFE,  0x3E,  0x90,  0x09, 	/* 4DC60 */
+	0x10,  0x08,  0x10,  0x29,  0xFF,  0x2E,  0x10,  0x28,  0x28,  0x28,  0x28,  0x28,  0x44,  0x2E,  0x44,  0x38, 	/* 4DC70 */
+	0x82,  0x61,  0x01,  0x8F,  0x00,  0x80,  0x3C,  0x80,  0x24,  0x8E,  0x24,  0x8A,  0x27,  0xEA,  0x3C,  0xAA, 	/* 4DC80 */
+	0x08,  0xAA,  0x08,  0xAA,  0x28,  0xAA,  0x2E,  0xAA,  0x28,  0xAA,  0x29,  0x2A,  0x29,  0x2A,  0x2D,  0x2E, 	/* 4DC90 */
+	0x3A,  0x20,  0x64,  0xC0,  0x96,  0x00,  0x00,  0x3F,  0xFF,  0x22,  0x20,  0x22,  0x20,  0x22,  0x20,  0x3E, 	/* 4DCA0 */
+	0x40,  0x08,  0x40,  0x08,  0x7C,  0x28,  0xC4,  0x2E,  0xC4,  0x29,  0x44,  0x28,  0x44,  0x28,  0x44,  0x2E, 	/* 4DCB0 */
+	0x44,  0x38,  0x7C,  0x60,  0x00,  0x9A,  0x00,  0x00,  0x3E,  0xFE,  0x22,  0xAA,  0x22,  0xAA,  0x22,  0xAA, 	/* 4DCC0 */
+	0x3E,  0xAA,  0x08,  0xAA,  0x09,  0xFF,  0x28,  0xAA,  0x2E,  0xAA,  0x28,  0xAA,  0x28,  0xAA,  0x28,  0xAA, 	/* 4DCD0 */
+	0x2E,  0xAA,  0x38,  0xAA,  0x60,  0x86,  0x9B,  0x00,  0x10,  0x3E,  0x10,  0x22,  0x10,  0x22,  0xFF,  0x22, 	/* 4DCE0 */
+	0x91,  0x3E,  0x92,  0x08,  0x90,  0x08,  0xFC,  0x28,  0xA4,  0x2E,  0xA4,  0x28,  0x94,  0x28,  0x98,  0x29, 	/* 4DCF0 */
+	0x18,  0x2F,  0x24,  0x3A,  0x42,  0x61,  0x81,  0x9D,  0x00,  0x00,  0x3E,  0xFE,  0x22,  0x80,  0x22,  0x80, 	/* 4DD00 */
+	0x22,  0x80,  0x22,  0xFC,  0x3E,  0x84,  0x08,  0x84,  0x28,  0x84,  0x2E,  0xFC,  0x28,  0x80,  0x28,  0x80, 	/* 4DD10 */
+	0x28,  0x80,  0x2F,  0x80,  0x38,  0xFF,  0x60,  0x00,  0x9F,  0x00,  0x00,  0x3E,  0xFC,  0x22,  0x84,  0x22, 	/* 4DD20 */
+	0x84,  0x22,  0xFC,  0x3E,  0x84,  0x08,  0x84,  0x08,  0xFC,  0x28,  0xA2,  0x2E,  0xA2,  0x28,  0x94,  0x28, 	/* 4DD30 */
+	0x94,  0x28,  0x88,  0x2E,  0xA4,  0x38,  0xC2,  0x63,  0x01,  0xA1,  0x00,  0x10,  0x3E,  0x10,  0x22,  0x10, 	/* 4DD40 */
+	0x23,  0xFF,  0x22,  0x28,  0x22,  0x28,  0x3E,  0x28,  0x08,  0xAC,  0x28,  0xAA,  0x2E,  0xAA,  0x29,  0x29, 	/* 4DD50 */
+	0x2A,  0x29,  0x28,  0x48,  0x2E,  0x48,  0x38,  0x88,  0x61,  0x18,  0xA3,  0x00,  0x10,  0x3E,  0x50,  0x22, 	/* 4DD60 */
+	0x50,  0x22,  0x7E,  0x22,  0x90,  0x3E,  0x90,  0x09,  0x10,  0x09,  0xFF,  0x28,  0x28,  0x2E,  0x28,  0x28, 	/* 4DD70 */
+	0x28,  0x28,  0x48,  0x28,  0x48,  0x2E,  0x89,  0x39,  0x09,  0x62,  0x07,  0xA8,  0x00,  0x10,  0x3E,  0x10, 	/* 4DD80 */
+	0x23,  0xFF,  0x22,  0x28,  0x22,  0x24,  0x22,  0x42,  0x3E,  0xFD,  0x09,  0x00,  0x28,  0xFE,  0x2F,  0x10, 	/* 4DD90 */
+	0x28,  0x10,  0x28,  0x3E,  0x28,  0x22,  0x2E,  0x02,  0x38,  0x02,  0x60,  0x0C,  0xAA,  0x00,  0x20,  0x3E, 	/* 4DDA0 */
+	0x3C,  0x22,  0x48,  0x22,  0x90,  0x23,  0xFF,  0x3E,  0x80,  0x08,  0x80,  0x08,  0xBC,  0x28,  0xA4,  0x2E, 	/* 4DDB0 */
+	0xA4,  0x28,  0xA4,  0x28,  0xAC,  0x28,  0xA0,  0x2F,  0x21,  0x39,  0x21,  0x62,  0x1F,  0xAB,  0x00,  0x00, 	/* 4DDC0 */
+	0x3E,  0xFC,  0x08,  0x84,  0x08,  0xA4,  0x08,  0x94,  0x0E,  0x95,  0x71,  0x03,  0x02,  0x01,  0x0F,  0xF8, 	/* 4DDD0 */
+	0x08,  0x08,  0x08,  0x08,  0x0F,  0xF8,  0x04,  0x80,  0x0C,  0xFC,  0x13,  0x80,  0x60,  0xFF,  0xAF,  0x00, 	/* 4DDE0 */
+	0x40,  0x3E,  0x40,  0x22,  0x7C,  0x22,  0x44,  0x22,  0xC8,  0x3E,  0xA8,  0x09,  0x10,  0x28,  0x28,  0x28, 	/* 4DDF0 */
+	0x44,  0x2E,  0x82,  0x29,  0x7D,  0x28,  0x44,  0x29,  0x44,  0x2E,  0x44,  0x38,  0x7C,  0x60,  0x00,  0xB3, 	/* 4DE00 */
+	0x00,  0x28,  0x3E,  0x28,  0x22,  0x2A,  0x23,  0x2A,  0x22,  0xAC,  0x22,  0xAC,  0x3E,  0x28,  0x08,  0x68, 	/* 4DE10 */
+	0x28,  0x6C,  0x2E,  0xAA,  0x29,  0x29,  0x28,  0x48,  0x28,  0x48,  0x2E,  0x89,  0x39,  0x09,  0x62,  0x07, 	/* 4DE20 */
+	0xB5,  0x00,  0x28,  0x3E,  0x24,  0x22,  0x20,  0x22,  0x3E,  0x22,  0xE0,  0x22,  0x3E,  0x3E,  0xE0,  0x08, 	/* 4DE30 */
+	0x1F,  0x28,  0xF0,  0x2E,  0x14,  0x28,  0x14,  0x28,  0x08,  0x29,  0x1A,  0x2E,  0x66,  0x39,  0x86,  0x60, 	/* 4DE40 */
+	0x02,  0xBC,  0x00,  0x00,  0x3E,  0xFE,  0x22,  0x82,  0x22,  0x82,  0x22,  0xFE,  0x3E,  0x80,  0x08,  0x80, 	/* 4DE50 */
+	0x08,  0xFE,  0x28,  0x82,  0x2E,  0xBA,  0x28,  0xAA,  0x28,  0xAA,  0x28,  0xAA,  0x2F,  0x3A,  0x39,  0x02, 	/* 4DE60 */
+	0x62,  0x0C,  0xBF,  0x00,  0x10,  0x3E,  0x10,  0x22,  0xFE,  0x22,  0x10,  0x22,  0x10,  0x3E,  0x10,  0x09, 	/* 4DE70 */
+	0xFF,  0x08,  0x10,  0x28,  0x10,  0x2E,  0x50,  0x28,  0x5E,  0x28,  0x50,  0x28,  0xD0,  0x2E,  0xB0,  0x39, 	/* 4DE80 */
+	0x18,  0x62,  0x07,  0x88,  0x00,  0x10,  0x3E,  0x10,  0x23,  0xFF,  0x22,  0x10,  0x22,  0xFE,  0x3E,  0x92, 	/* 4DE90 */
+	0x08,  0x92,  0x08,  0x92,  0x28,  0xFE,  0x2E,  0x10,  0x28,  0x38,  0x28,  0x38,  0x28,  0x54,  0x2E,  0x92, 	/* 4DEA0 */
+	0x39,  0x11,  0x60,  0x10,  0x89,  0x00,  0x10,  0x3E,  0x10,  0x22,  0xFC,  0x22,  0x84,  0x22,  0x84,  0x3E, 	/* 4DEB0 */
+	0xFC,  0x08,  0x84,  0x08,  0x84,  0x28,  0xFC,  0x2E,  0x92,  0x28,  0x92,  0x28,  0x8C,  0x28,  0x88,  0x2E, 	/* 4DEC0 */
+	0xA4,  0x38,  0xC2,  0x63,  0x01,  0x8A,  0x00,  0x00,  0x3E,  0xFE,  0x22,  0x04,  0x22,  0x68,  0x22,  0x10, 	/* 4DED0 */
+	0x3E,  0xFE,  0x08,  0x92,  0x28,  0x92,  0x28,  0xFE,  0x2E,  0x92,  0x28,  0x92,  0x28,  0xFE,  0x28,  0x92, 	/* 4DEE0 */
+	0x2E,  0x92,  0x38,  0x92,  0x60,  0x96,  0x8F,  0x00,  0x10,  0x3E,  0x12,  0x23,  0xF4,  0x22,  0x58,  0x22, 	/* 4DEF0 */
+	0x58,  0x22,  0x94,  0x3F,  0x12,  0x08,  0x31,  0x28,  0x00,  0x2E,  0xFC,  0x28,  0x84,  0x28,  0xFC,  0x28, 	/* 4DF00 */
+	0x84,  0x2E,  0x84,  0x38,  0xFC,  0x60,  0x00,  0x90,  0x00,  0x28,  0x3E,  0x24,  0x22,  0x2E,  0x23,  0xF2, 	/* 4DF10 */
+	0x22,  0x14,  0x3E,  0x18,  0x08,  0x65,  0x09,  0xAB,  0x28,  0x24,  0x2E,  0x2F,  0x29,  0xF2,  0x28,  0x14, 	/* 4DF20 */
+	0x28,  0x18,  0x2E,  0x65,  0x39,  0x83,  0x60,  0x01,  0x9D,  0x00,  0x00,  0x3E,  0xFE,  0x22,  0x92,  0x22, 	/* 4DF30 */
+	0x92,  0x22,  0xFE,  0x3E,  0x92,  0x08,  0x92,  0x08,  0xFE,  0x28,  0x10,  0x2E,  0xFF,  0x28,  0x10,  0x28, 	/* 4DF40 */
+	0x38,  0x28,  0x54,  0x2E,  0x92,  0x39,  0x11,  0x60,  0x10,  0x9E,  0x00,  0x00,  0x3E,  0xFE,  0x22,  0x82, 	/* 4DF50 */
+	0x22,  0x82,  0x22,  0xFE,  0x3E,  0x88,  0x08,  0x88,  0x08,  0xFF,  0x28,  0x88,  0x2E,  0x88,  0x28,  0xBE, 	/* 4DF60 */
+	0x28,  0xA2,  0x29,  0x22,  0x2F,  0x22,  0x3A,  0x3E,  0x60,  0x00,  0x9F,  0x01,  0x00,  0x3D,  0x00,  0x25, 	/* 4DF70 */
+	0x00,  0x25,  0xFE,  0x26,  0x92,  0x3C,  0x92,  0x08,  0x92,  0x0B,  0xF2,  0x28,  0x92,  0x2E,  0x92,  0x28, 	/* 4DF80 */
+	0x92,  0x28,  0xD2,  0x29,  0x32,  0x2D,  0x1E,  0x32,  0x00,  0x64,  0x00,  0xAA,  0x00,  0x10,  0x3E,  0x10, 	/* 4DF90 */
+	0x22,  0xFF,  0x22,  0x81,  0x22,  0x81,  0x3E,  0x7E,  0x08,  0x00,  0x08,  0x00,  0x29,  0xFF,  0x2E,  0x10, 	/* 4DFA0 */
+	0x28,  0x54,  0x28,  0x52,  0x28,  0x92,  0x2E,  0x91,  0x39,  0x11,  0x60,  0x30,  0xB0,  0x00,  0x70,  0x3E, 	/* 4DFB0 */
+	0x10,  0x22,  0x28,  0x22,  0x44,  0x22,  0xBA,  0x3F,  0x01,  0x09,  0xEA,  0x09,  0x2A,  0x29,  0xAA,  0x2F, 	/* 4DFC0 */
+	0x74,  0x29,  0x34,  0x29,  0xB4,  0x29,  0x6A,  0x2F,  0x2A,  0x39,  0x2A,  0x61,  0x6A,  0xB4,  0x00,  0x00, 	/* 4DFD0 */
+	0x3E,  0xFE,  0x22,  0x24,  0x22,  0x18,  0x22,  0xFE,  0x3E,  0x92,  0x08,  0xFE,  0x08,  0x92,  0x28,  0x92, 	/* 4DFE0 */
+	0x2E,  0xFE,  0x28,  0x10,  0x29,  0xFE,  0x28,  0x12,  0x2E,  0x22,  0x38,  0xC2,  0x63,  0x0C,  0xB5,  0x00, 	/* 4DFF0 */
+	0x04,  0x3E,  0x18,  0x22,  0xF0,  0x22,  0x10,  0x23,  0xFF,  0x3E,  0x10,  0x08,  0xFE,  0x08,  0x92,  0x28, 	/* 4E000 */
+	0xFE,  0x2E,  0x92,  0x28,  0xFE,  0x28,  0x10,  0x28,  0xFE,  0x2E,  0x10,  0x39,  0xFF,  0x60,  0x00,  0x82, 	/* 4E010 */
+	0x00,  0x00,  0x3E,  0xFE,  0x22,  0x24,  0x22,  0x18,  0x23,  0xFF,  0x3E,  0x32,  0x08,  0x54,  0x08,  0x90, 	/* 4E020 */
+	0x28,  0x30,  0x2E,  0x10,  0x29,  0xFF,  0x28,  0x38,  0x28,  0x54,  0x2E,  0x92,  0x39,  0x11,  0x60,  0x10, 	/* 4E030 */
+	0x84,  0x00,  0x10,  0x3E,  0x10,  0x22,  0xFE,  0x22,  0x44,  0x22,  0x24,  0x22,  0x28,  0x3F,  0xFF,  0x09, 	/* 4E040 */
+	0x11,  0x29,  0x11,  0x2E,  0xFE,  0x28,  0x92,  0x28,  0x92,  0x28,  0x92,  0x2E,  0x9C,  0x38,  0x10,  0x60, 	/* 4E050 */
+	0x10,  0x87,  0x01,  0x00,  0x7F,  0xFE,  0x44,  0x22,  0x5F,  0xFA,  0x04,  0x20,  0x1F,  0xF8,  0x04,  0x20, 	/* 4E060 */
+	0x7F,  0xFF,  0x08,  0x10,  0x17,  0xFC,  0x64,  0x13,  0x07,  0xF0,  0x04,  0x80,  0x06,  0xFC,  0x19,  0x80, 	/* 4E070 */
+	0x60,  0x7F,  0x88,  0x00,  0x02,  0x3E,  0x0C,  0x22,  0xF4,  0x22,  0x22,  0x22,  0x92,  0x3E,  0x91,  0x09, 	/* 4E080 */
+	0x11,  0x08,  0x20,  0x28,  0xCE,  0x2E,  0x82,  0x28,  0x82,  0x28,  0xEE,  0x28,  0x82,  0x2E,  0x82,  0x38, 	/* 4E090 */
+	0xFE,  0x60,  0x00,  0x89,  0x00,  0x84,  0x3E,  0x48,  0x23,  0xFE,  0x22,  0x20,  0x22,  0x20,  0x3E,  0xFC, 	/* 4E0A0 */
+	0x08,  0x20,  0x08,  0x20,  0x29,  0xFF,  0x2E,  0x40,  0x28,  0x7E,  0x28,  0x90,  0x29,  0x10,  0x2E,  0x10, 	/* 4E0B0 */
+	0x39,  0xFF,  0x60,  0x00,  0x8A,  0x00,  0x04,  0x3E,  0x18,  0x22,  0xE4,  0x22,  0x92,  0x22,  0x92,  0x3E, 	/* 4E0C0 */
+	0x81,  0x09,  0x11,  0x08,  0x24,  0x28,  0xE8,  0x2E,  0x16,  0x29,  0xFD,  0x28,  0x10,  0x29,  0xFF,  0x2E, 	/* 4E0D0 */
+	0x28,  0x38,  0x44,  0x61,  0x83,  0x8C,  0x00,  0x10,  0x3E,  0x10,  0x22,  0x28,  0x22,  0x28,  0x22,  0x7C, 	/* 4E0E0 */
+	0x22,  0x82,  0x3F,  0x7D,  0x08,  0x44,  0x28,  0x7C,  0x2E,  0x44,  0x28,  0x7C,  0x28,  0x80,  0x2A,  0xFE, 	/* 4E0F0 */
+	0x2D,  0x42,  0x32,  0x7E,  0x60,  0x00,  0x90,  0x00,  0x10,  0x3E,  0x10,  0x23,  0xD7,  0x22,  0x10,  0x23, 	/* 4E100 */
+	0xAB,  0x3E,  0x28,  0x08,  0x44,  0x08,  0x44,  0x28,  0xFE,  0x2F,  0x45,  0x28,  0x7C,  0x28,  0x44,  0x28, 	/* 4E110 */
+	0x7C,  0x2E,  0x44,  0x38,  0x44,  0x60,  0x4C,  0x95,  0x00,  0x00,  0x3E,  0xFE,  0x22,  0x92,  0x22,  0xFE, 	/* 4E120 */
+	0x22,  0x92,  0x3E,  0x92,  0x08,  0xFE,  0x08,  0x54,  0x29,  0xFF,  0x2E,  0x54,  0x28,  0x54,  0x28,  0xFE, 	/* 4E130 */
+	0x28,  0x10,  0x2E,  0xFE,  0x38,  0x10,  0x60,  0x10,  0x99,  0x00,  0x28,  0x00,  0x24,  0x1F,  0xFF,  0x12, 	/* 4E140 */
+	0x20,  0x13,  0x92,  0x12,  0x14,  0x1F,  0xC8,  0x2A,  0x95,  0x2A,  0x63,  0x57,  0xF9,  0x04,  0x08,  0x07, 	/* 4E150 */
+	0xF8,  0x02,  0x40,  0x03,  0x7C,  0x0C,  0xC0,  0x70,  0x3F,  0x9F,  0x00,  0x10,  0x3E,  0xFE,  0x22,  0x10, 	/* 4E160 */
+	0x22,  0xFE,  0x22,  0x10,  0x23,  0xFF,  0x3E,  0x00,  0x08,  0x7C,  0x28,  0x44,  0x2F,  0x7C,  0x28,  0x44, 	/* 4E170 */
+	0x28,  0x7C,  0x29,  0x44,  0x2E,  0x7C,  0x38,  0x46,  0x61,  0x81,  0xA0,  0x00,  0x10,  0x3E,  0x10,  0x22, 	/* 4E180 */
+	0xFF,  0x22,  0x80,  0x22,  0xA4,  0x3E,  0xA4,  0x08,  0xFF,  0x08,  0xA4,  0x28,  0xA4,  0x2E,  0xA4,  0x28, 	/* 4E190 */
+	0xBC,  0x29,  0x00,  0x29,  0x00,  0x2E,  0xAA,  0x38,  0x95,  0x61,  0x01,  0xA3,  0x00,  0x48,  0x3E,  0x48, 	/* 4E1A0 */
+	0x23,  0xFF,  0x22,  0x48,  0x22,  0x48,  0x3E,  0x78,  0x08,  0x10,  0x09,  0xFE,  0x29,  0x12,  0x2F,  0xDE, 	/* 4E1B0 */
+	0x29,  0x56,  0x29,  0x56,  0x29,  0xBA,  0x2F,  0x12,  0x39,  0x12,  0x61,  0x16,  0xA4,  0x00,  0x92,  0x3C, 	/* 4E1C0 */
+	0x92,  0x25,  0x12,  0x25,  0x2D,  0x26,  0x24,  0x3C,  0xC8,  0x08,  0x88,  0x09,  0x08,  0x29,  0x28,  0x2F, 	/* 4E1D0 */
+	0x2E,  0x29,  0x28,  0x29,  0x28,  0x29,  0x28,  0x2D,  0x58,  0x31,  0x48,  0x41,  0x87,  0xB2,  0x00,  0x1C, 	/* 4E1E0 */
+	0x3E,  0x44,  0x22,  0x44,  0x22,  0xFE,  0x23,  0x29,  0x3E,  0xFE,  0x08,  0xAA,  0x08,  0xCE,  0x28,  0xFE, 	/* 4E1F0 */
+	0x2E,  0x82,  0x28,  0xFE,  0x28,  0x04,  0x29,  0xFF,  0x2E,  0x44,  0x38,  0x24,  0x60,  0x0C,  0xB4,  0x00, 	/* 4E200 */
+	0x88,  0x3C,  0x8C,  0x24,  0x8A,  0x27,  0xEA,  0x24,  0x3F,  0x25,  0xC8,  0x3D,  0x48,  0x09,  0x4C,  0x09, 	/* 4E210 */
+	0x4C,  0x2F,  0xCC,  0x28,  0x94,  0x29,  0xD4,  0x29,  0xB4,  0x2A,  0x95,  0x3C,  0xA5,  0x61,  0xC3,  0xB6, 	/* 4E220 */
+	0x00,  0x00,  0x7B,  0xFF,  0x4A,  0x00,  0x4B,  0x14,  0x4A,  0xA4,  0x7B,  0xF7,  0x12,  0x59,  0x13,  0x5E, 	/* 4E230 */
+	0x53,  0x54,  0x5F,  0x54,  0x53,  0xF4,  0x52,  0x44,  0x52,  0x4A,  0x5C,  0x8A,  0x64,  0x92,  0x49,  0x21, 	/* 4E240 */
+	0xBC,  0x00,  0x28,  0x3E,  0xAA,  0x22,  0x6C,  0x22,  0x28,  0x23,  0xFF,  0x3E,  0x44,  0x08,  0x28,  0x08, 	/* 4E250 */
+	0xFE,  0x28,  0x10,  0x2E,  0xFE,  0x28,  0x10,  0x29,  0xFF,  0x28,  0x28,  0x2E,  0x44,  0x38,  0x82,  0x63, 	/* 4E260 */
+	0x01,  0x81,  0x00,  0x00,  0x3E,  0x7C,  0x22,  0x44,  0x22,  0x44,  0x22,  0x7C,  0x3F,  0xEF,  0x09,  0x29, 	/* 4E270 */
+	0x09,  0x29,  0x29,  0xEF,  0x2E,  0x10,  0x29,  0xFF,  0x28,  0x38,  0x28,  0x54,  0x2E,  0x92,  0x39,  0x11, 	/* 4E280 */
+	0x60,  0x10,  0x84,  0x00,  0x08,  0x1F,  0xFF,  0x10,  0xA2,  0x1F,  0x94,  0x10,  0x7F,  0x2F,  0x88,  0x28, 	/* 4E290 */
+	0xBE,  0x4F,  0x88,  0x00,  0x00,  0x0F,  0xF8,  0x08,  0x08,  0x0F,  0xF8,  0x04,  0x80,  0x06,  0xFC,  0x19, 	/* 4E2A0 */
+	0x80,  0x60,  0x7F,  0x85,  0x00,  0x00,  0x3E,  0xFE,  0x22,  0xAA,  0x22,  0xAA,  0x22,  0xFE,  0x3E,  0x40, 	/* 4E2B0 */
+	0x08,  0x7E,  0x08,  0xA2,  0x29,  0xFA,  0x2E,  0xAA,  0x28,  0xAA,  0x28,  0xFA,  0x28,  0x2A,  0x2E,  0x36, 	/* 4E2C0 */
+	0x39,  0xC2,  0x60,  0x0C,  0x87,  0x00,  0x44,  0x3E,  0x44,  0x23,  0xFF,  0x22,  0x44,  0x22,  0x12,  0x3E, 	/* 4E2D0 */
+	0xFE,  0x08,  0x14,  0x09,  0xFF,  0x28,  0x18,  0x2E,  0x24,  0x28,  0x7E,  0x29,  0xA2,  0x28,  0x3E,  0x2E, 	/* 4E2E0 */
+	0x22,  0x38,  0x3E,  0x60,  0x00,  0x8A,  0x00,  0x20,  0x3F,  0xFE,  0x22,  0x20,  0x22,  0xFC,  0x22,  0x00, 	/* 4E2F0 */
+	0x3F,  0xFF,  0x08,  0x02,  0x08,  0xF8,  0x2E,  0x20,  0x29,  0xFF,  0x28,  0x04,  0x2B,  0xFF,  0x29,  0x64, 	/* 4E300 */
+	0x2F,  0x54,  0x39,  0xC4,  0x60,  0x0C,  0x8B,  0x00,  0x10,  0x3E,  0x10,  0x23,  0xFF,  0x22,  0x29,  0x23, 	/* 4E310 */
+	0xD6,  0x3E,  0xD6,  0x09,  0x55,  0x0A,  0xD5,  0x28,  0x00,  0x2E,  0x82,  0x28,  0xFE,  0x28,  0x82,  0x28, 	/* 4E320 */
+	0xFE,  0x2E,  0x82,  0x38,  0x82,  0x61,  0x02,  0x8D,  0x00,  0x00,  0x3F,  0xFE,  0x22,  0x22,  0x22,  0xEE, 	/* 4E330 */
+	0x22,  0x22,  0x3F,  0xFE,  0x08,  0x44,  0x08,  0x48,  0x28,  0xFF,  0x2F,  0x88,  0x28,  0xFE,  0x28,  0x88, 	/* 4E340 */
+	0x28,  0xFE,  0x2E,  0x88,  0x38,  0xFF,  0x60,  0x80,  0x91,  0x01,  0xC0,  0x79,  0x4E,  0x4A,  0x2A,  0x4B, 	/* 4E350 */
+	0xEA,  0x4D,  0x5A,  0x7B,  0xEC,  0x12,  0xAC,  0x13,  0x6A,  0x53,  0xE9,  0x5E,  0x29,  0x53,  0xE9,  0x50, 	/* 4E360 */
+	0x89,  0x57,  0xFE,  0x58,  0xC8,  0x71,  0x28,  0x42,  0x08,  0x93,  0x00,  0x11,  0x3E,  0xEE,  0x22,  0x88, 	/* 4E370 */
+	0x22,  0xFF,  0x22,  0xAA,  0x3E,  0xB2,  0x09,  0x22,  0x08,  0xFC,  0x28,  0x84,  0x2E,  0xFC,  0x28,  0x84, 	/* 4E380 */
+	0x28,  0xFC,  0x28,  0x84,  0x2E,  0xFC,  0x38,  0x6C,  0x63,  0x82,  0x94,  0x00,  0x10,  0x3D,  0xFF,  0x25, 	/* 4E390 */
+	0x00,  0x25,  0x7E,  0x25,  0x52,  0x3D,  0x7E,  0x09,  0x52,  0x09,  0x7E,  0x2F,  0x10,  0x29,  0xFF,  0x29, 	/* 4E3A0 */
+	0x25,  0x29,  0xD3,  0x2B,  0x7E,  0x2D,  0x10,  0x32,  0xFF,  0x64,  0x00,  0x99,  0x00,  0x00,  0x3D,  0xDE, 	/* 4E3B0 */
+	0x25,  0x52,  0x25,  0xDE,  0x25,  0x52,  0x3D,  0xDE,  0x09,  0x02,  0x09,  0x52,  0x29,  0x7A,  0x2D,  0xD2, 	/* 4E3C0 */
+	0x29,  0x7A,  0x29,  0x52,  0x29,  0x7A,  0x2F,  0x52,  0x39,  0x7A,  0x61,  0x06,  0xA1,  0x00,  0x00,  0x3F, 	/* 4E3D0 */
+	0xFE,  0x22,  0x48,  0x22,  0x78,  0x22,  0x48,  0x3E,  0x7E,  0x09,  0xC8,  0x08,  0x08,  0x29,  0xFF,  0x2E, 	/* 4E3E0 */
+	0xAA,  0x28,  0xEE,  0x28,  0xAA,  0x28,  0xEE,  0x2E,  0xAB,  0x39,  0xFE,  0x60,  0x22,  0xAA,  0x00,  0x48, 	/* 4E3F0 */
+	0x3F,  0xFF,  0x24,  0x48,  0x25,  0xDE,  0x25,  0x52,  0x25,  0xDE,  0x3D,  0xDE,  0x09,  0x4A,  0x2D,  0x7A, 	/* 4E400 */
+	0x29,  0xD2,  0x29,  0x7A,  0x29,  0x52,  0x29,  0x7A,  0x2F,  0x52,  0x39,  0x7A,  0x61,  0x06,  0xAB,  0x00, 	/* 4E410 */
+	0x80,  0x01,  0x00,  0x0F,  0xF0,  0x08,  0x10,  0x08,  0x10,  0x0F,  0xF0,  0x08,  0x11,  0x0F,  0xF2,  0x08, 	/* 4E420 */
+	0x14,  0x08,  0x18,  0x0F,  0xF0,  0x78,  0x30,  0x00,  0xD0,  0x03,  0x10,  0x3C,  0x10,  0x00,  0x30,  0xAC, 	/* 4E430 */
+	0x02,  0x00,  0x04,  0x7E,  0x1F,  0x02,  0x11,  0x02,  0x11,  0x02,  0x1F,  0x7E,  0x11,  0x40,  0x1F,  0x40, 	/* 4E440 */
+	0x11,  0x40,  0x11,  0xFE,  0x1F,  0x02,  0x73,  0x02,  0x05,  0x02,  0x19,  0x02,  0x61,  0x04,  0x07,  0x18, 	/* 4E450 */
+	0xAF,  0x08,  0x00,  0x10,  0xFE,  0x3E,  0x80,  0x22,  0x84,  0x3E,  0x84,  0x22,  0xA4,  0x3E,  0x98,  0x22, 	/* 4E460 */
+	0x88,  0x23,  0x8C,  0x3E,  0x94,  0x62,  0x92,  0x06,  0xA2,  0x0A,  0xC0,  0x12,  0x80,  0x62,  0xFF,  0x06, 	/* 4E470 */
+	0x80,  0xB0,  0x04,  0x10,  0x08,  0x10,  0x1E,  0x10,  0x12,  0x10,  0x13,  0xFF,  0x1E,  0x10,  0x12,  0x38, 	/* 4E480 */
+	0x1E,  0x38,  0x12,  0x54,  0x12,  0x54,  0x1E,  0x92,  0x67,  0x11,  0x0A,  0x7C,  0x12,  0x10,  0x62,  0x10, 	/* 4E490 */
+	0x06,  0x10,  0xB1,  0x04,  0x00,  0x09,  0xF8,  0x1E,  0x48,  0x12,  0x4E,  0x12,  0x42,  0x1E,  0x42,  0x12, 	/* 4E4A0 */
+	0x82,  0x1F,  0x1C,  0x12,  0x10,  0x13,  0xFF,  0x1E,  0x38,  0x66,  0x54,  0x0A,  0x92,  0x13,  0x11,  0x62, 	/* 4E4B0 */
+	0x10,  0x06,  0x10,  0xBE,  0x04,  0x44,  0x08,  0x28,  0x1E,  0xFF,  0x12,  0x10,  0x12,  0xFE,  0x1E,  0x10, 	/* 4E4C0 */
+	0x12,  0x10,  0x1F,  0xFF,  0x12,  0x10,  0x12,  0x10,  0x1F,  0xFF,  0x66,  0x18,  0x0A,  0x28,  0x12,  0x44, 	/* 4E4D0 */
+	0x62,  0x82,  0x07,  0x01,  0x85,  0x08,  0x00,  0x11,  0xFF,  0x3D,  0x20,  0x25,  0x2A,  0x25,  0x54,  0x3D, 	/* 4E4E0 */
+	0x5F,  0x25,  0xD4,  0x3D,  0x74,  0x25,  0x5E,  0x27,  0x54,  0x7D,  0x54,  0x0D,  0x5E,  0x15,  0x54,  0x26, 	/* 4E4F0 */
+	0x54,  0x44,  0x5F,  0x0C,  0x40,  0x86,  0x04,  0x28,  0x08,  0xFE,  0x1E,  0xAA,  0x12,  0xFE,  0x12,  0xAA, 	/* 4E500 */
+	0x1E,  0xFE,  0x12,  0x00,  0x1F,  0xFF,  0x12,  0x00,  0x12,  0xFE,  0x1E,  0x82,  0x66,  0xFE,  0x0A,  0x44, 	/* 4E510 */
+	0x12,  0x28,  0x63,  0xFF,  0x06,  0x00,  0x88,  0x08,  0x08,  0x11,  0xFF,  0x3D,  0x22,  0x25,  0x24,  0x25, 	/* 4E520 */
+	0x5F,  0x3D,  0xF4,  0x25,  0x5E,  0x3D,  0x54,  0x25,  0x5E,  0x27,  0x54,  0x7D,  0x5F,  0x0D,  0x10,  0x16, 	/* 4E530 */
+	0xAA,  0x24,  0xA9,  0x45,  0x25,  0x0C,  0x1C,  0x8A,  0x00,  0x80,  0x00,  0x80,  0x3F,  0xFE,  0x00,  0x80, 	/* 4E540 */
+	0x0F,  0xF8,  0x08,  0x88,  0x08,  0x88,  0x0F,  0xF8,  0x08,  0x88,  0x08,  0x88,  0x0F,  0xF8,  0x00,  0x80, 	/* 4E550 */
+	0x7F,  0xFF,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x8B,  0x04,  0x20,  0x04,  0x20,  0x7F,  0xA0,  0x04, 	/* 4E560 */
+	0x20,  0x3F,  0xA0,  0x24,  0xA0,  0x24,  0xA0,  0x3F,  0xA0,  0x24,  0xA0,  0x24,  0xA0,  0x3F,  0xA0,  0x04, 	/* 4E570 */
+	0x21,  0x7F,  0xE1,  0x04,  0x11,  0x04,  0x0F,  0x04,  0x00,  0x8C,  0x04,  0x20,  0x04,  0x20,  0x7F,  0xA0, 	/* 4E580 */
+	0x04,  0x20,  0x3F,  0xFC,  0x25,  0x24,  0x25,  0x24,  0x3F,  0x24,  0x25,  0x24,  0x25,  0x24,  0x3F,  0x24, 	/* 4E590 */
+	0x04,  0x24,  0x7F,  0xC4,  0x04,  0x45,  0x04,  0x85,  0x05,  0x03,  0x8D,  0x00,  0x00,  0x3F,  0xFE,  0x20, 	/* 4E5A0 */
+	0x82,  0x20,  0x82,  0x1F,  0xFC,  0x00,  0x80,  0x1F,  0xFC,  0x10,  0x84,  0x1F,  0xFC,  0x10,  0x84,  0x10, 	/* 4E5B0 */
+	0x84,  0x1F,  0xFC,  0x00,  0x80,  0x7F,  0xFF,  0x00,  0x80,  0x00,  0x80,  0x92,  0x04,  0x00,  0x04,  0x7E, 	/* 4E5C0 */
+	0x7F,  0x90,  0x04,  0x10,  0x3F,  0x10,  0x25,  0x10,  0x25,  0x10,  0x3F,  0xFF,  0x25,  0x10,  0x25,  0x10, 	/* 4E5D0 */
+	0x3F,  0x10,  0x04,  0x10,  0x7F,  0x90,  0x04,  0x10,  0x04,  0x10,  0x04,  0x10,  0x9B,  0x08,  0x00,  0x08, 	/* 4E5E0 */
+	0x7F,  0x7F,  0x40,  0x08,  0x40,  0x3E,  0x5E,  0x2A,  0x52,  0x2A,  0x52,  0x3E,  0x52,  0x2A,  0x52,  0x2A, 	/* 4E5F0 */
+	0x52,  0x3E,  0x5C,  0x08,  0x50,  0x7F,  0x90,  0x08,  0x91,  0x09,  0x11,  0x08,  0x0F,  0x9F,  0x08,  0x20, 	/* 4E600 */
+	0x08,  0x20,  0x7F,  0xA0,  0x08,  0x20,  0x3F,  0x7E,  0x29,  0x52,  0x29,  0x54,  0x3F,  0x90,  0x29,  0x10, 	/* 4E610 */
+	0x29,  0x10,  0x3F,  0x28,  0x08,  0x28,  0x7F,  0xC4,  0x08,  0x44,  0x08,  0x82,  0x09,  0x01,  0xA2,  0x04, 	/* 4E620 */
+	0x00,  0x04,  0x3E,  0x7F,  0xC0,  0x04,  0x00,  0x3F,  0x00,  0x25,  0x00,  0x25,  0xFF,  0x3F,  0x10,  0x25, 	/* 4E630 */
+	0x10,  0x25,  0x10,  0x3F,  0x24,  0x04,  0x24,  0x7F,  0xA2,  0x04,  0x4E,  0x05,  0xF1,  0x04,  0x01,  0xA3, 	/* 4E640 */
+	0x00,  0x80,  0x3F,  0xFE,  0x00,  0x80,  0x0F,  0xF8,  0x08,  0x88,  0x0F,  0xF8,  0x08,  0x88,  0x0F,  0xF8, 	/* 4E650 */
+	0x00,  0x80,  0x7F,  0xFF,  0x00,  0x80,  0x18,  0x0C,  0x06,  0x30,  0x00,  0x00,  0x0E,  0x38,  0x70,  0x07, 	/* 4E660 */
+	0xAB,  0x08,  0x10,  0x08,  0x10,  0x7F,  0x28,  0x08,  0x28,  0x3E,  0x44,  0x2A,  0x92,  0x2B,  0x11,  0x3E, 	/* 4E670 */
+	0x24,  0x2A,  0x44,  0x2A,  0x88,  0x3E,  0x12,  0x08,  0x22,  0x7F,  0x44,  0x08,  0x08,  0x08,  0x30,  0x08, 	/* 4E680 */
+	0xC0,  0xB8,  0x04,  0x08,  0x04,  0x08,  0x7F,  0xC8,  0x04,  0x08,  0x3F,  0x7F,  0x25,  0x49,  0x25,  0x49, 	/* 4E690 */
+	0x3F,  0x49,  0x25,  0x7F,  0x25,  0x49,  0x3F,  0x49,  0x04,  0x49,  0x7F,  0xC9,  0x04,  0x49,  0x04,  0x7F, 	/* 4E6A0 */
+	0x04,  0x00,  0xBB,  0x08,  0x00,  0x09,  0xFF,  0x7F,  0x04,  0x08,  0x04,  0x3E,  0xF4,  0x2A,  0x94,  0x2A, 	/* 4E6B0 */
+	0x94,  0x3E,  0x94,  0x2A,  0x94,  0x2A,  0xF4,  0x3E,  0x04,  0x08,  0x04,  0x7F,  0x04,  0x08,  0x04,  0x08, 	/* 4E6C0 */
+	0x04,  0x08,  0x0C,  0xBC,  0x08,  0x10,  0x08,  0x50,  0x7F,  0x50,  0x08,  0x7E,  0x3E,  0x50,  0x2A,  0x90, 	/* 4E6D0 */
+	0x2A,  0x10,  0x3E,  0xFF,  0x2A,  0x10,  0x2A,  0x10,  0x3E,  0x18,  0x08,  0x28,  0x7F,  0x24,  0x08,  0x44, 	/* 4E6E0 */
+	0x08,  0x82,  0x09,  0x01,  0xBD,  0x08,  0x00,  0x08,  0xFE,  0x7F,  0x42,  0x08,  0x24,  0x3E,  0x28,  0x2A, 	/* 4E6F0 */
+	0x10,  0x2A,  0x6C,  0x3F,  0x83,  0x2A,  0x10,  0x2A,  0x10,  0x3E,  0xFE,  0x08,  0x10,  0x7F,  0x10,  0x08, 	/* 4E700 */
+	0x10,  0x09,  0xFF,  0x08,  0x00,  0xBE,  0x08,  0x0A,  0x08,  0x09,  0x7F,  0x09,  0x08,  0x08,  0x3E,  0xFF, 	/* 4E710 */
+	0x2A,  0x08,  0x2A,  0x08,  0x3E,  0xF8,  0x2A,  0x48,  0x2A,  0x48,  0x3E,  0x48,  0x08,  0x44,  0x7F,  0x75, 	/* 4E720 */
+	0x09,  0xC5,  0x08,  0x03,  0x08,  0x01,  0x83,  0x08,  0x10,  0x08,  0x10,  0x7F,  0x10,  0x09,  0xFF,  0x3E, 	/* 4E730 */
+	0x44,  0x2A,  0x44,  0x2A,  0x82,  0x3F,  0x45,  0x2A,  0x44,  0x2A,  0x28,  0x3E,  0x28,  0x08,  0x10,  0x7F, 	/* 4E740 */
+	0x28,  0x08,  0x44,  0x08,  0x82,  0x09,  0x01,  0x85,  0x08,  0x20,  0x08,  0x20,  0x7F,  0x3C,  0x08,  0x44, 	/* 4E750 */
+	0x3E,  0xA8,  0x2B,  0x10,  0x2A,  0x30,  0x3E,  0x48,  0x2A,  0x84,  0x2B,  0x02,  0x3E,  0xFD,  0x08,  0x84, 	/* 4E760 */
+	0x7F,  0x84,  0x08,  0x84,  0x08,  0xFC,  0x08,  0x00,  0x89,  0x04,  0x28,  0x04,  0x24,  0x3F,  0xA4,  0x04, 	/* 4E770 */
+	0x20,  0x7F,  0xFF,  0x04,  0x20,  0x7F,  0xE4,  0x04,  0x24,  0x3F,  0xA8,  0x24,  0x98,  0x3F,  0x90,  0x24, 	/* 4E780 */
+	0x98,  0x3F,  0xAA,  0x04,  0x2A,  0x7F,  0xC6,  0x04,  0x82,  0x8A,  0x08,  0x00,  0x08,  0xFF,  0x7F,  0x10, 	/* 4E790 */
+	0x08,  0x10,  0x3E,  0x24,  0x2A,  0x4E,  0x2B,  0xF1,  0x3E,  0x00,  0x2A,  0x10,  0x2A,  0x10,  0x3E,  0xFE, 	/* 4E7A0 */
+	0x08,  0x10,  0x7F,  0x10,  0x08,  0x10,  0x09,  0xFF,  0x08,  0x00,  0x8C,  0x08,  0x00,  0x08,  0xFF,  0x7F, 	/* 4E7B0 */
+	0x10,  0x08,  0x10,  0x3E,  0xFE,  0x2A,  0x92,  0x2A,  0x92,  0x3E,  0xD6,  0x2A,  0xD6,  0x2A,  0xD6,  0x3E, 	/* 4E7C0 */
+	0xD6,  0x08,  0xFE,  0x7F,  0x82,  0x08,  0x82,  0x08,  0x82,  0x08,  0x86,  0x92,  0x08,  0x00,  0x0B,  0xFF, 	/* 4E7D0 */
+	0x7E,  0xA8,  0x08,  0xA8,  0x3E,  0xE8,  0x2A,  0xA8,  0x2A,  0xA8,  0x3E,  0xA8,  0x2A,  0xE8,  0x2A,  0xA8, 	/* 4E7E0 */
+	0x3E,  0xA8,  0x08,  0xA8,  0x7E,  0xE8,  0x09,  0xA9,  0x08,  0x29,  0x08,  0x27,  0x93,  0x08,  0x10,  0x08, 	/* 4E7F0 */
+	0x1C,  0x7F,  0x24,  0x08,  0x48,  0x3E,  0x90,  0x2A,  0xFE,  0x2A,  0x92,  0x3E,  0x92,  0x2A,  0xA2,  0x2A, 	/* 4E800 */
+	0xFE,  0x3E,  0x28,  0x08,  0x28,  0x7F,  0x48,  0x08,  0x49,  0x08,  0x89,  0x0B,  0x07,  0x94,  0x08,  0x14, 	/* 4E810 */
+	0x08,  0x12,  0x7F,  0xFF,  0x08,  0x10,  0x3F,  0x10,  0x29,  0x7E,  0x29,  0x52,  0x3F,  0x52,  0x29,  0x7E, 	/* 4E820 */
+	0x29,  0x52,  0x3F,  0x52,  0x08,  0x7E,  0x7F,  0x52,  0x08,  0x52,  0x08,  0x52,  0x08,  0x56,  0x95,  0x08, 	/* 4E830 */
+	0x00,  0x08,  0xFF,  0x7F,  0x80,  0x08,  0x2A,  0x3E,  0x2A,  0x2A,  0x54,  0x2A,  0xD4,  0x3E,  0x2A,  0x2A, 	/* 4E840 */
+	0x2A,  0x2A,  0x00,  0x3E,  0x7E,  0x08,  0x10,  0x7F,  0x10,  0x08,  0x10,  0x08,  0xFF,  0x08,  0x00,  0x99, 	/* 4E850 */
+	0x08,  0x00,  0x09,  0xFF,  0x7E,  0xA0,  0x08,  0xA0,  0x3E,  0xFE,  0x2A,  0xAA,  0x2A,  0xAA,  0x3E,  0xAA, 	/* 4E860 */
+	0x2A,  0xEA,  0x2A,  0xAC,  0x3E,  0xA4,  0x08,  0xA4,  0x7E,  0xEA,  0x09,  0xB2,  0x08,  0x21,  0x08,  0x20, 	/* 4E870 */
+	0x9B,  0x08,  0x00,  0x09,  0xFF,  0x7E,  0x20,  0x08,  0x20,  0x3F,  0xFE,  0x2B,  0x22,  0x2B,  0x22,  0x3F, 	/* 4E880 */
+	0xFA,  0x2B,  0x6A,  0x2B,  0x6A,  0x3F,  0x6A,  0x09,  0xB6,  0x7F,  0x22,  0x09,  0x22,  0x09,  0x22,  0x09, 	/* 4E890 */
+	0x26,  0x9C,  0x08,  0x92,  0x08,  0x92,  0x7F,  0x24,  0x09,  0x6C,  0x3E,  0x92,  0x2A,  0x92,  0x2A,  0x00, 	/* 4E8A0 */
+	0x3E,  0xFE,  0x2A,  0x92,  0x2A,  0x92,  0x3E,  0xFE,  0x08,  0x92,  0x7F,  0x92,  0x08,  0x92,  0x08,  0xFE, 	/* 4E8B0 */
+	0x08,  0x00,  0x9D,  0x08,  0x00,  0x08,  0xFF,  0x4A,  0x91,  0x2A,  0x91,  0x2A,  0xFE,  0x2C,  0x10,  0x08, 	/* 4E8C0 */
+	0x7E,  0x7F,  0x52,  0x14,  0x7E,  0x14,  0x52,  0x14,  0x52,  0x15,  0x7E,  0x26,  0x10,  0x25,  0xFF,  0x40, 	/* 4E8D0 */
+	0x10,  0x00,  0x10,  0x9F,  0x08,  0x00,  0x09,  0xFE,  0x7E,  0xAA,  0x08,  0xAA,  0x3E,  0x44,  0x2A,  0xAA, 	/* 4E8E0 */
+	0x2B,  0x11,  0x3E,  0x00,  0x2B,  0xFE,  0x2A,  0x22,  0x3E,  0xAA,  0x08,  0xAA,  0x7E,  0x44,  0x08,  0xC4, 	/* 4E8F0 */
+	0x09,  0x2A,  0x0A,  0x11,  0xA6,  0x08,  0x08,  0x3E,  0x3E,  0x08,  0x08,  0x7F,  0x7F,  0x14,  0x14,  0x22, 	/* 4E900 */
+	0xA2,  0x5F,  0xFD,  0x00,  0x80,  0x0F,  0xF8,  0x08,  0x88,  0x0F,  0xF8,  0x08,  0x88,  0x0F,  0xF8,  0x00, 	/* 4E910 */
+	0x80,  0x7F,  0xFF,  0x00,  0x80,  0xA9,  0x02,  0x20,  0x7E,  0x3F,  0x02,  0x20,  0x3E,  0x3E,  0x02,  0x20, 	/* 4E920 */
+	0x7E,  0x3F,  0x04,  0x20,  0x08,  0xA0,  0x7F,  0xFF,  0x08,  0x88,  0x0F,  0xF8,  0x08,  0x88,  0x0F,  0xF8, 	/* 4E930 */
+	0x00,  0x80,  0x7F,  0xFF,  0x00,  0x80,  0xAA,  0x08,  0x10,  0x08,  0x10,  0x7F,  0x28,  0x08,  0x24,  0x3E, 	/* 4E940 */
+	0x42,  0x2A,  0xFD,  0x2B,  0x00,  0x3E,  0xFE,  0x2A,  0xAA,  0x2A,  0xAA,  0x3E,  0xFE,  0x08,  0xAA,  0x7F, 	/* 4E950 */
+	0xAA,  0x08,  0xAA,  0x08,  0xAA,  0x08,  0x86,  0xAF,  0x08,  0x00,  0x08,  0x7C,  0x7F,  0x44,  0x08,  0x7C, 	/* 4E960 */
+	0x3E,  0x00,  0x2B,  0xFF,  0x2A,  0x44,  0x3E,  0x44,  0x2A,  0x7C,  0x2A,  0x44,  0x3E,  0x7C,  0x08,  0x44, 	/* 4E970 */
+	0x7F,  0x47,  0x08,  0x7C,  0x09,  0xC4,  0x08,  0x04,  0xB3,  0x08,  0x20,  0x08,  0x20,  0x7F,  0xFC,  0x08, 	/* 4E980 */
+	0x20,  0x3E,  0xFC,  0x2A,  0x50,  0x2B,  0xFF,  0x3E,  0x88,  0x2B,  0xFC,  0x2A,  0x22,  0x3E,  0x21,  0x09, 	/* 4E990 */
+	0xFE,  0x7F,  0x20,  0x08,  0x50,  0x08,  0x8C,  0x0B,  0x03,  0xB8,  0x08,  0x10,  0x08,  0x10,  0x7F,  0x28, 	/* 4E9A0 */
+	0x08,  0x44,  0x3E,  0xFE,  0x2B,  0x01,  0x2A,  0xEA,  0x3E,  0xAA,  0x2A,  0xAA,  0x2A,  0xEA,  0x3E,  0xAA, 	/* 4E9B0 */
+	0x08,  0xAA,  0x7F,  0xEA,  0x08,  0xAA,  0x08,  0xA2,  0x08,  0xA6,  0xB9,  0x08,  0x20,  0x08,  0x20,  0x7F, 	/* 4E9C0 */
+	0x3F,  0x08,  0x40,  0x3E,  0xFC,  0x2B,  0x44,  0x2A,  0x7C,  0x3E,  0x44,  0x2A,  0x7C,  0x2A,  0x20,  0x3E, 	/* 4E9D0 */
+	0x7C,  0x08,  0xC4,  0x7F,  0x28,  0x08,  0x30,  0x08,  0xCC,  0x0B,  0x03,  0xBB,  0x08,  0x00,  0x08,  0xFF, 	/* 4E9E0 */
+	0x7F,  0x00,  0x08,  0x7C,  0x3E,  0x44,  0x2A,  0x44,  0x2A,  0x7C,  0x3E,  0x00,  0x2A,  0xFE,  0x2A,  0x92, 	/* 4E9F0 */
+	0x3E,  0x92,  0x08,  0xFE,  0x7F,  0x92,  0x08,  0x92,  0x08,  0xFE,  0x08,  0x00,  0xBE,  0x08,  0x00,  0x08, 	/* 4EA00 */
+	0xFE,  0x7F,  0x82,  0x08,  0x82,  0x3E,  0xFE,  0x2A,  0x80,  0x2A,  0xA4,  0x3E,  0xFF,  0x2A,  0xA4,  0x2A, 	/* 4EA10 */
+	0xA4,  0x3E,  0xFF,  0x08,  0xA9,  0x7F,  0x2A,  0x09,  0x24,  0x0A,  0x32,  0x08,  0xC1,  0xBF,  0x04,  0x00, 	/* 4EA20 */
+	0x38,  0x9E,  0x27,  0xF2,  0x20,  0x82,  0x3B,  0xEE,  0x22,  0xA2,  0x23,  0xE2,  0x22,  0xA2,  0x3B,  0xEE, 	/* 4EA30 */
+	0x20,  0x82,  0x27,  0xF2,  0x20,  0x82,  0x7F,  0xFF,  0x04,  0x30,  0x18,  0x0C,  0x60,  0x02,  0x82,  0x08, 	/* 4EA40 */
+	0x00,  0x7F,  0x3C,  0x08,  0x24,  0x3E,  0x24,  0x00,  0x25,  0x7F,  0x25,  0x41,  0x43,  0x3E,  0x80,  0x08, 	/* 4EA50 */
+	0x7C,  0x7F,  0x24,  0x2A,  0x24,  0x3E,  0x18,  0x2A,  0x08,  0x7F,  0x94,  0x08,  0x22,  0x08,  0x41,  0x84, 	/* 4EA60 */
+	0x08,  0x10,  0x08,  0x10,  0x7F,  0xFE,  0x08,  0x82,  0x3E,  0x92,  0x2A,  0xFE,  0x2A,  0x10,  0x3E,  0x7C, 	/* 4EA70 */
+	0x2A,  0x10,  0x2A,  0xFF,  0x3E,  0x00,  0x08,  0x7C,  0x7F,  0x44,  0x08,  0x44,  0x08,  0x7C,  0x08,  0x00, 	/* 4EA80 */
+	0x85,  0x08,  0x10,  0x08,  0x10,  0x7F,  0x7E,  0x08,  0x10,  0x3E,  0xFF,  0x2A,  0x00,  0x2A,  0x7E,  0x3E, 	/* 4EA90 */
+	0x42,  0x2A,  0x42,  0x2A,  0x7E,  0x3E,  0x19,  0x08,  0x2A,  0x7F,  0x64,  0x08,  0xA4,  0x08,  0x32,  0x08, 	/* 4EAA0 */
+	0xC1,  0x86,  0x08,  0x08,  0x08,  0x08,  0x7E,  0xFF,  0x08,  0x94,  0x3E,  0x94,  0x2A,  0xFF,  0x2A,  0x95, 	/* 4EAB0 */
+	0x3E,  0x95,  0x2A,  0xFF,  0x2A,  0xA4,  0x3E,  0xA5,  0x08,  0xBE,  0x7F,  0x24,  0x09,  0x24,  0x0A,  0x3D, 	/* 4EAC0 */
+	0x08,  0xC3,  0x89,  0x08,  0x10,  0x08,  0x10,  0x7F,  0xFF,  0x08,  0x10,  0x3E,  0xFE,  0x2A,  0x92,  0x2A, 	/* 4EAD0 */
+	0xFE,  0x3E,  0x92,  0x2A,  0xFE,  0x2A,  0x12,  0x3E,  0xFD,  0x08,  0x04,  0x7F,  0xFF,  0x08,  0x44,  0x08, 	/* 4EAE0 */
+	0x24,  0x08,  0x0C,  0x8C,  0x08,  0x00,  0x08,  0xFE,  0x7E,  0x10,  0x09,  0xFF,  0x3F,  0x11,  0x2B,  0xDD, 	/* 4EAF0 */
+	0x2B,  0x11,  0x3E,  0xCC,  0x2A,  0x00,  0x2A,  0xFC,  0x3E,  0x04,  0x08,  0x04,  0x7E,  0xFF,  0x08,  0x04, 	/* 4EB00 */
+	0x08,  0xFC,  0x08,  0x00,  0x8D,  0x11,  0x08,  0x11,  0x08,  0x7F,  0xE8,  0x11,  0x8F,  0x7D,  0x54,  0x56, 	/* 4EB10 */
+	0x54,  0x57,  0xA4,  0x7C,  0x14,  0x57,  0xD4,  0x56,  0x54,  0x7F,  0xC8,  0x12,  0x48,  0x13,  0xCC,  0x7E, 	/* 4EB20 */
+	0x54,  0x12,  0x62,  0x12,  0xC1,  0x8E,  0x08,  0x0C,  0x08,  0xF0,  0x7F,  0x10,  0x09,  0xFF,  0x3E,  0x48, 	/* 4EB30 */
+	0x2A,  0xFC,  0x2B,  0x4B,  0x3E,  0x78,  0x2A,  0x00,  0x2A,  0xFE,  0x3E,  0x82,  0x08,  0xBA,  0x7F,  0xAA, 	/* 4EB40 */
+	0x08,  0xBA,  0x08,  0x82,  0x08,  0x86,  0x97,  0x08,  0x0C,  0x08,  0x0A,  0x7E,  0xFF,  0x08,  0x88,  0x3E, 	/* 4EB50 */
+	0xFA,  0x2A,  0x8A,  0x2A,  0xF4,  0x3E,  0xD4,  0x2A,  0xF5,  0x2A,  0x8B,  0x3F,  0x11,  0x08,  0x28,  0x7E, 	/* 4EB60 */
+	0xAA,  0x08,  0xA1,  0x09,  0x25,  0x08,  0x1C,  0x9C,  0x08,  0x00,  0x08,  0xFE,  0x7F,  0x10,  0x08,  0xFF, 	/* 4EB70 */
+	0x3E,  0x91,  0x2A,  0xFD,  0x2A,  0x91,  0x3E,  0x6C,  0x2A,  0x00,  0x2A,  0xFF,  0x3E,  0x10,  0x08,  0xFE, 	/* 4EB80 */
+	0x7F,  0xAA,  0x08,  0xAA,  0x08,  0xAA,  0x08,  0x86,  0x9F,  0x00,  0x80,  0x1F,  0xFC,  0x00,  0x80,  0x07, 	/* 4EB90 */
+	0xF0,  0x04,  0x90,  0x07,  0xF0,  0x04,  0x90,  0x3F,  0xFE,  0x00,  0x80,  0x08,  0x10,  0x7F,  0xFE,  0x2A, 	/* 4EBA0 */
+	0x54,  0x3E,  0x7C,  0x2A,  0x54,  0x7F,  0xFF,  0x08,  0x10,  0xA1,  0x10,  0x84,  0x13,  0xE4,  0x68,  0x9A, 	/* 4EBB0 */
+	0x13,  0xE4,  0x2A,  0xAA,  0x7F,  0xFF,  0x12,  0xA4,  0x3B,  0xEE,  0x34,  0x8D,  0x53,  0xF4,  0x10,  0x84, 	/* 4EBC0 */
+	0x0F,  0xF8,  0x08,  0x08,  0x08,  0x08,  0x0F,  0xF8,  0x00,  0x00,  0xA2,  0x08,  0x8A,  0x08,  0x92,  0x7E, 	/* 4EBD0 */
+	0xBA,  0x09,  0x6D,  0x3F,  0x6D,  0x2A,  0xBA,  0x2A,  0xAA,  0x3F,  0x7D,  0x2B,  0xC7,  0x2A,  0x10,  0x3E, 	/* 4EBE0 */
+	0xFF,  0x08,  0x38,  0x7F,  0x54,  0x08,  0x92,  0x09,  0x11,  0x08,  0x10,  0xA3,  0x08,  0x00,  0x08,  0xFF, 	/* 4EBF0 */
+	0x7E,  0x89,  0x08,  0xB6,  0x3E,  0x92,  0x2A,  0xFF,  0x2A,  0x9A,  0x3E,  0xB6,  0x2A,  0xDB,  0x2A,  0x9A, 	/* 4EC00 */
+	0x3E,  0xA8,  0x08,  0xAE,  0x7F,  0x28,  0x09,  0x28,  0x0A,  0xFF,  0x08,  0x00,  0xA4,  0x08,  0x10,  0x08, 	/* 4EC10 */
+	0x1E,  0x7F,  0x10,  0x08,  0xFF,  0x3E,  0x9A,  0x2A,  0xF1,  0x2A,  0xBF,  0x3E,  0xAA,  0x2A,  0xBE,  0x2A, 	/* 4EC20 */
+	0xAA,  0x3F,  0x3E,  0x09,  0x00,  0x7E,  0xFE,  0x08,  0xAA,  0x09,  0xFF,  0x08,  0x00,  0x9B,  0x00,  0x80, 	/* 4EC30 */
+	0x00,  0x80,  0x1F,  0xFC,  0x04,  0x10,  0x02,  0x10,  0x02,  0x20,  0x02,  0x20,  0x7F,  0xFF,  0x00,  0x80, 	/* 4EC40 */
+	0x00,  0x80,  0x00,  0x80,  0x3F,  0xFE,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x9C,  0x00, 	/* 4EC50 */
+	0x80,  0x00,  0x80,  0x3F,  0xFE,  0x00,  0x80,  0x0F,  0xF8,  0x08,  0x08,  0x0F,  0xF8,  0x00,  0x80,  0x1F, 	/* 4EC60 */
+	0xFC,  0x04,  0x10,  0x02,  0x20,  0x7F,  0xFF,  0x00,  0x80,  0x1F,  0xFC,  0x00,  0x80,  0x00,  0x80,  0x9E, 	/* 4EC70 */
+	0x02,  0x10,  0x0C,  0x10,  0x79,  0xFE,  0x08,  0x84,  0x08,  0x44,  0x08,  0x44,  0x7F,  0x48,  0x09,  0xFF, 	/* 4EC80 */
+	0x08,  0x10,  0x3E,  0x10,  0x22,  0xFE,  0x22,  0x10,  0x22,  0x10,  0x22,  0x10,  0x3E,  0x10,  0x00,  0x10, 	/* 4EC90 */
+	0x9F,  0x00,  0x10,  0x1F,  0x10,  0x11,  0xFE,  0x11,  0x44,  0x11,  0x24,  0x1F,  0x28,  0x10,  0x28,  0x11, 	/* 4ECA0 */
+	0xFF,  0x10,  0x10,  0x1F,  0x10,  0x29,  0xFE,  0x29,  0x10,  0x49,  0x10,  0x09,  0x10,  0x0F,  0x10,  0x00, 	/* 4ECB0 */
+	0x10,  0xA3,  0x08,  0x10,  0x08,  0x10,  0x7F,  0xFF,  0x22,  0x10,  0x12,  0x10,  0x14,  0xFE,  0x7F,  0x92, 	/* 4ECC0 */
+	0x08,  0x92,  0x08,  0x92,  0x0E,  0xFE,  0x78,  0x38,  0x08,  0x54,  0x10,  0x92,  0x11,  0x11,  0x20,  0x10, 	/* 4ECD0 */
+	0x00,  0x10,  0xA7,  0x10,  0x08,  0x10,  0x08,  0x7F,  0xFE,  0x25,  0x52,  0x25,  0x52,  0x29,  0x54,  0x7D, 	/* 4ECE0 */
+	0x7F,  0x11,  0x48,  0x11,  0x48,  0x7D,  0x7F,  0x11,  0x48,  0x12,  0x48,  0x12,  0x48,  0x24,  0x48,  0x28, 	/* 4ECF0 */
+	0x48,  0x41,  0x88,  0xA8,  0x08,  0x48,  0x09,  0x48,  0x7F,  0x7F,  0x23,  0x62,  0x15,  0x52,  0x15,  0x54, 	/* 4ED00 */
+	0x7F,  0x7F,  0x09,  0x48,  0x09,  0x48,  0x7F,  0x7F,  0x09,  0x48,  0x08,  0x48,  0x10,  0x88,  0x10,  0x88, 	/* 4ED10 */
+	0x21,  0x08,  0x42,  0x08,  0xAD,  0x03,  0x08,  0x7C,  0x08,  0x25,  0x7F,  0x24,  0xA2,  0x40,  0x92,  0x3F, 	/* 4ED20 */
+	0x14,  0x0A,  0x14,  0x7F,  0xFF,  0x52,  0x88,  0x7D,  0x88,  0x40,  0xFF,  0x7E,  0x88,  0x52,  0x88,  0x4C, 	/* 4ED30 */
+	0x88,  0x52,  0x88,  0x61,  0x88,  0xAE,  0x10,  0x84,  0x10,  0x84,  0x7C,  0x9F,  0x2B,  0x4A,  0x29,  0x4A, 	/* 4ED40 */
+	0x28,  0x8A,  0x7C,  0xDF,  0x11,  0x24,  0x13,  0xE4,  0x7C,  0x9F,  0x12,  0x84,  0x12,  0xC4,  0x12,  0xA4, 	/* 4ED50 */
+	0x22,  0xA4,  0x24,  0x84,  0x40,  0x84,  0xAF,  0x08,  0x04,  0x09,  0xE4,  0x7E,  0x1F,  0x15,  0xFA,  0x14, 	/* 4ED60 */
+	0x0A,  0x15,  0xEA,  0x7E,  0x1F,  0x09,  0xE4,  0x08,  0x04,  0x0E,  0x1F,  0x79,  0xE4,  0x09,  0x24,  0x11, 	/* 4ED70 */
+	0x24,  0x11,  0x24,  0x21,  0xE4,  0x40,  0x04,  0xB0,  0x00,  0x00,  0x1F,  0xFE,  0x10,  0x00,  0x10,  0x00, 	/* 4ED80 */
+	0x17,  0xFC,  0x10,  0x00,  0x10,  0x00,  0x1F,  0xFF,  0x12,  0x84,  0x12,  0x84,  0x12,  0x48,  0x12,  0x50, 	/* 4ED90 */
+	0x22,  0x20,  0x22,  0x90,  0x43,  0x0C,  0x1C,  0x03,  0xB1,  0x00,  0x00,  0x1F,  0xFE,  0x10,  0x00,  0x1F, 	/* 4EDA0 */
+	0xFC,  0x10,  0x00,  0x1F,  0xFF,  0x14,  0x88,  0x24,  0x50,  0x27,  0xB0,  0x5C,  0x0E,  0x00,  0x10,  0x7F, 	/* 4EDB0 */
+	0xFF,  0x04,  0x10,  0x02,  0x10,  0x02,  0x10,  0x00,  0x30,  0xB2,  0x02,  0x20,  0x1F,  0xFC,  0x12,  0x24, 	/* 4EDC0 */
+	0x1F,  0xFC,  0x12,  0x24,  0x1F,  0xFC,  0x00,  0x00,  0x1F,  0xFE,  0x10,  0x00,  0x17,  0xFC,  0x10,  0x00, 	/* 4EDD0 */
+	0x1F,  0xFF,  0x24,  0x88,  0x24,  0x50,  0x47,  0x30,  0x1C,  0x0F,  0xB7,  0x10,  0x00,  0x08,  0x00,  0x08, 	/* 4EDE0 */
+	0x00,  0x00,  0x00,  0x20,  0x00,  0x10,  0x00,  0x13,  0xFF,  0x00,  0x00,  0x78,  0x00,  0x08,  0x00,  0x08, 	/* 4EDF0 */
+	0x00,  0x08,  0x00,  0x08,  0x00,  0x14,  0x00,  0x23,  0x00,  0x40,  0xFF,  0xBA,  0x00,  0x00,  0x20,  0x00, 	/* 4EE00 */
+	0x13,  0xFE,  0x10,  0x42,  0x00,  0x42,  0x00,  0x42,  0x00,  0x42,  0x78,  0x42,  0x08,  0x82,  0x08,  0x82, 	/* 4EE10 */
+	0x09,  0x02,  0x0A,  0x02,  0x0C,  0x04,  0x14,  0x18,  0x23,  0x00,  0x40,  0xFF,  0xBB,  0x00,  0x20,  0x20, 	/* 4EE20 */
+	0x20,  0x10,  0x20,  0x10,  0x20,  0x00,  0x20,  0x03,  0xFE,  0x00,  0x20,  0x78,  0x20,  0x08,  0x20,  0x08, 	/* 4EE30 */
+	0x20,  0x08,  0x20,  0x08,  0x20,  0x0C,  0x20,  0x14,  0x20,  0x23,  0x00,  0x40,  0xFF,  0xBC,  0x00,  0x00, 	/* 4EE40 */
+	0x20,  0xE0,  0x10,  0x20,  0x10,  0x20,  0x00,  0x20,  0x00,  0x20,  0x00,  0x20,  0x78,  0x50,  0x08,  0x50, 	/* 4EE50 */
+	0x08,  0x88,  0x09,  0x04,  0x0A,  0x02,  0x0C,  0x01,  0x14,  0x00,  0x23,  0x00,  0x40,  0xFF,  0xBF,  0x00, 	/* 4EE60 */
+	0x20,  0x20,  0x20,  0x10,  0x20,  0x11,  0x24,  0x01,  0x24,  0x01,  0x24,  0x01,  0x24,  0x79,  0x24,  0x09, 	/* 4EE70 */
+	0x24,  0x09,  0x24,  0x09,  0x24,  0x09,  0x24,  0x0D,  0xFC,  0x14,  0x00,  0x23,  0x00,  0x40,  0xFF,  0x82, 	/* 4EE80 */
+	0x00,  0x00,  0x23,  0xFC,  0x10,  0x20,  0x10,  0x20,  0x00,  0x20,  0x00,  0x20,  0x07,  0xFE,  0x78,  0x20, 	/* 4EE90 */
+	0x08,  0x20,  0x08,  0x20,  0x08,  0x20,  0x08,  0x20,  0x0C,  0x20,  0x14,  0x60,  0x23,  0x00,  0x40,  0xFF, 	/* 4EEA0 */
+	0x84,  0x01,  0x00,  0x21,  0x00,  0x11,  0xFF,  0x11,  0x00,  0x02,  0x00,  0x03,  0xFC,  0x04,  0x10,  0x78, 	/* 4EEB0 */
+	0x20,  0x08,  0x40,  0x08,  0x80,  0x08,  0x80,  0x09,  0x02,  0x0D,  0x02,  0x14,  0xFE,  0x23,  0x00,  0x40, 	/* 4EEC0 */
+	0xFF,  0x85,  0x00,  0x00,  0x27,  0xF8,  0x10,  0x08,  0x10,  0x88,  0x00,  0x88,  0x00,  0x88,  0x00,  0x88, 	/* 4EED0 */
+	0x7B,  0xF8,  0x08,  0x88,  0x08,  0x88,  0x08,  0x85,  0x08,  0x85,  0x0C,  0x83,  0x14,  0x01,  0x23,  0x00, 	/* 4EEE0 */
+	0x40,  0xFF,  0x8E,  0x00,  0x20,  0x20,  0x40,  0x11,  0x9E,  0x11,  0x12,  0x01,  0x12,  0x01,  0x12,  0x01, 	/* 4EEF0 */
+	0x12,  0x79,  0x12,  0x09,  0x12,  0x09,  0x52,  0x09,  0x92,  0x0B,  0x1C,  0x0C,  0x10,  0x16,  0x10,  0x21, 	/* 4EF00 */
+	0x00,  0x40,  0xFF,  0x91,  0x00,  0x04,  0x20,  0x18,  0x11,  0xE0,  0x11,  0x00,  0x01,  0x00,  0x01,  0xFE, 	/* 4EF10 */
+	0x01,  0x10,  0x79,  0x10,  0x09,  0x10,  0x09,  0x10,  0x0A,  0x10,  0x0A,  0x10,  0x0C,  0x10,  0x14,  0x10, 	/* 4EF20 */
+	0x23,  0x00,  0x40,  0xFF,  0x94,  0x00,  0x00,  0x21,  0xFF,  0x11,  0x00,  0x11,  0x00,  0x01,  0x00,  0x01, 	/* 4EF30 */
+	0xFC,  0x01,  0x44,  0x79,  0x44,  0x09,  0x28,  0x09,  0x18,  0x0A,  0x10,  0x0A,  0x68,  0x0D,  0x84,  0x14, 	/* 4EF40 */
+	0x02,  0x23,  0x00,  0x40,  0xFF,  0x9A,  0x10,  0x20,  0x08,  0x20,  0x08,  0x20,  0x03,  0xFE,  0x22,  0x22, 	/* 4EF50 */
+	0x12,  0x22,  0x12,  0x22,  0x02,  0x22,  0x7B,  0xFE,  0x08,  0x20,  0x08,  0x20,  0x08,  0x20,  0x08,  0x20, 	/* 4EF60 */
+	0x14,  0x20,  0x23,  0x00,  0x40,  0xFF,  0xA2,  0x10,  0x00,  0x0B,  0xFE,  0x08,  0x42,  0x00,  0x42,  0x20, 	/* 4EF70 */
+	0x42,  0x10,  0x82,  0x11,  0x1C,  0x02,  0x00,  0x79,  0xFC,  0x09,  0x04,  0x09,  0x04,  0x09,  0x04,  0x0D, 	/* 4EF80 */
+	0xFC,  0x14,  0x00,  0x23,  0x00,  0x40,  0xFF,  0xA5,  0x10,  0x00,  0x0B,  0xFE,  0x0A,  0x02,  0x02,  0x02, 	/* 4EF90 */
+	0x22,  0xFA,  0x12,  0x8A,  0x12,  0x8A,  0x02,  0x8A,  0x7A,  0x8A,  0x0A,  0xFA,  0x0A,  0x02,  0x0A,  0x02, 	/* 4EFA0 */
+	0x0A,  0x02,  0x16,  0x06,  0x23,  0x00,  0x40,  0xFF,  0xA6,  0x01,  0x00,  0x21,  0x00,  0x11,  0x1E,  0x17, 	/* 4EFB0 */
+	0xD2,  0x01,  0x52,  0x01,  0x52,  0x01,  0x52,  0x79,  0x52,  0x09,  0x52,  0x0A,  0x52,  0x0A,  0x52,  0x0C, 	/* 4EFC0 */
+	0x5E,  0x09,  0x80,  0x14,  0x00,  0x23,  0x00,  0x40,  0xFF,  0xA9,  0x01,  0x00,  0x21,  0x00,  0x11,  0xFE, 	/* 4EFD0 */
+	0x11,  0x20,  0x02,  0x20,  0x02,  0x20,  0x04,  0xA8,  0x78,  0xA4,  0x09,  0x24,  0x09,  0x22,  0x0A,  0x22, 	/* 4EFE0 */
+	0x08,  0x22,  0x0C,  0x20,  0x14,  0x60,  0x23,  0x00,  0x40,  0xFF,  0xAA,  0x10,  0x20,  0x08,  0x20,  0x08, 	/* 4EFF0 */
+	0x20,  0x00,  0x20,  0x21,  0xFE,  0x11,  0x22,  0x11,  0x22,  0x01,  0x22,  0x79,  0xFE,  0x09,  0x22,  0x09, 	/* 4F000 */
+	0x22,  0x09,  0x22,  0x0D,  0xFE,  0x14,  0x00,  0x23,  0x00,  0x40,  0xFF,  0xAB,  0x00,  0x20,  0x20,  0x20, 	/* 4F010 */
+	0x10,  0x40,  0x11,  0xFC,  0x01,  0x04,  0x01,  0x04,  0x01,  0x04,  0x79,  0xFC,  0x09,  0x04,  0x09,  0x04, 	/* 4F020 */
+	0x09,  0x04,  0x09,  0x04,  0x0D,  0xFC,  0x14,  0x00,  0x23,  0x00,  0x40,  0xFF,  0xAD,  0x00,  0x20,  0x20, 	/* 4F030 */
+	0xA0,  0x10,  0xA0,  0x11,  0xFE,  0x01,  0x20,  0x02,  0x20,  0x00,  0x20,  0x7F,  0xFF,  0x08,  0x20,  0x08, 	/* 4F040 */
+	0x50,  0x08,  0x90,  0x08,  0x88,  0x15,  0x04,  0x12,  0x02,  0x21,  0x80,  0x40,  0x7F,  0xAF,  0x10,  0x88, 	/* 4F050 */
+	0x08,  0x88,  0x08,  0xE8,  0x01,  0x28,  0x21,  0x28,  0x11,  0xA8,  0x12,  0xAC,  0x04,  0x4A,  0x78,  0x49, 	/* 4F060 */
+	0x08,  0x88,  0x08,  0x88,  0x09,  0x08,  0x0E,  0x08,  0x14,  0x08,  0x23,  0x00,  0x40,  0xFF,  0xB0,  0x00, 	/* 4F070 */
+	0x28,  0x20,  0x24,  0x10,  0x24,  0x10,  0x20,  0x07,  0xFF,  0x00,  0x20,  0x00,  0x20,  0x79,  0x28,  0x09, 	/* 4F080 */
+	0x24,  0x09,  0x24,  0x09,  0x22,  0x0A,  0x22,  0x0C,  0x20,  0x14,  0x20,  0x23,  0x00,  0x40,  0xFF,  0xB4, 	/* 4F090 */
+	0x10,  0x00,  0x09,  0xFE,  0x09,  0x02,  0x01,  0x02,  0x21,  0x7A,  0x11,  0x4A,  0x11,  0x4A,  0x01,  0x4A, 	/* 4F0A0 */
+	0x79,  0x4A,  0x09,  0x7A,  0x09,  0x02,  0x09,  0x02,  0x0D,  0xFE,  0x14,  0x00,  0x23,  0x00,  0x40,  0xFF, 	/* 4F0B0 */
+	0xB7,  0x00,  0x20,  0x21,  0x24,  0x10,  0xA4,  0x10,  0xA8,  0x00,  0x20,  0x07,  0xFF,  0x00,  0x70,  0x78, 	/* 4F0C0 */
+	0x70,  0x08,  0xA8,  0x08,  0xA8,  0x09,  0x24,  0x0A,  0x22,  0x08,  0x20,  0x14,  0x20,  0x23,  0x00,  0x40, 	/* 4F0D0 */
+	0xFF,  0xB8,  0x10,  0x84,  0x08,  0x44,  0x08,  0x48,  0x03,  0xFE,  0x20,  0x48,  0x10,  0x48,  0x10,  0x48, 	/* 4F0E0 */
+	0x03,  0xFF,  0x78,  0x48,  0x08,  0x48,  0x08,  0x48,  0x08,  0x48,  0x0C,  0x88,  0x15,  0x08,  0x23,  0x00, 	/* 4F0F0 */
+	0x40,  0xFF,  0xB9,  0x10,  0x20,  0x08,  0x20,  0x08,  0x20,  0x07,  0xFE,  0x20,  0x50,  0x10,  0x50,  0x11, 	/* 4F100 */
+	0x54,  0x01,  0x54,  0x79,  0x52,  0x09,  0x52,  0x0A,  0x52,  0x08,  0x92,  0x0C,  0x90,  0x15,  0x30,  0x23, 	/* 4F110 */
+	0x00,  0x40,  0xFF,  0xBA,  0x10,  0x00,  0x0B,  0xFF,  0x08,  0x50,  0x00,  0x50,  0x20,  0x50,  0x11,  0xFE, 	/* 4F120 */
+	0x11,  0x52,  0x01,  0x52,  0x79,  0x56,  0x09,  0x8E,  0x09,  0x02,  0x09,  0x02,  0x0D,  0xFE,  0x14,  0x00, 	/* 4F130 */
+	0x23,  0x00,  0x40,  0xFF,  0xBD,  0x00,  0x20,  0x20,  0x40,  0x11,  0xF8,  0x11,  0x08,  0x01,  0x08,  0x01, 	/* 4F140 */
+	0x08,  0x01,  0xF8,  0x79,  0x00,  0x09,  0xFC,  0x09,  0x04,  0x09,  0x04,  0x09,  0x04,  0x0D,  0xFC,  0x14, 	/* 4F150 */
+	0x00,  0x23,  0x00,  0x40,  0xFF,  0x80,  0x00,  0x00,  0x21,  0xF8,  0x11,  0x08,  0x11,  0x08,  0x01,  0xF8, 	/* 4F160 */
+	0x01,  0x08,  0x01,  0x08,  0x79,  0xFA,  0x09,  0x24,  0x09,  0x28,  0x09,  0x10,  0x09,  0xC8,  0x0F,  0x04, 	/* 4F170 */
+	0x14,  0x02,  0x23,  0x00,  0x40,  0xFF,  0x81,  0x01,  0x08,  0x20,  0x88,  0x10,  0x90,  0x10,  0x20,  0x03, 	/* 4F180 */
+	0xFE,  0x00,  0x20,  0x00,  0x20,  0x78,  0x20,  0x0F,  0xFF,  0x08,  0x30,  0x08,  0x48,  0x08,  0x84,  0x0D, 	/* 4F190 */
+	0x02,  0x14,  0x02,  0x23,  0x00,  0x40,  0xFF,  0x83,  0x00,  0xA0,  0x20,  0xA0,  0x14,  0xA4,  0x12,  0xA4, 	/* 4F1A0 */
+	0x02,  0xA8,  0x00,  0xB0,  0x01,  0xA0,  0x7A,  0xA8,  0x0C,  0xA4,  0x08,  0xA4,  0x09,  0x20,  0x09,  0x22, 	/* 4F1B0 */
+	0x0E,  0x22,  0x14,  0x1E,  0x23,  0x00,  0x40,  0xFF,  0x85,  0x10,  0x04,  0x08,  0x18,  0x09,  0xE0,  0x01, 	/* 4F1C0 */
+	0x00,  0x21,  0x00,  0x11,  0xFF,  0x11,  0x00,  0x01,  0x00,  0x79,  0xFC,  0x09,  0x84,  0x0A,  0x84,  0x0A, 	/* 4F1D0 */
+	0x84,  0x0C,  0xFC,  0x14,  0x00,  0x23,  0x00,  0x40,  0xFF,  0x86,  0x01,  0x08,  0x20,  0x88,  0x10,  0x90, 	/* 4F1E0 */
+	0x17,  0xFF,  0x00,  0x20,  0x01,  0x24,  0x01,  0x24,  0x79,  0x24,  0x09,  0x24,  0x09,  0xFC,  0x09,  0x24, 	/* 4F1F0 */
+	0x08,  0x20,  0x0C,  0x40,  0x14,  0x80,  0x23,  0x00,  0x40,  0xFF,  0x8B,  0x10,  0x24,  0x08,  0x22,  0x0B, 	/* 4F200 */
+	0xFF,  0x00,  0x20,  0x21,  0xFE,  0x11,  0x22,  0x11,  0x22,  0x01,  0xFE,  0x79,  0x22,  0x09,  0x22,  0x09, 	/* 4F210 */
+	0xFE,  0x09,  0x22,  0x0D,  0x22,  0x15,  0x06,  0x23,  0x00,  0x40,  0xFF,  0x8D,  0x10,  0x20,  0x08,  0xA8, 	/* 4F220 */
+	0x08,  0xA4,  0x01,  0x22,  0x23,  0xFC,  0x11,  0x04,  0x11,  0x04,  0x01,  0xFC,  0x79,  0x04,  0x09,  0x04, 	/* 4F230 */
+	0x09,  0xFC,  0x09,  0x04,  0x0D,  0x04,  0x15,  0x0C,  0x23,  0x00,  0x40,  0xFF,  0x8E,  0x10,  0x00,  0x0B, 	/* 4F240 */
+	0xFF,  0x08,  0x50,  0x00,  0x50,  0x21,  0xFE,  0x11,  0x52,  0x11,  0x56,  0x01,  0x5E,  0x79,  0x82,  0x09, 	/* 4F250 */
+	0x02,  0x09,  0xFE,  0x09,  0x02,  0x0D,  0xFE,  0x14,  0x00,  0x23,  0x00,  0x40,  0xFF,  0x8F,  0x00,  0x04, 	/* 4F260 */
+	0x20,  0x18,  0x11,  0xE0,  0x10,  0x20,  0x07,  0xFF,  0x00,  0x70,  0x00,  0xA8,  0x79,  0x24,  0x0B,  0xFB, 	/* 4F270 */
+	0x08,  0x48,  0x08,  0x4C,  0x08,  0x44,  0x0C,  0x84,  0x15,  0x18,  0x23,  0x00,  0x40,  0xFF,  0x90,  0x00, 	/* 4F280 */
+	0x00,  0x27,  0xFF,  0x10,  0x40,  0x10,  0x62,  0x01,  0xA2,  0x06,  0x34,  0x00,  0x54,  0x78,  0x98,  0x0B, 	/* 4F290 */
+	0x38,  0x08,  0x54,  0x08,  0x92,  0x0B,  0x11,  0x0C,  0x10,  0x14,  0x60,  0x23,  0x00,  0x40,  0xFF,  0x91, 	/* 4F2A0 */
+	0x10,  0x20,  0x08,  0x24,  0x08,  0x22,  0x03,  0xFF,  0x20,  0x20,  0x12,  0x22,  0x11,  0x32,  0x01,  0x34, 	/* 4F2B0 */
+	0x78,  0x68,  0x08,  0xA8,  0x09,  0x24,  0x0E,  0x22,  0x08,  0x21,  0x14,  0x60,  0x23,  0x00,  0x40,  0xFF, 	/* 4F2C0 */
+	0x93,  0x00,  0x04,  0x10,  0x38,  0x09,  0xD0,  0x09,  0x10,  0x01,  0xFF,  0x01,  0x10,  0x01,  0xFF,  0x79, 	/* 4F2D0 */
+	0x10,  0x09,  0x7E,  0x09,  0x52,  0x09,  0x52,  0x0A,  0x52,  0x0C,  0x5C,  0x14,  0x10,  0x23,  0x10,  0x40, 	/* 4F2E0 */
+	0xFF,  0x94,  0x00,  0x20,  0x20,  0x20,  0x10,  0x50,  0x10,  0x50,  0x00,  0x88,  0x01,  0xFC,  0x02,  0x22, 	/* 4F2F0 */
+	0x78,  0x21,  0x0B,  0xFE,  0x08,  0xA8,  0x08,  0xA4,  0x09,  0x22,  0x0E,  0x22,  0x14,  0x60,  0x23,  0x00, 	/* 4F300 */
+	0x40,  0xFF,  0x95,  0x10,  0x00,  0x0B,  0xFE,  0x09,  0x24,  0x02,  0x48,  0x26,  0xD8,  0x11,  0x24,  0x11, 	/* 4F310 */
+	0x24,  0x00,  0x00,  0x7B,  0xFE,  0x08,  0x20,  0x08,  0x20,  0x08,  0x20,  0x0F,  0xFF,  0x14,  0x00,  0x23, 	/* 4F320 */
+	0x00,  0x40,  0xFF,  0x96,  0x10,  0x48,  0x0A,  0x48,  0x09,  0x8A,  0x01,  0x8A,  0x21,  0x2C,  0x12,  0xAC, 	/* 4F330 */
+	0x14,  0xA8,  0x00,  0xC8,  0x79,  0x8C,  0x0A,  0x94,  0x0C,  0x94,  0x08,  0x92,  0x0B,  0x22,  0x14,  0x41, 	/* 4F340 */
+	0x23,  0x00,  0x40,  0xFF,  0x97,  0x00,  0x00,  0x27,  0xFE,  0x10,  0x00,  0x11,  0xF8,  0x01,  0x08,  0x01, 	/* 4F350 */
+	0x08,  0x01,  0x08,  0x79,  0xF8,  0x08,  0x00,  0x09,  0x08,  0x08,  0x88,  0x08,  0x90,  0x0F,  0xFE,  0x14, 	/* 4F360 */
+	0x00,  0x23,  0x00,  0x40,  0xFF,  0x99,  0x00,  0x00,  0x21,  0xFC,  0x10,  0x00,  0x17,  0xFF,  0x00,  0x00, 	/* 4F370 */
+	0x01,  0xFC,  0x00,  0x00,  0x79,  0xFC,  0x08,  0x00,  0x09,  0xFC,  0x09,  0x04,  0x09,  0x04,  0x15,  0xFC, 	/* 4F380 */
+	0x13,  0x04,  0x21,  0x80,  0x40,  0x7F,  0x9A,  0x00,  0x00,  0x23,  0xFC,  0x10,  0x88,  0x10,  0x50,  0x01, 	/* 4F390 */
+	0xFE,  0x01,  0x22,  0x01,  0x22,  0x79,  0xFE,  0x09,  0x22,  0x09,  0x22,  0x09,  0xFE,  0x09,  0x22,  0x0D, 	/* 4F3A0 */
+	0x22,  0x15,  0x26,  0x23,  0x00,  0x40,  0xFF,  0x9D,  0x01,  0x04,  0x21,  0x38,  0x11,  0x20,  0x11,  0x20, 	/* 4F3B0 */
+	0x07,  0xFF,  0x01,  0x24,  0x01,  0x24,  0x79,  0xE4,  0x0F,  0x24,  0x09,  0x24,  0x09,  0x44,  0x09,  0x84, 	/* 4F3C0 */
+	0x17,  0x04,  0x12,  0x04,  0x21,  0x80,  0x40,  0x7F,  0x9E,  0x10,  0x00,  0x09,  0xFC,  0x09,  0x04,  0x01, 	/* 4F3D0 */
+	0x04,  0x21,  0xFC,  0x10,  0x00,  0x13,  0xFE,  0x00,  0x20,  0x78,  0x20,  0x09,  0xFC,  0x08,  0x20,  0x08, 	/* 4F3E0 */
+	0x20,  0x0B,  0xFE,  0x14,  0x00,  0x23,  0x00,  0x40,  0xFF,  0x9F,  0x00,  0x20,  0x20,  0x20,  0x17,  0xFF, 	/* 4F3F0 */
+	0x10,  0x20,  0x00,  0x20,  0x03,  0xFE,  0x02,  0x22,  0x7A,  0x22,  0x0B,  0xFE,  0x08,  0x70,  0x08,  0xA8, 	/* 4F400 */
+	0x09,  0x24,  0x0E,  0x23,  0x14,  0x20,  0x23,  0x00,  0x40,  0xFF,  0xA0,  0x00,  0x20,  0x21,  0x20,  0x11, 	/* 4F410 */
+	0x20,  0x11,  0xFE,  0x02,  0x20,  0x02,  0x20,  0x07,  0xFF,  0x78,  0x00,  0x09,  0xFC,  0x09,  0x04,  0x09, 	/* 4F420 */
+	0x04,  0x09,  0x04,  0x0D,  0xFC,  0x14,  0x00,  0x23,  0x00,  0x40,  0xFF,  0xA1,  0x10,  0x20,  0x08,  0x28, 	/* 4F430 */
+	0x08,  0x46,  0x03,  0xF9,  0x20,  0x28,  0x10,  0x49,  0x10,  0x87,  0x03,  0x20,  0x78,  0x7C,  0x08,  0xC4, 	/* 4F440 */
+	0x0B,  0x28,  0x08,  0x30,  0x0C,  0x4C,  0x15,  0x83,  0x23,  0x00,  0x40,  0xFF,  0xA2,  0x00,  0x80,  0x20, 	/* 4F450 */
+	0xFC,  0x11,  0x08,  0x16,  0x90,  0x00,  0x60,  0x00,  0xD8,  0x07,  0x07,  0x78,  0x20,  0x0B,  0xFC,  0x08, 	/* 4F460 */
+	0x20,  0x09,  0xFC,  0x08,  0x20,  0x0F,  0xFE,  0x14,  0x20,  0x23,  0x20,  0x40,  0xFF,  0xA3,  0x00,  0x20, 	/* 4F470 */
+	0x20,  0x20,  0x17,  0xFF,  0x10,  0x20,  0x01,  0xFC,  0x01,  0x24,  0x01,  0x24,  0x79,  0xFC,  0x09,  0x24, 	/* 4F480 */
+	0x09,  0x24,  0x09,  0xFC,  0x08,  0x20,  0x0F,  0xFF,  0x14,  0x20,  0x23,  0x20,  0x40,  0xFF,  0xA7,  0x10, 	/* 4F490 */
+	0x48,  0x08,  0x44,  0x08,  0x84,  0x01,  0x22,  0x22,  0x22,  0x10,  0x50,  0x10,  0x88,  0x01,  0x04,  0x7A, 	/* 4F4A0 */
+	0xFE,  0x0C,  0x85,  0x08,  0x84,  0x08,  0x84,  0x0C,  0xFC,  0x14,  0x00,  0x23,  0x00,  0x40,  0xFF,  0xAE, 	/* 4F4B0 */
+	0x00,  0x20,  0x20,  0x20,  0x13,  0xFC,  0x10,  0x24,  0x07,  0xFF,  0x00,  0x24,  0x03,  0xFC,  0x7A,  0x24, 	/* 4F4C0 */
+	0x09,  0x24,  0x09,  0x28,  0x08,  0x70,  0x09,  0xAC,  0x0E,  0x23,  0x14,  0x60,  0x23,  0x00,  0x40,  0xFF, 	/* 4F4D0 */
+	0xB1,  0x00,  0x00,  0x21,  0xFE,  0x11,  0x22,  0x11,  0x22,  0x01,  0xFA,  0x01,  0x22,  0x01,  0xFE,  0x79, 	/* 4F4E0 */
+	0x02,  0x09,  0x7A,  0x09,  0x4A,  0x09,  0x4A,  0x0A,  0x7A,  0x0C,  0x02,  0x14,  0x06,  0x23,  0x00,  0x40, 	/* 4F4F0 */
+	0xFF,  0xB2,  0x00,  0x88,  0x20,  0x88,  0x11,  0x10,  0x11,  0xFE,  0x03,  0x10,  0x05,  0x10,  0x01,  0xFC, 	/* 4F500 */
+	0x39,  0x10,  0x09,  0x10,  0x09,  0xFC,  0x09,  0x10,  0x09,  0x10,  0x15,  0xFE,  0x13,  0x00,  0x21,  0x80, 	/* 4F510 */
+	0x40,  0x7F,  0xB5,  0x10,  0x20,  0x08,  0x20,  0x09,  0xFE,  0x00,  0x20,  0x20,  0x20,  0x13,  0xFF,  0x10, 	/* 4F520 */
+	0x48,  0x00,  0x49,  0x78,  0xA7,  0x0B,  0x20,  0x09,  0xFC,  0x08,  0x20,  0x0C,  0x20,  0x15,  0xFE,  0x23, 	/* 4F530 */
+	0x00,  0x40,  0xFF,  0xB6,  0x10,  0x04,  0x08,  0x18,  0x09,  0xE0,  0x00,  0x20,  0x23,  0xFF,  0x10,  0x70, 	/* 4F540 */
+	0x10,  0xAC,  0x03,  0x23,  0x78,  0x20,  0x0B,  0xFF,  0x08,  0x48,  0x08,  0xC8,  0x0C,  0x38,  0x14,  0xC4, 	/* 4F550 */
+	0x23,  0x00,  0x40,  0xFF,  0xB8,  0x00,  0x40,  0x20,  0x78,  0x10,  0x88,  0x11,  0x10,  0x07,  0xFC,  0x01, 	/* 4F560 */
+	0x24,  0x01,  0x24,  0x79,  0x24,  0x09,  0xFC,  0x08,  0x50,  0x08,  0x50,  0x08,  0x91,  0x15,  0x11,  0x12, 	/* 4F570 */
+	0x0F,  0x21,  0x80,  0x40,  0x7F,  0xB9,  0x10,  0x20,  0x08,  0x20,  0x09,  0xFE,  0x00,  0x20,  0x20,  0x20, 	/* 4F580 */
+	0x17,  0xFF,  0x10,  0x88,  0x00,  0x50,  0x7B,  0xFE,  0x08,  0x20,  0x08,  0x20,  0x0B,  0xFE,  0x0C,  0x20, 	/* 4F590 */
+	0x14,  0x20,  0x23,  0x00,  0x40,  0xFF,  0xBC,  0x00,  0x00,  0x27,  0xFF,  0x10,  0x00,  0x10,  0xFC,  0x00, 	/* 4F5A0 */
+	0x84,  0x00,  0xFC,  0x00,  0x00,  0x79,  0xFE,  0x09,  0x22,  0x09,  0x22,  0x09,  0xFE,  0x09,  0x22,  0x17, 	/* 4F5B0 */
+	0x22,  0x13,  0xFE,  0x21,  0x80,  0x40,  0x7F,  0xBE,  0x10,  0xE0,  0x08,  0x20,  0x08,  0x50,  0x01,  0x8C, 	/* 4F5C0 */
+	0x26,  0xFB,  0x10,  0x00,  0x13,  0xCA,  0x02,  0x4A,  0x7B,  0x4A,  0x0A,  0xD4,  0x0B,  0x54,  0x0A,  0xCA, 	/* 4F5D0 */
+	0x0E,  0x4A,  0x14,  0xCA,  0x23,  0x00,  0x40,  0xFF,  0x81,  0x00,  0x04,  0x20,  0x18,  0x13,  0xF0,  0x12, 	/* 4F5E0 */
+	0x10,  0x03,  0xFF,  0x02,  0x10,  0x02,  0xFC,  0x7A,  0x84,  0x0A,  0xFC,  0x0A,  0x84,  0x0A,  0xFC,  0x0A, 	/* 4F5F0 */
+	0x84,  0x0C,  0x84,  0x14,  0xFC,  0x23,  0x00,  0x40,  0xFF,  0x82,  0x01,  0x08,  0x20,  0x88,  0x10,  0x90, 	/* 4F600 */
+	0x17,  0xFE,  0x00,  0x44,  0x00,  0xA4,  0x03,  0x28,  0x78,  0x58,  0x08,  0x94,  0x0B,  0x34,  0x08,  0x52, 	/* 4F610 */
+	0x09,  0x91,  0x0C,  0x10,  0x14,  0x60,  0x23,  0x00,  0x40,  0xFF,  0x85,  0x00,  0x00,  0x21,  0xFE,  0x11, 	/* 4F620 */
+	0x02,  0x11,  0x02,  0x01,  0xFE,  0x01,  0x44,  0x01,  0x28,  0x79,  0xFE,  0x09,  0x10,  0x09,  0xFE,  0x0A, 	/* 4F630 */
+	0x10,  0x0A,  0xFF,  0x14,  0x10,  0x12,  0x10,  0x21,  0x90,  0x40,  0x7F,  0x87,  0x00,  0x00,  0x21,  0xFC, 	/* 4F640 */
+	0x11,  0x24,  0x11,  0xFC,  0x01,  0x24,  0x01,  0x24,  0x01,  0xFC,  0x78,  0x20,  0x0B,  0xFE,  0x0A,  0x22, 	/* 4F650 */
+	0x0A,  0x2A,  0x0A,  0x3A,  0x16,  0xCA,  0x12,  0x06,  0x21,  0x80,  0x40,  0x7F,  0x89,  0x10,  0x20,  0x08, 	/* 4F660 */
+	0x20,  0x08,  0x3E,  0x00,  0x20,  0x21,  0xFC,  0x11,  0x04,  0x11,  0xFC,  0x01,  0x04,  0x79,  0xFC,  0x09, 	/* 4F670 */
+	0x04,  0x09,  0x04,  0x09,  0xFC,  0x0C,  0x84,  0x15,  0x02,  0x23,  0x00,  0x40,  0xFF,  0x8A,  0x01,  0x08, 	/* 4F680 */
+	0x01,  0x08,  0x21,  0x08,  0x17,  0xFF,  0x11,  0x10,  0x01,  0x3E,  0x01,  0xC2,  0x79,  0x44,  0x09,  0x48, 	/* 4F690 */
+	0x0A,  0x7F,  0x0A,  0x48,  0x0C,  0x48,  0x08,  0x48,  0x15,  0x98,  0x23,  0x00,  0x40,  0xFF,  0x8B,  0x00, 	/* 4F6A0 */
+	0x00,  0x27,  0xFE,  0x14,  0x22,  0x14,  0x22,  0x03,  0xFC,  0x00,  0x20,  0x03,  0xFC,  0x7A,  0x24,  0x0B, 	/* 4F6B0 */
+	0xFC,  0x0A,  0x24,  0x0B,  0xFC,  0x08,  0x20,  0x17,  0xFE,  0x12,  0x20,  0x21,  0x80,  0x40,  0x7F,  0x8D, 	/* 4F6C0 */
+	0x00,  0x00,  0x23,  0xFF,  0x10,  0x00,  0x11,  0xFE,  0x01,  0x02,  0x01,  0xFE,  0x01,  0x00,  0x79,  0xFE, 	/* 4F6D0 */
+	0x09,  0xAA,  0x09,  0xAA,  0x0A,  0xFE,  0x0A,  0xAA,  0x0C,  0xAA,  0x14,  0xAA,  0x23,  0x86,  0x40,  0xFF, 	/* 4F6E0 */
+	0x8E,  0x00,  0x00,  0x21,  0xFC,  0x11,  0x04,  0x11,  0x3C,  0x01,  0x24,  0x01,  0x24,  0x03,  0xFE,  0x7A, 	/* 4F6F0 */
+	0x02,  0x0A,  0xFA,  0x0A,  0x8A,  0x0A,  0x8A,  0x0A,  0xFA,  0x0A,  0x02,  0x14,  0x06,  0x23,  0x00,  0x40, 	/* 4F700 */
+	0xFF,  0x8F,  0x10,  0x00,  0x09,  0xFC,  0x09,  0x04,  0x01,  0xFC,  0x21,  0x04,  0x11,  0xFC,  0x10,  0x80, 	/* 4F710 */
+	0x01,  0xFE,  0x7B,  0x22,  0x0D,  0x32,  0x09,  0x4A,  0x09,  0x82,  0x0D,  0xFA,  0x14,  0x0C,  0x23,  0x00, 	/* 4F720 */
+	0x40,  0xFF,  0x90,  0x10,  0x00,  0x09,  0xEE,  0x09,  0x22,  0x01,  0x22,  0x21,  0x22,  0x11,  0xEE,  0x11, 	/* 4F730 */
+	0x00,  0x01,  0xFE,  0x79,  0x12,  0x09,  0x0A,  0x09,  0xCC,  0x09,  0x04,  0x0D,  0x1A,  0x15,  0x61,  0x23, 	/* 4F740 */
+	0x00,  0x40,  0xFF,  0x91,  0x10,  0x10,  0x08,  0x20,  0x08,  0xFC,  0x00,  0x84,  0x20,  0xFC,  0x10,  0x84, 	/* 4F750 */
+	0x10,  0xFC,  0x00,  0x00,  0x79,  0xFE,  0x08,  0x10,  0x08,  0xFC,  0x08,  0x10,  0x0C,  0x10,  0x15,  0xFF, 	/* 4F760 */
+	0x22,  0x00,  0x41,  0xFF,  0x92,  0x10,  0x78,  0x08,  0x48,  0x08,  0x84,  0x01,  0xFE,  0x22,  0x51,  0x11, 	/* 4F770 */
+	0xFE,  0x11,  0x52,  0x01,  0x56,  0x79,  0x5E,  0x09,  0x82,  0x09,  0xFE,  0x09,  0x02,  0x0D,  0xFE,  0x14, 	/* 4F780 */
+	0x00,  0x23,  0x00,  0x40,  0xFF,  0x93,  0x01,  0x04,  0x20,  0x88,  0x17,  0xFF,  0x10,  0x40,  0x00,  0x80, 	/* 4F790 */
+	0x01,  0xFC,  0x01,  0x04,  0x79,  0xFC,  0x09,  0x04,  0x09,  0xFC,  0x09,  0x04,  0x09,  0x04,  0x0D,  0xFC, 	/* 4F7A0 */
+	0x14,  0x00,  0x23,  0x00,  0x40,  0xFF,  0x94,  0x00,  0x20,  0x20,  0x20,  0x11,  0xFC,  0x10,  0x20,  0x07, 	/* 4F7B0 */
+	0xFF,  0x00,  0x88,  0x00,  0x50,  0x7B,  0xFE,  0x08,  0x20,  0x09,  0xFC,  0x08,  0x20,  0x0B,  0xFE,  0x0C, 	/* 4F7C0 */
+	0x20,  0x14,  0x20,  0x23,  0x20,  0x40,  0xFF,  0x95,  0x00,  0x20,  0x23,  0xFC,  0x10,  0x44,  0x10,  0x44, 	/* 4F7D0 */
+	0x07,  0xFF,  0x00,  0x00,  0x01,  0xFC,  0x79,  0x04,  0x09,  0xFC,  0x08,  0x10,  0x09,  0xFE,  0x09,  0x10, 	/* 4F7E0 */
+	0x0F,  0xFF,  0x14,  0x10,  0x23,  0x10,  0x40,  0xFF,  0x96,  0x10,  0x20,  0x08,  0x20,  0x0B,  0xFF,  0x00, 	/* 4F7F0 */
+	0x20,  0x20,  0x20,  0x11,  0xFE,  0x11,  0x8A,  0x01,  0x52,  0x79,  0xFA,  0x09,  0x22,  0x09,  0xFA,  0x09, 	/* 4F800 */
+	0x22,  0x0D,  0x22,  0x15,  0x26,  0x23,  0x00,  0x40,  0xFF,  0x98,  0x10,  0x88,  0x0B,  0xFE,  0x08,  0x88, 	/* 4F810 */
+	0x03,  0xFE,  0x20,  0x88,  0x17,  0xFF,  0x10,  0x20,  0x01,  0xFC,  0x79,  0x24,  0x09,  0xFC,  0x09,  0x24, 	/* 4F820 */
+	0x0B,  0xFF,  0x0D,  0x04,  0x15,  0x0C,  0x23,  0x00,  0x40,  0xFF,  0x99,  0x10,  0x10,  0x08,  0x3E,  0x08, 	/* 4F830 */
+	0xC4,  0x03,  0x28,  0x20,  0xB0,  0x10,  0xC0,  0x17,  0x40,  0x00,  0xFE,  0x79,  0x20,  0x08,  0x20,  0x0F, 	/* 4F840 */
+	0xFF,  0x09,  0x22,  0x0D,  0x22,  0x15,  0xFE,  0x23,  0x00,  0x40,  0xFF,  0x9C,  0x00,  0x02,  0x27,  0x8C, 	/* 4F850 */
+	0x10,  0xF8,  0x11,  0x08,  0x01,  0x32,  0x01,  0x14,  0x01,  0x4C,  0x79,  0x92,  0x0F,  0x7D,  0x09,  0x08, 	/* 4F860 */
+	0x09,  0x2C,  0x09,  0x2A,  0x09,  0x49,  0x17,  0x08,  0x22,  0x00,  0x41,  0xFF,  0x9E,  0x10,  0x02,  0x08, 	/* 4F870 */
+	0x0C,  0x09,  0xF0,  0x01,  0x1E,  0x21,  0x10,  0x11,  0xFF,  0x11,  0xA2,  0x01,  0xB8,  0x79,  0xE2,  0x0A, 	/* 4F880 */
+	0xBE,  0x0A,  0x98,  0x0C,  0xA9,  0x09,  0x29,  0x14,  0x47,  0x23,  0x80,  0x40,  0xFF,  0xA0,  0x00,  0x40, 	/* 4F890 */
+	0x20,  0x40,  0x13,  0xFC,  0x10,  0x40,  0x07,  0xFE,  0x00,  0x00,  0x03,  0xFC,  0x7A,  0x04,  0x0B,  0xFC, 	/* 4F8A0 */
+	0x08,  0xC4,  0x09,  0x68,  0x0A,  0x50,  0x0C,  0x4C,  0x14,  0x43,  0x23,  0x00,  0x40,  0xFF,  0xA1,  0x02, 	/* 4F8B0 */
+	0x20,  0x21,  0x3E,  0x11,  0x52,  0x13,  0xF2,  0x00,  0x9E,  0x02,  0xB2,  0x02,  0xB2,  0x7A,  0xB2,  0x0B, 	/* 4F8C0 */
+	0xFE,  0x0A,  0x92,  0x08,  0x92,  0x09,  0x12,  0x16,  0x22,  0x12,  0x46,  0x21,  0x80,  0x40,  0xFF,  0xA3, 	/* 4F8D0 */
+	0x00,  0x20,  0x21,  0xFC,  0x11,  0x24,  0x11,  0xFC,  0x00,  0x20,  0x07,  0xFF,  0x00,  0x00,  0x79,  0xF8, 	/* 4F8E0 */
+	0x09,  0x08,  0x09,  0xF8,  0x09,  0x00,  0x09,  0xFC,  0x15,  0x04,  0x13,  0xFC,  0x21,  0x80,  0x40,  0x7F, 	/* 4F8F0 */
+	0xA5,  0x00,  0x0C,  0x23,  0xF0,  0x10,  0x84,  0x12,  0x44,  0x01,  0x48,  0x01,  0x10,  0x03,  0xFC,  0x78, 	/* 4F900 */
+	0x20,  0x08,  0x20,  0x0F,  0xFE,  0x09,  0x24,  0x09,  0x24,  0x15,  0xFC,  0x13,  0x04,  0x21,  0x80,  0x40, 	/* 4F910 */
+	0x7F,  0xA8,  0x01,  0x08,  0x21,  0x08,  0x37,  0xC8,  0x11,  0x1F,  0x07,  0xD2,  0x01,  0x12,  0x0F,  0xEA, 	/* 4F920 */
+	0x01,  0x0A,  0x79,  0xC4,  0x09,  0x4C,  0x0A,  0x4C,  0x0C,  0x52,  0x08,  0x62,  0x15,  0x81,  0x23,  0x00, 	/* 4F930 */
+	0x40,  0xFF,  0xA9,  0x00,  0x20,  0x20,  0x20,  0x13,  0xFF,  0x10,  0x84,  0x00,  0x48,  0x01,  0xFE,  0x01, 	/* 4F940 */
+	0x22,  0x79,  0xFE,  0x09,  0x22,  0x09,  0x7A,  0x09,  0x4A,  0x09,  0x7A,  0x15,  0x02,  0x13,  0x06,  0x21, 	/* 4F950 */
+	0x80,  0x40,  0x7F,  0xAD,  0x00,  0x50,  0x27,  0xFF,  0x10,  0x50,  0x13,  0xFE,  0x02,  0x52,  0x03,  0xFE, 	/* 4F960 */
+	0x02,  0x52,  0x7B,  0xFE,  0x08,  0x00,  0x09,  0xFC,  0x09,  0x04,  0x09,  0xFC,  0x15,  0x04,  0x13,  0xFC, 	/* 4F970 */
+	0x21,  0x80,  0x40,  0x7F,  0xAE,  0x00,  0x10,  0x20,  0x10,  0x11,  0xFF,  0x11,  0x00,  0x01,  0x24,  0x01, 	/* 4F980 */
+	0xFF,  0x01,  0x24,  0x79,  0x24,  0x09,  0x3C,  0x09,  0x24,  0x0A,  0x00,  0x0C,  0x54,  0x14,  0xAA,  0x13, 	/* 4F990 */
+	0x29,  0x21,  0x80,  0x40,  0x7F,  0xAF,  0x10,  0x00,  0x09,  0xFF,  0x09,  0x48,  0x01,  0x48,  0x21,  0xD9, 	/* 4F9A0 */
+	0x11,  0x65,  0x11,  0x4E,  0x01,  0x54,  0x79,  0xE6,  0x09,  0x4E,  0x09,  0x55,  0x0A,  0x65,  0x0C,  0x44, 	/* 4F9B0 */
+	0x14,  0xD8,  0x23,  0x00,  0x40,  0xFF,  0xB2,  0x10,  0x00,  0x09,  0xFE,  0x09,  0x02,  0x01,  0xFE,  0x21, 	/* 4F9C0 */
+	0x00,  0x11,  0xD6,  0x11,  0x10,  0x01,  0xD6,  0x79,  0x50,  0x09,  0x7C,  0x0A,  0x90,  0x0A,  0xFF,  0x0D, 	/* 4F9D0 */
+	0x10,  0x14,  0x10,  0x23,  0x00,  0x40,  0xFF,  0xB5,  0x01,  0x04,  0x20,  0x88,  0x17,  0xFF,  0x10,  0x90, 	/* 4F9E0 */
+	0x03,  0xFC,  0x02,  0x94,  0x03,  0x1C,  0x7B,  0xFC,  0x0A,  0x04,  0x0B,  0xFC,  0x08,  0x08,  0x0F,  0xFF, 	/* 4F9F0 */
+	0x14,  0x88,  0x12,  0x48,  0x21,  0x98,  0x40,  0xFF,  0xB6,  0x10,  0x10,  0x08,  0xFC,  0x08,  0x10,  0x01, 	/* 4FA00 */
+	0xFE,  0x20,  0x84,  0x13,  0xFF,  0x10,  0x84,  0x00,  0xE4,  0x7B,  0x1F,  0x08,  0x00,  0x09,  0xFE,  0x08, 	/* 4FA10 */
+	0x28,  0x0C,  0x49,  0x15,  0x87,  0x23,  0x00,  0x40,  0xFF,  0xB7,  0x00,  0x00,  0x17,  0xFE,  0x08,  0x90, 	/* 4FA20 */
+	0x0B,  0xFC,  0x02,  0x94,  0x03,  0xFC,  0x00,  0x40,  0x7F,  0xFF,  0x08,  0x88,  0x09,  0xF4,  0x0A,  0x13, 	/* 4FA30 */
+	0x0D,  0xF4,  0x09,  0x04,  0x14,  0xFC,  0x23,  0x00,  0x40,  0xFF,  0xB8,  0x00,  0x00,  0x27,  0xBC,  0x10, 	/* 4FA40 */
+	0x84,  0x17,  0xBC,  0x04,  0x20,  0x04,  0x62,  0x03,  0xDE,  0x71,  0x10,  0x17,  0xFC,  0x11,  0x10,  0x11, 	/* 4FA50 */
+	0x10,  0x1F,  0xFE,  0x10,  0xA0,  0x2B,  0x18,  0x26,  0x04,  0x41,  0xFF,  0xBA,  0x00,  0x20,  0x21,  0xF8, 	/* 4FA60 */
+	0x11,  0x28,  0x11,  0xF8,  0x00,  0x20,  0x07,  0xFE,  0x00,  0x00,  0x79,  0xF8,  0x09,  0x08,  0x09,  0xF8, 	/* 4FA70 */
+	0x09,  0x08,  0x09,  0xF8,  0x0D,  0x08,  0x15,  0xF8,  0x23,  0x04,  0x40,  0xFF,  0xBC,  0x00,  0x20,  0x20, 	/* 4FA80 */
+	0x20,  0x17,  0xFF,  0x12,  0x4A,  0x01,  0x84,  0x01,  0xFE,  0x02,  0x85,  0x7C,  0xFC,  0x08,  0x84,  0x08, 	/* 4FA90 */
+	0xFC,  0x09,  0x24,  0x09,  0x22,  0x0A,  0x22,  0x14,  0x60,  0x23,  0x00,  0x40,  0xFF,  0xBD,  0x10,  0x10, 	/* 4FAA0 */
+	0x08,  0x1E,  0x08,  0x10,  0x21,  0xFF,  0x11,  0x2A,  0x11,  0xF0,  0x01,  0x24,  0x79,  0xFF,  0x09,  0x21, 	/* 4FAB0 */
+	0x09,  0xD6,  0x0A,  0x2C,  0x0A,  0xDA,  0x0C,  0x2A,  0x14,  0xC9,  0x23,  0x18,  0x40,  0xFF,  0xBF,  0x00, 	/* 4FAC0 */
+	0x08,  0x23,  0xC8,  0x12,  0x7E,  0x12,  0x44,  0x02,  0x54,  0x03,  0xC8,  0x02,  0x7F,  0x7A,  0x08,  0x0B, 	/* 4FAD0 */
+	0xC8,  0x0B,  0x7E,  0x0D,  0x48,  0x09,  0x48,  0x0D,  0xC8,  0x14,  0x08,  0x23,  0x00,  0x40,  0xFF,  0x80, 	/* 4FAE0 */
+	0x10,  0x48,  0x08,  0x88,  0x0B,  0xC8,  0x02,  0x4F,  0x23,  0xD2,  0x12,  0x62,  0x13,  0xD2,  0x00,  0x94, 	/* 4FAF0 */
+	0x7F,  0xF4,  0x08,  0x8C,  0x09,  0xC8,  0x09,  0x54,  0x0A,  0x52,  0x14,  0xE1,  0x23,  0x00,  0x40,  0xFF, 	/* 4FB00 */
+	0x81,  0x10,  0x88,  0x0B,  0xFF,  0x08,  0x88,  0x01,  0xFC,  0x21,  0x24,  0x11,  0xFC,  0x11,  0x24,  0x01, 	/* 4FB10 */
+	0xFC,  0x78,  0x20,  0x0B,  0xFE,  0x0A,  0x2A,  0x0A,  0x36,  0x0A,  0xC2,  0x16,  0x06,  0x23,  0x00,  0x40, 	/* 4FB20 */
+	0xFF,  0x82,  0x21,  0x00,  0x11,  0xFE,  0x12,  0x4A,  0x04,  0x8A,  0x27,  0xD2,  0x15,  0x66,  0x17,  0xD0, 	/* 4FB30 */
+	0x05,  0x5E,  0x75,  0x68,  0x17,  0xC8,  0x14,  0x7F,  0x14,  0x48,  0x14,  0x48,  0x2C,  0xC8,  0x26,  0x00, 	/* 4FB40 */
+	0x41,  0xFF,  0x83,  0x10,  0x20,  0x0B,  0xFE,  0x0A,  0x4A,  0x01,  0x87,  0x26,  0x48,  0x13,  0xFE,  0x10, 	/* 4FB50 */
+	0x40,  0x00,  0xA2,  0x7B,  0x6C,  0x08,  0x98,  0x0B,  0x34,  0x08,  0xD2,  0x17,  0x11,  0x12,  0x60,  0x21, 	/* 4FB60 */
+	0x80,  0x40,  0x7F,  0x84,  0x00,  0x00,  0x23,  0xFC,  0x12,  0x94,  0x13,  0xFC,  0x00,  0x00,  0x0F,  0xFF, 	/* 4FB70 */
+	0x00,  0x00,  0x79,  0xF8,  0x09,  0x08,  0x09,  0xF8,  0x08,  0xC2,  0x09,  0x64,  0x16,  0x58,  0x12,  0x47, 	/* 4FB80 */
+	0x21,  0xC0,  0x40,  0x7F,  0x87,  0x10,  0x00,  0x0B,  0xFF,  0x08,  0xA4,  0x01,  0x22,  0x23,  0xFF,  0x11, 	/* 4FB90 */
+	0x22,  0x11,  0x76,  0x01,  0xAA,  0x79,  0x76,  0x09,  0x76,  0x09,  0xAA,  0x09,  0x76,  0x0D,  0x22,  0x15, 	/* 4FBA0 */
+	0x26,  0x22,  0x00,  0x41,  0xFF,  0x89,  0x10,  0x20,  0x08,  0xFC,  0x08,  0x84,  0x00,  0xFC,  0x20,  0x84, 	/* 4FBB0 */
+	0x10,  0xFC,  0x10,  0x84,  0x03,  0xFF,  0x7A,  0x01,  0x0A,  0x59,  0x08,  0x84,  0x09,  0xFE,  0x0E,  0x85, 	/* 4FBC0 */
+	0x14,  0xFC,  0x23,  0x00,  0x40,  0xFF,  0x8A,  0x10,  0x20,  0x08,  0xFC,  0x08,  0x84,  0x00,  0xFC,  0x20, 	/* 4FBD0 */
+	0x84,  0x10,  0xFC,  0x10,  0x84,  0x03,  0xFF,  0x7A,  0x49,  0x0B,  0xA7,  0x08,  0xFC,  0x08,  0x20,  0x0C, 	/* 4FBE0 */
+	0x7C,  0x14,  0x44,  0x23,  0x98,  0x40,  0xFF,  0x8F,  0x10,  0x00,  0x0B,  0xFE,  0x0A,  0x52,  0x03,  0xFE, 	/* 4FBF0 */
+	0x21,  0x00,  0x11,  0x12,  0x16,  0x9F,  0x01,  0x34,  0x7A,  0x9E,  0x0F,  0xD4,  0x09,  0x1E,  0x0B,  0x94, 	/* 4FC00 */
+	0x0D,  0x54,  0x15,  0x1F,  0x23,  0x00,  0x40,  0xFF,  0x91,  0x00,  0x00,  0x0F,  0xE0,  0x08,  0x20,  0x08, 	/* 4FC10 */
+	0x20,  0x0F,  0xE0,  0x00,  0x00,  0x3F,  0xF8,  0x21,  0x08,  0x21,  0x08,  0x21,  0x08,  0x3F,  0xF8,  0x20, 	/* 4FC20 */
+	0x00,  0x20,  0x00,  0x20,  0x02,  0x10,  0x02,  0x0F,  0xFE,  0xA3,  0x00,  0x00,  0x7F,  0x3E,  0x09,  0x22, 	/* 4FC30 */
+	0x09,  0x24,  0x09,  0x28,  0x3F,  0x38,  0x09,  0x24,  0x09,  0x22,  0x09,  0x22,  0x3F,  0x21,  0x09,  0x31, 	/* 4FC40 */
+	0x09,  0x29,  0x11,  0x26,  0x11,  0x20,  0x21,  0x20,  0x43,  0x20,  0xA6,  0x04,  0x00,  0x04,  0x3C,  0x3F, 	/* 4FC50 */
+	0xA4,  0x04,  0x24,  0x04,  0x28,  0x3F,  0xB0,  0x04,  0x28,  0x04,  0x24,  0x04,  0x22,  0x7F,  0xA2,  0x04, 	/* 4FC60 */
+	0x22,  0x04,  0x22,  0x08,  0x32,  0x08,  0x2C,  0x10,  0x20,  0x20,  0x20,  0xA8,  0x08,  0x00,  0x08,  0xBE, 	/* 4FC70 */
+	0x0B,  0x22,  0x7C,  0x24,  0x08,  0x24,  0x29,  0x28,  0x29,  0x24,  0x29,  0x22,  0x29,  0x22,  0x29,  0x21, 	/* 4FC80 */
+	0x3F,  0x21,  0x08,  0x31,  0x08,  0xAE,  0x08,  0xA0,  0x07,  0xA0,  0x00,  0x20,  0xAA,  0x00,  0x00,  0x3F, 	/* 4FC90 */
+	0x7C,  0x12,  0x44,  0x12,  0x44,  0x12,  0x48,  0x12,  0x50,  0x7F,  0xC8,  0x06,  0x44,  0x06,  0x44,  0x0A, 	/* 4FCA0 */
+	0x42,  0x0A,  0x42,  0x12,  0x62,  0x22,  0x5C,  0x42,  0x40,  0x02,  0x40,  0x06,  0x40,  0xAF,  0x11,  0x00, 	/* 4FCB0 */
+	0x11,  0x3E,  0x11,  0x22,  0x11,  0x24,  0x7F,  0xE4,  0x11,  0x28,  0x11,  0x24,  0x11,  0x22,  0x11,  0x22, 	/* 4FCC0 */
+	0x1F,  0x21,  0x11,  0x21,  0x11,  0x31,  0x11,  0x2E,  0x11,  0x20,  0x1F,  0x20,  0x00,  0x20,  0xB1,  0x01, 	/* 4FCD0 */
+	0x00,  0x06,  0x3E,  0x18,  0x22,  0x10,  0x24,  0x10,  0x24,  0x1F,  0xA8,  0x11,  0x24,  0x11,  0x22,  0x11, 	/* 4FCE0 */
+	0x22,  0x11,  0x21,  0x11,  0x21,  0x11,  0xF1,  0x1E,  0x2E,  0x60,  0x20,  0x00,  0x20,  0x00,  0x20,  0xB5, 	/* 4FCF0 */
+	0x00,  0x00,  0x7F,  0xBE,  0x08,  0xA2,  0x08,  0xA4,  0x10,  0xA4,  0x10,  0xA8,  0x20,  0xA4,  0x43,  0x22, 	/* 4FD00 */
+	0x00,  0x22,  0x3F,  0x21,  0x21,  0x21,  0x21,  0x31,  0x21,  0x2E,  0x21,  0x20,  0x3F,  0x20,  0x00,  0x20, 	/* 4FD10 */
+	0xB8,  0x01,  0x00,  0x06,  0x3E,  0x38,  0x22,  0x24,  0x24,  0x24,  0x24,  0x24,  0x28,  0x3F,  0xA4,  0x24, 	/* 4FD20 */
+	0x22,  0x24,  0x22,  0x24,  0x21,  0x22,  0x21,  0x3A,  0xB9,  0x62,  0xA6,  0x01,  0xA0,  0x7D,  0xA0,  0x00, 	/* 4FD30 */
+	0xA0,  0x81,  0x04,  0x00,  0x04,  0x1E,  0x7F,  0xF2,  0x04,  0x12,  0x08,  0x14,  0x0F,  0x98,  0x18,  0x94, 	/* 4FD40 */
+	0x18,  0x92,  0x2F,  0x91,  0x48,  0x91,  0x08,  0x91,  0x0F,  0x99,  0x08,  0x96,  0x08,  0x90,  0x08,  0x90, 	/* 4FD50 */
+	0x09,  0x90,  0x8A,  0x08,  0x00,  0x08,  0x3C,  0x08,  0x24,  0x7F,  0xA4,  0x12,  0x28,  0x11,  0x30,  0x22, 	/* 4FD60 */
+	0xA8,  0x52,  0xA4,  0x0A,  0x22,  0x0C,  0x22,  0x04,  0x22,  0x0A,  0x22,  0x09,  0x32,  0x11,  0x2C,  0x20, 	/* 4FD70 */
+	0x20,  0x40,  0x20,  0x8E,  0x08,  0x00,  0x08,  0x3C,  0x3F,  0x24,  0x21,  0x24,  0x21,  0x24,  0x3F,  0x28, 	/* 4FD80 */
+	0x21,  0x30,  0x21,  0x28,  0x3F,  0x24,  0x24,  0x22,  0x22,  0x22,  0x21,  0x22,  0x27,  0x32,  0x38,  0xAC, 	/* 4FD90 */
+	0x60,  0xA0,  0x00,  0x20,  0x9B,  0x00,  0x80,  0x03,  0x3E,  0x3D,  0x22,  0x28,  0xA4,  0x24,  0x64,  0x44, 	/* 4FDA0 */
+	0x68,  0x3F,  0x24,  0x01,  0x22,  0x02,  0x22,  0x04,  0xA1,  0x07,  0x21,  0x7C,  0x31,  0x04,  0x2E,  0x04, 	/* 4FDB0 */
+	0x20,  0x04,  0x20,  0x0C,  0x20,  0xA1,  0x00,  0x00,  0x3F,  0x3C,  0x09,  0x24,  0x09,  0x24,  0x7F,  0xA8, 	/* 4FDC0 */
+	0x09,  0x30,  0x09,  0x28,  0x3F,  0x24,  0x08,  0x24,  0x10,  0x22,  0x1F,  0x22,  0x31,  0x22,  0x31,  0x32, 	/* 4FDD0 */
+	0x51,  0x2C,  0x1F,  0x20,  0x00,  0x20,  0xA2,  0x00,  0x00,  0x3F,  0x3E,  0x21,  0x22,  0x21,  0x24,  0x3F, 	/* 4FDE0 */
+	0x24,  0x00,  0x28,  0x00,  0x24,  0x7F,  0xA2,  0x04,  0x22,  0x04,  0x21,  0x3F,  0x21,  0x04,  0x31,  0x05, 	/* 4FDF0 */
+	0xAE,  0x0E,  0x20,  0x70,  0x20,  0x00,  0x20,  0xA4,  0x04,  0x00,  0x06,  0x3E,  0x09,  0x22,  0x08,  0xA4, 	/* 4FE00 */
+	0x14,  0xA4,  0x24,  0x28,  0x0A,  0x24,  0x09,  0x22,  0x10,  0xA2,  0x20,  0x61,  0x5F,  0xA1,  0x10,  0xB1, 	/* 4FE10 */
+	0x10,  0xAE,  0x10,  0xA0,  0x1F,  0xA0,  0x00,  0x20,  0xA8,  0x08,  0x00,  0x08,  0x3E,  0x7F,  0xA2,  0x21, 	/* 4FE20 */
+	0x22,  0x12,  0x24,  0x12,  0x24,  0x14,  0x28,  0xFF,  0xA4,  0x00,  0x22,  0x00,  0x22,  0x3F,  0x21,  0x21, 	/* 4FE30 */
+	0x31,  0x21,  0x29,  0x21,  0x26,  0x3F,  0x20,  0x00,  0x20,  0xAD,  0x04,  0x00,  0x04,  0x3E,  0x7F,  0xE2, 	/* 4FE40 */
+	0x00,  0x22,  0x1F,  0xA4,  0x10,  0xA4,  0x1F,  0xA8,  0x00,  0x24,  0x3F,  0xA2,  0x01,  0x22,  0x02,  0x21, 	/* 4FE50 */
+	0x03,  0xB1,  0x7E,  0x29,  0x02,  0x26,  0x02,  0x20,  0x06,  0x20,  0xB5,  0x00,  0x80,  0x03,  0x3C,  0x3C, 	/* 4FE60 */
+	0x24,  0x04,  0x24,  0x3F,  0xE8,  0x14,  0xB0,  0x14,  0xA8,  0x7F,  0xE4,  0x14,  0xA2,  0x14,  0xA2,  0x3F, 	/* 4FE70 */
+	0xE2,  0x04,  0x32,  0x04,  0x2C,  0x05,  0xA0,  0x0E,  0x20,  0x30,  0x20,  0xB7,  0x08,  0x00,  0x0B,  0xDE, 	/* 4FE80 */
+	0x12,  0x52,  0x16,  0x52,  0x67,  0xD4,  0x1A,  0x58,  0x0A,  0x54,  0x0F,  0xD2,  0x16,  0x11,  0x26,  0x91, 	/* 4FE90 */
+	0x7A,  0x51,  0x0A,  0x59,  0x12,  0xB6,  0x13,  0x30,  0x26,  0x10,  0x40,  0x10,  0xBD,  0x04,  0x00,  0x04, 	/* 4FEA0 */
+	0x9E,  0x3F,  0x92,  0x04,  0x92,  0x05,  0x14,  0x05,  0x14,  0x7F,  0xF8,  0x04,  0x14,  0x0F,  0x92,  0x08, 	/* 4FEB0 */
+	0x91,  0x18,  0x91,  0x2F,  0x91,  0x48,  0x99,  0x08,  0x96,  0x0F,  0x90,  0x00,  0x10,  0x82,  0x00,  0x00, 	/* 4FEC0 */
+	0x3B,  0xBE,  0x2A,  0xA2,  0x2A,  0xA4,  0x3B,  0xA4,  0x00,  0x28,  0x3F,  0x24,  0x00,  0x22,  0x7F,  0xA2, 	/* 4FED0 */
+	0x08,  0x21,  0x08,  0x21,  0x1F,  0x31,  0x11,  0x2E,  0x01,  0x20,  0x01,  0x20,  0x06,  0x20,  0x92,  0x10, 	/* 4FEE0 */
+	0x00,  0x1F,  0xBE,  0x28,  0xA2,  0x6A,  0xA4,  0x2A,  0xA4,  0x3E,  0xA8,  0x10,  0xA4,  0x23,  0x22,  0x10, 	/* 4FEF0 */
+	0x22,  0x1F,  0xA1,  0x28,  0xA1,  0x6A,  0xB1,  0x2A,  0xAE,  0x3E,  0xA0,  0x10,  0xA0,  0x23,  0x20,  0x99, 	/* 4FF00 */
+	0x00,  0x00,  0x1F,  0x3E,  0x11,  0x22,  0x11,  0x24,  0x1F,  0x24,  0x04,  0x28,  0x7F,  0xE4,  0x00,  0x22, 	/* 4FF10 */
+	0x3F,  0xA2,  0x20,  0xA1,  0x2E,  0xA1,  0x2A,  0xB1,  0x2E,  0xAE,  0x20,  0xA0,  0x3F,  0xA0,  0x00,  0x20, 	/* 4FF20 */
+	0xAD,  0x11,  0x00,  0x0A,  0x1E,  0x7F,  0xD2,  0x0A,  0x12,  0x3F,  0x94,  0x2A,  0x98,  0x33,  0x94,  0x20, 	/* 4FF30 */
+	0x92,  0x3F,  0x92,  0x20,  0x91,  0x3F,  0x91,  0x04,  0x19,  0x7F,  0xD6,  0x0A,  0x10,  0x11,  0x10,  0x60, 	/* 4FF40 */
+	0x10,  0xB0,  0x04,  0x00,  0x24,  0xBE,  0x15,  0x22,  0x7F,  0xE4,  0x0E,  0x24,  0x15,  0x28,  0x64,  0xA4, 	/* 4FF50 */
+	0x14,  0x22,  0x18,  0xA2,  0x2B,  0xE1,  0x2A,  0xA1,  0x5A,  0xB1,  0x17,  0xEE,  0x10,  0xA0,  0x20,  0xA0, 	/* 4FF60 */
+	0x40,  0xA0,  0xB2,  0x00,  0x00,  0x3B,  0xBE,  0x2A,  0xA2,  0x3B,  0xA4,  0x00,  0x24,  0x3F,  0xA8,  0x24, 	/* 4FF70 */
+	0xA4,  0x24,  0xA2,  0x3F,  0xA2,  0x24,  0xA1,  0x3F,  0xA1,  0x04,  0x31,  0x7F,  0xEE,  0x04,  0x20,  0x04, 	/* 4FF80 */
+	0x20,  0x04,  0x20,  0x89,  0x00,  0x00,  0x7F,  0xFE,  0x02,  0x40,  0x02,  0x40,  0x3F,  0xFC,  0x22,  0x44, 	/* 4FF90 */
+	0x22,  0x44,  0x24,  0x4C,  0x28,  0x3C,  0x30,  0x04,  0x20,  0x04,  0x3F,  0xFC,  0x20,  0x04,  0x20,  0x04, 	/* 4FFA0 */
+	0x3F,  0xFC,  0x00,  0x00,  0x8A,  0x00,  0x00,  0x7F,  0xFF,  0x0A,  0x08,  0x0A,  0x08,  0x3F,  0x88,  0x2A, 	/* 4FFB0 */
+	0x88,  0x2A,  0x88,  0x2A,  0x88,  0x33,  0x88,  0x20,  0x88,  0x20,  0x88,  0x3F,  0x88,  0x20,  0x88,  0x20, 	/* 4FFC0 */
+	0x88,  0x3F,  0x88,  0x00,  0x18,  0x8B,  0x08,  0x10,  0x04,  0x10,  0x04,  0x20,  0x7F,  0xFE,  0x02,  0x40, 	/* 4FFD0 */
+	0x02,  0x40,  0x3F,  0xFC,  0x22,  0x44,  0x24,  0x4C,  0x28,  0x3C,  0x30,  0x04,  0x3F,  0xFC,  0x20,  0x04, 	/* 4FFE0 */
+	0x20,  0x04,  0x3F,  0xFC,  0x00,  0x00,  0x8C,  0x00,  0x20,  0x7F,  0xA0,  0x0C,  0x20,  0x0C,  0x3E,  0x3F, 	/* 4FFF0 */
+	0x42,  0x2D,  0x42,  0x2D,  0x82,  0x35,  0x22,  0x37,  0x12,  0x21,  0x12,  0x21,  0x02,  0x3F,  0x02,  0x21, 	/* 50000 */
+	0x02,  0x21,  0x02,  0x3F,  0x04,  0x00,  0x18,  0x8D,  0x00,  0x00,  0x7F,  0xFE,  0x0A,  0x02,  0x0A,  0x02, 	/* 50010 */
+	0x3F,  0x82,  0x2A,  0x82,  0x2A,  0xBE,  0x2A,  0xA0,  0x33,  0xA0,  0x30,  0xA0,  0x20,  0xA0,  0x3F,  0xA0, 	/* 50020 */
+	0x20,  0xA1,  0x20,  0xA1,  0x3F,  0x91,  0x00,  0x0F,  0x8E,  0x00,  0x04,  0x7F,  0xC4,  0x0A,  0x04,  0x0A, 	/* 50030 */
+	0x04,  0x3F,  0xFF,  0x2A,  0x84,  0x2A,  0x84,  0x2A,  0xA4,  0x2B,  0x94,  0x30,  0x94,  0x20,  0x84,  0x3F, 	/* 50040 */
+	0x84,  0x20,  0x84,  0x20,  0x84,  0x3F,  0x84,  0x00,  0x0C,  0x92,  0x10,  0x00,  0x0F,  0xFF,  0x08,  0x50, 	/* 50050 */
+	0x00,  0x50,  0x43,  0xFE,  0x22,  0x52,  0x22,  0x52,  0x02,  0x52,  0x0A,  0x92,  0x0A,  0x8E,  0x13,  0x02, 	/* 50060 */
+	0x13,  0xFE,  0x22,  0x02,  0x22,  0x02,  0x43,  0xFE,  0x40,  0x00,  0x94,  0x00,  0x20,  0x7F,  0x20,  0x0C, 	/* 50070 */
+	0xFC,  0x0C,  0x24,  0x3F,  0x24,  0x2D,  0x25,  0x2D,  0x45,  0x35,  0x93,  0x37,  0x10,  0x31,  0x10,  0x21, 	/* 50080 */
+	0xFF,  0x3F,  0x10,  0x21,  0x10,  0x21,  0x10,  0x3F,  0x10,  0x21,  0x10,  0x96,  0x00,  0x10,  0x7F,  0x90, 	/* 50090 */
+	0x0C,  0x10,  0x0C,  0xFF,  0x3F,  0x91,  0x2D,  0x91,  0x2D,  0x10,  0x2D,  0x18,  0x37,  0x18,  0x31,  0x18, 	/* 500A0 */
+	0x21,  0x28,  0x3F,  0x28,  0x21,  0x29,  0x21,  0x49,  0x3F,  0x89,  0x01,  0x07,  0x98,  0x00,  0x00,  0x7F, 	/* 500B0 */
+	0xBC,  0x0C,  0x24,  0x0C,  0x24,  0x3F,  0x25,  0x2D,  0x45,  0x2D,  0x83,  0x2D,  0x7C,  0x37,  0x04,  0x31, 	/* 500C0 */
+	0x24,  0x21,  0x24,  0x3F,  0x18,  0x21,  0x18,  0x21,  0x24,  0x3F,  0x42,  0x01,  0x81,  0xA2,  0x00,  0x20, 	/* 500D0 */
+	0x7F,  0xA0,  0x0C,  0x20,  0x0C,  0x3F,  0x3F,  0x50,  0x2D,  0x50,  0x2D,  0x90,  0x35,  0x1E,  0x37,  0x10, 	/* 500E0 */
+	0x21,  0x10,  0x21,  0x10,  0x3F,  0x1E,  0x21,  0x10,  0x21,  0x10,  0x3F,  0x10,  0x00,  0x10,  0xA3,  0x00, 	/* 500F0 */
+	0x24,  0x7F,  0xA4,  0x0C,  0x24,  0x0C,  0xFF,  0x3F,  0x24,  0x2D,  0x24,  0x2D,  0x24,  0x35,  0x24,  0x37, 	/* 50100 */
+	0x3C,  0x31,  0x24,  0x21,  0x24,  0x3F,  0x24,  0x21,  0x24,  0x21,  0x24,  0x3F,  0x3C,  0x00,  0x00,  0xA5, 	/* 50110 */
+	0x00,  0x02,  0x7F,  0x8C,  0x0C,  0x78,  0x0C,  0x08,  0x3F,  0x08,  0x2D,  0xFF,  0x2D,  0x08,  0x2D,  0x1C, 	/* 50120 */
+	0x37,  0x1C,  0x31,  0x2C,  0x21,  0x2A,  0x3F,  0x4A,  0x21,  0x89,  0x21,  0x08,  0x3F,  0x08,  0x00,  0x08, 	/* 50130 */
+	0xA9,  0x00,  0x08,  0x7F,  0x88,  0x0C,  0x1E,  0x0C,  0x12,  0x3F,  0x22,  0x2D,  0x64,  0x2D,  0x94,  0x2D, 	/* 50140 */
+	0x08,  0x37,  0x10,  0x31,  0x3E,  0x21,  0x22,  0x3F,  0x62,  0x21,  0xA2,  0x21,  0x22,  0x3F,  0x3E,  0x00, 	/* 50150 */
+	0x00,  0xAA,  0x00,  0x20,  0x7F,  0xA0,  0x0C,  0x3C,  0x0C,  0x24,  0x3F,  0x44,  0x2D,  0xA8,  0x2D,  0x18, 	/* 50160 */
+	0x35,  0x18,  0x37,  0x24,  0x21,  0x42,  0x21,  0xFD,  0x3F,  0x44,  0x21,  0x44,  0x21,  0x44,  0x3F,  0x7C, 	/* 50170 */
+	0x00,  0x00,  0xAC,  0x00,  0x02,  0x7F,  0xD2,  0x0C,  0x52,  0x0C,  0x52,  0x3F,  0x52,  0x2D,  0x5A,  0x2D, 	/* 50180 */
+	0xD6,  0x35,  0xF2,  0x37,  0x52,  0x21,  0x52,  0x21,  0x52,  0x3F,  0x52,  0x21,  0x52,  0x21,  0x42,  0x3F, 	/* 50190 */
+	0x82,  0x01,  0x02,  0xB2,  0x00,  0x00,  0x7F,  0xBE,  0x0A,  0x22,  0x0A,  0x22,  0x3F,  0xA2,  0x2A,  0xBE, 	/* 501A0 */
+	0x2A,  0x80,  0x2A,  0x82,  0x2B,  0xBC,  0x30,  0x88,  0x20,  0x88,  0x3F,  0xBE,  0x20,  0x88,  0x20,  0x88, 	/* 501B0 */
+	0x3F,  0xFF,  0x00,  0x00,  0xB3,  0x00,  0x08,  0x7F,  0xC8,  0x0A,  0x32,  0x0A,  0x14,  0x3F,  0x8C,  0x2A, 	/* 501C0 */
+	0x92,  0x2A,  0xFD,  0x2A,  0x81,  0x33,  0xBE,  0x20,  0xA2,  0x20,  0xBE,  0x3F,  0xA2,  0x20,  0xBE,  0x20, 	/* 501D0 */
+	0xA2,  0x3F,  0xA2,  0x00,  0x26,  0xB5,  0x00,  0x10,  0x7F,  0x92,  0x0C,  0xFE,  0x0C,  0x14,  0x3F,  0x18, 	/* 501E0 */
+	0x2D,  0xFF,  0x2D,  0x10,  0x35,  0x20,  0x37,  0x7C,  0x21,  0x84,  0x21,  0x08,  0x3F,  0xFF,  0x21,  0x08, 	/* 501F0 */
+	0x21,  0x08,  0x3F,  0x08,  0x00,  0x18,  0xB7,  0x00,  0x10,  0x7F,  0x50,  0x0C,  0x50,  0x0C,  0x7E,  0x3F, 	/* 50200 */
+	0x90,  0x2D,  0x10,  0x2D,  0x10,  0x2D,  0xFF,  0x37,  0x00,  0x31,  0x00,  0x21,  0x7C,  0x3F,  0x44,  0x21, 	/* 50210 */
+	0x44,  0x21,  0x44,  0x3F,  0x7C,  0x00,  0x00,  0xB8,  0x00,  0x10,  0x7F,  0x98,  0x0C,  0x26,  0x0C,  0xFD, 	/* 50220 */
+	0x3F,  0x28,  0x2D,  0x2A,  0x2D,  0x46,  0x35,  0xA0,  0x37,  0x3C,  0x31,  0x44,  0x21,  0x54,  0x3F,  0x98, 	/* 50230 */
+	0x21,  0x08,  0x21,  0x14,  0x3F,  0x22,  0x00,  0xC1,  0x82,  0x00,  0x24,  0x7F,  0xA4,  0x0C,  0x24,  0x0C, 	/* 50240 */
+	0xFF,  0x3F,  0x24,  0x2D,  0x24,  0x2D,  0x34,  0x35,  0x6E,  0x37,  0x6E,  0x31,  0xB5,  0x21,  0xA5,  0x3F, 	/* 50250 */
+	0x24,  0x21,  0x24,  0x21,  0x24,  0x3F,  0x24,  0x00,  0x24,  0x87,  0x00,  0x10,  0x7F,  0x10,  0x0C,  0xFF, 	/* 50260 */
+	0x0C,  0x00,  0x3F,  0x7C,  0x2D,  0x44,  0x2D,  0x7C,  0x35,  0x00,  0x37,  0x7C,  0x21,  0x08,  0x21,  0x10, 	/* 50270 */
+	0x3F,  0xFF,  0x21,  0x10,  0x21,  0x10,  0x3F,  0x10,  0x00,  0x30,  0x89,  0x00,  0x08,  0x7F,  0x88,  0x0C, 	/* 50280 */
+	0xFF,  0x0C,  0x24,  0x3F,  0x24,  0x2D,  0x24,  0x2D,  0x36,  0x35,  0x49,  0x37,  0x88,  0x31,  0xFF,  0x21, 	/* 50290 */
+	0x08,  0x3F,  0x08,  0x21,  0x08,  0x21,  0x08,  0x3F,  0x08,  0x00,  0x08,  0x8B,  0x00,  0x24,  0x7F,  0xA4, 	/* 502A0 */
+	0x0C,  0x24,  0x0C,  0xFF,  0x3F,  0x24,  0x2D,  0x24,  0x2D,  0xFF,  0x35,  0x00,  0x37,  0x3E,  0x31,  0x22, 	/* 502B0 */
+	0x21,  0x22,  0x3F,  0x3E,  0x21,  0x22,  0x21,  0x22,  0x3F,  0x3E,  0x00,  0x00,  0x8D,  0x00,  0x00,  0x7F, 	/* 502C0 */
+	0xFC,  0x0C,  0x44,  0x0C,  0x7C,  0x3F,  0x44,  0x2D,  0x44,  0x2D,  0x7C,  0x35,  0x00,  0x37,  0xFF,  0x21, 	/* 502D0 */
+	0x10,  0x21,  0x50,  0x3F,  0x5E,  0x21,  0x50,  0x21,  0x70,  0x3F,  0x98,  0x21,  0x07,  0x90,  0x00,  0x40, 	/* 502E0 */
+	0x7F,  0x4E,  0x14,  0x4A,  0x14,  0x4A,  0x15,  0xFA,  0x3E,  0x4E,  0x2A,  0x4A,  0x2A,  0x4A,  0x37,  0xEA, 	/* 502F0 */
+	0x33,  0x2E,  0x23,  0x2A,  0x3F,  0x2A,  0x23,  0xEA,  0x22,  0x12,  0x3E,  0x12,  0x00,  0x26,  0x92,  0x00, 	/* 50300 */
+	0x00,  0x7F,  0xFE,  0x0C,  0x42,  0x0C,  0x7E,  0x3F,  0x42,  0x2D,  0x42,  0x2D,  0x7E,  0x35,  0x10,  0x37, 	/* 50310 */
+	0x50,  0x21,  0x7E,  0x21,  0x90,  0x3F,  0x7E,  0x21,  0x10,  0x21,  0x10,  0x3F,  0xFF,  0x00,  0x00,  0x97, 	/* 50320 */
+	0x00,  0xE8,  0x7F,  0x2A,  0x0C,  0xAC,  0x0C,  0x65,  0x3F,  0x46,  0x2D,  0x42,  0x2D,  0xFD,  0x35,  0x28, 	/* 50330 */
+	0x37,  0x28,  0x31,  0x28,  0x21,  0xFF,  0x3F,  0x28,  0x21,  0x28,  0x21,  0x49,  0x3F,  0x49,  0x21,  0x87, 	/* 50340 */
+	0x9C,  0x00,  0x08,  0x7F,  0x90,  0x0C,  0x7E,  0x0C,  0x52,  0x3F,  0x52,  0x2D,  0x7E,  0x2D,  0x52,  0x35, 	/* 50350 */
+	0x52,  0x37,  0x7E,  0x31,  0x14,  0x21,  0x34,  0x3F,  0x3A,  0x21,  0x5E,  0x21,  0x51,  0x3F,  0x91,  0x01, 	/* 50360 */
+	0x0F,  0xA2,  0x00,  0x10,  0x7F,  0x10,  0x0C,  0xFF,  0x0C,  0x20,  0x3F,  0x20,  0x2D,  0x7E,  0x2D,  0xA2, 	/* 50370 */
+	0x35,  0x22,  0x37,  0x3E,  0x31,  0x00,  0x21,  0x7E,  0x3F,  0x6A,  0x21,  0x6A,  0x21,  0x6A,  0x3F,  0xFF, 	/* 50380 */
+	0x00,  0x00,  0xA4,  0x24,  0x0C,  0x15,  0xF4,  0x05,  0x44,  0x0C,  0xA8,  0x17,  0xFF,  0x24,  0x88,  0x04, 	/* 50390 */
+	0x18,  0x7F,  0xFF,  0x01,  0x20,  0x1F,  0xFC,  0x12,  0x24,  0x1C,  0x3C,  0x1F,  0xFC,  0x10,  0x04,  0x1F, 	/* 503A0 */
+	0xFC,  0x10,  0x04,  0xAA,  0x00,  0x00,  0x7F,  0xEE,  0x0C,  0x66,  0x0C,  0xBA,  0x3F,  0x66,  0x2D,  0xAA, 	/* 503B0 */
+	0x2D,  0x10,  0x2D,  0x28,  0x37,  0x4C,  0x31,  0xB2,  0x21,  0x05,  0x3F,  0x18,  0x21,  0x62,  0x21,  0x04, 	/* 503C0 */
+	0x3F,  0x18,  0x00,  0xE0,  0xAB,  0x00,  0x00,  0x3F,  0xBD,  0x27,  0xA5,  0x2A,  0x43,  0x3F,  0xFC,  0x25, 	/* 503D0 */
+	0x14,  0x28,  0x88,  0x3F,  0xB4,  0x00,  0xC2,  0x7F,  0xFF,  0x01,  0x40,  0x1F,  0xFC,  0x12,  0x4C,  0x1C, 	/* 503E0 */
+	0x3C,  0x1F,  0xFC,  0x00,  0x00,  0xAF,  0x00,  0x10,  0x7F,  0x90,  0x0C,  0xFE,  0x0C,  0x10,  0x3F,  0x24, 	/* 503F0 */
+	0x2D,  0xFA,  0x2D,  0x45,  0x35,  0x54,  0x37,  0x54,  0x31,  0x55,  0x21,  0x83,  0x3F,  0x7E,  0x21,  0x6A, 	/* 50400 */
+	0x21,  0x6A,  0x3F,  0xFF,  0x00,  0x00,  0xB4,  0x00,  0x28,  0x7F,  0xFE,  0x0C,  0xAA,  0x0C,  0xFE,  0x3F, 	/* 50410 */
+	0xAA,  0x2D,  0xFE,  0x2D,  0x00,  0x2D,  0xFF,  0x37,  0x00,  0x31,  0x7E,  0x21,  0x42,  0x3F,  0x7E,  0x21, 	/* 50420 */
+	0x24,  0x21,  0x18,  0x3F,  0xFF,  0x00,  0x00,  0xB5,  0x00,  0x08,  0x7F,  0x8F,  0x0C,  0x08,  0x0C,  0x7F, 	/* 50430 */
+	0x3F,  0x52,  0x2D,  0x5C,  0x2D,  0x71,  0x2D,  0x4F,  0x37,  0x40,  0x31,  0x7F,  0x21,  0x68,  0x3F,  0x55, 	/* 50440 */
+	0x21,  0x6E,  0x21,  0x96,  0x3F,  0x25,  0x00,  0x0C,  0xB8,  0x00,  0x10,  0x7F,  0x10,  0x0D,  0xFF,  0x0C, 	/* 50450 */
+	0x44,  0x3F,  0xAA,  0x2D,  0x29,  0x2D,  0xFE,  0x35,  0x28,  0x37,  0xFE,  0x21,  0x28,  0x21,  0xFF,  0x3F, 	/* 50460 */
+	0x28,  0x21,  0x4A,  0x21,  0xC4,  0x3F,  0x72,  0x01,  0x81,  0xBA,  0x00,  0x02,  0x7F,  0x7C,  0x0C,  0x10, 	/* 50470 */
+	0x0D,  0xFF,  0x3F,  0x10,  0x2D,  0x7E,  0x2D,  0x76,  0x35,  0x5A,  0x37,  0x7E,  0x31,  0x10,  0x21,  0xFE, 	/* 50480 */
+	0x3F,  0x10,  0x21,  0xFF,  0x21,  0x00,  0x3F,  0xAA,  0x01,  0x25,  0x80,  0x00,  0x10,  0x7F,  0xFF,  0x0C, 	/* 50490 */
+	0x00,  0x0C,  0xEE,  0x3F,  0xAA,  0x2D,  0xEE,  0x2D,  0x24,  0x2D,  0x7E,  0x37,  0x24,  0x31,  0x7E,  0x21, 	/* 504A0 */
+	0x24,  0x3F,  0xFF,  0x21,  0x32,  0x21,  0xCC,  0x3F,  0x74,  0x00,  0xC3,  0x81,  0x1B,  0xEE,  0x22,  0x22, 	/* 504B0 */
+	0x3B,  0xEE,  0x23,  0x62,  0x7F,  0xFF,  0x41,  0x41,  0x5F,  0xFD,  0x12,  0x24,  0x1F,  0xFC,  0x10,  0x04, 	/* 504C0 */
+	0x1F,  0xFC,  0x08,  0x08,  0x17,  0xF4,  0x61,  0x13,  0x06,  0x10,  0x18,  0x60,  0x86,  0x00,  0x04,  0x00, 	/* 504D0 */
+	0x78,  0x3F,  0x88,  0x08,  0x88,  0x04,  0x90,  0x04,  0xA0,  0x00,  0x80,  0x7F,  0xFF,  0x01,  0xC0,  0x02, 	/* 504E0 */
+	0xA0,  0x04,  0x90,  0x18,  0x8C,  0x60,  0x83,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x87,  0x00,  0x04, 	/* 504F0 */
+	0x00,  0x38,  0x1F,  0xC0,  0x00,  0x84,  0x08,  0x44,  0x04,  0x48,  0x04,  0x90,  0x00,  0x80,  0x7F,  0xFF, 	/* 50500 */
+	0x01,  0xC0,  0x02,  0xA0,  0x04,  0x90,  0x18,  0x8C,  0x60,  0x83,  0x00,  0x80,  0x00,  0x80,  0x88,  0x01, 	/* 50510 */
+	0x00,  0x06,  0x7E,  0x78,  0x42,  0x09,  0x42,  0x49,  0x42,  0x2A,  0x42,  0x28,  0x7E,  0x7F,  0x50,  0x08, 	/* 50520 */
+	0x50,  0x18,  0x50,  0x1C,  0x48,  0x2A,  0x48,  0x28,  0x44,  0x48,  0x84,  0x08,  0x82,  0x09,  0x01,  0x89, 	/* 50530 */
+	0x02,  0x10,  0x0C,  0x10,  0x78,  0x10,  0x0A,  0x10,  0x4A,  0xFE,  0x2C,  0x92,  0x28,  0x92,  0x7F,  0x92, 	/* 50540 */
+	0x08,  0x92,  0x1C,  0xFE,  0x1A,  0x92,  0x2A,  0x92,  0x28,  0x92,  0x48,  0x92,  0x08,  0xFE,  0x08,  0x00, 	/* 50550 */
+	0x8B,  0x02,  0x00,  0x0C,  0xFE,  0x78,  0xAA,  0x0A,  0xFE,  0x4A,  0x10,  0x2C,  0xFE,  0x28,  0x10,  0x7F, 	/* 50560 */
+	0xFF,  0x08,  0x44,  0x1C,  0x28,  0x1B,  0xFF,  0x2A,  0x10,  0x28,  0xFE,  0x48,  0x10,  0x08,  0x10,  0x08, 	/* 50570 */
+	0x10,  0x8C,  0x00,  0x00,  0x1F,  0xFC,  0x10,  0x84,  0x10,  0x84,  0x1F,  0xFC,  0x10,  0x84,  0x10,  0x84, 	/* 50580 */
+	0x10,  0x84,  0x1F,  0xFC,  0x00,  0x80,  0x00,  0x80,  0x1F,  0xFC,  0x00,  0x80,  0x00,  0x80,  0x7F,  0xFF, 	/* 50590 */
+	0x00,  0x00,  0x8D,  0x00,  0x18,  0x1F,  0xE0,  0x00,  0x80,  0x7F,  0xFF,  0x00,  0x80,  0x0F,  0xF8,  0x08, 	/* 505A0 */
+	0x88,  0x0F,  0xF8,  0x08,  0x88,  0x08,  0x88,  0x0F,  0xF8,  0x00,  0x80,  0x1F,  0xFC,  0x00,  0x80,  0x7F, 	/* 505B0 */
+	0xFF,  0x00,  0x00,  0x8E,  0x00,  0x00,  0x3F,  0xFE,  0x29,  0x04,  0x29,  0x48,  0x3F,  0x30,  0x29,  0x10, 	/* 505C0 */
+	0x29,  0xFF,  0x3F,  0x12,  0x08,  0x14,  0x08,  0x18,  0x7F,  0x10,  0x08,  0x10,  0x08,  0x10,  0x0F,  0x10, 	/* 505D0 */
+	0x70,  0x10,  0x00,  0x30,  0x8F,  0x00,  0x00,  0x0F,  0xF8,  0x08,  0x08,  0x0F,  0xF8,  0x08,  0x08,  0x7F, 	/* 505E0 */
+	0xFF,  0x00,  0x00,  0x0F,  0xF8,  0x08,  0x88,  0x0F,  0xF8,  0x08,  0x88,  0x0F,  0xF8,  0x00,  0x80,  0x1F, 	/* 505F0 */
+	0xFC,  0x00,  0x80,  0x7F,  0xFF,  0x90,  0x04,  0x10,  0x04,  0x10,  0x3F,  0xBF,  0x04,  0x24,  0x7F,  0xD4, 	/* 50600 */
+	0x15,  0x08,  0x24,  0x94,  0x44,  0x63,  0x1F,  0xFF,  0x12,  0x48,  0x13,  0xF8,  0x12,  0x48,  0x17,  0xFE, 	/* 50610 */
+	0x20,  0x40,  0x5F,  0xFF,  0x00,  0x00,  0x91,  0x00,  0x80,  0x00,  0x80,  0x01,  0x40,  0x02,  0x20,  0x04, 	/* 50620 */
+	0x10,  0x18,  0x0C,  0x67,  0xF3,  0x00,  0x80,  0x00,  0x80,  0x1F,  0xFE,  0x00,  0x80,  0x08,  0x88,  0x04, 	/* 50630 */
+	0x88,  0x04,  0x90,  0x3F,  0xFE,  0x00,  0x00,  0x96,  0x04,  0x00,  0x04,  0xFE,  0x0A,  0x12,  0x09,  0x12, 	/* 50640 */
+	0x10,  0x92,  0x3F,  0x12,  0x44,  0x12,  0x04,  0x12,  0x7F,  0x12,  0x04,  0x12,  0x25,  0x12,  0x16,  0x22, 	/* 50650 */
+	0x14,  0x22,  0x07,  0x42,  0x18,  0x82,  0x61,  0x0C,  0x98,  0x04,  0x00,  0x04,  0x00,  0x0A,  0xFF,  0x09, 	/* 50660 */
+	0x08,  0x10,  0x88,  0x3F,  0x08,  0x44,  0x08,  0x04,  0x08,  0x3F,  0x88,  0x04,  0x08,  0x25,  0x08,  0x15, 	/* 50670 */
+	0x08,  0x16,  0x08,  0x05,  0x88,  0x0E,  0x08,  0x70,  0x18,  0x9B,  0x04,  0x10,  0x04,  0x10,  0x0A,  0x10, 	/* 50680 */
+	0x09,  0x10,  0x10,  0xFE,  0x3F,  0x12,  0x44,  0x12,  0x04,  0x12,  0x7F,  0x12,  0x04,  0x12,  0x25,  0x12, 	/* 50690 */
+	0x16,  0x22,  0x14,  0x22,  0x07,  0x42,  0x18,  0x82,  0x61,  0x0C,  0x9C,  0x02,  0x20,  0x04,  0x18,  0x0A, 	/* 506A0 */
+	0x24,  0x31,  0x42,  0x00,  0x80,  0x03,  0x60,  0x0C,  0x18,  0x77,  0xF7,  0x00,  0x80,  0x00,  0x80,  0x7F, 	/* 506B0 */
+	0xFF,  0x08,  0x88,  0x04,  0x88,  0x04,  0x90,  0x3F,  0xFE,  0x00,  0x00,  0x9D,  0x04,  0x10,  0x04,  0x10, 	/* 506C0 */
+	0x0C,  0x10,  0x0A,  0x10,  0x11,  0x10,  0x3F,  0x90,  0x44,  0xFF,  0x04,  0x10,  0x7F,  0x90,  0x04,  0x10, 	/* 506D0 */
+	0x25,  0x10,  0x16,  0x10,  0x14,  0x10,  0x07,  0x10,  0x1C,  0x10,  0x60,  0x10,  0x9F,  0x08,  0x78,  0x08, 	/* 506E0 */
+	0x08,  0x14,  0x48,  0x12,  0x48,  0x21,  0x48,  0x7E,  0x48,  0x08,  0x48,  0x08,  0x48,  0x7F,  0x48,  0x08, 	/* 506F0 */
+	0x44,  0x4A,  0x84,  0x2C,  0x84,  0x28,  0x84,  0x0F,  0x02,  0x19,  0x02,  0x62,  0x01,  0xA1,  0x04,  0x20, 	/* 50700 */
+	0x04,  0x90,  0x04,  0x88,  0x09,  0x44,  0x12,  0x24,  0x04,  0x10,  0x18,  0x0C,  0x67,  0xF3,  0x00,  0x80, 	/* 50710 */
+	0x00,  0x80,  0x3F,  0xFE,  0x08,  0x88,  0x04,  0x88,  0x04,  0x90,  0x7F,  0xFF,  0x00,  0x00,  0xA3,  0x04, 	/* 50720 */
+	0x20,  0x04,  0x20,  0x0C,  0x20,  0x0A,  0x3E,  0x11,  0x42,  0x3F,  0x42,  0x44,  0x42,  0x04,  0xA2,  0x7F, 	/* 50730 */
+	0x12,  0x04,  0x12,  0x25,  0x12,  0x16,  0x02,  0x14,  0x02,  0x07,  0x02,  0x18,  0x04,  0x60,  0x18,  0xA6, 	/* 50740 */
+	0x04,  0x00,  0x04,  0x00,  0x0A,  0x7E,  0x09,  0x42,  0x10,  0xC2,  0x3F,  0x42,  0x44,  0x42,  0x04,  0x42, 	/* 50750 */
+	0x7F,  0xC2,  0x04,  0x42,  0x25,  0x42,  0x16,  0x42,  0x14,  0xC2,  0x07,  0x7E,  0x1C,  0x00,  0x60,  0x00, 	/* 50760 */
+	0xA7,  0x08,  0x02,  0x08,  0x52,  0x14,  0x52,  0x12,  0x52,  0x21,  0x52,  0x7E,  0x52,  0x08,  0x52,  0x08, 	/* 50770 */
+	0x52,  0x7F,  0x52,  0x08,  0x52,  0x4A,  0x52,  0x2C,  0x52,  0x28,  0x92,  0x0E,  0x82,  0x19,  0x02,  0x62, 	/* 50780 */
+	0x02,  0xB5,  0x08,  0x00,  0x09,  0xFC,  0x14,  0x84,  0x12,  0xA4,  0x21,  0x94,  0x7E,  0x54,  0x08,  0x44, 	/* 50790 */
+	0x08,  0x48,  0x7F,  0x28,  0x08,  0x30,  0x4A,  0x10,  0x2C,  0x28,  0x28,  0x28,  0x0E,  0x44,  0x18,  0x82, 	/* 507A0 */
+	0x63,  0x01,  0xB6,  0x08,  0x10,  0x08,  0x10,  0x14,  0x50,  0x12,  0x52,  0x21,  0x5E,  0x7E,  0x72,  0x09, 	/* 507B0 */
+	0xD2,  0x08,  0x52,  0x7F,  0x52,  0x08,  0x5C,  0x4A,  0x50,  0x2C,  0x51,  0x29,  0x41,  0x0E,  0x41,  0x18, 	/* 507C0 */
+	0x3F,  0x60,  0x00,  0xBC,  0x04,  0x00,  0x04,  0xFE,  0x0A,  0x12,  0x09,  0x12,  0x10,  0x12,  0x3F,  0x52, 	/* 507D0 */
+	0x44,  0x32,  0x04,  0x12,  0x7F,  0x1A,  0x04,  0x16,  0x25,  0x13,  0x16,  0x22,  0x14,  0x22,  0x07,  0x42, 	/* 507E0 */
+	0x18,  0x82,  0x61,  0x0C,  0xBF,  0x04,  0x04,  0x04,  0x18,  0x0A,  0x60,  0x09,  0x40,  0x10,  0xC0,  0x3F, 	/* 507F0 */
+	0x7F,  0x44,  0x44,  0x04,  0x44,  0x3F,  0x44,  0x04,  0x44,  0x25,  0x44,  0x16,  0x44,  0x14,  0x84,  0x06, 	/* 50800 */
+	0x84,  0x19,  0x04,  0x60,  0x04,  0x8D,  0x08,  0x20,  0x08,  0x22,  0x14,  0x2C,  0x13,  0xF0,  0x22,  0x20, 	/* 50810 */
+	0x7E,  0xA4,  0x08,  0xA4,  0x08,  0xA4,  0x7E,  0xA4,  0x08,  0xA4,  0x4A,  0xFC,  0x2C,  0x20,  0x28,  0x20, 	/* 50820 */
+	0x0E,  0x21,  0x18,  0x11,  0x60,  0x0F,  0x8E,  0x08,  0x20,  0x08,  0x20,  0x14,  0x20,  0x12,  0x3E,  0x21, 	/* 50830 */
+	0x42,  0x7E,  0x62,  0x08,  0xA2,  0x09,  0x22,  0x7F,  0x32,  0x08,  0x4A,  0x4A,  0x7A,  0x2C,  0xCA,  0x28, 	/* 50840 */
+	0x02,  0x0B,  0x02,  0x1C,  0x04,  0x60,  0x18,  0x91,  0x08,  0x00,  0x08,  0x7F,  0x14,  0x40,  0x12,  0x40, 	/* 50850 */
+	0x21,  0x40,  0x7E,  0x7E,  0x08,  0x42,  0x08,  0x52,  0x7E,  0x52,  0x08,  0x54,  0x4A,  0x4C,  0x2A,  0x48, 	/* 50860 */
+	0x28,  0x8C,  0x0E,  0x94,  0x19,  0x22,  0x62,  0xC1,  0x94,  0x08,  0x10,  0x08,  0x10,  0x14,  0x10,  0x12, 	/* 50870 */
+	0x54,  0x21,  0x52,  0x7F,  0x52,  0x08,  0x51,  0x08,  0x51,  0x7E,  0x94,  0x09,  0x14,  0x4A,  0x34,  0x2C, 	/* 50880 */
+	0x08,  0x28,  0x08,  0x0E,  0x10,  0x18,  0x60,  0x61,  0x80,  0x95,  0x08,  0x00,  0x08,  0xFC,  0x14,  0x24, 	/* 50890 */
+	0x12,  0x24,  0x21,  0x24,  0x7E,  0x24,  0x08,  0x24,  0x08,  0xFF,  0x7F,  0x24,  0x08,  0x24,  0x4A,  0x24, 	/* 508A0 */
+	0x2C,  0x24,  0x28,  0x24,  0x0E,  0x24,  0x19,  0xFF,  0x60,  0x00,  0x9E,  0x08,  0x40,  0x08,  0x40,  0x14, 	/* 508B0 */
+	0x40,  0x12,  0x7E,  0x21,  0x82,  0x7E,  0x82,  0x09,  0x02,  0x08,  0x7A,  0x7F,  0x02,  0x08,  0x0A,  0x4A, 	/* 508C0 */
+	0x12,  0x2C,  0x62,  0x28,  0x02,  0x0E,  0x02,  0x18,  0x04,  0x60,  0x18,  0xA9,  0x08,  0x00,  0x08,  0xFF, 	/* 508D0 */
+	0x14,  0x00,  0x12,  0x00,  0x21,  0x7E,  0x3E,  0x42,  0x48,  0x42,  0x08,  0x42,  0x7F,  0x7E,  0x08,  0x40, 	/* 508E0 */
+	0x4A,  0x40,  0x2C,  0x40,  0x28,  0x40,  0x0E,  0x80,  0x18,  0x80,  0x61,  0x00,  0xAC,  0x08,  0x00,  0x08, 	/* 508F0 */
+	0x7E,  0x14,  0x42,  0x12,  0x42,  0x21,  0x42,  0x7E,  0x42,  0x08,  0x7E,  0x08,  0x48,  0x7F,  0x48,  0x08, 	/* 50900 */
+	0x48,  0x4A,  0x48,  0x2C,  0x44,  0x28,  0x84,  0x0E,  0x84,  0x19,  0x02,  0x62,  0x01,  0xB4,  0x08,  0x10, 	/* 50910 */
+	0x08,  0x10,  0x14,  0x28,  0x12,  0x44,  0x21,  0x82,  0x7F,  0x7D,  0x08,  0x00,  0x08,  0x00,  0x7F,  0xFC, 	/* 50920 */
+	0x08,  0x24,  0x4A,  0x24,  0x2C,  0x24,  0x28,  0x24,  0x0E,  0x38,  0x18,  0x20,  0x60,  0x20,  0xB7,  0x08, 	/* 50930 */
+	0x10,  0x08,  0x10,  0x14,  0x10,  0x12,  0x10,  0x21,  0xFF,  0x7E,  0x10,  0x08,  0x10,  0x08,  0x10,  0x7F, 	/* 50940 */
+	0x10,  0x08,  0xFC,  0x4A,  0x84,  0x2C,  0x84,  0x28,  0x84,  0x0F,  0x84,  0x18,  0xFC,  0x60,  0x00,  0xBF, 	/* 50950 */
+	0x08,  0x00,  0x08,  0xFE,  0x14,  0x92,  0x12,  0x92,  0x21,  0x92,  0x7E,  0x92,  0x08,  0x92,  0x08,  0xFE, 	/* 50960 */
+	0x7E,  0x92,  0x08,  0x92,  0x4A,  0x92,  0x2C,  0x92,  0x28,  0x92,  0x0E,  0x92,  0x18,  0xFE,  0x60,  0x00, 	/* 50970 */
+	0x84,  0x08,  0x10,  0x08,  0x50,  0x14,  0x50,  0x12,  0x7E,  0x21,  0x90,  0x7E,  0x90,  0x09,  0x10,  0x08, 	/* 50980 */
+	0xFF,  0x7F,  0x10,  0x08,  0x10,  0x4A,  0x18,  0x2C,  0x28,  0x28,  0x24,  0x0E,  0x44,  0x18,  0x82,  0x63, 	/* 50990 */
+	0x01,  0x85,  0x08,  0x00,  0x08,  0xFF,  0x14,  0x40,  0x12,  0x40,  0x21,  0x40,  0x7E,  0x7E,  0x08,  0x42, 	/* 509A0 */
+	0x08,  0x42,  0x7F,  0x42,  0x08,  0x7E,  0x4A,  0x40,  0x2C,  0x40,  0x28,  0x40,  0x0E,  0x40,  0x19,  0xFF, 	/* 509B0 */
+	0x60,  0x00,  0x88,  0x08,  0x10,  0x08,  0x10,  0x14,  0x10,  0x12,  0xFF,  0x21,  0x81,  0x7E,  0x81,  0x08, 	/* 509C0 */
+	0x44,  0x08,  0x44,  0x7F,  0x48,  0x08,  0x50,  0x4A,  0x60,  0x2C,  0x40,  0x28,  0x41,  0x0E,  0x41,  0x18, 	/* 509D0 */
+	0x3F,  0x60,  0x00,  0x89,  0x08,  0x10,  0x08,  0x10,  0x14,  0x10,  0x13,  0xFF,  0x21,  0x10,  0x7E,  0x10, 	/* 509E0 */
+	0x08,  0x24,  0x08,  0xC4,  0x7E,  0x28,  0x08,  0x28,  0x4A,  0x10,  0x2C,  0x14,  0x28,  0x22,  0x0E,  0x4E, 	/* 509F0 */
+	0x19,  0xF1,  0x60,  0x01,  0x8B,  0x08,  0x40,  0x08,  0x40,  0x14,  0x7E,  0x12,  0x82,  0x21,  0x02,  0x7E, 	/* 50A00 */
+	0xF2,  0x08,  0x92,  0x08,  0x92,  0x7F,  0x92,  0x08,  0xF2,  0x4A,  0x9C,  0x2C,  0x80,  0x28,  0x80,  0x0B, 	/* 50A10 */
+	0x82,  0x1C,  0x42,  0x60,  0x3E,  0x90,  0x08,  0x00,  0x09,  0xFF,  0x14,  0x10,  0x12,  0x10,  0x21,  0x10, 	/* 50A20 */
+	0x7E,  0x20,  0x08,  0x20,  0x08,  0x7E,  0x7F,  0x62,  0x08,  0xA2,  0x4A,  0x22,  0x2C,  0x22,  0x28,  0x22, 	/* 50A30 */
+	0x0E,  0x22,  0x18,  0x3E,  0x60,  0x00,  0x97,  0x08,  0x44,  0x08,  0x44,  0x14,  0x44,  0x13,  0xFF,  0x21, 	/* 50A40 */
+	0x44,  0x7E,  0x44,  0x08,  0x44,  0x08,  0x44,  0x7F,  0x44,  0x08,  0x7C,  0x4A,  0x44,  0x2C,  0x44,  0x28, 	/* 50A50 */
+	0x44,  0x0E,  0x44,  0x18,  0x7C,  0x60,  0x00,  0x9A,  0x08,  0x20,  0x08,  0x20,  0x14,  0xCE,  0x12,  0xAA, 	/* 50A60 */
+	0x21,  0xAA,  0x7E,  0xAA,  0x08,  0xAA,  0x08,  0xAA,  0x7E,  0xAA,  0x08,  0xAA,  0x4A,  0xAA,  0x2C,  0xEA, 	/* 50A70 */
+	0x29,  0xAC,  0x0E,  0x48,  0x18,  0x48,  0x60,  0x88,  0x9B,  0x08,  0x3C,  0x08,  0x04,  0x14,  0x24,  0x12, 	/* 50A80 */
+	0x24,  0x22,  0x44,  0x7F,  0x42,  0x08,  0x82,  0x09,  0x01,  0x7E,  0x7C,  0x08,  0x44,  0x4A,  0x44,  0x2C, 	/* 50A90 */
+	0x44,  0x29,  0x44,  0x0E,  0x44,  0x18,  0x7C,  0x60,  0x00,  0x9E,  0x08,  0x10,  0x08,  0x14,  0x14,  0x12, 	/* 50AA0 */
+	0x12,  0x10,  0x21,  0xFF,  0x7E,  0x90,  0x08,  0x92,  0x08,  0x92,  0x7E,  0x92,  0x08,  0x94,  0x4A,  0x8C, 	/* 50AB0 */
+	0x2C,  0x88,  0x28,  0xED,  0x0D,  0x95,  0x1A,  0x23,  0x60,  0x41,  0xA2,  0x08,  0x10,  0x08,  0x10,  0x14, 	/* 50AC0 */
+	0x10,  0x12,  0x10,  0x21,  0xFF,  0x7E,  0x38,  0x08,  0x38,  0x08,  0x54,  0x7F,  0x54,  0x08,  0x92,  0x4A, 	/* 50AD0 */
+	0x91,  0x2D,  0x7C,  0x28,  0x10,  0x0E,  0x10,  0x18,  0x10,  0x60,  0x10,  0xA4,  0x08,  0x40,  0x08,  0x40, 	/* 50AE0 */
+	0x14,  0x40,  0x12,  0x7E,  0x21,  0x82,  0x7E,  0x82,  0x09,  0x7A,  0x08,  0x4A,  0x7F,  0x4A,  0x08,  0x4A, 	/* 50AF0 */
+	0x4A,  0x4A,  0x2C,  0x7A,  0x28,  0x02,  0x0E,  0x02,  0x18,  0x02,  0x60,  0x0C,  0xA6,  0x08,  0x00,  0x08, 	/* 50B00 */
+	0xFE,  0x14,  0x10,  0x12,  0x10,  0x21,  0x10,  0x7E,  0x50,  0x08,  0x50,  0x08,  0x5E,  0x7F,  0x50,  0x08, 	/* 50B10 */
+	0x50,  0x4A,  0x50,  0x2C,  0x50,  0x28,  0x50,  0x0E,  0x50,  0x1B,  0xFF,  0x60,  0x00,  0xB1,  0x08,  0x10, 	/* 50B20 */
+	0x08,  0x10,  0x14,  0x10,  0x12,  0x7F,  0x21,  0x40,  0x7E,  0x48,  0x08,  0x48,  0x08,  0x48,  0x7F,  0x48, 	/* 50B30 */
+	0x08,  0x48,  0x4A,  0x50,  0x2C,  0x54,  0x29,  0x92,  0x0E,  0xAE,  0x19,  0x71,  0x62,  0x01,  0xBE,  0x08, 	/* 50B40 */
+	0x10,  0x08,  0x10,  0x14,  0x28,  0x12,  0x44,  0x21,  0xFE,  0x7E,  0x02,  0x08,  0x50,  0x08,  0x50,  0x7E, 	/* 50B50 */
+	0xFE,  0x09,  0x10,  0x4A,  0x10,  0x2D,  0xFF,  0x28,  0x10,  0x0E,  0x10,  0x18,  0x10,  0x60,  0x10,  0x80, 	/* 50B60 */
+	0x04,  0x00,  0x04,  0x7C,  0x0C,  0x44,  0x0A,  0x44,  0x11,  0x7C,  0x3F,  0xC4,  0x44,  0x44,  0x04,  0x7C, 	/* 50B70 */
+	0x7F,  0x52,  0x04,  0x52,  0x25,  0x54,  0x16,  0x48,  0x14,  0x48,  0x07,  0x54,  0x18,  0x62,  0x61,  0x81, 	/* 50B80 */
+	0x83,  0x08,  0x20,  0x08,  0x20,  0x14,  0x20,  0x13,  0xFF,  0x21,  0x20,  0x7E,  0x50,  0x08,  0x8C,  0x09, 	/* 50B90 */
+	0xFA,  0x7F,  0x50,  0x08,  0x50,  0x4A,  0x50,  0x2C,  0x50,  0x28,  0x92,  0x0E,  0x92,  0x19,  0x12,  0x62, 	/* 50BA0 */
+	0x0E,  0x85,  0x08,  0x00,  0x08,  0xFE,  0x14,  0x82,  0x12,  0x82,  0x20,  0xFE,  0x7E,  0x82,  0x08,  0x82, 	/* 50BB0 */
+	0x08,  0xBA,  0x7F,  0xAA,  0x08,  0xAA,  0x4A,  0xAA,  0x2A,  0xBA,  0x2C,  0x82,  0x0E,  0x82,  0x18,  0x82, 	/* 50BC0 */
+	0x60,  0x86,  0x91,  0x08,  0x10,  0x08,  0x50,  0x14,  0x50,  0x12,  0x7E,  0x21,  0x90,  0x7E,  0x90,  0x09, 	/* 50BD0 */
+	0x10,  0x08,  0xFF,  0x7F,  0x28,  0x08,  0x28,  0x4A,  0x28,  0x2C,  0x48,  0x28,  0x49,  0x0E,  0x89,  0x19, 	/* 50BE0 */
+	0x09,  0x62,  0x07,  0x93,  0x08,  0x10,  0x08,  0x10,  0x14,  0x28,  0x12,  0x44,  0x21,  0x82,  0x7F,  0x01, 	/* 50BF0 */
+	0x08,  0xFE,  0x08,  0x10,  0x7F,  0x10,  0x08,  0x10,  0x4A,  0x7C,  0x2C,  0x10,  0x28,  0x10,  0x0E,  0x10, 	/* 50C00 */
+	0x19,  0xFF,  0x60,  0x00,  0x95,  0x08,  0x10,  0x08,  0x10,  0x15,  0xFF,  0x12,  0x10,  0x21,  0xFE,  0x7E, 	/* 50C10 */
+	0x12,  0x08,  0x12,  0x08,  0xFE,  0x7F,  0x90,  0x08,  0xFF,  0x4A,  0x11,  0x2C,  0x29,  0x28,  0x2E,  0x0E, 	/* 50C20 */
+	0x44,  0x19,  0x82,  0x66,  0x01,  0x96,  0x08,  0x10,  0x08,  0x50,  0x14,  0x50,  0x12,  0x7E,  0x21,  0x50, 	/* 50C30 */
+	0x7E,  0x90,  0x08,  0x10,  0x09,  0xFF,  0x7E,  0x38,  0x08,  0x38,  0x4A,  0x54,  0x2C,  0x54,  0x28,  0x92, 	/* 50C40 */
+	0x0F,  0x11,  0x18,  0x10,  0x60,  0x10,  0x98,  0x08,  0x20,  0x08,  0x20,  0x14,  0x3C,  0x12,  0x44,  0x20, 	/* 50C50 */
+	0x44,  0x7F,  0xC8,  0x09,  0x28,  0x08,  0x10,  0x7E,  0x20,  0x08,  0x7E,  0x4A,  0xC2,  0x2D,  0x42,  0x28, 	/* 50C60 */
+	0x42,  0x0E,  0x42,  0x18,  0x7E,  0x60,  0x00,  0x9A,  0x08,  0x28,  0x08,  0x28,  0x14,  0x2A,  0x12,  0xAA, 	/* 50C70 */
+	0x21,  0x6C,  0x7E,  0x68,  0x08,  0x28,  0x08,  0x28,  0x7F,  0x6C,  0x08,  0xAA,  0x4B,  0x29,  0x2C,  0x28, 	/* 50C80 */
+	0x28,  0x48,  0x0E,  0x49,  0x18,  0x89,  0x63,  0x07,  0x9B,  0x08,  0x02,  0x08,  0x0C,  0x14,  0xF0,  0x12, 	/* 50C90 */
+	0x10,  0x21,  0x10,  0x7E,  0x10,  0x09,  0xFF,  0x08,  0x10,  0x7F,  0x10,  0x08,  0x10,  0x4A,  0x7E,  0x2C, 	/* 50CA0 */
+	0x42,  0x28,  0x42,  0x0E,  0x42,  0x18,  0x7E,  0x60,  0x00,  0x9C,  0x08,  0x80,  0x08,  0x8F,  0x11,  0x40, 	/* 50CB0 */
+	0x11,  0x20,  0x22,  0x10,  0x4B,  0xE0,  0x0C,  0x9F,  0x10,  0x84,  0x17,  0xF4,  0x30,  0x84,  0x54,  0xA4, 	/* 50CC0 */
+	0x12,  0xC4,  0x12,  0xE4,  0x11,  0x84,  0x16,  0x04,  0x10,  0x0C,  0xAD,  0x08,  0x28,  0x08,  0x24,  0x14, 	/* 50CD0 */
+	0x20,  0x12,  0x3E,  0x21,  0xE0,  0x7E,  0x3E,  0x09,  0xE0,  0x08,  0x2F,  0x7E,  0x34,  0x09,  0xE4,  0x4A, 	/* 50CE0 */
+	0x18,  0x2C,  0x10,  0x29,  0x1A,  0x0E,  0x2A,  0x18,  0xC6,  0x63,  0x02,  0xB7,  0x04,  0x10,  0x04,  0x54, 	/* 50CF0 */
+	0x0A,  0x52,  0x09,  0x52,  0x10,  0x91,  0x3F,  0x7F,  0x44,  0x42,  0x04,  0x42,  0x3F,  0x7E,  0x04,  0x42, 	/* 50D00 */
+	0x25,  0x42,  0x16,  0x7E,  0x14,  0x42,  0x07,  0x42,  0x1C,  0x42,  0x60,  0x46,  0xB9,  0x08,  0x04,  0x08, 	/* 50D10 */
+	0x18,  0x14,  0xF0,  0x12,  0x10,  0x21,  0xFF,  0x7E,  0x38,  0x08,  0x54,  0x09,  0x93,  0x7E,  0x10,  0x08, 	/* 50D20 */
+	0xF8,  0x4A,  0x28,  0x2C,  0x2E,  0x28,  0x22,  0x0E,  0x42,  0x18,  0x82,  0x61,  0x0C,  0x8F,  0x08,  0x10, 	/* 50D30 */
+	0x08,  0x10,  0x15,  0xFF,  0x12,  0x10,  0x21,  0x54,  0x7E,  0x54,  0x08,  0x54,  0x08,  0xB6,  0x7E,  0x99, 	/* 50D40 */
+	0x09,  0x10,  0x4A,  0x28,  0x2C,  0x28,  0x28,  0x24,  0x0E,  0x44,  0x18,  0x82,  0x61,  0x01,  0x92,  0x08, 	/* 50D50 */
+	0x20,  0x08,  0x3C,  0x14,  0x24,  0x12,  0x48,  0x21,  0xB0,  0x7E,  0x18,  0x08,  0x64,  0x09,  0x93,  0x7E, 	/* 50D60 */
+	0xFE,  0x08,  0x10,  0x4A,  0x7C,  0x2C,  0x10,  0x29,  0xFF,  0x0E,  0x10,  0x18,  0x10,  0x60,  0x10,  0xA4, 	/* 50D70 */
+	0x08,  0x08,  0x09,  0xC8,  0x15,  0x48,  0x13,  0x48,  0x21,  0x7E,  0x7F,  0xCA,  0x09,  0x4A,  0x09,  0x4A, 	/* 50D80 */
+	0x7F,  0x4A,  0x09,  0xCA,  0x4B,  0x4A,  0x2D,  0x4A,  0x29,  0xF2,  0x0F,  0x12,  0x18,  0x22,  0x60,  0x4C, 	/* 50D90 */
+	0xA9,  0x08,  0x44,  0x08,  0x44,  0x15,  0xFF,  0x12,  0x44,  0x21,  0x44,  0x7E,  0x10,  0x08,  0x10,  0x09, 	/* 50DA0 */
+	0xFF,  0x7F,  0x40,  0x08,  0x40,  0x4A,  0x40,  0x2C,  0x40,  0x28,  0x40,  0x0E,  0x40,  0x18,  0x3E,  0x60, 	/* 50DB0 */
+	0x00,  0xAA,  0x08,  0x14,  0x08,  0x12,  0x15,  0xFF,  0x12,  0x10,  0x21,  0x10,  0x7E,  0xFE,  0x08,  0x92, 	/* 50DC0 */
+	0x08,  0x92,  0x7F,  0xFE,  0x08,  0x92,  0x4A,  0x92,  0x2C,  0xFE,  0x28,  0x92,  0x0F,  0x92,  0x18,  0x92, 	/* 50DD0 */
+	0x60,  0x96,  0xAD,  0x08,  0x44,  0x08,  0x24,  0x14,  0x28,  0x12,  0x7E,  0x21,  0x42,  0x7E,  0x42,  0x08, 	/* 50DE0 */
+	0x42,  0x08,  0x42,  0x7F,  0x7E,  0x08,  0x28,  0x4A,  0x28,  0x2A,  0x28,  0x2C,  0x48,  0x0B,  0x49,  0x1C, 	/* 50DF0 */
+	0x89,  0x61,  0x07,  0xB2,  0x08,  0x08,  0x08,  0x10,  0x14,  0x60,  0x12,  0x40,  0x21,  0x40,  0x7E,  0x7E, 	/* 50E00 */
+	0x08,  0x44,  0x08,  0x44,  0x7F,  0x44,  0x08,  0x44,  0x4B,  0xFF,  0x2C,  0x00,  0x28,  0x48,  0x0E,  0x44, 	/* 50E10 */
+	0x18,  0x82,  0x61,  0x02,  0xB3,  0x08,  0x20,  0x08,  0x20,  0x14,  0xFE,  0x12,  0x20,  0x20,  0xFC,  0x7E, 	/* 50E20 */
+	0x20,  0x09,  0xFF,  0x08,  0x24,  0x7E,  0x24,  0x09,  0xFF,  0x4A,  0x44,  0x2C,  0x44,  0x28,  0xA4,  0x0F, 	/* 50E30 */
+	0x24,  0x1A,  0x04,  0x60,  0x0C,  0xB8,  0x08,  0x00,  0x08,  0xFE,  0x14,  0x82,  0x12,  0x82,  0x20,  0xFE, 	/* 50E40 */
+	0x7E,  0x88,  0x08,  0x88,  0x08,  0xFF,  0x7F,  0x88,  0x08,  0x88,  0x4A,  0xBE,  0x2C,  0xA2,  0x28,  0xA2, 	/* 50E50 */
+	0x0F,  0x22,  0x19,  0x3E,  0x62,  0x00,  0xBA,  0x08,  0x10,  0x08,  0x10,  0x15,  0xFF,  0x13,  0x01,  0x21, 	/* 50E60 */
+	0x01,  0x7E,  0x80,  0x08,  0xEE,  0x08,  0xAA,  0x7E,  0xAA,  0x09,  0x2A,  0x4A,  0xAE,  0x2C,  0x48,  0x28, 	/* 50E70 */
+	0x48,  0x0E,  0x49,  0x18,  0x89,  0x61,  0x07,  0xBC,  0x08,  0x00,  0x08,  0xFE,  0x14,  0x82,  0x12,  0xCA, 	/* 50E80 */
+	0x21,  0xAA,  0x7E,  0x92,  0x08,  0xFE,  0x08,  0x92,  0x7F,  0x92,  0x08,  0xD6,  0x4A,  0xD6,  0x2C,  0xFE, 	/* 50E90 */
+	0x29,  0x82,  0x0E,  0x82,  0x18,  0x82,  0x60,  0x86,  0x86,  0x08,  0x20,  0x08,  0x20,  0x17,  0xFE,  0x12, 	/* 50EA0 */
+	0x20,  0x22,  0xFC,  0x7E,  0x20,  0x09,  0xFF,  0x08,  0x00,  0x7F,  0xFC,  0x08,  0x84,  0x4A,  0xFC,  0x2A, 	/* 50EB0 */
+	0x84,  0x2C,  0xFC,  0x0E,  0x84,  0x18,  0x84,  0x60,  0x8C,  0x8F,  0x08,  0x00,  0x0D,  0xFE,  0x16,  0x28, 	/* 50EC0 */
+	0x12,  0x28,  0x20,  0x28,  0x7E,  0xEE,  0x08,  0x82,  0x08,  0x82,  0x7E,  0x82,  0x08,  0xEE,  0x4A,  0x28, 	/* 50ED0 */
+	0x2C,  0x28,  0x28,  0x28,  0x0E,  0x28,  0x1B,  0xFF,  0x60,  0x00,  0x90,  0x08,  0x24,  0x08,  0x24,  0x14, 	/* 50EE0 */
+	0x48,  0x12,  0xFF,  0x21,  0x48,  0x7E,  0x48,  0x08,  0x48,  0x08,  0x7E,  0x7F,  0x48,  0x08,  0x48,  0x4A, 	/* 50EF0 */
+	0x7E,  0x2C,  0x48,  0x28,  0x48,  0x0E,  0x48,  0x18,  0x7F,  0x60,  0x00,  0x98,  0x08,  0x04,  0x08,  0x18, 	/* 50F00 */
+	0x14,  0xF0,  0x12,  0x10,  0x21,  0xFE,  0x7E,  0x54,  0x08,  0x54,  0x09,  0xFF,  0x7E,  0x54,  0x08,  0x54, 	/* 50F10 */
+	0x4A,  0x54,  0x2C,  0xFE,  0x28,  0x10,  0x0E,  0x10,  0x19,  0xFF,  0x60,  0x00,  0x99,  0x08,  0x49,  0x08, 	/* 50F20 */
+	0x49,  0x14,  0x92,  0x13,  0xB6,  0x23,  0x49,  0x7E,  0x49,  0x08,  0x00,  0x08,  0xFE,  0x7E,  0x92,  0x08, 	/* 50F30 */
+	0x92,  0x4A,  0xFE,  0x2C,  0x92,  0x28,  0x92,  0x0E,  0x92,  0x18,  0xFE,  0x60,  0x00,  0x9A,  0x08,  0x04, 	/* 50F40 */
+	0x08,  0x18,  0x14,  0xE4,  0x12,  0x52,  0x20,  0x89,  0x7F,  0x7E,  0x08,  0x12,  0x08,  0x12,  0x7F,  0xFF, 	/* 50F50 */
+	0x08,  0x12,  0x4A,  0x12,  0x2C,  0xFE,  0x28,  0x10,  0x0E,  0x10,  0x18,  0x10,  0x60,  0x30,  0xA0,  0x08, 	/* 50F60 */
+	0x10,  0x08,  0x10,  0x15,  0xFF,  0x13,  0x01,  0x21,  0x01,  0x7E,  0xFE,  0x08,  0x10,  0x08,  0x10,  0x7F, 	/* 50F70 */
+	0x90,  0x08,  0x9E,  0x4A,  0x90,  0x2C,  0x90,  0x28,  0xD0,  0x0E,  0xB0,  0x19,  0x18,  0x62,  0x07,  0xA2, 	/* 50F80 */
+	0x08,  0x28,  0x08,  0x24,  0x14,  0x2E,  0x13,  0xF2,  0x20,  0x14,  0x7E,  0x18,  0x08,  0x65,  0x09,  0xAB, 	/* 50F90 */
+	0x7E,  0x24,  0x08,  0x2F,  0x4B,  0xF2,  0x2C,  0x14,  0x28,  0x18,  0x0E,  0x65,  0x19,  0x83,  0x60,  0x01, 	/* 50FA0 */
+	0xA3,  0x08,  0x00,  0x09,  0xFE,  0x14,  0x22,  0x12,  0xAA,  0x20,  0x44,  0x7E,  0xAA,  0x09,  0x10,  0x08, 	/* 50FB0 */
+	0x00,  0x7F,  0xFE,  0x08,  0x22,  0x4A,  0xAA,  0x2C,  0xCC,  0x28,  0x44,  0x0E,  0xAC,  0x19,  0x12,  0x62, 	/* 50FC0 */
+	0x21,  0xA6,  0x04,  0x10,  0x04,  0x20,  0x0C,  0x7C,  0x0A,  0x44,  0x11,  0x7C,  0x3F,  0x44,  0x44,  0x44, 	/* 50FD0 */
+	0x04,  0x7C,  0x7F,  0x10,  0x04,  0xFE,  0x25,  0x92,  0x16,  0x92,  0x14,  0x92,  0x07,  0x9C,  0x18,  0x90, 	/* 50FE0 */
+	0x60,  0x10,  0xA8,  0x08,  0x44,  0x08,  0x44,  0x15,  0xFF,  0x12,  0x44,  0x21,  0x44,  0x7E,  0x00,  0x08, 	/* 50FF0 */
+	0x00,  0x08,  0xFE,  0x7F,  0x92,  0x08,  0x92,  0x4A,  0xFE,  0x2C,  0x92,  0x28,  0x92,  0x0E,  0x92,  0x18, 	/* 51000 */
+	0xFE,  0x60,  0x00,  0xAB,  0x08,  0x00,  0x08,  0xFC,  0x14,  0x84,  0x12,  0x84,  0x21,  0xFC,  0x7E,  0x84, 	/* 51010 */
+	0x08,  0x84,  0x08,  0xFC,  0x7F,  0x20,  0x08,  0x7E,  0x4A,  0xAA,  0x2D,  0x2A,  0x28,  0x4A,  0x0E,  0x92, 	/* 51020 */
+	0x18,  0x22,  0x60,  0x4C,  0xAC,  0x08,  0x10,  0x08,  0x10,  0x15,  0xFF,  0x12,  0x10,  0x20,  0xFE,  0x7E, 	/* 51030 */
+	0x92,  0x08,  0xFE,  0x08,  0x92,  0x7F,  0x92,  0x08,  0xFE,  0x4A,  0x38,  0x2C,  0x34,  0x28,  0x52,  0x0E, 	/* 51040 */
+	0x91,  0x19,  0x10,  0x60,  0x10,  0xAE,  0x08,  0x00,  0x08,  0xFE,  0x14,  0x92,  0x12,  0x92,  0x21,  0x92, 	/* 51050 */
+	0x7E,  0xFE,  0x08,  0x92,  0x08,  0x92,  0x7F,  0xBA,  0x08,  0xAA,  0x4A,  0xAA,  0x2C,  0xBA,  0x28,  0x82, 	/* 51060 */
+	0x0E,  0x82,  0x18,  0xFE,  0x60,  0x00,  0xAF,  0x08,  0x28,  0x08,  0x28,  0x14,  0x28,  0x12,  0xFE,  0x21, 	/* 51070 */
+	0x28,  0x7E,  0x28,  0x09,  0xFF,  0x08,  0x00,  0x7F,  0x7C,  0x08,  0x44,  0x4A,  0x44,  0x2C,  0x7C,  0x29, 	/* 51080 */
+	0x44,  0x0E,  0x44,  0x18,  0x7C,  0x60,  0x00,  0xB2,  0x04,  0x00,  0x04,  0xFC,  0x0C,  0x04,  0x0A,  0xFC, 	/* 51090 */
+	0x11,  0x04,  0x3F,  0x04,  0x44,  0xFF,  0x04,  0x12,  0x7F,  0x92,  0x04,  0x5C,  0x25,  0x38,  0x16,  0x34, 	/* 510A0 */
+	0x14,  0xD2,  0x07,  0x11,  0x18,  0x10,  0x60,  0x30,  0xB5,  0x08,  0x44,  0x08,  0x44,  0x15,  0xFF,  0x12, 	/* 510B0 */
+	0x44,  0x21,  0x44,  0x7E,  0x28,  0x08,  0x28,  0x08,  0x4A,  0x7E,  0x4A,  0x08,  0xCC,  0x4B,  0x48,  0x2C, 	/* 510C0 */
+	0x48,  0x28,  0x48,  0x0E,  0x49,  0x18,  0x49,  0x60,  0x47,  0xBA,  0x08,  0x44,  0x08,  0x44,  0x17,  0xFF, 	/* 510D0 */
+	0x12,  0x44,  0x21,  0x54,  0x7E,  0x10,  0x09,  0xFF,  0x08,  0x20,  0x7F,  0x20,  0x08,  0x3C,  0x4A,  0x24, 	/* 510E0 */
+	0x2C,  0x24,  0x28,  0x44,  0x0E,  0x44,  0x18,  0x84,  0x61,  0x18,  0xBB,  0x08,  0x08,  0x08,  0x0C,  0x14, 	/* 510F0 */
+	0xEA,  0x12,  0x08,  0x21,  0xFF,  0x7E,  0x08,  0x08,  0x28,  0x08,  0xA8,  0x7E,  0xB8,  0x08,  0xA8,  0x4A, 	/* 51100 */
+	0xA8,  0x2C,  0xA4,  0x28,  0xBD,  0x0E,  0xE5,  0x19,  0x83,  0x60,  0x01,  0x84,  0x08,  0x10,  0x08,  0x10, 	/* 51110 */
+	0x14,  0x10,  0x12,  0xFF,  0x21,  0x00,  0x7E,  0x7C,  0x08,  0x44,  0x08,  0x44,  0x7F,  0x44,  0x08,  0x7C, 	/* 51120 */
+	0x4A,  0x10,  0x2C,  0x58,  0x28,  0x54,  0x0E,  0x92,  0x19,  0x12,  0x60,  0x30,  0x8B,  0x08,  0x00,  0x08, 	/* 51130 */
+	0xFC,  0x14,  0x84,  0x12,  0xBC,  0x22,  0xA4,  0x7E,  0xA4,  0x08,  0xA4,  0x09,  0xFE,  0x7F,  0x02,  0x09, 	/* 51140 */
+	0x7A,  0x4B,  0x4A,  0x2D,  0x4A,  0x29,  0x7A,  0x0F,  0x02,  0x19,  0x02,  0x61,  0x06,  0x8D,  0x08,  0x10, 	/* 51150 */
+	0x08,  0x10,  0x14,  0xFF,  0x12,  0xA4,  0x20,  0xA4,  0x7E,  0xFF,  0x08,  0xA4,  0x08,  0xBC,  0x7F,  0x80, 	/* 51160 */
+	0x08,  0xFE,  0x4A,  0xA4,  0x2C,  0x94,  0x28,  0x88,  0x0F,  0x14,  0x19,  0x22,  0x62,  0xC1,  0x94,  0x08, 	/* 51170 */
+	0x00,  0x08,  0xEE,  0x14,  0xAA,  0x12,  0xAA,  0x21,  0xEE,  0x7E,  0x00,  0x08,  0xFE,  0x08,  0x00,  0x7F, 	/* 51180 */
+	0xFF,  0x08,  0x20,  0x4A,  0x20,  0x2C,  0x7C,  0x28,  0x44,  0x0E,  0x04,  0x18,  0x04,  0x60,  0x18,  0x96, 	/* 51190 */
+	0x08,  0x44,  0x08,  0x44,  0x15,  0xFF,  0x12,  0x44,  0x21,  0x7C,  0x7E,  0x44,  0x08,  0x7C,  0x08,  0x44, 	/* 511A0 */
+	0x7E,  0x44,  0x09,  0xFF,  0x4A,  0xA8,  0x2C,  0xAA,  0x28,  0xC6,  0x0E,  0x80,  0x18,  0xFF,  0x60,  0x00, 	/* 511B0 */
+	0x9B,  0x08,  0x40,  0x09,  0xBC,  0x15,  0x24,  0x13,  0x24,  0x21,  0xE5,  0x7F,  0x23,  0x09,  0x40,  0x09, 	/* 511C0 */
+	0xC0,  0x7F,  0x3E,  0x09,  0x02,  0x4B,  0x14,  0x2D,  0xD4,  0x29,  0x08,  0x0F,  0x14,  0x19,  0x22,  0x61, 	/* 511D0 */
+	0x41,  0x9C,  0x08,  0x00,  0x09,  0xEE,  0x15,  0x22,  0x13,  0x22,  0x21,  0x22,  0x7F,  0xEE,  0x09,  0x00, 	/* 511E0 */
+	0x09,  0x1E,  0x7F,  0xEA,  0x09,  0x0A,  0x4B,  0x0A,  0x2D,  0xE4,  0x29,  0x04,  0x0F,  0x0A,  0x19,  0x12, 	/* 511F0 */
+	0x61,  0x21,  0xA0,  0x08,  0x10,  0x08,  0x20,  0x14,  0x7C,  0x12,  0x44,  0x21,  0x7C,  0x7E,  0x44,  0x08, 	/* 51200 */
+	0x44,  0x08,  0x7C,  0x7E,  0x00,  0x08,  0xFE,  0x4A,  0x10,  0x2C,  0xFE,  0x28,  0x10,  0x0E,  0x10,  0x19, 	/* 51210 */
+	0xFF,  0x60,  0x00,  0xAC,  0x08,  0x28,  0x08,  0x48,  0x15,  0xC8,  0x12,  0x4A,  0x21,  0x5A,  0x7E,  0x5A, 	/* 51220 */
+	0x09,  0xEA,  0x08,  0x4C,  0x7F,  0x68,  0x08,  0xD8,  0x4A,  0xCC,  0x2D,  0x54,  0x28,  0x54,  0x0E,  0x52, 	/* 51230 */
+	0x18,  0x62,  0x60,  0x41,  0xAE,  0x08,  0x70,  0x08,  0x10,  0x14,  0x28,  0x12,  0x44,  0x20,  0xFA,  0x7F, 	/* 51240 */
+	0x01,  0x09,  0xEA,  0x09,  0x2A,  0x7F,  0xAA,  0x09,  0x74,  0x49,  0x34,  0x2D,  0xB4,  0x29,  0x6A,  0x0D, 	/* 51250 */
+	0x2A,  0x19,  0x2A,  0x61,  0x6A,  0xB5,  0x10,  0x10,  0x10,  0x10,  0x1B,  0xFC,  0x28,  0x94,  0x25,  0xFF, 	/* 51260 */
+	0x79,  0x14,  0x12,  0x14,  0x13,  0xFC,  0x7C,  0x90,  0x12,  0xFC,  0x56,  0x90,  0x39,  0x7E,  0x31,  0x90, 	/* 51270 */
+	0x15,  0x50,  0x1A,  0x30,  0x64,  0x0F,  0xBC,  0x08,  0x08,  0x08,  0x0A,  0x14,  0x09,  0x13,  0xFF,  0x21, 	/* 51280 */
+	0x08,  0x7F,  0x0A,  0x09,  0xFA,  0x09,  0x0A,  0x7F,  0x7A,  0x09,  0x5C,  0x4B,  0x54,  0x2D,  0x75,  0x29, 	/* 51290 */
+	0x0D,  0x0E,  0x13,  0x1A,  0x23,  0x64,  0x41,  0xBE,  0x08,  0x04,  0x08,  0x18,  0x14,  0xF0,  0x12,  0x10, 	/* 512A0 */
+	0x21,  0xFF,  0x7E,  0x10,  0x08,  0xFE,  0x08,  0x92,  0x7F,  0xFE,  0x08,  0x92,  0x4A,  0xFE,  0x2C,  0x10, 	/* 512B0 */
+	0x28,  0xFE,  0x0E,  0x10,  0x1B,  0xFF,  0x60,  0x00,  0x8C,  0x08,  0x88,  0x08,  0x50,  0x17,  0xFF,  0x12, 	/* 512C0 */
+	0x50,  0x21,  0xFC,  0x7E,  0x54,  0x08,  0x54,  0x09,  0xFF,  0x7E,  0x54,  0x09,  0xFC,  0x48,  0x58,  0x2C, 	/* 512D0 */
+	0xD4,  0x28,  0xD2,  0x0F,  0x51,  0x1A,  0x50,  0x60,  0x50,  0x94,  0x08,  0x10,  0x08,  0x10,  0x15,  0xFF, 	/* 512E0 */
+	0x13,  0x01,  0x21,  0x49,  0x7E,  0x44,  0x08,  0x52,  0x08,  0x92,  0x7E,  0x28,  0x08,  0x44,  0x4A,  0xFE, 	/* 512F0 */
+	0x2D,  0x45,  0x28,  0x44,  0x0E,  0x44,  0x18,  0x7C,  0x60,  0x00,  0x96,  0x08,  0x10,  0x08,  0x92,  0x14, 	/* 51300 */
+	0x52,  0x12,  0x54,  0x21,  0x7E,  0x7E,  0x42,  0x08,  0x42,  0x08,  0x7E,  0x7F,  0x42,  0x08,  0x7E,  0x4A, 	/* 51310 */
+	0x42,  0x2C,  0x42,  0x28,  0x7E,  0x0F,  0x14,  0x18,  0x62,  0x61,  0x81,  0x97,  0x08,  0x10,  0x08,  0x10, 	/* 51320 */
+	0x14,  0x28,  0x12,  0x44,  0x21,  0xFE,  0x7F,  0x01,  0x08,  0x7C,  0x08,  0x44,  0x7F,  0x7C,  0x08,  0x44, 	/* 51330 */
+	0x4A,  0x7C,  0x2C,  0x80,  0x28,  0xFE,  0x0F,  0x42,  0x1A,  0x7E,  0x60,  0x00,  0x9A,  0x08,  0x08,  0x09, 	/* 51340 */
+	0x10,  0x14,  0xBE,  0x12,  0xA2,  0x20,  0x22,  0x7E,  0x3E,  0x08,  0x20,  0x0B,  0xA0,  0x7E,  0xBE,  0x08, 	/* 51350 */
+	0xA2,  0x4A,  0xA2,  0x2C,  0xA2,  0x28,  0xFE,  0x0F,  0x20,  0x19,  0x18,  0x62,  0x07,  0xA7,  0x08,  0x10, 	/* 51360 */
+	0x08,  0x92,  0x14,  0x92,  0x12,  0xFE,  0x21,  0x00,  0x7E,  0xFF,  0x08,  0x00,  0x08,  0x7C,  0x7F,  0x44, 	/* 51370 */
+	0x08,  0x44,  0x4A,  0x7C,  0x2C,  0x44,  0x28,  0x24,  0x0E,  0x28,  0x19,  0xFF,  0x60,  0x00,  0xAC,  0x08, 	/* 51380 */
+	0x10,  0x08,  0x10,  0x15,  0xFF,  0x12,  0x00,  0x21,  0x7C,  0x7E,  0x44,  0x08,  0x7C,  0x08,  0x00,  0x7F, 	/* 51390 */
+	0xFE,  0x08,  0x82,  0x4A,  0xBA,  0x2C,  0xAA,  0x28,  0xAA,  0x0E,  0xBA,  0x18,  0x82,  0x60,  0x86,  0xAD, 	/* 513A0 */
+	0x08,  0x42,  0x08,  0x7C,  0x14,  0x41,  0x12,  0x3F,  0x21,  0x00,  0x7E,  0xBE,  0x08,  0xA2,  0x08,  0xBE, 	/* 513B0 */
+	0x7F,  0xA2,  0x08,  0xBE,  0x4A,  0xA2,  0x2C,  0xBE,  0x28,  0x80,  0x0E,  0xFF,  0x18,  0x66,  0x63,  0x81, 	/* 513C0 */
+	0xAE,  0x08,  0x10,  0x08,  0x10,  0x15,  0xFF,  0x12,  0x10,  0x21,  0x7C,  0x7E,  0x44,  0x08,  0x7C,  0x08, 	/* 513D0 */
+	0x44,  0x7F,  0xFC,  0x08,  0x44,  0x4A,  0x7C,  0x2C,  0x00,  0x29,  0xFF,  0x0E,  0x24,  0x18,  0xC2,  0x63, 	/* 513E0 */
+	0x01,  0xB0,  0x08,  0x78,  0x08,  0x08,  0x14,  0x48,  0x12,  0x74,  0x20,  0x84,  0x7E,  0xBA,  0x09,  0x09, 	/* 513F0 */
+	0x08,  0x44,  0x7E,  0x84,  0x08,  0xFE,  0x4B,  0x55,  0x2C,  0x54,  0x28,  0x54,  0x0E,  0x54,  0x19,  0xFF, 	/* 51400 */
+	0x60,  0x00,  0xB9,  0x08,  0x1C,  0x09,  0x04,  0x14,  0x92,  0x12,  0xA1,  0x20,  0x7E,  0x7F,  0x08,  0x08, 	/* 51410 */
+	0x88,  0x08,  0xBF,  0x7E,  0x08,  0x09,  0xD4,  0x4A,  0x54,  0x2C,  0x62,  0x28,  0x41,  0x0E,  0xA0,  0x19, 	/* 51420 */
+	0x18,  0x62,  0x07,  0x83,  0x08,  0x48,  0x08,  0x48,  0x14,  0x48,  0x13,  0xFF,  0x20,  0x90,  0x7E,  0xA8, 	/* 51430 */
+	0x08,  0xEF,  0x08,  0xB4,  0x7E,  0xA4,  0x08,  0xA4,  0x4A,  0xBF,  0x2C,  0xA4,  0x29,  0x2A,  0x0D,  0x2A, 	/* 51440 */
+	0x1A,  0x32,  0x60,  0xC1,  0x88,  0x09,  0x08,  0x08,  0x88,  0x14,  0xFF,  0x12,  0x08,  0x21,  0x3E,  0x7E, 	/* 51450 */
+	0xAA,  0x08,  0xAA,  0x08,  0x3E,  0x7E,  0x2A,  0x09,  0xAA,  0x4A,  0xBE,  0x2C,  0x88,  0x28,  0xBF,  0x0E, 	/* 51460 */
+	0xC8,  0x19,  0x28,  0x62,  0x1F,  0x90,  0x08,  0x00,  0x09,  0xFE,  0x14,  0xAA,  0x13,  0x32,  0x20,  0x66, 	/* 51470 */
+	0x7E,  0xAA,  0x08,  0x76,  0x08,  0x10,  0x7F,  0x28,  0x08,  0x4C,  0x49,  0x93,  0x2C,  0x64,  0x28,  0x1A, 	/* 51480 */
+	0x0E,  0x64,  0x18,  0x18,  0x60,  0xE0,  0x91,  0x08,  0x10,  0x08,  0x10,  0x14,  0xFF,  0x12,  0x44,  0x21, 	/* 51490 */
+	0x28,  0x7E,  0xFE,  0x08,  0x82,  0x08,  0x92,  0x7F,  0xFE,  0x08,  0x92,  0x4A,  0xBA,  0x2C,  0xAA,  0x28, 	/* 514A0 */
+	0xAA,  0x0E,  0xBA,  0x18,  0x82,  0x60,  0x86,  0x96,  0x01,  0x00,  0x1F,  0xFE,  0x12,  0x40,  0x1F,  0xFC, 	/* 514B0 */
+	0x12,  0x44,  0x1F,  0xFC,  0x14,  0x24,  0x27,  0xB8,  0x44,  0x22,  0x1E,  0x9E,  0x03,  0x60,  0x0C,  0x98, 	/* 514C0 */
+	0x77,  0xF7,  0x02,  0xA0,  0x7F,  0xFF,  0x00,  0x00,  0x97,  0x08,  0x00,  0x09,  0xFE,  0x15,  0x4A,  0x13, 	/* 514D0 */
+	0x4A,  0x21,  0xEA,  0x7F,  0x24,  0x09,  0xE4,  0x09,  0x4A,  0x7F,  0x51,  0x09,  0xE0,  0x4A,  0x10,  0x2C, 	/* 514E0 */
+	0xFE,  0x28,  0x10,  0x0E,  0x10,  0x19,  0xFF,  0x60,  0x00,  0x98,  0x08,  0x48,  0x09,  0x4E,  0x15,  0x52, 	/* 514F0 */
+	0x15,  0x5A,  0x23,  0x64,  0x7F,  0xD4,  0x08,  0x48,  0x08,  0x52,  0x7E,  0x62,  0x0B,  0xFF,  0x49,  0x42, 	/* 51500 */
+	0x2D,  0x52,  0x29,  0x4A,  0x0D,  0x4A,  0x1A,  0x42,  0x60,  0x46,  0x9D,  0x08,  0x00,  0x08,  0x7C,  0x14, 	/* 51510 */
+	0x44,  0x12,  0x7C,  0x21,  0x44,  0x7E,  0x7C,  0x08,  0x00,  0x09,  0xFF,  0x7F,  0x29,  0x09,  0xFF,  0x4A, 	/* 51520 */
+	0x00,  0x2C,  0xFC,  0x28,  0x48,  0x0E,  0x30,  0x18,  0xCC,  0x63,  0x03,  0xA1,  0x08,  0x10,  0x08,  0x10, 	/* 51530 */
+	0x15,  0xFE,  0x12,  0x84,  0x20,  0x48,  0x7F,  0xFF,  0x08,  0x00,  0x08,  0xFC,  0x7F,  0x84,  0x08,  0xFC, 	/* 51540 */
+	0x4A,  0x84,  0x2C,  0xFC,  0x28,  0x28,  0x0E,  0x49,  0x18,  0x89,  0x63,  0x07,  0xA4,  0x08,  0x10,  0x08, 	/* 51550 */
+	0xFE,  0x14,  0x92,  0x12,  0xFF,  0x21,  0x92,  0x7E,  0xFE,  0x08,  0x10,  0x08,  0xFE,  0x7E,  0x92,  0x08, 	/* 51560 */
+	0xFE,  0x4A,  0x20,  0x2D,  0xFF,  0x28,  0x48,  0x0E,  0xE8,  0x18,  0x38,  0x61,  0xC6,  0xA5,  0x08,  0x20, 	/* 51570 */
+	0x08,  0x20,  0x15,  0xFE,  0x13,  0x02,  0x21,  0x42,  0x7E,  0x7F,  0x08,  0x48,  0x08,  0x90,  0x7F,  0xBE, 	/* 51580 */
+	0x08,  0xA2,  0x4A,  0xA2,  0x2C,  0xBE,  0x28,  0xA2,  0x0E,  0xA2,  0x18,  0xBE,  0x60,  0x80,  0xA8,  0x08, 	/* 51590 */
+	0x06,  0x7F,  0xB8,  0x08,  0x20,  0x3F,  0x3F,  0x29,  0x24,  0x3F,  0x24,  0x29,  0x44,  0x7F,  0x84,  0x08, 	/* 515A0 */
+	0x84,  0x0B,  0x64,  0x0F,  0xF8,  0x70,  0x87,  0x0F,  0xF8,  0x04,  0x90,  0x7F,  0xFF,  0x00,  0x00,  0x83, 	/* 515B0 */
+	0x08,  0x10,  0x08,  0x7C,  0x14,  0x10,  0x12,  0xFE,  0x21,  0x00,  0x7E,  0x44,  0x09,  0xFF,  0x08,  0x44, 	/* 515C0 */
+	0x7E,  0x64,  0x09,  0x9F,  0x4A,  0x00,  0x2D,  0xFF,  0x28,  0x48,  0x0E,  0x49,  0x18,  0x89,  0x63,  0x07, 	/* 515D0 */
+	0x87,  0x08,  0x06,  0x08,  0xF8,  0x14,  0x92,  0x12,  0x54,  0x21,  0xFF,  0x7E,  0x38,  0x08,  0x54,  0x08, 	/* 515E0 */
+	0x92,  0x7F,  0xFF,  0x08,  0x92,  0x4A,  0x92,  0x2C,  0xFE,  0x28,  0x92,  0x0E,  0x92,  0x18,  0xFE,  0x60, 	/* 515F0 */
+	0x00,  0x90,  0x08,  0x10,  0x08,  0x10,  0x15,  0xFF,  0x12,  0x28,  0x20,  0xAA,  0x7E,  0x44,  0x08,  0xFE, 	/* 51600 */
+	0x09,  0x45,  0x7E,  0x7C,  0x08,  0x44,  0x4A,  0x7C,  0x2C,  0x10,  0x28,  0x54,  0x0E,  0x92,  0x19,  0x11, 	/* 51610 */
+	0x60,  0x30,  0x93,  0x08,  0x88,  0x08,  0x88,  0x1B,  0xE8,  0x14,  0x0F,  0x23,  0xD4,  0x7D,  0x54,  0x09, 	/* 51620 */
+	0xE4,  0x08,  0x04,  0x7F,  0xD4,  0x08,  0x54,  0x4C,  0x94,  0x28,  0xE8,  0x2B,  0x8C,  0x0C,  0x94,  0x30, 	/* 51630 */
+	0xA2,  0x41,  0xC1,  0x94,  0x08,  0x00,  0x0B,  0xFF,  0x14,  0x48,  0x13,  0xFE,  0x21,  0x4A,  0x7F,  0xFE, 	/* 51640 */
+	0x08,  0x00,  0x08,  0xFC,  0x7E,  0x84,  0x08,  0xFC,  0x4A,  0x84,  0x2C,  0xFC,  0x28,  0x20,  0x0F,  0xFF, 	/* 51650 */
+	0x18,  0x20,  0x60,  0x20,  0x98,  0x08,  0x10,  0x08,  0x10,  0x15,  0xFF,  0x12,  0x44,  0x21,  0xFF,  0x7F, 	/* 51660 */
+	0x00,  0x08,  0xFE,  0x08,  0x92,  0x7E,  0xFE,  0x08,  0x92,  0x4A,  0xFE,  0x2C,  0x10,  0x28,  0xFE,  0x0E, 	/* 51670 */
+	0x10,  0x19,  0xFF,  0x60,  0x00,  0x99,  0x08,  0xEA,  0x08,  0x2C,  0x14,  0xA9,  0x12,  0x66,  0x21,  0x44, 	/* 51680 */
+	0x7E,  0x82,  0x09,  0x7D,  0x08,  0x00,  0x7F,  0x7C,  0x08,  0x44,  0x4A,  0x44,  0x2C,  0x7C,  0x28,  0x44, 	/* 51690 */
+	0x0E,  0x28,  0x19,  0xFF,  0x60,  0x00,  0x9A,  0x08,  0x00,  0x09,  0xFF,  0x14,  0x28,  0x12,  0x28,  0x21, 	/* 516A0 */
+	0xEE,  0x7E,  0x82,  0x08,  0x82,  0x08,  0xEE,  0x7E,  0x28,  0x09,  0xFF,  0x4A,  0x10,  0x2C,  0xA8,  0x28, 	/* 516B0 */
+	0xAA,  0x0D,  0x25,  0x1A,  0x25,  0x60,  0x1C,  0xA1,  0x08,  0x48,  0x08,  0x4A,  0x19,  0xE9,  0x14,  0x48, 	/* 516C0 */
+	0x23,  0xFF,  0x3E,  0x08,  0x48,  0xEA,  0x08,  0xAA,  0x7E,  0xAA,  0x08,  0xEA,  0x4B,  0x2C,  0x2C,  0xA5, 	/* 516D0 */
+	0x28,  0x5D,  0x0E,  0xCB,  0x1B,  0x13,  0x60,  0x21,  0xAB,  0x08,  0x48,  0x08,  0x50,  0x14,  0xFF,  0x12, 	/* 516E0 */
+	0x90,  0x21,  0xFE,  0x7E,  0x90,  0x08,  0xFE,  0x08,  0x90,  0x7F,  0xFF,  0x08,  0x00,  0x4A,  0xEE,  0x2C, 	/* 516F0 */
+	0xAA,  0x28,  0xAA,  0x0E,  0xBA,  0x18,  0x82,  0x60,  0x86,  0xB5,  0x08,  0x4A,  0x09,  0xE9,  0x18,  0x48, 	/* 51700 */
+	0x17,  0xFF,  0x22,  0x08,  0x3F,  0xE8,  0x48,  0xAA,  0x08,  0xEA,  0x7E,  0x0A,  0x09,  0xFA,  0x4A,  0x4C, 	/* 51710 */
+	0x2D,  0xF5,  0x28,  0x4D,  0x0E,  0xEB,  0x1B,  0x13,  0x60,  0x21,  0xB6,  0x08,  0x00,  0x08,  0xFE,  0x14, 	/* 51720 */
+	0xAA,  0x12,  0xAA,  0x21,  0xFE,  0x7E,  0x00,  0x09,  0xFF,  0x08,  0x00,  0x7E,  0xFE,  0x08,  0x82,  0x4A, 	/* 51730 */
+	0xFE,  0x2C,  0x32,  0x28,  0x54,  0x0F,  0xC8,  0x18,  0x64,  0x61,  0x83,  0xB8,  0x08,  0x00,  0x08,  0xFE, 	/* 51740 */
+	0x14,  0xAA,  0x12,  0xAA,  0x20,  0xFE,  0x7E,  0x10,  0x08,  0xFE,  0x08,  0x10,  0x7F,  0xFF,  0x08,  0x44, 	/* 51750 */
+	0x4A,  0x28,  0x2D,  0xFF,  0x28,  0x10,  0x0E,  0xFE,  0x18,  0x10,  0x60,  0x10,  0xBA,  0x08,  0x92,  0x08, 	/* 51760 */
+	0x52,  0x14,  0x54,  0x13,  0xFF,  0x21,  0x01,  0x7F,  0x7D,  0x08,  0x44,  0x08,  0x7C,  0x7F,  0x00,  0x08, 	/* 51770 */
+	0xFE,  0x4A,  0x92,  0x2C,  0xFE,  0x28,  0x92,  0x0E,  0x92,  0x18,  0xFE,  0x60,  0x00,  0x81,  0x08,  0x00, 	/* 51780 */
+	0x08,  0x96,  0x14,  0xC6,  0x12,  0xAA,  0x21,  0x9A,  0x7E,  0xA6,  0x08,  0xD2,  0x08,  0xFE,  0x7F,  0x29, 	/* 51790 */
+	0x08,  0x47,  0x4A,  0xA0,  0x2C,  0x7C,  0x29,  0xA4,  0x0E,  0x18,  0x18,  0x6C,  0x63,  0x83,  0x84,  0x08, 	/* 517A0 */
+	0x10,  0x09,  0xFF,  0x14,  0x10,  0x12,  0x7E,  0x20,  0x00,  0x7F,  0xFF,  0x08,  0x02,  0x08,  0xFC,  0x7E, 	/* 517B0 */
+	0x10,  0x09,  0xFF,  0x4A,  0x02,  0x2C,  0xFF,  0x28,  0xB2,  0x0E,  0xAA,  0x18,  0xE2,  0x60,  0x06,  0x91, 	/* 517C0 */
+	0x08,  0x04,  0x08,  0xF4,  0x14,  0xA4,  0x12,  0xA7,  0x20,  0xF8,  0x7E,  0x90,  0x08,  0xF0,  0x08,  0xAF, 	/* 517D0 */
+	0x7F,  0xF0,  0x08,  0x00,  0x4A,  0xFE,  0x2C,  0xAA,  0x29,  0xAA,  0x0E,  0xAA,  0x19,  0xFF,  0x60,  0x00, 	/* 517E0 */
+	0x92,  0x00,  0x20,  0x3F,  0x7F,  0x24,  0x80,  0x3E,  0x7C,  0x22,  0x00,  0x3E,  0xFE,  0x24,  0xAA,  0x3F, 	/* 517F0 */
+	0xFE,  0x00,  0x80,  0x03,  0x60,  0x0F,  0xF8,  0x70,  0x87,  0x0F,  0xF8,  0x04,  0x90,  0x7F,  0xFF,  0x00, 	/* 51800 */
+	0x00,  0x93,  0x08,  0x08,  0x08,  0x3E,  0x14,  0x2A,  0x15,  0x3E,  0x22,  0x88,  0x7E,  0xFF,  0x08,  0x00, 	/* 51810 */
+	0x08,  0x3E,  0x7F,  0xA2,  0x08,  0xBE,  0x4A,  0xA0,  0x2C,  0xBE,  0x28,  0xA2,  0x0D,  0x7E,  0x19,  0x30, 	/* 51820 */
+	0x62,  0x0F,  0x9A,  0x08,  0x44,  0x09,  0xEF,  0x14,  0x44,  0x13,  0xFF,  0x21,  0x44,  0x7E,  0xAA,  0x09, 	/* 51830 */
+	0x01,  0x08,  0xFC,  0x7F,  0x84,  0x08,  0xFC,  0x4A,  0x84,  0x2C,  0xFC,  0x28,  0x84,  0x0E,  0xFC,  0x18, 	/* 51840 */
+	0xC4,  0x63,  0x02,  0x9B,  0x08,  0x08,  0x08,  0x08,  0x14,  0xFF,  0x12,  0x94,  0x21,  0xFF,  0x7E,  0x94, 	/* 51850 */
+	0x08,  0x9C,  0x08,  0xFF,  0x7E,  0x88,  0x08,  0xBE,  0x4A,  0xAA,  0x2C,  0xBE,  0x28,  0xAA,  0x0F,  0x3E, 	/* 51860 */
+	0x19,  0x12,  0x62,  0x61,  0x9E,  0x08,  0x92,  0x09,  0x24,  0x14,  0x92,  0x13,  0xFC,  0x21,  0x54,  0x7F, 	/* 51870 */
+	0x24,  0x09,  0x54,  0x09,  0xFC,  0x7E,  0x00,  0x09,  0xB4,  0x4D,  0x6C,  0x29,  0xB4,  0x2B,  0x6D,  0x1D, 	/* 51880 */
+	0x25,  0x11,  0xB3,  0x66,  0x61,  0xA0,  0x08,  0x8A,  0x08,  0x92,  0x15,  0x7D,  0x13,  0x6D,  0x20,  0xAA, 	/* 51890 */
+	0x7E,  0xBA,  0x09,  0x6D,  0x09,  0x7D,  0x7F,  0xD7,  0x08,  0x10,  0x4B,  0xFF,  0x2C,  0x38,  0x28,  0x54, 	/* 518A0 */
+	0x0E,  0x92,  0x19,  0x11,  0x60,  0x10,  0xA2,  0x08,  0x10,  0x08,  0x1E,  0x14,  0x10,  0x12,  0xFF,  0x21, 	/* 518B0 */
+	0x92,  0x7E,  0xFC,  0x08,  0x91,  0x08,  0xBF,  0x7F,  0xAA,  0x08,  0xBE,  0x4A,  0xAA,  0x2C,  0xBE,  0x28, 	/* 518C0 */
+	0xB0,  0x0F,  0x6A,  0x19,  0xA5,  0x62,  0x1C,  0xAA,  0x08,  0x10,  0x08,  0x1E,  0x14,  0x10,  0x12,  0xFF, 	/* 518D0 */
+	0x21,  0x9A,  0x7E,  0xF1,  0x08,  0xBF,  0x08,  0xAA,  0x7E,  0xBE,  0x08,  0xAA,  0x4A,  0xBE,  0x2C,  0x80, 	/* 518E0 */
+	0x29,  0xFE,  0x0E,  0xAA,  0x19,  0xFF,  0x62,  0x00,  0xB0,  0x08,  0x10,  0x08,  0x10,  0x14,  0x28,  0x12, 	/* 518F0 */
+	0x44,  0x21,  0xBB,  0x7E,  0x00,  0x09,  0xFF,  0x09,  0x6D,  0x7F,  0xFF,  0x08,  0x00,  0x4A,  0xFE,  0x2C, 	/* 51900 */
+	0xAA,  0x28,  0xFE,  0x0E,  0xAA,  0x18,  0xAA,  0x60,  0x86,  0xB5,  0x08,  0x44,  0x0B,  0xFF,  0x14,  0x44, 	/* 51910 */
+	0x12,  0xEE,  0x21,  0xAA,  0x7E,  0xEE,  0x08,  0x44,  0x08,  0x48,  0x7E,  0xFE,  0x09,  0x90,  0x4A,  0xFE, 	/* 51920 */
+	0x2C,  0x90,  0x28,  0xFE,  0x0E,  0x90,  0x18,  0xFF,  0x60,  0x00,  0xB7,  0x08,  0x00,  0x09,  0xFE,  0x14, 	/* 51930 */
+	0x48,  0x12,  0x78,  0x21,  0x48,  0x7E,  0x7E,  0x09,  0xC8,  0x08,  0x08,  0x3F,  0xFF,  0x08,  0xAA,  0x4A, 	/* 51940 */
+	0xEE,  0x2C,  0xAA,  0x28,  0xEE,  0x0E,  0xAB,  0x19,  0xFE,  0x60,  0x22,  0xBC,  0x08,  0x00,  0x09,  0xFE, 	/* 51950 */
+	0x15,  0x4A,  0x15,  0xFE,  0x22,  0x08,  0x7E,  0x92,  0x08,  0xBF,  0x0B,  0x54,  0x7E,  0x94,  0x09,  0x5F, 	/* 51960 */
+	0x4B,  0xF4,  0x2C,  0x9F,  0x29,  0xD4,  0x0D,  0xB4,  0x1A,  0x9F,  0x60,  0x80,  0xBD,  0x09,  0x8C,  0x09, 	/* 51970 */
+	0xEF,  0x16,  0x94,  0x13,  0xFF,  0x20,  0xC6,  0x7D,  0x6A,  0x0A,  0x53,  0x08,  0xFC,  0x7F,  0x84,  0x08, 	/* 51980 */
+	0xFC,  0x4A,  0x84,  0x2C,  0xFC,  0x28,  0x84,  0x0E,  0xFC,  0x18,  0xCC,  0x63,  0x02,  0xBE,  0x08,  0xC4, 	/* 51990 */
+	0x0B,  0xF4,  0x34,  0x0A,  0x09,  0xE4,  0x14,  0x0A,  0x7F,  0xFF,  0x09,  0x24,  0x2D,  0xF5,  0x4A,  0x95, 	/* 519A0 */
+	0x03,  0x60,  0x0F,  0xF8,  0x70,  0x87,  0x0F,  0xF8,  0x04,  0x90,  0x7F,  0xFF,  0x00,  0x00,  0xBF,  0x0A, 	/* 519B0 */
+	0x3C,  0x2B,  0x24,  0x7F,  0xA5,  0x12,  0x43,  0x3F,  0x81,  0x14,  0x7C,  0x25,  0x24,  0x37,  0x18,  0x25, 	/* 519C0 */
+	0x28,  0x3F,  0xC4,  0x03,  0x63,  0x0C,  0x98,  0x77,  0xF7,  0x02,  0xA0,  0x7F,  0xFF,  0x00,  0x00,  0x81, 	/* 519D0 */
+	0x09,  0xEF,  0x09,  0x29,  0x15,  0xEF,  0x13,  0x29,  0x21,  0xEF,  0x7E,  0x48,  0x08,  0xFF,  0x09,  0x90, 	/* 519E0 */
+	0x7E,  0xFE,  0x08,  0x90,  0x4A,  0xFE,  0x2C,  0x90,  0x2B,  0xFF,  0x0C,  0x44,  0x10,  0x38,  0x61,  0xC7, 	/* 519F0 */
+	0xB7,  0x00,  0x00,  0x07,  0xFC,  0x04,  0x00,  0x07,  0xF8,  0x04,  0x00,  0x07,  0xF8,  0x04,  0x00,  0x04, 	/* 51A00 */
+	0x00,  0x7F,  0xFF,  0x05,  0x08,  0x04,  0x88,  0x04,  0x50,  0x04,  0x20,  0x05,  0x90,  0x0E,  0x0C,  0x30, 	/* 51A10 */
+	0x03,  0x80,  0x00,  0x00,  0x7E,  0x7E,  0x42,  0x42,  0x7E,  0x7E,  0x42,  0x42,  0x42,  0x42,  0x7E,  0x7E, 	/* 51A20 */
+	0x40,  0x02,  0x40,  0x02,  0x40,  0x02,  0x40,  0x02,  0x40,  0x02,  0x40,  0x02,  0x40,  0x02,  0x40,  0x02, 	/* 51A30 */
+	0x40,  0x06,  0x82,  0x00,  0x00,  0x7E,  0x7E,  0x42,  0x42,  0x7E,  0x7E,  0x42,  0x42,  0x42,  0x42,  0x7E, 	/* 51A40 */
+	0x7E,  0x40,  0x02,  0x40,  0x02,  0x40,  0x02,  0x4F,  0xF2,  0x40,  0x02,  0x40,  0x02,  0x40,  0x02,  0x40, 	/* 51A50 */
+	0x02,  0x40,  0x06,  0x83,  0x00,  0x00,  0x7E,  0x7E,  0x42,  0x42,  0x7E,  0x7E,  0x42,  0x42,  0x7E,  0x7E, 	/* 51A60 */
+	0x41,  0x02,  0x41,  0x02,  0x41,  0x02,  0x41,  0x82,  0x42,  0x82,  0x42,  0x42,  0x44,  0x22,  0x48,  0x12, 	/* 51A70 */
+	0x40,  0x02,  0x40,  0x06,  0x87,  0x00,  0x00,  0x7E,  0x7E,  0x42,  0x42,  0x7E,  0x7E,  0x42,  0x42,  0x42, 	/* 51A80 */
+	0x42,  0x7E,  0x7E,  0x40,  0x02,  0x4F,  0xF2,  0x41,  0x02,  0x41,  0x82,  0x41,  0x42,  0x41,  0x22,  0x41, 	/* 51A90 */
+	0x02,  0x41,  0x02,  0x40,  0x06,  0x89,  0x00,  0x00,  0x7E,  0x7E,  0x42,  0x42,  0x7E,  0x7E,  0x42,  0x42, 	/* 51AA0 */
+	0x42,  0x42,  0x7E,  0x7E,  0x40,  0x82,  0x40,  0x82,  0x4F,  0xF2,  0x41,  0x82,  0x42,  0x82,  0x44,  0x82, 	/* 51AB0 */
+	0x58,  0x82,  0x41,  0x82,  0x40,  0x06,  0x8A,  0x00,  0x00,  0x7E,  0x7E,  0x42,  0x42,  0x7E,  0x7E,  0x42, 	/* 51AC0 */
+	0x42,  0x42,  0x42,  0x7E,  0x7E,  0x41,  0x02,  0x41,  0x02,  0x49,  0x12,  0x49,  0x12,  0x49,  0x12,  0x49, 	/* 51AD0 */
+	0x12,  0x4F,  0xF2,  0x40,  0x02,  0x40,  0x06,  0x8B,  0x00,  0x00,  0x7E,  0x7E,  0x42,  0x42,  0x7E,  0x7E, 	/* 51AE0 */
+	0x42,  0x42,  0x42,  0x42,  0x7E,  0x7E,  0x40,  0x02,  0x4F,  0xF2,  0x42,  0x42,  0x42,  0x42,  0x7F,  0xFA, 	/* 51AF0 */
+	0x42,  0x42,  0x44,  0x42,  0x48,  0x42,  0x40,  0x06,  0x8F,  0x00,  0x00,  0x7E,  0x7E,  0x42,  0x42,  0x7E, 	/* 51B00 */
+	0x7E,  0x42,  0x42,  0x7E,  0x7E,  0x40,  0x02,  0x4F,  0xF2,  0x41,  0x02,  0x41,  0x02,  0x47,  0xE2,  0x41, 	/* 51B10 */
+	0x02,  0x41,  0x02,  0x5F,  0xFA,  0x40,  0x02,  0x40,  0x06,  0x91,  0x00,  0x00,  0x7E,  0x7E,  0x42,  0x42, 	/* 51B20 */
+	0x7E,  0x7E,  0x42,  0x42,  0x7E,  0x7E,  0x41,  0x02,  0x41,  0x02,  0x5F,  0xF2,  0x41,  0x02,  0x43,  0x82, 	/* 51B30 */
+	0x45,  0x42,  0x49,  0x22,  0x51,  0x12,  0x41,  0x02,  0x40,  0x06,  0x93,  0x00,  0x00,  0x7E,  0x7E,  0x42, 	/* 51B40 */
+	0x42,  0x7E,  0x7E,  0x42,  0x42,  0x42,  0x42,  0x7E,  0x7E,  0x40,  0x02,  0x47,  0xE2,  0x44,  0x22,  0x47, 	/* 51B50 */
+	0xE2,  0x44,  0x22,  0x44,  0x22,  0x47,  0xE2,  0x40,  0x02,  0x40,  0x06,  0x94,  0x00,  0x00,  0x7E,  0x7E, 	/* 51B60 */
+	0x42,  0x42,  0x7E,  0x7E,  0x42,  0x42,  0x42,  0x42,  0x7F,  0x7E,  0x41,  0x02,  0x5F,  0xF2,  0x44,  0x42, 	/* 51B70 */
+	0x44,  0x42,  0x42,  0x82,  0x41,  0x02,  0x46,  0xC2,  0x58,  0x32,  0x40,  0x06,  0x96,  0x00,  0x00,  0x7E, 	/* 51B80 */
+	0x7E,  0x42,  0x42,  0x7E,  0x7E,  0x42,  0x42,  0x42,  0x42,  0x7E,  0x7E,  0x41,  0x02,  0x41,  0x12,  0x5D, 	/* 51B90 */
+	0x92,  0x45,  0xA2,  0x45,  0x42,  0x49,  0x22,  0x51,  0x1A,  0x43,  0x02,  0x40,  0x06,  0x98,  0x00,  0x00, 	/* 51BA0 */
+	0x7E,  0x7E,  0x42,  0x42,  0x7E,  0x7E,  0x42,  0x42,  0x7E,  0x7E,  0x40,  0x02,  0x4F,  0xE2,  0x49,  0x22, 	/* 51BB0 */
+	0x4F,  0xE2,  0x49,  0x22,  0x4F,  0xE2,  0x41,  0x02,  0x41,  0x02,  0x41,  0x02,  0x41,  0x06,  0x99,  0x00, 	/* 51BC0 */
+	0x00,  0x7E,  0x7E,  0x42,  0x42,  0x7E,  0x7E,  0x42,  0x42,  0x7E,  0x7E,  0x41,  0x02,  0x41,  0x02,  0x5F, 	/* 51BD0 */
+	0xFA,  0x41,  0x02,  0x4F,  0xF2,  0x49,  0x12,  0x49,  0x12,  0x49,  0x62,  0x41,  0x02,  0x41,  0x06,  0xA0, 	/* 51BE0 */
+	0x00,  0x00,  0x7E,  0x7E,  0x42,  0x42,  0x7E,  0x7E,  0x42,  0x42,  0x42,  0x42,  0x7E,  0x7E,  0x40,  0x02, 	/* 51BF0 */
+	0x4F,  0xF2,  0x41,  0x02,  0x41,  0x02,  0x47,  0xE2,  0x41,  0x42,  0x41,  0x22,  0x4F,  0xF2,  0x40,  0x06, 	/* 51C00 */
+	0xA2,  0x00,  0x00,  0x7E,  0x7E,  0x42,  0x42,  0x7E,  0x7E,  0x42,  0x42,  0x7E,  0x7E,  0x44,  0x22,  0x42, 	/* 51C10 */
+	0x42,  0x4F,  0xF2,  0x41,  0x02,  0x41,  0x02,  0x5F,  0xFA,  0x41,  0x42,  0x42,  0x22,  0x44,  0x12,  0x48, 	/* 51C20 */
+	0x06,  0xA3,  0x00,  0x00,  0x7E,  0x7E,  0x42,  0x42,  0x7E,  0x7E,  0x42,  0x42,  0x7E,  0x7E,  0x41,  0x02, 	/* 51C30 */
+	0x43,  0xE2,  0x4E,  0x42,  0x41,  0x82,  0x46,  0x62,  0x58,  0x1A,  0x47,  0xE2,  0x44,  0x22,  0x47,  0xE2, 	/* 51C40 */
+	0x40,  0x06,  0xA4,  0x00,  0x00,  0x7E,  0x7E,  0x42,  0x42,  0x7E,  0x7E,  0x42,  0x42,  0x7E,  0x7E,  0x40, 	/* 51C50 */
+	0x82,  0x41,  0x42,  0x46,  0x22,  0x5B,  0xDA,  0x40,  0x02,  0x47,  0xE2,  0x44,  0x22,  0x44,  0x22,  0x47, 	/* 51C60 */
+	0xE2,  0x40,  0x06,  0xA5,  0x00,  0x00,  0x7E,  0x7E,  0x42,  0x42,  0x7E,  0x7E,  0x42,  0x42,  0x7E,  0x7E, 	/* 51C70 */
+	0x42,  0x22,  0x42,  0x52,  0x47,  0xFA,  0x48,  0x42,  0x58,  0x52,  0x68,  0x62,  0x48,  0xAA,  0x4B,  0x1A, 	/* 51C80 */
+	0x48,  0x0A,  0x40,  0x06,  0xA7,  0x00,  0x00,  0x7E,  0x7E,  0x42,  0x42,  0x7E,  0x7E,  0x42,  0x42,  0x7E, 	/* 51C90 */
+	0x7E,  0x40,  0x02,  0x42,  0x42,  0x4F,  0xF2,  0x42,  0x42,  0x42,  0x42,  0x5F,  0xFA,  0x42,  0x42,  0x44, 	/* 51CA0 */
+	0x22,  0x58,  0x12,  0x40,  0x06,  0xA8,  0x00,  0x00,  0x7E,  0x7E,  0x42,  0x42,  0x7E,  0x7E,  0x42,  0x42, 	/* 51CB0 */
+	0x7E,  0x7E,  0x41,  0x02,  0x4F,  0xE2,  0x41,  0x02,  0x5F,  0xF2,  0x41,  0x02,  0x4F,  0xE2,  0x41,  0x02, 	/* 51CC0 */
+	0x5F,  0xF2,  0x40,  0x02,  0x40,  0x06,  0xAD,  0x00,  0x00,  0x7E,  0x7E,  0x42,  0x42,  0x7E,  0x7E,  0x42, 	/* 51CD0 */
+	0x42,  0x7E,  0x7E,  0x40,  0x02,  0x47,  0xE2,  0x44,  0x22,  0x47,  0xE2,  0x41,  0x02,  0x4F,  0xF2,  0x48, 	/* 51CE0 */
+	0x12,  0x48,  0x12,  0x4F,  0xF2,  0x40,  0x06,  0xB2,  0x00,  0x00,  0x7E,  0x7E,  0x42,  0x42,  0x7E,  0x7E, 	/* 51CF0 */
+	0x42,  0x42,  0x7E,  0x7E,  0x44,  0x42,  0x42,  0x82,  0x4F,  0xE2,  0x48,  0x22,  0x48,  0x22,  0x4F,  0xE2, 	/* 51D00 */
+	0x42,  0x82,  0x42,  0x92,  0x44,  0x72,  0x48,  0x06,  0xB9,  0x00,  0x00,  0x7E,  0x7E,  0x42,  0x42,  0x7E, 	/* 51D10 */
+	0x7E,  0x42,  0x42,  0x7E,  0x7E,  0x41,  0x02,  0x5F,  0xFA,  0x43,  0x42,  0x47,  0xE2,  0x4D,  0x32,  0x57, 	/* 51D20 */
+	0xEA,  0x45,  0x22,  0x47,  0xE2,  0x41,  0x12,  0x40,  0xF6,  0xBB,  0x00,  0x00,  0x7E,  0x7E,  0x42,  0x42, 	/* 51D30 */
+	0x7E,  0x7E,  0x42,  0x42,  0x7E,  0x7E,  0x42,  0x02,  0x43,  0xC2,  0x44,  0x42,  0x49,  0x82,  0x57,  0x72, 	/* 51D40 */
+	0x44,  0x12,  0x47,  0x72,  0x44,  0x12,  0x47,  0xF2,  0x40,  0x06,  0xBC,  0x00,  0x00,  0x7E,  0x7E,  0x42, 	/* 51D50 */
+	0x42,  0x7E,  0x7E,  0x42,  0x42,  0x7E,  0x7E,  0x44,  0x22,  0x5F,  0xA2,  0x44,  0x52,  0x47,  0x8A,  0x45, 	/* 51D60 */
+	0x22,  0x45,  0x12,  0x45,  0x42,  0x49,  0x22,  0x53,  0x12,  0x40,  0x06,  0xBE,  0x00,  0x00,  0x7E,  0x7E, 	/* 51D70 */
+	0x42,  0x42,  0x7E,  0x7E,  0x42,  0x42,  0x7E,  0x7E,  0x40,  0xA2,  0x5F,  0xFA,  0x4E,  0x82,  0x4A,  0x92, 	/* 51D80 */
+	0x4E,  0x52,  0x41,  0x62,  0x46,  0xAA,  0x59,  0x1A,  0x46,  0x0A,  0x40,  0x06,  0x83,  0x00,  0x00,  0x7E, 	/* 51D90 */
+	0x7E,  0x42,  0x42,  0x7E,  0x7E,  0x42,  0x42,  0x7E,  0x7E,  0x47,  0xE2,  0x44,  0x22,  0x47,  0xE2,  0x44, 	/* 51DA0 */
+	0x22,  0x47,  0xE2,  0x41,  0x12,  0x5F,  0xFA,  0x42,  0x42,  0x4C,  0x32,  0x40,  0x06,  0x87,  0x00,  0x00, 	/* 51DB0 */
+	0x7E,  0x7E,  0x42,  0x42,  0x7E,  0x7E,  0x42,  0x42,  0x42,  0x42,  0x7E,  0x7E,  0x41,  0x02,  0x4F,  0xF2, 	/* 51DC0 */
+	0x42,  0x42,  0x5F,  0xFA,  0x44,  0x22,  0x47,  0xE2,  0x44,  0x22,  0x47,  0xE2,  0x40,  0x06,  0x8A,  0x00, 	/* 51DD0 */
+	0x00,  0x7E,  0x7E,  0x42,  0x42,  0x7E,  0x7E,  0x42,  0x42,  0x7E,  0x7E,  0x48,  0x32,  0x45,  0xC2,  0x40, 	/* 51DE0 */
+	0x42,  0x53,  0xFA,  0x48,  0x42,  0x41,  0xF2,  0x45,  0x12,  0x49,  0x12,  0x51,  0xF2,  0x40,  0x06,  0x8C, 	/* 51DF0 */
+	0x00,  0x00,  0x7E,  0x7E,  0x42,  0x42,  0x7E,  0x7E,  0x42,  0x42,  0x7E,  0x7E,  0x40,  0x82,  0x5F,  0xFA, 	/* 51E00 */
+	0x46,  0xB2,  0x45,  0xD2,  0x47,  0xF2,  0x41,  0xC2,  0x42,  0xA2,  0x4C,  0x9A,  0x40,  0x82,  0x40,  0x06, 	/* 51E10 */
+	0x8D,  0x00,  0x00,  0x7E,  0x7E,  0x42,  0x42,  0x7E,  0x7E,  0x42,  0x42,  0x7E,  0x7E,  0x41,  0x22,  0x4F, 	/* 51E20 */
+	0xE2,  0x41,  0x42,  0x5F,  0xFA,  0x43,  0xE2,  0x46,  0x22,  0x4B,  0xE2,  0x52,  0x22,  0x43,  0xE2,  0x40, 	/* 51E30 */
+	0x06,  0x94,  0x00,  0x00,  0x7E,  0x7E,  0x42,  0x42,  0x7E,  0x7E,  0x42,  0x42,  0x7E,  0x7E,  0x41,  0x02, 	/* 51E40 */
+	0x4F,  0xE2,  0x41,  0x02,  0x5F,  0xFA,  0x42,  0x62,  0x4F,  0x92,  0x47,  0xF2,  0x45,  0x52,  0x5F,  0xFA, 	/* 51E50 */
+	0x40,  0x06,  0x95,  0x00,  0x00,  0x7E,  0x7E,  0x42,  0x42,  0x7E,  0x7E,  0x42,  0x42,  0x7E,  0x7E,  0x51, 	/* 51E60 */
+	0x02,  0x4A,  0x42,  0x5F,  0x7E,  0x44,  0x4A,  0x55,  0xA2,  0x5F,  0x22,  0x44,  0x52,  0x44,  0x92,  0x49, 	/* 51E70 */
+	0x0A,  0x40,  0x06,  0x96,  0x00,  0x00,  0x7E,  0x7E,  0x42,  0x42,  0x7E,  0x7E,  0x42,  0x42,  0x7E,  0x7E, 	/* 51E80 */
+	0x40,  0x02,  0x47,  0xF2,  0x44,  0x82,  0x47,  0xF2,  0x44,  0x82,  0x47,  0xFA,  0x4D,  0x2A,  0x4A,  0x8A, 	/* 51E90 */
+	0x52,  0x32,  0x40,  0x06,  0x98,  0x00,  0x00,  0x7E,  0x7E,  0x42,  0x42,  0x7E,  0x7E,  0x42,  0x42,  0x7E, 	/* 51EA0 */
+	0x7E,  0x40,  0x02,  0x5F,  0x12,  0x40,  0xFE,  0x5F,  0x12,  0x51,  0x92,  0x5F,  0x52,  0x4A,  0x12,  0x47, 	/* 51EB0 */
+	0x12,  0x5C,  0x32,  0x40,  0x06,  0x9C,  0x00,  0x00,  0x7E,  0x7E,  0x42,  0x42,  0x7E,  0x7E,  0x42,  0x42, 	/* 51EC0 */
+	0x7E,  0x7E,  0x44,  0x22,  0x5A,  0xD2,  0x44,  0x22,  0x4A,  0x52,  0x5D,  0xEA,  0x42,  0x42,  0x52,  0x4A, 	/* 51ED0 */
+	0x5E,  0x7A,  0x44,  0x42,  0x48,  0x46,  0xA1,  0x00,  0x00,  0x7E,  0x7E,  0x42,  0x42,  0x7E,  0x7E,  0x42, 	/* 51EE0 */
+	0x42,  0x7E,  0x7E,  0x40,  0x02,  0x4E,  0x72,  0x4A,  0x52,  0x4F,  0xF2,  0x45,  0x22,  0x47,  0xE2,  0x45, 	/* 51EF0 */
+	0x22,  0x5F,  0xFA,  0x41,  0x02,  0x41,  0x06,  0xA2,  0x00,  0x00,  0x7E,  0x7E,  0x42,  0x42,  0x7E,  0x7E, 	/* 51F00 */
+	0x42,  0x42,  0x7E,  0x7E,  0x40,  0x22,  0x5E,  0xFA,  0x52,  0x52,  0x5E,  0x52,  0x51,  0xFA,  0x5E,  0x22, 	/* 51F10 */
+	0x5A,  0xFA,  0x6A,  0x22,  0x4E,  0x22,  0x40,  0x06,  0xA5,  0x00,  0x00,  0x7E,  0x7E,  0x42,  0x42,  0x7E, 	/* 51F20 */
+	0x7E,  0x42,  0x42,  0x7E,  0x7E,  0x49,  0xF2,  0x44,  0x42,  0x53,  0xFA,  0x48,  0xA2,  0x5D,  0xFA,  0x44, 	/* 51F30 */
+	0x42,  0x44,  0xF2,  0x4A,  0x42,  0x51,  0xFA,  0x40,  0x06,  0x9C,  0x00,  0x80,  0x01,  0x00,  0x0F,  0xF0, 	/* 51F40 */
+	0x08,  0x10,  0x0F,  0xF0,  0x08,  0x00,  0x0F,  0xF8,  0x08,  0x08,  0x08,  0x08,  0x0F,  0xF8,  0x00,  0x80, 	/* 51F50 */
+	0x7F,  0xFF,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0xA1,  0x00,  0x04,  0x3C,  0x18,  0x24, 	/* 51F60 */
+	0xF0,  0x24,  0x10,  0x28,  0x10,  0x30,  0x10,  0x28,  0x10,  0x25,  0xFF,  0x24,  0x10,  0x22,  0x10,  0x22, 	/* 51F70 */
+	0x10,  0x32,  0x10,  0x2C,  0x10,  0x20,  0x10,  0x20,  0x10,  0x20,  0x10,  0xA8,  0x00,  0x00,  0x3D,  0xFF, 	/* 51F80 */
+	0x25,  0x00,  0x29,  0x00,  0x29,  0x7C,  0x31,  0x44,  0x29,  0x44,  0x25,  0x44,  0x25,  0x44,  0x25,  0x44, 	/* 51F90 */
+	0x25,  0x58,  0x26,  0x40,  0x3A,  0x42,  0x24,  0x42,  0x28,  0x3E,  0x20,  0x00,  0xAA,  0x00,  0x00,  0x3C, 	/* 51FA0 */
+	0xFF,  0x24,  0x80,  0x24,  0x80,  0x28,  0x80,  0x30,  0xFE,  0x28,  0xA2,  0x24,  0xA2,  0x24,  0xA4,  0x24, 	/* 51FB0 */
+	0x94,  0x24,  0x98,  0x39,  0x08,  0x21,  0x14,  0x22,  0x24,  0x24,  0xC2,  0x23,  0x01,  0xAE,  0x00,  0x00, 	/* 51FC0 */
+	0x3C,  0xFC,  0x24,  0x00,  0x28,  0x00,  0x28,  0x00,  0x33,  0xFF,  0x28,  0x48,  0x28,  0x48,  0x24,  0x48, 	/* 51FD0 */
+	0x24,  0x48,  0x24,  0x48,  0x24,  0x48,  0x38,  0x88,  0x20,  0x89,  0x21,  0x09,  0x22,  0x07,  0xAF,  0x00, 	/* 51FE0 */
+	0x10,  0x3C,  0x10,  0x24,  0x10,  0x24,  0x10,  0x28,  0x90,  0x30,  0x90,  0x28,  0x9E,  0x28,  0x90,  0x24, 	/* 51FF0 */
+	0x90,  0x24,  0x90,  0x24,  0x90,  0x24,  0x90,  0x38,  0x90,  0x20,  0x90,  0x23,  0xFF,  0x20,  0x00,  0xB2, 	/* 52000 */
+	0x00,  0x20,  0x3C,  0x20,  0x24,  0x20,  0x27,  0xFF,  0x28,  0x20,  0x30,  0x20,  0x28,  0x20,  0x24,  0x3E, 	/* 52010 */
+	0x22,  0x42,  0x22,  0x42,  0x22,  0x42,  0x22,  0x82,  0x3C,  0x82,  0x21,  0x02,  0x22,  0x04,  0x24,  0x18, 	/* 52020 */
+	0xBB,  0x00,  0x00,  0x3C,  0xFC,  0x24,  0x84,  0x24,  0x84,  0x28,  0x84,  0x30,  0xFC,  0x28,  0x84,  0x24, 	/* 52030 */
+	0x84,  0x22,  0x84,  0x22,  0xFC,  0x22,  0x84,  0x32,  0x84,  0x2C,  0x84,  0x20,  0x84,  0x23,  0xFF,  0x20, 	/* 52040 */
+	0x00,  0xBF,  0x00,  0x00,  0x3F,  0xFF,  0x24,  0x04,  0x24,  0x04,  0x29,  0xE4,  0x31,  0x24,  0x29,  0x24, 	/* 52050 */
+	0x25,  0x24,  0x25,  0x24,  0x25,  0x24,  0x25,  0xE4,  0x24,  0x04,  0x38,  0x04,  0x20,  0x04,  0x20,  0x04, 	/* 52060 */
+	0x20,  0x0C,  0x80,  0x00,  0x10,  0x3E,  0x10,  0x22,  0x10,  0x25,  0xFF,  0x29,  0x01,  0x29,  0x41,  0x24, 	/* 52070 */
+	0x40,  0x22,  0x44,  0x22,  0x58,  0x22,  0x60,  0x22,  0x40,  0x22,  0x40,  0x2C,  0x40,  0x20,  0x41,  0x20, 	/* 52080 */
+	0x21,  0x20,  0x1F,  0x82,  0x00,  0x10,  0x3C,  0x10,  0x24,  0x10,  0x25,  0xFF,  0x29,  0x12,  0x31,  0x14, 	/* 52090 */
+	0x29,  0x10,  0x29,  0xFC,  0x25,  0x44,  0x25,  0x44,  0x25,  0x28,  0x25,  0x28,  0x3A,  0x10,  0x22,  0x28, 	/* 520A0 */
+	0x24,  0xC4,  0x23,  0x03,  0x84,  0x00,  0x44,  0x3C,  0x44,  0x24,  0x44,  0x24,  0x84,  0x28,  0xFF,  0x30, 	/* 520B0 */
+	0x84,  0x29,  0x84,  0x26,  0xA4,  0x24,  0x94,  0x24,  0x94,  0x24,  0x84,  0x24,  0x84,  0x38,  0x84,  0x20, 	/* 520C0 */
+	0x84,  0x20,  0x84,  0x20,  0x8C,  0x8B,  0x00,  0x00,  0x3C,  0xFF,  0x24,  0x10,  0x29,  0x10,  0x29,  0x7E, 	/* 520D0 */
+	0x31,  0x52,  0x29,  0x52,  0x29,  0x5A,  0x25,  0x6A,  0x25,  0x66,  0x25,  0x42,  0x25,  0x42,  0x39,  0x46, 	/* 520E0 */
+	0x21,  0x00,  0x21,  0xFF,  0x20,  0x00,  0x8C,  0x00,  0x00,  0x3D,  0xFF,  0x24,  0x10,  0x24,  0x10,  0x28, 	/* 520F0 */
+	0x20,  0x30,  0xFE,  0x28,  0x82,  0x24,  0x82,  0x22,  0x82,  0x22,  0xFE,  0x22,  0x82,  0x32,  0x82,  0x2C, 	/* 52100 */
+	0x82,  0x20,  0x82,  0x20,  0xFE,  0x20,  0x00,  0x8D,  0x00,  0x20,  0x3C,  0x20,  0x24,  0x7C,  0x24,  0xC4, 	/* 52110 */
+	0x2B,  0x28,  0x30,  0x30,  0x28,  0xCC,  0x2B,  0x13,  0x24,  0x10,  0x25,  0xFE,  0x24,  0x90,  0x24,  0x90, 	/* 52120 */
+	0x3B,  0xFF,  0x20,  0x10,  0x20,  0x10,  0x20,  0x10,  0x8F,  0x00,  0x20,  0x3C,  0x20,  0x27,  0xFF,  0x24, 	/* 52130 */
+	0x20,  0x28,  0x20,  0x30,  0x7E,  0x28,  0x42,  0x24,  0xC2,  0x22,  0xFE,  0x23,  0x42,  0x22,  0x42,  0x32, 	/* 52140 */
+	0x7E,  0x2C,  0x42,  0x20,  0x42,  0x20,  0x42,  0x20,  0x46,  0x90,  0x00,  0x00,  0x3C,  0xFC,  0x24,  0x84, 	/* 52150 */
+	0x24,  0x84,  0x28,  0xFC,  0x30,  0x84,  0x28,  0x84,  0x24,  0xFE,  0x22,  0xA2,  0x22,  0x94,  0x22,  0x94, 	/* 52160 */
+	0x32,  0x88,  0x2C,  0x88,  0x20,  0xA4,  0x20,  0xC2,  0x23,  0x01,  0x9B,  0x01,  0x10,  0x3D,  0x10,  0x25, 	/* 52170 */
+	0x12,  0x25,  0xFC,  0x29,  0x10,  0x31,  0x10,  0x29,  0x11,  0x29,  0xCF,  0x27,  0x00,  0x24,  0x20,  0x24, 	/* 52180 */
+	0x20,  0x25,  0xFC,  0x38,  0x20,  0x20,  0x20,  0x27,  0xFF,  0x20,  0x00,  0x9C,  0x00,  0x20,  0x3C,  0x20, 	/* 52190 */
+	0x25,  0xFF,  0x28,  0x20,  0x28,  0xA4,  0x30,  0xA4,  0x28,  0xA4,  0x29,  0x6A,  0x25,  0x32,  0x26,  0x20, 	/* 521A0 */
+	0x24,  0x30,  0x24,  0x50,  0x38,  0x48,  0x20,  0x84,  0x23,  0x02,  0x2C,  0x01,  0x9D,  0x00,  0x20,  0x3C, 	/* 521B0 */
+	0x20,  0x27,  0xFF,  0x24,  0x20,  0x2B,  0x2C,  0x31,  0x24,  0x29,  0x24,  0x29,  0xA4,  0x25,  0x6A,  0x26, 	/* 521C0 */
+	0x31,  0x24,  0x50,  0x24,  0x50,  0x38,  0x88,  0x21,  0x04,  0x22,  0x02,  0x24,  0x01,  0x9E,  0x00,  0x24, 	/* 521D0 */
+	0x3C,  0x44,  0x25,  0xC4,  0x28,  0x44,  0x28,  0x44,  0x33,  0xFF,  0x28,  0x44,  0x28,  0x84,  0x24,  0x84, 	/* 521E0 */
+	0x25,  0x24,  0x24,  0x20,  0x25,  0xFE,  0x38,  0x20,  0x20,  0x20,  0x27,  0xFF,  0x20,  0x00,  0x9F,  0x00, 	/* 521F0 */
+	0x10,  0x3C,  0x90,  0x24,  0x9E,  0x28,  0x90,  0x28,  0x90,  0x33,  0xFF,  0x28,  0x10,  0x28,  0x50,  0x24, 	/* 52200 */
+	0x52,  0x24,  0x92,  0x25,  0x14,  0x24,  0x34,  0x38,  0x08,  0x20,  0x10,  0x20,  0x60,  0x23,  0x80,  0xA2, 	/* 52210 */
+	0x00,  0x10,  0x3C,  0x10,  0x25,  0xFF,  0x25,  0x01,  0x29,  0x01,  0x30,  0xFE,  0x28,  0x00,  0x24,  0x00, 	/* 52220 */
+	0x27,  0xFF,  0x24,  0x48,  0x24,  0x48,  0x34,  0x48,  0x28,  0x88,  0x20,  0x89,  0x21,  0x09,  0x22,  0x07, 	/* 52230 */
+	0xA3,  0x00,  0x20,  0x3C,  0x20,  0x27,  0xFF,  0x24,  0x20,  0x29,  0xFC,  0x31,  0x24,  0x29,  0x24,  0x25, 	/* 52240 */
+	0xFC,  0x25,  0x24,  0x25,  0x24,  0x25,  0xFC,  0x24,  0x20,  0x3B,  0xFF,  0x20,  0x20,  0x20,  0x20,  0x20, 	/* 52250 */
+	0x20,  0xA4,  0x00,  0x20,  0x3C,  0x20,  0x24,  0x50,  0x24,  0x50,  0x28,  0x88,  0x31,  0x04,  0x2A,  0xFA, 	/* 52260 */
+	0x28,  0x21,  0x24,  0x20,  0x27,  0xFE,  0x24,  0x20,  0x24,  0xA8,  0x38,  0xA4,  0x21,  0x22,  0x22,  0x22, 	/* 52270 */
+	0x20,  0x60,  0xA5,  0x00,  0x20,  0x3C,  0x20,  0x24,  0x3C,  0x24,  0x44,  0x28,  0x48,  0x30,  0x88,  0x28, 	/* 52280 */
+	0x10,  0x29,  0x3E,  0x25,  0x22,  0x25,  0x22,  0x25,  0x3E,  0x25,  0x22,  0x39,  0x22,  0x21,  0x22,  0x21, 	/* 52290 */
+	0x3E,  0x21,  0x00,  0xA6,  0x00,  0x20,  0x3C,  0x20,  0x27,  0xFE,  0x24,  0x20,  0x29,  0xFC,  0x30,  0x20, 	/* 522A0 */
+	0x2B,  0xFF,  0x28,  0x40,  0x24,  0x44,  0x27,  0xFF,  0x24,  0x84,  0x24,  0xC4,  0x39,  0x24,  0x22,  0x24, 	/* 522B0 */
+	0x24,  0x04,  0x20,  0x0C,  0xAA,  0x00,  0x20,  0x3C,  0x20,  0x25,  0xFE,  0x24,  0x84,  0x28,  0x44,  0x28, 	/* 522C0 */
+	0x48,  0x38,  0x48,  0x25,  0xFF,  0x22,  0x00,  0x22,  0x00,  0x22,  0xFC,  0x22,  0x84,  0x3C,  0x84,  0x20, 	/* 522D0 */
+	0x84,  0x20,  0xFC,  0x20,  0x00,  0xAC,  0x00,  0x00,  0x3F,  0xFF,  0x2A,  0x40,  0x2A,  0x40,  0x2A,  0x7E, 	/* 522E0 */
+	0x33,  0xD2,  0x2A,  0x52,  0x2A,  0x54,  0x27,  0xD4,  0x26,  0x4C,  0x26,  0x48,  0x26,  0x48,  0x3B,  0xD4, 	/* 522F0 */
+	0x26,  0x54,  0x20,  0x62,  0x20,  0x41,  0xB0,  0x00,  0x20,  0x3C,  0x20,  0x24,  0x50,  0x24,  0x88,  0x29, 	/* 52300 */
+	0x74,  0x32,  0x03,  0x29,  0xF8,  0x24,  0x10,  0x24,  0x20,  0x25,  0xFC,  0x24,  0x00,  0x27,  0xFF,  0x38, 	/* 52310 */
+	0x50,  0x20,  0x88,  0x27,  0xFC,  0x20,  0x04,  0xB2,  0x00,  0x08,  0x3C,  0x30,  0x25,  0xE0,  0x24,  0x20, 	/* 52320 */
+	0x2B,  0xFE,  0x31,  0x24,  0x29,  0x24,  0x29,  0x24,  0x27,  0xFF,  0x25,  0x24,  0x25,  0x24,  0x27,  0xFE, 	/* 52330 */
+	0x38,  0x20,  0x20,  0x20,  0x27,  0xFF,  0x20,  0x00,  0xB3,  0x00,  0x20,  0x3C,  0x20,  0x27,  0xFF,  0x24, 	/* 52340 */
+	0x20,  0x29,  0xFC,  0x31,  0x24,  0x29,  0xFC,  0x25,  0x24,  0x25,  0x24,  0x25,  0xFC,  0x24,  0x70,  0x24, 	/* 52350 */
+	0xA8,  0x39,  0x24,  0x22,  0x22,  0x24,  0x21,  0x20,  0x20,  0xB5,  0x00,  0x20,  0x3C,  0x20,  0x25,  0xFE, 	/* 52360 */
+	0x24,  0x20,  0x27,  0xFF,  0x28,  0x50,  0x30,  0x52,  0x28,  0x8E,  0x27,  0x40,  0x24,  0x78,  0x24,  0x88, 	/* 52370 */
+	0x27,  0x50,  0x38,  0x20,  0x20,  0x50,  0x21,  0x8C,  0x26,  0x03,  0xB6,  0x00,  0x80,  0x3C,  0x80,  0x24, 	/* 52380 */
+	0xFE,  0x25,  0x42,  0x29,  0x42,  0x32,  0xFA,  0x29,  0x22,  0x26,  0x22,  0x27,  0xFE,  0x24,  0x22,  0x25, 	/* 52390 */
+	0x2A,  0x39,  0x2A,  0x21,  0xFA,  0x20,  0x02,  0x20,  0x04,  0x20,  0x18,  0xB7,  0x00,  0x40,  0x3C,  0x40, 	/* 523A0 */
+	0x24,  0x7E,  0x24,  0x42,  0x28,  0x82,  0x30,  0x82,  0x29,  0x0C,  0x28,  0x20,  0x24,  0x40,  0x25,  0x9E, 	/* 523B0 */
+	0x25,  0x02,  0x25,  0xCE,  0x39,  0x02,  0x21,  0x02,  0x21,  0xFE,  0x20,  0x00,  0xB8,  0x00,  0x20,  0x3C, 	/* 523C0 */
+	0x20,  0x25,  0xFC,  0x24,  0x20,  0x24,  0x20,  0x2B,  0xFF,  0x30,  0x90,  0x28,  0x92,  0x25,  0x2E,  0x22, 	/* 523D0 */
+	0x20,  0x22,  0x20,  0x23,  0xFE,  0x3C,  0x20,  0x20,  0x20,  0x23,  0xFF,  0x20,  0x00,  0xBA,  0x00,  0x20, 	/* 523E0 */
+	0x3C,  0x20,  0x24,  0x50,  0x24,  0x88,  0x29,  0x04,  0x33,  0xFE,  0x28,  0x21,  0x29,  0xFC,  0x25,  0x24, 	/* 523F0 */
+	0x25,  0x24,  0x25,  0xFC,  0x24,  0x20,  0x38,  0x50,  0x20,  0x88,  0x21,  0x04,  0x26,  0x03,  0xBD,  0x00, 	/* 52400 */
+	0x00,  0x3D,  0xF8,  0x25,  0x08,  0x25,  0xF8,  0x29,  0x08,  0x31,  0x08,  0x29,  0xF8,  0x24,  0x00,  0x27, 	/* 52410 */
+	0xFF,  0x24,  0x80,  0x25,  0xFE,  0x26,  0x52,  0x38,  0x92,  0x21,  0x22,  0x20,  0x44,  0x20,  0x98,  0x85, 	/* 52420 */
+	0x00,  0x00,  0x3D,  0xFC,  0x25,  0x24,  0x25,  0x24,  0x29,  0xFC,  0x31,  0x24,  0x29,  0x24,  0x25,  0xFC, 	/* 52430 */
+	0x24,  0x20,  0x27,  0xFE,  0x26,  0x22,  0x26,  0x2A,  0x3A,  0x36,  0x22,  0xE6,  0x22,  0x02,  0x22,  0x06, 	/* 52440 */
+	0x86,  0x00,  0x40,  0x3C,  0x40,  0x24,  0xFC,  0x25,  0x08,  0x2A,  0x90,  0x34,  0x60,  0x28,  0xD8,  0x27, 	/* 52450 */
+	0x87,  0x24,  0xA0,  0x25,  0xFE,  0x26,  0x20,  0x25,  0xFC,  0x38,  0x20,  0x20,  0x20,  0x23,  0xFF,  0x20, 	/* 52460 */
+	0x00,  0x88,  0x00,  0x00,  0x3D,  0xFC,  0x25,  0x24,  0x25,  0x24,  0x29,  0xFC,  0x31,  0x24,  0x29,  0x24, 	/* 52470 */
+	0x29,  0xFC,  0x24,  0x00,  0x27,  0xFF,  0x25,  0x44,  0x25,  0x28,  0x39,  0x10,  0x21,  0x08,  0x21,  0xC4, 	/* 52480 */
+	0x27,  0x03,  0x8A,  0x01,  0x08,  0x3C,  0x88,  0x24,  0x90,  0x27,  0xFF,  0x28,  0x40,  0x30,  0xA2,  0x2B, 	/* 52490 */
+	0x2A,  0x28,  0x5C,  0x24,  0x98,  0x27,  0x34,  0x24,  0x54,  0x24,  0x92,  0x3B,  0x11,  0x20,  0x10,  0x20, 	/* 524A0 */
+	0x20,  0x20,  0xC0,  0x8B,  0x00,  0x20,  0x3C,  0x20,  0x27,  0xFF,  0x24,  0x40,  0x28,  0xFE,  0x31,  0x10, 	/* 524B0 */
+	0x2A,  0xFF,  0x24,  0x00,  0x24,  0xFC,  0x24,  0x84,  0x24,  0xFC,  0x24,  0x84,  0x38,  0xFC,  0x20,  0x84, 	/* 524C0 */
+	0x20,  0x84,  0x20,  0x8C,  0x8D,  0x00,  0x10,  0x3C,  0x20,  0x25,  0xFC,  0x29,  0x04,  0x29,  0xFC,  0x31, 	/* 524D0 */
+	0x04,  0x29,  0x04,  0x29,  0xFC,  0x24,  0x00,  0x25,  0xFE,  0x24,  0x20,  0x25,  0xFC,  0x38,  0x20,  0x20, 	/* 524E0 */
+	0x20,  0x27,  0xFF,  0x20,  0x00,  0x8E,  0x01,  0x10,  0x3D,  0x12,  0x25,  0xFC,  0x25,  0x10,  0x29,  0x10, 	/* 524F0 */
+	0x31,  0x11,  0x29,  0xCF,  0x27,  0x20,  0x24,  0xFE,  0x24,  0x82,  0x24,  0x82,  0x24,  0xFE,  0x38,  0x82, 	/* 52500 */
+	0x20,  0x82,  0x20,  0xFE,  0x20,  0x00,  0x8F,  0x00,  0x08,  0x3D,  0x08,  0x24,  0xFF,  0x24,  0x90,  0x28, 	/* 52510 */
+	0x10,  0x30,  0x1E,  0x28,  0x32,  0x27,  0xB2,  0x24,  0xDE,  0x24,  0x92,  0x24,  0x9E,  0x24,  0x92,  0x38, 	/* 52520 */
+	0xD2,  0x21,  0x56,  0x22,  0x30,  0x24,  0x0F,  0x94,  0x00,  0x00,  0x3D,  0xFE,  0x24,  0x00,  0x24,  0xFC, 	/* 52530 */
+	0x28,  0x84,  0x30,  0xFC,  0x28,  0x00,  0x25,  0xFE,  0x25,  0x2A,  0x25,  0x2A,  0x25,  0x4E,  0x25,  0x82, 	/* 52540 */
+	0x39,  0xFE,  0x21,  0x12,  0x21,  0x12,  0x21,  0x16,  0x95,  0x00,  0x00,  0x3D,  0xFC,  0x25,  0x04,  0x25, 	/* 52550 */
+	0x04,  0x29,  0xFC,  0x30,  0x00,  0x29,  0xFC,  0x25,  0x04,  0x25,  0xFC,  0x25,  0x04,  0x25,  0xFC,  0x25, 	/* 52560 */
+	0x04,  0x39,  0xFC,  0x20,  0x98,  0x23,  0x04,  0x2C,  0x02,  0x97,  0x00,  0x20,  0x3C,  0x40,  0x25,  0xFC, 	/* 52570 */
+	0x29,  0x24,  0x29,  0x24,  0x31,  0xFC,  0x29,  0x24,  0x29,  0x24,  0x25,  0xFC,  0x24,  0x52,  0x24,  0x52, 	/* 52580 */
+	0x24,  0x55,  0x38,  0x9F,  0x20,  0x90,  0x21,  0x11,  0x26,  0x0F,  0x98,  0x00,  0xB8,  0x3C,  0x88,  0x24, 	/* 52590 */
+	0x88,  0x24,  0xF4,  0x29,  0x02,  0x32,  0xB9,  0x28,  0x88,  0x29,  0x04,  0x26,  0x02,  0x25,  0xFD,  0x25, 	/* 525A0 */
+	0x54,  0x25,  0x54,  0x39,  0x54,  0x21,  0x54,  0x27,  0xFF,  0x20,  0x00,  0x99,  0x00,  0x20,  0x3C,  0xA8, 	/* 525B0 */
+	0x24,  0xA4,  0x25,  0x22,  0x2E,  0x20,  0x31,  0xFC,  0x29,  0x04,  0x29,  0xFC,  0x25,  0x04,  0x25,  0xFC, 	/* 525C0 */
+	0x24,  0x20,  0x24,  0xA8,  0x38,  0xA4,  0x21,  0x22,  0x22,  0x22,  0x20,  0x60,  0x9B,  0x00,  0x80,  0x3C, 	/* 525D0 */
+	0xFE,  0x25,  0x22,  0x25,  0xB4,  0x2A,  0x48,  0x35,  0x58,  0x28,  0xA4,  0x25,  0xFA,  0x26,  0x01,  0x24, 	/* 525E0 */
+	0x00,  0x27,  0xFE,  0x38,  0x20,  0x21,  0x28,  0x21,  0x24,  0x22,  0x22,  0x20,  0x60,  0x9C,  0x00,  0x20, 	/* 525F0 */
+	0x3C,  0x20,  0x25,  0xFE,  0x24,  0x84,  0x28,  0x48,  0x37,  0xFF,  0x28,  0x00,  0x29,  0xFC,  0x25,  0x04, 	/* 52600 */
+	0x25,  0xFC,  0x25,  0x04,  0x25,  0xFC,  0x38,  0x20,  0x23,  0xFF,  0x20,  0x20,  0x20,  0x20,  0xA0,  0x00, 	/* 52610 */
+	0x06,  0x3C,  0x1A,  0x27,  0xE2,  0x25,  0x24,  0x28,  0x98,  0x31,  0xFE,  0x28,  0x02,  0x24,  0xFE,  0x24, 	/* 52620 */
+	0x02,  0x25,  0xFE,  0x24,  0x10,  0x25,  0x4A,  0x39,  0x49,  0x21,  0x41,  0x22,  0x25,  0x20,  0x1C,  0xA3, 	/* 52630 */
+	0x00,  0x20,  0x3D,  0x24,  0x24,  0xA8,  0x27,  0xFE,  0x28,  0x70,  0x30,  0xAC,  0x2B,  0x23,  0x25,  0x24, 	/* 52640 */
+	0x25,  0xC4,  0x25,  0x7F,  0x26,  0x54,  0x25,  0x94,  0x38,  0xFF,  0x21,  0x04,  0x22,  0x04,  0x24,  0x04, 	/* 52650 */
+	0xA7,  0x00,  0x3C,  0x3A,  0x24,  0x29,  0x24,  0x29,  0x7A,  0x28,  0x91,  0x34,  0x32,  0x2A,  0xDA,  0x2A, 	/* 52660 */
+	0x2C,  0x28,  0xCC,  0x2F,  0x1A,  0x29,  0x6A,  0x29,  0x09,  0x32,  0x88,  0x22,  0x70,  0x24,  0x20,  0x28, 	/* 52670 */
+	0x1F,  0xA8,  0x00,  0x10,  0x7A,  0xFF,  0x49,  0x20,  0x51,  0x3E,  0x54,  0x48,  0x62,  0xBF,  0x52,  0x00, 	/* 52680 */
+	0x50,  0x3E,  0x4F,  0x22,  0x49,  0x3E,  0x49,  0x22,  0x49,  0x3E,  0x71,  0x22,  0x42,  0xA6,  0x44,  0x60, 	/* 52690 */
+	0x48,  0x1F,  0xAA,  0x00,  0x20,  0x3C,  0x20,  0x24,  0x50,  0x28,  0x88,  0x29,  0x04,  0x32,  0xFA,  0x28, 	/* 526A0 */
+	0x01,  0x2B,  0xDE,  0x26,  0x52,  0x26,  0x52,  0x27,  0xDE,  0x25,  0x08,  0x39,  0x08,  0x21,  0x8C,  0x22, 	/* 526B0 */
+	0x52,  0x24,  0x20,  0xB0,  0x00,  0x00,  0x3D,  0xFE,  0x25,  0x02,  0x2D,  0xFE,  0x29,  0x02,  0x31,  0xFE, 	/* 526C0 */
+	0x28,  0x84,  0x28,  0x84,  0x27,  0x5A,  0x24,  0x84,  0x25,  0x4A,  0x27,  0xFF,  0x38,  0x00,  0x21,  0x52, 	/* 526D0 */
+	0x21,  0x49,  0x22,  0x49,  0xB1,  0x00,  0x06,  0x3D,  0xF8,  0x24,  0x94,  0x24,  0x92,  0x2D,  0xFD,  0x2A, 	/* 526E0 */
+	0x20,  0x2F,  0xFF,  0x24,  0xFC,  0x24,  0x04,  0x27,  0xFF,  0x24,  0x04,  0x38,  0xFC,  0x22,  0xA0,  0x22, 	/* 526F0 */
+	0x96,  0x24,  0x85,  0x28,  0x7C,  0xB2,  0x00,  0x20,  0x3C,  0x24,  0x24,  0xA2,  0x28,  0xA6,  0x29,  0x69, 	/* 52700 */
+	0x32,  0x31,  0x28,  0xFE,  0x2B,  0x90,  0x24,  0xFC,  0x24,  0x90,  0x24,  0xFC,  0x24,  0x90,  0x38,  0xFE, 	/* 52710 */
+	0x22,  0x92,  0x22,  0x4A,  0x24,  0x0C,  0xB4,  0x00,  0x88,  0x3C,  0x88,  0x27,  0xFF,  0x29,  0x28,  0x29, 	/* 52720 */
+	0x4F,  0x37,  0xF1,  0x28,  0x0F,  0x29,  0xE8,  0x25,  0x2F,  0x25,  0xE8,  0x25,  0x2F,  0x25,  0xE8,  0x39, 	/* 52730 */
+	0x2F,  0x21,  0x28,  0x21,  0x29,  0x21,  0x67,  0xB6,  0x00,  0x80,  0x00,  0x80,  0x1F,  0xFC,  0x00,  0x84, 	/* 52740 */
+	0x7F,  0xFF,  0x00,  0x84,  0x00,  0x84,  0x1F,  0xFC,  0x20,  0x84,  0x10,  0xC4,  0x09,  0xC8,  0x0A,  0xB0, 	/* 52750 */
+	0x0C,  0x90,  0x70,  0x8C,  0x00,  0x83,  0x01,  0x80,  0xB7,  0x08,  0x10,  0x08,  0x10,  0x7F,  0x10,  0x08, 	/* 52760 */
+	0xFE,  0x3E,  0x12,  0x01,  0xFF,  0x3E,  0x12,  0x00,  0xFE,  0x7F,  0x10,  0x08,  0x92,  0x2C,  0x5C,  0x2A, 	/* 52770 */
+	0x78,  0x2A,  0x54,  0x4B,  0x92,  0x08,  0x11,  0x18,  0x30,  0xB8,  0x08,  0x10,  0x08,  0x10,  0x7E,  0xFE, 	/* 52780 */
+	0x08,  0x12,  0x1C,  0xFF,  0x2A,  0x12,  0x48,  0xFE,  0x00,  0x10,  0x3E,  0x92,  0x00,  0x54,  0x7F,  0x5C, 	/* 52790 */
+	0x08,  0x38,  0x2A,  0x54,  0x29,  0x92,  0x49,  0x11,  0x18,  0x30,  0xB9,  0x04,  0x20,  0x04,  0x20,  0x08, 	/* 527A0 */
+	0x40,  0x1F,  0xFE,  0x10,  0x80,  0x30,  0x80,  0x50,  0x80,  0x1F,  0xFC,  0x10,  0x80,  0x10,  0x80,  0x1F, 	/* 527B0 */
+	0xFC,  0x10,  0x80,  0x10,  0x80,  0x10,  0x80,  0x1F,  0xFF,  0x00,  0x00,  0xBB,  0x08,  0x20,  0x08,  0x40, 	/* 527C0 */
+	0x1F,  0xFC,  0x10,  0x80,  0x3F,  0xF8,  0x50,  0x80,  0x1F,  0xF8,  0x10,  0x80,  0x1F,  0xFE,  0x00,  0x00, 	/* 527D0 */
+	0x3F,  0xF8,  0x04,  0x10,  0x03,  0x60,  0x01,  0x80,  0x06,  0x70,  0x78,  0x0F,  0xBC,  0x04,  0x20,  0x04, 	/* 527E0 */
+	0x20,  0x08,  0x40,  0x0F,  0xFC,  0x18,  0x40,  0x2F,  0xF8,  0x48,  0x40,  0x0F,  0xF8,  0x08,  0x40,  0x0F, 	/* 527F0 */
+	0xFC,  0x00,  0x80,  0x00,  0x80,  0x7F,  0xFF,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x80,  0x00,  0x80, 	/* 52800 */
+	0x04,  0x88,  0x04,  0x84,  0x08,  0xA2,  0x10,  0xA2,  0x61,  0xC0,  0x00,  0x90,  0x03,  0x20,  0x0F,  0xFE, 	/* 52810 */
+	0x78,  0x40,  0x0F,  0xFC,  0x08,  0x40,  0x0F,  0xFC,  0x08,  0x40,  0x0F,  0xFE,  0x00,  0x00,  0x81,  0x00, 	/* 52820 */
+	0x00,  0x1F,  0xFF,  0x11,  0x20,  0x11,  0x24,  0x11,  0x48,  0x12,  0x7E,  0x12,  0xC8,  0x17,  0x48,  0x1A, 	/* 52830 */
+	0x7E,  0x12,  0x48,  0x12,  0x48,  0x12,  0x7E,  0x22,  0x48,  0x22,  0x48,  0x42,  0x7F,  0x02,  0x00,  0x84, 	/* 52840 */
+	0x08,  0x24,  0x08,  0x24,  0x08,  0x28,  0x7F,  0xFF,  0x08,  0x48,  0x0A,  0xC8,  0x0B,  0x48,  0x0A,  0x7E, 	/* 52850 */
+	0x12,  0x48,  0x14,  0x48,  0x16,  0x7E,  0x25,  0x48,  0x29,  0x48,  0x4E,  0xC8,  0x38,  0xFF,  0x00,  0x40, 	/* 52860 */
+	0x85,  0x00,  0x24,  0x3F,  0x24,  0x12,  0x48,  0x12,  0x7F,  0x12,  0xC8,  0x12,  0x48,  0x7F,  0xC8,  0x0A, 	/* 52870 */
+	0x7E,  0x0A,  0x48,  0x0A,  0x48,  0x0A,  0x7E,  0x12,  0x48,  0x12,  0x48,  0x22,  0x48,  0x42,  0x7F,  0x06, 	/* 52880 */
+	0x40,  0x86,  0x08,  0x20,  0x08,  0x40,  0x0F,  0xFE,  0x18,  0x40,  0x1F,  0xFC,  0x28,  0x40,  0x4F,  0xFC, 	/* 52890 */
+	0x08,  0x40,  0x0F,  0xFE,  0x00,  0x80,  0x7F,  0xFF,  0x01,  0xC0,  0x02,  0xA0,  0x0C,  0x98,  0x70,  0x87, 	/* 528A0 */
+	0x00,  0x80,  0x87,  0x00,  0x00,  0x7F,  0xFF,  0x00,  0x00,  0x1F,  0xFC,  0x10,  0x04,  0x1F,  0xFC,  0x12, 	/* 528B0 */
+	0x10,  0x12,  0x20,  0x17,  0xFE,  0x14,  0x20,  0x1F,  0xFC,  0x14,  0x20,  0x27,  0xFC,  0x24,  0x20,  0x47, 	/* 528C0 */
+	0xFE,  0x04,  0x00,  0x89,  0x10,  0x22,  0x10,  0x22,  0x1F,  0x44,  0x28,  0x7F,  0x28,  0xC8,  0x49,  0x48, 	/* 528D0 */
+	0x08,  0x48,  0x7F,  0x7E,  0x08,  0x48,  0x0C,  0x48,  0x14,  0x7E,  0x12,  0x48,  0x22,  0x48,  0x22,  0x48, 	/* 528E0 */
+	0x40,  0x7F,  0x00,  0x00,  0x8B,  0x04,  0x20,  0x08,  0x40,  0x1F,  0xFE,  0x30,  0x40,  0x5F,  0xFC,  0x10, 	/* 528F0 */
+	0x40,  0x1F,  0xFC,  0x10,  0x40,  0x1F,  0xFF,  0x00,  0x00,  0x3E,  0x3E,  0x22,  0x22,  0x22,  0x22,  0x23, 	/* 52900 */
+	0xE2,  0x20,  0x02,  0x20,  0x06,  0x8C,  0x0A,  0x24,  0x0A,  0x24,  0x0A,  0x48,  0x2A,  0x7F,  0x2A,  0xC8, 	/* 52910 */
+	0x2A,  0x48,  0x2E,  0xC8,  0x2B,  0x7E,  0x2A,  0x48,  0x2A,  0x48,  0x2A,  0x7E,  0x2A,  0x48,  0x2A,  0x48, 	/* 52920 */
+	0x2E,  0x48,  0x3A,  0x7F,  0x61,  0xC0,  0x8D,  0x00,  0x80,  0x00,  0x80,  0x7F,  0xFF,  0x04,  0x24,  0x04, 	/* 52930 */
+	0x28,  0x08,  0x7F,  0x32,  0xC8,  0x0E,  0x48,  0x05,  0x7E,  0x09,  0x48,  0x1F,  0x48,  0x72,  0x7E,  0x02, 	/* 52940 */
+	0x48,  0x04,  0x48,  0x08,  0x7F,  0x10,  0x00,  0x8E,  0x00,  0x24,  0x3C,  0x24,  0x24,  0x48,  0x24,  0xFF, 	/* 52950 */
+	0x25,  0x88,  0x3E,  0x88,  0x24,  0x88,  0x24,  0xFE,  0x24,  0x88,  0x3C,  0x88,  0x24,  0xFE,  0x24,  0x88, 	/* 52960 */
+	0x26,  0x88,  0x38,  0x88,  0x60,  0xFF,  0x00,  0x00,  0x91,  0x08,  0x24,  0x08,  0x24,  0x7E,  0x28,  0x0A, 	/* 52970 */
+	0x7F,  0x0A,  0x48,  0x12,  0xC8,  0x11,  0xC8,  0x28,  0x7E,  0x08,  0x48,  0x7F,  0xC8,  0x0C,  0x7E,  0x1A, 	/* 52980 */
+	0x48,  0x19,  0x48,  0x28,  0x48,  0x48,  0x7F,  0x08,  0x00,  0x95,  0x00,  0x12,  0x3F,  0x92,  0x20,  0xA4, 	/* 52990 */
+	0x24,  0xBF,  0x3E,  0xE4,  0x24,  0xA4,  0x24,  0xA4,  0x3F,  0xBE,  0x24,  0xA4,  0x2E,  0xA4,  0x2A,  0xBE, 	/* 529A0 */
+	0x2A,  0xA4,  0x2E,  0xA4,  0x20,  0xA4,  0x20,  0xBF,  0x41,  0x80,  0x96,  0x00,  0x24,  0x3F,  0x24,  0x21, 	/* 529B0 */
+	0x48,  0x21,  0x7F,  0x3F,  0xC8,  0x09,  0x48,  0x08,  0x48,  0x3F,  0x7E,  0x29,  0x48,  0x29,  0x48,  0x3F, 	/* 529C0 */
+	0x7E,  0x0A,  0x48,  0x09,  0x48,  0x09,  0x48,  0x0F,  0xFF,  0x70,  0x80,  0x99,  0x09,  0x24,  0x12,  0x28, 	/* 529D0 */
+	0x3F,  0xFF,  0x52,  0x48,  0x1F,  0x7E,  0x12,  0x48,  0x1F,  0x7E,  0x12,  0x48,  0x1F,  0xFF,  0x00,  0x00, 	/* 529E0 */
+	0x3F,  0xF8,  0x02,  0x10,  0x01,  0x20,  0x00,  0xC0,  0x07,  0x30,  0x78,  0x0F,  0x9B,  0x10,  0x24,  0x1F, 	/* 529F0 */
+	0x24,  0x31,  0x48,  0x55,  0x7F,  0x55,  0xC8,  0x7D,  0x48,  0x11,  0x48,  0x26,  0x7E,  0x10,  0x48,  0x1F, 	/* 52A00 */
+	0x48,  0x31,  0x7E,  0x55,  0x48,  0x55,  0x48,  0x7D,  0x48,  0x11,  0x7F,  0x26,  0x40,  0x9C,  0x08,  0x22, 	/* 52A10 */
+	0x08,  0x22,  0x7F,  0x24,  0x12,  0x7F,  0x12,  0xC8,  0x1A,  0x48,  0x25,  0x48,  0x48,  0x7E,  0x08,  0x48, 	/* 52A20 */
+	0x7F,  0x48,  0x08,  0x7E,  0x1C,  0x48,  0x1A,  0x48,  0x29,  0x48,  0x48,  0x7F,  0x08,  0x00,  0xA2,  0x08, 	/* 52A30 */
+	0x24,  0x08,  0x24,  0x7F,  0x48,  0x26,  0x7F,  0x3A,  0xC8,  0x2B,  0x48,  0x36,  0x48,  0x3E,  0x7E,  0x08, 	/* 52A40 */
+	0x48,  0x7F,  0x48,  0x49,  0x7E,  0x55,  0x48,  0x7B,  0x48,  0x41,  0x48,  0x41,  0x7F,  0x43,  0x40,  0xA3, 	/* 52A50 */
+	0x12,  0x24,  0x7F,  0xA4,  0x12,  0x28,  0x12,  0x7F,  0x3F,  0x48,  0x25,  0xC8,  0x25,  0x48,  0x3F,  0x7E, 	/* 52A60 */
+	0x04,  0x48,  0x3F,  0xC8,  0x04,  0x7E,  0x7F,  0xC8,  0x0A,  0x48,  0x09,  0x48,  0x10,  0xFF,  0x60,  0x00, 	/* 52A70 */
+	0xA8,  0x00,  0x00,  0x7F,  0xFF,  0x00,  0x80,  0x00,  0x80,  0x3F,  0xFE,  0x20,  0x82,  0x28,  0xA2,  0x24, 	/* 52A80 */
+	0x92,  0x24,  0x92,  0x20,  0x82,  0x28,  0xA2,  0x24,  0x92,  0x24,  0x92,  0x20,  0x82,  0x20,  0x82,  0x20, 	/* 52A90 */
+	0x06,  0xAA,  0x00,  0x00,  0x3F,  0xFC,  0x00,  0x80,  0x7F,  0xFE,  0x40,  0x82,  0x5C,  0xBA,  0x40,  0x82, 	/* 52AA0 */
+	0x1C,  0xB8,  0x00,  0x00,  0x1F,  0xF8,  0x00,  0x08,  0x0F,  0xF8,  0x00,  0x08,  0x00,  0x08,  0x1F,  0xF8, 	/* 52AB0 */
+	0x00,  0x00,  0xAB,  0x00,  0x00,  0x3F,  0xFC,  0x01,  0x00,  0x7F,  0xFE,  0x41,  0x02,  0x5D,  0x7A,  0x41, 	/* 52AC0 */
+	0x02,  0x1D,  0x78,  0x00,  0x00,  0x7F,  0xFE,  0x01,  0x00,  0x01,  0xC0,  0x01,  0x30,  0x01,  0x08,  0x01, 	/* 52AD0 */
+	0x00,  0x01,  0x00,  0xB0,  0x00,  0x00,  0x3F,  0xFC,  0x01,  0x00,  0x7F,  0xFE,  0x41,  0x02,  0x5D,  0x7A, 	/* 52AE0 */
+	0x41,  0x02,  0x1D,  0x78,  0x07,  0xE0,  0x04,  0x20,  0x08,  0x10,  0x1F,  0xE8,  0x61,  0x26,  0x02,  0x20, 	/* 52AF0 */
+	0x04,  0x20,  0x18,  0xC0,  0xB2,  0x00,  0x00,  0x3F,  0xFC,  0x01,  0x00,  0x7F,  0xFE,  0x41,  0x02,  0x5D, 	/* 52B00 */
+	0x7A,  0x41,  0x02,  0x1D,  0x78,  0x00,  0x00,  0x1F,  0xF8,  0x00,  0x00,  0x7F,  0xFE,  0x02,  0x40,  0x04, 	/* 52B10 */
+	0x30,  0x3F,  0xC8,  0x00,  0x04,  0xB6,  0x00,  0x00,  0x3F,  0xFC,  0x01,  0x00,  0x7F,  0xFE,  0x41,  0x02, 	/* 52B20 */
+	0x5D,  0x7A,  0x41,  0x02,  0x1D,  0x78,  0x02,  0x80,  0x04,  0x40,  0x1F,  0xF0,  0x60,  0x0E,  0x1F,  0xF0, 	/* 52B30 */
+	0x01,  0x10,  0x01,  0x60,  0x01,  0x00,  0xB7,  0x00,  0x00,  0x3F,  0xFC,  0x01,  0x00,  0x7F,  0xFE,  0x41, 	/* 52B40 */
+	0x02,  0x5F,  0x7A,  0x41,  0x02,  0x1F,  0x78,  0x00,  0x00,  0x3F,  0xFC,  0x21,  0x04,  0x21,  0x04,  0x3F, 	/* 52B50 */
+	0xFC,  0x21,  0x04,  0x3F,  0xFC,  0x00,  0x00,  0xB9,  0x00,  0x00,  0x3F,  0xFC,  0x00,  0x80,  0x7F,  0xFE, 	/* 52B60 */
+	0x40,  0x82,  0x5C,  0xBA,  0x4E,  0x9E,  0x08,  0x00,  0x0F,  0xFC,  0x10,  0x04,  0x1F,  0xC4,  0x28,  0x44, 	/* 52B70 */
+	0x4F,  0xD8,  0x08,  0x02,  0x08,  0x02,  0x07,  0xFE,  0xBB,  0x00,  0x00,  0x3F,  0xFC,  0x00,  0x80,  0x7F, 	/* 52B80 */
+	0xFE,  0x40,  0x82,  0x5E,  0xFA,  0x40,  0x82,  0x1E,  0xF8,  0x00,  0x00,  0x1F,  0xF8,  0x10,  0x88,  0x1F, 	/* 52B90 */
+	0xF8,  0x10,  0x88,  0x1F,  0xF9,  0x00,  0x81,  0x00,  0x7F,  0x80,  0x00,  0x00,  0x3F,  0xFC,  0x01,  0x00, 	/* 52BA0 */
+	0x7F,  0xFE,  0x41,  0x02,  0x5D,  0x7A,  0x41,  0x02,  0x1D,  0x78,  0x00,  0x00,  0x7F,  0xFE,  0x01,  0x00, 	/* 52BB0 */
+	0x3F,  0xFC,  0x22,  0x44,  0x22,  0x44,  0x22,  0x44,  0x20,  0x0C,  0x84,  0x00,  0x00,  0x3F,  0xFC,  0x00, 	/* 52BC0 */
+	0x80,  0x7F,  0xFE,  0x40,  0x82,  0x5C,  0xBA,  0x4E,  0x9E,  0x02,  0xA0,  0x04,  0x98,  0x1F,  0xF4,  0x64, 	/* 52BD0 */
+	0x12,  0x07,  0xF0,  0x04,  0x10,  0x07,  0xF0,  0x04,  0x10,  0x04,  0x30,  0x86,  0x00,  0x00,  0x3F,  0xFC, 	/* 52BE0 */
+	0x00,  0x80,  0x7F,  0xFE,  0x40,  0x82,  0x5C,  0xBA,  0x4E,  0x9E,  0x00,  0x04,  0x7C,  0x18,  0x09,  0xE0, 	/* 52BF0 */
+	0x1C,  0x20,  0x47,  0xFE,  0x24,  0x20,  0x19,  0xFC,  0x16,  0x00,  0x61,  0xFF,  0x87,  0x00,  0x00,  0x3F, 	/* 52C00 */
+	0xFC,  0x01,  0x00,  0x7F,  0xFE,  0x41,  0x02,  0x5D,  0x72,  0x4F,  0x3A,  0x01,  0x00,  0x1F,  0xFC,  0x10, 	/* 52C10 */
+	0x00,  0x1F,  0xF8,  0x10,  0x00,  0x1F,  0xFF,  0x24,  0x48,  0x27,  0x30,  0x5C,  0x0E,  0x88,  0x00,  0x00, 	/* 52C20 */
+	0x3F,  0xFC,  0x00,  0x80,  0x7F,  0xFE,  0x40,  0x82,  0x5C,  0xBA,  0x4E,  0x9E,  0x00,  0x20,  0x30,  0x20, 	/* 52C30 */
+	0x0B,  0xFF,  0x60,  0x20,  0x11,  0xFC,  0x05,  0x24,  0x09,  0x24,  0x11,  0x2C,  0x60,  0x20,  0x8A,  0x00, 	/* 52C40 */
+	0x00,  0x3F,  0xFC,  0x01,  0x00,  0x7F,  0xFE,  0x41,  0x02,  0x7D,  0x7A,  0x4F,  0x3E,  0x00,  0x00,  0x1F, 	/* 52C50 */
+	0xF8,  0x00,  0x00,  0x7F,  0xFE,  0x02,  0x48,  0x12,  0x48,  0x0A,  0x50,  0x7F,  0xFE,  0x00,  0x00,  0x8D, 	/* 52C60 */
+	0x00,  0x00,  0x3F,  0xFC,  0x00,  0x80,  0x7F,  0xFE,  0x40,  0x82,  0x5C,  0xBA,  0x4E,  0x9E,  0x04,  0x20, 	/* 52C70 */
+	0x0F,  0xFE,  0x18,  0x40,  0x2F,  0xFC,  0x48,  0x40,  0x0F,  0xFC,  0x08,  0x40,  0x0F,  0xFE,  0x00,  0x00, 	/* 52C80 */
+	0x8E,  0x00,  0x00,  0x3F,  0xFC,  0x00,  0x80,  0x7F,  0xFE,  0x40,  0x82,  0x5C,  0xBA,  0x0E,  0x9C,  0x00, 	/* 52C90 */
+	0x80,  0x1F,  0xF8,  0x04,  0x20,  0x7F,  0xFF,  0x01,  0x00,  0x3F,  0xFE,  0x06,  0x20,  0x03,  0xC0,  0x3C, 	/* 52CA0 */
+	0x38,  0x8F,  0x00,  0x00,  0x3F,  0xFC,  0x00,  0x80,  0x7F,  0xFE,  0x40,  0x82,  0x5E,  0xFA,  0x40,  0x82, 	/* 52CB0 */
+	0x1E,  0xBC,  0x02,  0x40,  0x3E,  0x7E,  0x02,  0x40,  0x3E,  0x7E,  0x07,  0x40,  0x7A,  0x7F,  0x04,  0x40, 	/* 52CC0 */
+	0x18,  0x40,  0x91,  0x00,  0x00,  0x3F,  0xFC,  0x00,  0x80,  0x7F,  0xFE,  0x40,  0x82,  0x5E,  0xFA,  0x40, 	/* 52CD0 */
+	0x82,  0x0E,  0xBC,  0x18,  0x20,  0x04,  0x3F,  0x60,  0x20,  0x11,  0xFC,  0x05,  0x04,  0x09,  0x04,  0x11, 	/* 52CE0 */
+	0xFC,  0x60,  0x00,  0x93,  0x00,  0x00,  0x3F,  0xFC,  0x00,  0x80,  0x7F,  0xFE,  0x40,  0x82,  0x5C,  0xB2, 	/* 52CF0 */
+	0x4E,  0x9E,  0x01,  0x00,  0x0E,  0x70,  0x08,  0x10,  0x0F,  0x70,  0x08,  0x10,  0x0F,  0xF2,  0x02,  0x42, 	/* 52D00 */
+	0x0C,  0x42,  0x70,  0x3E,  0x96,  0x00,  0x00,  0x3F,  0xFC,  0x00,  0x80,  0x7F,  0xFE,  0x40,  0x82,  0x5C, 	/* 52D10 */
+	0xFA,  0x40,  0x82,  0x1E,  0xBC,  0x08,  0x10,  0x7E,  0xFF,  0x0C,  0x30,  0x1A,  0x38,  0x19,  0x54,  0x28, 	/* 52D20 */
+	0x92,  0x49,  0x11,  0x08,  0x10,  0x99,  0x00,  0x00,  0x3F,  0xFC,  0x00,  0x80,  0x7F,  0xFE,  0x40,  0x82, 	/* 52D30 */
+	0x5E,  0xBA,  0x4F,  0x9E,  0x04,  0x20,  0x7F,  0xFE,  0x04,  0xA0,  0x0F,  0xF8,  0x08,  0x88,  0x7F,  0xFF, 	/* 52D40 */
+	0x01,  0x40,  0x06,  0x30,  0x78,  0x0F,  0x9C,  0x00,  0x00,  0x3F,  0xFC,  0x01,  0x00,  0x7F,  0xFE,  0x41, 	/* 52D50 */
+	0x02,  0x7D,  0x72,  0x5F,  0x3E,  0x01,  0x00,  0x08,  0x7C,  0x7F,  0x44,  0x08,  0x7C,  0x1C,  0x44,  0x1A, 	/* 52D60 */
+	0x7C,  0x29,  0x44,  0x48,  0x7C,  0x08,  0x00,  0x9E,  0x00,  0x00,  0x3F,  0xFC,  0x00,  0x80,  0x7F,  0xFE, 	/* 52D70 */
+	0x40,  0x82,  0x5C,  0xBA,  0x4E,  0x9E,  0x00,  0x00,  0x3E,  0xFC,  0x22,  0x04,  0x3E,  0xFC,  0x20,  0x00, 	/* 52D80 */
+	0x3E,  0xF8,  0x20,  0x48,  0x3E,  0x30,  0x21,  0xCE,  0xA4,  0x00,  0x00,  0x3F,  0xFC,  0x00,  0x80,  0x7F, 	/* 52D90 */
+	0xFE,  0x40,  0x82,  0x5E,  0xFA,  0x42,  0x82,  0x1C,  0xFC,  0x12,  0x24,  0x11,  0x44,  0x1F,  0xFC,  0x68, 	/* 52DA0 */
+	0x88,  0x0F,  0xF8,  0x08,  0x88,  0x0F,  0xF8,  0x00,  0x00,  0xA7,  0x00,  0x00,  0x3F,  0xFC,  0x01,  0x00, 	/* 52DB0 */
+	0x7F,  0xFE,  0x41,  0x02,  0x7D,  0x7A,  0x5F,  0x3E,  0x01,  0x40,  0x3F,  0x7E,  0x0A,  0x48,  0x04,  0xB0, 	/* 52DC0 */
+	0x7F,  0x2E,  0x0D,  0xFC,  0x16,  0x24,  0x64,  0x44,  0x0C,  0x98,  0xAA,  0x00,  0x00,  0x3F,  0xFC,  0x01, 	/* 52DD0 */
+	0x00,  0x7F,  0xFE,  0x41,  0x02,  0x5D,  0x7A,  0x41,  0x02,  0x18,  0x1C,  0x05,  0xE4,  0x60,  0x92,  0x11, 	/* 52DE0 */
+	0x7E,  0x00,  0x10,  0x07,  0xFF,  0x08,  0x10,  0x11,  0xFE,  0x60,  0x00,  0xB0,  0x00,  0x00,  0x3F,  0xFC, 	/* 52DF0 */
+	0x00,  0x80,  0x7F,  0xFE,  0x40,  0x82,  0x5E,  0xBA,  0x0F,  0x1C,  0x00,  0x20,  0x11,  0x20,  0x7F,  0xBF, 	/* 52E00 */
+	0x11,  0x64,  0x7F,  0xD4,  0x11,  0x08,  0x1F,  0x14,  0x11,  0x62,  0x13,  0x81,  0xB2,  0x00,  0x00,  0x3F, 	/* 52E10 */
+	0xFC,  0x01,  0x00,  0x7F,  0xFE,  0x41,  0x02,  0x7D,  0x7A,  0x5F,  0x3E,  0x01,  0x10,  0x3E,  0x3C,  0x22, 	/* 52E20 */
+	0x44,  0x3E,  0xA8,  0x08,  0x18,  0x2E,  0x64,  0x29,  0xFF,  0x2E,  0x44,  0x70,  0x7C,  0xB8,  0x00,  0x00, 	/* 52E30 */
+	0x3F,  0xFC,  0x01,  0x00,  0x7F,  0xFE,  0x41,  0x02,  0x7D,  0x7A,  0x0F,  0x3C,  0x12,  0x00,  0x7F,  0xBE, 	/* 52E40 */
+	0x12,  0x22,  0x3F,  0x3E,  0x25,  0x22,  0x3F,  0x3E,  0x04,  0x22,  0x7F,  0xC2,  0x04,  0x86,  0xB9,  0x00, 	/* 52E50 */
+	0x00,  0x3F,  0xFC,  0x00,  0x80,  0x7F,  0xFE,  0x40,  0x82,  0x5C,  0xBA,  0x4E,  0x9E,  0x00,  0x10,  0x1F, 	/* 52E60 */
+	0xFE,  0x11,  0x44,  0x1F,  0x28,  0x10,  0xFF,  0x2F,  0x10,  0x29,  0x7E,  0x4F,  0x10,  0x00,  0x10,  0xBD, 	/* 52E70 */
+	0x00,  0x00,  0x3F,  0xFC,  0x00,  0x80,  0x7F,  0xFE,  0x40,  0x82,  0x5C,  0xBA,  0x00,  0x80,  0x7F,  0xFE, 	/* 52E80 */
+	0x02,  0x44,  0x7D,  0xB8,  0x24,  0xA4,  0x4C,  0xB2,  0x0F,  0xF0,  0x08,  0x10,  0x0F,  0xF0,  0x10,  0x10, 	/* 52E90 */
+	0xBE,  0x00,  0x00,  0x3F,  0xFC,  0x00,  0x80,  0x7F,  0xFE,  0x40,  0x82,  0x5C,  0xBA,  0x4E,  0x9C,  0x08, 	/* 52EA0 */
+	0x00,  0x72,  0xFC,  0x2C,  0xA4,  0x70,  0xFC,  0x18,  0xA4,  0x6D,  0xFE,  0x14,  0x20,  0x67,  0xFF,  0x18, 	/* 52EB0 */
+	0x00,  0x82,  0x00,  0x00,  0x3F,  0xFC,  0x01,  0x00,  0x7F,  0xFE,  0x41,  0x02,  0x5D,  0x7A,  0x00,  0x00, 	/* 52EC0 */
+	0x1F,  0xFE,  0x17,  0x38,  0x12,  0x10,  0x1F,  0xFE,  0x17,  0x34,  0x1A,  0xD2,  0x24,  0x7C,  0x24,  0x40, 	/* 52ED0 */
+	0x5F,  0xFF,  0x84,  0x00,  0x00,  0x3F,  0xFC,  0x01,  0x00,  0x7F,  0xFE,  0x41,  0x02,  0x5D,  0x7A,  0x01, 	/* 52EE0 */
+	0x00,  0x3E,  0x7C,  0x00,  0x44,  0x7F,  0x7C,  0x00,  0x20,  0x3E,  0xFE,  0x01,  0x52,  0x3E,  0x6A,  0x22, 	/* 52EF0 */
+	0x7A,  0x3E,  0x0C,  0x86,  0x00,  0x08,  0x7F,  0x08,  0x08,  0xBE,  0x7F,  0x4A,  0x49,  0x7F,  0x6D,  0x0A, 	/* 52F00 */
+	0x49,  0xBE,  0x2C,  0x49,  0x00,  0x4E,  0x3E,  0x2C,  0x01,  0xDA,  0x7F,  0x6A,  0x08,  0x49,  0x14,  0x58, 	/* 52F10 */
+	0x7A,  0xA0,  0x03,  0x1F,  0x88,  0x00,  0x00,  0x3F,  0xFC,  0x00,  0x80,  0x7F,  0xFE,  0x40,  0x82,  0x5C, 	/* 52F20 */
+	0xBA,  0x4E,  0x9C,  0x00,  0x00,  0x7B,  0xDE,  0x4A,  0x52,  0x7B,  0xDE,  0x00,  0x00,  0x3F,  0xFC,  0x08, 	/* 52F30 */
+	0x90,  0x14,  0xA8,  0x7F,  0xFF,  0x89,  0x00,  0x02,  0x7F,  0x3C,  0x08,  0x4A,  0x7F,  0x24,  0x49,  0xFF, 	/* 52F40 */
+	0x6D,  0x91,  0x49,  0x2A,  0x2C,  0xA5,  0x01,  0x1D,  0x3E,  0x10,  0x00,  0x3C,  0x7F,  0x44,  0x08,  0xA8, 	/* 52F50 */
+	0x14,  0x18,  0x7A,  0x64,  0x03,  0x83,  0x92,  0x00,  0x80,  0x00,  0x80,  0x1F,  0xFE,  0x00,  0x80,  0x1F, 	/* 52F60 */
+	0xFC,  0x00,  0x80,  0x7F,  0xFF,  0x00,  0x00,  0x07,  0xF8,  0x04,  0x08,  0x07,  0xF8,  0x04,  0x08,  0x07, 	/* 52F70 */
+	0xF8,  0x04,  0x08,  0x04,  0x08,  0x04,  0x18,  0x96,  0x00,  0x10,  0x08,  0x10,  0x09,  0xFE,  0x08,  0x10, 	/* 52F80 */
+	0x7F,  0xFC,  0x02,  0x10,  0x23,  0xFF,  0x12,  0x00,  0x12,  0xFC,  0x14,  0x84,  0x14,  0xFC,  0x0B,  0x84, 	/* 52F90 */
+	0x1C,  0xFC,  0x60,  0x84,  0x00,  0x84,  0x00,  0x8C,  0x99,  0x08,  0x20,  0x08,  0x38,  0x7F,  0x48,  0x08, 	/* 52FA0 */
+	0x90,  0x3F,  0x20,  0x08,  0xFC,  0x7F,  0x24,  0x00,  0x24,  0x3F,  0xFF,  0x22,  0x24,  0x3E,  0x24,  0x22, 	/* 52FB0 */
+	0xFC,  0x3E,  0x20,  0x22,  0x20,  0x22,  0x20,  0x26,  0x60,  0x9C,  0x08,  0x04,  0x08,  0xF8,  0x7F,  0x64, 	/* 52FC0 */
+	0x08,  0x52,  0x3E,  0x92,  0x09,  0x02,  0x7F,  0xFC,  0x00,  0x14,  0x3E,  0xFF,  0x2A,  0x14,  0x2A,  0x14, 	/* 52FD0 */
+	0x3E,  0xFC,  0x22,  0x10,  0x22,  0x10,  0x22,  0x10,  0x26,  0x30,  0x9E,  0x02,  0x20,  0x02,  0x20,  0x02, 	/* 52FE0 */
+	0x20,  0x3E,  0x3E,  0x02,  0x20,  0x02,  0x20,  0x02,  0x20,  0x3E,  0x3E,  0x02,  0x20,  0x02,  0x20,  0x0E, 	/* 52FF0 */
+	0x20,  0x72,  0x3F,  0x04,  0x20,  0x04,  0x20,  0x08,  0x20,  0x10,  0x20,  0xA0,  0x08,  0x80,  0x0F,  0xFC, 	/* 53000 */
+	0x10,  0x80,  0x7F,  0xFF,  0x00,  0x00,  0x0F,  0xF8,  0x08,  0x08,  0x0F,  0xF8,  0x01,  0x20,  0x3F,  0x3E, 	/* 53010 */
+	0x01,  0x20,  0x3F,  0x3E,  0x03,  0xA0,  0x7E,  0x3F,  0x04,  0x20,  0x18,  0x20,  0xA1,  0x00,  0x80,  0x1F, 	/* 53020 */
+	0xFF,  0x11,  0x08,  0x1F,  0xFF,  0x11,  0x4A,  0x15,  0x5A,  0x15,  0x5B,  0x19,  0x28,  0x10,  0xA0,  0x1F, 	/* 53030 */
+	0xBE,  0x10,  0xA0,  0x17,  0xBC,  0x20,  0xA0,  0x3F,  0x3F,  0x41,  0x20,  0x02,  0x20,  0xA2,  0x00,  0x00, 	/* 53040 */
+	0x7F,  0xFF,  0x01,  0x00,  0x01,  0x00,  0x02,  0x00,  0x3F,  0xFE,  0x22,  0x22,  0x22,  0x22,  0x23,  0xE2, 	/* 53050 */
+	0x22,  0x22,  0x23,  0xE2,  0x22,  0x22,  0x22,  0x22,  0x22,  0x22,  0x3F,  0xFE,  0x00,  0x00,  0xA4,  0x00, 	/* 53060 */
+	0x20,  0x7F,  0x20,  0x08,  0x7E,  0x08,  0x42,  0x10,  0x82,  0x7F,  0xF2,  0x55,  0x52,  0x55,  0x52,  0x5D, 	/* 53070 */
+	0x52,  0x55,  0x72,  0x55,  0x42,  0x5D,  0x4C,  0x55,  0x40,  0x55,  0x41,  0x7F,  0x21,  0x00,  0x1F,  0xA6, 	/* 53080 */
+	0x00,  0x00,  0x7F,  0xFE,  0x04,  0x22,  0x04,  0x22,  0x08,  0x3E,  0x3F,  0xA2,  0x2A,  0xA2,  0x2A,  0xBE, 	/* 53090 */
+	0x2E,  0xA2,  0x2A,  0xA2,  0x2A,  0xBE,  0x2E,  0x94,  0x2A,  0x94,  0x2A,  0xA5,  0x3F,  0xC5,  0x00,  0x83, 	/* 530A0 */
+	0xA8,  0x00,  0x00,  0x1F,  0xFF,  0x18,  0x94,  0x1F,  0x92,  0x14,  0xFF,  0x17,  0x98,  0x24,  0x94,  0x27, 	/* 530B0 */
+	0xA2,  0x44,  0xC0,  0x7F,  0xFF,  0x01,  0x00,  0x1F,  0xFC,  0x13,  0xE4,  0x12,  0x24,  0x1F,  0xFC,  0x00, 	/* 530C0 */
+	0x00,  0xA9,  0x02,  0x20,  0x02,  0x20,  0x3F,  0xFE,  0x02,  0x20,  0x02,  0x20,  0x03,  0xE0,  0x00,  0x80, 	/* 530D0 */
+	0x0F,  0xF8,  0x08,  0x88,  0x08,  0x88,  0x0F,  0xF8,  0x00,  0x80,  0x7F,  0xFF,  0x00,  0x80,  0x00,  0x80, 	/* 530E0 */
+	0x00,  0x80,  0xAB,  0x12,  0x00,  0x12,  0x7E,  0x7F,  0x82,  0x12,  0x32,  0x12,  0x2A,  0x1E,  0x2A,  0x08, 	/* 530F0 */
+	0x22,  0x3F,  0x24,  0x29,  0x14,  0x29,  0x18,  0x3F,  0x08,  0x08,  0x18,  0x7F,  0x94,  0x08,  0x24,  0x08, 	/* 53100 */
+	0xC2,  0x0B,  0x01,  0xAD,  0x12,  0x00,  0x12,  0xFE,  0x7F,  0x92,  0x12,  0x12,  0x12,  0x12,  0x1E,  0x12, 	/* 53110 */
+	0x08,  0x72,  0x3F,  0x1A,  0x29,  0x16,  0x29,  0x12,  0x3F,  0x12,  0x08,  0x22,  0x7F,  0xA2,  0x08,  0x42, 	/* 53120 */
+	0x08,  0x84,  0x09,  0x18,  0xB1,  0x12,  0x00,  0x12,  0xFE,  0x7F,  0x12,  0x12,  0x12,  0x12,  0x52,  0x1E, 	/* 53130 */
+	0x32,  0x08,  0x12,  0x3F,  0x1A,  0x29,  0x16,  0x29,  0x13,  0x3F,  0x12,  0x08,  0x22,  0x7F,  0xA2,  0x08, 	/* 53140 */
+	0x42,  0x08,  0x82,  0x09,  0x0C,  0xB4,  0x12,  0x30,  0x12,  0x30,  0x7F,  0xB0,  0x12,  0x52,  0x12,  0x52, 	/* 53150 */
+	0x1E,  0x54,  0x08,  0xD8,  0x3F,  0x50,  0x29,  0x50,  0x29,  0x50,  0x3F,  0x50,  0x08,  0x51,  0x7F,  0xD1, 	/* 53160 */
+	0x08,  0x51,  0x08,  0x4F,  0x08,  0x40,  0xB9,  0x12,  0x30,  0x12,  0x10,  0x7F,  0x90,  0x12,  0x7E,  0x12, 	/* 53170 */
+	0x52,  0x1E,  0x52,  0x08,  0x52,  0x3F,  0x52,  0x29,  0x6A,  0x29,  0x6A,  0x3F,  0x46,  0x08,  0x42,  0x7F, 	/* 53180 */
+	0x42,  0x08,  0x42,  0x08,  0x42,  0x08,  0x46,  0xBA,  0x12,  0x10,  0x12,  0x10,  0x7F,  0x90,  0x12,  0xFF, 	/* 53190 */
+	0x12,  0x10,  0x1E,  0x10,  0x08,  0x10,  0x3F,  0x7E,  0x29,  0x10,  0x29,  0x38,  0x3F,  0x38,  0x08,  0x54, 	/* 531A0 */
+	0x7F,  0xD2,  0x08,  0x91,  0x09,  0x10,  0x08,  0x10,  0xBC,  0x12,  0x00,  0x12,  0x3E,  0x7F,  0xA2,  0x12, 	/* 531B0 */
+	0x22,  0x12,  0x22,  0x1E,  0x3E,  0x08,  0x22,  0x3F,  0x22,  0x29,  0x22,  0x29,  0x22,  0x3F,  0x3E,  0x08, 	/* 531C0 */
+	0x00,  0x7F,  0x80,  0x08,  0x00,  0x08,  0xFF,  0x08,  0x00,  0x81,  0x14,  0x10,  0x14,  0x10,  0x7F,  0x10, 	/* 531D0 */
+	0x14,  0xFF,  0x14,  0x91,  0x1C,  0x92,  0x08,  0x90,  0x3E,  0xFE,  0x2A,  0xA2,  0x2A,  0xA2,  0x3E,  0x94, 	/* 531E0 */
+	0x08,  0x98,  0x7F,  0x88,  0x09,  0x14,  0x09,  0x22,  0x0A,  0xC1,  0x84,  0x12,  0x20,  0x12,  0x20,  0x7F, 	/* 531F0 */
+	0x20,  0x12,  0x7E,  0x12,  0x42,  0x1E,  0x7A,  0x08,  0x8A,  0x3F,  0x0A,  0x29,  0x7A,  0x29,  0x42,  0x3F, 	/* 53200 */
+	0x42,  0x08,  0x4C,  0x7F,  0xC0,  0x08,  0x41,  0x08,  0x41,  0x08,  0x3F,  0x85,  0x12,  0x10,  0x12,  0x10, 	/* 53210 */
+	0x7F,  0x90,  0x12,  0x7E,  0x12,  0x52,  0x1E,  0x52,  0x08,  0x52,  0x3F,  0x52,  0x29,  0xFF,  0x29,  0x10, 	/* 53220 */
+	0x3F,  0x18,  0x08,  0x28,  0x7F,  0x24,  0x08,  0x44,  0x08,  0x82,  0x09,  0x01,  0x86,  0x12,  0x00,  0x12, 	/* 53230 */
+	0xFF,  0x7F,  0x90,  0x12,  0x10,  0x12,  0x10,  0x1E,  0x7E,  0x08,  0x52,  0x3F,  0x52,  0x29,  0x52,  0x29, 	/* 53240 */
+	0x6A,  0x3F,  0x6A,  0x08,  0x46,  0x7F,  0x42,  0x08,  0x42,  0x08,  0x42,  0x08,  0x46,  0x8B,  0x12,  0x08, 	/* 53250 */
+	0x12,  0x08,  0x7F,  0xBE,  0x12,  0x08,  0x12,  0x08,  0x1E,  0x08,  0x08,  0xFF,  0x3F,  0x00,  0x29,  0x08, 	/* 53260 */
+	0x29,  0x08,  0x3F,  0x7E,  0x08,  0x08,  0x7F,  0x08,  0x08,  0x08,  0x08,  0xFF,  0x08,  0x00,  0x8D,  0x12, 	/* 53270 */
+	0x10,  0x12,  0x10,  0x7F,  0xFE,  0x12,  0x82,  0x12,  0xA2,  0x1E,  0x20,  0x08,  0x20,  0x3F,  0xFF,  0x29, 	/* 53280 */
+	0x24,  0x29,  0x24,  0x3F,  0x44,  0x08,  0x68,  0x7F,  0x98,  0x08,  0x24,  0x08,  0x42,  0x09,  0x82,  0x8F, 	/* 53290 */
+	0x00,  0x00,  0x7F,  0x7C,  0x08,  0x44,  0x08,  0x65,  0x0E,  0x55,  0x70,  0x93,  0x02,  0x21,  0x3F,  0xFE, 	/* 532A0 */
+	0x02,  0x20,  0x03,  0xE0,  0x0F,  0xF8,  0x08,  0x88,  0x0F,  0xF8,  0x00,  0x80,  0x7F,  0xFF,  0x00,  0x80, 	/* 532B0 */
+	0x90,  0x12,  0x10,  0x12,  0x10,  0x7F,  0x90,  0x12,  0x1E,  0x12,  0x10,  0x1E,  0x10,  0x08,  0xFF,  0x3F, 	/* 532C0 */
+	0x00,  0x29,  0x00,  0x29,  0xFF,  0x3F,  0x10,  0x08,  0x18,  0x7F,  0x94,  0x08,  0x12,  0x08,  0x10,  0x08, 	/* 532D0 */
+	0x10,  0x98,  0x12,  0x10,  0x12,  0x92,  0x7F,  0x52,  0x12,  0x54,  0x1E,  0x10,  0x08,  0x7E,  0x3F,  0x42, 	/* 532E0 */
+	0x29,  0x42,  0x29,  0x7E,  0x3F,  0x42,  0x08,  0x42,  0x7F,  0xFE,  0x08,  0x42,  0x08,  0x42,  0x08,  0x42, 	/* 532F0 */
+	0x08,  0x46,  0x9C,  0x12,  0x10,  0x12,  0x12,  0x7F,  0xFC,  0x12,  0x38,  0x12,  0x34,  0x1E,  0x52,  0x08, 	/* 53300 */
+	0x91,  0x3F,  0x30,  0x29,  0x00,  0x29,  0x7C,  0x3F,  0x44,  0x08,  0x44,  0x7F,  0x7C,  0x08,  0x44,  0x08, 	/* 53310 */
+	0x7C,  0x08,  0x00,  0xA0,  0x14,  0x40,  0x14,  0x40,  0x7E,  0xFE,  0x14,  0x82,  0x15,  0x2A,  0x1E,  0xAA, 	/* 53320 */
+	0x08,  0xB2,  0x3F,  0xFE,  0x2A,  0x22,  0x2A,  0x72,  0x3E,  0x6A,  0x08,  0xA6,  0x7F,  0xA2,  0x09,  0x22, 	/* 53330 */
+	0x08,  0x24,  0x08,  0x18,  0xA3,  0x14,  0x00,  0x14,  0x7E,  0x7F,  0x24,  0x14,  0x18,  0x15,  0xFF,  0x1C, 	/* 53340 */
+	0x32,  0x08,  0x54,  0x3E,  0x90,  0x2A,  0x30,  0x2A,  0x10,  0x3F,  0xFF,  0x08,  0x38,  0x7F,  0x54,  0x08, 	/* 53350 */
+	0x92,  0x09,  0x11,  0x08,  0x10,  0xA6,  0x14,  0x28,  0x14,  0xC8,  0x7F,  0x88,  0x14,  0x8A,  0x14,  0x8A, 	/* 53360 */
+	0x1D,  0xFC,  0x08,  0x9C,  0x3E,  0xD8,  0x2A,  0xC8,  0x2B,  0xAC,  0x3E,  0x94,  0x08,  0x94,  0x7F,  0xA4, 	/* 53370 */
+	0x08,  0xA2,  0x08,  0xC2,  0x08,  0x81,  0xA8,  0x12,  0x00,  0x12,  0x7C,  0x7F,  0x44,  0x12,  0x7C,  0x12, 	/* 53380 */
+	0x44,  0x1E,  0x44,  0x08,  0x7C,  0x3F,  0x20,  0x29,  0x3E,  0x29,  0x52,  0x3F,  0xDA,  0x08,  0x6A,  0x7F, 	/* 53390 */
+	0x42,  0x08,  0x7A,  0x08,  0x02,  0x08,  0x0C,  0xAB,  0x14,  0x40,  0x14,  0x40,  0x7E,  0xFE,  0x14,  0x82, 	/* 533A0 */
+	0x15,  0x7A,  0x1C,  0x02,  0x08,  0xFE,  0x3E,  0x02,  0x2A,  0x7A,  0x2A,  0x02,  0x3E,  0x7A,  0x08,  0x02, 	/* 533B0 */
+	0x7F,  0x7A,  0x08,  0x4A,  0x08,  0x7A,  0x08,  0x0C,  0xAD,  0x14,  0x40,  0x14,  0x7F,  0x7F,  0x48,  0x14, 	/* 533C0 */
+	0x7E,  0x14,  0xAA,  0x1C,  0xAA,  0x09,  0xBE,  0x3E,  0xAA,  0x2A,  0xAA,  0x2A,  0xBE,  0x3E,  0x88,  0x08, 	/* 533D0 */
+	0xA8,  0x7F,  0x98,  0x08,  0x94,  0x08,  0xA2,  0x08,  0xC1,  0xB3,  0x14,  0x44,  0x14,  0x44,  0x7F,  0xFF, 	/* 533E0 */
+	0x14,  0x54,  0x14,  0x10,  0x1C,  0x28,  0x08,  0x44,  0x3E,  0xFA,  0x2B,  0x01,  0x2A,  0x00,  0x3E,  0xFC, 	/* 533F0 */
+	0x08,  0x84,  0x7F,  0x84,  0x08,  0x84,  0x08,  0xFC,  0x08,  0x00,  0xB4,  0x14,  0x24,  0x14,  0x24,  0x7F, 	/* 53400 */
+	0xFF,  0x14,  0x24,  0x14,  0x00,  0x1C,  0xFF,  0x08,  0x80,  0x3E,  0xFE,  0x2A,  0xD2,  0x2A,  0xFE,  0x3E, 	/* 53410 */
+	0xD2,  0x08,  0xD2,  0x7F,  0x7E,  0x09,  0x52,  0x0A,  0x52,  0x08,  0x56,  0x83,  0x14,  0x08,  0x15,  0x08, 	/* 53420 */
+	0x7E,  0xBE,  0x14,  0x88,  0x14,  0x7F,  0x1D,  0x22,  0x08,  0x94,  0x3E,  0xFE,  0x2A,  0x08,  0x2B,  0xBE, 	/* 53430 */
+	0x3E,  0x88,  0x08,  0xFF,  0x7E,  0x88,  0x09,  0x48,  0x09,  0x30,  0x0A,  0x0F,  0x86,  0x14,  0x00,  0x15, 	/* 53440 */
+	0x7F,  0x7E,  0x94,  0x14,  0xBE,  0x14,  0x2A,  0x1D,  0x3E,  0x08,  0x90,  0x3E,  0xFF,  0x2A,  0x14,  0x2B, 	/* 53450 */
+	0xBE,  0x3E,  0xC5,  0x08,  0x9C,  0x7E,  0x92,  0x09,  0x4E,  0x09,  0x30,  0x0A,  0x0F,  0x88,  0x14,  0x44, 	/* 53460 */
+	0x14,  0x44,  0x7F,  0xFF,  0x14,  0x44,  0x14,  0xFE,  0x1C,  0xAA,  0x08,  0xFE,  0x3E,  0x0C,  0x2A,  0x0A, 	/* 53470 */
+	0x2A,  0xFF,  0x3E,  0x88,  0x08,  0xCA,  0x7F,  0xA4,  0x08,  0xAD,  0x09,  0x13,  0x0A,  0x21,  0x8B,  0x01, 	/* 53480 */
+	0x00,  0x1F,  0xF8,  0x02,  0x08,  0x02,  0x08,  0x7F,  0xFF,  0x00,  0x00,  0x0F,  0xF8,  0x08,  0x08,  0x0F, 	/* 53490 */
+	0xF8,  0x00,  0x20,  0x0F,  0xFE,  0x08,  0x20,  0x08,  0x20,  0x7F,  0xFF,  0x00,  0x20,  0x00,  0x20,  0x93, 	/* 534A0 */
+	0x08,  0x10,  0x08,  0xFC,  0x7F,  0x24,  0x08,  0x24,  0x3F,  0xFF,  0x22,  0x00,  0x22,  0xFC,  0x3E,  0x84, 	/* 534B0 */
+	0x22,  0xFE,  0x22,  0x08,  0x3E,  0x7E,  0x08,  0x48,  0x7F,  0x48,  0x09,  0xFF,  0x08,  0x08,  0x08,  0x08, 	/* 534C0 */
+	0x9C,  0x04,  0x02,  0x3F,  0x0C,  0x09,  0x74,  0x09,  0x52,  0x7F,  0xC9,  0x00,  0x89,  0x1F,  0x00,  0x11, 	/* 534D0 */
+	0x10,  0x1F,  0x66,  0x02,  0x42,  0x1F,  0xC2,  0x12,  0x76,  0x12,  0x42,  0x7F,  0xC2,  0x02,  0x7E,  0x02, 	/* 534E0 */
+	0x00,  0xAD,  0x02,  0x20,  0x02,  0x20,  0x3E,  0x3E,  0x02,  0x20,  0x02,  0x20,  0x02,  0x20,  0x3E,  0x3E, 	/* 534F0 */
+	0x02,  0x20,  0x02,  0x20,  0x02,  0x20,  0x3E,  0x3E,  0x02,  0x20,  0x02,  0x20,  0x02,  0x20,  0x7F,  0xFF, 	/* 53500 */
+	0x00,  0x00,  0xAE,  0x02,  0x20,  0x02,  0x20,  0x7F,  0xFF,  0x02,  0x20,  0x00,  0x00,  0x02,  0x20,  0x3E, 	/* 53510 */
+	0x3E,  0x02,  0x20,  0x3E,  0x3E,  0x02,  0x20,  0x02,  0x20,  0x3E,  0x3E,  0x02,  0x20,  0x02,  0x20,  0x7F, 	/* 53520 */
+	0xFF,  0x00,  0x00,  0xB2,  0x00,  0x80,  0x7F,  0xFF,  0x02,  0x22,  0x7D,  0x5C,  0x14,  0x94,  0x24,  0x92, 	/* 53530 */
+	0x4C,  0x19,  0x01,  0x20,  0x3F,  0x3E,  0x01,  0x20,  0x1F,  0x3C,  0x01,  0x20,  0x1F,  0x3C,  0x01,  0x20, 	/* 53540 */
+	0x7F,  0xFF,  0x00,  0x00,  0xB3,  0x00,  0x80,  0x00,  0x80,  0x3F,  0xFE,  0x04,  0x10,  0x02,  0x10,  0x02, 	/* 53550 */
+	0x20,  0x7F,  0xFF,  0x00,  0x00,  0x07,  0xF0,  0x04,  0x10,  0x04,  0x10,  0x07,  0xF0,  0x04,  0x10,  0x04, 	/* 53560 */
+	0x10,  0x07,  0xF0,  0x00,  0x00,  0xB5,  0x08,  0x20,  0x08,  0x20,  0x7F,  0xA0,  0x22,  0x3E,  0x12,  0x42, 	/* 53570 */
+	0x14,  0x42,  0x7F,  0xBA,  0x00,  0x02,  0x3E,  0x02,  0x22,  0x0A,  0x22,  0x32,  0x3E,  0xC2,  0x22,  0x02, 	/* 53580 */
+	0x22,  0x02,  0x3E,  0x04,  0x00,  0x18,  0xB6,  0x08,  0x00,  0x08,  0xFE,  0x7F,  0x12,  0x22,  0x12,  0x12, 	/* 53590 */
+	0x12,  0x14,  0x22,  0x7F,  0xA2,  0x00,  0x4C,  0x3E,  0x80,  0x22,  0x7E,  0x22,  0x42,  0x3E,  0x42,  0x22, 	/* 535A0 */
+	0x42,  0x22,  0x42,  0x3E,  0x7E,  0x00,  0x00,  0xBB,  0x08,  0x00,  0x08,  0xFC,  0x7F,  0x84,  0x22,  0x84, 	/* 535B0 */
+	0x12,  0xFC,  0x14,  0x00,  0x7F,  0xFC,  0x00,  0x84,  0x3E,  0xFC,  0x22,  0x84,  0x22,  0xFC,  0x3E,  0x84, 	/* 535C0 */
+	0x22,  0xFC,  0x22,  0x48,  0x3E,  0x84,  0x03,  0x02,  0xBF,  0x11,  0xEE,  0x65,  0x2A,  0x29,  0xEA,  0x11, 	/* 535D0 */
+	0x2C,  0x1D,  0xEA,  0x65,  0x49,  0x09,  0xE9,  0x13,  0x2E,  0x20,  0x88,  0x5F,  0xFE,  0x02,  0x20,  0x7F, 	/* 535E0 */
+	0xFF,  0x04,  0x10,  0x07,  0xF0,  0x04,  0x10,  0x07,  0xF0,  0x81,  0x00,  0x00,  0x7F,  0xFE,  0x01,  0x00, 	/* 535F0 */
+	0x02,  0x00,  0x0F,  0xF0,  0x08,  0x10,  0x08,  0x10,  0x0F,  0xF0,  0x08,  0x10,  0x0F,  0xF0,  0x08,  0x10, 	/* 53600 */
+	0x08,  0x10,  0x0F,  0xF0,  0x02,  0x20,  0x0C,  0x18,  0x30,  0x04,  0x82,  0x00,  0x00,  0x03,  0xFF,  0x7E, 	/* 53610 */
+	0x20,  0x10,  0x40,  0x11,  0xFC,  0x11,  0x04,  0x11,  0x04,  0x11,  0xFC,  0x11,  0x04,  0x11,  0xFC,  0x11, 	/* 53620 */
+	0x04,  0x11,  0x04,  0x11,  0xFC,  0x10,  0x48,  0x31,  0x84,  0x06,  0x02,  0x83,  0x00,  0x00,  0x23,  0xFF, 	/* 53630 */
+	0x20,  0x20,  0x20,  0x40,  0x26,  0xFE,  0x38,  0x82,  0x20,  0x82,  0x20,  0xFE,  0x20,  0x82,  0x20,  0xFE, 	/* 53640 */
+	0x22,  0x82,  0x22,  0x82,  0x1E,  0xFE,  0x00,  0x44,  0x01,  0x82,  0x06,  0x01,  0x85,  0x00,  0x00,  0x03, 	/* 53650 */
+	0xFF,  0x00,  0x10,  0x7E,  0x20,  0x08,  0xFE,  0x08,  0x82,  0x08,  0x82,  0x08,  0xFE,  0x08,  0x82,  0x0A, 	/* 53660 */
+	0xFE,  0x0C,  0x82,  0x18,  0x82,  0x60,  0xFE,  0x00,  0x4C,  0x01,  0x82,  0x06,  0x01,  0x86,  0x00,  0x00, 	/* 53670 */
+	0x2B,  0xFF,  0x2A,  0x10,  0x2A,  0x20,  0x2A,  0x7E,  0x2A,  0x42,  0x2A,  0x42,  0x2A,  0x7E,  0x2A,  0x42, 	/* 53680 */
+	0x2A,  0x7E,  0x2A,  0x42,  0x2A,  0x42,  0x2A,  0x7E,  0x22,  0x2C,  0x22,  0xC2,  0x43,  0x01,  0x88,  0x08, 	/* 53690 */
+	0x00,  0x0B,  0xFF,  0x10,  0x10,  0x20,  0x20,  0x44,  0xFE,  0x04,  0x82,  0x08,  0x82,  0x08,  0xFE,  0x12, 	/* 536A0 */
+	0x82,  0x22,  0xFE,  0x44,  0x82,  0x04,  0x82,  0x08,  0xFE,  0x10,  0x24,  0x20,  0xC2,  0x43,  0x01,  0x8C, 	/* 536B0 */
+	0x0E,  0x00,  0x02,  0xFF,  0x12,  0x10,  0x12,  0x20,  0x11,  0x7E,  0x21,  0x42,  0x28,  0xC2,  0x48,  0x7E, 	/* 536C0 */
+	0x08,  0x42,  0x0C,  0x7E,  0x0A,  0x42,  0x12,  0x42,  0x15,  0x7E,  0x79,  0x24,  0x00,  0xC2,  0x03,  0x01, 	/* 536D0 */
+	0x8F,  0x08,  0x00,  0x08,  0xFF,  0x08,  0x10,  0x7F,  0xA0,  0x00,  0x7E,  0x1E,  0x42,  0x12,  0x42,  0x12, 	/* 536E0 */
+	0x7E,  0x12,  0x42,  0x12,  0x7E,  0x12,  0x42,  0x12,  0xC2,  0x11,  0xFE,  0x20,  0xA4,  0x40,  0x42,  0x01, 	/* 536F0 */
+	0x81,  0x90,  0x00,  0x00,  0x7F,  0xFF,  0x02,  0x10,  0x34,  0x20,  0x08,  0x7E,  0x08,  0x42,  0x7F,  0x42, 	/* 53700 */
+	0x09,  0x7E,  0x0A,  0x42,  0x0C,  0x7E,  0x08,  0x42,  0x08,  0x42,  0x08,  0x7E,  0x08,  0x14,  0x08,  0x62, 	/* 53710 */
+	0x19,  0x81,  0x91,  0x00,  0x00,  0x01,  0xFF,  0x3E,  0x10,  0x00,  0x20,  0x00,  0xFE,  0x00,  0x82,  0x7F, 	/* 53720 */
+	0x82,  0x14,  0xFE,  0x14,  0x82,  0x14,  0xFE,  0x14,  0x82,  0x15,  0x82,  0x26,  0xFE,  0x24,  0x24,  0x40, 	/* 53730 */
+	0xC2,  0x03,  0x01,  0x92,  0x00,  0x00,  0x0E,  0xFF,  0x02,  0x10,  0x12,  0x20,  0x11,  0x7E,  0x11,  0x42, 	/* 53740 */
+	0x20,  0xC2,  0x3F,  0x7E,  0x49,  0x42,  0x09,  0x7E,  0x09,  0x42,  0x11,  0x42,  0x11,  0x7E,  0x21,  0x24, 	/* 53750 */
+	0x46,  0x42,  0x01,  0x81,  0x93,  0x08,  0x00,  0x09,  0xFF,  0x0F,  0x10,  0x78,  0x20,  0x08,  0x7E,  0x2A, 	/* 53760 */
+	0x42,  0x2A,  0x7E,  0x2A,  0x42,  0x2A,  0x42,  0x2A,  0x7E,  0x3E,  0x42,  0x08,  0x42,  0x08,  0x7E,  0x09, 	/* 53770 */
+	0x24,  0x07,  0x42,  0x01,  0x81,  0x97,  0x04,  0x00,  0x04,  0xFF,  0x04,  0x10,  0x3F,  0xA0,  0x25,  0x7E, 	/* 53780 */
+	0x24,  0x42,  0x3F,  0x42,  0x29,  0x7E,  0x29,  0x42,  0x25,  0x7E,  0x26,  0x42,  0x22,  0x42,  0x25,  0x7E, 	/* 53790 */
+	0x49,  0x24,  0x10,  0x42,  0x21,  0x81,  0x98,  0x08,  0x00,  0x08,  0xFF,  0x14,  0x10,  0x12,  0x20,  0x21, 	/* 537A0 */
+	0x7E,  0x5E,  0x42,  0x00,  0x7E,  0x00,  0x42,  0x7E,  0x42,  0x12,  0x7E,  0x12,  0x42,  0x12,  0x42,  0x12, 	/* 537B0 */
+	0x7E,  0x14,  0x24,  0x10,  0x42,  0x11,  0x81,  0x9A,  0x00,  0x00,  0x7E,  0xFF,  0x22,  0x10,  0x14,  0x20, 	/* 537C0 */
+	0x08,  0x7E,  0x08,  0x42,  0x14,  0x42,  0x22,  0x7E,  0x49,  0x42,  0x08,  0x7E,  0x3E,  0x42,  0x08,  0x42, 	/* 537D0 */
+	0x09,  0x7E,  0x0E,  0x24,  0x70,  0x42,  0x01,  0x81,  0xA1,  0x08,  0x00,  0x09,  0xFF,  0x08,  0x10,  0x7F, 	/* 537E0 */
+	0x20,  0x08,  0x7E,  0x08,  0x42,  0x3E,  0x42,  0x00,  0x7E,  0x00,  0x42,  0x3E,  0x7E,  0x22,  0x42,  0x22, 	/* 537F0 */
+	0x42,  0x22,  0x7E,  0x3E,  0x24,  0x00,  0xC2,  0x03,  0x01,  0xA4,  0x00,  0x00,  0x3F,  0xFF,  0x22,  0x08, 	/* 53800 */
+	0x22,  0x10,  0x2A,  0x3E,  0x2B,  0x22,  0x29,  0x22,  0x29,  0x3E,  0x29,  0x22,  0x2B,  0x3E,  0x2A,  0x22, 	/* 53810 */
+	0x22,  0x22,  0x22,  0x3E,  0x3F,  0x94,  0x00,  0x22,  0x00,  0xC1,  0xAC,  0x04,  0x00,  0x04,  0xFF,  0x3F, 	/* 53820 */
+	0x10,  0x04,  0x20,  0x25,  0x7E,  0x15,  0x42,  0x16,  0x42,  0x04,  0x7E,  0x7F,  0xC2,  0x04,  0x7E,  0x04, 	/* 53830 */
+	0x42,  0x0A,  0x42,  0x09,  0x7E,  0x11,  0x24,  0x20,  0x42,  0x40,  0x81,  0xAD,  0x00,  0x00,  0x7F,  0xFE, 	/* 53840 */
+	0x00,  0x20,  0x00,  0x40,  0x3E,  0xFC,  0x22,  0x84,  0x22,  0x84,  0x22,  0xFC,  0x3E,  0x84,  0x02,  0xFC, 	/* 53850 */
+	0x22,  0x84,  0x14,  0x84,  0x15,  0xFC,  0x0E,  0x48,  0x70,  0x84,  0x03,  0x02,  0xB4,  0x20,  0x00,  0x22, 	/* 53860 */
+	0xFF,  0x3C,  0x10,  0x20,  0x20,  0x21,  0x7E,  0x1F,  0x42,  0x00,  0x42,  0x1E,  0x7E,  0x00,  0x42,  0x7F, 	/* 53870 */
+	0xFE,  0x04,  0x42,  0x16,  0x42,  0x15,  0x7E,  0x25,  0x24,  0x44,  0x42,  0x0D,  0x81,  0xB7,  0x04,  0x00, 	/* 53880 */
+	0x04,  0xFF,  0x0A,  0x10,  0x11,  0x20,  0x3E,  0xFE,  0x40,  0x42,  0x3F,  0x42,  0x01,  0x7E,  0x02,  0x42, 	/* 53890 */
+	0x04,  0x7E,  0x3F,  0x42,  0x21,  0x42,  0x21,  0x7E,  0x3F,  0x24,  0x00,  0xC2,  0x03,  0x01,  0xB8,  0x00, 	/* 538A0 */
+	0x00,  0x7F,  0x7F,  0x00,  0x08,  0x15,  0x10,  0x15,  0x7E,  0x2A,  0x42,  0x5A,  0x42,  0x25,  0x7E,  0x15, 	/* 538B0 */
+	0x42,  0x00,  0x7E,  0x7F,  0x42,  0x04,  0x42,  0x04,  0x7E,  0x07,  0x24,  0x18,  0xC2,  0x63,  0x01,  0xBB, 	/* 538C0 */
+	0x04,  0x00,  0x14,  0xFF,  0x17,  0x10,  0x14,  0x20,  0x14,  0x7E,  0x7F,  0xC2,  0x08,  0x42,  0x2A,  0x7E, 	/* 538D0 */
+	0x29,  0x42,  0x2B,  0x7E,  0x4A,  0xC2,  0x1C,  0x42,  0x04,  0x7E,  0x08,  0x24,  0x10,  0xC2,  0x63,  0x01, 	/* 538E0 */
+	0xBC,  0x08,  0x00,  0x08,  0xFF,  0x7F,  0x10,  0x08,  0x20,  0x08,  0x7E,  0x3F,  0x42,  0x29,  0x7E,  0x29, 	/* 538F0 */
+	0x42,  0x3F,  0x42,  0x28,  0x7E,  0x1C,  0x42,  0x1A,  0x42,  0x29,  0x7E,  0x28,  0x24,  0x48,  0x42,  0x09, 	/* 53900 */
+	0x81,  0xBD,  0x01,  0x00,  0x06,  0xFF,  0x3C,  0x10,  0x04,  0x20,  0x7F,  0xFE,  0x0E,  0x42,  0x15,  0x42, 	/* 53910 */
+	0x24,  0xFE,  0x44,  0x42,  0x1E,  0x7E,  0x12,  0x42,  0x12,  0x42,  0x12,  0xFE,  0x13,  0x24,  0x22,  0x42, 	/* 53920 */
+	0x41,  0x81,  0x86,  0x00,  0x00,  0x3F,  0xFF,  0x29,  0x10,  0x29,  0x20,  0x3F,  0x7E,  0x29,  0x42,  0x29, 	/* 53930 */
+	0x42,  0x3F,  0x7E,  0x08,  0x42,  0x7F,  0xFE,  0x0C,  0x42,  0x1A,  0x42,  0x29,  0x7E,  0x48,  0x24,  0x08, 	/* 53940 */
+	0x42,  0x09,  0x81,  0x8B,  0x00,  0x00,  0x3F,  0x7F,  0x29,  0x08,  0x29,  0x10,  0x3F,  0x3E,  0x29,  0x22, 	/* 53950 */
+	0x29,  0x22,  0x29,  0x3E,  0x3F,  0x22,  0x04,  0x3E,  0x22,  0x22,  0x2A,  0xA2,  0x28,  0x7E,  0x29,  0x54, 	/* 53960 */
+	0x49,  0x62,  0x07,  0x81,  0x8C,  0x00,  0x00,  0x3F,  0xFF,  0x22,  0x10,  0x3E,  0x20,  0x22,  0x7E,  0x22, 	/* 53970 */
+	0x42,  0x3E,  0x7E,  0x00,  0x42,  0x7F,  0xFE,  0x08,  0x42,  0x28,  0x42,  0x2F,  0x7E,  0x38,  0x14,  0x28, 	/* 53980 */
+	0x22,  0x26,  0x42,  0x41,  0xFF,  0x8D,  0x08,  0x00,  0x08,  0xFF,  0x7F,  0x10,  0x41,  0x20,  0x49,  0x7E, 	/* 53990 */
+	0x1E,  0x42,  0x22,  0x42,  0x54,  0x7E,  0x0C,  0x42,  0x0A,  0x7E,  0x11,  0x42,  0x3E,  0xC2,  0x52,  0x7E, 	/* 539A0 */
+	0x12,  0x24,  0x1E,  0xC2,  0x13,  0x01,  0x8E,  0x00,  0x00,  0x77,  0xFF,  0x55,  0x10,  0x55,  0x20,  0x77, 	/* 539B0 */
+	0x7E,  0x00,  0x42,  0x3E,  0x7E,  0x00,  0x42,  0x7F,  0x42,  0x10,  0x7E,  0x10,  0x42,  0x3E,  0x42,  0x22, 	/* 539C0 */
+	0x7E,  0x02,  0x24,  0x02,  0x62,  0x0C,  0xC1,  0x8F,  0x04,  0x00,  0x7F,  0xFF,  0x12,  0x10,  0x0C,  0x20, 	/* 539D0 */
+	0x12,  0x7E,  0x3F,  0xC2,  0x24,  0x42,  0x24,  0x7E,  0x2A,  0x42,  0x32,  0x7E,  0x24,  0x42,  0x29,  0x42, 	/* 539E0 */
+	0x52,  0x7E,  0x44,  0x24,  0x18,  0x42,  0x61,  0x81,  0x94,  0x08,  0x00,  0x08,  0xFF,  0x7F,  0x10,  0x22, 	/* 539F0 */
+	0x20,  0x14,  0x7E,  0x3F,  0x42,  0x22,  0x42,  0x24,  0x7E,  0x29,  0x42,  0x22,  0x7E,  0x24,  0x42,  0x28, 	/* 53A00 */
+	0xC2,  0x21,  0x7E,  0x42,  0x24,  0x0C,  0x42,  0x31,  0x81,  0x95,  0x00,  0x00,  0x3F,  0xFF,  0x22,  0x10, 	/* 53A10 */
+	0x22,  0x20,  0x3E,  0x7E,  0x22,  0x42,  0x22,  0x42,  0x3E,  0x7E,  0x14,  0x42,  0x15,  0x7E,  0x55,  0x42, 	/* 53A20 */
+	0x36,  0x42,  0x34,  0x7E,  0x17,  0x24,  0x1C,  0x42,  0x71,  0x81,  0x98,  0x00,  0x00,  0x3F,  0xFF,  0x22, 	/* 53A30 */
+	0x08,  0x24,  0x10,  0x2F,  0xBE,  0x28,  0xA2,  0x2F,  0xA2,  0x28,  0xBE,  0x28,  0xA2,  0x2F,  0xBE,  0x22, 	/* 53A40 */
+	0x22,  0x2B,  0x22,  0x2A,  0xBE,  0x4A,  0x54,  0x52,  0x22,  0x06,  0xC1,  0x9B,  0x08,  0x00,  0x08,  0xFF, 	/* 53A50 */
+	0x7F,  0x90,  0x08,  0x20,  0x3E,  0x7E,  0x22,  0x42,  0x3E,  0x42,  0x22,  0x7E,  0x3E,  0x42,  0x22,  0x7E, 	/* 53A60 */
+	0x3E,  0x42,  0x00,  0x42,  0x7F,  0xFE,  0x0A,  0x24,  0x11,  0x42,  0x61,  0x81,  0x9E,  0x08,  0x00,  0x49, 	/* 53A70 */
+	0xFF,  0x29,  0x10,  0x2A,  0x20,  0x7F,  0x7E,  0x1C,  0x42,  0x1A,  0x42,  0x2A,  0x7E,  0x48,  0x42,  0x08, 	/* 53A80 */
+	0x7E,  0x7F,  0x42,  0x08,  0x42,  0x14,  0x7E,  0x12,  0x24,  0x22,  0x42,  0x41,  0x81,  0xA7,  0x00,  0x00, 	/* 53A90 */
+	0x7F,  0xFF,  0x00,  0x10,  0x3F,  0x20,  0x21,  0x7E,  0x3F,  0x42,  0x25,  0x42,  0x2A,  0x7E,  0x2F,  0x42, 	/* 53AA0 */
+	0x3A,  0x7E,  0x2F,  0x42,  0x2A,  0x42,  0x2F,  0x7E,  0x4A,  0x14,  0x4F,  0xA2,  0x08,  0xC1,  0xAB,  0x04, 	/* 53AB0 */
+	0x00,  0x7F,  0xFF,  0x20,  0x88,  0x2E,  0x90,  0x2A,  0xBE,  0x2E,  0xA2,  0x3F,  0xA2,  0x00,  0x3E,  0x1F, 	/* 53AC0 */
+	0x22,  0x11,  0x3E,  0x1F,  0x22,  0x11,  0x22,  0x1F,  0x3E,  0x00,  0x14,  0x7F,  0xA2,  0x00,  0xC1,  0xAF, 	/* 53AD0 */
+	0x00,  0x00,  0x3F,  0x7F,  0x21,  0x08,  0x3F,  0x10,  0x21,  0x3E,  0x3F,  0x22,  0x11,  0x3E,  0x11,  0x22, 	/* 53AE0 */
+	0x6E,  0xA2,  0x11,  0x3E,  0x2A,  0xA2,  0x7F,  0xE2,  0x00,  0x3E,  0x2D,  0x14,  0x2A,  0xA2,  0x4A,  0xC1, 	/* 53AF0 */
+	0xB0,  0x04,  0x00,  0x17,  0xFF,  0x14,  0x08,  0x7F,  0xBE,  0x14,  0x22,  0x14,  0xBE,  0x2D,  0x22,  0x42, 	/* 53B00 */
+	0x3E,  0x0F,  0xFA,  0x78,  0x89,  0x0F,  0xF8,  0x08,  0x88,  0x0F,  0xF8,  0x01,  0x20,  0x7F,  0xFF,  0x00, 	/* 53B10 */
+	0x20,  0xB1,  0x04,  0x00,  0x07,  0xBF,  0x04,  0x08,  0x3F,  0xD0,  0x25,  0xBE,  0x3E,  0x22,  0x2F,  0xE2, 	/* 53B20 */
+	0x2A,  0xBE,  0x2F,  0xA2,  0x2A,  0xBE,  0x2F,  0xA2,  0x20,  0x22,  0x3F,  0xBE,  0x5A,  0x94,  0x7F,  0xE2, 	/* 53B30 */
+	0x40,  0x41,  0xB3,  0x00,  0x00,  0x3F,  0xFF,  0x11,  0x08,  0x1F,  0x10,  0x11,  0x3E,  0x1F,  0xA2,  0x31, 	/* 53B40 */
+	0x22,  0x01,  0x3E,  0x7F,  0xE2,  0x2A,  0xBE,  0x3B,  0xA2,  0x2A,  0xA2,  0x3B,  0xBE,  0x2A,  0x94,  0x7F, 	/* 53B50 */
+	0xA2,  0x08,  0xC1,  0xB4,  0x12,  0x00,  0x7F,  0xFF,  0x12,  0x08,  0x3B,  0x90,  0x2A,  0xBE,  0x3B,  0xA2, 	/* 53B60 */
+	0x12,  0x22,  0x14,  0x3E,  0x3F,  0xA2,  0x64,  0x3E,  0x3F,  0x22,  0x24,  0x22,  0x3F,  0x3E,  0x24,  0x14, 	/* 53B70 */
+	0x3F,  0xA2,  0x00,  0xC1,  0xA8,  0x00,  0x00,  0x1F,  0xF8,  0x10,  0x28,  0x10,  0xC8,  0x1F,  0x08,  0x11, 	/* 53B80 */
+	0x08,  0x17,  0xE8,  0x15,  0x28,  0x15,  0x28,  0x17,  0xE8,  0x11,  0x08,  0x11,  0x48,  0x11,  0x25,  0x21, 	/* 53B90 */
+	0xF5,  0x3E,  0x13,  0x40,  0x01,  0xAA,  0x00,  0x00,  0x3F,  0xFF,  0x00,  0x80,  0x00,  0xFE,  0x00,  0x80, 	/* 53BA0 */
+	0x1F,  0xFC,  0x10,  0x64,  0x17,  0x84,  0x10,  0x84,  0x17,  0xF4,  0x14,  0x94,  0x17,  0xF5,  0x10,  0xA5, 	/* 53BB0 */
+	0x20,  0x95,  0x2F,  0xFB,  0x40,  0x09,  0xAF,  0x08,  0x00,  0x09,  0xFE,  0x09,  0x02,  0x7F,  0x0A,  0x05, 	/* 53BC0 */
+	0xF2,  0x45,  0x22,  0x25,  0xFA,  0x25,  0xAA,  0x25,  0xAA,  0x29,  0xFA,  0x09,  0x22,  0x17,  0x32,  0x19, 	/* 53BD0 */
+	0x2B,  0x62,  0x3B,  0x03,  0xC5,  0x04,  0x01,  0xB1,  0x00,  0x08,  0x3F,  0xC8,  0x20,  0xC8,  0x23,  0x4A, 	/* 53BE0 */
+	0x3C,  0x52,  0x24,  0x57,  0x3F,  0x79,  0x35,  0x41,  0x35,  0x5E,  0x3F,  0x52,  0x24,  0x52,  0x26,  0x52, 	/* 53BF0 */
+	0x25,  0x5E,  0x27,  0x41,  0x38,  0xA1,  0x40,  0x1F,  0xB6,  0x00,  0x00,  0x3F,  0xBE,  0x21,  0xA2,  0x22, 	/* 53C00 */
+	0xBE,  0x3C,  0xA2,  0x24,  0xBE,  0x3F,  0xA2,  0x35,  0xBE,  0x35,  0xA2,  0x3F,  0xFF,  0x24,  0x94,  0x26, 	/* 53C10 */
+	0xA2,  0x25,  0xC1,  0x27,  0x40,  0x39,  0x21,  0x40,  0x1F,  0x83,  0x00,  0x00,  0x3F,  0xFF,  0x23,  0x14, 	/* 53C20 */
+	0x25,  0x7F,  0x3D,  0x55,  0x25,  0x7F,  0x3F,  0x00,  0x35,  0x3E,  0x35,  0x00,  0x3F,  0x7F,  0x25,  0x08, 	/* 53C30 */
+	0x27,  0x2A,  0x25,  0x49,  0x26,  0x98,  0x39,  0x41,  0x41,  0x3F,  0x84,  0x00,  0x00,  0x7F,  0x7E,  0x14, 	/* 53C40 */
+	0x42,  0x7F,  0x46,  0x55,  0x7A,  0x55,  0x52,  0x7F,  0x7E,  0x00,  0x56,  0x3E,  0x56,  0x00,  0x7E,  0x7F, 	/* 53C50 */
+	0x52,  0x08,  0x5B,  0x2C,  0x57,  0x2A,  0x9D,  0x48,  0xE3,  0x19,  0x01,  0x86,  0x14,  0x00,  0x12,  0xFE, 	/* 53C60 */
+	0x10,  0x86,  0x7E,  0x8A,  0x18,  0xF2,  0x14,  0xA2,  0x22,  0xFA,  0x40,  0xAA,  0x35,  0xAA,  0x2C,  0xFA, 	/* 53C70 */
+	0x7F,  0xA2,  0x24,  0xB2,  0x34,  0xAA,  0x2A,  0xFB,  0x4A,  0x85,  0x41,  0x05,  0x9B,  0x00,  0x00,  0x1F, 	/* 53C80 */
+	0xF2,  0x01,  0x1C,  0x03,  0x14,  0x0D,  0x0A,  0x39,  0x0A,  0x09,  0x06,  0x7F,  0xF2,  0x09,  0x12,  0x09, 	/* 53C90 */
+	0x14,  0x09,  0x18,  0x11,  0x14,  0x11,  0x0A,  0x21,  0x09,  0x41,  0x05,  0x01,  0x03,  0x9C,  0x02,  0x01, 	/* 53CA0 */
+	0x0C,  0xFD,  0x78,  0x26,  0x49,  0x55,  0x2A,  0xD4,  0x7F,  0x55,  0x1C,  0x53,  0x2A,  0x50,  0x49,  0xFD, 	/* 53CB0 */
+	0x3E,  0x55,  0x2A,  0x56,  0x3E,  0x55,  0x2A,  0x54,  0x2A,  0x95,  0x3E,  0x93,  0x01,  0x11,  0x9F,  0x00, 	/* 53CC0 */
+	0x80,  0x00,  0x80,  0x01,  0x40,  0x02,  0x20,  0x04,  0x90,  0x1F,  0xFC,  0x64,  0x13,  0x07,  0xF0,  0x04, 	/* 53CD0 */
+	0x10,  0x04,  0x10,  0x07,  0xF4,  0x04,  0x88,  0x04,  0x50,  0x04,  0x20,  0x07,  0x98,  0x38,  0x07,  0xA2, 	/* 53CE0 */
+	0x04,  0x00,  0x04,  0x78,  0x0A,  0x48,  0x09,  0x48,  0x14,  0xC8,  0x3F,  0x48,  0x51,  0x48,  0x1F,  0x48, 	/* 53CF0 */
+	0x11,  0x48,  0x11,  0x48,  0x1F,  0x48,  0x14,  0x48,  0x12,  0x49,  0x13,  0x49,  0x1C,  0x87,  0x31,  0x00, 	/* 53D00 */
+	0xA9,  0x08,  0x10,  0x08,  0x12,  0x14,  0x1C,  0x12,  0xF0,  0x3D,  0x10,  0x40,  0x10,  0x3E,  0x92,  0x22, 	/* 53D10 */
+	0x92,  0x3E,  0x92,  0x22,  0x92,  0x3E,  0xFE,  0x20,  0x10,  0x3E,  0x10,  0x20,  0x11,  0x3F,  0x11,  0x20, 	/* 53D20 */
+	0x0F,  0xAB,  0x08,  0x04,  0x08,  0x18,  0x14,  0xF0,  0x12,  0x10,  0x3D,  0x10,  0x40,  0x10,  0x3F,  0xFF, 	/* 53D30 */
+	0x22,  0x10,  0x3E,  0x10,  0x22,  0x18,  0x3E,  0x28,  0x20,  0x28,  0x3E,  0x44,  0x20,  0x44,  0x3E,  0x82, 	/* 53D40 */
+	0x21,  0x01,  0xAD,  0x08,  0x40,  0x08,  0x40,  0x14,  0x40,  0x1E,  0x7F,  0x21,  0x80,  0x7E,  0x90,  0x23, 	/* 53D50 */
+	0x10,  0x3E,  0xFE,  0x22,  0x12,  0x22,  0x12,  0x3E,  0x12,  0x20,  0x12,  0x3E,  0x22,  0x20,  0x22,  0x3F, 	/* 53D60 */
+	0x42,  0x20,  0x8C,  0xAE,  0x08,  0x20,  0x08,  0x20,  0x14,  0x20,  0x12,  0x3F,  0x3D,  0x42,  0x60,  0x54, 	/* 53D70 */
+	0x3E,  0x90,  0x22,  0x10,  0x3E,  0x10,  0x22,  0x18,  0x3E,  0x18,  0x20,  0x28,  0x3E,  0x24,  0x20,  0x44, 	/* 53D80 */
+	0x3E,  0x82,  0x21,  0x01,  0xAF,  0x08,  0x00,  0x08,  0x7F,  0x14,  0x40,  0x12,  0x40,  0x29,  0x40,  0x7E, 	/* 53D90 */
+	0x7E,  0x22,  0x42,  0x3E,  0x52,  0x22,  0x52,  0x22,  0x52,  0x3E,  0x54,  0x28,  0x4C,  0x24,  0x48,  0x26, 	/* 53DA0 */
+	0x94,  0x3A,  0xA2,  0x61,  0x41,  0xB2,  0x08,  0x20,  0x08,  0x20,  0x14,  0x20,  0x1A,  0x20,  0x29,  0x7F, 	/* 53DB0 */
+	0x7E,  0x51,  0x22,  0x52,  0x3E,  0x94,  0x23,  0x10,  0x22,  0x10,  0x3E,  0x28,  0x28,  0x28,  0x24,  0x44, 	/* 53DC0 */
+	0x26,  0x44,  0x3A,  0x82,  0x61,  0x01,  0xB4,  0x08,  0x20,  0x08,  0x20,  0x14,  0x20,  0x12,  0x48,  0x29, 	/* 53DD0 */
+	0x44,  0x7E,  0x8E,  0x23,  0xF2,  0x3E,  0x02,  0x22,  0x00,  0x22,  0x7C,  0x3E,  0x44,  0x24,  0x44,  0x22, 	/* 53DE0 */
+	0x44,  0x26,  0x44,  0x39,  0x7C,  0x60,  0x00,  0xBC,  0x08,  0x00,  0x08,  0xFE,  0x14,  0x02,  0x12,  0x02, 	/* 53DF0 */
+	0x29,  0xFA,  0x7E,  0x02,  0x22,  0x02,  0x3E,  0xF2,  0x22,  0x92,  0x22,  0x92,  0x3E,  0x92,  0x28,  0xF2, 	/* 53E00 */
+	0x24,  0x02,  0x26,  0x02,  0x3A,  0x02,  0x61,  0x0C,  0xBD,  0x08,  0x40,  0x08,  0x40,  0x14,  0x7E,  0x12, 	/* 53E10 */
+	0x42,  0x29,  0x82,  0x7E,  0xFA,  0x22,  0x8A,  0x3F,  0x0A,  0x22,  0x0A,  0x22,  0x7A,  0x3E,  0x4C,  0x28, 	/* 53E20 */
+	0x40,  0x24,  0x40,  0x24,  0x41,  0x3A,  0x21,  0x61,  0x1F,  0xBE,  0x08,  0x40,  0x08,  0x40,  0x14,  0x40, 	/* 53E30 */
+	0x12,  0x7F,  0x28,  0x90,  0x7E,  0x90,  0x23,  0x7E,  0x3E,  0x52,  0x22,  0x52,  0x22,  0x52,  0x3E,  0x52, 	/* 53E40 */
+	0x28,  0x52,  0x24,  0x5C,  0x26,  0x50,  0x3A,  0x10,  0x61,  0x10,  0x83,  0x08,  0x10,  0x08,  0x10,  0x14, 	/* 53E50 */
+	0x10,  0x12,  0xFF,  0x3D,  0x24,  0x40,  0x22,  0x3E,  0x42,  0x22,  0xA5,  0x3E,  0x24,  0x22,  0x14,  0x3E, 	/* 53E60 */
+	0x18,  0x20,  0x18,  0x3E,  0x28,  0x20,  0x44,  0x3E,  0x82,  0x21,  0x01,  0x85,  0x08,  0x42,  0x08,  0x22, 	/* 53E70 */
+	0x14,  0x24,  0x12,  0x00,  0x29,  0xFF,  0x7E,  0x24,  0x22,  0x24,  0x3E,  0x24,  0x22,  0xFF,  0x22,  0x24, 	/* 53E80 */
+	0x3E,  0x24,  0x28,  0x24,  0x24,  0x24,  0x2E,  0x44,  0x31,  0x44,  0x60,  0x84,  0x89,  0x08,  0x10,  0x08, 	/* 53E90 */
+	0x10,  0x14,  0x20,  0x12,  0xFE,  0x3D,  0x82,  0x40,  0x82,  0x3E,  0xBA,  0x22,  0xAA,  0x3E,  0xAA,  0x22, 	/* 53EA0 */
+	0xAA,  0x3E,  0xBA,  0x20,  0x82,  0x3E,  0x82,  0x20,  0x82,  0x3E,  0x82,  0x20,  0x86,  0x8A,  0x04,  0x10, 	/* 53EB0 */
+	0x02,  0x20,  0x3F,  0xFE,  0x00,  0x80,  0x1F,  0xFC,  0x00,  0x80,  0x7F,  0xFF,  0x02,  0xA0,  0x07,  0xF0, 	/* 53EC0 */
+	0x1C,  0x1C,  0x67,  0xF3,  0x04,  0x10,  0x07,  0xF4,  0x04,  0x48,  0x07,  0xB0,  0x38,  0x0F,  0x8C,  0x08, 	/* 53ED0 */
+	0x00,  0x09,  0xFF,  0x14,  0x44,  0x12,  0x44,  0x29,  0x44,  0x7E,  0x7C,  0x22,  0x44,  0x3E,  0x44,  0x22, 	/* 53EE0 */
+	0x7C,  0x22,  0x44,  0x3E,  0x44,  0x24,  0x47,  0x22,  0x7C,  0x26,  0xC4,  0x39,  0x04,  0x61,  0x04,  0x90, 	/* 53EF0 */
+	0x04,  0x00,  0x07,  0xFE,  0x04,  0x22,  0x0F,  0x14,  0x79,  0x88,  0x06,  0xB4,  0x19,  0x43,  0x62,  0xA0, 	/* 53F00 */
+	0x0F,  0xF8,  0x74,  0x17,  0x07,  0xF0,  0x04,  0x10,  0x07,  0xF4,  0x04,  0x88,  0x07,  0x70,  0x38,  0x0F, 	/* 53F10 */
+	0x92,  0x08,  0x04,  0x08,  0x18,  0x14,  0xE4,  0x12,  0x52,  0x3D,  0x52,  0x40,  0x91,  0x3F,  0x01,  0x22, 	/* 53F20 */
+	0x10,  0x3F,  0xFF,  0x22,  0x24,  0x3E,  0x24,  0x20,  0x64,  0x3E,  0x18,  0x20,  0x14,  0x3E,  0x62,  0x21, 	/* 53F30 */
+	0x82,  0x93,  0x08,  0x28,  0x08,  0x4C,  0x15,  0xCA,  0x1A,  0x4A,  0x28,  0x48,  0x7F,  0xFF,  0x22,  0x48, 	/* 53F40 */
+	0x3E,  0x4A,  0x22,  0x6A,  0x22,  0x4A,  0x3E,  0xC4,  0x29,  0x44,  0x24,  0x4D,  0x2C,  0x4B,  0x32,  0x53, 	/* 53F50 */
+	0x62,  0xE1,  0x94,  0x08,  0x14,  0x08,  0x12,  0x15,  0xFF,  0x12,  0x10,  0x3D,  0x10,  0x40,  0xFE,  0x3E, 	/* 53F60 */
+	0x92,  0x22,  0x92,  0x3E,  0xFE,  0x22,  0x92,  0x3E,  0x92,  0x20,  0xFE,  0x3E,  0x92,  0x20,  0x92,  0x3E, 	/* 53F70 */
+	0x92,  0x20,  0x96,  0x98,  0x08,  0x10,  0x08,  0x10,  0x14,  0x28,  0x12,  0x28,  0x3D,  0x44,  0x40,  0x42, 	/* 53F80 */
+	0x3E,  0xFD,  0x23,  0x10,  0x3E,  0x10,  0x22,  0xFE,  0x3E,  0x10,  0x20,  0x54,  0x3E,  0x54,  0x20,  0x92, 	/* 53F90 */
+	0x3F,  0x12,  0x20,  0x30,  0x9D,  0x08,  0x44,  0x08,  0x44,  0x15,  0xFF,  0x12,  0x44,  0x3D,  0x54,  0x40, 	/* 53FA0 */
+	0x10,  0x3F,  0xFF,  0x22,  0x20,  0x3E,  0x20,  0x22,  0x3C,  0x3E,  0x24,  0x20,  0x24,  0x3E,  0x44,  0x20, 	/* 53FB0 */
+	0x44,  0x3E,  0x84,  0x21,  0x18,  0x9E,  0x08,  0x28,  0x08,  0x24,  0x14,  0x2F,  0x12,  0xF2,  0x3D,  0x14, 	/* 53FC0 */
+	0x40,  0x08,  0x3E,  0x75,  0x23,  0x83,  0x3E,  0x28,  0x22,  0x24,  0x3E,  0x3F,  0x20,  0xD2,  0x3E,  0x14, 	/* 53FD0 */
+	0x20,  0x39,  0x3F,  0xC5,  0x20,  0x03,  0xA0,  0x08,  0x22,  0x08,  0x22,  0x14,  0x44,  0x13,  0xFF,  0x3D, 	/* 53FE0 */
+	0x44,  0x40,  0x44,  0x3E,  0x44,  0x22,  0x54,  0x3E,  0x64,  0x22,  0xDF,  0x3F,  0x44,  0x20,  0x44,  0x3E, 	/* 53FF0 */
+	0x44,  0x20,  0x84,  0x3E,  0x84,  0x21,  0x04,  0xA1,  0x08,  0x20,  0x08,  0x20,  0x14,  0x3E,  0x12,  0x22, 	/* 54000 */
+	0x3D,  0x22,  0x40,  0x42,  0x3E,  0x4C,  0x22,  0x80,  0x3E,  0x20,  0x22,  0xCE,  0x3E,  0x82,  0x20,  0xEE, 	/* 54010 */
+	0x3E,  0x82,  0x20,  0x82,  0x3E,  0xFE,  0x20,  0x00,  0xA4,  0x08,  0x10,  0x08,  0x92,  0x14,  0x92,  0x12, 	/* 54020 */
+	0xAC,  0x3D,  0x28,  0x40,  0x44,  0x3E,  0x82,  0x23,  0x11,  0x3E,  0x10,  0x22,  0x92,  0x3E,  0x92,  0x20, 	/* 54030 */
+	0xAC,  0x3F,  0x28,  0x20,  0x44,  0x3E,  0x82,  0x21,  0x01,  0xA8,  0x08,  0x10,  0x08,  0x10,  0x14,  0xFF, 	/* 54040 */
+	0x12,  0x81,  0x29,  0x81,  0x7E,  0x7C,  0x22,  0x44,  0x3E,  0x44,  0x22,  0x7C,  0x22,  0x40,  0x3E,  0x40, 	/* 54050 */
+	0x24,  0x7E,  0x22,  0x42,  0x26,  0x42,  0x39,  0x7E,  0x60,  0x00,  0xAC,  0x08,  0x80,  0x08,  0x9E,  0x14, 	/* 54060 */
+	0x92,  0x14,  0x92,  0x3B,  0xF2,  0x40,  0x9E,  0x3C,  0x92,  0x24,  0x92,  0x3D,  0xD2,  0x25,  0x5E,  0x3D, 	/* 54070 */
+	0x52,  0x21,  0x52,  0x3D,  0x52,  0x21,  0xD2,  0x3C,  0x22,  0x20,  0x46,  0xAE,  0x00,  0x10,  0x7F,  0x98, 	/* 54080 */
+	0x04,  0x2C,  0x0F,  0x72,  0x11,  0x89,  0x6A,  0x34,  0x04,  0x88,  0x19,  0x70,  0x63,  0xE0,  0x0C,  0x18, 	/* 54090 */
+	0x77,  0xF7,  0x04,  0x10,  0x07,  0xF8,  0x04,  0x90,  0x07,  0x60,  0x3C,  0x1F,  0xBD,  0x08,  0x10,  0x08, 	/* 540A0 */
+	0x20,  0x14,  0xFC,  0x12,  0xA4,  0x3D,  0xA4,  0x40,  0xFC,  0x3E,  0xA4,  0x22,  0xA4,  0x3E,  0xFC,  0x22, 	/* 540B0 */
+	0x32,  0x3E,  0x32,  0x20,  0x55,  0x3E,  0x5F,  0x20,  0x90,  0x3F,  0x11,  0x22,  0x0F,  0xBE,  0x08,  0x10, 	/* 540C0 */
+	0x08,  0xEF,  0x14,  0x85,  0x12,  0x85,  0x3D,  0xA5,  0x40,  0xA9,  0x3E,  0xEB,  0x23,  0x90,  0x3E,  0x00, 	/* 540D0 */
+	0x22,  0xFE,  0x3E,  0x92,  0x20,  0xFE,  0x3E,  0x92,  0x20,  0x92,  0x3E,  0xFE,  0x20,  0x00,  0x82,  0x08, 	/* 540E0 */
+	0x00,  0x08,  0x7E,  0x14,  0x52,  0x12,  0x52,  0x3D,  0x5A,  0x40,  0x56,  0x3E,  0x62,  0x22,  0x7E,  0x3E, 	/* 540F0 */
+	0x00,  0x22,  0xFE,  0x3E,  0xAA,  0x20,  0xAA,  0x3E,  0xAA,  0x20,  0xAA,  0x3F,  0xFF,  0x20,  0x00,  0x85, 	/* 54100 */
+	0x08,  0x00,  0x08,  0x7C,  0x14,  0x44,  0x12,  0x7C,  0x3D,  0x44,  0x40,  0x7C,  0x3E,  0x00,  0x22,  0xFF, 	/* 54110 */
+	0x3E,  0xA5,  0x22,  0xFF,  0x3E,  0x00,  0x20,  0xFE,  0x3E,  0x24,  0x20,  0x18,  0x3E,  0x64,  0x21,  0x83, 	/* 54120 */
+	0x89,  0x08,  0x44,  0x08,  0x44,  0x15,  0xFF,  0x12,  0x44,  0x3D,  0x7C,  0x40,  0x00,  0x3E,  0xFE,  0x22, 	/* 54130 */
+	0x92,  0x3E,  0xFE,  0x22,  0x10,  0x3E,  0xFE,  0x20,  0x10,  0x3E,  0xFE,  0x20,  0x10,  0x3F,  0xFF,  0x20, 	/* 54140 */
+	0x00,  0x8B,  0x08,  0x10,  0x08,  0x7E,  0x14,  0x52,  0x12,  0x7E,  0x3D,  0x10,  0x40,  0xFF,  0x3E,  0x00, 	/* 54150 */
+	0x22,  0x7E,  0x3E,  0x42,  0x22,  0x7E,  0x3E,  0x42,  0x20,  0x7E,  0x3E,  0x42,  0x20,  0x7E,  0x3E,  0x22, 	/* 54160 */
+	0x21,  0xC1,  0x8C,  0x08,  0x00,  0x08,  0xEE,  0x14,  0xAA,  0x12,  0xEE,  0x3D,  0x88,  0x40,  0x99,  0x3E, 	/* 54170 */
+	0x77,  0x22,  0x00,  0x3E,  0x24,  0x22,  0xFE,  0x3E,  0x24,  0x20,  0x24,  0x3F,  0xFF,  0x20,  0x24,  0x3E, 	/* 54180 */
+	0x42,  0x21,  0x81,  0x90,  0x08,  0x10,  0x09,  0xFF,  0x14,  0x10,  0x12,  0x7E,  0x3D,  0x00,  0x40,  0xFF, 	/* 54190 */
+	0x3E,  0x81,  0x22,  0x7D,  0x3E,  0x00,  0x22,  0x7E,  0x3E,  0x42,  0x20,  0x7E,  0x3E,  0x42,  0x20,  0x24, 	/* 541A0 */
+	0x3F,  0xFF,  0x20,  0x00,  0x91,  0x08,  0x52,  0x08,  0x52,  0x15,  0xBC,  0x12,  0xD2,  0x3C,  0x55,  0x40, 	/* 541B0 */
+	0xBF,  0x3D,  0xF4,  0x24,  0x12,  0x3D,  0xFF,  0x24,  0x94,  0x3C,  0x94,  0x20,  0xC8,  0x3D,  0x29,  0x21, 	/* 541C0 */
+	0x15,  0x3E,  0x23,  0x20,  0x41,  0x92,  0x08,  0x10,  0x08,  0x7C,  0x14,  0x10,  0x12,  0xFE,  0x3D,  0x00, 	/* 541D0 */
+	0x40,  0x44,  0x3E,  0xFF,  0x22,  0x44,  0x3E,  0x74,  0x23,  0x8F,  0x3E,  0x00,  0x21,  0xFF,  0x3C,  0x28, 	/* 541E0 */
+	0x20,  0x29,  0x3E,  0xC9,  0x23,  0x07,  0x95,  0x00,  0x08,  0x3E,  0x0E,  0x22,  0x08,  0x3E,  0x7F,  0x7F, 	/* 541F0 */
+	0xDA,  0x10,  0x74,  0x1E,  0x4F,  0x02,  0x54,  0x1C,  0x95,  0x03,  0x63,  0x0C,  0x18,  0x77,  0xF7,  0x04, 	/* 54200 */
+	0x10,  0x07,  0xF4,  0x04,  0x68,  0x3E,  0x1F,  0x97,  0x11,  0xEE,  0x65,  0x2A,  0x29,  0xEA,  0x11,  0x2C, 	/* 54210 */
+	0x1D,  0xEA,  0x65,  0x49,  0x0B,  0xEF,  0x10,  0xA8,  0x61,  0x48,  0x03,  0xF0,  0x0C,  0x1C,  0x77,  0xF3, 	/* 54220 */
+	0x04,  0x10,  0x07,  0xF4,  0x04,  0xE8,  0x7F,  0x1E,  0x96,  0x10,  0x10,  0x08,  0x10,  0x04,  0x20,  0x7F, 	/* 54230 */
+	0xFE,  0x01,  0x00,  0x02,  0x00,  0x1F,  0xF8,  0x10,  0x08,  0x10,  0x08,  0x1F,  0xF8,  0x10,  0x08,  0x1F, 	/* 54240 */
+	0xF8,  0x10,  0x08,  0x10,  0x08,  0x1F,  0xF8,  0x00,  0x00,  0x97,  0x10,  0x44,  0x10,  0x28,  0x11,  0xFF, 	/* 54250 */
+	0x10,  0x20,  0x7E,  0x7C,  0x12,  0x44,  0x12,  0x44,  0x12,  0x7C,  0x12,  0x44,  0x12,  0x7C,  0x12,  0x44, 	/* 54260 */
+	0x12,  0x44,  0x12,  0x7D,  0x22,  0x01,  0x21,  0x01,  0x40,  0xFF,  0x98,  0x22,  0x0A,  0x12,  0x09,  0x14, 	/* 54270 */
+	0x08,  0x7F,  0xFF,  0x08,  0x08,  0x3E,  0x08,  0x22,  0xEA,  0x22,  0xAA,  0x3E,  0xAA,  0x22,  0xEC,  0x22, 	/* 54280 */
+	0x04,  0x3E,  0x6D,  0x23,  0x95,  0x22,  0x23,  0x3E,  0x43,  0x00,  0x01,  0x99,  0x00,  0x08,  0x00,  0x70, 	/* 54290 */
+	0x1F,  0x80,  0x00,  0x80,  0x7F,  0xFF,  0x01,  0xC0,  0x02,  0xA0,  0x04,  0x90,  0x18,  0x8C,  0x6F,  0xFB, 	/* 542A0 */
+	0x08,  0x08,  0x0F,  0xF8,  0x08,  0x08,  0x08,  0x08,  0x0F,  0xF8,  0x00,  0x00,  0xA5,  0x02,  0x20,  0x04, 	/* 542B0 */
+	0x20,  0x38,  0x3F,  0x08,  0x40,  0x7F,  0xFC,  0x0C,  0x44,  0x1A,  0x7C,  0x29,  0x44,  0x48,  0x7C,  0x3E, 	/* 542C0 */
+	0x20,  0x22,  0x3C,  0x3E,  0x44,  0x23,  0xA8,  0x22,  0x30,  0x3E,  0xCC,  0x03,  0x03,  0xA8,  0x04,  0x3C, 	/* 542D0 */
+	0x3F,  0x25,  0x04,  0x47,  0x7F,  0xFC,  0x25,  0x24,  0x3F,  0x18,  0x20,  0x64,  0x4F,  0x83,  0x00,  0x80, 	/* 542E0 */
+	0x7F,  0xFF,  0x02,  0xA0,  0x07,  0xF0,  0x1C,  0x1C,  0x67,  0xF3,  0x04,  0x10,  0x07,  0xF0,  0xAC,  0x00, 	/* 542F0 */
+	0x00,  0x0F,  0xFC,  0x08,  0x80,  0x08,  0x80,  0x0F,  0xF8,  0x08,  0x80,  0x08,  0x80,  0x0F,  0xF8,  0x08, 	/* 54300 */
+	0x80,  0x08,  0x80,  0x0F,  0xFE,  0x00,  0x22,  0x14,  0x92,  0x12,  0x52,  0x22,  0x42,  0x40,  0x0C,  0xAD, 	/* 54310 */
+	0x00,  0x00,  0x3F,  0xFC,  0x24,  0x24,  0x24,  0x24,  0x3F,  0x24,  0x24,  0x24,  0x3F,  0x24,  0x24,  0x14, 	/* 54320 */
+	0x24,  0x14,  0x3F,  0x98,  0x04,  0x88,  0x32,  0x98,  0x2A,  0x94,  0x28,  0xA4,  0x41,  0x42,  0x06,  0x81, 	/* 54330 */
+	0xAE,  0x00,  0x00,  0x01,  0xFE,  0x21,  0x20,  0x11,  0x20,  0x11,  0xFC,  0x01,  0x20,  0x01,  0xFC,  0x09, 	/* 54340 */
+	0x20,  0x09,  0x20,  0x11,  0xFE,  0x10,  0x12,  0x25,  0x4A,  0x24,  0xAA,  0x44,  0xA2,  0x48,  0x02,  0x00, 	/* 54350 */
+	0x0C,  0xB3,  0x00,  0x08,  0x3F,  0xA8,  0x24,  0x28,  0x24,  0x2E,  0x3F,  0x2A,  0x24,  0x3A,  0x3F,  0xEA, 	/* 54360 */
+	0x24,  0x2A,  0x24,  0x2A,  0x3F,  0xAA,  0x04,  0xAE,  0x12,  0xA8,  0x2A,  0xA8,  0x28,  0xA1,  0x40,  0xA1, 	/* 54370 */
+	0x03,  0x1F,  0xB4,  0x00,  0x22,  0x3F,  0xAA,  0x24,  0x2A,  0x24,  0x2A,  0x3F,  0x2A,  0x24,  0x2A,  0x3F, 	/* 54380 */
+	0x2A,  0x24,  0x2A,  0x24,  0x2A,  0x3F,  0xAA,  0x02,  0xAA,  0x35,  0xAA,  0x2A,  0xAA,  0x2A,  0xA2,  0x41, 	/* 54390 */
+	0x42,  0x06,  0x82,  0xBC,  0x00,  0x08,  0x3F,  0x88,  0x24,  0x08,  0x24,  0xFF,  0x3F,  0x22,  0x24,  0x22, 	/* 543A0 */
+	0x3F,  0x22,  0x24,  0x14,  0x24,  0x14,  0x3F,  0x88,  0x04,  0x88,  0x32,  0x98,  0x2A,  0x94,  0x28,  0xA4, 	/* 543B0 */
+	0x41,  0x42,  0x06,  0x81,  0x81,  0x00,  0x04,  0x3F,  0xC4,  0x24,  0x24,  0x24,  0x18,  0x3F,  0x08,  0x24, 	/* 543C0 */
+	0x14,  0x3F,  0x22,  0x24,  0x40,  0x24,  0x02,  0x3F,  0xA2,  0x04,  0x94,  0x12,  0x8C,  0x2A,  0x88,  0x28, 	/* 543D0 */
+	0x94,  0x41,  0x22,  0x06,  0xC1,  0x84,  0x00,  0x10,  0x3F,  0x90,  0x24,  0x10,  0x24,  0xFF,  0x3F,  0x10, 	/* 543E0 */
+	0x24,  0x10,  0x3F,  0x10,  0x24,  0x18,  0x24,  0x28,  0x3F,  0xA8,  0x04,  0xA8,  0x32,  0xA8,  0x2A,  0xE4, 	/* 543F0 */
+	0x28,  0x94,  0x40,  0x92,  0x03,  0x01,  0x85,  0x00,  0x00,  0x3F,  0xBE,  0x24,  0x22,  0x24,  0x22,  0x3F, 	/* 54400 */
+	0x22,  0x24,  0x22,  0x3F,  0x3E,  0x24,  0x30,  0x24,  0x28,  0x3F,  0xA8,  0x14,  0xA8,  0x2A,  0xA8,  0x2A, 	/* 54410 */
+	0xA4,  0x28,  0xC4,  0x41,  0x42,  0x06,  0x81,  0x86,  0x00,  0x00,  0x3F,  0x7F,  0x24,  0x40,  0x24,  0x42, 	/* 54420 */
+	0x3F,  0x42,  0x24,  0x52,  0x3F,  0x4C,  0x24,  0x44,  0x24,  0x44,  0x3F,  0xCA,  0x04,  0xCA,  0x32,  0xD2, 	/* 54430 */
+	0x2A,  0xE0,  0x28,  0xC0,  0x41,  0x7F,  0x06,  0x40,  0x88,  0x00,  0x04,  0x3F,  0x88,  0x24,  0x30,  0x24, 	/* 54440 */
+	0x20,  0x3F,  0x20,  0x24,  0x3F,  0x3F,  0x24,  0x24,  0x24,  0x24,  0x24,  0x3F,  0xA4,  0x04,  0xA4,  0x32, 	/* 54450 */
+	0xA4,  0x2A,  0xA4,  0x28,  0xA4,  0x40,  0xFF,  0x03,  0x00,  0x90,  0x00,  0x10,  0x3F,  0x88,  0x24,  0x08, 	/* 54460 */
+	0x24,  0x7F,  0x3F,  0x88,  0x24,  0x08,  0x3F,  0x88,  0x24,  0x08,  0x24,  0x7E,  0x3F,  0x88,  0x04,  0x88, 	/* 54470 */
+	0x12,  0x88,  0x2A,  0x88,  0x28,  0x88,  0x40,  0xFF,  0x03,  0x00,  0x91,  0x04,  0x00,  0x7F,  0xFC,  0x09, 	/* 54480 */
+	0x44,  0x12,  0x28,  0x3C,  0x10,  0x0A,  0x6C,  0x11,  0x83,  0x6F,  0xF8,  0x08,  0x80,  0x0F,  0xF8,  0x08, 	/* 54490 */
+	0x80,  0x0F,  0xFC,  0x00,  0x44,  0x29,  0x24,  0x24,  0x84,  0x40,  0x18,  0x92,  0x00,  0x20,  0x3F,  0x20, 	/* 544A0 */
+	0x24,  0x3E,  0x24,  0x22,  0x3F,  0x42,  0x24,  0x7A,  0x3F,  0xAA,  0x25,  0x2A,  0x24,  0x2A,  0x3F,  0xAA, 	/* 544B0 */
+	0x04,  0xBA,  0x32,  0x82,  0x2A,  0x82,  0x28,  0x82,  0x40,  0x84,  0x03,  0x18,  0x95,  0x08,  0x00,  0x7F, 	/* 544C0 */
+	0x7E,  0x09,  0x42,  0x09,  0x42,  0x11,  0x7E,  0x26,  0x00,  0x4F,  0xF8,  0x08,  0x80,  0x0F,  0xF0,  0x08, 	/* 544D0 */
+	0x80,  0x0F,  0xF0,  0x08,  0x80,  0x0F,  0xFE,  0x29,  0x22,  0x24,  0x92,  0x40,  0x0C,  0x98,  0x00,  0x10, 	/* 544E0 */
+	0x3F,  0x90,  0x24,  0x10,  0x24,  0x14,  0x3F,  0x22,  0x24,  0x26,  0x3F,  0xF9,  0x24,  0x01,  0x24,  0x01, 	/* 544F0 */
+	0x3F,  0xBE,  0x04,  0xA2,  0x32,  0xA2,  0x2A,  0xA2,  0x28,  0xA2,  0x40,  0xBE,  0x03,  0x00,  0x9B,  0x00, 	/* 54500 */
+	0x08,  0x3F,  0x88,  0x24,  0x08,  0x24,  0x7E,  0x3F,  0x4A,  0x24,  0x4A,  0x3F,  0x4A,  0x24,  0x7E,  0x24, 	/* 54510 */
+	0x08,  0x3F,  0xA8,  0x04,  0xA8,  0x32,  0x90,  0x2A,  0x98,  0x28,  0xA8,  0x40,  0xC4,  0x03,  0x03,  0x9D, 	/* 54520 */
+	0x00,  0x08,  0x3F,  0x88,  0x24,  0x08,  0x24,  0x7F,  0x3F,  0x41,  0x24,  0x51,  0x3F,  0x10,  0x24,  0x11, 	/* 54530 */
+	0x24,  0x12,  0x3F,  0x9C,  0x04,  0x90,  0x32,  0x90,  0x2A,  0x90,  0x28,  0x91,  0x40,  0x91,  0x03,  0x0F, 	/* 54540 */
+	0x9F,  0x00,  0x00,  0x3F,  0x7E,  0x24,  0x5A,  0x24,  0x5A,  0x3F,  0x5A,  0x24,  0x5A,  0x3F,  0x5A,  0x24, 	/* 54550 */
+	0x6A,  0x24,  0x6E,  0x3F,  0x62,  0x05,  0x42,  0x13,  0x42,  0x2B,  0x42,  0x29,  0x42,  0x41,  0x7E,  0x06, 	/* 54560 */
+	0x00,  0xA2,  0x00,  0x42,  0x3F,  0x22,  0x24,  0x24,  0x24,  0xFF,  0x3F,  0x24,  0x24,  0x24,  0x3F,  0x24, 	/* 54570 */
+	0x24,  0xFF,  0x24,  0x24,  0x3F,  0xA4,  0x04,  0xA4,  0x32,  0xA4,  0x2A,  0xA4,  0x28,  0xA4,  0x41,  0x44, 	/* 54580 */
+	0x06,  0x84,  0xAD,  0x00,  0x08,  0x3F,  0x88,  0x24,  0x08,  0x24,  0x7F,  0x3F,  0x10,  0x24,  0x14,  0x3F, 	/* 54590 */
+	0xE4,  0x24,  0x28,  0x24,  0x1A,  0x3F,  0x92,  0x04,  0xA4,  0x32,  0xC8,  0x2A,  0x98,  0x28,  0xA4,  0x41, 	/* 545A0 */
+	0x42,  0x06,  0x81,  0xAE,  0x00,  0x08,  0x3F,  0x88,  0x24,  0x7F,  0x24,  0x24,  0x3F,  0x22,  0x24,  0x22, 	/* 545B0 */
+	0x3F,  0x45,  0x24,  0x95,  0x24,  0x14,  0x3F,  0x94,  0x04,  0x88,  0x32,  0x88,  0x2A,  0x94,  0x28,  0xA4, 	/* 545C0 */
+	0x41,  0x42,  0x06,  0x81,  0xB1,  0x00,  0x10,  0x3F,  0x90,  0x24,  0x1C,  0x24,  0x24,  0x3F,  0x64,  0x24, 	/* 545D0 */
+	0x98,  0x3F,  0x08,  0x24,  0x14,  0x24,  0x22,  0x3F,  0xC1,  0x04,  0xBE,  0x32,  0xA2,  0x2A,  0xA2,  0x28, 	/* 545E0 */
+	0xA2,  0x41,  0x3E,  0x06,  0x00,  0xB2,  0x00,  0x22,  0x3F,  0x2A,  0x24,  0x2A,  0x24,  0x2A,  0x3F,  0x2A, 	/* 545F0 */
+	0x24,  0x2A,  0x3F,  0x7A,  0x24,  0x7E,  0x24,  0xAE,  0x3F,  0x2A,  0x05,  0x2A,  0x33,  0x2A,  0x2B,  0x4A, 	/* 54600 */
+	0x29,  0x4A,  0x42,  0x82,  0x0D,  0x02,  0xB8,  0x00,  0x00,  0x3F,  0xBE,  0x24,  0x02,  0x24,  0x7F,  0x3F, 	/* 54610 */
+	0x02,  0x24,  0x3E,  0x3F,  0x00,  0x24,  0x7F,  0x24,  0x41,  0x3F,  0xFD,  0x04,  0xA4,  0x32,  0x94,  0x2A, 	/* 54620 */
+	0x88,  0x28,  0x94,  0x41,  0x22,  0x06,  0xC1,  0xBB,  0x00,  0x00,  0x3F,  0xBE,  0x24,  0x22,  0x24,  0x22, 	/* 54630 */
+	0x3F,  0x3E,  0x24,  0x22,  0x3F,  0x22,  0x24,  0x3E,  0x24,  0x00,  0x3F,  0xBE,  0x04,  0x88,  0x32,  0x88, 	/* 54640 */
+	0x2A,  0xFF,  0x28,  0x88,  0x40,  0x88,  0x03,  0x08,  0xBF,  0x00,  0x10,  0x3F,  0x98,  0x24,  0x26,  0x24, 	/* 54650 */
+	0xFD,  0x3F,  0x28,  0x24,  0x29,  0x3F,  0x47,  0x24,  0x90,  0x24,  0x1C,  0x3F,  0xA4,  0x04,  0xE4,  0x12, 	/* 54660 */
+	0xA8,  0x2A,  0x90,  0x28,  0xA8,  0x41,  0x44,  0x06,  0x83,  0x81,  0x00,  0x10,  0x3F,  0x10,  0x24,  0x7E, 	/* 54670 */
+	0x24,  0x52,  0x3F,  0x7E,  0x24,  0x52,  0x3F,  0x7E,  0x24,  0x00,  0x24,  0xFF,  0x3F,  0x90,  0x04,  0x90, 	/* 54680 */
+	0x32,  0xBE,  0x2A,  0xA2,  0x28,  0x82,  0x40,  0x82,  0x03,  0x0C,  0x85,  0x00,  0x12,  0x3F,  0x92,  0x24, 	/* 54690 */
+	0x14,  0x24,  0x3F,  0x3F,  0x24,  0x24,  0x64,  0x3F,  0xA4,  0x24,  0x3F,  0x24,  0x24,  0x3F,  0xA4,  0x04, 	/* 546A0 */
+	0xBF,  0x32,  0xA4,  0x2A,  0xA4,  0x28,  0xA4,  0x40,  0xBF,  0x03,  0x00,  0x8E,  0x00,  0x10,  0x3F,  0x10, 	/* 546B0 */
+	0x24,  0xFE,  0x24,  0x10,  0x3F,  0x28,  0x24,  0x44,  0x24,  0x80,  0x3F,  0xFF,  0x24,  0x02,  0x24,  0x3A, 	/* 546C0 */
+	0x3F,  0xAA,  0x14,  0xAA,  0x2A,  0xBA,  0x2A,  0x82,  0x20,  0x82,  0x43,  0x06,  0x8F,  0x00,  0x24,  0x3F, 	/* 546D0 */
+	0xA4,  0x24,  0x7F,  0x24,  0x24,  0x3F,  0x24,  0x24,  0x3C,  0x3F,  0x24,  0x24,  0x24,  0x24,  0x3C,  0x3F, 	/* 546E0 */
+	0xA4,  0x04,  0xA4,  0x32,  0xFF,  0x2A,  0x80,  0x28,  0xA4,  0x40,  0xA2,  0x03,  0x42,  0x92,  0x00,  0x00, 	/* 546F0 */
+	0x3F,  0xFC,  0x24,  0x44,  0x24,  0x28,  0x3F,  0x10,  0x24,  0x2C,  0x3F,  0xD3,  0x24,  0x10,  0x24,  0x7C, 	/* 54700 */
+	0x3F,  0x54,  0x05,  0x54,  0x2B,  0x7C,  0x2B,  0x18,  0x29,  0x14,  0x41,  0x1E,  0x06,  0xE1,  0x93,  0x00, 	/* 54710 */
+	0x10,  0x3F,  0x90,  0x24,  0x28,  0x24,  0x24,  0x3F,  0x7E,  0x24,  0x91,  0x3F,  0x7E,  0x24,  0x52,  0x24, 	/* 54720 */
+	0x52,  0x3F,  0x7E,  0x05,  0x10,  0x2B,  0x18,  0x2B,  0x28,  0x29,  0x24,  0x41,  0x42,  0x06,  0x81,  0x99, 	/* 54730 */
+	0x00,  0x00,  0x3F,  0xFF,  0x24,  0x00,  0x24,  0x7E,  0x3F,  0x42,  0x24,  0x42,  0x3F,  0x7E,  0x24,  0x40, 	/* 54740 */
+	0x24,  0x7F,  0x3E,  0xD5,  0x0A,  0xD5,  0x36,  0xFF,  0x2B,  0x55,  0x2A,  0x55,  0x42,  0x55,  0x0C,  0x43, 	/* 54750 */
+	0xA8,  0x00,  0x91,  0x3F,  0x49,  0x24,  0x4A,  0x24,  0x7E,  0x3F,  0x4A,  0x24,  0x4A,  0x3F,  0x7E,  0x24, 	/* 54760 */
+	0x4A,  0x24,  0x4A,  0x3F,  0xFE,  0x04,  0x88,  0x32,  0xFF,  0x2A,  0x88,  0x28,  0x88,  0x41,  0x08,  0x06, 	/* 54770 */
+	0x08,  0xAB,  0x00,  0x80,  0x3F,  0xFE,  0x22,  0x22,  0x0F,  0xF8,  0x02,  0x20,  0x0F,  0xF8,  0x02,  0x20, 	/* 54780 */
+	0x7F,  0xFF,  0x04,  0x10,  0x0F,  0xF8,  0x14,  0x84,  0x67,  0xF3,  0x04,  0x80,  0x17,  0xFC,  0x14,  0x94, 	/* 54790 */
+	0x22,  0x58,  0xB0,  0x01,  0x24,  0x3C,  0xA8,  0x25,  0xFE,  0x24,  0x50,  0x27,  0xFF,  0x3C,  0x88,  0x25, 	/* 547A0 */
+	0xFC,  0x26,  0x92,  0x24,  0xFD,  0x3C,  0x90,  0x24,  0xFC,  0x24,  0x90,  0x24,  0xFE,  0x25,  0x52,  0x25, 	/* 547B0 */
+	0x2A,  0x4E,  0x0C,  0xB7,  0x00,  0x00,  0x3F,  0xFE,  0x24,  0x2A,  0x24,  0x24,  0x3E,  0x94,  0x24,  0x48, 	/* 547C0 */
+	0x3E,  0x14,  0x24,  0x2A,  0x24,  0x49,  0x3F,  0xBE,  0x00,  0xAA,  0x34,  0xBE,  0x2A,  0x8C,  0x2A,  0x8A, 	/* 547D0 */
+	0x40,  0xFD,  0x03,  0x01,  0xBE,  0x00,  0x00,  0x3F,  0x7E,  0x24,  0x52,  0x24,  0x7E,  0x3F,  0x52,  0x24, 	/* 547E0 */
+	0x7E,  0x3F,  0x10,  0x24,  0x64,  0x24,  0x18,  0x3F,  0x36,  0x05,  0xFD,  0x33,  0x08,  0x2B,  0x2C,  0x29, 	/* 547F0 */
+	0x2A,  0x41,  0x49,  0x06,  0x08,  0x80,  0x02,  0x20,  0x3F,  0xFF,  0x02,  0x20,  0x0F,  0xF8,  0x08,  0x08, 	/* 54800 */
+	0x0F,  0xF8,  0x08,  0x08,  0x0F,  0xF8,  0x01,  0x00,  0x7F,  0xFF,  0x0C,  0x88,  0x17,  0xF4,  0x64,  0x83, 	/* 54810 */
+	0x17,  0xFC,  0x12,  0x54,  0x21,  0x18,  0x82,  0x00,  0x10,  0x3F,  0xA8,  0x24,  0x7C,  0x24,  0x44,  0x3E, 	/* 54820 */
+	0xAA,  0x24,  0xFF,  0x3E,  0x10,  0x24,  0x28,  0x24,  0x24,  0x3F,  0x4B,  0x05,  0xB4,  0x33,  0x08,  0x2B, 	/* 54830 */
+	0x72,  0x29,  0x04,  0x41,  0x18,  0x06,  0xE0,  0x83,  0x00,  0x00,  0x3F,  0xFF,  0x24,  0x14,  0x24,  0x7F, 	/* 54840 */
+	0x3F,  0x55,  0x24,  0x55,  0x3F,  0x7F,  0x24,  0x00,  0x24,  0x3E,  0x3F,  0x80,  0x04,  0xFF,  0x12,  0x88, 	/* 54850 */
+	0x2A,  0xAC,  0x28,  0xAA,  0x41,  0x49,  0x06,  0x18,  0x85,  0x00,  0x00,  0x3F,  0x7F,  0x24,  0x40,  0x24, 	/* 54860 */
+	0x5C,  0x3F,  0x54,  0x24,  0x54,  0x3F,  0x5C,  0x24,  0x40,  0x24,  0x7E,  0x3F,  0x6A,  0x05,  0x6A,  0x33, 	/* 54870 */
+	0x7E,  0x2B,  0x40,  0x29,  0x40,  0x41,  0x7F,  0x06,  0x00,  0x8D,  0x00,  0x10,  0x3F,  0x7C,  0x24,  0x10, 	/* 54880 */
+	0x24,  0xFE,  0x3F,  0x00,  0x24,  0x44,  0x3F,  0xFF,  0x24,  0x44,  0x24,  0x74,  0x3F,  0xCF,  0x05,  0x00, 	/* 54890 */
+	0x33,  0xFF,  0x2B,  0x28,  0x29,  0x29,  0x42,  0x49,  0x0D,  0x87,  0x95,  0x00,  0x04,  0x3F,  0xF8,  0x28, 	/* 548A0 */
+	0x10,  0x28,  0xFF,  0x3E,  0x24,  0x28,  0x7E,  0x3E,  0xA5,  0x28,  0x3C,  0x28,  0x00,  0x3E,  0xFE,  0x0A, 	/* 548B0 */
+	0x82,  0x36,  0xBA,  0x2A,  0xAA,  0x2A,  0xBA,  0x42,  0x82,  0x0C,  0x86,  0x97,  0x00,  0x10,  0x3F,  0x90, 	/* 548C0 */
+	0x24,  0x28,  0x24,  0x24,  0x3F,  0x42,  0x24,  0xBD,  0x3F,  0x00,  0x24,  0xEE,  0x24,  0xAA,  0x3F,  0xAA, 	/* 548D0 */
+	0x05,  0xEE,  0x33,  0x44,  0x2B,  0x44,  0x29,  0x66,  0x42,  0x99,  0x0D,  0x10,  0x9A,  0x0A,  0x20,  0x3F, 	/* 548E0 */
+	0xBF,  0x0A,  0x24,  0x1F,  0xD4,  0x1E,  0x98,  0x2A,  0x88,  0x4E,  0x94,  0x03,  0x22,  0x0F,  0xF9,  0x08, 	/* 548F0 */
+	0x80,  0x0F,  0xF8,  0x08,  0x80,  0x0F,  0xFC,  0x29,  0x24,  0x24,  0x94,  0x40,  0x18,  0x9B,  0x00,  0x00, 	/* 54900 */
+	0x3F,  0xFE,  0x24,  0xAA,  0x24,  0xFE,  0x3F,  0x10,  0x24,  0x7C,  0x3F,  0x10,  0x24,  0xFF,  0x24,  0x44, 	/* 54910 */
+	0x3F,  0x28,  0x05,  0xFF,  0x33,  0x10,  0x2B,  0xFE,  0x29,  0x10,  0x41,  0x10,  0x06,  0x10,  0x9F,  0x00, 	/* 54920 */
+	0x00,  0x3F,  0xF0,  0x24,  0xBE,  0x24,  0xE2,  0x3E,  0xAA,  0x24,  0xE4,  0x3E,  0xA4,  0x25,  0xEA,  0x24, 	/* 54930 */
+	0x31,  0x3E,  0x48,  0x02,  0x52,  0x2A,  0x94,  0x2A,  0x58,  0x2A,  0x54,  0x42,  0x93,  0x0C,  0x10,  0xA2, 	/* 54940 */
+	0x00,  0x10,  0x3F,  0x1E,  0x24,  0x10,  0x24,  0xFF,  0x3E,  0x9A,  0x24,  0xF1,  0x3E,  0xBF,  0x24,  0xAA, 	/* 54950 */
+	0x24,  0xBE,  0x3E,  0xAA,  0x02,  0xBE,  0x2A,  0x80,  0x2A,  0xFE,  0x23,  0x5A,  0x43,  0xFF,  0x0C,  0x00, 	/* 54960 */
+	0xA4,  0x00,  0x10,  0x3F,  0xFF,  0x24,  0x00,  0x24,  0xEE,  0x3E,  0xAA,  0x24,  0xEE,  0x3E,  0x28,  0x24, 	/* 54970 */
+	0xFE,  0x24,  0x28,  0x3F,  0xFE,  0x05,  0x28,  0x33,  0xFF,  0x2B,  0x6A,  0x29,  0xA4,  0x41,  0x32,  0x06, 	/* 54980 */
+	0xC1,  0xA5,  0x00,  0x15,  0x3F,  0x76,  0x24,  0x14,  0x24,  0x35,  0x3F,  0xC3,  0x24,  0x7E,  0x3F,  0x4A, 	/* 54990 */
+	0x24,  0x7E,  0x24,  0x4A,  0x3F,  0x7E,  0x05,  0x24,  0x33,  0x7E,  0x2B,  0x24,  0x29,  0xFF,  0x41,  0x24, 	/* 549A0 */
+	0x06,  0x42,  0xA9,  0x00,  0x24,  0x3F,  0xFF,  0x24,  0x24,  0x24,  0xEE,  0x3F,  0xAA,  0x24,  0xEE,  0x3F, 	/* 549B0 */
+	0x12,  0x24,  0x24,  0x24,  0x7F,  0x3F,  0x48,  0x05,  0xFE,  0x33,  0x48,  0x2B,  0x7E,  0x29,  0x48,  0x41, 	/* 549C0 */
+	0x7F,  0x06,  0x00,  0xAA,  0x00,  0x00,  0x3F,  0xEF,  0x24,  0x00,  0x25,  0xEF,  0x3F,  0x29,  0x24,  0x10, 	/* 549D0 */
+	0x3E,  0xFF,  0x24,  0xA8,  0x24,  0xFE,  0x3E,  0xAA,  0x02,  0xFE,  0x2A,  0xA4,  0x2A,  0xBF,  0x2B,  0x24, 	/* 549E0 */
+	0x42,  0x35,  0x0C,  0xC3,  0xAB,  0x00,  0x00,  0x07,  0xF8,  0x04,  0x80,  0x07,  0xF0,  0x04,  0x80,  0x17, 	/* 549F0 */
+	0xF8,  0x12,  0xA8,  0x20,  0x18,  0x1F,  0xBF,  0x14,  0x28,  0x1F,  0x3E,  0x14,  0x28,  0x1F,  0xBF,  0x2A, 	/* 54A00 */
+	0xD5,  0x28,  0xD1,  0x43,  0x06,  0xA8,  0x00,  0x00,  0x0F,  0xF0,  0x08,  0x10,  0x09,  0xF0,  0x09,  0x10, 	/* 54A10 */
+	0x7F,  0xFE,  0x40,  0x02,  0x4F,  0xF2,  0x08,  0x10,  0x0F,  0xF0,  0x08,  0x10,  0x0F,  0xF0,  0x08,  0x10, 	/* 54A20 */
+	0x08,  0x10,  0x08,  0x10,  0x08,  0x30,  0xAD,  0x00,  0x00,  0x3F,  0x3E,  0x21,  0x08,  0x2F,  0x08,  0x29, 	/* 54A30 */
+	0x08,  0x29,  0x08,  0x7F,  0x88,  0x40,  0xFF,  0x5F,  0x88,  0x11,  0x08,  0x1F,  0x08,  0x11,  0x08,  0x1F, 	/* 54A40 */
+	0x08,  0x11,  0x08,  0x11,  0x08,  0x13,  0x08,  0xB0,  0x00,  0x00,  0x3F,  0x3C,  0x21,  0x24,  0x2F,  0x25, 	/* 54A50 */
+	0x29,  0x25,  0x29,  0x25,  0x7F,  0xC3,  0x40,  0x80,  0x1F,  0x7C,  0x11,  0x24,  0x1F,  0x24,  0x11,  0x14, 	/* 54A60 */
+	0x1F,  0x08,  0x11,  0x14,  0x11,  0x22,  0x13,  0xC1,  0xB8,  0x00,  0x10,  0x3E,  0x10,  0x22,  0x10,  0x2E, 	/* 54A70 */
+	0xFF,  0x2A,  0x10,  0x2A,  0x14,  0x7F,  0x64,  0x41,  0x28,  0x7F,  0x12,  0x62,  0x12,  0x3E,  0x24,  0x22, 	/* 54A80 */
+	0xC4,  0x3E,  0x08,  0x22,  0x14,  0x22,  0x22,  0x26,  0xC2,  0xBC,  0x00,  0x10,  0x3F,  0x10,  0x21,  0x3C, 	/* 54A90 */
+	0x2F,  0x24,  0x29,  0x44,  0x29,  0xA8,  0x7F,  0x90,  0x40,  0xA8,  0x5F,  0x44,  0x11,  0x82,  0x1F,  0x7D, 	/* 54AA0 */
+	0x11,  0x44,  0x1F,  0x44,  0x11,  0x44,  0x11,  0x7C,  0x13,  0x00,  0x80,  0x00,  0x10,  0x3E,  0x20,  0x22, 	/* 54AB0 */
+	0x7E,  0x2E,  0x52,  0x2A,  0x52,  0x2A,  0x7E,  0x7F,  0x52,  0x41,  0x52,  0x3F,  0x7E,  0x22,  0x28,  0x3E, 	/* 54AC0 */
+	0x48,  0x23,  0xFF,  0x3E,  0x08,  0x22,  0x08,  0x22,  0x08,  0x26,  0x08,  0x84,  0x00,  0x08,  0x3E,  0x08, 	/* 54AD0 */
+	0x22,  0x7F,  0x2E,  0x88,  0x2A,  0x50,  0x7F,  0x5E,  0x41,  0x32,  0x7E,  0x3E,  0x23,  0xD2,  0x3E,  0x52, 	/* 54AE0 */
+	0x22,  0x5E,  0x3E,  0x52,  0x22,  0x52,  0x22,  0xB6,  0x23,  0x10,  0x26,  0x0F,  0x8F,  0x00,  0x10,  0x3E, 	/* 54AF0 */
+	0x7E,  0x22,  0x52,  0x2E,  0xFF,  0x2A,  0x52,  0x2A,  0x7E,  0x7F,  0x10,  0x41,  0x7E,  0x3E,  0x52,  0x22, 	/* 54B00 */
+	0x7E,  0x3E,  0x10,  0x23,  0xFF,  0x3E,  0x24,  0x22,  0x68,  0x22,  0x1C,  0x26,  0xE2,  0x91,  0x00,  0x00, 	/* 54B10 */
+	0x3E,  0xFE,  0x22,  0xAA,  0x2E,  0xAA,  0x2A,  0xFE,  0x2A,  0x40,  0x7F,  0x7E,  0x41,  0xA2,  0x3F,  0xFA, 	/* 54B20 */
+	0x22,  0xAA,  0x3E,  0xFA,  0x22,  0x32,  0x3E,  0x2A,  0x23,  0xF6,  0x22,  0x02,  0x26,  0x0C,  0x93,  0x00, 	/* 54B30 */
+	0x10,  0x3F,  0x7F,  0x22,  0x90,  0x2E,  0x9E,  0x2A,  0x24,  0x2B,  0x5F,  0x7E,  0x80,  0x42,  0x9E,  0x3E, 	/* 54B40 */
+	0x12,  0x25,  0xDE,  0x3C,  0x52,  0x24,  0x5E,  0x3C,  0x52,  0x24,  0xB6,  0x24,  0x98,  0x2D,  0x07,  0x94, 	/* 54B50 */
+	0x00,  0x28,  0x3E,  0xFE,  0x22,  0xAA,  0x2E,  0xFE,  0x2A,  0xAA,  0x2A,  0xFE,  0x7F,  0x00,  0x41,  0xFF, 	/* 54B60 */
+	0x3F,  0x00,  0x22,  0x7C,  0x3E,  0x44,  0x22,  0x7C,  0x3E,  0x44,  0x22,  0x28,  0x23,  0xFF,  0x26,  0x00, 	/* 54B70 */
+	0x98,  0x00,  0x80,  0x00,  0x80,  0x7F,  0xFF,  0x00,  0x00,  0x07,  0xF0,  0x04,  0x10,  0x07,  0xF0,  0x00, 	/* 54B80 */
+	0x00,  0x3F,  0xFE,  0x20,  0x02,  0x27,  0xF2,  0x24,  0x12,  0x24,  0x12,  0x27,  0xF2,  0x20,  0x02,  0x20, 	/* 54B90 */
+	0x06,  0x9E,  0x08,  0x00,  0x08,  0x7C,  0x7F,  0x44,  0x00,  0x44,  0x3E,  0x7C,  0x22,  0xEE,  0x3E,  0xAA, 	/* 54BA0 */
+	0x00,  0xAA,  0x7F,  0xEE,  0x41,  0x10,  0x5D,  0xFF,  0x55,  0x38,  0x55,  0x54,  0x5D,  0x92,  0x41,  0x11, 	/* 54BB0 */
+	0x43,  0x10,  0x9F,  0x00,  0x04,  0x1F,  0x84,  0x10,  0x08,  0x1F,  0x08,  0x10,  0x12,  0x10,  0x22,  0x1F, 	/* 54BC0 */
+	0x44,  0x10,  0x04,  0x10,  0x09,  0x7F,  0xD1,  0x14,  0x22,  0x12,  0x02,  0x11,  0x04,  0x23,  0x08,  0x7C, 	/* 54BD0 */
+	0x90,  0x00,  0xA0,  0xA2,  0x00,  0x04,  0x1F,  0x18,  0x10,  0x62,  0x1E,  0x0C,  0x10,  0x31,  0x7F,  0xC2, 	/* 54BE0 */
+	0x12,  0x0C,  0x1D,  0x30,  0x70,  0xC0,  0x04,  0x44,  0x04,  0x7C,  0x07,  0xC4,  0x7C,  0x44,  0x04,  0x59, 	/* 54BF0 */
+	0x04,  0x01,  0x03,  0xFF,  0xA3,  0x00,  0x04,  0x1F,  0x18,  0x10,  0x62,  0x1E,  0x04,  0x10,  0x19,  0x7F, 	/* 54C00 */
+	0xE2,  0x12,  0x04,  0x1D,  0x18,  0x70,  0xE0,  0x00,  0x80,  0x7F,  0xFF,  0x00,  0x80,  0x01,  0xF8,  0x02, 	/* 54C10 */
+	0x08,  0x0C,  0x08,  0x30,  0x70,  0xA6,  0x00,  0x04,  0x1F,  0x18,  0x10,  0x62,  0x1E,  0x0C,  0x10,  0x31, 	/* 54C20 */
+	0x7F,  0xC6,  0x12,  0x18,  0x7D,  0x60,  0x00,  0x10,  0x0F,  0xE0,  0x02,  0x00,  0x3F,  0xF8,  0x02,  0x00, 	/* 54C30 */
+	0x7F,  0xFE,  0x02,  0x04,  0x01,  0xFC,  0xAA,  0x00,  0x04,  0x1F,  0x98,  0x10,  0x60,  0x1F,  0x02,  0x10, 	/* 54C40 */
+	0x0C,  0x7F,  0x71,  0x12,  0x02,  0x1D,  0x0C,  0x21,  0x70,  0x7F,  0xFF,  0x01,  0x00,  0x03,  0xF0,  0x0E, 	/* 54C50 */
+	0x20,  0x71,  0xC0,  0x03,  0x60,  0x3C,  0x1E,  0xAB,  0x00,  0x04,  0x1F,  0x18,  0x10,  0x62,  0x1E,  0x0C, 	/* 54C60 */
+	0x10,  0x31,  0x7F,  0xC6,  0x12,  0x18,  0x7D,  0x60,  0x00,  0x00,  0x3F,  0xFC,  0x01,  0x04,  0x06,  0x0C, 	/* 54C70 */
+	0x38,  0x00,  0x0F,  0xF8,  0x08,  0x08,  0x0F,  0xF8,  0xAD,  0x00,  0x04,  0x1F,  0x98,  0x10,  0x62,  0x1F, 	/* 54C80 */
+	0x0C,  0x10,  0x31,  0x7F,  0xC2,  0x0A,  0x0C,  0x13,  0x70,  0x3C,  0x80,  0x04,  0x20,  0x24,  0x22,  0x27, 	/* 54C90 */
+	0xEC,  0x24,  0x30,  0x25,  0xA1,  0x2E,  0x21,  0x70,  0x1F,  0xAE,  0x00,  0x04,  0x1F,  0x18,  0x10,  0x62, 	/* 54CA0 */
+	0x1E,  0x0C,  0x10,  0x31,  0x7F,  0xC6,  0x12,  0x18,  0x7D,  0x60,  0x00,  0x88,  0x00,  0x84,  0x7F,  0xFF, 	/* 54CB0 */
+	0x01,  0x08,  0x02,  0x90,  0x0C,  0x60,  0x71,  0x98,  0x0E,  0x07,  0xAF,  0x00,  0x04,  0x1F,  0x18,  0x10, 	/* 54CC0 */
+	0x62,  0x1E,  0x0C,  0x10,  0x31,  0x7F,  0xC6,  0x12,  0x18,  0x7D,  0x60,  0x00,  0x80,  0x0F,  0xF8,  0x08, 	/* 54CD0 */
+	0x88,  0x0F,  0xF8,  0x08,  0x88,  0x7F,  0xFF,  0x08,  0x08,  0x08,  0x18,  0xB1,  0x00,  0x04,  0x1F,  0x18, 	/* 54CE0 */
+	0x10,  0x62,  0x1E,  0x0C,  0x10,  0x31,  0x7F,  0xC6,  0x12,  0x18,  0x7D,  0x60,  0x02,  0x20,  0x03,  0xFC, 	/* 54CF0 */
+	0x04,  0x04,  0x1F,  0xE4,  0x64,  0x24,  0x07,  0xF9,  0x04,  0x01,  0x03,  0xFF,  0xB4,  0x00,  0x04,  0x1F, 	/* 54D00 */
+	0x18,  0x10,  0x62,  0x1E,  0x0C,  0x10,  0x31,  0x7F,  0xC6,  0x12,  0x18,  0x7D,  0x60,  0x1F,  0xFC,  0x02, 	/* 54D10 */
+	0x24,  0x1F,  0xFC,  0x12,  0x20,  0x1F,  0xFE,  0x02,  0x22,  0x04,  0x2C,  0x08,  0x20,  0xB7,  0x00,  0x04, 	/* 54D20 */
+	0x1F,  0x18,  0x10,  0x62,  0x1E,  0x0C,  0x10,  0x31,  0x7F,  0xC6,  0x12,  0x18,  0x7D,  0x60,  0x02,  0x20, 	/* 54D30 */
+	0x1F,  0xFC,  0x12,  0x24,  0x1F,  0xFC,  0x12,  0x24,  0x12,  0x24,  0x1F,  0xFC,  0x00,  0x00,  0xBB,  0x00, 	/* 54D40 */
+	0x04,  0x1F,  0x18,  0x10,  0x62,  0x1E,  0x0C,  0x10,  0x31,  0x7F,  0xC6,  0x12,  0x18,  0x7D,  0x60,  0x00, 	/* 54D50 */
+	0x80,  0x7F,  0xFF,  0x00,  0x80,  0x3F,  0xFE,  0x00,  0x00,  0x0F,  0xF8,  0x08,  0x08,  0x0F,  0xF8,  0x86, 	/* 54D60 */
+	0x00,  0x04,  0x1F,  0x18,  0x10,  0x62,  0x1E,  0x0C,  0x10,  0x31,  0x7F,  0xC6,  0x12,  0x18,  0x7D,  0x60, 	/* 54D70 */
+	0x08,  0x5C,  0x7F,  0x44,  0x08,  0x54,  0x1C,  0x92,  0x1B,  0x31,  0x28,  0x48,  0x49,  0xFC,  0x08,  0x02, 	/* 54D80 */
+	0x98,  0x00,  0x04,  0x1F,  0x18,  0x10,  0x62,  0x1E,  0x0C,  0x10,  0x31,  0x7F,  0xC6,  0x12,  0x18,  0x7D, 	/* 54D90 */
+	0x60,  0x07,  0xF0,  0x04,  0x10,  0x1F,  0xFC,  0x12,  0x24,  0x7F,  0xFC,  0x06,  0x30,  0x01,  0xC0,  0x7E, 	/* 54DA0 */
+	0x3F,  0x9A,  0x00,  0x04,  0x1F,  0x18,  0x10,  0x62,  0x1E,  0x0C,  0x10,  0x31,  0x7F,  0xC6,  0x12,  0x18, 	/* 54DB0 */
+	0x7D,  0x60,  0x04,  0xFF,  0x18,  0x10,  0x62,  0x7E,  0x0C,  0x42,  0x31,  0x7E,  0x02,  0x42,  0x0C,  0x7E, 	/* 54DC0 */
+	0x71,  0xC1,  0x9F,  0x00,  0x04,  0x1F,  0x18,  0x10,  0x62,  0x1E,  0x0C,  0x10,  0x31,  0x7F,  0xC6,  0x12, 	/* 54DD0 */
+	0x18,  0x7D,  0x60,  0x0F,  0xFC,  0x09,  0x24,  0x7F,  0xFF,  0x04,  0x10,  0x07,  0xF4,  0x01,  0x48,  0x3E, 	/* 54DE0 */
+	0x30,  0x03,  0x0F,  0xA2,  0x00,  0x04,  0x1F,  0x18,  0x10,  0x62,  0x1E,  0x0C,  0x10,  0x31,  0x7F,  0xC6, 	/* 54DF0 */
+	0x12,  0x18,  0x7D,  0x60,  0x3F,  0xFE,  0x29,  0x22,  0x33,  0xF0,  0x0C,  0x10,  0x77,  0xF0,  0x04,  0x10, 	/* 54E00 */
+	0x07,  0xF0,  0x1C,  0x0C,  0xA3,  0x1F,  0x0C,  0x10,  0xF0,  0x1E,  0x06,  0x10,  0x78,  0x7F,  0x03,  0x12, 	/* 54E10 */
+	0x3C,  0x7D,  0x48,  0x04,  0x90,  0x3F,  0xFC,  0x25,  0x24,  0x3F,  0xFC,  0x10,  0x88,  0x1E,  0xE8,  0x10, 	/* 54E20 */
+	0x89,  0x1E,  0xE5,  0x71,  0x83,  0xA5,  0x00,  0x00,  0x5F,  0x7A,  0x44,  0x22,  0x5F,  0x7A,  0x44,  0x22, 	/* 54E30 */
+	0x5F,  0x7A,  0x40,  0x02,  0x40,  0x02,  0x40,  0x02,  0x40,  0x02,  0x40,  0x02,  0x40,  0x02,  0x40,  0x02, 	/* 54E40 */
+	0x40,  0x02,  0x40,  0x02,  0x40,  0x06,  0xA7,  0x00,  0x00,  0x5F,  0x7A,  0x44,  0x22,  0x5E,  0x7A,  0x44, 	/* 54E50 */
+	0x22,  0x5F,  0x7A,  0x40,  0x02,  0x41,  0x02,  0x5F,  0xFA,  0x41,  0x02,  0x4F,  0xF2,  0x49,  0x12,  0x49, 	/* 54E60 */
+	0x12,  0x49,  0x62,  0x49,  0x02,  0x41,  0x06,  0xA8,  0x00,  0x00,  0x5F,  0x7A,  0x44,  0x22,  0x5E,  0x7A, 	/* 54E70 */
+	0x44,  0x22,  0x5F,  0x7A,  0x40,  0x02,  0x42,  0x42,  0x4F,  0xF2,  0x42,  0x42,  0x42,  0x42,  0x5F,  0xFA, 	/* 54E80 */
+	0x42,  0x42,  0x44,  0x22,  0x58,  0x12,  0x40,  0x06,  0xA9,  0x00,  0x00,  0x5F,  0x7A,  0x44,  0x22,  0x5E, 	/* 54E90 */
+	0x7A,  0x44,  0x22,  0x5F,  0x7A,  0x41,  0x02,  0x4E,  0x72,  0x48,  0x12,  0x4E,  0x72,  0x48,  0x12,  0x4F, 	/* 54EA0 */
+	0xF2,  0x41,  0x42,  0x46,  0x4A,  0x58,  0x3A,  0x40,  0x06,  0xAA,  0x00,  0x00,  0x5F,  0x7A,  0x44,  0x12, 	/* 54EB0 */
+	0x5E,  0x7A,  0x44,  0x12,  0x5F,  0x7A,  0x40,  0x02,  0x5F,  0x92,  0x40,  0x12,  0x4F,  0xFE,  0x49,  0x92, 	/* 54EC0 */
+	0x4F,  0x52,  0x51,  0x12,  0x4A,  0x12,  0x47,  0x12,  0x58,  0x32,  0xAE,  0x00,  0x00,  0x5F,  0x7A,  0x44, 	/* 54ED0 */
+	0x12,  0x4E,  0x7A,  0x44,  0x12,  0x5F,  0x7A,  0x43,  0xC2,  0x4C,  0x82,  0x5F,  0xFA,  0x45,  0x6A,  0x5D, 	/* 54EE0 */
+	0x5A,  0x45,  0x6A,  0x5F,  0xFA,  0x45,  0x42,  0x5D,  0x4A,  0x41,  0x3A,  0xAF,  0x01,  0x00,  0x20,  0xA4, 	/* 54EF0 */
+	0x26,  0x24,  0x21,  0x44,  0x30,  0x94,  0x29,  0x4C,  0x22,  0x24,  0x2D,  0x24,  0x20,  0x84,  0x3F,  0xFC, 	/* 54F00 */
+	0x08,  0x08,  0x08,  0x30,  0x0F,  0xC0,  0x08,  0x02,  0x08,  0x02,  0x07,  0xFE,  0xB1,  0x09,  0x08,  0x09, 	/* 54F10 */
+	0xE8,  0x7E,  0x9F,  0x19,  0xEC,  0x2E,  0xBA,  0x4B,  0xE9,  0x08,  0x08,  0x7F,  0xFE,  0x4A,  0x82,  0x24, 	/* 54F20 */
+	0x8A,  0x2A,  0xF0,  0x3F,  0x84,  0x12,  0x78,  0x1C,  0x02,  0x11,  0x0C,  0x0F,  0x70,  0xB2,  0x00,  0x00, 	/* 54F30 */
+	0x7F,  0xFF,  0x00,  0x00,  0x0F,  0xF8,  0x08,  0x08,  0x0F,  0xF8,  0x00,  0x00,  0x3F,  0xFE,  0x22,  0x22, 	/* 54F40 */
+	0x22,  0x26,  0x24,  0x1E,  0x2B,  0xF2,  0x30,  0x82,  0x20,  0x82,  0x20,  0x82,  0x20,  0x06,  0xBB,  0x78, 	/* 54F50 */
+	0x9E,  0x0A,  0xA2,  0x39,  0xCE,  0x27,  0xF8,  0x39,  0xCE,  0x0A,  0xA2,  0x30,  0x8C,  0x7F,  0xFF,  0x08, 	/* 54F60 */
+	0x08,  0x0F,  0xF8,  0x00,  0x00,  0x3F,  0xFE,  0x22,  0x26,  0x2C,  0x1E,  0x23,  0xE2,  0x20,  0x86,  0xBC, 	/* 54F70 */
+	0x01,  0x00,  0x02,  0x00,  0x1F,  0xF8,  0x11,  0x08,  0x11,  0x08,  0x1F,  0xF8,  0x11,  0x08,  0x11,  0x08, 	/* 54F80 */
+	0x1F,  0xF8,  0x02,  0x90,  0x02,  0x90,  0x04,  0xA8,  0x04,  0xF8,  0x08,  0x8A,  0x10,  0x42,  0x60,  0x3E, 	/* 54F90 */
+	0x81,  0x08,  0x04,  0x10,  0x44,  0x3F,  0x24,  0x25,  0x14,  0x25,  0x94,  0x3F,  0x44,  0x25,  0x24,  0x25, 	/* 54FA0 */
+	0x24,  0x3F,  0x07,  0x0C,  0xFC,  0x0C,  0x84,  0x0D,  0x44,  0x17,  0xC4,  0x14,  0x06,  0x22,  0x02,  0x41, 	/* 54FB0 */
+	0xFE,  0x82,  0x00,  0x20,  0x00,  0x40,  0x3D,  0xFC,  0x01,  0x24,  0x01,  0x24,  0x01,  0xFC,  0x7F,  0x24, 	/* 54FC0 */
+	0x09,  0x24,  0x09,  0xFC,  0x08,  0x54,  0x14,  0x54,  0x12,  0x5A,  0x1E,  0x5E,  0x62,  0x91,  0x03,  0x11, 	/* 54FD0 */
+	0x0C,  0x0F,  0x83,  0x08,  0x20,  0x08,  0x24,  0x10,  0x22,  0x3E,  0xFF,  0x2A,  0x20,  0x2A,  0x24,  0x3E, 	/* 54FE0 */
+	0x24,  0x2A,  0x34,  0x2A,  0x54,  0x3F,  0x58,  0x15,  0x48,  0x16,  0xC8,  0x17,  0x94,  0x14,  0xA2,  0x23, 	/* 54FF0 */
+	0x41,  0x41,  0xFF,  0x84,  0x08,  0x20,  0x08,  0x40,  0x11,  0xFC,  0x3D,  0x24,  0x25,  0x24,  0x25,  0xFC, 	/* 55000 */
+	0x25,  0x24,  0x3D,  0x24,  0x25,  0xFC,  0x24,  0x54,  0x24,  0x54,  0x24,  0x5A,  0x3C,  0x9E,  0x00,  0x91, 	/* 55010 */
+	0x01,  0x11,  0x06,  0x0F,  0x85,  0x08,  0x08,  0x10,  0x08,  0x3F,  0x08,  0x29,  0x7E,  0x29,  0x08,  0x3F, 	/* 55020 */
+	0x08,  0x29,  0xFF,  0x29,  0x08,  0x3F,  0x9C,  0x14,  0x9C,  0x14,  0xAA,  0x15,  0x49,  0x15,  0x48,  0x27, 	/* 55030 */
+	0xA9,  0x22,  0x01,  0x41,  0xFF,  0x8D,  0x08,  0x00,  0x08,  0xFE,  0x10,  0x82,  0x3E,  0xC6,  0x2A,  0xAA, 	/* 55040 */
+	0x2A,  0xFE,  0x3E,  0x92,  0x2A,  0x92,  0x2A,  0xBE,  0x3E,  0xA2,  0x15,  0xA2,  0x16,  0x9A,  0x17,  0x82, 	/* 55050 */
+	0x14,  0x86,  0x22,  0x01,  0x41,  0xFF,  0x8E,  0x08,  0x00,  0x09,  0xFF,  0x10,  0x10,  0x3E,  0x10,  0x2A, 	/* 55060 */
+	0xFE,  0x2A,  0x92,  0x3E,  0x92,  0x2A,  0xFE,  0x2A,  0xB6,  0x3E,  0xB6,  0x15,  0xDA,  0x16,  0x92,  0x17, 	/* 55070 */
+	0x92,  0x14,  0x86,  0x22,  0x01,  0x41,  0xFF,  0x8F,  0x02,  0x10,  0x04,  0x20,  0x38,  0x7E,  0x08,  0x52, 	/* 55080 */
+	0x7F,  0x52,  0x1C,  0x7E,  0x2A,  0x52,  0x49,  0x52,  0x08,  0x7E,  0x7F,  0xAA,  0x12,  0x2A,  0x12,  0x2D, 	/* 55090 */
+	0x3C,  0x4F,  0x06,  0x48,  0x09,  0x89,  0x31,  0x07,  0x91,  0x08,  0x10,  0x09,  0xFF,  0x10,  0x6C,  0x3E, 	/* 550A0 */
+	0x54,  0x2A,  0x6C,  0x2A,  0x7C,  0x3E,  0x10,  0x2A,  0xFE,  0x2A,  0x92,  0x3E,  0xAA,  0x15,  0xFE,  0x16, 	/* 550B0 */
+	0x86,  0x17,  0x82,  0x14,  0x86,  0x22,  0x01,  0x41,  0xFF,  0x94,  0x00,  0x40,  0x1F,  0xFF,  0x11,  0x08, 	/* 550C0 */
+	0x1F,  0xFF,  0x11,  0x8C,  0x13,  0x5A,  0x15,  0x29,  0x1B,  0xFC,  0x12,  0x44,  0x13,  0xFC,  0x12,  0x44, 	/* 550D0 */
+	0x13,  0xFC,  0x20,  0xAA,  0x21,  0x2E,  0x46,  0x21,  0x18,  0x1F,  0x98,  0x00,  0x00,  0x1F,  0xFF,  0x14, 	/* 550E0 */
+	0x94,  0x17,  0x92,  0x14,  0xFF,  0x17,  0x98,  0x14,  0x94,  0x15,  0xA2,  0x14,  0x41,  0x13,  0xF8,  0x12, 	/* 550F0 */
+	0x48,  0x13,  0xF8,  0x22,  0x4C,  0x23,  0xF9,  0x41,  0x2D,  0x1E,  0x3F,  0x9A,  0x02,  0x00,  0x02,  0x00, 	/* 55100 */
+	0x03,  0xF0,  0x04,  0x20,  0x18,  0x40,  0x6F,  0xF8,  0x08,  0x88,  0x08,  0x88,  0x0F,  0xF8,  0x08,  0x88, 	/* 55110 */
+	0x08,  0x88,  0x0F,  0xF8,  0x10,  0x08,  0x14,  0x44,  0x22,  0x22,  0x42,  0x22,  0xAF,  0x02,  0x00,  0x07, 	/* 55120 */
+	0xE0,  0x18,  0x40,  0x7F,  0xFC,  0x10,  0x84,  0x1F,  0xFC,  0x10,  0x84,  0x1F,  0xFC,  0x14,  0x48,  0x22, 	/* 55130 */
+	0x24,  0x4F,  0xFA,  0x08,  0x08,  0x0F,  0xF8,  0x08,  0x08,  0x0F,  0xF8,  0x00,  0x00,  0xB4,  0x10,  0x10, 	/* 55140 */
+	0x1E,  0x10,  0x12,  0x10,  0x24,  0xFF,  0x7F,  0x10,  0x29,  0x10,  0x29,  0x1E,  0x3F,  0x12,  0x29,  0x12, 	/* 55150 */
+	0x29,  0x12,  0x3F,  0x12,  0x05,  0x22,  0x32,  0xA2,  0x2A,  0x42,  0x28,  0x84,  0x41,  0x18,  0x83,  0x08, 	/* 55160 */
+	0x00,  0x0E,  0xFE,  0x12,  0x10,  0x24,  0x54,  0x7F,  0x54,  0x29,  0x52,  0x29,  0x92,  0x3F,  0x10,  0x29, 	/* 55170 */
+	0xFF,  0x29,  0x10,  0x3F,  0x10,  0x05,  0x10,  0x32,  0x90,  0x2A,  0x10,  0x28,  0x10,  0x40,  0x10,  0x8E, 	/* 55180 */
+	0x08,  0x10,  0x0E,  0x10,  0x12,  0x10,  0x24,  0x10,  0x7F,  0x1F,  0x29,  0x10,  0x29,  0x10,  0x3F,  0x10, 	/* 55190 */
+	0x29,  0x10,  0x29,  0x7E,  0x3F,  0x42,  0x02,  0x42,  0x15,  0x42,  0x2A,  0x42,  0x2A,  0x7E,  0x40,  0x00, 	/* 551A0 */
+	0x91,  0x08,  0x20,  0x0E,  0x20,  0x12,  0x3E,  0x24,  0x42,  0x7F,  0x42,  0x29,  0xFA,  0x29,  0x4A,  0x3F, 	/* 551B0 */
+	0x4A,  0x29,  0x7A,  0x29,  0x42,  0x3F,  0x5C,  0x05,  0x40,  0x32,  0xC1,  0x2A,  0x41,  0x28,  0x3F,  0x40, 	/* 551C0 */
+	0x00,  0x92,  0x08,  0x12,  0x0E,  0x12,  0x12,  0x12,  0x24,  0x22,  0x7F,  0x3F,  0x29,  0x62,  0x29,  0xB2, 	/* 551D0 */
+	0x3F,  0x2A,  0x29,  0x2A,  0x29,  0x2A,  0x3F,  0x22,  0x05,  0x22,  0x32,  0xA2,  0x2A,  0x22,  0x28,  0x22, 	/* 551E0 */
+	0x40,  0x26,  0x93,  0x08,  0x20,  0x0E,  0x20,  0x12,  0x20,  0x24,  0x3F,  0x7F,  0x50,  0x29,  0x50,  0x29, 	/* 551F0 */
+	0x90,  0x3F,  0x1E,  0x29,  0x10,  0x29,  0x10,  0x3F,  0x10,  0x05,  0x1E,  0x32,  0x90,  0x2A,  0x10,  0x28, 	/* 55200 */
+	0x10,  0x40,  0x10,  0x96,  0x08,  0x00,  0x0F,  0xFF,  0x12,  0x10,  0x24,  0x10,  0x7F,  0x10,  0x29,  0x20, 	/* 55210 */
+	0x29,  0x20,  0x3F,  0x7E,  0x29,  0x62,  0x29,  0xA2,  0x3F,  0x22,  0x05,  0x22,  0x32,  0xA2,  0x2A,  0x22, 	/* 55220 */
+	0x28,  0x3E,  0x40,  0x00,  0x97,  0x08,  0x20,  0x0E,  0x20,  0x12,  0x3C,  0x24,  0x44,  0x7F,  0x48,  0x29, 	/* 55230 */
+	0xA8,  0x29,  0x10,  0x3F,  0x28,  0x29,  0x44,  0x29,  0xB2,  0x3F,  0x09,  0x05,  0x00,  0x32,  0xA0,  0x2A, 	/* 55240 */
+	0x18,  0x28,  0x04,  0x40,  0x02,  0x9F,  0x08,  0x10,  0x0E,  0x10,  0x12,  0xFE,  0x24,  0x82,  0x7F,  0x92, 	/* 55250 */
+	0x29,  0x10,  0x29,  0xFF,  0x3F,  0x24,  0x29,  0x24,  0x29,  0x24,  0x3F,  0x48,  0x05,  0x78,  0x32,  0x98, 	/* 55260 */
+	0x2A,  0x24,  0x28,  0x42,  0x41,  0x82,  0xA0,  0x08,  0x20,  0x0E,  0x3C,  0x12,  0x44,  0x24,  0x88,  0x7F, 	/* 55270 */
+	0x7F,  0x29,  0x40,  0x29,  0x40,  0x3F,  0x5E,  0x29,  0x52,  0x29,  0x52,  0x3F,  0x52,  0x05,  0x56,  0x32, 	/* 55280 */
+	0xD0,  0x2A,  0x91,  0x28,  0x91,  0x41,  0x0F,  0xA8,  0x08,  0x40,  0x0E,  0x44,  0x12,  0x78,  0x24,  0x40, 	/* 55290 */
+	0x7F,  0x41,  0x29,  0x41,  0x29,  0x3F,  0x3F,  0x00,  0x29,  0x3E,  0x29,  0x22,  0x3F,  0x22,  0x05,  0x3E, 	/* 552A0 */
+	0x32,  0xA2,  0x2A,  0x22,  0x28,  0x3E,  0x40,  0x00,  0xAA,  0x08,  0x10,  0x0E,  0x10,  0x13,  0xFF,  0x24, 	/* 552B0 */
+	0x10,  0x7F,  0x10,  0x29,  0x20,  0x29,  0x3E,  0x3F,  0x62,  0x29,  0xA2,  0x29,  0x3E,  0x3F,  0x22,  0x05, 	/* 552C0 */
+	0x3E,  0x32,  0xA2,  0x2A,  0x22,  0x28,  0x22,  0x40,  0x26,  0xAB,  0x08,  0x10,  0x0E,  0x10,  0x12,  0x10, 	/* 552D0 */
+	0x24,  0xFF,  0x7F,  0x24,  0x29,  0x22,  0x29,  0x46,  0x3F,  0xA5,  0x29,  0x24,  0x29,  0x14,  0x3F,  0x18, 	/* 552E0 */
+	0x05,  0x08,  0x32,  0x94,  0x2A,  0x24,  0x28,  0x42,  0x41,  0x81,  0xAD,  0x08,  0x10,  0x0E,  0x10,  0x12, 	/* 552F0 */
+	0xFE,  0x24,  0x10,  0x7F,  0x10,  0x29,  0x10,  0x29,  0xFF,  0x3F,  0x00,  0x29,  0x10,  0x29,  0x10,  0x3F, 	/* 55300 */
+	0xFE,  0x02,  0x10,  0x35,  0x10,  0x2A,  0x10,  0x2B,  0xFF,  0x40,  0x00,  0xAE,  0x08,  0x44,  0x0E,  0x24, 	/* 55310 */
+	0x12,  0x28,  0x24,  0xFF,  0x7F,  0x10,  0x29,  0x10,  0x29,  0x7E,  0x3F,  0x10,  0x29,  0x10,  0x29,  0x10, 	/* 55320 */
+	0x3F,  0xFF,  0x02,  0x10,  0x15,  0x10,  0x2A,  0x90,  0x2A,  0x10,  0x40,  0x10,  0xB4,  0x08,  0x48,  0x0E, 	/* 55330 */
+	0x48,  0x12,  0x48,  0x24,  0x48,  0x7E,  0x7F,  0x2A,  0x88,  0x2A,  0x88,  0x3F,  0x9C,  0x2A,  0x9C,  0x2A, 	/* 55340 */
+	0xAA,  0x3E,  0xAA,  0x04,  0xC9,  0x32,  0x88,  0x2A,  0x88,  0x28,  0x88,  0x40,  0x88,  0xB9,  0x08,  0x10, 	/* 55350 */
+	0x0E,  0x54,  0x12,  0x52,  0x24,  0x92,  0x7F,  0x91,  0x29,  0x7E,  0x29,  0x42,  0x3F,  0x42,  0x29,  0x7E, 	/* 55360 */
+	0x29,  0x42,  0x3F,  0x42,  0x05,  0x7E,  0x32,  0xC2,  0x2A,  0x42,  0x28,  0x42,  0x40,  0x46,  0x80,  0x08, 	/* 55370 */
+	0x02,  0x0E,  0xFC,  0x12,  0x10,  0x24,  0x14,  0x7F,  0xE4,  0x29,  0x38,  0x29,  0x10,  0x3F,  0x24,  0x29, 	/* 55380 */
+	0xFE,  0x29,  0x11,  0x3F,  0x10,  0x04,  0x54,  0x32,  0x52,  0x2A,  0x92,  0x29,  0x11,  0x40,  0x10,  0x86, 	/* 55390 */
+	0x08,  0x14,  0x0E,  0x12,  0x12,  0xFF,  0x24,  0x10,  0x7F,  0x10,  0x29,  0x7E,  0x29,  0x52,  0x3F,  0x52, 	/* 553A0 */
+	0x29,  0x7E,  0x29,  0x52,  0x3F,  0x52,  0x05,  0x7E,  0x32,  0xD2,  0x2A,  0x52,  0x28,  0x52,  0x40,  0x56, 	/* 553B0 */
+	0x89,  0x08,  0x00,  0x0F,  0x7E,  0x12,  0x52,  0x24,  0x52,  0x7F,  0x7E,  0x29,  0x52,  0x29,  0x52,  0x3F, 	/* 553C0 */
+	0x52,  0x29,  0x7E,  0x29,  0x10,  0x3F,  0x10,  0x05,  0x7E,  0x32,  0x90,  0x2A,  0x10,  0x28,  0xFF,  0x40, 	/* 553D0 */
+	0x00,  0x8A,  0x18,  0x10,  0x04,  0x54,  0x60,  0x92,  0x11,  0x35,  0x04,  0x18,  0x19,  0xE0,  0x61,  0x00, 	/* 553E0 */
+	0x03,  0xE0,  0x0C,  0x40,  0x3F,  0xF8,  0x08,  0x88,  0x0F,  0xF8,  0x08,  0x88,  0x0F,  0xF8,  0x12,  0x22, 	/* 553F0 */
+	0x61,  0x11,  0x8F,  0x08,  0x12,  0x0E,  0x62,  0x13,  0xCA,  0x24,  0x4A,  0x7E,  0x4A,  0x2B,  0xFA,  0x2A, 	/* 55400 */
+	0x4A,  0x3E,  0x4A,  0x2A,  0xEA,  0x2A,  0xDA,  0x3F,  0x4A,  0x05,  0x4A,  0x32,  0x42,  0x2A,  0x42,  0x28, 	/* 55410 */
+	0x42,  0x40,  0x46,  0x91,  0x08,  0x08,  0x0E,  0x68,  0x12,  0x18,  0x24,  0x24,  0x7F,  0x50,  0x29,  0xFF, 	/* 55420 */
+	0x29,  0x20,  0x3F,  0x50,  0x29,  0x7E,  0x29,  0xD2,  0x3F,  0x52,  0x05,  0x52,  0x32,  0xD2,  0x2A,  0x5C, 	/* 55430 */
+	0x28,  0x50,  0x40,  0x10,  0x92,  0x08,  0x00,  0x0E,  0x7E,  0x12,  0x04,  0x24,  0x28,  0x7F,  0x10,  0x29, 	/* 55440 */
+	0x7E,  0x29,  0x52,  0x3F,  0x52,  0x29,  0x7E,  0x29,  0x52,  0x3F,  0x52,  0x05,  0x7E,  0x32,  0xD2,  0x2A, 	/* 55450 */
+	0x52,  0x28,  0x52,  0x40,  0x56,  0x94,  0x08,  0x92,  0x0E,  0x92,  0x13,  0x24,  0x25,  0x24,  0x7E,  0x92, 	/* 55460 */
+	0x2A,  0x92,  0x2A,  0x00,  0x3E,  0xFE,  0x2A,  0x92,  0x2A,  0x92,  0x3E,  0xFE,  0x05,  0x92,  0x32,  0x92, 	/* 55470 */
+	0x2A,  0x92,  0x28,  0xFE,  0x40,  0x00,  0x96,  0x08,  0x10,  0x0E,  0x10,  0x12,  0xFE,  0x24,  0x10,  0x7F, 	/* 55480 */
+	0xFE,  0x29,  0x10,  0x29,  0xFF,  0x3F,  0x00,  0x29,  0x7C,  0x29,  0x44,  0x3F,  0x7C,  0x05,  0x44,  0x32, 	/* 55490 */
+	0xFC,  0x2A,  0x44,  0x28,  0x44,  0x40,  0x4C,  0x9B,  0x08,  0x00,  0x0E,  0x7E,  0x12,  0x52,  0x24,  0x52, 	/* 554A0 */
+	0x7F,  0x7E,  0x29,  0x52,  0x29,  0x52,  0x3F,  0x7E,  0x29,  0x42,  0x29,  0x7A,  0x3F,  0x6A,  0x05,  0x6A, 	/* 554B0 */
+	0x32,  0xFA,  0x2A,  0xAA,  0x28,  0x82,  0x41,  0x06,  0xA1,  0x08,  0x24,  0x0E,  0x24,  0x12,  0x24,  0x24, 	/* 554C0 */
+	0xE7,  0x7F,  0x24,  0x29,  0x24,  0x29,  0x24,  0x3F,  0xE7,  0x29,  0x24,  0x29,  0x24,  0x3F,  0x64,  0x05, 	/* 554D0 */
+	0xA7,  0x32,  0x24,  0x2A,  0x44,  0x28,  0x44,  0x40,  0x84,  0xA2,  0x08,  0x10,  0x0E,  0x20,  0x12,  0x4E, 	/* 554E0 */
+	0x24,  0x42,  0x7F,  0x42,  0x29,  0x6E,  0x29,  0x42,  0x3F,  0x42,  0x29,  0x7E,  0x29,  0x28,  0x3F,  0x28, 	/* 554F0 */
+	0x05,  0x28,  0x32,  0xC8,  0x2A,  0x49,  0x28,  0x89,  0x41,  0x07,  0xA3,  0x08,  0x00,  0x0E,  0x7C,  0x12, 	/* 55500 */
+	0x44,  0x24,  0x44,  0x7F,  0x7C,  0x29,  0x44,  0x29,  0x44,  0x3F,  0x7C,  0x29,  0x20,  0x29,  0x7E,  0x3F, 	/* 55510 */
+	0xAA,  0x05,  0x2A,  0x32,  0x52,  0x2A,  0x92,  0x28,  0x22,  0x40,  0x0C,  0xA4,  0x08,  0x00,  0x0E,  0x7E, 	/* 55520 */
+	0x12,  0x42,  0x24,  0x42,  0x7F,  0x7E,  0x29,  0x42,  0x29,  0x42,  0x3F,  0x7E,  0x29,  0x00,  0x29,  0x48, 	/* 55530 */
+	0x3F,  0x4A,  0x05,  0x7C,  0x32,  0xC8,  0x2A,  0x49,  0x28,  0x79,  0x41,  0x87,  0xA8,  0x08,  0x10,  0x0E, 	/* 55540 */
+	0x10,  0x12,  0xFF,  0x24,  0x00,  0x7F,  0x7C,  0x29,  0x44,  0x29,  0x44,  0x3F,  0x44,  0x29,  0x7C,  0x29, 	/* 55550 */
+	0x10,  0x3F,  0x58,  0x02,  0x54,  0x35,  0x52,  0x2A,  0x92,  0x2A,  0x10,  0x40,  0x30,  0xB0,  0x08,  0x10, 	/* 55560 */
+	0x0E,  0x10,  0x12,  0x28,  0x24,  0x44,  0x7F,  0xBA,  0x29,  0x01,  0x29,  0xFC,  0x3F,  0x04,  0x29,  0x08, 	/* 55570 */
+	0x29,  0x10,  0x3F,  0x08,  0x04,  0x2A,  0x32,  0xA1,  0x2A,  0xA5,  0x29,  0x25,  0x40,  0x1C,  0xB1,  0x08, 	/* 55580 */
+	0x10,  0x0E,  0x1E,  0x12,  0x10,  0x24,  0xFF,  0x7E,  0x96,  0x2A,  0x98,  0x2A,  0xF0,  0x3E,  0x91,  0x2A, 	/* 55590 */
+	0x8F,  0x2A,  0x80,  0x3E,  0xA8,  0x05,  0xA8,  0x32,  0xA8,  0x29,  0x49,  0x2A,  0x49,  0x40,  0x87,  0xB2, 	/* 555A0 */
+	0x08,  0x84,  0x0E,  0x84,  0x12,  0x84,  0x25,  0xEA,  0x7E,  0x8A,  0x2A,  0x8A,  0x2A,  0xF1,  0x3E,  0xA8, 	/* 555B0 */
+	0x2A,  0xA4,  0x2A,  0xA4,  0x3E,  0xA0,  0x05,  0x30,  0x33,  0x28,  0x2A,  0x24,  0x28,  0x22,  0x40,  0xC2, 	/* 555C0 */
+	0xB5,  0x08,  0x10,  0x0E,  0x18,  0x12,  0x24,  0x24,  0xFA,  0x7F,  0x10,  0x29,  0xFF,  0x29,  0x28,  0x3F, 	/* 555D0 */
+	0x4C,  0x29,  0x93,  0x29,  0x64,  0x3F,  0x08,  0x05,  0x32,  0x32,  0xC4,  0x2A,  0x08,  0x28,  0x30,  0x40, 	/* 555E0 */
+	0xC0,  0x84,  0x08,  0x08,  0x0E,  0x0A,  0x12,  0x09,  0x24,  0xFF,  0x7E,  0x88,  0x2A,  0xF8,  0x2A,  0xAA, 	/* 555F0 */
+	0x3E,  0xAA,  0x2A,  0xFA,  0x2A,  0xDA,  0x3E,  0xE4,  0x05,  0xB4,  0x32,  0xAD,  0x2B,  0x4B,  0x29,  0x13, 	/* 55600 */
+	0x42,  0x21,  0x86,  0x08,  0x10,  0x0E,  0x10,  0x12,  0xFE,  0x24,  0x10,  0x7F,  0xFE,  0x29,  0x28,  0x29, 	/* 55610 */
+	0xFF,  0x3F,  0x44,  0x29,  0x82,  0x29,  0x7D,  0x3F,  0x44,  0x05,  0x7C,  0x32,  0xC4,  0x2A,  0x44,  0x28, 	/* 55620 */
+	0x7C,  0x40,  0x00,  0x88,  0x08,  0x94,  0x0E,  0x94,  0x13,  0xFF,  0x24,  0x94,  0x7E,  0x9C,  0x2A,  0x80, 	/* 55630 */
+	0x2A,  0xFE,  0x3E,  0x10,  0x2A,  0x10,  0x2B,  0xFF,  0x3E,  0x38,  0x05,  0x38,  0x32,  0x54,  0x2A,  0x92, 	/* 55640 */
+	0x29,  0x11,  0x40,  0x10,  0x89,  0x08,  0x10,  0x0E,  0x20,  0x12,  0x7C,  0x24,  0x44,  0x7F,  0x7C,  0x29, 	/* 55650 */
+	0x44,  0x29,  0x44,  0x3F,  0x7C,  0x29,  0x00,  0x29,  0x7E,  0x3F,  0x10,  0x05,  0x7E,  0x32,  0x90,  0x2A, 	/* 55660 */
+	0x10,  0x28,  0xFF,  0x40,  0x00,  0x8A,  0x08,  0x10,  0x0E,  0x10,  0x13,  0xFF,  0x24,  0x10,  0x7E,  0x10, 	/* 55670 */
+	0x2A,  0xFE,  0x2A,  0x96,  0x3E,  0xDA,  0x2A,  0xB2,  0x2A,  0xFE,  0x3E,  0x38,  0x05,  0x34,  0x32,  0x54, 	/* 55680 */
+	0x2A,  0x92,  0x29,  0x11,  0x40,  0x10,  0x8C,  0x08,  0x2C,  0x0E,  0x24,  0x12,  0x24,  0x25,  0x7E,  0x7F, 	/* 55690 */
+	0x5A,  0x29,  0x99,  0x29,  0x7E,  0x3F,  0x5A,  0x29,  0x6A,  0x29,  0x6E,  0x3F,  0x42,  0x05,  0x7E,  0x32, 	/* 556A0 */
+	0xC2,  0x2A,  0x42,  0x28,  0x7E,  0x40,  0x00,  0x8D,  0x08,  0x28,  0x0E,  0x48,  0x13,  0x88,  0x24,  0x8A, 	/* 556B0 */
+	0x7E,  0x9A,  0x2B,  0xFA,  0x2A,  0x9C,  0x3E,  0xA8,  0x2A,  0xC8,  0x2B,  0xC8,  0x3E,  0xAC,  0x02,  0x94, 	/* 556C0 */
+	0x34,  0x94,  0x2A,  0xA2,  0x2A,  0xC2,  0x40,  0x81,  0x90,  0x08,  0x00,  0x0E,  0xEE,  0x12,  0xAA,  0x24, 	/* 556D0 */
+	0xAA,  0x7F,  0xEE,  0x29,  0x00,  0x29,  0x7E,  0x3F,  0x00,  0x29,  0xFF,  0x29,  0x10,  0x3F,  0x10,  0x05, 	/* 556E0 */
+	0x3E,  0x32,  0xA2,  0x2A,  0x02,  0x28,  0x02,  0x40,  0x0C,  0x92,  0x08,  0x20,  0x0E,  0x20,  0x12,  0x7F, 	/* 556F0 */
+	0x24,  0x40,  0x7F,  0xFC,  0x29,  0x44,  0x29,  0x7C,  0x3F,  0x44,  0x29,  0x7C,  0x29,  0x20,  0x3F,  0x3C, 	/* 55700 */
+	0x05,  0x44,  0x32,  0xA8,  0x2A,  0x10,  0x28,  0x6C,  0x41,  0x83,  0x93,  0x08,  0x00,  0x0E,  0x7E,  0x12, 	/* 55710 */
+	0x52,  0x24,  0x52,  0x7F,  0x7E,  0x29,  0x52,  0x29,  0x52,  0x3F,  0x52,  0x29,  0x7E,  0x29,  0x10,  0x3F, 	/* 55720 */
+	0x08,  0x04,  0xA8,  0x32,  0xA2,  0x2A,  0xA1,  0x29,  0x25,  0x40,  0x1C,  0x94,  0x08,  0x08,  0x0E,  0x0A, 	/* 55730 */
+	0x12,  0x09,  0x24,  0xFF,  0x7E,  0x88,  0x2A,  0x88,  0x2A,  0xFA,  0x3E,  0x8A,  0x2A,  0xFA,  0x2A,  0xDA, 	/* 55740 */
+	0x3E,  0xD4,  0x05,  0xF4,  0x32,  0x8D,  0x2B,  0x0B,  0x29,  0x13,  0x42,  0x21,  0x95,  0x08,  0x00,  0x0E, 	/* 55750 */
+	0xEE,  0x12,  0xA2,  0x24,  0xA2,  0x7E,  0xA2,  0x2A,  0xEE,  0x2A,  0x80,  0x3E,  0x9E,  0x2A,  0xEA,  0x2A, 	/* 55760 */
+	0x8A,  0x3E,  0x8A,  0x04,  0xE4,  0x32,  0x84,  0x2A,  0x8A,  0x28,  0x92,  0x40,  0xA1,  0x9B,  0x08,  0x00, 	/* 55770 */
+	0x0E,  0x7C,  0x12,  0x44,  0x24,  0x44,  0x7F,  0x7C,  0x29,  0x44,  0x29,  0x44,  0x3F,  0x7C,  0x29,  0x00, 	/* 55780 */
+	0x29,  0xFE,  0x3F,  0xAA,  0x05,  0xAA,  0x32,  0xAA,  0x2A,  0xAA,  0x29,  0xFF,  0x40,  0x00,  0xA1,  0x08, 	/* 55790 */
+	0x20,  0x0E,  0xCF,  0x12,  0x85,  0x24,  0x85,  0x7E,  0xA5,  0x2A,  0x95,  0x2A,  0xF9,  0x3F,  0x96,  0x2A, 	/* 557A0 */
+	0x00,  0x2A,  0x7E,  0x3E,  0x52,  0x05,  0x7E,  0x32,  0x52,  0x2A,  0x52,  0x28,  0x7E,  0x40,  0x00,  0xA4, 	/* 557B0 */
+	0x08,  0x20,  0x0E,  0x5F,  0x12,  0xE4,  0x24,  0xA4,  0x7E,  0xBF,  0x2A,  0xB5,  0x2A,  0xF5,  0x3E,  0x95, 	/* 557C0 */
+	0x2A,  0x95,  0x2A,  0xF5,  0x3E,  0xB5,  0x05,  0xB5,  0x32,  0xB7,  0x2A,  0xF4,  0x28,  0x94,  0x40,  0x84, 	/* 557D0 */
+	0xA5,  0x08,  0x00,  0x0E,  0xFE,  0x12,  0xAA,  0x24,  0xAA,  0x7F,  0xAA,  0x29,  0xFE,  0x29,  0x00,  0x3F, 	/* 557E0 */
+	0x54,  0x29,  0x54,  0x29,  0x52,  0x3F,  0x91,  0x05,  0x54,  0x32,  0x54,  0x2A,  0x92,  0x29,  0x11,  0x40, 	/* 557F0 */
+	0x10,  0xAD,  0x08,  0x20,  0x0E,  0x22,  0x12,  0xFC,  0x24,  0x28,  0x7F,  0xFF,  0x29,  0x20,  0x29,  0xCC, 	/* 55800 */
+	0x3F,  0x70,  0x29,  0x42,  0x29,  0x3E,  0x3F,  0x00,  0x05,  0x7C,  0x32,  0xC4,  0x2A,  0x7C,  0x28,  0x44, 	/* 55810 */
+	0x40,  0x7C,  0xAE,  0x08,  0x00,  0x0E,  0xFC,  0x12,  0xA4,  0x24,  0xA4,  0x7E,  0xB4,  0x2A,  0xAC,  0x2A, 	/* 55820 */
+	0xC4,  0x3E,  0xFC,  0x2A,  0x00,  0x2A,  0xFE,  0x3E,  0xAA,  0x05,  0xAA,  0x32,  0xAA,  0x2A,  0xAA,  0x29, 	/* 55830 */
+	0xFF,  0x40,  0x00,  0xAF,  0x08,  0x00,  0x0F,  0xFE,  0x12,  0x22,  0x24,  0x22,  0x7E,  0xEE,  0x2A,  0x88, 	/* 55840 */
+	0x2A,  0x88,  0x3E,  0xEE,  0x2A,  0x32,  0x2A,  0xAA,  0x3E,  0xAA,  0x02,  0x66,  0x35,  0xAA,  0x2B,  0x32, 	/* 55850 */
+	0x2A,  0x22,  0x40,  0xCC,  0xB0,  0x08,  0x04,  0x0E,  0xE4,  0x12,  0x04,  0x24,  0x1F,  0x7E,  0x15,  0x2B, 	/* 55860 */
+	0xF5,  0x2A,  0x5F,  0x3E,  0x55,  0x2B,  0x55,  0x2B,  0x55,  0x3F,  0x5F,  0x05,  0x54,  0x32,  0x54,  0x2A, 	/* 55870 */
+	0x44,  0x28,  0x44,  0x40,  0x44,  0xB2,  0x04,  0x10,  0x3F,  0x9F,  0x04,  0x24,  0x7F,  0xD4,  0x08,  0x14, 	/* 55880 */
+	0x0F,  0x08,  0x09,  0x14,  0x13,  0xE2,  0x24,  0x81,  0x1F,  0xF8,  0x08,  0x88,  0x0F,  0xF8,  0x08,  0x88, 	/* 55890 */
+	0x1F,  0xF8,  0x22,  0x22,  0x41,  0x11,  0xB9,  0x08,  0x00,  0x0E,  0xF0,  0x12,  0xBE,  0x24,  0xAA,  0x7E, 	/* 558A0 */
+	0xFA,  0x2A,  0x9A,  0x2A,  0xF4,  0x3E,  0xA6,  0x2A,  0xAA,  0x2A,  0xF1,  0x3E,  0x10,  0x05,  0x7C,  0x32, 	/* 558B0 */
+	0x90,  0x2A,  0x10,  0x29,  0xFF,  0x40,  0x00,  0xBA,  0x08,  0x10,  0x0E,  0x28,  0x12,  0xFC,  0x24,  0x42, 	/* 558C0 */
+	0x7E,  0xA5,  0x2B,  0xEF,  0x2A,  0x10,  0x3E,  0x28,  0x2A,  0x44,  0x2B,  0x93,  0x3E,  0x20,  0x05,  0xC8, 	/* 558D0 */
+	0x32,  0x32,  0x2A,  0xC4,  0x28,  0x18,  0x40,  0xE0,  0xBB,  0x08,  0x00,  0x0E,  0x7C,  0x12,  0x44,  0x24, 	/* 558E0 */
+	0x7C,  0x7F,  0x44,  0x29,  0x7C,  0x29,  0x00,  0x3F,  0xFE,  0x29,  0xAA,  0x29,  0xFE,  0x3F,  0x00,  0x05, 	/* 558F0 */
+	0xFC,  0x32,  0x48,  0x2A,  0x30,  0x28,  0x6C,  0x41,  0x83,  0xBE,  0x08,  0x00,  0x0F,  0xFF,  0x12,  0x28, 	/* 55900 */
+	0x24,  0xFE,  0x7E,  0xAA,  0x2A,  0xAA,  0x2A,  0xFE,  0x3E,  0x00,  0x2A,  0x7C,  0x2A,  0x00,  0x3F,  0xFF, 	/* 55910 */
+	0x05,  0x50,  0x32,  0x54,  0x2A,  0x92,  0x29,  0x11,  0x40,  0x30,  0x86,  0x08,  0x10,  0x0E,  0x10,  0x12, 	/* 55920 */
+	0xFE,  0x24,  0x44,  0x7F,  0x28,  0x29,  0xFF,  0x29,  0x00,  0x3F,  0x7C,  0x29,  0x44,  0x29,  0x7C,  0x3F, 	/* 55930 */
+	0x44,  0x05,  0x7C,  0x32,  0x90,  0x2A,  0xFF,  0x28,  0x10,  0x40,  0x10,  0x87,  0x08,  0x08,  0x0E,  0x08, 	/* 55940 */
+	0x12,  0xFF,  0x24,  0x88,  0x7E,  0xBE,  0x2A,  0x8A,  0x2A,  0xFF,  0x3E,  0x8A,  0x2A,  0xBE,  0x2A,  0xC8, 	/* 55950 */
+	0x3E,  0xAA,  0x04,  0xAA,  0x33,  0x1C,  0x29,  0x2A,  0x2A,  0xC9,  0x40,  0x18,  0x88,  0x10,  0x00,  0x1E, 	/* 55960 */
+	0xFE,  0x12,  0x10,  0x25,  0xFF,  0x7F,  0x11,  0x29,  0xDD,  0x29,  0x11,  0x3F,  0xDC,  0x29,  0x00,  0x29, 	/* 55970 */
+	0xFC,  0x3F,  0x04,  0x05,  0x04,  0x32,  0xFC,  0x2A,  0x04,  0x28,  0xFC,  0x40,  0x00,  0x92,  0x08,  0x42, 	/* 55980 */
+	0x0E,  0x24,  0x12,  0xFF,  0x24,  0x18,  0x7F,  0x7E,  0x29,  0x5A,  0x29,  0x6A,  0x3F,  0x7E,  0x29,  0x42, 	/* 55990 */
+	0x29,  0x7E,  0x3F,  0x04,  0x05,  0xFF,  0x32,  0x44,  0x2A,  0x24,  0x28,  0x04,  0x40,  0x0C,  0x97,  0x08, 	/* 559A0 */
+	0x10,  0x0E,  0x92,  0x12,  0x54,  0x24,  0xFF,  0x7E,  0x38,  0x2A,  0x54,  0x2A,  0x92,  0x3F,  0x51,  0x2A, 	/* 559B0 */
+	0x52,  0x2A,  0x6F,  0x3E,  0xAA,  0x05,  0xAA,  0x32,  0x7F,  0x2A,  0x42,  0x28,  0x82,  0x41,  0x02,  0x9A, 	/* 559C0 */
+	0x08,  0x10,  0x0E,  0xFF,  0x12,  0x10,  0x24,  0x7E,  0x7F,  0x00,  0x29,  0x7E,  0x29,  0x42,  0x3F,  0x7E, 	/* 559D0 */
+	0x29,  0x44,  0x29,  0x28,  0x3F,  0xFF,  0x05,  0x00,  0x32,  0xFE,  0x2A,  0x42,  0x28,  0x7E,  0x40,  0x00, 	/* 559E0 */
+	0xA0,  0x08,  0x10,  0x0E,  0x10,  0x12,  0x28,  0x24,  0x7C,  0x7E,  0x82,  0x2B,  0xFF,  0x2A,  0x92,  0x3E, 	/* 559F0 */
+	0xD6,  0x2A,  0xFE,  0x2A,  0x00,  0x3E,  0x7C,  0x05,  0x44,  0x32,  0x7C,  0x2A,  0x44,  0x28,  0x7C,  0x40, 	/* 55A00 */
+	0x00,  0xA7,  0x08,  0x28,  0x0E,  0x28,  0x12,  0xFE,  0x24,  0xAA,  0x7E,  0xFE,  0x2A,  0xAA,  0x2A,  0xFE, 	/* 55A10 */
+	0x3E,  0x00,  0x2B,  0xFF,  0x2A,  0x00,  0x3E,  0xFE,  0x04,  0x82,  0x32,  0xFE,  0x2A,  0x24,  0x29,  0xFF, 	/* 55A20 */
+	0x40,  0x00,  0xB6,  0x08,  0x44,  0x0E,  0x28,  0x12,  0xFE,  0x24,  0x10,  0x7E,  0xFE,  0x2A,  0x10,  0x2B, 	/* 55A30 */
+	0xFF,  0x3E,  0x54,  0x2A,  0xFE,  0x2B,  0x45,  0x3E,  0x7C,  0x05,  0x44,  0x32,  0x7D,  0x2A,  0x52,  0x28, 	/* 55A40 */
+	0x6C,  0x41,  0x83,  0xB8,  0x08,  0x10,  0x0E,  0x1E,  0x12,  0x10,  0x24,  0xFF,  0x7E,  0x9A,  0x2A,  0xF1, 	/* 55A50 */
+	0x2A,  0xBF,  0x3E,  0xAA,  0x2A,  0xBE,  0x2A,  0xAA,  0x3F,  0x3E,  0x05,  0x00,  0x32,  0xFE,  0x28,  0xAA, 	/* 55A60 */
+	0x29,  0xFF,  0x40,  0x00,  0xA5,  0x00,  0x80,  0x01,  0x00,  0x0F,  0xF0,  0x08,  0x10,  0x0F,  0xF0,  0x08, 	/* 55A70 */
+	0x10,  0x0F,  0xF0,  0x08,  0x00,  0x0F,  0xFF,  0x08,  0x00,  0x0F,  0xFE,  0x10,  0x22,  0x14,  0x92,  0x12, 	/* 55A80 */
+	0x52,  0x22,  0x42,  0x40,  0x0C,  0xA7,  0x01,  0x00,  0x0F,  0xF0,  0x08,  0x10,  0x0F,  0xF0,  0x08,  0x10, 	/* 55A90 */
+	0x08,  0x10,  0x0F,  0xFF,  0x08,  0x00,  0x0F,  0xFE,  0x29,  0x22,  0x24,  0x92,  0x40,  0x0C,  0x03,  0xF0, 	/* 55AA0 */
+	0x02,  0x11,  0x0C,  0x11,  0x70,  0x0F,  0xA9,  0x10,  0x20,  0x10,  0x40,  0x10,  0xFC,  0x7C,  0x84,  0x14, 	/* 55AB0 */
+	0xFC,  0x14,  0x84,  0x14,  0xFC,  0x14,  0x80,  0x14,  0xFF,  0x15,  0x80,  0x15,  0xFE,  0x23,  0x0A,  0x20, 	/* 55AC0 */
+	0xA6,  0x41,  0x52,  0x01,  0x52,  0x02,  0x0C,  0xAB,  0x00,  0x00,  0x1F,  0xFF,  0x10,  0x80,  0x13,  0xF8, 	/* 55AD0 */
+	0x12,  0x08,  0x13,  0xF8,  0x12,  0x08,  0x13,  0xF8,  0x12,  0x00,  0x13,  0xFF,  0x12,  0x00,  0x13,  0xFE, 	/* 55AE0 */
+	0x20,  0x0A,  0x25,  0x26,  0x44,  0x92,  0x08,  0x0C,  0xAC,  0x01,  0x00,  0x1F,  0xF0,  0x10,  0x10,  0x1F, 	/* 55AF0 */
+	0xF0,  0x10,  0x10,  0x1F,  0xF0,  0x10,  0x00,  0x1F,  0xFF,  0x10,  0x00,  0x1F,  0xFE,  0x00,  0x02,  0x07, 	/* 55B00 */
+	0xE2,  0x04,  0x2C,  0x04,  0x21,  0x18,  0x21,  0x60,  0x1F,  0xB0,  0x00,  0x20,  0x00,  0x40,  0x38,  0xFC, 	/* 55B10 */
+	0x08,  0x84,  0x08,  0xFC,  0x08,  0x84,  0x08,  0xFC,  0x0C,  0x80,  0x14,  0xFF,  0x14,  0x80,  0x12,  0xFE, 	/* 55B20 */
+	0x22,  0x2A,  0x21,  0x96,  0x41,  0x52,  0x02,  0x42,  0x00,  0x0C,  0xB3,  0x00,  0x00,  0x1F,  0xFC,  0x10, 	/* 55B30 */
+	0x04,  0x1F,  0xFC,  0x11,  0x04,  0x17,  0xE4,  0x14,  0x24,  0x17,  0xE4,  0x14,  0x24,  0x17,  0xFC,  0x14, 	/* 55B40 */
+	0x04,  0x17,  0xF4,  0x11,  0x54,  0x2C,  0xB5,  0x2A,  0x13,  0x50,  0x61,  0xB4,  0x00,  0x20,  0x00,  0x40, 	/* 55B50 */
+	0x79,  0xF8,  0x49,  0x08,  0x49,  0xF8,  0x49,  0x08,  0x49,  0xF8,  0x49,  0x00,  0x49,  0xFF,  0x49,  0x00, 	/* 55B60 */
+	0x79,  0xFE,  0x49,  0x52,  0x02,  0xAA,  0x02,  0xAA,  0x04,  0x84,  0x08,  0x18,  0xB6,  0x01,  0x10,  0x01, 	/* 55B70 */
+	0x08,  0x7F,  0xFF,  0x00,  0x80,  0x02,  0x61,  0x04,  0x19,  0x0F,  0xF7,  0x08,  0x10,  0x0F,  0xF0,  0x08, 	/* 55B80 */
+	0x10,  0x0F,  0xFF,  0x08,  0x00,  0x0F,  0xFE,  0x29,  0x22,  0x24,  0x92,  0x44,  0x0C,  0x83,  0x04,  0x10, 	/* 55B90 */
+	0x08,  0x10,  0x3E,  0x10,  0x22,  0x7E,  0x3E,  0x12,  0x22,  0x12,  0x3E,  0x12,  0x20,  0x12,  0x3F,  0xFF, 	/* 55BA0 */
+	0x20,  0x10,  0x3F,  0x98,  0x04,  0xA8,  0x32,  0xA8,  0x2A,  0xC4,  0x28,  0x82,  0x43,  0x01,  0x86,  0x08, 	/* 55BB0 */
+	0x10,  0x08,  0x20,  0x08,  0xFC,  0x7E,  0x84,  0x4A,  0xFC,  0x4A,  0x84,  0x08,  0xFC,  0x08,  0x80,  0x0C, 	/* 55BC0 */
+	0xFF,  0x14,  0x80,  0x14,  0xFE,  0x15,  0x12,  0x16,  0xCA,  0x24,  0xAA,  0x41,  0x22,  0x00,  0x0C,  0x87, 	/* 55BD0 */
+	0x20,  0x10,  0x24,  0x20,  0x38,  0xFC,  0x20,  0x84,  0x20,  0xFC,  0x22,  0x84,  0x1E,  0xFC,  0x08,  0x80, 	/* 55BE0 */
+	0x08,  0xFF,  0x08,  0x80,  0x7F,  0xFE,  0x08,  0x2A,  0x09,  0x96,  0x09,  0x52,  0x09,  0x42,  0x0A,  0x0C, 	/* 55BF0 */
+	0x88,  0x00,  0x00,  0x1F,  0xFF,  0x12,  0x20,  0x12,  0xFC,  0x12,  0x84,  0x14,  0xFC,  0x14,  0x84,  0x1C, 	/* 55C00 */
+	0xFC,  0x14,  0x80,  0x14,  0xFF,  0x14,  0x80,  0x14,  0xFE,  0x24,  0x2A,  0x25,  0x96,  0x45,  0x52,  0x06, 	/* 55C10 */
+	0x44,  0x89,  0x00,  0x10,  0x3E,  0x20,  0x24,  0xFC,  0x24,  0x84,  0x24,  0xFC,  0x24,  0x84,  0x24,  0xFC, 	/* 55C20 */
+	0x7F,  0x80,  0x0C,  0xFF,  0x0C,  0x80,  0x14,  0xFE,  0x14,  0x2A,  0x25,  0x96,  0x45,  0x52,  0x06,  0x42, 	/* 55C30 */
+	0x0C,  0x0C,  0x8E,  0x00,  0x20,  0x7F,  0x40,  0x42,  0xFC,  0x42,  0x84,  0x62,  0xFC,  0x54,  0x84,  0x4C, 	/* 55C40 */
+	0xFC,  0x44,  0x80,  0x4C,  0xFF,  0x4A,  0x80,  0x52,  0xFE,  0x52,  0x2A,  0x61,  0x96,  0x7F,  0x52,  0x01, 	/* 55C50 */
+	0x42,  0x02,  0x0C,  0x92,  0x08,  0x10,  0x08,  0x20,  0x14,  0xFC,  0x12,  0x84,  0x21,  0xFC,  0x7E,  0x84, 	/* 55C60 */
+	0x00,  0xFC,  0x00,  0x80,  0x7E,  0xFF,  0x12,  0x80,  0x12,  0xFE,  0x12,  0x2A,  0x1D,  0x96,  0x11,  0x52, 	/* 55C70 */
+	0x12,  0x42,  0x10,  0x0C,  0x95,  0x04,  0x08,  0x08,  0x08,  0x3E,  0xFE,  0x22,  0x82,  0x3E,  0xA2,  0x22, 	/* 55C80 */
+	0x20,  0x3E,  0x20,  0x20,  0x24,  0x3F,  0xA4,  0x20,  0x28,  0x3F,  0xB0,  0x04,  0xA0,  0x32,  0xA1,  0x2A, 	/* 55C90 */
+	0xA1,  0x28,  0xA1,  0x43,  0x1F,  0x9B,  0x08,  0x00,  0x0F,  0xFC,  0x31,  0x44,  0x0A,  0x58,  0x0D,  0x42, 	/* 55CA0 */
+	0x72,  0x3E,  0x0F,  0xF0,  0x08,  0x10,  0x0F,  0xF0,  0x08,  0x10,  0x0F,  0xFF,  0x08,  0x00,  0x0F,  0xFE, 	/* 55CB0 */
+	0x29,  0x22,  0x24,  0x92,  0x40,  0x0C,  0x9F,  0x01,  0x10,  0x02,  0x20,  0x3C,  0x7C,  0x24,  0x44,  0x24, 	/* 55CC0 */
+	0x7C,  0x24,  0x44,  0x3F,  0x7C,  0x24,  0x40,  0x24,  0x7F,  0x24,  0x40,  0x22,  0xFE,  0x3A,  0x92,  0x61, 	/* 55CD0 */
+	0xAA,  0x00,  0xAA,  0x7D,  0x02,  0x00,  0x0C,  0xA3,  0x08,  0x10,  0x08,  0x20,  0x08,  0xFC,  0x7F,  0x84, 	/* 55CE0 */
+	0x08,  0xFC,  0x08,  0x84,  0x08,  0xFC,  0x3E,  0x80,  0x22,  0xFF,  0x22,  0x80,  0x22,  0xFE,  0x22,  0x0A, 	/* 55CF0 */
+	0x3F,  0x56,  0x01,  0x52,  0x02,  0x02,  0x00,  0x0C,  0xA6,  0x00,  0x80,  0x1F,  0xFE,  0x10,  0x82,  0x7F, 	/* 55D00 */
+	0xFF,  0x02,  0x90,  0x0C,  0x8C,  0x77,  0xFB,  0x04,  0x08,  0x07,  0xF8,  0x04,  0x08,  0x07,  0xFF,  0x04, 	/* 55D10 */
+	0x00,  0x07,  0xFE,  0x14,  0x92,  0x12,  0x4A,  0x20,  0x0C,  0xA8,  0x00,  0x20,  0x7E,  0x40,  0x4A,  0xFC, 	/* 55D20 */
+	0x4A,  0x84,  0x4A,  0xFC,  0x7E,  0x84,  0x4A,  0xFC,  0x4A,  0x80,  0x4A,  0xFF,  0x7E,  0x80,  0x08,  0xFE, 	/* 55D30 */
+	0x08,  0x2A,  0x09,  0x96,  0x09,  0x52,  0x0A,  0x42,  0x0C,  0x0C,  0xAA,  0x08,  0x10,  0x08,  0x20,  0x08, 	/* 55D40 */
+	0xFC,  0x7E,  0x84,  0x42,  0xFC,  0x42,  0x84,  0x1C,  0xFC,  0x04,  0x80,  0x14,  0xFF,  0x12,  0x80,  0x12, 	/* 55D50 */
+	0xFE,  0x21,  0x2A,  0x21,  0x96,  0x41,  0x52,  0x02,  0x42,  0x00,  0x0C,  0xAB,  0x00,  0x20,  0x00,  0x40, 	/* 55D60 */
+	0x7D,  0xF8,  0x55,  0x08,  0x55,  0xF8,  0x55,  0x08,  0x7D,  0xF8,  0x55,  0x00,  0x55,  0xFF,  0x55,  0x00, 	/* 55D70 */
+	0x55,  0xFE,  0x7C,  0x52,  0x02,  0xAA,  0x02,  0xA2,  0x04,  0x02,  0x00,  0x0C,  0xAC,  0x11,  0x08,  0x08, 	/* 55D80 */
+	0x90,  0x7F,  0xFE,  0x42,  0x02,  0x4F,  0xF2,  0x08,  0x10,  0x0F,  0xF0,  0x08,  0x10,  0x0F,  0xF0,  0x08, 	/* 55D90 */
+	0x00,  0x0F,  0xFE,  0x08,  0x00,  0x0F,  0xFC,  0x29,  0x24,  0x24,  0x94,  0x40,  0x18,  0xBB,  0x20,  0x08, 	/* 55DA0 */
+	0x10,  0x10,  0x10,  0x7C,  0x0F,  0xC4,  0x42,  0x7C,  0x22,  0x44,  0x22,  0x7C,  0x02,  0x40,  0x0A,  0x7F, 	/* 55DB0 */
+	0x0A,  0x40,  0x13,  0x7E,  0x1C,  0x0A,  0x21,  0x56,  0x21,  0x2A,  0x42,  0x22,  0x40,  0x0C,  0xBE,  0x08, 	/* 55DC0 */
+	0x10,  0x08,  0x20,  0x14,  0xFC,  0x22,  0x84,  0x7D,  0xFC,  0x09,  0x84,  0x28,  0xFC,  0x3E,  0x80,  0x48, 	/* 55DD0 */
+	0xFF,  0x08,  0x80,  0x7F,  0xFE,  0x08,  0x2A,  0x09,  0x56,  0x09,  0x52,  0x0A,  0x02,  0x08,  0x0C,  0xBF, 	/* 55DE0 */
+	0x08,  0x10,  0x08,  0x20,  0x14,  0xFC,  0x14,  0x84,  0x22,  0xFC,  0x7D,  0x84,  0x00,  0xFC,  0x00,  0x80, 	/* 55DF0 */
+	0x3E,  0xFF,  0x22,  0x80,  0x22,  0xFE,  0x22,  0x2A,  0x3F,  0x96,  0x01,  0x52,  0x02,  0x42,  0x00,  0x0C, 	/* 55E00 */
+	0x81,  0x08,  0x10,  0x08,  0x20,  0x7F,  0xFC,  0x14,  0x84,  0x12,  0xFC,  0x22,  0x84,  0x45,  0xFC,  0x14, 	/* 55E10 */
+	0x80,  0x14,  0xFF,  0x08,  0x80,  0x0C,  0xFE,  0x12,  0x2A,  0x11,  0x96,  0x21,  0x52,  0x42,  0x42,  0x00, 	/* 55E20 */
+	0x0C,  0x84,  0x00,  0x10,  0x7F,  0x20,  0x08,  0xFC,  0x08,  0x84,  0x14,  0xFC,  0x22,  0x84,  0x7D,  0xFC, 	/* 55E30 */
+	0x09,  0x80,  0x08,  0xFF,  0x3E,  0x80,  0x08,  0xFE,  0x08,  0x2A,  0x0F,  0x96,  0x19,  0x52,  0x62,  0x42, 	/* 55E40 */
+	0x00,  0x0C,  0x86,  0x08,  0x80,  0x09,  0x0F,  0x13,  0xE0,  0x12,  0x20,  0x27,  0xE0,  0x46,  0x3F,  0x0B, 	/* 55E50 */
+	0xE4,  0x0A,  0x04,  0x13,  0xFC,  0x32,  0x04,  0x53,  0xF4,  0x10,  0x94,  0x16,  0x54,  0x15,  0x54,  0x19, 	/* 55E60 */
+	0x14,  0x10,  0x64,  0x88,  0x00,  0x10,  0x7F,  0x20,  0x12,  0xFC,  0x12,  0x84,  0x1E,  0xFC,  0x12,  0x84, 	/* 55E70 */
+	0x12,  0xFC,  0x12,  0x80,  0x1E,  0xFF,  0x12,  0x80,  0x12,  0xFE,  0x12,  0x12,  0x1E,  0xCA,  0x72,  0xAA, 	/* 55E80 */
+	0x03,  0x22,  0x02,  0x0C,  0x90,  0x00,  0x10,  0x7F,  0x20,  0x08,  0xFC,  0x08,  0x84,  0x2A,  0xFC,  0x2A, 	/* 55E90 */
+	0x84,  0x2A,  0xFC,  0x2D,  0x80,  0x5C,  0xFF,  0x48,  0x80,  0x08,  0xFE,  0x08,  0x2A,  0x0F,  0x96,  0x19, 	/* 55EA0 */
+	0x52,  0x62,  0x42,  0x00,  0x0C,  0x91,  0x00,  0x10,  0x3E,  0x20,  0x22,  0xFC,  0x22,  0x84,  0x3E,  0xFC, 	/* 55EB0 */
+	0x00,  0x84,  0x3E,  0xFC,  0x22,  0x80,  0x22,  0xFF,  0x3E,  0x80,  0x22,  0xFE,  0x22,  0x12,  0x3E,  0xCA, 	/* 55EC0 */
+	0x22,  0xAA,  0x23,  0x22,  0x26,  0x0C,  0x99,  0x00,  0x10,  0x3E,  0x20,  0x22,  0xFC,  0x22,  0x84,  0x3E, 	/* 55ED0 */
+	0xFC,  0x22,  0x84,  0x22,  0xFC,  0x22,  0x80,  0x3E,  0xFF,  0x22,  0x80,  0x22,  0xFE,  0x3E,  0x12,  0x14, 	/* 55EE0 */
+	0xCA,  0x12,  0xAA,  0x21,  0x22,  0x40,  0x0C,  0x9C,  0x22,  0x10,  0x12,  0x20,  0x14,  0x7C,  0x7F,  0x44, 	/* 55EF0 */
+	0x09,  0x7C,  0x3F,  0x44,  0x28,  0x7C,  0x28,  0x40,  0x3F,  0x7F,  0x09,  0x40,  0x19,  0x7E,  0x19,  0x52, 	/* 55F00 */
+	0x2E,  0xAA,  0x48,  0xAA,  0x09,  0x02,  0x08,  0x0C,  0x9D,  0x08,  0x10,  0x14,  0x20,  0x36,  0x7C,  0x55, 	/* 55F10 */
+	0x44,  0x14,  0x7C,  0x7F,  0xC4,  0x14,  0x7C,  0x15,  0x40,  0x1D,  0x7F,  0x16,  0x40,  0x36,  0x7E,  0x55, 	/* 55F20 */
+	0x2A,  0x17,  0x56,  0x1B,  0x56,  0x11,  0x82,  0x31,  0x1C,  0x9E,  0x03,  0x24,  0x3C,  0x22,  0x04,  0x10, 	/* 55F30 */
+	0x7F,  0xFF,  0x07,  0x14,  0x3C,  0x1A,  0x04,  0xE6,  0x05,  0x02,  0x0F,  0xF0,  0x08,  0x10,  0x0F,  0xFF, 	/* 55F40 */
+	0x08,  0x00,  0x0F,  0xFE,  0x24,  0x92,  0x22,  0x4A,  0x42,  0x0C,  0xA0,  0x08,  0x10,  0x28,  0x20,  0x28, 	/* 55F50 */
+	0xFC,  0x3E,  0x84,  0x28,  0xFC,  0x48,  0x84,  0x08,  0xFC,  0x7F,  0x80,  0x00,  0xFF,  0x3E,  0x80,  0x22, 	/* 55F60 */
+	0xFE,  0x22,  0x52,  0x22,  0xAA,  0x22,  0xAA,  0x3F,  0x02,  0x02,  0x0C,  0xA1,  0x02,  0x10,  0x3B,  0x20, 	/* 55F70 */
+	0x02,  0xFC,  0x02,  0x44,  0x7F,  0xFC,  0x02,  0x44,  0x0A,  0x7C,  0x2A,  0x40,  0x2E,  0x7F,  0x2A,  0x40, 	/* 55F80 */
+	0x2A,  0x7E,  0x29,  0x0A,  0x2F,  0x56,  0x39,  0x56,  0x61,  0x82,  0x00,  0x8C,  0xA4,  0x08,  0x10,  0x0E, 	/* 55F90 */
+	0x20,  0x12,  0xFC,  0x24,  0x84,  0x7E,  0xFC,  0x2A,  0x84,  0x2A,  0xFC,  0x3E,  0x80,  0x2A,  0xFF,  0x2A, 	/* 55FA0 */
+	0x80,  0x3E,  0xFE,  0x22,  0x12,  0x22,  0xCA,  0x22,  0xAA,  0x23,  0x22,  0x46,  0x0C,  0xAC,  0x00,  0x08, 	/* 55FB0 */
+	0x3B,  0x90,  0x2A,  0xBC,  0x2A,  0xA4,  0x2A,  0xBC,  0x3B,  0xA4,  0x2A,  0xBC,  0x2A,  0xA0,  0x2A,  0xBF, 	/* 55FC0 */
+	0x3B,  0xA0,  0x2A,  0xBE,  0x2A,  0x92,  0x2A,  0xAA,  0x2A,  0xAA,  0x2C,  0xC2,  0x59,  0x8C,  0xAF,  0x08, 	/* 55FD0 */
+	0x10,  0x10,  0x20,  0x3E,  0xFC,  0x2A,  0x84,  0x2A,  0xFC,  0x3E,  0x84,  0x2A,  0xFC,  0x2A,  0x80,  0x3E, 	/* 55FE0 */
+	0xFF,  0x14,  0x80,  0x24,  0xFE,  0x7F,  0x12,  0x04,  0xCA,  0x04,  0xAA,  0x05,  0x22,  0x04,  0x0C,  0xB2, 	/* 55FF0 */
+	0x14,  0x10,  0x14,  0x20,  0x7E,  0xFC,  0x14,  0x84,  0x14,  0xFC,  0x14,  0x84,  0x7F,  0xFC,  0x00,  0x80, 	/* 56000 */
+	0x3E,  0xFF,  0x22,  0x80,  0x22,  0xFE,  0x3E,  0x12,  0x22,  0xCA,  0x22,  0xAA,  0x3F,  0x22,  0x00,  0x0C, 	/* 56010 */
+	0xBA,  0x04,  0x08,  0x04,  0x10,  0x7F,  0xFC,  0x0A,  0x44,  0x0A,  0x7C,  0x13,  0xC4,  0x32,  0xFC,  0x36, 	/* 56020 */
+	0xC0,  0x55,  0x7F,  0x1B,  0x40,  0x11,  0x7E,  0x12,  0x92,  0x14,  0x4A,  0x18,  0xAA,  0x11,  0x22,  0x10, 	/* 56030 */
+	0x0C,  0x87,  0x08,  0x10,  0x08,  0x20,  0x7F,  0xFC,  0x08,  0x44,  0x3F,  0x7C,  0x29,  0x44,  0x3F,  0x7C, 	/* 56040 */
+	0x29,  0x40,  0x3F,  0x7F,  0x08,  0x40,  0x1C,  0x7E,  0x1A,  0x12,  0x29,  0xCA,  0x48,  0xAA,  0x09,  0x22, 	/* 56050 */
+	0x08,  0x0C,  0x89,  0x08,  0x10,  0x08,  0x20,  0x7F,  0xFC,  0x00,  0x84,  0x3E,  0xFC,  0x22,  0x84,  0x3E, 	/* 56060 */
+	0xFC,  0x00,  0x80,  0x3E,  0xFF,  0x04,  0x80,  0x08,  0xFE,  0x0F,  0x0A,  0x79,  0xA6,  0x09,  0x52,  0x09, 	/* 56070 */
+	0x52,  0x1A,  0x0C,  0x8F,  0x06,  0x10,  0x79,  0x20,  0x11,  0xFC,  0x4A,  0x84,  0x2A,  0xFC,  0x24,  0x84, 	/* 56080 */
+	0x08,  0xFC,  0x3E,  0x80,  0x08,  0xFF,  0x08,  0x80,  0x7F,  0xFE,  0x08,  0x52,  0x14,  0xAA,  0x12,  0xAA, 	/* 56090 */
+	0x23,  0x02,  0x40,  0x0C,  0x9A,  0x00,  0x10,  0x77,  0x20,  0x55,  0xFC,  0x55,  0x84,  0x77,  0xFC,  0x00, 	/* 560A0 */
+	0x84,  0x3E,  0xFC,  0x00,  0x80,  0x7F,  0xFF,  0x08,  0x80,  0x08,  0xFE,  0x1E,  0x12,  0x12,  0xCA,  0x02, 	/* 560B0 */
+	0xAA,  0x03,  0x22,  0x0C,  0x0C,  0xA4,  0x00,  0x10,  0x7F,  0x20,  0x41,  0xFC,  0x08,  0x84,  0x7F,  0xFC, 	/* 560C0 */
+	0x08,  0x84,  0x3E,  0xFC,  0x2A,  0x80,  0x3E,  0xFF,  0x2A,  0x80,  0x3E,  0xFE,  0x08,  0x2A,  0x7F,  0x96, 	/* 560D0 */
+	0x08,  0x92,  0x09,  0x02,  0x08,  0x0C,  0xA9,  0x3E,  0x20,  0x14,  0x3F,  0x08,  0x24,  0x7F,  0x54,  0x1A, 	/* 560E0 */
+	0x88,  0x2C,  0x14,  0x48,  0xA2,  0x1F,  0xF1,  0x04,  0x10,  0x07,  0xF0,  0x04,  0x10,  0x07,  0xFF,  0x04, 	/* 560F0 */
+	0x00,  0x27,  0xFC,  0x29,  0x24,  0x44,  0x98,  0xAB,  0x08,  0x10,  0x08,  0x20,  0x7F,  0xFC,  0x08,  0x44, 	/* 56100 */
+	0x7F,  0x7C,  0x4B,  0x44,  0x6D,  0x7C,  0x59,  0x40,  0x7F,  0x7F,  0x08,  0x40,  0x1C,  0x7E,  0x1A,  0x12, 	/* 56110 */
+	0x29,  0xCA,  0x48,  0xAA,  0x09,  0x22,  0x08,  0x0C,  0xAF,  0x08,  0x10,  0x2A,  0x54,  0x14,  0x28,  0x22, 	/* 56120 */
+	0x44,  0x7F,  0xFE,  0x41,  0x02,  0x4F,  0xF2,  0x08,  0x10,  0x0F,  0xF0,  0x08,  0x10,  0x0F,  0xFF,  0x08, 	/* 56130 */
+	0x00,  0x0F,  0xFE,  0x29,  0x22,  0x24,  0x92,  0x40,  0x0C,  0xB2,  0x1E,  0x10,  0x02,  0x20,  0x12,  0x7C, 	/* 56140 */
+	0x29,  0x44,  0x4C,  0xFC,  0x12,  0x44,  0x3E,  0x7C,  0x00,  0x40,  0x7F,  0x7F,  0x33,  0x40,  0x55,  0x7E, 	/* 56150 */
+	0x11,  0x2A,  0x13,  0x56,  0x35,  0x52,  0x51,  0x82,  0x13,  0x04,  0xB4,  0x08,  0x10,  0x08,  0x20,  0x7F, 	/* 56160 */
+	0x7C,  0x49,  0x44,  0x52,  0x7C,  0x14,  0x44,  0x3F,  0x7C,  0x24,  0x40,  0x64,  0x7F,  0x3F,  0x40,  0x24, 	/* 56170 */
+	0x7E,  0x3F,  0x2A,  0x24,  0x56,  0x24,  0x52,  0x3F,  0x82,  0x01,  0x0C,  0xB8,  0x00,  0x08,  0x7F,  0x10, 	/* 56180 */
+	0x11,  0x7C,  0x11,  0x44,  0x77,  0x7C,  0x44,  0x44,  0x44,  0x7C,  0x77,  0x40,  0x33,  0x7F,  0x55,  0x40, 	/* 56190 */
+	0x11,  0x7E,  0x33,  0x2A,  0x55,  0x56,  0x11,  0x52,  0x11,  0x82,  0x66,  0x0C,  0xBA,  0x08,  0x10,  0x08, 	/* 561A0 */
+	0x20,  0x6B,  0xFC,  0x08,  0x84,  0x6B,  0xFC,  0x14,  0x84,  0x14,  0xFC,  0x22,  0x80,  0x7F,  0xFF,  0x22, 	/* 561B0 */
+	0x80,  0x3E,  0xFE,  0x22,  0x2A,  0x3E,  0x96,  0x22,  0x92,  0x23,  0x02,  0x26,  0x0C,  0xBB,  0x00,  0x10, 	/* 561C0 */
+	0x3E,  0x20,  0x22,  0xFC,  0x2E,  0x84,  0x2A,  0xFC,  0x7F,  0x84,  0x41,  0xFC,  0x7E,  0x80,  0x22,  0xFF, 	/* 561D0 */
+	0x3E,  0x80,  0x22,  0xFE,  0x3E,  0x12,  0x22,  0xAA,  0x22,  0xAA,  0x23,  0x02,  0x26,  0x0C,  0x81,  0x17, 	/* 561E0 */
+	0x08,  0x11,  0x10,  0x11,  0x3C,  0x2E,  0xA4,  0x40,  0x7C,  0x17,  0x24,  0x11,  0x3C,  0x20,  0xA0,  0x7F, 	/* 561F0 */
+	0xFF,  0x2A,  0xA0,  0x2A,  0xBE,  0x2B,  0xCA,  0x3E,  0x56,  0x60,  0x52,  0x00,  0x82,  0x00,  0x0C,  0x82, 	/* 56200 */
+	0x04,  0x10,  0x0F,  0x20,  0x11,  0xFC,  0x6A,  0x84,  0x14,  0xFC,  0x18,  0x84,  0x68,  0xFC,  0x1F,  0x80, 	/* 56210 */
+	0x24,  0xFF,  0x04,  0x80,  0x7F,  0xFE,  0x04,  0x0A,  0x25,  0x56,  0x25,  0x52,  0x3F,  0x82,  0x00,  0x0C, 	/* 56220 */
+	0x84,  0x02,  0x10,  0x7C,  0x20,  0x0A,  0xFC,  0x29,  0x84,  0x21,  0xFC,  0x48,  0x84,  0x0A,  0xFC,  0x34, 	/* 56230 */
+	0x80,  0x0A,  0xFF,  0x7E,  0x80,  0x08,  0xFE,  0x3E,  0x12,  0x09,  0xCA,  0x14,  0xAA,  0x23,  0x22,  0x40, 	/* 56240 */
+	0x0C,  0x86,  0x22,  0x10,  0x3C,  0x20,  0x21,  0xFC,  0x1F,  0x84,  0x00,  0xFC,  0x5E,  0x84,  0x52,  0xFC, 	/* 56250 */
+	0x5E,  0x80,  0x52,  0xFF,  0x5E,  0x80,  0x52,  0xFE,  0x5E,  0x12,  0x40,  0xCA,  0x7F,  0xAA,  0x15,  0x22, 	/* 56260 */
+	0x62,  0x0C,  0x8F,  0x08,  0x10,  0x08,  0x20,  0x7F,  0xFC,  0x08,  0x84,  0x3E,  0xFC,  0x22,  0x84,  0x3E, 	/* 56270 */
+	0xFC,  0x22,  0x80,  0x3E,  0xFF,  0x22,  0x80,  0x3E,  0xFE,  0x00,  0x12,  0x7E,  0xCA,  0x14,  0xAA,  0x22, 	/* 56280 */
+	0xA2,  0xC1,  0x0C,  0x93,  0x04,  0x10,  0x04,  0x20,  0x3F,  0xFC,  0x20,  0x84,  0x2A,  0xFC,  0x2A,  0x84, 	/* 56290 */
+	0x3F,  0xFC,  0x2A,  0x80,  0x2A,  0xFF,  0x2A,  0x80,  0x2E,  0xFE,  0x42,  0x0A,  0x15,  0x56,  0x15,  0x52, 	/* 562A0 */
+	0x20,  0x82,  0x40,  0x0C,  0x99,  0x04,  0x10,  0x3F,  0x10,  0x04,  0x7C,  0x7F,  0x94,  0x12,  0x54,  0x3F, 	/* 562B0 */
+	0x35,  0x04,  0x2D,  0x3F,  0x43,  0x04,  0x80,  0x07,  0xF0,  0x04,  0x10,  0x07,  0xFF,  0x04,  0x00,  0x27, 	/* 562C0 */
+	0xFC,  0x29,  0x24,  0x44,  0x98,  0xA6,  0x12,  0x10,  0x14,  0x20,  0x3F,  0xFC,  0x64,  0x84,  0x3E,  0xFC, 	/* 562D0 */
+	0x24,  0x84,  0x24,  0xFC,  0x3E,  0x80,  0x24,  0xFF,  0x24,  0x80,  0x3F,  0xFE,  0x04,  0x12,  0x32,  0xCA, 	/* 562E0 */
+	0x2A,  0xAA,  0x29,  0x22,  0x40,  0x0C,  0xAD,  0x02,  0x10,  0x7C,  0x20,  0x49,  0xFC,  0x2A,  0x84,  0x7F, 	/* 562F0 */
+	0xFC,  0x1C,  0x84,  0x2A,  0xFC,  0x49,  0x80,  0x3E,  0xFF,  0x2A,  0x80,  0x2A,  0xFE,  0x3E,  0x12,  0x2A, 	/* 56300 */
+	0xCA,  0x2A,  0xAA,  0x3F,  0x22,  0x00,  0x0C,  0xAF,  0x04,  0x10,  0x04,  0x20,  0x7F,  0xFC,  0x04,  0x44, 	/* 56310 */
+	0x4A,  0xFC,  0x29,  0x44,  0x1F,  0x7C,  0x31,  0xC0,  0x5F,  0x7F,  0x11,  0x40,  0x1F,  0x7E,  0x04,  0x0A, 	/* 56320 */
+	0x16,  0x56,  0x25,  0x52,  0x45,  0x82,  0x0C,  0x0C,  0xB2,  0x08,  0x14,  0x7F,  0x12,  0x22,  0xFF,  0x3E, 	/* 56330 */
+	0x18,  0x0A,  0x28,  0x29,  0x2A,  0x29,  0x4A,  0x5A,  0x86,  0x0F,  0xF0,  0x08,  0x10,  0x0F,  0xFE,  0x08, 	/* 56340 */
+	0x00,  0x0F,  0xFE,  0x29,  0x22,  0x24,  0x92,  0x40,  0x0C,  0xB8,  0x00,  0x10,  0x3F,  0x20,  0x0A,  0x7C, 	/* 56350 */
+	0x04,  0x44,  0x7F,  0xFC,  0x15,  0x44,  0x24,  0x7C,  0x44,  0x40,  0x0C,  0x7F,  0x7F,  0x40,  0x55,  0x7E, 	/* 56360 */
+	0x67,  0x0A,  0x5D,  0x56,  0x55,  0x52,  0x5D,  0x82,  0x43,  0x0C,  0xB9,  0x00,  0x40,  0x1F,  0xFF,  0x12, 	/* 56370 */
+	0x48,  0x12,  0xFE,  0x15,  0x90,  0x1E,  0xFE,  0x14,  0x90,  0x14,  0xFF,  0x11,  0x00,  0x13,  0xF8,  0x12, 	/* 56380 */
+	0x08,  0x13,  0xFF,  0x22,  0x00,  0x2B,  0xFE,  0x4A,  0xAA,  0x11,  0x4C,  0xBA,  0x00,  0x20,  0x3E,  0x3C, 	/* 56390 */
+	0x22,  0xE4,  0x3E,  0x18,  0x08,  0x64,  0x2F,  0xFF,  0x28,  0x44,  0x3D,  0x7C,  0x67,  0xF0,  0x04,  0x10, 	/* 563A0 */
+	0x07,  0xFC,  0x04,  0x00,  0x07,  0xFE,  0x29,  0x22,  0x24,  0x92,  0x40,  0x0C,  0xBD,  0x06,  0x40,  0x19, 	/* 563B0 */
+	0x98,  0x12,  0x48,  0x19,  0x98,  0x12,  0x48,  0x7F,  0xFE,  0x41,  0x02,  0x4F,  0xF2,  0x08,  0x10,  0x0F, 	/* 563C0 */
+	0xF0,  0x08,  0x10,  0x0F,  0xFF,  0x08,  0x00,  0x2F,  0xFC,  0x29,  0x24,  0x44,  0x98,  0x9A,  0x00,  0x10, 	/* 563D0 */
+	0x3B,  0xA0,  0x2A,  0xBC,  0x3B,  0xA4,  0x2A,  0xBC,  0x3B,  0xA4,  0x2A,  0xBC,  0x3B,  0xA0,  0x4C,  0xFF, 	/* 563E0 */
+	0x08,  0x20,  0x7F,  0xBE,  0x0A,  0x0A,  0x12,  0x56,  0x1C,  0x52,  0x0A,  0x82,  0x31,  0x0C,  0x9B,  0x12, 	/* 563F0 */
+	0x10,  0x7F,  0xA0,  0x12,  0x7C,  0x77,  0x44,  0x55,  0x7C,  0x77,  0x44,  0x12,  0x7C,  0x14,  0x40,  0x3F, 	/* 56400 */
+	0x7F,  0x64,  0x40,  0x3E,  0x7E,  0x24,  0x52,  0x3E,  0xAA,  0x24,  0xAA,  0x3F,  0x02,  0x00,  0x0C,  0x9E, 	/* 56410 */
+	0x11,  0x84,  0x17,  0xE4,  0x68,  0x1A,  0x13,  0xC4,  0x28,  0x0A,  0x7F,  0xDF,  0x12,  0x44,  0x5B,  0xD5, 	/* 56420 */
+	0x54,  0x15,  0x0F,  0xF0,  0x08,  0x10,  0x0F,  0xFF,  0x08,  0x00,  0x2F,  0xFC,  0x29,  0x24,  0x44,  0x98, 	/* 56430 */
+	0xB5,  0x01,  0x00,  0x01,  0x00,  0x01,  0xFE,  0x01,  0x00,  0x01,  0x00,  0x3F,  0xFC,  0x21,  0x04,  0x2C, 	/* 56440 */
+	0x94,  0x22,  0x24,  0x31,  0x54,  0x28,  0x8C,  0x23,  0x44,  0x2C,  0x24,  0x20,  0x84,  0x3F,  0xFC,  0x00, 	/* 56450 */
+	0x00,  0xB8,  0x08,  0x10,  0x08,  0x10,  0x0F,  0x28,  0x08,  0x24,  0x08,  0x7E,  0x7F,  0x91,  0x49,  0x7E, 	/* 56460 */
+	0x45,  0x52,  0x55,  0x52,  0x4B,  0x7E,  0x6D,  0x10,  0x4B,  0x18,  0x51,  0x28,  0x49,  0x24,  0x7F,  0x42, 	/* 56470 */
+	0x01,  0x81,  0xB9,  0x08,  0x0A,  0x08,  0x09,  0x0F,  0x08,  0x08,  0x7F,  0x08,  0x48,  0x7F,  0x4A,  0x49, 	/* 56480 */
+	0x7A,  0x41,  0x4A,  0x55,  0x7A,  0x6B,  0x54,  0x49,  0x54,  0x55,  0x74,  0x41,  0x4D,  0x49,  0x53,  0x7F, 	/* 56490 */
+	0xA3,  0x01,  0x01,  0xBD,  0x00,  0x20,  0x3F,  0xBF,  0x24,  0x50,  0x24,  0x9E,  0x3F,  0x10,  0x21,  0x7E, 	/* 564A0 */
+	0x3F,  0x4A,  0x24,  0x6A,  0x24,  0x56,  0x3F,  0x6A,  0x00,  0x7E,  0x1F,  0xFC,  0x12,  0x44,  0x12,  0x44, 	/* 564B0 */
+	0x7F,  0xFF,  0x00,  0x00,  0xBF,  0x00,  0x80,  0x00,  0x80,  0x1F,  0xFF,  0x11,  0x20,  0x11,  0x20,  0x1F, 	/* 564C0 */
+	0xFE,  0x11,  0x22,  0x11,  0x22,  0x1F,  0xFE,  0x14,  0x20,  0x14,  0x24,  0x17,  0xB8,  0x24,  0x20,  0x24, 	/* 564D0 */
+	0x22,  0x47,  0xA2,  0x1C,  0x1E,  0x81,  0x00,  0x80,  0x01,  0xF0,  0x07,  0x20,  0x18,  0xC0,  0x7F,  0xFE, 	/* 564E0 */
+	0x11,  0x20,  0x1F,  0xFE,  0x11,  0x22,  0x11,  0x22,  0x1F,  0xFE,  0x14,  0x20,  0x14,  0x24,  0x27,  0xB8, 	/* 564F0 */
+	0x24,  0x22,  0x47,  0xA2,  0x1C,  0x1E,  0x88,  0x00,  0x40,  0x1F,  0xFF,  0x11,  0x20,  0x1F,  0xFE,  0x11, 	/* 56500 */
+	0x22,  0x1F,  0xFE,  0x17,  0xA2,  0x14,  0x3C,  0x17,  0xE1,  0x1C,  0x5F,  0x17,  0xFC,  0x10,  0x40,  0x23, 	/* 56510 */
+	0xF8,  0x20,  0x40,  0x5F,  0xFF,  0x00,  0x00,  0x8B,  0x00,  0x40,  0x1F,  0xFF,  0x11,  0x20,  0x1F,  0xFE, 	/* 56520 */
+	0x11,  0x22,  0x1F,  0xFE,  0x14,  0x20,  0x27,  0xBC,  0x24,  0x21,  0x4F,  0x1F,  0x10,  0x88,  0x08,  0x90, 	/* 56530 */
+	0x7F,  0xFF,  0x02,  0xA0,  0x0C,  0x98,  0x70,  0x87,  0x8C,  0x00,  0x40,  0x1F,  0xFF,  0x11,  0x20,  0x1F, 	/* 56540 */
+	0xFE,  0x11,  0x22,  0x1F,  0xFE,  0x14,  0x24,  0x37,  0xB8,  0x24,  0x21,  0x57,  0xFF,  0x12,  0x10,  0x1F, 	/* 56550 */
+	0xFC,  0x00,  0x04,  0x7F,  0xFF,  0x03,  0x18,  0x1C,  0x06,  0x91,  0x00,  0x40,  0x1F,  0xFF,  0x11,  0x20, 	/* 56560 */
+	0x1F,  0xFE,  0x11,  0x22,  0x1F,  0xFE,  0x14,  0x24,  0x27,  0xB8,  0x24,  0xA1,  0x47,  0x3F,  0x1C,  0x08, 	/* 56570 */
+	0x07,  0xB8,  0x04,  0x08,  0x07,  0xF9,  0x01,  0x21,  0x7E,  0x1F,  0x92,  0x04,  0x24,  0x04,  0x24,  0x3F, 	/* 56580 */
+	0xFF,  0x2A,  0x24,  0x2A,  0x24,  0x3F,  0xBC,  0x2A,  0xA4,  0x2A,  0xA4,  0x3F,  0xBC,  0x20,  0x24,  0x2A, 	/* 56590 */
+	0xA4,  0x2E,  0xFF,  0x2B,  0x00,  0x2A,  0x94,  0x4E,  0xA2,  0x19,  0xC2,  0x93,  0x08,  0x08,  0x7F,  0x7F, 	/* 565A0 */
+	0x1C,  0x1C,  0x2A,  0x2A,  0x48,  0x49,  0x00,  0x80,  0x1F,  0xFF,  0x11,  0x20,  0x1F,  0xFE,  0x11,  0x22, 	/* 565B0 */
+	0x1F,  0xFE,  0x14,  0x24,  0x27,  0xB8,  0x24,  0x22,  0x47,  0xE2,  0x1C,  0x1E,  0x95,  0x00,  0x40,  0x1F, 	/* 565C0 */
+	0xFF,  0x11,  0x10,  0x1F,  0xFE,  0x11,  0x12,  0x1F,  0xFE,  0x15,  0xBC,  0x26,  0x22,  0x5F,  0xFE,  0x10, 	/* 565D0 */
+	0x64,  0x13,  0x84,  0x1F,  0xFC,  0x12,  0xA4,  0x14,  0x94,  0x1F,  0xFC,  0x00,  0x00,  0x97,  0x3F,  0x7E, 	/* 565E0 */
+	0x00,  0x00,  0x1F,  0x7C,  0x11,  0x44,  0x15,  0x54,  0x00,  0x80,  0x1F,  0xFE,  0x11,  0x20,  0x1F,  0xFC, 	/* 565F0 */
+	0x11,  0x24,  0x1F,  0xFC,  0x14,  0x24,  0x27,  0xB8,  0x24,  0x22,  0x47,  0xA2,  0x38,  0x1E,  0x9D,  0x00, 	/* 56600 */
+	0x40,  0x1F,  0xFF,  0x11,  0x20,  0x1F,  0xFE,  0x11,  0x22,  0x1F,  0xFE,  0x24,  0x22,  0x27,  0xBC,  0x44, 	/* 56610 */
+	0x21,  0x1F,  0x9F,  0x11,  0x04,  0x1F,  0xFF,  0x11,  0x44,  0x7F,  0x24,  0x09,  0x04,  0x73,  0x0C,  0x9F, 	/* 56620 */
+	0x04,  0x0A,  0x04,  0x2A,  0x3F,  0x9C,  0x2A,  0x7F,  0x3F,  0x9C,  0x2A,  0xAA,  0x2A,  0xC9,  0x3F,  0xA8, 	/* 56630 */
+	0x20,  0x22,  0x2A,  0x3A,  0x2A,  0xAF,  0x2F,  0x6A,  0x2A,  0x9A,  0x2A,  0x9F,  0x4E,  0xA2,  0x11,  0xC2, 	/* 56640 */
+	0xA5,  0x00,  0x80,  0x00,  0x80,  0x7F,  0xFF,  0x08,  0x88,  0x08,  0x88,  0x0C,  0x8C,  0x13,  0x52,  0x22, 	/* 56650 */
+	0x20,  0x0D,  0x18,  0x71,  0xF7,  0x02,  0x10,  0x05,  0xA0,  0x18,  0x40,  0x01,  0xB0,  0x06,  0x08,  0x78, 	/* 56660 */
+	0x04,  0xA6,  0x00,  0x80,  0x00,  0x80,  0x3F,  0xFE,  0x00,  0x80,  0x1F,  0xFC,  0x00,  0x80,  0x7F,  0xFF, 	/* 56670 */
+	0x01,  0x00,  0x01,  0xF0,  0x02,  0x10,  0x0E,  0x20,  0x31,  0x40,  0x01,  0xC0,  0x02,  0x20,  0x0C,  0x18, 	/* 56680 */
+	0x70,  0x07,  0xA9,  0x08,  0x10,  0x08,  0x10,  0x7F,  0x10,  0x2A,  0x7E,  0x2A,  0x10,  0x3D,  0x10,  0x4C, 	/* 56690 */
+	0x10,  0x1A,  0x7F,  0x69,  0x90,  0x0E,  0x10,  0x12,  0x18,  0x34,  0x28,  0x4C,  0x24,  0x12,  0x42,  0x21, 	/* 566A0 */
+	0x80,  0x40,  0x7F,  0xAA,  0x08,  0x00,  0x08,  0xFF,  0x7F,  0x10,  0x2A,  0x10,  0x2A,  0x5E,  0x3D,  0x52, 	/* 566B0 */
+	0x4C,  0x52,  0x1A,  0x52,  0x69,  0x52,  0x0E,  0x52,  0x12,  0x7E,  0x34,  0x42,  0x4C,  0x02,  0x12,  0x0C, 	/* 566C0 */
+	0x21,  0x80,  0x40,  0x7F,  0xAD,  0x08,  0x20,  0x08,  0x20,  0x7F,  0x20,  0x2A,  0x3E,  0x2A,  0x42,  0x3D, 	/* 566D0 */
+	0x72,  0x4C,  0xD2,  0x1A,  0x52,  0x69,  0x72,  0x0E,  0x4C,  0x12,  0x40,  0x34,  0x42,  0x4C,  0x42,  0x12, 	/* 566E0 */
+	0x3E,  0x21,  0x80,  0x40,  0x7F,  0xB8,  0x08,  0x10,  0x08,  0x10,  0x7F,  0x10,  0x08,  0x7E,  0x3E,  0x10, 	/* 566F0 */
+	0x08,  0x10,  0x7F,  0x10,  0x08,  0xFF,  0x0E,  0x10,  0x12,  0x18,  0x32,  0x28,  0x4C,  0x24,  0x0C,  0x42, 	/* 56700 */
+	0x12,  0x81,  0x21,  0x80,  0x40,  0x7F,  0xB9,  0x08,  0x40,  0x08,  0x40,  0x3E,  0xFE,  0x08,  0xA2,  0x3F, 	/* 56710 */
+	0x2A,  0x08,  0xB2,  0x7F,  0x62,  0x10,  0xFA,  0x1E,  0x22,  0x12,  0x72,  0x34,  0xAA,  0x4D,  0x22,  0x0A, 	/* 56720 */
+	0x24,  0x11,  0x18,  0x20,  0xC0,  0x40,  0x3F,  0xBA,  0x08,  0x00,  0x09,  0xFF,  0x7F,  0x10,  0x08,  0x20, 	/* 56730 */
+	0x3E,  0xFE,  0x08,  0xAA,  0x7F,  0xBA,  0x08,  0xAA,  0x0E,  0xAA,  0x12,  0xBA,  0x2A,  0xAA,  0x44,  0xAA, 	/* 56740 */
+	0x0C,  0xFE,  0x12,  0x00,  0x21,  0x80,  0x40,  0x7F,  0xBB,  0x00,  0x80,  0x00,  0x80,  0x1F,  0xFE,  0x12, 	/* 56750 */
+	0x10,  0x12,  0x10,  0x12,  0x10,  0x1F,  0xFE,  0x12,  0x10,  0x16,  0x38,  0x17,  0x38,  0x16,  0xD4,  0x1A, 	/* 56760 */
+	0x54,  0x2A,  0x92,  0x32,  0x10,  0x42,  0x10,  0x02,  0x10,  0xBC,  0x00,  0x80,  0x00,  0x80,  0x1F,  0xFF, 	/* 56770 */
+	0x11,  0x08,  0x1F,  0xFF,  0x11,  0x08,  0x15,  0x5A,  0x15,  0x5A,  0x19,  0x5B,  0x10,  0x88,  0x10,  0x90, 	/* 56780 */
+	0x17,  0x20,  0x21,  0x48,  0x20,  0x84,  0x5F,  0xFA,  0x00,  0x02,  0xBE,  0x00,  0x40,  0x1F,  0xFF,  0x11, 	/* 56790 */
+	0x08,  0x1F,  0xFF,  0x11,  0x08,  0x15,  0xAA,  0x15,  0xAA,  0x1D,  0x4B,  0x10,  0x30,  0x13,  0xC0,  0x10, 	/* 567A0 */
+	0x78,  0x17,  0xC0,  0x20,  0x7E,  0x2F,  0xC1,  0x40,  0x41,  0x00,  0x3F,  0xBF,  0x00,  0x80,  0x00,  0x80, 	/* 567B0 */
+	0x1F,  0xFF,  0x12,  0x08,  0x1F,  0xFF,  0x13,  0x1C,  0x16,  0xAA,  0x1A,  0x49,  0x13,  0xF8,  0x12,  0x08, 	/* 567C0 */
+	0x13,  0xF8,  0x10,  0x40,  0x27,  0xFC,  0x24,  0x04,  0x47,  0xFC,  0x00,  0x00,  0x84,  0x02,  0x20,  0x02, 	/* 567D0 */
+	0x20,  0x1F,  0xFC,  0x02,  0x20,  0x02,  0x20,  0x7F,  0xFF,  0x00,  0x80,  0x0F,  0xF8,  0x08,  0x88,  0x08, 	/* 567E0 */
+	0x88,  0x0F,  0xF8,  0x08,  0x88,  0x08,  0x88,  0x0F,  0xF8,  0x04,  0x18,  0x38,  0x06,  0x8C,  0x06,  0x40, 	/* 567F0 */
+	0x19,  0x98,  0x12,  0x48,  0x19,  0x98,  0x12,  0x48,  0x7F,  0xFE,  0x42,  0x42,  0x5F,  0xFA,  0x02,  0x40, 	/* 56800 */
+	0x7F,  0xFE,  0x11,  0x08,  0x1F,  0xF8,  0x11,  0x08,  0x1F,  0xF8,  0x0C,  0x30,  0x70,  0x0C,  0x8D,  0x00, 	/* 56810 */
+	0x08,  0x00,  0x70,  0x1F,  0x80,  0x00,  0x80,  0x7F,  0xFF,  0x02,  0xA0,  0x0C,  0x98,  0x71,  0x47,  0x02, 	/* 56820 */
+	0x20,  0x0C,  0x98,  0x74,  0x8F,  0x02,  0x90,  0x03,  0xE0,  0x0C,  0x98,  0x30,  0x86,  0x01,  0x80,  0x8E, 	/* 56830 */
+	0x01,  0x10,  0x06,  0x10,  0x3C,  0x3E,  0x04,  0x2A,  0x7F,  0xCA,  0x0E,  0x12,  0x15,  0x22,  0x64,  0x8C, 	/* 56840 */
+	0x05,  0x40,  0x02,  0x20,  0x0C,  0x98,  0x78,  0xB7,  0x05,  0xC0,  0x06,  0xB0,  0x38,  0x8E,  0x01,  0x80, 	/* 56850 */
+	0x8F,  0x01,  0x10,  0x06,  0x10,  0x3C,  0x10,  0x04,  0x10,  0x7F,  0xDF,  0x0E,  0x10,  0x15,  0x10,  0x64, 	/* 56860 */
+	0x90,  0x0A,  0x10,  0x11,  0x7E,  0x74,  0xC2,  0x15,  0x42,  0x0E,  0x42,  0x35,  0x42,  0x44,  0xFE,  0x0C, 	/* 56870 */
+	0x00,  0x90,  0x02,  0x10,  0x0C,  0x10,  0x79,  0xFF,  0x08,  0x08,  0x7F,  0x4C,  0x1C,  0x74,  0x2A,  0x5C, 	/* 56880 */
+	0x48,  0x64,  0x14,  0x7C,  0x12,  0x20,  0x29,  0xFE,  0x6A,  0x92,  0x1C,  0x9A,  0x2A,  0xF6,  0x49,  0x82, 	/* 56890 */
+	0x18,  0x86,  0x92,  0x00,  0x00,  0x0F,  0xF8,  0x08,  0x88,  0x08,  0x88,  0x0F,  0xF8,  0x08,  0x88,  0x08, 	/* 568A0 */
+	0x88,  0x0F,  0xF8,  0x00,  0x80,  0x1F,  0xFC,  0x00,  0x80,  0x7F,  0xFF,  0x00,  0x00,  0x12,  0x24,  0x21, 	/* 568B0 */
+	0x12,  0x41,  0x11,  0x94,  0x00,  0x10,  0x3F,  0x10,  0x29,  0x10,  0x2B,  0x28,  0x3B,  0x28,  0x3D,  0x44, 	/* 568C0 */
+	0x29,  0xBE,  0x3F,  0x01,  0x08,  0x00,  0x3F,  0x7C,  0x08,  0x04,  0x0B,  0x84,  0x7D,  0x08,  0x22,  0x88, 	/* 568D0 */
+	0x2A,  0x10,  0x48,  0x10,  0x98,  0x00,  0x08,  0x3F,  0x8A,  0x24,  0x89,  0x25,  0x89,  0x35,  0x88,  0x2E, 	/* 568E0 */
+	0xFF,  0x2C,  0x88,  0x3F,  0x88,  0x04,  0x0C,  0x3F,  0x0C,  0x04,  0x14,  0x07,  0x94,  0x7D,  0x14,  0x32, 	/* 568F0 */
+	0xA2,  0x2A,  0x42,  0x48,  0x81,  0x99,  0x00,  0x10,  0x3F,  0x14,  0x29,  0x12,  0x3F,  0x10,  0x29,  0xFF, 	/* 56900 */
+	0x29,  0x10,  0x3F,  0x28,  0x08,  0x28,  0x3F,  0x24,  0x08,  0x44,  0x0E,  0x82,  0x79,  0x01,  0x10,  0x08, 	/* 56910 */
+	0x14,  0x44,  0x22,  0x22,  0x42,  0x22,  0x9B,  0x04,  0x28,  0x08,  0x24,  0x1B,  0xFF,  0x68,  0x20,  0x08, 	/* 56920 */
+	0x11,  0x0F,  0xFD,  0x08,  0x8B,  0x0F,  0xF9,  0x08,  0x88,  0x0F,  0xF8,  0x00,  0x80,  0x1F,  0xFC,  0x00, 	/* 56930 */
+	0x80,  0x7F,  0xFF,  0x12,  0x24,  0x61,  0x13,  0x9C,  0x00,  0x10,  0x3F,  0x52,  0x29,  0x52,  0x2B,  0x52, 	/* 56940 */
+	0x3B,  0x52,  0x3D,  0x52,  0x29,  0x7E,  0x3F,  0x10,  0x08,  0x10,  0x3F,  0x52,  0x08,  0x52,  0x0B,  0xD2, 	/* 56950 */
+	0x7D,  0x52,  0x22,  0xD2,  0x2A,  0xFE,  0x48,  0x00,  0x9D,  0x00,  0x48,  0x3E,  0x48,  0x2A,  0x48,  0x2E, 	/* 56960 */
+	0x7E,  0x3E,  0x4A,  0x3B,  0x8A,  0x2B,  0x2A,  0x3E,  0xAA,  0x08,  0x4A,  0x3E,  0x4A,  0x08,  0xAA,  0x0B, 	/* 56970 */
+	0x32,  0x7D,  0xD2,  0x22,  0x22,  0x2A,  0x42,  0x48,  0x8C,  0x9E,  0x00,  0x10,  0x3F,  0x10,  0x29,  0x10, 	/* 56980 */
+	0x2B,  0x1F,  0x3B,  0x10,  0x3D,  0x10,  0x29,  0x10,  0x3F,  0x10,  0x08,  0x7E,  0x3F,  0x42,  0x08,  0x42, 	/* 56990 */
+	0x0B,  0xC2,  0x7D,  0x42,  0x22,  0xC2,  0x2A,  0x7E,  0x48,  0x00,  0xA0,  0x00,  0x10,  0x3F,  0x10,  0x29, 	/* 569A0 */
+	0x10,  0x2B,  0xFF,  0x3B,  0x10,  0x3D,  0x10,  0x29,  0x10,  0x3F,  0x7E,  0x08,  0x00,  0x3F,  0x7C,  0x08, 	/* 569B0 */
+	0x44,  0x0B,  0xC4,  0x7D,  0x44,  0x22,  0xC4,  0x2A,  0x7C,  0x48,  0x00,  0xA5,  0x00,  0x10,  0x3F,  0x10, 	/* 569C0 */
+	0x29,  0xFF,  0x2B,  0x00,  0x3B,  0x7C,  0x3D,  0x44,  0x29,  0x44,  0x3F,  0x44,  0x08,  0x7C,  0x3F,  0x10, 	/* 569D0 */
+	0x08,  0x58,  0x0B,  0x54,  0x7D,  0x52,  0x22,  0x92,  0x2B,  0x10,  0x48,  0x30,  0xA8,  0x08,  0x90,  0x04, 	/* 569E0 */
+	0xA0,  0x7F,  0xFE,  0x40,  0x02,  0x4F,  0xF2,  0x08,  0x10,  0x0F,  0xF0,  0x00,  0x00,  0x1F,  0xF8,  0x14, 	/* 569F0 */
+	0xA8,  0x12,  0xC8,  0x3F,  0xFE,  0x00,  0x80,  0x7F,  0xFF,  0x14,  0x44,  0x62,  0x22,  0xAF,  0x00,  0x10, 	/* 56A00 */
+	0x3F,  0x10,  0x29,  0xFF,  0x2B,  0x44,  0x3B,  0x24,  0x3D,  0x28,  0x29,  0xFF,  0x3F,  0x00,  0x08,  0x7C, 	/* 56A10 */
+	0x3F,  0x44,  0x08,  0x44,  0x0B,  0xFC,  0x7D,  0x44,  0x22,  0xC4,  0x2A,  0x7C,  0x48,  0x00,  0xB4,  0x0D, 	/* 56A20 */
+	0x48,  0x0D,  0x48,  0x17,  0xC8,  0x10,  0x0F,  0x27,  0xD2,  0x4D,  0xD2,  0x0F,  0x5A,  0x15,  0x6A,  0x17, 	/* 56A30 */
+	0xCA,  0x31,  0x0C,  0x57,  0xC4,  0x11,  0x6C,  0x1F,  0x8A,  0x16,  0x52,  0x15,  0x22,  0x18,  0x41,  0xB6, 	/* 56A40 */
+	0x00,  0x00,  0x1F,  0xFF,  0x14,  0x4A,  0x17,  0xFF,  0x14,  0x48,  0x17,  0xCC,  0x14,  0x54,  0x24,  0xE2, 	/* 56A50 */
+	0x2F,  0xF9,  0x4C,  0x98,  0x0A,  0xA8,  0x3F,  0xFE,  0x00,  0x80,  0x7F,  0xFF,  0x12,  0x26,  0x61,  0x11, 	/* 56A60 */
+	0xB7,  0x00,  0x08,  0x3F,  0xFF,  0x29,  0x08,  0x2B,  0x7E,  0x3B,  0x00,  0x3D,  0x7F,  0x29,  0x55,  0x3F, 	/* 56A70 */
+	0x7F,  0x08,  0x22,  0x3F,  0x3E,  0x08,  0x22,  0x0B,  0xBE,  0x7D,  0x22,  0x22,  0xBE,  0x2A,  0x32,  0x48, 	/* 56A80 */
+	0xC1,  0xB9,  0x11,  0x44,  0x09,  0x44,  0x09,  0x48,  0x7F,  0xFF,  0x08,  0x88,  0x08,  0x84,  0x10,  0x82, 	/* 56A90 */
+	0x3F,  0xFD,  0x50,  0x85,  0x12,  0xA4,  0x12,  0xA4,  0x12,  0xA4,  0x12,  0xA4,  0x12,  0xA4,  0x14,  0xA4, 	/* 56AA0 */
+	0x10,  0x8C,  0xBB,  0x0A,  0x14,  0x2A,  0x92,  0x1B,  0x12,  0x7F,  0xFF,  0x15,  0x10,  0x24,  0x92,  0x44, 	/* 56AB0 */
+	0x12,  0x3F,  0xAA,  0x24,  0xAA,  0x2D,  0xAC,  0x2D,  0xA4,  0x2D,  0xCC,  0x2D,  0xCD,  0x34,  0x93,  0x24, 	/* 56AC0 */
+	0xA3,  0x25,  0x81,  0xBC,  0x0A,  0x08,  0x2A,  0x8C,  0x1B,  0x0A,  0x7F,  0xFF,  0x15,  0x08,  0x24,  0xBE, 	/* 56AD0 */
+	0x44,  0x2A,  0x3F,  0xAA,  0x24,  0xBE,  0x2D,  0xAA,  0x2D,  0xAA,  0x2D,  0xBE,  0x2D,  0xAA,  0x34,  0xAA, 	/* 56AE0 */
+	0x24,  0xAA,  0x25,  0xA6,  0xBD,  0x00,  0x00,  0x3F,  0xFC,  0x22,  0x44,  0x22,  0x44,  0x3E,  0x7C,  0x02, 	/* 56AF0 */
+	0x40,  0x3E,  0x7C,  0x22,  0x44,  0x22,  0x44,  0x3E,  0x7C,  0x22,  0x44,  0x22,  0x44,  0x3E,  0x7D,  0x02, 	/* 56B00 */
+	0x01,  0x02,  0x01,  0x01,  0xFF,  0x87,  0x04,  0x20,  0x3F,  0x3F,  0x04,  0x24,  0x7F,  0xB4,  0x08,  0x48, 	/* 56B10 */
+	0x1F,  0x14,  0x21,  0x22,  0x5F,  0xF9,  0x12,  0x48,  0x3E,  0x7C,  0x22,  0x44,  0x3E,  0x7C,  0x22,  0x44, 	/* 56B20 */
+	0x3E,  0x7D,  0x02,  0x01,  0x01,  0xFF,  0x88,  0x1A,  0x10,  0x29,  0x1F,  0x7F,  0xA4,  0x48,  0xD4,  0x5A, 	/* 56B30 */
+	0x88,  0x6A,  0x94,  0x49,  0xA2,  0x5F,  0xF9,  0x12,  0x48,  0x3E,  0x7C,  0x22,  0x44,  0x3E,  0x7C,  0x22, 	/* 56B40 */
+	0x44,  0x3E,  0x7D,  0x02,  0x01,  0x01,  0xFF,  0x8E,  0x00,  0x00,  0x17,  0xF4,  0x14,  0x14,  0x17,  0xF4, 	/* 56B50 */
+	0x14,  0x14,  0x17,  0xF4,  0x14,  0x14,  0x17,  0xF4,  0x10,  0x04,  0x3F,  0x7C,  0x01,  0x40,  0x7F,  0x7F, 	/* 56B60 */
+	0x09,  0x44,  0x09,  0x44,  0x11,  0x44,  0x21,  0x44,  0x93,  0x08,  0x10,  0x08,  0x10,  0x7F,  0xFF,  0x08, 	/* 56B70 */
+	0x10,  0x3E,  0x10,  0x00,  0xFC,  0x3E,  0x44,  0x22,  0x44,  0x22,  0x44,  0x3E,  0x28,  0x02,  0x28,  0x24, 	/* 56B80 */
+	0x10,  0x11,  0x28,  0x16,  0x44,  0x18,  0x82,  0x61,  0x01,  0x95,  0x04,  0x08,  0x7F,  0xC8,  0x04,  0x7F, 	/* 56B90 */
+	0x3F,  0x88,  0x11,  0x7E,  0x1F,  0x24,  0x12,  0x18,  0x0F,  0x94,  0x70,  0xA3,  0x01,  0xF0,  0x07,  0x10, 	/* 56BA0 */
+	0x18,  0xE0,  0x03,  0xD8,  0x7C,  0x27,  0x03,  0x80,  0x00,  0x70,  0xA0,  0x02,  0x00,  0x1C,  0xF8,  0x10, 	/* 56BB0 */
+	0x08,  0x1E,  0x78,  0x10,  0x08,  0x1F,  0xF8,  0x00,  0x00,  0x14,  0xC8,  0x12,  0xA8,  0x10,  0x88,  0x14, 	/* 56BC0 */
+	0xC8,  0x12,  0xA8,  0x10,  0x85,  0x16,  0xB5,  0x18,  0xC3,  0x63,  0x01,  0xA1,  0x02,  0x08,  0x21,  0x08, 	/* 56BD0 */
+	0x11,  0x10,  0x10,  0x20,  0x00,  0x40,  0x1F,  0xF8,  0x11,  0x08,  0x11,  0x08,  0x1F,  0xF8,  0x11,  0x08, 	/* 56BE0 */
+	0x11,  0x08,  0x1F,  0xF8,  0x11,  0x09,  0x21,  0x05,  0x21,  0x03,  0x41,  0x01,  0xAC,  0x08,  0x10,  0x33, 	/* 56BF0 */
+	0x10,  0x21,  0x10,  0x3B,  0x7E,  0x21,  0x52,  0x21,  0x52,  0x3F,  0x52,  0x00,  0x7E,  0x25,  0x52,  0x37, 	/* 56C00 */
+	0x52,  0x25,  0x52,  0x25,  0x7E,  0x37,  0x00,  0x24,  0x81,  0x37,  0x61,  0x6C,  0x1F,  0xBB,  0x01,  0x00, 	/* 56C10 */
+	0x07,  0xF0,  0x04,  0x10,  0x07,  0xF0,  0x04,  0x10,  0x07,  0xF0,  0x04,  0x10,  0x1F,  0xFC,  0x10,  0x84, 	/* 56C20 */
+	0x1F,  0xFC,  0x10,  0x84,  0x1F,  0xFC,  0x02,  0x10,  0x7F,  0xFF,  0x04,  0x10,  0x08,  0x10,  0xBE,  0x04, 	/* 56C30 */
+	0x00,  0x1F,  0x7E,  0x11,  0x08,  0x1F,  0x08,  0x11,  0x08,  0x1F,  0x08,  0x11,  0x08,  0x3F,  0xFF,  0x24, 	/* 56C40 */
+	0x88,  0x3F,  0x88,  0x24,  0x88,  0x3F,  0x88,  0x00,  0x08,  0x7F,  0xC8,  0x09,  0x08,  0x11,  0x08,  0x8A, 	/* 56C50 */
+	0x00,  0x80,  0x00,  0x80,  0x7F,  0xFF,  0x02,  0x22,  0x7D,  0x5C,  0x14,  0x94,  0x14,  0x94,  0x2C,  0x9A, 	/* 56C60 */
+	0x40,  0x81,  0x08,  0x08,  0x0F,  0xF8,  0x08,  0x08,  0x0F,  0xF8,  0x08,  0x08,  0x10,  0x08,  0x20,  0x08, 	/* 56C70 */
+	0x8B,  0x00,  0x80,  0x7F,  0xFF,  0x02,  0x22,  0x7D,  0x5C,  0x14,  0x94,  0x14,  0x92,  0x2C,  0x99,  0x48, 	/* 56C80 */
+	0x04,  0x0F,  0xFC,  0x08,  0x04,  0x0F,  0xFC,  0x08,  0x84,  0x0A,  0xA4,  0x12,  0x94,  0x14,  0x94,  0x21, 	/* 56C90 */
+	0x84,  0x8E,  0x00,  0x80,  0x7F,  0xFF,  0x02,  0x22,  0x3D,  0x5C,  0x14,  0x94,  0x2C,  0x9A,  0x50,  0x05, 	/* 56CA0 */
+	0x1F,  0xFC,  0x10,  0x04,  0x1F,  0xFC,  0x14,  0x14,  0x17,  0xF4,  0x14,  0x14,  0x17,  0xF4,  0x22,  0x24, 	/* 56CB0 */
+	0x44,  0x14,  0x8F,  0x00,  0x80,  0x7F,  0xFF,  0x02,  0x22,  0x7D,  0x5C,  0x14,  0x94,  0x2C,  0x9A,  0x48, 	/* 56CC0 */
+	0x85,  0x0F,  0xFC,  0x08,  0x04,  0x0F,  0xFC,  0x09,  0x24,  0x0F,  0x3C,  0x0F,  0x3C,  0x11,  0x24,  0x17, 	/* 56CD0 */
+	0xFC,  0x20,  0x04,  0x92,  0x00,  0x80,  0x08,  0x80,  0x08,  0xFC,  0x08,  0x80,  0x08,  0x80,  0x7F,  0xFF, 	/* 56CE0 */
+	0x12,  0x24,  0x12,  0x24,  0x15,  0x54,  0x1F,  0xFC,  0x12,  0x24,  0x12,  0x24,  0x15,  0x54,  0x10,  0x04, 	/* 56CF0 */
+	0x1F,  0xFC,  0x00,  0x00,  0x94,  0x04,  0x20,  0x14,  0x20,  0x17,  0xA0,  0x14,  0x22,  0x14,  0x22,  0x7F, 	/* 56D00 */
+	0xE4,  0x2A,  0xA8,  0x2A,  0xB0,  0x35,  0xA0,  0x3F,  0xA0,  0x2A,  0xA0,  0x2A,  0xA0,  0x35,  0xA1,  0x20, 	/* 56D10 */
+	0xA1,  0x3F,  0x9F,  0x00,  0x00,  0x9F,  0x04,  0x00,  0x14,  0x3E,  0x17,  0xA2,  0x14,  0x22,  0x14,  0x22, 	/* 56D20 */
+	0x7F,  0xBE,  0x2A,  0xA2,  0x2A,  0xA2,  0x35,  0xA2,  0x3F,  0xBE,  0x2A,  0xA2,  0x2A,  0xA2,  0x35,  0xA2, 	/* 56D30 */
+	0x20,  0xA2,  0x3F,  0xFF,  0x00,  0x00,  0xA0,  0x04,  0x00,  0x14,  0x7E,  0x17,  0x92,  0x14,  0x12,  0x14, 	/* 56D40 */
+	0x12,  0x7F,  0xD2,  0x2A,  0xA2,  0x2A,  0xAC,  0x35,  0xC0,  0x3F,  0xBE,  0x2A,  0xA2,  0x2A,  0xA2,  0x35, 	/* 56D50 */
+	0xA2,  0x20,  0xA2,  0x3F,  0xBE,  0x00,  0x00,  0xA1,  0x04,  0x08,  0x14,  0x08,  0x17,  0x94,  0x14,  0x14, 	/* 56D60 */
+	0x14,  0x22,  0x7F,  0xFD,  0x2A,  0x80,  0x2A,  0x80,  0x35,  0xFE,  0x3F,  0x92,  0x2A,  0x92,  0x2A,  0x92, 	/* 56D70 */
+	0x35,  0x9C,  0x20,  0x90,  0x3F,  0x90,  0x00,  0x10,  0xA2,  0x04,  0x10,  0x14,  0x10,  0x17,  0xA8,  0x14, 	/* 56D80 */
+	0x28,  0x14,  0x44,  0x7F,  0xBA,  0x25,  0x81,  0x36,  0x80,  0x2C,  0xFE,  0x3F,  0x92,  0x24,  0x92,  0x2E, 	/* 56D90 */
+	0x92,  0x35,  0x9C,  0x24,  0x90,  0x3F,  0x90,  0x00,  0x10,  0xA3,  0x04,  0x20,  0x14,  0x20,  0x17,  0xBE, 	/* 56DA0 */
+	0x14,  0x22,  0x14,  0x42,  0x7F,  0xFA,  0x2A,  0xAA,  0x2A,  0xAA,  0x35,  0xAA,  0x3F,  0xAA,  0x2A,  0xBA, 	/* 56DB0 */
+	0x2A,  0x82,  0x35,  0x82,  0x20,  0x82,  0x3F,  0x82,  0x00,  0x0C,  0xA6,  0x04,  0x00,  0x14,  0x3E,  0x17, 	/* 56DC0 */
+	0xA2,  0x14,  0x22,  0x14,  0x3E,  0x7F,  0xA2,  0x2A,  0xA2,  0x2A,  0xBE,  0x35,  0xA9,  0x3F,  0xAA,  0x2A, 	/* 56DD0 */
+	0xAC,  0x2A,  0xA8,  0x35,  0xA4,  0x20,  0xAC,  0x3F,  0xB2,  0x00,  0x61,  0xA7,  0x04,  0x00,  0x3F,  0x7E, 	/* 56DE0 */
+	0x04,  0x12,  0x3F,  0x12,  0x04,  0x22,  0x07,  0x4C,  0x7C,  0xFC,  0x04,  0x80,  0x7F,  0xFF,  0x12,  0x24, 	/* 56DF0 */
+	0x15,  0x54,  0x1F,  0xFC,  0x12,  0x24,  0x15,  0x54,  0x1F,  0xFC,  0x00,  0x00,  0xAA,  0x04,  0x00,  0x14, 	/* 56E00 */
+	0x3E,  0x17,  0xA2,  0x14,  0x22,  0x14,  0x22,  0x7F,  0xE2,  0x2A,  0xBE,  0x2A,  0x88,  0x35,  0xA8,  0x3F, 	/* 56E10 */
+	0xA8,  0x2A,  0xAF,  0x2A,  0xA8,  0x35,  0xA8,  0x20,  0xB8,  0x3F,  0xC8,  0x00,  0x87,  0xAC,  0x04,  0x00, 	/* 56E20 */
+	0x14,  0x7F,  0x17,  0x88,  0x14,  0x08,  0x14,  0x3E,  0x7F,  0xD2,  0x2A,  0x92,  0x2A,  0x92,  0x35,  0xFF, 	/* 56E30 */
+	0x3F,  0x80,  0x2A,  0xBE,  0x2A,  0xA2,  0x35,  0xA2,  0x20,  0xA2,  0x3F,  0xBE,  0x00,  0x00,  0xB2,  0x04, 	/* 56E40 */
+	0x04,  0x14,  0x78,  0x17,  0x90,  0x14,  0x7E,  0x14,  0x52,  0x7F,  0xD2,  0x2B,  0x7E,  0x2B,  0x10,  0x35, 	/* 56E50 */
+	0x7E,  0x3F,  0x52,  0x2B,  0x52,  0x2B,  0x6A,  0x35,  0x7E,  0x21,  0x42,  0x3F,  0x42,  0x00,  0x46,  0xB6, 	/* 56E60 */
+	0x04,  0x00,  0x14,  0x77,  0x17,  0xD5,  0x14,  0x55,  0x14,  0x77,  0x7F,  0xC0,  0x2A,  0xBE,  0x2A,  0x80, 	/* 56E70 */
+	0x35,  0xFF,  0x3F,  0x88,  0x2A,  0x88,  0x2A,  0x9E,  0x35,  0x92,  0x20,  0x82,  0x3F,  0x82,  0x00,  0x0C, 	/* 56E80 */
+	0xB7,  0x04,  0x00,  0x14,  0x7E,  0x17,  0x42,  0x14,  0x42,  0x14,  0x7E,  0x7F,  0xC0,  0x2B,  0x7F,  0x2B, 	/* 56E90 */
+	0x48,  0x35,  0x56,  0x3F,  0x7D,  0x2B,  0x48,  0x2B,  0x7E,  0x35,  0x48,  0x21,  0x88,  0x3F,  0xBF,  0x01, 	/* 56EA0 */
+	0x00,  0x8D,  0x04,  0x20,  0x04,  0x20,  0x3F,  0xBF,  0x11,  0x20,  0x0A,  0x3E,  0x7F,  0xC2,  0x00,  0x3E, 	/* 56EB0 */
+	0x1F,  0x20,  0x11,  0x3E,  0x1F,  0x20,  0x11,  0x3E,  0x1F,  0x20,  0x11,  0x3E,  0x11,  0x21,  0x11,  0x11, 	/* 56EC0 */
+	0x13,  0x0F,  0x95,  0x00,  0x80,  0x01,  0x40,  0x06,  0x30,  0x1F,  0xFC,  0x68,  0x0B,  0x0F,  0xF8,  0x04, 	/* 56ED0 */
+	0x20,  0x3F,  0xBF,  0x12,  0x20,  0x7F,  0xFE,  0x11,  0x02,  0x1F,  0x3E,  0x11,  0x20,  0x1F,  0x3E,  0x11, 	/* 56EE0 */
+	0x21,  0x13,  0x1F,  0x9C,  0x02,  0x00,  0x0F,  0xE0,  0x70,  0x40,  0x0F,  0xF8,  0x09,  0x48,  0x0F,  0x78, 	/* 56EF0 */
+	0x3D,  0x40,  0x7F,  0xFE,  0x05,  0x4A,  0x3D,  0x6A,  0x01,  0x52,  0x3D,  0x6A,  0x7F,  0xFE,  0x05,  0x01, 	/* 56F00 */
+	0x3D,  0x01,  0x00,  0xFF,  0x9D,  0x04,  0x40,  0x18,  0xF8,  0x71,  0x10,  0x17,  0xFC,  0x12,  0x54,  0x7B, 	/* 56F10 */
+	0xDC,  0x17,  0x50,  0x17,  0xFE,  0x39,  0x5A,  0x37,  0x56,  0x30,  0x5A,  0x57,  0x56,  0x57,  0xFE,  0x11, 	/* 56F20 */
+	0x41,  0x17,  0x41,  0x10,  0x3F,  0xA0,  0x00,  0x80,  0x01,  0x40,  0x02,  0x20,  0x0F,  0xF8,  0x70,  0x07, 	/* 56F30 */
+	0x1D,  0xEE,  0x15,  0x2A,  0x1D,  0xEE,  0x00,  0x00,  0x0F,  0xFC,  0x09,  0x24,  0x09,  0x24,  0x0F,  0xFC, 	/* 56F40 */
+	0x09,  0x24,  0x09,  0x24,  0x09,  0x2C,  0x81,  0x00,  0x00,  0x01,  0x80,  0x01,  0x80,  0x01,  0x80,  0x01, 	/* 56F50 */
+	0x80,  0x01,  0x00,  0x01,  0x00,  0x01,  0x00,  0x01,  0x00,  0x01,  0x00,  0x01,  0x00,  0x00,  0x00,  0x00, 	/* 56F60 */
+	0x00,  0x01,  0x00,  0x01,  0x00,  0x00,  0x00,  0x83,  0x02,  0x10,  0x02,  0x10,  0x02,  0x10,  0x02,  0x10, 	/* 56F70 */
+	0x1F,  0xFC,  0x1F,  0xFC,  0x04,  0x20,  0x04,  0x20,  0x04,  0x20,  0x04,  0x20,  0x3F,  0xF8,  0x3F,  0xF8, 	/* 56F80 */
+	0x08,  0x40,  0x08,  0x40,  0x08,  0x40,  0x08,  0x40,  0x84,  0x00,  0x00,  0x02,  0x80,  0x07,  0xC0,  0x0A, 	/* 56F90 */
+	0xA0,  0x12,  0x90,  0x12,  0x90,  0x0A,  0x80,  0x07,  0x80,  0x02,  0xE0,  0x02,  0x90,  0x12,  0x88,  0x12, 	/* 56FA0 */
+	0x88,  0x0A,  0x90,  0x07,  0xE0,  0x02,  0x80,  0x00,  0x00,  0x85,  0x00,  0x00,  0x38,  0x02,  0x64,  0x04, 	/* 56FB0 */
+	0x44,  0x08,  0x44,  0x10,  0x44,  0x20,  0x4C,  0x40,  0x38,  0x80,  0x01,  0x38,  0x02,  0x64,  0x04,  0x44, 	/* 56FC0 */
+	0x08,  0x44,  0x10,  0x44,  0x20,  0x4C,  0x40,  0x38,  0x00,  0x00,  0x86,  0x00,  0x00,  0x0F,  0x00,  0x10, 	/* 56FD0 */
+	0x80,  0x10,  0x80,  0x10,  0x80,  0x09,  0x00,  0x06,  0x10,  0x04,  0x10,  0x0A,  0x10,  0x11,  0x20,  0x20, 	/* 56FE0 */
+	0xA0,  0x20,  0x40,  0x20,  0xA0,  0x11,  0x12,  0x0E,  0x0C,  0x00,  0x00,  0x88,  0x00,  0x00,  0x00,  0x08, 	/* 56FF0 */
+	0x00,  0x10,  0x00,  0x20,  0x00,  0x40,  0x00,  0x40,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80, 	/* 57000 */
+	0x00,  0x80,  0x00,  0x40,  0x00,  0x40,  0x00,  0x20,  0x00,  0x10,  0x00,  0x08,  0x89,  0x00,  0x00,  0x10, 	/* 57010 */
+	0x00,  0x08,  0x00,  0x04,  0x00,  0x02,  0x00,  0x02,  0x00,  0x01,  0x00,  0x01,  0x00,  0x01,  0x00,  0x01, 	/* 57020 */
+	0x00,  0x01,  0x00,  0x02,  0x00,  0x02,  0x00,  0x04,  0x00,  0x08,  0x00,  0x10,  0x00,  0x8A,  0x00,  0x00, 	/* 57030 */
+	0x00,  0x00,  0x00,  0x00,  0x01,  0x00,  0x01,  0x00,  0x19,  0x30,  0x0D,  0x60,  0x03,  0x80,  0x01,  0x00, 	/* 57040 */
+	0x03,  0x80,  0x0D,  0x60,  0x19,  0x30,  0x01,  0x00,  0x01,  0x00,  0x00,  0x00,  0x00,  0x00,  0x8B,  0x00, 	/* 57050 */
+	0x00,  0x00,  0x00,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x1F,  0xFC,  0x00, 	/* 57060 */
+	0x80,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x00,  0x00,  0x00,  0x00,  0x8C, 	/* 57070 */
+	0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00, 	/* 57080 */
+	0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x60,  0x00,  0x60,  0x00,  0x20,  0x00,  0x40,  0x00, 	/* 57090 */
+	0x8D,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x3F, 	/* 570A0 */
+	0xFC,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00, 	/* 570B0 */
+	0x00,  0x8E,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00, 	/* 570C0 */
+	0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x60,  0x00,  0x60,  0x00,  0x00,  0x00, 	/* 570D0 */
+	0x00,  0x00,  0x8F,  0x00,  0x01,  0x00,  0x02,  0x00,  0x04,  0x00,  0x08,  0x00,  0x10,  0x00,  0x20,  0x00, 	/* 570E0 */
+	0x40,  0x00,  0x80,  0x01,  0x00,  0x02,  0x00,  0x04,  0x00,  0x08,  0x00,  0x10,  0x00,  0x20,  0x00,  0x40, 	/* 570F0 */
+	0x00,  0x80,  0x00,  0x90,  0x00,  0x00,  0x03,  0xC0,  0x04,  0x20,  0x08,  0x10,  0x08,  0x10,  0x10,  0x08, 	/* 57100 */
+	0x10,  0x08,  0x10,  0x08,  0x10,  0x08,  0x10,  0x08,  0x10,  0x08,  0x08,  0x10,  0x08,  0x10,  0x04,  0x20, 	/* 57110 */
+	0x03,  0xC0,  0x00,  0x00,  0x91,  0x00,  0x00,  0x00,  0x80,  0x00,  0x80,  0x01,  0x80,  0x02,  0x80,  0x00, 	/* 57120 */
+	0x80,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x00, 	/* 57130 */
+	0x80,  0x01,  0xC0,  0x00,  0x00,  0x92,  0x00,  0x00,  0x03,  0xE0,  0x04,  0x10,  0x08,  0x08,  0x08,  0x08, 	/* 57140 */
+	0x00,  0x08,  0x00,  0x10,  0x00,  0x20,  0x00,  0x40,  0x00,  0x80,  0x01,  0x00,  0x02,  0x00,  0x04,  0x00, 	/* 57150 */
+	0x04,  0x00,  0x0F,  0xF8,  0x00,  0x00,  0x93,  0x00,  0x00,  0x03,  0xC0,  0x0C,  0x20,  0x10,  0x10,  0x00, 	/* 57160 */
+	0x10,  0x00,  0x20,  0x00,  0x40,  0x03,  0xE0,  0x00,  0x10,  0x00,  0x08,  0x00,  0x08,  0x00,  0x08,  0x10, 	/* 57170 */
+	0x10,  0x0C,  0x60,  0x03,  0x80,  0x00,  0x00,  0x94,  0x00,  0x00,  0x00,  0x20,  0x00,  0x20,  0x00,  0x60, 	/* 57180 */
+	0x00,  0xA0,  0x01,  0x20,  0x02,  0x20,  0x04,  0x20,  0x08,  0x20,  0x10,  0x20,  0x1F,  0xFC,  0x00,  0x20, 	/* 57190 */
+	0x00,  0x20,  0x00,  0x20,  0x00,  0x70,  0x00,  0x00,  0x95,  0x00,  0x00,  0x0F,  0xF8,  0x08,  0x00,  0x08, 	/* 571A0 */
+	0x00,  0x08,  0x00,  0x08,  0x00,  0x0B,  0xE0,  0x0C,  0x10,  0x08,  0x08,  0x00,  0x08,  0x00,  0x08,  0x00, 	/* 571B0 */
+	0x08,  0x00,  0x10,  0x0C,  0x60,  0x03,  0x80,  0x00,  0x00,  0x96,  0x00,  0x00,  0x00,  0xE0,  0x03,  0x00, 	/* 571C0 */
+	0x04,  0x00,  0x08,  0x00,  0x08,  0x00,  0x13,  0xC0,  0x14,  0x20,  0x18,  0x10,  0x10,  0x08,  0x10,  0x08, 	/* 571D0 */
+	0x10,  0x08,  0x08,  0x10,  0x04,  0x20,  0x03,  0xC0,  0x00,  0x00,  0x97,  0x00,  0x00,  0x1F,  0xF8,  0x10, 	/* 571E0 */
+	0x08,  0x10,  0x10,  0x10,  0x10,  0x00,  0x20,  0x00,  0x20,  0x00,  0x40,  0x00,  0x40,  0x00,  0x80,  0x00, 	/* 571F0 */
+	0x80,  0x00,  0x80,  0x01,  0x00,  0x01,  0x00,  0x01,  0x00,  0x00,  0x00,  0x98,  0x00,  0x00,  0x03,  0xC0, 	/* 57200 */
+	0x0C,  0x30,  0x10,  0x08,  0x10,  0x08,  0x10,  0x08,  0x0C,  0x30,  0x03,  0xC0,  0x04,  0x20,  0x08,  0x10, 	/* 57210 */
+	0x10,  0x08,  0x10,  0x08,  0x18,  0x18,  0x0C,  0x30,  0x03,  0xC0,  0x00,  0x00,  0x99,  0x00,  0x00,  0x03, 	/* 57220 */
+	0xC0,  0x04,  0x20,  0x08,  0x10,  0x10,  0x08,  0x10,  0x08,  0x10,  0x08,  0x08,  0x18,  0x04,  0x28,  0x03, 	/* 57230 */
+	0xC8,  0x00,  0x10,  0x00,  0x10,  0x00,  0x20,  0x00,  0xC0,  0x07,  0x00,  0x00,  0x00,  0x9A,  0x00,  0x00, 	/* 57240 */
+	0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x01,  0x80,  0x01,  0x80,  0x00,  0x00,  0x00,  0x00, 	/* 57250 */
+	0x00,  0x00,  0x00,  0x00,  0x01,  0x80,  0x01,  0x80,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x9B,  0x00, 	/* 57260 */
+	0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x01,  0x80,  0x01,  0x80,  0x00,  0x00,  0x00, 	/* 57270 */
+	0x00,  0x00,  0x00,  0x00,  0x00,  0x01,  0x80,  0x01,  0x80,  0x00,  0x80,  0x01,  0x00,  0x00,  0x00,  0x9C, 	/* 57280 */
+	0x00,  0x00,  0x00,  0x00,  0x00,  0x18,  0x00,  0x60,  0x01,  0x80,  0x02,  0x00,  0x0C,  0x00,  0x30,  0x00, 	/* 57290 */
+	0x0C,  0x00,  0x02,  0x00,  0x01,  0x80,  0x00,  0x60,  0x00,  0x18,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00, 	/* 572A0 */
+	0x9D,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x3F,  0xFC,  0x00,  0x00,  0x00, 	/* 572B0 */
+	0x00,  0x00,  0x00,  0x3F,  0xFC,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00, 	/* 572C0 */
+	0x00,  0x9E,  0x00,  0x00,  0x00,  0x00,  0x18,  0x00,  0x06,  0x00,  0x01,  0x80,  0x00,  0x40,  0x00,  0x30, 	/* 572D0 */
+	0x00,  0x0C,  0x00,  0x30,  0x00,  0x40,  0x01,  0x80,  0x06,  0x00,  0x18,  0x00,  0x00,  0x00,  0x00,  0x00, 	/* 572E0 */
+	0x00,  0x00,  0x9F,  0x00,  0x00,  0x03,  0xC0,  0x04,  0x20,  0x08,  0x10,  0x08,  0x10,  0x08,  0x10,  0x04, 	/* 572F0 */
+	0x20,  0x00,  0x40,  0x00,  0x80,  0x01,  0x00,  0x01,  0x00,  0x00,  0x00,  0x00,  0x00,  0x01,  0x00,  0x01, 	/* 57300 */
+	0x00,  0x00,  0x00,  0xA0,  0x00,  0x00,  0x00,  0x00,  0x03,  0xC0,  0x0C,  0x30,  0x10,  0x08,  0x11,  0xA8, 	/* 57310 */
+	0x22,  0x64,  0x24,  0x44,  0x24,  0x44,  0x24,  0xE8,  0x13,  0x70,  0x10,  0x04,  0x0C,  0x18,  0x03,  0xE0, 	/* 57320 */
+	0x00,  0x00,  0x00,  0x00,  0xA1,  0x00,  0x00,  0x00,  0x80,  0x00,  0x80,  0x01,  0x40,  0x01,  0x40,  0x02, 	/* 57330 */
+	0x20,  0x02,  0x20,  0x04,  0x10,  0x07,  0xF0,  0x04,  0x10,  0x08,  0x08,  0x08,  0x08,  0x10,  0x04,  0x38, 	/* 57340 */
+	0x0E,  0x00,  0x00,  0x00,  0x00,  0xA2,  0x00,  0x00,  0x3F,  0xE0,  0x08,  0x10,  0x08,  0x08,  0x08,  0x08, 	/* 57350 */
+	0x08,  0x10,  0x0F,  0xE0,  0x08,  0x10,  0x08,  0x08,  0x08,  0x04,  0x08,  0x04,  0x08,  0x08,  0x08,  0x30, 	/* 57360 */
+	0x3F,  0xC0,  0x00,  0x00,  0x00,  0x00,  0xA3,  0x00,  0x00,  0x03,  0xC8,  0x0C,  0x28,  0x18,  0x18,  0x10, 	/* 57370 */
+	0x08,  0x20,  0x08,  0x20,  0x00,  0x20,  0x00,  0x20,  0x00,  0x20,  0x00,  0x10,  0x08,  0x18,  0x18,  0x0C, 	/* 57380 */
+	0x30,  0x03,  0xC0,  0x00,  0x00,  0x00,  0x00,  0xA4,  0x00,  0x00,  0x3F,  0x80,  0x08,  0x60,  0x08,  0x10, 	/* 57390 */
+	0x08,  0x08,  0x08,  0x08,  0x08,  0x04,  0x08,  0x04,  0x08,  0x04,  0x08,  0x08,  0x08,  0x08,  0x08,  0x10, 	/* 573A0 */
+	0x08,  0x60,  0x3F,  0x80,  0x00,  0x00,  0x00,  0x00,  0xA5,  0x00,  0x00,  0x3F,  0xF8,  0x08,  0x08,  0x08, 	/* 573B0 */
+	0x04,  0x08,  0x00,  0x08,  0x00,  0x08,  0x40,  0x0F,  0xC0,  0x08,  0x40,  0x08,  0x00,  0x08,  0x00,  0x08, 	/* 573C0 */
+	0x04,  0x08,  0x08,  0x3F,  0xF8,  0x00,  0x00,  0x00,  0x00,  0xA6,  0x00,  0x00,  0x1F,  0xF8,  0x04,  0x08, 	/* 573D0 */
+	0x04,  0x04,  0x04,  0x00,  0x04,  0x00,  0x04,  0x20,  0x07,  0xE0,  0x04,  0x20,  0x04,  0x00,  0x04,  0x00, 	/* 573E0 */
+	0x04,  0x00,  0x04,  0x00,  0x1F,  0x00,  0x00,  0x00,  0x00,  0x00,  0xA7,  0x00,  0x00,  0x03,  0xC8,  0x0C, 	/* 573F0 */
+	0x38,  0x18,  0x08,  0x10,  0x08,  0x20,  0x00,  0x20,  0x00,  0x20,  0x00,  0x20,  0x3E,  0x20,  0x08,  0x10, 	/* 57400 */
+	0x08,  0x18,  0x18,  0x0C,  0x68,  0x03,  0x88,  0x00,  0x00,  0x00,  0x00,  0xA8,  0x00,  0x00,  0x38,  0x1C, 	/* 57410 */
+	0x10,  0x08,  0x10,  0x08,  0x10,  0x08,  0x10,  0x08,  0x10,  0x08,  0x1F,  0xF8,  0x10,  0x08,  0x10,  0x08, 	/* 57420 */
+	0x10,  0x08,  0x10,  0x08,  0x10,  0x08,  0x38,  0x1C,  0x00,  0x00,  0x00,  0x00,  0xA9,  0x00,  0x00,  0x03, 	/* 57430 */
+	0x80,  0x01,  0x00,  0x01,  0x00,  0x01,  0x00,  0x01,  0x00,  0x01,  0x00,  0x01,  0x00,  0x01,  0x00,  0x01, 	/* 57440 */
+	0x00,  0x01,  0x00,  0x01,  0x00,  0x01,  0x00,  0x03,  0x80,  0x00,  0x00,  0x00,  0x00,  0xAA,  0x00,  0x00, 	/* 57450 */
+	0x00,  0x70,  0x00,  0x20,  0x00,  0x20,  0x00,  0x20,  0x00,  0x20,  0x00,  0x20,  0x00,  0x20,  0x00,  0x20, 	/* 57460 */
+	0x00,  0x20,  0x00,  0x20,  0x08,  0x20,  0x04,  0x40,  0x03,  0x80,  0x00,  0x00,  0x00,  0x00,  0xAB,  0x00, 	/* 57470 */
+	0x00,  0x1C,  0x1C,  0x08,  0x10,  0x08,  0x20,  0x08,  0x40,  0x08,  0x80,  0x09,  0x00,  0x0B,  0x00,  0x0C, 	/* 57480 */
+	0x80,  0x08,  0x40,  0x08,  0x20,  0x08,  0x10,  0x08,  0x08,  0x1C,  0x0E,  0x00,  0x00,  0x00,  0x00,  0xAC, 	/* 57490 */
+	0x00,  0x00,  0x0E,  0x00,  0x04,  0x00,  0x04,  0x00,  0x04,  0x00,  0x04,  0x00,  0x04,  0x00,  0x04,  0x00, 	/* 574A0 */
+	0x04,  0x00,  0x04,  0x00,  0x04,  0x00,  0x04,  0x04,  0x04,  0x04,  0x0F,  0xFC,  0x00,  0x00,  0x00,  0x00, 	/* 574B0 */
+	0xAD,  0x00,  0x00,  0x60,  0x0C,  0x20,  0x08,  0x30,  0x18,  0x30,  0x18,  0x28,  0x28,  0x28,  0x28,  0x24, 	/* 574C0 */
+	0x48,  0x24,  0x48,  0x24,  0x48,  0x22,  0x88,  0x22,  0x88,  0x21,  0x08,  0x71,  0x1C,  0x00,  0x00,  0x00, 	/* 574D0 */
+	0x00,  0xAE,  0x00,  0x00,  0x38,  0x1C,  0x18,  0x08,  0x14,  0x08,  0x14,  0x08,  0x12,  0x08,  0x11,  0x08, 	/* 574E0 */
+	0x11,  0x08,  0x10,  0x88,  0x10,  0x48,  0x10,  0x48,  0x10,  0x28,  0x10,  0x18,  0x38,  0x08,  0x00,  0x00, 	/* 574F0 */
+	0x00,  0x00,  0xAF,  0x00,  0x00,  0x03,  0xC0,  0x0C,  0x30,  0x18,  0x18,  0x10,  0x08,  0x20,  0x04,  0x20, 	/* 57500 */
+	0x04,  0x20,  0x04,  0x20,  0x04,  0x20,  0x04,  0x10,  0x08,  0x18,  0x18,  0x0C,  0x30,  0x03,  0xC0,  0x00, 	/* 57510 */
+	0x00,  0x00,  0x00,  0xB0,  0x00,  0x00,  0x1F,  0xE0,  0x04,  0x18,  0x04,  0x04,  0x04,  0x04,  0x04,  0x04, 	/* 57520 */
+	0x04,  0x18,  0x07,  0xE0,  0x04,  0x00,  0x04,  0x00,  0x04,  0x00,  0x04,  0x00,  0x04,  0x00,  0x0E,  0x00, 	/* 57530 */
+	0x00,  0x00,  0x00,  0x00,  0xB1,  0x00,  0x00,  0x03,  0xC0,  0x0C,  0x30,  0x18,  0x18,  0x10,  0x08,  0x20, 	/* 57540 */
+	0x04,  0x20,  0x04,  0x20,  0x04,  0x20,  0x04,  0x20,  0x04,  0x11,  0x88,  0x1A,  0x50,  0x0C,  0x20,  0x03, 	/* 57550 */
+	0xD2,  0x00,  0x0C,  0x00,  0x00,  0xB2,  0x00,  0x00,  0x3F,  0xC0,  0x08,  0x30,  0x08,  0x08,  0x08,  0x08, 	/* 57560 */
+	0x08,  0x08,  0x08,  0x30,  0x0F,  0xC0,  0x08,  0x20,  0x08,  0x20,  0x08,  0x10,  0x08,  0x10,  0x08,  0x08, 	/* 57570 */
+	0x1C,  0x1C,  0x00,  0x00,  0x00,  0x00,  0xB3,  0x00,  0x00,  0x03,  0xD0,  0x04,  0x30,  0x08,  0x10,  0x08, 	/* 57580 */
+	0x00,  0x08,  0x00,  0x04,  0x00,  0x03,  0xC0,  0x00,  0x30,  0x00,  0x08,  0x10,  0x08,  0x18,  0x08,  0x14, 	/* 57590 */
+	0x10,  0x03,  0xE0,  0x00,  0x00,  0x00,  0x00,  0xB4,  0x00,  0x00,  0x3F,  0xF8,  0x21,  0x08,  0x41,  0x04, 	/* 575A0 */
+	0x01,  0x00,  0x01,  0x00,  0x01,  0x00,  0x01,  0x00,  0x01,  0x00,  0x01,  0x00,  0x01,  0x00,  0x01,  0x00, 	/* 575B0 */
+	0x01,  0x00,  0x03,  0x80,  0x00,  0x00,  0x00,  0x00,  0xB5,  0x00,  0x00,  0x38,  0x1C,  0x10,  0x08,  0x10, 	/* 575C0 */
+	0x08,  0x10,  0x08,  0x10,  0x08,  0x10,  0x08,  0x10,  0x08,  0x10,  0x08,  0x10,  0x08,  0x10,  0x08,  0x08, 	/* 575D0 */
+	0x10,  0x04,  0x20,  0x03,  0xC0,  0x00,  0x00,  0x00,  0x00,  0xB6,  0x00,  0x00,  0x38,  0x1C,  0x10,  0x08, 	/* 575E0 */
+	0x10,  0x08,  0x08,  0x10,  0x08,  0x10,  0x08,  0x20,  0x04,  0x20,  0x04,  0x40,  0x04,  0x40,  0x02,  0x80, 	/* 575F0 */
+	0x02,  0x80,  0x01,  0x00,  0x01,  0x00,  0x00,  0x00,  0x00,  0x00,  0xB7,  0x00,  0x00,  0x71,  0x8E,  0x21, 	/* 57600 */
+	0x84,  0x21,  0x84,  0x21,  0x84,  0x22,  0x44,  0x12,  0x48,  0x12,  0x48,  0x14,  0x28,  0x14,  0x28,  0x0C, 	/* 57610 */
+	0x28,  0x0C,  0x30,  0x08,  0x10,  0x08,  0x10,  0x00,  0x00,  0x00,  0x00,  0xB8,  0x00,  0x00,  0x38,  0x38, 	/* 57620 */
+	0x10,  0x10,  0x08,  0x20,  0x04,  0x40,  0x04,  0x40,  0x02,  0x80,  0x01,  0x00,  0x02,  0x80,  0x04,  0x40, 	/* 57630 */
+	0x04,  0x40,  0x08,  0x20,  0x10,  0x10,  0x38,  0x38,  0x00,  0x00,  0x00,  0x00,  0xB9,  0x00,  0x00,  0x38, 	/* 57640 */
+	0x38,  0x10,  0x10,  0x08,  0x20,  0x08,  0x20,  0x04,  0x40,  0x04,  0x40,  0x02,  0x80,  0x01,  0x00,  0x01, 	/* 57650 */
+	0x00,  0x01,  0x00,  0x01,  0x00,  0x01,  0x00,  0x03,  0x80,  0x00,  0x00,  0x00,  0x00,  0xBA,  0x00,  0x00, 	/* 57660 */
+	0x0F,  0xF8,  0x08,  0x10,  0x10,  0x20,  0x00,  0x40,  0x00,  0x40,  0x00,  0x80,  0x01,  0x00,  0x01,  0x00, 	/* 57670 */
+	0x02,  0x00,  0x04,  0x00,  0x04,  0x08,  0x08,  0x08,  0x1F,  0xF8,  0x00,  0x00,  0x00,  0x00,  0xBB,  0x00, 	/* 57680 */
+	0xF8,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x00, 	/* 57690 */
+	0x80,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x00,  0xF8,  0xBC, 	/* 576A0 */
+	0x80,  0x00,  0x40,  0x00,  0x20,  0x00,  0x10,  0x00,  0x08,  0x00,  0x04,  0x00,  0x02,  0x00,  0x01,  0x00, 	/* 576B0 */
+	0x00,  0x80,  0x00,  0x40,  0x00,  0x20,  0x00,  0x10,  0x00,  0x08,  0x00,  0x04,  0x00,  0x02,  0x00,  0x01, 	/* 576C0 */
+	0xBD,  0x1F,  0x00,  0x01,  0x00,  0x01,  0x00,  0x01,  0x00,  0x01,  0x00,  0x01,  0x00,  0x01,  0x00,  0x01, 	/* 576D0 */
+	0x00,  0x01,  0x00,  0x01,  0x00,  0x01,  0x00,  0x01,  0x00,  0x01,  0x00,  0x01,  0x00,  0x01,  0x00,  0x1F, 	/* 576E0 */
+	0x00,  0xBE,  0x01,  0x00,  0x02,  0x80,  0x04,  0x40,  0x08,  0x20,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00, 	/* 576F0 */
+	0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00, 	/* 57700 */
+	0x00,  0x00,  0xBF,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00, 	/* 57710 */
+	0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00, 	/* 57720 */
+	0x00,  0xFF,  0xFF,  0x80,  0x02,  0x00,  0x02,  0x00,  0x01,  0x00,  0x00,  0x80,  0x00,  0x00,  0x00,  0x00, 	/* 57730 */
+	0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00, 	/* 57740 */
+	0x00,  0x00,  0x00,  0x00,  0x81,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x03, 	/* 57750 */
+	0xC0,  0x04,  0x20,  0x00,  0x20,  0x03,  0xA0,  0x04,  0x60,  0x08,  0x20,  0x08,  0x60,  0x08,  0xA8,  0x07, 	/* 57760 */
+	0x18,  0x00,  0x00,  0x00,  0x00,  0x82,  0x00,  0x00,  0x0C,  0x00,  0x04,  0x00,  0x04,  0x00,  0x04,  0x00, 	/* 57770 */
+	0x04,  0x00,  0x05,  0xC0,  0x06,  0x20,  0x04,  0x10,  0x04,  0x10,  0x04,  0x10,  0x04,  0x10,  0x06,  0x20, 	/* 57780 */
+	0x05,  0xC0,  0x00,  0x00,  0x00,  0x00,  0x83,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00, 	/* 57790 */
+	0x00,  0x03,  0x80,  0x04,  0x40,  0x08,  0x20,  0x08,  0x00,  0x08,  0x00,  0x08,  0x00,  0x08,  0x20,  0x04, 	/* 577A0 */
+	0x40,  0x03,  0x80,  0x00,  0x00,  0x00,  0x00,  0x84,  0x00,  0x00,  0x00,  0x60,  0x00,  0x20,  0x00,  0x20, 	/* 577B0 */
+	0x00,  0x20,  0x00,  0x20,  0x03,  0xA0,  0x04,  0x60,  0x08,  0x20,  0x08,  0x20,  0x08,  0x20,  0x08,  0x20, 	/* 577C0 */
+	0x04,  0x60,  0x03,  0xB0,  0x00,  0x00,  0x00,  0x00,  0x85,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00, 	/* 577D0 */
+	0x00,  0x00,  0x00,  0x03,  0x80,  0x04,  0x40,  0x08,  0x20,  0x08,  0x20,  0x0F,  0xE0,  0x08,  0x00,  0x08, 	/* 577E0 */
+	0x00,  0x04,  0x20,  0x03,  0xC0,  0x00,  0x00,  0x00,  0x00,  0x86,  0x00,  0x00,  0x00,  0xF0,  0x01,  0x90, 	/* 577F0 */
+	0x01,  0x00,  0x01,  0x00,  0x0F,  0xF0,  0x01,  0x00,  0x01,  0x00,  0x01,  0x00,  0x01,  0x00,  0x01,  0x00, 	/* 57800 */
+	0x01,  0x00,  0x01,  0x00,  0x03,  0x80,  0x00,  0x00,  0x00,  0x00,  0x87,  0x00,  0x00,  0x00,  0x00,  0x00, 	/* 57810 */
+	0x00,  0x00,  0x00,  0x00,  0x00,  0x03,  0xD0,  0x06,  0x20,  0x04,  0x20,  0x04,  0x20,  0x03,  0xC0,  0x04, 	/* 57820 */
+	0x00,  0x07,  0xE0,  0x08,  0x18,  0x08,  0x08,  0x04,  0x18,  0x03,  0xE0,  0x88,  0x00,  0x00,  0x0C,  0x00, 	/* 57830 */
+	0x04,  0x00,  0x04,  0x00,  0x04,  0x00,  0x05,  0xC0,  0x06,  0x20,  0x04,  0x10,  0x04,  0x10,  0x04,  0x10, 	/* 57840 */
+	0x04,  0x10,  0x04,  0x10,  0x04,  0x10,  0x0E,  0x38,  0x00,  0x00,  0x00,  0x00,  0x89,  0x00,  0x00,  0x01, 	/* 57850 */
+	0x80,  0x01,  0x80,  0x00,  0x00,  0x00,  0x00,  0x01,  0x80,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x00, 	/* 57860 */
+	0x80,  0x00,  0x80,  0x00,  0x80,  0x00,  0x80,  0x01,  0xC0,  0x00,  0x00,  0x00,  0x00,  0x8A,  0x00,  0x00, 	/* 57870 */
+	0x00,  0xC0,  0x00,  0xC0,  0x00,  0x00,  0x00,  0x00,  0x00,  0xC0,  0x00,  0x40,  0x00,  0x40,  0x00,  0x40, 	/* 57880 */
+	0x00,  0x40,  0x00,  0x40,  0x00,  0x40,  0x00,  0x40,  0x00,  0x40,  0x08,  0x80,  0x07,  0x00,  0x8B,  0x00, 	/* 57890 */
+	0x00,  0x18,  0x00,  0x08,  0x00,  0x08,  0x00,  0x08,  0x00,  0x08,  0x70,  0x08,  0x40,  0x09,  0x80,  0x0E, 	/* 578A0 */
+	0x00,  0x09,  0x00,  0x08,  0x80,  0x08,  0x40,  0x08,  0x20,  0x1C,  0x78,  0x00,  0x00,  0x00,  0x00,  0x8C, 	/* 578B0 */
+	0x00,  0x00,  0x03,  0x00,  0x01,  0x00,  0x01,  0x00,  0x01,  0x00,  0x01,  0x00,  0x01,  0x00,  0x01,  0x00, 	/* 578C0 */
+	0x01,  0x00,  0x01,  0x00,  0x01,  0x00,  0x01,  0x00,  0x01,  0x00,  0x03,  0x80,  0x00,  0x00,  0x00,  0x00, 	/* 578D0 */
+	0x8D,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x17,  0x30,  0x09,  0xC8,  0x08, 	/* 578E0 */
+	0x88,  0x08,  0x88,  0x08,  0x88,  0x08,  0x88,  0x08,  0x88,  0x08,  0x88,  0x1D,  0xDC,  0x00,  0x00,  0x00, 	/* 578F0 */
+	0x00,  0x8E,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x0C,  0xE0,  0x05,  0x30, 	/* 57900 */
+	0x06,  0x10,  0x04,  0x10,  0x04,  0x10,  0x04,  0x10,  0x04,  0x10,  0x04,  0x10,  0x0E,  0x38,  0x00,  0x00, 	/* 57910 */
+	0x00,  0x00,  0x8F,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x03,  0xC0,  0x04, 	/* 57920 */
+	0x20,  0x08,  0x10,  0x08,  0x10,  0x08,  0x10,  0x08,  0x10,  0x08,  0x10,  0x04,  0x20,  0x03,  0xC0,  0x00, 	/* 57930 */
+	0x00,  0x00,  0x00,  0x90,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x0D,  0xC0, 	/* 57940 */
+	0x06,  0x20,  0x04,  0x10,  0x04,  0x10,  0x04,  0x10,  0x04,  0x10,  0x06,  0x20,  0x05,  0xC0,  0x04,  0x00, 	/* 57950 */
+	0x04,  0x00,  0x0E,  0x00,  0x91,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x03, 	/* 57960 */
+	0xB0,  0x04,  0x60,  0x08,  0x20,  0x08,  0x20,  0x08,  0x20,  0x08,  0x20,  0x04,  0x60,  0x03,  0xA0,  0x00, 	/* 57970 */
+	0x20,  0x00,  0x20,  0x00,  0x70,  0x92,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00, 	/* 57980 */
+	0x06,  0x70,  0x02,  0x90,  0x03,  0x00,  0x02,  0x00,  0x02,  0x00,  0x02,  0x00,  0x02,  0x00,  0x02,  0x00, 	/* 57990 */
+	0x07,  0x00,  0x00,  0x00,  0x00,  0x00,  0x93,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00, 	/* 579A0 */
+	0x00,  0x03,  0xD0,  0x04,  0x30,  0x04,  0x10,  0x03,  0x00,  0x00,  0xC0,  0x00,  0x20,  0x04,  0x10,  0x06, 	/* 579B0 */
+	0x10,  0x05,  0xE0,  0x00,  0x00,  0x00,  0x00,  0x94,  0x00,  0x00,  0x00,  0x00,  0x02,  0x00,  0x02,  0x00, 	/* 579C0 */
+	0x02,  0x00,  0x1F,  0xE0,  0x02,  0x00,  0x02,  0x00,  0x02,  0x00,  0x02,  0x00,  0x02,  0x00,  0x02,  0x00, 	/* 579D0 */
+	0x03,  0x40,  0x01,  0xC0,  0x00,  0x00,  0x00,  0x00,  0x95,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00, 	/* 579E0 */
+	0x00,  0x00,  0x00,  0x0C,  0x30,  0x04,  0x10,  0x04,  0x10,  0x04,  0x10,  0x04,  0x10,  0x04,  0x10,  0x04, 	/* 579F0 */
+	0x10,  0x02,  0x30,  0x01,  0xD8,  0x00,  0x00,  0x00,  0x00,  0x96,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00, 	/* 57A00 */
+	0x00,  0x00,  0x00,  0x00,  0x1C,  0x70,  0x08,  0x20,  0x08,  0x20,  0x04,  0x40,  0x04,  0x40,  0x02,  0x80, 	/* 57A10 */
+	0x02,  0x80,  0x01,  0x00,  0x01,  0x00,  0x00,  0x00,  0x00,  0x00,  0x97,  0x00,  0x00,  0x00,  0x00,  0x00, 	/* 57A20 */
+	0x00,  0x00,  0x00,  0x00,  0x00,  0x39,  0x1C,  0x11,  0x08,  0x11,  0x88,  0x11,  0x88,  0x0A,  0x50,  0x0A, 	/* 57A30 */
+	0x50,  0x0A,  0x50,  0x04,  0x20,  0x04,  0x20,  0x00,  0x00,  0x00,  0x00,  0x98,  0x00,  0x00,  0x00,  0x00, 	/* 57A40 */
+	0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x0C,  0x30,  0x04,  0x20,  0x02,  0x40,  0x01,  0x80,  0x01,  0x80, 	/* 57A50 */
+	0x02,  0x40,  0x04,  0x20,  0x08,  0x10,  0x1C,  0x38,  0x00,  0x00,  0x00,  0x00,  0x99,  0x00,  0x00,  0x00, 	/* 57A60 */
+	0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x0E,  0x38,  0x04,  0x10,  0x04,  0x10,  0x02,  0x20,  0x02, 	/* 57A70 */
+	0x20,  0x01,  0x40,  0x01,  0x40,  0x00,  0x80,  0x00,  0x80,  0x09,  0x00,  0x06,  0x00,  0x9A,  0x00,  0x00, 	/* 57A80 */
+	0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x0F,  0xF0,  0x08,  0x20,  0x00,  0x40,  0x00,  0x80, 	/* 57A90 */
+	0x00,  0x80,  0x01,  0x00,  0x02,  0x10,  0x04,  0x10,  0x0F,  0xF0,  0x00,  0x00,  0x00,  0x00,  0x9B,  0x00, 	/* 57AA0 */
+	0x08,  0x00,  0x10,  0x00,  0x20,  0x00,  0x20,  0x00,  0x20,  0x00,  0x20,  0x00,  0x20,  0x00,  0xC0,  0x00, 	/* 57AB0 */
+	0x20,  0x00,  0x20,  0x00,  0x20,  0x00,  0x20,  0x00,  0x20,  0x00,  0x20,  0x00,  0x10,  0x00,  0x08,  0x9C, 	/* 57AC0 */
+	0x01,  0x00,  0x01,  0x00,  0x01,  0x00,  0x01,  0x00,  0x01,  0x00,  0x01,  0x00,  0x01,  0x00,  0x01,  0x00, 	/* 57AD0 */
+	0x01,  0x00,  0x01,  0x00,  0x01,  0x00,  0x01,  0x00,  0x01,  0x00,  0x01,  0x00,  0x01,  0x00,  0x01,  0x00, 	/* 57AE0 */
+	0x9D,  0x10,  0x00,  0x08,  0x00,  0x04,  0x00,  0x04,  0x00,  0x04,  0x00,  0x04,  0x00,  0x04,  0x00,  0x03, 	/* 57AF0 */
+	0x00,  0x04,  0x00,  0x04,  0x00,  0x04,  0x00,  0x04,  0x00,  0x04,  0x00,  0x04,  0x00,  0x08,  0x00,  0x10, 	/* 57B00 */
+	0x00,  0x9E,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x1C,  0x00, 	/* 57B10 */
+	0x23,  0x02,  0x40,  0xC4,  0x00,  0x38,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00, 	/* 57B20 */
+	0x00,  0x00,  0xA0,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x20,  0x03, 	/* 57B30 */
+	0xC0,  0x04,  0x60,  0x08,  0x50,  0x08,  0x80,  0x08,  0x80,  0x09,  0x10,  0x05,  0x20,  0x03,  0xC0,  0x02, 	/* 57B40 */
+	0x00,  0x04,  0x00,  0xA1,  0x00,  0x00,  0x00,  0xE0,  0x01,  0x10,  0x01,  0x00,  0x01,  0x00,  0x01,  0x00, 	/* 57B50 */
+	0x01,  0x00,  0x01,  0x00,  0x3F,  0xF8,  0x01,  0x00,  0x01,  0x00,  0x1E,  0x00,  0x23,  0x02,  0x22,  0xC4, 	/* 57B60 */
+	0x1C,  0x38,  0x00,  0x00,  0xA2,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00, 	/* 57B70 */
+	0x00,  0x3F,  0xFC,  0x00,  0x04,  0x00,  0x04,  0x00,  0x04,  0x00,  0x04,  0x00,  0x00,  0x00,  0x00,  0x00, 	/* 57B80 */
+	0x00,  0x00,  0x00,  0x00,  0x00,  0xA3,  0xFF,  0xFF,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00, 	/* 57B90 */
+	0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00, 	/* 57BA0 */
+	0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0xA5,  0x00,  0x00,  0x1C,  0x1C,  0x08,  0x08,  0x04,  0x10,  0x04, 	/* 57BB0 */
+	0x10,  0x3F,  0xFE,  0x02,  0x20,  0x01,  0x40,  0x00,  0x80,  0x3F,  0xFE,  0x00,  0x80,  0x00,  0x80,  0x00, 	/* 57BC0 */
+	0x80,  0x00,  0x80,  0x01,  0xC0,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00  	/* 57BD0 */
+};
+
+#endif
+
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/ui/stfont_disp/Makefile.config
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/ui/stfont_disp/Makefile.config	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/ui/stfont_disp/Makefile.config	(revision 457)
@@ -0,0 +1,56 @@
+#
+#   TOPPERS/ASP Kernel
+#       Toyohashi Open Platform for Embedded Real-Time Systems/
+#       Advanced Standard Profile Kernel
+#
+#   Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
+#                               Toyohashi Univ. of Technology, JAPAN
+#   Copyright (C) 2003-2008 by Ryosuke Takeuchi
+#                Platform Development Center RICOH COMPANY,LTD. JAPAN
+#   Copyright (C) 2017-2018 by TOPPERS PROJECT Educational Working Group.
+#
+#   上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+#   によって公表されている GNU General Public License の Version 2 に記
+#   述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+#   を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+#   利用と呼ぶ）することを無償で許諾する．
+#   (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+#       権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+#       スコード中に含まれていること．
+#   (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+#       用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+#       者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+#       の無保証規定を掲載すること．
+#   (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+#       用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+#       と．
+#     (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+#         作権表示，この利用条件および下記の無保証規定を掲載すること．
+#     (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+#         報告すること．
+#   (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+#       害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+#
+#   本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+#   よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+#   含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+#   接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+#
+#  @(#) $Id$
+#
+ 
+#
+#  Makefile のプロセッサ依存 (stfont_disp用)
+#
+
+#
+#  コンパイルオプション
+#
+INCLUDES := $(INCLUDES) -I$(SRCDIR)/ui/stfont_disp -I$(SRCDIR)/stmcube/Utilities/Fonts
+
+#
+#  プログラムに関する定義
+#
+SYSSVC_DIR := $(SYSSVC_DIR):$(SRCDIR)/ui/stfont_disp
+SYSSVC_COBJS := $(SYSSVC_COBJS) glcd_disp.o
+
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/ui/stfont_disp/glcd_disp.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/ui/stfont_disp/glcd_disp.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/ui/stfont_disp/glcd_disp.c	(revision 457)
@@ -0,0 +1,212 @@
+/*
+ *  TOPPERS/ASP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Advanced Standard Profile Kernel
+ * 
+ *  Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
+ *                              Toyohashi Univ. of Technology, JAPAN
+ *  Copyright (C) 2004-2012 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ *  Copyright (C) 2015-2019 by TOPPERS PROJECT Educational Working Group.
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  $Id$
+ */
+
+/* 
+ *  GRAPHIC-LCDテキスト表示プログラムの本体
+ */
+
+#include <kernel.h>
+#include <t_syslog.h>
+#include <t_stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <target_syssvc.h>
+#include "syssvc/serial.h"
+#include "syssvc/syslog.h"
+#include "glcd_disp.h"
+#include "font24.c"
+#include "font20.c"
+#include "font16.c"
+#include "font12.c"
+#include "font8.c"
+
+/*
+ *  文字描画
+ *  param1  pDrawProp: Pointer to Draw Prop
+ *  param2  x0: 文字描画 X座標始点
+ *  param3  y0: 文字描画 Y座標始点
+ *  param4  c:  文字イメージへのポインタ
+ */
+#ifndef MAX_FONT_IMAGE
+static void
+DrawChar(LCD_DrawProp_t *pDrawProp, uint16_t x0, uint16_t y0, const uint8_t *c)
+{
+	LCD_Handler_t *hlcd = pDrawProp->hlcd;
+	sFONT    *pFont = pDrawProp->pFont;
+	uint32_t h, w, stride;
+	uint8_t  *pchar;
+
+	stride = ((pFont->Width + 7)/8);
+	for(h = 0 ; h < pFont->Height ; h++){
+		pchar = ((uint8_t *)c + stride * h);
+		for(w = 0; w < pFont->Width ; w++){
+			if(pchar[w/8] & (1 << (7 - (w % 8)))){
+				lcd_drawPixel(hlcd, (x0 + w), (y0 + h), pDrawProp->TextColor);
+			}
+			else{
+				lcd_drawPixel(hlcd, (x0 + w), (y0 + h), pDrawProp->BackColor);
+			}
+		}
+	}
+}
+#else
+static void
+DrawChar(LCD_DrawProp_t *pDrawProp, uint16_t x0, uint16_t y0, const uint8_t *c)
+{
+	LCD_Handler_t *hlcd = pDrawProp->hlcd;
+	sFONT    *pFont = pDrawProp->pFont;
+	uint32_t h, w, stride;
+	const uint8_t  *pchar;
+	color_t  image[MAX_FONT_IMAGE];
+
+	stride = ((pFont->Width + 7)/8);
+	for(h = 0 ; h < pFont->Height ; h++){
+		pchar = ((uint8_t *)c + stride * h);
+		for(w = 0; w < pFont->Width ; w++){
+			if(pchar[w/8] & (1 << (7 - (w % 8)))){
+				image[w] = pDrawProp->TextColor;
+			}
+			else{
+				image[w] = pDrawProp->BackColor;
+			}
+		}
+		lcd_drawImageHLine(hlcd, x0, (y0 + h), pFont->Width, image);
+	}
+}
+#endif
+
+/*
+ *  文字列表示ラインクリア
+ *  param1  pDrawProp: Pointer to Draw Prop
+ *  param2  ライン番号
+ */
+void
+lcd_clearStringLine(LCD_DrawProp_t *pDrawProp, uint16_t Line)
+{
+	sFONT    *pFont = pDrawProp->pFont;
+	lcd_fillRect(pDrawProp->hlcd, 0, (Line * pFont->Height), pDrawProp->hlcd->_width, pFont->Height, pDrawProp->BackColor);
+}
+
+/*
+ *  一文字描画
+ *  param1  pDrawProp: Pointer to Draw Prop
+ *  param2  x0: 文字描画 X座標始点
+ *  param3  y0: 文字描画 Y座標始点
+ *  param4  描画アスキーコード(範囲は0x20から0x7Eまで)
+ */
+void
+lcd_DisplayChar(LCD_DrawProp_t *pDrawProp, uint16_t x0, uint16_t y0, uint8_t Ascii)
+{
+	sFONT    *pFont = pDrawProp->pFont;
+	DrawChar(pDrawProp, x0, y0, &pFont->table[(Ascii-' ') * pFont->Height * ((pFont->Width + 7) / 8)]);
+}
+
+/*
+ *  文字列描画
+ *  param1  pDrawProp: Pointer to Draw Prop
+ *  param1  x0: 文字列描画 X座標始点
+ *  param2  y0: 文字列描画 Y座標始点
+ *  param3  Text: 描画文字列へのポインタ
+ */
+void
+lcd_DisplayStringAt(LCD_DrawProp_t *pDrawProp, uint16_t x0, uint16_t y0, uint8_t *Text, Line_ModeTypdef Mode)
+{
+	sFONT    *pFont = pDrawProp->pFont;
+	uint16_t ref_column = 1, i = 0;
+	uint32_t size = 0, xsize = 0; 
+	uint8_t  *ptr = (uint8_t *)Text;
+
+	/* Get the text size */
+	while (*ptr++) size++;
+
+	/* Characters number per line */
+	xsize = (pDrawProp->hlcd->_width / pFont->Width);
+
+	switch(Mode){
+	case CENTER_MODE:
+		ref_column = x0 + ((xsize - size) * pFont->Width) / 2;
+		break;
+	case LEFT_MODE:
+		ref_column = x0;
+		break;
+	case RIGHT_MODE:
+		ref_column =  - x0 + ((xsize - size) * pFont->Width);
+		break;
+	default:
+		ref_column = x0;
+		break;
+	}
+
+	/*
+	 *  開始カラム位置をスクリーン内に収める
+	 */
+	if((ref_column < 1) || (ref_column >= 0x8000)){
+		ref_column = 1;
+	}
+
+	/*
+	 *  一文字描画を使って文字列を描画する
+	 */
+	while((*Text != 0) & (((pDrawProp->hlcd->_width - (i*pFont->Width)) & 0xFFFF) >= pFont->Width)){
+		lcd_DisplayChar(pDrawProp, ref_column, y0, *Text);
+		ref_column += pFont->Width;		/* 次のカラムに移動 */
+		Text++;							/* 次の文字に移動 */
+		i++;
+	}
+}
+
+/*
+ *  文字列描画
+ *  param1  pDrawProp: Pointer to Draw Prop
+ *  param2  x0: 文字列描画 X座標始点
+ *  param3  y0: 文字列描画 Y座標始点
+ *  param4  Text: 描画文字列へのポインタ
+ */
+void
+lcd_DisplayStringAtLine(LCD_DrawProp_t *pDrawProp, uint16_t Line, uint8_t *ptr)
+{
+	sFONT    *pFont = pDrawProp->pFont;
+
+	lcd_DisplayStringAt(pDrawProp, 0, Line * pFont->Height, ptr, LEFT_MODE);
+}
+
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/ui/stfont_disp/glcd_disp.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/ui/stfont_disp/glcd_disp.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/ui/stfont_disp/glcd_disp.h	(revision 457)
@@ -0,0 +1,114 @@
+/*
+ *  TOPPERS BASE PLATFORM MIDDLEWARE
+ * 
+ *  Copyright (C) 2017-2018 by TOPPERS PROJECT
+ *                             Educational Working Group.
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+#ifndef _GLCD_DISP_H_
+#define _GLCD_DISP_H_
+
+#ifdef __cplusplus
+ extern "C" {
+#endif 
+
+#include "glcd_core.h"
+#include "fonts.h"
+
+/*
+ *  テキスト表示ラインモード定義
+ */
+typedef enum
+{
+	CENTER_MODE = 0x01,	/* Center mode */
+	RIGHT_MODE,			/* Right mode  */
+	LEFT_MODE			/* Left mode   */
+}Line_ModeTypdef;
+
+
+/*
+ *  BSP表示関数変換定義
+ */
+#define BSP_LCD_Init()                  lcd_init(pHLCD, LCD_ORIENTATION_LANDSCAPE)
+#define BSP_LCD_DeInit()                lcd_deinit(pHLCD)
+#define BSP_LCD_LayerDefaultInit(a, b)  lcd_layerdefaultinit(pHLCD, pDRAWPROP, (a), (b))
+#define BSP_LCD_SetLayerWindow(i, x, y, w, h) lcd_setAddrWindow(pHLCD, (i), (x), (y), (w), (h))
+
+#define BSP_LCD_Clear(c)                lcd_clear(pHLCD, (c))
+#define BSP_LCD_ReadPixel(x, y)         lcd_readPixel(pHLCD, (x), (y))
+#define BSP_LCD_DrawPixel(x, y, c)      lcd_drawPixel(pHLCD, (x), (y), (c))
+#define BSP_LCD_DrawHLine(x, y, w)      lcd_drawFastHLine(pHLCD, (x), (y), (w), pDRAWPROP->TextColor)
+#define BSP_LCD_DrawVLine(x, y, h)      lcd_drawFastVLine(pHLCD, (x), (y), (h), pDRAWPROP->TextColor)
+#define BSP_LCD_DrawBitmap(x, y, p)     lcd_drawBitmap(pHLCD, (x), (y), (p))
+#define BSP_LCD_DrawRGBImage(x, y, xs, ys, p) lcd_drawRGBImage(pHLCD, (x), (y), (xs), (xy), (p))
+#define BSP_LCD_DisplayOn()             lcd_displayOn(pHLCD)
+#define BSP_LCD_DisplayOff()            lcd_displayOff(pHLCD)
+#define BSP_LCD_FillRect(x, y, w,h)     lcd_fillRect(pHLCD, (x), (y), (w), (h), pDRAWPROP->TextColor)
+
+#define BSP_LCD_DrawLine(x, y, x2, y2)  lcd_drawLine(pDRAWPROP, (x), (y), (x2), (y2))
+#define BSP_LCD_DrawRect(x, y, w, h)    lcd_drawRect(pDRAWPROP, (x), (y), (w), (h))
+#define BSP_LCD_DrawCircle(x, y, r)     lcd_DrawCircle(pDRAWPROP, (x), (y), (r))
+#define BSP_LCD_DrawEllipse(x, y, xr, yr) lcd_DrawEllipse(pDRAWPROP, (x), (y), (xr), (yr))
+#define BSP_LCD_DrawPolygon(a, b)       lcd_drawPolygon(pDRAWPROP, (a), (b))
+#define BSP_LCD_FillCircle(x, y, r)     lcd_fillCircle(pDRAWPROP, (x), (y), (r))
+#define BSP_LCD_FillEllipse(x, y, xr, yr) lcd_fillEllipse(pDRAWPROP, (x), (y), (xr), (yr))
+#define BSP_LCD_FillPolygon(a, b)       lcd_fillPolygon(pDRAWPROP, (a), (b))
+
+#define BSP_LCD_ClearStringLine(l)      lcd_clearStringLine(pDRAWPROP, (l))
+#define BSP_LCD_DisplayChar(x, y, a)    lcd_DisplayChar(pDRAWPROP, (x), (y), (a))
+#define BSP_LCD_DisplayStringAt(x, y, t, m) lcd_DisplayStringAt(pDRAWPROP, (x), (y), (t), (m))
+#define BSP_LCD_DisplayStringAtLine(l, p) lcd_DisplayStringAtLine(pDRAWPROP, (l), (p))
+
+#define BSP_LCD_SelectLayer(a)          pHLCD->layer = (a)
+#define BSP_LCD_GetXSize()              pHLCD->_width
+#define BSP_LCD_GetYSize()              pHLCD->_height
+#define BSP_LCD_SetTextColor(c)         pDRAWPROP->TextColor = (c)
+#define BSP_LCD_GetTextColor()          pDRAWPROP->TextColor
+#define BSP_LCD_SetBackColor(c)         pDRAWPROP->BackColor = (c)
+#define BSP_LCD_GetBackColor()          pDRAWPROP->BackColor
+#define BSP_LCD_SetFont(f)              pDRAWPROP->pFont = (f)
+#define BSP_LCD_GetFont()               ((sFONT *)pDRAWPROP->pFont)
+
+
+extern void lcd_clearStringLine(LCD_DrawProp_t *pDrawProp, uint16_t Line);
+extern void lcd_DisplayChar(LCD_DrawProp_t *pDrawProp, uint16_t Xpos, uint16_t Ypos, uint8_t Ascii);
+extern void lcd_DisplayStringAt(LCD_DrawProp_t *pDrawProp, uint16_t Xpos, uint16_t Ypos, uint8_t *Text, Line_ModeTypdef Mode);
+extern void lcd_DisplayStringAtLine(LCD_DrawProp_t *pDrawProp, uint16_t Line, uint8_t *ptr);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _GLCD_DISP_H_ */
+
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/usb/Makefile.config
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/usb/Makefile.config	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/usb/Makefile.config	(revision 457)
@@ -0,0 +1,77 @@
+#
+#   TOPPERS/ASP/FMP Kernel
+#       Toyohashi Open Platform for Embedded Real-Time Systems/
+#       Advanced Standard Profile Kernel
+#
+#   Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
+#                               Toyohashi Univ. of Technology, JAPAN
+#   Copyright (C) 2003-2008 by Ryosuke Takeuchi
+#                Platform Development Center RICOH COMPANY,LTD. JAPAN
+#   Copyright (C) 2015-2018 by TOPPERS PROJECT Educational Working Group.
+#
+#   上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+#   によって公表されている GNU General Public License の Version 2 に記
+#   述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+#   を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+#   利用と呼ぶ）することを無償で許諾する．
+#   (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+#       権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+#       スコード中に含まれていること．
+#   (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+#       用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+#       者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+#       の無保証規定を掲載すること．
+#   (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+#       用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+#       と．
+#     (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+#         作権表示，この利用条件および下記の無保証規定を掲載すること．
+#     (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+#         報告すること．
+#   (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+#       害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+#
+#   本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+#   よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+#   含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+#   接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+#
+#  @(#) $Id$
+#
+ 
+#
+#  Makefile のプロセッサ依存 (usb用)
+#
+
+ifeq ($(USB_OTG_MODE),)
+USB_OTG_MODE = USB_OTG_MODE_DEVICE
+endif
+
+#
+#  コンパイルオプション
+#
+INCLUDES := $(INCLUDES) -I$(SRCDIR)/usb/host/HID \
+		-I$(SRCDIR)/usb/host \
+		-I$(SRCDIR)/usb/host/MSC \
+		-I$(SRCDIR)/usb/host/SERIAL \
+		-I$(SRCDIR)/usb/host/PRT \
+		-I$(SRCDIR)/usb/host/BLUETOOTH \
+		-I$(SRCDIR)/usb/host/HUB \
+		-I$(SRCDIR)/usb/device \
+		-I$(SRCDIR)/usb 
+
+CDEFS := $(CDEFS) -DUSB_OTG_MODE=$(USB_OTG_MODE)
+
+#
+#  USBミドルウェアに関する定義
+#
+SYSSVC_DIR := $(SYSSVC_DIR):\
+		$(SRCDIR)/usb/host:$(SRCDIR)/usb/host/HID:$(SRCDIR)/usb/host/MSC:$(SRCDIR)/usb/host/SERIAL:$(SRCDIR)/usb/host/PRT:\
+		$(SRCDIR)/usb/host/BLUETOOTH:$(SRCDIR)/usb/host/HUB:\
+		$(SRCDIR)/usb/device:$(SRCDIR)/usb/device/HID:$(SRCDIR)/usb/device/SERIAL:$(SRCDIR)/usb
+ifneq ($(USB_OTG_MODE),USB_OTG_MODE_DEVICE)
+SYSSVC_COBJS := $(SYSSVC_COBJS) tusb_rtos.o tusbh_base.o tusbh_request.o 
+endif
+ifneq ($(USB_OTG_MODE),USB_OTG_MODE_HOST)
+SYSSVC_COBJS := $(SYSSVC_COBJS) tusbd_base.o tusbd_request.o 
+endif
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/usb/device/HID/tusbd_device.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/usb/device/HID/tusbd_device.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/usb/device/HID/tusbd_device.h	(revision 457)
@@ -0,0 +1,69 @@
+/*
+ *  TOPPERS BASE PLATFORM MIDDLEWARE
+ * 
+ *  Copyright (C) 2017-2017 by TOPPERS PROJECT
+ *                             Educational Working Group.
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+/*
+ *  TOPPERS USB DEVICE CLASS CONFIGURATION インクルードファイル
+ */
+
+#ifndef _TUSBD_DEVICE_H_
+#define _TUSBD_DEVICE_H_
+
+#define tusbdClassInit                tusbdHidInit
+#define tusbdClassDeInit              tusbdHidDeInit
+#define tusbdClassSuspend(a)
+#define tusbdClassResume(a)
+#define tusbdClassEp0RxReady(a)
+#define tusbdClassEp0TxSent(a)
+#define tusbdClassSetup               tusbdHidSetup
+#define tusbdClassDataIn              tusbdHidDataIn
+#define tusbdClassDataOut(a, b)
+#define tusbdClassInIncomlete(a, b)
+#define tusbdClassOutIncomlete(a, b)
+#define USBD_HID_SendReport           tusbdHidSendData
+
+#define TUSBD_HS_CONFIG_DESCRIPTOR    configurationHidDescriptor
+#define TUSBD_HS_CONFIG_DESC_LENGTH   TOTAL_HID_DESCRIPTOR_LENGTH
+#define TUSBD_FS_CONFIG_DESCRIPTOR    configurationHidDescriptor
+#define TUSBD_FS_CONFIG_DESC_LENGTH   TOTAL_HID_DESCRIPTOR_LENGTH
+#define TUSBD_OTR_CONFIG_DESCRIPTOR   configurationHidOtherDescriptor
+#define TUSBD_OTR_CONFIG_DESC_LENGTH  TOTAL_HID_DESCRIPTOR_LENGTH
+
+#include "tusbd_hid.h"
+
+
+#endif /* _TUSBD_DEVICE_H_ */
+
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/usb/device/HID/tusbd_hid.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/usb/device/HID/tusbd_hid.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/usb/device/HID/tusbd_hid.c	(revision 457)
@@ -0,0 +1,375 @@
+/*
+ *  TOPPERS BASE PLATFORM MIDDLEWARE
+ * 
+ *  Copyright (C) 2017-2017 by TOPPERS PROJECT
+ *                             Educational Working Group.
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+/*
+ *  USB Device HID CLASS部
+ */
+
+#include "tusbd_hid.h"
+
+
+
+#define HID_VERSION_1_11    (0x0111)
+
+#define HID_INTERVAL_TIME    10
+
+#ifndef HID_INTERFCAE_PROTOCOL
+#define HID_INTERFCAE_PROTOCOL    0x02		/* 2:mouse 1:keyboard */
+#endif
+
+
+
+/*
+ *  REPORT DESCRIPTOR
+ */
+static uint8_t reportDescriptor[]  __attribute__ ((aligned (USB_DATA_ALIGN))) = {
+
+	USAGE_PAGE(1),   0x01,
+	USAGE(1),   0x02,
+
+	COLLECTION(1),   0x01,
+	USAGE(1),   0x01,
+
+	COLLECTION(1),   0x00,
+	USAGE_PAGE(1),   0x09,
+	USAGE_MINIMUM(1),   0x01,
+	USAGE_MAXIMUM(1),   0x03,
+	LOGICAL_MINIMUM(1),   0x00,
+	LOGICAL_MAXIMUM(1),   0x01,
+	REPORT_COUNT(1),   0x03,
+	REPORT_SIZE(1),   0x01,
+	INPUT(1),   0x02,
+	REPORT_COUNT(1),   0x01,
+	REPORT_SIZE(1),   0x05,
+	INPUT(1),   0x01,
+	USAGE_PAGE(1),   0x01,
+	USAGE(1),   0x30,
+	USAGE(1),   0x31,
+	USAGE(1),   0x38,
+
+	LOGICAL_MINIMUM(1),   0x81,
+	LOGICAL_MAXIMUM(1),   0x7F,
+	REPORT_SIZE(1),  0x08,
+	REPORT_COUNT(1), 0x03,
+
+	INPUT(1),   0x06,
+	END_COLLECTION(0),
+
+	USAGE(1), 0x3c,
+	USAGE_PAGE(1), 0xff,
+	USAGE(1), 0x01,
+	LOGICAL_MINIMUM(1), 0x00,
+	LOGICAL_MAXIMUM(1), 0x01,
+	REPORT_SIZE(1), 0x01,
+	REPORT_COUNT(1), 0x02,
+	FEATURE(1), 0x22,
+	REPORT_SIZE(1), 0x06,
+	REPORT_COUNT(1), 0x01,
+	FEATURE(1), 0x01,
+	END_COLLECTION(0)
+};
+
+/*
+ *  USB HID DEVICE CONFIGURATION DESCRIPTOR
+ */
+uint8_t configurationHidDescriptor[TOTAL_HID_DESCRIPTOR_LENGTH]  __attribute__ ((aligned (USB_DATA_ALIGN))) =
+{
+	CONFIGURATION_DESCRIPTOR_LENGTH,    // bLength
+	CONFIGURATION_DESCRIPTOR,           // bDescriptorType
+	(TOTAL_HID_DESCRIPTOR_LENGTH & 0xFF),   // wTotalLength (LSB)
+	(TOTAL_HID_DESCRIPTOR_LENGTH >> 8),     // wTotalLength (MSB)
+ 	0x01,                               // bNumInterfaces
+	0x01,                               // bConfigurationValue
+	0x00,                               // iConfiguration
+	C_RESERVED | C_SELF_POWERED | C_REMOTE_WAKEUP,	// bmAttributes
+	C_POWER(100),                       // bMaxPower
+
+	INTERFACE_DESCRIPTOR_LENGTH,        // bLength
+	INTERFACE_DESCRIPTOR,               // bDescriptorType
+	0x00,                               // bInterfaceNumber
+	0x00,                               // bAlternateSetting
+	0x01,                               // bNumEndpoints
+	HID_CLASS,                          // bInterfaceClass
+	0x01,                               // bInterfaceSubClass : 1=BOOT, 0=no boot
+	HID_INTERFCAE_PROTOCOL,             // bInterfaceProtocol
+	0x00,                               // iInterface
+
+	HID_DESCRIPTOR_LENGTH,              // bLength
+	HID_DESCRIPTOR,                     // bDescriptorType
+	(HID_VERSION_1_11 & 0xFF),          // bcdHID (LSB)
+	(HID_VERSION_1_11 >> 8),            // bcdHID (MSB)
+	0x00,                               // bCountryCode
+	0x01,                               // bNumDescriptors
+	0x22,                               // bDescriptorType
+	(sizeof(reportDescriptor) & 0xFF),  // wDescriptorLength (LSB)
+	(sizeof(reportDescriptor) >> 8),    // wDescriptorLength (MSB)
+
+	ENDPOINT_DESCRIPTOR_LENGTH,         // bLength
+	ENDPOINT_DESCRIPTOR,                // bDescriptorType
+	EPIN_ADDR,                          // bEndpointAddress
+	USB_EP_TYPE_INTR,                   // bmAttributes
+	(EPIN_SIZE & 0xFF),                 // wMaxPacketSize (LSB)
+	(EPIN_SIZE >> 8),                   // wMaxPacketSize (MSB)
+	HID_INTERVAL_TIME                   // bInterval (milliseconds)
+};
+
+/*
+ *  USB HID DEVICE OTHER CONFIGURATION DESCRIPTOR
+ */
+uint8_t configurationHidOtherDescriptor[TOTAL_HID_DESCRIPTOR_LENGTH]  __attribute__ ((aligned (USB_DATA_ALIGN))) =
+{
+	CONFIGURATION_DESCRIPTOR_LENGTH,    // bLength
+	OTHER_SPEED_CONFIGURATION_DESC,     // bDescriptorType
+	(TOTAL_HID_DESCRIPTOR_LENGTH & 0xFF),   // wTotalLength (LSB)
+	(TOTAL_HID_DESCRIPTOR_LENGTH >> 8),     // wTotalLength (MSB)
+ 	0x01,                               // bNumInterfaces
+	0x01,                               // bConfigurationValue
+	0x00,                               // iConfiguration
+	C_RESERVED | C_SELF_POWERED | C_REMOTE_WAKEUP,	// bmAttributes
+	C_POWER(100),                       // bMaxPower
+
+	INTERFACE_DESCRIPTOR_LENGTH,        // bLength
+	INTERFACE_DESCRIPTOR,               // bDescriptorType
+	0x00,                               // bInterfaceNumber
+	0x00,                               // bAlternateSetting
+	0x01,                               // bNumEndpoints
+	HID_CLASS,                          // bInterfaceClass
+	0x01,                               // bInterfaceSubClass : 1=BOOT, 0=no boot*/
+	0x02,                               // bInterfaceProtocol : 0=none, 1=keyboard, 2=mouse*/
+	0x00,                               // iInterface
+
+	HID_DESCRIPTOR_LENGTH,              // bLength
+	HID_DESCRIPTOR,                     // bDescriptorType
+	(HID_VERSION_1_11 & 0xFF),          // bcdHID (LSB)
+	(HID_VERSION_1_11 >> 8),            // bcdHID (MSB)
+	0x00,                               // bCountryCode
+	0x01,                               // bNumDescriptors
+	0x22,                               // bDescriptorType
+	(sizeof(reportDescriptor) & 0xFF),  // wDescriptorLength (LSB)
+	(sizeof(reportDescriptor) >> 8),    // wDescriptorLength (MSB)
+
+	ENDPOINT_DESCRIPTOR_LENGTH,         // bLength
+	ENDPOINT_DESCRIPTOR,                // bDescriptorType
+	EPIN_ADDR,                          // bEndpointAddress
+	USB_EP_TYPE_INTR,                   // bmAttributes
+	(EPIN_SIZE & 0xFF),                 // wMaxPacketSize (LSB)
+	(EPIN_SIZE >> 8),                   // wMaxPacketSize (MSB)
+	HID_INTERVAL_TIME                   // bInterval (milliseconds)
+};
+
+static TUSBD_HID_Handle_t HID_CLASS_DATA __attribute__ ((aligned (USB_DATA_ALIGN)));
+
+
+/*
+ *  USB DEVICE HID初期化
+ *  parameter1 pdevice:  USB DEVICEハンドラ
+ *  parameter2 idx:      Configuration index
+ *  return     TUSBD_ERCODE
+ */
+TUSBD_ERCODE
+tusbdHidInit(TUSBD_Handle_t *pdevice, uint8_t idx)
+{
+	tusbdDriverOpenEp(pdevice, EPIN_ADDR, USB_EP_TYPE_INTR, EPIN_SIZE);
+	memset(&HID_CLASS_DATA, 0, sizeof(TUSBD_HID_Handle_t));
+	HID_CLASS_DATA.datastate = HID_DATA_IDLE;
+
+	pdevice->pClassData = &HID_CLASS_DATA;
+	return TUSBD_E_OK;
+}
+
+/*
+ *  USB DEVICE HIDクラス終了
+ *  parameter1 pdevice:  USB DEVICEハンドラ
+ *  parameter2 idx:      Configuration index
+ *  return     TUSBD_ERCODE
+ */
+TUSBD_ERCODE
+tusbdHidDeInit(TUSBD_Handle_t *pdevice, uint8_t idx)
+{
+	tusbdDriverCloseEp(pdevice, EPIN_ADDR);
+	pdevice->pClassData = NULL;
+	return TUSBD_E_OK;
+}
+
+/*
+ *  USB DEVICE HIDクラスセットアップ
+ *  parameter1 pdevice:  USB DEVICEハンドラ
+ *  parameter2 req:      usb control requests
+ *  return     TUSBD_ERCODE
+ */
+void
+tusbdHidSetup(TUSBD_Handle_t *pdevice, UsbSetupRequest *req)
+{
+	TUSBD_HID_Handle_t *hhid = (TUSBD_HID_Handle_t*) pdevice->pClassData;
+	uint16_t len = 0;
+	volatile uint8_t  *pbuf = NULL;
+	uint8_t  *p;
+	uint32_t i;
+
+	switch (req->bmRequest & USB_REQUEST_TYPE_MASK){
+	case USB_REQUEST_TYPE_STANDARD:
+		switch (req->bRequest){
+		case GET_DESCRIPTOR:
+			if((req->wValue >> 8) == HID_REPORT_DESCRIPTOR){
+				len = sizeof(reportDescriptor);
+				pbuf = reportDescriptor;
+			}
+			else if((req->wValue >> 8) == HID_DESCRIPTOR){
+				pbuf = tusbdFindDescriptor(pdevice, HID_DESCRIPTOR);
+				if(pbuf != NULL){
+					p   = pdevice->devData;
+					len = pbuf[0];
+					for(i = 0 ; i < len && i < 32 ; i++)
+						*p++ = *pbuf++;
+					pbuf = pdevice->devData;
+				}
+			}
+			if(len > 0){
+				if(len > req->wLength)
+					len = req->wLength;
+				tusbdControlSendData(pdevice, (uint8_t *)pbuf, len);
+			}
+			break;
+		case GET_INTERFACE:
+			pdevice->devData[0] = hhid->AltSetting;
+			tusbdControlSendData(pdevice, (uint8_t *)pdevice->devData, 1);
+			break;
+		case SET_INTERFACE:
+			hhid->AltSetting = (uint8_t)(req->wValue);
+			break;
+		}
+		break;
+	case USB_REQUEST_TYPE_CLASS:
+		switch (req->bRequest){
+		case USB_SET_PROTOCOL:
+			hhid->Protocol = (uint8_t)(req->wValue);
+			break;
+		case USB_GET_PROTOCOL:
+			pdevice->devData[0] = hhid->Protocol;
+			tusbdControlSendData(pdevice, (uint8_t *)pdevice->devData, 1);
+			break;
+		case USB_SET_IDLE:
+			hhid->IdleState = (uint8_t)(req->wValue >> 8);
+			break;
+		case USB_GET_IDLE:
+			pdevice->devData[0] = hhid->IdleState;
+			tusbdControlSendData(pdevice, (uint8_t *)pdevice->devData, 1);
+			break;
+		case USB_GET_REPORT:
+			len = sizeof(reportDescriptor);
+			pbuf = reportDescriptor;
+			if(len > req->wLength)
+				len = req->wLength;
+			tusbdControlSendData(pdevice, (uint8_t *)pbuf, len);
+			break;
+		case USB_SET_REPORT:
+			if(hhid->devReportLength > 0){
+				hhid->devReport[0] = req->wValue & 0xff;
+				len = hhid->devReportLength;
+				if(len > (req->wLength + 1))
+					len = req->wLength + 1;
+				p = pdevice->devData;
+				for(i = 0 ; i < len && i < 32 ; i++)
+					*p++ = hhid->devReport[i+1];
+				tusbdControlSendData(pdevice, pdevice->devData, len);
+				break;
+			}
+		default:
+			tusbdControlSendStall(pdevice, req);
+			return;
+		}
+		break;
+	}
+}
+
+/*
+ *  USB DEVICE HIDクラスデータイン
+ *  parameter1 pdevice:  USB DEVICEハンドラ
+ *  parameter2 epnum:    Endpoint#
+ *  return     TUSBD_ERCODE
+ */
+void
+tusbdHidDataIn(TUSBD_Handle_t *pdevice, uint8_t epnum)
+{
+	((TUSBD_HID_Handle_t *)pdevice->pClassData)->datastate = HID_DATA_IDLE;
+}
+
+/*
+ *  USB DEVICE HIDクラスデータ送信
+ *  parameter1 pdevice:  USB DEVICEハンドラ
+ *  parameter2 pdata:    送信データ
+ *  parameter3 len:      送信データ長
+ *  return     TUSBD_ERCODE
+ */
+TUSBD_ERCODE
+tusbdHidSendData(TUSBD_Handle_t *pdevice, uint8_t *pdata, uint16_t len)
+{
+	TUSBD_HID_Handle_t *hhid = (TUSBD_HID_Handle_t*)pdevice->pClassData;
+    uint32_t i;
+
+	if(pdevice->dev_state == TUSBD_STATE_CONFIGURED){
+		if(hhid->datastate == HID_DATA_IDLE){
+			hhid->datastate = HID_DATA_BUSY;
+			for(i = 0 ; i < len && i < 32 ; i++)
+				hhid->hidData[i] = *pdata++;
+			tusbdDriverStartTransmit(pdevice, EPIN_ADDR, hhid->hidData, i);
+			return TUSBD_E_OK;
+		}
+	}
+	return TUSBD_E_BUSY;
+}
+
+/*
+ *  USB DEVICE SETUP REPORT
+ *  parameter1 pdevice:  USB DEVICEハンドラ
+ *  parameter2 report:   送信リポートデータ
+ *  parameter3 len:      送信リポートデータ長
+ *  return     TUSBD_ERCODE
+ */
+TUSBD_ERCODE
+tusbdHidSetupReport(TUSBD_Handle_t *pdevice, uint8_t *report, uint16_t len)
+{
+	TUSBD_HID_Handle_t *hhid = (TUSBD_HID_Handle_t*)pdevice->pClassData;
+	uint32_t i;
+
+	for(i = 0 ; i < len && i < (NUM_MAX_OUTREPORT-1) ; i++)
+		hhid->devReport[i+1] = *report++;
+	hhid->devReportLength = i;
+	return 0;
+}
+
+
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/usb/device/HID/tusbd_hid.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/usb/device/HID/tusbd_hid.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/usb/device/HID/tusbd_hid.h	(revision 457)
@@ -0,0 +1,159 @@
+/*
+ *  TOPPERS BASE PLATFORM MIDDLEWARE
+ * 
+ *  Copyright (C) 2017-2017 by TOPPERS PROJECT
+ *                             Educational Working Group.
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+/* Copyright (c) 2010-2011 mbed.org, MIT License
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of this software
+ * and associated documentation files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all copies or
+ * substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+ * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/*
+ *  USB Device HID CLASSS部定義
+ */
+
+#ifndef _TUSBD_HID_H_
+#define _TUSBD_HID_H_
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+#include  "tusbd_base.h"
+
+
+#define EPIN_ADDR                 0x81
+#define EPIN_SIZE                 0x04
+
+#define TOTAL_HID_DESCRIPTOR_LENGTH ((1 * CONFIGURATION_DESCRIPTOR_LENGTH) \
+                               + (1 * INTERFACE_DESCRIPTOR_LENGTH) \
+                               + (1 * HID_DESCRIPTOR_LENGTH) \
+                               + (1 * ENDPOINT_DESCRIPTOR_LENGTH))
+
+#define NUM_MAX_OUTREPORT         128
+
+#define USB_GET_REPORT            0x1
+#define USB_GET_IDLE              0x2
+#define USB_GET_PROTOCOL          0x3
+#define USB_SET_REPORT            0x9
+#define USB_SET_IDLE              0xA
+#define USB_SET_PROTOCOL          0xB
+
+
+/* Main items */
+#define INPUT(size)               (0x80 | size)
+#define OUTPUT(size)              (0x90 | size)
+#define FEATURE(size)             (0xb0 | size)
+#define COLLECTION(size)          (0xa0 | size)
+#define END_COLLECTION(size)      (0xc0 | size)
+
+/* Global items */
+#define USAGE_PAGE(size)          (0x04 | size)
+#define LOGICAL_MINIMUM(size)     (0x14 | size)
+#define LOGICAL_MAXIMUM(size)     (0x24 | size)
+#define PHYSICAL_MINIMUM(size)    (0x34 | size)
+#define PHYSICAL_MAXIMUM(size)    (0x44 | size)
+#define UNIT_EXPONENT(size)       (0x54 | size)
+#define UNIT(size)                (0x64 | size)
+#define REPORT_SIZE(size)         (0x74 | size)
+#define REPORT_ID(size)           (0x84 | size)
+#define REPORT_COUNT(size)        (0x94 | size)
+#define PUSH(size)                (0xa4 | size)
+#define POP(size)                 (0xb4 | size)
+
+/* Local items */
+#define USAGE(size)               (0x08 | size)
+#define USAGE_MINIMUM(size)       (0x18 | size)
+#define USAGE_MAXIMUM(size)       (0x28 | size)
+#define DESIGNATOR_INDEX(size)    (0x38 | size)
+#define DESIGNATOR_MINIMUM(size)  (0x48 | size)
+#define DESIGNATOR_MAXIMUM(size)  (0x58 | size)
+#define STRING_INDEX(size)        (0x78 | size)
+#define STRING_MINIMUM(size)      (0x88 | size)
+#define STRING_MAXIMUM(size)      (0x98 | size)
+#define DELIMITER(size)           (0xa8 | size)
+
+/*
+ *  HIDデータ状態定義
+ */
+#define HID_DATA_IDLE             0
+#define HID_DATA_BUSY             1
+
+
+
+typedef struct
+{
+	uint8_t             hidData[32];
+	uint8_t             devReport[NUM_MAX_OUTREPORT];
+	uint16_t            devReportLength;
+	uint8_t             Protocol;
+	uint8_t             IdleState;
+	uint8_t             AltSetting;
+	uint8_t             datastate;
+} TUSBD_HID_Handle_t; 
+
+
+extern uint8_t configurationHidDescriptor[];
+extern uint8_t configurationHidOtherDescriptor[];
+
+
+TUSBD_ERCODE tusbdHidSendData(TUSBD_Handle_t *pdevice, uint8_t *pdata, uint16_t len);
+TUSBD_ERCODE tusbdHidSetupReport(TUSBD_Handle_t *pdevice, uint8_t *report, uint16_t len);
+
+TUSBD_ERCODE tusbdHidInit(TUSBD_Handle_t *pdevice, uint8_t idx);
+TUSBD_ERCODE tusbdHidDeInit(TUSBD_Handle_t *pdevice, uint8_t idx);
+void         tusbdHidSetup(TUSBD_Handle_t *pdevice, UsbSetupRequest *req);
+void         tusbdHidDataIn(TUSBD_Handle_t *pdevice, uint8_t epnum);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _TUSBD_HID_H_ */
+
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/usb/device/SERIAL/tusbd_device.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/usb/device/SERIAL/tusbd_device.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/usb/device/SERIAL/tusbd_device.h	(revision 457)
@@ -0,0 +1,68 @@
+/*
+ *  TOPPERS BASE PLATFORM MIDDLEWARE
+ * 
+ *  Copyright (C) 2017-2017 by TOPPERS PROJECT
+ *                             Educational Working Group.
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+/*
+ *  TOPPERS USB DEVICE CLASS CONFIGURATION インクルードファイル
+ */
+
+#ifndef _TUSBD_DEVICE_H_
+#define _TUSBD_DEVICE_H_
+
+#define tusbdClassInit                tusbdCdcInit
+#define tusbdClassDeInit              tusbdCdcDeInit
+#define tusbdClassSuspend(a)
+#define tusbdClassResume(a)
+#define tusbdClassEp0RxReady          tusbdCdcEP0RxReady
+#define tusbdClassEp0TxSent(a)
+#define tusbdClassSetup               tusbdCdcSetup
+#define tusbdClassDataIn              tusbdCdcDataIn
+#define tusbdClassDataOut             tusbdCdcDataOut
+#define tusbdClassInIncomlete(a, b)
+#define tusbdClassOutIncomlete(a, b)
+
+#define TUSBD_HS_CONFIG_DESCRIPTOR    configurationCdcHsDescriptor
+#define TUSBD_HS_CONFIG_DESC_LENGTH   TOTAL_CDC_DESCRIPTOR_LENGTH
+#define TUSBD_FS_CONFIG_DESCRIPTOR    configurationCdcFsDescriptor
+#define TUSBD_FS_CONFIG_DESC_LENGTH   TOTAL_CDC_DESCRIPTOR_LENGTH
+#define TUSBD_OTR_CONFIG_DESCRIPTOR   configurationCdcOtrDescriptor
+#define TUSBD_OTR_CONFIG_DESC_LENGTH  TOTAL_CDC_DESCRIPTOR_LENGTH
+
+#include "tusbd_serial.h"
+
+
+#endif /* _TUSBD_DEVICE_H_ */
+
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/usb/device/SERIAL/tusbd_serial.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/usb/device/SERIAL/tusbd_serial.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/usb/device/SERIAL/tusbd_serial.c	(revision 457)
@@ -0,0 +1,498 @@
+/*
+ *  TOPPERS BASE PLATFORM MIDDLEWARE
+ * 
+ *  Copyright (C) 2017-2017 by TOPPERS PROJECT
+ *                             Educational Working Group.
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+/*
+ *  USB Device Middleware CDC:SERIAL CLASS部
+ */
+
+#include "tusbd_serial.h"
+
+
+#define CDC_INTERVAL_TIME    16
+
+/*
+ *  USB CDC HS DEVICE CONFIGURATION DESCRIPTOR
+ */
+uint8_t configurationCdcHsDescriptor[TOTAL_CDC_DESCRIPTOR_LENGTH] __attribute__ ((aligned (USB_DATA_ALIGN))) =
+{
+	CONFIGURATION_DESCRIPTOR_LENGTH,	// bLength
+	CONFIGURATION_DESCRIPTOR,			// bDescriptorType
+	(TOTAL_CDC_DESCRIPTOR_LENGTH & 0xFF),   // wTotalLength (LSB)
+	(TOTAL_CDC_DESCRIPTOR_LENGTH >> 8),     // wTotalLength (MSB)
+	0x02,                               // bNumInterfaces
+	0x01,                               // bConfigurationValue
+	0x00,                               // iConfiguration
+	C_RESERVED | C_SELF_POWERED,        // bmAttributes
+	C_POWER(100),                       // bMaxPower
+
+	INTERFACE_DESCRIPTOR_LENGTH,        // bLength
+	INTERFACE_DESCRIPTOR,               // bDescriptorType
+	0x00,                               // bInterfaceNumber
+	0x00,                               // bAlternateSetting
+	0x01,                               // bNumEndpoints
+	CDC_CLASS,                          // bInterfaceClass
+	0x02,                               // bInterfaceSubClass
+	0x01,                               // bInterfaceProtocol
+	0x00,                               // iInterface
+
+	/* CDC Header Functional Descriptor, CDC Spec 5.2.3.1, Table 26 */
+ 	0x05,                               // bFunctionLength
+	0x24,                               // bDescriptorType
+	0x00,                               // bDescriptorSubtype
+	0x10, 0x01,                         // bcdCDC
+	/* Call Management Functional Descriptor, CDC Spec 5.2.3.2, Table 27 */
+	0x05,                               // bFunctionLength
+	0x24,                               // bDescriptorType
+	0x01,                               // bDescriptorSubtype
+	0x03,                               // bmCapabilities
+	0x01,                               // bDataInterface
+	/* Abstract Control Management Functional Descriptor, CDC Spec 5.2.3.3, Table 28 */
+	0x04,                               // bFunctionLength
+	0x24,                               // bDescriptorType
+	0x02,                               // bDescriptorSubtype
+	0x06,                               // bmCapabilities
+	/* Union Functional Descriptor, CDC Spec 5.2.3.8, Table 33 */
+	0x05,                               // bFunctionLength
+	0x24,                               // bDescriptorType
+	0x06,                               // bDescriptorSubtype
+	0x00,                               // bMasterInterface
+	0x01,                               // bSlaveInterface0
+
+	ENDPOINT_DESCRIPTOR_LENGTH,         // bLength
+	ENDPOINT_DESCRIPTOR,                // bDescriptorType
+	CDC_EPINT_ADDR,                     // bEndpointAddress
+	USB_EP_TYPE_INTR,                   // bmAttributes
+	(CDC_PACKET_SIZE_EPINT & 0xFF),     // wMaxPacketSize (LSB)
+	(CDC_PACKET_SIZE_EPINT >> 8),       // wMaxPacketSize (MSB)
+	CDC_INTERVAL_TIME,                  // bInterval
+
+	INTERFACE_DESCRIPTOR_LENGTH,        // bLength
+	INTERFACE_DESCRIPTOR,               // bDescriptorType
+	0x01,                               // bInterfaceNumber
+	0x00,                               // bAlternateSetting
+	0x02,                               // bNumEndpoints
+	DATA_INTERFACE_CLASS,               // bInterfaceClass
+	0x00,                               // bInterfaceSubClass
+	0x00,                               // bInterfaceProtocol
+	0x00,                               // iInterface
+
+	ENDPOINT_DESCRIPTOR_LENGTH,         // bLength
+	ENDPOINT_DESCRIPTOR,                // bDescriptorType
+	CDC_EPBULKOUT_ADDR,                 // bEndpointAddress
+	USB_EP_TYPE_BULK,                   // bmAttributes
+	(MAX_PACKET_SIZE_HS_EPBULK & 0xFF), // wMaxPacketSize (LSB)
+	(MAX_PACKET_SIZE_HS_EPBULK >> 8),   // wMaxPacketSize (MSB)
+	0x00,                               // bInterval (milliseconds)
+
+	ENDPOINT_DESCRIPTOR_LENGTH,         // bLength
+	ENDPOINT_DESCRIPTOR,                // bDescriptorType
+	CDC_EPBULKIN_ADDR,                  // bEndpointAddress
+	USB_EP_TYPE_BULK,                   // bmAttributes
+	(MAX_PACKET_SIZE_HS_EPBULK & 0xFF), // wMaxPacketSize (LSB)
+	(MAX_PACKET_SIZE_HS_EPBULK >> 8),   // wMaxPacketSize (MSB)
+	0x00                                // bInterval (milliseconds)
+};
+
+/*
+ *  USB CDC FS DEVICE CONFIGURATION DESCRIPTOR
+ */
+uint8_t configurationCdcFsDescriptor[TOTAL_CDC_DESCRIPTOR_LENGTH] __attribute__ ((aligned (USB_DATA_ALIGN))) =
+{
+  /*Configuration Descriptor*/
+	CONFIGURATION_DESCRIPTOR_LENGTH,	// bLength
+	CONFIGURATION_DESCRIPTOR,			// bDescriptorType
+	(TOTAL_CDC_DESCRIPTOR_LENGTH & 0xFF),   // wTotalLength (LSB)
+	(TOTAL_CDC_DESCRIPTOR_LENGTH >> 8),     // wTotalLength (MSB)
+	0x02,                               // bNumInterfaces
+	0x01,                               // bConfigurationValue
+	0x00,                               // iConfiguration
+	C_RESERVED | C_SELF_POWERED,        // bmAttributes
+	C_POWER(100),                       // bMaxPower
+
+	INTERFACE_DESCRIPTOR_LENGTH,        // bLength
+	INTERFACE_DESCRIPTOR,               // bDescriptorType
+	0x00,                               // bInterfaceNumber
+	0x00,                               // bAlternateSetting
+	0x01,                               // bNumEndpoints
+	CDC_CLASS,                          // bInterfaceClass
+	0x02,                               // bInterfaceSubClass
+	0x01,                               // bInterfaceProtocol
+	0x00,                               // iInterface
+
+	/* CDC Header Functional Descriptor, CDC Spec 5.2.3.1, Table 26 */
+ 	0x05,                               // bFunctionLength
+	0x24,                               // bDescriptorType
+	0x00,                               // bDescriptorSubtype
+	0x10, 0x01,                         // bcdCDC
+	/* Call Management Functional Descriptor, CDC Spec 5.2.3.2, Table 27 */
+	0x05,                               // bFunctionLength
+	0x24,                               // bDescriptorType
+	0x01,                               // bDescriptorSubtype
+	0x03,                               // bmCapabilities
+	0x01,                               // bDataInterface
+	/* Abstract Control Management Functional Descriptor, CDC Spec 5.2.3.3, Table 28 */
+	0x04,                               // bFunctionLength
+	0x24,                               // bDescriptorType
+	0x02,                               // bDescriptorSubtype
+	0x06,                               // bmCapabilities
+	/* Union Functional Descriptor, CDC Spec 5.2.3.8, Table 33 */
+	0x05,                               // bFunctionLength
+	0x24,                               // bDescriptorType
+	0x06,                               // bDescriptorSubtype
+	0x00,                               // bMasterInterface
+	0x01,                               // bSlaveInterface0
+
+	ENDPOINT_DESCRIPTOR_LENGTH,         // bLength
+	ENDPOINT_DESCRIPTOR,                // bDescriptorType
+	CDC_EPINT_ADDR,                     // bEndpointAddress
+	USB_EP_TYPE_INTR,                   // bmAttributes
+	(CDC_PACKET_SIZE_EPINT & 0xFF),     // wMaxPacketSize (LSB)
+	(CDC_PACKET_SIZE_EPINT >> 8),       // wMaxPacketSize (MSB)
+	CDC_INTERVAL_TIME,                  // bInterval
+
+	INTERFACE_DESCRIPTOR_LENGTH,        // bLength
+	INTERFACE_DESCRIPTOR,               // bDescriptorType
+	0x01,                               // bInterfaceNumber
+	0x00,                               // bAlternateSetting
+	0x02,                               // bNumEndpoints
+	DATA_INTERFACE_CLASS,               // bInterfaceClass
+	0x00,                               // bInterfaceSubClass
+	0x00,                               // bInterfaceProtocol
+	0x00,                               // iInterface
+
+	ENDPOINT_DESCRIPTOR_LENGTH,         // bLength
+	ENDPOINT_DESCRIPTOR,                // bDescriptorType
+	CDC_EPBULKOUT_ADDR,                 // bEndpointAddress
+	USB_EP_TYPE_BULK,                   // bmAttributes
+	(MAX_PACKET_SIZE_FS_EPBULK & 0xFF), // wMaxPacketSize (LSB)
+	(MAX_PACKET_SIZE_FS_EPBULK >> 8),   // wMaxPacketSize (MSB)
+	0x00,                               // bInterval (milliseconds)
+
+	ENDPOINT_DESCRIPTOR_LENGTH,         // bLength
+	ENDPOINT_DESCRIPTOR,                // bDescriptorType
+	CDC_EPBULKIN_ADDR,                  // bEndpointAddress
+	USB_EP_TYPE_BULK,                   // bmAttributes
+	(MAX_PACKET_SIZE_FS_EPBULK & 0xFF), // wMaxPacketSize (LSB)
+	(MAX_PACKET_SIZE_FS_EPBULK >> 8),   // wMaxPacketSize (MSB)
+	0x00                                // bInterval (milliseconds)
+} ;
+
+/*
+ *  USB CDC OTHER DEVICE CONFIGURATION DESCRIPTOR
+ */
+uint8_t configurationCdcOtrDescriptor[TOTAL_CDC_DESCRIPTOR_LENGTH] __attribute__ ((aligned (USB_DATA_ALIGN))) =
+{
+	CONFIGURATION_DESCRIPTOR_LENGTH,	// bLength
+	OTHER_SPEED_CONFIGURATION_DESC,     // bDescriptorType
+	(TOTAL_CDC_DESCRIPTOR_LENGTH & 0xFF),   // wTotalLength (LSB)
+	(TOTAL_CDC_DESCRIPTOR_LENGTH >> 8),     // wTotalLength (MSB)
+	0x02,                               // bNumInterfaces
+	0x01,                               // bConfigurationValue
+	0x04,                               // iConfiguration
+	C_RESERVED | C_SELF_POWERED,        // bmAttributes
+	C_POWER(100),                       // bMaxPower
+
+	INTERFACE_DESCRIPTOR_LENGTH,        // bLength
+	INTERFACE_DESCRIPTOR,               // bDescriptorType
+	0x00,                               // bInterfaceNumber
+	0x00,                               // bAlternateSetting
+	0x01,                               // bNumEndpoints
+	CDC_CLASS,                          // bInterfaceClass
+	0x02,                               // bInterfaceSubClass
+	0x01,                               // bInterfaceProtocol
+	0x00,                               // iInterface
+
+	/* CDC Header Functional Descriptor, CDC Spec 5.2.3.1, Table 26 */
+ 	0x05,                               // bFunctionLength
+	0x24,                               // bDescriptorType
+	0x00,                               // bDescriptorSubtype
+	0x10, 0x01,                         // bcdCDC
+	/* Call Management Functional Descriptor, CDC Spec 5.2.3.2, Table 27 */
+	0x05,                               // bFunctionLength
+	0x24,                               // bDescriptorType
+	0x01,                               // bDescriptorSubtype
+	0x03,                               // bmCapabilities
+	0x01,                               // bDataInterface
+	/* Abstract Control Management Functional Descriptor, CDC Spec 5.2.3.3, Table 28 */
+	0x04,                               // bFunctionLength
+	0x24,                               // bDescriptorType
+	0x02,                               // bDescriptorSubtype
+	0x06,                               // bmCapabilities
+	/* Union Functional Descriptor, CDC Spec 5.2.3.8, Table 33 */
+	0x05,                               // bFunctionLength
+	0x24,                               // bDescriptorType
+	0x06,                               // bDescriptorSubtype
+	0x00,                               // bMasterInterface
+	0x01,                               // bSlaveInterface0
+
+	ENDPOINT_DESCRIPTOR_LENGTH,         // bLength
+	ENDPOINT_DESCRIPTOR,                // bDescriptorType
+	CDC_EPINT_ADDR,                     // bEndpointAddress
+	USB_EP_TYPE_INTR,                   // bmAttributes
+	(CDC_PACKET_SIZE_EPINT & 0xFF),     // wMaxPacketSize (LSB)
+	(CDC_PACKET_SIZE_EPINT >> 8),       // wMaxPacketSize (MSB)
+	CDC_INTERVAL_TIME,                  // bInterval
+
+	INTERFACE_DESCRIPTOR_LENGTH,        // bLength
+	INTERFACE_DESCRIPTOR,               // bDescriptorType
+	0x01,                               // bInterfaceNumber
+	0x00,                               // bAlternateSetting
+	0x02,                               // bNumEndpoints
+	DATA_INTERFACE_CLASS,               // bInterfaceClass
+	0x00,                               // bInterfaceSubClass
+	0x00,                               // bInterfaceProtocol
+	0x00,                               // iInterface
+
+	ENDPOINT_DESCRIPTOR_LENGTH,         // bLength
+	ENDPOINT_DESCRIPTOR,                // bDescriptorType
+	CDC_EPBULKOUT_ADDR,                 // bEndpointAddress
+	USB_EP_TYPE_BULK,                   // bmAttributes
+	(MAX_PACKET_SIZE_FS_EPBULK & 0xFF), // wMaxPacketSize (LSB)
+	(MAX_PACKET_SIZE_FS_EPBULK >> 8),   // wMaxPacketSize (MSB)
+	0x00,                               // bInterval (milliseconds)
+
+	ENDPOINT_DESCRIPTOR_LENGTH,         // bLength
+	ENDPOINT_DESCRIPTOR,                // bDescriptorType
+	CDC_EPBULKIN_ADDR,                  // bEndpointAddress
+	USB_EP_TYPE_BULK,                   // bmAttributes
+	(MAX_PACKET_SIZE_FS_EPBULK & 0xFF), // wMaxPacketSize (LSB)
+	(MAX_PACKET_SIZE_FS_EPBULK >> 8),   // wMaxPacketSize (MSB)
+	0x00                                // bInterval (milliseconds)
+};
+
+static TUSBD_CDC_Handle_t CDC_CLASS_DATA  __attribute__ ((aligned (USB_DATA_ALIGN)));
+
+
+/*
+ *  USB DEVICE CDC初期化
+ *  parameter1 pdevice:  USB DEVICEハンドラ
+ *  parameter2 idx:      Configuration index
+ *  return     TUSBD_ERCODE
+ */
+TUSBD_ERCODE
+tusbdCdcInit(TUSBD_Handle_t *pdevice, uint8_t idx)
+{
+	TUSBD_CDC_Handle_t *hcdc;
+
+	memset(&CDC_CLASS_DATA, 0, sizeof(TUSBD_CDC_Handle_t));
+	pdevice->pClassData = &CDC_CLASS_DATA;
+	hcdc = (TUSBD_CDC_Handle_t*) pdevice->pClassData;
+	if(pdevice->dev_speed == USB_DEVICE_SPEED_HIGH)
+		hcdc->packetsize = MAX_PACKET_SIZE_HS_EPBULK;
+	else
+		hcdc->packetsize = MAX_PACKET_SIZE_FS_EPBULK;
+	hcdc->TxState = 0;
+	hcdc->CmdCode = 0xFF;
+
+	/*
+	 *  ENDPOINT OPEN
+	 */
+	tusbdDriverOpenEp(pdevice, CDC_EPBULKIN_ADDR, USB_EP_TYPE_BULK, hcdc->packetsize);
+	tusbdDriverOpenEp(pdevice, CDC_EPBULKOUT_ADDR, USB_EP_TYPE_BULK, hcdc->packetsize);
+	tusbdDriverOpenEp(pdevice, CDC_EPINT_ADDR, USB_EP_TYPE_INTR, CDC_PACKET_SIZE_EPINT);
+
+	/*
+	 *  SETUP RECEIVED PACKET AREA
+	 */
+	tusbdCdcSetReceivePacket(pdevice);
+	return TUSBD_E_OK;
+}
+
+/*
+ *  USB DEVICE HIDクラス終了
+ *  parameter1 pdevice:  USB DEVICEハンドラ
+ *  parameter2 idx:      Configuration index
+ *  return     TUSBD_ERCODE
+ */
+TUSBD_ERCODE
+tusbdCdcDeInit(TUSBD_Handle_t *pdevice, uint8_t cfgidx)
+{
+	/*
+	 * ENDPOINT CLOSE
+	 */
+	tusbdDriverCloseEp(pdevice, CDC_EPBULKIN_ADDR);
+	tusbdDriverCloseEp(pdevice, CDC_EPBULKOUT_ADDR);
+	tusbdDriverCloseEp(pdevice, CDC_EPINT_ADDR);
+	return TUSBD_E_OK;
+}
+
+/*
+ *  USB DEVICE CDCクラス EP0受信READY
+ *  parameter1 pdevice:  USB DEVICEハンドラ
+ *  return     TUSBD_ERCODE
+ */
+void
+tusbdCdcEP0RxReady(TUSBD_Handle_t *pdevice)
+{
+	TUSBD_CDC_Handle_t *hcdc = (TUSBD_CDC_Handle_t*)pdevice->pClassData;
+	void (*func)(TUSBD_CDC_Handle_t *, uint8_t, uint32_t);
+
+	if(((func = pdevice->pUsrData) != NULL) && (hcdc->CmdCode != 0xFF)){
+		func(hcdc, hcdc->CmdCode, hcdc->CmdLength);
+		hcdc->CmdCode = 0xFF;
+	}
+}
+
+/*
+ *  USB DEVICE CDCクラスセットアップ
+ *  parameter1 pdevice:  USB DEVICEハンドラ
+ *  parameter2 req:      usb control requests
+ *  return     TUSBD_ERCODE
+ */
+void
+tusbdCdcSetup(TUSBD_Handle_t *pdevice, UsbSetupRequest *req)
+{
+	TUSBD_CDC_Handle_t *hcdc = (TUSBD_CDC_Handle_t*) pdevice->pClassData;
+	void (*func)(TUSBD_CDC_Handle_t *, uint8_t, uint32_t);
+
+	func = pdevice->pUsrData;
+	switch (req->bmRequest & USB_REQUEST_TYPE_MASK){
+	case USB_REQUEST_TYPE_CLASS:
+		if(req->wLength){
+			if(req->bmRequest & USB_DEVICE_TO_HOST){
+				if(func != NULL)
+					func(hcdc, req->bRequest, req->wLength);
+				tusbdControlSendData(pdevice, (uint8_t *)hcdc->cmddata, req->wLength);
+			}
+			else{
+				hcdc->CmdCode   = req->bRequest;
+				hcdc->CmdLength = req->wLength;
+				tusbdControlReceiveStart(pdevice, (uint8_t *)hcdc->cmddata, req->wLength);
+			}
+		}
+		else if(func != NULL)
+			func(hcdc, req->bRequest, 0);
+		break;
+	case USB_REQUEST_TYPE_STANDARD:
+		switch(req->bRequest){
+		case GET_INTERFACE:
+			pdevice->devData[0] = 0;
+			tusbdControlSendData(pdevice, (uint8_t *)pdevice->devData, 1);
+			break;
+		case SET_INTERFACE:
+		default:
+			break;
+		}
+	default:
+		break;
+	}
+}
+
+/*
+ *  USB DEVICE CDCクラスデータイン
+ *  parameter1 pdevice:  USB DEVICEハンドラ
+ *  parameter2 epnum:    Endpoint#
+ *  return     TUSBD_ERCODE
+ */
+void
+tusbdCdcDataIn(TUSBD_Handle_t *pdevice, uint8_t epnum)
+{
+	TUSBD_CDC_Handle_t *hcdc = (TUSBD_CDC_Handle_t*) pdevice->pClassData;
+
+	if(pdevice->pClassData != NULL){
+		hcdc->TxState = 0;
+	}
+}
+
+/*
+ *  USB DEVICE CDCクラスデータアウト
+ *  parameter1 pdevice:  USB DEVICEハンドラ
+ *  parameter2 epnum:    Endpoint#
+ *  return     TUSBD_ERCODE
+ */
+void
+tusbdCdcDataOut(TUSBD_Handle_t *pdevice, uint8_t epnum)
+{
+	TUSBD_CDC_Handle_t *hcdc = (TUSBD_CDC_Handle_t*) pdevice->pClassData;
+	void (*func)(TUSBD_CDC_Handle_t *, uint8_t, uint32_t);
+
+	hcdc->RxLength = tusbdDriverGetRxDataSize(pdevice, epnum);
+	if((func = pdevice->pUsrData) != NULL){
+		func(hcdc, CDC_RECEIVED, hcdc->RxLength);
+	}
+}
+
+/*
+ *  USB DEVICE CDC START SENS DATA
+ *  parameter1 pdevice:  USB DEVICEハンドラ
+ *  parameter2 pbuff:    送信データ
+ *  parameter2 length:   送信データ長
+ *  return     TUSBD_ERCODE
+ */
+TUSBD_ERCODE
+tusbdCdcStartTransmit(TUSBD_Handle_t *pdevice, uint8_t *pbuff, uint32_t length)
+{
+	TUSBD_CDC_Handle_t *hcdc = (TUSBD_CDC_Handle_t*)pdevice->pClassData;
+
+	if(pdevice->pClassData != NULL){
+		if(hcdc->TxState == 0){
+			hcdc->TxState = 1;
+			hcdc->TxBuffer = pbuff;
+			hcdc->TxLength = length;
+
+			tusbCpuLock();
+			tusbdDriverStartTransmit(pdevice, CDC_EPBULKIN_ADDR, hcdc->TxBuffer, hcdc->TxLength);
+			tusbCpuUnLock();
+			return TUSBD_E_OK;
+		}
+		else
+			return TUSBD_E_BUSY;
+	}
+	else
+		return TUSBD_E_ERR;
+}
+
+/*
+ *  USB DEVICE CDC SETUP RECEVE PACKET
+ *  parameter1 pdevice:  USB DEVICEハンドラ
+ *  return     TUSBD_ERCODE
+ */
+TUSBD_ERCODE
+tusbdCdcSetReceivePacket(TUSBD_Handle_t *pdevice)
+{
+	TUSBD_CDC_Handle_t *hcdc = (TUSBD_CDC_Handle_t*)pdevice->pClassData;
+
+	if(pdevice->pClassData != NULL){
+		tusbCpuLock();
+		tusbdDriverSetupReceive(pdevice, CDC_EPBULKOUT_ADDR, hcdc->rxdata, hcdc->packetsize);
+		tusbCpuUnLock();
+		return TUSBD_E_OK;
+	}
+	else
+		return TUSBD_E_ERR;
+}
+
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/usb/device/SERIAL/tusbd_serial.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/usb/device/SERIAL/tusbd_serial.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/usb/device/SERIAL/tusbd_serial.h	(revision 457)
@@ -0,0 +1,133 @@
+/*
+ *  TOPPERS BASE PLATFORM MIDDLEWARE
+ * 
+ *  Copyright (C) 2017-2017 by TOPPERS PROJECT
+ *                             Educational Working Group.
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+/* Copyright (c) 2010-2011 mbed.org, MIT License
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of this software
+ * and associated documentation files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all copies or
+ * substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+ * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/*
+ *  USB Device CDC SERIAL CLASSS部定義
+ */
+
+#ifndef _TUSBD_SERIAL_H_
+#define _TUSBD_SERIAL_H_
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+#include  "tusbd_base.h"
+
+
+#define CDC_EPBULKIN_ADDR                           0x81
+#define CDC_EPBULKOUT_ADDR                          0x01
+#define CDC_EPINT_ADDR                              0x82
+
+#define TOTAL_CDC_DESCRIPTOR_LENGTH ((1 * CONFIGURATION_DESCRIPTOR_LENGTH) \
+                               + (2 * INTERFACE_DESCRIPTOR_LENGTH) \
+                               + (5 + 5 + 5 + 4) \
+                               + (3 * ENDPOINT_DESCRIPTOR_LENGTH))
+
+#define CDC_PACKET_SIZE_EPINT                       8
+#define CDC_LINE_CODE_SIZE                          7
+
+/*
+ *  CDC要求定義
+ */
+#define CDC_SEND_ENCAPSULATED_COMMAND               0x00
+#define CDC_GET_ENCAPSULATED_RESPONSE               0x01
+#define CDC_SET_COMM_FEATURE                        0x02
+#define CDC_GET_COMM_FEATURE                        0x03
+#define CDC_CLEAR_COMM_FEATURE                      0x04
+#define CDC_SET_LINE_CODING                         0x20
+#define CDC_GET_LINE_CODING                         0x21
+#define CDC_SET_CONTROL_LINE_STATE                  0x22
+#define CDC_SEND_BREAK                              0x23
+
+#define CDC_RECEIVED                                0x40
+
+
+typedef struct
+{
+	uint8_t  rxdata[MAX_PACKET_SIZE_HS_EPBULK];
+	uint8_t  cmddata[64];
+	uint8_t  CmdCode;
+	uint8_t  CmdLength;
+	uint16_t packetsize;
+	uint32_t RxLength;
+	uint8_t  *TxBuffer;
+	uint32_t TxLength;
+	volatile uint32_t TxState;
+} TUSBD_CDC_Handle_t;
+
+extern uint8_t configurationCdcHsDescriptor[];
+extern uint8_t configurationCdcFsDescriptor[];
+extern uint8_t configurationCdcOtrDescriptor[];
+
+
+TUSBD_ERCODE tusbdCdcSetReceivePacket(TUSBD_Handle_t *pdevice);
+TUSBD_ERCODE tusbdCdcStartTransmit(TUSBD_Handle_t *pdevice, uint8_t *pbuff, uint32_t length);
+
+
+TUSBD_ERCODE tusbdCdcInit(TUSBD_Handle_t *pdevice, uint8_t idx);
+TUSBD_ERCODE tusbdCdcDeInit(TUSBD_Handle_t *pdevice, uint8_t idx);
+void         tusbdCdcEP0RxReady(TUSBD_Handle_t *pdevice);
+void         tusbdCdcSetup(TUSBD_Handle_t *pdevice, UsbSetupRequest *req);
+void         tusbdCdcDataIn(TUSBD_Handle_t *pdevice, uint8_t epnum);
+void         tusbdCdcDataOut(TUSBD_Handle_t *pdevice, uint8_t epnum);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _TUSBD_SERIAL_H_ */
+
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/usb/device/tusbd_base.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/usb/device/tusbd_base.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/usb/device/tusbd_base.c	(revision 457)
@@ -0,0 +1,811 @@
+/*
+ *  TOPPERS BASE PLATFORM MIDDLEWARE
+ * 
+ *  Copyright (C) 2017-2017 by TOPPERS PROJECT
+ *                             Educational Working Group.
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+/*
+ *  USB Device Middleware BASE部
+ */
+
+#include "tusbd_base.h"
+#include "tusbd_device.h"
+
+
+#define NUM_MAX_REQUEST      13
+#define NUM_STRING_TABLE     7
+
+static void DeviceGetStatus(TUSBD_Handle_t *pdevice, UsbSetupRequest *req);
+static void DeviceClearFeature(TUSBD_Handle_t *pdevice, UsbSetupRequest *req);
+static void DeviceSetFeature(TUSBD_Handle_t *pdevice, UsbSetupRequest *req);
+static void DeviceGetDescriptor(TUSBD_Handle_t *pdevice, UsbSetupRequest *req);
+static void DeviceSetAddress(TUSBD_Handle_t *pdevice, UsbSetupRequest *req);
+static void DeviceGetConfiguration(TUSBD_Handle_t *pdevice, UsbSetupRequest *req);
+static void DeviceSetConfiguration(TUSBD_Handle_t *pdevice, UsbSetupRequest *req);
+static void EndpointGetStatus(TUSBD_Handle_t *pdevice, UsbSetupRequest *req);
+static void EndpointClearFeature(TUSBD_Handle_t *pdevice, UsbSetupRequest *req);
+static void EndpointSetFeature(TUSBD_Handle_t *pdevice, UsbSetupRequest *req);
+
+
+/*
+ *  DEVICE REQUEST関数テーブル
+ */
+static void (*usb_pbRequestDev[NUM_MAX_REQUEST])(TUSBD_Handle_t *pdevice, UsbSetupRequest *req) = {
+	DeviceGetStatus,        DeviceClearFeature,     tusbdControlSendStall, DeviceSetFeature,
+	tusbdControlSendStall,  DeviceSetAddress,       DeviceGetDescriptor,   tusbdControlSendStall,
+	DeviceGetConfiguration, DeviceSetConfiguration, tusbdControlSendStall, tusbdControlSendStall,
+	tusbdControlSendStall
+};
+
+/*
+ *  ENDPOINT REQUEST関数テーブル
+ */
+static void (*usb_pbRequestEp[NUM_MAX_REQUEST])(TUSBD_Handle_t *pdevice, UsbSetupRequest *req) = {
+	EndpointGetStatus,      EndpointClearFeature,   tusbdControlSendStall, EndpointSetFeature,
+	tusbdControlSendStall,  tusbdControlSendStall,  tusbdControlSendStall, tusbdControlSendStall,
+	tusbdControlSendStall,  tusbdControlSendStall,  tusbdControlSendStall, tusbdControlSendStall,
+	tusbdControlSendStall
+};
+
+static uint8_t *usb_string_table[NUM_STRING_TABLE] = {
+	TUSBD_LANGUAGEID_DESCRIPTOR,
+	TUSBD_MANUFACTURER_STRING,
+	TUSBD_PRODUCT_STRING,
+	TUSBD_SERIAL_STRING,
+	TUSBD_CONFIGURATION_STRING,
+	TUSBD_INTERFACE_STRING,
+	TUSBD_USER_STRING
+};
+
+
+/*
+ *  DEVICE REQUEST GET STATUS
+ */
+static void
+DeviceGetStatus(TUSBD_Handle_t *pdevice, UsbSetupRequest *req)
+{
+	switch (pdevice->dev_state){
+	case TUSBD_STATE_ADDRESSED:
+	case TUSBD_STATE_CONFIGURED:
+		pdevice->devData[0] = TUSBD_CONFIG_SELF_POWERED;
+		pdevice->devData[1] = 0;
+		if(pdevice->dev_remote_wakeup)
+			pdevice->devData[0] |= TUSBD_CONFIG_REMOTE_WAKEUP;
+		tusbdControlSendData(pdevice, (uint8_t *)pdevice->devData, 2);
+		break;
+	default:
+		tusbdControlSendStall(pdevice, req);
+		break;
+	}
+}
+
+/*
+ *  DEVICE REQUEST CLEAR FEATURE
+ */
+static void
+DeviceClearFeature(TUSBD_Handle_t *pdevice, UsbSetupRequest *req)
+{
+	switch (pdevice->dev_state){
+	case TUSBD_STATE_ADDRESSED:
+	case TUSBD_STATE_CONFIGURED:
+		if(req->wValue == USB_FEATURE_REMOTE_WAKEUP){
+			pdevice->dev_remote_wakeup = 0;
+			tusbdClassSetup(pdevice, req);
+			tusbdControlSendStatus(pdevice);
+		}
+		break;
+	default:
+		tusbdControlSendStall(pdevice, req);
+		break;
+	}
+}
+
+/*
+ *  DEVICE REQUEST SET FEATURE
+ */
+static void
+DeviceSetFeature(TUSBD_Handle_t *pdevice, UsbSetupRequest *req)
+{
+	if(req->wValue == USB_FEATURE_REMOTE_WAKEUP){
+		pdevice->dev_remote_wakeup = 1;
+		tusbdClassSetup(pdevice, req);
+		tusbdControlSendStatus(pdevice);
+	}
+}
+
+/*
+ *  DEVICE REQUEST GET DESCRIPTOR
+ */
+static void
+DeviceGetDescriptor(TUSBD_Handle_t *pdevice, UsbSetupRequest *req)
+{
+	uint16_t len;
+	uint8_t *pbuf;
+
+	switch (req->wValue >> 8){
+#if defined(TUSBD_BOS_DESCRIPTOR)
+	case BOS_DESCRIPTOR:
+		pbuf = TUSBD_BOS_DESCRIPTOR;
+		len  = TUSBD_BOS_DESCRIPTOR[0];
+		break;
+#endif
+	case DEVICE_DESCRIPTOR:
+		pbuf = TUSBD_DEVICE_DESCRIPTOR;
+		len  = TUSBD_DEVICE_DESCRIPTOR[0];
+		break;
+	case CONFIGURATION_DESCRIPTOR:
+		if(pdevice->dev_speed == USB_DEVICE_SPEED_HIGH){
+			pbuf = TUSBD_HS_CONFIG_DESCRIPTOR;
+			len  = TUSBD_HS_CONFIG_DESC_LENGTH;
+		}
+		else{
+			pbuf = TUSBD_FS_CONFIG_DESCRIPTOR;
+			len  = TUSBD_FS_CONFIG_DESC_LENGTH;
+		}
+		break;
+	case STRING_DESCRIPTOR:
+		if(((uint8_t)req->wValue) < NUM_STRING_TABLE){
+			pbuf = usb_string_table[(uint8_t)req->wValue];
+			if(pbuf == NULL){
+				tusbdControlSendStall(pdevice, req);
+				return;
+			}
+			len  = pbuf[0];
+		}
+		else{
+			tusbdControlSendStall(pdevice, req);
+			return;
+		}
+		break;
+	case DEVICE_QUALIFIER_DESCRIPTOR:
+		if(pdevice->dev_speed == USB_DEVICE_SPEED_HIGH){
+			pbuf = TUSBD_DEVICE_QUALIFIER_DESCRIPTOR;
+			len  = TUSBD_DEVICE_QUALIFIER_DESCRIPTOR[0];
+			break;
+		}
+		else{
+			tusbdControlSendStall(pdevice, req);
+			return;
+		}
+	case OTHER_SPEED_CONFIGURATION_DESC:
+		if(pdevice->dev_speed == USB_DEVICE_SPEED_HIGH){
+			pbuf = TUSBD_OTR_CONFIG_DESCRIPTOR;
+			len  = TUSBD_OTR_CONFIG_DESC_LENGTH;
+			break;
+		}
+		else{
+			tusbdControlSendStall(pdevice, req);
+			return;
+		}
+	default:
+		tusbdControlSendStall(pdevice, req);
+		return;
+	}
+
+	if(len != 0 && req->wLength != 0){
+		if(len > req->wLength)
+			len = req->wLength;
+		tusbdControlSendData(pdevice, pbuf, len);
+	}
+}
+
+/*
+ *  DEVICE REQUEST SET ADDRESS
+ */
+static void
+DeviceSetAddress(TUSBD_Handle_t *pdevice, UsbSetupRequest *req)
+{
+	uint8_t  dev_addr; 
+
+	if(req->wIndex == 0 && req->wLength == 0){
+		dev_addr = (uint8_t)(req->wValue) & 0x7F;
+		if(pdevice->dev_state == TUSBD_STATE_CONFIGURED){
+			tusbdControlSendStall(pdevice , req);
+		}
+		else{
+			pdevice->dev_address = dev_addr;
+			tusbdDriverSetUSBAddress(pdevice, dev_addr);
+			tusbdControlSendStatus(pdevice);
+			if(dev_addr != 0){
+				pdevice->dev_state = TUSBD_STATE_ADDRESSED;
+			}
+			else{
+				pdevice->dev_state = TUSBD_STATE_INIT;
+			}
+		}
+	}
+	else{
+		tusbdControlSendStall(pdevice, req);
+	}
+}
+
+/*
+ *  DEVICE REQUEST GET CONFIGURATION
+ */
+static void
+DeviceGetConfiguration(TUSBD_Handle_t *pdevice, UsbSetupRequest *req)
+{
+	if(req->wLength != 1){
+		tusbdControlSendStall(pdevice , req);
+	}
+	else{
+		switch (pdevice->dev_state){
+		case TUSBD_STATE_ADDRESSED:
+			pdevice->devData[0] = 0;
+			tusbdControlSendData(pdevice, (uint8_t *)pdevice->devData, 1);
+			break;
+		case TUSBD_STATE_CONFIGURED:
+			pdevice->devData[0] = pdevice->dev_config;
+			tusbdControlSendData(pdevice, (uint8_t *)pdevice->devData, 1);
+			break;
+		default:
+			tusbdControlSendStall(pdevice, req);
+			break;
+		}
+	}
+}
+
+/*
+ *  DEVICE REQUEST SET CONFIGURATION
+ */
+static void
+DeviceSetConfiguration(TUSBD_Handle_t *pdevice, UsbSetupRequest *req)
+{
+	uint8_t  cfgidx;
+
+	cfgidx = (uint8_t)(req->wValue);
+	if(cfgidx > TUSBD_MAX_NUM_CONFIGURATION){
+		tusbdControlSendStall(pdevice , req);
+		return;
+	}
+
+	switch (pdevice->dev_state){
+	case TUSBD_STATE_ADDRESSED:
+		if(cfgidx){
+			pdevice->dev_config = cfgidx;
+			pdevice->dev_state = TUSBD_STATE_CONFIGURED;
+			if(tusbdClassInit(pdevice, cfgidx) != TUSBD_E_OK){
+				tusbdControlSendStall(pdevice , req);
+				return;
+			}
+			tusbdControlSendStatus(pdevice);
+		}
+		else{
+			tusbdControlSendStatus(pdevice);
+		}
+		break;
+	case TUSBD_STATE_CONFIGURED:
+		if(cfgidx == 0){
+			pdevice->dev_state = TUSBD_STATE_ADDRESSED;
+			pdevice->dev_config = cfgidx;
+			tusbdClassDeInit(pdevice, cfgidx);
+			tusbdControlSendStatus(pdevice);
+		}
+		else if(cfgidx != pdevice->dev_config){
+			/*
+			 *  古いCONFIGURATIONをリセット
+			 */
+			tusbdClassDeInit(pdevice, cfgidx);
+
+			/*
+			 *  新しいCONFIGURATIONで初期化
+			 */
+			pdevice->dev_config = cfgidx;
+			if(tusbdClassInit(pdevice, cfgidx) != TUSBD_E_OK){
+				tusbdControlSendStall(pdevice , req);
+				return;
+			}
+			tusbdControlSendStatus(pdevice);
+		}
+		else{
+			tusbdControlSendStatus(pdevice);
+		}
+		break;
+	default:
+		tusbdControlSendStall(pdevice, req);
+		break;
+	}
+}
+
+/*
+ *  ENDPOINT REQUEST GET STATUS
+ */
+static void
+EndpointGetStatus(TUSBD_Handle_t *pdevice, UsbSetupRequest *req)
+{
+	TUSBD_Endpoint_t *pep;
+	uint8_t ep_addr = req->wIndex & 0xFF;
+
+	switch (pdevice->dev_state){
+	case TUSBD_STATE_ADDRESSED:
+		if((ep_addr & 0x7F) != 0x00){
+			tusbdDriverStallEp(pdevice , ep_addr);
+		}
+		break;
+	case TUSBD_STATE_CONFIGURED:
+		pep = ((ep_addr & USB_DEVICE_TO_HOST) != 0) ? &pdevice->ep_in[ep_addr & 0x7F] : &pdevice->ep_out[ep_addr & 0x7F];
+		if(tusbdDriverStallConditionEp(pdevice, ep_addr)){
+			pep->status = 0x0001;
+		}
+		else{
+			pep->status = 0x0000;
+		}
+		tusbdControlSendData(pdevice, (uint8_t *)&pep->status, 2);
+		break;
+	default:
+		tusbdControlSendStall(pdevice, req);
+		break;
+	}
+}
+
+/*
+ *  ENDPOINT REQUEST CLEAR FEATURE
+ */
+static void
+EndpointClearFeature(TUSBD_Handle_t *pdevice, UsbSetupRequest *req)
+{
+	uint8_t ep_addr = req->wIndex & 0xFF;
+
+	switch (pdevice->dev_state){
+	case TUSBD_STATE_ADDRESSED:
+		if((ep_addr & 0x7F) != 0x00){
+			tusbdDriverStallEp(pdevice , ep_addr);
+		}
+		break;
+	case TUSBD_STATE_CONFIGURED:
+		if(req->wValue == USB_FEATURE_EP_HALT){
+			if((ep_addr & 0x7F) != 0x00){
+				tusbdDriverClearStallEp(pdevice , ep_addr);
+				tusbdClassSetup(pdevice, req);
+			}
+			tusbdControlSendStatus(pdevice);
+		}
+		break;
+	default:
+		tusbdControlSendStall(pdevice, req);
+		break;
+	}
+}
+
+/*
+ *  ENDPOINT REQUEST SET FEATURE
+ */
+static void
+EndpointSetFeature(TUSBD_Handle_t *pdevice, UsbSetupRequest *req)
+{
+	uint8_t ep_addr = req->wIndex & 0xFF;
+
+	switch (pdevice->dev_state){
+	case TUSBD_STATE_ADDRESSED:
+		if((ep_addr & 0x7F) != 0x00){
+			tusbdDriverStallEp(pdevice , ep_addr);
+		}
+		break;
+	case TUSBD_STATE_CONFIGURED:
+		if(req->wValue == USB_FEATURE_EP_HALT){
+			if((ep_addr & 0x7F) != 0x00){
+				tusbdDriverStallEp(pdevice , ep_addr);
+			}
+		}
+		tusbdClassSetup(pdevice, req);
+		tusbdControlSendStatus(pdevice);
+		break;
+	default:
+		tusbdControlSendStall(pdevice, req);
+		break;
+	}
+}
+
+
+/*
+ *  USB DEVICE初期化
+ *  parameter1 pdevice:  USB DEVICEハンドラ
+ *  parameter2 id:    デバイスID
+ *  return     TUSBD_ERCODE
+ */
+TUSBD_ERCODE
+tusbdInit(TUSBD_Handle_t *pdevice, uint8_t id)
+{
+	if(pdevice == NULL)
+		return TUSBD_E_ERR;
+
+	/*
+	 *  ハンドラ初期化
+	 */
+	pdevice->dev_state = TUSBD_STATE_INIT;
+	pdevice->id = id;
+
+	/*
+	 *  ハードウェア初期化
+	 */
+	return tusbdDriverInit(pdevice);
+}
+
+/*
+ *  USB DEVICE終了
+ *  parameter1 pdevice:  USB DEVICEハンドラ
+ *  return    TUSBD_ERCODE
+ */
+TUSBD_ERCODE
+tusbdDeInit(TUSBD_Handle_t *pdevice)
+{
+	/*
+	 *  デバイス状態をリセットに
+	 */
+	pdevice->dev_state = TUSBD_STATE_RESET;
+
+	/*
+	 *  ドライバクラスを停止
+	 */
+	tusbdClassDeInit(pdevice, pdevice->dev_config);
+
+	/*
+	 *  ハードウェアを終了
+	 */
+	return tusbdDriverDeInit(pdevice);
+}
+
+/*
+ *  USB DEVICE開始
+ *  parameter1 pdevice:  USB DEVICEハンドラ
+ *  return    TUSBD_ERCODE
+ */
+TUSBD_ERCODE
+tusbdStart(TUSBD_Handle_t *pdevice)
+{
+	pdevice->ep0_state = TUSBD_EP0_IDLE;
+	/*
+	 *  USB DEVICEドライバ開始
+	 */
+	return tusbdDriverStart(pdevice);
+}
+
+/*
+ *  USB DEVICE 停止
+ *  parameter1 pdevice:  USB DEVICEハンドラ
+ *  return    TUSBD_ERCODE
+ */
+TUSBD_ERCODE
+tusbdStop(TUSBD_Handle_t *pdevice)
+{
+	/*
+	 *  ドライバクラス停止
+	 */
+	tusbdClassDeInit(pdevice, pdevice->dev_config);
+
+	/*
+	 *  USB DEVICEドライバ停止
+	 */
+	tusbdDriverStop(pdevice);
+	return TUSBD_E_OK;
+}
+
+
+/*
+ *  USB DEVICE EP0 SETUP STAGE処理
+ *  parameter1 pdevice:  USB DEVICEハンドラ
+ *  parameter2 psetup:セットアップデータ
+ *  return     TUSBD_ERCODE
+ */
+TUSBD_ERCODE
+tusbdSetupStage(TUSBD_Handle_t *pdevice, uint8_t *psetup)
+{
+	UsbSetupRequest  *req = &pdevice->request;
+	volatile uint8_t *p = psetup;
+
+	req->bmRequest     = p[0];
+	req->bRequest      = p[1];
+	req->wValue        = p[2] | (p[3] << 8);
+	req->wIndex        = p[4] | (p[5] << 8);
+	req->wLength       = p[6] | (p[7] << 8);
+
+	pdevice->ep0_state = TUSBD_EP0_SETUP;
+	pdevice->ep0_data_len = pdevice->request.wLength;
+
+	switch (pdevice->request.bmRequest & 0x1F){
+	case USB_RECIPIENT_DEVICE:
+		if(req->bRequest < NUM_MAX_REQUEST)
+			usb_pbRequestDev[req->bRequest](pdevice, req);
+		else
+			tusbdControlSendStall(pdevice, req);
+		break;
+	case USB_RECIPIENT_INTERFACE:
+		if(pdevice->dev_state == TUSBD_STATE_CONFIGURED){
+			if((req->wIndex & 0xFF) <= TUSBD_MAX_NUM_INTERFACES){
+				tusbdClassSetup(pdevice, req);
+				if(req->wLength == 0){
+					tusbdControlSendStatus(pdevice);
+				}
+			}
+		}
+		else
+			tusbdControlSendStall(pdevice, req);
+		break;
+	case USB_RECIPIENT_ENDPOINT:
+		if((req->bmRequest & USB_REQUEST_TYPE_MASK) == USB_REQUEST_TYPE_CLASS){
+			tusbdClassSetup(pdevice, req);
+		}
+		else{
+			if(req->bRequest < NUM_MAX_REQUEST)
+				usb_pbRequestEp[req->bRequest](pdevice, req);
+			else
+				tusbdControlSendStall(pdevice, req);
+		}
+		break;
+	default:
+		tusbdControlSendStall(pdevice, req);
+		break;
+	}
+	return TUSBD_E_OK;
+}
+
+/*
+ *  USB DEVICE DATAOUT(受信) STAGE処理
+ *  parameter1 pdevice:  USB DEVICEハンドラ
+ *  parameter2 epnum: エンドポイント番号
+ *  parameter3 pdata: 現在の受信データポインタ
+ *  return    TUSBD_ERCODE
+ */
+TUSBD_ERCODE
+tusbdDataOutStage(TUSBD_Handle_t *pdevice, uint8_t epnum, uint8_t *pdata)
+{
+	if(epnum == 0){	/* エンドポイント#0 */
+		TUSBD_Endpoint_t *pep = &pdevice->ep_out[0];
+		if(pdevice->ep0_state == TUSBD_EP0_DATAOUT){
+			if(pep->remlength > pep->maxpacket){
+				pep->remlength -=  pep->maxpacket;
+				if(pep->remlength < pep->maxpacket)
+					tusbdControlContinueReceive(pdevice, pdata, pep->remlength);
+				else
+					tusbdControlContinueReceive(pdevice, pdata, pep->maxpacket);
+			}
+			else{
+				if(pdevice->dev_state == TUSBD_STATE_CONFIGURED){
+					tusbdClassEp0RxReady(pdevice);
+				}
+				tusbdControlSendStatus(pdevice);
+			}
+		}
+	}
+	else if(pdevice->dev_state == TUSBD_STATE_CONFIGURED){
+		tusbdClassDataOut(pdevice, epnum);
+	}
+	return TUSBD_E_OK;
+}
+
+/*
+ *  USB DEVICE DATAIN(送信) STAGE処理
+ *  parameter1 pdevice:  USB DEVICEハンドラ
+ *  parameter2 epnum: エンドポイント番号
+ *  parameter3 pdata: 現在の送信データポインタ
+ *  return     TUSBD_ERCODE
+ */
+TUSBD_ERCODE
+tusbdDataInStage(TUSBD_Handle_t *pdevice, uint8_t epnum, uint8_t *pdata)
+{
+	if(epnum == 0){	/* エンドポイント#0 */
+		TUSBD_Endpoint_t *pep = &pdevice->ep_in[0];
+		if(pdevice->ep0_state == TUSBD_EP0_DATAIN){
+			if(pep->remlength > pep->maxpacket){
+				pep->remlength -=  pep->maxpacket;
+				tusbdControlContinueSendData(pdevice, pdata, pep->remlength);
+				/*
+				 *  受信設定初期化
+				 */
+				tusbdDriverSetupReceive(pdevice, 0, NULL, 0);
+			}
+			else{ /* ZERO LENGTH PACKET送信処理 */
+				if((pep->xfersize % pep->maxpacket) == 0 && pep->xfersize >= pep->maxpacket
+						&& pep->xfersize < pdevice->ep0_data_len){
+					tusbdControlContinueSendData(pdevice , NULL, 0);
+					pdevice->ep0_data_len = 0;
+					/*
+					 *  受信設定初期化
+					 */
+					tusbdDriverSetupReceive(pdevice, 0, NULL, 0);
+				}
+				else{
+					if(pdevice->dev_state == TUSBD_STATE_CONFIGURED){
+						tusbdClassEp0TxSent(pdevice);
+					}
+					tusbdControlReceiveStatus(pdevice);
+				}
+			}
+		}
+		if(pdevice->dev_test_mode == 1){
+			tusbdDriverTestMode(pdevice);
+			pdevice->dev_test_mode = 0;
+		}
+	}
+	else if(pdevice->dev_state == TUSBD_STATE_CONFIGURED){
+		tusbdClassDataIn(pdevice, epnum);
+	}
+	return TUSBD_E_OK;
+}
+
+/*
+ *  USB DEVICE RESET処理
+ *  parameter1 pdevice:  USB DEVICEハンドラ
+ *  return    TUSBD_ERCODE
+ */
+
+TUSBD_ERCODE
+tusbdReset(TUSBD_Handle_t  *pdevice)
+{
+	/*
+	 *  エンドポイント#0 オープン
+	 */
+	tusbdDriverOpenEp(pdevice, 0x00, USB_EP_TYPE_CTRL, USB_MAX_EP0_SIZE);
+	pdevice->ep_out[0].maxpacket = USB_MAX_EP0_SIZE;
+	tusbdDriverOpenEp(pdevice, 0x80, USB_EP_TYPE_CTRL, USB_MAX_EP0_SIZE);
+	pdevice->ep_in[0].maxpacket = USB_MAX_EP0_SIZE;
+
+	/*
+	 *  デバイスユーザーステートをデフォルトに
+	 */
+	pdevice->dev_state = TUSBD_STATE_INIT;
+
+	/*
+	 *  デバイスクラスをリセット
+	 */
+	return tusbdClassDeInit(pdevice, pdevice->dev_config);
+}
+
+
+/*
+ *  USB DEVICE SETUP SPEED処理
+ *  parameter1 pdevice:  USB DEVICEハンドラ
+ *  parameter2 speed: デバイススピード
+ *  return     TUSBD_ERCODE
+ */
+TUSBD_ERCODE
+tusbdSetSpeed(TUSBD_Handle_t  *pdevice, uint8_t speed)
+{
+	pdevice->dev_speed = speed & 3;
+	if(pdevice->makeDescriptor != NULL)
+		pdevice->makeDescriptor(pdevice->dev_speed);
+	return TUSBD_E_OK;
+}
+
+/*
+ *  USB DEVICE SUSPEND REQUEST処理
+ *  parameter1 pdevice:  USB DEVICEハンドラ
+ *  return     TUSBD_ERCODE
+ */
+TUSBD_ERCODE
+tusbdSuspend(TUSBD_Handle_t *pdevice)
+{
+	pdevice->dev_old_state =  pdevice->dev_state;
+	pdevice->dev_state  = TUSBD_STATE_SUSPENDED;
+	tusbdClassSuspend(pdevice);
+	return TUSBD_E_OK;
+}
+
+/*
+ *  USB DEVICE RESUME REQUEST処理
+ *  parameter1 pdevice:  USB DEVICEハンドラ
+ *  return     TUSBD_ERCODE
+ */
+
+TUSBD_ERCODE
+tusbdResume(TUSBD_Handle_t *pdevice)
+{
+	pdevice->dev_state = pdevice->dev_old_state;
+	tusbdClassResume(pdevice);
+	return TUSBD_E_OK;
+}
+
+/*
+ *  USB DEVICE ISOIN INCOMPLETE処理
+ *  parameter1 pdevice:  USB DEVICEハンドラ
+ *  parameter2 epnum: エンドポイント番号
+ *  return     TUSBD_ERCODE
+ */
+TUSBD_ERCODE
+tusbdIsoInIncomplete(TUSBD_Handle_t *pdevice, uint8_t epnum)
+{
+	tusbdClassInIncomlete(pdevice, epnum);
+	return TUSBD_E_OK;
+}
+
+/*
+ *  USB DEVICE ISOOUT INCOMPLETE処理
+ *  parameter1 pdevice:  USB DEVICEハンドラ
+ *  parameter2 epnum: エンドポイント番号
+ *  return     TUSBD_ERCODE
+ */
+TUSBD_ERCODE
+tusbdIsoOutIncomplete(TUSBD_Handle_t *pdevice, uint8_t epnum)
+{
+	tusbdClassOutIncomlete(pdevice, epnum);
+	return TUSBD_E_OK;
+}
+
+/*
+ *  USB DEVICE CONNECTED処理
+ *  parameter1 pdevice:  USB DEVICEハンドラ
+ *  return     TUSBD_ERCODE
+ */
+TUSBD_ERCODE
+tusbdDeviceConnected(TUSBD_Handle_t *pdevice)
+{
+	return TUSBD_E_OK;
+}
+
+/*
+ *  USB DEVICE DISCONNECTED処理
+ *  parameter1 pdevice:  USB DEVICEハンドラ
+ *  return     TUSBD_ERCODE
+ */
+TUSBD_ERCODE
+tusbdDeviceDisconnected(TUSBD_Handle_t *pdevice)
+{
+	/* Free Class Resources */
+	pdevice->dev_state = TUSBD_STATE_INIT;
+	tusbdClassDeInit(pdevice, pdevice->dev_config);
+	return TUSBD_E_OK;
+}
+
+/*
+ *  USB DEVICE SEARCH DIECRIPTOR
+ *  parameter1 pdevice:  USB DEVICEハンドラ
+ *  parameter2 type:     検索DESCRIPTORタイプ
+ *  return     DESCRIPTORポインタ
+ */
+uint8_t *
+tusbdFindDescriptor(TUSBD_Handle_t *pdevice, uint8_t type)
+{
+	uint16_t wTotalLength;
+	uint8_t *cptr = TUSBD_FS_CONFIG_DESCRIPTOR;
+	uint8_t *dptr;
+
+    if(cptr == NULL)
+		return NULL;
+	if(cptr[0] != CONFIGURATION_DESCRIPTOR_LENGTH || cptr[1] != CONFIGURATION_DESCRIPTOR)
+		return NULL;
+
+	wTotalLength = cptr[2] | (cptr[3] << 8);
+    if(wTotalLength <= (CONFIGURATION_DESCRIPTOR_LENGTH+2))
+		return NULL;
+
+	dptr = cptr + CONFIGURATION_DESCRIPTOR_LENGTH;
+    do{
+		if(dptr[1] == type)
+			return dptr;
+		dptr += dptr[0];	/* bLength */
+	}while(dptr < (cptr + wTotalLength));
+    return NULL;
+}
+
+
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/usb/device/tusbd_base.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/usb/device/tusbd_base.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/usb/device/tusbd_base.h	(revision 457)
@@ -0,0 +1,183 @@
+/*
+ *  TOPPERS BASE PLATFORM MIDDLEWARE
+ * 
+ *  Copyright (C) 2017-2017 by TOPPERS PROJECT
+ *                             Educational Working Group.
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+/*
+ *  USB Device Middleware BASE部定義
+ */
+
+#ifndef _TUSBD_BASE_H_
+#define _TUSBD_BASE_H_
+
+#include "tusb_rtos.h"
+#include "tusb_types.h"
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+#ifndef TUSBD_NUM_ENDPOINT
+#define TUSBD_NUM_ENDPOINT                    15
+#endif
+
+#define USB_REQUEST_TYPE_MASK                 0x60
+
+#define TUSBD_CONFIG_REMOTE_WAKEUP            0x02
+
+#define USB_FEATURE_EP_HALT                   0
+#define USB_FEATURE_REMOTE_WAKEUP             1
+#define USB_FEATURE_TEST_MODE                 2
+
+
+
+#define USB_HS_MAX_PACKET_SIZE                512
+#define USB_FS_MAX_PACKET_SIZE                64
+#define USB_MAX_EP0_SIZE                      USB_FS_MAX_PACKET_SIZE
+
+/*
+ *  デバイス状態定義
+ */
+#define TUSBD_STATE_RESET                     0		/* 未実行状態 */
+#define TUSBD_STATE_INIT                      1		/* 初期化状態 */
+#define TUSBD_STATE_ADDRESSED                 2		/* アドレス設定済み状態 */
+#define TUSBD_STATE_CONFIGURED                3		/* エナミュレーション終了状態 */
+#define TUSBD_STATE_SUSPENDED                 4		/* サスペンド状態 */
+
+/*
+ *  エンドポイント#0状態
+ */
+#define TUSBD_EP0_IDLE                        0		/* アイドル状態 */
+#define TUSBD_EP0_SETUP                       1		/* SETUP状態 */
+#define TUSBD_EP0_DATAIN                      2		/* DATAIN状態 */
+#define TUSBD_EP0_DATAOUT                     3		/* DATAOUT状態 */
+#define TUSBD_EP0_STATUSIN                    4		/* STATUSIN状態 */
+#define TUSBD_EP0_STATUSOUT                   5		/* STATUSOUT状態 */
+
+/* bmAttributes in configuration descriptor */
+/* C_RESERVED must always be set */
+#define C_RESERVED                            (1<<7)
+#define C_SELF_POWERED                        (1<<6)
+#define C_REMOTE_WAKEUP                       (1<<5)
+
+/* bMaxPower in configuration descriptor */
+#define C_POWER(mA)                           ((mA)/2)
+
+/*
+ *  エンドポイント管理型
+ */
+typedef struct
+{
+	uint16_t                   status;
+	uint16_t                   maxpacket;
+	uint32_t                   xfersize;
+	uint32_t                   remlength;
+} TUSBD_Endpoint_t;
+
+/*
+ *  USBデバイスハンドラ
+ */
+typedef struct
+{
+	uint8_t                    devData[32];
+	uint8_t                    id;
+	uint8_t                    dev_speed;
+	uint8_t                    dev_address;
+	uint8_t                    dev_config;
+	uint8_t                    dev_test_mode;
+	uint8_t                    dev_remote_wakeup;
+	uint8_t                    ep0_state;
+	uint16_t                   ep0_data_len;
+	uint8_t                    dev_state;
+	uint8_t                    dev_old_state;
+	TUSBD_Endpoint_t           ep_in[TUSBD_NUM_ENDPOINT];
+	TUSBD_Endpoint_t           ep_out[TUSBD_NUM_ENDPOINT];
+
+	UsbSetupRequest            request;
+	void                       *pClassData;
+	void                       *pSysData;
+	void                       *pUsrData;
+	void                       (*makeDescriptor)(uint8_t speed);
+} TUSBD_Handle_t;
+
+#include "tusbd_conf.h"
+
+#ifndef MAX_PACKET_SIZE_HS_EPBULK
+#define MAX_PACKET_SIZE_HS_EPBULK             512
+#endif
+#ifndef MAX_PACKET_SIZE_FS_EPBULK
+#define MAX_PACKET_SIZE_FS_EPBULK             64
+#endif
+
+
+/*
+ *  関数プロトタイプ宣言
+ */
+TUSBD_ERCODE tusbdInit(TUSBD_Handle_t *pdevice, uint8_t id);
+TUSBD_ERCODE tusbdDeInit(TUSBD_Handle_t *pdevice);
+TUSBD_ERCODE tusbdStart(TUSBD_Handle_t *pdevice);
+TUSBD_ERCODE tusbdStop(TUSBD_Handle_t *pdevice);
+
+TUSBD_ERCODE tusbdSetupStage(TUSBD_Handle_t *pdevice, uint8_t *psetup);
+TUSBD_ERCODE tusbdDataOutStage(TUSBD_Handle_t *pdevice, uint8_t epnum, uint8_t *pdata);
+TUSBD_ERCODE tusbdDataInStage(TUSBD_Handle_t *pdevice, uint8_t epnum, uint8_t *pdata);
+
+TUSBD_ERCODE tusbdReset(TUSBD_Handle_t *pdevice);
+TUSBD_ERCODE tusbdSetSpeed(TUSBD_Handle_t *pdevice, uint8_t speed);
+TUSBD_ERCODE tusbdSuspend(TUSBD_Handle_t *pdevice);
+TUSBD_ERCODE tusbdResume(TUSBD_Handle_t *pdevice);
+TUSBD_ERCODE tusbdIsoInIncomplete(TUSBD_Handle_t *pdevice, uint8_t epnum);
+TUSBD_ERCODE tusbdIsoOutIncomplete(TUSBD_Handle_t *pdevice, uint8_t epnum);
+
+TUSBD_ERCODE tusbdDeviceConnected(TUSBD_Handle_t *pdevice);
+TUSBD_ERCODE tusbdDeviceDisconnected(TUSBD_Handle_t *pdevice);
+
+TUSBD_ERCODE tusbdControlSendData(TUSBD_Handle_t *pdevice, uint8_t *buf, uint16_t len);
+TUSBD_ERCODE tusbdControlReceiveStart(TUSBD_Handle_t *pdevice, uint8_t *pbuf, uint16_t len);
+TUSBD_ERCODE tusbdControlSendStatus(TUSBD_Handle_t *pdevice);
+TUSBD_ERCODE tusbdControlReceiveStatus(TUSBD_Handle_t *pdevice);
+void         tusbdControlSendStall(TUSBD_Handle_t *pdevice, UsbSetupRequest *req);
+
+#define tusbdControlContinueSendData(d, b, l)   tusbdDriverStartTransmit((d), 0x00, (b), (l))
+#define tusbdControlContinueReceive(d, b, l) tusbdDriverSetupReceive((d), 0x00, (b), (l))
+
+uint8_t      *tusbdFindDescriptor(TUSBD_Handle_t *pdevice, uint8_t type);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _TUSBD_BASE_H_ */
+
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/usb/device/tusbd_request.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/usb/device/tusbd_request.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/usb/device/tusbd_request.c	(revision 457)
@@ -0,0 +1,115 @@
+/*
+ *  TOPPERS BASE PLATFORM MIDDLEWARE
+ * 
+ *  Copyright (C) 2017-2017 by TOPPERS PROJECT
+ *                             Educational Working Group.
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+/*
+ *  USB Device Middleware REQUEST部
+ */
+
+#include "tusbd_base.h"
+
+
+/*
+ *  USB DEVICE コントロール通信 送信開始
+ *  parameter1 pdevice:  USB DEVICEハンドラ
+ *  parameter2 pbuf:     送信バッファ
+ *  parameter3 len:      送信データ長
+ *  return     TUSBD_ERCODE
+ */
+TUSBD_ERCODE
+tusbdControlSendData(TUSBD_Handle_t *pdevice, uint8_t *pbuf, uint16_t len)
+{
+	pdevice->ep0_state          = TUSBD_EP0_DATAIN;
+	pdevice->ep_in[0].xfersize  = len;
+	pdevice->ep_in[0].remlength = len;
+	return tusbdDriverStartTransmit(pdevice, 0x00, pbuf, len);
+}
+
+/*
+ *  USB DEVICE コントロール通信 受信開始
+ *  parameter1 pdevice:  USB DEVICEハンドラ
+ *  parameter2 pbuf:     受信バッファ
+ *  parameter3 len:      受信データ長
+ *  return     TUSBD_ERCODE
+ */
+TUSBD_ERCODE
+tusbdControlReceiveStart(TUSBD_Handle_t *pdevice, uint8_t *pbuf, uint16_t len)
+{
+	pdevice->ep0_state = TUSBD_EP0_DATAOUT; 
+	pdevice->ep_out[0].xfersize  = len;
+	pdevice->ep_out[0].remlength = len;
+	return tusbdDriverSetupReceive(pdevice, 0, pbuf, len);
+}
+
+/*
+ *  USB DEVICE コントロール通信 ステータス送信
+ *  parameter1 pdevice:  USB DEVICEハンドラ
+ *  return     TUSBD_ERCODE
+ */
+TUSBD_ERCODE
+tusbdControlSendStatus(TUSBD_Handle_t *pdevice)
+{
+	pdevice->ep0_state = TUSBD_EP0_STATUSIN;
+	return tusbdDriverStartTransmit(pdevice, 0x00, NULL, 0);
+}
+
+/*
+ *  USB DEVICE コントロール通信 ステータス受信
+ *  parameter1 pdevice:  USB DEVICEハンドラ
+ *  return     TUSBD_ERCODE
+ */
+TUSBD_ERCODE
+tusbdControlReceiveStatus(TUSBD_Handle_t *pdevice)
+{
+	pdevice->ep0_state = TUSBD_EP0_STATUSOUT;
+	return tusbdDriverSetupReceive(pdevice, 0, NULL, 0);
+}
+
+/*
+ *  USB DEVICE コントロール通信 STALL送信
+ *  parameter1 pdevice:  USB DEVICEハンドラ
+ *  parameter2 req:      セットアップリクエスト
+ *  return     TUSBD_ERCODE
+ */
+
+void
+tusbdControlSendStall(TUSBD_Handle_t *pdevice, UsbSetupRequest *req)
+{
+	pdevice->ep0_state = TUSBD_EP0_IDLE;
+	tusbdDriverStallEp(pdevice, req->bmRequest & 0x80);
+}
+
+
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/usb/host/BLUETOOTH/tusbh_bluetooth.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/usb/host/BLUETOOTH/tusbh_bluetooth.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/usb/host/BLUETOOTH/tusbh_bluetooth.c	(revision 457)
@@ -0,0 +1,493 @@
+/*
+ *  TOPPERS BASE PLATFORM MIDDLEWARE
+ * 
+ *  Copyright (C) 2017-2018 by TOPPERS PROJECT
+ *                             Educational Working Group.
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+/*
+ *  USB Host Middleware BLUETOOTH CLASS部
+ */
+
+#include "tusbh_bluetooth.h"
+
+#define BLUETOOTH_SENDDATA(d, b, l)   tusbhControlRequest((d), (b), BLUETOOTH_DATA_TYPE, 0, 0, 0, (l))
+#define ORDER_MASK  (BT_INTERRUPT_ORDER | BT_CTLWRITE_ORDER | BT_BLKREAD_ORDER | BT_BLKWRITE_ORDER)
+
+static TUSBH_ERCODE tusbhBLUETOOTHInit(TUSBH_Device_t *pdevice);
+static TUSBH_ERCODE tusbhBLUETOOTHeInit(TUSBH_Device_t *pdevice);
+static TUSBH_ERCODE tusbhBLUETOOTHProcess(TUSBH_Device_t *pdevice, uint8_t *mes);
+
+static TUSBH_Class_t BLUETOOTH_Class = {
+	NULL,
+	"BLUETOOTH",
+	BLUETOOTH_CLASS,
+	tusbhBLUETOOTHInit,
+	tusbhBLUETOOTHeInit,
+	tusbhBLUETOOTHProcess,
+	NULL
+};
+
+/*
+ *  SERIALクラスセットアップ関数
+ */
+void tusbhLinkBLUETOOTH(TUSBH_Handle_t *phost)
+{
+	tusbhLinkClass(phost, &BLUETOOTH_Class);
+}
+
+/*
+ *  BLUETOOTHクラス初期設定
+ *  parameter1 pdevice:  デバイスハンドラ
+ *  return     TUSBH_ERCODE
+ */
+static TUSBH_ERCODE
+tusbhBLUETOOTHInit(TUSBH_Device_t *pdevice)
+{
+	uint8_t interface = 0; 
+	BLUETOOTH_Handle_t *hblue;
+	TUSBH_Handle_t *phost = pdevice->pHost;
+	uint8_t max_ep, i;
+
+	interface = tusbhFindInterface(pdevice, pdevice->pClass->classCode, 0x01, 0x01);
+
+	if(interface == NO_INTERFACE){
+		syslog_1(LOG_ERROR, "[BLUETOOTH] Cannot Find the interface for %s class.", pdevice->pClass->Name);
+		return TUSBH_E_ERR;
+	}
+	tusbhSelectInterface(pdevice, interface);
+
+	hblue = (BLUETOOTH_Handle_t *)tusbmalloc(sizeof(BLUETOOTH_Handle_t));
+	pdevice->pData = hblue;
+	memset(hblue, 0, sizeof(BLUETOOTH_Handle_t));
+	max_ep = pdevice->ItfDesc[interface].bNumEndpoints;
+	if(max_ep < 3 || (pdevice->EpDesc[interface][0].bEndpointAddress & 0x80) == 0)
+		return TUSBH_E_ERR;
+
+	hblue->CommInEp     = pdevice->EpDesc[interface][0].bEndpointAddress;
+    hblue->CommInEpSize = pdevice->EpDesc[interface][0].wMaxPacketSize;
+	hblue->CommInPipe   = tusbhAllocPipe(phost, hblue->CommInEp);
+	hblue->poll         = pdevice->EpDesc[interface][0].bInterval;
+
+	if(hblue->poll < BT_MIN_POLL)
+		hblue->poll = BT_MIN_POLL;
+
+	for(i = 1 ; i < max_ep; i++){
+		if(pdevice->EpDesc[interface][i].bEndpointAddress & 0x80){
+			hblue->InEp     = (pdevice->EpDesc[interface][i].bEndpointAddress);
+			hblue->InEpSize = pdevice->EpDesc[interface][i].wMaxPacketSize;
+			hblue->InPipe = tusbhAllocPipe(phost, hblue->InEp);
+		}
+		else{
+			hblue->OutEp = (pdevice->EpDesc[interface][i].bEndpointAddress);
+			hblue->OutEpSize = pdevice->EpDesc[interface][i].wMaxPacketSize;
+			hblue->OutPipe = tusbhAllocPipe(phost, hblue->OutEp);
+		}
+	}
+
+	if(hblue->OutPipe == 0 || hblue->InPipe == 0)
+		return TUSBH_E_ERR;
+
+	hblue->state = BLUETOOTH_PROCESS_INIT;
+	hblue->timer = 0;
+	hblue->pDev = pdevice;
+
+	/*
+	 *  NSCチャネルオープン
+	 */
+	tusbhOpenPipe(pdevice, hblue->CommInPipe, hblue->CommInEp, USB_EP_TYPE_INTR, 64);
+	tusbhHDSetToggle(phost, hblue->CommInPipe, 0);
+	tusbhOpenPipe(pdevice, hblue->OutPipe, hblue->OutEp, USB_EP_TYPE_BULK, hblue->OutEpSize);
+	tusbhHDSetToggle(phost, hblue->OutPipe, 0);
+	tusbhOpenPipe(pdevice, hblue->InPipe, hblue->InEp, USB_EP_TYPE_BULK, hblue->InEpSize);
+	tusbhHDSetToggle(phost, hblue->InPipe, 0);
+
+	/* タイマースタート */
+	pdevice->timeid = pdevice->timecount = hblue->poll;
+	return TUSBH_E_OK;
+}
+
+/*
+ *  BLUETOOTHクラス終了設定
+ *  parameter1 pdevice:  デバイスハンドラ
+ *  return     TUSBH_ERCODE
+ */
+static TUSBH_ERCODE
+tusbhBLUETOOTHeInit(TUSBH_Device_t *pdevice)
+{
+	BLUETOOTH_Handle_t *hblue;
+	TUSBH_Handle_t *phost = pdevice->pHost;
+
+	hblue = (BLUETOOTH_Handle_t *)pdevice->pData;
+	hblue->ifstate  &= ~ORDER_MASK;
+	if(hblue->CommInPipe != 0){
+		tusbhClosePipe(pdevice, hblue->CommInPipe);
+		tusbFreePipe(phost, hblue->CommInPipe);
+		hblue->CommInPipe = 0;
+	}
+
+	if(hblue->OutPipe != 0){
+		tusbhClosePipe(pdevice, hblue->OutPipe);
+		tusbFreePipe(phost, hblue->OutPipe);
+		hblue->OutPipe = 0;
+	}
+
+	if(hblue->InPipe != 0){
+		tusbhClosePipe(pdevice, hblue->InPipe);
+		tusbFreePipe(phost, hblue->InPipe);
+		hblue->InPipe = 0;
+	}
+
+	if(pdevice->pData != NULL){
+		tusbfree(pdevice->pData);
+		pdevice->pData = NULL;
+	}
+	return TUSBH_E_OK;
+}
+
+/*
+ *  BLUETOOTHクラスプロセス実行
+ *  parameter1 pdevice:  デバイスハンドラ
+ *  parameter2 mes:      通信メッセージへのポインタ
+ *  return     TUSBH_ERCODE
+ */
+static TUSBH_ERCODE
+tusbhBLUETOOTHProcess(TUSBH_Device_t *pdevice, uint8_t *mes)
+{
+	BLUETOOTH_Handle_t *hblue  = (BLUETOOTH_Handle_t *)pdevice->pData;
+	TUSBH_Handle_t *phost = pdevice->pHost;
+	void (*func)(TUSBH_Device_t *, uint8_t, int16_t, uint8_t *) = pdevice->pClass->subfunc;
+	TUSBH_URBState_t URB_Status = mes[3];
+	TUSBH_ERCODE ercd = TUSBH_E_BUSY;
+	uint8_t mesreq = 0;
+	bool_t  timereq = false;
+
+	if(mes[0] == TUSBH_TIME_EVENT){
+		hblue->timer += mes[3];
+		pdevice->timeid = pdevice->timecount = hblue->poll;
+		timereq = true;
+	}
+	else if(mes[0] == TUSBH_CLASS_EVENT && mes[2] != 0)
+		hblue->state = mes[2];
+	switch (hblue->state){
+	case BLUETOOTH_PROCESS_INIT:
+		if(phost->usrcallback != NULL)
+			phost->usrcallback(phost, pdevice, HOST_USER_CLASS_ACTIVE);
+		hblue->state = BLUETOOTH_PROCESS_IDLE;
+	case BLUETOOTH_PROCESS_IDLE:
+		if(timereq && (hblue->ifstate & (BT_INTERRUPT_ORDER | BT_INTERRUPT_REQUEST)) == BT_INTERRUPT_ORDER){
+			tusbhInterruptRead(pdevice, &hblue->CommInBuf[0], hblue->CommInEpSize, hblue->CommInPipe);
+			hblue->ifstate |= BT_INTERRUPT_REQUEST;
+		}
+		if(mes[0] != TUSBH_URB_EVENT)
+			break;
+		if(mes[2] == hblue->CommInPipe){	/* interrupt */
+			if(URB_Status == TUSBH_URB_DONE){
+				if(func != NULL)
+					func(pdevice, HCI_EVENT_PACKET, hblue->CommInEpSize, &hblue->CommInBuf[0]);
+				hblue->ifstate &= ~BT_INTERRUPT_REQUEST;
+			}
+			else if(URB_Status == TUSBH_URB_STALL)
+				hblue->state = BLUETOOTH_PROCESS_ERROR;
+			else
+				hblue->ifstate &= ~BT_INTERRUPT_REQUEST;
+		}
+		else if(mes[2] == hblue->InPipe){	/* blk read */
+			if(URB_Status == TUSBH_URB_DONE){
+				if(func != NULL)
+					func(pdevice, HCI_ACL_DATA_PACKET, tusbhHDTrasLength(phost, hblue->InPipe), hblue->pBRecvBuff);
+			}
+			else if(URB_Status == TUSBH_URB_NOTREADY){
+				hblue->ifstate |= BT_BLKREAD_ORDER;
+				mesreq = BLUETOOTH_PROCESS_RECEIVE;
+			}
+			else if(URB_Status == TUSBH_URB_STALL)
+				hblue->state = BLUETOOTH_PROCESS_ERROR;
+			else{
+				if(func != NULL)
+					func(pdevice, HCI_ACL_DATA_PACKET, -1, hblue->pBRecvBuff);
+			}
+			hblue->ifstate &= ~BT_BLKREAD_REQUEST;
+		}
+		else if(mes[2] == hblue->OutPipe){	/* blk write */
+			if(URB_Status == TUSBH_URB_DONE){
+				hblue->BTrnLen += hblue->BTrnCLen;
+				if(hblue->BTrnLen >= hblue->BTrnSize){
+					if(func != NULL)
+						func(pdevice, HCI_SCO_DATA_PACKET, hblue->BTrnSize, NULL);
+					if((hblue->ifstate & (BT_CTLWRITE_ORDER | BT_CTLWRITE_REQUEST)) == BT_CTLWRITE_ORDER)
+						mesreq = BLUETOOTH_PROCESS_SEND;
+				}
+				else{
+					hblue->ifstate |= BT_BLKWRITE_ORDER;
+					mesreq = BLUETOOTH_PROCESS_SEND;
+				}
+			}
+			else if(URB_Status == TUSBH_URB_NOTREADY){
+				hblue->ifstate |= BT_BLKWRITE_ORDER;
+				mesreq = BLUETOOTH_PROCESS_SEND;
+			}
+			else if(URB_Status == TUSBH_URB_STALL)
+				hblue->state = BLUETOOTH_PROCESS_ERROR;
+			else{
+				if(func != NULL)
+					func(pdevice, HCI_SCO_DATA_PACKET, 0, NULL);
+				if((hblue->ifstate & (BT_CTLWRITE_ORDER | BT_CTLWRITE_REQUEST)) == BT_CTLWRITE_ORDER)
+					mesreq = BLUETOOTH_PROCESS_SEND;
+			}
+			hblue->ifstate &= ~BT_BLKWRITE_REQUEST;
+		}
+		else{								/* control write */
+			TUSBH_ERCODE status = tusbhControlWait(pdevice, mes);
+			if(status == TUSBH_E_OK){
+				hblue->ifstate &= ~BT_CTLWRITE_REQUEST;
+				if(func != NULL)
+					func(pdevice, HCI_COMMAND_DATA_PACKET, hblue->CTrnSize, hblue->pCTrnBuff);
+				if((hblue->ifstate & BT_INTERRUPT_STOP) == 0)
+					hblue->ifstate  |= BT_INTERRUPT_ORDER;
+				if((hblue->ifstate & (BT_BLKWRITE_ORDER | BT_BLKWRITE_REQUEST)) == BT_BLKWRITE_ORDER)
+					mesreq = BLUETOOTH_PROCESS_SEND;
+			}
+			else if(status != TUSBH_E_BUSY && status != TUSBH_E_BUSY_URB){
+				hblue->state = BLUETOOTH_PROCESS_ERROR;
+				hblue->ifstate  &= ~BT_CTLWRITE_REQUEST;
+			}
+		}
+		tusbSendData(phost->process_event, TUSBH_CLASS_EVENT, pdevice->idx, mesreq, 0);
+		break;
+	case BLUETOOTH_PROCESS_SEND:
+		if((hblue->ifstate & (BT_CTLWRITE_ORDER | BT_CTLWRITE_REQUEST | BT_BLKWRITE_REQUEST)) == BT_CTLWRITE_ORDER){
+			BLUETOOTH_SENDDATA(pdevice, hblue->pCTrnBuff, hblue->CTrnSize);
+			hblue->ifstate |= BT_CTLWRITE_REQUEST;
+			hblue->ifstate &= ~BT_CTLWRITE_ORDER;
+		}
+		if((hblue->ifstate & (BT_BLKWRITE_ORDER | BT_BLKWRITE_REQUEST | BT_CTLWRITE_REQUEST)) == BT_BLKWRITE_ORDER){
+			hblue->BTrnCLen = hblue->BTrnSize - hblue->BTrnLen;
+			if(hblue->BTrnCLen > hblue->OutEpSize)
+				hblue->BTrnCLen = hblue->OutEpSize;
+			tusbhBulkWrite(pdevice, &hblue->pBTrnBuff[hblue->BTrnLen], hblue->BTrnCLen, hblue->OutPipe);
+			hblue->ifstate |= BT_BLKWRITE_REQUEST;
+			hblue->ifstate &= ~BT_BLKWRITE_ORDER;
+		}
+		hblue->state = BLUETOOTH_PROCESS_IDLE;
+		break;
+	case BLUETOOTH_PROCESS_RECEIVE:
+		if((hblue->ifstate & (BT_BLKREAD_ORDER | BT_BLKREAD_REQUEST)) == BT_BLKREAD_ORDER){
+			tusbhBulkRead(pdevice, hblue->pBRecvBuff, hblue->BRecvSize, hblue->InPipe);
+			hblue->ifstate &= ~BT_BLKREAD_ORDER;
+			hblue->ifstate |= BT_BLKREAD_REQUEST;
+		}
+		hblue->state = BLUETOOTH_PROCESS_IDLE;
+		break;
+	case BLUETOOTH_PROCESS_ERROR:
+		break;
+	default:
+		break;
+	}
+	return ercd;
+}
+
+
+/*
+ *  BLUETOOTH TRANSFAR READY
+ *  parameter1 phost:   ホストハンドラ
+ *  parameter2 unit:    UNIT#
+ *  parameter3 mode:    確認モード
+ *  return     bool
+ */
+bool_t
+tusbhBluetoothTransfarReady(TUSBH_Handle_t *phost, uint8_t unit, uint8_t mode)
+{
+	TUSBH_Device_t *pdevice = tusbhSearchDevice(phost, BLUETOOTH_Class.classCode, &unit);
+	BLUETOOTH_Handle_t *hblue;
+	bool_t result = false;
+
+	if(pdevice != NULL){
+		hblue = pdevice->pData;
+		if(pdevice->dstate != DEVICE_CLASS)
+			return false;
+		if(hblue->state == BLUETOOTH_PROCESS_ERROR)
+			return false;
+	}
+	else
+		return false;
+	switch(mode){
+	case HCI_COMMAND_DATA_PACKET:
+		result = (hblue->ifstate & (BT_CTLWRITE_ORDER | BT_CTLWRITE_REQUEST)) == 0;
+		break;
+	case HCI_ACL_DATA_PACKET:
+		result = (hblue->ifstate & (BT_BLKREAD_ORDER | BT_BLKREAD_REQUEST)) == 0;
+		break;
+	case HCI_SCO_DATA_PACKET:
+		result = (hblue->ifstate & (BT_BLKWRITE_ORDER | BT_BLKWRITE_REQUEST)) == 0;
+		break;
+	case HCI_EVENT_PACKET:
+		result = (hblue->ifstate & BT_INTERRUPT_REQUEST) == 0;
+		break;
+	default:
+		break;
+	}
+	return result;
+}
+
+/*
+ *  BLUETOOTH INTERRUPT POLL TIMING
+ *  parameter1 phost:   ホストハンドラ
+ *  parameter2 unit:    UNIT#
+ *  parameter3 mode:    確認モード
+ *  return     bool
+ */
+TUSBH_ERCODE
+tusbhBluetoothInterruptPollTiming(TUSBH_Handle_t *phost, uint8_t unit, uint32_t timing)
+{
+	TUSBH_Device_t *pdevice = tusbhSearchDevice(phost, BLUETOOTH_Class.classCode, &unit);
+	BLUETOOTH_Handle_t *hblue;
+
+	if(pdevice != NULL){
+		hblue = pdevice->pData;
+		if(pdevice->dstate != DEVICE_CLASS)
+			return TUSBH_E_OBJ;
+		if(hblue->state == BLUETOOTH_PROCESS_ERROR)
+			return TUSBH_E_ERR;
+	}
+	else
+		return TUSBH_E_OBJ;
+	if(timing == 0){
+		hblue->ifstate |= BT_INTERRUPT_STOP;
+		hblue->ifstate &= ~BT_INTERRUPT_ORDER;
+	}
+	else{
+		if(timing < BT_MIN_POLL)
+			hblue->poll = BT_MIN_POLL;
+		else
+			hblue->poll = timing;
+		hblue->ifstate &= ~BT_INTERRUPT_STOP;
+		hblue->ifstate |= BT_INTERRUPT_ORDER;
+	}
+	return TUSBH_E_OK;
+}
+
+/*
+ *  BLUETOOTH DATA SEND
+ *  parameter1 phost:   ホストハンドラ
+ *  parameter2 unit:    UNIT#
+ *  parameter3 mode:    パケットタイプ
+ *  parameter4 pbuf:    送信データ領域へのポインタ(cache aline)
+ *  parameter5 length:  送信データ長
+ *  return     TUSBH_ERCODE
+ */
+TUSBH_ERCODE
+tusbhBluetoothSend(TUSBH_Handle_t *phost, uint8_t unit, uint8_t mode, uint8_t *pbuf, uint16_t length)
+{
+	TUSBH_Device_t *pdevice = tusbhSearchDevice(phost, BLUETOOTH_Class.classCode, &unit);
+	BLUETOOTH_Handle_t *hblue;
+
+	if(pdevice != NULL){
+		hblue = pdevice->pData;
+		if(pdevice->dstate != DEVICE_CLASS)
+			return TUSBH_E_OBJ;
+		if(hblue->state == BLUETOOTH_PROCESS_ERROR)
+			return TUSBH_E_ERR;
+	}
+	else
+		return TUSBH_E_OBJ;
+
+    /*
+	 *  送信データ設定
+	 */
+	if(mode == HCI_COMMAND_DATA_PACKET){
+		if(length > BT_CONTROL_SIZE)
+			return TUSBH_E_PAR;
+		if((hblue->ifstate & BT_CTLWRITE_ORDER) != 0)
+			return TUSBH_E_OBJ;
+		hblue->CTrnSize  = length;
+		hblue->pCTrnBuff = pbuf;
+		hblue->ifstate |= BT_CTLWRITE_ORDER;
+	}
+	else if(mode == HCI_SCO_DATA_PACKET){
+		if((hblue->ifstate & BT_BLKWRITE_ORDER) != 0)
+			return TUSBH_E_OBJ;
+		hblue->BTrnSize   = length;
+		hblue->BTrnLen    = 0;
+		hblue->BTrnCLen   = 0;
+		hblue->pBTrnBuff  = pbuf;
+		hblue->ifstate |= BT_BLKWRITE_ORDER;
+	}
+	else
+		return TUSBH_E_PAR;
+	tusbSendData(phost->process_event, TUSBH_CLASS_EVENT, pdevice->idx, BLUETOOTH_PROCESS_SEND, 0);
+	return TUSBH_E_OK;
+}
+
+/*
+ *  BLUETOOTH RECEIVE BULK IN
+ *  parameter1 phost:   ホストハンドラ
+ *  parameter2 unit:    UNIT#
+ *  parameter3 pbuf:    受信データ領域へのポインタ(cache aline)
+ *  parameter4 length:  受信データ長
+ *  return     TUSBH_ERCODE
+ */
+TUSBH_ERCODE
+tusbhBluetoothReceiveBulk(TUSBH_Handle_t *phost, uint8_t unit, uint8_t *pbuf, uint16_t length)
+{
+	TUSBH_Device_t *pdevice = tusbhSearchDevice(phost, BLUETOOTH_Class.classCode, &unit);
+	BLUETOOTH_Handle_t *hblue;
+
+	if(pdevice != NULL){
+		hblue = pdevice->pData;
+		if(pdevice->dstate != DEVICE_CLASS)
+			return TUSBH_E_OBJ;
+	}
+	else
+		return TUSBH_E_OBJ;
+	if(length < hblue->InEpSize)
+		return TUSBH_E_PAR;
+	hblue->BRecvSize  = length;
+	hblue->pBRecvBuff = pbuf;
+	hblue->ifstate |= BT_BLKREAD_ORDER;
+	tusbSendData(phost->process_event, TUSBH_CLASS_EVENT, pdevice->idx, BLUETOOTH_PROCESS_RECEIVE, 0);
+	return TUSBH_E_OK;
+}
+
+/*
+ *  BLUETOOTHコールバック関数
+ *  parameter1 phost:   ホストハンドラ
+ *  parameter2 func:    関数ポインタ
+ */
+void
+tusbhSetBluetoothCallBack(TUSBH_Handle_t *phost, void (*func)(TUSBH_Device_t *p, uint8_t, int16_t, uint8_t *))
+{
+	BLUETOOTH_Class.subfunc = func;
+}
+
+
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/usb/host/BLUETOOTH/tusbh_bluetooth.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/usb/host/BLUETOOTH/tusbh_bluetooth.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/usb/host/BLUETOOTH/tusbh_bluetooth.h	(revision 457)
@@ -0,0 +1,140 @@
+/*
+ *  TOPPERS BASE PLATFORM MIDDLEWARE
+ * 
+ *  Copyright (C) 2017-2018 by TOPPERS PROJECT
+ *                             Educational Working Group.
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+/*
+ *  USB Host Middleware BLUETOOTH部定義
+ */
+
+#ifndef _HUSBH_BLUETOOTH_H_
+#define _HUSBH_BLUETOOTH_H_
+
+#include "tusbh_base.h"
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+
+#define BLUETOOTH_DATA_TYPE             (USB_HOST_TO_DEVICE | USB_REQUEST_TYPE_CLASS | USB_RECIPIENT_DEVICE)
+
+
+#define HCI_COMMAND_DATA_PACKET         0x01
+#define HCI_ACL_DATA_PACKET             0x02
+#define HCI_SCO_DATA_PACKET             0x03
+#define HCI_EVENT_PACKET                0x04
+
+/*
+ *  BLUETOOTHクラスの状態定義
+ */
+#define BT_INTERRUPT_REQUEST            (1<<0)
+#define BT_CTLWRITE_REQUEST             (1<<1)
+#define BT_BLKREAD_REQUEST              (1<<2)
+#define BT_BLKWRITE_REQUEST             (1<<3)
+
+#define BT_INTERRUPT_ORDER              (1<<8)
+#define BT_CTLWRITE_ORDER               (1<<9)
+#define BT_BLKREAD_ORDER                (1<<10)
+#define BT_BLKWRITE_ORDER               (1<<11)
+#define BT_INTERRUPT_STOP               (1<<12)
+
+#ifndef BT_MIN_POLL
+#define BT_MIN_POLL                     20
+#endif
+
+#define BT_CONTROL_SIZE                 64
+
+/*
+ *  BLUETOOTHプロセスの状態定義
+ */
+enum
+{
+	BLUETOOTH_PROCESS_INIT = 0,
+	BLUETOOTH_PROCESS_IDLE,
+	BLUETOOTH_PROCESS_SEND,
+	BLUETOOTH_PROCESS_RECEIVE,
+	BLUETOOTH_PROCESS_ERROR
+};
+
+/*
+ *  BLUTOOTHハンドラ定義
+ */
+typedef struct
+{
+	TUSBH_Device_t            *pDev;
+
+	uint8_t                   state;
+	uint8_t                   poll;
+	uint16_t                  ifstate;
+
+	uint8_t                   CommInPipe;
+	uint8_t                   CommInEp;
+	uint16_t                  CommInEpSize;
+	uint8_t                   InPipe;
+	uint8_t                   OutPipe;
+	uint8_t                   OutEp;
+	uint8_t                   InEp;
+	uint16_t                  OutEpSize;
+	uint16_t                  InEpSize;
+	uint16_t                  CTrnSize;
+	uint16_t                  BTrnSize;
+	uint16_t                  BTrnLen;
+	uint16_t                  BTrnCLen;
+	uint16_t                  BRecvSize;
+	uint16_t                  dummy;
+
+	uint8_t                   CommInBuf[BT_CONTROL_SIZE];
+	uint8_t                   *pBRecvBuff;
+	uint8_t                   *pBTrnBuff;
+	uint8_t                   *pCTrnBuff;
+	uint32_t                  timer;
+} BLUETOOTH_Handle_t;
+
+
+void         tusbhLinkBLUETOOTH(TUSBH_Handle_t *phost);
+bool_t       tusbhBluetoothTransfarReady(TUSBH_Handle_t *phost, uint8_t unit, uint8_t mode);
+TUSBH_ERCODE tusbhBluetoothInterruptPollTiming(TUSBH_Handle_t *phost, uint8_t unit, uint32_t timing);
+TUSBH_ERCODE tusbhBluetoothSend(TUSBH_Handle_t *phost, uint8_t unit, uint8_t mode, uint8_t *pbuf, uint16_t length);
+TUSBH_ERCODE tusbhBluetoothReceiveBulk(TUSBH_Handle_t *phost, uint8_t unit, uint8_t *pbuf, uint16_t length);
+void tusbhSetBluetoothCallBack(TUSBH_Handle_t *phost, void (*func)(TUSBH_Device_t *p, uint8_t, int16_t, uint8_t *));
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _HUSBH_BLUETOOTH_H_ */
+
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/usb/host/HID/tusbh_hid.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/usb/host/HID/tusbh_hid.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/usb/host/HID/tusbh_hid.c	(revision 457)
@@ -0,0 +1,402 @@
+/*
+ *  TOPPERS BASE PLATFORM MIDDLEWARE
+ * 
+ *  Copyright (C) 2017-2017 by TOPPERS PROJECT
+ *                             Educational Working Group.
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+/*
+ *  USB Host Middleware HID CLASS部
+ */
+
+#include "tusbh_hid.h"
+
+
+#define HID_SETIDLE(d, dur, rep)     tusbhControlRequest((d), NULL, HID_SET_TYPE, USB_HID_SET_IDLE, ((dur << 8) | (rep)), 0, 0)
+#define HID_SETPROTOCOL(d, p)        tusbhControlRequest((d), NULL, HID_SET_TYPE, USB_HID_SET_PROTOCOL, (((p) != 0) ? 0 : 1), 0, 0)
+#define HID_GETREPORT(d, t, i, b, l) tusbhControlRequest((d), (b), HID_GET_TYPE, USB_HID_GET_REPORT, ((t << 8 ) | i), 0, (l))
+#define HID_SETREPORT(d, t, i, b, l) tusbhControlRequest((d), (b), HID_SET_TYPE, USB_HID_SET_REPORT, ((t << 8 ) | i), 0, (l))
+
+static TUSBH_ERCODE tusbhHIDInit(TUSBH_Device_t *pdevice);
+static TUSBH_ERCODE tusbhHIDDeInit(TUSBH_Device_t *pdevice);
+static TUSBH_ERCODE tusbdHIDProcess(TUSBH_Device_t *pdevice, uint8_t *mes);
+
+TUSBH_Class_t HID_Class = {
+	NULL,
+	"HID",
+	HID_CLASS,
+	tusbhHIDInit,
+	tusbhHIDDeInit,
+	tusbdHIDProcess,
+	NULL
+};
+
+/*
+ *  HIDクラスセットアップ関数
+ */
+void tusbhLinkHID(TUSBH_Handle_t *phost)
+{
+	tusbhLinkClass(phost, &HID_Class);
+}
+
+/*
+ *  HIDクラス初期設定
+ *  parameter1 pdevice:  デバイスハンドラ
+ *  return     TUSBH_ERCODE
+ */
+static TUSBH_ERCODE
+tusbhHIDInit(TUSBH_Device_t *pdevice)
+{
+	TUSBH_Handle_t *phost = pdevice->pHost;
+	uint8_t max_ep;
+	uint8_t interface;
+	TUSBH_ERCODE status = TUSBH_E_ERR;
+	HID_Handle_t *hhid;
+
+	interface = tusbhFindInterface(pdevice, pdevice->pClass->classCode, HID_BOOT_CODE, 0xFF);
+
+	if(interface == NO_INTERFACE){
+		syslog_1(LOG_ERROR, "[HID] Cannot Find the interface for %s class !", pdevice->pClass->Name);
+		return TUSBH_E_ERR;
+	}
+
+	tusbhSelectInterface(pdevice, interface);
+	pdevice->pData = tusbmalloc(sizeof(HID_Handle_t));
+	hhid = (HID_Handle_t *)pdevice->pData;
+	memset(hhid, 0, sizeof(HID_Handle_t));
+	hhid->state = THID_ERROR;
+
+	/*
+	 *  デバイスの検索
+	 */
+	if(pdevice->ItfDesc[pdevice->sel_interface].bInterfaceProtocol == HID_KEYBRD_BOOT_CODE){
+		syslog_0(LOG_NOTICE, "[HID] found KeyBoard device !"); 
+		hhid->type =  HID_KEYBOARD_TYPE;
+	}
+	else if(pdevice->ItfDesc[pdevice->sel_interface].bInterfaceProtocol == HID_MOUSE_BOOT_CODE){
+		syslog_0(LOG_NOTICE, "[HID] found Mouse device !");
+		hhid->type =  HID_MOUSE_TYPE;
+	}
+	else{
+		syslog_0(LOG_ERROR, "[HID] no device !");
+		return TUSBH_E_ERR;
+	}
+
+	hhid->ep_addr   = pdevice->EpDesc[pdevice->sel_interface][0].bEndpointAddress;
+	hhid->length    = pdevice->EpDesc[pdevice->sel_interface][0].wMaxPacketSize;
+	hhid->poll      = pdevice->EpDesc[pdevice->sel_interface][0].bInterval ;
+
+	if(hhid->poll < HID_MIN_POLL)
+		hhid->poll = HID_MIN_POLL;
+
+	max_ep = pdevice->ItfDesc[pdevice->sel_interface].bNumEndpoints;
+	if(max_ep == 0 || (pdevice->EpDesc[pdevice->sel_interface][0].bEndpointAddress & 0x80) == 0)
+		return TUSBH_E_ERR;
+
+#if 1	/* ROI DEBUG */
+	syslog_3(LOG_NOTICE, "## max_ep(%d) length(%d) poll(%d) ##", max_ep, hhid->length, hhid->poll);
+#endif	/* ROI DEBUG */
+	if(hhid->length > HID_MAX_REPORT_LENGTH)
+		hhid->length = HID_MAX_REPORT_LENGTH;
+
+	/*
+	 *  インターラプト インエンドポイント オープン
+	 */
+	hhid->InPipe  = tusbhAllocPipe(phost, hhid->ep_addr);
+	tusbhOpenPipe(pdevice, hhid->InPipe, hhid->ep_addr, USB_EP_TYPE_INTR, hhid->length);
+	tusbhHDSetToggle(phost, hhid->InPipe, 0);
+
+	/*
+	 *  HID DESCRIPTOR取得
+	 */
+	if(tusbhGetDescriptor(pdevice, (USB_RECIPIENT_INTERFACE | USB_REQUEST_TYPE_STANDARD),
+						((HID_DESCRIPTOR << 8) & 0xFF00), pdevice->Data, HID_DESCRIPTOR_LENGTH) != TUSBH_E_OK)
+		return TUSBH_E_ERR;
+	hhid->ReportDescLength  = (pdevice->Data[7] & 0xff) | (pdevice->Data[8] << 8);
+	syslog_1(LOG_NOTICE, "## hhid->DescLength(%d) ##", hhid->ReportDescLength);
+	if(hhid->ReportDescLength > 64)
+		hhid->ReportDescLength = 64;
+
+	/*
+	 *  HID REPORT DESCRIPTOR取得
+	 */
+	if(tusbhGetDescriptor(pdevice, (USB_RECIPIENT_INTERFACE | USB_REQUEST_TYPE_STANDARD),
+						((HID_REPORT_DESCRIPTOR << 8) & 0xFF00), pdevice->Data, hhid->ReportDescLength) != TUSBH_E_OK)
+		return TUSBH_E_ERR;
+	tusbmemcpy(hhid->ReportDesc, pdevice->Data, hhid->ReportDescLength);
+	syslog_1(LOG_NOTICE, "## hhid->ReportDesc[%08x] ##", hhid->ReportDesc);
+
+	/*
+	 *  IDEL設定
+	 */
+	status = HID_SETIDLE(pdevice, 0, 0);
+	if(status != TUSBH_E_OK && status != TUSBH_E_NOSPT)
+		return status;
+
+	/*
+	 *  PROTOCOL #0 設定
+	 */
+	if((status = HID_SETPROTOCOL(pdevice, 0)) != TUSBH_E_OK)
+		return status;
+
+	/* タイマースタート */
+	hhid->state     = THID_INIT;
+	pdevice->timeid = pdevice->timecount = hhid->poll;
+	return TUSBH_E_OK;
+}
+
+/*
+ *  HUBクラス終了設定
+ *  parameter1 pdevice:  デバイスハンドラ
+ *  return     TUSBH_ERCODE
+ */
+static TUSBH_ERCODE
+tusbhHIDDeInit(TUSBH_Device_t *pdevice)
+{
+	TUSBH_Handle_t *phost = pdevice->pHost;
+	HID_Handle_t *hhid;
+
+	hhid =  (HID_Handle_t *)pdevice->pData;
+	if(hhid->InPipe != 0x00){
+		tusbhClosePipe(pdevice, hhid->InPipe);
+		tusbFreePipe(phost, hhid->InPipe);
+		hhid->InPipe = 0;
+	}
+
+	if(pdevice->pData != NULL){
+		tusbfree(pdevice->pData);
+		pdevice->pData = NULL;
+	}
+	return TUSBH_E_OK;
+}
+
+
+/*
+ *  HIDクラスプロセス実行
+ *  parameter1 pdevice:  デバイスハンドラ
+ *  parameter2 mes:      通信メッセージへのポインタ
+ *  return     TUSBH_ERCODE
+ */
+static TUSBH_ERCODE
+tusbdHIDProcess(TUSBH_Device_t *pdevice, uint8_t *mes)
+{
+	TUSBH_ERCODE status = TUSBH_E_OK, status2;
+	HID_Handle_t *hhid = (HID_Handle_t *)pdevice->pData;
+	TUSBH_URBState_t URB_Status = mes[3];
+	TUSBH_Handle_t *phost = pdevice->pHost;
+	void (*func)(TUSBH_Device_t *, uint8_t, uint8_t *) = pdevice->pClass->subfunc;
+
+	switch (hhid->state){
+	case THID_INIT:
+		if(phost->usrcallback != NULL)
+			phost->usrcallback(phost, pdevice, HOST_USER_CLASS_ACTIVE);
+	case THID_IDLE:
+		hhid->ReportType = 0x01;
+		hhid->ReportId   = 0;
+		HID_GETREPORT(pdevice, hhid->ReportType, hhid->ReportId, hhid->buffer, hhid->length);
+		hhid->state = THID_GETREPORT_WAIT;
+		break;
+	case THID_GETREPORT_WAIT:
+		if((status2 = tusbhControlWait(pdevice, mes)) == TUSBH_E_OK){
+			hhid->ReportLength = hhid->length;
+			tusbmemcpy(hhid->Report, hhid->buffer, hhid->ReportLength);
+			if(func != NULL)
+				func(pdevice, 0, hhid->Report);
+			syslog_2(LOG_NOTICE, "## THID_GETREPORT_WAIT hhid->Report[%08x] (%d) ##", hhid->Report, hhid->ReportLength);
+			hhid->state = THID_GET_DATA;
+			pdevice->timeid    = hhid->poll;
+			pdevice->timecount = hhid->poll;
+		}
+		else if(status2 == TUSBH_E_NOSPT){
+			if(func != NULL)
+				func(pdevice, 0, 0);
+			hhid->state = THID_GET_DATA;
+			pdevice->timeid    = hhid->poll;
+			pdevice->timecount = hhid->poll;
+		}
+		else if(status2 != TUSBH_E_BUSY && status2 != TUSBH_E_BUSY_URB){
+			syslog_1(LOG_NOTICE, "## tusbdHIDProcess ERROR status(%d) ##", status2);
+			hhid->state = THID_ERROR;
+		}
+		break;
+	case THID_SETREPORT:
+		tusbmemcpy(hhid->buffer, hhid->Report, hhid->ReportLength);
+		HID_SETREPORT(pdevice, hhid->ReportType, hhid->ReportId, hhid->buffer, hhid->ReportLength);
+		hhid->state = THID_SETREPORT_WAIT;
+		break;
+	case THID_SETREPORT_WAIT:
+		if((status2 = tusbhControlWait(pdevice, mes)) == TUSBH_E_OK){
+			syslog_2(LOG_NOTICE, "## THID_SETREPORT_WAIT(1) hhid->Report[%08x] (%d) ##", hhid->Report, hhid->ReportLength);
+			hhid->state = THID_GET_DATA;
+			pdevice->timeid    = hhid->poll;
+			pdevice->timecount = hhid->poll;
+		}
+		else if(status2 == TUSBH_E_NOSPT){
+			syslog_2(LOG_NOTICE, "## THID_SETREPORT_WAIT(2) hhid->Report[%08x] (%d) ##", hhid->Report, hhid->ReportLength);
+			hhid->state = THID_GET_DATA;
+			pdevice->timeid    = hhid->poll;
+			pdevice->timecount = hhid->poll;
+		}
+		else if(status2 != TUSBH_E_BUSY && status2 != TUSBH_E_BUSY_URB){
+			syslog_1(LOG_NOTICE, "## tusbdHIDProcess ERROR status(%d) ##", status2);
+			hhid->state = THID_ERROR;
+		}
+		break;
+	case THID_GET_DATA:
+		if(pdevice->is_connected == 0)
+			break;
+		if(hhid->ReqReport == 0xFF){
+			hhid->state = THID_SETREPORT;
+			tusbSendData(phost->process_event, TUSBH_CLASS_EVENT, pdevice->idx, 0, 0);
+			break;
+		}
+		tusbhInterruptRead(pdevice, hhid->buffer, hhid->length, hhid->InPipe);
+		hhid->state = THID_POLL;
+		hhid->DataReady = 0;
+		break;
+	case THID_POLL:
+		if(mes[0] != TUSBH_URB_EVENT)
+			break;
+		if(URB_Status == TUSBH_URB_DONE){
+			if(hhid->DataReady == 0){
+        		hhid->DataReady = 1;
+				if(func != NULL)
+					func(pdevice, hhid->length, hhid->buffer);
+				pdevice->timeid    = hhid->poll;
+				pdevice->timecount = hhid->poll;
+				hhid->state = THID_GET_DATA;
+			}
+		}
+		else if(URB_Status == TUSBH_URB_STALL){
+			/*
+			 *  STALLならCLEAR FEATURE実行
+			 */
+			if(tusbhClearFeature(pdevice, hhid->ep_addr) == TUSBH_E_OK){
+				/* Change state to issue next IN token */
+				hhid->state =THID_CLEARFEATURE_WAIT;
+			}
+		}
+		else{
+			pdevice->timeid    = hhid->poll;
+			pdevice->timecount = hhid->poll;
+			hhid->state = THID_GET_DATA;
+		}
+		break;
+	case THID_CLEARFEATURE_WAIT:
+		if((status2 = tusbhControlWait(pdevice, mes)) == TUSBH_E_OK){
+			hhid->state = THID_GET_DATA;
+			pdevice->timeid    = hhid->poll;
+			pdevice->timecount = hhid->poll;
+		}
+		else if(status2 == TUSBH_E_NOSPT){
+			hhid->state = THID_GET_DATA;
+			pdevice->timeid    = hhid->poll;
+			pdevice->timecount = hhid->poll;
+		}
+		else if(status2 != TUSBH_E_BUSY && status2 != TUSBH_E_BUSY_URB){
+			syslog_1(LOG_ERROR, "tusbdHIDProcess ERROR status(%d) !", status2);
+			hhid->state = THID_ERROR;
+		}
+		break;
+
+	default:
+		break;
+	}
+	return status;
+}
+
+/*
+ *  HIDデバイスリポート設定
+ *  parameter1 hhid:    HIDハンドラ
+ *  parameter2 type:    report type
+ *  parameter3 id:      report id
+ *  parameter4 pbuf:    report data
+ *  parameter5 len:     report data length
+ *  return     TUSBH_ERCODE
+ */
+TUSBH_ERCODE
+tubhHidSetReport(HID_Handle_t *hhid, uint8_t type, uint8_t id, uint8_t* pbuf, uint8_t len)
+{
+	hhid->ReportType   = type;
+	hhid->ReportId     = id;
+	hhid->ReportLength = len;
+	tusbmemcpy(hhid->Report, pbuf, hhid->ReportLength);
+	hhid->ReqReport = 0xFF;
+	while(hhid->ReqReport == 0xFF){
+		tusbSleep(10);
+	}
+	return (TUSBH_ERCODE)hhid->ReqReport;
+}
+
+/*
+ *  HIDデバイスタイプ取得
+ *  parameter1 hhid:    HIDハンドラ
+ *  return     poll     デバイスタイプ
+ */
+uint8_t
+tusbhHidGetType(TUSBH_Device_t *pdevice)
+{
+	HID_Handle_t *hhid = (HID_Handle_t *)pdevice->pData;
+
+	if(hhid == NULL)
+		return HID_UNKNOWN_TYPE;
+	else
+		return hhid->type;
+}
+
+
+/*
+ *  HIDポーリングインターバル時間取得
+ *  parameter1 hhid:    HIDハンドラ
+ *  return     poll     インターバル時間(ms)
+ */
+uint8_t
+tusbhHidGetPollInterval(TUSBH_Device_t *pdevice)
+{
+	HID_Handle_t *hhid = (HID_Handle_t *)pdevice->pData;
+
+	if(hhid == NULL)
+		return 0;
+	else
+		return hhid->poll;
+}
+
+/*
+ *  HID コールバック関数設定
+ */
+void
+tusbhSetHidCallBack(TUSBH_Handle_t *phost, void (*func)(TUSBH_Device_t *pdevice, uint8_t, uint8_t *))
+{
+	HID_Class.subfunc = func;
+}
+
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/usb/host/HID/tusbh_hid.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/usb/host/HID/tusbh_hid.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/usb/host/HID/tusbh_hid.h	(revision 457)
@@ -0,0 +1,134 @@
+/*
+ *  TOPPERS BASE PLATFORM MIDDLEWARE
+ * 
+ *  Copyright (C) 2017-2017 by TOPPERS PROJECT
+ *                             Educational Working Group.
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+/*
+ *  USB Host Middleware HID部定義
+ */
+
+#ifndef _HUSBH_HID_H_
+#define _HUSBH_HID_H_
+
+#include "tusbh_base.h"
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+
+#define HID_MIN_POLL            10
+#define HID_MAX_REPORT_LENGTH   8
+
+#define HID_MOUSE_TYPE          1
+#define HID_KEYBOARD_TYPE       2
+#define HID_UNKNOWN_TYPE        0xFF
+
+/*
+ *  HID BOOT Interface Descriptor field values
+ */
+#define HID_BOOT_CODE           0x01
+#define HID_KEYBRD_BOOT_CODE    0x01
+#define HID_MOUSE_BOOT_CODE     0x02
+
+
+/*
+ *  HIDクラス要求ID
+ */
+#define USB_HID_GET_REPORT      0x01
+#define USB_HID_GET_IDLE        0x02
+#define USB_HID_GET_PROTOCOL    0x03
+#define USB_HID_SET_REPORT      0x09
+#define USB_HID_SET_IDLE        0x0A
+#define USB_HID_SET_PROTOCOL    0x0B
+
+#define HID_SET_TYPE            (USB_HOST_TO_DEVICE | USB_REQUEST_TYPE_CLASS | USB_RECIPIENT_INTERFACE)
+#define HID_GET_TYPE            (USB_HOST_TO_DEVICE | USB_REQUEST_TYPE_CLASS | USB_RECIPIENT_INTERFACE | USB_RECIPIENT_ENDPOINT)
+
+/*
+ *  HID状態定義
+ */
+enum {
+	THID_INIT = 0,
+	THID_IDLE,
+	THID_GETREPORT_WAIT,
+	THID_SETREPORT,
+	THID_SETREPORT_WAIT,
+	THID_GET_DATA,
+	THID_POLL,
+	THID_CLEARFEATURE_WAIT,
+	THID_ERROR
+};
+
+
+/*
+ *  HIDハンドラ定義
+ */
+typedef struct
+{
+	uint8_t                   buffer[32];
+	uint8_t                   type;
+	uint8_t                   InPipe;
+	uint8_t                   state;
+	uint8_t                   ep_addr;
+	uint8_t                   DataReady;
+	uint8_t                   ReqReport;
+	uint16_t                  length;
+	uint16_t                  poll;
+	uint32_t                  timer;
+	uint16_t                  ReportDescLength;
+	uint8_t                   ReportDesc[66];
+	uint8_t                   ReportType;
+	uint8_t                   ReportId;
+	uint16_t                  ReportLength;
+	uint8_t                   Report[32];
+} HID_Handle_t;
+
+
+void    tusbhLinkHID(TUSBH_Handle_t *phost);
+
+TUSBH_ERCODE tubhHidSetReport(HID_Handle_t *hhid, uint8_t type, uint8_t id, uint8_t* pbuf, uint8_t len);
+uint8_t tusbhHidGetType(TUSBH_Device_t *pdevice);
+uint8_t tusbhHidGetPollInterval(TUSBH_Device_t *hdevice);
+void    tusbhSetHidCallBack(TUSBH_Handle_t *phost, void (*func)(TUSBH_Device_t *, uint8_t, uint8_t *));
+
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _HUSBH_HID_H_ */
+
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/usb/host/HUB/tusbh_hub.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/usb/host/HUB/tusbh_hub.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/usb/host/HUB/tusbh_hub.c	(revision 457)
@@ -0,0 +1,370 @@
+/*
+ *  TOPPERS BASE PLATFORM MIDDLEWARE
+ * 
+ *  Copyright (C) 2017-2017 by TOPPERS PROJECT
+ *                             Educational Working Group.
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+/*
+ *  USB Host Middleware HUB CLASS部
+ */
+
+#include "tusbh_hub.h"
+
+#define CLASS_GETDESC_TYPE          (USB_DEVICE_TO_HOST | USB_REQUEST_TYPE_CLASS)
+#define PORT_POWER_FEATURE(d, p)    tusbhControlRequest((d), NULL, PORT_SETFEATURE_TYPE, SET_FEATURE, PORT_POWERFEATURE, (p), 0)
+#define PORT_RESET_FEATURE(d, p)    tusbhControlRequest((d), NULL, PORT_SETFEATURE_TYPE, SET_FEATURE, PORT_RESETFEATURE, (p), 0)
+#define PORT_CLEAR_FEATURE(d, f, p) tusbhControlRequest((d), NULL, PORT_CLEARFEATURE_TYPE, CLEAR_FEATURE, (f), (p), 0)
+#define PORT_GET_STATUS(d, b, p)    tusbhControlRequest((d), (b), PORT_GETSTATUS_TYPE, GET_STATUS, 0, (p), 4)
+
+#define GET_PORT(i)                 (i+1)
+
+
+static TUSBH_ERCODE tusbhHUBInit(TUSBH_Device_t *pdevice);
+static TUSBH_ERCODE tusbhHUBDeInit(TUSBH_Device_t *pdevice);
+static TUSBH_ERCODE tusbhHUBProcess(TUSBH_Device_t *pdevice, uint8_t *mes);
+
+static TUSBH_Class_t HUB_Class = {
+	NULL,
+	"HUB",
+	HUB_CLASS,
+	tusbhHUBInit,
+	tusbhHUBDeInit,
+	tusbhHUBProcess,
+	NULL
+};
+
+/*
+ *  HUBクラスセットアップ関数
+ */
+void tusbhLinkHUB(TUSBH_Handle_t *phost)
+{
+	tusbhLinkClass(phost, &HUB_Class);
+}
+
+
+/*
+ *  HUBクラス初期設定
+ *  parameter1 pdevice:  デバイスハンドラ
+ *  return     TUSBH_ERCODE
+ */
+static TUSBH_ERCODE
+tusbhHUBInit(TUSBH_Device_t *pdevice)
+{
+	uint8_t interface = 0; 
+	HUB_Handle_t *hhub;
+	TUSBH_Handle_t *phost = pdevice->pHost;
+	uint8_t max_ep, i;
+
+	interface = tusbhFindInterface(pdevice, pdevice->pClass->classCode, 0, 0);
+
+	if(interface == NO_INTERFACE){
+		syslog_1(LOG_ERROR, "[HUB] Cannot Find the interface for %s class.", pdevice->pClass->Name);
+		return TUSBH_E_ERR;
+	}
+
+	tusbhSelectInterface(pdevice, interface);
+	hhub = (HUB_Handle_t *)tusbmalloc(sizeof(HUB_Handle_t));
+	pdevice->pData = hhub;
+	memset(hhub, 0, sizeof(HUB_Handle_t));
+	hhub->hubid     = ++phost->numHub;
+	pdevice->hubid  = hhub->hubid;
+	hhub->state     = THUB_IDLE;
+	hhub->cstate    = THUB_CONNCET_IDEL;
+	hhub->ep_addr   = pdevice->EpDesc[pdevice->sel_interface][0].bEndpointAddress;
+	hhub->length    = pdevice->EpDesc[pdevice->sel_interface][0].wMaxPacketSize;
+	hhub->poll      = pdevice->EpDesc[pdevice->sel_interface][0].bInterval;
+
+	max_ep = pdevice->ItfDesc[pdevice->sel_interface].bNumEndpoints;
+	if(max_ep == 0 || (pdevice->EpDesc[pdevice->sel_interface][0].bEndpointAddress & 0x80) == 0)
+		return TUSBH_E_ERR;
+
+
+	syslog_4(LOG_NOTICE, "## max_ep(%d) length(%d) poll(%d) b(%d) ##", max_ep, hhub->length, hhub->poll, offsetof(HUB_Handle_t, buffer));
+	hhub->InPipe  = tusbhAllocPipe(phost, hhub->ep_addr);
+
+	/*
+	 *  IN ENDPOINT OPEN
+	 */
+	tusbhOpenPipe(pdevice, hhub->InPipe, hhub->ep_addr, USB_EP_TYPE_INTR, hhub->length);
+	tusbhHDSetToggle(phost, hhub->InPipe, 0);
+
+	if(tusbhGetDescriptor(pdevice, CLASS_GETDESC_TYPE, (0x29 << 8), hhub->buffer, sizeof(HubDescriptor)) != TUSBH_E_OK)
+		return TUSBH_E_ERR;
+	hhub->numport         = hhub->buffer[2];
+	hhub->characteristics = hhub->buffer[3];
+	hhub->starttime       = hhub->buffer[5] * 2;
+	syslog_1(LOG_NOTICE, "## hhub->numport(%d) ##", hhub->numport);
+
+	for(i = 0 ; i < hhub->numport ; i++){
+		PORT_POWER_FEATURE(pdevice, GET_PORT(i));
+	}
+
+	/* タイマースタート */
+	hhub->timer = 0;
+	pdevice->timeid = pdevice->timecount = hhub->poll;
+	return TUSBH_E_OK;
+}
+
+/*
+ *  HUBクラス終了設定
+ *  parameter1 pdevice:  デバイスハンドラ
+ *  return     TUSBH_ERCODE
+ */
+static TUSBH_ERCODE
+tusbhHUBDeInit(TUSBH_Device_t *pdevice)
+{
+	HUB_Handle_t *hhub = (HUB_Handle_t *)pdevice->pData;
+	TUSBH_Handle_t *phost = pdevice->pHost;
+
+	if(hhub->InPipe != 0){
+		tusbhClosePipe(pdevice, hhub->InPipe);
+		tusbFreePipe(phost, hhub->InPipe);
+		hhub->InPipe = 0;
+	}
+	if(phost->numHub > 0)
+		phost->numHub--;
+
+	if(pdevice->pData != NULL){
+		tusbfree(pdevice->pData);
+		pdevice->pData = NULL;
+	}
+	return TUSBH_E_OK;
+}
+
+/*
+ *  HUBクラスプロセス実行
+ *  parameter1 pdevice:  デバイスハンドラ
+ *  parameter2 mes:      通信メッセージへのポインタ
+ *  return     TUSBH_ERCODE
+ */
+static TUSBH_ERCODE
+tusbhHUBProcess(TUSBH_Device_t *pdevice, uint8_t *mes)
+{
+	HUB_Handle_t   *hhub;
+	TUSBH_Handle_t *phost = pdevice->pHost;
+	TUSBH_Device_t *pdevicep;
+	TUSBH_ERCODE   status = TUSBH_E_OK;
+	TUSBH_URBState_t URB_Status = mes[3];
+	uint32_t pstatus = 0;
+	uint32_t i;
+
+	hhub = (HUB_Handle_t *)pdevice->pData;
+	if(mes[0] == TUSBH_TIME_EVENT)
+		hhub->timer += mes[3];
+	else if(mes[0] == TUSBH_RESET_EVENT)
+		hhub->reset_portid = mes[3];
+	switch (hhub->state){
+	case THUB_IDLE:
+		if(phost->usrcallback != NULL)
+			phost->usrcallback(phost, pdevice, HOST_USER_CLASS_ACTIVE);
+		hhub->state = THUB_SYNC;
+	case THUB_SYNC:
+		if(hhub->timer < hhub->starttime){
+			pdevice->timecount = hhub->poll;
+			break;
+		}
+		hhub->portno = 0;
+		hhub->cstate = THUB_CONNCET_IDEL;
+		if(hhub->reset_portid > 0){
+			PORT_RESET_FEATURE(pdevice, hhub->reset_portid);
+			hhub->state = THUB_PORT_RESET_WAIT;
+			hhub->reset_portid = 0;
+		}
+	case THUB_GET_DATA:
+		tusbhInterruptRead(pdevice, hhub->buffer, hhub->length, hhub->InPipe);
+		hhub->state = THUB_POLL;
+		break;
+	case THUB_POLL:
+		if(mes[0] != TUSBH_URB_EVENT)
+			 break;
+		if(URB_Status == TUSBH_URB_DONE){
+			PORT_GET_STATUS(pdevice, hhub->buffer, GET_PORT(hhub->portno));
+			hhub->state = THUB_GET_STATUS_WAIT;
+		}
+		else if(URB_Status == TUSBH_URB_STALL){ /* IN Endpoint Stalled */
+			hhub->state = THUB_PORT_ERROR;
+			tusbSendData(phost->process_event, TUSBH_CLASS_EVENT, pdevice->idx, 0, 0);
+		}
+		else{
+			hhub->state = THUB_GET_DATA;
+			pdevice->timecount = hhub->poll;
+		}
+		break;
+	case THUB_GET_STATUS_WAIT:
+		if((status = tusbhControlWait(pdevice, mes)) == TUSBH_E_OK){
+			uint8_t speed;
+			pstatus  = hhub->buffer[0];
+			pstatus |= hhub->buffer[1] << 8;
+			pstatus |= hhub->buffer[2] << 16;
+			pstatus |= hhub->buffer[3] << 24;
+#if 1	/* ROI DEBUG */
+			if((pstatus & 0xffff0000) != 0)
+				syslog_2(LOG_NOTICE, "## PSTATUS port(%d) status[%08x] ##", hhub->portno, pstatus);
+#endif	/* ROI DEBUG */
+
+			if((pstatus & PORT_CHANGE_CONNECTION) != 0){
+				if((pstatus & PORT_STATUS_CONNECTION) != 0)
+					hhub->cstate = THUB_CONNECT_RESET;
+				else
+					tusbSendData(phost->connect_event, TUSBH_DISCONNECT_EVENT, hhub->hubid, GET_PORT(hhub->portno), 0);
+				PORT_CLEAR_FEATURE(pdevice, PORT_CLEAR_CONNECTION_FEATURE, GET_PORT(hhub->portno));
+				hhub->state = THUB_CLEAR_FEATURE_WAIT;
+			}
+			else if((pstatus & PORT_CHANGE_RESET) != 0){
+				PORT_CLEAR_FEATURE(pdevice, PORT_CLEAR_RESET_FEATURE, GET_PORT(hhub->portno));
+				hhub->state = THUB_CLEAR_FEATURE_WAIT;
+				if(hhub->cstate == THUB_CONNECT_RESET){
+					if((pstatus & (PORT_STATUS_CONNECTION | PORT_STATUS_ENABLE)) == (PORT_STATUS_CONNECTION | PORT_STATUS_ENABLE)){
+						hhub->cstate = THUB_CONNECT_ENABLE;
+						if((pstatus & PORT_STATUS_LOW_SPEED) != 0)
+							speed = USB_DEVICE_SPEED_LOW;
+						else
+							speed = USB_DEVICE_SPEED_FULL;
+						tusbSendData(phost->connect_event, TUSBH_CONNECT_EVENT, hhub->hubid, GET_PORT(hhub->portno), speed);
+					}
+				}
+			}
+			else if((pstatus & PORT_CHANGE_ENABLE) != 0){
+				PORT_CLEAR_FEATURE(pdevice, PORT_CLEAR_ENABLE_FEATURE, GET_PORT(hhub->portno));
+				hhub->state = THUB_CLEAR_FEATURE_WAIT;
+				if(hhub->cstate == THUB_CONNECT_RESET){
+					if((pstatus & (PORT_STATUS_CONNECTION | PORT_STATUS_ENABLE)) == (PORT_STATUS_CONNECTION | PORT_STATUS_ENABLE)){
+						hhub->cstate = THUB_CONNECT_ENABLE;
+						if((pstatus & PORT_STATUS_LOW_SPEED) != 0)
+							speed = USB_DEVICE_SPEED_LOW;
+						else
+							speed = USB_DEVICE_SPEED_FULL;
+						tusbSendData(phost->connect_event, TUSBH_CONNECT_EVENT, hhub->hubid, GET_PORT(hhub->portno), speed);
+					}
+				}
+			}
+			else if((pstatus & PORT_CHANGE_OVER_CURRENT) != 0){
+				tusbSendData(phost->connect_event, TUSBH_DISCONNECT_EVENT, hhub->hubid, GET_PORT(hhub->portno), 0);
+				PORT_CLEAR_FEATURE(pdevice, PORT_OVER_CURRENT_FEATURE, GET_PORT(hhub->portno));
+				hhub->state = THUB_CLEAR_FEATURE_WAIT;
+			}
+//			else if(hhub->connect != 0){
+			else if(hhub->cstate != THUB_CONNCET_IDEL){
+				hhub->state = THUB_GET_DATA;
+				pdevice->timecount = hhub->poll;
+			}
+			else if(++hhub->portno < hhub->numport){
+				PORT_GET_STATUS(pdevice, hhub->buffer, GET_PORT(hhub->portno));
+				hhub->state = THUB_GET_STATUS_WAIT;
+			}
+			else{
+				hhub->state = THUB_SYNC;
+				pdevice->timecount = hhub->poll;
+			}
+		}
+		else if(status != TUSBH_E_BUSY && status != TUSBH_E_BUSY_URB){
+			hhub->state = THUB_PORT_ERROR;
+			tusbSendData(phost->process_event, TUSBH_CLASS_EVENT, pdevice->idx, 0, 0);
+		}
+		break;
+	case THUB_CLEAR_FEATURE_WAIT:
+		if((status = tusbhControlWait(pdevice, mes)) == TUSBH_E_OK){
+			if(hhub->cstate == THUB_CONNECT_RESET){
+				PORT_RESET_FEATURE(pdevice, GET_PORT(hhub->portno));
+				hhub->state = THUB_PORT_RESET_WAIT;
+			}
+			else if(hhub->cstate == THUB_CONNECT_ENABLE){
+				hhub->state = THUB_CONNECT_WAIT;
+				pdevice->timecount = 50;
+			}
+			else if(++hhub->portno < hhub->numport){
+				PORT_GET_STATUS(pdevice, hhub->buffer, GET_PORT(hhub->portno));
+				hhub->state = THUB_GET_STATUS_WAIT;
+			}
+			else{
+				hhub->state = THUB_SYNC;
+				pdevice->timecount = hhub->poll;
+			}
+		}
+		else if(status != TUSBH_E_BUSY && status != TUSBH_E_BUSY_URB){
+			hhub->state = THUB_PORT_ERROR;
+			tusbSendData(phost->process_event, TUSBH_CLASS_EVENT, pdevice->idx, 0, 0);
+		}
+		break;
+	case THUB_PORT_RESET_WAIT:
+		if((status = tusbhControlWait(pdevice, mes)) == TUSBH_E_OK){
+			hhub->state = THUB_GET_DATA;
+			pdevice->timecount = hhub->poll;
+		}
+		else if(status != TUSBH_E_BUSY && status != TUSBH_E_BUSY_URB){
+			hhub->state = THUB_PORT_ERROR;
+			tusbSendData(phost->process_event, TUSBH_CLASS_EVENT, pdevice->idx, 0, 0);
+		}
+		break;
+	case THUB_CONNECT_WAIT:
+		pdevice->timecount = 200;
+		for(i = 0, pdevicep = phost->pDevice ; i < phost->numDevice && pdevicep != NULL ; i++){
+			if(pdevicep->hub == hhub->hubid && pdevicep->port == GET_PORT(hhub->portno)){
+				if(pdevicep->dstate >= DEVICE_CLASS){
+					if(pdevicep->pClass != NULL)
+						syslog_2(LOG_NOTICE, "[HUB] connected idx(%d) class[%s] !", pdevicep->idx, pdevicep->pClass->Name);
+					hhub->cstate  = THUB_CONNCET_IDEL;
+					if(++hhub->portno < hhub->numport){
+						PORT_GET_STATUS(pdevice, hhub->buffer, GET_PORT(hhub->portno));
+						hhub->state = THUB_GET_STATUS_WAIT;
+					}
+					else{
+						hhub->state = THUB_SYNC;
+						pdevice->timecount = hhub->poll;
+					}
+				}
+				break;
+			}
+			pdevicep = pdevicep->pNext;
+		}
+		break;
+	case THUB_PORT_ERROR:
+		tusbhClearFeature(pdevice, hhub->ep_addr);
+		hhub->state = THUB_PORT_ERROR_WAIT;
+		break;
+	case THUB_PORT_ERROR_WAIT:
+		if(tusbhControlWait(pdevice, mes) == TUSBH_E_OK){
+			hhub->state = THUB_SYNC;
+			pdevice->timecount = hhub->poll;
+		}
+		else if(status == TUSBH_E_BUSY_URB)
+			status = TUSBH_E_BUSY;
+		break;
+
+	default:
+		break;
+	}
+	return status;
+}
+
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/usb/host/HUB/tusbh_hub.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/usb/host/HUB/tusbh_hub.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/usb/host/HUB/tusbh_hub.h	(revision 457)
@@ -0,0 +1,144 @@
+/*
+ *  TOPPERS BASE PLATFORM MIDDLEWARE
+ * 
+ *  Copyright (C) 2017-2017 by TOPPERS PROJECT
+ *                             Educational Working Group.
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+/*
+ *  USB Host Middleware HUB部定義
+ */
+
+#ifndef _HUSBH_HUB_H_
+#define _HUSBH_HUB_H_
+
+#include "tusbh_base.h"
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+
+
+#define PORT_CONNECTION_FEATURE         (0x00)
+#define PORT_ENABLEFEATURE              (0x01)
+#define PORT_SUSPEND                    (0x02)
+#define PORT_OVER_CURRENT_FEATURE       (0x03)
+#define PORT_RESETFEATURE               (0x04)
+#define PORT_POWERFEATURE               (0x08)
+#define PORT_LOW_SPEED                  (0x09)
+
+#define PORT_CLEAR_CONNECTION_FEATURE   (0x10)
+#define PORT_CLEAR_ENABLE_FEATURE       (0x11)
+#define PORT_CLEAR_RESET_FEATURE        (0x14)
+
+#define PORT_SETFEATURE_TYPE            (USB_HOST_TO_DEVICE | USB_REQUEST_TYPE_CLASS | USB_RECIPIENT_INTERFACE | USB_RECIPIENT_ENDPOINT)
+#define PORT_CLEARFEATURE_TYPE          (USB_HOST_TO_DEVICE | USB_REQUEST_TYPE_CLASS | USB_RECIPIENT_INTERFACE | USB_RECIPIENT_ENDPOINT)
+#define PORT_GETSTATUS_TYPE             (USB_DEVICE_TO_HOST | USB_REQUEST_TYPE_CLASS | USB_RECIPIENT_INTERFACE | USB_RECIPIENT_ENDPOINT)
+
+#define PORT_STATUS_CONNECTION          (1<<PORT_CONNECTION_FEATURE)
+#define PORT_STATUS_ENABLE              (1<<PORT_ENABLEFEATURE)
+#define PORT_STATUS_SUSPEND             (1<<PORT_SUSPEND)
+#define PORT_STATUS_OVER_CURRENT        (1<<PORT_OVER_CURRENT_FEATURE)
+#define PORT_STATUS_RESET               (1<<PORT_RESETFEATURE)
+#define PORT_STATUS_POWER               (1<<PORT_POWERFEATURE)
+#define PORT_STATUS_LOW_SPEED           (1<<PORT_LOW_SPEED)
+
+#define PORT_CHANGE_CONNECTION          (1<<16)
+#define PORT_CHANGE_ENABLE              (1<<17)
+#define PORT_CHANGE_SUSPEND             (1<<18)
+#define PORT_CHANGE_OVER_CURRENT        (1<<19)
+#define PORT_CHANGE_RESET               (1<<20)
+
+/*
+ * HUB状態定義
+ */
+enum
+{
+	THUB_IDLE = 0,
+	THUB_SYNC,
+	THUB_GET_DATA,
+	THUB_POLL,
+	THUB_GET_STATUS_WAIT,
+	THUB_CLEAR_FEATURE_WAIT,
+	THUB_PORT_RESET_WAIT,
+	THUB_CONNECT_WAIT,
+	THUB_PORT_ERROR,
+	THUB_PORT_ERROR_WAIT
+};
+
+/*
+ *  HUB CONNECT状態定義
+ */
+enum
+{
+	THUB_CONNCET_IDEL = 0,
+	THUB_CONNECT_RESET,
+	THUB_CONNECT_ENABLE,
+	THUB_CONNECT_ACTIVE
+};
+
+/*
+ *  HUBハンドラ定義
+ */
+typedef struct
+{
+	TUSBH_Device_t            *pDev;
+	uint8_t                   state;
+	uint8_t                   hubid;
+	uint8_t                   numport;
+	uint8_t                   characteristics;
+	uint32_t                  timer;
+	uint32_t                  starttime;
+
+	uint8_t                   InPipe;
+	uint8_t                   ep_addr;
+	uint8_t                   portno;
+	uint8_t                   cstate;
+	uint16_t                  length;
+	uint16_t                  poll; 
+	uint32_t                  reset_portid;
+	uint32_t                  dummy2;
+	uint8_t                   buffer[64];
+} HUB_Handle_t;
+
+
+void  tusbhLinkHUB(TUSBH_Handle_t *phost);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _HUSBH_HUB_H_ */
+
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/usb/host/MSC/tusbh_msc.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/usb/host/MSC/tusbh_msc.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/usb/host/MSC/tusbh_msc.c	(revision 457)
@@ -0,0 +1,976 @@
+/*
+ *  TOPPERS BASE PLATFORM MIDDLEWARE
+ * 
+ *  Copyright (C) 2017-2017 by TOPPERS PROJECT
+ *                             Educational Working Group.
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+/*
+ *  USB Host Middleware MSC CLASS部
+ */
+
+#include "tusbh_msc.h"
+
+
+typedef enum {
+	BOT_OK,
+	BOT_BUSY,
+	BOT_SENSE,
+	BOT_ERROR
+} BOT_TYPE;
+
+#define CBW_SIGNATURE               0x43425355
+#define CSW_SIGNATURE               0x53425355
+#define CBW_TAG                     0x20304050
+
+#define BOT_CBW_LENGTH              31			/* CBW送信パケット長 */
+#define BOT_CSW_LENGTH              13			/* CSW受信パケット長 */
+
+#define UNIT_READY_TIMEOUT          (10000)
+
+#define BOT_REQUEST_GETMAXLUN(d, b) tusbhControlRequest((d), (b), BOT_REQUEST_GETMAXLUN_TYPE, USB_REQ_GET_MAX_LUN, 0, 0, 1)
+#define BOT_REQUEST_RESET(d)        tusbhControlRequest((d), 0, BOT_REQUEST_RESET_TYPE, USB_REQ_BOT_RESET, 0, 0, 0)
+
+
+/*
+ *  SENSEデータ
+ */
+typedef struct
+{
+	uint8_t key;
+	uint8_t asc;
+	uint8_t ascq;
+} SCSI_Sense_t;
+
+
+static TUSBH_ERCODE tusbhMSCInit(TUSBH_Device_t *pdevice);
+static TUSBH_ERCODE tusbhMSCDeInit(TUSBH_Device_t *pdevice);
+static TUSBH_ERCODE tusbhMSCProcess(TUSBH_Device_t *pdevice, uint8_t *mes);
+
+static TUSBH_Class_t MSC_Class = {
+	NULL,
+	"MSC",
+	MSC_CLASS,
+	tusbhMSCInit,
+	tusbhMSCDeInit,
+	tusbhMSCProcess,
+	NULL
+};
+
+/*
+ *  MSCクラスセットアップ関数
+ */
+void tusbhLinkMSC(TUSBH_Handle_t *phost)
+{
+	tusbhLinkClass(phost, &MSC_Class);
+}
+
+/*
+ * MSC SCSI Inquiry要求
+ *  parameter1 hmcs:    MSCハンドラ
+ *  parameter2 lun:     LUN#
+ *  return     TUSBH_E_BUSY
+ */
+static TUSBH_ERCODE
+tusbhMscSCSIInquiry(MSC_Handle_t *hmsc, uint8_t lun)
+{
+	hmsc->hbot.cbw.DataTransferLength = DATA_LEN_INQUIRY;
+	hmsc->hbot.cbw.Flags = USB_DEVICE_TO_HOST;
+	hmsc->hbot.cbw.CBLength = CBW_LENGTH;
+
+	tusbmemset(hmsc->hbot.cbw.CB, 0, CBW_LENGTH);
+	hmsc->hbot.cbw.CB[0]  = OPCODE_INQUIRY;
+	hmsc->hbot.cbw.CB[1]  = (lun << 5);
+	hmsc->hbot.cbw.CB[2]  = 0;
+	hmsc->hbot.cbw.CB[3]  = 0;
+	hmsc->hbot.cbw.CB[4]  = 0x24;
+	hmsc->hbot.cbw.CB[5]  = 0;
+
+	hmsc->hbot.state = BOT_SEND_CBW;
+	hmsc->hbot.pbuf = (uint8_t *)hmsc->hbot.data;
+	return TUSBH_E_BUSY;
+}
+
+/*
+ * MSC SCSI Test Unit Ready要求
+ *  parameter1 hmcs:    MSCハンドラ
+ *  parameter2 lun:     LUN#
+ *  return     TUSBH_E_BUSY
+ */
+static TUSBH_ERCODE
+tusbhMscSCSITestUnitReady(MSC_Handle_t *hmsc, uint8_t lun)
+{
+	hmsc->hbot.cbw.DataTransferLength = DATA_LEN_MODE_TEST_UNIT_READY;
+	hmsc->hbot.cbw.Flags = USB_HOST_TO_DEVICE;
+	hmsc->hbot.cbw.CBLength = CBW_LENGTH;
+
+	tusbmemset(hmsc->hbot.cbw.CB, 0, CBW_CB_LENGTH);
+	hmsc->hbot.cbw.CB[0]  = OPCODE_TEST_UNIT_READY; 
+
+	hmsc->hbot.state = BOT_SEND_CBW;
+	return TUSBH_E_BUSY;
+}
+
+/*
+ * MSC SCSI Read Capacity要求
+ *  parameter1 hmcs:    MSCハンドラ
+ *  parameter2 lun:     LUN#
+ *  return     TUSBH_E_BUSY
+ */
+static TUSBH_ERCODE
+tusbhMscSCSIReadCapacity(MSC_Handle_t *hmsc, uint8_t lun)
+{
+	hmsc->hbot.cbw.DataTransferLength = DATA_LEN_READ_CAPACITY10;
+	hmsc->hbot.cbw.Flags = USB_DEVICE_TO_HOST;
+	hmsc->hbot.cbw.CBLength = CBW_LENGTH;
+
+	tusbmemset(hmsc->hbot.cbw.CB, 0, CBW_CB_LENGTH);
+	hmsc->hbot.cbw.CB[0]  = OPCODE_READ_CAPACITY10;
+
+	hmsc->hbot.state = BOT_SEND_CBW;
+    hmsc->hbot.pbuf = (uint8_t *)hmsc->hbot.data;
+	return TUSBH_E_BUSY;
+}
+
+/*
+ * MSC SCSI Request Sense要求
+ *  parameter1 hmcs:    MSCハンドラ
+ *  parameter2 lun:     LUN#
+ *  return     TUSBH_E_BUSY
+ */
+static TUSBH_ERCODE
+tusbhMscSCSIRequestSense(MSC_Handle_t *hmsc, uint8_t lun)
+{
+	hmsc->hbot.cbw.DataTransferLength = DATA_LEN_REQUEST_SENSE;
+	hmsc->hbot.cbw.Flags = USB_DEVICE_TO_HOST;
+	hmsc->hbot.cbw.CBLength = CBW_LENGTH;
+
+	tusbmemset(hmsc->hbot.cbw.CB, 0, CBW_CB_LENGTH);
+	hmsc->hbot.cbw.CB[0]  = OPCODE_REQUEST_SENSE;
+	hmsc->hbot.cbw.CB[1]  = (lun << 5);
+	hmsc->hbot.cbw.CB[2]  = 0;
+	hmsc->hbot.cbw.CB[3]  = 0;
+	hmsc->hbot.cbw.CB[4]  = DATA_LEN_REQUEST_SENSE;
+	hmsc->hbot.cbw.CB[5]  = 0;
+
+	hmsc->hbot.state = BOT_SEND_CBW;
+	hmsc->hbot.pbuf = (uint8_t *)hmsc->hbot.data;
+	return TUSBH_E_BUSY;
+}
+
+/*
+ *  SCCI データ転送
+ *  parameter1 hmcs:    MSCハンドラ
+ *  parameter2 mes:     メッセージへのポインタ
+ *  parameter3 lun:     LUN#
+ *  return     BOT_TYPE
+ */
+static BOT_TYPE
+tusbhMscSCSITransfer(MSC_Handle_t *hmsc, uint8_t *mes, uint8_t lun)
+{
+	TUSBH_Device_t *pdevice = hmsc->pDev;
+	TUSBH_Handle_t *phost;
+	BOT_TYPE       status = BOT_BUSY;
+	TUSBH_ERCODE   ercd  = TUSBH_E_BUSY;
+	TUSBH_URBState_t URB_Status = mes[3];
+	uint8_t toggle = 0;
+
+	phost = pdevice->pHost;
+	switch (hmsc->hbot.state){
+	case BOT_SEND_CBW:
+		hmsc->hbot.cbw.LUN = lun;
+		hmsc->hbot.state = BOT_SEND_CBW_WAIT;
+		tusbhBulkWrite(pdevice, (uint8_t *)&hmsc->hbot.cbw, BOT_CBW_LENGTH, hmsc->OutPipe);
+		break;
+
+	case BOT_SEND_CBW_WAIT:
+		if(mes[0] != TUSBH_URB_EVENT)
+			break;
+		if(URB_Status == TUSBH_URB_DONE){
+			if(hmsc->hbot.cbw.DataTransferLength != 0){
+				if(((hmsc->hbot.cbw.Flags) & USB_REQUEST_DIR_MASK) == USB_DEVICE_TO_HOST){
+					/*
+					 *  BOT DATA INケース
+					 */
+					tusbhBulkRead (pdevice, hmsc->hbot.pbuf, hmsc->InEpSize, hmsc->InPipe);
+					hmsc->hbot.state  = BOT_DATA_IN_WAIT;
+				}
+				else{
+					/*
+					 *  BOT DATA OUTケース
+					 */
+					tusbhBulkWrite(pdevice, hmsc->hbot.pbuf, hmsc->OutEpSize, hmsc->OutPipe);
+					hmsc->hbot.state  = BOT_DATA_OUT_WAIT;
+				}
+			}
+			else{
+				/*
+				 *  ステータス通信ケース
+				 */
+				tusbhBulkRead(pdevice, (uint8_t *)&hmsc->hbot.csw, BOT_CSW_LENGTH, hmsc->InPipe);
+				hmsc->hbot.state  = BOT_RECEIVE_CSW_WAIT;
+			}
+		}
+		else if(URB_Status == TUSBH_URB_NOTREADY){
+			/*
+			 * CBWを再送
+			 */
+			hmsc->hbot.state = BOT_SEND_CBW;
+			tusbSendData(phost->process_event, TUSBH_CLASS_EVENT, pdevice->idx, 0, 0);
+		}
+		else if(URB_Status == TUSBH_URB_STALL){
+			/*
+			 *  Clear Fuature Out Endpoint(CBWSTALL)
+			 */
+			ercd = tusbhClearFeature(pdevice, hmsc->OutEp);
+			if(ercd == TUSBH_E_OK){ 
+				toggle = tusbhHDGetToggle(phost, hmsc->OutPipe);
+				tusbhHDSetToggle(phost, hmsc->OutPipe, 1- toggle);
+				tusbhHDSetToggle(phost, hmsc->InPipe, 0);
+				/*
+				 *  Clear Fuature In Endpoint
+				 */
+				ercd = tusbhClearFeature(pdevice, hmsc->InEp);
+				if(ercd == TUSBH_E_OK){
+					tusbhBulkRead(pdevice, (uint8_t *)&hmsc->hbot.csw, BOT_CSW_LENGTH, hmsc->InPipe);
+					hmsc->hbot.state  = BOT_RECEIVE_CSW_WAIT;
+				}
+				else
+					hmsc->hbot.state = BOT_STATE_ERROR;
+			}
+			else
+				hmsc->hbot.state = BOT_STATE_ERROR;
+			tusbSendData(phost->process_event, TUSBH_CLASS_EVENT, pdevice->idx, 0, 0);
+		}
+		break;
+
+	case BOT_DATA_IN_WAIT:
+		if(mes[0] != TUSBH_URB_EVENT)
+			break;
+		if(URB_Status == TUSBH_URB_DONE){
+			/*
+			 *  受信データ長アップデート
+			 */
+			if(hmsc->hbot.cbw.DataTransferLength > hmsc->InEpSize){
+				hmsc->hbot.pbuf += hmsc->InEpSize;
+				hmsc->hbot.cbw.DataTransferLength -= hmsc->InEpSize;
+			}
+			else
+				hmsc->hbot.cbw.DataTransferLength = 0;
+			if(hmsc->hbot.cbw.DataTransferLength > 0){
+				/*
+				 *  次のパケット要求
+				 */
+				tusbhBulkRead(pdevice, hmsc->hbot.pbuf, hmsc->InEpSize, hmsc->InPipe);
+			}
+			else{
+				/*
+				 *  受信終了、CSW受信要求
+				 */
+				tusbhBulkRead(pdevice, (uint8_t *)&hmsc->hbot.csw, BOT_CSW_LENGTH, hmsc->InPipe);
+				hmsc->hbot.state  = BOT_RECEIVE_CSW_WAIT;
+			}
+		}
+		else if(URB_Status == TUSBH_URB_STALL){
+			/*
+			 *  Clear Fuature In Endpoint(受信STALL)
+			 */
+			ercd = tusbhClearFeature(pdevice, hmsc->InEp);
+			if(ercd == TUSBH_E_OK){
+				tusbhBulkRead(pdevice, (uint8_t *)&hmsc->hbot.csw, BOT_CSW_LENGTH, hmsc->InPipe);
+				hmsc->hbot.state  = BOT_RECEIVE_CSW_WAIT;
+			}
+			else
+				hmsc->hbot.state = BOT_STATE_ERROR;
+			tusbSendData(phost->process_event, TUSBH_CLASS_EVENT, pdevice->idx, 0, 0);
+		}
+		break;
+
+	case BOT_DATA_OUT_WAIT:
+		if(mes[0] != TUSBH_URB_EVENT)
+			break;
+		if(URB_Status == TUSBH_URB_DONE){
+			/*
+			 *  送信データ長アップデート
+			 */
+			if(hmsc->hbot.cbw.DataTransferLength > hmsc->OutEpSize){
+				hmsc->hbot.pbuf += hmsc->OutEpSize;
+				hmsc->hbot.cbw.DataTransferLength -= hmsc->OutEpSize; 
+			}
+			else
+				hmsc->hbot.cbw.DataTransferLength = 0;
+			if(hmsc->hbot.cbw.DataTransferLength > 0){
+				/*
+				 *  次のパケット送信
+				 */
+				tusbhBulkWrite(pdevice, hmsc->hbot.pbuf, hmsc->OutEpSize, hmsc->OutPipe);
+			}
+			else{
+				/*
+				 *  送信終了、CSW受信要求
+				 */
+				tusbhBulkRead(pdevice, (uint8_t *)&hmsc->hbot.csw, BOT_CSW_LENGTH, hmsc->InPipe);
+				hmsc->hbot.state  = BOT_RECEIVE_CSW_WAIT;
+			}
+		}
+		else if(URB_Status == TUSBH_URB_NOTREADY){
+			/*
+			 *  再送設定
+			 */
+			tusbhBulkWrite(pdevice, hmsc->hbot.pbuf, hmsc->OutEpSize, hmsc->OutPipe);
+			hmsc->hbot.state  = BOT_DATA_OUT_WAIT;
+		}
+		else if(URB_Status == TUSBH_URB_STALL){
+			/*
+			 *  Clear Fuature Out Endpoint(送信STALL)
+			 */
+			ercd = tusbhClearFeature(pdevice, hmsc->OutEp);
+			if(ercd == TUSBH_E_OK){ 
+				toggle = tusbhHDGetToggle(phost, hmsc->OutPipe);
+				tusbhHDSetToggle(phost, hmsc->OutPipe, 1- toggle);
+				tusbhHDSetToggle(phost, hmsc->InPipe, 0);
+				/*
+				 *  Clear Fuature In Endpoint
+				 */
+				ercd = tusbhClearFeature(pdevice, hmsc->InEp);
+				if(ercd == TUSBH_E_OK){
+					tusbhBulkRead(pdevice, (uint8_t *)&hmsc->hbot.csw, BOT_CSW_LENGTH, hmsc->InPipe);
+					hmsc->hbot.state  = BOT_RECEIVE_CSW_WAIT;
+				}
+				else
+					hmsc->hbot.state = BOT_STATE_ERROR;
+			}
+			else
+				hmsc->hbot.state = BOT_STATE_ERROR;
+			tusbSendData(phost->process_event, TUSBH_CLASS_EVENT, pdevice->idx, 0, 0);
+		}
+		break;
+
+	case BOT_RECEIVE_CSW_WAIT:
+		if(mes[0] != TUSBH_URB_EVENT)
+			break;
+		if(URB_Status == TUSBH_URB_DONE){
+			hmsc->hbot.state = BOT_SEND_CBW;
+			if(hmsc->hbot.csw.Signature != CSW_SIGNATURE)
+				status = BOT_ERROR;
+			else if(hmsc->hbot.csw.Status == 0)
+				status = BOT_OK;
+			else if(hmsc->hbot.csw.Status == 1){
+#if 1	/* ROI DEBUG */
+				syslog_1(LOG_NOTICE, "## SBH_MSC_BOT_Process BOT_RECEIVE_CSW_WAIT ERROR CSW_Status(%d) ##", hmsc->hbot.csw.Status);
+#endif	/* ROI DEBUG */
+				status = BOT_SENSE;
+			}
+			else
+				status = BOT_ERROR;
+			tusbSendData(phost->process_event, TUSBH_CLASS_EVENT, pdevice->idx, 0, 0);
+		}
+		else if(URB_Status == TUSBH_URB_STALL){
+			/*
+			 *  Clear Fuature In Endpoint(CSW-STALL)
+			 */
+			ercd = tusbhClearFeature(pdevice, hmsc->InEp);
+			if(ercd == TUSBH_E_OK){
+				tusbhBulkRead(pdevice, (uint8_t *)&hmsc->hbot.csw, BOT_CSW_LENGTH, hmsc->InPipe);
+				hmsc->hbot.state  = BOT_RECEIVE_CSW_WAIT;
+			}
+			else
+				hmsc->hbot.state = BOT_STATE_ERROR;
+			tusbSendData (phost->process_event, TUSBH_CLASS_EVENT, pdevice->idx, 0, 0);
+		}
+		break;
+
+	case BOT_STATE_ERROR:
+		BOT_REQUEST_RESET(pdevice);
+		hmsc->hbot.state = BOT_STATE_ERROR_WAIT;
+		break;
+
+	case BOT_STATE_ERROR_WAIT:
+		if((ercd = tusbhControlWait(pdevice, mes)) == TUSBH_E_OK)
+			hmsc->hbot.state = BOT_SEND_CBW;
+		else if(ercd != TUSBH_E_BUSY && ercd != TUSBH_E_BUSY_URB)
+			status = BOT_ERROR;
+		break;
+
+	default:
+		break;
+	}
+	return status;
+}
+
+/*
+ * MSC SCSI Disk Initialize
+ *  parameter1 hmcs:    MSCハンドラ
+ *  parameter2 lun:     LUN#
+ *  return     TUSBH_E_BUSY
+ */
+static TUSBH_ERCODE
+tusbhMscSCSIDiskInitailize(MSC_Handle_t *hmsc, uint8_t *mes, uint8_t lun)
+{
+	MSC_Unit_t   *punit = &hmsc->unit[lun];
+	SCSI_Sense_t sense;
+	TUSBH_ERCODE status = TUSBH_E_OK;
+	BOT_TYPE bot_status = BOT_BUSY;
+
+	switch (punit->state){
+	case MSC_UNIT_INIT:
+		syslog_1(LOG_NOTICE, "[MSC]LUN : #%d", lun);
+		punit->state = MSC_UNIT_READ_INQUIRY_WAIT;
+		status = tusbhMscSCSIInquiry(hmsc, lun);
+	case MSC_UNIT_READ_INQUIRY_WAIT:
+		bot_status = tusbhMscSCSITransfer(hmsc, mes, lun);
+		if(bot_status == BOT_OK){
+			/*
+			 *  INQUIRY情報取得
+			 */
+			punit->DeviceType = hmsc->hbot.pbuf[0] & 0x1F;
+			punit->PeripheralQualifier = hmsc->hbot.pbuf[0] >> 5;  
+			punit->RemovableMedia = (hmsc->hbot.pbuf[1] & 0x80)== 0x80;
+			tusbmemcpy(punit->vendor_id, &hmsc->hbot.pbuf[8], 8);
+			tusbmemcpy(punit->product_id, &hmsc->hbot.pbuf[16], 16);
+			tusbmemcpy(punit->revision_id, &hmsc->hbot.pbuf[32], 4);
+
+			syslog_1(LOG_NOTICE, "[MSC]Inquiry Vendor  : %s", punit->vendor_id);
+			syslog_1(LOG_NOTICE, "[MSC]Inquiry Product : %s", punit->product_id);
+			syslog_1(LOG_NOTICE, "[MSC]Inquiry Version : %s", punit->revision_id);
+			punit->state = MSC_UNIT_TEST_UNIT_READY_WAIT;
+			status = tusbhMscSCSITestUnitReady(hmsc, lun);
+		}
+		else if(bot_status == BOT_SENSE){
+			punit->state = MSC_UNIT_REQUEST_SENSE_WAIT;
+			punit->pre_state = MSC_UNIT_READ_INQUIRY_WAIT;
+			status = tusbhMscSCSIRequestSense(hmsc, lun);
+		}
+		else if(bot_status == BOT_ERROR){
+			punit->state = MSC_UNIT_ERROR;
+		}
+		else{
+			dly_tsk(10);
+			if(++hmsc->urb_wait > 500)
+				punit->state = MSC_UNIT_ERROR;
+		}
+		break;
+	case MSC_UNIT_TEST_UNIT_READY_WAIT:
+		bot_status = tusbhMscSCSITransfer(hmsc, mes, lun);
+		if(bot_status == BOT_OK){
+			syslog_1(LOG_NOTICE, "[MSC] Device ready(%d) !", lun);
+			punit->state = MSC_UNIT_READ_CAPACITY_WAIT;
+			status = tusbhMscSCSIReadCapacity(hmsc, lun);
+		}
+		else if(bot_status == BOT_SENSE){
+			if(hmsc->timer >= UNIT_READY_TIMEOUT){
+				syslog_1(LOG_NOTICE, "[MSC] Device NOT ready(%d) !", lun);
+			}
+			punit->state = MSC_UNIT_REQUEST_SENSE_WAIT; 
+			punit->pre_state = MSC_UNIT_TEST_UNIT_READY_WAIT;
+			status = tusbhMscSCSIRequestSense(hmsc, lun);
+		}
+		else if(bot_status == BOT_ERROR){
+			punit->state = MSC_UNIT_ERROR;
+		}
+		else{
+			dly_tsk(10);
+			if(++hmsc->urb_wait > 500)
+				punit->state = MSC_UNIT_ERROR;
+		}
+		break;
+	case MSC_UNIT_READ_CAPACITY_WAIT:
+		bot_status = tusbhMscSCSITransfer(hmsc, mes, lun);
+		if(bot_status == BOT_OK){
+			/*
+			 *  ユニット容量を取得
+			 */
+			punit->num_block = hmsc->hbot.pbuf[3] | (hmsc->hbot.pbuf[2] << 8) |
+								 (hmsc->hbot.pbuf[1] << 16) | (hmsc->hbot.pbuf[0] << 24);
+			punit->block_size = hmsc->hbot.pbuf[7] | (hmsc->hbot.pbuf[6] << 8); 
+			syslog_1(LOG_NOTICE, "[MSC] Device capacity : %u Bytes", \
+				(uint32_t)(punit->num_block * punit->block_size));
+			syslog_1(LOG_NOTICE, "      Block number : %u", (uint32_t)(punit->num_block));
+			syslog_1(LOG_NOTICE, "      Block Size   : %u", (uint32_t)(punit->block_size));
+			punit->state = MSC_UNIT_IDLE;
+			hmsc->lun++;
+		}
+		else if(bot_status == BOT_SENSE){
+			punit->state = MSC_UNIT_REQUEST_SENSE_WAIT;
+			punit->pre_state = MSC_UNIT_READ_CAPACITY_WAIT;
+			status = tusbhMscSCSIRequestSense(hmsc, lun);
+		}
+		else if(bot_status == BOT_ERROR){
+			punit->state = MSC_UNIT_ERROR;
+		}
+		else{
+			dly_tsk(10);
+			if(++hmsc->urb_wait > 500)
+				punit->state = MSC_UNIT_ERROR;
+		}
+		break;
+	case MSC_UNIT_REQUEST_SENSE_WAIT:
+		bot_status = tusbhMscSCSITransfer(hmsc, mes, lun);
+		if(bot_status == BOT_OK){
+			sense.key  = hmsc->hbot.pbuf[2] & 0x0F;
+			sense.asc  = hmsc->hbot.pbuf[12];
+			sense.ascq = hmsc->hbot.pbuf[13];
+			if(sense.key == SCSI_SENSE_KEY_UNIT_ATTENTION || sense.key == SCSI_SENSE_KEY_NOT_READY){
+				if(hmsc->timer < UNIT_READY_TIMEOUT){
+					if(punit->pre_state == MSC_UNIT_READ_INQUIRY_WAIT){
+						punit->state = MSC_UNIT_READ_INQUIRY_WAIT;
+						status = tusbhMscSCSIInquiry(hmsc, lun);
+						break;
+					}
+					else if(punit->pre_state == MSC_UNIT_TEST_UNIT_READY_WAIT){
+						punit->state = MSC_UNIT_TEST_UNIT_READY_WAIT;
+						status = tusbhMscSCSITestUnitReady(hmsc, lun);
+						break;
+					}
+					else if(punit->pre_state == MSC_UNIT_READ_CAPACITY_WAIT){
+						punit->state = MSC_UNIT_READ_CAPACITY_WAIT;
+						status = tusbhMscSCSIReadCapacity(hmsc, lun);
+						break;
+					}
+				}
+			}
+			syslog_1(LOG_NOTICE, "[MSC] Sense Key  : %x", sense.key);
+			syslog_1(LOG_NOTICE, "[MSC] Additional Sense Code : %x", sense.asc);
+			syslog_1(LOG_NOTICE, "[MSC] Additional Sense Code Qualifier: %x", sense.ascq);
+			punit->state = MSC_UNIT_IDLE;
+			lun++;
+		}
+		else if(bot_status == BOT_SENSE || bot_status == BOT_ERROR){
+			punit->state = MSC_UNIT_ERROR;
+		}
+		else{
+			dly_tsk(10);
+			if(++hmsc->urb_wait > 500)
+				punit->state = MSC_UNIT_ERROR;
+		}
+		break;
+	case MSC_UNIT_ERROR:
+		hmsc->lun++;
+		break;
+	default:
+		break;
+	}
+	return status;
+}
+
+
+/*
+ *  MSCクラス初期設定
+ *  parameter1 pdevice:  デバイスハンドラ
+ *  return     TUSBH_ERCODE
+ */
+static TUSBH_ERCODE
+tusbhMSCInit(TUSBH_Device_t *pdevice)
+{
+	uint8_t interface = 0; 
+	TUSBH_ERCODE status = TUSBH_E_ERR ;
+	MSC_Handle_t *hmsc;
+	TUSBH_Handle_t *phost = pdevice->pHost;
+	uint8_t max_ep, i;
+
+	interface = tusbhFindInterface(pdevice, pdevice->pClass->classCode, MSC_TRANSPARENT_SUBCLASS, MSC_BOT_PROTOCOL);
+
+	if(interface == NO_INTERFACE){
+		syslog_1(LOG_ERROR, "[MSC] Cannot Find the interface for %s class.", pdevice->pClass->Name);
+		return TUSBH_E_ERR;
+	}
+	tusbhSelectInterface(pdevice, interface);
+
+	hmsc = (MSC_Handle_t *)tusbmalloc(sizeof(MSC_Handle_t));
+	pdevice->pData = hmsc;
+	memset(hmsc, 0, sizeof(MSC_Handle_t));
+	max_ep = ((pdevice->ItfDesc[pdevice->sel_interface].bNumEndpoints <= 2) ?
+              pdevice->ItfDesc[pdevice->sel_interface].bNumEndpoints : 2);
+
+	for(i = 0 ; i < max_ep; i++){
+		if(pdevice->EpDesc[pdevice->sel_interface][i].bEndpointAddress & 0x80){
+			hmsc->InEp     = (pdevice->EpDesc[pdevice->sel_interface][i].bEndpointAddress);
+			hmsc->InEpSize = pdevice->EpDesc[pdevice->sel_interface][i].wMaxPacketSize;
+			hmsc->InPipe = tusbhAllocPipe(phost, hmsc->InEp);
+		}
+		else{
+			hmsc->OutEp = (pdevice->EpDesc[pdevice->sel_interface][i].bEndpointAddress);
+			hmsc->OutEpSize = pdevice->EpDesc[pdevice->sel_interface][i].wMaxPacketSize;
+			hmsc->OutPipe = tusbhAllocPipe(phost, hmsc->OutEp);
+		}
+	}
+	if(hmsc->OutPipe == 0 || hmsc->InPipe == 0)
+		return TUSBH_E_ERR;
+
+	hmsc->lun = 0;
+	hmsc->state = MSC_PROCESS_INIT;
+	hmsc->urb_wait = 0;
+	hmsc->timer = 0;
+	hmsc->pDev = pdevice;
+
+	hmsc->hbot.cbw.Signature = CBW_SIGNATURE;
+	hmsc->hbot.cbw.Tag = CBW_TAG;
+	hmsc->hbot.state = BOT_SEND_CBW;
+
+	/*
+	 *  NSCチャネルオープン
+	 */
+	tusbhOpenPipe(pdevice, hmsc->OutPipe, hmsc->OutEp, USB_EP_TYPE_BULK, hmsc->OutEpSize);
+	tusbhHDSetToggle(phost, hmsc->OutPipe, 0);
+	tusbhOpenPipe(pdevice, hmsc->InPipe, hmsc->InEp, USB_EP_TYPE_BULK, hmsc->InEpSize);
+	tusbhHDSetToggle(phost, hmsc->InPipe, 0);
+
+	/*
+	 *  最大LUNを取得
+	 */
+	status = BOT_REQUEST_GETMAXLUN(pdevice, ((uint8_t *)&hmsc->hbot.data));
+	hmsc->max_lun = hmsc->hbot.data[0];
+
+	/*
+	 *  NO SUPPORT受信の場合、0を設定
+	 */
+	if(status == TUSBH_E_NOSPT){
+		hmsc->max_lun = 0;
+		status = TUSBH_E_OK;
+	}
+
+	/*
+	 *  UNIT領域の初期化
+	 */
+	if(status == TUSBH_E_OK){
+		uint32_t i;
+		hmsc->max_lun = (uint8_t )(hmsc->max_lun) + 1;
+		syslog_1(LOG_NOTICE, "[MSC] Number of supported LUN: %d", (int32_t)(hmsc->max_lun));
+
+		for(i = 0; i < hmsc->max_lun; i++){
+			tusbmemset(&hmsc->unit[i], 0, sizeof(hmsc->unit));
+			hmsc->unit[i].state = MSC_UNIT_INIT;
+		}
+	}
+	pdevice->numUnit = hmsc->max_lun;
+	/* タイマースタート */
+	pdevice->timeid = pdevice->timecount = 100;
+	return TUSBH_E_OK;
+}
+
+/*
+ *  MSCクラス終了設定
+ *  parameter1 pdevice:  デバイスハンドラ
+ *  return     TUSBH_ERCODE
+ */
+static TUSBH_ERCODE
+tusbhMSCDeInit(TUSBH_Device_t *pdevice)
+{
+	MSC_Handle_t *hmsc;
+	TUSBH_Handle_t *phost = pdevice->pHost;
+
+	hmsc = (MSC_Handle_t *)pdevice->pData;
+	if(hmsc->OutPipe != 0){
+		tusbhClosePipe(pdevice, hmsc->OutPipe);
+		tusbFreePipe(phost, hmsc->OutPipe);
+		hmsc->OutPipe = 0;
+	}
+
+	if(hmsc->InPipe != 0){
+		tusbhClosePipe(pdevice, hmsc->InPipe);
+		tusbFreePipe(phost, hmsc->InPipe);
+		hmsc->InPipe = 0;
+	}
+
+	if(pdevice->pData != NULL){
+		tusbfree(pdevice->pData);
+		pdevice->pData = NULL;
+	}
+	return TUSBH_E_OK;
+}
+
+/*
+ *  MSCクラスプロセス実行
+ *  parameter1 pdevice:  デバイスハンドラ
+ *  parameter2 mes:      通信メッセージへのポインタ
+ *  return     TUSBH_ERCODE
+ */
+static TUSBH_ERCODE
+tusbhMSCProcess(TUSBH_Device_t *pdevice, uint8_t *mes)
+{
+	MSC_Handle_t   *hmsc;
+	MSC_Unit_t     *punit;
+	TUSBH_Handle_t *phost = pdevice->pHost;
+	TUSBH_ERCODE status = TUSBH_E_OK;
+	BOT_TYPE bot_status = BOT_BUSY;
+
+	hmsc = (MSC_Handle_t *)pdevice->pData;
+    if(mes[0] == TUSBH_URB_EVENT){
+		hmsc->urb_wait = 0;
+    }
+	else if(mes[0] == TUSBH_TIME_EVENT){
+		hmsc->timer += mes[3];
+		pdevice->timecount = mes[3];
+	}
+	switch (hmsc->state){
+	case MSC_PROCESS_INIT:
+		if(hmsc->lun < hmsc->max_lun){
+			status = tusbhMscSCSIDiskInitailize(hmsc, mes, hmsc->lun);
+			tusbSendData(phost->process_event, TUSBH_CLASS_EVENT, pdevice->idx, 0, 0);
+		}
+		else{
+			hmsc->lun = 0;
+			hmsc->state = MSC_PROCESS_IDLE;
+			if(phost->usrcallback != NULL)
+				phost->usrcallback(phost, pdevice, HOST_USER_CLASS_ACTIVE);
+		}
+		break;
+	case MSC_PROCESS_READ_WAIT:
+	case MSC_PROCESS_WRITE_WAIT:
+		if(hmsc->lun >= hmsc->max_lun)
+			break;
+		punit = &hmsc->unit[hmsc->lun];
+		if(punit->rw_status == TUSBH_E_BUSY){
+			bot_status = tusbhMscSCSITransfer(hmsc, mes, hmsc->lun);
+			if(bot_status == BOT_SENSE){
+				hmsc->state = MSC_PROCESS_REQUEST_SENSE_WAIT;
+				tusbhMscSCSIRequestSense(hmsc, hmsc->lun);
+				tusbSendData( phost->process_event, TUSBH_CLASS_EVENT, pdevice->idx, 0, 0);
+			}
+			else if(bot_status == BOT_ERROR){
+				punit->rw_status = TUSBH_E_ERR;
+			}
+			else if(bot_status != BOT_BUSY){
+				punit->rw_status = TUSBH_E_OK;
+				if(punit->rw_taskid != 0)
+					tusbWakeup(punit->rw_taskid);
+			}
+		}
+		break;
+    case MSC_PROCESS_REQUEST_SENSE_WAIT:
+		if(hmsc->lun >= hmsc->max_lun)
+			break;
+		punit = &hmsc->unit[hmsc->lun];
+		if(punit->rw_status == TUSBH_E_BUSY){
+			bot_status = tusbhMscSCSITransfer(hmsc, mes, hmsc->lun);
+			if(bot_status == BOT_OK){
+				punit->rw_status = TUSBH_E_OK;
+				if(punit->rw_taskid != 0)
+					tusbWakeup(punit->rw_taskid);
+			}
+			else if(bot_status != BOT_BUSY){
+				punit->rw_status = TUSBH_E_ERR;
+			}
+		}
+		break;
+	case MSC_PROCESS_IDLE:
+		status = TUSBH_E_OK;
+		break;
+	default:
+		break;
+	}
+	return status;
+}
+
+/*
+ *  ユニット READY確認
+ *  parameter1 phost:   ホストハンドラ
+ *  parameter2 lun:     unit#
+ *  return     status:  (0: not ready / 1: ready)
+ */
+uint8_t
+tusbhMscUnitIsReady(TUSBH_Handle_t *phost, uint8_t lun)
+{
+	TUSBH_Device_t *pdevice = tusbhSearchDevice(phost, MSC_Class.classCode, &lun);
+	MSC_Handle_t *hmsc;
+
+	if(pdevice == NULL)
+		return 0;
+	hmsc = (MSC_Handle_t *)pdevice->pData;
+
+	if(pdevice->dstate == DEVICE_CLASS)
+		return (hmsc->unit[lun].state >= MSC_UNIT_IDLE);
+	else
+		return 0;
+}
+
+/*
+ *  ユニット情報を取得
+ *  parameter1 phost:   ホストハンドラ
+ *  parameter2 lun:     unit#
+ *  parameter3 info:    ユニット取得領域へのポインタ
+ *  return     TUSBH_ERCODE
+ */
+TUSBH_ERCODE
+tusbhMscGetLUNInfo(TUSBH_Handle_t *phost, uint8_t lun, MSC_Unit_t *info)
+{
+	TUSBH_Device_t *pdevice = tusbhSearchDevice(phost, MSC_Class.classCode, &lun);
+	MSC_Handle_t *hmsc;
+
+	if(pdevice == NULL)
+		return TUSBH_E_OBJ;
+	hmsc = (MSC_Handle_t *) pdevice->pData;
+
+	if(pdevice->dstate == DEVICE_CLASS){
+		tusbmemcpy(info, &hmsc->unit[lun], sizeof(MSC_Unit_t));
+		return TUSBH_E_OK;
+	}
+	else
+		return TUSBH_E_OBJ;
+}
+
+/*
+ *  MSC BLOCK READ
+ *  parameter1 phost:   ホストハンドラ
+ *  parameter2 lun:     unit#
+ *  parameter3 address: ユニットアドレス
+ *  parameter4 pbuf:    受信データ領域へのポインタ
+ *  parameter5 num:     受信ブロック数
+ *  return     TUSBH_ERCODE
+ */
+TUSBH_ERCODE
+tusbhMscRead(TUSBH_Handle_t *phost, uint8_t lun, uint32_t address, uint8_t *pbuf, uint32_t num)
+{
+	TUSBH_Device_t *pdevice = tusbhSearchDevice(phost, MSC_Class.classCode, &lun);
+	MSC_Handle_t *hmsc;
+	TUSBH_ERCODE status = TUSBH_E_BUSY;
+	uint32_t i;
+
+	if(pdevice != NULL){
+		hmsc = pdevice->pData;
+		if(pdevice->dstate != DEVICE_CLASS || hmsc->unit[lun].state != MSC_UNIT_IDLE)
+			return TUSBH_E_OBJ;
+	}
+	else
+		return TUSBH_E_OBJ;
+	if(lun >= hmsc->max_lun)
+		return TUSBH_E_PAR;
+
+	hmsc->state = MSC_PROCESS_READ_WAIT;
+	hmsc->unit[lun].rw_status = TUSBH_E_BUSY;
+	hmsc->unit[lun].rw_taskid = tusbGetTaskID();
+	hmsc->unit[lun].state = MSC_UNIT_READ_WAIT;
+	hmsc->lun = lun;
+
+    /*
+	 *  BLOCK READ CBW設定
+	 */
+	hmsc->hbot.cbw.DataTransferLength = num * 512;
+	hmsc->hbot.cbw.Flags = USB_DEVICE_TO_HOST;
+	hmsc->hbot.cbw.CBLength = CBW_LENGTH;
+	tusbmemset(hmsc->hbot.cbw.CB, 0, CBW_CB_LENGTH);
+	hmsc->hbot.cbw.CB[0]  = OPCODE_READ10; 
+
+	hmsc->hbot.cbw.CB[2]  = (address >> 24) & 0xff;
+	hmsc->hbot.cbw.CB[3]  = (address >> 16) & 0xff;
+	hmsc->hbot.cbw.CB[4]  = (address >> 8) & 0xff;
+	hmsc->hbot.cbw.CB[5]  = address & 0xff;
+
+	hmsc->hbot.cbw.CB[7]  = (num >> 8) & 0xff;
+	hmsc->hbot.cbw.CB[8]  = num & 0xff;
+
+    hmsc->hbot.state = BOT_SEND_CBW;
+    hmsc->hbot.pbuf = pbuf;
+    tusbSendData(phost->process_event, TUSBH_CLASS_EVENT, pdevice->idx, 0, 0);
+
+	for(i = 0 ; i < (num * 1000) ; i++){
+		tusbSleep(50);
+		if((status = hmsc->unit[lun].rw_status) != TUSBH_E_BUSY)
+			break;
+	}
+	if(status == TUSBH_E_BUSY)
+		status = TUSBH_E_TMOUT;
+	hmsc->unit[lun].rw_taskid = 0;
+	hmsc->unit[lun].state = MSC_UNIT_IDLE;
+	hmsc->state = MSC_PROCESS_IDLE;
+	return status;
+}
+
+/*
+ *  MSC BLOCK WRITE
+ *  parameter1 phost:   ホストハンドラ
+ *  parameter2 lun:     unit#
+ *  parameter3 address: ユニットアドレス
+ *  parameter4 pbuf:    送信データ領域へのポインタ
+ *  parameter5 num:     送信ブロック数
+ *  return     TUSBH_ERCODE
+ */
+TUSBH_ERCODE
+tusbhMscWrite(TUSBH_Handle_t *phost, uint8_t lun, uint32_t address, uint8_t *pbuf, uint32_t num)
+{
+	TUSBH_Device_t *pdevice = tusbhSearchDevice(phost, MSC_Class.classCode, &lun);
+	MSC_Handle_t *hmsc;
+	TUSBH_ERCODE status = TUSBH_E_BUSY;
+	uint32_t i;
+
+	if(pdevice != NULL){
+		hmsc = pdevice->pData;
+		if(pdevice->dstate != DEVICE_CLASS || hmsc->unit[lun].state != MSC_UNIT_IDLE)
+			return TUSBH_E_OBJ;
+	}
+	else
+		return TUSBH_E_OBJ;
+	if(lun >= hmsc->max_lun)
+		return TUSBH_E_PAR;
+
+	hmsc->state = MSC_PROCESS_WRITE_WAIT;
+	hmsc->unit[lun].rw_taskid = tusbGetTaskID();
+	hmsc->unit[lun].rw_status = TUSBH_E_BUSY;
+	hmsc->unit[lun].state = MSC_UNIT_WRITE_WAIT;
+	hmsc->lun = lun;
+
+    /*
+	 *  BLOCK WRITE CBW設定
+	 */
+	hmsc->hbot.cbw.DataTransferLength = num * 512;
+	hmsc->hbot.cbw.Flags = USB_HOST_TO_DEVICE;
+	hmsc->hbot.cbw.CBLength = CBW_LENGTH;
+	tusbmemset(hmsc->hbot.cbw.CB, 0, CBW_CB_LENGTH);
+	hmsc->hbot.cbw.CB[0]  = OPCODE_WRITE10; 
+
+	hmsc->hbot.cbw.CB[2]  = (address >> 24) & 0xff;
+	hmsc->hbot.cbw.CB[3]  = (address >> 16) & 0xff;
+	hmsc->hbot.cbw.CB[4]  = (address >> 8) & 0xff;
+	hmsc->hbot.cbw.CB[5]  = (((uint8_t*)&address)[0]);
+
+	hmsc->hbot.cbw.CB[7]  = (num >> 8) & 0xff;
+	hmsc->hbot.cbw.CB[8]  = num & 0xff;
+
+	hmsc->hbot.state = BOT_SEND_CBW;
+	hmsc->hbot.pbuf = pbuf;
+	tusbSendData(phost->process_event, TUSBH_CLASS_EVENT, pdevice->idx, 0, 0);
+
+	for(i = 0 ; i < (num * 1000) ; i++){
+		tusbSleep(50);
+		if((status = hmsc->unit[lun].rw_status) != TUSBH_E_BUSY)
+			break;
+	}
+	if(status == TUSBH_E_BUSY)
+		status = TUSBH_E_TMOUT;
+	hmsc->unit[lun].rw_taskid = 0;
+	hmsc->unit[lun].state = MSC_UNIT_IDLE;
+	hmsc->state = MSC_PROCESS_IDLE;
+	return status;
+}
+
+
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/usb/host/MSC/tusbh_msc.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/usb/host/MSC/tusbh_msc.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/usb/host/MSC/tusbh_msc.h	(revision 457)
@@ -0,0 +1,238 @@
+/*
+ *  TOPPERS BASE PLATFORM MIDDLEWARE
+ * 
+ *  Copyright (C) 2017-2017 by TOPPERS PROJECT
+ *                             Educational Working Group.
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+/*
+ *  USB Host Middleware MSC部定義
+ */
+
+#ifndef _HUSBH_MSC_H_
+#define _HUSBH_MSC_H_
+
+#include "tusbh_base.h"
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+
+#ifndef NUM_MAX_MSC_UNIT
+#define NUM_MAX_MSC_UNIT                2
+#endif
+
+/*
+ *  MSCインターフェイス定義
+ */
+#define MSC_TRANSPARENT_SUBCLASS        0x06
+#define MSC_BOT_PROTOCOL                0x50
+
+/*
+ *  BOT通信パケット定義
+ */ 
+#define OPCODE_TEST_UNIT_READY          0x00
+#define OPCODE_READ_CAPACITY10          0x25
+#define OPCODE_READ10                   0x28
+#define OPCODE_WRITE10                  0x2A
+#define OPCODE_REQUEST_SENSE            0x03
+#define OPCODE_INQUIRY                  0x12
+
+#define DATA_LEN_MODE_TEST_UNIT_READY   0
+#define DATA_LEN_READ_CAPACITY10        8
+#define DATA_LEN_INQUIRY                36
+#define DATA_LEN_REQUEST_SENSE          14
+
+#define CBW_CB_LENGTH                   16
+#define CBW_LENGTH                      10
+
+/*
+ *  SENSE KEY定義
+ */
+#define SCSI_SENSE_KEY_NO_SENSE         0x00
+#define SCSI_SENSE_KEY_RECOVERED_ERROR  0x01
+#define SCSI_SENSE_KEY_NOT_READY        0x02
+#define SCSI_SENSE_KEY_MEDIUM_ERROR     0x03
+#define SCSI_SENSE_KEY_HARDWARE_ERROR   0x04
+#define SCSI_SENSE_KEY_ILLEGAL_REQUEST  0x05
+#define SCSI_SENSE_KEY_UNIT_ATTENTION   0x06
+#define SCSI_SENSE_KEY_DATA_PROTECT     0x07
+#define SCSI_SENSE_KEY_BLANK_CHECK      0x08
+#define SCSI_SENSE_KEY_VENDOR_SPECIFIC  0x09
+#define SCSI_SENSE_KEY_COPY_ABORTED     0x0A
+#define SCSI_SENSE_KEY_ABORTED_COMMAND  0x0B
+#define SCSI_SENSE_KEY_VOLUME_OVERFLOW  0x0D
+#define SCSI_SENSE_KEY_MISCOMPARE       0x0E
+
+/*
+ *  MSCコントロール通信定義
+ */
+#define USB_REQ_BOT_RESET               0xFF
+#define USB_REQ_GET_MAX_LUN             0xFE
+
+#define BOT_REQUEST_GETMAXLUN_TYPE      (USB_DEVICE_TO_HOST | USB_REQUEST_TYPE_CLASS | USB_RECIPIENT_INTERFACE)
+#define BOT_REQUEST_RESET_TYPE          (USB_HOST_TO_DEVICE | USB_REQUEST_TYPE_CLASS | USB_RECIPIENT_INTERFACE)
+
+/*
+ *  MSCプロセスの状態定義
+ */
+enum
+{
+	MSC_PROCESS_INIT = 0,
+	MSC_PROCESS_IDLE,
+	MSC_PROCESS_READ_WAIT,
+	MSC_PROCESS_WRITE_WAIT,
+	MSC_PROCESS_REQUEST_SENSE_WAIT
+};
+
+/*
+ *  MSCユニットの状態定義
+ */
+typedef enum
+{
+	MSC_UNIT_INIT = 0,
+	MSC_UNIT_TEST_UNIT_READY_WAIT,
+	MSC_UNIT_READ_CAPACITY_WAIT,
+	MSC_UNIT_READ_INQUIRY_WAIT,
+	MSC_UNIT_REQUEST_SENSE_WAIT,
+	MSC_UNIT_ERROR,
+	MSC_UNIT_IDLE,
+	MSC_UNIT_READ_WAIT,
+	MSC_UNIT_WRITE_WAIT,
+} MSC_UNIT_STATE_t;
+
+/*
+ *  BOT状態定義
+ */
+typedef enum {
+	BOT_SEND_CBW  = 1,
+	BOT_SEND_CBW_WAIT,
+	BOT_DATA_IN_WAIT,
+	BOT_DATA_OUT_WAIT,
+	BOT_RECEIVE_CSW_WAIT,
+	BOT_STATE_ERROR,
+	BOT_STATE_ERROR_WAIT
+} BOT_STATE_t;
+
+typedef struct
+{
+	uint32_t                 Signature;
+	uint32_t                 Tag;
+	uint32_t                 DataTransferLength;
+	uint8_t                  Flags;
+	uint8_t                  LUN;
+	uint8_t                  CBLength;
+	uint8_t                  CB[CBW_CB_LENGTH];
+} BOT_CBW_t;
+
+typedef struct
+{
+	uint32_t                 Signature;
+	uint32_t                 Tag;
+	uint32_t                 DataResidue;
+	uint8_t                  Status;
+} BOT_CSW_t;
+
+/*
+ *  BOTハンドラ型定義
+ */
+typedef struct
+{
+	uint32_t                 data[32];
+	BOT_CBW_t                cbw;
+	uint32_t                 dummy2[8];
+	BOT_CSW_t                csw;
+	uint8_t                  dummy3[12];
+	uint8_t                  *pbuf;
+	BOT_STATE_t              state;
+} BOT_Handle_t;
+
+/*
+ *  MSC ユニット定義
+ */
+typedef struct
+{
+	MSC_UNIT_STATE_t            state; 
+	MSC_UNIT_STATE_t            pre_state;
+	uint32_t                    num_block;
+	uint32_t                    block_size;
+	uint8_t                     DeviceType;
+	uint8_t                     PeripheralQualifier;
+	uint8_t                     RemovableMedia;
+	uint8_t                     vendor_id[12];
+	uint8_t                     product_id[20];
+	uint8_t                     revision_id[8];
+	TUSBH_ERCODE                rw_status;
+	int32_t                     rw_taskid;
+} MSC_Unit_t;
+
+/*
+ *  MSCハンドラ定義
+ */
+typedef struct
+{
+	TUSBH_Device_t            *pDev;
+	uint8_t                   state;
+	uint8_t                   max_lun;
+    uint8_t                   lun;
+	uint8_t                   dymmy1;
+
+	uint8_t                   InPipe;
+	uint8_t                   OutPipe;
+	uint8_t                   OutEp;
+	uint8_t                   InEp;
+	uint16_t                  OutEpSize;
+	uint16_t                  InEpSize;
+	uint32_t                  timer;
+	uint32_t                  urb_wait;
+	uint32_t                  dummy[2];
+	BOT_Handle_t              hbot;
+	MSC_Unit_t                unit[NUM_MAX_MSC_UNIT];
+} MSC_Handle_t;
+
+
+void         tusbhLinkMSC(TUSBH_Handle_t *phost);
+uint8_t      tusbhMscUnitIsReady(TUSBH_Handle_t *phost, uint8_t lun);
+TUSBH_ERCODE tusbhMscGetLUNInfo(TUSBH_Handle_t *phost, uint8_t lun, MSC_Unit_t *info);
+TUSBH_ERCODE tusbhMscRead(TUSBH_Handle_t *phost, uint8_t lun, uint32_t address, uint8_t *pbuf, uint32_t num);
+TUSBH_ERCODE tusbhMscWrite(TUSBH_Handle_t *phost, uint8_t lun, uint32_t address, uint8_t *pbuf, uint32_t num);
+
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _HUSBH_MSC_H_ */
+
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/usb/host/PRT/tusbh_prt.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/usb/host/PRT/tusbh_prt.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/usb/host/PRT/tusbh_prt.c	(revision 457)
@@ -0,0 +1,477 @@
+/*
+ *  TOPPERS BASE PLATFORM MIDDLEWARE
+ * 
+ *  Copyright (C) 2017-2018 by TOPPERS PROJECT
+ *                             Educational Working Group.
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+/*
+ *  USB Host Middleware PRT CLASS部
+ */
+
+#include "tusbh_prt.h"
+
+
+#define CONTROL_STATUS                  1
+#define CONTROL_VENDER                  2
+
+
+#define PRT_REQUEST_VENDER(d, b, c, l)  tusbhControlRequest((d), (b), PRT_VENDER_SEND_TYPE, (c), 0, 0, (l))
+#define PRT_REQUEST_STATUS(d, b, c, l)  tusbhControlRequest((d), (b), PRT_REQUEST_STATUS_TYPE, (c), 0, 0, (l))
+
+
+static TUSBH_ERCODE tusbhPRTInit(TUSBH_Device_t *pdevice);
+static TUSBH_ERCODE tusbhPRTDeInit(TUSBH_Device_t *pdevice);
+static TUSBH_ERCODE tusbhPRTProcess(TUSBH_Device_t *pdevice, uint8_t *mes);
+
+static TUSBH_Class_t PRT_Class = {
+	NULL,
+	"PRT",
+	PRT_CLASS,
+	tusbhPRTInit,
+	tusbhPRTDeInit,
+	tusbhPRTProcess,
+	NULL
+};
+
+/*
+ *  PRTクラスセットアップ関数
+ */
+void tusbhLinkPRT(TUSBH_Handle_t *phost)
+{
+	tusbhLinkClass(phost, &PRT_Class);
+}
+
+/*
+ *  PRTクラス初期設定
+ *  parameter1 pdevice:  デバイスハンドラ
+ *  return     TUSBH_ERCODE
+ */
+static TUSBH_ERCODE
+tusbhPRTInit(TUSBH_Device_t *pdevice)
+{
+	uint8_t interface = 0; 
+	PRT_Handle_t *hprt;
+	TUSBH_Handle_t *phost = pdevice->pHost;
+	uint8_t max_ep, i;
+
+	interface = tusbhFindInterface(pdevice, pdevice->pClass->classCode, 0x01, 0x02);
+
+	if(interface == NO_INTERFACE){
+		syslog_1(LOG_ERROR, "[PRT] Cannot Find the interface for %s class.", pdevice->pClass->Name);
+		return TUSBH_E_ERR;
+	}
+	tusbhSelectInterface(pdevice, interface);
+
+	hprt = (PRT_Handle_t *)tusbmalloc(sizeof(PRT_Handle_t));
+	pdevice->pData = hprt;
+	memset(hprt, 0, sizeof(PRT_Handle_t));
+	max_ep = ((pdevice->ItfDesc[interface].bNumEndpoints <= 2) ?
+              pdevice->ItfDesc[interface].bNumEndpoints : 2);
+#if 1	/* ROI DEBUG */
+	syslog_3(LOG_NOTICE, "## tusbhPRTInit hmsc[%08x] max_ep(%d) buffer(%d) ##", hprt, max_ep, offsetof(PRT_Handle_t, buffer));
+#endif	/* ROI DEBUG */
+
+	for(i = 0 ; i < max_ep; i++){
+		if(pdevice->EpDesc[interface][i].bEndpointAddress & 0x80){
+			hprt->InEp     = (pdevice->EpDesc[interface][i].bEndpointAddress);
+			hprt->InEpSize = pdevice->EpDesc[interface][i].wMaxPacketSize;
+			hprt->InPipe = tusbhAllocPipe(phost, hprt->InEp);
+		}
+		else{
+			hprt->OutEp = (pdevice->EpDesc[interface][i].bEndpointAddress);
+			hprt->OutEpSize = pdevice->EpDesc[interface][i].wMaxPacketSize;
+			hprt->OutPipe = tusbhAllocPipe(phost, hprt->OutEp);
+		}
+	}
+	if(hprt->OutPipe == 0 || hprt->InPipe == 0)
+		return TUSBH_E_ERR;
+
+	hprt->state = PRT_PROCESS_INIT;
+	hprt->timer = 0;
+	hprt->pDev = pdevice;
+
+	/*
+	 *  NSCチャネルオープン
+	 */
+	tusbhOpenPipe(pdevice, hprt->OutPipe, hprt->OutEp, USB_EP_TYPE_BULK, hprt->OutEpSize);
+	tusbhHDSetToggle(phost, hprt->OutPipe, 0);
+	tusbhOpenPipe(pdevice, hprt->InPipe, hprt->InEp, USB_EP_TYPE_BULK, hprt->InEpSize);
+	tusbhHDSetToggle(phost, hprt->InPipe, 0);
+
+	/* タイマースタート */
+	pdevice->timeid = pdevice->timecount = 100;
+	return TUSBH_E_OK;
+}
+
+/*
+ *  PRTクラス終了設定
+ *  parameter1 pdevice:  デバイスハンドラ
+ *  return     TUSBH_ERCODE
+ */
+static TUSBH_ERCODE
+tusbhPRTDeInit(TUSBH_Device_t *pdevice)
+{
+	PRT_Handle_t *hprt;
+	TUSBH_Handle_t *phost = pdevice->pHost;
+
+	hprt = (PRT_Handle_t *)pdevice->pData;
+	if(hprt->OutPipe != 0){
+		tusbhClosePipe(pdevice, hprt->OutPipe);
+		tusbFreePipe(phost, hprt->OutPipe);
+		hprt->OutPipe = 0;
+	}
+
+	if(hprt->InPipe != 0){
+		tusbhClosePipe(pdevice, hprt->InPipe);
+		tusbFreePipe(phost, hprt->InPipe);
+		hprt->InPipe = 0;
+	}
+
+	if(pdevice->pData != NULL){
+		tusbfree(pdevice->pData);
+		pdevice->pData = NULL;
+	}
+	return TUSBH_E_OK;
+}
+
+/*
+ *  PRTクラスプロセス実行
+ *  parameter1 pdevice:  デバイスハンドラ
+ *  parameter2 mes:      通信メッセージへのポインタ
+ *  return     TUSBH_ERCODE
+ */
+static TUSBH_ERCODE
+tusbhPRTProcess(TUSBH_Device_t *pdevice, uint8_t *mes)
+{
+	PRT_Handle_t   *hprt  = (PRT_Handle_t *)pdevice->pData;
+	TUSBH_Handle_t *phost = pdevice->pHost;
+	void (*func)(TUSBH_Device_t *, uint8_t, TUSBH_ERCODE, uint32_t) = pdevice->pClass->subfunc;
+	TUSBH_URBState_t URB_Status = mes[3];
+	TUSBH_ERCODE ercd = TUSBH_E_BUSY;
+	int32_t length;
+
+    if(mes[0] == TUSBH_URB_EVENT){
+		hprt->urb_wait = 0;
+    }
+	else if(mes[0] == TUSBH_TIME_EVENT){
+		hprt->timer += mes[3];
+		pdevice->timecount = mes[3];
+	}
+	else if(mes[0] == TUSBH_CLASS_EVENT && mes[2] != 0)
+		hprt->state = mes[2];
+	switch (hprt->state){
+	case PRT_PROCESS_INIT:
+		if(phost->usrcallback != NULL)
+			phost->usrcallback(phost, pdevice, HOST_USER_CLASS_ACTIVE);
+		hprt->state = PRT_PROCESS_IDLE;
+	case PRT_PROCESS_IDLE:
+		if(mes[0] != TUSBH_URB_EVENT){
+			ercd = TUSBH_E_OK;
+			break;
+		}
+		if(mes[2] == pdevice->cntl_pipe_in || mes[2] == pdevice->cntl_pipe_out){
+			ercd = tusbhControlWait(pdevice, mes);
+			if(ercd == TUSBH_E_OK){
+				hprt->state = PRT_PROCESS_IDLE;
+				hprt->controlType = 0;
+			}
+			else if(ercd != TUSBH_E_BUSY && ercd != TUSBH_E_BUSY_URB){
+				hprt->state = PRT_PROCESS_ERROR;
+				hprt->controlType = 0;
+			}
+			break;
+		}
+		else if(URB_Status == TUSBH_URB_DONE){
+			if(mes[2] == hprt->InPipe){
+				hprt->RxTrnPktSize = tusbhHDTrasLength(phost, hprt->InPipe);
+				hprt->RxTrnLength += hprt->RxTrnPktSize;
+				hprt->pRxTrnBuff += hprt->RxTrnPktSize;
+				hprt->rwr_status = TUSBH_E_OK;
+				if(func != NULL)
+					func(pdevice, PRT_LINE_STATUS_RECEIVED, TUSBH_E_OK, hprt->RxTrnLength);
+			}
+			else{
+				hprt->TxTrnLength += hprt->TxTrnPktSize;
+				hprt->pTxTrnBuff += hprt->TxTrnPktSize;
+				if(hprt->TxTrnSize > hprt->TxTrnLength)
+					hprt->state = PRT_PROCESS_SEND;
+				else{
+					hprt->rwt_status = TUSBH_E_OK;
+					if(func != NULL)
+						func(pdevice, PRT_LINE_STATUS_SENDED, TUSBH_E_OK, hprt->TxTrnLength);
+				}
+			}
+		}
+		else if(URB_Status == TUSBH_URB_NOTREADY){
+			if(mes[2] == hprt->InPipe)
+				hprt->state = PRT_PROCESS_RECEIVE;
+			else
+				hprt->state = PRT_PROCESS_SEND;
+		}
+		else{
+			hprt->state = PRT_PROCESS_ERROR;
+			if(mes[2] == hprt->InPipe)
+				hprt->rwr_status = TUSBH_E_ERR;
+			else
+				hprt->rwt_status = TUSBH_E_ERR;
+			if(func != NULL)
+				func(pdevice, PRT_LINE_STATUS_CHANGED, TUSBH_E_ERR, 0);
+		}
+		tusbSendData(phost->process_event, TUSBH_CLASS_EVENT, pdevice->idx, 0, 0);
+		break;
+	case PRT_PROCESS_CONTROL:
+		if(hprt->controlType == CONTROL_VENDER)
+			PRT_REQUEST_VENDER(pdevice, hprt->buffer, hprt->controlRequest, hprt->controlLength);
+		else
+			PRT_REQUEST_STATUS(pdevice, hprt->buffer, hprt->controlRequest, hprt->controlLength);
+		hprt->state = PRT_PROCESS_IDLE;
+		break;
+	case PRT_PROCESS_SEND:
+		length = hprt->TxTrnSize - hprt->TxTrnLength;
+		if(length > hprt->OutEpSize)
+			hprt->TxTrnPktSize = hprt->OutEpSize;
+		else
+			hprt->TxTrnPktSize = length;
+		tusbhBulkWrite(pdevice, hprt->pTxTrnBuff, hprt->TxTrnPktSize, hprt->OutPipe);
+		hprt->state = PRT_PROCESS_IDLE;
+		break;
+	case PRT_PROCESS_RECEIVE:
+		length = hprt->RxTrnSize - hprt->RxTrnLength;
+		if(length > hprt->InEpSize)
+			hprt->RxTrnPktSize = hprt->InEpSize;
+		else
+			hprt->RxTrnPktSize = length;
+		tusbhBulkRead(pdevice, hprt->pRxTrnBuff, hprt->RxTrnPktSize, hprt->InPipe);
+		hprt->state = PRT_PROCESS_IDLE;
+		break;
+	case PRT_PROCESS_ERROR:
+		tusbhClearFeature(pdevice, 0x00);
+		hprt->state = PRT_PROCESS_ERROR_WAIT;
+		break;
+	case PRT_PROCESS_ERROR_WAIT:
+		if(tusbhControlWait(pdevice, mes) == TUSBH_E_OK)
+			hprt->state = PRT_PROCESS_IDLE;
+		break;
+
+
+	default:
+		break;
+	}
+	return ercd;
+}
+
+/*
+ *  PRT SEND EOJ
+ *  parameter1 phost:   ホストハンドラ
+ *  parameter2 unit:    UNIT#
+ *  parameter3 cmd:     設定コマンド
+ *  return     TUSBH_ERCODE
+ */
+TUSBH_ERCODE
+tusbhPrtEOJ(TUSBH_Handle_t *phost, uint8_t unit, uint8_t cmd, uint8_t prm1, uint8_t prm2)
+{
+	TUSBH_Device_t *pdevice = tusbhSearchDevice(phost, PRT_Class.classCode, &unit);
+	PRT_Handle_t *hprt;
+
+	if(pdevice == NULL)
+		return TUSBH_E_OBJ;
+	hprt = (PRT_Handle_t *)pdevice->pData;
+	if(pdevice->dstate == DEVICE_CLASS){
+		hprt->buffer[0] = cmd;
+		hprt->buffer[1] = prm1;
+		hprt->buffer[2] = prm2;
+		hprt->controlType    = CONTROL_VENDER;
+		hprt->controlRequest  = PRT_VERNDER_REQUEST_EOJ;
+		hprt->controlLength  = 3;
+		hprt->state = PRT_PROCESS_CONTROL;
+		tusbSendData(phost->process_event, TUSBH_CLASS_EVENT, pdevice->idx, 0, 0);
+		while(hprt->controlType != 0){
+			tusbSleep(1);
+		}
+	}
+	return TUSBH_E_OK;
+}
+
+/*
+ *  PRT GET PORTID
+ *  parameter1 phost:   ホストハンドラ
+ *  parameter2 unit:    UNIT#
+ *  parameter3 cmd:     設定コマンド
+ *  return     TUSBH_ERCODE
+ */
+TUSBH_ERCODE
+tusbhPrtPortID(TUSBH_Handle_t *phost, uint8_t unit, uint8_t *buf)
+{
+	TUSBH_Device_t *pdevice = tusbhSearchDevice(phost, PRT_Class.classCode, &unit);
+	PRT_Handle_t *hprt;
+
+	if(pdevice == NULL)
+		return TUSBH_E_OBJ;
+	hprt = (PRT_Handle_t *)pdevice->pData;
+	if(pdevice->dstate == DEVICE_CLASS){
+		hprt->controlType    = CONTROL_STATUS;
+		hprt->controlRequest = PRT_REQUEST_DEVICEID;
+		hprt->controlLength  = 1;
+		tusbSendData(phost->process_event, TUSBH_CLASS_EVENT, pdevice->idx, PRT_PROCESS_CONTROL, 0);
+		while(hprt->controlType != 0){
+			tusbSleep(1);
+		}
+		*buf = hprt->buffer[0];
+	}
+	return TUSBH_E_OK;
+}
+
+/*
+ *  PRT GET PRINT STATUS
+ *  parameter1 phost:   ホストハンドラ
+ *  parameter2 unit:    UNIT#
+ *  parameter3 cmd:     設定コマンド
+ *  return     TUSBH_ERCODE
+ */
+TUSBH_ERCODE
+tusbhPrtPortStatus(TUSBH_Handle_t *phost, uint8_t unit, uint8_t *buf, uint32_t length)
+{
+	TUSBH_Device_t *pdevice = tusbhSearchDevice(phost, PRT_Class.classCode, &unit);
+	PRT_Handle_t *hprt;
+	uint32_t trans_len, packet_len;
+
+	if(length > PRT_MAX_PORTSTATUS_SIZE)
+		trans_len = PRT_MAX_PORTSTATUS_SIZE;
+	else
+		trans_len = length;
+	if(pdevice == NULL)
+		return TUSBH_E_OBJ;
+	hprt = (PRT_Handle_t *)pdevice->pData;
+	if(pdevice->dstate == DEVICE_CLASS){
+		hprt->controlType    = CONTROL_STATUS;
+		hprt->controlRequest = PRT_REQUEST_PORTSTATUS;
+		hprt->controlLength  = trans_len;
+		tusbSendData(phost->process_event, TUSBH_CLASS_EVENT, pdevice->idx, PRT_PROCESS_CONTROL, 0);
+		while(hprt->controlType != 0){
+			tusbSleep(1);
+		}
+		packet_len = (hprt->buffer[0] << 8) | hprt->buffer[1];
+		if(trans_len > (packet_len + 2))
+			trans_len = packet_len + 2;
+		tusbmemcpy(buf, hprt->buffer, trans_len);
+	}
+	return TUSBH_E_OK;
+}
+
+/*
+ *  PRT DATA RECEIVE
+ *  parameter1 phost:   ホストハンドラ
+ *  parameter2 unit:    UNIT#
+ *  parameter3 pbuf:    受信データ領域へのポインタ
+ *  parameter4 length:  受信ブロック長
+ *  return     TUSBH_ERCODE
+ */
+TUSBH_ERCODE
+tusbhPrtReceive(TUSBH_Handle_t *phost, uint8_t unit, uint8_t *pbuf, uint32_t length)
+{
+	TUSBH_Device_t *pdevice = tusbhSearchDevice(phost, PRT_Class.classCode, &unit);
+	PRT_Handle_t *hprt;
+
+	if(pdevice != NULL){
+		hprt = pdevice->pData;
+		if(pdevice->dstate != DEVICE_CLASS)
+			return TUSBH_E_OBJ;
+		if(hprt->state == PRT_PROCESS_ERROR)
+			return TUSBH_E_ERR;
+		if(hprt->rwr_status == TUSBH_E_BUSY)
+			return TUSBH_E_OBJ;
+	}
+	else
+		return TUSBH_E_OBJ;
+
+    /*
+	 *  受信データ設定
+	 */
+	hprt->RxTrnSize   = length;
+	hprt->RxTrnLength = 0;
+	hprt->pRxTrnBuff  = pbuf;
+	hprt->rwr_status  = TUSBH_E_BUSY;
+	tusbSendData(phost->process_event, TUSBH_CLASS_EVENT, pdevice->idx, PRT_PROCESS_RECEIVE, 0);
+	return TUSBH_E_OK;
+}
+
+/*
+ *  PRT DATA SEND
+ *  parameter1 phost:   ホストハンドラ
+ *  parameter2 unit:    UNIT#
+ *  parameter3 pbuf:    送信データ領域へのポインタ
+ *  parameter4 length:  送信データ長
+ *  return     TUSBH_ERCODE
+ */
+TUSBH_ERCODE
+tusbhPrtSend(TUSBH_Handle_t *phost, uint8_t unit, uint8_t *pbuf, uint32_t length)
+{
+	TUSBH_Device_t *pdevice = tusbhSearchDevice(phost, PRT_Class.classCode, &unit);
+	PRT_Handle_t *hprt;
+
+	if(pdevice != NULL){
+		hprt = pdevice->pData;
+		if(pdevice->dstate != DEVICE_CLASS)
+			return TUSBH_E_OBJ;
+		if(hprt->state == PRT_PROCESS_ERROR)
+			return TUSBH_E_ERR;
+		if(hprt->rwt_status == TUSBH_E_BUSY)
+			return TUSBH_E_OBJ;
+	}
+	else
+		return TUSBH_E_OBJ;
+
+    /*
+	 *  送信データ設定
+	 */
+	hprt->TxTrnSize   = length;
+	hprt->TxTrnLength = 0;
+	hprt->pTxTrnBuff  = pbuf;
+	hprt->rwt_status  = TUSBH_E_BUSY;
+	tusbSendData(phost->process_event, TUSBH_CLASS_EVENT, pdevice->idx, PRT_PROCESS_SEND, 0);
+	return TUSBH_E_OK;
+}
+
+/*
+ *  PRTコールバック関数
+ *  parameter1 phost:   ホストハンドラ
+ *  parameter2 func:    関数ポインタ
+ */
+void
+tusbhSetPrtCallBack(TUSBH_Handle_t *phost, void (*func)(TUSBH_Device_t *p, uint8_t, TUSBH_ERCODE, uint32_t))
+{
+	PRT_Class.subfunc = func;
+}
+
+
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/usb/host/PRT/tusbh_prt.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/usb/host/PRT/tusbh_prt.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/usb/host/PRT/tusbh_prt.h	(revision 457)
@@ -0,0 +1,132 @@
+/*
+ *  TOPPERS BASE PLATFORM MIDDLEWARE
+ * 
+ *  Copyright (C) 2017-2018 by TOPPERS PROJECT
+ *                             Educational Working Group.
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+/*
+ *  USB Host Middleware PRT部定義
+ */
+
+#ifndef _HUSBH_PRT_H_
+#define _HUSBH_PRT_H_
+
+#include "tusbh_base.h"
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+
+#define PRT_VERNDER_REQUEST_EOJ     0
+#define PRT_REQUEST_PORTSTATUS      0
+#define PRT_REQUEST_DEVICEID        1
+#define PRT_REQUEST_SOFTRESET       2
+
+#define PRT_MAX_PORTSTATUS_SIZE     256
+
+#define PRT_REQUEST_STATUS_TYPE         (USB_DEVICE_TO_HOST | USB_REQUEST_TYPE_CLASS | USB_RECIPIENT_INTERFACE)
+#define PRT_VENDER_SEND_TYPE            (USB_HOST_TO_DEVICE | USB_REQUEST_TYPE_VENDOR | USB_RECIPIENT_INTERFACE)
+
+/*
+ *  PRTコールバックコード定義
+ */
+#define PRT_LINE_STATUS_CHANGED         1
+#define PRT_LINE_STATUS_SENDED          2
+#define PRT_LINE_STATUS_RECEIVED        3
+
+/*
+ *  PRTプロセスの状態定義
+ */
+enum
+{
+	PRT_PROCESS_INIT = 0,
+	PRT_PROCESS_IDLE,
+	PRT_PROCESS_CONTROL,
+	PRT_PROCESS_SEND,
+	PRT_PROCESS_RECEIVE,
+	PRT_PROCESS_ERROR,
+	PRT_PROCESS_ERROR_WAIT
+};
+
+/*
+ *  PRTハンドラ定義
+ */
+typedef struct
+{
+	TUSBH_Device_t            *pDev;
+	uint8_t                   state;
+	uint8_t                   cmd;
+	uint8_t                   dummy[2];
+	uint16_t                  TxTrnPktSize;
+	uint16_t                  RxTrnPktSize;
+
+	uint8_t                   InPipe;
+	uint8_t                   OutPipe;
+	uint8_t                   OutEp;
+	uint8_t                   InEp;
+	uint16_t                  OutEpSize;
+	uint16_t                  InEpSize;
+	uint8_t                   controlType;
+	uint8_t                   controlRequest;
+	uint16_t                  controlLength;
+	uint32_t                  TxTrnLength;
+	uint32_t                  TxTrnSize;
+	uint8_t                   *pTxTrnBuff;
+	uint32_t                  RxTrnLength;
+	uint32_t                  RxTrnSize;
+	uint8_t                   *pRxTrnBuff;
+	uint32_t                  timer;
+	uint32_t                  urb_wait;
+	uint32_t                  rwt_status;
+	uint32_t                  rwr_status;
+	uint8_t                   buffer[PRT_MAX_PORTSTATUS_SIZE];
+} PRT_Handle_t;
+
+
+void         tusbhLinkPRT(TUSBH_Handle_t *phost);
+TUSBH_ERCODE tusbhPrtEOJ(TUSBH_Handle_t *phost, uint8_t unit, uint8_t cmd, uint8_t prm1, uint8_t prm2);
+TUSBH_ERCODE tusbhPrtPortID(TUSBH_Handle_t *phost, uint8_t unit, uint8_t *buf);
+TUSBH_ERCODE tusbhPrtPortStatus(TUSBH_Handle_t *phost, uint8_t unit, uint8_t *buf, uint32_t length);
+TUSBH_ERCODE tusbhPrtSend(TUSBH_Handle_t *phost, uint8_t unit, uint8_t *pbuf, uint32_t length);
+TUSBH_ERCODE tusbhPrtReceive(TUSBH_Handle_t *phost, uint8_t unit, uint8_t *pbuf, uint32_t length);
+void tusbhSetPrtCallBack(TUSBH_Handle_t *phost, void (*func)(TUSBH_Device_t *p, uint8_t, TUSBH_ERCODE, uint32_t));
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _HUSBH_PRT_H_ */
+
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/usb/host/SERIAL/tusbh_serial.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/usb/host/SERIAL/tusbh_serial.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/usb/host/SERIAL/tusbh_serial.c	(revision 457)
@@ -0,0 +1,498 @@
+/*
+ *  TOPPERS BASE PLATFORM MIDDLEWARE
+ * 
+ *  Copyright (C) 2017-2018 by TOPPERS PROJECT
+ *                             Educational Working Group.
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+/*
+ *  USB Host Middleware CDC:SERIAL CLASS部
+ */
+
+#include "tusbh_serial.h"
+
+
+#define CDC_REQUEST_GETLINE(d, b)   tusbhControlRequest((d), (b), CDC_REQUEST_GETLINE_TYPE, CDC_GET_LINE_CODING, 0, 0, LINE_CODING_STRUCTURE_SIZE)
+#define CDC_REQUEST_SETLINE(d, b)   tusbhControlRequest((d), (b), CDC_REQUEST_SETLINE_TYPE, CDC_SET_LINE_CODING, 0, 0, LINE_CODING_STRUCTURE_SIZE)
+
+
+static TUSBH_ERCODE tusbhCDCInit(TUSBH_Device_t *pdevice);
+static TUSBH_ERCODE tusbhCDCDeInit(TUSBH_Device_t *pdevice);
+static TUSBH_ERCODE tusbhCDCProcess(TUSBH_Device_t *pdevice, uint8_t *mes);
+
+static TUSBH_Class_t SERAIL_Class = {
+	NULL,
+	"CDC",
+	CDC_CLASS,
+	tusbhCDCInit,
+	tusbhCDCDeInit,
+	tusbhCDCProcess,
+	NULL
+};
+
+/*
+ *  SERIALクラスセットアップ関数
+ */
+void tusbhLinkSERIAL(TUSBH_Handle_t *phost)
+{
+	tusbhLinkClass(phost, &SERAIL_Class);
+}
+
+/*
+ *  CDCクラス初期設定
+ *  parameter1 pdevice:  デバイスハンドラ
+ *  return     TUSBH_ERCODE
+ */
+static TUSBH_ERCODE
+tusbhCDCInit(TUSBH_Device_t *pdevice)
+{
+	uint8_t interface = 0; 
+	CDC_Handle_t *hcdc;
+	TUSBH_Handle_t *phost = pdevice->pHost;
+	uint8_t max_ep, i;
+
+	interface = tusbhFindInterface(pdevice, pdevice->pClass->classCode, ABSTRACT_CONTROL_MODEL, CDC_ITU_T_V_250);
+
+	if(interface == NO_INTERFACE){
+		syslog_1(LOG_ERROR, "[CDC] Cannot Find the interface for %s class.", pdevice->pClass->Name);
+		return TUSBH_E_ERR;
+	}
+	tusbhSelectInterface(pdevice, interface);
+
+	hcdc = (CDC_Handle_t *)tusbmalloc(sizeof(CDC_Handle_t));
+	pdevice->pData = hcdc;
+	memset(hcdc, 0, sizeof(CDC_Handle_t));
+	max_ep = ((pdevice->ItfDesc[interface].bNumEndpoints <= 2) ?
+              pdevice->ItfDesc[interface].bNumEndpoints : 2);
+#if 1	/* ROI DEBUG */
+	syslog_3(LOG_NOTICE, "## tusbhCDCInit hmsc[%08x] max_ep(%d) csw(%d) ##", hcdc, max_ep, 0);
+#endif	/* ROI DEBUG */
+	if(max_ep == 0 || (pdevice->EpDesc[interface][0].bEndpointAddress & 0x80) == 0)
+		return TUSBH_E_ERR;
+
+	hcdc->CommInEp     = pdevice->EpDesc[interface][0].bEndpointAddress;
+    hcdc->CommInEpSize = pdevice->EpDesc[interface][0].wMaxPacketSize;
+	hcdc->CommInPipe   = tusbhAllocPipe(phost, hcdc->CommInEp);
+
+	/*
+	 *  COMMNUCATION IN ENDPOINT OPEN
+	 */
+	tusbhOpenPipe(pdevice, hcdc->CommInPipe, hcdc->CommInEp, USB_EP_TYPE_INTR, hcdc->CommInEpSize);
+	tusbhHDSetToggle(phost, hcdc->CommInPipe, 0);
+
+    interface = tusbhFindInterface(pdevice, DATA_INTERFACE_CLASS, 0x00, DIC_NO_SPECIFIC_PROTOCOL_CODE);
+	if(interface == NO_INTERFACE){
+		syslog_1(LOG_ERROR, "[CDC] Cannot Find the interface for %s class.", pdevice->pClass->Name);
+		return TUSBH_E_ERR;
+	}
+	max_ep = ((pdevice->ItfDesc[interface].bNumEndpoints <= 2) ?
+              pdevice->ItfDesc[interface].bNumEndpoints : 2);
+
+	for(i = 0 ; i < max_ep; i++){
+		if(pdevice->EpDesc[interface][i].bEndpointAddress & 0x80){
+			hcdc->InEp     = (pdevice->EpDesc[interface][i].bEndpointAddress);
+			hcdc->InEpSize = pdevice->EpDesc[interface][i].wMaxPacketSize;
+			hcdc->InPipe = tusbhAllocPipe(phost, hcdc->InEp);
+		}
+		else{
+			hcdc->OutEp = (pdevice->EpDesc[interface][i].bEndpointAddress);
+			hcdc->OutEpSize = pdevice->EpDesc[interface][i].wMaxPacketSize;
+			hcdc->OutPipe = tusbhAllocPipe(phost, hcdc->OutEp);
+		}
+	}
+	if(hcdc->OutPipe == 0 || hcdc->InPipe == 0)
+		return TUSBH_E_ERR;
+
+	hcdc->state = CDC_PROCESS_INIT;
+	hcdc->timer = 0;
+	hcdc->pDev = pdevice;
+
+	/*
+	 *  NSCチャネルオープン
+	 */
+	tusbhOpenPipe(pdevice, hcdc->OutPipe, hcdc->OutEp, USB_EP_TYPE_BULK, hcdc->OutEpSize);
+	tusbhHDSetToggle(phost, hcdc->OutPipe, 0);
+	tusbhOpenPipe(pdevice, hcdc->InPipe, hcdc->InEp, USB_EP_TYPE_BULK, hcdc->InEpSize);
+	tusbhHDSetToggle(phost, hcdc->InPipe, 0);
+
+	/* タイマースタート */
+	pdevice->timeid = pdevice->timecount = 100;
+	return TUSBH_E_OK;
+}
+
+/*
+ *  CDCクラス終了設定
+ *  parameter1 pdevice:  デバイスハンドラ
+ *  return     TUSBH_ERCODE
+ */
+static TUSBH_ERCODE
+tusbhCDCDeInit(TUSBH_Device_t *pdevice)
+{
+	CDC_Handle_t *hcdc;
+	TUSBH_Handle_t *phost = pdevice->pHost;
+
+	hcdc = (CDC_Handle_t *)pdevice->pData;
+	if(hcdc->CommInPipe != 0){
+		tusbhClosePipe(pdevice, hcdc->CommInPipe);
+		tusbFreePipe(phost, hcdc->CommInPipe);
+		hcdc->CommInPipe = 0;
+	}
+
+	if(hcdc->OutPipe != 0){
+		tusbhClosePipe(pdevice, hcdc->OutPipe);
+		tusbFreePipe(phost, hcdc->OutPipe);
+		hcdc->OutPipe = 0;
+	}
+
+	if(hcdc->InPipe != 0){
+		tusbhClosePipe(pdevice, hcdc->InPipe);
+		tusbFreePipe(phost, hcdc->InPipe);
+		hcdc->InPipe = 0;
+	}
+
+	if(pdevice->pData != NULL){
+		tusbfree(pdevice->pData);
+		pdevice->pData = NULL;
+	}
+	return TUSBH_E_OK;
+}
+
+/*
+ *  CDCクラスプロセス実行
+ *  parameter1 pdevice:  デバイスハンドラ
+ *  parameter2 mes:      通信メッセージへのポインタ
+ *  return     TUSBH_ERCODE
+ */
+static TUSBH_ERCODE
+tusbhCDCProcess(TUSBH_Device_t *pdevice, uint8_t *mes)
+{
+	CDC_Handle_t   *hcdc  = (CDC_Handle_t *)pdevice->pData;
+	TUSBH_Handle_t *phost = pdevice->pHost;
+	void (*func)(TUSBH_Device_t *, uint8_t) = pdevice->pClass->subfunc;
+	TUSBH_URBState_t URB_Status = mes[3];
+	TUSBH_ERCODE ercd = TUSBH_E_BUSY;
+	TUSBH_ERCODE status;
+	int32_t length;
+	uint8_t cmd = CDC_LINE_STATUS_CHANGED;
+
+    if(mes[0] == TUSBH_URB_EVENT)
+		hcdc->urb_wait = 0;
+	else if(mes[0] == TUSBH_TIME_EVENT){
+		hcdc->timer += mes[3];
+		pdevice->timecount = mes[3];
+	}
+	else if(mes[0] == TUSBH_CLASS_EVENT && mes[2] != 0)
+		hcdc->state  = mes[2];
+	switch (hcdc->state){
+	case CDC_PROCESS_INIT:
+		CDC_REQUEST_GETLINE(pdevice, (uint8_t *)(&hcdc->oLineCoding));
+		hcdc->state = CDC_PROCESS_INIT_WAIT;
+		break;
+	case CDC_PROCESS_INIT_WAIT:
+		status = tusbhControlWait(pdevice, mes);
+		if(status == TUSBH_E_OK){
+			if(phost->usrcallback != NULL)
+				phost->usrcallback(phost, pdevice, HOST_USER_CLASS_ACTIVE);
+			hcdc->state = CDC_PROCESS_IDLE;
+		}
+		else if(status != TUSBH_E_BUSY && status != TUSBH_E_BUSY_URB)
+			hcdc->state = CDC_PROCESS_ERROR;
+		break;
+	case CDC_PROCESS_IDLE:
+		if(mes[0] != TUSBH_URB_EVENT){
+			ercd = TUSBH_E_OK;
+			break;
+		}
+		if(mes[2] == pdevice->cntl_pipe_in || mes[2] == pdevice->cntl_pipe_out){
+			status = tusbhControlWait(pdevice, mes);
+			if(status == TUSBH_E_OK){
+				hcdc->state = CDC_PROCESS_IDLE;
+				if((hcdc->oLineCoding.stop_bits != hcdc->uLineCoding.stop_bits) ||
+					(hcdc->oLineCoding.data_bits != hcdc->uLineCoding.data_bits) ||
+					(hcdc->oLineCoding.parity != hcdc->uLineCoding.parity) ||
+					(hcdc->oLineCoding.baudrate != hcdc->uLineCoding.baudrate)){
+						if(func != NULL)
+							func(pdevice, CDC_LINE_STATUS_CHANGED);
+				}
+			}
+			else if(status != TUSBH_E_BUSY && status != TUSBH_E_BUSY_URB)
+				hcdc->state = CDC_PROCESS_ERROR;
+		}
+		else if(hcdc->rw_status != TUSBH_E_BUSY)
+			hcdc->state = CDC_PROCESS_ERROR;
+		else if(URB_Status == TUSBH_URB_DONE){
+			if(mes[2] == hcdc->InPipe){
+				hcdc->RxTrnPktSize = tusbhHDTrasLength(phost, hcdc->InPipe);
+				cmd = CDC_LINE_STATUS_RECEIVED;
+				hcdc->RxTrnLength += hcdc->RxTrnPktSize;
+				hcdc->pRxTrnBuff += hcdc->RxTrnPktSize;
+				hcdc->state = CDC_PROCESS_IDLE;
+			}
+			else{
+				cmd = CDC_LINE_STATUS_SENDED;
+				hcdc->TxTrnLength += hcdc->TxTrnPktSize;
+				hcdc->pTxTrnBuff += hcdc->TxTrnPktSize;
+				if(hcdc->TxTrnSize > hcdc->TxTrnLength)
+					hcdc->state = CDC_PROCESS_SEND;
+				else
+					hcdc->state = CDC_PROCESS_IDLE;
+			}
+			if(hcdc->state == CDC_PROCESS_IDLE){
+				hcdc->rw_status = TUSBH_E_OK;
+				if(func != NULL)
+					func(pdevice, cmd);
+				if(hcdc->rw_taskid != 0)
+					tusbWakeup(hcdc->rw_taskid);
+			}
+		}
+		else if(URB_Status == TUSBH_URB_NOTREADY){
+			if(mes[2] == hcdc->InPipe)
+				hcdc->state = CDC_PROCESS_RECEIVE;
+			else
+				hcdc->state = CDC_PROCESS_SEND;
+		}
+		else{
+			hcdc->state = CDC_PROCESS_ERROR;
+			hcdc->rw_status = TUSBH_E_ERR;
+			if(func != NULL)
+				func(pdevice, cmd);
+			if(hcdc->rw_taskid != 0)
+				tusbWakeup(hcdc->rw_taskid);
+		}
+		tusbSendData(phost->process_event, TUSBH_CLASS_EVENT, pdevice->idx, 0, 0);
+		break;
+	case CDC_PROCESS_SET_LINE_CODING:
+		CDC_REQUEST_SETLINE(pdevice, (uint8_t *)&hcdc->uLineCoding);
+		hcdc->state = CDC_PROCESS_SET_LINE_CODING_WAIT;
+		break;
+	case CDC_PROCESS_SET_LINE_CODING_WAIT:
+		status = tusbhControlWait(pdevice, mes);
+		if(status == TUSBH_E_OK)
+			hcdc->state = CDC_PROCESS_GET_LINE_CODING;
+		else if(status != TUSBH_E_BUSY && status != TUSBH_E_BUSY_URB)
+			hcdc->state = CDC_PROCESS_ERROR;
+		break;
+	case CDC_PROCESS_GET_LINE_CODING:
+		CDC_REQUEST_GETLINE(pdevice, (uint8_t *)&hcdc->uLineCoding);
+		hcdc->state = CDC_PROCESS_IDLE;
+		break;
+	case CDC_PROCESS_SEND:
+		length = hcdc->TxTrnSize - hcdc->TxTrnLength;
+		if(length > hcdc->OutEpSize)
+			hcdc->TxTrnPktSize = hcdc->OutEpSize;
+		else
+			hcdc->TxTrnPktSize = length;
+		tusbhBulkWrite(pdevice, hcdc->pTxTrnBuff, hcdc->TxTrnPktSize, hcdc->OutPipe);
+		hcdc->state = CDC_PROCESS_IDLE;
+		break;
+	case CDC_PROCESS_RECEIVE:
+		length = hcdc->RxTrnSize - hcdc->RxTrnLength;
+		if(length > hcdc->InEpSize)
+			hcdc->RxTrnPktSize = hcdc->InEpSize;
+		else
+			hcdc->RxTrnPktSize = length;
+		tusbhBulkRead(pdevice, hcdc->pRxTrnBuff, hcdc->RxTrnPktSize, hcdc->InPipe);
+		hcdc->state = CDC_PROCESS_IDLE;
+		break;
+	case CDC_PROCESS_ERROR:
+		tusbhClearFeature(pdevice, 0x00);
+		hcdc->state = CDC_PROCESS_ERROR_WAIT;
+		break;
+	case CDC_PROCESS_ERROR_WAIT:
+		if(tusbhControlWait(pdevice, mes) == TUSBH_E_OK)
+			hcdc->state = CDC_PROCESS_IDLE;
+		break;
+	default:
+		break;
+	}
+	return ercd;
+}
+
+/*
+ *  SERIAL LINE CODINGデータ領域を設定
+ *  parameter1 phost:   ホストハンドラ
+ *  parameter2 unit:    UNIT#
+ *  parameter3 linecod: ユーザのLINE CODING格納領域へのポインタ
+ *  return     TUSBH_ERCODE
+ */
+TUSBH_ERCODE
+tusbhCdcSetLineCoding(TUSBH_Handle_t *phost, uint8_t unit, Line_Coding_t *linecod)
+{
+	TUSBH_Device_t *pdevice = tusbhSearchDevice(phost, SERAIL_Class.classCode, &unit);
+	CDC_Handle_t *hcdc;
+
+	if(pdevice == NULL)
+		return TUSBH_E_OBJ;
+	hcdc = (CDC_Handle_t *)pdevice->pData;
+	if(pdevice->dstate == DEVICE_CLASS){
+		tusbmemcpy(&hcdc->uLineCoding, linecod, sizeof(Line_Coding_t));
+		tusbSendData(phost->process_event, TUSBH_CLASS_EVENT, pdevice->idx, CDC_PROCESS_SET_LINE_CODING, 0);
+	}
+	return TUSBH_E_OK;
+}
+
+/*
+ *  SERIAL LINE CODINGデータ取得
+ *  parameter1 phost:   ホストハンドラ
+ *  parameter2 unit:    UNIT#
+ *  parameter3 linecod: LINE CODING格納領域へのポインタ
+ *  return     TUSBH_ERCODE
+*/
+TUSBH_ERCODE
+tusbhCdcGetLineCoding(TUSBH_Handle_t *phost, uint8_t unit, Line_Coding_t *linecod)
+{
+	TUSBH_Device_t *pdevice = tusbhSearchDevice(phost, SERAIL_Class.classCode, &unit);
+	CDC_Handle_t *hcdc;
+
+	if(pdevice == NULL)
+		return TUSBH_E_OBJ;
+	hcdc = pdevice->pData;
+	*linecod = hcdc->oLineCoding;
+	return TUSBH_E_OK;
+}
+
+
+/*
+ *  CDC DATA RECEIVE
+ *  parameter1 phost:   ホストハンドラ
+ *  parameter2 unit:    UNIT#
+ *  parameter3 pbuf:    受信データ領域へのポインタ
+ *  parameter4 length:  受信ブロック長
+ *  return     TUSBH_ERCODE
+ */
+TUSBH_ERCODE
+tusbhCdcReceive(TUSBH_Handle_t *phost, uint8_t unit, uint8_t *pbuf, uint32_t *length, uint32_t timeout)
+{
+	TUSBH_Device_t *pdevice = tusbhSearchDevice(phost, SERAIL_Class.classCode, &unit);
+	CDC_Handle_t *hcdc;
+	TUSBH_ERCODE status = TUSBH_E_BUSY;
+	uint32_t i;
+
+	if(pdevice != NULL){
+		hcdc = pdevice->pData;
+		if(pdevice->dstate != DEVICE_CLASS)
+			return TUSBH_E_OBJ;
+		if(hcdc->state == CDC_PROCESS_ERROR)
+			return TUSBH_E_ERR;
+	}
+	else
+		return TUSBH_E_OBJ;
+
+    /*
+	 *  受信データ設定
+	 */
+	hcdc->RxTrnSize   = *length;
+	hcdc->RxTrnLength = 0;
+	hcdc->pRxTrnBuff  = pbuf;
+	hcdc->rw_status = TUSBH_E_BUSY;
+	hcdc->rw_taskid = tusbGetTaskID();
+	tusbSendData(phost->process_event, TUSBH_CLASS_EVENT, pdevice->idx, CDC_PROCESS_RECEIVE, 0);
+
+	if(timeout != 0)
+		timeout += 9;
+	timeout /= 10;
+	for(i = 0 ; i < timeout ; i++){
+		tusbSleep(10);
+		if((status = hcdc->rw_status) != TUSBH_E_BUSY)
+			break;
+	}
+	if(status == TUSBH_E_BUSY){
+		hcdc->rw_status = TUSBH_E_TMOUT;
+		status = TUSBH_E_TMOUT;
+	}
+	*length = hcdc->RxTrnLength;
+	hcdc->rw_taskid = 0;
+	return status;
+}
+
+/*
+ *  CDC DATA SEND
+ *  parameter1 phost:   ホストハンドラ
+ *  parameter2 unit:    UNIT#
+ *  parameter3 pbuf:    送信データ領域へのポインタ
+ *  parameter4 length:  送信データ長
+ *  return     TUSBH_ERCODE
+ */
+TUSBH_ERCODE
+tusbhCdcSend(TUSBH_Handle_t *phost, uint8_t unit, uint8_t *pbuf, uint32_t length)
+{
+	TUSBH_Device_t *pdevice = tusbhSearchDevice(phost, SERAIL_Class.classCode, &unit);
+	CDC_Handle_t *hcdc;
+	TUSBH_ERCODE status = TUSBH_E_BUSY;
+	uint32_t i;
+
+	if(pdevice != NULL){
+		hcdc = pdevice->pData;
+		if(pdevice->dstate != DEVICE_CLASS)
+			return TUSBH_E_OBJ;
+		if(hcdc->state == CDC_PROCESS_ERROR)
+			return TUSBH_E_ERR;
+	}
+	else
+		return TUSBH_E_OBJ;
+
+    /*
+	 *  送信データ設定
+	 */
+	hcdc->TxTrnSize   = length;
+	hcdc->TxTrnLength = 0;
+	hcdc->pTxTrnBuff  = pbuf;
+	hcdc->rw_status = TUSBH_E_BUSY;
+	hcdc->rw_taskid = tusbGetTaskID();
+	tusbSendData(phost->process_event, TUSBH_CLASS_EVENT, pdevice->idx, CDC_PROCESS_SEND, 0);
+
+	for(i = 0 ; i < (length * 10) ; i++){
+		tusbSleep(50);
+		if((status = hcdc->rw_status) != TUSBH_E_BUSY)
+			break;
+	}
+	if(status == TUSBH_E_BUSY){
+		hcdc->rw_status = TUSBH_E_TMOUT;
+		status = TUSBH_E_TMOUT;
+	}
+	hcdc->rw_taskid = 0;
+	return status;
+}
+
+/*
+ *  SERIALコールバック関数
+ *  parameter1 phost:   ホストハンドラ
+ *  parameter2 func:    関数ポインタ
+ */
+void
+tusbhSetCdcCallBack(TUSBH_Handle_t *phost, void (*func)(TUSBH_Device_t *p, uint8_t))
+{
+	SERAIL_Class.subfunc = func;
+}
+
+
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/usb/host/SERIAL/tusbh_serial.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/usb/host/SERIAL/tusbh_serial.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/usb/host/SERIAL/tusbh_serial.h	(revision 457)
@@ -0,0 +1,165 @@
+/*
+ *  TOPPERS BASE PLATFORM MIDDLEWARE
+ * 
+ *  Copyright (C) 2017-2018 by TOPPERS PROJECT
+ *                             Educational Working Group.
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+/*
+ *  USB Host Middleware CDC:SERIAL部定義
+ */
+
+#ifndef _HUSBH_SERIAL_H_
+#define _HUSBH_SERIAL_H_
+
+#include "tusbh_base.h"
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+
+/*
+ *  COMMUNCATION SUB CLASS CODE定義
+ */
+#define COMMUNICATIONS_INTERFACE_CLASS  0x00
+#define DIRECT_LINE_CONTROL_MODEL       0x01
+#define ABSTRACT_CONTROL_MODEL          0x02
+#define TELEPHONE_CONTROL_MODEL         0x03
+#define MULTICHANNEL_CONTROL_MODEL      0x04
+#define CAPI_CONTROL_MODEL              0x05
+#define ETHERNET_NETWORKING_CONTROL_MODEL 0x06
+#define ATM_NETWORKING_CONTROL_MODEL    0x07
+#define WIRELESS_HANDSET_CONTROL_MODEL  0x08
+#define MOBILE_DIRECT_LINE_MODEL        0x0A
+#define ETHERNET_EMULATION_MODEL        0x0C
+#define NETWORK_CONTROL_MODEL           0x0D
+
+
+/*
+ *  COMMUNICATION INTERFCAE CLASS 制御プロトコルコード定義
+ */
+#define CDC_NO_SPECIFIC_PROTOCOL_CODE   0x00
+#define CDC_ITU_T_V_250                 0x01
+#define CDC_VENDOR_SPECIFIC             0xFF
+
+/*
+ *  DATA INTERFCAE CLASS 制御プロトコルコード定義
+ */
+#define DIC_NO_SPECIFIC_PROTOCOL_CODE   0x00
+#define DIC_USBNCM_1_0                  0x01
+
+
+#define CDC_SET_LINE_CODING             0x20
+#define CDC_GET_LINE_CODING             0x21
+#define CDC_SET_CONTROL_LINE_STATE      0x22
+#define CDC_SEND_BREAK                  0x23
+
+#define CDC_REQUEST_GETLINE_TYPE        (USB_DEVICE_TO_HOST | USB_REQUEST_TYPE_CLASS | USB_RECIPIENT_INTERFACE)
+#define CDC_REQUEST_SETLINE_TYPE        (USB_HOST_TO_DEVICE | USB_REQUEST_TYPE_CLASS | USB_RECIPIENT_INTERFACE)
+
+#define LINE_CODING_STRUCTURE_SIZE      0x07
+
+/*
+ *  CDCコールバックコード定義
+ */
+#define CDC_LINE_STATUS_CHANGED         1
+#define CDC_LINE_STATUS_SENDED          2
+#define CDC_LINE_STATUS_RECEIVED        3
+
+/*
+ *  CDCプロセスの状態定義
+ */
+enum
+{
+	CDC_PROCESS_INIT = 0,
+	CDC_PROCESS_INIT_WAIT,
+	CDC_PROCESS_IDLE,
+	CDC_PROCESS_SET_LINE_CODING,
+	CDC_PROCESS_SET_LINE_CODING_WAIT,
+	CDC_PROCESS_GET_LINE_CODING,
+	CDC_PROCESS_SEND,
+	CDC_PROCESS_RECEIVE,
+	CDC_PROCESS_ERROR,
+	CDC_PROCESS_ERROR_WAIT
+};
+
+/*
+ *  CDCハンドラ定義
+ */
+typedef struct
+{
+	TUSBH_Device_t            *pDev;
+	uint8_t                   state;
+	uint8_t                   dummy;
+	uint16_t                  RxTrnPktSize;
+	uint16_t                  TxTrnPktSize;
+
+	uint8_t                   CommInPipe;
+	uint8_t                   CommInEp;
+	uint16_t                  CommInEpSize;
+	uint8_t                   InPipe;
+	uint8_t                   OutPipe;
+	uint8_t                   OutEp;
+	uint8_t                   InEp;
+	uint16_t                  OutEpSize;
+	uint16_t                  InEpSize;
+	uint32_t                  RxTrnLength;
+	uint32_t                  RxTrnSize;
+	uint8_t                   *pRxTrnBuff;
+	uint32_t                  TxTrnLength;
+	uint32_t                  TxTrnSize;
+	uint8_t                   *pTxTrnBuff;
+	uint32_t                  timer;
+	uint32_t                  urb_wait;
+	ID                        rw_taskid;
+	uint32_t                  rw_status;
+	Line_Coding_t             oLineCoding;
+	Line_Coding_t             uLineCoding;
+} CDC_Handle_t;
+
+
+void         tusbhLinkSERIAL(TUSBH_Handle_t *phost);
+TUSBH_ERCODE tusbhCdcSetLineCoding(TUSBH_Handle_t *phost, uint8_t unit, Line_Coding_t *linecod);
+TUSBH_ERCODE tusbhCdcGetLineCoding(TUSBH_Handle_t *phost, uint8_t unit, Line_Coding_t *linecod);
+TUSBH_ERCODE tusbhCdcSend(TUSBH_Handle_t *phost, uint8_t unit, uint8_t *pbuf, uint32_t length);
+TUSBH_ERCODE tusbhCdcReceive(TUSBH_Handle_t *phost, uint8_t unit, uint8_t *pbuf, uint32_t *length, uint32_t timeout);
+void tusbhSetCdcCallBack(TUSBH_Handle_t *phost, void (*func)(TUSBH_Device_t *p, uint8_t));
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _HUSBH_SERIAL_H_ */
+
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/usb/host/tusbh.cfg
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/usb/host/tusbh.cfg	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/usb/host/tusbh.cfg	(revision 457)
@@ -0,0 +1,16 @@
+/*
+ *  @(#) $Id$
+ */
+
+/*
+ *  TUSBHミドルウェアのコンフィギュレーションファイル
+ */
+
+#include "tusbh_base.h"
+
+CRE_TSK(TUSBH_P_TASK, { TA_NULL, 0, tusbhProcessTask, TUSB_PROCESS_PRIO, TUSB_PROCESS_STACK_SIZE, NULL });
+CRE_TSK(TUSBH_E_TASK, { TA_NULL, 0, tusbhEventTask, TUSB_PROCESS_PRIO-1, TUSB_HANDLE_STACK_SIZE, NULL });
+CRE_DTQ(USBH_EVT1_DTQ,{ TA_NULL, NUM_USBH_EVT1, NULL});
+CRE_DTQ(USBH_EVT2_DTQ,{ TA_NULL, NUM_USBH_EVT2, NULL});
+CRE_CYC(TUSBH_CYC_HDR, { TA_NULL, 0, tusbhCyclicHandler, 1, 0 });
+
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/usb/host/tusbh_base.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/usb/host/tusbh_base.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/usb/host/tusbh_base.c	(revision 457)
@@ -0,0 +1,1104 @@
+/*
+ *  TOPPERS BASE PLATFORM MIDDLEWARE
+ * 
+ *  Copyright (C) 2017-2019 by TOPPERS PROJECT
+ *                             Educational Working Group.
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+/*
+ *  USB Host Middleware BASE部
+ */
+
+#include "tusbh_base.h"
+
+
+#define USBH_ADDRESS_DEFAULT            0
+#define USBH_MPS_DEFAULT                0x40
+#define USBH_DEVICE_ADDRESS(d)          ((d)->idx + 1)
+
+#define USBH_SET_CONFIGURATION(d, i)    tusbhControlRequest((d), 0, SET_CONFIGURATION_TYPE, SET_CONFIGURATION, (i), 0, 0)
+#define USBH_SET_ADDRESS(d, a)          tusbhControlRequest((d), 0, SET_ADDRESS_TYPE, SET_ADDRESS, (a), 0, 0)
+
+#ifndef CONNECT_WAIT_TIME
+#define CONNECT_WAIT_TIME               200
+#endif
+
+static TUSBH_Handle_t *usbh_arg;
+
+/*
+ *  デバイスハンドラ初期化
+ */
+static void
+tusbhInitDevice(TUSBH_Device_t *pdevice)
+{
+	memset(pdevice->Data, 0, TUSBH_MAX_DATA_BUFFER);
+
+	pdevice->cntl_pipe_size = USBH_MPS_DEFAULT;
+	pdevice->cntl_errcount  = 0;
+	pdevice->pClass  = NULL;
+	pdevice->address = USBH_ADDRESS_DEFAULT;
+	pdevice->speed   = USB_DEVICE_SPEED_FULL;
+	pdevice->dstate  = DEVICE_IDLE;
+}
+
+/*
+ *  アロケート・デバイスハンドラ
+ */
+static TUSBH_Device_t *
+tusbhAllocDevice(TUSBH_Handle_t *phost)
+{
+	TUSBH_Device_t *pdevice;
+	int i;
+
+	if(phost->numDevice >= MAX_DEVICE_CONNECTED)
+		return NULL;
+	if((pdevice = tusbmalloc(sizeof(TUSBH_Device_t))) == NULL)
+		return NULL;
+	memset(pdevice, 0, sizeof(TUSBH_Device_t));
+	if(phost->numDevice == 0)
+		phost->pDevice = pdevice;
+	else{
+		TUSBH_Device_t *pnext = phost->pDevice;
+		for(i = 1 ; i < phost->numDevice ; i++)
+			pnext = pnext->pNext;
+		pnext->pNext = pdevice;
+	}
+	pdevice->hub   = 0xff;
+	pdevice->port  = 0xff;
+	pdevice->pHost = phost;
+	pdevice->idx  = phost->numDevice++;
+	tusbhInitDevice(pdevice);
+	return pdevice;
+}
+
+/*
+ *  デバイスハンドラ検索
+ */
+static TUSBH_Device_t*
+tusbhFindDevice(TUSBH_Handle_t *phost, uint8_t idx)
+{
+	TUSBH_Device_t *pdevice = phost->pDevice;
+	uint8_t i;
+
+	for(i = 0 ; i < idx ; i++)
+		pdevice = pdevice->pNext;
+	return pdevice;
+}
+
+/*
+ *  有効デバイス数
+ */
+static uint8_t
+tusbActivateDevice(TUSBH_Handle_t *phost)
+{
+	TUSBH_Device_t *pdevice = phost->pDevice;
+	uint8_t i, actdevice = 0;
+
+	for(i = 0 ; i < phost->numDevice && pdevice != NULL ; i++){
+		if(pdevice->pClass != NULL)
+			actdevice++;
+		pdevice = pdevice->pNext;
+	}
+	return actdevice;
+}
+
+/*
+ *  SEARCH DEVICE
+ *  parameter1 phost:     ホストハンドラ
+ *  parameter2 classCide: クラスコード
+ *  parameter3 plun:      unit#
+ *  return     デバイスハンドラ
+ */
+TUSBH_Device_t *
+tusbhSearchDevice(TUSBH_Handle_t *phost, uint8_t classCode, uint8_t *plun)
+{
+	TUSBH_Device_t *pdevice = phost->pDevice;
+	uint8_t i;
+
+	for(i = 0 ; i < phost->numDevice && pdevice != NULL ; i++){
+		if(pdevice->type == classCode){
+			if(*plun < pdevice->numUnit)
+				break;
+			else
+				*plun -= pdevice->numUnit;
+		}
+		pdevice = pdevice->pNext;
+	}
+	return pdevice;
+}
+
+
+/*
+ *  HC-PIPEのアロケート
+ *  parameter1 pdevice: デバイスハンドラ
+ *  parameter2 ep_addr: エンドポイントアドレス
+ *  return     PIPE番号(0xFFでエラー)
+ */
+uint8_t
+tusbhAllocPipe(TUSBH_Handle_t *phost, uint8_t ep_addr)
+{
+	uint8_t idx = 0;
+
+	for(idx = 0 ; idx < phost->numPipes ; idx++){
+		if((phost->pipes[idx].attribute & PIPE_ACTIVATE) == 0 && tusbhHDCheckPipe(phost, idx)){
+			phost->pipes[idx].attribute = PIPE_ACTIVATE | ep_addr;
+			return idx;
+		}
+	}
+	syslog_2(LOG_ERROR, "tusbhAllocPipe no free pipe [%08x] ep(%d) !", phost, ep_addr);
+	return 0xFF;
+}
+
+/*
+ *  HC-PIPEの解放
+ *  parameter1 pdevice: デバイスハンドラ
+ *  parameter2 no:      PIPE番号
+ *  return     TUSBH_ERCODE
+ */
+TUSBH_ERCODE
+tusbFreePipe(TUSBH_Handle_t *phost, uint8_t no)
+{
+	if(no < phost->numPipes){
+		phost->pipes[no].attribute &= ~PIPE_ACTIVATE;
+	}
+	return TUSBH_E_OK;
+}
+
+
+/*
+ *  USBホスト初期化処理
+ *  parameter1 phost:   ホストハンドラ
+ *  parameter2 pufunc:ユーザポインタ関数
+ *  parameter3 id:      USBホストID
+ *  return     TUSBH_ERCODE
+ */
+TUSBH_ERCODE
+tusbhInit(TUSBH_Handle_t *phost, void (*pufunc)(TUSBH_Handle_t *phost, TUSBH_Device_t *pdevice, uint8_t ), uint8_t id)
+{
+	uint8_t i;
+
+	/*
+	 *  USBホスト構造体の確認
+	 */
+	if(phost == NULL){
+		syslog_0(LOG_ERROR, "Invalid Host handle !");
+		return TUSBH_E_PAR; 
+	}
+
+	/*
+	 *  ホストIDをセット
+	 */
+	phost->id = id;
+
+	/*
+	 *  リンクカウントを初期化
+	 */
+	phost->numClass = 0;
+	phost->numDevice = 0;
+	phost->numHub    = 0;
+
+	/*
+	 *  PIPEの初期化
+	 */
+	for(i = 0 ; i < MAX_EPS_PIPES; i++){
+		phost->pipes[i].attribute = 0;
+		phost->pipes[i].index     = 0;
+	}
+
+	/*
+	 *  ユーザー関数の保存
+	 */
+	if(pufunc != NULL)
+		phost->usrcallback = pufunc;
+
+	/*
+	 * タスク用にUSBホストハンドラを保存
+	 */
+	usbh_arg = phost;
+
+	/*
+	 *  LOWレベルドライバの初期化
+	 */
+	tusbhHDInit(phost);
+
+	/*
+	 *  タスクの起動
+	 */
+	tusbStartTask(phost->eventTaskID);
+	tusbStartTask(phost->processTaskID);
+	return TUSBH_E_OK;
+}
+
+/*
+ *  USBホスト終了処理
+ *  parameter1 phost:   ホストハンドラ
+ *  return     TUSBH_ERCODE
+ */
+TUSBH_ERCODE
+tusbhDeInit(TUSBH_Handle_t *phost)
+{
+	TUSBH_Device_t *pdevice;
+	uint8_t idx;
+
+	for(idx = 0, pdevice = phost->pDevice ; idx < phost->numDevice ; idx++){
+		tusbfree(pdevice);
+		pdevice = pdevice->pNext;
+	}
+	phost->pDevice = 0;
+
+	if(phost->pSysData != NULL){
+		tusbhHDStop(phost);
+	}
+	return TUSBH_E_OK;
+}
+
+/*
+ *  クラス実行モジュールのリンク
+ *  parameter1 phost:   ホストハンドラ
+ *  parameter2 pclass:  クラス構造体へのポインタ
+ *  return     TUSBH_ERCODE
+ */
+TUSBH_ERCODE
+tusbhLinkClass(TUSBH_Handle_t *phost, TUSBH_Class_t *pclass)
+{
+	if(pclass == NULL)
+		return TUSBH_E_ERR;
+	pclass->pNext = NULL;
+	if(phost->numClass == 0)
+		phost->pClass = pclass;
+	else{
+		TUSBH_Class_t *pnext = phost->pClass;
+		uint32_t i;
+		for(i = 1 ; i < phost->numClass ; i++)
+			pnext = pnext->pNext;
+		pnext->pNext = pclass;
+	}
+	phost->numClass++;
+	return TUSBH_E_OK;
+}
+
+/*
+ *  USBホスト開始
+ *  parameter1 phost:   ホストハンドラ
+ *  return     TUSBH_ERCODE
+ */
+TUSBH_ERCODE
+tusbhStart(TUSBH_Handle_t *phost)
+{
+	/*
+	 *  LOWレベルドライバをスタート
+	 */
+	tusbhHDStart(phost);
+
+	/*
+	 *  VBUSを有効化
+	 */
+	tusbhHDControlVBUS(phost, true);
+	return TUSBH_E_OK;
+}
+
+/*
+ *  USBホスト停止
+ *  parameter1 phost:   ホストハンドラ
+ *  return     TUSBH_ERCODE
+ */
+TUSBH_ERCODE
+tusbhStop(TUSBH_Handle_t *phost)
+{
+	TUSBH_Device_t *pdevice = phost->pDevice;
+	uint8_t i = 0;
+
+	/*
+	 *  LOWレベルドライバ停止
+	 */
+	tusbhHDStop(phost);
+
+	/*
+	 *  VBUSの停止
+	 */ 
+	tusbhHDControlVBUS(phost, false);
+
+	/*
+	 *  PIPEの解放
+	 */
+	for(i = 0 ; i < phost->numDevice && pdevice != NULL ; i++){
+		tusbFreePipe(phost, pdevice->cntl_pipe_in);
+		tusbFreePipe(phost, pdevice->cntl_pipe_out);
+		pdevice = pdevice->pNext;
+	}
+	return TUSBH_E_OK;
+}
+
+/*
+ *  HUBのリセット要求
+ *  parameter1 pdevice: デバイスハンドラ
+ *  return     TUSBH_ERCODE
+ */
+TUSBH_ERCODE
+tusbhResetHub(TUSBH_Device_t *pdevice)
+{
+	TUSBH_Handle_t *phost = pdevice->pHost;
+	TUSBH_Device_t *pdeviceh;
+	uint32_t idx;
+
+	syslog_2(LOG_ERROR, "tusbhResetHub hub(%d) port(%d) !", pdevice->hub, pdevice->port);
+	for(idx = 0, pdeviceh = phost->pDevice ; idx < phost->numDevice ; idx++){
+		if(pdevice->hub == pdeviceh->hubid){
+			tusbSendData(phost->process_event, TUSBH_RESET_EVENT, pdeviceh->idx, 0, pdevice->port);
+			break;
+		}
+		pdeviceh = pdeviceh->pNext;
+	}
+	return TUSBH_E_OK;
+}
+
+/*
+ *  デバイスにインターフェイスを設定
+ *  parameter1 pdevice: デバイスハンドラ
+ *  parameter2 interface: インターフェイス値
+ *  return     TUSBH_ERCODE
+ */
+TUSBH_ERCODE
+tusbhSelectInterface(TUSBH_Device_t *pdevice, uint8_t interface)
+{
+	TUSBH_ERCODE ercd = TUSBH_E_OK;
+
+	if(interface < pdevice->CfgDesc.bNumInterfaces){
+		pdevice->sel_interface = interface;
+		syslog_2(LOG_NOTICE, "Switching to Interface device(%d) (#%d)", pdevice->idx, interface);
+		syslog_1(LOG_NOTICE, "Class    : 0x%02x", pdevice->ItfDesc[interface].bInterfaceClass );
+		syslog_1(LOG_NOTICE, "SubClass : 0x%02x", pdevice->ItfDesc[interface].bInterfaceSubClass );
+		syslog_1(LOG_NOTICE, "Protocol : 0x%02x", pdevice->ItfDesc[interface].bInterfaceProtocol );
+	}
+	else{
+		syslog_1(LOG_ERROR, "Cannot Select This Interface (%d) !", pdevice->idx);
+		ercd = TUSBH_E_ERR; 
+	}
+	return ercd;
+}
+
+/*
+ *  クラス番号を取得
+ *  parameter1 pdevice: デバイスハンドラ
+ *  return     Class code
+ */
+uint8_t
+tusbhGetActiveClass(TUSBH_Device_t *pdevice)
+{
+	return (pdevice->ItfDesc[0].bInterfaceClass);
+}
+
+/*
+ *  クラス情報からインターフェイスのインデックスを返す
+ *  parameter1 pdevice: デバイスハンドラ
+ *  parameter2 Class:   Class code
+ *  parameter3 SubClass:Sub Class code
+ *  parameter4 Protocal:Protocol code
+ *  return     interface index(ない場合はNO_INTERFACE)
+ */
+uint8_t
+tusbhFindInterface(TUSBH_Device_t *pdevice, uint8_t Class, uint8_t SubClass, uint8_t Protocol)
+{
+	InterfaceDescriptor    *pif = NULL;
+	int8_t                 if_ix = 0;
+
+	while(if_ix < TUSBH_MAX_NUM_INTERFACES){
+		pif = &pdevice->ItfDesc[if_ix];
+		if((pif->bInterfaceClass == Class || Class == 0xFF) &&
+			(pif->bInterfaceSubClass == SubClass || SubClass == 0xFF) &&
+				(pif->bInterfaceProtocol == Protocol || Protocol == 0xFF)){
+			return  if_ix;
+		}
+		if_ix++;
+	}
+	return NO_INTERFACE;
+}
+
+/*
+ *  インターフェイス情報からインターフェイスのインデックスを返す
+ *  parameter1 pdevice: デバイスハンドラ
+ *  parameter2 interface: interface number
+ *  parameter3 altsetnum: alternate setting #
+ *  return     interface index(ない場合は0xff)
+ */
+uint8_t
+tusbhFindInterfacebynumber(TUSBH_Device_t *pdevice, uint8_t interface, uint8_t altsetno)
+{
+	InterfaceDescriptor    *pif = NULL;
+	int8_t                 if_ix = 0;
+
+	while (if_ix < TUSBH_MAX_NUM_INTERFACES){
+		pif = &pdevice->ItfDesc[if_ix];
+		if((pif->bInterfaceNumber == interface) && (pif->bAlternateSetting == altsetno)){
+			return  if_ix;
+		}
+		if_ix++;
+	}
+	return 0xFF;
+}
+
+/*
+ *  OPEN PIPE
+ *  parameter1 pdevice: デバイスハンドラ
+ *  parameter2 pipe:    PIPE#
+ *  parameter3 epnum:   EP番号
+ *  parameter5 type:    エンドポイントタイプ
+ *  parameter6 eps:     MAXパケットサイズ
+ *  return     TUSBH_ERCODE
+ */
+TUSBH_ERCODE
+tusbhOpenPipe(TUSBH_Device_t *pdevice, uint8_t pipe, uint8_t epnum, uint8_t type, uint16_t mps)
+{
+	TUSBH_Handle_t *phost = pdevice->pHost;
+
+	phost->pipes[pipe].type = type;
+	return tusbhHDOpenPipe(phost, pipe, epnum, pdevice->address, pdevice->speed, type, mps);
+}
+
+/*
+ *  CLOSE PIPE
+ *  parameter1 pdevice: デバイスハンドラ
+ *  parameter2 pipe:    PIPE#
+ *  return     TUSBH_ERCODE
+ */
+TUSBH_ERCODE
+tusbhClosePipe(TUSBH_Device_t *pdevice, uint8_t pipe)
+{
+	return tusbhHDClosePipe(pdevice->pHost, pipe);
+}
+
+/*
+ *  SUBMIT URB
+ *  parameter1 pdevice: デバイスハンドラ
+ *  parameter2 pipe:    パイプ番号
+ *  parameter3 type:    SUBMITタイプ
+ *  parameter4 eptype:  エンドポイントタイプ
+ *  parameter5 buff:    データ領域へのポインタ
+ *  parameter6 length:  データ長
+ *  return     TUSBH_ERCODE
+ */
+TUSBH_ERCODE
+tusbhSubmitURB(TUSBH_Device_t *pdevice, uint8_t pipe, uint16_t type, uint8_t eptype, uint8_t* buff, uint16_t length)
+{
+	TUSBH_Handle_t *phost = pdevice->pHost;
+	uint8_t dir, token;
+	uint8_t do_ping = 0;
+
+	phost->pipes[pipe].index = pdevice->idx;
+	if(eptype != phost->pipes[pipe].type){
+		syslog_3(LOG_ERROR, "tusbhSubmitURB EPTYPE ERROR pipe(%d) rtype(%d) ctype(%d) !", pipe, eptype, phost->pipes[pipe].type);
+		return TUSBH_E_ERR;
+	}
+	if(eptype == USB_EP_TYPE_BULK || eptype == USB_EP_TYPE_CTRL){
+		if(pdevice->speed == USB_DEVICE_SPEED_HIGH && type == SUBMIT_WRITE)
+			do_ping = 1;
+	}
+	dir   = type >> 8;
+	token = type & 0xff;
+	return tsubhHDSubmitURB(phost, pipe, dir, token, buff, length, do_ping);
+}
+
+/*
+ *  Device Descriporコマンドをデバイスに送信し取得する
+ *  parameter1 pdevice: デバイスハンドラ
+ *  parameter2 length:  Descripor長
+ *  return     TUSBH_ERCODE
+ */
+static TUSBH_ERCODE
+tusbhGetDeviceDescriptor(TUSBH_Device_t *pdevice, uint8_t length)
+{
+	TUSBH_ERCODE  ercd;
+	volatile uint8_t    *buff = pdevice->Data;
+	DeviceDescriptor *dev_desc = &pdevice->DevDesc;
+
+	if((ercd = tusbhGetDescriptor(pdevice,
+                                  USB_RECIPIENT_DEVICE | USB_REQUEST_TYPE_STANDARD,                          
+                                  ((DEVICE_DESCRIPTOR << 8) & 0xFF00),
+                                  (uint8_t *)buff,
+                                  length)) == TUSBH_E_OK){
+		/*
+		 *  DEVICE DESCRIPTER取得
+		 */
+		dev_desc->bLength            = buff[0];
+		dev_desc->bDescriptorType    = buff[1];
+		dev_desc->bcdUSB             = (buff[2] & 0xff) | (buff[3] << 8);
+		dev_desc->bDeviceClass       = buff[4];
+		dev_desc->bDeviceSubClass    = buff[5];
+		dev_desc->bDeviceProtocol    = buff[6];
+		dev_desc->bMaxPacketSize     = buff[7];
+
+		if(length > 8){ /* For 1st time after device connection, Host may issue only 8 bytes for   Device Descriptor Length  */
+			dev_desc->idVendor           = (buff[8]  & 0xff) | (buff[9]  << 8);
+			dev_desc->idProduct          = (buff[10] & 0xff) | (buff[11] << 8);
+			dev_desc->bcdDevice          = (buff[12] & 0xff) | (buff[12] << 8);
+			dev_desc->iManufacturer      = buff[14];
+			dev_desc->iProduct           = buff[15];
+			dev_desc->iSerialNumber      = buff[16];
+			dev_desc->bNumConfigurations = buff[17];
+		}
+	}
+	return ercd;
+}
+
+/*
+ *  Config Descriporコマンドをデバイスに送信し取得する
+ *  parameter1 pdevice: デバイスハンドラ
+ *  parameter2 length:  Descripor長
+ *  return     TUSBH_ERCODE
+ */
+static TUSBH_ERCODE
+tusbhGetConfigDescriptor(TUSBH_Device_t *pdevice, uint16_t length)
+{
+	ConfigurationDescriptor *cfg_desc = &pdevice->CfgDesc;
+	TUSBH_Handle_t     *phost = pdevice->pHost;
+	volatile uint8_t   *pdbuff;
+	TUSBH_ERCODE ercd;
+
+	if(phost->pCfgData != NULL)
+		pdbuff = (volatile uint8_t *)phost->pCfgData;
+	else
+		pdbuff = (volatile uint8_t *)pdevice->Data;
+	if((ercd = tusbhGetDescriptor(pdevice,
+                                  USB_RECIPIENT_DEVICE | USB_REQUEST_TYPE_STANDARD,
+                                  ((CONFIGURATION_DESCRIPTOR << 8) & 0xFF00),
+                                  (uint8_t *)pdbuff,
+                                  length)) == TUSBH_E_OK){
+
+		/*
+		 *  CONFIGURATION DESCRIPTOR設定
+		 */
+		cfg_desc->bLength             = pdbuff[0];
+		cfg_desc->bDescriptorType     = pdbuff[1];
+		cfg_desc->wTotalLength        = (pdbuff[2] & 0xff) | (pdbuff[3] << 8);
+		cfg_desc->bNumInterfaces      = pdbuff[4];
+		cfg_desc->bConfigurationValue = pdbuff[5];
+		cfg_desc->iConfiguration      = pdbuff[6];
+		cfg_desc->bmAttributes        = pdbuff[7];
+		cfg_desc->bMaxPower           = pdbuff[8];
+
+		if (length > CONFIGURATION_DESCRIPTOR_LENGTH){
+			uint16_t ptr = CONFIGURATION_DESCRIPTOR_LENGTH;
+			int8_t   if_ix = 0;
+			int8_t   ep_ix = 0;
+
+			while(if_ix < TUSBH_MAX_NUM_INTERFACES && ptr < cfg_desc->wTotalLength){
+				ptr += pdbuff[0];
+				pdbuff = (volatile uint8_t *)(pdbuff + pdbuff[0]);
+				if(pdbuff[1] == INTERFACE_DESCRIPTOR){
+					InterfaceDescriptor *pif = &pdevice->ItfDesc[if_ix];
+					/*
+					 *  INTERFACE DESCRIPTOR設定
+					 */
+  					pif->bLength            = pdbuff[0];
+					pif->bDescriptorType    = pdbuff[1];
+					pif->bInterfaceNumber   = pdbuff[2];
+					pif->bAlternateSetting  = pdbuff[3];
+					pif->bNumEndpoints      = pdbuff[4];
+					pif->bInterfaceClass    = pdbuff[5];
+					pif->bInterfaceSubClass = pdbuff[6];
+					pif->bInterfaceProtocol = pdbuff[7];
+					pif->iInterface         = pdbuff[8];
+
+					ep_ix = 0;
+					while ((ep_ix < pif->bNumEndpoints) && (ptr < cfg_desc->wTotalLength)){
+						ptr += pdbuff[0];
+						pdbuff = (volatile uint8_t *)(pdbuff + pdbuff[0]);
+						if(pdbuff[1] == ENDPOINT_DESCRIPTOR){
+							EndpointDescriptor *pep = &pdevice->EpDesc[if_ix][ep_ix];
+							/*
+							 *  ENDPOINT DESCRIPTOR設定
+							 */
+							pep->bLength          = pdbuff[0];
+							pep->bDescriptorType  = pdbuff[1];
+							pep->bEndpointAddress = pdbuff[2];
+							pep->bmAttributes     = pdbuff[3];
+							pep->wMaxPacketSize   = (pdbuff[4] & 0xff) | (pdbuff[5] << 8);
+							pep->bInterval        = pdbuff[6];
+							ep_ix++;
+						}
+					}
+					if_ix++;
+				}
+			}
+		}
+	}
+	return ercd;
+}
+
+/*
+ *  String Descriporコマンドをデバイスに送信
+ *  parameter1 pdevice: デバイスハンドラ
+ *  parameter2 string_index:  String index
+ *  parameter3 buff:          取り出し用のバッファ領域
+ *  parameter4 length:        Descripor長
+ *  return     TUSBH_ERCODE
+ */
+static TUSBH_ERCODE
+tusbhGetStringDescriptor(TUSBH_Device_t *pdevice,
+                                uint8_t string_index, 
+                                uint8_t *buff, 
+                                uint16_t length)
+{
+	uint8_t *psrc = pdevice->Data;
+	TUSBH_ERCODE ercd;
+
+	if((ercd = tusbhGetDescriptor(pdevice,
+                                  USB_RECIPIENT_DEVICE | USB_REQUEST_TYPE_STANDARD,
+                                  ((STRING_DESCRIPTOR << 8) & 0xFF00) | string_index, 
+                                  psrc,
+                                  length)) == TUSBH_E_OK){
+  		/*
+		 * UINCODEをアスキー文字列に変換
+		 */
+		if(psrc[1] == STRING_DESCRIPTOR){ /* String Typeならバッファにセット */
+			int strlength = psrc[0]-2;
+			uint32_t i;
+			for(i = 0 ; i < length && i < strlength ; i += 2){
+				*buff++ =  psrc[i+2];
+			}
+			*buff = 0;
+		}
+	}
+	return ercd;
+}
+
+/*
+ *  USBのエナミュレートを実行する
+ *  parameter1 pdevice: デバイスハンドラ
+ *  return     TUSBH_ERCODE
+ */
+static TUSBH_ERCODE
+tusbhEnumerate(TUSBH_Device_t *pdevice)
+{
+	TUSBH_ERCODE ercd = TUSBH_E_OK;
+
+	/*
+	 *  8バイトで Device Descriptorを取得
+	 */
+	if((ercd = tusbhGetDeviceDescriptor(pdevice, 8)) != TUSBH_E_OK)
+		return ercd;
+
+	/*
+	 *  bMaxPacketSizeでパイプを再オープン
+	 */
+	pdevice->cntl_pipe_size = pdevice->DevDesc.bMaxPacketSize;
+	tusbhOpenPipe(pdevice, pdevice->cntl_pipe_in, 0x80, USB_EP_TYPE_CTRL,
+				pdevice->cntl_pipe_size);
+
+	tusbhOpenPipe(pdevice, pdevice->cntl_pipe_out, 0x00, USB_EP_TYPE_CTRL,
+				pdevice->cntl_pipe_size);
+
+	/*
+	 *  フルサイズで Device Descriptorを取得
+	 */
+	if((ercd != tusbhGetDeviceDescriptor(pdevice, DEVICE_DESCRIPTOR_LENGTH)) != TUSBH_E_OK)
+		return ercd;
+
+	syslog_1(LOG_NOTICE, "VID: 0x%04x", pdevice->DevDesc.idVendor );
+	syslog_1(LOG_NOTICE, "PID: 0x%04x", pdevice->DevDesc.idProduct);
+
+	/*
+	 *  デバイスにデバイスアドレスをセット
+	 */
+	if((ercd = USBH_SET_ADDRESS(pdevice, USBH_DEVICE_ADDRESS(pdevice))) != TUSBH_E_OK)
+		return ercd;
+
+	/*
+	 *  設定アドレスでパイプを再オープン
+	 */
+	tusbDelay(2);
+	pdevice->address = USBH_DEVICE_ADDRESS(pdevice);
+	syslog_1(LOG_NOTICE, "Address (#%d) assigned.", pdevice->address);
+
+	tusbhOpenPipe(pdevice, pdevice->cntl_pipe_in, 0x80, USB_EP_TYPE_CTRL,
+				pdevice->cntl_pipe_size);
+
+	tusbhOpenPipe(pdevice, pdevice->cntl_pipe_out, 0x00, USB_EP_TYPE_CTRL,
+				pdevice->cntl_pipe_size);
+
+	/*
+	 *  スタンダードサイズで Configuration descriptorを取得
+	 */
+	if((ercd = tusbhGetConfigDescriptor(pdevice, CONFIGURATION_DESCRIPTOR_LENGTH)) != TUSBH_E_OK)
+		return ercd;
+
+	/*
+	 *  フルサイズでConfiguraion Descriptorを取得
+	 */
+	if((ercd = tusbhGetConfigDescriptor(pdevice, pdevice->CfgDesc.wTotalLength)) != TUSBH_E_OK)
+		return ercd;
+
+	/*
+	 *  Manufacturer文字列を取得
+	 */
+	if(pdevice->DevDesc.iManufacturer != 0){ /* Check that Manufacturer String is available */
+		if(tusbhGetStringDescriptor(pdevice, pdevice->DevDesc.iManufacturer, 
+				pdevice->Data , 0xff) == TUSBH_E_OK){
+			strncpy(pdevice->Manufacturer, (const char *)pdevice->Data, TUSBH_STR_LENGTH);
+			/*
+			 *  Manufacturingを表示
+			 */
+			syslog_1(LOG_NOTICE, "Manufacturer : %s",  pdevice->Manufacturer);
+		}
+	}
+	else
+		syslog_0(LOG_NOTICE, "Manufacturer : N/A");
+
+	/*
+	 *  Product文字列を取得
+	 */
+	if(pdevice->DevDesc.iProduct != 0){ /* Check that Product string is available */
+		if(tusbhGetStringDescriptor(pdevice, pdevice->DevDesc.iProduct, 
+						pdevice->Data, 0xff) == TUSBH_E_OK){
+			strncpy(pdevice->Prodeuct, (const char *)pdevice->Data, TUSBH_STR_LENGTH);
+			/* User callback for Product string */
+			syslog_1(LOG_NOTICE, "Product : %s",  pdevice->Prodeuct);
+		}
+	}
+	else
+		syslog_0(LOG_NOTICE, "Product : N/A");
+
+	/*
+	 *  シリアル番号取得
+	 */
+	if(pdevice->DevDesc.iSerialNumber != 0){ /* Check that Serial number string is available */    
+		if((ercd = tusbhGetStringDescriptor(pdevice, pdevice->DevDesc.iSerialNumber, 
+						pdevice->Data, 0xff)) == TUSBH_E_OK){
+			strncpy(pdevice->Serial, (const char *)pdevice->Data, TUSBH_STR_LENGTH);
+			/* User callback for Serial number string */
+			syslog_1(LOG_NOTICE, "Serial Number : %s",  pdevice->Serial);
+		}
+	}
+	else{
+		syslog_0(LOG_NOTICE, "Serial Number : N/A"); 
+		ercd = TUSBH_E_OK;
+	}
+	return ercd;
+}
+
+/*
+ *  USBホストプロセスタスク
+ */
+void
+tusbhProcessTask(intptr_t exinf)
+{
+	TUSBH_Handle_t *phost = usbh_arg;
+	TUSBH_Device_t *pdevice;
+	TUSBH_Class_t  *pnext;
+	TUSBH_ERCODE ercd = TUSBH_E_OK;
+	ER           rercd;
+	uint8_t mes[4];
+	uint32_t no;
+
+	for(;;){
+		rercd = tusbRecvData(phost->process_event, mes, 0);
+		if(rercd == E_OK){
+			if((pdevice = tusbhFindDevice(phost, mes[1])) == NULL){
+				syslog_1(LOG_NOTICE, "USBH no device message(%d) !", mes[1]);
+				continue;
+			}
+			pdevice = tusbhFindDevice(phost, mes[1]);
+			switch (pdevice->dstate){
+			case DEVICE_ATTACHED:
+				syslog_2(LOG_NOTICE, "USBH Device Attached(%d) speed(%d) !", pdevice->idx, pdevice->speed);
+				if(phost->usrcallback != NULL)
+					phost->usrcallback(phost, pdevice, HOST_USER_CONNECTION);
+
+				/*
+				 *  100ms待ちコントロール通信用PIPEをアサイン
+				 */
+				tusbDelay(100); 
+
+				pdevice->cntl_pipe_out = tusbhAllocPipe(phost, 0x00);
+				pdevice->cntl_pipe_in  = tusbhAllocPipe(phost, 0x80);
+
+				/*
+				 *  IN/OUTのPIPEをオープン
+				 */
+				tusbhOpenPipe(pdevice, pdevice->cntl_pipe_in, 0x80, USB_EP_TYPE_CTRL,
+								pdevice->cntl_pipe_size);
+
+				tusbhOpenPipe(pdevice, pdevice->cntl_pipe_out, 0x00, USB_EP_TYPE_CTRL,
+								pdevice->cntl_pipe_size);
+				pdevice->numUnit = 1;
+				pdevice->pre_connected = 0;
+
+				/*
+				 *  エナミュレーション実行
+				 */
+				if((ercd = tusbhEnumerate(pdevice)) == TUSBH_E_OK){
+					syslog_1(LOG_NOTICE, "Enumeration done(%d) !", pdevice->idx);
+					pdevice->sel_interface = 0;
+					if(pdevice->DevDesc.bNumConfigurations != 1){
+						if(phost->usrcallback != NULL)
+							phost->usrcallback(phost, pdevice, HOST_USER_SELECT_CONFIGURATION);
+					}
+					else
+						syslog_1(LOG_NOTICE, "This device has only 1 configuration(%d) !", pdevice->idx);
+					if(USBH_SET_CONFIGURATION(pdevice, pdevice->CfgDesc.bConfigurationValue) == TUSBH_E_OK){
+						pdevice->dstate  = DEVICE_CHECK_CLASS;
+						syslog_1(LOG_NOTICE, "Default configuration set(%d) !", pdevice->idx);
+					}
+					else if(ercd == TUSBH_E_ERR){
+						pdevice->dstate = DEVICE_DISCONNECTED;
+						syslog_1(LOG_ERROR, "Enumeration set configuraion error(%) !", pdevice->idx);
+						tusbSendData(phost->process_event, TUSBH_PORT_EVENT, pdevice->idx, 0, 0);
+					}
+				}
+				else{
+					pdevice->dstate = DEVICE_DISCONNECTED;
+					syslog_2(LOG_ERROR, "Enumeration sequence fail idx(%d) ercd(%d) !", pdevice->idx, ercd);
+					tusbSendData(phost->process_event, TUSBH_PORT_EVENT, pdevice->idx, 0, 0);
+				}
+				break;
+			case DEVICE_CHECK_CLASS:
+				pdevice->pClass = NULL;
+				for(no = 0, pnext = phost->pClass ; no < phost->numClass ; no++){
+					if(pnext->classCode == pdevice->ItfDesc[0].bInterfaceClass){
+						pdevice->pClass = pnext;
+						break;
+					}
+					pnext = pnext->pNext;
+				}
+				if(pdevice->pClass != NULL){
+					if((ercd = pdevice->pClass->Init(pdevice)) == TUSBH_E_OK){
+						syslog_2(LOG_NOTICE, "Class start[%s] (%d) !", pdevice->pClass->Name, pdevice->idx);
+						pdevice->dstate  = DEVICE_CLASS;
+						pdevice->type    = pdevice->pClass->classCode;
+						if(phost->usrcallback != NULL)
+							phost->usrcallback(phost, pdevice, HOST_USER_CLASS_SELECTED);
+						if(tusbActivateDevice(phost) == 1)
+							tusbTimerControl(1);
+					}
+					else{
+						pdevice->dstate  = DEVICE_ABORT_STATE;
+						syslog_3(LOG_ERROR, "Class[%s] initial error(%d) (%d) !", pdevice->pClass->Name, ercd, pdevice->idx);
+					}
+				}
+				else{
+					pdevice->dstate  = DEVICE_ABORT_STATE;
+					syslog_1(LOG_ERROR, "No registered class for this device(%d) !", pdevice->idx);
+				}
+				break;
+			case DEVICE_CLASS:
+				/*
+				 *  USB HOSTクラス処理
+				 */
+				if(pdevice->pClass != NULL)
+					pdevice->pClass->Process(pdevice, mes);
+				break;
+			case DEVICE_DISCONNECTED:
+				/*
+				 *  USB HOSTクラスの終了処理
+				 */
+				syslog_1(LOG_NOTICE, "USBH device disconnect(%d) !", pdevice->idx);
+				if(pdevice->pClass != NULL){
+					pdevice->pClass->DeInit(pdevice); 
+					pdevice->pClass = NULL;
+				}
+				tusbhInitDevice(pdevice);
+				if(tusbActivateDevice(phost) == 0)
+					tusbTimerControl(0);
+				pdevice->dstate = DEVICE_IDLE;
+				break;
+
+			case DEVICE_IDLE:
+			case DEVICE_ABORT_STATE:
+			default :
+				break;
+			}
+		}
+	}
+}
+
+/*
+ *  タイマハンドラ
+ */
+void
+tusbhCyclicHandler(intptr_t exinf)
+{
+	TUSBH_Handle_t *phost = usbh_arg;
+	TUSBH_Device_t *pdevice;
+	uint8_t i;
+
+	if(phost == NULL)
+		return;
+	pdevice = phost->pDevice;
+	for(i = 0 ; i < phost->numDevice && pdevice != NULL ; i++){
+		if(pdevice->pClass != NULL && pdevice->timecount > 0){
+			if(--pdevice->timecount == 0)
+				tusbiSendData(phost->process_event, TUSBH_TIME_EVENT, pdevice->idx, 0, pdevice->timeid);
+		}
+		pdevice = pdevice->pNext;
+	}
+}
+
+/*
+ *  USBデバイスコネクト処理
+ */
+static void
+tusbhHandleConnect(TUSBH_Handle_t *phost, uint8_t hub, uint8_t port, uint8_t prm)
+{
+	TUSBH_Device_t *pdevice;
+	uint32_t no;
+
+	for(no = 0, pdevice = phost->pDevice ; no < phost->numDevice && pdevice != NULL ; no++){
+		if(pdevice->activate != 0 && pdevice->hub == hub && pdevice->port == port){
+			break;
+		}
+		pdevice = pdevice->pNext;
+	}
+	if(pdevice == NULL){
+		pdevice = tusbhAllocDevice(phost);
+		if(pdevice == NULL || pdevice->idx != no){
+			syslog_2(LOG_ERROR, "usbh device allocation error (%d)(%d) !", no, pdevice->idx);
+			return;
+		}
+	}
+	if(phost->numClass == 0)
+		syslog_0(LOG_ERROR, "No Regist Class !");
+	else if(pdevice != NULL){
+		if(pdevice->pre_connected == 0){
+			syslog_4(LOG_INFO, "connect pdevice[%08x] hub(%d) port(%d) speed(%d) !", pdevice, hub, port, prm);
+			pdevice->hub  = hub;
+			pdevice->port = port;
+			pdevice->activate = 1;
+			pdevice->pre_connected = 1;
+
+			/*
+			 *  接続後 CONNECT_WAIT_TIME ms待ち
+			 */
+			tusbDelay(CONNECT_WAIT_TIME);
+			if(hub == 0){
+				tusbhHDResetPort(phost);
+				tusbDelay(100);
+				pdevice->speed = tusbhHDGetSpeed(phost);
+			}
+			else{
+				pdevice->speed = prm;
+				tusbDelay(200);
+			}
+			pdevice->is_connected = 1;
+			if(pdevice->dstate == DEVICE_IDLE){
+				pdevice->dstate = DEVICE_ATTACHED;
+				tusbSendData(phost->process_event, TUSBH_PORT_EVENT, pdevice->idx, 0, 0);
+			}
+		}
+		else if(pdevice->dstate == DEVICE_DISCONNECTED)
+			tusbSendData(phost->process_event, TUSBH_PORT_EVENT, pdevice->idx, 0, 0);
+	}
+}
+
+/*
+ *  USBデバイスディスコネクト処理
+ */
+static void
+tusbhHandleDisconnect(TUSBH_Handle_t *phost, uint8_t hub, uint8_t port, uint8_t prm)
+{
+	TUSBH_Device_t *pdevice = phost->pDevice;
+	uint32_t no;
+
+	for(no = 0 ; no < phost->numDevice ; no++, pdevice = pdevice->pNext){
+		if(pdevice == NULL)
+			return;
+		if(pdevice->activate != 0 && pdevice->hub == hub && pdevice->port == port)
+			break;
+	}
+	if(no >= phost->numDevice)
+		return;
+	if(pdevice->is_connected == 0)
+		return;
+
+	/*
+	 *  Hostペリフェラル停止
+	 */
+	if(hub == 0)
+		tusbhHDStop(phost);
+
+	/*
+	 *  コントロール通信用PIPEを解放
+	 */
+	tusbhClosePipe(pdevice, pdevice->cntl_pipe_in);
+	tusbFreePipe(phost, pdevice->cntl_pipe_in);
+	tusbhClosePipe(pdevice, pdevice->cntl_pipe_out);
+	tusbFreePipe(phost, pdevice->cntl_pipe_out);
+
+	pdevice->is_connected = 0;
+	pdevice->pre_connected = 0;
+
+	/*
+	 *  ユーザーへ通知
+	 */
+	if(phost->usrcallback != NULL)
+		phost->usrcallback(phost, pdevice, HOST_USER_DISCONNECTION);
+	syslog_4(LOG_NOTICE, "USB Device disconnected [%02x][%02x][%02x] device(%d) !", hub, port, prm, pdevice->idx); 
+
+	/*
+	 *  Hostペリフェラル再開
+	 */
+	if(hub == 0)
+		tusbhHDStart(phost);
+
+	pdevice->dstate = DEVICE_DISCONNECTED;
+	tusbSendData(phost->process_event, TUSBH_PORT_EVENT, pdevice->idx, 0, 0);
+}
+
+/*
+ *  USBホストイベントタスク
+ */
+void
+tusbhEventTask(intptr_t exinf)
+{
+	uint8_t       mes[4];
+	ER            ercd;
+
+	for(;;){
+		ercd = tusbRecvData(usbh_arg->connect_event, mes, 0);
+
+		if(ercd == E_OK){
+			syslog_4(LOG_INFO, "usbh_task evt(%d) [%02x][%02x][%02x] !", mes[0], mes[1], mes[2], mes[3]);
+			if(mes[0] == TUSBH_CONNECT_EVENT)
+				tusbhHandleConnect(usbh_arg, mes[1], mes[2], mes[3]);
+			else if(mes[0] == TUSBH_DISCONNECT_EVENT){
+				dly_tsk(200);
+				tusbhHandleDisconnect(usbh_arg, mes[1], mes[2], mes[3]);
+			}
+			else if(mes[0] == TUSBH_IDCHANGE_EVENT){
+				dly_tsk(200);
+				tusbhHDStart(usbh_arg);
+			}
+		}
+	}
+}
+
+
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/usb/host/tusbh_base.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/usb/host/tusbh_base.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/usb/host/tusbh_base.h	(revision 457)
@@ -0,0 +1,293 @@
+/*
+ *  TOPPERS BASE PLATFORM MIDDLEWARE
+ * 
+ *  Copyright (C) 2017-2018 by TOPPERS PROJECT
+ *                             Educational Working Group.
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+/*
+ *  USB Host Middleware BASE部定義
+ */
+
+#ifndef _HUSBH_BASE_H_
+#define _HUSBH_BASE_H_
+
+#include "tusb_rtos.h"
+#include "tusb_types.h"
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+#ifndef TUSBH_MAX_NUM_ENDPOINTS
+#define TUSBH_MAX_NUM_ENDPOINTS           3
+#endif
+#ifndef TUSBH_MAX_NUM_INTERFACES
+#define TUSBH_MAX_NUM_INTERFACES          2
+#endif
+#ifndef TUSBH_MAX_DATA_BUFFER
+#define TUSBH_MAX_DATA_BUFFER             0x200
+#endif
+
+/*
+ *  STMユーザーイベント
+ */
+#define HOST_USER_SELECT_CONFIGURATION    1
+#define HOST_USER_CLASS_ACTIVE            2
+#define HOST_USER_CLASS_SELECTED          3
+#define HOST_USER_CONNECTION              4
+#define HOST_USER_DISCONNECTION           5
+#define HOST_USER_UNRECOVERED_ERROR       6
+
+/*Standard Feature Selector for clear feature command*/
+#define FEATURE_SELECTOR_ENDPOINT         0X00
+#define FEATURE_SELECTOR_DEVICE           0X01
+
+/*
+ *  SUBMITタイプ
+ */
+#define SUBMIT_SETUP                      ((0<<8) | USB_PID_SETUP)
+#define SUBMIT_WRITE                      ((0<<8) | USB_PID_DATA)
+#define SUBMIT_READ                       ((1<<8) | USB_PID_DATA)
+
+/*
+ *  パイプ属性定義
+ */
+#define PIPE_ACTIVATE                     0x8000
+#define PIPE_ADDRESS                      0x00FF
+
+
+#define NO_INTERFACE                      0xFF
+
+
+/*
+ *  URBステート定義
+ */
+typedef enum {
+	TUSBH_URB_IDLE = 0,
+	TUSBH_URB_DONE,
+	TUSBH_URB_NOTREADY,
+	TUSBH_URB_NYET,
+	TUSBH_URB_ERROR,
+	TUSBH_URB_STALL
+} TUSBH_URBState_t;
+
+/*
+ *  プロセスイベント
+ */
+enum {
+	TUSBH_PORT_EVENT = 1,
+	TUSBH_URB_EVENT,
+	TUSBH_TIME_EVENT,
+	TUSBH_CLASS_EVENT,
+	TUSBH_RESET_EVENT
+};
+
+enum {
+	TUSBH_CONNECT_EVENT = 1,
+	TUSBH_DISCONNECT_EVENT,
+	TUSBH_IDCHANGE_EVENT,
+};
+
+/*
+ *  デバイス状態定義
+ */
+enum {
+	DEVICE_IDLE = 0,
+	DEVICE_ATTACHED,
+	DEVICE_DISCONNECTED,
+	DEVICE_CHECK_CLASS,
+	DEVICE_CLASS,
+	DEVICE_SUSPENDED,
+	DEVICE_ABORT_STATE,
+};
+
+/*
+ *  CONTROL通信状態
+ */
+enum {
+	CONTROL_IDLE = 0,
+	CONTROL_SETUP,
+	CONTROL_SETUP_WAIT,
+	CONTROL_DATA_IN_WAIT,
+	CONTROL_DATA_OUT_WAIT,
+	CONTROL_STATUS_IN_WAIT,
+	CONTROL_STATUS_OUT_WAIT,
+	CONTROL_ERROR
+};
+
+
+#define USBH_HandleTypeDef     TUSBH_Handle_t
+typedef struct _TUSBH_Handle_t TUSBH_Handle_t;
+typedef struct _TUSBH_Class_t  TUSBH_Class_t;
+typedef struct _TUSBH_Device_t TUSBH_Device_t;
+
+typedef struct
+{
+	uint16_t                   attribute;
+	uint8_t                    index;
+	uint8_t                    type;
+} USBH_Pipe_t;
+
+/*
+ *  USBホストクラス定義
+ */
+struct _TUSBH_Class_t
+{
+	TUSBH_Class_t              *pNext;
+	const char                 *Name;
+	uint32_t                   classCode;
+	TUSBH_ERCODE               (*Init)(TUSBH_Device_t *pdevice);
+	TUSBH_ERCODE               (*DeInit)(TUSBH_Device_t *pdevice);
+	TUSBH_ERCODE               (*Process)(TUSBH_Device_t *pdevice, uint8_t *mes);
+	void                       *subfunc;
+};
+
+/*
+ *  USBホストデバイスハンドラ
+ */
+struct _TUSBH_Device_t
+{
+	TUSBH_Device_t             *pNext;
+	TUSBH_Handle_t             *pHost;
+	TUSBH_Class_t              *pClass;
+	uint8_t                    activate;
+	uint8_t                    address;
+	uint8_t                    speed;
+	volatile uint8_t           is_connected;
+	uint8_t                    pre_connected;
+	uint8_t                    sel_interface;
+	uint8_t                    hub;
+	uint8_t                    port;
+	uint8_t                    idx;
+	volatile uint8_t           dstate;
+	uint16_t                   timeid;
+	uint32_t                   timecount;
+
+	uint8_t                    cntl_pipe_in;
+	uint8_t                    cntl_pipe_out;
+	uint8_t                    cntl_pipe_size;
+	uint8_t                    cntl_errcount;
+    uint8_t                    setupPacket[8];
+	uint32_t                   dummy[6];	/* dummy for cache */
+	uint8_t                    Data[TUSBH_MAX_DATA_BUFFER];
+	DeviceDescriptor           DevDesc;
+	ConfigurationDescriptor    CfgDesc;
+	InterfaceDescriptor        ItfDesc[TUSBH_MAX_NUM_INTERFACES];
+	EndpointDescriptor         EpDesc[TUSBH_MAX_NUM_INTERFACES][TUSBH_MAX_NUM_ENDPOINTS];
+
+	uint8_t                    type;
+	uint8_t                    hubid;
+	volatile uint8_t           cstate;
+	uint8_t                    numUnit;
+	void                       *pData;
+	uint8_t                    *cbuff;
+	char                       Manufacturer[TUSBH_STR_LENGTH];
+	char                       Prodeuct[TUSBH_STR_LENGTH];
+	char                       Serial[TUSBH_STR_LENGTH];
+};
+
+/*
+ *  USBホストハンドラ
+ */
+struct _TUSBH_Handle_t
+{
+	TUSBH_Device_t             *pDevice;
+	TUSBH_Class_t              *pClass;
+	USBH_Pipe_t                pipes[MAX_EPS_PIPES];
+	uint32_t                   numPipes;
+	void                       *pSysData;
+	uint8_t                    *pCfgData;
+	void                       (*usrcallback)(TUSBH_Handle_t *pHandle, TUSBH_Device_t *pdevice, uint8_t id);
+
+	uint8_t                    id;
+	uint8_t                    numDevice;
+	uint8_t                    numClass;
+	uint8_t                    numHub;
+	ID                         processTaskID;
+	ID                         eventTaskID;
+	ID                         process_event;
+	ID                         connect_event;
+};
+
+#include "tusbh_conf.h"
+
+/*
+ *  関数プロトタイプ宣言
+ */
+TUSBH_ERCODE tusbhInit(TUSBH_Handle_t *phost, void (*pufunc)(TUSBH_Handle_t*, TUSBH_Device_t *, uint8_t ), uint8_t id);
+TUSBH_ERCODE tusbhDeInit(TUSBH_Handle_t *phost);
+TUSBH_ERCODE tusbhLinkClass(TUSBH_Handle_t *phost, TUSBH_Class_t *pclass);
+TUSBH_ERCODE tusbhStart(TUSBH_Handle_t *phost);
+TUSBH_ERCODE tusbhStop(TUSBH_Handle_t *phost);
+
+TUSBH_ERCODE tusbhResetHub(TUSBH_Device_t *pdevice);
+TUSBH_ERCODE tusbhSelectInterface(TUSBH_Device_t *pdevice, uint8_t interface);
+uint8_t      tusbhFindInterface(TUSBH_Device_t *pdevice, uint8_t Class, uint8_t SubClass, uint8_t Protocol);
+uint8_t      tusbhGetActiveClass(TUSBH_Device_t *pdevice);
+uint8_t      tusbhFindInterfacebynumber(TUSBH_Device_t *pdevice, uint8_t interface, uint8_t altsetno);
+
+TUSBH_ERCODE tusbhControlRequest(TUSBH_Device_t *pdevice, uint8_t *buff, uint8_t type, uint8_t request, uint16_t value, uint16_t index, uint16_t length);
+TUSBH_ERCODE tusbhControlWait(TUSBH_Device_t *pdevice, uint8_t *mes);
+TUSBH_ERCODE tusbhGetDescriptor(TUSBH_Device_t *pdevice, uint8_t req_type, uint16_t value, uint8_t* buff, uint16_t length);
+TUSBH_ERCODE tusbhSetInterface(TUSBH_Device_t *pdevice, uint8_t ep_num, uint8_t interface);
+TUSBH_ERCODE tusbhClearFeature(TUSBH_Device_t *pdevice, uint8_t ep_num);
+
+TUSBH_ERCODE tusbhOpenPipe(TUSBH_Device_t *, uint8_t, uint8_t, uint8_t, uint16_t);
+TUSBH_ERCODE tusbhClosePipe(TUSBH_Device_t *, uint8_t pipe);
+TUSBH_ERCODE tusbhSubmitURB(TUSBH_Device_t *pdevice, uint8_t, uint16_t, uint8_t, uint8_t*, uint16_t);
+TUSBH_ERCODE tusbhControlSendSetup(TUSBH_Device_t *pdevice, uint8_t *buff, uint8_t pipe_num);
+TUSBH_ERCODE tusbhControlSendData(TUSBH_Device_t *pdevice, uint8_t *buff, uint16_t length, uint8_t pipe_num);
+TUSBH_ERCODE tusbhControlReceiveData(TUSBH_Device_t *pdevice, uint8_t* buff, uint16_t length, uint8_t pipe_num);
+TUSBH_ERCODE tusbhBulkWrite(TUSBH_Device_t *pdevice, uint8_t *buff, uint16_t length, uint8_t pipe_num);
+TUSBH_ERCODE tusbhBulkRead(TUSBH_Device_t *pdevice, uint8_t *buff, uint16_t length, uint8_t pipe_num);
+TUSBH_ERCODE tusbhInterruptWrite(TUSBH_Device_t *pdevice, uint8_t *buff, uint8_t length, uint8_t pipe_num);
+TUSBH_ERCODE tusbhInterruptRead(TUSBH_Device_t *pdevice, uint8_t *buff, uint8_t length, uint8_t pipe_num);
+TUSBH_ERCODE tusbhIsocWrite(TUSBH_Device_t *pdevice, uint8_t *buff, uint32_t length, uint8_t pipe_num);
+TUSBH_ERCODE tusbhIsocRead(TUSBH_Device_t *pdevice, uint8_t *buff, uint32_t length, uint8_t pipe_num);
+
+void tusbhProcessTask(intptr_t exinf);
+void tusbhEventTask(intptr_t exinf);
+void tusbhCyclicHandler(intptr_t exinf);
+
+TUSBH_Device_t *tusbhSearchDevice(TUSBH_Handle_t *phost, uint8_t classCode, uint8_t *plun);
+uint8_t tusbhAllocPipe(TUSBH_Handle_t *phost, uint8_t ep_addr);
+TUSBH_ERCODE tusbFreePipe(TUSBH_Handle_t *phost, uint8_t no);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _HUSBH_BASE_H_ */
+
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/usb/host/tusbh_request.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/usb/host/tusbh_request.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/usb/host/tusbh_request.c	(revision 457)
@@ -0,0 +1,459 @@
+/*
+ *  TOPPERS BASE PLATFORM MIDDLEWARE
+ * 
+ *  Copyright (C) 2017-2017 by TOPPERS PROJECT
+ *                             Educational Working Group.
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+/*
+ *  USB Host Middleware 通信リクエスト部
+ */
+
+#include "tusbh_base.h"
+
+
+/*
+ *  BULK通信：WRITE
+ *  parameter1 pdevice:  デバイスハンドラ
+ *  parameter2 buff:     データ領域
+ *  parameter3 length:   データ長
+ *  parameter4 pipe_num: PIPE番号
+ *  return     TUSBH_ERCOCE
+ */
+TUSBH_ERCODE
+tusbhBulkWrite(TUSBH_Device_t *pdevice, uint8_t *buff, uint16_t length, uint8_t pipe_num)
+{ 
+	return tusbhSubmitURB(pdevice, pipe_num, SUBMIT_WRITE, USB_EP_TYPE_BULK, buff, length);
+}
+
+/*
+ *  BULK通信：READ
+ *  parameter1 pdevice:  デバイスハンドラ
+ *  parameter2 buff:     データ領域
+ *  parameter3 length:   データ長
+ *  parameter4 pipe_num: PIPE番号
+ *  return     TUSBH_ERCOCE
+ */
+TUSBH_ERCODE
+tusbhBulkRead(TUSBH_Device_t *pdevice, uint8_t *buff, uint16_t length, uint8_t pipe_num)
+{
+	return tusbhSubmitURB(pdevice, pipe_num, SUBMIT_READ, USB_EP_TYPE_BULK, buff, length);
+}
+
+/*
+ *  INTERRUPT通信：WRITE
+ *  parameter1 pdevice:  デバイスハンドラ
+ *  parameter2 buff:     データ領域
+ *  parameter3 length:   データ長
+ *  parameter4 pipe_num: PIPE番号
+ *  return     TUSBH_ERCOCE
+ */
+TUSBH_ERCODE
+tusbhInterruptWrite(TUSBH_Device_t *pdevice, uint8_t *buff, uint8_t length, uint8_t pipe_num)
+{
+	return tusbhSubmitURB(pdevice, pipe_num, SUBMIT_WRITE, USB_EP_TYPE_INTR, buff, length);
+}
+
+/*
+ *  INTERRUPT通信：READ
+ *  parameter1 pdevice:  デバイスハンドラ
+ *  parameter2 buff:     データ領域
+ *  parameter3 length:   データ長
+ *  parameter4 pipe_num: PIPE番号
+ *  return     TUSBH_ERCOCE
+ */
+TUSBH_ERCODE
+tusbhInterruptRead(TUSBH_Device_t *pdevice, uint8_t *buff, uint8_t length, uint8_t pipe_num)
+{
+	return tusbhSubmitURB(pdevice, pipe_num, SUBMIT_READ, USB_EP_TYPE_INTR, buff, length);
+}
+
+/*
+ *  ISOC通信：WRITE
+ *  parameter1 pdevice:  デバイスハンドラ
+ *  parameter2 buff:     データ領域
+ *  parameter3 length:   データ長
+ *  parameter4 pipe_num: PIPE番号
+ *  return     TUSBH_ERCOCE
+ */
+TUSBH_ERCODE
+tusbhIsocWrite(TUSBH_Device_t *pdevice, uint8_t *buff, uint32_t length, uint8_t pipe_num)
+{
+	return tusbhSubmitURB(pdevice, pipe_num, SUBMIT_WRITE, USB_EP_TYPE_ISOC, buff, length);
+}
+
+/**
+  * @brief  USBH_IsocReceiveData
+  *         Receives the Device Response to the Isochronous IN token
+  * @param  phost: Host Handle
+  * @param  buff: Buffer pointer in which the response needs to be copied
+  * @param  length: Length of the data to be received
+  * @param  pipe_num: Pipe Number
+  * @retval USBH Status. 
+  */
+TUSBH_ERCODE
+tusbhIsocRead(TUSBH_Device_t *pdevice, uint8_t *buff, uint32_t length, uint8_t pipe_num)
+{
+	return tusbhSubmitURB(pdevice, pipe_num, SUBMIT_READ, USB_EP_TYPE_ISOC, buff, length);
+}
+
+
+/*
+ *  コントロール通信：SETUP送信
+ *  parameter1 pdevice:  デバイスハンドラ
+ *  parameter2 buff:     セットアップデータ領域
+ *  parameter3 pipe_num: PIPE番号
+ *  return     TUSBH_ERCOCE
+ */
+TUSBH_ERCODE
+tusbhControlSendSetup(TUSBH_Device_t *pdevice, uint8_t *buff, uint8_t pipe_num)
+{
+	return tusbhSubmitURB(pdevice, pipe_num, SUBMIT_SETUP, USB_EP_TYPE_CTRL, buff, SETUP_PKT_LENGTH);
+}
+
+/*
+ *  コントロール通信：データ送信
+ *  parameter1 pdevice:  デバイスハンドラ
+ *  parameter2 buff:     データ領域
+ *  parameter3 length:   データ長
+ *  parameter4 pipe_num: パイプ番号
+ *  return     TUSBH_ERCOCE
+ */
+TUSBH_ERCODE
+tusbhControlSendData(TUSBH_Device_t *pdevice, uint8_t *buff, uint16_t length, uint8_t pipe_num)
+{
+	return tusbhSubmitURB(pdevice, pipe_num, SUBMIT_WRITE, USB_EP_TYPE_CTRL, buff, length);
+}
+
+/*
+ *  コントロール通信：データ受信
+ *  parameter1 pdevice:  デバイスハンドラ
+ *  parameter2 buff:     データ領域
+ *  parameter3 length:   データ長
+ *  parameter4 pipe_num: パイプ番号
+ *  return     TUSBH_ERCOCE
+ */
+TUSBH_ERCODE
+tusbhControlReceiveData(TUSBH_Device_t *pdevice, uint8_t* buff, uint16_t length, uint8_t pipe_num)
+{
+	return tusbhSubmitURB(pdevice, pipe_num, SUBMIT_READ, USB_EP_TYPE_CTRL, buff, length);
+}
+
+/*
+ *  コントロール通信：DESCRIPTOR取得
+ *  parameter1 pdevice:  デバイスハンドラ
+ *  parameter2 req_type: DESCRIPTORタイプ
+ *  parameter3 value:    DESCRIPTOR要求値
+ *  parameter4 buff:     DESCRIPTO格納領域
+ *  parameter5 length:   DESCRIPTOR長
+ *  return     TUSBH_ERCOCE
+ */
+TUSBH_ERCODE
+tusbhGetDescriptor(TUSBH_Device_t *pdevice, uint8_t req_type, uint16_t value, uint8_t* buff, uint16_t length)
+{
+	uint16_t index;
+
+	if((value & 0xff00) == ((STRING_DESCRIPTOR << 8) & 0xFF00)){
+		index = 0x0409;
+	}
+	else
+		index = 0;
+	return tusbhControlRequest(pdevice, buff, (USB_DEVICE_TO_HOST | req_type), GET_DESCRIPTOR, value, index, length );
+}
+
+/*
+ *  コントロール通信：SET INTERFACEの送信
+ *  parameter1 pdevice: デバイスハンドラ
+ *  parameter2 ep_num:  エンドポイント番号
+ *  parameter3 interface: インタフェース値
+ *  return     TUSBH_ERCOCE
+ */
+TUSBH_ERCODE
+tusbhSetInterface(TUSBH_Device_t *pdevice, uint8_t ep_num, uint8_t interface)
+{
+	return tusbhControlRequest(pdevice, 0, SET_INTERFACE_TYPE, SET_INTERFACE, interface, ep_num, 0);
+}
+
+/*
+ *  コントロール通信：CLEAR FEATUREの送信
+ *  parameter1 pdevice: デバイスハンドラ
+ *  parameter2 ep_num:  エンドポイント番号
+ *  return     TUSBH_ERCOCE
+ */
+TUSBH_ERCODE
+tusbhClearFeature(TUSBH_Device_t *pdevice, uint8_t ep_num) 
+{
+	return tusbhControlRequest(pdevice, 0, CLEAR_FEATURE_TYPE, CLEAR_FEATURE, FEATURE_SELECTOR_ENDPOINT, ep_num, 0 );
+}
+
+
+/*
+ *  コントロール通信の要求
+ *  parameter1 pdevice: デバイスハンドラ
+ *  parameter2 buff:    通信バッファ
+ *  parameter3 type:    bmRequestType
+ *  parameter4 request: bRequest
+ *  parameter5 value:   wValue
+ *  parameter6 index:   wIndex
+ *  parameter7 length:  wLength
+ *  return     TUSBH_ERCOCE
+ */
+TUSBH_ERCODE
+tusbhControlRequest(TUSBH_Device_t *pdevice, uint8_t *buff, uint8_t type, uint8_t request, uint16_t value, uint16_t index, uint16_t length)
+{
+	TUSBH_Handle_t *phost = pdevice->pHost;
+	TUSBH_ERCODE ercd = TUSBH_E_BUSY;
+	uint8_t mes[4];
+
+	pdevice->cstate = CONTROL_SETUP;
+	pdevice->setupPacket[0] = type;
+	pdevice->setupPacket[1] = request;
+	pdevice->setupPacket[2] = (uint8_t)value;
+	pdevice->setupPacket[3] = (uint8_t)(value >> 8);
+	pdevice->setupPacket[4] = (uint8_t)index;
+	pdevice->setupPacket[5] = (uint8_t)(index >> 8);
+	pdevice->setupPacket[6] = (uint8_t)length; 
+	pdevice->setupPacket[7] = (uint8_t)(length >> 8); 
+	pdevice->cbuff          = buff;
+	mes[0]                  = TUSBH_PORT_EVENT;
+
+	do{
+		ercd = tusbhControlWait(pdevice, mes);
+		if(pdevice->dstate == DEVICE_CLASS)
+			return ercd;
+		while(ercd == TUSBH_E_BUSY_URB){
+			if(tusbRecvData(phost->process_event, mes, 4000) != E_OK){
+				syslog_1(LOG_ERROR, "tusbhControlRequest urb timeout state(%d) !", pdevice->cstate);
+				ercd = TUSBH_E_TMOUT;
+				break;
+			}
+			else if(mes[0] == TUSBH_URB_EVENT && mes[1] == pdevice->idx){
+				ercd = TUSBH_E_BUSY;
+			}
+			else if(mes[1] != pdevice->idx){
+				TUSBH_Device_t *pdevice2 = phost->pDevice;
+				uint8_t i;
+				for(i = 0 ; i < mes[1] ; i++)
+					pdevice2 = pdevice2->pNext;
+				if(pdevice2 != NULL && pdevice2->pClass != NULL && pdevice2->dstate == DEVICE_CLASS)
+					pdevice2->pClass->Process(pdevice2, mes);
+				else{
+#if 1	/* ROI DEBUG */
+					syslog_4(LOG_ERROR, "### tusbhControlRequest Can't EXEC [%02x][%02x][%02x][%02x] ###", mes[0], mes[1], mes[2], mes[3]);
+#endif	/* ROI DEBUG */
+					tusbDelay(10);
+					tusbSendData(phost->process_event, mes[0], mes[1], mes[2], mes[3]);
+				}
+			}
+		}
+	}while(ercd == TUSBH_E_BUSY);
+	return ercd;
+}
+
+/*
+ *  コントロール通信の待ち
+ *  parameter1 pdevice: デバイスハンドラ
+ *  parameter2 mes:     メッセージへのポインタ
+ *  return     TUSBH_ERCOCE
+ */
+TUSBH_ERCODE
+tusbhControlWait(TUSBH_Device_t *pdevice, uint8_t *mes)
+{
+	TUSBH_Handle_t *phost = pdevice->pHost;
+	TUSBH_ERCODE ercd = TUSBH_E_BUSY;
+	TUSBH_URBState_t URB_Status = mes[3];
+	uint8_t  type = pdevice->setupPacket[0];
+	uint16_t length = (pdevice->setupPacket[7] << 8) | (pdevice->setupPacket[6] & 0xFF);
+
+	switch(pdevice->cstate){
+	case CONTROL_SETUP:	/* PACKETセットアップ */
+		tusbhControlSendSetup(pdevice, (uint8_t *)&pdevice->setupPacket, pdevice->cntl_pipe_out); 
+		pdevice->cstate = CONTROL_SETUP_WAIT;
+		ercd = TUSBH_E_BUSY_URB;
+		break;
+	case CONTROL_SETUP_WAIT:	/* PACKETセットアップ URB待ち */
+		if(mes[0] != TUSBH_URB_EVENT)
+			break;
+		if(URB_Status == TUSBH_URB_DONE){	/* 正常終了 */
+			uint8_t direction = (type & USB_REQUEST_DIR_MASK);
+			if(length != 0 ){
+				if(direction == USB_DEVICE_TO_HOST){	/* データREAD */
+					tusbhControlReceiveData(pdevice, pdevice->cbuff, length, pdevice->cntl_pipe_in);
+					pdevice->cstate = CONTROL_DATA_IN_WAIT;
+				}
+				else{						/* データWRITE */
+					tusbhControlSendData(pdevice, pdevice->cbuff, length, pdevice->cntl_pipe_out);
+					pdevice->cstate = CONTROL_DATA_OUT_WAIT;
+				}
+			}
+			else{			/* ステータス通信 */
+				if(direction == USB_DEVICE_TO_HOST){	/* ステータス受信 */
+					tusbhControlSendData(pdevice, 0, 0, pdevice->cntl_pipe_out);
+					pdevice->cstate = CONTROL_STATUS_OUT_WAIT;
+				}
+				else{						/* ステータス送信 */
+					tusbhControlReceiveData(pdevice, 0, 0, pdevice->cntl_pipe_in);
+					pdevice->cstate = CONTROL_STATUS_IN_WAIT;
+				}
+			}
+			ercd = TUSBH_E_BUSY_URB;
+		}
+		else if(URB_Status == TUSBH_URB_ERROR)	/* USBエラー */
+			pdevice->cstate = CONTROL_ERROR;
+		else if(URB_Status == TUSBH_URB_NOTREADY){
+			syslog_0(LOG_NOTICE, "### tusbhControlRequest REAET STATE1 ###");
+			pdevice->cstate = CONTROL_SETUP;
+		}
+		else{
+			syslog_2(LOG_ERROR, "tusbhControlRequest urb error state(%d) urb[%02x] !", pdevice->cstate, URB_Status);
+			ercd = TUSBH_E_URB;
+		}
+		break;
+	case CONTROL_DATA_IN_WAIT:		/* データ受信待ち */
+		if(mes[0] != TUSBH_URB_EVENT)
+			break;
+		if(URB_Status == TUSBH_URB_DONE){	/* 正常終了 */
+			tusbhControlSendData(pdevice, 0, 0, pdevice->cntl_pipe_out);
+			pdevice->cstate = CONTROL_STATUS_OUT_WAIT;
+			ercd = TUSBH_E_BUSY_URB;
+		}
+		else if(URB_Status == TUSBH_URB_STALL){	/* ステール状態 */
+			pdevice->cstate = CONTROL_IDLE;
+			ercd = TUSBH_E_NOSPT;
+		}
+		else if(URB_Status == TUSBH_URB_ERROR)	/* URBエラー */
+			pdevice->cstate = CONTROL_ERROR;
+		else if(URB_Status == TUSBH_URB_NOTREADY){
+			syslog_0(LOG_NOTICE, "### tusbhControlRequest REAET STATE2 ###");
+			pdevice->cstate = CONTROL_SETUP;
+		}
+		else{
+			syslog_2(LOG_ERROR, "tusbhControlRequest urb error state(%d) urb[%02x] !", pdevice->cstate, URB_Status);
+			ercd = TUSBH_E_URB;
+		}
+		break;
+	case CONTROL_DATA_OUT_WAIT:	/* データ送信終了待ち */
+		if(mes[0] != TUSBH_URB_EVENT)
+			break;
+		if(URB_Status == TUSBH_URB_DONE){	/* 正常終了 */
+			tusbhControlReceiveData(pdevice, 0, 0, pdevice->cntl_pipe_in);
+			pdevice->cstate = CONTROL_STATUS_IN_WAIT;
+			ercd = TUSBH_E_BUSY_URB;
+		}
+		else if(URB_Status == TUSBH_URB_STALL){	/* ステール状態 */
+			pdevice->cstate = CONTROL_IDLE;
+			ercd = TUSBH_E_NOSPT;
+		}
+		else if(URB_Status == TUSBH_URB_NOTREADY){
+			/* Nack received from device */
+			tusbhControlSendData(pdevice, pdevice->cbuff, length, pdevice->cntl_pipe_out);
+			ercd = TUSBH_E_BUSY_URB;
+		}
+		else if(URB_Status == TUSBH_URB_ERROR)	/* USBエラー */
+			pdevice->cstate = CONTROL_ERROR;
+		else{
+			syslog_2(LOG_ERROR, "tusbhControlRequest urb error state(%d) urb[%02x] !", pdevice->cstate, URB_Status);
+			ercd = TUSBH_E_URB;
+		}
+		break;
+	case CONTROL_STATUS_IN_WAIT:	/* ステータス送信待ち */
+		if(mes[0] != TUSBH_URB_EVENT)
+			break;
+		if(URB_Status == TUSBH_URB_DONE){	/* 正常終了 */
+			pdevice->cstate = CONTROL_IDLE;
+			ercd = TUSBH_E_OK;
+			tusbSendData(phost->process_event, TUSBH_PORT_EVENT, pdevice->idx, 0, 0);
+		}
+		else if(URB_Status == TUSBH_URB_ERROR)	/* USBエラー */
+			pdevice->cstate = CONTROL_ERROR;
+		else if(URB_Status == TUSBH_URB_STALL){	/* ステール状態 */
+			pdevice->cstate = CONTROL_IDLE;
+			ercd = TUSBH_E_NOSPT;
+		}
+		else if(URB_Status == TUSBH_URB_NOTREADY){
+			syslog_0(LOG_NOTICE, "### tusbhControlRequest REAET STATE3 ###");
+			pdevice->cstate = CONTROL_SETUP;
+		}
+		else{
+			syslog_2(LOG_ERROR, "tusbhControlRequest urb error state(%d) urb[%02x] !", pdevice->cstate, URB_Status);
+			ercd = TUSBH_E_URB;
+		}
+		break;
+	case CONTROL_STATUS_OUT_WAIT:	/* ステータス受信待ち */
+		if(mes[0] != TUSBH_URB_EVENT)
+			break;
+		if(URB_Status == TUSBH_URB_DONE){
+			pdevice->cstate = CONTROL_IDLE;
+			ercd = TUSBH_E_OK;
+			tusbSendData(phost->process_event, TUSBH_PORT_EVENT, pdevice->idx, 0, 0);
+		}
+		else if(URB_Status == TUSBH_URB_NOTREADY){ 
+			tusbhControlSendData(pdevice, 0, 0, pdevice->cntl_pipe_out);
+			ercd = TUSBH_E_BUSY_URB;
+		}
+		else if(URB_Status == TUSBH_URB_ERROR)	/* USBエラー */
+			pdevice->cstate = CONTROL_ERROR;
+		else{
+			syslog_2(LOG_ERROR, "tusbhControlRequest urb error state(%d) urb[%02x] !", pdevice->cstate, URB_Status);
+			ercd = TUSBH_E_URB;
+		}
+		break;
+	case CONTROL_ERROR:
+		/*
+		 *  コントロール通信エラーケース
+		 *  エラーカウントが TUSBH_MAX_ERROR_COUNT以下ならばリトライする
+		 */
+		if(++pdevice->cntl_errcount <= TUSBH_MAX_ERROR_COUNT){
+			if(pdevice->hub == 0)
+				tusbhHDStop(phost);
+			else
+				tusbhResetHub(pdevice);
+			/*
+			 *  リトライする
+			 */
+			pdevice->cstate = CONTROL_SETUP;
+		}
+		else{
+			if(phost->usrcallback != NULL)
+				phost->usrcallback(phost, pdevice, HOST_USER_UNRECOVERED_ERROR);
+			pdevice->cntl_errcount = 0;
+			syslog_1(LOG_ERROR, "tusbhControlRequest error count(%d) !", pdevice->cntl_errcount);
+			ercd = TUSBH_E_ERR;
+		}
+		break;
+	default:
+		break;
+	}
+	return ercd;
+}
+
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/usb/mscdiskio.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/usb/mscdiskio.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/usb/mscdiskio.c	(revision 457)
@@ -0,0 +1,294 @@
+/*
+ *  TOPPERS/ASP/FMP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Advanced Standard Profile Kernel
+ * 
+ *  Copyright (C) 2008-2011 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ *  Copyright (C) 2015-2017 by TOPPERS PROJECT Educational Working Group.
+ * 
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ * ＭＳＣ専用ストレージ関数をサポートする
+ * 擬似的なストレージ関数郡であり、標準ライブラリィと分けての使用が望ましい。
+ * 1. msc_init                 この関数郡の初期化関数(bssがゼロ設定の場合この関数は不要)
+ * 2. msc_sense                MSCのセンスを行う
+ * 3. msc_diskstatus           MSCのステータス取得:なし
+ * 4. msc_diskread             MSCの読み込み:なし
+ * 5. msc_diskwrite            MSCの書き込み:なし
+ * 6. msc_iocil                MSCのIO制御:なし
+ *
+ */
+
+#include "kernel_impl.h"
+#include <stdlib.h>
+#include <string.h>
+#include <t_syslog.h>
+#include <t_stdlib.h>
+#include "fcntl.h"
+#include "device.h"
+#include "storagedevice.h"
+#include "ff.h"
+#include "diskio.h"
+#include "usb_otg.h"
+#include "mscdiskio.h"
+#include "tusbh_msc.h"
+
+static int msc_sense(void *psdev, bool_t on);
+static int msc_diskstatus(void *psdev);
+static int msc_diskread(void *pif, BYTE *Buffer, DWORD SectorNumber, BYTE SectorCount);
+static int msc_diskwrite(void *pif, const BYTE *Buffer, DWORD SectorNumber, BYTE SectorCount);
+static int msc_diskioctl(void *pif, BYTE Func, void* Buffer);
+
+static const StorageDeviceFunc_t fatfsMscDeviceFunc = {
+	msc_sense,
+	msc_diskstatus,
+	msc_diskstatus,
+	(int(*)())msc_diskread,
+	(int(*)())msc_diskwrite,
+	(int(*)())msc_diskioctl
+};
+
+static MSC_Unit_t MSCLUNInfo;
+static FATFS ActiveFatFsObj __attribute__ ((aligned (32)));
+
+/*
+ *  FatFs用SDカードファイルドライバの初期化
+ */
+#if MSC_DEVNO == 0
+void sd_init(intptr_t exinf)
+#else
+void msc_init(intptr_t exinf)
+#endif
+{
+	StorageDevice_t *psdev;
+
+	SDMSetupDevice(MSC_DEVNO, &psdev);
+	psdev->pdevf            = (StorageDeviceFunc_t *)&fatfsMscDeviceFunc;
+	psdev->pdevff           = (StorageDeviceFileFunc_t *)&fatfsSDeviceFileFunc;
+	psdev->_sdev_secsize    = 512;
+	psdev->_sdev_port       = MSC_PORTID;
+#ifdef SDEV_INSWAIT_TIME
+	psdev->_sdev_inswait    = SDEV_INSWAIT_TIME;
+#else
+	psdev->_sdev_inswait    = 0;
+#endif
+	psdev->_sdev_attribute |= SDEV_INSERTCHK|SDEV_CHKREMOVE;
+	psdev->_sdev_local[0]   = &ActiveFatFsObj;
+	psdev->_sdev_local[1]   = NULL;
+}
+
+/*
+ *  MSCセンス関数
+ */
+static int msc_sense(void *pif, BOOL on)
+{
+	StorageDevice_t  *psdev = pif;
+	TUSBH_Handle_t   *husbh;
+	TUSBH_ERCODE     status;
+	bool_t   exist;
+	char     pdrv;
+	int      result = FR_DISK_ERR;
+
+	pdrv  = psdev->_sdev_port - MSC_PORTID;
+	husbh = (TUSBH_Handle_t *)psdev->_sdev_local[1];
+	if(husbh == NULL)
+		exist = 0;
+	else
+		exist = tusbhMscUnitIsReady(husbh, pdrv);
+	if(on && !exist){
+		f_mount(psdev->_sdev_devno, 0);
+		psdev->_sdev_attribute &= ~SDEV_DEVERROR;
+		return TRUE;
+	}
+	else if(!on && exist){
+		psdev->_sdev_instimer += SENSE_TIME;
+		status = tusbhMscGetLUNInfo(husbh, pdrv, &MSCLUNInfo);
+		if(status != TUSBH_E_OK)
+			psdev->_sdev_attribute |= SDEV_DEVERROR;
+		else
+			psdev->_sdev_maxsec = MSCLUNInfo.num_block;
+		if((psdev->_sdev_attribute & SDEV_DEVERROR) == 0)
+			result = f_mount(psdev->_sdev_devno, &ActiveFatFsObj);
+		if(result != FR_OK)
+			psdev->_sdev_attribute |= SDEV_DEVERROR;
+		else
+			psdev->_sdev_local[0]   = &ActiveFatFsObj;
+#if 1
+		syslog_3(LOG_NOTICE, "## attr[%04x] max(%d) result(%d) ##", psdev->_sdev_attribute, psdev->_sdev_maxsec, result);
+#endif
+		return TRUE;
+	}
+	else
+		return FALSE;
+}
+
+/*
+ *  FatFs用MSCステータス関数
+ */
+static int msc_diskstatus(void *pif)
+{
+	TUSBH_Handle_t  *husbh;
+	StorageDevice_t *psdev = pif;
+
+	if(psdev == NULL)
+		return STA_NODISK;
+	husbh = (TUSBH_Handle_t *)psdev->_sdev_local[1];
+	if((psdev->_sdev_attribute & (SDEV_EMPLOY|SDEV_NOTUSE)) != SDEV_EMPLOY || husbh == NULL)
+		return STA_NOINIT;
+	else
+		return 0;
+}
+
+/*
+ *  FatFs用MSC読み込み関数
+ */
+static int msc_diskread(void *pif, BYTE *Buffer, DWORD SectorNumber, BYTE SectorCount)
+{
+ 	StorageDevice_t   *psdev = pif;
+	USB_OTG_Handle_t  *husb;
+	TUSBH_Handle_t    *husbh;
+	TUSBH_ERCODE      status;
+	char              pdrv;
+	int               retry = 0;
+	uint8_t           *buff = NULL;
+	unsigned int      align = ((unsigned int)Buffer) & 3;
+	BYTE              *buffer = (BYTE *)Buffer;
+
+	husbh = (TUSBH_Handle_t *)psdev->_sdev_local[1];
+	husb  = (USB_OTG_Handle_t *)husbh->pSysData;
+	pdrv  = psdev->_sdev_port - MSC_PORTID;
+	if((psdev->_sdev_attribute & (SDEV_EMPLOY|SDEV_NOTUSE)) != SDEV_EMPLOY || husbh == NULL)
+		return RES_ERROR;
+	if(align != 0 && husb->Init.dma_enable == 1){
+		uint32_t *addr = malloc_cache(psdev->_sdev_secsize*SectorCount);
+		if(addr != NULL){
+			buff   = buffer;
+			buffer = (BYTE *)addr;
+		}
+	}
+	do{
+		status = tusbhMscRead(husbh, pdrv, SectorNumber, (uint8_t *)buffer, SectorCount);
+		if(status == TUSBH_E_SYS)
+			break;
+		retry++;
+	}while(status != TUSBH_E_OK && retry < RETRY_COUNT);
+	if(buff != NULL){
+		tusbmemcpy(buff, buffer, psdev->_sdev_secsize*SectorCount);
+		free_cache(buffer);
+	}
+	if(status == TUSBH_E_OK)
+		return RES_OK;
+	else if(status == TUSBH_E_SYS)
+		psdev->_sdev_attribute |= SDEV_DEVERROR;
+	return RES_ERROR;
+}
+
+/*
+ *  FatFs用MSC書き込み関数
+ */
+static int msc_diskwrite(void *pif, const BYTE *Buffer, DWORD SectorNumber, BYTE SectorCount)
+{
+ 	StorageDevice_t   *psdev = pif;
+	USB_OTG_Handle_t  *husb;
+	TUSBH_Handle_t    *husbh;
+	TUSBH_ERCODE      status;
+	char              pdrv;
+	int               retry = 0;
+	uint8_t           *buff = NULL;
+	unsigned int      align = ((unsigned int)Buffer) & 3;
+	BYTE              *buffer = (BYTE *)Buffer;
+
+	husbh = (TUSBH_Handle_t *)psdev->_sdev_local[1];
+	husb  = (USB_OTG_Handle_t *)husbh->pSysData;
+	pdrv  = psdev->_sdev_port - MSC_PORTID;
+	if((psdev->_sdev_attribute & (SDEV_EMPLOY|SDEV_NOTUSE)) != SDEV_EMPLOY || husbh == NULL)
+		return RES_ERROR;
+	if(align != 0 && husb->Init.dma_enable == 1){
+		uint32_t *addr = malloc_cache(psdev->_sdev_secsize*SectorCount);
+		if(addr != NULL){
+			buff   = (uint8_t *)buffer;
+			buffer = (BYTE *)addr;
+			tusbmemcpy(buffer, buff, psdev->_sdev_secsize*SectorCount);
+		}
+	}
+	do{
+		status = tusbhMscWrite(husbh, pdrv, SectorNumber, (uint8_t *)buffer, SectorCount);
+		if(status == TUSBH_E_SYS)
+			break;
+		retry++;
+	}while(status != TUSBH_E_OK && retry < RETRY_COUNT);
+	if(buff != NULL)
+		free_cache(buffer);
+	if(status == TUSBH_E_OK)
+		return RES_OK;
+	else if(status == TUSBH_E_SYS)
+		psdev->_sdev_attribute |= SDEV_DEVERROR;
+	return RES_ERROR;
+}
+
+
+/*
+ *  FatFs用MSC-DISKIO制御関数
+ */
+static int msc_diskioctl(void *pif, BYTE Func, void* Buffer)
+{
+	StorageDevice_t *psdev = (StorageDevice_t *)pif;
+	DRESULT         result;
+
+	if(psdev == NULL)
+		return RES_ERROR;
+	if((psdev->_sdev_attribute & (SDEV_EMPLOY|SDEV_NOTUSE)) != SDEV_EMPLOY)
+		return RES_ERROR;
+	switch(Func){
+	case CTRL_SYNC:
+		result = RES_OK;			/* no action */
+		break;
+	case GET_SECTOR_COUNT:
+		*((DWORD *)Buffer) = psdev->_sdev_maxsec;
+		syslog_2(LOG_NOTICE, "ioctl notuse (%d)(%d) ", (int)Func, psdev->_sdev_maxsec);
+		result = RES_OK;
+		break;
+	case GET_BLOCK_SIZE:
+		*((DWORD *)Buffer) = 135;	/* ERASE_BLK */
+		syslog_1(LOG_NOTICE, "call disk_ioctl(GET_BLOCK_SIZE, %08x)", (int)(*((DWORD *)Buffer)));
+		result = RES_OK;
+		break;
+	default:
+		syslog_2(LOG_NOTICE, "call disk_ioctl(%d, %08x)", (int)psdev->_sdev_devno, (int)Buffer);
+		slp_tsk();
+		result = RES_PARERR;
+		break;
+	}
+	return result;
+}
+
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/usb/mscdiskio.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/usb/mscdiskio.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/usb/mscdiskio.h	(revision 457)
@@ -0,0 +1,57 @@
+/*
+ *  TOPPERS/ASP/FMP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Advanced Standard Profile Kernel
+ * 
+ *  Copyright (C) 2012 by GT Development Center RICOH COMPANY,LTD. JAPAN
+ *  Copyright (C) 2015-2017 by TOPPERS PROJECT Educational Working Group.
+ * 
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+#ifndef _MSCDISKIO_H_
+#define _MSCDISKIO_H_
+
+#include "storagedevice.h"
+
+#define RETRY_COUNT    8
+
+#ifndef MSC_DEVNO
+#define MSC_DEVNO      0
+#endif
+#define MSC_PORTID     1
+
+extern StorageDeviceFileFunc_t fatfsSDeviceFileFunc;
+
+extern void sd_init(intptr_t exinf);
+extern void msc_init(intptr_t exinf);
+
+#endif
+
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/usb/tusb_rtos.c
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/usb/tusb_rtos.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/usb/tusb_rtos.c	(revision 457)
@@ -0,0 +1,177 @@
+/*
+ *  TOPPERS BASE PLATFORM MIDDLEWARE
+ * 
+ *  Copyright (C) 2017-2017 by TOPPERS PROJECT
+ *                             Educational Working Group.
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+/*
+ *  USB Middleware RTOS依存部
+ */
+
+#include "tusb_rtos.h"
+#include "kernel_cfg.h"
+
+
+/*
+ *  タスク状態でのメッセージ送信
+ */
+ER
+tusbSendData(ID qid, uint8_t evt, uint8_t prm1, uint8_t prm2, uint8_t prm3)
+{
+	intptr_t data;
+	ER       ercd;
+
+	data = (evt << 24) | (prm1 << 16) | (prm2 << 8) | prm3;
+	ercd = psnd_dtq(qid, data);
+	if(ercd != E_OK){
+		syslog_5(LOG_ERROR, "tusbSendData send(%d) error [%02x][%02x][%02x][%02x]", qid, evt, prm1, prm2, prm3);
+	}
+	return ercd;
+}
+
+/*
+ *  非タスク状態でのメッセージ送信
+ */
+ER
+tusbiSendData(ID qid, uint8_t evt, uint8_t prm1, uint8_t prm2, uint8_t prm3)
+{
+	intptr_t data;
+	ER       ercd;
+
+	data = (evt << 24) | (prm1 << 16) | (prm2 << 8) | prm3;
+	ercd = ipsnd_dtq(qid, data);
+	if(ercd != E_OK){
+		syslog_5(LOG_ERROR, "tusbiSendData send(%d) error [%02x][%02x][%02x][%02x]", qid, evt, prm1, prm2, prm3);
+	}
+	return ercd;
+}
+
+/*
+ *  タスク状態でのメッセージ受信
+ */
+ER
+tusbRecvData(ID qid, uint8_t *pmes, uint32_t timeout)
+{
+	intptr_t data;
+	ER       ercd;
+
+	if(timeout == 0)
+		ercd = rcv_dtq(qid, &data);
+	else
+		ercd = trcv_dtq(qid, &data, timeout);
+	if(ercd != E_OK){
+		syslog_1(LOG_ERROR, "tusbRecvData(%d) error !", qid);
+	}
+	else{
+		pmes[0] = (data >> 24) & 0xff;
+		pmes[1] = (data >> 16) & 0xff;
+		pmes[2] = (data >> 8) & 0xff;
+		pmes[3] = data & 0xff;
+	}
+	return ercd;
+}
+
+/*
+ *  タスクID取出し
+ */
+int32_t
+tusbGetTaskID(void)
+{
+	ER ercd;
+	ID tid = 0;
+
+	ercd = get_tid(&tid);
+	if(ercd != E_OK){
+		syslog_1(LOG_ERROR, "tusbhGetTaskID get fail(%d) !", ercd);
+		return 0;
+	}
+	else
+		return (int32_t)tid;
+}
+
+/*
+ *  タスク起動
+ */
+ER
+tusbStartTask(ID taskid)
+{
+	ER ercd = act_tsk(taskid);
+
+	if(ercd != E_OK)
+		syslog_2(LOG_ERROR, "tusbStartTask actvate error id(%d) error(%d) !", taskid, ercd);
+	return ercd;
+}
+
+/*
+ *  タイマー制御
+ */
+ER
+tusbTimerControl(uint8_t activate)
+{
+	ER ercd;
+
+	if(activate == 0)
+		ercd = stp_cyc(TUSBH_CYC_HDR);
+	else
+		ercd = sta_cyc(TUSBH_CYC_HDR);
+	return ercd;
+}
+
+/*
+ *  ローカルなmemset関数
+ */
+void
+tusbmemset(void *d, const char val, int len)
+{
+	char *dd = d;
+	int i;
+	for(i = 0 ; i < len ; i++){
+		*dd++ = val;
+	}
+}
+
+/*
+ *  ローカルなmemcpy関数
+ */
+void
+tusbmemcpy(void *d, void *s, int len)
+{
+	uint8_t *dd = d;
+	uint8_t *ss = s;
+	int i;
+	for(i = 0 ; i < len ; i++){
+		*dd++ = *ss++;
+	}
+}
+
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/usb/tusb_rtos.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/usb/tusb_rtos.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/usb/tusb_rtos.h	(revision 457)
@@ -0,0 +1,96 @@
+/*
+ *  TOPPERS BASE PLATFORM MIDDLEWARE
+ * 
+ *  Copyright (C) 2017-2017 by TOPPERS PROJECT
+ *                             Educational Working Group.
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+/*
+ *  USB Middleware RTOS依存部定義
+ */
+
+#ifndef _TUSB_RTOS_H_
+#define _TUSB_RTOS_H_
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <kernel.h>
+#include <t_syslog.h>
+#include <t_stdlib.h>
+#include <sil.h>
+#include <target_syssvc.h>
+#include "syssvc/serial.h"
+#include "syssvc/syslog.h"
+#include "t_syslog.h"
+#include "device.h"
+
+#ifdef CACHE_LINE_SIZE
+#define USB_DATA_ALIGN      CACHE_LINE_SIZE
+#else
+#define USB_DATA_ALIGN      4
+#endif
+
+#define TUSB_PROCESS_PRIO       6
+#define TUSB_PROCESS_STACK_SIZE 4096
+#define TUSB_HANDLE_STACK_SIZE  1024
+
+/*
+ *  SYSSVCメモリ管理関数
+ */
+extern void *malloc_cache(uint32_t len);
+extern void free_cache(void *addr);
+
+
+extern ER tusbSendData(ID qid, uint8_t evt, uint8_t prm1, uint8_t prm2, uint8_t prm3);
+extern ER tusbiSendData(ID qid, uint8_t evt, uint8_t prm1, uint8_t prm2, uint8_t prm3);
+extern ER tusbRecvData(ID qid, uint8_t *pmes, uint32_t timeout);
+extern ER tusbStartTask(ID taskid);
+extern int32_t tusbGetTaskID(void);
+extern ER tusbTimerControl(uint8_t activate);
+
+#define tusbmalloc          malloc_cache
+#define tusbfree            free_cache
+extern void tusbmemset(void *d, const char val, int len);
+extern void tusbmemcpy(void *d, void *s, int len);
+
+#define tusbCpuLock         loc_cpu
+#define tusbCpuUnLock       unl_cpu
+#define tusbDelay(t)        dly_tsk((t))
+#define tusbSleep(t)        tslp_tsk((t))
+#define tusbWakeup(id)      wup_tsk((id))
+
+
+#endif /* _TUSB_RTOS_H_ */
+
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/usb/tusb_types.h
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/usb/tusb_types.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/usb/tusb_types.h	(revision 457)
@@ -0,0 +1,255 @@
+/*
+ *  TOPPERS BASE PLATFORM MIDDLEWARE
+ * 
+ *  Copyright (C) 2017-2018 by TOPPERS PROJECT
+ *                             Educational Working Group.
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+/* mbed USBHost Library
+ * Copyright (c) 2006-2013 ARM Limited
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ *  USB Host/Device Middleware 型外部宣言
+ */
+
+#ifndef _TUSB_TYPES_H_
+#define _TUSB_TYPES_H_
+
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* Control RequestType Fields */
+#define USB_DEVICE_TO_HOST         0x80
+#define USB_HOST_TO_DEVICE         0x00
+#define USB_REQUEST_DIR_MASK       USB_DEVICE_TO_HOST
+#define USB_REQUEST_TYPE_VENDOR    0x40
+#define USB_REQUEST_TYPE_CLASS     0x20
+#define USB_REQUEST_TYPE_STANDARD  0x00
+#define USB_RECIPIENT_OTHER        0x03
+#define USB_RECIPIENT_ENDPOINT     0x02
+#define USB_RECIPIENT_INTERFACE    0x01
+#define USB_RECIPIENT_DEVICE       0x00
+
+/* USB Standard Requests */
+#define GET_STATUS                 0x00
+#define CLEAR_FEATURE              0x01
+#define SET_FEATURE                0x03
+#define SET_ADDRESS                0x05
+#define GET_DESCRIPTOR             0x06
+#define SET_DESCRIPTOR             0x07
+#define GET_CONFIGURATION          0x08
+#define SET_CONFIGURATION          0x09
+#define GET_INTERFACE              0x0A
+#define SET_INTERFACE              0x0B
+
+/* Descriptor Types of USB Specifications */
+#define DEVICE_DESCRIPTOR              (1)
+#define CONFIGURATION_DESCRIPTOR       (2)
+#define STRING_DESCRIPTOR              (3)
+#define INTERFACE_DESCRIPTOR           (4)
+#define ENDPOINT_DESCRIPTOR            (5)
+#define DEVICE_QUALIFIER_DESCRIPTOR    (6)
+#define OTHER_SPEED_CONFIGURATION_DESC (7)
+#define BOS_DESCRIPTOR                 (15)
+#define HID_DESCRIPTOR                 (33)
+#define HID_REPORT_DESCRIPTOR          (34)
+
+#define SET_CONFIGURATION_TYPE 	   (USB_HOST_TO_DEVICE | USB_RECIPIENT_DEVICE | USB_REQUEST_TYPE_STANDARD)
+#define SET_ADDRESS_TYPE           (USB_HOST_TO_DEVICE | USB_RECIPIENT_DEVICE | USB_REQUEST_TYPE_STANDARD)
+#define SET_INTERFACE_TYPE         (USB_HOST_TO_DEVICE | USB_RECIPIENT_INTERFACE | USB_REQUEST_TYPE_STANDARD)
+#define CLEAR_FEATURE_TYPE         (USB_HOST_TO_DEVICE | USB_RECIPIENT_ENDPOINT | USB_REQUEST_TYPE_STANDARD)
+
+/* USB Descriptor Length */
+#define DEVICE_DESCRIPTOR_LENGTH        0x12
+#define CONFIGURATION_DESCRIPTOR_LENGTH 0x09
+#define INTERFACE_DESCRIPTOR_LENGTH     0x09
+#define ENDPOINT_DESCRIPTOR_LENGTH      0x07
+#define HID_DESCRIPTOR_LENGTH           0x09
+
+
+#define USB_EP_TYPE_CTRL           0x00
+#define USB_EP_TYPE_ISOC           0x01
+#define USB_EP_TYPE_BULK           0x02
+#define USB_EP_TYPE_INTR           0x03
+
+#define USB_PID_SETUP              0
+#define USB_PID_DATA               1
+
+/* Class code */
+#define AUDIO_CLASS                0x01
+#define CDC_CLASS                  0x02
+#define HID_CLASS                  0x03
+#define PRT_CLASS                  0x07
+#define MSC_CLASS                  0x08
+#define HUB_CLASS                  0x09
+#define DATA_INTERFACE_CLASS       0x0A
+#define BLUETOOTH_CLASS            0xE0
+
+/* usb speed */
+#define USB_DEVICE_SPEED_HIGH      0
+#define USB_DEVICE_SPEED_FULL      1
+#define USB_DEVICE_SPEED_LOW       2
+
+
+#define SETUP_PKT_LENGTH           8
+
+#define MAX_DEVICE_CONNECTED       4
+#ifndef MAX_EPS_PIPES
+#define MAX_EPS_PIPES              32
+#endif
+
+#define TUSBH_MAX_ERROR_COUNT      2
+#define TUSBH_STR_LENGTH           64
+
+typedef struct {
+    uint8_t   bLength;
+    uint8_t   bDescriptorType;
+    uint16_t  bcdUSB;
+    uint8_t   bDeviceClass;
+    uint8_t   bDeviceSubClass; 
+    uint8_t   bDeviceProtocol;
+    uint8_t   bMaxPacketSize;
+    uint16_t  idVendor;
+    uint16_t  idProduct;
+    uint16_t  bcdDevice;
+    uint8_t   iManufacturer;
+    uint8_t   iProduct;
+    uint8_t   iSerialNumber;
+    uint8_t   bNumConfigurations;
+} DeviceDescriptor;
+
+typedef struct {
+    uint8_t   bLength;
+    uint8_t   bDescriptorType;
+    uint16_t  wTotalLength;
+    uint8_t   bNumInterfaces;
+    uint8_t   bConfigurationValue;
+    uint8_t   iConfiguration;
+    uint8_t   bmAttributes;
+    uint8_t   bMaxPower;
+} ConfigurationDescriptor;
+
+typedef struct {
+	uint8_t   bLength;
+	uint8_t   bDescriptorType;
+	uint8_t   bInterfaceNumber;
+	uint8_t   bAlternateSetting;
+	uint8_t   bNumEndpoints;
+	uint8_t   bInterfaceClass;
+	uint8_t   bInterfaceSubClass;
+	uint8_t   bInterfaceProtocol;
+	uint8_t   iInterface;
+} InterfaceDescriptor;
+
+typedef struct {
+    uint8_t   bLength;
+    uint8_t   bDescriptorType;
+    uint8_t   bEndpointAddress;
+    uint8_t   bmAttributes;
+    uint16_t  wMaxPacketSize;
+    uint8_t   bInterval;
+} EndpointDescriptor;
+
+typedef struct {
+	uint8_t   bDescLength;
+	uint8_t   bDescriptorType;
+	uint8_t   bNbrPorts;
+	uint8_t   wHubCharacteristics[2];
+	uint8_t   bPwrOn2PwrGood;
+	uint8_t   bHubContrCurrent;
+	uint8_t   DeviceRemovable;
+	uint8_t   PortPweCtrlMak;
+} HubDescriptor;
+
+typedef struct {
+	uint8_t   bmRequest;
+	uint8_t   bRequest;
+	uint16_t  wValue;
+	uint16_t  wIndex;
+	uint16_t  wLength;
+} UsbSetupRequest;
+
+typedef struct {
+    uint32_t  baudrate;
+    uint8_t   stop_bits;	/* 0-1 Stop bit 1-1.5 Stop bits 2-2 Stop bits */
+    uint8_t   parity;		/* 0:None 1:Odd 2:Even 3:Mark 4:Space */
+    uint8_t   data_bits;
+} Line_Coding_t;
+
+
+/*
+ *  TUSBH ERROR CODE型
+ */
+typedef enum {
+	TUSBH_E_OK = 0,
+	TUSBH_E_BUSY,
+	TUSBH_E_BUSY_URB,
+	TUSBH_E_PAR,
+	TUSBH_E_OBJ,
+	TUSBH_E_ERR,
+	TUSBH_E_URB,
+	TUSBH_E_RTOS,
+	TUSBH_E_NOSPT,
+	TUSBH_E_TMOUT,
+	TUSBH_E_SYS,
+} TUSBH_ERCODE;
+
+/*
+ *  TUSBD ERROR CODE型
+ */
+typedef enum {
+	TUSBD_E_OK = 0,
+	TUSBD_E_BUSY,
+	TUSBD_E_ERR
+} TUSBD_ERCODE;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif	/* _TUSB_TYPES_H_ */
+
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/utils/applyrename
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/utils/applyrename	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/utils/applyrename	(revision 457)
@@ -0,0 +1,134 @@
+#! /usr/bin/perl
+#
+#  TOPPERS Software
+#      Toyohashi Open Platform for Embedded Real-Time Systems
+# 
+#  Copyright (C) 2003 by Embedded and Real-Time Systems Laboratory
+#                              Toyohashi Univ. of Technology, JAPAN
+#  Copyright (C) 2004-2011 by Embedded and Real-Time Systems Laboratory
+#              Graduate School of Information Science, Nagoya Univ., JAPAN
+# 
+#  ä¸è¨èä½æ¨©è
+ã¯ï¼ä»¥ä¸ã®(1)ï½(4)ã®æ¡ä»¶ãæºããå ´åã«éãï¼æ¬ã½ããã¦ã§
+#  ã¢ï¼æ¬ã½ããã¦ã§ã¢ãæ¹å¤ãããã®ãå«ãï¼ä»¥ä¸åãï¼ãä½¿ç¨ã»è¤è£½ã»æ¹
+#  å¤ã»åé
+å¸ï¼ä»¥ä¸ï¼å©ç¨ã¨å¼ã¶ï¼ãããã¨ãç¡åã§è¨±è«¾ããï¼
+#  (1) æ¬ã½ããã¦ã§ã¢ãã½ã¼ã¹ã³ã¼ãã®å½¢ã§å©ç¨ããå ´åã«ã¯ï¼ä¸è¨ã®èä½
+#      æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨ã®ç¡ä¿è¨¼è¦å®ãï¼ãã®ã¾ã¾ã®å½¢ã§ã½ã¼
+#      ã¹ã³ã¼ãä¸­ã«å«ã¾ãã¦ãããã¨ï¼
+#  (2) æ¬ã½ããã¦ã§ã¢ãï¼ã©ã¤ãã©ãªå½¢å¼ãªã©ï¼ä»ã®ã½ããã¦ã§ã¢éçºã«ä½¿
+#      ç¨ã§ããå½¢ã§åé
+å¸ããå ´åã«ã¯ï¼åé
+å¸ã«ä¼´ããã­ã¥ã¡ã³ãï¼å©ç¨
+#      è
+ããã¥ã¢ã«ãªã©ï¼ã«ï¼ä¸è¨ã®èä½æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨
+#      ã®ç¡ä¿è¨¼è¦å®ãæ²è¼ãããã¨ï¼
+#  (3) æ¬ã½ããã¦ã§ã¢ãï¼æ©å¨ã«çµã¿è¾¼ããªã©ï¼ä»ã®ã½ããã¦ã§ã¢éçºã«ä½¿
+#      ç¨ã§ããªãå½¢ã§åé
+å¸ããå ´åã«ã¯ï¼æ¬¡ã®ããããã®æ¡ä»¶ãæºããã
+#      ã¨ï¼
+#    (a) åé
+å¸ã«ä¼´ããã­ã¥ã¡ã³ãï¼å©ç¨è
+ããã¥ã¢ã«ãªã©ï¼ã«ï¼ä¸è¨ã®è
+#        ä½æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨ã®ç¡ä¿è¨¼è¦å®ãæ²è¼ãããã¨ï¼
+#    (b) åé
+å¸ã®å½¢æ
+ãï¼å¥ã«å®ããæ¹æ³ã«ãã£ã¦ï¼TOPPERSãã­ã¸ã§ã¯ãã«
+#        å ±åãããã¨ï¼
+#  (4) æ¬ã½ããã¦ã§ã¢ã®å©ç¨ã«ããç´æ¥çã¾ãã¯éæ¥çã«çãããããªãæ
+#      å®³ãããï¼ä¸è¨èä½æ¨©è
+ããã³TOPPERSãã­ã¸ã§ã¯ããå
+è²¬ãããã¨ï¼
+#      ã¾ãï¼æ¬ã½ããã¦ã§ã¢ã®ã¦ã¼ã¶ã¾ãã¯ã¨ã³ãã¦ã¼ã¶ããã®ãããªãç
+#      ç±ã«åºã¥ãè«æ±ãããï¼ä¸è¨èä½æ¨©è
+ããã³TOPPERSãã­ã¸ã§ã¯ãã
+#      å
+è²¬ãããã¨ï¼
+# 
+#  æ¬ã½ããã¦ã§ã¢ã¯ï¼ç¡ä¿è¨¼ã§æä¾ããã¦ãããã®ã§ããï¼ä¸è¨èä½æ¨©è
+ã
+#  ãã³TOPPERSãã­ã¸ã§ã¯ãã¯ï¼æ¬ã½ããã¦ã§ã¢ã«é¢ãã¦ï¼ç¹å®ã®ä½¿ç¨ç®ç
+#  ã«å¯¾ããé©åæ§ãå«ãã¦ï¼ãããªãä¿è¨¼ãè¡ããªãï¼ã¾ãï¼æ¬ã½ããã¦ã§
+#  ã¢ã®å©ç¨ã«ããç´æ¥çã¾ãã¯éæ¥çã«çãããããªãæå®³ã«é¢ãã¦ãï¼ã
+#  ã®è²¬ä»»ãè² ããªãï¼
+# 
+#  @(#) $Id$
+# 
+
+#
+#  ãã¡ã¤ã«ã«ãªãã¼ã ãé©ç¨ãã
+#
+sub applyrename
+{
+	local($infile) = @_;
+	local($outfile) = $infile.".new";
+	local($line);
+
+	open(INFILE, "< ".$infile) || die;
+	open(OUTFILE, "> ".$outfile) || die;
+
+	while ($line = <INFILE>) {
+		$line =~ s/\b(_?)($syms)\b/$1_kernel_$2/gc;
+		print OUTFILE $line;
+	}
+
+	close(INFILE);
+	close(OUTFILE);
+
+	if (`cmp $infile $outfile`) {
+		rename($infile, $infile.".bak");
+		rename($outfile, $infile);
+		print STDERR "Modified: ",$infile,"\n";
+	}
+	else {
+		unlink($outfile);
+	}
+}
+
+#
+#  ã¨ã©ã¼ãã§ãã¯
+#
+if ($#ARGV < 1) {
+	die "Usage: appyrename <prefix> <filelist>\n";
+}
+
+#
+#  åæå
+#
+@syms = ();
+$name = $ARGV[0];
+
+#
+#  ã·ã³ãã«ãªã¹ããèª­ã¿è¾¼ã
+#
+$deffile = $name."_rename.def";
+open(INFILE, $deffile) || die "Cannot open $deffile";
+while ($line = <INFILE>) {
+	chomp $line;
+	if ($line =~ /^#(.*)$/) {
+		# do nothing
+	}
+	elsif ($line =~ /^INCLUDE[ \t]+(.*)$/) {
+		# do nothing
+	}
+	elsif ($line ne "") {
+		@syms = (@syms, $line)
+	}
+}
+close(INFILE);
+
+#
+#  æ­£è¦è¡¨ç¾ãä½ã
+#
+$syms = join("|", @syms);
+
+#
+#  ãã¡ã¤ã«ã«ãªãã¼ã ãé©ç¨ãã
+#
+shift @ARGV;
+foreach $infile (@ARGV) {
+	# ãã¡ã¤ã«ã§ãªããã°ã¹ã­ãã
+	next unless (-f $infile);
+
+	applyrename($infile) if ($infile ne $deffile);
+}
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/utils/genoffset
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/utils/genoffset	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/utils/genoffset	(revision 457)
@@ -0,0 +1,287 @@
+#! /usr/bin/perl
+#
+#  TOPPERS Software
+#      Toyohashi Open Platform for Embedded Real-Time Systems
+# 
+#  Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
+#                              Toyohashi Univ. of Technology, JAPAN
+#  Copyright (C) 2004-2011 by Embedded and Real-Time Systems Laboratory
+#              Graduate School of Information Science, Nagoya Univ., JAPAN
+# 
+#  ä¸è¨èä½æ¨©è
+ã¯ï¼ä»¥ä¸ã®(1)ï½(4)ã®æ¡ä»¶ãæºããå ´åã«éãï¼æ¬ã½ããã¦ã§
+#  ã¢ï¼æ¬ã½ããã¦ã§ã¢ãæ¹å¤ãããã®ãå«ãï¼ä»¥ä¸åãï¼ãä½¿ç¨ã»è¤è£½ã»æ¹
+#  å¤ã»åé
+å¸ï¼ä»¥ä¸ï¼å©ç¨ã¨å¼ã¶ï¼ãããã¨ãç¡åã§è¨±è«¾ããï¼
+#  (1) æ¬ã½ããã¦ã§ã¢ãã½ã¼ã¹ã³ã¼ãã®å½¢ã§å©ç¨ããå ´åã«ã¯ï¼ä¸è¨ã®èä½
+#      æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨ã®ç¡ä¿è¨¼è¦å®ãï¼ãã®ã¾ã¾ã®å½¢ã§ã½ã¼
+#      ã¹ã³ã¼ãä¸­ã«å«ã¾ãã¦ãããã¨ï¼
+#  (2) æ¬ã½ããã¦ã§ã¢ãï¼ã©ã¤ãã©ãªå½¢å¼ãªã©ï¼ä»ã®ã½ããã¦ã§ã¢éçºã«ä½¿
+#      ç¨ã§ããå½¢ã§åé
+å¸ããå ´åã«ã¯ï¼åé
+å¸ã«ä¼´ããã­ã¥ã¡ã³ãï¼å©ç¨
+#      è
+ããã¥ã¢ã«ãªã©ï¼ã«ï¼ä¸è¨ã®èä½æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨
+#      ã®ç¡ä¿è¨¼è¦å®ãæ²è¼ãããã¨ï¼
+#  (3) æ¬ã½ããã¦ã§ã¢ãï¼æ©å¨ã«çµã¿è¾¼ããªã©ï¼ä»ã®ã½ããã¦ã§ã¢éçºã«ä½¿
+#      ç¨ã§ããªãå½¢ã§åé
+å¸ããå ´åã«ã¯ï¼æ¬¡ã®ããããã®æ¡ä»¶ãæºããã
+#      ã¨ï¼
+#    (a) åé
+å¸ã«ä¼´ããã­ã¥ã¡ã³ãï¼å©ç¨è
+ããã¥ã¢ã«ãªã©ï¼ã«ï¼ä¸è¨ã®è
+#        ä½æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨ã®ç¡ä¿è¨¼è¦å®ãæ²è¼ãããã¨ï¼
+#    (b) åé
+å¸ã®å½¢æ
+ãï¼å¥ã«å®ããæ¹æ³ã«ãã£ã¦ï¼TOPPERSãã­ã¸ã§ã¯ãã«
+#        å ±åãããã¨ï¼
+#  (4) æ¬ã½ããã¦ã§ã¢ã®å©ç¨ã«ããç´æ¥çã¾ãã¯éæ¥çã«çãããããªãæ
+#      å®³ãããï¼ä¸è¨èä½æ¨©è
+ããã³TOPPERSãã­ã¸ã§ã¯ããå
+è²¬ãããã¨ï¼
+#      ã¾ãï¼æ¬ã½ããã¦ã§ã¢ã®ã¦ã¼ã¶ã¾ãã¯ã¨ã³ãã¦ã¼ã¶ããã®ãããªãç
+#      ç±ã«åºã¥ãè«æ±ãããï¼ä¸è¨èä½æ¨©è
+ããã³TOPPERSãã­ã¸ã§ã¯ãã
+#      å
+è²¬ãããã¨ï¼
+# 
+#  æ¬ã½ããã¦ã§ã¢ã¯ï¼ç¡ä¿è¨¼ã§æä¾ããã¦ãããã®ã§ããï¼ä¸è¨èä½æ¨©è
+ã
+#  ãã³TOPPERSãã­ã¸ã§ã¯ãã¯ï¼æ¬ã½ããã¦ã§ã¢ã«é¢ãã¦ï¼ç¹å®ã®ä½¿ç¨ç®ç
+#  ã«å¯¾ããé©åæ§ãå«ãã¦ï¼ãããªãä¿è¨¼ãè¡ããªãï¼ã¾ãï¼æ¬ã½ããã¦ã§
+#  ã¢ã®å©ç¨ã«ããç´æ¥çã¾ãã¯éæ¥çã«çãããããªãæå®³ã«é¢ãã¦ãï¼ã
+#  ã®è²¬ä»»ãè² ããªãï¼
+# 
+#  @(#) $Id$
+# 
+
+#
+#  åæå
+#
+$infile = $ARGV[0];
+$sil_endian = "";
+
+#
+#  è§£éã§ãããã£ã¬ã¯ãã£ãã®ãã¼ãã«
+#
+%directives = (
+	"long", "",
+	"dword", "",
+	"word", "",
+	"hword", "",
+	"int", "",
+	"short", "",
+	"half", "",
+	"byte", "",
+	"value", "",
+	"uaword", "",
+	"uashort", "",
+	"data32", 4,
+	"data16", 2,
+	"data8", 1,
+	"zero", -1,
+	"space", -1,
+	"globl", 0,
+	"global", 0,
+	"align", 0,
+	"p2align", 0,
+	"even", 0,
+	"data", 0,
+	"stabs", 0,
+	"type", 0,
+	"size", 0,
+	"section", 0,
+	"sdata", 0,
+	"code", 0,
+);
+
+#
+#  ãªãã»ããå¤ã®åºå
+#
+sub parse_offset {
+	my($label, $val) = @_;
+
+	printf "#define %s\t%d\n",$label,$val;
+}
+
+#
+#  ãã£ã¬ã¯ãã£ãã®èª­ã¿åã
+#
+sub ref_bit {
+	my($size) = @_;
+	my($dir, $directive);
+
+	while ($line = <INFILE>) {
+		chomp $line;
+		next if ($line =~ /^[ \t]*[#;].*$/);
+
+		if ($line =~ /[ \t]*\.([a-zA-Z0-9]+)[ \t]*([^ \t]*)[ \t]*/
+						&& defined($dir = $directives{$1})) {
+			$directive = $1;
+			if ($dir eq "") {
+				# ç»é²ãã¹ããã£ã¬ã¯ãã£ã
+				$directives{$directive} = $size;
+			}
+			last;
+		}
+		else {
+			# è§£æã§ããªãè¡
+			print STDERR "genoffset: cannot parse: $line\n";
+			$error = 1;
+		}
+	}
+}
+
+#
+#  ããããµã¼ã
+#
+sub search_bit {
+	my($val) = @_;
+	my($val_bit);
+
+	return(-1) if ($val == 0);
+
+	$val_bit = 0;
+	while (($val & 1) == 0) {
+		$val >>= 1;
+		$val_bit++;
+	}
+	return($val_bit);
+}
+
+#
+#  ãããä½ç½®ã®åºå
+#
+sub parse_bit {
+	my($endian, $size, $label) = @_;
+	my($offset, $dir, $val, $val_bit);
+
+	if ($sil_endian && $endian ne $sil_endian) {
+		# ã¨ã³ãã£ã¢ã³ã®ä¸ä¸è´
+		print STDERR "genoffset: endian mismatch: $line\n";
+		$error = 1;
+	}
+
+	$offset = 0;
+	while ($line = <INFILE>) {
+		chomp $line;
+		next if ($line =~ /^[ \t]*[#;].*$/);
+
+		if ($line =~ /[ \t]*\.([a-zA-Z0-9]+)[ \t]*([^ \t]*)[ \t]*/
+						&& defined($dir = $directives{$1})) {
+			$val = $2;
+
+			# 16é²æ°ã¨8é²æ°ã®æ°å¤ã¸ã®å¤æå¦ç
+			if ($val =~ /^0x(.+)$/) {
+				$val = hex($1);
+			}
+			elsif ($val =~ /^0(.+)$/) {
+				$val = oct($1);
+			}
+
+			if ($dir eq "") {
+				# ãµã¤ãºãç¥ããªããã£ã¬ã¯ãã£ã
+				print STDERR "genoffset: unknown directive: $line\n";
+				$error = 1;
+			}
+			elsif ($dir == 0) {
+				# èª­ã¿é£ã°ãã¹ããã£ã¬ã¯ãã£ã
+			}
+			elsif ($dir == -1) {
+				# .zeroãã£ã¬ã¯ãã£ãã®å¦ç
+				$offset += $val;
+			}
+			elsif ($val == 0) {
+				# å¤ã0ã®ãã£ã¼ã«ãã®å¦ç
+				$offset += $dir;
+			}
+			else {
+				# å¤ã0ã§ãªããã£ã¼ã«ããè¦ã¤ããã°ã«ã¼ããçµäº
+				last;
+			}
+		}
+		else {
+			# è§£æã§ããªãè¡
+			print STDERR "genoffset: cannot parse: $line\n";
+			$error = 1;
+		}
+	}
+
+	# ãããä½ç½®ãæ¢ã
+	$val_bit = search_bit($val);
+
+	# ãã¤ãåä½ã«æç®ãã
+	if ($endian eq "B") {
+		$offset += $dir - 1;
+		$offset -= $val_bit >> 3;
+	}
+	else {
+		$offset += $val_bit >> 3;
+	}
+	$val_bit &= 0x07;
+
+	# åºååä½ã«æç®ãã
+	if ($size eq "W") {
+		if ($endian eq "B") {
+			$val_bit += 24;
+			$val_bit -= ($offset & 0x03) << 3;
+		}
+		else {
+			$val_bit += ($offset & 0x03) << 3;
+		}
+		$offset &= ~0x03;
+	}
+	elsif ($size eq "H") {
+		if ($endian eq "B") {
+			$val_bit += 8;
+			$val_bit -= ($offset & 0x01) << 3;
+		}
+		else {
+			$val_bit += ($offset & 0x01) << 3;
+		}
+		$offset &= ~0x01;
+	}
+
+	# å®ç¾©ã®åºå
+	$label =~ s/^_//;
+	printf "#define %s\t%d\n",$label,$offset;
+	printf "#define %s_bit\t%d\n",$label,$val_bit;
+	printf "#define %s_mask\t0x%x\n",$label,(1 << $val_bit);
+}
+
+#
+#  ã¡ã¤ã³ã«ã¼ãã³
+#
+print "/* This file is generated by genoffset. */\n";
+print "\n";
+
+$error = 0;
+open(INFILE, $infile) || die "Cannot open $infile";
+while ($line = <INFILE>) {
+	chomp $line;
+
+	if ($line =~ /^[ \t]*OFFSET_DEF ([^ \t]+) = [#\$]?([^ \t]+)/) {
+		parse_offset($1, $2);
+	}
+	elsif ($line =~ /^[ \t]*_?BIT_REF_([0-9]+):/) {
+		ref_bit($1);
+	}
+	elsif ($line =~ /^[ \t]*SIL_ENDIAN = ([BL])/) {
+		$sil_endian = $1;
+	}
+}
+#
+#  ã³ã³ãã¤ã©ãã°ã­ã¼ãã«å¤æ°ã®é
+ç½®é åºãå¤æ´ããã¨ï¼BIT_REF_?ãä¸ã«ãª
+#  ãå¯è½æ§ãããããï¼é ­ããèª­ã¿ç´ãï¼
+#
+seek(INFILE, 0, SEEK_SET);
+while ($line = <INFILE>) {
+	chomp $line;
+
+	if ($line =~ /^[ \t]*_?BIT_([BL])([BHW])_([^ \t]+):/) {
+		parse_bit($1, $2, $3);
+	}
+}
+close(INFILE);
+exit($error);
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/utils/genrename
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/utils/genrename	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/utils/genrename	(revision 457)
@@ -0,0 +1,265 @@
+#! /usr/bin/perl
+#
+#  TOPPERS Software
+#      Toyohashi Open Platform for Embedded Real-Time Systems
+# 
+#  Copyright (C) 2003 by Embedded and Real-Time Systems Laboratory
+#                              Toyohashi Univ. of Technology, JAPAN
+#  Copyright (C) 2005-2011 by Embedded and Real-Time Systems Laboratory
+#              Graduate School of Information Science, Nagoya Univ., JAPAN
+# 
+#  ä¸è¨èä½æ¨©è
+ã¯ï¼ä»¥ä¸ã®(1)ï½(4)ã®æ¡ä»¶ãæºããå ´åã«éãï¼æ¬ã½ããã¦ã§
+#  ã¢ï¼æ¬ã½ããã¦ã§ã¢ãæ¹å¤ãããã®ãå«ãï¼ä»¥ä¸åãï¼ãä½¿ç¨ã»è¤è£½ã»æ¹
+#  å¤ã»åé
+å¸ï¼ä»¥ä¸ï¼å©ç¨ã¨å¼ã¶ï¼ãããã¨ãç¡åã§è¨±è«¾ããï¼
+#  (1) æ¬ã½ããã¦ã§ã¢ãã½ã¼ã¹ã³ã¼ãã®å½¢ã§å©ç¨ããå ´åã«ã¯ï¼ä¸è¨ã®èä½
+#      æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨ã®ç¡ä¿è¨¼è¦å®ãï¼ãã®ã¾ã¾ã®å½¢ã§ã½ã¼
+#      ã¹ã³ã¼ãä¸­ã«å«ã¾ãã¦ãããã¨ï¼
+#  (2) æ¬ã½ããã¦ã§ã¢ãï¼ã©ã¤ãã©ãªå½¢å¼ãªã©ï¼ä»ã®ã½ããã¦ã§ã¢éçºã«ä½¿
+#      ç¨ã§ããå½¢ã§åé
+å¸ããå ´åã«ã¯ï¼åé
+å¸ã«ä¼´ããã­ã¥ã¡ã³ãï¼å©ç¨
+#      è
+ããã¥ã¢ã«ãªã©ï¼ã«ï¼ä¸è¨ã®èä½æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨
+#      ã®ç¡ä¿è¨¼è¦å®ãæ²è¼ãããã¨ï¼
+#  (3) æ¬ã½ããã¦ã§ã¢ãï¼æ©å¨ã«çµã¿è¾¼ããªã©ï¼ä»ã®ã½ããã¦ã§ã¢éçºã«ä½¿
+#      ç¨ã§ããªãå½¢ã§åé
+å¸ããå ´åã«ã¯ï¼æ¬¡ã®ããããã®æ¡ä»¶ãæºããã
+#      ã¨ï¼
+#    (a) åé
+å¸ã«ä¼´ããã­ã¥ã¡ã³ãï¼å©ç¨è
+ããã¥ã¢ã«ãªã©ï¼ã«ï¼ä¸è¨ã®è
+#        ä½æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨ã®ç¡ä¿è¨¼è¦å®ãæ²è¼ãããã¨ï¼
+#    (b) åé
+å¸ã®å½¢æ
+ãï¼å¥ã«å®ããæ¹æ³ã«ãã£ã¦ï¼TOPPERSãã­ã¸ã§ã¯ãã«
+#        å ±åãããã¨ï¼
+#  (4) æ¬ã½ããã¦ã§ã¢ã®å©ç¨ã«ããç´æ¥çã¾ãã¯éæ¥çã«çãããããªãæ
+#      å®³ãããï¼ä¸è¨èä½æ¨©è
+ããã³TOPPERSãã­ã¸ã§ã¯ããå
+è²¬ãããã¨ï¼
+#      ã¾ãï¼æ¬ã½ããã¦ã§ã¢ã®ã¦ã¼ã¶ã¾ãã¯ã¨ã³ãã¦ã¼ã¶ããã®ãããªãç
+#      ç±ã«åºã¥ãè«æ±ãããï¼ä¸è¨èä½æ¨©è
+ããã³TOPPERSãã­ã¸ã§ã¯ãã
+#      å
+è²¬ãããã¨ï¼
+# 
+#  æ¬ã½ããã¦ã§ã¢ã¯ï¼ç¡ä¿è¨¼ã§æä¾ããã¦ãããã®ã§ããï¼ä¸è¨èä½æ¨©è
+ã
+#  ãã³TOPPERSãã­ã¸ã§ã¯ãã¯ï¼æ¬ã½ããã¦ã§ã¢ã«é¢ãã¦ï¼ç¹å®ã®ä½¿ç¨ç®ç
+#  ã«å¯¾ããé©åæ§ãå«ãã¦ï¼ãããªãä¿è¨¼ãè¡ããªãï¼ã¾ãï¼æ¬ã½ããã¦ã§
+#  ã¢ã®å©ç¨ã«ããç´æ¥çã¾ãã¯éæ¥çã«çãããããªãæå®³ã«é¢ãã¦ãï¼ã
+#  ã®è²¬ä»»ãè² ããªãï¼
+# 
+#  @(#) $Id$
+# 
+
+#
+#  å
+é ­ã«ã¤ããæå­å
+#
+sub prefix_string {
+	local($sym) = @_;
+
+	if ($sym =~ /[a-z]/) {
+		return("_kernel_");
+	}
+	else {
+		return("_KERNEL_");
+	}
+}
+
+#
+#  ãªãã¼ã å®ç¾©ãçæãã
+#
+sub generate_define
+{
+	local($sym, $prefix) = @_;
+
+	print FILE "#define ",$prefix,$sym;
+	print FILE "\t" if (length($prefix.$sym) < 4);
+	print FILE "\t" if (length($prefix.$sym) < 8);
+	print FILE "\t" if (length($prefix.$sym) < 12);
+	print FILE "\t" if (length($prefix.$sym) < 16);
+	print FILE "\t" if (length($prefix.$sym) < 20);
+	print FILE "\t" if (length($prefix.$sym) < 24);
+	print FILE "\t",$prefix,prefix_string($sym),$sym,"\n";
+}
+
+#
+#  ãªãã¼ã è§£é¤ãçæãã
+#
+sub generate_undef
+{
+	local($sym, $prefix) = @_;
+
+	print FILE "#undef ",$prefix,$sym,"\n";
+}
+
+#
+#  ã¤ã³ã¯ã«ã¼ããã£ã¬ã¯ãã£ããçæãã
+#
+sub generate_include
+{
+	local($file, $prefix) = @_;
+
+	$file =~ s/([>"])$/_$prefix.h$1/;
+	$includes .= "#include ".$file."\n";
+}
+
+#
+#  ã¨ã©ã¼ãã§ãã¯
+#
+if ($#ARGV != 0) {
+	die "Usage: genrename <prefix>\n";
+}
+
+#
+#  åæå
+#
+@syms = ();
+$name = $ARGV[0];
+$NAME = $name; $NAME =~ y/a-z/A-Z/;
+
+$infile = $name."_rename.def";
+$header_defsym = "TOPPERS_".$NAME."_RENAME_H";
+
+#
+#  ã·ã³ãã«ãªã¹ããèª­ã¿è¾¼ã
+#
+open(INFILE, $infile) || die "Cannot open $infile";
+while ($line = <INFILE>) {
+	chomp $line;
+	@syms = (@syms, $line);
+}
+close(INFILE);
+
+#
+#  ???_rename.h ãçæãã
+#
+$includes = "";
+$file = $name."_rename.h";
+open(FILE, "> ".$file);
+
+print FILE <<END;
+/* This file is generated from $infile by genrename. */
+
+#ifndef $header_defsym
+#define $header_defsym
+
+END
+
+foreach $sym (@syms) {
+	if ($sym =~ /^#(.*)$/) {
+		print FILE "/*\n";
+		print FILE " * ",$1,"\n";
+		print FILE " */\n";
+	}
+	elsif ($sym =~ /^INCLUDE[ \t]+(.*)$/) {
+		generate_include($1, "rename");
+	}
+	elsif ($sym ne "") {
+		generate_define($sym, "");
+	}
+	else {
+		print FILE "\n";
+	}
+}
+
+print FILE <<END;
+
+#ifdef TOPPERS_LABEL_ASM
+
+END
+
+foreach $sym (@syms) {
+	if ($sym =~ /^#(.*)$/) {
+		print FILE "/*\n";
+		print FILE " * ",$1,"\n";
+		print FILE " */\n";
+	}
+	elsif ($sym =~ /^INCLUDE[ \t]+(.*)$/) {
+		# do nothing
+	}
+	elsif ($sym ne "") {
+		generate_define($sym, "_");
+	}
+	else {
+		print FILE "\n";
+	}
+}
+
+print FILE <<END;
+
+#endif /* TOPPERS_LABEL_ASM */
+
+$includes
+#endif /* $header_defsym */
+END
+
+#
+#  ???_unrename.h ãçæãã
+#
+$includes = "";
+$file = $name."_unrename.h";
+open(FILE, "> ".$file);
+
+print FILE <<END;
+/* This file is generated from $infile by genrename. */
+
+/* This file is included only when $name\_rename.h has been included. */
+#ifdef $header_defsym
+#undef $header_defsym
+
+END
+
+foreach $sym (@syms) {
+	if ($sym =~ /^#(.*)$/) {
+		print FILE "/*\n";
+		print FILE " * ",$1,"\n";
+		print FILE " */\n";
+	}
+	elsif ($sym =~ /^INCLUDE[ \t]+(.*)$/) {
+		generate_include($1, "unrename");
+	}
+	elsif ($sym ne "") {
+		generate_undef($sym, "");
+	}
+	else {
+		print FILE "\n";
+	}
+}
+
+print FILE <<END;
+
+#ifdef TOPPERS_LABEL_ASM
+
+END
+
+foreach $sym (@syms) {
+	if ($sym =~ /^#(.*)$/) {
+		print FILE "/*\n";
+		print FILE " * ",$1,"\n";
+		print FILE " */\n";
+	}
+	elsif ($sym =~ /^INCLUDE[ \t]+(.*)$/) {
+		# do nothing
+	}
+	elsif ($sym ne "") {
+		generate_undef($sym, "_");
+	}
+	else {
+		print FILE "\n";
+	}
+}
+
+print FILE <<END;
+
+#endif /* TOPPERS_LABEL_ASM */
+
+$includes
+#endif /* $header_defsym */
+END
+
+close(FILE);
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/utils/gentest
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/utils/gentest	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/utils/gentest	(revision 457)
@@ -0,0 +1,379 @@
+#! /usr/bin/perl
+#
+#  TOPPERS Software
+#      Toyohashi Open Platform for Embedded Real-Time Systems
+# 
+#  Copyright (C) 2007-2014 by Embedded and Real-Time Systems Laboratory
+#              Graduate School of Information Science, Nagoya Univ., JAPAN
+# 
+#  ä¸è¨èä½æ¨©è
+ã¯ï¼ä»¥ä¸ã®(1)ï½(4)ã®æ¡ä»¶ãæºããå ´åã«éãï¼æ¬ã½ããã¦ã§
+#  ã¢ï¼æ¬ã½ããã¦ã§ã¢ãæ¹å¤ãããã®ãå«ãï¼ä»¥ä¸åãï¼ãä½¿ç¨ã»è¤è£½ã»æ¹
+#  å¤ã»åé
+å¸ï¼ä»¥ä¸ï¼å©ç¨ã¨å¼ã¶ï¼ãããã¨ãç¡åã§è¨±è«¾ããï¼
+#  (1) æ¬ã½ããã¦ã§ã¢ãã½ã¼ã¹ã³ã¼ãã®å½¢ã§å©ç¨ããå ´åã«ã¯ï¼ä¸è¨ã®èä½
+#      æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨ã®ç¡ä¿è¨¼è¦å®ãï¼ãã®ã¾ã¾ã®å½¢ã§ã½ã¼
+#      ã¹ã³ã¼ãä¸­ã«å«ã¾ãã¦ãããã¨ï¼
+#  (2) æ¬ã½ããã¦ã§ã¢ãï¼ã©ã¤ãã©ãªå½¢å¼ãªã©ï¼ä»ã®ã½ããã¦ã§ã¢éçºã«ä½¿
+#      ç¨ã§ããå½¢ã§åé
+å¸ããå ´åã«ã¯ï¼åé
+å¸ã«ä¼´ããã­ã¥ã¡ã³ãï¼å©ç¨
+#      è
+ããã¥ã¢ã«ãªã©ï¼ã«ï¼ä¸è¨ã®èä½æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨
+#      ã®ç¡ä¿è¨¼è¦å®ãæ²è¼ãããã¨ï¼
+#  (3) æ¬ã½ããã¦ã§ã¢ãï¼æ©å¨ã«çµã¿è¾¼ããªã©ï¼ä»ã®ã½ããã¦ã§ã¢éçºã«ä½¿
+#      ç¨ã§ããªãå½¢ã§åé
+å¸ããå ´åã«ã¯ï¼æ¬¡ã®ããããã®æ¡ä»¶ãæºããã
+#      ã¨ï¼
+#    (a) åé
+å¸ã«ä¼´ããã­ã¥ã¡ã³ãï¼å©ç¨è
+ããã¥ã¢ã«ãªã©ï¼ã«ï¼ä¸è¨ã®è
+#        ä½æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨ã®ç¡ä¿è¨¼è¦å®ãæ²è¼ãããã¨ï¼
+#    (b) åé
+å¸ã®å½¢æ
+ãï¼å¥ã«å®ããæ¹æ³ã«ãã£ã¦ï¼TOPPERSãã­ã¸ã§ã¯ãã«
+#        å ±åãããã¨ï¼
+#  (4) æ¬ã½ããã¦ã§ã¢ã®å©ç¨ã«ããç´æ¥çã¾ãã¯éæ¥çã«çãããããªãæ
+#      å®³ãããï¼ä¸è¨èä½æ¨©è
+ããã³TOPPERSãã­ã¸ã§ã¯ããå
+è²¬ãããã¨ï¼
+#      ã¾ãï¼æ¬ã½ããã¦ã§ã¢ã®ã¦ã¼ã¶ã¾ãã¯ã¨ã³ãã¦ã¼ã¶ããã®ãããªãç
+#      ç±ã«åºã¥ãè«æ±ãããï¼ä¸è¨èä½æ¨©è
+ããã³TOPPERSãã­ã¸ã§ã¯ãã
+#      å
+è²¬ãããã¨ï¼
+# 
+#  æ¬ã½ããã¦ã§ã¢ã¯ï¼ç¡ä¿è¨¼ã§æä¾ããã¦ãããã®ã§ããï¼ä¸è¨èä½æ¨©è
+ã
+#  ãã³TOPPERSãã­ã¸ã§ã¯ãã¯ï¼æ¬ã½ããã¦ã§ã¢ã«é¢ãã¦ï¼ç¹å®ã®ä½¿ç¨ç®ç
+#  ã«å¯¾ããé©åæ§ãå«ãã¦ï¼ãããªãä¿è¨¼ãè¡ããªãï¼ã¾ãï¼æ¬ã½ããã¦ã§
+#  ã¢ã®å©ç¨ã«ããç´æ¥çã¾ãã¯éæ¥çã«çãããããªãæå®³ã«é¢ãã¦ãï¼ã
+#  ã®è²¬ä»»ãè² ããªãï¼
+# 
+#  $Id$
+# 
+
+#
+#		ãã¹ããã­ã°ã©ã çæãã¼ã«
+#
+
+use open ":encoding(euc-jp)";
+use encoding "euc-jp";
+
+$infile = $ARGV[0];
+
+%parampos = (
+	"get_pri" => 2,
+	"get_inf" => 1,
+	"ref_tsk" => 2,
+	"ref_tex" => 2,
+	"ref_sem" => 2,
+	"ref_flg" => 2,
+	"ref_dtq" => 2,
+	"ref_pdq" => 2,
+	"ref_mbx" => 2,
+	"ref_mtx" => 2,
+	"ref_mbf" => 2,
+	"ref_mpf" => 2,
+	"get_tim" => 1,
+	"get_utm" => 1,
+	"ref_cyc" => 2,
+	"ref_alm" => 2,
+	"get_tid" => 1,
+	"iget_tid" => 1,
+	"get_ipm" => 1,
+);
+
+%paramtype = (
+	"get_pri" => "PRI",
+	"get_inf" => "intptr_t",
+	"ref_tsk" => "T_RTSK",
+	"ref_tex" => "T_RTEX",
+	"ref_sem" => "T_RSEM",
+	"ref_flg" => "T_RFLG",
+	"ref_dtq" => "T_RDTQ",
+	"ref_pdq" => "T_RPDQ",
+	"ref_mbx" => "T_RMBX",
+	"ref_mtx" => "T_RMTX",
+	"ref_mbf" => "T_RMBF",
+	"ref_mpf" => "T_RMPF",
+	"get_tim" => "SYSTIM",
+	"get_utm" => "SYSUTM",
+	"ref_cyc" => "T_RCYC",
+	"ref_alm" => "T_RALM",
+	"get_tid" => "ID",
+	"iget_tid" => "ID",
+	"get_ipm" => "PRI",
+);
+
+$last_check_point = 0;
+
+sub gen_var_def {
+	local($svc_call) = @_;
+	local($svcname, @params);
+	local($typename, $varname);
+
+	if ($svc_call =~ /^([a-z_]+)\((.*)\)$/) {
+		$svcname = $1;
+		@params = split(/\s*,\s*/, $2);
+
+		if ($parampos{$svcname}) {
+			$varname = $params[@parampos{$svcname} - 1];
+			$varname =~ s/^\&//;
+			$typename = $paramtype{$svcname};
+			${$TASKVAR{$tskid}}{$typename} = ${varname};
+		}
+	}
+}
+
+sub gen_svc_call {
+	local($svc_call, $error_code_string) = @_;
+	local($error_code);
+
+	${$TASKVAR{$tskid}}{"ER_UINT"} = "ercd";
+
+	push(@{$TASKCODE{$tskid}{$tskcnt}}, sprintf("\tercd = %s;", $svc_call));
+	gen_var_def($svc_call);
+
+	if ($error_code_string eq "") {
+		push(@{$TASKCODE{$tskid}{$tskcnt}},
+								sprintf("\tcheck_ercd(ercd, E_OK);"), "");
+	}
+	elsif ($error_code_string =~ /^\-\>\s*noreturn$/) {
+		push(@{$TASKCODE{$tskid}{$tskcnt}}, "");
+	}
+	else {
+		$error_code = $error_code_string;
+		$error_code =~ s/^\-\>\s*([A-Za-z0-9_]*)$/$1/;
+		push(@{$TASKCODE{$tskid}{$tskcnt}},
+						sprintf("\tcheck_ercd(ercd, %s);", $error_code), "");
+	}
+}
+
+sub parse_line {
+	local($line) = @_;
+
+	while ($line =~ s/\\$//) {
+		$line1 = <INFILE>;
+		$output_line .= $line1;
+		chomp $line1;
+		$line1 =~ s/^\s*\*\s*//;
+		$line1 =~ s/\s*\/\/.*$//;
+		$line1 =~ s/\s*\.\.\..*$//;
+		$line .= $line1;
+	}
+
+	if ($line =~ /^\.\./) {
+		# do nothing.
+	}
+	elsif ($line =~ /^==\s*((TASK|ALM|CPUEXC|EXTSVC)[0-9]*)(.*)$/) {
+		$procflag = 1;
+		$tskid = $1;
+		$line2 = $3;
+		if ($line2 =~ /^\-TEX(.*)$/) {
+			$tskid = $tskid."-TEX";
+			$line2 = $1;
+		}
+		if ($line2 =~ /^\-([0-9]+)(.*)$/) {
+			$tskcnt = $1;
+			if (!$TASKCOUNTVAR{$tskid}) {
+				if ($tskid =~ /^TASK([0-9]*)$/) {
+					$countvar = "task$1_count";
+				}
+				elsif ($tskid =~ /^TASK([0-9]*)-TEX$/) {
+					$countvar = "tex_task$1_count";
+				}
+				elsif ($tskid =~ /^ALM([0-9]*)$/) {
+					$countvar = "alarm$1_count";
+				}
+				elsif ($tskid =~ /^CPUEXC([0-9]*)$/) {
+					$countvar = "cpuexc$1_count";
+				}
+				elsif ($tskid =~ /^EXTSVC([0-9]*)$/) {
+					$countvar = "extsvc$1_count";
+				}
+				$TASKCOUNTVAR{$tskid} = $countvar;
+			}
+		}
+		else {
+			$tskcnt = "";
+		}
+		if ($startflag) {
+			push(@{$TASKCODE{$tskid}{$tskcnt}}, "\ttest_start(__FILE__);");
+			push(@{$TASKCODE{$tskid}{$tskcnt}}, "");
+			$startflag = 0;
+		}
+	}
+	elsif (!$procflag) {
+		# do nothing.
+	}
+	elsif ($line =~ /^([0-9]+\:)\s*END$/) {
+		$check_str = $1;
+		$check_no = ++$last_check_point;
+		push(@{$TASKCODE{$tskid}{$tskcnt}},
+								sprintf("\tcheck_finish(%d);", $check_no));
+		$procflag = 0;
+		$output_line =~ s/$check_str/$check_no:/;
+	}
+	else {
+		if ($line =~ /^([0-9]+\:)\s*(.*)/) {
+			$check_str = $1;
+			$line = $2;
+			$check_no = ++$last_check_point;
+			push(@{$TASKCODE{$tskid}{$tskcnt}},
+								sprintf("\tcheck_point(%d);", $check_no));
+			$output_line =~ s/$check_str/$check_no:/;
+		}
+		if ($line =~ /^(assert\(.*\))$/) {
+			$assert_string = $1;
+			push(@{$TASKCODE{$tskid}{$tskcnt}},
+								sprintf("\tcheck_%s;", $assert_string), "");
+		}
+		elsif ($line =~ /^(state(_i)?\(.*\))$/) {
+			$state_string = $1;
+			push(@{$TASKCODE{$tskid}{$tskcnt}},
+								sprintf("\tcheck_%s;", $state_string), "");
+		}
+		elsif ($line =~ /^call\((.*)\)$/ || $line =~ /^DO\((.*)\)$/) {
+			$call_string = $1;
+			push(@{$TASKCODE{$tskid}{$tskcnt}},
+									sprintf("\t%s;", $call_string), "");
+		}
+		elsif ($line =~ /^MISSING$/) {
+			push(@{$TASKCODE{$tskid}{$tskcnt}}, "");
+		}
+		elsif ($line =~ /^RETURN((\(.*\))?)$/) {
+			$return_string = $1;
+			push(@{$TASKCODE{$tskid}{$tskcnt}},
+									"\treturn".$return_string.";", "");
+		}
+		elsif ($line =~ /^GOTO\((.*)\)$/) {
+			$goto_string = $1;
+			push(@{$TASKCODE{$tskid}{$tskcnt}},
+									sprintf("\tgoto %s;", $goto_string), "");
+		}
+		elsif ($line =~ /^LABEL\((.*)\)$/) {
+			$label_string = $1;
+			$indent_string = $indentstr;
+			$indent_string =~ s/\t$//;
+			push(@{$TASKCODE{$tskid}{$tskcnt}},
+									sprintf("%s:", $label_string));
+		}
+		elsif ($line =~ /^([a-z_]+\(.*\))\s*(\-\>\s*[A-Za-z0-9_]*)?\s*$/) {
+			$svc_call = $1;
+			$error_code_string = $2;
+			gen_svc_call($svc_call, $error_code_string);
+		}
+		else {
+			print STDERR "Error: ",$line,"\n";
+		}
+	}
+}
+
+#
+#  ã¹ã¯ãªãããã¡ã¤ã«èª­è¾¼ã¿å¦ç
+#
+$procflag = 0;
+$startflag = 1;
+$outflag = 1;
+open(INFILE, $infile) || die "Cannot open $infile";
+while (($line = <INFILE>) && $outflag) {
+	$output_line = $line;
+	chomp $line;
+	$line =~ s/^\s*\*\s*//;
+	$line =~ s/\s*\/\/.*$//;
+	$line =~ s/\s*\.\.\..*$//;
+	if ($line) {
+		parse_line($line);
+	}
+	print $output_line;
+	if ($output_line =~ /DO NOT DELETE THIS LINE/) {
+		$outflag = 0;
+	}
+}
+close(INFILE);
+
+#
+#  ã¿ã¹ã¯ã®å¤æ°å®ç¾©ã®ã³ã¼ãåºå
+#
+sub output_task_vardef {
+	my($tskid) = @_;
+
+	foreach my $typename (keys(%{$TASKVAR{$tskid}})) {
+		print "\t",$typename, (length($typename) < 4 ? "\t\t" : "\t"),
+								${$TASKVAR{$tskid}}{$typename},";\n";
+	}
+}
+
+#
+#  ã¿ã¹ã¯æ¬ä½ã®ã³ã¼ãåºå
+#
+sub output_task_body {
+	my($tskid) = @_;
+
+	foreach my $tskcnt (sort {$a <=> $b} (keys(%{$TASKCODE{$tskid}}))) {
+		printf "\tcase %d:\n", $tskcnt;
+		foreach my $line (@{$TASKCODE{$tskid}{$tskcnt}}) {
+			print "\t",$line if ($line);
+			print "\n";
+		}
+		printf "\t\tcheck_point(0);\n\n";
+	}
+}
+
+#
+#  ã¿ã¹ã¯ã³ã¼ãã®åºå
+#
+sub output_task {
+	if ($TASKCOUNTVAR{$tskid}) {
+		printf "\nstatic uint_t\t%s = 0;\n", $TASKCOUNTVAR{$tskid};
+	}
+	if ($tskid =~ /^TASK([0-9]*)$/) {
+		print "\nvoid\n";
+		print "task$1(intptr_t exinf)\n";
+	}
+	elsif ($tskid =~ /^TASK([0-9]*)-TEX$/) {
+		print "\nvoid\n";
+		print "tex_task$1(TEXPTN texptn, intptr_t exinf)\n";
+	}
+	elsif ($tskid =~ /^ALM([0-9]*)$/) {
+		print "\nvoid\n";
+		print "alarm$1_handler(intptr_t exinf)\n";
+	}
+	elsif ($tskid =~ /^CPUEXC([0-9]*)$/) {
+		print "\nvoid\n";
+		print "cpuexc$1_handler(void *p_excinf)\n";
+	}
+	elsif ($tskid =~ /^EXTSVC([0-9]*)$/) {
+		print "\nER_UINT\n";
+		print "extsvc$1_routine(intptr_t par1, intptr_t par2, intptr_t par3,\n";
+		print "\t\t\t\t\t\t\t\tintptr_t par4, intptr_t par5, ID cdmid)\n";
+	}
+	print "{\n";
+	output_task_vardef($tskid);
+	print "\n";
+	if ($TASKCOUNTVAR{$tskid}) {
+		printf "\tswitch (++%s) {\n", $TASKCOUNTVAR{$tskid};
+		output_task_body($tskid);
+		printf "\tdefault:\n";
+		printf "\t\tcheck_point(0);\n";
+		printf "\t}\n";
+	}
+	else {
+		foreach my $line (@{$TASKCODE{$tskid}{""}}) {
+			print $line,"\n";
+		}
+	}
+	print "\tcheck_point(0);\n";
+	if ($tskid =~ /^EXTSVC([0-9]*)$/) {
+		print "\treturn(E_SYS);\n";
+	}
+	print "}\n";
+}
+
+#
+#  ãã¹ããã­ã°ã©ã åºåå¦ç
+#
+foreach $tskid (sort(keys(%TASKCODE))) {
+	output_task();
+}
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/utils/makedep
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/utils/makedep	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/utils/makedep	(revision 457)
@@ -0,0 +1,194 @@
+#! /usr/bin/perl
+#
+#  TOPPERS Software
+#      Toyohashi Open Platform for Embedded Real-Time Systems
+# 
+#  Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
+#                              Toyohashi Univ. of Technology, JAPAN
+#  Copyright (C) 2004-2013 by Embedded and Real-Time Systems Laboratory
+#              Graduate School of Information Science, Nagoya Univ., JAPAN
+# 
+#  ä¸è¨èä½æ¨©è
+ã¯ï¼ä»¥ä¸ã®(1)ï½(4)ã®æ¡ä»¶ãæºããå ´åã«éãï¼æ¬ã½ããã¦ã§
+#  ã¢ï¼æ¬ã½ããã¦ã§ã¢ãæ¹å¤ãããã®ãå«ãï¼ä»¥ä¸åãï¼ãä½¿ç¨ã»è¤è£½ã»æ¹
+#  å¤ã»åé
+å¸ï¼ä»¥ä¸ï¼å©ç¨ã¨å¼ã¶ï¼ãããã¨ãç¡åã§è¨±è«¾ããï¼
+#  (1) æ¬ã½ããã¦ã§ã¢ãã½ã¼ã¹ã³ã¼ãã®å½¢ã§å©ç¨ããå ´åã«ã¯ï¼ä¸è¨ã®èä½
+#      æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨ã®ç¡ä¿è¨¼è¦å®ãï¼ãã®ã¾ã¾ã®å½¢ã§ã½ã¼
+#      ã¹ã³ã¼ãä¸­ã«å«ã¾ãã¦ãããã¨ï¼
+#  (2) æ¬ã½ããã¦ã§ã¢ãï¼ã©ã¤ãã©ãªå½¢å¼ãªã©ï¼ä»ã®ã½ããã¦ã§ã¢éçºã«ä½¿
+#      ç¨ã§ããå½¢ã§åé
+å¸ããå ´åã«ã¯ï¼åé
+å¸ã«ä¼´ããã­ã¥ã¡ã³ãï¼å©ç¨
+#      è
+ããã¥ã¢ã«ãªã©ï¼ã«ï¼ä¸è¨ã®èä½æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨
+#      ã®ç¡ä¿è¨¼è¦å®ãæ²è¼ãããã¨ï¼
+#  (3) æ¬ã½ããã¦ã§ã¢ãï¼æ©å¨ã«çµã¿è¾¼ããªã©ï¼ä»ã®ã½ããã¦ã§ã¢éçºã«ä½¿
+#      ç¨ã§ããªãå½¢ã§åé
+å¸ããå ´åã«ã¯ï¼æ¬¡ã®ããããã®æ¡ä»¶ãæºããã
+#      ã¨ï¼
+#    (a) åé
+å¸ã«ä¼´ããã­ã¥ã¡ã³ãï¼å©ç¨è
+ããã¥ã¢ã«ãªã©ï¼ã«ï¼ä¸è¨ã®è
+#        ä½æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨ã®ç¡ä¿è¨¼è¦å®ãæ²è¼ãããã¨ï¼
+#    (b) åé
+å¸ã®å½¢æ
+ãï¼å¥ã«å®ããæ¹æ³ã«ãã£ã¦ï¼TOPPERSãã­ã¸ã§ã¯ãã«
+#        å ±åãããã¨ï¼
+#  (4) æ¬ã½ããã¦ã§ã¢ã®å©ç¨ã«ããç´æ¥çã¾ãã¯éæ¥çã«çãããããªãæ
+#      å®³ãããï¼ä¸è¨èä½æ¨©è
+ããã³TOPPERSãã­ã¸ã§ã¯ããå
+è²¬ãããã¨ï¼
+#      ã¾ãï¼æ¬ã½ããã¦ã§ã¢ã®ã¦ã¼ã¶ã¾ãã¯ã¨ã³ãã¦ã¼ã¶ããã®ãããªãç
+#      ç±ã«åºã¥ãè«æ±ãããï¼ä¸è¨èä½æ¨©è
+ããã³TOPPERSãã­ã¸ã§ã¯ãã
+#      å
+è²¬ãããã¨ï¼
+# 
+#  æ¬ã½ããã¦ã§ã¢ã¯ï¼ç¡ä¿è¨¼ã§æä¾ããã¦ãããã®ã§ããï¼ä¸è¨èä½æ¨©è
+ã
+#  ãã³TOPPERSãã­ã¸ã§ã¯ãã¯ï¼æ¬ã½ããã¦ã§ã¢ã«é¢ãã¦ï¼ç¹å®ã®ä½¿ç¨ç®ç
+#  ã«å¯¾ããé©åæ§ãå«ãã¦ï¼ãããªãä¿è¨¼ãè¡ããªãï¼ã¾ãï¼æ¬ã½ããã¦ã§
+#  ã¢ã®å©ç¨ã«ããç´æ¥çã¾ãã¯éæ¥çã«çãããããªãæå®³ã«é¢ãã¦ãï¼ã
+#  ã®è²¬ä»»ãè² ããªãï¼
+# 
+#  @(#) $Id$
+# 
+
+use Getopt::Std;
+
+#  ãªãã·ã§ã³ã®å®ç¾©
+#
+#  -C <cc_path>		Cã³ã³ãã¤ã©ã®ã³ãã³ãå
+#  -O <cc_opts>		Cã³ã³ãã¤ã©/CPPã«æ¸¡ããªãã·ã§ã³
+#  -X				ã½ã¼ã¹ãã¡ã¤ã«ãå¼·å¶çã«Cããããã¡ã¤ã«ã¨è¦ãªã
+#
+#  -T <target>		ã¿ã¼ã²ããåï¼ã®ãªã¹ãï¼
+#  -D <t_dir>		ã¿ã¼ã²ããã®ãã£ã¬ã¯ããªåãæå®ããï¼-Tãç¨ããå ´
+#					åã¯ç¡å¹ï¼
+#  -d				ã¿ã¼ã²ããã®ãã£ã¬ã¯ããªé¨ãä¿æããï¼-Tãç¨ããå ´
+#					åã¯ç¡å¹ï¼
+#  -S				è¤æ°ã®ã¿ã¼ã²ãããããä¾å­ã«ã¼ã«ãï¼ã¿ã¼ã²ããæ¯ã«
+#					åå²ããï¼ããããªãã¨å¯¾å¿ã§ããªãmakeããããããï¼
+#
+#  -R <dirname>		Cygwinç°å¢ã«ãããã«ã¼ããã£ã¬ã¯ããªåãæå®ãã
+#					ï¼ããã©ã«ãã¯cygdriveï¼
+
+#
+#  ãªãã·ã§ã³ã®å¦ç
+#
+getopt("COTDR");
+
+$cc_path = $opt_C;
+$cc_opts = $opt_O;
+
+if ($opt_T) {
+	$target_name = $opt_T;
+}
+elsif ($opt_D) {
+	$target_dir = $opt_D;
+}
+elsif (!$opt_d) {
+	$target_dir = "";
+}
+
+if ($opt_R) {
+	$cygwin_root = $opt_R;
+}
+else {
+	$cygwin_root = "cygdrive";
+}
+
+#
+#  Cygwinç°å¢ã®å¤å¥
+#
+if ($^O eq 'cygwin') {
+	$cygwin = 1;
+}
+
+#
+#  %dependlist ã«ä½ãããä¾å­é¢ä¿ãåºåãã
+#
+sub output_dependlist {
+	local($target) = @_;
+	local($column, $len, $file);
+
+	print $target, ": ";
+	$column = length($target) + 2;
+
+	foreach $file (keys(%dependlist)) {
+		$len = length($file) + 1;
+		if ($column > 8 && $column + $len >= 70) {
+			print "\\\n\t";
+			$column = 8;
+		}
+		$column += $len;
+		print "$file ";
+	}
+	print "\n";
+}
+
+#
+#  $file ã®ä¾å­é¢ä¿ã %dependlist ã«ä½ã
+#
+sub makedepend_one {
+	local($file) = @_;
+	local($command, $input, $dir, $filename);
+
+	$command = "$cc_path -E $cc_opts";
+	if ($opt_X) {
+		$command .= " -x c-header";
+	}
+	unless (open(INPUT, "$command $file |")) {
+		print STDERR "makedep: can't open $file\n";
+		exit(1);
+	}
+	while ($line = <INPUT>) {
+		if ($line =~ /^\#[a-zA-Z]*\s*([0-9]+)\s*\"([^\"]+)\"/) {
+			$filename = $2;
+			$filename =~ s/ /\\ /g;
+			if ($filename !~ /^\<.*\>$/ && $filename !~ /\/$/) {
+				if ($cygwin) {
+					$filename =~ s/\\\\/\//g;
+					$filename =~ s/^([a-zA-Z]):/\/$cygwin_root\/$1/;
+				}
+				$dependlist{$filename} = 1;
+			}
+		}
+	}
+	unless (close(INPUT)) {
+		print STDERR "makedep: can't execute $command\n";
+		exit(1);
+	}
+}
+
+#
+#  ã¡ã¤ã³ã«ã¼ãã³
+#
+foreach $file (@ARGV) {
+	%dependlist = ();
+	makedepend_one($file);
+	if (%dependlist) {
+		if ($target_name) {
+			if ($opt_S) {
+				foreach $target (split(/[ \t]+/, $target_name)) {
+					output_dependlist($target);
+				}
+			}
+			else {
+				output_dependlist($target_name);
+			}
+		}
+		else {
+			$target = $file;
+			$target =~ s/(.*)\.(.*)/$1.o/;
+			if (defined($target_dir)) {
+				$target =~ s/^.*\/([^\/]+)$/$1/;
+				if ($target_dir) {
+					$target = $target_dir."/".$target;
+				}
+			}
+			output_dependlist($target);
+		}
+	}
+}
Index: azure_iot_hub_f767zi/trunk/asp_baseplatform/utils/makerelease
===================================================================
--- azure_iot_hub_f767zi/trunk/asp_baseplatform/utils/makerelease	(revision 457)
+++ azure_iot_hub_f767zi/trunk/asp_baseplatform/utils/makerelease	(revision 457)
@@ -0,0 +1,171 @@
+#! /usr/bin/perl
+#
+#  TOPPERS Software
+#      Toyohashi Open Platform for Embedded Real-Time Systems
+# 
+#  Copyright (C) 2006-2011 by Embedded and Real-Time Systems Laboratory
+#              Graduate School of Information Science, Nagoya Univ., JAPAN
+# 
+#  ä¸è¨èä½æ¨©è
+ã¯ï¼ä»¥ä¸ã®(1)ï½(4)ã®æ¡ä»¶ãæºããå ´åã«éãï¼æ¬ã½ããã¦ã§
+#  ã¢ï¼æ¬ã½ããã¦ã§ã¢ãæ¹å¤ãããã®ãå«ãï¼ä»¥ä¸åãï¼ãä½¿ç¨ã»è¤è£½ã»æ¹
+#  å¤ã»åé
+å¸ï¼ä»¥ä¸ï¼å©ç¨ã¨å¼ã¶ï¼ãããã¨ãç¡åã§è¨±è«¾ããï¼
+#  (1) æ¬ã½ããã¦ã§ã¢ãã½ã¼ã¹ã³ã¼ãã®å½¢ã§å©ç¨ããå ´åã«ã¯ï¼ä¸è¨ã®èä½
+#      æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨ã®ç¡ä¿è¨¼è¦å®ãï¼ãã®ã¾ã¾ã®å½¢ã§ã½ã¼
+#      ã¹ã³ã¼ãä¸­ã«å«ã¾ãã¦ãããã¨ï¼
+#  (2) æ¬ã½ããã¦ã§ã¢ãï¼ã©ã¤ãã©ãªå½¢å¼ãªã©ï¼ä»ã®ã½ããã¦ã§ã¢éçºã«ä½¿
+#      ç¨ã§ããå½¢ã§åé
+å¸ããå ´åã«ã¯ï¼åé
+å¸ã«ä¼´ããã­ã¥ã¡ã³ãï¼å©ç¨
+#      è
+ããã¥ã¢ã«ãªã©ï¼ã«ï¼ä¸è¨ã®èä½æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨
+#      ã®ç¡ä¿è¨¼è¦å®ãæ²è¼ãããã¨ï¼
+#  (3) æ¬ã½ããã¦ã§ã¢ãï¼æ©å¨ã«çµã¿è¾¼ããªã©ï¼ä»ã®ã½ããã¦ã§ã¢éçºã«ä½¿
+#      ç¨ã§ããªãå½¢ã§åé
+å¸ããå ´åã«ã¯ï¼æ¬¡ã®ããããã®æ¡ä»¶ãæºããã
+#      ã¨ï¼
+#    (a) åé
+å¸ã«ä¼´ããã­ã¥ã¡ã³ãï¼å©ç¨è
+ããã¥ã¢ã«ãªã©ï¼ã«ï¼ä¸è¨ã®è
+#        ä½æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨ã®ç¡ä¿è¨¼è¦å®ãæ²è¼ãããã¨ï¼
+#    (b) åé
+å¸ã®å½¢æ
+ãï¼å¥ã«å®ããæ¹æ³ã«ãã£ã¦ï¼TOPPERSãã­ã¸ã§ã¯ãã«
+#        å ±åãããã¨ï¼
+#  (4) æ¬ã½ããã¦ã§ã¢ã®å©ç¨ã«ããç´æ¥çã¾ãã¯éæ¥çã«çãããããªãæ
+#      å®³ãããï¼ä¸è¨èä½æ¨©è
+ããã³TOPPERSãã­ã¸ã§ã¯ããå
+è²¬ãããã¨ï¼
+#      ã¾ãï¼æ¬ã½ããã¦ã§ã¢ã®ã¦ã¼ã¶ã¾ãã¯ã¨ã³ãã¦ã¼ã¶ããã®ãããªãç
+#      ç±ã«åºã¥ãè«æ±ãããï¼ä¸è¨èä½æ¨©è
+ããã³TOPPERSãã­ã¸ã§ã¯ãã
+#      å
+è²¬ãããã¨ï¼
+# 
+#  æ¬ã½ããã¦ã§ã¢ã¯ï¼ç¡ä¿è¨¼ã§æä¾ããã¦ãããã®ã§ããï¼ä¸è¨èä½æ¨©è
+ã
+#  ãã³TOPPERSãã­ã¸ã§ã¯ãã¯ï¼æ¬ã½ããã¦ã§ã¢ã«é¢ãã¦ï¼ç¹å®ã®ä½¿ç¨ç®ç
+#  ã«å¯¾ããé©åæ§ãå«ãã¦ï¼ãããªãä¿è¨¼ãè¡ããªãï¼ã¾ãï¼æ¬ã½ããã¦ã§
+#  ã¢ã®å©ç¨ã«ããç´æ¥çã¾ãã¯éæ¥çã«çãããããªãæå®³ã«é¢ãã¦ãï¼ã
+#  ã®è²¬ä»»ãè² ããªãï¼
+# 
+#  @(#) $Id$
+# 
+
+use Cwd;
+
+$cwd = getcwd();
+$cwd =~ s/^.*[\/\\]([^\/\\]+)$/$1/;
+$prefix = "./".$cwd;
+
+@file_list = ();
+%file_list = ();
+
+if ($#ARGV >= 0) {
+	$arg1 = $ARGV[0];
+	$arg1 =~ s/\.\///;
+}
+else {
+	$arg1 = "MANIFEST";
+}
+
+sub gen_path
+{
+	local($base, $path) = @_;
+
+	while ($path =~ /^..\/(.*)$/) {
+		$path = $1;
+		$base =~ s/(\/?)[^\/]*\/$/$1/;
+	}
+	return($base.$path);
+}
+
+sub read_file {
+	local($filename) = @_;
+	local($fh, $dirname);
+
+	if ($filename =~ /^(.*\/)[^\/]*$/) {
+		$dirname = $1;
+	}
+	else {
+		$dirname = "";
+	}
+
+	open($fh, $filename) || die "Cannot open $filename";
+	while ($line = <$fh>) {
+		chomp $line;
+		$line =~ s/\r$//;
+		$line =~ s/[ \t]*\#.*$//;
+		next if ($line =~ /^[ \t]*$/);
+
+		if ($line =~ /^E_PACKAGE[ \t]+(.*)$/) {
+			if ($package) {
+				die "Duplicated E_PACKAGE directive.";
+			}
+			else {
+				$package = $1;
+				$e_package = 1;
+			}
+		}
+		elsif ($line =~ /^PACKAGE[ \t]+(.*)$/) {
+			if ($package) {
+				if (!$e_package && $package != $1) {
+					die "Inconsistent PACKAGE directive.";
+				}
+			}
+			else {
+				$package = $1;
+			}
+		}
+		elsif ($line =~ /^VERSION[ \t]+(.*)$/) {
+			if ($version) {
+				if (!$e_package && $version != $1) {
+					die "Inconsistent VERSION directive.";
+				}
+			}
+			else {
+				$version = $1;
+				if ($version =~ /%date/) {
+					@current_time = localtime();
+					$vdate = sprintf("%04d%02d%02d", $current_time[5]+1900,
+										$current_time[4]+1, $current_time[3]);
+					$version =~ s/%date/$vdate/;
+				}
+			}
+		}
+		elsif ($line =~ /^INCLUDE[ \t]+(.*)$/) {
+			read_file(gen_path($dirname, $1));
+		}
+		else {
+			$filename = $prefix."/".$dirname.$line;
+			while ($filename =~ s|/[^/]+/\.\./|/|) {}
+			if ($file_list{$filename}) {
+				die "$filename is duplicated.";
+			}
+			else {
+				push(@file_list, $filename);
+				$file_list{$filename} = $filename;
+			}
+		}
+	}
+	close($fh);
+}
+
+read_file($arg1);
+unless ($package) {
+	die "PACKAGE/E_PACKAGE directive not found.";
+}
+unless ($version) {
+	die "VERSION directive not found.";
+}
+
+if (! -d "RELEASE") {
+	mkdir("RELEASE");
+}
+
+$archive_name = $package."-".$version.".tar.gz";
+$file_list = join(" ", @file_list);
+$command = "tar cvfz RELEASE/$archive_name -C .. $file_list\n";
+die if (system($command));
+print STDERR "== RELEASE/$archive_name is generated. ==\n";
Index: azure_iot_hub_f767zi/trunk/azure_iot_sdk/.vscode/c_cpp_properties.json
===================================================================
--- azure_iot_hub_f767zi/trunk/azure_iot_sdk/.vscode/c_cpp_properties.json	(revision 457)
+++ azure_iot_hub_f767zi/trunk/azure_iot_sdk/.vscode/c_cpp_properties.json	(revision 457)
@@ -0,0 +1,39 @@
+{
+    "configurations": [
+        {
+            "name": "STM32F767 NUCLEO-144",
+            "includePath": [
+                "${workspaceFolder}/../asp_baseplatform/include",
+                "${workspaceFolder}/../asp_baseplatform/arch/gcc",
+                "${workspaceFolder}/../asp_baseplatform/arch/arm_m_gcc/common",
+                "${workspaceFolder}/../asp_baseplatform/arch/arm_m_gcc/stm32f7xx",
+                "${workspaceFolder}/../asp_baseplatform/target/stm32f767nucleo144_gcc",
+                "${workspaceFolder}/../asp_baseplatform/lwip/lwip-2.1.2/src/include",
+                "${workspaceFolder}/../asp_baseplatform/lwip/lwip-2.1.2/src/include/compat/posix",
+                "${workspaceFolder}/../asp_baseplatform/lwip/contrib-2.1.0/ports/toppers/include",
+                "${workspaceFolder}/../asp_baseplatform/lwip/contrib-2.1.0",
+                "${workspaceFolder}/../asp_baseplatform/OBJ/STM32F767NUCLEO144_GCC/MAC",
+                "${workspaceFolder}/../azure_iot_sdk/c-utility/inc",
+                "${workspaceFolder}/../azure_iot_sdk/c-utility/pal/toppers",
+                "${workspaceFolder}/../azure_iot_sdk/iothub_client/inc",
+                "${workspaceFolder}/../azure_iot_sdk/iothub_client/inc/internal",
+                "${workspaceFolder}/../azure_iot_sdk/deps/parson",
+                "${workspaceFolder}/../azure_iot_sdk/umqtt/inc",
+                "${workspaceFolder}/../wolfssl-4.4.0/wolfssl",
+                "${workspaceFolder}/../wolfssl-4.4.0/wolfssl/wolfcrypt",
+                "${workspaceFolder}/../wolfssl-4.4.0",
+                "${workspaceFolder}/../zlib-1.2.11/src"
+            ],
+            "defines": [
+                "USE_WOLFSSL=1",
+                "get_time=azure_get_time"
+            ],
+            "windowsSdkVersion": "10.0.17763.0",
+            "compilerPath": "C:\\Program Files (x86)\\GNU Tools ARM Embedded\\9 2019-q4-major\\bin\\arm-none-eabi-gcc.exe",
+            "cStandard": "c11",
+            "cppStandard": "c++17",
+            "intelliSenseMode": "gcc-x64"
+        }
+    ],
+    "version": 4
+}
Index: azure_iot_hub_f767zi/trunk/azure_iot_sdk/.vscode/settings.json
===================================================================
--- azure_iot_hub_f767zi/trunk/azure_iot_sdk/.vscode/settings.json	(revision 457)
+++ azure_iot_hub_f767zi/trunk/azure_iot_sdk/.vscode/settings.json	(revision 457)
@@ -0,0 +1,17 @@
+// Place your settings in this file to overwrite default and user settings.
+{
+    "terminal.integrated.setLocaleVariables": true,
+    "terminal.integrated.shell.windows": "C:\\msys64\\usr\\bin\\bash.exe",
+    "terminal.integrated.shellArgs.windows": [
+        "--login",
+        "-i"
+    ],
+    "terminal.integrated.env.windows": {
+        "PATH": "C:\\Program Files (x86)\\GNU Tools ARM Embedded\\9 2019-q4-major\\bin",
+        "CHERE_INVOKING": "1",
+        "MSYS2_PATH_TYPE": "inherit",
+        "MSYSTEM": "MINGW64"
+    },
+    "C_Cpp.intelliSenseEngine": "Tag Parser",
+    "C_Cpp.default.intelliSenseMode": "gcc-x64"
+}
Index: azure_iot_hub_f767zi/trunk/azure_iot_sdk/.vscode/tasks.json
===================================================================
--- azure_iot_hub_f767zi/trunk/azure_iot_sdk/.vscode/tasks.json	(revision 457)
+++ azure_iot_hub_f767zi/trunk/azure_iot_sdk/.vscode/tasks.json	(revision 457)
@@ -0,0 +1,57 @@
+{
+    // See https://go.microsoft.com/fwlink/?LinkId=733558
+    // for the documentation about the tasks.json format
+    "version": "2.0.0",
+    "name": "make",
+    "type": "shell",
+    "problemMatcher": {
+        "owner": "cpp",
+        "fileLocation": [
+            "relative",
+            "${workspaceFolder}/Debug"
+        ],
+        "pattern": {
+            "regexp": "^(.*):(\\d+):(\\d+):\\s+(warning|error|fatal error):\\s+(.*)$",
+            "file": 1,
+            "line": 2,
+            "column": 3,
+            "severity": 4,
+            "message": 5
+        }
+    },
+    "tasks": [
+        {
+            "label": "build azure_iot_sdk",
+            "args": [
+                "-j",
+                "all"
+            ],
+            "linux": {
+                "command": "make"
+            },
+            "osx": {
+                "command": "make"
+            },
+            "windows": {
+                "command": "make.exe"
+            },
+            "group": "build"
+        },
+        {
+            "label": "clean azure_iot_sdk",
+            "args": [
+                "clean"
+            ],
+            "linux": {
+                "command": "make"
+            },
+            "osx": {
+                "command": "make"
+            },
+            "windows": {
+                "command": "make.exe"
+            },
+            "group": "build"
+        }
+    ]
+}
Index: azure_iot_hub_f767zi/trunk/azure_iot_sdk/Makefile
===================================================================
--- azure_iot_hub_f767zi/trunk/azure_iot_sdk/Makefile	(revision 457)
+++ azure_iot_hub_f767zi/trunk/azure_iot_sdk/Makefile	(revision 457)
@@ -0,0 +1,321 @@
+# This file was automagically generated by mbed.org. For more information, 
+# see http://mbed.org/handbook/Exporting-to-GCC-ARM-Embedded
+
+###############################################################################
+# Boiler-plate
+
+# cross-platform directory manipulation
+ifeq ($(shell echo $$OS),$$OS)
+    MAKEDIR = if not exist "$(1)" mkdir "$(1)"
+    RM = rmdir /S /Q "$(1)"
+else
+    MAKEDIR = '$(SHELL)' -c "mkdir -p \"$(1)\""
+    RM = '$(SHELL)' -c "rm -rf \"$(1)\""
+endif
+
+OBJDIR := Debug
+# Move to the build directory
+ifeq (,$(filter $(OBJDIR),$(notdir $(CURDIR))))
+.SUFFIXES:
+mkfile_path := $(abspath $(lastword $(MAKEFILE_LIST)))
+MAKETARGET = '$(MAKE)' --no-print-directory -C $(OBJDIR) -f '$(mkfile_path)' \
+		'SRCDIR=$(CURDIR)' $(MAKECMDGOALS)
+.PHONY: $(OBJDIR) clean
+all:
+	+@$(call MAKEDIR,$(OBJDIR))
+	+@$(MAKETARGET)
+$(OBJDIR): all
+Makefile : ;
+% :: $(OBJDIR) ; :
+clean :
+	$(call RM,$(OBJDIR))
+
+else
+
+# trick rules into thinking we are in the root, when we are in the bulid dir
+VPATH = ../../azure_iot_sdk
+
+# Boiler-plate
+###############################################################################
+# Project settings
+
+PROJECT := azure_iot_sdk
+
+
+# Project settings
+###############################################################################
+# Objects and Paths
+
+OBJECTS += c-utility/adapters/agenttime_mbed.o
+OBJECTS += c-utility/adapters/httpapi_compact.o
+OBJECTS += c-utility/adapters/lock_toppers.o
+OBJECTS += c-utility/adapters/platform_toppers.o
+OBJECTS += c-utility/adapters/socketio_esp_at.o
+OBJECTS += c-utility/adapters/threadapi_toppers.o
+OBJECTS += c-utility/adapters/tickcounter_toppers.o
+OBJECTS += c-utility/adapters/tlsio_esp_at.o
+OBJECTS += c-utility/adapters/tlsio_wolfssl.o
+OBJECTS += c-utility/adapters/uniqueid_stub.o
+OBJECTS += c-utility/src/azure_base32.o
+OBJECTS += c-utility/src/azure_base64.o
+OBJECTS += c-utility/src/buffer.o
+OBJECTS += c-utility/src/connection_string_parser.o
+OBJECTS += c-utility/src/consolelogger.o
+OBJECTS += c-utility/src/constbuffer.o
+OBJECTS += c-utility/src/constmap.o
+OBJECTS += c-utility/src/crt_abstractions.o
+#OBJECTS += c-utility/src/dns_resolver_sync.o
+OBJECTS += c-utility/src/doublylinkedlist.o
+OBJECTS += c-utility/src/gb_rand.o
+OBJECTS += c-utility/src/gb_stdio.o
+OBJECTS += c-utility/src/gb_time.o
+OBJECTS += c-utility/src/gballoc.o
+OBJECTS += c-utility/src/hmac.o
+OBJECTS += c-utility/src/hmacsha256.o
+OBJECTS += c-utility/src/http_proxy_io.o
+OBJECTS += c-utility/src/httpapiex.o
+OBJECTS += c-utility/src/httpapiexsas.o
+OBJECTS += c-utility/src/httpheaders.o
+OBJECTS += c-utility/src/map.o
+OBJECTS += c-utility/src/optionhandler.o
+OBJECTS += c-utility/src/sastoken.o
+OBJECTS += c-utility/src/sha1.o
+OBJECTS += c-utility/src/sha224.o
+OBJECTS += c-utility/src/sha384-512.o
+OBJECTS += c-utility/src/singlylinkedlist.o
+OBJECTS += c-utility/src/string_token.o
+OBJECTS += c-utility/src/string_tokenizer.o
+OBJECTS += c-utility/src/strings.o
+OBJECTS += c-utility/src/urlencode.o
+OBJECTS += c-utility/src/usha.o
+OBJECTS += c-utility/src/utf8_checker.o
+OBJECTS += c-utility/src/uuid.o
+OBJECTS += c-utility/src/uws_client.o
+OBJECTS += c-utility/src/uws_frame_encoder.o
+OBJECTS += c-utility/src/vector.o
+OBJECTS += c-utility/src/wsio.o
+OBJECTS += c-utility/src/xio.o
+OBJECTS += c-utility/src/xlogging.o
+OBJECTS += certs/certs.o
+OBJECTS += deps/parson/parson.o
+OBJECTS += iothub_client/src/blob.o
+OBJECTS += iothub_client/src/iothub.o
+OBJECTS += iothub_client/src/iothub_client.o
+OBJECTS += iothub_client/src/iothub_client_authorization.o
+OBJECTS += iothub_client/src/iothub_client_core.o
+OBJECTS += iothub_client/src/iothub_client_core_ll.o
+OBJECTS += iothub_client/src/iothub_client_diagnostic.o
+OBJECTS += iothub_client/src/iothub_client_ll.o
+OBJECTS += iothub_client/src/iothub_client_ll_uploadtoblob.o
+OBJECTS += iothub_client/src/iothub_client_retry_control.o
+OBJECTS += iothub_client/src/iothub_device_client_ll.o
+OBJECTS += iothub_client/src/iothub_message.o
+OBJECTS += iothub_client/src/iothub_transport_ll_private.o
+OBJECTS += iothub_client/src/iothubtransport.o
+OBJECTS += iothub_client/src/iothubtransport_mqtt_common.o
+OBJECTS += iothub_client/src/iothubtransporthttp.o
+OBJECTS += iothub_client/src/iothubtransportmqtt.o
+OBJECTS += iothub_client/src/iothubtransportmqtt_websockets.o
+OBJECTS += iothub_client/src/version.o
+OBJECTS += provisioning_client/adapters/hsm_client_data.o
+OBJECTS += provisioning_client/adapters/hsm_client_key.o
+OBJECTS += provisioning_client/src/iothub_auth_client.o
+OBJECTS += provisioning_client/src/iothub_security_factory.o
+OBJECTS += provisioning_client/src/prov_auth_client.o
+OBJECTS += provisioning_client/src/prov_device_client.o
+OBJECTS += provisioning_client/src/prov_device_ll_client.o
+OBJECTS += provisioning_client/src/prov_security_factory.o
+OBJECTS += provisioning_client/src/prov_transport_http_client.o
+OBJECTS += provisioning_client/src/prov_transport_mqtt_client.o
+OBJECTS += provisioning_client/src/prov_transport_mqtt_common.o
+OBJECTS += provisioning_client/src/prov_transport_mqtt_ws_client.o
+OBJECTS += serializer/src/methodreturn.o
+OBJECTS += serializer/src/multitree.o
+OBJECTS += serializer/src/schema.o
+OBJECTS += serializer/src/schemalib.o
+OBJECTS += serializer/src/schemaserializer.o
+OBJECTS += serializer/src/datamarshaller.o
+OBJECTS += serializer/src/datapublisher.o
+OBJECTS += serializer/src/dataserializer.o
+OBJECTS += serializer/src/iotdevice.o
+OBJECTS += serializer/src/jsondecoder.o
+OBJECTS += serializer/src/jsonencoder.o
+OBJECTS += serializer/src/agenttypesystem.o
+OBJECTS += serializer/src/codefirst.o
+OBJECTS += serializer/src/commanddecoder.o
+OBJECTS += uhttp/src/uhttp.o
+OBJECTS += umqtt/src/mqtt_client.o
+OBJECTS += umqtt/src/mqtt_codec.o
+OBJECTS += umqtt/src/mqtt_message.o
+
+INCLUDE_PATHS += -I../../asp_baseplatform
+INCLUDE_PATHS += -I../../asp_baseplatform/include
+INCLUDE_PATHS += -I../../asp_baseplatform/arch
+INCLUDE_PATHS += -I../../asp_baseplatform/arch/arm_m_gcc/common
+INCLUDE_PATHS += -I../../asp_baseplatform/arch/arm_m_gcc/stm32f7xx
+INCLUDE_PATHS += -I../../asp_baseplatform/target/stm32f767nucleo144_gcc
+INCLUDE_PATHS += -I../../asp_baseplatform/lwip/lwip-2.1.2/src/include
+INCLUDE_PATHS += -I../../asp_baseplatform/lwip/lwip-2.1.2/src/include/compat/posix
+INCLUDE_PATHS += -I../../asp_baseplatform/lwip/contrib-2.1.0/ports/toppers/include
+INCLUDE_PATHS += -I../../asp_baseplatform/lwip/contrib-2.1.0
+INCLUDE_PATHS += -I../../asp_baseplatform/OBJ/STM32F767NUCLEO144_GCC/MAC
+INCLUDE_PATHS += -I../../asp_baseplatform/monitor
+INCLUDE_PATHS += -I../../asp_baseplatform/files
+INCLUDE_PATHS += -I../../azure_iot_sdk/c-utility/inc
+INCLUDE_PATHS += -I../../azure_iot_sdk/c-utility/pal/toppers
+INCLUDE_PATHS += -I../../azure_iot_sdk/iothub_client/inc
+INCLUDE_PATHS += -I../../azure_iot_sdk/iothub_client/inc/internal
+INCLUDE_PATHS += -I../../azure_iot_sdk/provisioning_client/adapters
+INCLUDE_PATHS += -I../../azure_iot_sdk/provisioning_client/inc
+INCLUDE_PATHS += -I../../azure_iot_sdk/provisioning_client/inc/azure_prov_client/internal
+INCLUDE_PATHS += -I../../azure_iot_sdk/deps/parson
+INCLUDE_PATHS += -I../../azure_iot_sdk/deps/azure-macro-utils-c/inc
+INCLUDE_PATHS += -I../../azure_iot_sdk/deps/umock-c/inc
+INCLUDE_PATHS += -I../../azure_iot_sdk/serializer/inc
+INCLUDE_PATHS += -I../../azure_iot_sdk/uhttp/inc
+INCLUDE_PATHS += -I../../azure_iot_sdk/umqtt/inc
+INCLUDE_PATHS += -I../../wolfssl-4.4.0/wolfssl
+INCLUDE_PATHS += -I../../wolfssl-4.4.0/wolfssl/wolfcrypt
+INCLUDE_PATHS += -I../../wolfssl-4.4.0
+INCLUDE_PATHS += -I../../zlib-1.2.11/src
+
+# Objects and Paths
+###############################################################################
+# Tools and Flags
+
+AS      = arm-none-eabi-gcc
+CC      = arm-none-eabi-gcc
+CPP     = arm-none-eabi-g++
+AR      = arm-none-eabi-ar
+RANLIB  = arm-none-eabi-ranlib
+
+
+C_FLAGS += -std=gnu11
+C_FLAGS += -mcpu=cortex-m4
+C_FLAGS += -march=armv7e-m
+C_FLAGS += -mthumb
+C_FLAGS += -mlittle-endian
+C_FLAGS += -mfloat-abi=hard
+C_FLAGS += -mfpu=fpv4-sp-d16
+C_FLAGS += -Os
+C_FLAGS += -fmessage-length=0
+C_FLAGS += -fsigned-char
+C_FLAGS += -ffunction-sections
+C_FLAGS += -fdata-sections
+C_FLAGS += -Wall
+C_FLAGS += -Wextra
+C_FLAGS += -Wno-unused-parameter
+C_FLAGS += -Wno-missing-field-initializers
+C_FLAGS += -Wnull-dereference
+
+C_FLAGS += -Wno-unused-variable
+C_FLAGS += -Wno-unused-function
+
+C_FLAGS += -g3
+C_FLAGS += -Wstack-usage=256
+
+C_FLAGS += -DWOLFSSL_USER_SETTINGS
+C_FLAGS += -DCYASSL_USER_SETTINGS
+C_FLAGS += -DUSE_WOLFSSL=1
+C_FLAGS += -DHSM_TYPE_SYMM_KEY
+C_FLAGS += -DUSE_PROV_MODULE
+C_FLAGS += -Dget_time=azure_get_time
+
+CXX_FLAGS += -std=gnu++11
+CXX_FLAGS += -mcpu=cortex-m4
+CXX_FLAGS += -march=armv7e-m
+CXX_FLAGS += -mthumb
+CXX_FLAGS += -mlittle-endian
+CXX_FLAGS += -mfloat-abi=hard
+CXX_FLAGS += -mfpu=fpv4-sp-d16
+CXX_FLAGS += -Os
+CXX_FLAGS += -fmessage-length=0
+CXX_FLAGS += -fsigned-char
+CXX_FLAGS += -ffunction-sections
+CXX_FLAGS += -fdata-sections
+CXX_FLAGS += -Wall
+CXX_FLAGS += -Wextra
+CXX_FLAGS += -Wno-unused-parameter
+CXX_FLAGS += -Wno-missing-field-initializers
+CXX_FLAGS += -Wnull-dereference
+
+CXX_FLAGS += -g3
+CXX_FLAGS += -Wstack-usage=256
+
+CXX_FLAGS += -DWOLFSSL_USER_SETTINGS
+CXX_FLAGS += -DCYASSL_USER_SETTINGS
+CXX_FLAGS += -DUSE_WOLFSSL=1
+CXX_FLAGS += -DHSM_TYPE_SYMM_KEY
+CXX_FLAGS += -DUSE_PROV_MODULE
+CXX_FLAGS += -Dget_time=azure_get_time
+
+ASM_FLAGS += -x
+ASM_FLAGS += assembler-with-cpp
+ASM_FLAGS += -mcpu=cortex-m4
+ASM_FLAGS += -march=armv7e-m
+ASM_FLAGS += -mthumb
+ASM_FLAGS += -mlittle-endian
+ASM_FLAGS += -mfloat-abi=hard
+ASM_FLAGS += -mfpu=fpv4-sp-d16
+ASM_FLAGS += -Os
+ASM_FLAGS += -fmessage-length=0
+ASM_FLAGS += -fsigned-char
+ASM_FLAGS += -ffunction-sections
+ASM_FLAGS += -fdata-sections
+ASM_FLAGS += -Wall
+ASM_FLAGS += -Wextra
+ASM_FLAGS += -Wno-unused-parameter
+ASM_FLAGS += -Wno-missing-field-initializers
+ASM_FLAGS += -Wnull-dereference
+ASM_FLAGS += -g3
+ASM_FLAGS += -Wstack-usage=256
+
+
+# Tools and Flags
+###############################################################################
+# Rules
+
+.PHONY: all lst size
+
+
+all: lib$(PROJECT).a
+
+
+.s.o:
+	+@$(call MAKEDIR,$(dir $@))
+	+@echo "Assemble: $(notdir $<)"
+	@$(AS) -c $(ASM_FLAGS) -o $@ $<
+
+
+.S.o:
+	+@$(call MAKEDIR,$(dir $@))
+	+@echo "Assemble: $(notdir $<)"
+	@$(AS) -c $(ASM_FLAGS) -o $@ $<
+
+.c.o:
+	+@$(call MAKEDIR,$(dir $@))
+	+@echo "Compile: $(notdir $<)"
+	@$(CC) $(C_FLAGS) $(INCLUDE_PATHS) -MMD -MP -MF"$(@:%.o=%.d)" -MT"$(@)" -c -o "$@" "$<"
+
+.cpp.o:
+	+@$(call MAKEDIR,$(dir $@))
+	+@echo "Compile: $(notdir $<)"
+	@$(CPP) $(CXX_FLAGS) $(INCLUDE_PATHS) -MMD -MP -MF"$(@:%.o=%.d)" -MT"$(@)" -c -o "$@" "$<"
+
+lib$(PROJECT).a: $(OBJECTS)
+	rm -f lib$(PROJECT).a
+	$(AR) -rcs lib$(PROJECT).a $(OBJECTS)
+	$(RANLIB) lib$(PROJECT).a
+
+
+
+# Rules
+###############################################################################
+# Dependencies
+
+DEPS = $(OBJECTS:.o=.d) $(SYS_OBJECTS:.o=.d)
+-include $(DEPS)
+endif
+
+# Dependencies
+###############################################################################
Index: azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/adapters/agenttime_mbed.c
===================================================================
--- azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/adapters/agenttime_mbed.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/adapters/agenttime_mbed.c	(revision 457)
@@ -0,0 +1,28 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+#include "azure_c_shared_utility/agenttime.h"
+
+// mbed version of gmtime() returns NULL.
+// system RTC should be set to UTC as its localtime 
+
+time_t get_time(time_t* currentTime)
+{
+    return time(currentTime);
+}
+
+double get_difftime(time_t stopTime, time_t startTime)
+{
+    return difftime(stopTime, startTime);
+}
+
+
+struct tm* get_gmtime(time_t* currentTime)
+{
+    return localtime(currentTime);
+}
+
+char* get_ctime(time_t* timeToGet)
+{
+    return ctime(timeToGet);
+}
Index: azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/adapters/httpapi_compact.c
===================================================================
--- azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/adapters/httpapi_compact.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/adapters/httpapi_compact.c	(revision 457)
@@ -0,0 +1,1573 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <ctype.h>
+#include <string.h>
+#include <limits.h>
+
+#include "azure_macro_utils/macro_utils.h"
+#include "azure_c_shared_utility/gballoc.h"
+#include "azure_c_shared_utility/httpheaders.h"
+#include "azure_c_shared_utility/crt_abstractions.h"
+#include "azure_c_shared_utility/xlogging.h"
+#include "azure_c_shared_utility/xio.h"
+#include "azure_c_shared_utility/platform.h"
+#include "azure_c_shared_utility/tlsio.h"
+#include "azure_c_shared_utility/threadapi.h"
+#include "azure_c_shared_utility/shared_util_options.h"
+#include "azure_c_shared_utility/http_proxy_io.h"
+
+#ifdef _MSC_VER
+#define snprintf _snprintf
+#endif
+
+/*Codes_SRS_HTTPAPI_COMPACT_21_001: [ The httpapi_compact shall implement the methods defined by the httpapi.h. ]*/
+/*Codes_SRS_HTTPAPI_COMPACT_21_002: [ The httpapi_compact shall support the http requests. ]*/
+/*Codes_SRS_HTTPAPI_COMPACT_21_003: [ The httpapi_compact shall return error codes defined by HTTPAPI_RESULT. ]*/
+#include "azure_c_shared_utility/httpapi.h"
+
+#define MAX_HOSTNAME     64
+#define TEMP_BUFFER_SIZE 1024
+
+/*Codes_SRS_HTTPAPI_COMPACT_21_077: [ The HTTPAPI_ExecuteRequest shall wait, at least, 10 seconds for the SSL open process. ]*/
+#define MAX_OPEN_RETRY   100
+/*Codes_SRS_HTTPAPI_COMPACT_21_084: [ The HTTPAPI_CloseConnection shall wait, at least, 10 seconds for the SSL close process. ]*/
+#define MAX_CLOSE_RETRY   100
+/*Codes_SRS_HTTPAPI_COMPACT_21_079: [ The HTTPAPI_ExecuteRequest shall wait, at least, 20 seconds to send a buffer using the SSL connection. ]*/
+#define MAX_SEND_RETRY   200
+/*Codes_SRS_HTTPAPI_COMPACT_21_081: [ The HTTPAPI_ExecuteRequest shall try to read the message with the response up to 20 seconds. ]*/
+#define MAX_RECEIVE_RETRY   200
+/*Codes_SRS_HTTPAPI_COMPACT_21_083: [ The HTTPAPI_ExecuteRequest shall wait, at least, 100 milliseconds between retries. ]*/
+#define RETRY_INTERVAL_IN_MICROSECONDS  100
+
+MU_DEFINE_ENUM_STRINGS(HTTPAPI_RESULT, HTTPAPI_RESULT_VALUES)
+
+typedef struct HTTP_HANDLE_DATA_TAG
+{
+    char*           hostName;
+    char*           certificate;
+    char*           x509ClientCertificate;
+    char*           x509ClientPrivateKey;
+    const char*     proxy_host;
+    int             proxy_port;
+    const char*     proxy_username;
+    const char*     proxy_password;
+    XIO_HANDLE      xio_handle;
+    size_t          received_bytes_count;
+    unsigned char*  received_bytes;
+    unsigned int    is_io_error : 1;
+    unsigned int    is_connected : 1;
+    unsigned int    send_completed : 1;
+} HTTP_HANDLE_DATA;
+
+/*the following function does the same as sscanf(pos2, "%d", &sec)*/
+/*this function only exists because some of platforms do not have sscanf. */
+static int ParseStringToDecimal(const char *src, int* dst)
+{
+    int result;
+    char* next;
+    long num = strtol(src, &next, 0);
+    if (src == next || num < INT_MIN || num > INT_MAX)
+    {
+        result = EOF;
+    }
+    else
+    {
+        result = 1;
+    }
+    if (num < INT_MIN) num = INT_MIN;
+    if (num > INT_MAX) num = INT_MAX;
+    *dst = (int)num;
+    return result;
+}
+
+/*the following function does the same as sscanf(pos2, "%x", &sec)*/
+/*this function only exists because some of platforms do not have sscanf. This is not a full implementation; it only works with well-defined x numbers. */
+#define HEXA_DIGIT_VAL(c)         (((c>='0') && (c<='9')) ? (c-'0') : ((c>='a') && (c<='f')) ? (c-'a'+10) : ((c>='A') && (c<='F')) ? (c-'A'+10) : -1)
+static int ParseStringToHexadecimal(const char *src, size_t* dst)
+{
+    int result;
+    int digitVal;
+    if (src == NULL)
+    {
+        result = EOF;
+    }
+    else if (HEXA_DIGIT_VAL(*src) == -1)
+    {
+        result = EOF;
+    }
+    else
+    {
+        (*dst) = 0;
+        while ((digitVal = HEXA_DIGIT_VAL(*src)) != -1)
+        {
+            (*dst) *= 0x10;
+            (*dst) += (size_t)digitVal;
+            src++;
+        }
+        result = 1;
+    }
+    return result;
+}
+
+/*the following function does the same as sscanf(buf, "HTTP/%*d.%*d %d %*[^\r\n]", &ret) */
+/*this function only exists because some of platforms do not have sscanf. This is not a full implementation; it only works with well-defined HTTP response. */
+static int  ParseHttpResponse(const char* src, int* dst)
+{
+    int result;
+    static const char HTTPPrefix[] = "HTTP/";
+    bool fail;
+    const char* runPrefix;
+
+    if ((src == NULL) || (dst == NULL))
+    {
+        result = EOF;
+    }
+    else
+    {
+        fail = false;
+        runPrefix = HTTPPrefix;
+
+        while((*runPrefix) != '\0')
+        {
+            if ((*runPrefix) != (*src))
+            {
+                fail = true;
+                break;
+            }
+            src++;
+            runPrefix++;
+        }
+
+        if (!fail)
+        {
+            while ((*src) != '.')
+            {
+                if ((*src) == '\0')
+                {
+                    fail = true;
+                    break;
+                }
+                src++;
+            }
+        }
+
+        if (!fail)
+        {
+            while ((*src) != ' ')
+            {
+                if ((*src) == '\0')
+                {
+                    fail = true;
+                    break;
+                }
+                src++;
+            }
+        }
+
+        if (fail)
+        {
+            result = EOF;
+        }
+        else
+        {
+            result = ParseStringToDecimal(src, dst);
+        }
+    }
+
+    return result;
+}
+
+HTTPAPI_RESULT HTTPAPI_Init(void)
+{
+/*Codes_SRS_HTTPAPI_COMPACT_21_004: [ The HTTPAPI_Init shall allocate all memory to control the http protocol. ]*/
+/*Codes_SRS_HTTPAPI_COMPACT_21_007: [ If there is not enough memory to control the http protocol, the HTTPAPI_Init shall return HTTPAPI_ALLOC_FAILED. ]*/
+/**
+ * No memory is necessary.
+ */
+
+ /*Codes_SRS_HTTPAPI_COMPACT_21_006: [ If HTTPAPI_Init succeed allocating all the needed memory, it shall return HTTPAPI_OK. ]*/
+return HTTPAPI_OK;
+}
+
+void HTTPAPI_Deinit(void)
+{
+    /*Codes_SRS_HTTPAPI_COMPACT_21_009: [ The HTTPAPI_Init shall release all memory allocated by the httpapi_compact. ]*/
+    /**
+    * No memory was necessary.
+    */
+}
+
+/*Codes_SRS_HTTPAPI_COMPACT_21_011: [ The HTTPAPI_CreateConnection shall create an http connection to the host specified by the hostName parameter. ]*/
+HTTP_HANDLE HTTPAPI_CreateConnection(const char* hostName)
+{
+    HTTP_HANDLE_DATA* http_instance;
+
+    if (hostName == NULL)
+    {
+        /*Codes_SRS_HTTPAPI_COMPACT_21_014: [ If the hostName is NULL, the HTTPAPI_CreateConnection shall return NULL as the handle. ]*/
+        LogError("Invalid host name. Null hostName parameter.");
+        http_instance = NULL;
+    }
+    else if (*hostName == '\0')
+    {
+        /*Codes_SRS_HTTPAPI_COMPACT_21_015: [ If the hostName is empty, the HTTPAPI_CreateConnection shall return NULL as the handle. ]*/
+        LogError("Invalid host name. Empty string.");
+        http_instance = NULL;
+    }
+    else
+    {
+        http_instance = (HTTP_HANDLE_DATA*)malloc(sizeof(HTTP_HANDLE_DATA));
+        /*Codes_SRS_HTTPAPI_COMPACT_21_013: [ If there is not enough memory to control the http connection, the HTTPAPI_CreateConnection shall return NULL as the handle. ]*/
+        if (http_instance == NULL)
+        {
+            LogError("There is no memory to control the http connection");
+        }
+        else if(mallocAndStrcpy_s((char**)&(http_instance->hostName), hostName) != 0)
+        {
+            LogError("failure allocate host name");
+            free(http_instance);
+            http_instance = NULL;
+        }
+        else
+        {
+            http_instance->xio_handle = NULL;
+            http_instance->is_connected = 0;
+            http_instance->is_io_error = 0;
+            http_instance->received_bytes_count = 0;
+            http_instance->received_bytes = NULL;
+            http_instance->certificate = NULL;
+            http_instance->x509ClientCertificate = NULL;
+            http_instance->x509ClientPrivateKey = NULL;
+            http_instance->proxy_host = NULL;
+            http_instance->proxy_port = 0;
+            http_instance->proxy_username = NULL;
+            http_instance->proxy_password = NULL;
+        }
+    }
+
+    /*Codes_SRS_HTTPAPI_COMPACT_21_012: [ The HTTPAPI_CreateConnection shall return a non-NULL handle on success. ]*/
+    return (HTTP_HANDLE)http_instance;
+}
+
+static void on_io_close_complete(void* context)
+{
+    HTTP_HANDLE_DATA* http_instance = (HTTP_HANDLE_DATA*)context;
+
+    if (http_instance != NULL)
+    {
+        http_instance->is_connected = 0;
+    }
+}
+
+void HTTPAPI_CloseConnection(HTTP_HANDLE handle)
+{
+    HTTP_HANDLE_DATA* http_instance = (HTTP_HANDLE_DATA*)handle;
+
+    /*Codes_SRS_HTTPAPI_COMPACT_21_020: [ If the connection handle is NULL, the HTTPAPI_CloseConnection shall not do anything. ]*/
+    if (http_instance != NULL)
+    {
+        /*Codes_SRS_HTTPAPI_COMPACT_21_019: [ If there is no previous connection, the HTTPAPI_CloseConnection shall not do anything. ]*/
+        if (http_instance->xio_handle != NULL)
+        {
+            http_instance->is_io_error = 0;
+            /*Codes_SRS_HTTPAPI_COMPACT_21_017: [ The HTTPAPI_CloseConnection shall close the connection previously created in HTTPAPI_ExecuteRequest. ]*/
+            if (xio_close(http_instance->xio_handle, on_io_close_complete, http_instance) != 0)
+            {
+                LogError("The SSL got error closing the connection");
+                /*Codes_SRS_HTTPAPI_COMPACT_21_087: [ If the xio return anything different than 0, the HTTPAPI_CloseConnection shall destroy the connection anyway. ]*/
+                http_instance->is_connected = 0;
+            }
+            else
+            {
+                /*Codes_SRS_HTTPAPI_COMPACT_21_084: [ The HTTPAPI_CloseConnection shall wait, at least, 10 seconds for the SSL close process. ]*/
+                int countRetry = MAX_CLOSE_RETRY;
+                while (http_instance->is_connected == 1)
+                {
+                    xio_dowork(http_instance->xio_handle);
+                    if ((countRetry--) < 0)
+                    {
+                        /*Codes_SRS_HTTPAPI_COMPACT_21_085: [ If the HTTPAPI_CloseConnection retries 10 seconds to close the connection without success, it shall destroy the connection anyway. ]*/
+                        LogError("Close timeout. The SSL didn't close the connection");
+                        http_instance->is_connected = 0;
+                    }
+                    else if (http_instance->is_io_error == 1)
+                    {
+                        LogError("The SSL got error closing the connection");
+                        http_instance->is_connected = 0;
+                    }
+                    else if (http_instance->is_connected == 1)
+                    {
+                        LogInfo("Waiting for TLS close connection");
+                        /*Codes_SRS_HTTPAPI_COMPACT_21_086: [ The HTTPAPI_CloseConnection shall wait, at least, 100 milliseconds between retries. ]*/
+                        ThreadAPI_Sleep(RETRY_INTERVAL_IN_MICROSECONDS);
+                    }
+                }
+            }
+            /*Codes_SRS_HTTPAPI_COMPACT_21_076: [ After close the connection, The HTTPAPI_CloseConnection shall destroy the connection previously created in HTTPAPI_CreateConnection. ]*/
+            xio_destroy(http_instance->xio_handle);
+        }
+
+        if (http_instance->hostName != NULL)
+        {
+            free((void*)http_instance->hostName);
+        }
+
+#ifndef DO_NOT_COPY_TRUSTED_CERTS_STRING
+        /*Codes_SRS_HTTPAPI_COMPACT_21_018: [ If there is a certificate associated to this connection, the HTTPAPI_CloseConnection shall free all allocated memory for the certificate. ]*/
+        if (http_instance->certificate)
+        {
+            free(http_instance->certificate);
+        }
+#endif
+
+        /*Codes_SRS_HTTPAPI_COMPACT_06_001: [ If there is a x509 client certificate associated to this connection, the HTTAPI_CloseConnection shall free all allocated memory for the certificate. ]*/
+        if (http_instance->x509ClientCertificate)
+        {
+            free(http_instance->x509ClientCertificate);
+        }
+
+        /*Codes_SRS_HTTPAPI_COMPACT_06_002: [ If there is a x509 client private key associated to this connection, then HTTP_CloseConnection shall free all the allocated memory for the private key. ]*/
+        if (http_instance->x509ClientPrivateKey)
+        {
+            free(http_instance->x509ClientPrivateKey);
+        }
+
+        if (http_instance->proxy_host != NULL)
+        {
+            free((void*)http_instance->proxy_host);
+        }
+        if (http_instance->proxy_username != NULL)
+        {
+            free((void*)http_instance->proxy_username);
+        }
+        if (http_instance->proxy_password != NULL)
+        {
+            free((void*)http_instance->proxy_password);
+        }
+
+        free(http_instance);
+    }
+}
+
+static void on_io_open_complete(void* context, IO_OPEN_RESULT open_result)
+{
+    HTTP_HANDLE_DATA* http_instance = (HTTP_HANDLE_DATA*)context;
+
+    if (http_instance != NULL)
+    {
+        if (open_result == IO_OPEN_OK)
+        {
+            http_instance->is_connected = 1;
+            http_instance->is_io_error = 0;
+        }
+        else
+        {
+            http_instance->is_io_error = 1;
+        }
+    }
+}
+
+static void on_send_complete(void* context, IO_SEND_RESULT send_result)
+{
+    HTTP_HANDLE_DATA* http_instance = (HTTP_HANDLE_DATA*)context;
+
+    if (http_instance != NULL)
+    {
+        if (send_result == IO_SEND_OK)
+        {
+            http_instance->send_completed = 1;
+            http_instance->is_io_error = 0;
+        }
+        else
+        {
+            http_instance->is_io_error = 1;
+        }
+    }
+}
+
+#define TOLOWER(c) (((c>='A') && (c<='Z'))?c-'A'+'a':c)
+static int InternStrnicmp(const char* s1, const char* s2, size_t n)
+{
+    int result;
+
+    if (s1 == NULL) result = -1;
+    else if (s2 == NULL) result = 1;
+    else
+    {
+        result = 0;
+
+        while(n-- && result == 0)
+        {
+            if (*s1 == 0) result = -1;
+            else if (*s2 == 0) result = 1;
+            else
+            {
+
+                result = TOLOWER(*s1) - TOLOWER(*s2);
+                ++s1;
+                ++s2;
+            }
+        }
+    }
+
+    return result;
+}
+
+static void on_bytes_received(void* context, const unsigned char* buffer, size_t size)
+{
+    unsigned char* new_received_bytes;
+    HTTP_HANDLE_DATA* http_instance = (HTTP_HANDLE_DATA*)context;
+
+    if (http_instance != NULL)
+    {
+
+        if (buffer == NULL)
+        {
+            http_instance->is_io_error = 1;
+            LogError("NULL pointer error");
+        }
+        else
+        {
+            /* Here we got some bytes so we'll buffer them so the receive functions can consumer it */
+            new_received_bytes = (unsigned char*)realloc(http_instance->received_bytes, http_instance->received_bytes_count + size);
+            if (new_received_bytes == NULL)
+            {
+                http_instance->is_io_error = 1;
+                LogError("Error allocating memory for received data");
+            }
+            else
+            {
+                http_instance->received_bytes = new_received_bytes;
+                if (memcpy(http_instance->received_bytes + http_instance->received_bytes_count, buffer, size) == NULL)
+                {
+                    http_instance->is_io_error = 1;
+                    LogError("Error copping received data to the HTTP bufffer");
+                }
+                else
+                {
+                    http_instance->received_bytes_count += size;
+                }
+            }
+        }
+    }
+}
+
+static void on_io_error(void* context)
+{
+    HTTP_HANDLE_DATA* http_instance = (HTTP_HANDLE_DATA*)context;
+    if (http_instance != NULL)
+    {
+        http_instance->is_io_error = 1;
+        LogError("Error signalled by underlying IO");
+    }
+}
+
+static int conn_receive(HTTP_HANDLE_DATA* http_instance, char* buffer, int count)
+{
+    int result;
+
+    if ((http_instance == NULL) || (buffer == NULL) || (count < 0))
+    {
+        LogError("conn_receive: %s", ((http_instance == NULL) ? "Invalid HTTP instance" : "Invalid HTTP buffer"));
+        result = -1;
+    }
+    else
+    {
+        result = 0;
+        while (result < count)
+        {
+            xio_dowork(http_instance->xio_handle);
+
+            /* if any error was detected while receiving then simply break and report it */
+            if (http_instance->is_io_error != 0)
+            {
+                LogError("xio reported error on dowork");
+                result = -1;
+                break;
+            }
+
+            if (http_instance->received_bytes_count >= (size_t)count)
+            {
+                /* Consuming bytes from the receive buffer */
+                (void)memcpy(buffer, http_instance->received_bytes, count);
+                (void)memmove(http_instance->received_bytes, http_instance->received_bytes + count, http_instance->received_bytes_count - count);
+                http_instance->received_bytes_count -= count;
+
+                /* we're not reallocating at each consumption so that we don't trash due to byte by byte consumption */
+                if (http_instance->received_bytes_count == 0)
+                {
+                    free(http_instance->received_bytes);
+                    http_instance->received_bytes = NULL;
+                }
+
+                result = count;
+                break;
+            }
+
+            /*Codes_SRS_HTTPAPI_COMPACT_21_083: [ The HTTPAPI_ExecuteRequest shall wait, at least, 100 milliseconds between retries. ]*/
+            ThreadAPI_Sleep(RETRY_INTERVAL_IN_MICROSECONDS);
+        }
+    }
+
+    return result;
+}
+
+static void conn_receive_discard_buffer(HTTP_HANDLE_DATA* http_instance)
+{
+    if (http_instance != NULL)
+    {
+        if (http_instance->received_bytes != NULL)
+        {
+            free(http_instance->received_bytes);
+            http_instance->received_bytes = NULL;
+        }
+        http_instance->received_bytes_count = 0;
+    }
+}
+
+static int readLine(HTTP_HANDLE_DATA* http_instance, char* buf, const size_t maxBufSize)
+{
+    int resultLineSize;
+
+    if ((http_instance == NULL) || (buf == NULL) || (maxBufSize == 0))
+    {
+        LogError("%s", ((http_instance == NULL) ? "Invalid HTTP instance" : "Invalid HTTP buffer"));
+        resultLineSize = -1;
+    }
+    else
+    {
+        char* destByte = buf;
+        /*Codes_SRS_HTTPAPI_COMPACT_21_081: [ The HTTPAPI_ExecuteRequest shall try to read the message with the response up to 20 seconds. ]*/
+        int countRetry = MAX_RECEIVE_RETRY;
+        bool endOfSearch = false;
+        resultLineSize = -1;
+        while (!endOfSearch)
+        {
+            xio_dowork(http_instance->xio_handle);
+
+            /* if any error was detected while receiving then simply break and report it */
+            if (http_instance->is_io_error != 0)
+            {
+                LogError("xio reported error on dowork");
+                endOfSearch = true;
+            }
+            else
+            {
+                unsigned char* receivedByte = http_instance->received_bytes;
+                while (receivedByte < (http_instance->received_bytes + http_instance->received_bytes_count))
+                {
+                    if ((*receivedByte) != '\r')
+                    {
+                        (*destByte) = (*receivedByte);
+                        destByte++;
+                        receivedByte++;
+
+                        if (destByte >= (buf + maxBufSize - 1))
+                        {
+                            LogError("Received message is bigger than the http buffer");
+                            receivedByte = http_instance->received_bytes + http_instance->received_bytes_count;
+                            endOfSearch = true;
+                            break;
+                        }
+                    }
+                    else
+                    {
+                        receivedByte++;
+                        if ((receivedByte < (http_instance->received_bytes + http_instance->received_bytes_count)) && ((*receivedByte) == '\n'))
+                        {
+                            receivedByte++;
+                        }
+                        (*destByte) = '\0';
+                        resultLineSize = (int)(destByte - buf);
+                        endOfSearch = true;
+                        break;
+                    }
+                }
+
+                http_instance->received_bytes_count -= (receivedByte - http_instance->received_bytes);
+                if (http_instance->received_bytes_count != 0)
+                {
+                    (void)memmove(http_instance->received_bytes, receivedByte, http_instance->received_bytes_count);
+                }
+                else
+                {
+                    conn_receive_discard_buffer(http_instance);
+                }
+            }
+
+            if (!endOfSearch)
+            {
+                if ((countRetry--) > 0)
+                {
+                    /*Codes_SRS_HTTPAPI_COMPACT_21_083: [ The HTTPAPI_ExecuteRequest shall wait, at least, 100 milliseconds between retries. ]*/
+                    ThreadAPI_Sleep(RETRY_INTERVAL_IN_MICROSECONDS);
+                }
+                else
+                {
+                    /*Codes_SRS_HTTPAPI_COMPACT_21_082: [ If the HTTPAPI_ExecuteRequest retries 20 seconds to receive the message without success, it shall fail and return HTTPAPI_READ_DATA_FAILED. ]*/
+                    LogError("Receive timeout. The HTTP request is incomplete");
+                    endOfSearch = true;
+                }
+            }
+        }
+    }
+
+    return resultLineSize;
+}
+
+static int readChunk(HTTP_HANDLE_DATA* http_instance, char* buf, size_t size)
+{
+    int cur, offset;
+
+    // read content with specified length, even if it is received
+    // only in chunks due to fragmentation in the networking layer.
+    // returns -1 in case of error.
+    offset = 0;
+    while (size > (size_t)0)
+    {
+        cur = conn_receive(http_instance, buf + offset, (int)size);
+
+        // end of stream reached
+        if (cur == 0)
+        {
+            break;
+        }
+
+        // read cur bytes (might be less than requested)
+        size -= (size_t)cur;
+        offset += cur;
+    }
+
+    return offset;
+}
+
+static int skipN(HTTP_HANDLE_DATA* http_instance, size_t n)
+{
+    // read and abandon response content with specified length
+    // returns -1 in case of error.
+
+    int result;
+
+    if (http_instance == NULL)
+    {
+        LogError("Invalid HTTP instance");
+        result = -1;
+    }
+    else
+    {
+        /*Codes_SRS_HTTPAPI_COMPACT_21_081: [ The HTTPAPI_ExecuteRequest shall try to read the message with the response up to 20 seconds. ]*/
+        int countRetry = MAX_RECEIVE_RETRY;
+        result = (int)n;
+        while (n > 0)
+        {
+            xio_dowork(http_instance->xio_handle);
+
+            /* if any error was detected while receiving then simply break and report it */
+            if (http_instance->is_io_error != 0)
+            {
+                LogError("xio reported error on dowork");
+                result = -1;
+                n = 0;
+            }
+            else
+            {
+                if (http_instance->received_bytes_count <= n)
+                {
+                    n -= http_instance->received_bytes_count;
+                    http_instance->received_bytes_count = 0;
+                }
+                else
+                {
+                    http_instance->received_bytes_count -= n;
+                    (void)memmove(http_instance->received_bytes, http_instance->received_bytes + n, http_instance->received_bytes_count);
+                    n = 0;
+                }
+
+                if (n > 0)
+                {
+                    if ((countRetry--) > 0)
+                    {
+                        /*Codes_SRS_HTTPAPI_COMPACT_21_083: [ The HTTPAPI_ExecuteRequest shall wait, at least, 100 milliseconds between retries. ]*/
+                        ThreadAPI_Sleep(RETRY_INTERVAL_IN_MICROSECONDS);
+                    }
+                    else
+                    {
+                        /*Codes_SRS_HTTPAPI_COMPACT_21_082: [ If the HTTPAPI_ExecuteRequest retries 20 seconds to receive the message without success, it shall fail and return HTTPAPI_READ_DATA_FAILED. ]*/
+                        LogError("Receive timeout. The HTTP request is incomplete");
+                        n = 0;
+                        result = -1;
+                    }
+                }
+            }
+        }
+    }
+
+    return result;
+}
+
+
+/*Codes_SRS_HTTPAPI_COMPACT_21_021: [ The HTTPAPI_ExecuteRequest shall execute the http communtication with the provided host, sending a request and reciving the response. ]*/
+static HTTPAPI_RESULT OpenXIOConnection(HTTP_HANDLE_DATA* http_instance)
+{
+    HTTPAPI_RESULT result;
+    TLSIO_CONFIG tlsio_config;
+    HTTP_PROXY_IO_CONFIG http_proxy_io_config;
+
+    if (http_instance->is_connected != 0)
+    {
+        /*Codes_SRS_HTTPAPI_COMPACT_21_033: [ If the whole process succeed, the HTTPAPI_ExecuteRequest shall retur HTTPAPI_OK. ]*/
+        result = HTTPAPI_OK;
+    }
+    else
+    {
+        http_instance->is_io_error = 0;
+        tlsio_config.hostname = http_instance->hostName;
+        tlsio_config.port = 443;
+
+        if (http_instance->proxy_host != NULL) {
+            tlsio_config.underlying_io_interface = http_proxy_io_get_interface_description();
+        }
+        else {
+            tlsio_config.underlying_io_interface = NULL;
+        }
+
+        if (tlsio_config.underlying_io_interface != NULL) {
+            tlsio_config.underlying_io_parameters = (void*)&http_proxy_io_config;
+
+            http_proxy_io_config.proxy_hostname = http_instance->proxy_host;
+            http_proxy_io_config.proxy_port = http_instance->proxy_port;
+            http_proxy_io_config.username = http_instance->proxy_username;
+            http_proxy_io_config.password = http_instance->proxy_password;
+            http_proxy_io_config.hostname = http_instance->hostName;
+            http_proxy_io_config.port = 443;
+        }
+        else {
+            tlsio_config.underlying_io_parameters = NULL;
+        }
+
+        http_instance->xio_handle = xio_create(platform_get_default_tlsio(), (void*)&tlsio_config);
+
+        if (http_instance->xio_handle == NULL)
+        {
+            LogError("Create connection failed");
+            free(http_instance);
+            http_instance = NULL;
+            result = HTTPAPI_ERROR;
+        }
+        /*Codes_SRS_HTTPAPI_COMPACT_21_022: [ If a Certificate was provided, the HTTPAPI_ExecuteRequest shall set this option on the transport layer. ]*/
+        else if ((http_instance->certificate != NULL) &&
+            (xio_setoption(http_instance->xio_handle, OPTION_TRUSTED_CERT, http_instance->certificate) != 0))
+        {
+            /*Codes_SRS_HTTPAPI_COMPACT_21_023: [ If the transport failed setting the Certificate, the HTTPAPI_ExecuteRequest shall not send any request and return HTTPAPI_SET_OPTION_FAILED. ]*/
+            result = HTTPAPI_SET_OPTION_FAILED;
+            LogInfo("Could not load certificate");
+        }
+        /*Codes_SRS_HTTPAPI_COMPACT_06_003: [ If the x509 client certificate is provided, the HTTPAPI_ExecuteRequest shall set this option on the transport layer. ]*/
+        else if ((http_instance->x509ClientCertificate != NULL) &&
+            (xio_setoption(http_instance->xio_handle, SU_OPTION_X509_CERT, http_instance->x509ClientCertificate) != 0))
+        {
+            /*Codes_SRS_HTTPAPI_COMPACT_06_005: [ If the transport failed setting the client certificate, the HTTPAPI_ExecuteRequest shall not send any request and return HTTPAPI_SET_OPTION_FAILED. ]*/
+            result = HTTPAPI_SET_OPTION_FAILED;
+            LogInfo("Could not load the client certificate");
+        }
+        else if ((http_instance->x509ClientPrivateKey != NULL) &&
+            (xio_setoption(http_instance->xio_handle, SU_OPTION_X509_PRIVATE_KEY, http_instance->x509ClientPrivateKey) != 0))
+        {
+            /*Codes_SRS_HTTPAPI_COMPACT_06_006: [ If the transport failed setting the client certificate private key, the HTTPAPI_ExecuteRequest shall not send any request and return HTTPAPI_SET_OPTION_FAILED. ] */
+            result = HTTPAPI_SET_OPTION_FAILED;
+            LogInfo("Could not load the client certificate private key");
+        }
+        else
+        {
+            /*Codes_SRS_HTTPAPI_COMPACT_21_024: [ The HTTPAPI_ExecuteRequest shall open the transport connection with the host to send the request. ]*/
+            if (xio_open(http_instance->xio_handle, on_io_open_complete, http_instance, on_bytes_received, http_instance, on_io_error, http_instance) != 0)
+            {
+                /*Codes_SRS_HTTPAPI_COMPACT_21_025: [ If the open process failed, the HTTPAPI_ExecuteRequest shall not send any request and return HTTPAPI_OPEN_REQUEST_FAILED. ]*/
+                result = HTTPAPI_OPEN_REQUEST_FAILED;
+            }
+            else
+            {
+                int countRetry;
+                /*Codes_SRS_HTTPAPI_COMPACT_21_033: [ If the whole process succeed, the HTTPAPI_ExecuteRequest shall retur HTTPAPI_OK. ]*/
+                result = HTTPAPI_OK;
+                /*Codes_SRS_HTTPAPI_COMPACT_21_077: [ The HTTPAPI_ExecuteRequest shall wait, at least, 10 seconds for the SSL open process. ]*/
+                countRetry = MAX_OPEN_RETRY;
+                while ((http_instance->is_connected == 0) &&
+                    (http_instance->is_io_error == 0))
+                {
+                    xio_dowork(http_instance->xio_handle);
+                    //LogInfo("Waiting for TLS connection");
+                    if ((countRetry--) < 0)
+                    {
+                        /*Codes_SRS_HTTPAPI_COMPACT_21_078: [ If the HTTPAPI_ExecuteRequest cannot open the connection in 10 seconds, it shall fail and return HTTPAPI_OPEN_REQUEST_FAILED. ]*/
+                        LogError("Open timeout. The HTTP request is incomplete");
+                        result = HTTPAPI_OPEN_REQUEST_FAILED;
+                        break;
+                    }
+                    else
+                    {
+                        /*Codes_SRS_HTTPAPI_COMPACT_21_083: [ The HTTPAPI_ExecuteRequest shall wait, at least, 100 milliseconds between retries. ]*/
+                        ThreadAPI_Sleep(RETRY_INTERVAL_IN_MICROSECONDS);
+                    }
+                }
+            }
+        }
+    }
+
+    if ((http_instance->is_io_error != 0) && (result == HTTPAPI_OK))
+    {
+        /*Codes_SRS_HTTPAPI_COMPACT_21_025: [ If the open process failed, the HTTPAPI_ExecuteRequest shall not send any request and return HTTPAPI_OPEN_REQUEST_FAILED. ]*/
+        result = HTTPAPI_OPEN_REQUEST_FAILED;
+    }
+
+    return result;
+}
+
+static HTTPAPI_RESULT conn_send_all(HTTP_HANDLE_DATA* http_instance, const unsigned char* buf, size_t bufLen)
+{
+    HTTPAPI_RESULT result;
+
+    http_instance->send_completed = 0;
+    http_instance->is_io_error = 0;
+    if (xio_send(http_instance->xio_handle, buf, bufLen, on_send_complete, http_instance) != 0)
+    {
+        /*Codes_SRS_HTTPAPI_COMPACT_21_028: [ If the HTTPAPI_ExecuteRequest cannot send the request header, it shall return HTTPAPI_HTTP_HEADERS_FAILED. ]*/
+        result = HTTPAPI_SEND_REQUEST_FAILED;
+    }
+    else
+    {
+        /*Codes_SRS_HTTPAPI_COMPACT_21_079: [ The HTTPAPI_ExecuteRequest shall wait, at least, 20 seconds to send a buffer using the SSL connection. ]*/
+        int countRetry = MAX_SEND_RETRY;
+        /*Codes_SRS_HTTPAPI_COMPACT_21_033: [ If the whole process succeed, the HTTPAPI_ExecuteRequest shall retur HTTPAPI_OK. ]*/
+        result = HTTPAPI_OK;
+        while ((http_instance->send_completed == 0) && (result == HTTPAPI_OK))
+        {
+            xio_dowork(http_instance->xio_handle);
+            if (http_instance->is_io_error != 0)
+            {
+                /*Codes_SRS_HTTPAPI_COMPACT_21_028: [ If the HTTPAPI_ExecuteRequest cannot send the request header, it shall return HTTPAPI_HTTP_HEADERS_FAILED. ]*/
+                result = HTTPAPI_SEND_REQUEST_FAILED;
+            }
+            else if ((countRetry--) <= 0)
+            {
+                /*Codes_SRS_HTTPAPI_COMPACT_21_080: [ If the HTTPAPI_ExecuteRequest retries to send the message for 20 seconds without success, it shall fail and return HTTPAPI_SEND_REQUEST_FAILED. ]*/
+                LogError("Send timeout. The HTTP request is incomplete");
+                /*Codes_SRS_HTTPAPI_COMPACT_21_028: [ If the HTTPAPI_ExecuteRequest cannot send the request header, it shall return HTTPAPI_HTTP_HEADERS_FAILED. ]*/
+                result = HTTPAPI_SEND_REQUEST_FAILED;
+            }
+            else
+            {
+                /*Codes_SRS_HTTPAPI_COMPACT_21_083: [ The HTTPAPI_ExecuteRequest shall wait, at least, 100 milliseconds between retries. ]*/
+                ThreadAPI_Sleep(RETRY_INTERVAL_IN_MICROSECONDS);
+            }
+        }
+    }
+
+    return result;
+}
+
+/*Codes_SRS_HTTPAPI_COMPACT_21_035: [ The HTTPAPI_ExecuteRequest shall execute resquest for types GET, POST, PUT, DELETE, PATCH, HEAD. ]*/
+const char httpapiRequestString[6][7] = { "GET", "POST", "PUT", "DELETE", "PATCH", "HEAD" };
+const char* get_request_type(HTTPAPI_REQUEST_TYPE requestType)
+{
+    return (const char*)httpapiRequestString[requestType - HTTPAPI_REQUEST_GET];
+}
+
+/*Codes_SRS_HTTPAPI_COMPACT_21_026: [ If the open process succeed, the HTTPAPI_ExecuteRequest shall send the request message to the host. ]*/
+static HTTPAPI_RESULT SendHeadsToXIO(HTTP_HANDLE_DATA* http_instance, HTTPAPI_REQUEST_TYPE requestType, const char* relativePath, HTTP_HEADERS_HANDLE httpHeadersHandle, size_t headersCount)
+{
+    HTTPAPI_RESULT result;
+    char    buf[TEMP_BUFFER_SIZE];
+    int     ret;
+
+    //Send request
+    /*Codes_SRS_HTTPAPI_COMPACT_21_038: [ The HTTPAPI_ExecuteRequest shall execute the resquest for the path in relativePath parameter. ]*/
+    /*Codes_SRS_HTTPAPI_COMPACT_21_036: [ The request type shall be provided in the parameter requestType. ]*/
+    if (((ret = snprintf(buf, sizeof(buf), "%s %s HTTP/1.1\r\n", get_request_type(requestType), relativePath)) < 0) ||
+        ((size_t)ret >= sizeof(buf)))
+    {
+        /*Codes_SRS_HTTPAPI_COMPACT_21_027: [ If the HTTPAPI_ExecuteRequest cannot create a buffer to send the request, it shall not send any request and return HTTPAPI_STRING_PROCESSING_ERROR. ]*/
+        result = HTTPAPI_STRING_PROCESSING_ERROR;
+    }
+        /*Codes_SRS_HTTPAPI_COMPACT_21_028: [ If the HTTPAPI_ExecuteRequest cannot send the request header, it shall return HTTPAPI_HTTP_HEADERS_FAILED. ]*/
+    else if ((result = conn_send_all(http_instance, (const unsigned char*)buf, strlen(buf))) == HTTPAPI_OK)
+    {
+        size_t i;
+        //Send default headers
+        /*Codes_SRS_HTTPAPI_COMPACT_21_033: [ If the whole process succeed, the HTTPAPI_ExecuteRequest shall retur HTTPAPI_OK. ]*/
+        for (i = 0; ((i < headersCount) && (result == HTTPAPI_OK)); i++)
+        {
+            char* header;
+            if (HTTPHeaders_GetHeader(httpHeadersHandle, i, &header) != HTTP_HEADERS_OK)
+            {
+                /*Codes_SRS_HTTPAPI_COMPACT_21_027: [ If the HTTPAPI_ExecuteRequest cannot create a buffer to send the request, it shall not send any request and return HTTPAPI_STRING_PROCESSING_ERROR. ]*/
+                result = HTTPAPI_STRING_PROCESSING_ERROR;
+            }
+            else
+            {
+                if ((result = conn_send_all(http_instance, (const unsigned char*)header, strlen(header))) == HTTPAPI_OK)
+                {
+                    result = conn_send_all(http_instance, (const unsigned char*)"\r\n", (size_t)2);
+                }
+                free(header);
+            }
+        }
+
+        //Close headers
+        if (result == HTTPAPI_OK)
+        {
+            result = conn_send_all(http_instance, (const unsigned char*)"\r\n", (size_t)2);
+        }
+    }
+    return result;
+}
+
+/*Codes_SRS_HTTPAPI_COMPACT_21_042: [ The request can contain the a content message, provided in content parameter. ]*/
+static HTTPAPI_RESULT SendContentToXIO(HTTP_HANDLE_DATA* http_instance, const unsigned char* content, size_t contentLength)
+{
+    HTTPAPI_RESULT result;
+
+    //Send data (if available)
+    /*Codes_SRS_HTTPAPI_COMPACT_21_045: [ If the contentLength is lower than one, the HTTPAPI_ExecuteRequest shall send the request without content. ]*/
+    if (content && contentLength > 0)
+    {
+        /*Codes_SRS_HTTPAPI_COMPACT_21_044: [ If the content is not NULL, the number of bytes in the content shall be provided in contentLength parameter. ]*/
+        result = conn_send_all(http_instance, content, contentLength);
+    }
+    else
+    {
+        /*Codes_SRS_HTTPAPI_COMPACT_21_043: [ If the content is NULL, the HTTPAPI_ExecuteRequest shall send the request without content. ]*/
+        /*Codes_SRS_HTTPAPI_COMPACT_21_033: [ If the whole process succeed, the HTTPAPI_ExecuteRequest shall retur HTTPAPI_OK. ]*/
+        result = HTTPAPI_OK;
+    }
+    return result;
+}
+
+/*Codes_SRS_HTTPAPI_COMPACT_21_030: [ At the end of the transmission, the HTTPAPI_ExecuteRequest shall receive the response from the host. ]*/
+static HTTPAPI_RESULT ReceiveHeaderFromXIO(HTTP_HANDLE_DATA* http_instance, unsigned int* statusCode)
+{
+    HTTPAPI_RESULT result;
+    char    buf[TEMP_BUFFER_SIZE];
+    int     ret;
+
+    http_instance->is_io_error = 0;
+
+    //Receive response
+    if (readLine(http_instance, buf, TEMP_BUFFER_SIZE) < 0)
+    {
+        /*Codes_SRS_HTTPAPI_COMPACT_21_032: [ If the HTTPAPI_ExecuteRequest cannot read the message with the request result, it shall return HTTPAPI_READ_DATA_FAILED. ]*/
+        /*Codes_SRS_HTTPAPI_COMPACT_21_082: [ If the HTTPAPI_ExecuteRequest retries 20 seconds to receive the message without success, it shall fail and return HTTPAPI_READ_DATA_FAILED. ]*/
+        result = HTTPAPI_READ_DATA_FAILED;
+    }
+    //Parse HTTP response
+    else if (ParseHttpResponse(buf, &ret) != 1)
+    {
+        //Cannot match string, error
+        /*Codes_SRS_HTTPAPI_COMPACT_21_055: [ If the HTTPAPI_ExecuteRequest cannot parser the received message, it shall return HTTPAPI_RECEIVE_RESPONSE_FAILED. ]*/
+        LogInfo("Not a correct HTTP answer");
+        result = HTTPAPI_RECEIVE_RESPONSE_FAILED;
+    }
+    else
+    {
+        /*Codes_SRS_HTTPAPI_COMPACT_21_046: [ The HTTPAPI_ExecuteRequest shall return the http status reported by the host in the received response. ]*/
+        /*Codes_SRS_HTTPAPI_COMPACT_21_048: [ If the statusCode is NULL, the HTTPAPI_ExecuteRequest shall report not report any status. ]*/
+        if (statusCode)
+        {
+            /*Codes_SRS_HTTPAPI_COMPACT_21_047: [ The HTTPAPI_ExecuteRequest shall report the status in the statusCode parameter. ]*/
+            *statusCode = ret;
+        }
+        /*Codes_SRS_HTTPAPI_COMPACT_21_033: [ If the whole process succeed, the HTTPAPI_ExecuteRequest shall retur HTTPAPI_OK. ]*/
+        result = HTTPAPI_OK;
+    }
+
+    return result;
+}
+
+static HTTPAPI_RESULT ReceiveContentInfoFromXIO(HTTP_HANDLE_DATA* http_instance, HTTP_HEADERS_HANDLE responseHeadersHandle, size_t* bodyLength, bool* chunked)
+{
+    HTTPAPI_RESULT result;
+    char    buf[TEMP_BUFFER_SIZE];
+    const char* substr;
+    char* whereIsColon;
+    int lengthInMsg;
+    const char ContentLength[] = "content-length:";
+    const size_t ContentLengthSize = sizeof(ContentLength) - 1;
+    const char TransferEncoding[] = "transfer-encoding:";
+    const size_t TransferEncodingSize = sizeof(TransferEncoding) - 1;
+    const char Chunked[] = "chunked";
+    const size_t ChunkedSize = sizeof(Chunked) - 1;
+
+    http_instance->is_io_error = 0;
+
+    //Read HTTP response headers
+    if (readLine(http_instance, buf, sizeof(buf)) < 0)
+    {
+        /*Codes_SRS_HTTPAPI_COMPACT_21_032: [ If the HTTPAPI_ExecuteRequest cannot read the message with the request result, it shall return HTTPAPI_READ_DATA_FAILED. ]*/
+        /*Codes_SRS_HTTPAPI_COMPACT_21_082: [ If the HTTPAPI_ExecuteRequest retries 20 seconds to receive the message without success, it shall fail and return HTTPAPI_READ_DATA_FAILED. ]*/
+        result = HTTPAPI_READ_DATA_FAILED;
+    }
+    else
+    {
+        /*Codes_SRS_HTTPAPI_COMPACT_21_033: [ If the whole process succeed, the HTTPAPI_ExecuteRequest shall retur HTTPAPI_OK. ]*/
+        result = HTTPAPI_OK;
+
+        while (*buf && (result == HTTPAPI_OK))
+        {
+            if (InternStrnicmp(buf, ContentLength, ContentLengthSize) == 0)
+            {
+                substr = buf + ContentLengthSize;
+                if (ParseStringToDecimal(substr, &lengthInMsg) != 1)
+                {
+                    /*Codes_SRS_HTTPAPI_COMPACT_21_032: [ If the HTTPAPI_ExecuteRequest cannot read the message with the request result, it shall return HTTPAPI_READ_DATA_FAILED. ]*/
+                    result = HTTPAPI_READ_DATA_FAILED;
+                }
+                else
+                {
+                    (*bodyLength) = (size_t)lengthInMsg;
+                }
+            }
+            else if (InternStrnicmp(buf, TransferEncoding, TransferEncodingSize) == 0)
+            {
+                substr = buf + TransferEncodingSize;
+
+                while (isspace(*substr)) substr++;
+
+                if (InternStrnicmp(substr, Chunked, ChunkedSize) == 0)
+                {
+                    (*chunked) = true;
+                }
+            }
+
+            if (result == HTTPAPI_OK)
+            {
+                whereIsColon = strchr((char*)buf, ':');
+                /*Codes_SRS_HTTPAPI_COMPACT_21_049: [ If responseHeadersHandle is provide, the HTTPAPI_ExecuteRequest shall prepare a Response Header usign the HTTPHeaders_AddHeaderNameValuePair. ]*/
+                if (whereIsColon && (responseHeadersHandle != NULL))
+                {
+                    *whereIsColon = '\0';
+                    HTTPHeaders_AddHeaderNameValuePair(responseHeadersHandle, buf, whereIsColon + 1);
+                }
+
+                if (readLine(http_instance, buf, sizeof(buf)) < 0)
+                {
+                    /*Codes_SRS_HTTPAPI_COMPACT_21_032: [ If the HTTPAPI_ExecuteRequest cannot read the message with the request result, it shall return HTTPAPI_READ_DATA_FAILED. ]*/
+                    /*Codes_SRS_HTTPAPI_COMPACT_21_082: [ If the HTTPAPI_ExecuteRequest retries 20 seconds to receive the message without success, it shall fail and return HTTPAPI_READ_DATA_FAILED. ]*/
+                    result = HTTPAPI_READ_DATA_FAILED;
+                }
+            }
+        }
+    }
+
+    return result;
+}
+
+static HTTPAPI_RESULT ReadHTTPResponseBodyFromXIO(HTTP_HANDLE_DATA* http_instance, size_t bodyLength, bool chunked, BUFFER_HANDLE responseContent)
+{
+    HTTPAPI_RESULT result;
+    char    buf[TEMP_BUFFER_SIZE];
+    const unsigned char* receivedContent;
+
+    http_instance->is_io_error = 0;
+
+    //Read HTTP response body
+    if (!chunked)
+    {
+        if (bodyLength)
+        {
+            if (responseContent != NULL)
+            {
+                if (BUFFER_pre_build(responseContent, bodyLength) != 0)
+                {
+                    /*Codes_SRS_HTTPAPI_COMPACT_21_052: [ If any memory allocation get fail, the HTTPAPI_ExecuteRequest shall return HTTPAPI_ALLOC_FAILED. ]*/
+                    result = HTTPAPI_ALLOC_FAILED;
+                }
+                else if (BUFFER_content(responseContent, &receivedContent) != 0)
+                {
+                    (void)BUFFER_unbuild(responseContent);
+
+                    /*Codes_SRS_HTTPAPI_COMPACT_21_052: [ If any memory allocation get fail, the HTTPAPI_ExecuteRequest shall return HTTPAPI_ALLOC_FAILED. ]*/
+                    result = HTTPAPI_ALLOC_FAILED;
+                }
+                else if (readChunk(http_instance, (char*)receivedContent, bodyLength) < 0)
+                {
+                    /*Codes_SRS_HTTPAPI_COMPACT_21_032: [ If the HTTPAPI_ExecuteRequest cannot read the message with the request result, it shall return HTTPAPI_READ_DATA_FAILED. ]*/
+                    result = HTTPAPI_READ_DATA_FAILED;
+                }
+                else
+                {
+                    /*Codes_SRS_HTTPAPI_COMPACT_21_033: [ If the whole process succeed, the HTTPAPI_ExecuteRequest shall retur HTTPAPI_OK. ]*/
+                    result = HTTPAPI_OK;
+                }
+            }
+            else
+            {
+                /*Codes_SRS_HTTPAPI_COMPACT_21_051: [ If the responseContent is NULL, the HTTPAPI_ExecuteRequest shall ignore any content in the response. ]*/
+                if (skipN(http_instance, bodyLength) < 0)
+                {
+                    /*Codes_SRS_HTTPAPI_COMPACT_21_082: [ If the HTTPAPI_ExecuteRequest retries 20 seconds to receive the message without success, it shall fail and return HTTPAPI_READ_DATA_FAILED. ]*/
+                    result = HTTPAPI_READ_DATA_FAILED;
+                }
+                else
+                {
+                    result = HTTPAPI_OK;
+                }
+            }
+        }
+        else
+        {
+            /*Codes_SRS_HTTPAPI_COMPACT_21_033: [ If the whole process succeed, the HTTPAPI_ExecuteRequest shall retur HTTPAPI_OK. ]*/
+            result = HTTPAPI_OK;
+        }
+    }
+    else
+    {
+        size_t size = 0;
+        /*Codes_SRS_HTTPAPI_COMPACT_21_033: [ If the whole process succeed, the HTTPAPI_ExecuteRequest shall retur HTTPAPI_OK. ]*/
+        result = HTTPAPI_OK;
+        while (result == HTTPAPI_OK)
+        {
+            size_t chunkSize;
+            if (readLine(http_instance, buf, sizeof(buf)) < 0)    // read [length in hex]/r/n
+            {
+                /*Codes_SRS_HTTPAPI_COMPACT_21_032: [ If the HTTPAPI_ExecuteRequest cannot read the message with the request result, it shall return HTTPAPI_READ_DATA_FAILED. ]*/
+                /*Codes_SRS_HTTPAPI_COMPACT_21_082: [ If the HTTPAPI_ExecuteRequest retries 20 seconds to receive the message without success, it shall fail and return HTTPAPI_READ_DATA_FAILED. ]*/
+                result = HTTPAPI_READ_DATA_FAILED;
+            }
+            else if (ParseStringToHexadecimal(buf, &chunkSize) != 1)     // chunkSize is length of next line (/r/n is not counted)
+            {
+                //Cannot match string, error
+                /*Codes_SRS_HTTPAPI_COMPACT_21_055: [ If the HTTPAPI_ExecuteRequest cannot parser the received message, it shall return HTTPAPI_RECEIVE_RESPONSE_FAILED. ]*/
+                result = HTTPAPI_RECEIVE_RESPONSE_FAILED;
+            }
+            else if (chunkSize == 0)
+            {
+                // 0 length means next line is just '\r\n' and end of chunks
+                if (readChunk(http_instance, (char*)buf, (size_t)2) < 0
+                    || buf[0] != '\r' || buf[1] != '\n') // skip /r/n
+                {
+                    (void)BUFFER_unbuild(responseContent);
+
+                    result = HTTPAPI_READ_DATA_FAILED;
+                }
+                break;
+            }
+            else
+            {
+                if (responseContent != NULL)
+                {
+                    if (BUFFER_enlarge(responseContent, chunkSize) != 0)
+                    {
+                        (void)BUFFER_unbuild(responseContent);
+
+                        /*Codes_SRS_HTTPAPI_COMPACT_21_052: [ If any memory allocation get fail, the HTTPAPI_ExecuteRequest shall return HTTPAPI_ALLOC_FAILED. ]*/
+                        result = HTTPAPI_ALLOC_FAILED;
+                    }
+                    else if (BUFFER_content(responseContent, &receivedContent) != 0)
+                    {
+                        (void)BUFFER_unbuild(responseContent);
+
+                        /*Codes_SRS_HTTPAPI_COMPACT_21_052: [ If any memory allocation get fail, the HTTPAPI_ExecuteRequest shall return HTTPAPI_ALLOC_FAILED. ]*/
+                        result = HTTPAPI_ALLOC_FAILED;
+                    }
+                    else if (readChunk(http_instance, (char*)receivedContent + size, chunkSize) < 0)
+                    {
+                        result = HTTPAPI_READ_DATA_FAILED;
+                    }
+                }
+                else
+                {
+                    /*Codes_SRS_HTTPAPI_COMPACT_21_051: [ If the responseContent is NULL, the HTTPAPI_ExecuteRequest shall ignore any content in the response. ]*/
+                    if (skipN(http_instance, chunkSize) < 0)
+                    {
+                        /*Codes_SRS_HTTPAPI_COMPACT_21_082: [ If the HTTPAPI_ExecuteRequest retries 20 seconds to receive the message without success, it shall fail and return HTTPAPI_READ_DATA_FAILED. ]*/
+                        result = HTTPAPI_READ_DATA_FAILED;
+                    }
+                }
+
+                if (result == HTTPAPI_OK)
+                {
+                    if (readChunk(http_instance, (char*)buf, (size_t)2) < 0
+                        || buf[0] != '\r' || buf[1] != '\n') // skip /r/n
+                    {
+                        result = HTTPAPI_READ_DATA_FAILED;
+                    }
+                    size += chunkSize;
+                }
+            }
+        }
+
+    }
+    return result;
+}
+
+
+/*Codes_SRS_HTTPAPI_COMPACT_21_037: [ If the request type is unknown, the HTTPAPI_ExecuteRequest shall return HTTPAPI_INVALID_ARG. ]*/
+static bool validRequestType(HTTPAPI_REQUEST_TYPE requestType)
+{
+    bool result;
+
+    if ((requestType == HTTPAPI_REQUEST_GET) ||
+        (requestType == HTTPAPI_REQUEST_POST) ||
+        (requestType == HTTPAPI_REQUEST_PUT) ||
+        (requestType == HTTPAPI_REQUEST_DELETE) ||
+        (requestType == HTTPAPI_REQUEST_PATCH) ||
+        (requestType == HTTPAPI_REQUEST_HEAD))
+    {
+        result = true;
+    }
+    else
+    {
+        result = false;
+    }
+
+    return result;
+}
+
+/*Codes_SRS_HTTPAPI_COMPACT_21_021: [ The HTTPAPI_ExecuteRequest shall execute the http communtication with the provided host, sending a request and reciving the response. ]*/
+/*Codes_SRS_HTTPAPI_COMPACT_21_050: [ If there is a content in the response, the HTTPAPI_ExecuteRequest shall copy it in the responseContent buffer. ]*/
+//Note: This function assumes that "Host:" and "Content-Length:" headers are setup
+//      by the caller of HTTPAPI_ExecuteRequest() (which is true for httptransport.c).
+HTTPAPI_RESULT HTTPAPI_ExecuteRequest(HTTP_HANDLE handle, HTTPAPI_REQUEST_TYPE requestType, const char* relativePath,
+    HTTP_HEADERS_HANDLE httpHeadersHandle, const unsigned char* content,
+    size_t contentLength, unsigned int* statusCode,
+    HTTP_HEADERS_HANDLE responseHeadersHandle, BUFFER_HANDLE responseContent)
+{
+    HTTPAPI_RESULT result = HTTPAPI_ERROR;
+    size_t  headersCount;
+    size_t  bodyLength = 0;
+    bool    chunked = false;
+    HTTP_HANDLE_DATA* http_instance = (HTTP_HANDLE_DATA*)handle;
+
+    /*Codes_SRS_HTTPAPI_COMPACT_21_034: [ If there is no previous connection, the HTTPAPI_ExecuteRequest shall return HTTPAPI_INVALID_ARG. ]*/
+    /*Codes_SRS_HTTPAPI_COMPACT_21_037: [ If the request type is unknown, the HTTPAPI_ExecuteRequest shall return HTTPAPI_INVALID_ARG. ]*/
+    /*Codes_SRS_HTTPAPI_COMPACT_21_039: [ If the relativePath is NULL or invalid, the HTTPAPI_ExecuteRequest shall return HTTPAPI_INVALID_ARG. ]*/
+    /*Codes_SRS_HTTPAPI_COMPACT_21_041: [ If the httpHeadersHandle is NULL or invalid, the HTTPAPI_ExecuteRequest shall return HTTPAPI_INVALID_ARG. ]*/
+    /*Codes_SRS_HTTPAPI_COMPACT_21_053: [ The HTTPAPI_ExecuteRequest shall produce a set of http header to send to the host. ]*/
+    /*Codes_SRS_HTTPAPI_COMPACT_21_040: [ The request shall contain the http header provided in httpHeadersHandle parameter. ]*/
+    /*Codes_SRS_HTTPAPI_COMPACT_21_054: [ If Http header maker cannot provide the number of headers, the HTTPAPI_ExecuteRequest shall return HTTPAPI_INVALID_ARG. ]*/
+    if (http_instance == NULL ||
+        relativePath == NULL ||
+        httpHeadersHandle == NULL ||
+        !validRequestType(requestType) ||
+        HTTPHeaders_GetHeaderCount(httpHeadersHandle, &headersCount) != HTTP_HEADERS_OK)
+    {
+        result = HTTPAPI_INVALID_ARG;
+        LogError("(result = %" PRI_MU_ENUM ")", MU_ENUM_VALUE(HTTPAPI_RESULT, result));
+    }
+    /*Codes_SRS_HTTPAPI_COMPACT_21_024: [ The HTTPAPI_ExecuteRequest shall open the transport connection with the host to send the request. ]*/
+    else if ((result = OpenXIOConnection(http_instance)) != HTTPAPI_OK)
+    {
+        LogError("Open HTTP connection failed (result = %" PRI_MU_ENUM ")", MU_ENUM_VALUE(HTTPAPI_RESULT, result));
+    }
+    /*Codes_SRS_HTTPAPI_COMPACT_21_026: [ If the open process succeed, the HTTPAPI_ExecuteRequest shall send the request message to the host. ]*/
+    else if ((result = SendHeadsToXIO(http_instance, requestType, relativePath, httpHeadersHandle, headersCount)) != HTTPAPI_OK)
+    {
+        LogError("Send heads to HTTP failed (result = %" PRI_MU_ENUM ")", MU_ENUM_VALUE(HTTPAPI_RESULT, result));
+    }
+    /*Codes_SRS_HTTPAPI_COMPACT_21_042: [ The request can contain the a content message, provided in content parameter. ]*/
+    else if ((result = SendContentToXIO(http_instance, content, contentLength)) != HTTPAPI_OK)
+    {
+        LogError("Send content to HTTP failed (result = %" PRI_MU_ENUM ")", MU_ENUM_VALUE(HTTPAPI_RESULT, result));
+    }
+    /*Codes_SRS_HTTPAPI_COMPACT_21_030: [ At the end of the transmission, the HTTPAPI_ExecuteRequest shall receive the response from the host. ]*/
+    /*Codes_SRS_HTTPAPI_COMPACT_21_073: [ The message received by the HTTPAPI_ExecuteRequest shall starts with a valid header. ]*/
+    else if ((result = ReceiveHeaderFromXIO(http_instance, statusCode)) != HTTPAPI_OK)
+    {
+        LogError("Receive header from HTTP failed (result = %" PRI_MU_ENUM ")", MU_ENUM_VALUE(HTTPAPI_RESULT, result));
+    }
+    /*Codes_SRS_HTTPAPI_COMPACT_21_074: [ After the header, the message received by the HTTPAPI_ExecuteRequest can contain addition information about the content. ]*/
+    else if ((result = ReceiveContentInfoFromXIO(http_instance, responseHeadersHandle, &bodyLength, &chunked)) != HTTPAPI_OK)
+    {
+        LogError("Receive content information from HTTP failed (result = %" PRI_MU_ENUM ")", MU_ENUM_VALUE(HTTPAPI_RESULT, result));
+    }
+    /*Codes_SRS_HTTPAPI_COMPACT_42_084: [ The message received by the HTTPAPI_ExecuteRequest should not contain http body. ]*/
+    else if (requestType != HTTPAPI_REQUEST_HEAD)
+    {
+        /*Codes_SRS_HTTPAPI_COMPACT_21_075: [ The message received by the HTTPAPI_ExecuteRequest can contain a body with the message content. ]*/
+        if ((result = ReadHTTPResponseBodyFromXIO(http_instance, bodyLength, chunked, responseContent)) != HTTPAPI_OK)
+        {
+            LogError("Read HTTP response body from HTTP failed (result = %" PRI_MU_ENUM ")", MU_ENUM_VALUE(HTTPAPI_RESULT, result));
+        }
+    }
+
+    conn_receive_discard_buffer(http_instance);
+
+    return result;
+}
+
+/*Codes_SRS_HTTPAPI_COMPACT_21_056: [ The HTTPAPI_SetOption shall change the HTTP options. ]*/
+/*Codes_SRS_HTTPAPI_COMPACT_21_057: [ The HTTPAPI_SetOption shall receive a handle that identiry the HTTP connection. ]*/
+/*Codes_SRS_HTTPAPI_COMPACT_21_058: [ The HTTPAPI_SetOption shall receive the option as a pair optionName/value. ]*/
+HTTPAPI_RESULT HTTPAPI_SetOption(HTTP_HANDLE handle, const char* optionName, const void* value)
+{
+    HTTPAPI_RESULT result;
+    HTTP_HANDLE_DATA* http_instance = (HTTP_HANDLE_DATA*)handle;
+
+    if (
+        (http_instance == NULL) ||
+        (optionName == NULL) ||
+        (value == NULL)
+        )
+    {
+        /*Codes_SRS_HTTPAPI_COMPACT_21_059: [ If the handle is NULL, the HTTPAPI_SetOption shall return HTTPAPI_INVALID_ARG. ]*/
+        /*Codes_SRS_HTTPAPI_COMPACT_21_060: [ If the optionName is NULL, the HTTPAPI_SetOption shall return HTTPAPI_INVALID_ARG. ]*/
+        /*Codes_SRS_HTTPAPI_COMPACT_21_061: [ If the value is NULL, the HTTPAPI_SetOption shall return HTTPAPI_INVALID_ARG. ]*/
+        result = HTTPAPI_INVALID_ARG;
+    }
+    else if (strcmp(OPTION_TRUSTED_CERT, optionName) == 0)
+    {
+#ifdef DO_NOT_COPY_TRUSTED_CERTS_STRING
+        result = HTTPAPI_OK;
+        http_instance->certificate = (char*)value;
+#else
+        int len;
+
+        if (http_instance->certificate)
+        {
+            free(http_instance->certificate);
+        }
+
+        len = (int)strlen((char*)value);
+        http_instance->certificate = (char*)malloc((len + 1) * sizeof(char));
+        if (http_instance->certificate == NULL)
+        {
+            /*Codes_SRS_HTTPAPI_COMPACT_21_062: [ If any memory allocation get fail, the HTTPAPI_SetOption shall return HTTPAPI_ALLOC_FAILED. ]*/
+            result = HTTPAPI_ALLOC_FAILED;
+            LogInfo("unable to allocate memory for the certificate in HTTPAPI_SetOption");
+        }
+        else
+        {
+            /*Codes_SRS_HTTPAPI_COMPACT_21_064: [ If the HTTPAPI_SetOption get success setting the option, it shall return HTTPAPI_OK. ]*/
+            (void)strcpy(http_instance->certificate, (const char*)value);
+            result = HTTPAPI_OK;
+        }
+#endif // DO_NOT_COPY_TRUSTED_CERTS_STRING
+    }
+    else if (strcmp(SU_OPTION_X509_CERT, optionName) == 0)
+    {
+        int len;
+        if (http_instance->x509ClientCertificate)
+        {
+            free(http_instance->x509ClientCertificate);
+        }
+
+        len = (int)strlen((char*)value);
+        http_instance->x509ClientCertificate = (char*)malloc((len + 1) * sizeof(char));
+        if (http_instance->x509ClientCertificate == NULL)
+        {
+            /*Codes_SRS_HTTPAPI_COMPACT_21_062: [ If any memory allocation get fail, the HTTPAPI_SetOption shall return HTTPAPI_ALLOC_FAILED. ]*/
+            result = HTTPAPI_ALLOC_FAILED;
+            LogInfo("unable to allocate memory for the client certificate in HTTPAPI_SetOption");
+        }
+        else
+        {
+            /*Codes_SRS_HTTPAPI_COMPACT_21_064: [ If the HTTPAPI_SetOption get success setting the option, it shall return HTTPAPI_OK. ]*/
+            (void)strcpy(http_instance->x509ClientCertificate, (const char*)value);
+            result = HTTPAPI_OK;
+        }
+    }
+    else if (strcmp(SU_OPTION_X509_PRIVATE_KEY, optionName) == 0)
+    {
+        int len;
+        if (http_instance->x509ClientPrivateKey)
+        {
+            free(http_instance->x509ClientPrivateKey);
+        }
+
+        len = (int)strlen((char*)value);
+        http_instance->x509ClientPrivateKey = (char*)malloc((len + 1) * sizeof(char));
+        if (http_instance->x509ClientPrivateKey == NULL)
+        {
+            /*Codes_SRS_HTTPAPI_COMPACT_21_062: [ If any memory allocation get fail, the HTTPAPI_SetOption shall return HTTPAPI_ALLOC_FAILED. ]*/
+            result = HTTPAPI_ALLOC_FAILED;
+            LogInfo("unable to allocate memory for the client private key in HTTPAPI_SetOption");
+        }
+        else
+        {
+            /*Codes_SRS_HTTPAPI_COMPACT_21_064: [ If the HTTPAPI_SetOption get success setting the option, it shall return HTTPAPI_OK. ]*/
+            (void)strcpy(http_instance->x509ClientPrivateKey, (const char*)value);
+            result = HTTPAPI_OK;
+        }
+    }
+    else if (strcmp(OPTION_HTTP_PROXY, optionName) == 0)
+    {
+        HTTP_PROXY_OPTIONS* proxy_data = (HTTP_PROXY_OPTIONS*)value;
+        if (proxy_data->host_address == NULL || proxy_data->port <= 0)
+        {
+            LogError("invalid proxy_data values ( host_address = %p, port = %d)", proxy_data->host_address, proxy_data->port);
+            result = HTTPAPI_ERROR;
+        }
+        else
+        {
+            if(http_instance->proxy_host != NULL)
+            {
+                free((void*)http_instance->proxy_host);
+                http_instance->proxy_host = NULL;
+            }
+            if(mallocAndStrcpy_s((char**)&(http_instance->proxy_host), (const char*)proxy_data->host_address) != 0)
+            {
+                LogError("failure allocate proxy host");
+                result = HTTPAPI_ERROR;
+            }
+            else
+            {
+                http_instance->proxy_port = proxy_data->port;
+
+                if (proxy_data->username != NULL && proxy_data->password != NULL)
+                {
+                    if(http_instance->proxy_username != NULL)
+                    {
+                        free((void*)http_instance->proxy_username);
+                        http_instance->proxy_username = NULL;
+                    }
+                    if(mallocAndStrcpy_s((char**)&(http_instance->proxy_username), (const char*)proxy_data->username) != 0)
+                    {
+                        LogError("failure allocate proxy username");
+                        free((void*)http_instance->proxy_host);
+                        http_instance->proxy_host = NULL;
+                        result = HTTPAPI_ERROR;
+                    }
+                    else
+                    {
+                        if(http_instance->proxy_password != NULL)
+                        {
+                          free((void*)http_instance->proxy_password);
+                          http_instance->proxy_password = NULL;
+                        }
+                        if(mallocAndStrcpy_s((char**)&(http_instance->proxy_password), (const char*)proxy_data->password) != 0)
+                        {
+                            LogError("failure allocate proxy password");
+                            free((void*)http_instance->proxy_host);
+                            http_instance->proxy_host = NULL;
+                            free((void*)http_instance->proxy_username);
+                            http_instance->proxy_username = NULL;
+                            result = HTTPAPI_ERROR;
+                        }
+                        else
+                        {
+                          result = HTTPAPI_OK;
+                        }
+                    }
+                }
+                else
+                {
+                    result = HTTPAPI_OK;
+                }
+            }
+        }
+    }
+    else
+    {
+        /*Codes_SRS_HTTPAPI_COMPACT_21_063: [ If the HTTP do not support the optionName, the HTTPAPI_SetOption shall return HTTPAPI_INVALID_ARG. ]*/
+        result = HTTPAPI_INVALID_ARG;
+        LogInfo("unknown option %s", optionName);
+    }
+    return result;
+}
+
+/*Codes_SRS_HTTPAPI_COMPACT_21_065: [ The HTTPAPI_CloneOption shall provide the means to clone the HTTP option. ]*/
+/*Codes_SRS_HTTPAPI_COMPACT_21_066: [ The HTTPAPI_CloneOption shall return a clone of the value identified by the optionName. ]*/
+HTTPAPI_RESULT HTTPAPI_CloneOption(const char* optionName, const void* value, const void** savedValue)
+{
+    HTTPAPI_RESULT result;
+    size_t certLen;
+    char* tempCert;
+
+    if (
+        (optionName == NULL) ||
+        (value == NULL) ||
+        (savedValue == NULL)
+        )
+    {
+        /*Codes_SRS_HTTPAPI_COMPACT_21_067: [ If the optionName is NULL, the HTTPAPI_CloneOption shall return HTTPAPI_INVALID_ARG. ]*/
+        /*Codes_SRS_HTTPAPI_COMPACT_21_068: [ If the value is NULL, the HTTPAPI_CloneOption shall return HTTPAPI_INVALID_ARG. ]*/
+        /*Codes_SRS_HTTPAPI_COMPACT_21_069: [ If the savedValue is NULL, the HTTPAPI_CloneOption shall return HTTPAPI_INVALID_ARG. ]*/
+        result = HTTPAPI_INVALID_ARG;
+    }
+    else if (strcmp(OPTION_TRUSTED_CERT, optionName) == 0)
+    {
+#ifdef DO_NOT_COPY_TRUSTED_CERTS_STRING
+        *savedValue = (const void*)value;
+        result = HTTPAPI_OK;
+#else
+        certLen = strlen((const char*)value);
+        tempCert = (char*)malloc((certLen + 1) * sizeof(char));
+        if (tempCert == NULL)
+        {
+            /*Codes_SRS_HTTPAPI_COMPACT_21_070: [ If any memory allocation get fail, the HTTPAPI_CloneOption shall return HTTPAPI_ALLOC_FAILED. ]*/
+            result = HTTPAPI_ALLOC_FAILED;
+        }
+        else
+        {
+            /*Codes_SRS_HTTPAPI_COMPACT_21_072: [ If the HTTPAPI_CloneOption get success setting the option, it shall return HTTPAPI_OK. ]*/
+            (void)strcpy(tempCert, (const char*)value);
+            *savedValue = tempCert;
+            result = HTTPAPI_OK;
+        }
+#endif // DO_NOT_COPY_TRUSTED_CERTS_STRING
+    }
+    else if (strcmp(SU_OPTION_X509_CERT, optionName) == 0)
+    {
+        certLen = strlen((const char*)value);
+        tempCert = (char*)malloc((certLen + 1) * sizeof(char));
+        if (tempCert == NULL)
+        {
+            /*Codes_SRS_HTTPAPI_COMPACT_21_070: [ If any memory allocation get fail, the HTTPAPI_CloneOption shall return HTTPAPI_ALLOC_FAILED. ]*/
+            result = HTTPAPI_ALLOC_FAILED;
+        }
+        else
+        {
+            /*Codes_SRS_HTTPAPI_COMPACT_21_072: [ If the HTTPAPI_CloneOption get success setting the option, it shall return HTTPAPI_OK. ]*/
+            (void)strcpy(tempCert, (const char*)value);
+            *savedValue = tempCert;
+            result = HTTPAPI_OK;
+        }
+    }
+    else if (strcmp(SU_OPTION_X509_PRIVATE_KEY, optionName) == 0)
+    {
+        certLen = strlen((const char*)value);
+        tempCert = (char*)malloc((certLen + 1) * sizeof(char));
+        if (tempCert == NULL)
+        {
+            /*Codes_SRS_HTTPAPI_COMPACT_21_070: [ If any memory allocation get fail, the HTTPAPI_CloneOption shall return HTTPAPI_ALLOC_FAILED. ]*/
+            result = HTTPAPI_ALLOC_FAILED;
+        }
+        else
+        {
+            /*Codes_SRS_HTTPAPI_COMPACT_21_072: [ If the HTTPAPI_CloneOption get success setting the option, it shall return HTTPAPI_OK. ]*/
+            (void)strcpy(tempCert, (const char*)value);
+            *savedValue = tempCert;
+            result = HTTPAPI_OK;
+        }
+    }
+    else if (strcmp(OPTION_HTTP_PROXY, optionName) == 0)
+    {
+        HTTP_PROXY_OPTIONS* proxy_data = (HTTP_PROXY_OPTIONS*)value;
+
+        HTTP_PROXY_OPTIONS* new_proxy_info = malloc(sizeof(HTTP_PROXY_OPTIONS));
+        if (new_proxy_info == NULL)
+        {
+            LogError("unable to allocate proxy option information");
+            result = HTTPAPI_ERROR;
+        }
+        else
+        {
+            new_proxy_info->host_address = proxy_data->host_address;
+            new_proxy_info->port = proxy_data->port;
+            new_proxy_info->password = proxy_data->password;
+            new_proxy_info->username = proxy_data->username;
+            *savedValue = new_proxy_info;
+            result = HTTPAPI_OK;
+        }
+    }
+    else
+    {
+        /*Codes_SRS_HTTPAPI_COMPACT_21_071: [ If the HTTP do not support the optionName, the HTTPAPI_CloneOption shall return HTTPAPI_INVALID_ARG. ]*/
+        result = HTTPAPI_INVALID_ARG;
+        LogInfo("unknown option %s", optionName);
+    }
+    return result;
+}
Index: azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/adapters/lock_toppers.c
===================================================================
--- azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/adapters/lock_toppers.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/adapters/lock_toppers.c	(revision 457)
@@ -0,0 +1,216 @@
+/*
+ *  TOPPERS PROJECT Home Network Working Group Software
+ *
+ *  Copyright (C) 2019 Cores Co., Ltd. Japan
+ *
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ *
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ *
+ *  @(#) $Id$
+ */
+#include <stdint.h>
+#include <stdlib.h>
+#include <kernel.h>
+#include <t_stdlib.h>
+#include "azure_c_shared_utility/lock.h"
+#include "azure_c_shared_utility/xlogging.h"
+
+#ifdef TOPPERS_SUPPORT_DYNAMIC_CRE
+#define MAX_MUTEX 4
+#define TASK_PRIORITY ((TMAX_TPRI + TMIN_TPRI) / 2)
+
+typedef struct _mutex
+{
+	ID mtxid;
+	ID tskid;
+	int count;
+} toppersMutex;
+static toppersMutex mutexs[MAX_MUTEX] = {0};
+#endif
+
+LOCK_HANDLE Lock_Init(void)
+{
+#ifndef TOPPERS_SUPPORT_DYNAMIC_CRE
+	LogError("TOPPERS/ASP does not support lock function.");
+	return LOCK_ERROR;
+#else
+	ER_ID ret;
+	T_CMTX cmtx;
+	toppersMutex *mutex = NULL;
+
+	for (int i = 0; i < MAX_MUTEX; i++)
+	{
+		if (mutexs[i].mtxid == 0)
+		{
+			mutex = &mutexs[i];
+			break;
+		}
+	}
+
+	if (mutex == NULL)
+	{
+		LogError("Not enough memory.");
+	}
+	else
+	{
+		memset(&cmtx, 0, sizeof(cmtx));
+
+		cmtx.mtxatr = TA_TPRI;
+		cmtx.ceilpri = TASK_PRIORITY;
+
+		ret = acre_mtx(&cmtx);
+		if (ret < 0)
+		{
+			mutex->mtxid = 0;
+			mutex = NULL;
+			LogError("Failed acre_mtx(%d).", ret);
+		}
+		else
+		{
+			mutex->mtxid = (ID)ret;
+			mutex->count = 0;
+		}
+	}
+
+	return (LOCK_HANDLE *)mutex;
+#endif
+}
+
+LOCK_RESULT Lock(LOCK_HANDLE handle)
+{
+#ifndef TOPPERS_SUPPORT_DYNAMIC_CRE
+	LogError("TOPPERS/ASP does not support lock function.");
+	return LOCK_ERROR;
+#else
+	T_RMTX rmtx;
+	toppersMutex *mutex = (toppersMutex *)handle;
+	ID tskid = 0;
+	ER ret;
+
+	if (mutex == NULL)
+	{
+		LogError("Invalid argument; handle is NULL.");
+		return LOCK_ERROR;
+	}
+
+	ret = get_tid(&tskid);
+	if (ret < 0) {
+		LogError("Failed task.");
+		return LOCK_ERROR;
+	}
+
+	ret = loc_mtx(mutex->mtxid);
+	if (ret == E_OBJ)
+	{
+		mutex->count++;
+	}
+	else if (ret < 0)
+	{
+		LogError("Failed loc_mtx(%d).", mutex->mtxid);
+		return LOCK_ERROR;
+	}
+
+	mutex->tskid = tskid;
+
+	return LOCK_OK;
+#endif
+}
+
+LOCK_RESULT Unlock(LOCK_HANDLE handle)
+{
+#ifndef TOPPERS_SUPPORT_DYNAMIC_CRE
+	LogError("TOPPERS/ASP does not support lock function.");
+	return LOCK_ERROR;
+#else
+	toppersMutex *mutex = (toppersMutex *)handle;
+	ID tskid = 0;
+	ER ret;
+
+	if (mutex == NULL)
+	{
+		LogError("Invalid argument; handle is NULL.");
+		return LOCK_ERROR;
+	}
+
+	ret = get_tid(&tskid);
+	if (ret < 0) {
+		LogError("Failed task.");
+		return LOCK_ERROR;
+	}
+
+	loc_cpu();
+
+	if ((mutex->tskid == tskid) && (mutex->count > 0))
+	{
+		mutex->count--;
+		unl_cpu();
+	}
+	else
+	{
+		unl_cpu();
+
+		ret = unl_mtx(mutex->mtxid);
+		if (ret < 0)
+		{
+			LogError("Failed unl_mtx(%d).", mutex->mtxid);
+			return LOCK_ERROR;
+		}
+	}
+
+	return LOCK_OK;
+#endif
+}
+
+LOCK_RESULT Lock_Deinit(LOCK_HANDLE handle)
+{
+#ifndef TOPPERS_SUPPORT_DYNAMIC_CRE
+	LogError("TOPPERS/ASP does not support lock function.");
+	return LOCK_ERROR;
+#else
+	toppersMutex *mutex = (toppersMutex *)handle;
+	ER ret;
+
+	if (mutex == NULL)
+	{
+		LogError("Failed argument; handle is NULL.");
+		return LOCK_ERROR;
+	}
+
+	ret = del_mtx(mutex->mtxid);
+	if (ret < 0)
+	{
+		LogError("Failed del_mtx(%d).", mutex->mtxid);
+		return LOCK_ERROR;
+	}
+
+	mutex->mtxid = 0;
+
+	return LOCK_OK;
+#endif
+}
Index: azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/adapters/platform_toppers.c
===================================================================
--- azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/adapters/platform_toppers.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/adapters/platform_toppers.c	(revision 457)
@@ -0,0 +1,67 @@
+/*
+ *  TOPPERS PROJECT Home Network Working Group Software
+ * 
+ *  Copyright (C) 2019 Cores Co., Ltd. Japan
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+#include <stdint.h>
+#include <stdlib.h>
+#include <kernel.h>
+#include "azure_c_shared_utility/platform.h"
+#include "azure_c_shared_utility/optimize_size.h"
+#include "azure_c_shared_utility/xio.h"
+#include "azure_c_shared_utility/tlsio_esp_at.h"
+#include "azure_c_shared_utility/tlsio_wolfssl.h"
+#include "target_syssvc.h"
+
+int platform_init(void)
+{
+	return 0;
+}
+
+const IO_INTERFACE_DESCRIPTION* platform_get_default_tlsio(void)
+{
+	//return tlsio_esp_at_get_interface_description();
+	return tlsio_wolfssl_get_interface_description();
+}
+
+STRING_HANDLE platform_get_platform_info(PLATFORM_INFO_OPTION options)
+{
+	// Expected format: "(<runtime name>; <operating system name>; <platform>)"
+
+	return STRING_construct("(native; TOPPERS/ASP; "TARGET_NAME")");
+}
+
+void platform_deinit(void)
+{
+}
Index: azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/adapters/socketio_esp_at.c
===================================================================
--- azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/adapters/socketio_esp_at.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/adapters/socketio_esp_at.c	(revision 457)
@@ -0,0 +1,496 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+#include <stdlib.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <string.h>
+#include "azure_c_shared_utility/socketio.h"
+#include "azure_c_shared_utility/singlylinkedlist.h"
+#include "azure_c_shared_utility/esp_at_socket.h"
+#include "azure_c_shared_utility/optimize_size.h"
+#include "azure_c_shared_utility/xlogging.h"
+
+#define ESP_AT_XIO_RECEIVE_BUFFER_SIZE    128
+
+typedef enum IO_STATE_TAG
+{
+    IO_STATE_CLOSED,
+    IO_STATE_OPENING,
+    IO_STATE_OPEN,
+    IO_STATE_CLOSING,
+    IO_STATE_ERROR
+} IO_STATE;
+
+typedef struct PENDING_SOCKET_IO_TAG
+{
+    unsigned char* bytes;
+    size_t size;
+    ON_SEND_COMPLETE on_send_complete;
+    void* callback_context;
+    SINGLYLINKEDLIST_HANDLE pending_io_list;
+} PENDING_SOCKET_IO;
+
+typedef struct SOCKET_IO_INSTANCE_TAG
+{
+    ESP_AT_SOCKET_HANDLE tcp_socket_connection;
+    ON_BYTES_RECEIVED on_bytes_received;
+    ON_IO_ERROR on_io_error;
+    void* on_bytes_received_context;
+    void* on_io_error_context;
+    char* hostname;
+    int port;
+    IO_STATE io_state;
+    SINGLYLINKEDLIST_HANDLE pending_io_list;
+} SOCKET_IO_INSTANCE;
+
+/*this function will clone an option given by name and value*/
+static void* socketio_CloneOption(const char* name, const void* value)
+{
+    (void)name;
+    (void)value;
+    return NULL;
+}
+
+/*this function destroys an option previously created*/
+static void socketio_DestroyOption(const char* name, const void* value)
+{
+    (void)name;
+    (void)value;
+}
+
+static OPTIONHANDLER_HANDLE socketio_retrieveoptions(CONCRETE_IO_HANDLE socket_io)
+{
+    OPTIONHANDLER_HANDLE result;
+    (void)socket_io;
+    result = OptionHandler_Create(socketio_CloneOption, socketio_DestroyOption, socketio_setoption);
+    if (result == NULL)
+    {
+        /*return as is*/
+    }
+    else
+    {
+        /*insert here work to add the options to "result" handle*/
+    }
+    return result;
+}
+
+static const IO_INTERFACE_DESCRIPTION socket_io_interface_description =
+{
+    socketio_retrieveoptions,
+    socketio_create,
+    socketio_destroy,
+    socketio_open,
+    socketio_close,
+    socketio_send,
+    socketio_dowork,
+    socketio_setoption
+};
+
+static void indicate_error(SOCKET_IO_INSTANCE* socket_io_instance)
+{
+    if ((socket_io_instance->io_state == IO_STATE_CLOSED)
+        || (socket_io_instance->io_state == IO_STATE_ERROR))
+    {
+        return;
+    }
+    socket_io_instance->io_state = IO_STATE_ERROR;
+    if (socket_io_instance->on_io_error != NULL)
+    {
+        socket_io_instance->on_io_error(socket_io_instance->on_io_error_context);
+    }
+}
+
+static int add_pending_io(SOCKET_IO_INSTANCE* socket_io_instance, const unsigned char* buffer, size_t size, ON_SEND_COMPLETE on_send_complete, void* callback_context)
+{
+    int result;
+    PENDING_SOCKET_IO* pending_socket_io = (PENDING_SOCKET_IO*)malloc(sizeof(PENDING_SOCKET_IO));
+    if (pending_socket_io == NULL)
+    {
+        LogError("Allocation Failure: Unable to allocate pending list.");
+        result = MU_FAILURE;
+    }
+    else
+    {
+        pending_socket_io->bytes = (unsigned char*)malloc(size);
+        if (pending_socket_io->bytes == NULL)
+        {
+            LogError("Allocation Failure: Unable to allocate pending list.");
+            free(pending_socket_io);
+            result = MU_FAILURE;
+        }
+        else
+        {
+            pending_socket_io->size = size;
+            pending_socket_io->on_send_complete = on_send_complete;
+            pending_socket_io->callback_context = callback_context;
+            pending_socket_io->pending_io_list = socket_io_instance->pending_io_list;
+            (void)memcpy(pending_socket_io->bytes, buffer, size);
+            if (singlylinkedlist_add(socket_io_instance->pending_io_list, pending_socket_io) == NULL)
+            {
+                LogError("Failure: Unable to add socket to pending list.");
+                free(pending_socket_io->bytes);
+                free(pending_socket_io);
+                result = MU_FAILURE;
+            }
+            else
+            {
+                result = 0;
+            }
+        }
+    }
+
+    return result;
+}
+
+#define NSAPI_ERROR_WOULD_BLOCK   -3001
+
+static int retrieve_data(SOCKET_IO_INSTANCE* socket_io_instance)
+{
+    int received = 1;
+    int total_received = 0;
+
+    unsigned char* recv_bytes = malloc(ESP_AT_XIO_RECEIVE_BUFFER_SIZE);
+    if (recv_bytes == NULL)
+    {
+        LogError("Socketio_Failure: NULL allocating input buffer.");
+        indicate_error(socket_io_instance);
+        return -1;
+    }
+    
+    while (received > 0)
+    {
+        received = esp_at_socket_receive(socket_io_instance->tcp_socket_connection, (char*)recv_bytes, ESP_AT_XIO_RECEIVE_BUFFER_SIZE);
+        if (received > 0)
+        {
+            total_received += received;
+            if (socket_io_instance->on_bytes_received != NULL)
+            {
+                /* explictly ignoring here the result of the callback */
+                socket_io_instance->on_bytes_received(socket_io_instance->on_bytes_received_context, recv_bytes, received);
+            }
+        }
+        else if (received < 0)
+        {
+            if(received != NSAPI_ERROR_WOULD_BLOCK)     // NSAPI_ERROR_WOULD_BLOCK is not a real error but pending.
+            {
+                indicate_error(socket_io_instance);
+                LogError("Socketio_Failure: underlying IO error %d.", received);
+                free(recv_bytes);
+                return -1;
+            }
+        }
+    }
+    free(recv_bytes);
+    
+    return total_received;
+}
+
+static int send_queued_data(SOCKET_IO_INSTANCE* socket_io_instance)
+{
+    int errors = 0;
+    int sent = 0;
+    
+    LIST_ITEM_HANDLE first_pending_io = singlylinkedlist_get_head_item(socket_io_instance->pending_io_list);
+    while (first_pending_io != NULL)
+    {
+        PENDING_SOCKET_IO* pending_socket_io = (PENDING_SOCKET_IO*)singlylinkedlist_item_get_value(first_pending_io);
+        if (pending_socket_io == NULL)
+        {
+            indicate_error(socket_io_instance);
+            return -1;
+        }
+
+        int send_result = esp_at_socket_send(socket_io_instance->tcp_socket_connection, (const char*)pending_socket_io->bytes, pending_socket_io->size);
+        if (send_result != (int)pending_socket_io->size)
+        {
+            if (send_result == 0)
+            {
+                // The underlying network layer may encounter hardware / environment issues, 
+                // but the driver doesn't handle it properly. So here the send API always return 0, 
+                // this causes the program running into dead loop if not check it here.
+                if (errors++ >= 10)
+                {
+                    // Treat it as a network error after try 10 times.
+                    LogError("Socketio_Failure: encountered unknow connection issue, the connection will be restarted.");
+                    indicate_error(socket_io_instance);
+                    return -1;
+                }
+                ThreadAPI_Sleep(10);
+            }
+            else if (send_result < 0)
+            {
+                indicate_error(socket_io_instance);
+                return -1;
+            }
+            else
+            {
+                /* send something, wait for the rest */
+                memmove(pending_socket_io->bytes, pending_socket_io->bytes + send_result, pending_socket_io->size - send_result);
+                sent += send_result;
+            }
+        }
+        else
+        {
+            sent += send_result;
+            if (pending_socket_io->on_send_complete != NULL)
+            {
+                pending_socket_io->on_send_complete(pending_socket_io->callback_context, IO_SEND_OK);
+            }
+
+            free(pending_socket_io->bytes);
+            free(pending_socket_io);
+            if (singlylinkedlist_remove(socket_io_instance->pending_io_list, first_pending_io) != 0)
+            {
+                indicate_error(socket_io_instance);
+                return -1;
+            }
+            errors = 0;
+        }
+
+        first_pending_io = singlylinkedlist_get_head_item(socket_io_instance->pending_io_list);
+    }
+
+    return sent;
+}
+
+static void close_tcp_connection(SOCKET_IO_INSTANCE* socket_io_instance)
+{
+    if (socket_io_instance->io_state != IO_STATE_CLOSED)
+    {
+        if (socket_io_instance->tcp_socket_connection != NULL)
+        {
+            esp_at_socket_close(socket_io_instance->tcp_socket_connection);
+            esp_at_socket_destroy(socket_io_instance->tcp_socket_connection);
+            socket_io_instance->tcp_socket_connection = NULL;
+        }
+        socket_io_instance->io_state = IO_STATE_CLOSED;
+    }
+}
+
+CONCRETE_IO_HANDLE socketio_create(void* io_create_parameters)
+{
+    SOCKETIO_CONFIG* socket_io_config = io_create_parameters;
+    SOCKET_IO_INSTANCE* result;
+
+    if (socket_io_config == NULL)
+    {
+        result = NULL;
+    }
+    else
+    {    
+        result = (SOCKET_IO_INSTANCE*)malloc(sizeof(SOCKET_IO_INSTANCE));
+        if (result == NULL){
+            LogError("Socketio_Failure: NULL allocating socket io instance.");
+        }
+        else
+        {
+            result->pending_io_list = singlylinkedlist_create();
+            if (result->pending_io_list == NULL)
+            {
+                free(result);
+                result = NULL;
+            }
+            else
+            {
+                result->hostname = strdup(socket_io_config->hostname);
+                if (result->hostname == NULL)
+                {
+                    singlylinkedlist_destroy(result->pending_io_list);
+                    free(result);
+                    result = NULL;
+                }
+                else
+                {
+                    result->port = socket_io_config->port;
+                    result->on_bytes_received = NULL;
+                    result->on_io_error = NULL;
+                    result->on_bytes_received_context = NULL;
+                    result->on_io_error_context = NULL;
+                    result->io_state = IO_STATE_CLOSED;
+                    result->tcp_socket_connection = NULL;
+                }
+            }
+        }
+    }
+
+    return result;
+}
+
+void socketio_destroy(CONCRETE_IO_HANDLE socket_io)
+{
+    if (socket_io != NULL)
+    {
+        SOCKET_IO_INSTANCE* socket_io_instance = (SOCKET_IO_INSTANCE*)socket_io;
+
+        // Close the tcp connection
+        close_tcp_connection(socket_io_instance);
+    
+        // Clear all pending IOs
+        LIST_ITEM_HANDLE first_pending_io = singlylinkedlist_get_head_item(socket_io_instance->pending_io_list);
+        while (first_pending_io != NULL)
+        {
+            PENDING_SOCKET_IO* pending_socket_io = (PENDING_SOCKET_IO*)singlylinkedlist_item_get_value(first_pending_io);
+            if (pending_socket_io != NULL)
+            {
+                free(pending_socket_io->bytes);
+                free(pending_socket_io);
+            }
+
+            (void)singlylinkedlist_remove(socket_io_instance->pending_io_list, first_pending_io);
+            first_pending_io = singlylinkedlist_get_head_item(socket_io_instance->pending_io_list);
+        }
+        singlylinkedlist_destroy(socket_io_instance->pending_io_list);
+    
+        if(socket_io_instance->hostname != NULL)
+        {
+            free(socket_io_instance->hostname);
+            socket_io_instance->hostname = NULL;
+        }
+        free(socket_io);
+    }
+}
+
+int socketio_open(CONCRETE_IO_HANDLE socket_io, ON_IO_OPEN_COMPLETE on_io_open_complete, void* on_io_open_complete_context, ON_BYTES_RECEIVED on_bytes_received, void* on_bytes_received_context, ON_IO_ERROR on_io_error, void* on_io_error_context)
+{
+    int result;
+    SOCKET_IO_INSTANCE* socket_io_instance = (SOCKET_IO_INSTANCE*)socket_io;
+    
+
+    if (socket_io_instance == NULL ||
+        socket_io_instance->io_state != IO_STATE_CLOSED)
+    {
+        result = MU_FAILURE;
+    }
+    else
+    {
+        socket_io_instance->tcp_socket_connection = esp_at_socket_create(false);
+        if (socket_io_instance->tcp_socket_connection == NULL)
+        {
+            result = MU_FAILURE;
+        }
+        else
+        {
+            if (esp_at_socket_connect(socket_io_instance->tcp_socket_connection, socket_io_instance->hostname, socket_io_instance->port) != 0)
+            {
+                esp_at_socket_destroy(socket_io_instance->tcp_socket_connection);
+                socket_io_instance->tcp_socket_connection = NULL;
+                result = MU_FAILURE;
+            }
+            else
+            {
+                esp_at_socket_set_blocking(socket_io_instance->tcp_socket_connection, false, 0);
+
+                socket_io_instance->on_bytes_received = on_bytes_received;
+                socket_io_instance->on_bytes_received_context = on_bytes_received_context;
+
+                socket_io_instance->on_io_error = on_io_error;
+                socket_io_instance->on_io_error_context = on_io_error_context;
+
+                socket_io_instance->io_state = IO_STATE_OPEN;
+
+                result = 0;
+            }
+        }
+    }
+    
+    if (on_io_open_complete != NULL)
+    {
+        on_io_open_complete(on_io_open_complete_context, result == 0 ? IO_OPEN_OK : IO_OPEN_ERROR);
+    }
+
+    return result;
+}
+
+int socketio_close(CONCRETE_IO_HANDLE socket_io, ON_IO_CLOSE_COMPLETE on_io_close_complete, void* callback_context)
+{
+    int result = 0;
+
+    if (socket_io == NULL)
+    {
+        result = MU_FAILURE;
+    }
+    else
+    {
+        SOCKET_IO_INSTANCE* socket_io_instance = (SOCKET_IO_INSTANCE*)socket_io;
+        if (socket_io_instance->io_state == IO_STATE_CLOSED || 
+            socket_io_instance->io_state == IO_STATE_ERROR)
+        {
+            result = MU_FAILURE;
+        }
+        else
+        {
+            close_tcp_connection(socket_io_instance);
+            if (on_io_close_complete != NULL)
+            {
+                on_io_close_complete(callback_context);
+            }
+            result = 0;
+        }
+    }
+    
+    return result;
+}
+
+int socketio_send(CONCRETE_IO_HANDLE socket_io, const void* buffer, size_t size, ON_SEND_COMPLETE on_send_complete, void* callback_context)
+{
+    int result;
+
+    if ((socket_io == NULL) ||
+        (buffer == NULL) ||
+        (size == 0))
+    {
+        /* Invalid arguments */
+        result = MU_FAILURE;
+    }
+    else
+    {
+        result = 0;
+
+        SOCKET_IO_INSTANCE* socket_io_instance = (SOCKET_IO_INSTANCE*)socket_io;
+        if (socket_io_instance->io_state != IO_STATE_OPEN)
+        {
+            result = MU_FAILURE;
+        }
+        else
+        {
+            // Queue the data, and the socketio_dowork sends the package later
+            if (add_pending_io(socket_io_instance, buffer, size, on_send_complete, callback_context) != 0)
+            {
+                result = MU_FAILURE;
+            }
+        }
+    }
+
+    return result;
+}
+
+void socketio_dowork(CONCRETE_IO_HANDLE socket_io)
+{
+    if (socket_io != NULL)
+    {
+        SOCKET_IO_INSTANCE* socket_io_instance = (SOCKET_IO_INSTANCE*)socket_io;
+        if (socket_io_instance->io_state == IO_STATE_OPEN)
+        {
+            // Retrieve all data from IoT Hub
+            if (retrieve_data(socket_io_instance) < 0)
+            {
+                return;
+            }
+        
+            // Send all packages in the queue
+            send_queued_data(socket_io_instance);
+        }
+    }
+}
+
+int socketio_setoption(CONCRETE_IO_HANDLE socket_io, const char* optionName, const void* value)
+{
+    /* Not implementing any options, do nothing */
+    return OPTIONHANDLER_OK;
+}
+
+const IO_INTERFACE_DESCRIPTION* socketio_get_interface_description(void)
+{
+    return &socket_io_interface_description;
+}
Index: azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/adapters/socketio_lwip.c
===================================================================
--- azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/adapters/socketio_lwip.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/adapters/socketio_lwip.c	(revision 457)
@@ -0,0 +1,1222 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+#ifndef _BSD_SOURCE
+#define _BSD_SOURCE
+#define SOCKETIO_BERKELEY_UNDEF_BSD_SOURCE
+#endif
+
+#define _DEFAULT_SOURCE
+#include <net/if.h>
+#undef _DEFAULT_SOURCE
+
+#ifdef SOCKETIO_BERKELEY_UNDEF_BSD_SOURCE
+#undef _BSD_SOURCE
+#undef SOCKETIO_BERKELEY_UNDEF_BSD_SOURCE
+#endif
+
+#include <signal.h>
+#include <stdlib.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <string.h>
+#include <ctype.h>
+#include "azure_c_shared_utility/socketio.h"
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/select.h>
+#ifdef TIZENRT
+#include <net/lwip/tcp.h>
+#else
+#include <lwip/tcp.h>
+#endif
+#include <netdb.h>
+#include <unistd.h>
+#include <errno.h>
+#include "azure_c_shared_utility/singlylinkedlist.h"
+#include "azure_c_shared_utility/gballoc.h"
+#include "azure_c_shared_utility/gbnetwork.h"
+#include "azure_c_shared_utility/optimize_size.h"
+#include "azure_c_shared_utility/optionhandler.h"
+#include "azure_c_shared_utility/shared_util_options.h"
+#include "azure_c_shared_utility/xlogging.h"
+#include "azure_c_shared_utility/const_defines.h"
+#include "azure_c_shared_utility/dns_resolver.h"
+//#include <sys/ioctl.h>
+//#include <netinet/in.h>
+//#include <arpa/inet.h>
+//#include <sys/un.h>
+
+#define SOCKET_SUCCESS                 0
+#define INVALID_SOCKET                 -1
+#define SOCKET_SEND_FAILURE            -1
+#define MAC_ADDRESS_STRING_LENGTH      18
+
+#ifndef IFREQ_BUFFER_SIZE
+#define IFREQ_BUFFER_SIZE              1024
+#endif
+
+// connect timeout in seconds
+#define CONNECT_TIMEOUT         10
+
+typedef enum IO_STATE_TAG
+{
+    IO_STATE_CLOSED,
+    IO_STATE_OPENING,
+    IO_STATE_OPEN,
+    IO_STATE_CLOSING,
+    IO_STATE_ERROR
+} IO_STATE;
+
+typedef struct PENDING_SOCKET_IO_TAG
+{
+    unsigned char* bytes;
+    size_t size;
+    ON_SEND_COMPLETE on_send_complete;
+    void* callback_context;
+    SINGLYLINKEDLIST_HANDLE pending_io_list;
+} PENDING_SOCKET_IO;
+
+typedef struct SOCKET_IO_INSTANCE_TAG
+{
+    int socket;
+    SOCKETIO_ADDRESS_TYPE address_type;
+    ON_BYTES_RECEIVED on_bytes_received;
+    ON_IO_ERROR on_io_error;
+    ON_IO_OPEN_COMPLETE on_io_open_complete;
+    void* on_bytes_received_context;
+    void* on_io_error_context;
+    void* on_io_open_complete_context;
+    char* hostname;
+    int port;
+    char* target_mac_address;
+    IO_STATE io_state;
+    SINGLYLINKEDLIST_HANDLE pending_io_list;
+    unsigned char recv_bytes[RECEIVE_BYTES_VALUE];
+    DNSRESOLVER_HANDLE dns_resolver;
+} SOCKET_IO_INSTANCE;
+
+typedef struct NETWORK_INTERFACE_DESCRIPTION_TAG
+{
+    char* name;
+    char* mac_address;
+    char* ip_address;
+    struct NETWORK_INTERFACE_DESCRIPTION_TAG* next;
+} NETWORK_INTERFACE_DESCRIPTION;
+
+/*this function will clone an option given by name and value*/
+static void* socketio_CloneOption(const char* name, const void* value)
+{
+    void* result;
+
+    if (name != NULL)
+    {
+        result = NULL;
+
+        if (strcmp(name, OPTION_NET_INT_MAC_ADDRESS) == 0)
+        {
+            if (value == NULL)
+            {
+                LogError("Failed cloning option %s (value is NULL)", name);
+            }
+            else
+            {
+                if ((result = malloc(sizeof(char) * (strlen((char*)value) + 1))) == NULL)
+                {
+                    LogError("Failed cloning option %s (malloc failed)", name);
+                }
+                else if (strcpy((char*)result, (char*)value) == NULL)
+                {
+                    LogError("Failed cloning option %s (strcpy failed)", name);
+                    free(result);
+                    result = NULL;
+                }
+            }
+        }
+        else
+        {
+            LogError("Cannot clone option %s (not suppported)", name);
+        }
+    }
+    else
+    {
+        result = NULL;
+    }
+    return result;
+}
+
+/*this function destroys an option previously created*/
+static void socketio_DestroyOption(const char* name, const void* value)
+{
+    if (name != NULL)
+    {
+        if (strcmp(name, OPTION_NET_INT_MAC_ADDRESS) == 0 && value != NULL)
+        {
+            free((void*)value);
+        }
+    }
+}
+
+static OPTIONHANDLER_HANDLE socketio_retrieveoptions(CONCRETE_IO_HANDLE handle)
+{
+    OPTIONHANDLER_HANDLE result;
+
+    if (handle == NULL)
+    {
+        LogError("failed retrieving options (handle is NULL)");
+        result = NULL;
+    }
+    else
+    {
+        SOCKET_IO_INSTANCE* socket_io_instance = (SOCKET_IO_INSTANCE*)handle;
+
+        result = OptionHandler_Create(socketio_CloneOption, socketio_DestroyOption, socketio_setoption);
+        if (result == NULL)
+        {
+            LogError("unable to OptionHandler_Create");
+        }
+        else if (socket_io_instance->target_mac_address != NULL &&
+            OptionHandler_AddOption(result, OPTION_NET_INT_MAC_ADDRESS, socket_io_instance->target_mac_address) != OPTIONHANDLER_OK)
+        {
+            LogError("failed retrieving options (failed adding net_interface_mac_address)");
+            OptionHandler_Destroy(result);
+            result = NULL;
+        }
+    }
+
+    return result;
+}
+
+static const IO_INTERFACE_DESCRIPTION socket_io_interface_description =
+{
+    socketio_retrieveoptions,
+    socketio_create,
+    socketio_destroy,
+    socketio_open,
+    socketio_close,
+    socketio_send,
+    socketio_dowork,
+    socketio_setoption
+};
+
+static void indicate_error(SOCKET_IO_INSTANCE* socket_io_instance)
+{
+    socket_io_instance->io_state = IO_STATE_ERROR;
+    if (socket_io_instance->on_io_error != NULL)
+    {
+        socket_io_instance->on_io_error(socket_io_instance->on_io_error_context);
+    }
+}
+
+static int add_pending_io(SOCKET_IO_INSTANCE* socket_io_instance, const unsigned char* buffer, size_t size, ON_SEND_COMPLETE on_send_complete, void* callback_context)
+{
+    int result;
+    PENDING_SOCKET_IO* pending_socket_io = (PENDING_SOCKET_IO*)malloc(sizeof(PENDING_SOCKET_IO));
+    if (pending_socket_io == NULL)
+    {
+        result = MU_FAILURE;
+    }
+    else
+    {
+        pending_socket_io->bytes = (unsigned char*)malloc(size);
+        if (pending_socket_io->bytes == NULL)
+        {
+            LogError("Allocation Failure: Unable to allocate pending list.");
+            free(pending_socket_io);
+            result = MU_FAILURE;
+        }
+        else
+        {
+            pending_socket_io->size = size;
+            pending_socket_io->on_send_complete = on_send_complete;
+            pending_socket_io->callback_context = callback_context;
+            pending_socket_io->pending_io_list = socket_io_instance->pending_io_list;
+            (void)memcpy(pending_socket_io->bytes, buffer, size);
+
+            if (singlylinkedlist_add(socket_io_instance->pending_io_list, pending_socket_io) == NULL)
+            {
+                LogError("Failure: Unable to add socket to pending list.");
+                free(pending_socket_io->bytes);
+                free(pending_socket_io);
+                result = MU_FAILURE;
+            }
+            else
+            {
+                result = 0;
+            }
+        }
+    }
+    return result;
+}
+
+static STATIC_VAR_UNUSED void signal_callback(int signum)
+{
+    AZURE_UNREFERENCED_PARAMETER(signum);
+    LogError("Socket received signal %d.", signum);
+}
+
+static int lookup_address(SOCKET_IO_INSTANCE* socket_io_instance)
+{
+    int result = 0;
+
+    if (socket_io_instance->address_type == ADDRESS_TYPE_IP)
+    {
+        if (!dns_resolver_is_lookup_complete(socket_io_instance->dns_resolver))
+        {
+            socket_io_instance->io_state = IO_STATE_OPENING;
+        }
+        else
+        {
+            socket_io_instance->io_state = IO_STATE_OPEN;
+        }
+    }
+    else //ADDRESS_TYPE_DOMAIN_SOCKET
+    {
+        socket_io_instance->io_state = IO_STATE_OPEN;
+    }
+
+    return result;
+}
+
+static int initiate_socket_connection(SOCKET_IO_INSTANCE* socket_io_instance)
+{
+    int result;
+    int flags;
+    struct addrinfo* addr = NULL;
+    struct sockaddr* connect_addr = NULL;
+    struct sockaddr_un addrInfoUn;
+    socklen_t connect_addr_len;
+
+    if (socket_io_instance->address_type == ADDRESS_TYPE_IP)
+    {
+        if(!dns_resolver_is_lookup_complete(socket_io_instance->dns_resolver))
+        {
+            LogError("DNS did not resolve IP address");
+            result = MU_FAILURE;
+        }
+        else
+        {
+            addr = dns_resolver_get_addrInfo(socket_io_instance->dns_resolver);
+
+            if (addr == NULL)
+            {
+                LogError("DNS resolution failed");
+                result = MU_FAILURE;
+            }
+            else
+            {
+                connect_addr = addr->ai_addr;
+                connect_addr_len = sizeof(*addr->ai_addr);
+                result = 0;
+            }
+        }
+    }
+    else
+    {
+        size_t hostname_len = strlen(socket_io_instance->hostname);
+        if (hostname_len + 1 > sizeof(addrInfoUn.sun_path))
+        {
+            LogError("Hostname %s is too long for a unix socket (max len = %lu)", socket_io_instance->hostname, (unsigned long)sizeof(addrInfoUn.sun_path));
+            result = MU_FAILURE;
+        }
+        else
+        {
+            memset(&addrInfoUn, 0, sizeof(addrInfoUn));
+            addrInfoUn.sun_family = AF_UNIX;
+            // No need to add NULL terminator due to the above memset
+            (void)memcpy(addrInfoUn.sun_path, socket_io_instance->hostname, hostname_len);
+
+            connect_addr = (struct sockaddr*)&addrInfoUn;
+            connect_addr_len = sizeof(addrInfoUn);
+            result = 0;
+        }
+    }
+
+    if (result == 0)
+    {
+        if ((-1 == (flags = fcntl(socket_io_instance->socket, F_GETFL, 0))) ||
+            (fcntl(socket_io_instance->socket, F_SETFL, flags | O_NONBLOCK) == -1))
+        {
+            LogError("Failure: fcntl failure.");
+            result = MU_FAILURE;
+        }
+        else
+        {
+            result = connect(socket_io_instance->socket, connect_addr, connect_addr_len);
+            if ((result != 0) && (errno != EINPROGRESS))
+            {
+                LogError("Failure: connect failure %d.", errno);
+                result = MU_FAILURE;
+            }
+            else
+            {
+                // Async connect will return -1.
+                result = 0;
+                if (socket_io_instance->on_io_open_complete != NULL)
+                {
+                    socket_io_instance->on_io_open_complete(socket_io_instance->on_io_open_complete_context, IO_OPEN_OK /*: IO_OPEN_ERROR*/);
+                }
+            }
+        }
+    }
+
+    return result;
+}
+
+static int lookup_address_and_initiate_socket_connection(SOCKET_IO_INSTANCE* socket_io_instance)
+{
+    int result;
+
+    result = lookup_address(socket_io_instance);
+
+    if(socket_io_instance->io_state == IO_STATE_OPEN)
+    {
+        if (result == 0)
+        {
+            result = initiate_socket_connection(socket_io_instance);
+        }
+    }
+
+    return result;
+}
+
+static int wait_for_connection(SOCKET_IO_INSTANCE* socket_io_instance)
+{
+    int result;
+    int err;
+    int retval;
+    int select_errno = 0;
+
+    fd_set fdset;
+    struct timeval tv;
+
+    FD_ZERO(&fdset);
+    FD_SET(socket_io_instance->socket, &fdset);
+    tv.tv_sec = CONNECT_TIMEOUT;
+    tv.tv_usec = 0;
+
+    do
+    {
+        retval = select(socket_io_instance->socket + 1, NULL, &fdset, NULL, &tv);
+
+        if (retval < 0)
+        {
+            select_errno = errno;
+        }
+    } while (retval < 0 && select_errno == EINTR);
+
+    if (retval != 1)
+    {
+        LogError("Failure: select failure.");
+        result = MU_FAILURE;
+    }
+    else
+    {
+        int so_error = 0;
+        socklen_t len = sizeof(so_error);
+        err = getsockopt(socket_io_instance->socket, SOL_SOCKET, SO_ERROR, &so_error, &len);
+        if (err != 0)
+        {
+            LogError("Failure: getsockopt failure %d.", errno);
+            result = MU_FAILURE;
+        }
+        else if (so_error != 0)
+        {
+            err = so_error;
+            LogError("Failure: connect failure %d.", so_error);
+            result = MU_FAILURE;
+        }
+        else
+        {
+            result = 0;
+        }
+    }
+
+    return result;
+}
+
+
+
+#ifndef __APPLE__
+static void destroy_network_interface_descriptions(NETWORK_INTERFACE_DESCRIPTION* nid)
+{
+    if (nid != NULL)
+    {
+        if (nid->next != NULL)
+        {
+            destroy_network_interface_descriptions(nid->next);
+        }
+
+        if (nid->name != NULL)
+        {
+            free(nid->name);
+        }
+
+        if (nid->mac_address != NULL)
+        {
+            free(nid->mac_address);
+        }
+
+        if (nid->ip_address != NULL)
+        {
+            free(nid->ip_address);
+        }
+
+        free(nid);
+    }
+}
+
+static NETWORK_INTERFACE_DESCRIPTION* create_network_interface_description(struct ifreq *ifr, NETWORK_INTERFACE_DESCRIPTION* previous_nid)
+{
+    NETWORK_INTERFACE_DESCRIPTION* result;
+
+    if ((result = (NETWORK_INTERFACE_DESCRIPTION*)malloc(sizeof(NETWORK_INTERFACE_DESCRIPTION))) == NULL)
+    {
+        LogError("Failed allocating NETWORK_INTERFACE_DESCRIPTION");
+    }
+    else if ((result->name = (char*)malloc(sizeof(char) * (strlen(ifr->ifr_name) + 1))) == NULL)
+    {
+        LogError("failed setting interface description name (malloc failed)");
+        destroy_network_interface_descriptions(result);
+        result = NULL;
+    }
+    else if (strcpy(result->name, ifr->ifr_name) == NULL)
+    {
+        LogError("failed setting interface description name (strcpy failed)");
+        destroy_network_interface_descriptions(result);
+        result = NULL;
+    }
+    else
+    {
+        char* ip_address;
+        unsigned char* mac = (unsigned char*)ifr->ifr_hwaddr.sa_data;
+
+        if ((result->mac_address = (char*)malloc(sizeof(char) * MAC_ADDRESS_STRING_LENGTH)) == NULL)
+        {
+            LogError("failed formatting mac address (malloc failed)");
+            destroy_network_interface_descriptions(result);
+            result = NULL;
+        }
+        else if (sprintf(result->mac_address, "%02X:%02X:%02X:%02X:%02X:%02X", mac[0],mac[1],mac[2],mac[3],mac[4],mac[5]) <= 0)
+        {
+            LogError("failed formatting mac address (sprintf failed)");
+            destroy_network_interface_descriptions(result);
+            result = NULL;
+        }
+        else if ((ip_address = inet_ntoa(((struct sockaddr_in*)&ifr->ifr_addr)->sin_addr)) == NULL)
+        {
+            LogError("failed setting the ip address (inet_ntoa failed)");
+            destroy_network_interface_descriptions(result);
+            result = NULL;
+        }
+        else if ((result->ip_address = (char*)malloc(sizeof(char) * (strlen(ip_address) + 1))) == NULL)
+        {
+            LogError("failed setting the ip address (malloc failed)");
+            destroy_network_interface_descriptions(result);
+            result = NULL;
+        }
+        else if (strcpy(result->ip_address, ip_address) == NULL)
+        {
+            LogError("failed setting the ip address (strcpy failed)");
+            destroy_network_interface_descriptions(result);
+            result = NULL;
+        }
+        else
+        {
+            result->next = NULL;
+
+            if (previous_nid != NULL)
+            {
+                previous_nid->next = result;
+            }
+        }
+    }
+
+    return result;
+}
+
+static int get_network_interface_descriptions(int socket, NETWORK_INTERFACE_DESCRIPTION** nid)
+{
+    int result;
+
+    struct ifreq ifr;
+    struct ifconf ifc;
+    char buf[IFREQ_BUFFER_SIZE];
+
+    ifc.ifc_len = sizeof(buf);
+    ifc.ifc_buf = buf;
+
+    if (ioctl(socket, SIOCGIFCONF, &ifc) == -1)
+    {
+        LogError("ioctl failed querying socket (SIOCGIFCONF, errno=%d)", errno);
+        result = MU_FAILURE;
+    }
+    else
+    {
+        NETWORK_INTERFACE_DESCRIPTION* root_nid = NULL;
+        NETWORK_INTERFACE_DESCRIPTION* new_nid = NULL;
+
+        struct ifreq* it = ifc.ifc_req;
+        const struct ifreq* const end = it + (ifc.ifc_len / sizeof(struct ifreq));
+
+        result = 0;
+
+        for (; it != end; ++it)
+        {
+            strcpy(ifr.ifr_name, it->ifr_name);
+
+            if (ioctl(socket, SIOCGIFFLAGS, &ifr) != 0)
+            {
+                LogError("ioctl failed querying socket (SIOCGIFFLAGS, errno=%d)", errno);
+                result = MU_FAILURE;
+                break;
+            }
+            else if (ioctl(socket, SIOCGIFHWADDR, &ifr) != 0)
+            {
+                LogError("ioctl failed querying socket (SIOCGIFHWADDR, errno=%d)", errno);
+                result = MU_FAILURE;
+                break;
+            }
+            else if (ioctl(socket, SIOCGIFADDR, &ifr) != 0)
+            {
+                LogError("ioctl failed querying socket (SIOCGIFADDR, errno=%d)", errno);
+                result = MU_FAILURE;
+                break;
+            }
+            else if ((new_nid = create_network_interface_description(&ifr, new_nid)) == NULL)
+            {
+                LogError("Failed creating network interface description");
+                result = MU_FAILURE;
+                break;
+            }
+            else if (root_nid == NULL)
+            {
+                root_nid = new_nid;
+            }
+        }
+
+        if (result == 0)
+        {
+            *nid = root_nid;
+        }
+        else
+        {
+            destroy_network_interface_descriptions(root_nid);
+        }
+    }
+
+    return result;
+}
+
+static int set_target_network_interface(int socket, char* mac_address)
+{
+    int result;
+    NETWORK_INTERFACE_DESCRIPTION* nid;
+
+    if (get_network_interface_descriptions(socket, &nid) != 0)
+    {
+        LogError("Failed getting network interface descriptions");
+        result = MU_FAILURE;
+    }
+    else
+    {
+        NETWORK_INTERFACE_DESCRIPTION* current_nid = nid;
+
+        while(current_nid != NULL)
+        {
+            if (strcmp(mac_address, current_nid->mac_address) == 0)
+            {
+                break;
+            }
+
+            current_nid = current_nid->next;
+        }
+
+        if (current_nid == NULL)
+        {
+            LogError("Did not find a network interface matching MAC ADDRESS");
+            result = MU_FAILURE;
+        }
+        else if (setsockopt(socket, SOL_SOCKET, SO_BINDTODEVICE, current_nid->name, strlen(current_nid->name)) != 0)
+        {
+            LogError("setsockopt failed (%d)", errno);
+            result = MU_FAILURE;
+        }
+        else
+        {
+            result = 0;
+        }
+
+        destroy_network_interface_descriptions(nid);
+    }
+
+    return result;
+}
+#endif //__APPLE__
+
+static void destroy_socket_io_instance(SOCKET_IO_INSTANCE* instance)
+{
+    if (instance->dns_resolver != NULL)
+    {
+        dns_resolver_destroy(instance->dns_resolver);
+    }
+
+    free(instance->hostname);
+    free(instance->target_mac_address);
+
+    if (instance->pending_io_list != NULL)
+    {
+        singlylinkedlist_destroy(instance->pending_io_list);
+    }
+
+    free(instance);
+}
+
+CONCRETE_IO_HANDLE socketio_create(void* io_create_parameters)
+{
+    SOCKETIO_CONFIG* socket_io_config = io_create_parameters;
+    SOCKET_IO_INSTANCE* result;
+
+    if (socket_io_config == NULL)
+    {
+        LogError("Invalid argument: socket_io_config is NULL");
+        result = NULL;
+    }
+    else
+    {
+        result = malloc(sizeof(SOCKET_IO_INSTANCE));
+        if (result != NULL)
+        {
+            (void)memset(result, 0, sizeof(SOCKET_IO_INSTANCE));
+
+            result->address_type = ADDRESS_TYPE_IP;
+            result->pending_io_list = singlylinkedlist_create();
+            if (result->pending_io_list == NULL)
+            {
+                LogError("Failure: singlylinkedlist_create unable to create pending list.");
+                destroy_socket_io_instance(result);
+                result = NULL;
+            }
+            else
+            {
+                if (socket_io_config->hostname != NULL)
+                {
+                    result->hostname = (char*)malloc(strlen(socket_io_config->hostname) + 1);
+                    if (result->hostname != NULL)
+                    {
+                        (void)strcpy(result->hostname, socket_io_config->hostname);
+                    }
+
+                    result->socket = INVALID_SOCKET;
+                }
+                else
+                {
+                    result->hostname = NULL;
+                    result->socket = *((int*)socket_io_config->accepted_socket);
+                }
+
+                if ((result->hostname == NULL) && (result->socket == INVALID_SOCKET))
+                {
+                    LogError("Failure: hostname == NULL and socket is invalid.");
+                    destroy_socket_io_instance(result);
+                    result = NULL;
+                }
+                else
+                {
+                    result->port = socket_io_config->port;
+                    result->on_io_open_complete = NULL;
+                    result->dns_resolver = dns_resolver_create(result->hostname, socket_io_config->port, NULL);
+                    result->target_mac_address = NULL;
+                    result->on_bytes_received = NULL;
+                    result->on_io_error = NULL;
+                    result->on_bytes_received_context = NULL;
+                    result->on_io_error_context = NULL;
+                    result->io_state = IO_STATE_CLOSED;
+                }
+            }
+        }
+        else
+        {
+            LogError("Allocation Failure: SOCKET_IO_INSTANCE");
+        }
+    }
+
+    return result;
+}
+
+void socketio_destroy(CONCRETE_IO_HANDLE socket_io)
+{
+    if (socket_io != NULL)
+    {
+        SOCKET_IO_INSTANCE* socket_io_instance = (SOCKET_IO_INSTANCE*)socket_io;
+        /* we cannot do much if the close fails, so just ignore the result */
+        if (socket_io_instance->socket != INVALID_SOCKET)
+        {
+            close(socket_io_instance->socket);
+        }
+
+        /* clear allpending IOs */
+        LIST_ITEM_HANDLE first_pending_io = singlylinkedlist_get_head_item(socket_io_instance->pending_io_list);
+        while (first_pending_io != NULL)
+        {
+            PENDING_SOCKET_IO* pending_socket_io = (PENDING_SOCKET_IO*)singlylinkedlist_item_get_value(first_pending_io);
+            if (pending_socket_io != NULL)
+            {
+                free(pending_socket_io->bytes);
+                free(pending_socket_io);
+            }
+
+            (void)singlylinkedlist_remove(socket_io_instance->pending_io_list, first_pending_io);
+            first_pending_io = singlylinkedlist_get_head_item(socket_io_instance->pending_io_list);
+        }
+
+        destroy_socket_io_instance(socket_io_instance);
+    }
+}
+
+int socketio_open(CONCRETE_IO_HANDLE socket_io, ON_IO_OPEN_COMPLETE on_io_open_complete, void* on_io_open_complete_context, ON_BYTES_RECEIVED on_bytes_received, void* on_bytes_received_context, ON_IO_ERROR on_io_error, void* on_io_error_context)
+{
+    int result;
+
+    SOCKET_IO_INSTANCE* socket_io_instance = (SOCKET_IO_INSTANCE*)socket_io;
+    if (socket_io == NULL)
+    {
+        LogError("Invalid argument: SOCKET_IO_INSTANCE is NULL");
+        result = MU_FAILURE;
+    }
+    else
+    {
+        if (socket_io_instance->io_state != IO_STATE_CLOSED)
+        {
+            LogError("Failure: socket state is not closed.");
+            result = MU_FAILURE;
+        }
+        else if (socket_io_instance->socket != INVALID_SOCKET)
+        {
+            // Opening an accepted socket
+            socket_io_instance->on_bytes_received_context = on_bytes_received_context;
+            socket_io_instance->on_bytes_received = on_bytes_received;
+            socket_io_instance->on_io_error = on_io_error;
+            socket_io_instance->on_io_error_context = on_io_error_context;
+
+            socket_io_instance->io_state = IO_STATE_OPEN;
+
+            result = 0;
+        }
+        else
+        {
+            socket_io_instance->socket = socket (socket_io_instance->address_type == ADDRESS_TYPE_IP ? AF_INET : AF_UNIX, SOCK_STREAM, 0);
+            if (socket_io_instance->socket < SOCKET_SUCCESS)
+            {
+                LogError("Failure: socket create failure %d.", socket_io_instance->socket);
+                result = MU_FAILURE;
+            }
+#ifndef __APPLE__
+            else if (socket_io_instance->target_mac_address != NULL &&
+                     set_target_network_interface(socket_io_instance->socket, socket_io_instance->target_mac_address) != 0)
+            {
+                LogError("Failure: failed selecting target network interface (MACADDR=%s).", socket_io_instance->target_mac_address);
+                result = MU_FAILURE;
+            }
+#endif //__APPLE__
+            else if ((result = lookup_address_and_initiate_socket_connection(socket_io_instance)) != 0)
+            {
+                LogError("lookup_address_and_connect_socket failed");
+            }
+            else if ((result = wait_for_connection(socket_io_instance)) != 0)
+            {
+                LogError("wait_for_connection failed");
+            }
+
+            if (result == 0)
+            {
+                socket_io_instance->on_bytes_received = on_bytes_received;
+                socket_io_instance->on_bytes_received_context = on_bytes_received_context;
+
+                socket_io_instance->on_io_error = on_io_error;
+                socket_io_instance->on_io_error_context = on_io_error_context;
+
+                socket_io_instance->on_io_open_complete = on_io_open_complete;
+                socket_io_instance->on_io_open_complete_context = on_io_open_complete_context;
+            }
+            else
+            {
+                if (socket_io_instance->socket >= SOCKET_SUCCESS)
+                {
+                    close(socket_io_instance->socket);
+                }
+                socket_io_instance->socket = INVALID_SOCKET;
+            }
+        }
+    }
+
+    if (socket_io_instance->io_state != IO_STATE_OPENING)
+    {
+        if (on_io_open_complete != NULL)
+        {
+            on_io_open_complete(on_io_open_complete_context, result == 0 ? IO_OPEN_OK : IO_OPEN_ERROR);
+        }
+    }
+
+    return result;
+}
+
+int socketio_close(CONCRETE_IO_HANDLE socket_io, ON_IO_CLOSE_COMPLETE on_io_close_complete, void* callback_context)
+{
+    int result = 0;
+
+    if (socket_io == NULL)
+    {
+        result = MU_FAILURE;
+    }
+    else
+    {
+        SOCKET_IO_INSTANCE* socket_io_instance = (SOCKET_IO_INSTANCE*)socket_io;
+        if ((socket_io_instance->io_state != IO_STATE_CLOSED) && (socket_io_instance->io_state != IO_STATE_CLOSING))
+        {
+            // Only close if the socket isn't already in the closed or closing state
+            (void)shutdown(socket_io_instance->socket, SHUT_RDWR);
+            close(socket_io_instance->socket);
+            socket_io_instance->socket = INVALID_SOCKET;
+            socket_io_instance->io_state = IO_STATE_CLOSED;
+        }
+
+        if (on_io_close_complete != NULL)
+        {
+            on_io_close_complete(callback_context);
+        }
+
+        result = 0;
+    }
+
+    return result;
+}
+
+int socketio_send(CONCRETE_IO_HANDLE socket_io, const void* buffer, size_t size, ON_SEND_COMPLETE on_send_complete, void* callback_context)
+{
+    int result;
+
+    if ((socket_io == NULL) ||
+        (buffer == NULL) ||
+        (size == 0))
+    {
+        /* Invalid arguments */
+        LogError("Invalid argument: send given invalid parameter");
+        result = MU_FAILURE;
+    }
+    else
+    {
+        SOCKET_IO_INSTANCE* socket_io_instance = (SOCKET_IO_INSTANCE*)socket_io;
+        if (socket_io_instance->io_state != IO_STATE_OPEN)
+        {
+            LogError("Failure: socket state is not opened.");
+            result = MU_FAILURE;
+        }
+        else
+        {
+            LIST_ITEM_HANDLE first_pending_io = singlylinkedlist_get_head_item(socket_io_instance->pending_io_list);
+            if (first_pending_io != NULL)
+            {
+                if (add_pending_io(socket_io_instance, buffer, size, on_send_complete, callback_context) != 0)
+                {
+                    LogError("Failure: add_pending_io failed.");
+                    result = MU_FAILURE;
+                }
+                else
+                {
+                    result = 0;
+                }
+            }
+            else
+            {
+                signal(SIGPIPE, SIG_IGN);
+
+                ssize_t send_result = send(socket_io_instance->socket, buffer, size, 0);
+                if ((size_t)send_result != size)
+                {
+                    if (send_result == SOCKET_SEND_FAILURE && errno != EAGAIN)
+                    {
+                        LogError("Failure: sending socket failed. errno=%d (%s).", errno, strerror(errno));
+                        result = MU_FAILURE;
+                    }
+                    else
+                    {
+                        /*send says "come back later" with EAGAIN - likely the socket buffer cannot accept more data*/
+                        /* queue data */
+                        size_t bytes_sent = (send_result < 0 ? 0 : send_result);
+
+                        if (add_pending_io(socket_io_instance, buffer + bytes_sent, size - bytes_sent, on_send_complete, callback_context) != 0)
+                        {
+                            LogError("Failure: add_pending_io failed.");
+                            result = MU_FAILURE;
+                        }
+                        else
+                        {
+                            result = 0;
+                        }
+                    }
+                }
+                else
+                {
+                    if (on_send_complete != NULL)
+                    {
+                        on_send_complete(callback_context, IO_SEND_OK);
+                    }
+
+                    result = 0;
+                }
+            }
+        }
+    }
+
+    return result;
+}
+
+void socketio_dowork(CONCRETE_IO_HANDLE socket_io)
+{
+    if (socket_io != NULL)
+    {
+        SOCKET_IO_INSTANCE* socket_io_instance = (SOCKET_IO_INSTANCE*)socket_io;
+        signal(SIGPIPE, SIG_IGN);
+
+        if (socket_io_instance->io_state == IO_STATE_OPEN)
+        {
+            LIST_ITEM_HANDLE first_pending_io = singlylinkedlist_get_head_item(socket_io_instance->pending_io_list);
+            while (first_pending_io != NULL)
+            {
+                PENDING_SOCKET_IO* pending_socket_io = (PENDING_SOCKET_IO*)singlylinkedlist_item_get_value(first_pending_io);
+                if (pending_socket_io == NULL)
+                {
+                    indicate_error(socket_io_instance);
+                    LogError("Failure: retrieving socket from list");
+                    break;
+                }
+
+                ssize_t send_result = send(socket_io_instance->socket, pending_socket_io->bytes, pending_socket_io->size, 0);
+                if ((send_result < 0) || ((size_t)send_result != pending_socket_io->size))
+                {
+                    if (send_result == INVALID_SOCKET)
+                    {
+                        if (errno == EAGAIN) /*send says "come back later" with EAGAIN - likely the socket buffer cannot accept more data*/
+                        {
+                            /*do nothing until next dowork */
+                            break;
+                        }
+                        else
+                        {
+                            free(pending_socket_io->bytes);
+                            free(pending_socket_io);
+                            (void)singlylinkedlist_remove(socket_io_instance->pending_io_list, first_pending_io);
+
+                            LogError("Failure: sending Socket information. errno=%d (%s).", errno, strerror(errno));
+                            indicate_error(socket_io_instance);
+                        }
+                    }
+                    else
+                    {
+                        /* simply wait until next dowork */
+                        (void)memmove(pending_socket_io->bytes, pending_socket_io->bytes + send_result, pending_socket_io->size - send_result);
+                        pending_socket_io->size -= send_result;
+                        break;
+                    }
+                }
+                else
+                {
+                    if (pending_socket_io->on_send_complete != NULL)
+                    {
+                        pending_socket_io->on_send_complete(pending_socket_io->callback_context, IO_SEND_OK);
+                    }
+
+                    free(pending_socket_io->bytes);
+                    free(pending_socket_io);
+                    if (singlylinkedlist_remove(socket_io_instance->pending_io_list, first_pending_io) != 0)
+                    {
+                        indicate_error(socket_io_instance);
+                        LogError("Failure: unable to remove socket from list");
+                    }
+                }
+
+                first_pending_io = singlylinkedlist_get_head_item(socket_io_instance->pending_io_list);
+            }
+
+            if (socket_io_instance->io_state == IO_STATE_OPEN)
+            {
+                ssize_t received = 0;
+                do
+                {
+                    received = recv(socket_io_instance->socket, socket_io_instance->recv_bytes, RECEIVE_BYTES_VALUE, 0);
+                    if (received > 0)
+                    {
+                        if (socket_io_instance->on_bytes_received != NULL)
+                        {
+                            /* Explicitly ignoring here the result of the callback */
+                            (void)socket_io_instance->on_bytes_received(socket_io_instance->on_bytes_received_context, socket_io_instance->recv_bytes, received);
+                        }
+                    }
+                    else if (received == 0)
+                    {
+                        // Do not log error here due to this is probably the socket being closed on the other end
+                        indicate_error(socket_io_instance);
+                    }
+                    else if (received < 0 && errno != EAGAIN)
+                    {
+                        LogError("Socketio_Failure: Receiving data from endpoint: errno=%d.", errno);
+                        indicate_error(socket_io_instance);
+                    }
+
+                } while (received > 0 && socket_io_instance->io_state == IO_STATE_OPEN);
+            }
+        }
+        else
+        {
+            if (socket_io_instance->io_state == IO_STATE_OPENING)
+            {
+                if(lookup_address(socket_io_instance) != 0)
+                {
+                    LogError("Socketio_Failure: lookup address failed");
+                    indicate_error(socket_io_instance);
+                }
+                else
+                {
+                    if(socket_io_instance->io_state == IO_STATE_OPEN)
+                    {
+                        initiate_socket_connection(socket_io_instance);
+                    }
+                }
+
+            }
+        }
+    }
+}
+
+// Edison is missing this from netinet/tcp.h, but this code still works if we manually define it.
+#ifndef SOL_TCP
+#define SOL_TCP 6
+#endif
+
+#ifndef __APPLE__
+static void strtoup(char* str)
+{
+    if (str != NULL)
+    {
+        while (*str != '\0')
+        {
+            if (isalpha((int)*str) && islower((int)*str))
+            {
+                *str = (char)toupper((int)*str);
+            }
+            str++;
+        }
+    }
+}
+#endif // __APPLE__
+
+static int socketio_setaddresstype_option(SOCKET_IO_INSTANCE* socket_io_instance, const char* addressType)
+{
+    int result;
+
+    if (socket_io_instance->io_state != IO_STATE_CLOSED)
+    {
+        LogError("Socket's type can only be changed when in state 'IO_STATE_CLOSED'.  Current state=%d", socket_io_instance->io_state);
+        result = MU_FAILURE;
+    }
+    else if (strcmp(addressType, OPTION_ADDRESS_TYPE_DOMAIN_SOCKET) == 0)
+    {
+        socket_io_instance->address_type = ADDRESS_TYPE_DOMAIN_SOCKET;
+        result = 0;
+    }
+    else if (strcmp(addressType, OPTION_ADDRESS_TYPE_IP_SOCKET) == 0)
+    {
+        socket_io_instance->address_type = ADDRESS_TYPE_IP;
+        result = 0;
+    }
+    else
+    {
+        LogError("Address type %s is not supported", addressType);
+        result = MU_FAILURE;
+    }
+
+    return result;
+}
+
+int socketio_setoption(CONCRETE_IO_HANDLE socket_io, const char* optionName, const void* value)
+{
+    int result;
+
+    if (socket_io == NULL ||
+        optionName == NULL ||
+        value == NULL)
+    {
+        result = MU_FAILURE;
+    }
+    else
+    {
+        SOCKET_IO_INSTANCE* socket_io_instance = (SOCKET_IO_INSTANCE*)socket_io;
+
+        if (strcmp(optionName, "tcp_keepalive") == 0)
+        {
+            result = setsockopt(socket_io_instance->socket, SOL_SOCKET, SO_KEEPALIVE, value, sizeof(int));
+            if (result == -1) result = errno;
+        }
+        else if (strcmp(optionName, "tcp_keepalive_time") == 0)
+        {
+#ifdef __APPLE__
+            result = setsockopt(socket_io_instance->socket, IPPROTO_TCP, TCP_KEEPALIVE, value, sizeof(int));
+#else
+            result = setsockopt(socket_io_instance->socket, SOL_TCP, TCP_KEEPIDLE, value, sizeof(int));
+#endif
+            if (result == -1) result = errno;
+        }
+        else if (strcmp(optionName, "tcp_keepalive_interval") == 0)
+        {
+            result = setsockopt(socket_io_instance->socket, SOL_TCP, TCP_KEEPINTVL, value, sizeof(int));
+            if (result == -1) result = errno;
+        }
+        else if (strcmp(optionName, OPTION_NET_INT_MAC_ADDRESS) == 0)
+        {
+#ifdef __APPLE__
+            LogError("option not supported.");
+            result = MU_FAILURE;
+#else
+            if (strlen(value) == 0)
+            {
+                LogError("option value must be a valid mac address");
+                result = MU_FAILURE;
+            }
+            else if ((socket_io_instance->target_mac_address = (char*)malloc(sizeof(char) * (strlen(value) + 1))) == NULL)
+            {
+                LogError("failed setting net_interface_mac_address option (malloc failed)");
+                result = MU_FAILURE;
+            }
+            else if (strcpy(socket_io_instance->target_mac_address, value) == NULL)
+            {
+                LogError("failed setting net_interface_mac_address option (strcpy failed)");
+                free(socket_io_instance->target_mac_address);
+                socket_io_instance->target_mac_address = NULL;
+                result = MU_FAILURE;
+            }
+            else
+            {
+                strtoup(socket_io_instance->target_mac_address);
+                result = 0;
+            }
+#endif
+        }
+        else if (strcmp(optionName, OPTION_ADDRESS_TYPE) == 0)
+        {
+            result = socketio_setaddresstype_option(socket_io_instance, (const char*)value);
+        }
+        else
+        {
+            result = MU_FAILURE;
+        }
+    }
+
+    return result;
+}
+
+const IO_INTERFACE_DESCRIPTION* socketio_get_interface_description(void)
+{
+    return &socket_io_interface_description;
+}
+
Index: azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/adapters/threadapi_toppers.c
===================================================================
--- azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/adapters/threadapi_toppers.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/adapters/threadapi_toppers.c	(revision 457)
@@ -0,0 +1,189 @@
+/*
+ *  TOPPERS PROJECT Home Network Working Group Software
+ * 
+ *  Copyright (C) 2019 Cores Co., Ltd. Japan
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+#include <stdint.h>
+#include <stdlib.h>
+#include <kernel.h>
+#include <t_stdlib.h>
+#include "azure_c_shared_utility/threadapi.h"
+#include "azure_c_shared_utility/xlogging.h"
+
+MU_DEFINE_ENUM_STRINGS(THREADAPI_RESULT, THREADAPI_RESULT_VALUES);
+
+#ifdef TOPPERS_SUPPORT_DYNAMIC_CRE
+#define MAX_THREADS 4
+#define TASK_PRIORITY ((TMAX_TPRI + TMIN_TPRI) / 2)
+
+typedef struct _thread
+{
+	ID tskid;
+	int result;
+} toppersThread;
+static toppersThread threads[MAX_THREADS] = { 0 };
+#endif
+
+THREADAPI_RESULT ThreadAPI_Create(THREAD_HANDLE* threadHandle, THREAD_START_FUNC func, void* arg)
+{
+#ifndef TOPPERS_SUPPORT_DYNAMIC_CRE
+	LogError("TOPPERS/ASP does not support multi-thread function.");
+	return THREADAPI_ERROR;
+#else
+	THREADAPI_RESULT result;
+	if ((threadHandle == NULL) ||
+		(func == NULL))
+	{
+		result = THREADAPI_INVALID_ARG;
+		LogError("(result = %s)", MU_ENUM_TO_STRING(THREADAPI_RESULT, result));
+	}
+	else {
+		ER_ID ret;
+		T_CTSK ctsk;
+		toppersThread *thread = NULL;
+
+		for (int i = 0; i < MAX_THREADS; i++) {
+			if (threads[i].tskid == 0) {
+				thread = &threads[i];
+				break;
+			}
+		}
+
+		memset(&ctsk, 0, sizeof(ctsk));
+
+		ctsk.exinf = (intptr_t)arg;
+		ctsk.task = (TASK)func;
+		ctsk.itskpri = TASK_PRIORITY;
+
+		ret = acre_tsk(&ctsk);
+		if (ret > 0) {
+			if (thread == NULL) {
+				for (int i = 0; i < MAX_THREADS; i++) {
+					if (threads[i].tskid == ret) {
+						thread = &threads[i];
+						break;
+					}
+				}
+			}
+			if (thread != NULL) {
+				thread->result = 0;
+			}
+			if (act_tsk(ret) == E_OK) {
+				*threadHandle = (THREAD_HANDLE)(ret);
+				result = THREADAPI_OK;
+			}
+			else {
+				del_tsk(ret);
+				result = THREADAPI_ERROR;
+				LogError("(result = %s)", MU_ENUM_TO_STRING(THREADAPI_RESULT, result));
+			}
+		}
+		else {
+			result = THREADAPI_NO_MEMORY;
+			LogError("(result = %s)", MU_ENUM_TO_STRING(THREADAPI_RESULT, result));
+		}
+	}
+
+	return result;
+#endif
+}
+
+THREADAPI_RESULT ThreadAPI_Join(THREAD_HANDLE threadHandle, int *res)
+{
+#ifndef TOPPERS_SUPPORT_DYNAMIC_CRE
+	LogError("TOPPERS/ASP does not support multi-thread function.");
+	return THREADAPI_ERROR;
+#else
+	ID tskid = (ID)threadHandle;
+	T_RTSK rtsk;
+	toppersThread *thread = NULL;
+	ER ret;
+
+	for (;;) {
+		ret = ref_tsk(tskid, &rtsk);
+		if ((ret != E_OK) || (rtsk.tskstat == TTS_DMT))
+			break;
+
+		dly_tsk(10);
+	}
+
+	for (int i = 0; i < MAX_THREADS; i++) {
+		if (threads[i].tskid == ret) {
+			thread = &threads[i];
+			break;
+		}
+	}
+
+	if (thread != NULL) {
+		*res = thread->result;
+	}
+
+	return THREADAPI_OK;
+#endif
+}
+
+void ThreadAPI_Exit(int res)
+{
+	ER ret;
+#ifdef TOPPERS_SUPPORT_DYNAMIC_CRE
+	ID tskid;
+
+	ret = get_tid(&tskid);
+	if (ret != E_OK) {
+		LogError("get_tid error. %s", itron_strerror(ret));
+		return;
+	}
+
+	for (int i = 0; i < MAX_THREADS; i++) {
+		if (threads[i].tskid == tskid) {
+			threads[i].result = res;
+			break;
+		}
+	}
+#endif
+	ret = ext_tsk();
+	if (ret != E_OK) {
+		LogError("ext_tsk error. %s", itron_strerror(ret));
+	}
+}
+
+void ThreadAPI_Sleep(unsigned int milliseconds)
+{
+	ER ret;
+
+	ret = dly_tsk((RELTIM)milliseconds);
+	if (ret != E_OK) {
+		LogError("dly_tsk error. %s", itron_strerror(ret));
+	}
+}
Index: azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/adapters/tickcounter_toppers.c
===================================================================
--- azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/adapters/tickcounter_toppers.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/adapters/tickcounter_toppers.c	(revision 457)
@@ -0,0 +1,105 @@
+/*
+ *  TOPPERS PROJECT Home Network Working Group Software
+ * 
+ *  Copyright (C) 2019 Cores Co., Ltd. Japan
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+#include <stdint.h>
+#include <stdlib.h>
+#include <kernel.h>
+#include <sil.h>
+#include "azure_c_shared_utility/tickcounter.h"
+#include "azure_c_shared_utility/optimize_size.h"
+#include "azure_c_shared_utility/xlogging.h"
+
+typedef struct tick_counter_instance_tag
+{
+	SYSTIM last_clock_value;
+	tickcounter_ms_t current_ms;
+} TICK_COUNTER_INSTANCE_TAG;
+
+TICK_COUNTER_HANDLE tickcounter_create(void)
+{
+	ER ret;
+	SYSTIM now;
+	TICK_COUNTER_INSTANCE_TAG* result;
+
+	result = (TICK_COUNTER_INSTANCE_TAG *)malloc(sizeof(TICK_COUNTER_INSTANCE_TAG));
+
+	if (get_tim(&now) != E_OK) {
+		LogError("tickcounter failed: time return INVALID_TIME.");
+		free(result);
+		result = NULL;
+	}
+	else {
+		result->last_clock_value = now;
+		result->current_ms = 0;
+	}
+
+	return (TICK_COUNTER_HANDLE)result;
+}
+
+void tickcounter_destroy(TICK_COUNTER_HANDLE tick_counter)
+{
+	if (tick_counter != NULL)
+	{
+		free((TICK_COUNTER_INSTANCE_TAG *)tick_counter);
+	}
+}
+
+int tickcounter_get_current_ms(TICK_COUNTER_HANDLE tick_counter, tickcounter_ms_t * current_ms)
+{
+	ER ret;
+	SYSTIM now;
+	int result;
+
+	if (tick_counter == NULL || current_ms == NULL)
+	{
+		result = MU_FAILURE;
+	}
+	else
+	{
+		if (get_tim(&now) != E_OK) {
+			result = MU_FAILURE;
+		}
+		else {
+			TICK_COUNTER_INSTANCE_TAG* tick_counter_instance = (TICK_COUNTER_INSTANCE_TAG*)tick_counter;
+			tick_counter_instance->current_ms += (now - tick_counter_instance->last_clock_value);
+			tick_counter_instance->last_clock_value = now;
+			*current_ms = tick_counter_instance->current_ms;
+			result = 0;
+		}
+	}
+
+	return result;
+}
Index: azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/adapters/tlsio_esp_at.c
===================================================================
--- azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/adapters/tlsio_esp_at.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/adapters/tlsio_esp_at.c	(revision 457)
@@ -0,0 +1,497 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+#include <stdlib.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <string.h>
+#include "azure_c_shared_utility/tlsio.h"
+#include "azure_c_shared_utility/tlsio_esp_at.h"
+#include "azure_c_shared_utility/singlylinkedlist.h"
+#include "azure_c_shared_utility/esp_at_socket.h"
+#include "azure_c_shared_utility/optimize_size.h"
+#include "azure_c_shared_utility/xlogging.h"
+
+#define ESP_AT_XIO_RECEIVE_BUFFER_SIZE    128
+
+typedef enum IO_STATE_TAG
+{
+    IO_STATE_CLOSED,
+    IO_STATE_OPENING,
+    IO_STATE_OPEN,
+    IO_STATE_CLOSING,
+    IO_STATE_ERROR
+} IO_STATE;
+
+typedef struct PENDING_TLS_IO_TAG
+{
+    unsigned char* bytes;
+    size_t size;
+    ON_SEND_COMPLETE on_send_complete;
+    void* callback_context;
+    SINGLYLINKEDLIST_HANDLE pending_io_list;
+} PENDING_TLS_IO;
+
+typedef struct TLS_IO_INSTANCE_TAG
+{
+    ESP_AT_SOCKET_HANDLE tcp_socket_connection;
+    ON_BYTES_RECEIVED on_bytes_received;
+    ON_IO_ERROR on_io_error;
+    void* on_bytes_received_context;
+    void* on_io_error_context;
+    char* hostname;
+    int port;
+    IO_STATE io_state;
+    SINGLYLINKEDLIST_HANDLE pending_io_list;
+} TLS_IO_INSTANCE;
+
+/*this function will clone an option given by name and value*/
+static void* tlsio_esp_at_CloneOption(const char* name, const void* value)
+{
+    (void)name;
+    (void)value;
+    return NULL;
+}
+
+/*this function destroys an option previously created*/
+static void tlsio_esp_at_DestroyOption(const char* name, const void* value)
+{
+    (void)name;
+    (void)value;
+}
+
+static OPTIONHANDLER_HANDLE tlsio_esp_at_retrieveoptions(CONCRETE_IO_HANDLE tlsio_esp_at)
+{
+    OPTIONHANDLER_HANDLE result;
+    (void)tlsio_esp_at;
+    result = OptionHandler_Create(tlsio_esp_at_CloneOption, tlsio_esp_at_DestroyOption, tlsio_esp_at_setoption);
+    if (result == NULL)
+    {
+        /*return as is*/
+    }
+    else
+    {
+        /*insert here work to add the options to "result" handle*/
+    }
+    return result;
+}
+
+static const IO_INTERFACE_DESCRIPTION tlsio_esp_at_interface_description =
+{
+    tlsio_esp_at_retrieveoptions,
+    tlsio_esp_at_create,
+    tlsio_esp_at_destroy,
+    tlsio_esp_at_open,
+    tlsio_esp_at_close,
+    tlsio_esp_at_send,
+    tlsio_esp_at_dowork,
+    tlsio_esp_at_setoption
+};
+
+static void indicate_error(TLS_IO_INSTANCE* tlsio_esp_at_instance)
+{
+    if ((tlsio_esp_at_instance->io_state == IO_STATE_CLOSED)
+        || (tlsio_esp_at_instance->io_state == IO_STATE_ERROR))
+    {
+        return;
+    }
+    tlsio_esp_at_instance->io_state = IO_STATE_ERROR;
+    if (tlsio_esp_at_instance->on_io_error != NULL)
+    {
+        tlsio_esp_at_instance->on_io_error(tlsio_esp_at_instance->on_io_error_context);
+    }
+}
+
+static int add_pending_io(TLS_IO_INSTANCE* tlsio_esp_at_instance, const unsigned char* buffer, size_t size, ON_SEND_COMPLETE on_send_complete, void* callback_context)
+{
+    int result;
+    PENDING_TLS_IO* pending_tlsio_esp_at = (PENDING_TLS_IO*)malloc(sizeof(PENDING_TLS_IO));
+    if (pending_tlsio_esp_at == NULL)
+    {
+        LogError("Allocation Failure: Unable to allocate pending list.");
+        result = MU_FAILURE;
+    }
+    else
+    {
+        pending_tlsio_esp_at->bytes = (unsigned char*)malloc(size);
+        if (pending_tlsio_esp_at->bytes == NULL)
+        {
+            LogError("Allocation Failure: Unable to allocate pending list.");
+            free(pending_tlsio_esp_at);
+            result = MU_FAILURE;
+        }
+        else
+        {
+            pending_tlsio_esp_at->size = size;
+            pending_tlsio_esp_at->on_send_complete = on_send_complete;
+            pending_tlsio_esp_at->callback_context = callback_context;
+            pending_tlsio_esp_at->pending_io_list = tlsio_esp_at_instance->pending_io_list;
+            (void)memcpy(pending_tlsio_esp_at->bytes, buffer, size);
+            if (singlylinkedlist_add(tlsio_esp_at_instance->pending_io_list, pending_tlsio_esp_at) == NULL)
+            {
+                LogError("Failure: Unable to add socket to pending list.");
+                free(pending_tlsio_esp_at->bytes);
+                free(pending_tlsio_esp_at);
+                result = MU_FAILURE;
+            }
+            else
+            {
+                result = 0;
+            }
+        }
+    }
+
+    return result;
+}
+
+#define NSAPI_ERROR_WOULD_BLOCK   -3001
+
+static int retrieve_data(TLS_IO_INSTANCE* tlsio_esp_at_instance)
+{
+    int received = 1;
+    int total_received = 0;
+
+    unsigned char* recv_bytes = malloc(ESP_AT_XIO_RECEIVE_BUFFER_SIZE);
+    if (recv_bytes == NULL)
+    {
+        LogError("Socketio_Failure: NULL allocating input buffer.");
+        indicate_error(tlsio_esp_at_instance);
+        return -1;
+    }
+    
+    while (received > 0)
+    {
+        received = esp_at_socket_receive(tlsio_esp_at_instance->tcp_socket_connection, (char*)recv_bytes, ESP_AT_XIO_RECEIVE_BUFFER_SIZE);
+        if (received > 0)
+        {
+            total_received += received;
+            if (tlsio_esp_at_instance->on_bytes_received != NULL)
+            {
+                /* explictly ignoring here the result of the callback */
+                tlsio_esp_at_instance->on_bytes_received(tlsio_esp_at_instance->on_bytes_received_context, recv_bytes, received);
+            }
+        }
+        else if (received < 0)
+        {
+            if(received != NSAPI_ERROR_WOULD_BLOCK)     // NSAPI_ERROR_WOULD_BLOCK is not a real error but pending.
+            {
+                indicate_error(tlsio_esp_at_instance);
+                LogError("Socketio_Failure: underlying IO error %d.", received);
+                free(recv_bytes);
+                return -1;
+            }
+        }
+    }
+    free(recv_bytes);
+    
+    return total_received;
+}
+
+static int send_queued_data(TLS_IO_INSTANCE* tlsio_esp_at_instance)
+{
+    int errors = 0;
+    int sent = 0;
+    
+    LIST_ITEM_HANDLE first_pending_io = singlylinkedlist_get_head_item(tlsio_esp_at_instance->pending_io_list);
+    while (first_pending_io != NULL)
+    {
+        PENDING_TLS_IO* pending_tlsio_esp_at = (PENDING_TLS_IO*)singlylinkedlist_item_get_value(first_pending_io);
+        if (pending_tlsio_esp_at == NULL)
+        {
+            indicate_error(tlsio_esp_at_instance);
+            return -1;
+        }
+
+        int send_result = esp_at_socket_send(tlsio_esp_at_instance->tcp_socket_connection, (const char*)pending_tlsio_esp_at->bytes, pending_tlsio_esp_at->size);
+        if (send_result != (int)pending_tlsio_esp_at->size)
+        {
+            if (send_result == 0)
+            {
+                // The underlying network layer may encounter hardware / environment issues, 
+                // but the driver doesn't handle it properly. So here the send API always return 0, 
+                // this causes the program running into dead loop if not check it here.
+                if (errors++ >= 10)
+                {
+                    // Treat it as a network error after try 10 times.
+                    LogError("Socketio_Failure: encountered unknow connection issue, the connection will be restarted.");
+                    indicate_error(tlsio_esp_at_instance);
+                    return -1;
+                }
+                ThreadAPI_Sleep(10);
+            }
+            else if (send_result < 0)
+            {
+                indicate_error(tlsio_esp_at_instance);
+                return -1;
+            }
+            else
+            {
+                /* send something, wait for the rest */
+                memmove(pending_tlsio_esp_at->bytes, pending_tlsio_esp_at->bytes + send_result, pending_tlsio_esp_at->size - send_result);
+                sent += send_result;
+            }
+        }
+        else
+        {
+            sent += send_result;
+            if (pending_tlsio_esp_at->on_send_complete != NULL)
+            {
+                pending_tlsio_esp_at->on_send_complete(pending_tlsio_esp_at->callback_context, IO_SEND_OK);
+            }
+
+            free(pending_tlsio_esp_at->bytes);
+            free(pending_tlsio_esp_at);
+            if (singlylinkedlist_remove(tlsio_esp_at_instance->pending_io_list, first_pending_io) != 0)
+            {
+                indicate_error(tlsio_esp_at_instance);
+                return -1;
+            }
+            errors = 0;
+        }
+
+        first_pending_io = singlylinkedlist_get_head_item(tlsio_esp_at_instance->pending_io_list);
+    }
+
+    return sent;
+}
+
+static void close_tcp_connection(TLS_IO_INSTANCE* tlsio_esp_at_instance)
+{
+    if (tlsio_esp_at_instance->io_state != IO_STATE_CLOSED)
+    {
+        if (tlsio_esp_at_instance->tcp_socket_connection != NULL)
+        {
+            esp_at_socket_close(tlsio_esp_at_instance->tcp_socket_connection);
+            esp_at_socket_destroy(tlsio_esp_at_instance->tcp_socket_connection);
+            tlsio_esp_at_instance->tcp_socket_connection = NULL;
+        }
+        tlsio_esp_at_instance->io_state = IO_STATE_CLOSED;
+    }
+}
+
+CONCRETE_IO_HANDLE tlsio_esp_at_create(void* io_create_parameters)
+{
+    TLSIO_CONFIG* tlsio_esp_at_config = io_create_parameters;
+    TLS_IO_INSTANCE* result;
+
+    if (tlsio_esp_at_config == NULL)
+    {
+        result = NULL;
+    }
+    else
+    {    
+        result = (TLS_IO_INSTANCE*)malloc(sizeof(TLS_IO_INSTANCE));
+        if (result == NULL) {
+            LogError("Socketio_Failure: NULL allocating socket io instance.");
+        }
+        else
+        {
+            result->pending_io_list = singlylinkedlist_create();
+            if (result->pending_io_list == NULL)
+            {
+                free(result);
+                result = NULL;
+            }
+            else
+            {
+                result->hostname = strdup(tlsio_esp_at_config->hostname);
+                if (result->hostname == NULL)
+                {
+                    singlylinkedlist_destroy(result->pending_io_list);
+                    free(result);
+                    result = NULL;
+                }
+                else
+                {
+                    result->port = tlsio_esp_at_config->port;
+                    result->on_bytes_received = NULL;
+                    result->on_io_error = NULL;
+                    result->on_bytes_received_context = NULL;
+                    result->on_io_error_context = NULL;
+                    result->io_state = IO_STATE_CLOSED;
+                    result->tcp_socket_connection = NULL;
+                }
+            }
+        }
+    }
+
+    return result;
+}
+
+void tlsio_esp_at_destroy(CONCRETE_IO_HANDLE tlsio_esp_at)
+{
+    if (tlsio_esp_at != NULL)
+    {
+        TLS_IO_INSTANCE* tlsio_esp_at_instance = (TLS_IO_INSTANCE*)tlsio_esp_at;
+
+        // Close the tcp connection
+        close_tcp_connection(tlsio_esp_at_instance);
+    
+        // Clear all pending IOs
+        LIST_ITEM_HANDLE first_pending_io = singlylinkedlist_get_head_item(tlsio_esp_at_instance->pending_io_list);
+        while (first_pending_io != NULL)
+        {
+            PENDING_TLS_IO* pending_tlsio_esp_at = (PENDING_TLS_IO*)singlylinkedlist_item_get_value(first_pending_io);
+            if (pending_tlsio_esp_at != NULL)
+            {
+                free(pending_tlsio_esp_at->bytes);
+                free(pending_tlsio_esp_at);
+            }
+
+            (void)singlylinkedlist_remove(tlsio_esp_at_instance->pending_io_list, first_pending_io);
+            first_pending_io = singlylinkedlist_get_head_item(tlsio_esp_at_instance->pending_io_list);
+        }
+        singlylinkedlist_destroy(tlsio_esp_at_instance->pending_io_list);
+    
+        if(tlsio_esp_at_instance->hostname != NULL)
+        {
+            free(tlsio_esp_at_instance->hostname);
+            tlsio_esp_at_instance->hostname = NULL;
+        }
+        free(tlsio_esp_at);
+    }
+}
+
+int tlsio_esp_at_open(CONCRETE_IO_HANDLE tlsio_esp_at, ON_IO_OPEN_COMPLETE on_io_open_complete, void* on_io_open_complete_context, ON_BYTES_RECEIVED on_bytes_received, void* on_bytes_received_context, ON_IO_ERROR on_io_error, void* on_io_error_context)
+{
+    int result;
+    TLS_IO_INSTANCE* tlsio_esp_at_instance = (TLS_IO_INSTANCE*)tlsio_esp_at;
+    
+
+    if (tlsio_esp_at_instance == NULL ||
+        tlsio_esp_at_instance->io_state != IO_STATE_CLOSED)
+    {
+        result = MU_FAILURE;
+    }
+    else
+    {
+        tlsio_esp_at_instance->tcp_socket_connection = esp_at_socket_create(true);
+        if (tlsio_esp_at_instance->tcp_socket_connection == NULL)
+        {
+            result = MU_FAILURE;
+        }
+        else
+        {
+            if (esp_at_socket_connect(tlsio_esp_at_instance->tcp_socket_connection, tlsio_esp_at_instance->hostname, tlsio_esp_at_instance->port) != 0)
+            {
+                esp_at_socket_destroy(tlsio_esp_at_instance->tcp_socket_connection);
+                tlsio_esp_at_instance->tcp_socket_connection = NULL;
+                result = MU_FAILURE;
+            }
+            else
+            {
+                esp_at_socket_set_blocking(tlsio_esp_at_instance->tcp_socket_connection, false, 0);
+
+                tlsio_esp_at_instance->on_bytes_received = on_bytes_received;
+                tlsio_esp_at_instance->on_bytes_received_context = on_bytes_received_context;
+
+                tlsio_esp_at_instance->on_io_error = on_io_error;
+                tlsio_esp_at_instance->on_io_error_context = on_io_error_context;
+
+                tlsio_esp_at_instance->io_state = IO_STATE_OPEN;
+
+                result = 0;
+            }
+        }
+    }
+    
+    if (on_io_open_complete != NULL)
+    {
+        on_io_open_complete(on_io_open_complete_context, result == 0 ? IO_OPEN_OK : IO_OPEN_ERROR);
+    }
+
+    return result;
+}
+
+int tlsio_esp_at_close(CONCRETE_IO_HANDLE tlsio_esp_at, ON_IO_CLOSE_COMPLETE on_io_close_complete, void* callback_context)
+{
+    int result = 0;
+
+    if (tlsio_esp_at == NULL)
+    {
+        result = MU_FAILURE;
+    }
+    else
+    {
+        TLS_IO_INSTANCE* tlsio_esp_at_instance = (TLS_IO_INSTANCE*)tlsio_esp_at;
+        if (tlsio_esp_at_instance->io_state == IO_STATE_CLOSED || 
+            tlsio_esp_at_instance->io_state == IO_STATE_ERROR)
+        {
+            result = MU_FAILURE;
+        }
+        else
+        {
+            close_tcp_connection(tlsio_esp_at_instance);
+            if (on_io_close_complete != NULL)
+            {
+                on_io_close_complete(callback_context);
+            }
+            result = 0;
+        }
+    }
+    
+    return result;
+}
+
+int tlsio_esp_at_send(CONCRETE_IO_HANDLE tlsio_esp_at, const void* buffer, size_t size, ON_SEND_COMPLETE on_send_complete, void* callback_context)
+{
+    int result;
+
+    if ((tlsio_esp_at == NULL) ||
+        (buffer == NULL) ||
+        (size == 0))
+    {
+        /* Invalid arguments */
+        result = MU_FAILURE;
+    }
+    else
+    {
+        result = 0;
+
+        TLS_IO_INSTANCE* tlsio_esp_at_instance = (TLS_IO_INSTANCE*)tlsio_esp_at;
+        if (tlsio_esp_at_instance->io_state != IO_STATE_OPEN)
+        {
+            result = MU_FAILURE;
+        }
+        else
+        {
+            // Queue the data, and the tlsio_esp_at_dowork sends the package later
+            if (add_pending_io(tlsio_esp_at_instance, buffer, size, on_send_complete, callback_context) != 0)
+            {
+                result = MU_FAILURE;
+            }
+        }
+    }
+
+    return result;
+}
+
+void tlsio_esp_at_dowork(CONCRETE_IO_HANDLE tlsio_esp_at)
+{
+    if (tlsio_esp_at != NULL)
+    {
+        TLS_IO_INSTANCE* tlsio_esp_at_instance = (TLS_IO_INSTANCE*)tlsio_esp_at;
+        if (tlsio_esp_at_instance->io_state == IO_STATE_OPEN)
+        {
+            // Retrieve all data from IoT Hub
+            if (retrieve_data(tlsio_esp_at_instance) < 0)
+            {
+                return;
+            }
+        
+            // Send all packages in the queue
+            send_queued_data(tlsio_esp_at_instance);
+        }
+    }
+}
+
+int tlsio_esp_at_setoption(CONCRETE_IO_HANDLE tlsio_esp_at, const char* optionName, const void* value)
+{
+    /* Not implementing any options, do nothing */
+    return OPTIONHANDLER_OK;
+}
+
+const IO_INTERFACE_DESCRIPTION* tlsio_esp_at_get_interface_description(void)
+{
+    return &tlsio_esp_at_interface_description;
+}
Index: azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/adapters/tlsio_wolfssl.c
===================================================================
--- azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/adapters/tlsio_wolfssl.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/adapters/tlsio_wolfssl.c	(revision 457)
@@ -0,0 +1,985 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+#include <stdlib.h>
+#define WOLFSSL_OPTIONS_IGNORE_SYS
+#include "wolfssl/options.h"
+#include "wolfssl/ssl.h"
+#include "wolfssl/error-ssl.h"
+#include "wolfssl/wolfcrypt/types.h"
+#include <stdio.h>
+#include <stdbool.h>
+#include <string.h>
+#include "azure_c_shared_utility/gballoc.h"
+#include "azure_c_shared_utility/tlsio.h"
+#include "azure_c_shared_utility/tlsio_wolfssl.h"
+#include "azure_c_shared_utility/socketio.h"
+#include "azure_c_shared_utility/crt_abstractions.h"
+#include "azure_c_shared_utility/optimize_size.h"
+#include "azure_c_shared_utility/xlogging.h"
+#include "azure_c_shared_utility/shared_util_options.h"
+#include "azure_c_shared_utility/threadapi.h"
+
+typedef enum TLSIO_STATE_ENUM_TAG
+{
+    TLSIO_STATE_NOT_OPEN,
+    TLSIO_STATE_OPENING_UNDERLYING_IO,
+    TLSIO_STATE_IN_HANDSHAKE,
+    TLSIO_STATE_OPEN,
+    TLSIO_STATE_CLOSING,
+    TLSIO_STATE_ERROR
+} TLSIO_STATE_ENUM;
+
+typedef struct TLS_IO_INSTANCE_TAG
+{
+    XIO_HANDLE socket_io;
+    ON_BYTES_RECEIVED on_bytes_received;
+    ON_IO_OPEN_COMPLETE on_io_open_complete;
+    ON_IO_CLOSE_COMPLETE on_io_close_complete;
+    ON_IO_ERROR on_io_error;
+    void* on_bytes_received_context;
+    void* on_io_open_complete_context;
+    void* on_io_close_complete_context;
+    void* on_io_error_context;
+    WOLFSSL* ssl;
+    WOLFSSL_CTX* ssl_context;
+    TLSIO_STATE_ENUM tlsio_state;
+    unsigned char* socket_io_read_bytes;
+    size_t socket_io_read_byte_count;
+    ON_SEND_COMPLETE on_send_complete;
+    void* on_send_complete_callback_context;
+    char* certificate;
+    char* x509certificate;
+    char* x509privatekey;
+    int wolfssl_device_id;
+    size_t socket_reads;
+} TLS_IO_INSTANCE;
+
+STATIC_VAR_UNUSED const char* const OPTION_WOLFSSL_SET_DEVICE_ID = "SetDeviceId";
+static const size_t SOCKET_READ_LIMIT = 10000; // 10,000 ms ?
+
+/*this function will clone an option given by name and value*/
+static void* tlsio_wolfssl_CloneOption(const char* name, const void* value)
+{
+    void* result;
+    if ((name == NULL) || (value == NULL))
+    {
+        LogError("invalid parameter detected: const char* name=%p, const void* value=%p", name, value);
+        result = NULL;
+    }
+    else
+    {
+        if (strcmp(name, OPTION_TRUSTED_CERT) == 0)
+        {
+            if (mallocAndStrcpy_s((char**)&result, value) != 0)
+            {
+                LogError("unable to mallocAndStrcpy_s TrustedCerts value");
+                result = NULL;
+            }
+            else
+            {
+                /*return as is*/
+            }
+        }
+        else if (strcmp(name, SU_OPTION_X509_CERT) == 0)
+        {
+            if (mallocAndStrcpy_s((char**)&result, value) != 0)
+            {
+                LogError("unable to mallocAndStrcpy_s x509certificate value");
+                result = NULL;
+            }
+            else
+            {
+                /*return as is*/
+            }
+        }
+        else if (strcmp(name, SU_OPTION_X509_PRIVATE_KEY) == 0)
+        {
+            if (mallocAndStrcpy_s((char**)&result, value) != 0)
+            {
+                LogError("unable to mallocAndStrcpy_s x509privatekey value");
+                result = NULL;
+            }
+            else
+            {
+                /*return as is*/
+            }
+        }
+        else
+        {
+            LogError("not handled option : %s", name);
+            result = NULL;
+        }
+    }
+    return result;
+}
+
+/*this function destroys an option previously created*/
+static void tlsio_wolfssl_DestroyOption(const char* name, const void* value)
+{
+    /*since all options for this layer are actually string copies., disposing of one is just calling free*/
+    if ((name == NULL) || (value == NULL))
+    {
+        LogError("invalid parameter detected: const char* name=%p, const void* value=%p", name, value);
+    }
+    else
+    {
+        if ((strcmp(name, OPTION_TRUSTED_CERT) == 0) ||
+            (strcmp(name, SU_OPTION_X509_CERT) == 0) ||
+            (strcmp(name, SU_OPTION_X509_PRIVATE_KEY) == 0))
+        {
+            free((void*)value);
+        }
+        else
+        {
+            LogError("not handled option : %s", name);
+        }
+    }
+}
+
+static OPTIONHANDLER_HANDLE tlsio_wolfssl_retrieveoptions(CONCRETE_IO_HANDLE tls_io)
+{
+    OPTIONHANDLER_HANDLE result;
+    if (tls_io == NULL)
+    {
+        LogError("NULL tls_io parameter");
+        result = NULL;
+    }
+    else
+    {
+        result = OptionHandler_Create(tlsio_wolfssl_CloneOption, tlsio_wolfssl_DestroyOption, tlsio_wolfssl_setoption);
+        if (result == NULL)
+        {
+            LogError("unable to OptionHandler_Create");
+            /*return as is*/
+        }
+        else
+        {
+            /*this layer cares about the certificates and the x509 credentials*/
+            TLS_IO_INSTANCE* tls_io_instance = (TLS_IO_INSTANCE*)tls_io;
+            if (
+                (tls_io_instance->x509certificate != NULL) &&
+                (OptionHandler_AddOption(result, SU_OPTION_X509_CERT, tls_io_instance->x509certificate) != OPTIONHANDLER_OK)
+                )
+            {
+                LogError("unable to save x509certificate option");
+                OptionHandler_Destroy(result);
+                result = NULL;
+            }
+            else if (
+                (tls_io_instance->x509privatekey != NULL) &&
+                (OptionHandler_AddOption(result, SU_OPTION_X509_PRIVATE_KEY, tls_io_instance->x509privatekey) != OPTIONHANDLER_OK)
+                )
+            {
+                LogError("unable to save x509privatekey option");
+                OptionHandler_Destroy(result);
+                result = NULL;
+            }
+            else if (
+                (tls_io_instance->certificate != NULL) &&
+                (OptionHandler_AddOption(result, OPTION_TRUSTED_CERT, tls_io_instance->certificate) != OPTIONHANDLER_OK)
+                )
+            {
+                LogError("unable to save TrustedCerts option");
+                OptionHandler_Destroy(result);
+                result = NULL;
+            }
+            else
+            {
+                /*all is fine, all interesting options have been saved*/
+                /*return as is*/
+            }
+        }
+    }
+
+    return result;
+}
+
+static const IO_INTERFACE_DESCRIPTION tlsio_wolfssl_interface_description =
+{
+    tlsio_wolfssl_retrieveoptions,
+    tlsio_wolfssl_create,
+    tlsio_wolfssl_destroy,
+    tlsio_wolfssl_open,
+    tlsio_wolfssl_close,
+    tlsio_wolfssl_send,
+    tlsio_wolfssl_dowork,
+    tlsio_wolfssl_setoption
+};
+
+static void indicate_error(TLS_IO_INSTANCE* tls_io_instance)
+{
+    if (tls_io_instance->on_io_error != NULL)
+    {
+        tls_io_instance->on_io_error(tls_io_instance->on_io_error_context);
+    }
+}
+
+static void indicate_open_complete(TLS_IO_INSTANCE* tls_io_instance, IO_OPEN_RESULT open_result)
+{
+    if (tls_io_instance->on_io_open_complete != NULL)
+    {
+        tls_io_instance->on_io_open_complete(tls_io_instance->on_io_open_complete_context, open_result);
+    }
+}
+
+static int decode_ssl_received_bytes(TLS_IO_INSTANCE* tls_io_instance)
+{
+    int result = 0;
+    unsigned char buffer[64];
+
+    int rcv_bytes = 0;
+    do
+    {
+        rcv_bytes = wolfSSL_read(tls_io_instance->ssl, buffer, sizeof(buffer));
+        if (rcv_bytes > 0)
+        {
+            if (tls_io_instance->on_bytes_received != NULL)
+            {
+                tls_io_instance->on_bytes_received(tls_io_instance->on_bytes_received_context, buffer, rcv_bytes);
+            }
+        }
+    } while (rcv_bytes > 0);
+    return result;
+}
+
+static void on_underlying_io_open_complete(void* context, IO_OPEN_RESULT open_result)
+{
+    TLS_IO_INSTANCE* tls_io_instance = (TLS_IO_INSTANCE*)context;
+
+    if (open_result != IO_OPEN_OK)
+    {
+        LogError("Underlying IO open failed");
+        tls_io_instance->tlsio_state = TLSIO_STATE_ERROR;
+        indicate_open_complete(tls_io_instance, IO_OPEN_ERROR);
+    }
+    else
+    {
+        int res;
+        tls_io_instance->tlsio_state = TLSIO_STATE_IN_HANDSHAKE;
+        tls_io_instance->socket_reads = 0;
+
+        res = wolfSSL_connect(tls_io_instance->ssl);
+        if (res != SSL_SUCCESS)
+        {
+            LogError("WolfSSL connect failed");
+            indicate_open_complete(tls_io_instance, IO_OPEN_ERROR);
+            tls_io_instance->tlsio_state = TLSIO_STATE_ERROR;
+        }
+    }
+}
+
+static void on_underlying_io_bytes_received(void* context, const unsigned char* buffer, size_t size)
+{
+    if (context != NULL)
+    {
+        TLS_IO_INSTANCE* tls_io_instance = (TLS_IO_INSTANCE*)context;
+
+        unsigned char* new_socket_io_read_bytes = (unsigned char*)realloc(tls_io_instance->socket_io_read_bytes, tls_io_instance->socket_io_read_byte_count + size);
+        if (new_socket_io_read_bytes == NULL)
+        {
+            LogError("Failed allocating memory for received bytes");
+            tls_io_instance->tlsio_state = TLSIO_STATE_ERROR;
+            indicate_error(tls_io_instance);
+        }
+        else
+        {
+            tls_io_instance->socket_io_read_bytes = new_socket_io_read_bytes;
+            (void)memcpy(tls_io_instance->socket_io_read_bytes + tls_io_instance->socket_io_read_byte_count, buffer, size);
+            tls_io_instance->socket_io_read_byte_count += size;
+        }
+    }
+    else
+    {
+        LogInfo("Supplied context is NULL on bytes_received");
+    }
+}
+
+static void on_underlying_io_error(void* context)
+{
+    if (context != NULL)
+    {
+        TLS_IO_INSTANCE* tls_io_instance = (TLS_IO_INSTANCE*)context;
+
+        switch (tls_io_instance->tlsio_state)
+        {
+        default:
+            LogError("Unknown TLS IO WolfSSL state: %d", (int)tls_io_instance->tlsio_state);
+            break;
+
+        case TLSIO_STATE_NOT_OPEN:
+        case TLSIO_STATE_ERROR:
+            break;
+
+        case TLSIO_STATE_OPENING_UNDERLYING_IO:
+        case TLSIO_STATE_IN_HANDSHAKE:
+            tls_io_instance->tlsio_state = TLSIO_STATE_ERROR;
+            indicate_open_complete(tls_io_instance, IO_OPEN_ERROR);
+            break;
+
+        case TLSIO_STATE_OPEN:
+            tls_io_instance->tlsio_state = TLSIO_STATE_ERROR;
+            indicate_error(tls_io_instance);
+            break;
+        }
+    }
+    else
+    {
+        LogInfo("Supplied context is NULL on io_error");
+    }
+}
+
+static void on_underlying_io_close_complete(void* context)
+{
+    TLS_IO_INSTANCE* tls_io_instance = (TLS_IO_INSTANCE*)context;
+
+    if (tls_io_instance->tlsio_state != TLSIO_STATE_CLOSING)
+    {
+        LogError("on_underlying_io_close_complete called when not in CLOSING state");
+    }
+    else
+    {
+        if (tls_io_instance->on_io_close_complete != NULL)
+        {
+            tls_io_instance->on_io_close_complete(tls_io_instance->on_io_close_complete_context);
+        }
+        tls_io_instance->tlsio_state = TLSIO_STATE_NOT_OPEN;
+    }
+}
+
+static int on_io_recv(WOLFSSL *ssl, char *buf, int sz, void *context)
+{
+    int result;
+    if (context != NULL)
+    {
+        TLS_IO_INSTANCE* tls_io_instance = (TLS_IO_INSTANCE*)context;
+        unsigned char* new_socket_io_read_bytes;
+
+        AZURE_UNREFERENCED_PARAMETER(ssl);
+        if (tls_io_instance->socket_io_read_byte_count == 0)
+        {
+            if (tls_io_instance->socket_reads >= SOCKET_READ_LIMIT) {
+                return WOLFSSL_CBIO_ERR_TIMEOUT;
+            }
+            xio_dowork(tls_io_instance->socket_io);
+            if (tls_io_instance->tlsio_state == TLSIO_STATE_IN_HANDSHAKE)
+            {
+                tls_io_instance->socket_reads++;
+                ThreadAPI_Sleep(1);
+                return 0;
+            }
+        }
+
+        result = tls_io_instance->socket_io_read_byte_count;
+        if (result > sz)
+        {
+            result = sz;
+        }
+
+        if (result > 0)
+        {
+            (void)memcpy(buf, tls_io_instance->socket_io_read_bytes, result);
+            (void)memmove(tls_io_instance->socket_io_read_bytes, tls_io_instance->socket_io_read_bytes + result, tls_io_instance->socket_io_read_byte_count - result);
+            tls_io_instance->socket_io_read_byte_count -= result;
+            if (tls_io_instance->socket_io_read_byte_count > 0)
+            {
+                new_socket_io_read_bytes = (unsigned char*)realloc(tls_io_instance->socket_io_read_bytes, tls_io_instance->socket_io_read_byte_count);
+                if (new_socket_io_read_bytes != NULL)
+                {
+                    tls_io_instance->socket_io_read_bytes = new_socket_io_read_bytes;
+                }
+            }
+            else
+            {
+                free(tls_io_instance->socket_io_read_bytes);
+                tls_io_instance->socket_io_read_bytes = NULL;
+            }
+        }
+
+        if (tls_io_instance->tlsio_state == TLSIO_STATE_ERROR)
+        {
+            result = WOLFSSL_CBIO_ERR_GENERAL;
+        }
+        else if ( (result == 0) && (tls_io_instance->tlsio_state == TLSIO_STATE_OPEN))
+        {
+            result = WOLFSSL_CBIO_ERR_WANT_READ;
+        }
+        else if ((result == 0) && (tls_io_instance->tlsio_state == TLSIO_STATE_CLOSING || tls_io_instance->tlsio_state == TLSIO_STATE_NOT_OPEN))
+        {
+            result = WOLFSSL_CBIO_ERR_CONN_CLOSE;
+        }
+    }
+    else
+    {
+        result = WOLFSSL_CBIO_ERR_GENERAL;
+    }
+    return result;
+}
+
+static void on_send_complete(void* context, IO_SEND_RESULT send_result)
+{
+	TLS_IO_INSTANCE* tls_io_instance = (TLS_IO_INSTANCE*)context;
+	if ((tls_io_instance == NULL) || (tls_io_instance->on_send_complete == NULL))
+		return;
+
+	tls_io_instance->on_send_complete(tls_io_instance->on_send_complete_callback_context, send_result);
+
+	tls_io_instance->on_send_complete = NULL;
+	tls_io_instance->on_send_complete_callback_context = NULL;
+}
+
+static int on_io_send(WOLFSSL *ssl, char *buf, int sz, void *context)
+{
+    int result, ret;
+    AZURE_UNREFERENCED_PARAMETER(ssl);
+
+    TLS_IO_INSTANCE* tls_io_instance = (TLS_IO_INSTANCE*)context;
+
+    if ((ret = xio_send(tls_io_instance->socket_io, buf, sz, on_send_complete, tls_io_instance)) != 0)
+    {
+        LogError("Failed sending bytes through underlying IO %d", ret);
+        tls_io_instance->tlsio_state = TLSIO_STATE_ERROR;
+        indicate_error(tls_io_instance);
+        result = 0;
+    }
+    else
+    {
+        result = sz;
+    }
+
+    return result;
+}
+
+static int on_handshake_done(WOLFSSL* ssl, void* context)
+{
+    AZURE_UNREFERENCED_PARAMETER(ssl);
+    TLS_IO_INSTANCE* tls_io_instance = (TLS_IO_INSTANCE*)context;
+    if (tls_io_instance->tlsio_state == TLSIO_STATE_OPEN) {
+        LogInfo("on_handshake_done called in TLSIO_STATE_OPEN state");
+    }
+    else if (tls_io_instance->tlsio_state != TLSIO_STATE_IN_HANDSHAKE)
+    {
+        LogInfo("on_handshake_done called when not in IN_HANDSHAKE state");
+    }
+    else
+    {
+        tls_io_instance->tlsio_state = TLSIO_STATE_OPEN;
+        indicate_open_complete(tls_io_instance, IO_OPEN_OK);
+    }
+
+    return 0;
+}
+
+static int add_certificate_to_store(TLS_IO_INSTANCE* tls_io_instance)
+{
+    int result;
+    if (tls_io_instance->certificate != NULL)
+    {
+        int res = wolfSSL_CTX_load_verify_buffer(tls_io_instance->ssl_context, (const unsigned char*)tls_io_instance->certificate, strlen(tls_io_instance->certificate), SSL_FILETYPE_PEM);
+        if (res != SSL_SUCCESS)
+        {
+            LogError("wolfSSL_CTX_load_verify_buffer failed");
+            result = MU_FAILURE;
+        }
+        else
+        {
+            result = 0;
+        }
+    }
+    else
+    {
+        result = 0;
+    }
+    return result;
+}
+
+static int x509_wolfssl_add_credentials(WOLFSSL* ssl, char* x509certificate, char* x509privatekey) {
+
+    int result;
+
+    if (wolfSSL_use_certificate_chain_buffer(ssl, (unsigned char*)x509certificate, strlen(x509certificate)) != SSL_SUCCESS)
+    {
+        LogError("unable to load x509 client certificate");
+        result = MU_FAILURE;
+    }
+    else if (wolfSSL_use_PrivateKey_buffer(ssl, (unsigned char*)x509privatekey, strlen(x509privatekey), SSL_FILETYPE_PEM) != SSL_SUCCESS)
+    {
+        LogError("unable to load x509 client private key");
+        result = MU_FAILURE;
+    }
+#ifdef HAVE_SECURE_RENEGOTIATION
+    else if (wolfSSL_UseSecureRenegotiation(ssl) != SSL_SUCCESS)
+    {
+        LogError("unable to enable secure renegotiation");
+        result = MU_FAILURE;
+    }
+#endif
+    else
+    {
+        result = 0;
+    }
+    return result;
+}
+
+static void destroy_wolfssl_instance(TLS_IO_INSTANCE* tls_io_instance)
+{
+    wolfSSL_free(tls_io_instance->ssl);
+    tls_io_instance->ssl = NULL;
+}
+
+static int create_wolfssl_instance(TLS_IO_INSTANCE* tls_io_instance)
+{
+    int result;
+    tls_io_instance->ssl = wolfSSL_new(tls_io_instance->ssl_context);
+    if (tls_io_instance->ssl == NULL)
+    {
+        LogError("Failed to add certificates to store");
+        result = MU_FAILURE;
+    }
+    else
+    {
+        tls_io_instance->socket_io_read_bytes = NULL;
+        tls_io_instance->socket_io_read_byte_count = 0;
+        tls_io_instance->on_send_complete = NULL;
+        tls_io_instance->on_send_complete_callback_context = NULL;
+#ifdef INVALID_DEVID
+        tls_io_instance->wolfssl_device_id = INVALID_DEVID;
+#endif
+
+        wolfSSL_set_using_nonblock(tls_io_instance->ssl, 1);
+        wolfSSL_SetHsDoneCb(tls_io_instance->ssl, on_handshake_done, tls_io_instance);
+        wolfSSL_SetIOWriteCtx(tls_io_instance->ssl, tls_io_instance);
+        wolfSSL_SetIOReadCtx(tls_io_instance->ssl, tls_io_instance);
+
+        tls_io_instance->tlsio_state = TLSIO_STATE_NOT_OPEN;
+        result = 0;
+    }
+    return result;
+}
+
+static int prepare_wolfssl_open(TLS_IO_INSTANCE* tls_io_instance)
+{
+    int result;
+    if (add_certificate_to_store(tls_io_instance) != 0)
+    {
+        LogError("Failed to add certificates to store");
+        result = MU_FAILURE;
+    }
+    /*x509 authentication can only be build before underlying connection is realized*/
+    else if ((tls_io_instance->x509certificate != NULL) &&
+        (tls_io_instance->x509privatekey != NULL) &&
+        (x509_wolfssl_add_credentials(tls_io_instance->ssl, tls_io_instance->x509certificate, tls_io_instance->x509privatekey) != 0))
+    {
+        destroy_wolfssl_instance(tls_io_instance);
+        LogError("unable to use x509 authentication");
+        result = MU_FAILURE;
+    }
+#ifdef INVALID_DEVID
+    else if (tls_io_instance->wolfssl_device_id != INVALID_DEVID && wolfSSL_SetDevId(tls_io_instance->ssl, tls_io_instance->wolfssl_device_id) != WOLFSSL_SUCCESS)
+    {
+        LogError("Failure setting device id");
+        result = MU_FAILURE;
+    }
+#endif
+    else
+    {
+        result = 0;
+    }
+    return result;
+}
+
+int tlsio_wolfssl_init(void)
+{
+    (void)wolfSSL_library_init();
+    wolfSSL_load_error_strings();
+
+    return 0;
+}
+
+void tlsio_wolfssl_deinit(void)
+{
+}
+
+CONCRETE_IO_HANDLE tlsio_wolfssl_create(void* io_create_parameters)
+{
+    TLS_IO_INSTANCE* result;
+
+    if (io_create_parameters == NULL)
+    {
+        LogError("NULL io_create_parameters");
+        result = NULL;
+    }
+    else
+    {
+        TLSIO_CONFIG* tls_io_config = io_create_parameters;
+
+        result = (TLS_IO_INSTANCE*)malloc(sizeof(TLS_IO_INSTANCE));
+        if (result == NULL)
+        {
+            LogError("Failed allocating memory for the TLS IO instance.");
+        }
+        else
+        {
+            (void)memset(result, 0, sizeof(TLS_IO_INSTANCE));
+            result->tlsio_state = TLSIO_STATE_NOT_OPEN;
+
+            result->ssl_context = wolfSSL_CTX_new(wolfTLSv1_2_client_method());
+            if (result->ssl_context == NULL)
+            {
+                LogError("Cannot create the wolfSSL context");
+                free(result);
+                result = NULL;
+            }
+            else
+            {
+                // Set the recv and send function on the wolfssl context object
+                wolfSSL_SetIOSend(result->ssl_context, on_io_send);
+                wolfSSL_SetIORecv(result->ssl_context, on_io_recv);
+
+                SOCKETIO_CONFIG socketio_config;
+                const IO_INTERFACE_DESCRIPTION* underlying_io_interface;
+                void* io_interface_parameters;
+
+                if (tls_io_config->underlying_io_interface != NULL)
+                {
+                    underlying_io_interface = tls_io_config->underlying_io_interface;
+                    io_interface_parameters = tls_io_config->underlying_io_parameters;
+                }
+                else
+                {
+                    socketio_config.hostname = tls_io_config->hostname;
+                    socketio_config.port = tls_io_config->port;
+                    socketio_config.accepted_socket = NULL;
+
+                    underlying_io_interface = socketio_get_interface_description();
+                    io_interface_parameters = &socketio_config;
+                }
+
+                if (underlying_io_interface == NULL)
+                {
+                    LogError("Failed getting socket IO interface description.");
+                    wolfSSL_CTX_free(result->ssl_context);
+                    free(result);
+                    result = NULL;
+                }
+                else
+                {
+                    result->socket_io = xio_create(underlying_io_interface, io_interface_parameters);
+                    if (result->socket_io == NULL)
+                    {
+                        LogError("Failure connecting to underlying socket_io");
+                        wolfSSL_CTX_free(result->ssl_context);
+                        free(result);
+                        result = NULL;
+                    }
+                    else if (create_wolfssl_instance(result) != 0)
+                    {
+                        LogError("Failure connecting to underlying socket_io");
+                        wolfSSL_CTX_free(result->ssl_context);
+                        free(result);
+                        result = NULL;
+                    }
+                }
+            }
+        }
+    }
+
+    return result;
+}
+
+void tlsio_wolfssl_destroy(CONCRETE_IO_HANDLE tls_io)
+{
+    if (tls_io != NULL)
+    {
+        TLS_IO_INSTANCE* tls_io_instance = (TLS_IO_INSTANCE*)tls_io;
+        if (tls_io_instance->socket_io_read_bytes != NULL)
+        {
+            free(tls_io_instance->socket_io_read_bytes);
+            tls_io_instance->socket_io_read_bytes = NULL;
+        }
+        if (tls_io_instance->certificate != NULL)
+        {
+            free(tls_io_instance->certificate);
+            tls_io_instance->certificate = NULL;
+        }
+        if (tls_io_instance->x509certificate != NULL)
+        {
+            free(tls_io_instance->x509certificate);
+            tls_io_instance->x509certificate = NULL;
+        }
+        if (tls_io_instance->x509privatekey != NULL)
+        {
+            free(tls_io_instance->x509privatekey);
+            tls_io_instance->x509privatekey = NULL;
+        }
+        destroy_wolfssl_instance(tls_io_instance);
+
+        wolfSSL_CTX_free(tls_io_instance->ssl_context);
+        tls_io_instance->ssl_context = NULL;
+
+        xio_destroy(tls_io_instance->socket_io);
+        free(tls_io);
+    }
+}
+
+int tlsio_wolfssl_open(CONCRETE_IO_HANDLE tls_io, ON_IO_OPEN_COMPLETE on_io_open_complete, void* on_io_open_complete_context, ON_BYTES_RECEIVED on_bytes_received, void* on_bytes_received_context, ON_IO_ERROR on_io_error, void* on_io_error_context)
+{
+    int result;
+
+    if (tls_io == NULL)
+    {
+        LogError("NULL tls_io instance");
+        result = MU_FAILURE;
+    }
+    else
+    {
+        TLS_IO_INSTANCE* tls_io_instance = (TLS_IO_INSTANCE*)tls_io;
+
+        if (tls_io_instance->tlsio_state != TLSIO_STATE_NOT_OPEN)
+        {
+            LogError("Invalid state encountered.");
+            result = MU_FAILURE;
+        }
+        else
+        {
+            tls_io_instance->on_bytes_received = on_bytes_received;
+            tls_io_instance->on_bytes_received_context = on_bytes_received_context;
+
+            tls_io_instance->on_io_open_complete = on_io_open_complete;
+            tls_io_instance->on_io_open_complete_context = on_io_open_complete_context;
+
+            tls_io_instance->on_io_error = on_io_error;
+            tls_io_instance->on_io_error_context = on_io_error_context;
+
+            tls_io_instance->tlsio_state = TLSIO_STATE_OPENING_UNDERLYING_IO;
+
+            if (prepare_wolfssl_open(tls_io_instance) != 0)
+            {
+                LogError("Cannot create wolfssl instance.");
+                tls_io_instance->tlsio_state = TLSIO_STATE_NOT_OPEN;
+                result = MU_FAILURE;
+            }
+            else if (xio_open(tls_io_instance->socket_io, on_underlying_io_open_complete, tls_io_instance, on_underlying_io_bytes_received, tls_io_instance, on_underlying_io_error, tls_io_instance) != 0)
+            {
+                LogError("Cannot open the underlying IO.");
+                tls_io_instance->tlsio_state = TLSIO_STATE_NOT_OPEN;
+                result = MU_FAILURE;
+            }
+            else
+            {
+                // The state can get changed in the on_underlying_io_open_complete
+                if (tls_io_instance->tlsio_state != TLSIO_STATE_OPEN)
+                {
+                    LogError("Failed to connect to server.  The certificates may not be correct.");
+                    result = MU_FAILURE;
+                }
+                else
+                {
+                    result = 0;
+                }
+            }
+        }
+    }
+
+    return result;
+}
+
+int tlsio_wolfssl_close(CONCRETE_IO_HANDLE tls_io, ON_IO_CLOSE_COMPLETE on_io_close_complete, void* callback_context)
+{
+    int result = 0;
+
+    if (tls_io == NULL)
+    {
+        LogError("NULL tls_io handle.");
+        result = MU_FAILURE;
+    }
+    else
+    {
+        TLS_IO_INSTANCE* tls_io_instance = (TLS_IO_INSTANCE*)tls_io;
+
+        if ((tls_io_instance->tlsio_state == TLSIO_STATE_NOT_OPEN) ||
+            (tls_io_instance->tlsio_state == TLSIO_STATE_CLOSING))
+        {
+            LogError("Close called while not open.");
+            result = MU_FAILURE;
+        }
+        else
+        {
+            tls_io_instance->tlsio_state = TLSIO_STATE_CLOSING;
+            tls_io_instance->on_io_close_complete = on_io_close_complete;
+            tls_io_instance->on_io_close_complete_context = callback_context;
+
+            if (xio_close(tls_io_instance->socket_io, on_underlying_io_close_complete, tls_io_instance) != 0)
+            {
+                LogError("xio_close failed.");
+                result = MU_FAILURE;
+            }
+            else
+            {
+                result = 0;
+            }
+        }
+    }
+
+    return result;
+}
+
+int tlsio_wolfssl_send(CONCRETE_IO_HANDLE tls_io, const void* buffer, size_t size, ON_SEND_COMPLETE on_send_complete, void* callback_context)
+{
+    int result;
+
+    if (tls_io == NULL || buffer == NULL || size == 0)
+    {
+        LogError("Invalid parameter specified tls_io: %p, buffer: %p, size: %ul", tls_io, buffer, (unsigned int)size);
+        result = MU_FAILURE;
+    }
+    else
+    {
+        TLS_IO_INSTANCE* tls_io_instance = (TLS_IO_INSTANCE*)tls_io;
+
+        if (tls_io_instance->tlsio_state != TLSIO_STATE_OPEN)
+        {
+            LogError("send called while not open");
+            result = MU_FAILURE;
+        }
+        if (tls_io_instance->on_send_complete != NULL)
+        {
+            LogError("Error writing data");
+            result = MU_FAILURE;
+        }
+        else
+        {
+            tls_io_instance->on_send_complete = on_send_complete;
+            tls_io_instance->on_send_complete_callback_context = callback_context;
+
+            int res = wolfSSL_write(tls_io_instance->ssl, buffer, size);
+            if ((res < 0) || ((size_t)res != size)) // Best way I can think of to safely compare an int to a size_t
+            {
+                LogError("Error writing data through WolfSSL");
+                result = MU_FAILURE;
+            }
+            else
+            {
+                result = 0;
+            }
+        }
+    }
+
+    return result;
+}
+
+void tlsio_wolfssl_dowork(CONCRETE_IO_HANDLE tls_io)
+{
+    if (tls_io == NULL)
+    {
+        LogError("NULL tls_io");
+    }
+    else
+    {
+        TLS_IO_INSTANCE* tls_io_instance = (TLS_IO_INSTANCE*)tls_io;
+
+        if ((tls_io_instance->tlsio_state != TLSIO_STATE_NOT_OPEN) &&
+            (tls_io_instance->tlsio_state != TLSIO_STATE_ERROR))
+        {
+            if (tls_io_instance->tlsio_state != TLSIO_STATE_OPENING_UNDERLYING_IO)
+                decode_ssl_received_bytes(tls_io_instance);
+            xio_dowork(tls_io_instance->socket_io);
+        }
+    }
+}
+
+
+static int process_option(char** destination, const char* name, const char* value)
+{
+    int result;
+    if (*destination != NULL)
+    {
+        free(*destination);
+        *destination = NULL;
+    }
+    if (mallocAndStrcpy_s(destination, value) != 0)
+    {
+        LogError("unable to process option %s",name);
+        result = MU_FAILURE;
+    }
+    else
+    {
+        result = 0;
+    }
+    return result;
+}
+
+int tlsio_wolfssl_setoption(CONCRETE_IO_HANDLE tls_io, const char* optionName, const void* value)
+{
+    int result;
+
+    if (tls_io == NULL || optionName == NULL)
+    {
+        LogError("Bad arguments, tls_io = %p, optionName = %p", tls_io, optionName);
+        result = MU_FAILURE;
+    }
+    else
+    {
+        TLS_IO_INSTANCE* tls_io_instance = (TLS_IO_INSTANCE*)tls_io;
+
+        if (strcmp(OPTION_TRUSTED_CERT, optionName) == 0)
+        {
+            result  = process_option(&tls_io_instance->certificate, optionName, value);
+        }
+        else if (strcmp(SU_OPTION_X509_CERT, optionName) == 0 || strcmp(OPTION_X509_ECC_CERT, optionName) == 0)
+        {
+            result = process_option(&tls_io_instance->x509certificate, optionName, value);
+        }
+        else if (strcmp(SU_OPTION_X509_PRIVATE_KEY, optionName) == 0 || strcmp(OPTION_X509_ECC_KEY, optionName) == 0)
+        {
+            result = process_option(&tls_io_instance->x509privatekey, optionName, value);
+        }
+        else if (strcmp(optionName, OPTION_SET_TLS_RENEGOTIATION) == 0)
+        {
+            // No need to do anything for WolfSSL
+            result = 0;
+        }
+#ifdef INVALID_DEVID
+        else if (strcmp(OPTION_WOLFSSL_SET_DEVICE_ID, optionName) == 0)
+        {
+            int device_id = *((int *)value);
+            if (tls_io_instance->ssl != NULL)
+            {
+                if (tls_io_instance->ssl != NULL && wolfSSL_SetDevId(tls_io_instance->ssl, device_id) != WOLFSSL_SUCCESS)
+                {
+                    LogError("Failure setting device id on ssl");
+                    result = MU_FAILURE;
+                }
+                else
+                {
+                    result = 0;
+                }
+            }
+            else
+            {
+                // Save the id till we create the ssl object
+                tls_io_instance->wolfssl_device_id = device_id;
+                result = 0;
+            }
+        }
+#endif
+        else
+        {
+            if (tls_io_instance->socket_io == NULL)
+            {
+                LogError("NULL underlying IO handle");
+                result = MU_FAILURE;
+            }
+            else
+            {
+                result = xio_setoption(tls_io_instance->socket_io, optionName, value);
+            }
+        }
+    }
+
+    return result;
+}
+const IO_INTERFACE_DESCRIPTION* tlsio_wolfssl_get_interface_description(void)
+{
+    return &tlsio_wolfssl_interface_description;
+}
Index: azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/adapters/uniqueid_stub.c
===================================================================
--- azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/adapters/uniqueid_stub.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/adapters/uniqueid_stub.c	(revision 457)
@@ -0,0 +1,76 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+#include <stdlib.h>
+#include <stdint.h>
+#include "azure_c_shared_utility/uniqueid.h"
+#include "azure_c_shared_utility/xlogging.h"
+#include <time.h>
+
+MU_DEFINE_ENUM_STRINGS(UNIQUEID_RESULT, UNIQUEID_RESULT_VALUES);
+
+static const char tochar[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
+static void generate128BitUUID(unsigned char* arrayOfByte)
+{
+    size_t arrayIndex;
+
+    for (arrayIndex = 0; arrayIndex < 16; arrayIndex++)
+    {
+        arrayOfByte[arrayIndex] = (unsigned char)rand();
+    }
+
+    //
+    // Stick in the version field for random uuid.
+    //
+    arrayOfByte[7] &= 0x0f; //clear the bit field
+    arrayOfByte[7] |= 0x40; //set the ones we care about
+
+    //
+    // Stick in the variant field for the random uuid.
+    //
+    arrayOfByte[8] &= 0xf3; // Clear
+    arrayOfByte[8] |= 0x08; // Set
+
+}
+
+// TODO: The User will need to call srand before calling this function
+UNIQUEID_RESULT UniqueId_Generate(char* uid, size_t len)
+{
+    UNIQUEID_RESULT result;
+    unsigned char arrayOfChar[16];
+
+    /* Codes_SRS_UNIQUEID_07_002: [If uid is NULL then UniqueId_Generate shall return UNIQUEID_INVALID_ARG] */
+    /* Codes_SRS_UNIQUEID_07_003: [If len is less then 37 then UniqueId_Generate shall return UNIQUEID_INVALID_ARG] */
+    if (uid == NULL || len < 37)
+    {
+        result = UNIQUEID_INVALID_ARG;
+        LogError("Buffer Size is Null or length is less then 37 bytes");
+    }
+    else 
+    {
+        size_t arrayIndex;
+        size_t shiftCount;
+        size_t characterPosition = 0;
+
+        /* Codes_SRS_UNIQUEID_07_001: [UniqueId_Generate shall create a unique Id 36 character long string.] */
+        generate128BitUUID(arrayOfChar);
+        for (arrayIndex = 0; arrayIndex < 16; arrayIndex++)
+        {
+            for (shiftCount = 0; shiftCount <= 1; shiftCount++)
+            {
+                char hexChar = tochar[arrayOfChar[arrayIndex] & 0xf];
+                if ((characterPosition == 8) || (characterPosition == 13) || (characterPosition == 18) || (characterPosition == 23))
+                {
+                    uid[characterPosition] = '-';
+                    characterPosition++;
+                }
+                uid[characterPosition] = hexChar;
+                characterPosition++;
+                arrayOfChar[arrayIndex] = arrayOfChar[arrayIndex] >> 4;
+            }
+        }
+        uid[characterPosition] = 0;
+        result = UNIQUEID_OK;
+    }
+    return result;
+}
Index: azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/inc/azure_c_shared_utility/agenttime.h
===================================================================
--- azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/inc/azure_c_shared_utility/agenttime.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/inc/azure_c_shared_utility/agenttime.h	(revision 457)
@@ -0,0 +1,63 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+/** @file agenttime.h
+*	@brief Function prototypes for time related functions.
+*
+*	@details These functions are implemented with C standard functions,
+*	and therefore they are platform independent. But then a platform
+*	can replace these functions with its own implementation as necessary.
+*/
+
+#ifndef AGENTTIME_H
+#define AGENTTIME_H
+
+#include <time.h>
+#include "umock_c/umock_c_prod.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/** @brief Get current calendar time.
+*
+*	@details This function provides the same functionality as the
+*	standard C @c time() function.
+*/
+MOCKABLE_FUNCTION(, time_t, get_time, time_t*, currentTime);
+
+/** @brief Get UTC in @c tm struct.
+*
+*	@details This function provides the same functionality as the
+*	standard C @c gmtime() function.
+*/
+MOCKABLE_FUNCTION(, struct tm*, get_gmtime, time_t*, currentTime);
+
+/** @brief Get current time representation of the given calendar time.
+*
+*	@details This function provides the same functionality as the
+*	standard C @c mktime() function.
+*/
+MOCKABLE_FUNCTION(, time_t, get_mktime, struct tm*, cal_time);
+
+/** @brief Gets a C-string representation of the given time.
+*
+*	@details This function provides the same functionality as the
+*	standard C @c ctime() function.
+*/
+MOCKABLE_FUNCTION(, char*, get_ctime, time_t*, timeToGet);
+
+/** @brief Gets the difference in seconds between @c stopTime and
+*	@c startTime.
+*
+*	@details This function provides the same functionality as the
+*	standard C @c difftime() function.
+*/
+MOCKABLE_FUNCTION(, double, get_difftime, time_t, stopTime, time_t, startTime);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif  // AGENTTIME_H
Index: azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/inc/azure_c_shared_utility/azure_base32.h
===================================================================
--- azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/inc/azure_c_shared_utility/azure_base32.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/inc/azure_c_shared_utility/azure_base32.h	(revision 457)
@@ -0,0 +1,63 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+#ifndef AZURE_BASE32_H
+#define AZURE_BASE32_H
+
+#ifdef __cplusplus
+#include <cstddef>
+#else
+#include <stddef.h>
+#endif
+
+#include "azure_c_shared_utility/strings.h"
+#include "azure_c_shared_utility/buffer_.h"
+
+#include "umock_c/umock_c_prod.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+* @brief Encodes the BUFFER_HANDLE to a base 32 STRING_HANDLE
+*
+* @param    input   BUFFER_HANDLE of the unsigned char* to be encoded
+*
+* @return   A base32 encoded STRING_HANDLE that will need to be deallocated
+*/
+MOCKABLE_FUNCTION(, STRING_HANDLE, Azure_Base32_Encode, BUFFER_HANDLE, input);
+
+/**
+* @brief    Encodes the BUFFER_HANDLE to a base 32 char*
+*
+* @param    source   An unsigned char* to be encoded
+* @param    size     The lenght in bytes of the source variable
+*
+* @return   A base32 encoded string that will need to be deallocated
+*/
+MOCKABLE_FUNCTION(, char*, Azure_Base32_Encode_Bytes, const unsigned char*, source, size_t, size);
+
+/**
+* @brief    Decodes a base32 encoded STRING_HANDLE to a BUFFER_HANDLE
+*
+* @param    handle   STRING_HANDLE of a base32 encode string
+*
+* @return   A BUFFER_HANDLE of the result of decoding the handle
+*/
+MOCKABLE_FUNCTION(, BUFFER_HANDLE, Azure_Base32_Decode, STRING_HANDLE, handle);
+
+/**
+* @brief    Decodes a base32 encoded char* to a BUFFER_HANDLE
+*
+* @param    source   char* of a base32 encode string
+*
+* @return   A BUFFER_HANDLE of the result of decoding the source
+*/
+MOCKABLE_FUNCTION(, BUFFER_HANDLE, Azure_Base32_Decode_String, const char*, source);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* AZURE_BASE32_H */
Index: azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/inc/azure_c_shared_utility/azure_base64.h
===================================================================
--- azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/inc/azure_c_shared_utility/azure_base64.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/inc/azure_c_shared_utility/azure_base64.h	(revision 457)
@@ -0,0 +1,85 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+/** @file azure_base64.h
+*    @brief Prototypes for functions related to encoding/decoding
+*    a @c buffer using standard base64 encoding.
+*/
+
+#ifndef AZURE_BASE64_H
+#define AZURE_BASE64_H
+
+#ifdef __cplusplus
+#include <cstddef>
+#else
+#include <stddef.h>
+#endif
+
+#include "azure_c_shared_utility/strings.h"
+#include "azure_c_shared_utility/buffer_.h"
+
+#include "umock_c/umock_c_prod.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @brief    Base64 encodes a buffer and returns the resulting string.
+ *
+ * @param    input    The buffer that needs to be base64 encoded.
+ *
+ *             Azure_Base64_Encode takes as a parameter a pointer to a BUFFER. If @p input is @c NULL then
+ *             @c Azure_Base64_Encode returns @c NULL. The size of the BUFFER pointed to by @p input may
+ *             be zero. If when allocating memory to produce the encoding a failure occurs, then @c
+ *             Azure_Base64_Encode returns @c NULL. Otherwise
+ *             @c Azure_Base64_Encode returns a pointer to a STRING. That string contains the
+ *             base 64 encoding of the @p input. This encoding of @p input will not contain embedded
+ *             line feeds.
+ *
+ * @return    A @c STRING_HANDLE containing the base64 encoding of @p input.
+ */
+MOCKABLE_FUNCTION(, STRING_HANDLE, Azure_Base64_Encode, BUFFER_HANDLE, input);
+
+/**
+ * @brief    Base64 encodes the buffer pointed to by @p source and returns the resulting string.
+ *
+ * @param    source    The buffer that needs to be base64 encoded.
+ * @param    size      The size.
+ *
+ *             This function produces a @c STRING_HANDLE containing the base64 encoding of the
+ *             buffer pointed to by @p source, having the size as given by
+ *             @p size. If @p source is @c NULL then @c Azure_Base64_Encode_Bytes returns @c NULL
+ *             If @p source is not @c NULL and @p size is zero, then @c Azure_Base64_Encode_Bytes produces
+ *             an empty @c STRING_HANDLE. Otherwise, @c Azure_Base64_Encode_Bytes produces a
+ *             @c STRING_HANDLE containing the Base64 representation of the buffer. In case of
+ *             any errors, @c Azure_Base64_Encode_Bytes returns @c NULL.].
+ *
+ * @return    @c NULL in case an error occurs or a @c STRING_HANDLE containing the base64 encoding
+ *             of @p input.
+ *
+ */
+MOCKABLE_FUNCTION(, STRING_HANDLE, Azure_Base64_Encode_Bytes, const unsigned char*, source, size_t, size);
+
+/**
+ * @brief    Base64 decodes the buffer pointed to by @p source and returns the resulting buffer.
+ *
+ * @param    source    A base64 encoded string buffer.
+ *
+ *           This function decodes the string pointed at by @p source using base64 decoding and
+ *             returns the resulting buffer. If @p source is @c NULL then
+ *             @c Azure_Base64_Decode returns NULL. If the string pointed to by @p source is zero
+ *             length then the handle returned refers to a zero length buffer. If there is any
+ *             memory allocation failure during the decode or if the source string has an invalid
+ *             length for a base 64 encoded string then @c Azure_Base64_Decode returns @c NULL.
+ *
+ * @return    A @c BUFFER_HANDLE pointing to a buffer containing the result of base64 decoding @p
+ *             source.
+ */
+MOCKABLE_FUNCTION(, BUFFER_HANDLE, Azure_Base64_Decode, const char*, source);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* AZURE_BASE64_H */
Index: azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/inc/azure_c_shared_utility/buffer_.h
===================================================================
--- azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/inc/azure_c_shared_utility/buffer_.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/inc/azure_c_shared_utility/buffer_.h	(revision 457)
@@ -0,0 +1,46 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+#ifndef BUFFER__H
+#define BUFFER__H
+
+#ifdef __cplusplus
+#include <cstddef>
+#else
+#include <stddef.h>
+#include <stdbool.h>
+#endif
+
+#include "umock_c/umock_c_prod.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+typedef struct BUFFER_TAG* BUFFER_HANDLE;
+
+MOCKABLE_FUNCTION(, BUFFER_HANDLE, BUFFER_new);
+MOCKABLE_FUNCTION(, BUFFER_HANDLE, BUFFER_create, const unsigned char*, source, size_t, size);
+MOCKABLE_FUNCTION(, BUFFER_HANDLE, BUFFER_create_with_size, size_t, buff_size);
+MOCKABLE_FUNCTION(, void, BUFFER_delete, BUFFER_HANDLE, handle);
+MOCKABLE_FUNCTION(, int, BUFFER_pre_build, BUFFER_HANDLE, handle, size_t, size);
+MOCKABLE_FUNCTION(, int, BUFFER_build, BUFFER_HANDLE, handle, const unsigned char*, source, size_t, size);
+MOCKABLE_FUNCTION(, int, BUFFER_append_build, BUFFER_HANDLE, handle, const unsigned char*, source, size_t, size);
+MOCKABLE_FUNCTION(, int, BUFFER_unbuild, BUFFER_HANDLE, handle);
+MOCKABLE_FUNCTION(, int, BUFFER_enlarge, BUFFER_HANDLE, handle, size_t, enlargeSize);
+MOCKABLE_FUNCTION(, int, BUFFER_shrink, BUFFER_HANDLE, handle, size_t, decreaseSize, bool, fromEnd);
+MOCKABLE_FUNCTION(, int, BUFFER_content, BUFFER_HANDLE, handle, const unsigned char**, content);
+MOCKABLE_FUNCTION(, int, BUFFER_size, BUFFER_HANDLE, handle, size_t*, size);
+MOCKABLE_FUNCTION(, int, BUFFER_append, BUFFER_HANDLE, handle1, BUFFER_HANDLE, handle2);
+MOCKABLE_FUNCTION(, int, BUFFER_prepend, BUFFER_HANDLE, handle1, BUFFER_HANDLE, handle2);
+MOCKABLE_FUNCTION(, int, BUFFER_fill, BUFFER_HANDLE, handle, unsigned char, fill_char);
+MOCKABLE_FUNCTION(, unsigned char*, BUFFER_u_char, BUFFER_HANDLE, handle);
+MOCKABLE_FUNCTION(, size_t, BUFFER_length, BUFFER_HANDLE, handle);
+MOCKABLE_FUNCTION(, BUFFER_HANDLE, BUFFER_clone, BUFFER_HANDLE, handle);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif  /* BUFFER__H */
Index: azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/inc/azure_c_shared_utility/condition.h
===================================================================
--- azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/inc/azure_c_shared_utility/condition.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/inc/azure_c_shared_utility/condition.h	(revision 457)
@@ -0,0 +1,72 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+#ifndef CONDITION_H
+#define CONDITION_H
+
+#include "azure_macro_utils/macro_utils.h"
+#include "azure_c_shared_utility/lock.h"
+#include "umock_c/umock_c_prod.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef void* COND_HANDLE;
+
+#define COND_RESULT_VALUES \
+    COND_OK, \
+    COND_INVALID_ARG, \
+    COND_ERROR, \
+    COND_TIMEOUT \
+
+/**
+* @brief Enumeration specifying the lock status.
+*/
+MU_DEFINE_ENUM(COND_RESULT, COND_RESULT_VALUES);
+
+/**
+* @brief	This API creates and returns a valid condition handle.
+*
+* @return	A valid @c COND_HANDLE when successful or @c NULL otherwise.
+*/
+MOCKABLE_FUNCTION(, COND_HANDLE, Condition_Init);
+
+/**
+* @brief	unblock all currently working condition.
+*
+* @param	handle	A valid handle to the lock.
+*
+* @return	Returns @c COND_OK when the condition object has been
+* 			destroyed and @c COND_ERROR when an error occurs
+* 			and @c COND_TIMEOUT when the handle times out.
+*/
+MOCKABLE_FUNCTION(, COND_RESULT, Condition_Post, COND_HANDLE, handle);
+
+/**
+* @brief	block on the condition handle unti the thread is signalled
+*           or until the timeout_milliseconds is reached.
+*
+* @param	handle	A valid handle to the lock.
+*
+* @return	Returns @c COND_OK when the condition object has been
+* 			destroyed and @c COND_ERROR when an error occurs
+* 			and @c COND_TIMEOUT when the handle times out.
+*/
+MOCKABLE_FUNCTION(, COND_RESULT, Condition_Wait, COND_HANDLE, handle, LOCK_HANDLE, lock, int, timeout_milliseconds);
+
+/**
+* @brief	The condition instance is deinitialized.
+*
+* @param	handle	A valid handle to the condition.
+*
+* @return	Returns @c COND_OK when the condition object has been
+* 			destroyed and @c COND_ERROR when an error occurs.
+*/
+MOCKABLE_FUNCTION(, void, Condition_Deinit, COND_HANDLE, handle);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* CONDITION_H */
Index: azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/inc/azure_c_shared_utility/connection_string_parser.h
===================================================================
--- azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/inc/azure_c_shared_utility/connection_string_parser.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/inc/azure_c_shared_utility/connection_string_parser.h	(revision 457)
@@ -0,0 +1,26 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+#ifndef CONNECTION_STRING_PARSER_H
+#define CONNECTION_STRING_PARSER_H
+
+#include "azure_c_shared_utility/map.h"
+#include "azure_c_shared_utility/strings.h"
+
+#include "umock_c/umock_c_prod.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+    MOCKABLE_FUNCTION(, MAP_HANDLE, connectionstringparser_parse_from_char, const char*, connection_string);
+    MOCKABLE_FUNCTION(, MAP_HANDLE, connectionstringparser_parse, STRING_HANDLE, connection_string);
+    MOCKABLE_FUNCTION(, int, connectionstringparser_splitHostName_from_char, const char*, hostName, STRING_HANDLE, nameString, STRING_HANDLE, suffixString);
+    MOCKABLE_FUNCTION(, int, connectionstringparser_splitHostName, STRING_HANDLE, hostNameString, STRING_HANDLE, nameString, STRING_HANDLE, suffixString);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* CONNECTION_STRING_PARSER_H */
Index: azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/inc/azure_c_shared_utility/consolelogger.h
===================================================================
--- azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/inc/azure_c_shared_utility/consolelogger.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/inc/azure_c_shared_utility/consolelogger.h	(revision 457)
@@ -0,0 +1,23 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+#ifndef CONSOLELOGGER_H
+#define CONSOLELOGGER_H
+
+#include "azure_c_shared_utility/xlogging.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+    void consolelogger_log(LOG_CATEGORY log_category, const char* file, const char* func, int line, unsigned int options, const char* format, ...);
+
+#if (defined(_MSC_VER))
+    void consolelogger_log_with_GetLastError(const char* file, const char* func, int line, const char* format, ...);
+#endif
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* CONSOLELOGGER_H */
Index: azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/inc/azure_c_shared_utility/const_defines.h
===================================================================
--- azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/inc/azure_c_shared_utility/const_defines.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/inc/azure_c_shared_utility/const_defines.h	(revision 457)
@@ -0,0 +1,26 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+#ifndef CONST_DEFINES_H
+#define CONST_DEFINES_H
+
+// Used to remove GCC warning unused
+#ifdef __GNUC__
+    #define STATIC_VAR_UNUSED __attribute__ ((unused))
+#else
+    #define STATIC_VAR_UNUSED
+#endif
+
+#ifndef AZURE_UNREFERENCED_PARAMETER
+#define AZURE_UNREFERENCED_PARAMETER(param)   (void)(param)
+#endif
+
+#ifdef _MSC_VER
+#define AZURE_DEPRECATED __declspec(deprecated)
+#elif defined(__GNUC__) | defined(__clang__)
+#define AZURE_DEPRECATED __attribute__((__deprecated__))
+#else
+#define AZURE_DEPRECATED
+#endif
+
+#endif // CONST_DEFINES
Index: azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/inc/azure_c_shared_utility/constbuffer.h
===================================================================
--- azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/inc/azure_c_shared_utility/constbuffer.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/inc/azure_c_shared_utility/constbuffer.h	(revision 457)
@@ -0,0 +1,61 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+#ifndef CONSTBUFFER_H
+#define CONSTBUFFER_H
+
+#ifdef __cplusplus
+#include <cstddef>
+#else
+#include <stddef.h>
+#include <stdbool.h>
+#endif
+
+#include "azure_c_shared_utility/buffer_.h"
+
+#include "umock_c/umock_c_prod.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/*this is the handle*/
+typedef struct CONSTBUFFER_HANDLE_DATA_TAG* CONSTBUFFER_HANDLE;
+
+/*this is what is returned when the content of the buffer needs access*/
+typedef struct CONSTBUFFER_TAG
+{
+    const unsigned char* buffer;
+    size_t size;
+} CONSTBUFFER;
+
+typedef void(*CONSTBUFFER_CUSTOM_FREE_FUNC)(void* context);
+
+MOCKABLE_INTERFACE(constbuffer,
+    /*this creates a new constbuffer from a memory area*/
+    FUNCTION(, CONSTBUFFER_HANDLE, CONSTBUFFER_Create, const unsigned char*, source, size_t, size),
+
+    /*this creates a new constbuffer from an existing BUFFER_HANDLE*/
+    FUNCTION(, CONSTBUFFER_HANDLE, CONSTBUFFER_CreateFromBuffer, BUFFER_HANDLE, buffer),
+
+    FUNCTION(, CONSTBUFFER_HANDLE, CONSTBUFFER_CreateWithMoveMemory, unsigned char*, source, size_t, size),
+
+    FUNCTION(, CONSTBUFFER_HANDLE, CONSTBUFFER_CreateWithCustomFree, const unsigned char*, source, size_t, size, CONSTBUFFER_CUSTOM_FREE_FUNC, customFreeFunc, void*, customFreeFuncContext),
+
+    FUNCTION(, CONSTBUFFER_HANDLE, CONSTBUFFER_CreateFromOffsetAndSize, CONSTBUFFER_HANDLE, handle, size_t, offset, size_t, size),
+
+    FUNCTION(, void, CONSTBUFFER_IncRef, CONSTBUFFER_HANDLE, constbufferHandle),
+
+    FUNCTION(, void, CONSTBUFFER_DecRef, CONSTBUFFER_HANDLE, constbufferHandle),
+
+    FUNCTION(, const CONSTBUFFER*, CONSTBUFFER_GetContent, CONSTBUFFER_HANDLE, constbufferHandle),
+
+    FUNCTION(, bool, CONSTBUFFER_HANDLE_contain_same, CONSTBUFFER_HANDLE, left, CONSTBUFFER_HANDLE, right)
+)
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif  /* CONSTBUFFER_H */
Index: azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/inc/azure_c_shared_utility/constmap.h
===================================================================
--- azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/inc/azure_c_shared_utility/constmap.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/inc/azure_c_shared_utility/constmap.h	(revision 457)
@@ -0,0 +1,134 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+/** @file       constmap.h
+*    @brief        ConstMap is a module that implements a read-only dictionary
+*           of @c const char* keys to @c const char* values.
+*/
+
+#ifndef CONSTMAP_H
+#define CONSTMAP_H
+
+#ifdef __cplusplus
+#include <cstddef>
+#else
+#include <stddef.h>
+#endif
+
+#include "azure_macro_utils/macro_utils.h"
+#include "azure_c_shared_utility/crt_abstractions.h"
+#include "azure_c_shared_utility/map.h"
+#include "umock_c/umock_c_prod.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#define CONSTMAP_RESULT_VALUES \
+    CONSTMAP_OK, \
+    CONSTMAP_ERROR, \
+    CONSTMAP_INVALIDARG, \
+    CONSTMAP_KEYNOTFOUND
+
+/** @brief Enumeration specifying the status of calls to various APIs in this
+ *  module.
+ */
+MU_DEFINE_ENUM(CONSTMAP_RESULT, CONSTMAP_RESULT_VALUES);
+
+typedef struct CONSTMAP_HANDLE_DATA_TAG* CONSTMAP_HANDLE;
+
+
+/**
+ * @brief   Creates a new read-only map from a map handle.
+ *
+ * @param   sourceMap   The map from which we will populate key,value
+ *                      into the read-only map.
+ *
+ * @return  A valid @c CONSTMAP_HANDLE or @c NULL in case an error occurs.
+ */
+MOCKABLE_FUNCTION(, CONSTMAP_HANDLE, ConstMap_Create, MAP_HANDLE, sourceMap);
+
+ /**
+  * @brief  Destroy a read-only map.  Deallocate memory associated with handle.
+  * @param  handle      Handle to a read-only map.
+  */
+MOCKABLE_FUNCTION(, void, ConstMap_Destroy, CONSTMAP_HANDLE, handle);
+
+ /**
+  * @brief  Clone a read-only map from another read-only map.
+  * @param  handle      Handle to a read-only map.
+  * @return A valid @c CONSTMAP_HANDLE or @c NULL in case an error occurs.
+  */
+MOCKABLE_FUNCTION(, CONSTMAP_HANDLE, ConstMap_Clone, CONSTMAP_HANDLE, handle);
+
+ /**
+  * @brief  Create a map handle populated from the read-only map.
+  * @param  handle      Handle to a read-only map.
+  * @return A valid @c MAP_HANDLE or @c NULL in case an error occurs.
+  *
+  * The new MAP_HANDLE needs to be destroyed when it is no longer needed.
+  */
+MOCKABLE_FUNCTION(, MAP_HANDLE, ConstMap_CloneWriteable, CONSTMAP_HANDLE, handle);
+
+/**
+ * @brief   This function returns a true if the map contains a key
+ *            with the same value the parameter @p key.
+ *
+ * @param   handle      The handle to an existing map.
+ * @param   key         The key that the caller wants checked.
+ *
+ * @return                The function returns @c true if the key exists
+ *                        in the map and @c false if key is not found or
+ *                        parameters are invalid.
+ */
+MOCKABLE_FUNCTION(, bool, ConstMap_ContainsKey, CONSTMAP_HANDLE, handle, const char*, key);
+
+/**
+ * @brief   This function returns @c true if at least one <key,value> pair
+ *            exists in the map where the entry's value is equal to the
+ *            parameter @c value.
+ *
+ * @param   handle          The handle to an existing map.
+ * @param   value           The value that the caller wants checked.
+ *
+ * @return                    The function returns @c true if the value exists
+ *                            in the map and @c false if value is not found or
+ *                            parameters are invalid.
+ */
+MOCKABLE_FUNCTION(, bool, ConstMap_ContainsValue, CONSTMAP_HANDLE, handle, const char*, value);
+
+/**
+ * @brief   Retrieves the value of a stored key.
+ *
+ * @param   handle  The handle to an existing map.
+ * @param   key     The key to be looked up in the map.
+ *
+ * @return  Returns @c NULL in case the input arguments are @c NULL or if the
+ *          requested key is not found in the map. Returns a pointer to the
+ *          key's value otherwise.
+ */
+MOCKABLE_FUNCTION(, const char*, ConstMap_GetValue, CONSTMAP_HANDLE, handle, const char*, key);
+
+ /**
+ * @brief   Retrieves the complete list of keys and values from the map
+ *          in @p values and @p keys. Also writes the size of the list
+ *          in @p count.
+ *
+ * @param   handle      The handle to an existing map.
+ * @param   keys        The location where the list of keys is to be written.
+ * @param   values      The location where the list of values is to be written.
+ * @param   count       The number of stored keys and values is written at the
+ *                      location indicated by this pointer.
+ *
+ * @return  Returns @c CONSTMAP_OK if the keys and values are retrieved
+ *                     and written successfully or an error code otherwise.
+ */
+MOCKABLE_FUNCTION(, CONSTMAP_RESULT, ConstMap_GetInternals, CONSTMAP_HANDLE, handle, const char*const**, keys, const char*const**, values, size_t*, count);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* CONSTMAP_H */
Index: azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/inc/azure_c_shared_utility/crt_abstractions.h
===================================================================
--- azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/inc/azure_c_shared_utility/crt_abstractions.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/inc/azure_c_shared_utility/crt_abstractions.h	(revision 457)
@@ -0,0 +1,135 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+#ifndef CRT_ABSTRACTIONS_H
+#define CRT_ABSTRACTIONS_H
+
+#ifdef __cplusplus
+#include <cstdio>
+#include <cstring>
+#include <cerrno>
+#include <cmath>
+#else // __cplusplus
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#endif // __cplusplus
+
+#include "umock_c/umock_c_prod.h"
+
+#ifdef _MSC_VER
+
+#ifdef QUARKGALILEO
+#define HAS_STDBOOL
+#ifdef __cplusplus
+typedef bool _Bool;
+#else
+/*galileo apparently has _Bool and bool as built in types*/
+#endif
+#endif // QUARKGALILEO
+
+#define HAS_STDBOOL
+#ifdef __cplusplus
+/*because C++ doesn't do anything about _Bool... */
+#define _Bool bool
+#else // __cplusplus
+#include <stdbool.h>
+#endif // __cplusplus
+
+#else //  _MSC_VER
+
+#if defined __STDC_VERSION__
+#if ((__STDC_VERSION__  == 199901L) || (__STDC_VERSION__ == 201000L) || (__STDC_VERSION__ == 201112L) || (__STDC_VERSION__ == 201710L))
+/*C99, C11 (including GNU 4.6) or C18 compiler */
+#define HAS_STDBOOL
+#include <stdbool.h>
+#endif //  ((__STDC_VERSION__  == 199901L) || (__STDC_VERSION__ == 201000L) || (__STDC_VERSION__ == 201112L) || (__STDC_VERSION__ == 201710L))
+#endif // __STDC_VERSION__
+#endif //  _MSC_VER
+
+#ifdef __cplusplus
+extern "C" {
+#endif // __cplusplus
+
+#ifndef HAS_STDBOOL
+#ifdef __cplusplus
+#define _Bool bool
+#else // __cplusplus
+typedef unsigned char _Bool;
+typedef unsigned char bool;
+#define false 0
+#define true 1
+#endif // __cplusplus
+#endif // HAS_STDBOOL
+
+
+/* Codes_SRS_CRT_ABSTRACTIONS_99_001:[The module shall not redefine the secure functions implemented by Microsoft CRT.] */
+/* Codes_SRS_CRT_ABSTRACTIONS_99_040 : [The module shall still compile when building on a Microsoft platform.] */
+/* Codes_SRS_CRT_ABSTRACTIONS_99_002: [CRTAbstractions module shall expose the following API]*/
+#if defined (_MSC_VER) || defined (MINGW_HAS_SECURE_API)
+#else // _MSC_VER || MINGW_HAS_SECURE_API
+
+/* Adding definitions from errno.h & crtdefs.h */
+#if !defined (_TRUNCATE)
+#define _TRUNCATE ((size_t)-1)
+#endif  /* !defined (_TRUNCATE) */
+
+#if !defined STRUNCATE
+#define STRUNCATE       80
+#endif  /* !defined (STRUNCATE) */
+
+int strcpy_s(char* dst, size_t dstSizeInBytes, const char* src);
+int strcat_s(char* dst, size_t dstSizeInBytes, const char* src);
+int strncpy_s(char* dst, size_t dstSizeInBytes, const char* src, size_t maxCount);
+int sprintf_s(char* dst, size_t dstSizeInBytes, const char* format, ...);
+#endif // _MSC_VER || MINGW_HAS_SECURE_API
+
+unsigned long long strtoull_s(const char* nptr, char** endPtr, int base);
+float strtof_s(const char* nptr, char** endPtr);
+long double strtold_s(const char* nptr, char** endPtr);
+
+#ifdef _MSC_VER
+#define stricmp _stricmp
+#endif // _MSC_VER
+
+MOCKABLE_FUNCTION(, int, mallocAndStrcpy_s, char**, destination, const char*, source);
+MOCKABLE_FUNCTION(, int, unsignedIntToString, char*, destination, size_t, destinationSize, unsigned int, value);
+MOCKABLE_FUNCTION(, int, size_tToString, char*, destination, size_t, destinationSize, size_t, value);
+
+/*following logic shall define the TOUPPER and ISDIGIT, we do that because the SDK is not happy with some Arduino implementation of it.*/
+#define TOUPPER(c)      ((((c)>='a') && ((c)<='z'))?(c)-'a'+'A':c)
+#define ISDIGIT(c)      ((((c)>='0') && ((c)<='9'))?1:0)
+
+/*following logic shall define the ISNAN macro*/
+/*if runing on Microsoft Visual C compiler, than ISNAN shall be _isnan*/
+/*else if running on C99 or C11, ISNAN shall be isnan*/
+/*else if running on C89 ... #error and inform user*/
+
+#ifdef _MSC_VER
+#define ISNAN _isnan
+#else // _MSC_VER
+#if defined __STDC_VERSION__
+#if ((__STDC_VERSION__  == 199901L) || (__STDC_VERSION__ == 201000L) || (__STDC_VERSION__ == 201112L) || (__STDC_VERSION__ == 201710L))
+/*C99, C11 (including GNU 4.6) or C18 compiler */
+#define ISNAN isnan
+#else //  ((__STDC_VERSION__  == 199901L) || (__STDC_VERSION__ == 201000L) || (__STDC_VERSION__ == 201112L) || (__STDC_VERSION__ == 201710L))
+#error update this file to contain the latest C standard.
+#endif // ((__STDC_VERSION__  == 199901L) || (__STDC_VERSION__ == 201000L) || (__STDC_VERSION__ == 201112L) || (__STDC_VERSION__ == 201710L))
+#else // __STDC_VERSION__
+#ifdef __cplusplus
+/*C++ defines isnan... in C11*/
+extern "C++" {
+#define ISNAN std::isnan
+}
+#else // __cplusplus
+#error unknown (or C89) compiler, provide ISNAN with the same meaning as isnan in C99 standard
+#endif // __cplusplus
+
+#endif // __STDC_VERSION__
+#endif // _MSC_VER
+
+#ifdef __cplusplus
+}
+#endif // __cplusplus
+
+#endif /* CRT_ABSTRACTIONS_H */
Index: azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/inc/azure_c_shared_utility/dns_resolver.h
===================================================================
--- azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/inc/azure_c_shared_utility/dns_resolver.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/inc/azure_c_shared_utility/dns_resolver.h	(revision 457)
@@ -0,0 +1,72 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+/** @file ssl_socket.h
+ *    @brief     Implements socket creation for TLSIO adapters.
+ */
+
+#ifndef AZURE_IOT_DNS_H
+#define AZURE_IOT_DNS_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "azure_macro_utils/macro_utils.h"
+#include "umock_c/umock_c_prod.h"
+
+    typedef void* DNSRESOLVER_HANDLE;
+
+    // If options are added in future, DNSRESOLVER_OPTIONS will become a struct containing the options
+    typedef void DNSRESOLVER_OPTIONS;
+
+    /**
+    * @brief    Begin the process of an asynchronous DNS lookup.
+    *
+    * @param   hostname    The url of the host to look up.
+    *
+    * @return    @c The newly created DNSRESOLVER_HANDLE.
+    */
+    MOCKABLE_FUNCTION(, DNSRESOLVER_HANDLE, dns_resolver_create, const char*, hostname, int, port, const DNSRESOLVER_OPTIONS*, options);
+
+    /**
+    * @brief    Continue the lookup process and report its completion state. Must be polled repeatedly for completion.
+    *
+    * @param   dns    The DNSRESOLVER_HANDLE.
+    *
+    * @return    @c A bool to indicate completion.
+    */
+    MOCKABLE_FUNCTION(, bool, dns_resolver_is_lookup_complete, DNSRESOLVER_HANDLE, dns);
+
+    /**
+    * @brief    Return the IPv4 of a completed lookup process. Call only after dns_resolver_is_lookup_complete indicates completion.
+    *
+    * @param   dns    The DNSRESOLVER_HANDLE.
+    *
+    * @return    @c A uint32_t IPv4 address. 0 indicates failure or not finished.
+    */
+    MOCKABLE_FUNCTION(, uint32_t, dns_resolver_get_ipv4, DNSRESOLVER_HANDLE, dns);
+
+    /**
+    * @brief    Return the addrInfo of a completed lookup process. Call only after dns_resolver_is_lookup_complete indicates completion.
+    *
+    * @param   dns    The DNSRESOLVER_HANDLE.
+    *
+    * @return    @c A struct addrinfo. 0 indicates failure or not finished.
+    */
+    MOCKABLE_FUNCTION(, struct addrinfo*, dns_resolver_get_addrInfo, DNSRESOLVER_HANDLE, dns);
+    
+
+    /**
+    * @brief    Destroy the module.
+    *
+    * @param   dns    The DNSRESOLVER_HANDLE.
+    */
+    MOCKABLE_FUNCTION(, void, dns_resolver_destroy, DNSRESOLVER_HANDLE, dns);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* AZURE_IOT_DNS_H */
Index: azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/inc/azure_c_shared_utility/doublylinkedlist.h
===================================================================
--- azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/inc/azure_c_shared_utility/doublylinkedlist.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/inc/azure_c_shared_utility/doublylinkedlist.h	(revision 457)
@@ -0,0 +1,45 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+#ifndef DOUBLYLINKEDLIST_H
+#define DOUBLYLINKEDLIST_H
+
+#ifdef __cplusplus
+#include <cstddef>
+#else
+#include <stddef.h>
+#endif
+
+#include <stdint.h>
+#include "umock_c/umock_c_prod.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+typedef struct DLIST_ENTRY_TAG
+{
+    struct DLIST_ENTRY_TAG *Flink;
+    struct DLIST_ENTRY_TAG *Blink;
+} DLIST_ENTRY, *PDLIST_ENTRY;
+
+MOCKABLE_FUNCTION(, void, DList_InitializeListHead, PDLIST_ENTRY, listHead);
+MOCKABLE_FUNCTION(, int, DList_IsListEmpty, const PDLIST_ENTRY, listHead);
+MOCKABLE_FUNCTION(, void, DList_InsertTailList, PDLIST_ENTRY, listHead, PDLIST_ENTRY, listEntry);
+MOCKABLE_FUNCTION(, void, DList_InsertHeadList, PDLIST_ENTRY, listHead, PDLIST_ENTRY, listEntry);
+MOCKABLE_FUNCTION(, void, DList_AppendTailList, PDLIST_ENTRY, listHead, PDLIST_ENTRY, ListToAppend);
+MOCKABLE_FUNCTION(, int, DList_RemoveEntryList, PDLIST_ENTRY, listEntry);
+MOCKABLE_FUNCTION(, PDLIST_ENTRY, DList_RemoveHeadList, PDLIST_ENTRY, listHead);
+
+//
+// Calculate the address of the base of the structure given its type, and an
+// address of a field within the structure.
+//
+#define containingRecord(address, type, field) ((type *)((uintptr_t)(address) - offsetof(type,field)))
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* DOUBLYLINKEDLIST_H */
Index: azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/inc/azure_c_shared_utility/esp_at_socket.h
===================================================================
--- azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/inc/azure_c_shared_utility/esp_at_socket.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/inc/azure_c_shared_utility/esp_at_socket.h	(revision 457)
@@ -0,0 +1,26 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+#ifndef ESP_AT_SOCKET_H
+#define ESP_AT_SOCKET_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+	typedef void* ESP_AT_SOCKET_HANDLE;
+
+	ESP_AT_SOCKET_HANDLE esp_at_socket_create(bool ssl);
+	void esp_at_socket_set_blocking(ESP_AT_SOCKET_HANDLE espAtSocketHandle, bool blocking, unsigned int timeout);
+	void esp_at_socket_destroy(ESP_AT_SOCKET_HANDLE espAtSocketHandle);
+	int esp_at_socket_connect(ESP_AT_SOCKET_HANDLE espAtSocketHandle, const char* host, const int port);
+	bool esp_at_socket_is_connected(ESP_AT_SOCKET_HANDLE espAtSocketHandle);
+	void esp_at_socket_close(ESP_AT_SOCKET_HANDLE espAtSocketHandle);
+	int esp_at_socket_send(ESP_AT_SOCKET_HANDLE espAtSocketHandle, const char* data, int length);
+	int esp_at_socket_receive(ESP_AT_SOCKET_HANDLE espAtSocketHandle, char* data, int length);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* ESP_AT_SOCKET_H */
Index: azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/inc/azure_c_shared_utility/gb_rand.h
===================================================================
--- azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/inc/azure_c_shared_utility/gb_rand.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/inc/azure_c_shared_utility/gb_rand.h	(revision 457)
@@ -0,0 +1,19 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+#ifndef GB_RAND_H
+#define GB_RAND_H
+
+#include "umock_c/umock_c_prod.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+MOCKABLE_FUNCTION(, int, gb_rand);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* GB_RAND_H */
Index: azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/inc/azure_c_shared_utility/gb_stdio.h
===================================================================
--- azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/inc/azure_c_shared_utility/gb_stdio.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/inc/azure_c_shared_utility/gb_stdio.h	(revision 457)
@@ -0,0 +1,76 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+#ifndef GB_STDIO_H
+#define GB_STDIO_H
+
+/*this file, if included instead of <stdio.h> has the following functionality:
+1) if GB_STDIO_INTERCEPT is defined then
+    a) some of the stdio.h symbols shall be redefined, for example: fopen => gb_fopen
+    b) all "code" using the fopen will actually (because of the preprocessor) call to gb_fopen
+    c) gb_fopen shall blindly call into fopen, thus realizing a passthrough
+
+    reason is: unittesting. fopen is comes with the C Run Time and cannot be mocked (that is, in the global namespace cannot exist a function called fopen
+
+2) if GB_STDIO_INTERCEPT is not defined then
+    a) it shall include <stdio.h> => no passthrough, just direct linking.
+*/
+
+#ifndef GB_STDIO_INTERCEPT
+#ifdef __cplusplus
+#include <cstdio>
+#else
+#include <stdio.h>
+#endif
+#else
+
+/*source level intercepting of function calls*/
+#define fopen           fopen_never_called_never_implemented_always_forgotten
+#define fclose          fclose_never_called_never_implemented_always_forgotten
+#define fseek           fseek_never_called_never_implemented_always_forgotten
+#define ftell           ftell_never_called_never_implemented_always_forgotten
+#define fprintf         fprintf_never_called_never_implemented_always_forgotten
+
+#ifdef __cplusplus
+#include <cstdio>
+#else
+#include <stdio.h>
+#endif
+
+#include "umock_c/umock_c_prod.h"
+
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#undef fopen
+#define fopen gb_fopen
+MOCKABLE_FUNCTION(, FILE*, gb_fopen, const char*, filename, const char*, mode);
+
+
+#undef fclose
+#define fclose gb_fclose
+MOCKABLE_FUNCTION(, int, fclose, FILE *, stream);
+
+#undef fseek
+#define fseek gb_fseek
+MOCKABLE_FUNCTION(, int, fseek, FILE *,stream, long int, offset, int, whence);
+
+#undef ftell
+#define ftell gb_ftell
+MOCKABLE_FUNCTION(, long int, ftell, FILE *, stream);
+
+#undef fprintf
+#define fprintf gb_fprintf
+extern int fprintf(FILE * stream, const char * format, ...);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /*GB_STDIO_INTERCEPT*/
+
+#endif /* GB_STDIO_H */
Index: azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/inc/azure_c_shared_utility/gb_time.h
===================================================================
--- azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/inc/azure_c_shared_utility/gb_time.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/inc/azure_c_shared_utility/gb_time.h	(revision 457)
@@ -0,0 +1,64 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+#ifndef GB_TIME_H
+#define GB_TIME_H
+
+/*this file, if included instead of <stdio.h> has the following functionality:
+1) if GB_TIME_INTERCEPT is defined then
+    a) some of the time.h symbols shall be redefined, for example: time => gb_time
+    b) all "code" using the time will actually (because of the preprocessor) call to gb_time
+    c) gb_time shall blindly call into time, thus realizing a passthrough
+
+    reason is: unittesting. time comes with the C Run Time and cannot be mocked (that is, in the global namespace cannot exist a function called time
+
+2) if GB_TIME_INTERCEPT is not defined then
+    a) it shall include <time.h> => no passthrough, just direct linking.
+*/
+
+#ifndef GB_TIME_INTERCEPT
+#ifdef __cplusplus
+#include <ctime>
+#else
+#include <time.h>
+#endif
+#else
+
+/*source level intercepting of function calls*/
+#define time                    time_never_called_never_implemented_always_forgotten
+#define localtime               localtime_never_called_never_implemented_always_forgotten
+#define strftime                strftime_never_called_never_implemented_always_forgotten
+
+#ifdef __cplusplus
+#include <ctime>
+#else
+#include <time.h>
+#endif
+
+#include "umock_c/umock_c_prod.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#undef time
+#define time gb_time
+MOCKABLE_FUNCTION(, time_t, time, time_t *, timer);
+
+#undef localtime
+#define localtime gb_localtime
+MOCKABLE_FUNCTION(, struct tm *, localtime, const time_t *, timer);
+
+#undef strftime
+#define strftime gb_strftime
+MOCKABLE_FUNCTION(, size_t, strftime, char *, s, size_t, maxsize, const char *, format, const struct tm *, timeptr);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /*GB_TIME_INTERCEPT*/
+
+#endif /* GB_TIME_H */
Index: azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/inc/azure_c_shared_utility/gballoc.h
===================================================================
--- azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/inc/azure_c_shared_utility/gballoc.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/inc/azure_c_shared_utility/gballoc.h	(revision 457)
@@ -0,0 +1,87 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+#ifndef GBALLOC_H
+#define GBALLOC_H
+
+#ifdef __cplusplus
+#include <cstdlib>
+#else
+#include <stdlib.h>
+#endif
+
+#include "umock_c/umock_c_prod.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+// GB_USE_CUSTOM_HEAP disables the implementations in gballoc.c and
+// requires that an external library implement the gballoc_malloc family
+// declared here.
+#if defined(GB_USE_CUSTOM_HEAP)
+MOCKABLE_FUNCTION(, void*, gballoc_malloc, size_t, size);
+MOCKABLE_FUNCTION(, void*, gballoc_calloc, size_t, nmemb, size_t, size);
+MOCKABLE_FUNCTION(, void*, gballoc_realloc, void*, ptr, size_t, size);
+MOCKABLE_FUNCTION(, void, gballoc_free, void*, ptr);
+
+#define malloc gballoc_malloc
+#define calloc gballoc_calloc
+#define realloc gballoc_realloc
+#define free gballoc_free
+
+/* all translation units that need memory measurement need to have GB_MEASURE_MEMORY_FOR_THIS defined */
+/* GB_DEBUG_ALLOC is the switch that turns the measurement on/off, so that it is not on always */
+#elif defined(GB_DEBUG_ALLOC)
+
+MOCKABLE_FUNCTION(, int, gballoc_init);
+MOCKABLE_FUNCTION(, void, gballoc_deinit);
+MOCKABLE_FUNCTION(, void*, gballoc_malloc, size_t, size);
+MOCKABLE_FUNCTION(, void*, gballoc_calloc, size_t, nmemb, size_t, size);
+MOCKABLE_FUNCTION(, void*, gballoc_realloc, void*, ptr, size_t, size);
+MOCKABLE_FUNCTION(, void, gballoc_free, void*, ptr);
+
+MOCKABLE_FUNCTION(, size_t, gballoc_getMaximumMemoryUsed);
+MOCKABLE_FUNCTION(, size_t, gballoc_getCurrentMemoryUsed);
+MOCKABLE_FUNCTION(, size_t, gballoc_getAllocationCount);
+MOCKABLE_FUNCTION(, void, gballoc_resetMetrics);
+
+/* if GB_MEASURE_MEMORY_FOR_THIS is defined then we want to redirect memory allocation functions to gballoc_xxx functions */
+#ifdef GB_MEASURE_MEMORY_FOR_THIS
+/* Unfortunately this is still needed here for things to still compile when using _CRTDBG_MAP_ALLOC.
+That is because there is a rogue component (most likely CppUnitTest) including crtdbg. */
+#if defined(_CRTDBG_MAP_ALLOC) && defined(_DEBUG)
+#undef _malloc_dbg
+#undef _calloc_dbg
+#undef _realloc_dbg
+#undef _free_dbg
+#define _malloc_dbg(size, ...) gballoc_malloc(size)
+#define _calloc_dbg(nmemb, size, ...) gballoc_calloc(nmemb, size)
+#define _realloc_dbg(ptr, size, ...) gballoc_realloc(ptr, size)
+#define _free_dbg(ptr, ...) gballoc_free(ptr)
+#else
+#define malloc gballoc_malloc
+#define calloc gballoc_calloc
+#define realloc gballoc_realloc
+#define free gballoc_free
+#endif
+#endif
+
+#else /* GB_DEBUG_ALLOC */
+
+#define gballoc_init() 0
+#define gballoc_deinit() ((void)0)
+
+#define gballoc_getMaximumMemoryUsed() SIZE_MAX
+#define gballoc_getCurrentMemoryUsed() SIZE_MAX
+#define gballoc_getAllocationCount() SIZE_MAX
+#define gballoc_resetMetrics() ((void)0)
+
+#endif /* GB_DEBUG_ALLOC */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* GBALLOC_H */
Index: azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/inc/azure_c_shared_utility/gbnetwork.h
===================================================================
--- azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/inc/azure_c_shared_utility/gbnetwork.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/inc/azure_c_shared_utility/gbnetwork.h	(revision 457)
@@ -0,0 +1,75 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+#ifndef GBNETWORK_H
+#define GBNETWORK_H
+
+#ifdef __cplusplus
+#include <cstdlib>
+#include <cstdint>
+#else
+#include <stdlib.h>
+#include <stdint.h>
+#endif
+
+#include "umock_c/umock_c_prod.h"
+
+#ifdef WIN32
+    #include <winsock2.h>
+#else
+    #include <sys/socket.h>
+#endif
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/* all translation units that need network measurement need to have GB_MEASURE_NETWORK_FOR_THIS defined */
+/* GB_DEBUG_NETWORK is the switch that turns the measurement on/off, so that it is not on always */
+#if defined(GB_DEBUG_NETWORK)
+
+MOCKABLE_FUNCTION(, int, gbnetwork_init);
+MOCKABLE_FUNCTION(, void, gbnetwork_deinit);
+
+#ifdef WIN32
+MOCKABLE_FUNCTION(, int, gbnetwork_send, SOCKET, sock, const char*, buf, int, len, int, flags);
+#else
+MOCKABLE_FUNCTION(, ssize_t, gbnetwork_send, int, sock, const void*, buf, size_t, len, int, flags);
+#endif
+
+#ifdef WIN32
+MOCKABLE_FUNCTION(, int, gbnetwork_recv, SOCKET, sock, char*, buf, int, len, int, flags);
+#else
+MOCKABLE_FUNCTION(, ssize_t, gbnetwork_recv, int, sock, void*, buf, size_t, len, int, flags);
+#endif
+
+MOCKABLE_FUNCTION(, uint64_t, gbnetwork_getBytesSent);
+MOCKABLE_FUNCTION(, uint64_t, gbnetwork_getNumSends);
+MOCKABLE_FUNCTION(, uint64_t, gbnetwork_getBytesRecv);
+MOCKABLE_FUNCTION(, uint64_t, gbnetwork_getNumRecv);
+MOCKABLE_FUNCTION(, void, gbnetwork_resetMetrics);
+
+/* if GB_MEASURE_NETWORK_FOR_THIS is defined then we want to redirect network send functions to gbnetwork_xxx functions */
+#ifdef GB_MEASURE_NETWORK_FOR_THIS
+#define send gbnetwork_send
+#define recv gbnetwork_recv
+#endif
+
+#else /* GB_DEBUG_NETWORK */
+
+#define gbnetwork_init() 0
+#define gbnetwork_deinit() ((void)0)
+#define gbnetwork_getBytesSent() 0
+#define gbnetwork_getNumSends() 0
+
+#define gbnetwork_getBytesRecv() 0
+#define gbnetwork_getNumRecv() 0
+
+#endif /* GB_DEBUG_NETWORK */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* GBNETWORK_H */
Index: azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/inc/azure_c_shared_utility/hmac.h
===================================================================
--- azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/inc/azure_c_shared_utility/hmac.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/inc/azure_c_shared_utility/hmac.h	(revision 457)
@@ -0,0 +1,28 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+#ifndef HMAC_H
+#define HMAC_H
+
+#ifdef __cplusplus
+#include <cstdint>
+#else
+#include <stdint.h>
+#endif
+
+#include "azure_c_shared_utility/sha.h"
+#include "umock_c/umock_c_prod.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+    MOCKABLE_FUNCTION(, int, hmac, SHAversion, whichSha, const unsigned char *, text, int, text_len,
+    const unsigned char *, key, int, key_len,
+    uint8_t, digest[USHAMaxHashSize]);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* HMAC_H */
Index: azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/inc/azure_c_shared_utility/hmacsha256.h
===================================================================
--- azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/inc/azure_c_shared_utility/hmacsha256.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/inc/azure_c_shared_utility/hmacsha256.h	(revision 457)
@@ -0,0 +1,34 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+#ifndef HMACSHA256_H
+#define HMACSHA256_H
+
+#ifdef __cplusplus
+#include <cstddef>
+#else
+#include <stddef.h>
+#endif
+
+#include "azure_macro_utils/macro_utils.h"
+#include "azure_c_shared_utility/buffer_.h"
+#include "umock_c/umock_c_prod.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define HMACSHA256_RESULT_VALUES              \
+    HMACSHA256_OK,                            \
+    HMACSHA256_INVALID_ARG,                   \
+    HMACSHA256_ERROR
+
+MU_DEFINE_ENUM(HMACSHA256_RESULT, HMACSHA256_RESULT_VALUES)
+
+MOCKABLE_FUNCTION(, HMACSHA256_RESULT, HMACSHA256_ComputeHash, const unsigned char*, key, size_t, keyLen, const unsigned char*, payload, size_t, payloadLen, BUFFER_HANDLE, hash);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* HMACSHA256_H */
Index: azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/inc/azure_c_shared_utility/http_proxy_io.h
===================================================================
--- azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/inc/azure_c_shared_utility/http_proxy_io.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/inc/azure_c_shared_utility/http_proxy_io.h	(revision 457)
@@ -0,0 +1,30 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+#ifndef HTTP_PROXY_IO_H
+#define HTTP_PROXY_IO_H
+
+#include "azure_c_shared_utility/xio.h"
+#include "umock_c/umock_c_prod.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+typedef struct HTTP_PROXY_IO_CONFIG_TAG
+{
+    const char* hostname;
+    int port;
+    const char* proxy_hostname;
+    int proxy_port;
+    const char* username;
+    const char* password;
+} HTTP_PROXY_IO_CONFIG;
+
+MOCKABLE_FUNCTION(, const IO_INTERFACE_DESCRIPTION*, http_proxy_io_get_interface_description);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* HTTP_PROXY_IO_H */
Index: azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/inc/azure_c_shared_utility/httpapi.h
===================================================================
--- azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/inc/azure_c_shared_utility/httpapi.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/inc/azure_c_shared_utility/httpapi.h	(revision 457)
@@ -0,0 +1,205 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+/** @file httpapi.h
+ *    @brief     This module implements the standard HTTP API used by the C IoT client
+ *             library.
+ *
+ *    @details For example, on the Windows platform the HTTP API code uses
+ *             WinHTTP and for Linux it uses curl and so forth. HTTPAPI must support
+ *             HTTPs (HTTP+SSL).
+ */
+
+#ifndef HTTPAPI_H
+#define HTTPAPI_H
+
+#ifdef __cplusplus
+#include <cstddef>
+#else
+#include <stddef.h>
+#endif
+
+#include "azure_macro_utils/macro_utils.h"
+#include "azure_c_shared_utility/httpheaders.h"
+#include "azure_c_shared_utility/buffer_.h"
+#include "umock_c/umock_c_prod.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct HTTP_HANDLE_DATA_TAG* HTTP_HANDLE;
+
+#define AMBIGUOUS_STATUS_CODE           (300)
+
+#define HTTPAPI_RESULT_VALUES                \
+HTTPAPI_OK,                                  \
+HTTPAPI_INVALID_ARG,                         \
+HTTPAPI_ERROR,                               \
+HTTPAPI_OPEN_REQUEST_FAILED,                 \
+HTTPAPI_SET_OPTION_FAILED,                   \
+HTTPAPI_SEND_REQUEST_FAILED,                 \
+HTTPAPI_RECEIVE_RESPONSE_FAILED,             \
+HTTPAPI_QUERY_HEADERS_FAILED,                \
+HTTPAPI_QUERY_DATA_AVAILABLE_FAILED,         \
+HTTPAPI_READ_DATA_FAILED,                    \
+HTTPAPI_ALREADY_INIT,                        \
+HTTPAPI_NOT_INIT,                            \
+HTTPAPI_HTTP_HEADERS_FAILED,                 \
+HTTPAPI_STRING_PROCESSING_ERROR,             \
+HTTPAPI_ALLOC_FAILED,                        \
+HTTPAPI_INIT_FAILED,                         \
+HTTPAPI_INSUFFICIENT_RESPONSE_BUFFER,        \
+HTTPAPI_SET_X509_FAILURE,                    \
+HTTPAPI_SET_TIMEOUTS_FAILED                  \
+
+/** @brief Enumeration specifying the possible return values for the APIs in
+ *           this module.
+ */
+MU_DEFINE_ENUM(HTTPAPI_RESULT, HTTPAPI_RESULT_VALUES);
+
+#define HTTPAPI_REQUEST_TYPE_VALUES\
+    HTTPAPI_REQUEST_GET,            \
+    HTTPAPI_REQUEST_POST,           \
+    HTTPAPI_REQUEST_PUT,            \
+    HTTPAPI_REQUEST_DELETE,         \
+    HTTPAPI_REQUEST_PATCH,          \
+    HTTPAPI_REQUEST_HEAD            \
+
+
+/** @brief Enumeration specifying the HTTP request verbs accepted by
+ *    the HTTPAPI module.
+ */
+MU_DEFINE_ENUM(HTTPAPI_REQUEST_TYPE, HTTPAPI_REQUEST_TYPE_VALUES);
+
+#define MAX_HOSTNAME_LEN        65
+#define MAX_USERNAME_LEN        65
+#define MAX_PASSWORD_LEN        65
+
+/**
+ * @brief    Global initialization for the HTTP API component.
+ *
+ *            Platform specific implementations are expected to initialize
+ *            the underlying HTTP API stacks.
+ *
+ * @return    @c HTTPAPI_OK if initialization is successful or an error
+ *             code in case it fails.
+ */
+MOCKABLE_FUNCTION(, HTTPAPI_RESULT, HTTPAPI_Init);
+
+/** @brief    Free resources allocated in ::HTTPAPI_Init. */
+MOCKABLE_FUNCTION(, void, HTTPAPI_Deinit);
+
+/**
+ * @brief    Creates an HTTPS connection to the host specified by the @p
+ *             hostName parameter.
+ *
+ * @param    hostName    Name of the host.
+ *
+ *            This function returns a handle to the newly created connection.
+ *            You can use the handle in subsequent calls to execute specific
+ *            HTTP calls using ::HTTPAPI_ExecuteRequest.
+ *
+ * @return    A @c HTTP_HANDLE to the newly created connection or @c NULL in
+ *             case an error occurs.
+ */
+MOCKABLE_FUNCTION(, HTTP_HANDLE, HTTPAPI_CreateConnection, const char*, hostName);
+
+/**
+ * @brief    Closes a connection created with ::HTTPAPI_CreateConnection.
+ *
+ * @param    handle    The handle to the HTTP connection created via ::HTTPAPI_CreateConnection.
+ *
+ *             All resources allocated by ::HTTPAPI_CreateConnection should be
+ *             freed in ::HTTPAPI_CloseConnection.
+ */
+MOCKABLE_FUNCTION(, void, HTTPAPI_CloseConnection, HTTP_HANDLE, handle);
+
+/**
+ * @brief    Sends the HTTP request to the host and handles the response for
+ *             the HTTP call.
+ *
+ * @param    handle                     The handle to the HTTP connection created
+ *                                     via ::HTTPAPI_CreateConnection.
+ * @param    requestType                 Specifies which HTTP method is used (GET,
+ *                                     POST, DELETE, PUT, PATCH).
+ * @param    relativePath             Specifies the relative path of the URL
+ *                                     excluding the host name.
+ * @param    httpHeadersHandle         Specifies a set of HTTP headers (name-value
+ *                                     pairs) to be added to the
+ *                                     HTTP request. The @p httpHeadersHandle
+ *                                     handle can be created and setup with
+ *                                     the proper name-value pairs by using the
+ *                                     HTTPHeaders APIs available in @c
+ *                                     HTTPHeaders.h.
+ * @param    content                     Specifies a pointer to the request body.
+ *                                     This value is optional and can be @c NULL.
+ * @param    contentLength             Specifies the request body size (this is
+ *                                     typically added into the HTTP headers as
+ *                                     the Content-Length header). This value is
+ *                                     optional and can be 0.
+ * @param   statusCode               This is an out parameter, where
+ *                                     ::HTTPAPI_ExecuteRequest returns the status
+ *                                     code from the HTTP response (200, 201, 400,
+ *                                     401, etc.)
+ * @param    responseHeadersHandle    This is an HTTP headers handle to which
+ *                                     ::HTTPAPI_ExecuteRequest must add all the
+ *                                     HTTP response headers so that the caller of
+ *                                     ::HTTPAPI_ExecuteRequest can inspect them.
+ *                                     You can manipulate @p responseHeadersHandle
+ *                                     by using the HTTPHeaders APIs available in
+ *                                     @c HTTPHeaders.h
+ * @param    responseContent             This is a buffer that must be filled by
+ *                                     ::HTTPAPI_ExecuteRequest with the contents
+ *                                     of the HTTP response body. The buffer size
+ *                                     must be increased by the
+ *                                     ::HTTPAPI_ExecuteRequest implementation in
+ *                                     order to fit the response body.
+ *                                     ::HTTPAPI_ExecuteRequest must also handle
+ *                                     chunked transfer encoding for HTTP responses.
+ *                                     To manipulate the @p responseContent buffer,
+ *                                     use the APIs available in @c Strings.h.
+ *
+ * @return    @c HTTPAPI_OK if the API call is successful or an error
+ *             code in case it fails.
+ */
+MOCKABLE_FUNCTION(, HTTPAPI_RESULT, HTTPAPI_ExecuteRequest, HTTP_HANDLE, handle, HTTPAPI_REQUEST_TYPE, requestType, const char*, relativePath,
+                                             HTTP_HEADERS_HANDLE, httpHeadersHandle, const unsigned char*, content,
+                                             size_t, contentLength, unsigned int*, statusCode,
+                                             HTTP_HEADERS_HANDLE, responseHeadersHandle, BUFFER_HANDLE, responseContent);
+
+/**
+ * @brief    Sets the option named @p optionName bearing the value
+ *             @p value for the HTTP_HANDLE @p handle.
+ *
+ * @param    handle          The handle to the HTTP connection created via
+ *                         ::HTTPAPI_CreateConnection.
+ * @param    optionName    A @c NULL terminated string representing the name
+ *                         of the option.
+ * @param    value          A pointer to the value for the option.
+ *
+ * @return    @c HTTPAPI_OK if initialization is successful or an error
+ *             code in case it fails.
+ */
+MOCKABLE_FUNCTION(, HTTPAPI_RESULT, HTTPAPI_SetOption, HTTP_HANDLE, handle, const char*, optionName, const void*, value);
+
+/**
+ * @brief    Clones the option named @p optionName bearing the value @p value
+ *             into the pointer @p savedValue.
+ *
+ * @param    optionName    A @c NULL terminated string representing the name of
+ *                         the option
+ * @param    value          A pointer to the value of the option.
+ * @param    savedValue    This pointer receives the copy of the value of the
+ *                         option. The copy needs to be free-able.
+ *
+ * @return    @c HTTPAPI_OK if initialization is successful or an error
+ *             code in case it fails.
+ */
+MOCKABLE_FUNCTION(, HTTPAPI_RESULT, HTTPAPI_CloneOption, const char*, optionName, const void*, value, const void**, savedValue);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* HTTPAPI_H */
Index: azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/inc/azure_c_shared_utility/httpapiex.h
===================================================================
--- azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/inc/azure_c_shared_utility/httpapiex.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/inc/azure_c_shared_utility/httpapiex.h	(revision 457)
@@ -0,0 +1,128 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+/** @file httpapiex.h
+*    @brief        This is a utility module that provides HTTP requests with
+*                build-in retry capabilities.
+*
+*    @details    HTTAPIEX is a utility module that provides HTTP requests with build-in
+*                retry capability to an HTTP server. Features over "regular" HTTPAPI include:
+*                    - Optional parameters
+*                    - Implementation independent
+*                    - Retry mechanism
+*                    - Persistent options
+*/
+
+#ifndef HTTPAPIEX_H
+#define HTTPAPIEX_H
+
+#ifdef __cplusplus
+#include <cstddef>
+#else
+#include <stddef.h>
+#endif
+
+#include "azure_macro_utils/macro_utils.h"
+#include "azure_c_shared_utility/httpapi.h"
+#include "umock_c/umock_c_prod.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct HTTPAPIEX_HANDLE_DATA_TAG* HTTPAPIEX_HANDLE;
+
+#define HTTPAPIEX_RESULT_VALUES \
+    HTTPAPIEX_OK, \
+    HTTPAPIEX_ERROR, \
+    HTTPAPIEX_INVALID_ARG, \
+    HTTPAPIEX_RECOVERYFAILED
+/*to be continued*/
+
+/** @brief Enumeration specifying the status of calls to various APIs in this module.
+*/
+MU_DEFINE_ENUM(HTTPAPIEX_RESULT, HTTPAPIEX_RESULT_VALUES);
+
+/**
+ * @brief    Initialize the HTTPAPIEX.
+ *
+ *  This API shall be called only once before call any other HTTPAPIEX API. 
+ *  **This API is NOT thread safe**.
+ *
+ * @return    An @c HTTPAPIEX_RESULT indicating the status of the call.
+ */
+MOCKABLE_FUNCTION(, HTTPAPIEX_RESULT, HTTPAPIEX_Init);
+
+/**
+ * @brief    Deinitialize the HTTPAPIEX.
+ *
+ *  This API shall be called only once to release all HTTP resources. No other HTTPAPIEX 
+ *      API shall be called after call this API.
+ *  **This API is NOT thread safe**.
+ */
+MOCKABLE_FUNCTION(, void, HTTPAPIEX_Deinit);
+
+/**
+ * @brief    Creates an @c HTTPAPIEX_HANDLE that can be used in further calls.
+ *
+ * @param    hostName    Pointer to a null-terminated string that contains the host name
+ *                         of an HTTP server.
+ *
+ *            If @p hostName is @c NULL then @c HTTPAPIEX_Create returns @c NULL. The @p
+ *            hostName value is saved and associated with the returned handle. If creating
+ *            the handle fails for any reason, then @c HTTAPIEX_Create returns @c NULL.
+ *            Otherwise, @c HTTPAPIEX_Create returns an @c HTTAPIEX_HANDLE suitable for
+ *            further calls to the module.
+ *
+ * @return    An @c HTTAPIEX_HANDLE suitable for further calls to the module.
+ */
+MOCKABLE_FUNCTION(, HTTPAPIEX_HANDLE, HTTPAPIEX_Create, const char*, hostName);
+
+/**
+ * @brief    Tries to execute an HTTP request.
+ *
+ * @param    handle                         A valid @c HTTPAPIEX_HANDLE value.
+ * @param    requestType                     A value from the ::HTTPAPI_REQUEST_TYPE enum.
+ * @param    relativePath                 Relative path to send the request to on the server.
+ * @param    requestHttpHeadersHandle     Handle to the request HTTP headers.
+ * @param    requestContent                 The request content.
+ * @param     statusCode                     If non-null, the HTTP status code is written to this
+ *                                         pointer.
+ * @param    responseHttpHeadersHandle    Handle to the response HTTP headers.
+ * @param    responseContent                 The response content.
+ *
+ *             @c HTTPAPIEX_ExecuteRequest tries to execute an HTTP request of type @p
+ *             requestType, on the server's @p relativePath, pushing the request HTTP
+ *             headers @p requestHttpHeadersHandle, having the content of the request
+ *             as pointed to by @p requestContent. If successful,  @c HTTAPIEX_ExecuteRequest
+ *             writes in the out @p parameter statusCode the HTTP status, populates the @p
+ *             responseHeadersHandle with the response headers and copies the response body
+ *             to @p responseContent.
+ *
+ * @return    An @c HTTAPIEX_HANDLE suitable for further calls to the module.
+ */
+MOCKABLE_FUNCTION(, HTTPAPIEX_RESULT, HTTPAPIEX_ExecuteRequest, HTTPAPIEX_HANDLE, handle, HTTPAPI_REQUEST_TYPE, requestType, const char*, relativePath, HTTP_HEADERS_HANDLE, requestHttpHeadersHandle, BUFFER_HANDLE, requestContent, unsigned int*, statusCode, HTTP_HEADERS_HANDLE, responseHttpHeadersHandle, BUFFER_HANDLE, responseContent);
+
+/**
+ * @brief    Frees all resources used by the @c HTTPAPIEX_HANDLE object.
+ *
+ * @param    handle    The @c HTTPAPIEX_HANDLE object to be freed.
+ */
+MOCKABLE_FUNCTION(, void, HTTPAPIEX_Destroy, HTTPAPIEX_HANDLE, handle);
+
+/**
+ * @brief    Sets the option @p optionName to the value pointed to by @p value.
+ *
+ * @param    handle          The @c HTTPAPIEX_HANDLE representing this session.
+ * @param    optionName    Name of the option.
+ * @param    value          The value to be set for the option.
+ *
+ * @return    An @c HTTPAPIEX_RESULT indicating the status of the call.
+ */
+MOCKABLE_FUNCTION(, HTTPAPIEX_RESULT, HTTPAPIEX_SetOption, HTTPAPIEX_HANDLE, handle, const char*, optionName, const void*, value);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* HTTPAPIEX_H */
Index: azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/inc/azure_c_shared_utility/httpapiexsas.h
===================================================================
--- azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/inc/azure_c_shared_utility/httpapiexsas.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/inc/azure_c_shared_utility/httpapiexsas.h	(revision 457)
@@ -0,0 +1,31 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+#ifndef HTTPAPIEX_SAS_H
+#define HTTPAPIEX_SAS_H
+
+#include "azure_c_shared_utility/strings.h"
+#include "azure_c_shared_utility/buffer_.h"
+#include "azure_c_shared_utility/httpheaders.h"
+#include "azure_c_shared_utility/httpapiex.h"
+#include "umock_c/umock_c_prod.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+    
+typedef struct HTTPAPIEX_SAS_STATE_TAG* HTTPAPIEX_SAS_HANDLE;
+
+MOCKABLE_FUNCTION(, HTTPAPIEX_SAS_HANDLE, HTTPAPIEX_SAS_Create, STRING_HANDLE, key, STRING_HANDLE, uriResource, STRING_HANDLE, keyName);
+
+MOCKABLE_FUNCTION(, HTTPAPIEX_SAS_HANDLE, HTTPAPIEX_SAS_Create_From_String, const char*, key, const char*, uriResource, const char*, keyName);
+
+MOCKABLE_FUNCTION(, void, HTTPAPIEX_SAS_Destroy, HTTPAPIEX_SAS_HANDLE, handle);
+
+MOCKABLE_FUNCTION(, HTTPAPIEX_RESULT, HTTPAPIEX_SAS_ExecuteRequest, HTTPAPIEX_SAS_HANDLE, sasHandle, HTTPAPIEX_HANDLE, handle, HTTPAPI_REQUEST_TYPE, requestType, const char*, relativePath, HTTP_HEADERS_HANDLE, requestHttpHeadersHandle, BUFFER_HANDLE, requestContent, unsigned int*, statusCode, HTTP_HEADERS_HANDLE, responseHeadersHandle, BUFFER_HANDLE, responseContent);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* HTTPAPIEX_SAS_H */
Index: azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/inc/azure_c_shared_utility/httpheaders.h
===================================================================
--- azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/inc/azure_c_shared_utility/httpheaders.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/inc/azure_c_shared_utility/httpheaders.h	(revision 457)
@@ -0,0 +1,161 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+/** @file httpheaders.h
+*    @brief This is a utility module that handles HTTP message-headers.
+*
+*    @details An application would use ::HTTPHeaders_Alloc to create a new set of HTTP headers.
+*             After getting the handle, the application would build in several headers by
+*             consecutive calls to ::HTTPHeaders_AddHeaderNameValuePair. When the headers are
+*             constructed, the application can retrieve the stored data by calling one of the
+*             following functions:
+*                - ::HTTPHeaders_FindHeaderValue - when the name of the header is known and it
+*                  wants to know the value of that header
+*                - ::HTTPHeaders_GetHeaderCount - when the application needs to know the count
+*                  of all the headers
+*                - ::HTTPHeaders_GetHeader - when the application needs to retrieve the
+*                  <code>name + ": " + value</code> string based on an index.
+*/
+
+#ifndef HTTPHEADERS_H
+#define HTTPHEADERS_H
+
+#ifdef __cplusplus
+#include <cstddef>
+#else
+#include <stddef.h>
+#endif
+
+#include "azure_macro_utils/macro_utils.h"
+#include "umock_c/umock_c_prod.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*Codes_SRS_HTTP_HEADERS_99_001:[ HttpHeaders shall have the following interface]*/
+
+#define HTTP_HEADERS_RESULT_VALUES \
+HTTP_HEADERS_OK,                  \
+HTTP_HEADERS_INVALID_ARG,         \
+HTTP_HEADERS_ALLOC_FAILED,        \
+HTTP_HEADERS_INSUFFICIENT_BUFFER, \
+HTTP_HEADERS_ERROR                \
+
+/** @brief Enumeration specifying the status of calls to various APIs in this module.
+*/
+MU_DEFINE_ENUM(HTTP_HEADERS_RESULT, HTTP_HEADERS_RESULT_VALUES);
+typedef struct HTTP_HEADERS_HANDLE_DATA_TAG* HTTP_HEADERS_HANDLE;
+
+/**
+ * @brief    Produces a @c HTTP_HANDLE that can later be used in subsequent calls to the module.
+ *
+ *            This function returns @c NULL in case an error occurs. After successful execution
+ *            ::HTTPHeaders_GetHeaderCount will report @c 0 existing headers.
+ *
+ * @return    A HTTP_HEADERS_HANDLE representing the newly created collection of HTTP headers.
+ */
+MOCKABLE_FUNCTION(, HTTP_HEADERS_HANDLE, HTTPHeaders_Alloc);
+
+/**
+ * @brief    De-allocates the data structures allocated by previous API calls to the same handle.
+ *
+ * @param    httpHeadersHandle    A valid @c HTTP_HEADERS_HANDLE value.
+ */
+MOCKABLE_FUNCTION(, void, HTTPHeaders_Free, HTTP_HEADERS_HANDLE, httpHeadersHandle);
+
+/**
+ * @brief    Adds a header record from the @p name and @p value parameters.
+ *
+ * @param    httpHeadersHandle    A valid @c HTTP_HEADERS_HANDLE value.
+ * @param    name                 The name of the HTTP header to add. It is invalid for
+ *                                 the name to include the ':' character or character codes
+ *                                 outside the range 33-126.
+ * @param    value                 The value to be assigned to the header.
+ *
+ *            The function stores the @c name:value pair in such a way that when later
+ *            retrieved by a call to ::HTTPHeaders_GetHeader it will return a string
+ *            that is @c strcmp equal to @c name+": "+value. If the name already exists
+ *            in the collection of headers, the function concatenates the new value
+ *            after the existing value, separated by a comma and a space as in:
+ *            <code>old-value+", "+new-value</code>.
+ *
+ * @return    Returns @c HTTP_HEADERS_OK when execution is successful or an error code from
+ *             the ::HTTPAPIEX_RESULT enum.
+ */
+MOCKABLE_FUNCTION(, HTTP_HEADERS_RESULT, HTTPHeaders_AddHeaderNameValuePair, HTTP_HEADERS_HANDLE, httpHeadersHandle, const char*, name, const char*, value);
+
+/**
+ * @brief    This API performs exactly the same as ::HTTPHeaders_AddHeaderNameValuePair
+ *             except that if the header name already exists then the already existing value
+ *             will be replaced as opposed to being concatenated to.
+ *
+ * @param    httpHeadersHandle    A valid @c HTTP_HEADERS_HANDLE value.
+ * @param    name                 The name of the HTTP header to add/replace. It is invalid for
+ *                                 the name to include the ':' character or character codes
+ *                                 outside the range 33-126.
+ * @param    value                 The value to be assigned to the header.
+ *
+ * @return    Returns @c HTTP_HEADERS_OK when execution is successful or an error code from
+ *             the ::HTTPAPIEX_RESULT enum.
+ */
+MOCKABLE_FUNCTION(, HTTP_HEADERS_RESULT, HTTPHeaders_ReplaceHeaderNameValuePair, HTTP_HEADERS_HANDLE, httpHeadersHandle, const char*, name, const char*, value);
+
+/**
+ * @brief    Retrieves the value for a previously stored name.
+ *
+ * @param    httpHeadersHandle    A valid @c HTTP_HEADERS_HANDLE value.
+ * @param    name                 The name of the HTTP header to find.
+ *
+ * @return    The return value points to a string that shall be @c strcmp equal
+ *             to the original stored string.
+ */
+MOCKABLE_FUNCTION(, const char*, HTTPHeaders_FindHeaderValue, HTTP_HEADERS_HANDLE, httpHeadersHandle, const char*, name);
+
+/**
+ * @brief    This API retrieves the number of stored headers.
+ *
+ * @param    httpHeadersHandle    A valid @c HTTP_HEADERS_HANDLE value.
+ * @param    headersCount        If non-null, the API writes the number of
+ *                                 into the memory pointed at by this parameter.
+ *
+ * @return    Returns @c HTTP_HEADERS_OK when execution is successful or
+ *             @c HTTP_HEADERS_ERROR when an error occurs.
+ */
+MOCKABLE_FUNCTION(, HTTP_HEADERS_RESULT, HTTPHeaders_GetHeaderCount, HTTP_HEADERS_HANDLE, httpHeadersHandle, size_t*, headersCount);
+
+/**
+ * @brief    This API retrieves the string name+": "+value for the header
+ *             element at the given @p index.
+ *
+ * @param    handle            A valid @c HTTP_HEADERS_HANDLE value.
+ * @param    index            Zero-based index of the item in the
+ *                             headers collection.
+ * @param   destination        If non-null, the header value is written into a
+ *                             new string a pointer to which is written into this
+ *                             parameters. It is the caller's responsibility to free
+ *                             this memory.
+ *
+ * @return    Returns @c HTTP_HEADERS_OK when execution is successful or
+ *             @c HTTP_HEADERS_ERROR when an error occurs.
+ */
+MOCKABLE_FUNCTION(, HTTP_HEADERS_RESULT, HTTPHeaders_GetHeader, HTTP_HEADERS_HANDLE, handle, size_t, index, char**, destination);
+
+/**
+ * @brief    This API produces a clone of the @p handle parameter.
+ *
+ * @param   handle  A valid @c HTTP_HEADERS_HANDLE value.
+ *
+ *            If @p handle is not @c NULL this function clones the content
+ *            of the handle to a new handle and returns it.
+ *
+ * @return    A @c HTTP_HEADERS_HANDLE containing a cloned copy of the
+ *             contents of @p handle.
+ */
+MOCKABLE_FUNCTION(, HTTP_HEADERS_HANDLE, HTTPHeaders_Clone, HTTP_HEADERS_HANDLE, handle);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* HTTPHEADERS_H */
Index: azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/inc/azure_c_shared_utility/lock.h
===================================================================
--- azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/inc/azure_c_shared_utility/lock.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/inc/azure_c_shared_utility/lock.h	(revision 457)
@@ -0,0 +1,77 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+/** @file lock.h  
+*	@brief		A minimalistic platform agnostic lock abstraction for thread
+*				synchronization.
+*	@details	The Lock component is implemented in order to achieve thread
+*				synchronization, as we may have a requirement to consume locks
+*				across different platforms. This component exposes some generic
+*				APIs so that it can be extended for platform specific
+*				implementations.
+*/
+
+#ifndef LOCK_H
+#define LOCK_H
+
+#include "azure_macro_utils/macro_utils.h"
+#include "umock_c/umock_c_prod.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef void* LOCK_HANDLE;
+
+#define LOCK_RESULT_VALUES \
+    LOCK_OK, \
+    LOCK_ERROR \
+
+/** @brief Enumeration specifying the lock status.
+*/
+MU_DEFINE_ENUM(LOCK_RESULT, LOCK_RESULT_VALUES);
+
+/**
+ * @brief	This API creates and returns a valid lock handle.
+ *
+ * @return	A valid @c LOCK_HANDLE when successful or @c NULL otherwise.
+ */
+MOCKABLE_FUNCTION(, LOCK_HANDLE, Lock_Init);
+
+/**
+ * @brief	Acquires a lock on the given lock handle. Uses platform
+ * 			specific mutex primitives in its implementation.
+ *
+ * @param	handle	A valid handle to the lock.
+ *
+ * @return	Returns @c LOCK_OK when a lock has been acquired and
+ * 			@c LOCK_ERROR when an error occurs.
+ */
+MOCKABLE_FUNCTION(, LOCK_RESULT, Lock, LOCK_HANDLE, handle);
+
+/**
+ * @brief	Releases the lock on the given lock handle. Uses platform
+ * 			specific mutex primitives in its implementation.
+ *
+ * @param	handle	A valid handle to the lock.
+ *
+ * @return	Returns @c LOCK_OK when the lock has been released and
+ * 			@c LOCK_ERROR when an error occurs.
+ */
+MOCKABLE_FUNCTION(, LOCK_RESULT, Unlock, LOCK_HANDLE, handle);
+
+/**
+ * @brief	The lock instance is destroyed.
+ *
+ * @param	handle	A valid handle to the lock.
+ *
+ * @return	Returns @c LOCK_OK when the lock object has been
+ * 			destroyed and @c LOCK_ERROR when an error occurs.
+ */
+MOCKABLE_FUNCTION(, LOCK_RESULT, Lock_Deinit, LOCK_HANDLE, handle);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LOCK_H */
Index: azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/inc/azure_c_shared_utility/map.h
===================================================================
--- azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/inc/azure_c_shared_utility/map.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/inc/azure_c_shared_utility/map.h	(revision 457)
@@ -0,0 +1,205 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+/** @file       map.h
+*    @brief        Map is a module that implements a dictionary of @c STRING_HANDLE
+*               keys to @c STRING_HANDLE values.
+*/
+
+#ifndef MAP_H
+#define MAP_H
+
+#ifdef __cplusplus
+#include <cstddef>
+#else
+#include <stddef.h>
+#endif
+
+#include "azure_macro_utils/macro_utils.h"
+#include "azure_c_shared_utility/strings.h"
+#include "azure_c_shared_utility/crt_abstractions.h"
+#include "umock_c/umock_c_prod.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#define MAP_RESULT_VALUES \
+    MAP_OK, \
+    MAP_ERROR, \
+    MAP_INVALIDARG, \
+    MAP_KEYEXISTS, \
+    MAP_KEYNOTFOUND, \
+    MAP_FILTER_REJECT
+
+/** @brief Enumeration specifying the status of calls to various APIs in this
+ *  module.
+ */
+MU_DEFINE_ENUM(MAP_RESULT, MAP_RESULT_VALUES);
+
+typedef struct MAP_HANDLE_DATA_TAG* MAP_HANDLE;
+
+typedef int (*MAP_FILTER_CALLBACK)(const char* mapProperty, const char* mapValue);
+
+/**
+ * @brief   Creates a new, empty map.
+ *
+ * @param   mapFilterFunc   A callback function supplied by the caller that is
+ *                          invoked during calls to ::Map_Add and
+ *                          ::Map_AddOrUpdate to provide the caller an
+ *                          opportunity to indicate whether the new entry or
+ *                          the update to an existing entry can be made or not.
+ *                          The callback function can request that the operation
+ *                          be canceled by returning a non-zero value from the
+ *                          callback.
+ *
+ * @return  A valid @c MAP_HANDLE or @c NULL in case an error occurs.
+ */
+MOCKABLE_FUNCTION(, MAP_HANDLE, Map_Create, MAP_FILTER_CALLBACK, mapFilterFunc);
+
+/**
+ * @brief   Release all resources associated with the map.
+ *
+ * @param   handle  The handle to an existing map.
+ */
+MOCKABLE_FUNCTION(, void, Map_Destroy, MAP_HANDLE, handle);
+
+/**
+ * @brief   Creates a copy of the map indicated by @p handle and returns a
+ *          handle to it.
+ *
+ * @param   handle  The handle to an existing map.
+ *
+ * @return  A valid @c MAP_HANDLE to the cloned copy of the map or @c NULL
+ *          in case an error occurs.
+ */
+MOCKABLE_FUNCTION(, MAP_HANDLE, Map_Clone, MAP_HANDLE, handle);
+
+/**
+ * @brief   Adds a key/value pair to the map.
+ *
+ * @param   handle  The handle to an existing map.
+ * @param   key     The @c key to be used for this map entry.
+ * @param   value   The @c value to be associated with @p key.
+ *
+ *          If a non-NULL pointer to a callback function was supplied
+ *          via the @c mapFilterFunc parameter when ::Map_Create was
+ *          called then that callback is invoked when a new entry is
+ *          added and if the callback returns a non-zero value then
+ *          the function cancels the add operation and returns
+ *          @c MAP_FILTER_REJECT.
+ *
+ * @return  If any of the input parameters are @c NULL then this function
+ *          returns @c MAP_INVALID_ARG. If the key already exists in the
+ *          map then @c MAP_KEYEXISTS is returned. If the filter function
+ *          associated with the map rejects the entry then
+ *          @c MAP_FILTER_REJECT is returned. In case an error occurs when
+ *          the new key is added to the map the function returns @c MAP_ERROR.
+ *          If everything goes well then @c MAP_OK is returned.
+ */
+MOCKABLE_FUNCTION(, MAP_RESULT, Map_Add, MAP_HANDLE, handle, const char*, key, const char*, value);
+
+/**
+ * @brief   Adds/updates a key/value pair to the map.
+ *
+ * @param   handle  The handle to an existing map.
+ * @param   key     The @c key to be used for this map entry.
+ * @param   value   The @c value to be associated with @p key.
+ *
+ *          This function behaves exactly like ::Map_Add except that if the key
+ *          already exists in the map then it overwrites the value with the
+ *          supplied value instead of returning an error. If a non-NULL pointer
+ *          to a callback function was supplied via the @c mapFilterFunc parameter
+ *          when ::Map_Create was called then that callback is invoked when a new
+ *          entry is added or when an existing entry is updated and if the
+ *          callback returns a non-zero value then the function cancels the
+ *          add/update operation and returns @c MAP_FILTER_REJECT.
+ *
+ * @return  If any of the input parameters are @c NULL then this function
+ *          returns @c MAP_INVALID_ARG. If the filter function associated
+ *          with the map rejects the entry then @c MAP_FILTER_REJECT is
+ *          returned. In case an error occurs when the new key is
+ *          added/updated in the map the function returns @c MAP_ERROR. If
+ *          everything goes well then @c MAP_OK is returned.
+ */
+MOCKABLE_FUNCTION(, MAP_RESULT, Map_AddOrUpdate, MAP_HANDLE, handle, const char*, key, const char*, value);
+
+/**
+ * @brief   Removes a key and its associated value from the map.
+ *
+ * @param   handle  The handle to an existing map.
+ * @param   key     The @c key of the item to be deleted.
+ *
+ * @return  Returns @c MAP_OK if the key was deleted successfully or an
+ *          error code otherwise.
+ */
+MOCKABLE_FUNCTION(, MAP_RESULT, Map_Delete, MAP_HANDLE, handle, const char*, key);
+
+/**
+ * @brief   This function returns a boolean value in @p keyExists if the map
+ *          contains a key with the same value the parameter @p key.
+ *
+ * @param   handle      The handle to an existing map.
+ * @param   key         The key that the caller wants checked.
+ * @param   keyExists   The function writes @c true at the address pointed at
+ *                      by this parameter if the key exists in the map and
+ *                      @c false otherwise.
+ *
+ * @return  Returns @c MAP_OK if the check was performed successfully or an
+ *          error code otherwise.
+ */
+MOCKABLE_FUNCTION(, MAP_RESULT, Map_ContainsKey, MAP_HANDLE, handle, const char*, key, bool*, keyExists);
+
+/**
+ * @brief   This function returns @c true in @p valueExists if at
+ *          least one <key,value> pair exists in the map where the entry's
+ *          value is equal to the parameter @c value.
+ *
+ * @param   handle          The handle to an existing map.
+ * @param   value           The value that the caller wants checked.
+ * @param   valueExists     The function writes @c true at the address pointed at
+ *                          by this parameter if the value exists in the map and
+ *                          @c false otherwise.
+ *
+ * @return  Returns @c MAP_OK if the check was performed successfully or an
+ *          error code otherwise.
+ */
+MOCKABLE_FUNCTION(, MAP_RESULT, Map_ContainsValue, MAP_HANDLE, handle, const char*, value, bool*, valueExists);
+
+/**
+ * @brief   Retrieves the value of a stored key.
+ *
+ * @param   handle  The handle to an existing map.
+ * @param   key     The key to be looked up in the map.
+ *
+ * @return  Returns @c NULL in case the input arguments are @c NULL or if the
+ *          requested key is not found in the map. Returns a pointer to the
+ *          key's value otherwise.
+ */
+MOCKABLE_FUNCTION(, const char*, Map_GetValueFromKey, MAP_HANDLE, handle, const char*, key);
+
+/**
+ * @brief   Retrieves the complete list of keys and values from the map
+ *          in @p values and @p keys. Also writes the size of the list
+ *          in @p count.
+ *
+ * @param   handle      The handle to an existing map.
+ * @param   keys        The location where the list of keys is to be written.
+ * @param   values      The location where the list of values is to be written.
+ * @param   count       The number of stored keys and values is written at the
+ *                      location indicated by this pointer.
+ *
+ * @return  Returns @c MAP_OK if the keys and values are retrieved and written
+ *          successfully or an error code otherwise.
+ */
+MOCKABLE_FUNCTION(, MAP_RESULT, Map_GetInternals, MAP_HANDLE, handle, const char*const**, keys, const char*const**, values, size_t*, count);
+
+/*this API creates a JSON object from the content of the map*/
+MOCKABLE_FUNCTION(, STRING_HANDLE, Map_ToJSON, MAP_HANDLE, handle);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* MAP_H */
Index: azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/inc/azure_c_shared_utility/optimize_size.h
===================================================================
--- azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/inc/azure_c_shared_utility/optimize_size.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/inc/azure_c_shared_utility/optimize_size.h	(revision 457)
@@ -0,0 +1,24 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+#ifndef OPTIMIZE_SIZE_H
+#define OPTIMIZE_SIZE_H
+
+#if (defined __MSP430FR5969__)
+    #define OPTIMIZE_RETURN_CODES
+    #define NO_VERBOSE_OUTPUT
+    #ifdef DEBUG
+        #define MINIMAL_LOGERROR
+    #else
+        #define NO_LOGGING
+    #endif
+#endif
+
+#if (defined OPTIMIZE_RETURN_CODES)
+    #define MU_FAILURE 1
+#else
+    #define MU_FAILURE __LINE__
+#endif
+
+#endif // OPTIMIZE_SIZE_H
+
Index: azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/inc/azure_c_shared_utility/optionhandler.h
===================================================================
--- azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/inc/azure_c_shared_utility/optionhandler.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/inc/azure_c_shared_utility/optionhandler.h	(revision 457)
@@ -0,0 +1,47 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+#ifndef OPTIONHANDLER_H
+#define OPTIONHANDLER_H
+
+#include "azure_macro_utils/macro_utils.h"
+#include "umock_c/umock_c_prod.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+#define OPTIONHANDLER_RESULT_VALUES \
+    OPTIONHANDLER_OK, \
+    OPTIONHANDLER_ERROR, \
+    OPTIONHANDLER_INVALIDARG
+
+MU_DEFINE_ENUM_WITHOUT_INVALID(OPTIONHANDLER_RESULT, OPTIONHANDLER_RESULT_VALUES)
+
+typedef struct OPTIONHANDLER_HANDLE_DATA_TAG* OPTIONHANDLER_HANDLE;
+
+/*the following function pointer points to a function that produces a clone of the option specified by name and value (that is, a clone of void* value)*/
+/*returns NULL if it failed to produce a clone, otherwise returns a non-NULL value*/
+/*to be implemented by every module*/
+typedef void* (*pfCloneOption)(const char* name, const void* value);
+
+/*the following function pointer points to a function that frees resources allocated for an option*/
+/*to be implemented by every module*/
+typedef void (*pfDestroyOption)(const char* name, const void* value);
+
+/*the following function pointer points to a function that sets an option for a module*/
+/*to be implemented by every module*/
+/*returns 0 if _SetOption succeeded, any other value is error, if the option is not intended for that module, returns 0*/
+typedef int (*pfSetOption)(void* handle, const char* name, const void* value);
+
+MOCKABLE_FUNCTION(, OPTIONHANDLER_HANDLE, OptionHandler_Create, pfCloneOption, cloneOption, pfDestroyOption, destroyOption, pfSetOption, setOption);
+MOCKABLE_FUNCTION(, OPTIONHANDLER_HANDLE, OptionHandler_Clone, OPTIONHANDLER_HANDLE, handler);
+MOCKABLE_FUNCTION(, OPTIONHANDLER_RESULT, OptionHandler_AddOption, OPTIONHANDLER_HANDLE, handle, const char*, name, const void*, value);
+MOCKABLE_FUNCTION(, OPTIONHANDLER_RESULT, OptionHandler_FeedOptions, OPTIONHANDLER_HANDLE, handle, void*, destinationHandle);
+MOCKABLE_FUNCTION(, void, OptionHandler_Destroy, OPTIONHANDLER_HANDLE, handle);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /*OPTIONHANDLER*/
Index: azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/inc/azure_c_shared_utility/platform.h
===================================================================
--- azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/inc/azure_c_shared_utility/platform.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/inc/azure_c_shared_utility/platform.h	(revision 457)
@@ -0,0 +1,32 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+#ifndef PLATFORM_H
+#define PLATFORM_H
+
+#include "azure_c_shared_utility/strings.h"
+#include "azure_c_shared_utility/xio.h"
+#include "umock_c/umock_c_prod.h"
+
+#define GUID_LENGTH 64
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+    #define PLATFORM_INFO_OPTION_VALUES       \
+        PLATFORM_INFO_OPTION_DEFAULT,         \
+        PLATFORM_INFO_OPTION_RETRIEVE_SQM
+
+    MU_DEFINE_ENUM(PLATFORM_INFO_OPTION, PLATFORM_INFO_OPTION_VALUES);
+
+    MOCKABLE_FUNCTION(, int, platform_init);
+    MOCKABLE_FUNCTION(, void, platform_deinit);
+    MOCKABLE_FUNCTION(, const IO_INTERFACE_DESCRIPTION*, platform_get_default_tlsio);
+    MOCKABLE_FUNCTION(, STRING_HANDLE, platform_get_platform_info, PLATFORM_INFO_OPTION, options);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* PLATFORM_H */
Index: azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/inc/azure_c_shared_utility/refcount.h
===================================================================
--- azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/inc/azure_c_shared_utility/refcount.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/inc/azure_c_shared_utility/refcount.h	(revision 457)
@@ -0,0 +1,125 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+
+/*this header contains macros for ref_counting a variable.
+
+There are no upper bound checks related to uint32_t overflow because we expect that bigger issues are in
+the system when more than 4 billion references exist to the same variable. In the case when such an overflow
+occurs, the object's ref count will reach zero (while still having 0xFFFFFFFF references) and likely the
+controlling code will take the decision to free the object's resources. Then, any of the 0xFFFFFFFF references
+will interact with deallocated memory / resources resulting in an undefined behavior.
+*/
+
+#ifndef REFCOUNT_H
+#define REFCOUNT_H
+
+#ifdef __cplusplus
+#include <cstdlib>
+#include <cstdint>
+#else
+#include <stdlib.h>
+#include <stdint.h>
+#endif
+
+#include "azure_c_shared_utility/gballoc.h"
+#include "azure_macro_utils/macro_utils.h"
+
+// Include the platform-specific file that defines atomic functionality
+#include "refcount_os.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#define REFCOUNT_TYPE(type) \
+struct MU_C2(MU_C2(REFCOUNT_, type), _TAG)
+
+#define REFCOUNT_SHORT_TYPE(type) \
+MU_C2(REFCOUNT_, type)
+
+#define REFCOUNT_TYPE_DECLARE_CREATE(type) MU_C2(REFCOUNT_SHORT_TYPE(type), _Create)
+#define REFCOUNT_TYPE_DECLARE_CREATE_WITH_EXTRA_SIZE(type) MU_C2(REFCOUNT_SHORT_TYPE(type), _Create_With_Extra_Size)
+#define REFCOUNT_TYPE_CREATE(type) MU_C2(REFCOUNT_SHORT_TYPE(type), _Create)()
+#define REFCOUNT_TYPE_CREATE_WITH_EXTRA_SIZE(type, size) MU_C2(REFCOUNT_SHORT_TYPE(type), _Create_With_Extra_Size)(size)
+#define REFCOUNT_TYPE_DECLARE_DESTROY(type) MU_C2(REFCOUNT_SHORT_TYPE(type), _Destroy)
+#define REFCOUNT_TYPE_DESTROY(type, var) MU_C2(REFCOUNT_SHORT_TYPE(type), _Destroy)(var)
+
+/*this introduces a new refcount'd type based on another type */
+/*and an initializer for that new type that also sets the ref count to 1. The type must not have a flexible array*/
+/*the newly allocated memory shall be free'd by free()*/
+/*and the ref counting is handled internally by the type in the _Create/ _Create_With_Extra_Size /_Clone /_Destroy functions */
+
+/* Codes_SRS_REFCOUNT_01_005: [ REFCOUNT_TYPE_CREATE_WITH_EXTRA_SIZE shall allocate memory for the type that is ref counted (type) plus extra memory enough to hold size bytes. ]*/
+/* Codes_SRS_REFCOUNT_01_006: [ On success it shall return a non-NULL handle to the allocated ref counted type type. ]*/
+/* Codes_SRS_REFCOUNT_01_007: [ If any error occurs, REFCOUNT_TYPE_CREATE_WITH_EXTRA_SIZE shall return NULL. ]*/
+#define DEFINE_CREATE_WITH_EXTRA_SIZE(type) \
+static type* REFCOUNT_TYPE_DECLARE_CREATE_WITH_EXTRA_SIZE(type)(size_t size) \
+{ \
+    REFCOUNT_TYPE(type)* ref_counted = (REFCOUNT_TYPE(type)*)malloc(sizeof(REFCOUNT_TYPE(type)) + size); \
+    type* result; \
+    if (ref_counted == NULL) \
+    { \
+        result = NULL; \
+    } \
+    else \
+    { \
+        result = &ref_counted->counted; \
+        INIT_REF(type, result); \
+    } \
+    return result; \
+} \
+
+/* Codes_SRS_REFCOUNT_01_002: [ REFCOUNT_TYPE_CREATE shall allocate memory for the type that is ref counted. ]*/
+/* Codes_SRS_REFCOUNT_01_003: [ On success it shall return a non-NULL handle to the allocated ref counted type type. ]*/
+/* Codes_SRS_REFCOUNT_01_004: [ If any error occurs, REFCOUNT_TYPE_CREATE shall return NULL. ]*/
+#define DEFINE_CREATE(type) \
+static type* REFCOUNT_TYPE_DECLARE_CREATE(type) (void) \
+{ \
+    return REFCOUNT_TYPE_DECLARE_CREATE_WITH_EXTRA_SIZE(type)(0); \
+} \
+
+/* Codes_SRS_REFCOUNT_01_008: [ REFCOUNT_TYPE_DESTROY shall free the memory allocated by REFCOUNT_TYPE_CREATE or REFCOUNT_TYPE_CREATE_WITH_EXTRA_SIZE. ]*/
+/* Codes_SRS_REFCOUNT_01_009: [ If counted_type is NULL, REFCOUNT_TYPE_DESTROY shall return. ]*/
+#define DEFINE_DESTROY(type) \
+static void REFCOUNT_TYPE_DECLARE_DESTROY(type)(type* counted_type) \
+{ \
+    void* ref_counted = (void*)((unsigned char*)counted_type - offsetof(REFCOUNT_TYPE(type), counted)); \
+    free(ref_counted); \
+}
+
+#define DEFINE_REFCOUNT_TYPE(type) \
+REFCOUNT_TYPE(type) \
+{ \
+    COUNT_TYPE count; \
+    type counted; \
+}; \
+DEFINE_CREATE_WITH_EXTRA_SIZE(type) \
+DEFINE_CREATE(type) \
+DEFINE_DESTROY(type) \
+
+#ifndef DEC_RETURN_ZERO
+#error refcount_os.h does not define DEC_RETURN_ZERO
+#endif // !DEC_RETURN_ZERO
+#ifndef INC_REF_VAR
+#error refcount_os.h does not define INC_REF_VAR
+#endif // !INC_REF
+#ifndef DEC_REF_VAR
+#error refcount_os.h does not define DEC_REF_VAR
+#endif // !DEC_REF
+#ifndef INIT_REF_VAR
+#error refcount_os.h does not define INIT_REF_VAR
+#endif // !INIT_REF
+
+#define INC_REF(type, var) INC_REF_VAR(((REFCOUNT_TYPE(type)*)((unsigned char*)var - offsetof(REFCOUNT_TYPE(type), counted)))->count)
+#define DEC_REF(type, var) DEC_REF_VAR(((REFCOUNT_TYPE(type)*)((unsigned char*)var - offsetof(REFCOUNT_TYPE(type), counted)))->count)
+#define INIT_REF(type, var) INIT_REF_VAR(((REFCOUNT_TYPE(type)*)((unsigned char*)var - offsetof(REFCOUNT_TYPE(type), counted)))->count)
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /*REFCOUNT_H*/
+
+
Index: azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/inc/azure_c_shared_utility/sastoken.h
===================================================================
--- azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/inc/azure_c_shared_utility/sastoken.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/inc/azure_c_shared_utility/sastoken.h	(revision 457)
@@ -0,0 +1,27 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+#ifndef SASTOKEN_H
+#define SASTOKEN_H
+
+#ifdef __cplusplus
+#else
+#include <stdbool.h>
+#endif
+
+#include "azure_c_shared_utility/strings.h"
+#include "umock_c/umock_c_prod.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+    MOCKABLE_FUNCTION(, bool, SASToken_Validate, STRING_HANDLE, sasToken);
+    MOCKABLE_FUNCTION(, STRING_HANDLE, SASToken_Create, STRING_HANDLE, key, STRING_HANDLE, scope, STRING_HANDLE, keyName, size_t, expiry);
+    MOCKABLE_FUNCTION(, STRING_HANDLE, SASToken_CreateString, const char*, key, const char*, scope, const char*, keyName, size_t, expiry);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* SASTOKEN_H */
Index: azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/inc/azure_c_shared_utility/sha-private.h
===================================================================
--- azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/inc/azure_c_shared_utility/sha-private.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/inc/azure_c_shared_utility/sha-private.h	(revision 457)
@@ -0,0 +1,33 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+/*************************** sha-private.h ***************************/
+/********************** See RFC 4634 for details *********************/
+#ifndef _SHA_PRIVATE__H
+#define _SHA_PRIVATE__H
+/*
+* These definitions are defined in FIPS-180-2, section 4.1.
+* Ch() and Maj() are defined identically in sections 4.1.1,
+* 4.1.2 and 4.1.3.
+*
+* The definitions used in FIPS-180-2 are as follows:
+*/
+
+#ifndef USE_MODIFIED_MACROS
+#define SHA_Ch(x,y,z)        (((x) & (y)) ^ ((~(x)) & (z)))
+#define SHA_Maj(x,y,z)       (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z)))
+
+#else /* USE_MODIFIED_MACROS */
+/*
+* The following definitions are equivalent and potentially faster.
+*/
+
+#define SHA_Ch(x, y, z)      (((x) & ((y) ^ (z))) ^ (z))
+#define SHA_Maj(x, y, z)     (((x) & ((y) | (z))) | ((y) & (z)))
+
+#endif /* USE_MODIFIED_MACROS */
+
+#define SHA_Parity(x, y, z)  ((x) ^ (y) ^ (z))
+
+#endif /* _SHA_PRIVATE__H */
+
Index: azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/inc/azure_c_shared_utility/sha.h
===================================================================
--- azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/inc/azure_c_shared_utility/sha.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/inc/azure_c_shared_utility/sha.h	(revision 457)
@@ -0,0 +1,260 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+/**************************** sha.h ****************************/
+/******************* See RFC 4634 for details ******************/
+#ifndef _SHA_H_
+#define _SHA_H_
+
+/*
+ *  Description:
+ *      This file implements the Secure Hash Signature Standard
+ *      algorithms as defined in the National Institute of Standards
+ *      and Technology Federal Information Processing Standards
+ *      Publication (FIPS PUB) 180-1 published on April 17, 1995, 180-2
+ *      published on August 1, 2002, and the FIPS PUB 180-2 Change
+ *      Notice published on February 28, 2004.
+ *
+ *      A combined document showing all algorithms is available at
+ *              http://csrc.nist.gov/publications/fips/
+ *              fips180-2/fips180-2withchangenotice.pdf
+ *
+ *      The five hashes are defined in these sizes:
+ *              SHA-1           20 byte / 160 bit
+ *              SHA-224         28 byte / 224 bit
+ *              SHA-256         32 byte / 256 bit
+ *              SHA-384         48 byte / 384 bit
+ *              SHA-512         64 byte / 512 bit
+ */
+
+#ifdef __cplusplus
+#include <cstdint>
+#else
+#include <stdint.h>
+#endif
+
+/*
+ * If you do not have the ISO standard stdint.h header file, then you
+ * must typedef the following:
+ *    name              meaning
+ *  uint64_t         unsigned 64 bit integer
+ *  uint32_t         unsigned 32 bit integer
+ *  uint8_t          unsigned 8 bit integer (i.e., unsigned char)
+ *  int_least16_t    integer of >= 16 bits
+ *
+ */
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#ifndef _SHA_enum_
+#define _SHA_enum_
+/*
+ *  All SHA functions return one of these values.
+ */
+enum {
+    shaSuccess = 0,
+    shaNull,            /* Null pointer parameter */
+    shaInputTooLong,    /* input data too long */
+    shaStateError,      /* called Input after FinalBits or Result */
+    shaBadParam         /* passed a bad parameter */
+};
+#endif /* _SHA_enum_ */
+
+/*
+ *  These constants hold size information for each of the SHA
+ *  hashing operations
+ */
+enum {
+    SHA1_Message_Block_Size = 64, SHA224_Message_Block_Size = 64,
+    SHA256_Message_Block_Size = 64, SHA384_Message_Block_Size = 128,
+    SHA512_Message_Block_Size = 128,
+    USHA_Max_Message_Block_Size = SHA512_Message_Block_Size,
+
+    SHA1HashSize = 20, SHA224HashSize = 28, SHA256HashSize = 32,
+    SHA384HashSize = 48, SHA512HashSize = 64,
+    USHAMaxHashSize = SHA512HashSize,
+
+    SHA1HashSizeBits = 160, SHA224HashSizeBits = 224,
+    SHA256HashSizeBits = 256, SHA384HashSizeBits = 384,
+    SHA512HashSizeBits = 512, USHAMaxHashSizeBits = SHA512HashSizeBits
+};
+
+/*
+ *  These constants are used in the USHA (unified sha) functions.
+ */
+typedef enum SHAversion {
+    SHA1, SHA224, SHA256, SHA384, SHA512
+} SHAversion;
+
+/*
+ *  This structure will hold context information for the SHA-1
+ *  hashing operation.
+ */
+typedef struct SHA1Context {
+    uint32_t Intermediate_Hash[SHA1HashSize/4]; /* Message Digest */
+
+    uint32_t Length_Low;                /* Message length in bits */
+    uint32_t Length_High;               /* Message length in bits */
+
+    int_least16_t Message_Block_Index;  /* Message_Block array index */
+                                        /* 512-bit message blocks */
+    uint8_t Message_Block[SHA1_Message_Block_Size];
+
+    int Computed;                       /* Is the digest computed? */
+    int Corrupted;                      /* Is the digest corrupted? */
+} SHA1Context;
+
+/*
+ *  This structure will hold context information for the SHA-256
+ *  hashing operation.
+ */
+typedef struct SHA256Context {
+    uint32_t Intermediate_Hash[SHA256HashSize/4]; /* Message Digest */
+
+    uint32_t Length_Low;                /* Message length in bits */
+    uint32_t Length_High;               /* Message length in bits */
+
+    int_least16_t Message_Block_Index;  /* Message_Block array index */
+                                        /* 512-bit message blocks */
+    uint8_t Message_Block[SHA256_Message_Block_Size];
+
+    int Computed;                       /* Is the digest computed? */
+    int Corrupted;                      /* Is the digest corrupted? */
+} SHA256Context;
+
+/*
+ *  This structure will hold context information for the SHA-512
+ *  hashing operation.
+ */
+typedef struct SHA512Context {
+#ifdef USE_32BIT_ONLY
+    uint32_t Intermediate_Hash[SHA512HashSize/4]; /* Message Digest  */
+    uint32_t Length[4];                 /* Message length in bits */
+#else /* !USE_32BIT_ONLY */
+    uint64_t Intermediate_Hash[SHA512HashSize/8]; /* Message Digest */
+    uint64_t Length_Low, Length_High;   /* Message length in bits */
+#endif /* USE_32BIT_ONLY */
+
+    int_least16_t Message_Block_Index;  /* Message_Block array index */
+                                        /* 1024-bit message blocks */
+    uint8_t Message_Block[SHA512_Message_Block_Size];
+
+    int Computed;                       /* Is the digest computed?*/
+    int Corrupted;                      /* Is the digest corrupted? */
+} SHA512Context;
+
+/*
+ *  This structure will hold context information for the SHA-224
+ *  hashing operation. It uses the SHA-256 structure for computation.
+ */
+typedef struct SHA256Context SHA224Context;
+
+/*
+ *  This structure will hold context information for the SHA-384
+ *  hashing operation. It uses the SHA-512 structure for computation.
+ */
+typedef struct SHA512Context SHA384Context;
+
+/*
+ *  This structure holds context information for all SHA
+ *  hashing operations.
+ */
+typedef struct USHAContext {
+    int whichSha;               /* which SHA is being used */
+    union {
+      SHA1Context sha1Context;
+      SHA224Context sha224Context; SHA256Context sha256Context;
+      SHA384Context sha384Context; SHA512Context sha512Context;
+    } ctx;
+} USHAContext;
+
+/*
+ *  This structure will hold context information for the HMAC
+ *  keyed hashing operation.
+ */
+typedef struct HMACContext {
+    int whichSha;               /* which SHA is being used */
+    int hashSize;               /* hash size of SHA being used */
+    int blockSize;              /* block size of SHA being used */
+    USHAContext shaContext;     /* SHA context */
+    unsigned char k_opad[USHA_Max_Message_Block_Size];
+                        /* outer padding - key XORd with opad */
+} HMACContext;
+
+
+/*
+ *  Function Prototypes
+ */
+
+/* SHA-1 */
+int SHA1Reset(SHA1Context *);
+int SHA1Input(SHA1Context *, const uint8_t *bytes, unsigned int bytecount);
+int SHA1FinalBits(SHA1Context *, const uint8_t bits, unsigned int bitcount);
+int SHA1Result(SHA1Context *, uint8_t Message_Digest[SHA1HashSize]);
+
+/* SHA-224 */
+int SHA224Reset(SHA224Context *);
+int SHA224Input(SHA224Context *, const uint8_t *bytes, unsigned int bytecount);
+int SHA224FinalBits(SHA224Context *, const uint8_t bits, unsigned int bitcount);
+int SHA224Result(SHA224Context *, uint8_t Message_Digest[SHA224HashSize]);
+
+/* SHA-256 */
+int SHA256Reset(SHA256Context *);
+int SHA256Input(SHA256Context *, const uint8_t *bytes, unsigned int bytecount);
+int SHA256FinalBits(SHA256Context *, const uint8_t bits, unsigned int bitcount);
+int SHA256Result(SHA256Context *, uint8_t Message_Digest[SHA256HashSize]);
+
+/* SHA-384 */
+int SHA384Reset(SHA384Context *);
+int SHA384Input(SHA384Context *, const uint8_t *bytes, unsigned int bytecount);
+int SHA384FinalBits(SHA384Context *, const uint8_t bits, unsigned int bitcount);
+int SHA384Result(SHA384Context *, uint8_t Message_Digest[SHA384HashSize]);
+
+/* SHA-512 */
+int SHA512Reset(SHA512Context *);
+int SHA512Input(SHA512Context *, const uint8_t *bytes, unsigned int bytecount);
+int SHA512FinalBits(SHA512Context *, const uint8_t bits, unsigned int bitcount);
+int SHA512Result(SHA512Context *, uint8_t Message_Digest[SHA512HashSize]);
+
+/* Unified SHA functions, chosen by whichSha */
+int USHAReset(USHAContext *, SHAversion whichSha);
+int USHAInput(USHAContext *, const uint8_t *bytes, unsigned int bytecount);
+int USHAFinalBits(USHAContext *, const uint8_t bits, unsigned int bitcount);
+int USHAResult(USHAContext *, uint8_t Message_Digest[USHAMaxHashSize]);
+int USHABlockSize(enum SHAversion whichSha);
+int USHAHashSize(enum SHAversion whichSha);
+int USHAHashSizeBits(enum SHAversion whichSha);
+
+/*
+ * HMAC Keyed-Hashing for Message Authentication, RFC2104,
+ * for all SHAs.
+ * This interface allows a fixed-length text input to be used.
+ */
+int hmac(SHAversion whichSha, /* which SHA algorithm to use */
+    const unsigned char *text,     /* pointer to data stream */
+    int text_len,                  /* length of data stream */
+    const unsigned char *key,      /* pointer to authentication key */
+    int key_len,                   /* length of authentication key */
+    uint8_t digest[USHAMaxHashSize]); /* caller digest to fill in */
+
+/*
+ * HMAC Keyed-Hashing for Message Authentication, RFC2104,
+ * for all SHAs.
+ * This interface allows any length of text input to be used.
+ */
+int hmacReset(HMACContext *ctx, enum SHAversion whichSha, const unsigned char *key, int key_len);
+int hmacInput(HMACContext *ctx, const unsigned char *text, int text_len);
+
+int hmacFinalBits(HMACContext *ctx, const uint8_t bits, unsigned int bitcount);
+int hmacResult(HMACContext *ctx, uint8_t digest[USHAMaxHashSize]);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _SHA_H_ */
+
Index: azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/inc/azure_c_shared_utility/shared_util_options.h
===================================================================
--- azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/inc/azure_c_shared_utility/shared_util_options.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/inc/azure_c_shared_utility/shared_util_options.h	(revision 457)
@@ -0,0 +1,59 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+#ifndef SHARED_UTIL_OPTIONS_H
+#define SHARED_UTIL_OPTIONS_H
+
+#include "azure_c_shared_utility/const_defines.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+    typedef struct HTTP_PROXY_OPTIONS_TAG
+    {
+        const char* host_address;
+        int port;
+        const char* username;
+        const char* password;
+    } HTTP_PROXY_OPTIONS;
+
+    static STATIC_VAR_UNUSED const char* const OPTION_HTTP_PROXY = "proxy_data";
+    static STATIC_VAR_UNUSED const char* const OPTION_HTTP_TIMEOUT = "timeout";
+
+    static STATIC_VAR_UNUSED const char* const OPTION_TRUSTED_CERT = "TrustedCerts";
+
+    // Clients should not use OPTION_OPENSSL_CIPHER_SUITE except for very specialized scenarios.
+    // They instead should rely on the underlying client TLS stack and service to negotiate an appropriate cipher.
+    static STATIC_VAR_UNUSED const char* const OPTION_OPENSSL_CIPHER_SUITE = "CipherSuite";
+
+    static STATIC_VAR_UNUSED const char* const SU_OPTION_X509_CERT = "x509certificate";
+    static STATIC_VAR_UNUSED const char* const SU_OPTION_X509_PRIVATE_KEY = "x509privatekey";
+
+    static STATIC_VAR_UNUSED const char* const OPTION_X509_ECC_CERT = "x509EccCertificate";
+    static STATIC_VAR_UNUSED const char* const OPTION_X509_ECC_KEY = "x509EccAliasKey";
+
+    static STATIC_VAR_UNUSED const char* const OPTION_CURL_LOW_SPEED_LIMIT = "CURLOPT_LOW_SPEED_LIMIT";
+    static STATIC_VAR_UNUSED const char* const OPTION_CURL_LOW_SPEED_TIME = "CURLOPT_LOW_SPEED_TIME";
+    static STATIC_VAR_UNUSED const char* const OPTION_CURL_FRESH_CONNECT = "CURLOPT_FRESH_CONNECT";
+    static STATIC_VAR_UNUSED const char* const OPTION_CURL_FORBID_REUSE = "CURLOPT_FORBID_REUSE";
+    static STATIC_VAR_UNUSED const char* const OPTION_CURL_VERBOSE = "CURLOPT_VERBOSE";
+
+    static STATIC_VAR_UNUSED const char* const OPTION_NET_INT_MAC_ADDRESS = "net_interface_mac_address";
+
+    static STATIC_VAR_UNUSED const char* const OPTION_SET_TLS_RENEGOTIATION = "tls_renegotiation";
+
+    // DEPRECATED: The underlying security library for your platform will use a secure TLS version 
+    // that in general  should not be overridden with OPTION_TLS_VERSION.
+    static STATIC_VAR_UNUSED const char* const OPTION_TLS_VERSION = "tls_version";
+
+    static STATIC_VAR_UNUSED const char* const OPTION_ADDRESS_TYPE = "ADDRESS_TYPE";
+    static STATIC_VAR_UNUSED const char* const OPTION_ADDRESS_TYPE_DOMAIN_SOCKET = "DOMAIN_SOCKET";
+    static STATIC_VAR_UNUSED const char* const OPTION_ADDRESS_TYPE_IP_SOCKET = "IP_SOCKET";
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* SHARED_UTIL_OPTIONS_H */
Index: azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/inc/azure_c_shared_utility/singlylinkedlist.h
===================================================================
--- azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/inc/azure_c_shared_utility/singlylinkedlist.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/inc/azure_c_shared_utility/singlylinkedlist.h	(revision 457)
@@ -0,0 +1,60 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+#ifndef SINGLYLINKEDLIST_H
+#define SINGLYLINKEDLIST_H
+
+#ifdef __cplusplus
+#else
+#include "stdbool.h"
+#endif /* __cplusplus */
+
+#include "umock_c/umock_c_prod.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+typedef struct SINGLYLINKEDLIST_INSTANCE_TAG* SINGLYLINKEDLIST_HANDLE;
+typedef struct LIST_ITEM_INSTANCE_TAG* LIST_ITEM_HANDLE;
+
+/**
+* @brief                        Function passed to singlylinkedlist_find, which returns whichever first list item that matches it.
+* @param list_item                Current list node being evaluated.
+* @param match_context            Context passed to singlylinkedlist_find.
+* @returns                        True to indicate that the current list node is the one to be returned, or false to continue traversing the list.
+*/
+typedef bool (*LIST_MATCH_FUNCTION)(LIST_ITEM_HANDLE list_item, const void* match_context);
+/**
+* @brief                        Function passed to singlylinkedlist_remove_if, which is used to define if an item of the list should be removed or not.
+* @param item                    Value of the current list node being evaluated for removal.
+* @param match_context            Context passed to singlylinkedlist_remove_if.
+* @param continue_processing    Indicates if singlylinkedlist_remove_if shall continue iterating through the next nodes of the list or stop.
+* @returns                        True to indicate that the current list node shall be removed, or false to not to.
+*/
+typedef bool (*LIST_CONDITION_FUNCTION)(const void* item, const void* match_context, bool* continue_processing);
+/**
+* @brief                        Function passed to singlylinkedlist_foreach, which is called for the value of each node of the list.
+* @param item                    Value of the current list node being processed.
+* @param action_context            Context passed to singlylinkedlist_foreach.
+* @param continue_processing    Indicates if singlylinkedlist_foreach shall continue iterating through the next nodes of the list or stop.
+*/
+typedef void (*LIST_ACTION_FUNCTION)(const void* item, const void* action_context, bool* continue_processing);
+
+MOCKABLE_FUNCTION(, SINGLYLINKEDLIST_HANDLE, singlylinkedlist_create);
+MOCKABLE_FUNCTION(, void, singlylinkedlist_destroy, SINGLYLINKEDLIST_HANDLE, list);
+MOCKABLE_FUNCTION(, LIST_ITEM_HANDLE, singlylinkedlist_add, SINGLYLINKEDLIST_HANDLE, list, const void*, item);
+MOCKABLE_FUNCTION(, LIST_ITEM_HANDLE, singlylinkedlist_add_head, SINGLYLINKEDLIST_HANDLE, list, const void*, item);
+MOCKABLE_FUNCTION(, int, singlylinkedlist_remove, SINGLYLINKEDLIST_HANDLE, list, LIST_ITEM_HANDLE, item_handle);
+MOCKABLE_FUNCTION(, LIST_ITEM_HANDLE, singlylinkedlist_get_head_item, SINGLYLINKEDLIST_HANDLE, list);
+MOCKABLE_FUNCTION(, LIST_ITEM_HANDLE, singlylinkedlist_get_next_item, LIST_ITEM_HANDLE, item_handle);
+MOCKABLE_FUNCTION(, LIST_ITEM_HANDLE, singlylinkedlist_find, SINGLYLINKEDLIST_HANDLE, list, LIST_MATCH_FUNCTION, match_function, const void*, match_context);
+MOCKABLE_FUNCTION(, const void*, singlylinkedlist_item_get_value, LIST_ITEM_HANDLE, item_handle);
+MOCKABLE_FUNCTION(, int, singlylinkedlist_remove_if, SINGLYLINKEDLIST_HANDLE, list, LIST_CONDITION_FUNCTION, condition_function, const void*, match_context);
+MOCKABLE_FUNCTION(, int, singlylinkedlist_foreach, SINGLYLINKEDLIST_HANDLE, list, LIST_ACTION_FUNCTION, action_function, const void*, action_context);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* SINGLYLINKEDLIST_H */
Index: azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/inc/azure_c_shared_utility/socketio.h
===================================================================
--- azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/inc/azure_c_shared_utility/socketio.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/inc/azure_c_shared_utility/socketio.h	(revision 457)
@@ -0,0 +1,52 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+#ifndef SOCKETIO_H
+#define SOCKETIO_H
+
+#ifdef __cplusplus
+#include <cstddef>
+#else
+#include <stddef.h>
+#endif /* __cplusplus */
+
+#include "azure_c_shared_utility/xio.h"
+#include "azure_c_shared_utility/xlogging.h"
+#include "umock_c/umock_c_prod.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+typedef struct SOCKETIO_CONFIG_TAG
+{
+    const char* hostname;
+    int port;
+    void* accepted_socket;
+} SOCKETIO_CONFIG;
+
+typedef enum SOCKETIO_ADDRESS_TYPE_TAG
+{
+    ADDRESS_TYPE_IP,
+    ADDRESS_TYPE_DOMAIN_SOCKET
+} SOCKETIO_ADDRESS_TYPE;
+
+#ifndef XIO_RECEIVE_BUFFER_SIZE
+#define XIO_RECEIVE_BUFFER_SIZE     64
+#endif
+
+MOCKABLE_FUNCTION(, CONCRETE_IO_HANDLE, socketio_create, void*, io_create_parameters);
+MOCKABLE_FUNCTION(, void, socketio_destroy, CONCRETE_IO_HANDLE, socket_io);
+MOCKABLE_FUNCTION(, int, socketio_open, CONCRETE_IO_HANDLE, socket_io, ON_IO_OPEN_COMPLETE, on_io_open_complete, void*, on_io_open_complete_context, ON_BYTES_RECEIVED, on_bytes_received, void*, on_bytes_received_context, ON_IO_ERROR, on_io_error, void*, on_io_error_context);
+MOCKABLE_FUNCTION(, int, socketio_close, CONCRETE_IO_HANDLE, socket_io, ON_IO_CLOSE_COMPLETE, on_io_close_complete, void*, callback_context);
+MOCKABLE_FUNCTION(, int, socketio_send, CONCRETE_IO_HANDLE, socket_io, const void*, buffer, size_t, size, ON_SEND_COMPLETE, on_send_complete, void*, callback_context);
+MOCKABLE_FUNCTION(, void, socketio_dowork, CONCRETE_IO_HANDLE, socket_io);
+MOCKABLE_FUNCTION(, int, socketio_setoption, CONCRETE_IO_HANDLE, socket_io, const char*, optionName, const void*, value);
+
+MOCKABLE_FUNCTION(, const IO_INTERFACE_DESCRIPTION*, socketio_get_interface_description);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* SOCKETIO_H */
Index: azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/inc/azure_c_shared_utility/string_token.h
===================================================================
--- azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/inc/azure_c_shared_utility/string_token.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/inc/azure_c_shared_utility/string_token.h	(revision 457)
@@ -0,0 +1,95 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+#ifndef STRING_TOKEN_H
+#define STRING_TOKEN_H
+
+#ifdef __cplusplus
+#include <cstddef>
+#else
+#include <stddef.h>
+#include <stdbool.h>
+#endif
+
+#include "umock_c/umock_c_prod.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+typedef struct STRING_TOKEN_TAG* STRING_TOKEN_HANDLE;
+
+/*
+*    @brief     Tries to identify the first token defined in source up to its length using the delimiters provided.
+*    @Remark    If no delimiter is found, the entire source string becomes the resulting token. Empty tokens (when delimiters occur side-by-side) can also detected.
+*    @param     source        The initial string to be tokenized.
+*    @param     length        The length of the source string, not including the null-terminator.
+*    @param     delimiters    Array with null-terminated strings to be used as token delimiters.
+*    @param     n_delims      Number of elements in delimiters array.
+*    @return    A STRING_TOKEN_HANDLE if no failures occur (arguments, memory allocation), or NULL otherwise.
+*/
+MOCKABLE_FUNCTION(, STRING_TOKEN_HANDLE, StringToken_GetFirst, const char*, source, size_t, length, const char**, delimiters, size_t, n_delims);
+
+/*
+*    @brief     Tries to identify the next token defined in source up to its length using the delimiters provided.
+*    @Remark    After StringToken_GetFirst is initially called, StringToken_GetNext shall be called for obtaining the next tokens.
+*               If no delimiter is found, the entire source string becomes the resulting token.
+*               Empty tokens (when delimiters occur side-by-side) can also detected.
+*    @param     token         The handle returned by StringToken_GetFirst.
+*    @param     delimiters    Array with null-terminated strings to be used as token delimiters.
+*    @param     n_delims      Number of elements in delimiters array.
+*    @return    True if a token could be identified, or false if the tokenizer already reached the end of the source string an no more tokens are available.
+*/
+MOCKABLE_FUNCTION(, bool, StringToken_GetNext, STRING_TOKEN_HANDLE, token, const char**, delimiters, size_t, n_delims);
+
+/*
+*    @brief     Gets the pointer to the beginning of the current token identified in the source string.
+*    @param     token         The handle returned by StringToken_GetFirst.
+*    @return    The pointer to the token identified in the last successfull call to StringToken_GetFirst or StringToken_GetNext.
+*               If the token string is empty (e.g., between two delimiters side-by-side or if a delimiter occurs at the end of the source string),
+*               NULL is returned instead of an empty string.
+*/
+MOCKABLE_FUNCTION(, const char*, StringToken_GetValue, STRING_TOKEN_HANDLE, token);
+
+/*
+*    @brief     Gets the length of the current token identified in the source string.
+*    @param     token         The handle returned by StringToken_GetFirst.
+*    @return    A non-zero value if the current token is not empty, zero otherwise.
+*/
+MOCKABLE_FUNCTION(, size_t, StringToken_GetLength, STRING_TOKEN_HANDLE, token);
+
+/*
+*    @brief     Gets a pointer to last delimiter identified (which defined the current token).
+*    @param     token         The handle returned by StringToken_GetFirst.
+*    @return    If a delimiter was identified in the previous search,
+*               the pointer returned is to the element in the delimiters array provided in the previous call to StringToken_GetFirst or StringToken_GetNext;
+*               it returns NULL if no delimiter was found in the previous call to those functions.
+*/
+MOCKABLE_FUNCTION(, const char*, StringToken_GetDelimiter, STRING_TOKEN_HANDLE, token);
+
+/*
+*    @brief     Splits a string into an array with all the tokens identified using the delimiters provided.
+*    @param     source           The string to be tokenized.
+*    @param     length           The length of the source string, not including the null-terminator.
+*    @param     delimiters       Array with null-terminated strings to be used as token delimiters.
+*    @param     n_delims         Number of elements in delimiters array.
+*    @param     include_empty    Indicates if empty strings shall be included (as NULL values) in the resulting array.
+*    @param     tokens           If no failures occur, the resulting array with the split tokens (dynamically allocated).
+*    @param     token_count      The number of elements in the tokens array.
+*    @return    Zero if no failures occur, or a non-zero value otherwise.
+*/
+MOCKABLE_FUNCTION(, int, StringToken_Split, const char*, source, size_t, length, const char**, delimiters, size_t, n_delims, bool, include_empty, char***, tokens, size_t*, token_count);
+
+/*
+*    @brief     Destroys the handle created when calling StringToken_GetFirst.
+*    @param     token         The handle returned by StringToken_GetFirst.
+*    @return    Nothing
+*/
+MOCKABLE_FUNCTION(, void, StringToken_Destroy, STRING_TOKEN_HANDLE, token);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif  /*STRING_TOKEN_H*/
Index: azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/inc/azure_c_shared_utility/string_tokenizer.h
===================================================================
--- azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/inc/azure_c_shared_utility/string_tokenizer.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/inc/azure_c_shared_utility/string_tokenizer.h	(revision 457)
@@ -0,0 +1,25 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+#ifndef STRING_TOKENIZER_H
+#define STRING_TOKENIZER_H
+
+#include "azure_c_shared_utility/strings.h"
+#include "umock_c/umock_c_prod.h"
+#include "azure_c_shared_utility/string_tokenizer_types.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+MOCKABLE_FUNCTION(, STRING_TOKENIZER_HANDLE, STRING_TOKENIZER_create, STRING_HANDLE, handle);
+MOCKABLE_FUNCTION(, STRING_TOKENIZER_HANDLE, STRING_TOKENIZER_create_from_char, const char*, input);
+MOCKABLE_FUNCTION(, int, STRING_TOKENIZER_get_next_token, STRING_TOKENIZER_HANDLE, t, STRING_HANDLE, output, const char*, delimiters);
+MOCKABLE_FUNCTION(, void, STRING_TOKENIZER_destroy, STRING_TOKENIZER_HANDLE, t);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif  /*STRING_TOKENIZER_H*/
Index: azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/inc/azure_c_shared_utility/string_tokenizer_types.h
===================================================================
--- azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/inc/azure_c_shared_utility/string_tokenizer_types.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/inc/azure_c_shared_utility/string_tokenizer_types.h	(revision 457)
@@ -0,0 +1,18 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+#ifndef STRING_TOKENIZER_TYPES_H
+#define STRING_TOKENIZER_TYPES_H
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+    typedef struct STRING_TOKEN_TAG* STRING_TOKENIZER_HANDLE;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif  /*STRING_TOKENIZER_TYPES_H*/
Index: azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/inc/azure_c_shared_utility/strings.h
===================================================================
--- azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/inc/azure_c_shared_utility/strings.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/inc/azure_c_shared_utility/strings.h	(revision 457)
@@ -0,0 +1,48 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+#ifndef STRINGS_H
+#define STRINGS_H
+
+#ifdef __cplusplus
+#include <cstddef>
+#else
+#include <stddef.h>
+#endif
+
+#include "umock_c/umock_c_prod.h"
+#include "azure_c_shared_utility/strings_types.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+MOCKABLE_FUNCTION(, STRING_HANDLE, STRING_new);
+MOCKABLE_FUNCTION(, STRING_HANDLE, STRING_clone, STRING_HANDLE, handle);
+MOCKABLE_FUNCTION(, STRING_HANDLE, STRING_construct, const char*, psz);
+MOCKABLE_FUNCTION(, STRING_HANDLE, STRING_construct_n, const char*, psz, size_t, n);
+MOCKABLE_FUNCTION(, STRING_HANDLE, STRING_new_with_memory, const char*, memory);
+MOCKABLE_FUNCTION(, STRING_HANDLE, STRING_new_quoted, const char*, source);
+MOCKABLE_FUNCTION(, STRING_HANDLE, STRING_new_JSON, const char*, source);
+MOCKABLE_FUNCTION(, STRING_HANDLE, STRING_from_byte_array, const unsigned char*, source, size_t, size);
+MOCKABLE_FUNCTION(, void, STRING_delete, STRING_HANDLE, handle);
+MOCKABLE_FUNCTION(, int, STRING_concat, STRING_HANDLE, handle, const char*, s2);
+MOCKABLE_FUNCTION(, int, STRING_concat_with_STRING, STRING_HANDLE, s1, STRING_HANDLE, s2);
+MOCKABLE_FUNCTION(, int, STRING_quote, STRING_HANDLE, handle);
+MOCKABLE_FUNCTION(, int, STRING_copy, STRING_HANDLE, s1, const char*, s2);
+MOCKABLE_FUNCTION(, int, STRING_copy_n, STRING_HANDLE, s1, const char*, s2, size_t, n);
+MOCKABLE_FUNCTION(, const char*, STRING_c_str, STRING_HANDLE, handle);
+MOCKABLE_FUNCTION(, int, STRING_empty, STRING_HANDLE, handle);
+MOCKABLE_FUNCTION(, size_t, STRING_length, STRING_HANDLE, handle);
+MOCKABLE_FUNCTION(, int, STRING_compare, STRING_HANDLE, s1, STRING_HANDLE, s2);
+MOCKABLE_FUNCTION(, int, STRING_replace, STRING_HANDLE, handle, char, target, char, replace);
+
+extern STRING_HANDLE STRING_construct_sprintf(const char* format, ...);
+extern int STRING_sprintf(STRING_HANDLE s1, const char* format, ...);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif  /*STRINGS_H*/
Index: azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/inc/azure_c_shared_utility/strings_types.h
===================================================================
--- azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/inc/azure_c_shared_utility/strings_types.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/inc/azure_c_shared_utility/strings_types.h	(revision 457)
@@ -0,0 +1,18 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+#ifndef STRINGS_TYPES_H
+#define STRINGS_TYPES_H
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+    typedef struct STRING_TAG* STRING_HANDLE;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif  /*STRINGS_TYPES_H*/
Index: azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/inc/azure_c_shared_utility/tcpsocketconnection_c.h
===================================================================
--- azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/inc/azure_c_shared_utility/tcpsocketconnection_c.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/inc/azure_c_shared_utility/tcpsocketconnection_c.h	(revision 457)
@@ -0,0 +1,28 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+#ifndef TCPSOCKETCONNECTION_C_H
+#define TCPSOCKETCONNECTION_C_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+	typedef void* TCPSOCKETCONNECTION_HANDLE;
+
+	TCPSOCKETCONNECTION_HANDLE tcpsocketconnection_create(void);
+	void tcpsocketconnection_set_blocking(TCPSOCKETCONNECTION_HANDLE tcpSocketConnectionHandle, bool blocking, unsigned int timeout);
+	void tcpsocketconnection_destroy(TCPSOCKETCONNECTION_HANDLE tcpSocketConnectionHandle);
+	int tcpsocketconnection_connect(TCPSOCKETCONNECTION_HANDLE tcpSocketConnectionHandle, const char* host, const int port);
+	bool tcpsocketconnection_is_connected(TCPSOCKETCONNECTION_HANDLE tcpSocketConnectionHandle);
+	void tcpsocketconnection_close(TCPSOCKETCONNECTION_HANDLE tcpSocketConnectionHandle);
+	int tcpsocketconnection_send(TCPSOCKETCONNECTION_HANDLE tcpSocketConnectionHandle, const char* data, int length);
+	int tcpsocketconnection_send_all(TCPSOCKETCONNECTION_HANDLE tcpSocketConnectionHandle, const char* data, int length);
+	int tcpsocketconnection_receive(TCPSOCKETCONNECTION_HANDLE tcpSocketConnectionHandle, char* data, int length);
+	int tcpsocketconnection_receive_all(TCPSOCKETCONNECTION_HANDLE tcpSocketConnectionHandle, char* data, int length);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* TCPSOCKETCONNECTION_C_H */
Index: azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/inc/azure_c_shared_utility/threadapi.h
===================================================================
--- azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/inc/azure_c_shared_utility/threadapi.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/inc/azure_c_shared_utility/threadapi.h	(revision 457)
@@ -0,0 +1,90 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+/** @file threadapi.h
+ *	@brief	 This module implements support for creating new threads,
+ *			 terminating threads and sleeping threads.
+ */
+
+#ifndef THREADAPI_H
+#define THREADAPI_H
+
+#include "azure_macro_utils/macro_utils.h"
+#include "umock_c/umock_c_prod.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+    
+typedef int(*THREAD_START_FUNC)(void *);
+
+#define THREADAPI_RESULT_VALUES \
+    THREADAPI_OK,               \
+    THREADAPI_INVALID_ARG,      \
+    THREADAPI_NO_MEMORY,        \
+    THREADAPI_ERROR
+
+/** @brief Enumeration specifying the possible return values for the APIs in
+ *		   this module.
+ */
+MU_DEFINE_ENUM(THREADAPI_RESULT, THREADAPI_RESULT_VALUES);
+
+typedef void* THREAD_HANDLE;
+
+/**
+ * @brief	Creates a thread with the entry point specified by the @p func
+ * 			argument.
+ *
+ * @param   threadHandle	The handle to the new thread is returned in this
+ * 							pointer.
+ * @param	func			A function pointer that indicates the entry point
+ * 							to the new thread.
+ * @param   arg				A void pointer that must be passed to the function
+ * 							pointed to by @p func.
+ *
+ * @return	@c THREADAPI_OK if the API call is successful or an error
+ * 			code in case it fails.
+ */
+MOCKABLE_FUNCTION(, THREADAPI_RESULT, ThreadAPI_Create, THREAD_HANDLE*, threadHandle, THREAD_START_FUNC, func, void*, arg);
+
+/**
+ * @brief	Blocks the calling thread by waiting on the thread identified by
+ * 			the @p threadHandle argument to complete.
+ *
+ * @param	threadHandle	The handle of the thread to wait for completion.
+ * @param   res 			The result returned by the thread which is passed
+ * 							to the ::ThreadAPI_Exit function.
+ *
+ *			When the @p threadHandle thread completes, all resources associated
+ *			with the thread must be released and the thread handle will no
+ *			longer be valid.
+ * 
+ * @return	@c THREADAPI_OK if the API call is successful or an error
+ * 			code in case it fails.
+ */
+MOCKABLE_FUNCTION(, THREADAPI_RESULT, ThreadAPI_Join, THREAD_HANDLE, threadHandle, int*, res);
+
+/**
+ * @brief	This function is called by a thread when the thread exits.
+ *
+ * @param	res		An integer that represents the exit status of the thread.
+ * 				
+ * 			This function is called by a thread when the thread exits in order
+ * 			to return a result value to the caller of the ::ThreadAPI_Join
+ * 			function. The @p res value must be copied into the @p res out
+ * 			argument passed to the ::ThreadAPI_Join function.
+ */
+MOCKABLE_FUNCTION(, void, ThreadAPI_Exit, int, res);
+
+/**
+ * @brief	Sleeps the current thread for the given number of milliseconds.
+ *
+ * @param	milliseconds	The number of milliseconds to sleep.
+ */
+MOCKABLE_FUNCTION(, void, ThreadAPI_Sleep, unsigned int, milliseconds);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* THREADAPI_H */
Index: azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/inc/azure_c_shared_utility/tickcounter.h
===================================================================
--- azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/inc/azure_c_shared_utility/tickcounter.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/inc/azure_c_shared_utility/tickcounter.h	(revision 457)
@@ -0,0 +1,35 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+#ifndef TICKCOUNTER_H
+#define TICKCOUNTER_H
+
+#ifdef __cplusplus
+#include <cstdint>
+#else
+#include <stdint.h>
+#endif
+
+#include "umock_c/umock_c_prod.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif /* __cplusplus */
+
+#if defined(_WIN32) || defined(__MBED__) || defined(__APPLE__)
+    typedef uint_fast64_t tickcounter_ms_t; // Use 64-bit because of 32-bit is going to roll over back to zero after roughly 49.7 days that is not good for IoT devices which need keep running for months
+#else
+    typedef uint_fast32_t tickcounter_ms_t;
+#endif
+    typedef struct TICK_COUNTER_INSTANCE_TAG *TICK_COUNTER_HANDLE;
+
+    MOCKABLE_FUNCTION(, TICK_COUNTER_HANDLE, tickcounter_create);
+    MOCKABLE_FUNCTION(, void, tickcounter_destroy, TICK_COUNTER_HANDLE, tick_counter);
+    MOCKABLE_FUNCTION(, int, tickcounter_get_current_ms, TICK_COUNTER_HANDLE, tick_counter, tickcounter_ms_t *, current_ms);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* TICKCOUNTER_H */
Index: azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/inc/azure_c_shared_utility/tlsio.h
===================================================================
--- azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/inc/azure_c_shared_utility/tlsio.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/inc/azure_c_shared_utility/tlsio.h	(revision 457)
@@ -0,0 +1,25 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+#ifndef TLSIO_H
+#define TLSIO_H
+
+#include "xio.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+typedef struct TLSIO_CONFIG_TAG
+{
+    const char* hostname;
+    int port;
+    const IO_INTERFACE_DESCRIPTION* underlying_io_interface;
+    void* underlying_io_parameters;
+} TLSIO_CONFIG;
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* TLSIO_H */
Index: azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/inc/azure_c_shared_utility/tlsio_esp_at.h
===================================================================
--- azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/inc/azure_c_shared_utility/tlsio_esp_at.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/inc/azure_c_shared_utility/tlsio_esp_at.h	(revision 457)
@@ -0,0 +1,33 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+#ifndef TLSIO_ESP_AT_H
+#define TLSIO_ESP_AT_H
+
+#include "azure_c_shared_utility/xio.h"
+#include "azure_c_shared_utility/xlogging.h"
+#include "umock_c/umock_c_prod.h"
+#include "azure_c_shared_utility/const_defines.h"
+
+#ifdef __cplusplus
+extern "C" {
+#include <cstddef>
+#else
+#include <stddef.h>
+#endif /* __cplusplus */
+
+MOCKABLE_FUNCTION(, CONCRETE_IO_HANDLE, tlsio_esp_at_create, void*, io_create_parameters);
+MOCKABLE_FUNCTION(, void, tlsio_esp_at_destroy, CONCRETE_IO_HANDLE, tls_io);
+MOCKABLE_FUNCTION(, int, tlsio_esp_at_open, CONCRETE_IO_HANDLE, tls_io, ON_IO_OPEN_COMPLETE, on_io_open_complete, void*, on_io_open_complete_context, ON_BYTES_RECEIVED, on_bytes_received, void*, on_bytes_received_context, ON_IO_ERROR, on_io_error, void*, on_io_error_context);
+MOCKABLE_FUNCTION(, int, tlsio_esp_at_close, CONCRETE_IO_HANDLE, tls_io, ON_IO_CLOSE_COMPLETE, on_io_close_complete, void*, callback_context);
+MOCKABLE_FUNCTION(, int, tlsio_esp_at_send, CONCRETE_IO_HANDLE, tls_io, const void*, buffer, size_t, size, ON_SEND_COMPLETE, on_send_complete, void*, callback_context);
+MOCKABLE_FUNCTION(, void, tlsio_esp_at_dowork, CONCRETE_IO_HANDLE, tls_io);
+MOCKABLE_FUNCTION(, int, tlsio_esp_at_setoption, CONCRETE_IO_HANDLE, tls_io, const char*, optionName, const void*, value);
+
+MOCKABLE_FUNCTION(, const IO_INTERFACE_DESCRIPTION*, tlsio_esp_at_get_interface_description);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* TLSIO_ESP_AT_H */
Index: azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/inc/azure_c_shared_utility/tlsio_mbedtls.h
===================================================================
--- azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/inc/azure_c_shared_utility/tlsio_mbedtls.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/inc/azure_c_shared_utility/tlsio_mbedtls.h	(revision 457)
@@ -0,0 +1,33 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+#ifndef TLSIO_MBEDTLS_H
+#define TLSIO_MBEDTLS_H
+
+#include "azure_c_shared_utility/xio.h"
+#include "umock_c/umock_c_prod.h"
+
+#ifdef __cplusplus
+extern "C" {
+#include <cstddef>
+#else
+#include <stddef.h>
+#endif /* __cplusplus */
+
+extern const IO_INTERFACE_DESCRIPTION* tlsio_mbedtls_get_interface_description(void);
+
+MOCKABLE_FUNCTION(, CONCRETE_IO_HANDLE, tlsio_mbedtls_create, void*, io_create_parameters);
+MOCKABLE_FUNCTION(, void, tlsio_mbedtls_destroy, CONCRETE_IO_HANDLE, tls_io);
+MOCKABLE_FUNCTION(, int, tlsio_mbedtls_open, CONCRETE_IO_HANDLE, tls_io, ON_IO_OPEN_COMPLETE, on_io_open_complete, void*, on_io_open_complete_context, ON_BYTES_RECEIVED, on_bytes_received, void*, on_bytes_received_context, ON_IO_ERROR, on_io_error, void*, on_io_error_context);
+MOCKABLE_FUNCTION(, int, tlsio_mbedtls_close, CONCRETE_IO_HANDLE, tls_io, ON_IO_CLOSE_COMPLETE, on_io_close_complete, void*, callback_context);
+MOCKABLE_FUNCTION(, int, tlsio_mbedtls_send, CONCRETE_IO_HANDLE, tls_io, const void*, buffer, size_t, size, ON_SEND_COMPLETE, on_send_complete, void*, callback_context);
+MOCKABLE_FUNCTION(, void, tlsio_mbedtls_dowork, CONCRETE_IO_HANDLE, tls_io);
+MOCKABLE_FUNCTION(, int, tlsio_mbedtls_setoption, CONCRETE_IO_HANDLE, tls_io, const char*, optionName, const void*, value);
+
+MOCKABLE_FUNCTION(, const IO_INTERFACE_DESCRIPTION*, tlsio_mbedtls_get_interface_description);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* TLSIO_MBEDTLS_H */
Index: azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/inc/azure_c_shared_utility/tlsio_wolfssl.h
===================================================================
--- azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/inc/azure_c_shared_utility/tlsio_wolfssl.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/inc/azure_c_shared_utility/tlsio_wolfssl.h	(revision 457)
@@ -0,0 +1,35 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+#ifndef TLSIO_WOLFSSL_H
+#define TLSIO_WOLFSSL_H
+
+#include "azure_c_shared_utility/xio.h"
+#include "azure_c_shared_utility/xlogging.h"
+#include "umock_c/umock_c_prod.h"
+#include "azure_c_shared_utility/const_defines.h"
+
+#ifdef __cplusplus
+extern "C" {
+#include <cstddef>
+#else
+#include <stddef.h>
+#endif /* __cplusplus */
+
+extern const char* const OPTION_WOLFSSL_SET_DEVICE_ID;
+
+MOCKABLE_FUNCTION(, CONCRETE_IO_HANDLE, tlsio_wolfssl_create, void*, io_create_parameters);
+MOCKABLE_FUNCTION(, void, tlsio_wolfssl_destroy, CONCRETE_IO_HANDLE, tls_io);
+MOCKABLE_FUNCTION(, int, tlsio_wolfssl_open, CONCRETE_IO_HANDLE, tls_io, ON_IO_OPEN_COMPLETE, on_io_open_complete, void*, on_io_open_complete_context, ON_BYTES_RECEIVED, on_bytes_received, void*, on_bytes_received_context, ON_IO_ERROR, on_io_error, void*, on_io_error_context);
+MOCKABLE_FUNCTION(, int, tlsio_wolfssl_close, CONCRETE_IO_HANDLE, tls_io, ON_IO_CLOSE_COMPLETE, on_io_close_complete, void*, callback_context);
+MOCKABLE_FUNCTION(, int, tlsio_wolfssl_send, CONCRETE_IO_HANDLE, tls_io, const void*, buffer, size_t, size, ON_SEND_COMPLETE, on_send_complete, void*, callback_context);
+MOCKABLE_FUNCTION(, void, tlsio_wolfssl_dowork, CONCRETE_IO_HANDLE, tls_io);
+MOCKABLE_FUNCTION(, int, tlsio_wolfssl_setoption, CONCRETE_IO_HANDLE, tls_io, const char*, optionName, const void*, value);
+
+MOCKABLE_FUNCTION(, const IO_INTERFACE_DESCRIPTION*, tlsio_wolfssl_get_interface_description);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* TLSIO_WOLFSSL_H */
Index: azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/inc/azure_c_shared_utility/uniqueid.h
===================================================================
--- azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/inc/azure_c_shared_utility/uniqueid.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/inc/azure_c_shared_utility/uniqueid.h	(revision 457)
@@ -0,0 +1,33 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+#ifndef UNIQUEID_H
+#define UNIQUEID_H
+
+#ifdef __cplusplus
+#include <cstddef>
+#else
+#include <stddef.h>
+#endif
+
+#include "azure_macro_utils/macro_utils.h"
+#include "umock_c/umock_c_prod.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define UNIQUEID_RESULT_VALUES    \
+    UNIQUEID_OK,                  \
+    UNIQUEID_INVALID_ARG,         \
+    UNIQUEID_ERROR
+
+    MU_DEFINE_ENUM(UNIQUEID_RESULT, UNIQUEID_RESULT_VALUES)
+
+        MOCKABLE_FUNCTION(, UNIQUEID_RESULT, UniqueId_Generate, char*, uid, size_t, bufferSize);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* UNIQUEID_H */
Index: azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/inc/azure_c_shared_utility/urlencode.h
===================================================================
--- azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/inc/azure_c_shared_utility/urlencode.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/inc/azure_c_shared_utility/urlencode.h	(revision 457)
@@ -0,0 +1,44 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+#ifndef URLENCODE_H
+#define URLENCODE_H
+
+#include "azure_c_shared_utility/strings.h"
+#include "umock_c/umock_c_prod.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+    /* @brief   URL Encode (aka percent encode) a string.
+    * Please note that while the URL encoder accepts the full range of 8-bit extended ASCII,
+    * it has unpredictable behavior beyond the 7-bit ASCII standard. This function does NOT
+    * guarantee correctness of output for characters outside this range.
+    *
+    * @param    URL Encode can be done on a const char* or a STRING_HANDLE, use the appropriate
+    * function depending on input type, they both behave the same way.
+    *
+    * @return   Returns a STRING_HANDLE with the encoded string, or NULL on failure.
+    */
+    MOCKABLE_FUNCTION(, STRING_HANDLE, URL_Encode, STRING_HANDLE, input);
+    MOCKABLE_FUNCTION(, STRING_HANDLE, URL_EncodeString, const char*, textEncode);
+
+    /* @brief   URL Decode (aka percent decode) a string.
+    * Please note that the URL decoder only supports decoding characters that fall within the
+    * 7-bit ASCII range. It does NOT support 8-bit extended ASCII, and will fail if you try.
+    *
+    * @param    URL Decode can be done on a const char* or a STRING_HANDLE, use the appropriate
+    * function depending on input type, they both behave the same way.
+    *
+    * @return   Returns a STRING_HANDLE with the decoded string, or NULL on failure.
+    */
+    MOCKABLE_FUNCTION(, STRING_HANDLE, URL_Decode, STRING_HANDLE, input);
+    MOCKABLE_FUNCTION(, STRING_HANDLE, URL_DecodeString, const char*, textDecode);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* URLENCODE_H */
+
Index: azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/inc/azure_c_shared_utility/utf8_checker.h
===================================================================
--- azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/inc/azure_c_shared_utility/utf8_checker.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/inc/azure_c_shared_utility/utf8_checker.h	(revision 457)
@@ -0,0 +1,26 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+#ifndef UTF8_CHECKER_H
+#define UTF8_CHECKER_H
+
+#ifdef __cplusplus
+#include <cstddef>
+#else
+#include <stdbool.h>
+#include <stddef.h>
+#endif
+
+#include "umock_c/umock_c_prod.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+MOCKABLE_FUNCTION(, bool, utf8_checker_is_valid_utf8, const unsigned char*, utf8_str, size_t, length);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* UTF8_CHECKER_H */
Index: azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/inc/azure_c_shared_utility/uuid.h
===================================================================
--- azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/inc/azure_c_shared_utility/uuid.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/inc/azure_c_shared_utility/uuid.h	(revision 457)
@@ -0,0 +1,61 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+#ifndef UUID_H
+#define UUID_H
+
+#ifdef __cplusplus
+#include <cstddef>
+#include <cstdint>
+#else
+#include <stddef.h>
+#include <stdint.h>
+#include <stdbool.h>
+#endif /* __cplusplus */
+
+#include "umock_c/umock_c_prod.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+typedef unsigned char UUID_T[16];
+
+/* These 2 strings can be conveniently used directly in printf statements
+  Notice that PRI_UUID has to be used like any other print format specifier, meaning it
+  has to be preceded with % */
+#define PRI_UUID        "02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x"
+#define UUID_FORMAT_VALUES(uuid) \
+    (uuid)[0], (uuid)[1], (uuid)[2], (uuid)[3], (uuid)[4], (uuid)[5], (uuid)[6], (uuid)[7], \
+    (uuid)[8], (uuid)[9], (uuid)[10], (uuid)[11], (uuid)[12], (uuid)[13], (uuid)[14], (uuid)[15]
+
+#define UUID_FORMAT_VALUES_OR_NULL(uuid) \
+    ((uuid) == NULL) ? 0 : (uuid)[0], ((uuid) == NULL) ? 0 : (uuid)[1], ((uuid) == NULL) ? 0 : (uuid)[2], ((uuid) == NULL) ? 0 : (uuid)[3], \
+    ((uuid) == NULL) ? 0 : (uuid)[4], ((uuid) == NULL) ? 0 : (uuid)[5], ((uuid) == NULL) ? 0 : (uuid)[6], ((uuid) == NULL) ? 0 : (uuid)[7], \
+    ((uuid) == NULL) ? 0 : (uuid)[8], ((uuid) == NULL) ? 0 : (uuid)[9], ((uuid) == NULL) ? 0 : (uuid)[10], ((uuid) == NULL) ? 0 : (uuid)[11], \
+    ((uuid) == NULL) ? 0 : (uuid)[12], ((uuid) == NULL) ? 0 : (uuid)[13], ((uuid) == NULL) ? 0 : (uuid)[14], ((uuid) == NULL) ? 0 : (uuid)[15] \
+
+/* @brief               Generates a true UUID
+*  @param uuid          A pre-allocated buffer for the bytes of the generated UUID
+*  @returns             Zero if no failures occur, non-zero otherwise.
+*/
+MOCKABLE_FUNCTION(, int, UUID_generate, UUID_T*, uuid);
+
+/* @brief               Gets the UUID value (byte sequence) of an well-formed UUID string.
+*  @param uuid_string   A null-terminated well-formed UUID string (e.g., "7f907d75-5e13-44cf-a1a3-19a01a2b4528").
+*  @param uuid          Sequence of bytes representing an UUID.
+*  @returns             Zero if no failures occur, non-zero otherwise.
+*/
+MOCKABLE_FUNCTION(, int, UUID_from_string, const char*, uuid_string, UUID_T*, uuid);
+
+/* @brief               Gets the string representation of the UUID value.
+*  @param uuid          Sequence of bytes representing an UUID.
+*  @returns             A null-terminated string representation of the UUID value provided (e.g., "7f907d75-5e13-44cf-a1a3-19a01a2b4528").
+*/
+MOCKABLE_FUNCTION(, char*, UUID_to_string, const UUID_T*, uuid);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* UUID_H */
Index: azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/inc/azure_c_shared_utility/uws_client.h
===================================================================
--- azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/inc/azure_c_shared_utility/uws_client.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/inc/azure_c_shared_utility/uws_client.h	(revision 457)
@@ -0,0 +1,121 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+#ifndef UWS_CLIENT_H
+#define UWS_CLIENT_H
+
+#ifdef __cplusplus
+#include <cstddef>
+#include <cstdint>
+#else
+#include <stdbool.h>
+#include <stddef.h>
+#include <stdint.h>
+#endif
+
+#include "xio.h"
+#include "umock_c/umock_c_prod.h"
+#include "azure_c_shared_utility/optionhandler.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct UWS_CLIENT_INSTANCE_TAG* UWS_CLIENT_HANDLE;
+
+#define WS_SEND_FRAME_RESULT_VALUES \
+    WS_SEND_FRAME_OK, \
+    WS_SEND_FRAME_ERROR, \
+    WS_SEND_FRAME_CANCELLED
+
+MU_DEFINE_ENUM(WS_SEND_FRAME_RESULT, WS_SEND_FRAME_RESULT_VALUES);
+
+#define WS_OPEN_RESULT_VALUES \
+    WS_OPEN_OK, \
+    WS_OPEN_ERROR_UNDERLYING_IO_OPEN_FAILED, \
+    WS_OPEN_ERROR_UNDERLYING_IO_OPEN_CANCELLED, \
+    WS_OPEN_ERROR_NOT_ENOUGH_MEMORY, \
+    WS_OPEN_ERROR_CANNOT_CONSTRUCT_UPGRADE_REQUEST, \
+    WS_OPEN_ERROR_CANNOT_SEND_UPGRADE_REQUEST, \
+    WS_OPEN_ERROR_MULTIPLE_UNDERLYING_IO_OPEN_EVENTS, \
+    WS_OPEN_ERROR_CONSTRUCTING_UPGRADE_REQUEST, \
+    WS_OPEN_ERROR_INVALID_BYTES_RECEIVED_ARGUMENTS, \
+    WS_OPEN_ERROR_BYTES_RECEIVED_BEFORE_UNDERLYING_OPEN, \
+    WS_OPEN_CANCELLED, \
+    WS_OPEN_ERROR_UNDERLYING_IO_ERROR, \
+    WS_OPEN_ERROR_BAD_UPGRADE_RESPONSE, \
+    WS_OPEN_ERROR_BAD_RESPONSE_STATUS, \
+    WS_OPEN_ERROR_BASE64_ENCODE_FAILED
+
+MU_DEFINE_ENUM(WS_OPEN_RESULT, WS_OPEN_RESULT_VALUES);
+
+#define WS_ERROR_VALUES \
+    WS_ERROR_NOT_ENOUGH_MEMORY, \
+    WS_ERROR_BAD_FRAME_RECEIVED, \
+    WS_ERROR_CANNOT_REMOVE_SENT_ITEM_FROM_LIST, \
+    WS_ERROR_UNDERLYING_IO_ERROR, \
+    WS_ERROR_CANNOT_CLOSE_UNDERLYING_IO
+
+MU_DEFINE_ENUM(WS_ERROR, WS_ERROR_VALUES);
+
+#define WS_FRAME_TYPE_UNKNOWN       0x00
+#define WS_FRAME_TYPE_TEXT          0x01
+#define WS_FRAME_TYPE_BINARY        0x02
+
+/* Codes_SRS_UWS_CLIENT_01_324: [ 1000 indicates a normal closure, meaning that the purpose for which the connection was established has been fulfilled. ]*/
+/* Codes_SRS_UWS_CLIENT_01_325: [ 1001 indicates that an endpoint is "going away", such as a server going down or a browser having navigated away from a page. ]*/
+/* Codes_SRS_UWS_CLIENT_01_326: [ 1002 indicates that an endpoint is terminating the connection due to a protocol error. ]*/
+/* Codes_SRS_UWS_CLIENT_01_327: [ 1003 indicates that an endpoint is terminating the connection because it has received a type of data it cannot accept (e.g., an endpoint that understands only text data MAY send this if it receives a binary message). ]*/
+/* Codes_SRS_UWS_CLIENT_01_328: [ Reserved.  The specific meaning might be defined in the future. ]*/
+/* Codes_SRS_UWS_CLIENT_01_329: [ 1005 is a reserved value and MUST NOT be set as a status code in a Close control frame by an endpoint. ]*/
+/* Codes_SRS_UWS_CLIENT_01_330: [ 1006 is a reserved value and MUST NOT be set as a status code in a Close control frame by an endpoint. ]*/
+/* Codes_SRS_UWS_CLIENT_01_331: [ 1007 indicates that an endpoint is terminating the connection because it has received data within a message that was not consistent with the type of the message (e.g., non-UTF-8 [RFC3629] data within a text message). ]*/
+/* Codes_SRS_UWS_CLIENT_01_332: [ 1008 indicates that an endpoint is terminating the connection because it has received a message that violates its policy. ]*/
+/* Codes_SRS_UWS_CLIENT_01_333: [ 1009 indicates that an endpoint is terminating the connection because it has received a message that is too big for it to process. ]*/
+/* Codes_SRS_UWS_CLIENT_01_334: [ 1010 indicates that an endpoint (client) is terminating the connection because it has expected the server to negotiate one or more extension, but the server didn't return them in the response message of the WebSocket handshake. ]*/
+/* Codes_SRS_UWS_CLIENT_01_336: [ 1011 indicates that a server is terminating the connection because it encountered an unexpected condition that prevented it from fulfilling the request. ]*/
+/* Codes_SRS_UWS_CLIENT_01_337: [ 1015 is a reserved value and MUST NOT be set as a status code in a Close control frame by an endpoint. ]*/
+/*  */
+#define CLOSE_NORMAL                        1000
+#define CLOSE_GOING_AWAY                    1001
+#define CLOSE_PROTOCOL_ERROR                1002
+#define CLOSE_CANNOT_ACCEPT_DATA_TYPE       1003
+#define CLOSE_UNDEFINED_1004                1004
+#define CLOSE_RESERVED_1005                 1005
+#define CLOSE_RESERVED_1006                 1006
+#define CLOSE_INCONSISTENT_DATA_IN_MESSAGE  1007
+#define CLOSE_POLICY_VIOLATION              1008
+#define CLOSE_MESSAGE_TOO_BIG               1009
+#define CLOSE_UNSUPPORTED_EXTENSION_LIST    1010
+#define CLOSE_UNEXPECTED_CONDITION          1011
+#define CLOSE_RESERVED_1015                 1015
+
+typedef void(*ON_WS_FRAME_RECEIVED)(void* context, unsigned char frame_type, const unsigned char* buffer, size_t size);
+typedef void(*ON_WS_SEND_FRAME_COMPLETE)(void* context, WS_SEND_FRAME_RESULT ws_send_frame_result);
+typedef void(*ON_WS_OPEN_COMPLETE)(void* context, WS_OPEN_RESULT ws_open_result);
+typedef void(*ON_WS_CLOSE_COMPLETE)(void* context);
+typedef void(*ON_WS_PEER_CLOSED)(void* context, uint16_t* close_code, const unsigned char* extra_data, size_t extra_data_length);
+typedef void(*ON_WS_ERROR)(void* context, WS_ERROR error_code);
+
+typedef struct WS_PROTOCOL_TAG
+{
+    const char* protocol;
+} WS_PROTOCOL;
+
+MOCKABLE_FUNCTION(, UWS_CLIENT_HANDLE, uws_client_create, const char*, hostname, unsigned int, port, const char*, resource_name, bool, use_ssl, const WS_PROTOCOL*, protocols, size_t, protocol_count);
+MOCKABLE_FUNCTION(, UWS_CLIENT_HANDLE, uws_client_create_with_io, const IO_INTERFACE_DESCRIPTION*, io_interface, void*, io_create_parameters, const char*, hostname, unsigned int, port, const char*, resource_name, const WS_PROTOCOL*, protocols, size_t, protocol_count)
+MOCKABLE_FUNCTION(, void, uws_client_destroy, UWS_CLIENT_HANDLE, uws_client);
+MOCKABLE_FUNCTION(, int, uws_client_open_async, UWS_CLIENT_HANDLE, uws_client, ON_WS_OPEN_COMPLETE, on_ws_open_complete, void*, on_ws_open_complete_context, ON_WS_FRAME_RECEIVED, on_ws_frame_received, void*, on_ws_frame_received_context, ON_WS_PEER_CLOSED, on_ws_peer_closed, void*, on_ws_peer_closed_context, ON_WS_ERROR, on_ws_error, void*, on_ws_error_context);
+MOCKABLE_FUNCTION(, int, uws_client_close_async, UWS_CLIENT_HANDLE, uws_client, ON_WS_CLOSE_COMPLETE, on_ws_close_complete, void*, on_ws_close_complete_context);
+MOCKABLE_FUNCTION(, int, uws_client_close_handshake_async, UWS_CLIENT_HANDLE, uws_client, uint16_t, close_code, const char*, close_reason, ON_WS_CLOSE_COMPLETE, on_ws_close_complete, void*, on_ws_close_complete_context);
+MOCKABLE_FUNCTION(, int, uws_client_send_frame_async, UWS_CLIENT_HANDLE, uws_client, unsigned char, frame_type, const unsigned char*, buffer, size_t, size, bool, is_final, ON_WS_SEND_FRAME_COMPLETE, on_ws_send_frame_complete, void*, callback_context);
+MOCKABLE_FUNCTION(, void, uws_client_dowork, UWS_CLIENT_HANDLE, uws_client);
+MOCKABLE_FUNCTION(, int, uws_client_set_request_header, UWS_CLIENT_HANDLE, uws_client, const char*, name, const char*, value);
+MOCKABLE_FUNCTION(, int, uws_client_set_option, UWS_CLIENT_HANDLE, uws_client, const char*, option_name, const void*, value);
+MOCKABLE_FUNCTION(, OPTIONHANDLER_HANDLE, uws_client_retrieve_options, UWS_CLIENT_HANDLE, uws_client);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* UWS_CLIENT_H */
Index: azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/inc/azure_c_shared_utility/uws_frame_encoder.h
===================================================================
--- azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/inc/azure_c_shared_utility/uws_frame_encoder.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/inc/azure_c_shared_utility/uws_frame_encoder.h	(revision 457)
@@ -0,0 +1,52 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+#ifndef UWS_FRAME_ENCODER_H
+#define UWS_FRAME_ENCODER_H
+
+#ifdef __cplusplus
+#include <cstddef>
+#else
+#include <stdbool.h>
+#include <stddef.h>
+#endif
+
+#include "azure_c_shared_utility/buffer_.h"
+#include "umock_c/umock_c_prod.h"
+#include "azure_macro_utils/macro_utils.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define RESERVED_1  0x04
+#define RESERVED_2  0x02
+#define RESERVED_3  0x01
+
+#define WS_FRAME_TYPE_VALUES \
+    WS_CONTINUATION_FRAME, \
+    WS_TEXT_FRAME, \
+    WS_BINARY_FRAME, \
+    WS_RESERVED_NON_CONTROL_FRAME_3, \
+    WS_RESERVED_NON_CONTROL_FRAME_4, \
+    WS_RESERVED_NON_CONTROL_FRAME_5, \
+    WS_RESERVED_NON_CONTROL_FRAME_6, \
+    WS_RESERVED_NON_CONTROL_FRAME_7, \
+    WS_CLOSE_FRAME, \
+    WS_PING_FRAME, \
+    WS_PONG_FRAME, \
+    WS_RESERVED_CONTROL_FRAME_B, \
+    WS_RESERVED_CONTROL_FRAME_C, \
+    WS_RESERVED_CONTROL_FRAME_D, \
+    WS_RESERVED_CONTROL_FRAME_E, \
+    WS_RESERVED_CONTROL_FRAME_F
+
+MU_DEFINE_ENUM_WITHOUT_INVALID(WS_FRAME_TYPE, WS_FRAME_TYPE_VALUES);
+
+MOCKABLE_FUNCTION(, BUFFER_HANDLE, uws_frame_encoder_encode, WS_FRAME_TYPE, opcode, const unsigned char*, payload, size_t, length, bool, is_masked, bool, is_final, unsigned char, reserved);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* UWS_FRAME_ENCODER_H */
Index: azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/inc/azure_c_shared_utility/vector.h
===================================================================
--- azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/inc/azure_c_shared_utility/vector.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/inc/azure_c_shared_utility/vector.h	(revision 457)
@@ -0,0 +1,49 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+#ifndef VECTOR_H
+#define VECTOR_H
+
+#ifdef __cplusplus
+#include <cstddef>
+#else
+#include <stddef.h>
+#include <stdbool.h>
+#endif
+
+#include "azure_c_shared_utility/crt_abstractions.h"
+#include "umock_c/umock_c_prod.h"
+#include "azure_c_shared_utility/vector_types.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+MOCKABLE_INTERFACE(vector,
+    /* creation */
+    FUNCTION(, VECTOR_HANDLE, VECTOR_create, size_t, elementSize),
+    FUNCTION(, VECTOR_HANDLE, VECTOR_move, VECTOR_HANDLE, handle),
+    FUNCTION(, void, VECTOR_destroy, VECTOR_HANDLE, handle),
+
+    /* insertion */
+    FUNCTION(, int, VECTOR_push_back, VECTOR_HANDLE, handle, const void*, elements, size_t, numElements),
+
+    /* removal */
+    FUNCTION(, void, VECTOR_erase, VECTOR_HANDLE, handle, void*, elements, size_t, numElements),
+    FUNCTION(, void, VECTOR_clear, VECTOR_HANDLE, handle),
+
+    /* access */
+    FUNCTION(, void*, VECTOR_element, VECTOR_HANDLE, handle, size_t, index),
+    FUNCTION(, void*, VECTOR_front, VECTOR_HANDLE, handle),
+    FUNCTION(, void*, VECTOR_back, VECTOR_HANDLE, handle),
+    FUNCTION(, void*, VECTOR_find_if, VECTOR_HANDLE, handle, PREDICATE_FUNCTION, pred, const void*, value),
+
+    /* capacity */
+    FUNCTION(, size_t, VECTOR_size, VECTOR_HANDLE, handle)
+)
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* VECTOR_H */
Index: azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/inc/azure_c_shared_utility/vector_types.h
===================================================================
--- azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/inc/azure_c_shared_utility/vector_types.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/inc/azure_c_shared_utility/vector_types.h	(revision 457)
@@ -0,0 +1,25 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+#ifndef VECTOR_TYPES_H
+#define VECTOR_TYPES_H
+
+#ifdef __cplusplus
+#else
+#include <stdbool.h>
+#endif
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+typedef struct VECTOR_TAG* VECTOR_HANDLE;
+
+typedef bool(*PREDICATE_FUNCTION)(const void* element, const void* value);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* VECTOR_TYPES_H */
Index: azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/inc/azure_c_shared_utility/vector_types_internal.h
===================================================================
--- azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/inc/azure_c_shared_utility/vector_types_internal.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/inc/azure_c_shared_utility/vector_types_internal.h	(revision 457)
@@ -0,0 +1,29 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+#ifndef VECTOR_TYPES_INTERNAL_H
+#define VECTOR_TYPES_INTERNAL_H
+
+#ifdef __cplusplus
+#include <cstddef>
+#else
+#include <stddef.h>
+#endif
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+    typedef struct VECTOR_TAG
+    {
+        void* storage;
+        size_t count;
+        size_t elementSize;
+    } VECTOR;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* VECTOR_TYPES_INTERNAL_H */
Index: azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/inc/azure_c_shared_utility/wsio.h
===================================================================
--- azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/inc/azure_c_shared_utility/wsio.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/inc/azure_c_shared_utility/wsio.h	(revision 457)
@@ -0,0 +1,38 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+#ifndef WSIO_H
+#define WSIO_H
+
+#ifdef __cplusplus
+#include <cstddef>
+#else
+#include <stddef.h>
+#include <stdbool.h>
+#endif /* __cplusplus */
+
+#include "azure_c_shared_utility/xio.h"
+#include "azure_c_shared_utility/xlogging.h"
+#include "umock_c/umock_c_prod.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+typedef struct WSIO_CONFIG_TAG
+{
+    const IO_INTERFACE_DESCRIPTION* underlying_io_interface;
+    void* underlying_io_parameters;
+    const char* hostname;
+    int port;
+    const char* resource_name;
+    const char* protocol;
+} WSIO_CONFIG;
+
+MOCKABLE_FUNCTION(, const IO_INTERFACE_DESCRIPTION*, wsio_get_interface_description);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* WSIO_H */
Index: azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/inc/azure_c_shared_utility/xio.h
===================================================================
--- azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/inc/azure_c_shared_utility/xio.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/inc/azure_c_shared_utility/xio.h	(revision 457)
@@ -0,0 +1,80 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+#ifndef XIO_H
+#define XIO_H
+
+#ifdef __cplusplus
+#include <cstddef>
+#else
+#include <stddef.h>
+#endif /* __cplusplus */
+
+#include "azure_c_shared_utility/optionhandler.h"
+
+#include "umock_c/umock_c_prod.h"
+#include "azure_macro_utils/macro_utils.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+typedef struct XIO_INSTANCE_TAG* XIO_HANDLE;
+typedef void* CONCRETE_IO_HANDLE;
+
+#define IO_SEND_RESULT_VALUES \
+    IO_SEND_OK, \
+    IO_SEND_ERROR, \
+    IO_SEND_CANCELLED
+
+MU_DEFINE_ENUM(IO_SEND_RESULT, IO_SEND_RESULT_VALUES);
+
+#define IO_OPEN_RESULT_VALUES \
+    IO_OPEN_OK, \
+    IO_OPEN_ERROR, \
+    IO_OPEN_CANCELLED
+
+MU_DEFINE_ENUM(IO_OPEN_RESULT, IO_OPEN_RESULT_VALUES);
+
+typedef void(*ON_BYTES_RECEIVED)(void* context, const unsigned char* buffer, size_t size);
+typedef void(*ON_SEND_COMPLETE)(void* context, IO_SEND_RESULT send_result);
+typedef void(*ON_IO_OPEN_COMPLETE)(void* context, IO_OPEN_RESULT open_result);
+typedef void(*ON_IO_CLOSE_COMPLETE)(void* context);
+typedef void(*ON_IO_ERROR)(void* context);
+
+typedef OPTIONHANDLER_HANDLE (*IO_RETRIEVEOPTIONS)(CONCRETE_IO_HANDLE concrete_io);
+typedef CONCRETE_IO_HANDLE(*IO_CREATE)(void* io_create_parameters);
+typedef void(*IO_DESTROY)(CONCRETE_IO_HANDLE concrete_io);
+typedef int(*IO_OPEN)(CONCRETE_IO_HANDLE concrete_io, ON_IO_OPEN_COMPLETE on_io_open_complete, void* on_io_open_complete_context, ON_BYTES_RECEIVED on_bytes_received, void* on_bytes_received_context, ON_IO_ERROR on_io_error, void* on_io_error_context);
+typedef int(*IO_CLOSE)(CONCRETE_IO_HANDLE concrete_io, ON_IO_CLOSE_COMPLETE on_io_close_complete, void* callback_context);
+typedef int(*IO_SEND)(CONCRETE_IO_HANDLE concrete_io, const void* buffer, size_t size, ON_SEND_COMPLETE on_send_complete, void* callback_context);
+typedef void(*IO_DOWORK)(CONCRETE_IO_HANDLE concrete_io);
+typedef int(*IO_SETOPTION)(CONCRETE_IO_HANDLE concrete_io, const char* optionName, const void* value);
+
+
+typedef struct IO_INTERFACE_DESCRIPTION_TAG
+{
+    IO_RETRIEVEOPTIONS concrete_io_retrieveoptions;
+    IO_CREATE concrete_io_create;
+    IO_DESTROY concrete_io_destroy;
+    IO_OPEN concrete_io_open;
+    IO_CLOSE concrete_io_close;
+    IO_SEND concrete_io_send;
+    IO_DOWORK concrete_io_dowork;
+    IO_SETOPTION concrete_io_setoption;
+} IO_INTERFACE_DESCRIPTION;
+
+MOCKABLE_FUNCTION(, XIO_HANDLE, xio_create, const IO_INTERFACE_DESCRIPTION*, io_interface_description, const void*, io_create_parameters);
+MOCKABLE_FUNCTION(, void, xio_destroy, XIO_HANDLE, xio);
+MOCKABLE_FUNCTION(, int, xio_open, XIO_HANDLE, xio, ON_IO_OPEN_COMPLETE, on_io_open_complete, void*, on_io_open_complete_context, ON_BYTES_RECEIVED, on_bytes_received, void*, on_bytes_received_context, ON_IO_ERROR, on_io_error, void*, on_io_error_context);
+MOCKABLE_FUNCTION(, int, xio_close, XIO_HANDLE, xio, ON_IO_CLOSE_COMPLETE, on_io_close_complete, void*, callback_context);
+MOCKABLE_FUNCTION(, int, xio_send, XIO_HANDLE, xio, const void*, buffer, size_t, size, ON_SEND_COMPLETE, on_send_complete, void*, callback_context);
+MOCKABLE_FUNCTION(, void, xio_dowork, XIO_HANDLE, xio);
+MOCKABLE_FUNCTION(, int, xio_setoption, XIO_HANDLE, xio, const char*, optionName, const void*, value);
+MOCKABLE_FUNCTION(, OPTIONHANDLER_HANDLE, xio_retrieveoptions, XIO_HANDLE, xio);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* XIO_H */
Index: azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/inc/azure_c_shared_utility/xlogging.h
===================================================================
--- azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/inc/azure_c_shared_utility/xlogging.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/inc/azure_c_shared_utility/xlogging.h	(revision 457)
@@ -0,0 +1,228 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+#ifndef XLOGGING_H
+#define XLOGGING_H
+
+#ifdef __cplusplus
+#include <cstdlib>
+#else
+#include <stdlib.h>
+#endif
+
+#include "azure_macro_utils/macro_utils.h"
+
+#include "azure_c_shared_utility/agenttime.h"
+#include "azure_c_shared_utility/optimize_size.h"
+
+#ifdef LOGERROR_CAPTURES_STACK_TRACES
+#include "azure_c_shared_utility/logging_stacktrace.h"
+#endif
+
+#if defined(ESP8266_RTOS)
+#include "c_types.h"
+#endif
+
+#if defined(ARDUINO_ARCH_ESP8266)
+#include "esp8266/azcpgmspace.h"
+#endif
+
+#ifdef __cplusplus
+/* Some compilers do not want to play by the standard, specifically ARM CC */
+#ifdef MBED_BUILD_TIMESTAMP
+#include <stdio.h>
+#else
+#include <cstdio>
+#endif
+#else
+#include <stdio.h>
+#endif /* __cplusplus */
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+#ifdef TIZENRT
+#undef LOG_INFO
+#endif
+
+typedef enum LOG_CATEGORY_TAG
+{
+    AZ_LOG_ERROR,
+    AZ_LOG_INFO,
+    AZ_LOG_TRACE
+} LOG_CATEGORY;
+
+#if defined _MSC_VER
+#define FUNC_NAME __FUNCDNAME__
+#else
+#define FUNC_NAME __func__
+#endif
+
+typedef void(*LOGGER_LOG)(LOG_CATEGORY log_category, const char* file, const char* func, int line, unsigned int options, const char* format, ...);
+typedef void(*LOGGER_LOG_GETLASTERROR)(const char* file, const char* func, int line, const char* format, ...);
+
+#define TEMP_BUFFER_SIZE 1024
+#define MESSAGE_BUFFER_SIZE 260
+
+#define LOG_NONE 0x00
+#define LOG_LINE 0x01
+
+/*no logging is useful when time and fprintf are mocked*/
+#ifdef NO_LOGGING
+#define LOG(...)
+#define LogInfo(...)
+#define LogBinary(...)
+#define LogError(...)
+#define LogLastError(...)
+#define xlogging_get_log_function() NULL
+#define xlogging_set_log_function(...)
+#define LogErrorWinHTTPWithGetLastErrorAsString(...)
+#define UNUSED(x) (void)(x)
+#elif (defined MINIMAL_LOGERROR)
+#define LOG(...)
+#define LogInfo(...)
+#define LogBinary(...)
+#define LogError(...) printf("error %s: line %d\n",__FILE__,__LINE__);
+#define xlogging_get_log_function() NULL
+#define xlogging_set_log_function(...)
+#define LogErrorWinHTTPWithGetLastErrorAsString(...)
+#define UNUSED(x) (void)(x)
+
+#elif defined(ESP8266_RTOS)
+#define LogInfo(FORMAT, ...) do {    \
+        static const char flash_str[] ICACHE_RODATA_ATTR STORE_ATTR = FORMAT;  \
+        printf(flash_str, ##__VA_ARGS__);   \
+        printf("\n");\
+    } while((void)0,0)
+
+#define LogError LogInfo
+#define LOG(log_category, log_options, FORMAT, ...)  { \
+        static const char flash_str[] ICACHE_RODATA_ATTR STORE_ATTR = (FORMAT); \
+        printf(flash_str, ##__VA_ARGS__); \
+        printf("\r\n"); \
+}
+
+#else /* NOT ESP8266_RTOS */
+
+// In order to make sure that the compiler evaluates the arguments and issues an error if they do not conform to printf
+// specifications, we call printf with the format and __VA_ARGS__. Since C && operator is shortcircuiting no actual runtime call to printf is performed.
+#if defined _MSC_VER
+#ifndef LOGERROR_CAPTURES_STACK_TRACES
+// ignore warning C4127 
+#define LOG(log_category, log_options, format, ...) \
+{ \
+    (void)(0 && printf(format, __VA_ARGS__)); \
+    { \
+        LOGGER_LOG l = xlogging_get_log_function(); \
+        if (l != NULL) \
+        { \
+            l(log_category, __FILE__, FUNC_NAME, __LINE__, log_options, format, __VA_ARGS__); \
+        } \
+    } \
+}
+#else /*LOGERROR_CAPTURES_STACK_TRACES is defined*/ 
+#define STACK_PRINT_FORMAT "\nStack:\n%s"
+
+#define LOG(log_category, log_options, format, ...) MU_C3(LOG,_,log_category)(log_category, log_options, format, __VA_ARGS__)
+
+#define LOG_AZ_LOG_ERROR(log_category, log_options, format, ...)                                                                                                        \
+{                                                                                                                                                                       \
+    (void)(0 && printf(format, __VA_ARGS__));                                                                                                                           \
+    {                                                                                                                                                                   \
+        LOGGER_LOG l = xlogging_get_log_function();                                                                                                                     \
+        if (l != NULL)                                                                                                                                                  \
+        {                                                                                                                                                               \
+            char* stackAsString = getStackAsString();                                                                                                                   \
+            if (stackAsString == NULL)                                                                                                                                  \
+            {                                                                                                                                                           \
+                l(log_category, __FILE__, FUNC_NAME, __LINE__, log_options, format, __VA_ARGS__);                                                                       \
+            }                                                                                                                                                           \
+            else                                                                                                                                                        \
+            {                                                                                                                                                           \
+                size_t formatSize = strlen(format);                                                                                                                     \
+                char* formatWithStack = (char*)logging_malloc(formatSize + sizeof("STACK_PRINT_FORMAT"));                                                               \
+                if (formatWithStack == NULL)                                                                                                                            \
+                {                                                                                                                                                       \
+                    l(log_category, __FILE__, FUNC_NAME, __LINE__, log_options, format, __VA_ARGS__);                                                                   \
+                }                                                                                                                                                       \
+                else                                                                                                                                                    \
+                {                                                                                                                                                       \
+                    (void)memcpy(formatWithStack, format, formatSize);                                                                                                  \
+                    (void)memcpy(formatWithStack + formatSize, STACK_PRINT_FORMAT, sizeof(STACK_PRINT_FORMAT));                                                         \
+                    l(log_category, __FILE__, FUNC_NAME, __LINE__, log_options, formatWithStack, __VA_ARGS__, stackAsString);                                           \
+                    logging_free(formatWithStack);                                                                                                                      \
+                }                                                                                                                                                       \
+                logging_free(stackAsString);                                                                                                                            \
+            }                                                                                                                                                           \
+        }                                                                                                                                                               \
+    }                                                                                                                                                                   \
+}
+
+#define LOG_AZ_LOG_TRACE LOG_AZ_LOG_INFO
+
+#define LOG_AZ_LOG_INFO(log_category, log_options, format, ...)                                                                                                         \
+{                                                                                                                                                                       \
+    (void)(0 && printf(format, __VA_ARGS__));                                                                                                                           \
+    {                                                                                                                                                                   \
+        LOGGER_LOG l = xlogging_get_log_function();                                                                                                                     \
+        if (l != NULL)                                                                                                                                                  \
+        {                                                                                                                                                               \
+            l(log_category, __FILE__, FUNC_NAME, __LINE__, log_options, format, __VA_ARGS__);                                                                           \
+        }                                                                                                                                                               \
+    }                                                                                                                                                                   \
+}
+
+#endif /*LOGERROR_CAPTURES_STACK_TRACES*/
+#else
+#define LOG(log_category, log_options, format, ...) { (void)(0 && printf(format, ##__VA_ARGS__)); { LOGGER_LOG l = xlogging_get_log_function(); if (l != NULL) l(log_category, __FILE__, FUNC_NAME, __LINE__, log_options, format, ##__VA_ARGS__); } }
+#endif
+
+#if defined _MSC_VER
+#define LogInfo(FORMAT, ...) do{LOG(AZ_LOG_INFO, LOG_LINE, FORMAT, __VA_ARGS__); }while((void)0,0)
+#else
+#define LogInfo(FORMAT, ...) do{LOG(AZ_LOG_INFO, LOG_LINE, FORMAT, ##__VA_ARGS__); }while((void)0,0)
+#endif
+
+#ifdef WIN32
+extern void xlogging_LogErrorWinHTTPWithGetLastErrorAsStringFormatter(int errorMessageID);
+#endif
+
+#if defined _MSC_VER
+
+extern void xlogging_set_log_function_GetLastError(LOGGER_LOG_GETLASTERROR log_function);
+extern LOGGER_LOG_GETLASTERROR xlogging_get_log_function_GetLastError(void);
+#define LogLastError(FORMAT, ...) do{ LOGGER_LOG_GETLASTERROR l = xlogging_get_log_function_GetLastError(); if(l!=NULL) l(__FILE__, FUNC_NAME, __LINE__, FORMAT, __VA_ARGS__); }while((void)0,0)
+
+#define LogError(FORMAT, ...) do{ LOG(AZ_LOG_ERROR, LOG_LINE, FORMAT, __VA_ARGS__); }while((void)0,0)
+#define LogErrorWinHTTPWithGetLastErrorAsString(FORMAT, ...) do { \
+                int errorMessageID = GetLastError(); \
+                LogError(FORMAT, __VA_ARGS__); \
+                xlogging_LogErrorWinHTTPWithGetLastErrorAsStringFormatter(errorMessageID); \
+            } while((void)0,0)
+#else // _MSC_VER
+#define LogError(FORMAT, ...) do{ LOG(AZ_LOG_ERROR, LOG_LINE, FORMAT, ##__VA_ARGS__); }while((void)0,0)
+
+#ifdef WIN32
+// Included when compiling on Windows but not with MSVC, e.g. with MinGW.
+#define LogErrorWinHTTPWithGetLastErrorAsString(FORMAT, ...) do { \
+                int errorMessageID = GetLastError(); \
+                LogError(FORMAT, ##__VA_ARGS__); \
+                xlogging_LogErrorWinHTTPWithGetLastErrorAsStringFormatter(errorMessageID); \
+            } while((void)0,0)
+#endif // WIN32
+
+#endif // _MSC_VER
+
+extern void LogBinary(const char* comment, const void* data, size_t size);
+
+extern void xlogging_set_log_function(LOGGER_LOG log_function);
+extern LOGGER_LOG xlogging_get_log_function(void);
+
+#endif /* NOT ESP8266_RTOS */
+
+#ifdef __cplusplus
+}   // extern "C"
+#endif /* __cplusplus */
+
+#endif /* XLOGGING_H */
Index: azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/pal/toppers/refcount_os.h
===================================================================
--- azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/pal/toppers/refcount_os.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/pal/toppers/refcount_os.h	(revision 457)
@@ -0,0 +1,21 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+// This file gets included into refcount.h as a means of extending the behavior of
+// atomic increment, decrement, and test.
+//
+// The Azure IoT C SDK does not require thread-safe refcount operations, so
+// this file is appropriate for any device when using the Azure IoT C SDK.
+
+#ifndef REFCOUNT_OS_H__GENERIC
+#define REFCOUNT_OS_H__GENERIC
+
+#define COUNT_TYPE uint32_t
+
+#define DEC_RETURN_ZERO (0)
+
+#define INC_REF_VAR(count) ++(count)
+#define DEC_REF_VAR(count) --(count)
+#define INIT_REF_VAR(count) do { count = 1; } while((void)0,0)
+
+#endif // REFCOUNT_OS_H__GENERIC
Index: azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/pal/toppers/socket_async_os.h
===================================================================
--- azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/pal/toppers/socket_async_os.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/pal/toppers/socket_async_os.h	(revision 457)
@@ -0,0 +1,14 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+//This file pulls in OS-specific header files to allow compilation of socket_async.c under
+// most OS's except for Windows.
+
+// For Linux systems
+#include <sys/types.h>
+//#include <lwip/sockets.h>
+#include <sys/select.h>
+#include <sys/errno.h>
+#include <unistd.h>
+//#include <netdb.h>
+
Index: azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/src/azure_base32.c
===================================================================
--- azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/src/azure_base32.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/src/azure_base32.c	(revision 457)
@@ -0,0 +1,397 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+#include <stdlib.h>
+#include <stdint.h>
+#include <ctype.h>
+#include "azure_c_shared_utility/buffer_.h"
+#include "azure_c_shared_utility/xlogging.h"
+#include "azure_c_shared_utility/gballoc.h"
+#include "azure_c_shared_utility/strings.h"
+
+#include "azure_c_shared_utility/azure_base32.h"
+
+static const unsigned char BASE32_EQUAL_SIGN = 32;
+
+static const char BASE32_VALUES[] = "abcdefghijklmnopqrstuvwxyz234567=";
+#define TARGET_BLOCK_SIZE       5
+#define INVALID_CHAR_POS        260
+
+#define BASE32_INPUT_SIZE       8
+
+#define ASCII_VALUE_MAX         0x80
+
+static size_t base32_encoding_length(size_t src_len)
+{
+    return (((src_len + TARGET_BLOCK_SIZE - 1) / TARGET_BLOCK_SIZE) * 8);
+}
+
+static size_t base32_decoding_length(size_t src_len)
+{
+    return ((src_len*TARGET_BLOCK_SIZE) / 8);
+}
+
+static unsigned char convert_value_to_base32_char(unsigned char value)
+{
+    unsigned char result;
+
+    if (value >= 50 && value <= 55)
+    {
+        result = 0x1a+(value-50);
+    }
+    else if (value == 61)
+    {
+        result = 0x20;
+    }
+    else if ((value <= 49) || (value >= 56 && value <= 64))
+    {
+        result = 0xFF;
+    }
+    else if (value >= 65 && value <= 90)
+    {
+        result = 0x00 + (value - 65);
+    }
+    else if (value >= 91 && value <= 96)
+    {
+        result = 0xFF;
+    }
+    else if (value >= 97 && value <= 123)
+    {
+        result = 0x00 + (value - 97);
+    }
+    else // value > 123
+    {
+        result = 0xFF;
+    }
+    return result;
+}
+
+static char* base32_encode_impl(const unsigned char* source, size_t src_size)
+{
+    char* result;
+
+    // Allocate target buffer
+    size_t output_len = base32_encoding_length(src_size);
+    /* Codes_SRS_BASE32_07_009: [ base32_encode_impl shall allocate the buffer to the size of the encoding value. ] */
+    if ((result = (char*)malloc(output_len + 1)) == NULL)
+    {
+        LogError("Failure allocating output buffer");
+    }
+    else
+    {
+        const unsigned char* iterator = source;
+        size_t block_len = 0;
+        size_t result_len = 0;
+        unsigned char pos1 = 0;
+        unsigned char pos2 = 0;
+        unsigned char pos3 = 0;
+        unsigned char pos4 = 0;
+        unsigned char pos5 = 0;
+        unsigned char pos6 = 0;
+        unsigned char pos7 = 0;
+        unsigned char pos8 = 0;
+
+        memset(result, 0, output_len + 1);
+
+        // Go through the source buffer sectioning off blocks of 5
+        /* Codes_SRS_BASE32_07_010: [ base32_encode_impl shall look through source and separate each block into 5 bit chunks ] */
+        while (src_size >= 1 && result != NULL)
+        {
+            pos1 = pos2 = pos3 = pos4 = pos5 = pos6 = pos7 = pos8 = 0;
+            block_len = src_size > TARGET_BLOCK_SIZE ? TARGET_BLOCK_SIZE : src_size;
+            // Fall through switch block to process the 5 (or smaller) block
+            switch (block_len)
+            {
+            case 5:
+                pos8 = (iterator[4] & 0x1f);
+                pos7 = ((iterator[4] & 0xe0) >> 5);
+                // fall through
+            case 4:
+                pos7 |= ((iterator[3] & 0x03) << 3);
+                pos6 = ((iterator[3] & 0x7c) >> 2);
+                pos5 = ((iterator[3] & 0x80) >> 7);
+                // fall through
+            case 3:
+                pos5 |= ((iterator[2] & 0x0f) << 1);
+                pos4 = ((iterator[2] & 0xf0) >> 4);
+                // fall through
+            case 2:
+                pos4 |= ((iterator[1] & 0x01) << 4);
+                pos3 = ((iterator[1] & 0x3e) >> 1);
+                pos2 = ((iterator[1] & 0xc0) >> 6);
+                // fall through
+            case 1:
+                pos2 |= ((iterator[0] & 0x07) << 2);
+                pos1 = ((iterator[0] & 0xf8) >> 3);
+                break;
+            }
+            // Move the iterator the block size
+            iterator += block_len;
+            // and decrement the src_size;
+            src_size -= block_len;
+
+            /* Codes_SRS_BASE32_07_012: [ If the src_size is not divisible by 8, base32_encode_impl shall pad the remaining places with =. ] */
+            switch (block_len)
+            {
+                case 1: pos3 = pos4 = 32; // fall through
+                case 2: pos5 = 32; // fall through
+                case 3: pos6 = pos7 = 32; // fall through
+                case 4: pos8 = 32; // fall through
+                case 5:
+                    break;
+            }
+
+            /* Codes_SRS_BASE32_07_011: [ base32_encode_impl shall then map the 5 bit chunks into one of the BASE32 values (a-z,2,3,4,5,6,7) values. ] */
+            result[result_len++] = BASE32_VALUES[pos1];
+            result[result_len++] = BASE32_VALUES[pos2];
+            result[result_len++] = BASE32_VALUES[pos3];
+            result[result_len++] = BASE32_VALUES[pos4];
+            result[result_len++] = BASE32_VALUES[pos5];
+            result[result_len++] = BASE32_VALUES[pos6];
+            result[result_len++] = BASE32_VALUES[pos7];
+            result[result_len++] = BASE32_VALUES[pos8];
+        }
+    }
+    return result;
+}
+
+static BUFFER_HANDLE base32_decode_impl(const char* source)
+{
+    BUFFER_HANDLE result;
+
+    size_t src_length = strlen(source);
+    if (src_length % BASE32_INPUT_SIZE != 0)
+    {
+        /* Codes_SRS_BASE32_07_021: [ If the source length is not evenly divisible by 8, base32_decode_impl shall return NULL. ] */
+        LogError("Failure invalid input length %lu", (unsigned long)src_length);
+        result = NULL;
+    }
+    else
+    {
+        size_t dest_size = 0;
+        unsigned char* temp_buffer;
+        unsigned char* dest_buff;
+        bool continue_processing = true;
+        unsigned char input[8];
+        const char* iterator = source;
+
+        /* Codes_SRS_BASE32_07_022: [ base32_decode_impl shall allocate a temp buffer to store the in process value. ] */
+        size_t allocation_len = base32_decoding_length(src_length);
+        if ((temp_buffer = (unsigned char*)malloc(allocation_len)) == NULL)
+        {
+            /* Codes_SRS_BASE32_07_023: [ If an error is encountered, base32_decode_impl shall return NULL. ] */
+            LogError("Failure allocating buffer");
+            result = NULL;
+        }
+        else
+        {
+            dest_buff = temp_buffer;
+            while (*iterator != '\0')
+            {
+                size_t index = 0;
+                /* Codes_SRS_BASE32_07_024: [ base32_decode_impl shall loop through and collect 8 characters from the source variable. ] */
+                for (index = 0; index < BASE32_INPUT_SIZE; index++)
+                {
+                    input[index] = *iterator;
+                    iterator++;
+                    if (input[index] >= ASCII_VALUE_MAX)
+                    {
+                        LogError("Failure source encoding");
+                        continue_processing = false;
+                        break;
+                    }
+
+                    input[index] = convert_value_to_base32_char(input[index]);
+                }
+
+                if (!continue_processing)
+                {
+                    result = NULL;
+                    break;
+                }
+                else if ((dest_size + TARGET_BLOCK_SIZE) > allocation_len)
+                {
+                    LogError("Failure target length exceeded");
+                    result = NULL;
+                    continue_processing = false;
+                    break;
+                }
+                else
+                {
+                    // Codes_SRS_BASE32_07_025: [ base32_decode_impl shall group 5 bytes at a time into the temp buffer. ]
+                    *dest_buff++ = ((input[0] & 0x1f) << 3) | ((input[1] & 0x1c) >> 2);
+                    *dest_buff++ = ((input[1] & 0x03) << 6) | ((input[2] & 0x1f) << 1) | ((input[3] & 0x10) >> 4);
+                    *dest_buff++ = ((input[3] & 0x0f) << 4) | ((input[4] & 0x1e) >> 1);
+                    *dest_buff++ = ((input[4] & 0x01) << 7) | ((input[5] & 0x1f) << 2) | ((input[6] & 0x18) >> 3);
+                    *dest_buff++ = ((input[6] & 0x07) << 5) | (input[7] & 0x1f);
+                    dest_size += TARGET_BLOCK_SIZE;
+                    // If there is padding remove it
+                    // Because we are packing 5 bytes into an 8 byte variable we need to check every other
+                    // variable for padding
+                    if (input[7] == BASE32_EQUAL_SIGN)
+                    {
+                        --dest_size;
+                        if (input[5] == BASE32_EQUAL_SIGN)
+                        {
+                            --dest_size;
+                            if (input[4] == BASE32_EQUAL_SIGN)
+                            {
+                                --dest_size;
+                                if (input[2] == BASE32_EQUAL_SIGN)
+                                {
+                                    --dest_size;
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+
+            if (!continue_processing)
+            {
+                result = NULL;
+            }
+            else
+            {
+                /* Codes_SRS_BASE32_07_026: [ Once base32_decode_impl is complete it shall create a BUFFER with the temp buffer. ] */
+                result = BUFFER_create(temp_buffer, dest_size);
+                if (result == NULL)
+                {
+                    LogError("Failure: BUFFER_create failed to create decoded buffer");
+                }
+            }
+            free(temp_buffer);
+        }
+    }
+    return result;
+}
+
+BUFFER_HANDLE Azure_Base32_Decode(STRING_HANDLE handle)
+{
+    BUFFER_HANDLE result;
+    if (handle == NULL)
+    {
+        /* Codes_SRS_BASE32_07_016: [ If source is NULL Azure_Base32_Decode shall return NULL. ] */
+        LogError("invalid parameter handle");
+        result = NULL;
+    }
+    else
+    {
+        const char* str_source = STRING_c_str(handle);
+        if (str_source == NULL)
+        {
+            /* Codes_SRS_BASE32_07_027: [ If the string in source value is NULL, Azure_Base32_Decode shall return NULL. ] */
+            LogError("NULL value specified in string");
+            result = NULL;
+        }
+        else
+        {
+            /* Codes_SRS_BASE32_07_018: [ Azure_Base32_Decode shall call base32_decode_impl to decode the base64 value. ] */
+            result = base32_decode_impl(str_source);
+        }
+    }
+    /* Codes_SRS_BASE32_07_017: [ On success Azure_Base32_Decode shall return a BUFFER_HANDLE that contains the decoded bytes for source. ] */
+    return result;
+}
+
+BUFFER_HANDLE Azure_Base32_Decode_String(const char* source)
+{
+    BUFFER_HANDLE result;
+    if (source == NULL)
+    {
+        /* Codes_SRS_BASE32_07_008: [ If source is NULL Azure_Base32_Decode_String shall return NULL. ] */
+        LogError("invalid parameter source=NULL");
+        result = NULL;
+    }
+    else
+    {
+        /* Codes_SRS_BASE32_07_020: [ Azure_Base32_Decode_String shall call base32_decode_impl to decode the base64 value. ] */
+        result = base32_decode_impl(source);
+    }
+    /* Codes_SRS_BASE32_07_019: [ On success Azure_Base32_Decode_String shall return a BUFFER_HANDLE that contains the decoded bytes for source. ] */
+    return result;
+}
+
+char* Azure_Base32_Encode_Bytes(const unsigned char* source, size_t size)
+{
+    char* result;
+    if (source == NULL)
+    {
+        /* Codes_SRS_BASE32_07_004: [ If source is NULL Azure_Base32_Encode_Bytes shall return NULL. ] */
+        result = NULL;
+        LogError("Failure: Invalid input parameter source");
+    }
+    else if (size == 0)
+    {
+        /* Codes_SRS_BASE32_07_005: [ If size is 0 Azure_Base32_Encode_Bytes shall return an empty string. ] */
+        if ((result = malloc(1)) != NULL)
+        {
+            strcpy(result, "");
+        }
+        else
+        {
+            LogError("unable to allocate memory for result");
+        }
+    }
+    else
+    {
+        /* Codes_SRS_BASE32_07_007: [ Azure_Base32_Encode_Bytes shall call into base32_Encode_impl to encode the source data. ] */
+        result = base32_encode_impl(source, size);
+        if (result == NULL)
+        {
+            /* Codes_SRS_BASE32_07_014: [ Upon failure Azure_Base32_Encode_Bytes shall return NULL. ] */
+            LogError("encoding of unsigned char failed.");
+        }
+    }
+    /* Codes_SRS_BASE32_07_006: [ If successful Azure_Base32_Encode_Bytes shall return the base32 value of input. ] */
+    return result;
+}
+
+STRING_HANDLE Azure_Base32_Encode(BUFFER_HANDLE source)
+{
+    STRING_HANDLE result;
+    if (source == NULL)
+    {
+        /* Codes_SRS_BASE32_07_001: [ If source is NULL Azure_Base32_Encode shall return NULL. ] */
+        result = NULL;
+        LogError("Failure: Invalid input parameter");
+    }
+    else
+    {
+        size_t input_len = BUFFER_length(source);
+        const unsigned char* input_value = BUFFER_u_char(source);
+        if (input_value == NULL || input_len == 0)
+        {
+            /* Codes_SRS_BASE32_07_015: [ If size is 0 Azure_Base32_Encode shall return an empty string. ] */
+            result = STRING_new();
+            if (result == NULL)
+            {
+                LogError("Failure constructing new string.");
+            }
+        }
+        else
+        {
+            /* Codes_SRS_BASE32_07_003: [ Azure_Base32_Encode shall call into base32_Encode_impl to encode the source data. ] */
+            char* encoded = base32_encode_impl(input_value, input_len);
+            if (encoded == NULL)
+            {
+                /* Codes_SRS_BASE32_07_014: [ Upon failure Azure_Base32_Encode shall return NULL. ] */
+                LogError("base32 encode implementation failed.");
+                result = NULL;
+            }
+            else
+            {
+                /* Codes_SRS_BASE32_07_012: [ Azure_Base32_Encode shall wrap the base32_Encode_impl result into a STRING_HANDLE. ] */
+                result = STRING_construct(encoded);
+                if (result == NULL)
+                {
+                    /* Codes_SRS_BASE32_07_014: [ Upon failure Azure_Base32_Encode shall return NULL. ] */
+                    LogError("string construction failed.");
+                }
+                free(encoded);
+            }
+        }
+    }
+    /* Codes_SRS_BASE32_07_002: [ If successful Azure_Base32_Encode shall return the base32 value of source. ] */
+    return result;
+}
Index: azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/src/azure_base64.c
===================================================================
--- azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/src/azure_base64.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/src/azure_base64.c	(revision 457)
@@ -0,0 +1,367 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+#include <stdlib.h>
+#include <stdint.h>
+#include "azure_c_shared_utility/gballoc.h"
+#include "azure_c_shared_utility/azure_base64.h"
+#include "azure_c_shared_utility/xlogging.h"
+
+
+#define splitInt(intVal, bytePos)   (char)((intVal >> (bytePos << 3)) & 0xFF)
+#define joinChars(a, b, c, d) (uint32_t)((uint32_t)a + ((uint32_t)b << 8) + ((uint32_t)c << 16) + ((uint32_t)d << 24))
+
+static char base64char(unsigned char val)
+{
+    char result;
+
+    if (val < 26)
+    {
+        result = 'A' + (char)val;
+    }
+    else if (val < 52)
+    {
+        result = 'a' + ((char)val - 26);
+    }
+    else if (val < 62)
+    {
+        result = '0' + ((char)val - 52);
+    }
+    else if (val == 62)
+    {
+        result = '+';
+    }
+    else
+    {
+        result = '/';
+    }
+
+    return result;
+}
+
+static char base64b16(unsigned char val)
+{
+    const uint32_t base64b16values[4] = {
+        joinChars('A', 'E', 'I', 'M'),
+        joinChars('Q', 'U', 'Y', 'c'),
+        joinChars('g', 'k', 'o', 's'),
+        joinChars('w', '0', '4', '8')
+    };
+    return splitInt(base64b16values[val >> 2], (val & 0x03));
+}
+
+static char base64b8(unsigned char val)
+{
+    const uint32_t base64b8values = joinChars('A', 'Q', 'g', 'w');
+    return splitInt(base64b8values, val);
+}
+
+static int base64toValue(char base64character, unsigned char* value)
+{
+    int result = 0;
+    if (('A' <= base64character) && (base64character <= 'Z'))
+    {
+        *value = base64character - 'A';
+    }
+    else if (('a' <= base64character) && (base64character <= 'z'))
+    {
+        *value = ('Z' - 'A') + 1 + (base64character - 'a');
+    }
+    else if (('0' <= base64character) && (base64character <= '9'))
+    {
+        *value = ('Z' - 'A') + 1 + ('z' - 'a') + 1 + (base64character - '0');
+    }
+    else if ('+' == base64character)
+    {
+        *value = 62;
+    }
+    else if ('/' == base64character)
+    {
+        *value = 63;
+    }
+    else
+    {
+        *value = 0;
+        result = -1;
+    }
+    return result;
+}
+
+static size_t numberOfBase64Characters(const char* encodedString)
+{
+    size_t length = 0;
+    unsigned char junkChar;
+    while (base64toValue(encodedString[length],&junkChar) != -1)
+    {
+        length++;
+    }
+    return length;
+}
+
+/*returns the count of original bytes before being base64 encoded*/
+/*notice NO validation of the content of encodedString. Its length is validated to be a multiple of 4.*/
+static size_t Base64decode_len(const char *encodedString)
+{
+    size_t result;
+    size_t sourceLength = strlen(encodedString);
+
+    if (sourceLength == 0)
+    {
+        result = 0;
+    }
+    else
+    {
+        result = sourceLength / 4 * 3;
+        if (encodedString[sourceLength - 1] == '=')
+        {
+            if (encodedString[sourceLength - 2] == '=')
+            {
+                result --;
+            }
+            result--;
+        }
+    }
+    return result;
+}
+
+static void Base64decode(unsigned char *decodedString, const char *base64String)
+{
+
+    size_t numberOfEncodedChars;
+    size_t indexOfFirstEncodedChar;
+    size_t decodedIndex;
+
+    //
+    // We can only operate on individual bytes.  If we attempt to work
+    // on anything larger we could get an alignment fault on some
+    // architectures
+    //
+
+    numberOfEncodedChars = numberOfBase64Characters(base64String);
+    indexOfFirstEncodedChar = 0;
+    decodedIndex = 0;
+    while (numberOfEncodedChars >= 4)
+    {
+        unsigned char c1;
+        unsigned char c2;
+        unsigned char c3;
+        unsigned char c4;
+        (void)base64toValue(base64String[indexOfFirstEncodedChar], &c1);
+        (void)base64toValue(base64String[indexOfFirstEncodedChar + 1], &c2);
+        (void)base64toValue(base64String[indexOfFirstEncodedChar + 2], &c3);
+        (void)base64toValue(base64String[indexOfFirstEncodedChar + 3], &c4);
+        decodedString[decodedIndex] = (c1 << 2) | (c2 >> 4);
+        decodedIndex++;
+        decodedString[decodedIndex] = ((c2 & 0x0f) << 4) | (c3 >> 2);
+        decodedIndex++;
+        decodedString[decodedIndex] = ((c3 & 0x03) << 6) | c4;
+        decodedIndex++;
+        numberOfEncodedChars -= 4;
+        indexOfFirstEncodedChar += 4;
+
+    }
+
+    if (numberOfEncodedChars == 2)
+    {
+        unsigned char c1;
+        unsigned char c2;
+        (void)base64toValue(base64String[indexOfFirstEncodedChar], &c1);
+        (void)base64toValue(base64String[indexOfFirstEncodedChar + 1], &c2);
+        decodedString[decodedIndex] = (c1 << 2) | (c2 >> 4);
+    }
+    else if (numberOfEncodedChars == 3)
+    {
+        unsigned char c1;
+        unsigned char c2;
+        unsigned char c3;
+        (void)base64toValue(base64String[indexOfFirstEncodedChar], &c1);
+        (void)base64toValue(base64String[indexOfFirstEncodedChar + 1], &c2);
+        (void)base64toValue(base64String[indexOfFirstEncodedChar + 2], &c3);
+        decodedString[decodedIndex] = (c1 << 2) | (c2 >> 4);
+        decodedIndex++;
+        decodedString[decodedIndex] = ((c2 & 0x0f) << 4) | (c3 >> 2);
+    }
+}
+
+BUFFER_HANDLE Azure_Base64_Decode(const char* source)
+{
+    BUFFER_HANDLE result;
+    /*Codes_SRS_BASE64_06_008: [If source is NULL then Azure_Base64_Decode shall return NULL.]*/
+    if (source == NULL)
+    {
+        LogError("invalid parameter const char* source=%p", source);
+        result = NULL;
+    }
+    else
+    {
+        if ((strlen(source) % 4) != 0)
+        {
+            /*Codes_SRS_BASE64_06_011: [If the source string has an invalid length for a base 64 encoded string then Azure_Base64_Decode shall return NULL.]*/
+            LogError("Invalid length Base64 string!");
+            result = NULL;
+        }
+        else
+        {
+            if ((result = BUFFER_new()) == NULL)
+            {
+                /*Codes_SRS_BASE64_06_010: [If there is any memory allocation failure during the decode then Azure_Base64_Decode shall return NULL.]*/
+                LogError("Could not create a buffer to decoding.");
+            }
+            else
+            {
+                size_t sizeOfOutputBuffer = Base64decode_len(source);
+                /*Codes_SRS_BASE64_06_009: [If the string pointed to by source is zero length then the handle returned shall refer to a zero length buffer.]*/
+                if (sizeOfOutputBuffer > 0)
+                {
+                    if (BUFFER_pre_build(result, sizeOfOutputBuffer) != 0)
+                    {
+                        /*Codes_SRS_BASE64_06_010: [If there is any memory allocation failure during the decode then Azure_Base64_Decode shall return NULL.]*/
+                        LogError("Could not prebuild a buffer for base 64 decoding.");
+                        BUFFER_delete(result);
+                        result = NULL;
+                    }
+                    else
+                    {
+                        Base64decode(BUFFER_u_char(result), source);
+                    }
+                }
+            }
+        }
+    }
+    return result;
+}
+
+
+static STRING_HANDLE Base64_Encode_Internal(const unsigned char* source, size_t size)
+{
+    STRING_HANDLE result;
+    size_t neededSize = 0;
+    char* encoded;
+    size_t currentPosition = 0;
+    neededSize += (size == 0) ? (0) : ((((size - 1) / 3) + 1) * 4);
+    neededSize += 1; /*+1 because \0 at the end of the string*/
+    /*Codes_SRS_BASE64_06_006: [If when allocating memory to produce the encoding a failure occurs then Azure_Base64_Encode shall return NULL.]*/
+    encoded = (char*)malloc(neededSize);
+    if (encoded == NULL)
+    {
+        result = NULL;
+        LogError("Azure_Base64_Encode:: Allocation failed.");
+    }
+    else
+    {
+        /*b0            b1(+1)          b2(+2)
+        7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0
+        |----c1---| |----c2---| |----c3---| |----c4---|
+        */
+
+        size_t destinationPosition = 0;
+        while (size - currentPosition >= 3)
+        {
+            char c1 = base64char(source[currentPosition] >> 2);
+            char c2 = base64char(
+                ((source[currentPosition] & 3) << 4) |
+                    (source[currentPosition + 1] >> 4)
+            );
+            char c3 = base64char(
+                ((source[currentPosition + 1] & 0x0F) << 2) |
+                    ((source[currentPosition + 2] >> 6) & 3)
+            );
+            char c4 = base64char(
+                source[currentPosition + 2] & 0x3F
+            );
+            currentPosition += 3;
+            encoded[destinationPosition++] = c1;
+            encoded[destinationPosition++] = c2;
+            encoded[destinationPosition++] = c3;
+            encoded[destinationPosition++] = c4;
+
+        }
+        if (size - currentPosition == 2)
+        {
+            char c1 = base64char(source[currentPosition] >> 2);
+            char c2 = base64char(
+                ((source[currentPosition] & 0x03) << 4) |
+                    (source[currentPosition + 1] >> 4)
+            );
+            char c3 = base64b16(source[currentPosition + 1] & 0x0F);
+            encoded[destinationPosition++] = c1;
+            encoded[destinationPosition++] = c2;
+            encoded[destinationPosition++] = c3;
+            encoded[destinationPosition++] = '=';
+        }
+        else if (size - currentPosition == 1)
+        {
+            char c1 = base64char(source[currentPosition] >> 2);
+            char c2 = base64b8(source[currentPosition] & 0x03);
+            encoded[destinationPosition++] = c1;
+            encoded[destinationPosition++] = c2;
+            encoded[destinationPosition++] = '=';
+            encoded[destinationPosition++] = '=';
+        }
+
+        /*null terminating the string*/
+        encoded[destinationPosition] = '\0';
+        /*Codes_SRS_BASE64_06_007: [Otherwise Azure_Base64_Encode shall return a pointer to STRING, that string contains the base 64 encoding of input.]*/
+        result = STRING_new_with_memory(encoded);
+        if (result == NULL)
+        {
+            free(encoded);
+            LogError("Azure_Base64_Encode:: Allocation failed for return value.");
+        }
+    }
+    return result;
+}
+
+STRING_HANDLE Azure_Base64_Encode_Bytes(const unsigned char* source, size_t size)
+{
+    STRING_HANDLE result;
+    /*Codes_SRS_BASE64_02_001: [If source is NULL then Azure_Base64_Encode_Bytes shall return NULL.] */
+    if (source == NULL)
+    {
+        result = NULL;
+    }
+    /*Codes_SRS_BASE64_02_002: [If source is not NULL and size is zero, then Azure_Base64_Encode_Bytes shall produce an empty STRING_HANDLE.] */
+    else if (size == 0)
+    {
+        result = STRING_new(); /*empty string*/
+    }
+    else
+    {
+        result = Base64_Encode_Internal(source, size);
+    }
+    return result;
+}
+
+STRING_HANDLE Azure_Base64_Encode(BUFFER_HANDLE input)
+{
+    STRING_HANDLE result;
+    /*the following will happen*/
+    /*1. the "data" of the binary shall be "eaten" 3 characters at a time and produce 4 base64 encoded characters for as long as there are more than 3 characters still to process*/
+    /*2. the remaining characters (1 or 2) shall be encoded.*/
+    /*there's a level of assumption that 'a' corresponds to 0b000000 and that '_' corresponds to 0b111111*/
+    /*the encoding will use the optional [=] or [==] at the end of the encoded string, so that other less standard aware libraries can do their work*/
+    /*these are the bits of the 3 normal bytes to be encoded*/
+
+    /*Codes_SRS_BASE64_06_001: [If input is NULL then Azure_Base64_Encode shall return NULL.]*/
+    if (input == NULL)
+    {
+        result = NULL;
+        LogError("Azure_Base64_Encode:: NULL input");
+    }
+    else
+    {
+        size_t inputSize;
+        const unsigned char* inputBinary;
+        if ((BUFFER_content(input, &inputBinary) != 0) ||
+            (BUFFER_size(input, &inputSize) != 0))
+        {
+            result = NULL;
+            LogError("Azure_Base64_Encode:: BUFFER_routines failure.");
+        }
+        else
+        {
+            result = Base64_Encode_Internal(inputBinary, inputSize);
+        }
+    }
+    return result;
+}
Index: azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/src/buffer.c
===================================================================
--- azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/src/buffer.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/src/buffer.c	(revision 457)
@@ -0,0 +1,667 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+#include <stdlib.h>
+#include <string.h>
+#include <stdbool.h>
+#include "azure_c_shared_utility/gballoc.h"
+#include "azure_c_shared_utility/buffer_.h"
+#include "azure_c_shared_utility/optimize_size.h"
+#include "azure_c_shared_utility/xlogging.h"
+
+typedef struct BUFFER_TAG
+{
+    unsigned char* buffer;
+    size_t size;
+} BUFFER;
+
+/* Codes_SRS_BUFFER_07_001: [BUFFER_new shall allocate a BUFFER_HANDLE that will contain a NULL unsigned char*.] */
+BUFFER_HANDLE BUFFER_new(void)
+{
+    BUFFER* temp = (BUFFER*)calloc(1, sizeof(BUFFER));
+    /* Codes_SRS_BUFFER_07_002: [BUFFER_new shall return NULL on any error that occurs.] */
+    if (temp != NULL)
+    {
+        temp->buffer = NULL;
+        temp->size = 0;
+    }
+    return (BUFFER_HANDLE)temp;
+}
+
+static int BUFFER_safemalloc(BUFFER* handleptr, size_t size)
+{
+    int result;
+    size_t sizetomalloc = size;
+    if (size == 0)
+    {
+        sizetomalloc = 1;
+    }
+    handleptr->buffer = (unsigned char*)malloc(sizetomalloc);
+    if (handleptr->buffer == NULL)
+    {
+        /*Codes_SRS_BUFFER_02_003: [If allocating memory fails, then BUFFER_create shall return NULL.]*/
+        LogError("Failure allocating data");
+        result = MU_FAILURE;
+    }
+    else
+    {
+        // we still consider the real buffer size is 0
+        handleptr->size = size;
+        result = 0;
+    }
+    return result;
+}
+
+BUFFER_HANDLE BUFFER_create(const unsigned char* source, size_t size)
+{
+    BUFFER* result;
+    /*Codes_SRS_BUFFER_02_001: [If source is NULL then BUFFER_create shall return NULL.]*/
+    if (source == NULL)
+    {
+        LogError("invalid parameter source: %p", source);
+        result = NULL;
+    }
+    else
+    {
+        /*Codes_SRS_BUFFER_02_002: [Otherwise, BUFFER_create shall allocate memory to hold size bytes and shall copy from source size bytes into the newly allocated memory.] */
+        result = (BUFFER*)calloc(1, sizeof(BUFFER));
+        if (result == NULL)
+        {
+            /*Codes_SRS_BUFFER_02_003: [If allocating memory fails, then BUFFER_create shall return NULL.] */
+            /*fallthrough*/
+            LogError("Failure allocating BUFFER structure");
+        }
+        else
+        {
+            /* Codes_SRS_BUFFER_02_005: [If size parameter is 0 then 1 byte of memory shall be allocated yet size of the buffer shall be set to 0.]*/
+            if (BUFFER_safemalloc(result, size) != 0)
+            {
+                LogError("unable to BUFFER_safemalloc ");
+                free(result);
+                result = NULL;
+            }
+            else
+            {
+                /*Codes_SRS_BUFFER_02_004: [Otherwise, BUFFER_create shall return a non-NULL handle.] */
+                (void)memcpy(result->buffer, source, size);
+            }
+        }
+    }
+    return (BUFFER_HANDLE)result;
+}
+
+// Codes_SRS_BUFFER_07_029: [ BUFFER_create_with_size shall create a BUFFER_HANDLE with a pre allocated underlying buffer size.]
+BUFFER_HANDLE BUFFER_create_with_size(size_t buff_size)
+{
+    BUFFER* result;
+    result = (BUFFER*)calloc(1, sizeof(BUFFER));
+    if (result != NULL)
+    {
+        if (buff_size == 0)
+        {
+            // Codes_SRS_BUFFER_07_030: [ If buff_size is 0 BUFFER_create_with_size shall create a valid non-NULL handle of zero size. ]
+            result->size = 0;
+            result->buffer = NULL;
+        }
+        else
+        {
+            // Codes_SRS_BUFFER_07_031: [ BUFFER_create_with_size shall allocate a buffer of buff_size. ]
+            result->size = buff_size;
+            if ((result->buffer = (unsigned char*)malloc(result->size)) == NULL)
+            {
+                // Codes_SRS_BUFFER_07_032: [ If allocating memory fails, then BUFFER_create_with_size shall return NULL. ]
+                LogError("unable to allocate buffer");
+                free(result);
+                result = NULL;
+            }
+        }
+    }
+    else
+    {
+        // Codes_SRS_BUFFER_07_032: [ If allocating memory fails, then BUFFER_create_with_size shall return NULL. ]
+        LogError("unable to allocate BUFFER");
+    }
+    // Codes_SRS_BUFFER_07_033: [ Otherwise, BUFFER_create_with_size shall return a non-NULL handle. ]
+    return (BUFFER_HANDLE)result;
+}
+
+/* Codes_SRS_BUFFER_07_003: [BUFFER_delete shall delete the data associated with the BUFFER_HANDLE along with the Buffer.] */
+void BUFFER_delete(BUFFER_HANDLE handle)
+{
+    /* Codes_SRS_BUFFER_07_004: [BUFFER_delete shall not delete any BUFFER_HANDLE that is NULL.] */
+    if (handle != NULL)
+    {
+        BUFFER* b = (BUFFER*)handle;
+        if (b->buffer != NULL)
+        {
+            /* Codes_SRS_BUFFER_07_003: [BUFFER_delete shall delete the data associated with the BUFFER_HANDLE along with the Buffer.] */
+            free(b->buffer);
+        }
+        free(b);
+    }
+}
+
+/*return 0 if the buffer was copied*/
+/*else return different than zero*/
+/* Codes_SRS_BUFFER_07_008: [BUFFER_build allocates size_t bytes, copies the unsigned char* into the buffer and returns zero on success.] */
+int BUFFER_build(BUFFER_HANDLE handle, const unsigned char* source, size_t size)
+{
+    int result;
+    if (handle == NULL)
+    {
+        /* Codes_SRS_BUFFER_07_009: [BUFFER_build shall return nonzero if handle is NULL ] */
+        result = MU_FAILURE;
+    }
+    /* Codes_SRS_BUFFER_01_002: [The size argument can be zero, in which case the underlying buffer held by the buffer instance shall be freed.] */
+    else if (size == 0)
+    {
+        /* Codes_SRS_BUFFER_01_003: [If size is zero, source can be NULL.] */
+        BUFFER* b = (BUFFER*)handle;
+        free(b->buffer);
+        b->buffer = NULL;
+        b->size = 0;
+
+        result = 0;
+    }
+    else
+    {
+        if (source == NULL)
+        {
+            /* Codes_SRS_BUFFER_01_001: [If size is positive and source is NULL, BUFFER_build shall return nonzero] */
+            result = MU_FAILURE;
+        }
+        else
+        {
+            BUFFER* b = (BUFFER*)handle;
+            /* Codes_SRS_BUFFER_07_011: [BUFFER_build shall overwrite previous contents if the buffer has been previously allocated.] */
+            unsigned char* newBuffer = (unsigned char*)realloc(b->buffer, size);
+            if (newBuffer == NULL)
+            {
+                /* Codes_SRS_BUFFER_07_010: [BUFFER_build shall return nonzero if any error is encountered.] */
+                LogError("Failure reallocating buffer");
+                result = MU_FAILURE;
+            }
+            else
+            {
+                b->buffer = newBuffer;
+                b->size = size;
+                /* Codes_SRS_BUFFER_01_002: [The size argument can be zero, in which case nothing shall be copied from source.] */
+                (void)memcpy(b->buffer, source, size);
+
+                result = 0;
+            }
+        }
+    }
+
+    return result;
+}
+
+int BUFFER_append_build(BUFFER_HANDLE handle, const unsigned char* source, size_t size)
+{
+    int result;
+    if (handle == NULL || source == NULL || size == 0)
+    {
+        /* Codes_SRS_BUFFER_07_029: [ BUFFER_append_build shall return nonzero if handle or source are NULL or if size is 0. ] */
+        LogError("BUFFER_append_build failed invalid parameter handle: %p, source: %p, size: %lu", handle, source, (unsigned long)size);
+        result = MU_FAILURE;
+    }
+    else
+    {
+        if (handle->buffer == NULL)
+        {
+            /* Codes_SRS_BUFFER_07_030: [ if handle->buffer is NULL BUFFER_append_build shall allocate the a buffer of size bytes... ] */
+            if (BUFFER_safemalloc(handle, size) != 0)
+            {
+                /* Codes_SRS_BUFFER_07_035: [ If any error is encountered BUFFER_append_build shall return a non-null value. ] */
+                LogError("Failure with BUFFER_safemalloc");
+                result = MU_FAILURE;
+            }
+            else
+            {
+                /* Codes_SRS_BUFFER_07_031: [ ... and copy the contents of source to handle->buffer. ] */
+                (void)memcpy(handle->buffer, source, size);
+                /* Codes_SRS_BUFFER_07_034: [ On success BUFFER_append_build shall return 0 ] */
+                result = 0;
+            }
+        }
+        else
+        {
+            /* Codes_SRS_BUFFER_07_032: [ if handle->buffer is not NULL BUFFER_append_build shall realloc the buffer to be the handle->size + size ] */
+            unsigned char* temp = (unsigned char*)realloc(handle->buffer, handle->size + size);
+            if (temp == NULL)
+            {
+                /* Codes_SRS_BUFFER_07_035: [ If any error is encountered BUFFER_append_build shall return a non-null value. ] */
+                LogError("Failure reallocating temporary buffer");
+                result = MU_FAILURE;
+            }
+            else
+            {
+                /* Codes_SRS_BUFFER_07_033: [ ... and copy the contents of source to the end of the buffer. ] */
+                handle->buffer = temp;
+                // Append the BUFFER
+                (void)memcpy(&handle->buffer[handle->size], source, size);
+                handle->size += size;
+                /* Codes_SRS_BUFFER_07_034: [ On success BUFFER_append_build shall return 0 ] */
+                result = 0;
+            }
+        }
+    }
+    return result;
+}
+
+/*return 0 if the buffer was pre-build(that is, had its space allocated)*/
+/*else return different than zero*/
+/* Codes_SRS_BUFFER_07_005: [BUFFER_pre_build allocates size_t bytes of BUFFER_HANDLE and returns zero on success.] */
+int BUFFER_pre_build(BUFFER_HANDLE handle, size_t size)
+{
+    int result;
+    if (handle == NULL)
+    {
+        /* Codes_SRS_BUFFER_07_006: [If handle is NULL or size is 0 then BUFFER_pre_build shall return a nonzero value.] */
+        result = MU_FAILURE;
+    }
+    else if (size == 0)
+    {
+        /* Codes_SRS_BUFFER_07_006: [If handle is NULL or size is 0 then BUFFER_pre_build shall return a nonzero value.] */
+        result = MU_FAILURE;
+    }
+    else
+    {
+        BUFFER* b = (BUFFER*)handle;
+        if (b->buffer != NULL)
+        {
+            /* Codes_SRS_BUFFER_07_007: [BUFFER_pre_build shall return nonzero if the buffer has been previously allocated and is not NULL.] */
+            LogError("Failure buffer data is NULL");
+            result = MU_FAILURE;
+        }
+        else
+        {
+            if ((b->buffer = (unsigned char*)malloc(size)) == NULL)
+            {
+                /* Codes_SRS_BUFFER_07_013: [BUFFER_pre_build shall return nonzero if any error is encountered.] */
+                LogError("Failure allocating buffer");
+                result = MU_FAILURE;
+            }
+            else
+            {
+                b->size = size;
+                result = 0;
+            }
+        }
+    }
+    return result;
+}
+
+/* Codes_SRS_BUFFER_07_019: [BUFFER_content shall return the data contained within the BUFFER_HANDLE.] */
+int BUFFER_content(BUFFER_HANDLE handle, const unsigned char** content)
+{
+    int result;
+    if ((handle == NULL) || (content == NULL))
+    {
+        /* Codes_SRS_BUFFER_07_020: [If the handle and/or content*is NULL BUFFER_content shall return nonzero.] */
+        result = MU_FAILURE;
+    }
+    else
+    {
+        BUFFER* b = (BUFFER*)handle;
+        *content = b->buffer;
+        result = 0;
+    }
+    return result;
+}
+
+/*return 0 if everything went ok and whatever was built in the buffer was unbuilt*/
+/* Codes_SRS_BUFFER_07_012: [BUFFER_unbuild shall clear the underlying unsigned char* data associated with the BUFFER_HANDLE this will return zero on success.] */
+extern int BUFFER_unbuild(BUFFER_HANDLE handle)
+{
+    int result;
+    if (handle == NULL)
+    {
+        /* Codes_SRS_BUFFER_07_014: [BUFFER_unbuild shall return a nonzero value if BUFFER_HANDLE is NULL.] */
+        LogError("Failure: handle is invalid.");
+        result = MU_FAILURE;
+    }
+    else
+    {
+        BUFFER* b = (BUFFER*)handle;
+        if (b->buffer != NULL)
+        {
+            free(b->buffer);
+            b->buffer = NULL;
+            b->size = 0;
+        
+        }
+
+        /* Codes_SRS_BUFFER_07_015: [BUFFER_unbuild shall always return success if the unsigned char* referenced by BUFFER_HANDLE is NULL.] */
+        result = 0;
+    }
+    return result;
+}
+
+/* Codes_SRS_BUFFER_07_016: [BUFFER_enlarge shall increase the size of the unsigned char* referenced by BUFFER_HANDLE.] */
+int BUFFER_enlarge(BUFFER_HANDLE handle, size_t enlargeSize)
+{
+    int result;
+    if (handle == NULL)
+    {
+        /* Codes_SRS_BUFFER_07_017: [BUFFER_enlarge shall return a nonzero result if any parameters are NULL or zero.] */
+        LogError("Failure: handle is invalid.");
+        result = MU_FAILURE;
+    }
+    else if (enlargeSize == 0)
+    {
+        /* Codes_SRS_BUFFER_07_017: [BUFFER_enlarge shall return a nonzero result if any parameters are NULL or zero.] */
+        LogError("Failure: enlargeSize size is 0.");
+        result = MU_FAILURE;
+    }
+    else
+    {
+        BUFFER* b = (BUFFER*)handle;
+        unsigned char* temp = (unsigned char*)realloc(b->buffer, b->size + enlargeSize);
+        if (temp == NULL)
+        {
+            /* Codes_SRS_BUFFER_07_018: [BUFFER_enlarge shall return a nonzero result if any error is encountered.] */
+            LogError("Failure: allocating temp buffer.");
+            result = MU_FAILURE;
+        }
+        else
+        {
+            b->buffer = temp;
+            b->size += enlargeSize;
+            result = 0;
+        }
+    }
+    return result;
+}
+
+int BUFFER_shrink(BUFFER_HANDLE handle, size_t decreaseSize, bool fromEnd)
+{
+    int result;
+    if (handle == NULL)
+    {
+        /* Codes_SRS_BUFFER_07_036: [ if handle is NULL, BUFFER_shrink shall return a non-null value ]*/
+        LogError("Failure: handle is invalid.");
+        result = MU_FAILURE;
+    }
+    else if (decreaseSize == 0)
+    {
+        /* Codes_SRS_BUFFER_07_037: [ If decreaseSize is equal zero, BUFFER_shrink shall return a non-null value ] */
+        LogError("Failure: decrease size is 0.");
+        result = MU_FAILURE;
+    }
+    else if (decreaseSize > handle->size)
+    {
+        /* Codes_SRS_BUFFER_07_038: [ If decreaseSize is less than the size of the buffer, BUFFER_shrink shall return a non-null value ] */
+        LogError("Failure: decrease size is less than buffer size.");
+        result = MU_FAILURE;
+    }
+    else
+    {
+        /* Codes_SRS_BUFFER_07_039: [ BUFFER_shrink shall allocate a temporary buffer of existing buffer size minus decreaseSize. ] */
+        size_t alloc_size = handle->size - decreaseSize;
+        if (alloc_size == 0)
+        {
+            /* Codes_SRS_BUFFER_07_043: [ If the decreaseSize is equal the buffer size , BUFFER_shrink shall deallocate the buffer and set the size to zero. ] */
+            free(handle->buffer);
+            handle->buffer = NULL;
+            handle->size = 0;
+            result = 0;
+        }
+        else
+        {
+            unsigned char* tmp = malloc(alloc_size);
+            if (tmp == NULL)
+            {
+                /* Codes_SRS_BUFFER_07_042: [ If a failure is encountered, BUFFER_shrink shall return a non-null value ] */
+                LogError("Failure: allocating temp buffer.");
+                result = MU_FAILURE;
+            }
+            else
+            {
+                if (fromEnd)
+                {
+                    /* Codes_SRS_BUFFER_07_040: [ if the fromEnd variable is true, BUFFER_shrink shall remove the end of the buffer of size decreaseSize. ] */
+                    memcpy(tmp, handle->buffer, alloc_size);
+                    free(handle->buffer);
+                    handle->buffer = tmp;
+                    handle->size = alloc_size;
+                    result = 0;
+                }
+                else
+                {
+                    /* Codes_SRS_BUFFER_07_041: [ if the fromEnd variable is false, BUFFER_shrink shall remove the beginning of the buffer of size decreaseSize. ] */
+                    memcpy(tmp, handle->buffer + decreaseSize, alloc_size);
+                    free(handle->buffer);
+                    handle->buffer = tmp;
+                    handle->size = alloc_size;
+                    result = 0;
+                }
+            }
+        }
+    }
+    return result;
+}
+
+/* Codes_SRS_BUFFER_07_021: [BUFFER_size shall place the size of the associated buffer in the size variable and return zero on success.] */
+int BUFFER_size(BUFFER_HANDLE handle, size_t* size)
+{
+    int result;
+    if ((handle == NULL) || (size == NULL))
+    {
+        /* Codes_SRS_BUFFER_07_022: [BUFFER_size shall return a nonzero value for any error that is encountered.] */
+        result = MU_FAILURE;
+    }
+    else
+    {
+        BUFFER* b = (BUFFER*)handle;
+        *size = b->size;
+        result = 0;
+    }
+    return result;
+}
+
+/* Codes_SRS_BUFFER_07_024: [BUFFER_append concatenates b2 onto b1 without modifying b2 and shall return zero on success.] */
+int BUFFER_append(BUFFER_HANDLE handle1, BUFFER_HANDLE handle2)
+{
+    int result;
+    if ( (handle1 == NULL) || (handle2 == NULL) || (handle1 == handle2) )
+    {
+        /* Codes_SRS_BUFFER_07_023: [BUFFER_append shall return a nonzero upon any error that is encountered.] */
+        result = MU_FAILURE;
+    }
+    else
+    {
+        BUFFER* b1 = (BUFFER*)handle1;
+        BUFFER* b2 = (BUFFER*)handle2;
+        if (b1->buffer == NULL)
+        {
+            /* Codes_SRS_BUFFER_07_023: [BUFFER_append shall return a nonzero upon any error that is encountered.] */
+            result = MU_FAILURE;
+        }
+        else if (b2->buffer == NULL)
+        {
+            /* Codes_SRS_BUFFER_07_023: [BUFFER_append shall return a nonzero upon any error that is encountered.] */
+            result = MU_FAILURE;
+        }
+        else
+        {
+            if (b2->size ==0)
+            {
+                // b2->size = 0, whatever b1->size is, do nothing
+                result = 0;
+            }
+            else
+            {
+                // b2->size != 0, whatever b1->size is
+                unsigned char* temp = (unsigned char*)realloc(b1->buffer, b1->size + b2->size);
+                if (temp == NULL)
+                {
+                    /* Codes_SRS_BUFFER_07_023: [BUFFER_append shall return a nonzero upon any error that is encountered.] */
+                    LogError("Failure: allocating temp buffer.");
+                    result = MU_FAILURE;
+                }
+                else
+                {
+                    /* Codes_SRS_BUFFER_07_024: [BUFFER_append concatenates b2 onto b1 without modifying b2 and shall return zero on success.]*/
+                    b1->buffer = temp;
+                    // Append the BUFFER
+                    (void)memcpy(&b1->buffer[b1->size], b2->buffer, b2->size);
+                    b1->size += b2->size;
+                    result = 0;
+                }
+            }
+        }
+    }
+    return result;
+}
+
+int BUFFER_prepend(BUFFER_HANDLE handle1, BUFFER_HANDLE handle2)
+{
+    int result;
+    if ((handle1 == NULL) || (handle2 == NULL) || (handle1 == handle2))
+    {
+        /* Codes_SRS_BUFFER_01_005: [ BUFFER_prepend shall return a non-zero upon value any error that is encountered. ]*/
+        result = MU_FAILURE;
+    }
+    else
+    {
+        BUFFER* b1 = (BUFFER*)handle1;
+        BUFFER* b2 = (BUFFER*)handle2;
+        if (b1->buffer == NULL)
+        {
+            /* Codes_SRS_BUFFER_01_005: [ BUFFER_prepend shall return a non-zero upon value any error that is encountered. ]*/
+            result = MU_FAILURE;
+        }
+        else if (b2->buffer == NULL)
+        {
+            /* Codes_SRS_BUFFER_01_005: [ BUFFER_prepend shall return a non-zero upon value any error that is encountered. ]*/
+            result = MU_FAILURE;
+        }
+        else
+        {
+            //put b2 ahead of b1: [b2][b1], return b1
+            if (b2->size ==0)
+            {
+                // do nothing
+                result = 0;
+            }
+            else
+            {
+                // b2->size != 0
+                unsigned char* temp = (unsigned char*)malloc(b1->size + b2->size);
+                if (temp == NULL)
+                {
+                    /* Codes_SRS_BUFFER_01_005: [ BUFFER_prepend shall return a non-zero upon value any error that is encountered. ]*/
+                    LogError("Failure: allocating temp buffer.");
+                    result = MU_FAILURE;
+                }
+                else
+                {
+                    /* Codes_SRS_BUFFER_01_004: [ BUFFER_prepend concatenates handle1 onto handle2 without modifying handle1 and shall return zero on success. ]*/
+                    // Append the BUFFER
+                    (void)memcpy(temp, b2->buffer, b2->size);
+                    // start from b1->size to append b1
+                    (void)memcpy(&temp[b2->size], b1->buffer, b1->size);
+                    free(b1->buffer);
+                    b1->buffer = temp;
+                    b1->size += b2->size;
+                    result = 0;
+                }
+            }
+        }
+    }
+    return result;
+}
+
+int BUFFER_fill(BUFFER_HANDLE handle, unsigned char fill_char)
+{
+    int result;
+    if (handle == NULL)
+    {
+        /* Codes_SRS_BUFFER_07_002: [ If handle is NULL BUFFER_fill shall return a non-zero value. ] */
+        LogError("Invalid parameter specified, handle == NULL.");
+        result = MU_FAILURE;
+    }
+    else
+    {
+        size_t index;
+        /* Codes_SRS_BUFFER_07_001: [ BUFFER_fill shall fill the supplied BUFFER_HANDLE with the supplied fill character. ] */
+        BUFFER* buffer_data = (BUFFER*)handle;
+        for (index = 0; index < buffer_data->size; index++)
+        {
+            buffer_data->buffer[index] = fill_char;
+        }
+        result = 0;
+    }
+    return result;
+}
+
+
+/* Codes_SRS_BUFFER_07_025: [BUFFER_u_char shall return a pointer to the underlying unsigned char*.] */
+unsigned char* BUFFER_u_char(BUFFER_HANDLE handle)
+{
+    BUFFER* handleData = (BUFFER*)handle;
+    unsigned char* result;
+    if (handle == NULL || handleData->size == 0)
+    {
+        /* Codes_SRS_BUFFER_07_026: [BUFFER_u_char shall return NULL for any error that is encountered.] */
+        /* Codes_SRS_BUFFER_07_029: [BUFFER_u_char shall return NULL if underlying buffer size is zero.] */
+        result = NULL;
+    }
+    else
+    {
+        result = handleData->buffer;
+    }
+    return result;
+}
+
+/* Codes_SRS_BUFFER_07_027: [BUFFER_length shall return the size of the underlying buffer.] */
+size_t BUFFER_length(BUFFER_HANDLE handle)
+{
+    size_t result;
+    if (handle == NULL)
+    {
+        /* Codes_SRS_BUFFER_07_028: [BUFFER_length shall return zero for any error that is encountered.] */
+        result = 0;
+    }
+    else
+    {
+        BUFFER* b = (BUFFER*)handle;
+        result = b->size;
+    }
+    return result;
+}
+
+BUFFER_HANDLE BUFFER_clone(BUFFER_HANDLE handle)
+{
+    BUFFER_HANDLE result;
+    if (handle == NULL)
+    {
+        result = NULL;
+    }
+    else
+    {
+        BUFFER* suppliedBuff = (BUFFER*)handle;
+        BUFFER* b = (BUFFER*)calloc(1, sizeof(BUFFER));
+        if (b != NULL)
+        {
+            if (BUFFER_safemalloc(b, suppliedBuff->size) != 0)
+            {
+                free(b);
+                LogError("Failure: allocating temp buffer.");
+                result = NULL;
+            }
+            else
+            {
+                (void)memcpy(b->buffer, suppliedBuff->buffer, suppliedBuff->size);
+                b->size = suppliedBuff->size;
+                result = (BUFFER_HANDLE)b;
+            }
+        }
+        else
+        {
+            result = NULL;
+        }
+    }
+    return result;
+}
Index: azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/src/connection_string_parser.c
===================================================================
--- azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/src/connection_string_parser.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/src/connection_string_parser.c	(revision 457)
@@ -0,0 +1,234 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+#include <stdbool.h>
+#include "azure_c_shared_utility/connection_string_parser.h"
+#include "azure_c_shared_utility/map.h"
+#include "azure_c_shared_utility/strings.h"
+#include "azure_c_shared_utility/string_tokenizer.h"
+#include "azure_c_shared_utility/optimize_size.h"
+#include "azure_c_shared_utility/xlogging.h"
+
+
+MAP_HANDLE connectionstringparser_parse_from_char(const char* connection_string)
+{
+    MAP_HANDLE result;
+    STRING_HANDLE connString = NULL;
+
+    /* Codes_SRS_CONNECTIONSTRINGPARSER_21_020: [connectionstringparser_parse_from_char shall create a STRING_HANDLE from the connection_string passed in as argument and parse it using the connectionstringparser_parse.]*/
+    if ((connString = STRING_construct(connection_string)) == NULL)
+    {
+        /* Codes_SRS_CONNECTIONSTRINGPARSER_21_021: [If connectionstringparser_parse_from_char get error creating a STRING_HANDLE, it shall return NULL.]*/
+        LogError("Error constructing connection String");
+        result = NULL;
+    }
+    else
+    {
+        result = connectionstringparser_parse(connString);
+        STRING_delete(connString);
+    }
+
+    return result;
+}
+
+/* Codes_SRS_CONNECTIONSTRINGPARSER_01_001: [connectionstringparser_parse shall parse all key value pairs from the connection_string passed in as argument and return a new map that holds the key/value pairs.] */
+MAP_HANDLE connectionstringparser_parse(STRING_HANDLE connection_string)
+{
+    MAP_HANDLE result;
+
+    if (connection_string == NULL)
+    {
+        /* Codes_SRS_CONNECTIONSTRINGPARSER_01_002: [If connection_string is NULL then connectionstringparser_parse shall fail and return NULL.] */
+        result = NULL;
+        LogError("NULL connection string passed to tokenizer.");
+    }
+    else
+    {
+        /* Codes_SRS_CONNECTIONSTRINGPARSER_01_003: [connectionstringparser_parse shall create a STRING tokenizer to be used for parsing the connection string, by calling STRING_TOKENIZER_create.] */
+        /* Codes_SRS_CONNECTIONSTRINGPARSER_01_004: [connectionstringparser_parse shall start scanning at the beginning of the connection string.] */
+        STRING_TOKENIZER_HANDLE tokenizer = STRING_TOKENIZER_create(connection_string);
+        if (tokenizer == NULL)
+        {
+            /* Codes_SRS_CONNECTIONSTRINGPARSER_01_015: [If STRING_TOKENIZER_create fails, connectionstringparser_parse shall fail and return NULL.] */
+            result = NULL;
+            LogError("Error creating STRING tokenizer.");
+        }
+        else
+        {
+            /* Codes_SRS_CONNECTIONSTRINGPARSER_01_016: [2 STRINGs shall be allocated in order to hold the to be parsed key and value tokens.] */
+            STRING_HANDLE token_key_string = STRING_new();
+            if (token_key_string == NULL)
+            {
+                /* Codes_SRS_CONNECTIONSTRINGPARSER_01_017: [If allocating the STRINGs fails connectionstringparser_parse shall fail and return NULL.] */
+                result = NULL;
+                LogError("Error creating key token STRING.");
+            }
+            else
+            {
+                STRING_HANDLE token_value_string = STRING_new();
+                if (token_value_string == NULL)
+                {
+                    /* Codes_SRS_CONNECTIONSTRINGPARSER_01_017: [If allocating the STRINGs fails connectionstringparser_parse shall fail and return NULL.] */
+                    result = NULL;
+                    LogError("Error creating value token STRING.");
+                }
+                else
+                {
+                    result = Map_Create(NULL);
+                    if (result == NULL)
+                    {
+                        /* Codes_SRS_CONNECTIONSTRINGPARSER_01_018: [If creating the result map fails, then connectionstringparser_parse shall return NULL.] */
+                        LogError("Error creating Map.");
+                    }
+                    else
+                    {
+                        /* Codes_SRS_CONNECTIONSTRINGPARSER_01_005: [The following actions shall be repeated until parsing is complete:] */
+                        /* Codes_SRS_CONNECTIONSTRINGPARSER_01_006: [connectionstringparser_parse shall find a token (the key of the key/value pair) delimited by the = character, by calling STRING_TOKENIZER_get_next_token.] */
+                        /* Codes_SRS_CONNECTIONSTRINGPARSER_01_007: [If STRING_TOKENIZER_get_next_token fails, parsing shall be considered complete.] */
+                        while (STRING_TOKENIZER_get_next_token(tokenizer, token_key_string, "=") == 0)
+                        {
+                            bool is_error = false;
+
+                            /* Codes_SRS_CONNECTIONSTRINGPARSER_01_008: [connectionstringparser_parse shall find a token (the value of the key/value pair) delimited by the ; character, by calling STRING_TOKENIZER_get_next_token.] */
+                            if (STRING_TOKENIZER_get_next_token(tokenizer, token_value_string, ";") != 0)
+                            {
+                                /* Codes_SRS_CONNECTIONSTRINGPARSER_01_009: [If STRING_TOKENIZER_get_next_token fails, connectionstringparser_parse shall fail and return NULL (freeing the allocated result map).] */
+                                is_error = true;
+                                LogError("Error reading value token from the connection string.");
+                            }
+                            else
+                            {
+                                /* Codes_SRS_CONNECTIONSTRINGPARSER_01_011: [The C strings for the key and value shall be extracted from the previously parsed STRINGs by using STRING_c_str.] */
+                                const char* token = STRING_c_str(token_key_string);
+                                /* Codes_SRS_CONNECTIONSTRINGPARSER_01_013: [If STRING_c_str fails then connectionstringparser_parse shall fail and return NULL (freeing the allocated result map).] */
+                                if ((token == NULL) ||
+                                    /* Codes_SRS_CONNECTIONSTRINGPARSER_01_019: [If the key length is zero then connectionstringparser_parse shall fail and return NULL (freeing the allocated result map).] */
+                                    (strlen(token) == 0))
+                                {
+                                    is_error = true;
+                                    LogError("The key token is NULL or empty.");
+                                }
+                                else
+                                {
+                                    /* Codes_SRS_CONNECTIONSTRINGPARSER_01_011: [The C strings for the key and value shall be extracted from the previously parsed STRINGs by using STRING_c_str.] */
+                                    const char* value = STRING_c_str(token_value_string);
+                                    if (value == NULL)
+                                    {
+                                        /* Codes_SRS_CONNECTIONSTRINGPARSER_01_013: [If STRING_c_str fails then connectionstringparser_parse shall fail and return NULL (freeing the allocated result map).] */
+                                        is_error = true;
+                                        LogError("Could not get C string for value token.");
+                                    }
+                                    else
+                                    {
+                                        /* Codes_SRS_CONNECTIONSTRINGPARSER_01_010: [The key and value shall be added to the result map by using Map_Add.] */
+                                        if (Map_Add(result, token, value) != MAP_OK)
+                                        {
+                                            /* Codes_SRS_CONNECTIONSTRINGPARSER_01_012: [If Map_Add fails connectionstringparser_parse shall fail and return NULL (freeing the allocated result map).] */
+                                            is_error = true;
+                                            LogError("Could not add the key/value pair to the result map.");
+                                        }
+                                    }
+                                }
+                            }
+
+                            if (is_error)
+                            {
+                                LogError("Error parsing connection string.");
+                                Map_Destroy(result);
+                                result = NULL;
+                                break;
+                            }
+                        }
+                    }
+
+                    STRING_delete(token_value_string);
+                }
+
+                STRING_delete(token_key_string);
+            }
+
+            /* Codes_SRS_CONNECTIONSTRINGPARSER_01_014: [After the parsing is complete the previously allocated STRINGs and STRING tokenizer shall be freed by calling STRING_TOKENIZER_destroy.] */
+            STRING_TOKENIZER_destroy(tokenizer);
+        }
+    }
+
+    return result;
+}
+
+/* Codes_SRS_CONNECTIONSTRINGPARSER_21_022: [connectionstringparser_splitHostName_from_char shall split the provided hostName in name and suffix.]*/
+int connectionstringparser_splitHostName_from_char(const char* hostName, STRING_HANDLE nameString, STRING_HANDLE suffixString)
+{
+    int result;
+    const char* runHostName = hostName;
+
+    if ((hostName == NULL) || ((*hostName) == '\0') || ((*hostName) == '.') || (nameString == NULL) || (suffixString == NULL))
+    {
+        /* Codes_SRS_CONNECTIONSTRINGPARSER_21_026: [If the hostName is NULL, connectionstringparser_splitHostName_from_char shall return MU_FAILURE.]*/
+        /* Codes_SRS_CONNECTIONSTRINGPARSER_21_027: [If the hostName is an empty string, connectionstringparser_splitHostName_from_char shall return MU_FAILURE.]*/
+        /* Codes_SRS_CONNECTIONSTRINGPARSER_21_028: [If the nameString is NULL, connectionstringparser_splitHostName_from_char shall return MU_FAILURE.]*/
+        /* Codes_SRS_CONNECTIONSTRINGPARSER_21_029: [If the suffixString is NULL, connectionstringparser_splitHostName_from_char shall return MU_FAILURE.]*/
+        /* Codes_SRS_CONNECTIONSTRINGPARSER_21_030: [If the hostName is not a valid host name, connectionstringparser_splitHostName_from_char shall return MU_FAILURE.]*/
+        result = MU_FAILURE;
+    }
+    else
+    {
+        while ((*runHostName) != '\0')
+        {
+            if ((*runHostName) == '.')
+            {
+                /* Codes_SRS_CONNECTIONSTRINGPARSER_21_023: [connectionstringparser_splitHostName_from_char shall copy all characters, from the beginning of the hostName to the first . to the nameString.]*/
+                /* Codes_SRS_CONNECTIONSTRINGPARSER_21_024: [connectionstringparser_splitHostName_from_char shall copy all characters, from the first . to the end of the hostName, to the suffixString.]*/
+                runHostName++;
+                break;
+            }
+            runHostName++;
+        }
+
+        if ((*runHostName) == '\0')
+        {
+            /* Codes_SRS_CONNECTIONSTRINGPARSER_21_030: [If the hostName is not a valid host name, connectionstringparser_splitHostName_from_char shall return MU_FAILURE.]*/
+            result = MU_FAILURE;
+        }
+        else
+        {
+            /* Codes_SRS_CONNECTIONSTRINGPARSER_21_023: [connectionstringparser_splitHostName_from_char shall copy all characters, from the beginning of the hostName to the first . to the nameString.]*/
+            if (STRING_copy_n(nameString, hostName, runHostName - hostName - 1) != 0)
+            {
+                /* Codes_SRS_CONNECTIONSTRINGPARSER_21_031: [If connectionstringparser_splitHostName_from_char get error copying the name to the nameString, it shall return MU_FAILURE.]*/
+                result = MU_FAILURE;
+            }
+            /* Codes_SRS_CONNECTIONSTRINGPARSER_21_024: [connectionstringparser_splitHostName_from_char shall copy all characters, from the first . to the end of the hostName, to the suffixString.]*/
+            else if (STRING_copy(suffixString, runHostName) != 0)
+            {
+                /* Codes_SRS_CONNECTIONSTRINGPARSER_21_032: [If connectionstringparser_splitHostName_from_char get error copying the suffix to the suffixString, it shall return MU_FAILURE.]*/
+                result = MU_FAILURE;
+            }
+            else
+            {
+                /* Codes_SRS_CONNECTIONSTRINGPARSER_21_025: [If connectionstringparser_splitHostName_from_char get success splitting the hostName, it shall return 0.]*/
+                result = 0;
+            }
+        }
+    }
+
+    return result;
+}
+
+
+int connectionstringparser_splitHostName(STRING_HANDLE hostNameString, STRING_HANDLE nameString, STRING_HANDLE suffixString)
+{
+    int result;
+
+    if (hostNameString == NULL)
+    {
+        /* Codes_SRS_CONNECTIONSTRINGPARSER_21_034: [If the hostNameString is NULL, connectionstringparser_splitHostName shall return MU_FAILURE.]*/
+        result = MU_FAILURE;
+    }
+    else
+    {
+        /* Codes_SRS_CONNECTIONSTRINGPARSER_21_033: [connectionstringparser_splitHostName shall convert the hostNameString to a connection_string passed in as argument, and call connectionstringparser_splitHostName_from_char.]*/
+        result = connectionstringparser_splitHostName_from_char(STRING_c_str(hostNameString), nameString, suffixString);
+    }
+
+    return result;
+}
Index: azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/src/consolelogger.c
===================================================================
--- azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/src/consolelogger.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/src/consolelogger.c	(revision 457)
@@ -0,0 +1,230 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+#include <stdarg.h>
+#include <stdio.h>
+#include <time.h>
+#include "azure_c_shared_utility/xlogging.h"
+#include "azure_c_shared_utility/consolelogger.h"
+
+#if (defined(_MSC_VER))
+#include "windows.h"
+
+/*returns a string as if printed by vprintf*/
+static char* vprintf_alloc(const char* format, va_list va)
+{
+    char* result;
+    int neededSize = vsnprintf(NULL, 0, format, va);
+    if (neededSize < 0)
+    {
+        result = NULL;
+    }
+    else
+    {
+        result = (char*)malloc(neededSize + 1);
+        if (result == NULL)
+        {
+            /*return as is*/
+        }
+        else
+        {
+            if (vsnprintf(result, neededSize + 1, format, va) != neededSize)
+            {
+                free(result);
+                result = NULL;
+            }
+        }
+    }
+    return result;
+}
+
+/*returns a string as if printed by printf*/
+static char* printf_alloc(const char* format, ...)
+{
+    char* result;
+    va_list va;
+    va_start(va, format);
+    result = vprintf_alloc(format, va);
+    va_end(va);
+    return result;
+}
+
+/*returns NULL if it fails*/
+static char* lastErrorToString(DWORD lastError)
+{
+    char* result;
+    if (lastError == 0)
+    {
+        result = printf_alloc(""); /*no error should appear*/
+        if (result == NULL)
+        {
+            (void)printf("failure in printf_alloc");
+        }
+        else
+        {
+            /*return as is*/
+        }
+    }
+    else
+    {
+        char temp[MESSAGE_BUFFER_SIZE];
+        if (FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, lastError, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), temp, MESSAGE_BUFFER_SIZE, NULL) == 0)
+        {
+            result = printf_alloc("GetLastError()=0X%x", lastError);
+            if (result == NULL)
+            {
+                (void)printf("failure in printf_alloc\n");
+                /*return as is*/
+            }
+            else
+            {
+                /*return as is*/
+            }
+        }
+        else
+        {
+            /*eliminate the \r or \n from the string*/
+            /*one replace of each is enough*/
+            char* whereAreThey;
+            if ((whereAreThey = strchr(temp, '\r')) != NULL)
+            {
+                *whereAreThey = '\0';
+            }
+            if ((whereAreThey = strchr(temp, '\n')) != NULL)
+            {
+                *whereAreThey = '\0';
+            }
+
+            result = printf_alloc("GetLastError()==0X%x (%s)", lastError, temp);
+
+            if (result == NULL)
+            {
+                (void)printf("failure in printf_alloc\n");
+                /*return as is*/
+            }
+            else
+            {
+                /*return as is*/
+            }
+        }
+    }
+    return result;
+}
+/*this function will use 1x printf (in the happy case) .*/
+/*more than 1x printf / function call can mean intermingled LogErrors in a multithreaded env*/
+/*the function will also attempt to produce some human readable strings for GetLastError*/
+void consolelogger_log_with_GetLastError(const char* file, const char* func, int line, const char* format, ...)
+{
+    DWORD lastError;
+    char* lastErrorAsString;
+    int lastErrorAsString_should_be_freed;
+    time_t t;
+    int systemMessage_should_be_freed;
+    char* systemMessage;
+    int userMessage_should_be_freed;
+    char* userMessage;
+
+    va_list args;
+    va_start(args, format);
+
+    /*this is what this case will do:
+    1. snip the last error
+    2. create a string with what that last error means
+    3. printf the system message (__FILE__, __LINE__ etc) + the last error + whatever the user wanted
+    */
+    /*1. snip the last error*/
+    lastError = GetLastError();
+
+    /*2. create a string with what that last error means*/
+    lastErrorAsString = lastErrorToString(lastError);
+    if (lastErrorAsString == NULL)
+    {
+        (void)printf("failure in lastErrorToString");
+        lastErrorAsString = "";
+        lastErrorAsString_should_be_freed = 0;
+    }
+    else
+    {
+        lastErrorAsString_should_be_freed = 1;
+    }
+
+    t = time(NULL);
+    systemMessage = printf_alloc("Error: Time:%.24s File:%s Func:%s Line:%d %s", ctime(&t), file, func, line, lastErrorAsString);
+
+    if (systemMessage == NULL)
+    {
+        systemMessage = "";
+        (void)printf("Error: [FAILED] Time:%.24s File : %s Func : %s Line : %d %s", ctime(&t), file, func, line, lastErrorAsString);
+        systemMessage_should_be_freed = 0;
+    }
+    else
+    {
+        systemMessage_should_be_freed = 1;
+    }
+
+    userMessage = vprintf_alloc(format, args);
+    if (userMessage == NULL)
+    {
+        (void)printf("[FAILED] ");
+        (void)vprintf(format, args);
+        (void)printf("\n");
+        userMessage_should_be_freed = 0;
+    }
+    else
+    {
+        /*3. printf the system message(__FILE__, __LINE__ etc) + the last error + whatever the user wanted*/
+        (void)printf("%s %s\n", systemMessage, userMessage);
+        userMessage_should_be_freed = 1;
+    }
+
+    if (userMessage_should_be_freed == 1)
+    {
+        free(userMessage);
+    }
+
+    if (systemMessage_should_be_freed == 1)
+    {
+        free(systemMessage);
+    }
+
+    if (lastErrorAsString_should_be_freed == 1)
+    {
+        free(lastErrorAsString);
+    }
+    va_end(args);
+}
+#endif
+
+#if defined(__GNUC__)
+__attribute__ ((format (printf, 6, 7)))
+#endif
+void consolelogger_log(LOG_CATEGORY log_category, const char* file, const char* func, int line, unsigned int options, const char* format, ...)
+{
+    time_t t;
+    va_list args;
+    va_start(args, format);
+
+    t = time(NULL);
+
+    switch (log_category)
+    {
+    case AZ_LOG_INFO:
+        (void)printf("Info: ");
+        break;
+    case AZ_LOG_ERROR:
+        (void)printf("Error: Time:%.24s File:%s Func:%s Line:%d ", ctime(&t), file, func, line);
+        break;
+    default:
+        break;
+    }
+
+    (void)vprintf(format, args);
+    va_end(args);
+
+    (void)log_category;
+    if (options & LOG_LINE)
+    {
+        (void)printf("\r\n");
+    }
+}
+
Index: azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/src/constbuffer.c
===================================================================
--- azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/src/constbuffer.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/src/constbuffer.c	(revision 457)
@@ -0,0 +1,350 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+#include <stdlib.h>
+#include <stdbool.h>
+#include "azure_macro_utils/macro_utils.h"
+#include "azure_c_shared_utility/gballoc.h"
+#include "azure_c_shared_utility/xlogging.h"
+#include "azure_c_shared_utility/refcount.h"
+
+#include "azure_c_shared_utility/constbuffer.h"
+
+#define CONSTBUFFER_TYPE_VALUES \
+    CONSTBUFFER_TYPE_COPIED, \
+    CONSTBUFFER_TYPE_MEMORY_MOVED, \
+    CONSTBUFFER_TYPE_WITH_CUSTOM_FREE, \
+    CONSTBUFFER_TYPE_FROM_OFFSET_AND_SIZE
+
+MU_DEFINE_ENUM(CONSTBUFFER_TYPE, CONSTBUFFER_TYPE_VALUES)
+
+typedef struct CONSTBUFFER_HANDLE_DATA_TAG
+{
+    CONSTBUFFER alias;
+    COUNT_TYPE count;
+    CONSTBUFFER_TYPE buffer_type;
+    CONSTBUFFER_CUSTOM_FREE_FUNC custom_free_func;
+    void* custom_free_func_context;
+    CONSTBUFFER_HANDLE originalHandle; /*where the CONSTBUFFER_TYPE_FROM_OFFSET_AND_SIZE was build from*/
+} CONSTBUFFER_HANDLE_DATA;
+
+static CONSTBUFFER_HANDLE CONSTBUFFER_Create_Internal(const unsigned char* source, size_t size)
+{
+    CONSTBUFFER_HANDLE result;
+    /*Codes_SRS_CONSTBUFFER_02_005: [The non-NULL handle returned by CONSTBUFFER_Create shall have its ref count set to "1".]*/
+    /*Codes_SRS_CONSTBUFFER_02_010: [The non-NULL handle returned by CONSTBUFFER_CreateFromBuffer shall have its ref count set to "1".]*/
+    result = (CONSTBUFFER_HANDLE)calloc(1, (sizeof(CONSTBUFFER_HANDLE_DATA) + size));
+    if (result == NULL)
+    {
+        /*Codes_SRS_CONSTBUFFER_02_003: [If creating the copy fails then CONSTBUFFER_Create shall return NULL.]*/
+        /*Codes_SRS_CONSTBUFFER_02_008: [If copying the content fails, then CONSTBUFFER_CreateFromBuffer shall fail and return NULL.] */
+        LogError("unable to malloc");
+        /*return as is*/
+    }
+    else
+    {
+        INIT_REF_VAR(result->count);
+
+        /*Codes_SRS_CONSTBUFFER_02_002: [Otherwise, CONSTBUFFER_Create shall create a copy of the memory area pointed to by source having size bytes.]*/
+        result->alias.size = size;
+        if (size == 0)
+        {
+            result->alias.buffer = NULL;
+        }
+        else
+        {
+            unsigned char* temp = (unsigned char*)(result + 1);
+            /*Codes_SRS_CONSTBUFFER_02_004: [Otherwise CONSTBUFFER_Create shall return a non-NULL handle.]*/
+            /*Codes_SRS_CONSTBUFFER_02_007: [Otherwise, CONSTBUFFER_CreateFromBuffer shall copy the content of buffer.]*/
+            /*Codes_SRS_CONSTBUFFER_02_009: [Otherwise, CONSTBUFFER_CreateFromBuffer shall return a non-NULL handle.]*/
+            (void)memcpy(temp, source, size);
+            result->alias.buffer = temp;
+        }
+
+        result->buffer_type = CONSTBUFFER_TYPE_COPIED;
+    }
+    return result;
+}
+
+IMPLEMENT_MOCKABLE_FUNCTION(, CONSTBUFFER_HANDLE, CONSTBUFFER_Create, const unsigned char*, source, size_t, size)
+{
+    CONSTBUFFER_HANDLE result;
+    /*Codes_SRS_CONSTBUFFER_02_001: [If source is NULL and size is different than 0 then CONSTBUFFER_Create shall fail and return NULL.]*/
+    if (
+        (source == NULL) &&
+        (size != 0)
+        )
+    {
+        LogError("invalid arguments passes to CONSTBUFFER_Create");
+        result = NULL;
+    }
+    else
+    {
+        result = CONSTBUFFER_Create_Internal(source, size);
+    }
+    return result;
+}
+
+/*this creates a new constbuffer from an existing BUFFER_HANDLE*/
+IMPLEMENT_MOCKABLE_FUNCTION(, CONSTBUFFER_HANDLE, CONSTBUFFER_CreateFromBuffer, BUFFER_HANDLE, buffer)
+{
+    CONSTBUFFER_HANDLE result;
+    /*Codes_SRS_CONSTBUFFER_02_006: [If buffer is NULL then CONSTBUFFER_CreateFromBuffer shall fail and return NULL.]*/
+    if (buffer == NULL)
+    {
+        LogError("invalid arg passed to CONSTBUFFER_CreateFromBuffer");
+        result = NULL;
+    }
+    else
+    {
+        size_t length = BUFFER_length(buffer);
+        unsigned char* rawBuffer = BUFFER_u_char(buffer);
+        result = CONSTBUFFER_Create_Internal(rawBuffer, length);
+    }
+    return result;
+}
+
+IMPLEMENT_MOCKABLE_FUNCTION(, CONSTBUFFER_HANDLE, CONSTBUFFER_CreateWithMoveMemory, unsigned char*, source, size_t, size)
+{
+    CONSTBUFFER_HANDLE result;
+
+    /* Codes_SRS_CONSTBUFFER_01_001: [ If source is NULL and size is different than 0 then CONSTBUFFER_Create shall fail and return NULL. ]*/
+    if ((source == NULL) && (size > 0))
+    {
+        LogError("Invalid arguments: unsigned char* source=%p, size_t size=%u", source, (unsigned int)size);
+        result = NULL;
+    }
+    else
+    {
+        result = (CONSTBUFFER_HANDLE)calloc(1, sizeof(CONSTBUFFER_HANDLE_DATA));
+        if (result == NULL)
+        {
+            /* Codes_SRS_CONSTBUFFER_01_005: [ If any error occurs, CONSTBUFFER_CreateWithMoveMemory shall fail and return NULL. ]*/
+            LogError("malloc failed");
+        }
+        else
+        {
+            /* Codes_SRS_CONSTBUFFER_01_004: [ If source is non-NULL and size is 0, the source pointer shall be owned (and freed) by the newly created instance of const buffer. ]*/
+            /* Codes_SRS_CONSTBUFFER_01_002: [ CONSTBUFFER_CreateWithMoveMemory shall store the source and size and return a non-NULL handle to the newly created const buffer. ]*/
+            result->alias.buffer = source;
+            result->alias.size = size;
+            result->buffer_type = CONSTBUFFER_TYPE_MEMORY_MOVED;
+
+            /* Codes_SRS_CONSTBUFFER_01_003: [ The non-NULL handle returned by CONSTBUFFER_CreateWithMoveMemory shall have its ref count set to "1". ]*/
+            INIT_REF_VAR(result->count);
+        }
+    }
+
+    return result;
+}
+
+IMPLEMENT_MOCKABLE_FUNCTION(, CONSTBUFFER_HANDLE, CONSTBUFFER_CreateWithCustomFree, const unsigned char*, source, size_t, size, CONSTBUFFER_CUSTOM_FREE_FUNC, customFreeFunc, void*, customFreeFuncContext)
+{
+    CONSTBUFFER_HANDLE result;
+
+    /* Codes_SRS_CONSTBUFFER_01_014: [ customFreeFuncContext shall be allowed to be NULL. ]*/
+
+    if (
+        /* Codes_SRS_CONSTBUFFER_01_006: [ If source is NULL and size is different than 0 then CONSTBUFFER_CreateWithCustomFree shall fail and return NULL. ]*/
+        ((source == NULL) && (size > 0)) ||
+        /* Codes_SRS_CONSTBUFFER_01_013: [ If customFreeFunc is NULL, CONSTBUFFER_CreateWithCustomFree shall fail and return NULL. ]*/
+        (customFreeFunc == NULL)
+        )
+    {
+        LogError("Invalid arguments: unsigned char* source=%p, size_t size=%u, customFreeFunc=%p, customFreeFuncContext=%p",
+            source, (unsigned int)size, customFreeFunc, customFreeFuncContext);
+        result = NULL;
+    }
+    else
+    {
+        result = (CONSTBUFFER_HANDLE)calloc(1, sizeof(CONSTBUFFER_HANDLE_DATA));
+        if (result == NULL)
+        {
+            /* Codes_SRS_CONSTBUFFER_01_011: [ If any error occurs, CONSTBUFFER_CreateWithMoveMemory shall fail and return NULL. ]*/
+            LogError("malloc failed");
+        }
+        else
+        {
+            /* Codes_SRS_CONSTBUFFER_01_007: [ If source is non-NULL and size is 0, the source pointer shall be owned (and freed) by the newly created instance of const buffer. ]*/
+            /* Codes_SRS_CONSTBUFFER_01_008: [ CONSTBUFFER_CreateWithCustomFree shall store the source and size and return a non-NULL handle to the newly created const buffer. ]*/
+            result->alias.buffer = source;
+            result->alias.size = size;
+            result->buffer_type = CONSTBUFFER_TYPE_WITH_CUSTOM_FREE;
+
+            /* Codes_SRS_CONSTBUFFER_01_009: [ CONSTBUFFER_CreateWithCustomFree shall store customFreeFunc and customFreeFuncContext in order to use them to free the memory when the CONST buffer resources are freed. ]*/
+            result->custom_free_func = customFreeFunc;
+            result->custom_free_func_context = customFreeFuncContext;
+
+            /* Codes_SRS_CONSTBUFFER_01_010: [ The non-NULL handle returned by CONSTBUFFER_CreateWithCustomFree shall have its ref count set to 1. ]*/
+            INIT_REF_VAR(result->count);
+        }
+    }
+
+    return result;
+}
+
+IMPLEMENT_MOCKABLE_FUNCTION(, CONSTBUFFER_HANDLE, CONSTBUFFER_CreateFromOffsetAndSize, CONSTBUFFER_HANDLE, handle, size_t, offset, size_t, size)
+{
+    CONSTBUFFER_HANDLE result;
+
+    if (
+        /*Codes_SRS_CONSTBUFFER_02_025: [ If handle is NULL then CONSTBUFFER_CreateFromOffsetAndSize shall fail and return NULL. ]*/
+        (handle == NULL) ||
+        /*Codes_SRS_CONSTBUFFER_02_026: [ If offset is greater than or equal to handles's size then CONSTBUFFER_CreateFromOffsetAndSize shall fail and return NULL. ]*/
+        (offset > handle->alias.size) ||
+        /*Codes_SRS_CONSTBUFFER_02_032: [ If there are any failures then CONSTBUFFER_CreateFromOffsetAndSize shall fail and return NULL. ]*/
+        (offset > SIZE_MAX - size) ||
+        /*Codes_SRS_CONSTBUFFER_02_027: [ If offset + size exceed handles's size then CONSTBUFFER_CreateFromOffsetAndSize shall fail and return NULL. ]*/
+        (offset + size > handle->alias.size)
+        )
+    {
+        LogError("invalid arguments CONSTBUFFER_HANDLE handle=%p, size_t offset=%zu, size_t size=%zu",
+            handle, offset, size);
+        result = NULL;
+    }
+    else
+    {
+        /*Codes_SRS_CONSTBUFFER_02_028: [ CONSTBUFFER_CreateFromOffsetAndSize shall allocate memory for a new CONSTBUFFER_HANDLE's content. ]*/
+        result = (CONSTBUFFER_HANDLE)calloc(1, sizeof(CONSTBUFFER_HANDLE_DATA));
+        if (result == NULL)
+        {
+            /*Codes_SRS_CONSTBUFFER_02_032: [ If there are any failures then CONSTBUFFER_CreateFromOffsetAndSize shall fail and return NULL. ]*/
+            LogError("failure in malloc(sizeof(CONSTBUFFER_HANDLE_DATA)=%zu)", sizeof(CONSTBUFFER_HANDLE_DATA));
+            /*return as is*/
+        }
+        else
+        {
+            result->buffer_type = CONSTBUFFER_TYPE_FROM_OFFSET_AND_SIZE;
+            result->alias.buffer = handle->alias.buffer+offset;
+            result->alias.size = size;
+
+            /*Codes_SRS_CONSTBUFFER_02_030: [ CONSTBUFFER_CreateFromOffsetAndSize shall increment the reference count of handle. ]*/
+            INC_REF_VAR(handle->count);
+            result->originalHandle = handle;
+
+            /*Codes_SRS_CONSTBUFFER_02_029: [ CONSTBUFFER_CreateFromOffsetAndSize shall set the ref count of the newly created CONSTBUFFER_HANDLE to the initial value. ]*/
+            INIT_REF_VAR(result->count);
+
+            /*Codes_SRS_CONSTBUFFER_02_031: [ CONSTBUFFER_CreateFromOffsetAndSize shall succeed and return a non-NULL value. ]*/
+        }
+    }
+    return result;
+}
+
+IMPLEMENT_MOCKABLE_FUNCTION(, void, CONSTBUFFER_IncRef, CONSTBUFFER_HANDLE, constbufferHandle)
+{
+    if (constbufferHandle == NULL)
+    {
+        /*Codes_SRS_CONSTBUFFER_02_013: [If constbufferHandle is NULL then CONSTBUFFER_IncRef shall return.]*/
+        LogError("Invalid arguments: CONSTBUFFER_HANDLE constbufferHandle=%p", constbufferHandle);
+    }
+    else
+    {
+        /*Codes_SRS_CONSTBUFFER_02_014: [Otherwise, CONSTBUFFER_IncRef shall increment the reference count.]*/
+        INC_REF_VAR(constbufferHandle->count);
+    }
+}
+
+IMPLEMENT_MOCKABLE_FUNCTION(, const CONSTBUFFER*, CONSTBUFFER_GetContent, CONSTBUFFER_HANDLE, constbufferHandle)
+{
+    const CONSTBUFFER* result;
+    if (constbufferHandle == NULL)
+    {
+        /*Codes_SRS_CONSTBUFFER_02_011: [If constbufferHandle is NULL then CONSTBUFFER_GetContent shall return NULL.]*/
+        result = NULL;
+        LogError("invalid arg");
+    }
+    else
+    {
+        /*Codes_SRS_CONSTBUFFER_02_012: [Otherwise, CONSTBUFFER_GetContent shall return a const CONSTBUFFER* that matches byte by byte the original bytes used to created the const buffer and has the same length.]*/
+        result = &(constbufferHandle->alias);
+    }
+    return result;
+}
+
+static void CONSTBUFFER_DecRef_internal(CONSTBUFFER_HANDLE constbufferHandle)
+{
+    /*Codes_SRS_CONSTBUFFER_02_016: [Otherwise, CONSTBUFFER_DecRef shall decrement the refcount on the constbufferHandle handle.]*/
+    if (DEC_REF_VAR(constbufferHandle->count) == DEC_RETURN_ZERO)
+    {
+        if (constbufferHandle->buffer_type == CONSTBUFFER_TYPE_MEMORY_MOVED)
+        {
+            free((void*)constbufferHandle->alias.buffer);
+        }
+        else if (constbufferHandle->buffer_type == CONSTBUFFER_TYPE_WITH_CUSTOM_FREE)
+        {
+            /* Codes_SRS_CONSTBUFFER_01_012: [ If the buffer was created by calling CONSTBUFFER_CreateWithCustomFree, the customFreeFunc function shall be called to free the memory, while passed customFreeFuncContext as argument. ]*/
+            constbufferHandle->custom_free_func(constbufferHandle->custom_free_func_context);
+        }
+        /*Codes_SRS_CONSTBUFFER_02_024: [ If the constbufferHandle was created by calling CONSTBUFFER_CreateFromOffsetAndSize then CONSTBUFFER_DecRef shall decrement the ref count of the original handle passed to CONSTBUFFER_CreateFromOffsetAndSize. ]*/
+        else if (constbufferHandle->buffer_type == CONSTBUFFER_TYPE_FROM_OFFSET_AND_SIZE)
+        {
+            CONSTBUFFER_DecRef_internal(constbufferHandle->originalHandle);
+        }
+
+        /*Codes_SRS_CONSTBUFFER_02_017: [If the refcount reaches zero, then CONSTBUFFER_DecRef shall deallocate all resources used by the CONSTBUFFER_HANDLE.]*/
+        free(constbufferHandle);
+    }
+}
+
+IMPLEMENT_MOCKABLE_FUNCTION(, void, CONSTBUFFER_DecRef, CONSTBUFFER_HANDLE, constbufferHandle)
+{
+    if (constbufferHandle == NULL)
+    {
+        /*Codes_SRS_CONSTBUFFER_02_015: [If constbufferHandle is NULL then CONSTBUFFER_DecRef shall do nothing.]*/
+        LogError("Invalid arguments: CONSTBUFFER_HANDLE constbufferHandle=%p", constbufferHandle);
+    }
+    else
+    {
+        CONSTBUFFER_DecRef_internal(constbufferHandle);
+    }
+}
+
+
+IMPLEMENT_MOCKABLE_FUNCTION(, bool, CONSTBUFFER_HANDLE_contain_same, CONSTBUFFER_HANDLE, left, CONSTBUFFER_HANDLE, right)
+{
+    bool result;
+    if (left == NULL)
+    {
+        if (right == NULL)
+        {
+            /*Codes_SRS_CONSTBUFFER_02_018: [ If left is NULL and right is NULL then CONSTBUFFER_HANDLE_contain_same shall return true. ]*/
+            result = true;
+        }
+        else
+        {
+            /*Codes_SRS_CONSTBUFFER_02_019: [ If left is NULL and right is not NULL then CONSTBUFFER_HANDLE_contain_same shall return false. ]*/
+            result = false;
+        }
+    }
+    else
+    {
+        if (right == NULL)
+        {
+            /*Codes_SRS_CONSTBUFFER_02_020: [ If left is not NULL and right is NULL then CONSTBUFFER_HANDLE_contain_same shall return false. ]*/
+            result = false;
+        }
+        else
+        {
+            if (left->alias.size != right->alias.size)
+            {
+                /*Codes_SRS_CONSTBUFFER_02_021: [ If left's size is different than right's size then CONSTBUFFER_HANDLE_contain_same shall return false. ]*/
+                result = false;
+            }
+            else
+            {
+                if (memcmp(left->alias.buffer, right->alias.buffer, left->alias.size) != 0)
+                {
+                    /*Codes_SRS_CONSTBUFFER_02_022: [ If left's buffer is contains different bytes than rights's buffer then CONSTBUFFER_HANDLE_contain_same shall return false. ]*/
+                    result = false;
+                }
+                else
+                {
+                    /*Codes_SRS_CONSTBUFFER_02_023: [ CONSTBUFFER_HANDLE_contain_same shall return true. ]*/
+                    result = true;
+                }
+            }
+        }
+    }
+    return result;
+}
Index: azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/src/constmap.c
===================================================================
--- azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/src/constmap.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/src/constmap.c	(revision 457)
@@ -0,0 +1,226 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+#include <stdlib.h>
+#include <stdbool.h>
+#include "azure_macro_utils/macro_utils.h"
+#include "azure_c_shared_utility/gballoc.h"
+#include "azure_c_shared_utility/map.h"
+#include "azure_c_shared_utility/constmap.h"
+#include "azure_c_shared_utility/xlogging.h"
+#include "azure_c_shared_utility/refcount.h"
+
+MU_DEFINE_ENUM_STRINGS(CONSTMAP_RESULT, CONSTMAP_RESULT_VALUES);
+
+typedef struct CONSTMAP_HANDLE_DATA_TAG
+{
+    MAP_HANDLE map;
+} CONSTMAP_HANDLE_DATA;
+
+DEFINE_REFCOUNT_TYPE(CONSTMAP_HANDLE_DATA);
+
+#define LOG_CONSTMAP_ERROR(result) LogError("result = %" PRI_MU_ENUM "", MU_ENUM_VALUE(CONSTMAP_RESULT, (result)));
+
+CONSTMAP_HANDLE ConstMap_Create(MAP_HANDLE sourceMap)
+{
+    CONSTMAP_HANDLE_DATA* result = REFCOUNT_TYPE_CREATE(CONSTMAP_HANDLE_DATA);
+
+    if (result == NULL)
+    {
+        LOG_CONSTMAP_ERROR(CONSTMAP_INVALIDARG);
+    }
+    else
+    {
+        /*Codes_SRS_CONSTMAP_17_048: [ConstMap_Create shall accept any non-NULL MAP_HANDLE as input.]*/
+        /*Codes_SRS_CONSTMAP_17_001: [ConstMap_Create shall create an immutable map, populated by the key, value pairs in the source map.]*/
+        result->map = Map_Clone(sourceMap);
+        if (result->map == NULL)
+        {
+            LOG_CONSTMAP_ERROR(CONSTMAP_ERROR);
+            REFCOUNT_TYPE_DESTROY(CONSTMAP_HANDLE_DATA, result);
+            /*Codes_SRS_CONSTMAP_17_002: [If during creation there are any errors, then ConstMap_Create shall return NULL.]*/
+            result = NULL;
+        }
+    }
+    /*Codes_SRS_CONSTMAP_17_003: [Otherwise, it shall return a non-NULL handle that can be used in subsequent calls.]*/
+    return (CONSTMAP_HANDLE)result;
+}
+
+void ConstMap_Destroy(CONSTMAP_HANDLE handle)
+{
+    /*Codes_SRS_CONSTMAP_17_005: [If parameter handle is NULL then ConstMap_Destroy shall take no action.]*/
+    if (handle == NULL)
+    {
+        LOG_CONSTMAP_ERROR(CONSTMAP_INVALIDARG);
+    }
+    else
+    {
+        /*Codes_SRS_CONSTMAP_17_049: [ConstMap_Destroy shall decrement the internal reference count of the immutable map.]*/
+        if (DEC_REF(CONSTMAP_HANDLE_DATA, handle) == DEC_RETURN_ZERO)
+        {
+            /*Codes_SRS_CONSTMAP_17_004: [If the reference count is zero, ConstMap_Destroy shall release all resources associated with the immutable map.]*/
+            Map_Destroy(((CONSTMAP_HANDLE_DATA *)handle)->map);
+            REFCOUNT_TYPE_DESTROY(CONSTMAP_HANDLE_DATA, handle);
+        }
+
+    }
+}
+
+CONSTMAP_HANDLE ConstMap_Clone(CONSTMAP_HANDLE handle)
+{
+    /*Codes_SRS_CONSTMAP_17_038: [ConstMap_Clone returns NULL if parameter handle is NULL.] */
+    if (handle == NULL)
+    {
+        LOG_CONSTMAP_ERROR(CONSTMAP_INVALIDARG);
+    }
+    else
+    {
+        /*Codes_SRS_CONSTMAP_17_039: [ConstMap_Clone shall increase the internal reference count of the immutable map indicated by parameter handle]*/
+        /*Codes_SRS_CONSTMAP_17_050: [ConstMap_Clone shall return the non-NULL handle. ]*/
+        INC_REF(CONSTMAP_HANDLE_DATA, handle);
+    }
+    return (handle);
+}
+
+static CONSTMAP_RESULT ConstMap_ErrorConvert(MAP_RESULT mapResult)
+{
+    CONSTMAP_RESULT result;
+    switch (mapResult)
+    {
+        case MAP_OK:
+            result = CONSTMAP_OK;
+            break;
+        case MAP_INVALIDARG:
+            result = CONSTMAP_INVALIDARG;
+            break;
+        case MAP_KEYNOTFOUND:
+            result = CONSTMAP_KEYNOTFOUND;
+            break;
+        default:
+            result = CONSTMAP_ERROR;
+            break;
+    }
+    return result;
+}
+
+MAP_HANDLE ConstMap_CloneWriteable(CONSTMAP_HANDLE handle)
+{
+    MAP_HANDLE result = NULL;
+    if (handle == NULL)
+    {
+        /*Codes_SRS_CONSTMAP_17_051: [ConstMap_CloneWriteable returns NULL if parameter handle is NULL. ]*/
+        LOG_CONSTMAP_ERROR(CONSTMAP_INVALIDARG);
+    }
+    else
+    {
+        /*Codes_SRS_CONSTMAP_17_052: [ConstMap_CloneWriteable shall create a new, writeable map, populated by the key, value pairs in the parameter defined by handle.]*/
+        /*Codes_SRS_CONSTMAP_17_053: [If during cloning, any operation fails, then ConstMap_CloneWriteableap_Clone shall return NULL.]*/
+        /*Codes_SRS_CONSTMAP_17_054: [Otherwise, ConstMap_CloneWriteable shall return a non-NULL handle that can be used in subsequent calls.]*/
+        result = Map_Clone(((CONSTMAP_HANDLE_DATA *)handle)->map);
+    }
+    return result;
+}
+
+bool ConstMap_ContainsKey(CONSTMAP_HANDLE handle, const char* key )
+{
+    bool keyExists = false;
+    if (handle == NULL)
+    {
+        /*Codes_SRS_CONSTMAP_17_024: [If parameter handle or key are NULL then ConstMap_ContainsKey shall return false.]*/
+        LOG_CONSTMAP_ERROR(CONSTMAP_INVALIDARG);
+    }
+    else
+    {
+        if (key == NULL)
+        {
+            LOG_CONSTMAP_ERROR(CONSTMAP_INVALIDARG);
+        }
+        else
+        {
+            /*Codes_SRS_CONSTMAP_17_025: [Otherwise if a key exists then ConstMap_ContainsKey shall return true.]*/
+            MAP_RESULT mapResult = Map_ContainsKey(((CONSTMAP_HANDLE_DATA *)handle)->map, key, &keyExists);
+            if (mapResult != MAP_OK)
+            {
+                /*Codes_SRS_CONSTMAP_17_026: [If a key doesn't exist, then ConstMap_ContainsKey shall return false.]*/
+                keyExists = false;
+                LOG_CONSTMAP_ERROR(ConstMap_ErrorConvert(mapResult));
+            }
+        }
+    }
+    return keyExists;
+}
+
+bool ConstMap_ContainsValue(CONSTMAP_HANDLE handle, const char* value)
+{
+    bool valueExists = false;
+    if (handle == NULL)
+    {
+        /*Codes_SRS_CONSTMAP_17_027: [If parameter handle or value is NULL then ConstMap_ContainsValue shall return false.]*/
+        LOG_CONSTMAP_ERROR(CONSTMAP_INVALIDARG);
+    }
+    else
+    {
+        if (value == NULL)
+        {
+            LOG_CONSTMAP_ERROR(CONSTMAP_INVALIDARG);
+        }
+        else
+        {
+            /*Codes_SRS_CONSTMAP_17_028: [Otherwise, if a pair has its value equal to the parameter value, the ConstMap_ContainsValue shall return true.]*/
+            MAP_RESULT mapResult = Map_ContainsValue(((CONSTMAP_HANDLE_DATA *)handle)->map, value, &valueExists);
+            if (mapResult != MAP_OK)
+            {
+                /*Codes_SRS_CONSTMAP_17_029: [Otherwise, if such a does not exist, then ConstMap_ContainsValue shall return false.]*/
+                LOG_CONSTMAP_ERROR(ConstMap_ErrorConvert(mapResult));
+            }
+        }
+    }
+    return valueExists;
+}
+
+const char* ConstMap_GetValue(CONSTMAP_HANDLE handle, const char* key)
+{
+    const char* value = NULL;
+
+    if (handle == NULL)
+    {
+        /*Codes_SRS_CONSTMAP_17_040: [If parameter handle or key is NULL then ConstMap_GetValue returns NULL.]*/
+        LOG_CONSTMAP_ERROR(CONSTMAP_INVALIDARG);
+    }
+    else
+    {
+        if (key == NULL)
+        {
+            /*Codes_SRS_CONSTMAP_17_040: [If parameter handle or key is NULL then ConstMap_GetValue returns NULL.]*/
+            LOG_CONSTMAP_ERROR(CONSTMAP_INVALIDARG);
+        }
+        else
+        {
+            /*Codes_SRS_CONSTMAP_17_041: [If the key is not found, then ConstMap_GetValue returns NULL.]*/
+            /*Codes_SRS_CONSTMAP_17_042: [Otherwise, ConstMap_GetValue returns the key's value.]*/
+            value = Map_GetValueFromKey(((CONSTMAP_HANDLE_DATA *)handle)->map, key);
+        }
+    }
+    return value;
+}
+
+CONSTMAP_RESULT ConstMap_GetInternals(CONSTMAP_HANDLE handle, const char*const** keys, const char*const** values, size_t* count)
+{
+    CONSTMAP_RESULT result;
+    if (handle == NULL)
+    {
+        /*Codes_SRS_CONSTMAP_17_046: [If parameter handle, keys, values or count is NULL then ConstMap_GetInternals shall return CONSTMAP_INVALIDARG.]*/
+        result = CONSTMAP_INVALIDARG;
+        LOG_CONSTMAP_ERROR(result);
+    }
+    else
+    {
+        /*Codes_SRS_CONSTMAP_17_043: [ConstMap_GetInternals shall produce in *keys a pointer to an array of const char* having all the keys stored so far by the map.]
+         *Codes_SRS_CONSTMAP_17_044: [ConstMap_GetInternals shall produce in *values a pointer to an array of const char* having all the values stored so far by the map.]
+         *Codes_SRS_CONSTMAP_17_045: [ ConstMap_GetInternals shall produce in *count the number of stored keys and values.]
+         */
+        MAP_RESULT mapResult = Map_GetInternals(((CONSTMAP_HANDLE_DATA *)handle)->map, keys, values, count);
+        result = ConstMap_ErrorConvert(mapResult);
+    }
+    return result;
+}
Index: azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/src/crt_abstractions.c
===================================================================
--- azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/src/crt_abstractions.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/src/crt_abstractions.c	(revision 457)
@@ -0,0 +1,837 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+#define __STDC_WANT_LIB_EXT1__ 1
+
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <limits.h>
+#include <float.h>
+#include <math.h>
+#include <errno.h>
+#include "azure_c_shared_utility/gballoc.h"
+#include "azure_c_shared_utility/optimize_size.h"
+#include "azure_c_shared_utility/crt_abstractions.h"
+
+// VS 2008 does not have INFINITY and all the nice goodies...
+#if defined (TIZENRT)
+#define DEFINE_INFINITY 1
+#else
+
+#if defined _MSC_VER
+#if _MSC_VER <= 1500
+#define DEFINE_INFINITY 1
+#endif
+#endif
+#endif
+
+#if defined DEFINE_INFINITY
+
+#pragma warning(disable:4756 4056) // warning C4756: overflow in constant arithmetic
+
+// These defines are missing in math.h for WEC2013 SDK
+#ifndef _HUGE_ENUF
+#define _HUGE_ENUF  1e+300  // _HUGE_ENUF*_HUGE_ENUF must overflow
+#endif
+
+#define INFINITY   ((float)(_HUGE_ENUF * _HUGE_ENUF))
+#define HUGE_VALF  ((float)INFINITY)
+#define HUGE_VALL  ((long double)INFINITY)
+#define NAN        ((float)(INFINITY * 0.0F))
+#endif
+
+#if defined (_MSC_VER) || defined (MINGW_HAS_SECURE_API)
+#else
+
+/*Codes_SRS_CRT_ABSTRACTIONS_99_008: [strcat_s shall append the src to dst and terminates the resulting string with a null character.]*/
+int strcat_s(char* dst, size_t dstSizeInBytes, const char* src)
+{
+    int result;
+    /*Codes_SRS_CRT_ABSTRACTIONS_99_004: [If dst is NULL or unterminated, the error code returned shall be EINVAL & dst shall not be modified.]*/
+    if (dst == NULL)
+    {
+        result = EINVAL;
+    }
+    /*Codes_SRS_CRT_ABSTRACTIONS_99_005: [If src is NULL, the error code returned shall be EINVAL and dst[0] shall be set to 0.]*/
+    else if (src == NULL)
+    {
+        dst[0] = '\0';
+        result = EINVAL;
+    }
+    else
+    {
+        /*Codes_SRS_CRT_ABSTRACTIONS_99_006: [If the dstSizeInBytes is 0 or smaller than the required size for dst & src, the error code returned shall be ERANGE & dst[0] set to 0.]*/
+        if (dstSizeInBytes == 0)
+        {
+            result = ERANGE;
+            dst[0] = '\0';
+        }
+        else
+        {
+            size_t dstStrLen = 0;
+            size_t src_len = strlen(src);
+#ifdef __STDC_LIB_EXT1__
+            dstStrLen = strnlen_s(dst, dstSizeInBytes);
+#else
+            size_t i;
+            for(i=0; (i < dstSizeInBytes) && (dst[i]!= '\0'); i++)
+            {
+            }
+            dstStrLen = i;
+#endif
+            /*Codes_SRS_CRT_ABSTRACTIONS_99_004: [If dst is NULL or unterminated, the error code returned shall be EINVAL & dst shall not be modified.]*/
+            if (dstSizeInBytes == dstStrLen) /* this means the dst string is not terminated*/
+            {
+                result = EINVAL;
+            }
+            // If we are instructed to write too much data to the buffer
+            // return ERANGE
+            else if ((src_len + dstStrLen) >= dstSizeInBytes)
+            {
+                dst[0] = '\0';
+                result = ERANGE;
+            }
+            else
+            {
+                // memcpy should at most copy the result of strlen(src) or there may be
+                // some issues with copying unwanted memory
+                size_t bytes_to_cpy = dstSizeInBytes - dstStrLen;
+                if (bytes_to_cpy > src_len)
+                {
+                    bytes_to_cpy = src_len;
+                }
+
+                /*Codes_SRS_CRT_ABSTRACTIONS_99_009: [The initial character of src shall overwrite the terminating null character of dst.]*/
+                if (memcpy(&dst[dstStrLen], src, bytes_to_cpy) == NULL)
+                /*Codes_SRS_CRT_ABSTRACTIONS_99_006: [If the dstSizeInBytes is 0 or smaller than the required size for dst & src, the error code returned shall be ERANGE & dst[0] set to 0.]*/
+                {
+                    dst[0] = '\0';
+                    result = ERANGE;
+                }
+                else
+                {
+                    /*Codes_SRS_CRT_ABSTRACTIONS_99_003: [strcat_s shall return Zero upon success.]*/
+                    dst[dstStrLen+bytes_to_cpy] = '\0';
+                    result = 0;
+                }
+            }
+        }
+    }
+    return result;
+}
+
+/*Codes_SRS_CRT_ABSTRACTIONS_99_025: [strncpy_s shall copy the first N characters of src to dst, where N is the lesser of MaxCount and the length of src.]*/
+int strncpy_s(char* dst, size_t dstSizeInBytes, const char* src, size_t maxCount)
+{
+    int result;
+    int truncationFlag = 0;
+    /*Codes_SRS_CRT_ABSTRACTIONS_99_020: [If dst is NULL, the error code returned shall be EINVAL and dst shall not be modified.]*/
+    if (dst == NULL)
+    {
+        result = EINVAL;
+    }
+    /*Codes_SRS_CRT_ABSTRACTIONS_99_021: [If src is NULL, the error code returned shall be EINVAL and dst[0] shall be set to 0.]*/
+    else if (src == NULL)
+    {
+        dst[0] = '\0';
+        result = EINVAL;
+    }
+    /*Codes_SRS_CRT_ABSTRACTIONS_99_022: [If the dstSizeInBytes is 0, the error code returned shall be EINVAL and dst shall not be modified.]*/
+    else if (dstSizeInBytes == 0)
+    {
+        result = EINVAL;
+    }
+    else
+    {
+        size_t srcLength = strlen(src);
+        if (maxCount != _TRUNCATE)
+        {
+            /*Codes_SRS_CRT_ABSTRACTIONS_99_041: [If those N characters will fit within dst (whose size is given as dstSizeInBytes) and still leave room for a null terminator, then those characters shall be copied and a terminating null is appended; otherwise, strDest[0] is set to the null character and ERANGE error code returned.]*/
+            if (srcLength > maxCount)
+            {
+                srcLength = maxCount;
+            }
+
+            /*Codes_SRS_CRT_ABSTRACTIONS_99_023: [If dst is not NULL & dstSizeInBytes is smaller than the required size for the src string, the error code returned shall be ERANGE and dst[0] shall be set to 0.]*/
+            if (srcLength + 1 > dstSizeInBytes)
+            {
+                dst[0] = '\0';
+                result = ERANGE;
+            }
+            else
+            {
+                (void)memcpy(dst, src, srcLength);
+                dst[srcLength] = '\0';
+                /*Codes_SRS_CRT_ABSTRACTIONS_99_018: [strncpy_s shall return Zero upon success]*/
+                result = 0;
+            }
+        }
+        /*Codes_SRS_CRT_ABSTRACTIONS_99_026: [If MaxCount is _TRUNCATE (defined as -1), then as much of src as will fit into dst shall be copied while still leaving room for the terminating null to be appended.]*/
+        else
+        {
+            if (srcLength + 1 > dstSizeInBytes )
+            {
+                srcLength = dstSizeInBytes - 1;
+                truncationFlag = 1;
+            }
+            (void)memcpy(dst, src, srcLength);
+            dst[srcLength] = '\0';
+            result = 0;
+        }
+    }
+
+    /*Codes_SRS_CRT_ABSTRACTIONS_99_019: [If truncation occurred as a result of the copy, the error code returned shall be STRUNCATE.]*/
+    if (truncationFlag == 1)
+    {
+        result = STRUNCATE;
+    }
+
+    return result;
+}
+
+/* Codes_SRS_CRT_ABSTRACTIONS_99_016: [strcpy_s shall copy the contents in the address of src, including the terminating null character, to the location that's specified by dst.]*/
+int strcpy_s(char* dst, size_t dstSizeInBytes, const char* src)
+{
+    int result;
+
+    /* Codes_SRS_CRT_ABSTRACTIONS_99_012: [If dst is NULL, the error code returned shall be EINVAL & dst shall not be modified.]*/
+    if (dst == NULL)
+    {
+        result = EINVAL;
+    }
+    /* Codes_SRS_CRT_ABSTRACTIONS_99_013: [If src is NULL, the error code returned shall be EINVAL and dst[0] shall be set to 0.]*/
+    else if (src == NULL)
+    {
+        dst[0] = '\0';
+        result = EINVAL;
+    }
+    /* Codes_SRS_CRT_ABSTRACTIONS_99_014: [If the dstSizeInBytes is 0 or smaller than the required size for the src string, the error code returned shall be ERANGE & dst[0] set to 0.]*/
+    else if (dstSizeInBytes == 0)
+    {
+        dst[0] = '\0';
+        result = ERANGE;
+    }
+    else
+    {
+        size_t neededBuffer = strlen(src);
+        /* Codes_SRS_CRT_ABSTRACTIONS_99_014: [If the dstSizeInBytes is 0 or smaller than the required size for the src string, the error code returned shall be ERANGE & dst[0] set to 0.]*/
+        if (neededBuffer + 1 > dstSizeInBytes)
+        {
+            dst[0] = '\0';
+            result = ERANGE;
+        }
+        else
+        {
+            (void)memcpy(dst, src, neededBuffer + 1);
+            /*Codes_SRS_CRT_ABSTRACTIONS_99_011: [strcpy_s shall return Zero upon success]*/
+            result = 0;
+        }
+    }
+
+    return result;
+}
+
+/*Codes_SRS_CRT_ABSTRACTIONS_99_029: [The sprintf_s function shall format and store series of characters and values in dst.  Each argument (if any) is converted and output according to the corresponding Format Specification in the format variable.]*/
+/*Codes_SRS_CRT_ABSTRACTIONS_99_031: [A null character is appended after the last character written.]*/
+int sprintf_s(char* dst, size_t dstSizeInBytes, const char* format, ...)
+{
+    int result;
+    /*Codes_SRS_CRT_ABSTRACTIONS_99_028: [If dst or format is a null pointer, sprintf_s shall return -1 and set errno to EINVAL]*/
+    if ((dst == NULL) ||
+        (format == NULL))
+    {
+        errno = EINVAL;
+        result = -1;
+    }
+    else
+    {
+        /*Codes_SRS_CRT_ABSTRACTIONS_99_033: [sprintf_s shall check the format string for valid formatting characters.  If the check fails, the function returns -1.]*/
+
+#if defined _MSC_VER
+#error crt_abstractions is not provided for Microsoft Compilers
+#else
+        /*not Microsoft compiler... */
+#if defined (__STDC_VERSION__) || (__cplusplus)
+#if ( \
+        ((__STDC_VERSION__  == 199901L) || (__STDC_VERSION__ == 201000L) || (__STDC_VERSION__ == 201112L) || (__STDC_VERSION__ == 201710L)) || \
+        (defined __cplusplus) \
+    )
+        /*C99 compiler*/
+        va_list args;
+        va_start(args, format);
+        /*Codes_SRS_CRT_ABSTRACTIONS_99_027: [sprintf_s shall return the number of characters stored in dst upon success.  This number shall not include the terminating null character.]*/
+        result = vsnprintf(dst, dstSizeInBytes, format, args);
+        va_end(args);
+
+        /*C99: Thus, the null-terminated output has been completely written if and only if the returned value is nonnegative and less than n*/
+        if (result < 0)
+        {
+            result = -1;
+        }
+        else if ((size_t)result >= dstSizeInBytes)
+        {
+            /*Codes_SRS_CRT_ABSTRACTIONS_99_034: [If the dst buffer is too small for the text being printed, then dst is set to an empty string and the function shall return -1.]*/
+            dst[0] = '\0';
+            result = -1;
+        }
+        else
+        {
+            /*do nothing, all is fine*/
+        }
+#else
+#error STDC_VERSION defined, but of unknown value; unable to sprinf_s, or provide own implementation
+#endif
+#else
+#error for STDC_VERSION undefined (assumed C89), provide own implementation of sprintf_s
+#endif
+#endif
+    }
+    return result;
+}
+#endif /* _MSC_VER || MINGW_HAS_SECURE_API */
+
+/*Codes_SRS_CRT_ABSTRACTIONS_21_006: [The strtoull_s must use the letters from a(or A) through z(or Z) to represent the numbers between 10 to 35.]*/
+/* returns the integer value that correspond to the character 'c'. If the character is invalid, it returns -1. */
+#define DIGIT_VAL(c)         (((c>='0') && (c<='9')) ? (c-'0') : ((c>='a') && (c<='z')) ? (c-'a'+10) : ((c>='A') && (c<='Z')) ? (c-'A'+10) : -1)
+#define IN_BASE_RANGE(d, b)  ((d >= 0) && (d < b))
+
+/*Codes_SRS_CRT_ABSTRACTIONS_21_010: [The white-space must be one of the characters ' ', '\f', '\n', '\r', '\t', '\v'.]*/
+#define IS_SPACE(c)           (c == ' ' || c == '\f' || c == '\n' || c == '\r' || c == '\t' || c == '\v')
+
+/*Codes_SRS_CRT_ABSTRACTIONS_21_001: [The strtoull_s must convert the initial portion of the string pointed to by nptr to unsigned long long int representation.]*/
+/*Codes_SRS_CRT_ABSTRACTIONS_21_002: [The strtoull_s must resembling an integer represented in some radix determined by the value of base.]*/
+/*Codes_SRS_CRT_ABSTRACTIONS_21_003: [The strtoull_s must return the integer that represents the value in the initial part of the string. If any.]*/
+unsigned long long strtoull_s(const char* nptr, char** endptr, int base)
+{
+    unsigned long long result = 0ULL;
+    bool validStr = true;
+    char* runner = (char*)nptr;
+    bool isNegative = false;
+    int digitVal;
+
+    /*Codes_SRS_CRT_ABSTRACTIONS_21_005: [The strtoull_s must convert number using base 2 to 36.]*/
+    /*Codes_SRS_CRT_ABSTRACTIONS_21_012: [If the subject sequence is empty or does not have the expected form, the strtoull_s must not perform any conversion; the value of nptr is stored in the object pointed to by endptr, provided that endptr is not a NULL pointer.]*/
+    /*Codes_SRS_CRT_ABSTRACTIONS_21_013: [If no conversion could be performed, the strtoull_s returns the value 0L.]*/
+    /*Codes_SRS_CRT_ABSTRACTIONS_21_035: [If the nptr is NULL, the strtoull_s must **not** perform any conversion and must returns 0L; endptr must receive NULL, provided that endptr is not a NULL pointer.]*/
+        if (((base >= 2) || (base == 0)) && (base <= 36) && (runner != NULL))
+    {
+        /*Codes_SRS_CRT_ABSTRACTIONS_21_011: [The valid sequence starts after the first non-white-space character, followed by an optional positive or negative sign, a number or a letter(depending of the base).]*/
+        /*Codes_SRS_CRT_ABSTRACTIONS_21_010: [The white-space must be one of the characters ' ', '\f', '\n', '\r', '\t', '\v'.]*/
+        while (IS_SPACE(*runner))
+        {
+            runner++;
+        }
+        if ((*runner) == '+')
+        {
+            runner++;
+        }
+        else if ((*runner) == '-')
+        {
+            /*Codes_SRS_CRT_ABSTRACTIONS_21_038: [If the subject sequence starts with a negative sign, the strtoull_s will convert it to the posive representation of the negative value.]*/
+            isNegative = true;
+            runner++;
+        }
+
+        if ((*runner) == '0')
+        {
+            if ((*(runner+1) == 'x') || (*(runner+1) == 'X'))
+            {
+                /*Codes_SRS_CRT_ABSTRACTIONS_21_008: [If the base is 0 and '0x' or '0X' precedes the number, strtoull_s must convert to a hexadecimal (base 16).]*/
+                /* hexadecimal... */
+                if ((base == 0) || (base == 16))
+                {
+                    base = 16;
+                    runner += 2;
+                }
+            }
+            else if((base == 0) || (base == 8))
+            {
+                /*Codes_SRS_CRT_ABSTRACTIONS_21_009: [If the base is 0 and '0' precedes the number, strtoull_s must convert to an octal (base 8).]*/
+                /* octal... */
+                base = 8;
+                runner++;
+            }
+        }
+
+        if(base == 0)
+        {
+            /*Codes_SRS_CRT_ABSTRACTIONS_21_007: [If the base is 0 and no special chars precedes the number, strtoull_s must convert to a decimal (base 10).]*/
+            /* decimal... */
+            base = 10;
+        }
+
+        digitVal = DIGIT_VAL(*runner);
+        if (validStr && IN_BASE_RANGE(digitVal, base))
+        {
+            errno = 0;
+            do
+            {
+                if (((ULLONG_MAX - digitVal) / base) < result)
+                {
+                    /*Codes_SRS_CRT_ABSTRACTIONS_21_014: [If the correct value is outside the range, the strtoull_s returns the value ULLONG_MAX, and errno will receive the value ERANGE.]*/
+                    /* overflow... */
+                    result = ULLONG_MAX;
+                    errno = ERANGE;
+                }
+                else
+                {
+                    result = result * base + digitVal;
+                }
+                runner++;
+                digitVal = DIGIT_VAL(*runner);
+            } while (IN_BASE_RANGE(digitVal, base));
+        }
+        else
+        {
+            runner = (char*)nptr;
+        }
+    }
+
+    /*Codes_SRS_CRT_ABSTRACTIONS_21_004: [The strtoull_s must return in endptr a final string of one or more unrecognized characters, including the terminating null character of the input string.]*/
+    if (endptr != NULL)
+    {
+        (*endptr) = (char*)runner;
+    }
+
+    /*Codes_SRS_CRT_ABSTRACTIONS_21_038: [If the subject sequence starts with a negative sign, the strtoull_s will convert it to the posive representation of the negative value.]*/
+    if (isNegative)
+    {
+        result = ULLONG_MAX - result + 1;
+    }
+
+    return result;
+}
+
+/*Codes_SRS_CRT_ABSTRACTIONS_21_023: [If the string is 'INF' of 'INFINITY' (ignoring case), the strtof_s must return the INFINITY value for float.]*/
+/*Codes_SRS_CRT_ABSTRACTIONS_21_024: [If the string is 'NAN' or 'NAN(...)' (ignoring case), the strtof_s must return 0.0f and points endptr to the first character after the 'NAN' sequence.]*/
+/*Codes_SRS_CRT_ABSTRACTIONS_21_033: [If the string is 'INF' of 'INFINITY' (ignoring case), the strtold_s must return the INFINITY value for long double.]*/
+/*Codes_SRS_CRT_ABSTRACTIONS_21_034: [If the string is 'NAN' or 'NAN(...)' (ignoring case), the strtold_s must return 0.0 and points endptr to the first character after the 'NAN' sequence.]*/
+static int substricmp(const char* nptr, const char* subsrt)
+{
+    int result = 0;
+    while (((*subsrt) != '\0') && (result == 0))
+    {
+        result = TOUPPER(*nptr) - TOUPPER(*subsrt);
+        nptr++;
+        subsrt++;
+    }
+    return result;
+}
+
+/*Codes_SRS_CRT_ABSTRACTIONS_21_023: [If the string is 'INF' of 'INFINITY' (ignoring case), the strtof_s must return the INFINITY value for float.]*/
+/*Codes_SRS_CRT_ABSTRACTIONS_21_033: [If the string is 'INF' of 'INFINITY' (ignoring case), the strtold_s must return the INFINITY value for long double.]*/
+static bool isInfinity(const char** endptr)
+{
+    bool result = false;
+    if (substricmp((*endptr), "INF") == 0)
+    {
+        (*endptr) += 3;
+        result = true;
+        if (substricmp((*endptr), "INITY") == 0)
+        {
+            (*endptr) += 5;
+        }
+    }
+    return result;
+}
+
+/*Codes_SRS_CRT_ABSTRACTIONS_21_024: [If the string is 'NAN' or 'NAN(...)' (ignoring case), the strtof_s must return 0.0f and points endptr to the first character after the 'NAN' sequence.]*/
+/*Codes_SRS_CRT_ABSTRACTIONS_21_034: [If the string is 'NAN' or 'NAN(...)' (ignoring case), the strtold_s must return 0.0 and points endptr to the first character after the 'NAN' sequence.]*/
+static bool isNaN(const char** endptr)
+{
+    const char* runner = (*endptr);
+    bool result = false;
+    if (substricmp(runner, "NAN") == 0)
+    {
+        runner += 3;
+        result = true;
+        if ((*runner) == '(')
+        {
+            do
+            {
+                runner++;
+            } while (((*runner) != '\0') && ((*runner) != ')'));
+            if ((*runner) == ')')
+                runner++;
+            else
+                result = false;
+        }
+    }
+    if (result)
+        (*endptr) = runner;
+    return result;
+}
+
+#define FLOAT_STRING_TYPE_VALUES    \
+            FST_INFINITY,           \
+            FST_NAN,                \
+            FST_NUMBER,             \
+            FST_OVERFLOW,           \
+            FST_ERROR
+
+MU_DEFINE_ENUM(FLOAT_STRING_TYPE, FLOAT_STRING_TYPE_VALUES);
+
+static FLOAT_STRING_TYPE splitFloatString(const char* nptr, char** endptr, int *signal, double *fraction, int *exponential)
+{
+    FLOAT_STRING_TYPE result = FST_ERROR;
+
+    unsigned long long ullInteger = 0;
+    unsigned long long ullFraction = 0;
+    int integerSize = 0;
+    int fractionSize = 0;
+    char* startptr;
+
+    (*endptr) = (char*)nptr;
+
+    /*Codes_SRS_CRT_ABSTRACTIONS_21_018: [The white-space for strtof_s must be one of the characters ' ', '\f', '\n', '\r', '\t', '\v'.]*/
+    /*Codes_SRS_CRT_ABSTRACTIONS_21_028: [The white-space for strtold_s must be one of the characters ' ', '\f', '\n', '\r', '\t', '\v'.]*/
+    while (IS_SPACE(**endptr))
+    {
+        (*endptr)++;
+    }
+
+    /*Codes_SRS_CRT_ABSTRACTIONS_21_019: [The valid sequence for strtof_s starts after the first non-white - space character, followed by an optional positive or negative sign, a number, 'INF', or 'NAN' (ignoring case).]*/
+    /*Codes_SRS_CRT_ABSTRACTIONS_21_029: [The valid sequence for strtold_s starts after the first non-white - space character, followed by an optional positive or negative sign, a number, 'INF', or 'NAN' (ignoring case).]*/
+    (*signal) = +1;
+    if ((**endptr) == '+')
+    {
+        (*endptr)++;
+    }
+    else if ((**endptr) == '-')
+    {
+        (*signal) = -1;
+        (*endptr)++;
+    }
+
+    /*Codes_SRS_CRT_ABSTRACTIONS_21_023: [If the string is 'INF' of 'INFINITY' (ignoring case), the strtof_s must return the INFINITY value for float.]*/
+    /*Codes_SRS_CRT_ABSTRACTIONS_21_033: [If the string is 'INF' of 'INFINITY' (ignoring case), the strtold_s must return the INFINITY value for long double.]*/
+    if (isInfinity((const char**)endptr))
+    {
+        result = FST_INFINITY;
+    }
+    /*Codes_SRS_CRT_ABSTRACTIONS_21_034: [If the string is 'NAN' or 'NAN(...)' (ignoring case), the strtold_s must return 0.0 and points endptr to the first character after the 'NAN' sequence.]*/
+    /*Codes_SRS_CRT_ABSTRACTIONS_21_024: [If the string is 'NAN' or 'NAN(...)' (ignoring case), the strtof_s must return 0.0f and points endptr to the first character after the 'NAN' sequence.]*/
+    else if (isNaN((const char**)endptr))
+    {
+        result = FST_NAN;
+    }
+    else if (IN_BASE_RANGE(DIGIT_VAL(**endptr), 10))
+    {
+        result = FST_NUMBER;
+        startptr = *endptr;
+        /* integers will go to the fraction and exponential. */
+        ullInteger = strtoull_s(startptr, endptr, 10);
+        integerSize = (int)((*endptr) - startptr);
+        if ((ullInteger == ULLONG_MAX) && (errno != 0))
+        {
+            result = FST_OVERFLOW;
+        }
+
+        /* get the real fraction part, if exist. */
+        if ((**endptr) == '.')
+        {
+            startptr = (*endptr) + 1;
+            ullFraction = strtoull_s(startptr, endptr, 10);
+            fractionSize = (int)((*endptr) - startptr);
+            if ((ullFraction == ULLONG_MAX) && (errno != 0))
+            {
+                result = FST_OVERFLOW;
+            }
+        }
+
+        if (((**endptr) == 'e') || ((**endptr) == 'E'))
+        {
+            startptr = (*endptr) + 1;
+            (*exponential) = (int)strtol(startptr, endptr, 10);
+            if (((*exponential) < (DBL_MAX_10_EXP * (-1))) || ((*exponential) > DBL_MAX_10_EXP))
+            {
+                result = FST_OVERFLOW;
+            }
+        }
+        else
+        {
+            (*exponential) = 0;
+        }
+
+        if (result == FST_NUMBER)
+        {
+            /* Add ullInteger to ullFraction. */
+            ullFraction += (ullInteger * (unsigned long long)(pow(10, (double)fractionSize)));
+            (*fraction) = ((double)ullFraction / (pow(10.0f, ((double)fractionSize + (double)integerSize - 1.00))));
+
+            /* Unify rest of integerSize and fractionSize in the exponential. */
+            (*exponential) += integerSize - 1;
+        }
+    }
+
+    return result;
+}
+
+/*Codes_SRS_CRT_ABSTRACTIONS_21_015: [The strtof_s must convert the initial portion of the string pointed to by nptr to float representation.]*/
+/*Codes_SRS_CRT_ABSTRACTIONS_21_016: [The strtof_s must return the float that represents the value in the initial part of the string. If any.]*/
+float strtof_s(const char* nptr, char** endptr)
+{
+    int signal = 1;
+    double fraction;
+    int exponential;
+    char* runner = (char*)nptr;
+    double val;
+
+    /*Codes_SRS_CRT_ABSTRACTIONS_21_021: [If no conversion could be performed, the strtof_s returns the value 0.0.]*/
+    float result = 0.0;
+
+    /*Codes_SRS_CRT_ABSTRACTIONS_21_036: [**If the nptr is NULL, the strtof_s must not perform any conversion and must returns 0.0f; endptr must receive NULL, provided that endptr is not a NULL pointer.]*/
+    if (nptr != NULL)
+    {
+        switch (splitFloatString(nptr, &runner, &signal, &fraction, &exponential))
+        {
+        case FST_INFINITY:
+            /*Codes_SRS_CRT_ABSTRACTIONS_21_023: [If the string is 'INF' of 'INFINITY' (ignoring case), the strtof_s must return the INFINITY value for float.]*/
+            result = INFINITY * (signal);
+            errno = 0;
+            break;
+        case FST_NAN:
+            /*Codes_SRS_CRT_ABSTRACTIONS_21_024: [If the string is 'NAN' or 'NAN(...)' (ignoring case), the strtof_s must return 0.0f and points endptr to the first character after the 'NAN' sequence.]*/
+            result = NAN;
+            break;
+        case FST_NUMBER:
+            val = fraction * pow(10.0, (double)exponential) * (double)signal;
+            if ((val >= (FLT_MAX * (-1.0f))) && (val <= FLT_MAX))
+            {
+                /*Codes_SRS_CRT_ABSTRACTIONS_21_016: [The strtof_s must return the float that represents the value in the initial part of the string. If any.]*/
+                result = (float)val;
+            }
+            else
+            {
+                /*Codes_SRS_CRT_ABSTRACTIONS_21_022: [If the correct value is outside the range, the strtof_s returns the value plus or minus HUGE_VALF, and errno will receive the value ERANGE.]*/
+                result = HUGE_VALF * (signal);
+                errno = ERANGE;
+            }
+            break;
+        case FST_OVERFLOW:
+            /*Codes_SRS_CRT_ABSTRACTIONS_21_022: [If the correct value is outside the range, the strtof_s returns the value plus or minus HUGE_VALF, and errno will receive the value ERANGE.]*/
+            result = HUGE_VALF * (signal);
+            errno = ERANGE;
+            break;
+        default:
+            /*Codes_SRS_CRT_ABSTRACTIONS_21_020: [If the subject sequence is empty or does not have the expected form, the strtof_s must not perform any conversion and must returns 0.0f; the value of nptr is stored in the object pointed to by endptr, provided that endptr is not a NULL pointer.]*/
+            runner = (char*)nptr;
+            break;
+        }
+    }
+
+    /*Codes_SRS_CRT_ABSTRACTIONS_21_017: [The strtof_s must return in endptr a final string of one or more unrecognized characters, including the terminating null character of the input string.]*/
+    if (endptr != NULL)
+    {
+        (*endptr) = runner;
+    }
+
+    return result;
+}
+
+/*Codes_SRS_CRT_ABSTRACTIONS_21_025: [The strtold_s must convert the initial portion of the string pointed to by nptr to long double representation.]*/
+/*Codes_SRS_CRT_ABSTRACTIONS_21_026: [The strtold_s must return the long double that represents the value in the initial part of the string. If any.]*/
+long double strtold_s(const char* nptr, char** endptr)
+{
+    int signal = 1;
+    double fraction;
+    int exponential;
+    char* runner = (char*)nptr;
+
+    /*Codes_SRS_CRT_ABSTRACTIONS_21_031: [If no conversion could be performed, the strtold_s returns the value 0.0.]*/
+    long double result = 0.0;
+
+    /*Codes_SRS_CRT_ABSTRACTIONS_21_037: [If the nptr is NULL, the strtold_s must not perform any conversion and must returns 0.0; endptr must receive NULL, provided that endptr is not a NULL pointer.]*/
+    if (nptr != NULL)
+    {
+        switch (splitFloatString(nptr, &runner, &signal, &fraction, &exponential))
+        {
+        case FST_INFINITY:
+            /*Codes_SRS_CRT_ABSTRACTIONS_21_033: [If the string is 'INF' of 'INFINITY' (ignoring case), the strtold_s must return the INFINITY value for long double.]*/
+            result = (long double)INFINITY * (long double)(signal);
+            errno = 0;
+            break;
+        case FST_NAN:
+            /*Codes_SRS_CRT_ABSTRACTIONS_21_034: [If the string is 'NAN' or 'NAN(...)' (ignoring case), the strtold_s must return 0.0 and points endptr to the first character after the 'NAN' sequence.]*/
+            result = (long double)NAN;
+            break;
+        case FST_NUMBER:
+            if ((exponential != DBL_MAX_10_EXP || (fraction <= 1.7976931348623158)) &&
+                (exponential != (DBL_MAX_10_EXP * (-1)) || (fraction <= 2.2250738585072014)))
+            {
+                /*Codes_SRS_CRT_ABSTRACTIONS_21_026: [The strtold_s must return the long double that represents the value in the initial part of the string. If any.]*/
+                result = fraction * pow(10.0, (double)exponential) * (double)signal;
+            }
+            else
+            {
+                /*Codes_SRS_CRT_ABSTRACTIONS_21_032: [If the correct value is outside the range, the strtold_s returns the value plus or minus HUGE_VALL, and errno will receive the value ERANGE.]*/
+                result = (long double)HUGE_VALF * (long double)(signal);
+                errno = ERANGE;
+            }
+            break;
+        case FST_OVERFLOW:
+            /*Codes_SRS_CRT_ABSTRACTIONS_21_032: [If the correct value is outside the range, the strtold_s returns the value plus or minus HUGE_VALL, and errno will receive the value ERANGE.]*/
+            result = (long double)HUGE_VALF * (long double)(signal);
+            errno = ERANGE;
+            break;
+        default:
+            /*Codes_SRS_CRT_ABSTRACTIONS_21_030: [If the subject sequence is empty or does not have the expected form, the strtold_s must not perform any conversion and must returns 0.0; the value of nptr is stored in the object pointed to by endptr, provided that endptr is not a NULL pointer.]*/
+            runner = (char*)nptr;
+            break;
+        }
+    }
+
+    /*Codes_SRS_CRT_ABSTRACTIONS_21_027: [The strtold_s must return in endptr a final string of one or more unrecognized characters, including the terminating null character of the input string.]*/
+    if (endptr != NULL)
+    {
+        (*endptr) = runner;
+    }
+
+    return result;
+}
+
+
+/*Codes_SRS_CRT_ABSTRACTIONS_99_038: [mallocAndstrcpy_s shall allocate memory for destination buffer to fit the string in the source parameter.]*/
+int mallocAndStrcpy_s(char** destination, const char* source)
+{
+    int result;
+    int copied_result;
+    /*Codes_SRS_CRT_ABSTRACTIONS_99_036: [destination parameter or source parameter is NULL, the error code returned shall be EINVAL and destination shall not be modified.]*/
+    if ((destination == NULL) || (source == NULL))
+    {
+        /*If strDestination or strSource is a NULL pointer[...]these functions return EINVAL */
+        result = EINVAL;
+    }
+    else
+    {
+        size_t l = strlen(source);
+        char* temp = (char*)malloc(l + 1);
+
+        /*Codes_SRS_CRT_ABSTRACTIONS_99_037: [Upon failure to allocate memory for the destination, the function will return ENOMEM.]*/
+        if (temp == NULL)
+        {
+            result = ENOMEM;
+        }
+        else
+        {
+            *destination = temp;
+            /*Codes_SRS_CRT_ABSTRACTIONS_99_039: [mallocAndstrcpy_s shall copy the contents in the address source, including the terminating null character into location specified by the destination pointer after the memory allocation.]*/
+            copied_result = strcpy_s(*destination, l + 1, source);
+            if (copied_result < 0) /*strcpy_s error*/
+            {
+                free(*destination);
+                *destination = NULL;
+                result = copied_result;
+            }
+            else
+            {
+                /*Codes_SRS_CRT_ABSTRACTIONS_99_035: [mallocAndstrcpy_s shall return Zero upon success]*/
+                result = 0;
+            }
+        }
+    }
+    return result;
+}
+
+/*takes "value" and transforms it into a decimal string*/
+/*10 => "10"*/
+/*return 0 when everything went ok*/
+/*Codes_SRS_CRT_ABSTRACTIONS_02_001: [unsignedIntToString shall convert the parameter value to its decimal representation as a string in the buffer indicated by parameter destination having the size indicated by parameter destinationSize.] */
+int unsignedIntToString(char* destination, size_t destinationSize, unsigned int value)
+{
+    int result;
+    size_t pos;
+    /*the below loop gets the number in reverse order*/
+    /*Codes_SRS_CRT_ABSTRACTIONS_02_003: [If destination is NULL then unsignedIntToString shall fail.] */
+    /*Codes_SRS_CRT_ABSTRACTIONS_02_002: [If the conversion fails for any reason (for example, insufficient buffer space), a non-zero return value shall be supplied and unsignedIntToString shall fail.] */
+    if (
+        (destination == NULL) ||
+        (destinationSize < 2) /*because the smallest number is '0\0' which requires 2 characters*/
+        )
+    {
+        result = MU_FAILURE;
+    }
+    else
+    {
+        pos = 0;
+        do
+        {
+            destination[pos++] = '0' + (value % 10);
+            value /= 10;
+        } while ((value > 0) && (pos < (destinationSize-1)));
+
+        if (value == 0)
+        {
+            size_t w;
+            destination[pos] = '\0';
+            /*all converted and they fit*/
+            for (w = 0; w <= (pos-1) >> 1; w++)
+            {
+                char temp;
+                temp = destination[w];
+                destination[w] = destination[pos - 1 - w];
+                destination[pos -1 - w] = temp;
+            }
+            /*Codes_SRS_CRT_ABSTRACTIONS_02_004: [If the conversion has been successfull then unsignedIntToString shall return 0.] */
+            result = 0;
+        }
+        else
+        {
+            /*Codes_SRS_CRT_ABSTRACTIONS_02_002: [If the conversion fails for any reason (for example, insufficient buffer space), a non-zero return value shall be supplied and unsignedIntToString shall fail.] */
+            result = MU_FAILURE;
+        }
+    }
+    return result;
+}
+
+/*takes "value" and transforms it into a decimal string*/
+/*10 => "10"*/
+/*return 0 when everything went ok*/
+/*Codes_SRS_CRT_ABSTRACTIONS_02_001: [unsignedIntToString shall convert the parameter value to its decimal representation as a string in the buffer indicated by parameter destination having the size indicated by parameter destinationSize.] */
+int size_tToString(char* destination, size_t destinationSize, size_t value)
+{
+    int result;
+    size_t pos;
+    /*the below loop gets the number in reverse order*/
+    /*Codes_SRS_CRT_ABSTRACTIONS_02_003: [If destination is NULL then unsignedIntToString shall fail.] */
+    /*Codes_SRS_CRT_ABSTRACTIONS_02_002: [If the conversion fails for any reason (for example, insufficient buffer space), a non-zero return value shall be supplied and unsignedIntToString shall fail.] */
+    if (
+        (destination == NULL) ||
+        (destinationSize < 2) /*because the smallest number is '0\0' which requires 2 characters*/
+        )
+    {
+        result = MU_FAILURE;
+    }
+    else
+    {
+        pos = 0;
+        do
+        {
+            destination[pos++] = '0' + (value % 10);
+            value /= 10;
+        } while ((value > 0) && (pos < (destinationSize - 1)));
+
+        if (value == 0)
+        {
+            size_t w;
+            destination[pos] = '\0';
+            /*all converted and they fit*/
+            for (w = 0; w <= (pos - 1) >> 1; w++)
+            {
+                char temp;
+                temp = destination[w];
+                destination[w] = destination[pos - 1 - w];
+                destination[pos - 1 - w] = temp;
+            }
+            /*Codes_SRS_CRT_ABSTRACTIONS_02_004: [If the conversion has been successfull then unsignedIntToString shall return 0.] */
+            result = 0;
+        }
+        else
+        {
+            /*Codes_SRS_CRT_ABSTRACTIONS_02_002: [If the conversion fails for any reason (for example, insufficient buffer space), a non-zero return value shall be supplied and unsignedIntToString shall fail.] */
+            result = MU_FAILURE;
+        }
+    }
+    return result;
+}
Index: azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/src/dns_resolver_sync.c
===================================================================
--- azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/src/dns_resolver_sync.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/src/dns_resolver_sync.c	(revision 457)
@@ -0,0 +1,255 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdlib.h>
+
+// This file is OS-specific, and is identified by setting include directories
+// in the project
+#include "socket_async_os.h"
+
+#include "azure_c_shared_utility/dns_resolver.h"
+#include "azure_c_shared_utility/gballoc.h"
+#include "azure_c_shared_utility/crt_abstractions.h"
+#include "azure_c_shared_utility/xlogging.h"
+
+
+// EXTRACT_IPV4 pulls the uint32_t IPv4 address out of an addrinfo struct
+// This will not be needed for the asynchronous design
+// The default definition handles lwIP. Please add comments for other systems tested.
+#define EXTRACT_IPV4(ptr) ((struct sockaddr_in *) ptr->ai_addr)->sin_addr.s_addr
+
+typedef struct
+{
+    char* hostname;
+    int port;
+    uint32_t ip_v4;
+    bool is_complete;
+    bool is_failed;
+    struct addrinfo* addrInfo;
+} DNSRESOLVER_INSTANCE;
+
+DNSRESOLVER_HANDLE dns_resolver_create(const char* hostname, int port, const DNSRESOLVER_OPTIONS* options)
+{
+    /* Codes_SRS_dns_resolver_30_012: [ The optional options parameter shall be ignored. ]*/
+    DNSRESOLVER_INSTANCE* result;
+    (void)options;
+    if (hostname == NULL)
+    {
+        /* Codes_SRS_dns_resolver_30_011: [ If the hostname parameter is NULL, dns_resolver_create shall log an error and return NULL. ]*/
+        LogError("NULL hostname");
+        result = NULL;
+    }
+    else
+    {
+        result = malloc(sizeof(DNSRESOLVER_INSTANCE));
+        if (result == NULL)
+        {
+            /* Codes_SRS_dns_resolver_30_014: [ On any failure, dns_resolver_create shall log an error and return NULL. ]*/
+            LogError("malloc instance failed");
+            result = NULL;
+        }
+        else
+        {
+            int ms_result;
+            result->is_complete = false;
+            result->is_failed = false;
+            result->ip_v4 = 0;
+            result->port = port;
+            /* Codes_SRS_dns_resolver_30_010: [ dns_resolver_create shall make a copy of the hostname parameter to allow immediate deletion by the caller. ]*/
+            ms_result = mallocAndStrcpy_s(&result->hostname, hostname);
+            if (ms_result != 0)
+            {
+                /* Codes_SRS_dns_resolver_30_014: [ On any failure, dns_resolver_create shall log an error and return NULL. ]*/
+                free(result);
+                result = NULL;
+            }
+        }
+    }
+    return result;
+}
+
+/* Codes_SRS_dns_resolver_30_021: [ dns_resolver_is_create_complete shall perform the asynchronous work of DNS lookup and log any errors. ]*/
+bool dns_resolver_is_lookup_complete(DNSRESOLVER_HANDLE dns_in)
+{
+    DNSRESOLVER_INSTANCE* dns = (DNSRESOLVER_INSTANCE*)dns_in;
+
+    bool result;
+    if (dns == NULL)
+    {
+        /* Codes_SRS_dns_resolver_30_020: [ If the dns parameter is NULL, dns_resolver_is_create_complete shall log an error and return false. ]*/
+        LogError("NULL dns");
+        result = false;
+    }
+    else
+    {
+        if (dns->is_complete)
+        {
+            /* Codes_SRS_dns_resolver_30_024: [ If dns_resolver_is_create_complete has previously returned true, dns_resolver_is_create_complete shall do nothing and return true. ]*/
+            result = true;
+        }
+        else
+        {
+            char portString[16];
+            struct addrinfo *addrInfo = NULL;
+            struct addrinfo *ptr = NULL;
+            struct addrinfo hints;
+            int getAddrResult;
+
+            //--------------------------------
+            // Setup the hints address info structure
+            // which is passed to the getaddrinfo() function
+            memset(&hints, 0, sizeof(hints));
+            hints.ai_family = AF_INET;
+            hints.ai_socktype = SOCK_STREAM;
+            hints.ai_protocol = 0;
+
+            //--------------------------------
+            // Call getaddrinfo(). If the call succeeds,
+            // the result variable will hold a linked list
+            // of addrinfo structures containing response
+            // information
+            if (sprintf(portString, "%u", dns->port) < 0)
+            {
+                LogError("Failure: sprintf failed to encode the port.");
+                result = MU_FAILURE;
+            }
+
+            getAddrResult = getaddrinfo(dns->hostname, portString, &hints, &addrInfo);
+            if (getAddrResult == 0)
+            {
+                dns->addrInfo = addrInfo;
+                
+                // If we find the AF_INET address, use it as the return value
+                for (ptr = addrInfo; ptr != NULL; ptr = ptr->ai_next)
+                {
+                    switch (ptr->ai_family)
+                    {
+                    case AF_INET:
+                        /* Codes_SRS_dns_resolver_30_032: [ If dns_resolver_is_create_complete has returned true and the lookup process has succeeded, dns_resolver_get_ipv4 shall return the discovered IPv4 address. ]*/
+                        dns->ip_v4 = EXTRACT_IPV4(ptr);
+                        break;
+                    }
+                }
+                /* Codes_SRS_dns_resolver_30_033: [ If dns_resolver_is_create_complete has returned true and the lookup process has failed, dns_resolver_get_ipv4 shall return 0. ]*/
+                dns->is_failed = (dns->ip_v4 == 0);
+            }
+            else
+            {
+                /* Codes_SRS_dns_resolver_30_033: [ If dns_resolver_is_create_complete has returned true and the lookup process has failed, dns_resolver_get_ipv4 shall return 0. ]*/
+                LogInfo("Failed DNS lookup for %s: %d", dns->hostname, getAddrResult);
+                dns->is_failed = true;
+            }
+
+            /* Codes_SRS_dns_resolver_30_021: [ dns_resolver_is_create_complete shall perform the asynchronous work of DNS lookup and log any errors. ]*/
+            // Only make one attempt at lookup for this
+            // synchronous implementation
+            dns->is_complete = true;
+
+            // This synchronous implementation is incapable of being incomplete, so SRS_dns_resolver_30_023 does not ever happen
+            /* Codes_SRS_dns_resolver_30_023: [ If the DNS lookup process is not yet complete, dns_resolver_is_create_complete shall return false. ]*/
+            /* Codes_SRS_dns_resolver_30_022: [ If the DNS lookup process has completed, dns_resolver_is_create_complete shall return true. ]*/
+            result = true;
+        }
+    }
+
+    return result;
+}
+
+void dns_resolver_destroy(DNSRESOLVER_HANDLE dns_in)
+{
+    DNSRESOLVER_INSTANCE* dns = (DNSRESOLVER_INSTANCE*)dns_in;
+    if (dns == NULL)
+    {
+        /* Codes_SRS_dns_resolver_30_050: [ If the dns parameter is NULL, dns_resolver_destroy shall log an error and do nothing. ]*/
+        LogError("NULL dns");
+    }
+    else
+    {
+        /* Codes_SRS_dns_resolver_30_051: [ dns_resolver_destroy shall delete all acquired resources and delete the DNSRESOLVER_HANDLE. ]*/
+        if(dns->is_complete && !dns->is_failed && dns->addrInfo != NULL)
+        {
+            freeaddrinfo(dns->addrInfo);
+        }
+
+        if(dns->hostname != NULL)
+        {
+            free(dns->hostname);
+        }
+        
+        free(dns);
+        dns = NULL;
+    }
+}
+
+uint32_t dns_resolver_get_ipv4(DNSRESOLVER_HANDLE dns_in)
+{
+    DNSRESOLVER_INSTANCE* dns = (DNSRESOLVER_INSTANCE*)dns_in;
+    uint32_t result;
+    if (dns == NULL)
+    {
+        /* Codes_SRS_dns_resolver_30_030: [ If the dns parameter is NULL, dns_resolver_get_ipv4 shall log an error and return 0. ]*/
+        LogError("NULL dns");
+        result = 0;
+    }
+    else
+    {
+        if (dns->is_complete)
+        {
+            if (dns->is_failed)
+            {
+                /* Codes_SRS_dns_resolver_30_033: [ If dns_resolver_is_create_complete has returned true and the lookup process has failed, dns_resolver_get_ipv4 shall return 0. ]*/
+                result = 0;
+            }
+            else
+            {
+                /* Codes_SRS_dns_resolver_30_032: [ If dns_resolver_is_create_complete has returned true and the lookup process has succeeded, dns_resolver_get_ipv4 shall return the discovered IPv4 address. ]*/
+                result = dns->ip_v4;
+            }
+        }
+        else
+        {
+            /* Codes_SRS_dns_resolver_30_031: [ If dns_resolver_is_create_complete has not yet returned true, dns_resolver_get_ipv4 shall log an error and return 0. ]*/
+            LogError("dns_resolver_get_ipv4 when not complete");
+            result = 0;
+        }
+    }
+    return result;
+}
+
+struct addrinfo* dns_resolver_get_addrInfo(DNSRESOLVER_HANDLE dns_in)
+{
+    DNSRESOLVER_INSTANCE* dns = (DNSRESOLVER_INSTANCE*)dns_in;
+    struct addrinfo* result;
+    if (dns == NULL)
+    {
+        /* Codes_SRS_dns_resolver_30_030: [ If the dns parameter is NULL, dns_resolver_get_ipv4 shall log an error and return 0. ]*/
+        LogError("NULL dns");
+        result = NULL;
+    }
+    else
+    {
+        if (dns->is_complete)
+        {
+            if (dns->is_failed)
+            {
+                /* Codes_SRS_dns_resolver_30_033: [ If dns_resolver_is_create_complete has returned true and the lookup process has failed, dns_resolver_get_ipv4 shall return 0. ]*/
+                result = NULL;
+            }
+            else
+            {
+                /* Codes_SRS_dns_resolver_30_032: [ If dns_resolver_is_create_complete has returned true and the lookup process has succeeded, dns_resolver_get_ipv4 shall return the discovered IPv4 address. ]*/
+                result = dns->addrInfo;
+            }
+        }
+        else
+        {
+            /* Codes_SRS_dns_resolver_30_031: [ If dns_resolver_is_create_complete has not yet returned true, dns_resolver_get_ipv4 shall log an error and return 0. ]*/
+            LogError("dns_resolver_get_ipv4 when not complete");
+            result = NULL;
+        }
+    }
+    return result;
+}
Index: azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/src/doublylinkedlist.c
===================================================================
--- azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/src/doublylinkedlist.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/src/doublylinkedlist.c	(revision 457)
@@ -0,0 +1,107 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+#include "azure_c_shared_utility/doublylinkedlist.h"
+
+void
+DList_InitializeListHead(
+    PDLIST_ENTRY ListHead
+)
+{
+    /* Codes_SRS_DLIST_06_005: [DList_InitializeListHead will initialize the Flink & Blink to the address of the DLIST_ENTRY.] */
+    ListHead->Flink = ListHead->Blink = ListHead;
+    return;
+}
+
+int
+DList_IsListEmpty(
+    const PDLIST_ENTRY ListHead
+)
+{
+    /* Codes_SRS_DLIST_06_003: [DList_IsListEmpty shall return a non-zero value if there are no DLIST_ENTRY's on this list other than the list head.] */
+    /* Codes_SRS_DLIST_06_004: [DList_IsListEmpty shall return 0 if there is one or more items in the list.] */
+    return (ListHead->Flink == ListHead);
+}
+
+int
+DList_RemoveEntryList(
+    PDLIST_ENTRY Entry
+)
+{
+    /* Codes_SRS_DLIST_06_008: [DList_RemoveEntryList shall remove a listEntry from whatever list it is properly part of.] */
+    /* Codes_SRS_DLIST_06_009: [The remaining list is properly formed.] */
+    /* Codes_SRS_DLIST_06_010: [DList_RemoveEntryList shall return non-zero if the remaining list is empty.] */
+    /* Codes_SRS_DLIST_06_011: [DList_RemoveEntryList shall return zero if the remaining list is NOT empty.] */
+    PDLIST_ENTRY Blink;
+    PDLIST_ENTRY Flink;
+
+    Flink = Entry->Flink;
+    Blink = Entry->Blink;
+    Blink->Flink = Flink;
+    Flink->Blink = Blink;
+    return (Flink == Blink);
+}
+
+PDLIST_ENTRY
+DList_RemoveHeadList(
+    PDLIST_ENTRY ListHead
+)
+{
+    /* Codes_SRS_DLIST_06_012: [DList_RemoveHeadList removes the oldest entry from the list defined by the listHead parameter and returns a pointer to that entry.] */
+    /* Codes_SRS_DLIST_06_013: [DList_RemoveHeadList shall return listHead if that's the only item in the list.] */
+
+    PDLIST_ENTRY Flink;
+    PDLIST_ENTRY Entry;
+
+    Entry = ListHead->Flink;
+    Flink = Entry->Flink;
+    ListHead->Flink = Flink;
+    Flink->Blink = ListHead;
+    return Entry;
+}
+
+
+
+void
+DList_InsertTailList(
+    PDLIST_ENTRY ListHead,
+    PDLIST_ENTRY Entry
+)
+{
+    PDLIST_ENTRY Blink;
+
+    /* Codes_SRS_DLIST_06_006: [DListInsertTailList shall place the DLIST_ENTRY at the end of the list defined by the listHead parameter.] */
+    Blink = ListHead->Blink;
+    Entry->Flink = ListHead;
+    Entry->Blink = Blink;
+    Blink->Flink = Entry;
+    ListHead->Blink = Entry;
+    return;
+}
+
+
+void
+DList_AppendTailList(
+    PDLIST_ENTRY ListHead,
+    PDLIST_ENTRY ListToAppend
+)
+{
+    /* Codes_SRS_DLIST_06_007: [DList_AppendTailList shall place the list defined by listToAppend at the end of the list defined by the listHead parameter.] */
+    PDLIST_ENTRY ListEnd = ListHead->Blink;
+
+    ListHead->Blink->Flink = ListToAppend;
+    ListHead->Blink = ListToAppend->Blink;
+    ListToAppend->Blink->Flink = ListHead;
+    ListToAppend->Blink = ListEnd;
+    return;
+}
+
+
+/*Codes_SRS_DLIST_02_002: [DList_InsertHeadList inserts a singular entry in the list having as head listHead after "head".]*/
+void DList_InsertHeadList(PDLIST_ENTRY listHead, PDLIST_ENTRY entry)
+{
+    entry->Blink = listHead;
+    entry->Flink = listHead->Flink;
+    listHead->Flink->Blink = entry;
+    listHead->Flink = entry;
+}
Index: azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/src/gb_rand.c
===================================================================
--- azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/src/gb_rand.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/src/gb_rand.c	(revision 457)
@@ -0,0 +1,16 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+#ifdef __cplusplus
+#include <cstdlib>
+#else
+#include <stdlib.h>
+#endif
+
+#include "azure_c_shared_utility/gb_rand.h"
+
+/*this is rand*/
+int gb_rand(void)
+{
+    return rand();
+}
Index: azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/src/gb_stdio.c
===================================================================
--- azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/src/gb_stdio.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/src/gb_stdio.c	(revision 457)
@@ -0,0 +1,54 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+/*depending if the symbol GB_STDIO_INTERCEPT is defined, this file does the following
+
+    a) if GB_STDIO_INTERCEPT is NOT defined, then the file shall be empty (almost:)
+    b) if GB_STDIO_INTERCEPT is defined, then the file shall call to the 'real' stdio.h functions from their gb_* synonyms*/
+#ifdef _MSC_VER
+/* compiler warning C4206: nonstandard extension used: translation unit is empty */
+/* linker warning 4221: This object file does not define any previously undefined public symbols, so it will not be used by any link operation that consumes this library */
+const int avoid_warnings_B9EB480E_6AE7_43B3_9249_47993776BA7B = 0;
+#endif
+#ifdef GB_STDIO_INTERCEPT
+
+#ifdef __cplusplus
+#include <cstdio>
+#include <cstdarg>
+#else
+#include <stdio.h>
+#include <stdarg.h>
+#endif
+
+#include "azure_c_shared_utility/gb_stdio.h"
+
+/*this is fopen*/
+FILE *gb_fopen(const char * filename, const char * mode)
+{
+    return fopen(filename, mode);
+}
+
+int gb_fclose(FILE *stream)
+{
+    return fclose(stream);
+}
+
+int gb_fseek(FILE *stream, long int offset, int whence)
+{
+    return fseek(stream, offset, whence);
+}
+
+long int gb_ftell(FILE *stream)
+{
+    return ftell(stream);
+}
+
+int fprintf(FILE * stream, const char * format, ...)
+{
+    va_list args;
+    va_start(args, format);
+    vfprintf(stream, format, args);
+    va_end(args);
+}
+
+#endif
Index: azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/src/gb_time.c
===================================================================
--- azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/src/gb_time.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/src/gb_time.c	(revision 457)
@@ -0,0 +1,40 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+/*depending if the symbol GB_TIME_INTERCEPT is defined, this file does the following
+
+    a) if GB_TIME_INTERCEPT is NOT defined, then the file shall be empty (almost:)
+    b) if GB_TIME_INTERCEPT is defined, then the file shall call to the 'real' time.h functions from their gb_* synonyms*/
+#ifdef _MSC_VER
+/* compiler warning C4206: nonstandard extension used: translation unit is empty */
+/* linker warning 4221: This object file does not define any previously undefined public symbols, so it will not be used by any link operation that consumes this library */
+const int avoid_warnings_0CA668EF_F2C4_49A8_A30D_7257C67173A4 = 0;
+#endif
+#ifdef GB_TIME_INTERCEPT
+
+#ifdef __cplusplus
+#include <ctime>
+#else
+#include <time.h>
+#endif
+
+#include "azure_c_shared_utility/gb_time.h"
+
+/*this is time*/
+time_t gb_time(time_t *timer);
+{
+    return time(timer);
+}
+
+/*this is localtime*/
+struct tm *gb_localtime(const time_t *timer)
+{
+    return gb_localtime(timer);
+}
+
+size_t gb_strftime(char * s, size_t maxsize, const char * format, const struct tm * timeptr)
+{
+    return strftime(s, maxsize, format, timeptr);
+}
+
+#endif
Index: azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/src/gballoc.c
===================================================================
--- azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/src/gballoc.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/src/gballoc.c	(revision 457)
@@ -0,0 +1,444 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+#include <stdlib.h>
+#include <stdint.h>
+#include "azure_c_shared_utility/lock.h"
+#include "azure_c_shared_utility/optimize_size.h"
+#include "azure_c_shared_utility/xlogging.h"
+
+#ifndef GB_USE_CUSTOM_HEAP
+
+#ifndef SIZE_MAX
+#define SIZE_MAX ((size_t)~(size_t)0)
+#endif
+
+typedef struct ALLOCATION_TAG
+{
+    size_t size;
+    void* ptr;
+    void* next;
+} ALLOCATION;
+
+typedef enum GBALLOC_STATE_TAG
+{
+    GBALLOC_STATE_INIT,
+    GBALLOC_STATE_NOT_INIT
+} GBALLOC_STATE;
+
+static ALLOCATION* head = NULL;
+static size_t totalSize = 0;
+static size_t maxSize = 0;
+static size_t g_allocations = 0;
+static GBALLOC_STATE gballocState = GBALLOC_STATE_NOT_INIT;
+
+static LOCK_HANDLE gballocThreadSafeLock = NULL;
+
+int gballoc_init(void)
+{
+    int result;
+
+    if (gballocState != GBALLOC_STATE_NOT_INIT)
+    {
+        /* Codes_SRS_GBALLOC_01_025: [Init after Init shall fail and return a non-zero value.] */
+        result = MU_FAILURE;
+    }
+    /* Codes_SRS_GBALLOC_01_026: [gballoc_Init shall create a lock handle that will be used to make the other gballoc APIs thread-safe.] */
+    else if ((gballocThreadSafeLock = Lock_Init()) == NULL)
+    {
+        /* Codes_SRS_GBALLOC_01_027: [If the Lock creation fails, gballoc_init shall return a non-zero value.]*/
+        result = MU_FAILURE;
+    }
+    else
+    {
+        gballocState = GBALLOC_STATE_INIT;
+
+        /* Codes_ SRS_GBALLOC_01_002: [Upon initialization the total memory used and maximum total memory used tracked by the module shall be set to 0.] */
+        totalSize = 0;
+        maxSize = 0;
+        g_allocations = 0;
+
+        /* Codes_SRS_GBALLOC_01_024: [gballoc_init shall initialize the gballoc module and return 0 upon success.] */
+        result = 0;
+    }
+
+    return result;
+}
+
+void gballoc_deinit(void)
+{
+    if (gballocState == GBALLOC_STATE_INIT)
+    {
+        /* Codes_SRS_GBALLOC_01_028: [gballoc_deinit shall free all resources allocated by gballoc_init.] */
+        (void)Lock_Deinit(gballocThreadSafeLock);
+    }
+
+    gballocState = GBALLOC_STATE_NOT_INIT;
+}
+
+void* gballoc_malloc(size_t size)
+{
+    void* result;
+
+    if (gballocState != GBALLOC_STATE_INIT)
+    {
+        /* Codes_SRS_GBALLOC_01_039: [If gballoc was not initialized gballoc_malloc shall simply call malloc without any memory tracking being performed.] */
+        result = malloc(size);
+    }
+    /* Codes_SRS_GBALLOC_01_030: [gballoc_malloc shall ensure thread safety by using the lock created by gballoc_Init.] */
+    else if (LOCK_OK != Lock(gballocThreadSafeLock))
+    {
+        /* Codes_SRS_GBALLOC_01_048: [If acquiring the lock fails, gballoc_malloc shall return NULL.] */
+        LogError("Failed to get the Lock.");
+        result = NULL;
+    }
+    else
+    {
+        ALLOCATION* allocation = (ALLOCATION*)calloc(1, sizeof(ALLOCATION));
+        if (allocation == NULL)
+        {
+            result = NULL;
+        }
+        else
+        {
+            /* Codes_SRS_GBALLOC_01_003: [gb_malloc shall call the C99 malloc function and return its result.] */
+            result = malloc(size);
+            if (result == NULL)
+            {
+                /* Codes_SRS_GBALLOC_01_012: [When the underlying malloc call fails, gballoc_malloc shall return NULL and size should not be counted towards total memory used.] */
+                free(allocation);
+            }
+            else
+            {
+                /* Codes_SRS_GBALLOC_01_004: [If the underlying malloc call is successful, gb_malloc shall increment the total memory used with the amount indicated by size.] */
+                allocation->ptr = result;
+                allocation->size = size;
+                allocation->next = head;
+                head = allocation;
+
+                g_allocations++;
+                totalSize += size;
+                /* Codes_SRS_GBALLOC_01_011: [The maximum total memory used shall be the maximum of the total memory used at any point.] */
+                if (maxSize < totalSize)
+                {
+                    maxSize = totalSize;
+                }
+            }
+        }
+
+        (void)Unlock(gballocThreadSafeLock);
+    }
+
+    return result;
+}
+
+void* gballoc_calloc(size_t nmemb, size_t size)
+{
+    void* result;
+
+    if (gballocState != GBALLOC_STATE_INIT)
+    {
+        /* Codes_SRS_GBALLOC_01_040: [If gballoc was not initialized gballoc_calloc shall simply call calloc without any memory tracking being performed.] */
+        result = calloc(nmemb, size);
+    }
+    /* Codes_SRS_GBALLOC_01_031: [gballoc_calloc shall ensure thread safety by using the lock created by gballoc_Init]  */
+    else if (LOCK_OK != Lock(gballocThreadSafeLock))
+    {
+        /* Codes_SRS_GBALLOC_01_046: [If acquiring the lock fails, gballoc_calloc shall return NULL.] */
+        LogError("Failed to get the Lock.");
+        result = NULL;
+    }
+    else
+    {
+        ALLOCATION* allocation = (ALLOCATION*)calloc(1, sizeof(ALLOCATION));
+        if (allocation == NULL)
+        {
+            result = NULL;
+        }
+        else
+        {
+            /* Codes_SRS_GBALLOC_01_020: [gballoc_calloc shall call the C99 calloc function and return its result.] */
+            result = calloc(nmemb, size);
+            if (result == NULL)
+            {
+                /* Codes_SRS_GBALLOC_01_022: [When the underlying calloc call fails, gballoc_calloc shall return NULL and size should not be counted towards total memory used.] */
+                free(allocation);
+            }
+            else
+            {
+                /* Codes_SRS_GBALLOC_01_021: [If the underlying calloc call is successful, gballoc_calloc shall increment the total memory used with nmemb*size.] */
+                allocation->ptr = result;
+                allocation->size = nmemb * size;
+                allocation->next = head;
+                head = allocation;
+                g_allocations++;
+
+                totalSize += allocation->size;
+                /* Codes_SRS_GBALLOC_01_011: [The maximum total memory used shall be the maximum of the total memory used at any point.] */
+                if (maxSize < totalSize)
+                {
+                    maxSize = totalSize;
+                }
+            }
+        }
+
+        (void)Unlock(gballocThreadSafeLock);
+    }
+
+    return result;
+}
+
+void* gballoc_realloc(void* ptr, size_t size)
+{
+    ALLOCATION* curr;
+    void* result;
+    ALLOCATION* allocation = NULL;
+
+    if (gballocState != GBALLOC_STATE_INIT)
+    {
+        /* Codes_SRS_GBALLOC_01_041: [If gballoc was not initialized gballoc_realloc shall shall simply call realloc without any memory tracking being performed.] */
+        result = realloc(ptr, size);
+    }
+    /* Codes_SRS_GBALLOC_01_032: [gballoc_realloc shall ensure thread safety by using the lock created by gballoc_Init.] */
+    else if (LOCK_OK != Lock(gballocThreadSafeLock))
+    {
+        /* Codes_SRS_GBALLOC_01_047: [If acquiring the lock fails, gballoc_realloc shall return NULL.] */
+        LogError("Failed to get the Lock.");
+        result = NULL;
+    }
+    else
+    {
+        if (ptr == NULL)
+        {
+            /* Codes_SRS_GBALLOC_01_017: [When ptr is NULL, gballoc_realloc shall call the underlying realloc with ptr being NULL and the realloc result shall be tracked by gballoc.] */
+            allocation = (ALLOCATION*)calloc(1, sizeof(ALLOCATION));
+        }
+        else
+        {
+            curr = head;
+            while (curr != NULL)
+            {
+                if (curr->ptr == ptr)
+                {
+                    allocation = curr;
+                    break;
+                }
+                else
+                {
+                    curr = (ALLOCATION*)curr->next;
+                }
+            }
+        }
+
+        if (allocation == NULL)
+        {
+            /* Codes_SRS_GBALLOC_01_015: [When allocating memory used for tracking by gballoc_realloc fails, gballoc_realloc shall return NULL and no change should be made to the counted total memory usage.] */
+            /* Codes_SRS_GBALLOC_01_016: [When the ptr pointer cannot be found in the pointers tracked by gballoc, gballoc_realloc shall return NULL and the underlying realloc shall not be called.] */
+            result = NULL;
+        }
+        else
+        {
+            result = realloc(ptr, size);
+            if (result == NULL)
+            {
+                /* Codes_SRS_GBALLOC_01_014: [When the underlying realloc call fails, gballoc_realloc shall return NULL and no change should be made to the counted total memory usage.] */
+                if (ptr == NULL)
+                {
+                    free(allocation);
+                }
+            }
+            else
+            {
+                if (ptr != NULL)
+                {
+                    /* Codes_SRS_GBALLOC_01_006: [If the underlying realloc call is successful, gballoc_realloc shall look up the size associated with the pointer ptr and decrease the total memory used with that size.] */
+                    allocation->ptr = result;
+                    totalSize -= allocation->size;
+                    allocation->size = size;
+                }
+                else
+                {
+                    /* add block */
+                    allocation->ptr = result;
+                    allocation->size = size;
+                    allocation->next = head;
+                    head = allocation;
+                }
+
+                /* Codes_SRS_GBALLOC_01_007: [If realloc is successful, gballoc_realloc shall also increment the total memory used value tracked by this module.] */
+                totalSize += size;
+                g_allocations++;
+
+                /* Codes_SRS_GBALLOC_01_011: [The maximum total memory used shall be the maximum of the total memory used at any point.] */
+                if (maxSize < totalSize)
+                {
+                    maxSize = totalSize;
+                }
+            }
+        }
+
+        (void)Unlock(gballocThreadSafeLock);
+    }
+
+    return result;
+}
+
+void gballoc_free(void* ptr)
+{
+    ALLOCATION* curr = head;
+    ALLOCATION* prev = NULL;
+
+    if (gballocState != GBALLOC_STATE_INIT)
+    {
+        /* Codes_SRS_GBALLOC_01_042: [If gballoc was not initialized gballoc_free shall shall simply call free.] */
+        free(ptr);
+    }
+    /* Codes_SRS_GBALLOC_01_033: [gballoc_free shall ensure thread safety by using the lock created by gballoc_Init.] */
+    else if (LOCK_OK != Lock(gballocThreadSafeLock))
+    {
+        /* Codes_SRS_GBALLOC_01_049: [If acquiring the lock fails, gballoc_free shall do nothing.] */
+        LogError("Failed to get the Lock.");
+    }
+    else
+    {
+        /* Codes_SRS_GBALLOC_01_009: [gballoc_free shall also look up the size associated with the ptr pointer and decrease the total memory used with the associated size amount.] */
+        while (curr != NULL)
+        {
+            if (curr->ptr == ptr)
+            {
+                /* Codes_SRS_GBALLOC_01_008: [gballoc_free shall call the C99 free function.] */
+                free(ptr);
+                totalSize -= curr->size;
+                if (prev != NULL)
+                {
+                    prev->next = curr->next;
+                }
+                else
+                {
+                    head = (ALLOCATION*)curr->next;
+                }
+
+                free(curr);
+                break;
+            }
+
+            prev = curr;
+            curr = (ALLOCATION*)curr->next;
+        }
+
+        if ((curr == NULL) && (ptr != NULL))
+        {
+            /* Codes_SRS_GBALLOC_01_019: [When the ptr pointer cannot be found in the pointers tracked by gballoc, gballoc_free shall not free any memory.] */
+
+            /* could not find the allocation */
+            LogError("Could not free allocation for address %p (not found)", ptr);
+        }
+        (void)Unlock(gballocThreadSafeLock);
+    }
+}
+
+size_t gballoc_getMaximumMemoryUsed(void)
+{
+    size_t result;
+
+    /* Codes_SRS_GBALLOC_01_038: [If gballoc was not initialized gballoc_getMaximumMemoryUsed shall return MAX_INT_SIZE.] */
+    if (gballocState != GBALLOC_STATE_INIT)
+    {
+        LogError("gballoc is not initialized.");
+        result = SIZE_MAX;
+    }
+    /* Codes_SRS_GBALLOC_01_034: [gballoc_getMaximumMemoryUsed shall ensure thread safety by using the lock created by gballoc_Init.]  */
+    else if (LOCK_OK != Lock(gballocThreadSafeLock))
+    {
+        /* Codes_SRS_GBALLOC_01_050: [If the lock cannot be acquired, gballoc_getMaximumMemoryUsed shall return SIZE_MAX.]  */
+        LogError("Failed to get the Lock.");
+        result = SIZE_MAX;
+    }
+    else
+    {
+        /* Codes_SRS_GBALLOC_01_010: [gballoc_getMaximumMemoryUsed shall return the maximum amount of total memory used recorded since the module initialization.] */
+        result = maxSize;
+        (void)Unlock(gballocThreadSafeLock);
+    }
+
+    return result;
+}
+
+size_t gballoc_getCurrentMemoryUsed(void)
+{
+    size_t result;
+
+    /* Codes_SRS_GBALLOC_01_044: [If gballoc was not initialized gballoc_getCurrentMemoryUsed shall return SIZE_MAX.] */
+    if (gballocState != GBALLOC_STATE_INIT)
+    {
+        LogError("gballoc is not initialized.");
+        result = SIZE_MAX;
+    }
+    /* Codes_SRS_GBALLOC_01_036: [gballoc_getCurrentMemoryUsed shall ensure thread safety by using the lock created by gballoc_Init.]*/
+    else if (LOCK_OK != Lock(gballocThreadSafeLock))
+    {
+        /* Codes_SRS_GBALLOC_01_051: [If the lock cannot be acquired, gballoc_getCurrentMemoryUsed shall return SIZE_MAX.] */
+        LogError("Failed to get the Lock.");
+        result = SIZE_MAX;
+    }
+    else
+    {
+        /*Codes_SRS_GBALLOC_02_001: [gballoc_getCurrentMemoryUsed shall return the currently used memory size.] */
+        result = totalSize;
+        (void)Unlock(gballocThreadSafeLock);
+    }
+
+    return result;
+}
+
+size_t gballoc_getAllocationCount(void)
+{
+    size_t result;
+
+    /* Codes_SRS_GBALLOC_07_001: [ If gballoc was not initialized gballoc_getAllocationCount shall return 0. ] */
+    if (gballocState != GBALLOC_STATE_INIT)
+    {
+        LogError("gballoc is not initialized.");
+        result = 0;
+    }
+    /* Codes_SRS_GBALLOC_07_002: [ gballoc_getAllocationCount shall ensure thread safety by using the lock created by gballoc_Init ] */
+    else if (LOCK_OK != Lock(gballocThreadSafeLock))
+    {
+        /* Codes_SRS_GBALLOC_07_003: [ If the lock cannot be acquired, gballoc_getAllocationCount shall return 0. ] */
+        LogError("Failed to get the Lock.");
+        result = 0;
+    }
+    else
+    {
+        /* Codes_SRS_GBALLOC_07_004: [ gballoc_getAllocationCount shall return the currently number of allocations. ] */
+        result = g_allocations;
+        (void)Unlock(gballocThreadSafeLock);
+    }
+
+    return result;
+}
+
+void gballoc_resetMetrics()
+{
+    /* Codes_SRS_GBALLOC_07_005: [ If gballoc was not initialized gballoc_reset Metrics shall do nothing.] */
+    if (gballocState != GBALLOC_STATE_INIT)
+    {
+        LogError("gballoc is not initialized.");
+    }
+    /* Codes_SRS_GBALLOC_07_006: [ gballoc_resetMetrics shall ensure thread safety by using the lock created by gballoc_Init ]*/
+    else if (LOCK_OK != Lock(gballocThreadSafeLock))
+    {
+        /* Codes_SRS_GBALLOC_07_007: [ If the lock cannot be acquired, gballoc_reset Metrics shall do nothing.] */
+        LogError("Failed to get the Lock.");
+    }
+    else
+    {
+        /* Codes_SRS_GBALLOC_07_008: [ gballoc_resetMetrics shall reset the total allocation size, max allocation size and number of allocation to zero. ] */
+        totalSize = 0;
+        maxSize = 0;
+        g_allocations = 0;
+        (void)Unlock(gballocThreadSafeLock);
+    }
+}
+
+#endif // GB_USE_CUSTOM_HEAP
Index: azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/src/hmac.c
===================================================================
--- azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/src/hmac.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/src/hmac.c	(revision 457)
@@ -0,0 +1,233 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+/**************************** hmac.c ****************************/
+/******************** See RFC 4634 for details ******************/
+/*
+*  Description:
+*      This file implements the HMAC algorithm (Keyed-Hashing for
+*      Message Authentication, RFC2104), expressed in terms of the
+*      various SHA algorithms.
+*/
+
+#include "azure_c_shared_utility/sha.h"
+
+/*
+*  hmac
+*
+*  Description:
+*      This function will compute an HMAC message digest.
+*
+*  Parameters:
+*      whichSha: [in]
+*          One of SHA1, SHA224, SHA256, SHA384, SHA512
+*      key: [in]
+*          The secret shared key.
+*      key_len: [in]
+*          The length of the secret shared key.
+*      message_array: [in]
+*          An array of characters representing the message.
+*      length: [in]
+*          The length of the message in message_array
+*      digest: [out]
+*          Where the digest is returned.
+*          NOTE: The length of the digest is determined by
+*              the value of whichSha.
+*
+*  Returns:
+*      sha Error Code.
+*
+*/
+int hmac(SHAversion whichSha, const unsigned char *text, int text_len,
+    const unsigned char *key, int key_len,
+    uint8_t digest[USHAMaxHashSize])
+{
+    HMACContext ctx;
+    return hmacReset(&ctx, whichSha, key, key_len) ||
+        hmacInput(&ctx, text, text_len) ||
+        hmacResult(&ctx, digest);
+}
+
+/*
+*  hmacReset
+*
+*  Description:
+*      This function will initialize the hmacContext in preparation
+*      for computing a new HMAC message digest.
+*
+*  Parameters:
+*      context: [in/out]
+*          The context to reset.
+*      whichSha: [in]
+*          One of SHA1, SHA224, SHA256, SHA384, SHA512
+*      key: [in]
+*          The secret shared key.
+*      key_len: [in]
+*          The length of the secret shared key.
+*
+*  Returns:
+*      sha Error Code.
+*
+*/
+int hmacReset(HMACContext *ctx, enum SHAversion whichSha,
+    const unsigned char *key, int key_len)
+{
+    int i, blocksize, hashsize;
+
+    /* inner padding - key XORd with ipad */
+    unsigned char k_ipad[USHA_Max_Message_Block_Size];
+
+    /* temporary buffer when keylen > blocksize */
+    unsigned char tempkey[USHAMaxHashSize];
+
+    if (!ctx) return shaNull;
+
+    blocksize = ctx->blockSize = USHABlockSize(whichSha);
+    hashsize = ctx->hashSize = USHAHashSize(whichSha);
+
+    ctx->whichSha = whichSha;
+
+    /*
+    * If key is longer than the hash blocksize,
+    * reset it to key = HASH(key).
+    */
+    if (key_len > blocksize) {
+        USHAContext tctx;
+        int err = USHAReset(&tctx, whichSha) ||
+            USHAInput(&tctx, key, key_len) ||
+            USHAResult(&tctx, tempkey);
+        if (err != shaSuccess) return err;
+
+        key = tempkey;
+        key_len = hashsize;
+    }
+
+    /*
+    * The HMAC transform looks like:
+    *
+    * SHA(K XOR opad, SHA(K XOR ipad, text))
+    *
+    * where K is an n byte key.
+    * ipad is the byte 0x36 repeated blocksize times
+    * opad is the byte 0x5c repeated blocksize times
+    * and text is the data being protected.
+    */
+
+    /* store key into the pads, XOR'd with ipad and opad values */
+    for (i = 0; i < key_len; i++) {
+        k_ipad[i] = key[i] ^ 0x36;
+        ctx->k_opad[i] = key[i] ^ 0x5c;
+    }
+    /* remaining pad bytes are '\0' XOR'd with ipad and opad values */
+    for (; i < blocksize; i++) {
+        k_ipad[i] = 0x36;
+        ctx->k_opad[i] = 0x5c;
+    }
+
+    /* perform inner hash */
+    /* init context for 1st pass */
+    return USHAReset(&ctx->shaContext, whichSha) ||
+        /* and start with inner pad */
+        USHAInput(&ctx->shaContext, k_ipad, blocksize);
+}
+
+/*
+*  hmacInput
+*
+*  Description:
+*      This function accepts an array of octets as the next portion
+*      of the message.
+*
+*  Parameters:
+*      context: [in/out]
+*          The HMAC context to update
+*      message_array: [in]
+*          An array of characters representing the next portion of
+*          the message.
+*      length: [in]
+*          The length of the message in message_array
+*
+*  Returns:
+*      sha Error Code.
+*
+*/
+int hmacInput(HMACContext *ctx, const unsigned char *text,
+    int text_len)
+{
+    if (!ctx) return shaNull;
+    /* then text of datagram */
+    return USHAInput(&ctx->shaContext, text, text_len);
+}
+
+/*
+* HMACFinalBits
+*
+* Description:
+*   This function will add in any final bits of the message.
+*
+* Parameters:
+*   context: [in/out]
+*     The HMAC context to update
+*   message_bits: [in]
+*     The final bits of the message, in the upper portion of the
+*     byte. (Use 0b###00000 instead of 0b00000### to input the
+*     three bits ###.)
+*   length: [in]
+*     The number of bits in message_bits, between 1 and 7.
+*
+* Returns:
+*   sha Error Code.
+*/
+int hmacFinalBits(HMACContext *ctx,
+    const uint8_t bits,
+    unsigned int bitcount)
+{
+    if (!ctx) return shaNull;
+    /* then final bits of datagram */
+    return USHAFinalBits(&ctx->shaContext, bits, bitcount);
+}
+
+/*
+* HMACResult
+*
+* Description:
+*   This function will return the N-byte message digest into the
+*   Message_Digest array provided by the caller.
+*   NOTE: The first octet of hash is stored in the 0th element,
+*      the last octet of hash in the Nth element.
+*
+* Parameters:
+*   context: [in/out]
+*     The context to use to calculate the HMAC hash.
+*   digest: [out]
+*     Where the digest is returned.
+*   NOTE 2: The length of the hash is determined by the value of
+*      whichSha that was passed to hmacReset().
+*
+* Returns:
+*   sha Error Code.
+*
+*/
+int hmacResult(HMACContext *ctx, uint8_t *digest)
+{
+    if (!ctx) return shaNull;
+
+    /* finish up 1st pass */
+    /* (Use digest here as a temporary buffer.) */
+    return USHAResult(&ctx->shaContext, digest) ||
+
+        /* perform outer SHA */
+        /* init context for 2nd pass */
+        USHAReset(&ctx->shaContext, (SHAversion)ctx->whichSha) ||
+
+        /* start with outer pad */
+        USHAInput(&ctx->shaContext, ctx->k_opad, ctx->blockSize) ||
+
+        /* then results of 1st hash */
+        USHAInput(&ctx->shaContext, digest, ctx->hashSize) ||
+
+        /* finish up 2nd pass */
+        USHAResult(&ctx->shaContext, digest);
+}
+
+
Index: azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/src/hmacsha256.c
===================================================================
--- azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/src/hmacsha256.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/src/hmacsha256.c	(revision 457)
@@ -0,0 +1,35 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+#include <stddef.h>
+#include "azure_c_shared_utility/hmacsha256.h"
+#include "azure_c_shared_utility/hmac.h"
+#include "azure_c_shared_utility/buffer_.h"
+
+HMACSHA256_RESULT HMACSHA256_ComputeHash(const unsigned char* key, size_t keyLen, const unsigned char* payload, size_t payloadLen, BUFFER_HANDLE hash)
+{
+    HMACSHA256_RESULT result;
+
+    if (key == NULL ||
+        keyLen == 0 ||
+        payload == NULL ||
+        payloadLen == 0 ||
+        hash == NULL)
+    {
+        result = HMACSHA256_INVALID_ARG;
+    }
+    else
+    {
+        if ((BUFFER_enlarge(hash, 32) != 0) ||
+            (hmac(SHA256, payload, (int)payloadLen, key, (int)keyLen, BUFFER_u_char(hash) ) != 0))
+        {
+            result = HMACSHA256_ERROR;
+        }
+        else
+        {
+            result = HMACSHA256_OK;
+        }
+    }
+
+    return result;
+}
Index: azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/src/http_proxy_io.c
===================================================================
--- azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/src/http_proxy_io.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/src/http_proxy_io.c	(revision 457)
@@ -0,0 +1,1048 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdbool.h>
+#include <stdint.h>
+#include <limits.h>
+#include "azure_c_shared_utility/gballoc.h"
+#include "azure_c_shared_utility/xio.h"
+#include "azure_c_shared_utility/socketio.h"
+#include "azure_c_shared_utility/crt_abstractions.h"
+#include "azure_c_shared_utility/http_proxy_io.h"
+#include "azure_c_shared_utility/azure_base64.h"
+
+static const char* const OPTION_UNDERLYING_IO_OPTIONS = "underlying_io_options";
+
+typedef enum HTTP_PROXY_IO_STATE_TAG
+{
+    HTTP_PROXY_IO_STATE_CLOSED,
+    HTTP_PROXY_IO_STATE_OPENING_UNDERLYING_IO,
+    HTTP_PROXY_IO_STATE_WAITING_FOR_CONNECT_RESPONSE,
+    HTTP_PROXY_IO_STATE_OPEN,
+    HTTP_PROXY_IO_STATE_CLOSING,
+    HTTP_PROXY_IO_STATE_ERROR
+} HTTP_PROXY_IO_STATE;
+
+typedef struct HTTP_PROXY_IO_INSTANCE_TAG
+{
+    HTTP_PROXY_IO_STATE http_proxy_io_state;
+    ON_BYTES_RECEIVED on_bytes_received;
+    void* on_bytes_received_context;
+    ON_IO_ERROR on_io_error;
+    void* on_io_error_context;
+    ON_IO_OPEN_COMPLETE on_io_open_complete;
+    void* on_io_open_complete_context;
+    ON_IO_CLOSE_COMPLETE on_io_close_complete;
+    void* on_io_close_complete_context;
+    char* hostname;
+    int port;
+    char* proxy_hostname;
+    int proxy_port;
+    char* username;
+    char* password;
+    XIO_HANDLE underlying_io;
+    unsigned char* receive_buffer;
+    size_t receive_buffer_size;
+} HTTP_PROXY_IO_INSTANCE;
+
+static CONCRETE_IO_HANDLE http_proxy_io_create(void* io_create_parameters)
+{
+    HTTP_PROXY_IO_INSTANCE* result;
+
+    if (io_create_parameters == NULL)
+    {
+        /* Codes_SRS_HTTP_PROXY_IO_01_002: [ If io_create_parameters is NULL, http_proxy_io_create shall fail and return NULL. ]*/
+        result = NULL;
+        LogError("NULL io_create_parameters.");
+    }
+    else
+    {
+        /* Codes_SRS_HTTP_PROXY_IO_01_003: [ io_create_parameters shall be used as an HTTP_PROXY_IO_CONFIG*. ]*/
+        HTTP_PROXY_IO_CONFIG* http_proxy_io_config = (HTTP_PROXY_IO_CONFIG*)io_create_parameters;
+        if ((http_proxy_io_config->hostname == NULL) ||
+            (http_proxy_io_config->proxy_hostname == NULL))
+        {
+            /* Codes_SRS_HTTP_PROXY_IO_01_004: [ If the hostname or proxy_hostname member is NULL, then http_proxy_io_create shall fail and return NULL. ]*/
+            result = NULL;
+            LogError("Bad arguments: hostname = %p, proxy_hostname = %p",
+                http_proxy_io_config->hostname, http_proxy_io_config->proxy_hostname);
+        }
+        /* Codes_SRS_HTTP_PROXY_IO_01_095: [ If one of the fields username and password is non-NULL, then the other has to be also non-NULL, otherwise http_proxy_io_create shall fail and return NULL. ]*/
+        else if (((http_proxy_io_config->username == NULL) && (http_proxy_io_config->password != NULL)) ||
+            ((http_proxy_io_config->username != NULL) && (http_proxy_io_config->password == NULL)))
+        {
+            result = NULL;
+            LogError("Bad arguments: username = %p, password = %p",
+                http_proxy_io_config->username, http_proxy_io_config->password);
+        }
+        else
+        {
+            /* Codes_SRS_HTTP_PROXY_IO_01_001: [ http_proxy_io_create shall create a new instance of the HTTP proxy IO. ]*/
+            result = (HTTP_PROXY_IO_INSTANCE*)calloc(1, sizeof(HTTP_PROXY_IO_INSTANCE));
+            if (result == NULL)
+            {
+                /* Codes_SRS_HTTP_PROXY_IO_01_051: [ If allocating memory for the new instance fails, http_proxy_io_create shall fail and return NULL. ]*/
+                LogError("Failed allocating HTTP proxy IO instance.");
+            }
+            else
+            {
+                /* Codes_SRS_HTTP_PROXY_IO_01_005: [ http_proxy_io_create shall copy the hostname, port, username and password values for later use when the actual CONNECT is performed. ]*/
+                /* Codes_SRS_HTTP_PROXY_IO_01_006: [ hostname and proxy_hostname, username and password shall be copied by calling mallocAndStrcpy_s. ]*/
+                if (mallocAndStrcpy_s(&result->hostname, http_proxy_io_config->hostname) != 0)
+                {
+                    /* Codes_SRS_HTTP_PROXY_IO_01_007: [ If mallocAndStrcpy_s fails then http_proxy_io_create shall fail and return NULL. ]*/
+                    LogError("Failed to copy the hostname.");
+                    /* Codes_SRS_HTTP_PROXY_IO_01_008: [ When http_proxy_io_create fails, all allocated resources up to that point shall be freed. ]*/
+                    free(result);
+                    result = NULL;
+                }
+                else
+                {
+                    /* Codes_SRS_HTTP_PROXY_IO_01_006: [ hostname and proxy_hostname, username and password shall be copied by calling mallocAndStrcpy_s. ]*/
+                    if (mallocAndStrcpy_s(&result->proxy_hostname, http_proxy_io_config->proxy_hostname) != 0)
+                    {
+                        /* Codes_SRS_HTTP_PROXY_IO_01_007: [ If mallocAndStrcpy_s fails then http_proxy_io_create shall fail and return NULL. ]*/
+                        LogError("Failed to copy the proxy_hostname.");
+                        /* Codes_SRS_HTTP_PROXY_IO_01_008: [ When http_proxy_io_create fails, all allocated resources up to that point shall be freed. ]*/
+                        free(result->hostname);
+                        free(result);
+                        result = NULL;
+                    }
+                    else
+                    {
+                        result->username = NULL;
+                        result->password = NULL;
+
+                        /* Codes_SRS_HTTP_PROXY_IO_01_006: [ hostname and proxy_hostname, username and password shall be copied by calling mallocAndStrcpy_s. ]*/
+                        /* Codes_SRS_HTTP_PROXY_IO_01_094: [ username and password shall be optional. ]*/
+                        if ((http_proxy_io_config->username != NULL) && (mallocAndStrcpy_s(&result->username, http_proxy_io_config->username) != 0))
+                        {
+                            /* Codes_SRS_HTTP_PROXY_IO_01_007: [ If mallocAndStrcpy_s fails then http_proxy_io_create shall fail and return NULL. ]*/
+                            LogError("Failed to copy the username.");
+                            /* Codes_SRS_HTTP_PROXY_IO_01_008: [ When http_proxy_io_create fails, all allocated resources up to that point shall be freed. ]*/
+                            free(result->proxy_hostname);
+                            free(result->hostname);
+                            free(result);
+                            result = NULL;
+                        }
+                        else
+                        {
+                            /* Codes_SRS_HTTP_PROXY_IO_01_006: [ hostname and proxy_hostname, username and password shall be copied by calling mallocAndStrcpy_s. ]*/
+                            /* Codes_SRS_HTTP_PROXY_IO_01_094: [ username and password shall be optional. ]*/
+                            if ((http_proxy_io_config->password != NULL) && (mallocAndStrcpy_s(&result->password, http_proxy_io_config->password) != 0))
+                            {
+                                /* Codes_SRS_HTTP_PROXY_IO_01_007: [ If mallocAndStrcpy_s fails then http_proxy_io_create shall fail and return NULL. ]*/
+                                LogError("Failed to copy the passowrd.");
+                                /* Codes_SRS_HTTP_PROXY_IO_01_008: [ When http_proxy_io_create fails, all allocated resources up to that point shall be freed. ]*/
+                                free(result->username);
+                                free(result->proxy_hostname);
+                                free(result->hostname);
+                                free(result);
+                                result = NULL;
+                            }
+                            else
+                            {
+                                /* Codes_SRS_HTTP_PROXY_IO_01_010: [ - io_interface_description shall be set to the result of socketio_get_interface_description. ]*/
+                                const IO_INTERFACE_DESCRIPTION* underlying_io_interface = socketio_get_interface_description();
+                                if (underlying_io_interface == NULL)
+                                {
+                                    /* Codes_SRS_HTTP_PROXY_IO_01_050: [ If socketio_get_interface_description fails, http_proxy_io_create shall fail and return NULL. ]*/
+                                    LogError("Unable to get the socket IO interface description.");
+                                    /* Codes_SRS_HTTP_PROXY_IO_01_008: [ When http_proxy_io_create fails, all allocated resources up to that point shall be freed. ]*/
+                                    free(result->password);
+                                    free(result->username);
+                                    free(result->proxy_hostname);
+                                    free(result->hostname);
+                                    free(result);
+                                    result = NULL;
+                                }
+                                else
+                                {
+                                    SOCKETIO_CONFIG socket_io_config;
+
+                                    /* Codes_SRS_HTTP_PROXY_IO_01_011: [ - xio_create_parameters shall be set to a SOCKETIO_CONFIG* where hostname is set to the proxy_hostname member of io_create_parameters and port is set to the proxy_port member of io_create_parameters. ]*/
+                                    socket_io_config.hostname = http_proxy_io_config->proxy_hostname;
+                                    socket_io_config.port = http_proxy_io_config->proxy_port;
+                                    socket_io_config.accepted_socket = NULL;
+
+                                    /* Codes_SRS_HTTP_PROXY_IO_01_009: [ http_proxy_io_create shall create a new socket IO by calling xio_create with the arguments: ]*/
+                                    result->underlying_io = xio_create(underlying_io_interface, &socket_io_config);
+                                    if (result->underlying_io == NULL)
+                                    {
+                                        /* Codes_SRS_HTTP_PROXY_IO_01_012: [ If xio_create fails, http_proxy_io_create shall fail and return NULL. ]*/
+                                        LogError("Unable to create the underlying IO.");
+                                        /* Codes_SRS_HTTP_PROXY_IO_01_008: [ When http_proxy_io_create fails, all allocated resources up to that point shall be freed. ]*/
+                                        free(result->password);
+                                        free(result->username);
+                                        free(result->proxy_hostname);
+                                        free(result->hostname);
+                                        free(result);
+                                        result = NULL;
+                                    }
+                                    else
+                                    {
+                                        result->port = http_proxy_io_config->port;
+                                        result->proxy_port = http_proxy_io_config->proxy_port;
+                                        result->receive_buffer = NULL;
+                                        result->receive_buffer_size = 0;
+                                        result->http_proxy_io_state = HTTP_PROXY_IO_STATE_CLOSED;
+                                    }
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    return result;
+}
+
+static void http_proxy_io_destroy(CONCRETE_IO_HANDLE http_proxy_io)
+{
+    if (http_proxy_io == NULL)
+    {
+        /* Codes_SRS_HTTP_PROXY_IO_01_014: [ If http_proxy_io is NULL, http_proxy_io_destroy shall do nothing. ]*/
+        LogError("NULL http_proxy_io.");
+    }
+    else
+    {
+        HTTP_PROXY_IO_INSTANCE* http_proxy_io_instance = (HTTP_PROXY_IO_INSTANCE*)http_proxy_io;
+
+        /* Codes_SRS_HTTP_PROXY_IO_01_013: [ http_proxy_io_destroy shall free the HTTP proxy IO instance indicated by http_proxy_io. ]*/
+        if (http_proxy_io_instance->receive_buffer != NULL)
+        {
+            free(http_proxy_io_instance->receive_buffer);
+        }
+
+        /* Codes_SRS_HTTP_PROXY_IO_01_016: [ http_proxy_io_destroy shall destroy the underlying IO created in http_proxy_io_create by calling xio_destroy. ]*/
+        xio_destroy(http_proxy_io_instance->underlying_io);
+        free(http_proxy_io_instance->hostname);
+        free(http_proxy_io_instance->proxy_hostname);
+        free(http_proxy_io_instance->username);
+        free(http_proxy_io_instance->password);
+        free(http_proxy_io_instance);
+    }
+}
+
+static void indicate_open_complete_error_and_close(HTTP_PROXY_IO_INSTANCE* http_proxy_io_instance)
+{
+    http_proxy_io_instance->http_proxy_io_state = HTTP_PROXY_IO_STATE_CLOSED;
+    (void)xio_close(http_proxy_io_instance->underlying_io, NULL, NULL);
+    http_proxy_io_instance->on_io_open_complete(http_proxy_io_instance->on_io_open_complete_context, IO_OPEN_ERROR);
+}
+
+// This callback usage needs to be either verified and commented or integrated into
+// the state machine.
+static void unchecked_on_send_complete(void* context, IO_SEND_RESULT send_result)
+{
+    (void)context;
+    (void)send_result;
+}
+
+static void on_underlying_io_open_complete(void* context, IO_OPEN_RESULT open_result)
+{
+    if (context == NULL)
+    {
+        /* Codes_SRS_HTTP_PROXY_IO_01_081: [ on_underlying_io_open_complete called with NULL context shall do nothing. ]*/
+        LogError("NULL context in on_underlying_io_open_complete");
+    }
+    else
+    {
+        HTTP_PROXY_IO_INSTANCE* http_proxy_io_instance = (HTTP_PROXY_IO_INSTANCE*)context;
+        switch (http_proxy_io_instance->http_proxy_io_state)
+        {
+        default:
+            LogError("on_underlying_io_open_complete called in an unexpected state.");
+            break;
+
+        case HTTP_PROXY_IO_STATE_CLOSING:
+        case HTTP_PROXY_IO_STATE_OPEN:
+            /* Codes_SRS_HTTP_PROXY_IO_01_077: [ When on_underlying_io_open_complete is called in after OPEN has completed, the on_io_error callback shall be triggered passing the on_io_error_context argument as context. ]*/
+            http_proxy_io_instance->on_io_error(http_proxy_io_instance->on_io_error_context);
+            break;
+
+        case HTTP_PROXY_IO_STATE_WAITING_FOR_CONNECT_RESPONSE:
+            /* Codes_SRS_HTTP_PROXY_IO_01_076: [ When on_underlying_io_open_complete is called while waiting for the CONNECT reply, the on_open_complete callback shall be triggered with IO_OPEN_ERROR, passing also the on_open_complete_context argument as context. ]*/
+            LogError("Open complete called again by underlying IO.");
+            indicate_open_complete_error_and_close(http_proxy_io_instance);
+            break;
+
+        case HTTP_PROXY_IO_STATE_OPENING_UNDERLYING_IO:
+            switch (open_result)
+            {
+            default:
+            case IO_OPEN_ERROR:
+                /* Codes_SRS_HTTP_PROXY_IO_01_078: [ When on_underlying_io_open_complete is called with IO_OPEN_ERROR, the on_open_complete callback shall be triggered with IO_OPEN_ERROR, passing also the on_open_complete_context argument as context. ]*/
+                LogError("Underlying IO open failed");
+                indicate_open_complete_error_and_close(http_proxy_io_instance);
+                break;
+
+            case IO_OPEN_CANCELLED:
+                /* Codes_SRS_HTTP_PROXY_IO_01_079: [ When on_underlying_io_open_complete is called with IO_OPEN_CANCELLED, the on_open_complete callback shall be triggered with IO_OPEN_CANCELLED, passing also the on_open_complete_context argument as context. ]*/
+                LogError("Underlying IO open failed");
+                http_proxy_io_instance->http_proxy_io_state = HTTP_PROXY_IO_STATE_CLOSED;
+                (void)xio_close(http_proxy_io_instance->underlying_io, NULL, NULL);
+                http_proxy_io_instance->on_io_open_complete(http_proxy_io_instance->on_io_open_complete_context, IO_OPEN_CANCELLED);
+                break;
+
+            case IO_OPEN_OK:
+            {
+                STRING_HANDLE encoded_auth_string;
+
+                /* Codes_SRS_HTTP_PROXY_IO_01_057: [ When on_underlying_io_open_complete is called, the http_proxy_io shall send the CONNECT request constructed per RFC 2817: ]*/
+                http_proxy_io_instance->http_proxy_io_state = HTTP_PROXY_IO_STATE_WAITING_FOR_CONNECT_RESPONSE;
+
+                if (http_proxy_io_instance->username != NULL)
+                {
+                    char* plain_auth_string_bytes;
+
+                    /* Codes_SRS_HTTP_PROXY_IO_01_060: [ - The value of Proxy-Authorization shall be the constructed according to RFC 2617. ]*/
+                    int plain_auth_string_length = (int)(strlen(http_proxy_io_instance->username)+1);
+                    if (http_proxy_io_instance->password != NULL)
+                    {
+                        plain_auth_string_length += (int)strlen(http_proxy_io_instance->password);
+                    }
+
+                    if (plain_auth_string_length < 0)
+                    {
+                        /* Codes_SRS_HTTP_PROXY_IO_01_062: [ If any failure is encountered while constructing the request, the on_open_complete callback shall be triggered with IO_OPEN_ERROR, passing also the on_open_complete_context argument as context. ]*/
+                        encoded_auth_string = NULL;
+                        indicate_open_complete_error_and_close(http_proxy_io_instance);
+                    }
+                    else
+                    {
+                        plain_auth_string_bytes = (char*)malloc(plain_auth_string_length + 1);
+                        if (plain_auth_string_bytes == NULL)
+                        {
+                            /* Codes_SRS_HTTP_PROXY_IO_01_062: [ If any failure is encountered while constructing the request, the on_open_complete callback shall be triggered with IO_OPEN_ERROR, passing also the on_open_complete_context argument as context. ]*/
+                            encoded_auth_string = NULL;
+                            indicate_open_complete_error_and_close(http_proxy_io_instance);
+                        }
+                        else
+                        {
+                            /* Codes_SRS_HTTP_PROXY_IO_01_091: [ To receive authorization, the client sends the userid and password, separated by a single colon (":") character, within a base64 [7] encoded string in the credentials. ]*/
+                            /* Codes_SRS_HTTP_PROXY_IO_01_092: [ A client MAY preemptively send the corresponding Authorization header with requests for resources in that space without receipt of another challenge from the server. ]*/
+                            /* Codes_SRS_HTTP_PROXY_IO_01_093: [ Userids might be case sensitive. ]*/
+                            if (sprintf(plain_auth_string_bytes, "%s:%s", http_proxy_io_instance->username, (http_proxy_io_instance->password == NULL) ? "" : http_proxy_io_instance->password) < 0)
+                            {
+                                /* Codes_SRS_HTTP_PROXY_IO_01_062: [ If any failure is encountered while constructing the request, the on_open_complete callback shall be triggered with IO_OPEN_ERROR, passing also the on_open_complete_context argument as context. ]*/
+                                encoded_auth_string = NULL;
+                                indicate_open_complete_error_and_close(http_proxy_io_instance);
+                            }
+                            else
+                            {
+                                /* Codes_SRS_HTTP_PROXY_IO_01_061: [ Encoding to Base64 shall be done by calling Azure_Base64_Encode_Bytes. ]*/
+                                encoded_auth_string = Azure_Base64_Encode_Bytes((const unsigned char*)plain_auth_string_bytes, plain_auth_string_length);
+                                if (encoded_auth_string == NULL)
+                                {
+                                    /* Codes_SRS_HTTP_PROXY_IO_01_062: [ If any failure is encountered while constructing the request, the on_open_complete callback shall be triggered with IO_OPEN_ERROR, passing also the on_open_complete_context argument as context. ]*/
+                                    LogError("Cannot Base64 encode auth string");
+                                    indicate_open_complete_error_and_close(http_proxy_io_instance);
+                                }
+                            }
+
+                            free(plain_auth_string_bytes);
+                        }
+                    }
+                }
+                else
+                {
+                    encoded_auth_string = NULL;
+                }
+
+                if ((http_proxy_io_instance->username != NULL) &&
+                    (encoded_auth_string == NULL))
+                {
+                    LogError("Cannot create authorization header");
+                }
+                else
+                {
+                    int connect_request_length;
+                    const char* auth_string_payload;
+                    /* Codes_SRS_HTTP_PROXY_IO_01_075: [ The Request-URI portion of the Request-Line is always an 'authority' as defined by URI Generic Syntax [2], which is to say the host name and port number destination of the requested connection separated by a colon: ]*/
+                    const char request_format[] = "CONNECT %s:%d HTTP/1.1\r\nHost:%s:%d%s%s\r\n\r\n";
+                    const char proxy_basic[] = "\r\nProxy-authorization: Basic ";
+                    if (http_proxy_io_instance->username != NULL)
+                    {
+                        auth_string_payload = STRING_c_str(encoded_auth_string);
+                    }
+                    else
+                    {
+                        auth_string_payload = "";
+                    }
+
+                    /* Codes_SRS_HTTP_PROXY_IO_01_059: [ - If username and password have been specified in the arguments passed to http_proxy_io_create, then the header Proxy-Authorization shall be added to the request. ]*/
+
+                    connect_request_length = (int)(strlen(request_format)+(strlen(http_proxy_io_instance->hostname)*2)+strlen(auth_string_payload)+10);
+                    if (http_proxy_io_instance->username != NULL)
+                    {
+                        connect_request_length += (int)strlen(proxy_basic);
+                    }
+
+                    if (connect_request_length < 0)
+                    {
+                        /* Codes_SRS_HTTP_PROXY_IO_01_062: [ If any failure is encountered while constructing the request, the on_open_complete callback shall be triggered with IO_OPEN_ERROR, passing also the on_open_complete_context argument as context. ]*/
+                        LogError("Cannot encode the CONNECT request");
+                        indicate_open_complete_error_and_close(http_proxy_io_instance);
+                    }
+                    else
+                    {
+                        char* connect_request = (char*)malloc(connect_request_length + 1);
+                        if (connect_request == NULL)
+                        {
+                            /* Codes_SRS_HTTP_PROXY_IO_01_062: [ If any failure is encountered while constructing the request, the on_open_complete callback shall be triggered with IO_OPEN_ERROR, passing also the on_open_complete_context argument as context. ]*/
+                            LogError("Cannot allocate memory for CONNECT request");
+                            indicate_open_complete_error_and_close(http_proxy_io_instance);
+                        }
+                        else
+                        {
+                            /* Codes_SRS_HTTP_PROXY_IO_01_059: [ - If username and password have been specified in the arguments passed to http_proxy_io_create, then the header Proxy-Authorization shall be added to the request. ]*/
+                            connect_request_length = sprintf(connect_request, request_format,
+                                http_proxy_io_instance->hostname,
+                                http_proxy_io_instance->port,
+                                http_proxy_io_instance->hostname,
+                                http_proxy_io_instance->port,
+                                (http_proxy_io_instance->username != NULL) ? proxy_basic : "",
+                                auth_string_payload);
+
+                            if (connect_request_length < 0)
+                            {
+                                /* Codes_SRS_HTTP_PROXY_IO_01_062: [ If any failure is encountered while constructing the request, the on_open_complete callback shall be triggered with IO_OPEN_ERROR, passing also the on_open_complete_context argument as context. ]*/
+                                LogError("Cannot encode the CONNECT request");
+                                indicate_open_complete_error_and_close(http_proxy_io_instance);
+                            }
+                            else
+                            {
+                                /* Codes_SRS_HTTP_PROXY_IO_01_063: [ The request shall be sent by calling xio_send and passing NULL as on_send_complete callback. ]*/
+                                if (xio_send(http_proxy_io_instance->underlying_io, connect_request, connect_request_length, unchecked_on_send_complete, NULL) != 0)
+                                {
+                                    /* Codes_SRS_HTTP_PROXY_IO_01_064: [ If xio_send fails, the on_open_complete callback shall be triggered with IO_OPEN_ERROR, passing also the on_open_complete_context argument as context. ]*/
+                                    LogError("Could not send CONNECT request");
+                                    indicate_open_complete_error_and_close(http_proxy_io_instance);
+                                }
+                            }
+
+                            free(connect_request);
+                        }
+                    }
+                }
+
+                if (encoded_auth_string != NULL)
+                {
+                    STRING_delete(encoded_auth_string);
+                }
+
+                break;
+            }
+            }
+
+            break;
+        }
+    }
+}
+
+static void on_underlying_io_error(void* context)
+{
+    if (context == NULL)
+    {
+        /* Codes_SRS_HTTP_PROXY_IO_01_088: [ on_underlying_io_error called with NULL context shall do nothing. ]*/
+        LogError("NULL context in on_underlying_io_error");
+    }
+    else
+    {
+        HTTP_PROXY_IO_INSTANCE* http_proxy_io_instance = (HTTP_PROXY_IO_INSTANCE*)context;
+
+        switch (http_proxy_io_instance->http_proxy_io_state)
+        {
+        default:
+            LogError("on_underlying_io_error in invalid state");
+            break;
+
+        case HTTP_PROXY_IO_STATE_OPENING_UNDERLYING_IO:
+        case HTTP_PROXY_IO_STATE_WAITING_FOR_CONNECT_RESPONSE:
+            /* Codes_SRS_HTTP_PROXY_IO_01_087: [ If the on_underlying_io_error callback is called while OPENING, the on_open_complete callback shall be triggered with IO_OPEN_ERROR, passing also the on_open_complete_context argument as context. ]*/
+            indicate_open_complete_error_and_close(http_proxy_io_instance);
+            break;
+
+        case HTTP_PROXY_IO_STATE_OPEN:
+            /* Codes_SRS_HTTP_PROXY_IO_01_089: [ If the on_underlying_io_error callback is called while the IO is OPEN, the on_io_error callback shall be called with the on_io_error_context argument as context. ]*/
+            http_proxy_io_instance->http_proxy_io_state = HTTP_PROXY_IO_STATE_ERROR;
+            http_proxy_io_instance->on_io_error(http_proxy_io_instance->on_io_error_context);
+            break;
+        }
+    }
+}
+
+static void on_underlying_io_close_complete(void* context)
+{
+    if (context == NULL)
+    {
+        /* Cdoes_SRS_HTTP_PROXY_IO_01_084: [ on_underlying_io_close_complete called with NULL context shall do nothing. ]*/
+        LogError("NULL context in on_underlying_io_open_complete");
+    }
+    else
+    {
+        HTTP_PROXY_IO_INSTANCE* http_proxy_io_instance = (HTTP_PROXY_IO_INSTANCE*)context;
+
+        switch (http_proxy_io_instance->http_proxy_io_state)
+        {
+        default:
+            LogError("on_underlying_io_close_complete called in an invalid state");
+            break;
+
+        case HTTP_PROXY_IO_STATE_CLOSING:
+            http_proxy_io_instance->http_proxy_io_state = HTTP_PROXY_IO_STATE_CLOSED;
+
+            /* Codes_SRS_HTTP_PROXY_IO_01_086: [ If the on_io_close_complete callback passed to http_proxy_io_close was NULL, no callback shall be triggered. ]*/
+            if (http_proxy_io_instance->on_io_close_complete != NULL)
+            {
+                /* Codes_SRS_HTTP_PROXY_IO_01_083: [ on_underlying_io_close_complete while CLOSING shall call the on_io_close_complete callback, passing to it the on_io_close_complete_context as context argument. ]*/
+                http_proxy_io_instance->on_io_close_complete(http_proxy_io_instance->on_io_close_complete_context);
+            }
+
+            break;
+        }
+    }
+}
+
+/*the following function does the same as sscanf(pos2, "%d", &sec)*/
+/*this function only exists because some of platforms do not have sscanf. */
+static int ParseStringToDecimal(const char *src, int* dst)
+{
+    int result;
+    char* next;
+
+    (*dst) = (int)strtol(src, &next, 0);
+    if ((src == next) || ((((*dst) == INT_MAX) || ((*dst) == INT_MIN)) && (errno != 0)))
+    {
+        result = __LINE__;
+    }
+    else
+    {
+        result = 0;
+    }
+
+    return result;
+}
+
+/*the following function does the same as sscanf(buf, "HTTP/%*d.%*d %d %*[^\r\n]", &ret) */
+/*this function only exists because some of platforms do not have sscanf. This is not a full implementation; it only works with well-defined HTTP response. */
+static int ParseHttpResponse(const char* src, int* dst)
+{
+    int result;
+    static const char HTTPPrefix[] = "HTTP/";
+    bool fail;
+    const char* runPrefix;
+
+    if ((src == NULL) || (dst == NULL))
+    {
+        result = __LINE__;
+    }
+    else
+    {
+        fail = false;
+        runPrefix = HTTPPrefix;
+
+        while ((*runPrefix) != '\0')
+        {
+            if ((*runPrefix) != (*src))
+            {
+                fail = true;
+                break;
+            }
+            src++;
+            runPrefix++;
+        }
+
+        if (!fail)
+        {
+            while ((*src) != '.')
+            {
+                if ((*src) == '\0')
+                {
+                    fail = true;
+                    break;
+                }
+                src++;
+            }
+        }
+
+        if (!fail)
+        {
+            while ((*src) != ' ')
+            {
+                if ((*src) == '\0')
+                {
+                    fail = true;
+                    break;
+                }
+                src++;
+            }
+        }
+
+        if (fail)
+        {
+            result = __LINE__;
+        }
+        else
+        {
+            if (ParseStringToDecimal(src, dst) != 0)
+            {
+                result = __LINE__;
+            }
+            else
+            {
+                result = 0;
+            }
+        }
+    }
+
+    return result;
+}
+
+static void on_underlying_io_bytes_received(void* context, const unsigned char* buffer, size_t size)
+{
+    if (context == NULL)
+    {
+        /* Codes_SRS_HTTP_PROXY_IO_01_082: [ on_underlying_io_bytes_received called with NULL context shall do nothing. ]*/
+        LogError("NULL context in on_underlying_io_bytes_received");
+    }
+    else
+    {
+        HTTP_PROXY_IO_INSTANCE* http_proxy_io_instance = (HTTP_PROXY_IO_INSTANCE*)context;
+
+        switch (http_proxy_io_instance->http_proxy_io_state)
+        {
+        default:
+        case HTTP_PROXY_IO_STATE_CLOSING:
+            LogError("Bytes received in invalid state");
+            break;
+
+        case HTTP_PROXY_IO_STATE_OPENING_UNDERLYING_IO:
+            /* Codes_SRS_HTTP_PROXY_IO_01_080: [ If on_underlying_io_bytes_received is called while the underlying IO is being opened, the on_open_complete callback shall be triggered with IO_OPEN_ERROR, passing also the on_open_complete_context argument as context. ]*/
+            LogError("Bytes received while opening underlying IO");
+            indicate_open_complete_error_and_close(http_proxy_io_instance);
+            break;
+
+        case HTTP_PROXY_IO_STATE_WAITING_FOR_CONNECT_RESPONSE:
+        {
+            /* Codes_SRS_HTTP_PROXY_IO_01_065: [ When bytes are received and the response to the CONNECT request was not yet received, the bytes shall be accumulated until a double new-line is detected. ]*/
+            unsigned char* new_receive_buffer = (unsigned char*)realloc(http_proxy_io_instance->receive_buffer, http_proxy_io_instance->receive_buffer_size + size + 1);
+            if (new_receive_buffer == NULL)
+            {
+                /* Codes_SRS_HTTP_PROXY_IO_01_067: [ If allocating memory for the buffered bytes fails, the on_open_complete callback shall be triggered with IO_OPEN_ERROR, passing also the on_open_complete_context argument as context. ]*/
+                LogError("Cannot allocate memory for received data");
+                indicate_open_complete_error_and_close(http_proxy_io_instance);
+            }
+            else
+            {
+                http_proxy_io_instance->receive_buffer = new_receive_buffer;
+                memcpy(http_proxy_io_instance->receive_buffer + http_proxy_io_instance->receive_buffer_size, buffer, size);
+                http_proxy_io_instance->receive_buffer_size += size;
+            }
+
+            if (http_proxy_io_instance->receive_buffer_size >= 4)
+            {
+                const char* request_end_ptr;
+
+                http_proxy_io_instance->receive_buffer[http_proxy_io_instance->receive_buffer_size] = 0;
+
+                /* Codes_SRS_HTTP_PROXY_IO_01_066: [ When a double new-line is detected the response shall be parsed in order to extract the status code. ]*/
+                if ((http_proxy_io_instance->receive_buffer_size >= 4) &&
+                    ((request_end_ptr = strstr((const char*)http_proxy_io_instance->receive_buffer, "\r\n\r\n")) != NULL))
+                {
+                    int status_code;
+
+                    /* This part should really be done with the HTTPAPI, but that has to be done as a separate step
+                    as the HTTPAPI has to expose somehow the underlying IO and currently this would be a too big of a change. */
+
+                    if (ParseHttpResponse((const char*)http_proxy_io_instance->receive_buffer, &status_code) != 0)
+                    {
+                        /* Codes_SRS_HTTP_PROXY_IO_01_068: [ If parsing the CONNECT response fails, the on_open_complete callback shall be triggered with IO_OPEN_ERROR, passing also the on_open_complete_context argument as context. ]*/
+                        LogError("Cannot decode HTTP response");
+                        indicate_open_complete_error_and_close(http_proxy_io_instance);
+                    }
+                    /* Codes_SRS_HTTP_PROXY_IO_01_069: [ Any successful (2xx) response to a CONNECT request indicates that the proxy has established a connection to the requested host and port, and has switched to tunneling the current connection to that server connection. ]*/
+                    /* Codes_SRS_HTTP_PROXY_IO_01_090: [ Any successful (2xx) response to a CONNECT request indicates that the proxy has established a connection to the requested host and port, and has switched to tunneling the current connection to that server connection. ]*/
+                    else if ((status_code < 200) || (status_code > 299))
+                    {
+                        /* Codes_SRS_HTTP_PROXY_IO_01_071: [ If the status code is not successful, the on_open_complete callback shall be triggered with IO_OPEN_ERROR, passing also the on_open_complete_context argument as context. ]*/
+                        LogError("Bad status (%d) received in CONNECT response", status_code);
+                        indicate_open_complete_error_and_close(http_proxy_io_instance);
+                    }
+                    else
+                    {
+                        size_t length_remaining = http_proxy_io_instance->receive_buffer + http_proxy_io_instance->receive_buffer_size - ((const unsigned char *)request_end_ptr + 4);
+
+                        /* Codes_SRS_HTTP_PROXY_IO_01_073: [ Once a success status code was parsed, the IO shall be OPEN. ]*/
+                        http_proxy_io_instance->http_proxy_io_state = HTTP_PROXY_IO_STATE_OPEN;
+                        /* Codes_SRS_HTTP_PROXY_IO_01_070: [ When a success status code is parsed, the on_open_complete callback shall be triggered with IO_OPEN_OK, passing also the on_open_complete_context argument as context. ]*/
+                        http_proxy_io_instance->on_io_open_complete(http_proxy_io_instance->on_io_open_complete_context, IO_OPEN_OK);
+
+                        if (length_remaining > 0)
+                        {
+                            /* Codes_SRS_HTTP_PROXY_IO_01_072: [ Any bytes that are extra (not consumed by the CONNECT response), shall be indicated as received by calling the on_bytes_received callback and passing the on_bytes_received_context as context argument. ]*/
+                            http_proxy_io_instance->on_bytes_received(http_proxy_io_instance->on_bytes_received_context, (const unsigned char*)request_end_ptr + 4, length_remaining);
+                        }
+                    }
+                }
+            }
+            break;
+        }
+        case HTTP_PROXY_IO_STATE_OPEN:
+            /* Codes_SRS_HTTP_PROXY_IO_01_074: [ If on_underlying_io_bytes_received is called while OPEN, all bytes shall be indicated as received by calling the on_bytes_received callback and passing the on_bytes_received_context as context argument. ]*/
+            http_proxy_io_instance->on_bytes_received(http_proxy_io_instance->on_bytes_received_context, buffer, size);
+            break;
+        }
+    }
+}
+
+static int http_proxy_io_open(CONCRETE_IO_HANDLE http_proxy_io, ON_IO_OPEN_COMPLETE on_io_open_complete, void* on_io_open_complete_context, ON_BYTES_RECEIVED on_bytes_received, void* on_bytes_received_context, ON_IO_ERROR on_io_error, void* on_io_error_context)
+{
+    int result;
+
+    /* Codes_SRS_HTTP_PROXY_IO_01_051: [ The arguments on_io_open_complete_context, on_bytes_received_context and on_io_error_context shall be allowed to be NULL. ]*/
+    /* Codes_SRS_HTTP_PROXY_IO_01_018: [ If any of the arguments http_proxy_io, on_io_open_complete, on_bytes_received or on_io_error are NULL then http_proxy_io_open shall return a non-zero value. ]*/
+    if ((http_proxy_io == NULL) ||
+        (on_io_open_complete == NULL) ||
+        (on_bytes_received == NULL) ||
+        (on_io_error == NULL))
+    {
+        LogError("Bad arguments: http_proxy_io = %p, on_io_open_complete = %p, on_bytes_received = %p, on_io_error_context = %p.",
+            http_proxy_io,
+            on_io_open_complete,
+            on_bytes_received,
+            on_io_error);
+        result = __LINE__;
+    }
+    else
+    {
+        HTTP_PROXY_IO_INSTANCE* http_proxy_io_instance = (HTTP_PROXY_IO_INSTANCE*)http_proxy_io;
+
+        if (http_proxy_io_instance->http_proxy_io_state != HTTP_PROXY_IO_STATE_CLOSED)
+        {
+            LogError("Invalid tlsio_state. Expected state is HTTP_PROXY_IO_STATE_CLOSED.");
+            result = __LINE__;
+        }
+        else
+        {
+            http_proxy_io_instance->on_bytes_received = on_bytes_received;
+            http_proxy_io_instance->on_bytes_received_context = on_bytes_received_context;
+
+            http_proxy_io_instance->on_io_error = on_io_error;
+            http_proxy_io_instance->on_io_error_context = on_io_error_context;
+
+            http_proxy_io_instance->on_io_open_complete = on_io_open_complete;
+            http_proxy_io_instance->on_io_open_complete_context = on_io_open_complete_context;
+
+            http_proxy_io_instance->http_proxy_io_state = HTTP_PROXY_IO_STATE_OPENING_UNDERLYING_IO;
+
+            /* Codes_SRS_HTTP_PROXY_IO_01_019: [ http_proxy_io_open shall open the underlying IO by calling xio_open on the underlying IO handle created in http_proxy_io_create, while passing to it the callbacks on_underlying_io_open_complete, on_underlying_io_bytes_received and on_underlying_io_error. ]*/
+            if (xio_open(http_proxy_io_instance->underlying_io, on_underlying_io_open_complete, http_proxy_io_instance, on_underlying_io_bytes_received, http_proxy_io_instance, on_underlying_io_error, http_proxy_io_instance) != 0)
+            {
+                /* Codes_SRS_HTTP_PROXY_IO_01_020: [ If xio_open fails, then http_proxy_io_open shall return a non-zero value. ]*/
+                http_proxy_io_instance->http_proxy_io_state = HTTP_PROXY_IO_STATE_CLOSED;
+                LogError("Cannot open the underlying IO.");
+                result = __LINE__;
+            }
+            else
+            {
+                /* Codes_SRS_HTTP_PROXY_IO_01_017: [ http_proxy_io_open shall open the HTTP proxy IO and on success it shall return 0. ]*/
+                result = 0;
+            }
+        }
+    }
+
+    return result;
+}
+
+static int http_proxy_io_close(CONCRETE_IO_HANDLE http_proxy_io, ON_IO_CLOSE_COMPLETE on_io_close_complete, void* on_io_close_complete_context)
+{
+    int result = 0;
+
+    /* Codes_SRS_HTTP_PROXY_IO_01_052: [ on_io_close_complete_context shall be allowed to be NULL. ]*/
+    /* Codes_SRS_HTTP_PROXY_IO_01_028: [ on_io_close_complete shall be allowed to be NULL. ]*/
+    if (http_proxy_io == NULL)
+    {
+        /* Codes_SRS_HTTP_PROXY_IO_01_023: [ If the argument http_proxy_io is NULL, http_proxy_io_close shall fail and return a non-zero value. ]*/
+        result = __LINE__;
+        LogError("NULL http_proxy_io.");
+    }
+    else
+    {
+        HTTP_PROXY_IO_INSTANCE* http_proxy_io_instance = (HTTP_PROXY_IO_INSTANCE*)http_proxy_io;
+
+        /* Codes_SRS_HTTP_PROXY_IO_01_027: [ If http_proxy_io_close is called when not open, http_proxy_io_close shall fail and return a non-zero value. ]*/
+        if ((http_proxy_io_instance->http_proxy_io_state == HTTP_PROXY_IO_STATE_CLOSED) ||
+            /* Codes_SRS_HTTP_PROXY_IO_01_054: [ http_proxy_io_close while OPENING shall fail and return a non-zero value. ]*/
+            (http_proxy_io_instance->http_proxy_io_state == HTTP_PROXY_IO_STATE_CLOSING))
+        {
+            result = __LINE__;
+            LogError("Invalid tlsio_state. Expected state is HTTP_PROXY_IO_STATE_OPEN.");
+        }
+        else if ((http_proxy_io_instance->http_proxy_io_state == HTTP_PROXY_IO_STATE_OPENING_UNDERLYING_IO) ||
+            (http_proxy_io_instance->http_proxy_io_state == HTTP_PROXY_IO_STATE_WAITING_FOR_CONNECT_RESPONSE))
+        {
+            /* Codes_SRS_HTTP_PROXY_IO_01_053: [ http_proxy_io_close while OPENING shall trigger the on_io_open_complete callback with IO_OPEN_CANCELLED. ]*/
+            http_proxy_io_instance->http_proxy_io_state = HTTP_PROXY_IO_STATE_CLOSED;
+            (void)xio_close(http_proxy_io_instance->underlying_io, NULL, NULL);
+            http_proxy_io_instance->on_io_open_complete(http_proxy_io_instance->on_io_open_complete_context, IO_OPEN_CANCELLED);
+
+            /* Codes_SRS_HTTP_PROXY_IO_01_022: [ http_proxy_io_close shall close the HTTP proxy IO and on success it shall return 0. ]*/
+            result = 0;
+        }
+        else
+        {
+            HTTP_PROXY_IO_STATE previous_state = http_proxy_io_instance->http_proxy_io_state;
+
+            http_proxy_io_instance->http_proxy_io_state = HTTP_PROXY_IO_STATE_CLOSING;
+
+            /* Codes_SRS_HTTP_PROXY_IO_01_026: [ The on_io_close_complete and on_io_close_complete_context arguments shall be saved for later use. ]*/
+            http_proxy_io_instance->on_io_close_complete = on_io_close_complete;
+            http_proxy_io_instance->on_io_close_complete_context = on_io_close_complete_context;
+
+            /* Codes_SRS_HTTP_PROXY_IO_01_024: [ http_proxy_io_close shall close the underlying IO by calling xio_close on the IO handle create in http_proxy_io_create, while passing to it the on_underlying_io_close_complete callback. ]*/
+            if (xio_close(http_proxy_io_instance->underlying_io, on_underlying_io_close_complete, http_proxy_io_instance) != 0)
+            {
+                /* Codes_SRS_HTTP_PROXY_IO_01_025: [ If xio_close fails, http_proxy_io_close shall fail and return a non-zero value. ]*/
+                result = __LINE__;
+                http_proxy_io_instance->http_proxy_io_state = previous_state;
+                LogError("Cannot close underlying IO.");
+            }
+            else
+            {
+                /* Codes_SRS_HTTP_PROXY_IO_01_022: [ http_proxy_io_close shall close the HTTP proxy IO and on success it shall return 0. ]*/
+                result = 0;
+            }
+        }
+    }
+
+    return result;
+}
+
+static int http_proxy_io_send(CONCRETE_IO_HANDLE http_proxy_io, const void* buffer, size_t size, ON_SEND_COMPLETE on_send_complete, void* on_send_complete_context)
+{
+    int result;
+
+    /* Codes_SRS_HTTP_PROXY_IO_01_032: [ on_send_complete shall be allowed to be NULL. ]*/
+    /* Codes_SRS_HTTP_PROXY_IO_01_030: [ If any of the arguments http_proxy_io or buffer is NULL, http_proxy_io_send shall fail and return a non-zero value. ]*/
+    if ((http_proxy_io == NULL) ||
+        (buffer == NULL) ||
+        /* Codes_SRS_HTTP_PROXY_IO_01_031: [ If size is 0, http_proxy_io_send shall fail and return a non-zero value. ]*/
+        (size == 0))
+    {
+        result = __LINE__;
+        LogError("Bad arguments: http_proxy_io = %p, buffer = %p.",
+            http_proxy_io, buffer);
+    }
+    else
+    {
+        HTTP_PROXY_IO_INSTANCE* http_proxy_io_instance = (HTTP_PROXY_IO_INSTANCE*)http_proxy_io;
+
+        /* Codes_SRS_HTTP_PROXY_IO_01_034: [ If http_proxy_io_send is called when the IO is not open, http_proxy_io_send shall fail and return a non-zero value. ]*/
+        /* Codes_SRS_HTTP_PROXY_IO_01_035: [ If the IO is in an error state (an error was reported through the on_io_error callback), http_proxy_io_send shall fail and return a non-zero value. ]*/
+        if (http_proxy_io_instance->http_proxy_io_state != HTTP_PROXY_IO_STATE_OPEN)
+        {
+            result = __LINE__;
+            LogError("Invalid HTTP proxy IO state. Expected state is HTTP_PROXY_IO_STATE_OPEN.");
+        }
+        else
+        {
+            /* Codes_SRS_HTTP_PROXY_IO_01_033: [ http_proxy_io_send shall send the bytes by calling xio_send on the underlying IO created in http_proxy_io_create and passing buffer and size as arguments. ]*/
+            if (xio_send(http_proxy_io_instance->underlying_io, buffer, size, on_send_complete, on_send_complete_context) != 0)
+            {
+                /* Codes_SRS_HTTP_PROXY_IO_01_055: [ If xio_send fails, http_proxy_io_send shall fail and return a non-zero value. ]*/
+                result = __LINE__;
+                LogError("Underlying xio_send failed.");
+            }
+            else
+            {
+                /* Codes_SRS_HTTP_PROXY_IO_01_029: [ http_proxy_io_send shall send the size bytes pointed to by buffer and on success it shall return 0. ]*/
+                result = 0;
+            }
+        }
+    }
+
+    return result;
+}
+
+static void http_proxy_io_dowork(CONCRETE_IO_HANDLE http_proxy_io)
+{
+    if (http_proxy_io == NULL)
+    {
+        /* Codes_SRS_HTTP_PROXY_IO_01_038: [ If the http_proxy_io argument is NULL, http_proxy_io_dowork shall do nothing. ]*/
+        LogError("NULL http_proxy_io.");
+    }
+    else
+    {
+        HTTP_PROXY_IO_INSTANCE* http_proxy_io_instance = (HTTP_PROXY_IO_INSTANCE*)http_proxy_io;
+
+        if (http_proxy_io_instance->http_proxy_io_state != HTTP_PROXY_IO_STATE_CLOSED)
+        {
+            /* Codes_SRS_HTTP_PROXY_IO_01_037: [ http_proxy_io_dowork shall call xio_dowork on the underlying IO created in http_proxy_io_create. ]*/
+            xio_dowork(http_proxy_io_instance->underlying_io);
+        }
+    }
+}
+
+static int http_proxy_io_set_option(CONCRETE_IO_HANDLE http_proxy_io, const char* option_name, const void* value)
+{
+    int result;
+
+    if ((http_proxy_io == NULL) || (option_name == NULL))
+    {
+        /* Codes_SRS_HTTP_PROXY_IO_01_040: [ If any of the arguments http_proxy_io or option_name is NULL, http_proxy_io_set_option shall return a non-zero value. ]*/
+        LogError("Bad arguments: http_proxy_io = %p, option_name = %p",
+            http_proxy_io, option_name);
+        result = MU_FAILURE;
+    }
+    else
+    {
+        HTTP_PROXY_IO_INSTANCE* http_proxy_io_instance = (HTTP_PROXY_IO_INSTANCE*)http_proxy_io;
+
+        /* Codes_SRS_HTTP_PROXY_IO_01_045: [ None. ]*/
+
+        if (strcmp(option_name, OPTION_UNDERLYING_IO_OPTIONS) == 0)
+        {
+            if (OptionHandler_FeedOptions((OPTIONHANDLER_HANDLE)value, (void*)http_proxy_io_instance->underlying_io) != OPTIONHANDLER_OK)
+            {
+                LogError("failed feeding options to underlying I/O instance");
+                result = MU_FAILURE;
+            }
+            else
+            {
+                result = 0;
+            }
+        }
+        /* Codes_SRS_HTTP_PROXY_IO_01_043: [ If the option_name argument indicates an option that is not handled by http_proxy_io_set_option, then xio_setoption shall be called on the underlying IO created in http_proxy_io_create, passing the option name and value to it. ]*/
+        /* Codes_SRS_HTTP_PROXY_IO_01_056: [ The value argument shall be allowed to be NULL. ]*/
+        else if (xio_setoption(http_proxy_io_instance->underlying_io, option_name, value) != 0)
+        {
+            /* Codes_SRS_HTTP_PROXY_IO_01_044: [ if xio_setoption fails, http_proxy_io_set_option shall return a non-zero value. ]*/
+            LogError("Unrecognized option %s", option_name);
+            result = MU_FAILURE;
+        }
+        else
+        {
+            /* Codes_SRS_HTTP_PROXY_IO_01_042: [ If the option was handled by http_proxy_io_set_option or the underlying IO, then http_proxy_io_set_option shall return 0. ]*/
+            result = 0;
+        }
+    }
+
+    return result;
+}
+
+/*this function will clone an option given by name and value*/
+static void* http_proxy_io_clone_option(const char* name, const void* value)
+{
+    void* result;
+    if (
+        (name == NULL) || (value == NULL)
+        )
+    {
+        LogError("invalid parameter detected: name=%p, value=%p", name, value);
+        result = NULL;
+    }
+    else
+    {
+        if (strcmp(name, OPTION_UNDERLYING_IO_OPTIONS) == 0)
+        {
+            result = (void*)value;
+        }
+        else
+        {
+            LogError("not handled option : %s", name);
+            result = NULL;
+        }
+    }
+
+    return result;
+}
+
+/*this function destroys an option previously created*/
+static void http_proxy_io_destroy_option(const char* name, const void* value)
+{
+    /*since all options for this layer are actually string copies., disposing of one is just calling free*/
+    if (
+        (name == NULL) || (value == NULL)
+        )
+    {
+        LogError("invalid parameter detected: const char* name=%p, const void* value=%p", name, value);
+    }
+    else
+    {
+        if (strcmp(name, OPTION_UNDERLYING_IO_OPTIONS) == 0)
+        {
+            OptionHandler_Destroy((OPTIONHANDLER_HANDLE)value);
+        }
+        else
+        {
+            LogError("not handled option : %s", name);
+        }
+    }
+}
+
+static OPTIONHANDLER_HANDLE http_proxy_io_retrieve_options(CONCRETE_IO_HANDLE http_proxy_io)
+{
+    OPTIONHANDLER_HANDLE result;
+
+    if (http_proxy_io == NULL)
+    {
+        /* Codes_SRS_HTTP_PROXY_IO_01_047: [ If the parameter http_proxy_io is NULL then http_proxy_io_retrieve_options shall fail and return NULL. ]*/
+        LogError("invalid parameter detected: CONCRETE_IO_HANDLE handle=%p", http_proxy_io);
+        result = NULL;
+    }
+    else
+    {
+        HTTP_PROXY_IO_INSTANCE* http_proxy_io_instance = (HTTP_PROXY_IO_INSTANCE*)http_proxy_io;
+
+        result = OptionHandler_Create(http_proxy_io_clone_option, http_proxy_io_destroy_option, http_proxy_io_set_option);
+
+        if (result == NULL)
+        {
+            LogError("OptionHandler_Create failed");
+        }
+        else
+        {
+            OPTIONHANDLER_HANDLE underlying_io_options;
+
+            /* Codes_SRS_HTTP_PROXY_IO_01_046: [ http_proxy_io_retrieve_options shall return an OPTIONHANDLER_HANDLE obtained by calling xio_retrieveoptions on the underlying IO created in http_proxy_io_create. ]*/
+            if ((underlying_io_options = xio_retrieveoptions(http_proxy_io_instance->underlying_io)) == NULL ||
+                OptionHandler_AddOption(result, OPTION_UNDERLYING_IO_OPTIONS, underlying_io_options) != OPTIONHANDLER_OK)
+            {
+                /* Codes_SRS_HTTP_PROXY_IO_01_048: [ If xio_retrieveoptions fails, http_proxy_io_retrieve_options shall return NULL. ]*/
+                LogError("unable to save underlying_io options");
+                OptionHandler_Destroy(underlying_io_options);
+                OptionHandler_Destroy(result);
+                result = NULL;
+            }
+            else
+            {
+                // All is fine.
+            }
+        }
+    }
+    return result;
+}
+
+static const IO_INTERFACE_DESCRIPTION http_proxy_io_interface_description =
+{
+    http_proxy_io_retrieve_options,
+    http_proxy_io_create,
+    http_proxy_io_destroy,
+    http_proxy_io_open,
+    http_proxy_io_close,
+    http_proxy_io_send,
+    http_proxy_io_dowork,
+    http_proxy_io_set_option
+};
+
+const IO_INTERFACE_DESCRIPTION* http_proxy_io_get_interface_description(void)
+{
+    /* Codes_SRS_HTTP_PROXY_IO_01_049: [ http_proxy_io_get_interface_description shall return a pointer to an IO_INTERFACE_DESCRIPTION structure that contains pointers to the functions: http_proxy_io_retrieve_options, http_proxy_io_retrieve_create, http_proxy_io_destroy, http_proxy_io_open, http_proxy_io_close, http_proxy_io_send and http_proxy_io_dowork. ]*/
+    return &http_proxy_io_interface_description;
+}
Index: azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/src/httpapiex.c
===================================================================
--- azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/src/httpapiex.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/src/httpapiex.c	(revision 457)
@@ -0,0 +1,712 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+#include <stdbool.h>
+#include <stdlib.h>
+#include "azure_macro_utils/macro_utils.h"
+#include "azure_c_shared_utility/gballoc.h"
+#include "azure_c_shared_utility/httpapiex.h"
+#include "azure_c_shared_utility/optimize_size.h"
+#include "azure_c_shared_utility/xlogging.h"
+#include "azure_c_shared_utility/strings.h"
+#include "azure_c_shared_utility/crt_abstractions.h"
+#include "azure_c_shared_utility/vector.h"
+
+typedef struct HTTPAPIEX_SAVED_OPTION_TAG
+{
+    const char* optionName;
+    const void* value;
+}HTTPAPIEX_SAVED_OPTION;
+
+typedef struct HTTPAPIEX_HANDLE_DATA_TAG
+{
+    STRING_HANDLE hostName;
+    int k;
+    HTTP_HANDLE httpHandle;
+    VECTOR_HANDLE savedOptions;
+}HTTPAPIEX_HANDLE_DATA;
+
+MU_DEFINE_ENUM_STRINGS(HTTPAPIEX_RESULT, HTTPAPIEX_RESULT_VALUES);
+
+#define LOG_HTTAPIEX_ERROR() LogError("error code = %" PRI_MU_ENUM "", MU_ENUM_VALUE(HTTPAPIEX_RESULT, result))
+
+static int useGlobalInitialization = 0;
+
+HTTPAPIEX_RESULT HTTPAPIEX_Init(void)
+{
+    HTTPAPIEX_RESULT result;
+
+    /*Codes_SRS_HTTPAPIEX_21_045: [If HTTPAPIEX_Init is calling more than once, it shall initialize the HTTP by calling HTTAPI_Init only once, and return success for all calls.] */
+    if (useGlobalInitialization == 0)
+    {
+        /*Codes_SRS_HTTPAPIEX_21_044: [HTTPAPIEX_Init shall initialize the HTTP by calling HTTAPI_Init.] */
+        if (HTTPAPI_Init() == HTTPAPI_OK)
+        {
+            useGlobalInitialization++;
+            result = HTTPAPIEX_OK;
+        }
+        else
+        {
+            /*Codes_SRS_HTTPAPIEX_21_046: [If HTTAPI_Init, HTTPAPIEX_Init shall return HTTPAPIEX_ERROR.] */
+            result = HTTPAPIEX_ERROR;
+        }
+    }
+    else
+    {
+        useGlobalInitialization++;
+        result = HTTPAPIEX_OK;
+    }
+
+    return result;
+}
+
+void HTTPAPIEX_Deinit(void)
+{
+    /*Codes_SRS_HTTPAPIEX_21_047: [HTTPAPIEX_Deinit shall de-initialize the HTTP by calling HTTAPI_Deinit.] */
+    useGlobalInitialization--;
+    if (useGlobalInitialization == 0)
+    {
+        HTTPAPI_Deinit();
+    }
+}
+
+HTTPAPIEX_HANDLE HTTPAPIEX_Create(const char* hostName)
+{
+    HTTPAPIEX_HANDLE result;
+    /*Codes_SRS_HTTPAPIEX_02_001: [If parameter hostName is NULL then HTTPAPIEX_Create shall return NULL.]*/
+    if (hostName == NULL)
+    {
+        LogError("invalid (NULL) parameter");
+        result = NULL;
+    }
+    else
+    {
+        /*Codes_SRS_HTTPAPIEX_02_005: [If creating the handle fails for any reason, then HTTAPIEX_Create shall return NULL.] */
+        HTTPAPIEX_HANDLE_DATA* handleData = (HTTPAPIEX_HANDLE_DATA*)calloc(1, sizeof(HTTPAPIEX_HANDLE_DATA));
+        if (handleData == NULL)
+        {
+            LogError("malloc failed.");
+            result = NULL;
+        }
+        else
+        {
+            /*Codes_SRS_HTTPAPIEX_02_002: [Parameter hostName shall be saved.]*/
+            handleData->hostName = STRING_construct(hostName);
+            if (handleData->hostName == NULL)
+            {
+                free(handleData);
+                LogError("unable to STRING_construct");
+                result = NULL;
+            }
+            else
+            {
+                /*Codes_SRS_HTTPAPIEX_02_004: [Otherwise, HTTPAPIEX_Create shall return a HTTAPIEX_HANDLE suitable for further calls to the module.] */
+                handleData->savedOptions = VECTOR_create(sizeof(HTTPAPIEX_SAVED_OPTION));
+                if (handleData->savedOptions == NULL)
+                {
+                    STRING_delete(handleData->hostName);
+                    free(handleData);
+                    result = NULL;
+                }
+                else
+                {
+                    handleData->k = -1;
+                    handleData->httpHandle = NULL;
+                    result = handleData;
+                }
+            }
+        }
+    }
+    return result;
+}
+
+/*this function builds the default request http headers if none are specified*/
+/*returns 0 if no error*/
+/*any other code is error*/
+static int buildRequestHttpHeadersHandle(HTTPAPIEX_HANDLE_DATA *handleData, BUFFER_HANDLE requestContent, HTTP_HEADERS_HANDLE originalRequestHttpHeadersHandle, bool* isOriginalRequestHttpHeadersHandle, HTTP_HEADERS_HANDLE* toBeUsedRequestHttpHeadersHandle)
+{
+    int result;
+
+
+    if (originalRequestHttpHeadersHandle != NULL)
+    {
+        *toBeUsedRequestHttpHeadersHandle = originalRequestHttpHeadersHandle;
+        *isOriginalRequestHttpHeadersHandle = true;
+
+    }
+    else
+    {
+        /*Codes_SRS_HTTPAPIEX_02_009: [If parameter requestHttpHeadersHandle is NULL then HTTPAPIEX_ExecuteRequest shall allocate a temporary internal instance of HTTPHEADERS, shall add to that instance the following headers
+        Host:{hostname} - as it was indicated by the call to HTTPAPIEX_Create API call
+        Content-Length:the size of the requestContent parameter, and use this instance to all the subsequent calls to HTTPAPI_ExecuteRequest as parameter httpHeadersHandle.]
+        */
+        *isOriginalRequestHttpHeadersHandle = false;
+        *toBeUsedRequestHttpHeadersHandle = HTTPHeaders_Alloc();
+    }
+
+    if (*toBeUsedRequestHttpHeadersHandle == NULL)
+    {
+        result = MU_FAILURE;
+        LogError("unable to HTTPHeaders_Alloc");
+    }
+    else
+    {
+        char temp[22] = { 0 };
+        (void)size_tToString(temp, 22, BUFFER_length(requestContent)); /*cannot fail, MAX_uint64 has 19 digits*/
+        /*Codes_SRS_HTTPAPIEX_02_011: [If parameter requestHttpHeadersHandle is not NULL then HTTPAPIEX_ExecuteRequest shall create or update the following headers of the request:
+        Host:{hostname}
+        Content-Length:the size of the requestContent parameter, and shall use the so constructed HTTPHEADERS object to all calls to HTTPAPI_ExecuteRequest as parameter httpHeadersHandle.]
+        */
+        /*Codes_SRS_HTTPAPIEX_02_009: [If parameter requestHttpHeadersHandle is NULL then HTTPAPIEX_ExecuteRequest shall allocate a temporary internal instance of HTTPHEADERS, shall add to that instance the following headers
+        Host:{hostname} - as it was indicated by the call to HTTPAPIEX_Create API call
+        Content-Length:the size of the requestContent parameter, and use this instance to all the subsequent calls to HTTPAPI_ExecuteRequest as parameter httpHeadersHandle.]
+        */
+        if (!(
+            (HTTPHeaders_ReplaceHeaderNameValuePair(*toBeUsedRequestHttpHeadersHandle, "Host", STRING_c_str(handleData->hostName)) == HTTP_HEADERS_OK) &&
+            (HTTPHeaders_ReplaceHeaderNameValuePair(*toBeUsedRequestHttpHeadersHandle, "Content-Length", temp) == HTTP_HEADERS_OK)
+            ))
+        {
+            if (! *isOriginalRequestHttpHeadersHandle)
+            {
+                HTTPHeaders_Free(*toBeUsedRequestHttpHeadersHandle);
+            }
+            *toBeUsedRequestHttpHeadersHandle = NULL;
+            result = MU_FAILURE;
+        }
+        else
+        {
+            result = 0;
+        }
+    }
+    return result;
+}
+
+static int buildResponseHttpHeadersHandle(HTTP_HEADERS_HANDLE originalResponsetHttpHeadersHandle, bool* isOriginalResponseHttpHeadersHandle, HTTP_HEADERS_HANDLE* toBeUsedResponsetHttpHeadersHandle)
+{
+    int result;
+    if (originalResponsetHttpHeadersHandle == NULL)
+    {
+        if ((*toBeUsedResponsetHttpHeadersHandle = HTTPHeaders_Alloc()) == NULL)
+        {
+            result = MU_FAILURE;
+        }
+        else
+        {
+            *isOriginalResponseHttpHeadersHandle = false;
+            result = 0;
+        }
+    }
+    else
+    {
+        *isOriginalResponseHttpHeadersHandle = true;
+        *toBeUsedResponsetHttpHeadersHandle = originalResponsetHttpHeadersHandle;
+        result = 0;
+    }
+    return result;
+}
+
+
+static int buildBufferIfNotExist(BUFFER_HANDLE originalRequestContent, bool* isOriginalRequestContent, BUFFER_HANDLE* toBeUsedRequestContent)
+{
+    int result;
+    if (originalRequestContent == NULL)
+    {
+        *toBeUsedRequestContent = BUFFER_new();
+        if (*toBeUsedRequestContent == NULL)
+        {
+            result = MU_FAILURE;
+        }
+        else
+        {
+            *isOriginalRequestContent = false;
+            result = 0;
+        }
+    }
+    else
+    {
+        *isOriginalRequestContent = true;
+        *toBeUsedRequestContent = originalRequestContent;
+        result = 0;
+    }
+    return result;
+}
+
+static unsigned int dummyStatusCode;
+
+static int buildAllRequests(HTTPAPIEX_HANDLE_DATA* handle, HTTPAPI_REQUEST_TYPE requestType, const char* relativePath,
+    HTTP_HEADERS_HANDLE requestHttpHeadersHandle, BUFFER_HANDLE requestContent, unsigned int* statusCode,
+    HTTP_HEADERS_HANDLE responseHttpHeadersHandle, BUFFER_HANDLE responseContent,
+
+    const char** toBeUsedRelativePath,
+    HTTP_HEADERS_HANDLE *toBeUsedRequestHttpHeadersHandle, bool *isOriginalRequestHttpHeadersHandle,
+    BUFFER_HANDLE *toBeUsedRequestContent, bool *isOriginalRequestContent,
+    unsigned int** toBeUsedStatusCode,
+    HTTP_HEADERS_HANDLE *toBeUsedResponseHttpHeadersHandle, bool *isOriginalResponseHttpHeadersHandle,
+    BUFFER_HANDLE *toBeUsedResponseContent, bool *isOriginalResponseContent)
+{
+    int result;
+    (void)requestType;
+    /*Codes_SRS_HTTPAPIEX_02_013: [If requestContent is NULL then HTTPAPIEX_ExecuteRequest shall behave as if a buffer of zero size would have been used, that is, it shall call HTTPAPI_ExecuteRequest with parameter content = NULL and contentLength = 0.]*/
+    /*Codes_SRS_HTTPAPIEX_02_014: [If requestContent is not NULL then its content and its size shall be used for parameters content and contentLength of HTTPAPI_ExecuteRequest.] */
+    if (buildBufferIfNotExist(requestContent, isOriginalRequestContent, toBeUsedRequestContent) != 0)
+    {
+        LogError("unable to build the request content");
+        result = MU_FAILURE;
+    }
+    else
+    {
+        if (buildRequestHttpHeadersHandle(handle, *toBeUsedRequestContent, requestHttpHeadersHandle, isOriginalRequestHttpHeadersHandle, toBeUsedRequestHttpHeadersHandle) != 0)
+        {
+            /*Codes_SRS_HTTPAPIEX_02_010: [If any of the operations in SRS_HTTAPIEX_02_009 fails, then HTTPAPIEX_ExecuteRequest shall return HTTPAPIEX_ERROR.] */
+            if (*isOriginalRequestContent == false)
+            {
+                BUFFER_delete(*toBeUsedRequestContent);
+            }
+            LogError("unable to build the request http headers handle");
+            result = MU_FAILURE;
+        }
+        else
+        {
+            /*Codes_SRS_HTTPAPIEX_02_008: [If parameter relativePath is NULL then HTTPAPIEX_INVALID_ARG shall not assume a relative path - that is, it will assume an empty path ("").] */
+            if (relativePath == NULL)
+            {
+                *toBeUsedRelativePath = "";
+            }
+            else
+            {
+                *toBeUsedRelativePath = relativePath;
+            }
+
+            /*Codes_SRS_HTTPAPIEX_02_015: [If statusCode is NULL then HTTPAPIEX_ExecuteRequest shall not write in statusCode the HTTP status code, and it will use a temporary internal int for parameter statusCode to the calls of HTTPAPI_ExecuteRequest.] */
+            if (statusCode == NULL)
+            {
+                /*Codes_SRS_HTTPAPIEX_02_016: [If statusCode is not NULL then If statusCode is NULL then HTTPAPIEX_ExecuteRequest shall use it for parameter statusCode to the calls of HTTPAPI_ExecuteRequest.] */
+                *toBeUsedStatusCode = &dummyStatusCode;
+            }
+            else
+            {
+                *toBeUsedStatusCode = statusCode;
+            }
+
+            /*Codes_SRS_HTTPAPIEX_02_017: [If responseHeaders handle is NULL then HTTPAPIEX_ExecuteRequest shall create a temporary internal instance of HTTPHEADERS object and use that for responseHeaders parameter of HTTPAPI_ExecuteRequest call.] */
+            /*Codes_SRS_HTTPAPIEX_02_019: [If responseHeaders is not NULL, then then HTTPAPIEX_ExecuteRequest shall use that object as parameter responseHeaders of HTTPAPI_ExecuteRequest call.] */
+            if (buildResponseHttpHeadersHandle(responseHttpHeadersHandle, isOriginalResponseHttpHeadersHandle, toBeUsedResponseHttpHeadersHandle) != 0)
+            {
+                /*Codes_SRS_HTTPAPIEX_02_018: [If creating the temporary http headers in SRS_HTTPAPIEX_02_017 fails then HTTPAPIEX_ExecuteRequest shall return HTTPAPIEX_ERROR.] */
+                if (*isOriginalRequestContent == false)
+                {
+                    BUFFER_delete(*toBeUsedRequestContent);
+                }
+                if (*isOriginalRequestHttpHeadersHandle == false)
+                {
+                    HTTPHeaders_Free(*toBeUsedRequestHttpHeadersHandle);
+                }
+                LogError("unable to build response content");
+                result = MU_FAILURE;
+            }
+            else
+            {
+                /*Codes_SRS_HTTPAPIEX_02_020: [If responseContent is NULL then HTTPAPIEX_ExecuteRequest shall create a temporary internal BUFFER object and use that as parameter responseContent of HTTPAPI_ExecuteRequest call.] */
+                /*Codes_SRS_HTTPAPIEX_02_022: [If responseContent is not NULL then HTTPAPIEX_ExecuteRequest use that as parameter responseContent of HTTPAPI_ExecuteRequest call.] */
+                if (buildBufferIfNotExist(responseContent, isOriginalResponseContent, toBeUsedResponseContent) != 0)
+                {
+                    /*Codes_SRS_HTTPAPIEX_02_021: [If creating the BUFFER_HANDLE in SRS_HTTPAPIEX_02_020 fails, then HTTPAPIEX_ExecuteRequest shall return HTTPAPIEX_ERROR.] */
+                    if (*isOriginalRequestContent == false)
+                    {
+                        BUFFER_delete(*toBeUsedRequestContent);
+                    }
+                    if (*isOriginalRequestHttpHeadersHandle == false)
+                    {
+                        HTTPHeaders_Free(*toBeUsedRequestHttpHeadersHandle);
+                    }
+                    if (*isOriginalResponseHttpHeadersHandle == false)
+                    {
+                        HTTPHeaders_Free(*toBeUsedResponseHttpHeadersHandle);
+                    }
+                    LogError("unable to build response content");
+                    result = MU_FAILURE;
+                }
+                else
+                {
+                    result = 0;
+                }
+            }
+        }
+    }
+    return result;
+}
+
+HTTPAPIEX_RESULT HTTPAPIEX_ExecuteRequest(HTTPAPIEX_HANDLE handle, HTTPAPI_REQUEST_TYPE requestType, const char* relativePath,
+    HTTP_HEADERS_HANDLE requestHttpHeadersHandle, BUFFER_HANDLE requestContent, unsigned int* statusCode,
+    HTTP_HEADERS_HANDLE responseHttpHeadersHandle, BUFFER_HANDLE responseContent)
+{
+    HTTPAPIEX_RESULT result;
+    /*Codes_SRS_HTTPAPIEX_02_006: [If parameter handle is NULL then HTTPAPIEX_ExecuteRequest shall fail and return HTTPAPIEX_INVALID_ARG.]*/
+    if (handle == NULL)
+    {
+        result = HTTPAPIEX_INVALID_ARG;
+        LOG_HTTAPIEX_ERROR();
+    }
+    else
+    {
+        /*Codes_SRS_HTTPAPIEX_02_007: [If parameter requestType does not indicate a valid request, HTTPAPIEX_ExecuteRequest shall fail and return HTTPAPIEX_INVALID_ARG.] */
+        if (requestType >= MU_COUNT_ARG(HTTPAPI_REQUEST_TYPE_VALUES))
+        {
+            result = HTTPAPIEX_INVALID_ARG;
+            LOG_HTTAPIEX_ERROR();
+        }
+        else
+        {
+            HTTPAPIEX_HANDLE_DATA *handleData = (HTTPAPIEX_HANDLE_DATA *)handle;
+
+            /*call to buildAll*/
+            const char* toBeUsedRelativePath;
+            HTTP_HEADERS_HANDLE toBeUsedRequestHttpHeadersHandle; bool isOriginalRequestHttpHeadersHandle;
+            BUFFER_HANDLE toBeUsedRequestContent; bool isOriginalRequestContent;
+            unsigned int* toBeUsedStatusCode;
+            HTTP_HEADERS_HANDLE toBeUsedResponseHttpHeadersHandle; bool isOriginalResponseHttpHeadersHandle;
+            BUFFER_HANDLE toBeUsedResponseContent;  bool isOriginalResponseContent;
+
+            if (buildAllRequests(handleData, requestType, relativePath, requestHttpHeadersHandle, requestContent, statusCode, responseHttpHeadersHandle, responseContent,
+                &toBeUsedRelativePath,
+                &toBeUsedRequestHttpHeadersHandle, &isOriginalRequestHttpHeadersHandle,
+                &toBeUsedRequestContent, &isOriginalRequestContent,
+                &toBeUsedStatusCode,
+                &toBeUsedResponseHttpHeadersHandle, &isOriginalResponseHttpHeadersHandle,
+                &toBeUsedResponseContent, &isOriginalResponseContent) != 0)
+            {
+                result = HTTPAPIEX_ERROR;
+                LOG_HTTAPIEX_ERROR();
+            }
+            else
+            {
+
+                /*Codes_SRS_HTTPAPIEX_02_023: [HTTPAPIEX_ExecuteRequest shall try to execute the HTTP call by ensuring the following API call sequence is respected:]*/
+                /*Codes_SRS_HTTPAPIEX_02_024: [If any point in the sequence fails, HTTPAPIEX_ExecuteRequest shall attempt to recover by going back to the previous step and retrying that step.]*/
+                /*Codes_SRS_HTTPAPIEX_02_025: [If the first step fails, then the sequence fails.]*/
+                /*Codes_SRS_HTTPAPIEX_02_026: [A step shall be retried at most once.]*/
+                /*Codes_SRS_HTTPAPIEX_02_027: [If a step has been retried then all subsequent steps shall be retried too.]*/
+                bool st[3] = { false, false, false }; /*the three levels of possible failure in resilient send: HTTAPI_Init, HTTPAPI_CreateConnection, HTTPAPI_ExecuteRequest*/
+                if (handleData->k == -1)
+                {
+                    handleData->k = 0;
+                }
+
+                do
+                {
+                    bool goOn;
+
+                    if (handleData->k > 2)
+                    {
+                        /* error */
+                        break;
+                    }
+
+                    if (st[handleData->k] == true) /*already been tried*/
+                    {
+                        goOn = false;
+                    }
+                    else
+                    {
+                        switch (handleData->k)
+                        {
+                        case 0:
+                        {
+                            if (useGlobalInitialization > 0)
+                            {
+                                /*Codes_SRS_HTTPAPIEX_21_048: [If HTTPAPIEX_Init was called, HTTPAPI_ExecuteRequest shall not call HTTPAPI_Init.] */
+                                goOn = true;
+                            }
+                            else if (HTTPAPI_Init() != HTTPAPI_OK)
+                            {
+                                goOn = false;
+                            }
+                            else
+                            {
+                                goOn = true;
+                            }
+                            break;
+                        }
+                        case 1:
+                        {
+                            if ((handleData->httpHandle = HTTPAPI_CreateConnection(STRING_c_str(handleData->hostName))) == NULL)
+                            {
+                                goOn = false;
+                            }
+                            else
+                            {
+                                size_t i;
+                                size_t vectorSize = VECTOR_size(handleData->savedOptions);
+                                for (i = 0; i < vectorSize; i++)
+                                {
+                                    /*Codes_SRS_HTTPAPIEX_02_035: [HTTPAPIEX_ExecuteRequest shall pass all the saved options (see HTTPAPIEX_SetOption) to the newly create HTTPAPI_HANDLE in step 2 by calling HTTPAPI_SetOption.]*/
+                                    /*Codes_SRS_HTTPAPIEX_02_036: [If setting the option fails, then the failure shall be ignored.] */
+                                    HTTPAPIEX_SAVED_OPTION* option = (HTTPAPIEX_SAVED_OPTION*)VECTOR_element(handleData->savedOptions, i);
+                                    if (HTTPAPI_SetOption(handleData->httpHandle, option->optionName, option->value) != HTTPAPI_OK)
+                                    {
+                                        LogError("HTTPAPI_SetOption failed when called for option %s", option->optionName);
+                                    }
+                                }
+                                goOn = true;
+                            }
+                            break;
+                        }
+                        case 2:
+                        {
+                            size_t length = BUFFER_length(toBeUsedRequestContent);
+                            unsigned char* buffer = BUFFER_u_char(toBeUsedRequestContent);
+                            if (HTTPAPI_ExecuteRequest(handleData->httpHandle, requestType, toBeUsedRelativePath, toBeUsedRequestHttpHeadersHandle, buffer, length, toBeUsedStatusCode, toBeUsedResponseHttpHeadersHandle, toBeUsedResponseContent) != HTTPAPI_OK)
+                            {
+                                goOn = false;
+                            }
+                            else
+                            {
+                                goOn = true;
+                            }
+                            break;
+                        }
+                        default:
+                        {
+                            /*serious error*/
+                            goOn = false;
+                            break;
+                        }
+                        }
+                    }
+
+                    if (goOn)
+                    {
+                        if (handleData->k == 2)
+                        {
+                            /*Codes_SRS_HTTPAPIEX_02_028: [HTTPAPIEX_ExecuteRequest shall return HTTPAPIEX_OK when a call to HTTPAPI_ExecuteRequest has been completed successfully.]*/
+                            result = HTTPAPIEX_OK;
+                            goto out;
+                        }
+                        else
+                        {
+                            st[handleData->k] = true;
+                            handleData->k++;
+                            st[handleData->k] = false;
+                        }
+                    }
+                    else
+                    {
+                        st[handleData->k] = false;
+                        handleData->k--;
+                        switch (handleData->k)
+                        {
+                        case 0:
+                        {
+                            /*Codes_SRS_HTTPAPIEX_21_049: [If HTTPAPIEX_Init was called, HTTPAPI_ExecuteRequest shall not call HTTPAPI_Deinit.] */
+                            if (useGlobalInitialization == 0)
+                            {
+                                HTTPAPI_Deinit();
+                            }
+                            break;
+                        }
+                        case 1:
+                        {
+                            HTTPAPI_CloseConnection(handleData->httpHandle);
+                            handleData->httpHandle = NULL;
+                            break;
+                        }
+                        case 2:
+                        {
+                            break;
+                        }
+                        default:
+                        {
+                            break;
+                        }
+                        }
+                    }
+                } while (handleData->k >= 0);
+                /*Codes_SRS_HTTPAPIEX_02_029: [Otherwise, HTTAPIEX_ExecuteRequest shall return HTTPAPIEX_RECOVERYFAILED.] */
+                result = HTTPAPIEX_RECOVERYFAILED;
+                LogError("unable to recover sending to a working state");
+            out:;
+                /*in all cases, unbuild the temporaries*/
+                if (isOriginalRequestContent == false)
+                {
+                    BUFFER_delete(toBeUsedRequestContent);
+                }
+                if (isOriginalRequestHttpHeadersHandle == false)
+                {
+                    HTTPHeaders_Free(toBeUsedRequestHttpHeadersHandle);
+                }
+                if (isOriginalResponseContent == false)
+                {
+                    BUFFER_delete(toBeUsedResponseContent);
+                }
+                if (isOriginalResponseHttpHeadersHandle == false)
+                {
+                    HTTPHeaders_Free(toBeUsedResponseHttpHeadersHandle);
+                }
+            }
+        }
+    }
+    return result;
+}
+
+
+void HTTPAPIEX_Destroy(HTTPAPIEX_HANDLE handle)
+{
+    if (handle != NULL)
+    {
+        /*Codes_SRS_HTTPAPIEX_02_042: [HTTPAPIEX_Destroy shall free all the resources used by HTTAPIEX_HANDLE.]*/
+        size_t i;
+        size_t vectorSize;
+        HTTPAPIEX_HANDLE_DATA* handleData = (HTTPAPIEX_HANDLE_DATA*)handle;
+
+        if (handleData->k == 2)
+        {
+            HTTPAPI_CloseConnection(handleData->httpHandle);
+            /*Codes_SRS_HTTPAPIEX_21_050: [If HTTPAPIEX_Init was called, HTTPAPI_Destroy shall not call HTTPAPI_Deinit.] */
+            if (useGlobalInitialization == 0)
+            {
+                HTTPAPI_Deinit();
+            }
+        }
+        STRING_delete(handleData->hostName);
+
+        vectorSize = VECTOR_size(handleData->savedOptions);
+        for (i = 0; i < vectorSize; i++)
+        {
+            HTTPAPIEX_SAVED_OPTION* savedOption = (HTTPAPIEX_SAVED_OPTION*)VECTOR_element(handleData->savedOptions, i);
+            free((void*)savedOption->optionName);
+            free((void*)savedOption->value);
+        }
+        VECTOR_destroy(handleData->savedOptions);
+
+        free(handle);
+    }
+    else
+    {
+        /*Codes_SRS_HTTPAPIEX_02_043: [If parameter handle is NULL then HTTPAPIEX_Destroy shall take no action.] */
+    }
+}
+
+static bool sameName(const void* element, const void* value)
+{
+    return (strcmp(((HTTPAPIEX_SAVED_OPTION*)element)->optionName, (const char*)value) == 0) ? true : false;
+}
+
+/*return 0 on success, any other value is error*/
+/*obs: value is already cloned at the time of calling this function */
+static int createOrUpdateOption(HTTPAPIEX_HANDLE_DATA* handleData, const char* optionName, const void* value)
+{
+    /*this function is called after the option value has been saved (cloned)*/
+    int result;
+
+    /*decide bwtween update or create*/
+    HTTPAPIEX_SAVED_OPTION* whereIsIt = (HTTPAPIEX_SAVED_OPTION*)VECTOR_find_if(handleData->savedOptions, sameName, optionName);
+    if (whereIsIt != NULL)
+    {
+        free((void*)(whereIsIt->value));
+        whereIsIt->value = value;
+        result = 0;
+    }
+    else
+    {
+        HTTPAPIEX_SAVED_OPTION newOption;
+        if (mallocAndStrcpy_s((char**)&(newOption.optionName), optionName) != 0)
+        {
+            free((void*)value);
+            result = MU_FAILURE;
+        }
+        else
+        {
+            newOption.value = value;
+            if (VECTOR_push_back(handleData->savedOptions, &newOption, 1) != 0)
+            {
+                LogError("unable to VECTOR_push_back");
+                free((void*)newOption.optionName);
+                free((void*)value);
+                result = MU_FAILURE;
+            }
+            else
+            {
+                result = 0;
+            }
+        }
+    }
+
+    return result;
+}
+
+HTTPAPIEX_RESULT HTTPAPIEX_SetOption(HTTPAPIEX_HANDLE handle, const char* optionName, const void* value)
+{
+    HTTPAPIEX_RESULT result;
+    /*Codes_SRS_HTTPAPIEX_02_032: [If parameter handle is NULL then HTTPAPIEX_SetOption shall return HTTPAPIEX_INVALID_ARG.] */
+    /*Codes_SRS_HTTPAPIEX_02_033: [If parameter optionName is NULL then HTTPAPIEX_SetOption shall return HTTPAPIEX_INVALID_ARG.] */
+    /*Codes_SRS_HTTPAPIEX_02_034: [If parameter value is NULL then HTTPAPIEX_SetOption shall return HTTPAPIEX_INVALID_ARG.] */
+    if (
+        (handle == NULL) ||
+        (optionName == NULL) ||
+        (value == NULL)
+        )
+    {
+        result = HTTPAPIEX_INVALID_ARG;
+        LOG_HTTAPIEX_ERROR();
+    }
+    else
+    {
+        const void* savedOption;
+        HTTPAPI_RESULT saveOptionResult;
+
+        /*Codes_SRS_HTTPAPIEX_02_037: [HTTPAPIEX_SetOption shall attempt to save the value of the option by calling HTTPAPI_CloneOption passing optionName and value, irrespective of the existence of a HTTPAPI_HANDLE] */
+        saveOptionResult = HTTPAPI_CloneOption(optionName, value, &savedOption);
+
+        if(saveOptionResult == HTTPAPI_INVALID_ARG)
+        {
+            /*Codes_SRS_HTTPAPIEX_02_038: [If HTTPAPI_CloneOption returns HTTPAPI_INVALID_ARG then HTTPAPIEX shall return HTTPAPIEX_INVALID_ARG.] */
+            result = HTTPAPIEX_INVALID_ARG;
+            LOG_HTTAPIEX_ERROR();
+        }
+        else if (saveOptionResult != HTTPAPI_OK)
+        {
+            /*Codes_SRS_HTTPAPIEX_02_040: [For all other return values of HTTPAPI_SetOption, HTTPIAPIEX_SetOption shall return HTTPAPIEX_ERROR.] */
+            result = HTTPAPIEX_ERROR;
+            LOG_HTTAPIEX_ERROR();
+        }
+        else
+        {
+            HTTPAPIEX_HANDLE_DATA* handleData = (HTTPAPIEX_HANDLE_DATA*)handle;
+            /*Codes_SRS_HTTPAPIEX_02_039: [If HTTPAPI_CloneOption returns HTTPAPI_OK then HTTPAPIEX_SetOption shall create or update the pair optionName/value.]*/
+            if (createOrUpdateOption(handleData, optionName, savedOption) != 0)
+            {
+                /*Codes_SRS_HTTPAPIEX_02_041: [If creating or updating the pair optionName/value fails then shall return HTTPAPIEX_ERROR.] */
+                result = HTTPAPIEX_ERROR;
+                LOG_HTTAPIEX_ERROR();
+
+            }
+            else
+            {
+                /*Codes_SRS_HTTPAPIEX_02_031: [If HTTPAPI_HANDLE exists then HTTPAPIEX_SetOption shall call HTTPAPI_SetOption passing the same optionName and value and shall return a value conforming to the below table:] */
+                if (handleData->httpHandle != NULL)
+                {
+                    HTTPAPI_RESULT HTTPAPI_result = HTTPAPI_SetOption(handleData->httpHandle, optionName, value);
+                    if (HTTPAPI_result == HTTPAPI_OK)
+                    {
+                        result = HTTPAPIEX_OK;
+                    }
+                    else if (HTTPAPI_result == HTTPAPI_INVALID_ARG)
+                    {
+                        result = HTTPAPIEX_INVALID_ARG;
+                        LOG_HTTAPIEX_ERROR();
+                    }
+                    else
+                    {
+                        result = HTTPAPIEX_ERROR;
+                        LOG_HTTAPIEX_ERROR();
+                    }
+                }
+                else
+                {
+                    result = HTTPAPIEX_OK;
+                }
+            }
+        }
+    }
+    return result;
+}
Index: azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/src/httpapiexsas.c
===================================================================
--- azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/src/httpapiexsas.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/src/httpapiexsas.c	(revision 457)
@@ -0,0 +1,186 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+#include <stdlib.h>
+#include <time.h>
+#include "azure_c_shared_utility/gballoc.h"
+#include "azure_c_shared_utility/agenttime.h"
+#include "azure_c_shared_utility/strings.h"
+#include "azure_c_shared_utility/buffer_.h"
+#include "azure_c_shared_utility/sastoken.h"
+#include "azure_c_shared_utility/httpheaders.h"
+#include "azure_c_shared_utility/httpapiex.h"
+#include "azure_c_shared_utility/httpapiexsas.h"
+#include "azure_c_shared_utility/xlogging.h"
+#include "azure_c_shared_utility/crt_abstractions.h"
+
+#define SHARED_ACCESS_SIGNATURE_PREFIX "sas="
+
+typedef struct HTTPAPIEX_SAS_STATE_TAG
+{
+    char* key;
+    char* uriResource;
+    char* keyName;
+} HTTPAPIEX_SAS_STATE;
+
+static HTTPAPIEX_SAS_STATE* construct_httpex_sas(const char* key, const char* uriResource, const char* keyName)
+{
+    HTTPAPIEX_SAS_STATE* result;
+
+    result = (HTTPAPIEX_SAS_STATE*)malloc(sizeof(HTTPAPIEX_SAS_STATE));
+    if (result == NULL)
+    {
+        LogError("Failure allocating HTTPAPIEX_SAS_Create.");
+    }
+    else
+    {
+        (void)memset(result, 0, sizeof(HTTPAPIEX_SAS_STATE));
+        if (mallocAndStrcpy_s(&result->key, key) != 0)
+        {
+            /*Codes_SRS_HTTPAPIEXSAS_06_004: [If there are any other errors in the instantiation of this handle then HTTPAPIEX_SAS_Create shall return NULL.]*/
+            LogError("Failure allocating sas key.");
+            HTTPAPIEX_SAS_Destroy(result);
+            result = NULL;
+        }
+        else if (mallocAndStrcpy_s(&result->uriResource, uriResource) != 0)
+        {
+            /*Codes_SRS_HTTPAPIEXSAS_06_004: [If there are any other errors in the instantiation of this handle then HTTPAPIEX_SAS_Create shall return NULL.]*/
+            LogError("Failure allocating sas uriResource.");
+            HTTPAPIEX_SAS_Destroy(result);
+            result = NULL;
+        }
+        else if (keyName != NULL && mallocAndStrcpy_s(&result->keyName, keyName) != 0)
+        {
+            /*Codes_SRS_HTTPAPIEXSAS_06_004: [If there are any other errors in the instantiation of this handle then HTTPAPIEX_SAS_Create shall return NULL.]*/
+            LogError("Failure allocating sas keyName.");
+            HTTPAPIEX_SAS_Destroy(result);
+            result = NULL;
+        }
+    }
+    return result;
+}
+
+HTTPAPIEX_SAS_HANDLE HTTPAPIEX_SAS_Create_From_String(const char* key, const char* uriResource, const char* keyName)
+{
+    HTTPAPIEX_SAS_HANDLE result = NULL;
+    if (key == NULL || uriResource == NULL)
+    {
+        /* Codes_SRS_HTTPAPIEXSAS_07_001: [ If the parameter key or uriResource is NULL then HTTPAPIEX_SAS_Create_From_String shall return NULL. ] */
+        LogError("Invalid parameter key: %p, uriResource: %p", key, uriResource);
+        result = NULL;
+    }
+    else
+    {
+        /* Codes_SRS_HTTPAPIEXSAS_07_002: [ If there are any other errors in the instantiation of this handle then HTTPAPIEX_SAS_Create_From_String shall return NULL. ] */
+        result = construct_httpex_sas(key, uriResource, keyName);
+    }
+    /* Codes_SRS_HTTPAPIEXSAS_07_003: [ HTTPAPIEX_SAS_Create_From_String shall create a new instance of HTTPAPIEX_SAS and return a non-NULL handle to it ] */
+    return result;
+}
+
+HTTPAPIEX_SAS_HANDLE HTTPAPIEX_SAS_Create(STRING_HANDLE key, STRING_HANDLE uriResource, STRING_HANDLE keyName)
+{
+    HTTPAPIEX_SAS_HANDLE result = NULL;
+    if (key == NULL)
+    {
+        /*Codes_SRS_HTTPAPIEXSAS_06_001: [If the parameter key is NULL then HTTPAPIEX_SAS_Create shall return NULL.]*/
+        LogError("No key passed to HTTPAPIEX_SAS_Create.");
+    }
+    else if (uriResource == NULL)
+    {
+        /*Codes_SRS_HTTPAPIEXSAS_06_002: [If the parameter uriResource is NULL then HTTPAPIEX_SAS_Create shall return NULL.]*/
+        LogError("No uri resource passed to HTTPAPIEX_SAS_Create.");
+    }
+    else
+    {
+        /*Codes_SRS_HTTPAPIEXSAS_06_003: [The parameter keyName for HTTPAPIEX_SAS_Create is optional and can be NULL.]*/
+        /*Codes_SRS_HTTPAPIEXSAS_01_001: [ HTTPAPIEX_SAS_Create shall create a new instance of HTTPAPIEX_SAS and return a non-NULL handle to it. ]*/
+        const char* keyStr = STRING_c_str(key);
+        const char* uriStr = STRING_c_str(uriResource);
+        const char* keyNameStr = STRING_c_str(keyName);
+        result = construct_httpex_sas(keyStr, uriStr, keyNameStr);
+    }
+    return result;
+}
+
+void HTTPAPIEX_SAS_Destroy(HTTPAPIEX_SAS_HANDLE handle)
+{
+    /*Codes_SRS_HTTPAPIEXSAS_06_005: [If the parameter handle is NULL then HTTAPIEX_SAS_Destroy shall do nothing and return.]*/
+    if (handle)
+    {
+        HTTPAPIEX_SAS_STATE* state = (HTTPAPIEX_SAS_STATE*)handle;
+        /*Codes_SRS_HTTPAPIEXSAS_06_006: [HTTAPIEX_SAS_Destroy shall deallocate any structures denoted by the parameter handle.]*/
+        if (state->key)
+        {
+            free(state->key);
+        }
+        if (state->uriResource)
+        {
+            free(state->uriResource);
+        }
+        if (state->keyName)
+        {
+            free(state->keyName);
+        }
+        free(state);
+    }
+}
+
+HTTPAPIEX_RESULT HTTPAPIEX_SAS_ExecuteRequest(HTTPAPIEX_SAS_HANDLE sasHandle, HTTPAPIEX_HANDLE handle, HTTPAPI_REQUEST_TYPE requestType, const char* relativePath, HTTP_HEADERS_HANDLE requestHttpHeadersHandle, BUFFER_HANDLE requestContent, unsigned int* statusCode, HTTP_HEADERS_HANDLE responseHeadersHandle, BUFFER_HANDLE responseContent)
+{
+    /*Codes_SRS_HTTPAPIEXSAS_06_007: [If the parameter sasHandle is NULL then HTTPAPIEX_SAS_ExecuteRequest shall simply invoke HTTPAPIEX_ExecuteRequest with the remaining parameters (following sasHandle) as its arguments and shall return immediately with the result of that call as the result of HTTPAPIEX_SAS_ExecuteRequest.]*/
+    if (sasHandle != NULL)
+    {
+        /*Codes_SRS_HTTPAPIEXSAS_06_008: [if the parameter requestHttpHeadersHandle is NULL then fallthrough.]*/
+        if (requestHttpHeadersHandle != NULL)
+        {
+            /*Codes_SRS_HTTPAPIEXSAS_06_009: [HTTPHeaders_FindHeaderValue shall be invoked with the requestHttpHeadersHandle as its first argument and the string "Authorization" as its second argument.]*/
+            /*Codes_SRS_HTTPAPIEXSAS_06_010: [If the return result of the invocation of HTTPHeaders_FindHeaderValue is NULL then fallthrough.]*/
+            if (HTTPHeaders_FindHeaderValue(requestHttpHeadersHandle, "Authorization") != NULL)
+            {
+                HTTPAPIEX_SAS_STATE* state = (HTTPAPIEX_SAS_STATE*)sasHandle;
+                /*Codes_SRS_HTTPAPIEXSAS_06_018: [A value of type time_t that shall be known as currentTime is obtained from calling get_time.]*/
+                time_t currentTime = get_time(NULL);
+                /*Codes_SRS_HTTPAPIEXSAS_06_019: [If the value of currentTime is (time_t)-1 is then fallthrough.]*/
+                if (currentTime == (time_t)-1)
+                {
+                    LogError("Time does not appear to be working.");
+                }
+                else
+                {
+                    STRING_HANDLE newSASToken = NULL;
+                    if (strncmp(state->key, SHARED_ACCESS_SIGNATURE_PREFIX, 4) == 0)
+                    {
+                        /*Codes_SRS_HTTPAPIEXSAS_06_017: [If state->key is prefixed with "sas=", SharedAccessSignature will be used rather than created.  STRING_construct will be invoked.]*/
+                        newSASToken = STRING_construct(&state->key[4]);
+                    }
+                    else
+                    {
+                        /*Codes_SRS_HTTPAPIEXSAS_06_011: [SASToken_Create shall be invoked.]*/
+                        /*Codes_SRS_HTTPAPIEXSAS_06_012: [If the return result of SASToken_Create is NULL then fallthrough.]*/
+                        size_t expiry = (size_t)(difftime(currentTime, 0) + 3600);
+                        newSASToken = SASToken_CreateString(state->key, state->uriResource, state->keyName, expiry);
+                    }
+
+                    if (newSASToken != NULL)
+                    {
+                        /*Codes_SRS_HTTPAPIEXSAS_06_013: [HTTPHeaders_ReplaceHeaderNameValuePair shall be invoked with "Authorization" as its second argument and STRING_c_str (newSASToken) as its third argument.]*/
+                        if (HTTPHeaders_ReplaceHeaderNameValuePair(requestHttpHeadersHandle, "Authorization", STRING_c_str(newSASToken)) != HTTP_HEADERS_OK)
+                        {
+                            /*Codes_SRS_HTTPAPIEXSAS_06_014: [If the result of the invocation of HTTPHeaders_ReplaceHeaderNameValuePair is NOT HTTP_HEADERS_OK then fallthrough.]*/
+                            LogError("Unable to replace the old SAS Token.");
+                        }
+                        /*Codes_SRS_HTTPAPIEXSAS_06_015: [STRING_delete(newSASToken) will be invoked.]*/
+                        STRING_delete(newSASToken);
+                    }
+                    else
+                    {
+                        LogError("Unable to create a new SAS token.");
+                    }
+                }
+            }
+        }
+    }
+    /*Codes_SRS_HTTPAPIEXSAS_06_016: [HTTPAPIEX_ExecuteRequest with the remaining parameters (following sasHandle) as its arguments will be invoked and the result of that call is the result of HTTPAPIEX_SAS_ExecuteRequest.]*/
+    return HTTPAPIEX_ExecuteRequest(handle,requestType,relativePath,requestHttpHeadersHandle,requestContent,statusCode,responseHeadersHandle,responseContent);
+}
Index: azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/src/httpheaders.c
===================================================================
--- azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/src/httpheaders.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/src/httpheaders.c	(revision 457)
@@ -0,0 +1,336 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+#include <stdlib.h>
+#include <string.h>
+#include "azure_macro_utils/macro_utils.h"
+#include "azure_c_shared_utility/gballoc.h"
+#include "azure_c_shared_utility/map.h"
+#include "azure_c_shared_utility/httpheaders.h"
+#include "azure_c_shared_utility/crt_abstractions.h"
+#include "azure_c_shared_utility/xlogging.h"
+
+MU_DEFINE_ENUM_STRINGS(HTTP_HEADERS_RESULT, HTTP_HEADERS_RESULT_VALUES);
+
+typedef struct HTTP_HEADERS_HANDLE_DATA_TAG
+{
+    MAP_HANDLE headers;
+} HTTP_HEADERS_HANDLE_DATA;
+
+HTTP_HEADERS_HANDLE HTTPHeaders_Alloc(void)
+{
+    /*Codes_SRS_HTTP_HEADERS_99_002:[ This API shall produce a HTTP_HANDLE that can later be used in subsequent calls to the module.]*/
+    HTTP_HEADERS_HANDLE_DATA* result;
+    result = (HTTP_HEADERS_HANDLE_DATA*)malloc(sizeof(HTTP_HEADERS_HANDLE_DATA));
+
+    if (result == NULL)
+    {
+        LogError("malloc failed");
+    }
+    else
+    {
+        /*Codes_SRS_HTTP_HEADERS_99_004:[ After a successful init, HTTPHeaders_GetHeaderCount shall report 0 existing headers.]*/
+        result->headers = Map_Create(NULL);
+        if (result->headers == NULL)
+        {
+            LogError("Map_Create failed");
+            free(result);
+            result = NULL;
+        }
+        else
+        {
+            /*all is fine*/
+        }
+    }
+
+    /*Codes_SRS_HTTP_HEADERS_99_003:[ The function shall return NULL when the function cannot execute properly]*/
+    return (HTTP_HEADERS_HANDLE)result;
+}
+
+/*Codes_SRS_HTTP_HEADERS_99_005:[ Calling this API shall de-allocate the data structures allocated by previous API calls to the same handle.]*/
+void HTTPHeaders_Free(HTTP_HEADERS_HANDLE handle)
+{
+    /*Codes_SRS_HTTP_HEADERS_02_001: [If httpHeadersHandle is NULL then HTTPHeaders_Free shall perform no action.] */
+    if (handle == NULL)
+    {
+        /*do nothing*/
+    }
+    else
+    {
+        /*Codes_SRS_HTTP_HEADERS_99_005:[ Calling this API shall de-allocate the data structures allocated by previous API calls to the same handle.]*/
+        HTTP_HEADERS_HANDLE_DATA* handleData = (HTTP_HEADERS_HANDLE_DATA*)handle;
+
+        Map_Destroy(handleData->headers);
+        free(handleData);
+    }
+}
+
+/*Codes_SRS_HTTP_HEADERS_99_012:[ Calling this API shall record a header from name and value parameters.]*/
+static HTTP_HEADERS_RESULT headers_ReplaceHeaderNameValuePair(HTTP_HEADERS_HANDLE handle, const char* name, const char* value, bool replace)
+{
+    HTTP_HEADERS_RESULT result;
+    /*Codes_SRS_HTTP_HEADERS_99_014:[ The function shall return when the handle is not valid or when name parameter is NULL or when value parameter is NULL.]*/
+    if (
+        (handle == NULL) ||
+        (name == NULL) ||
+        (value == NULL)
+        )
+    {
+        result = HTTP_HEADERS_INVALID_ARG;
+        LogError("invalid arg (NULL) , result= %" PRI_MU_ENUM "", MU_ENUM_VALUE(HTTP_HEADERS_RESULT, result));
+    }
+    else
+    {
+        /*Codes_SRS_HTTP_HEADERS_99_036:[ If name contains the characters outside character codes 33 to 126 then the return value shall be HTTP_HEADERS_INVALID_ARG]*/
+        /*Codes_SRS_HTTP_HEADERS_99_031:[ If name contains the character ":" then the return value shall be HTTP_HEADERS_INVALID_ARG.]*/
+        size_t i;
+        size_t nameLen = strlen(name);
+        for (i = 0; i < nameLen; i++)
+        {
+            if ((name[i] < 33) || (126 < name[i]) || (name[i] == ':'))
+            {
+                break;
+            }
+        }
+
+        if (i < nameLen)
+        {
+            result = HTTP_HEADERS_INVALID_ARG;
+            LogError("(result = %" PRI_MU_ENUM ")", MU_ENUM_VALUE(HTTP_HEADERS_RESULT, result));
+        }
+        else
+        {
+            HTTP_HEADERS_HANDLE_DATA* handleData = (HTTP_HEADERS_HANDLE_DATA*)handle;
+            const char* existingValue = Map_GetValueFromKey(handleData->headers, name);
+            /*eat up the whitespaces from value, as per RFC 2616, chapter 4.2 "The field value MAY be preceded by any amount of LWS, though a single SP is preferred."*/
+            /*Codes_SRS_HTTP_HEADERS_02_002: [The LWS from the beginning of the value shall not be stored.] */
+            while ((value[0] == ' ') || (value[0] == '\t') || (value[0] == '\r') || (value[0] == '\n'))
+            {
+                value++;
+            }
+
+            if (!replace && (existingValue != NULL))
+            {
+                size_t existingValueLen = strlen(existingValue);
+                size_t valueLen = strlen(value);
+                char* newValue = (char*)malloc(sizeof(char) * (existingValueLen + /*COMMA_AND_SPACE_LENGTH*/ 2 + valueLen + /*EOL*/ 1));
+                if (newValue == NULL)
+                {
+                    /*Codes_SRS_HTTP_HEADERS_99_015:[ The function shall return HTTP_HEADERS_ALLOC_FAILED when an internal request to allocate memory fails.]*/
+                    result = HTTP_HEADERS_ALLOC_FAILED;
+                    LogError("failed to malloc , result= %" PRI_MU_ENUM "", MU_ENUM_VALUE(HTTP_HEADERS_RESULT, result));
+                }
+                else
+                {
+                    char* runNewValue;
+                    /*Codes_SRS_HTTP_HEADERS_99_017:[ If the name already exists in the collection of headers, the function shall concatenate the new value after the existing value, separated by a comma and a space as in: old-value+", "+new-value.]*/
+                    (void)memcpy(newValue, existingValue, existingValueLen);
+                    runNewValue = newValue + existingValueLen;
+                    (*runNewValue++) = ',';
+                    (*runNewValue++) = ' ';
+                    (void)memcpy(runNewValue, value, valueLen + /*EOL*/ 1);
+
+                    /*Codes_SRS_HTTP_HEADERS_99_016:[ The function shall store the name:value pair in such a way that when later retrieved by a call to GetHeader it will return a string that shall strcmp equal to the name+": "+value.]*/
+                    if (Map_AddOrUpdate(handleData->headers, name, newValue) != MAP_OK)
+                    {
+                        /*Codes_SRS_HTTP_HEADERS_99_015:[ The function shall return HTTP_HEADERS_ALLOC_FAILED when an internal request to allocate memory fails.]*/
+                        result = HTTP_HEADERS_ERROR;
+                        LogError("failed to Map_AddOrUpdate, result= %" PRI_MU_ENUM "", MU_ENUM_VALUE(HTTP_HEADERS_RESULT, result));
+                    }
+                    else
+                    {
+                        /*Codes_SRS_HTTP_HEADERS_99_013:[ The function shall return HTTP_HEADERS_OK when execution is successful.]*/
+                        result = HTTP_HEADERS_OK;
+                    }
+                    free(newValue);
+                }
+            }
+            else
+            {
+                /*Codes_SRS_HTTP_HEADERS_99_016:[ The function shall store the name:value pair in such a way that when later retrieved by a call to GetHeader it will return a string that shall strcmp equal to the name+": "+value.]*/
+                if (Map_AddOrUpdate(handleData->headers, name, value) != MAP_OK)
+                {
+                    /*Codes_SRS_HTTP_HEADERS_99_015:[ The function shall return HTTP_HEADERS_ALLOC_FAILED when an internal request to allocate memory fails.]*/
+                    result = HTTP_HEADERS_ALLOC_FAILED;
+                    LogError("failed to Map_AddOrUpdate, result= %" PRI_MU_ENUM "", MU_ENUM_VALUE(HTTP_HEADERS_RESULT, result));
+                }
+                else
+                {
+                    result = HTTP_HEADERS_OK;
+                }
+            }
+        }
+    }
+
+    return result;
+}
+
+HTTP_HEADERS_RESULT HTTPHeaders_AddHeaderNameValuePair(HTTP_HEADERS_HANDLE httpHeadersHandle, const char* name, const char* value)
+{
+    return headers_ReplaceHeaderNameValuePair(httpHeadersHandle, name, value, false);
+}
+
+/* Codes_SRS_HTTP_HEADERS_06_001: [This API will perform exactly as HTTPHeaders_AddHeaderNameValuePair except that if the header name already exists the already existing value will be replaced as opposed to concatenated to.] */
+HTTP_HEADERS_RESULT HTTPHeaders_ReplaceHeaderNameValuePair(HTTP_HEADERS_HANDLE httpHeadersHandle, const char* name, const char* value)
+{
+    return headers_ReplaceHeaderNameValuePair(httpHeadersHandle, name, value, true);
+}
+
+
+const char* HTTPHeaders_FindHeaderValue(HTTP_HEADERS_HANDLE httpHeadersHandle, const char* name)
+{
+    const char* result;
+    /*Codes_SRS_HTTP_HEADERS_99_022:[ The return value shall be NULL if name parameter is NULL or if httpHeadersHandle is NULL]*/
+    if (
+        (httpHeadersHandle == NULL) ||
+        (name == NULL)
+        )
+    {
+        result = NULL;
+    }
+    else
+    {
+        /*Codes_SRS_HTTP_HEADERS_99_018:[ Calling this API shall retrieve the value for a previously stored name.]*/
+        /*Codes_SRS_HTTP_HEADERS_99_020:[ The return value shall be different than NULL when the name matches the name of a previously stored name:value pair.] */
+        /*Codes_SRS_HTTP_HEADERS_99_021:[ In this case the return value shall point to a string that shall strcmp equal to the original stored string.]*/
+        HTTP_HEADERS_HANDLE_DATA* handleData = (HTTP_HEADERS_HANDLE_DATA*)httpHeadersHandle;
+        result = Map_GetValueFromKey(handleData->headers, name);
+    }
+    return result;
+
+}
+
+HTTP_HEADERS_RESULT HTTPHeaders_GetHeaderCount(HTTP_HEADERS_HANDLE handle, size_t* headerCount)
+{
+    HTTP_HEADERS_RESULT result;
+    /*Codes_SRS_HTTP_HEADERS_99_024:[ The function shall return HTTP_HEADERS_INVALID_ARG when an invalid handle is passed.]*/
+    /*Codes_SRS_HTTP_HEADERS_99_025:[ The function shall return HTTP_HEADERS_INVALID_ARG when headersCount is NULL.]*/
+    if ((handle == NULL) ||
+        (headerCount == NULL))
+    {
+        result = HTTP_HEADERS_INVALID_ARG;
+        LogError("(result = %" PRI_MU_ENUM ")", MU_ENUM_VALUE(HTTP_HEADERS_RESULT, result));
+    }
+    else
+    {
+        HTTP_HEADERS_HANDLE_DATA *handleData = (HTTP_HEADERS_HANDLE_DATA *)handle;
+        const char*const* keys;
+        const char*const* values;
+        /*Codes_SRS_HTTP_HEADERS_99_023:[ Calling this API shall provide the number of stored headers.]*/
+        if (Map_GetInternals(handleData->headers, &keys, &values, headerCount) != MAP_OK)
+        {
+            /*Codes_SRS_HTTP_HEADERS_99_037:[ The function shall return HTTP_HEADERS_ERROR when an internal error occurs.]*/
+            result = HTTP_HEADERS_ERROR;
+            LogError("Map_GetInternals failed, result= %" PRI_MU_ENUM "", MU_ENUM_VALUE(HTTP_HEADERS_RESULT, result));
+        }
+        else
+        {
+            /*Codes_SRS_HTTP_HEADERS_99_026:[ The function shall write in *headersCount the number of currently stored headers and shall return HTTP_HEADERS_OK]*/
+            result = HTTP_HEADERS_OK;
+        }
+    }
+
+    return result;
+}
+
+/*produces a string in *destination that is equal to name: value*/
+HTTP_HEADERS_RESULT HTTPHeaders_GetHeader(HTTP_HEADERS_HANDLE handle, size_t index, char** destination)
+{
+    HTTP_HEADERS_RESULT result = HTTP_HEADERS_OK;
+
+    /*Codes_SRS_HTTP_HEADERS_99_028:[ The function shall return NULL if the handle is invalid.]*/
+    /*Codes_SRS_HTTP_HEADERS_99_032:[ The function shall return HTTP_HEADERS_INVALID_ARG if the destination  is NULL]*/
+    if (
+        (handle == NULL) ||
+        (destination == NULL)
+        )
+    {
+        result = HTTP_HEADERS_INVALID_ARG;
+        LogError("invalid arg (NULL), result= %" PRI_MU_ENUM "", MU_ENUM_VALUE(HTTP_HEADERS_RESULT, result));
+    }
+    /*Codes_SRS_HTTP_HEADERS_99_029:[ The function shall return HTTP_HEADERS_INVALID_ARG if index is not valid (for example, out of range) for the currently stored headers.]*/
+    else
+    {
+        HTTP_HEADERS_HANDLE_DATA* handleData = (HTTP_HEADERS_HANDLE_DATA*)handle;
+        const char*const* keys;
+        const char*const* values;
+        size_t headerCount;
+        if (Map_GetInternals(handleData->headers, &keys, &values, &headerCount) != MAP_OK)
+        {
+            /*Codes_SRS_HTTP_HEADERS_99_034:[ The function shall return HTTP_HEADERS_ERROR when an internal error occurs]*/
+            result = HTTP_HEADERS_ERROR;
+            LogError("Map_GetInternals failed, result= %" PRI_MU_ENUM "", MU_ENUM_VALUE(HTTP_HEADERS_RESULT, result));
+        }
+        else
+        {
+            /*Codes_SRS_HTTP_HEADERS_99_029:[ The function shall return HTTP_HEADERS_INVALID_ARG if index is not valid (for example, out of range) for the currently stored headers.]*/
+            if (index >= headerCount)
+            {
+                result = HTTP_HEADERS_INVALID_ARG;
+                LogError("index out of bounds, result= %" PRI_MU_ENUM "", MU_ENUM_VALUE(HTTP_HEADERS_RESULT, result));
+            }
+            else
+            {
+                size_t keyLen = strlen(keys[index]);
+                size_t valueLen = strlen(values[index]);
+                *destination = (char*)malloc(sizeof(char) * (keyLen + /*COLON_AND_SPACE_LENGTH*/ 2 + valueLen + /*EOL*/ 1));
+                if (*destination == NULL)
+                {
+                    /*Codes_SRS_HTTP_HEADERS_99_034:[ The function shall return HTTP_HEADERS_ERROR when an internal error occurs]*/
+                    result = HTTP_HEADERS_ERROR;
+                    LogError("unable to malloc, result= %" PRI_MU_ENUM "", MU_ENUM_VALUE(HTTP_HEADERS_RESULT, result));
+                }
+                else
+                {
+                    /*Codes_SRS_HTTP_HEADERS_99_016:[ The function shall store the name:value pair in such a way that when later retrieved by a call to GetHeader it will return a string that shall strcmp equal to the name+": "+value.]*/
+                    /*Codes_SRS_HTTP_HEADERS_99_027:[ Calling this API shall produce the string value+": "+pair) for the index header in the *destination parameter.]*/
+                    char* runDestination = (*destination);
+                    (void)memcpy(runDestination, keys[index], keyLen);
+                    runDestination += keyLen;
+                    (*runDestination++) = ':';
+                    (*runDestination++) = ' ';
+                    (void)memcpy(runDestination, values[index], valueLen + /*EOL*/ 1);
+                    /*Codes_SRS_HTTP_HEADERS_99_035:[ The function shall return HTTP_HEADERS_OK when the function executed without error.]*/
+                    result = HTTP_HEADERS_OK;
+                }
+            }
+        }
+    }
+
+    return result;
+}
+
+HTTP_HEADERS_HANDLE HTTPHeaders_Clone(HTTP_HEADERS_HANDLE handle)
+{
+    HTTP_HEADERS_HANDLE_DATA* result;
+    /*Codes_SRS_HTTP_HEADERS_02_003: [If handle is NULL then HTTPHeaders_Clone shall return NULL.] */
+    if (handle == NULL)
+    {
+        result = NULL;
+    }
+    else
+    {
+        /*Codes_SRS_HTTP_HEADERS_02_004: [Otherwise HTTPHeaders_Clone shall clone the content of handle to a new handle.] */
+        result = (HTTP_HEADERS_HANDLE_DATA*)malloc(sizeof(HTTP_HEADERS_HANDLE_DATA));
+        if (result == NULL)
+        {
+            /*Codes_SRS_HTTP_HEADERS_02_005: [If cloning fails for any reason, then HTTPHeaders_Clone shall return NULL.] */
+        }
+        else
+        {
+            HTTP_HEADERS_HANDLE_DATA* handleData = handle;
+            result->headers = Map_Clone(handleData->headers);
+            if (result->headers == NULL)
+            {
+                /*Codes_SRS_HTTP_HEADERS_02_005: [If cloning fails for any reason, then HTTPHeaders_Clone shall return NULL.] */
+                free(result);
+                result = NULL;
+            }
+            else
+            {
+                /*all is fine*/
+            }
+        }
+    }
+    return result;
+}
Index: azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/src/map.c
===================================================================
--- azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/src/map.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/src/map.c	(revision 457)
@@ -0,0 +1,678 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+#include <stdlib.h>
+#include "azure_macro_utils/macro_utils.h"
+#include "azure_c_shared_utility/gballoc.h"
+#include "azure_c_shared_utility/map.h"
+#include "azure_c_shared_utility/optimize_size.h"
+#include "azure_c_shared_utility/xlogging.h"
+#include "azure_c_shared_utility/strings.h"
+
+MU_DEFINE_ENUM_STRINGS(MAP_RESULT, MAP_RESULT_VALUES);
+
+typedef struct MAP_HANDLE_DATA_TAG
+{
+    char** keys;
+    char** values;
+    size_t count;
+    MAP_FILTER_CALLBACK mapFilterCallback;
+}MAP_HANDLE_DATA;
+
+#define LOG_MAP_ERROR LogError("result = %" PRI_MU_ENUM "", MU_ENUM_VALUE(MAP_RESULT, result));
+
+MAP_HANDLE Map_Create(MAP_FILTER_CALLBACK mapFilterFunc)
+{
+    /*Codes_SRS_MAP_02_001: [Map_Create shall create a new, empty map.]*/
+    MAP_HANDLE_DATA* result = (MAP_HANDLE_DATA*)calloc(1, sizeof(MAP_HANDLE_DATA));
+    /*Codes_SRS_MAP_02_002: [If during creation there are any error, then Map_Create shall return NULL.]*/
+    if (result != NULL)
+    {
+        /*Codes_SRS_MAP_02_003: [Otherwise, it shall return a non-NULL handle that can be used in subsequent calls.] */
+        result->keys = NULL;
+        result->values = NULL;
+        result->count = 0;
+        result->mapFilterCallback = mapFilterFunc;
+    }
+    return (MAP_HANDLE)result;
+}
+
+void Map_Destroy(MAP_HANDLE handle)
+{
+    /*Codes_SRS_MAP_02_005: [If parameter handle is NULL then Map_Destroy shall take no action.] */
+    if (handle != NULL)
+    {
+        /*Codes_SRS_MAP_02_004: [Map_Destroy shall release all resources associated with the map.] */
+        MAP_HANDLE_DATA* handleData = (MAP_HANDLE_DATA*)handle;
+        size_t i;
+
+        for (i = 0; i < handleData->count; i++)
+        {
+            free(handleData->keys[i]);
+            free(handleData->values[i]);
+        }
+        free(handleData->keys);
+        free(handleData->values);
+        free(handleData);
+    }
+}
+
+/*makes a copy of a vector of const char*, having size "size". source cannot be NULL*/
+/*returns NULL if it fails*/
+static char** Map_CloneVector(const char*const * source, size_t count)
+{
+    char** result;
+    result = (char**)malloc(count *sizeof(char*));
+    if (result == NULL)
+    {
+        /*do nothing, just return it (NULL)*/
+    }
+    else
+    {
+        size_t i;
+        for (i = 0; i < count; i++)
+        {
+            if (mallocAndStrcpy_s(result + i, source[i]) != 0)
+            {
+                break;
+            }
+        }
+
+        if (i == count)
+        {
+            /*it is all good, proceed to return result*/
+        }
+        else
+        {
+            size_t j;
+            for (j = 0; j < i; j++)
+            {
+                free(result[j]);
+            }
+            free(result);
+            result = NULL;
+        }
+    }
+    return result;
+}
+
+/*Codes_SRS_MAP_02_039: [Map_Clone shall make a copy of the map indicated by parameter handle and return a non-NULL handle to it.]*/
+MAP_HANDLE Map_Clone(MAP_HANDLE handle)
+{
+    MAP_HANDLE_DATA* result;
+    if (handle == NULL)
+    {
+        /*Codes_SRS_MAP_02_038: [Map_Clone returns NULL if parameter handle is NULL.]*/
+        result = NULL;
+        LogError("invalid arg to Map_Clone (NULL)");
+    }
+    else
+    {
+        MAP_HANDLE_DATA * handleData = (MAP_HANDLE_DATA *)handle;
+        result = (MAP_HANDLE_DATA*)calloc(1, sizeof(MAP_HANDLE_DATA));
+        if (result == NULL)
+        {
+            /*Codes_SRS_MAP_02_047: [If during cloning, any operation fails, then Map_Clone shall return NULL.] */
+            /*do nothing, proceed to return it, this is an error case*/
+            LogError("unable to malloc");
+        }
+        else
+        {
+            if (handleData->count == 0)
+            {
+                result->count = 0;
+                result->keys = NULL;
+                result->values = NULL;
+                result->mapFilterCallback = NULL;
+            }
+            else
+            {
+                result->mapFilterCallback = handleData->mapFilterCallback;
+                result->count = handleData->count;
+                if( (result->keys = Map_CloneVector((const char* const*)handleData->keys, handleData->count))==NULL)
+                {
+                    /*Codes_SRS_MAP_02_047: [If during cloning, any operation fails, then Map_Clone shall return NULL.] */
+                    LogError("unable to clone keys");
+                    free(result);
+                    result = NULL;
+                }
+                else if ((result->values = Map_CloneVector((const char* const*)handleData->values, handleData->count)) == NULL)
+                {
+                    size_t i;
+                    /*Codes_SRS_MAP_02_047: [If during cloning, any operation fails, then Map_Clone shall return NULL.] */
+                    LogError("unable to clone values");
+                    for (i = 0; i < result->count; i++)
+                    {
+                        free(result->keys[i]);
+                    }
+                    free(result->keys);
+                    free(result);
+                    result = NULL;
+                }
+                else
+                {
+                    /*all fine, return it*/
+                }
+            }
+        }
+    }
+    return (MAP_HANDLE)result;
+}
+
+static int Map_IncreaseStorageKeysValues(MAP_HANDLE_DATA* handleData)
+{
+    int result;
+    char** newKeys = (char**)realloc(handleData->keys, (handleData->count + 1) * sizeof(char*));
+    if (newKeys == NULL)
+    {
+        LogError("realloc error");
+        result = MU_FAILURE;
+    }
+    else
+    {
+        char** newValues;
+        handleData->keys = newKeys;
+        handleData->keys[handleData->count] = NULL;
+        newValues = (char**)realloc(handleData->values, (handleData->count + 1) * sizeof(char*));
+        if (newValues == NULL)
+        {
+            LogError("realloc error");
+            if (handleData->count == 0) /*avoiding an implementation defined behavior */
+            {
+                free(handleData->keys);
+                handleData->keys = NULL;
+            }
+            else
+            {
+                char** undoneKeys = (char**)realloc(handleData->keys, (handleData->count) * sizeof(char*));
+                if (undoneKeys == NULL)
+                {
+                    LogError("CATASTROPHIC error, unable to undo through realloc to a smaller size");
+                }
+                else
+                {
+                    handleData->keys = undoneKeys;
+                }
+            }
+            result = MU_FAILURE;
+        }
+        else
+        {
+            handleData->values = newValues;
+            handleData->values[handleData->count] = NULL;
+            handleData->count++;
+            result = 0;
+        }
+    }
+    return result;
+}
+
+static void Map_DecreaseStorageKeysValues(MAP_HANDLE_DATA* handleData)
+{
+    if (handleData->count == 1)
+    {
+        free(handleData->keys);
+        handleData->keys = NULL;
+        free(handleData->values);
+        handleData->values = NULL;
+        handleData->count = 0;
+        handleData->mapFilterCallback = NULL;
+    }
+    else
+    {
+        /*certainly > 1...*/
+        char** undoneValues;
+        char** undoneKeys = (char**)realloc(handleData->keys, sizeof(char*)* (handleData->count - 1));
+        if (undoneKeys == NULL)
+        {
+            LogError("CATASTROPHIC error, unable to undo through realloc to a smaller size");
+        }
+        else
+        {
+            handleData->keys = undoneKeys;
+        }
+
+        undoneValues = (char**)realloc(handleData->values, sizeof(char*)* (handleData->count - 1));
+        if (undoneValues == NULL)
+        {
+            LogError("CATASTROPHIC error, unable to undo through realloc to a smaller size");
+        }
+        else
+        {
+            handleData->values = undoneValues;
+        }
+
+        handleData->count--;
+    }
+}
+
+static char** findKey(MAP_HANDLE_DATA* handleData, const char* key)
+{
+    char** result;
+    if (handleData->keys == NULL)
+    {
+        result = NULL;
+    }
+    else
+    {
+        size_t i;
+        result = NULL;
+        for (i = 0; i < handleData->count; i++)
+        {
+            if (strcmp(handleData->keys[i], key) == 0)
+            {
+                result = handleData->keys + i;
+                break;
+            }
+        }
+    }
+    return result;
+}
+
+static char** findValue(MAP_HANDLE_DATA* handleData, const char* value)
+{
+    char** result;
+    if (handleData->values == NULL)
+    {
+        result = NULL;
+    }
+    else
+    {
+        size_t i;
+        result = NULL;
+        for (i = 0; i < handleData->count; i++)
+        {
+            if (strcmp(handleData->values[i], value) == 0)
+            {
+                result = handleData->values + i;
+                break;
+            }
+        }
+    }
+    return result;
+}
+
+static int insertNewKeyValue(MAP_HANDLE_DATA* handleData, const char* key, const char* value)
+{
+    int result;
+    if (Map_IncreaseStorageKeysValues(handleData) != 0) /*this increases handleData->count*/
+    {
+        result = MU_FAILURE;
+    }
+    else
+    {
+        if (mallocAndStrcpy_s(&(handleData->keys[handleData->count - 1]), key) != 0)
+        {
+            Map_DecreaseStorageKeysValues(handleData);
+            LogError("unable to mallocAndStrcpy_s");
+            result = MU_FAILURE;
+        }
+        else
+        {
+            if (mallocAndStrcpy_s(&(handleData->values[handleData->count - 1]), value) != 0)
+            {
+                free(handleData->keys[handleData->count - 1]);
+                Map_DecreaseStorageKeysValues(handleData);
+                LogError("unable to mallocAndStrcpy_s");
+                result = MU_FAILURE;
+            }
+            else
+            {
+                result = 0;
+            }
+        }
+    }
+    return result;
+}
+
+MAP_RESULT Map_Add(MAP_HANDLE handle, const char* key, const char* value)
+{
+    MAP_RESULT result;
+    /*Codes_SRS_MAP_02_006: [If parameter handle is NULL then Map_Add shall return MAP_INVALID_ARG.] */
+    /*Codes_SRS_MAP_02_007: [If parameter key is NULL then Map_Add shall return MAP_INVALID_ARG.]*/
+    /*Codes_SRS_MAP_02_008: [If parameter value is NULL then Map_Add shall return MAP_INVALID_ARG.] */
+    if (
+        (handle == NULL) ||
+        (key == NULL) ||
+        (value == NULL)
+        )
+    {
+        result = MAP_INVALIDARG;
+        LOG_MAP_ERROR;
+    }
+    else
+    {
+        MAP_HANDLE_DATA* handleData = (MAP_HANDLE_DATA*)handle;
+        /*Codes_SRS_MAP_02_009: [If the key already exists, then Map_Add shall return MAP_KEYEXISTS.] */
+        if (findKey(handleData, key) != NULL)
+        {
+            result = MAP_KEYEXISTS;
+        }
+        else
+        {
+            /* Codes_SRS_MAP_07_009: [If the mapFilterCallback function is not NULL, then the return value will be check and if it is not zero then Map_Add shall return MAP_FILTER_REJECT.] */
+            if ( (handleData->mapFilterCallback != NULL) && (handleData->mapFilterCallback(key, value) != 0) )
+            {
+                result = MAP_FILTER_REJECT;
+            }
+            else
+            {
+                /*Codes_SRS_MAP_02_010: [Otherwise, Map_Add shall add the pair <key,value> to the map.] */
+                if (insertNewKeyValue(handleData, key, value) != 0)
+                {
+                    /*Codes_SRS_MAP_02_011: [If adding the pair <key,value> fails then Map_Add shall return MAP_ERROR.] */
+                    result = MAP_ERROR;
+                    LOG_MAP_ERROR;
+                }
+                else
+                {
+                    /*Codes_SRS_MAP_02_012: [Otherwise, Map_Add shall return MAP_OK.] */
+                    result = MAP_OK;
+                }
+            }
+        }
+    }
+    return result;
+}
+
+MAP_RESULT Map_AddOrUpdate(MAP_HANDLE handle, const char* key, const char* value)
+{
+    MAP_RESULT result;
+    /*Codes_SRS_MAP_02_013: [If parameter handle is NULL then Map_AddOrUpdate shall return MAP_INVALID_ARG.]*/
+    /*Codes_SRS_MAP_02_014: [If parameter key is NULL then Map_AddOrUpdate shall return MAP_INVALID_ARG.]*/
+    /*Codes_SRS_MAP_02_015: [If parameter value is NULL then Map_AddOrUpdate shall return MAP_INVALID_ARG.] */
+    if (
+        (handle == NULL) ||
+        (key == NULL) ||
+        (value == NULL)
+        )
+    {
+        result = MAP_INVALIDARG;
+        LOG_MAP_ERROR;
+    }
+    else
+    {
+        MAP_HANDLE_DATA* handleData = (MAP_HANDLE_DATA*)handle;
+
+        /* Codes_SRS_MAP_07_008: [If the mapFilterCallback function is not NULL, then the return value will be check and if it is not zero then Map_AddOrUpdate shall return MAP_FILTER_REJECT.] */
+        if (handleData->mapFilterCallback != NULL && handleData->mapFilterCallback(key, value) != 0)
+        {
+            result = MAP_FILTER_REJECT;
+        }
+        else
+        {
+            char** whereIsIt = findKey(handleData, key);
+            if (whereIsIt == NULL)
+            {
+                /*Codes_SRS_MAP_02_017: [Otherwise, Map_AddOrUpdate shall add the pair <key,value> to the map.]*/
+                if (insertNewKeyValue(handleData, key, value) != 0)
+                {
+                    result = MAP_ERROR;
+                    LOG_MAP_ERROR;
+                }
+                else
+                {
+                    result = MAP_OK;
+                }
+            }
+            else
+            {
+                /*Codes_SRS_MAP_02_016: [If the key already exists, then Map_AddOrUpdate shall overwrite the value of the existing key with parameter value.]*/
+                size_t index = whereIsIt - handleData->keys;
+                size_t valueLength = strlen(value);
+                /*try to realloc value of this key*/
+                char* newValue = (char*)realloc(handleData->values[index],valueLength  + 1);
+                if (newValue == NULL)
+                {
+                    result = MAP_ERROR;
+                    LOG_MAP_ERROR;
+                }
+                else
+                {
+                    (void)memcpy(newValue, value, valueLength + 1);
+                    handleData->values[index] = newValue;
+                    /*Codes_SRS_MAP_02_019: [Otherwise, Map_AddOrUpdate shall return MAP_OK.] */
+                    result = MAP_OK;
+                }
+            }
+        }
+    }
+    return result;
+}
+
+MAP_RESULT Map_Delete(MAP_HANDLE handle, const char* key)
+{
+    MAP_RESULT result;
+    /*Codes_SRS_MAP_02_020: [If parameter handle is NULL then Map_Delete shall return MAP_INVALIDARG.]*/
+    /*Codes_SRS_MAP_02_021: [If parameter key is NULL then Map_Delete shall return MAP_INVALIDARG.]*/
+    if (
+        (handle == NULL) ||
+        (key == NULL)
+        )
+    {
+        result = MAP_INVALIDARG;
+        LOG_MAP_ERROR;
+    }
+    else
+    {
+        MAP_HANDLE_DATA* handleData = (MAP_HANDLE_DATA*)handle;
+        char** whereIsIt = findKey(handleData,key);
+        if (whereIsIt == NULL)
+        {
+            /*Codes_SRS_MAP_02_022: [If key does not exist then Map_Delete shall return MAP_KEYNOTFOUND.]*/
+            result = MAP_KEYNOTFOUND;
+        }
+        else
+        {
+            /*Codes_SRS_MAP_02_023: [Otherwise, Map_Delete shall remove the key and its associated value from the map and return MAP_OK.]*/
+            size_t index = whereIsIt - handleData->keys;
+            free(handleData->keys[index]);
+            free(handleData->values[index]);
+            memmove(handleData->keys + index, handleData->keys + index + 1, (handleData->count - index - 1)*sizeof(char*)); /*if order doesn't matter... then this can be optimized*/
+            memmove(handleData->values + index, handleData->values + index + 1, (handleData->count - index - 1)*sizeof(char*));
+            Map_DecreaseStorageKeysValues(handleData);
+            result = MAP_OK;
+        }
+
+    }
+    return result;
+}
+
+MAP_RESULT Map_ContainsKey(MAP_HANDLE handle, const char* key, bool* keyExists)
+{
+    MAP_RESULT result;
+    /*Codes_SRS_MAP_02_024: [If parameter handle, key or keyExists are NULL then Map_ContainsKey shall return MAP_INVALIDARG.]*/
+    if (
+        (handle ==NULL) ||
+        (key == NULL) ||
+        (keyExists == NULL)
+        )
+    {
+        result = MAP_INVALIDARG;
+        LOG_MAP_ERROR;
+    }
+    else
+    {
+        MAP_HANDLE_DATA* handleData = (MAP_HANDLE_DATA*)handle;
+        /*Codes_SRS_MAP_02_025: [Otherwise if a key exists then Map_ContainsKey shall return MAP_OK and shall write in keyExists "true".]*/
+        /*Codes_SRS_MAP_02_026: [If a key doesn't exist, then Map_ContainsKey shall return MAP_OK and write in keyExists "false".] */
+        *keyExists = (findKey(handleData, key) != NULL) ? true: false;
+        result = MAP_OK;
+    }
+    return result;
+}
+
+MAP_RESULT Map_ContainsValue(MAP_HANDLE handle, const char* value, bool* valueExists)
+{
+    MAP_RESULT result;
+    /*Codes_SRS_MAP_02_027: [If parameter handle, value or valueExists is NULL then Map_ContainsValue shall return MAP_INVALIDARG.] */
+    if (
+        (handle == NULL) ||
+        (value == NULL) ||
+        (valueExists == NULL)
+        )
+    {
+        result = MAP_INVALIDARG;
+        LOG_MAP_ERROR;
+    }
+    else
+    {
+        MAP_HANDLE_DATA* handleData = (MAP_HANDLE_DATA*)handle;
+        /*Codes_SRS_MAP_02_028: [Otherwise, if a pair <key, value> has its value equal to the parameter value, the Map_ContainsValue shall return MAP_OK and shall write in valueExists "true".]*/
+        /*Codes_SRS_MAP_02_029: [Otherwise, if such a <key, value> does not exist, then Map_ContainsValue shall return MAP_OK and shall write in valueExists "false".] */
+        *valueExists = (findValue(handleData, value) != NULL) ? true : false;
+        result = MAP_OK;
+    }
+    return result;
+}
+
+const char* Map_GetValueFromKey(MAP_HANDLE handle, const char* key)
+{
+    const char* result;
+    /*Codes_SRS_MAP_02_040: [If parameter handle or key is NULL then Map_GetValueFromKey returns NULL.]*/
+    if (
+        (handle == NULL) ||
+        (key == NULL)
+        )
+    {
+        result = NULL;
+        LogError("invalid parameter to Map_GetValueFromKey");
+    }
+    else
+    {
+        MAP_HANDLE_DATA * handleData = (MAP_HANDLE_DATA *)handle;
+        char** whereIsIt = findKey(handleData, key);
+        if(whereIsIt == NULL)
+        {
+            /*Codes_SRS_MAP_02_041: [If the key is not found, then Map_GetValueFromKey returns NULL.]*/
+            result = NULL;
+        }
+        else
+        {
+            /*Codes_SRS_MAP_02_042: [Otherwise, Map_GetValueFromKey returns the key's value.] */
+            size_t index = whereIsIt - handleData->keys;
+            result = handleData->values[index];
+        }
+    }
+    return result;
+}
+
+MAP_RESULT Map_GetInternals(MAP_HANDLE handle, const char*const** keys, const char*const** values, size_t* count)
+{
+    MAP_RESULT result;
+    /*Codes_SRS_MAP_02_046: [If parameter handle, keys, values or count is NULL then Map_GetInternals shall return MAP_INVALIDARG.] */
+    if (
+        (handle == NULL) ||
+        (keys == NULL) ||
+        (values == NULL) ||
+        (count == NULL)
+        )
+    {
+        result = MAP_INVALIDARG;
+        LOG_MAP_ERROR;
+    }
+    else
+    {
+        /*Codes_SRS_MAP_02_043: [Map_GetInternals shall produce in *keys an pointer to an array of const char* having all the keys stored so far by the map.]*/
+        /*Codes_SRS_MAP_02_044: [Map_GetInternals shall produce in *values a pointer to an array of const char* having all the values stored so far by the map.]*/
+        /*Codes_SRS_MAP_02_045: [  Map_GetInternals shall produce in *count the number of stored keys and values.]*/
+        MAP_HANDLE_DATA * handleData = (MAP_HANDLE_DATA *)handle;
+        *keys =(const char* const*)(handleData->keys);
+        *values = (const char* const*)(handleData->values);
+        *count = handleData->count;
+        result = MAP_OK;
+    }
+    return result;
+}
+
+STRING_HANDLE Map_ToJSON(MAP_HANDLE handle)
+{
+    STRING_HANDLE result;
+    /*Codes_SRS_MAP_02_052: [If parameter handle is NULL then Map_ToJSON shall return NULL.] */
+    if (handle == NULL)
+    {
+        result = NULL;
+        LogError("invalid arg (NULL)");
+    }
+    else
+    {
+        /*Codes_SRS_MAP_02_048: [Map_ToJSON shall produce a STRING_HANDLE representing the content of the MAP.] */
+        result = STRING_construct("{");
+        if (result == NULL)
+        {
+            LogError("STRING_construct failed");
+        }
+        else
+        {
+            size_t i;
+            MAP_HANDLE_DATA* handleData = (MAP_HANDLE_DATA *)handle;
+            /*Codes_SRS_MAP_02_049: [If the MAP is empty, then Map_ToJSON shall produce the string "{}".*/
+            bool breakFor = false; /*used to break out of for*/
+            for (i = 0; (i < handleData->count) && (!breakFor); i++)
+            {
+                /*add one entry to the JSON*/
+                /*Codes_SRS_MAP_02_050: [If the map has properties then Map_ToJSON shall produce the following string:{"name1":"value1", "name2":"value2" ...}]*/
+                STRING_HANDLE key = STRING_new_JSON(handleData->keys[i]);
+                if (key == NULL)
+                {
+                    LogError("STRING_new_JSON failed");
+                    STRING_delete(result);
+                    result = NULL;
+                    breakFor = true;
+                }
+                else
+                {
+                    STRING_HANDLE value = STRING_new_JSON(handleData->values[i]);
+                    if (value == NULL)
+                    {
+                        LogError("STRING_new_JSON failed");
+                        STRING_delete(result);
+                        result = NULL;
+                        breakFor = true;
+                    }
+                    else
+                    {
+                        if (!(
+                            ((i>0) ? (STRING_concat(result, ",") == 0) : 1) &&
+                            (STRING_concat_with_STRING(result, key) == 0) &&
+                            (STRING_concat(result, ":") == 0) &&
+                            (STRING_concat_with_STRING(result, value) == 0)
+                            ))
+                        {
+                            LogError("failed to build the JSON");
+                            STRING_delete(result);
+                            result = NULL;
+                            breakFor = true;
+                        }
+                        else
+                        {
+                            /*all nice, go to the next element in the map*/
+                        }
+                        STRING_delete(value);
+                    }
+                    STRING_delete(key);
+                }
+            }
+
+            if (breakFor)
+            {
+                LogError("error happened during JSON string builder");
+            }
+            else
+            {
+                if (STRING_concat(result, "}") != 0)
+                {
+                    LogError("failed to build the JSON");
+                    STRING_delete(result);
+                    result = NULL;
+                }
+                else
+                {
+                    /*return as is, JSON has been build*/
+                }
+            }
+        }
+    }
+    return result;
+
+}
Index: azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/src/optionhandler.c
===================================================================
--- azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/src/optionhandler.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/src/optionhandler.c	(revision 457)
@@ -0,0 +1,268 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+#include <stdlib.h>
+#include "azure_c_shared_utility/optionhandler.h"
+#include "azure_c_shared_utility/xlogging.h"
+#include "azure_c_shared_utility/gballoc.h"
+#include "azure_c_shared_utility/vector.h"
+
+typedef struct OPTION_TAG
+{
+    const char* name;
+    void* storage;
+}OPTION;
+
+typedef struct OPTIONHANDLER_HANDLE_DATA_TAG
+{
+    pfCloneOption cloneOption;
+    pfDestroyOption destroyOption;
+    pfSetOption setOption;
+    VECTOR_HANDLE storage;
+}OPTIONHANDLER_HANDLE_DATA;
+
+static OPTIONHANDLER_HANDLE CreateInternal(pfCloneOption cloneOption, pfDestroyOption destroyOption, pfSetOption setOption)
+{
+    OPTIONHANDLER_HANDLE result;
+
+    result = (OPTIONHANDLER_HANDLE_DATA*)malloc(sizeof(OPTIONHANDLER_HANDLE_DATA));
+    if (result == NULL)
+    {
+        /*Codes_SRS_OPTIONHANDLER_02_004: [ Otherwise, OptionHandler_Create shall fail and return NULL. ]*/
+        LogError("unable to malloc");
+        /*return as is*/
+    }
+    else
+    {
+        /*Codes_SRS_OPTIONHANDLER_02_002: [ OptionHandler_Create shall create an empty VECTOR that will hold pairs of const char* and void*. ]*/
+        result->storage = VECTOR_create(sizeof(OPTION));
+        if (result->storage == NULL)
+        {
+            /*Codes_SRS_OPTIONHANDLER_02_004: [ Otherwise, OptionHandler_Create shall fail and return NULL. ]*/
+            LogError("unable to VECTOR_create");
+            free(result);
+            result = NULL;
+        }
+        else
+        {
+            /*Codes_SRS_OPTIONHANDLER_02_003: [ If all the operations succeed then OptionHandler_Create shall succeed and return a non-NULL handle. ]*/
+            result->cloneOption = cloneOption;
+            result->destroyOption = destroyOption;
+            result->setOption = setOption;
+            /*return as is*/
+        }
+    }
+
+    return result;
+}
+
+static OPTIONHANDLER_RESULT AddOptionInternal(OPTIONHANDLER_HANDLE handle, const char* name, const void* value)
+{
+    OPTIONHANDLER_RESULT result;
+    const char* cloneOfName;
+    if (mallocAndStrcpy_s((char**)&cloneOfName, name) != 0)
+    {
+        /*Codes_SRS_OPTIONHANDLER_02_009: [ Otherwise, OptionHandler_AddProperty shall succeed and return OPTIONHANDLER_ERROR. ]*/
+        LogError("unable to clone name");
+        result = OPTIONHANDLER_ERROR;
+    }
+    else
+    {
+        /*Codes_SRS_OPTIONHANDLER_02_006: [ OptionHandler_AddProperty shall call pfCloneOption passing name and value. ]*/
+        void* cloneOfValue = handle->cloneOption(name, value);
+        if (cloneOfValue == NULL)
+        {
+            /*Codes_SRS_OPTIONHANDLER_02_009: [ Otherwise, OptionHandler_AddProperty shall succeed and return OPTIONHANDLER_ERROR. ]*/
+            LogError("unable to clone value");
+            free((void*)cloneOfName);
+            result = OPTIONHANDLER_ERROR;
+        }
+        else
+        {
+            OPTION temp;
+            temp.name = cloneOfName;
+            temp.storage = cloneOfValue;
+            /*Codes_SRS_OPTIONHANDLER_02_007: [ OptionHandler_AddProperty shall use VECTOR APIs to save the name and the newly created clone of value. ]*/
+            if (VECTOR_push_back(handle->storage, &temp, 1) != 0)
+            {
+                /*Codes_SRS_OPTIONHANDLER_02_009: [ Otherwise, OptionHandler_AddProperty shall succeed and return OPTIONHANDLER_ERROR. ]*/
+                LogError("unable to VECTOR_push_back");
+                handle->destroyOption(name, cloneOfValue);
+                free((void*)cloneOfName);
+                result = OPTIONHANDLER_ERROR;
+            }
+            else
+            {
+                /*Codes_SRS_OPTIONHANDLER_02_008: [ If all the operations succed then OptionHandler_AddProperty shall succeed and return OPTIONHANDLER_OK. ]*/
+                result = OPTIONHANDLER_OK;
+            }
+        }
+    }
+
+    return result;
+}
+
+static void DestroyInternal(OPTIONHANDLER_HANDLE handle)
+{
+    /*Codes_SRS_OPTIONHANDLER_02_016: [ Otherwise, OptionHandler_Destroy shall free all used resources. ]*/
+    size_t nOptions = VECTOR_size(handle->storage), i;
+    for (i = 0; i < nOptions; i++)
+    {
+        OPTION* option = (OPTION*)VECTOR_element(handle->storage, i);
+        handle->destroyOption(option->name, option->storage);
+        free((void*)option->name);
+    }
+
+    VECTOR_destroy(handle->storage);
+    free(handle);
+}
+
+OPTIONHANDLER_HANDLE OptionHandler_Create(pfCloneOption cloneOption, pfDestroyOption destroyOption, pfSetOption setOption)
+{
+    /*Codes_SRS_OPTIONHANDLER_02_001: [ OptionHandler_Create shall fail and retun NULL if any parameters are NULL. ]*/
+    OPTIONHANDLER_HANDLE_DATA* result;
+    if (
+        (cloneOption == NULL) ||
+        (destroyOption == NULL) ||
+        (setOption == NULL)
+        )
+    {
+        LogError("invalid parameter = pfCloneOption cloneOption=%p, pfDestroyOption destroyOption=%p, pfSetOption setOption=%p", cloneOption, destroyOption, setOption);
+        result = NULL;
+    }
+    else
+    {
+        result = CreateInternal(cloneOption, destroyOption, setOption);
+    }
+
+    return result;
+
+}
+
+OPTIONHANDLER_HANDLE OptionHandler_Clone(OPTIONHANDLER_HANDLE handler)
+{
+    OPTIONHANDLER_HANDLE_DATA* result;
+
+    if (handler == NULL)
+    {
+        /* Codes_SRS_OPTIONHANDLER_01_010: [ If handler is NULL, OptionHandler_Clone shall fail and return NULL. ]*/
+        LogError("NULL argument: handler");
+        result = NULL;
+    }
+    else
+    {
+        /* Codes_SRS_OPTIONHANDLER_01_001: [ OptionHandler_Clone shall clone an existing option handler instance. ]*/
+        /* Codes_SRS_OPTIONHANDLER_01_002: [ On success it shall return a non-NULL handle. ]*/
+        /* Codes_SRS_OPTIONHANDLER_01_003: [ OptionHandler_Clone shall allocate memory for the new option handler instance. ]*/
+        result = CreateInternal(handler->cloneOption, handler->destroyOption, handler->setOption);
+        if (result == NULL)
+        {
+            /* Codes_SRS_OPTIONHANDLER_01_004: [ If allocating memory fails, OptionHandler_Clone shall return NULL. ]*/
+            LogError("unable to create option handler");
+        }
+        else
+        {
+            /* Codes_SRS_OPTIONHANDLER_01_005: [ OptionHandler_Clone shall iterate through all the options stored by the option handler to be cloned by using VECTOR's iteration mechanism. ]*/
+            size_t option_count = VECTOR_size(handler->storage);
+            size_t i;
+
+            for (i = 0; i < option_count; i++)
+            {
+                OPTION* option = (OPTION*)VECTOR_element(handler->storage, i);
+
+                /* Codes_SRS_OPTIONHANDLER_01_006: [ For each option the option name shall be cloned by calling mallocAndStrcpy_s. ]*/
+                /* Codes_SRS_OPTIONHANDLER_01_007: [ For each option the value shall be cloned by using the cloning function associated with the source option handler handler. ]*/
+                if (AddOptionInternal(result, option->name, option->storage) != OPTIONHANDLER_OK)
+                {
+                    /* Codes_SRS_OPTIONHANDLER_01_008: [ If cloning one of the option names fails, OptionHandler_Clone shall return NULL. ]*/
+                    /* Codes_SRS_OPTIONHANDLER_01_009: [ If cloning one of the option values fails, OptionHandler_Clone shall return NULL. ]*/
+                    LogError("Error cloning option %s", option->name);
+                    break;
+                }
+            }
+
+            if (i < option_count)
+            {
+                DestroyInternal(result);
+                result = NULL;
+            }
+        }
+    }
+
+    return result;
+}
+
+OPTIONHANDLER_RESULT OptionHandler_AddOption(OPTIONHANDLER_HANDLE handle, const char* name, const void* value)
+{
+    OPTIONHANDLER_RESULT result;
+    /*Codes_SRS_OPTIONHANDLER_02_001: [ OptionHandler_Create shall fail and retun NULL if any parameters are NULL. ]*/
+    if (
+        (handle == NULL) ||
+        (name == NULL) ||
+        (value == NULL)
+        )
+    {
+        LogError("invalid arguments: OPTIONHANDLER_HANDLE handle=%p, const char* name=%p, void* value=%p", handle, name, value);
+        result= OPTIONHANDLER_INVALIDARG;
+    }
+    else
+    {
+        result = AddOptionInternal(handle, name, value);
+    }
+
+    return result;
+}
+
+OPTIONHANDLER_RESULT OptionHandler_FeedOptions(OPTIONHANDLER_HANDLE handle, void* destinationHandle)
+{
+    OPTIONHANDLER_RESULT result;
+    /*Codes_SRS_OPTIONHANDLER_02_010: [ OptionHandler_FeedOptions shall fail and return OPTIONHANDLER_INVALIDARG if any argument is NULL. ]*/
+    if (
+        (handle == NULL) ||
+        (destinationHandle == NULL)
+        )
+    {
+        LogError("invalid arguments OPTIONHANDLER_HANDLE handle=%p, void* destinationHandle=%p", handle, destinationHandle);
+        result = OPTIONHANDLER_INVALIDARG;
+    }
+    else
+    {
+        /*Codes_SRS_OPTIONHANDLER_02_011: [ Otherwise, OptionHandler_FeedOptions shall use VECTOR's iteration mechanisms to retrieve pairs of name, value (const char* and void*). ]*/
+        size_t nOptions = VECTOR_size(handle->storage), i;
+        for (i = 0;i < nOptions;i++)
+        {
+            OPTION* option = (OPTION*)VECTOR_element(handle->storage, i);
+            /*Codes_SRS_OPTIONHANDLER_02_012: [ OptionHandler_FeedOptions shall call for every pair of name,value setOption passing destinationHandle, name and value. ]*/
+            if (handle->setOption(destinationHandle, option->name, option->storage) != 0)
+            {
+                LogError("failure while trying to SetOption with option %s", option->name);
+                break;
+            }
+        }
+
+        if (i == nOptions)
+        {
+            /*Codes_SRS_OPTIONHANDLER_02_014: [ Otherwise, OptionHandler_FeedOptions shall fail and return OPTIONHANDLER_ERROR. ]*/
+            result = OPTIONHANDLER_OK;
+        }
+        else
+        {
+            /*Codes_SRS_OPTIONHANDLER_02_013: [ If all the operations succeed then OptionHandler_FeedOptions shall succeed and return OPTIONHANDLER_OK. ]*/
+            result = OPTIONHANDLER_ERROR;
+        }
+    }
+    return result;
+}
+
+void OptionHandler_Destroy(OPTIONHANDLER_HANDLE handle)
+{
+    /*Codes_SRS_OPTIONHANDLER_02_015: [ OptionHandler_Destroy shall do nothing if parameter handle is NULL. ]*/
+    if (handle == NULL)
+    {
+        LogError("invalid argument OPTIONHANDLER_HANDLE handle=%p", handle);
+    }
+    else
+    {
+        DestroyInternal(handle);
+    }
+}
Index: azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/src/sastoken.c
===================================================================
--- azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/src/sastoken.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/src/sastoken.c	(revision 457)
@@ -0,0 +1,346 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include "azure_c_shared_utility/gballoc.h"
+#include "azure_c_shared_utility/sastoken.h"
+#include "azure_c_shared_utility/urlencode.h"
+#include "azure_c_shared_utility/hmacsha256.h"
+#include "azure_c_shared_utility/azure_base64.h"
+#include "azure_c_shared_utility/agenttime.h"
+#include "azure_c_shared_utility/strings.h"
+#include "azure_c_shared_utility/buffer_.h"
+#include "azure_c_shared_utility/xlogging.h"
+#include "azure_c_shared_utility/crt_abstractions.h"
+
+static double getExpiryValue(const char* expiryASCII)
+{
+    double value = 0;
+    size_t i = 0;
+    for (i = 0; expiryASCII[i] != '\0'; i++)
+    {
+        if (expiryASCII[i] >= '0' && expiryASCII[i] <= '9')
+        {
+            value = value * 10 + (double)(expiryASCII[i] - '0');
+        }
+        else
+        {
+            value = 0;
+            break;
+        }
+    }
+    return value;
+}
+
+bool SASToken_Validate(STRING_HANDLE sasToken)
+{
+    bool result;
+    /*Codes_SRS_SASTOKEN_25_025: [**SASToken_Validate shall get the SASToken value by invoking STRING_c_str on the handle.**]***/
+    const char* sasTokenArray = STRING_c_str(sasToken);
+
+    /* Codes_SRS_SASTOKEN_25_024: [**If handle is NULL then SASToken_Validate shall return false.**] */
+    /* Codes_SRS_SASTOKEN_25_026: [**If STRING_c_str on handle return NULL then SASToken_Validate shall return false.**] */
+    if (sasToken == NULL || sasTokenArray == NULL)
+    {
+        result = false;
+    }
+    else
+    {
+        int seStart = -1, seStop = -1;
+        int srStart = -1, srStop = -1;
+        int sigStart = -1, sigStop = -1;
+        int tokenLength = (int)STRING_length(sasToken);
+        int i;
+        for (i = 0; i < tokenLength; i++)
+        {
+            if (sasTokenArray[i] == 's' && sasTokenArray[i + 1] == 'e' && sasTokenArray[i + 2] == '=') // Look for se=
+            {
+                seStart = i + 3;
+                if (srStart > 0 && srStop < 0)
+                {
+                    if (sasTokenArray[i - 1] != '&' && sasTokenArray[i - 1] == ' ') // look for either & or space
+                        srStop = i - 1;
+                    else if (sasTokenArray[i - 1] == '&')
+                        srStop = i - 2;
+                    else
+                        seStart = -1; // as the format is not either "&se=" or " se="
+                }
+                else if (sigStart > 0 && sigStop < 0)
+                {
+                    if (sasTokenArray[i - 1] != '&' && sasTokenArray[i - 1] == ' ')
+                        sigStop = i - 1;
+                    else if (sasTokenArray[i - 1] == '&')
+                        sigStop = i - 2;
+                    else
+                        seStart = -1;
+                }
+            }
+            else if (sasTokenArray[i] == 's' && sasTokenArray[i + 1] == 'r' && sasTokenArray[i + 2] == '=') // Look for sr=
+            {
+                srStart = i + 3;
+                if (seStart > 0 && seStop < 0)
+                {
+                    if (sasTokenArray[i - 1] != '&' && sasTokenArray[i - 1] == ' ')
+                        seStop = i - 1;
+                    else if (sasTokenArray[i - 1] == '&')
+                        seStop = i - 2;
+                    else
+                        srStart = -1;
+                }
+                else if (sigStart > 0 && sigStop < 0)
+                {
+                    if (sasTokenArray[i - 1] != '&' && sasTokenArray[i - 1] == ' ')
+                        sigStop = i - 1;
+                    else if (sasTokenArray[i - 1] == '&')
+                        sigStop = i - 2;
+                    else
+                        srStart = -1;
+                }
+            }
+            else if (sasTokenArray[i] == 's' && sasTokenArray[i + 1] == 'i' && sasTokenArray[i + 2] == 'g' && sasTokenArray[i + 3] == '=') // Look for sig=
+            {
+                sigStart = i + 4;
+                if (srStart > 0 && srStop < 0)
+                {
+                    if (sasTokenArray[i - 1] != '&' && sasTokenArray[i - 1] == ' ')
+                        srStop = i - 1;
+                    else if (sasTokenArray[i - 1] == '&')
+                        srStop = i - 2;
+                    else
+                        sigStart = -1;
+                }
+                else if (seStart > 0 && seStop < 0)
+                {
+                    if (sasTokenArray[i - 1] != '&' && sasTokenArray[i - 1] == ' ')
+                        seStop = i - 1;
+                    else if (sasTokenArray[i - 1] == '&')
+                        seStop = i - 2;
+                    else
+                        sigStart = -1;
+                }
+            }
+        }
+
+        /*Codes_SRS_SASTOKEN_25_027: [**If SASTOKEN does not obey the SASToken format then SASToken_Validate shall return false.**]***/
+        /*Codes_SRS_SASTOKEN_25_028: [**SASToken_validate shall check for the presence of sr, se and sig from the token and return false if not found**]***/
+        if (seStart < 0 || srStart < 0 || sigStart < 0)
+        {
+            result = false;
+        }
+        else
+        {
+            if (seStop < 0)
+            {
+                seStop = tokenLength;
+            }
+            else if (srStop < 0)
+            {
+                srStop = tokenLength;
+            }
+            else if (sigStop < 0)
+            {
+                sigStop = tokenLength;
+            }
+
+            if ((seStop <= seStart) ||
+                (srStop <= srStart) ||
+                (sigStop <= sigStart))
+            {
+                result = false;
+            }
+            else
+            {
+                char* expiryASCII = (char*)malloc(seStop - seStart + 1);
+                /*Codes_SRS_SASTOKEN_25_031: [**If malloc fails during validation then SASToken_Validate shall return false.**]***/
+                if (expiryASCII == NULL)
+                {
+                    result = false;
+                }
+                else
+                {
+                    double expiry;
+                    // Add the Null terminator here
+                    memset(expiryASCII, 0, seStop - seStart + 1);
+                    for (i = seStart; i < seStop; i++)
+                    {
+                        // The se contains the expiration values, if a & token is encountered then
+                        // the se field is complete.
+                        if (sasTokenArray[i] == '&')
+                        {
+                            break;
+                        }
+                        expiryASCII[i - seStart] = sasTokenArray[i];
+                    }
+                    expiry = getExpiryValue(expiryASCII);
+                    /*Codes_SRS_SASTOKEN_25_029: [**SASToken_validate shall check for expiry time from token and if token has expired then would return false **]***/
+                    if (expiry <= 0)
+                    {
+                        result = false;
+                    }
+                    else
+                    {
+                        double secSinceEpoch = get_difftime(get_time(NULL), (time_t)0);
+                        if (expiry < secSinceEpoch)
+                        {
+                            /*Codes_SRS_SASTOKEN_25_029: [**SASToken_validate shall check for expiry time from token and if token has expired then would return false **]***/
+                            result = false;
+                        }
+                        else
+                        {
+                            /*Codes_SRS_SASTOKEN_25_030: [**SASToken_validate shall return true only if the format is obeyed and the token has not yet expired **]***/
+                            result = true;
+                        }
+                    }
+                    free(expiryASCII);
+                }
+            }
+        }
+    }
+
+    return result;
+}
+
+static STRING_HANDLE construct_sas_token(const char* key, const char* scope, const char* keyname, size_t expiry)
+{
+    STRING_HANDLE result;
+
+    char tokenExpirationTime[32] = { 0 };
+
+    BUFFER_HANDLE decodedKey;
+
+    /*Codes_SRS_SASTOKEN_06_029: [The key parameter is decoded from base64.]*/
+    if ((decodedKey = Azure_Base64_Decode(key)) == NULL)
+    {
+        /*Codes_SRS_SASTOKEN_06_030: [If there is an error in the decoding then SASToken_Create shall return NULL.]*/
+        LogError("Unable to decode the key for generating the SAS.");
+        result = NULL;
+    }
+    else
+    {
+        /*Codes_SRS_SASTOKEN_06_026: [If the conversion to string form fails for any reason then SASToken_Create shall return NULL.]*/
+        if (size_tToString(tokenExpirationTime, sizeof(tokenExpirationTime), expiry) != 0)
+        {
+            LogError("For some reason converting seconds to a string failed.  No SAS can be generated.");
+            result = NULL;
+        }
+        else
+        {
+            STRING_HANDLE toBeHashed = NULL;
+            BUFFER_HANDLE hash = NULL;
+            if (((hash = BUFFER_new()) == NULL) ||
+                ((toBeHashed = STRING_new()) == NULL) ||
+                ((result = STRING_new()) == NULL))
+            {
+                LogError("Unable to allocate memory to prepare SAS token.");
+                result = NULL;
+            }
+            else
+            {
+                /*Codes_SRS_SASTOKEN_06_009: [The scope is the basis for creating a STRING_HANDLE.]*/
+                /*Codes_SRS_SASTOKEN_06_010: [A "\n" is appended to that string.]*/
+                /*Codes_SRS_SASTOKEN_06_011: [tokenExpirationTime is appended to that string.]*/
+                if ((STRING_concat(toBeHashed, scope) != 0) ||
+                    (STRING_concat(toBeHashed, "\n") != 0) ||
+                    (STRING_concat(toBeHashed, tokenExpirationTime) != 0))
+                {
+                    LogError("Unable to build the input to the HMAC to prepare SAS token.");
+                    STRING_delete(result);
+                    result = NULL;
+                }
+                else
+                {
+                    STRING_HANDLE base64Signature = NULL;
+                    STRING_HANDLE urlEncodedSignature = NULL;
+                    size_t inLen = STRING_length(toBeHashed);
+                    const unsigned char* inBuf = (const unsigned char*)STRING_c_str(toBeHashed);
+                    size_t outLen = BUFFER_length(decodedKey);
+                    unsigned char* outBuf = BUFFER_u_char(decodedKey);
+                    /*Codes_SRS_SASTOKEN_06_013: [If an error is returned from the HMAC256 function then NULL is returned from SASToken_Create.]*/
+                    /*Codes_SRS_SASTOKEN_06_012: [An HMAC256 hash is calculated using the decodedKey, over toBeHashed.]*/
+                    /*Codes_SRS_SASTOKEN_06_014: [If there are any errors from the following operations then NULL shall be returned.]*/
+                    /*Codes_SRS_SASTOKEN_06_015: [The hash is base 64 encoded.]*/
+                    /*Codes_SRS_SASTOKEN_06_028: [base64Signature shall be url encoded.]*/
+                    /*Codes_SRS_SASTOKEN_06_016: [The string "SharedAccessSignature sr=" is the first part of the result of SASToken_Create.]*/
+                    /*Codes_SRS_SASTOKEN_06_017: [The scope parameter is appended to result.]*/
+                    /*Codes_SRS_SASTOKEN_06_018: [The string "&sig=" is appended to result.]*/
+                    /*Codes_SRS_SASTOKEN_06_019: [The string urlEncodedSignature shall be appended to result.]*/
+                    /*Codes_SRS_SASTOKEN_06_020: [The string "&se=" shall be appended to result.]*/
+                    /*Codes_SRS_SASTOKEN_06_021: [tokenExpirationTime is appended to result.]*/
+                    /*Codes_SRS_SASTOKEN_06_022: [If keyName is non-NULL, the string "&skn=" is appended to result.]*/
+                    /*Codes_SRS_SASTOKEN_06_023: [If keyName is non-NULL, the argument keyName is appended to result.]*/
+                    if ((HMACSHA256_ComputeHash(outBuf, outLen, inBuf, inLen, hash) != HMACSHA256_OK) ||
+                        ((base64Signature = Azure_Base64_Encode(hash)) == NULL) ||
+                        ((urlEncodedSignature = URL_Encode(base64Signature)) == NULL) ||
+                        (STRING_copy(result, "SharedAccessSignature sr=") != 0) ||
+                        (STRING_concat(result, scope) != 0) ||
+                        (STRING_concat(result, "&sig=") != 0) ||
+                        (STRING_concat_with_STRING(result, urlEncodedSignature) != 0) ||
+                        (STRING_concat(result, "&se=") != 0) ||
+                        (STRING_concat(result, tokenExpirationTime) != 0) ||
+                        ((keyname != NULL) && (STRING_concat(result, "&skn=") != 0)) ||
+                        ((keyname != NULL) && (STRING_concat(result, keyname) != 0)))
+                    {
+                        LogError("Unable to build the SAS token.");
+                        STRING_delete(result);
+                        result = NULL;
+                    }
+                    else
+                    {
+                        /* everything OK */
+                    }
+                    STRING_delete(base64Signature);
+                    STRING_delete(urlEncodedSignature);
+                }
+            }
+            STRING_delete(toBeHashed);
+            BUFFER_delete(hash);
+        }
+        BUFFER_delete(decodedKey);
+    }
+    return result;
+}
+
+STRING_HANDLE SASToken_Create(STRING_HANDLE key, STRING_HANDLE scope, STRING_HANDLE keyName, size_t expiry)
+{
+    STRING_HANDLE result;
+
+    /*Codes_SRS_SASTOKEN_06_001: [If key is NULL then SASToken_Create shall return NULL.]*/
+    /*Codes_SRS_SASTOKEN_06_003: [If scope is NULL then SASToken_Create shall return NULL.]*/
+    /*Codes_SRS_SASTOKEN_06_007: [keyName is optional and can be set to NULL.]*/
+    if ((key == NULL) ||
+        (scope == NULL))
+    {
+        LogError("Invalid Parameter to SASToken_Create. handle key: %p, handle scope: %p, handle keyName: %p", key, scope, keyName);
+        result = NULL;
+    }
+    else
+    {
+        const char* string_key = STRING_c_str(key);
+        const char* string_scope = STRING_c_str(scope);
+        const char* string_name = STRING_c_str(keyName);
+        result = construct_sas_token(string_key, string_scope, string_name, expiry);
+    }
+    return result;
+}
+
+STRING_HANDLE SASToken_CreateString(const char* key, const char* scope, const char* keyName, size_t expiry)
+{
+    STRING_HANDLE result;
+
+    /*Codes_SRS_SASTOKEN_06_001: [If key is NULL then SASToken_Create shall return NULL.]*/
+    /*Codes_SRS_SASTOKEN_06_003: [If scope is NULL then SASToken_Create shall return NULL.]*/
+    /*Codes_SRS_SASTOKEN_06_007: [keyName is optional and can be set to NULL.]*/
+    if ((key == NULL) ||
+        (scope == NULL))
+    {
+        LogError("Invalid Parameter to SASToken_Create. handle key: %p, handle scope: %p, handle keyName: %p", key, scope, keyName);
+        result = NULL;
+    }
+    else
+    {
+        result = construct_sas_token(key, scope, keyName, expiry);
+    }
+    return result;
+}
Index: azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/src/sha1.c
===================================================================
--- azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/src/sha1.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/src/sha1.c	(revision 457)
@@ -0,0 +1,445 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+/**************************** sha1.c ****************************/
+/******************** See RFC 4634 for details ******************/
+/*
+*  Description:
+*      This file implements the Secure Hash Signature Standard
+*      algorithms as defined in the National Institute of Standards
+*      and Technology Federal Information Processing Standards
+*      Publication (FIPS PUB) 180-1 published on April 17, 1995, 180-2
+*      published on August 1, 2002, and the FIPS PUB 180-2 Change
+*      Notice published on February 28, 2004.
+*
+*      A combined document showing all algorithms is available at
+*              http://csrc.nist.gov/publications/fips/
+*              fips180-2/fips180-2withchangenotice.pdf
+*
+*      The SHA-1 algorithm produces a 160-bit message digest for a
+*      given data stream.  It should take about 2**n steps to find a
+*      message with the same digest as a given message and
+*      2**(n/2) to find any two messages with the same digest,
+*      when n is the digest size in bits.  Therefore, this
+*      algorithm can serve as a means of providing a
+*      "fingerprint" for a message.
+*
+*  Portability Issues:
+*      SHA-1 is defined in terms of 32-bit "words".  This code
+*      uses <stdint.h> (included via "sha.h") to define 32 and 8
+*      bit unsigned integer types.  If your C compiler does not
+*      support 32 bit unsigned integers, this code is not
+*      appropriate.
+*
+*  Caveats:
+*      SHA-1 is designed to work with messages less than 2^64 bits
+*      long. This implementation uses SHA1Input() to hash the bits
+*      that are a multiple of the size of an 8-bit character, and then
+*      uses SHA1FinalBits() to hash the final few bits of the input.
+*/
+
+#include <stdlib.h>
+#include "azure_c_shared_utility/gballoc.h"
+
+#include "azure_c_shared_utility/sha.h"
+#include "azure_c_shared_utility/sha-private.h"
+
+/*
+*  Define the SHA1 circular left shift macro
+*/
+#define SHA1_ROTL(bits,word) \
+                (((word) << (bits)) | ((word) >> (32-(bits))))
+
+/*
+* add "length" to the length
+*/
+#define SHA1AddLength(context, length)                     \
+    (addTemp = (context)->Length_Low,                      \
+     (context)->Corrupted =                                \
+        (((context)->Length_Low += (length)) < addTemp) && \
+        (++(context)->Length_High == 0) ? 1 : 0)
+
+/* Local Function Prototypes */
+static void SHA1Finalize(SHA1Context *context, uint8_t Pad_Byte);
+static void SHA1PadMessage(SHA1Context *, uint8_t Pad_Byte);
+static void SHA1ProcessMessageBlock(SHA1Context *);
+
+/*
+*  SHA1Reset
+*
+*  Description:
+*      This function will initialize the SHA1Context in preparation
+*      for computing a new SHA1 message digest.
+*
+*  Parameters:
+*      context: [in/out]
+*          The context to reset.
+*
+*  Returns:
+*      sha Error Code.
+*
+*/
+int SHA1Reset(SHA1Context *context)
+{
+    if (!context)
+        return shaNull;
+
+    context->Length_Low = 0;
+    context->Length_High = 0;
+    context->Message_Block_Index = 0;
+
+
+    /* Initial Hash Values: FIPS-180-2 section 5.3.1 */
+    context->Intermediate_Hash[0] = 0x67452301;
+    context->Intermediate_Hash[1] = 0xEFCDAB89;
+    context->Intermediate_Hash[2] = 0x98BADCFE;
+    context->Intermediate_Hash[3] = 0x10325476;
+    context->Intermediate_Hash[4] = 0xC3D2E1F0;
+
+    context->Computed = 0;
+    context->Corrupted = 0;
+
+    return shaSuccess;
+}
+
+/*
+*  SHA1Input
+*
+*  Description:
+*      This function accepts an array of octets as the next portion
+*      of the message.
+*
+*  Parameters:
+*      context: [in/out]
+*          The SHA context to update
+*      message_array: [in]
+*          An array of characters representing the next portion of
+*          the message.
+*      length: [in]
+*          The length of the message in message_array
+*
+*  Returns:
+*      sha Error Code.
+*
+*/
+int SHA1Input(SHA1Context *context, const uint8_t *message_array, unsigned int length)
+{
+    int result;
+    uint32_t addTemp;
+    if (!length)
+    {
+        result = shaSuccess;
+    }
+    else if (!context || !message_array)
+    {
+        result = shaNull;
+    }
+    else if (context->Computed) 
+    {
+        result = context->Corrupted = shaStateError;
+    }
+    else if (context->Corrupted)
+    {
+        result = context->Corrupted;
+    }
+    else
+    {
+        while (length-- && !context->Corrupted)
+        {
+            context->Message_Block[context->Message_Block_Index++] = (*message_array & 0xFF);
+
+            if (!SHA1AddLength(context, 8) && (context->Message_Block_Index == SHA1_Message_Block_Size))
+            {
+                SHA1ProcessMessageBlock(context);
+            }
+            message_array++;
+        }
+        result = shaSuccess;
+    }
+    return result;
+}
+
+/*
+* SHA1FinalBits
+*
+* Description:
+*   This function will add in any final bits of the message.
+*
+* Parameters:
+*   context: [in/out]
+*     The SHA context to update
+*   message_bits: [in]
+*     The final bits of the message, in the upper portion of the
+*     byte. (Use 0b###00000 instead of 0b00000### to input the
+*     three bits ###.)
+*   length: [in]
+*     The number of bits in message_bits, between 1 and 7.
+*
+* Returns:
+*   sha Error Code.
+*/
+int SHA1FinalBits(SHA1Context *context, const uint8_t message_bits,
+    unsigned int length)
+{
+    uint32_t addTemp;
+
+    uint8_t masks[8] = {
+        /* 0 0b00000000 */ 0x00, /* 1 0b10000000 */ 0x80,
+        /* 2 0b11000000 */ 0xC0, /* 3 0b11100000 */ 0xE0,
+        /* 4 0b11110000 */ 0xF0, /* 5 0b11111000 */ 0xF8,
+        /* 6 0b11111100 */ 0xFC, /* 7 0b11111110 */ 0xFE
+    };
+    uint8_t markbit[8] = {
+        /* 0 0b10000000 */ 0x80, /* 1 0b01000000 */ 0x40,
+        /* 2 0b00100000 */ 0x20, /* 3 0b00010000 */ 0x10,
+        /* 4 0b00001000 */ 0x08, /* 5 0b00000100 */ 0x04,
+        /* 6 0b00000010 */ 0x02, /* 7 0b00000001 */ 0x01
+    };
+
+    if (!length)
+        return shaSuccess;
+
+    if (!context)
+        return shaNull;
+
+    if (context->Computed || (length >= 8) || (length == 0)) {
+        context->Corrupted = shaStateError;
+        return shaStateError;
+    }
+
+    if (context->Corrupted)
+        return context->Corrupted;
+
+    SHA1AddLength(context, length);
+    SHA1Finalize(context,
+        (uint8_t)((message_bits & masks[length]) | markbit[length]));
+
+    return shaSuccess;
+}
+
+/*
+* SHA1Result
+*
+* Description:
+*   This function will return the 160-bit message digest into the
+*   Message_Digest array provided by the caller.
+*   NOTE: The first octet of hash is stored in the 0th element,
+*      the last octet of hash in the 19th element.
+*
+* Parameters:
+*   context: [in/out]
+*     The context to use to calculate the SHA-1 hash.
+*   Message_Digest: [out]
+*     Where the digest is returned.
+*
+* Returns:
+*   sha Error Code.
+*
+*/
+int SHA1Result(SHA1Context *context,
+    uint8_t Message_Digest[SHA1HashSize])
+{
+    int i;
+
+    if (!context || !Message_Digest)
+        return shaNull;
+
+    if (context->Corrupted)
+        return context->Corrupted;
+
+    if (!context->Computed)
+        SHA1Finalize(context, 0x80);
+
+    for (i = 0; i < SHA1HashSize; ++i)
+        Message_Digest[i] = (uint8_t)(context->Intermediate_Hash[i >> 2]
+        >> 8 * (3 - (i & 0x03)));
+
+    return shaSuccess;
+}
+
+/*
+* SHA1Finalize
+*
+* Description:
+*   This helper function finishes off the digest calculations.
+*
+* Parameters:
+*   context: [in/out]
+*     The SHA context to update
+*   Pad_Byte: [in]
+*     The last byte to add to the digest before the 0-padding
+*     and length. This will contain the last bits of the message
+*     followed by another single bit. If the message was an
+*     exact multiple of 8-bits long, Pad_Byte will be 0x80.
+*
+* Returns:
+*   sha Error Code.
+*
+*/
+static void SHA1Finalize(SHA1Context *context, uint8_t Pad_Byte)
+{
+    int i;
+    SHA1PadMessage(context, Pad_Byte);
+    /* message may be sensitive, clear it out */
+    for (i = 0; i < SHA1_Message_Block_Size; ++i)
+        context->Message_Block[i] = 0;
+    context->Length_Low = 0;  /* and clear length */
+    context->Length_High = 0;
+    context->Computed = 1;
+}
+
+/*
+* SHA1PadMessage
+*
+* Description:
+*   According to the standard, the message must be padded to an
+*   even 512 bits. The first padding bit must be a '1'. The last
+*   64 bits represent the length of the original message. All bits
+*   in between should be 0. This helper function will pad the
+*   message according to those rules by filling the Message_Block
+*   array accordingly. When it returns, it can be assumed that the
+*   message digest has been computed.
+*
+* Parameters:
+*   context: [in/out]
+*     The context to pad
+*   Pad_Byte: [in]
+*     The last byte to add to the digest before the 0-padding
+*     and length. This will contain the last bits of the message
+*     followed by another single bit. If the message was an
+*     exact multiple of 8-bits long, Pad_Byte will be 0x80.
+*
+* Returns:
+*   Nothing.
+*/
+static void SHA1PadMessage(SHA1Context *context, uint8_t Pad_Byte)
+{
+    /*
+    * Check to see if the current message block is too small to hold
+    * the initial padding bits and length. If so, we will pad the
+    * block, process it, and then continue padding into a second
+    * block.
+    */
+    if (context->Message_Block_Index >= (SHA1_Message_Block_Size - 8)) {
+        context->Message_Block[context->Message_Block_Index++] = Pad_Byte;
+        while (context->Message_Block_Index < SHA1_Message_Block_Size)
+            context->Message_Block[context->Message_Block_Index++] = 0;
+
+        SHA1ProcessMessageBlock(context);
+    }
+    else
+        context->Message_Block[context->Message_Block_Index++] = Pad_Byte;
+
+    while (context->Message_Block_Index < (SHA1_Message_Block_Size - 8))
+        context->Message_Block[context->Message_Block_Index++] = 0;
+
+    /*
+    * Store the message length as the last 8 octets
+    */
+    context->Message_Block[56] = (uint8_t)(context->Length_High >> 24);
+    context->Message_Block[57] = (uint8_t)(context->Length_High >> 16);
+
+    context->Message_Block[58] = (uint8_t)(context->Length_High >> 8);
+    context->Message_Block[59] = (uint8_t)(context->Length_High);
+    context->Message_Block[60] = (uint8_t)(context->Length_Low >> 24);
+    context->Message_Block[61] = (uint8_t)(context->Length_Low >> 16);
+    context->Message_Block[62] = (uint8_t)(context->Length_Low >> 8);
+    context->Message_Block[63] = (uint8_t)(context->Length_Low);
+
+    SHA1ProcessMessageBlock(context);
+}
+
+/*
+* SHA1ProcessMessageBlock
+*
+* Description:
+*   This helper function will process the next 512 bits of the
+*   message stored in the Message_Block array.
+*
+* Parameters:
+*   None.
+*
+* Returns:
+*   Nothing.
+*
+* Comments:
+*   Many of the variable names in this code, especially the
+*   single character names, were used because those were the
+*   names used in the publication.
+*/
+static void SHA1ProcessMessageBlock(SHA1Context *context)
+{
+    /* Constants defined in FIPS-180-2, section 4.2.1 */
+    const uint32_t K[4] = {
+        0x5A827999, 0x6ED9EBA1, 0x8F1BBCDC, 0xCA62C1D6
+    };
+    int        t;               /* Loop counter */
+    uint32_t   temp;            /* Temporary word value */
+    uint32_t   W[80];           /* Word sequence */
+    uint32_t   A, B, C, D, E;   /* Word buffers */
+
+    /*
+    * Initialize the first 16 words in the array W
+    */
+    for (t = 0; t < 16; t++) {
+        W[t] = ((uint32_t)context->Message_Block[t * 4]) << 24;
+        W[t] |= ((uint32_t)context->Message_Block[t * 4 + 1]) << 16;
+        W[t] |= ((uint32_t)context->Message_Block[t * 4 + 2]) << 8;
+        W[t] |= ((uint32_t)context->Message_Block[t * 4 + 3]);
+    }
+
+    for (t = 16; t < 80; t++)
+        W[t] = SHA1_ROTL(1, W[t - 3] ^ W[t - 8] ^ W[t - 14] ^ W[t - 16]);
+
+    A = context->Intermediate_Hash[0];
+    B = context->Intermediate_Hash[1];
+    C = context->Intermediate_Hash[2];
+    D = context->Intermediate_Hash[3];
+    E = context->Intermediate_Hash[4];
+
+    for (t = 0; t < 20; t++) {
+        temp = SHA1_ROTL(5, A) + SHA_Ch(B, C, D) + E + W[t] + K[0];
+        E = D;
+        D = C;
+        C = SHA1_ROTL(30, B);
+        B = A;
+        A = temp;
+    }
+
+    for (t = 20; t < 40; t++) {
+        temp = SHA1_ROTL(5, A) + SHA_Parity(B, C, D) + E + W[t] + K[1];
+        E = D;
+        D = C;
+        C = SHA1_ROTL(30, B);
+        B = A;
+        A = temp;
+    }
+
+    for (t = 40; t < 60; t++) {
+        temp = SHA1_ROTL(5, A) + SHA_Maj(B, C, D) + E + W[t] + K[2];
+        E = D;
+        D = C;
+        C = SHA1_ROTL(30, B);
+        B = A;
+        A = temp;
+    }
+
+    for (t = 60; t < 80; t++) {
+        temp = SHA1_ROTL(5, A) + SHA_Parity(B, C, D) + E + W[t] + K[3];
+        E = D;
+        D = C;
+        C = SHA1_ROTL(30, B);
+        B = A;
+        A = temp;
+    }
+
+    context->Intermediate_Hash[0] += A;
+    context->Intermediate_Hash[1] += B;
+    context->Intermediate_Hash[2] += C;
+
+    context->Intermediate_Hash[3] += D;
+    context->Intermediate_Hash[4] += E;
+
+    context->Message_Block_Index = 0;
+}
+
Index: azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/src/sha224.c
===================================================================
--- azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/src/sha224.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/src/sha224.c	(revision 457)
@@ -0,0 +1,624 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+/*************************** sha224-256.c ***************************/
+/********************* See RFC 4634 for details *********************/
+/*
+* Description:
+*   This file implements the Secure Hash Signature Standard
+*   algorithms as defined in the National Institute of Standards
+*   and Technology Federal Information Processing Standards
+*   Publication (FIPS PUB) 180-1 published on April 17, 1995, 180-2
+*   published on August 1, 2002, and the FIPS PUB 180-2 Change
+*   Notice published on February 28, 2004.
+*
+*   A combined document showing all algorithms is available at
+*       http://csrc.nist.gov/publications/fips/
+*       fips180-2/fips180-2withchangenotice.pdf
+*
+*   The SHA-224 and SHA-256 algorithms produce 224-bit and 256-bit
+*   message digests for a given data stream. It should take about
+*   2**n steps to find a message with the same digest as a given
+*   message and 2**(n/2) to find any two messages with the same
+*   digest, when n is the digest size in bits. Therefore, this
+*   algorithm can serve as a means of providing a
+*   "fingerprint" for a message.
+*
+* Portability Issues:
+*   SHA-224 and SHA-256 are defined in terms of 32-bit "words".
+*   This code uses <stdint.h> (included via "sha.h") to define 32
+*   and 8 bit unsigned integer types. If your C compiler does not
+*   support 32 bit unsigned integers, this code is not
+*   appropriate.
+*
+* Caveats:
+*   SHA-224 and SHA-256 are designed to work with messages less
+*   than 2^64 bits long. This implementation uses SHA224/256Input()
+*   to hash the bits that are a multiple of the size of an 8-bit
+*   character, and then uses SHA224/256FinalBits() to hash the
+*   final few bits of the input.
+*/
+
+#include <stdlib.h>
+#include <stdint.h>
+
+#include "azure_c_shared_utility/sha.h"
+#include "azure_c_shared_utility/sha-private.h"
+/* Define the SHA shift, rotate left and rotate right macro */
+#define SHA256_SHR(bits,word)      ((word) >> (bits))
+#define SHA256_ROTL(bits,word)                         \
+  (((word) << (bits)) | ((word) >> (32-(bits))))
+#define SHA256_ROTR(bits,word)                         \
+  (((word) >> (bits)) | ((word) << (32-(bits))))
+
+/* Define the SHA SIGMA and sigma macros */
+#define SHA256_SIGMA0(word)   \
+  (SHA256_ROTR( 2,word) ^ SHA256_ROTR(13,word) ^ SHA256_ROTR(22,word))
+#define SHA256_SIGMA1(word)   \
+  (SHA256_ROTR( 6,word) ^ SHA256_ROTR(11,word) ^ SHA256_ROTR(25,word))
+#define SHA256_sigma0(word)   \
+  (SHA256_ROTR( 7,word) ^ SHA256_ROTR(18,word) ^ SHA256_SHR( 3,word))
+#define SHA256_sigma1(word)   \
+  (SHA256_ROTR(17,word) ^ SHA256_ROTR(19,word) ^ SHA256_SHR(10,word))
+
+/*
+* add "length" to the length
+*/
+#define SHA224_256AddLength(context, length)               \
+  (addTemp = (context)->Length_Low, (context)->Corrupted = \
+    (((context)->Length_Low += (length)) < addTemp) &&     \
+    (++(context)->Length_High == 0) ? 1 : 0)
+
+/* Local Function Prototypes */
+static void SHA224_256Finalize(SHA256Context *context, uint8_t Pad_Byte);
+static void SHA224_256PadMessage(SHA256Context *context, uint8_t Pad_Byte);
+static void SHA224_256ProcessMessageBlock(SHA256Context *context);
+static int SHA224_256Reset(SHA256Context *context, uint32_t *H0);
+static int SHA224_256ResultN(SHA256Context *context, uint8_t Message_Digest[], int HashSize);
+
+/* Initial Hash Values: FIPS-180-2 Change Notice 1 */
+static uint32_t SHA224_H0[SHA256HashSize / 4] = {
+    0xC1059ED8, 0x367CD507, 0x3070DD17, 0xF70E5939,
+    0xFFC00B31, 0x68581511, 0x64F98FA7, 0xBEFA4FA4
+};
+
+/* Initial Hash Values: FIPS-180-2 section 5.3.2 */
+static uint32_t SHA256_H0[SHA256HashSize / 4] = {
+    0x6A09E667, 0xBB67AE85, 0x3C6EF372, 0xA54FF53A,
+    0x510E527F, 0x9B05688C, 0x1F83D9AB, 0x5BE0CD19
+};
+
+/*
+* SHA224Reset
+*
+* Description:
+*   This function will initialize the SHA384Context in preparation
+*   for computing a new SHA224 message digest.
+*
+* Parameters:
+*   context: [in/out]
+*     The context to reset.
+*
+* Returns:
+*   sha Error Code.
+*/
+int SHA224Reset(SHA224Context *context)
+{
+    return SHA224_256Reset(context, SHA224_H0);
+}
+
+/*
+* SHA224Input
+*
+* Description:
+*   This function accepts an array of octets as the next portion
+*   of the message.
+*
+* Parameters:
+*   context: [in/out]
+*     The SHA context to update
+*   message_array: [in]
+*     An array of characters representing the next portion of
+*     the message.
+*   length: [in]
+*     The length of the message in message_array
+*
+* Returns:
+*   sha Error Code.
+*
+*/
+int SHA224Input(SHA224Context *context, const uint8_t *message_array, unsigned int length)
+{
+    return SHA256Input(context, message_array, length);
+}
+
+/*
+* SHA224FinalBits
+*
+* Description:
+*   This function will add in any final bits of the message.
+*
+* Parameters:
+*   context: [in/out]
+*     The SHA context to update
+*   message_bits: [in]
+*     The final bits of the message, in the upper portion of the
+*     byte. (Use 0b###00000 instead of 0b00000### to input the
+*     three bits ###.)
+*   length: [in]
+*     The number of bits in message_bits, between 1 and 7.
+*
+* Returns:
+*   sha Error Code.
+*/
+int SHA224FinalBits(SHA224Context *context, const uint8_t message_bits, unsigned int length)
+{
+    return SHA256FinalBits(context, message_bits, length);
+}
+
+/*
+* SHA224Result
+*
+* Description:
+*   This function will return the 224-bit message
+*   digest into the Message_Digest array provided by the caller.
+*   NOTE: The first octet of hash is stored in the 0th element,
+*      the last octet of hash in the 28th element.
+*
+* Parameters:
+*   context: [in/out]
+*     The context to use to calculate the SHA hash.
+*   Message_Digest: [out]
+*     Where the digest is returned.
+*
+* Returns:
+*   sha Error Code.
+*/
+int SHA224Result(SHA224Context *context, uint8_t Message_Digest[SHA224HashSize])
+{
+    return SHA224_256ResultN(context, Message_Digest, SHA224HashSize);
+}
+
+/*
+* SHA256Reset
+*
+* Description:
+*   This function will initialize the SHA256Context in preparation
+*   for computing a new SHA256 message digest.
+*
+* Parameters:
+*   context: [in/out]
+*     The context to reset.
+*
+* Returns:
+*   sha Error Code.
+*/
+int SHA256Reset(SHA256Context *context)
+{
+    return SHA224_256Reset(context, SHA256_H0);
+}
+
+/*
+* SHA256Input
+*
+* Description:
+*   This function accepts an array of octets as the next portion
+*   of the message.
+*
+* Parameters:
+*   context: [in/out]
+*     The SHA context to update
+*   message_array: [in]
+*     An array of characters representing the next portion of
+*     the message.
+*   length: [in]
+*     The length of the message in message_array
+*
+* Returns:
+*   sha Error Code.
+*/
+int SHA256Input(SHA256Context *context, const uint8_t *message_array, unsigned int length)
+{
+    int result;
+    uint32_t addTemp;
+    if (!length)
+    {
+        result = shaSuccess;
+    }
+    else if (!context || !message_array)
+    {
+        result = shaNull;
+    }
+    else if (context->Computed)
+    {
+        result = context->Corrupted = shaStateError;
+    }
+    else if (context->Corrupted)
+    {
+        result = context->Corrupted;
+    }
+    else
+    {
+        while (length-- && !context->Corrupted)
+        {
+            context->Message_Block[context->Message_Block_Index++] = (*message_array & 0xFF);
+
+            if (!SHA224_256AddLength(context, 8) && (context->Message_Block_Index == SHA256_Message_Block_Size))
+            {
+                SHA224_256ProcessMessageBlock(context);
+            }
+            message_array++;
+        }
+        result = shaSuccess;
+    }
+    return result;
+}
+
+/*
+* SHA256FinalBits
+*
+* Description:
+*   This function will add in any final bits of the message.
+*
+* Parameters:
+*   context: [in/out]
+*     The SHA context to update
+*   message_bits: [in]
+*     The final bits of the message, in the upper portion of the
+*     byte. (Use 0b###00000 instead of 0b00000### to input the
+*     three bits ###.)
+*   length: [in]
+*     The number of bits in message_bits, between 1 and 7.
+*
+* Returns:
+*   sha Error Code.
+*/
+int SHA256FinalBits(SHA256Context *context, const uint8_t message_bits, unsigned int length)
+{
+    int result;
+    uint32_t addTemp;
+    uint8_t masks[8] = {
+        /* 0 0b00000000 */ 0x00, /* 1 0b10000000 */ 0x80,
+        /* 2 0b11000000 */ 0xC0, /* 3 0b11100000 */ 0xE0,
+        /* 4 0b11110000 */ 0xF0, /* 5 0b11111000 */ 0xF8,
+        /* 6 0b11111100 */ 0xFC, /* 7 0b11111110 */ 0xFE
+    };
+
+    uint8_t markbit[8] = {
+        /* 0 0b10000000 */ 0x80, /* 1 0b01000000 */ 0x40,
+        /* 2 0b00100000 */ 0x20, /* 3 0b00010000 */ 0x10,
+        /* 4 0b00001000 */ 0x08, /* 5 0b00000100 */ 0x04,
+        /* 6 0b00000010 */ 0x02, /* 7 0b00000001 */ 0x01
+    };
+
+    if (!length)
+    {
+        result = shaSuccess;
+    }
+    else if (!context)
+    {
+        result = shaNull;
+    }
+    else if ((context->Computed) || (length >= 8) || (length == 0))
+    {
+        result = context->Corrupted = shaStateError;
+    }
+    else if (context->Corrupted)
+    {
+        result = context->Corrupted;
+    }
+    else
+    {
+        SHA224_256AddLength(context, length);
+        SHA224_256Finalize(context, (uint8_t)((message_bits & masks[length]) | markbit[length]));
+        result = shaSuccess;
+    }
+    return result;
+}
+
+/*
+* SHA256Result
+*
+* Description:
+*   This function will return the 256-bit message
+*   digest into the Message_Digest array provided by the caller.
+*   NOTE: The first octet of hash is stored in the 0th element,
+*      the last octet of hash in the 32nd element.
+*
+* Parameters:
+*   context: [in/out]
+*     The context to use to calculate the SHA hash.
+*   Message_Digest: [out]
+*     Where the digest is returned.
+*
+* Returns:
+*   sha Error Code.
+*/
+int SHA256Result(SHA256Context *context, uint8_t Message_Digest[SHA256HashSize])
+{
+    return SHA224_256ResultN(context, Message_Digest, SHA256HashSize);
+}
+
+/*
+* SHA224_256Finalize
+*
+* Description:
+*   This helper function finishes off the digest calculations.
+*
+* Parameters:
+*   context: [in/out]
+*     The SHA context to update
+*   Pad_Byte: [in]
+*     The last byte to add to the digest before the 0-padding
+*     and length. This will contain the last bits of the message
+*     followed by another single bit. If the message was an
+*     exact multiple of 8-bits long, Pad_Byte will be 0x80.
+*
+* Returns:
+*   sha Error Code.
+*/
+static void SHA224_256Finalize(SHA256Context *context, uint8_t Pad_Byte)
+{
+    int i;
+    SHA224_256PadMessage(context, Pad_Byte);
+    /* message may be sensitive, so clear it out */
+    for (i = 0; i < SHA256_Message_Block_Size; ++i)
+    {
+        context->Message_Block[i] = 0;
+    }
+    context->Length_Low = 0;  /* and clear length */
+    context->Length_High = 0;
+    context->Computed = 1;
+}
+
+/*
+* SHA224_256PadMessage
+*
+* Description:
+*   According to the standard, the message must be padded to an
+*   even 512 bits. The first padding bit must be a '1'. The
+*   last 64 bits represent the length of the original message.
+*   All bits in between should be 0. This helper function will pad
+*   the message according to those rules by filling the
+*   Message_Block array accordingly. When it returns, it can be
+*   assumed that the message digest has been computed.
+*
+* Parameters:
+*   context: [in/out]
+*     The context to pad
+*   Pad_Byte: [in]
+*     The last byte to add to the digest before the 0-padding
+*     and length. This will contain the last bits of the message
+*     followed by another single bit. If the message was an
+*     exact multiple of 8-bits long, Pad_Byte will be 0x80.
+*
+* Returns:
+*   Nothing.
+*/
+static void SHA224_256PadMessage(SHA256Context *context, uint8_t Pad_Byte)
+{
+    /*
+    * Check to see if the current message block is too small to hold
+    * the initial padding bits and length. If so, we will pad the
+    * block, process it, and then continue padding into a second
+    * block.
+    */
+    if (context->Message_Block_Index >= (SHA256_Message_Block_Size - 8))
+    {
+        context->Message_Block[context->Message_Block_Index++] = Pad_Byte;
+        while (context->Message_Block_Index < SHA256_Message_Block_Size)
+        {
+            context->Message_Block[context->Message_Block_Index++] = 0;
+        }
+        SHA224_256ProcessMessageBlock(context);
+    }
+    else
+    {
+        context->Message_Block[context->Message_Block_Index++] = Pad_Byte;
+    }
+
+    while (context->Message_Block_Index < (SHA256_Message_Block_Size - 8))
+    {
+        context->Message_Block[context->Message_Block_Index++] = 0;
+    }
+
+    /*
+    * Store the message length as the last 8 octets
+    */
+    context->Message_Block[56] = (uint8_t)(context->Length_High >> 24);
+    context->Message_Block[57] = (uint8_t)(context->Length_High >> 16);
+    context->Message_Block[58] = (uint8_t)(context->Length_High >> 8);
+    context->Message_Block[59] = (uint8_t)(context->Length_High);
+    context->Message_Block[60] = (uint8_t)(context->Length_Low >> 24);
+    context->Message_Block[61] = (uint8_t)(context->Length_Low >> 16);
+    context->Message_Block[62] = (uint8_t)(context->Length_Low >> 8);
+    context->Message_Block[63] = (uint8_t)(context->Length_Low);
+
+    SHA224_256ProcessMessageBlock(context);
+}
+
+/*
+* SHA224_256ProcessMessageBlock
+*
+* Description:
+*   This function will process the next 512 bits of the message
+*   stored in the Message_Block array.
+*
+* Parameters:
+*   context: [in/out]
+*     The SHA context to update
+*
+* Returns:
+*   Nothing.
+*
+* Comments:
+*   Many of the variable names in this code, especially the
+*   single character names, were used because those were the
+*   names used in the publication.
+*/
+static void SHA224_256ProcessMessageBlock(SHA256Context *context)
+{
+    /* Constants defined in FIPS-180-2, section 4.2.2 */
+    static const uint32_t K[64] = {
+        0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b,
+        0x59f111f1, 0x923f82a4, 0xab1c5ed5, 0xd807aa98, 0x12835b01,
+        0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7,
+        0xc19bf174, 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc,
+        0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, 0x983e5152,
+        0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147,
+        0x06ca6351, 0x14292967, 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc,
+        0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
+        0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819,
+        0xd6990624, 0xf40e3585, 0x106aa070, 0x19a4c116, 0x1e376c08,
+        0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f,
+        0x682e6ff3, 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
+        0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
+    };
+    int        t, t4;                   /* Loop counter */
+    uint32_t   temp1, temp2;            /* Temporary word value */
+    uint32_t   W[64];                   /* Word sequence */
+    uint32_t   A, B, C, D, E, F, G, H;  /* Word buffers */
+
+    /*
+    * Initialize the first 16 words in the array W
+    */
+    for (t = t4 = 0; t < 16; t++, t4 += 4)
+    {
+        W[t] = (((uint32_t)context->Message_Block[t4]) << 24) |
+            (((uint32_t)context->Message_Block[t4 + 1]) << 16) |
+            (((uint32_t)context->Message_Block[t4 + 2]) << 8) |
+            (((uint32_t)context->Message_Block[t4 + 3]));
+    }
+    for (t = 16; t < 64; t++)
+    {
+        W[t] = SHA256_sigma1(W[t - 2]) + W[t - 7] +
+            SHA256_sigma0(W[t - 15]) + W[t - 16];
+    }
+    A = context->Intermediate_Hash[0];
+    B = context->Intermediate_Hash[1];
+    C = context->Intermediate_Hash[2];
+    D = context->Intermediate_Hash[3];
+    E = context->Intermediate_Hash[4];
+    F = context->Intermediate_Hash[5];
+    G = context->Intermediate_Hash[6];
+    H = context->Intermediate_Hash[7];
+
+    for (t = 0; t < 64; t++)
+    {
+        temp1 = H + SHA256_SIGMA1(E) + SHA_Ch(E, F, G) + K[t] + W[t];
+        temp2 = SHA256_SIGMA0(A) + SHA_Maj(A, B, C);
+        H = G;
+        G = F;
+        F = E;
+        E = D + temp1;
+        D = C;
+        C = B;
+        B = A;
+        A = temp1 + temp2;
+    }
+
+    context->Intermediate_Hash[0] += A;
+    context->Intermediate_Hash[1] += B;
+    context->Intermediate_Hash[2] += C;
+    context->Intermediate_Hash[3] += D;
+    context->Intermediate_Hash[4] += E;
+    context->Intermediate_Hash[5] += F;
+    context->Intermediate_Hash[6] += G;
+    context->Intermediate_Hash[7] += H;
+
+    context->Message_Block_Index = 0;
+}
+
+/*
+* SHA224_256Reset
+*
+* Description:
+*   This helper function will initialize the SHA256Context in
+*   preparation for computing a new SHA256 message digest.
+*
+* Parameters:
+*   context: [in/out]
+*     The context to reset.
+*   H0
+*     The initial hash value to use.
+*
+* Returns:
+*   sha Error Code.
+*/
+static int SHA224_256Reset(SHA256Context *context, uint32_t *H0)
+{
+    int result;
+    if (!context)
+    {
+        result = shaNull;
+    }
+    else
+    {
+        context->Length_Low = 0;
+        context->Length_High = 0;
+        context->Message_Block_Index = 0;
+
+        context->Intermediate_Hash[0] = H0[0];
+        context->Intermediate_Hash[1] = H0[1];
+        context->Intermediate_Hash[2] = H0[2];
+        context->Intermediate_Hash[3] = H0[3];
+        context->Intermediate_Hash[4] = H0[4];
+        context->Intermediate_Hash[5] = H0[5];
+        context->Intermediate_Hash[6] = H0[6];
+        context->Intermediate_Hash[7] = H0[7];
+
+        context->Computed = 0;
+        context->Corrupted = 0;
+        result = shaSuccess;
+    }
+    return result;
+}
+
+/*
+* SHA224_256ResultN
+*
+* Description:
+*   This helper function will return the 224-bit or 256-bit message
+*   digest into the Message_Digest array provided by the caller.
+*   NOTE: The first octet of hash is stored in the 0th element,
+*      the last octet of hash in the 28th/32nd element.
+*
+* Parameters:
+*   context: [in/out]
+*     The context to use to calculate the SHA hash.
+*   Message_Digest: [out]
+*     Where the digest is returned.
+*   HashSize: [in]
+*     The size of the hash, either 28 or 32.
+*
+* Returns:
+*   sha Error Code.
+*/
+static int SHA224_256ResultN(SHA256Context *context, uint8_t Message_Digest[], int HashSize)
+{
+    int result;
+    int i;
+
+    if (!context || !Message_Digest)
+    {
+        result = shaNull;
+    }
+    else if (context->Corrupted)
+    {
+        result = context->Corrupted;
+    }
+    else
+    {
+        if (!context->Computed)
+        {
+            SHA224_256Finalize(context, 0x80);
+        }
+        for (i = 0; i < HashSize; ++i)
+        {
+            Message_Digest[i] = (uint8_t)(context->Intermediate_Hash[i >> 2] >> 8 * (3 - (i & 0x03)));
+        }
+        result = shaSuccess;
+    }
+    return result;
+}
+
Index: azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/src/sha384-512.c
===================================================================
--- azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/src/sha384-512.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/src/sha384-512.c	(revision 457)
@@ -0,0 +1,1046 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+/*************************** sha384-512.c ***************************/
+/********************* See RFC 4634 for details *********************/
+/*
+* Description:
+*   This file implements the Secure Hash Signature Standard
+*   algorithms as defined in the National Institute of Standards
+*   and Technology Federal Information Processing Standards
+*   Publication (FIPS PUB) 180-1 published on April 17, 1995, 180-2
+*   published on August 1, 2002, and the FIPS PUB 180-2 Change
+*   Notice published on February 28, 2004.
+*
+*   A combined document showing all algorithms is available at
+*       http://csrc.nist.gov/publications/fips/
+*       fips180-2/fips180-2withchangenotice.pdf
+*
+*   The SHA-384 and SHA-512 algorithms produce 384-bit and 512-bit
+*   message digests for a given data stream. It should take about
+*   2**n steps to find a message with the same digest as a given
+*   message and 2**(n/2) to find any two messages with the same
+*   digest, when n is the digest size in bits. Therefore, this
+*   algorithm can serve as a means of providing a
+*   "fingerprint" for a message.
+*
+* Portability Issues:
+*   SHA-384 and SHA-512 are defined in terms of 64-bit "words",
+*   but if USE_32BIT_ONLY is #defined, this code is implemented in
+*   terms of 32-bit "words". This code uses <stdint.h> (included
+*   via "sha.h") to define the 64, 32 and 8 bit unsigned integer
+*   types. If your C compiler does not support 64 bit unsigned
+*   integers, and you do not #define USE_32BIT_ONLY, this code is
+*   not appropriate.
+*
+* Caveats:
+*   SHA-384 and SHA-512 are designed to work with messages less
+*   than 2^128 bits long. This implementation uses
+*   SHA384/512Input() to hash the bits that are a multiple of the
+*   size of an 8-bit character, and then uses SHA384/256FinalBits()
+*   to hash the final few bits of the input.
+*
+*/
+
+#include <stdlib.h>
+#include "azure_c_shared_utility/gballoc.h"
+
+#include "azure_c_shared_utility/sha.h"
+#include "azure_c_shared_utility/sha-private.h"
+
+#ifdef USE_32BIT_ONLY
+#error IoTHubClient does not support USE_32BIT_ONLY flag
+/*
+* Define 64-bit arithmetic in terms of 32-bit arithmetic.
+* Each 64-bit number is represented in a 2-word array.
+* All macros are defined such that the result is the last parameter.
+*/
+
+/*
+* Define shift, rotate left and rotate right functions
+*/
+#define SHA512_SHR(bits, word, ret) (                          \
+    /* (((uint64_t)((word))) >> (bits)) */                     \
+    (ret)[0] = (((bits) < 32) && ((bits) >= 0)) ?              \
+      ((word)[0] >> (bits)) : 0,                               \
+    (ret)[1] = ((bits) > 32) ? ((word)[0] >> ((bits) - 32)) :  \
+      ((bits) == 32) ? (word)[0] :                             \
+      ((bits) >= 0) ?                                          \
+        (((word)[0] << (32 - (bits))) |                        \
+        ((word)[1] >> (bits))) : 0 )
+
+#define SHA512_SHL(bits, word, ret) (                          \
+    /* (((uint64_t)(word)) << (bits)) */                       \
+    (ret)[0] = ((bits) > 32) ? ((word)[1] << ((bits) - 32)) :  \
+         ((bits) == 32) ? (word)[1] :                          \
+         ((bits) >= 0) ?                                       \
+           (((word)[0] << (bits)) |                            \
+           ((word)[1] >> (32 - (bits)))) :                     \
+0, \
+(ret)[1] = (((bits) < 32) && ((bits) >= 0)) ? \
+((word)[1] << (bits)) : 0)
+
+/*
+* Define 64-bit OR
+*/
+#define SHA512_OR(word1, word2, ret) (                         \
+    (ret)[0] = (word1)[0] | (word2)[0],                        \
+    (ret)[1] = (word1)[1] | (word2)[1] )
+
+/*
+* Define 64-bit XOR
+*/
+#define SHA512_XOR(word1, word2, ret) (                        \
+    (ret)[0] = (word1)[0] ^ (word2)[0],                        \
+    (ret)[1] = (word1)[1] ^ (word2)[1] )
+
+/*
+* Define 64-bit AND
+*/
+#define SHA512_AND(word1, word2, ret) (                        \
+    (ret)[0] = (word1)[0] & (word2)[0],                        \
+    (ret)[1] = (word1)[1] & (word2)[1] )
+
+/*
+* Define 64-bit TILDA
+*/
+#define SHA512_TILDA(word, ret)                                \
+  ( (ret)[0] = ~(word)[0], (ret)[1] = ~(word)[1] )
+
+/*
+* Define 64-bit ADD
+*/
+#define SHA512_ADD(word1, word2, ret) (                        \
+    (ret)[1] = (word1)[1], (ret)[1] += (word2)[1],             \
+    (ret)[0] = (word1)[0] + (word2)[0] + ((ret)[1] < (word1)[1]) )
+
+/*
+* Add the 4word value in word2 to word1.
+*/
+static uint32_t ADDTO4_temp, ADDTO4_temp2;
+#define SHA512_ADDTO4(word1, word2) (                          \
+    ADDTO4_temp = (word1)[3],                                  \
+    (word1)[3] += (word2)[3],                                  \
+    ADDTO4_temp2 = (word1)[2],                                 \
+    (word1)[2] += (word2)[2] + ((word1)[3] < ADDTO4_temp),     \
+    ADDTO4_temp = (word1)[1],                                  \
+(word1)[1] += (word2)[1] + ((word1)[2] < ADDTO4_temp2), \
+(word1)[0] += (word2)[0] + ((word1)[1] < ADDTO4_temp))
+
+/*
+* Add the 2word value in word2 to word1.
+*/
+static uint32_t ADDTO2_temp;
+#define SHA512_ADDTO2(word1, word2) (                          \
+    ADDTO2_temp = (word1)[1],                                  \
+    (word1)[1] += (word2)[1],                                  \
+    (word1)[0] += (word2)[0] + ((word1)[1] < ADDTO2_temp) )
+
+/*
+* SHA rotate   ((word >> bits) | (word << (64-bits)))
+*/
+static uint32_t ROTR_temp1[2], ROTR_temp2[2];
+#define SHA512_ROTR(bits, word, ret) (                         \
+    SHA512_SHR((bits), (word), ROTR_temp1),                    \
+    SHA512_SHL(64-(bits), (word), ROTR_temp2),                 \
+    SHA512_OR(ROTR_temp1, ROTR_temp2, (ret)) )
+
+/*
+* Define the SHA SIGMA and sigma macros
+*  SHA512_ROTR(28,word) ^ SHA512_ROTR(34,word) ^ SHA512_ROTR(39,word)
+*/
+static uint32_t SIGMA0_temp1[2], SIGMA0_temp2[2],
+SIGMA0_temp3[2], SIGMA0_temp4[2];
+#define SHA512_SIGMA0(word, ret) (                             \
+    SHA512_ROTR(28, (word), SIGMA0_temp1),                     \
+    SHA512_ROTR(34, (word), SIGMA0_temp2),                     \
+    SHA512_ROTR(39, (word), SIGMA0_temp3),                     \
+    SHA512_XOR(SIGMA0_temp2, SIGMA0_temp3, SIGMA0_temp4),      \
+    SHA512_XOR(SIGMA0_temp1, SIGMA0_temp4, (ret)) )
+
+/*
+* SHA512_ROTR(14,word) ^ SHA512_ROTR(18,word) ^ SHA512_ROTR(41,word)
+*/
+static uint32_t SIGMA1_temp1[2], SIGMA1_temp2[2],
+SIGMA1_temp3[2], SIGMA1_temp4[2];
+#define SHA512_SIGMA1(word, ret) (                             \
+    SHA512_ROTR(14, (word), SIGMA1_temp1),                     \
+    SHA512_ROTR(18, (word), SIGMA1_temp2),                     \
+    SHA512_ROTR(41, (word), SIGMA1_temp3),                     \
+    SHA512_XOR(SIGMA1_temp2, SIGMA1_temp3, SIGMA1_temp4),      \
+    SHA512_XOR(SIGMA1_temp1, SIGMA1_temp4, (ret)) )
+
+/*
+* (SHA512_ROTR( 1,word) ^ SHA512_ROTR( 8,word) ^ SHA512_SHR( 7,word))
+*/
+static uint32_t sigma0_temp1[2], sigma0_temp2[2],
+sigma0_temp3[2], sigma0_temp4[2];
+#define SHA512_sigma0(word, ret) (                             \
+    SHA512_ROTR( 1, (word), sigma0_temp1),                     \
+    SHA512_ROTR( 8, (word), sigma0_temp2),                     \
+    SHA512_SHR( 7, (word), sigma0_temp3),                      \
+    SHA512_XOR(sigma0_temp2, sigma0_temp3, sigma0_temp4),      \
+    SHA512_XOR(sigma0_temp1, sigma0_temp4, (ret)) )
+
+/*
+* (SHA512_ROTR(19,word) ^ SHA512_ROTR(61,word) ^ SHA512_SHR( 6,word))
+*/
+static uint32_t sigma1_temp1[2], sigma1_temp2[2],
+sigma1_temp3[2], sigma1_temp4[2];
+#define SHA512_sigma1(word, ret) (                             \
+    SHA512_ROTR(19, (word), sigma1_temp1),                     \
+    SHA512_ROTR(61, (word), sigma1_temp2),                     \
+    SHA512_SHR( 6, (word), sigma1_temp3),                      \
+    SHA512_XOR(sigma1_temp2, sigma1_temp3, sigma1_temp4),      \
+    SHA512_XOR(sigma1_temp1, sigma1_temp4, (ret)) )
+
+#undef SHA_Ch
+#undef SHA_Maj
+
+#ifndef USE_MODIFIED_MACROS
+/*
+* These definitions are the ones used in FIPS-180-2, section 4.1.3
+*  Ch(x,y,z)   ((x & y) ^ (~x & z))
+*/
+static uint32_t Ch_temp1[2], Ch_temp2[2], Ch_temp3[2];
+#define SHA_Ch(x, y, z, ret) (                                 \
+    SHA512_AND(x, y, Ch_temp1),                                \
+    SHA512_TILDA(x, Ch_temp2),                                 \
+    SHA512_AND(Ch_temp2, z, Ch_temp3),                         \
+    SHA512_XOR(Ch_temp1, Ch_temp3, (ret)) )
+/*
+*  Maj(x,y,z)  (((x)&(y)) ^ ((x)&(z)) ^ ((y)&(z)))
+*/
+static uint32_t Maj_temp1[2], Maj_temp2[2],
+Maj_temp3[2], Maj_temp4[2];
+#define SHA_Maj(x, y, z, ret) (                                \
+    SHA512_AND(x, y, Maj_temp1),                               \
+    SHA512_AND(x, z, Maj_temp2),                               \
+    SHA512_AND(y, z, Maj_temp3),                               \
+    SHA512_XOR(Maj_temp2, Maj_temp3, Maj_temp4),               \
+    SHA512_XOR(Maj_temp1, Maj_temp4, (ret)) )
+
+#else /* !USE_32BIT_ONLY */
+/*
+* These definitions are potentially faster equivalents for the ones
+* used in FIPS-180-2, section 4.1.3.
+*   ((x & y) ^ (~x & z)) becomes
+*   ((x & (y ^ z)) ^ z)
+*/
+#define SHA_Ch(x, y, z, ret) (                                 \
+   (ret)[0] = (((x)[0] & ((y)[0] ^ (z)[0])) ^ (z)[0]),         \
+   (ret)[1] = (((x)[1] & ((y)[1] ^ (z)[1])) ^ (z)[1]) )
+
+/*
+*   ((x & y) ^ (x & z) ^ (y & z)) becomes
+*   ((x & (y | z)) | (y & z))
+*/
+#define SHA_Maj(x, y, z, ret) (                                 \
+   ret[0] = (((x)[0] & ((y)[0] | (z)[0])) | ((y)[0] & (z)[0])), \
+   ret[1] = (((x)[1] & ((y)[1] | (z)[1])) | ((y)[1] & (z)[1])) )
+#endif /* USE_MODIFIED_MACROS */
+
+/*
+* add "length" to the length
+*/
+static uint32_t addTemp[4] = { 0, 0, 0, 0 };
+#define SHA384_512AddLength(context, length) (                        \
+    addTemp[3] = (length), SHA512_ADDTO4((context)->Length, addTemp), \
+    (context)->Corrupted = (((context)->Length[3] == 0) &&            \
+       ((context)->Length[2] == 0) && ((context)->Length[1] == 0) &&  \
+       ((context)->Length[0] < 8)) ? 1 : 0 )
+
+/* Local Function Prototypes */
+static void SHA384_512Finalize(SHA512Context *context,
+    uint8_t Pad_Byte);
+static void SHA384_512PadMessage(SHA512Context *context,
+    uint8_t Pad_Byte);
+static void SHA384_512ProcessMessageBlock(SHA512Context *context);
+static int SHA384_512Reset(SHA512Context *context, uint32_t H0[]);
+static int SHA384_512ResultN(SHA512Context *context,
+    uint8_t Message_Digest[], int HashSize);
+
+/* Initial Hash Values: FIPS-180-2 sections 5.3.3 and 5.3.4 */
+static uint32_t SHA384_H0[SHA512HashSize / 4] = {
+    0xCBBB9D5D, 0xC1059ED8, 0x629A292A, 0x367CD507, 0x9159015A,
+    0x3070DD17, 0x152FECD8, 0xF70E5939, 0x67332667, 0xFFC00B31,
+    0x8EB44A87, 0x68581511, 0xDB0C2E0D, 0x64F98FA7, 0x47B5481D,
+    0xBEFA4FA4
+};
+
+static uint32_t SHA512_H0[SHA512HashSize / 4] = {
+    0x6A09E667, 0xF3BCC908, 0xBB67AE85, 0x84CAA73B, 0x3C6EF372,
+    0xFE94F82B, 0xA54FF53A, 0x5F1D36F1, 0x510E527F, 0xADE682D1,
+    0x9B05688C, 0x2B3E6C1F, 0x1F83D9AB, 0xFB41BD6B, 0x5BE0CD19,
+    0x137E2179
+};
+
+#else /* !USE_32BIT_ONLY */
+
+/* Define the SHA shift, rotate left and rotate right macro */
+#define SHA512_SHR(bits,word)  (((uint64_t)(word)) >> (bits))
+#define SHA512_ROTR(bits,word) ((((uint64_t)(word)) >> (bits)) | \
+                                (((uint64_t)(word)) << (64-(bits))))
+
+/* Define the SHA SIGMA and sigma macros */
+#define SHA512_SIGMA0(word)   \
+ (SHA512_ROTR(28,word) ^ SHA512_ROTR(34,word) ^ SHA512_ROTR(39,word))
+#define SHA512_SIGMA1(word)   \
+ (SHA512_ROTR(14,word) ^ SHA512_ROTR(18,word) ^ SHA512_ROTR(41,word))
+#define SHA512_sigma0(word)   \
+ (SHA512_ROTR( 1,word) ^ SHA512_ROTR( 8,word) ^ SHA512_SHR( 7,word))
+#define SHA512_sigma1(word)   \
+ (SHA512_ROTR(19,word) ^ SHA512_ROTR(61,word) ^ SHA512_SHR( 6,word))
+
+/*
+* add "length" to the length
+*/
+#define SHA384_512AddLength(context, length)                   \
+   (addTemp = context->Length_Low, context->Corrupted =        \
+    ((context->Length_Low += length) < addTemp) &&             \
+    (++context->Length_High == 0) ? 1 : 0)
+
+/* Local Function Prototypes */
+static void SHA384_512Finalize(SHA512Context *context,
+    uint8_t Pad_Byte);
+static void SHA384_512PadMessage(SHA512Context *context,
+    uint8_t Pad_Byte);
+static void SHA384_512ProcessMessageBlock(SHA512Context *context);
+static int SHA384_512Reset(SHA512Context *context, uint64_t H0[]);
+static int SHA384_512ResultN(SHA512Context *context,
+    uint8_t Message_Digest[], int HashSize);
+
+/* Initial Hash Values: FIPS-180-2 sections 5.3.3 and 5.3.4 */
+static uint64_t SHA384_H0[] = {
+    0xCBBB9D5DC1059ED8ull, 0x629A292A367CD507ull, 0x9159015A3070DD17ull,
+    0x152FECD8F70E5939ull, 0x67332667FFC00B31ull, 0x8EB44A8768581511ull,
+    0xDB0C2E0D64F98FA7ull, 0x47B5481DBEFA4FA4ull
+};
+static uint64_t SHA512_H0[] = {
+    0x6A09E667F3BCC908ull, 0xBB67AE8584CAA73Bull, 0x3C6EF372FE94F82Bull,
+    0xA54FF53A5F1D36F1ull, 0x510E527FADE682D1ull, 0x9B05688C2B3E6C1Full,
+    0x1F83D9ABFB41BD6Bull, 0x5BE0CD19137E2179ull
+};
+
+#endif /* USE_32BIT_ONLY */
+
+/*
+* SHA384Reset
+*
+* Description:
+*   This function will initialize the SHA384Context in preparation
+*   for computing a new SHA384 message digest.
+*
+* Parameters:
+*   context: [in/out]
+*     The context to reset.
+*
+* Returns:
+*   sha Error Code.
+*
+*/
+int SHA384Reset(SHA384Context *context)
+{
+    return SHA384_512Reset(context, SHA384_H0);
+}
+
+/*
+* SHA384Input
+*
+* Description:
+*   This function accepts an array of octets as the next portion
+*   of the message.
+*
+* Parameters:
+*   context: [in/out]
+*     The SHA context to update
+*   message_array: [in]
+*     An array of characters representing the next portion of
+*     the message.
+*   length: [in]
+*     The length of the message in message_array
+*
+* Returns:
+*   sha Error Code.
+*
+*/
+int SHA384Input(SHA384Context *context,
+    const uint8_t *message_array, unsigned int length)
+{
+    return SHA512Input(context, message_array, length);
+}
+
+/*
+* SHA384FinalBits
+*
+* Description:
+*   This function will add in any final bits of the message.
+*
+* Parameters:
+*   context: [in/out]
+*     The SHA context to update
+*   message_bits: [in]
+*     The final bits of the message, in the upper portion of the
+*     byte. (Use 0b###00000 instead of 0b00000### to input the
+*     three bits ###.)
+*   length: [in]
+*     The number of bits in message_bits, between 1 and 7.
+*
+* Returns:
+*   sha Error Code.
+*
+*/
+int SHA384FinalBits(SHA384Context *context,
+    const uint8_t message_bits, unsigned int length)
+{
+    return SHA512FinalBits(context, message_bits, length);
+}
+
+/*
+* SHA384Result
+*
+* Description:
+*   This function will return the 384-bit message
+*   digest into the Message_Digest array provided by the caller.
+*   NOTE: The first octet of hash is stored in the 0th element,
+*      the last octet of hash in the 48th element.
+*
+* Parameters:
+*   context: [in/out]
+*     The context to use to calculate the SHA hash.
+*   Message_Digest: [out]
+*     Where the digest is returned.
+*
+* Returns:
+*   sha Error Code.
+*
+*/
+int SHA384Result(SHA384Context *context,
+    uint8_t Message_Digest[SHA384HashSize])
+{
+    return SHA384_512ResultN(context, Message_Digest, SHA384HashSize);
+}
+
+/*
+* SHA512Reset
+*
+* Description:
+*   This function will initialize the SHA512Context in preparation
+*   for computing a new SHA512 message digest.
+*
+* Parameters:
+*   context: [in/out]
+*     The context to reset.
+*
+* Returns:
+*   sha Error Code.
+*
+*/
+int SHA512Reset(SHA512Context *context)
+{
+    return SHA384_512Reset(context, SHA512_H0);
+}
+
+/*
+* SHA512Input
+*
+* Description:
+*   This function accepts an array of octets as the next portion
+*   of the message.
+*
+* Parameters:
+*   context: [in/out]
+*     The SHA context to update
+*   message_array: [in]
+*     An array of characters representing the next portion of
+*     the message.
+*   length: [in]
+*     The length of the message in message_array
+*
+* Returns:
+*   sha Error Code.
+*
+*/
+int SHA512Input(SHA512Context *context,
+    const uint8_t *message_array,
+    unsigned int length)
+{
+    uint64_t addTemp;
+    if (!length)
+        return shaSuccess;
+
+    if (!context || !message_array)
+        return shaNull;
+
+    if (context->Computed) {
+        context->Corrupted = shaStateError;
+        return shaStateError;
+    }
+
+    if (context->Corrupted)
+        return context->Corrupted;
+
+    while (length-- && !context->Corrupted) {
+        context->Message_Block[context->Message_Block_Index++] =
+            (*message_array & 0xFF);
+
+        if (!SHA384_512AddLength(context, 8) &&
+            (context->Message_Block_Index == SHA512_Message_Block_Size))
+            SHA384_512ProcessMessageBlock(context);
+
+        message_array++;
+    }
+
+    return shaSuccess;
+}
+
+/*
+* SHA512FinalBits
+*
+* Description:
+*   This function will add in any final bits of the message.
+*
+* Parameters:
+*   context: [in/out]
+*     The SHA context to update
+*   message_bits: [in]
+*     The final bits of the message, in the upper portion of the
+*     byte. (Use 0b###00000 instead of 0b00000### to input the
+*     three bits ###.)
+*   length: [in]
+*     The number of bits in message_bits, between 1 and 7.
+*
+* Returns:
+*   sha Error Code.
+*
+*/
+int SHA512FinalBits(SHA512Context *context,
+    const uint8_t message_bits, unsigned int length)
+{
+    uint64_t addTemp;
+    uint8_t masks[8] = {
+        /* 0 0b00000000 */ 0x00, /* 1 0b10000000 */ 0x80,
+        /* 2 0b11000000 */ 0xC0, /* 3 0b11100000 */ 0xE0,
+        /* 4 0b11110000 */ 0xF0, /* 5 0b11111000 */ 0xF8,
+        /* 6 0b11111100 */ 0xFC, /* 7 0b11111110 */ 0xFE
+    };
+    uint8_t markbit[8] = {
+        /* 0 0b10000000 */ 0x80, /* 1 0b01000000 */ 0x40,
+        /* 2 0b00100000 */ 0x20, /* 3 0b00010000 */ 0x10,
+        /* 4 0b00001000 */ 0x08, /* 5 0b00000100 */ 0x04,
+        /* 6 0b00000010 */ 0x02, /* 7 0b00000001 */ 0x01
+    };
+
+    if (!length)
+        return shaSuccess;
+
+    if (!context)
+        return shaNull;
+
+    if ((context->Computed) || (length >= 8) || (length == 0)) {
+        context->Corrupted = shaStateError;
+        return shaStateError;
+    }
+
+    if (context->Corrupted)
+        return context->Corrupted;
+
+    SHA384_512AddLength(context, length);
+    SHA384_512Finalize(context, (uint8_t)
+        ((message_bits & masks[length]) | markbit[length]));
+
+    return shaSuccess;
+}
+
+/*
+* SHA384_512Finalize
+*
+* Description:
+*   This helper function finishes off the digest calculations.
+*
+* Parameters:
+*   context: [in/out]
+*     The SHA context to update
+*   Pad_Byte: [in]
+*     The last byte to add to the digest before the 0-padding
+*     and length. This will contain the last bits of the message
+*     followed by another single bit. If the message was an
+*     exact multiple of 8-bits long, Pad_Byte will be 0x80.
+*
+* Returns:
+*   sha Error Code.
+*
+*/
+static void SHA384_512Finalize(SHA512Context *context,
+    uint8_t Pad_Byte)
+{
+    int_least16_t i;
+    SHA384_512PadMessage(context, Pad_Byte);
+    /* message may be sensitive, clear it out */
+    for (i = 0; i < SHA512_Message_Block_Size; ++i)
+        context->Message_Block[i] = 0;
+#ifdef USE_32BIT_ONLY    /* and clear length */
+    context->Length[0] = context->Length[1] = 0;
+    context->Length[2] = context->Length[3] = 0;
+#else /* !USE_32BIT_ONLY */
+    context->Length_Low = 0;
+    context->Length_High = 0;
+#endif /* USE_32BIT_ONLY */
+    context->Computed = 1;
+}
+
+/*
+* SHA512Result
+*
+* Description:
+*   This function will return the 512-bit message
+*   digest into the Message_Digest array provided by the caller.
+*   NOTE: The first octet of hash is stored in the 0th element,
+*      the last octet of hash in the 64th element.
+*
+* Parameters:
+*   context: [in/out]
+*     The context to use to calculate the SHA hash.
+*   Message_Digest: [out]
+*     Where the digest is returned.
+*
+* Returns:
+*   sha Error Code.
+*
+*/
+int SHA512Result(SHA512Context *context,
+    uint8_t Message_Digest[SHA512HashSize])
+{
+    return SHA384_512ResultN(context, Message_Digest, SHA512HashSize);
+}
+
+/*
+* SHA384_512PadMessage
+*
+* Description:
+*   According to the standard, the message must be padded to an
+*   even 1024 bits. The first padding bit must be a '1'. The
+*   last 128 bits represent the length of the original message.
+*   All bits in between should be 0. This helper function will
+*   pad the message according to those rules by filling the
+*   Message_Block array accordingly. When it returns, it can be
+*   assumed that the message digest has been computed.
+*
+* Parameters:
+*   context: [in/out]
+*     The context to pad
+*   Pad_Byte: [in]
+*     The last byte to add to the digest before the 0-padding
+*     and length. This will contain the last bits of the message
+*     followed by another single bit. If the message was an
+*     exact multiple of 8-bits long, Pad_Byte will be 0x80.
+*
+* Returns:
+*   Nothing.
+*
+*/
+static void SHA384_512PadMessage(SHA512Context *context,
+    uint8_t Pad_Byte)
+{
+    /*
+    * Check to see if the current message block is too small to hold
+    * the initial padding bits and length. If so, we will pad the
+    * block, process it, and then continue padding into a second
+    * block.
+    */
+    if (context->Message_Block_Index >= (SHA512_Message_Block_Size - 16)) {
+        context->Message_Block[context->Message_Block_Index++] = Pad_Byte;
+        while (context->Message_Block_Index < SHA512_Message_Block_Size)
+            context->Message_Block[context->Message_Block_Index++] = 0;
+
+        SHA384_512ProcessMessageBlock(context);
+    }
+    else
+        context->Message_Block[context->Message_Block_Index++] = Pad_Byte;
+
+    while (context->Message_Block_Index < (SHA512_Message_Block_Size - 16))
+        context->Message_Block[context->Message_Block_Index++] = 0;
+
+    /*
+    * Store the message length as the last 16 octets
+    */
+#ifdef USE_32BIT_ONLY
+    context->Message_Block[112] = (uint8_t)(context->Length[0] >> 24);
+    context->Message_Block[113] = (uint8_t)(context->Length[0] >> 16);
+    context->Message_Block[114] = (uint8_t)(context->Length[0] >> 8);
+    context->Message_Block[115] = (uint8_t)(context->Length[0]);
+    context->Message_Block[116] = (uint8_t)(context->Length[1] >> 24);
+    context->Message_Block[117] = (uint8_t)(context->Length[1] >> 16);
+    context->Message_Block[118] = (uint8_t)(context->Length[1] >> 8);
+    context->Message_Block[119] = (uint8_t)(context->Length[1]);
+
+    context->Message_Block[120] = (uint8_t)(context->Length[2] >> 24);
+    context->Message_Block[121] = (uint8_t)(context->Length[2] >> 16);
+    context->Message_Block[122] = (uint8_t)(context->Length[2] >> 8);
+    context->Message_Block[123] = (uint8_t)(context->Length[2]);
+    context->Message_Block[124] = (uint8_t)(context->Length[3] >> 24);
+    context->Message_Block[125] = (uint8_t)(context->Length[3] >> 16);
+    context->Message_Block[126] = (uint8_t)(context->Length[3] >> 8);
+    context->Message_Block[127] = (uint8_t)(context->Length[3]);
+#else /* !USE_32BIT_ONLY */
+    context->Message_Block[112] = (uint8_t)(context->Length_High >> 56);
+    context->Message_Block[113] = (uint8_t)(context->Length_High >> 48);
+    context->Message_Block[114] = (uint8_t)(context->Length_High >> 40);
+    context->Message_Block[115] = (uint8_t)(context->Length_High >> 32);
+    context->Message_Block[116] = (uint8_t)(context->Length_High >> 24);
+    context->Message_Block[117] = (uint8_t)(context->Length_High >> 16);
+    context->Message_Block[118] = (uint8_t)(context->Length_High >> 8);
+    context->Message_Block[119] = (uint8_t)(context->Length_High);
+
+    context->Message_Block[120] = (uint8_t)(context->Length_Low >> 56);
+    context->Message_Block[121] = (uint8_t)(context->Length_Low >> 48);
+    context->Message_Block[122] = (uint8_t)(context->Length_Low >> 40);
+    context->Message_Block[123] = (uint8_t)(context->Length_Low >> 32);
+    context->Message_Block[124] = (uint8_t)(context->Length_Low >> 24);
+    context->Message_Block[125] = (uint8_t)(context->Length_Low >> 16);
+    context->Message_Block[126] = (uint8_t)(context->Length_Low >> 8);
+    context->Message_Block[127] = (uint8_t)(context->Length_Low);
+#endif /* USE_32BIT_ONLY */
+
+    SHA384_512ProcessMessageBlock(context);
+}
+
+/*
+* SHA384_512ProcessMessageBlock
+*
+* Description:
+*   This helper function will process the next 1024 bits of the
+*   message stored in the Message_Block array.
+*
+* Parameters:
+*   context: [in/out]
+*     The SHA context to update
+*
+* Returns:
+*   Nothing.
+*
+* Comments:
+*   Many of the variable names in this code, especially the
+*   single character names, were used because those were the
+*   names used in the publication.
+*
+*
+*/
+static void SHA384_512ProcessMessageBlock(SHA512Context *context)
+{
+    /* Constants defined in FIPS-180-2, section 4.2.3 */
+#ifdef USE_32BIT_ONLY
+    static const uint32_t K[80 * 2] = {
+        0x428A2F98, 0xD728AE22, 0x71374491, 0x23EF65CD, 0xB5C0FBCF,
+        0xEC4D3B2F, 0xE9B5DBA5, 0x8189DBBC, 0x3956C25B, 0xF348B538,
+        0x59F111F1, 0xB605D019, 0x923F82A4, 0xAF194F9B, 0xAB1C5ED5,
+        0xDA6D8118, 0xD807AA98, 0xA3030242, 0x12835B01, 0x45706FBE,
+        0x243185BE, 0x4EE4B28C, 0x550C7DC3, 0xD5FFB4E2, 0x72BE5D74,
+        0xF27B896F, 0x80DEB1FE, 0x3B1696B1, 0x9BDC06A7, 0x25C71235,
+        0xC19BF174, 0xCF692694, 0xE49B69C1, 0x9EF14AD2, 0xEFBE4786,
+        0x384F25E3, 0x0FC19DC6, 0x8B8CD5B5, 0x240CA1CC, 0x77AC9C65,
+        0x2DE92C6F, 0x592B0275, 0x4A7484AA, 0x6EA6E483, 0x5CB0A9DC,
+        0xBD41FBD4, 0x76F988DA, 0x831153B5, 0x983E5152, 0xEE66DFAB,
+        0xA831C66D, 0x2DB43210, 0xB00327C8, 0x98FB213F, 0xBF597FC7,
+        0xBEEF0EE4, 0xC6E00BF3, 0x3DA88FC2, 0xD5A79147, 0x930AA725,
+        0x06CA6351, 0xE003826F, 0x14292967, 0x0A0E6E70, 0x27B70A85,
+        0x46D22FFC, 0x2E1B2138, 0x5C26C926, 0x4D2C6DFC, 0x5AC42AED,
+        0x53380D13, 0x9D95B3DF, 0x650A7354, 0x8BAF63DE, 0x766A0ABB,
+        0x3C77B2A8, 0x81C2C92E, 0x47EDAEE6, 0x92722C85, 0x1482353B,
+        0xA2BFE8A1, 0x4CF10364, 0xA81A664B, 0xBC423001, 0xC24B8B70,
+        0xD0F89791, 0xC76C51A3, 0x0654BE30, 0xD192E819, 0xD6EF5218,
+        0xD6990624, 0x5565A910, 0xF40E3585, 0x5771202A, 0x106AA070,
+        0x32BBD1B8, 0x19A4C116, 0xB8D2D0C8, 0x1E376C08, 0x5141AB53,
+        0x2748774C, 0xDF8EEB99, 0x34B0BCB5, 0xE19B48A8, 0x391C0CB3,
+        0xC5C95A63, 0x4ED8AA4A, 0xE3418ACB, 0x5B9CCA4F, 0x7763E373,
+        0x682E6FF3, 0xD6B2B8A3, 0x748F82EE, 0x5DEFB2FC, 0x78A5636F,
+        0x43172F60, 0x84C87814, 0xA1F0AB72, 0x8CC70208, 0x1A6439EC,
+        0x90BEFFFA, 0x23631E28, 0xA4506CEB, 0xDE82BDE9, 0xBEF9A3F7,
+        0xB2C67915, 0xC67178F2, 0xE372532B, 0xCA273ECE, 0xEA26619C,
+        0xD186B8C7, 0x21C0C207, 0xEADA7DD6, 0xCDE0EB1E, 0xF57D4F7F,
+        0xEE6ED178, 0x06F067AA, 0x72176FBA, 0x0A637DC5, 0xA2C898A6,
+        0x113F9804, 0xBEF90DAE, 0x1B710B35, 0x131C471B, 0x28DB77F5,
+        0x23047D84, 0x32CAAB7B, 0x40C72493, 0x3C9EBE0A, 0x15C9BEBC,
+        0x431D67C4, 0x9C100D4C, 0x4CC5D4BE, 0xCB3E42B6, 0x597F299C,
+        0xFC657E2A, 0x5FCB6FAB, 0x3AD6FAEC, 0x6C44198C, 0x4A475817
+    };
+    int     t, t2, t8;                  /* Loop counter */
+    uint32_t  temp1[2], temp2[2],       /* Temporary word values */
+        temp3[2], temp4[2], temp5[2];
+    uint32_t  W[2 * 80];                  /* Word sequence */
+    uint32_t  A[2], B[2], C[2], D[2],   /* Word buffers */
+        E[2], F[2], G[2], H[2];
+
+    /* Initialize the first 16 words in the array W */
+    for (t = t2 = t8 = 0; t < 16; t++, t8 += 8) {
+        W[t2++] = ((((uint32_t)context->Message_Block[t8])) << 24) |
+            ((((uint32_t)context->Message_Block[t8 + 1])) << 16) |
+            ((((uint32_t)context->Message_Block[t8 + 2])) << 8) |
+            ((((uint32_t)context->Message_Block[t8 + 3])));
+        W[t2++] = ((((uint32_t)context->Message_Block[t8 + 4])) << 24) |
+            ((((uint32_t)context->Message_Block[t8 + 5])) << 16) |
+            ((((uint32_t)context->Message_Block[t8 + 6])) << 8) |
+            ((((uint32_t)context->Message_Block[t8 + 7])));
+    }
+
+    for (t = 16; t < 80; t++, t2 += 2) {
+        /* W[t] = SHA512_sigma1(W[t-2]) + W[t-7] +
+        SHA512_sigma0(W[t-15]) + W[t-16]; */
+        uint32_t *Wt2 = &W[t2 - 2 * 2];
+        uint32_t *Wt7 = &W[t2 - 7 * 2];
+        uint32_t *Wt15 = &W[t2 - 15 * 2];
+        uint32_t *Wt16 = &W[t2 - 16 * 2];
+        SHA512_sigma1(Wt2, temp1);
+        SHA512_ADD(temp1, Wt7, temp2);
+        SHA512_sigma0(Wt15, temp1);
+        SHA512_ADD(temp1, Wt16, temp3);
+        SHA512_ADD(temp2, temp3, &W[t2]);
+    }
+
+    A[0] = context->Intermediate_Hash[0];
+    A[1] = context->Intermediate_Hash[1];
+    B[0] = context->Intermediate_Hash[2];
+    B[1] = context->Intermediate_Hash[3];
+    C[0] = context->Intermediate_Hash[4];
+    C[1] = context->Intermediate_Hash[5];
+    D[0] = context->Intermediate_Hash[6];
+    D[1] = context->Intermediate_Hash[7];
+    E[0] = context->Intermediate_Hash[8];
+    E[1] = context->Intermediate_Hash[9];
+    F[0] = context->Intermediate_Hash[10];
+    F[1] = context->Intermediate_Hash[11];
+    G[0] = context->Intermediate_Hash[12];
+    G[1] = context->Intermediate_Hash[13];
+    H[0] = context->Intermediate_Hash[14];
+    H[1] = context->Intermediate_Hash[15];
+
+    for (t = t2 = 0; t < 80; t++, t2 += 2) {
+        /*
+        * temp1 = H + SHA512_SIGMA1(E) + SHA_Ch(E,F,G) + K[t] + W[t];
+        */
+        SHA512_SIGMA1(E, temp1);
+        SHA512_ADD(H, temp1, temp2);
+        SHA_Ch(E, F, G, temp3);
+        SHA512_ADD(temp2, temp3, temp4);
+        SHA512_ADD(&K[t2], &W[t2], temp5);
+        SHA512_ADD(temp4, temp5, temp1);
+        /*
+        * temp2 = SHA512_SIGMA0(A) + SHA_Maj(A,B,C);
+        */
+        SHA512_SIGMA0(A, temp3);
+        SHA_Maj(A, B, C, temp4);
+        SHA512_ADD(temp3, temp4, temp2);
+        H[0] = G[0]; H[1] = G[1];
+        G[0] = F[0]; G[1] = F[1];
+        F[0] = E[0]; F[1] = E[1];
+        SHA512_ADD(D, temp1, E);
+        D[0] = C[0]; D[1] = C[1];
+        C[0] = B[0]; C[1] = B[1];
+        B[0] = A[0]; B[1] = A[1];
+        SHA512_ADD(temp1, temp2, A);
+    }
+
+    SHA512_ADDTO2(&context->Intermediate_Hash[0], A);
+    SHA512_ADDTO2(&context->Intermediate_Hash[2], B);
+    SHA512_ADDTO2(&context->Intermediate_Hash[4], C);
+    SHA512_ADDTO2(&context->Intermediate_Hash[6], D);
+    SHA512_ADDTO2(&context->Intermediate_Hash[8], E);
+    SHA512_ADDTO2(&context->Intermediate_Hash[10], F);
+    SHA512_ADDTO2(&context->Intermediate_Hash[12], G);
+    SHA512_ADDTO2(&context->Intermediate_Hash[14], H);
+
+#else /* !USE_32BIT_ONLY */
+    static const uint64_t K[80] = {
+        0x428A2F98D728AE22ull, 0x7137449123EF65CDull, 0xB5C0FBCFEC4D3B2Full,
+        0xE9B5DBA58189DBBCull, 0x3956C25BF348B538ull, 0x59F111F1B605D019ull,
+        0x923F82A4AF194F9Bull, 0xAB1C5ED5DA6D8118ull, 0xD807AA98A3030242ull,
+        0x12835B0145706FBEull, 0x243185BE4EE4B28Cull, 0x550C7DC3D5FFB4E2ull,
+        0x72BE5D74F27B896Full, 0x80DEB1FE3B1696B1ull, 0x9BDC06A725C71235ull,
+        0xC19BF174CF692694ull, 0xE49B69C19EF14AD2ull, 0xEFBE4786384F25E3ull,
+        0x0FC19DC68B8CD5B5ull, 0x240CA1CC77AC9C65ull, 0x2DE92C6F592B0275ull,
+        0x4A7484AA6EA6E483ull, 0x5CB0A9DCBD41FBD4ull, 0x76F988DA831153B5ull,
+        0x983E5152EE66DFABull, 0xA831C66D2DB43210ull, 0xB00327C898FB213Full,
+        0xBF597FC7BEEF0EE4ull, 0xC6E00BF33DA88FC2ull, 0xD5A79147930AA725ull,
+        0x06CA6351E003826Full, 0x142929670A0E6E70ull, 0x27B70A8546D22FFCull,
+        0x2E1B21385C26C926ull, 0x4D2C6DFC5AC42AEDull, 0x53380D139D95B3DFull,
+        0x650A73548BAF63DEull, 0x766A0ABB3C77B2A8ull, 0x81C2C92E47EDAEE6ull,
+        0x92722C851482353Bull, 0xA2BFE8A14CF10364ull, 0xA81A664BBC423001ull,
+        0xC24B8B70D0F89791ull, 0xC76C51A30654BE30ull, 0xD192E819D6EF5218ull,
+        0xD69906245565A910ull, 0xF40E35855771202Aull, 0x106AA07032BBD1B8ull,
+        0x19A4C116B8D2D0C8ull, 0x1E376C085141AB53ull, 0x2748774CDF8EEB99ull,
+        0x34B0BCB5E19B48A8ull, 0x391C0CB3C5C95A63ull, 0x4ED8AA4AE3418ACBull,
+        0x5B9CCA4F7763E373ull, 0x682E6FF3D6B2B8A3ull, 0x748F82EE5DEFB2FCull,
+        0x78A5636F43172F60ull, 0x84C87814A1F0AB72ull, 0x8CC702081A6439ECull,
+        0x90BEFFFA23631E28ull, 0xA4506CEBDE82BDE9ull, 0xBEF9A3F7B2C67915ull,
+        0xC67178F2E372532Bull, 0xCA273ECEEA26619Cull, 0xD186B8C721C0C207ull,
+        0xEADA7DD6CDE0EB1Eull, 0xF57D4F7FEE6ED178ull, 0x06F067AA72176FBAull,
+        0x0A637DC5A2C898A6ull, 0x113F9804BEF90DAEull, 0x1B710B35131C471Bull,
+        0x28DB77F523047D84ull, 0x32CAAB7B40C72493ull, 0x3C9EBE0A15C9BEBCull,
+        0x431D67C49C100D4Cull, 0x4CC5D4BECB3E42B6ull, 0x597F299CFC657E2Aull,
+        0x5FCB6FAB3AD6FAECull, 0x6C44198C4A475817ull
+    };
+    int        t, t8;                   /* Loop counter */
+    uint64_t   temp1, temp2;            /* Temporary word value */
+    uint64_t   W[80];                   /* Word sequence */
+    uint64_t   A, B, C, D, E, F, G, H;  /* Word buffers */
+
+    /*
+    * Initialize the first 16 words in the array W
+    */
+    for (t = t8 = 0; t < 16; t++, t8 += 8)
+        W[t] = ((uint64_t)(context->Message_Block[t8]) << 56) |
+        ((uint64_t)(context->Message_Block[t8 + 1]) << 48) |
+        ((uint64_t)(context->Message_Block[t8 + 2]) << 40) |
+        ((uint64_t)(context->Message_Block[t8 + 3]) << 32) |
+        ((uint64_t)(context->Message_Block[t8 + 4]) << 24) |
+        ((uint64_t)(context->Message_Block[t8 + 5]) << 16) |
+        ((uint64_t)(context->Message_Block[t8 + 6]) << 8) |
+        ((uint64_t)(context->Message_Block[t8 + 7]));
+
+    for (t = 16; t < 80; t++)
+        W[t] = SHA512_sigma1(W[t - 2]) + W[t - 7] +
+        SHA512_sigma0(W[t - 15]) + W[t - 16];
+
+    A = context->Intermediate_Hash[0];
+    B = context->Intermediate_Hash[1];
+    C = context->Intermediate_Hash[2];
+    D = context->Intermediate_Hash[3];
+    E = context->Intermediate_Hash[4];
+    F = context->Intermediate_Hash[5];
+    G = context->Intermediate_Hash[6];
+    H = context->Intermediate_Hash[7];
+
+    for (t = 0; t < 80; t++) {
+        temp1 = H + SHA512_SIGMA1(E) + SHA_Ch(E, F, G) + K[t] + W[t];
+        temp2 = SHA512_SIGMA0(A) + SHA_Maj(A, B, C);
+        H = G;
+        G = F;
+        F = E;
+        E = D + temp1;
+        D = C;
+        C = B;
+        B = A;
+        A = temp1 + temp2;
+    }
+
+    context->Intermediate_Hash[0] += A;
+    context->Intermediate_Hash[1] += B;
+    context->Intermediate_Hash[2] += C;
+    context->Intermediate_Hash[3] += D;
+    context->Intermediate_Hash[4] += E;
+    context->Intermediate_Hash[5] += F;
+    context->Intermediate_Hash[6] += G;
+    context->Intermediate_Hash[7] += H;
+#endif /* USE_32BIT_ONLY */
+
+    context->Message_Block_Index = 0;
+}
+
+/*
+* SHA384_512Reset
+*
+* Description:
+*   This helper function will initialize the SHA512Context in
+*   preparation for computing a new SHA384 or SHA512 message
+*   digest.
+*
+* Parameters:
+*   context: [in/out]
+*     The context to reset.
+*   H0
+*     The initial hash value to use.
+*
+* Returns:
+*   sha Error Code.
+*
+*/
+#ifdef USE_32BIT_ONLY
+static int SHA384_512Reset(SHA512Context *context, uint32_t H0[])
+#else /* !USE_32BIT_ONLY */
+static int SHA384_512Reset(SHA512Context *context, uint64_t H0[])
+#endif /* USE_32BIT_ONLY */
+{
+    int i;
+    if (!context)
+        return shaNull;
+
+    context->Message_Block_Index = 0;
+
+#ifdef USE_32BIT_ONLY
+    context->Length[0] = context->Length[1] = 0;
+    context->Length[2] = context->Length[3] = 0;
+
+    for (i = 0; i < SHA512HashSize / 4; i++)
+        context->Intermediate_Hash[i] = H0[i];
+#else /* !USE_32BIT_ONLY */
+    context->Length_High = context->Length_Low = 0;
+
+    for (i = 0; i < SHA512HashSize / 8; i++)
+        context->Intermediate_Hash[i] = H0[i];
+#endif /* USE_32BIT_ONLY */
+
+    context->Computed = 0;
+    context->Corrupted = 0;
+
+    return shaSuccess;
+}
+
+/*
+* SHA384_512ResultN
+*
+* Description:
+*   This helper function will return the 384-bit or 512-bit message
+*   digest into the Message_Digest array provided by the caller.
+*   NOTE: The first octet of hash is stored in the 0th element,
+*      the last octet of hash in the 48th/64th element.
+*
+* Parameters:
+*   context: [in/out]
+*     The context to use to calculate the SHA hash.
+*   Message_Digest: [out]
+*     Where the digest is returned.
+*   HashSize: [in]
+*     The size of the hash, either 48 or 64.
+*
+* Returns:
+*   sha Error Code.
+*
+*/
+static int SHA384_512ResultN(SHA512Context *context,
+    uint8_t Message_Digest[], int HashSize)
+{
+    int i;
+
+#ifdef USE_32BIT_ONLY
+    int i2;
+#endif /* USE_32BIT_ONLY */
+
+    if (!context || !Message_Digest)
+        return shaNull;
+
+    if (context->Corrupted)
+        return context->Corrupted;
+
+    if (!context->Computed)
+        SHA384_512Finalize(context, 0x80);
+
+#ifdef USE_32BIT_ONLY
+    for (i = i2 = 0; i < HashSize;) {
+        Message_Digest[i++] = (uint8_t)(context->Intermediate_Hash[i2] >> 24);
+        Message_Digest[i++] = (uint8_t)(context->Intermediate_Hash[i2] >> 16);
+        Message_Digest[i++] = (uint8_t)(context->Intermediate_Hash[i2] >> 8);
+        Message_Digest[i++] = (uint8_t)(context->Intermediate_Hash[i2++]);
+        Message_Digest[i++] = (uint8_t)(context->Intermediate_Hash[i2] >> 24);
+        Message_Digest[i++] = (uint8_t)(context->Intermediate_Hash[i2] >> 16);
+        Message_Digest[i++] = (uint8_t)(context->Intermediate_Hash[i2] >> 8);
+        Message_Digest[i++] = (uint8_t)(context->Intermediate_Hash[i2++]);
+    }
+#else /* !USE_32BIT_ONLY */
+    for (i = 0; i < HashSize; ++i)
+        Message_Digest[i] = (uint8_t)
+        (context->Intermediate_Hash[i >> 3] >> 8 * (7 - (i % 8)));
+#endif /* USE_32BIT_ONLY */
+
+    return shaSuccess;
+}
+
Index: azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/src/singlylinkedlist.c
===================================================================
--- azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/src/singlylinkedlist.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/src/singlylinkedlist.c	(revision 457)
@@ -0,0 +1,409 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+#include <stdlib.h>
+#include "azure_c_shared_utility/gballoc.h"
+#include "azure_c_shared_utility/singlylinkedlist.h"
+#include "azure_c_shared_utility/optimize_size.h"
+#include "azure_c_shared_utility/xlogging.h"
+
+typedef struct LIST_ITEM_INSTANCE_TAG
+{
+    const void* item;
+    void* next;
+} LIST_ITEM_INSTANCE;
+
+typedef struct SINGLYLINKEDLIST_INSTANCE_TAG
+{
+    LIST_ITEM_INSTANCE* head;
+    LIST_ITEM_INSTANCE* tail;
+} LIST_INSTANCE;
+
+SINGLYLINKEDLIST_HANDLE singlylinkedlist_create(void)
+{
+    LIST_INSTANCE* result;
+
+    /* Codes_SRS_LIST_01_001: [singlylinkedlist_create shall create a new list and return a non-NULL handle on success.] */
+    result = (LIST_INSTANCE*)malloc(sizeof(LIST_INSTANCE));
+    if (result != NULL)
+    {
+        /* Codes_SRS_LIST_01_002: [If any error occurs during the list creation, singlylinkedlist_create shall return NULL.] */
+        result->head = NULL;
+        result->tail = NULL;
+    }
+
+    return result;
+}
+
+void singlylinkedlist_destroy(SINGLYLINKEDLIST_HANDLE list)
+{
+    /* Codes_SRS_LIST_01_004: [If the list argument is NULL, no freeing of resources shall occur.] */
+    if (list != NULL)
+    {
+        LIST_INSTANCE* list_instance = (LIST_INSTANCE*)list;
+
+        while (list_instance->head != NULL)
+        {
+            LIST_ITEM_INSTANCE* current_item = list_instance->head;
+            list_instance->head = (LIST_ITEM_INSTANCE*)current_item->next;
+            free(current_item);
+        }
+
+        /* Codes_SRS_LIST_01_003: [singlylinkedlist_destroy shall free all resources associated with the list identified by the handle argument.] */
+        free(list_instance);
+    }
+}
+
+LIST_ITEM_HANDLE singlylinkedlist_add(SINGLYLINKEDLIST_HANDLE list, const void* item)
+{
+    LIST_ITEM_INSTANCE* result;
+
+    /* Codes_SRS_LIST_01_006: [If any of the arguments is NULL, singlylinkedlist_add shall not add the item to the list and return NULL.] */
+    if ((list == NULL) ||
+        (item == NULL))
+    {
+        LogError("Invalid argument (list=%p, item=%p)", list, item);
+        result = NULL;
+    }
+    else
+    {
+        LIST_INSTANCE* list_instance = (LIST_INSTANCE*)list;
+        result = (LIST_ITEM_INSTANCE*)malloc(sizeof(LIST_ITEM_INSTANCE));
+
+        if (result == NULL)
+        {
+            /* Codes_SRS_LIST_01_007: [If allocating the new list node fails, singlylinkedlist_add shall return NULL.] */
+            /*return as is*/
+        }
+        else
+        {
+            /* Codes_SRS_LIST_01_005: [singlylinkedlist_add shall add one item to the tail of the list and on success it shall return a handle to the added item.] */
+            result->next = NULL;
+            result->item = item;
+
+            if (list_instance->head == NULL)
+            {
+                list_instance->head = result;
+                list_instance->tail = result;
+            }
+            else
+            {
+                list_instance->tail->next = result;
+                list_instance->tail = result;
+            }
+        }
+    }
+
+    return result;
+}
+
+int singlylinkedlist_remove(SINGLYLINKEDLIST_HANDLE list, LIST_ITEM_HANDLE item)
+{
+    int result;
+
+    /* Codes_SRS_LIST_01_024: [If any of the arguments list or item_handle is NULL, singlylinkedlist_remove shall fail and return a non-zero value.] */
+    if ((list == NULL) ||
+        (item == NULL))
+    {
+        LogError("Invalid argument (list=%p, item=%p)", list, item);
+        result = MU_FAILURE;
+    }
+    else
+    {
+        LIST_INSTANCE* list_instance = (LIST_INSTANCE*)list;
+        LIST_ITEM_INSTANCE* current_item = list_instance->head;
+        LIST_ITEM_INSTANCE* previous_item = NULL;
+
+        while (current_item != NULL)
+        {
+            if (current_item == item)
+            {
+                if (previous_item != NULL)
+                {
+                    previous_item->next = current_item->next;
+                }
+                else
+                {
+                    list_instance->head = (LIST_ITEM_INSTANCE*)current_item->next;
+                }
+
+                if (current_item == list_instance->tail)
+                {
+                    list_instance->tail = previous_item;
+                }
+
+                free(current_item);
+
+                break;
+            }
+
+            previous_item = current_item;
+            current_item = (LIST_ITEM_INSTANCE*)current_item->next;
+        }
+
+        if (current_item == NULL)
+        {
+            /* Codes_SRS_LIST_01_025: [If the item item_handle is not found in the list, then singlylinkedlist_remove shall fail and return a non-zero value.] */
+            result = MU_FAILURE;
+        }
+        else
+        {
+            /* Codes_SRS_LIST_01_023: [singlylinkedlist_remove shall remove a list item from the list and on success it shall return 0.] */
+            result = 0;
+        }
+    }
+
+    return result;
+}
+
+LIST_ITEM_HANDLE singlylinkedlist_get_head_item(SINGLYLINKEDLIST_HANDLE list)
+{
+    LIST_ITEM_HANDLE result;
+
+    if (list == NULL)
+    {
+        /* Codes_SRS_LIST_01_009: [If the list argument is NULL, singlylinkedlist_get_head_item shall return NULL.] */
+        LogError("Invalid argument (list=NULL)");
+        result = NULL;
+    }
+    else
+    {
+        LIST_INSTANCE* list_instance = (LIST_INSTANCE*)list;
+
+        /* Codes_SRS_LIST_01_008: [singlylinkedlist_get_head_item shall return the head of the list.] */
+        /* Codes_SRS_LIST_01_010: [If the list is empty, singlylinkedlist_get_head_item_shall_return NULL.] */
+        result = list_instance->head;
+    }
+
+    return result;
+}
+
+LIST_ITEM_HANDLE singlylinkedlist_get_next_item(LIST_ITEM_HANDLE item_handle)
+{
+    LIST_ITEM_HANDLE result;
+
+    if (item_handle == NULL)
+    {
+        LogError("Invalid argument (list is NULL)");
+        /* Codes_SRS_LIST_01_019: [If item_handle is NULL then singlylinkedlist_get_next_item shall return NULL.] */
+        result = NULL;
+    }
+    else
+    {
+        /* Codes_SRS_LIST_01_018: [singlylinkedlist_get_next_item shall return the next item in the list following the item item_handle.] */
+        result = (LIST_ITEM_HANDLE)((LIST_ITEM_INSTANCE*)item_handle)->next;
+    }
+
+    return result;
+}
+
+const void* singlylinkedlist_item_get_value(LIST_ITEM_HANDLE item_handle)
+{
+    const void* result;
+
+    if (item_handle == NULL)
+    {
+        LogError("Invalid argument (item_handle is NULL)");
+        /* Codes_SRS_LIST_01_021: [If item_handle is NULL, singlylinkedlist_item_get_value shall return NULL.] */
+        result = NULL;
+    }
+    else
+    {
+        /* Codes_SRS_LIST_01_020: [singlylinkedlist_item_get_value shall return the value associated with the list item identified by the item_handle argument.] */
+        result = ((LIST_ITEM_INSTANCE*)item_handle)->item;
+    }
+
+    return result;
+}
+
+LIST_ITEM_HANDLE singlylinkedlist_find(SINGLYLINKEDLIST_HANDLE list, LIST_MATCH_FUNCTION match_function, const void* match_context)
+{
+    LIST_ITEM_HANDLE result;
+
+    if ((list == NULL) ||
+        (match_function == NULL))
+    {
+        LogError("Invalid argument (list=%p, match_function=%p)", list, match_function);
+        /* Codes_SRS_LIST_01_012: [If the list or the match_function argument is NULL, singlylinkedlist_find shall return NULL.] */
+        result = NULL;
+    }
+    else
+    {
+        LIST_INSTANCE* list_instance = (LIST_INSTANCE*)list;
+        LIST_ITEM_INSTANCE* current = list_instance->head;
+
+        /* Codes_SRS_LIST_01_011: [singlylinkedlist_find shall iterate through all items in a list and return the first one that satisfies a certain match function.] */
+        while (current != NULL)
+        {
+            /* Codes_SRS_LIST_01_014: [list find shall determine whether an item satisfies the match criteria by invoking the match function for each item in the list until a matching item is found.] */
+            /* Codes_SRS_LIST_01_013: [The match_function shall get as arguments the list item being attempted to be matched and the match_context as is.] */
+            if (match_function((LIST_ITEM_HANDLE)current, match_context) == true)
+            {
+                /* Codes_SRS_LIST_01_017: [If the match function returns true, singlylinkedlist_find shall consider that item as matching.] */
+                break;
+            }
+
+            /* Codes_SRS_LIST_01_016: [If the match function returns false, singlylinkedlist_find shall consider that item as not matching.] */
+            current = (LIST_ITEM_INSTANCE*)current->next;
+        }
+
+        if (current == NULL)
+        {
+            /* Codes_SRS_LIST_01_015: [If the list is empty, singlylinkedlist_find shall return NULL.] */
+            result = NULL;
+        }
+        else
+        {
+            result = current;
+        }
+    }
+
+    return result;
+}
+
+int singlylinkedlist_remove_if(SINGLYLINKEDLIST_HANDLE list, LIST_CONDITION_FUNCTION condition_function, const void* match_context)
+{
+    int result;
+    /* Codes_SRS_LIST_09_001: [ If the list or the condition_function argument is NULL, singlylinkedlist_remove_if shall return non-zero value. ] */
+    if ((list == NULL) ||
+        (condition_function == NULL))
+    {
+        LogError("Invalid argument (list=%p, condition_function=%p)", list, condition_function);
+        result = MU_FAILURE;
+    }
+    else
+    {
+        LIST_INSTANCE* list_instance = (LIST_INSTANCE*)list;
+        LIST_ITEM_INSTANCE* current_item = list_instance->head;
+        LIST_ITEM_INSTANCE* next_item = NULL;
+        LIST_ITEM_INSTANCE* previous_item = NULL;
+
+        /* Codes_SRS_LIST_09_002: [ singlylinkedlist_remove_if shall iterate through all items in a list and remove all that satisfies a certain condition function. ] */
+        while (current_item != NULL)
+        {
+            bool continue_processing = false;
+
+            next_item = (LIST_ITEM_INSTANCE*)current_item->next;
+
+            /* Codes_SRS_LIST_09_003: [ singlylinkedlist_remove_if shall determine whether an item satisfies the condition criteria by invoking the condition function for that item. ] */
+            /* Codes_SRS_LIST_09_004: [ If the condition function returns true, singlylinkedlist_find shall consider that item as to be removed. ] */
+            if (condition_function(current_item->item, match_context, &continue_processing) == true)
+            {
+                if (previous_item != NULL)
+                {
+                    previous_item->next = next_item;
+                }
+                else
+                {
+                    list_instance->head = next_item;
+                }
+
+                if (current_item == list_instance->tail)
+                {
+                    list_instance->tail = previous_item;
+                }
+
+                free(current_item);
+            }
+            /* Codes_SRS_LIST_09_005: [ If the condition function returns false, singlylinkedlist_find shall consider that item as not to be removed. ] */
+            else
+            {
+                previous_item = current_item;
+            }
+
+            /* Codes_SRS_LIST_09_006: [ If the condition function returns continue_processing as false, singlylinkedlist_remove_if shall stop iterating through the list and return. ] */
+            if (continue_processing == false)
+            {
+                break;
+            }
+
+            current_item = next_item;
+        }
+
+        /* Codes_SRS_LIST_09_007: [ If no errors occur, singlylinkedlist_remove_if shall return zero. ] */
+        result = 0;
+    }
+
+    return result;
+}
+
+int singlylinkedlist_foreach(SINGLYLINKEDLIST_HANDLE list, LIST_ACTION_FUNCTION action_function, const void* action_context)
+{
+    int result;
+
+    /* Codes_SRS_LIST_09_008: [ If the list or the action_function argument is NULL, singlylinkedlist_foreach shall return non-zero value. ] */
+    if ((list == NULL) ||
+        (action_function == NULL))
+    {
+        LogError("Invalid argument (list=%p, action_function=%p)", list, action_function);
+        result = MU_FAILURE;
+    }
+    else
+    {
+        LIST_INSTANCE* list_instance = (LIST_INSTANCE*)list;
+        LIST_ITEM_INSTANCE* list_item = list_instance->head;
+
+        while (list_item != NULL)
+        {
+            bool continue_processing = false;
+
+            /* Codes_SRS_LIST_09_009: [ singlylinkedlist_foreach shall iterate through all items in a list and invoke action_function for each one of them. ] */
+            action_function(list_item->item, action_context, &continue_processing);
+
+            /* Codes_SRS_LIST_09_010: [ If the condition function returns continue_processing as false, singlylinkedlist_foreach shall stop iterating through the list and return. ] */
+            if (continue_processing == false)
+            {
+                break;
+            }
+
+            list_item = (LIST_ITEM_INSTANCE*)list_item->next;
+        }
+
+        /* Codes_SRS_LIST_09_011: [ If no errors occur, singlylinkedlist_foreach shall return zero. ] */
+        result = 0;
+    }
+
+    return result;
+}
+
+LIST_ITEM_HANDLE singlylinkedlist_add_head(SINGLYLINKEDLIST_HANDLE list, const void* item)
+{
+    LIST_ITEM_HANDLE result;
+
+    /* Codes_SRS_LIST_02_001: [ If list is NULL then singlylinkedlist_add_head shall fail and return NULL. ]*/
+    if (list == NULL)
+    {
+        LogError("Invalid argument SINGLYLINKEDLIST_HANDLE list=%p", list);
+        result = NULL;
+    }
+    else
+    {
+        result = malloc(sizeof(LIST_ITEM_INSTANCE));
+
+        if (result == NULL)
+        {
+            /*Codes_SRS_LIST_02_003: [ If there are any failures then singlylinkedlist_add_head shall fail and return NULL. ]*/
+            LogError("failure in malloc");
+            /*return as is*/
+        }
+        else
+        {
+            /*Codes_SRS_LIST_02_002: [ singlylinkedlist_add_head shall insert item at head, succeed and return a non-NULL value. ]*/
+            result->item = item;
+            if (list->head == NULL)
+            {
+                result->next = NULL;
+                list->head = result;
+                list->tail = result;
+                
+            }
+            else
+            {
+                result->next = list->head;
+                list->head = result;
+            }
+        }
+    }
+
+    return result;
+}
Index: azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/src/string_token.c
===================================================================
--- azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/src/string_token.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/src/string_token.c	(revision 457)
@@ -0,0 +1,390 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+#include <stdlib.h>
+#include <stdbool.h>
+#include <stdarg.h>
+#include "azure_c_shared_utility/gballoc.h"
+#include "azure_c_shared_utility/optimize_size.h"
+#include "azure_c_shared_utility/xlogging.h"
+#include "azure_c_shared_utility/crt_abstractions.h"
+#include "azure_c_shared_utility/string_token.h"
+
+typedef struct STRING_TOKEN_TAG
+{
+    const char* source;
+    size_t length;
+
+    const char* token_start;
+    const char* delimiter_start;
+    const char* delimiter;
+} STRING_TOKEN;
+
+static size_t* get_delimiters_lengths(const char** delimiters, size_t n_delims)
+{
+    size_t* result;
+
+    if ((result = malloc(sizeof(size_t) * n_delims)) == NULL)
+    {
+        LogError("Failed to allocate array for delimiters lengths");
+    }
+    else
+    {
+        size_t i;
+        for (i = 0; i < n_delims; i++)
+        {
+            if (delimiters[i] == NULL)
+            {
+                // Codes_SRS_STRING_TOKENIZER_09_002: [ If any of the strings in delimiters are NULL, the function shall return NULL ]
+                LogError("Invalid argument (delimiter %lu is NULL)", (unsigned long)i);
+                free(result);
+                result = NULL;
+                break;
+            }
+            else
+            {
+                result[i] = strlen(delimiters[i]);
+            }
+        }
+    }
+
+    return result;
+}
+
+static int get_next_token(STRING_TOKEN* token, const char** delimiters, size_t n_delims)
+{
+    int result;
+
+    if (token->token_start != NULL && token->delimiter_start == NULL)
+    {
+        // The parser reached the end of the input string.
+        result = MU_FAILURE;
+    }
+    else
+    {
+        size_t* delimiters_lengths;
+
+        if ((delimiters_lengths = get_delimiters_lengths(delimiters, n_delims)) == NULL)
+        {
+            LogError("Failed to get delimiters lengths");
+            result = MU_FAILURE;
+        }
+        else
+        {
+            const char* new_token_start;
+            const char* current_pos;
+            const char* stop_pos = (char*)token->source + token->length;
+            size_t j; // iterator for the delimiters.
+
+            if (token->delimiter_start == NULL)
+            {
+                // Codes_SRS_STRING_TOKENIZER_09_005: [ The source string shall be split in a token starting from the beginning of source up to occurrence of any one of the demiliters, whichever occurs first in the order provided ]
+                new_token_start = (char*)token->source;
+            }
+            else
+            {
+                // Codes_SRS_STRING_TOKENIZER_09_010: [ The next token shall be selected starting from the position in source right after the previous delimiter up to occurrence of any one of demiliters, whichever occurs first in the order provided ]
+                new_token_start = token->delimiter_start + strlen(token->delimiter);
+            }
+
+            current_pos = new_token_start;
+            result = 0;
+
+            while (current_pos < stop_pos)
+            {
+                for (j = 0; j < n_delims; j++)
+                {
+                    if (*current_pos == *delimiters[j])
+                    {
+                        size_t k;
+                        for (k = 1; k < delimiters_lengths[j] && (current_pos + k) < stop_pos; k++)
+                        {
+                            if (*(current_pos + k) != *(delimiters[j] + k))
+                            {
+                                break;
+                            }
+                        }
+
+                        if (k == delimiters_lengths[j])
+                        {
+                            token->delimiter_start = current_pos;
+                            token->delimiter = delimiters[j];
+
+                            if (token->delimiter_start == token->source)
+                            {
+                                // Delimiter occurs in the beginning of the source string.
+                                token->token_start = NULL;
+                            }
+                            else
+                            {
+                                token->token_start = new_token_start;
+                            }
+                            goto SCAN_COMPLETED;
+                        }
+                    }
+                }
+
+                current_pos++;
+            }
+
+            // Codes_SRS_STRING_TOKENIZER_09_006: [ If the source string does not have any of the demiliters, the resulting token shall be the entire source string ]
+            // Codes_SRS_STRING_TOKENIZER_09_011: [ If the source string, starting right after the position of the last delimiter found, does not have any of the demiliters, the resulting token shall be the entire remaining of the source string ]
+            if (current_pos == stop_pos)
+            {
+                token->token_start = new_token_start;
+                token->delimiter_start = NULL;
+                // Codes_SRS_STRING_TOKENIZER_09_019: [ If the current token extends to the end of source, the function shall return NULL ]
+                token->delimiter = NULL;
+            }
+
+SCAN_COMPLETED:
+            free(delimiters_lengths);
+        }
+    }
+
+    return result;
+}
+
+STRING_TOKEN_HANDLE StringToken_GetFirst(const char* source, size_t length, const char** delimiters, size_t n_delims)
+{
+    STRING_TOKEN* result;
+
+    // Codes_SRS_STRING_TOKENIZER_09_001: [ If source or delimiters are NULL, or n_delims is zero, the function shall return NULL ]
+    if (source == NULL || delimiters == NULL || n_delims == 0)
+    {
+        LogError("Invalid argument (source=%p, delimiters=%p, n_delims=%lu)", source, delimiters, (unsigned long)n_delims);
+        result = NULL;
+    }
+    else
+    {
+        // Codes_SRS_STRING_TOKENIZER_09_003: [ A STRING_TOKEN structure shall be allocated to hold the token parameters ]
+        if ((result = (STRING_TOKEN*)malloc(sizeof(STRING_TOKEN))) == NULL)
+        {
+            // Codes_SRS_STRING_TOKENIZER_09_004: [ If the STRING_TOKEN structure fails to be allocated, the function shall return NULL ]
+            LogError("Failed allocating STRING_TOKEN");
+        }
+        else
+        {
+            (void)memset(result, 0, sizeof(STRING_TOKEN));
+            result->source = source;
+            result->length = length;
+
+            if (get_next_token(result, delimiters, n_delims) != 0)
+            {
+                LogError("Failed to get first token");
+                // Codes_SRS_STRING_TOKENIZER_09_007: [ If any failure occurs, all memory allocated by this function shall be released ]
+                free(result);
+                result = NULL;
+            }
+        }
+    }
+
+    return result;
+}
+
+bool StringToken_GetNext(STRING_TOKEN_HANDLE token, const char** delimiters, size_t n_delims)
+{
+    bool result;
+
+    // Codes_SRS_STRING_TOKENIZER_09_008: [ If token or delimiters are NULL, or n_delims is zero, the function shall return false ]
+    if (token == NULL || delimiters == NULL || n_delims == 0)
+    {
+        LogError("Invalid argument (token=%p, delimiters=%p, n_delims=%lu)", token, delimiters, (unsigned long)n_delims);
+        result = false;
+    }
+    else if (get_next_token(token, delimiters, n_delims) != 0)
+    {
+        // Codes_SRS_STRING_TOKENIZER_09_009: [ If the previous token already extended to the end of source, the function shall return false ]
+        result = false;
+    }
+    else
+    {
+        // Codes_SRS_STRING_TOKENIZER_09_012: [ If a token was identified, the function shall return true ]
+        result = true;
+    }
+
+    return result;
+}
+
+const char* StringToken_GetValue(STRING_TOKEN_HANDLE token)
+{
+    const char* result;
+
+    // Codes_SRS_STRING_TOKENIZER_09_013: [ If token is NULL the function shall return NULL ]
+    if (token == NULL)
+    {
+        LogError("Invalig argument (token is NULL)");
+        result = NULL;
+    }
+    // Beyond the length of the source string.
+    else if (token->token_start == (token->source + token->length))
+    {
+        result = NULL;
+    }
+    // Two delimiters side by side (empty token).
+    else if (token->token_start == token->delimiter_start)
+    {
+        result = NULL;
+    }
+    else
+    {
+        // Codes_SRS_STRING_TOKENIZER_09_014: [ The function shall return the pointer to the position in source where the current token starts. ]
+        result = token->token_start;
+    }
+
+    return result;
+}
+
+size_t StringToken_GetLength(STRING_TOKEN_HANDLE token)
+{
+    size_t result;
+
+    // Codes_SRS_STRING_TOKENIZER_09_015: [ If token is NULL the function shall return zero ]
+    if (token == NULL)
+    {
+        LogError("Invalig argument (token is NULL)");
+        result = 0;
+    }
+    // Codes_SRS_STRING_TOKENIZER_09_016: [ The function shall return the length of the current token ]
+    else if (token->token_start == NULL)
+    {
+        result = 0;
+    }
+    else if (token->delimiter_start == NULL)
+    {
+        result = token->source + token->length - token->token_start;
+    }
+    else
+    {
+        result = token->delimiter_start - token->token_start;
+    }
+
+    return result;
+}
+
+const char* StringToken_GetDelimiter(STRING_TOKEN_HANDLE token)
+{
+    const char* result;
+
+    if (token == NULL)
+    {
+        // Codes_SRS_STRING_TOKENIZER_09_017: [ If token is NULL the function shall return NULL ]
+        LogError("Invalig argument (token is NULL)");
+        result = NULL;
+    }
+    else
+    {
+        // Codes_SRS_STRING_TOKENIZER_09_018: [ The function shall return a pointer to the delimiter that defined the current token, as passed to the previous call to StringToken_GetNext() or StringToken_GetFirst() ]
+        result = token->delimiter;
+    }
+
+    return result;
+}
+
+int StringToken_Split(const char* source, size_t length, const char** delimiters, size_t n_delims, bool include_empty, char*** tokens, size_t* token_count)
+{
+    int result;
+
+    // Codes_SRS_STRING_TOKENIZER_09_022: [ If source, delimiters, token or token_count are NULL, or n_delims is zero the function shall return a non-zero value ]
+    if (source == NULL || delimiters == NULL || n_delims == 0 || tokens == NULL || token_count == NULL)
+    {
+        LogError("Invalid argument (source=%p, delimiters=%p, n_delims=%lu, tokens=%p, token_count=%p)", source, delimiters, (unsigned long)n_delims, tokens, token_count);
+        result = MU_FAILURE;
+    }
+    else
+    {
+        STRING_TOKEN_HANDLE tokenizer;
+
+        // Codes_SRS_STRING_TOKENIZER_09_023: [ source (up to length) shall be split into individual tokens separated by any of delimiters ]
+        tokenizer = StringToken_GetFirst(source, length, delimiters, n_delims);
+
+        *token_count = 0;
+        *tokens = NULL;
+        // Codes_SRS_STRING_TOKENIZER_09_027: [ If no failures occur the function shall return zero ]
+        result = 0;
+
+        if (tokenizer != NULL)
+        {
+            do
+            {
+                const char* tokenValue;
+                size_t tokenLength;
+
+                tokenValue = StringToken_GetValue(tokenizer);
+                tokenLength = StringToken_GetLength(tokenizer);
+
+                if ((tokenValue != NULL && tokenLength == 0) || (tokenValue == NULL && tokenLength > 0))
+                {
+                    LogError("Unexpected token value (%p) or length (%lu)", tokenValue, (unsigned long)tokenLength);
+                    result = MU_FAILURE;
+                    break;
+                }
+                // Codes_SRS_STRING_TOKENIZER_09_024: [ All NULL tokens shall be ommited if include_empty is not TRUE ]
+                else if (tokenValue != NULL || include_empty)
+                {
+                    char** temp_token;
+                    // Codes_SRS_STRING_TOKENIZER_09_025: [ The tokens shall be stored in tokens, and their count stored in token_count ]
+                    *token_count = (*token_count) + 1;
+
+                    if ((temp_token = (char**)realloc(*tokens, sizeof(char*) * (*token_count))) == NULL)
+                    {
+                        // Codes_SRS_STRING_TOKENIZER_09_026: [ If any failures splitting or storing the tokens occur the function shall return a non-zero value ]
+                        LogError("Failed re-allocating the token array");
+                        (*token_count)--;
+                        result = MU_FAILURE;
+                        break;
+                    }
+                    else
+                    {
+                        *tokens = temp_token;
+                        if (tokenLength == 0)
+                        {
+                            (*tokens)[(*token_count) - 1] = NULL;
+                        }
+                        else if (((*tokens)[(*token_count) - 1] = (char*)malloc(sizeof(char) * (tokenLength + 1))) == NULL)
+                        {
+                            // Codes_SRS_STRING_TOKENIZER_09_026: [ If any failures splitting or storing the tokens occur the function shall return a non-zero value ]
+                            LogError("Failed copying token into array");
+                            *token_count = (*token_count) - 1;
+                            result = MU_FAILURE;
+                            break;
+                        }
+                        else
+                        {
+                            (void)memcpy((*tokens)[(*token_count) - 1], tokenValue, tokenLength);
+                            (*tokens)[(*token_count) - 1][tokenLength] = '\0';
+                        }
+                    }
+                }
+            } while (StringToken_GetNext(tokenizer, delimiters, n_delims));
+
+            StringToken_Destroy(tokenizer);
+
+            if (result != 0)
+            {
+                while ((*token_count) > 0 && *tokens != NULL)
+                {
+                    *token_count = (*token_count) - 1;
+                    free((*tokens)[*token_count]);
+                }
+                free(*tokens);
+            }
+        }
+    }
+
+    return result;
+}
+
+void StringToken_Destroy(STRING_TOKEN_HANDLE token)
+{
+    if (token == NULL)
+    {
+        // Codes_SRS_STRING_TOKENIZER_09_020: [ If token is NULL the function shall return ]
+        LogError("Invalig argument (token is NULL)");
+    }
+    else
+    {
+        // Codes_SRS_STRING_TOKENIZER_09_021: [ Otherwise the memory allocated for STRING_TOKEN shall be released ]
+        free(token);
+    }
+}
Index: azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/src/string_tokenizer.c
===================================================================
--- azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/src/string_tokenizer.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/src/string_tokenizer.c	(revision 457)
@@ -0,0 +1,202 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+#include <stdlib.h>
+#include <stdbool.h>
+#include "azure_c_shared_utility/gballoc.h"
+#include "azure_c_shared_utility/string_tokenizer.h"
+#include "azure_c_shared_utility/optimize_size.h"
+#include "azure_c_shared_utility/xlogging.h"
+#include "azure_c_shared_utility/crt_abstractions.h"
+
+typedef struct STRING_TOKEN_TAG
+{
+    const char* inputString;
+    const char* currentPos;
+    size_t sizeOfinputString;
+} STRING_TOKEN;
+
+STRING_TOKENIZER_HANDLE STRING_TOKENIZER_create(STRING_HANDLE handle)
+{
+    STRING_TOKENIZER_HANDLE result;
+
+    /* Codes_SRS_STRING_04_001: [STRING_TOKENIZER_create shall return an NULL STRING_TOKENIZER_HANDLE if parameter handle is NULL] */
+    if (handle == NULL)
+    {
+        LogError("Invalid Argument. Handle cannot be NULL.");
+        result = NULL;
+    }
+    else
+    {
+        /* Codes_SRS_STRING_04_002: [STRING_TOKENIZER_create shall allocate a new STRING_TOKENIZER_HANDLE having the content of the STRING_HANDLE copied and current position pointing at the beginning of the string] */
+        result = STRING_TOKENIZER_create_from_char(STRING_c_str(handle));
+    }
+
+    return result;
+}
+
+extern STRING_TOKENIZER_HANDLE STRING_TOKENIZER_create_from_char(const char* input)
+{
+    STRING_TOKEN *result;
+    char* inputStringToMalloc;
+
+    /* Codes_SRS_STRING_07_001: [STRING_TOKENIZER_create shall return an NULL STRING_TOKENIZER_HANDLE if parameter input is NULL] */
+    if (input == NULL)
+    {
+        LogError("Invalid Argument. Handle cannot be NULL.");
+        result = NULL;
+    }
+    /* Codes_SRS_STRING_07_002: [STRING_TOKENIZER_create shall allocate a new STRING_TOKENIZER_HANDLE having the content of the STRING_HANDLE copied and current position pointing at the beginning of the string] */
+    else if ((result = (STRING_TOKEN*)calloc(1, sizeof(STRING_TOKEN))) == NULL)
+    {
+        LogError("Memory Allocation failed. Cannot allocate STRING_TOKENIZER.");
+    }
+    else if ((mallocAndStrcpy_s(&inputStringToMalloc, input)) != 0)
+    {
+        LogError("Memory Allocation Failed. Cannot allocate and copy string Content.");
+        free(result);
+        result = NULL;
+    }
+    else
+    {
+        result->inputString = inputStringToMalloc;
+        result->currentPos = result->inputString; //Current Pos will point to the initial position of Token.
+        result->sizeOfinputString = strlen(result->inputString); //Calculate Size of Current String
+    }
+    return (STRING_TOKENIZER_HANDLE)result;
+}
+
+int STRING_TOKENIZER_get_next_token(STRING_TOKENIZER_HANDLE tokenizer, STRING_HANDLE output, const char* delimiters)
+{
+    int result;
+    /* Codes_SRS_STRING_04_004: [STRING_TOKENIZER_get_next_token shall return a nonzero value if any of the 3 parameters is NULL] */
+    if (tokenizer == NULL || output == NULL || delimiters == NULL)
+    {
+        result = MU_FAILURE;
+    }
+    else
+    {
+        STRING_TOKEN* token = (STRING_TOKEN*)tokenizer;
+        /* Codes_SRS_STRING_04_011: [Each subsequent call to STRING_TOKENIZER_get_next_token starts searching from the saved position on t and behaves as described above.] */
+        size_t remainingInputStringSize = token->sizeOfinputString - (token->currentPos - token->inputString);
+        size_t delimitterSize = strlen(delimiters);
+
+        /* First Check if we reached the end of the string*/
+        /* Codes_SRS_STRING_TOKENIZER_04_014: [STRING_TOKENIZER_get_next_token shall return nonzero value if t contains an empty string.] */
+        if (remainingInputStringSize == 0)
+        {
+            result = MU_FAILURE;
+        }
+        else if (delimitterSize == 0)
+        {
+            LogError("Empty delimiters parameter.");
+            result = MU_FAILURE;
+        }
+        else
+        {
+            size_t i;
+            /* Codes_SRS_STRING_04_005: [STRING_TOKENIZER_get_next_token searches the string inside STRING_TOKENIZER_HANDLE for the first character that is NOT contained in the current delimiter] */
+            for (i = 0; i < remainingInputStringSize; i++)
+            {
+                size_t j;
+
+                bool foundDelimitter = false;
+                for (j = 0; j < delimitterSize; j++)
+                {
+                    if (token->currentPos[i] == delimiters[j])
+                    {
+                        foundDelimitter = true;
+                        break;
+                    }
+                }
+
+                /* Codes_SRS_STRING_04_007: [If such a character is found, STRING_TOKENIZER_get_next_token consider it as the start of a token.] */
+                if (!foundDelimitter)
+                {
+                    break;
+                }
+            }
+
+            /* Codes_SRS_STRING_04_006: [If no such character is found, then STRING_TOKENIZER_get_next_token shall return a nonzero Value (You've reach the end of the string or the string consists with only delimiters).] */
+            //At this point update Current Pos to the character of the last token found or end of String.
+            token->currentPos += i;
+
+            //Update the remainingInputStringSize
+            remainingInputStringSize -= i;
+
+            /* Codes_SRS_STRING_04_006: [If no such character is found, then STRING_TOKENIZER_get_next_token shall return a nonzero Value (You've reach the end of the string or the string consists with only delimiters).] */
+            if (remainingInputStringSize == 0)
+            {
+                result = MU_FAILURE;
+            }
+            else
+            {
+                bool foundDelimitter = false;
+                const char* endOfTokenPosition=NULL;
+                size_t amountOfCharactersToCopy;
+                size_t j;
+                //At this point the Current Pos is pointing to a character that is point to a nonDelimiter. So, now search for a Delimiter, till the end of the String.
+                /*Codes_SRS_STRING_04_008: [STRING_TOKENIZER_get_next_token than searches from the start of a token for a character that is contained in the delimiters string.] */
+                /* Codes_SRS_STRING_04_009: [If no such character is found, STRING_TOKENIZER_get_next_token extends the current token to the end of the string inside t, copies the token to output and returns 0.] */
+                /* Codes_SRS_STRING_04_010: [If such a character is found, STRING_TOKENIZER_get_next_token consider it the end of the token and copy it's content to output, updates the current position inside t to the next character and returns 0.] */
+                for (j = 0; j < delimitterSize; j++)
+                {
+                    if ((endOfTokenPosition = strchr(token->currentPos, delimiters[j])) != NULL)
+                    {
+                        foundDelimitter = true;
+                        break;
+                    }
+                }
+
+                //If token not found, than update the EndOfToken to the end of the inputString;
+                if (endOfTokenPosition == NULL)
+                {
+                    amountOfCharactersToCopy = remainingInputStringSize;
+                }
+                else
+                {
+                    amountOfCharactersToCopy = endOfTokenPosition - token->currentPos;
+                }
+
+                //copy here the string to output.
+                if (STRING_copy_n(output, token->currentPos, amountOfCharactersToCopy) != 0)
+                {
+                    LogError("Problem copying token to output String.");
+                    result = MU_FAILURE;
+                }
+                else
+                {
+                    //Update the Current position.
+                    //Check if end of String reached so, currentPos points to the end of String.
+                    if (foundDelimitter)
+                    {
+                        token->currentPos += amountOfCharactersToCopy + 1;
+                    }
+                    else
+                    {
+                        token->currentPos += amountOfCharactersToCopy;
+                    }
+
+                    result = 0; //Result will be on the output.
+                }
+            }
+        }
+    }
+
+    return result;
+}
+
+
+/* Codes_SRS_STRING_TOKENIZER_04_012: [STRING_TOKENIZER_destroy shall free the memory allocated by the STRING_TOKENIZER_create ] */
+void STRING_TOKENIZER_destroy(STRING_TOKENIZER_HANDLE t)
+{
+    /* Codes_SRS_STRING_TOKENIZER_04_013: [When the t argument is NULL, then STRING_TOKENIZER_destroy shall not attempt to free] */
+    if (t != NULL)
+    {
+        STRING_TOKEN* value = (STRING_TOKEN*)t;
+        free((char*)value->inputString);
+        value->inputString = NULL;
+        free(value);
+    }
+}
+
Index: azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/src/strings.c
===================================================================
--- azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/src/strings.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/src/strings.c	(revision 457)
@@ -0,0 +1,851 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+#include <stdlib.h>
+#include <string.h>
+#include <stdarg.h>
+#include <stdio.h>
+
+#include "azure_c_shared_utility/gballoc.h"
+#include "azure_c_shared_utility/strings.h"
+#include "azure_c_shared_utility/optimize_size.h"
+#include "azure_c_shared_utility/xlogging.h"
+
+static const char hexToASCII[16] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
+
+typedef struct STRING_TAG
+{
+    char* s;
+} STRING;
+
+/*this function will allocate a new string with just '\0' in it*/
+/*return NULL if it fails*/
+/* Codes_SRS_STRING_07_001: [STRING_new shall allocate a new STRING_HANDLE pointing to an empty string.] */
+STRING_HANDLE STRING_new(void)
+{
+    STRING* result;
+    if ((result = (STRING*)malloc(sizeof(STRING))) != NULL)
+    {
+        if ((result->s = (char*)malloc(1)) != NULL)
+        {
+            result->s[0] = '\0';
+        }
+        else
+        {
+            /* Codes_SRS_STRING_07_002: [STRING_new shall return an NULL STRING_HANDLE on any error that is encountered.] */
+            LogError("Failure allocating in STRING_new.");
+            free(result);
+            result = NULL;
+        }
+    }
+    return (STRING_HANDLE)result;
+}
+
+/*Codes_SRS_STRING_02_001: [STRING_clone shall produce a new string having the same content as the handle string.*/
+STRING_HANDLE STRING_clone(STRING_HANDLE handle)
+{
+    STRING* result;
+    /*Codes_SRS_STRING_02_002: [If parameter handle is NULL then STRING_clone shall return NULL.]*/
+    if (handle == NULL)
+    {
+        result = NULL;
+    }
+    else
+    {
+        /*Codes_SRS_STRING_02_003: [If STRING_clone fails for any reason, it shall return NULL.] */
+        if ((result = (STRING*)malloc(sizeof(STRING))) != NULL)
+        {
+            STRING* source = (STRING*)handle;
+            /*Codes_SRS_STRING_02_003: [If STRING_clone fails for any reason, it shall return NULL.] */
+            size_t sourceLen = strlen(source->s);
+            if ((result->s = (char*)malloc(sourceLen + 1)) == NULL)
+            {
+                LogError("Failure allocating clone value.");
+                free(result);
+                result = NULL;
+            }
+            else
+            {
+                (void)memcpy(result->s, source->s, sourceLen + 1);
+            }
+        }
+        else
+        {
+            /*not much to do, result is NULL from malloc*/
+        }
+    }
+    return (STRING_HANDLE)result;
+}
+
+/* Codes_SRS_STRING_07_003: [STRING_construct shall allocate a new string with the value of the specified const char*.] */
+STRING_HANDLE STRING_construct(const char* psz)
+{
+    STRING_HANDLE result;
+    if (psz == NULL)
+    {
+        /* Codes_SRS_STRING_07_005: [If the supplied const char* is NULL STRING_construct shall return a NULL value.] */
+        result = NULL;
+    }
+    else
+    {
+        STRING* str;
+        if ((str = (STRING*)malloc(sizeof(STRING))) != NULL)
+        {
+            size_t nLen = strlen(psz) + 1;
+            if ((str->s = (char*)malloc(nLen)) != NULL)
+            {
+                (void)memcpy(str->s, psz, nLen);
+                result = (STRING_HANDLE)str;
+            }
+            /* Codes_SRS_STRING_07_032: [STRING_construct encounters any error it shall return a NULL value.] */
+            else
+            {
+                LogError("Failure allocating constructed value.");
+                free(str);
+                result = NULL;
+            }
+        }
+        else
+        {
+            /* Codes_SRS_STRING_07_032: [STRING_construct encounters any error it shall return a NULL value.] */
+            LogError("Failure allocating value.");
+            result = NULL;
+        }
+    }
+    return result;
+}
+
+#if defined(__GNUC__)
+__attribute__ ((format (printf, 1, 2)))
+#endif
+STRING_HANDLE STRING_construct_sprintf(const char* format, ...)
+{
+    STRING* result;
+
+#ifdef STRINGS_C_SPRINTF_BUFFER_SIZE
+    size_t maxBufSize = STRINGS_C_SPRINTF_BUFFER_SIZE;
+    char buf[STRINGS_C_SPRINTF_BUFFER_SIZE];
+#else
+    size_t maxBufSize = 0;
+    char* buf = NULL;
+#endif
+
+    if (format != NULL)
+    {
+        va_list arg_list;
+        int length;
+        va_start(arg_list, format);
+
+        /* Codes_SRS_STRING_07_041: [STRING_construct_sprintf shall determine the size of the resulting string and allocate the necessary memory.] */
+        length = vsnprintf(buf, maxBufSize, format, arg_list);
+        va_end(arg_list);
+        if (length > 0)
+        {
+            result = (STRING*)malloc(sizeof(STRING));
+            if (result != NULL)
+            {
+                result->s = (char*)malloc(length+1);
+                if (result->s != NULL)
+                {
+                    va_start(arg_list, format);
+                    if (vsnprintf(result->s, length+1, format, arg_list) < 0)
+                    {
+                        /* Codes_SRS_STRING_07_040: [If any error is encountered STRING_construct_sprintf shall return NULL.] */
+                        free(result->s);
+                        free(result);
+                        result = NULL;
+                        LogError("Failure: vsnprintf formatting failed.");
+                    }
+                    va_end(arg_list);
+                }
+                else
+                {
+                    /* Codes_SRS_STRING_07_040: [If any error is encountered STRING_construct_sprintf shall return NULL.] */
+                    free(result);
+                    result = NULL;
+                    LogError("Failure: allocation sprintf value failed.");
+                }
+            }
+            else
+            {
+                LogError("Failure: allocation failed.");
+            }
+        }
+        else if (length == 0)
+        {
+            result = (STRING*)STRING_new();
+        }
+        else
+        {
+            /* Codes_SRS_STRING_07_039: [If the parameter format is NULL then STRING_construct_sprintf shall return NULL.] */
+            result = NULL;
+            LogError("Failure: vsnprintf return 0 length");
+        }
+    }
+    else
+    {
+        LogError("Failure: invalid argument.");
+        result = NULL;
+    }
+    /* Codes_SRS_STRING_07_045: [STRING_construct_sprintf shall allocate a new string with the value of the specified printf formated const char. ] */
+    return (STRING_HANDLE)result;
+}
+
+/*this function will return a new STRING with the memory for the actual string passed in as a parameter.*/
+/*return NULL if it fails.*/
+/* The supplied memory must have been allocated with malloc! */
+/* Codes_SRS_STRING_07_006: [STRING_new_with_memory shall return a STRING_HANDLE by using the supplied char* memory.] */
+STRING_HANDLE STRING_new_with_memory(const char* memory)
+{
+    STRING* result;
+    if (memory == NULL)
+    {
+        /* Codes_SRS_STRING_07_007: [STRING_new_with_memory shall return a NULL STRING_HANDLE if the supplied char* is NULL.] */
+        result = NULL;
+    }
+    else
+    {
+        if ((result = (STRING*)malloc(sizeof(STRING))) != NULL)
+        {
+            result->s = (char*)memory;
+        }
+        else
+        {
+            LogError("Failure: allocating memory string");
+        }
+    }
+    return (STRING_HANDLE)result;
+}
+
+/* Codes_SRS_STRING_07_008: [STRING_new_quoted shall return a valid STRING_HANDLE Copying the supplied const char* value surrounded by quotes.] */
+STRING_HANDLE STRING_new_quoted(const char* source)
+{
+    STRING* result;
+    if (source == NULL)
+    {
+        /* Codes_SRS_STRING_07_009: [STRING_new_quoted shall return a NULL STRING_HANDLE if the supplied const char* is NULL.] */
+        result = NULL;
+    }
+    else if ((result = (STRING*)malloc(sizeof(STRING))) != NULL)
+    {
+        size_t sourceLength = strlen(source);
+        if ((result->s = (char*)malloc(sourceLength + 3)) != NULL)
+        {
+            result->s[0] = '"';
+            (void)memcpy(result->s + 1, source, sourceLength);
+            result->s[sourceLength + 1] = '"';
+            result->s[sourceLength + 2] = '\0';
+        }
+        else
+        {
+            /* Codes_SRS_STRING_07_031: [STRING_new_quoted shall return a NULL STRING_HANDLE if any error is encountered.] */
+            LogError("Failure allocating quoted string value.");
+            free(result);
+            result = NULL;
+        }
+    }
+    return (STRING_HANDLE)result;
+}
+
+/*this function takes a regular const char* and turns in into "this is a\"JSON\" strings\u0008" (starting and ending quote included)*/
+/*the newly created handle needs to be disposed of with STRING_delete*/
+/*returns NULL if there are errors*/
+STRING_HANDLE STRING_new_JSON(const char* source)
+{
+    STRING* result;
+    if (source == NULL)
+    {
+        /*Codes_SRS_STRING_02_011: [If source is NULL then STRING_new_JSON shall return NULL.] */
+        result = NULL;
+        LogError("invalid arg (NULL)");
+    }
+    else
+    {
+        size_t i;
+        size_t nControlCharacters = 0; /*counts how many characters are to be expanded from 1 character to \uxxxx (6 characters)*/
+        size_t nEscapeCharacters = 0;
+        size_t vlen = strlen(source);
+
+        for (i = 0; i < vlen; i++)
+        {
+            /*Codes_SRS_STRING_02_014: [If any character has the value outside [1...127] then STRING_new_JSON shall fail and return NULL.] */
+            if ((unsigned char)source[i] >= 128) /*this be a UNICODE character begin*/
+            {
+                break;
+            }
+            else
+            {
+                if (source[i] <= 0x1F)
+                {
+                    nControlCharacters++;
+                }
+                else if (
+                    (source[i] == '"') ||
+                    (source[i] == '\\') ||
+                    (source[i] == '/')
+                    )
+                {
+                    nEscapeCharacters++;
+                }
+            }
+        }
+
+        if (i < vlen)
+        {
+            result = NULL;
+            LogError("invalid character in input string");
+        }
+        else
+        {
+            if ((result = (STRING*)malloc(sizeof(STRING))) == NULL)
+            {
+                /*Codes_SRS_STRING_02_021: [If the complete JSON representation cannot be produced, then STRING_new_JSON shall fail and return NULL.] */
+                LogError("malloc json failure");
+            }
+            else if ((result->s = (char*)malloc(vlen + 5 * nControlCharacters + nEscapeCharacters + 3)) == NULL)
+            {
+                /*Codes_SRS_STRING_02_021: [If the complete JSON representation cannot be produced, then STRING_new_JSON shall fail and return NULL.] */
+                free(result);
+                result = NULL;
+                LogError("malloc failed");
+            }
+            else
+            {
+                size_t pos = 0;
+                /*Codes_SRS_STRING_02_012: [The string shall begin with the quote character.] */
+                result->s[pos++] = '"';
+                for (i = 0; i < vlen; i++)
+                {
+                    if (source[i] <= 0x1F)
+                    {
+                        /*Codes_SRS_STRING_02_019: [If the character code is less than 0x20 then it shall be represented as \u00xx, where xx is the hex representation of the character code.]*/
+                        result->s[pos++] = '\\';
+                        result->s[pos++] = 'u';
+                        result->s[pos++] = '0';
+                        result->s[pos++] = '0';
+                        result->s[pos++] = hexToASCII[(source[i] & 0xF0) >> 4]; /*high nibble*/
+                        result->s[pos++] = hexToASCII[source[i] & 0x0F]; /*low nibble*/
+                    }
+                    else if (source[i] == '"')
+                    {
+                        /*Codes_SRS_STRING_02_016: [If the character is " (quote) then it shall be repsented as \".] */
+                        result->s[pos++] = '\\';
+                        result->s[pos++] = '"';
+                    }
+                    else if (source[i] == '\\')
+                    {
+                        /*Codes_SRS_STRING_02_017: [If the character is \ (backslash) then it shall represented as \\.] */
+                        result->s[pos++] = '\\';
+                        result->s[pos++] = '\\';
+                    }
+                    else if (source[i] == '/')
+                    {
+                        /*Codes_SRS_STRING_02_018: [If the character is / (slash) then it shall be represented as \/.] */
+                        result->s[pos++] = '\\';
+                        result->s[pos++] = '/';
+                    }
+                    else
+                    {
+                        /*Codes_SRS_STRING_02_013: [The string shall copy the characters of source "as they are" (until the '\0' character) with the following exceptions:] */
+                        result->s[pos++] = source[i];
+                    }
+                }
+                /*Codes_SRS_STRING_02_020: [The string shall end with " (quote).] */
+                result->s[pos++] = '"';
+                /*zero terminating it*/
+                result->s[pos] = '\0';
+            }
+        }
+
+    }
+    return (STRING_HANDLE)result;
+}
+
+/*this function will concatenate to the string s1 the string s2, resulting in s1+s2*/
+/*returns 0 if success*/
+/*any other error code is failure*/
+/* Codes_SRS_STRING_07_012: [STRING_concat shall concatenate the given STRING_HANDLE and the const char* value and place the value in the handle.] */
+int STRING_concat(STRING_HANDLE handle, const char* s2)
+{
+    int result;
+    if ((handle == NULL) || (s2 == NULL))
+    {
+        /* Codes_SRS_STRING_07_013: [STRING_concat shall return a nonzero number if an error is encountered.] */
+        result = MU_FAILURE;
+    }
+    else
+    {
+        STRING* s1 = (STRING*)handle;
+        size_t s1Length = strlen(s1->s);
+        size_t s2Length = strlen(s2);
+        char* temp = (char*)realloc(s1->s, s1Length + s2Length + 1);
+        if (temp == NULL)
+        {
+            /* Codes_SRS_STRING_07_013: [STRING_concat shall return a nonzero number if an error is encountered.] */
+            LogError("Failure reallocating value.");
+            result = MU_FAILURE;
+        }
+        else
+        {
+            s1->s = temp;
+            (void)memcpy(s1->s + s1Length, s2, s2Length + 1);
+            result = 0;
+        }
+    }
+    return result;
+}
+
+/*this function will concatenate to the string s1 the string s2, resulting in s1+s2*/
+/*returns 0 if success*/
+/*any other error code is failure*/
+/* Codes_SRS_STRING_07_034: [String_Concat_with_STRING shall concatenate a given STRING_HANDLE variable with a source STRING_HANDLE.] */
+int STRING_concat_with_STRING(STRING_HANDLE s1, STRING_HANDLE s2)
+{
+    int result;
+    if ((s1 == NULL) || (s2 == NULL))
+    {
+        /* Codes_SRS_STRING_07_035: [String_Concat_with_STRING shall return a nonzero number if an error is encountered.] */
+        LogError("Invalid argument specified");
+        result = MU_FAILURE;
+    }
+    else
+    {
+        STRING* dest = (STRING*)s1;
+        STRING* src = (STRING*)s2;
+
+        size_t s1Length = strlen(dest->s);
+        size_t s2Length = strlen(src->s);
+        char* temp = (char*)realloc(dest->s, s1Length + s2Length + 1);
+        if (temp == NULL)
+        {
+            /* Codes_SRS_STRING_07_035: [String_Concat_with_STRING shall return a nonzero number if an error is encountered.] */
+            LogError("Failure reallocating value");
+            result = MU_FAILURE;
+        }
+        else
+        {
+            dest->s = temp;
+            /* Codes_SRS_STRING_07_034: [String_Concat_with_STRING shall concatenate a given STRING_HANDLE variable with a source STRING_HANDLE.] */
+            (void)memcpy(dest->s + s1Length, src->s, s2Length + 1);
+            result = 0;
+        }
+    }
+    return result;
+}
+
+/*this function will copy the string from s2 to s1*/
+/*returns 0 if success*/
+/*any other error code is failure*/
+/* Codes_SRS_STRING_07_016: [STRING_copy shall copy the const char* into the supplied STRING_HANDLE.] */
+int STRING_copy(STRING_HANDLE handle, const char* s2)
+{
+    int result;
+    if ((handle == NULL) || (s2 == NULL))
+    {
+        /* Codes_SRS_STRING_07_017: [STRING_copy shall return a nonzero value if any of the supplied parameters are NULL.] */
+        result = MU_FAILURE;
+    }
+    else
+    {
+        STRING* s1 = (STRING*)handle;
+        /* Codes_SRS_STRING_07_026: [If the underlying char* refered to by s1 handle is equal to char* s2 than STRING_copy shall be a noop and return 0.] */
+        if (s1->s != s2)
+        {
+            size_t s2Length = strlen(s2);
+            char* temp = (char*)realloc(s1->s, s2Length + 1);
+            if (temp == NULL)
+            {
+                LogError("Failure reallocating value.");
+                /* Codes_SRS_STRING_07_027: [STRING_copy shall return a nonzero value if any error is encountered.] */
+                result = MU_FAILURE;
+            }
+            else
+            {
+                s1->s = temp;
+                memmove(s1->s, s2, s2Length + 1);
+                result = 0;
+            }
+        }
+        else
+        {
+            /* Codes_SRS_STRING_07_033: [If overlapping pointer address is given to STRING_copy the behavior is undefined.] */
+            result = 0;
+        }
+    }
+    return result;
+}
+
+/*this function will copy n chars from s2 to the string s1, resulting in n chars only from s2 being stored in s1.*/
+/*returns 0 if success*/
+/*any other error code is failure*/
+/* Codes_SRS_STRING_07_018: [STRING_copy_n shall copy the number of characters in const char* or the size_t whichever is lesser.] */
+int STRING_copy_n(STRING_HANDLE handle, const char* s2, size_t n)
+{
+    int result;
+    if ((handle == NULL) || (s2 == NULL))
+    {
+        /* Codes_SRS_STRING_07_019: [STRING_copy_n shall return a nonzero value if STRING_HANDLE or const char* is NULL.] */
+        result = MU_FAILURE;
+    }
+    else
+    {
+        STRING* s1 = (STRING*)handle;
+        size_t s2Length = strlen(s2);
+        char* temp;
+        if (s2Length > n)
+        {
+            s2Length = n;
+        }
+
+        temp = (char*)realloc(s1->s, s2Length + 1);
+        if (temp == NULL)
+        {
+            LogError("Failure reallocating value.");
+            /* Codes_SRS_STRING_07_028: [STRING_copy_n shall return a nonzero value if any error is encountered.] */
+            result = MU_FAILURE;
+        }
+        else
+        {
+            s1->s = temp;
+            (void)memcpy(s1->s, s2, s2Length);
+            s1->s[s2Length] = 0;
+            result = 0;
+        }
+
+    }
+    return result;
+}
+
+#if defined(__GNUC__)
+__attribute__ ((format (printf, 2, 3)))
+#endif
+int STRING_sprintf(STRING_HANDLE handle, const char* format, ...)
+{
+    int result;
+
+#ifdef STRINGS_C_SPRINTF_BUFFER_SIZE
+    size_t maxBufSize = STRINGS_C_SPRINTF_BUFFER_SIZE;
+    char buf[STRINGS_C_SPRINTF_BUFFER_SIZE];
+#else
+    size_t maxBufSize = 0;
+    char* buf = NULL;
+#endif
+
+    if (handle == NULL || format == NULL)
+    {
+        /* Codes_SRS_STRING_07_042: [if the parameters s1 or format are NULL then STRING_sprintf shall return non zero value.] */
+        LogError("Invalid arg (NULL)");
+        result = MU_FAILURE;
+    }
+    else
+    {
+        va_list arg_list;
+        int s2Length;
+        va_start(arg_list, format);
+
+        s2Length = vsnprintf(buf, maxBufSize, format, arg_list);
+        va_end(arg_list);
+        if (s2Length < 0)
+        {
+            /* Codes_SRS_STRING_07_043: [If any error is encountered STRING_sprintf shall return a non zero value.] */
+            LogError("Failure vsnprintf return < 0");
+            result = MU_FAILURE;
+        }
+        else if (s2Length == 0)
+        {
+            // Don't need to reallocate and nothing should be added
+            result = 0;
+        }
+        else
+        {
+            STRING* s1 = (STRING*)handle;
+            char* temp;
+            size_t s1Length = strlen(s1->s);
+            temp = (char*)realloc(s1->s, s1Length + s2Length + 1);
+            if (temp != NULL)
+            {
+                s1->s = temp;
+                va_start(arg_list, format);
+                if (vsnprintf(s1->s + s1Length, s1Length + s2Length + 1, format, arg_list) < 0)
+                {
+                    /* Codes_SRS_STRING_07_043: [If any error is encountered STRING_sprintf shall return a non zero value.] */
+                    LogError("Failure vsnprintf formatting error");
+                    s1->s[s1Length] = '\0';
+                    result = MU_FAILURE;
+                }
+                else
+                {
+                    /* Codes_SRS_STRING_07_044: [On success STRING_sprintf shall return 0.]*/
+                    result = 0;
+                }
+                va_end(arg_list);
+            }
+            else
+            {
+                /* Codes_SRS_STRING_07_043: [If any error is encountered STRING_sprintf shall return a non zero value.] */
+                LogError("Failure unable to reallocate memory");
+                result = MU_FAILURE;
+            }
+        }
+    }
+    return result;
+}
+
+/*this function will quote the string passed as argument string =>"string"*/
+/*returns 0 if success*/ /*doesn't change the string otherwise*/
+/*any other error code is failure*/
+/* Codes_SRS_STRING_07_014: [STRING_quote shall "quote" the supplied STRING_HANDLE and return 0 on success.] */
+int STRING_quote(STRING_HANDLE handle)
+{
+    int result;
+    if (handle == NULL)
+    {
+        /* Codes_SRS_STRING_07_015: [STRING_quote shall return a nonzero value if any of the supplied parameters are NULL.] */
+        result = MU_FAILURE;
+    }
+    else
+    {
+        STRING* s1 = (STRING*)handle;
+        size_t s1Length = strlen(s1->s);
+        char* temp = (char*)realloc(s1->s, s1Length + 2 + 1);/*2 because 2 quotes, 1 because '\0'*/
+        if (temp == NULL)
+        {
+            LogError("Failure reallocating value.");
+            /* Codes_SRS_STRING_07_029: [STRING_quote shall return a nonzero value if any error is encountered.] */
+            result = MU_FAILURE;
+        }
+        else
+        {
+            s1->s = temp;
+            memmove(s1->s + 1, s1->s, s1Length);
+            s1->s[0] = '"';
+            s1->s[s1Length + 1] = '"';
+            s1->s[s1Length + 2] = '\0';
+            result = 0;
+        }
+    }
+    return result;
+}
+/*this function will revert a string to an empty state*/
+/*Returns 0 if the revert was succesful*/
+/* Codes_SRS_STRING_07_022: [STRING_empty shall revert the STRING_HANDLE to an empty state.] */
+int STRING_empty(STRING_HANDLE handle)
+{
+    int result;
+    if (handle == NULL)
+    {
+        /* Codes_SRS_STRING_07_023: [STRING_empty shall return a nonzero value if the STRING_HANDLE is NULL.] */
+        result = MU_FAILURE;
+    }
+    else
+    {
+        STRING* s1 = (STRING*)handle;
+        char* temp = (char*)realloc(s1->s, 1);
+        if (temp == NULL)
+        {
+            LogError("Failure reallocating value.");
+            /* Codes_SRS_STRING_07_030: [STRING_empty shall return a nonzero value if the STRING_HANDLE is NULL.] */
+            result = MU_FAILURE;
+        }
+        else
+        {
+            s1->s = temp;
+            s1->s[0] = '\0';
+            result = 0;
+        }
+    }
+    return result;
+}
+
+/*this function will deallocate a string constructed by str_new*/
+/* Codes_SRS_STRING_07_010: [STRING_delete will free the memory allocated by the STRING_HANDLE.] */
+void STRING_delete(STRING_HANDLE handle)
+{
+    /* Codes_SRS_STRING_07_011: [STRING_delete will not attempt to free anything with a NULL STRING_HANDLE.] */
+    if (handle != NULL)
+    {
+        STRING* value = (STRING*)handle;
+        free(value->s);
+        value->s = NULL;
+        free(value);
+    }
+}
+
+/* Codes_SRS_STRING_07_020: [STRING_c_str shall return the const char* associated with the given STRING_HANDLE.] */
+const char* STRING_c_str(STRING_HANDLE handle)
+{
+    const char* result;
+    if (handle != NULL)
+    {
+        result = ((STRING*)handle)->s;
+    }
+    else
+    {
+        /* Codes_SRS_STRING_07_021: [STRING_c_str shall return NULL if the STRING_HANDLE is NULL.] */
+        result = NULL;
+    }
+    return result;
+}
+
+/* Codes_SRS_STRING_07_024: [STRING_length shall return the length of the underlying char* for the given handle] */
+size_t STRING_length(STRING_HANDLE handle)
+{
+    size_t result = 0;
+    /* Codes_SRS_STRING_07_025: [STRING_length shall return zero if the given handle is NULL.] */
+    if (handle != NULL)
+    {
+        STRING* value = (STRING*)handle;
+        result = strlen(value->s);
+    }
+    return result;
+}
+
+/*Codes_SRS_STRING_02_007: [STRING_construct_n shall construct a STRING_HANDLE from first "n" characters of the string pointed to by psz parameter.]*/
+STRING_HANDLE STRING_construct_n(const char* psz, size_t n)
+{
+    STRING_HANDLE result;
+    /*Codes_SRS_STRING_02_008: [If psz is NULL then STRING_construct_n shall return NULL.] */
+    if (psz == NULL)
+    {
+        result = NULL;
+        LogError("invalid arg (NULL)");
+    }
+    else
+    {
+        size_t len = strlen(psz);
+        /*Codes_SRS_STRING_02_009: [If n is bigger than the size of the string psz, then STRING_construct_n shall return NULL.] */
+        if (n > len)
+        {
+            result = NULL;
+            LogError("invalig arg (n is bigger than the size of the string)");
+        }
+        else
+        {
+            STRING* str;
+            if ((str = (STRING*)malloc(sizeof(STRING))) != NULL)
+            {
+                if ((str->s = (char*)malloc(len + 1)) != NULL)
+                {
+                    (void)memcpy(str->s, psz, n);
+                    str->s[n] = '\0';
+                    result = (STRING_HANDLE)str;
+                }
+                /* Codes_SRS_STRING_02_010: [In all other error cases, STRING_construct_n shall return NULL.]  */
+                else
+                {
+                    LogError("Failure allocating value.");
+                    free(str);
+                    result = NULL;
+                }
+            }
+            else
+            {
+                /* Codes_SRS_STRING_02_010: [In all other error cases, STRING_construct_n shall return NULL.]  */
+                result = NULL;
+            }
+        }
+    }
+    return result;
+}
+
+/* Codes_SRS_STRING_07_034: [STRING_compare returns an integer greater than, equal to, or less than zero, accordingly as the string pointed to by s1 is greater than, equal to, or less than the string s2.] */
+int STRING_compare(STRING_HANDLE s1, STRING_HANDLE s2)
+{
+    int result;
+    if (s1 == NULL && s2 == NULL)
+    {
+        /* Codes_SRS_STRING_07_035: [If h1 and h2 are both NULL then STRING_compare shall return 0.]*/
+        result = 0;
+    }
+    else if (s1 == NULL)
+    {
+        /* Codes_SRS_STRING_07_036: [If h1 is NULL and h2 is nonNULL then STRING_compare shall return 1.]*/
+        result = 1;
+    }
+    else if (s2 == NULL)
+    {
+        /* Codes_SRS_STRING_07_037: [If h2 is NULL and h1 is nonNULL then STRING_compare shall return -1.] */
+        result = -1;
+    }
+    else
+    {
+        /* Codes_SRS_STRING_07_038: [STRING_compare shall compare the char s variable using the strcmp function.] */
+        STRING* value1 = (STRING*)s1;
+        STRING* value2 = (STRING*)s2;
+        result = strcmp(value1->s, value2->s);
+    }
+    return result;
+}
+
+STRING_HANDLE STRING_from_byte_array(const unsigned char* source, size_t size)
+{
+    STRING* result;
+    /*Codes_SRS_STRING_02_022: [ If source is NULL and size > 0 then STRING_from_BUFFER shall fail and return NULL. ]*/
+    if ((source == NULL) && (size > 0))
+    {
+        LogError("invalid parameter (NULL)");
+        result = NULL;
+    }
+    else
+    {
+        /*Codes_SRS_STRING_02_023: [ Otherwise, STRING_from_BUFFER shall build a string that has the same content (byte-by-byte) as source and return a non-NULL handle. ]*/
+        result = (STRING*)malloc(sizeof(STRING));
+        if (result == NULL)
+        {
+            /*Codes_SRS_STRING_02_024: [ If building the string fails, then STRING_from_BUFFER shall fail and return NULL. ]*/
+            LogError("oom - unable to malloc");
+            /*return as is*/
+        }
+        else
+        {
+            /*Codes_SRS_STRING_02_023: [ Otherwise, STRING_from_BUFFER shall build a string that has the same content (byte-by-byte) as source and return a non-NULL handle. ]*/
+            result->s = (char*)malloc(size + 1);
+            if (result->s == NULL)
+            {
+                /*Codes_SRS_STRING_02_024: [ If building the string fails, then STRING_from_BUFFER shall fail and return NULL. ]*/
+                LogError("oom - unable to malloc");
+                free(result);
+                result = NULL;
+            }
+            else
+            {
+                (void)memcpy(result->s, source, size);
+                result->s[size] = '\0'; /*all is fine*/
+            }
+        }
+    }
+    return (STRING_HANDLE)result;
+}
+
+int STRING_replace(STRING_HANDLE handle, char target, char replace)
+{
+    int result;
+    if (handle == NULL)
+    {
+        /* Codes_SRS_STRING_07_046: [ If handle is NULL STRING_replace shall return a non-zero value. ] */
+        result = MU_FAILURE;
+    }
+    else if (target == replace)
+    {
+        /* Codes_SRS_STRING_07_048: [ If target and replace are equal STRING_replace, shall do nothing shall return zero. ] */
+        result = 0;
+    }
+    else
+    {
+        size_t length;
+        size_t index;
+        /* Codes_SRS_STRING_07_047: [ STRING_replace shall replace all instances of target with replace. ] */
+        STRING* str_value = (STRING*)handle;
+        length = strlen(str_value->s);
+        for (index = 0; index < length; index++)
+        {
+            if (str_value->s[index] == target)
+            {
+                str_value->s[index] = replace;
+            }
+        }
+        /* Codes_SRS_STRING_07_049: [ On success STRING_replace shall return zero. ] */
+        result = 0;
+    }
+    return result;
+}
Index: azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/src/urlencode.c
===================================================================
--- azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/src/urlencode.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/src/urlencode.c	(revision 457)
@@ -0,0 +1,350 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+#include <stdlib.h>
+#include <string.h>
+#include "azure_c_shared_utility/gballoc.h"
+#include "azure_c_shared_utility/urlencode.h"
+#include "azure_c_shared_utility/xlogging.h"
+#include "azure_c_shared_utility/strings.h"
+#include "azure_c_shared_utility/crt_abstractions.h"
+
+#define NIBBLE_TO_STRING(c) (char)((c) < 10 ? (c) + '0' : (c) - 10 + 'a')
+#define NIBBLE_FROM_STRING(c) (char)(ISDIGIT(c) ? (c) - '0' : TOUPPER(c) + 10 - 'A')
+#define IS_HEXDIGIT(c) (            \
+    ((c >= '0') && (c <= '9')) ||   \
+    ((c >= 'A') && (c <= 'F')) ||   \
+    ((c >= 'a') && (c <= 'f'))      \
+)
+#define IS_PRINTABLE(c) (                           \
+    (c == 0) ||                                     \
+    (c == '!') ||                                   \
+    (c == '(') || (c == ')') || (c == '*') ||       \
+    (c == '-') || (c == '.') ||                     \
+    ((c >= '0') && (c <= '9')) ||                   \
+    ((c >= 'A') && (c <= 'Z')) ||                   \
+    (c == '_') ||                                   \
+    ((c >= 'a') && (c <= 'z'))                      \
+)
+
+/*The below macros are to be called on the big nibble of a hex value*/
+#define IS_IN_ASCII_RANGE(c) (  \
+    (c >= '0') && (c <= '7')    \
+)
+#define IS_IN_EXTENDED_ASCII_RANGE(c) ( \
+    ((c >= '8') && (c <= '9')) ||       \
+    ((c >= 'A') && (c <= 'F')) ||       \
+    ((c >= 'a') && (c <= 'f'))          \
+)
+#define IS_IN_CONTINUATION_BYTE_RANGE(c) (  \
+    (c == '8') || (c == '9') ||             \
+    (c == 'A') || (c == 'B') ||             \
+    (c == 'a') || (c == 'b')                \
+)
+#define IS_IN_LEADING_BYTE_RANGE(c) (   \
+    ((c >= 'C') && (c <= 'F')) ||       \
+    ((c >= 'c') && (c <= 'f'))          \
+)
+#define IS_IN_UNSUPPORTED_LEADING_BYTE_RANGE(c) (   \
+    ((c >= 'D') && (c <= 'F')) ||                   \
+    ((c >= 'd') && (c <= 'f'))                      \
+)
+
+static size_t URL_PrintableChar(unsigned char charVal, char* buffer)
+{
+    size_t size;
+    if (IS_PRINTABLE(charVal))
+    {
+        buffer[0] = (char)charVal;
+        size = 1;
+    }
+    else
+    {
+        char bigNibbleStr;
+        char littleNibbleStr;
+        unsigned char bigNibbleVal = charVal >> 4;
+        unsigned char littleNibbleVal = charVal & 0x0F;
+
+        if (bigNibbleVal >= 0x0C)
+        {
+            bigNibbleVal -= 0x04;
+        }
+
+        bigNibbleStr = NIBBLE_TO_STRING(bigNibbleVal);
+        littleNibbleStr = NIBBLE_TO_STRING(littleNibbleVal);
+
+        buffer[0] = '%';
+
+        if (charVal < 0x80)
+        {
+            buffer[1] = bigNibbleStr;
+            buffer[2] = littleNibbleStr;
+            size = 3;
+        }
+        else
+        {
+            buffer[1] = 'c';
+            buffer[3] = '%';
+            buffer[4] = bigNibbleStr;
+            buffer[5] = littleNibbleStr;
+            if (charVal < 0xC0)
+            {
+                buffer[2] = '2';
+            }
+            else
+            {
+                buffer[2] = '3';
+            }
+            size = 6;
+        }
+    }
+
+    return size;
+}
+
+static size_t calculateDecodedStringSize(const char* encodedString, size_t len)
+{
+    size_t decodedSize = 0;
+
+    if (encodedString == NULL)
+    {
+        LogError("Null encoded string");
+    }
+    else if (len == 0)
+    {
+        decodedSize = 1; //for null terminator
+    }
+    else
+    {
+        size_t remaining_len = len;
+        size_t next_step = 0;
+        size_t i = 0;
+        while (i < len)
+        {
+            //percent encoded character
+            if (encodedString[i] == '%')
+            {
+                if (remaining_len < 3 || !IS_HEXDIGIT(encodedString[i+1]) || !IS_HEXDIGIT(encodedString[i+2]))
+                {
+                    LogError("Incomplete or invalid percent encoding");
+                    break;
+                }
+                else if (!IS_IN_ASCII_RANGE(encodedString[i+1]))
+                {
+                    LogError("Out of range of characters accepted by this decoder");
+                    break;
+                }
+                else
+                {
+                    decodedSize++;
+                    next_step = 3;
+                }
+            }
+            else if (!IS_PRINTABLE(encodedString[i]))
+            {
+                LogError("Unprintable value in encoded string");
+                break;
+            }
+            //safe character
+            else
+            {
+                decodedSize++;
+                next_step = 1;
+            }
+
+            i += next_step;
+            remaining_len -= next_step;
+        }
+
+        if (encodedString[i] != '\0') //i.e. broke out of above loop due to error
+        {
+            decodedSize = 0;
+        }
+        else
+        {
+            decodedSize++; //add space for the null terminator
+        }
+    }
+    return decodedSize;
+}
+
+static unsigned char charFromNibbles(char bigNibbleStr, char littleNibbleStr)
+{
+    unsigned char bigNibbleVal = NIBBLE_FROM_STRING(bigNibbleStr);
+    unsigned char littleNibbleVal = NIBBLE_FROM_STRING(littleNibbleStr);
+
+    return bigNibbleVal << 4 | littleNibbleVal;
+}
+
+static void createDecodedString(const char* input, size_t input_size, char* output)
+{
+    /* Note that there is no danger of reckless indexing here, as calculateDecodedStringSize()
+    has already checked lengths of strings to ensure the formatting is always correct*/
+    size_t i = 0;
+    while (i <= input_size) //the <= instead of < ensures the '\0' will be copied
+    {
+        if (input[i] != '%')
+        {
+            *output++ = input[i];
+            i++;
+        }
+        else
+        {
+            *output++ = charFromNibbles(input[i+1], input[i+2]);
+            i += 3;
+        }
+    }
+}
+
+static size_t URL_PrintableCharSize(unsigned char charVal)
+{
+    size_t size;
+    if (IS_PRINTABLE(charVal))
+    {
+        size = 1;
+    }
+    else
+    {
+        if (charVal < 0x80)
+        {
+            size = 3;
+        }
+        else
+        {
+            size = 6;
+        }
+    }
+    return size;
+}
+
+static STRING_HANDLE encode_url_data(const char* text)
+{
+    STRING_HANDLE result;
+    size_t lengthOfResult = 0;
+    char* encodedURL;
+    unsigned char currentUnsignedChar;
+    const char* iterator = text;
+
+    /*Codes_SRS_URL_ENCODE_06_003: [If input is a zero length string then URL_Encode will return a zero length string.]*/
+    do
+    {
+        currentUnsignedChar = (unsigned char)(*iterator++);
+        lengthOfResult += URL_PrintableCharSize(currentUnsignedChar);
+    } while (currentUnsignedChar != 0);
+
+    if ((encodedURL = (char*)malloc(lengthOfResult)) == NULL)
+    {
+        /*Codes_SRS_URL_ENCODE_06_002: [If an error occurs during the encoding of input then URL_Encode will return NULL.]*/
+        result = NULL;
+        LogError("URL_Encode:: MALLOC failure on encode.");
+    }
+    else
+    {
+        size_t currentEncodePosition = 0;
+        iterator = text;;
+        do
+        {
+            currentUnsignedChar = (unsigned char)(*iterator++);
+            currentEncodePosition += URL_PrintableChar(currentUnsignedChar, &encodedURL[currentEncodePosition]);
+        } while (currentUnsignedChar != 0);
+
+        result = STRING_new_with_memory(encodedURL);
+        if (result == NULL)
+        {
+            LogError("URL_Encode:: MALLOC failure on encode.");
+            free(encodedURL);
+        }
+    }
+    return result;
+}
+
+STRING_HANDLE URL_EncodeString(const char* textEncode)
+{
+    STRING_HANDLE result;
+    if (textEncode == NULL)
+    {
+        result = NULL;
+    }
+    else
+    {
+        result = encode_url_data(textEncode);
+    }
+    return result;
+}
+
+STRING_HANDLE URL_Encode(STRING_HANDLE input)
+{
+    STRING_HANDLE result;
+    if (input == NULL)
+    {
+        /*Codes_SRS_URL_ENCODE_06_001: [If input is NULL then URL_Encode will return NULL.]*/
+        result = NULL;
+        LogError("URL_Encode:: NULL input");
+    }
+    else
+    {
+        result = encode_url_data(STRING_c_str(input));
+    }
+    return result;
+}
+
+STRING_HANDLE URL_DecodeString(const char* textDecode)
+{
+    STRING_HANDLE result;
+    if (textDecode == NULL)
+    {
+        result = NULL;
+    }
+    else
+    {
+        STRING_HANDLE tempString = STRING_construct(textDecode);
+        if (tempString == NULL)
+        {
+            result = NULL;
+        }
+        else
+        {
+            result = URL_Decode(tempString);
+            STRING_delete(tempString);
+        }
+    }
+    return result;
+}
+
+STRING_HANDLE URL_Decode(STRING_HANDLE input)
+{
+    STRING_HANDLE result;
+    if (input == NULL)
+    {
+        LogError("URL_Decode:: NULL input");
+        result = NULL;
+    }
+    else
+    {
+        size_t decodedStringSize;
+        char* decodedString;
+        const char* inputString = STRING_c_str(input);
+        size_t inputLen = strlen(inputString);
+        if ((decodedStringSize = calculateDecodedStringSize(inputString, inputLen)) == 0)
+        {
+            LogError("URL_Decode:: Invalid input string");
+            result = NULL;
+        }
+        else if ((decodedString = (char*)malloc(decodedStringSize)) == NULL)
+        {
+            LogError("URL_Decode:: MALLOC failure on decode.");
+            result = NULL;
+        }
+        else
+        {
+            createDecodedString(inputString, inputLen, decodedString);
+            result = STRING_new_with_memory(decodedString);
+            if (result == NULL)
+            {
+                LogError("URL_Decode:: MALLOC failure on decode");
+                free(decodedString);
+            }
+        }
+    }
+    return result;
+}
Index: azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/src/usha.c
===================================================================
--- azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/src/usha.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/src/usha.c	(revision 457)
@@ -0,0 +1,263 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+/**************************** usha.c ****************************/
+/******************** See RFC 4634 for details ******************/
+/*
+*  Description:
+*     This file implements a unified interface to the SHA algorithms.
+*/
+
+#include "azure_c_shared_utility/sha.h"
+
+/*
+*  USHAReset
+*
+*  Description:
+*      This function will initialize the SHA Context in preparation
+*      for computing a new SHA message digest.
+*
+*  Parameters:
+*      context: [in/out]
+*          The context to reset.
+*      whichSha: [in]
+*          Selects which SHA reset to call
+*
+*  Returns:
+*      sha Error Code.
+*
+*/
+int USHAReset(USHAContext *ctx, enum SHAversion whichSha)
+{
+    if (ctx) {
+        ctx->whichSha = whichSha;
+        switch (whichSha) {
+        case SHA1:   return SHA1Reset((SHA1Context*)&ctx->ctx);
+        case SHA224: return SHA224Reset((SHA224Context*)&ctx->ctx);
+        case SHA256: return SHA256Reset((SHA256Context*)&ctx->ctx);
+        case SHA384: return SHA384Reset((SHA384Context*)&ctx->ctx);
+        case SHA512: return SHA512Reset((SHA512Context*)&ctx->ctx);
+        default: return shaBadParam;
+        }
+    }
+    else {
+        return shaNull;
+    }
+}
+
+/*
+*  USHAInput
+*
+*  Description:
+*      This function accepts an array of octets as the next portion
+*      of the message.
+*
+*  Parameters:
+*      context: [in/out]
+*          The SHA context to update
+*      message_array: [in]
+*          An array of characters representing the next portion of
+*          the message.
+*      length: [in]
+*          The length of the message in message_array
+*
+*  Returns:
+*      sha Error Code.
+*
+*/
+int USHAInput(USHAContext *ctx,
+    const uint8_t *bytes, unsigned int bytecount)
+{
+    if (ctx) {
+        switch (ctx->whichSha) {
+        case SHA1:
+            return SHA1Input((SHA1Context*)&ctx->ctx, bytes, bytecount);
+        case SHA224:
+            return SHA224Input((SHA224Context*)&ctx->ctx, bytes,
+                bytecount);
+        case SHA256:
+            return SHA256Input((SHA256Context*)&ctx->ctx, bytes,
+                bytecount);
+        case SHA384:
+            return SHA384Input((SHA384Context*)&ctx->ctx, bytes,
+                bytecount);
+        case SHA512:
+            return SHA512Input((SHA512Context*)&ctx->ctx, bytes,
+                bytecount);
+        default: return shaBadParam;
+        }
+    }
+    else {
+        return shaNull;
+    }
+}
+
+/*
+* USHAFinalBits
+*
+* Description:
+*   This function will add in any final bits of the message.
+*
+* Parameters:
+*   context: [in/out]
+*     The SHA context to update
+*   message_bits: [in]
+*     The final bits of the message, in the upper portion of the
+*     byte. (Use 0b###00000 instead of 0b00000### to input the
+*     three bits ###.)
+*   length: [in]
+*     The number of bits in message_bits, between 1 and 7.
+*
+* Returns:
+*   sha Error Code.
+*/
+int USHAFinalBits(USHAContext *ctx,
+const uint8_t bits, unsigned int bitcount)
+{
+    if (ctx) {
+        switch (ctx->whichSha) {
+        case SHA1:
+            return SHA1FinalBits((SHA1Context*)&ctx->ctx, bits, bitcount);
+        case SHA224:
+            return SHA224FinalBits((SHA224Context*)&ctx->ctx, bits,
+                bitcount);
+        case SHA256:
+            return SHA256FinalBits((SHA256Context*)&ctx->ctx, bits,
+                bitcount);
+        case SHA384:
+            return SHA384FinalBits((SHA384Context*)&ctx->ctx, bits,
+                bitcount);
+        case SHA512:
+            return SHA512FinalBits((SHA512Context*)&ctx->ctx, bits,
+                bitcount);
+        default: return shaBadParam;
+        }
+    }
+    else {
+        return shaNull;
+    }
+}
+
+/*
+* USHAResult
+*
+* Description:
+*   This function will return the 160-bit message digest into the
+*   Message_Digest array provided by the caller.
+*   NOTE: The first octet of hash is stored in the 0th element,
+*      the last octet of hash in the 19th element.
+*
+* Parameters:
+*   context: [in/out]
+*     The context to use to calculate the SHA-1 hash.
+*   Message_Digest: [out]
+*     Where the digest is returned.
+*
+* Returns:
+*   sha Error Code.
+*
+*/
+int USHAResult(USHAContext *ctx,
+    uint8_t Message_Digest[USHAMaxHashSize])
+{
+    if (ctx) {
+        switch (ctx->whichSha) {
+        case SHA1:
+            return SHA1Result((SHA1Context*)&ctx->ctx, Message_Digest);
+        case SHA224:
+            return SHA224Result((SHA224Context*)&ctx->ctx, Message_Digest);
+        case SHA256:
+            return SHA256Result((SHA256Context*)&ctx->ctx, Message_Digest);
+        case SHA384:
+            return SHA384Result((SHA384Context*)&ctx->ctx, Message_Digest);
+        case SHA512:
+            return SHA512Result((SHA512Context*)&ctx->ctx, Message_Digest);
+        default: return shaBadParam;
+        }
+    }
+    else {
+        return shaNull;
+    }
+}
+
+/*
+* USHABlockSize
+*
+* Description:
+*   This function will return the blocksize for the given SHA
+*   algorithm.
+*
+* Parameters:
+*   whichSha:
+*     which SHA algorithm to query
+*
+* Returns:
+*   block size
+*
+*/
+int USHABlockSize(enum SHAversion whichSha)
+{
+    switch (whichSha) {
+    case SHA1:   return SHA1_Message_Block_Size;
+    case SHA224: return SHA224_Message_Block_Size;
+    case SHA256: return SHA256_Message_Block_Size;
+    case SHA384: return SHA384_Message_Block_Size;
+    default:
+    case SHA512: return SHA512_Message_Block_Size;
+    }
+}
+
+/*
+* USHAHashSize
+*
+* Description:
+*   This function will return the hashsize for the given SHA
+*   algorithm.
+*
+* Parameters:
+*   whichSha:
+*     which SHA algorithm to query
+*
+* Returns:
+*   hash size
+*
+*/
+int USHAHashSize(enum SHAversion whichSha)
+{
+    switch (whichSha) {
+    case SHA1:   return SHA1HashSize;
+    case SHA224: return SHA224HashSize;
+    case SHA256: return SHA256HashSize;
+    case SHA384: return SHA384HashSize;
+    default:
+    case SHA512: return SHA512HashSize;
+    }
+}
+
+/*
+* USHAHashSizeBits
+*
+* Description:
+*   This function will return the hashsize for the given SHA
+*   algorithm, expressed in bits.
+*
+* Parameters:
+*   whichSha:
+*     which SHA algorithm to query
+*
+* Returns:
+*   hash size in bits
+*
+*/
+int USHAHashSizeBits(enum SHAversion whichSha)
+{
+    switch (whichSha) {
+    case SHA1:   return SHA1HashSizeBits;
+    case SHA224: return SHA224HashSizeBits;
+    case SHA256: return SHA256HashSizeBits;
+    case SHA384: return SHA384HashSizeBits;
+    default:
+    case SHA512: return SHA512HashSizeBits;
+    }
+}
+
Index: azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/src/utf8_checker.c
===================================================================
--- azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/src/utf8_checker.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/src/utf8_checker.c	(revision 457)
@@ -0,0 +1,175 @@
+ // Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+#ifdef __cplusplus
+#include <cstdlib>
+#include <cstdint>
+#else
+#include <stdlib.h>
+#include <stdbool.h>
+#include <stdint.h>
+#endif
+
+#include "azure_c_shared_utility/utf8_checker.h"
+
+bool utf8_checker_is_valid_utf8(const unsigned char* utf8_str, size_t length)
+{
+    bool result;
+
+    if (utf8_str == NULL)
+    {
+        /* Codes_SRS_UTF8_CHECKER_01_002: [ If utf8_checker_is_valid_utf8 is called with NULL utf8_str it shall return false. ]*/
+        result = false;
+    }
+    else
+    {
+        size_t pos = 0;
+
+        /* Codes_SRS_UTF8_CHECKER_01_003: [ If length is 0, utf8_checker_is_valid_utf8 shall consider utf8_str to be valid UTF-8 and return true. ]*/
+        result = true;
+
+        while ((result == true) &&
+               (pos < length))
+        {
+            /* Codes_SRS_UTF8_CHECKER_01_001: [ utf8_checker_is_valid_utf8 shall verify that the sequence of chars pointed to by utf8_str represent UTF-8 encoded codepoints. ]*/
+            if ((utf8_str[pos] >> 3) == 0x1E)
+            {
+                /* 4 bytes */
+                /* Codes_SRS_UTF8_CHECKER_01_009: [ 000uuuuu zzzzyyyy yyxxxxxx 11110uuu 10uuzzzz 10yyyyyy 10xxxxxx ]*/
+                uint32_t code_point = (utf8_str[pos] & 0x07);
+
+                pos++;
+                if ((pos < length) &&
+                    ((utf8_str[pos] >> 6) == 0x02))
+                {
+                    code_point <<= 6;
+                    code_point += utf8_str[pos] & 0x3F;
+
+                    pos++;
+                    if ((pos < length) &&
+                        ((utf8_str[pos] >> 6) == 0x02))
+                    {
+                        code_point <<= 6;
+                        code_point += utf8_str[pos] & 0x3F;
+
+                        pos++;
+                        if ((pos < length) &&
+                            ((utf8_str[pos] >> 6) == 0x02))
+                        {
+                            code_point <<= 6;
+                            code_point += utf8_str[pos] & 0x3F;
+
+                            if (code_point <= 0xFFFF)
+                            {
+                                result = false;
+                            }
+                            else
+                            {
+                                /* Codes_SRS_UTF8_CHECKER_01_005: [ On success it shall return true. ]*/
+                                result = true;
+                                pos++;
+                            }
+                        }
+                        else
+                        {
+                            result = false;
+                        }
+                    }
+                    else
+                    {
+                        result = false;
+                    }
+                }
+                else
+                {
+                    result = false;
+                }
+            }
+            else if ((utf8_str[pos] >> 4) == 0x0E)
+            {
+                /* 3 bytes */
+                /* Codes_SRS_UTF8_CHECKER_01_008: [ zzzzyyyy yyxxxxxx 1110zzzz 10yyyyyy 10xxxxxx ]*/
+                uint32_t code_point = (utf8_str[pos] & 0x0F);
+
+                pos++;
+                if ((pos < length) &&
+                    ((utf8_str[pos] >> 6) == 0x02))
+                {
+                    code_point <<= 6;
+                    code_point += utf8_str[pos] & 0x3F;
+
+                    pos++;
+                    if ((pos < length) &&
+                        ((utf8_str[pos] >> 6) == 0x02))
+                    {
+                        code_point <<= 6;
+                        code_point += utf8_str[pos] & 0x3F;
+
+                        if (code_point <= 0x7FF)
+                        {
+                            result = false;
+                        }
+                        else
+                        {
+                            /* Codes_SRS_UTF8_CHECKER_01_005: [ On success it shall return true. ]*/
+                            result = true;
+                            pos++;
+                        }
+                    }
+                    else
+                    {
+                        result = false;
+                    }
+                }
+                else
+                {
+                    result = false;
+                }
+            }
+            else if ((utf8_str[pos] >> 5) == 0x06)
+            {
+                /* 2 bytes */
+                /* Codes_SRS_UTF8_CHECKER_01_007: [ 00000yyy yyxxxxxx 110yyyyy 10xxxxxx ]*/
+                uint32_t code_point = (utf8_str[pos] & 0x1F);
+
+                pos++;
+                if ((pos < length) &&
+                    ((utf8_str[pos] >> 6) == 0x02))
+                {
+                    code_point <<= 6;
+                    code_point += utf8_str[pos] & 0x3F;
+
+                    if (code_point <= 0x7F)
+                    {
+                        result = false;
+                    }
+                    else
+                    {
+                        /* Codes_SRS_UTF8_CHECKER_01_005: [ On success it shall return true. ]*/
+                        result = true;
+                        pos++;
+                    }
+                }
+                else
+                {
+                    result = false;
+                }
+            }
+            else if ((utf8_str[pos] >> 7) == 0x00)
+            {
+                /* 1 byte */
+                /* Codes_SRS_UTF8_CHECKER_01_006: [ 00000000 0xxxxxxx 0xxxxxxx ]*/
+                /* Codes_SRS_UTF8_CHECKER_01_005: [ On success it shall return true. ]*/
+                result = true;
+                pos++;
+            }
+            else
+            {
+                /* error */
+                result = false;
+            }
+        }
+    }
+
+    return result;
+}
Index: azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/src/uuid.c
===================================================================
--- azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/src/uuid.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/src/uuid.c	(revision 457)
@@ -0,0 +1,167 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+#include <stdlib.h>
+#include <stdio.h>
+#include "azure_c_shared_utility/gballoc.h"
+#include "azure_c_shared_utility/uuid.h"
+#include "azure_c_shared_utility/uniqueid.h"
+#include "azure_c_shared_utility/optimize_size.h"
+#include "azure_c_shared_utility/xlogging.h"
+
+#define UUID_STRING_LENGTH          36
+#define UUID_STRING_SIZE            (UUID_STRING_LENGTH + 1)
+#define __SUCCESS__                 0
+#define UUID_FORMAT_STRING          "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x"
+
+int UUID_from_string(const char* uuid_string, UUID_T* uuid)
+{
+    int result;
+
+    // Codes_SRS_UUID_09_007: [ If uuid_string or uuid are NULL, UUID_from_string shall return a non-zero value ]
+    if (uuid_string == NULL || uuid == NULL)
+    {
+        LogError("Invalid argument (uuid_string=%p, uuid=%p)", uuid_string, uuid);
+        result = MU_FAILURE;
+    }
+    else
+    {
+        size_t uuid_string_length = strlen(uuid_string);
+
+        if (uuid_string_length != UUID_STRING_LENGTH)
+        {
+            LogError("Unexpected size for an UUID string (%lu)", (unsigned long)uuid_string_length);
+            result = MU_FAILURE;
+        }
+        else
+        {
+            // Codes_SRS_UUID_09_008: [ Each pair of digits in uuid_string, excluding dashes, shall be read as a single HEX value and saved on the respective position in uuid ]
+            size_t i, j;
+            char* uuid_bytes;
+
+            uuid_bytes = (char *)uuid;
+            // Codes_SRS_UUID_09_010: [ If no failures occur, UUID_from_string shall return zero ]
+            result = __SUCCESS__;
+
+            for (i = 0, j = 0; i < uuid_string_length; )
+            {
+                if (uuid_string[i] == '-')
+                {
+                    i++;
+                }
+                else
+                {
+                    char double_hex_digit[3] = { 0, 0, 0 };
+
+                    (void)memcpy(double_hex_digit, uuid_string + i, 2);
+
+                    if (sscanf(double_hex_digit, "%02hhx", uuid_bytes + j) != 1)
+                    {
+                        // Codes_SRS_UUID_09_009: [ If uuid fails to be generated, UUID_from_string shall return a non-zero value ]
+                        LogError("Failed decoding UUID string (%lu)", (unsigned long)i);
+                        result = MU_FAILURE;
+                        break;
+                    }
+                    else
+                    {
+                        i += 2;
+                        j++;
+                    }
+                }
+            }
+        }
+    }
+
+    return result;
+}
+
+char* UUID_to_string(const UUID_T* uuid)
+{
+    char* result;
+
+    // Codes_SRS_UUID_09_011: [ If uuid is NULL, UUID_to_string shall return a non-zero value ]
+    if (uuid == NULL)
+    {
+        LogError("Invalid argument (uuid is NULL)");
+        result = NULL;
+    }
+    // Codes_SRS_UUID_09_012: [ UUID_to_string shall allocate a valid UUID string (uuid_string) as per RFC 4122 ]
+    else if ((result = (char*)malloc(sizeof(char) * UUID_STRING_SIZE)) == NULL)
+    {
+        // Codes_SRS_UUID_09_013: [ If uuid_string fails to be allocated, UUID_to_string shall return NULL ]
+        LogError("Failed allocating UUID string");
+    }
+    else
+    {
+        unsigned char* uuid_bytes;
+        int number_of_chars_written;
+
+        uuid_bytes = (unsigned char*)uuid;
+
+        // Codes_SRS_UUID_09_014: [ Each character in uuid shall be written in the respective positions of uuid_string as a 2-digit HEX value ]  
+        number_of_chars_written = sprintf(result, "%" PRI_UUID,
+            UUID_FORMAT_VALUES(uuid_bytes));
+
+        if (number_of_chars_written != UUID_STRING_LENGTH)
+        {
+            // Tests_SRS_UUID_09_015: [ If uuid_string fails to be set, UUID_to_string shall return NULL ]
+            LogError("Failed encoding UUID string");
+            free(result);
+            result = NULL;
+        }
+    }
+
+    // Codes_SRS_UUID_09_016: [ If no failures occur, UUID_to_string shall return uuid_string ]
+    return result;
+}
+
+int UUID_generate(UUID_T* uuid)
+{
+    int result;
+
+    // Codes_SRS_UUID_09_001: [ If uuid is NULL, UUID_generate shall return a non-zero value ]
+    if (uuid == NULL)
+    {
+        LogError("Invalid argument (uuid is NULL)");
+        result = MU_FAILURE;
+    }
+    else
+    {
+        char* uuid_string;
+
+        if ((uuid_string = (char*)malloc(sizeof(char) * UUID_STRING_SIZE)) == NULL)
+        {
+            // Codes_SRS_UUID_09_003: [ If the UUID string fails to be obtained, UUID_generate shall fail and return a non-zero value ]
+            LogError("Failed allocating UUID string");
+            result = MU_FAILURE;
+        }
+        else
+        {
+            (void)memset(uuid_string, 0, sizeof(char) * UUID_STRING_SIZE);
+
+            // Codes_SRS_UUID_09_002: [ UUID_generate shall obtain an UUID string from UniqueId_Generate ]
+            if (UniqueId_Generate(uuid_string, UUID_STRING_SIZE) != UNIQUEID_OK)
+            {
+                // Codes_SRS_UUID_09_003: [ If the UUID string fails to be obtained, UUID_generate shall fail and return a non-zero value ]
+                LogError("Failed generating UUID");
+                result = MU_FAILURE;
+            }
+            // Codes_SRS_UUID_09_004: [ The UUID string shall be parsed into an UUID_T type (16 unsigned char array) and filled in uuid ]
+            else if (UUID_from_string(uuid_string, uuid) != 0)
+            {
+                // Codes_SRS_UUID_09_005: [ If uuid fails to be set, UUID_generate shall fail and return a non-zero value ]
+                LogError("Failed parsing UUID string");
+                result = MU_FAILURE;
+            }
+            else
+            {
+                // Codes_SRS_UUID_09_006: [ If no failures occur, UUID_generate shall return zero ]
+                result = __SUCCESS__;
+            }
+
+            free(uuid_string);
+        }
+    }
+
+    return result;
+}
Index: azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/src/uws_client.c
===================================================================
--- azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/src/uws_client.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/src/uws_client.c	(revision 457)
@@ -0,0 +1,2237 @@
+ // Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+#include <stdlib.h>
+#include <stdint.h>
+#include <limits.h>
+#include <ctype.h>
+#include <limits.h>
+#include "azure_c_shared_utility/gballoc.h"
+#include "azure_c_shared_utility/uws_client.h"
+#include "azure_c_shared_utility/optimize_size.h"
+#include "azure_c_shared_utility/xlogging.h"
+#include "azure_c_shared_utility/xio.h"
+#include "azure_c_shared_utility/singlylinkedlist.h"
+#include "azure_c_shared_utility/socketio.h"
+#include "azure_c_shared_utility/platform.h"
+#include "azure_c_shared_utility/tlsio.h"
+#include "azure_c_shared_utility/crt_abstractions.h"
+#include "azure_c_shared_utility/buffer_.h"
+#include "azure_c_shared_utility/uws_frame_encoder.h"
+#include "azure_c_shared_utility/crt_abstractions.h"
+#include "azure_c_shared_utility/utf8_checker.h"
+#include "azure_c_shared_utility/gb_rand.h"
+#include "azure_c_shared_utility/azure_base64.h"
+#include "azure_c_shared_utility/optionhandler.h"
+#include "azure_c_shared_utility/map.h"
+#include "azure_c_shared_utility/shared_util_options.h"
+
+static const char* UWS_CLIENT_OPTIONS = "uWSClientOptions";
+
+static const char* HTTP_HEADER_KEY_VALUE_SEPARATOR = ": ";
+static const size_t HTTP_HEADER_KEY_VALUE_SEPARATOR_LENGTH = 2;
+static const char* HTTP_HEADER_TERMINATOR = "\r\n";
+static const size_t HTTP_HEADER_TERMINATOR_LENGTH = 2;
+
+/* Requirements not needed as they are optional:
+Codes_SRS_UWS_CLIENT_01_254: [ If an endpoint receives a Ping frame and has not yet sent Pong frame(s) in response to previous Ping frame(s), the endpoint MAY elect to send a Pong frame for only the most recently processed Ping frame. ]
+Codes_SRS_UWS_CLIENT_01_255: [ A Pong frame MAY be sent unsolicited. ]
+Codes_SRS_UWS_CLIENT_01_256: [ A response to an unsolicited Pong frame is not expected. ]
+*/
+
+/* Requirements satisfied by the underlying TLS/socket stack
+Codes_SRS_UWS_CLIENT_01_362: [ To achieve reasonable levels of protection, clients should use only Strong TLS algorithms. ]
+Codes_SRS_UWS_CLIENT_01_289: [ An endpoint SHOULD use a method that cleanly closes the TCP connection, as well as the TLS session, if applicable, discarding any trailing bytes that may have been received. ]
+Codes_SRS_UWS_CLIENT_01_078: [ Otherwise, all further communication on this channel MUST run through the encrypted tunnel [RFC5246]. ]
+Codes_SRS_UWS_CLIENT_01_141: [ masking is done whether or not the WebSocket Protocol is running over TLS. ]
+*/
+
+/* Requirements satisfied by the way the APIs are designed:
+Codes_SRS_UWS_CLIENT_01_211: [One implication of this is that in absence of extensions, senders and receivers must not depend on the presence of specific frame boundaries.]
+*/
+
+typedef enum UWS_STATE_TAG
+{
+    UWS_STATE_CLOSED,
+    UWS_STATE_OPENING_UNDERLYING_IO,
+    UWS_STATE_WAITING_FOR_UPGRADE_RESPONSE,
+    UWS_STATE_OPEN,
+    UWS_STATE_CLOSING_WAITING_FOR_CLOSE,
+    UWS_STATE_CLOSING_SENDING_CLOSE,
+    UWS_STATE_CLOSING_UNDERLYING_IO,
+    UWS_STATE_ERROR
+} UWS_STATE;
+
+typedef struct WS_INSTANCE_PROTOCOL_TAG
+{
+    char* protocol;
+} WS_INSTANCE_PROTOCOL;
+
+typedef struct WS_PENDING_SEND_TAG
+{
+    ON_WS_SEND_FRAME_COMPLETE on_ws_send_frame_complete;
+    void* context;
+    UWS_CLIENT_HANDLE uws_client;
+} WS_PENDING_SEND;
+
+typedef struct UWS_CLIENT_INSTANCE_TAG
+{
+    SINGLYLINKEDLIST_HANDLE pending_sends;
+    XIO_HANDLE underlying_io;
+    char* hostname;
+    char* resource_name;
+    WS_INSTANCE_PROTOCOL* protocols;
+    size_t protocol_count;
+    int port;
+    MAP_HANDLE request_headers;
+    UWS_STATE uws_state;
+    ON_WS_OPEN_COMPLETE on_ws_open_complete;
+    void* on_ws_open_complete_context;
+    ON_WS_FRAME_RECEIVED on_ws_frame_received;
+    void* on_ws_frame_received_context;
+    ON_WS_PEER_CLOSED on_ws_peer_closed;
+    void* on_ws_peer_closed_context;
+    ON_WS_ERROR on_ws_error;
+    void* on_ws_error_context;
+    ON_WS_CLOSE_COMPLETE on_ws_close_complete;
+    void* on_ws_close_complete_context;
+    unsigned char* stream_buffer;
+    size_t stream_buffer_count;
+    unsigned char* fragment_buffer;
+    size_t fragment_buffer_count;
+    unsigned char fragmented_frame_type;
+} UWS_CLIENT_INSTANCE;
+
+/* Codes_SRS_UWS_CLIENT_01_360: [ Connection confidentiality and integrity is provided by running the WebSocket Protocol over TLS (wss URIs). ]*/
+/* Codes_SRS_UWS_CLIENT_01_361: [ WebSocket implementations MUST support TLS and SHOULD employ it when communicating with their peers. ]*/
+/* Codes_SRS_UWS_CLIENT_01_063: [ A client will need to supply a /host/, /port/, /resource name/, and a /secure/ flag, which are the components of a WebSocket URI as discussed in Section 3, along with a list of /protocols/ and /extensions/ to be used. ]*/
+UWS_CLIENT_HANDLE uws_client_create(const char* hostname, unsigned int port, const char* resource_name, bool use_ssl, const WS_PROTOCOL* protocols, size_t protocol_count)
+{
+    UWS_CLIENT_HANDLE result;
+
+    /* Codes_SRS_UWS_CLIENT_01_002: [ If any of the arguments hostname and resource_name is NULL then uws_client_create shall return NULL. ]*/
+    if ((hostname == NULL) ||
+        (resource_name == NULL) ||
+        /* Codes_SRS_UWS_CLIENT_01_411: [ If protocol_count is non zero and protocols is NULL then uws_client_create shall fail and return NULL. ]*/
+        ((protocols == NULL) && (protocol_count > 0)))
+    {
+        LogError("Invalid arguments: hostname = %p, resource_name = %p, protocols = %p, protocol_count = %lu", hostname, resource_name, protocols, (unsigned long)protocol_count);
+        result = NULL;
+    }
+    else
+    {
+        /* Codes_SRS_UWS_CLIENT_01_412: [ If the protocol member of any of the items in the protocols argument is NULL, then uws_client_create shall fail and return NULL. ]*/
+        size_t i;
+        for (i = 0; i < protocol_count; i++)
+        {
+            if (protocols[i].protocol == NULL)
+            {
+                break;
+            }
+        }
+
+        if (i < protocol_count)
+        {
+            LogError("Protocol index %lu has NULL name", (unsigned long)i);
+            result = NULL;
+        }
+        else
+        {
+            /* Codes_SRS_UWS_CLIENT_01_001: [uws_client_create shall create an instance of uws and return a non-NULL handle to it.]*/
+            result = (UWS_CLIENT_HANDLE)malloc(sizeof(UWS_CLIENT_INSTANCE));
+            if (result == NULL)
+            {
+                /* Codes_SRS_UWS_CLIENT_01_003: [ If allocating memory for the new uws instance fails then uws_client_create shall return NULL. ]*/
+                LogError("Could not allocate uWS instance");
+            }
+            else
+            {
+                (void)memset(result, 0, sizeof(UWS_CLIENT_INSTANCE));
+
+                /* Codes_SRS_UWS_CLIENT_01_004: [ The argument hostname shall be copied for later use. ]*/
+                if (mallocAndStrcpy_s(&result->hostname, hostname) != 0)
+                {
+                    /* Codes_SRS_UWS_CLIENT_01_392: [ If allocating memory for the copy of the hostname argument fails, then uws_client_create shall return NULL. ]*/
+                    LogError("Could not copy hostname.");
+                    free(result);
+                    result = NULL;
+                }
+                else
+                {
+                    /* Codes_SRS_UWS_CLIENT_01_404: [ The argument resource_name shall be copied for later use. ]*/
+                    if (mallocAndStrcpy_s(&result->resource_name, resource_name) != 0)
+                    {
+                        /* Codes_SRS_UWS_CLIENT_01_405: [ If allocating memory for the copy of the resource argument fails, then uws_client_create shall return NULL. ]*/
+                        LogError("Could not copy resource.");
+                        free(result->hostname);
+                        free(result);
+                        result = NULL;
+                    }
+                    else if ((result->request_headers = Map_Create(NULL)) == NULL)
+                    {
+                        LogError("Failed allocating MAP for request headers");
+                        free(result->resource_name);
+                        free(result->hostname);
+                        free(result);
+                        result = NULL;
+                    }
+                    else
+                    {
+                        /* Codes_SRS_UWS_CLIENT_01_017: [ uws_client_create shall create a pending send IO list that is to be used to queue send packets by calling singlylinkedlist_create. ]*/
+                        result->pending_sends = singlylinkedlist_create();
+                        if (result->pending_sends == NULL)
+                        {
+                            /* Codes_SRS_UWS_CLIENT_01_018: [ If singlylinkedlist_create fails then uws_client_create shall fail and return NULL. ]*/
+                            LogError("Could not allocate pending send frames list");
+                            Map_Destroy(result->request_headers);
+                            free(result->resource_name);
+                            free(result->hostname);
+                            free(result);
+                            result = NULL;
+                        }
+                        else
+                        {
+                            if (use_ssl == true)
+                            {
+                                TLSIO_CONFIG tlsio_config;
+
+                                /* Codes_SRS_UWS_CLIENT_01_006: [ If use_ssl is true then uws_client_create shall obtain the interface used to create a tlsio instance by calling platform_get_default_tlsio. ]*/
+                                /* Codes_SRS_UWS_CLIENT_01_076: [ If /secure/ is true, the client MUST perform a TLS handshake over the connection after opening the connection and before sending the handshake data [RFC2818]. ]*/
+                                const IO_INTERFACE_DESCRIPTION* tlsio_interface = platform_get_default_tlsio();
+                                if (tlsio_interface == NULL)
+                                {
+                                    /* Codes_SRS_UWS_CLIENT_01_007: [ If obtaining the underlying IO interface fails, then uws_client_create shall fail and return NULL. ]*/
+                                    LogError("NULL TLSIO interface description");
+                                    result->underlying_io = NULL;
+                                }
+                                else
+                                {
+                                    SOCKETIO_CONFIG socketio_config;
+
+                                    /* Codes_SRS_UWS_CLIENT_01_013: [ The create arguments for the tls IO (when use_ssl is 1) shall have: ]*/
+                                    /* Codes_SRS_UWS_CLIENT_01_014: [ - hostname set to the hostname argument passed to uws_client_create. ]*/
+                                    /* Codes_SRS_UWS_CLIENT_01_015: [ - port set to the port argument passed to uws_client_create. ]*/
+                                    socketio_config.hostname = hostname;
+                                    socketio_config.port = port;
+                                    socketio_config.accepted_socket = NULL;
+
+                                    tlsio_config.hostname = hostname;
+                                    tlsio_config.port = port;
+                                    tlsio_config.underlying_io_interface = socketio_get_interface_description();
+                                    tlsio_config.underlying_io_parameters = &socketio_config;
+
+                                    result->underlying_io = xio_create(tlsio_interface, &tlsio_config);
+                                    if (result->underlying_io == NULL)
+                                    {
+                                        LogError("Cannot create underlying TLS IO.");
+                                    }
+                                    else
+                                    {
+                                        // Set the underlying socket to turn on renegotiation
+                                        bool set_renegotiation = true;
+                                        xio_setoption(result->underlying_io, OPTION_SET_TLS_RENEGOTIATION, &set_renegotiation);
+                                    }
+                                }
+                            }
+                            else
+                            {
+                                SOCKETIO_CONFIG socketio_config;
+                                /* Codes_SRS_UWS_CLIENT_01_005: [ If use_ssl is false then uws_client_create shall obtain the interface used to create a socketio instance by calling socketio_get_interface_description. ]*/
+                                const IO_INTERFACE_DESCRIPTION* socketio_interface = socketio_get_interface_description();
+                                if (socketio_interface == NULL)
+                                {
+                                    /* Codes_SRS_UWS_CLIENT_01_007: [ If obtaining the underlying IO interface fails, then uws_client_create shall fail and return NULL. ]*/
+                                    LogError("NULL socketio interface description");
+                                    result->underlying_io = NULL;
+                                }
+                                else
+                                {
+                                    /* Codes_SRS_UWS_CLIENT_01_010: [ The create arguments for the socket IO (when use_ssl is 0) shall have: ]*/
+                                    /* Codes_SRS_UWS_CLIENT_01_011: [ - hostname set to the hostname argument passed to uws_client_create. ]*/
+                                    /* Codes_SRS_UWS_CLIENT_01_012: [ - port set to the port argument passed to uws_client_create. ]*/
+                                    socketio_config.hostname = hostname;
+                                    socketio_config.port = port;
+                                    socketio_config.accepted_socket = NULL;
+
+                                    /* Codes_SRS_UWS_CLIENT_01_008: [ The obtained interface shall be used to create the IO used as underlying IO by the newly created uws instance. ]*/
+                                    /* Codes_SRS_UWS_CLIENT_01_009: [ The underlying IO shall be created by calling xio_create. ]*/
+                                    result->underlying_io = xio_create(socketio_interface, &socketio_config);
+                                    if (result->underlying_io == NULL)
+                                    {
+                                        LogError("Cannot create underlying socket IO.");
+                                    }
+                                }
+                            }
+
+                            if (result->underlying_io == NULL)
+                            {
+                                /* Codes_SRS_UWS_CLIENT_01_016: [ If xio_create fails, then uws_client_create shall fail and return NULL. ]*/
+                                singlylinkedlist_destroy(result->pending_sends);
+                                Map_Destroy(result->request_headers);
+                                free(result->resource_name);
+                                free(result->hostname);
+                                free(result);
+                                result = NULL;
+                            }
+                            else
+                            {
+                                result->uws_state = UWS_STATE_CLOSED;
+                                /* Codes_SRS_UWS_CLIENT_01_403: [ The argument port shall be copied for later use. ]*/
+                                result->port = port;
+
+                                result->fragmented_frame_type = WS_FRAME_TYPE_UNKNOWN;
+
+                                result->protocol_count = protocol_count;
+
+                                /* Codes_SRS_UWS_CLIENT_01_410: [ The protocols argument shall be allowed to be NULL, in which case no protocol is to be specified by the client in the upgrade request. ]*/
+                                if (protocols == NULL)
+                                {
+                                    result->protocols = NULL;
+                                }
+                                else
+                                {
+                                    result->protocols = (WS_INSTANCE_PROTOCOL*)malloc(sizeof(WS_INSTANCE_PROTOCOL) * protocol_count);
+                                    if (result->protocols == NULL)
+                                    {
+                                        /* Codes_SRS_UWS_CLIENT_01_414: [ If allocating memory for the copied protocol information fails then uws_client_create shall fail and return NULL. ]*/
+                                        LogError("Cannot allocate memory for the protocols array.");
+                                        xio_destroy(result->underlying_io);
+                                        singlylinkedlist_destroy(result->pending_sends);
+                                        Map_Destroy(result->request_headers);
+                                        free(result->resource_name);
+                                        free(result->hostname);
+                                        free(result);
+                                        result = NULL;
+                                    }
+                                    else
+                                    {
+                                        /* Codes_SRS_UWS_CLIENT_01_413: [ The protocol information indicated by protocols and protocol_count shall be copied for later use (for constructing the upgrade request). ]*/
+                                        for (i = 0; i < protocol_count; i++)
+                                        {
+                                            if (mallocAndStrcpy_s(&result->protocols[i].protocol, protocols[i].protocol) != 0)
+                                            {
+                                                /* Codes_SRS_UWS_CLIENT_01_414: [ If allocating memory for the copied protocol information fails then uws_client_create shall fail and return NULL. ]*/
+                                                LogError("Cannot allocate memory for the protocol index %u.", (unsigned int)i);
+                                                break;
+                                            }
+                                        }
+
+                                        if (i < protocol_count)
+                                        {
+                                            size_t j;
+
+                                            for (j = 0; j < i; j++)
+                                            {
+                                                free(result->protocols[j].protocol);
+                                            }
+
+                                            free(result->protocols);
+                                            xio_destroy(result->underlying_io);
+                                            singlylinkedlist_destroy(result->pending_sends);
+                                            Map_Destroy(result->request_headers);
+                                            free(result->resource_name);
+                                            free(result->hostname);
+                                            free(result);
+                                            result = NULL;
+                                        }
+                                        else
+                                        {
+                                            result->protocol_count = protocol_count;
+                                        }
+                                    }
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    return result;
+}
+
+UWS_CLIENT_HANDLE uws_client_create_with_io(const IO_INTERFACE_DESCRIPTION* io_interface, void* io_create_parameters, const char* hostname, unsigned int port, const char* resource_name, const WS_PROTOCOL* protocols, size_t protocol_count)
+{
+    UWS_CLIENT_HANDLE result;
+
+    /* Codes_SRS_UWS_CLIENT_01_516: [ If any of the arguments io_interface, hostname and resource_name is NULL then uws_client_create_with_io shall return NULL. ]*/
+    if ((hostname == NULL) ||
+        (io_interface == NULL) ||
+        (resource_name == NULL) ||
+        /* Codes_SRS_UWS_CLIENT_01_525: [ If protocol_count is non zero and protocols is NULL then uws_client_create_with_io shall fail and return NULL. ]*/
+        ((protocols == NULL) && (protocol_count > 0)))
+    {
+        LogError("Invalid arguments: io_interface = %p, resource_name = %p, protocols = %p, protocol_count = %lu", io_interface, resource_name, protocols, (unsigned long)protocol_count);
+        result = NULL;
+    }
+    else
+    {
+        size_t i;
+        for (i = 0; i < protocol_count; i++)
+        {
+            if (protocols[i].protocol == NULL)
+            {
+                break;
+            }
+        }
+
+        if (i < protocol_count)
+        {
+            /* Codes_SRS_UWS_CLIENT_01_526: [ If the protocol member of any of the items in the protocols argument is NULL, then uws_client_create_with_io shall fail and return NULL. ]*/
+            LogError("Protocol index %lu has NULL name", (unsigned long)i);
+            result = NULL;
+        }
+        else
+        {
+            /* Codes_SRS_UWS_CLIENT_01_515: [ uws_client_create_with_io shall create an instance of uws and return a non-NULL handle to it. ]*/
+            result = (UWS_CLIENT_HANDLE)malloc(sizeof(UWS_CLIENT_INSTANCE));
+            if (result == NULL)
+            {
+                /* Codes_SRS_UWS_CLIENT_01_517: [ If allocating memory for the new uws instance fails then uws_client_create_with_io shall return NULL. ]*/
+                LogError("Could not allocate uWS instance");
+            }
+            else
+            {
+                memset(result, 0, sizeof(UWS_CLIENT_INSTANCE));
+
+                /* Codes_SRS_UWS_CLIENT_01_518: [ The argument hostname shall be copied for later use. ]*/
+                if (mallocAndStrcpy_s(&result->hostname, hostname) != 0)
+                {
+                    /* Codes_SRS_UWS_CLIENT_01_519: [ If allocating memory for the copy of the hostname argument fails, then uws_client_create shall return NULL. ]*/
+                    LogError("Could not copy hostname.");
+                    free(result);
+                    result = NULL;
+                }
+                else
+                {
+                    /* Codes_SRS_UWS_CLIENT_01_523: [ The argument resource_name shall be copied for later use. ]*/
+                    if (mallocAndStrcpy_s(&result->resource_name, resource_name) != 0)
+                    {
+                        /* Codes_SRS_UWS_CLIENT_01_529: [ If allocating memory for the copy of the resource_name argument fails, then uws_client_create_with_io shall return NULL. ]*/
+                        LogError("Could not copy resource.");
+                        free(result->hostname);
+                        free(result);
+                        result = NULL;
+                    }
+                    else if ((result->request_headers = Map_Create(NULL)) == NULL)
+                    {
+                        LogError("Failed allocating MAP for request headers");
+                        free(result->resource_name);
+                        free(result->hostname);
+                        free(result);
+                        result = NULL;
+                    }
+                    else
+                    {
+                        /* Codes_SRS_UWS_CLIENT_01_530: [ uws_client_create_with_io shall create a pending send IO list that is to be used to queue send packets by calling singlylinkedlist_create. ]*/
+                        result->pending_sends = singlylinkedlist_create();
+                        if (result->pending_sends == NULL)
+                        {
+                            /* Codes_SRS_UWS_CLIENT_01_531: [ If singlylinkedlist_create fails then uws_client_create_with_io shall fail and return NULL. ]*/
+                            LogError("Could not allocate pending send frames list");
+                            Map_Destroy(result->request_headers);
+                            free(result->resource_name);
+                            free(result->hostname);
+                            free(result);
+                            result = NULL;
+                        }
+                        else
+                        {
+                            /* Codes_SRS_UWS_CLIENT_01_521: [ The underlying IO shall be created by calling xio_create, while passing as arguments the io_interface and io_create_parameters argument values. ]*/
+                            result->underlying_io = xio_create(io_interface, io_create_parameters);
+                            if (result->underlying_io == NULL)
+                            {
+                                /* Codes_SRS_UWS_CLIENT_01_522: [ If xio_create fails, then uws_client_create_with_io shall fail and return NULL. ]*/
+                                LogError("Cannot create underlying IO.");
+                                singlylinkedlist_destroy(result->pending_sends);
+                                Map_Destroy(result->request_headers);
+                                free(result->resource_name);
+                                free(result->hostname);
+                                free(result);
+                                result = NULL;
+                            }
+                            else
+                            {
+                                // Set the underlying socket to turn on renegotiation
+                                bool set_renegotiation = true;
+                                (void)xio_setoption(result->underlying_io, OPTION_SET_TLS_RENEGOTIATION, &set_renegotiation);
+
+                                result->uws_state = UWS_STATE_CLOSED;
+
+                                /* Codes_SRS_UWS_CLIENT_01_520: [ The argument port shall be copied for later use. ]*/
+                                result->port = port;
+
+                                result->fragmented_frame_type = WS_FRAME_TYPE_UNKNOWN;
+
+                                result->protocol_count = protocol_count;
+
+                                /* Codes_SRS_UWS_CLIENT_01_524: [ The protocols argument shall be allowed to be NULL, in which case no protocol is to be specified by the client in the upgrade request. ]*/
+                                if (protocols == NULL)
+                                {
+                                    result->protocols = NULL;
+                                }
+                                else
+                                {
+                                    result->protocols = (WS_INSTANCE_PROTOCOL*)malloc(sizeof(WS_INSTANCE_PROTOCOL) * protocol_count);
+                                    if (result->protocols == NULL)
+                                    {
+                                        /* Codes_SRS_UWS_CLIENT_01_414: [ If allocating memory for the copied protocol information fails then uws_client_create shall fail and return NULL. ]*/
+                                        LogError("Cannot allocate memory for the protocols array.");
+                                        xio_destroy(result->underlying_io);
+                                        singlylinkedlist_destroy(result->pending_sends);
+                                        Map_Destroy(result->request_headers);
+                                        free(result->resource_name);
+                                        free(result->hostname);
+                                        free(result);
+                                        result = NULL;
+                                    }
+                                    else
+                                    {
+                                        /* Codes_SRS_UWS_CLIENT_01_527: [ The protocol information indicated by protocols and protocol_count shall be copied for later use (for constructing the upgrade request). ]*/
+                                        for (i = 0; i < protocol_count; i++)
+                                        {
+                                            if (mallocAndStrcpy_s(&result->protocols[i].protocol, protocols[i].protocol) != 0)
+                                            {
+                                                /* Codes_SRS_UWS_CLIENT_01_528: [ If allocating memory for the copied protocol information fails then uws_client_create_with_io shall fail and return NULL. ]*/
+                                                LogError("Cannot allocate memory for the protocol index %u.", (unsigned int)i);
+                                                break;
+                                            }
+                                        }
+
+                                        if (i < protocol_count)
+                                        {
+                                            size_t j;
+
+                                            for (j = 0; j < i; j++)
+                                            {
+                                                free(result->protocols[j].protocol);
+                                            }
+
+                                            free(result->protocols);
+                                            xio_destroy(result->underlying_io);
+                                            singlylinkedlist_destroy(result->pending_sends);
+                                            Map_Destroy(result->request_headers);
+                                            free(result->resource_name);
+                                            free(result->hostname);
+                                            free(result);
+                                            result = NULL;
+                                        }
+                                        else
+                                        {
+                                            result->protocol_count = protocol_count;
+                                        }
+                                    }
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    return result;
+}
+
+void uws_client_destroy(UWS_CLIENT_HANDLE uws_client)
+{
+    /* Codes_SRS_UWS_CLIENT_01_020: [ If uws_client is NULL, uws_client_destroy shall do nothing. ]*/
+    if (uws_client == NULL)
+    {
+        LogError("NULL uws handle");
+    }
+    else
+    {
+        free(uws_client->stream_buffer);
+        free(uws_client->fragment_buffer);
+
+        /* Codes_SRS_UWS_CLIENT_01_021: [ uws_client_destroy shall perform a close action if the uws instance has already been open. ]*/
+        switch (uws_client->uws_state)
+        {
+        default:
+            break;
+
+        case UWS_STATE_OPEN:
+        case UWS_STATE_ERROR:
+            uws_client_close_async(uws_client, NULL, NULL);
+            break;
+        }
+
+        if (uws_client->protocol_count > 0)
+        {
+            size_t i;
+
+            /* Codes_SRS_UWS_CLIENT_01_437: [ uws_client_destroy shall free the protocols array allocated in uws_client_create. ]*/
+            for (i = 0; i < uws_client->protocol_count; i++)
+            {
+                free(uws_client->protocols[i].protocol);
+            }
+
+            free(uws_client->protocols);
+        }
+
+        /* Codes_SRS_UWS_CLIENT_01_019: [ uws_client_destroy shall free all resources associated with the uws instance. ]*/
+        /* Codes_SRS_UWS_CLIENT_01_023: [ uws_client_destroy shall ensure the underlying IO created in uws_client_open_async is destroyed by calling xio_destroy. ]*/
+        if (uws_client->underlying_io != NULL)
+        {
+            xio_destroy(uws_client->underlying_io);
+            uws_client->underlying_io = NULL;
+        }
+
+        /* Codes_SRS_UWS_CLIENT_01_024: [ uws_client_destroy shall free the list used to track the pending sends by calling singlylinkedlist_destroy. ]*/
+        singlylinkedlist_destroy(uws_client->pending_sends);
+        free(uws_client->resource_name);
+        free(uws_client->hostname);
+        Map_Destroy(uws_client->request_headers);
+        free(uws_client);
+    }
+}
+
+static void indicate_ws_open_complete_error(UWS_CLIENT_INSTANCE* uws_client, WS_OPEN_RESULT ws_open_result)
+{
+    /* Codes_SRS_UWS_CLIENT_01_409: [ After any error is indicated by on_ws_open_complete, a subsequent uws_client_open_async shall be possible. ]*/
+    uws_client->uws_state = UWS_STATE_CLOSED;
+    uws_client->on_ws_open_complete(uws_client->on_ws_open_complete_context, ws_open_result);
+}
+
+static void indicate_ws_open_complete_error_and_close(UWS_CLIENT_INSTANCE* uws_client, WS_OPEN_RESULT ws_open_result)
+{
+    (void)xio_close(uws_client->underlying_io, NULL, NULL);
+    indicate_ws_open_complete_error(uws_client, ws_open_result);
+}
+
+static void indicate_ws_error(UWS_CLIENT_INSTANCE* uws_client, WS_ERROR error_code)
+{
+    uws_client->uws_state = UWS_STATE_ERROR;
+    uws_client->on_ws_error(uws_client->on_ws_error_context, error_code);
+}
+
+static void indicate_ws_close_complete(UWS_CLIENT_INSTANCE* uws_client)
+{
+    uws_client->uws_state = UWS_STATE_CLOSED;
+
+    /* Codes_SRS_UWS_CLIENT_01_496: [ If the close was initiated by the peer no on_ws_close_complete shall be called. ]*/
+    if (uws_client->on_ws_close_complete != NULL)
+    {
+        /* Codes_SRS_UWS_CLIENT_01_491: [ When calling on_ws_close_complete callback, the on_ws_close_complete_context argument shall be passed to it. ]*/
+        uws_client->on_ws_close_complete(uws_client->on_ws_close_complete_context);
+    }
+}
+
+// This callback usage needs to be either verified and commented or integrated into
+// the state machine.
+static void unchecked_on_send_complete(void* context, IO_SEND_RESULT send_result)
+{
+    (void)context;
+    (void)send_result;
+}
+
+static int send_close_frame(UWS_CLIENT_INSTANCE* uws_client, unsigned int close_error_code)
+{
+    unsigned char* close_frame;
+    unsigned char close_frame_payload[2];
+    size_t close_frame_length;
+    int result;
+    BUFFER_HANDLE close_frame_buffer;
+
+    close_frame_payload[0] = (unsigned char)(close_error_code >> 8);
+    close_frame_payload[1] = (unsigned char)(close_error_code & 0xFF);
+
+    /* Codes_SRS_UWS_CLIENT_01_140: [ To avoid confusing network intermediaries (such as intercepting proxies) and for security reasons that are further discussed in Section 10.3, a client MUST mask all frames that it sends to the server (see Section 5.3 for further details). ]*/
+    close_frame_buffer = uws_frame_encoder_encode(WS_CLOSE_FRAME, close_frame_payload, sizeof(close_frame_payload), true, true, 0);
+    if (close_frame_buffer == NULL)
+    {
+        LogError("Encoding of CLOSE failed.");
+        result = MU_FAILURE;
+    }
+    else
+    {
+        close_frame = BUFFER_u_char(close_frame_buffer);
+        close_frame_length = BUFFER_length(close_frame_buffer);
+
+        /* Codes_SRS_UWS_CLIENT_01_471: [ The callback on_underlying_io_close_sent shall be passed as argument to xio_send. ]*/
+        if (xio_send(uws_client->underlying_io, close_frame, close_frame_length, unchecked_on_send_complete, NULL) != 0)
+        {
+            LogError("Sending CLOSE frame failed.");
+            result = MU_FAILURE;
+        }
+        else
+        {
+            result = 0;
+        }
+
+        BUFFER_delete(close_frame_buffer);
+    }
+
+    return result;
+}
+
+static void indicate_ws_error_and_close(UWS_CLIENT_INSTANCE* uws_client, WS_ERROR error_code, unsigned int close_error_code)
+{
+    uws_client->uws_state = UWS_STATE_ERROR;
+
+    (void)send_close_frame(uws_client, close_error_code);
+
+    uws_client->on_ws_error(uws_client->on_ws_error_context, error_code);
+}
+
+static char* get_request_headers(MAP_HANDLE headers)
+{
+    char* result;
+    const char* const* keys;
+    const char* const* values;
+    size_t count;
+
+    if (Map_GetInternals(headers, &keys, &values, &count) != MAP_OK)
+    {
+        LogError("Failed getting the request headers");
+        result = NULL;
+    }
+    else
+    {
+        size_t length = 0;
+        size_t i;
+
+        for (i = 0; i < count; i++)
+        {
+            // 4 = 2 (": ") + 2 ("\r\n")
+            length += strlen(keys[i]) + strlen(values[i]) + 4;
+        }
+
+        if ((result = (char*)malloc(sizeof(char) * (length + 1))) == NULL)
+        {
+            LogError("Failed allocating string for request headers");
+            result = NULL;
+        }
+        else
+        {
+            size_t position = 0;
+
+            for (i = 0; i < count; i++)
+            {
+                size_t key_length = strlen(keys[i]);
+                size_t value_length = strlen(values[i]);
+
+                (void)memcpy(result + position, keys[i], key_length);
+                position += key_length;
+                (void)memcpy(result + position, HTTP_HEADER_KEY_VALUE_SEPARATOR, HTTP_HEADER_KEY_VALUE_SEPARATOR_LENGTH);
+                position += HTTP_HEADER_KEY_VALUE_SEPARATOR_LENGTH;
+                (void)memcpy(result + position, values[i], value_length);
+                position += value_length;
+                (void)memcpy(result + position, HTTP_HEADER_TERMINATOR, HTTP_HEADER_TERMINATOR_LENGTH);
+                position += HTTP_HEADER_TERMINATOR_LENGTH;
+            }
+
+            result[position] = '\0';
+        }
+    }
+
+    return result;
+}
+
+static void on_underlying_io_open_complete(void* context, IO_OPEN_RESULT open_result)
+{
+    UWS_CLIENT_HANDLE uws_client = (UWS_CLIENT_HANDLE)context;
+    /* Codes_SRS_UWS_CLIENT_01_401: [ If on_underlying_io_open_complete is called with a NULL context, on_underlying_io_open_complete shall do nothing. ]*/
+    if (uws_client == NULL)
+    {
+        LogError("NULL context");
+    }
+    else
+    {
+        switch (uws_client->uws_state)
+        {
+        default:
+        case UWS_STATE_WAITING_FOR_UPGRADE_RESPONSE:
+            /* Codes_SRS_UWS_CLIENT_01_407: [ When on_underlying_io_open_complete is called when the uws instance has send the upgrade request but it is waiting for the response, an error shall be reported to the user by calling the on_ws_open_complete with WS_OPEN_ERROR_MULTIPLE_UNDERLYING_IO_OPEN_EVENTS. ]*/
+            LogError("underlying on_io_open_complete was called again after upgrade request was sent.");
+            indicate_ws_open_complete_error_and_close(uws_client, WS_OPEN_ERROR_MULTIPLE_UNDERLYING_IO_OPEN_EVENTS);
+            break;
+        case UWS_STATE_OPENING_UNDERLYING_IO:
+            switch (open_result)
+            {
+            default:
+            case IO_OPEN_ERROR:
+                /* Codes_SRS_UWS_CLIENT_01_369: [ When on_underlying_io_open_complete is called with IO_OPEN_ERROR while uws is OPENING (uws_client_open_async was called), uws shall report that the open failed by calling the on_ws_open_complete callback passed to uws_client_open_async with WS_OPEN_ERROR_UNDERLYING_IO_OPEN_FAILED. ]*/
+                indicate_ws_open_complete_error(uws_client, WS_OPEN_ERROR_UNDERLYING_IO_OPEN_FAILED);
+                break;
+
+            case IO_OPEN_CANCELLED:
+                /* Codes_SRS_UWS_CLIENT_01_402: [ When on_underlying_io_open_complete is called with IO_OPEN_CANCELLED while uws is OPENING (uws_client_open_async was called), uws shall report that the open failed by calling the on_ws_open_complete callback passed to uws_client_open_async with WS_OPEN_ERROR_UNDERLYING_IO_OPEN_CANCELLED. ]*/
+                indicate_ws_open_complete_error(uws_client, WS_OPEN_ERROR_UNDERLYING_IO_OPEN_CANCELLED);
+                break;
+
+            case IO_OPEN_OK:
+            {
+                int upgrade_request_length;
+                char* upgrade_request;
+                size_t i;
+                unsigned char nonce[16];
+                STRING_HANDLE base64_nonce;
+                char* request_headers = NULL;
+
+                /* Codes_SRS_UWS_CLIENT_01_089: [ The value of this header field MUST be a nonce consisting of a randomly selected 16-byte value that has been base64-encoded (see Section 4 of [RFC4648]). ]*/
+                /* Codes_SRS_UWS_CLIENT_01_090: [ The nonce MUST be selected randomly for each connection. ]*/
+                for (i = 0; i < sizeof(nonce); i++)
+                {
+                    nonce[i] = (unsigned char)gb_rand();
+                }
+
+                /* Codes_SRS_UWS_CLIENT_01_497: [ The nonce needed for the upgrade request shall be Base64 encoded with Azure_Base64_Encode_Bytes. ]*/
+                base64_nonce = Azure_Base64_Encode_Bytes(nonce, sizeof(nonce));
+                if (base64_nonce == NULL)
+                {
+                    /* Codes_SRS_UWS_CLIENT_01_498: [ If Base64 encoding the nonce for the upgrade request fails, then the uws client shall report that the open failed by calling the on_ws_open_complete callback passed to uws_client_open_async with WS_OPEN_ERROR_BASE64_ENCODE_FAILED. ]*/
+                    LogError("Cannot construct the WebSocket upgrade request");
+                    indicate_ws_open_complete_error(uws_client, WS_OPEN_ERROR_BASE64_ENCODE_FAILED);
+                }
+                else if ((request_headers = get_request_headers(uws_client->request_headers)) == NULL)
+                {
+                    LogError("Cannot construct the WebSocket request headers");
+                    indicate_ws_open_complete_error(uws_client, WS_OPEN_ERROR_CONSTRUCTING_UPGRADE_REQUEST);
+                }
+                else
+                {
+                    /* Codes_SRS_UWS_CLIENT_01_371: [ When on_underlying_io_open_complete is called with IO_OPEN_OK while uws is OPENING (uws_client_open_async was called), uws shall prepare the WebSockets upgrade request. ]*/
+                    /* Codes_SRS_UWS_CLIENT_01_081: [ The handshake consists of an HTTP Upgrade request, along with a list of required and optional header fields. ]*/
+                    /* Codes_SRS_UWS_CLIENT_01_082: [ The handshake MUST be a valid HTTP request as specified by [RFC2616]. ]*/
+                    /* Codes_SRS_UWS_CLIENT_01_083: [ The method of the request MUST be GET, and the HTTP version MUST be at least 1.1. ]*/
+                    /* Codes_SRS_UWS_CLIENT_01_084: [ The "Request-URI" part of the request MUST match the /resource name/ defined in Section 3 (a relative URI) or be an absolute http/https URI that, when parsed, has a /resource name/, /host/, and /port/ that match the corresponding ws/wss URI. ]*/
+                    /* Codes_SRS_UWS_CLIENT_01_085: [ The request MUST contain a |Host| header field whose value contains /host/ plus optionally ":" followed by /port/ (when not using the default port). ]*/
+                    /* Codes_SRS_UWS_CLIENT_01_086: [ The request MUST contain an |Upgrade| header field whose value MUST include the "websocket" keyword. ]*/
+                    /* Codes_SRS_UWS_CLIENT_01_087: [ The request MUST contain a |Connection| header field whose value MUST include the "Upgrade" token. ]*/
+                    /* Codes_SRS_UWS_CLIENT_01_088: [ The request MUST include a header field with the name |Sec-WebSocket-Key|. ]*/
+                    /* Codes_SRS_UWS_CLIENT_01_094: [ The request MUST include a header field with the name |Sec-WebSocket-Version|. ]*/
+                    /* Codes_SRS_UWS_CLIENT_01_095: [ The value of this header field MUST be 13. ]*/
+                    /* Codes_SRS_UWS_CLIENT_01_096: [ The request MAY include a header field with the name |Sec-WebSocket-Protocol|. ]*/
+                    /* Codes_SRS_UWS_CLIENT_01_100: [ The request MAY include a header field with the name |Sec-WebSocket-Extensions|. ]*/
+                    /* Codes_SRS_UWS_CLIENT_01_101: [ The request MAY include any other header fields, for example, cookies [RFC6265] and/or authentication-related header fields such as the |Authorization| header field [RFC2616], which are processed according to documents that define them. ] */
+                    const char upgrade_request_format[] = "GET %s HTTP/1.1\r\n"
+                        "Host: %s:%d\r\n"
+                        "Upgrade: websocket\r\n"
+                        "Connection: Upgrade\r\n"
+                        "Sec-WebSocket-Key: %s\r\n"
+                        "Sec-WebSocket-Protocol: %s\r\n"
+                        "Sec-WebSocket-Version: 13\r\n"
+                        "%s"
+                        "\r\n";
+
+                    const char* base64_nonce_chars = STRING_c_str(base64_nonce);
+
+                    upgrade_request_length = (int)(strlen(upgrade_request_format) + strlen(uws_client->resource_name)+strlen(uws_client->hostname) + strlen(base64_nonce_chars) + strlen(uws_client->protocols[0].protocol) + strlen(request_headers) + 5);
+                    if (upgrade_request_length < 0)
+                    {
+                        /* Codes_SRS_UWS_CLIENT_01_408: [ If constructing of the WebSocket upgrade request fails, uws shall report that the open failed by calling the on_ws_open_complete callback passed to uws_client_open_async with WS_OPEN_ERROR_CONSTRUCTING_UPGRADE_REQUEST. ]*/
+                        LogError("Cannot construct the WebSocket upgrade request");
+                        indicate_ws_open_complete_error_and_close(uws_client, WS_OPEN_ERROR_CONSTRUCTING_UPGRADE_REQUEST);
+                    }
+                    else
+                    {
+                        upgrade_request = (char*)malloc(upgrade_request_length + 1);
+                        if (upgrade_request == NULL)
+                        {
+                            /* Codes_SRS_UWS_CLIENT_01_406: [ If not enough memory can be allocated to construct the WebSocket upgrade request, uws shall report that the open failed by calling the on_ws_open_complete callback passed to uws_client_open_async with WS_OPEN_ERROR_NOT_ENOUGH_MEMORY. ]*/
+                            LogError("Cannot allocate memory for the WebSocket upgrade request");
+                            indicate_ws_open_complete_error_and_close(uws_client, WS_OPEN_ERROR_NOT_ENOUGH_MEMORY);
+                        }
+                        else
+                        {
+
+                            upgrade_request_length = sprintf(upgrade_request, upgrade_request_format,
+                                uws_client->resource_name,
+                                uws_client->hostname,
+                                uws_client->port,
+                                base64_nonce_chars,
+                                uws_client->protocols[0].protocol,
+                                request_headers);
+
+                            /* No need to have any send complete here, as we are monitoring the received bytes */
+                            /* Codes_SRS_UWS_CLIENT_01_372: [ Once prepared the WebSocket upgrade request shall be sent by calling xio_send. ]*/
+                            /* Codes_SRS_UWS_CLIENT_01_080: [ Once a connection to the server has been established (including a connection via a proxy or over a TLS-encrypted tunnel), the client MUST send an opening handshake to the server. ]*/
+                            if (xio_send(uws_client->underlying_io, upgrade_request, upgrade_request_length, unchecked_on_send_complete, NULL) != 0)
+                            {
+                                /* Codes_SRS_UWS_CLIENT_01_373: [ If xio_send fails then uws shall report that the open failed by calling the on_ws_open_complete callback passed to uws_client_open_async with WS_OPEN_ERROR_CANNOT_SEND_UPGRADE_REQUEST. ]*/
+                                LogError("Cannot send upgrade request");
+                                indicate_ws_open_complete_error_and_close(uws_client, WS_OPEN_ERROR_CANNOT_SEND_UPGRADE_REQUEST);
+                            }
+                            else
+                            {
+                                /* Codes_SRS_UWS_CLIENT_01_102: [ Once the client's opening handshake has been sent, the client MUST wait for a response from the server before sending any further data. ]*/
+                                uws_client->uws_state = UWS_STATE_WAITING_FOR_UPGRADE_RESPONSE;
+                            }
+
+                            free(upgrade_request);
+                        }
+                    }
+
+                    STRING_delete(base64_nonce);
+                    free(request_headers);
+                }
+
+                break;
+            }
+            }
+        }
+    }
+}
+
+static void consume_stream_buffer_bytes(UWS_CLIENT_INSTANCE* uws_client, size_t consumed_bytes)
+{
+    if (consumed_bytes < uws_client->stream_buffer_count)
+    {
+        (void)memmove(uws_client->stream_buffer, uws_client->stream_buffer + consumed_bytes, uws_client->stream_buffer_count - consumed_bytes);
+    }
+
+    uws_client->stream_buffer_count -= consumed_bytes;
+}
+
+static void on_underlying_io_close_complete(void* context)
+{
+    if (context == NULL)
+    {
+        /* Codes_SRS_UWS_CLIENT_01_477: [ When on_underlying_io_close_complete is called with a NULL context, it shall do nothing. ]*/
+        LogError("NULL context for on_underlying_io_close_complete");
+    }
+    else
+    {
+        UWS_CLIENT_HANDLE uws_client = (UWS_CLIENT_HANDLE)context;
+        if (uws_client->uws_state == UWS_STATE_CLOSING_UNDERLYING_IO)
+        {
+            /* Codes_SRS_UWS_CLIENT_01_475: [ When on_underlying_io_close_complete is called while closing the underlying IO a subsequent uws_client_open_async shall succeed. ]*/
+            indicate_ws_close_complete(uws_client);
+            uws_client->uws_state = UWS_STATE_CLOSED;
+        }
+    }
+}
+
+static void on_underlying_io_close_sent(void* context, IO_SEND_RESULT io_send_result)
+{
+    if (context == NULL)
+    {
+        /* Codes_SRS_UWS_CLIENT_01_489: [ When on_underlying_io_close_sent is called with NULL context, it shall do nothing. ] */
+        LogError("NULL context in ");
+    }
+    else
+    {
+        UWS_CLIENT_INSTANCE* uws_client = (UWS_CLIENT_HANDLE)context;
+
+        switch (io_send_result)
+        {
+        default:
+            LogError("Unknown enum value: %d", io_send_result);
+            break;
+
+        case IO_SEND_OK:
+        case IO_SEND_CANCELLED:
+            if (uws_client->uws_state == UWS_STATE_CLOSING_SENDING_CLOSE)
+            {
+                uws_client->uws_state = UWS_STATE_CLOSING_UNDERLYING_IO;
+
+                /* Codes_SRS_UWS_CLIENT_01_490: [ When on_underlying_io_close_sent is called while the uws client is CLOSING, on_underlying_io_close_sent shall close the underlying IO by calling xio_close. ]*/
+                if (xio_close(uws_client->underlying_io, on_underlying_io_close_complete, uws_client) != 0)
+                {
+                    /* Codes_SRS_UWS_CLIENT_01_496: [ If the close was initiated by the peer no on_ws_close_complete shall be called. ]*/
+                    indicate_ws_close_complete(uws_client);
+                }
+            }
+
+        case IO_SEND_ERROR:
+            break;
+        }
+    }
+}
+
+/*the following function does the same as sscanf(pos2, "%d", &sec)*/
+/*this function only exists because some of platforms do not have sscanf. */
+static int ParseStringToDecimal(const char *src, int* dst)
+{
+    int result;
+    char* next;
+
+    (*dst) = (int)strtol(src, &next, 0);
+    if ((src == next) || ((((*dst) == INT_MAX) || ((*dst) == INT_MIN)) && (errno != 0)))
+    {
+        result = MU_FAILURE;
+    }
+    else
+    {
+        result = 0;
+    }
+
+    return result;
+}
+
+/*the following function does the same as sscanf(buf, "HTTP/%*d.%*d %d %*[^\r\n]", &ret) */
+/*this function only exists because some of platforms do not have sscanf. This is not a full implementation; it only works with well-defined HTTP response. */
+static int ParseHttpResponse(const char* src, int* dst)
+{
+    int result;
+    static const char HTTPPrefix[] = "HTTP/";
+    bool fail;
+    const char* runPrefix;
+
+    if ((src == NULL) || (dst == NULL))
+    {
+        result = MU_FAILURE;
+    }
+    else
+    {
+        fail = false;
+        runPrefix = HTTPPrefix;
+
+        while ((*runPrefix) != '\0')
+        {
+            if ((*runPrefix) != (*src))
+            {
+                fail = true;
+                break;
+            }
+            src++;
+            runPrefix++;
+        }
+
+        if (!fail)
+        {
+            while ((*src) != '.')
+            {
+                if ((*src) == '\0')
+                {
+                    fail = true;
+                    break;
+                }
+                src++;
+            }
+        }
+
+        if (!fail)
+        {
+            while ((*src) != ' ')
+            {
+                if ((*src) == '\0')
+                {
+                    fail = true;
+                    break;
+                }
+                src++;
+            }
+        }
+
+        if (fail)
+        {
+            result = MU_FAILURE;
+        }
+        else
+        {
+            if (ParseStringToDecimal(src, dst) != 0)
+            {
+                result = MU_FAILURE;
+            }
+            else
+            {
+                result = 0;
+            }
+        }
+    }
+
+    return result;
+}
+
+static int process_frame_fragment(UWS_CLIENT_INSTANCE *uws_client, size_t length, size_t needed_bytes)
+{
+    int result;
+    unsigned char *new_fragment_bytes = (unsigned char *)realloc(uws_client->fragment_buffer, uws_client->fragment_buffer_count + length);
+    if (new_fragment_bytes == NULL)
+    {
+        /* Codes_SRS_UWS_CLIENT_01_379: [ If allocating memory for accumulating the bytes fails, uws shall report that the open failed by calling the on_ws_open_complete callback passed to uws_client_open_async with WS_OPEN_ERROR_NOT_ENOUGH_MEMORY. ]*/
+        LogError("Cannot allocate memory for received data");
+        indicate_ws_error(uws_client, WS_ERROR_NOT_ENOUGH_MEMORY);
+        result = MU_FAILURE;
+    }
+    else
+    {
+        uws_client->fragment_buffer = new_fragment_bytes;
+        (void)memcpy(uws_client->fragment_buffer + uws_client->fragment_buffer_count, uws_client->stream_buffer + needed_bytes - length, length);
+        uws_client->fragment_buffer_count += length;
+        result = 0;
+    }
+
+    return result;
+}
+
+static void on_underlying_io_bytes_received(void* context, const unsigned char* buffer, size_t size)
+{
+    /* Codes_SRS_UWS_CLIENT_01_415: [ If called with a NULL context argument, on_underlying_io_bytes_received shall do nothing. ]*/
+    if (context != NULL)
+    {
+        UWS_CLIENT_HANDLE uws_client = (UWS_CLIENT_HANDLE)context;
+
+        if ((buffer == NULL) ||
+            (size == 0))
+        {
+            /* Codes_SRS_UWS_CLIENT_01_416: [ If called with NULL buffer or zero size and the state of the iws is OPENING, uws shall report that the open failed by calling the on_ws_open_complete callback passed to uws_client_open_async with WS_OPEN_ERROR_INVALID_BYTES_RECEIVED_ARGUMENTS. ]*/
+            indicate_ws_open_complete_error_and_close(uws_client, WS_OPEN_ERROR_INVALID_BYTES_RECEIVED_ARGUMENTS);
+        }
+        else
+        {
+            unsigned char decode_stream = 1;
+
+            switch (uws_client->uws_state)
+            {
+            default:
+            case UWS_STATE_CLOSED:
+                decode_stream = 0;
+                break;
+
+            case UWS_STATE_OPENING_UNDERLYING_IO:
+                /* Codes_SRS_UWS_CLIENT_01_417: [ When on_underlying_io_bytes_received is called while OPENING but before the on_underlying_io_open_complete has been called, uws shall report that the open failed by calling the on_ws_open_complete callback passed to uws_client_open_async with WS_OPEN_ERROR_BYTES_RECEIVED_BEFORE_UNDERLYING_OPEN. ]*/
+                indicate_ws_open_complete_error_and_close(uws_client, WS_OPEN_ERROR_BYTES_RECEIVED_BEFORE_UNDERLYING_OPEN);
+                decode_stream = 0;
+                break;
+
+            case UWS_STATE_WAITING_FOR_UPGRADE_RESPONSE:
+            {
+                /* Codes_SRS_UWS_CLIENT_01_378: [ When on_underlying_io_bytes_received is called while the uws is OPENING, the received bytes shall be accumulated in order to attempt parsing the WebSocket Upgrade response. ]*/
+                unsigned char* new_received_bytes = (unsigned char*)realloc(uws_client->stream_buffer, uws_client->stream_buffer_count + size + 1);
+                if (new_received_bytes == NULL)
+                {
+                    /* Codes_SRS_UWS_CLIENT_01_379: [ If allocating memory for accumulating the bytes fails, uws shall report that the open failed by calling the on_ws_open_complete callback passed to uws_client_open_async with WS_OPEN_ERROR_NOT_ENOUGH_MEMORY. ]*/
+                    indicate_ws_open_complete_error_and_close(uws_client, WS_OPEN_ERROR_NOT_ENOUGH_MEMORY);
+                    decode_stream = 0;
+                }
+                else
+                {
+                    uws_client->stream_buffer = new_received_bytes;
+                    (void)memcpy(uws_client->stream_buffer + uws_client->stream_buffer_count, buffer, size);
+                    uws_client->stream_buffer_count += size;
+
+                    decode_stream = 1;
+                }
+
+                break;
+            }
+
+            case UWS_STATE_OPEN:
+            case UWS_STATE_CLOSING_WAITING_FOR_CLOSE:
+            {
+                /* Codes_SRS_UWS_CLIENT_01_385: [ If the state of the uws instance is OPEN, the received bytes shall be used for decoding WebSocket frames. ]*/
+                unsigned char* new_received_bytes = (unsigned char*)realloc(uws_client->stream_buffer, uws_client->stream_buffer_count + size + 1);
+                if (new_received_bytes == NULL)
+                {
+                    /* Codes_SRS_UWS_CLIENT_01_418: [ If allocating memory for the bytes accumulated for decoding WebSocket frames fails, an error shall be indicated by calling the on_ws_error callback with WS_ERROR_NOT_ENOUGH_MEMORY. ]*/
+                    LogError("Cannot allocate memory for received data");
+                    indicate_ws_error(uws_client, WS_ERROR_NOT_ENOUGH_MEMORY);
+
+                    decode_stream = 0;
+                }
+                else
+                {
+                    uws_client->stream_buffer = new_received_bytes;
+                    (void)memcpy(uws_client->stream_buffer + uws_client->stream_buffer_count, buffer, size);
+                    uws_client->stream_buffer_count += size;
+
+                    decode_stream = 1;
+                }
+
+                break;
+            }
+            }
+
+            while (decode_stream)
+            {
+                decode_stream = 0;
+
+                switch (uws_client->uws_state)
+                {
+                default:
+                case UWS_STATE_CLOSED:
+                    break;
+
+                case UWS_STATE_OPENING_UNDERLYING_IO:
+                    /* Codes_SRS_UWS_CLIENT_01_417: [ When on_underlying_io_bytes_received is called while OPENING but before the on_underlying_io_open_complete has been called, uws shall report that the open failed by calling the on_ws_open_complete callback passed to uws_client_open_async with WS_OPEN_ERROR_BYTES_RECEIVED_BEFORE_UNDERLYING_OPEN. ]*/
+                    indicate_ws_open_complete_error_and_close(uws_client, WS_OPEN_ERROR_BYTES_RECEIVED_BEFORE_UNDERLYING_OPEN);
+                    break;
+
+                case UWS_STATE_WAITING_FOR_UPGRADE_RESPONSE:
+                {
+                    const char* request_end_ptr;
+
+                    /* Make sure it is zero terminated */
+                    uws_client->stream_buffer[uws_client->stream_buffer_count] = '\0';
+
+                    /* Codes_SRS_UWS_CLIENT_01_380: [ If an WebSocket Upgrade request can be parsed from the accumulated bytes, the status shall be read from the WebSocket upgrade response. ]*/
+                    /* Codes_SRS_UWS_CLIENT_01_381: [ If the status is 101, uws shall be considered OPEN and this shall be indicated by calling the on_ws_open_complete callback passed to uws_client_open_async with IO_OPEN_OK. ]*/
+                    if ((uws_client->stream_buffer_count >= 4) &&
+                        ((request_end_ptr = strstr((const char*)uws_client->stream_buffer, "\r\n\r\n")) != NULL))
+                    {
+                        int status_code;
+
+                        /* This part should really be done with the HTTPAPI, but that has to be done as a separate step
+                        as the HTTPAPI has to expose somehow the underlying IO and currently this would be a too big of a change. */
+
+                        /* Codes_SRS_UWS_CLIENT_01_382: [ If a negative status is decoded from the WebSocket upgrade request, an error shall be indicated by calling the on_ws_open_complete callback passed to uws_client_open_async with WS_OPEN_ERROR_BAD_RESPONSE_STATUS. ]*/
+                        /* Codes_SRS_UWS_CLIENT_01_478: [ A Status-Line with a 101 response code as per RFC 2616 [RFC2616]. ]*/
+                        if (ParseHttpResponse((const char*)uws_client->stream_buffer, &status_code) != 0)
+                        {
+                            /* Codes_SRS_UWS_CLIENT_01_383: [ If the WebSocket upgrade request cannot be decoded an error shall be indicated by calling the on_ws_open_complete callback passed to uws_client_open_async with WS_OPEN_ERROR_BAD_UPGRADE_RESPONSE. ]*/
+                            LogError("Cannot decode HTTP response");
+                            indicate_ws_open_complete_error_and_close(uws_client, WS_OPEN_ERROR_BAD_UPGRADE_RESPONSE);
+                        }
+                        else if (status_code != 101)
+                        {
+                            /* Codes_SRS_UWS_CLIENT_01_382: [ If a negative status is decoded from the WebSocket upgrade request, an error shall be indicated by calling the on_ws_open_complete callback passed to uws_client_open_async with WS_OPEN_ERROR_BAD_RESPONSE_STATUS. ]*/
+                            LogError("Bad status (%d) received in WebSocket Upgrade response", status_code);
+                            indicate_ws_open_complete_error_and_close(uws_client, WS_OPEN_ERROR_BAD_RESPONSE_STATUS);
+                        }
+                        else
+                        {
+                            /* Codes_SRS_UWS_CLIENT_01_384: [ Any extra bytes that are left unconsumed after decoding a succesfull WebSocket upgrade response shall be used for decoding WebSocket frames ]*/
+                            consume_stream_buffer_bytes(uws_client, request_end_ptr - (char*)uws_client->stream_buffer + 4);
+
+                            /* Codes_SRS_UWS_CLIENT_01_381: [ If the status is 101, uws shall be considered OPEN and this shall be indicated by calling the on_ws_open_complete callback passed to uws_client_open_async with IO_OPEN_OK. ]*/
+                            uws_client->uws_state = UWS_STATE_OPEN;
+
+                            /* Codes_SRS_UWS_CLIENT_01_065: [ When the client is to _Establish a WebSocket Connection_ given a set of (/host/, /port/, /resource name/, and /secure/ flag), along with a list of /protocols/ and /extensions/ to be used, and an /origin/ in the case of web browsers, it MUST open a connection, send an opening handshake, and read the server's handshake in response. ]*/
+                            /* Codes_SRS_UWS_CLIENT_01_115: [ If the server's response is validated as provided for above, it is said that _The WebSocket Connection is Established_ and that the WebSocket Connection is in the OPEN state. ]*/
+                            uws_client->on_ws_open_complete(uws_client->on_ws_open_complete_context, WS_OPEN_OK);
+
+                            decode_stream = 1;
+                        }
+                    }
+
+                    break;
+                }
+
+                case UWS_STATE_OPEN:
+                case UWS_STATE_CLOSING_WAITING_FOR_CLOSE:
+                {
+                    size_t needed_bytes = 2;
+                    size_t length;
+
+                    /* Codes_SRS_UWS_CLIENT_01_277: [ To receive WebSocket data, an endpoint listens on the underlying network connection. ]*/
+                    /* Codes_SRS_UWS_CLIENT_01_278: [ Incoming data MUST be parsed as WebSocket frames as defined in Section 5.2. ]*/
+                    if (uws_client->stream_buffer_count >= needed_bytes)
+                    {
+                        unsigned char has_error = 0;
+
+                        /* Codes_SRS_UWS_CLIENT_01_160: [ Defines whether the "Payload data" is masked. ]*/
+                        if ((uws_client->stream_buffer[1] & 0x80) != 0)
+                        {
+                            /* Codes_SRS_UWS_CLIENT_01_144: [ A client MUST close a connection if it detects a masked frame. ]*/
+                            /* Codes_SRS_UWS_CLIENT_01_145: [ In this case, it MAY use the status code 1002 (protocol error) as defined in Section 7.4.1. (These rules might be relaxed in a future specification.) ]*/
+                            LogError("Masked frame detected by WebSocket client");
+                            indicate_ws_error_and_close(uws_client, WS_ERROR_BAD_FRAME_RECEIVED, 1002);
+                        }
+
+                        /* Codes_SRS_UWS_CLIENT_01_163: [ The length of the "Payload data", in bytes: ]*/
+                        /* Codes_SRS_UWS_CLIENT_01_164: [ if 0-125, that is the payload length. ]*/
+                        length = uws_client->stream_buffer[1];
+
+                        if (length == 126)
+                        {
+                            /* Codes_SRS_UWS_CLIENT_01_165: [ If 126, the following 2 bytes interpreted as a 16-bit unsigned integer are the payload length. ]*/
+                            needed_bytes += 2;
+                            if (uws_client->stream_buffer_count >= needed_bytes)
+                            {
+                                /* Codes_SRS_UWS_CLIENT_01_167: [ Multibyte length quantities are expressed in network byte order. ]*/
+                                length = ((size_t)(uws_client->stream_buffer[2]) << 8) + (size_t)uws_client->stream_buffer[3];
+
+                                if (length < 126)
+                                {
+                                    /* Codes_SRS_UWS_CLIENT_01_168: [ Note that in all cases, the minimal number of bytes MUST be used to encode the length, for example, the length of a 124-byte-long string can't be encoded as the sequence 126, 0, 124. ]*/
+                                    LogError("Bad frame: received a %u length on the 16 bit length", (unsigned int)length);
+
+                                    /* Codes_SRS_UWS_CLIENT_01_419: [ If there is an error decoding the WebSocket frame, an error shall be indicated by calling the on_ws_error callback with WS_ERROR_BAD_FRAME_RECEIVED. ]*/
+                                    indicate_ws_error(uws_client, WS_ERROR_BAD_FRAME_RECEIVED);
+                                    has_error = 1;
+                                }
+                                else
+                                {
+                                    needed_bytes += (size_t)length;
+                                }
+                            }
+                        }
+                        else if (length == 127)
+                        {
+                            /* Codes_SRS_UWS_CLIENT_01_166: [ If 127, the following 8 bytes interpreted as a 64-bit unsigned integer (the most significant bit MUST be 0) are the payload length. ]*/
+                            needed_bytes += 8;
+                            if (uws_client->stream_buffer_count >= needed_bytes)
+                            {
+                                if ((uws_client->stream_buffer[2] & 0x80) != 0)
+                                {
+                                    LogError("Bad frame: received a 64 bit length frame with the highest bit set");
+
+                                    /* Codes_SRS_UWS_CLIENT_01_419: [ If there is an error decoding the WebSocket frame, an error shall be indicated by calling the on_ws_error callback with WS_ERROR_BAD_FRAME_RECEIVED. ]*/
+                                    indicate_ws_error(uws_client, WS_ERROR_BAD_FRAME_RECEIVED);
+                                    has_error = 1;
+                                }
+                                else
+                                {
+                                    /* Codes_SRS_UWS_CLIENT_01_167: [ Multibyte length quantities are expressed in network byte order. ]*/
+                                    length = (size_t)(((uint64_t)(uws_client->stream_buffer[2]) << 56) +
+                                        (((uint64_t)uws_client->stream_buffer[3]) << 48) +
+                                        (((uint64_t)uws_client->stream_buffer[4]) << 40) +
+                                        (((uint64_t)uws_client->stream_buffer[5]) << 32) +
+                                        (((uint64_t)uws_client->stream_buffer[6]) << 24) +
+                                        (((uint64_t)uws_client->stream_buffer[7]) << 16) +
+                                        (((uint64_t)uws_client->stream_buffer[8]) << 8) +
+                                        (uint64_t)(uws_client->stream_buffer[9]));
+
+                                    if (length < 65536)
+                                    {
+                                        /* Codes_SRS_UWS_CLIENT_01_168: [ Note that in all cases, the minimal number of bytes MUST be used to encode the length, for example, the length of a 124-byte-long string can't be encoded as the sequence 126, 0, 124. ]*/
+                                        LogError("Bad frame: received a %u length on the 64 bit length", (unsigned int)length);
+
+                                        /* Codes_SRS_UWS_CLIENT_01_419: [ If there is an error decoding the WebSocket frame, an error shall be indicated by calling the on_ws_error callback with WS_ERROR_BAD_FRAME_RECEIVED. ]*/
+                                        indicate_ws_error(uws_client, WS_ERROR_BAD_FRAME_RECEIVED);
+                                        has_error = 1;
+                                    }
+                                    else
+                                    {
+                                        needed_bytes += length;
+                                    }
+                                }
+                            }
+                        }
+                        else
+                        {
+                            needed_bytes += length;
+                        }
+
+                        if ((has_error == 0) &&
+                            (uws_client->stream_buffer_count >= needed_bytes))
+                        {
+                            unsigned char opcode = uws_client->stream_buffer[0] & 0xF;
+
+                            /* Codes_SRS_UWS_CLIENT_01_147: [ Indicates that this is the final fragment in a message. ]*/
+                            bool is_final = (uws_client->stream_buffer[0] & 0x80) != 0;
+
+                            switch (opcode)
+                            {
+                            default:
+                                break;
+                                /* Codes_SRS_UWS_CLIENT_01_152: [* *  %x0 denotes a continuation frame *]*/
+                            case (unsigned char)WS_CONTINUATION_FRAME:
+                            {
+                                /* Codes_SRS_UWS_CLIENT_01_213: [ A fragmented message consists of a single frame with the FIN bit clear and an opcode other than 0, followed by zero or more frames with the FIN bit clear and the opcode set to 0, and terminated by a single frame with the FIN bit set and an opcode of 0. ]*/
+                                /* Codes_SRS_UWS_CLIENT_01_216: [ Message fragments MUST be delivered to the recipient in the order sent by the sender. ]*/
+                                /* Codes_SRS_UWS_CLIENT_01_219: [ A sender MAY create fragments of any size for non-control messages. ]*/
+                                if (process_frame_fragment(uws_client, length, needed_bytes) != 0)
+                                {
+                                    break;
+                                }
+
+                                if (is_final)
+                                {
+                                    /* Codes_SRS_UWS_CLIENT_01_225: [ As a consequence of these rules, all fragments of a message are of the same type, as set by the first fragment's opcode. ]*/
+                                    if (uws_client->fragmented_frame_type == WS_FRAME_TYPE_UNKNOWN)
+                                    {
+                                        LogError("Continuation fragment received without initial fragment specifying frame data type");
+                                        indicate_ws_error(uws_client, WS_ERROR_BAD_FRAME_RECEIVED);
+                                        decode_stream = 1;
+                                        break;
+                                    }
+                                    uws_client->on_ws_frame_received(uws_client->on_ws_frame_received_context, uws_client->fragmented_frame_type, uws_client->fragment_buffer, uws_client->fragment_buffer_count);
+                                    uws_client->fragment_buffer_count = 0;
+                                    uws_client->fragmented_frame_type = WS_FRAME_TYPE_UNKNOWN;
+                                }
+                                decode_stream = 1;
+                                break;
+                            }
+                                /* Codes_SRS_UWS_CLIENT_01_153: [ *  %x1 denotes a text frame ]*/
+                                /* Codes_SRS_UWS_CLIENT_01_258: [** Currently defined opcodes for data frames include 0x1 (Text), 0x2 (Binary). ]*/
+                            case (unsigned char)WS_TEXT_FRAME:
+                            {
+                                /* Codes_SRS_UWS_CLIENT_01_386: [ When a WebSocket data frame is decoded succesfully it shall be indicated via the callback on_ws_frame_received. ]*/
+                                /* Codes_SRS_UWS_CLIENT_01_169: [ The payload length is the length of the "Extension data" + the length of the "Application data". ]*/
+                                /* Codes_SRS_UWS_CLIENT_01_173: [ The "Payload data" is defined as "Extension data" concatenated with "Application data". ]*/
+                                /* Codes_SRS_UWS_CLIENT_01_280: [ Upon receiving a data frame (Section 5.6), the endpoint MUST note the /type/ of the data as defined by the opcode (frame-opcode) from Section 5.2. ]*/
+                                /* Codes_SRS_UWS_CLIENT_01_281: [ The "Application data" from this frame is defined as the /data/ of the message. ]*/
+                                /* Codes_SRS_UWS_CLIENT_01_282: [ If the frame comprises an unfragmented message (Section 5.4), it is said that _A WebSocket Message Has Been Received_ with type /type/ and data /data/. ]*/
+                                if (is_final)
+                                {
+                                    uws_client->on_ws_frame_received(uws_client->on_ws_frame_received_context, WS_FRAME_TYPE_TEXT, uws_client->stream_buffer + needed_bytes - length, length);
+                                }
+                                else
+                                {
+                                    /* Codes_SRS_UWS_CLIENT_01_217: [ The fragments of one message MUST NOT be interleaved between the fragments of another message unless an extension has been negotiated that can interpret the interleaving. ]*/
+                                    if (uws_client->fragmented_frame_type != WS_FRAME_TYPE_UNKNOWN)
+                                    {
+                                        LogError("Fragmented frame received interleaved between the fragments of another message");
+                                        indicate_ws_error(uws_client, WS_ERROR_BAD_FRAME_RECEIVED);
+                                        decode_stream = 1;
+                                        break;
+                                    }
+                                    /* Codes_SRS_UWS_CLIENT_01_213: [ A fragmented message consists of a single frame with the FIN bit clear and an opcode other than 0, followed by zero or more frames with the FIN bit clear and the opcode set to 0, and terminated by a single frame with the FIN bit set and an opcode of 0. ]*/
+                                    /* Codes_SRS_UWS_CLIENT_01_216: [ Message fragments MUST be delivered to the recipient in the order sent by the sender. ]*/
+                                    /* Codes_SRS_UWS_CLIENT_01_219: [ A sender MAY create fragments of any size for non-control messages. ]*/
+                                    if (process_frame_fragment(uws_client, length, needed_bytes) != 0)
+                                    {
+                                        break;
+                                    }
+
+                                    /* Codes_SRS_UWS_CLIENT_01_225: [ As a consequence of these rules, all fragments of a message are of the same type, as set by the first fragment's opcode. ]*/
+                                    /* Codes_SRS_UWS_CLIENT_01_226: [ Since control frames cannot be fragmented, the type for all fragments in a message MUST be either text, binary, or one of the reserved opcodes. ]*/
+                                    uws_client->fragmented_frame_type = WS_FRAME_TYPE_TEXT;
+                                }
+                                decode_stream = 1;
+                                break;
+                            }
+
+                                /* Codes_SRS_UWS_CLIENT_01_154: [ *  %x2 denotes a binary frame ]*/
+                            case (unsigned char)WS_BINARY_FRAME:
+                            {
+                                /* Codes_SRS_UWS_CLIENT_01_386: [ When a WebSocket data frame is decoded succesfully it shall be indicated via the callback on_ws_frame_received. ]*/
+                                /* Codes_SRS_UWS_CLIENT_01_169: [ The payload length is the length of the "Extension data" + the length of the "Application data". ]*/
+                                /* Codes_SRS_UWS_CLIENT_01_173: [ The "Payload data" is defined as "Extension data" concatenated with "Application data". ]*/
+                                /* Codes_SRS_UWS_CLIENT_01_264: [ The "Payload data" is arbitrary binary data whose interpretation is solely up to the application layer. ]*/
+                                /* Codes_SRS_UWS_CLIENT_01_280: [ Upon receiving a data frame (Section 5.6), the endpoint MUST note the /type/ of the data as defined by the opcode (frame-opcode) from Section 5.2. ]*/
+                                /* Codes_SRS_UWS_CLIENT_01_281: [ The "Application data" from this frame is defined as the /data/ of the message. ]*/
+                                /* Codes_SRS_UWS_CLIENT_01_282: [ If the frame comprises an unfragmented message (Section 5.4), it is said that _A WebSocket Message Has Been Received_ with type /type/ and data /data/. ]*/
+                                if (is_final)
+                                {
+                                    uws_client->on_ws_frame_received(uws_client->on_ws_frame_received_context, WS_FRAME_TYPE_BINARY, uws_client->stream_buffer + needed_bytes - length, length);
+                                }
+                                else
+                                {
+                                    /* Codes_SRS_UWS_CLIENT_01_217: [ The fragments of one message MUST NOT be interleaved between the fragments of another message unless an extension has been negotiated that can interpret the interleaving. ]*/
+                                    if (uws_client->fragmented_frame_type != WS_FRAME_TYPE_UNKNOWN)
+                                    {
+                                        LogError("Fragmented frame received interleaved between the fragments of another message");
+                                        indicate_ws_error(uws_client, WS_ERROR_BAD_FRAME_RECEIVED);
+                                        decode_stream = 1;
+                                        break;
+                                    }
+                                    /* Codes_SRS_UWS_CLIENT_01_213: [ A fragmented message consists of a single frame with the FIN bit clear and an opcode other than 0, followed by zero or more frames with the FIN bit clear and the opcode set to 0, and terminated by a single frame with the FIN bit set and an opcode of 0. ]*/
+                                    /* Codes_SRS_UWS_CLIENT_01_216: [ Message fragments MUST be delivered to the recipient in the order sent by the sender. ]*/
+                                    /* Codes_SRS_UWS_CLIENT_01_219: [ A sender MAY create fragments of any size for non-control messages. ]*/
+                                    if (process_frame_fragment(uws_client, length, needed_bytes) != 0)
+                                    {
+                                        break;
+                                    }
+
+                                    /* Codes_SRS_UWS_CLIENT_01_225: [ As a consequence of these rules, all fragments of a message are of the same type, as set by the first fragment's opcode. ]*/
+                                    /* Codes_SRS_UWS_CLIENT_01_226: [ Since control frames cannot be fragmented, the type for all fragments in a message MUST be either text, binary, or one of the reserved opcodes. ]*/
+                                    uws_client->fragmented_frame_type = WS_FRAME_TYPE_BINARY;
+                                }
+                                decode_stream = 1;
+                                break;
+                            }
+
+                                /* Codes_SRS_UWS_CLIENT_01_156: [ *  %x8 denotes a connection close ]*/
+                                /* Codes_SRS_UWS_CLIENT_01_234: [ The Close frame contains an opcode of 0x8. ]*/
+                                /* Codes_SRS_UWS_CLIENT_01_214: [ Control frames (see Section 5.5) MAY be injected in the middle of a fragmented message. ]*/
+                            case (unsigned char)WS_CLOSE_FRAME:
+                            {
+                                uint16_t close_code;
+                                uint16_t* close_code_ptr;
+                                const unsigned char* data_ptr = uws_client->stream_buffer + needed_bytes - length;
+                                const unsigned char* extra_data_ptr;
+                                size_t extra_data_length;
+                                unsigned char* close_frame_bytes;
+                                size_t close_frame_length;
+                                bool utf8_error = false;
+
+                                /* Codes_SRS_UWS_CLIENT_01_215: [ Control frames themselves MUST NOT be fragmented. ]*/
+                                if (!is_final)
+                                {
+                                    LogError("Fragmented control frame received.");
+                                    indicate_ws_error(uws_client, WS_ERROR_BAD_FRAME_RECEIVED);
+                                    break;
+                                }
+
+                                /* Codes_SRS_UWS_CLIENT_01_235: [ The Close frame MAY contain a body (the "Application data" portion of the frame) that indicates a reason for closing, such as an endpoint shutting down, an endpoint having received a frame too large, or an endpoint having received a frame that does not conform to the format expected by the endpoint. ]*/
+                                if (length >= 2)
+                                {
+                                    /* Codes_SRS_UWS_CLIENT_01_236: [ If there is a body, the first two bytes of the body MUST be a 2-byte unsigned integer (in network byte order) representing a status code with value /code/ defined in Section 7.4. ]*/
+                                    close_code = (data_ptr[0] << 8) + data_ptr[1];
+
+                                    /* Codes_SRS_UWS_CLIENT_01_461: [ The argument close_code shall be set to point to the code extracted from the CLOSE frame. ]*/
+                                    close_code_ptr = &close_code;
+                                }
+                                else
+                                {
+                                    /* Codes_SRS_UWS_CLIENT_01_462: [ If no code can be extracted then close_code shall be NULL. ]*/
+                                    close_code_ptr = NULL;
+                                }
+
+                                if (length > 2)
+                                {
+                                    /* Codes_SRS_UWS_CLIENT_01_463: [ The extra bytes (besides the close code) shall be passed to the on_ws_peer_closed callback by using extra_data and extra_data_length. ]*/
+                                    extra_data_ptr = data_ptr + 2;
+                                    extra_data_length = length - 2;
+
+                                    /* Codes_SRS_UWS_CLIENT_01_238: [ As the data is not guaranteed to be human readable, clients MUST NOT show it to end users. ]*/
+                                    /* Codes_SRS_UWS_CLIENT_01_237: [ Following the 2-byte integer, the body MAY contain UTF-8-encoded data with value /reason/, the interpretation of which is not defined by this specification. ]*/
+                                    if (utf8_checker_is_valid_utf8(extra_data_ptr, extra_data_length) != true)
+                                    {
+                                        LogError("Reason in CLOSE frame is not UTF-8.");
+                                        extra_data_ptr = NULL;
+                                        extra_data_length = 0;
+                                        utf8_error = true;
+                                    }
+                                }
+                                else
+                                {
+                                    extra_data_ptr = NULL;
+                                    extra_data_length = 0;
+                                }
+
+                                if (utf8_error)
+                                {
+                                    uws_client->uws_state = UWS_STATE_CLOSING_UNDERLYING_IO;
+                                    if (xio_close(uws_client->underlying_io, on_underlying_io_close_complete, uws_client) != 0)
+                                    {
+                                        LogError("Could not close underlying IO");
+                                        indicate_ws_error(uws_client, WS_ERROR_CANNOT_CLOSE_UNDERLYING_IO);
+                                        uws_client->uws_state = UWS_STATE_CLOSED;
+                                    }
+                                }
+                                else
+                                {
+                                    BUFFER_HANDLE close_frame_buffer;
+
+                                    if (uws_client->uws_state == UWS_STATE_CLOSING_WAITING_FOR_CLOSE)
+                                    {
+                                        uws_client->uws_state = UWS_STATE_CLOSING_UNDERLYING_IO;
+                                        if (xio_close(uws_client->underlying_io, on_underlying_io_close_complete, uws_client) != 0)
+                                        {
+                                            indicate_ws_close_complete(uws_client);
+                                            uws_client->uws_state = UWS_STATE_CLOSED;
+                                        }
+                                    }
+                                    else
+                                    {
+                                        /* Codes_SRS_UWS_CLIENT_01_296: [ Upon either sending or receiving a Close control frame, it is said that _The WebSocket Closing Handshake is Started_ and that the WebSocket connection is in the CLOSING state. ]*/
+                                        /* Codes_SRS_UWS_CLIENT_01_240: [ The application MUST NOT send any more data frames after sending a Close frame. ]*/
+                                        uws_client->uws_state = UWS_STATE_CLOSING_SENDING_CLOSE;
+                                    }
+
+                                    /* Codes_SRS_UWS_CLIENT_01_241: [ If an endpoint receives a Close frame and did not previously send a Close frame, the endpoint MUST send a Close frame in response. ]*/
+                                    /* Codes_SRS_UWS_CLIENT_01_242: [ It SHOULD do so as soon as practical. ]*/
+                                    /* Codes_SRS_UWS_CLIENT_01_239: [ Close frames sent from client to server must be masked as per Section 5.3. ]*/
+                                    /* Codes_SRS_UWS_CLIENT_01_140: [ To avoid confusing network intermediaries (such as intercepting proxies) and for security reasons that are further discussed in Section 10.3, a client MUST mask all frames that it sends to the server (see Section 5.3 for further details). ]*/
+                                    close_frame_buffer = uws_frame_encoder_encode(WS_CLOSE_FRAME, NULL, 0, true, true, 0);
+                                    if (close_frame_buffer == NULL)
+                                    {
+                                        LogError("Cannot encode the response CLOSE frame");
+
+                                        /* Codes_SRS_UWS_CLIENT_01_288: [ To _Close the WebSocket Connection_, an endpoint closes the underlying TCP connection. ]*/
+                                        /* Codes_SRS_UWS_CLIENT_01_290: [ An endpoint MAY close the connection via any means available when necessary, such as when under attack. ]*/
+                                        uws_client->uws_state = UWS_STATE_CLOSING_UNDERLYING_IO;
+                                        if (xio_close(uws_client->underlying_io, on_underlying_io_close_complete, uws_client) != 0)
+                                        {
+                                            indicate_ws_error(uws_client, WS_ERROR_CANNOT_CLOSE_UNDERLYING_IO);
+                                            uws_client->uws_state = UWS_STATE_CLOSED;
+                                        }
+                                    }
+                                    else
+                                    {
+                                        close_frame_bytes = BUFFER_u_char(close_frame_buffer);
+                                        close_frame_length = BUFFER_length(close_frame_buffer);
+                                        if (xio_send(uws_client->underlying_io, close_frame_bytes, close_frame_length, on_underlying_io_close_sent, uws_client) != 0)
+                                        {
+                                            LogError("Cannot send the response CLOSE frame");
+
+                                            /* Codes_SRS_UWS_CLIENT_01_288: [ To _Close the WebSocket Connection_, an endpoint closes the underlying TCP connection. ]*/
+                                            /* Codes_SRS_UWS_CLIENT_01_290: [ An endpoint MAY close the connection via any means available when necessary, such as when under attack. ]*/
+                                            uws_client->uws_state = UWS_STATE_CLOSING_UNDERLYING_IO;
+                                            if (xio_close(uws_client->underlying_io, on_underlying_io_close_complete, uws_client) != 0)
+                                            {
+                                                indicate_ws_error(uws_client, WS_ERROR_CANNOT_CLOSE_UNDERLYING_IO);
+                                                uws_client->uws_state = UWS_STATE_CLOSED;
+                                            }
+                                        }
+
+                                        BUFFER_delete(close_frame_buffer);
+                                    }
+                                }
+
+                                /* Codes_SRS_UWS_CLIENT_01_460: [ When a CLOSE frame is received the callback on_ws_peer_closed passed to uws_client_open_async shall be called, while passing to it the argument on_ws_peer_closed_context. ]*/
+                                uws_client->on_ws_peer_closed(uws_client->on_ws_peer_closed_context, close_code_ptr, extra_data_ptr, extra_data_length);
+
+                                break;
+                            }
+
+                                /* Codes_SRS_UWS_CLIENT_01_157: [ *  %x9 denotes a ping ]*/
+                                /* Codes_SRS_UWS_CLIENT_01_247: [ The Ping frame contains an opcode of 0x9. ]*/
+                                /* Codes_SRS_UWS_CLIENT_01_251: [ An endpoint MAY send a Ping frame any time after the connection is established and before the connection is closed. ]*/
+                                /* Codes_SRS_UWS_CLIENT_01_214: [ Control frames (see Section 5.5) MAY be injected in the middle of a fragmented message. ]*/
+                            case (unsigned char)WS_PING_FRAME:
+                            {
+                                /* Codes_SRS_UWS_CLIENT_01_249: [ Upon receipt of a Ping frame, an endpoint MUST send a Pong frame in response ]*/
+                                /* Codes_SRS_UWS_CLIENT_01_250: [ It SHOULD respond with Pong frame as soon as is practical. ]*/
+                                unsigned char* pong_frame;
+                                size_t pong_frame_length;
+                                BUFFER_HANDLE pong_frame_buffer;
+
+                                /* Codes_SRS_UWS_CLIENT_01_215: [ Control frames themselves MUST NOT be fragmented. ]*/
+                                if (!is_final)
+                                {
+                                    LogError("Fragmented control frame received.");
+                                    indicate_ws_error(uws_client, WS_ERROR_BAD_FRAME_RECEIVED);
+                                    break;
+                                }
+
+                                /* Codes_SRS_UWS_CLIENT_01_140: [ To avoid confusing network intermediaries (such as intercepting proxies) and for security reasons that are further discussed in Section 10.3, a client MUST mask all frames that it sends to the server (see Section 5.3 for further details). ]*/
+                                pong_frame_buffer = uws_frame_encoder_encode(WS_PONG_FRAME, uws_client->stream_buffer + needed_bytes - length, length, true, true, 0);
+                                if (pong_frame_buffer == NULL)
+                                {
+                                    LogError("Encoding of PONG failed.");
+                                }
+                                else
+                                {
+                                    /* Codes_SRS_UWS_CLIENT_01_248: [ A Ping frame MAY include "Application data". ]*/
+                                    pong_frame = BUFFER_u_char(pong_frame_buffer);
+                                    pong_frame_length = BUFFER_length(pong_frame_buffer);
+                                    if (xio_send(uws_client->underlying_io, pong_frame, pong_frame_length, unchecked_on_send_complete, NULL) != 0)
+                                    {
+                                        LogError("Sending PONG frame failed.");
+                                    }
+
+                                    BUFFER_delete(pong_frame_buffer);
+                                }
+
+                                break;
+                            }
+                            /* Codes_SRS_UWS_CLIENT_01_252: [ The Pong frame contains an opcode of 0xA. ]*/
+                            case (unsigned char)WS_PONG_FRAME:
+                                break;
+                            }
+
+                            consume_stream_buffer_bytes(uws_client, needed_bytes);
+                        }
+                    }
+
+                    break;
+                }
+                }
+            }
+        }
+    }
+}
+
+static void on_underlying_io_error(void* context)
+{
+    UWS_CLIENT_HANDLE uws_client = (UWS_CLIENT_HANDLE)context;
+
+    switch (uws_client->uws_state)
+    {
+    default:
+        break;
+
+    case UWS_STATE_CLOSING_WAITING_FOR_CLOSE:
+    case UWS_STATE_CLOSING_SENDING_CLOSE:
+    case UWS_STATE_CLOSING_UNDERLYING_IO:
+        /* Codes_SRS_UWS_CLIENT_01_500: [ The callback on_ws_close_complete shall be called, while passing the on_ws_close_complete_context argument to it. ]*/
+        /* Codes_SRS_UWS_CLIENT_01_377: [ When on_underlying_io_error is called while the uws instance is CLOSING the underlying IO shall be closed by calling xio_close. ]*/
+        (void)xio_close(uws_client->underlying_io, NULL, NULL);
+
+        /* Codes_SRS_UWS_CLIENT_01_499: [ If the CLOSE was due to the peer closing, the callback on_ws_close_complete shall not be called. ]*/
+        indicate_ws_close_complete(uws_client);
+        break;
+
+    case UWS_STATE_OPENING_UNDERLYING_IO:
+    case UWS_STATE_WAITING_FOR_UPGRADE_RESPONSE:
+        /* Codes_SRS_UWS_CLIENT_01_375: [ When on_underlying_io_error is called while uws is OPENING, uws shall report that the open failed by calling the on_ws_open_complete callback passed to uws_client_open_async with WS_OPEN_ERROR_UNDERLYING_IO_ERROR. ]*/
+        /* Codes_SRS_UWS_CLIENT_01_077: [ If this fails (e.g., the server's certificate could not be verified), then the client MUST _Fail the WebSocket Connection_ and abort the connection. ]*/
+        indicate_ws_open_complete_error_and_close(uws_client, WS_OPEN_ERROR_UNDERLYING_IO_ERROR);
+        break;
+
+    case UWS_STATE_OPEN:
+        /* Codes_SRS_UWS_CLIENT_01_376: [ When on_underlying_io_error is called while the uws instance is OPEN, an error shall be reported to the user by calling the on_ws_error callback that was passed to uws_client_open_async with the argument WS_ERROR_UNDERLYING_IO_ERROR. ]*/
+        /* Codes_SRS_UWS_CLIENT_01_318: [ Servers MAY close the WebSocket connection whenever desired. ]*/
+        /* Codes_SRS_UWS_CLIENT_01_269: [ If at any point the state of the WebSocket connection changes, the endpoint MUST abort the following steps. ]*/
+        indicate_ws_error(uws_client, WS_ERROR_UNDERLYING_IO_ERROR);
+        break;
+    }
+}
+
+int uws_client_open_async(UWS_CLIENT_HANDLE uws_client, ON_WS_OPEN_COMPLETE on_ws_open_complete, void* on_ws_open_complete_context, ON_WS_FRAME_RECEIVED on_ws_frame_received, void* on_ws_frame_received_context, ON_WS_PEER_CLOSED on_ws_peer_closed, void* on_ws_peer_closed_context, ON_WS_ERROR on_ws_error, void* on_ws_error_context)
+{
+    int result;
+
+    /* Codes_SRS_UWS_CLIENT_01_393: [ The context arguments for the callbacks shall be allowed to be NULL. ]*/
+    if ((uws_client == NULL) ||
+        (on_ws_open_complete == NULL) ||
+        (on_ws_frame_received == NULL) ||
+        (on_ws_peer_closed == NULL) ||
+        (on_ws_error == NULL))
+    {
+        /* Codes_SRS_UWS_CLIENT_01_027: [ If uws_client, on_ws_open_complete, on_ws_frame_received, on_ws_peer_closed or on_ws_error is NULL, uws_client_open_async shall fail and return a non-zero value. ]*/
+        LogError("Invalid arguments: uws=%p, on_ws_open_complete=%p, on_ws_frame_received=%p, on_ws_error=%p",
+            uws_client, on_ws_open_complete, on_ws_frame_received, on_ws_error);
+        result = MU_FAILURE;
+    }
+    else
+    {
+        if (uws_client->uws_state != UWS_STATE_CLOSED)
+        {
+            /* Codes_SRS_UWS_CLIENT_01_400: [ uws_client_open_async while CLOSING shall fail and return a non-zero value. ]*/
+            /* Codes_SRS_UWS_CLIENT_01_394: [ uws_client_open_async while the uws instance is already OPEN or OPENING shall fail and return a non-zero value. ]*/
+            LogError("Invalid uWS state while trying to open: %d", (int)uws_client->uws_state);
+            result = MU_FAILURE;
+        }
+        else
+        {
+            uws_client->uws_state = UWS_STATE_OPENING_UNDERLYING_IO;
+
+            uws_client->stream_buffer_count = 0;
+            uws_client->fragment_buffer_count = 0;
+            uws_client->fragmented_frame_type = WS_FRAME_TYPE_UNKNOWN;
+
+            uws_client->on_ws_open_complete = on_ws_open_complete;
+            uws_client->on_ws_open_complete_context = on_ws_open_complete_context;
+            uws_client->on_ws_frame_received = on_ws_frame_received;
+            uws_client->on_ws_frame_received_context = on_ws_frame_received_context;
+            uws_client->on_ws_peer_closed = on_ws_peer_closed;
+            uws_client->on_ws_peer_closed_context = on_ws_peer_closed_context;
+            uws_client->on_ws_error = on_ws_error;
+            uws_client->on_ws_error_context = on_ws_error_context;
+
+            /* Codes_SRS_UWS_CLIENT_01_025: [ uws_client_open_async shall open the underlying IO by calling xio_open and providing the IO handle created in uws_client_create as argument. ]*/
+            /* Codes_SRS_UWS_CLIENT_01_367: [ The callbacks on_underlying_io_open_complete, on_underlying_io_bytes_received and on_underlying_io_error shall be passed as arguments to xio_open. ]*/
+            /* Codes_SRS_UWS_CLIENT_01_061: [ To _Establish a WebSocket Connection_, a client opens a connection and sends a handshake as defined in this section. ]*/
+            if (xio_open(uws_client->underlying_io, on_underlying_io_open_complete, uws_client, on_underlying_io_bytes_received, uws_client, on_underlying_io_error, uws_client) != 0)
+            {
+                /* Codes_SRS_UWS_CLIENT_01_028: [ If opening the underlying IO fails then uws_client_open_async shall fail and return a non-zero value. ]*/
+                /* Codes_SRS_UWS_CLIENT_01_075: [ If the connection could not be opened, either because a direct connection failed or because any proxy used returned an error, then the client MUST _Fail the WebSocket Connection_ and abort the connection attempt. ]*/
+                LogError("Opening the underlying IO failed");
+                uws_client->uws_state = UWS_STATE_CLOSED;
+                result = MU_FAILURE;
+            }
+            else
+            {
+                /* Codes_SRS_UWS_CLIENT_01_026: [ On success, uws_client_open_async shall return 0. ]*/
+                result = 0;
+            }
+        }
+    }
+
+    return result;
+}
+
+static int complete_send_frame(WS_PENDING_SEND* ws_pending_send, LIST_ITEM_HANDLE pending_send_frame_item, WS_SEND_FRAME_RESULT ws_send_frame_result)
+{
+    int result;
+    UWS_CLIENT_INSTANCE* uws_client = ws_pending_send->uws_client;
+
+    /* Codes_SRS_UWS_CLIENT_01_432: [ The indicated sent frame shall be removed from the list by calling singlylinkedlist_remove. ]*/
+    if (singlylinkedlist_remove(uws_client->pending_sends, pending_send_frame_item) != 0)
+    {
+        LogError("Failed removing item from list");
+        result = MU_FAILURE;
+    }
+    else
+    {
+        if (ws_pending_send->on_ws_send_frame_complete != NULL)
+        {
+            /* Codes_SRS_UWS_CLIENT_01_037: [ When indicating pending send frames as cancelled the callback context passed to the on_ws_send_frame_complete callback shall be the context given to uws_client_send_frame_async. ]*/
+            ws_pending_send->on_ws_send_frame_complete(ws_pending_send->context, ws_send_frame_result);
+        }
+
+        /* Codes_SRS_UWS_CLIENT_01_434: [ The memory associated with the sent frame shall be freed. ]*/
+        free(ws_pending_send);
+
+        result = 0;
+    }
+
+    return result;
+}
+
+/* Codes_SRS_UWS_CLIENT_01_029: [ uws_client_close_async shall close the uws instance connection if an open action is either pending or has completed successfully (if the IO is open). ]*/
+/* Codes_SRS_UWS_CLIENT_01_317: [ Clients SHOULD NOT close the WebSocket connection arbitrarily. ]*/
+int uws_client_close_async(UWS_CLIENT_HANDLE uws_client, ON_WS_CLOSE_COMPLETE on_ws_close_complete, void* on_ws_close_complete_context)
+{
+    int result;
+
+    /* Codes_SRS_UWS_CLIENT_01_397: [ The on_ws_close_complete argument shall be allowed to be NULL, in which case no callback shall be called when the close is complete. ]*/
+    /* Codes_SRS_UWS_CLIENT_01_398: [ on_ws_close_complete_context shall also be allows to be NULL. ]*/
+    if (uws_client == NULL)
+    {
+        /* Codes_SRS_UWS_CLIENT_01_030: [ if uws_client is NULL, uws_client_close_async shall return a non-zero value. ]*/
+        LogError("NULL uWS handle.");
+        result = MU_FAILURE;
+    }
+    else
+    {
+        if ((uws_client->uws_state == UWS_STATE_CLOSED) ||
+            (uws_client->uws_state == UWS_STATE_CLOSING_SENDING_CLOSE) ||
+            (uws_client->uws_state == UWS_STATE_CLOSING_WAITING_FOR_CLOSE) ||
+            (uws_client->uws_state == UWS_STATE_CLOSING_UNDERLYING_IO))
+        {
+            /* Codes_SRS_UWS_CLIENT_01_032: [ uws_client_close_async when no open action has been issued shall fail and return a non-zero value. ]*/
+            LogError("close has been called when already CLOSED");
+            result = MU_FAILURE;
+        }
+        else
+        {
+            /* Codes_SRS_UWS_CLIENT_01_399: [ on_ws_close_complete and on_ws_close_complete_context shall be saved and the callback on_ws_close_complete shall be triggered when the close is complete. ]*/
+            uws_client->on_ws_close_complete = on_ws_close_complete;
+            uws_client->on_ws_close_complete_context = on_ws_close_complete_context;
+
+            uws_client->uws_state = UWS_STATE_CLOSING_UNDERLYING_IO;
+
+            /* Codes_SRS_UWS_CLIENT_01_031: [ uws_client_close_async shall close the connection by calling xio_close while passing as argument the IO handle created in uws_client_create. ]*/
+            /* Codes_SRS_UWS_CLIENT_01_368: [ The callback on_underlying_io_close shall be passed as argument to xio_close. ]*/
+            if (xio_close(uws_client->underlying_io, (on_ws_close_complete == NULL) ? NULL :  on_underlying_io_close_complete, (on_ws_close_complete == NULL) ? NULL : uws_client) != 0)
+            {
+                /* Codes_SRS_UWS_CLIENT_01_395: [ If xio_close fails, uws_client_close_async shall fail and return a non-zero value. ]*/
+                LogError("Closing the underlying IO failed.");
+                result = MU_FAILURE;
+            }
+            else
+            {
+                /* Codes_SRS_UWS_CLIENT_01_034: [ uws_client_close_async shall obtain all the pending send frames by repetitively querying for the head of the pending IO list and freeing that head item. ]*/
+                LIST_ITEM_HANDLE first_pending_send;
+
+                /* Codes_SRS_UWS_CLIENT_01_035: [ Obtaining the head of the pending send frames list shall be done by calling singlylinkedlist_get_head_item. ]*/
+                while ((first_pending_send = singlylinkedlist_get_head_item(uws_client->pending_sends)) != NULL)
+                {
+                    WS_PENDING_SEND* ws_pending_send = (WS_PENDING_SEND*)singlylinkedlist_item_get_value(first_pending_send);
+
+                    /* Codes_SRS_UWS_CLIENT_01_036: [ For each pending send frame the send complete callback shall be called with UWS_SEND_FRAME_CANCELLED. ]*/
+                    complete_send_frame(ws_pending_send, first_pending_send, WS_SEND_FRAME_CANCELLED);
+                }
+
+                /* Codes_SRS_UWS_CLIENT_01_396: [ On success uws_client_close_async shall return 0. ]*/
+                result = 0;
+            }
+        }
+    }
+
+    return result;
+}
+
+/* Codes_SRS_UWS_CLIENT_01_317: [ Clients SHOULD NOT close the WebSocket connection arbitrarily. ]*/
+int uws_client_close_handshake_async(UWS_CLIENT_HANDLE uws_client, uint16_t close_code, const char* close_reason, ON_WS_CLOSE_COMPLETE on_ws_close_complete, void* on_ws_close_complete_context)
+{
+    int result;
+
+    if (uws_client == NULL)
+    {
+        /* Codes_SRS_UWS_CLIENT_01_467: [ if uws_client is NULL, uws_client_close_handshake_async shall return a non-zero value. ]*/
+        LogError("NULL uws_client");
+        result = MU_FAILURE;
+    }
+    else
+    {
+        if ((uws_client->uws_state == UWS_STATE_CLOSED) ||
+            /* Codes_SRS_UWS_CLIENT_01_474: [ uws_client_close_handshake_async when already CLOSING shall fail and return a non-zero value. ]*/
+            (uws_client->uws_state == UWS_STATE_CLOSING_WAITING_FOR_CLOSE) ||
+            (uws_client->uws_state == UWS_STATE_CLOSING_SENDING_CLOSE) ||
+            (uws_client->uws_state == UWS_STATE_CLOSING_UNDERLYING_IO))
+        {
+            /* Codes_SRS_UWS_CLIENT_01_473: [ uws_client_close_handshake_async when no open action has been issued shall fail and return a non-zero value. ]*/
+            LogError("uws_client_close_handshake_async has been called when already CLOSED");
+            result = MU_FAILURE;
+        }
+        else
+        {
+            (void)close_reason;
+
+            /* Codes_SRS_UWS_CLIENT_01_468: [ on_ws_close_complete and on_ws_close_complete_context shall be saved and the callback on_ws_close_complete shall be triggered when the close is complete. ]*/
+            /* Codes_SRS_UWS_CLIENT_01_469: [ The on_ws_close_complete argument shall be allowed to be NULL, in which case no callback shall be called when the close is complete. ]*/
+            /* Codes_SRS_UWS_CLIENT_01_470: [ on_ws_close_complete_context shall also be allowed to be NULL. ]*/
+            uws_client->on_ws_close_complete = on_ws_close_complete;
+            uws_client->on_ws_close_complete_context = on_ws_close_complete_context;
+
+            uws_client->uws_state = UWS_STATE_CLOSING_WAITING_FOR_CLOSE;
+
+            /* Codes_SRS_UWS_CLIENT_01_465: [ uws_client_close_handshake_async shall initiate the close handshake by sending a close frame to the peer. ]*/
+            if (send_close_frame(uws_client, close_code) != 0)
+            {
+                /* Codes_SRS_UWS_CLIENT_01_472: [ If xio_send fails, uws_client_close_handshake_async shall fail and return a non-zero value. ]*/
+                LogError("Sending CLOSE frame failed");
+                result = MU_FAILURE;
+            }
+            else
+            {
+                LIST_ITEM_HANDLE first_pending_send;
+
+                while ((first_pending_send = singlylinkedlist_get_head_item(uws_client->pending_sends)) != NULL)
+                {
+                    WS_PENDING_SEND* ws_pending_send = (WS_PENDING_SEND*)singlylinkedlist_item_get_value(first_pending_send);
+
+                    complete_send_frame(ws_pending_send, first_pending_send, WS_SEND_FRAME_CANCELLED);
+                }
+
+                /* Codes_SRS_UWS_CLIENT_01_466: [ On success uws_client_close_handshake_async shall return 0. ]*/
+                result = 0;
+            }
+        }
+    }
+
+    return result;
+}
+
+static void on_underlying_io_send_complete(void* context, IO_SEND_RESULT send_result)
+{
+    if (context == NULL)
+    {
+        /* Codes_SRS_UWS_CLIENT_01_435: [ When on_underlying_io_send_complete is called with a NULL context, it shall do nothing. ]*/
+        LogError("on_underlying_io_send_complete called with NULL context");
+    }
+    else
+    {
+        LIST_ITEM_HANDLE ws_pending_send_list_item = (LIST_ITEM_HANDLE)context;
+        WS_PENDING_SEND* ws_pending_send = (WS_PENDING_SEND*)singlylinkedlist_item_get_value(ws_pending_send_list_item);
+        if (ws_pending_send != NULL)
+        {
+            UWS_CLIENT_HANDLE uws_client = ws_pending_send->uws_client;
+            WS_SEND_FRAME_RESULT ws_send_frame_result;
+
+            switch (send_result)
+            {
+                /* Codes_SRS_UWS_CLIENT_01_436: [ When on_underlying_io_send_complete is called with any other error code, the send shall be indicated to the uws user by calling on_ws_send_frame_complete with WS_SEND_FRAME_ERROR. ]*/
+            default:
+            case IO_SEND_ERROR:
+                /* Codes_SRS_UWS_CLIENT_01_390: [ When on_underlying_io_send_complete is called with IO_SEND_ERROR as a result of sending a WebSocket frame to the underlying IO, the send shall be indicated to the uws user by calling on_ws_send_frame_complete with WS_SEND_FRAME_ERROR. ]*/
+                ws_send_frame_result = WS_SEND_FRAME_ERROR;
+                break;
+
+            case IO_SEND_OK:
+                /* Codes_SRS_UWS_CLIENT_01_389: [ When on_underlying_io_send_complete is called with IO_SEND_OK as a result of sending a WebSocket frame to the underlying IO, the send shall be indicated to the uws user by calling on_ws_send_frame_complete with WS_SEND_FRAME_OK. ]*/
+                ws_send_frame_result = WS_SEND_FRAME_OK;
+                break;
+
+            case IO_SEND_CANCELLED:
+                /* Codes_SRS_UWS_CLIENT_01_391: [ When on_underlying_io_send_complete is called with IO_SEND_CANCELLED as a result of sending a WebSocket frame to the underlying IO, the send shall be indicated to the uws user by calling on_ws_send_frame_complete with WS_SEND_FRAME_CANCELLED. ]*/
+                ws_send_frame_result = WS_SEND_FRAME_CANCELLED;
+                break;
+            }
+
+            if (complete_send_frame(ws_pending_send, ws_pending_send_list_item, ws_send_frame_result) != 0)
+            {
+                /* Codes_SRS_UWS_CLIENT_01_433: [ If singlylinkedlist_remove fails an error shall be indicated by calling the on_ws_error callback with WS_ERROR_CANNOT_REMOVE_SENT_ITEM_FROM_LIST. ]*/
+                indicate_ws_error(uws_client, WS_ERROR_CANNOT_REMOVE_SENT_ITEM_FROM_LIST);
+            }
+        }
+        else
+        {
+            LogError("Failing getting singlylinkedlist_item_get_value on_underlying_io_send_complete");
+        }
+    }
+}
+
+static bool find_list_node(LIST_ITEM_HANDLE list_item, const void* match_context)
+{
+    return list_item == (LIST_ITEM_HANDLE)match_context;
+}
+
+int uws_client_send_frame_async(UWS_CLIENT_HANDLE uws_client, unsigned char frame_type, const unsigned char* buffer, size_t size, bool is_final, ON_WS_SEND_FRAME_COMPLETE on_ws_send_frame_complete, void* on_ws_send_frame_complete_context)
+{
+    int result;
+
+    if (uws_client == NULL)
+    {
+        /* Codes_SRS_UWS_CLIENT_01_044: [ If any the arguments uws_client is NULL, uws_client_send_frame_async shall fail and return a non-zero value. ]*/
+        LogError("NULL uws handle.");
+        result = MU_FAILURE;
+    }
+    else if ((buffer == NULL) &&
+        (size > 0))
+    {
+        /* Codes_SRS_UWS_CLIENT_01_045: [ If size is non-zero and buffer is NULL then uws_client_send_frame_async shall fail and return a non-zero value. ]*/
+        LogError("NULL buffer with %u size.", (unsigned int)size);
+        result = MU_FAILURE;
+    }
+    /* Codes_SRS_UWS_CLIENT_01_146: [ A data frame MAY be transmitted by either the client or the server at any time after opening handshake completion and before that endpoint has sent a Close frame (Section 5.5.1). ]*/
+    /* Codes_SRS_UWS_CLIENT_01_268: [ The endpoint MUST ensure the WebSocket connection is in the OPEN state ]*/
+    else if (uws_client->uws_state != UWS_STATE_OPEN)
+    {
+        /* Codes_SRS_UWS_CLIENT_01_043: [ If the uws instance is not OPEN (open has not been called or is still in progress) then uws_client_send_frame_async shall fail and return a non-zero value. ]*/
+        LogError("uws not in OPEN state.");
+        result = MU_FAILURE;
+    }
+    else
+    {
+        WS_PENDING_SEND* ws_pending_send = (WS_PENDING_SEND*)malloc(sizeof(WS_PENDING_SEND));
+        if (ws_pending_send == NULL)
+        {
+            /* Codes_SRS_UWS_CLIENT_01_047: [ If allocating memory for the newly queued item fails, uws_client_send_frame_async shall fail and return a non-zero value. ]*/
+            LogError("Cannot allocate memory for frame to be sent.");
+            result = MU_FAILURE;
+        }
+        else
+        {
+            BUFFER_HANDLE non_control_frame_buffer;
+
+            /* Codes_SRS_UWS_CLIENT_01_425: [ Encoding shall be done by calling uws_frame_encoder_encode and passing to it the buffer and size argument for payload, the is_final flag and setting is_masked to true. ]*/
+            /* Codes_SRS_UWS_CLIENT_01_270: [ An endpoint MUST encapsulate the /data/ in a WebSocket frame as defined in Section 5.2. ]*/
+            /* Codes_SRS_UWS_CLIENT_01_272: [ The opcode (frame-opcode) of the first frame containing the data MUST be set to the appropriate value from Section 5.2 for data that is to be interpreted by the recipient as text or binary data. ]*/
+            /* Codes_SRS_UWS_CLIENT_01_274: [ If the data is being sent by the client, the frame(s) MUST be masked as defined in Section 5.3. ]*/
+            non_control_frame_buffer = uws_frame_encoder_encode((WS_FRAME_TYPE)frame_type, buffer, size, true, is_final, 0);
+            if (non_control_frame_buffer == NULL)
+            {
+                /* Codes_SRS_UWS_CLIENT_01_426: [ If uws_frame_encoder_encode fails, uws_client_send_frame_async shall fail and return a non-zero value. ]*/
+                LogError("Failed encoding WebSocket frame");
+                free(ws_pending_send);
+                result = MU_FAILURE;
+            }
+            else
+            {
+                const unsigned char* encoded_frame;
+                size_t encoded_frame_length;
+                LIST_ITEM_HANDLE new_pending_send_list_item;
+
+                /* Codes_SRS_UWS_CLIENT_01_428: [ The encoded frame buffer memory shall be obtained by calling BUFFER_u_char on the encode buffer. ]*/
+                encoded_frame = BUFFER_u_char(non_control_frame_buffer);
+                /* Codes_SRS_UWS_CLIENT_01_429: [ The encoded frame size shall be obtained by calling BUFFER_length on the encode buffer. ]*/
+                encoded_frame_length = BUFFER_length(non_control_frame_buffer);
+
+                /* Codes_SRS_UWS_CLIENT_01_038: [ uws_client_send_frame_async shall create and queue a structure that contains: ]*/
+                /* Codes_SRS_UWS_CLIENT_01_050: [ The argument on_ws_send_frame_complete shall be optional, if NULL is passed by the caller then no send complete callback shall be triggered. ]*/
+                /* Codes_SRS_UWS_CLIENT_01_040: [ - the send complete callback on_ws_send_frame_complete ]*/
+                /* Codes_SRS_UWS_CLIENT_01_041: [ - the send complete callback context on_ws_send_frame_complete_context ]*/
+                ws_pending_send->on_ws_send_frame_complete = on_ws_send_frame_complete;
+                ws_pending_send->context = on_ws_send_frame_complete_context;
+                ws_pending_send->uws_client = uws_client;
+
+                /* Codes_SRS_UWS_CLIENT_01_048: [ Queueing shall be done by calling singlylinkedlist_add. ]*/
+                new_pending_send_list_item = singlylinkedlist_add(uws_client->pending_sends, ws_pending_send);
+                if (new_pending_send_list_item == NULL)
+                {
+                    /* Codes_SRS_UWS_CLIENT_01_049: [ If singlylinkedlist_add fails, uws_client_send_frame_async shall fail and return a non-zero value. ]*/
+                    LogError("Could not allocate memory for pending frames");
+                    free(ws_pending_send);
+                    result = MU_FAILURE;
+                }
+                else
+                {
+                    /* Codes_SRS_UWS_CLIENT_01_431: [ Once encoded the frame shall be sent by using xio_send with the following arguments: ]*/
+                    /* Codes_SRS_UWS_CLIENT_01_053: [ - the io handle shall be the underlyiong IO handle created in uws_client_create. ]*/
+                    /* Codes_SRS_UWS_CLIENT_01_054: [ - the buffer argument shall point to the complete websocket frame to be sent. ]*/
+                    /* Codes_SRS_UWS_CLIENT_01_055: [ - the size argument shall indicate the websocket frame length. ]*/
+                    /* Codes_SRS_UWS_CLIENT_01_056: [ - the send_complete callback shall be the on_underlying_io_send_complete function. ]*/
+                    /* Codes_SRS_UWS_CLIENT_01_057: [ - the send_complete_context argument shall identify the pending send. ]*/
+                    /* Codes_SRS_UWS_CLIENT_01_276: [ The frame(s) that have been formed MUST be transmitted over the underlying network connection. ]*/
+                    if (xio_send(uws_client->underlying_io, encoded_frame, encoded_frame_length, on_underlying_io_send_complete, new_pending_send_list_item) != 0)
+                    {
+                        /* Codes_SRS_UWS_CLIENT_01_058: [ If xio_send fails, uws_client_send_frame_async shall fail and return a non-zero value. ]*/
+                        LogError("Could not send bytes through the underlying IO");
+
+                        /* Codes_SRS_UWS_CLIENT_09_001: [ If xio_send fails and the message is still queued, it shall be de-queued and destroyed. ] */
+                        if (singlylinkedlist_find(uws_client->pending_sends, find_list_node, new_pending_send_list_item) != NULL)
+                        {
+                            // Guards against double free in case the underlying I/O invoked 'on_underlying_io_send_complete' within xio_send.
+                            (void)singlylinkedlist_remove(uws_client->pending_sends, new_pending_send_list_item);
+                            free(ws_pending_send);
+                        }
+
+                        result = MU_FAILURE;
+                    }
+                    else
+                    {
+                        /* Codes_SRS_UWS_CLIENT_01_042: [ On success, uws_client_send_frame_async shall return 0. ]*/
+                        result = 0;
+                    }
+                }
+
+                BUFFER_delete(non_control_frame_buffer);
+            }
+        }
+    }
+
+    return result;
+}
+
+void uws_client_dowork(UWS_CLIENT_HANDLE uws_client)
+{
+    if (uws_client == NULL)
+    {
+        /* Codes_SRS_UWS_CLIENT_01_059: [ If the uws_client argument is NULL, uws_client_dowork shall do nothing. ]*/
+        LogError("NULL uws handle.");
+    }
+    else
+    {
+        /* Codes_SRS_UWS_CLIENT_01_060: [ If the IO is not yet open, uws_client_dowork shall do nothing. ]*/
+        if (uws_client->uws_state != UWS_STATE_CLOSED)
+        {
+            /* Codes_SRS_UWS_CLIENT_01_430: [ uws_client_dowork shall call xio_dowork with the IO handle argument set to the underlying IO created in uws_client_create. ]*/
+            xio_dowork(uws_client->underlying_io);
+        }
+    }
+}
+
+int uws_client_set_option(UWS_CLIENT_HANDLE uws_client, const char* option_name, const void* value)
+{
+    int result;
+
+    if (
+        (uws_client == NULL) ||
+        (option_name == NULL)
+        )
+    {
+        /* Codes_SRS_UWS_CLIENT_01_440: [ If any of the arguments uws_client or option_name is NULL uws_client_set_option shall return a non-zero value. ]*/
+        LogError("invalid parameter (NULL) passed to uws_client_set_option");
+        result = MU_FAILURE;
+    }
+    else
+    {
+        if (strcmp(UWS_CLIENT_OPTIONS, option_name) == 0)
+        {
+            /* Codes_SRS_UWS_CLIENT_01_510: [ If the option name is uWSClientOptions then uws_client_set_option shall call OptionHandler_FeedOptions and pass to it the underlying IO handle and the value argument. ]*/
+            if (OptionHandler_FeedOptions((OPTIONHANDLER_HANDLE)value, uws_client->underlying_io) != OPTIONHANDLER_OK)
+            {
+                /* Codes_SRS_UWS_CLIENT_01_511: [ If OptionHandler_FeedOptions fails, uws_client_set_option shall fail and return a non-zero value. ]*/
+                LogError("OptionHandler_FeedOptions failed");
+                result = MU_FAILURE;
+            }
+            else
+            {
+                /* Codes_SRS_UWS_CLIENT_01_442: [ On success, uws_client_set_option shall return 0. ]*/
+                result = 0;
+            }
+        }
+        else
+        {
+            /* Codes_SRS_UWS_CLIENT_01_441: [ Otherwise all options shall be passed as they are to the underlying IO by calling xio_setoption. ]*/
+            if (xio_setoption(uws_client->underlying_io, option_name, value) != 0)
+            {
+                /* Codes_SRS_UWS_CLIENT_01_443: [ If xio_setoption fails, uws_client_set_option shall fail and return a non-zero value. ]*/
+                LogError("xio_setoption failed.");
+                result = MU_FAILURE;
+            }
+            else
+            {
+                /* Codes_SRS_UWS_CLIENT_01_442: [ On success, uws_client_set_option shall return 0. ]*/
+                result = 0;
+            }
+        }
+    }
+
+    return result;
+}
+
+static void* uws_client_clone_option(const char* name, const void* value)
+{
+    void* result;
+
+    if (
+        (name == NULL) ||
+        (value == NULL)
+        )
+    {
+        /* Codes_SRS_UWS_CLIENT_01_506: [ If uws_client_clone_option is called with NULL name or value it shall return NULL. ]*/
+        LogError("invalid argument detected: const char* name=%p, const void* value=%p", name, value);
+        result = NULL;
+    }
+    else
+    {
+        if (strcmp(name, UWS_CLIENT_OPTIONS) == 0)
+        {
+            /* Codes_SRS_UWS_CLIENT_01_507: [ uws_client_clone_option called with name being uWSClientOptions shall return the same value. ]*/
+            result = (void*)value;
+        }
+        else
+        {
+            /* Codes_SRS_UWS_CLIENT_01_512: [ uws_client_clone_option called with any other option name than uWSClientOptions shall return NULL. ]*/
+            LogError("unknown option: %s", name);
+            result = NULL;
+        }
+    }
+
+    return result;
+}
+
+static void uws_client_destroy_option(const char* name, const void* value)
+{
+    if (
+        (name == NULL) ||
+        (value == NULL)
+        )
+    {
+        /* Codes_SRS_UWS_CLIENT_01_509: [ If uws_client_destroy_option is called with NULL name or value it shall do nothing. ]*/
+        LogError("invalid argument detected: const char* name=%p, const void* value=%p", name, value);
+    }
+    else
+    {
+        if (strcmp(name, UWS_CLIENT_OPTIONS) == 0)
+        {
+            /* Codes_SRS_UWS_CLIENT_01_508: [ uws_client_destroy_option called with the option name being uWSClientOptions shall destroy the value by calling OptionHandler_Destroy. ]*/
+            OptionHandler_Destroy((OPTIONHANDLER_HANDLE)value);
+        }
+        else
+        {
+            /* Codes_SRS_UWS_CLIENT_01_513: [ If uws_client_destroy_option is called with any other name it shall do nothing. ]*/
+            LogError("unknown option: %s", name);
+        }
+    }
+}
+
+OPTIONHANDLER_HANDLE uws_client_retrieve_options(UWS_CLIENT_HANDLE uws_client)
+{
+    OPTIONHANDLER_HANDLE result;
+
+    if (uws_client == NULL)
+    {
+        /* Codes_SRS_UWS_CLIENT_01_444: [ If parameter uws_client is NULL then uws_client_retrieve_options shall fail and return NULL. ]*/
+        LogError("NULL uws handle.");
+        result = NULL;
+    }
+    else
+    {
+        /* Codes_SRS_UWS_CLIENT_01_445: [ uws_client_retrieve_options shall call OptionHandler_Create to produce an OPTIONHANDLER_HANDLE and on success return the new OPTIONHANDLER_HANDLE handle. ]*/
+        result = OptionHandler_Create(uws_client_clone_option, uws_client_destroy_option, (pfSetOption)uws_client_set_option);
+        if (result == NULL)
+        {
+            /* Codes_SRS_UWS_CLIENT_01_446: [ If OptionHandler_Create fails then uws_client_retrieve_options shall fail and return NULL. ]*/
+            LogError("OptionHandler_Create failed");
+        }
+        else
+        {
+            /* Codes_SRS_UWS_CLIENT_01_502: [ When calling xio_retrieveoptions the underlying IO handle shall be passed to it. ]*/
+            OPTIONHANDLER_HANDLE underlying_io_options = xio_retrieveoptions(uws_client->underlying_io);
+            if (underlying_io_options == NULL)
+            {
+                /* Codes_SRS_UWS_CLIENT_01_503: [ If xio_retrieveoptions fails, uws_client_retrieve_options shall fail and return NULL. ]*/
+                LogError("unable to concrete_io_retrieveoptions");
+                OptionHandler_Destroy(result);
+                result = NULL;
+            }
+            else
+            {
+                /* Codes_SRS_UWS_CLIENT_01_501: [ uws_client_retrieve_options shall add to the option handler one option, whose name shall be uWSClientOptions and the value shall be queried by calling xio_retrieveoptions. ]*/
+                /* Codes_SRS_UWS_CLIENT_01_504: [ Adding the option shall be done by calling OptionHandler_AddOption. ]*/
+                if (OptionHandler_AddOption(result, UWS_CLIENT_OPTIONS, underlying_io_options) != OPTIONHANDLER_OK)
+                {
+                    /* Codes_SRS_UWS_CLIENT_01_505: [ If OptionHandler_AddOption fails, uws_client_retrieve_options shall fail and return NULL. ]*/
+                    LogError("OptionHandler_AddOption failed");
+                    OptionHandler_Destroy(underlying_io_options);
+                    OptionHandler_Destroy(result);
+                    result = NULL;
+                }
+            }
+        }
+
+    }
+
+    return result;
+}
+
+int uws_client_set_request_header(UWS_CLIENT_HANDLE uws_client, const char* name, const char* value)
+{
+    int result;
+
+    if (uws_client == NULL || name == NULL || value == NULL)
+    {
+        // Codes_SRS_UWS_CLIENT_09_002: [ If any of the arguments uws_client or name or value is NULL uws_client_set_request_header shall fail and return a non-zero value. ]
+        LogError("invalid parameter (uws_client=%p, name=%p, value=%p)", uws_client, name, value);
+        result = MU_FAILURE;
+    }
+    // Codes_SRS_UWS_CLIENT_09_003: [ A copy of name and value shall be stored for later sending in the request message. ]
+    else if (Map_AddOrUpdate(uws_client->request_headers, name, value) != MAP_OK)
+    {
+        // Codes_SRS_UWS_CLIENT_09_004: [ If name or value fail to be stored the function shall fail and return a non-zero value. ]
+        LogError("Failed adding request header %s", name);
+        result = MU_FAILURE;
+    }
+    else
+    {
+        // Codes_SRS_UWS_CLIENT_09_005: [ If no failures occur the function shall return zero. ]
+        result = 0;
+    }
+
+    return result;
+}
Index: azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/src/uws_frame_encoder.c
===================================================================
--- azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/src/uws_frame_encoder.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/src/uws_frame_encoder.c	(revision 457)
@@ -0,0 +1,190 @@
+ // Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+#include <stdlib.h>
+#include <stdint.h>
+#include <stdbool.h>
+#include "azure_c_shared_utility/gballoc.h"
+#include "azure_c_shared_utility/gb_rand.h"
+#include "azure_c_shared_utility/uws_frame_encoder.h"
+#include "azure_c_shared_utility/xlogging.h"
+#include "azure_c_shared_utility/buffer_.h"
+#include "azure_c_shared_utility/uniqueid.h"
+
+BUFFER_HANDLE uws_frame_encoder_encode(WS_FRAME_TYPE opcode, const unsigned char* payload, size_t length, bool is_masked, bool is_final, unsigned char reserved)
+{
+    BUFFER_HANDLE result;
+
+    if (reserved > 7)
+    {
+        /* Codes_SRS_UWS_FRAME_ENCODER_01_052: [ If reserved has any bits set except the lowest 3 then uws_frame_encoder_encode shall fail and return NULL. ]*/
+        LogError("Bad reserved value: 0x%02x", reserved);
+        result = NULL;
+    }
+    else if (opcode > 0x0F)
+    {
+        /* Codes_SRS_UWS_FRAME_ENCODER_01_006: [ If an unknown opcode is received, the receiving endpoint MUST _Fail the WebSocket Connection_. ]*/
+        LogError("Invalid opcode: 0x%02x", opcode);
+        result = NULL;
+    }
+    else if ((length > 0) &&
+        (payload == NULL))
+    {
+        /* Codes_SRS_UWS_FRAME_ENCODER_01_054: [ If length is greater than 0 and payload is NULL, then uws_frame_encoder_encode shall fail and return NULL. ]*/
+        LogError("Invalid arguments: NULL payload and length=%u", (unsigned int)length);
+        result = NULL;
+    }
+    else
+    {
+        size_t needed_bytes = 2;
+        size_t header_bytes;
+
+        /* Codes_SRS_UWS_FRAME_ENCODER_01_044: [ On success uws_frame_encoder_encode shall return a non-NULL handle to the result buffer. ]*/
+        /* Codes_SRS_UWS_FRAME_ENCODER_01_048: [ The newly created buffer shall be created by calling BUFFER_new. ]*/
+        result = BUFFER_new();
+        if (result == NULL)
+        {
+            /* Codes_SRS_UWS_FRAME_ENCODER_01_049: [ If BUFFER_new fails then uws_frame_encoder_encode shall fail and return NULL. ]*/
+            LogError("Cannot create new buffer");
+        }
+        else
+        {
+            /* Codes_SRS_UWS_FRAME_ENCODER_01_001: [ uws_frame_encoder_encode shall encode the information given in opcode, payload, length, is_masked, is_final and reserved according to the RFC6455 into a new buffer.]*/
+            if (length > 65535)
+            {
+                needed_bytes += 8;
+            }
+            else if (length > 125)
+            {
+                needed_bytes += 2;
+            }
+
+            if (is_masked)
+            {
+                needed_bytes += 4;
+            }
+
+            header_bytes = needed_bytes;
+            needed_bytes += length;
+
+            /* Codes_SRS_UWS_FRAME_ENCODER_01_046: [ The result buffer shall be resized accordingly using BUFFER_enlarge. ]*/
+            if (BUFFER_enlarge(result, needed_bytes) != 0)
+            {
+                /* Codes_SRS_UWS_FRAME_ENCODER_01_047: [ If BUFFER_enlarge fails then uws_frame_encoder_encode shall fail and return NULL. ]*/
+                LogError("Cannot allocate memory for encoded frame");
+                BUFFER_delete(result);
+                result = NULL;
+            }
+            else
+            {
+                /* Codes_SRS_UWS_FRAME_ENCODER_01_050: [ The allocated memory shall be accessed by calling BUFFER_u_char. ]*/
+                unsigned char* buffer = BUFFER_u_char(result);
+                if (buffer == NULL)
+                {
+                    /* Codes_SRS_UWS_FRAME_ENCODER_01_051: [ If BUFFER_u_char fails then uws_frame_encoder_encode shall fail and return a NULL. ]*/
+                    LogError("Cannot get encoded buffer pointer");
+                    BUFFER_delete(result);
+                    result = NULL;
+                }
+                else
+                {
+                    /* Codes_SRS_UWS_FRAME_ENCODER_01_007: [ *  %x0 denotes a continuation frame ]*/
+                    /* Codes_SRS_UWS_FRAME_ENCODER_01_008: [ *  %x1 denotes a text frame ]*/
+                    /* Codes_SRS_UWS_FRAME_ENCODER_01_009: [ *  %x2 denotes a binary frame ]*/
+                    /* Codes_SRS_UWS_FRAME_ENCODER_01_010: [ *  %x3-7 are reserved for further non-control frames ]*/
+                    /* Codes_SRS_UWS_FRAME_ENCODER_01_011: [ *  %x8 denotes a connection close ]*/
+                    /* Codes_SRS_UWS_FRAME_ENCODER_01_012: [ *  %x9 denotes a ping ]*/
+                    /* Codes_SRS_UWS_FRAME_ENCODER_01_013: [ *  %xA denotes a pong ]*/
+                    /* Codes_SRS_UWS_FRAME_ENCODER_01_014: [ *  %xB-F are reserved for further control frames ]*/
+                    buffer[0] = (unsigned char)opcode;
+
+                    /* Codes_SRS_UWS_FRAME_ENCODER_01_002: [ Indicates that this is the final fragment in a message. ]*/
+                    /* Codes_SRS_UWS_FRAME_ENCODER_01_003: [ The first fragment MAY also be the final fragment. ]*/
+                    if (is_final)
+                    {
+                        buffer[0] |= 0x80;
+                    }
+
+                    /* Codes_SRS_UWS_FRAME_ENCODER_01_004: [ MUST be 0 unless an extension is negotiated that defines meanings for non-zero values. ]*/
+                    buffer[0] |= reserved << 4;
+
+                    /* Codes_SRS_UWS_FRAME_ENCODER_01_022: [ Note that in all cases, the minimal number of bytes MUST be used to encode the length, for example, the length of a 124-byte-long string can't be encoded as the sequence 126, 0, 124. ]*/
+                    /* Codes_SRS_UWS_FRAME_ENCODER_01_018: [ The length of the "Payload data", in bytes: ]*/
+                    /* Codes_SRS_UWS_FRAME_ENCODER_01_023: [ The payload length is the length of the "Extension data" + the length of the "Application data". ]*/
+                    /* Codes_SRS_UWS_FRAME_ENCODER_01_042: [ The payload length, indicated in the framing as frame-payload-length, does NOT include the length of the masking key. ]*/
+                    if (length > 65535)
+                    {
+                        /* Codes_SRS_UWS_FRAME_ENCODER_01_020: [ If 127, the following 8 bytes interpreted as a 64-bit unsigned integer (the most significant bit MUST be 0) are the payload length. ]*/
+                        buffer[1] = 127;
+
+                        /* Codes_SRS_UWS_FRAME_ENCODER_01_021: [ Multibyte length quantities are expressed in network byte order. ]*/
+                        buffer[2] = (unsigned char)((uint64_t)length >> 56) & 0xFF;
+                        buffer[3] = (unsigned char)((uint64_t)length >> 48) & 0xFF;
+                        buffer[4] = (unsigned char)((uint64_t)length >> 40) & 0xFF;
+                        buffer[5] = (unsigned char)((uint64_t)length >> 32) & 0xFF;
+                        buffer[6] = (unsigned char)((uint64_t)length >> 24) & 0xFF;
+                        buffer[7] = (unsigned char)((uint64_t)length >> 16) & 0xFF;
+                        buffer[8] = (unsigned char)((uint64_t)length >> 8) & 0xFF;
+                        buffer[9] = (unsigned char)(length & 0xFF);
+                    }
+                    else if (length > 125)
+                    {
+                        /* Codes_SRS_UWS_FRAME_ENCODER_01_019: [ If 126, the following 2 bytes interpreted as a 16-bit unsigned integer are the payload length. ]*/
+                        buffer[1] = 126;
+
+                        /* Codes_SRS_UWS_FRAME_ENCODER_01_021: [ Multibyte length quantities are expressed in network byte order. ]*/
+                        buffer[2] = (unsigned char)(length >> 8);
+                        buffer[3] = (unsigned char)(length & 0xFF);
+                    }
+                    else
+                    {
+                        /* Codes_SRS_UWS_FRAME_ENCODER_01_043: [ if 0-125, that is the payload length. ]*/
+                        buffer[1] = (unsigned char)length;
+                    }
+
+                    if (is_masked)
+                    {
+                        /* Codes_SRS_UWS_FRAME_ENCODER_01_015: [ Defines whether the "Payload data" is masked. ]*/
+                        /* Codes_SRS_UWS_FRAME_ENCODER_01_033: [ A masked frame MUST have the field frame-masked set to 1, as defined in Section 5.2. ]*/
+                        buffer[1] |= 0x80;
+
+                        /* Codes_SRS_UWS_FRAME_ENCODER_01_053: [ In order to obtain a 32 bit value for masking, gb_rand shall be used 4 times (for each byte). ]*/
+                        /* Codes_SRS_UWS_FRAME_ENCODER_01_016: [ If set to 1, a masking key is present in masking-key, and this is used to unmask the "Payload data" as per Section 5.3. ]*/
+                        /* Codes_SRS_UWS_FRAME_ENCODER_01_026: [ This field is present if the mask bit is set to 1 and is absent if the mask bit is set to 0. ]*/
+                        /* Codes_SRS_UWS_FRAME_ENCODER_01_034: [ The masking key is contained completely within the frame, as defined in Section 5.2 as frame-masking-key. ]*/
+                        /* Codes_SRS_UWS_FRAME_ENCODER_01_036: [ The masking key is a 32-bit value chosen at random by the client. ]*/
+                        /* Codes_SRS_UWS_FRAME_ENCODER_01_037: [ When preparing a masked frame, the client MUST pick a fresh masking key from the set of allowed 32-bit values. ]*/
+                        /* Codes_SRS_UWS_FRAME_ENCODER_01_038: [ The masking key needs to be unpredictable; thus, the masking key MUST be derived from a strong source of entropy, and the masking key for a given frame MUST NOT make it simple for a server/proxy to predict the masking key for a subsequent frame. ]*/
+                        buffer[header_bytes - 4] = (unsigned char)gb_rand();
+                        buffer[header_bytes - 3] = (unsigned char)gb_rand();
+                        buffer[header_bytes - 2] = (unsigned char)gb_rand();
+                        buffer[header_bytes - 1] = (unsigned char)gb_rand();
+                    }
+
+                    if (length > 0)
+                    {
+                        if (is_masked)
+                        {
+                            size_t i;
+
+                            /* Codes_SRS_UWS_FRAME_ENCODER_01_035: [ It is used to mask the "Payload data" defined in the same section as frame-payload-data, which includes "Extension data" and "Application data". ]*/
+                            /* Codes_SRS_UWS_FRAME_ENCODER_01_039: [ To convert masked data into unmasked data, or vice versa, the following algorithm is applied. ]*/
+                            /* Codes_SRS_UWS_FRAME_ENCODER_01_040: [ The same algorithm applies regardless of the direction of the translation, e.g., the same steps are applied to mask the data as to unmask the data. ]*/
+                            for (i = 0; i < length; i++)
+                            {
+                                /* Codes_SRS_UWS_FRAME_ENCODER_01_041: [ Octet i of the transformed data ("transformed-octet-i") is the XOR of octet i of the original data ("original-octet-i") with octet at index i modulo 4 of the masking key ("masking-key-octet-j"): ]*/
+                                buffer[header_bytes + i] = ((unsigned char*)payload)[i] ^ buffer[header_bytes - 4 + (i % 4)];
+                            }
+                        }
+                        else
+                        {
+                            (void)memcpy(buffer + header_bytes, payload, length);
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    return result;
+}
Index: azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/src/vector.c
===================================================================
--- azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/src/vector.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/src/vector.c	(revision 457)
@@ -0,0 +1,338 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+#include <stdlib.h>
+#include "azure_c_shared_utility/gballoc.h"
+#include "azure_c_shared_utility/vector.h"
+#include "azure_c_shared_utility/optimize_size.h"
+#include "azure_c_shared_utility/xlogging.h"
+
+#include "azure_c_shared_utility/vector_types_internal.h"
+
+IMPLEMENT_MOCKABLE_FUNCTION(, VECTOR_HANDLE, VECTOR_create, size_t, elementSize)
+{
+    VECTOR_HANDLE result;
+
+    /* Codes_SRS_VECTOR_10_002: [VECTOR_create shall fail and return NULL if elementsize is 0.] */
+    if (elementSize == 0)
+    {
+        LogError("invalid elementSize(%zd).", elementSize);
+        result = NULL;
+    }
+    else
+    {
+        result = (VECTOR*)malloc(sizeof(VECTOR));
+        /* Codes_SRS_VECTOR_10_002 : [VECTOR_create shall fail and return NULL if malloc fails.] */
+        if (result == NULL)
+        {
+            LogError("malloc failed.");
+        }
+        else
+        {
+            /* Codes_SRS_VECTOR_10_001: [VECTOR_create shall allocate a VECTOR_HANDLE that will contain an empty vector.The size of each element is given with the parameter elementSize.] */
+            result->storage = NULL;
+            result->count = 0;
+            result->elementSize = elementSize;
+        }
+    }
+    return result;
+}
+
+IMPLEMENT_MOCKABLE_FUNCTION(, void, VECTOR_destroy, VECTOR_HANDLE, handle)
+{
+    /* Codes_SRS_VECTOR_10_009: [VECTOR_destroy shall return if the given handle is NULL.] */
+    if (handle == NULL)
+    {
+        LogError("invalid argument handle(NULL).");
+    }
+    else
+    {
+        /* Codes_SRS_VECTOR_10_008: [VECTOR_destroy shall free the given handle and its internal storage.] */
+        free(handle->storage);
+        free(handle);
+    }
+}
+
+IMPLEMENT_MOCKABLE_FUNCTION(, VECTOR_HANDLE, VECTOR_move, VECTOR_HANDLE, handle)
+{
+    VECTOR_HANDLE result;
+    if (handle == NULL)
+    {
+        /* Codes_SRS_VECTOR_10_005: [VECTOR_move shall fail and return NULL if the given handle is NULL.] */
+        LogError("invalid argument - handle(NULL).");
+        result = NULL;
+    }
+    else
+    {
+        result = (VECTOR*)malloc(sizeof(VECTOR));
+        if (result == NULL)
+        {
+            /* Codes_SRS_VECTOR_10_006: [VECTOR_move shall fail and return NULL if malloc fails.] */
+            LogError("malloc failed.");
+        }
+        else
+        {
+            /* Codes_SRS_VECTOR_10_004: [VECTOR_move shall allocate a VECTOR_HANDLE and move the data to it from the given handle.] */
+            result->count = handle->count;
+            result->elementSize = handle->elementSize;
+            result->storage = handle->storage;
+
+            handle->storage = NULL;
+            handle->count = 0;
+        }
+    }
+    return result;
+}
+
+/* insertion */
+
+IMPLEMENT_MOCKABLE_FUNCTION(, int, VECTOR_push_back, VECTOR_HANDLE, handle, const void*, elements, size_t, numElements)
+{
+    int result;
+    if (handle == NULL || elements == NULL || numElements == 0)
+    {
+       /* Codes_SRS_VECTOR_10_011: [VECTOR_push_back shall fail and return non-zero if handle is NULL.] */
+       /* Codes_SRS_VECTOR_10_034: [VECTOR_push_back shall fail and return non-zero if elements is NULL.] */
+       /* Codes_SRS_VECTOR_10_035: [VECTOR_push_back shall fail and return non-zero if numElements is 0.] */
+        LogError("invalid argument - handle(%p), elements(%p), numElements(%zd).", handle, elements, numElements);
+        result = MU_FAILURE;
+    }
+    else
+    {
+        size_t curSize = handle->elementSize * handle->count;
+        size_t appendSize = handle->elementSize * numElements;
+
+        void* temp = realloc(handle->storage, curSize + appendSize);
+        if (temp == NULL)
+        {
+           /* Codes_SRS_VECTOR_10_012: [VECTOR_push_back shall fail and return non-zero if memory allocation fails.] */
+            LogError("realloc failed.");
+            result = MU_FAILURE;
+        }
+        else
+        {
+            /* Codes_SRS_VECTOR_10_013: [VECTOR_push_back shall append the given elements and return 0 indicating success.] */
+            (void)memcpy((unsigned char*)temp + curSize, elements, appendSize);
+            handle->storage = temp;
+            handle->count += numElements;
+            result = 0;
+        }
+    }
+    return result;
+}
+
+/* removal */
+
+IMPLEMENT_MOCKABLE_FUNCTION(, void, VECTOR_erase, VECTOR_HANDLE, handle, void*, elements, size_t, numElements)
+{
+    if (handle == NULL || elements == NULL || numElements == 0)
+    {
+        /* Codes_SRS_VECTOR_10_015: [VECTOR_erase shall return if handle is NULL.] */
+        /* Codes_SRS_VECTOR_10_038: [VECTOR_erase shall return if elements is NULL.] */
+        /* Codes_SRS_VECTOR_10_039: [VECTOR_erase shall return if numElements is 0.] */
+        LogError("invalid argument - handle(%p), elements(%p), numElements(%zd).", handle, elements, numElements);
+    }
+    else
+    {
+        if (elements < handle->storage)
+        {
+            /* Codes_SRS_VECTOR_10_040: [VECTOR_erase shall return if elements is out of bound.] */
+            LogError("invalid argument elements(%p) is not a member of this object.", elements);
+        }
+        else
+        {
+            ptrdiff_t diff = ((unsigned char*)elements) - ((unsigned char*)handle->storage);
+            if ((diff % handle->elementSize) != 0)
+            {
+                /* Codes_SRS_VECTOR_10_041: [VECTOR_erase shall return if elements is misaligned.] */
+                LogError("invalid argument - elements(%p) is misaligned", elements);
+            }
+            else
+            {
+                /* Compute the arguments needed for memmove. */
+                unsigned char* src = (unsigned char*)elements + (handle->elementSize * numElements);
+                unsigned char* srcEnd = (unsigned char*)handle->storage + (handle->elementSize * handle->count);
+                if (src > srcEnd)
+                {
+                    /* Codes_SRS_VECTOR_10_040: [VECTOR_erase shall return if elements is out of bound.] */
+                    LogError("invalid argument - numElements(%zd) is out of bound.", numElements);
+                }
+                else
+                {
+                    /* Codes_SRS_VECTOR_10_014: [VECTOR_erase shall remove the 'numElements' starting at 'elements' and reduce its internal storage.] */
+                    handle->count -= numElements;
+                    if (handle->count == 0)
+                    {
+                        free(handle->storage);
+                        handle->storage = NULL;
+                    }
+                    else
+                    {
+                        void* tmp;
+                        (void)memmove(elements, src, srcEnd - src);
+                        tmp = realloc(handle->storage, (handle->elementSize * handle->count));
+                        if (tmp == NULL)
+                        {
+                            LogInfo("realloc failed. Keeping original internal storage pointer.");
+                        }
+                        else
+                        {
+                            handle->storage = tmp;
+                        }
+                    }
+                }
+            }
+        }
+    }
+}
+
+IMPLEMENT_MOCKABLE_FUNCTION(, void, VECTOR_clear, VECTOR_HANDLE, handle)
+{
+    /* Codes_SRS_VECTOR_10_017: [VECTOR_clear shall if the object is NULL or empty.] */
+    if (handle == NULL)
+    {
+        LogError("invalid argument handle(NULL).");
+    }
+    else
+    {
+        /* Codes_SRS_VECTOR_10_016: [VECTOR_clear shall remove all elements from the object and release internal storage.] */
+        free(handle->storage);
+        handle->storage = NULL;
+        handle->count = 0;
+    }
+}
+
+/* access */
+
+IMPLEMENT_MOCKABLE_FUNCTION(, void*, VECTOR_element, VECTOR_HANDLE, handle, size_t, index)
+{
+    void* result;
+    if (handle == NULL)
+    {
+        /* Codes_SRS_VECTOR_10_019: [VECTOR_element shall fail and return NULL if handle is NULL.] */
+        LogError("invalid argument handle(NULL).");
+        result = NULL;
+    }
+    else
+    {
+        if (index >= handle->count)
+        {
+            /* Codes_SRS_VECTOR_10_020: [VECTOR_element shall fail and return NULL if the given index is out of range.] */
+            LogError("invalid argument - index(%zd); should be >= 0 and < %zd.", index, handle->count);
+            result = NULL;
+        }
+        else
+        {
+            /* Codes_SRS_VECTOR_10_018: [VECTOR_element shall return the element at the given index.] */
+            result = (unsigned char*)handle->storage + (handle->elementSize * index);
+        }
+    }
+    return result;
+}
+
+IMPLEMENT_MOCKABLE_FUNCTION(, void*, VECTOR_front, VECTOR_HANDLE, handle)
+{
+    void* result;
+    if (handle == NULL)
+    {
+        /* Codes_SRS_VECTOR_10_022: [VECTOR_front shall fail and return NULL if handle is NULL.] */
+        LogError("invalid argument handle (NULL).");
+        result = NULL;
+    }
+    else
+    {
+        if (handle->count == 0)
+        {
+            /* Codes_SRS_VECTOR_10_028: [VECTOR_front shall return NULL if the vector is empty.] */
+            LogError("vector is empty.");
+            result = NULL;
+        }
+        else
+        {
+            /* Codes_SRS_VECTOR_10_021: [VECTOR_front shall return a pointer to the element at index 0.] */
+            result = handle->storage;
+        }
+    }
+    return result;
+}
+
+IMPLEMENT_MOCKABLE_FUNCTION(, void*, VECTOR_back, VECTOR_HANDLE, handle)
+{
+    void* result;
+    if (handle == NULL)
+    {
+        /* Codes_SRS_VECTOR_10_024: [VECTOR_back shall fail and return NULL if handle is NULL.] */
+        LogError("invalid argument handle (NULL).");
+        result = NULL;
+    }
+    else
+    {
+        if (handle->count == 0)
+        {
+            /* Codes_SRS_VECTOR_10_029: [VECTOR_back shall return NULL if the vector is empty.] */
+            LogError("vector is empty.");
+            result = NULL;
+        }
+        else
+        {
+            /* Codes_SRS_VECTOR_10_023: [VECTOR_front shall return the last element of the vector.] */
+            result = (unsigned char*)handle->storage + (handle->elementSize * (handle->count - 1));
+        }
+    }
+    return result;
+}
+
+IMPLEMENT_MOCKABLE_FUNCTION(, void*, VECTOR_find_if, VECTOR_HANDLE, handle, PREDICATE_FUNCTION, pred, const void*, value)
+{
+    void* result;
+    if (handle == NULL || pred == NULL)
+    {
+        /* Codes_SRS_VECTOR_10_030: [VECTOR_find_if shall fail and return NULL if handle is NULL.] */
+        /* Codes_SRS_VECTOR_10_036: [VECTOR_find_if shall fail and return NULL if pred is NULL.] */
+        LogError("invalid argument - handle(%p), pred(%p)", handle, pred);
+        result = NULL;
+    }
+    else
+    {
+        size_t i;
+        for (i = 0; i < handle->count; ++i)
+        {
+            if (true == pred((unsigned char*)handle->storage + (handle->elementSize * i), value))
+            {
+                /* Codes_SRS_VECTOR_10_031: [VECTOR_find_if shall return the first element in the vector that matches pred.] */
+                break;
+            }
+        }
+
+        if (i == handle->count)
+        {
+            /* Codes_SRS_VECTOR_10_032: [VECTOR_find_if shall return NULL if no matching element is found.] */
+            result = NULL;
+        }
+        else
+        {
+            /* Codes_SRS_VECTOR_10_031: [VECTOR_find_if shall return the first element in the vector that matches pred.]*/
+            result = (unsigned char*)handle->storage + (handle->elementSize * i);
+        }
+    }
+    return result;
+}
+
+/* capacity */
+
+IMPLEMENT_MOCKABLE_FUNCTION(, size_t, VECTOR_size, VECTOR_HANDLE, handle)
+{
+    size_t result;
+    if (handle == NULL)
+    {
+        /* Codes_SRS_VECTOR_10_026: [**VECTOR_size shall return 0 if the given handle is NULL.] */
+        LogError("invalid argument handle(NULL).");
+        result = 0;
+    }
+    else
+    {
+        /* Codes_SRS_VECTOR_10_025: [VECTOR_size shall return the number of elements stored with the given handle.] */
+        result = handle->count;
+    }
+    return result;
+}
Index: azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/src/wsio.c
===================================================================
--- azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/src/wsio.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/src/wsio.c	(revision 457)
@@ -0,0 +1,825 @@
+ // Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdbool.h>
+#include <stdint.h>
+#include "azure_c_shared_utility/gballoc.h"
+#include "azure_c_shared_utility/wsio.h"
+#include "azure_c_shared_utility/xlogging.h"
+#include "azure_c_shared_utility/singlylinkedlist.h"
+#include "azure_c_shared_utility/optionhandler.h"
+#include "azure_c_shared_utility/xio.h"
+#include "azure_c_shared_utility/shared_util_options.h"
+#include "azure_c_shared_utility/crt_abstractions.h"
+#include "azure_c_shared_utility/uws_client.h"
+#include "azure_c_shared_utility/optimize_size.h"
+
+static const char* WSIO_OPTIONS = "WSIOOptions";
+
+typedef enum IO_STATE_TAG
+{
+    IO_STATE_NOT_OPEN,
+    IO_STATE_OPENING,
+    IO_STATE_OPEN,
+    IO_STATE_CLOSING,
+    IO_STATE_ERROR
+} IO_STATE;
+
+typedef struct PENDING_IO_TAG
+{
+    ON_SEND_COMPLETE on_send_complete;
+    void* callback_context;
+    void* wsio;
+} PENDING_IO;
+
+typedef struct WSIO_INSTANCE_TAG
+{
+    ON_BYTES_RECEIVED on_bytes_received;
+    void* on_bytes_received_context;
+    ON_IO_OPEN_COMPLETE on_io_open_complete;
+    void* on_io_open_complete_context;
+    ON_IO_ERROR on_io_error;
+    void* on_io_error_context;
+    ON_IO_CLOSE_COMPLETE on_io_close_complete;
+    void* on_io_close_complete_context;
+    IO_STATE io_state;
+    SINGLYLINKEDLIST_HANDLE pending_io_list;
+    UWS_CLIENT_HANDLE uws;
+} WSIO_INSTANCE;
+
+static void indicate_error(WSIO_INSTANCE* wsio_instance)
+{
+    wsio_instance->io_state = IO_STATE_ERROR;
+    wsio_instance->on_io_error(wsio_instance->on_io_error_context);
+}
+
+static void indicate_open_complete(WSIO_INSTANCE* ws_io_instance, IO_OPEN_RESULT open_result)
+{
+    ws_io_instance->on_io_open_complete(ws_io_instance->on_io_open_complete_context, open_result);
+}
+
+static void complete_send_item(LIST_ITEM_HANDLE pending_io_list_item, IO_SEND_RESULT io_send_result)
+{
+    PENDING_IO* pending_io = (PENDING_IO*)singlylinkedlist_item_get_value(pending_io_list_item);
+    WSIO_INSTANCE* wsio_instance = (WSIO_INSTANCE*)pending_io->wsio;
+
+    /* Codes_SRS_WSIO_01_145: [ Removing it from the list shall be done by calling singlylinkedlist_remove. ]*/
+    if (singlylinkedlist_remove(wsio_instance->pending_io_list, pending_io_list_item) != 0)
+    {
+        LogError("Failed removing pending IO from linked list.");
+    }
+
+    /* Codes_SRS_WSIO_01_105: [ The argument on_send_complete shall be optional, if NULL is passed by the caller then no send complete callback shall be triggered. ]*/
+    if (pending_io->on_send_complete != NULL)
+    {
+        pending_io->on_send_complete(pending_io->callback_context, io_send_result);
+    }
+
+    /* Codes_SRS_WSIO_01_144: [ Also the pending IO data shall be freed. ]*/
+    free(pending_io);
+}
+
+static void on_underlying_ws_send_frame_complete(void* context, WS_SEND_FRAME_RESULT ws_send_frame_result)
+{
+    if (context == NULL)
+    {
+        LogError("NULL context for on_underlying_ws_send_frame_complete");
+    }
+    else
+    {
+        IO_SEND_RESULT io_send_result;
+        LIST_ITEM_HANDLE list_item_handle = (LIST_ITEM_HANDLE)context;
+
+        /* Codes_SRS_WSIO_01_143: [ When on_underlying_ws_send_frame_complete is called after sending a WebSocket frame, the pending IO shall be removed from the list. ]*/
+        switch (ws_send_frame_result)
+        {
+        default:
+            /* Codes_SRS_WSIO_01_148: [ When on_underlying_ws_send_frame_complete is called with any other error code, the callback on_send_complete shall be called with IO_SEND_ERROR. ]*/
+            LogError("Frame send error with result %d", (int)ws_send_frame_result);
+            io_send_result = IO_SEND_ERROR;
+            break;
+
+        case WS_SEND_FRAME_OK:
+            /* Codes_SRS_WSIO_01_146: [ When on_underlying_ws_send_frame_complete is called with WS_SEND_OK, the callback on_send_complete shall be called with IO_SEND_OK. ]*/
+            io_send_result = IO_SEND_OK;
+            break;
+
+        case WS_SEND_FRAME_CANCELLED:
+            /* Codes_SRS_WSIO_01_147: [ When on_underlying_ws_send_frame_complete is called with WS_SEND_CANCELLED, the callback on_send_complete shall be called with IO_SEND_CANCELLED. ]*/
+            io_send_result = IO_SEND_CANCELLED;
+            break;
+        }
+
+        complete_send_item(list_item_handle, io_send_result);
+    }
+}
+
+static void on_underlying_ws_close_complete(void* context)
+{
+    WSIO_INSTANCE* wsio_instance = (WSIO_INSTANCE*)context;
+    if (wsio_instance == NULL)
+    {
+        /* Codes_SRS_WSIO_01_161: [ If the context passed to on_underlying_ws_close_complete is NULL, on_underlying_ws_close_complete shall do nothing. ]*/
+        LogError("NULL context passed to on_underlying_ws_close_complete");
+    }
+    else
+    {
+        wsio_instance->io_state = IO_STATE_NOT_OPEN;
+
+        /* Codes_SRS_WSIO_01_160: [ If NULL was passed to wsio_close no callback shall be called. ]*/
+        if (wsio_instance->on_io_close_complete != NULL)
+        {
+            /* Codes_SRS_WSIO_01_159: [ When on_underlying_ws_close_complete while the IO is closing (after wsio_close), the close shall be indicated up by calling the on_io_close_complete callback passed to wsio_close. ]*/
+            /* Codes_SRS_WSIO_01_163: [ When on_io_close_complete is called, the context passed to wsio_close shall be passed as argument to on_io_close_complete. ]*/
+            wsio_instance->on_io_close_complete(wsio_instance->on_io_close_complete_context);
+        }
+    }
+}
+
+static int internal_close(WSIO_INSTANCE* wsio_instance, ON_IO_CLOSE_COMPLETE on_io_close_complete, void* on_io_close_complete_context)
+{
+    int result;
+
+    /* Codes_SRS_WSIO_01_089: [ wsio_close after a wsio_close shall fail and return a non-zero value.  ]*/
+    /* Codes_SRS_WSIO_01_088: [ wsio_close when no open action has been issued shall fail and return a non-zero value. ]*/
+    if (wsio_instance->io_state == IO_STATE_NOT_OPEN)
+    {
+        LogError("wsio_close when not open.");
+        result = MU_FAILURE;
+    }
+    else
+    {
+        if (wsio_instance->io_state == IO_STATE_OPENING)
+        {
+            wsio_instance->io_state = IO_STATE_NOT_OPEN;
+            indicate_open_complete(wsio_instance, IO_OPEN_CANCELLED);
+            result = 0;
+        }
+        else if (wsio_instance->io_state == IO_STATE_CLOSING)
+        {
+            LogError("Already closing");
+            result = MU_FAILURE;
+        }
+        else
+        {
+            LIST_ITEM_HANDLE first_pending_io;
+
+            wsio_instance->io_state = IO_STATE_CLOSING;
+
+            wsio_instance->on_io_close_complete = on_io_close_complete;
+            wsio_instance->on_io_close_complete_context = on_io_close_complete_context;
+
+            /* Codes_SRS_WSIO_01_087: [ wsio_close shall call uws_client_close_async while passing as argument the IO handle created in wsio_create.  ]*/
+            if (uws_client_close_async(wsio_instance->uws, on_underlying_ws_close_complete, wsio_instance) != 0)
+            {
+                /* Codes_SRS_WSIO_01_164: [ When uws_client_close_async fails, wsio_close shall call the on_io_close_complete callback and continue. ] */
+                if (wsio_instance->on_io_close_complete != NULL)
+                {
+                    wsio_instance->on_io_close_complete(wsio_instance->on_io_close_complete_context);
+                }
+            }
+
+            /* Codes_SRS_WSIO_01_085: [ wsio_close shall close the websockets IO if an open action is either pending or has completed successfully (if the IO is open).  ]*/
+            /* Codes_SRS_WSIO_01_091: [ wsio_close shall obtain all the pending IO items by repetitively querying for the head of the pending IO list and freeing that head item. ]*/
+            /* Codes_SRS_WSIO_01_092: [ Obtaining the head of the pending IO list shall be done by calling singlylinkedlist_get_head_item. ]*/
+            while ((first_pending_io = singlylinkedlist_get_head_item(wsio_instance->pending_io_list)) != NULL)
+            {
+                complete_send_item(first_pending_io, IO_SEND_CANCELLED);
+            }
+
+            /* Codes_SRS_WSIO_01_133: [ On success wsio_close shall return 0. ]*/
+            result = 0;
+            wsio_instance->io_state = IO_STATE_NOT_OPEN;
+        }
+    }
+    return result;
+}
+
+CONCRETE_IO_HANDLE wsio_create(void* io_create_parameters)
+{
+    /* Codes_SRS_WSIO_01_066: [ io_create_parameters shall be used as a WSIO_CONFIG* . ]*/
+    WSIO_CONFIG* ws_io_config = (WSIO_CONFIG*)io_create_parameters;
+    WSIO_INSTANCE* result;
+
+    /* Codes_SRS_WSIO_01_065: [ If the argument io_create_parameters is NULL then wsio_create shall return NULL. ]*/
+    if ((ws_io_config == NULL) ||
+        /* Codes_SRS_WSIO_01_067: [ If any of the members hostname, resource_name or protocol is NULL in WSIO_CONFIG then wsio_create shall return NULL. ]*/
+        (ws_io_config->hostname == NULL) ||
+        (ws_io_config->resource_name == NULL) ||
+        (ws_io_config->protocol == NULL))
+    {
+        LogError("NULL io_create_parameters.");
+        result = NULL;
+    }
+    else
+    {
+        /* Codes_SRS_WSIO_01_001: [wsio_create shall create an instance of wsio and return a non-NULL handle to it.] */
+        result = (WSIO_INSTANCE*)calloc(1, sizeof(WSIO_INSTANCE));
+        if (result == NULL)
+        {
+            /* Codes_SRS_WSIO_01_068: [ If allocating memory for the new wsio instance fails then wsio_create shall return NULL. ]*/
+            LogError("Cannot allocate memory for the new WSIO instance.");
+        }
+        else
+        {
+            WS_PROTOCOL protocols;
+
+            protocols.protocol = ws_io_config->protocol;
+
+            result->on_bytes_received = NULL;
+            result->on_bytes_received_context = NULL;
+            result->on_io_open_complete = NULL;
+            result->on_io_open_complete_context = NULL;
+            result->on_io_error = NULL;
+            result->on_io_error_context = NULL;
+            result->on_io_close_complete = NULL;
+            result->on_io_close_complete_context = NULL;
+
+            /* Codes_SRS_WSIO_01_070: [ The underlying uws instance shall be created by calling uws_client_create_with_io. ]*/
+            /* Codes_SRS_WSIO_01_071: [ The arguments for uws_client_create_with_io shall be: ]*/
+            /* Codes_SRS_WSIO_01_185: [ - underlying_io_interface shall be set to the underlying_io_interface field in the io_create_parameters passed to wsio_create. ]*/
+            /* Codes_SRS_WSIO_01_186: [ - underlying_io_parameters shall be set to the underlying_io_parameters field in the io_create_parameters passed to wsio_create. ]*/
+            /* Codes_SRS_WSIO_01_072: [ - hostname set to the hostname field in the io_create_parameters passed to wsio_create. ]*/
+            /* Codes_SRS_WSIO_01_130: [ - port set to the port field in the io_create_parameters passed to wsio_create. ]*/
+            /* Codes_SRS_WSIO_01_128: [ - resource_name set to the resource_name field in the io_create_parameters passed to wsio_create. ]*/
+            /* Codes_SRS_WSIO_01_129: [ - protocols shall be filled with only one structure, that shall have the protocol set to the value of the protocol field in the io_create_parameters passed to wsio_create. ]*/
+            result->uws = uws_client_create_with_io(ws_io_config->underlying_io_interface, ws_io_config->underlying_io_parameters, ws_io_config->hostname, ws_io_config->port, ws_io_config->resource_name, &protocols, 1);
+            if (result->uws == NULL)
+            {
+                /* Codes_SRS_WSIO_01_075: [ If uws_client_create_with_io fails, then wsio_create shall fail and return NULL. ]*/
+                LogError("Cannot create uws instance.");
+                free(result);
+                result = NULL;
+            }
+            else
+            {
+                /* Codes_SRS_WSIO_01_076: [ wsio_create shall create a pending send IO list that is to be used to queue send packets by calling singlylinkedlist_create. ]*/
+                result->pending_io_list = singlylinkedlist_create();
+                if (result->pending_io_list == NULL)
+                {
+                    /* Codes_SRS_WSIO_01_077: [ If singlylinkedlist_create fails then wsio_create shall fail and return NULL. ]*/
+                    LogError("Cannot create singly linked list.");
+                    uws_client_destroy(result->uws);
+                    free(result);
+                    result = NULL;
+                }
+                else
+                {
+                    result->io_state = IO_STATE_NOT_OPEN;
+                }
+            }
+        }
+    }
+
+    return result;
+}
+
+void wsio_destroy(CONCRETE_IO_HANDLE ws_io)
+{
+    /* Codes_SRS_WSIO_01_079: [ If ws_io is NULL, wsio_destroy shall do nothing.  ]*/
+    if (ws_io == NULL)
+    {
+        LogError("NULL handle");
+    }
+    else
+    {
+        WSIO_INSTANCE* wsio_instance = (WSIO_INSTANCE*)ws_io;
+
+        if (wsio_instance->io_state != IO_STATE_NOT_OPEN)
+        {
+            internal_close(wsio_instance, NULL, NULL);
+        }
+
+        /* Codes_SRS_WSIO_01_078: [ wsio_destroy shall free all resources associated with the wsio instance. ]*/
+        /* Codes_SRS_WSIO_01_080: [ wsio_destroy shall destroy the uws instance created in wsio_create by calling uws_client_destroy. ]*/
+        uws_client_destroy(wsio_instance->uws);
+        /* Codes_SRS_WSIO_01_081: [ wsio_destroy shall free the list used to track the pending send IOs by calling singlylinkedlist_destroy. ]*/
+        singlylinkedlist_destroy(wsio_instance->pending_io_list);
+        free(ws_io);
+    }
+}
+
+static void on_underlying_ws_open_complete(void* context, WS_OPEN_RESULT open_result)
+{
+    if (context == NULL)
+    {
+        /* Codes_SRS_WSIO_01_138: [ When on_underlying_ws_open_complete is called with a NULL context, it shall do nothing. ]*/
+        LogError("NULL context in on_underlying_ws_open_complete");
+    }
+    else
+    {
+        WSIO_INSTANCE* wsio_instance = (WSIO_INSTANCE*)context;
+
+        switch (wsio_instance->io_state)
+        {
+        default:
+        /* Codes_SRS_WSIO_01_142: [ When on_underlying_ws_open_complete is called while in the CLOSING state an error shall be indicated by calling the on_io_error callback passed to wsio_open. ]*/
+        case IO_STATE_CLOSING:
+        /* Codes_SRS_WSIO_01_141: [ When on_underlying_ws_open_complete is called while in the ERROR state it shall indicate an error by calling the on_io_error callback passed to wsio_open. ]*/
+        case IO_STATE_ERROR:
+        /* Codes_SRS_WSIO_01_139: [ When on_underlying_ws_open_complete is called while in OPEN state it shall indicate an error by calling the on_io_error callback passed to wsio_open and switch to the ERROR state. ]*/
+        case IO_STATE_OPEN:
+            /* Codes_SRS_WSIO_01_140: [ When calling on_io_error, the on_io_error_context argument given in wsio_open shall be passed to the callback on_io_error. ]*/
+            indicate_error(wsio_instance);
+            break;
+
+        case IO_STATE_OPENING:
+            wsio_instance->io_state = IO_STATE_OPEN;
+
+            switch (open_result)
+            {
+            default:
+                /* Codes_SRS_WSIO_01_137: [ When on_underlying_ws_open_complete is called with any other error code while the IO is opening, the callback on_io_open_complete shall be called with IO_OPEN_ERROR. ]*/
+                wsio_instance->io_state = IO_STATE_NOT_OPEN;
+                indicate_open_complete(wsio_instance, IO_OPEN_ERROR);
+                break;
+
+            case WS_OPEN_CANCELLED:
+                /* Codes_SRS_WSIO_01_149: [ When on_underlying_ws_open_complete is called with WS_OPEN_CANCELLED while the IO is opening, the callback on_io_open_complete shall be called with IO_OPEN_CANCELLED. ]*/
+                wsio_instance->io_state = IO_STATE_NOT_OPEN;
+                indicate_open_complete(wsio_instance, IO_OPEN_CANCELLED);
+                break;
+
+            case WS_OPEN_OK:
+                /* Codes_SRS_WSIO_01_136: [ When on_underlying_ws_open_complete is called with WS_OPEN_OK while the IO is opening, the callback on_io_open_complete shall be called with IO_OPEN_OK. ]*/
+                wsio_instance->io_state = IO_STATE_OPEN;
+                indicate_open_complete(wsio_instance, IO_OPEN_OK);
+                break;
+            }
+
+            break;
+        }
+    }
+}
+
+static void on_underlying_ws_frame_received(void* context, unsigned char frame_type, const unsigned char* buffer, size_t size)
+{
+    if (context == NULL)
+    {
+        /* Codes_SRS_WSIO_01_150: [ If on_underlying_ws_frame_received is called with NULL context it shall do nothing. ]*/
+        LogError("NULL context for on_underlying_ws_frame_received");
+    }
+    else
+    {
+        WSIO_INSTANCE* wsio_instance = (WSIO_INSTANCE*)context;
+
+        if (wsio_instance->io_state != IO_STATE_OPEN)
+        {
+            /* Codes_SRS_WSIO_01_126: [ If on_underlying_ws_frame_received is called while the IO is in any state other than OPEN, it shall do nothing. ]*/
+            LogError("on_underlying_ws_frame_received called in a bad state.");
+        }
+        else
+        {
+            if (frame_type != WS_FRAME_TYPE_BINARY)
+            {
+                /* Codes_SRS_WSIO_01_151: [ If the WebSocket frame type is not binary then an error shall be indicated by calling the on_io_error callback passed to wsio_open. ]*/
+                LogError("Invalid non binary WebSocket frame received.");
+                /* Codes_SRS_WSIO_01_152: [ When calling on_io_error, the on_io_error_context argument given in wsio_open shall be passed to the callback on_io_error. ]*/
+                indicate_error(wsio_instance);
+            }
+            else
+            {
+                /* Codes_SRS_WSIO_01_153: [ When on_underlying_ws_frame_received is called with zero size, no bytes shall be indicated up as received. ]*/
+                if (size > 0)
+                {
+                    if (buffer == NULL)
+                    {
+                        /* Codes_SRS_WSIO_01_154: [ When on_underlying_ws_frame_received is called with a positive size and a NULL buffer, an error shall be indicated by calling the on_io_error callback passed to wsio_open. ]*/
+                        LogError("NULL buffer received for Websocket frame with positive payload length.");
+                        indicate_error(wsio_instance);
+                    }
+                    else
+                    {
+                        /* Codes_SRS_WSIO_01_124: [ When on_underlying_ws_frame_received is called the bytes in the frame shall be indicated by calling the on_bytes_received callback passed to wsio_open. ]*/
+                        /* Codes_SRS_WSIO_01_125: [ When calling on_bytes_received, the on_bytes_received_context argument given in wsio_open shall be passed to the callback on_bytes_received. ]*/
+                        wsio_instance->on_bytes_received(wsio_instance->on_bytes_received_context, buffer, size);
+                    }
+                }
+            }
+        }
+    }
+}
+
+static void on_underlying_ws_peer_closed(void* context, uint16_t* close_code, const unsigned char* extra_data, size_t extra_data_length)
+{
+    /* Codes_SRS_WSIO_01_168: [ The close_code, extra_data and extra_data_length arguments shall be ignored. ]*/
+    (void)close_code;
+    (void)extra_data;
+    (void)extra_data_length;
+
+    if (context == NULL)
+    {
+        /* Codes_SRS_WSIO_01_167: [ If on_underlying_ws_peer_closed is called with a NULL context it shall do nothing. ]*/
+        LogError("NULL context for on_underlying_ws_peer_closed");
+    }
+    else
+    {
+        WSIO_INSTANCE* wsio_instance = (WSIO_INSTANCE*)context;
+
+        switch (wsio_instance->io_state)
+        {
+        default:
+            /* Codes_SRS_WSIO_01_166: [ When on_underlying_ws_peer_closed and the state of the IO is OPEN an error shall be indicated by calling the on_io_error callback passed to wsio_open. ]*/
+        case IO_STATE_OPEN:
+            /* Codes_SRS_WSIO_01_169: [ When on_underlying_ws_peer_closed and the state of the IO is CLOSING an error shall be indicated by calling the on_io_error callback passed to wsio_open. ]*/
+        case IO_STATE_CLOSING:
+            indicate_error(wsio_instance);
+            break;
+
+        case IO_STATE_NOT_OPEN:
+            // Codes_SRS_WSIO_07_001: [When on_underlying_ws_peer_closed and the state of the IO is NOT_OPEN an error will be raised and the io_state will remain as NOT_OPEN]
+            indicate_error(wsio_instance);
+            wsio_instance->io_state = IO_STATE_NOT_OPEN;
+            break;
+
+        case IO_STATE_OPENING:
+            /* Codes_SRS_WSIO_01_170: [ When on_underlying_ws_peer_closed and the state of the IO is OPENING an error shall be indicated by calling the on_io_open_complete callback passed to wsio_open with the error code IO_OPEN_ERROR. ]*/
+            wsio_instance->io_state = IO_STATE_NOT_OPEN;
+            indicate_open_complete(wsio_instance, IO_OPEN_ERROR);
+            break;
+        }
+    }
+}
+
+static void on_underlying_ws_error(void* context, WS_ERROR ws_error)
+{
+    (void)ws_error;
+    /* Don't have much to do with the error here */
+    LogError("on_underlying_ws_error called with error code %d", (int)ws_error);
+
+    if (context == NULL)
+    {
+        /* Codes_SRS_WSIO_01_135: [ When on_underlying_ws_error is called with a NULL context, it shall do nothing. ]*/
+        LogError("NULL context in on_underlying_ws_error");
+    }
+    else
+    {
+        WSIO_INSTANCE* wsio_instance = (WSIO_INSTANCE*)context;
+
+        if (wsio_instance->io_state == IO_STATE_OPENING)
+        {
+            /* Codes_SRS_WSIO_01_123: [ When calling on_io_error, the on_io_error_context argument given in wsio_open shall be passed to the callback on_io_error. ]*/
+            wsio_instance->on_io_open_complete(wsio_instance->on_io_open_complete_context, IO_OPEN_ERROR);
+            wsio_instance->io_state = IO_STATE_NOT_OPEN;
+        }
+        else
+        {
+            /* Codes_SRS_WSIO_01_123: [ When calling on_io_error, the on_io_error_context argument given in wsio_open shall be passed to the callback on_io_error. ]*/
+            wsio_instance->on_io_error(wsio_instance->on_io_error_context);
+        }
+    }
+}
+
+int wsio_open(CONCRETE_IO_HANDLE ws_io, ON_IO_OPEN_COMPLETE on_io_open_complete, void* on_io_open_complete_context, ON_BYTES_RECEIVED on_bytes_received, void* on_bytes_received_context, ON_IO_ERROR on_io_error, void* on_io_error_context)
+{
+    int result = 0;
+
+    if ((ws_io == NULL) ||
+        (on_io_open_complete == NULL) ||
+        (on_bytes_received == NULL) ||
+        (on_io_error == NULL))
+    {
+        /* Codes_SRS_WSIO_01_132: [ If any of the arguments ws_io, on_io_open_complete, on_bytes_received, on_io_error is NULL, wsio_open shall fail and return a non-zero value. ]*/
+        LogError("Bad arguments: ws_io=%p, on_io_open_complete=%p, on_bytes_received=%p, on_io_error=%p",
+            ws_io, on_io_open_complete, on_bytes_received, on_io_error);
+        result = MU_FAILURE;
+    }
+    else
+    {
+        WSIO_INSTANCE* wsio_instance = (WSIO_INSTANCE*)ws_io;
+
+        if (wsio_instance->io_state != IO_STATE_NOT_OPEN)
+        {
+            /* Codes_SRS_WSIO_01_165: [ wsio_open when CLOSING shall fail and return a non-zero value. ]*/
+            /* Codes_SRS_WSIO_01_131: [ wsio_open when already OPEN or OPENING shall fail and return a non-zero value. ]*/
+            LogError("wsio has already been opened current state: %d", wsio_instance->io_state);
+            result = MU_FAILURE;
+        }
+        else
+        {
+            wsio_instance->on_bytes_received = on_bytes_received;
+            wsio_instance->on_bytes_received_context = on_bytes_received_context;
+            wsio_instance->on_io_open_complete = on_io_open_complete;
+            wsio_instance->on_io_open_complete_context = on_io_open_complete_context;
+            wsio_instance->on_io_error = on_io_error;
+            wsio_instance->on_io_error_context = on_io_error_context;
+
+            wsio_instance->io_state = IO_STATE_OPENING;
+
+            /* Codes_SRS_WSIO_01_082: [ wsio_open shall open the underlying uws instance by calling uws_client_open_async and providing the uws handle created in wsio_create as argument. ] */
+            if (uws_client_open_async(wsio_instance->uws, on_underlying_ws_open_complete, wsio_instance, on_underlying_ws_frame_received, wsio_instance, on_underlying_ws_peer_closed, wsio_instance, on_underlying_ws_error, wsio_instance) != 0)
+            {
+                /* Codes_SRS_WSIO_01_084: [ If opening the underlying uws instance fails then wsio_open shall fail and return a non-zero value. ]*/
+                LogError("Opening the uws instance failed.");
+                wsio_instance->io_state = IO_STATE_NOT_OPEN;
+                result = MU_FAILURE;
+            }
+            else
+            {
+                /* Codes_SRS_WSIO_01_083: [ On success, wsio_open shall return 0. ]*/
+                result = 0;
+            }
+        }
+    }
+
+    return result;
+}
+
+int wsio_close(CONCRETE_IO_HANDLE ws_io, ON_IO_CLOSE_COMPLETE on_io_close_complete, void* on_io_close_complete_context)
+{
+    int result = 0;
+
+    if (ws_io == NULL)
+    {
+        /* Codes_SRS_WSIO_01_086: [ if ws_io is NULL, wsio_close shall return a non-zero value.  ]*/
+        LogError("NULL handle");
+        result = MU_FAILURE;
+    }
+    else
+    {
+        WSIO_INSTANCE* wsio_instance = (WSIO_INSTANCE*)ws_io;
+
+        if (internal_close(wsio_instance, on_io_close_complete, on_io_close_complete_context) != 0)
+        {
+            result = MU_FAILURE;
+        }
+        else
+        {
+            result = 0;
+        }
+    }
+
+    return result;
+}
+
+int wsio_send(CONCRETE_IO_HANDLE ws_io, const void* buffer, size_t size, ON_SEND_COMPLETE on_send_complete, void* callback_context)
+{
+    int result;
+
+    /* Codes_SRS_WSIO_01_100: [ If any of the arguments ws_io or buffer are NULL, wsio_send shall fail and return a non-zero value. ]*/
+    if ((ws_io == NULL) ||
+        (buffer == NULL) ||
+        /* Codes_SRS_WSIO_01_101: [ If size is zero then wsio_send shall fail and return a non-zero value. ]*/
+        (size == 0))
+    {
+        LogError("Bad arguments: ws_io=%p, buffer=%p, size=%u",
+            ws_io, buffer, (unsigned int)size);
+        result = MU_FAILURE;
+    }
+    else
+    {
+        WSIO_INSTANCE* wsio_instance = (WSIO_INSTANCE*)ws_io;
+
+        if (wsio_instance->io_state != IO_STATE_OPEN)
+        {
+            /* Codes_SRS_WSIO_01_099: [ If the wsio is not OPEN (open has not been called or is still in progress) then wsio_send shall fail and return a non-zero value. ]*/
+            LogError("Attempting to send when not open");
+            result = MU_FAILURE;
+        }
+        else
+        {
+            LIST_ITEM_HANDLE new_item;
+            PENDING_IO* pending_socket_io = (PENDING_IO*)malloc(sizeof(PENDING_IO));
+            if (pending_socket_io == NULL)
+            {
+                /* Codes_SRS_WSIO_01_134: [ If allocating memory for the pending IO data fails, wsio_send shall fail and return a non-zero value. ]*/
+                result = MU_FAILURE;
+            }
+            else
+            {
+                /* Codes_SRS_WSIO_01_103: [ The entry shall contain the on_send_complete callback and its context. ]*/
+                pending_socket_io->on_send_complete = on_send_complete;
+                pending_socket_io->callback_context = callback_context;
+                pending_socket_io->wsio = wsio_instance;
+
+                /* Codes_SRS_WSIO_01_102: [ An entry shall be queued in the singly linked list by calling singlylinkedlist_add. ]*/
+                if ((new_item = singlylinkedlist_add(wsio_instance->pending_io_list, pending_socket_io)) == NULL)
+                {
+                    /* Codes_SRS_WSIO_01_104: [ If singlylinkedlist_add fails, wsio_send shall fail and return a non-zero value. ]*/
+                    free(pending_socket_io);
+                    result = MU_FAILURE;
+                }
+                else
+                {
+                    /* Codes_SRS_WSIO_01_095: [ wsio_send shall call uws_client_send_frame_async, passing the buffer and size arguments as they are: ]*/
+                    /* Codes_SRS_WSIO_01_097: [ The is_final argument shall be set to true. ]*/
+                    /* Codes_SRS_WSIO_01_096: [ The frame type used shall be WS_FRAME_TYPE_BINARY. ]*/
+                    if (uws_client_send_frame_async(wsio_instance->uws, WS_FRAME_TYPE_BINARY, (const unsigned char*)buffer, size, true, on_underlying_ws_send_frame_complete, new_item) != 0)
+                    {
+                        if (singlylinkedlist_remove(wsio_instance->pending_io_list, new_item) != 0)
+                        {
+                            LogError("Failed removing pending IO from linked list.");
+                        }
+
+                        free(pending_socket_io);
+                        result = MU_FAILURE;
+                    }
+                    else
+                    {
+                        /* Codes_SRS_WSIO_01_098: [ On success, wsio_send shall return 0. ]*/
+                        result = 0;
+                    }
+                }
+            }
+        }
+    }
+
+    return result;
+}
+
+void wsio_dowork(CONCRETE_IO_HANDLE ws_io)
+{
+    if (ws_io == NULL)
+    {
+        /* Codes_SRS_WSIO_01_107: [ If the ws_io argument is NULL, wsio_dowork shall do nothing. ]*/
+        LogError("NULL handle");
+    }
+    else
+    {
+        WSIO_INSTANCE* wsio_instance = (WSIO_INSTANCE*)ws_io;
+
+        /* Codes_SRS_WSIO_01_108: [ If the IO is not yet open, wsio_dowork shall do nothing. ]*/
+        if (wsio_instance->io_state != IO_STATE_NOT_OPEN)
+        {
+            /* Codes_SRS_WSIO_01_106: [ wsio_dowork shall call uws_client_dowork with the uws handle created in wsio_create. ]*/
+            uws_client_dowork(wsio_instance->uws);
+        }
+    }
+}
+
+int wsio_setoption(CONCRETE_IO_HANDLE ws_io, const char* optionName, const void* value)
+{
+    int result;
+    if (
+        /* Codes_SRS_WSIO_01_109: [ If any of the arguments ws_io or option_name is NULL wsio_setoption shall return a non-zero value. ]*/
+        (ws_io == NULL) ||
+        (optionName == NULL)
+        )
+    {
+        LogError("Bad parameters: ws_io=%p, optionName=%p",
+            ws_io, optionName);
+        result = MU_FAILURE;
+    }
+    else
+    {
+        WSIO_INSTANCE* wsio_instance = (WSIO_INSTANCE*)ws_io;
+
+        if (strcmp(WSIO_OPTIONS, optionName) == 0)
+        {
+            /* Codes_SRS_WSIO_01_183: [ If the option name is WSIOOptions then wsio_setoption shall call OptionHandler_FeedOptions and pass to it the underlying IO handle and the value argument. ]*/
+            if (OptionHandler_FeedOptions((OPTIONHANDLER_HANDLE)value, wsio_instance->uws) != OPTIONHANDLER_OK)
+            {
+                /* Codes_SRS_WSIO_01_184: [ If OptionHandler_FeedOptions fails, wsio_setoption shall fail and return a non-zero value. ]*/
+                LogError("unable to OptionHandler_FeedOptions");
+                result = MU_FAILURE;
+            }
+            else
+            {
+                /* Codes_SRS_WSIO_01_158: [ On success, wsio_setoption shall return 0. ]*/
+                result = 0;
+            }
+        }
+        else
+        {
+            /* Codes_SRS_WSIO_01_156: [ Otherwise all options shall be passed as they are to uws by calling uws_client_set_option. ]*/
+            if (uws_client_set_option(wsio_instance->uws, optionName, value) != 0)
+            {
+                /* Codes_SRS_WSIO_01_157: [ If uws_client_set_option fails, wsio_setoption shall fail and return a non-zero value. ]*/
+                LogError("Setting the option %s failed", optionName);
+                result = MU_FAILURE;
+            }
+            else
+            {
+                /* Codes_SRS_WSIO_01_158: [ On success, wsio_setoption shall return 0. ]*/
+                result = 0;
+            }
+        }
+    }
+
+    return result;
+}
+
+static void* wsio_clone_option(const char* name, const void* value)
+{
+    void *result;
+
+    if (
+        (name == NULL) ||
+        (value == NULL)
+        )
+    {
+        /* Codes_SRS_WSIO_01_174: [ If wsio_clone_option is called with NULL name or value it shall return NULL. ]*/
+        LogError("invalid argument detected: const char* name=%p, const void* value=%p", name, value);
+        result = NULL;
+    }
+    else
+    {
+        if (strcmp(name, WSIO_OPTIONS) == 0)
+        {
+            /* Codes_SRS_WSIO_01_171: [** wsio_clone_option called with name being WSIOOptions shall return the same value. ]*/
+            result = (void*)value;
+        }
+        else
+        {
+            /* Codes_SRS_WSIO_01_173: [ wsio_clone_option called with any other option name than WSIOOptions shall return NULL. ]*/
+            LogError("unknown option: %s", name);
+            result = NULL;
+        }
+    }
+
+    return result;
+}
+
+static void wsio_destroy_option(const char* name, const void* value)
+{
+    if (
+        (name == NULL) ||
+        (value == NULL)
+        )
+    {
+        /* Codes_SRS_WSIO_01_177: [ If wsio_destroy_option is called with NULL name or value it shall do nothing. ]*/
+        LogError("Bad arguments: const char* name=%p, const void* value=%p", name, value);
+    }
+    else
+    {
+        if (strcmp(name, WSIO_OPTIONS) == 0)
+        {
+            /* Codes_SRS_WSIO_01_175: [ wsio_destroy_option called with the option name being WSIOOptions shall destroy the value by calling OptionHandler_Destroy. ]*/
+            OptionHandler_Destroy((OPTIONHANDLER_HANDLE)value);
+        }
+        else
+        {
+            /* Codes_SRS_WSIO_01_176: [ If wsio_destroy_option is called with any other name it shall do nothing. ]*/
+            LogError("unknown option: %s", name);
+        }
+    }
+}
+
+OPTIONHANDLER_HANDLE wsio_retrieveoptions(CONCRETE_IO_HANDLE handle)
+{
+    OPTIONHANDLER_HANDLE result;
+    if (handle == NULL)
+    {
+        /* Codes_SRS_WSIO_01_118: [ If parameter handle is NULL then wsio_retrieveoptions shall fail and return NULL. ]*/
+        LogError("parameter handle is NULL");
+        result = NULL;
+    }
+    else
+    {
+        WSIO_INSTANCE* wsio = (WSIO_INSTANCE*)handle;
+
+        /* Codes_SRS_WSIO_01_119: [ wsio_retrieveoptions shall call OptionHandler_Create to produce an OPTIONHANDLER_HANDLE and on success return the new OPTIONHANDLER_HANDLE handle. ]*/
+        result = OptionHandler_Create(wsio_clone_option, wsio_destroy_option, wsio_setoption);
+        if (result == NULL)
+        {
+            /* Codes_SRS_WSIO_01_120: [ If OptionHandler_Create fails then wsio_retrieveoptions shall fail and return NULL.  ]*/
+            LogError("OptionHandler_Create failed");
+        }
+        else
+        {
+            /* Codes_SRS_WSIO_01_179: [ When calling uws_client_retrieve_options the uws client handle shall be passed to it. ]*/
+            /* Codes_SRS_WSIO_01_178: [ uws_client_retrieve_options shall add to the option handler one option, whose name shall be uWSCLientOptions and the value shall be queried by calling uws_client_retrieve_options. ]*/
+            OPTIONHANDLER_HANDLE concreteOptions = uws_client_retrieve_options(wsio->uws);
+            if (concreteOptions == NULL)
+            {
+                /* Codes_SRS_WSIO_01_180: [ If uws_client_retrieve_options fails, uws_client_retrieve_options shall fail and return NULL. ]*/
+                LogError("unable to concrete_io_retrieveoptions");
+                OptionHandler_Destroy(result);
+                result = NULL;
+            }
+            else
+            {
+                /* Codes_SRS_WSIO_01_181: [ Adding the option shall be done by calling OptionHandler_AddOption. ]*/
+                if (OptionHandler_AddOption(result, WSIO_OPTIONS, concreteOptions) != OPTIONHANDLER_OK)
+                {
+                    /* Codes_SRS_WSIO_01_182: [ If OptionHandler_AddOption fails, uws_client_retrieve_options shall fail and return NULL. ]*/
+                    LogError("unable to OptionHandler_AddOption");
+                    OptionHandler_Destroy(concreteOptions);
+                    OptionHandler_Destroy(result);
+                    result = NULL;
+                }
+            }
+        }
+    }
+
+    return result;
+}
+
+static const IO_INTERFACE_DESCRIPTION ws_io_interface_description =
+{
+    wsio_retrieveoptions,
+    wsio_create,
+    wsio_destroy,
+    wsio_open,
+    wsio_close,
+    wsio_send,
+    wsio_dowork,
+    wsio_setoption
+};
+
+const IO_INTERFACE_DESCRIPTION* wsio_get_interface_description(void)
+{
+    return &ws_io_interface_description;
+}
Index: azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/src/xio.c
===================================================================
--- azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/src/xio.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/src/xio.c	(revision 457)
@@ -0,0 +1,302 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+#include <stdlib.h>
+#include "azure_c_shared_utility/gballoc.h"
+#include "azure_c_shared_utility/optimize_size.h"
+#include "azure_c_shared_utility/xio.h"
+#include "azure_c_shared_utility/xlogging.h"
+
+static const char* CONCRETE_OPTIONS = "concreteOptions";
+
+typedef struct XIO_INSTANCE_TAG
+{
+    const IO_INTERFACE_DESCRIPTION* io_interface_description;
+    CONCRETE_IO_HANDLE concrete_xio_handle;
+} XIO_INSTANCE;
+
+XIO_HANDLE xio_create(const IO_INTERFACE_DESCRIPTION* io_interface_description, const void* xio_create_parameters)
+{
+    XIO_INSTANCE* xio_instance;
+    /* Codes_SRS_XIO_01_003: [If the argument io_interface_description is NULL, xio_create shall return NULL.] */
+    if ((io_interface_description == NULL) ||
+        /* Codes_SRS_XIO_01_004: [If any io_interface_description member is NULL, xio_create shall return NULL.] */
+        (io_interface_description->concrete_io_retrieveoptions == NULL) ||
+        (io_interface_description->concrete_io_create == NULL) ||
+        (io_interface_description->concrete_io_destroy == NULL) ||
+        (io_interface_description->concrete_io_open == NULL) ||
+        (io_interface_description->concrete_io_close == NULL) ||
+        (io_interface_description->concrete_io_send == NULL) ||
+        (io_interface_description->concrete_io_dowork == NULL) ||
+        (io_interface_description->concrete_io_setoption == NULL))
+    {
+        xio_instance = NULL;
+    }
+    else
+    {
+        xio_instance = (XIO_INSTANCE*)malloc(sizeof(XIO_INSTANCE));
+
+        /* Codes_SRS_XIO_01_017: [If allocating the memory needed for the IO interface fails then xio_create shall return NULL.] */
+        if (xio_instance != NULL)
+        {
+            /* Codes_SRS_XIO_01_001: [xio_create shall return on success a non-NULL handle to a new IO interface.] */
+            xio_instance->io_interface_description = io_interface_description;
+
+            /* Codes_SRS_XIO_01_002: [In order to instantiate the concrete IO implementation the function concrete_io_create from the io_interface_description shall be called, passing the xio_create_parameters argument.] */
+            xio_instance->concrete_xio_handle = xio_instance->io_interface_description->concrete_io_create((void*)xio_create_parameters);
+
+            /* Codes_SRS_XIO_01_016: [If the underlying concrete_io_create call fails, xio_create shall return NULL.] */
+            if (xio_instance->concrete_xio_handle == NULL)
+            {
+                free(xio_instance);
+                xio_instance = NULL;
+            }
+        }
+    }
+    return (XIO_HANDLE)xio_instance;
+}
+
+void xio_destroy(XIO_HANDLE xio)
+{
+    /* Codes_SRS_XIO_01_007: [If the argument io is NULL, xio_destroy shall do nothing.] */
+    if (xio != NULL)
+    {
+        XIO_INSTANCE* xio_instance = (XIO_INSTANCE*)xio;
+
+        /* Codes_SRS_XIO_01_006: [xio_destroy shall also call the concrete_io_destroy function that is member of the io_interface_description argument passed to xio_create, while passing as argument to concrete_io_destroy the result of the underlying concrete_io_create handle that was called as part of the xio_create call.] */
+        xio_instance->io_interface_description->concrete_io_destroy(xio_instance->concrete_xio_handle);
+
+        /* Codes_SRS_XIO_01_005: [xio_destroy shall free all resources associated with the IO handle.] */
+        free(xio_instance);
+    }
+}
+
+int xio_open(XIO_HANDLE xio, ON_IO_OPEN_COMPLETE on_io_open_complete, void* on_io_open_complete_context, ON_BYTES_RECEIVED on_bytes_received, void* on_bytes_received_context, ON_IO_ERROR on_io_error, void* on_io_error_context)
+{
+    int result;
+
+    if (xio == NULL)
+    {
+        /* Codes_SRS_XIO_01_021: [If handle is NULL, xio_open shall return a non-zero value.] */
+        result = MU_FAILURE;
+    }
+    else
+    {
+        XIO_INSTANCE* xio_instance = (XIO_INSTANCE*)xio;
+
+        /* Codes_SRS_XIO_01_019: [xio_open shall call the specific concrete_xio_open function specified in xio_create, passing callback function and context arguments for three events: open completed, bytes received, and IO error.] */
+        if (xio_instance->io_interface_description->concrete_io_open(xio_instance->concrete_xio_handle, on_io_open_complete, on_io_open_complete_context, on_bytes_received, on_bytes_received_context, on_io_error, on_io_error_context) != 0)
+        {
+            /* Codes_SRS_XIO_01_022: [If the underlying concrete_io_open fails, xio_open shall return a non-zero value.] */
+            result = MU_FAILURE;
+        }
+        else
+        {
+            /* Codes_SRS_XIO_01_020: [On success, xio_open shall return 0.] */
+            result = 0;
+        }
+    }
+
+    return result;
+}
+
+int xio_close(XIO_HANDLE xio, ON_IO_CLOSE_COMPLETE on_io_close_complete, void* callback_context)
+{
+    int result;
+
+    if (xio == NULL)
+    {
+        /* Codes_SRS_XIO_01_025: [If handle is NULL, xio_close shall return a non-zero value.] */
+        result = MU_FAILURE;
+    }
+    else
+    {
+        XIO_INSTANCE* xio_instance = (XIO_INSTANCE*)xio;
+
+        /* Codes_SRS_XIO_01_023: [xio_close shall call the specific concrete_io_close function specified in xio_create.] */
+        if (xio_instance->io_interface_description->concrete_io_close(xio_instance->concrete_xio_handle, on_io_close_complete, callback_context) != 0)
+        {
+            /* Codes_SRS_XIO_01_026: [If the underlying concrete_io_close fails, xio_close shall return a non-zero value.] */
+            result = MU_FAILURE;
+        }
+        else
+        {
+            /* Codes_SRS_XIO_01_024: [On success, xio_close shall return 0.] */
+            result = 0;
+        }
+    }
+
+    return result;
+}
+
+int xio_send(XIO_HANDLE xio, const void* buffer, size_t size, ON_SEND_COMPLETE on_send_complete, void* callback_context)
+{
+    int result;
+
+    /* Codes_SRS_XIO_01_011: [No error check shall be performed on buffer and size.] */
+    /* Codes_SRS_XIO_01_010: [If handle is NULL, xio_send shall return a non-zero value.] */
+    if (xio == NULL)
+    {
+        result = MU_FAILURE;
+    }
+    else
+    {
+        XIO_INSTANCE* xio_instance = (XIO_INSTANCE*)xio;
+
+        /* Codes_SRS_XIO_01_008: [xio_send shall pass the sequence of bytes pointed to by buffer to the concrete IO implementation specified in xio_create, by calling the concrete_io_send function while passing down the buffer and size arguments to it.] */
+        /* Codes_SRS_XIO_01_009: [On success, xio_send shall return 0.] */
+        /* Codes_SRS_XIO_01_015: [If the underlying concrete_io_send fails, xio_send shall return a non-zero value.] */
+        /* Codes_SRS_XIO_01_027: [xio_send shall pass to the concrete_io_send function the on_send_complete and callback_context arguments.] */
+        result = xio_instance->io_interface_description->concrete_io_send(xio_instance->concrete_xio_handle, buffer, size, on_send_complete, callback_context);
+    }
+
+    return result;
+}
+
+void xio_dowork(XIO_HANDLE xio)
+{
+    /* Codes_SRS_XIO_01_018: [When the handle argument is NULL, xio_dowork shall do nothing.] */
+    if (xio != NULL)
+    {
+        XIO_INSTANCE* xio_instance = (XIO_INSTANCE*)xio;
+
+        /* Codes_SRS_XIO_01_012: [xio_dowork shall call the concrete XIO implementation specified in xio_create, by calling the concrete_io_dowork function.] */
+        xio_instance->io_interface_description->concrete_io_dowork(xio_instance->concrete_xio_handle);
+    }
+}
+
+int xio_setoption(XIO_HANDLE xio, const char* optionName, const void* value)
+{
+    int result;
+
+    /* Codes_SRS_XIO_03_030: [If the xio argument or the optionName argument is NULL, xio_setoption shall return a non-zero value.] */
+    if (xio == NULL || optionName == NULL)
+    {
+        result = MU_FAILURE;
+    }
+    else
+    {
+        XIO_INSTANCE* xio_instance = (XIO_INSTANCE*)xio;
+
+        if (strcmp(CONCRETE_OPTIONS, optionName) == 0)
+        {
+            /*then value is a pointer to OPTIONHANDLER_HANDLE*/
+            if (OptionHandler_FeedOptions((OPTIONHANDLER_HANDLE)value, xio_instance->concrete_xio_handle) != OPTIONHANDLER_OK)
+            {
+                LogError("unable to OptionHandler_FeedOptions");
+                result = MU_FAILURE;
+            }
+            else
+            {
+                result = 0;
+            }
+        }
+        else /*passthrough*/
+        {
+            /* Codes_SRS_XIO_003_028: [xio_setoption shall pass the optionName and value to the concrete IO implementation specified in xio_create by invoking the concrete_xio_setoption function.] */
+            /* Codes_SRS_XIO_03_029: [xio_setoption shall return 0 upon success.] */
+            /* Codes_SRS_XIO_03_031: [If the underlying concrete_xio_setoption fails, xio_setOption shall return a non-zero value.] */
+            result = xio_instance->io_interface_description->concrete_io_setoption(xio_instance->concrete_xio_handle, optionName, value);
+        }
+    }
+
+    return result;
+}
+
+static void* xio_CloneOption(const char* name, const void* value)
+{
+    void *result;
+    if (
+        (name == NULL) ||
+        (value == NULL)
+        )
+    {
+        LogError("invalid argument detected: const char* name=%p, const void* value=%p", name, value);
+        result = NULL;
+    }
+    else
+    {
+        if (strcmp(name, CONCRETE_OPTIONS) == 0)
+        {
+            result = (void*)value;
+        }
+        else
+        {
+            LogError("unknown option: %s", name);
+            result = NULL;
+        }
+    }
+    return result;
+}
+
+
+static void xio_DestroyOption(const char* name, const void* value)
+{
+    if (
+        (name == NULL) ||
+        (value == NULL)
+        )
+    {
+        LogError("invalid argument detected: const char* name=%p, const void* value=%p", name, value);
+    }
+    else
+    {
+        if (strcmp(name, CONCRETE_OPTIONS) == 0)
+        {
+            OptionHandler_Destroy((OPTIONHANDLER_HANDLE)value);
+        }
+        else
+        {
+            LogError("unknown option: %s", name);
+        }
+    }
+}
+
+OPTIONHANDLER_HANDLE xio_retrieveoptions(XIO_HANDLE xio)
+{
+    OPTIONHANDLER_HANDLE result;
+
+    if (xio == NULL)
+    {
+        LogError("invalid argument detected: XIO_HANDLE xio=%p", xio);
+        result = NULL;
+    }
+    else
+    {
+        XIO_INSTANCE* xio_instance = (XIO_INSTANCE*)xio;
+        /*xio_retrieveoptions shall return a OPTIONHANDLER_HANDLE that has 1 option called "underlyingOptions" which is of type OPTIONHANDLER_HANDLE*/
+        result = OptionHandler_Create(xio_CloneOption, xio_DestroyOption, (pfSetOption)xio_setoption);
+        if (result == NULL)
+        {
+            LogError("unable to OptionHandler_Create");
+            /*return as is*/
+        }
+        else
+        {
+            OPTIONHANDLER_HANDLE concreteOptions = xio_instance->io_interface_description->concrete_io_retrieveoptions(xio_instance->concrete_xio_handle);
+            if (concreteOptions == NULL)
+            {
+                LogError("unable to concrete_io_retrieveoptions");
+                OptionHandler_Destroy(result);
+                result = NULL;
+            }
+            else
+            {
+                if (OptionHandler_AddOption(result, CONCRETE_OPTIONS, concreteOptions) != OPTIONHANDLER_OK)
+                {
+                    LogError("unable to OptionHandler_AddOption");
+                    OptionHandler_Destroy(concreteOptions);
+                    OptionHandler_Destroy(result);
+                    result = NULL;
+                }
+                else
+                {
+                    /*all is fine*/
+                }
+            }
+        }
+    }
+
+    return result;
+}
+
Index: azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/src/xlogging.c
===================================================================
--- azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/src/xlogging.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/src/xlogging.c	(revision 457)
@@ -0,0 +1,145 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+#include "azure_c_shared_utility/xlogging.h"
+#include "azure_c_shared_utility/consolelogger.h"
+
+#ifndef NO_LOGGING
+
+#ifdef WIN32
+#include "windows.h"
+#endif // WIN32
+
+
+LOGGER_LOG global_log_function = consolelogger_log;
+
+void xlogging_set_log_function(LOGGER_LOG log_function)
+{
+    global_log_function = log_function;
+}
+
+LOGGER_LOG xlogging_get_log_function(void)
+{
+    return global_log_function;
+}
+
+#if (defined(_MSC_VER))
+
+LOGGER_LOG_GETLASTERROR global_log_function_GetLastError = consolelogger_log_with_GetLastError;
+
+void xlogging_set_log_function_GetLastError(LOGGER_LOG_GETLASTERROR log_function_GetLastError)
+{
+    global_log_function_GetLastError = log_function_GetLastError;
+}
+
+LOGGER_LOG_GETLASTERROR xlogging_get_log_function_GetLastError(void)
+{
+    return global_log_function_GetLastError;
+}
+#endif
+
+/* Print up to 16 bytes per line. */
+#define LINE_SIZE 16
+
+/* Return the printable char for the provided value. */
+#define PRINTABLE(c)         ((c >= ' ') && (c <= '~')) ? (char)c : '.'
+
+/* Convert the lower nibble of the provided byte to a hexadecimal printable char. */
+#define HEX_STR(c)           (((c) & 0xF) < 0xA) ? (char)(((c) & 0xF) + '0') : (char)(((c) & 0xF) - 0xA + 'A')
+
+void LogBinary(const char* comment, const void* data, size_t size)
+{
+    char charBuf[LINE_SIZE + 1];
+    char hexBuf[LINE_SIZE * 3 + 1];
+    size_t countbuf = 0;
+    size_t i = 0;
+    const unsigned char* bufAsChar = (const unsigned char*)data;
+    const unsigned char* startPos = bufAsChar;
+
+    LOG(AZ_LOG_TRACE, LOG_LINE, "%s     %lu bytes", comment, (unsigned long)size);
+
+    /* Print the whole buffer. */
+    for (i = 0; i < size; i++)
+    {
+        /* Store the printable value of the char in the charBuf to print. */
+        charBuf[countbuf] = PRINTABLE(*bufAsChar);
+
+        /* Convert the high nibble to a printable hexadecimal value. */
+        hexBuf[countbuf * 3] = HEX_STR(*bufAsChar >> 4);
+
+        /* Convert the low nibble to a printable hexadecimal value. */
+        hexBuf[countbuf * 3 + 1] = HEX_STR(*bufAsChar);
+
+        hexBuf[countbuf * 3 + 2] = ' ';
+
+        countbuf++;
+        bufAsChar++;
+        /* If the line is full, print it to start another one. */
+        if (countbuf == LINE_SIZE)
+        {
+            charBuf[countbuf] = '\0';
+            hexBuf[countbuf * 3] = '\0';
+            LOG(AZ_LOG_TRACE, LOG_LINE, "%p: %s    %s", startPos, hexBuf, charBuf);
+            countbuf = 0;
+            startPos = bufAsChar;
+        }
+    }
+
+    /* If the last line does not fit the line size. */
+    if (countbuf > 0)
+    {
+        /* Close the charBuf string. */
+        charBuf[countbuf] = '\0';
+
+        /* Fill the hexBuf with spaces to keep the charBuf alignment. */
+        while ((countbuf++) < LINE_SIZE - 1)
+        {
+            hexBuf[countbuf * 3] = ' ';
+            hexBuf[countbuf * 3 + 1] = ' ';
+            hexBuf[countbuf * 3 + 2] = ' ';
+        }
+        hexBuf[countbuf * 3] = '\0';
+
+        /* Print the last line. */
+        LOG(AZ_LOG_TRACE, LOG_LINE, "%p: %s    %s", startPos, hexBuf, charBuf);
+    }
+}
+
+#ifdef WIN32
+
+void xlogging_LogErrorWinHTTPWithGetLastErrorAsStringFormatter(int errorMessageID)
+{
+    char messageBuffer[MESSAGE_BUFFER_SIZE];
+    if (errorMessageID == 0)
+    {
+        LogError("GetLastError() returned 0. Make sure you are calling this right after the code that failed. ");
+    }
+    else
+    {
+        int size = FormatMessage(FORMAT_MESSAGE_FROM_HMODULE | FORMAT_MESSAGE_IGNORE_INSERTS,
+            GetModuleHandle("WinHttp"), errorMessageID, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), messageBuffer, MESSAGE_BUFFER_SIZE, NULL);
+        if (size == 0)
+        {
+            size = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, errorMessageID, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), messageBuffer, MESSAGE_BUFFER_SIZE, NULL);
+            if (size == 0)
+            {
+                LogError("GetLastError Code: %d. ", errorMessageID);
+            }
+            else
+            {
+                LogError("GetLastError: %s.", messageBuffer);
+            }
+        }
+        else
+        {
+            LogError("GetLastError: %s.", messageBuffer);
+        }
+    }
+}
+#endif // WIN32
+
+
+#endif // NO_LOGGING
+
+
+
Index: azure_iot_hub_f767zi/trunk/azure_iot_sdk/certs/certs.c
===================================================================
--- azure_iot_hub_f767zi/trunk/azure_iot_sdk/certs/certs.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/azure_iot_sdk/certs/certs.c	(revision 457)
@@ -0,0 +1,103 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+/* This file contains certs needed to communicate with Azure (IoT) */
+
+#include "certs.h"
+/* Note: for devices with limited resources, only one cert should be loaded. 
+   #defines are used to reduce memory footprint of certificates.
+   For DE and CN regions, please build with -DUSE_MICROSOFTAZURE_DE_CERT or -DUSE_PORTAL_AZURE_CN_CERT, respectively, 
+   if you wish to load ONLY those certs.
+*/
+#if !defined(USE_BALTIMORE_CERT) && !defined(USE_MICROSOFTAZURE_DE_CERT) && !defined(USE_PORTAL_AZURE_CN_CERT)
+// For legacy, if no certificates were explicitly selected then include all of them
+#define USE_BALTIMORE_CERT
+#define USE_MICROSOFTAZURE_DE_CERT 
+#define USE_PORTAL_AZURE_CN_CERT
+#endif
+
+const char certificates[] =
+#if defined(USE_BALTIMORE_CERT)
+/* DigiCert Baltimore Root --Used Globally--*/
+// This cert should be used when connecting to Azure IoT on the Azure Cloud available globally. When in doubt, use this cert.
+"-----BEGIN CERTIFICATE-----\r\n"
+"MIIDdzCCAl+gAwIBAgIEAgAAuTANBgkqhkiG9w0BAQUFADBaMQswCQYDVQQGEwJJ\r\n"
+"RTESMBAGA1UEChMJQmFsdGltb3JlMRMwEQYDVQQLEwpDeWJlclRydXN0MSIwIAYD\r\n"
+"VQQDExlCYWx0aW1vcmUgQ3liZXJUcnVzdCBSb290MB4XDTAwMDUxMjE4NDYwMFoX\r\n"
+"DTI1MDUxMjIzNTkwMFowWjELMAkGA1UEBhMCSUUxEjAQBgNVBAoTCUJhbHRpbW9y\r\n"
+"ZTETMBEGA1UECxMKQ3liZXJUcnVzdDEiMCAGA1UEAxMZQmFsdGltb3JlIEN5YmVy\r\n"
+"VHJ1c3QgUm9vdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKMEuyKr\r\n"
+"mD1X6CZymrV51Cni4eiVgLGw41uOKymaZN+hXe2wCQVt2yguzmKiYv60iNoS6zjr\r\n"
+"IZ3AQSsBUnuId9Mcj8e6uYi1agnnc+gRQKfRzMpijS3ljwumUNKoUMMo6vWrJYeK\r\n"
+"mpYcqWe4PwzV9/lSEy/CG9VwcPCPwBLKBsua4dnKM3p31vjsufFoREJIE9LAwqSu\r\n"
+"XmD+tqYF/LTdB1kC1FkYmGP1pWPgkAx9XbIGevOF6uvUA65ehD5f/xXtabz5OTZy\r\n"
+"dc93Uk3zyZAsuT3lySNTPx8kmCFcB5kpvcY67Oduhjprl3RjM71oGDHweI12v/ye\r\n"
+"jl0qhqdNkNwnGjkCAwEAAaNFMEMwHQYDVR0OBBYEFOWdWTCCR1jMrPoIVDaGezq1\r\n"
+"BE3wMBIGA1UdEwEB/wQIMAYBAf8CAQMwDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3\r\n"
+"DQEBBQUAA4IBAQCFDF2O5G9RaEIFoN27TyclhAO992T9Ldcw46QQF+vaKSm2eT92\r\n"
+"9hkTI7gQCvlYpNRhcL0EYWoSihfVCr3FvDB81ukMJY2GQE/szKN+OMY3EU/t3Wgx\r\n"
+"jkzSswF07r51XgdIGn9w/xZchMB5hbgF/X++ZRGjD8ACtPhSNzkE1akxehi/oCr0\r\n"
+"Epn3o0WC4zxe9Z2etciefC7IpJ5OCBRLbf1wbWsaY71k5h+3zvDyny67G7fyUIhz\r\n"
+"ksLi4xaNmjICq44Y3ekQEe5+NauQrz4wlHrQMz2nZQ/1/I6eYs9HRCwBXbsdtTLS\r\n"
+"R9I4LtD+gdwyah617jzV/OeBHRnDJELqYzmp\r\n"
+"-----END CERTIFICATE-----\r\n"
+#endif /* BALTIMORE_CERT */
+
+#if defined(USE_PORTAL_AZURE_CN_CERT)
+/* DigiCert Global Root CA */
+// This cert should be used when connecting to Azure IoT on the https://portal.azure.cn Cloud address.
+"-----BEGIN CERTIFICATE-----\r\n"
+"MIIDrzCCApegAwIBAgIQCDvgVpBCRrGhdWrJWZHHSjANBgkqhkiG9w0BAQUFADBh\r\n"
+"MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3\r\n"
+"d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBD\r\n"
+"QTAeFw0wNjExMTAwMDAwMDBaFw0zMTExMTAwMDAwMDBaMGExCzAJBgNVBAYTAlVT\r\n"
+"MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5j\r\n"
+"b20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IENBMIIBIjANBgkqhkiG\r\n"
+"9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4jvhEXLeqKTTo1eqUKKPC3eQyaKl7hLOllsB\r\n"
+"CSDMAZOnTjC3U/dDxGkAV53ijSLdhwZAAIEJzs4bg7/fzTtxRuLWZscFs3YnFo97\r\n"
+"nh6Vfe63SKMI2tavegw5BmV/Sl0fvBf4q77uKNd0f3p4mVmFaG5cIzJLv07A6Fpt\r\n"
+"43C/dxC//AH2hdmoRBBYMql1GNXRor5H4idq9Joz+EkIYIvUX7Q6hL+hqkpMfT7P\r\n"
+"T19sdl6gSzeRntwi5m3OFBqOasv+zbMUZBfHWymeMr/y7vrTC0LUq7dBMtoM1O/4\r\n"
+"gdW7jVg/tRvoSSiicNoxBN33shbyTApOB6jtSj1etX+jkMOvJwIDAQABo2MwYTAO\r\n"
+"BgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUA95QNVbR\r\n"
+"TLtm8KPiGxvDl7I90VUwHwYDVR0jBBgwFoAUA95QNVbRTLtm8KPiGxvDl7I90VUw\r\n"
+"DQYJKoZIhvcNAQEFBQADggEBAMucN6pIExIK+t1EnE9SsPTfrgT1eXkIoyQY/Esr\r\n"
+"hMAtudXH/vTBH1jLuG2cenTnmCmrEbXjcKChzUyImZOMkXDiqw8cvpOp/2PV5Adg\r\n"
+"06O/nVsJ8dWO41P0jmP6P6fbtGbfYmbW0W5BjfIttep3Sp+dWOIrWcBAI+0tKIJF\r\n"
+"PnlUkiaY4IBIqDfv8NZ5YBberOgOzW6sRBc4L0na4UU+Krk2U886UAb3LujEV0ls\r\n"
+"YSEY1QSteDwsOoBrp+uvFRTp2InBuThs4pFsiv9kuXclVzDAGySj4dzp30d8tbQk\r\n"
+"CAUw7C29C79Fv1C5qfPrmAESrciIxpg0X40KPMbp1ZWVbd4=\r\n"
+"-----END CERTIFICATE-----\r\n"
+#endif /* PORTAL_AZURE_CN_CERT */
+
+#if defined(USE_MICROSOFTAZURE_DE_CERT)
+/* D-TRUST Root Class 3 CA 2 2009 */
+// This cert should be used when connecting to Azure IoT on the https://portal.microsoftazure.de Cloud address.
+"-----BEGIN CERTIFICATE-----\r\n"
+"MIIEMzCCAxugAwIBAgIDCYPzMA0GCSqGSIb3DQEBCwUAME0xCzAJBgNVBAYTAkRF\r\n"
+"MRUwEwYDVQQKDAxELVRydXN0IEdtYkgxJzAlBgNVBAMMHkQtVFJVU1QgUm9vdCBD\r\n"
+"bGFzcyAzIENBIDIgMjAwOTAeFw0wOTExMDUwODM1NThaFw0yOTExMDUwODM1NTha\r\n"
+"ME0xCzAJBgNVBAYTAkRFMRUwEwYDVQQKDAxELVRydXN0IEdtYkgxJzAlBgNVBAMM\r\n"
+"HkQtVFJVU1QgUm9vdCBDbGFzcyAzIENBIDIgMjAwOTCCASIwDQYJKoZIhvcNAQEB\r\n"
+"BQADggEPADCCAQoCggEBANOySs96R+91myP6Oi/WUEWJNTrGa9v+2wBoqOADER03\r\n"
+"UAifTUpolDWzU9GUY6cgVq/eUXjsKj3zSEhQPgrfRlWLJ23DEE0NkVJD2IfgXU42\r\n"
+"tSHKXzlABF9bfsyjxiupQB7ZNoTWSPOSHjRGICTBpFGOShrvUD9pXRl/RcPHAY9R\r\n"
+"ySPocq60vFYJfxLLHLGvKZAKyVXMD9O0Gu1HNVpK7ZxzBCHQqr0ME7UAyiZsxGsM\r\n"
+"lFqVlNpQmvH/pStmMaTJOKDfHR+4CS7zp+hnUquVH+BGPtikw8paxTGA6Eian5Rp\r\n"
+"/hnd2HN8gcqW3o7tszIFZYQ05ub9VxC1X3a/L7AQDcUCAwEAAaOCARowggEWMA8G\r\n"
+"A1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFP3aFMSfMN4hvR5COfyrYyNJ4PGEMA4G\r\n"
+"A1UdDwEB/wQEAwIBBjCB0wYDVR0fBIHLMIHIMIGAoH6gfIZ6bGRhcDovL2RpcmVj\r\n"
+"dG9yeS5kLXRydXN0Lm5ldC9DTj1ELVRSVVNUJTIwUm9vdCUyMENsYXNzJTIwMyUy\r\n"
+"MENBJTIwMiUyMDIwMDksTz1ELVRydXN0JTIwR21iSCxDPURFP2NlcnRpZmljYXRl\r\n"
+"cmV2b2NhdGlvbmxpc3QwQ6BBoD+GPWh0dHA6Ly93d3cuZC10cnVzdC5uZXQvY3Js\r\n"
+"L2QtdHJ1c3Rfcm9vdF9jbGFzc18zX2NhXzJfMjAwOS5jcmwwDQYJKoZIhvcNAQEL\r\n"
+"BQADggEBAH+X2zDI36ScfSF6gHDOFBJpiBSVYEQBrLLpME+bUMJm2H6NMLVwMeni\r\n"
+"acfzcNsgFYbQDfC+rAF1hM5+n02/t2A7nPPKHeJeaNijnZflQGDSNiH+0LS4F9p0\r\n"
+"o3/U37CYAqxva2ssJSRyoWXuJVrl5jLn8t+rSfrzkGkj2wTZ51xY/GXUl77M/C4K\r\n"
+"zCUqNQT4YJEVdT1B/yMfGchs64JTBKbkTCJNjYy6zltz7GRUUG3RnFX7acM2w4y8\r\n"
+"PIWmawomDeCTmGCufsYkl4phX5GOZpIJhzbNi5stPvZR1FDUWSi9g/LMKHtThm3Y\r\n"
+"Johw1+qRzT65ysCQblrGXnRl11z+o+I=\r\n"
+"-----END CERTIFICATE-----\r\n"
+#endif /* MICROSOFTAZURE_DE_CERT */
+
+;
Index: azure_iot_hub_f767zi/trunk/azure_iot_sdk/certs/certs.h
===================================================================
--- azure_iot_hub_f767zi/trunk/azure_iot_sdk/certs/certs.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/azure_iot_sdk/certs/certs.h	(revision 457)
@@ -0,0 +1,18 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+#ifndef CERTS_H
+#define CERTS_H
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+    extern const char certificates[];
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* CERTS_H */
Index: azure_iot_hub_f767zi/trunk/azure_iot_sdk/deps/azure-macro-utils-c/inc/azure_macro_utils/macro_utils.h
===================================================================
--- azure_iot_hub_f767zi/trunk/azure_iot_sdk/deps/azure-macro-utils-c/inc/azure_macro_utils/macro_utils.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/azure_iot_sdk/deps/azure-macro-utils-c/inc/azure_macro_utils/macro_utils.h	(revision 457)
@@ -0,0 +1,217 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+#ifndef MACRO_UTILS_H
+#define MACRO_UTILS_H
+
+#include "azure_macro_utils/macro_utils_generated.h"
+
+#ifdef __cplusplus
+#include <cstring>
+#include <cstddef>
+extern "C" {
+#else
+#include <string.h>
+#include <stddef.h>
+#endif
+
+#if (defined OPTIMIZE_RETURN_CODES)
+    #define MU_FAILURE 1
+#else
+    #define MU_FAILURE __LINE__
+#endif
+
+/*"pointer or NULL" macro - because when printf-ing arguments NULL is not valid for %s (section 7.1.4 of C11 standard) */
+#define MU_P_OR_NULL(p) (((p)!=NULL)?(p):"NULL")
+#define MU_WP_OR_NULL(p) (((p)!=NULL)?(p):L"NULL")
+
+#define MU_TOSTRING_(x) #x
+#define MU_TOSTRING(x) MU_TOSTRING_(x)
+
+#define MU_TRIGGER_PARENTHESIS(...) ,
+
+#define MU_LPAREN (
+
+#define MU_C2_(x,y) x##y
+
+#define MU_C2(x,y) MU_C2_(x,y)
+
+#define MU_C3(x,y,z) MU_C2(x, MU_C2(y,z))
+
+#define MU_C4(x,y,z, u) MU_C2(MU_C2(x,y), MU_C2(z,u))
+
+#define MU_C5(x,y,z,u, v) MU_C2(MU_C4(x,y, z, u), v)
+
+#define MU_C1_(x) x
+
+#define MU_C1(x) MU_C1_(x)
+
+#define MU_C2STRING(x,y) x y
+
+#define MU_C3STRING(x,y,z) x y z
+
+#define MU_C4STRING(x,y,z,u) x y z u
+
+#define MU_C5STRING(x,y,z,u,v) x y z u v
+
+/* we need some sort of macro that does:
+MU_IF(0, "true", "false") => "false"
+MU_IF(1, "true", "false") => "true"
+MU_IF(X, "true", "false") => "true"
+*/
+
+#define MU_INTERNALIF(x) MU_INTERNALIF##x
+#define MU_INTERNALIF0
+
+#define MU_ISZERO(x) MU_COUNT_ARG(MU_INTERNALIF(x))
+
+#define MU_IF(condition, trueBranch, falseBranch) MU_C2(MU_IF,MU_ISZERO(condition))(trueBranch, falseBranch)
+#define MU_IF0(trueBranch, falseBranch) falseBranch
+#define MU_IF1(trueBranch, falseBranch) trueBranch
+
+
+/*the following macro want to eat empty arguments from a list */
+/*examples:                                                   */
+/*MU_EAT_EMPTY_ARGS(, , X) expands to X                       */
+
+#define MU_EXPAND_TO_NOTHING(arg)
+#define MU_EAT_EMPTY_ARG(arg_count, arg) MU_IF(MU_ISEMPTY(arg),,arg) MU_IF(MU_ISEMPTY(arg),MU_EXPAND_TO_NOTHING,MU_IFCOMMALOGIC)(MU_DEC(arg_count))
+#define MU_EAT_EMPTY_ARGS(...) MU_FOR_EACH_1_COUNTED(MU_EAT_EMPTY_ARG, __VA_ARGS__)
+
+#define MU_DEFINE_ENUMERATION_CONSTANT(x) x,
+/*MU_DEFINE_ENUM_WITHOUT_INVALID goes to header*/
+#define MU_DEFINE_ENUM_WITHOUT_INVALID(enumName, ...) typedef enum MU_C2(enumName, _TAG) { MU_FOR_EACH_1(MU_DEFINE_ENUMERATION_CONSTANT, __VA_ARGS__)} enumName; \
+    extern const char* MU_C2(enumName,Strings)(enumName value); \
+    extern int MU_C2(enumName, _FromString)(const char* enumAsString, enumName* destination);
+
+// this macro is a wrapper on top of MU_DEFINE_ENUM_WITHOUT_INVALID, adding an _INVALID value as the first enum value in the enum
+#define MU_DEFINE_ENUM(enumName, ...) \
+    MU_DEFINE_ENUM_WITHOUT_INVALID(enumName, MU_C2(enumName, _INVALID), __VA_ARGS__)
+
+#define MU_DEFINE_ENUMERATION_CONSTANT_AS_WIDESTRING(x) MU_C2(L, MU_TOSTRING(x)) , 
+#define MU_DEFINE_ENUMERATION_CONSTANT_AS_STRING(x) MU_TOSTRING(x) , 
+/*MU_DEFINE_ENUM_STRINGS_WITHOUT_INVALID goes to .c*/
+#define MU_DEFINE_ENUM_STRINGS_WITHOUT_INVALID(enumName, ...) const char* MU_C2(enumName, StringStorage)[MU_COUNT_ARG(__VA_ARGS__)] = {MU_FOR_EACH_1(MU_DEFINE_ENUMERATION_CONSTANT_AS_STRING, __VA_ARGS__)}; \
+const char* MU_C2(enumName,Strings)(enumName value)                \
+{                                                                  \
+    if((int)value<0 || (int)value>=MU_COUNT_ARG(__VA_ARGS__))      \
+    {                                                              \
+        /*this is an error case*/                                  \
+        return "NULL";                                             \
+    }                                                              \
+    else                                                           \
+    {                                                              \
+        return MU_C2(enumName, StringStorage)[value];              \
+    }                                                              \
+}                                                                  \
+int MU_C2(enumName, _FromString)(const char* enumAsString, enumName* destination)  \
+{                                                                               \
+    if(                                                                         \
+        (enumAsString==NULL) || (destination==NULL)                             \
+    )                                                                           \
+    {                                                                           \
+        return MU_FAILURE;                                                      \
+    }                                                                           \
+    else                                                                        \
+    {                                                                           \
+        size_t i;                                                               \
+        for(i=0;i<MU_COUNT_ARG(__VA_ARGS__);i++)                                \
+        {                                                                       \
+            if(strcmp(enumAsString, MU_C2(enumName, StringStorage)[i])==0)      \
+            {                                                                   \
+                *destination = (enumName)i;                                     \
+                return 0;                                                       \
+            }                                                                   \
+        }                                                                       \
+        return MU_FAILURE;                                                      \
+    }                                                                           \
+}                                                                               \
+
+// this macro is a wrapper on top of MU_DEFINE_ENUM_STRINGS_WITHOUT_INVALID, adding an _INVALID value as the first enum value in the enum
+#define MU_DEFINE_ENUM_STRINGS(enumName, ...) \
+    MU_DEFINE_ENUM_STRINGS_WITHOUT_INVALID(enumName, MU_C2(enumName, _INVALID), __VA_ARGS__)
+
+#define MU_DEFINE_LOCAL_ENUM_WITHOUT_INVALID(enumName, ...) typedef enum MU_C2(enumName, _TAG) { MU_FOR_EACH_1(MU_DEFINE_ENUMERATION_CONSTANT, __VA_ARGS__)} enumName; \
+static const char* MU_C2(enumName, StringStorage)[MU_COUNT_ARG(__VA_ARGS__)] = {MU_FOR_EACH_1(MU_DEFINE_ENUMERATION_CONSTANT_AS_STRING, __VA_ARGS__)}; \
+static const char* MU_C2(enumName,Strings)(enumName value)         \
+{                                                                  \
+    if((int)value<0 || (int)value>=MU_COUNT_ARG(__VA_ARGS__))      \
+    {                                                              \
+        /*this is an error case*/                                  \
+        return "NULL";                                             \
+    }                                                              \
+    else                                                           \
+    {                                                              \
+        return MU_C2(enumName, StringStorage)[value];              \
+    }                                                              \
+}
+
+// this macro is a wrapper on top of MU_DEFINE_LOCAL_ENUM_WITHOUT_INVALID, adding an _INVALID value as the first enum value in the enum
+#define MU_DEFINE_LOCAL_ENUM(enumName, ...) \
+    MU_DEFINE_LOCAL_ENUM_WITHOUT_INVALID(enumName, MU_C2(enumName, _INVALID), __VA_ARGS__)
+
+// this macro returns the number of enum values (taking into account that an invalid value is generated)
+#define MU_ENUM_VALUE_COUNT(...) (MU_COUNT_ARG(__VA_ARGS__) + 1)
+
+// this macro returns the number of enum 2 values (taking into account that an invalid value is generated)
+#define MU_ENUM_2_VALUE_COUNT(...) ((MU_COUNT_ARG(__VA_ARGS__) / 2) + 1)
+
+#define MU_ENUM_TO_STRING(enumName, enumValue) MU_C2(enumName, Strings)(enumValue)
+#define MU_STRING_TO_ENUM(stringValue, enumName, addressOfEnumVariable) MU_C2(enumName, _FromString)(stringValue, addressOfEnumVariable)
+
+#define MU_EMPTY()
+#define MACRO_UTILS_DELAY(id) id MU_EMPTY MU_LPAREN )
+
+#define MU_DEFINE_ENUMERATION_CONSTANT_2(enumerationConstant, constantExpression) enumerationConstant = constantExpression,
+
+#define MU_DECLARE_ENUM_STRINGS_2(enumIdentifier, ...) extern const char* MU_C3(MU_, enumIdentifier,_ToString)(enumIdentifier enumerationConstant);
+
+#define MU_DEFINE_ENUM_2_WITHOUT_INVALID(enumIdentifier, ... ) typedef enum MU_C2(enumIdentifier, _TAG) {MU_FOR_EACH_2(MU_DEFINE_ENUMERATION_CONSTANT_2, __VA_ARGS__)} enumIdentifier; \
+    MU_DECLARE_ENUM_STRINGS_2(enumIdentifier, __VA_ARGS__)
+
+// this macro is a wrapper on top of MU_DEFINE_ENUM, adding an _INVALID value as the first enum value in the enum
+#define MU_DEFINE_ENUM_2(enumName, ...) \
+    MU_DEFINE_ENUM_2_WITHOUT_INVALID(enumName, MU_C2(enumName, _INVALID), (int)0xDDDDDDDD, __VA_ARGS__)
+
+typedef struct ENUM_VALUE_AND_STRING_TAG
+{
+    int value;
+    const char* valueAsString;
+}ENUM_VALUE_AND_STRING;
+
+#define MU_DEFINE_ENUM_VALUE_AND_STRING(enumerationConstant, constantExpression) {enumerationConstant, MU_TOSTRING(enumerationConstant)},
+#define MU_DEFINE_ENUM_STRINGS_2(enumIdentifier, ... ) static const ENUM_VALUE_AND_STRING MU_C2(enumIdentifier, _ValuesAndStrings)[MU_DIV2(MU_COUNT_ARG(__VA_ARGS__))] ={MU_FOR_EACH_2(MU_DEFINE_ENUM_VALUE_AND_STRING, __VA_ARGS__)}; \
+const char* MU_C3(MU_, enumIdentifier,_ToString)(enumIdentifier value)                                                                                                                                                       \
+{                                                                                                                                                                                                                    \
+    for(size_t i=0;i<sizeof(MU_C2(enumIdentifier, _ValuesAndStrings))/sizeof(MU_C2(enumIdentifier, _ValuesAndStrings)[0]);i++)                                                                                             \
+    {                                                                                                                                                                                                                \
+        if(MU_C2(enumIdentifier, _ValuesAndStrings)[i].value == (int)value)                                                                                                                                             \
+        {                                                                                                                                                                                                            \
+            return MU_C2(enumIdentifier, _ValuesAndStrings)[i].valueAsString;                                                                                                                                           \
+        }                                                                                                                                                                                                            \
+    }                                                                                                                                                                                                                \
+    return "NULL";                                                                                                                                                                                                   \
+}                                                                                                                                                                                                                    \
+
+#define MU_ENUM_TO_STRING_2(enumIdentifier, value) MU_C3(MU_, enumIdentifier,_ToString)(value)
+
+/*PRI_MU_ENUM and MU_ENUM_VALUE/MU_ENUM_VALUE_2 work together as printf format specifier/argument. e.g: printf("enumValue was=%" PRI_MU_ENUM "\n", MU_ENUM_TO_STRING(enumIdentifier, enumValue));*/
+#define PRI_MU_ENUM "s%s (%d)"
+
+#define MU_ENUM_VALUE(enumIdentifier, value) "", MU_ENUM_TO_STRING(enumIdentifier, (value)), (int)(value)
+
+#define MU_ENUM_VALUE_2(enumIdentifier, value) "", MU_ENUM_TO_STRING_2(enumIdentifier, (value)), (int)(value)
+
+#define MU_DEFINE_STRUCT_FIELD(fieldType, fieldName) fieldType fieldName;
+
+/*MU_DEFINE_STRUCT allows creating a struct typedef based on a list of fields*/
+#define MU_DEFINE_STRUCT(structName, ...) typedef struct MU_C2(structName, _TAG) { MU_FOR_EACH_2(MU_DEFINE_STRUCT_FIELD, __VA_ARGS__)} structName;
+
+// this macro allows counting of elements in an array
+#define MU_COUNT_ARRAY_ITEMS(A) (sizeof(A)/sizeof((A)[0]))
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /*MACRO_UTILS_H*/
Index: azure_iot_hub_f767zi/trunk/azure_iot_sdk/deps/azure-macro-utils-c/inc/azure_macro_utils/macro_utils_generated.h
===================================================================
--- azure_iot_hub_f767zi/trunk/azure_iot_sdk/deps/azure-macro-utils-c/inc/azure_macro_utils/macro_utils_generated.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/azure_iot_sdk/deps/azure-macro-utils-c/inc/azure_macro_utils/macro_utils_generated.h	(revision 457)
@@ -0,0 +1,22477 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+/*THIS FILE IS GENERATED*/
+/*DO NOT EDIT BY HAND!!!*/
+/*instead edit macro_utils_generated.tt here: http://www.github.com/azure/azure-macro-utils-c.git */
+
+
+#ifndef MACRO_UTILS_GENERATED_H
+#define MACRO_UTILS_GENERATED_H
+
+#define MU_IFCOMMA(N) MU_C2(MU_IFCOMMA_, N)
+#define MU_IFCOMMA_0
+#define MU_IFCOMMA_2
+#define MU_IFCOMMA_4 ,
+#define MU_IFCOMMA_6 ,
+#define MU_IFCOMMA_8 ,
+#define MU_IFCOMMA_10 ,
+#define MU_IFCOMMA_12 ,
+#define MU_IFCOMMA_14 ,
+#define MU_IFCOMMA_16 ,
+#define MU_IFCOMMA_18 ,
+#define MU_IFCOMMA_20 ,
+#define MU_IFCOMMA_22 ,
+#define MU_IFCOMMA_24 ,
+#define MU_IFCOMMA_26 ,
+#define MU_IFCOMMA_28 ,
+#define MU_IFCOMMA_30 ,
+#define MU_IFCOMMA_32 ,
+#define MU_IFCOMMA_34 ,
+#define MU_IFCOMMA_36 ,
+#define MU_IFCOMMA_38 ,
+#define MU_IFCOMMA_40 ,
+#define MU_IFCOMMA_42 ,
+#define MU_IFCOMMA_44 ,
+#define MU_IFCOMMA_46 ,
+#define MU_IFCOMMA_48 ,
+#define MU_IFCOMMA_50 ,
+#define MU_IFCOMMA_52 ,
+#define MU_IFCOMMA_54 ,
+#define MU_IFCOMMA_56 ,
+#define MU_IFCOMMA_58 ,
+#define MU_IFCOMMA_60 ,
+#define MU_IFCOMMA_62 ,
+#define MU_IFCOMMA_64 ,
+#define MU_IFCOMMA_66 ,
+#define MU_IFCOMMA_68 ,
+#define MU_IFCOMMA_70 ,
+#define MU_IFCOMMA_72 ,
+#define MU_IFCOMMA_74 ,
+#define MU_IFCOMMA_76 ,
+#define MU_IFCOMMA_78 ,
+#define MU_IFCOMMA_80 ,
+#define MU_IFCOMMA_82 ,
+#define MU_IFCOMMA_84 ,
+#define MU_IFCOMMA_86 ,
+#define MU_IFCOMMA_88 ,
+#define MU_IFCOMMA_90 ,
+#define MU_IFCOMMA_92 ,
+#define MU_IFCOMMA_94 ,
+#define MU_IFCOMMA_96 ,
+#define MU_IFCOMMA_98 ,
+#define MU_IFCOMMA_100 ,
+#define MU_IFCOMMA_102 ,
+#define MU_IFCOMMA_104 ,
+#define MU_IFCOMMA_106 ,
+#define MU_IFCOMMA_108 ,
+#define MU_IFCOMMA_110 ,
+#define MU_IFCOMMA_112 ,
+#define MU_IFCOMMA_114 ,
+#define MU_IFCOMMA_116 ,
+#define MU_IFCOMMA_118 ,
+#define MU_IFCOMMA_120 ,
+#define MU_IFCOMMA_122 ,
+#define MU_IFCOMMA_124 ,
+
+#define MU_IFCOMMALOGIC(N) MU_C2(MU_IFCOMMALOGIC_, N)
+#define MU_IFCOMMALOGIC_0 
+#define MU_IFCOMMALOGIC_1 ,
+#define MU_IFCOMMALOGIC_2 ,
+#define MU_IFCOMMALOGIC_3 ,
+#define MU_IFCOMMALOGIC_4 ,
+#define MU_IFCOMMALOGIC_5 ,
+#define MU_IFCOMMALOGIC_6 ,
+#define MU_IFCOMMALOGIC_7 ,
+#define MU_IFCOMMALOGIC_8 ,
+#define MU_IFCOMMALOGIC_9 ,
+#define MU_IFCOMMALOGIC_10 ,
+#define MU_IFCOMMALOGIC_11 ,
+#define MU_IFCOMMALOGIC_12 ,
+#define MU_IFCOMMALOGIC_13 ,
+#define MU_IFCOMMALOGIC_14 ,
+#define MU_IFCOMMALOGIC_15 ,
+#define MU_IFCOMMALOGIC_16 ,
+#define MU_IFCOMMALOGIC_17 ,
+#define MU_IFCOMMALOGIC_18 ,
+#define MU_IFCOMMALOGIC_19 ,
+#define MU_IFCOMMALOGIC_20 ,
+#define MU_IFCOMMALOGIC_21 ,
+#define MU_IFCOMMALOGIC_22 ,
+#define MU_IFCOMMALOGIC_23 ,
+#define MU_IFCOMMALOGIC_24 ,
+#define MU_IFCOMMALOGIC_25 ,
+#define MU_IFCOMMALOGIC_26 ,
+#define MU_IFCOMMALOGIC_27 ,
+#define MU_IFCOMMALOGIC_28 ,
+#define MU_IFCOMMALOGIC_29 ,
+#define MU_IFCOMMALOGIC_30 ,
+#define MU_IFCOMMALOGIC_31 ,
+#define MU_IFCOMMALOGIC_32 ,
+#define MU_IFCOMMALOGIC_33 ,
+#define MU_IFCOMMALOGIC_34 ,
+#define MU_IFCOMMALOGIC_35 ,
+#define MU_IFCOMMALOGIC_36 ,
+#define MU_IFCOMMALOGIC_37 ,
+#define MU_IFCOMMALOGIC_38 ,
+#define MU_IFCOMMALOGIC_39 ,
+#define MU_IFCOMMALOGIC_40 ,
+#define MU_IFCOMMALOGIC_41 ,
+#define MU_IFCOMMALOGIC_42 ,
+#define MU_IFCOMMALOGIC_43 ,
+#define MU_IFCOMMALOGIC_44 ,
+#define MU_IFCOMMALOGIC_45 ,
+#define MU_IFCOMMALOGIC_46 ,
+#define MU_IFCOMMALOGIC_47 ,
+#define MU_IFCOMMALOGIC_48 ,
+#define MU_IFCOMMALOGIC_49 ,
+#define MU_IFCOMMALOGIC_50 ,
+#define MU_IFCOMMALOGIC_51 ,
+#define MU_IFCOMMALOGIC_52 ,
+#define MU_IFCOMMALOGIC_53 ,
+#define MU_IFCOMMALOGIC_54 ,
+#define MU_IFCOMMALOGIC_55 ,
+#define MU_IFCOMMALOGIC_56 ,
+#define MU_IFCOMMALOGIC_57 ,
+#define MU_IFCOMMALOGIC_58 ,
+#define MU_IFCOMMALOGIC_59 ,
+#define MU_IFCOMMALOGIC_60 ,
+#define MU_IFCOMMALOGIC_61 ,
+#define MU_IFCOMMALOGIC_62 ,
+#define MU_IFCOMMALOGIC_63 ,
+#define MU_IFCOMMALOGIC_64 ,
+#define MU_IFCOMMALOGIC_65 ,
+#define MU_IFCOMMALOGIC_66 ,
+#define MU_IFCOMMALOGIC_67 ,
+#define MU_IFCOMMALOGIC_68 ,
+#define MU_IFCOMMALOGIC_69 ,
+#define MU_IFCOMMALOGIC_70 ,
+#define MU_IFCOMMALOGIC_71 ,
+#define MU_IFCOMMALOGIC_72 ,
+#define MU_IFCOMMALOGIC_73 ,
+#define MU_IFCOMMALOGIC_74 ,
+#define MU_IFCOMMALOGIC_75 ,
+#define MU_IFCOMMALOGIC_76 ,
+#define MU_IFCOMMALOGIC_77 ,
+#define MU_IFCOMMALOGIC_78 ,
+#define MU_IFCOMMALOGIC_79 ,
+#define MU_IFCOMMALOGIC_80 ,
+#define MU_IFCOMMALOGIC_81 ,
+#define MU_IFCOMMALOGIC_82 ,
+#define MU_IFCOMMALOGIC_83 ,
+#define MU_IFCOMMALOGIC_84 ,
+#define MU_IFCOMMALOGIC_85 ,
+#define MU_IFCOMMALOGIC_86 ,
+#define MU_IFCOMMALOGIC_87 ,
+#define MU_IFCOMMALOGIC_88 ,
+#define MU_IFCOMMALOGIC_89 ,
+#define MU_IFCOMMALOGIC_90 ,
+#define MU_IFCOMMALOGIC_91 ,
+#define MU_IFCOMMALOGIC_92 ,
+#define MU_IFCOMMALOGIC_93 ,
+#define MU_IFCOMMALOGIC_94 ,
+#define MU_IFCOMMALOGIC_95 ,
+#define MU_IFCOMMALOGIC_96 ,
+#define MU_IFCOMMALOGIC_97 ,
+#define MU_IFCOMMALOGIC_98 ,
+#define MU_IFCOMMALOGIC_99 ,
+#define MU_IFCOMMALOGIC_100 ,
+#define MU_IFCOMMALOGIC_101 ,
+#define MU_IFCOMMALOGIC_102 ,
+#define MU_IFCOMMALOGIC_103 ,
+#define MU_IFCOMMALOGIC_104 ,
+#define MU_IFCOMMALOGIC_105 ,
+#define MU_IFCOMMALOGIC_106 ,
+#define MU_IFCOMMALOGIC_107 ,
+#define MU_IFCOMMALOGIC_108 ,
+#define MU_IFCOMMALOGIC_109 ,
+#define MU_IFCOMMALOGIC_110 ,
+#define MU_IFCOMMALOGIC_111 ,
+#define MU_IFCOMMALOGIC_112 ,
+#define MU_IFCOMMALOGIC_113 ,
+#define MU_IFCOMMALOGIC_114 ,
+#define MU_IFCOMMALOGIC_115 ,
+#define MU_IFCOMMALOGIC_116 ,
+#define MU_IFCOMMALOGIC_117 ,
+#define MU_IFCOMMALOGIC_118 ,
+#define MU_IFCOMMALOGIC_119 ,
+#define MU_IFCOMMALOGIC_120 ,
+#define MU_IFCOMMALOGIC_121 ,
+#define MU_IFCOMMALOGIC_122 ,
+#define MU_IFCOMMALOGIC_123 ,
+#define MU_IFCOMMALOGIC_124 ,
+
+#define MU_IFCOMMA_NOFIRST(N) MU_C2(MU_IFCOMMA_NOFIRST, N)
+#define MU_IFCOMMA_NOFIRST1 
+#define MU_IFCOMMA_NOFIRST2 ,
+#define MU_IFCOMMA_NOFIRST3 ,
+#define MU_IFCOMMA_NOFIRST4 ,
+#define MU_IFCOMMA_NOFIRST5 ,
+#define MU_IFCOMMA_NOFIRST6 ,
+#define MU_IFCOMMA_NOFIRST7 ,
+#define MU_IFCOMMA_NOFIRST8 ,
+#define MU_IFCOMMA_NOFIRST9 ,
+#define MU_IFCOMMA_NOFIRST10 ,
+#define MU_IFCOMMA_NOFIRST11 ,
+#define MU_IFCOMMA_NOFIRST12 ,
+#define MU_IFCOMMA_NOFIRST13 ,
+#define MU_IFCOMMA_NOFIRST14 ,
+#define MU_IFCOMMA_NOFIRST15 ,
+#define MU_IFCOMMA_NOFIRST16 ,
+#define MU_IFCOMMA_NOFIRST17 ,
+#define MU_IFCOMMA_NOFIRST18 ,
+#define MU_IFCOMMA_NOFIRST19 ,
+#define MU_IFCOMMA_NOFIRST20 ,
+#define MU_IFCOMMA_NOFIRST21 ,
+#define MU_IFCOMMA_NOFIRST22 ,
+#define MU_IFCOMMA_NOFIRST23 ,
+#define MU_IFCOMMA_NOFIRST24 ,
+#define MU_IFCOMMA_NOFIRST25 ,
+#define MU_IFCOMMA_NOFIRST26 ,
+#define MU_IFCOMMA_NOFIRST27 ,
+#define MU_IFCOMMA_NOFIRST28 ,
+#define MU_IFCOMMA_NOFIRST29 ,
+#define MU_IFCOMMA_NOFIRST30 ,
+#define MU_IFCOMMA_NOFIRST31 ,
+#define MU_IFCOMMA_NOFIRST32 ,
+#define MU_IFCOMMA_NOFIRST33 ,
+#define MU_IFCOMMA_NOFIRST34 ,
+#define MU_IFCOMMA_NOFIRST35 ,
+#define MU_IFCOMMA_NOFIRST36 ,
+#define MU_IFCOMMA_NOFIRST37 ,
+#define MU_IFCOMMA_NOFIRST38 ,
+#define MU_IFCOMMA_NOFIRST39 ,
+#define MU_IFCOMMA_NOFIRST40 ,
+#define MU_IFCOMMA_NOFIRST41 ,
+#define MU_IFCOMMA_NOFIRST42 ,
+#define MU_IFCOMMA_NOFIRST43 ,
+#define MU_IFCOMMA_NOFIRST44 ,
+#define MU_IFCOMMA_NOFIRST45 ,
+#define MU_IFCOMMA_NOFIRST46 ,
+#define MU_IFCOMMA_NOFIRST47 ,
+#define MU_IFCOMMA_NOFIRST48 ,
+#define MU_IFCOMMA_NOFIRST49 ,
+#define MU_IFCOMMA_NOFIRST50 ,
+#define MU_IFCOMMA_NOFIRST51 ,
+#define MU_IFCOMMA_NOFIRST52 ,
+#define MU_IFCOMMA_NOFIRST53 ,
+#define MU_IFCOMMA_NOFIRST54 ,
+#define MU_IFCOMMA_NOFIRST55 ,
+#define MU_IFCOMMA_NOFIRST56 ,
+#define MU_IFCOMMA_NOFIRST57 ,
+#define MU_IFCOMMA_NOFIRST58 ,
+#define MU_IFCOMMA_NOFIRST59 ,
+#define MU_IFCOMMA_NOFIRST60 ,
+#define MU_IFCOMMA_NOFIRST61 ,
+#define MU_IFCOMMA_NOFIRST62 ,
+#define MU_IFCOMMA_NOFIRST63 ,
+#define MU_IFCOMMA_NOFIRST64 ,
+#define MU_IFCOMMA_NOFIRST65 ,
+#define MU_IFCOMMA_NOFIRST66 ,
+#define MU_IFCOMMA_NOFIRST67 ,
+#define MU_IFCOMMA_NOFIRST68 ,
+#define MU_IFCOMMA_NOFIRST69 ,
+#define MU_IFCOMMA_NOFIRST70 ,
+#define MU_IFCOMMA_NOFIRST71 ,
+#define MU_IFCOMMA_NOFIRST72 ,
+#define MU_IFCOMMA_NOFIRST73 ,
+#define MU_IFCOMMA_NOFIRST74 ,
+#define MU_IFCOMMA_NOFIRST75 ,
+#define MU_IFCOMMA_NOFIRST76 ,
+#define MU_IFCOMMA_NOFIRST77 ,
+#define MU_IFCOMMA_NOFIRST78 ,
+#define MU_IFCOMMA_NOFIRST79 ,
+#define MU_IFCOMMA_NOFIRST80 ,
+#define MU_IFCOMMA_NOFIRST81 ,
+#define MU_IFCOMMA_NOFIRST82 ,
+#define MU_IFCOMMA_NOFIRST83 ,
+#define MU_IFCOMMA_NOFIRST84 ,
+#define MU_IFCOMMA_NOFIRST85 ,
+#define MU_IFCOMMA_NOFIRST86 ,
+#define MU_IFCOMMA_NOFIRST87 ,
+#define MU_IFCOMMA_NOFIRST88 ,
+#define MU_IFCOMMA_NOFIRST89 ,
+#define MU_IFCOMMA_NOFIRST90 ,
+#define MU_IFCOMMA_NOFIRST91 ,
+#define MU_IFCOMMA_NOFIRST92 ,
+#define MU_IFCOMMA_NOFIRST93 ,
+#define MU_IFCOMMA_NOFIRST94 ,
+#define MU_IFCOMMA_NOFIRST95 ,
+#define MU_IFCOMMA_NOFIRST96 ,
+#define MU_IFCOMMA_NOFIRST97 ,
+#define MU_IFCOMMA_NOFIRST98 ,
+#define MU_IFCOMMA_NOFIRST99 ,
+#define MU_IFCOMMA_NOFIRST100 ,
+#define MU_IFCOMMA_NOFIRST101 ,
+#define MU_IFCOMMA_NOFIRST102 ,
+#define MU_IFCOMMA_NOFIRST103 ,
+#define MU_IFCOMMA_NOFIRST104 ,
+#define MU_IFCOMMA_NOFIRST105 ,
+#define MU_IFCOMMA_NOFIRST106 ,
+#define MU_IFCOMMA_NOFIRST107 ,
+#define MU_IFCOMMA_NOFIRST108 ,
+#define MU_IFCOMMA_NOFIRST109 ,
+#define MU_IFCOMMA_NOFIRST110 ,
+#define MU_IFCOMMA_NOFIRST111 ,
+#define MU_IFCOMMA_NOFIRST112 ,
+#define MU_IFCOMMA_NOFIRST113 ,
+#define MU_IFCOMMA_NOFIRST114 ,
+#define MU_IFCOMMA_NOFIRST115 ,
+#define MU_IFCOMMA_NOFIRST116 ,
+#define MU_IFCOMMA_NOFIRST117 ,
+#define MU_IFCOMMA_NOFIRST118 ,
+#define MU_IFCOMMA_NOFIRST119 ,
+#define MU_IFCOMMA_NOFIRST120 ,
+#define MU_IFCOMMA_NOFIRST121 ,
+#define MU_IFCOMMA_NOFIRST122 ,
+#define MU_IFCOMMA_NOFIRST123 ,
+#define MU_IFCOMMA_NOFIRST124 ,
+
+#define MU_DEC(x) MU_C2(MU_DEC,x)
+#define MU_DEC2048 2047
+#define MU_DEC2047 2046
+#define MU_DEC2046 2045
+#define MU_DEC2045 2044
+#define MU_DEC2044 2043
+#define MU_DEC2043 2042
+#define MU_DEC2042 2041
+#define MU_DEC2041 2040
+#define MU_DEC2040 2039
+#define MU_DEC2039 2038
+#define MU_DEC2038 2037
+#define MU_DEC2037 2036
+#define MU_DEC2036 2035
+#define MU_DEC2035 2034
+#define MU_DEC2034 2033
+#define MU_DEC2033 2032
+#define MU_DEC2032 2031
+#define MU_DEC2031 2030
+#define MU_DEC2030 2029
+#define MU_DEC2029 2028
+#define MU_DEC2028 2027
+#define MU_DEC2027 2026
+#define MU_DEC2026 2025
+#define MU_DEC2025 2024
+#define MU_DEC2024 2023
+#define MU_DEC2023 2022
+#define MU_DEC2022 2021
+#define MU_DEC2021 2020
+#define MU_DEC2020 2019
+#define MU_DEC2019 2018
+#define MU_DEC2018 2017
+#define MU_DEC2017 2016
+#define MU_DEC2016 2015
+#define MU_DEC2015 2014
+#define MU_DEC2014 2013
+#define MU_DEC2013 2012
+#define MU_DEC2012 2011
+#define MU_DEC2011 2010
+#define MU_DEC2010 2009
+#define MU_DEC2009 2008
+#define MU_DEC2008 2007
+#define MU_DEC2007 2006
+#define MU_DEC2006 2005
+#define MU_DEC2005 2004
+#define MU_DEC2004 2003
+#define MU_DEC2003 2002
+#define MU_DEC2002 2001
+#define MU_DEC2001 2000
+#define MU_DEC2000 1999
+#define MU_DEC1999 1998
+#define MU_DEC1998 1997
+#define MU_DEC1997 1996
+#define MU_DEC1996 1995
+#define MU_DEC1995 1994
+#define MU_DEC1994 1993
+#define MU_DEC1993 1992
+#define MU_DEC1992 1991
+#define MU_DEC1991 1990
+#define MU_DEC1990 1989
+#define MU_DEC1989 1988
+#define MU_DEC1988 1987
+#define MU_DEC1987 1986
+#define MU_DEC1986 1985
+#define MU_DEC1985 1984
+#define MU_DEC1984 1983
+#define MU_DEC1983 1982
+#define MU_DEC1982 1981
+#define MU_DEC1981 1980
+#define MU_DEC1980 1979
+#define MU_DEC1979 1978
+#define MU_DEC1978 1977
+#define MU_DEC1977 1976
+#define MU_DEC1976 1975
+#define MU_DEC1975 1974
+#define MU_DEC1974 1973
+#define MU_DEC1973 1972
+#define MU_DEC1972 1971
+#define MU_DEC1971 1970
+#define MU_DEC1970 1969
+#define MU_DEC1969 1968
+#define MU_DEC1968 1967
+#define MU_DEC1967 1966
+#define MU_DEC1966 1965
+#define MU_DEC1965 1964
+#define MU_DEC1964 1963
+#define MU_DEC1963 1962
+#define MU_DEC1962 1961
+#define MU_DEC1961 1960
+#define MU_DEC1960 1959
+#define MU_DEC1959 1958
+#define MU_DEC1958 1957
+#define MU_DEC1957 1956
+#define MU_DEC1956 1955
+#define MU_DEC1955 1954
+#define MU_DEC1954 1953
+#define MU_DEC1953 1952
+#define MU_DEC1952 1951
+#define MU_DEC1951 1950
+#define MU_DEC1950 1949
+#define MU_DEC1949 1948
+#define MU_DEC1948 1947
+#define MU_DEC1947 1946
+#define MU_DEC1946 1945
+#define MU_DEC1945 1944
+#define MU_DEC1944 1943
+#define MU_DEC1943 1942
+#define MU_DEC1942 1941
+#define MU_DEC1941 1940
+#define MU_DEC1940 1939
+#define MU_DEC1939 1938
+#define MU_DEC1938 1937
+#define MU_DEC1937 1936
+#define MU_DEC1936 1935
+#define MU_DEC1935 1934
+#define MU_DEC1934 1933
+#define MU_DEC1933 1932
+#define MU_DEC1932 1931
+#define MU_DEC1931 1930
+#define MU_DEC1930 1929
+#define MU_DEC1929 1928
+#define MU_DEC1928 1927
+#define MU_DEC1927 1926
+#define MU_DEC1926 1925
+#define MU_DEC1925 1924
+#define MU_DEC1924 1923
+#define MU_DEC1923 1922
+#define MU_DEC1922 1921
+#define MU_DEC1921 1920
+#define MU_DEC1920 1919
+#define MU_DEC1919 1918
+#define MU_DEC1918 1917
+#define MU_DEC1917 1916
+#define MU_DEC1916 1915
+#define MU_DEC1915 1914
+#define MU_DEC1914 1913
+#define MU_DEC1913 1912
+#define MU_DEC1912 1911
+#define MU_DEC1911 1910
+#define MU_DEC1910 1909
+#define MU_DEC1909 1908
+#define MU_DEC1908 1907
+#define MU_DEC1907 1906
+#define MU_DEC1906 1905
+#define MU_DEC1905 1904
+#define MU_DEC1904 1903
+#define MU_DEC1903 1902
+#define MU_DEC1902 1901
+#define MU_DEC1901 1900
+#define MU_DEC1900 1899
+#define MU_DEC1899 1898
+#define MU_DEC1898 1897
+#define MU_DEC1897 1896
+#define MU_DEC1896 1895
+#define MU_DEC1895 1894
+#define MU_DEC1894 1893
+#define MU_DEC1893 1892
+#define MU_DEC1892 1891
+#define MU_DEC1891 1890
+#define MU_DEC1890 1889
+#define MU_DEC1889 1888
+#define MU_DEC1888 1887
+#define MU_DEC1887 1886
+#define MU_DEC1886 1885
+#define MU_DEC1885 1884
+#define MU_DEC1884 1883
+#define MU_DEC1883 1882
+#define MU_DEC1882 1881
+#define MU_DEC1881 1880
+#define MU_DEC1880 1879
+#define MU_DEC1879 1878
+#define MU_DEC1878 1877
+#define MU_DEC1877 1876
+#define MU_DEC1876 1875
+#define MU_DEC1875 1874
+#define MU_DEC1874 1873
+#define MU_DEC1873 1872
+#define MU_DEC1872 1871
+#define MU_DEC1871 1870
+#define MU_DEC1870 1869
+#define MU_DEC1869 1868
+#define MU_DEC1868 1867
+#define MU_DEC1867 1866
+#define MU_DEC1866 1865
+#define MU_DEC1865 1864
+#define MU_DEC1864 1863
+#define MU_DEC1863 1862
+#define MU_DEC1862 1861
+#define MU_DEC1861 1860
+#define MU_DEC1860 1859
+#define MU_DEC1859 1858
+#define MU_DEC1858 1857
+#define MU_DEC1857 1856
+#define MU_DEC1856 1855
+#define MU_DEC1855 1854
+#define MU_DEC1854 1853
+#define MU_DEC1853 1852
+#define MU_DEC1852 1851
+#define MU_DEC1851 1850
+#define MU_DEC1850 1849
+#define MU_DEC1849 1848
+#define MU_DEC1848 1847
+#define MU_DEC1847 1846
+#define MU_DEC1846 1845
+#define MU_DEC1845 1844
+#define MU_DEC1844 1843
+#define MU_DEC1843 1842
+#define MU_DEC1842 1841
+#define MU_DEC1841 1840
+#define MU_DEC1840 1839
+#define MU_DEC1839 1838
+#define MU_DEC1838 1837
+#define MU_DEC1837 1836
+#define MU_DEC1836 1835
+#define MU_DEC1835 1834
+#define MU_DEC1834 1833
+#define MU_DEC1833 1832
+#define MU_DEC1832 1831
+#define MU_DEC1831 1830
+#define MU_DEC1830 1829
+#define MU_DEC1829 1828
+#define MU_DEC1828 1827
+#define MU_DEC1827 1826
+#define MU_DEC1826 1825
+#define MU_DEC1825 1824
+#define MU_DEC1824 1823
+#define MU_DEC1823 1822
+#define MU_DEC1822 1821
+#define MU_DEC1821 1820
+#define MU_DEC1820 1819
+#define MU_DEC1819 1818
+#define MU_DEC1818 1817
+#define MU_DEC1817 1816
+#define MU_DEC1816 1815
+#define MU_DEC1815 1814
+#define MU_DEC1814 1813
+#define MU_DEC1813 1812
+#define MU_DEC1812 1811
+#define MU_DEC1811 1810
+#define MU_DEC1810 1809
+#define MU_DEC1809 1808
+#define MU_DEC1808 1807
+#define MU_DEC1807 1806
+#define MU_DEC1806 1805
+#define MU_DEC1805 1804
+#define MU_DEC1804 1803
+#define MU_DEC1803 1802
+#define MU_DEC1802 1801
+#define MU_DEC1801 1800
+#define MU_DEC1800 1799
+#define MU_DEC1799 1798
+#define MU_DEC1798 1797
+#define MU_DEC1797 1796
+#define MU_DEC1796 1795
+#define MU_DEC1795 1794
+#define MU_DEC1794 1793
+#define MU_DEC1793 1792
+#define MU_DEC1792 1791
+#define MU_DEC1791 1790
+#define MU_DEC1790 1789
+#define MU_DEC1789 1788
+#define MU_DEC1788 1787
+#define MU_DEC1787 1786
+#define MU_DEC1786 1785
+#define MU_DEC1785 1784
+#define MU_DEC1784 1783
+#define MU_DEC1783 1782
+#define MU_DEC1782 1781
+#define MU_DEC1781 1780
+#define MU_DEC1780 1779
+#define MU_DEC1779 1778
+#define MU_DEC1778 1777
+#define MU_DEC1777 1776
+#define MU_DEC1776 1775
+#define MU_DEC1775 1774
+#define MU_DEC1774 1773
+#define MU_DEC1773 1772
+#define MU_DEC1772 1771
+#define MU_DEC1771 1770
+#define MU_DEC1770 1769
+#define MU_DEC1769 1768
+#define MU_DEC1768 1767
+#define MU_DEC1767 1766
+#define MU_DEC1766 1765
+#define MU_DEC1765 1764
+#define MU_DEC1764 1763
+#define MU_DEC1763 1762
+#define MU_DEC1762 1761
+#define MU_DEC1761 1760
+#define MU_DEC1760 1759
+#define MU_DEC1759 1758
+#define MU_DEC1758 1757
+#define MU_DEC1757 1756
+#define MU_DEC1756 1755
+#define MU_DEC1755 1754
+#define MU_DEC1754 1753
+#define MU_DEC1753 1752
+#define MU_DEC1752 1751
+#define MU_DEC1751 1750
+#define MU_DEC1750 1749
+#define MU_DEC1749 1748
+#define MU_DEC1748 1747
+#define MU_DEC1747 1746
+#define MU_DEC1746 1745
+#define MU_DEC1745 1744
+#define MU_DEC1744 1743
+#define MU_DEC1743 1742
+#define MU_DEC1742 1741
+#define MU_DEC1741 1740
+#define MU_DEC1740 1739
+#define MU_DEC1739 1738
+#define MU_DEC1738 1737
+#define MU_DEC1737 1736
+#define MU_DEC1736 1735
+#define MU_DEC1735 1734
+#define MU_DEC1734 1733
+#define MU_DEC1733 1732
+#define MU_DEC1732 1731
+#define MU_DEC1731 1730
+#define MU_DEC1730 1729
+#define MU_DEC1729 1728
+#define MU_DEC1728 1727
+#define MU_DEC1727 1726
+#define MU_DEC1726 1725
+#define MU_DEC1725 1724
+#define MU_DEC1724 1723
+#define MU_DEC1723 1722
+#define MU_DEC1722 1721
+#define MU_DEC1721 1720
+#define MU_DEC1720 1719
+#define MU_DEC1719 1718
+#define MU_DEC1718 1717
+#define MU_DEC1717 1716
+#define MU_DEC1716 1715
+#define MU_DEC1715 1714
+#define MU_DEC1714 1713
+#define MU_DEC1713 1712
+#define MU_DEC1712 1711
+#define MU_DEC1711 1710
+#define MU_DEC1710 1709
+#define MU_DEC1709 1708
+#define MU_DEC1708 1707
+#define MU_DEC1707 1706
+#define MU_DEC1706 1705
+#define MU_DEC1705 1704
+#define MU_DEC1704 1703
+#define MU_DEC1703 1702
+#define MU_DEC1702 1701
+#define MU_DEC1701 1700
+#define MU_DEC1700 1699
+#define MU_DEC1699 1698
+#define MU_DEC1698 1697
+#define MU_DEC1697 1696
+#define MU_DEC1696 1695
+#define MU_DEC1695 1694
+#define MU_DEC1694 1693
+#define MU_DEC1693 1692
+#define MU_DEC1692 1691
+#define MU_DEC1691 1690
+#define MU_DEC1690 1689
+#define MU_DEC1689 1688
+#define MU_DEC1688 1687
+#define MU_DEC1687 1686
+#define MU_DEC1686 1685
+#define MU_DEC1685 1684
+#define MU_DEC1684 1683
+#define MU_DEC1683 1682
+#define MU_DEC1682 1681
+#define MU_DEC1681 1680
+#define MU_DEC1680 1679
+#define MU_DEC1679 1678
+#define MU_DEC1678 1677
+#define MU_DEC1677 1676
+#define MU_DEC1676 1675
+#define MU_DEC1675 1674
+#define MU_DEC1674 1673
+#define MU_DEC1673 1672
+#define MU_DEC1672 1671
+#define MU_DEC1671 1670
+#define MU_DEC1670 1669
+#define MU_DEC1669 1668
+#define MU_DEC1668 1667
+#define MU_DEC1667 1666
+#define MU_DEC1666 1665
+#define MU_DEC1665 1664
+#define MU_DEC1664 1663
+#define MU_DEC1663 1662
+#define MU_DEC1662 1661
+#define MU_DEC1661 1660
+#define MU_DEC1660 1659
+#define MU_DEC1659 1658
+#define MU_DEC1658 1657
+#define MU_DEC1657 1656
+#define MU_DEC1656 1655
+#define MU_DEC1655 1654
+#define MU_DEC1654 1653
+#define MU_DEC1653 1652
+#define MU_DEC1652 1651
+#define MU_DEC1651 1650
+#define MU_DEC1650 1649
+#define MU_DEC1649 1648
+#define MU_DEC1648 1647
+#define MU_DEC1647 1646
+#define MU_DEC1646 1645
+#define MU_DEC1645 1644
+#define MU_DEC1644 1643
+#define MU_DEC1643 1642
+#define MU_DEC1642 1641
+#define MU_DEC1641 1640
+#define MU_DEC1640 1639
+#define MU_DEC1639 1638
+#define MU_DEC1638 1637
+#define MU_DEC1637 1636
+#define MU_DEC1636 1635
+#define MU_DEC1635 1634
+#define MU_DEC1634 1633
+#define MU_DEC1633 1632
+#define MU_DEC1632 1631
+#define MU_DEC1631 1630
+#define MU_DEC1630 1629
+#define MU_DEC1629 1628
+#define MU_DEC1628 1627
+#define MU_DEC1627 1626
+#define MU_DEC1626 1625
+#define MU_DEC1625 1624
+#define MU_DEC1624 1623
+#define MU_DEC1623 1622
+#define MU_DEC1622 1621
+#define MU_DEC1621 1620
+#define MU_DEC1620 1619
+#define MU_DEC1619 1618
+#define MU_DEC1618 1617
+#define MU_DEC1617 1616
+#define MU_DEC1616 1615
+#define MU_DEC1615 1614
+#define MU_DEC1614 1613
+#define MU_DEC1613 1612
+#define MU_DEC1612 1611
+#define MU_DEC1611 1610
+#define MU_DEC1610 1609
+#define MU_DEC1609 1608
+#define MU_DEC1608 1607
+#define MU_DEC1607 1606
+#define MU_DEC1606 1605
+#define MU_DEC1605 1604
+#define MU_DEC1604 1603
+#define MU_DEC1603 1602
+#define MU_DEC1602 1601
+#define MU_DEC1601 1600
+#define MU_DEC1600 1599
+#define MU_DEC1599 1598
+#define MU_DEC1598 1597
+#define MU_DEC1597 1596
+#define MU_DEC1596 1595
+#define MU_DEC1595 1594
+#define MU_DEC1594 1593
+#define MU_DEC1593 1592
+#define MU_DEC1592 1591
+#define MU_DEC1591 1590
+#define MU_DEC1590 1589
+#define MU_DEC1589 1588
+#define MU_DEC1588 1587
+#define MU_DEC1587 1586
+#define MU_DEC1586 1585
+#define MU_DEC1585 1584
+#define MU_DEC1584 1583
+#define MU_DEC1583 1582
+#define MU_DEC1582 1581
+#define MU_DEC1581 1580
+#define MU_DEC1580 1579
+#define MU_DEC1579 1578
+#define MU_DEC1578 1577
+#define MU_DEC1577 1576
+#define MU_DEC1576 1575
+#define MU_DEC1575 1574
+#define MU_DEC1574 1573
+#define MU_DEC1573 1572
+#define MU_DEC1572 1571
+#define MU_DEC1571 1570
+#define MU_DEC1570 1569
+#define MU_DEC1569 1568
+#define MU_DEC1568 1567
+#define MU_DEC1567 1566
+#define MU_DEC1566 1565
+#define MU_DEC1565 1564
+#define MU_DEC1564 1563
+#define MU_DEC1563 1562
+#define MU_DEC1562 1561
+#define MU_DEC1561 1560
+#define MU_DEC1560 1559
+#define MU_DEC1559 1558
+#define MU_DEC1558 1557
+#define MU_DEC1557 1556
+#define MU_DEC1556 1555
+#define MU_DEC1555 1554
+#define MU_DEC1554 1553
+#define MU_DEC1553 1552
+#define MU_DEC1552 1551
+#define MU_DEC1551 1550
+#define MU_DEC1550 1549
+#define MU_DEC1549 1548
+#define MU_DEC1548 1547
+#define MU_DEC1547 1546
+#define MU_DEC1546 1545
+#define MU_DEC1545 1544
+#define MU_DEC1544 1543
+#define MU_DEC1543 1542
+#define MU_DEC1542 1541
+#define MU_DEC1541 1540
+#define MU_DEC1540 1539
+#define MU_DEC1539 1538
+#define MU_DEC1538 1537
+#define MU_DEC1537 1536
+#define MU_DEC1536 1535
+#define MU_DEC1535 1534
+#define MU_DEC1534 1533
+#define MU_DEC1533 1532
+#define MU_DEC1532 1531
+#define MU_DEC1531 1530
+#define MU_DEC1530 1529
+#define MU_DEC1529 1528
+#define MU_DEC1528 1527
+#define MU_DEC1527 1526
+#define MU_DEC1526 1525
+#define MU_DEC1525 1524
+#define MU_DEC1524 1523
+#define MU_DEC1523 1522
+#define MU_DEC1522 1521
+#define MU_DEC1521 1520
+#define MU_DEC1520 1519
+#define MU_DEC1519 1518
+#define MU_DEC1518 1517
+#define MU_DEC1517 1516
+#define MU_DEC1516 1515
+#define MU_DEC1515 1514
+#define MU_DEC1514 1513
+#define MU_DEC1513 1512
+#define MU_DEC1512 1511
+#define MU_DEC1511 1510
+#define MU_DEC1510 1509
+#define MU_DEC1509 1508
+#define MU_DEC1508 1507
+#define MU_DEC1507 1506
+#define MU_DEC1506 1505
+#define MU_DEC1505 1504
+#define MU_DEC1504 1503
+#define MU_DEC1503 1502
+#define MU_DEC1502 1501
+#define MU_DEC1501 1500
+#define MU_DEC1500 1499
+#define MU_DEC1499 1498
+#define MU_DEC1498 1497
+#define MU_DEC1497 1496
+#define MU_DEC1496 1495
+#define MU_DEC1495 1494
+#define MU_DEC1494 1493
+#define MU_DEC1493 1492
+#define MU_DEC1492 1491
+#define MU_DEC1491 1490
+#define MU_DEC1490 1489
+#define MU_DEC1489 1488
+#define MU_DEC1488 1487
+#define MU_DEC1487 1486
+#define MU_DEC1486 1485
+#define MU_DEC1485 1484
+#define MU_DEC1484 1483
+#define MU_DEC1483 1482
+#define MU_DEC1482 1481
+#define MU_DEC1481 1480
+#define MU_DEC1480 1479
+#define MU_DEC1479 1478
+#define MU_DEC1478 1477
+#define MU_DEC1477 1476
+#define MU_DEC1476 1475
+#define MU_DEC1475 1474
+#define MU_DEC1474 1473
+#define MU_DEC1473 1472
+#define MU_DEC1472 1471
+#define MU_DEC1471 1470
+#define MU_DEC1470 1469
+#define MU_DEC1469 1468
+#define MU_DEC1468 1467
+#define MU_DEC1467 1466
+#define MU_DEC1466 1465
+#define MU_DEC1465 1464
+#define MU_DEC1464 1463
+#define MU_DEC1463 1462
+#define MU_DEC1462 1461
+#define MU_DEC1461 1460
+#define MU_DEC1460 1459
+#define MU_DEC1459 1458
+#define MU_DEC1458 1457
+#define MU_DEC1457 1456
+#define MU_DEC1456 1455
+#define MU_DEC1455 1454
+#define MU_DEC1454 1453
+#define MU_DEC1453 1452
+#define MU_DEC1452 1451
+#define MU_DEC1451 1450
+#define MU_DEC1450 1449
+#define MU_DEC1449 1448
+#define MU_DEC1448 1447
+#define MU_DEC1447 1446
+#define MU_DEC1446 1445
+#define MU_DEC1445 1444
+#define MU_DEC1444 1443
+#define MU_DEC1443 1442
+#define MU_DEC1442 1441
+#define MU_DEC1441 1440
+#define MU_DEC1440 1439
+#define MU_DEC1439 1438
+#define MU_DEC1438 1437
+#define MU_DEC1437 1436
+#define MU_DEC1436 1435
+#define MU_DEC1435 1434
+#define MU_DEC1434 1433
+#define MU_DEC1433 1432
+#define MU_DEC1432 1431
+#define MU_DEC1431 1430
+#define MU_DEC1430 1429
+#define MU_DEC1429 1428
+#define MU_DEC1428 1427
+#define MU_DEC1427 1426
+#define MU_DEC1426 1425
+#define MU_DEC1425 1424
+#define MU_DEC1424 1423
+#define MU_DEC1423 1422
+#define MU_DEC1422 1421
+#define MU_DEC1421 1420
+#define MU_DEC1420 1419
+#define MU_DEC1419 1418
+#define MU_DEC1418 1417
+#define MU_DEC1417 1416
+#define MU_DEC1416 1415
+#define MU_DEC1415 1414
+#define MU_DEC1414 1413
+#define MU_DEC1413 1412
+#define MU_DEC1412 1411
+#define MU_DEC1411 1410
+#define MU_DEC1410 1409
+#define MU_DEC1409 1408
+#define MU_DEC1408 1407
+#define MU_DEC1407 1406
+#define MU_DEC1406 1405
+#define MU_DEC1405 1404
+#define MU_DEC1404 1403
+#define MU_DEC1403 1402
+#define MU_DEC1402 1401
+#define MU_DEC1401 1400
+#define MU_DEC1400 1399
+#define MU_DEC1399 1398
+#define MU_DEC1398 1397
+#define MU_DEC1397 1396
+#define MU_DEC1396 1395
+#define MU_DEC1395 1394
+#define MU_DEC1394 1393
+#define MU_DEC1393 1392
+#define MU_DEC1392 1391
+#define MU_DEC1391 1390
+#define MU_DEC1390 1389
+#define MU_DEC1389 1388
+#define MU_DEC1388 1387
+#define MU_DEC1387 1386
+#define MU_DEC1386 1385
+#define MU_DEC1385 1384
+#define MU_DEC1384 1383
+#define MU_DEC1383 1382
+#define MU_DEC1382 1381
+#define MU_DEC1381 1380
+#define MU_DEC1380 1379
+#define MU_DEC1379 1378
+#define MU_DEC1378 1377
+#define MU_DEC1377 1376
+#define MU_DEC1376 1375
+#define MU_DEC1375 1374
+#define MU_DEC1374 1373
+#define MU_DEC1373 1372
+#define MU_DEC1372 1371
+#define MU_DEC1371 1370
+#define MU_DEC1370 1369
+#define MU_DEC1369 1368
+#define MU_DEC1368 1367
+#define MU_DEC1367 1366
+#define MU_DEC1366 1365
+#define MU_DEC1365 1364
+#define MU_DEC1364 1363
+#define MU_DEC1363 1362
+#define MU_DEC1362 1361
+#define MU_DEC1361 1360
+#define MU_DEC1360 1359
+#define MU_DEC1359 1358
+#define MU_DEC1358 1357
+#define MU_DEC1357 1356
+#define MU_DEC1356 1355
+#define MU_DEC1355 1354
+#define MU_DEC1354 1353
+#define MU_DEC1353 1352
+#define MU_DEC1352 1351
+#define MU_DEC1351 1350
+#define MU_DEC1350 1349
+#define MU_DEC1349 1348
+#define MU_DEC1348 1347
+#define MU_DEC1347 1346
+#define MU_DEC1346 1345
+#define MU_DEC1345 1344
+#define MU_DEC1344 1343
+#define MU_DEC1343 1342
+#define MU_DEC1342 1341
+#define MU_DEC1341 1340
+#define MU_DEC1340 1339
+#define MU_DEC1339 1338
+#define MU_DEC1338 1337
+#define MU_DEC1337 1336
+#define MU_DEC1336 1335
+#define MU_DEC1335 1334
+#define MU_DEC1334 1333
+#define MU_DEC1333 1332
+#define MU_DEC1332 1331
+#define MU_DEC1331 1330
+#define MU_DEC1330 1329
+#define MU_DEC1329 1328
+#define MU_DEC1328 1327
+#define MU_DEC1327 1326
+#define MU_DEC1326 1325
+#define MU_DEC1325 1324
+#define MU_DEC1324 1323
+#define MU_DEC1323 1322
+#define MU_DEC1322 1321
+#define MU_DEC1321 1320
+#define MU_DEC1320 1319
+#define MU_DEC1319 1318
+#define MU_DEC1318 1317
+#define MU_DEC1317 1316
+#define MU_DEC1316 1315
+#define MU_DEC1315 1314
+#define MU_DEC1314 1313
+#define MU_DEC1313 1312
+#define MU_DEC1312 1311
+#define MU_DEC1311 1310
+#define MU_DEC1310 1309
+#define MU_DEC1309 1308
+#define MU_DEC1308 1307
+#define MU_DEC1307 1306
+#define MU_DEC1306 1305
+#define MU_DEC1305 1304
+#define MU_DEC1304 1303
+#define MU_DEC1303 1302
+#define MU_DEC1302 1301
+#define MU_DEC1301 1300
+#define MU_DEC1300 1299
+#define MU_DEC1299 1298
+#define MU_DEC1298 1297
+#define MU_DEC1297 1296
+#define MU_DEC1296 1295
+#define MU_DEC1295 1294
+#define MU_DEC1294 1293
+#define MU_DEC1293 1292
+#define MU_DEC1292 1291
+#define MU_DEC1291 1290
+#define MU_DEC1290 1289
+#define MU_DEC1289 1288
+#define MU_DEC1288 1287
+#define MU_DEC1287 1286
+#define MU_DEC1286 1285
+#define MU_DEC1285 1284
+#define MU_DEC1284 1283
+#define MU_DEC1283 1282
+#define MU_DEC1282 1281
+#define MU_DEC1281 1280
+#define MU_DEC1280 1279
+#define MU_DEC1279 1278
+#define MU_DEC1278 1277
+#define MU_DEC1277 1276
+#define MU_DEC1276 1275
+#define MU_DEC1275 1274
+#define MU_DEC1274 1273
+#define MU_DEC1273 1272
+#define MU_DEC1272 1271
+#define MU_DEC1271 1270
+#define MU_DEC1270 1269
+#define MU_DEC1269 1268
+#define MU_DEC1268 1267
+#define MU_DEC1267 1266
+#define MU_DEC1266 1265
+#define MU_DEC1265 1264
+#define MU_DEC1264 1263
+#define MU_DEC1263 1262
+#define MU_DEC1262 1261
+#define MU_DEC1261 1260
+#define MU_DEC1260 1259
+#define MU_DEC1259 1258
+#define MU_DEC1258 1257
+#define MU_DEC1257 1256
+#define MU_DEC1256 1255
+#define MU_DEC1255 1254
+#define MU_DEC1254 1253
+#define MU_DEC1253 1252
+#define MU_DEC1252 1251
+#define MU_DEC1251 1250
+#define MU_DEC1250 1249
+#define MU_DEC1249 1248
+#define MU_DEC1248 1247
+#define MU_DEC1247 1246
+#define MU_DEC1246 1245
+#define MU_DEC1245 1244
+#define MU_DEC1244 1243
+#define MU_DEC1243 1242
+#define MU_DEC1242 1241
+#define MU_DEC1241 1240
+#define MU_DEC1240 1239
+#define MU_DEC1239 1238
+#define MU_DEC1238 1237
+#define MU_DEC1237 1236
+#define MU_DEC1236 1235
+#define MU_DEC1235 1234
+#define MU_DEC1234 1233
+#define MU_DEC1233 1232
+#define MU_DEC1232 1231
+#define MU_DEC1231 1230
+#define MU_DEC1230 1229
+#define MU_DEC1229 1228
+#define MU_DEC1228 1227
+#define MU_DEC1227 1226
+#define MU_DEC1226 1225
+#define MU_DEC1225 1224
+#define MU_DEC1224 1223
+#define MU_DEC1223 1222
+#define MU_DEC1222 1221
+#define MU_DEC1221 1220
+#define MU_DEC1220 1219
+#define MU_DEC1219 1218
+#define MU_DEC1218 1217
+#define MU_DEC1217 1216
+#define MU_DEC1216 1215
+#define MU_DEC1215 1214
+#define MU_DEC1214 1213
+#define MU_DEC1213 1212
+#define MU_DEC1212 1211
+#define MU_DEC1211 1210
+#define MU_DEC1210 1209
+#define MU_DEC1209 1208
+#define MU_DEC1208 1207
+#define MU_DEC1207 1206
+#define MU_DEC1206 1205
+#define MU_DEC1205 1204
+#define MU_DEC1204 1203
+#define MU_DEC1203 1202
+#define MU_DEC1202 1201
+#define MU_DEC1201 1200
+#define MU_DEC1200 1199
+#define MU_DEC1199 1198
+#define MU_DEC1198 1197
+#define MU_DEC1197 1196
+#define MU_DEC1196 1195
+#define MU_DEC1195 1194
+#define MU_DEC1194 1193
+#define MU_DEC1193 1192
+#define MU_DEC1192 1191
+#define MU_DEC1191 1190
+#define MU_DEC1190 1189
+#define MU_DEC1189 1188
+#define MU_DEC1188 1187
+#define MU_DEC1187 1186
+#define MU_DEC1186 1185
+#define MU_DEC1185 1184
+#define MU_DEC1184 1183
+#define MU_DEC1183 1182
+#define MU_DEC1182 1181
+#define MU_DEC1181 1180
+#define MU_DEC1180 1179
+#define MU_DEC1179 1178
+#define MU_DEC1178 1177
+#define MU_DEC1177 1176
+#define MU_DEC1176 1175
+#define MU_DEC1175 1174
+#define MU_DEC1174 1173
+#define MU_DEC1173 1172
+#define MU_DEC1172 1171
+#define MU_DEC1171 1170
+#define MU_DEC1170 1169
+#define MU_DEC1169 1168
+#define MU_DEC1168 1167
+#define MU_DEC1167 1166
+#define MU_DEC1166 1165
+#define MU_DEC1165 1164
+#define MU_DEC1164 1163
+#define MU_DEC1163 1162
+#define MU_DEC1162 1161
+#define MU_DEC1161 1160
+#define MU_DEC1160 1159
+#define MU_DEC1159 1158
+#define MU_DEC1158 1157
+#define MU_DEC1157 1156
+#define MU_DEC1156 1155
+#define MU_DEC1155 1154
+#define MU_DEC1154 1153
+#define MU_DEC1153 1152
+#define MU_DEC1152 1151
+#define MU_DEC1151 1150
+#define MU_DEC1150 1149
+#define MU_DEC1149 1148
+#define MU_DEC1148 1147
+#define MU_DEC1147 1146
+#define MU_DEC1146 1145
+#define MU_DEC1145 1144
+#define MU_DEC1144 1143
+#define MU_DEC1143 1142
+#define MU_DEC1142 1141
+#define MU_DEC1141 1140
+#define MU_DEC1140 1139
+#define MU_DEC1139 1138
+#define MU_DEC1138 1137
+#define MU_DEC1137 1136
+#define MU_DEC1136 1135
+#define MU_DEC1135 1134
+#define MU_DEC1134 1133
+#define MU_DEC1133 1132
+#define MU_DEC1132 1131
+#define MU_DEC1131 1130
+#define MU_DEC1130 1129
+#define MU_DEC1129 1128
+#define MU_DEC1128 1127
+#define MU_DEC1127 1126
+#define MU_DEC1126 1125
+#define MU_DEC1125 1124
+#define MU_DEC1124 1123
+#define MU_DEC1123 1122
+#define MU_DEC1122 1121
+#define MU_DEC1121 1120
+#define MU_DEC1120 1119
+#define MU_DEC1119 1118
+#define MU_DEC1118 1117
+#define MU_DEC1117 1116
+#define MU_DEC1116 1115
+#define MU_DEC1115 1114
+#define MU_DEC1114 1113
+#define MU_DEC1113 1112
+#define MU_DEC1112 1111
+#define MU_DEC1111 1110
+#define MU_DEC1110 1109
+#define MU_DEC1109 1108
+#define MU_DEC1108 1107
+#define MU_DEC1107 1106
+#define MU_DEC1106 1105
+#define MU_DEC1105 1104
+#define MU_DEC1104 1103
+#define MU_DEC1103 1102
+#define MU_DEC1102 1101
+#define MU_DEC1101 1100
+#define MU_DEC1100 1099
+#define MU_DEC1099 1098
+#define MU_DEC1098 1097
+#define MU_DEC1097 1096
+#define MU_DEC1096 1095
+#define MU_DEC1095 1094
+#define MU_DEC1094 1093
+#define MU_DEC1093 1092
+#define MU_DEC1092 1091
+#define MU_DEC1091 1090
+#define MU_DEC1090 1089
+#define MU_DEC1089 1088
+#define MU_DEC1088 1087
+#define MU_DEC1087 1086
+#define MU_DEC1086 1085
+#define MU_DEC1085 1084
+#define MU_DEC1084 1083
+#define MU_DEC1083 1082
+#define MU_DEC1082 1081
+#define MU_DEC1081 1080
+#define MU_DEC1080 1079
+#define MU_DEC1079 1078
+#define MU_DEC1078 1077
+#define MU_DEC1077 1076
+#define MU_DEC1076 1075
+#define MU_DEC1075 1074
+#define MU_DEC1074 1073
+#define MU_DEC1073 1072
+#define MU_DEC1072 1071
+#define MU_DEC1071 1070
+#define MU_DEC1070 1069
+#define MU_DEC1069 1068
+#define MU_DEC1068 1067
+#define MU_DEC1067 1066
+#define MU_DEC1066 1065
+#define MU_DEC1065 1064
+#define MU_DEC1064 1063
+#define MU_DEC1063 1062
+#define MU_DEC1062 1061
+#define MU_DEC1061 1060
+#define MU_DEC1060 1059
+#define MU_DEC1059 1058
+#define MU_DEC1058 1057
+#define MU_DEC1057 1056
+#define MU_DEC1056 1055
+#define MU_DEC1055 1054
+#define MU_DEC1054 1053
+#define MU_DEC1053 1052
+#define MU_DEC1052 1051
+#define MU_DEC1051 1050
+#define MU_DEC1050 1049
+#define MU_DEC1049 1048
+#define MU_DEC1048 1047
+#define MU_DEC1047 1046
+#define MU_DEC1046 1045
+#define MU_DEC1045 1044
+#define MU_DEC1044 1043
+#define MU_DEC1043 1042
+#define MU_DEC1042 1041
+#define MU_DEC1041 1040
+#define MU_DEC1040 1039
+#define MU_DEC1039 1038
+#define MU_DEC1038 1037
+#define MU_DEC1037 1036
+#define MU_DEC1036 1035
+#define MU_DEC1035 1034
+#define MU_DEC1034 1033
+#define MU_DEC1033 1032
+#define MU_DEC1032 1031
+#define MU_DEC1031 1030
+#define MU_DEC1030 1029
+#define MU_DEC1029 1028
+#define MU_DEC1028 1027
+#define MU_DEC1027 1026
+#define MU_DEC1026 1025
+#define MU_DEC1025 1024
+#define MU_DEC1024 1023
+#define MU_DEC1023 1022
+#define MU_DEC1022 1021
+#define MU_DEC1021 1020
+#define MU_DEC1020 1019
+#define MU_DEC1019 1018
+#define MU_DEC1018 1017
+#define MU_DEC1017 1016
+#define MU_DEC1016 1015
+#define MU_DEC1015 1014
+#define MU_DEC1014 1013
+#define MU_DEC1013 1012
+#define MU_DEC1012 1011
+#define MU_DEC1011 1010
+#define MU_DEC1010 1009
+#define MU_DEC1009 1008
+#define MU_DEC1008 1007
+#define MU_DEC1007 1006
+#define MU_DEC1006 1005
+#define MU_DEC1005 1004
+#define MU_DEC1004 1003
+#define MU_DEC1003 1002
+#define MU_DEC1002 1001
+#define MU_DEC1001 1000
+#define MU_DEC1000 999
+#define MU_DEC999 998
+#define MU_DEC998 997
+#define MU_DEC997 996
+#define MU_DEC996 995
+#define MU_DEC995 994
+#define MU_DEC994 993
+#define MU_DEC993 992
+#define MU_DEC992 991
+#define MU_DEC991 990
+#define MU_DEC990 989
+#define MU_DEC989 988
+#define MU_DEC988 987
+#define MU_DEC987 986
+#define MU_DEC986 985
+#define MU_DEC985 984
+#define MU_DEC984 983
+#define MU_DEC983 982
+#define MU_DEC982 981
+#define MU_DEC981 980
+#define MU_DEC980 979
+#define MU_DEC979 978
+#define MU_DEC978 977
+#define MU_DEC977 976
+#define MU_DEC976 975
+#define MU_DEC975 974
+#define MU_DEC974 973
+#define MU_DEC973 972
+#define MU_DEC972 971
+#define MU_DEC971 970
+#define MU_DEC970 969
+#define MU_DEC969 968
+#define MU_DEC968 967
+#define MU_DEC967 966
+#define MU_DEC966 965
+#define MU_DEC965 964
+#define MU_DEC964 963
+#define MU_DEC963 962
+#define MU_DEC962 961
+#define MU_DEC961 960
+#define MU_DEC960 959
+#define MU_DEC959 958
+#define MU_DEC958 957
+#define MU_DEC957 956
+#define MU_DEC956 955
+#define MU_DEC955 954
+#define MU_DEC954 953
+#define MU_DEC953 952
+#define MU_DEC952 951
+#define MU_DEC951 950
+#define MU_DEC950 949
+#define MU_DEC949 948
+#define MU_DEC948 947
+#define MU_DEC947 946
+#define MU_DEC946 945
+#define MU_DEC945 944
+#define MU_DEC944 943
+#define MU_DEC943 942
+#define MU_DEC942 941
+#define MU_DEC941 940
+#define MU_DEC940 939
+#define MU_DEC939 938
+#define MU_DEC938 937
+#define MU_DEC937 936
+#define MU_DEC936 935
+#define MU_DEC935 934
+#define MU_DEC934 933
+#define MU_DEC933 932
+#define MU_DEC932 931
+#define MU_DEC931 930
+#define MU_DEC930 929
+#define MU_DEC929 928
+#define MU_DEC928 927
+#define MU_DEC927 926
+#define MU_DEC926 925
+#define MU_DEC925 924
+#define MU_DEC924 923
+#define MU_DEC923 922
+#define MU_DEC922 921
+#define MU_DEC921 920
+#define MU_DEC920 919
+#define MU_DEC919 918
+#define MU_DEC918 917
+#define MU_DEC917 916
+#define MU_DEC916 915
+#define MU_DEC915 914
+#define MU_DEC914 913
+#define MU_DEC913 912
+#define MU_DEC912 911
+#define MU_DEC911 910
+#define MU_DEC910 909
+#define MU_DEC909 908
+#define MU_DEC908 907
+#define MU_DEC907 906
+#define MU_DEC906 905
+#define MU_DEC905 904
+#define MU_DEC904 903
+#define MU_DEC903 902
+#define MU_DEC902 901
+#define MU_DEC901 900
+#define MU_DEC900 899
+#define MU_DEC899 898
+#define MU_DEC898 897
+#define MU_DEC897 896
+#define MU_DEC896 895
+#define MU_DEC895 894
+#define MU_DEC894 893
+#define MU_DEC893 892
+#define MU_DEC892 891
+#define MU_DEC891 890
+#define MU_DEC890 889
+#define MU_DEC889 888
+#define MU_DEC888 887
+#define MU_DEC887 886
+#define MU_DEC886 885
+#define MU_DEC885 884
+#define MU_DEC884 883
+#define MU_DEC883 882
+#define MU_DEC882 881
+#define MU_DEC881 880
+#define MU_DEC880 879
+#define MU_DEC879 878
+#define MU_DEC878 877
+#define MU_DEC877 876
+#define MU_DEC876 875
+#define MU_DEC875 874
+#define MU_DEC874 873
+#define MU_DEC873 872
+#define MU_DEC872 871
+#define MU_DEC871 870
+#define MU_DEC870 869
+#define MU_DEC869 868
+#define MU_DEC868 867
+#define MU_DEC867 866
+#define MU_DEC866 865
+#define MU_DEC865 864
+#define MU_DEC864 863
+#define MU_DEC863 862
+#define MU_DEC862 861
+#define MU_DEC861 860
+#define MU_DEC860 859
+#define MU_DEC859 858
+#define MU_DEC858 857
+#define MU_DEC857 856
+#define MU_DEC856 855
+#define MU_DEC855 854
+#define MU_DEC854 853
+#define MU_DEC853 852
+#define MU_DEC852 851
+#define MU_DEC851 850
+#define MU_DEC850 849
+#define MU_DEC849 848
+#define MU_DEC848 847
+#define MU_DEC847 846
+#define MU_DEC846 845
+#define MU_DEC845 844
+#define MU_DEC844 843
+#define MU_DEC843 842
+#define MU_DEC842 841
+#define MU_DEC841 840
+#define MU_DEC840 839
+#define MU_DEC839 838
+#define MU_DEC838 837
+#define MU_DEC837 836
+#define MU_DEC836 835
+#define MU_DEC835 834
+#define MU_DEC834 833
+#define MU_DEC833 832
+#define MU_DEC832 831
+#define MU_DEC831 830
+#define MU_DEC830 829
+#define MU_DEC829 828
+#define MU_DEC828 827
+#define MU_DEC827 826
+#define MU_DEC826 825
+#define MU_DEC825 824
+#define MU_DEC824 823
+#define MU_DEC823 822
+#define MU_DEC822 821
+#define MU_DEC821 820
+#define MU_DEC820 819
+#define MU_DEC819 818
+#define MU_DEC818 817
+#define MU_DEC817 816
+#define MU_DEC816 815
+#define MU_DEC815 814
+#define MU_DEC814 813
+#define MU_DEC813 812
+#define MU_DEC812 811
+#define MU_DEC811 810
+#define MU_DEC810 809
+#define MU_DEC809 808
+#define MU_DEC808 807
+#define MU_DEC807 806
+#define MU_DEC806 805
+#define MU_DEC805 804
+#define MU_DEC804 803
+#define MU_DEC803 802
+#define MU_DEC802 801
+#define MU_DEC801 800
+#define MU_DEC800 799
+#define MU_DEC799 798
+#define MU_DEC798 797
+#define MU_DEC797 796
+#define MU_DEC796 795
+#define MU_DEC795 794
+#define MU_DEC794 793
+#define MU_DEC793 792
+#define MU_DEC792 791
+#define MU_DEC791 790
+#define MU_DEC790 789
+#define MU_DEC789 788
+#define MU_DEC788 787
+#define MU_DEC787 786
+#define MU_DEC786 785
+#define MU_DEC785 784
+#define MU_DEC784 783
+#define MU_DEC783 782
+#define MU_DEC782 781
+#define MU_DEC781 780
+#define MU_DEC780 779
+#define MU_DEC779 778
+#define MU_DEC778 777
+#define MU_DEC777 776
+#define MU_DEC776 775
+#define MU_DEC775 774
+#define MU_DEC774 773
+#define MU_DEC773 772
+#define MU_DEC772 771
+#define MU_DEC771 770
+#define MU_DEC770 769
+#define MU_DEC769 768
+#define MU_DEC768 767
+#define MU_DEC767 766
+#define MU_DEC766 765
+#define MU_DEC765 764
+#define MU_DEC764 763
+#define MU_DEC763 762
+#define MU_DEC762 761
+#define MU_DEC761 760
+#define MU_DEC760 759
+#define MU_DEC759 758
+#define MU_DEC758 757
+#define MU_DEC757 756
+#define MU_DEC756 755
+#define MU_DEC755 754
+#define MU_DEC754 753
+#define MU_DEC753 752
+#define MU_DEC752 751
+#define MU_DEC751 750
+#define MU_DEC750 749
+#define MU_DEC749 748
+#define MU_DEC748 747
+#define MU_DEC747 746
+#define MU_DEC746 745
+#define MU_DEC745 744
+#define MU_DEC744 743
+#define MU_DEC743 742
+#define MU_DEC742 741
+#define MU_DEC741 740
+#define MU_DEC740 739
+#define MU_DEC739 738
+#define MU_DEC738 737
+#define MU_DEC737 736
+#define MU_DEC736 735
+#define MU_DEC735 734
+#define MU_DEC734 733
+#define MU_DEC733 732
+#define MU_DEC732 731
+#define MU_DEC731 730
+#define MU_DEC730 729
+#define MU_DEC729 728
+#define MU_DEC728 727
+#define MU_DEC727 726
+#define MU_DEC726 725
+#define MU_DEC725 724
+#define MU_DEC724 723
+#define MU_DEC723 722
+#define MU_DEC722 721
+#define MU_DEC721 720
+#define MU_DEC720 719
+#define MU_DEC719 718
+#define MU_DEC718 717
+#define MU_DEC717 716
+#define MU_DEC716 715
+#define MU_DEC715 714
+#define MU_DEC714 713
+#define MU_DEC713 712
+#define MU_DEC712 711
+#define MU_DEC711 710
+#define MU_DEC710 709
+#define MU_DEC709 708
+#define MU_DEC708 707
+#define MU_DEC707 706
+#define MU_DEC706 705
+#define MU_DEC705 704
+#define MU_DEC704 703
+#define MU_DEC703 702
+#define MU_DEC702 701
+#define MU_DEC701 700
+#define MU_DEC700 699
+#define MU_DEC699 698
+#define MU_DEC698 697
+#define MU_DEC697 696
+#define MU_DEC696 695
+#define MU_DEC695 694
+#define MU_DEC694 693
+#define MU_DEC693 692
+#define MU_DEC692 691
+#define MU_DEC691 690
+#define MU_DEC690 689
+#define MU_DEC689 688
+#define MU_DEC688 687
+#define MU_DEC687 686
+#define MU_DEC686 685
+#define MU_DEC685 684
+#define MU_DEC684 683
+#define MU_DEC683 682
+#define MU_DEC682 681
+#define MU_DEC681 680
+#define MU_DEC680 679
+#define MU_DEC679 678
+#define MU_DEC678 677
+#define MU_DEC677 676
+#define MU_DEC676 675
+#define MU_DEC675 674
+#define MU_DEC674 673
+#define MU_DEC673 672
+#define MU_DEC672 671
+#define MU_DEC671 670
+#define MU_DEC670 669
+#define MU_DEC669 668
+#define MU_DEC668 667
+#define MU_DEC667 666
+#define MU_DEC666 665
+#define MU_DEC665 664
+#define MU_DEC664 663
+#define MU_DEC663 662
+#define MU_DEC662 661
+#define MU_DEC661 660
+#define MU_DEC660 659
+#define MU_DEC659 658
+#define MU_DEC658 657
+#define MU_DEC657 656
+#define MU_DEC656 655
+#define MU_DEC655 654
+#define MU_DEC654 653
+#define MU_DEC653 652
+#define MU_DEC652 651
+#define MU_DEC651 650
+#define MU_DEC650 649
+#define MU_DEC649 648
+#define MU_DEC648 647
+#define MU_DEC647 646
+#define MU_DEC646 645
+#define MU_DEC645 644
+#define MU_DEC644 643
+#define MU_DEC643 642
+#define MU_DEC642 641
+#define MU_DEC641 640
+#define MU_DEC640 639
+#define MU_DEC639 638
+#define MU_DEC638 637
+#define MU_DEC637 636
+#define MU_DEC636 635
+#define MU_DEC635 634
+#define MU_DEC634 633
+#define MU_DEC633 632
+#define MU_DEC632 631
+#define MU_DEC631 630
+#define MU_DEC630 629
+#define MU_DEC629 628
+#define MU_DEC628 627
+#define MU_DEC627 626
+#define MU_DEC626 625
+#define MU_DEC625 624
+#define MU_DEC624 623
+#define MU_DEC623 622
+#define MU_DEC622 621
+#define MU_DEC621 620
+#define MU_DEC620 619
+#define MU_DEC619 618
+#define MU_DEC618 617
+#define MU_DEC617 616
+#define MU_DEC616 615
+#define MU_DEC615 614
+#define MU_DEC614 613
+#define MU_DEC613 612
+#define MU_DEC612 611
+#define MU_DEC611 610
+#define MU_DEC610 609
+#define MU_DEC609 608
+#define MU_DEC608 607
+#define MU_DEC607 606
+#define MU_DEC606 605
+#define MU_DEC605 604
+#define MU_DEC604 603
+#define MU_DEC603 602
+#define MU_DEC602 601
+#define MU_DEC601 600
+#define MU_DEC600 599
+#define MU_DEC599 598
+#define MU_DEC598 597
+#define MU_DEC597 596
+#define MU_DEC596 595
+#define MU_DEC595 594
+#define MU_DEC594 593
+#define MU_DEC593 592
+#define MU_DEC592 591
+#define MU_DEC591 590
+#define MU_DEC590 589
+#define MU_DEC589 588
+#define MU_DEC588 587
+#define MU_DEC587 586
+#define MU_DEC586 585
+#define MU_DEC585 584
+#define MU_DEC584 583
+#define MU_DEC583 582
+#define MU_DEC582 581
+#define MU_DEC581 580
+#define MU_DEC580 579
+#define MU_DEC579 578
+#define MU_DEC578 577
+#define MU_DEC577 576
+#define MU_DEC576 575
+#define MU_DEC575 574
+#define MU_DEC574 573
+#define MU_DEC573 572
+#define MU_DEC572 571
+#define MU_DEC571 570
+#define MU_DEC570 569
+#define MU_DEC569 568
+#define MU_DEC568 567
+#define MU_DEC567 566
+#define MU_DEC566 565
+#define MU_DEC565 564
+#define MU_DEC564 563
+#define MU_DEC563 562
+#define MU_DEC562 561
+#define MU_DEC561 560
+#define MU_DEC560 559
+#define MU_DEC559 558
+#define MU_DEC558 557
+#define MU_DEC557 556
+#define MU_DEC556 555
+#define MU_DEC555 554
+#define MU_DEC554 553
+#define MU_DEC553 552
+#define MU_DEC552 551
+#define MU_DEC551 550
+#define MU_DEC550 549
+#define MU_DEC549 548
+#define MU_DEC548 547
+#define MU_DEC547 546
+#define MU_DEC546 545
+#define MU_DEC545 544
+#define MU_DEC544 543
+#define MU_DEC543 542
+#define MU_DEC542 541
+#define MU_DEC541 540
+#define MU_DEC540 539
+#define MU_DEC539 538
+#define MU_DEC538 537
+#define MU_DEC537 536
+#define MU_DEC536 535
+#define MU_DEC535 534
+#define MU_DEC534 533
+#define MU_DEC533 532
+#define MU_DEC532 531
+#define MU_DEC531 530
+#define MU_DEC530 529
+#define MU_DEC529 528
+#define MU_DEC528 527
+#define MU_DEC527 526
+#define MU_DEC526 525
+#define MU_DEC525 524
+#define MU_DEC524 523
+#define MU_DEC523 522
+#define MU_DEC522 521
+#define MU_DEC521 520
+#define MU_DEC520 519
+#define MU_DEC519 518
+#define MU_DEC518 517
+#define MU_DEC517 516
+#define MU_DEC516 515
+#define MU_DEC515 514
+#define MU_DEC514 513
+#define MU_DEC513 512
+#define MU_DEC512 511
+#define MU_DEC511 510
+#define MU_DEC510 509
+#define MU_DEC509 508
+#define MU_DEC508 507
+#define MU_DEC507 506
+#define MU_DEC506 505
+#define MU_DEC505 504
+#define MU_DEC504 503
+#define MU_DEC503 502
+#define MU_DEC502 501
+#define MU_DEC501 500
+#define MU_DEC500 499
+#define MU_DEC499 498
+#define MU_DEC498 497
+#define MU_DEC497 496
+#define MU_DEC496 495
+#define MU_DEC495 494
+#define MU_DEC494 493
+#define MU_DEC493 492
+#define MU_DEC492 491
+#define MU_DEC491 490
+#define MU_DEC490 489
+#define MU_DEC489 488
+#define MU_DEC488 487
+#define MU_DEC487 486
+#define MU_DEC486 485
+#define MU_DEC485 484
+#define MU_DEC484 483
+#define MU_DEC483 482
+#define MU_DEC482 481
+#define MU_DEC481 480
+#define MU_DEC480 479
+#define MU_DEC479 478
+#define MU_DEC478 477
+#define MU_DEC477 476
+#define MU_DEC476 475
+#define MU_DEC475 474
+#define MU_DEC474 473
+#define MU_DEC473 472
+#define MU_DEC472 471
+#define MU_DEC471 470
+#define MU_DEC470 469
+#define MU_DEC469 468
+#define MU_DEC468 467
+#define MU_DEC467 466
+#define MU_DEC466 465
+#define MU_DEC465 464
+#define MU_DEC464 463
+#define MU_DEC463 462
+#define MU_DEC462 461
+#define MU_DEC461 460
+#define MU_DEC460 459
+#define MU_DEC459 458
+#define MU_DEC458 457
+#define MU_DEC457 456
+#define MU_DEC456 455
+#define MU_DEC455 454
+#define MU_DEC454 453
+#define MU_DEC453 452
+#define MU_DEC452 451
+#define MU_DEC451 450
+#define MU_DEC450 449
+#define MU_DEC449 448
+#define MU_DEC448 447
+#define MU_DEC447 446
+#define MU_DEC446 445
+#define MU_DEC445 444
+#define MU_DEC444 443
+#define MU_DEC443 442
+#define MU_DEC442 441
+#define MU_DEC441 440
+#define MU_DEC440 439
+#define MU_DEC439 438
+#define MU_DEC438 437
+#define MU_DEC437 436
+#define MU_DEC436 435
+#define MU_DEC435 434
+#define MU_DEC434 433
+#define MU_DEC433 432
+#define MU_DEC432 431
+#define MU_DEC431 430
+#define MU_DEC430 429
+#define MU_DEC429 428
+#define MU_DEC428 427
+#define MU_DEC427 426
+#define MU_DEC426 425
+#define MU_DEC425 424
+#define MU_DEC424 423
+#define MU_DEC423 422
+#define MU_DEC422 421
+#define MU_DEC421 420
+#define MU_DEC420 419
+#define MU_DEC419 418
+#define MU_DEC418 417
+#define MU_DEC417 416
+#define MU_DEC416 415
+#define MU_DEC415 414
+#define MU_DEC414 413
+#define MU_DEC413 412
+#define MU_DEC412 411
+#define MU_DEC411 410
+#define MU_DEC410 409
+#define MU_DEC409 408
+#define MU_DEC408 407
+#define MU_DEC407 406
+#define MU_DEC406 405
+#define MU_DEC405 404
+#define MU_DEC404 403
+#define MU_DEC403 402
+#define MU_DEC402 401
+#define MU_DEC401 400
+#define MU_DEC400 399
+#define MU_DEC399 398
+#define MU_DEC398 397
+#define MU_DEC397 396
+#define MU_DEC396 395
+#define MU_DEC395 394
+#define MU_DEC394 393
+#define MU_DEC393 392
+#define MU_DEC392 391
+#define MU_DEC391 390
+#define MU_DEC390 389
+#define MU_DEC389 388
+#define MU_DEC388 387
+#define MU_DEC387 386
+#define MU_DEC386 385
+#define MU_DEC385 384
+#define MU_DEC384 383
+#define MU_DEC383 382
+#define MU_DEC382 381
+#define MU_DEC381 380
+#define MU_DEC380 379
+#define MU_DEC379 378
+#define MU_DEC378 377
+#define MU_DEC377 376
+#define MU_DEC376 375
+#define MU_DEC375 374
+#define MU_DEC374 373
+#define MU_DEC373 372
+#define MU_DEC372 371
+#define MU_DEC371 370
+#define MU_DEC370 369
+#define MU_DEC369 368
+#define MU_DEC368 367
+#define MU_DEC367 366
+#define MU_DEC366 365
+#define MU_DEC365 364
+#define MU_DEC364 363
+#define MU_DEC363 362
+#define MU_DEC362 361
+#define MU_DEC361 360
+#define MU_DEC360 359
+#define MU_DEC359 358
+#define MU_DEC358 357
+#define MU_DEC357 356
+#define MU_DEC356 355
+#define MU_DEC355 354
+#define MU_DEC354 353
+#define MU_DEC353 352
+#define MU_DEC352 351
+#define MU_DEC351 350
+#define MU_DEC350 349
+#define MU_DEC349 348
+#define MU_DEC348 347
+#define MU_DEC347 346
+#define MU_DEC346 345
+#define MU_DEC345 344
+#define MU_DEC344 343
+#define MU_DEC343 342
+#define MU_DEC342 341
+#define MU_DEC341 340
+#define MU_DEC340 339
+#define MU_DEC339 338
+#define MU_DEC338 337
+#define MU_DEC337 336
+#define MU_DEC336 335
+#define MU_DEC335 334
+#define MU_DEC334 333
+#define MU_DEC333 332
+#define MU_DEC332 331
+#define MU_DEC331 330
+#define MU_DEC330 329
+#define MU_DEC329 328
+#define MU_DEC328 327
+#define MU_DEC327 326
+#define MU_DEC326 325
+#define MU_DEC325 324
+#define MU_DEC324 323
+#define MU_DEC323 322
+#define MU_DEC322 321
+#define MU_DEC321 320
+#define MU_DEC320 319
+#define MU_DEC319 318
+#define MU_DEC318 317
+#define MU_DEC317 316
+#define MU_DEC316 315
+#define MU_DEC315 314
+#define MU_DEC314 313
+#define MU_DEC313 312
+#define MU_DEC312 311
+#define MU_DEC311 310
+#define MU_DEC310 309
+#define MU_DEC309 308
+#define MU_DEC308 307
+#define MU_DEC307 306
+#define MU_DEC306 305
+#define MU_DEC305 304
+#define MU_DEC304 303
+#define MU_DEC303 302
+#define MU_DEC302 301
+#define MU_DEC301 300
+#define MU_DEC300 299
+#define MU_DEC299 298
+#define MU_DEC298 297
+#define MU_DEC297 296
+#define MU_DEC296 295
+#define MU_DEC295 294
+#define MU_DEC294 293
+#define MU_DEC293 292
+#define MU_DEC292 291
+#define MU_DEC291 290
+#define MU_DEC290 289
+#define MU_DEC289 288
+#define MU_DEC288 287
+#define MU_DEC287 286
+#define MU_DEC286 285
+#define MU_DEC285 284
+#define MU_DEC284 283
+#define MU_DEC283 282
+#define MU_DEC282 281
+#define MU_DEC281 280
+#define MU_DEC280 279
+#define MU_DEC279 278
+#define MU_DEC278 277
+#define MU_DEC277 276
+#define MU_DEC276 275
+#define MU_DEC275 274
+#define MU_DEC274 273
+#define MU_DEC273 272
+#define MU_DEC272 271
+#define MU_DEC271 270
+#define MU_DEC270 269
+#define MU_DEC269 268
+#define MU_DEC268 267
+#define MU_DEC267 266
+#define MU_DEC266 265
+#define MU_DEC265 264
+#define MU_DEC264 263
+#define MU_DEC263 262
+#define MU_DEC262 261
+#define MU_DEC261 260
+#define MU_DEC260 259
+#define MU_DEC259 258
+#define MU_DEC258 257
+#define MU_DEC257 256
+#define MU_DEC256 255
+#define MU_DEC255 254
+#define MU_DEC254 253
+#define MU_DEC253 252
+#define MU_DEC252 251
+#define MU_DEC251 250
+#define MU_DEC250 249
+#define MU_DEC249 248
+#define MU_DEC248 247
+#define MU_DEC247 246
+#define MU_DEC246 245
+#define MU_DEC245 244
+#define MU_DEC244 243
+#define MU_DEC243 242
+#define MU_DEC242 241
+#define MU_DEC241 240
+#define MU_DEC240 239
+#define MU_DEC239 238
+#define MU_DEC238 237
+#define MU_DEC237 236
+#define MU_DEC236 235
+#define MU_DEC235 234
+#define MU_DEC234 233
+#define MU_DEC233 232
+#define MU_DEC232 231
+#define MU_DEC231 230
+#define MU_DEC230 229
+#define MU_DEC229 228
+#define MU_DEC228 227
+#define MU_DEC227 226
+#define MU_DEC226 225
+#define MU_DEC225 224
+#define MU_DEC224 223
+#define MU_DEC223 222
+#define MU_DEC222 221
+#define MU_DEC221 220
+#define MU_DEC220 219
+#define MU_DEC219 218
+#define MU_DEC218 217
+#define MU_DEC217 216
+#define MU_DEC216 215
+#define MU_DEC215 214
+#define MU_DEC214 213
+#define MU_DEC213 212
+#define MU_DEC212 211
+#define MU_DEC211 210
+#define MU_DEC210 209
+#define MU_DEC209 208
+#define MU_DEC208 207
+#define MU_DEC207 206
+#define MU_DEC206 205
+#define MU_DEC205 204
+#define MU_DEC204 203
+#define MU_DEC203 202
+#define MU_DEC202 201
+#define MU_DEC201 200
+#define MU_DEC200 199
+#define MU_DEC199 198
+#define MU_DEC198 197
+#define MU_DEC197 196
+#define MU_DEC196 195
+#define MU_DEC195 194
+#define MU_DEC194 193
+#define MU_DEC193 192
+#define MU_DEC192 191
+#define MU_DEC191 190
+#define MU_DEC190 189
+#define MU_DEC189 188
+#define MU_DEC188 187
+#define MU_DEC187 186
+#define MU_DEC186 185
+#define MU_DEC185 184
+#define MU_DEC184 183
+#define MU_DEC183 182
+#define MU_DEC182 181
+#define MU_DEC181 180
+#define MU_DEC180 179
+#define MU_DEC179 178
+#define MU_DEC178 177
+#define MU_DEC177 176
+#define MU_DEC176 175
+#define MU_DEC175 174
+#define MU_DEC174 173
+#define MU_DEC173 172
+#define MU_DEC172 171
+#define MU_DEC171 170
+#define MU_DEC170 169
+#define MU_DEC169 168
+#define MU_DEC168 167
+#define MU_DEC167 166
+#define MU_DEC166 165
+#define MU_DEC165 164
+#define MU_DEC164 163
+#define MU_DEC163 162
+#define MU_DEC162 161
+#define MU_DEC161 160
+#define MU_DEC160 159
+#define MU_DEC159 158
+#define MU_DEC158 157
+#define MU_DEC157 156
+#define MU_DEC156 155
+#define MU_DEC155 154
+#define MU_DEC154 153
+#define MU_DEC153 152
+#define MU_DEC152 151
+#define MU_DEC151 150
+#define MU_DEC150 149
+#define MU_DEC149 148
+#define MU_DEC148 147
+#define MU_DEC147 146
+#define MU_DEC146 145
+#define MU_DEC145 144
+#define MU_DEC144 143
+#define MU_DEC143 142
+#define MU_DEC142 141
+#define MU_DEC141 140
+#define MU_DEC140 139
+#define MU_DEC139 138
+#define MU_DEC138 137
+#define MU_DEC137 136
+#define MU_DEC136 135
+#define MU_DEC135 134
+#define MU_DEC134 133
+#define MU_DEC133 132
+#define MU_DEC132 131
+#define MU_DEC131 130
+#define MU_DEC130 129
+#define MU_DEC129 128
+#define MU_DEC128 127
+#define MU_DEC127 126
+#define MU_DEC126 125
+#define MU_DEC125 124
+#define MU_DEC124 123
+#define MU_DEC123 122
+#define MU_DEC122 121
+#define MU_DEC121 120
+#define MU_DEC120 119
+#define MU_DEC119 118
+#define MU_DEC118 117
+#define MU_DEC117 116
+#define MU_DEC116 115
+#define MU_DEC115 114
+#define MU_DEC114 113
+#define MU_DEC113 112
+#define MU_DEC112 111
+#define MU_DEC111 110
+#define MU_DEC110 109
+#define MU_DEC109 108
+#define MU_DEC108 107
+#define MU_DEC107 106
+#define MU_DEC106 105
+#define MU_DEC105 104
+#define MU_DEC104 103
+#define MU_DEC103 102
+#define MU_DEC102 101
+#define MU_DEC101 100
+#define MU_DEC100 99
+#define MU_DEC99 98
+#define MU_DEC98 97
+#define MU_DEC97 96
+#define MU_DEC96 95
+#define MU_DEC95 94
+#define MU_DEC94 93
+#define MU_DEC93 92
+#define MU_DEC92 91
+#define MU_DEC91 90
+#define MU_DEC90 89
+#define MU_DEC89 88
+#define MU_DEC88 87
+#define MU_DEC87 86
+#define MU_DEC86 85
+#define MU_DEC85 84
+#define MU_DEC84 83
+#define MU_DEC83 82
+#define MU_DEC82 81
+#define MU_DEC81 80
+#define MU_DEC80 79
+#define MU_DEC79 78
+#define MU_DEC78 77
+#define MU_DEC77 76
+#define MU_DEC76 75
+#define MU_DEC75 74
+#define MU_DEC74 73
+#define MU_DEC73 72
+#define MU_DEC72 71
+#define MU_DEC71 70
+#define MU_DEC70 69
+#define MU_DEC69 68
+#define MU_DEC68 67
+#define MU_DEC67 66
+#define MU_DEC66 65
+#define MU_DEC65 64
+#define MU_DEC64 63
+#define MU_DEC63 62
+#define MU_DEC62 61
+#define MU_DEC61 60
+#define MU_DEC60 59
+#define MU_DEC59 58
+#define MU_DEC58 57
+#define MU_DEC57 56
+#define MU_DEC56 55
+#define MU_DEC55 54
+#define MU_DEC54 53
+#define MU_DEC53 52
+#define MU_DEC52 51
+#define MU_DEC51 50
+#define MU_DEC50 49
+#define MU_DEC49 48
+#define MU_DEC48 47
+#define MU_DEC47 46
+#define MU_DEC46 45
+#define MU_DEC45 44
+#define MU_DEC44 43
+#define MU_DEC43 42
+#define MU_DEC42 41
+#define MU_DEC41 40
+#define MU_DEC40 39
+#define MU_DEC39 38
+#define MU_DEC38 37
+#define MU_DEC37 36
+#define MU_DEC36 35
+#define MU_DEC35 34
+#define MU_DEC34 33
+#define MU_DEC33 32
+#define MU_DEC32 31
+#define MU_DEC31 30
+#define MU_DEC30 29
+#define MU_DEC29 28
+#define MU_DEC28 27
+#define MU_DEC27 26
+#define MU_DEC26 25
+#define MU_DEC25 24
+#define MU_DEC24 23
+#define MU_DEC23 22
+#define MU_DEC22 21
+#define MU_DEC21 20
+#define MU_DEC20 19
+#define MU_DEC19 18
+#define MU_DEC18 17
+#define MU_DEC17 16
+#define MU_DEC16 15
+#define MU_DEC15 14
+#define MU_DEC14 13
+#define MU_DEC13 12
+#define MU_DEC12 11
+#define MU_DEC11 10
+#define MU_DEC10 9
+#define MU_DEC9 8
+#define MU_DEC8 7
+#define MU_DEC7 6
+#define MU_DEC6 5
+#define MU_DEC5 4
+#define MU_DEC4 3
+#define MU_DEC3 2
+#define MU_DEC2 1
+#define MU_DEC1 0
+
+#define MU_INC(x) MU_C2(MU_INC,x)
+#define MU_INC2048 2049
+#define MU_INC2047 2048
+#define MU_INC2046 2047
+#define MU_INC2045 2046
+#define MU_INC2044 2045
+#define MU_INC2043 2044
+#define MU_INC2042 2043
+#define MU_INC2041 2042
+#define MU_INC2040 2041
+#define MU_INC2039 2040
+#define MU_INC2038 2039
+#define MU_INC2037 2038
+#define MU_INC2036 2037
+#define MU_INC2035 2036
+#define MU_INC2034 2035
+#define MU_INC2033 2034
+#define MU_INC2032 2033
+#define MU_INC2031 2032
+#define MU_INC2030 2031
+#define MU_INC2029 2030
+#define MU_INC2028 2029
+#define MU_INC2027 2028
+#define MU_INC2026 2027
+#define MU_INC2025 2026
+#define MU_INC2024 2025
+#define MU_INC2023 2024
+#define MU_INC2022 2023
+#define MU_INC2021 2022
+#define MU_INC2020 2021
+#define MU_INC2019 2020
+#define MU_INC2018 2019
+#define MU_INC2017 2018
+#define MU_INC2016 2017
+#define MU_INC2015 2016
+#define MU_INC2014 2015
+#define MU_INC2013 2014
+#define MU_INC2012 2013
+#define MU_INC2011 2012
+#define MU_INC2010 2011
+#define MU_INC2009 2010
+#define MU_INC2008 2009
+#define MU_INC2007 2008
+#define MU_INC2006 2007
+#define MU_INC2005 2006
+#define MU_INC2004 2005
+#define MU_INC2003 2004
+#define MU_INC2002 2003
+#define MU_INC2001 2002
+#define MU_INC2000 2001
+#define MU_INC1999 2000
+#define MU_INC1998 1999
+#define MU_INC1997 1998
+#define MU_INC1996 1997
+#define MU_INC1995 1996
+#define MU_INC1994 1995
+#define MU_INC1993 1994
+#define MU_INC1992 1993
+#define MU_INC1991 1992
+#define MU_INC1990 1991
+#define MU_INC1989 1990
+#define MU_INC1988 1989
+#define MU_INC1987 1988
+#define MU_INC1986 1987
+#define MU_INC1985 1986
+#define MU_INC1984 1985
+#define MU_INC1983 1984
+#define MU_INC1982 1983
+#define MU_INC1981 1982
+#define MU_INC1980 1981
+#define MU_INC1979 1980
+#define MU_INC1978 1979
+#define MU_INC1977 1978
+#define MU_INC1976 1977
+#define MU_INC1975 1976
+#define MU_INC1974 1975
+#define MU_INC1973 1974
+#define MU_INC1972 1973
+#define MU_INC1971 1972
+#define MU_INC1970 1971
+#define MU_INC1969 1970
+#define MU_INC1968 1969
+#define MU_INC1967 1968
+#define MU_INC1966 1967
+#define MU_INC1965 1966
+#define MU_INC1964 1965
+#define MU_INC1963 1964
+#define MU_INC1962 1963
+#define MU_INC1961 1962
+#define MU_INC1960 1961
+#define MU_INC1959 1960
+#define MU_INC1958 1959
+#define MU_INC1957 1958
+#define MU_INC1956 1957
+#define MU_INC1955 1956
+#define MU_INC1954 1955
+#define MU_INC1953 1954
+#define MU_INC1952 1953
+#define MU_INC1951 1952
+#define MU_INC1950 1951
+#define MU_INC1949 1950
+#define MU_INC1948 1949
+#define MU_INC1947 1948
+#define MU_INC1946 1947
+#define MU_INC1945 1946
+#define MU_INC1944 1945
+#define MU_INC1943 1944
+#define MU_INC1942 1943
+#define MU_INC1941 1942
+#define MU_INC1940 1941
+#define MU_INC1939 1940
+#define MU_INC1938 1939
+#define MU_INC1937 1938
+#define MU_INC1936 1937
+#define MU_INC1935 1936
+#define MU_INC1934 1935
+#define MU_INC1933 1934
+#define MU_INC1932 1933
+#define MU_INC1931 1932
+#define MU_INC1930 1931
+#define MU_INC1929 1930
+#define MU_INC1928 1929
+#define MU_INC1927 1928
+#define MU_INC1926 1927
+#define MU_INC1925 1926
+#define MU_INC1924 1925
+#define MU_INC1923 1924
+#define MU_INC1922 1923
+#define MU_INC1921 1922
+#define MU_INC1920 1921
+#define MU_INC1919 1920
+#define MU_INC1918 1919
+#define MU_INC1917 1918
+#define MU_INC1916 1917
+#define MU_INC1915 1916
+#define MU_INC1914 1915
+#define MU_INC1913 1914
+#define MU_INC1912 1913
+#define MU_INC1911 1912
+#define MU_INC1910 1911
+#define MU_INC1909 1910
+#define MU_INC1908 1909
+#define MU_INC1907 1908
+#define MU_INC1906 1907
+#define MU_INC1905 1906
+#define MU_INC1904 1905
+#define MU_INC1903 1904
+#define MU_INC1902 1903
+#define MU_INC1901 1902
+#define MU_INC1900 1901
+#define MU_INC1899 1900
+#define MU_INC1898 1899
+#define MU_INC1897 1898
+#define MU_INC1896 1897
+#define MU_INC1895 1896
+#define MU_INC1894 1895
+#define MU_INC1893 1894
+#define MU_INC1892 1893
+#define MU_INC1891 1892
+#define MU_INC1890 1891
+#define MU_INC1889 1890
+#define MU_INC1888 1889
+#define MU_INC1887 1888
+#define MU_INC1886 1887
+#define MU_INC1885 1886
+#define MU_INC1884 1885
+#define MU_INC1883 1884
+#define MU_INC1882 1883
+#define MU_INC1881 1882
+#define MU_INC1880 1881
+#define MU_INC1879 1880
+#define MU_INC1878 1879
+#define MU_INC1877 1878
+#define MU_INC1876 1877
+#define MU_INC1875 1876
+#define MU_INC1874 1875
+#define MU_INC1873 1874
+#define MU_INC1872 1873
+#define MU_INC1871 1872
+#define MU_INC1870 1871
+#define MU_INC1869 1870
+#define MU_INC1868 1869
+#define MU_INC1867 1868
+#define MU_INC1866 1867
+#define MU_INC1865 1866
+#define MU_INC1864 1865
+#define MU_INC1863 1864
+#define MU_INC1862 1863
+#define MU_INC1861 1862
+#define MU_INC1860 1861
+#define MU_INC1859 1860
+#define MU_INC1858 1859
+#define MU_INC1857 1858
+#define MU_INC1856 1857
+#define MU_INC1855 1856
+#define MU_INC1854 1855
+#define MU_INC1853 1854
+#define MU_INC1852 1853
+#define MU_INC1851 1852
+#define MU_INC1850 1851
+#define MU_INC1849 1850
+#define MU_INC1848 1849
+#define MU_INC1847 1848
+#define MU_INC1846 1847
+#define MU_INC1845 1846
+#define MU_INC1844 1845
+#define MU_INC1843 1844
+#define MU_INC1842 1843
+#define MU_INC1841 1842
+#define MU_INC1840 1841
+#define MU_INC1839 1840
+#define MU_INC1838 1839
+#define MU_INC1837 1838
+#define MU_INC1836 1837
+#define MU_INC1835 1836
+#define MU_INC1834 1835
+#define MU_INC1833 1834
+#define MU_INC1832 1833
+#define MU_INC1831 1832
+#define MU_INC1830 1831
+#define MU_INC1829 1830
+#define MU_INC1828 1829
+#define MU_INC1827 1828
+#define MU_INC1826 1827
+#define MU_INC1825 1826
+#define MU_INC1824 1825
+#define MU_INC1823 1824
+#define MU_INC1822 1823
+#define MU_INC1821 1822
+#define MU_INC1820 1821
+#define MU_INC1819 1820
+#define MU_INC1818 1819
+#define MU_INC1817 1818
+#define MU_INC1816 1817
+#define MU_INC1815 1816
+#define MU_INC1814 1815
+#define MU_INC1813 1814
+#define MU_INC1812 1813
+#define MU_INC1811 1812
+#define MU_INC1810 1811
+#define MU_INC1809 1810
+#define MU_INC1808 1809
+#define MU_INC1807 1808
+#define MU_INC1806 1807
+#define MU_INC1805 1806
+#define MU_INC1804 1805
+#define MU_INC1803 1804
+#define MU_INC1802 1803
+#define MU_INC1801 1802
+#define MU_INC1800 1801
+#define MU_INC1799 1800
+#define MU_INC1798 1799
+#define MU_INC1797 1798
+#define MU_INC1796 1797
+#define MU_INC1795 1796
+#define MU_INC1794 1795
+#define MU_INC1793 1794
+#define MU_INC1792 1793
+#define MU_INC1791 1792
+#define MU_INC1790 1791
+#define MU_INC1789 1790
+#define MU_INC1788 1789
+#define MU_INC1787 1788
+#define MU_INC1786 1787
+#define MU_INC1785 1786
+#define MU_INC1784 1785
+#define MU_INC1783 1784
+#define MU_INC1782 1783
+#define MU_INC1781 1782
+#define MU_INC1780 1781
+#define MU_INC1779 1780
+#define MU_INC1778 1779
+#define MU_INC1777 1778
+#define MU_INC1776 1777
+#define MU_INC1775 1776
+#define MU_INC1774 1775
+#define MU_INC1773 1774
+#define MU_INC1772 1773
+#define MU_INC1771 1772
+#define MU_INC1770 1771
+#define MU_INC1769 1770
+#define MU_INC1768 1769
+#define MU_INC1767 1768
+#define MU_INC1766 1767
+#define MU_INC1765 1766
+#define MU_INC1764 1765
+#define MU_INC1763 1764
+#define MU_INC1762 1763
+#define MU_INC1761 1762
+#define MU_INC1760 1761
+#define MU_INC1759 1760
+#define MU_INC1758 1759
+#define MU_INC1757 1758
+#define MU_INC1756 1757
+#define MU_INC1755 1756
+#define MU_INC1754 1755
+#define MU_INC1753 1754
+#define MU_INC1752 1753
+#define MU_INC1751 1752
+#define MU_INC1750 1751
+#define MU_INC1749 1750
+#define MU_INC1748 1749
+#define MU_INC1747 1748
+#define MU_INC1746 1747
+#define MU_INC1745 1746
+#define MU_INC1744 1745
+#define MU_INC1743 1744
+#define MU_INC1742 1743
+#define MU_INC1741 1742
+#define MU_INC1740 1741
+#define MU_INC1739 1740
+#define MU_INC1738 1739
+#define MU_INC1737 1738
+#define MU_INC1736 1737
+#define MU_INC1735 1736
+#define MU_INC1734 1735
+#define MU_INC1733 1734
+#define MU_INC1732 1733
+#define MU_INC1731 1732
+#define MU_INC1730 1731
+#define MU_INC1729 1730
+#define MU_INC1728 1729
+#define MU_INC1727 1728
+#define MU_INC1726 1727
+#define MU_INC1725 1726
+#define MU_INC1724 1725
+#define MU_INC1723 1724
+#define MU_INC1722 1723
+#define MU_INC1721 1722
+#define MU_INC1720 1721
+#define MU_INC1719 1720
+#define MU_INC1718 1719
+#define MU_INC1717 1718
+#define MU_INC1716 1717
+#define MU_INC1715 1716
+#define MU_INC1714 1715
+#define MU_INC1713 1714
+#define MU_INC1712 1713
+#define MU_INC1711 1712
+#define MU_INC1710 1711
+#define MU_INC1709 1710
+#define MU_INC1708 1709
+#define MU_INC1707 1708
+#define MU_INC1706 1707
+#define MU_INC1705 1706
+#define MU_INC1704 1705
+#define MU_INC1703 1704
+#define MU_INC1702 1703
+#define MU_INC1701 1702
+#define MU_INC1700 1701
+#define MU_INC1699 1700
+#define MU_INC1698 1699
+#define MU_INC1697 1698
+#define MU_INC1696 1697
+#define MU_INC1695 1696
+#define MU_INC1694 1695
+#define MU_INC1693 1694
+#define MU_INC1692 1693
+#define MU_INC1691 1692
+#define MU_INC1690 1691
+#define MU_INC1689 1690
+#define MU_INC1688 1689
+#define MU_INC1687 1688
+#define MU_INC1686 1687
+#define MU_INC1685 1686
+#define MU_INC1684 1685
+#define MU_INC1683 1684
+#define MU_INC1682 1683
+#define MU_INC1681 1682
+#define MU_INC1680 1681
+#define MU_INC1679 1680
+#define MU_INC1678 1679
+#define MU_INC1677 1678
+#define MU_INC1676 1677
+#define MU_INC1675 1676
+#define MU_INC1674 1675
+#define MU_INC1673 1674
+#define MU_INC1672 1673
+#define MU_INC1671 1672
+#define MU_INC1670 1671
+#define MU_INC1669 1670
+#define MU_INC1668 1669
+#define MU_INC1667 1668
+#define MU_INC1666 1667
+#define MU_INC1665 1666
+#define MU_INC1664 1665
+#define MU_INC1663 1664
+#define MU_INC1662 1663
+#define MU_INC1661 1662
+#define MU_INC1660 1661
+#define MU_INC1659 1660
+#define MU_INC1658 1659
+#define MU_INC1657 1658
+#define MU_INC1656 1657
+#define MU_INC1655 1656
+#define MU_INC1654 1655
+#define MU_INC1653 1654
+#define MU_INC1652 1653
+#define MU_INC1651 1652
+#define MU_INC1650 1651
+#define MU_INC1649 1650
+#define MU_INC1648 1649
+#define MU_INC1647 1648
+#define MU_INC1646 1647
+#define MU_INC1645 1646
+#define MU_INC1644 1645
+#define MU_INC1643 1644
+#define MU_INC1642 1643
+#define MU_INC1641 1642
+#define MU_INC1640 1641
+#define MU_INC1639 1640
+#define MU_INC1638 1639
+#define MU_INC1637 1638
+#define MU_INC1636 1637
+#define MU_INC1635 1636
+#define MU_INC1634 1635
+#define MU_INC1633 1634
+#define MU_INC1632 1633
+#define MU_INC1631 1632
+#define MU_INC1630 1631
+#define MU_INC1629 1630
+#define MU_INC1628 1629
+#define MU_INC1627 1628
+#define MU_INC1626 1627
+#define MU_INC1625 1626
+#define MU_INC1624 1625
+#define MU_INC1623 1624
+#define MU_INC1622 1623
+#define MU_INC1621 1622
+#define MU_INC1620 1621
+#define MU_INC1619 1620
+#define MU_INC1618 1619
+#define MU_INC1617 1618
+#define MU_INC1616 1617
+#define MU_INC1615 1616
+#define MU_INC1614 1615
+#define MU_INC1613 1614
+#define MU_INC1612 1613
+#define MU_INC1611 1612
+#define MU_INC1610 1611
+#define MU_INC1609 1610
+#define MU_INC1608 1609
+#define MU_INC1607 1608
+#define MU_INC1606 1607
+#define MU_INC1605 1606
+#define MU_INC1604 1605
+#define MU_INC1603 1604
+#define MU_INC1602 1603
+#define MU_INC1601 1602
+#define MU_INC1600 1601
+#define MU_INC1599 1600
+#define MU_INC1598 1599
+#define MU_INC1597 1598
+#define MU_INC1596 1597
+#define MU_INC1595 1596
+#define MU_INC1594 1595
+#define MU_INC1593 1594
+#define MU_INC1592 1593
+#define MU_INC1591 1592
+#define MU_INC1590 1591
+#define MU_INC1589 1590
+#define MU_INC1588 1589
+#define MU_INC1587 1588
+#define MU_INC1586 1587
+#define MU_INC1585 1586
+#define MU_INC1584 1585
+#define MU_INC1583 1584
+#define MU_INC1582 1583
+#define MU_INC1581 1582
+#define MU_INC1580 1581
+#define MU_INC1579 1580
+#define MU_INC1578 1579
+#define MU_INC1577 1578
+#define MU_INC1576 1577
+#define MU_INC1575 1576
+#define MU_INC1574 1575
+#define MU_INC1573 1574
+#define MU_INC1572 1573
+#define MU_INC1571 1572
+#define MU_INC1570 1571
+#define MU_INC1569 1570
+#define MU_INC1568 1569
+#define MU_INC1567 1568
+#define MU_INC1566 1567
+#define MU_INC1565 1566
+#define MU_INC1564 1565
+#define MU_INC1563 1564
+#define MU_INC1562 1563
+#define MU_INC1561 1562
+#define MU_INC1560 1561
+#define MU_INC1559 1560
+#define MU_INC1558 1559
+#define MU_INC1557 1558
+#define MU_INC1556 1557
+#define MU_INC1555 1556
+#define MU_INC1554 1555
+#define MU_INC1553 1554
+#define MU_INC1552 1553
+#define MU_INC1551 1552
+#define MU_INC1550 1551
+#define MU_INC1549 1550
+#define MU_INC1548 1549
+#define MU_INC1547 1548
+#define MU_INC1546 1547
+#define MU_INC1545 1546
+#define MU_INC1544 1545
+#define MU_INC1543 1544
+#define MU_INC1542 1543
+#define MU_INC1541 1542
+#define MU_INC1540 1541
+#define MU_INC1539 1540
+#define MU_INC1538 1539
+#define MU_INC1537 1538
+#define MU_INC1536 1537
+#define MU_INC1535 1536
+#define MU_INC1534 1535
+#define MU_INC1533 1534
+#define MU_INC1532 1533
+#define MU_INC1531 1532
+#define MU_INC1530 1531
+#define MU_INC1529 1530
+#define MU_INC1528 1529
+#define MU_INC1527 1528
+#define MU_INC1526 1527
+#define MU_INC1525 1526
+#define MU_INC1524 1525
+#define MU_INC1523 1524
+#define MU_INC1522 1523
+#define MU_INC1521 1522
+#define MU_INC1520 1521
+#define MU_INC1519 1520
+#define MU_INC1518 1519
+#define MU_INC1517 1518
+#define MU_INC1516 1517
+#define MU_INC1515 1516
+#define MU_INC1514 1515
+#define MU_INC1513 1514
+#define MU_INC1512 1513
+#define MU_INC1511 1512
+#define MU_INC1510 1511
+#define MU_INC1509 1510
+#define MU_INC1508 1509
+#define MU_INC1507 1508
+#define MU_INC1506 1507
+#define MU_INC1505 1506
+#define MU_INC1504 1505
+#define MU_INC1503 1504
+#define MU_INC1502 1503
+#define MU_INC1501 1502
+#define MU_INC1500 1501
+#define MU_INC1499 1500
+#define MU_INC1498 1499
+#define MU_INC1497 1498
+#define MU_INC1496 1497
+#define MU_INC1495 1496
+#define MU_INC1494 1495
+#define MU_INC1493 1494
+#define MU_INC1492 1493
+#define MU_INC1491 1492
+#define MU_INC1490 1491
+#define MU_INC1489 1490
+#define MU_INC1488 1489
+#define MU_INC1487 1488
+#define MU_INC1486 1487
+#define MU_INC1485 1486
+#define MU_INC1484 1485
+#define MU_INC1483 1484
+#define MU_INC1482 1483
+#define MU_INC1481 1482
+#define MU_INC1480 1481
+#define MU_INC1479 1480
+#define MU_INC1478 1479
+#define MU_INC1477 1478
+#define MU_INC1476 1477
+#define MU_INC1475 1476
+#define MU_INC1474 1475
+#define MU_INC1473 1474
+#define MU_INC1472 1473
+#define MU_INC1471 1472
+#define MU_INC1470 1471
+#define MU_INC1469 1470
+#define MU_INC1468 1469
+#define MU_INC1467 1468
+#define MU_INC1466 1467
+#define MU_INC1465 1466
+#define MU_INC1464 1465
+#define MU_INC1463 1464
+#define MU_INC1462 1463
+#define MU_INC1461 1462
+#define MU_INC1460 1461
+#define MU_INC1459 1460
+#define MU_INC1458 1459
+#define MU_INC1457 1458
+#define MU_INC1456 1457
+#define MU_INC1455 1456
+#define MU_INC1454 1455
+#define MU_INC1453 1454
+#define MU_INC1452 1453
+#define MU_INC1451 1452
+#define MU_INC1450 1451
+#define MU_INC1449 1450
+#define MU_INC1448 1449
+#define MU_INC1447 1448
+#define MU_INC1446 1447
+#define MU_INC1445 1446
+#define MU_INC1444 1445
+#define MU_INC1443 1444
+#define MU_INC1442 1443
+#define MU_INC1441 1442
+#define MU_INC1440 1441
+#define MU_INC1439 1440
+#define MU_INC1438 1439
+#define MU_INC1437 1438
+#define MU_INC1436 1437
+#define MU_INC1435 1436
+#define MU_INC1434 1435
+#define MU_INC1433 1434
+#define MU_INC1432 1433
+#define MU_INC1431 1432
+#define MU_INC1430 1431
+#define MU_INC1429 1430
+#define MU_INC1428 1429
+#define MU_INC1427 1428
+#define MU_INC1426 1427
+#define MU_INC1425 1426
+#define MU_INC1424 1425
+#define MU_INC1423 1424
+#define MU_INC1422 1423
+#define MU_INC1421 1422
+#define MU_INC1420 1421
+#define MU_INC1419 1420
+#define MU_INC1418 1419
+#define MU_INC1417 1418
+#define MU_INC1416 1417
+#define MU_INC1415 1416
+#define MU_INC1414 1415
+#define MU_INC1413 1414
+#define MU_INC1412 1413
+#define MU_INC1411 1412
+#define MU_INC1410 1411
+#define MU_INC1409 1410
+#define MU_INC1408 1409
+#define MU_INC1407 1408
+#define MU_INC1406 1407
+#define MU_INC1405 1406
+#define MU_INC1404 1405
+#define MU_INC1403 1404
+#define MU_INC1402 1403
+#define MU_INC1401 1402
+#define MU_INC1400 1401
+#define MU_INC1399 1400
+#define MU_INC1398 1399
+#define MU_INC1397 1398
+#define MU_INC1396 1397
+#define MU_INC1395 1396
+#define MU_INC1394 1395
+#define MU_INC1393 1394
+#define MU_INC1392 1393
+#define MU_INC1391 1392
+#define MU_INC1390 1391
+#define MU_INC1389 1390
+#define MU_INC1388 1389
+#define MU_INC1387 1388
+#define MU_INC1386 1387
+#define MU_INC1385 1386
+#define MU_INC1384 1385
+#define MU_INC1383 1384
+#define MU_INC1382 1383
+#define MU_INC1381 1382
+#define MU_INC1380 1381
+#define MU_INC1379 1380
+#define MU_INC1378 1379
+#define MU_INC1377 1378
+#define MU_INC1376 1377
+#define MU_INC1375 1376
+#define MU_INC1374 1375
+#define MU_INC1373 1374
+#define MU_INC1372 1373
+#define MU_INC1371 1372
+#define MU_INC1370 1371
+#define MU_INC1369 1370
+#define MU_INC1368 1369
+#define MU_INC1367 1368
+#define MU_INC1366 1367
+#define MU_INC1365 1366
+#define MU_INC1364 1365
+#define MU_INC1363 1364
+#define MU_INC1362 1363
+#define MU_INC1361 1362
+#define MU_INC1360 1361
+#define MU_INC1359 1360
+#define MU_INC1358 1359
+#define MU_INC1357 1358
+#define MU_INC1356 1357
+#define MU_INC1355 1356
+#define MU_INC1354 1355
+#define MU_INC1353 1354
+#define MU_INC1352 1353
+#define MU_INC1351 1352
+#define MU_INC1350 1351
+#define MU_INC1349 1350
+#define MU_INC1348 1349
+#define MU_INC1347 1348
+#define MU_INC1346 1347
+#define MU_INC1345 1346
+#define MU_INC1344 1345
+#define MU_INC1343 1344
+#define MU_INC1342 1343
+#define MU_INC1341 1342
+#define MU_INC1340 1341
+#define MU_INC1339 1340
+#define MU_INC1338 1339
+#define MU_INC1337 1338
+#define MU_INC1336 1337
+#define MU_INC1335 1336
+#define MU_INC1334 1335
+#define MU_INC1333 1334
+#define MU_INC1332 1333
+#define MU_INC1331 1332
+#define MU_INC1330 1331
+#define MU_INC1329 1330
+#define MU_INC1328 1329
+#define MU_INC1327 1328
+#define MU_INC1326 1327
+#define MU_INC1325 1326
+#define MU_INC1324 1325
+#define MU_INC1323 1324
+#define MU_INC1322 1323
+#define MU_INC1321 1322
+#define MU_INC1320 1321
+#define MU_INC1319 1320
+#define MU_INC1318 1319
+#define MU_INC1317 1318
+#define MU_INC1316 1317
+#define MU_INC1315 1316
+#define MU_INC1314 1315
+#define MU_INC1313 1314
+#define MU_INC1312 1313
+#define MU_INC1311 1312
+#define MU_INC1310 1311
+#define MU_INC1309 1310
+#define MU_INC1308 1309
+#define MU_INC1307 1308
+#define MU_INC1306 1307
+#define MU_INC1305 1306
+#define MU_INC1304 1305
+#define MU_INC1303 1304
+#define MU_INC1302 1303
+#define MU_INC1301 1302
+#define MU_INC1300 1301
+#define MU_INC1299 1300
+#define MU_INC1298 1299
+#define MU_INC1297 1298
+#define MU_INC1296 1297
+#define MU_INC1295 1296
+#define MU_INC1294 1295
+#define MU_INC1293 1294
+#define MU_INC1292 1293
+#define MU_INC1291 1292
+#define MU_INC1290 1291
+#define MU_INC1289 1290
+#define MU_INC1288 1289
+#define MU_INC1287 1288
+#define MU_INC1286 1287
+#define MU_INC1285 1286
+#define MU_INC1284 1285
+#define MU_INC1283 1284
+#define MU_INC1282 1283
+#define MU_INC1281 1282
+#define MU_INC1280 1281
+#define MU_INC1279 1280
+#define MU_INC1278 1279
+#define MU_INC1277 1278
+#define MU_INC1276 1277
+#define MU_INC1275 1276
+#define MU_INC1274 1275
+#define MU_INC1273 1274
+#define MU_INC1272 1273
+#define MU_INC1271 1272
+#define MU_INC1270 1271
+#define MU_INC1269 1270
+#define MU_INC1268 1269
+#define MU_INC1267 1268
+#define MU_INC1266 1267
+#define MU_INC1265 1266
+#define MU_INC1264 1265
+#define MU_INC1263 1264
+#define MU_INC1262 1263
+#define MU_INC1261 1262
+#define MU_INC1260 1261
+#define MU_INC1259 1260
+#define MU_INC1258 1259
+#define MU_INC1257 1258
+#define MU_INC1256 1257
+#define MU_INC1255 1256
+#define MU_INC1254 1255
+#define MU_INC1253 1254
+#define MU_INC1252 1253
+#define MU_INC1251 1252
+#define MU_INC1250 1251
+#define MU_INC1249 1250
+#define MU_INC1248 1249
+#define MU_INC1247 1248
+#define MU_INC1246 1247
+#define MU_INC1245 1246
+#define MU_INC1244 1245
+#define MU_INC1243 1244
+#define MU_INC1242 1243
+#define MU_INC1241 1242
+#define MU_INC1240 1241
+#define MU_INC1239 1240
+#define MU_INC1238 1239
+#define MU_INC1237 1238
+#define MU_INC1236 1237
+#define MU_INC1235 1236
+#define MU_INC1234 1235
+#define MU_INC1233 1234
+#define MU_INC1232 1233
+#define MU_INC1231 1232
+#define MU_INC1230 1231
+#define MU_INC1229 1230
+#define MU_INC1228 1229
+#define MU_INC1227 1228
+#define MU_INC1226 1227
+#define MU_INC1225 1226
+#define MU_INC1224 1225
+#define MU_INC1223 1224
+#define MU_INC1222 1223
+#define MU_INC1221 1222
+#define MU_INC1220 1221
+#define MU_INC1219 1220
+#define MU_INC1218 1219
+#define MU_INC1217 1218
+#define MU_INC1216 1217
+#define MU_INC1215 1216
+#define MU_INC1214 1215
+#define MU_INC1213 1214
+#define MU_INC1212 1213
+#define MU_INC1211 1212
+#define MU_INC1210 1211
+#define MU_INC1209 1210
+#define MU_INC1208 1209
+#define MU_INC1207 1208
+#define MU_INC1206 1207
+#define MU_INC1205 1206
+#define MU_INC1204 1205
+#define MU_INC1203 1204
+#define MU_INC1202 1203
+#define MU_INC1201 1202
+#define MU_INC1200 1201
+#define MU_INC1199 1200
+#define MU_INC1198 1199
+#define MU_INC1197 1198
+#define MU_INC1196 1197
+#define MU_INC1195 1196
+#define MU_INC1194 1195
+#define MU_INC1193 1194
+#define MU_INC1192 1193
+#define MU_INC1191 1192
+#define MU_INC1190 1191
+#define MU_INC1189 1190
+#define MU_INC1188 1189
+#define MU_INC1187 1188
+#define MU_INC1186 1187
+#define MU_INC1185 1186
+#define MU_INC1184 1185
+#define MU_INC1183 1184
+#define MU_INC1182 1183
+#define MU_INC1181 1182
+#define MU_INC1180 1181
+#define MU_INC1179 1180
+#define MU_INC1178 1179
+#define MU_INC1177 1178
+#define MU_INC1176 1177
+#define MU_INC1175 1176
+#define MU_INC1174 1175
+#define MU_INC1173 1174
+#define MU_INC1172 1173
+#define MU_INC1171 1172
+#define MU_INC1170 1171
+#define MU_INC1169 1170
+#define MU_INC1168 1169
+#define MU_INC1167 1168
+#define MU_INC1166 1167
+#define MU_INC1165 1166
+#define MU_INC1164 1165
+#define MU_INC1163 1164
+#define MU_INC1162 1163
+#define MU_INC1161 1162
+#define MU_INC1160 1161
+#define MU_INC1159 1160
+#define MU_INC1158 1159
+#define MU_INC1157 1158
+#define MU_INC1156 1157
+#define MU_INC1155 1156
+#define MU_INC1154 1155
+#define MU_INC1153 1154
+#define MU_INC1152 1153
+#define MU_INC1151 1152
+#define MU_INC1150 1151
+#define MU_INC1149 1150
+#define MU_INC1148 1149
+#define MU_INC1147 1148
+#define MU_INC1146 1147
+#define MU_INC1145 1146
+#define MU_INC1144 1145
+#define MU_INC1143 1144
+#define MU_INC1142 1143
+#define MU_INC1141 1142
+#define MU_INC1140 1141
+#define MU_INC1139 1140
+#define MU_INC1138 1139
+#define MU_INC1137 1138
+#define MU_INC1136 1137
+#define MU_INC1135 1136
+#define MU_INC1134 1135
+#define MU_INC1133 1134
+#define MU_INC1132 1133
+#define MU_INC1131 1132
+#define MU_INC1130 1131
+#define MU_INC1129 1130
+#define MU_INC1128 1129
+#define MU_INC1127 1128
+#define MU_INC1126 1127
+#define MU_INC1125 1126
+#define MU_INC1124 1125
+#define MU_INC1123 1124
+#define MU_INC1122 1123
+#define MU_INC1121 1122
+#define MU_INC1120 1121
+#define MU_INC1119 1120
+#define MU_INC1118 1119
+#define MU_INC1117 1118
+#define MU_INC1116 1117
+#define MU_INC1115 1116
+#define MU_INC1114 1115
+#define MU_INC1113 1114
+#define MU_INC1112 1113
+#define MU_INC1111 1112
+#define MU_INC1110 1111
+#define MU_INC1109 1110
+#define MU_INC1108 1109
+#define MU_INC1107 1108
+#define MU_INC1106 1107
+#define MU_INC1105 1106
+#define MU_INC1104 1105
+#define MU_INC1103 1104
+#define MU_INC1102 1103
+#define MU_INC1101 1102
+#define MU_INC1100 1101
+#define MU_INC1099 1100
+#define MU_INC1098 1099
+#define MU_INC1097 1098
+#define MU_INC1096 1097
+#define MU_INC1095 1096
+#define MU_INC1094 1095
+#define MU_INC1093 1094
+#define MU_INC1092 1093
+#define MU_INC1091 1092
+#define MU_INC1090 1091
+#define MU_INC1089 1090
+#define MU_INC1088 1089
+#define MU_INC1087 1088
+#define MU_INC1086 1087
+#define MU_INC1085 1086
+#define MU_INC1084 1085
+#define MU_INC1083 1084
+#define MU_INC1082 1083
+#define MU_INC1081 1082
+#define MU_INC1080 1081
+#define MU_INC1079 1080
+#define MU_INC1078 1079
+#define MU_INC1077 1078
+#define MU_INC1076 1077
+#define MU_INC1075 1076
+#define MU_INC1074 1075
+#define MU_INC1073 1074
+#define MU_INC1072 1073
+#define MU_INC1071 1072
+#define MU_INC1070 1071
+#define MU_INC1069 1070
+#define MU_INC1068 1069
+#define MU_INC1067 1068
+#define MU_INC1066 1067
+#define MU_INC1065 1066
+#define MU_INC1064 1065
+#define MU_INC1063 1064
+#define MU_INC1062 1063
+#define MU_INC1061 1062
+#define MU_INC1060 1061
+#define MU_INC1059 1060
+#define MU_INC1058 1059
+#define MU_INC1057 1058
+#define MU_INC1056 1057
+#define MU_INC1055 1056
+#define MU_INC1054 1055
+#define MU_INC1053 1054
+#define MU_INC1052 1053
+#define MU_INC1051 1052
+#define MU_INC1050 1051
+#define MU_INC1049 1050
+#define MU_INC1048 1049
+#define MU_INC1047 1048
+#define MU_INC1046 1047
+#define MU_INC1045 1046
+#define MU_INC1044 1045
+#define MU_INC1043 1044
+#define MU_INC1042 1043
+#define MU_INC1041 1042
+#define MU_INC1040 1041
+#define MU_INC1039 1040
+#define MU_INC1038 1039
+#define MU_INC1037 1038
+#define MU_INC1036 1037
+#define MU_INC1035 1036
+#define MU_INC1034 1035
+#define MU_INC1033 1034
+#define MU_INC1032 1033
+#define MU_INC1031 1032
+#define MU_INC1030 1031
+#define MU_INC1029 1030
+#define MU_INC1028 1029
+#define MU_INC1027 1028
+#define MU_INC1026 1027
+#define MU_INC1025 1026
+#define MU_INC1024 1025
+#define MU_INC1023 1024
+#define MU_INC1022 1023
+#define MU_INC1021 1022
+#define MU_INC1020 1021
+#define MU_INC1019 1020
+#define MU_INC1018 1019
+#define MU_INC1017 1018
+#define MU_INC1016 1017
+#define MU_INC1015 1016
+#define MU_INC1014 1015
+#define MU_INC1013 1014
+#define MU_INC1012 1013
+#define MU_INC1011 1012
+#define MU_INC1010 1011
+#define MU_INC1009 1010
+#define MU_INC1008 1009
+#define MU_INC1007 1008
+#define MU_INC1006 1007
+#define MU_INC1005 1006
+#define MU_INC1004 1005
+#define MU_INC1003 1004
+#define MU_INC1002 1003
+#define MU_INC1001 1002
+#define MU_INC1000 1001
+#define MU_INC999 1000
+#define MU_INC998 999
+#define MU_INC997 998
+#define MU_INC996 997
+#define MU_INC995 996
+#define MU_INC994 995
+#define MU_INC993 994
+#define MU_INC992 993
+#define MU_INC991 992
+#define MU_INC990 991
+#define MU_INC989 990
+#define MU_INC988 989
+#define MU_INC987 988
+#define MU_INC986 987
+#define MU_INC985 986
+#define MU_INC984 985
+#define MU_INC983 984
+#define MU_INC982 983
+#define MU_INC981 982
+#define MU_INC980 981
+#define MU_INC979 980
+#define MU_INC978 979
+#define MU_INC977 978
+#define MU_INC976 977
+#define MU_INC975 976
+#define MU_INC974 975
+#define MU_INC973 974
+#define MU_INC972 973
+#define MU_INC971 972
+#define MU_INC970 971
+#define MU_INC969 970
+#define MU_INC968 969
+#define MU_INC967 968
+#define MU_INC966 967
+#define MU_INC965 966
+#define MU_INC964 965
+#define MU_INC963 964
+#define MU_INC962 963
+#define MU_INC961 962
+#define MU_INC960 961
+#define MU_INC959 960
+#define MU_INC958 959
+#define MU_INC957 958
+#define MU_INC956 957
+#define MU_INC955 956
+#define MU_INC954 955
+#define MU_INC953 954
+#define MU_INC952 953
+#define MU_INC951 952
+#define MU_INC950 951
+#define MU_INC949 950
+#define MU_INC948 949
+#define MU_INC947 948
+#define MU_INC946 947
+#define MU_INC945 946
+#define MU_INC944 945
+#define MU_INC943 944
+#define MU_INC942 943
+#define MU_INC941 942
+#define MU_INC940 941
+#define MU_INC939 940
+#define MU_INC938 939
+#define MU_INC937 938
+#define MU_INC936 937
+#define MU_INC935 936
+#define MU_INC934 935
+#define MU_INC933 934
+#define MU_INC932 933
+#define MU_INC931 932
+#define MU_INC930 931
+#define MU_INC929 930
+#define MU_INC928 929
+#define MU_INC927 928
+#define MU_INC926 927
+#define MU_INC925 926
+#define MU_INC924 925
+#define MU_INC923 924
+#define MU_INC922 923
+#define MU_INC921 922
+#define MU_INC920 921
+#define MU_INC919 920
+#define MU_INC918 919
+#define MU_INC917 918
+#define MU_INC916 917
+#define MU_INC915 916
+#define MU_INC914 915
+#define MU_INC913 914
+#define MU_INC912 913
+#define MU_INC911 912
+#define MU_INC910 911
+#define MU_INC909 910
+#define MU_INC908 909
+#define MU_INC907 908
+#define MU_INC906 907
+#define MU_INC905 906
+#define MU_INC904 905
+#define MU_INC903 904
+#define MU_INC902 903
+#define MU_INC901 902
+#define MU_INC900 901
+#define MU_INC899 900
+#define MU_INC898 899
+#define MU_INC897 898
+#define MU_INC896 897
+#define MU_INC895 896
+#define MU_INC894 895
+#define MU_INC893 894
+#define MU_INC892 893
+#define MU_INC891 892
+#define MU_INC890 891
+#define MU_INC889 890
+#define MU_INC888 889
+#define MU_INC887 888
+#define MU_INC886 887
+#define MU_INC885 886
+#define MU_INC884 885
+#define MU_INC883 884
+#define MU_INC882 883
+#define MU_INC881 882
+#define MU_INC880 881
+#define MU_INC879 880
+#define MU_INC878 879
+#define MU_INC877 878
+#define MU_INC876 877
+#define MU_INC875 876
+#define MU_INC874 875
+#define MU_INC873 874
+#define MU_INC872 873
+#define MU_INC871 872
+#define MU_INC870 871
+#define MU_INC869 870
+#define MU_INC868 869
+#define MU_INC867 868
+#define MU_INC866 867
+#define MU_INC865 866
+#define MU_INC864 865
+#define MU_INC863 864
+#define MU_INC862 863
+#define MU_INC861 862
+#define MU_INC860 861
+#define MU_INC859 860
+#define MU_INC858 859
+#define MU_INC857 858
+#define MU_INC856 857
+#define MU_INC855 856
+#define MU_INC854 855
+#define MU_INC853 854
+#define MU_INC852 853
+#define MU_INC851 852
+#define MU_INC850 851
+#define MU_INC849 850
+#define MU_INC848 849
+#define MU_INC847 848
+#define MU_INC846 847
+#define MU_INC845 846
+#define MU_INC844 845
+#define MU_INC843 844
+#define MU_INC842 843
+#define MU_INC841 842
+#define MU_INC840 841
+#define MU_INC839 840
+#define MU_INC838 839
+#define MU_INC837 838
+#define MU_INC836 837
+#define MU_INC835 836
+#define MU_INC834 835
+#define MU_INC833 834
+#define MU_INC832 833
+#define MU_INC831 832
+#define MU_INC830 831
+#define MU_INC829 830
+#define MU_INC828 829
+#define MU_INC827 828
+#define MU_INC826 827
+#define MU_INC825 826
+#define MU_INC824 825
+#define MU_INC823 824
+#define MU_INC822 823
+#define MU_INC821 822
+#define MU_INC820 821
+#define MU_INC819 820
+#define MU_INC818 819
+#define MU_INC817 818
+#define MU_INC816 817
+#define MU_INC815 816
+#define MU_INC814 815
+#define MU_INC813 814
+#define MU_INC812 813
+#define MU_INC811 812
+#define MU_INC810 811
+#define MU_INC809 810
+#define MU_INC808 809
+#define MU_INC807 808
+#define MU_INC806 807
+#define MU_INC805 806
+#define MU_INC804 805
+#define MU_INC803 804
+#define MU_INC802 803
+#define MU_INC801 802
+#define MU_INC800 801
+#define MU_INC799 800
+#define MU_INC798 799
+#define MU_INC797 798
+#define MU_INC796 797
+#define MU_INC795 796
+#define MU_INC794 795
+#define MU_INC793 794
+#define MU_INC792 793
+#define MU_INC791 792
+#define MU_INC790 791
+#define MU_INC789 790
+#define MU_INC788 789
+#define MU_INC787 788
+#define MU_INC786 787
+#define MU_INC785 786
+#define MU_INC784 785
+#define MU_INC783 784
+#define MU_INC782 783
+#define MU_INC781 782
+#define MU_INC780 781
+#define MU_INC779 780
+#define MU_INC778 779
+#define MU_INC777 778
+#define MU_INC776 777
+#define MU_INC775 776
+#define MU_INC774 775
+#define MU_INC773 774
+#define MU_INC772 773
+#define MU_INC771 772
+#define MU_INC770 771
+#define MU_INC769 770
+#define MU_INC768 769
+#define MU_INC767 768
+#define MU_INC766 767
+#define MU_INC765 766
+#define MU_INC764 765
+#define MU_INC763 764
+#define MU_INC762 763
+#define MU_INC761 762
+#define MU_INC760 761
+#define MU_INC759 760
+#define MU_INC758 759
+#define MU_INC757 758
+#define MU_INC756 757
+#define MU_INC755 756
+#define MU_INC754 755
+#define MU_INC753 754
+#define MU_INC752 753
+#define MU_INC751 752
+#define MU_INC750 751
+#define MU_INC749 750
+#define MU_INC748 749
+#define MU_INC747 748
+#define MU_INC746 747
+#define MU_INC745 746
+#define MU_INC744 745
+#define MU_INC743 744
+#define MU_INC742 743
+#define MU_INC741 742
+#define MU_INC740 741
+#define MU_INC739 740
+#define MU_INC738 739
+#define MU_INC737 738
+#define MU_INC736 737
+#define MU_INC735 736
+#define MU_INC734 735
+#define MU_INC733 734
+#define MU_INC732 733
+#define MU_INC731 732
+#define MU_INC730 731
+#define MU_INC729 730
+#define MU_INC728 729
+#define MU_INC727 728
+#define MU_INC726 727
+#define MU_INC725 726
+#define MU_INC724 725
+#define MU_INC723 724
+#define MU_INC722 723
+#define MU_INC721 722
+#define MU_INC720 721
+#define MU_INC719 720
+#define MU_INC718 719
+#define MU_INC717 718
+#define MU_INC716 717
+#define MU_INC715 716
+#define MU_INC714 715
+#define MU_INC713 714
+#define MU_INC712 713
+#define MU_INC711 712
+#define MU_INC710 711
+#define MU_INC709 710
+#define MU_INC708 709
+#define MU_INC707 708
+#define MU_INC706 707
+#define MU_INC705 706
+#define MU_INC704 705
+#define MU_INC703 704
+#define MU_INC702 703
+#define MU_INC701 702
+#define MU_INC700 701
+#define MU_INC699 700
+#define MU_INC698 699
+#define MU_INC697 698
+#define MU_INC696 697
+#define MU_INC695 696
+#define MU_INC694 695
+#define MU_INC693 694
+#define MU_INC692 693
+#define MU_INC691 692
+#define MU_INC690 691
+#define MU_INC689 690
+#define MU_INC688 689
+#define MU_INC687 688
+#define MU_INC686 687
+#define MU_INC685 686
+#define MU_INC684 685
+#define MU_INC683 684
+#define MU_INC682 683
+#define MU_INC681 682
+#define MU_INC680 681
+#define MU_INC679 680
+#define MU_INC678 679
+#define MU_INC677 678
+#define MU_INC676 677
+#define MU_INC675 676
+#define MU_INC674 675
+#define MU_INC673 674
+#define MU_INC672 673
+#define MU_INC671 672
+#define MU_INC670 671
+#define MU_INC669 670
+#define MU_INC668 669
+#define MU_INC667 668
+#define MU_INC666 667
+#define MU_INC665 666
+#define MU_INC664 665
+#define MU_INC663 664
+#define MU_INC662 663
+#define MU_INC661 662
+#define MU_INC660 661
+#define MU_INC659 660
+#define MU_INC658 659
+#define MU_INC657 658
+#define MU_INC656 657
+#define MU_INC655 656
+#define MU_INC654 655
+#define MU_INC653 654
+#define MU_INC652 653
+#define MU_INC651 652
+#define MU_INC650 651
+#define MU_INC649 650
+#define MU_INC648 649
+#define MU_INC647 648
+#define MU_INC646 647
+#define MU_INC645 646
+#define MU_INC644 645
+#define MU_INC643 644
+#define MU_INC642 643
+#define MU_INC641 642
+#define MU_INC640 641
+#define MU_INC639 640
+#define MU_INC638 639
+#define MU_INC637 638
+#define MU_INC636 637
+#define MU_INC635 636
+#define MU_INC634 635
+#define MU_INC633 634
+#define MU_INC632 633
+#define MU_INC631 632
+#define MU_INC630 631
+#define MU_INC629 630
+#define MU_INC628 629
+#define MU_INC627 628
+#define MU_INC626 627
+#define MU_INC625 626
+#define MU_INC624 625
+#define MU_INC623 624
+#define MU_INC622 623
+#define MU_INC621 622
+#define MU_INC620 621
+#define MU_INC619 620
+#define MU_INC618 619
+#define MU_INC617 618
+#define MU_INC616 617
+#define MU_INC615 616
+#define MU_INC614 615
+#define MU_INC613 614
+#define MU_INC612 613
+#define MU_INC611 612
+#define MU_INC610 611
+#define MU_INC609 610
+#define MU_INC608 609
+#define MU_INC607 608
+#define MU_INC606 607
+#define MU_INC605 606
+#define MU_INC604 605
+#define MU_INC603 604
+#define MU_INC602 603
+#define MU_INC601 602
+#define MU_INC600 601
+#define MU_INC599 600
+#define MU_INC598 599
+#define MU_INC597 598
+#define MU_INC596 597
+#define MU_INC595 596
+#define MU_INC594 595
+#define MU_INC593 594
+#define MU_INC592 593
+#define MU_INC591 592
+#define MU_INC590 591
+#define MU_INC589 590
+#define MU_INC588 589
+#define MU_INC587 588
+#define MU_INC586 587
+#define MU_INC585 586
+#define MU_INC584 585
+#define MU_INC583 584
+#define MU_INC582 583
+#define MU_INC581 582
+#define MU_INC580 581
+#define MU_INC579 580
+#define MU_INC578 579
+#define MU_INC577 578
+#define MU_INC576 577
+#define MU_INC575 576
+#define MU_INC574 575
+#define MU_INC573 574
+#define MU_INC572 573
+#define MU_INC571 572
+#define MU_INC570 571
+#define MU_INC569 570
+#define MU_INC568 569
+#define MU_INC567 568
+#define MU_INC566 567
+#define MU_INC565 566
+#define MU_INC564 565
+#define MU_INC563 564
+#define MU_INC562 563
+#define MU_INC561 562
+#define MU_INC560 561
+#define MU_INC559 560
+#define MU_INC558 559
+#define MU_INC557 558
+#define MU_INC556 557
+#define MU_INC555 556
+#define MU_INC554 555
+#define MU_INC553 554
+#define MU_INC552 553
+#define MU_INC551 552
+#define MU_INC550 551
+#define MU_INC549 550
+#define MU_INC548 549
+#define MU_INC547 548
+#define MU_INC546 547
+#define MU_INC545 546
+#define MU_INC544 545
+#define MU_INC543 544
+#define MU_INC542 543
+#define MU_INC541 542
+#define MU_INC540 541
+#define MU_INC539 540
+#define MU_INC538 539
+#define MU_INC537 538
+#define MU_INC536 537
+#define MU_INC535 536
+#define MU_INC534 535
+#define MU_INC533 534
+#define MU_INC532 533
+#define MU_INC531 532
+#define MU_INC530 531
+#define MU_INC529 530
+#define MU_INC528 529
+#define MU_INC527 528
+#define MU_INC526 527
+#define MU_INC525 526
+#define MU_INC524 525
+#define MU_INC523 524
+#define MU_INC522 523
+#define MU_INC521 522
+#define MU_INC520 521
+#define MU_INC519 520
+#define MU_INC518 519
+#define MU_INC517 518
+#define MU_INC516 517
+#define MU_INC515 516
+#define MU_INC514 515
+#define MU_INC513 514
+#define MU_INC512 513
+#define MU_INC511 512
+#define MU_INC510 511
+#define MU_INC509 510
+#define MU_INC508 509
+#define MU_INC507 508
+#define MU_INC506 507
+#define MU_INC505 506
+#define MU_INC504 505
+#define MU_INC503 504
+#define MU_INC502 503
+#define MU_INC501 502
+#define MU_INC500 501
+#define MU_INC499 500
+#define MU_INC498 499
+#define MU_INC497 498
+#define MU_INC496 497
+#define MU_INC495 496
+#define MU_INC494 495
+#define MU_INC493 494
+#define MU_INC492 493
+#define MU_INC491 492
+#define MU_INC490 491
+#define MU_INC489 490
+#define MU_INC488 489
+#define MU_INC487 488
+#define MU_INC486 487
+#define MU_INC485 486
+#define MU_INC484 485
+#define MU_INC483 484
+#define MU_INC482 483
+#define MU_INC481 482
+#define MU_INC480 481
+#define MU_INC479 480
+#define MU_INC478 479
+#define MU_INC477 478
+#define MU_INC476 477
+#define MU_INC475 476
+#define MU_INC474 475
+#define MU_INC473 474
+#define MU_INC472 473
+#define MU_INC471 472
+#define MU_INC470 471
+#define MU_INC469 470
+#define MU_INC468 469
+#define MU_INC467 468
+#define MU_INC466 467
+#define MU_INC465 466
+#define MU_INC464 465
+#define MU_INC463 464
+#define MU_INC462 463
+#define MU_INC461 462
+#define MU_INC460 461
+#define MU_INC459 460
+#define MU_INC458 459
+#define MU_INC457 458
+#define MU_INC456 457
+#define MU_INC455 456
+#define MU_INC454 455
+#define MU_INC453 454
+#define MU_INC452 453
+#define MU_INC451 452
+#define MU_INC450 451
+#define MU_INC449 450
+#define MU_INC448 449
+#define MU_INC447 448
+#define MU_INC446 447
+#define MU_INC445 446
+#define MU_INC444 445
+#define MU_INC443 444
+#define MU_INC442 443
+#define MU_INC441 442
+#define MU_INC440 441
+#define MU_INC439 440
+#define MU_INC438 439
+#define MU_INC437 438
+#define MU_INC436 437
+#define MU_INC435 436
+#define MU_INC434 435
+#define MU_INC433 434
+#define MU_INC432 433
+#define MU_INC431 432
+#define MU_INC430 431
+#define MU_INC429 430
+#define MU_INC428 429
+#define MU_INC427 428
+#define MU_INC426 427
+#define MU_INC425 426
+#define MU_INC424 425
+#define MU_INC423 424
+#define MU_INC422 423
+#define MU_INC421 422
+#define MU_INC420 421
+#define MU_INC419 420
+#define MU_INC418 419
+#define MU_INC417 418
+#define MU_INC416 417
+#define MU_INC415 416
+#define MU_INC414 415
+#define MU_INC413 414
+#define MU_INC412 413
+#define MU_INC411 412
+#define MU_INC410 411
+#define MU_INC409 410
+#define MU_INC408 409
+#define MU_INC407 408
+#define MU_INC406 407
+#define MU_INC405 406
+#define MU_INC404 405
+#define MU_INC403 404
+#define MU_INC402 403
+#define MU_INC401 402
+#define MU_INC400 401
+#define MU_INC399 400
+#define MU_INC398 399
+#define MU_INC397 398
+#define MU_INC396 397
+#define MU_INC395 396
+#define MU_INC394 395
+#define MU_INC393 394
+#define MU_INC392 393
+#define MU_INC391 392
+#define MU_INC390 391
+#define MU_INC389 390
+#define MU_INC388 389
+#define MU_INC387 388
+#define MU_INC386 387
+#define MU_INC385 386
+#define MU_INC384 385
+#define MU_INC383 384
+#define MU_INC382 383
+#define MU_INC381 382
+#define MU_INC380 381
+#define MU_INC379 380
+#define MU_INC378 379
+#define MU_INC377 378
+#define MU_INC376 377
+#define MU_INC375 376
+#define MU_INC374 375
+#define MU_INC373 374
+#define MU_INC372 373
+#define MU_INC371 372
+#define MU_INC370 371
+#define MU_INC369 370
+#define MU_INC368 369
+#define MU_INC367 368
+#define MU_INC366 367
+#define MU_INC365 366
+#define MU_INC364 365
+#define MU_INC363 364
+#define MU_INC362 363
+#define MU_INC361 362
+#define MU_INC360 361
+#define MU_INC359 360
+#define MU_INC358 359
+#define MU_INC357 358
+#define MU_INC356 357
+#define MU_INC355 356
+#define MU_INC354 355
+#define MU_INC353 354
+#define MU_INC352 353
+#define MU_INC351 352
+#define MU_INC350 351
+#define MU_INC349 350
+#define MU_INC348 349
+#define MU_INC347 348
+#define MU_INC346 347
+#define MU_INC345 346
+#define MU_INC344 345
+#define MU_INC343 344
+#define MU_INC342 343
+#define MU_INC341 342
+#define MU_INC340 341
+#define MU_INC339 340
+#define MU_INC338 339
+#define MU_INC337 338
+#define MU_INC336 337
+#define MU_INC335 336
+#define MU_INC334 335
+#define MU_INC333 334
+#define MU_INC332 333
+#define MU_INC331 332
+#define MU_INC330 331
+#define MU_INC329 330
+#define MU_INC328 329
+#define MU_INC327 328
+#define MU_INC326 327
+#define MU_INC325 326
+#define MU_INC324 325
+#define MU_INC323 324
+#define MU_INC322 323
+#define MU_INC321 322
+#define MU_INC320 321
+#define MU_INC319 320
+#define MU_INC318 319
+#define MU_INC317 318
+#define MU_INC316 317
+#define MU_INC315 316
+#define MU_INC314 315
+#define MU_INC313 314
+#define MU_INC312 313
+#define MU_INC311 312
+#define MU_INC310 311
+#define MU_INC309 310
+#define MU_INC308 309
+#define MU_INC307 308
+#define MU_INC306 307
+#define MU_INC305 306
+#define MU_INC304 305
+#define MU_INC303 304
+#define MU_INC302 303
+#define MU_INC301 302
+#define MU_INC300 301
+#define MU_INC299 300
+#define MU_INC298 299
+#define MU_INC297 298
+#define MU_INC296 297
+#define MU_INC295 296
+#define MU_INC294 295
+#define MU_INC293 294
+#define MU_INC292 293
+#define MU_INC291 292
+#define MU_INC290 291
+#define MU_INC289 290
+#define MU_INC288 289
+#define MU_INC287 288
+#define MU_INC286 287
+#define MU_INC285 286
+#define MU_INC284 285
+#define MU_INC283 284
+#define MU_INC282 283
+#define MU_INC281 282
+#define MU_INC280 281
+#define MU_INC279 280
+#define MU_INC278 279
+#define MU_INC277 278
+#define MU_INC276 277
+#define MU_INC275 276
+#define MU_INC274 275
+#define MU_INC273 274
+#define MU_INC272 273
+#define MU_INC271 272
+#define MU_INC270 271
+#define MU_INC269 270
+#define MU_INC268 269
+#define MU_INC267 268
+#define MU_INC266 267
+#define MU_INC265 266
+#define MU_INC264 265
+#define MU_INC263 264
+#define MU_INC262 263
+#define MU_INC261 262
+#define MU_INC260 261
+#define MU_INC259 260
+#define MU_INC258 259
+#define MU_INC257 258
+#define MU_INC256 257
+#define MU_INC255 256
+#define MU_INC254 255
+#define MU_INC253 254
+#define MU_INC252 253
+#define MU_INC251 252
+#define MU_INC250 251
+#define MU_INC249 250
+#define MU_INC248 249
+#define MU_INC247 248
+#define MU_INC246 247
+#define MU_INC245 246
+#define MU_INC244 245
+#define MU_INC243 244
+#define MU_INC242 243
+#define MU_INC241 242
+#define MU_INC240 241
+#define MU_INC239 240
+#define MU_INC238 239
+#define MU_INC237 238
+#define MU_INC236 237
+#define MU_INC235 236
+#define MU_INC234 235
+#define MU_INC233 234
+#define MU_INC232 233
+#define MU_INC231 232
+#define MU_INC230 231
+#define MU_INC229 230
+#define MU_INC228 229
+#define MU_INC227 228
+#define MU_INC226 227
+#define MU_INC225 226
+#define MU_INC224 225
+#define MU_INC223 224
+#define MU_INC222 223
+#define MU_INC221 222
+#define MU_INC220 221
+#define MU_INC219 220
+#define MU_INC218 219
+#define MU_INC217 218
+#define MU_INC216 217
+#define MU_INC215 216
+#define MU_INC214 215
+#define MU_INC213 214
+#define MU_INC212 213
+#define MU_INC211 212
+#define MU_INC210 211
+#define MU_INC209 210
+#define MU_INC208 209
+#define MU_INC207 208
+#define MU_INC206 207
+#define MU_INC205 206
+#define MU_INC204 205
+#define MU_INC203 204
+#define MU_INC202 203
+#define MU_INC201 202
+#define MU_INC200 201
+#define MU_INC199 200
+#define MU_INC198 199
+#define MU_INC197 198
+#define MU_INC196 197
+#define MU_INC195 196
+#define MU_INC194 195
+#define MU_INC193 194
+#define MU_INC192 193
+#define MU_INC191 192
+#define MU_INC190 191
+#define MU_INC189 190
+#define MU_INC188 189
+#define MU_INC187 188
+#define MU_INC186 187
+#define MU_INC185 186
+#define MU_INC184 185
+#define MU_INC183 184
+#define MU_INC182 183
+#define MU_INC181 182
+#define MU_INC180 181
+#define MU_INC179 180
+#define MU_INC178 179
+#define MU_INC177 178
+#define MU_INC176 177
+#define MU_INC175 176
+#define MU_INC174 175
+#define MU_INC173 174
+#define MU_INC172 173
+#define MU_INC171 172
+#define MU_INC170 171
+#define MU_INC169 170
+#define MU_INC168 169
+#define MU_INC167 168
+#define MU_INC166 167
+#define MU_INC165 166
+#define MU_INC164 165
+#define MU_INC163 164
+#define MU_INC162 163
+#define MU_INC161 162
+#define MU_INC160 161
+#define MU_INC159 160
+#define MU_INC158 159
+#define MU_INC157 158
+#define MU_INC156 157
+#define MU_INC155 156
+#define MU_INC154 155
+#define MU_INC153 154
+#define MU_INC152 153
+#define MU_INC151 152
+#define MU_INC150 151
+#define MU_INC149 150
+#define MU_INC148 149
+#define MU_INC147 148
+#define MU_INC146 147
+#define MU_INC145 146
+#define MU_INC144 145
+#define MU_INC143 144
+#define MU_INC142 143
+#define MU_INC141 142
+#define MU_INC140 141
+#define MU_INC139 140
+#define MU_INC138 139
+#define MU_INC137 138
+#define MU_INC136 137
+#define MU_INC135 136
+#define MU_INC134 135
+#define MU_INC133 134
+#define MU_INC132 133
+#define MU_INC131 132
+#define MU_INC130 131
+#define MU_INC129 130
+#define MU_INC128 129
+#define MU_INC127 128
+#define MU_INC126 127
+#define MU_INC125 126
+#define MU_INC124 125
+#define MU_INC123 124
+#define MU_INC122 123
+#define MU_INC121 122
+#define MU_INC120 121
+#define MU_INC119 120
+#define MU_INC118 119
+#define MU_INC117 118
+#define MU_INC116 117
+#define MU_INC115 116
+#define MU_INC114 115
+#define MU_INC113 114
+#define MU_INC112 113
+#define MU_INC111 112
+#define MU_INC110 111
+#define MU_INC109 110
+#define MU_INC108 109
+#define MU_INC107 108
+#define MU_INC106 107
+#define MU_INC105 106
+#define MU_INC104 105
+#define MU_INC103 104
+#define MU_INC102 103
+#define MU_INC101 102
+#define MU_INC100 101
+#define MU_INC99 100
+#define MU_INC98 99
+#define MU_INC97 98
+#define MU_INC96 97
+#define MU_INC95 96
+#define MU_INC94 95
+#define MU_INC93 94
+#define MU_INC92 93
+#define MU_INC91 92
+#define MU_INC90 91
+#define MU_INC89 90
+#define MU_INC88 89
+#define MU_INC87 88
+#define MU_INC86 87
+#define MU_INC85 86
+#define MU_INC84 85
+#define MU_INC83 84
+#define MU_INC82 83
+#define MU_INC81 82
+#define MU_INC80 81
+#define MU_INC79 80
+#define MU_INC78 79
+#define MU_INC77 78
+#define MU_INC76 77
+#define MU_INC75 76
+#define MU_INC74 75
+#define MU_INC73 74
+#define MU_INC72 73
+#define MU_INC71 72
+#define MU_INC70 71
+#define MU_INC69 70
+#define MU_INC68 69
+#define MU_INC67 68
+#define MU_INC66 67
+#define MU_INC65 66
+#define MU_INC64 65
+#define MU_INC63 64
+#define MU_INC62 63
+#define MU_INC61 62
+#define MU_INC60 61
+#define MU_INC59 60
+#define MU_INC58 59
+#define MU_INC57 58
+#define MU_INC56 57
+#define MU_INC55 56
+#define MU_INC54 55
+#define MU_INC53 54
+#define MU_INC52 53
+#define MU_INC51 52
+#define MU_INC50 51
+#define MU_INC49 50
+#define MU_INC48 49
+#define MU_INC47 48
+#define MU_INC46 47
+#define MU_INC45 46
+#define MU_INC44 45
+#define MU_INC43 44
+#define MU_INC42 43
+#define MU_INC41 42
+#define MU_INC40 41
+#define MU_INC39 40
+#define MU_INC38 39
+#define MU_INC37 38
+#define MU_INC36 37
+#define MU_INC35 36
+#define MU_INC34 35
+#define MU_INC33 34
+#define MU_INC32 33
+#define MU_INC31 32
+#define MU_INC30 31
+#define MU_INC29 30
+#define MU_INC28 29
+#define MU_INC27 28
+#define MU_INC26 27
+#define MU_INC25 26
+#define MU_INC24 25
+#define MU_INC23 24
+#define MU_INC22 23
+#define MU_INC21 22
+#define MU_INC20 21
+#define MU_INC19 20
+#define MU_INC18 19
+#define MU_INC17 18
+#define MU_INC16 17
+#define MU_INC15 16
+#define MU_INC14 15
+#define MU_INC13 14
+#define MU_INC12 13
+#define MU_INC11 12
+#define MU_INC10 11
+#define MU_INC9 10
+#define MU_INC8 9
+#define MU_INC7 8
+#define MU_INC6 7
+#define MU_INC5 6
+#define MU_INC4 5
+#define MU_INC3 4
+#define MU_INC2 3
+#define MU_INC1 2
+#define MU_INC0 1
+
+#define MU_DIV2(x) MU_C2(MU_DIV2_,x)
+
+#define MU_DIV2_2048 1024
+#define MU_DIV2_2047 1023
+#define MU_DIV2_2046 1023
+#define MU_DIV2_2045 1022
+#define MU_DIV2_2044 1022
+#define MU_DIV2_2043 1021
+#define MU_DIV2_2042 1021
+#define MU_DIV2_2041 1020
+#define MU_DIV2_2040 1020
+#define MU_DIV2_2039 1019
+#define MU_DIV2_2038 1019
+#define MU_DIV2_2037 1018
+#define MU_DIV2_2036 1018
+#define MU_DIV2_2035 1017
+#define MU_DIV2_2034 1017
+#define MU_DIV2_2033 1016
+#define MU_DIV2_2032 1016
+#define MU_DIV2_2031 1015
+#define MU_DIV2_2030 1015
+#define MU_DIV2_2029 1014
+#define MU_DIV2_2028 1014
+#define MU_DIV2_2027 1013
+#define MU_DIV2_2026 1013
+#define MU_DIV2_2025 1012
+#define MU_DIV2_2024 1012
+#define MU_DIV2_2023 1011
+#define MU_DIV2_2022 1011
+#define MU_DIV2_2021 1010
+#define MU_DIV2_2020 1010
+#define MU_DIV2_2019 1009
+#define MU_DIV2_2018 1009
+#define MU_DIV2_2017 1008
+#define MU_DIV2_2016 1008
+#define MU_DIV2_2015 1007
+#define MU_DIV2_2014 1007
+#define MU_DIV2_2013 1006
+#define MU_DIV2_2012 1006
+#define MU_DIV2_2011 1005
+#define MU_DIV2_2010 1005
+#define MU_DIV2_2009 1004
+#define MU_DIV2_2008 1004
+#define MU_DIV2_2007 1003
+#define MU_DIV2_2006 1003
+#define MU_DIV2_2005 1002
+#define MU_DIV2_2004 1002
+#define MU_DIV2_2003 1001
+#define MU_DIV2_2002 1001
+#define MU_DIV2_2001 1000
+#define MU_DIV2_2000 1000
+#define MU_DIV2_1999 999
+#define MU_DIV2_1998 999
+#define MU_DIV2_1997 998
+#define MU_DIV2_1996 998
+#define MU_DIV2_1995 997
+#define MU_DIV2_1994 997
+#define MU_DIV2_1993 996
+#define MU_DIV2_1992 996
+#define MU_DIV2_1991 995
+#define MU_DIV2_1990 995
+#define MU_DIV2_1989 994
+#define MU_DIV2_1988 994
+#define MU_DIV2_1987 993
+#define MU_DIV2_1986 993
+#define MU_DIV2_1985 992
+#define MU_DIV2_1984 992
+#define MU_DIV2_1983 991
+#define MU_DIV2_1982 991
+#define MU_DIV2_1981 990
+#define MU_DIV2_1980 990
+#define MU_DIV2_1979 989
+#define MU_DIV2_1978 989
+#define MU_DIV2_1977 988
+#define MU_DIV2_1976 988
+#define MU_DIV2_1975 987
+#define MU_DIV2_1974 987
+#define MU_DIV2_1973 986
+#define MU_DIV2_1972 986
+#define MU_DIV2_1971 985
+#define MU_DIV2_1970 985
+#define MU_DIV2_1969 984
+#define MU_DIV2_1968 984
+#define MU_DIV2_1967 983
+#define MU_DIV2_1966 983
+#define MU_DIV2_1965 982
+#define MU_DIV2_1964 982
+#define MU_DIV2_1963 981
+#define MU_DIV2_1962 981
+#define MU_DIV2_1961 980
+#define MU_DIV2_1960 980
+#define MU_DIV2_1959 979
+#define MU_DIV2_1958 979
+#define MU_DIV2_1957 978
+#define MU_DIV2_1956 978
+#define MU_DIV2_1955 977
+#define MU_DIV2_1954 977
+#define MU_DIV2_1953 976
+#define MU_DIV2_1952 976
+#define MU_DIV2_1951 975
+#define MU_DIV2_1950 975
+#define MU_DIV2_1949 974
+#define MU_DIV2_1948 974
+#define MU_DIV2_1947 973
+#define MU_DIV2_1946 973
+#define MU_DIV2_1945 972
+#define MU_DIV2_1944 972
+#define MU_DIV2_1943 971
+#define MU_DIV2_1942 971
+#define MU_DIV2_1941 970
+#define MU_DIV2_1940 970
+#define MU_DIV2_1939 969
+#define MU_DIV2_1938 969
+#define MU_DIV2_1937 968
+#define MU_DIV2_1936 968
+#define MU_DIV2_1935 967
+#define MU_DIV2_1934 967
+#define MU_DIV2_1933 966
+#define MU_DIV2_1932 966
+#define MU_DIV2_1931 965
+#define MU_DIV2_1930 965
+#define MU_DIV2_1929 964
+#define MU_DIV2_1928 964
+#define MU_DIV2_1927 963
+#define MU_DIV2_1926 963
+#define MU_DIV2_1925 962
+#define MU_DIV2_1924 962
+#define MU_DIV2_1923 961
+#define MU_DIV2_1922 961
+#define MU_DIV2_1921 960
+#define MU_DIV2_1920 960
+#define MU_DIV2_1919 959
+#define MU_DIV2_1918 959
+#define MU_DIV2_1917 958
+#define MU_DIV2_1916 958
+#define MU_DIV2_1915 957
+#define MU_DIV2_1914 957
+#define MU_DIV2_1913 956
+#define MU_DIV2_1912 956
+#define MU_DIV2_1911 955
+#define MU_DIV2_1910 955
+#define MU_DIV2_1909 954
+#define MU_DIV2_1908 954
+#define MU_DIV2_1907 953
+#define MU_DIV2_1906 953
+#define MU_DIV2_1905 952
+#define MU_DIV2_1904 952
+#define MU_DIV2_1903 951
+#define MU_DIV2_1902 951
+#define MU_DIV2_1901 950
+#define MU_DIV2_1900 950
+#define MU_DIV2_1899 949
+#define MU_DIV2_1898 949
+#define MU_DIV2_1897 948
+#define MU_DIV2_1896 948
+#define MU_DIV2_1895 947
+#define MU_DIV2_1894 947
+#define MU_DIV2_1893 946
+#define MU_DIV2_1892 946
+#define MU_DIV2_1891 945
+#define MU_DIV2_1890 945
+#define MU_DIV2_1889 944
+#define MU_DIV2_1888 944
+#define MU_DIV2_1887 943
+#define MU_DIV2_1886 943
+#define MU_DIV2_1885 942
+#define MU_DIV2_1884 942
+#define MU_DIV2_1883 941
+#define MU_DIV2_1882 941
+#define MU_DIV2_1881 940
+#define MU_DIV2_1880 940
+#define MU_DIV2_1879 939
+#define MU_DIV2_1878 939
+#define MU_DIV2_1877 938
+#define MU_DIV2_1876 938
+#define MU_DIV2_1875 937
+#define MU_DIV2_1874 937
+#define MU_DIV2_1873 936
+#define MU_DIV2_1872 936
+#define MU_DIV2_1871 935
+#define MU_DIV2_1870 935
+#define MU_DIV2_1869 934
+#define MU_DIV2_1868 934
+#define MU_DIV2_1867 933
+#define MU_DIV2_1866 933
+#define MU_DIV2_1865 932
+#define MU_DIV2_1864 932
+#define MU_DIV2_1863 931
+#define MU_DIV2_1862 931
+#define MU_DIV2_1861 930
+#define MU_DIV2_1860 930
+#define MU_DIV2_1859 929
+#define MU_DIV2_1858 929
+#define MU_DIV2_1857 928
+#define MU_DIV2_1856 928
+#define MU_DIV2_1855 927
+#define MU_DIV2_1854 927
+#define MU_DIV2_1853 926
+#define MU_DIV2_1852 926
+#define MU_DIV2_1851 925
+#define MU_DIV2_1850 925
+#define MU_DIV2_1849 924
+#define MU_DIV2_1848 924
+#define MU_DIV2_1847 923
+#define MU_DIV2_1846 923
+#define MU_DIV2_1845 922
+#define MU_DIV2_1844 922
+#define MU_DIV2_1843 921
+#define MU_DIV2_1842 921
+#define MU_DIV2_1841 920
+#define MU_DIV2_1840 920
+#define MU_DIV2_1839 919
+#define MU_DIV2_1838 919
+#define MU_DIV2_1837 918
+#define MU_DIV2_1836 918
+#define MU_DIV2_1835 917
+#define MU_DIV2_1834 917
+#define MU_DIV2_1833 916
+#define MU_DIV2_1832 916
+#define MU_DIV2_1831 915
+#define MU_DIV2_1830 915
+#define MU_DIV2_1829 914
+#define MU_DIV2_1828 914
+#define MU_DIV2_1827 913
+#define MU_DIV2_1826 913
+#define MU_DIV2_1825 912
+#define MU_DIV2_1824 912
+#define MU_DIV2_1823 911
+#define MU_DIV2_1822 911
+#define MU_DIV2_1821 910
+#define MU_DIV2_1820 910
+#define MU_DIV2_1819 909
+#define MU_DIV2_1818 909
+#define MU_DIV2_1817 908
+#define MU_DIV2_1816 908
+#define MU_DIV2_1815 907
+#define MU_DIV2_1814 907
+#define MU_DIV2_1813 906
+#define MU_DIV2_1812 906
+#define MU_DIV2_1811 905
+#define MU_DIV2_1810 905
+#define MU_DIV2_1809 904
+#define MU_DIV2_1808 904
+#define MU_DIV2_1807 903
+#define MU_DIV2_1806 903
+#define MU_DIV2_1805 902
+#define MU_DIV2_1804 902
+#define MU_DIV2_1803 901
+#define MU_DIV2_1802 901
+#define MU_DIV2_1801 900
+#define MU_DIV2_1800 900
+#define MU_DIV2_1799 899
+#define MU_DIV2_1798 899
+#define MU_DIV2_1797 898
+#define MU_DIV2_1796 898
+#define MU_DIV2_1795 897
+#define MU_DIV2_1794 897
+#define MU_DIV2_1793 896
+#define MU_DIV2_1792 896
+#define MU_DIV2_1791 895
+#define MU_DIV2_1790 895
+#define MU_DIV2_1789 894
+#define MU_DIV2_1788 894
+#define MU_DIV2_1787 893
+#define MU_DIV2_1786 893
+#define MU_DIV2_1785 892
+#define MU_DIV2_1784 892
+#define MU_DIV2_1783 891
+#define MU_DIV2_1782 891
+#define MU_DIV2_1781 890
+#define MU_DIV2_1780 890
+#define MU_DIV2_1779 889
+#define MU_DIV2_1778 889
+#define MU_DIV2_1777 888
+#define MU_DIV2_1776 888
+#define MU_DIV2_1775 887
+#define MU_DIV2_1774 887
+#define MU_DIV2_1773 886
+#define MU_DIV2_1772 886
+#define MU_DIV2_1771 885
+#define MU_DIV2_1770 885
+#define MU_DIV2_1769 884
+#define MU_DIV2_1768 884
+#define MU_DIV2_1767 883
+#define MU_DIV2_1766 883
+#define MU_DIV2_1765 882
+#define MU_DIV2_1764 882
+#define MU_DIV2_1763 881
+#define MU_DIV2_1762 881
+#define MU_DIV2_1761 880
+#define MU_DIV2_1760 880
+#define MU_DIV2_1759 879
+#define MU_DIV2_1758 879
+#define MU_DIV2_1757 878
+#define MU_DIV2_1756 878
+#define MU_DIV2_1755 877
+#define MU_DIV2_1754 877
+#define MU_DIV2_1753 876
+#define MU_DIV2_1752 876
+#define MU_DIV2_1751 875
+#define MU_DIV2_1750 875
+#define MU_DIV2_1749 874
+#define MU_DIV2_1748 874
+#define MU_DIV2_1747 873
+#define MU_DIV2_1746 873
+#define MU_DIV2_1745 872
+#define MU_DIV2_1744 872
+#define MU_DIV2_1743 871
+#define MU_DIV2_1742 871
+#define MU_DIV2_1741 870
+#define MU_DIV2_1740 870
+#define MU_DIV2_1739 869
+#define MU_DIV2_1738 869
+#define MU_DIV2_1737 868
+#define MU_DIV2_1736 868
+#define MU_DIV2_1735 867
+#define MU_DIV2_1734 867
+#define MU_DIV2_1733 866
+#define MU_DIV2_1732 866
+#define MU_DIV2_1731 865
+#define MU_DIV2_1730 865
+#define MU_DIV2_1729 864
+#define MU_DIV2_1728 864
+#define MU_DIV2_1727 863
+#define MU_DIV2_1726 863
+#define MU_DIV2_1725 862
+#define MU_DIV2_1724 862
+#define MU_DIV2_1723 861
+#define MU_DIV2_1722 861
+#define MU_DIV2_1721 860
+#define MU_DIV2_1720 860
+#define MU_DIV2_1719 859
+#define MU_DIV2_1718 859
+#define MU_DIV2_1717 858
+#define MU_DIV2_1716 858
+#define MU_DIV2_1715 857
+#define MU_DIV2_1714 857
+#define MU_DIV2_1713 856
+#define MU_DIV2_1712 856
+#define MU_DIV2_1711 855
+#define MU_DIV2_1710 855
+#define MU_DIV2_1709 854
+#define MU_DIV2_1708 854
+#define MU_DIV2_1707 853
+#define MU_DIV2_1706 853
+#define MU_DIV2_1705 852
+#define MU_DIV2_1704 852
+#define MU_DIV2_1703 851
+#define MU_DIV2_1702 851
+#define MU_DIV2_1701 850
+#define MU_DIV2_1700 850
+#define MU_DIV2_1699 849
+#define MU_DIV2_1698 849
+#define MU_DIV2_1697 848
+#define MU_DIV2_1696 848
+#define MU_DIV2_1695 847
+#define MU_DIV2_1694 847
+#define MU_DIV2_1693 846
+#define MU_DIV2_1692 846
+#define MU_DIV2_1691 845
+#define MU_DIV2_1690 845
+#define MU_DIV2_1689 844
+#define MU_DIV2_1688 844
+#define MU_DIV2_1687 843
+#define MU_DIV2_1686 843
+#define MU_DIV2_1685 842
+#define MU_DIV2_1684 842
+#define MU_DIV2_1683 841
+#define MU_DIV2_1682 841
+#define MU_DIV2_1681 840
+#define MU_DIV2_1680 840
+#define MU_DIV2_1679 839
+#define MU_DIV2_1678 839
+#define MU_DIV2_1677 838
+#define MU_DIV2_1676 838
+#define MU_DIV2_1675 837
+#define MU_DIV2_1674 837
+#define MU_DIV2_1673 836
+#define MU_DIV2_1672 836
+#define MU_DIV2_1671 835
+#define MU_DIV2_1670 835
+#define MU_DIV2_1669 834
+#define MU_DIV2_1668 834
+#define MU_DIV2_1667 833
+#define MU_DIV2_1666 833
+#define MU_DIV2_1665 832
+#define MU_DIV2_1664 832
+#define MU_DIV2_1663 831
+#define MU_DIV2_1662 831
+#define MU_DIV2_1661 830
+#define MU_DIV2_1660 830
+#define MU_DIV2_1659 829
+#define MU_DIV2_1658 829
+#define MU_DIV2_1657 828
+#define MU_DIV2_1656 828
+#define MU_DIV2_1655 827
+#define MU_DIV2_1654 827
+#define MU_DIV2_1653 826
+#define MU_DIV2_1652 826
+#define MU_DIV2_1651 825
+#define MU_DIV2_1650 825
+#define MU_DIV2_1649 824
+#define MU_DIV2_1648 824
+#define MU_DIV2_1647 823
+#define MU_DIV2_1646 823
+#define MU_DIV2_1645 822
+#define MU_DIV2_1644 822
+#define MU_DIV2_1643 821
+#define MU_DIV2_1642 821
+#define MU_DIV2_1641 820
+#define MU_DIV2_1640 820
+#define MU_DIV2_1639 819
+#define MU_DIV2_1638 819
+#define MU_DIV2_1637 818
+#define MU_DIV2_1636 818
+#define MU_DIV2_1635 817
+#define MU_DIV2_1634 817
+#define MU_DIV2_1633 816
+#define MU_DIV2_1632 816
+#define MU_DIV2_1631 815
+#define MU_DIV2_1630 815
+#define MU_DIV2_1629 814
+#define MU_DIV2_1628 814
+#define MU_DIV2_1627 813
+#define MU_DIV2_1626 813
+#define MU_DIV2_1625 812
+#define MU_DIV2_1624 812
+#define MU_DIV2_1623 811
+#define MU_DIV2_1622 811
+#define MU_DIV2_1621 810
+#define MU_DIV2_1620 810
+#define MU_DIV2_1619 809
+#define MU_DIV2_1618 809
+#define MU_DIV2_1617 808
+#define MU_DIV2_1616 808
+#define MU_DIV2_1615 807
+#define MU_DIV2_1614 807
+#define MU_DIV2_1613 806
+#define MU_DIV2_1612 806
+#define MU_DIV2_1611 805
+#define MU_DIV2_1610 805
+#define MU_DIV2_1609 804
+#define MU_DIV2_1608 804
+#define MU_DIV2_1607 803
+#define MU_DIV2_1606 803
+#define MU_DIV2_1605 802
+#define MU_DIV2_1604 802
+#define MU_DIV2_1603 801
+#define MU_DIV2_1602 801
+#define MU_DIV2_1601 800
+#define MU_DIV2_1600 800
+#define MU_DIV2_1599 799
+#define MU_DIV2_1598 799
+#define MU_DIV2_1597 798
+#define MU_DIV2_1596 798
+#define MU_DIV2_1595 797
+#define MU_DIV2_1594 797
+#define MU_DIV2_1593 796
+#define MU_DIV2_1592 796
+#define MU_DIV2_1591 795
+#define MU_DIV2_1590 795
+#define MU_DIV2_1589 794
+#define MU_DIV2_1588 794
+#define MU_DIV2_1587 793
+#define MU_DIV2_1586 793
+#define MU_DIV2_1585 792
+#define MU_DIV2_1584 792
+#define MU_DIV2_1583 791
+#define MU_DIV2_1582 791
+#define MU_DIV2_1581 790
+#define MU_DIV2_1580 790
+#define MU_DIV2_1579 789
+#define MU_DIV2_1578 789
+#define MU_DIV2_1577 788
+#define MU_DIV2_1576 788
+#define MU_DIV2_1575 787
+#define MU_DIV2_1574 787
+#define MU_DIV2_1573 786
+#define MU_DIV2_1572 786
+#define MU_DIV2_1571 785
+#define MU_DIV2_1570 785
+#define MU_DIV2_1569 784
+#define MU_DIV2_1568 784
+#define MU_DIV2_1567 783
+#define MU_DIV2_1566 783
+#define MU_DIV2_1565 782
+#define MU_DIV2_1564 782
+#define MU_DIV2_1563 781
+#define MU_DIV2_1562 781
+#define MU_DIV2_1561 780
+#define MU_DIV2_1560 780
+#define MU_DIV2_1559 779
+#define MU_DIV2_1558 779
+#define MU_DIV2_1557 778
+#define MU_DIV2_1556 778
+#define MU_DIV2_1555 777
+#define MU_DIV2_1554 777
+#define MU_DIV2_1553 776
+#define MU_DIV2_1552 776
+#define MU_DIV2_1551 775
+#define MU_DIV2_1550 775
+#define MU_DIV2_1549 774
+#define MU_DIV2_1548 774
+#define MU_DIV2_1547 773
+#define MU_DIV2_1546 773
+#define MU_DIV2_1545 772
+#define MU_DIV2_1544 772
+#define MU_DIV2_1543 771
+#define MU_DIV2_1542 771
+#define MU_DIV2_1541 770
+#define MU_DIV2_1540 770
+#define MU_DIV2_1539 769
+#define MU_DIV2_1538 769
+#define MU_DIV2_1537 768
+#define MU_DIV2_1536 768
+#define MU_DIV2_1535 767
+#define MU_DIV2_1534 767
+#define MU_DIV2_1533 766
+#define MU_DIV2_1532 766
+#define MU_DIV2_1531 765
+#define MU_DIV2_1530 765
+#define MU_DIV2_1529 764
+#define MU_DIV2_1528 764
+#define MU_DIV2_1527 763
+#define MU_DIV2_1526 763
+#define MU_DIV2_1525 762
+#define MU_DIV2_1524 762
+#define MU_DIV2_1523 761
+#define MU_DIV2_1522 761
+#define MU_DIV2_1521 760
+#define MU_DIV2_1520 760
+#define MU_DIV2_1519 759
+#define MU_DIV2_1518 759
+#define MU_DIV2_1517 758
+#define MU_DIV2_1516 758
+#define MU_DIV2_1515 757
+#define MU_DIV2_1514 757
+#define MU_DIV2_1513 756
+#define MU_DIV2_1512 756
+#define MU_DIV2_1511 755
+#define MU_DIV2_1510 755
+#define MU_DIV2_1509 754
+#define MU_DIV2_1508 754
+#define MU_DIV2_1507 753
+#define MU_DIV2_1506 753
+#define MU_DIV2_1505 752
+#define MU_DIV2_1504 752
+#define MU_DIV2_1503 751
+#define MU_DIV2_1502 751
+#define MU_DIV2_1501 750
+#define MU_DIV2_1500 750
+#define MU_DIV2_1499 749
+#define MU_DIV2_1498 749
+#define MU_DIV2_1497 748
+#define MU_DIV2_1496 748
+#define MU_DIV2_1495 747
+#define MU_DIV2_1494 747
+#define MU_DIV2_1493 746
+#define MU_DIV2_1492 746
+#define MU_DIV2_1491 745
+#define MU_DIV2_1490 745
+#define MU_DIV2_1489 744
+#define MU_DIV2_1488 744
+#define MU_DIV2_1487 743
+#define MU_DIV2_1486 743
+#define MU_DIV2_1485 742
+#define MU_DIV2_1484 742
+#define MU_DIV2_1483 741
+#define MU_DIV2_1482 741
+#define MU_DIV2_1481 740
+#define MU_DIV2_1480 740
+#define MU_DIV2_1479 739
+#define MU_DIV2_1478 739
+#define MU_DIV2_1477 738
+#define MU_DIV2_1476 738
+#define MU_DIV2_1475 737
+#define MU_DIV2_1474 737
+#define MU_DIV2_1473 736
+#define MU_DIV2_1472 736
+#define MU_DIV2_1471 735
+#define MU_DIV2_1470 735
+#define MU_DIV2_1469 734
+#define MU_DIV2_1468 734
+#define MU_DIV2_1467 733
+#define MU_DIV2_1466 733
+#define MU_DIV2_1465 732
+#define MU_DIV2_1464 732
+#define MU_DIV2_1463 731
+#define MU_DIV2_1462 731
+#define MU_DIV2_1461 730
+#define MU_DIV2_1460 730
+#define MU_DIV2_1459 729
+#define MU_DIV2_1458 729
+#define MU_DIV2_1457 728
+#define MU_DIV2_1456 728
+#define MU_DIV2_1455 727
+#define MU_DIV2_1454 727
+#define MU_DIV2_1453 726
+#define MU_DIV2_1452 726
+#define MU_DIV2_1451 725
+#define MU_DIV2_1450 725
+#define MU_DIV2_1449 724
+#define MU_DIV2_1448 724
+#define MU_DIV2_1447 723
+#define MU_DIV2_1446 723
+#define MU_DIV2_1445 722
+#define MU_DIV2_1444 722
+#define MU_DIV2_1443 721
+#define MU_DIV2_1442 721
+#define MU_DIV2_1441 720
+#define MU_DIV2_1440 720
+#define MU_DIV2_1439 719
+#define MU_DIV2_1438 719
+#define MU_DIV2_1437 718
+#define MU_DIV2_1436 718
+#define MU_DIV2_1435 717
+#define MU_DIV2_1434 717
+#define MU_DIV2_1433 716
+#define MU_DIV2_1432 716
+#define MU_DIV2_1431 715
+#define MU_DIV2_1430 715
+#define MU_DIV2_1429 714
+#define MU_DIV2_1428 714
+#define MU_DIV2_1427 713
+#define MU_DIV2_1426 713
+#define MU_DIV2_1425 712
+#define MU_DIV2_1424 712
+#define MU_DIV2_1423 711
+#define MU_DIV2_1422 711
+#define MU_DIV2_1421 710
+#define MU_DIV2_1420 710
+#define MU_DIV2_1419 709
+#define MU_DIV2_1418 709
+#define MU_DIV2_1417 708
+#define MU_DIV2_1416 708
+#define MU_DIV2_1415 707
+#define MU_DIV2_1414 707
+#define MU_DIV2_1413 706
+#define MU_DIV2_1412 706
+#define MU_DIV2_1411 705
+#define MU_DIV2_1410 705
+#define MU_DIV2_1409 704
+#define MU_DIV2_1408 704
+#define MU_DIV2_1407 703
+#define MU_DIV2_1406 703
+#define MU_DIV2_1405 702
+#define MU_DIV2_1404 702
+#define MU_DIV2_1403 701
+#define MU_DIV2_1402 701
+#define MU_DIV2_1401 700
+#define MU_DIV2_1400 700
+#define MU_DIV2_1399 699
+#define MU_DIV2_1398 699
+#define MU_DIV2_1397 698
+#define MU_DIV2_1396 698
+#define MU_DIV2_1395 697
+#define MU_DIV2_1394 697
+#define MU_DIV2_1393 696
+#define MU_DIV2_1392 696
+#define MU_DIV2_1391 695
+#define MU_DIV2_1390 695
+#define MU_DIV2_1389 694
+#define MU_DIV2_1388 694
+#define MU_DIV2_1387 693
+#define MU_DIV2_1386 693
+#define MU_DIV2_1385 692
+#define MU_DIV2_1384 692
+#define MU_DIV2_1383 691
+#define MU_DIV2_1382 691
+#define MU_DIV2_1381 690
+#define MU_DIV2_1380 690
+#define MU_DIV2_1379 689
+#define MU_DIV2_1378 689
+#define MU_DIV2_1377 688
+#define MU_DIV2_1376 688
+#define MU_DIV2_1375 687
+#define MU_DIV2_1374 687
+#define MU_DIV2_1373 686
+#define MU_DIV2_1372 686
+#define MU_DIV2_1371 685
+#define MU_DIV2_1370 685
+#define MU_DIV2_1369 684
+#define MU_DIV2_1368 684
+#define MU_DIV2_1367 683
+#define MU_DIV2_1366 683
+#define MU_DIV2_1365 682
+#define MU_DIV2_1364 682
+#define MU_DIV2_1363 681
+#define MU_DIV2_1362 681
+#define MU_DIV2_1361 680
+#define MU_DIV2_1360 680
+#define MU_DIV2_1359 679
+#define MU_DIV2_1358 679
+#define MU_DIV2_1357 678
+#define MU_DIV2_1356 678
+#define MU_DIV2_1355 677
+#define MU_DIV2_1354 677
+#define MU_DIV2_1353 676
+#define MU_DIV2_1352 676
+#define MU_DIV2_1351 675
+#define MU_DIV2_1350 675
+#define MU_DIV2_1349 674
+#define MU_DIV2_1348 674
+#define MU_DIV2_1347 673
+#define MU_DIV2_1346 673
+#define MU_DIV2_1345 672
+#define MU_DIV2_1344 672
+#define MU_DIV2_1343 671
+#define MU_DIV2_1342 671
+#define MU_DIV2_1341 670
+#define MU_DIV2_1340 670
+#define MU_DIV2_1339 669
+#define MU_DIV2_1338 669
+#define MU_DIV2_1337 668
+#define MU_DIV2_1336 668
+#define MU_DIV2_1335 667
+#define MU_DIV2_1334 667
+#define MU_DIV2_1333 666
+#define MU_DIV2_1332 666
+#define MU_DIV2_1331 665
+#define MU_DIV2_1330 665
+#define MU_DIV2_1329 664
+#define MU_DIV2_1328 664
+#define MU_DIV2_1327 663
+#define MU_DIV2_1326 663
+#define MU_DIV2_1325 662
+#define MU_DIV2_1324 662
+#define MU_DIV2_1323 661
+#define MU_DIV2_1322 661
+#define MU_DIV2_1321 660
+#define MU_DIV2_1320 660
+#define MU_DIV2_1319 659
+#define MU_DIV2_1318 659
+#define MU_DIV2_1317 658
+#define MU_DIV2_1316 658
+#define MU_DIV2_1315 657
+#define MU_DIV2_1314 657
+#define MU_DIV2_1313 656
+#define MU_DIV2_1312 656
+#define MU_DIV2_1311 655
+#define MU_DIV2_1310 655
+#define MU_DIV2_1309 654
+#define MU_DIV2_1308 654
+#define MU_DIV2_1307 653
+#define MU_DIV2_1306 653
+#define MU_DIV2_1305 652
+#define MU_DIV2_1304 652
+#define MU_DIV2_1303 651
+#define MU_DIV2_1302 651
+#define MU_DIV2_1301 650
+#define MU_DIV2_1300 650
+#define MU_DIV2_1299 649
+#define MU_DIV2_1298 649
+#define MU_DIV2_1297 648
+#define MU_DIV2_1296 648
+#define MU_DIV2_1295 647
+#define MU_DIV2_1294 647
+#define MU_DIV2_1293 646
+#define MU_DIV2_1292 646
+#define MU_DIV2_1291 645
+#define MU_DIV2_1290 645
+#define MU_DIV2_1289 644
+#define MU_DIV2_1288 644
+#define MU_DIV2_1287 643
+#define MU_DIV2_1286 643
+#define MU_DIV2_1285 642
+#define MU_DIV2_1284 642
+#define MU_DIV2_1283 641
+#define MU_DIV2_1282 641
+#define MU_DIV2_1281 640
+#define MU_DIV2_1280 640
+#define MU_DIV2_1279 639
+#define MU_DIV2_1278 639
+#define MU_DIV2_1277 638
+#define MU_DIV2_1276 638
+#define MU_DIV2_1275 637
+#define MU_DIV2_1274 637
+#define MU_DIV2_1273 636
+#define MU_DIV2_1272 636
+#define MU_DIV2_1271 635
+#define MU_DIV2_1270 635
+#define MU_DIV2_1269 634
+#define MU_DIV2_1268 634
+#define MU_DIV2_1267 633
+#define MU_DIV2_1266 633
+#define MU_DIV2_1265 632
+#define MU_DIV2_1264 632
+#define MU_DIV2_1263 631
+#define MU_DIV2_1262 631
+#define MU_DIV2_1261 630
+#define MU_DIV2_1260 630
+#define MU_DIV2_1259 629
+#define MU_DIV2_1258 629
+#define MU_DIV2_1257 628
+#define MU_DIV2_1256 628
+#define MU_DIV2_1255 627
+#define MU_DIV2_1254 627
+#define MU_DIV2_1253 626
+#define MU_DIV2_1252 626
+#define MU_DIV2_1251 625
+#define MU_DIV2_1250 625
+#define MU_DIV2_1249 624
+#define MU_DIV2_1248 624
+#define MU_DIV2_1247 623
+#define MU_DIV2_1246 623
+#define MU_DIV2_1245 622
+#define MU_DIV2_1244 622
+#define MU_DIV2_1243 621
+#define MU_DIV2_1242 621
+#define MU_DIV2_1241 620
+#define MU_DIV2_1240 620
+#define MU_DIV2_1239 619
+#define MU_DIV2_1238 619
+#define MU_DIV2_1237 618
+#define MU_DIV2_1236 618
+#define MU_DIV2_1235 617
+#define MU_DIV2_1234 617
+#define MU_DIV2_1233 616
+#define MU_DIV2_1232 616
+#define MU_DIV2_1231 615
+#define MU_DIV2_1230 615
+#define MU_DIV2_1229 614
+#define MU_DIV2_1228 614
+#define MU_DIV2_1227 613
+#define MU_DIV2_1226 613
+#define MU_DIV2_1225 612
+#define MU_DIV2_1224 612
+#define MU_DIV2_1223 611
+#define MU_DIV2_1222 611
+#define MU_DIV2_1221 610
+#define MU_DIV2_1220 610
+#define MU_DIV2_1219 609
+#define MU_DIV2_1218 609
+#define MU_DIV2_1217 608
+#define MU_DIV2_1216 608
+#define MU_DIV2_1215 607
+#define MU_DIV2_1214 607
+#define MU_DIV2_1213 606
+#define MU_DIV2_1212 606
+#define MU_DIV2_1211 605
+#define MU_DIV2_1210 605
+#define MU_DIV2_1209 604
+#define MU_DIV2_1208 604
+#define MU_DIV2_1207 603
+#define MU_DIV2_1206 603
+#define MU_DIV2_1205 602
+#define MU_DIV2_1204 602
+#define MU_DIV2_1203 601
+#define MU_DIV2_1202 601
+#define MU_DIV2_1201 600
+#define MU_DIV2_1200 600
+#define MU_DIV2_1199 599
+#define MU_DIV2_1198 599
+#define MU_DIV2_1197 598
+#define MU_DIV2_1196 598
+#define MU_DIV2_1195 597
+#define MU_DIV2_1194 597
+#define MU_DIV2_1193 596
+#define MU_DIV2_1192 596
+#define MU_DIV2_1191 595
+#define MU_DIV2_1190 595
+#define MU_DIV2_1189 594
+#define MU_DIV2_1188 594
+#define MU_DIV2_1187 593
+#define MU_DIV2_1186 593
+#define MU_DIV2_1185 592
+#define MU_DIV2_1184 592
+#define MU_DIV2_1183 591
+#define MU_DIV2_1182 591
+#define MU_DIV2_1181 590
+#define MU_DIV2_1180 590
+#define MU_DIV2_1179 589
+#define MU_DIV2_1178 589
+#define MU_DIV2_1177 588
+#define MU_DIV2_1176 588
+#define MU_DIV2_1175 587
+#define MU_DIV2_1174 587
+#define MU_DIV2_1173 586
+#define MU_DIV2_1172 586
+#define MU_DIV2_1171 585
+#define MU_DIV2_1170 585
+#define MU_DIV2_1169 584
+#define MU_DIV2_1168 584
+#define MU_DIV2_1167 583
+#define MU_DIV2_1166 583
+#define MU_DIV2_1165 582
+#define MU_DIV2_1164 582
+#define MU_DIV2_1163 581
+#define MU_DIV2_1162 581
+#define MU_DIV2_1161 580
+#define MU_DIV2_1160 580
+#define MU_DIV2_1159 579
+#define MU_DIV2_1158 579
+#define MU_DIV2_1157 578
+#define MU_DIV2_1156 578
+#define MU_DIV2_1155 577
+#define MU_DIV2_1154 577
+#define MU_DIV2_1153 576
+#define MU_DIV2_1152 576
+#define MU_DIV2_1151 575
+#define MU_DIV2_1150 575
+#define MU_DIV2_1149 574
+#define MU_DIV2_1148 574
+#define MU_DIV2_1147 573
+#define MU_DIV2_1146 573
+#define MU_DIV2_1145 572
+#define MU_DIV2_1144 572
+#define MU_DIV2_1143 571
+#define MU_DIV2_1142 571
+#define MU_DIV2_1141 570
+#define MU_DIV2_1140 570
+#define MU_DIV2_1139 569
+#define MU_DIV2_1138 569
+#define MU_DIV2_1137 568
+#define MU_DIV2_1136 568
+#define MU_DIV2_1135 567
+#define MU_DIV2_1134 567
+#define MU_DIV2_1133 566
+#define MU_DIV2_1132 566
+#define MU_DIV2_1131 565
+#define MU_DIV2_1130 565
+#define MU_DIV2_1129 564
+#define MU_DIV2_1128 564
+#define MU_DIV2_1127 563
+#define MU_DIV2_1126 563
+#define MU_DIV2_1125 562
+#define MU_DIV2_1124 562
+#define MU_DIV2_1123 561
+#define MU_DIV2_1122 561
+#define MU_DIV2_1121 560
+#define MU_DIV2_1120 560
+#define MU_DIV2_1119 559
+#define MU_DIV2_1118 559
+#define MU_DIV2_1117 558
+#define MU_DIV2_1116 558
+#define MU_DIV2_1115 557
+#define MU_DIV2_1114 557
+#define MU_DIV2_1113 556
+#define MU_DIV2_1112 556
+#define MU_DIV2_1111 555
+#define MU_DIV2_1110 555
+#define MU_DIV2_1109 554
+#define MU_DIV2_1108 554
+#define MU_DIV2_1107 553
+#define MU_DIV2_1106 553
+#define MU_DIV2_1105 552
+#define MU_DIV2_1104 552
+#define MU_DIV2_1103 551
+#define MU_DIV2_1102 551
+#define MU_DIV2_1101 550
+#define MU_DIV2_1100 550
+#define MU_DIV2_1099 549
+#define MU_DIV2_1098 549
+#define MU_DIV2_1097 548
+#define MU_DIV2_1096 548
+#define MU_DIV2_1095 547
+#define MU_DIV2_1094 547
+#define MU_DIV2_1093 546
+#define MU_DIV2_1092 546
+#define MU_DIV2_1091 545
+#define MU_DIV2_1090 545
+#define MU_DIV2_1089 544
+#define MU_DIV2_1088 544
+#define MU_DIV2_1087 543
+#define MU_DIV2_1086 543
+#define MU_DIV2_1085 542
+#define MU_DIV2_1084 542
+#define MU_DIV2_1083 541
+#define MU_DIV2_1082 541
+#define MU_DIV2_1081 540
+#define MU_DIV2_1080 540
+#define MU_DIV2_1079 539
+#define MU_DIV2_1078 539
+#define MU_DIV2_1077 538
+#define MU_DIV2_1076 538
+#define MU_DIV2_1075 537
+#define MU_DIV2_1074 537
+#define MU_DIV2_1073 536
+#define MU_DIV2_1072 536
+#define MU_DIV2_1071 535
+#define MU_DIV2_1070 535
+#define MU_DIV2_1069 534
+#define MU_DIV2_1068 534
+#define MU_DIV2_1067 533
+#define MU_DIV2_1066 533
+#define MU_DIV2_1065 532
+#define MU_DIV2_1064 532
+#define MU_DIV2_1063 531
+#define MU_DIV2_1062 531
+#define MU_DIV2_1061 530
+#define MU_DIV2_1060 530
+#define MU_DIV2_1059 529
+#define MU_DIV2_1058 529
+#define MU_DIV2_1057 528
+#define MU_DIV2_1056 528
+#define MU_DIV2_1055 527
+#define MU_DIV2_1054 527
+#define MU_DIV2_1053 526
+#define MU_DIV2_1052 526
+#define MU_DIV2_1051 525
+#define MU_DIV2_1050 525
+#define MU_DIV2_1049 524
+#define MU_DIV2_1048 524
+#define MU_DIV2_1047 523
+#define MU_DIV2_1046 523
+#define MU_DIV2_1045 522
+#define MU_DIV2_1044 522
+#define MU_DIV2_1043 521
+#define MU_DIV2_1042 521
+#define MU_DIV2_1041 520
+#define MU_DIV2_1040 520
+#define MU_DIV2_1039 519
+#define MU_DIV2_1038 519
+#define MU_DIV2_1037 518
+#define MU_DIV2_1036 518
+#define MU_DIV2_1035 517
+#define MU_DIV2_1034 517
+#define MU_DIV2_1033 516
+#define MU_DIV2_1032 516
+#define MU_DIV2_1031 515
+#define MU_DIV2_1030 515
+#define MU_DIV2_1029 514
+#define MU_DIV2_1028 514
+#define MU_DIV2_1027 513
+#define MU_DIV2_1026 513
+#define MU_DIV2_1025 512
+#define MU_DIV2_1024 512
+#define MU_DIV2_1023 511
+#define MU_DIV2_1022 511
+#define MU_DIV2_1021 510
+#define MU_DIV2_1020 510
+#define MU_DIV2_1019 509
+#define MU_DIV2_1018 509
+#define MU_DIV2_1017 508
+#define MU_DIV2_1016 508
+#define MU_DIV2_1015 507
+#define MU_DIV2_1014 507
+#define MU_DIV2_1013 506
+#define MU_DIV2_1012 506
+#define MU_DIV2_1011 505
+#define MU_DIV2_1010 505
+#define MU_DIV2_1009 504
+#define MU_DIV2_1008 504
+#define MU_DIV2_1007 503
+#define MU_DIV2_1006 503
+#define MU_DIV2_1005 502
+#define MU_DIV2_1004 502
+#define MU_DIV2_1003 501
+#define MU_DIV2_1002 501
+#define MU_DIV2_1001 500
+#define MU_DIV2_1000 500
+#define MU_DIV2_999 499
+#define MU_DIV2_998 499
+#define MU_DIV2_997 498
+#define MU_DIV2_996 498
+#define MU_DIV2_995 497
+#define MU_DIV2_994 497
+#define MU_DIV2_993 496
+#define MU_DIV2_992 496
+#define MU_DIV2_991 495
+#define MU_DIV2_990 495
+#define MU_DIV2_989 494
+#define MU_DIV2_988 494
+#define MU_DIV2_987 493
+#define MU_DIV2_986 493
+#define MU_DIV2_985 492
+#define MU_DIV2_984 492
+#define MU_DIV2_983 491
+#define MU_DIV2_982 491
+#define MU_DIV2_981 490
+#define MU_DIV2_980 490
+#define MU_DIV2_979 489
+#define MU_DIV2_978 489
+#define MU_DIV2_977 488
+#define MU_DIV2_976 488
+#define MU_DIV2_975 487
+#define MU_DIV2_974 487
+#define MU_DIV2_973 486
+#define MU_DIV2_972 486
+#define MU_DIV2_971 485
+#define MU_DIV2_970 485
+#define MU_DIV2_969 484
+#define MU_DIV2_968 484
+#define MU_DIV2_967 483
+#define MU_DIV2_966 483
+#define MU_DIV2_965 482
+#define MU_DIV2_964 482
+#define MU_DIV2_963 481
+#define MU_DIV2_962 481
+#define MU_DIV2_961 480
+#define MU_DIV2_960 480
+#define MU_DIV2_959 479
+#define MU_DIV2_958 479
+#define MU_DIV2_957 478
+#define MU_DIV2_956 478
+#define MU_DIV2_955 477
+#define MU_DIV2_954 477
+#define MU_DIV2_953 476
+#define MU_DIV2_952 476
+#define MU_DIV2_951 475
+#define MU_DIV2_950 475
+#define MU_DIV2_949 474
+#define MU_DIV2_948 474
+#define MU_DIV2_947 473
+#define MU_DIV2_946 473
+#define MU_DIV2_945 472
+#define MU_DIV2_944 472
+#define MU_DIV2_943 471
+#define MU_DIV2_942 471
+#define MU_DIV2_941 470
+#define MU_DIV2_940 470
+#define MU_DIV2_939 469
+#define MU_DIV2_938 469
+#define MU_DIV2_937 468
+#define MU_DIV2_936 468
+#define MU_DIV2_935 467
+#define MU_DIV2_934 467
+#define MU_DIV2_933 466
+#define MU_DIV2_932 466
+#define MU_DIV2_931 465
+#define MU_DIV2_930 465
+#define MU_DIV2_929 464
+#define MU_DIV2_928 464
+#define MU_DIV2_927 463
+#define MU_DIV2_926 463
+#define MU_DIV2_925 462
+#define MU_DIV2_924 462
+#define MU_DIV2_923 461
+#define MU_DIV2_922 461
+#define MU_DIV2_921 460
+#define MU_DIV2_920 460
+#define MU_DIV2_919 459
+#define MU_DIV2_918 459
+#define MU_DIV2_917 458
+#define MU_DIV2_916 458
+#define MU_DIV2_915 457
+#define MU_DIV2_914 457
+#define MU_DIV2_913 456
+#define MU_DIV2_912 456
+#define MU_DIV2_911 455
+#define MU_DIV2_910 455
+#define MU_DIV2_909 454
+#define MU_DIV2_908 454
+#define MU_DIV2_907 453
+#define MU_DIV2_906 453
+#define MU_DIV2_905 452
+#define MU_DIV2_904 452
+#define MU_DIV2_903 451
+#define MU_DIV2_902 451
+#define MU_DIV2_901 450
+#define MU_DIV2_900 450
+#define MU_DIV2_899 449
+#define MU_DIV2_898 449
+#define MU_DIV2_897 448
+#define MU_DIV2_896 448
+#define MU_DIV2_895 447
+#define MU_DIV2_894 447
+#define MU_DIV2_893 446
+#define MU_DIV2_892 446
+#define MU_DIV2_891 445
+#define MU_DIV2_890 445
+#define MU_DIV2_889 444
+#define MU_DIV2_888 444
+#define MU_DIV2_887 443
+#define MU_DIV2_886 443
+#define MU_DIV2_885 442
+#define MU_DIV2_884 442
+#define MU_DIV2_883 441
+#define MU_DIV2_882 441
+#define MU_DIV2_881 440
+#define MU_DIV2_880 440
+#define MU_DIV2_879 439
+#define MU_DIV2_878 439
+#define MU_DIV2_877 438
+#define MU_DIV2_876 438
+#define MU_DIV2_875 437
+#define MU_DIV2_874 437
+#define MU_DIV2_873 436
+#define MU_DIV2_872 436
+#define MU_DIV2_871 435
+#define MU_DIV2_870 435
+#define MU_DIV2_869 434
+#define MU_DIV2_868 434
+#define MU_DIV2_867 433
+#define MU_DIV2_866 433
+#define MU_DIV2_865 432
+#define MU_DIV2_864 432
+#define MU_DIV2_863 431
+#define MU_DIV2_862 431
+#define MU_DIV2_861 430
+#define MU_DIV2_860 430
+#define MU_DIV2_859 429
+#define MU_DIV2_858 429
+#define MU_DIV2_857 428
+#define MU_DIV2_856 428
+#define MU_DIV2_855 427
+#define MU_DIV2_854 427
+#define MU_DIV2_853 426
+#define MU_DIV2_852 426
+#define MU_DIV2_851 425
+#define MU_DIV2_850 425
+#define MU_DIV2_849 424
+#define MU_DIV2_848 424
+#define MU_DIV2_847 423
+#define MU_DIV2_846 423
+#define MU_DIV2_845 422
+#define MU_DIV2_844 422
+#define MU_DIV2_843 421
+#define MU_DIV2_842 421
+#define MU_DIV2_841 420
+#define MU_DIV2_840 420
+#define MU_DIV2_839 419
+#define MU_DIV2_838 419
+#define MU_DIV2_837 418
+#define MU_DIV2_836 418
+#define MU_DIV2_835 417
+#define MU_DIV2_834 417
+#define MU_DIV2_833 416
+#define MU_DIV2_832 416
+#define MU_DIV2_831 415
+#define MU_DIV2_830 415
+#define MU_DIV2_829 414
+#define MU_DIV2_828 414
+#define MU_DIV2_827 413
+#define MU_DIV2_826 413
+#define MU_DIV2_825 412
+#define MU_DIV2_824 412
+#define MU_DIV2_823 411
+#define MU_DIV2_822 411
+#define MU_DIV2_821 410
+#define MU_DIV2_820 410
+#define MU_DIV2_819 409
+#define MU_DIV2_818 409
+#define MU_DIV2_817 408
+#define MU_DIV2_816 408
+#define MU_DIV2_815 407
+#define MU_DIV2_814 407
+#define MU_DIV2_813 406
+#define MU_DIV2_812 406
+#define MU_DIV2_811 405
+#define MU_DIV2_810 405
+#define MU_DIV2_809 404
+#define MU_DIV2_808 404
+#define MU_DIV2_807 403
+#define MU_DIV2_806 403
+#define MU_DIV2_805 402
+#define MU_DIV2_804 402
+#define MU_DIV2_803 401
+#define MU_DIV2_802 401
+#define MU_DIV2_801 400
+#define MU_DIV2_800 400
+#define MU_DIV2_799 399
+#define MU_DIV2_798 399
+#define MU_DIV2_797 398
+#define MU_DIV2_796 398
+#define MU_DIV2_795 397
+#define MU_DIV2_794 397
+#define MU_DIV2_793 396
+#define MU_DIV2_792 396
+#define MU_DIV2_791 395
+#define MU_DIV2_790 395
+#define MU_DIV2_789 394
+#define MU_DIV2_788 394
+#define MU_DIV2_787 393
+#define MU_DIV2_786 393
+#define MU_DIV2_785 392
+#define MU_DIV2_784 392
+#define MU_DIV2_783 391
+#define MU_DIV2_782 391
+#define MU_DIV2_781 390
+#define MU_DIV2_780 390
+#define MU_DIV2_779 389
+#define MU_DIV2_778 389
+#define MU_DIV2_777 388
+#define MU_DIV2_776 388
+#define MU_DIV2_775 387
+#define MU_DIV2_774 387
+#define MU_DIV2_773 386
+#define MU_DIV2_772 386
+#define MU_DIV2_771 385
+#define MU_DIV2_770 385
+#define MU_DIV2_769 384
+#define MU_DIV2_768 384
+#define MU_DIV2_767 383
+#define MU_DIV2_766 383
+#define MU_DIV2_765 382
+#define MU_DIV2_764 382
+#define MU_DIV2_763 381
+#define MU_DIV2_762 381
+#define MU_DIV2_761 380
+#define MU_DIV2_760 380
+#define MU_DIV2_759 379
+#define MU_DIV2_758 379
+#define MU_DIV2_757 378
+#define MU_DIV2_756 378
+#define MU_DIV2_755 377
+#define MU_DIV2_754 377
+#define MU_DIV2_753 376
+#define MU_DIV2_752 376
+#define MU_DIV2_751 375
+#define MU_DIV2_750 375
+#define MU_DIV2_749 374
+#define MU_DIV2_748 374
+#define MU_DIV2_747 373
+#define MU_DIV2_746 373
+#define MU_DIV2_745 372
+#define MU_DIV2_744 372
+#define MU_DIV2_743 371
+#define MU_DIV2_742 371
+#define MU_DIV2_741 370
+#define MU_DIV2_740 370
+#define MU_DIV2_739 369
+#define MU_DIV2_738 369
+#define MU_DIV2_737 368
+#define MU_DIV2_736 368
+#define MU_DIV2_735 367
+#define MU_DIV2_734 367
+#define MU_DIV2_733 366
+#define MU_DIV2_732 366
+#define MU_DIV2_731 365
+#define MU_DIV2_730 365
+#define MU_DIV2_729 364
+#define MU_DIV2_728 364
+#define MU_DIV2_727 363
+#define MU_DIV2_726 363
+#define MU_DIV2_725 362
+#define MU_DIV2_724 362
+#define MU_DIV2_723 361
+#define MU_DIV2_722 361
+#define MU_DIV2_721 360
+#define MU_DIV2_720 360
+#define MU_DIV2_719 359
+#define MU_DIV2_718 359
+#define MU_DIV2_717 358
+#define MU_DIV2_716 358
+#define MU_DIV2_715 357
+#define MU_DIV2_714 357
+#define MU_DIV2_713 356
+#define MU_DIV2_712 356
+#define MU_DIV2_711 355
+#define MU_DIV2_710 355
+#define MU_DIV2_709 354
+#define MU_DIV2_708 354
+#define MU_DIV2_707 353
+#define MU_DIV2_706 353
+#define MU_DIV2_705 352
+#define MU_DIV2_704 352
+#define MU_DIV2_703 351
+#define MU_DIV2_702 351
+#define MU_DIV2_701 350
+#define MU_DIV2_700 350
+#define MU_DIV2_699 349
+#define MU_DIV2_698 349
+#define MU_DIV2_697 348
+#define MU_DIV2_696 348
+#define MU_DIV2_695 347
+#define MU_DIV2_694 347
+#define MU_DIV2_693 346
+#define MU_DIV2_692 346
+#define MU_DIV2_691 345
+#define MU_DIV2_690 345
+#define MU_DIV2_689 344
+#define MU_DIV2_688 344
+#define MU_DIV2_687 343
+#define MU_DIV2_686 343
+#define MU_DIV2_685 342
+#define MU_DIV2_684 342
+#define MU_DIV2_683 341
+#define MU_DIV2_682 341
+#define MU_DIV2_681 340
+#define MU_DIV2_680 340
+#define MU_DIV2_679 339
+#define MU_DIV2_678 339
+#define MU_DIV2_677 338
+#define MU_DIV2_676 338
+#define MU_DIV2_675 337
+#define MU_DIV2_674 337
+#define MU_DIV2_673 336
+#define MU_DIV2_672 336
+#define MU_DIV2_671 335
+#define MU_DIV2_670 335
+#define MU_DIV2_669 334
+#define MU_DIV2_668 334
+#define MU_DIV2_667 333
+#define MU_DIV2_666 333
+#define MU_DIV2_665 332
+#define MU_DIV2_664 332
+#define MU_DIV2_663 331
+#define MU_DIV2_662 331
+#define MU_DIV2_661 330
+#define MU_DIV2_660 330
+#define MU_DIV2_659 329
+#define MU_DIV2_658 329
+#define MU_DIV2_657 328
+#define MU_DIV2_656 328
+#define MU_DIV2_655 327
+#define MU_DIV2_654 327
+#define MU_DIV2_653 326
+#define MU_DIV2_652 326
+#define MU_DIV2_651 325
+#define MU_DIV2_650 325
+#define MU_DIV2_649 324
+#define MU_DIV2_648 324
+#define MU_DIV2_647 323
+#define MU_DIV2_646 323
+#define MU_DIV2_645 322
+#define MU_DIV2_644 322
+#define MU_DIV2_643 321
+#define MU_DIV2_642 321
+#define MU_DIV2_641 320
+#define MU_DIV2_640 320
+#define MU_DIV2_639 319
+#define MU_DIV2_638 319
+#define MU_DIV2_637 318
+#define MU_DIV2_636 318
+#define MU_DIV2_635 317
+#define MU_DIV2_634 317
+#define MU_DIV2_633 316
+#define MU_DIV2_632 316
+#define MU_DIV2_631 315
+#define MU_DIV2_630 315
+#define MU_DIV2_629 314
+#define MU_DIV2_628 314
+#define MU_DIV2_627 313
+#define MU_DIV2_626 313
+#define MU_DIV2_625 312
+#define MU_DIV2_624 312
+#define MU_DIV2_623 311
+#define MU_DIV2_622 311
+#define MU_DIV2_621 310
+#define MU_DIV2_620 310
+#define MU_DIV2_619 309
+#define MU_DIV2_618 309
+#define MU_DIV2_617 308
+#define MU_DIV2_616 308
+#define MU_DIV2_615 307
+#define MU_DIV2_614 307
+#define MU_DIV2_613 306
+#define MU_DIV2_612 306
+#define MU_DIV2_611 305
+#define MU_DIV2_610 305
+#define MU_DIV2_609 304
+#define MU_DIV2_608 304
+#define MU_DIV2_607 303
+#define MU_DIV2_606 303
+#define MU_DIV2_605 302
+#define MU_DIV2_604 302
+#define MU_DIV2_603 301
+#define MU_DIV2_602 301
+#define MU_DIV2_601 300
+#define MU_DIV2_600 300
+#define MU_DIV2_599 299
+#define MU_DIV2_598 299
+#define MU_DIV2_597 298
+#define MU_DIV2_596 298
+#define MU_DIV2_595 297
+#define MU_DIV2_594 297
+#define MU_DIV2_593 296
+#define MU_DIV2_592 296
+#define MU_DIV2_591 295
+#define MU_DIV2_590 295
+#define MU_DIV2_589 294
+#define MU_DIV2_588 294
+#define MU_DIV2_587 293
+#define MU_DIV2_586 293
+#define MU_DIV2_585 292
+#define MU_DIV2_584 292
+#define MU_DIV2_583 291
+#define MU_DIV2_582 291
+#define MU_DIV2_581 290
+#define MU_DIV2_580 290
+#define MU_DIV2_579 289
+#define MU_DIV2_578 289
+#define MU_DIV2_577 288
+#define MU_DIV2_576 288
+#define MU_DIV2_575 287
+#define MU_DIV2_574 287
+#define MU_DIV2_573 286
+#define MU_DIV2_572 286
+#define MU_DIV2_571 285
+#define MU_DIV2_570 285
+#define MU_DIV2_569 284
+#define MU_DIV2_568 284
+#define MU_DIV2_567 283
+#define MU_DIV2_566 283
+#define MU_DIV2_565 282
+#define MU_DIV2_564 282
+#define MU_DIV2_563 281
+#define MU_DIV2_562 281
+#define MU_DIV2_561 280
+#define MU_DIV2_560 280
+#define MU_DIV2_559 279
+#define MU_DIV2_558 279
+#define MU_DIV2_557 278
+#define MU_DIV2_556 278
+#define MU_DIV2_555 277
+#define MU_DIV2_554 277
+#define MU_DIV2_553 276
+#define MU_DIV2_552 276
+#define MU_DIV2_551 275
+#define MU_DIV2_550 275
+#define MU_DIV2_549 274
+#define MU_DIV2_548 274
+#define MU_DIV2_547 273
+#define MU_DIV2_546 273
+#define MU_DIV2_545 272
+#define MU_DIV2_544 272
+#define MU_DIV2_543 271
+#define MU_DIV2_542 271
+#define MU_DIV2_541 270
+#define MU_DIV2_540 270
+#define MU_DIV2_539 269
+#define MU_DIV2_538 269
+#define MU_DIV2_537 268
+#define MU_DIV2_536 268
+#define MU_DIV2_535 267
+#define MU_DIV2_534 267
+#define MU_DIV2_533 266
+#define MU_DIV2_532 266
+#define MU_DIV2_531 265
+#define MU_DIV2_530 265
+#define MU_DIV2_529 264
+#define MU_DIV2_528 264
+#define MU_DIV2_527 263
+#define MU_DIV2_526 263
+#define MU_DIV2_525 262
+#define MU_DIV2_524 262
+#define MU_DIV2_523 261
+#define MU_DIV2_522 261
+#define MU_DIV2_521 260
+#define MU_DIV2_520 260
+#define MU_DIV2_519 259
+#define MU_DIV2_518 259
+#define MU_DIV2_517 258
+#define MU_DIV2_516 258
+#define MU_DIV2_515 257
+#define MU_DIV2_514 257
+#define MU_DIV2_513 256
+#define MU_DIV2_512 256
+#define MU_DIV2_511 255
+#define MU_DIV2_510 255
+#define MU_DIV2_509 254
+#define MU_DIV2_508 254
+#define MU_DIV2_507 253
+#define MU_DIV2_506 253
+#define MU_DIV2_505 252
+#define MU_DIV2_504 252
+#define MU_DIV2_503 251
+#define MU_DIV2_502 251
+#define MU_DIV2_501 250
+#define MU_DIV2_500 250
+#define MU_DIV2_499 249
+#define MU_DIV2_498 249
+#define MU_DIV2_497 248
+#define MU_DIV2_496 248
+#define MU_DIV2_495 247
+#define MU_DIV2_494 247
+#define MU_DIV2_493 246
+#define MU_DIV2_492 246
+#define MU_DIV2_491 245
+#define MU_DIV2_490 245
+#define MU_DIV2_489 244
+#define MU_DIV2_488 244
+#define MU_DIV2_487 243
+#define MU_DIV2_486 243
+#define MU_DIV2_485 242
+#define MU_DIV2_484 242
+#define MU_DIV2_483 241
+#define MU_DIV2_482 241
+#define MU_DIV2_481 240
+#define MU_DIV2_480 240
+#define MU_DIV2_479 239
+#define MU_DIV2_478 239
+#define MU_DIV2_477 238
+#define MU_DIV2_476 238
+#define MU_DIV2_475 237
+#define MU_DIV2_474 237
+#define MU_DIV2_473 236
+#define MU_DIV2_472 236
+#define MU_DIV2_471 235
+#define MU_DIV2_470 235
+#define MU_DIV2_469 234
+#define MU_DIV2_468 234
+#define MU_DIV2_467 233
+#define MU_DIV2_466 233
+#define MU_DIV2_465 232
+#define MU_DIV2_464 232
+#define MU_DIV2_463 231
+#define MU_DIV2_462 231
+#define MU_DIV2_461 230
+#define MU_DIV2_460 230
+#define MU_DIV2_459 229
+#define MU_DIV2_458 229
+#define MU_DIV2_457 228
+#define MU_DIV2_456 228
+#define MU_DIV2_455 227
+#define MU_DIV2_454 227
+#define MU_DIV2_453 226
+#define MU_DIV2_452 226
+#define MU_DIV2_451 225
+#define MU_DIV2_450 225
+#define MU_DIV2_449 224
+#define MU_DIV2_448 224
+#define MU_DIV2_447 223
+#define MU_DIV2_446 223
+#define MU_DIV2_445 222
+#define MU_DIV2_444 222
+#define MU_DIV2_443 221
+#define MU_DIV2_442 221
+#define MU_DIV2_441 220
+#define MU_DIV2_440 220
+#define MU_DIV2_439 219
+#define MU_DIV2_438 219
+#define MU_DIV2_437 218
+#define MU_DIV2_436 218
+#define MU_DIV2_435 217
+#define MU_DIV2_434 217
+#define MU_DIV2_433 216
+#define MU_DIV2_432 216
+#define MU_DIV2_431 215
+#define MU_DIV2_430 215
+#define MU_DIV2_429 214
+#define MU_DIV2_428 214
+#define MU_DIV2_427 213
+#define MU_DIV2_426 213
+#define MU_DIV2_425 212
+#define MU_DIV2_424 212
+#define MU_DIV2_423 211
+#define MU_DIV2_422 211
+#define MU_DIV2_421 210
+#define MU_DIV2_420 210
+#define MU_DIV2_419 209
+#define MU_DIV2_418 209
+#define MU_DIV2_417 208
+#define MU_DIV2_416 208
+#define MU_DIV2_415 207
+#define MU_DIV2_414 207
+#define MU_DIV2_413 206
+#define MU_DIV2_412 206
+#define MU_DIV2_411 205
+#define MU_DIV2_410 205
+#define MU_DIV2_409 204
+#define MU_DIV2_408 204
+#define MU_DIV2_407 203
+#define MU_DIV2_406 203
+#define MU_DIV2_405 202
+#define MU_DIV2_404 202
+#define MU_DIV2_403 201
+#define MU_DIV2_402 201
+#define MU_DIV2_401 200
+#define MU_DIV2_400 200
+#define MU_DIV2_399 199
+#define MU_DIV2_398 199
+#define MU_DIV2_397 198
+#define MU_DIV2_396 198
+#define MU_DIV2_395 197
+#define MU_DIV2_394 197
+#define MU_DIV2_393 196
+#define MU_DIV2_392 196
+#define MU_DIV2_391 195
+#define MU_DIV2_390 195
+#define MU_DIV2_389 194
+#define MU_DIV2_388 194
+#define MU_DIV2_387 193
+#define MU_DIV2_386 193
+#define MU_DIV2_385 192
+#define MU_DIV2_384 192
+#define MU_DIV2_383 191
+#define MU_DIV2_382 191
+#define MU_DIV2_381 190
+#define MU_DIV2_380 190
+#define MU_DIV2_379 189
+#define MU_DIV2_378 189
+#define MU_DIV2_377 188
+#define MU_DIV2_376 188
+#define MU_DIV2_375 187
+#define MU_DIV2_374 187
+#define MU_DIV2_373 186
+#define MU_DIV2_372 186
+#define MU_DIV2_371 185
+#define MU_DIV2_370 185
+#define MU_DIV2_369 184
+#define MU_DIV2_368 184
+#define MU_DIV2_367 183
+#define MU_DIV2_366 183
+#define MU_DIV2_365 182
+#define MU_DIV2_364 182
+#define MU_DIV2_363 181
+#define MU_DIV2_362 181
+#define MU_DIV2_361 180
+#define MU_DIV2_360 180
+#define MU_DIV2_359 179
+#define MU_DIV2_358 179
+#define MU_DIV2_357 178
+#define MU_DIV2_356 178
+#define MU_DIV2_355 177
+#define MU_DIV2_354 177
+#define MU_DIV2_353 176
+#define MU_DIV2_352 176
+#define MU_DIV2_351 175
+#define MU_DIV2_350 175
+#define MU_DIV2_349 174
+#define MU_DIV2_348 174
+#define MU_DIV2_347 173
+#define MU_DIV2_346 173
+#define MU_DIV2_345 172
+#define MU_DIV2_344 172
+#define MU_DIV2_343 171
+#define MU_DIV2_342 171
+#define MU_DIV2_341 170
+#define MU_DIV2_340 170
+#define MU_DIV2_339 169
+#define MU_DIV2_338 169
+#define MU_DIV2_337 168
+#define MU_DIV2_336 168
+#define MU_DIV2_335 167
+#define MU_DIV2_334 167
+#define MU_DIV2_333 166
+#define MU_DIV2_332 166
+#define MU_DIV2_331 165
+#define MU_DIV2_330 165
+#define MU_DIV2_329 164
+#define MU_DIV2_328 164
+#define MU_DIV2_327 163
+#define MU_DIV2_326 163
+#define MU_DIV2_325 162
+#define MU_DIV2_324 162
+#define MU_DIV2_323 161
+#define MU_DIV2_322 161
+#define MU_DIV2_321 160
+#define MU_DIV2_320 160
+#define MU_DIV2_319 159
+#define MU_DIV2_318 159
+#define MU_DIV2_317 158
+#define MU_DIV2_316 158
+#define MU_DIV2_315 157
+#define MU_DIV2_314 157
+#define MU_DIV2_313 156
+#define MU_DIV2_312 156
+#define MU_DIV2_311 155
+#define MU_DIV2_310 155
+#define MU_DIV2_309 154
+#define MU_DIV2_308 154
+#define MU_DIV2_307 153
+#define MU_DIV2_306 153
+#define MU_DIV2_305 152
+#define MU_DIV2_304 152
+#define MU_DIV2_303 151
+#define MU_DIV2_302 151
+#define MU_DIV2_301 150
+#define MU_DIV2_300 150
+#define MU_DIV2_299 149
+#define MU_DIV2_298 149
+#define MU_DIV2_297 148
+#define MU_DIV2_296 148
+#define MU_DIV2_295 147
+#define MU_DIV2_294 147
+#define MU_DIV2_293 146
+#define MU_DIV2_292 146
+#define MU_DIV2_291 145
+#define MU_DIV2_290 145
+#define MU_DIV2_289 144
+#define MU_DIV2_288 144
+#define MU_DIV2_287 143
+#define MU_DIV2_286 143
+#define MU_DIV2_285 142
+#define MU_DIV2_284 142
+#define MU_DIV2_283 141
+#define MU_DIV2_282 141
+#define MU_DIV2_281 140
+#define MU_DIV2_280 140
+#define MU_DIV2_279 139
+#define MU_DIV2_278 139
+#define MU_DIV2_277 138
+#define MU_DIV2_276 138
+#define MU_DIV2_275 137
+#define MU_DIV2_274 137
+#define MU_DIV2_273 136
+#define MU_DIV2_272 136
+#define MU_DIV2_271 135
+#define MU_DIV2_270 135
+#define MU_DIV2_269 134
+#define MU_DIV2_268 134
+#define MU_DIV2_267 133
+#define MU_DIV2_266 133
+#define MU_DIV2_265 132
+#define MU_DIV2_264 132
+#define MU_DIV2_263 131
+#define MU_DIV2_262 131
+#define MU_DIV2_261 130
+#define MU_DIV2_260 130
+#define MU_DIV2_259 129
+#define MU_DIV2_258 129
+#define MU_DIV2_257 128
+#define MU_DIV2_256 128
+#define MU_DIV2_255 127
+#define MU_DIV2_254 127
+#define MU_DIV2_253 126
+#define MU_DIV2_252 126
+#define MU_DIV2_251 125
+#define MU_DIV2_250 125
+#define MU_DIV2_249 124
+#define MU_DIV2_248 124
+#define MU_DIV2_247 123
+#define MU_DIV2_246 123
+#define MU_DIV2_245 122
+#define MU_DIV2_244 122
+#define MU_DIV2_243 121
+#define MU_DIV2_242 121
+#define MU_DIV2_241 120
+#define MU_DIV2_240 120
+#define MU_DIV2_239 119
+#define MU_DIV2_238 119
+#define MU_DIV2_237 118
+#define MU_DIV2_236 118
+#define MU_DIV2_235 117
+#define MU_DIV2_234 117
+#define MU_DIV2_233 116
+#define MU_DIV2_232 116
+#define MU_DIV2_231 115
+#define MU_DIV2_230 115
+#define MU_DIV2_229 114
+#define MU_DIV2_228 114
+#define MU_DIV2_227 113
+#define MU_DIV2_226 113
+#define MU_DIV2_225 112
+#define MU_DIV2_224 112
+#define MU_DIV2_223 111
+#define MU_DIV2_222 111
+#define MU_DIV2_221 110
+#define MU_DIV2_220 110
+#define MU_DIV2_219 109
+#define MU_DIV2_218 109
+#define MU_DIV2_217 108
+#define MU_DIV2_216 108
+#define MU_DIV2_215 107
+#define MU_DIV2_214 107
+#define MU_DIV2_213 106
+#define MU_DIV2_212 106
+#define MU_DIV2_211 105
+#define MU_DIV2_210 105
+#define MU_DIV2_209 104
+#define MU_DIV2_208 104
+#define MU_DIV2_207 103
+#define MU_DIV2_206 103
+#define MU_DIV2_205 102
+#define MU_DIV2_204 102
+#define MU_DIV2_203 101
+#define MU_DIV2_202 101
+#define MU_DIV2_201 100
+#define MU_DIV2_200 100
+#define MU_DIV2_199 99
+#define MU_DIV2_198 99
+#define MU_DIV2_197 98
+#define MU_DIV2_196 98
+#define MU_DIV2_195 97
+#define MU_DIV2_194 97
+#define MU_DIV2_193 96
+#define MU_DIV2_192 96
+#define MU_DIV2_191 95
+#define MU_DIV2_190 95
+#define MU_DIV2_189 94
+#define MU_DIV2_188 94
+#define MU_DIV2_187 93
+#define MU_DIV2_186 93
+#define MU_DIV2_185 92
+#define MU_DIV2_184 92
+#define MU_DIV2_183 91
+#define MU_DIV2_182 91
+#define MU_DIV2_181 90
+#define MU_DIV2_180 90
+#define MU_DIV2_179 89
+#define MU_DIV2_178 89
+#define MU_DIV2_177 88
+#define MU_DIV2_176 88
+#define MU_DIV2_175 87
+#define MU_DIV2_174 87
+#define MU_DIV2_173 86
+#define MU_DIV2_172 86
+#define MU_DIV2_171 85
+#define MU_DIV2_170 85
+#define MU_DIV2_169 84
+#define MU_DIV2_168 84
+#define MU_DIV2_167 83
+#define MU_DIV2_166 83
+#define MU_DIV2_165 82
+#define MU_DIV2_164 82
+#define MU_DIV2_163 81
+#define MU_DIV2_162 81
+#define MU_DIV2_161 80
+#define MU_DIV2_160 80
+#define MU_DIV2_159 79
+#define MU_DIV2_158 79
+#define MU_DIV2_157 78
+#define MU_DIV2_156 78
+#define MU_DIV2_155 77
+#define MU_DIV2_154 77
+#define MU_DIV2_153 76
+#define MU_DIV2_152 76
+#define MU_DIV2_151 75
+#define MU_DIV2_150 75
+#define MU_DIV2_149 74
+#define MU_DIV2_148 74
+#define MU_DIV2_147 73
+#define MU_DIV2_146 73
+#define MU_DIV2_145 72
+#define MU_DIV2_144 72
+#define MU_DIV2_143 71
+#define MU_DIV2_142 71
+#define MU_DIV2_141 70
+#define MU_DIV2_140 70
+#define MU_DIV2_139 69
+#define MU_DIV2_138 69
+#define MU_DIV2_137 68
+#define MU_DIV2_136 68
+#define MU_DIV2_135 67
+#define MU_DIV2_134 67
+#define MU_DIV2_133 66
+#define MU_DIV2_132 66
+#define MU_DIV2_131 65
+#define MU_DIV2_130 65
+#define MU_DIV2_129 64
+#define MU_DIV2_128 64
+#define MU_DIV2_127 63
+#define MU_DIV2_126 63
+#define MU_DIV2_125 62
+#define MU_DIV2_124 62
+#define MU_DIV2_123 61
+#define MU_DIV2_122 61
+#define MU_DIV2_121 60
+#define MU_DIV2_120 60
+#define MU_DIV2_119 59
+#define MU_DIV2_118 59
+#define MU_DIV2_117 58
+#define MU_DIV2_116 58
+#define MU_DIV2_115 57
+#define MU_DIV2_114 57
+#define MU_DIV2_113 56
+#define MU_DIV2_112 56
+#define MU_DIV2_111 55
+#define MU_DIV2_110 55
+#define MU_DIV2_109 54
+#define MU_DIV2_108 54
+#define MU_DIV2_107 53
+#define MU_DIV2_106 53
+#define MU_DIV2_105 52
+#define MU_DIV2_104 52
+#define MU_DIV2_103 51
+#define MU_DIV2_102 51
+#define MU_DIV2_101 50
+#define MU_DIV2_100 50
+#define MU_DIV2_99 49
+#define MU_DIV2_98 49
+#define MU_DIV2_97 48
+#define MU_DIV2_96 48
+#define MU_DIV2_95 47
+#define MU_DIV2_94 47
+#define MU_DIV2_93 46
+#define MU_DIV2_92 46
+#define MU_DIV2_91 45
+#define MU_DIV2_90 45
+#define MU_DIV2_89 44
+#define MU_DIV2_88 44
+#define MU_DIV2_87 43
+#define MU_DIV2_86 43
+#define MU_DIV2_85 42
+#define MU_DIV2_84 42
+#define MU_DIV2_83 41
+#define MU_DIV2_82 41
+#define MU_DIV2_81 40
+#define MU_DIV2_80 40
+#define MU_DIV2_79 39
+#define MU_DIV2_78 39
+#define MU_DIV2_77 38
+#define MU_DIV2_76 38
+#define MU_DIV2_75 37
+#define MU_DIV2_74 37
+#define MU_DIV2_73 36
+#define MU_DIV2_72 36
+#define MU_DIV2_71 35
+#define MU_DIV2_70 35
+#define MU_DIV2_69 34
+#define MU_DIV2_68 34
+#define MU_DIV2_67 33
+#define MU_DIV2_66 33
+#define MU_DIV2_65 32
+#define MU_DIV2_64 32
+#define MU_DIV2_63 31
+#define MU_DIV2_62 31
+#define MU_DIV2_61 30
+#define MU_DIV2_60 30
+#define MU_DIV2_59 29
+#define MU_DIV2_58 29
+#define MU_DIV2_57 28
+#define MU_DIV2_56 28
+#define MU_DIV2_55 27
+#define MU_DIV2_54 27
+#define MU_DIV2_53 26
+#define MU_DIV2_52 26
+#define MU_DIV2_51 25
+#define MU_DIV2_50 25
+#define MU_DIV2_49 24
+#define MU_DIV2_48 24
+#define MU_DIV2_47 23
+#define MU_DIV2_46 23
+#define MU_DIV2_45 22
+#define MU_DIV2_44 22
+#define MU_DIV2_43 21
+#define MU_DIV2_42 21
+#define MU_DIV2_41 20
+#define MU_DIV2_40 20
+#define MU_DIV2_39 19
+#define MU_DIV2_38 19
+#define MU_DIV2_37 18
+#define MU_DIV2_36 18
+#define MU_DIV2_35 17
+#define MU_DIV2_34 17
+#define MU_DIV2_33 16
+#define MU_DIV2_32 16
+#define MU_DIV2_31 15
+#define MU_DIV2_30 15
+#define MU_DIV2_29 14
+#define MU_DIV2_28 14
+#define MU_DIV2_27 13
+#define MU_DIV2_26 13
+#define MU_DIV2_25 12
+#define MU_DIV2_24 12
+#define MU_DIV2_23 11
+#define MU_DIV2_22 11
+#define MU_DIV2_21 10
+#define MU_DIV2_20 10
+#define MU_DIV2_19 9
+#define MU_DIV2_18 9
+#define MU_DIV2_17 8
+#define MU_DIV2_16 8
+#define MU_DIV2_15 7
+#define MU_DIV2_14 7
+#define MU_DIV2_13 6
+#define MU_DIV2_12 6
+#define MU_DIV2_11 5
+#define MU_DIV2_10 5
+#define MU_DIV2_9 4
+#define MU_DIV2_8 4
+#define MU_DIV2_7 3
+#define MU_DIV2_6 3
+#define MU_DIV2_5 2
+#define MU_DIV2_4 2
+#define MU_DIV2_3 1
+#define MU_DIV2_2 1
+#define MU_DIV2_1 0
+#define MU_DIV2_0 0
+
+#define MU_MOD2(x) MU_C2(MU_MOD2_,x)
+#define MU_MOD2_2048 0
+#define MU_MOD2_2047 1
+#define MU_MOD2_2046 0
+#define MU_MOD2_2045 1
+#define MU_MOD2_2044 0
+#define MU_MOD2_2043 1
+#define MU_MOD2_2042 0
+#define MU_MOD2_2041 1
+#define MU_MOD2_2040 0
+#define MU_MOD2_2039 1
+#define MU_MOD2_2038 0
+#define MU_MOD2_2037 1
+#define MU_MOD2_2036 0
+#define MU_MOD2_2035 1
+#define MU_MOD2_2034 0
+#define MU_MOD2_2033 1
+#define MU_MOD2_2032 0
+#define MU_MOD2_2031 1
+#define MU_MOD2_2030 0
+#define MU_MOD2_2029 1
+#define MU_MOD2_2028 0
+#define MU_MOD2_2027 1
+#define MU_MOD2_2026 0
+#define MU_MOD2_2025 1
+#define MU_MOD2_2024 0
+#define MU_MOD2_2023 1
+#define MU_MOD2_2022 0
+#define MU_MOD2_2021 1
+#define MU_MOD2_2020 0
+#define MU_MOD2_2019 1
+#define MU_MOD2_2018 0
+#define MU_MOD2_2017 1
+#define MU_MOD2_2016 0
+#define MU_MOD2_2015 1
+#define MU_MOD2_2014 0
+#define MU_MOD2_2013 1
+#define MU_MOD2_2012 0
+#define MU_MOD2_2011 1
+#define MU_MOD2_2010 0
+#define MU_MOD2_2009 1
+#define MU_MOD2_2008 0
+#define MU_MOD2_2007 1
+#define MU_MOD2_2006 0
+#define MU_MOD2_2005 1
+#define MU_MOD2_2004 0
+#define MU_MOD2_2003 1
+#define MU_MOD2_2002 0
+#define MU_MOD2_2001 1
+#define MU_MOD2_2000 0
+#define MU_MOD2_1999 1
+#define MU_MOD2_1998 0
+#define MU_MOD2_1997 1
+#define MU_MOD2_1996 0
+#define MU_MOD2_1995 1
+#define MU_MOD2_1994 0
+#define MU_MOD2_1993 1
+#define MU_MOD2_1992 0
+#define MU_MOD2_1991 1
+#define MU_MOD2_1990 0
+#define MU_MOD2_1989 1
+#define MU_MOD2_1988 0
+#define MU_MOD2_1987 1
+#define MU_MOD2_1986 0
+#define MU_MOD2_1985 1
+#define MU_MOD2_1984 0
+#define MU_MOD2_1983 1
+#define MU_MOD2_1982 0
+#define MU_MOD2_1981 1
+#define MU_MOD2_1980 0
+#define MU_MOD2_1979 1
+#define MU_MOD2_1978 0
+#define MU_MOD2_1977 1
+#define MU_MOD2_1976 0
+#define MU_MOD2_1975 1
+#define MU_MOD2_1974 0
+#define MU_MOD2_1973 1
+#define MU_MOD2_1972 0
+#define MU_MOD2_1971 1
+#define MU_MOD2_1970 0
+#define MU_MOD2_1969 1
+#define MU_MOD2_1968 0
+#define MU_MOD2_1967 1
+#define MU_MOD2_1966 0
+#define MU_MOD2_1965 1
+#define MU_MOD2_1964 0
+#define MU_MOD2_1963 1
+#define MU_MOD2_1962 0
+#define MU_MOD2_1961 1
+#define MU_MOD2_1960 0
+#define MU_MOD2_1959 1
+#define MU_MOD2_1958 0
+#define MU_MOD2_1957 1
+#define MU_MOD2_1956 0
+#define MU_MOD2_1955 1
+#define MU_MOD2_1954 0
+#define MU_MOD2_1953 1
+#define MU_MOD2_1952 0
+#define MU_MOD2_1951 1
+#define MU_MOD2_1950 0
+#define MU_MOD2_1949 1
+#define MU_MOD2_1948 0
+#define MU_MOD2_1947 1
+#define MU_MOD2_1946 0
+#define MU_MOD2_1945 1
+#define MU_MOD2_1944 0
+#define MU_MOD2_1943 1
+#define MU_MOD2_1942 0
+#define MU_MOD2_1941 1
+#define MU_MOD2_1940 0
+#define MU_MOD2_1939 1
+#define MU_MOD2_1938 0
+#define MU_MOD2_1937 1
+#define MU_MOD2_1936 0
+#define MU_MOD2_1935 1
+#define MU_MOD2_1934 0
+#define MU_MOD2_1933 1
+#define MU_MOD2_1932 0
+#define MU_MOD2_1931 1
+#define MU_MOD2_1930 0
+#define MU_MOD2_1929 1
+#define MU_MOD2_1928 0
+#define MU_MOD2_1927 1
+#define MU_MOD2_1926 0
+#define MU_MOD2_1925 1
+#define MU_MOD2_1924 0
+#define MU_MOD2_1923 1
+#define MU_MOD2_1922 0
+#define MU_MOD2_1921 1
+#define MU_MOD2_1920 0
+#define MU_MOD2_1919 1
+#define MU_MOD2_1918 0
+#define MU_MOD2_1917 1
+#define MU_MOD2_1916 0
+#define MU_MOD2_1915 1
+#define MU_MOD2_1914 0
+#define MU_MOD2_1913 1
+#define MU_MOD2_1912 0
+#define MU_MOD2_1911 1
+#define MU_MOD2_1910 0
+#define MU_MOD2_1909 1
+#define MU_MOD2_1908 0
+#define MU_MOD2_1907 1
+#define MU_MOD2_1906 0
+#define MU_MOD2_1905 1
+#define MU_MOD2_1904 0
+#define MU_MOD2_1903 1
+#define MU_MOD2_1902 0
+#define MU_MOD2_1901 1
+#define MU_MOD2_1900 0
+#define MU_MOD2_1899 1
+#define MU_MOD2_1898 0
+#define MU_MOD2_1897 1
+#define MU_MOD2_1896 0
+#define MU_MOD2_1895 1
+#define MU_MOD2_1894 0
+#define MU_MOD2_1893 1
+#define MU_MOD2_1892 0
+#define MU_MOD2_1891 1
+#define MU_MOD2_1890 0
+#define MU_MOD2_1889 1
+#define MU_MOD2_1888 0
+#define MU_MOD2_1887 1
+#define MU_MOD2_1886 0
+#define MU_MOD2_1885 1
+#define MU_MOD2_1884 0
+#define MU_MOD2_1883 1
+#define MU_MOD2_1882 0
+#define MU_MOD2_1881 1
+#define MU_MOD2_1880 0
+#define MU_MOD2_1879 1
+#define MU_MOD2_1878 0
+#define MU_MOD2_1877 1
+#define MU_MOD2_1876 0
+#define MU_MOD2_1875 1
+#define MU_MOD2_1874 0
+#define MU_MOD2_1873 1
+#define MU_MOD2_1872 0
+#define MU_MOD2_1871 1
+#define MU_MOD2_1870 0
+#define MU_MOD2_1869 1
+#define MU_MOD2_1868 0
+#define MU_MOD2_1867 1
+#define MU_MOD2_1866 0
+#define MU_MOD2_1865 1
+#define MU_MOD2_1864 0
+#define MU_MOD2_1863 1
+#define MU_MOD2_1862 0
+#define MU_MOD2_1861 1
+#define MU_MOD2_1860 0
+#define MU_MOD2_1859 1
+#define MU_MOD2_1858 0
+#define MU_MOD2_1857 1
+#define MU_MOD2_1856 0
+#define MU_MOD2_1855 1
+#define MU_MOD2_1854 0
+#define MU_MOD2_1853 1
+#define MU_MOD2_1852 0
+#define MU_MOD2_1851 1
+#define MU_MOD2_1850 0
+#define MU_MOD2_1849 1
+#define MU_MOD2_1848 0
+#define MU_MOD2_1847 1
+#define MU_MOD2_1846 0
+#define MU_MOD2_1845 1
+#define MU_MOD2_1844 0
+#define MU_MOD2_1843 1
+#define MU_MOD2_1842 0
+#define MU_MOD2_1841 1
+#define MU_MOD2_1840 0
+#define MU_MOD2_1839 1
+#define MU_MOD2_1838 0
+#define MU_MOD2_1837 1
+#define MU_MOD2_1836 0
+#define MU_MOD2_1835 1
+#define MU_MOD2_1834 0
+#define MU_MOD2_1833 1
+#define MU_MOD2_1832 0
+#define MU_MOD2_1831 1
+#define MU_MOD2_1830 0
+#define MU_MOD2_1829 1
+#define MU_MOD2_1828 0
+#define MU_MOD2_1827 1
+#define MU_MOD2_1826 0
+#define MU_MOD2_1825 1
+#define MU_MOD2_1824 0
+#define MU_MOD2_1823 1
+#define MU_MOD2_1822 0
+#define MU_MOD2_1821 1
+#define MU_MOD2_1820 0
+#define MU_MOD2_1819 1
+#define MU_MOD2_1818 0
+#define MU_MOD2_1817 1
+#define MU_MOD2_1816 0
+#define MU_MOD2_1815 1
+#define MU_MOD2_1814 0
+#define MU_MOD2_1813 1
+#define MU_MOD2_1812 0
+#define MU_MOD2_1811 1
+#define MU_MOD2_1810 0
+#define MU_MOD2_1809 1
+#define MU_MOD2_1808 0
+#define MU_MOD2_1807 1
+#define MU_MOD2_1806 0
+#define MU_MOD2_1805 1
+#define MU_MOD2_1804 0
+#define MU_MOD2_1803 1
+#define MU_MOD2_1802 0
+#define MU_MOD2_1801 1
+#define MU_MOD2_1800 0
+#define MU_MOD2_1799 1
+#define MU_MOD2_1798 0
+#define MU_MOD2_1797 1
+#define MU_MOD2_1796 0
+#define MU_MOD2_1795 1
+#define MU_MOD2_1794 0
+#define MU_MOD2_1793 1
+#define MU_MOD2_1792 0
+#define MU_MOD2_1791 1
+#define MU_MOD2_1790 0
+#define MU_MOD2_1789 1
+#define MU_MOD2_1788 0
+#define MU_MOD2_1787 1
+#define MU_MOD2_1786 0
+#define MU_MOD2_1785 1
+#define MU_MOD2_1784 0
+#define MU_MOD2_1783 1
+#define MU_MOD2_1782 0
+#define MU_MOD2_1781 1
+#define MU_MOD2_1780 0
+#define MU_MOD2_1779 1
+#define MU_MOD2_1778 0
+#define MU_MOD2_1777 1
+#define MU_MOD2_1776 0
+#define MU_MOD2_1775 1
+#define MU_MOD2_1774 0
+#define MU_MOD2_1773 1
+#define MU_MOD2_1772 0
+#define MU_MOD2_1771 1
+#define MU_MOD2_1770 0
+#define MU_MOD2_1769 1
+#define MU_MOD2_1768 0
+#define MU_MOD2_1767 1
+#define MU_MOD2_1766 0
+#define MU_MOD2_1765 1
+#define MU_MOD2_1764 0
+#define MU_MOD2_1763 1
+#define MU_MOD2_1762 0
+#define MU_MOD2_1761 1
+#define MU_MOD2_1760 0
+#define MU_MOD2_1759 1
+#define MU_MOD2_1758 0
+#define MU_MOD2_1757 1
+#define MU_MOD2_1756 0
+#define MU_MOD2_1755 1
+#define MU_MOD2_1754 0
+#define MU_MOD2_1753 1
+#define MU_MOD2_1752 0
+#define MU_MOD2_1751 1
+#define MU_MOD2_1750 0
+#define MU_MOD2_1749 1
+#define MU_MOD2_1748 0
+#define MU_MOD2_1747 1
+#define MU_MOD2_1746 0
+#define MU_MOD2_1745 1
+#define MU_MOD2_1744 0
+#define MU_MOD2_1743 1
+#define MU_MOD2_1742 0
+#define MU_MOD2_1741 1
+#define MU_MOD2_1740 0
+#define MU_MOD2_1739 1
+#define MU_MOD2_1738 0
+#define MU_MOD2_1737 1
+#define MU_MOD2_1736 0
+#define MU_MOD2_1735 1
+#define MU_MOD2_1734 0
+#define MU_MOD2_1733 1
+#define MU_MOD2_1732 0
+#define MU_MOD2_1731 1
+#define MU_MOD2_1730 0
+#define MU_MOD2_1729 1
+#define MU_MOD2_1728 0
+#define MU_MOD2_1727 1
+#define MU_MOD2_1726 0
+#define MU_MOD2_1725 1
+#define MU_MOD2_1724 0
+#define MU_MOD2_1723 1
+#define MU_MOD2_1722 0
+#define MU_MOD2_1721 1
+#define MU_MOD2_1720 0
+#define MU_MOD2_1719 1
+#define MU_MOD2_1718 0
+#define MU_MOD2_1717 1
+#define MU_MOD2_1716 0
+#define MU_MOD2_1715 1
+#define MU_MOD2_1714 0
+#define MU_MOD2_1713 1
+#define MU_MOD2_1712 0
+#define MU_MOD2_1711 1
+#define MU_MOD2_1710 0
+#define MU_MOD2_1709 1
+#define MU_MOD2_1708 0
+#define MU_MOD2_1707 1
+#define MU_MOD2_1706 0
+#define MU_MOD2_1705 1
+#define MU_MOD2_1704 0
+#define MU_MOD2_1703 1
+#define MU_MOD2_1702 0
+#define MU_MOD2_1701 1
+#define MU_MOD2_1700 0
+#define MU_MOD2_1699 1
+#define MU_MOD2_1698 0
+#define MU_MOD2_1697 1
+#define MU_MOD2_1696 0
+#define MU_MOD2_1695 1
+#define MU_MOD2_1694 0
+#define MU_MOD2_1693 1
+#define MU_MOD2_1692 0
+#define MU_MOD2_1691 1
+#define MU_MOD2_1690 0
+#define MU_MOD2_1689 1
+#define MU_MOD2_1688 0
+#define MU_MOD2_1687 1
+#define MU_MOD2_1686 0
+#define MU_MOD2_1685 1
+#define MU_MOD2_1684 0
+#define MU_MOD2_1683 1
+#define MU_MOD2_1682 0
+#define MU_MOD2_1681 1
+#define MU_MOD2_1680 0
+#define MU_MOD2_1679 1
+#define MU_MOD2_1678 0
+#define MU_MOD2_1677 1
+#define MU_MOD2_1676 0
+#define MU_MOD2_1675 1
+#define MU_MOD2_1674 0
+#define MU_MOD2_1673 1
+#define MU_MOD2_1672 0
+#define MU_MOD2_1671 1
+#define MU_MOD2_1670 0
+#define MU_MOD2_1669 1
+#define MU_MOD2_1668 0
+#define MU_MOD2_1667 1
+#define MU_MOD2_1666 0
+#define MU_MOD2_1665 1
+#define MU_MOD2_1664 0
+#define MU_MOD2_1663 1
+#define MU_MOD2_1662 0
+#define MU_MOD2_1661 1
+#define MU_MOD2_1660 0
+#define MU_MOD2_1659 1
+#define MU_MOD2_1658 0
+#define MU_MOD2_1657 1
+#define MU_MOD2_1656 0
+#define MU_MOD2_1655 1
+#define MU_MOD2_1654 0
+#define MU_MOD2_1653 1
+#define MU_MOD2_1652 0
+#define MU_MOD2_1651 1
+#define MU_MOD2_1650 0
+#define MU_MOD2_1649 1
+#define MU_MOD2_1648 0
+#define MU_MOD2_1647 1
+#define MU_MOD2_1646 0
+#define MU_MOD2_1645 1
+#define MU_MOD2_1644 0
+#define MU_MOD2_1643 1
+#define MU_MOD2_1642 0
+#define MU_MOD2_1641 1
+#define MU_MOD2_1640 0
+#define MU_MOD2_1639 1
+#define MU_MOD2_1638 0
+#define MU_MOD2_1637 1
+#define MU_MOD2_1636 0
+#define MU_MOD2_1635 1
+#define MU_MOD2_1634 0
+#define MU_MOD2_1633 1
+#define MU_MOD2_1632 0
+#define MU_MOD2_1631 1
+#define MU_MOD2_1630 0
+#define MU_MOD2_1629 1
+#define MU_MOD2_1628 0
+#define MU_MOD2_1627 1
+#define MU_MOD2_1626 0
+#define MU_MOD2_1625 1
+#define MU_MOD2_1624 0
+#define MU_MOD2_1623 1
+#define MU_MOD2_1622 0
+#define MU_MOD2_1621 1
+#define MU_MOD2_1620 0
+#define MU_MOD2_1619 1
+#define MU_MOD2_1618 0
+#define MU_MOD2_1617 1
+#define MU_MOD2_1616 0
+#define MU_MOD2_1615 1
+#define MU_MOD2_1614 0
+#define MU_MOD2_1613 1
+#define MU_MOD2_1612 0
+#define MU_MOD2_1611 1
+#define MU_MOD2_1610 0
+#define MU_MOD2_1609 1
+#define MU_MOD2_1608 0
+#define MU_MOD2_1607 1
+#define MU_MOD2_1606 0
+#define MU_MOD2_1605 1
+#define MU_MOD2_1604 0
+#define MU_MOD2_1603 1
+#define MU_MOD2_1602 0
+#define MU_MOD2_1601 1
+#define MU_MOD2_1600 0
+#define MU_MOD2_1599 1
+#define MU_MOD2_1598 0
+#define MU_MOD2_1597 1
+#define MU_MOD2_1596 0
+#define MU_MOD2_1595 1
+#define MU_MOD2_1594 0
+#define MU_MOD2_1593 1
+#define MU_MOD2_1592 0
+#define MU_MOD2_1591 1
+#define MU_MOD2_1590 0
+#define MU_MOD2_1589 1
+#define MU_MOD2_1588 0
+#define MU_MOD2_1587 1
+#define MU_MOD2_1586 0
+#define MU_MOD2_1585 1
+#define MU_MOD2_1584 0
+#define MU_MOD2_1583 1
+#define MU_MOD2_1582 0
+#define MU_MOD2_1581 1
+#define MU_MOD2_1580 0
+#define MU_MOD2_1579 1
+#define MU_MOD2_1578 0
+#define MU_MOD2_1577 1
+#define MU_MOD2_1576 0
+#define MU_MOD2_1575 1
+#define MU_MOD2_1574 0
+#define MU_MOD2_1573 1
+#define MU_MOD2_1572 0
+#define MU_MOD2_1571 1
+#define MU_MOD2_1570 0
+#define MU_MOD2_1569 1
+#define MU_MOD2_1568 0
+#define MU_MOD2_1567 1
+#define MU_MOD2_1566 0
+#define MU_MOD2_1565 1
+#define MU_MOD2_1564 0
+#define MU_MOD2_1563 1
+#define MU_MOD2_1562 0
+#define MU_MOD2_1561 1
+#define MU_MOD2_1560 0
+#define MU_MOD2_1559 1
+#define MU_MOD2_1558 0
+#define MU_MOD2_1557 1
+#define MU_MOD2_1556 0
+#define MU_MOD2_1555 1
+#define MU_MOD2_1554 0
+#define MU_MOD2_1553 1
+#define MU_MOD2_1552 0
+#define MU_MOD2_1551 1
+#define MU_MOD2_1550 0
+#define MU_MOD2_1549 1
+#define MU_MOD2_1548 0
+#define MU_MOD2_1547 1
+#define MU_MOD2_1546 0
+#define MU_MOD2_1545 1
+#define MU_MOD2_1544 0
+#define MU_MOD2_1543 1
+#define MU_MOD2_1542 0
+#define MU_MOD2_1541 1
+#define MU_MOD2_1540 0
+#define MU_MOD2_1539 1
+#define MU_MOD2_1538 0
+#define MU_MOD2_1537 1
+#define MU_MOD2_1536 0
+#define MU_MOD2_1535 1
+#define MU_MOD2_1534 0
+#define MU_MOD2_1533 1
+#define MU_MOD2_1532 0
+#define MU_MOD2_1531 1
+#define MU_MOD2_1530 0
+#define MU_MOD2_1529 1
+#define MU_MOD2_1528 0
+#define MU_MOD2_1527 1
+#define MU_MOD2_1526 0
+#define MU_MOD2_1525 1
+#define MU_MOD2_1524 0
+#define MU_MOD2_1523 1
+#define MU_MOD2_1522 0
+#define MU_MOD2_1521 1
+#define MU_MOD2_1520 0
+#define MU_MOD2_1519 1
+#define MU_MOD2_1518 0
+#define MU_MOD2_1517 1
+#define MU_MOD2_1516 0
+#define MU_MOD2_1515 1
+#define MU_MOD2_1514 0
+#define MU_MOD2_1513 1
+#define MU_MOD2_1512 0
+#define MU_MOD2_1511 1
+#define MU_MOD2_1510 0
+#define MU_MOD2_1509 1
+#define MU_MOD2_1508 0
+#define MU_MOD2_1507 1
+#define MU_MOD2_1506 0
+#define MU_MOD2_1505 1
+#define MU_MOD2_1504 0
+#define MU_MOD2_1503 1
+#define MU_MOD2_1502 0
+#define MU_MOD2_1501 1
+#define MU_MOD2_1500 0
+#define MU_MOD2_1499 1
+#define MU_MOD2_1498 0
+#define MU_MOD2_1497 1
+#define MU_MOD2_1496 0
+#define MU_MOD2_1495 1
+#define MU_MOD2_1494 0
+#define MU_MOD2_1493 1
+#define MU_MOD2_1492 0
+#define MU_MOD2_1491 1
+#define MU_MOD2_1490 0
+#define MU_MOD2_1489 1
+#define MU_MOD2_1488 0
+#define MU_MOD2_1487 1
+#define MU_MOD2_1486 0
+#define MU_MOD2_1485 1
+#define MU_MOD2_1484 0
+#define MU_MOD2_1483 1
+#define MU_MOD2_1482 0
+#define MU_MOD2_1481 1
+#define MU_MOD2_1480 0
+#define MU_MOD2_1479 1
+#define MU_MOD2_1478 0
+#define MU_MOD2_1477 1
+#define MU_MOD2_1476 0
+#define MU_MOD2_1475 1
+#define MU_MOD2_1474 0
+#define MU_MOD2_1473 1
+#define MU_MOD2_1472 0
+#define MU_MOD2_1471 1
+#define MU_MOD2_1470 0
+#define MU_MOD2_1469 1
+#define MU_MOD2_1468 0
+#define MU_MOD2_1467 1
+#define MU_MOD2_1466 0
+#define MU_MOD2_1465 1
+#define MU_MOD2_1464 0
+#define MU_MOD2_1463 1
+#define MU_MOD2_1462 0
+#define MU_MOD2_1461 1
+#define MU_MOD2_1460 0
+#define MU_MOD2_1459 1
+#define MU_MOD2_1458 0
+#define MU_MOD2_1457 1
+#define MU_MOD2_1456 0
+#define MU_MOD2_1455 1
+#define MU_MOD2_1454 0
+#define MU_MOD2_1453 1
+#define MU_MOD2_1452 0
+#define MU_MOD2_1451 1
+#define MU_MOD2_1450 0
+#define MU_MOD2_1449 1
+#define MU_MOD2_1448 0
+#define MU_MOD2_1447 1
+#define MU_MOD2_1446 0
+#define MU_MOD2_1445 1
+#define MU_MOD2_1444 0
+#define MU_MOD2_1443 1
+#define MU_MOD2_1442 0
+#define MU_MOD2_1441 1
+#define MU_MOD2_1440 0
+#define MU_MOD2_1439 1
+#define MU_MOD2_1438 0
+#define MU_MOD2_1437 1
+#define MU_MOD2_1436 0
+#define MU_MOD2_1435 1
+#define MU_MOD2_1434 0
+#define MU_MOD2_1433 1
+#define MU_MOD2_1432 0
+#define MU_MOD2_1431 1
+#define MU_MOD2_1430 0
+#define MU_MOD2_1429 1
+#define MU_MOD2_1428 0
+#define MU_MOD2_1427 1
+#define MU_MOD2_1426 0
+#define MU_MOD2_1425 1
+#define MU_MOD2_1424 0
+#define MU_MOD2_1423 1
+#define MU_MOD2_1422 0
+#define MU_MOD2_1421 1
+#define MU_MOD2_1420 0
+#define MU_MOD2_1419 1
+#define MU_MOD2_1418 0
+#define MU_MOD2_1417 1
+#define MU_MOD2_1416 0
+#define MU_MOD2_1415 1
+#define MU_MOD2_1414 0
+#define MU_MOD2_1413 1
+#define MU_MOD2_1412 0
+#define MU_MOD2_1411 1
+#define MU_MOD2_1410 0
+#define MU_MOD2_1409 1
+#define MU_MOD2_1408 0
+#define MU_MOD2_1407 1
+#define MU_MOD2_1406 0
+#define MU_MOD2_1405 1
+#define MU_MOD2_1404 0
+#define MU_MOD2_1403 1
+#define MU_MOD2_1402 0
+#define MU_MOD2_1401 1
+#define MU_MOD2_1400 0
+#define MU_MOD2_1399 1
+#define MU_MOD2_1398 0
+#define MU_MOD2_1397 1
+#define MU_MOD2_1396 0
+#define MU_MOD2_1395 1
+#define MU_MOD2_1394 0
+#define MU_MOD2_1393 1
+#define MU_MOD2_1392 0
+#define MU_MOD2_1391 1
+#define MU_MOD2_1390 0
+#define MU_MOD2_1389 1
+#define MU_MOD2_1388 0
+#define MU_MOD2_1387 1
+#define MU_MOD2_1386 0
+#define MU_MOD2_1385 1
+#define MU_MOD2_1384 0
+#define MU_MOD2_1383 1
+#define MU_MOD2_1382 0
+#define MU_MOD2_1381 1
+#define MU_MOD2_1380 0
+#define MU_MOD2_1379 1
+#define MU_MOD2_1378 0
+#define MU_MOD2_1377 1
+#define MU_MOD2_1376 0
+#define MU_MOD2_1375 1
+#define MU_MOD2_1374 0
+#define MU_MOD2_1373 1
+#define MU_MOD2_1372 0
+#define MU_MOD2_1371 1
+#define MU_MOD2_1370 0
+#define MU_MOD2_1369 1
+#define MU_MOD2_1368 0
+#define MU_MOD2_1367 1
+#define MU_MOD2_1366 0
+#define MU_MOD2_1365 1
+#define MU_MOD2_1364 0
+#define MU_MOD2_1363 1
+#define MU_MOD2_1362 0
+#define MU_MOD2_1361 1
+#define MU_MOD2_1360 0
+#define MU_MOD2_1359 1
+#define MU_MOD2_1358 0
+#define MU_MOD2_1357 1
+#define MU_MOD2_1356 0
+#define MU_MOD2_1355 1
+#define MU_MOD2_1354 0
+#define MU_MOD2_1353 1
+#define MU_MOD2_1352 0
+#define MU_MOD2_1351 1
+#define MU_MOD2_1350 0
+#define MU_MOD2_1349 1
+#define MU_MOD2_1348 0
+#define MU_MOD2_1347 1
+#define MU_MOD2_1346 0
+#define MU_MOD2_1345 1
+#define MU_MOD2_1344 0
+#define MU_MOD2_1343 1
+#define MU_MOD2_1342 0
+#define MU_MOD2_1341 1
+#define MU_MOD2_1340 0
+#define MU_MOD2_1339 1
+#define MU_MOD2_1338 0
+#define MU_MOD2_1337 1
+#define MU_MOD2_1336 0
+#define MU_MOD2_1335 1
+#define MU_MOD2_1334 0
+#define MU_MOD2_1333 1
+#define MU_MOD2_1332 0
+#define MU_MOD2_1331 1
+#define MU_MOD2_1330 0
+#define MU_MOD2_1329 1
+#define MU_MOD2_1328 0
+#define MU_MOD2_1327 1
+#define MU_MOD2_1326 0
+#define MU_MOD2_1325 1
+#define MU_MOD2_1324 0
+#define MU_MOD2_1323 1
+#define MU_MOD2_1322 0
+#define MU_MOD2_1321 1
+#define MU_MOD2_1320 0
+#define MU_MOD2_1319 1
+#define MU_MOD2_1318 0
+#define MU_MOD2_1317 1
+#define MU_MOD2_1316 0
+#define MU_MOD2_1315 1
+#define MU_MOD2_1314 0
+#define MU_MOD2_1313 1
+#define MU_MOD2_1312 0
+#define MU_MOD2_1311 1
+#define MU_MOD2_1310 0
+#define MU_MOD2_1309 1
+#define MU_MOD2_1308 0
+#define MU_MOD2_1307 1
+#define MU_MOD2_1306 0
+#define MU_MOD2_1305 1
+#define MU_MOD2_1304 0
+#define MU_MOD2_1303 1
+#define MU_MOD2_1302 0
+#define MU_MOD2_1301 1
+#define MU_MOD2_1300 0
+#define MU_MOD2_1299 1
+#define MU_MOD2_1298 0
+#define MU_MOD2_1297 1
+#define MU_MOD2_1296 0
+#define MU_MOD2_1295 1
+#define MU_MOD2_1294 0
+#define MU_MOD2_1293 1
+#define MU_MOD2_1292 0
+#define MU_MOD2_1291 1
+#define MU_MOD2_1290 0
+#define MU_MOD2_1289 1
+#define MU_MOD2_1288 0
+#define MU_MOD2_1287 1
+#define MU_MOD2_1286 0
+#define MU_MOD2_1285 1
+#define MU_MOD2_1284 0
+#define MU_MOD2_1283 1
+#define MU_MOD2_1282 0
+#define MU_MOD2_1281 1
+#define MU_MOD2_1280 0
+#define MU_MOD2_1279 1
+#define MU_MOD2_1278 0
+#define MU_MOD2_1277 1
+#define MU_MOD2_1276 0
+#define MU_MOD2_1275 1
+#define MU_MOD2_1274 0
+#define MU_MOD2_1273 1
+#define MU_MOD2_1272 0
+#define MU_MOD2_1271 1
+#define MU_MOD2_1270 0
+#define MU_MOD2_1269 1
+#define MU_MOD2_1268 0
+#define MU_MOD2_1267 1
+#define MU_MOD2_1266 0
+#define MU_MOD2_1265 1
+#define MU_MOD2_1264 0
+#define MU_MOD2_1263 1
+#define MU_MOD2_1262 0
+#define MU_MOD2_1261 1
+#define MU_MOD2_1260 0
+#define MU_MOD2_1259 1
+#define MU_MOD2_1258 0
+#define MU_MOD2_1257 1
+#define MU_MOD2_1256 0
+#define MU_MOD2_1255 1
+#define MU_MOD2_1254 0
+#define MU_MOD2_1253 1
+#define MU_MOD2_1252 0
+#define MU_MOD2_1251 1
+#define MU_MOD2_1250 0
+#define MU_MOD2_1249 1
+#define MU_MOD2_1248 0
+#define MU_MOD2_1247 1
+#define MU_MOD2_1246 0
+#define MU_MOD2_1245 1
+#define MU_MOD2_1244 0
+#define MU_MOD2_1243 1
+#define MU_MOD2_1242 0
+#define MU_MOD2_1241 1
+#define MU_MOD2_1240 0
+#define MU_MOD2_1239 1
+#define MU_MOD2_1238 0
+#define MU_MOD2_1237 1
+#define MU_MOD2_1236 0
+#define MU_MOD2_1235 1
+#define MU_MOD2_1234 0
+#define MU_MOD2_1233 1
+#define MU_MOD2_1232 0
+#define MU_MOD2_1231 1
+#define MU_MOD2_1230 0
+#define MU_MOD2_1229 1
+#define MU_MOD2_1228 0
+#define MU_MOD2_1227 1
+#define MU_MOD2_1226 0
+#define MU_MOD2_1225 1
+#define MU_MOD2_1224 0
+#define MU_MOD2_1223 1
+#define MU_MOD2_1222 0
+#define MU_MOD2_1221 1
+#define MU_MOD2_1220 0
+#define MU_MOD2_1219 1
+#define MU_MOD2_1218 0
+#define MU_MOD2_1217 1
+#define MU_MOD2_1216 0
+#define MU_MOD2_1215 1
+#define MU_MOD2_1214 0
+#define MU_MOD2_1213 1
+#define MU_MOD2_1212 0
+#define MU_MOD2_1211 1
+#define MU_MOD2_1210 0
+#define MU_MOD2_1209 1
+#define MU_MOD2_1208 0
+#define MU_MOD2_1207 1
+#define MU_MOD2_1206 0
+#define MU_MOD2_1205 1
+#define MU_MOD2_1204 0
+#define MU_MOD2_1203 1
+#define MU_MOD2_1202 0
+#define MU_MOD2_1201 1
+#define MU_MOD2_1200 0
+#define MU_MOD2_1199 1
+#define MU_MOD2_1198 0
+#define MU_MOD2_1197 1
+#define MU_MOD2_1196 0
+#define MU_MOD2_1195 1
+#define MU_MOD2_1194 0
+#define MU_MOD2_1193 1
+#define MU_MOD2_1192 0
+#define MU_MOD2_1191 1
+#define MU_MOD2_1190 0
+#define MU_MOD2_1189 1
+#define MU_MOD2_1188 0
+#define MU_MOD2_1187 1
+#define MU_MOD2_1186 0
+#define MU_MOD2_1185 1
+#define MU_MOD2_1184 0
+#define MU_MOD2_1183 1
+#define MU_MOD2_1182 0
+#define MU_MOD2_1181 1
+#define MU_MOD2_1180 0
+#define MU_MOD2_1179 1
+#define MU_MOD2_1178 0
+#define MU_MOD2_1177 1
+#define MU_MOD2_1176 0
+#define MU_MOD2_1175 1
+#define MU_MOD2_1174 0
+#define MU_MOD2_1173 1
+#define MU_MOD2_1172 0
+#define MU_MOD2_1171 1
+#define MU_MOD2_1170 0
+#define MU_MOD2_1169 1
+#define MU_MOD2_1168 0
+#define MU_MOD2_1167 1
+#define MU_MOD2_1166 0
+#define MU_MOD2_1165 1
+#define MU_MOD2_1164 0
+#define MU_MOD2_1163 1
+#define MU_MOD2_1162 0
+#define MU_MOD2_1161 1
+#define MU_MOD2_1160 0
+#define MU_MOD2_1159 1
+#define MU_MOD2_1158 0
+#define MU_MOD2_1157 1
+#define MU_MOD2_1156 0
+#define MU_MOD2_1155 1
+#define MU_MOD2_1154 0
+#define MU_MOD2_1153 1
+#define MU_MOD2_1152 0
+#define MU_MOD2_1151 1
+#define MU_MOD2_1150 0
+#define MU_MOD2_1149 1
+#define MU_MOD2_1148 0
+#define MU_MOD2_1147 1
+#define MU_MOD2_1146 0
+#define MU_MOD2_1145 1
+#define MU_MOD2_1144 0
+#define MU_MOD2_1143 1
+#define MU_MOD2_1142 0
+#define MU_MOD2_1141 1
+#define MU_MOD2_1140 0
+#define MU_MOD2_1139 1
+#define MU_MOD2_1138 0
+#define MU_MOD2_1137 1
+#define MU_MOD2_1136 0
+#define MU_MOD2_1135 1
+#define MU_MOD2_1134 0
+#define MU_MOD2_1133 1
+#define MU_MOD2_1132 0
+#define MU_MOD2_1131 1
+#define MU_MOD2_1130 0
+#define MU_MOD2_1129 1
+#define MU_MOD2_1128 0
+#define MU_MOD2_1127 1
+#define MU_MOD2_1126 0
+#define MU_MOD2_1125 1
+#define MU_MOD2_1124 0
+#define MU_MOD2_1123 1
+#define MU_MOD2_1122 0
+#define MU_MOD2_1121 1
+#define MU_MOD2_1120 0
+#define MU_MOD2_1119 1
+#define MU_MOD2_1118 0
+#define MU_MOD2_1117 1
+#define MU_MOD2_1116 0
+#define MU_MOD2_1115 1
+#define MU_MOD2_1114 0
+#define MU_MOD2_1113 1
+#define MU_MOD2_1112 0
+#define MU_MOD2_1111 1
+#define MU_MOD2_1110 0
+#define MU_MOD2_1109 1
+#define MU_MOD2_1108 0
+#define MU_MOD2_1107 1
+#define MU_MOD2_1106 0
+#define MU_MOD2_1105 1
+#define MU_MOD2_1104 0
+#define MU_MOD2_1103 1
+#define MU_MOD2_1102 0
+#define MU_MOD2_1101 1
+#define MU_MOD2_1100 0
+#define MU_MOD2_1099 1
+#define MU_MOD2_1098 0
+#define MU_MOD2_1097 1
+#define MU_MOD2_1096 0
+#define MU_MOD2_1095 1
+#define MU_MOD2_1094 0
+#define MU_MOD2_1093 1
+#define MU_MOD2_1092 0
+#define MU_MOD2_1091 1
+#define MU_MOD2_1090 0
+#define MU_MOD2_1089 1
+#define MU_MOD2_1088 0
+#define MU_MOD2_1087 1
+#define MU_MOD2_1086 0
+#define MU_MOD2_1085 1
+#define MU_MOD2_1084 0
+#define MU_MOD2_1083 1
+#define MU_MOD2_1082 0
+#define MU_MOD2_1081 1
+#define MU_MOD2_1080 0
+#define MU_MOD2_1079 1
+#define MU_MOD2_1078 0
+#define MU_MOD2_1077 1
+#define MU_MOD2_1076 0
+#define MU_MOD2_1075 1
+#define MU_MOD2_1074 0
+#define MU_MOD2_1073 1
+#define MU_MOD2_1072 0
+#define MU_MOD2_1071 1
+#define MU_MOD2_1070 0
+#define MU_MOD2_1069 1
+#define MU_MOD2_1068 0
+#define MU_MOD2_1067 1
+#define MU_MOD2_1066 0
+#define MU_MOD2_1065 1
+#define MU_MOD2_1064 0
+#define MU_MOD2_1063 1
+#define MU_MOD2_1062 0
+#define MU_MOD2_1061 1
+#define MU_MOD2_1060 0
+#define MU_MOD2_1059 1
+#define MU_MOD2_1058 0
+#define MU_MOD2_1057 1
+#define MU_MOD2_1056 0
+#define MU_MOD2_1055 1
+#define MU_MOD2_1054 0
+#define MU_MOD2_1053 1
+#define MU_MOD2_1052 0
+#define MU_MOD2_1051 1
+#define MU_MOD2_1050 0
+#define MU_MOD2_1049 1
+#define MU_MOD2_1048 0
+#define MU_MOD2_1047 1
+#define MU_MOD2_1046 0
+#define MU_MOD2_1045 1
+#define MU_MOD2_1044 0
+#define MU_MOD2_1043 1
+#define MU_MOD2_1042 0
+#define MU_MOD2_1041 1
+#define MU_MOD2_1040 0
+#define MU_MOD2_1039 1
+#define MU_MOD2_1038 0
+#define MU_MOD2_1037 1
+#define MU_MOD2_1036 0
+#define MU_MOD2_1035 1
+#define MU_MOD2_1034 0
+#define MU_MOD2_1033 1
+#define MU_MOD2_1032 0
+#define MU_MOD2_1031 1
+#define MU_MOD2_1030 0
+#define MU_MOD2_1029 1
+#define MU_MOD2_1028 0
+#define MU_MOD2_1027 1
+#define MU_MOD2_1026 0
+#define MU_MOD2_1025 1
+#define MU_MOD2_1024 0
+#define MU_MOD2_1023 1
+#define MU_MOD2_1022 0
+#define MU_MOD2_1021 1
+#define MU_MOD2_1020 0
+#define MU_MOD2_1019 1
+#define MU_MOD2_1018 0
+#define MU_MOD2_1017 1
+#define MU_MOD2_1016 0
+#define MU_MOD2_1015 1
+#define MU_MOD2_1014 0
+#define MU_MOD2_1013 1
+#define MU_MOD2_1012 0
+#define MU_MOD2_1011 1
+#define MU_MOD2_1010 0
+#define MU_MOD2_1009 1
+#define MU_MOD2_1008 0
+#define MU_MOD2_1007 1
+#define MU_MOD2_1006 0
+#define MU_MOD2_1005 1
+#define MU_MOD2_1004 0
+#define MU_MOD2_1003 1
+#define MU_MOD2_1002 0
+#define MU_MOD2_1001 1
+#define MU_MOD2_1000 0
+#define MU_MOD2_999 1
+#define MU_MOD2_998 0
+#define MU_MOD2_997 1
+#define MU_MOD2_996 0
+#define MU_MOD2_995 1
+#define MU_MOD2_994 0
+#define MU_MOD2_993 1
+#define MU_MOD2_992 0
+#define MU_MOD2_991 1
+#define MU_MOD2_990 0
+#define MU_MOD2_989 1
+#define MU_MOD2_988 0
+#define MU_MOD2_987 1
+#define MU_MOD2_986 0
+#define MU_MOD2_985 1
+#define MU_MOD2_984 0
+#define MU_MOD2_983 1
+#define MU_MOD2_982 0
+#define MU_MOD2_981 1
+#define MU_MOD2_980 0
+#define MU_MOD2_979 1
+#define MU_MOD2_978 0
+#define MU_MOD2_977 1
+#define MU_MOD2_976 0
+#define MU_MOD2_975 1
+#define MU_MOD2_974 0
+#define MU_MOD2_973 1
+#define MU_MOD2_972 0
+#define MU_MOD2_971 1
+#define MU_MOD2_970 0
+#define MU_MOD2_969 1
+#define MU_MOD2_968 0
+#define MU_MOD2_967 1
+#define MU_MOD2_966 0
+#define MU_MOD2_965 1
+#define MU_MOD2_964 0
+#define MU_MOD2_963 1
+#define MU_MOD2_962 0
+#define MU_MOD2_961 1
+#define MU_MOD2_960 0
+#define MU_MOD2_959 1
+#define MU_MOD2_958 0
+#define MU_MOD2_957 1
+#define MU_MOD2_956 0
+#define MU_MOD2_955 1
+#define MU_MOD2_954 0
+#define MU_MOD2_953 1
+#define MU_MOD2_952 0
+#define MU_MOD2_951 1
+#define MU_MOD2_950 0
+#define MU_MOD2_949 1
+#define MU_MOD2_948 0
+#define MU_MOD2_947 1
+#define MU_MOD2_946 0
+#define MU_MOD2_945 1
+#define MU_MOD2_944 0
+#define MU_MOD2_943 1
+#define MU_MOD2_942 0
+#define MU_MOD2_941 1
+#define MU_MOD2_940 0
+#define MU_MOD2_939 1
+#define MU_MOD2_938 0
+#define MU_MOD2_937 1
+#define MU_MOD2_936 0
+#define MU_MOD2_935 1
+#define MU_MOD2_934 0
+#define MU_MOD2_933 1
+#define MU_MOD2_932 0
+#define MU_MOD2_931 1
+#define MU_MOD2_930 0
+#define MU_MOD2_929 1
+#define MU_MOD2_928 0
+#define MU_MOD2_927 1
+#define MU_MOD2_926 0
+#define MU_MOD2_925 1
+#define MU_MOD2_924 0
+#define MU_MOD2_923 1
+#define MU_MOD2_922 0
+#define MU_MOD2_921 1
+#define MU_MOD2_920 0
+#define MU_MOD2_919 1
+#define MU_MOD2_918 0
+#define MU_MOD2_917 1
+#define MU_MOD2_916 0
+#define MU_MOD2_915 1
+#define MU_MOD2_914 0
+#define MU_MOD2_913 1
+#define MU_MOD2_912 0
+#define MU_MOD2_911 1
+#define MU_MOD2_910 0
+#define MU_MOD2_909 1
+#define MU_MOD2_908 0
+#define MU_MOD2_907 1
+#define MU_MOD2_906 0
+#define MU_MOD2_905 1
+#define MU_MOD2_904 0
+#define MU_MOD2_903 1
+#define MU_MOD2_902 0
+#define MU_MOD2_901 1
+#define MU_MOD2_900 0
+#define MU_MOD2_899 1
+#define MU_MOD2_898 0
+#define MU_MOD2_897 1
+#define MU_MOD2_896 0
+#define MU_MOD2_895 1
+#define MU_MOD2_894 0
+#define MU_MOD2_893 1
+#define MU_MOD2_892 0
+#define MU_MOD2_891 1
+#define MU_MOD2_890 0
+#define MU_MOD2_889 1
+#define MU_MOD2_888 0
+#define MU_MOD2_887 1
+#define MU_MOD2_886 0
+#define MU_MOD2_885 1
+#define MU_MOD2_884 0
+#define MU_MOD2_883 1
+#define MU_MOD2_882 0
+#define MU_MOD2_881 1
+#define MU_MOD2_880 0
+#define MU_MOD2_879 1
+#define MU_MOD2_878 0
+#define MU_MOD2_877 1
+#define MU_MOD2_876 0
+#define MU_MOD2_875 1
+#define MU_MOD2_874 0
+#define MU_MOD2_873 1
+#define MU_MOD2_872 0
+#define MU_MOD2_871 1
+#define MU_MOD2_870 0
+#define MU_MOD2_869 1
+#define MU_MOD2_868 0
+#define MU_MOD2_867 1
+#define MU_MOD2_866 0
+#define MU_MOD2_865 1
+#define MU_MOD2_864 0
+#define MU_MOD2_863 1
+#define MU_MOD2_862 0
+#define MU_MOD2_861 1
+#define MU_MOD2_860 0
+#define MU_MOD2_859 1
+#define MU_MOD2_858 0
+#define MU_MOD2_857 1
+#define MU_MOD2_856 0
+#define MU_MOD2_855 1
+#define MU_MOD2_854 0
+#define MU_MOD2_853 1
+#define MU_MOD2_852 0
+#define MU_MOD2_851 1
+#define MU_MOD2_850 0
+#define MU_MOD2_849 1
+#define MU_MOD2_848 0
+#define MU_MOD2_847 1
+#define MU_MOD2_846 0
+#define MU_MOD2_845 1
+#define MU_MOD2_844 0
+#define MU_MOD2_843 1
+#define MU_MOD2_842 0
+#define MU_MOD2_841 1
+#define MU_MOD2_840 0
+#define MU_MOD2_839 1
+#define MU_MOD2_838 0
+#define MU_MOD2_837 1
+#define MU_MOD2_836 0
+#define MU_MOD2_835 1
+#define MU_MOD2_834 0
+#define MU_MOD2_833 1
+#define MU_MOD2_832 0
+#define MU_MOD2_831 1
+#define MU_MOD2_830 0
+#define MU_MOD2_829 1
+#define MU_MOD2_828 0
+#define MU_MOD2_827 1
+#define MU_MOD2_826 0
+#define MU_MOD2_825 1
+#define MU_MOD2_824 0
+#define MU_MOD2_823 1
+#define MU_MOD2_822 0
+#define MU_MOD2_821 1
+#define MU_MOD2_820 0
+#define MU_MOD2_819 1
+#define MU_MOD2_818 0
+#define MU_MOD2_817 1
+#define MU_MOD2_816 0
+#define MU_MOD2_815 1
+#define MU_MOD2_814 0
+#define MU_MOD2_813 1
+#define MU_MOD2_812 0
+#define MU_MOD2_811 1
+#define MU_MOD2_810 0
+#define MU_MOD2_809 1
+#define MU_MOD2_808 0
+#define MU_MOD2_807 1
+#define MU_MOD2_806 0
+#define MU_MOD2_805 1
+#define MU_MOD2_804 0
+#define MU_MOD2_803 1
+#define MU_MOD2_802 0
+#define MU_MOD2_801 1
+#define MU_MOD2_800 0
+#define MU_MOD2_799 1
+#define MU_MOD2_798 0
+#define MU_MOD2_797 1
+#define MU_MOD2_796 0
+#define MU_MOD2_795 1
+#define MU_MOD2_794 0
+#define MU_MOD2_793 1
+#define MU_MOD2_792 0
+#define MU_MOD2_791 1
+#define MU_MOD2_790 0
+#define MU_MOD2_789 1
+#define MU_MOD2_788 0
+#define MU_MOD2_787 1
+#define MU_MOD2_786 0
+#define MU_MOD2_785 1
+#define MU_MOD2_784 0
+#define MU_MOD2_783 1
+#define MU_MOD2_782 0
+#define MU_MOD2_781 1
+#define MU_MOD2_780 0
+#define MU_MOD2_779 1
+#define MU_MOD2_778 0
+#define MU_MOD2_777 1
+#define MU_MOD2_776 0
+#define MU_MOD2_775 1
+#define MU_MOD2_774 0
+#define MU_MOD2_773 1
+#define MU_MOD2_772 0
+#define MU_MOD2_771 1
+#define MU_MOD2_770 0
+#define MU_MOD2_769 1
+#define MU_MOD2_768 0
+#define MU_MOD2_767 1
+#define MU_MOD2_766 0
+#define MU_MOD2_765 1
+#define MU_MOD2_764 0
+#define MU_MOD2_763 1
+#define MU_MOD2_762 0
+#define MU_MOD2_761 1
+#define MU_MOD2_760 0
+#define MU_MOD2_759 1
+#define MU_MOD2_758 0
+#define MU_MOD2_757 1
+#define MU_MOD2_756 0
+#define MU_MOD2_755 1
+#define MU_MOD2_754 0
+#define MU_MOD2_753 1
+#define MU_MOD2_752 0
+#define MU_MOD2_751 1
+#define MU_MOD2_750 0
+#define MU_MOD2_749 1
+#define MU_MOD2_748 0
+#define MU_MOD2_747 1
+#define MU_MOD2_746 0
+#define MU_MOD2_745 1
+#define MU_MOD2_744 0
+#define MU_MOD2_743 1
+#define MU_MOD2_742 0
+#define MU_MOD2_741 1
+#define MU_MOD2_740 0
+#define MU_MOD2_739 1
+#define MU_MOD2_738 0
+#define MU_MOD2_737 1
+#define MU_MOD2_736 0
+#define MU_MOD2_735 1
+#define MU_MOD2_734 0
+#define MU_MOD2_733 1
+#define MU_MOD2_732 0
+#define MU_MOD2_731 1
+#define MU_MOD2_730 0
+#define MU_MOD2_729 1
+#define MU_MOD2_728 0
+#define MU_MOD2_727 1
+#define MU_MOD2_726 0
+#define MU_MOD2_725 1
+#define MU_MOD2_724 0
+#define MU_MOD2_723 1
+#define MU_MOD2_722 0
+#define MU_MOD2_721 1
+#define MU_MOD2_720 0
+#define MU_MOD2_719 1
+#define MU_MOD2_718 0
+#define MU_MOD2_717 1
+#define MU_MOD2_716 0
+#define MU_MOD2_715 1
+#define MU_MOD2_714 0
+#define MU_MOD2_713 1
+#define MU_MOD2_712 0
+#define MU_MOD2_711 1
+#define MU_MOD2_710 0
+#define MU_MOD2_709 1
+#define MU_MOD2_708 0
+#define MU_MOD2_707 1
+#define MU_MOD2_706 0
+#define MU_MOD2_705 1
+#define MU_MOD2_704 0
+#define MU_MOD2_703 1
+#define MU_MOD2_702 0
+#define MU_MOD2_701 1
+#define MU_MOD2_700 0
+#define MU_MOD2_699 1
+#define MU_MOD2_698 0
+#define MU_MOD2_697 1
+#define MU_MOD2_696 0
+#define MU_MOD2_695 1
+#define MU_MOD2_694 0
+#define MU_MOD2_693 1
+#define MU_MOD2_692 0
+#define MU_MOD2_691 1
+#define MU_MOD2_690 0
+#define MU_MOD2_689 1
+#define MU_MOD2_688 0
+#define MU_MOD2_687 1
+#define MU_MOD2_686 0
+#define MU_MOD2_685 1
+#define MU_MOD2_684 0
+#define MU_MOD2_683 1
+#define MU_MOD2_682 0
+#define MU_MOD2_681 1
+#define MU_MOD2_680 0
+#define MU_MOD2_679 1
+#define MU_MOD2_678 0
+#define MU_MOD2_677 1
+#define MU_MOD2_676 0
+#define MU_MOD2_675 1
+#define MU_MOD2_674 0
+#define MU_MOD2_673 1
+#define MU_MOD2_672 0
+#define MU_MOD2_671 1
+#define MU_MOD2_670 0
+#define MU_MOD2_669 1
+#define MU_MOD2_668 0
+#define MU_MOD2_667 1
+#define MU_MOD2_666 0
+#define MU_MOD2_665 1
+#define MU_MOD2_664 0
+#define MU_MOD2_663 1
+#define MU_MOD2_662 0
+#define MU_MOD2_661 1
+#define MU_MOD2_660 0
+#define MU_MOD2_659 1
+#define MU_MOD2_658 0
+#define MU_MOD2_657 1
+#define MU_MOD2_656 0
+#define MU_MOD2_655 1
+#define MU_MOD2_654 0
+#define MU_MOD2_653 1
+#define MU_MOD2_652 0
+#define MU_MOD2_651 1
+#define MU_MOD2_650 0
+#define MU_MOD2_649 1
+#define MU_MOD2_648 0
+#define MU_MOD2_647 1
+#define MU_MOD2_646 0
+#define MU_MOD2_645 1
+#define MU_MOD2_644 0
+#define MU_MOD2_643 1
+#define MU_MOD2_642 0
+#define MU_MOD2_641 1
+#define MU_MOD2_640 0
+#define MU_MOD2_639 1
+#define MU_MOD2_638 0
+#define MU_MOD2_637 1
+#define MU_MOD2_636 0
+#define MU_MOD2_635 1
+#define MU_MOD2_634 0
+#define MU_MOD2_633 1
+#define MU_MOD2_632 0
+#define MU_MOD2_631 1
+#define MU_MOD2_630 0
+#define MU_MOD2_629 1
+#define MU_MOD2_628 0
+#define MU_MOD2_627 1
+#define MU_MOD2_626 0
+#define MU_MOD2_625 1
+#define MU_MOD2_624 0
+#define MU_MOD2_623 1
+#define MU_MOD2_622 0
+#define MU_MOD2_621 1
+#define MU_MOD2_620 0
+#define MU_MOD2_619 1
+#define MU_MOD2_618 0
+#define MU_MOD2_617 1
+#define MU_MOD2_616 0
+#define MU_MOD2_615 1
+#define MU_MOD2_614 0
+#define MU_MOD2_613 1
+#define MU_MOD2_612 0
+#define MU_MOD2_611 1
+#define MU_MOD2_610 0
+#define MU_MOD2_609 1
+#define MU_MOD2_608 0
+#define MU_MOD2_607 1
+#define MU_MOD2_606 0
+#define MU_MOD2_605 1
+#define MU_MOD2_604 0
+#define MU_MOD2_603 1
+#define MU_MOD2_602 0
+#define MU_MOD2_601 1
+#define MU_MOD2_600 0
+#define MU_MOD2_599 1
+#define MU_MOD2_598 0
+#define MU_MOD2_597 1
+#define MU_MOD2_596 0
+#define MU_MOD2_595 1
+#define MU_MOD2_594 0
+#define MU_MOD2_593 1
+#define MU_MOD2_592 0
+#define MU_MOD2_591 1
+#define MU_MOD2_590 0
+#define MU_MOD2_589 1
+#define MU_MOD2_588 0
+#define MU_MOD2_587 1
+#define MU_MOD2_586 0
+#define MU_MOD2_585 1
+#define MU_MOD2_584 0
+#define MU_MOD2_583 1
+#define MU_MOD2_582 0
+#define MU_MOD2_581 1
+#define MU_MOD2_580 0
+#define MU_MOD2_579 1
+#define MU_MOD2_578 0
+#define MU_MOD2_577 1
+#define MU_MOD2_576 0
+#define MU_MOD2_575 1
+#define MU_MOD2_574 0
+#define MU_MOD2_573 1
+#define MU_MOD2_572 0
+#define MU_MOD2_571 1
+#define MU_MOD2_570 0
+#define MU_MOD2_569 1
+#define MU_MOD2_568 0
+#define MU_MOD2_567 1
+#define MU_MOD2_566 0
+#define MU_MOD2_565 1
+#define MU_MOD2_564 0
+#define MU_MOD2_563 1
+#define MU_MOD2_562 0
+#define MU_MOD2_561 1
+#define MU_MOD2_560 0
+#define MU_MOD2_559 1
+#define MU_MOD2_558 0
+#define MU_MOD2_557 1
+#define MU_MOD2_556 0
+#define MU_MOD2_555 1
+#define MU_MOD2_554 0
+#define MU_MOD2_553 1
+#define MU_MOD2_552 0
+#define MU_MOD2_551 1
+#define MU_MOD2_550 0
+#define MU_MOD2_549 1
+#define MU_MOD2_548 0
+#define MU_MOD2_547 1
+#define MU_MOD2_546 0
+#define MU_MOD2_545 1
+#define MU_MOD2_544 0
+#define MU_MOD2_543 1
+#define MU_MOD2_542 0
+#define MU_MOD2_541 1
+#define MU_MOD2_540 0
+#define MU_MOD2_539 1
+#define MU_MOD2_538 0
+#define MU_MOD2_537 1
+#define MU_MOD2_536 0
+#define MU_MOD2_535 1
+#define MU_MOD2_534 0
+#define MU_MOD2_533 1
+#define MU_MOD2_532 0
+#define MU_MOD2_531 1
+#define MU_MOD2_530 0
+#define MU_MOD2_529 1
+#define MU_MOD2_528 0
+#define MU_MOD2_527 1
+#define MU_MOD2_526 0
+#define MU_MOD2_525 1
+#define MU_MOD2_524 0
+#define MU_MOD2_523 1
+#define MU_MOD2_522 0
+#define MU_MOD2_521 1
+#define MU_MOD2_520 0
+#define MU_MOD2_519 1
+#define MU_MOD2_518 0
+#define MU_MOD2_517 1
+#define MU_MOD2_516 0
+#define MU_MOD2_515 1
+#define MU_MOD2_514 0
+#define MU_MOD2_513 1
+#define MU_MOD2_512 0
+#define MU_MOD2_511 1
+#define MU_MOD2_510 0
+#define MU_MOD2_509 1
+#define MU_MOD2_508 0
+#define MU_MOD2_507 1
+#define MU_MOD2_506 0
+#define MU_MOD2_505 1
+#define MU_MOD2_504 0
+#define MU_MOD2_503 1
+#define MU_MOD2_502 0
+#define MU_MOD2_501 1
+#define MU_MOD2_500 0
+#define MU_MOD2_499 1
+#define MU_MOD2_498 0
+#define MU_MOD2_497 1
+#define MU_MOD2_496 0
+#define MU_MOD2_495 1
+#define MU_MOD2_494 0
+#define MU_MOD2_493 1
+#define MU_MOD2_492 0
+#define MU_MOD2_491 1
+#define MU_MOD2_490 0
+#define MU_MOD2_489 1
+#define MU_MOD2_488 0
+#define MU_MOD2_487 1
+#define MU_MOD2_486 0
+#define MU_MOD2_485 1
+#define MU_MOD2_484 0
+#define MU_MOD2_483 1
+#define MU_MOD2_482 0
+#define MU_MOD2_481 1
+#define MU_MOD2_480 0
+#define MU_MOD2_479 1
+#define MU_MOD2_478 0
+#define MU_MOD2_477 1
+#define MU_MOD2_476 0
+#define MU_MOD2_475 1
+#define MU_MOD2_474 0
+#define MU_MOD2_473 1
+#define MU_MOD2_472 0
+#define MU_MOD2_471 1
+#define MU_MOD2_470 0
+#define MU_MOD2_469 1
+#define MU_MOD2_468 0
+#define MU_MOD2_467 1
+#define MU_MOD2_466 0
+#define MU_MOD2_465 1
+#define MU_MOD2_464 0
+#define MU_MOD2_463 1
+#define MU_MOD2_462 0
+#define MU_MOD2_461 1
+#define MU_MOD2_460 0
+#define MU_MOD2_459 1
+#define MU_MOD2_458 0
+#define MU_MOD2_457 1
+#define MU_MOD2_456 0
+#define MU_MOD2_455 1
+#define MU_MOD2_454 0
+#define MU_MOD2_453 1
+#define MU_MOD2_452 0
+#define MU_MOD2_451 1
+#define MU_MOD2_450 0
+#define MU_MOD2_449 1
+#define MU_MOD2_448 0
+#define MU_MOD2_447 1
+#define MU_MOD2_446 0
+#define MU_MOD2_445 1
+#define MU_MOD2_444 0
+#define MU_MOD2_443 1
+#define MU_MOD2_442 0
+#define MU_MOD2_441 1
+#define MU_MOD2_440 0
+#define MU_MOD2_439 1
+#define MU_MOD2_438 0
+#define MU_MOD2_437 1
+#define MU_MOD2_436 0
+#define MU_MOD2_435 1
+#define MU_MOD2_434 0
+#define MU_MOD2_433 1
+#define MU_MOD2_432 0
+#define MU_MOD2_431 1
+#define MU_MOD2_430 0
+#define MU_MOD2_429 1
+#define MU_MOD2_428 0
+#define MU_MOD2_427 1
+#define MU_MOD2_426 0
+#define MU_MOD2_425 1
+#define MU_MOD2_424 0
+#define MU_MOD2_423 1
+#define MU_MOD2_422 0
+#define MU_MOD2_421 1
+#define MU_MOD2_420 0
+#define MU_MOD2_419 1
+#define MU_MOD2_418 0
+#define MU_MOD2_417 1
+#define MU_MOD2_416 0
+#define MU_MOD2_415 1
+#define MU_MOD2_414 0
+#define MU_MOD2_413 1
+#define MU_MOD2_412 0
+#define MU_MOD2_411 1
+#define MU_MOD2_410 0
+#define MU_MOD2_409 1
+#define MU_MOD2_408 0
+#define MU_MOD2_407 1
+#define MU_MOD2_406 0
+#define MU_MOD2_405 1
+#define MU_MOD2_404 0
+#define MU_MOD2_403 1
+#define MU_MOD2_402 0
+#define MU_MOD2_401 1
+#define MU_MOD2_400 0
+#define MU_MOD2_399 1
+#define MU_MOD2_398 0
+#define MU_MOD2_397 1
+#define MU_MOD2_396 0
+#define MU_MOD2_395 1
+#define MU_MOD2_394 0
+#define MU_MOD2_393 1
+#define MU_MOD2_392 0
+#define MU_MOD2_391 1
+#define MU_MOD2_390 0
+#define MU_MOD2_389 1
+#define MU_MOD2_388 0
+#define MU_MOD2_387 1
+#define MU_MOD2_386 0
+#define MU_MOD2_385 1
+#define MU_MOD2_384 0
+#define MU_MOD2_383 1
+#define MU_MOD2_382 0
+#define MU_MOD2_381 1
+#define MU_MOD2_380 0
+#define MU_MOD2_379 1
+#define MU_MOD2_378 0
+#define MU_MOD2_377 1
+#define MU_MOD2_376 0
+#define MU_MOD2_375 1
+#define MU_MOD2_374 0
+#define MU_MOD2_373 1
+#define MU_MOD2_372 0
+#define MU_MOD2_371 1
+#define MU_MOD2_370 0
+#define MU_MOD2_369 1
+#define MU_MOD2_368 0
+#define MU_MOD2_367 1
+#define MU_MOD2_366 0
+#define MU_MOD2_365 1
+#define MU_MOD2_364 0
+#define MU_MOD2_363 1
+#define MU_MOD2_362 0
+#define MU_MOD2_361 1
+#define MU_MOD2_360 0
+#define MU_MOD2_359 1
+#define MU_MOD2_358 0
+#define MU_MOD2_357 1
+#define MU_MOD2_356 0
+#define MU_MOD2_355 1
+#define MU_MOD2_354 0
+#define MU_MOD2_353 1
+#define MU_MOD2_352 0
+#define MU_MOD2_351 1
+#define MU_MOD2_350 0
+#define MU_MOD2_349 1
+#define MU_MOD2_348 0
+#define MU_MOD2_347 1
+#define MU_MOD2_346 0
+#define MU_MOD2_345 1
+#define MU_MOD2_344 0
+#define MU_MOD2_343 1
+#define MU_MOD2_342 0
+#define MU_MOD2_341 1
+#define MU_MOD2_340 0
+#define MU_MOD2_339 1
+#define MU_MOD2_338 0
+#define MU_MOD2_337 1
+#define MU_MOD2_336 0
+#define MU_MOD2_335 1
+#define MU_MOD2_334 0
+#define MU_MOD2_333 1
+#define MU_MOD2_332 0
+#define MU_MOD2_331 1
+#define MU_MOD2_330 0
+#define MU_MOD2_329 1
+#define MU_MOD2_328 0
+#define MU_MOD2_327 1
+#define MU_MOD2_326 0
+#define MU_MOD2_325 1
+#define MU_MOD2_324 0
+#define MU_MOD2_323 1
+#define MU_MOD2_322 0
+#define MU_MOD2_321 1
+#define MU_MOD2_320 0
+#define MU_MOD2_319 1
+#define MU_MOD2_318 0
+#define MU_MOD2_317 1
+#define MU_MOD2_316 0
+#define MU_MOD2_315 1
+#define MU_MOD2_314 0
+#define MU_MOD2_313 1
+#define MU_MOD2_312 0
+#define MU_MOD2_311 1
+#define MU_MOD2_310 0
+#define MU_MOD2_309 1
+#define MU_MOD2_308 0
+#define MU_MOD2_307 1
+#define MU_MOD2_306 0
+#define MU_MOD2_305 1
+#define MU_MOD2_304 0
+#define MU_MOD2_303 1
+#define MU_MOD2_302 0
+#define MU_MOD2_301 1
+#define MU_MOD2_300 0
+#define MU_MOD2_299 1
+#define MU_MOD2_298 0
+#define MU_MOD2_297 1
+#define MU_MOD2_296 0
+#define MU_MOD2_295 1
+#define MU_MOD2_294 0
+#define MU_MOD2_293 1
+#define MU_MOD2_292 0
+#define MU_MOD2_291 1
+#define MU_MOD2_290 0
+#define MU_MOD2_289 1
+#define MU_MOD2_288 0
+#define MU_MOD2_287 1
+#define MU_MOD2_286 0
+#define MU_MOD2_285 1
+#define MU_MOD2_284 0
+#define MU_MOD2_283 1
+#define MU_MOD2_282 0
+#define MU_MOD2_281 1
+#define MU_MOD2_280 0
+#define MU_MOD2_279 1
+#define MU_MOD2_278 0
+#define MU_MOD2_277 1
+#define MU_MOD2_276 0
+#define MU_MOD2_275 1
+#define MU_MOD2_274 0
+#define MU_MOD2_273 1
+#define MU_MOD2_272 0
+#define MU_MOD2_271 1
+#define MU_MOD2_270 0
+#define MU_MOD2_269 1
+#define MU_MOD2_268 0
+#define MU_MOD2_267 1
+#define MU_MOD2_266 0
+#define MU_MOD2_265 1
+#define MU_MOD2_264 0
+#define MU_MOD2_263 1
+#define MU_MOD2_262 0
+#define MU_MOD2_261 1
+#define MU_MOD2_260 0
+#define MU_MOD2_259 1
+#define MU_MOD2_258 0
+#define MU_MOD2_257 1
+#define MU_MOD2_256 0
+#define MU_MOD2_255 1
+#define MU_MOD2_254 0
+#define MU_MOD2_253 1
+#define MU_MOD2_252 0
+#define MU_MOD2_251 1
+#define MU_MOD2_250 0
+#define MU_MOD2_249 1
+#define MU_MOD2_248 0
+#define MU_MOD2_247 1
+#define MU_MOD2_246 0
+#define MU_MOD2_245 1
+#define MU_MOD2_244 0
+#define MU_MOD2_243 1
+#define MU_MOD2_242 0
+#define MU_MOD2_241 1
+#define MU_MOD2_240 0
+#define MU_MOD2_239 1
+#define MU_MOD2_238 0
+#define MU_MOD2_237 1
+#define MU_MOD2_236 0
+#define MU_MOD2_235 1
+#define MU_MOD2_234 0
+#define MU_MOD2_233 1
+#define MU_MOD2_232 0
+#define MU_MOD2_231 1
+#define MU_MOD2_230 0
+#define MU_MOD2_229 1
+#define MU_MOD2_228 0
+#define MU_MOD2_227 1
+#define MU_MOD2_226 0
+#define MU_MOD2_225 1
+#define MU_MOD2_224 0
+#define MU_MOD2_223 1
+#define MU_MOD2_222 0
+#define MU_MOD2_221 1
+#define MU_MOD2_220 0
+#define MU_MOD2_219 1
+#define MU_MOD2_218 0
+#define MU_MOD2_217 1
+#define MU_MOD2_216 0
+#define MU_MOD2_215 1
+#define MU_MOD2_214 0
+#define MU_MOD2_213 1
+#define MU_MOD2_212 0
+#define MU_MOD2_211 1
+#define MU_MOD2_210 0
+#define MU_MOD2_209 1
+#define MU_MOD2_208 0
+#define MU_MOD2_207 1
+#define MU_MOD2_206 0
+#define MU_MOD2_205 1
+#define MU_MOD2_204 0
+#define MU_MOD2_203 1
+#define MU_MOD2_202 0
+#define MU_MOD2_201 1
+#define MU_MOD2_200 0
+#define MU_MOD2_199 1
+#define MU_MOD2_198 0
+#define MU_MOD2_197 1
+#define MU_MOD2_196 0
+#define MU_MOD2_195 1
+#define MU_MOD2_194 0
+#define MU_MOD2_193 1
+#define MU_MOD2_192 0
+#define MU_MOD2_191 1
+#define MU_MOD2_190 0
+#define MU_MOD2_189 1
+#define MU_MOD2_188 0
+#define MU_MOD2_187 1
+#define MU_MOD2_186 0
+#define MU_MOD2_185 1
+#define MU_MOD2_184 0
+#define MU_MOD2_183 1
+#define MU_MOD2_182 0
+#define MU_MOD2_181 1
+#define MU_MOD2_180 0
+#define MU_MOD2_179 1
+#define MU_MOD2_178 0
+#define MU_MOD2_177 1
+#define MU_MOD2_176 0
+#define MU_MOD2_175 1
+#define MU_MOD2_174 0
+#define MU_MOD2_173 1
+#define MU_MOD2_172 0
+#define MU_MOD2_171 1
+#define MU_MOD2_170 0
+#define MU_MOD2_169 1
+#define MU_MOD2_168 0
+#define MU_MOD2_167 1
+#define MU_MOD2_166 0
+#define MU_MOD2_165 1
+#define MU_MOD2_164 0
+#define MU_MOD2_163 1
+#define MU_MOD2_162 0
+#define MU_MOD2_161 1
+#define MU_MOD2_160 0
+#define MU_MOD2_159 1
+#define MU_MOD2_158 0
+#define MU_MOD2_157 1
+#define MU_MOD2_156 0
+#define MU_MOD2_155 1
+#define MU_MOD2_154 0
+#define MU_MOD2_153 1
+#define MU_MOD2_152 0
+#define MU_MOD2_151 1
+#define MU_MOD2_150 0
+#define MU_MOD2_149 1
+#define MU_MOD2_148 0
+#define MU_MOD2_147 1
+#define MU_MOD2_146 0
+#define MU_MOD2_145 1
+#define MU_MOD2_144 0
+#define MU_MOD2_143 1
+#define MU_MOD2_142 0
+#define MU_MOD2_141 1
+#define MU_MOD2_140 0
+#define MU_MOD2_139 1
+#define MU_MOD2_138 0
+#define MU_MOD2_137 1
+#define MU_MOD2_136 0
+#define MU_MOD2_135 1
+#define MU_MOD2_134 0
+#define MU_MOD2_133 1
+#define MU_MOD2_132 0
+#define MU_MOD2_131 1
+#define MU_MOD2_130 0
+#define MU_MOD2_129 1
+#define MU_MOD2_128 0
+#define MU_MOD2_127 1
+#define MU_MOD2_126 0
+#define MU_MOD2_125 1
+#define MU_MOD2_124 0
+#define MU_MOD2_123 1
+#define MU_MOD2_122 0
+#define MU_MOD2_121 1
+#define MU_MOD2_120 0
+#define MU_MOD2_119 1
+#define MU_MOD2_118 0
+#define MU_MOD2_117 1
+#define MU_MOD2_116 0
+#define MU_MOD2_115 1
+#define MU_MOD2_114 0
+#define MU_MOD2_113 1
+#define MU_MOD2_112 0
+#define MU_MOD2_111 1
+#define MU_MOD2_110 0
+#define MU_MOD2_109 1
+#define MU_MOD2_108 0
+#define MU_MOD2_107 1
+#define MU_MOD2_106 0
+#define MU_MOD2_105 1
+#define MU_MOD2_104 0
+#define MU_MOD2_103 1
+#define MU_MOD2_102 0
+#define MU_MOD2_101 1
+#define MU_MOD2_100 0
+#define MU_MOD2_99 1
+#define MU_MOD2_98 0
+#define MU_MOD2_97 1
+#define MU_MOD2_96 0
+#define MU_MOD2_95 1
+#define MU_MOD2_94 0
+#define MU_MOD2_93 1
+#define MU_MOD2_92 0
+#define MU_MOD2_91 1
+#define MU_MOD2_90 0
+#define MU_MOD2_89 1
+#define MU_MOD2_88 0
+#define MU_MOD2_87 1
+#define MU_MOD2_86 0
+#define MU_MOD2_85 1
+#define MU_MOD2_84 0
+#define MU_MOD2_83 1
+#define MU_MOD2_82 0
+#define MU_MOD2_81 1
+#define MU_MOD2_80 0
+#define MU_MOD2_79 1
+#define MU_MOD2_78 0
+#define MU_MOD2_77 1
+#define MU_MOD2_76 0
+#define MU_MOD2_75 1
+#define MU_MOD2_74 0
+#define MU_MOD2_73 1
+#define MU_MOD2_72 0
+#define MU_MOD2_71 1
+#define MU_MOD2_70 0
+#define MU_MOD2_69 1
+#define MU_MOD2_68 0
+#define MU_MOD2_67 1
+#define MU_MOD2_66 0
+#define MU_MOD2_65 1
+#define MU_MOD2_64 0
+#define MU_MOD2_63 1
+#define MU_MOD2_62 0
+#define MU_MOD2_61 1
+#define MU_MOD2_60 0
+#define MU_MOD2_59 1
+#define MU_MOD2_58 0
+#define MU_MOD2_57 1
+#define MU_MOD2_56 0
+#define MU_MOD2_55 1
+#define MU_MOD2_54 0
+#define MU_MOD2_53 1
+#define MU_MOD2_52 0
+#define MU_MOD2_51 1
+#define MU_MOD2_50 0
+#define MU_MOD2_49 1
+#define MU_MOD2_48 0
+#define MU_MOD2_47 1
+#define MU_MOD2_46 0
+#define MU_MOD2_45 1
+#define MU_MOD2_44 0
+#define MU_MOD2_43 1
+#define MU_MOD2_42 0
+#define MU_MOD2_41 1
+#define MU_MOD2_40 0
+#define MU_MOD2_39 1
+#define MU_MOD2_38 0
+#define MU_MOD2_37 1
+#define MU_MOD2_36 0
+#define MU_MOD2_35 1
+#define MU_MOD2_34 0
+#define MU_MOD2_33 1
+#define MU_MOD2_32 0
+#define MU_MOD2_31 1
+#define MU_MOD2_30 0
+#define MU_MOD2_29 1
+#define MU_MOD2_28 0
+#define MU_MOD2_27 1
+#define MU_MOD2_26 0
+#define MU_MOD2_25 1
+#define MU_MOD2_24 0
+#define MU_MOD2_23 1
+#define MU_MOD2_22 0
+#define MU_MOD2_21 1
+#define MU_MOD2_20 0
+#define MU_MOD2_19 1
+#define MU_MOD2_18 0
+#define MU_MOD2_17 1
+#define MU_MOD2_16 0
+#define MU_MOD2_15 1
+#define MU_MOD2_14 0
+#define MU_MOD2_13 1
+#define MU_MOD2_12 0
+#define MU_MOD2_11 1
+#define MU_MOD2_10 0
+#define MU_MOD2_9 1
+#define MU_MOD2_8 0
+#define MU_MOD2_7 1
+#define MU_MOD2_6 0
+#define MU_MOD2_5 1
+#define MU_MOD2_4 0
+#define MU_MOD2_3 1
+#define MU_MOD2_2 0
+#define MU_MOD2_1 1
+#define MU_MOD2_0 0
+
+#define MU_THE_NTH_ARG(P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104, P105, P106, P107, P108, P109, P110, P111, P112, P113, P114, P115, P116, P117, P118, P119, P120, P121, P122, P123, P124,  ... ) P124
+
+#ifdef _MSC_VER
+#define MU_COUNT_1_OR_MORE_ARG(...) MU_THE_NTH_ARG MU_LPAREN __VA_ARGS__, \
+123, 122, 121, 120, 119, 118, 117, 116, 115, 114, 113, 112, 111, 110, 109, 108, 107, 106, 105, 104, 103, 102, 101, 100, 99, 98, 97, 96, 95, 94, 93, 92, 91, 90, 89, 88, 87, 86, 85, 84, 83, 82, 81, 80, 79, 78, 77, 76, 75, 74, 73, 72, 71, 70, 69, 68, 67, 66, 65, 64, 63, 62, 61, 60, 59, 58, 57, 56, 55, 54, 53, 52, 51, 50, 49, 48, 47, 46, 45, 44, 43, 42, 41, 40, 39, 38, 37, 36, 35, 34, 33, 32, 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1)
+#define MU_MORE_THAN_1_ARG(...) MU_THE_NTH_ARG MU_LPAREN __VA_ARGS__, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0)
+#else
+#define MU_COUNT_1_OR_MORE_ARG(...) MU_THE_NTH_ARG (__VA_ARGS__, \
+123, 122, 121, 120, 119, 118, 117, 116, 115, 114, 113, 112, 111, 110, 109, 108, 107, 106, 105, 104, 103, 102, 101, 100, 99, 98, 97, 96, 95, 94, 93, 92, 91, 90, 89, 88, 87, 86, 85, 84, 83, 82, 81, 80, 79, 78, 77, 76, 75, 74, 73, 72, 71, 70, 69, 68, 67, 66, 65, 64, 63, 62, 61, 60, 59, 58, 57, 56, 55, 54, 53, 52, 51, 50, 49, 48, 47, 46, 45, 44, 43, 42, 41, 40, 39, 38, 37, 36, 35, 34, 33, 32, 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1)
+#define MU_MORE_THAN_1_ARG(...) MU_THE_NTH_ARG(__VA_ARGS__, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 0)
+#endif
+
+#define MU_COUNT_ARG(...) MU_C2(MU_COUNT_ARG_, MU_ISEMPTY(__VA_ARGS__))(__VA_ARGS__)
+#define MU_COUNT_ARG_1(...) 0
+#define MU_COUNT_ARG_0(...) MU_C1(MU_COUNT_1_OR_MORE_ARG(__VA_ARGS__))
+
+#define MU_ISEMPTY(...) MU_C5(MU_DISPATCH_EMPTY_, MU_MORE_THAN_1_ARG(MU_TRIGGER_PARENTHESIS __VA_ARGS__ ()), MU_MORE_THAN_1_ARG(__VA_ARGS__), MU_MORE_THAN_1_ARG(__VA_ARGS__ ()), MU_MORE_THAN_1_ARG(MU_TRIGGER_PARENTHESIS __VA_ARGS__))
+#define MU_DISPATCH_EMPTY_1000 1
+#define MU_DISPATCH_EMPTY_0000 0
+#define MU_DISPATCH_EMPTY_1100 0
+#define MU_DISPATCH_EMPTY_1111 0
+#define MU_DISPATCH_EMPTY_1001 0
+#define MU_DISPATCH_EMPTY_1010 0
+
+
+#define MU_FOR_EACH_1_124(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104, P105, P106, P107, P108, P109, P110, P111, P112, P113, P114, P115, P116, P117, P118, P119, P120, P121, P122, P123, P124) \
+X(P1) \
+MU_FOR_EACH_1_123(X, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104, P105, P106, P107, P108, P109, P110, P111, P112, P113, P114, P115, P116, P117, P118, P119, P120, P121, P122, P123, P124)
+
+#define MU_FOR_EACH_1_123(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104, P105, P106, P107, P108, P109, P110, P111, P112, P113, P114, P115, P116, P117, P118, P119, P120, P121, P122, P123) \
+X(P1) \
+MU_FOR_EACH_1_122(X, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104, P105, P106, P107, P108, P109, P110, P111, P112, P113, P114, P115, P116, P117, P118, P119, P120, P121, P122, P123)
+
+#define MU_FOR_EACH_1_122(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104, P105, P106, P107, P108, P109, P110, P111, P112, P113, P114, P115, P116, P117, P118, P119, P120, P121, P122) \
+X(P1) \
+MU_FOR_EACH_1_121(X, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104, P105, P106, P107, P108, P109, P110, P111, P112, P113, P114, P115, P116, P117, P118, P119, P120, P121, P122)
+
+#define MU_FOR_EACH_1_121(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104, P105, P106, P107, P108, P109, P110, P111, P112, P113, P114, P115, P116, P117, P118, P119, P120, P121) \
+X(P1) \
+MU_FOR_EACH_1_120(X, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104, P105, P106, P107, P108, P109, P110, P111, P112, P113, P114, P115, P116, P117, P118, P119, P120, P121)
+
+#define MU_FOR_EACH_1_120(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104, P105, P106, P107, P108, P109, P110, P111, P112, P113, P114, P115, P116, P117, P118, P119, P120) \
+X(P1) \
+MU_FOR_EACH_1_119(X, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104, P105, P106, P107, P108, P109, P110, P111, P112, P113, P114, P115, P116, P117, P118, P119, P120)
+
+#define MU_FOR_EACH_1_119(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104, P105, P106, P107, P108, P109, P110, P111, P112, P113, P114, P115, P116, P117, P118, P119) \
+X(P1) \
+MU_FOR_EACH_1_118(X, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104, P105, P106, P107, P108, P109, P110, P111, P112, P113, P114, P115, P116, P117, P118, P119)
+
+#define MU_FOR_EACH_1_118(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104, P105, P106, P107, P108, P109, P110, P111, P112, P113, P114, P115, P116, P117, P118) \
+X(P1) \
+MU_FOR_EACH_1_117(X, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104, P105, P106, P107, P108, P109, P110, P111, P112, P113, P114, P115, P116, P117, P118)
+
+#define MU_FOR_EACH_1_117(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104, P105, P106, P107, P108, P109, P110, P111, P112, P113, P114, P115, P116, P117) \
+X(P1) \
+MU_FOR_EACH_1_116(X, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104, P105, P106, P107, P108, P109, P110, P111, P112, P113, P114, P115, P116, P117)
+
+#define MU_FOR_EACH_1_116(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104, P105, P106, P107, P108, P109, P110, P111, P112, P113, P114, P115, P116) \
+X(P1) \
+MU_FOR_EACH_1_115(X, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104, P105, P106, P107, P108, P109, P110, P111, P112, P113, P114, P115, P116)
+
+#define MU_FOR_EACH_1_115(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104, P105, P106, P107, P108, P109, P110, P111, P112, P113, P114, P115) \
+X(P1) \
+MU_FOR_EACH_1_114(X, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104, P105, P106, P107, P108, P109, P110, P111, P112, P113, P114, P115)
+
+#define MU_FOR_EACH_1_114(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104, P105, P106, P107, P108, P109, P110, P111, P112, P113, P114) \
+X(P1) \
+MU_FOR_EACH_1_113(X, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104, P105, P106, P107, P108, P109, P110, P111, P112, P113, P114)
+
+#define MU_FOR_EACH_1_113(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104, P105, P106, P107, P108, P109, P110, P111, P112, P113) \
+X(P1) \
+MU_FOR_EACH_1_112(X, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104, P105, P106, P107, P108, P109, P110, P111, P112, P113)
+
+#define MU_FOR_EACH_1_112(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104, P105, P106, P107, P108, P109, P110, P111, P112) \
+X(P1) \
+MU_FOR_EACH_1_111(X, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104, P105, P106, P107, P108, P109, P110, P111, P112)
+
+#define MU_FOR_EACH_1_111(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104, P105, P106, P107, P108, P109, P110, P111) \
+X(P1) \
+MU_FOR_EACH_1_110(X, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104, P105, P106, P107, P108, P109, P110, P111)
+
+#define MU_FOR_EACH_1_110(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104, P105, P106, P107, P108, P109, P110) \
+X(P1) \
+MU_FOR_EACH_1_109(X, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104, P105, P106, P107, P108, P109, P110)
+
+#define MU_FOR_EACH_1_109(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104, P105, P106, P107, P108, P109) \
+X(P1) \
+MU_FOR_EACH_1_108(X, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104, P105, P106, P107, P108, P109)
+
+#define MU_FOR_EACH_1_108(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104, P105, P106, P107, P108) \
+X(P1) \
+MU_FOR_EACH_1_107(X, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104, P105, P106, P107, P108)
+
+#define MU_FOR_EACH_1_107(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104, P105, P106, P107) \
+X(P1) \
+MU_FOR_EACH_1_106(X, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104, P105, P106, P107)
+
+#define MU_FOR_EACH_1_106(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104, P105, P106) \
+X(P1) \
+MU_FOR_EACH_1_105(X, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104, P105, P106)
+
+#define MU_FOR_EACH_1_105(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104, P105) \
+X(P1) \
+MU_FOR_EACH_1_104(X, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104, P105)
+
+#define MU_FOR_EACH_1_104(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104) \
+X(P1) \
+MU_FOR_EACH_1_103(X, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104)
+
+#define MU_FOR_EACH_1_103(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103) \
+X(P1) \
+MU_FOR_EACH_1_102(X, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103)
+
+#define MU_FOR_EACH_1_102(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102) \
+X(P1) \
+MU_FOR_EACH_1_101(X, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102)
+
+#define MU_FOR_EACH_1_101(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101) \
+X(P1) \
+MU_FOR_EACH_1_100(X, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101)
+
+#define MU_FOR_EACH_1_100(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100) \
+X(P1) \
+MU_FOR_EACH_1_99(X, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100)
+
+#define MU_FOR_EACH_1_99(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99) \
+X(P1) \
+MU_FOR_EACH_1_98(X, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99)
+
+#define MU_FOR_EACH_1_98(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98) \
+X(P1) \
+MU_FOR_EACH_1_97(X, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98)
+
+#define MU_FOR_EACH_1_97(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97) \
+X(P1) \
+MU_FOR_EACH_1_96(X, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97)
+
+#define MU_FOR_EACH_1_96(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96) \
+X(P1) \
+MU_FOR_EACH_1_95(X, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96)
+
+#define MU_FOR_EACH_1_95(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95) \
+X(P1) \
+MU_FOR_EACH_1_94(X, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95)
+
+#define MU_FOR_EACH_1_94(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94) \
+X(P1) \
+MU_FOR_EACH_1_93(X, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94)
+
+#define MU_FOR_EACH_1_93(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93) \
+X(P1) \
+MU_FOR_EACH_1_92(X, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93)
+
+#define MU_FOR_EACH_1_92(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92) \
+X(P1) \
+MU_FOR_EACH_1_91(X, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92)
+
+#define MU_FOR_EACH_1_91(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91) \
+X(P1) \
+MU_FOR_EACH_1_90(X, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91)
+
+#define MU_FOR_EACH_1_90(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90) \
+X(P1) \
+MU_FOR_EACH_1_89(X, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90)
+
+#define MU_FOR_EACH_1_89(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89) \
+X(P1) \
+MU_FOR_EACH_1_88(X, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89)
+
+#define MU_FOR_EACH_1_88(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88) \
+X(P1) \
+MU_FOR_EACH_1_87(X, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88)
+
+#define MU_FOR_EACH_1_87(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87) \
+X(P1) \
+MU_FOR_EACH_1_86(X, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87)
+
+#define MU_FOR_EACH_1_86(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86) \
+X(P1) \
+MU_FOR_EACH_1_85(X, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86)
+
+#define MU_FOR_EACH_1_85(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85) \
+X(P1) \
+MU_FOR_EACH_1_84(X, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85)
+
+#define MU_FOR_EACH_1_84(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84) \
+X(P1) \
+MU_FOR_EACH_1_83(X, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84)
+
+#define MU_FOR_EACH_1_83(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83) \
+X(P1) \
+MU_FOR_EACH_1_82(X, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83)
+
+#define MU_FOR_EACH_1_82(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82) \
+X(P1) \
+MU_FOR_EACH_1_81(X, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82)
+
+#define MU_FOR_EACH_1_81(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81) \
+X(P1) \
+MU_FOR_EACH_1_80(X, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81)
+
+#define MU_FOR_EACH_1_80(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80) \
+X(P1) \
+MU_FOR_EACH_1_79(X, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80)
+
+#define MU_FOR_EACH_1_79(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79) \
+X(P1) \
+MU_FOR_EACH_1_78(X, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79)
+
+#define MU_FOR_EACH_1_78(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78) \
+X(P1) \
+MU_FOR_EACH_1_77(X, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78)
+
+#define MU_FOR_EACH_1_77(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77) \
+X(P1) \
+MU_FOR_EACH_1_76(X, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77)
+
+#define MU_FOR_EACH_1_76(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76) \
+X(P1) \
+MU_FOR_EACH_1_75(X, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76)
+
+#define MU_FOR_EACH_1_75(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75) \
+X(P1) \
+MU_FOR_EACH_1_74(X, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75)
+
+#define MU_FOR_EACH_1_74(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74) \
+X(P1) \
+MU_FOR_EACH_1_73(X, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74)
+
+#define MU_FOR_EACH_1_73(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73) \
+X(P1) \
+MU_FOR_EACH_1_72(X, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73)
+
+#define MU_FOR_EACH_1_72(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72) \
+X(P1) \
+MU_FOR_EACH_1_71(X, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72)
+
+#define MU_FOR_EACH_1_71(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71) \
+X(P1) \
+MU_FOR_EACH_1_70(X, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71)
+
+#define MU_FOR_EACH_1_70(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70) \
+X(P1) \
+MU_FOR_EACH_1_69(X, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70)
+
+#define MU_FOR_EACH_1_69(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69) \
+X(P1) \
+MU_FOR_EACH_1_68(X, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69)
+
+#define MU_FOR_EACH_1_68(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68) \
+X(P1) \
+MU_FOR_EACH_1_67(X, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68)
+
+#define MU_FOR_EACH_1_67(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67) \
+X(P1) \
+MU_FOR_EACH_1_66(X, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67)
+
+#define MU_FOR_EACH_1_66(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66) \
+X(P1) \
+MU_FOR_EACH_1_65(X, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66)
+
+#define MU_FOR_EACH_1_65(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65) \
+X(P1) \
+MU_FOR_EACH_1_64(X, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65)
+
+#define MU_FOR_EACH_1_64(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64) \
+X(P1) \
+MU_FOR_EACH_1_63(X, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64)
+
+#define MU_FOR_EACH_1_63(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63) \
+X(P1) \
+MU_FOR_EACH_1_62(X, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63)
+
+#define MU_FOR_EACH_1_62(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62) \
+X(P1) \
+MU_FOR_EACH_1_61(X, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62)
+
+#define MU_FOR_EACH_1_61(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61) \
+X(P1) \
+MU_FOR_EACH_1_60(X, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61)
+
+#define MU_FOR_EACH_1_60(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60) \
+X(P1) \
+MU_FOR_EACH_1_59(X, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60)
+
+#define MU_FOR_EACH_1_59(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59) \
+X(P1) \
+MU_FOR_EACH_1_58(X, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59)
+
+#define MU_FOR_EACH_1_58(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58) \
+X(P1) \
+MU_FOR_EACH_1_57(X, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58)
+
+#define MU_FOR_EACH_1_57(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57) \
+X(P1) \
+MU_FOR_EACH_1_56(X, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57)
+
+#define MU_FOR_EACH_1_56(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56) \
+X(P1) \
+MU_FOR_EACH_1_55(X, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56)
+
+#define MU_FOR_EACH_1_55(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55) \
+X(P1) \
+MU_FOR_EACH_1_54(X, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55)
+
+#define MU_FOR_EACH_1_54(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54) \
+X(P1) \
+MU_FOR_EACH_1_53(X, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54)
+
+#define MU_FOR_EACH_1_53(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53) \
+X(P1) \
+MU_FOR_EACH_1_52(X, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53)
+
+#define MU_FOR_EACH_1_52(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52) \
+X(P1) \
+MU_FOR_EACH_1_51(X, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52)
+
+#define MU_FOR_EACH_1_51(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51) \
+X(P1) \
+MU_FOR_EACH_1_50(X, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51)
+
+#define MU_FOR_EACH_1_50(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50) \
+X(P1) \
+MU_FOR_EACH_1_49(X, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50)
+
+#define MU_FOR_EACH_1_49(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49) \
+X(P1) \
+MU_FOR_EACH_1_48(X, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49)
+
+#define MU_FOR_EACH_1_48(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48) \
+X(P1) \
+MU_FOR_EACH_1_47(X, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48)
+
+#define MU_FOR_EACH_1_47(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47) \
+X(P1) \
+MU_FOR_EACH_1_46(X, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47)
+
+#define MU_FOR_EACH_1_46(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46) \
+X(P1) \
+MU_FOR_EACH_1_45(X, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46)
+
+#define MU_FOR_EACH_1_45(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45) \
+X(P1) \
+MU_FOR_EACH_1_44(X, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45)
+
+#define MU_FOR_EACH_1_44(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44) \
+X(P1) \
+MU_FOR_EACH_1_43(X, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44)
+
+#define MU_FOR_EACH_1_43(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43) \
+X(P1) \
+MU_FOR_EACH_1_42(X, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43)
+
+#define MU_FOR_EACH_1_42(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42) \
+X(P1) \
+MU_FOR_EACH_1_41(X, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42)
+
+#define MU_FOR_EACH_1_41(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41) \
+X(P1) \
+MU_FOR_EACH_1_40(X, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41)
+
+#define MU_FOR_EACH_1_40(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40) \
+X(P1) \
+MU_FOR_EACH_1_39(X, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40)
+
+#define MU_FOR_EACH_1_39(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39) \
+X(P1) \
+MU_FOR_EACH_1_38(X, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39)
+
+#define MU_FOR_EACH_1_38(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38) \
+X(P1) \
+MU_FOR_EACH_1_37(X, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38)
+
+#define MU_FOR_EACH_1_37(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37) \
+X(P1) \
+MU_FOR_EACH_1_36(X, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37)
+
+#define MU_FOR_EACH_1_36(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36) \
+X(P1) \
+MU_FOR_EACH_1_35(X, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36)
+
+#define MU_FOR_EACH_1_35(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35) \
+X(P1) \
+MU_FOR_EACH_1_34(X, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35)
+
+#define MU_FOR_EACH_1_34(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34) \
+X(P1) \
+MU_FOR_EACH_1_33(X, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34)
+
+#define MU_FOR_EACH_1_33(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33) \
+X(P1) \
+MU_FOR_EACH_1_32(X, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33)
+
+#define MU_FOR_EACH_1_32(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32) \
+X(P1) \
+MU_FOR_EACH_1_31(X, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32)
+
+#define MU_FOR_EACH_1_31(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31) \
+X(P1) \
+MU_FOR_EACH_1_30(X, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31)
+
+#define MU_FOR_EACH_1_30(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30) \
+X(P1) \
+MU_FOR_EACH_1_29(X, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30)
+
+#define MU_FOR_EACH_1_29(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29) \
+X(P1) \
+MU_FOR_EACH_1_28(X, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29)
+
+#define MU_FOR_EACH_1_28(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28) \
+X(P1) \
+MU_FOR_EACH_1_27(X, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28)
+
+#define MU_FOR_EACH_1_27(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27) \
+X(P1) \
+MU_FOR_EACH_1_26(X, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27)
+
+#define MU_FOR_EACH_1_26(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26) \
+X(P1) \
+MU_FOR_EACH_1_25(X, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26)
+
+#define MU_FOR_EACH_1_25(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25) \
+X(P1) \
+MU_FOR_EACH_1_24(X, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25)
+
+#define MU_FOR_EACH_1_24(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24) \
+X(P1) \
+MU_FOR_EACH_1_23(X, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24)
+
+#define MU_FOR_EACH_1_23(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23) \
+X(P1) \
+MU_FOR_EACH_1_22(X, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23)
+
+#define MU_FOR_EACH_1_22(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22) \
+X(P1) \
+MU_FOR_EACH_1_21(X, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22)
+
+#define MU_FOR_EACH_1_21(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21) \
+X(P1) \
+MU_FOR_EACH_1_20(X, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21)
+
+#define MU_FOR_EACH_1_20(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20) \
+X(P1) \
+MU_FOR_EACH_1_19(X, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20)
+
+#define MU_FOR_EACH_1_19(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19) \
+X(P1) \
+MU_FOR_EACH_1_18(X, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19)
+
+#define MU_FOR_EACH_1_18(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18) \
+X(P1) \
+MU_FOR_EACH_1_17(X, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18)
+
+#define MU_FOR_EACH_1_17(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17) \
+X(P1) \
+MU_FOR_EACH_1_16(X, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17)
+
+#define MU_FOR_EACH_1_16(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16) \
+X(P1) \
+MU_FOR_EACH_1_15(X, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16)
+
+#define MU_FOR_EACH_1_15(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15) \
+X(P1) \
+MU_FOR_EACH_1_14(X, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15)
+
+#define MU_FOR_EACH_1_14(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14) \
+X(P1) \
+MU_FOR_EACH_1_13(X, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14)
+
+#define MU_FOR_EACH_1_13(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13) \
+X(P1) \
+MU_FOR_EACH_1_12(X, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13)
+
+#define MU_FOR_EACH_1_12(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12) \
+X(P1) \
+MU_FOR_EACH_1_11(X, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12)
+
+#define MU_FOR_EACH_1_11(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11) \
+X(P1) \
+MU_FOR_EACH_1_10(X, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11)
+
+#define MU_FOR_EACH_1_10(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10) \
+X(P1) \
+MU_FOR_EACH_1_9(X, P2, P3, P4, P5, P6, P7, P8, P9, P10)
+
+#define MU_FOR_EACH_1_9(X, P1, P2, P3, P4, P5, P6, P7, P8, P9) \
+X(P1) \
+MU_FOR_EACH_1_8(X, P2, P3, P4, P5, P6, P7, P8, P9)
+
+#define MU_FOR_EACH_1_8(X, P1, P2, P3, P4, P5, P6, P7, P8) \
+X(P1) \
+MU_FOR_EACH_1_7(X, P2, P3, P4, P5, P6, P7, P8)
+
+#define MU_FOR_EACH_1_7(X, P1, P2, P3, P4, P5, P6, P7) \
+X(P1) \
+MU_FOR_EACH_1_6(X, P2, P3, P4, P5, P6, P7)
+
+#define MU_FOR_EACH_1_6(X, P1, P2, P3, P4, P5, P6) \
+X(P1) \
+MU_FOR_EACH_1_5(X, P2, P3, P4, P5, P6)
+
+#define MU_FOR_EACH_1_5(X, P1, P2, P3, P4, P5) \
+X(P1) \
+MU_FOR_EACH_1_4(X, P2, P3, P4, P5)
+
+#define MU_FOR_EACH_1_4(X, P1, P2, P3, P4) \
+X(P1) \
+MU_FOR_EACH_1_3(X, P2, P3, P4)
+
+#define MU_FOR_EACH_1_3(X, P1, P2, P3) \
+X(P1) \
+MU_FOR_EACH_1_2(X, P2, P3)
+
+#define MU_FOR_EACH_1_2(X, P1, P2) \
+X(P1) \
+MU_FOR_EACH_1_1(X, P2)
+
+#define MU_FOR_EACH_1_1(X, P1) \
+X(P1)
+
+#ifdef _MSC_VER
+#define MU_FOR_EACH_1(MACRO_TO_INVOKE, ...) MU_C2(MU_FOR_EACH_1_,MU_C1(MU_COUNT_ARG(__VA_ARGS__))) MU_LPAREN MACRO_TO_INVOKE, __VA_ARGS__)
+#else
+#define MU_FOR_EACH_1(MACRO_TO_INVOKE, ...) MU_C2(MU_FOR_EACH_1_,MU_C1(MU_COUNT_ARG(__VA_ARGS__))) ( MACRO_TO_INVOKE, __VA_ARGS__)
+#endif
+
+#define MU_FOR_EACH_1_KEEP_1_124(X, keep, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104, P105, P106, P107, P108, P109, P110, P111, P112, P113, P114, P115, P116, P117, P118, P119, P120, P121, P122, P123, P124) \
+X(keep, P1) \
+MU_FOR_EACH_1_KEEP_1_123(X, keep, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104, P105, P106, P107, P108, P109, P110, P111, P112, P113, P114, P115, P116, P117, P118, P119, P120, P121, P122, P123, P124)
+
+
+#define MU_FOR_EACH_1_KEEP_1_123(X, keep, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104, P105, P106, P107, P108, P109, P110, P111, P112, P113, P114, P115, P116, P117, P118, P119, P120, P121, P122, P123) \
+X(keep, P1) \
+MU_FOR_EACH_1_KEEP_1_122(X, keep, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104, P105, P106, P107, P108, P109, P110, P111, P112, P113, P114, P115, P116, P117, P118, P119, P120, P121, P122, P123)
+
+
+#define MU_FOR_EACH_1_KEEP_1_122(X, keep, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104, P105, P106, P107, P108, P109, P110, P111, P112, P113, P114, P115, P116, P117, P118, P119, P120, P121, P122) \
+X(keep, P1) \
+MU_FOR_EACH_1_KEEP_1_121(X, keep, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104, P105, P106, P107, P108, P109, P110, P111, P112, P113, P114, P115, P116, P117, P118, P119, P120, P121, P122)
+
+
+#define MU_FOR_EACH_1_KEEP_1_121(X, keep, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104, P105, P106, P107, P108, P109, P110, P111, P112, P113, P114, P115, P116, P117, P118, P119, P120, P121) \
+X(keep, P1) \
+MU_FOR_EACH_1_KEEP_1_120(X, keep, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104, P105, P106, P107, P108, P109, P110, P111, P112, P113, P114, P115, P116, P117, P118, P119, P120, P121)
+
+
+#define MU_FOR_EACH_1_KEEP_1_120(X, keep, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104, P105, P106, P107, P108, P109, P110, P111, P112, P113, P114, P115, P116, P117, P118, P119, P120) \
+X(keep, P1) \
+MU_FOR_EACH_1_KEEP_1_119(X, keep, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104, P105, P106, P107, P108, P109, P110, P111, P112, P113, P114, P115, P116, P117, P118, P119, P120)
+
+
+#define MU_FOR_EACH_1_KEEP_1_119(X, keep, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104, P105, P106, P107, P108, P109, P110, P111, P112, P113, P114, P115, P116, P117, P118, P119) \
+X(keep, P1) \
+MU_FOR_EACH_1_KEEP_1_118(X, keep, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104, P105, P106, P107, P108, P109, P110, P111, P112, P113, P114, P115, P116, P117, P118, P119)
+
+
+#define MU_FOR_EACH_1_KEEP_1_118(X, keep, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104, P105, P106, P107, P108, P109, P110, P111, P112, P113, P114, P115, P116, P117, P118) \
+X(keep, P1) \
+MU_FOR_EACH_1_KEEP_1_117(X, keep, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104, P105, P106, P107, P108, P109, P110, P111, P112, P113, P114, P115, P116, P117, P118)
+
+
+#define MU_FOR_EACH_1_KEEP_1_117(X, keep, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104, P105, P106, P107, P108, P109, P110, P111, P112, P113, P114, P115, P116, P117) \
+X(keep, P1) \
+MU_FOR_EACH_1_KEEP_1_116(X, keep, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104, P105, P106, P107, P108, P109, P110, P111, P112, P113, P114, P115, P116, P117)
+
+
+#define MU_FOR_EACH_1_KEEP_1_116(X, keep, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104, P105, P106, P107, P108, P109, P110, P111, P112, P113, P114, P115, P116) \
+X(keep, P1) \
+MU_FOR_EACH_1_KEEP_1_115(X, keep, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104, P105, P106, P107, P108, P109, P110, P111, P112, P113, P114, P115, P116)
+
+
+#define MU_FOR_EACH_1_KEEP_1_115(X, keep, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104, P105, P106, P107, P108, P109, P110, P111, P112, P113, P114, P115) \
+X(keep, P1) \
+MU_FOR_EACH_1_KEEP_1_114(X, keep, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104, P105, P106, P107, P108, P109, P110, P111, P112, P113, P114, P115)
+
+
+#define MU_FOR_EACH_1_KEEP_1_114(X, keep, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104, P105, P106, P107, P108, P109, P110, P111, P112, P113, P114) \
+X(keep, P1) \
+MU_FOR_EACH_1_KEEP_1_113(X, keep, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104, P105, P106, P107, P108, P109, P110, P111, P112, P113, P114)
+
+
+#define MU_FOR_EACH_1_KEEP_1_113(X, keep, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104, P105, P106, P107, P108, P109, P110, P111, P112, P113) \
+X(keep, P1) \
+MU_FOR_EACH_1_KEEP_1_112(X, keep, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104, P105, P106, P107, P108, P109, P110, P111, P112, P113)
+
+
+#define MU_FOR_EACH_1_KEEP_1_112(X, keep, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104, P105, P106, P107, P108, P109, P110, P111, P112) \
+X(keep, P1) \
+MU_FOR_EACH_1_KEEP_1_111(X, keep, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104, P105, P106, P107, P108, P109, P110, P111, P112)
+
+
+#define MU_FOR_EACH_1_KEEP_1_111(X, keep, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104, P105, P106, P107, P108, P109, P110, P111) \
+X(keep, P1) \
+MU_FOR_EACH_1_KEEP_1_110(X, keep, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104, P105, P106, P107, P108, P109, P110, P111)
+
+
+#define MU_FOR_EACH_1_KEEP_1_110(X, keep, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104, P105, P106, P107, P108, P109, P110) \
+X(keep, P1) \
+MU_FOR_EACH_1_KEEP_1_109(X, keep, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104, P105, P106, P107, P108, P109, P110)
+
+
+#define MU_FOR_EACH_1_KEEP_1_109(X, keep, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104, P105, P106, P107, P108, P109) \
+X(keep, P1) \
+MU_FOR_EACH_1_KEEP_1_108(X, keep, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104, P105, P106, P107, P108, P109)
+
+
+#define MU_FOR_EACH_1_KEEP_1_108(X, keep, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104, P105, P106, P107, P108) \
+X(keep, P1) \
+MU_FOR_EACH_1_KEEP_1_107(X, keep, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104, P105, P106, P107, P108)
+
+
+#define MU_FOR_EACH_1_KEEP_1_107(X, keep, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104, P105, P106, P107) \
+X(keep, P1) \
+MU_FOR_EACH_1_KEEP_1_106(X, keep, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104, P105, P106, P107)
+
+
+#define MU_FOR_EACH_1_KEEP_1_106(X, keep, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104, P105, P106) \
+X(keep, P1) \
+MU_FOR_EACH_1_KEEP_1_105(X, keep, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104, P105, P106)
+
+
+#define MU_FOR_EACH_1_KEEP_1_105(X, keep, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104, P105) \
+X(keep, P1) \
+MU_FOR_EACH_1_KEEP_1_104(X, keep, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104, P105)
+
+
+#define MU_FOR_EACH_1_KEEP_1_104(X, keep, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104) \
+X(keep, P1) \
+MU_FOR_EACH_1_KEEP_1_103(X, keep, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104)
+
+
+#define MU_FOR_EACH_1_KEEP_1_103(X, keep, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103) \
+X(keep, P1) \
+MU_FOR_EACH_1_KEEP_1_102(X, keep, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103)
+
+
+#define MU_FOR_EACH_1_KEEP_1_102(X, keep, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102) \
+X(keep, P1) \
+MU_FOR_EACH_1_KEEP_1_101(X, keep, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102)
+
+
+#define MU_FOR_EACH_1_KEEP_1_101(X, keep, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101) \
+X(keep, P1) \
+MU_FOR_EACH_1_KEEP_1_100(X, keep, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101)
+
+
+#define MU_FOR_EACH_1_KEEP_1_100(X, keep, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100) \
+X(keep, P1) \
+MU_FOR_EACH_1_KEEP_1_99(X, keep, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100)
+
+
+#define MU_FOR_EACH_1_KEEP_1_99(X, keep, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99) \
+X(keep, P1) \
+MU_FOR_EACH_1_KEEP_1_98(X, keep, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99)
+
+
+#define MU_FOR_EACH_1_KEEP_1_98(X, keep, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98) \
+X(keep, P1) \
+MU_FOR_EACH_1_KEEP_1_97(X, keep, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98)
+
+
+#define MU_FOR_EACH_1_KEEP_1_97(X, keep, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97) \
+X(keep, P1) \
+MU_FOR_EACH_1_KEEP_1_96(X, keep, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97)
+
+
+#define MU_FOR_EACH_1_KEEP_1_96(X, keep, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96) \
+X(keep, P1) \
+MU_FOR_EACH_1_KEEP_1_95(X, keep, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96)
+
+
+#define MU_FOR_EACH_1_KEEP_1_95(X, keep, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95) \
+X(keep, P1) \
+MU_FOR_EACH_1_KEEP_1_94(X, keep, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95)
+
+
+#define MU_FOR_EACH_1_KEEP_1_94(X, keep, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94) \
+X(keep, P1) \
+MU_FOR_EACH_1_KEEP_1_93(X, keep, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94)
+
+
+#define MU_FOR_EACH_1_KEEP_1_93(X, keep, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93) \
+X(keep, P1) \
+MU_FOR_EACH_1_KEEP_1_92(X, keep, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93)
+
+
+#define MU_FOR_EACH_1_KEEP_1_92(X, keep, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92) \
+X(keep, P1) \
+MU_FOR_EACH_1_KEEP_1_91(X, keep, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92)
+
+
+#define MU_FOR_EACH_1_KEEP_1_91(X, keep, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91) \
+X(keep, P1) \
+MU_FOR_EACH_1_KEEP_1_90(X, keep, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91)
+
+
+#define MU_FOR_EACH_1_KEEP_1_90(X, keep, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90) \
+X(keep, P1) \
+MU_FOR_EACH_1_KEEP_1_89(X, keep, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90)
+
+
+#define MU_FOR_EACH_1_KEEP_1_89(X, keep, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89) \
+X(keep, P1) \
+MU_FOR_EACH_1_KEEP_1_88(X, keep, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89)
+
+
+#define MU_FOR_EACH_1_KEEP_1_88(X, keep, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88) \
+X(keep, P1) \
+MU_FOR_EACH_1_KEEP_1_87(X, keep, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88)
+
+
+#define MU_FOR_EACH_1_KEEP_1_87(X, keep, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87) \
+X(keep, P1) \
+MU_FOR_EACH_1_KEEP_1_86(X, keep, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87)
+
+
+#define MU_FOR_EACH_1_KEEP_1_86(X, keep, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86) \
+X(keep, P1) \
+MU_FOR_EACH_1_KEEP_1_85(X, keep, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86)
+
+
+#define MU_FOR_EACH_1_KEEP_1_85(X, keep, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85) \
+X(keep, P1) \
+MU_FOR_EACH_1_KEEP_1_84(X, keep, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85)
+
+
+#define MU_FOR_EACH_1_KEEP_1_84(X, keep, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84) \
+X(keep, P1) \
+MU_FOR_EACH_1_KEEP_1_83(X, keep, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84)
+
+
+#define MU_FOR_EACH_1_KEEP_1_83(X, keep, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83) \
+X(keep, P1) \
+MU_FOR_EACH_1_KEEP_1_82(X, keep, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83)
+
+
+#define MU_FOR_EACH_1_KEEP_1_82(X, keep, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82) \
+X(keep, P1) \
+MU_FOR_EACH_1_KEEP_1_81(X, keep, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82)
+
+
+#define MU_FOR_EACH_1_KEEP_1_81(X, keep, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81) \
+X(keep, P1) \
+MU_FOR_EACH_1_KEEP_1_80(X, keep, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81)
+
+
+#define MU_FOR_EACH_1_KEEP_1_80(X, keep, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80) \
+X(keep, P1) \
+MU_FOR_EACH_1_KEEP_1_79(X, keep, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80)
+
+
+#define MU_FOR_EACH_1_KEEP_1_79(X, keep, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79) \
+X(keep, P1) \
+MU_FOR_EACH_1_KEEP_1_78(X, keep, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79)
+
+
+#define MU_FOR_EACH_1_KEEP_1_78(X, keep, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78) \
+X(keep, P1) \
+MU_FOR_EACH_1_KEEP_1_77(X, keep, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78)
+
+
+#define MU_FOR_EACH_1_KEEP_1_77(X, keep, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77) \
+X(keep, P1) \
+MU_FOR_EACH_1_KEEP_1_76(X, keep, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77)
+
+
+#define MU_FOR_EACH_1_KEEP_1_76(X, keep, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76) \
+X(keep, P1) \
+MU_FOR_EACH_1_KEEP_1_75(X, keep, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76)
+
+
+#define MU_FOR_EACH_1_KEEP_1_75(X, keep, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75) \
+X(keep, P1) \
+MU_FOR_EACH_1_KEEP_1_74(X, keep, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75)
+
+
+#define MU_FOR_EACH_1_KEEP_1_74(X, keep, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74) \
+X(keep, P1) \
+MU_FOR_EACH_1_KEEP_1_73(X, keep, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74)
+
+
+#define MU_FOR_EACH_1_KEEP_1_73(X, keep, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73) \
+X(keep, P1) \
+MU_FOR_EACH_1_KEEP_1_72(X, keep, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73)
+
+
+#define MU_FOR_EACH_1_KEEP_1_72(X, keep, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72) \
+X(keep, P1) \
+MU_FOR_EACH_1_KEEP_1_71(X, keep, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72)
+
+
+#define MU_FOR_EACH_1_KEEP_1_71(X, keep, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71) \
+X(keep, P1) \
+MU_FOR_EACH_1_KEEP_1_70(X, keep, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71)
+
+
+#define MU_FOR_EACH_1_KEEP_1_70(X, keep, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70) \
+X(keep, P1) \
+MU_FOR_EACH_1_KEEP_1_69(X, keep, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70)
+
+
+#define MU_FOR_EACH_1_KEEP_1_69(X, keep, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69) \
+X(keep, P1) \
+MU_FOR_EACH_1_KEEP_1_68(X, keep, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69)
+
+
+#define MU_FOR_EACH_1_KEEP_1_68(X, keep, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68) \
+X(keep, P1) \
+MU_FOR_EACH_1_KEEP_1_67(X, keep, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68)
+
+
+#define MU_FOR_EACH_1_KEEP_1_67(X, keep, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67) \
+X(keep, P1) \
+MU_FOR_EACH_1_KEEP_1_66(X, keep, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67)
+
+
+#define MU_FOR_EACH_1_KEEP_1_66(X, keep, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66) \
+X(keep, P1) \
+MU_FOR_EACH_1_KEEP_1_65(X, keep, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66)
+
+
+#define MU_FOR_EACH_1_KEEP_1_65(X, keep, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65) \
+X(keep, P1) \
+MU_FOR_EACH_1_KEEP_1_64(X, keep, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65)
+
+
+#define MU_FOR_EACH_1_KEEP_1_64(X, keep, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64) \
+X(keep, P1) \
+MU_FOR_EACH_1_KEEP_1_63(X, keep, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64)
+
+
+#define MU_FOR_EACH_1_KEEP_1_63(X, keep, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63) \
+X(keep, P1) \
+MU_FOR_EACH_1_KEEP_1_62(X, keep, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63)
+
+
+#define MU_FOR_EACH_1_KEEP_1_62(X, keep, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62) \
+X(keep, P1) \
+MU_FOR_EACH_1_KEEP_1_61(X, keep, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62)
+
+
+#define MU_FOR_EACH_1_KEEP_1_61(X, keep, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61) \
+X(keep, P1) \
+MU_FOR_EACH_1_KEEP_1_60(X, keep, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61)
+
+
+#define MU_FOR_EACH_1_KEEP_1_60(X, keep, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60) \
+X(keep, P1) \
+MU_FOR_EACH_1_KEEP_1_59(X, keep, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60)
+
+
+#define MU_FOR_EACH_1_KEEP_1_59(X, keep, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59) \
+X(keep, P1) \
+MU_FOR_EACH_1_KEEP_1_58(X, keep, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59)
+
+
+#define MU_FOR_EACH_1_KEEP_1_58(X, keep, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58) \
+X(keep, P1) \
+MU_FOR_EACH_1_KEEP_1_57(X, keep, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58)
+
+
+#define MU_FOR_EACH_1_KEEP_1_57(X, keep, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57) \
+X(keep, P1) \
+MU_FOR_EACH_1_KEEP_1_56(X, keep, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57)
+
+
+#define MU_FOR_EACH_1_KEEP_1_56(X, keep, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56) \
+X(keep, P1) \
+MU_FOR_EACH_1_KEEP_1_55(X, keep, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56)
+
+
+#define MU_FOR_EACH_1_KEEP_1_55(X, keep, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55) \
+X(keep, P1) \
+MU_FOR_EACH_1_KEEP_1_54(X, keep, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55)
+
+
+#define MU_FOR_EACH_1_KEEP_1_54(X, keep, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54) \
+X(keep, P1) \
+MU_FOR_EACH_1_KEEP_1_53(X, keep, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54)
+
+
+#define MU_FOR_EACH_1_KEEP_1_53(X, keep, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53) \
+X(keep, P1) \
+MU_FOR_EACH_1_KEEP_1_52(X, keep, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53)
+
+
+#define MU_FOR_EACH_1_KEEP_1_52(X, keep, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52) \
+X(keep, P1) \
+MU_FOR_EACH_1_KEEP_1_51(X, keep, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52)
+
+
+#define MU_FOR_EACH_1_KEEP_1_51(X, keep, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51) \
+X(keep, P1) \
+MU_FOR_EACH_1_KEEP_1_50(X, keep, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51)
+
+
+#define MU_FOR_EACH_1_KEEP_1_50(X, keep, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50) \
+X(keep, P1) \
+MU_FOR_EACH_1_KEEP_1_49(X, keep, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50)
+
+
+#define MU_FOR_EACH_1_KEEP_1_49(X, keep, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49) \
+X(keep, P1) \
+MU_FOR_EACH_1_KEEP_1_48(X, keep, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49)
+
+
+#define MU_FOR_EACH_1_KEEP_1_48(X, keep, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48) \
+X(keep, P1) \
+MU_FOR_EACH_1_KEEP_1_47(X, keep, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48)
+
+
+#define MU_FOR_EACH_1_KEEP_1_47(X, keep, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47) \
+X(keep, P1) \
+MU_FOR_EACH_1_KEEP_1_46(X, keep, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47)
+
+
+#define MU_FOR_EACH_1_KEEP_1_46(X, keep, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46) \
+X(keep, P1) \
+MU_FOR_EACH_1_KEEP_1_45(X, keep, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46)
+
+
+#define MU_FOR_EACH_1_KEEP_1_45(X, keep, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45) \
+X(keep, P1) \
+MU_FOR_EACH_1_KEEP_1_44(X, keep, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45)
+
+
+#define MU_FOR_EACH_1_KEEP_1_44(X, keep, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44) \
+X(keep, P1) \
+MU_FOR_EACH_1_KEEP_1_43(X, keep, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44)
+
+
+#define MU_FOR_EACH_1_KEEP_1_43(X, keep, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43) \
+X(keep, P1) \
+MU_FOR_EACH_1_KEEP_1_42(X, keep, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43)
+
+
+#define MU_FOR_EACH_1_KEEP_1_42(X, keep, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42) \
+X(keep, P1) \
+MU_FOR_EACH_1_KEEP_1_41(X, keep, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42)
+
+
+#define MU_FOR_EACH_1_KEEP_1_41(X, keep, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41) \
+X(keep, P1) \
+MU_FOR_EACH_1_KEEP_1_40(X, keep, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41)
+
+
+#define MU_FOR_EACH_1_KEEP_1_40(X, keep, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40) \
+X(keep, P1) \
+MU_FOR_EACH_1_KEEP_1_39(X, keep, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40)
+
+
+#define MU_FOR_EACH_1_KEEP_1_39(X, keep, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39) \
+X(keep, P1) \
+MU_FOR_EACH_1_KEEP_1_38(X, keep, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39)
+
+
+#define MU_FOR_EACH_1_KEEP_1_38(X, keep, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38) \
+X(keep, P1) \
+MU_FOR_EACH_1_KEEP_1_37(X, keep, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38)
+
+
+#define MU_FOR_EACH_1_KEEP_1_37(X, keep, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37) \
+X(keep, P1) \
+MU_FOR_EACH_1_KEEP_1_36(X, keep, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37)
+
+
+#define MU_FOR_EACH_1_KEEP_1_36(X, keep, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36) \
+X(keep, P1) \
+MU_FOR_EACH_1_KEEP_1_35(X, keep, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36)
+
+
+#define MU_FOR_EACH_1_KEEP_1_35(X, keep, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35) \
+X(keep, P1) \
+MU_FOR_EACH_1_KEEP_1_34(X, keep, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35)
+
+
+#define MU_FOR_EACH_1_KEEP_1_34(X, keep, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34) \
+X(keep, P1) \
+MU_FOR_EACH_1_KEEP_1_33(X, keep, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34)
+
+
+#define MU_FOR_EACH_1_KEEP_1_33(X, keep, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33) \
+X(keep, P1) \
+MU_FOR_EACH_1_KEEP_1_32(X, keep, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33)
+
+
+#define MU_FOR_EACH_1_KEEP_1_32(X, keep, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32) \
+X(keep, P1) \
+MU_FOR_EACH_1_KEEP_1_31(X, keep, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32)
+
+
+#define MU_FOR_EACH_1_KEEP_1_31(X, keep, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31) \
+X(keep, P1) \
+MU_FOR_EACH_1_KEEP_1_30(X, keep, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31)
+
+
+#define MU_FOR_EACH_1_KEEP_1_30(X, keep, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30) \
+X(keep, P1) \
+MU_FOR_EACH_1_KEEP_1_29(X, keep, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30)
+
+
+#define MU_FOR_EACH_1_KEEP_1_29(X, keep, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29) \
+X(keep, P1) \
+MU_FOR_EACH_1_KEEP_1_28(X, keep, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29)
+
+
+#define MU_FOR_EACH_1_KEEP_1_28(X, keep, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28) \
+X(keep, P1) \
+MU_FOR_EACH_1_KEEP_1_27(X, keep, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28)
+
+
+#define MU_FOR_EACH_1_KEEP_1_27(X, keep, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27) \
+X(keep, P1) \
+MU_FOR_EACH_1_KEEP_1_26(X, keep, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27)
+
+
+#define MU_FOR_EACH_1_KEEP_1_26(X, keep, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26) \
+X(keep, P1) \
+MU_FOR_EACH_1_KEEP_1_25(X, keep, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26)
+
+
+#define MU_FOR_EACH_1_KEEP_1_25(X, keep, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25) \
+X(keep, P1) \
+MU_FOR_EACH_1_KEEP_1_24(X, keep, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25)
+
+
+#define MU_FOR_EACH_1_KEEP_1_24(X, keep, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24) \
+X(keep, P1) \
+MU_FOR_EACH_1_KEEP_1_23(X, keep, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24)
+
+
+#define MU_FOR_EACH_1_KEEP_1_23(X, keep, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23) \
+X(keep, P1) \
+MU_FOR_EACH_1_KEEP_1_22(X, keep, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23)
+
+
+#define MU_FOR_EACH_1_KEEP_1_22(X, keep, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22) \
+X(keep, P1) \
+MU_FOR_EACH_1_KEEP_1_21(X, keep, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22)
+
+
+#define MU_FOR_EACH_1_KEEP_1_21(X, keep, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21) \
+X(keep, P1) \
+MU_FOR_EACH_1_KEEP_1_20(X, keep, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21)
+
+
+#define MU_FOR_EACH_1_KEEP_1_20(X, keep, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20) \
+X(keep, P1) \
+MU_FOR_EACH_1_KEEP_1_19(X, keep, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20)
+
+
+#define MU_FOR_EACH_1_KEEP_1_19(X, keep, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19) \
+X(keep, P1) \
+MU_FOR_EACH_1_KEEP_1_18(X, keep, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19)
+
+
+#define MU_FOR_EACH_1_KEEP_1_18(X, keep, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18) \
+X(keep, P1) \
+MU_FOR_EACH_1_KEEP_1_17(X, keep, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18)
+
+
+#define MU_FOR_EACH_1_KEEP_1_17(X, keep, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17) \
+X(keep, P1) \
+MU_FOR_EACH_1_KEEP_1_16(X, keep, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17)
+
+
+#define MU_FOR_EACH_1_KEEP_1_16(X, keep, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16) \
+X(keep, P1) \
+MU_FOR_EACH_1_KEEP_1_15(X, keep, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16)
+
+
+#define MU_FOR_EACH_1_KEEP_1_15(X, keep, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15) \
+X(keep, P1) \
+MU_FOR_EACH_1_KEEP_1_14(X, keep, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15)
+
+
+#define MU_FOR_EACH_1_KEEP_1_14(X, keep, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14) \
+X(keep, P1) \
+MU_FOR_EACH_1_KEEP_1_13(X, keep, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14)
+
+
+#define MU_FOR_EACH_1_KEEP_1_13(X, keep, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13) \
+X(keep, P1) \
+MU_FOR_EACH_1_KEEP_1_12(X, keep, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13)
+
+
+#define MU_FOR_EACH_1_KEEP_1_12(X, keep, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12) \
+X(keep, P1) \
+MU_FOR_EACH_1_KEEP_1_11(X, keep, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12)
+
+
+#define MU_FOR_EACH_1_KEEP_1_11(X, keep, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11) \
+X(keep, P1) \
+MU_FOR_EACH_1_KEEP_1_10(X, keep, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11)
+
+
+#define MU_FOR_EACH_1_KEEP_1_10(X, keep, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10) \
+X(keep, P1) \
+MU_FOR_EACH_1_KEEP_1_9(X, keep, P2, P3, P4, P5, P6, P7, P8, P9, P10)
+
+
+#define MU_FOR_EACH_1_KEEP_1_9(X, keep, P1, P2, P3, P4, P5, P6, P7, P8, P9) \
+X(keep, P1) \
+MU_FOR_EACH_1_KEEP_1_8(X, keep, P2, P3, P4, P5, P6, P7, P8, P9)
+
+
+#define MU_FOR_EACH_1_KEEP_1_8(X, keep, P1, P2, P3, P4, P5, P6, P7, P8) \
+X(keep, P1) \
+MU_FOR_EACH_1_KEEP_1_7(X, keep, P2, P3, P4, P5, P6, P7, P8)
+
+
+#define MU_FOR_EACH_1_KEEP_1_7(X, keep, P1, P2, P3, P4, P5, P6, P7) \
+X(keep, P1) \
+MU_FOR_EACH_1_KEEP_1_6(X, keep, P2, P3, P4, P5, P6, P7)
+
+
+#define MU_FOR_EACH_1_KEEP_1_6(X, keep, P1, P2, P3, P4, P5, P6) \
+X(keep, P1) \
+MU_FOR_EACH_1_KEEP_1_5(X, keep, P2, P3, P4, P5, P6)
+
+
+#define MU_FOR_EACH_1_KEEP_1_5(X, keep, P1, P2, P3, P4, P5) \
+X(keep, P1) \
+MU_FOR_EACH_1_KEEP_1_4(X, keep, P2, P3, P4, P5)
+
+
+#define MU_FOR_EACH_1_KEEP_1_4(X, keep, P1, P2, P3, P4) \
+X(keep, P1) \
+MU_FOR_EACH_1_KEEP_1_3(X, keep, P2, P3, P4)
+
+
+#define MU_FOR_EACH_1_KEEP_1_3(X, keep, P1, P2, P3) \
+X(keep, P1) \
+MU_FOR_EACH_1_KEEP_1_2(X, keep, P2, P3)
+
+
+#define MU_FOR_EACH_1_KEEP_1_2(X, keep, P1, P2) \
+X(keep, P1) \
+MU_FOR_EACH_1_KEEP_1_1(X, keep, P2)
+
+
+
+#define MU_FOR_EACH_1_KEEP_1_1(X, keep, P1) \
+X(keep, P1)
+
+#ifdef _MSC_VER
+#define MU_FOR_EACH_1_KEEP_1(MACRO_TO_INVOKE, ...) MU_C2(MU_FOR_EACH_1_KEEP_1_, MU_C2(MU_DEC,MU_C1(MU_COUNT_ARG(__VA_ARGS__)))) MU_LPAREN MACRO_TO_INVOKE, __VA_ARGS__)
+#else
+#define MU_FOR_EACH_1_KEEP_1(MACRO_TO_INVOKE, ...) MU_C2(MU_FOR_EACH_1_KEEP_1_, MU_C2(MU_DEC,MU_C1(MU_COUNT_ARG(__VA_ARGS__)))) ( MACRO_TO_INVOKE, __VA_ARGS__)
+#endif
+
+#define MU_FOR_EACH_1_KEEP_2_124(X, keep1, keep2, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104, P105, P106, P107, P108, P109, P110, P111, P112, P113, P114, P115, P116, P117, P118, P119, P120, P121, P122, P123, P124) \
+X(keep1, keep2, P1) \
+MU_FOR_EACH_1_KEEP_2_123(X, keep1, keep2, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104, P105, P106, P107, P108, P109, P110, P111, P112, P113, P114, P115, P116, P117, P118, P119, P120, P121, P122, P123, P124)
+
+
+#define MU_FOR_EACH_1_KEEP_2_123(X, keep1, keep2, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104, P105, P106, P107, P108, P109, P110, P111, P112, P113, P114, P115, P116, P117, P118, P119, P120, P121, P122, P123) \
+X(keep1, keep2, P1) \
+MU_FOR_EACH_1_KEEP_2_122(X, keep1, keep2, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104, P105, P106, P107, P108, P109, P110, P111, P112, P113, P114, P115, P116, P117, P118, P119, P120, P121, P122, P123)
+
+
+#define MU_FOR_EACH_1_KEEP_2_122(X, keep1, keep2, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104, P105, P106, P107, P108, P109, P110, P111, P112, P113, P114, P115, P116, P117, P118, P119, P120, P121, P122) \
+X(keep1, keep2, P1) \
+MU_FOR_EACH_1_KEEP_2_121(X, keep1, keep2, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104, P105, P106, P107, P108, P109, P110, P111, P112, P113, P114, P115, P116, P117, P118, P119, P120, P121, P122)
+
+
+#define MU_FOR_EACH_1_KEEP_2_121(X, keep1, keep2, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104, P105, P106, P107, P108, P109, P110, P111, P112, P113, P114, P115, P116, P117, P118, P119, P120, P121) \
+X(keep1, keep2, P1) \
+MU_FOR_EACH_1_KEEP_2_120(X, keep1, keep2, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104, P105, P106, P107, P108, P109, P110, P111, P112, P113, P114, P115, P116, P117, P118, P119, P120, P121)
+
+
+#define MU_FOR_EACH_1_KEEP_2_120(X, keep1, keep2, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104, P105, P106, P107, P108, P109, P110, P111, P112, P113, P114, P115, P116, P117, P118, P119, P120) \
+X(keep1, keep2, P1) \
+MU_FOR_EACH_1_KEEP_2_119(X, keep1, keep2, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104, P105, P106, P107, P108, P109, P110, P111, P112, P113, P114, P115, P116, P117, P118, P119, P120)
+
+
+#define MU_FOR_EACH_1_KEEP_2_119(X, keep1, keep2, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104, P105, P106, P107, P108, P109, P110, P111, P112, P113, P114, P115, P116, P117, P118, P119) \
+X(keep1, keep2, P1) \
+MU_FOR_EACH_1_KEEP_2_118(X, keep1, keep2, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104, P105, P106, P107, P108, P109, P110, P111, P112, P113, P114, P115, P116, P117, P118, P119)
+
+
+#define MU_FOR_EACH_1_KEEP_2_118(X, keep1, keep2, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104, P105, P106, P107, P108, P109, P110, P111, P112, P113, P114, P115, P116, P117, P118) \
+X(keep1, keep2, P1) \
+MU_FOR_EACH_1_KEEP_2_117(X, keep1, keep2, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104, P105, P106, P107, P108, P109, P110, P111, P112, P113, P114, P115, P116, P117, P118)
+
+
+#define MU_FOR_EACH_1_KEEP_2_117(X, keep1, keep2, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104, P105, P106, P107, P108, P109, P110, P111, P112, P113, P114, P115, P116, P117) \
+X(keep1, keep2, P1) \
+MU_FOR_EACH_1_KEEP_2_116(X, keep1, keep2, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104, P105, P106, P107, P108, P109, P110, P111, P112, P113, P114, P115, P116, P117)
+
+
+#define MU_FOR_EACH_1_KEEP_2_116(X, keep1, keep2, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104, P105, P106, P107, P108, P109, P110, P111, P112, P113, P114, P115, P116) \
+X(keep1, keep2, P1) \
+MU_FOR_EACH_1_KEEP_2_115(X, keep1, keep2, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104, P105, P106, P107, P108, P109, P110, P111, P112, P113, P114, P115, P116)
+
+
+#define MU_FOR_EACH_1_KEEP_2_115(X, keep1, keep2, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104, P105, P106, P107, P108, P109, P110, P111, P112, P113, P114, P115) \
+X(keep1, keep2, P1) \
+MU_FOR_EACH_1_KEEP_2_114(X, keep1, keep2, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104, P105, P106, P107, P108, P109, P110, P111, P112, P113, P114, P115)
+
+
+#define MU_FOR_EACH_1_KEEP_2_114(X, keep1, keep2, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104, P105, P106, P107, P108, P109, P110, P111, P112, P113, P114) \
+X(keep1, keep2, P1) \
+MU_FOR_EACH_1_KEEP_2_113(X, keep1, keep2, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104, P105, P106, P107, P108, P109, P110, P111, P112, P113, P114)
+
+
+#define MU_FOR_EACH_1_KEEP_2_113(X, keep1, keep2, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104, P105, P106, P107, P108, P109, P110, P111, P112, P113) \
+X(keep1, keep2, P1) \
+MU_FOR_EACH_1_KEEP_2_112(X, keep1, keep2, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104, P105, P106, P107, P108, P109, P110, P111, P112, P113)
+
+
+#define MU_FOR_EACH_1_KEEP_2_112(X, keep1, keep2, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104, P105, P106, P107, P108, P109, P110, P111, P112) \
+X(keep1, keep2, P1) \
+MU_FOR_EACH_1_KEEP_2_111(X, keep1, keep2, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104, P105, P106, P107, P108, P109, P110, P111, P112)
+
+
+#define MU_FOR_EACH_1_KEEP_2_111(X, keep1, keep2, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104, P105, P106, P107, P108, P109, P110, P111) \
+X(keep1, keep2, P1) \
+MU_FOR_EACH_1_KEEP_2_110(X, keep1, keep2, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104, P105, P106, P107, P108, P109, P110, P111)
+
+
+#define MU_FOR_EACH_1_KEEP_2_110(X, keep1, keep2, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104, P105, P106, P107, P108, P109, P110) \
+X(keep1, keep2, P1) \
+MU_FOR_EACH_1_KEEP_2_109(X, keep1, keep2, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104, P105, P106, P107, P108, P109, P110)
+
+
+#define MU_FOR_EACH_1_KEEP_2_109(X, keep1, keep2, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104, P105, P106, P107, P108, P109) \
+X(keep1, keep2, P1) \
+MU_FOR_EACH_1_KEEP_2_108(X, keep1, keep2, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104, P105, P106, P107, P108, P109)
+
+
+#define MU_FOR_EACH_1_KEEP_2_108(X, keep1, keep2, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104, P105, P106, P107, P108) \
+X(keep1, keep2, P1) \
+MU_FOR_EACH_1_KEEP_2_107(X, keep1, keep2, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104, P105, P106, P107, P108)
+
+
+#define MU_FOR_EACH_1_KEEP_2_107(X, keep1, keep2, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104, P105, P106, P107) \
+X(keep1, keep2, P1) \
+MU_FOR_EACH_1_KEEP_2_106(X, keep1, keep2, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104, P105, P106, P107)
+
+
+#define MU_FOR_EACH_1_KEEP_2_106(X, keep1, keep2, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104, P105, P106) \
+X(keep1, keep2, P1) \
+MU_FOR_EACH_1_KEEP_2_105(X, keep1, keep2, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104, P105, P106)
+
+
+#define MU_FOR_EACH_1_KEEP_2_105(X, keep1, keep2, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104, P105) \
+X(keep1, keep2, P1) \
+MU_FOR_EACH_1_KEEP_2_104(X, keep1, keep2, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104, P105)
+
+
+#define MU_FOR_EACH_1_KEEP_2_104(X, keep1, keep2, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104) \
+X(keep1, keep2, P1) \
+MU_FOR_EACH_1_KEEP_2_103(X, keep1, keep2, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104)
+
+
+#define MU_FOR_EACH_1_KEEP_2_103(X, keep1, keep2, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103) \
+X(keep1, keep2, P1) \
+MU_FOR_EACH_1_KEEP_2_102(X, keep1, keep2, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103)
+
+
+#define MU_FOR_EACH_1_KEEP_2_102(X, keep1, keep2, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102) \
+X(keep1, keep2, P1) \
+MU_FOR_EACH_1_KEEP_2_101(X, keep1, keep2, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102)
+
+
+#define MU_FOR_EACH_1_KEEP_2_101(X, keep1, keep2, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101) \
+X(keep1, keep2, P1) \
+MU_FOR_EACH_1_KEEP_2_100(X, keep1, keep2, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101)
+
+
+#define MU_FOR_EACH_1_KEEP_2_100(X, keep1, keep2, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100) \
+X(keep1, keep2, P1) \
+MU_FOR_EACH_1_KEEP_2_99(X, keep1, keep2, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100)
+
+
+#define MU_FOR_EACH_1_KEEP_2_99(X, keep1, keep2, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99) \
+X(keep1, keep2, P1) \
+MU_FOR_EACH_1_KEEP_2_98(X, keep1, keep2, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99)
+
+
+#define MU_FOR_EACH_1_KEEP_2_98(X, keep1, keep2, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98) \
+X(keep1, keep2, P1) \
+MU_FOR_EACH_1_KEEP_2_97(X, keep1, keep2, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98)
+
+
+#define MU_FOR_EACH_1_KEEP_2_97(X, keep1, keep2, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97) \
+X(keep1, keep2, P1) \
+MU_FOR_EACH_1_KEEP_2_96(X, keep1, keep2, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97)
+
+
+#define MU_FOR_EACH_1_KEEP_2_96(X, keep1, keep2, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96) \
+X(keep1, keep2, P1) \
+MU_FOR_EACH_1_KEEP_2_95(X, keep1, keep2, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96)
+
+
+#define MU_FOR_EACH_1_KEEP_2_95(X, keep1, keep2, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95) \
+X(keep1, keep2, P1) \
+MU_FOR_EACH_1_KEEP_2_94(X, keep1, keep2, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95)
+
+
+#define MU_FOR_EACH_1_KEEP_2_94(X, keep1, keep2, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94) \
+X(keep1, keep2, P1) \
+MU_FOR_EACH_1_KEEP_2_93(X, keep1, keep2, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94)
+
+
+#define MU_FOR_EACH_1_KEEP_2_93(X, keep1, keep2, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93) \
+X(keep1, keep2, P1) \
+MU_FOR_EACH_1_KEEP_2_92(X, keep1, keep2, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93)
+
+
+#define MU_FOR_EACH_1_KEEP_2_92(X, keep1, keep2, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92) \
+X(keep1, keep2, P1) \
+MU_FOR_EACH_1_KEEP_2_91(X, keep1, keep2, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92)
+
+
+#define MU_FOR_EACH_1_KEEP_2_91(X, keep1, keep2, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91) \
+X(keep1, keep2, P1) \
+MU_FOR_EACH_1_KEEP_2_90(X, keep1, keep2, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91)
+
+
+#define MU_FOR_EACH_1_KEEP_2_90(X, keep1, keep2, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90) \
+X(keep1, keep2, P1) \
+MU_FOR_EACH_1_KEEP_2_89(X, keep1, keep2, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90)
+
+
+#define MU_FOR_EACH_1_KEEP_2_89(X, keep1, keep2, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89) \
+X(keep1, keep2, P1) \
+MU_FOR_EACH_1_KEEP_2_88(X, keep1, keep2, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89)
+
+
+#define MU_FOR_EACH_1_KEEP_2_88(X, keep1, keep2, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88) \
+X(keep1, keep2, P1) \
+MU_FOR_EACH_1_KEEP_2_87(X, keep1, keep2, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88)
+
+
+#define MU_FOR_EACH_1_KEEP_2_87(X, keep1, keep2, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87) \
+X(keep1, keep2, P1) \
+MU_FOR_EACH_1_KEEP_2_86(X, keep1, keep2, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87)
+
+
+#define MU_FOR_EACH_1_KEEP_2_86(X, keep1, keep2, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86) \
+X(keep1, keep2, P1) \
+MU_FOR_EACH_1_KEEP_2_85(X, keep1, keep2, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86)
+
+
+#define MU_FOR_EACH_1_KEEP_2_85(X, keep1, keep2, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85) \
+X(keep1, keep2, P1) \
+MU_FOR_EACH_1_KEEP_2_84(X, keep1, keep2, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85)
+
+
+#define MU_FOR_EACH_1_KEEP_2_84(X, keep1, keep2, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84) \
+X(keep1, keep2, P1) \
+MU_FOR_EACH_1_KEEP_2_83(X, keep1, keep2, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84)
+
+
+#define MU_FOR_EACH_1_KEEP_2_83(X, keep1, keep2, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83) \
+X(keep1, keep2, P1) \
+MU_FOR_EACH_1_KEEP_2_82(X, keep1, keep2, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83)
+
+
+#define MU_FOR_EACH_1_KEEP_2_82(X, keep1, keep2, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82) \
+X(keep1, keep2, P1) \
+MU_FOR_EACH_1_KEEP_2_81(X, keep1, keep2, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82)
+
+
+#define MU_FOR_EACH_1_KEEP_2_81(X, keep1, keep2, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81) \
+X(keep1, keep2, P1) \
+MU_FOR_EACH_1_KEEP_2_80(X, keep1, keep2, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81)
+
+
+#define MU_FOR_EACH_1_KEEP_2_80(X, keep1, keep2, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80) \
+X(keep1, keep2, P1) \
+MU_FOR_EACH_1_KEEP_2_79(X, keep1, keep2, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80)
+
+
+#define MU_FOR_EACH_1_KEEP_2_79(X, keep1, keep2, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79) \
+X(keep1, keep2, P1) \
+MU_FOR_EACH_1_KEEP_2_78(X, keep1, keep2, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79)
+
+
+#define MU_FOR_EACH_1_KEEP_2_78(X, keep1, keep2, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78) \
+X(keep1, keep2, P1) \
+MU_FOR_EACH_1_KEEP_2_77(X, keep1, keep2, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78)
+
+
+#define MU_FOR_EACH_1_KEEP_2_77(X, keep1, keep2, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77) \
+X(keep1, keep2, P1) \
+MU_FOR_EACH_1_KEEP_2_76(X, keep1, keep2, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77)
+
+
+#define MU_FOR_EACH_1_KEEP_2_76(X, keep1, keep2, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76) \
+X(keep1, keep2, P1) \
+MU_FOR_EACH_1_KEEP_2_75(X, keep1, keep2, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76)
+
+
+#define MU_FOR_EACH_1_KEEP_2_75(X, keep1, keep2, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75) \
+X(keep1, keep2, P1) \
+MU_FOR_EACH_1_KEEP_2_74(X, keep1, keep2, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75)
+
+
+#define MU_FOR_EACH_1_KEEP_2_74(X, keep1, keep2, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74) \
+X(keep1, keep2, P1) \
+MU_FOR_EACH_1_KEEP_2_73(X, keep1, keep2, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74)
+
+
+#define MU_FOR_EACH_1_KEEP_2_73(X, keep1, keep2, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73) \
+X(keep1, keep2, P1) \
+MU_FOR_EACH_1_KEEP_2_72(X, keep1, keep2, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73)
+
+
+#define MU_FOR_EACH_1_KEEP_2_72(X, keep1, keep2, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72) \
+X(keep1, keep2, P1) \
+MU_FOR_EACH_1_KEEP_2_71(X, keep1, keep2, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72)
+
+
+#define MU_FOR_EACH_1_KEEP_2_71(X, keep1, keep2, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71) \
+X(keep1, keep2, P1) \
+MU_FOR_EACH_1_KEEP_2_70(X, keep1, keep2, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71)
+
+
+#define MU_FOR_EACH_1_KEEP_2_70(X, keep1, keep2, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70) \
+X(keep1, keep2, P1) \
+MU_FOR_EACH_1_KEEP_2_69(X, keep1, keep2, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70)
+
+
+#define MU_FOR_EACH_1_KEEP_2_69(X, keep1, keep2, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69) \
+X(keep1, keep2, P1) \
+MU_FOR_EACH_1_KEEP_2_68(X, keep1, keep2, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69)
+
+
+#define MU_FOR_EACH_1_KEEP_2_68(X, keep1, keep2, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68) \
+X(keep1, keep2, P1) \
+MU_FOR_EACH_1_KEEP_2_67(X, keep1, keep2, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68)
+
+
+#define MU_FOR_EACH_1_KEEP_2_67(X, keep1, keep2, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67) \
+X(keep1, keep2, P1) \
+MU_FOR_EACH_1_KEEP_2_66(X, keep1, keep2, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67)
+
+
+#define MU_FOR_EACH_1_KEEP_2_66(X, keep1, keep2, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66) \
+X(keep1, keep2, P1) \
+MU_FOR_EACH_1_KEEP_2_65(X, keep1, keep2, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66)
+
+
+#define MU_FOR_EACH_1_KEEP_2_65(X, keep1, keep2, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65) \
+X(keep1, keep2, P1) \
+MU_FOR_EACH_1_KEEP_2_64(X, keep1, keep2, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65)
+
+
+#define MU_FOR_EACH_1_KEEP_2_64(X, keep1, keep2, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64) \
+X(keep1, keep2, P1) \
+MU_FOR_EACH_1_KEEP_2_63(X, keep1, keep2, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64)
+
+
+#define MU_FOR_EACH_1_KEEP_2_63(X, keep1, keep2, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63) \
+X(keep1, keep2, P1) \
+MU_FOR_EACH_1_KEEP_2_62(X, keep1, keep2, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63)
+
+
+#define MU_FOR_EACH_1_KEEP_2_62(X, keep1, keep2, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62) \
+X(keep1, keep2, P1) \
+MU_FOR_EACH_1_KEEP_2_61(X, keep1, keep2, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62)
+
+
+#define MU_FOR_EACH_1_KEEP_2_61(X, keep1, keep2, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61) \
+X(keep1, keep2, P1) \
+MU_FOR_EACH_1_KEEP_2_60(X, keep1, keep2, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61)
+
+
+#define MU_FOR_EACH_1_KEEP_2_60(X, keep1, keep2, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60) \
+X(keep1, keep2, P1) \
+MU_FOR_EACH_1_KEEP_2_59(X, keep1, keep2, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60)
+
+
+#define MU_FOR_EACH_1_KEEP_2_59(X, keep1, keep2, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59) \
+X(keep1, keep2, P1) \
+MU_FOR_EACH_1_KEEP_2_58(X, keep1, keep2, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59)
+
+
+#define MU_FOR_EACH_1_KEEP_2_58(X, keep1, keep2, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58) \
+X(keep1, keep2, P1) \
+MU_FOR_EACH_1_KEEP_2_57(X, keep1, keep2, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58)
+
+
+#define MU_FOR_EACH_1_KEEP_2_57(X, keep1, keep2, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57) \
+X(keep1, keep2, P1) \
+MU_FOR_EACH_1_KEEP_2_56(X, keep1, keep2, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57)
+
+
+#define MU_FOR_EACH_1_KEEP_2_56(X, keep1, keep2, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56) \
+X(keep1, keep2, P1) \
+MU_FOR_EACH_1_KEEP_2_55(X, keep1, keep2, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56)
+
+
+#define MU_FOR_EACH_1_KEEP_2_55(X, keep1, keep2, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55) \
+X(keep1, keep2, P1) \
+MU_FOR_EACH_1_KEEP_2_54(X, keep1, keep2, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55)
+
+
+#define MU_FOR_EACH_1_KEEP_2_54(X, keep1, keep2, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54) \
+X(keep1, keep2, P1) \
+MU_FOR_EACH_1_KEEP_2_53(X, keep1, keep2, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54)
+
+
+#define MU_FOR_EACH_1_KEEP_2_53(X, keep1, keep2, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53) \
+X(keep1, keep2, P1) \
+MU_FOR_EACH_1_KEEP_2_52(X, keep1, keep2, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53)
+
+
+#define MU_FOR_EACH_1_KEEP_2_52(X, keep1, keep2, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52) \
+X(keep1, keep2, P1) \
+MU_FOR_EACH_1_KEEP_2_51(X, keep1, keep2, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52)
+
+
+#define MU_FOR_EACH_1_KEEP_2_51(X, keep1, keep2, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51) \
+X(keep1, keep2, P1) \
+MU_FOR_EACH_1_KEEP_2_50(X, keep1, keep2, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51)
+
+
+#define MU_FOR_EACH_1_KEEP_2_50(X, keep1, keep2, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50) \
+X(keep1, keep2, P1) \
+MU_FOR_EACH_1_KEEP_2_49(X, keep1, keep2, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50)
+
+
+#define MU_FOR_EACH_1_KEEP_2_49(X, keep1, keep2, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49) \
+X(keep1, keep2, P1) \
+MU_FOR_EACH_1_KEEP_2_48(X, keep1, keep2, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49)
+
+
+#define MU_FOR_EACH_1_KEEP_2_48(X, keep1, keep2, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48) \
+X(keep1, keep2, P1) \
+MU_FOR_EACH_1_KEEP_2_47(X, keep1, keep2, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48)
+
+
+#define MU_FOR_EACH_1_KEEP_2_47(X, keep1, keep2, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47) \
+X(keep1, keep2, P1) \
+MU_FOR_EACH_1_KEEP_2_46(X, keep1, keep2, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47)
+
+
+#define MU_FOR_EACH_1_KEEP_2_46(X, keep1, keep2, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46) \
+X(keep1, keep2, P1) \
+MU_FOR_EACH_1_KEEP_2_45(X, keep1, keep2, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46)
+
+
+#define MU_FOR_EACH_1_KEEP_2_45(X, keep1, keep2, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45) \
+X(keep1, keep2, P1) \
+MU_FOR_EACH_1_KEEP_2_44(X, keep1, keep2, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45)
+
+
+#define MU_FOR_EACH_1_KEEP_2_44(X, keep1, keep2, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44) \
+X(keep1, keep2, P1) \
+MU_FOR_EACH_1_KEEP_2_43(X, keep1, keep2, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44)
+
+
+#define MU_FOR_EACH_1_KEEP_2_43(X, keep1, keep2, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43) \
+X(keep1, keep2, P1) \
+MU_FOR_EACH_1_KEEP_2_42(X, keep1, keep2, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43)
+
+
+#define MU_FOR_EACH_1_KEEP_2_42(X, keep1, keep2, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42) \
+X(keep1, keep2, P1) \
+MU_FOR_EACH_1_KEEP_2_41(X, keep1, keep2, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42)
+
+
+#define MU_FOR_EACH_1_KEEP_2_41(X, keep1, keep2, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41) \
+X(keep1, keep2, P1) \
+MU_FOR_EACH_1_KEEP_2_40(X, keep1, keep2, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41)
+
+
+#define MU_FOR_EACH_1_KEEP_2_40(X, keep1, keep2, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40) \
+X(keep1, keep2, P1) \
+MU_FOR_EACH_1_KEEP_2_39(X, keep1, keep2, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40)
+
+
+#define MU_FOR_EACH_1_KEEP_2_39(X, keep1, keep2, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39) \
+X(keep1, keep2, P1) \
+MU_FOR_EACH_1_KEEP_2_38(X, keep1, keep2, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39)
+
+
+#define MU_FOR_EACH_1_KEEP_2_38(X, keep1, keep2, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38) \
+X(keep1, keep2, P1) \
+MU_FOR_EACH_1_KEEP_2_37(X, keep1, keep2, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38)
+
+
+#define MU_FOR_EACH_1_KEEP_2_37(X, keep1, keep2, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37) \
+X(keep1, keep2, P1) \
+MU_FOR_EACH_1_KEEP_2_36(X, keep1, keep2, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37)
+
+
+#define MU_FOR_EACH_1_KEEP_2_36(X, keep1, keep2, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36) \
+X(keep1, keep2, P1) \
+MU_FOR_EACH_1_KEEP_2_35(X, keep1, keep2, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36)
+
+
+#define MU_FOR_EACH_1_KEEP_2_35(X, keep1, keep2, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35) \
+X(keep1, keep2, P1) \
+MU_FOR_EACH_1_KEEP_2_34(X, keep1, keep2, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35)
+
+
+#define MU_FOR_EACH_1_KEEP_2_34(X, keep1, keep2, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34) \
+X(keep1, keep2, P1) \
+MU_FOR_EACH_1_KEEP_2_33(X, keep1, keep2, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34)
+
+
+#define MU_FOR_EACH_1_KEEP_2_33(X, keep1, keep2, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33) \
+X(keep1, keep2, P1) \
+MU_FOR_EACH_1_KEEP_2_32(X, keep1, keep2, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33)
+
+
+#define MU_FOR_EACH_1_KEEP_2_32(X, keep1, keep2, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32) \
+X(keep1, keep2, P1) \
+MU_FOR_EACH_1_KEEP_2_31(X, keep1, keep2, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32)
+
+
+#define MU_FOR_EACH_1_KEEP_2_31(X, keep1, keep2, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31) \
+X(keep1, keep2, P1) \
+MU_FOR_EACH_1_KEEP_2_30(X, keep1, keep2, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31)
+
+
+#define MU_FOR_EACH_1_KEEP_2_30(X, keep1, keep2, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30) \
+X(keep1, keep2, P1) \
+MU_FOR_EACH_1_KEEP_2_29(X, keep1, keep2, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30)
+
+
+#define MU_FOR_EACH_1_KEEP_2_29(X, keep1, keep2, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29) \
+X(keep1, keep2, P1) \
+MU_FOR_EACH_1_KEEP_2_28(X, keep1, keep2, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29)
+
+
+#define MU_FOR_EACH_1_KEEP_2_28(X, keep1, keep2, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28) \
+X(keep1, keep2, P1) \
+MU_FOR_EACH_1_KEEP_2_27(X, keep1, keep2, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28)
+
+
+#define MU_FOR_EACH_1_KEEP_2_27(X, keep1, keep2, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27) \
+X(keep1, keep2, P1) \
+MU_FOR_EACH_1_KEEP_2_26(X, keep1, keep2, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27)
+
+
+#define MU_FOR_EACH_1_KEEP_2_26(X, keep1, keep2, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26) \
+X(keep1, keep2, P1) \
+MU_FOR_EACH_1_KEEP_2_25(X, keep1, keep2, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26)
+
+
+#define MU_FOR_EACH_1_KEEP_2_25(X, keep1, keep2, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25) \
+X(keep1, keep2, P1) \
+MU_FOR_EACH_1_KEEP_2_24(X, keep1, keep2, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25)
+
+
+#define MU_FOR_EACH_1_KEEP_2_24(X, keep1, keep2, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24) \
+X(keep1, keep2, P1) \
+MU_FOR_EACH_1_KEEP_2_23(X, keep1, keep2, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24)
+
+
+#define MU_FOR_EACH_1_KEEP_2_23(X, keep1, keep2, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23) \
+X(keep1, keep2, P1) \
+MU_FOR_EACH_1_KEEP_2_22(X, keep1, keep2, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23)
+
+
+#define MU_FOR_EACH_1_KEEP_2_22(X, keep1, keep2, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22) \
+X(keep1, keep2, P1) \
+MU_FOR_EACH_1_KEEP_2_21(X, keep1, keep2, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22)
+
+
+#define MU_FOR_EACH_1_KEEP_2_21(X, keep1, keep2, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21) \
+X(keep1, keep2, P1) \
+MU_FOR_EACH_1_KEEP_2_20(X, keep1, keep2, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21)
+
+
+#define MU_FOR_EACH_1_KEEP_2_20(X, keep1, keep2, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20) \
+X(keep1, keep2, P1) \
+MU_FOR_EACH_1_KEEP_2_19(X, keep1, keep2, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20)
+
+
+#define MU_FOR_EACH_1_KEEP_2_19(X, keep1, keep2, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19) \
+X(keep1, keep2, P1) \
+MU_FOR_EACH_1_KEEP_2_18(X, keep1, keep2, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19)
+
+
+#define MU_FOR_EACH_1_KEEP_2_18(X, keep1, keep2, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18) \
+X(keep1, keep2, P1) \
+MU_FOR_EACH_1_KEEP_2_17(X, keep1, keep2, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18)
+
+
+#define MU_FOR_EACH_1_KEEP_2_17(X, keep1, keep2, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17) \
+X(keep1, keep2, P1) \
+MU_FOR_EACH_1_KEEP_2_16(X, keep1, keep2, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17)
+
+
+#define MU_FOR_EACH_1_KEEP_2_16(X, keep1, keep2, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16) \
+X(keep1, keep2, P1) \
+MU_FOR_EACH_1_KEEP_2_15(X, keep1, keep2, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16)
+
+
+#define MU_FOR_EACH_1_KEEP_2_15(X, keep1, keep2, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15) \
+X(keep1, keep2, P1) \
+MU_FOR_EACH_1_KEEP_2_14(X, keep1, keep2, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15)
+
+
+#define MU_FOR_EACH_1_KEEP_2_14(X, keep1, keep2, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14) \
+X(keep1, keep2, P1) \
+MU_FOR_EACH_1_KEEP_2_13(X, keep1, keep2, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14)
+
+
+#define MU_FOR_EACH_1_KEEP_2_13(X, keep1, keep2, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13) \
+X(keep1, keep2, P1) \
+MU_FOR_EACH_1_KEEP_2_12(X, keep1, keep2, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13)
+
+
+#define MU_FOR_EACH_1_KEEP_2_12(X, keep1, keep2, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12) \
+X(keep1, keep2, P1) \
+MU_FOR_EACH_1_KEEP_2_11(X, keep1, keep2, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12)
+
+
+#define MU_FOR_EACH_1_KEEP_2_11(X, keep1, keep2, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11) \
+X(keep1, keep2, P1) \
+MU_FOR_EACH_1_KEEP_2_10(X, keep1, keep2, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11)
+
+
+#define MU_FOR_EACH_1_KEEP_2_10(X, keep1, keep2, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10) \
+X(keep1, keep2, P1) \
+MU_FOR_EACH_1_KEEP_2_9(X, keep1, keep2, P2, P3, P4, P5, P6, P7, P8, P9, P10)
+
+
+#define MU_FOR_EACH_1_KEEP_2_9(X, keep1, keep2, P1, P2, P3, P4, P5, P6, P7, P8, P9) \
+X(keep1, keep2, P1) \
+MU_FOR_EACH_1_KEEP_2_8(X, keep1, keep2, P2, P3, P4, P5, P6, P7, P8, P9)
+
+
+#define MU_FOR_EACH_1_KEEP_2_8(X, keep1, keep2, P1, P2, P3, P4, P5, P6, P7, P8) \
+X(keep1, keep2, P1) \
+MU_FOR_EACH_1_KEEP_2_7(X, keep1, keep2, P2, P3, P4, P5, P6, P7, P8)
+
+
+#define MU_FOR_EACH_1_KEEP_2_7(X, keep1, keep2, P1, P2, P3, P4, P5, P6, P7) \
+X(keep1, keep2, P1) \
+MU_FOR_EACH_1_KEEP_2_6(X, keep1, keep2, P2, P3, P4, P5, P6, P7)
+
+
+#define MU_FOR_EACH_1_KEEP_2_6(X, keep1, keep2, P1, P2, P3, P4, P5, P6) \
+X(keep1, keep2, P1) \
+MU_FOR_EACH_1_KEEP_2_5(X, keep1, keep2, P2, P3, P4, P5, P6)
+
+
+#define MU_FOR_EACH_1_KEEP_2_5(X, keep1, keep2, P1, P2, P3, P4, P5) \
+X(keep1, keep2, P1) \
+MU_FOR_EACH_1_KEEP_2_4(X, keep1, keep2, P2, P3, P4, P5)
+
+
+#define MU_FOR_EACH_1_KEEP_2_4(X, keep1, keep2, P1, P2, P3, P4) \
+X(keep1, keep2, P1) \
+MU_FOR_EACH_1_KEEP_2_3(X, keep1, keep2, P2, P3, P4)
+
+
+#define MU_FOR_EACH_1_KEEP_2_3(X, keep1, keep2, P1, P2, P3) \
+X(keep1, keep2, P1) \
+MU_FOR_EACH_1_KEEP_2_2(X, keep1, keep2, P2, P3)
+
+
+#define MU_FOR_EACH_1_KEEP_2_2(X, keep1, keep2, P1, P2) \
+X(keep1, keep2, P1) \
+MU_FOR_EACH_1_KEEP_2_1(X, keep1, keep2, P2)
+
+
+
+#define MU_FOR_EACH_1_KEEP_2_1(X, keep1, keep2, P1) \
+X(keep1, keep2, P1)
+
+#define MU_FOR_EACH_1_KEEP_2_0(...)
+
+#ifdef _MSC_VER
+#define MU_FOR_EACH_1_KEEP_2(MACRO_TO_INVOKE, ...) MU_C2(MU_FOR_EACH_1_KEEP_2_, MU_C2(MU_DEC,MU_C2(MU_DEC,MU_C1(MU_COUNT_ARG(__VA_ARGS__))))) MU_LPAREN MACRO_TO_INVOKE, __VA_ARGS__)
+#else
+#define MU_FOR_EACH_1_KEEP_2(MACRO_TO_INVOKE, ...) MU_C2(MU_FOR_EACH_1_KEEP_2_, MU_C2(MU_DEC,MU_C2(MU_DEC,MU_C1(MU_COUNT_ARG(__VA_ARGS__))))) ( MACRO_TO_INVOKE, __VA_ARGS__)
+#endif
+
+#define MU_FOR_EACH_2_KEEP_1_124(X, keep, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104, P105, P106, P107, P108, P109, P110, P111, P112, P113, P114, P115, P116, P117, P118, P119, P120, P121, P122, P123, P124) \
+X(keep, P1, P2) \
+MU_FOR_EACH_2_KEEP_1_122(X, keep, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104, P105, P106, P107, P108, P109, P110, P111, P112, P113, P114, P115, P116, P117, P118, P119, P120, P121, P122, P123, P124)
+
+
+#define MU_FOR_EACH_2_KEEP_1_122(X, keep, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104, P105, P106, P107, P108, P109, P110, P111, P112, P113, P114, P115, P116, P117, P118, P119, P120, P121, P122) \
+X(keep, P1, P2) \
+MU_FOR_EACH_2_KEEP_1_120(X, keep, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104, P105, P106, P107, P108, P109, P110, P111, P112, P113, P114, P115, P116, P117, P118, P119, P120, P121, P122)
+
+
+#define MU_FOR_EACH_2_KEEP_1_120(X, keep, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104, P105, P106, P107, P108, P109, P110, P111, P112, P113, P114, P115, P116, P117, P118, P119, P120) \
+X(keep, P1, P2) \
+MU_FOR_EACH_2_KEEP_1_118(X, keep, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104, P105, P106, P107, P108, P109, P110, P111, P112, P113, P114, P115, P116, P117, P118, P119, P120)
+
+
+#define MU_FOR_EACH_2_KEEP_1_118(X, keep, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104, P105, P106, P107, P108, P109, P110, P111, P112, P113, P114, P115, P116, P117, P118) \
+X(keep, P1, P2) \
+MU_FOR_EACH_2_KEEP_1_116(X, keep, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104, P105, P106, P107, P108, P109, P110, P111, P112, P113, P114, P115, P116, P117, P118)
+
+
+#define MU_FOR_EACH_2_KEEP_1_116(X, keep, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104, P105, P106, P107, P108, P109, P110, P111, P112, P113, P114, P115, P116) \
+X(keep, P1, P2) \
+MU_FOR_EACH_2_KEEP_1_114(X, keep, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104, P105, P106, P107, P108, P109, P110, P111, P112, P113, P114, P115, P116)
+
+
+#define MU_FOR_EACH_2_KEEP_1_114(X, keep, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104, P105, P106, P107, P108, P109, P110, P111, P112, P113, P114) \
+X(keep, P1, P2) \
+MU_FOR_EACH_2_KEEP_1_112(X, keep, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104, P105, P106, P107, P108, P109, P110, P111, P112, P113, P114)
+
+
+#define MU_FOR_EACH_2_KEEP_1_112(X, keep, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104, P105, P106, P107, P108, P109, P110, P111, P112) \
+X(keep, P1, P2) \
+MU_FOR_EACH_2_KEEP_1_110(X, keep, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104, P105, P106, P107, P108, P109, P110, P111, P112)
+
+
+#define MU_FOR_EACH_2_KEEP_1_110(X, keep, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104, P105, P106, P107, P108, P109, P110) \
+X(keep, P1, P2) \
+MU_FOR_EACH_2_KEEP_1_108(X, keep, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104, P105, P106, P107, P108, P109, P110)
+
+
+#define MU_FOR_EACH_2_KEEP_1_108(X, keep, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104, P105, P106, P107, P108) \
+X(keep, P1, P2) \
+MU_FOR_EACH_2_KEEP_1_106(X, keep, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104, P105, P106, P107, P108)
+
+
+#define MU_FOR_EACH_2_KEEP_1_106(X, keep, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104, P105, P106) \
+X(keep, P1, P2) \
+MU_FOR_EACH_2_KEEP_1_104(X, keep, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104, P105, P106)
+
+
+#define MU_FOR_EACH_2_KEEP_1_104(X, keep, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104) \
+X(keep, P1, P2) \
+MU_FOR_EACH_2_KEEP_1_102(X, keep, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104)
+
+
+#define MU_FOR_EACH_2_KEEP_1_102(X, keep, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102) \
+X(keep, P1, P2) \
+MU_FOR_EACH_2_KEEP_1_100(X, keep, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102)
+
+
+#define MU_FOR_EACH_2_KEEP_1_100(X, keep, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100) \
+X(keep, P1, P2) \
+MU_FOR_EACH_2_KEEP_1_98(X, keep, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100)
+
+
+#define MU_FOR_EACH_2_KEEP_1_98(X, keep, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98) \
+X(keep, P1, P2) \
+MU_FOR_EACH_2_KEEP_1_96(X, keep, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98)
+
+
+#define MU_FOR_EACH_2_KEEP_1_96(X, keep, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96) \
+X(keep, P1, P2) \
+MU_FOR_EACH_2_KEEP_1_94(X, keep, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96)
+
+
+#define MU_FOR_EACH_2_KEEP_1_94(X, keep, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94) \
+X(keep, P1, P2) \
+MU_FOR_EACH_2_KEEP_1_92(X, keep, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94)
+
+
+#define MU_FOR_EACH_2_KEEP_1_92(X, keep, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92) \
+X(keep, P1, P2) \
+MU_FOR_EACH_2_KEEP_1_90(X, keep, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92)
+
+
+#define MU_FOR_EACH_2_KEEP_1_90(X, keep, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90) \
+X(keep, P1, P2) \
+MU_FOR_EACH_2_KEEP_1_88(X, keep, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90)
+
+
+#define MU_FOR_EACH_2_KEEP_1_88(X, keep, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88) \
+X(keep, P1, P2) \
+MU_FOR_EACH_2_KEEP_1_86(X, keep, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88)
+
+
+#define MU_FOR_EACH_2_KEEP_1_86(X, keep, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86) \
+X(keep, P1, P2) \
+MU_FOR_EACH_2_KEEP_1_84(X, keep, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86)
+
+
+#define MU_FOR_EACH_2_KEEP_1_84(X, keep, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84) \
+X(keep, P1, P2) \
+MU_FOR_EACH_2_KEEP_1_82(X, keep, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84)
+
+
+#define MU_FOR_EACH_2_KEEP_1_82(X, keep, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82) \
+X(keep, P1, P2) \
+MU_FOR_EACH_2_KEEP_1_80(X, keep, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82)
+
+
+#define MU_FOR_EACH_2_KEEP_1_80(X, keep, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80) \
+X(keep, P1, P2) \
+MU_FOR_EACH_2_KEEP_1_78(X, keep, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80)
+
+
+#define MU_FOR_EACH_2_KEEP_1_78(X, keep, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78) \
+X(keep, P1, P2) \
+MU_FOR_EACH_2_KEEP_1_76(X, keep, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78)
+
+
+#define MU_FOR_EACH_2_KEEP_1_76(X, keep, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76) \
+X(keep, P1, P2) \
+MU_FOR_EACH_2_KEEP_1_74(X, keep, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76)
+
+
+#define MU_FOR_EACH_2_KEEP_1_74(X, keep, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74) \
+X(keep, P1, P2) \
+MU_FOR_EACH_2_KEEP_1_72(X, keep, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74)
+
+
+#define MU_FOR_EACH_2_KEEP_1_72(X, keep, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72) \
+X(keep, P1, P2) \
+MU_FOR_EACH_2_KEEP_1_70(X, keep, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72)
+
+
+#define MU_FOR_EACH_2_KEEP_1_70(X, keep, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70) \
+X(keep, P1, P2) \
+MU_FOR_EACH_2_KEEP_1_68(X, keep, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70)
+
+
+#define MU_FOR_EACH_2_KEEP_1_68(X, keep, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68) \
+X(keep, P1, P2) \
+MU_FOR_EACH_2_KEEP_1_66(X, keep, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68)
+
+
+#define MU_FOR_EACH_2_KEEP_1_66(X, keep, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66) \
+X(keep, P1, P2) \
+MU_FOR_EACH_2_KEEP_1_64(X, keep, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66)
+
+
+#define MU_FOR_EACH_2_KEEP_1_64(X, keep, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64) \
+X(keep, P1, P2) \
+MU_FOR_EACH_2_KEEP_1_62(X, keep, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64)
+
+
+#define MU_FOR_EACH_2_KEEP_1_62(X, keep, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62) \
+X(keep, P1, P2) \
+MU_FOR_EACH_2_KEEP_1_60(X, keep, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62)
+
+
+#define MU_FOR_EACH_2_KEEP_1_60(X, keep, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60) \
+X(keep, P1, P2) \
+MU_FOR_EACH_2_KEEP_1_58(X, keep, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60)
+
+
+#define MU_FOR_EACH_2_KEEP_1_58(X, keep, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58) \
+X(keep, P1, P2) \
+MU_FOR_EACH_2_KEEP_1_56(X, keep, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58)
+
+
+#define MU_FOR_EACH_2_KEEP_1_56(X, keep, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56) \
+X(keep, P1, P2) \
+MU_FOR_EACH_2_KEEP_1_54(X, keep, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56)
+
+
+#define MU_FOR_EACH_2_KEEP_1_54(X, keep, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54) \
+X(keep, P1, P2) \
+MU_FOR_EACH_2_KEEP_1_52(X, keep, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54)
+
+
+#define MU_FOR_EACH_2_KEEP_1_52(X, keep, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52) \
+X(keep, P1, P2) \
+MU_FOR_EACH_2_KEEP_1_50(X, keep, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52)
+
+
+#define MU_FOR_EACH_2_KEEP_1_50(X, keep, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50) \
+X(keep, P1, P2) \
+MU_FOR_EACH_2_KEEP_1_48(X, keep, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50)
+
+
+#define MU_FOR_EACH_2_KEEP_1_48(X, keep, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48) \
+X(keep, P1, P2) \
+MU_FOR_EACH_2_KEEP_1_46(X, keep, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48)
+
+
+#define MU_FOR_EACH_2_KEEP_1_46(X, keep, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46) \
+X(keep, P1, P2) \
+MU_FOR_EACH_2_KEEP_1_44(X, keep, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46)
+
+
+#define MU_FOR_EACH_2_KEEP_1_44(X, keep, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44) \
+X(keep, P1, P2) \
+MU_FOR_EACH_2_KEEP_1_42(X, keep, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44)
+
+
+#define MU_FOR_EACH_2_KEEP_1_42(X, keep, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42) \
+X(keep, P1, P2) \
+MU_FOR_EACH_2_KEEP_1_40(X, keep, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42)
+
+
+#define MU_FOR_EACH_2_KEEP_1_40(X, keep, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40) \
+X(keep, P1, P2) \
+MU_FOR_EACH_2_KEEP_1_38(X, keep, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40)
+
+
+#define MU_FOR_EACH_2_KEEP_1_38(X, keep, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38) \
+X(keep, P1, P2) \
+MU_FOR_EACH_2_KEEP_1_36(X, keep, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38)
+
+
+#define MU_FOR_EACH_2_KEEP_1_36(X, keep, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36) \
+X(keep, P1, P2) \
+MU_FOR_EACH_2_KEEP_1_34(X, keep, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36)
+
+
+#define MU_FOR_EACH_2_KEEP_1_34(X, keep, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34) \
+X(keep, P1, P2) \
+MU_FOR_EACH_2_KEEP_1_32(X, keep, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34)
+
+
+#define MU_FOR_EACH_2_KEEP_1_32(X, keep, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32) \
+X(keep, P1, P2) \
+MU_FOR_EACH_2_KEEP_1_30(X, keep, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32)
+
+
+#define MU_FOR_EACH_2_KEEP_1_30(X, keep, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30) \
+X(keep, P1, P2) \
+MU_FOR_EACH_2_KEEP_1_28(X, keep, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30)
+
+
+#define MU_FOR_EACH_2_KEEP_1_28(X, keep, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28) \
+X(keep, P1, P2) \
+MU_FOR_EACH_2_KEEP_1_26(X, keep, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28)
+
+
+#define MU_FOR_EACH_2_KEEP_1_26(X, keep, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26) \
+X(keep, P1, P2) \
+MU_FOR_EACH_2_KEEP_1_24(X, keep, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26)
+
+
+#define MU_FOR_EACH_2_KEEP_1_24(X, keep, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24) \
+X(keep, P1, P2) \
+MU_FOR_EACH_2_KEEP_1_22(X, keep, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24)
+
+
+#define MU_FOR_EACH_2_KEEP_1_22(X, keep, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22) \
+X(keep, P1, P2) \
+MU_FOR_EACH_2_KEEP_1_20(X, keep, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22)
+
+
+#define MU_FOR_EACH_2_KEEP_1_20(X, keep, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20) \
+X(keep, P1, P2) \
+MU_FOR_EACH_2_KEEP_1_18(X, keep, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20)
+
+
+#define MU_FOR_EACH_2_KEEP_1_18(X, keep, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18) \
+X(keep, P1, P2) \
+MU_FOR_EACH_2_KEEP_1_16(X, keep, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18)
+
+
+#define MU_FOR_EACH_2_KEEP_1_16(X, keep, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16) \
+X(keep, P1, P2) \
+MU_FOR_EACH_2_KEEP_1_14(X, keep, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16)
+
+
+#define MU_FOR_EACH_2_KEEP_1_14(X, keep, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14) \
+X(keep, P1, P2) \
+MU_FOR_EACH_2_KEEP_1_12(X, keep, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14)
+
+
+#define MU_FOR_EACH_2_KEEP_1_12(X, keep, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12) \
+X(keep, P1, P2) \
+MU_FOR_EACH_2_KEEP_1_10(X, keep, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12)
+
+
+#define MU_FOR_EACH_2_KEEP_1_10(X, keep, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10) \
+X(keep, P1, P2) \
+MU_FOR_EACH_2_KEEP_1_8(X, keep, P3, P4, P5, P6, P7, P8, P9, P10)
+
+
+#define MU_FOR_EACH_2_KEEP_1_8(X, keep, P1, P2, P3, P4, P5, P6, P7, P8) \
+X(keep, P1, P2) \
+MU_FOR_EACH_2_KEEP_1_6(X, keep, P3, P4, P5, P6, P7, P8)
+
+
+#define MU_FOR_EACH_2_KEEP_1_6(X, keep, P1, P2, P3, P4, P5, P6) \
+X(keep, P1, P2) \
+MU_FOR_EACH_2_KEEP_1_4(X, keep, P3, P4, P5, P6)
+
+
+#define MU_FOR_EACH_2_KEEP_1_4(X, keep, P1, P2, P3, P4) \
+X(keep, P1, P2) \
+MU_FOR_EACH_2_KEEP_1_2(X, keep, P3, P4)
+
+
+
+#define MU_FOR_EACH_2_KEEP_1_1(...)
+
+#define MU_FOR_EACH_2_KEEP_1_0(...)
+
+#define MU_FOR_EACH_2_KEEP_1_2(X, keep, P1, P2) \
+    X(keep, P1, P2) \
+
+#ifdef _MSC_VER
+#define MU_FOR_EACH_2_KEEP_1(MACRO_TO_INVOKE, ...) MU_C2(MU_FOR_EACH_2_KEEP_1_, MU_C2(MU_DEC,MU_C1(MU_COUNT_ARG(__VA_ARGS__)))) MU_LPAREN MACRO_TO_INVOKE, __VA_ARGS__)
+#else
+#define MU_FOR_EACH_2_KEEP_1(MACRO_TO_INVOKE, ...) MU_C2(MU_FOR_EACH_2_KEEP_1_, MU_C2(MU_DEC,MU_C1(MU_COUNT_ARG(__VA_ARGS__)))) ( MACRO_TO_INVOKE, __VA_ARGS__)
+#endif
+
+
+#define MU_FOR_EACH_2_KEEP_2_124(X, keep1, keep2, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104, P105, P106, P107, P108, P109, P110, P111, P112, P113, P114, P115, P116, P117, P118, P119, P120, P121, P122, P123, P124) \
+X(keep1, keep2, P1, P2) \
+MU_FOR_EACH_2_KEEP_2_122(X, keep1, keep2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104, P105, P106, P107, P108, P109, P110, P111, P112, P113, P114, P115, P116, P117, P118, P119, P120, P121, P122, P123, P124)
+
+
+#define MU_FOR_EACH_2_KEEP_2_122(X, keep1, keep2, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104, P105, P106, P107, P108, P109, P110, P111, P112, P113, P114, P115, P116, P117, P118, P119, P120, P121, P122) \
+X(keep1, keep2, P1, P2) \
+MU_FOR_EACH_2_KEEP_2_120(X, keep1, keep2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104, P105, P106, P107, P108, P109, P110, P111, P112, P113, P114, P115, P116, P117, P118, P119, P120, P121, P122)
+
+
+#define MU_FOR_EACH_2_KEEP_2_120(X, keep1, keep2, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104, P105, P106, P107, P108, P109, P110, P111, P112, P113, P114, P115, P116, P117, P118, P119, P120) \
+X(keep1, keep2, P1, P2) \
+MU_FOR_EACH_2_KEEP_2_118(X, keep1, keep2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104, P105, P106, P107, P108, P109, P110, P111, P112, P113, P114, P115, P116, P117, P118, P119, P120)
+
+
+#define MU_FOR_EACH_2_KEEP_2_118(X, keep1, keep2, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104, P105, P106, P107, P108, P109, P110, P111, P112, P113, P114, P115, P116, P117, P118) \
+X(keep1, keep2, P1, P2) \
+MU_FOR_EACH_2_KEEP_2_116(X, keep1, keep2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104, P105, P106, P107, P108, P109, P110, P111, P112, P113, P114, P115, P116, P117, P118)
+
+
+#define MU_FOR_EACH_2_KEEP_2_116(X, keep1, keep2, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104, P105, P106, P107, P108, P109, P110, P111, P112, P113, P114, P115, P116) \
+X(keep1, keep2, P1, P2) \
+MU_FOR_EACH_2_KEEP_2_114(X, keep1, keep2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104, P105, P106, P107, P108, P109, P110, P111, P112, P113, P114, P115, P116)
+
+
+#define MU_FOR_EACH_2_KEEP_2_114(X, keep1, keep2, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104, P105, P106, P107, P108, P109, P110, P111, P112, P113, P114) \
+X(keep1, keep2, P1, P2) \
+MU_FOR_EACH_2_KEEP_2_112(X, keep1, keep2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104, P105, P106, P107, P108, P109, P110, P111, P112, P113, P114)
+
+
+#define MU_FOR_EACH_2_KEEP_2_112(X, keep1, keep2, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104, P105, P106, P107, P108, P109, P110, P111, P112) \
+X(keep1, keep2, P1, P2) \
+MU_FOR_EACH_2_KEEP_2_110(X, keep1, keep2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104, P105, P106, P107, P108, P109, P110, P111, P112)
+
+
+#define MU_FOR_EACH_2_KEEP_2_110(X, keep1, keep2, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104, P105, P106, P107, P108, P109, P110) \
+X(keep1, keep2, P1, P2) \
+MU_FOR_EACH_2_KEEP_2_108(X, keep1, keep2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104, P105, P106, P107, P108, P109, P110)
+
+
+#define MU_FOR_EACH_2_KEEP_2_108(X, keep1, keep2, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104, P105, P106, P107, P108) \
+X(keep1, keep2, P1, P2) \
+MU_FOR_EACH_2_KEEP_2_106(X, keep1, keep2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104, P105, P106, P107, P108)
+
+
+#define MU_FOR_EACH_2_KEEP_2_106(X, keep1, keep2, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104, P105, P106) \
+X(keep1, keep2, P1, P2) \
+MU_FOR_EACH_2_KEEP_2_104(X, keep1, keep2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104, P105, P106)
+
+
+#define MU_FOR_EACH_2_KEEP_2_104(X, keep1, keep2, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104) \
+X(keep1, keep2, P1, P2) \
+MU_FOR_EACH_2_KEEP_2_102(X, keep1, keep2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104)
+
+
+#define MU_FOR_EACH_2_KEEP_2_102(X, keep1, keep2, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102) \
+X(keep1, keep2, P1, P2) \
+MU_FOR_EACH_2_KEEP_2_100(X, keep1, keep2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102)
+
+
+#define MU_FOR_EACH_2_KEEP_2_100(X, keep1, keep2, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100) \
+X(keep1, keep2, P1, P2) \
+MU_FOR_EACH_2_KEEP_2_98(X, keep1, keep2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100)
+
+
+#define MU_FOR_EACH_2_KEEP_2_98(X, keep1, keep2, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98) \
+X(keep1, keep2, P1, P2) \
+MU_FOR_EACH_2_KEEP_2_96(X, keep1, keep2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98)
+
+
+#define MU_FOR_EACH_2_KEEP_2_96(X, keep1, keep2, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96) \
+X(keep1, keep2, P1, P2) \
+MU_FOR_EACH_2_KEEP_2_94(X, keep1, keep2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96)
+
+
+#define MU_FOR_EACH_2_KEEP_2_94(X, keep1, keep2, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94) \
+X(keep1, keep2, P1, P2) \
+MU_FOR_EACH_2_KEEP_2_92(X, keep1, keep2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94)
+
+
+#define MU_FOR_EACH_2_KEEP_2_92(X, keep1, keep2, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92) \
+X(keep1, keep2, P1, P2) \
+MU_FOR_EACH_2_KEEP_2_90(X, keep1, keep2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92)
+
+
+#define MU_FOR_EACH_2_KEEP_2_90(X, keep1, keep2, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90) \
+X(keep1, keep2, P1, P2) \
+MU_FOR_EACH_2_KEEP_2_88(X, keep1, keep2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90)
+
+
+#define MU_FOR_EACH_2_KEEP_2_88(X, keep1, keep2, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88) \
+X(keep1, keep2, P1, P2) \
+MU_FOR_EACH_2_KEEP_2_86(X, keep1, keep2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88)
+
+
+#define MU_FOR_EACH_2_KEEP_2_86(X, keep1, keep2, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86) \
+X(keep1, keep2, P1, P2) \
+MU_FOR_EACH_2_KEEP_2_84(X, keep1, keep2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86)
+
+
+#define MU_FOR_EACH_2_KEEP_2_84(X, keep1, keep2, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84) \
+X(keep1, keep2, P1, P2) \
+MU_FOR_EACH_2_KEEP_2_82(X, keep1, keep2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84)
+
+
+#define MU_FOR_EACH_2_KEEP_2_82(X, keep1, keep2, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82) \
+X(keep1, keep2, P1, P2) \
+MU_FOR_EACH_2_KEEP_2_80(X, keep1, keep2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82)
+
+
+#define MU_FOR_EACH_2_KEEP_2_80(X, keep1, keep2, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80) \
+X(keep1, keep2, P1, P2) \
+MU_FOR_EACH_2_KEEP_2_78(X, keep1, keep2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80)
+
+
+#define MU_FOR_EACH_2_KEEP_2_78(X, keep1, keep2, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78) \
+X(keep1, keep2, P1, P2) \
+MU_FOR_EACH_2_KEEP_2_76(X, keep1, keep2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78)
+
+
+#define MU_FOR_EACH_2_KEEP_2_76(X, keep1, keep2, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76) \
+X(keep1, keep2, P1, P2) \
+MU_FOR_EACH_2_KEEP_2_74(X, keep1, keep2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76)
+
+
+#define MU_FOR_EACH_2_KEEP_2_74(X, keep1, keep2, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74) \
+X(keep1, keep2, P1, P2) \
+MU_FOR_EACH_2_KEEP_2_72(X, keep1, keep2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74)
+
+
+#define MU_FOR_EACH_2_KEEP_2_72(X, keep1, keep2, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72) \
+X(keep1, keep2, P1, P2) \
+MU_FOR_EACH_2_KEEP_2_70(X, keep1, keep2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72)
+
+
+#define MU_FOR_EACH_2_KEEP_2_70(X, keep1, keep2, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70) \
+X(keep1, keep2, P1, P2) \
+MU_FOR_EACH_2_KEEP_2_68(X, keep1, keep2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70)
+
+
+#define MU_FOR_EACH_2_KEEP_2_68(X, keep1, keep2, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68) \
+X(keep1, keep2, P1, P2) \
+MU_FOR_EACH_2_KEEP_2_66(X, keep1, keep2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68)
+
+
+#define MU_FOR_EACH_2_KEEP_2_66(X, keep1, keep2, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66) \
+X(keep1, keep2, P1, P2) \
+MU_FOR_EACH_2_KEEP_2_64(X, keep1, keep2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66)
+
+
+#define MU_FOR_EACH_2_KEEP_2_64(X, keep1, keep2, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64) \
+X(keep1, keep2, P1, P2) \
+MU_FOR_EACH_2_KEEP_2_62(X, keep1, keep2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64)
+
+
+#define MU_FOR_EACH_2_KEEP_2_62(X, keep1, keep2, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62) \
+X(keep1, keep2, P1, P2) \
+MU_FOR_EACH_2_KEEP_2_60(X, keep1, keep2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62)
+
+
+#define MU_FOR_EACH_2_KEEP_2_60(X, keep1, keep2, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60) \
+X(keep1, keep2, P1, P2) \
+MU_FOR_EACH_2_KEEP_2_58(X, keep1, keep2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60)
+
+
+#define MU_FOR_EACH_2_KEEP_2_58(X, keep1, keep2, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58) \
+X(keep1, keep2, P1, P2) \
+MU_FOR_EACH_2_KEEP_2_56(X, keep1, keep2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58)
+
+
+#define MU_FOR_EACH_2_KEEP_2_56(X, keep1, keep2, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56) \
+X(keep1, keep2, P1, P2) \
+MU_FOR_EACH_2_KEEP_2_54(X, keep1, keep2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56)
+
+
+#define MU_FOR_EACH_2_KEEP_2_54(X, keep1, keep2, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54) \
+X(keep1, keep2, P1, P2) \
+MU_FOR_EACH_2_KEEP_2_52(X, keep1, keep2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54)
+
+
+#define MU_FOR_EACH_2_KEEP_2_52(X, keep1, keep2, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52) \
+X(keep1, keep2, P1, P2) \
+MU_FOR_EACH_2_KEEP_2_50(X, keep1, keep2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52)
+
+
+#define MU_FOR_EACH_2_KEEP_2_50(X, keep1, keep2, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50) \
+X(keep1, keep2, P1, P2) \
+MU_FOR_EACH_2_KEEP_2_48(X, keep1, keep2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50)
+
+
+#define MU_FOR_EACH_2_KEEP_2_48(X, keep1, keep2, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48) \
+X(keep1, keep2, P1, P2) \
+MU_FOR_EACH_2_KEEP_2_46(X, keep1, keep2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48)
+
+
+#define MU_FOR_EACH_2_KEEP_2_46(X, keep1, keep2, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46) \
+X(keep1, keep2, P1, P2) \
+MU_FOR_EACH_2_KEEP_2_44(X, keep1, keep2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46)
+
+
+#define MU_FOR_EACH_2_KEEP_2_44(X, keep1, keep2, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44) \
+X(keep1, keep2, P1, P2) \
+MU_FOR_EACH_2_KEEP_2_42(X, keep1, keep2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44)
+
+
+#define MU_FOR_EACH_2_KEEP_2_42(X, keep1, keep2, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42) \
+X(keep1, keep2, P1, P2) \
+MU_FOR_EACH_2_KEEP_2_40(X, keep1, keep2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42)
+
+
+#define MU_FOR_EACH_2_KEEP_2_40(X, keep1, keep2, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40) \
+X(keep1, keep2, P1, P2) \
+MU_FOR_EACH_2_KEEP_2_38(X, keep1, keep2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40)
+
+
+#define MU_FOR_EACH_2_KEEP_2_38(X, keep1, keep2, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38) \
+X(keep1, keep2, P1, P2) \
+MU_FOR_EACH_2_KEEP_2_36(X, keep1, keep2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38)
+
+
+#define MU_FOR_EACH_2_KEEP_2_36(X, keep1, keep2, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36) \
+X(keep1, keep2, P1, P2) \
+MU_FOR_EACH_2_KEEP_2_34(X, keep1, keep2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36)
+
+
+#define MU_FOR_EACH_2_KEEP_2_34(X, keep1, keep2, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34) \
+X(keep1, keep2, P1, P2) \
+MU_FOR_EACH_2_KEEP_2_32(X, keep1, keep2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34)
+
+
+#define MU_FOR_EACH_2_KEEP_2_32(X, keep1, keep2, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32) \
+X(keep1, keep2, P1, P2) \
+MU_FOR_EACH_2_KEEP_2_30(X, keep1, keep2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32)
+
+
+#define MU_FOR_EACH_2_KEEP_2_30(X, keep1, keep2, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30) \
+X(keep1, keep2, P1, P2) \
+MU_FOR_EACH_2_KEEP_2_28(X, keep1, keep2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30)
+
+
+#define MU_FOR_EACH_2_KEEP_2_28(X, keep1, keep2, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28) \
+X(keep1, keep2, P1, P2) \
+MU_FOR_EACH_2_KEEP_2_26(X, keep1, keep2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28)
+
+
+#define MU_FOR_EACH_2_KEEP_2_26(X, keep1, keep2, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26) \
+X(keep1, keep2, P1, P2) \
+MU_FOR_EACH_2_KEEP_2_24(X, keep1, keep2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26)
+
+
+#define MU_FOR_EACH_2_KEEP_2_24(X, keep1, keep2, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24) \
+X(keep1, keep2, P1, P2) \
+MU_FOR_EACH_2_KEEP_2_22(X, keep1, keep2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24)
+
+
+#define MU_FOR_EACH_2_KEEP_2_22(X, keep1, keep2, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22) \
+X(keep1, keep2, P1, P2) \
+MU_FOR_EACH_2_KEEP_2_20(X, keep1, keep2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22)
+
+
+#define MU_FOR_EACH_2_KEEP_2_20(X, keep1, keep2, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20) \
+X(keep1, keep2, P1, P2) \
+MU_FOR_EACH_2_KEEP_2_18(X, keep1, keep2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20)
+
+
+#define MU_FOR_EACH_2_KEEP_2_18(X, keep1, keep2, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18) \
+X(keep1, keep2, P1, P2) \
+MU_FOR_EACH_2_KEEP_2_16(X, keep1, keep2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18)
+
+
+#define MU_FOR_EACH_2_KEEP_2_16(X, keep1, keep2, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16) \
+X(keep1, keep2, P1, P2) \
+MU_FOR_EACH_2_KEEP_2_14(X, keep1, keep2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16)
+
+
+#define MU_FOR_EACH_2_KEEP_2_14(X, keep1, keep2, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14) \
+X(keep1, keep2, P1, P2) \
+MU_FOR_EACH_2_KEEP_2_12(X, keep1, keep2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14)
+
+
+#define MU_FOR_EACH_2_KEEP_2_12(X, keep1, keep2, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12) \
+X(keep1, keep2, P1, P2) \
+MU_FOR_EACH_2_KEEP_2_10(X, keep1, keep2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12)
+
+
+#define MU_FOR_EACH_2_KEEP_2_10(X, keep1, keep2, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10) \
+X(keep1, keep2, P1, P2) \
+MU_FOR_EACH_2_KEEP_2_8(X, keep1, keep2, P3, P4, P5, P6, P7, P8, P9, P10)
+
+
+#define MU_FOR_EACH_2_KEEP_2_8(X, keep1, keep2, P1, P2, P3, P4, P5, P6, P7, P8) \
+X(keep1, keep2, P1, P2) \
+MU_FOR_EACH_2_KEEP_2_6(X, keep1, keep2, P3, P4, P5, P6, P7, P8)
+
+
+#define MU_FOR_EACH_2_KEEP_2_6(X, keep1, keep2, P1, P2, P3, P4, P5, P6) \
+X(keep1, keep2, P1, P2) \
+MU_FOR_EACH_2_KEEP_2_4(X, keep1, keep2, P3, P4, P5, P6)
+
+
+#define MU_FOR_EACH_2_KEEP_2_4(X, keep1, keep2, P1, P2, P3, P4) \
+X(keep1, keep2, P1, P2) \
+MU_FOR_EACH_2_KEEP_2_2(X, keep1, keep2, P3, P4)
+
+
+
+#define MU_FOR_EACH_2_KEEP_2_1(...)
+
+#define MU_FOR_EACH_2_KEEP_2_0(...)
+
+#define MU_FOR_EACH_2_KEEP_2_2(X, keep1, keep2, P1, P2) \
+    X(keep1, keep2, P1, P2) \
+
+#ifdef _MSC_VER
+#define MU_FOR_EACH_2_KEEP_2(MACRO_TO_INVOKE, ...) MU_C2(MU_FOR_EACH_2_KEEP_2_, MU_C2(MU_DEC,MU_C2(MU_DEC,MU_C1(MU_COUNT_ARG(__VA_ARGS__))))) MU_LPAREN MACRO_TO_INVOKE, __VA_ARGS__)
+#else
+#define MU_FOR_EACH_2_KEEP_2(MACRO_TO_INVOKE, ...) MU_C2(MU_FOR_EACH_2_KEEP_2_, MU_C2(MU_DEC, MU_C2(MU_DEC,MU_C1(MU_COUNT_ARG(__VA_ARGS__))))) ( MACRO_TO_INVOKE, __VA_ARGS__)
+#endif
+
+
+#define MU_FOR_EACH_2_0(...)
+
+#define MU_FOR_EACH_2_2(X, P1, P2) \
+X(P1, P2)
+
+#define MU_FOR_EACH_2_4(X, P1, P2, P3, P4) \
+X(P1, P2) \
+MU_FOR_EACH_2_2(X, P3, P4)
+
+#define MU_FOR_EACH_2_6(X, P1, P2, P3, P4, P5, P6) \
+X(P1, P2) \
+MU_FOR_EACH_2_4(X, P3, P4, P5, P6)
+
+#define MU_FOR_EACH_2_8(X, P1, P2, P3, P4, P5, P6, P7, P8) \
+X(P1, P2) \
+MU_FOR_EACH_2_6(X, P3, P4, P5, P6, P7, P8)
+
+#define MU_FOR_EACH_2_10(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10) \
+X(P1, P2) \
+MU_FOR_EACH_2_8(X, P3, P4, P5, P6, P7, P8, P9, P10)
+
+#define MU_FOR_EACH_2_12(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12) \
+X(P1, P2) \
+MU_FOR_EACH_2_10(X, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12)
+
+#define MU_FOR_EACH_2_14(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14) \
+X(P1, P2) \
+MU_FOR_EACH_2_12(X, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14)
+
+#define MU_FOR_EACH_2_16(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16) \
+X(P1, P2) \
+MU_FOR_EACH_2_14(X, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16)
+
+#define MU_FOR_EACH_2_18(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18) \
+X(P1, P2) \
+MU_FOR_EACH_2_16(X, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18)
+
+#define MU_FOR_EACH_2_20(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20) \
+X(P1, P2) \
+MU_FOR_EACH_2_18(X, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20)
+
+#define MU_FOR_EACH_2_22(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22) \
+X(P1, P2) \
+MU_FOR_EACH_2_20(X, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22)
+
+#define MU_FOR_EACH_2_24(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24) \
+X(P1, P2) \
+MU_FOR_EACH_2_22(X, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24)
+
+#define MU_FOR_EACH_2_26(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26) \
+X(P1, P2) \
+MU_FOR_EACH_2_24(X, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26)
+
+#define MU_FOR_EACH_2_28(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28) \
+X(P1, P2) \
+MU_FOR_EACH_2_26(X, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28)
+
+#define MU_FOR_EACH_2_30(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30) \
+X(P1, P2) \
+MU_FOR_EACH_2_28(X, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30)
+
+#define MU_FOR_EACH_2_32(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32) \
+X(P1, P2) \
+MU_FOR_EACH_2_30(X, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32)
+
+#define MU_FOR_EACH_2_34(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34) \
+X(P1, P2) \
+MU_FOR_EACH_2_32(X, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34)
+
+#define MU_FOR_EACH_2_36(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36) \
+X(P1, P2) \
+MU_FOR_EACH_2_34(X, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36)
+
+#define MU_FOR_EACH_2_38(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38) \
+X(P1, P2) \
+MU_FOR_EACH_2_36(X, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38)
+
+#define MU_FOR_EACH_2_40(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40) \
+X(P1, P2) \
+MU_FOR_EACH_2_38(X, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40)
+
+#define MU_FOR_EACH_2_42(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42) \
+X(P1, P2) \
+MU_FOR_EACH_2_40(X, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42)
+
+#define MU_FOR_EACH_2_44(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44) \
+X(P1, P2) \
+MU_FOR_EACH_2_42(X, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44)
+
+#define MU_FOR_EACH_2_46(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46) \
+X(P1, P2) \
+MU_FOR_EACH_2_44(X, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46)
+
+#define MU_FOR_EACH_2_48(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48) \
+X(P1, P2) \
+MU_FOR_EACH_2_46(X, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48)
+
+#define MU_FOR_EACH_2_50(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50) \
+X(P1, P2) \
+MU_FOR_EACH_2_48(X, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50)
+
+#define MU_FOR_EACH_2_52(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52) \
+X(P1, P2) \
+MU_FOR_EACH_2_50(X, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52)
+
+#define MU_FOR_EACH_2_54(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54) \
+X(P1, P2) \
+MU_FOR_EACH_2_52(X, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54)
+
+#define MU_FOR_EACH_2_56(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56) \
+X(P1, P2) \
+MU_FOR_EACH_2_54(X, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56)
+
+#define MU_FOR_EACH_2_58(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58) \
+X(P1, P2) \
+MU_FOR_EACH_2_56(X, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58)
+
+#define MU_FOR_EACH_2_60(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60) \
+X(P1, P2) \
+MU_FOR_EACH_2_58(X, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60)
+
+#define MU_FOR_EACH_2_62(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62) \
+X(P1, P2) \
+MU_FOR_EACH_2_60(X, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62)
+
+#define MU_FOR_EACH_2_64(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64) \
+X(P1, P2) \
+MU_FOR_EACH_2_62(X, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64)
+
+#define MU_FOR_EACH_2_66(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66) \
+X(P1, P2) \
+MU_FOR_EACH_2_64(X, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66)
+
+#define MU_FOR_EACH_2_68(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68) \
+X(P1, P2) \
+MU_FOR_EACH_2_66(X, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68)
+
+#define MU_FOR_EACH_2_70(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70) \
+X(P1, P2) \
+MU_FOR_EACH_2_68(X, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70)
+
+#define MU_FOR_EACH_2_72(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72) \
+X(P1, P2) \
+MU_FOR_EACH_2_70(X, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72)
+
+#define MU_FOR_EACH_2_74(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74) \
+X(P1, P2) \
+MU_FOR_EACH_2_72(X, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74)
+
+#define MU_FOR_EACH_2_76(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76) \
+X(P1, P2) \
+MU_FOR_EACH_2_74(X, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76)
+
+#define MU_FOR_EACH_2_78(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78) \
+X(P1, P2) \
+MU_FOR_EACH_2_76(X, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78)
+
+#define MU_FOR_EACH_2_80(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80) \
+X(P1, P2) \
+MU_FOR_EACH_2_78(X, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80)
+
+#define MU_FOR_EACH_2_82(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82) \
+X(P1, P2) \
+MU_FOR_EACH_2_80(X, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82)
+
+#define MU_FOR_EACH_2_84(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84) \
+X(P1, P2) \
+MU_FOR_EACH_2_82(X, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84)
+
+#define MU_FOR_EACH_2_86(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86) \
+X(P1, P2) \
+MU_FOR_EACH_2_84(X, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86)
+
+#define MU_FOR_EACH_2_88(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88) \
+X(P1, P2) \
+MU_FOR_EACH_2_86(X, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88)
+
+#define MU_FOR_EACH_2_90(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90) \
+X(P1, P2) \
+MU_FOR_EACH_2_88(X, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90)
+
+#define MU_FOR_EACH_2_92(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92) \
+X(P1, P2) \
+MU_FOR_EACH_2_90(X, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92)
+
+#define MU_FOR_EACH_2_94(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94) \
+X(P1, P2) \
+MU_FOR_EACH_2_92(X, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94)
+
+#define MU_FOR_EACH_2_96(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96) \
+X(P1, P2) \
+MU_FOR_EACH_2_94(X, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96)
+
+#define MU_FOR_EACH_2_98(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98) \
+X(P1, P2) \
+MU_FOR_EACH_2_96(X, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98)
+
+#define MU_FOR_EACH_2_100(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100) \
+X(P1, P2) \
+MU_FOR_EACH_2_98(X, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100)
+
+#define MU_FOR_EACH_2_102(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102) \
+X(P1, P2) \
+MU_FOR_EACH_2_100(X, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102)
+
+#define MU_FOR_EACH_2_104(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104) \
+X(P1, P2) \
+MU_FOR_EACH_2_102(X, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104)
+
+#define MU_FOR_EACH_2_106(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104, P105, P106) \
+X(P1, P2) \
+MU_FOR_EACH_2_104(X, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104, P105, P106)
+
+#define MU_FOR_EACH_2_108(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104, P105, P106, P107, P108) \
+X(P1, P2) \
+MU_FOR_EACH_2_106(X, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104, P105, P106, P107, P108)
+
+#define MU_FOR_EACH_2_110(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104, P105, P106, P107, P108, P109, P110) \
+X(P1, P2) \
+MU_FOR_EACH_2_108(X, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104, P105, P106, P107, P108, P109, P110)
+
+#define MU_FOR_EACH_2_112(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104, P105, P106, P107, P108, P109, P110, P111, P112) \
+X(P1, P2) \
+MU_FOR_EACH_2_110(X, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104, P105, P106, P107, P108, P109, P110, P111, P112)
+
+#define MU_FOR_EACH_2_114(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104, P105, P106, P107, P108, P109, P110, P111, P112, P113, P114) \
+X(P1, P2) \
+MU_FOR_EACH_2_112(X, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104, P105, P106, P107, P108, P109, P110, P111, P112, P113, P114)
+
+#define MU_FOR_EACH_2_116(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104, P105, P106, P107, P108, P109, P110, P111, P112, P113, P114, P115, P116) \
+X(P1, P2) \
+MU_FOR_EACH_2_114(X, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104, P105, P106, P107, P108, P109, P110, P111, P112, P113, P114, P115, P116)
+
+#define MU_FOR_EACH_2_118(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104, P105, P106, P107, P108, P109, P110, P111, P112, P113, P114, P115, P116, P117, P118) \
+X(P1, P2) \
+MU_FOR_EACH_2_116(X, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104, P105, P106, P107, P108, P109, P110, P111, P112, P113, P114, P115, P116, P117, P118)
+
+#define MU_FOR_EACH_2_120(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104, P105, P106, P107, P108, P109, P110, P111, P112, P113, P114, P115, P116, P117, P118, P119, P120) \
+X(P1, P2) \
+MU_FOR_EACH_2_118(X, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104, P105, P106, P107, P108, P109, P110, P111, P112, P113, P114, P115, P116, P117, P118, P119, P120)
+
+#define MU_FOR_EACH_2_122(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104, P105, P106, P107, P108, P109, P110, P111, P112, P113, P114, P115, P116, P117, P118, P119, P120, P121, P122) \
+X(P1, P2) \
+MU_FOR_EACH_2_120(X, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104, P105, P106, P107, P108, P109, P110, P111, P112, P113, P114, P115, P116, P117, P118, P119, P120, P121, P122)
+
+#define MU_FOR_EACH_2_124(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104, P105, P106, P107, P108, P109, P110, P111, P112, P113, P114, P115, P116, P117, P118, P119, P120, P121, P122, P123, P124) \
+X(P1, P2) \
+MU_FOR_EACH_2_122(X, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104, P105, P106, P107, P108, P109, P110, P111, P112, P113, P114, P115, P116, P117, P118, P119, P120, P121, P122, P123, P124)
+
+
+#define MU_FOR_EACH_2_REVERSE_0(...)
+
+#define MU_FOR_EACH_2_REVERSE_2(X, P1, P2) \
+X(P1, P2)
+
+#define MU_FOR_EACH_2_REVERSE_4(X, P1, P2, P3, P4) \
+X(P3, P4) \
+MU_FOR_EACH_2_REVERSE_2(X, P1, P2)
+
+#define MU_FOR_EACH_2_REVERSE_6(X, P1, P2, P3, P4, P5, P6) \
+X(P5, P6) \
+MU_FOR_EACH_2_REVERSE_4(X, P1, P2, P3, P4)
+
+#define MU_FOR_EACH_2_REVERSE_8(X, P1, P2, P3, P4, P5, P6, P7, P8) \
+X(P7, P8) \
+MU_FOR_EACH_2_REVERSE_6(X, P1, P2, P3, P4, P5, P6)
+
+#define MU_FOR_EACH_2_REVERSE_10(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10) \
+X(P9, P10) \
+MU_FOR_EACH_2_REVERSE_8(X, P1, P2, P3, P4, P5, P6, P7, P8)
+
+#define MU_FOR_EACH_2_REVERSE_12(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12) \
+X(P11, P12) \
+MU_FOR_EACH_2_REVERSE_10(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10)
+
+#define MU_FOR_EACH_2_REVERSE_14(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14) \
+X(P13, P14) \
+MU_FOR_EACH_2_REVERSE_12(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12)
+
+#define MU_FOR_EACH_2_REVERSE_16(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16) \
+X(P15, P16) \
+MU_FOR_EACH_2_REVERSE_14(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14)
+
+#define MU_FOR_EACH_2_REVERSE_18(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18) \
+X(P17, P18) \
+MU_FOR_EACH_2_REVERSE_16(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16)
+
+#define MU_FOR_EACH_2_REVERSE_20(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20) \
+X(P19, P20) \
+MU_FOR_EACH_2_REVERSE_18(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18)
+
+#define MU_FOR_EACH_2_REVERSE_22(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22) \
+X(P21, P22) \
+MU_FOR_EACH_2_REVERSE_20(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20)
+
+#define MU_FOR_EACH_2_REVERSE_24(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24) \
+X(P23, P24) \
+MU_FOR_EACH_2_REVERSE_22(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22)
+
+#define MU_FOR_EACH_2_REVERSE_26(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26) \
+X(P25, P26) \
+MU_FOR_EACH_2_REVERSE_24(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24)
+
+#define MU_FOR_EACH_2_REVERSE_28(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28) \
+X(P27, P28) \
+MU_FOR_EACH_2_REVERSE_26(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26)
+
+#define MU_FOR_EACH_2_REVERSE_30(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30) \
+X(P29, P30) \
+MU_FOR_EACH_2_REVERSE_28(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28)
+
+#define MU_FOR_EACH_2_REVERSE_32(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32) \
+X(P31, P32) \
+MU_FOR_EACH_2_REVERSE_30(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30)
+
+#define MU_FOR_EACH_2_REVERSE_34(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34) \
+X(P33, P34) \
+MU_FOR_EACH_2_REVERSE_32(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32)
+
+#define MU_FOR_EACH_2_REVERSE_36(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36) \
+X(P35, P36) \
+MU_FOR_EACH_2_REVERSE_34(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34)
+
+#define MU_FOR_EACH_2_REVERSE_38(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38) \
+X(P37, P38) \
+MU_FOR_EACH_2_REVERSE_36(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36)
+
+#define MU_FOR_EACH_2_REVERSE_40(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40) \
+X(P39, P40) \
+MU_FOR_EACH_2_REVERSE_38(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38)
+
+#define MU_FOR_EACH_2_REVERSE_42(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42) \
+X(P41, P42) \
+MU_FOR_EACH_2_REVERSE_40(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40)
+
+#define MU_FOR_EACH_2_REVERSE_44(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44) \
+X(P43, P44) \
+MU_FOR_EACH_2_REVERSE_42(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42)
+
+#define MU_FOR_EACH_2_REVERSE_46(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46) \
+X(P45, P46) \
+MU_FOR_EACH_2_REVERSE_44(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44)
+
+#define MU_FOR_EACH_2_REVERSE_48(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48) \
+X(P47, P48) \
+MU_FOR_EACH_2_REVERSE_46(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46)
+
+#define MU_FOR_EACH_2_REVERSE_50(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50) \
+X(P49, P50) \
+MU_FOR_EACH_2_REVERSE_48(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48)
+
+#define MU_FOR_EACH_2_REVERSE_52(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52) \
+X(P51, P52) \
+MU_FOR_EACH_2_REVERSE_50(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50)
+
+#define MU_FOR_EACH_2_REVERSE_54(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54) \
+X(P53, P54) \
+MU_FOR_EACH_2_REVERSE_52(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52)
+
+#define MU_FOR_EACH_2_REVERSE_56(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56) \
+X(P55, P56) \
+MU_FOR_EACH_2_REVERSE_54(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54)
+
+#define MU_FOR_EACH_2_REVERSE_58(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58) \
+X(P57, P58) \
+MU_FOR_EACH_2_REVERSE_56(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56)
+
+#define MU_FOR_EACH_2_REVERSE_60(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60) \
+X(P59, P60) \
+MU_FOR_EACH_2_REVERSE_58(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58)
+
+#define MU_FOR_EACH_2_REVERSE_62(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62) \
+X(P61, P62) \
+MU_FOR_EACH_2_REVERSE_60(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60)
+
+#define MU_FOR_EACH_2_REVERSE_64(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64) \
+X(P63, P64) \
+MU_FOR_EACH_2_REVERSE_62(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62)
+
+#define MU_FOR_EACH_2_REVERSE_66(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66) \
+X(P65, P66) \
+MU_FOR_EACH_2_REVERSE_64(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64)
+
+#define MU_FOR_EACH_2_REVERSE_68(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68) \
+X(P67, P68) \
+MU_FOR_EACH_2_REVERSE_66(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66)
+
+#define MU_FOR_EACH_2_REVERSE_70(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70) \
+X(P69, P70) \
+MU_FOR_EACH_2_REVERSE_68(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68)
+
+#define MU_FOR_EACH_2_REVERSE_72(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72) \
+X(P71, P72) \
+MU_FOR_EACH_2_REVERSE_70(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70)
+
+#define MU_FOR_EACH_2_REVERSE_74(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74) \
+X(P73, P74) \
+MU_FOR_EACH_2_REVERSE_72(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72)
+
+#define MU_FOR_EACH_2_REVERSE_76(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76) \
+X(P75, P76) \
+MU_FOR_EACH_2_REVERSE_74(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74)
+
+#define MU_FOR_EACH_2_REVERSE_78(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78) \
+X(P77, P78) \
+MU_FOR_EACH_2_REVERSE_76(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76)
+
+#define MU_FOR_EACH_2_REVERSE_80(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80) \
+X(P79, P80) \
+MU_FOR_EACH_2_REVERSE_78(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78)
+
+#define MU_FOR_EACH_2_REVERSE_82(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82) \
+X(P81, P82) \
+MU_FOR_EACH_2_REVERSE_80(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80)
+
+#define MU_FOR_EACH_2_REVERSE_84(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84) \
+X(P83, P84) \
+MU_FOR_EACH_2_REVERSE_82(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82)
+
+#define MU_FOR_EACH_2_REVERSE_86(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86) \
+X(P85, P86) \
+MU_FOR_EACH_2_REVERSE_84(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84)
+
+#define MU_FOR_EACH_2_REVERSE_88(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88) \
+X(P87, P88) \
+MU_FOR_EACH_2_REVERSE_86(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86)
+
+#define MU_FOR_EACH_2_REVERSE_90(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90) \
+X(P89, P90) \
+MU_FOR_EACH_2_REVERSE_88(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88)
+
+#define MU_FOR_EACH_2_REVERSE_92(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92) \
+X(P91, P92) \
+MU_FOR_EACH_2_REVERSE_90(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90)
+
+#define MU_FOR_EACH_2_REVERSE_94(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94) \
+X(P93, P94) \
+MU_FOR_EACH_2_REVERSE_92(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92)
+
+#define MU_FOR_EACH_2_REVERSE_96(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96) \
+X(P95, P96) \
+MU_FOR_EACH_2_REVERSE_94(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94)
+
+#define MU_FOR_EACH_2_REVERSE_98(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98) \
+X(P97, P98) \
+MU_FOR_EACH_2_REVERSE_96(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96)
+
+#define MU_FOR_EACH_2_REVERSE_100(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100) \
+X(P99, P100) \
+MU_FOR_EACH_2_REVERSE_98(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98)
+
+#define MU_FOR_EACH_2_REVERSE_102(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102) \
+X(P101, P102) \
+MU_FOR_EACH_2_REVERSE_100(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100)
+
+#define MU_FOR_EACH_2_REVERSE_104(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104) \
+X(P103, P104) \
+MU_FOR_EACH_2_REVERSE_102(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102)
+
+#define MU_FOR_EACH_2_REVERSE_106(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104, P105, P106) \
+X(P105, P106) \
+MU_FOR_EACH_2_REVERSE_104(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104)
+
+#define MU_FOR_EACH_2_REVERSE_108(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104, P105, P106, P107, P108) \
+X(P107, P108) \
+MU_FOR_EACH_2_REVERSE_106(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104, P105, P106)
+
+#define MU_FOR_EACH_2_REVERSE_110(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104, P105, P106, P107, P108, P109, P110) \
+X(P109, P110) \
+MU_FOR_EACH_2_REVERSE_108(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104, P105, P106, P107, P108)
+
+#define MU_FOR_EACH_2_REVERSE_112(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104, P105, P106, P107, P108, P109, P110, P111, P112) \
+X(P111, P112) \
+MU_FOR_EACH_2_REVERSE_110(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104, P105, P106, P107, P108, P109, P110)
+
+#define MU_FOR_EACH_2_REVERSE_114(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104, P105, P106, P107, P108, P109, P110, P111, P112, P113, P114) \
+X(P113, P114) \
+MU_FOR_EACH_2_REVERSE_112(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104, P105, P106, P107, P108, P109, P110, P111, P112)
+
+#define MU_FOR_EACH_2_REVERSE_116(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104, P105, P106, P107, P108, P109, P110, P111, P112, P113, P114, P115, P116) \
+X(P115, P116) \
+MU_FOR_EACH_2_REVERSE_114(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104, P105, P106, P107, P108, P109, P110, P111, P112, P113, P114)
+
+#define MU_FOR_EACH_2_REVERSE_118(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104, P105, P106, P107, P108, P109, P110, P111, P112, P113, P114, P115, P116, P117, P118) \
+X(P117, P118) \
+MU_FOR_EACH_2_REVERSE_116(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104, P105, P106, P107, P108, P109, P110, P111, P112, P113, P114, P115, P116)
+
+#define MU_FOR_EACH_2_REVERSE_120(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104, P105, P106, P107, P108, P109, P110, P111, P112, P113, P114, P115, P116, P117, P118, P119, P120) \
+X(P119, P120) \
+MU_FOR_EACH_2_REVERSE_118(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104, P105, P106, P107, P108, P109, P110, P111, P112, P113, P114, P115, P116, P117, P118)
+
+#define MU_FOR_EACH_2_REVERSE_122(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104, P105, P106, P107, P108, P109, P110, P111, P112, P113, P114, P115, P116, P117, P118, P119, P120, P121, P122) \
+X(P121, P122) \
+MU_FOR_EACH_2_REVERSE_120(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104, P105, P106, P107, P108, P109, P110, P111, P112, P113, P114, P115, P116, P117, P118, P119, P120)
+
+#define MU_FOR_EACH_2_REVERSE_124(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104, P105, P106, P107, P108, P109, P110, P111, P112, P113, P114, P115, P116, P117, P118, P119, P120, P121, P122, P123, P124) \
+X(P123, P124) \
+MU_FOR_EACH_2_REVERSE_122(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104, P105, P106, P107, P108, P109, P110, P111, P112, P113, P114, P115, P116, P117, P118, P119, P120, P121, P122)
+
+
+#define MU_FOR_EACH_1_COUNTED_0(...)
+
+#define MU_FOR_EACH_1_COUNTED_1(X, P1) \
+    X(1, P1)
+
+#define MU_FOR_EACH_1_COUNTED_2(X, P1, P2) \
+X(2, P1) \
+MU_FOR_EACH_1_COUNTED_1(X, P2)
+
+#define MU_FOR_EACH_1_COUNTED_3(X, P1, P2, P3) \
+X(3, P1) \
+MU_FOR_EACH_1_COUNTED_2(X, P2, P3)
+
+#define MU_FOR_EACH_1_COUNTED_4(X, P1, P2, P3, P4) \
+X(4, P1) \
+MU_FOR_EACH_1_COUNTED_3(X, P2, P3, P4)
+
+#define MU_FOR_EACH_1_COUNTED_5(X, P1, P2, P3, P4, P5) \
+X(5, P1) \
+MU_FOR_EACH_1_COUNTED_4(X, P2, P3, P4, P5)
+
+#define MU_FOR_EACH_1_COUNTED_6(X, P1, P2, P3, P4, P5, P6) \
+X(6, P1) \
+MU_FOR_EACH_1_COUNTED_5(X, P2, P3, P4, P5, P6)
+
+#define MU_FOR_EACH_1_COUNTED_7(X, P1, P2, P3, P4, P5, P6, P7) \
+X(7, P1) \
+MU_FOR_EACH_1_COUNTED_6(X, P2, P3, P4, P5, P6, P7)
+
+#define MU_FOR_EACH_1_COUNTED_8(X, P1, P2, P3, P4, P5, P6, P7, P8) \
+X(8, P1) \
+MU_FOR_EACH_1_COUNTED_7(X, P2, P3, P4, P5, P6, P7, P8)
+
+#define MU_FOR_EACH_1_COUNTED_9(X, P1, P2, P3, P4, P5, P6, P7, P8, P9) \
+X(9, P1) \
+MU_FOR_EACH_1_COUNTED_8(X, P2, P3, P4, P5, P6, P7, P8, P9)
+
+#define MU_FOR_EACH_1_COUNTED_10(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10) \
+X(10, P1) \
+MU_FOR_EACH_1_COUNTED_9(X, P2, P3, P4, P5, P6, P7, P8, P9, P10)
+
+#define MU_FOR_EACH_1_COUNTED_11(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11) \
+X(11, P1) \
+MU_FOR_EACH_1_COUNTED_10(X, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11)
+
+#define MU_FOR_EACH_1_COUNTED_12(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12) \
+X(12, P1) \
+MU_FOR_EACH_1_COUNTED_11(X, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12)
+
+#define MU_FOR_EACH_1_COUNTED_13(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13) \
+X(13, P1) \
+MU_FOR_EACH_1_COUNTED_12(X, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13)
+
+#define MU_FOR_EACH_1_COUNTED_14(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14) \
+X(14, P1) \
+MU_FOR_EACH_1_COUNTED_13(X, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14)
+
+#define MU_FOR_EACH_1_COUNTED_15(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15) \
+X(15, P1) \
+MU_FOR_EACH_1_COUNTED_14(X, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15)
+
+#define MU_FOR_EACH_1_COUNTED_16(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16) \
+X(16, P1) \
+MU_FOR_EACH_1_COUNTED_15(X, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16)
+
+#define MU_FOR_EACH_1_COUNTED_17(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17) \
+X(17, P1) \
+MU_FOR_EACH_1_COUNTED_16(X, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17)
+
+#define MU_FOR_EACH_1_COUNTED_18(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18) \
+X(18, P1) \
+MU_FOR_EACH_1_COUNTED_17(X, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18)
+
+#define MU_FOR_EACH_1_COUNTED_19(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19) \
+X(19, P1) \
+MU_FOR_EACH_1_COUNTED_18(X, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19)
+
+#define MU_FOR_EACH_1_COUNTED_20(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20) \
+X(20, P1) \
+MU_FOR_EACH_1_COUNTED_19(X, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20)
+
+#define MU_FOR_EACH_1_COUNTED_21(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21) \
+X(21, P1) \
+MU_FOR_EACH_1_COUNTED_20(X, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21)
+
+#define MU_FOR_EACH_1_COUNTED_22(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22) \
+X(22, P1) \
+MU_FOR_EACH_1_COUNTED_21(X, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22)
+
+#define MU_FOR_EACH_1_COUNTED_23(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23) \
+X(23, P1) \
+MU_FOR_EACH_1_COUNTED_22(X, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23)
+
+#define MU_FOR_EACH_1_COUNTED_24(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24) \
+X(24, P1) \
+MU_FOR_EACH_1_COUNTED_23(X, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24)
+
+#define MU_FOR_EACH_1_COUNTED_25(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25) \
+X(25, P1) \
+MU_FOR_EACH_1_COUNTED_24(X, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25)
+
+#define MU_FOR_EACH_1_COUNTED_26(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26) \
+X(26, P1) \
+MU_FOR_EACH_1_COUNTED_25(X, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26)
+
+#define MU_FOR_EACH_1_COUNTED_27(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27) \
+X(27, P1) \
+MU_FOR_EACH_1_COUNTED_26(X, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27)
+
+#define MU_FOR_EACH_1_COUNTED_28(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28) \
+X(28, P1) \
+MU_FOR_EACH_1_COUNTED_27(X, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28)
+
+#define MU_FOR_EACH_1_COUNTED_29(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29) \
+X(29, P1) \
+MU_FOR_EACH_1_COUNTED_28(X, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29)
+
+#define MU_FOR_EACH_1_COUNTED_30(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30) \
+X(30, P1) \
+MU_FOR_EACH_1_COUNTED_29(X, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30)
+
+#define MU_FOR_EACH_1_COUNTED_31(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31) \
+X(31, P1) \
+MU_FOR_EACH_1_COUNTED_30(X, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31)
+
+#define MU_FOR_EACH_1_COUNTED_32(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32) \
+X(32, P1) \
+MU_FOR_EACH_1_COUNTED_31(X, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32)
+
+#define MU_FOR_EACH_1_COUNTED_33(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33) \
+X(33, P1) \
+MU_FOR_EACH_1_COUNTED_32(X, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33)
+
+#define MU_FOR_EACH_1_COUNTED_34(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34) \
+X(34, P1) \
+MU_FOR_EACH_1_COUNTED_33(X, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34)
+
+#define MU_FOR_EACH_1_COUNTED_35(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35) \
+X(35, P1) \
+MU_FOR_EACH_1_COUNTED_34(X, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35)
+
+#define MU_FOR_EACH_1_COUNTED_36(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36) \
+X(36, P1) \
+MU_FOR_EACH_1_COUNTED_35(X, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36)
+
+#define MU_FOR_EACH_1_COUNTED_37(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37) \
+X(37, P1) \
+MU_FOR_EACH_1_COUNTED_36(X, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37)
+
+#define MU_FOR_EACH_1_COUNTED_38(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38) \
+X(38, P1) \
+MU_FOR_EACH_1_COUNTED_37(X, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38)
+
+#define MU_FOR_EACH_1_COUNTED_39(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39) \
+X(39, P1) \
+MU_FOR_EACH_1_COUNTED_38(X, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39)
+
+#define MU_FOR_EACH_1_COUNTED_40(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40) \
+X(40, P1) \
+MU_FOR_EACH_1_COUNTED_39(X, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40)
+
+#define MU_FOR_EACH_1_COUNTED_41(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41) \
+X(41, P1) \
+MU_FOR_EACH_1_COUNTED_40(X, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41)
+
+#define MU_FOR_EACH_1_COUNTED_42(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42) \
+X(42, P1) \
+MU_FOR_EACH_1_COUNTED_41(X, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42)
+
+#define MU_FOR_EACH_1_COUNTED_43(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43) \
+X(43, P1) \
+MU_FOR_EACH_1_COUNTED_42(X, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43)
+
+#define MU_FOR_EACH_1_COUNTED_44(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44) \
+X(44, P1) \
+MU_FOR_EACH_1_COUNTED_43(X, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44)
+
+#define MU_FOR_EACH_1_COUNTED_45(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45) \
+X(45, P1) \
+MU_FOR_EACH_1_COUNTED_44(X, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45)
+
+#define MU_FOR_EACH_1_COUNTED_46(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46) \
+X(46, P1) \
+MU_FOR_EACH_1_COUNTED_45(X, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46)
+
+#define MU_FOR_EACH_1_COUNTED_47(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47) \
+X(47, P1) \
+MU_FOR_EACH_1_COUNTED_46(X, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47)
+
+#define MU_FOR_EACH_1_COUNTED_48(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48) \
+X(48, P1) \
+MU_FOR_EACH_1_COUNTED_47(X, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48)
+
+#define MU_FOR_EACH_1_COUNTED_49(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49) \
+X(49, P1) \
+MU_FOR_EACH_1_COUNTED_48(X, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49)
+
+#define MU_FOR_EACH_1_COUNTED_50(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50) \
+X(50, P1) \
+MU_FOR_EACH_1_COUNTED_49(X, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50)
+
+#define MU_FOR_EACH_1_COUNTED_51(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51) \
+X(51, P1) \
+MU_FOR_EACH_1_COUNTED_50(X, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51)
+
+#define MU_FOR_EACH_1_COUNTED_52(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52) \
+X(52, P1) \
+MU_FOR_EACH_1_COUNTED_51(X, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52)
+
+#define MU_FOR_EACH_1_COUNTED_53(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53) \
+X(53, P1) \
+MU_FOR_EACH_1_COUNTED_52(X, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53)
+
+#define MU_FOR_EACH_1_COUNTED_54(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54) \
+X(54, P1) \
+MU_FOR_EACH_1_COUNTED_53(X, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54)
+
+#define MU_FOR_EACH_1_COUNTED_55(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55) \
+X(55, P1) \
+MU_FOR_EACH_1_COUNTED_54(X, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55)
+
+#define MU_FOR_EACH_1_COUNTED_56(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56) \
+X(56, P1) \
+MU_FOR_EACH_1_COUNTED_55(X, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56)
+
+#define MU_FOR_EACH_1_COUNTED_57(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57) \
+X(57, P1) \
+MU_FOR_EACH_1_COUNTED_56(X, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57)
+
+#define MU_FOR_EACH_1_COUNTED_58(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58) \
+X(58, P1) \
+MU_FOR_EACH_1_COUNTED_57(X, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58)
+
+#define MU_FOR_EACH_1_COUNTED_59(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59) \
+X(59, P1) \
+MU_FOR_EACH_1_COUNTED_58(X, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59)
+
+#define MU_FOR_EACH_1_COUNTED_60(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60) \
+X(60, P1) \
+MU_FOR_EACH_1_COUNTED_59(X, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60)
+
+#define MU_FOR_EACH_1_COUNTED_61(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61) \
+X(61, P1) \
+MU_FOR_EACH_1_COUNTED_60(X, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61)
+
+#define MU_FOR_EACH_1_COUNTED_62(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62) \
+X(62, P1) \
+MU_FOR_EACH_1_COUNTED_61(X, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62)
+
+#define MU_FOR_EACH_1_COUNTED_63(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63) \
+X(63, P1) \
+MU_FOR_EACH_1_COUNTED_62(X, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63)
+
+#define MU_FOR_EACH_1_COUNTED_64(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64) \
+X(64, P1) \
+MU_FOR_EACH_1_COUNTED_63(X, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64)
+
+#define MU_FOR_EACH_1_COUNTED_65(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65) \
+X(65, P1) \
+MU_FOR_EACH_1_COUNTED_64(X, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65)
+
+#define MU_FOR_EACH_1_COUNTED_66(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66) \
+X(66, P1) \
+MU_FOR_EACH_1_COUNTED_65(X, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66)
+
+#define MU_FOR_EACH_1_COUNTED_67(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67) \
+X(67, P1) \
+MU_FOR_EACH_1_COUNTED_66(X, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67)
+
+#define MU_FOR_EACH_1_COUNTED_68(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68) \
+X(68, P1) \
+MU_FOR_EACH_1_COUNTED_67(X, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68)
+
+#define MU_FOR_EACH_1_COUNTED_69(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69) \
+X(69, P1) \
+MU_FOR_EACH_1_COUNTED_68(X, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69)
+
+#define MU_FOR_EACH_1_COUNTED_70(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70) \
+X(70, P1) \
+MU_FOR_EACH_1_COUNTED_69(X, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70)
+
+#define MU_FOR_EACH_1_COUNTED_71(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71) \
+X(71, P1) \
+MU_FOR_EACH_1_COUNTED_70(X, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71)
+
+#define MU_FOR_EACH_1_COUNTED_72(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72) \
+X(72, P1) \
+MU_FOR_EACH_1_COUNTED_71(X, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72)
+
+#define MU_FOR_EACH_1_COUNTED_73(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73) \
+X(73, P1) \
+MU_FOR_EACH_1_COUNTED_72(X, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73)
+
+#define MU_FOR_EACH_1_COUNTED_74(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74) \
+X(74, P1) \
+MU_FOR_EACH_1_COUNTED_73(X, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74)
+
+#define MU_FOR_EACH_1_COUNTED_75(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75) \
+X(75, P1) \
+MU_FOR_EACH_1_COUNTED_74(X, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75)
+
+#define MU_FOR_EACH_1_COUNTED_76(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76) \
+X(76, P1) \
+MU_FOR_EACH_1_COUNTED_75(X, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76)
+
+#define MU_FOR_EACH_1_COUNTED_77(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77) \
+X(77, P1) \
+MU_FOR_EACH_1_COUNTED_76(X, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77)
+
+#define MU_FOR_EACH_1_COUNTED_78(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78) \
+X(78, P1) \
+MU_FOR_EACH_1_COUNTED_77(X, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78)
+
+#define MU_FOR_EACH_1_COUNTED_79(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79) \
+X(79, P1) \
+MU_FOR_EACH_1_COUNTED_78(X, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79)
+
+#define MU_FOR_EACH_1_COUNTED_80(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80) \
+X(80, P1) \
+MU_FOR_EACH_1_COUNTED_79(X, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80)
+
+#define MU_FOR_EACH_1_COUNTED_81(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81) \
+X(81, P1) \
+MU_FOR_EACH_1_COUNTED_80(X, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81)
+
+#define MU_FOR_EACH_1_COUNTED_82(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82) \
+X(82, P1) \
+MU_FOR_EACH_1_COUNTED_81(X, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82)
+
+#define MU_FOR_EACH_1_COUNTED_83(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83) \
+X(83, P1) \
+MU_FOR_EACH_1_COUNTED_82(X, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83)
+
+#define MU_FOR_EACH_1_COUNTED_84(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84) \
+X(84, P1) \
+MU_FOR_EACH_1_COUNTED_83(X, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84)
+
+#define MU_FOR_EACH_1_COUNTED_85(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85) \
+X(85, P1) \
+MU_FOR_EACH_1_COUNTED_84(X, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85)
+
+#define MU_FOR_EACH_1_COUNTED_86(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86) \
+X(86, P1) \
+MU_FOR_EACH_1_COUNTED_85(X, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86)
+
+#define MU_FOR_EACH_1_COUNTED_87(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87) \
+X(87, P1) \
+MU_FOR_EACH_1_COUNTED_86(X, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87)
+
+#define MU_FOR_EACH_1_COUNTED_88(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88) \
+X(88, P1) \
+MU_FOR_EACH_1_COUNTED_87(X, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88)
+
+#define MU_FOR_EACH_1_COUNTED_89(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89) \
+X(89, P1) \
+MU_FOR_EACH_1_COUNTED_88(X, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89)
+
+#define MU_FOR_EACH_1_COUNTED_90(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90) \
+X(90, P1) \
+MU_FOR_EACH_1_COUNTED_89(X, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90)
+
+#define MU_FOR_EACH_1_COUNTED_91(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91) \
+X(91, P1) \
+MU_FOR_EACH_1_COUNTED_90(X, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91)
+
+#define MU_FOR_EACH_1_COUNTED_92(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92) \
+X(92, P1) \
+MU_FOR_EACH_1_COUNTED_91(X, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92)
+
+#define MU_FOR_EACH_1_COUNTED_93(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93) \
+X(93, P1) \
+MU_FOR_EACH_1_COUNTED_92(X, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93)
+
+#define MU_FOR_EACH_1_COUNTED_94(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94) \
+X(94, P1) \
+MU_FOR_EACH_1_COUNTED_93(X, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94)
+
+#define MU_FOR_EACH_1_COUNTED_95(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95) \
+X(95, P1) \
+MU_FOR_EACH_1_COUNTED_94(X, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95)
+
+#define MU_FOR_EACH_1_COUNTED_96(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96) \
+X(96, P1) \
+MU_FOR_EACH_1_COUNTED_95(X, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96)
+
+#define MU_FOR_EACH_1_COUNTED_97(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97) \
+X(97, P1) \
+MU_FOR_EACH_1_COUNTED_96(X, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97)
+
+#define MU_FOR_EACH_1_COUNTED_98(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98) \
+X(98, P1) \
+MU_FOR_EACH_1_COUNTED_97(X, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98)
+
+#define MU_FOR_EACH_1_COUNTED_99(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99) \
+X(99, P1) \
+MU_FOR_EACH_1_COUNTED_98(X, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99)
+
+#define MU_FOR_EACH_1_COUNTED_100(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100) \
+X(100, P1) \
+MU_FOR_EACH_1_COUNTED_99(X, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100)
+
+#define MU_FOR_EACH_1_COUNTED_101(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101) \
+X(101, P1) \
+MU_FOR_EACH_1_COUNTED_100(X, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101)
+
+#define MU_FOR_EACH_1_COUNTED_102(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102) \
+X(102, P1) \
+MU_FOR_EACH_1_COUNTED_101(X, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102)
+
+#define MU_FOR_EACH_1_COUNTED_103(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103) \
+X(103, P1) \
+MU_FOR_EACH_1_COUNTED_102(X, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103)
+
+#define MU_FOR_EACH_1_COUNTED_104(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104) \
+X(104, P1) \
+MU_FOR_EACH_1_COUNTED_103(X, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104)
+
+#define MU_FOR_EACH_1_COUNTED_105(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104, P105) \
+X(105, P1) \
+MU_FOR_EACH_1_COUNTED_104(X, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104, P105)
+
+#define MU_FOR_EACH_1_COUNTED_106(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104, P105, P106) \
+X(106, P1) \
+MU_FOR_EACH_1_COUNTED_105(X, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104, P105, P106)
+
+#define MU_FOR_EACH_1_COUNTED_107(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104, P105, P106, P107) \
+X(107, P1) \
+MU_FOR_EACH_1_COUNTED_106(X, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104, P105, P106, P107)
+
+#define MU_FOR_EACH_1_COUNTED_108(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104, P105, P106, P107, P108) \
+X(108, P1) \
+MU_FOR_EACH_1_COUNTED_107(X, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104, P105, P106, P107, P108)
+
+#define MU_FOR_EACH_1_COUNTED_109(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104, P105, P106, P107, P108, P109) \
+X(109, P1) \
+MU_FOR_EACH_1_COUNTED_108(X, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104, P105, P106, P107, P108, P109)
+
+#define MU_FOR_EACH_1_COUNTED_110(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104, P105, P106, P107, P108, P109, P110) \
+X(110, P1) \
+MU_FOR_EACH_1_COUNTED_109(X, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104, P105, P106, P107, P108, P109, P110)
+
+#define MU_FOR_EACH_1_COUNTED_111(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104, P105, P106, P107, P108, P109, P110, P111) \
+X(111, P1) \
+MU_FOR_EACH_1_COUNTED_110(X, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104, P105, P106, P107, P108, P109, P110, P111)
+
+#define MU_FOR_EACH_1_COUNTED_112(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104, P105, P106, P107, P108, P109, P110, P111, P112) \
+X(112, P1) \
+MU_FOR_EACH_1_COUNTED_111(X, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104, P105, P106, P107, P108, P109, P110, P111, P112)
+
+#define MU_FOR_EACH_1_COUNTED_113(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104, P105, P106, P107, P108, P109, P110, P111, P112, P113) \
+X(113, P1) \
+MU_FOR_EACH_1_COUNTED_112(X, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104, P105, P106, P107, P108, P109, P110, P111, P112, P113)
+
+#define MU_FOR_EACH_1_COUNTED_114(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104, P105, P106, P107, P108, P109, P110, P111, P112, P113, P114) \
+X(114, P1) \
+MU_FOR_EACH_1_COUNTED_113(X, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104, P105, P106, P107, P108, P109, P110, P111, P112, P113, P114)
+
+#define MU_FOR_EACH_1_COUNTED_115(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104, P105, P106, P107, P108, P109, P110, P111, P112, P113, P114, P115) \
+X(115, P1) \
+MU_FOR_EACH_1_COUNTED_114(X, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104, P105, P106, P107, P108, P109, P110, P111, P112, P113, P114, P115)
+
+#define MU_FOR_EACH_1_COUNTED_116(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104, P105, P106, P107, P108, P109, P110, P111, P112, P113, P114, P115, P116) \
+X(116, P1) \
+MU_FOR_EACH_1_COUNTED_115(X, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104, P105, P106, P107, P108, P109, P110, P111, P112, P113, P114, P115, P116)
+
+#define MU_FOR_EACH_1_COUNTED_117(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104, P105, P106, P107, P108, P109, P110, P111, P112, P113, P114, P115, P116, P117) \
+X(117, P1) \
+MU_FOR_EACH_1_COUNTED_116(X, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104, P105, P106, P107, P108, P109, P110, P111, P112, P113, P114, P115, P116, P117)
+
+#define MU_FOR_EACH_1_COUNTED_118(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104, P105, P106, P107, P108, P109, P110, P111, P112, P113, P114, P115, P116, P117, P118) \
+X(118, P1) \
+MU_FOR_EACH_1_COUNTED_117(X, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104, P105, P106, P107, P108, P109, P110, P111, P112, P113, P114, P115, P116, P117, P118)
+
+#define MU_FOR_EACH_1_COUNTED_119(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104, P105, P106, P107, P108, P109, P110, P111, P112, P113, P114, P115, P116, P117, P118, P119) \
+X(119, P1) \
+MU_FOR_EACH_1_COUNTED_118(X, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104, P105, P106, P107, P108, P109, P110, P111, P112, P113, P114, P115, P116, P117, P118, P119)
+
+#define MU_FOR_EACH_1_COUNTED_120(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104, P105, P106, P107, P108, P109, P110, P111, P112, P113, P114, P115, P116, P117, P118, P119, P120) \
+X(120, P1) \
+MU_FOR_EACH_1_COUNTED_119(X, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104, P105, P106, P107, P108, P109, P110, P111, P112, P113, P114, P115, P116, P117, P118, P119, P120)
+
+#define MU_FOR_EACH_1_COUNTED_121(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104, P105, P106, P107, P108, P109, P110, P111, P112, P113, P114, P115, P116, P117, P118, P119, P120, P121) \
+X(121, P1) \
+MU_FOR_EACH_1_COUNTED_120(X, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104, P105, P106, P107, P108, P109, P110, P111, P112, P113, P114, P115, P116, P117, P118, P119, P120, P121)
+
+#define MU_FOR_EACH_1_COUNTED_122(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104, P105, P106, P107, P108, P109, P110, P111, P112, P113, P114, P115, P116, P117, P118, P119, P120, P121, P122) \
+X(122, P1) \
+MU_FOR_EACH_1_COUNTED_121(X, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104, P105, P106, P107, P108, P109, P110, P111, P112, P113, P114, P115, P116, P117, P118, P119, P120, P121, P122)
+
+#define MU_FOR_EACH_1_COUNTED_123(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104, P105, P106, P107, P108, P109, P110, P111, P112, P113, P114, P115, P116, P117, P118, P119, P120, P121, P122, P123) \
+X(123, P1) \
+MU_FOR_EACH_1_COUNTED_122(X, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104, P105, P106, P107, P108, P109, P110, P111, P112, P113, P114, P115, P116, P117, P118, P119, P120, P121, P122, P123)
+
+#define MU_FOR_EACH_1_COUNTED_124(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104, P105, P106, P107, P108, P109, P110, P111, P112, P113, P114, P115, P116, P117, P118, P119, P120, P121, P122, P123, P124) \
+X(124, P1) \
+MU_FOR_EACH_1_COUNTED_123(X, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104, P105, P106, P107, P108, P109, P110, P111, P112, P113, P114, P115, P116, P117, P118, P119, P120, P121, P122, P123, P124)
+
+
+#define MU_FOR_EACH_2_COUNTED_0(...)
+
+#define MU_FOR_EACH_2_COUNTED_2(X, P1, P2) \
+    X(2, P1, P2)
+
+#define MU_FOR_EACH_2_COUNTED_4(X, P1, P2, P3, P4) \
+X(4, P1, P2) \
+MU_FOR_EACH_2_COUNTED_2(X, P3, P4)
+
+#define MU_FOR_EACH_2_COUNTED_6(X, P1, P2, P3, P4, P5, P6) \
+X(6, P1, P2) \
+MU_FOR_EACH_2_COUNTED_4(X, P3, P4, P5, P6)
+
+#define MU_FOR_EACH_2_COUNTED_8(X, P1, P2, P3, P4, P5, P6, P7, P8) \
+X(8, P1, P2) \
+MU_FOR_EACH_2_COUNTED_6(X, P3, P4, P5, P6, P7, P8)
+
+#define MU_FOR_EACH_2_COUNTED_10(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10) \
+X(10, P1, P2) \
+MU_FOR_EACH_2_COUNTED_8(X, P3, P4, P5, P6, P7, P8, P9, P10)
+
+#define MU_FOR_EACH_2_COUNTED_12(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12) \
+X(12, P1, P2) \
+MU_FOR_EACH_2_COUNTED_10(X, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12)
+
+#define MU_FOR_EACH_2_COUNTED_14(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14) \
+X(14, P1, P2) \
+MU_FOR_EACH_2_COUNTED_12(X, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14)
+
+#define MU_FOR_EACH_2_COUNTED_16(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16) \
+X(16, P1, P2) \
+MU_FOR_EACH_2_COUNTED_14(X, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16)
+
+#define MU_FOR_EACH_2_COUNTED_18(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18) \
+X(18, P1, P2) \
+MU_FOR_EACH_2_COUNTED_16(X, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18)
+
+#define MU_FOR_EACH_2_COUNTED_20(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20) \
+X(20, P1, P2) \
+MU_FOR_EACH_2_COUNTED_18(X, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20)
+
+#define MU_FOR_EACH_2_COUNTED_22(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22) \
+X(22, P1, P2) \
+MU_FOR_EACH_2_COUNTED_20(X, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22)
+
+#define MU_FOR_EACH_2_COUNTED_24(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24) \
+X(24, P1, P2) \
+MU_FOR_EACH_2_COUNTED_22(X, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24)
+
+#define MU_FOR_EACH_2_COUNTED_26(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26) \
+X(26, P1, P2) \
+MU_FOR_EACH_2_COUNTED_24(X, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26)
+
+#define MU_FOR_EACH_2_COUNTED_28(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28) \
+X(28, P1, P2) \
+MU_FOR_EACH_2_COUNTED_26(X, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28)
+
+#define MU_FOR_EACH_2_COUNTED_30(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30) \
+X(30, P1, P2) \
+MU_FOR_EACH_2_COUNTED_28(X, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30)
+
+#define MU_FOR_EACH_2_COUNTED_32(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32) \
+X(32, P1, P2) \
+MU_FOR_EACH_2_COUNTED_30(X, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32)
+
+#define MU_FOR_EACH_2_COUNTED_34(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34) \
+X(34, P1, P2) \
+MU_FOR_EACH_2_COUNTED_32(X, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34)
+
+#define MU_FOR_EACH_2_COUNTED_36(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36) \
+X(36, P1, P2) \
+MU_FOR_EACH_2_COUNTED_34(X, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36)
+
+#define MU_FOR_EACH_2_COUNTED_38(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38) \
+X(38, P1, P2) \
+MU_FOR_EACH_2_COUNTED_36(X, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38)
+
+#define MU_FOR_EACH_2_COUNTED_40(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40) \
+X(40, P1, P2) \
+MU_FOR_EACH_2_COUNTED_38(X, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40)
+
+#define MU_FOR_EACH_2_COUNTED_42(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42) \
+X(42, P1, P2) \
+MU_FOR_EACH_2_COUNTED_40(X, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42)
+
+#define MU_FOR_EACH_2_COUNTED_44(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44) \
+X(44, P1, P2) \
+MU_FOR_EACH_2_COUNTED_42(X, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44)
+
+#define MU_FOR_EACH_2_COUNTED_46(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46) \
+X(46, P1, P2) \
+MU_FOR_EACH_2_COUNTED_44(X, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46)
+
+#define MU_FOR_EACH_2_COUNTED_48(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48) \
+X(48, P1, P2) \
+MU_FOR_EACH_2_COUNTED_46(X, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48)
+
+#define MU_FOR_EACH_2_COUNTED_50(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50) \
+X(50, P1, P2) \
+MU_FOR_EACH_2_COUNTED_48(X, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50)
+
+#define MU_FOR_EACH_2_COUNTED_52(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52) \
+X(52, P1, P2) \
+MU_FOR_EACH_2_COUNTED_50(X, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52)
+
+#define MU_FOR_EACH_2_COUNTED_54(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54) \
+X(54, P1, P2) \
+MU_FOR_EACH_2_COUNTED_52(X, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54)
+
+#define MU_FOR_EACH_2_COUNTED_56(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56) \
+X(56, P1, P2) \
+MU_FOR_EACH_2_COUNTED_54(X, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56)
+
+#define MU_FOR_EACH_2_COUNTED_58(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58) \
+X(58, P1, P2) \
+MU_FOR_EACH_2_COUNTED_56(X, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58)
+
+#define MU_FOR_EACH_2_COUNTED_60(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60) \
+X(60, P1, P2) \
+MU_FOR_EACH_2_COUNTED_58(X, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60)
+
+#define MU_FOR_EACH_2_COUNTED_62(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62) \
+X(62, P1, P2) \
+MU_FOR_EACH_2_COUNTED_60(X, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62)
+
+#define MU_FOR_EACH_2_COUNTED_64(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64) \
+X(64, P1, P2) \
+MU_FOR_EACH_2_COUNTED_62(X, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64)
+
+#define MU_FOR_EACH_2_COUNTED_66(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66) \
+X(66, P1, P2) \
+MU_FOR_EACH_2_COUNTED_64(X, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66)
+
+#define MU_FOR_EACH_2_COUNTED_68(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68) \
+X(68, P1, P2) \
+MU_FOR_EACH_2_COUNTED_66(X, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68)
+
+#define MU_FOR_EACH_2_COUNTED_70(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70) \
+X(70, P1, P2) \
+MU_FOR_EACH_2_COUNTED_68(X, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70)
+
+#define MU_FOR_EACH_2_COUNTED_72(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72) \
+X(72, P1, P2) \
+MU_FOR_EACH_2_COUNTED_70(X, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72)
+
+#define MU_FOR_EACH_2_COUNTED_74(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74) \
+X(74, P1, P2) \
+MU_FOR_EACH_2_COUNTED_72(X, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74)
+
+#define MU_FOR_EACH_2_COUNTED_76(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76) \
+X(76, P1, P2) \
+MU_FOR_EACH_2_COUNTED_74(X, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76)
+
+#define MU_FOR_EACH_2_COUNTED_78(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78) \
+X(78, P1, P2) \
+MU_FOR_EACH_2_COUNTED_76(X, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78)
+
+#define MU_FOR_EACH_2_COUNTED_80(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80) \
+X(80, P1, P2) \
+MU_FOR_EACH_2_COUNTED_78(X, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80)
+
+#define MU_FOR_EACH_2_COUNTED_82(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82) \
+X(82, P1, P2) \
+MU_FOR_EACH_2_COUNTED_80(X, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82)
+
+#define MU_FOR_EACH_2_COUNTED_84(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84) \
+X(84, P1, P2) \
+MU_FOR_EACH_2_COUNTED_82(X, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84)
+
+#define MU_FOR_EACH_2_COUNTED_86(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86) \
+X(86, P1, P2) \
+MU_FOR_EACH_2_COUNTED_84(X, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86)
+
+#define MU_FOR_EACH_2_COUNTED_88(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88) \
+X(88, P1, P2) \
+MU_FOR_EACH_2_COUNTED_86(X, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88)
+
+#define MU_FOR_EACH_2_COUNTED_90(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90) \
+X(90, P1, P2) \
+MU_FOR_EACH_2_COUNTED_88(X, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90)
+
+#define MU_FOR_EACH_2_COUNTED_92(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92) \
+X(92, P1, P2) \
+MU_FOR_EACH_2_COUNTED_90(X, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92)
+
+#define MU_FOR_EACH_2_COUNTED_94(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94) \
+X(94, P1, P2) \
+MU_FOR_EACH_2_COUNTED_92(X, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94)
+
+#define MU_FOR_EACH_2_COUNTED_96(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96) \
+X(96, P1, P2) \
+MU_FOR_EACH_2_COUNTED_94(X, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96)
+
+#define MU_FOR_EACH_2_COUNTED_98(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98) \
+X(98, P1, P2) \
+MU_FOR_EACH_2_COUNTED_96(X, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98)
+
+#define MU_FOR_EACH_2_COUNTED_100(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100) \
+X(100, P1, P2) \
+MU_FOR_EACH_2_COUNTED_98(X, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100)
+
+#define MU_FOR_EACH_2_COUNTED_102(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102) \
+X(102, P1, P2) \
+MU_FOR_EACH_2_COUNTED_100(X, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102)
+
+#define MU_FOR_EACH_2_COUNTED_104(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104) \
+X(104, P1, P2) \
+MU_FOR_EACH_2_COUNTED_102(X, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104)
+
+#define MU_FOR_EACH_2_COUNTED_106(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104, P105, P106) \
+X(106, P1, P2) \
+MU_FOR_EACH_2_COUNTED_104(X, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104, P105, P106)
+
+#define MU_FOR_EACH_2_COUNTED_108(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104, P105, P106, P107, P108) \
+X(108, P1, P2) \
+MU_FOR_EACH_2_COUNTED_106(X, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104, P105, P106, P107, P108)
+
+#define MU_FOR_EACH_2_COUNTED_110(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104, P105, P106, P107, P108, P109, P110) \
+X(110, P1, P2) \
+MU_FOR_EACH_2_COUNTED_108(X, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104, P105, P106, P107, P108, P109, P110)
+
+#define MU_FOR_EACH_2_COUNTED_112(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104, P105, P106, P107, P108, P109, P110, P111, P112) \
+X(112, P1, P2) \
+MU_FOR_EACH_2_COUNTED_110(X, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104, P105, P106, P107, P108, P109, P110, P111, P112)
+
+#define MU_FOR_EACH_2_COUNTED_114(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104, P105, P106, P107, P108, P109, P110, P111, P112, P113, P114) \
+X(114, P1, P2) \
+MU_FOR_EACH_2_COUNTED_112(X, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104, P105, P106, P107, P108, P109, P110, P111, P112, P113, P114)
+
+#define MU_FOR_EACH_2_COUNTED_116(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104, P105, P106, P107, P108, P109, P110, P111, P112, P113, P114, P115, P116) \
+X(116, P1, P2) \
+MU_FOR_EACH_2_COUNTED_114(X, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104, P105, P106, P107, P108, P109, P110, P111, P112, P113, P114, P115, P116)
+
+#define MU_FOR_EACH_2_COUNTED_118(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104, P105, P106, P107, P108, P109, P110, P111, P112, P113, P114, P115, P116, P117, P118) \
+X(118, P1, P2) \
+MU_FOR_EACH_2_COUNTED_116(X, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104, P105, P106, P107, P108, P109, P110, P111, P112, P113, P114, P115, P116, P117, P118)
+
+#define MU_FOR_EACH_2_COUNTED_120(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104, P105, P106, P107, P108, P109, P110, P111, P112, P113, P114, P115, P116, P117, P118, P119, P120) \
+X(120, P1, P2) \
+MU_FOR_EACH_2_COUNTED_118(X, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104, P105, P106, P107, P108, P109, P110, P111, P112, P113, P114, P115, P116, P117, P118, P119, P120)
+
+#define MU_FOR_EACH_2_COUNTED_122(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104, P105, P106, P107, P108, P109, P110, P111, P112, P113, P114, P115, P116, P117, P118, P119, P120, P121, P122) \
+X(122, P1, P2) \
+MU_FOR_EACH_2_COUNTED_120(X, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104, P105, P106, P107, P108, P109, P110, P111, P112, P113, P114, P115, P116, P117, P118, P119, P120, P121, P122)
+
+#define MU_FOR_EACH_2_COUNTED_124(X, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104, P105, P106, P107, P108, P109, P110, P111, P112, P113, P114, P115, P116, P117, P118, P119, P120, P121, P122, P123, P124) \
+X(124, P1, P2) \
+MU_FOR_EACH_2_COUNTED_122(X, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40, P41, P42, P43, P44, P45, P46, P47, P48, P49, P50, P51, P52, P53, P54, P55, P56, P57, P58, P59, P60, P61, P62, P63, P64, P65, P66, P67, P68, P69, P70, P71, P72, P73, P74, P75, P76, P77, P78, P79, P80, P81, P82, P83, P84, P85, P86, P87, P88, P89, P90, P91, P92, P93, P94, P95, P96, P97, P98, P99, P100, P101, P102, P103, P104, P105, P106, P107, P108, P109, P110, P111, P112, P113, P114, P115, P116, P117, P118, P119, P120, P121, P122, P123, P124)
+
+
+#ifdef _MSC_VER
+#define MU_FOR_EACH_2(MACRO_TO_INVOKE, ...) MU_C2(MU_FOR_EACH_2_, MU_C1(MU_COUNT_ARG(__VA_ARGS__))) MU_LPAREN MACRO_TO_INVOKE, __VA_ARGS__)
+/*the COUNTED breed of MU_FOR_EACH macro invokes a macro with 3 parameters: 1st being the count of invocation. For example.
+MU_FOR_EACH_2_COUNTER(MACRO, a,b,c,d,e,f) will result in 
+MACRO(6, a,b)
+MACRO(4, c,d)
+MACRO(2, e,f)
+This macro exists because we need a "stop condition" in outputting COMMA... when calling a function f(a,b,c,d) cannot be f(a,b,c,d,) <=doesn't compile (as opposed to enum definition)
+*/
+#define MU_FOR_EACH_2_COUNTED(MACRO_TO_INVOKE, ...) MU_C2(MU_FOR_EACH_2_COUNTED_, MU_C1(MU_COUNT_ARG(__VA_ARGS__))) MU_LPAREN MACRO_TO_INVOKE, __VA_ARGS__)
+#define MU_FOR_EACH_1_COUNTED(MACRO_TO_INVOKE, ...) MU_C2(MU_FOR_EACH_1_COUNTED_, MU_C1(MU_COUNT_ARG(__VA_ARGS__))) MU_LPAREN MACRO_TO_INVOKE, __VA_ARGS__)
+
+/*MU_FOR_EACH_2_REVERSE acts just like MU_FOR_EACH_2, but in reverse order. Example:
+MU_FOR_EACH_2_REVERSE(X,a,b,c,d,e,f) => X(e,f) X(c,d) X (a, b) in this order */
+#define MU_FOR_EACH_2_REVERSE(MACRO_TO_INVOKE, ...) MU_C2(MU_FOR_EACH_2_REVERSE_, MU_C1(MU_COUNT_ARG(__VA_ARGS__))) MU_LPAREN MACRO_TO_INVOKE, __VA_ARGS__)
+#else
+#define MU_FOR_EACH_2(MACRO_TO_INVOKE, ...) MU_C2(MU_FOR_EACH_2_, MU_C1(MU_COUNT_ARG(__VA_ARGS__))) ( MACRO_TO_INVOKE, __VA_ARGS__)
+#define MU_FOR_EACH_2_COUNTED(MACRO_TO_INVOKE, ...) MU_C2(MU_FOR_EACH_2_COUNTED_, MU_C1(MU_COUNT_ARG(__VA_ARGS__))) ( MACRO_TO_INVOKE,  __VA_ARGS__)
+#define MU_FOR_EACH_1_COUNTED(MACRO_TO_INVOKE, ...) MU_C2(MU_FOR_EACH_1_COUNTED_, MU_C1(MU_COUNT_ARG(__VA_ARGS__))) ( MACRO_TO_INVOKE,  __VA_ARGS__)
+#define MU_FOR_EACH_2_REVERSE(MACRO_TO_INVOKE, ...) MU_C2(MU_FOR_EACH_2_REVERSE_, MU_C1(MU_COUNT_ARG(__VA_ARGS__))) ( MACRO_TO_INVOKE, __VA_ARGS__)
+#endif
+
+#ifdef _MSC_VER
+#define MU_EXPAND_OR_MU_C1(x) x
+#else
+#define MU_EXPAND_OR_MU_C1(...) __VA_ARGS__
+#endif
+
+#define MU_EXPAND_ARGS(...) __VA_ARGS__
+#define MU_EXPAND_TWICE(...) MU_EXPAND_ARGS(__VA_ARGS__)
+
+#define MU_DO_0(MACRO, ...) \
+MACRO(0, __VA_ARGS__)
+
+#define MU_DO_1(MACRO, ...) \
+MACRO(1, __VA_ARGS__) \
+MU_DO_0(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_2(MACRO, ...) \
+MACRO(2, __VA_ARGS__) \
+MU_DO_1(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_3(MACRO, ...) \
+MACRO(3, __VA_ARGS__) \
+MU_DO_2(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_4(MACRO, ...) \
+MACRO(4, __VA_ARGS__) \
+MU_DO_3(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_5(MACRO, ...) \
+MACRO(5, __VA_ARGS__) \
+MU_DO_4(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_6(MACRO, ...) \
+MACRO(6, __VA_ARGS__) \
+MU_DO_5(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_7(MACRO, ...) \
+MACRO(7, __VA_ARGS__) \
+MU_DO_6(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_8(MACRO, ...) \
+MACRO(8, __VA_ARGS__) \
+MU_DO_7(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_9(MACRO, ...) \
+MACRO(9, __VA_ARGS__) \
+MU_DO_8(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_10(MACRO, ...) \
+MACRO(10, __VA_ARGS__) \
+MU_DO_9(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_11(MACRO, ...) \
+MACRO(11, __VA_ARGS__) \
+MU_DO_10(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_12(MACRO, ...) \
+MACRO(12, __VA_ARGS__) \
+MU_DO_11(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_13(MACRO, ...) \
+MACRO(13, __VA_ARGS__) \
+MU_DO_12(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_14(MACRO, ...) \
+MACRO(14, __VA_ARGS__) \
+MU_DO_13(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_15(MACRO, ...) \
+MACRO(15, __VA_ARGS__) \
+MU_DO_14(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_16(MACRO, ...) \
+MACRO(16, __VA_ARGS__) \
+MU_DO_15(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_17(MACRO, ...) \
+MACRO(17, __VA_ARGS__) \
+MU_DO_16(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_18(MACRO, ...) \
+MACRO(18, __VA_ARGS__) \
+MU_DO_17(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_19(MACRO, ...) \
+MACRO(19, __VA_ARGS__) \
+MU_DO_18(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_20(MACRO, ...) \
+MACRO(20, __VA_ARGS__) \
+MU_DO_19(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_21(MACRO, ...) \
+MACRO(21, __VA_ARGS__) \
+MU_DO_20(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_22(MACRO, ...) \
+MACRO(22, __VA_ARGS__) \
+MU_DO_21(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_23(MACRO, ...) \
+MACRO(23, __VA_ARGS__) \
+MU_DO_22(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_24(MACRO, ...) \
+MACRO(24, __VA_ARGS__) \
+MU_DO_23(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_25(MACRO, ...) \
+MACRO(25, __VA_ARGS__) \
+MU_DO_24(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_26(MACRO, ...) \
+MACRO(26, __VA_ARGS__) \
+MU_DO_25(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_27(MACRO, ...) \
+MACRO(27, __VA_ARGS__) \
+MU_DO_26(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_28(MACRO, ...) \
+MACRO(28, __VA_ARGS__) \
+MU_DO_27(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_29(MACRO, ...) \
+MACRO(29, __VA_ARGS__) \
+MU_DO_28(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_30(MACRO, ...) \
+MACRO(30, __VA_ARGS__) \
+MU_DO_29(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_31(MACRO, ...) \
+MACRO(31, __VA_ARGS__) \
+MU_DO_30(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_32(MACRO, ...) \
+MACRO(32, __VA_ARGS__) \
+MU_DO_31(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_33(MACRO, ...) \
+MACRO(33, __VA_ARGS__) \
+MU_DO_32(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_34(MACRO, ...) \
+MACRO(34, __VA_ARGS__) \
+MU_DO_33(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_35(MACRO, ...) \
+MACRO(35, __VA_ARGS__) \
+MU_DO_34(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_36(MACRO, ...) \
+MACRO(36, __VA_ARGS__) \
+MU_DO_35(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_37(MACRO, ...) \
+MACRO(37, __VA_ARGS__) \
+MU_DO_36(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_38(MACRO, ...) \
+MACRO(38, __VA_ARGS__) \
+MU_DO_37(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_39(MACRO, ...) \
+MACRO(39, __VA_ARGS__) \
+MU_DO_38(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_40(MACRO, ...) \
+MACRO(40, __VA_ARGS__) \
+MU_DO_39(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_41(MACRO, ...) \
+MACRO(41, __VA_ARGS__) \
+MU_DO_40(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_42(MACRO, ...) \
+MACRO(42, __VA_ARGS__) \
+MU_DO_41(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_43(MACRO, ...) \
+MACRO(43, __VA_ARGS__) \
+MU_DO_42(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_44(MACRO, ...) \
+MACRO(44, __VA_ARGS__) \
+MU_DO_43(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_45(MACRO, ...) \
+MACRO(45, __VA_ARGS__) \
+MU_DO_44(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_46(MACRO, ...) \
+MACRO(46, __VA_ARGS__) \
+MU_DO_45(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_47(MACRO, ...) \
+MACRO(47, __VA_ARGS__) \
+MU_DO_46(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_48(MACRO, ...) \
+MACRO(48, __VA_ARGS__) \
+MU_DO_47(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_49(MACRO, ...) \
+MACRO(49, __VA_ARGS__) \
+MU_DO_48(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_50(MACRO, ...) \
+MACRO(50, __VA_ARGS__) \
+MU_DO_49(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_51(MACRO, ...) \
+MACRO(51, __VA_ARGS__) \
+MU_DO_50(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_52(MACRO, ...) \
+MACRO(52, __VA_ARGS__) \
+MU_DO_51(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_53(MACRO, ...) \
+MACRO(53, __VA_ARGS__) \
+MU_DO_52(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_54(MACRO, ...) \
+MACRO(54, __VA_ARGS__) \
+MU_DO_53(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_55(MACRO, ...) \
+MACRO(55, __VA_ARGS__) \
+MU_DO_54(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_56(MACRO, ...) \
+MACRO(56, __VA_ARGS__) \
+MU_DO_55(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_57(MACRO, ...) \
+MACRO(57, __VA_ARGS__) \
+MU_DO_56(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_58(MACRO, ...) \
+MACRO(58, __VA_ARGS__) \
+MU_DO_57(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_59(MACRO, ...) \
+MACRO(59, __VA_ARGS__) \
+MU_DO_58(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_60(MACRO, ...) \
+MACRO(60, __VA_ARGS__) \
+MU_DO_59(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_61(MACRO, ...) \
+MACRO(61, __VA_ARGS__) \
+MU_DO_60(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_62(MACRO, ...) \
+MACRO(62, __VA_ARGS__) \
+MU_DO_61(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_63(MACRO, ...) \
+MACRO(63, __VA_ARGS__) \
+MU_DO_62(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_64(MACRO, ...) \
+MACRO(64, __VA_ARGS__) \
+MU_DO_63(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_65(MACRO, ...) \
+MACRO(65, __VA_ARGS__) \
+MU_DO_64(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_66(MACRO, ...) \
+MACRO(66, __VA_ARGS__) \
+MU_DO_65(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_67(MACRO, ...) \
+MACRO(67, __VA_ARGS__) \
+MU_DO_66(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_68(MACRO, ...) \
+MACRO(68, __VA_ARGS__) \
+MU_DO_67(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_69(MACRO, ...) \
+MACRO(69, __VA_ARGS__) \
+MU_DO_68(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_70(MACRO, ...) \
+MACRO(70, __VA_ARGS__) \
+MU_DO_69(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_71(MACRO, ...) \
+MACRO(71, __VA_ARGS__) \
+MU_DO_70(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_72(MACRO, ...) \
+MACRO(72, __VA_ARGS__) \
+MU_DO_71(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_73(MACRO, ...) \
+MACRO(73, __VA_ARGS__) \
+MU_DO_72(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_74(MACRO, ...) \
+MACRO(74, __VA_ARGS__) \
+MU_DO_73(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_75(MACRO, ...) \
+MACRO(75, __VA_ARGS__) \
+MU_DO_74(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_76(MACRO, ...) \
+MACRO(76, __VA_ARGS__) \
+MU_DO_75(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_77(MACRO, ...) \
+MACRO(77, __VA_ARGS__) \
+MU_DO_76(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_78(MACRO, ...) \
+MACRO(78, __VA_ARGS__) \
+MU_DO_77(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_79(MACRO, ...) \
+MACRO(79, __VA_ARGS__) \
+MU_DO_78(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_80(MACRO, ...) \
+MACRO(80, __VA_ARGS__) \
+MU_DO_79(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_81(MACRO, ...) \
+MACRO(81, __VA_ARGS__) \
+MU_DO_80(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_82(MACRO, ...) \
+MACRO(82, __VA_ARGS__) \
+MU_DO_81(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_83(MACRO, ...) \
+MACRO(83, __VA_ARGS__) \
+MU_DO_82(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_84(MACRO, ...) \
+MACRO(84, __VA_ARGS__) \
+MU_DO_83(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_85(MACRO, ...) \
+MACRO(85, __VA_ARGS__) \
+MU_DO_84(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_86(MACRO, ...) \
+MACRO(86, __VA_ARGS__) \
+MU_DO_85(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_87(MACRO, ...) \
+MACRO(87, __VA_ARGS__) \
+MU_DO_86(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_88(MACRO, ...) \
+MACRO(88, __VA_ARGS__) \
+MU_DO_87(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_89(MACRO, ...) \
+MACRO(89, __VA_ARGS__) \
+MU_DO_88(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_90(MACRO, ...) \
+MACRO(90, __VA_ARGS__) \
+MU_DO_89(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_91(MACRO, ...) \
+MACRO(91, __VA_ARGS__) \
+MU_DO_90(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_92(MACRO, ...) \
+MACRO(92, __VA_ARGS__) \
+MU_DO_91(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_93(MACRO, ...) \
+MACRO(93, __VA_ARGS__) \
+MU_DO_92(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_94(MACRO, ...) \
+MACRO(94, __VA_ARGS__) \
+MU_DO_93(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_95(MACRO, ...) \
+MACRO(95, __VA_ARGS__) \
+MU_DO_94(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_96(MACRO, ...) \
+MACRO(96, __VA_ARGS__) \
+MU_DO_95(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_97(MACRO, ...) \
+MACRO(97, __VA_ARGS__) \
+MU_DO_96(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_98(MACRO, ...) \
+MACRO(98, __VA_ARGS__) \
+MU_DO_97(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_99(MACRO, ...) \
+MACRO(99, __VA_ARGS__) \
+MU_DO_98(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_100(MACRO, ...) \
+MACRO(100, __VA_ARGS__) \
+MU_DO_99(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_101(MACRO, ...) \
+MACRO(101, __VA_ARGS__) \
+MU_DO_100(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_102(MACRO, ...) \
+MACRO(102, __VA_ARGS__) \
+MU_DO_101(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_103(MACRO, ...) \
+MACRO(103, __VA_ARGS__) \
+MU_DO_102(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_104(MACRO, ...) \
+MACRO(104, __VA_ARGS__) \
+MU_DO_103(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_105(MACRO, ...) \
+MACRO(105, __VA_ARGS__) \
+MU_DO_104(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_106(MACRO, ...) \
+MACRO(106, __VA_ARGS__) \
+MU_DO_105(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_107(MACRO, ...) \
+MACRO(107, __VA_ARGS__) \
+MU_DO_106(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_108(MACRO, ...) \
+MACRO(108, __VA_ARGS__) \
+MU_DO_107(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_109(MACRO, ...) \
+MACRO(109, __VA_ARGS__) \
+MU_DO_108(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_110(MACRO, ...) \
+MACRO(110, __VA_ARGS__) \
+MU_DO_109(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_111(MACRO, ...) \
+MACRO(111, __VA_ARGS__) \
+MU_DO_110(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_112(MACRO, ...) \
+MACRO(112, __VA_ARGS__) \
+MU_DO_111(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_113(MACRO, ...) \
+MACRO(113, __VA_ARGS__) \
+MU_DO_112(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_114(MACRO, ...) \
+MACRO(114, __VA_ARGS__) \
+MU_DO_113(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_115(MACRO, ...) \
+MACRO(115, __VA_ARGS__) \
+MU_DO_114(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_116(MACRO, ...) \
+MACRO(116, __VA_ARGS__) \
+MU_DO_115(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_117(MACRO, ...) \
+MACRO(117, __VA_ARGS__) \
+MU_DO_116(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_118(MACRO, ...) \
+MACRO(118, __VA_ARGS__) \
+MU_DO_117(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_119(MACRO, ...) \
+MACRO(119, __VA_ARGS__) \
+MU_DO_118(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_120(MACRO, ...) \
+MACRO(120, __VA_ARGS__) \
+MU_DO_119(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_121(MACRO, ...) \
+MACRO(121, __VA_ARGS__) \
+MU_DO_120(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_122(MACRO, ...) \
+MACRO(122, __VA_ARGS__) \
+MU_DO_121(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_123(MACRO, ...) \
+MACRO(123, __VA_ARGS__) \
+MU_DO_122(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_124(MACRO, ...) \
+MACRO(124, __VA_ARGS__) \
+MU_DO_123(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_125(MACRO, ...) \
+MACRO(125, __VA_ARGS__) \
+MU_DO_124(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_126(MACRO, ...) \
+MACRO(126, __VA_ARGS__) \
+MU_DO_125(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_127(MACRO, ...) \
+MACRO(127, __VA_ARGS__) \
+MU_DO_126(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_128(MACRO, ...) \
+MACRO(128, __VA_ARGS__) \
+MU_DO_127(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_129(MACRO, ...) \
+MACRO(129, __VA_ARGS__) \
+MU_DO_128(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_130(MACRO, ...) \
+MACRO(130, __VA_ARGS__) \
+MU_DO_129(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_131(MACRO, ...) \
+MACRO(131, __VA_ARGS__) \
+MU_DO_130(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_132(MACRO, ...) \
+MACRO(132, __VA_ARGS__) \
+MU_DO_131(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_133(MACRO, ...) \
+MACRO(133, __VA_ARGS__) \
+MU_DO_132(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_134(MACRO, ...) \
+MACRO(134, __VA_ARGS__) \
+MU_DO_133(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_135(MACRO, ...) \
+MACRO(135, __VA_ARGS__) \
+MU_DO_134(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_136(MACRO, ...) \
+MACRO(136, __VA_ARGS__) \
+MU_DO_135(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_137(MACRO, ...) \
+MACRO(137, __VA_ARGS__) \
+MU_DO_136(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_138(MACRO, ...) \
+MACRO(138, __VA_ARGS__) \
+MU_DO_137(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_139(MACRO, ...) \
+MACRO(139, __VA_ARGS__) \
+MU_DO_138(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_140(MACRO, ...) \
+MACRO(140, __VA_ARGS__) \
+MU_DO_139(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_141(MACRO, ...) \
+MACRO(141, __VA_ARGS__) \
+MU_DO_140(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_142(MACRO, ...) \
+MACRO(142, __VA_ARGS__) \
+MU_DO_141(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_143(MACRO, ...) \
+MACRO(143, __VA_ARGS__) \
+MU_DO_142(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_144(MACRO, ...) \
+MACRO(144, __VA_ARGS__) \
+MU_DO_143(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_145(MACRO, ...) \
+MACRO(145, __VA_ARGS__) \
+MU_DO_144(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_146(MACRO, ...) \
+MACRO(146, __VA_ARGS__) \
+MU_DO_145(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_147(MACRO, ...) \
+MACRO(147, __VA_ARGS__) \
+MU_DO_146(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_148(MACRO, ...) \
+MACRO(148, __VA_ARGS__) \
+MU_DO_147(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_149(MACRO, ...) \
+MACRO(149, __VA_ARGS__) \
+MU_DO_148(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_150(MACRO, ...) \
+MACRO(150, __VA_ARGS__) \
+MU_DO_149(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_151(MACRO, ...) \
+MACRO(151, __VA_ARGS__) \
+MU_DO_150(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_152(MACRO, ...) \
+MACRO(152, __VA_ARGS__) \
+MU_DO_151(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_153(MACRO, ...) \
+MACRO(153, __VA_ARGS__) \
+MU_DO_152(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_154(MACRO, ...) \
+MACRO(154, __VA_ARGS__) \
+MU_DO_153(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_155(MACRO, ...) \
+MACRO(155, __VA_ARGS__) \
+MU_DO_154(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_156(MACRO, ...) \
+MACRO(156, __VA_ARGS__) \
+MU_DO_155(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_157(MACRO, ...) \
+MACRO(157, __VA_ARGS__) \
+MU_DO_156(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_158(MACRO, ...) \
+MACRO(158, __VA_ARGS__) \
+MU_DO_157(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_159(MACRO, ...) \
+MACRO(159, __VA_ARGS__) \
+MU_DO_158(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_160(MACRO, ...) \
+MACRO(160, __VA_ARGS__) \
+MU_DO_159(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_161(MACRO, ...) \
+MACRO(161, __VA_ARGS__) \
+MU_DO_160(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_162(MACRO, ...) \
+MACRO(162, __VA_ARGS__) \
+MU_DO_161(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_163(MACRO, ...) \
+MACRO(163, __VA_ARGS__) \
+MU_DO_162(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_164(MACRO, ...) \
+MACRO(164, __VA_ARGS__) \
+MU_DO_163(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_165(MACRO, ...) \
+MACRO(165, __VA_ARGS__) \
+MU_DO_164(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_166(MACRO, ...) \
+MACRO(166, __VA_ARGS__) \
+MU_DO_165(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_167(MACRO, ...) \
+MACRO(167, __VA_ARGS__) \
+MU_DO_166(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_168(MACRO, ...) \
+MACRO(168, __VA_ARGS__) \
+MU_DO_167(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_169(MACRO, ...) \
+MACRO(169, __VA_ARGS__) \
+MU_DO_168(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_170(MACRO, ...) \
+MACRO(170, __VA_ARGS__) \
+MU_DO_169(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_171(MACRO, ...) \
+MACRO(171, __VA_ARGS__) \
+MU_DO_170(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_172(MACRO, ...) \
+MACRO(172, __VA_ARGS__) \
+MU_DO_171(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_173(MACRO, ...) \
+MACRO(173, __VA_ARGS__) \
+MU_DO_172(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_174(MACRO, ...) \
+MACRO(174, __VA_ARGS__) \
+MU_DO_173(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_175(MACRO, ...) \
+MACRO(175, __VA_ARGS__) \
+MU_DO_174(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_176(MACRO, ...) \
+MACRO(176, __VA_ARGS__) \
+MU_DO_175(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_177(MACRO, ...) \
+MACRO(177, __VA_ARGS__) \
+MU_DO_176(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_178(MACRO, ...) \
+MACRO(178, __VA_ARGS__) \
+MU_DO_177(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_179(MACRO, ...) \
+MACRO(179, __VA_ARGS__) \
+MU_DO_178(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_180(MACRO, ...) \
+MACRO(180, __VA_ARGS__) \
+MU_DO_179(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_181(MACRO, ...) \
+MACRO(181, __VA_ARGS__) \
+MU_DO_180(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_182(MACRO, ...) \
+MACRO(182, __VA_ARGS__) \
+MU_DO_181(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_183(MACRO, ...) \
+MACRO(183, __VA_ARGS__) \
+MU_DO_182(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_184(MACRO, ...) \
+MACRO(184, __VA_ARGS__) \
+MU_DO_183(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_185(MACRO, ...) \
+MACRO(185, __VA_ARGS__) \
+MU_DO_184(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_186(MACRO, ...) \
+MACRO(186, __VA_ARGS__) \
+MU_DO_185(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_187(MACRO, ...) \
+MACRO(187, __VA_ARGS__) \
+MU_DO_186(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_188(MACRO, ...) \
+MACRO(188, __VA_ARGS__) \
+MU_DO_187(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_189(MACRO, ...) \
+MACRO(189, __VA_ARGS__) \
+MU_DO_188(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_190(MACRO, ...) \
+MACRO(190, __VA_ARGS__) \
+MU_DO_189(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_191(MACRO, ...) \
+MACRO(191, __VA_ARGS__) \
+MU_DO_190(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_192(MACRO, ...) \
+MACRO(192, __VA_ARGS__) \
+MU_DO_191(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_193(MACRO, ...) \
+MACRO(193, __VA_ARGS__) \
+MU_DO_192(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_194(MACRO, ...) \
+MACRO(194, __VA_ARGS__) \
+MU_DO_193(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_195(MACRO, ...) \
+MACRO(195, __VA_ARGS__) \
+MU_DO_194(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_196(MACRO, ...) \
+MACRO(196, __VA_ARGS__) \
+MU_DO_195(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_197(MACRO, ...) \
+MACRO(197, __VA_ARGS__) \
+MU_DO_196(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_198(MACRO, ...) \
+MACRO(198, __VA_ARGS__) \
+MU_DO_197(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_199(MACRO, ...) \
+MACRO(199, __VA_ARGS__) \
+MU_DO_198(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_200(MACRO, ...) \
+MACRO(200, __VA_ARGS__) \
+MU_DO_199(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_201(MACRO, ...) \
+MACRO(201, __VA_ARGS__) \
+MU_DO_200(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_202(MACRO, ...) \
+MACRO(202, __VA_ARGS__) \
+MU_DO_201(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_203(MACRO, ...) \
+MACRO(203, __VA_ARGS__) \
+MU_DO_202(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_204(MACRO, ...) \
+MACRO(204, __VA_ARGS__) \
+MU_DO_203(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_205(MACRO, ...) \
+MACRO(205, __VA_ARGS__) \
+MU_DO_204(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_206(MACRO, ...) \
+MACRO(206, __VA_ARGS__) \
+MU_DO_205(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_207(MACRO, ...) \
+MACRO(207, __VA_ARGS__) \
+MU_DO_206(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_208(MACRO, ...) \
+MACRO(208, __VA_ARGS__) \
+MU_DO_207(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_209(MACRO, ...) \
+MACRO(209, __VA_ARGS__) \
+MU_DO_208(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_210(MACRO, ...) \
+MACRO(210, __VA_ARGS__) \
+MU_DO_209(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_211(MACRO, ...) \
+MACRO(211, __VA_ARGS__) \
+MU_DO_210(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_212(MACRO, ...) \
+MACRO(212, __VA_ARGS__) \
+MU_DO_211(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_213(MACRO, ...) \
+MACRO(213, __VA_ARGS__) \
+MU_DO_212(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_214(MACRO, ...) \
+MACRO(214, __VA_ARGS__) \
+MU_DO_213(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_215(MACRO, ...) \
+MACRO(215, __VA_ARGS__) \
+MU_DO_214(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_216(MACRO, ...) \
+MACRO(216, __VA_ARGS__) \
+MU_DO_215(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_217(MACRO, ...) \
+MACRO(217, __VA_ARGS__) \
+MU_DO_216(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_218(MACRO, ...) \
+MACRO(218, __VA_ARGS__) \
+MU_DO_217(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_219(MACRO, ...) \
+MACRO(219, __VA_ARGS__) \
+MU_DO_218(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_220(MACRO, ...) \
+MACRO(220, __VA_ARGS__) \
+MU_DO_219(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_221(MACRO, ...) \
+MACRO(221, __VA_ARGS__) \
+MU_DO_220(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_222(MACRO, ...) \
+MACRO(222, __VA_ARGS__) \
+MU_DO_221(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_223(MACRO, ...) \
+MACRO(223, __VA_ARGS__) \
+MU_DO_222(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_224(MACRO, ...) \
+MACRO(224, __VA_ARGS__) \
+MU_DO_223(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_225(MACRO, ...) \
+MACRO(225, __VA_ARGS__) \
+MU_DO_224(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_226(MACRO, ...) \
+MACRO(226, __VA_ARGS__) \
+MU_DO_225(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_227(MACRO, ...) \
+MACRO(227, __VA_ARGS__) \
+MU_DO_226(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_228(MACRO, ...) \
+MACRO(228, __VA_ARGS__) \
+MU_DO_227(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_229(MACRO, ...) \
+MACRO(229, __VA_ARGS__) \
+MU_DO_228(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_230(MACRO, ...) \
+MACRO(230, __VA_ARGS__) \
+MU_DO_229(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_231(MACRO, ...) \
+MACRO(231, __VA_ARGS__) \
+MU_DO_230(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_232(MACRO, ...) \
+MACRO(232, __VA_ARGS__) \
+MU_DO_231(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_233(MACRO, ...) \
+MACRO(233, __VA_ARGS__) \
+MU_DO_232(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_234(MACRO, ...) \
+MACRO(234, __VA_ARGS__) \
+MU_DO_233(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_235(MACRO, ...) \
+MACRO(235, __VA_ARGS__) \
+MU_DO_234(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_236(MACRO, ...) \
+MACRO(236, __VA_ARGS__) \
+MU_DO_235(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_237(MACRO, ...) \
+MACRO(237, __VA_ARGS__) \
+MU_DO_236(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_238(MACRO, ...) \
+MACRO(238, __VA_ARGS__) \
+MU_DO_237(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_239(MACRO, ...) \
+MACRO(239, __VA_ARGS__) \
+MU_DO_238(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_240(MACRO, ...) \
+MACRO(240, __VA_ARGS__) \
+MU_DO_239(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_241(MACRO, ...) \
+MACRO(241, __VA_ARGS__) \
+MU_DO_240(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_242(MACRO, ...) \
+MACRO(242, __VA_ARGS__) \
+MU_DO_241(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_243(MACRO, ...) \
+MACRO(243, __VA_ARGS__) \
+MU_DO_242(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_244(MACRO, ...) \
+MACRO(244, __VA_ARGS__) \
+MU_DO_243(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_245(MACRO, ...) \
+MACRO(245, __VA_ARGS__) \
+MU_DO_244(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_246(MACRO, ...) \
+MACRO(246, __VA_ARGS__) \
+MU_DO_245(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_247(MACRO, ...) \
+MACRO(247, __VA_ARGS__) \
+MU_DO_246(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_248(MACRO, ...) \
+MACRO(248, __VA_ARGS__) \
+MU_DO_247(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_249(MACRO, ...) \
+MACRO(249, __VA_ARGS__) \
+MU_DO_248(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_250(MACRO, ...) \
+MACRO(250, __VA_ARGS__) \
+MU_DO_249(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_251(MACRO, ...) \
+MACRO(251, __VA_ARGS__) \
+MU_DO_250(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_252(MACRO, ...) \
+MACRO(252, __VA_ARGS__) \
+MU_DO_251(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_253(MACRO, ...) \
+MACRO(253, __VA_ARGS__) \
+MU_DO_252(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_254(MACRO, ...) \
+MACRO(254, __VA_ARGS__) \
+MU_DO_253(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_255(MACRO, ...) \
+MACRO(255, __VA_ARGS__) \
+MU_DO_254(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_256(MACRO, ...) \
+MACRO(256, __VA_ARGS__) \
+MU_DO_255(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_257(MACRO, ...) \
+MACRO(257, __VA_ARGS__) \
+MU_DO_256(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_258(MACRO, ...) \
+MACRO(258, __VA_ARGS__) \
+MU_DO_257(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_259(MACRO, ...) \
+MACRO(259, __VA_ARGS__) \
+MU_DO_258(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_260(MACRO, ...) \
+MACRO(260, __VA_ARGS__) \
+MU_DO_259(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_261(MACRO, ...) \
+MACRO(261, __VA_ARGS__) \
+MU_DO_260(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_262(MACRO, ...) \
+MACRO(262, __VA_ARGS__) \
+MU_DO_261(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_263(MACRO, ...) \
+MACRO(263, __VA_ARGS__) \
+MU_DO_262(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_264(MACRO, ...) \
+MACRO(264, __VA_ARGS__) \
+MU_DO_263(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_265(MACRO, ...) \
+MACRO(265, __VA_ARGS__) \
+MU_DO_264(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_266(MACRO, ...) \
+MACRO(266, __VA_ARGS__) \
+MU_DO_265(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_267(MACRO, ...) \
+MACRO(267, __VA_ARGS__) \
+MU_DO_266(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_268(MACRO, ...) \
+MACRO(268, __VA_ARGS__) \
+MU_DO_267(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_269(MACRO, ...) \
+MACRO(269, __VA_ARGS__) \
+MU_DO_268(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_270(MACRO, ...) \
+MACRO(270, __VA_ARGS__) \
+MU_DO_269(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_271(MACRO, ...) \
+MACRO(271, __VA_ARGS__) \
+MU_DO_270(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_272(MACRO, ...) \
+MACRO(272, __VA_ARGS__) \
+MU_DO_271(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_273(MACRO, ...) \
+MACRO(273, __VA_ARGS__) \
+MU_DO_272(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_274(MACRO, ...) \
+MACRO(274, __VA_ARGS__) \
+MU_DO_273(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_275(MACRO, ...) \
+MACRO(275, __VA_ARGS__) \
+MU_DO_274(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_276(MACRO, ...) \
+MACRO(276, __VA_ARGS__) \
+MU_DO_275(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_277(MACRO, ...) \
+MACRO(277, __VA_ARGS__) \
+MU_DO_276(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_278(MACRO, ...) \
+MACRO(278, __VA_ARGS__) \
+MU_DO_277(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_279(MACRO, ...) \
+MACRO(279, __VA_ARGS__) \
+MU_DO_278(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_280(MACRO, ...) \
+MACRO(280, __VA_ARGS__) \
+MU_DO_279(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_281(MACRO, ...) \
+MACRO(281, __VA_ARGS__) \
+MU_DO_280(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_282(MACRO, ...) \
+MACRO(282, __VA_ARGS__) \
+MU_DO_281(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_283(MACRO, ...) \
+MACRO(283, __VA_ARGS__) \
+MU_DO_282(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_284(MACRO, ...) \
+MACRO(284, __VA_ARGS__) \
+MU_DO_283(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_285(MACRO, ...) \
+MACRO(285, __VA_ARGS__) \
+MU_DO_284(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_286(MACRO, ...) \
+MACRO(286, __VA_ARGS__) \
+MU_DO_285(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_287(MACRO, ...) \
+MACRO(287, __VA_ARGS__) \
+MU_DO_286(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_288(MACRO, ...) \
+MACRO(288, __VA_ARGS__) \
+MU_DO_287(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_289(MACRO, ...) \
+MACRO(289, __VA_ARGS__) \
+MU_DO_288(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_290(MACRO, ...) \
+MACRO(290, __VA_ARGS__) \
+MU_DO_289(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_291(MACRO, ...) \
+MACRO(291, __VA_ARGS__) \
+MU_DO_290(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_292(MACRO, ...) \
+MACRO(292, __VA_ARGS__) \
+MU_DO_291(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_293(MACRO, ...) \
+MACRO(293, __VA_ARGS__) \
+MU_DO_292(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_294(MACRO, ...) \
+MACRO(294, __VA_ARGS__) \
+MU_DO_293(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_295(MACRO, ...) \
+MACRO(295, __VA_ARGS__) \
+MU_DO_294(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_296(MACRO, ...) \
+MACRO(296, __VA_ARGS__) \
+MU_DO_295(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_297(MACRO, ...) \
+MACRO(297, __VA_ARGS__) \
+MU_DO_296(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_298(MACRO, ...) \
+MACRO(298, __VA_ARGS__) \
+MU_DO_297(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_299(MACRO, ...) \
+MACRO(299, __VA_ARGS__) \
+MU_DO_298(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_300(MACRO, ...) \
+MACRO(300, __VA_ARGS__) \
+MU_DO_299(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_301(MACRO, ...) \
+MACRO(301, __VA_ARGS__) \
+MU_DO_300(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_302(MACRO, ...) \
+MACRO(302, __VA_ARGS__) \
+MU_DO_301(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_303(MACRO, ...) \
+MACRO(303, __VA_ARGS__) \
+MU_DO_302(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_304(MACRO, ...) \
+MACRO(304, __VA_ARGS__) \
+MU_DO_303(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_305(MACRO, ...) \
+MACRO(305, __VA_ARGS__) \
+MU_DO_304(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_306(MACRO, ...) \
+MACRO(306, __VA_ARGS__) \
+MU_DO_305(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_307(MACRO, ...) \
+MACRO(307, __VA_ARGS__) \
+MU_DO_306(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_308(MACRO, ...) \
+MACRO(308, __VA_ARGS__) \
+MU_DO_307(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_309(MACRO, ...) \
+MACRO(309, __VA_ARGS__) \
+MU_DO_308(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_310(MACRO, ...) \
+MACRO(310, __VA_ARGS__) \
+MU_DO_309(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_311(MACRO, ...) \
+MACRO(311, __VA_ARGS__) \
+MU_DO_310(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_312(MACRO, ...) \
+MACRO(312, __VA_ARGS__) \
+MU_DO_311(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_313(MACRO, ...) \
+MACRO(313, __VA_ARGS__) \
+MU_DO_312(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_314(MACRO, ...) \
+MACRO(314, __VA_ARGS__) \
+MU_DO_313(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_315(MACRO, ...) \
+MACRO(315, __VA_ARGS__) \
+MU_DO_314(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_316(MACRO, ...) \
+MACRO(316, __VA_ARGS__) \
+MU_DO_315(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_317(MACRO, ...) \
+MACRO(317, __VA_ARGS__) \
+MU_DO_316(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_318(MACRO, ...) \
+MACRO(318, __VA_ARGS__) \
+MU_DO_317(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_319(MACRO, ...) \
+MACRO(319, __VA_ARGS__) \
+MU_DO_318(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_320(MACRO, ...) \
+MACRO(320, __VA_ARGS__) \
+MU_DO_319(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_321(MACRO, ...) \
+MACRO(321, __VA_ARGS__) \
+MU_DO_320(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_322(MACRO, ...) \
+MACRO(322, __VA_ARGS__) \
+MU_DO_321(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_323(MACRO, ...) \
+MACRO(323, __VA_ARGS__) \
+MU_DO_322(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_324(MACRO, ...) \
+MACRO(324, __VA_ARGS__) \
+MU_DO_323(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_325(MACRO, ...) \
+MACRO(325, __VA_ARGS__) \
+MU_DO_324(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_326(MACRO, ...) \
+MACRO(326, __VA_ARGS__) \
+MU_DO_325(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_327(MACRO, ...) \
+MACRO(327, __VA_ARGS__) \
+MU_DO_326(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_328(MACRO, ...) \
+MACRO(328, __VA_ARGS__) \
+MU_DO_327(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_329(MACRO, ...) \
+MACRO(329, __VA_ARGS__) \
+MU_DO_328(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_330(MACRO, ...) \
+MACRO(330, __VA_ARGS__) \
+MU_DO_329(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_331(MACRO, ...) \
+MACRO(331, __VA_ARGS__) \
+MU_DO_330(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_332(MACRO, ...) \
+MACRO(332, __VA_ARGS__) \
+MU_DO_331(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_333(MACRO, ...) \
+MACRO(333, __VA_ARGS__) \
+MU_DO_332(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_334(MACRO, ...) \
+MACRO(334, __VA_ARGS__) \
+MU_DO_333(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_335(MACRO, ...) \
+MACRO(335, __VA_ARGS__) \
+MU_DO_334(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_336(MACRO, ...) \
+MACRO(336, __VA_ARGS__) \
+MU_DO_335(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_337(MACRO, ...) \
+MACRO(337, __VA_ARGS__) \
+MU_DO_336(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_338(MACRO, ...) \
+MACRO(338, __VA_ARGS__) \
+MU_DO_337(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_339(MACRO, ...) \
+MACRO(339, __VA_ARGS__) \
+MU_DO_338(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_340(MACRO, ...) \
+MACRO(340, __VA_ARGS__) \
+MU_DO_339(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_341(MACRO, ...) \
+MACRO(341, __VA_ARGS__) \
+MU_DO_340(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_342(MACRO, ...) \
+MACRO(342, __VA_ARGS__) \
+MU_DO_341(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_343(MACRO, ...) \
+MACRO(343, __VA_ARGS__) \
+MU_DO_342(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_344(MACRO, ...) \
+MACRO(344, __VA_ARGS__) \
+MU_DO_343(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_345(MACRO, ...) \
+MACRO(345, __VA_ARGS__) \
+MU_DO_344(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_346(MACRO, ...) \
+MACRO(346, __VA_ARGS__) \
+MU_DO_345(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_347(MACRO, ...) \
+MACRO(347, __VA_ARGS__) \
+MU_DO_346(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_348(MACRO, ...) \
+MACRO(348, __VA_ARGS__) \
+MU_DO_347(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_349(MACRO, ...) \
+MACRO(349, __VA_ARGS__) \
+MU_DO_348(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_350(MACRO, ...) \
+MACRO(350, __VA_ARGS__) \
+MU_DO_349(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_351(MACRO, ...) \
+MACRO(351, __VA_ARGS__) \
+MU_DO_350(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_352(MACRO, ...) \
+MACRO(352, __VA_ARGS__) \
+MU_DO_351(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_353(MACRO, ...) \
+MACRO(353, __VA_ARGS__) \
+MU_DO_352(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_354(MACRO, ...) \
+MACRO(354, __VA_ARGS__) \
+MU_DO_353(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_355(MACRO, ...) \
+MACRO(355, __VA_ARGS__) \
+MU_DO_354(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_356(MACRO, ...) \
+MACRO(356, __VA_ARGS__) \
+MU_DO_355(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_357(MACRO, ...) \
+MACRO(357, __VA_ARGS__) \
+MU_DO_356(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_358(MACRO, ...) \
+MACRO(358, __VA_ARGS__) \
+MU_DO_357(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_359(MACRO, ...) \
+MACRO(359, __VA_ARGS__) \
+MU_DO_358(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_360(MACRO, ...) \
+MACRO(360, __VA_ARGS__) \
+MU_DO_359(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_361(MACRO, ...) \
+MACRO(361, __VA_ARGS__) \
+MU_DO_360(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_362(MACRO, ...) \
+MACRO(362, __VA_ARGS__) \
+MU_DO_361(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_363(MACRO, ...) \
+MACRO(363, __VA_ARGS__) \
+MU_DO_362(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_364(MACRO, ...) \
+MACRO(364, __VA_ARGS__) \
+MU_DO_363(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_365(MACRO, ...) \
+MACRO(365, __VA_ARGS__) \
+MU_DO_364(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_366(MACRO, ...) \
+MACRO(366, __VA_ARGS__) \
+MU_DO_365(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_367(MACRO, ...) \
+MACRO(367, __VA_ARGS__) \
+MU_DO_366(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_368(MACRO, ...) \
+MACRO(368, __VA_ARGS__) \
+MU_DO_367(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_369(MACRO, ...) \
+MACRO(369, __VA_ARGS__) \
+MU_DO_368(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_370(MACRO, ...) \
+MACRO(370, __VA_ARGS__) \
+MU_DO_369(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_371(MACRO, ...) \
+MACRO(371, __VA_ARGS__) \
+MU_DO_370(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_372(MACRO, ...) \
+MACRO(372, __VA_ARGS__) \
+MU_DO_371(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_373(MACRO, ...) \
+MACRO(373, __VA_ARGS__) \
+MU_DO_372(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_374(MACRO, ...) \
+MACRO(374, __VA_ARGS__) \
+MU_DO_373(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_375(MACRO, ...) \
+MACRO(375, __VA_ARGS__) \
+MU_DO_374(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_376(MACRO, ...) \
+MACRO(376, __VA_ARGS__) \
+MU_DO_375(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_377(MACRO, ...) \
+MACRO(377, __VA_ARGS__) \
+MU_DO_376(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_378(MACRO, ...) \
+MACRO(378, __VA_ARGS__) \
+MU_DO_377(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_379(MACRO, ...) \
+MACRO(379, __VA_ARGS__) \
+MU_DO_378(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_380(MACRO, ...) \
+MACRO(380, __VA_ARGS__) \
+MU_DO_379(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_381(MACRO, ...) \
+MACRO(381, __VA_ARGS__) \
+MU_DO_380(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_382(MACRO, ...) \
+MACRO(382, __VA_ARGS__) \
+MU_DO_381(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_383(MACRO, ...) \
+MACRO(383, __VA_ARGS__) \
+MU_DO_382(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_384(MACRO, ...) \
+MACRO(384, __VA_ARGS__) \
+MU_DO_383(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_385(MACRO, ...) \
+MACRO(385, __VA_ARGS__) \
+MU_DO_384(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_386(MACRO, ...) \
+MACRO(386, __VA_ARGS__) \
+MU_DO_385(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_387(MACRO, ...) \
+MACRO(387, __VA_ARGS__) \
+MU_DO_386(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_388(MACRO, ...) \
+MACRO(388, __VA_ARGS__) \
+MU_DO_387(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_389(MACRO, ...) \
+MACRO(389, __VA_ARGS__) \
+MU_DO_388(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_390(MACRO, ...) \
+MACRO(390, __VA_ARGS__) \
+MU_DO_389(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_391(MACRO, ...) \
+MACRO(391, __VA_ARGS__) \
+MU_DO_390(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_392(MACRO, ...) \
+MACRO(392, __VA_ARGS__) \
+MU_DO_391(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_393(MACRO, ...) \
+MACRO(393, __VA_ARGS__) \
+MU_DO_392(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_394(MACRO, ...) \
+MACRO(394, __VA_ARGS__) \
+MU_DO_393(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_395(MACRO, ...) \
+MACRO(395, __VA_ARGS__) \
+MU_DO_394(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_396(MACRO, ...) \
+MACRO(396, __VA_ARGS__) \
+MU_DO_395(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_397(MACRO, ...) \
+MACRO(397, __VA_ARGS__) \
+MU_DO_396(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_398(MACRO, ...) \
+MACRO(398, __VA_ARGS__) \
+MU_DO_397(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_399(MACRO, ...) \
+MACRO(399, __VA_ARGS__) \
+MU_DO_398(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_400(MACRO, ...) \
+MACRO(400, __VA_ARGS__) \
+MU_DO_399(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_401(MACRO, ...) \
+MACRO(401, __VA_ARGS__) \
+MU_DO_400(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_402(MACRO, ...) \
+MACRO(402, __VA_ARGS__) \
+MU_DO_401(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_403(MACRO, ...) \
+MACRO(403, __VA_ARGS__) \
+MU_DO_402(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_404(MACRO, ...) \
+MACRO(404, __VA_ARGS__) \
+MU_DO_403(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_405(MACRO, ...) \
+MACRO(405, __VA_ARGS__) \
+MU_DO_404(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_406(MACRO, ...) \
+MACRO(406, __VA_ARGS__) \
+MU_DO_405(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_407(MACRO, ...) \
+MACRO(407, __VA_ARGS__) \
+MU_DO_406(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_408(MACRO, ...) \
+MACRO(408, __VA_ARGS__) \
+MU_DO_407(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_409(MACRO, ...) \
+MACRO(409, __VA_ARGS__) \
+MU_DO_408(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_410(MACRO, ...) \
+MACRO(410, __VA_ARGS__) \
+MU_DO_409(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_411(MACRO, ...) \
+MACRO(411, __VA_ARGS__) \
+MU_DO_410(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_412(MACRO, ...) \
+MACRO(412, __VA_ARGS__) \
+MU_DO_411(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_413(MACRO, ...) \
+MACRO(413, __VA_ARGS__) \
+MU_DO_412(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_414(MACRO, ...) \
+MACRO(414, __VA_ARGS__) \
+MU_DO_413(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_415(MACRO, ...) \
+MACRO(415, __VA_ARGS__) \
+MU_DO_414(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_416(MACRO, ...) \
+MACRO(416, __VA_ARGS__) \
+MU_DO_415(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_417(MACRO, ...) \
+MACRO(417, __VA_ARGS__) \
+MU_DO_416(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_418(MACRO, ...) \
+MACRO(418, __VA_ARGS__) \
+MU_DO_417(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_419(MACRO, ...) \
+MACRO(419, __VA_ARGS__) \
+MU_DO_418(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_420(MACRO, ...) \
+MACRO(420, __VA_ARGS__) \
+MU_DO_419(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_421(MACRO, ...) \
+MACRO(421, __VA_ARGS__) \
+MU_DO_420(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_422(MACRO, ...) \
+MACRO(422, __VA_ARGS__) \
+MU_DO_421(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_423(MACRO, ...) \
+MACRO(423, __VA_ARGS__) \
+MU_DO_422(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_424(MACRO, ...) \
+MACRO(424, __VA_ARGS__) \
+MU_DO_423(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_425(MACRO, ...) \
+MACRO(425, __VA_ARGS__) \
+MU_DO_424(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_426(MACRO, ...) \
+MACRO(426, __VA_ARGS__) \
+MU_DO_425(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_427(MACRO, ...) \
+MACRO(427, __VA_ARGS__) \
+MU_DO_426(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_428(MACRO, ...) \
+MACRO(428, __VA_ARGS__) \
+MU_DO_427(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_429(MACRO, ...) \
+MACRO(429, __VA_ARGS__) \
+MU_DO_428(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_430(MACRO, ...) \
+MACRO(430, __VA_ARGS__) \
+MU_DO_429(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_431(MACRO, ...) \
+MACRO(431, __VA_ARGS__) \
+MU_DO_430(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_432(MACRO, ...) \
+MACRO(432, __VA_ARGS__) \
+MU_DO_431(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_433(MACRO, ...) \
+MACRO(433, __VA_ARGS__) \
+MU_DO_432(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_434(MACRO, ...) \
+MACRO(434, __VA_ARGS__) \
+MU_DO_433(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_435(MACRO, ...) \
+MACRO(435, __VA_ARGS__) \
+MU_DO_434(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_436(MACRO, ...) \
+MACRO(436, __VA_ARGS__) \
+MU_DO_435(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_437(MACRO, ...) \
+MACRO(437, __VA_ARGS__) \
+MU_DO_436(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_438(MACRO, ...) \
+MACRO(438, __VA_ARGS__) \
+MU_DO_437(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_439(MACRO, ...) \
+MACRO(439, __VA_ARGS__) \
+MU_DO_438(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_440(MACRO, ...) \
+MACRO(440, __VA_ARGS__) \
+MU_DO_439(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_441(MACRO, ...) \
+MACRO(441, __VA_ARGS__) \
+MU_DO_440(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_442(MACRO, ...) \
+MACRO(442, __VA_ARGS__) \
+MU_DO_441(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_443(MACRO, ...) \
+MACRO(443, __VA_ARGS__) \
+MU_DO_442(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_444(MACRO, ...) \
+MACRO(444, __VA_ARGS__) \
+MU_DO_443(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_445(MACRO, ...) \
+MACRO(445, __VA_ARGS__) \
+MU_DO_444(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_446(MACRO, ...) \
+MACRO(446, __VA_ARGS__) \
+MU_DO_445(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_447(MACRO, ...) \
+MACRO(447, __VA_ARGS__) \
+MU_DO_446(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_448(MACRO, ...) \
+MACRO(448, __VA_ARGS__) \
+MU_DO_447(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_449(MACRO, ...) \
+MACRO(449, __VA_ARGS__) \
+MU_DO_448(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_450(MACRO, ...) \
+MACRO(450, __VA_ARGS__) \
+MU_DO_449(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_451(MACRO, ...) \
+MACRO(451, __VA_ARGS__) \
+MU_DO_450(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_452(MACRO, ...) \
+MACRO(452, __VA_ARGS__) \
+MU_DO_451(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_453(MACRO, ...) \
+MACRO(453, __VA_ARGS__) \
+MU_DO_452(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_454(MACRO, ...) \
+MACRO(454, __VA_ARGS__) \
+MU_DO_453(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_455(MACRO, ...) \
+MACRO(455, __VA_ARGS__) \
+MU_DO_454(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_456(MACRO, ...) \
+MACRO(456, __VA_ARGS__) \
+MU_DO_455(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_457(MACRO, ...) \
+MACRO(457, __VA_ARGS__) \
+MU_DO_456(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_458(MACRO, ...) \
+MACRO(458, __VA_ARGS__) \
+MU_DO_457(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_459(MACRO, ...) \
+MACRO(459, __VA_ARGS__) \
+MU_DO_458(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_460(MACRO, ...) \
+MACRO(460, __VA_ARGS__) \
+MU_DO_459(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_461(MACRO, ...) \
+MACRO(461, __VA_ARGS__) \
+MU_DO_460(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_462(MACRO, ...) \
+MACRO(462, __VA_ARGS__) \
+MU_DO_461(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_463(MACRO, ...) \
+MACRO(463, __VA_ARGS__) \
+MU_DO_462(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_464(MACRO, ...) \
+MACRO(464, __VA_ARGS__) \
+MU_DO_463(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_465(MACRO, ...) \
+MACRO(465, __VA_ARGS__) \
+MU_DO_464(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_466(MACRO, ...) \
+MACRO(466, __VA_ARGS__) \
+MU_DO_465(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_467(MACRO, ...) \
+MACRO(467, __VA_ARGS__) \
+MU_DO_466(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_468(MACRO, ...) \
+MACRO(468, __VA_ARGS__) \
+MU_DO_467(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_469(MACRO, ...) \
+MACRO(469, __VA_ARGS__) \
+MU_DO_468(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_470(MACRO, ...) \
+MACRO(470, __VA_ARGS__) \
+MU_DO_469(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_471(MACRO, ...) \
+MACRO(471, __VA_ARGS__) \
+MU_DO_470(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_472(MACRO, ...) \
+MACRO(472, __VA_ARGS__) \
+MU_DO_471(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_473(MACRO, ...) \
+MACRO(473, __VA_ARGS__) \
+MU_DO_472(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_474(MACRO, ...) \
+MACRO(474, __VA_ARGS__) \
+MU_DO_473(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_475(MACRO, ...) \
+MACRO(475, __VA_ARGS__) \
+MU_DO_474(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_476(MACRO, ...) \
+MACRO(476, __VA_ARGS__) \
+MU_DO_475(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_477(MACRO, ...) \
+MACRO(477, __VA_ARGS__) \
+MU_DO_476(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_478(MACRO, ...) \
+MACRO(478, __VA_ARGS__) \
+MU_DO_477(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_479(MACRO, ...) \
+MACRO(479, __VA_ARGS__) \
+MU_DO_478(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_480(MACRO, ...) \
+MACRO(480, __VA_ARGS__) \
+MU_DO_479(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_481(MACRO, ...) \
+MACRO(481, __VA_ARGS__) \
+MU_DO_480(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_482(MACRO, ...) \
+MACRO(482, __VA_ARGS__) \
+MU_DO_481(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_483(MACRO, ...) \
+MACRO(483, __VA_ARGS__) \
+MU_DO_482(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_484(MACRO, ...) \
+MACRO(484, __VA_ARGS__) \
+MU_DO_483(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_485(MACRO, ...) \
+MACRO(485, __VA_ARGS__) \
+MU_DO_484(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_486(MACRO, ...) \
+MACRO(486, __VA_ARGS__) \
+MU_DO_485(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_487(MACRO, ...) \
+MACRO(487, __VA_ARGS__) \
+MU_DO_486(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_488(MACRO, ...) \
+MACRO(488, __VA_ARGS__) \
+MU_DO_487(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_489(MACRO, ...) \
+MACRO(489, __VA_ARGS__) \
+MU_DO_488(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_490(MACRO, ...) \
+MACRO(490, __VA_ARGS__) \
+MU_DO_489(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_491(MACRO, ...) \
+MACRO(491, __VA_ARGS__) \
+MU_DO_490(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_492(MACRO, ...) \
+MACRO(492, __VA_ARGS__) \
+MU_DO_491(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_493(MACRO, ...) \
+MACRO(493, __VA_ARGS__) \
+MU_DO_492(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_494(MACRO, ...) \
+MACRO(494, __VA_ARGS__) \
+MU_DO_493(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_495(MACRO, ...) \
+MACRO(495, __VA_ARGS__) \
+MU_DO_494(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_496(MACRO, ...) \
+MACRO(496, __VA_ARGS__) \
+MU_DO_495(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_497(MACRO, ...) \
+MACRO(497, __VA_ARGS__) \
+MU_DO_496(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_498(MACRO, ...) \
+MACRO(498, __VA_ARGS__) \
+MU_DO_497(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_499(MACRO, ...) \
+MACRO(499, __VA_ARGS__) \
+MU_DO_498(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_500(MACRO, ...) \
+MACRO(500, __VA_ARGS__) \
+MU_DO_499(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_501(MACRO, ...) \
+MACRO(501, __VA_ARGS__) \
+MU_DO_500(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_502(MACRO, ...) \
+MACRO(502, __VA_ARGS__) \
+MU_DO_501(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_503(MACRO, ...) \
+MACRO(503, __VA_ARGS__) \
+MU_DO_502(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_504(MACRO, ...) \
+MACRO(504, __VA_ARGS__) \
+MU_DO_503(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_505(MACRO, ...) \
+MACRO(505, __VA_ARGS__) \
+MU_DO_504(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_506(MACRO, ...) \
+MACRO(506, __VA_ARGS__) \
+MU_DO_505(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_507(MACRO, ...) \
+MACRO(507, __VA_ARGS__) \
+MU_DO_506(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_508(MACRO, ...) \
+MACRO(508, __VA_ARGS__) \
+MU_DO_507(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_509(MACRO, ...) \
+MACRO(509, __VA_ARGS__) \
+MU_DO_508(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_510(MACRO, ...) \
+MACRO(510, __VA_ARGS__) \
+MU_DO_509(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_511(MACRO, ...) \
+MACRO(511, __VA_ARGS__) \
+MU_DO_510(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_512(MACRO, ...) \
+MACRO(512, __VA_ARGS__) \
+MU_DO_511(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_513(MACRO, ...) \
+MACRO(513, __VA_ARGS__) \
+MU_DO_512(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_514(MACRO, ...) \
+MACRO(514, __VA_ARGS__) \
+MU_DO_513(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_515(MACRO, ...) \
+MACRO(515, __VA_ARGS__) \
+MU_DO_514(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_516(MACRO, ...) \
+MACRO(516, __VA_ARGS__) \
+MU_DO_515(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_517(MACRO, ...) \
+MACRO(517, __VA_ARGS__) \
+MU_DO_516(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_518(MACRO, ...) \
+MACRO(518, __VA_ARGS__) \
+MU_DO_517(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_519(MACRO, ...) \
+MACRO(519, __VA_ARGS__) \
+MU_DO_518(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_520(MACRO, ...) \
+MACRO(520, __VA_ARGS__) \
+MU_DO_519(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_521(MACRO, ...) \
+MACRO(521, __VA_ARGS__) \
+MU_DO_520(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_522(MACRO, ...) \
+MACRO(522, __VA_ARGS__) \
+MU_DO_521(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_523(MACRO, ...) \
+MACRO(523, __VA_ARGS__) \
+MU_DO_522(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_524(MACRO, ...) \
+MACRO(524, __VA_ARGS__) \
+MU_DO_523(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_525(MACRO, ...) \
+MACRO(525, __VA_ARGS__) \
+MU_DO_524(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_526(MACRO, ...) \
+MACRO(526, __VA_ARGS__) \
+MU_DO_525(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_527(MACRO, ...) \
+MACRO(527, __VA_ARGS__) \
+MU_DO_526(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_528(MACRO, ...) \
+MACRO(528, __VA_ARGS__) \
+MU_DO_527(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_529(MACRO, ...) \
+MACRO(529, __VA_ARGS__) \
+MU_DO_528(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_530(MACRO, ...) \
+MACRO(530, __VA_ARGS__) \
+MU_DO_529(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_531(MACRO, ...) \
+MACRO(531, __VA_ARGS__) \
+MU_DO_530(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_532(MACRO, ...) \
+MACRO(532, __VA_ARGS__) \
+MU_DO_531(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_533(MACRO, ...) \
+MACRO(533, __VA_ARGS__) \
+MU_DO_532(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_534(MACRO, ...) \
+MACRO(534, __VA_ARGS__) \
+MU_DO_533(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_535(MACRO, ...) \
+MACRO(535, __VA_ARGS__) \
+MU_DO_534(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_536(MACRO, ...) \
+MACRO(536, __VA_ARGS__) \
+MU_DO_535(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_537(MACRO, ...) \
+MACRO(537, __VA_ARGS__) \
+MU_DO_536(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_538(MACRO, ...) \
+MACRO(538, __VA_ARGS__) \
+MU_DO_537(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_539(MACRO, ...) \
+MACRO(539, __VA_ARGS__) \
+MU_DO_538(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_540(MACRO, ...) \
+MACRO(540, __VA_ARGS__) \
+MU_DO_539(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_541(MACRO, ...) \
+MACRO(541, __VA_ARGS__) \
+MU_DO_540(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_542(MACRO, ...) \
+MACRO(542, __VA_ARGS__) \
+MU_DO_541(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_543(MACRO, ...) \
+MACRO(543, __VA_ARGS__) \
+MU_DO_542(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_544(MACRO, ...) \
+MACRO(544, __VA_ARGS__) \
+MU_DO_543(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_545(MACRO, ...) \
+MACRO(545, __VA_ARGS__) \
+MU_DO_544(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_546(MACRO, ...) \
+MACRO(546, __VA_ARGS__) \
+MU_DO_545(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_547(MACRO, ...) \
+MACRO(547, __VA_ARGS__) \
+MU_DO_546(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_548(MACRO, ...) \
+MACRO(548, __VA_ARGS__) \
+MU_DO_547(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_549(MACRO, ...) \
+MACRO(549, __VA_ARGS__) \
+MU_DO_548(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_550(MACRO, ...) \
+MACRO(550, __VA_ARGS__) \
+MU_DO_549(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_551(MACRO, ...) \
+MACRO(551, __VA_ARGS__) \
+MU_DO_550(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_552(MACRO, ...) \
+MACRO(552, __VA_ARGS__) \
+MU_DO_551(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_553(MACRO, ...) \
+MACRO(553, __VA_ARGS__) \
+MU_DO_552(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_554(MACRO, ...) \
+MACRO(554, __VA_ARGS__) \
+MU_DO_553(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_555(MACRO, ...) \
+MACRO(555, __VA_ARGS__) \
+MU_DO_554(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_556(MACRO, ...) \
+MACRO(556, __VA_ARGS__) \
+MU_DO_555(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_557(MACRO, ...) \
+MACRO(557, __VA_ARGS__) \
+MU_DO_556(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_558(MACRO, ...) \
+MACRO(558, __VA_ARGS__) \
+MU_DO_557(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_559(MACRO, ...) \
+MACRO(559, __VA_ARGS__) \
+MU_DO_558(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_560(MACRO, ...) \
+MACRO(560, __VA_ARGS__) \
+MU_DO_559(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_561(MACRO, ...) \
+MACRO(561, __VA_ARGS__) \
+MU_DO_560(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_562(MACRO, ...) \
+MACRO(562, __VA_ARGS__) \
+MU_DO_561(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_563(MACRO, ...) \
+MACRO(563, __VA_ARGS__) \
+MU_DO_562(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_564(MACRO, ...) \
+MACRO(564, __VA_ARGS__) \
+MU_DO_563(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_565(MACRO, ...) \
+MACRO(565, __VA_ARGS__) \
+MU_DO_564(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_566(MACRO, ...) \
+MACRO(566, __VA_ARGS__) \
+MU_DO_565(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_567(MACRO, ...) \
+MACRO(567, __VA_ARGS__) \
+MU_DO_566(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_568(MACRO, ...) \
+MACRO(568, __VA_ARGS__) \
+MU_DO_567(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_569(MACRO, ...) \
+MACRO(569, __VA_ARGS__) \
+MU_DO_568(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_570(MACRO, ...) \
+MACRO(570, __VA_ARGS__) \
+MU_DO_569(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_571(MACRO, ...) \
+MACRO(571, __VA_ARGS__) \
+MU_DO_570(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_572(MACRO, ...) \
+MACRO(572, __VA_ARGS__) \
+MU_DO_571(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_573(MACRO, ...) \
+MACRO(573, __VA_ARGS__) \
+MU_DO_572(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_574(MACRO, ...) \
+MACRO(574, __VA_ARGS__) \
+MU_DO_573(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_575(MACRO, ...) \
+MACRO(575, __VA_ARGS__) \
+MU_DO_574(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_576(MACRO, ...) \
+MACRO(576, __VA_ARGS__) \
+MU_DO_575(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_577(MACRO, ...) \
+MACRO(577, __VA_ARGS__) \
+MU_DO_576(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_578(MACRO, ...) \
+MACRO(578, __VA_ARGS__) \
+MU_DO_577(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_579(MACRO, ...) \
+MACRO(579, __VA_ARGS__) \
+MU_DO_578(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_580(MACRO, ...) \
+MACRO(580, __VA_ARGS__) \
+MU_DO_579(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_581(MACRO, ...) \
+MACRO(581, __VA_ARGS__) \
+MU_DO_580(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_582(MACRO, ...) \
+MACRO(582, __VA_ARGS__) \
+MU_DO_581(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_583(MACRO, ...) \
+MACRO(583, __VA_ARGS__) \
+MU_DO_582(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_584(MACRO, ...) \
+MACRO(584, __VA_ARGS__) \
+MU_DO_583(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_585(MACRO, ...) \
+MACRO(585, __VA_ARGS__) \
+MU_DO_584(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_586(MACRO, ...) \
+MACRO(586, __VA_ARGS__) \
+MU_DO_585(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_587(MACRO, ...) \
+MACRO(587, __VA_ARGS__) \
+MU_DO_586(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_588(MACRO, ...) \
+MACRO(588, __VA_ARGS__) \
+MU_DO_587(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_589(MACRO, ...) \
+MACRO(589, __VA_ARGS__) \
+MU_DO_588(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_590(MACRO, ...) \
+MACRO(590, __VA_ARGS__) \
+MU_DO_589(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_591(MACRO, ...) \
+MACRO(591, __VA_ARGS__) \
+MU_DO_590(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_592(MACRO, ...) \
+MACRO(592, __VA_ARGS__) \
+MU_DO_591(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_593(MACRO, ...) \
+MACRO(593, __VA_ARGS__) \
+MU_DO_592(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_594(MACRO, ...) \
+MACRO(594, __VA_ARGS__) \
+MU_DO_593(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_595(MACRO, ...) \
+MACRO(595, __VA_ARGS__) \
+MU_DO_594(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_596(MACRO, ...) \
+MACRO(596, __VA_ARGS__) \
+MU_DO_595(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_597(MACRO, ...) \
+MACRO(597, __VA_ARGS__) \
+MU_DO_596(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_598(MACRO, ...) \
+MACRO(598, __VA_ARGS__) \
+MU_DO_597(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_599(MACRO, ...) \
+MACRO(599, __VA_ARGS__) \
+MU_DO_598(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_600(MACRO, ...) \
+MACRO(600, __VA_ARGS__) \
+MU_DO_599(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_601(MACRO, ...) \
+MACRO(601, __VA_ARGS__) \
+MU_DO_600(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_602(MACRO, ...) \
+MACRO(602, __VA_ARGS__) \
+MU_DO_601(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_603(MACRO, ...) \
+MACRO(603, __VA_ARGS__) \
+MU_DO_602(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_604(MACRO, ...) \
+MACRO(604, __VA_ARGS__) \
+MU_DO_603(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_605(MACRO, ...) \
+MACRO(605, __VA_ARGS__) \
+MU_DO_604(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_606(MACRO, ...) \
+MACRO(606, __VA_ARGS__) \
+MU_DO_605(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_607(MACRO, ...) \
+MACRO(607, __VA_ARGS__) \
+MU_DO_606(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_608(MACRO, ...) \
+MACRO(608, __VA_ARGS__) \
+MU_DO_607(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_609(MACRO, ...) \
+MACRO(609, __VA_ARGS__) \
+MU_DO_608(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_610(MACRO, ...) \
+MACRO(610, __VA_ARGS__) \
+MU_DO_609(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_611(MACRO, ...) \
+MACRO(611, __VA_ARGS__) \
+MU_DO_610(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_612(MACRO, ...) \
+MACRO(612, __VA_ARGS__) \
+MU_DO_611(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_613(MACRO, ...) \
+MACRO(613, __VA_ARGS__) \
+MU_DO_612(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_614(MACRO, ...) \
+MACRO(614, __VA_ARGS__) \
+MU_DO_613(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_615(MACRO, ...) \
+MACRO(615, __VA_ARGS__) \
+MU_DO_614(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_616(MACRO, ...) \
+MACRO(616, __VA_ARGS__) \
+MU_DO_615(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_617(MACRO, ...) \
+MACRO(617, __VA_ARGS__) \
+MU_DO_616(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_618(MACRO, ...) \
+MACRO(618, __VA_ARGS__) \
+MU_DO_617(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_619(MACRO, ...) \
+MACRO(619, __VA_ARGS__) \
+MU_DO_618(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_620(MACRO, ...) \
+MACRO(620, __VA_ARGS__) \
+MU_DO_619(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_621(MACRO, ...) \
+MACRO(621, __VA_ARGS__) \
+MU_DO_620(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_622(MACRO, ...) \
+MACRO(622, __VA_ARGS__) \
+MU_DO_621(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_623(MACRO, ...) \
+MACRO(623, __VA_ARGS__) \
+MU_DO_622(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_624(MACRO, ...) \
+MACRO(624, __VA_ARGS__) \
+MU_DO_623(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_625(MACRO, ...) \
+MACRO(625, __VA_ARGS__) \
+MU_DO_624(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_626(MACRO, ...) \
+MACRO(626, __VA_ARGS__) \
+MU_DO_625(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_627(MACRO, ...) \
+MACRO(627, __VA_ARGS__) \
+MU_DO_626(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_628(MACRO, ...) \
+MACRO(628, __VA_ARGS__) \
+MU_DO_627(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_629(MACRO, ...) \
+MACRO(629, __VA_ARGS__) \
+MU_DO_628(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_630(MACRO, ...) \
+MACRO(630, __VA_ARGS__) \
+MU_DO_629(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_631(MACRO, ...) \
+MACRO(631, __VA_ARGS__) \
+MU_DO_630(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_632(MACRO, ...) \
+MACRO(632, __VA_ARGS__) \
+MU_DO_631(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_633(MACRO, ...) \
+MACRO(633, __VA_ARGS__) \
+MU_DO_632(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_634(MACRO, ...) \
+MACRO(634, __VA_ARGS__) \
+MU_DO_633(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_635(MACRO, ...) \
+MACRO(635, __VA_ARGS__) \
+MU_DO_634(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_636(MACRO, ...) \
+MACRO(636, __VA_ARGS__) \
+MU_DO_635(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_637(MACRO, ...) \
+MACRO(637, __VA_ARGS__) \
+MU_DO_636(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_638(MACRO, ...) \
+MACRO(638, __VA_ARGS__) \
+MU_DO_637(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_639(MACRO, ...) \
+MACRO(639, __VA_ARGS__) \
+MU_DO_638(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_640(MACRO, ...) \
+MACRO(640, __VA_ARGS__) \
+MU_DO_639(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_641(MACRO, ...) \
+MACRO(641, __VA_ARGS__) \
+MU_DO_640(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_642(MACRO, ...) \
+MACRO(642, __VA_ARGS__) \
+MU_DO_641(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_643(MACRO, ...) \
+MACRO(643, __VA_ARGS__) \
+MU_DO_642(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_644(MACRO, ...) \
+MACRO(644, __VA_ARGS__) \
+MU_DO_643(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_645(MACRO, ...) \
+MACRO(645, __VA_ARGS__) \
+MU_DO_644(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_646(MACRO, ...) \
+MACRO(646, __VA_ARGS__) \
+MU_DO_645(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_647(MACRO, ...) \
+MACRO(647, __VA_ARGS__) \
+MU_DO_646(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_648(MACRO, ...) \
+MACRO(648, __VA_ARGS__) \
+MU_DO_647(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_649(MACRO, ...) \
+MACRO(649, __VA_ARGS__) \
+MU_DO_648(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_650(MACRO, ...) \
+MACRO(650, __VA_ARGS__) \
+MU_DO_649(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_651(MACRO, ...) \
+MACRO(651, __VA_ARGS__) \
+MU_DO_650(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_652(MACRO, ...) \
+MACRO(652, __VA_ARGS__) \
+MU_DO_651(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_653(MACRO, ...) \
+MACRO(653, __VA_ARGS__) \
+MU_DO_652(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_654(MACRO, ...) \
+MACRO(654, __VA_ARGS__) \
+MU_DO_653(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_655(MACRO, ...) \
+MACRO(655, __VA_ARGS__) \
+MU_DO_654(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_656(MACRO, ...) \
+MACRO(656, __VA_ARGS__) \
+MU_DO_655(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_657(MACRO, ...) \
+MACRO(657, __VA_ARGS__) \
+MU_DO_656(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_658(MACRO, ...) \
+MACRO(658, __VA_ARGS__) \
+MU_DO_657(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_659(MACRO, ...) \
+MACRO(659, __VA_ARGS__) \
+MU_DO_658(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_660(MACRO, ...) \
+MACRO(660, __VA_ARGS__) \
+MU_DO_659(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_661(MACRO, ...) \
+MACRO(661, __VA_ARGS__) \
+MU_DO_660(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_662(MACRO, ...) \
+MACRO(662, __VA_ARGS__) \
+MU_DO_661(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_663(MACRO, ...) \
+MACRO(663, __VA_ARGS__) \
+MU_DO_662(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_664(MACRO, ...) \
+MACRO(664, __VA_ARGS__) \
+MU_DO_663(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_665(MACRO, ...) \
+MACRO(665, __VA_ARGS__) \
+MU_DO_664(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_666(MACRO, ...) \
+MACRO(666, __VA_ARGS__) \
+MU_DO_665(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_667(MACRO, ...) \
+MACRO(667, __VA_ARGS__) \
+MU_DO_666(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_668(MACRO, ...) \
+MACRO(668, __VA_ARGS__) \
+MU_DO_667(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_669(MACRO, ...) \
+MACRO(669, __VA_ARGS__) \
+MU_DO_668(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_670(MACRO, ...) \
+MACRO(670, __VA_ARGS__) \
+MU_DO_669(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_671(MACRO, ...) \
+MACRO(671, __VA_ARGS__) \
+MU_DO_670(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_672(MACRO, ...) \
+MACRO(672, __VA_ARGS__) \
+MU_DO_671(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_673(MACRO, ...) \
+MACRO(673, __VA_ARGS__) \
+MU_DO_672(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_674(MACRO, ...) \
+MACRO(674, __VA_ARGS__) \
+MU_DO_673(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_675(MACRO, ...) \
+MACRO(675, __VA_ARGS__) \
+MU_DO_674(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_676(MACRO, ...) \
+MACRO(676, __VA_ARGS__) \
+MU_DO_675(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_677(MACRO, ...) \
+MACRO(677, __VA_ARGS__) \
+MU_DO_676(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_678(MACRO, ...) \
+MACRO(678, __VA_ARGS__) \
+MU_DO_677(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_679(MACRO, ...) \
+MACRO(679, __VA_ARGS__) \
+MU_DO_678(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_680(MACRO, ...) \
+MACRO(680, __VA_ARGS__) \
+MU_DO_679(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_681(MACRO, ...) \
+MACRO(681, __VA_ARGS__) \
+MU_DO_680(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_682(MACRO, ...) \
+MACRO(682, __VA_ARGS__) \
+MU_DO_681(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_683(MACRO, ...) \
+MACRO(683, __VA_ARGS__) \
+MU_DO_682(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_684(MACRO, ...) \
+MACRO(684, __VA_ARGS__) \
+MU_DO_683(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_685(MACRO, ...) \
+MACRO(685, __VA_ARGS__) \
+MU_DO_684(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_686(MACRO, ...) \
+MACRO(686, __VA_ARGS__) \
+MU_DO_685(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_687(MACRO, ...) \
+MACRO(687, __VA_ARGS__) \
+MU_DO_686(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_688(MACRO, ...) \
+MACRO(688, __VA_ARGS__) \
+MU_DO_687(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_689(MACRO, ...) \
+MACRO(689, __VA_ARGS__) \
+MU_DO_688(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_690(MACRO, ...) \
+MACRO(690, __VA_ARGS__) \
+MU_DO_689(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_691(MACRO, ...) \
+MACRO(691, __VA_ARGS__) \
+MU_DO_690(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_692(MACRO, ...) \
+MACRO(692, __VA_ARGS__) \
+MU_DO_691(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_693(MACRO, ...) \
+MACRO(693, __VA_ARGS__) \
+MU_DO_692(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_694(MACRO, ...) \
+MACRO(694, __VA_ARGS__) \
+MU_DO_693(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_695(MACRO, ...) \
+MACRO(695, __VA_ARGS__) \
+MU_DO_694(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_696(MACRO, ...) \
+MACRO(696, __VA_ARGS__) \
+MU_DO_695(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_697(MACRO, ...) \
+MACRO(697, __VA_ARGS__) \
+MU_DO_696(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_698(MACRO, ...) \
+MACRO(698, __VA_ARGS__) \
+MU_DO_697(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_699(MACRO, ...) \
+MACRO(699, __VA_ARGS__) \
+MU_DO_698(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_700(MACRO, ...) \
+MACRO(700, __VA_ARGS__) \
+MU_DO_699(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_701(MACRO, ...) \
+MACRO(701, __VA_ARGS__) \
+MU_DO_700(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_702(MACRO, ...) \
+MACRO(702, __VA_ARGS__) \
+MU_DO_701(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_703(MACRO, ...) \
+MACRO(703, __VA_ARGS__) \
+MU_DO_702(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_704(MACRO, ...) \
+MACRO(704, __VA_ARGS__) \
+MU_DO_703(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_705(MACRO, ...) \
+MACRO(705, __VA_ARGS__) \
+MU_DO_704(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_706(MACRO, ...) \
+MACRO(706, __VA_ARGS__) \
+MU_DO_705(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_707(MACRO, ...) \
+MACRO(707, __VA_ARGS__) \
+MU_DO_706(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_708(MACRO, ...) \
+MACRO(708, __VA_ARGS__) \
+MU_DO_707(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_709(MACRO, ...) \
+MACRO(709, __VA_ARGS__) \
+MU_DO_708(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_710(MACRO, ...) \
+MACRO(710, __VA_ARGS__) \
+MU_DO_709(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_711(MACRO, ...) \
+MACRO(711, __VA_ARGS__) \
+MU_DO_710(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_712(MACRO, ...) \
+MACRO(712, __VA_ARGS__) \
+MU_DO_711(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_713(MACRO, ...) \
+MACRO(713, __VA_ARGS__) \
+MU_DO_712(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_714(MACRO, ...) \
+MACRO(714, __VA_ARGS__) \
+MU_DO_713(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_715(MACRO, ...) \
+MACRO(715, __VA_ARGS__) \
+MU_DO_714(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_716(MACRO, ...) \
+MACRO(716, __VA_ARGS__) \
+MU_DO_715(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_717(MACRO, ...) \
+MACRO(717, __VA_ARGS__) \
+MU_DO_716(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_718(MACRO, ...) \
+MACRO(718, __VA_ARGS__) \
+MU_DO_717(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_719(MACRO, ...) \
+MACRO(719, __VA_ARGS__) \
+MU_DO_718(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_720(MACRO, ...) \
+MACRO(720, __VA_ARGS__) \
+MU_DO_719(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_721(MACRO, ...) \
+MACRO(721, __VA_ARGS__) \
+MU_DO_720(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_722(MACRO, ...) \
+MACRO(722, __VA_ARGS__) \
+MU_DO_721(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_723(MACRO, ...) \
+MACRO(723, __VA_ARGS__) \
+MU_DO_722(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_724(MACRO, ...) \
+MACRO(724, __VA_ARGS__) \
+MU_DO_723(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_725(MACRO, ...) \
+MACRO(725, __VA_ARGS__) \
+MU_DO_724(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_726(MACRO, ...) \
+MACRO(726, __VA_ARGS__) \
+MU_DO_725(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_727(MACRO, ...) \
+MACRO(727, __VA_ARGS__) \
+MU_DO_726(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_728(MACRO, ...) \
+MACRO(728, __VA_ARGS__) \
+MU_DO_727(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_729(MACRO, ...) \
+MACRO(729, __VA_ARGS__) \
+MU_DO_728(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_730(MACRO, ...) \
+MACRO(730, __VA_ARGS__) \
+MU_DO_729(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_731(MACRO, ...) \
+MACRO(731, __VA_ARGS__) \
+MU_DO_730(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_732(MACRO, ...) \
+MACRO(732, __VA_ARGS__) \
+MU_DO_731(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_733(MACRO, ...) \
+MACRO(733, __VA_ARGS__) \
+MU_DO_732(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_734(MACRO, ...) \
+MACRO(734, __VA_ARGS__) \
+MU_DO_733(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_735(MACRO, ...) \
+MACRO(735, __VA_ARGS__) \
+MU_DO_734(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_736(MACRO, ...) \
+MACRO(736, __VA_ARGS__) \
+MU_DO_735(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_737(MACRO, ...) \
+MACRO(737, __VA_ARGS__) \
+MU_DO_736(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_738(MACRO, ...) \
+MACRO(738, __VA_ARGS__) \
+MU_DO_737(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_739(MACRO, ...) \
+MACRO(739, __VA_ARGS__) \
+MU_DO_738(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_740(MACRO, ...) \
+MACRO(740, __VA_ARGS__) \
+MU_DO_739(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_741(MACRO, ...) \
+MACRO(741, __VA_ARGS__) \
+MU_DO_740(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_742(MACRO, ...) \
+MACRO(742, __VA_ARGS__) \
+MU_DO_741(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_743(MACRO, ...) \
+MACRO(743, __VA_ARGS__) \
+MU_DO_742(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_744(MACRO, ...) \
+MACRO(744, __VA_ARGS__) \
+MU_DO_743(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_745(MACRO, ...) \
+MACRO(745, __VA_ARGS__) \
+MU_DO_744(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_746(MACRO, ...) \
+MACRO(746, __VA_ARGS__) \
+MU_DO_745(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_747(MACRO, ...) \
+MACRO(747, __VA_ARGS__) \
+MU_DO_746(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_748(MACRO, ...) \
+MACRO(748, __VA_ARGS__) \
+MU_DO_747(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_749(MACRO, ...) \
+MACRO(749, __VA_ARGS__) \
+MU_DO_748(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_750(MACRO, ...) \
+MACRO(750, __VA_ARGS__) \
+MU_DO_749(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_751(MACRO, ...) \
+MACRO(751, __VA_ARGS__) \
+MU_DO_750(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_752(MACRO, ...) \
+MACRO(752, __VA_ARGS__) \
+MU_DO_751(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_753(MACRO, ...) \
+MACRO(753, __VA_ARGS__) \
+MU_DO_752(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_754(MACRO, ...) \
+MACRO(754, __VA_ARGS__) \
+MU_DO_753(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_755(MACRO, ...) \
+MACRO(755, __VA_ARGS__) \
+MU_DO_754(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_756(MACRO, ...) \
+MACRO(756, __VA_ARGS__) \
+MU_DO_755(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_757(MACRO, ...) \
+MACRO(757, __VA_ARGS__) \
+MU_DO_756(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_758(MACRO, ...) \
+MACRO(758, __VA_ARGS__) \
+MU_DO_757(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_759(MACRO, ...) \
+MACRO(759, __VA_ARGS__) \
+MU_DO_758(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_760(MACRO, ...) \
+MACRO(760, __VA_ARGS__) \
+MU_DO_759(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_761(MACRO, ...) \
+MACRO(761, __VA_ARGS__) \
+MU_DO_760(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_762(MACRO, ...) \
+MACRO(762, __VA_ARGS__) \
+MU_DO_761(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_763(MACRO, ...) \
+MACRO(763, __VA_ARGS__) \
+MU_DO_762(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_764(MACRO, ...) \
+MACRO(764, __VA_ARGS__) \
+MU_DO_763(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_765(MACRO, ...) \
+MACRO(765, __VA_ARGS__) \
+MU_DO_764(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_766(MACRO, ...) \
+MACRO(766, __VA_ARGS__) \
+MU_DO_765(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_767(MACRO, ...) \
+MACRO(767, __VA_ARGS__) \
+MU_DO_766(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_768(MACRO, ...) \
+MACRO(768, __VA_ARGS__) \
+MU_DO_767(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_769(MACRO, ...) \
+MACRO(769, __VA_ARGS__) \
+MU_DO_768(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_770(MACRO, ...) \
+MACRO(770, __VA_ARGS__) \
+MU_DO_769(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_771(MACRO, ...) \
+MACRO(771, __VA_ARGS__) \
+MU_DO_770(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_772(MACRO, ...) \
+MACRO(772, __VA_ARGS__) \
+MU_DO_771(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_773(MACRO, ...) \
+MACRO(773, __VA_ARGS__) \
+MU_DO_772(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_774(MACRO, ...) \
+MACRO(774, __VA_ARGS__) \
+MU_DO_773(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_775(MACRO, ...) \
+MACRO(775, __VA_ARGS__) \
+MU_DO_774(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_776(MACRO, ...) \
+MACRO(776, __VA_ARGS__) \
+MU_DO_775(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_777(MACRO, ...) \
+MACRO(777, __VA_ARGS__) \
+MU_DO_776(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_778(MACRO, ...) \
+MACRO(778, __VA_ARGS__) \
+MU_DO_777(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_779(MACRO, ...) \
+MACRO(779, __VA_ARGS__) \
+MU_DO_778(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_780(MACRO, ...) \
+MACRO(780, __VA_ARGS__) \
+MU_DO_779(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_781(MACRO, ...) \
+MACRO(781, __VA_ARGS__) \
+MU_DO_780(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_782(MACRO, ...) \
+MACRO(782, __VA_ARGS__) \
+MU_DO_781(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_783(MACRO, ...) \
+MACRO(783, __VA_ARGS__) \
+MU_DO_782(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_784(MACRO, ...) \
+MACRO(784, __VA_ARGS__) \
+MU_DO_783(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_785(MACRO, ...) \
+MACRO(785, __VA_ARGS__) \
+MU_DO_784(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_786(MACRO, ...) \
+MACRO(786, __VA_ARGS__) \
+MU_DO_785(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_787(MACRO, ...) \
+MACRO(787, __VA_ARGS__) \
+MU_DO_786(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_788(MACRO, ...) \
+MACRO(788, __VA_ARGS__) \
+MU_DO_787(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_789(MACRO, ...) \
+MACRO(789, __VA_ARGS__) \
+MU_DO_788(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_790(MACRO, ...) \
+MACRO(790, __VA_ARGS__) \
+MU_DO_789(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_791(MACRO, ...) \
+MACRO(791, __VA_ARGS__) \
+MU_DO_790(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_792(MACRO, ...) \
+MACRO(792, __VA_ARGS__) \
+MU_DO_791(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_793(MACRO, ...) \
+MACRO(793, __VA_ARGS__) \
+MU_DO_792(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_794(MACRO, ...) \
+MACRO(794, __VA_ARGS__) \
+MU_DO_793(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_795(MACRO, ...) \
+MACRO(795, __VA_ARGS__) \
+MU_DO_794(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_796(MACRO, ...) \
+MACRO(796, __VA_ARGS__) \
+MU_DO_795(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_797(MACRO, ...) \
+MACRO(797, __VA_ARGS__) \
+MU_DO_796(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_798(MACRO, ...) \
+MACRO(798, __VA_ARGS__) \
+MU_DO_797(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_799(MACRO, ...) \
+MACRO(799, __VA_ARGS__) \
+MU_DO_798(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_800(MACRO, ...) \
+MACRO(800, __VA_ARGS__) \
+MU_DO_799(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_801(MACRO, ...) \
+MACRO(801, __VA_ARGS__) \
+MU_DO_800(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_802(MACRO, ...) \
+MACRO(802, __VA_ARGS__) \
+MU_DO_801(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_803(MACRO, ...) \
+MACRO(803, __VA_ARGS__) \
+MU_DO_802(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_804(MACRO, ...) \
+MACRO(804, __VA_ARGS__) \
+MU_DO_803(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_805(MACRO, ...) \
+MACRO(805, __VA_ARGS__) \
+MU_DO_804(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_806(MACRO, ...) \
+MACRO(806, __VA_ARGS__) \
+MU_DO_805(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_807(MACRO, ...) \
+MACRO(807, __VA_ARGS__) \
+MU_DO_806(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_808(MACRO, ...) \
+MACRO(808, __VA_ARGS__) \
+MU_DO_807(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_809(MACRO, ...) \
+MACRO(809, __VA_ARGS__) \
+MU_DO_808(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_810(MACRO, ...) \
+MACRO(810, __VA_ARGS__) \
+MU_DO_809(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_811(MACRO, ...) \
+MACRO(811, __VA_ARGS__) \
+MU_DO_810(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_812(MACRO, ...) \
+MACRO(812, __VA_ARGS__) \
+MU_DO_811(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_813(MACRO, ...) \
+MACRO(813, __VA_ARGS__) \
+MU_DO_812(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_814(MACRO, ...) \
+MACRO(814, __VA_ARGS__) \
+MU_DO_813(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_815(MACRO, ...) \
+MACRO(815, __VA_ARGS__) \
+MU_DO_814(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_816(MACRO, ...) \
+MACRO(816, __VA_ARGS__) \
+MU_DO_815(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_817(MACRO, ...) \
+MACRO(817, __VA_ARGS__) \
+MU_DO_816(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_818(MACRO, ...) \
+MACRO(818, __VA_ARGS__) \
+MU_DO_817(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_819(MACRO, ...) \
+MACRO(819, __VA_ARGS__) \
+MU_DO_818(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_820(MACRO, ...) \
+MACRO(820, __VA_ARGS__) \
+MU_DO_819(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_821(MACRO, ...) \
+MACRO(821, __VA_ARGS__) \
+MU_DO_820(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_822(MACRO, ...) \
+MACRO(822, __VA_ARGS__) \
+MU_DO_821(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_823(MACRO, ...) \
+MACRO(823, __VA_ARGS__) \
+MU_DO_822(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_824(MACRO, ...) \
+MACRO(824, __VA_ARGS__) \
+MU_DO_823(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_825(MACRO, ...) \
+MACRO(825, __VA_ARGS__) \
+MU_DO_824(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_826(MACRO, ...) \
+MACRO(826, __VA_ARGS__) \
+MU_DO_825(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_827(MACRO, ...) \
+MACRO(827, __VA_ARGS__) \
+MU_DO_826(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_828(MACRO, ...) \
+MACRO(828, __VA_ARGS__) \
+MU_DO_827(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_829(MACRO, ...) \
+MACRO(829, __VA_ARGS__) \
+MU_DO_828(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_830(MACRO, ...) \
+MACRO(830, __VA_ARGS__) \
+MU_DO_829(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_831(MACRO, ...) \
+MACRO(831, __VA_ARGS__) \
+MU_DO_830(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_832(MACRO, ...) \
+MACRO(832, __VA_ARGS__) \
+MU_DO_831(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_833(MACRO, ...) \
+MACRO(833, __VA_ARGS__) \
+MU_DO_832(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_834(MACRO, ...) \
+MACRO(834, __VA_ARGS__) \
+MU_DO_833(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_835(MACRO, ...) \
+MACRO(835, __VA_ARGS__) \
+MU_DO_834(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_836(MACRO, ...) \
+MACRO(836, __VA_ARGS__) \
+MU_DO_835(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_837(MACRO, ...) \
+MACRO(837, __VA_ARGS__) \
+MU_DO_836(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_838(MACRO, ...) \
+MACRO(838, __VA_ARGS__) \
+MU_DO_837(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_839(MACRO, ...) \
+MACRO(839, __VA_ARGS__) \
+MU_DO_838(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_840(MACRO, ...) \
+MACRO(840, __VA_ARGS__) \
+MU_DO_839(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_841(MACRO, ...) \
+MACRO(841, __VA_ARGS__) \
+MU_DO_840(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_842(MACRO, ...) \
+MACRO(842, __VA_ARGS__) \
+MU_DO_841(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_843(MACRO, ...) \
+MACRO(843, __VA_ARGS__) \
+MU_DO_842(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_844(MACRO, ...) \
+MACRO(844, __VA_ARGS__) \
+MU_DO_843(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_845(MACRO, ...) \
+MACRO(845, __VA_ARGS__) \
+MU_DO_844(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_846(MACRO, ...) \
+MACRO(846, __VA_ARGS__) \
+MU_DO_845(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_847(MACRO, ...) \
+MACRO(847, __VA_ARGS__) \
+MU_DO_846(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_848(MACRO, ...) \
+MACRO(848, __VA_ARGS__) \
+MU_DO_847(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_849(MACRO, ...) \
+MACRO(849, __VA_ARGS__) \
+MU_DO_848(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_850(MACRO, ...) \
+MACRO(850, __VA_ARGS__) \
+MU_DO_849(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_851(MACRO, ...) \
+MACRO(851, __VA_ARGS__) \
+MU_DO_850(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_852(MACRO, ...) \
+MACRO(852, __VA_ARGS__) \
+MU_DO_851(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_853(MACRO, ...) \
+MACRO(853, __VA_ARGS__) \
+MU_DO_852(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_854(MACRO, ...) \
+MACRO(854, __VA_ARGS__) \
+MU_DO_853(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_855(MACRO, ...) \
+MACRO(855, __VA_ARGS__) \
+MU_DO_854(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_856(MACRO, ...) \
+MACRO(856, __VA_ARGS__) \
+MU_DO_855(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_857(MACRO, ...) \
+MACRO(857, __VA_ARGS__) \
+MU_DO_856(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_858(MACRO, ...) \
+MACRO(858, __VA_ARGS__) \
+MU_DO_857(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_859(MACRO, ...) \
+MACRO(859, __VA_ARGS__) \
+MU_DO_858(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_860(MACRO, ...) \
+MACRO(860, __VA_ARGS__) \
+MU_DO_859(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_861(MACRO, ...) \
+MACRO(861, __VA_ARGS__) \
+MU_DO_860(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_862(MACRO, ...) \
+MACRO(862, __VA_ARGS__) \
+MU_DO_861(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_863(MACRO, ...) \
+MACRO(863, __VA_ARGS__) \
+MU_DO_862(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_864(MACRO, ...) \
+MACRO(864, __VA_ARGS__) \
+MU_DO_863(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_865(MACRO, ...) \
+MACRO(865, __VA_ARGS__) \
+MU_DO_864(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_866(MACRO, ...) \
+MACRO(866, __VA_ARGS__) \
+MU_DO_865(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_867(MACRO, ...) \
+MACRO(867, __VA_ARGS__) \
+MU_DO_866(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_868(MACRO, ...) \
+MACRO(868, __VA_ARGS__) \
+MU_DO_867(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_869(MACRO, ...) \
+MACRO(869, __VA_ARGS__) \
+MU_DO_868(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_870(MACRO, ...) \
+MACRO(870, __VA_ARGS__) \
+MU_DO_869(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_871(MACRO, ...) \
+MACRO(871, __VA_ARGS__) \
+MU_DO_870(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_872(MACRO, ...) \
+MACRO(872, __VA_ARGS__) \
+MU_DO_871(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_873(MACRO, ...) \
+MACRO(873, __VA_ARGS__) \
+MU_DO_872(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_874(MACRO, ...) \
+MACRO(874, __VA_ARGS__) \
+MU_DO_873(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_875(MACRO, ...) \
+MACRO(875, __VA_ARGS__) \
+MU_DO_874(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_876(MACRO, ...) \
+MACRO(876, __VA_ARGS__) \
+MU_DO_875(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_877(MACRO, ...) \
+MACRO(877, __VA_ARGS__) \
+MU_DO_876(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_878(MACRO, ...) \
+MACRO(878, __VA_ARGS__) \
+MU_DO_877(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_879(MACRO, ...) \
+MACRO(879, __VA_ARGS__) \
+MU_DO_878(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_880(MACRO, ...) \
+MACRO(880, __VA_ARGS__) \
+MU_DO_879(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_881(MACRO, ...) \
+MACRO(881, __VA_ARGS__) \
+MU_DO_880(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_882(MACRO, ...) \
+MACRO(882, __VA_ARGS__) \
+MU_DO_881(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_883(MACRO, ...) \
+MACRO(883, __VA_ARGS__) \
+MU_DO_882(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_884(MACRO, ...) \
+MACRO(884, __VA_ARGS__) \
+MU_DO_883(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_885(MACRO, ...) \
+MACRO(885, __VA_ARGS__) \
+MU_DO_884(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_886(MACRO, ...) \
+MACRO(886, __VA_ARGS__) \
+MU_DO_885(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_887(MACRO, ...) \
+MACRO(887, __VA_ARGS__) \
+MU_DO_886(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_888(MACRO, ...) \
+MACRO(888, __VA_ARGS__) \
+MU_DO_887(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_889(MACRO, ...) \
+MACRO(889, __VA_ARGS__) \
+MU_DO_888(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_890(MACRO, ...) \
+MACRO(890, __VA_ARGS__) \
+MU_DO_889(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_891(MACRO, ...) \
+MACRO(891, __VA_ARGS__) \
+MU_DO_890(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_892(MACRO, ...) \
+MACRO(892, __VA_ARGS__) \
+MU_DO_891(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_893(MACRO, ...) \
+MACRO(893, __VA_ARGS__) \
+MU_DO_892(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_894(MACRO, ...) \
+MACRO(894, __VA_ARGS__) \
+MU_DO_893(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_895(MACRO, ...) \
+MACRO(895, __VA_ARGS__) \
+MU_DO_894(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_896(MACRO, ...) \
+MACRO(896, __VA_ARGS__) \
+MU_DO_895(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_897(MACRO, ...) \
+MACRO(897, __VA_ARGS__) \
+MU_DO_896(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_898(MACRO, ...) \
+MACRO(898, __VA_ARGS__) \
+MU_DO_897(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_899(MACRO, ...) \
+MACRO(899, __VA_ARGS__) \
+MU_DO_898(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_900(MACRO, ...) \
+MACRO(900, __VA_ARGS__) \
+MU_DO_899(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_901(MACRO, ...) \
+MACRO(901, __VA_ARGS__) \
+MU_DO_900(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_902(MACRO, ...) \
+MACRO(902, __VA_ARGS__) \
+MU_DO_901(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_903(MACRO, ...) \
+MACRO(903, __VA_ARGS__) \
+MU_DO_902(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_904(MACRO, ...) \
+MACRO(904, __VA_ARGS__) \
+MU_DO_903(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_905(MACRO, ...) \
+MACRO(905, __VA_ARGS__) \
+MU_DO_904(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_906(MACRO, ...) \
+MACRO(906, __VA_ARGS__) \
+MU_DO_905(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_907(MACRO, ...) \
+MACRO(907, __VA_ARGS__) \
+MU_DO_906(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_908(MACRO, ...) \
+MACRO(908, __VA_ARGS__) \
+MU_DO_907(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_909(MACRO, ...) \
+MACRO(909, __VA_ARGS__) \
+MU_DO_908(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_910(MACRO, ...) \
+MACRO(910, __VA_ARGS__) \
+MU_DO_909(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_911(MACRO, ...) \
+MACRO(911, __VA_ARGS__) \
+MU_DO_910(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_912(MACRO, ...) \
+MACRO(912, __VA_ARGS__) \
+MU_DO_911(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_913(MACRO, ...) \
+MACRO(913, __VA_ARGS__) \
+MU_DO_912(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_914(MACRO, ...) \
+MACRO(914, __VA_ARGS__) \
+MU_DO_913(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_915(MACRO, ...) \
+MACRO(915, __VA_ARGS__) \
+MU_DO_914(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_916(MACRO, ...) \
+MACRO(916, __VA_ARGS__) \
+MU_DO_915(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_917(MACRO, ...) \
+MACRO(917, __VA_ARGS__) \
+MU_DO_916(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_918(MACRO, ...) \
+MACRO(918, __VA_ARGS__) \
+MU_DO_917(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_919(MACRO, ...) \
+MACRO(919, __VA_ARGS__) \
+MU_DO_918(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_920(MACRO, ...) \
+MACRO(920, __VA_ARGS__) \
+MU_DO_919(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_921(MACRO, ...) \
+MACRO(921, __VA_ARGS__) \
+MU_DO_920(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_922(MACRO, ...) \
+MACRO(922, __VA_ARGS__) \
+MU_DO_921(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_923(MACRO, ...) \
+MACRO(923, __VA_ARGS__) \
+MU_DO_922(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_924(MACRO, ...) \
+MACRO(924, __VA_ARGS__) \
+MU_DO_923(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_925(MACRO, ...) \
+MACRO(925, __VA_ARGS__) \
+MU_DO_924(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_926(MACRO, ...) \
+MACRO(926, __VA_ARGS__) \
+MU_DO_925(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_927(MACRO, ...) \
+MACRO(927, __VA_ARGS__) \
+MU_DO_926(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_928(MACRO, ...) \
+MACRO(928, __VA_ARGS__) \
+MU_DO_927(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_929(MACRO, ...) \
+MACRO(929, __VA_ARGS__) \
+MU_DO_928(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_930(MACRO, ...) \
+MACRO(930, __VA_ARGS__) \
+MU_DO_929(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_931(MACRO, ...) \
+MACRO(931, __VA_ARGS__) \
+MU_DO_930(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_932(MACRO, ...) \
+MACRO(932, __VA_ARGS__) \
+MU_DO_931(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_933(MACRO, ...) \
+MACRO(933, __VA_ARGS__) \
+MU_DO_932(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_934(MACRO, ...) \
+MACRO(934, __VA_ARGS__) \
+MU_DO_933(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_935(MACRO, ...) \
+MACRO(935, __VA_ARGS__) \
+MU_DO_934(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_936(MACRO, ...) \
+MACRO(936, __VA_ARGS__) \
+MU_DO_935(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_937(MACRO, ...) \
+MACRO(937, __VA_ARGS__) \
+MU_DO_936(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_938(MACRO, ...) \
+MACRO(938, __VA_ARGS__) \
+MU_DO_937(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_939(MACRO, ...) \
+MACRO(939, __VA_ARGS__) \
+MU_DO_938(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_940(MACRO, ...) \
+MACRO(940, __VA_ARGS__) \
+MU_DO_939(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_941(MACRO, ...) \
+MACRO(941, __VA_ARGS__) \
+MU_DO_940(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_942(MACRO, ...) \
+MACRO(942, __VA_ARGS__) \
+MU_DO_941(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_943(MACRO, ...) \
+MACRO(943, __VA_ARGS__) \
+MU_DO_942(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_944(MACRO, ...) \
+MACRO(944, __VA_ARGS__) \
+MU_DO_943(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_945(MACRO, ...) \
+MACRO(945, __VA_ARGS__) \
+MU_DO_944(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_946(MACRO, ...) \
+MACRO(946, __VA_ARGS__) \
+MU_DO_945(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_947(MACRO, ...) \
+MACRO(947, __VA_ARGS__) \
+MU_DO_946(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_948(MACRO, ...) \
+MACRO(948, __VA_ARGS__) \
+MU_DO_947(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_949(MACRO, ...) \
+MACRO(949, __VA_ARGS__) \
+MU_DO_948(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_950(MACRO, ...) \
+MACRO(950, __VA_ARGS__) \
+MU_DO_949(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_951(MACRO, ...) \
+MACRO(951, __VA_ARGS__) \
+MU_DO_950(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_952(MACRO, ...) \
+MACRO(952, __VA_ARGS__) \
+MU_DO_951(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_953(MACRO, ...) \
+MACRO(953, __VA_ARGS__) \
+MU_DO_952(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_954(MACRO, ...) \
+MACRO(954, __VA_ARGS__) \
+MU_DO_953(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_955(MACRO, ...) \
+MACRO(955, __VA_ARGS__) \
+MU_DO_954(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_956(MACRO, ...) \
+MACRO(956, __VA_ARGS__) \
+MU_DO_955(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_957(MACRO, ...) \
+MACRO(957, __VA_ARGS__) \
+MU_DO_956(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_958(MACRO, ...) \
+MACRO(958, __VA_ARGS__) \
+MU_DO_957(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_959(MACRO, ...) \
+MACRO(959, __VA_ARGS__) \
+MU_DO_958(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_960(MACRO, ...) \
+MACRO(960, __VA_ARGS__) \
+MU_DO_959(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_961(MACRO, ...) \
+MACRO(961, __VA_ARGS__) \
+MU_DO_960(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_962(MACRO, ...) \
+MACRO(962, __VA_ARGS__) \
+MU_DO_961(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_963(MACRO, ...) \
+MACRO(963, __VA_ARGS__) \
+MU_DO_962(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_964(MACRO, ...) \
+MACRO(964, __VA_ARGS__) \
+MU_DO_963(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_965(MACRO, ...) \
+MACRO(965, __VA_ARGS__) \
+MU_DO_964(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_966(MACRO, ...) \
+MACRO(966, __VA_ARGS__) \
+MU_DO_965(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_967(MACRO, ...) \
+MACRO(967, __VA_ARGS__) \
+MU_DO_966(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_968(MACRO, ...) \
+MACRO(968, __VA_ARGS__) \
+MU_DO_967(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_969(MACRO, ...) \
+MACRO(969, __VA_ARGS__) \
+MU_DO_968(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_970(MACRO, ...) \
+MACRO(970, __VA_ARGS__) \
+MU_DO_969(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_971(MACRO, ...) \
+MACRO(971, __VA_ARGS__) \
+MU_DO_970(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_972(MACRO, ...) \
+MACRO(972, __VA_ARGS__) \
+MU_DO_971(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_973(MACRO, ...) \
+MACRO(973, __VA_ARGS__) \
+MU_DO_972(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_974(MACRO, ...) \
+MACRO(974, __VA_ARGS__) \
+MU_DO_973(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_975(MACRO, ...) \
+MACRO(975, __VA_ARGS__) \
+MU_DO_974(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_976(MACRO, ...) \
+MACRO(976, __VA_ARGS__) \
+MU_DO_975(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_977(MACRO, ...) \
+MACRO(977, __VA_ARGS__) \
+MU_DO_976(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_978(MACRO, ...) \
+MACRO(978, __VA_ARGS__) \
+MU_DO_977(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_979(MACRO, ...) \
+MACRO(979, __VA_ARGS__) \
+MU_DO_978(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_980(MACRO, ...) \
+MACRO(980, __VA_ARGS__) \
+MU_DO_979(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_981(MACRO, ...) \
+MACRO(981, __VA_ARGS__) \
+MU_DO_980(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_982(MACRO, ...) \
+MACRO(982, __VA_ARGS__) \
+MU_DO_981(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_983(MACRO, ...) \
+MACRO(983, __VA_ARGS__) \
+MU_DO_982(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_984(MACRO, ...) \
+MACRO(984, __VA_ARGS__) \
+MU_DO_983(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_985(MACRO, ...) \
+MACRO(985, __VA_ARGS__) \
+MU_DO_984(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_986(MACRO, ...) \
+MACRO(986, __VA_ARGS__) \
+MU_DO_985(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_987(MACRO, ...) \
+MACRO(987, __VA_ARGS__) \
+MU_DO_986(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_988(MACRO, ...) \
+MACRO(988, __VA_ARGS__) \
+MU_DO_987(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_989(MACRO, ...) \
+MACRO(989, __VA_ARGS__) \
+MU_DO_988(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_990(MACRO, ...) \
+MACRO(990, __VA_ARGS__) \
+MU_DO_989(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_991(MACRO, ...) \
+MACRO(991, __VA_ARGS__) \
+MU_DO_990(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_992(MACRO, ...) \
+MACRO(992, __VA_ARGS__) \
+MU_DO_991(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_993(MACRO, ...) \
+MACRO(993, __VA_ARGS__) \
+MU_DO_992(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_994(MACRO, ...) \
+MACRO(994, __VA_ARGS__) \
+MU_DO_993(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_995(MACRO, ...) \
+MACRO(995, __VA_ARGS__) \
+MU_DO_994(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_996(MACRO, ...) \
+MACRO(996, __VA_ARGS__) \
+MU_DO_995(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_997(MACRO, ...) \
+MACRO(997, __VA_ARGS__) \
+MU_DO_996(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_998(MACRO, ...) \
+MACRO(998, __VA_ARGS__) \
+MU_DO_997(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_999(MACRO, ...) \
+MACRO(999, __VA_ARGS__) \
+MU_DO_998(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1000(MACRO, ...) \
+MACRO(1000, __VA_ARGS__) \
+MU_DO_999(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1001(MACRO, ...) \
+MACRO(1001, __VA_ARGS__) \
+MU_DO_1000(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1002(MACRO, ...) \
+MACRO(1002, __VA_ARGS__) \
+MU_DO_1001(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1003(MACRO, ...) \
+MACRO(1003, __VA_ARGS__) \
+MU_DO_1002(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1004(MACRO, ...) \
+MACRO(1004, __VA_ARGS__) \
+MU_DO_1003(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1005(MACRO, ...) \
+MACRO(1005, __VA_ARGS__) \
+MU_DO_1004(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1006(MACRO, ...) \
+MACRO(1006, __VA_ARGS__) \
+MU_DO_1005(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1007(MACRO, ...) \
+MACRO(1007, __VA_ARGS__) \
+MU_DO_1006(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1008(MACRO, ...) \
+MACRO(1008, __VA_ARGS__) \
+MU_DO_1007(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1009(MACRO, ...) \
+MACRO(1009, __VA_ARGS__) \
+MU_DO_1008(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1010(MACRO, ...) \
+MACRO(1010, __VA_ARGS__) \
+MU_DO_1009(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1011(MACRO, ...) \
+MACRO(1011, __VA_ARGS__) \
+MU_DO_1010(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1012(MACRO, ...) \
+MACRO(1012, __VA_ARGS__) \
+MU_DO_1011(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1013(MACRO, ...) \
+MACRO(1013, __VA_ARGS__) \
+MU_DO_1012(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1014(MACRO, ...) \
+MACRO(1014, __VA_ARGS__) \
+MU_DO_1013(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1015(MACRO, ...) \
+MACRO(1015, __VA_ARGS__) \
+MU_DO_1014(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1016(MACRO, ...) \
+MACRO(1016, __VA_ARGS__) \
+MU_DO_1015(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1017(MACRO, ...) \
+MACRO(1017, __VA_ARGS__) \
+MU_DO_1016(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1018(MACRO, ...) \
+MACRO(1018, __VA_ARGS__) \
+MU_DO_1017(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1019(MACRO, ...) \
+MACRO(1019, __VA_ARGS__) \
+MU_DO_1018(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1020(MACRO, ...) \
+MACRO(1020, __VA_ARGS__) \
+MU_DO_1019(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1021(MACRO, ...) \
+MACRO(1021, __VA_ARGS__) \
+MU_DO_1020(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1022(MACRO, ...) \
+MACRO(1022, __VA_ARGS__) \
+MU_DO_1021(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1023(MACRO, ...) \
+MACRO(1023, __VA_ARGS__) \
+MU_DO_1022(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1024(MACRO, ...) \
+MACRO(1024, __VA_ARGS__) \
+MU_DO_1023(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1025(MACRO, ...) \
+MACRO(1025, __VA_ARGS__) \
+MU_DO_1024(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1026(MACRO, ...) \
+MACRO(1026, __VA_ARGS__) \
+MU_DO_1025(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1027(MACRO, ...) \
+MACRO(1027, __VA_ARGS__) \
+MU_DO_1026(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1028(MACRO, ...) \
+MACRO(1028, __VA_ARGS__) \
+MU_DO_1027(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1029(MACRO, ...) \
+MACRO(1029, __VA_ARGS__) \
+MU_DO_1028(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1030(MACRO, ...) \
+MACRO(1030, __VA_ARGS__) \
+MU_DO_1029(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1031(MACRO, ...) \
+MACRO(1031, __VA_ARGS__) \
+MU_DO_1030(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1032(MACRO, ...) \
+MACRO(1032, __VA_ARGS__) \
+MU_DO_1031(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1033(MACRO, ...) \
+MACRO(1033, __VA_ARGS__) \
+MU_DO_1032(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1034(MACRO, ...) \
+MACRO(1034, __VA_ARGS__) \
+MU_DO_1033(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1035(MACRO, ...) \
+MACRO(1035, __VA_ARGS__) \
+MU_DO_1034(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1036(MACRO, ...) \
+MACRO(1036, __VA_ARGS__) \
+MU_DO_1035(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1037(MACRO, ...) \
+MACRO(1037, __VA_ARGS__) \
+MU_DO_1036(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1038(MACRO, ...) \
+MACRO(1038, __VA_ARGS__) \
+MU_DO_1037(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1039(MACRO, ...) \
+MACRO(1039, __VA_ARGS__) \
+MU_DO_1038(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1040(MACRO, ...) \
+MACRO(1040, __VA_ARGS__) \
+MU_DO_1039(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1041(MACRO, ...) \
+MACRO(1041, __VA_ARGS__) \
+MU_DO_1040(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1042(MACRO, ...) \
+MACRO(1042, __VA_ARGS__) \
+MU_DO_1041(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1043(MACRO, ...) \
+MACRO(1043, __VA_ARGS__) \
+MU_DO_1042(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1044(MACRO, ...) \
+MACRO(1044, __VA_ARGS__) \
+MU_DO_1043(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1045(MACRO, ...) \
+MACRO(1045, __VA_ARGS__) \
+MU_DO_1044(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1046(MACRO, ...) \
+MACRO(1046, __VA_ARGS__) \
+MU_DO_1045(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1047(MACRO, ...) \
+MACRO(1047, __VA_ARGS__) \
+MU_DO_1046(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1048(MACRO, ...) \
+MACRO(1048, __VA_ARGS__) \
+MU_DO_1047(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1049(MACRO, ...) \
+MACRO(1049, __VA_ARGS__) \
+MU_DO_1048(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1050(MACRO, ...) \
+MACRO(1050, __VA_ARGS__) \
+MU_DO_1049(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1051(MACRO, ...) \
+MACRO(1051, __VA_ARGS__) \
+MU_DO_1050(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1052(MACRO, ...) \
+MACRO(1052, __VA_ARGS__) \
+MU_DO_1051(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1053(MACRO, ...) \
+MACRO(1053, __VA_ARGS__) \
+MU_DO_1052(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1054(MACRO, ...) \
+MACRO(1054, __VA_ARGS__) \
+MU_DO_1053(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1055(MACRO, ...) \
+MACRO(1055, __VA_ARGS__) \
+MU_DO_1054(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1056(MACRO, ...) \
+MACRO(1056, __VA_ARGS__) \
+MU_DO_1055(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1057(MACRO, ...) \
+MACRO(1057, __VA_ARGS__) \
+MU_DO_1056(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1058(MACRO, ...) \
+MACRO(1058, __VA_ARGS__) \
+MU_DO_1057(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1059(MACRO, ...) \
+MACRO(1059, __VA_ARGS__) \
+MU_DO_1058(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1060(MACRO, ...) \
+MACRO(1060, __VA_ARGS__) \
+MU_DO_1059(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1061(MACRO, ...) \
+MACRO(1061, __VA_ARGS__) \
+MU_DO_1060(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1062(MACRO, ...) \
+MACRO(1062, __VA_ARGS__) \
+MU_DO_1061(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1063(MACRO, ...) \
+MACRO(1063, __VA_ARGS__) \
+MU_DO_1062(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1064(MACRO, ...) \
+MACRO(1064, __VA_ARGS__) \
+MU_DO_1063(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1065(MACRO, ...) \
+MACRO(1065, __VA_ARGS__) \
+MU_DO_1064(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1066(MACRO, ...) \
+MACRO(1066, __VA_ARGS__) \
+MU_DO_1065(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1067(MACRO, ...) \
+MACRO(1067, __VA_ARGS__) \
+MU_DO_1066(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1068(MACRO, ...) \
+MACRO(1068, __VA_ARGS__) \
+MU_DO_1067(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1069(MACRO, ...) \
+MACRO(1069, __VA_ARGS__) \
+MU_DO_1068(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1070(MACRO, ...) \
+MACRO(1070, __VA_ARGS__) \
+MU_DO_1069(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1071(MACRO, ...) \
+MACRO(1071, __VA_ARGS__) \
+MU_DO_1070(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1072(MACRO, ...) \
+MACRO(1072, __VA_ARGS__) \
+MU_DO_1071(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1073(MACRO, ...) \
+MACRO(1073, __VA_ARGS__) \
+MU_DO_1072(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1074(MACRO, ...) \
+MACRO(1074, __VA_ARGS__) \
+MU_DO_1073(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1075(MACRO, ...) \
+MACRO(1075, __VA_ARGS__) \
+MU_DO_1074(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1076(MACRO, ...) \
+MACRO(1076, __VA_ARGS__) \
+MU_DO_1075(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1077(MACRO, ...) \
+MACRO(1077, __VA_ARGS__) \
+MU_DO_1076(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1078(MACRO, ...) \
+MACRO(1078, __VA_ARGS__) \
+MU_DO_1077(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1079(MACRO, ...) \
+MACRO(1079, __VA_ARGS__) \
+MU_DO_1078(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1080(MACRO, ...) \
+MACRO(1080, __VA_ARGS__) \
+MU_DO_1079(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1081(MACRO, ...) \
+MACRO(1081, __VA_ARGS__) \
+MU_DO_1080(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1082(MACRO, ...) \
+MACRO(1082, __VA_ARGS__) \
+MU_DO_1081(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1083(MACRO, ...) \
+MACRO(1083, __VA_ARGS__) \
+MU_DO_1082(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1084(MACRO, ...) \
+MACRO(1084, __VA_ARGS__) \
+MU_DO_1083(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1085(MACRO, ...) \
+MACRO(1085, __VA_ARGS__) \
+MU_DO_1084(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1086(MACRO, ...) \
+MACRO(1086, __VA_ARGS__) \
+MU_DO_1085(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1087(MACRO, ...) \
+MACRO(1087, __VA_ARGS__) \
+MU_DO_1086(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1088(MACRO, ...) \
+MACRO(1088, __VA_ARGS__) \
+MU_DO_1087(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1089(MACRO, ...) \
+MACRO(1089, __VA_ARGS__) \
+MU_DO_1088(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1090(MACRO, ...) \
+MACRO(1090, __VA_ARGS__) \
+MU_DO_1089(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1091(MACRO, ...) \
+MACRO(1091, __VA_ARGS__) \
+MU_DO_1090(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1092(MACRO, ...) \
+MACRO(1092, __VA_ARGS__) \
+MU_DO_1091(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1093(MACRO, ...) \
+MACRO(1093, __VA_ARGS__) \
+MU_DO_1092(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1094(MACRO, ...) \
+MACRO(1094, __VA_ARGS__) \
+MU_DO_1093(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1095(MACRO, ...) \
+MACRO(1095, __VA_ARGS__) \
+MU_DO_1094(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1096(MACRO, ...) \
+MACRO(1096, __VA_ARGS__) \
+MU_DO_1095(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1097(MACRO, ...) \
+MACRO(1097, __VA_ARGS__) \
+MU_DO_1096(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1098(MACRO, ...) \
+MACRO(1098, __VA_ARGS__) \
+MU_DO_1097(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1099(MACRO, ...) \
+MACRO(1099, __VA_ARGS__) \
+MU_DO_1098(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1100(MACRO, ...) \
+MACRO(1100, __VA_ARGS__) \
+MU_DO_1099(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1101(MACRO, ...) \
+MACRO(1101, __VA_ARGS__) \
+MU_DO_1100(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1102(MACRO, ...) \
+MACRO(1102, __VA_ARGS__) \
+MU_DO_1101(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1103(MACRO, ...) \
+MACRO(1103, __VA_ARGS__) \
+MU_DO_1102(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1104(MACRO, ...) \
+MACRO(1104, __VA_ARGS__) \
+MU_DO_1103(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1105(MACRO, ...) \
+MACRO(1105, __VA_ARGS__) \
+MU_DO_1104(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1106(MACRO, ...) \
+MACRO(1106, __VA_ARGS__) \
+MU_DO_1105(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1107(MACRO, ...) \
+MACRO(1107, __VA_ARGS__) \
+MU_DO_1106(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1108(MACRO, ...) \
+MACRO(1108, __VA_ARGS__) \
+MU_DO_1107(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1109(MACRO, ...) \
+MACRO(1109, __VA_ARGS__) \
+MU_DO_1108(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1110(MACRO, ...) \
+MACRO(1110, __VA_ARGS__) \
+MU_DO_1109(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1111(MACRO, ...) \
+MACRO(1111, __VA_ARGS__) \
+MU_DO_1110(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1112(MACRO, ...) \
+MACRO(1112, __VA_ARGS__) \
+MU_DO_1111(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1113(MACRO, ...) \
+MACRO(1113, __VA_ARGS__) \
+MU_DO_1112(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1114(MACRO, ...) \
+MACRO(1114, __VA_ARGS__) \
+MU_DO_1113(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1115(MACRO, ...) \
+MACRO(1115, __VA_ARGS__) \
+MU_DO_1114(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1116(MACRO, ...) \
+MACRO(1116, __VA_ARGS__) \
+MU_DO_1115(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1117(MACRO, ...) \
+MACRO(1117, __VA_ARGS__) \
+MU_DO_1116(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1118(MACRO, ...) \
+MACRO(1118, __VA_ARGS__) \
+MU_DO_1117(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1119(MACRO, ...) \
+MACRO(1119, __VA_ARGS__) \
+MU_DO_1118(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1120(MACRO, ...) \
+MACRO(1120, __VA_ARGS__) \
+MU_DO_1119(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1121(MACRO, ...) \
+MACRO(1121, __VA_ARGS__) \
+MU_DO_1120(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1122(MACRO, ...) \
+MACRO(1122, __VA_ARGS__) \
+MU_DO_1121(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1123(MACRO, ...) \
+MACRO(1123, __VA_ARGS__) \
+MU_DO_1122(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1124(MACRO, ...) \
+MACRO(1124, __VA_ARGS__) \
+MU_DO_1123(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1125(MACRO, ...) \
+MACRO(1125, __VA_ARGS__) \
+MU_DO_1124(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1126(MACRO, ...) \
+MACRO(1126, __VA_ARGS__) \
+MU_DO_1125(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1127(MACRO, ...) \
+MACRO(1127, __VA_ARGS__) \
+MU_DO_1126(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1128(MACRO, ...) \
+MACRO(1128, __VA_ARGS__) \
+MU_DO_1127(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1129(MACRO, ...) \
+MACRO(1129, __VA_ARGS__) \
+MU_DO_1128(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1130(MACRO, ...) \
+MACRO(1130, __VA_ARGS__) \
+MU_DO_1129(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1131(MACRO, ...) \
+MACRO(1131, __VA_ARGS__) \
+MU_DO_1130(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1132(MACRO, ...) \
+MACRO(1132, __VA_ARGS__) \
+MU_DO_1131(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1133(MACRO, ...) \
+MACRO(1133, __VA_ARGS__) \
+MU_DO_1132(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1134(MACRO, ...) \
+MACRO(1134, __VA_ARGS__) \
+MU_DO_1133(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1135(MACRO, ...) \
+MACRO(1135, __VA_ARGS__) \
+MU_DO_1134(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1136(MACRO, ...) \
+MACRO(1136, __VA_ARGS__) \
+MU_DO_1135(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1137(MACRO, ...) \
+MACRO(1137, __VA_ARGS__) \
+MU_DO_1136(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1138(MACRO, ...) \
+MACRO(1138, __VA_ARGS__) \
+MU_DO_1137(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1139(MACRO, ...) \
+MACRO(1139, __VA_ARGS__) \
+MU_DO_1138(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1140(MACRO, ...) \
+MACRO(1140, __VA_ARGS__) \
+MU_DO_1139(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1141(MACRO, ...) \
+MACRO(1141, __VA_ARGS__) \
+MU_DO_1140(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1142(MACRO, ...) \
+MACRO(1142, __VA_ARGS__) \
+MU_DO_1141(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1143(MACRO, ...) \
+MACRO(1143, __VA_ARGS__) \
+MU_DO_1142(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1144(MACRO, ...) \
+MACRO(1144, __VA_ARGS__) \
+MU_DO_1143(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1145(MACRO, ...) \
+MACRO(1145, __VA_ARGS__) \
+MU_DO_1144(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1146(MACRO, ...) \
+MACRO(1146, __VA_ARGS__) \
+MU_DO_1145(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1147(MACRO, ...) \
+MACRO(1147, __VA_ARGS__) \
+MU_DO_1146(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1148(MACRO, ...) \
+MACRO(1148, __VA_ARGS__) \
+MU_DO_1147(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1149(MACRO, ...) \
+MACRO(1149, __VA_ARGS__) \
+MU_DO_1148(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1150(MACRO, ...) \
+MACRO(1150, __VA_ARGS__) \
+MU_DO_1149(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1151(MACRO, ...) \
+MACRO(1151, __VA_ARGS__) \
+MU_DO_1150(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1152(MACRO, ...) \
+MACRO(1152, __VA_ARGS__) \
+MU_DO_1151(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1153(MACRO, ...) \
+MACRO(1153, __VA_ARGS__) \
+MU_DO_1152(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1154(MACRO, ...) \
+MACRO(1154, __VA_ARGS__) \
+MU_DO_1153(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1155(MACRO, ...) \
+MACRO(1155, __VA_ARGS__) \
+MU_DO_1154(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1156(MACRO, ...) \
+MACRO(1156, __VA_ARGS__) \
+MU_DO_1155(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1157(MACRO, ...) \
+MACRO(1157, __VA_ARGS__) \
+MU_DO_1156(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1158(MACRO, ...) \
+MACRO(1158, __VA_ARGS__) \
+MU_DO_1157(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1159(MACRO, ...) \
+MACRO(1159, __VA_ARGS__) \
+MU_DO_1158(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1160(MACRO, ...) \
+MACRO(1160, __VA_ARGS__) \
+MU_DO_1159(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1161(MACRO, ...) \
+MACRO(1161, __VA_ARGS__) \
+MU_DO_1160(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1162(MACRO, ...) \
+MACRO(1162, __VA_ARGS__) \
+MU_DO_1161(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1163(MACRO, ...) \
+MACRO(1163, __VA_ARGS__) \
+MU_DO_1162(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1164(MACRO, ...) \
+MACRO(1164, __VA_ARGS__) \
+MU_DO_1163(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1165(MACRO, ...) \
+MACRO(1165, __VA_ARGS__) \
+MU_DO_1164(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1166(MACRO, ...) \
+MACRO(1166, __VA_ARGS__) \
+MU_DO_1165(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1167(MACRO, ...) \
+MACRO(1167, __VA_ARGS__) \
+MU_DO_1166(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1168(MACRO, ...) \
+MACRO(1168, __VA_ARGS__) \
+MU_DO_1167(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1169(MACRO, ...) \
+MACRO(1169, __VA_ARGS__) \
+MU_DO_1168(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1170(MACRO, ...) \
+MACRO(1170, __VA_ARGS__) \
+MU_DO_1169(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1171(MACRO, ...) \
+MACRO(1171, __VA_ARGS__) \
+MU_DO_1170(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1172(MACRO, ...) \
+MACRO(1172, __VA_ARGS__) \
+MU_DO_1171(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1173(MACRO, ...) \
+MACRO(1173, __VA_ARGS__) \
+MU_DO_1172(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1174(MACRO, ...) \
+MACRO(1174, __VA_ARGS__) \
+MU_DO_1173(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1175(MACRO, ...) \
+MACRO(1175, __VA_ARGS__) \
+MU_DO_1174(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1176(MACRO, ...) \
+MACRO(1176, __VA_ARGS__) \
+MU_DO_1175(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1177(MACRO, ...) \
+MACRO(1177, __VA_ARGS__) \
+MU_DO_1176(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1178(MACRO, ...) \
+MACRO(1178, __VA_ARGS__) \
+MU_DO_1177(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1179(MACRO, ...) \
+MACRO(1179, __VA_ARGS__) \
+MU_DO_1178(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1180(MACRO, ...) \
+MACRO(1180, __VA_ARGS__) \
+MU_DO_1179(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1181(MACRO, ...) \
+MACRO(1181, __VA_ARGS__) \
+MU_DO_1180(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1182(MACRO, ...) \
+MACRO(1182, __VA_ARGS__) \
+MU_DO_1181(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1183(MACRO, ...) \
+MACRO(1183, __VA_ARGS__) \
+MU_DO_1182(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1184(MACRO, ...) \
+MACRO(1184, __VA_ARGS__) \
+MU_DO_1183(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1185(MACRO, ...) \
+MACRO(1185, __VA_ARGS__) \
+MU_DO_1184(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1186(MACRO, ...) \
+MACRO(1186, __VA_ARGS__) \
+MU_DO_1185(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1187(MACRO, ...) \
+MACRO(1187, __VA_ARGS__) \
+MU_DO_1186(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1188(MACRO, ...) \
+MACRO(1188, __VA_ARGS__) \
+MU_DO_1187(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1189(MACRO, ...) \
+MACRO(1189, __VA_ARGS__) \
+MU_DO_1188(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1190(MACRO, ...) \
+MACRO(1190, __VA_ARGS__) \
+MU_DO_1189(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1191(MACRO, ...) \
+MACRO(1191, __VA_ARGS__) \
+MU_DO_1190(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1192(MACRO, ...) \
+MACRO(1192, __VA_ARGS__) \
+MU_DO_1191(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1193(MACRO, ...) \
+MACRO(1193, __VA_ARGS__) \
+MU_DO_1192(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1194(MACRO, ...) \
+MACRO(1194, __VA_ARGS__) \
+MU_DO_1193(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1195(MACRO, ...) \
+MACRO(1195, __VA_ARGS__) \
+MU_DO_1194(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1196(MACRO, ...) \
+MACRO(1196, __VA_ARGS__) \
+MU_DO_1195(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1197(MACRO, ...) \
+MACRO(1197, __VA_ARGS__) \
+MU_DO_1196(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1198(MACRO, ...) \
+MACRO(1198, __VA_ARGS__) \
+MU_DO_1197(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1199(MACRO, ...) \
+MACRO(1199, __VA_ARGS__) \
+MU_DO_1198(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1200(MACRO, ...) \
+MACRO(1200, __VA_ARGS__) \
+MU_DO_1199(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1201(MACRO, ...) \
+MACRO(1201, __VA_ARGS__) \
+MU_DO_1200(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1202(MACRO, ...) \
+MACRO(1202, __VA_ARGS__) \
+MU_DO_1201(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1203(MACRO, ...) \
+MACRO(1203, __VA_ARGS__) \
+MU_DO_1202(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1204(MACRO, ...) \
+MACRO(1204, __VA_ARGS__) \
+MU_DO_1203(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1205(MACRO, ...) \
+MACRO(1205, __VA_ARGS__) \
+MU_DO_1204(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1206(MACRO, ...) \
+MACRO(1206, __VA_ARGS__) \
+MU_DO_1205(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1207(MACRO, ...) \
+MACRO(1207, __VA_ARGS__) \
+MU_DO_1206(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1208(MACRO, ...) \
+MACRO(1208, __VA_ARGS__) \
+MU_DO_1207(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1209(MACRO, ...) \
+MACRO(1209, __VA_ARGS__) \
+MU_DO_1208(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1210(MACRO, ...) \
+MACRO(1210, __VA_ARGS__) \
+MU_DO_1209(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1211(MACRO, ...) \
+MACRO(1211, __VA_ARGS__) \
+MU_DO_1210(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1212(MACRO, ...) \
+MACRO(1212, __VA_ARGS__) \
+MU_DO_1211(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1213(MACRO, ...) \
+MACRO(1213, __VA_ARGS__) \
+MU_DO_1212(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1214(MACRO, ...) \
+MACRO(1214, __VA_ARGS__) \
+MU_DO_1213(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1215(MACRO, ...) \
+MACRO(1215, __VA_ARGS__) \
+MU_DO_1214(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1216(MACRO, ...) \
+MACRO(1216, __VA_ARGS__) \
+MU_DO_1215(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1217(MACRO, ...) \
+MACRO(1217, __VA_ARGS__) \
+MU_DO_1216(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1218(MACRO, ...) \
+MACRO(1218, __VA_ARGS__) \
+MU_DO_1217(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1219(MACRO, ...) \
+MACRO(1219, __VA_ARGS__) \
+MU_DO_1218(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1220(MACRO, ...) \
+MACRO(1220, __VA_ARGS__) \
+MU_DO_1219(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1221(MACRO, ...) \
+MACRO(1221, __VA_ARGS__) \
+MU_DO_1220(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1222(MACRO, ...) \
+MACRO(1222, __VA_ARGS__) \
+MU_DO_1221(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1223(MACRO, ...) \
+MACRO(1223, __VA_ARGS__) \
+MU_DO_1222(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1224(MACRO, ...) \
+MACRO(1224, __VA_ARGS__) \
+MU_DO_1223(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1225(MACRO, ...) \
+MACRO(1225, __VA_ARGS__) \
+MU_DO_1224(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1226(MACRO, ...) \
+MACRO(1226, __VA_ARGS__) \
+MU_DO_1225(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1227(MACRO, ...) \
+MACRO(1227, __VA_ARGS__) \
+MU_DO_1226(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1228(MACRO, ...) \
+MACRO(1228, __VA_ARGS__) \
+MU_DO_1227(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1229(MACRO, ...) \
+MACRO(1229, __VA_ARGS__) \
+MU_DO_1228(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1230(MACRO, ...) \
+MACRO(1230, __VA_ARGS__) \
+MU_DO_1229(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1231(MACRO, ...) \
+MACRO(1231, __VA_ARGS__) \
+MU_DO_1230(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1232(MACRO, ...) \
+MACRO(1232, __VA_ARGS__) \
+MU_DO_1231(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1233(MACRO, ...) \
+MACRO(1233, __VA_ARGS__) \
+MU_DO_1232(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1234(MACRO, ...) \
+MACRO(1234, __VA_ARGS__) \
+MU_DO_1233(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1235(MACRO, ...) \
+MACRO(1235, __VA_ARGS__) \
+MU_DO_1234(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1236(MACRO, ...) \
+MACRO(1236, __VA_ARGS__) \
+MU_DO_1235(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1237(MACRO, ...) \
+MACRO(1237, __VA_ARGS__) \
+MU_DO_1236(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1238(MACRO, ...) \
+MACRO(1238, __VA_ARGS__) \
+MU_DO_1237(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1239(MACRO, ...) \
+MACRO(1239, __VA_ARGS__) \
+MU_DO_1238(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1240(MACRO, ...) \
+MACRO(1240, __VA_ARGS__) \
+MU_DO_1239(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1241(MACRO, ...) \
+MACRO(1241, __VA_ARGS__) \
+MU_DO_1240(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1242(MACRO, ...) \
+MACRO(1242, __VA_ARGS__) \
+MU_DO_1241(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1243(MACRO, ...) \
+MACRO(1243, __VA_ARGS__) \
+MU_DO_1242(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1244(MACRO, ...) \
+MACRO(1244, __VA_ARGS__) \
+MU_DO_1243(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1245(MACRO, ...) \
+MACRO(1245, __VA_ARGS__) \
+MU_DO_1244(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1246(MACRO, ...) \
+MACRO(1246, __VA_ARGS__) \
+MU_DO_1245(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1247(MACRO, ...) \
+MACRO(1247, __VA_ARGS__) \
+MU_DO_1246(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1248(MACRO, ...) \
+MACRO(1248, __VA_ARGS__) \
+MU_DO_1247(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1249(MACRO, ...) \
+MACRO(1249, __VA_ARGS__) \
+MU_DO_1248(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1250(MACRO, ...) \
+MACRO(1250, __VA_ARGS__) \
+MU_DO_1249(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1251(MACRO, ...) \
+MACRO(1251, __VA_ARGS__) \
+MU_DO_1250(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1252(MACRO, ...) \
+MACRO(1252, __VA_ARGS__) \
+MU_DO_1251(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1253(MACRO, ...) \
+MACRO(1253, __VA_ARGS__) \
+MU_DO_1252(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1254(MACRO, ...) \
+MACRO(1254, __VA_ARGS__) \
+MU_DO_1253(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1255(MACRO, ...) \
+MACRO(1255, __VA_ARGS__) \
+MU_DO_1254(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1256(MACRO, ...) \
+MACRO(1256, __VA_ARGS__) \
+MU_DO_1255(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1257(MACRO, ...) \
+MACRO(1257, __VA_ARGS__) \
+MU_DO_1256(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1258(MACRO, ...) \
+MACRO(1258, __VA_ARGS__) \
+MU_DO_1257(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1259(MACRO, ...) \
+MACRO(1259, __VA_ARGS__) \
+MU_DO_1258(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1260(MACRO, ...) \
+MACRO(1260, __VA_ARGS__) \
+MU_DO_1259(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1261(MACRO, ...) \
+MACRO(1261, __VA_ARGS__) \
+MU_DO_1260(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1262(MACRO, ...) \
+MACRO(1262, __VA_ARGS__) \
+MU_DO_1261(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1263(MACRO, ...) \
+MACRO(1263, __VA_ARGS__) \
+MU_DO_1262(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1264(MACRO, ...) \
+MACRO(1264, __VA_ARGS__) \
+MU_DO_1263(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1265(MACRO, ...) \
+MACRO(1265, __VA_ARGS__) \
+MU_DO_1264(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1266(MACRO, ...) \
+MACRO(1266, __VA_ARGS__) \
+MU_DO_1265(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1267(MACRO, ...) \
+MACRO(1267, __VA_ARGS__) \
+MU_DO_1266(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1268(MACRO, ...) \
+MACRO(1268, __VA_ARGS__) \
+MU_DO_1267(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1269(MACRO, ...) \
+MACRO(1269, __VA_ARGS__) \
+MU_DO_1268(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1270(MACRO, ...) \
+MACRO(1270, __VA_ARGS__) \
+MU_DO_1269(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1271(MACRO, ...) \
+MACRO(1271, __VA_ARGS__) \
+MU_DO_1270(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1272(MACRO, ...) \
+MACRO(1272, __VA_ARGS__) \
+MU_DO_1271(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1273(MACRO, ...) \
+MACRO(1273, __VA_ARGS__) \
+MU_DO_1272(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1274(MACRO, ...) \
+MACRO(1274, __VA_ARGS__) \
+MU_DO_1273(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1275(MACRO, ...) \
+MACRO(1275, __VA_ARGS__) \
+MU_DO_1274(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1276(MACRO, ...) \
+MACRO(1276, __VA_ARGS__) \
+MU_DO_1275(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1277(MACRO, ...) \
+MACRO(1277, __VA_ARGS__) \
+MU_DO_1276(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1278(MACRO, ...) \
+MACRO(1278, __VA_ARGS__) \
+MU_DO_1277(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1279(MACRO, ...) \
+MACRO(1279, __VA_ARGS__) \
+MU_DO_1278(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1280(MACRO, ...) \
+MACRO(1280, __VA_ARGS__) \
+MU_DO_1279(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1281(MACRO, ...) \
+MACRO(1281, __VA_ARGS__) \
+MU_DO_1280(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1282(MACRO, ...) \
+MACRO(1282, __VA_ARGS__) \
+MU_DO_1281(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1283(MACRO, ...) \
+MACRO(1283, __VA_ARGS__) \
+MU_DO_1282(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1284(MACRO, ...) \
+MACRO(1284, __VA_ARGS__) \
+MU_DO_1283(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1285(MACRO, ...) \
+MACRO(1285, __VA_ARGS__) \
+MU_DO_1284(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1286(MACRO, ...) \
+MACRO(1286, __VA_ARGS__) \
+MU_DO_1285(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1287(MACRO, ...) \
+MACRO(1287, __VA_ARGS__) \
+MU_DO_1286(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1288(MACRO, ...) \
+MACRO(1288, __VA_ARGS__) \
+MU_DO_1287(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1289(MACRO, ...) \
+MACRO(1289, __VA_ARGS__) \
+MU_DO_1288(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1290(MACRO, ...) \
+MACRO(1290, __VA_ARGS__) \
+MU_DO_1289(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1291(MACRO, ...) \
+MACRO(1291, __VA_ARGS__) \
+MU_DO_1290(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1292(MACRO, ...) \
+MACRO(1292, __VA_ARGS__) \
+MU_DO_1291(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1293(MACRO, ...) \
+MACRO(1293, __VA_ARGS__) \
+MU_DO_1292(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1294(MACRO, ...) \
+MACRO(1294, __VA_ARGS__) \
+MU_DO_1293(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1295(MACRO, ...) \
+MACRO(1295, __VA_ARGS__) \
+MU_DO_1294(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1296(MACRO, ...) \
+MACRO(1296, __VA_ARGS__) \
+MU_DO_1295(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1297(MACRO, ...) \
+MACRO(1297, __VA_ARGS__) \
+MU_DO_1296(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1298(MACRO, ...) \
+MACRO(1298, __VA_ARGS__) \
+MU_DO_1297(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1299(MACRO, ...) \
+MACRO(1299, __VA_ARGS__) \
+MU_DO_1298(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1300(MACRO, ...) \
+MACRO(1300, __VA_ARGS__) \
+MU_DO_1299(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1301(MACRO, ...) \
+MACRO(1301, __VA_ARGS__) \
+MU_DO_1300(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1302(MACRO, ...) \
+MACRO(1302, __VA_ARGS__) \
+MU_DO_1301(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1303(MACRO, ...) \
+MACRO(1303, __VA_ARGS__) \
+MU_DO_1302(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1304(MACRO, ...) \
+MACRO(1304, __VA_ARGS__) \
+MU_DO_1303(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1305(MACRO, ...) \
+MACRO(1305, __VA_ARGS__) \
+MU_DO_1304(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1306(MACRO, ...) \
+MACRO(1306, __VA_ARGS__) \
+MU_DO_1305(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1307(MACRO, ...) \
+MACRO(1307, __VA_ARGS__) \
+MU_DO_1306(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1308(MACRO, ...) \
+MACRO(1308, __VA_ARGS__) \
+MU_DO_1307(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1309(MACRO, ...) \
+MACRO(1309, __VA_ARGS__) \
+MU_DO_1308(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1310(MACRO, ...) \
+MACRO(1310, __VA_ARGS__) \
+MU_DO_1309(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1311(MACRO, ...) \
+MACRO(1311, __VA_ARGS__) \
+MU_DO_1310(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1312(MACRO, ...) \
+MACRO(1312, __VA_ARGS__) \
+MU_DO_1311(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1313(MACRO, ...) \
+MACRO(1313, __VA_ARGS__) \
+MU_DO_1312(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1314(MACRO, ...) \
+MACRO(1314, __VA_ARGS__) \
+MU_DO_1313(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1315(MACRO, ...) \
+MACRO(1315, __VA_ARGS__) \
+MU_DO_1314(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1316(MACRO, ...) \
+MACRO(1316, __VA_ARGS__) \
+MU_DO_1315(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1317(MACRO, ...) \
+MACRO(1317, __VA_ARGS__) \
+MU_DO_1316(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1318(MACRO, ...) \
+MACRO(1318, __VA_ARGS__) \
+MU_DO_1317(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1319(MACRO, ...) \
+MACRO(1319, __VA_ARGS__) \
+MU_DO_1318(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1320(MACRO, ...) \
+MACRO(1320, __VA_ARGS__) \
+MU_DO_1319(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1321(MACRO, ...) \
+MACRO(1321, __VA_ARGS__) \
+MU_DO_1320(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1322(MACRO, ...) \
+MACRO(1322, __VA_ARGS__) \
+MU_DO_1321(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1323(MACRO, ...) \
+MACRO(1323, __VA_ARGS__) \
+MU_DO_1322(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1324(MACRO, ...) \
+MACRO(1324, __VA_ARGS__) \
+MU_DO_1323(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1325(MACRO, ...) \
+MACRO(1325, __VA_ARGS__) \
+MU_DO_1324(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1326(MACRO, ...) \
+MACRO(1326, __VA_ARGS__) \
+MU_DO_1325(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1327(MACRO, ...) \
+MACRO(1327, __VA_ARGS__) \
+MU_DO_1326(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1328(MACRO, ...) \
+MACRO(1328, __VA_ARGS__) \
+MU_DO_1327(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1329(MACRO, ...) \
+MACRO(1329, __VA_ARGS__) \
+MU_DO_1328(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1330(MACRO, ...) \
+MACRO(1330, __VA_ARGS__) \
+MU_DO_1329(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1331(MACRO, ...) \
+MACRO(1331, __VA_ARGS__) \
+MU_DO_1330(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1332(MACRO, ...) \
+MACRO(1332, __VA_ARGS__) \
+MU_DO_1331(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1333(MACRO, ...) \
+MACRO(1333, __VA_ARGS__) \
+MU_DO_1332(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1334(MACRO, ...) \
+MACRO(1334, __VA_ARGS__) \
+MU_DO_1333(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1335(MACRO, ...) \
+MACRO(1335, __VA_ARGS__) \
+MU_DO_1334(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1336(MACRO, ...) \
+MACRO(1336, __VA_ARGS__) \
+MU_DO_1335(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1337(MACRO, ...) \
+MACRO(1337, __VA_ARGS__) \
+MU_DO_1336(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1338(MACRO, ...) \
+MACRO(1338, __VA_ARGS__) \
+MU_DO_1337(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1339(MACRO, ...) \
+MACRO(1339, __VA_ARGS__) \
+MU_DO_1338(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1340(MACRO, ...) \
+MACRO(1340, __VA_ARGS__) \
+MU_DO_1339(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1341(MACRO, ...) \
+MACRO(1341, __VA_ARGS__) \
+MU_DO_1340(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1342(MACRO, ...) \
+MACRO(1342, __VA_ARGS__) \
+MU_DO_1341(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1343(MACRO, ...) \
+MACRO(1343, __VA_ARGS__) \
+MU_DO_1342(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1344(MACRO, ...) \
+MACRO(1344, __VA_ARGS__) \
+MU_DO_1343(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1345(MACRO, ...) \
+MACRO(1345, __VA_ARGS__) \
+MU_DO_1344(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1346(MACRO, ...) \
+MACRO(1346, __VA_ARGS__) \
+MU_DO_1345(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1347(MACRO, ...) \
+MACRO(1347, __VA_ARGS__) \
+MU_DO_1346(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1348(MACRO, ...) \
+MACRO(1348, __VA_ARGS__) \
+MU_DO_1347(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1349(MACRO, ...) \
+MACRO(1349, __VA_ARGS__) \
+MU_DO_1348(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1350(MACRO, ...) \
+MACRO(1350, __VA_ARGS__) \
+MU_DO_1349(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1351(MACRO, ...) \
+MACRO(1351, __VA_ARGS__) \
+MU_DO_1350(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1352(MACRO, ...) \
+MACRO(1352, __VA_ARGS__) \
+MU_DO_1351(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1353(MACRO, ...) \
+MACRO(1353, __VA_ARGS__) \
+MU_DO_1352(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1354(MACRO, ...) \
+MACRO(1354, __VA_ARGS__) \
+MU_DO_1353(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1355(MACRO, ...) \
+MACRO(1355, __VA_ARGS__) \
+MU_DO_1354(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1356(MACRO, ...) \
+MACRO(1356, __VA_ARGS__) \
+MU_DO_1355(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1357(MACRO, ...) \
+MACRO(1357, __VA_ARGS__) \
+MU_DO_1356(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1358(MACRO, ...) \
+MACRO(1358, __VA_ARGS__) \
+MU_DO_1357(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1359(MACRO, ...) \
+MACRO(1359, __VA_ARGS__) \
+MU_DO_1358(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1360(MACRO, ...) \
+MACRO(1360, __VA_ARGS__) \
+MU_DO_1359(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1361(MACRO, ...) \
+MACRO(1361, __VA_ARGS__) \
+MU_DO_1360(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1362(MACRO, ...) \
+MACRO(1362, __VA_ARGS__) \
+MU_DO_1361(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1363(MACRO, ...) \
+MACRO(1363, __VA_ARGS__) \
+MU_DO_1362(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1364(MACRO, ...) \
+MACRO(1364, __VA_ARGS__) \
+MU_DO_1363(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1365(MACRO, ...) \
+MACRO(1365, __VA_ARGS__) \
+MU_DO_1364(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1366(MACRO, ...) \
+MACRO(1366, __VA_ARGS__) \
+MU_DO_1365(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1367(MACRO, ...) \
+MACRO(1367, __VA_ARGS__) \
+MU_DO_1366(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1368(MACRO, ...) \
+MACRO(1368, __VA_ARGS__) \
+MU_DO_1367(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1369(MACRO, ...) \
+MACRO(1369, __VA_ARGS__) \
+MU_DO_1368(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1370(MACRO, ...) \
+MACRO(1370, __VA_ARGS__) \
+MU_DO_1369(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1371(MACRO, ...) \
+MACRO(1371, __VA_ARGS__) \
+MU_DO_1370(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1372(MACRO, ...) \
+MACRO(1372, __VA_ARGS__) \
+MU_DO_1371(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1373(MACRO, ...) \
+MACRO(1373, __VA_ARGS__) \
+MU_DO_1372(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1374(MACRO, ...) \
+MACRO(1374, __VA_ARGS__) \
+MU_DO_1373(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1375(MACRO, ...) \
+MACRO(1375, __VA_ARGS__) \
+MU_DO_1374(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1376(MACRO, ...) \
+MACRO(1376, __VA_ARGS__) \
+MU_DO_1375(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1377(MACRO, ...) \
+MACRO(1377, __VA_ARGS__) \
+MU_DO_1376(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1378(MACRO, ...) \
+MACRO(1378, __VA_ARGS__) \
+MU_DO_1377(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1379(MACRO, ...) \
+MACRO(1379, __VA_ARGS__) \
+MU_DO_1378(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1380(MACRO, ...) \
+MACRO(1380, __VA_ARGS__) \
+MU_DO_1379(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1381(MACRO, ...) \
+MACRO(1381, __VA_ARGS__) \
+MU_DO_1380(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1382(MACRO, ...) \
+MACRO(1382, __VA_ARGS__) \
+MU_DO_1381(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1383(MACRO, ...) \
+MACRO(1383, __VA_ARGS__) \
+MU_DO_1382(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1384(MACRO, ...) \
+MACRO(1384, __VA_ARGS__) \
+MU_DO_1383(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1385(MACRO, ...) \
+MACRO(1385, __VA_ARGS__) \
+MU_DO_1384(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1386(MACRO, ...) \
+MACRO(1386, __VA_ARGS__) \
+MU_DO_1385(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1387(MACRO, ...) \
+MACRO(1387, __VA_ARGS__) \
+MU_DO_1386(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1388(MACRO, ...) \
+MACRO(1388, __VA_ARGS__) \
+MU_DO_1387(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1389(MACRO, ...) \
+MACRO(1389, __VA_ARGS__) \
+MU_DO_1388(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1390(MACRO, ...) \
+MACRO(1390, __VA_ARGS__) \
+MU_DO_1389(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1391(MACRO, ...) \
+MACRO(1391, __VA_ARGS__) \
+MU_DO_1390(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1392(MACRO, ...) \
+MACRO(1392, __VA_ARGS__) \
+MU_DO_1391(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1393(MACRO, ...) \
+MACRO(1393, __VA_ARGS__) \
+MU_DO_1392(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1394(MACRO, ...) \
+MACRO(1394, __VA_ARGS__) \
+MU_DO_1393(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1395(MACRO, ...) \
+MACRO(1395, __VA_ARGS__) \
+MU_DO_1394(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1396(MACRO, ...) \
+MACRO(1396, __VA_ARGS__) \
+MU_DO_1395(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1397(MACRO, ...) \
+MACRO(1397, __VA_ARGS__) \
+MU_DO_1396(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1398(MACRO, ...) \
+MACRO(1398, __VA_ARGS__) \
+MU_DO_1397(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1399(MACRO, ...) \
+MACRO(1399, __VA_ARGS__) \
+MU_DO_1398(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1400(MACRO, ...) \
+MACRO(1400, __VA_ARGS__) \
+MU_DO_1399(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1401(MACRO, ...) \
+MACRO(1401, __VA_ARGS__) \
+MU_DO_1400(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1402(MACRO, ...) \
+MACRO(1402, __VA_ARGS__) \
+MU_DO_1401(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1403(MACRO, ...) \
+MACRO(1403, __VA_ARGS__) \
+MU_DO_1402(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1404(MACRO, ...) \
+MACRO(1404, __VA_ARGS__) \
+MU_DO_1403(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1405(MACRO, ...) \
+MACRO(1405, __VA_ARGS__) \
+MU_DO_1404(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1406(MACRO, ...) \
+MACRO(1406, __VA_ARGS__) \
+MU_DO_1405(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1407(MACRO, ...) \
+MACRO(1407, __VA_ARGS__) \
+MU_DO_1406(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1408(MACRO, ...) \
+MACRO(1408, __VA_ARGS__) \
+MU_DO_1407(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1409(MACRO, ...) \
+MACRO(1409, __VA_ARGS__) \
+MU_DO_1408(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1410(MACRO, ...) \
+MACRO(1410, __VA_ARGS__) \
+MU_DO_1409(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1411(MACRO, ...) \
+MACRO(1411, __VA_ARGS__) \
+MU_DO_1410(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1412(MACRO, ...) \
+MACRO(1412, __VA_ARGS__) \
+MU_DO_1411(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1413(MACRO, ...) \
+MACRO(1413, __VA_ARGS__) \
+MU_DO_1412(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1414(MACRO, ...) \
+MACRO(1414, __VA_ARGS__) \
+MU_DO_1413(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1415(MACRO, ...) \
+MACRO(1415, __VA_ARGS__) \
+MU_DO_1414(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1416(MACRO, ...) \
+MACRO(1416, __VA_ARGS__) \
+MU_DO_1415(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1417(MACRO, ...) \
+MACRO(1417, __VA_ARGS__) \
+MU_DO_1416(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1418(MACRO, ...) \
+MACRO(1418, __VA_ARGS__) \
+MU_DO_1417(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1419(MACRO, ...) \
+MACRO(1419, __VA_ARGS__) \
+MU_DO_1418(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1420(MACRO, ...) \
+MACRO(1420, __VA_ARGS__) \
+MU_DO_1419(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1421(MACRO, ...) \
+MACRO(1421, __VA_ARGS__) \
+MU_DO_1420(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1422(MACRO, ...) \
+MACRO(1422, __VA_ARGS__) \
+MU_DO_1421(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1423(MACRO, ...) \
+MACRO(1423, __VA_ARGS__) \
+MU_DO_1422(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1424(MACRO, ...) \
+MACRO(1424, __VA_ARGS__) \
+MU_DO_1423(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1425(MACRO, ...) \
+MACRO(1425, __VA_ARGS__) \
+MU_DO_1424(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1426(MACRO, ...) \
+MACRO(1426, __VA_ARGS__) \
+MU_DO_1425(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1427(MACRO, ...) \
+MACRO(1427, __VA_ARGS__) \
+MU_DO_1426(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1428(MACRO, ...) \
+MACRO(1428, __VA_ARGS__) \
+MU_DO_1427(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1429(MACRO, ...) \
+MACRO(1429, __VA_ARGS__) \
+MU_DO_1428(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1430(MACRO, ...) \
+MACRO(1430, __VA_ARGS__) \
+MU_DO_1429(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1431(MACRO, ...) \
+MACRO(1431, __VA_ARGS__) \
+MU_DO_1430(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1432(MACRO, ...) \
+MACRO(1432, __VA_ARGS__) \
+MU_DO_1431(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1433(MACRO, ...) \
+MACRO(1433, __VA_ARGS__) \
+MU_DO_1432(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1434(MACRO, ...) \
+MACRO(1434, __VA_ARGS__) \
+MU_DO_1433(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1435(MACRO, ...) \
+MACRO(1435, __VA_ARGS__) \
+MU_DO_1434(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1436(MACRO, ...) \
+MACRO(1436, __VA_ARGS__) \
+MU_DO_1435(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1437(MACRO, ...) \
+MACRO(1437, __VA_ARGS__) \
+MU_DO_1436(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1438(MACRO, ...) \
+MACRO(1438, __VA_ARGS__) \
+MU_DO_1437(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1439(MACRO, ...) \
+MACRO(1439, __VA_ARGS__) \
+MU_DO_1438(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1440(MACRO, ...) \
+MACRO(1440, __VA_ARGS__) \
+MU_DO_1439(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1441(MACRO, ...) \
+MACRO(1441, __VA_ARGS__) \
+MU_DO_1440(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1442(MACRO, ...) \
+MACRO(1442, __VA_ARGS__) \
+MU_DO_1441(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1443(MACRO, ...) \
+MACRO(1443, __VA_ARGS__) \
+MU_DO_1442(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1444(MACRO, ...) \
+MACRO(1444, __VA_ARGS__) \
+MU_DO_1443(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1445(MACRO, ...) \
+MACRO(1445, __VA_ARGS__) \
+MU_DO_1444(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1446(MACRO, ...) \
+MACRO(1446, __VA_ARGS__) \
+MU_DO_1445(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1447(MACRO, ...) \
+MACRO(1447, __VA_ARGS__) \
+MU_DO_1446(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1448(MACRO, ...) \
+MACRO(1448, __VA_ARGS__) \
+MU_DO_1447(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1449(MACRO, ...) \
+MACRO(1449, __VA_ARGS__) \
+MU_DO_1448(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1450(MACRO, ...) \
+MACRO(1450, __VA_ARGS__) \
+MU_DO_1449(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1451(MACRO, ...) \
+MACRO(1451, __VA_ARGS__) \
+MU_DO_1450(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1452(MACRO, ...) \
+MACRO(1452, __VA_ARGS__) \
+MU_DO_1451(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1453(MACRO, ...) \
+MACRO(1453, __VA_ARGS__) \
+MU_DO_1452(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1454(MACRO, ...) \
+MACRO(1454, __VA_ARGS__) \
+MU_DO_1453(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1455(MACRO, ...) \
+MACRO(1455, __VA_ARGS__) \
+MU_DO_1454(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1456(MACRO, ...) \
+MACRO(1456, __VA_ARGS__) \
+MU_DO_1455(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1457(MACRO, ...) \
+MACRO(1457, __VA_ARGS__) \
+MU_DO_1456(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1458(MACRO, ...) \
+MACRO(1458, __VA_ARGS__) \
+MU_DO_1457(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1459(MACRO, ...) \
+MACRO(1459, __VA_ARGS__) \
+MU_DO_1458(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1460(MACRO, ...) \
+MACRO(1460, __VA_ARGS__) \
+MU_DO_1459(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1461(MACRO, ...) \
+MACRO(1461, __VA_ARGS__) \
+MU_DO_1460(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1462(MACRO, ...) \
+MACRO(1462, __VA_ARGS__) \
+MU_DO_1461(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1463(MACRO, ...) \
+MACRO(1463, __VA_ARGS__) \
+MU_DO_1462(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1464(MACRO, ...) \
+MACRO(1464, __VA_ARGS__) \
+MU_DO_1463(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1465(MACRO, ...) \
+MACRO(1465, __VA_ARGS__) \
+MU_DO_1464(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1466(MACRO, ...) \
+MACRO(1466, __VA_ARGS__) \
+MU_DO_1465(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1467(MACRO, ...) \
+MACRO(1467, __VA_ARGS__) \
+MU_DO_1466(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1468(MACRO, ...) \
+MACRO(1468, __VA_ARGS__) \
+MU_DO_1467(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1469(MACRO, ...) \
+MACRO(1469, __VA_ARGS__) \
+MU_DO_1468(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1470(MACRO, ...) \
+MACRO(1470, __VA_ARGS__) \
+MU_DO_1469(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1471(MACRO, ...) \
+MACRO(1471, __VA_ARGS__) \
+MU_DO_1470(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1472(MACRO, ...) \
+MACRO(1472, __VA_ARGS__) \
+MU_DO_1471(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1473(MACRO, ...) \
+MACRO(1473, __VA_ARGS__) \
+MU_DO_1472(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1474(MACRO, ...) \
+MACRO(1474, __VA_ARGS__) \
+MU_DO_1473(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1475(MACRO, ...) \
+MACRO(1475, __VA_ARGS__) \
+MU_DO_1474(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1476(MACRO, ...) \
+MACRO(1476, __VA_ARGS__) \
+MU_DO_1475(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1477(MACRO, ...) \
+MACRO(1477, __VA_ARGS__) \
+MU_DO_1476(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1478(MACRO, ...) \
+MACRO(1478, __VA_ARGS__) \
+MU_DO_1477(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1479(MACRO, ...) \
+MACRO(1479, __VA_ARGS__) \
+MU_DO_1478(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1480(MACRO, ...) \
+MACRO(1480, __VA_ARGS__) \
+MU_DO_1479(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1481(MACRO, ...) \
+MACRO(1481, __VA_ARGS__) \
+MU_DO_1480(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1482(MACRO, ...) \
+MACRO(1482, __VA_ARGS__) \
+MU_DO_1481(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1483(MACRO, ...) \
+MACRO(1483, __VA_ARGS__) \
+MU_DO_1482(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1484(MACRO, ...) \
+MACRO(1484, __VA_ARGS__) \
+MU_DO_1483(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1485(MACRO, ...) \
+MACRO(1485, __VA_ARGS__) \
+MU_DO_1484(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1486(MACRO, ...) \
+MACRO(1486, __VA_ARGS__) \
+MU_DO_1485(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1487(MACRO, ...) \
+MACRO(1487, __VA_ARGS__) \
+MU_DO_1486(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1488(MACRO, ...) \
+MACRO(1488, __VA_ARGS__) \
+MU_DO_1487(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1489(MACRO, ...) \
+MACRO(1489, __VA_ARGS__) \
+MU_DO_1488(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1490(MACRO, ...) \
+MACRO(1490, __VA_ARGS__) \
+MU_DO_1489(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1491(MACRO, ...) \
+MACRO(1491, __VA_ARGS__) \
+MU_DO_1490(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1492(MACRO, ...) \
+MACRO(1492, __VA_ARGS__) \
+MU_DO_1491(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1493(MACRO, ...) \
+MACRO(1493, __VA_ARGS__) \
+MU_DO_1492(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1494(MACRO, ...) \
+MACRO(1494, __VA_ARGS__) \
+MU_DO_1493(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1495(MACRO, ...) \
+MACRO(1495, __VA_ARGS__) \
+MU_DO_1494(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1496(MACRO, ...) \
+MACRO(1496, __VA_ARGS__) \
+MU_DO_1495(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1497(MACRO, ...) \
+MACRO(1497, __VA_ARGS__) \
+MU_DO_1496(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1498(MACRO, ...) \
+MACRO(1498, __VA_ARGS__) \
+MU_DO_1497(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1499(MACRO, ...) \
+MACRO(1499, __VA_ARGS__) \
+MU_DO_1498(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1500(MACRO, ...) \
+MACRO(1500, __VA_ARGS__) \
+MU_DO_1499(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1501(MACRO, ...) \
+MACRO(1501, __VA_ARGS__) \
+MU_DO_1500(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1502(MACRO, ...) \
+MACRO(1502, __VA_ARGS__) \
+MU_DO_1501(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1503(MACRO, ...) \
+MACRO(1503, __VA_ARGS__) \
+MU_DO_1502(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1504(MACRO, ...) \
+MACRO(1504, __VA_ARGS__) \
+MU_DO_1503(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1505(MACRO, ...) \
+MACRO(1505, __VA_ARGS__) \
+MU_DO_1504(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1506(MACRO, ...) \
+MACRO(1506, __VA_ARGS__) \
+MU_DO_1505(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1507(MACRO, ...) \
+MACRO(1507, __VA_ARGS__) \
+MU_DO_1506(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1508(MACRO, ...) \
+MACRO(1508, __VA_ARGS__) \
+MU_DO_1507(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1509(MACRO, ...) \
+MACRO(1509, __VA_ARGS__) \
+MU_DO_1508(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1510(MACRO, ...) \
+MACRO(1510, __VA_ARGS__) \
+MU_DO_1509(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1511(MACRO, ...) \
+MACRO(1511, __VA_ARGS__) \
+MU_DO_1510(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1512(MACRO, ...) \
+MACRO(1512, __VA_ARGS__) \
+MU_DO_1511(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1513(MACRO, ...) \
+MACRO(1513, __VA_ARGS__) \
+MU_DO_1512(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1514(MACRO, ...) \
+MACRO(1514, __VA_ARGS__) \
+MU_DO_1513(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1515(MACRO, ...) \
+MACRO(1515, __VA_ARGS__) \
+MU_DO_1514(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1516(MACRO, ...) \
+MACRO(1516, __VA_ARGS__) \
+MU_DO_1515(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1517(MACRO, ...) \
+MACRO(1517, __VA_ARGS__) \
+MU_DO_1516(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1518(MACRO, ...) \
+MACRO(1518, __VA_ARGS__) \
+MU_DO_1517(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1519(MACRO, ...) \
+MACRO(1519, __VA_ARGS__) \
+MU_DO_1518(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1520(MACRO, ...) \
+MACRO(1520, __VA_ARGS__) \
+MU_DO_1519(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1521(MACRO, ...) \
+MACRO(1521, __VA_ARGS__) \
+MU_DO_1520(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1522(MACRO, ...) \
+MACRO(1522, __VA_ARGS__) \
+MU_DO_1521(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1523(MACRO, ...) \
+MACRO(1523, __VA_ARGS__) \
+MU_DO_1522(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1524(MACRO, ...) \
+MACRO(1524, __VA_ARGS__) \
+MU_DO_1523(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1525(MACRO, ...) \
+MACRO(1525, __VA_ARGS__) \
+MU_DO_1524(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1526(MACRO, ...) \
+MACRO(1526, __VA_ARGS__) \
+MU_DO_1525(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1527(MACRO, ...) \
+MACRO(1527, __VA_ARGS__) \
+MU_DO_1526(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1528(MACRO, ...) \
+MACRO(1528, __VA_ARGS__) \
+MU_DO_1527(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1529(MACRO, ...) \
+MACRO(1529, __VA_ARGS__) \
+MU_DO_1528(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1530(MACRO, ...) \
+MACRO(1530, __VA_ARGS__) \
+MU_DO_1529(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1531(MACRO, ...) \
+MACRO(1531, __VA_ARGS__) \
+MU_DO_1530(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1532(MACRO, ...) \
+MACRO(1532, __VA_ARGS__) \
+MU_DO_1531(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1533(MACRO, ...) \
+MACRO(1533, __VA_ARGS__) \
+MU_DO_1532(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1534(MACRO, ...) \
+MACRO(1534, __VA_ARGS__) \
+MU_DO_1533(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1535(MACRO, ...) \
+MACRO(1535, __VA_ARGS__) \
+MU_DO_1534(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1536(MACRO, ...) \
+MACRO(1536, __VA_ARGS__) \
+MU_DO_1535(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1537(MACRO, ...) \
+MACRO(1537, __VA_ARGS__) \
+MU_DO_1536(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1538(MACRO, ...) \
+MACRO(1538, __VA_ARGS__) \
+MU_DO_1537(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1539(MACRO, ...) \
+MACRO(1539, __VA_ARGS__) \
+MU_DO_1538(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1540(MACRO, ...) \
+MACRO(1540, __VA_ARGS__) \
+MU_DO_1539(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1541(MACRO, ...) \
+MACRO(1541, __VA_ARGS__) \
+MU_DO_1540(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1542(MACRO, ...) \
+MACRO(1542, __VA_ARGS__) \
+MU_DO_1541(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1543(MACRO, ...) \
+MACRO(1543, __VA_ARGS__) \
+MU_DO_1542(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1544(MACRO, ...) \
+MACRO(1544, __VA_ARGS__) \
+MU_DO_1543(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1545(MACRO, ...) \
+MACRO(1545, __VA_ARGS__) \
+MU_DO_1544(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1546(MACRO, ...) \
+MACRO(1546, __VA_ARGS__) \
+MU_DO_1545(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1547(MACRO, ...) \
+MACRO(1547, __VA_ARGS__) \
+MU_DO_1546(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1548(MACRO, ...) \
+MACRO(1548, __VA_ARGS__) \
+MU_DO_1547(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1549(MACRO, ...) \
+MACRO(1549, __VA_ARGS__) \
+MU_DO_1548(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1550(MACRO, ...) \
+MACRO(1550, __VA_ARGS__) \
+MU_DO_1549(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1551(MACRO, ...) \
+MACRO(1551, __VA_ARGS__) \
+MU_DO_1550(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1552(MACRO, ...) \
+MACRO(1552, __VA_ARGS__) \
+MU_DO_1551(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1553(MACRO, ...) \
+MACRO(1553, __VA_ARGS__) \
+MU_DO_1552(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1554(MACRO, ...) \
+MACRO(1554, __VA_ARGS__) \
+MU_DO_1553(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1555(MACRO, ...) \
+MACRO(1555, __VA_ARGS__) \
+MU_DO_1554(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1556(MACRO, ...) \
+MACRO(1556, __VA_ARGS__) \
+MU_DO_1555(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1557(MACRO, ...) \
+MACRO(1557, __VA_ARGS__) \
+MU_DO_1556(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1558(MACRO, ...) \
+MACRO(1558, __VA_ARGS__) \
+MU_DO_1557(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1559(MACRO, ...) \
+MACRO(1559, __VA_ARGS__) \
+MU_DO_1558(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1560(MACRO, ...) \
+MACRO(1560, __VA_ARGS__) \
+MU_DO_1559(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1561(MACRO, ...) \
+MACRO(1561, __VA_ARGS__) \
+MU_DO_1560(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1562(MACRO, ...) \
+MACRO(1562, __VA_ARGS__) \
+MU_DO_1561(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1563(MACRO, ...) \
+MACRO(1563, __VA_ARGS__) \
+MU_DO_1562(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1564(MACRO, ...) \
+MACRO(1564, __VA_ARGS__) \
+MU_DO_1563(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1565(MACRO, ...) \
+MACRO(1565, __VA_ARGS__) \
+MU_DO_1564(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1566(MACRO, ...) \
+MACRO(1566, __VA_ARGS__) \
+MU_DO_1565(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1567(MACRO, ...) \
+MACRO(1567, __VA_ARGS__) \
+MU_DO_1566(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1568(MACRO, ...) \
+MACRO(1568, __VA_ARGS__) \
+MU_DO_1567(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1569(MACRO, ...) \
+MACRO(1569, __VA_ARGS__) \
+MU_DO_1568(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1570(MACRO, ...) \
+MACRO(1570, __VA_ARGS__) \
+MU_DO_1569(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1571(MACRO, ...) \
+MACRO(1571, __VA_ARGS__) \
+MU_DO_1570(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1572(MACRO, ...) \
+MACRO(1572, __VA_ARGS__) \
+MU_DO_1571(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1573(MACRO, ...) \
+MACRO(1573, __VA_ARGS__) \
+MU_DO_1572(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1574(MACRO, ...) \
+MACRO(1574, __VA_ARGS__) \
+MU_DO_1573(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1575(MACRO, ...) \
+MACRO(1575, __VA_ARGS__) \
+MU_DO_1574(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1576(MACRO, ...) \
+MACRO(1576, __VA_ARGS__) \
+MU_DO_1575(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1577(MACRO, ...) \
+MACRO(1577, __VA_ARGS__) \
+MU_DO_1576(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1578(MACRO, ...) \
+MACRO(1578, __VA_ARGS__) \
+MU_DO_1577(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1579(MACRO, ...) \
+MACRO(1579, __VA_ARGS__) \
+MU_DO_1578(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1580(MACRO, ...) \
+MACRO(1580, __VA_ARGS__) \
+MU_DO_1579(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1581(MACRO, ...) \
+MACRO(1581, __VA_ARGS__) \
+MU_DO_1580(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1582(MACRO, ...) \
+MACRO(1582, __VA_ARGS__) \
+MU_DO_1581(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1583(MACRO, ...) \
+MACRO(1583, __VA_ARGS__) \
+MU_DO_1582(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1584(MACRO, ...) \
+MACRO(1584, __VA_ARGS__) \
+MU_DO_1583(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1585(MACRO, ...) \
+MACRO(1585, __VA_ARGS__) \
+MU_DO_1584(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1586(MACRO, ...) \
+MACRO(1586, __VA_ARGS__) \
+MU_DO_1585(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1587(MACRO, ...) \
+MACRO(1587, __VA_ARGS__) \
+MU_DO_1586(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1588(MACRO, ...) \
+MACRO(1588, __VA_ARGS__) \
+MU_DO_1587(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1589(MACRO, ...) \
+MACRO(1589, __VA_ARGS__) \
+MU_DO_1588(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1590(MACRO, ...) \
+MACRO(1590, __VA_ARGS__) \
+MU_DO_1589(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1591(MACRO, ...) \
+MACRO(1591, __VA_ARGS__) \
+MU_DO_1590(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1592(MACRO, ...) \
+MACRO(1592, __VA_ARGS__) \
+MU_DO_1591(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1593(MACRO, ...) \
+MACRO(1593, __VA_ARGS__) \
+MU_DO_1592(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1594(MACRO, ...) \
+MACRO(1594, __VA_ARGS__) \
+MU_DO_1593(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1595(MACRO, ...) \
+MACRO(1595, __VA_ARGS__) \
+MU_DO_1594(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1596(MACRO, ...) \
+MACRO(1596, __VA_ARGS__) \
+MU_DO_1595(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1597(MACRO, ...) \
+MACRO(1597, __VA_ARGS__) \
+MU_DO_1596(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1598(MACRO, ...) \
+MACRO(1598, __VA_ARGS__) \
+MU_DO_1597(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1599(MACRO, ...) \
+MACRO(1599, __VA_ARGS__) \
+MU_DO_1598(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1600(MACRO, ...) \
+MACRO(1600, __VA_ARGS__) \
+MU_DO_1599(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1601(MACRO, ...) \
+MACRO(1601, __VA_ARGS__) \
+MU_DO_1600(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1602(MACRO, ...) \
+MACRO(1602, __VA_ARGS__) \
+MU_DO_1601(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1603(MACRO, ...) \
+MACRO(1603, __VA_ARGS__) \
+MU_DO_1602(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1604(MACRO, ...) \
+MACRO(1604, __VA_ARGS__) \
+MU_DO_1603(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1605(MACRO, ...) \
+MACRO(1605, __VA_ARGS__) \
+MU_DO_1604(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1606(MACRO, ...) \
+MACRO(1606, __VA_ARGS__) \
+MU_DO_1605(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1607(MACRO, ...) \
+MACRO(1607, __VA_ARGS__) \
+MU_DO_1606(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1608(MACRO, ...) \
+MACRO(1608, __VA_ARGS__) \
+MU_DO_1607(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1609(MACRO, ...) \
+MACRO(1609, __VA_ARGS__) \
+MU_DO_1608(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1610(MACRO, ...) \
+MACRO(1610, __VA_ARGS__) \
+MU_DO_1609(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1611(MACRO, ...) \
+MACRO(1611, __VA_ARGS__) \
+MU_DO_1610(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1612(MACRO, ...) \
+MACRO(1612, __VA_ARGS__) \
+MU_DO_1611(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1613(MACRO, ...) \
+MACRO(1613, __VA_ARGS__) \
+MU_DO_1612(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1614(MACRO, ...) \
+MACRO(1614, __VA_ARGS__) \
+MU_DO_1613(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1615(MACRO, ...) \
+MACRO(1615, __VA_ARGS__) \
+MU_DO_1614(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1616(MACRO, ...) \
+MACRO(1616, __VA_ARGS__) \
+MU_DO_1615(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1617(MACRO, ...) \
+MACRO(1617, __VA_ARGS__) \
+MU_DO_1616(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1618(MACRO, ...) \
+MACRO(1618, __VA_ARGS__) \
+MU_DO_1617(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1619(MACRO, ...) \
+MACRO(1619, __VA_ARGS__) \
+MU_DO_1618(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1620(MACRO, ...) \
+MACRO(1620, __VA_ARGS__) \
+MU_DO_1619(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1621(MACRO, ...) \
+MACRO(1621, __VA_ARGS__) \
+MU_DO_1620(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1622(MACRO, ...) \
+MACRO(1622, __VA_ARGS__) \
+MU_DO_1621(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1623(MACRO, ...) \
+MACRO(1623, __VA_ARGS__) \
+MU_DO_1622(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1624(MACRO, ...) \
+MACRO(1624, __VA_ARGS__) \
+MU_DO_1623(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1625(MACRO, ...) \
+MACRO(1625, __VA_ARGS__) \
+MU_DO_1624(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1626(MACRO, ...) \
+MACRO(1626, __VA_ARGS__) \
+MU_DO_1625(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1627(MACRO, ...) \
+MACRO(1627, __VA_ARGS__) \
+MU_DO_1626(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1628(MACRO, ...) \
+MACRO(1628, __VA_ARGS__) \
+MU_DO_1627(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1629(MACRO, ...) \
+MACRO(1629, __VA_ARGS__) \
+MU_DO_1628(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1630(MACRO, ...) \
+MACRO(1630, __VA_ARGS__) \
+MU_DO_1629(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1631(MACRO, ...) \
+MACRO(1631, __VA_ARGS__) \
+MU_DO_1630(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1632(MACRO, ...) \
+MACRO(1632, __VA_ARGS__) \
+MU_DO_1631(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1633(MACRO, ...) \
+MACRO(1633, __VA_ARGS__) \
+MU_DO_1632(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1634(MACRO, ...) \
+MACRO(1634, __VA_ARGS__) \
+MU_DO_1633(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1635(MACRO, ...) \
+MACRO(1635, __VA_ARGS__) \
+MU_DO_1634(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1636(MACRO, ...) \
+MACRO(1636, __VA_ARGS__) \
+MU_DO_1635(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1637(MACRO, ...) \
+MACRO(1637, __VA_ARGS__) \
+MU_DO_1636(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1638(MACRO, ...) \
+MACRO(1638, __VA_ARGS__) \
+MU_DO_1637(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1639(MACRO, ...) \
+MACRO(1639, __VA_ARGS__) \
+MU_DO_1638(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1640(MACRO, ...) \
+MACRO(1640, __VA_ARGS__) \
+MU_DO_1639(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1641(MACRO, ...) \
+MACRO(1641, __VA_ARGS__) \
+MU_DO_1640(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1642(MACRO, ...) \
+MACRO(1642, __VA_ARGS__) \
+MU_DO_1641(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1643(MACRO, ...) \
+MACRO(1643, __VA_ARGS__) \
+MU_DO_1642(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1644(MACRO, ...) \
+MACRO(1644, __VA_ARGS__) \
+MU_DO_1643(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1645(MACRO, ...) \
+MACRO(1645, __VA_ARGS__) \
+MU_DO_1644(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1646(MACRO, ...) \
+MACRO(1646, __VA_ARGS__) \
+MU_DO_1645(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1647(MACRO, ...) \
+MACRO(1647, __VA_ARGS__) \
+MU_DO_1646(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1648(MACRO, ...) \
+MACRO(1648, __VA_ARGS__) \
+MU_DO_1647(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1649(MACRO, ...) \
+MACRO(1649, __VA_ARGS__) \
+MU_DO_1648(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1650(MACRO, ...) \
+MACRO(1650, __VA_ARGS__) \
+MU_DO_1649(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1651(MACRO, ...) \
+MACRO(1651, __VA_ARGS__) \
+MU_DO_1650(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1652(MACRO, ...) \
+MACRO(1652, __VA_ARGS__) \
+MU_DO_1651(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1653(MACRO, ...) \
+MACRO(1653, __VA_ARGS__) \
+MU_DO_1652(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1654(MACRO, ...) \
+MACRO(1654, __VA_ARGS__) \
+MU_DO_1653(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1655(MACRO, ...) \
+MACRO(1655, __VA_ARGS__) \
+MU_DO_1654(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1656(MACRO, ...) \
+MACRO(1656, __VA_ARGS__) \
+MU_DO_1655(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1657(MACRO, ...) \
+MACRO(1657, __VA_ARGS__) \
+MU_DO_1656(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1658(MACRO, ...) \
+MACRO(1658, __VA_ARGS__) \
+MU_DO_1657(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1659(MACRO, ...) \
+MACRO(1659, __VA_ARGS__) \
+MU_DO_1658(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1660(MACRO, ...) \
+MACRO(1660, __VA_ARGS__) \
+MU_DO_1659(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1661(MACRO, ...) \
+MACRO(1661, __VA_ARGS__) \
+MU_DO_1660(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1662(MACRO, ...) \
+MACRO(1662, __VA_ARGS__) \
+MU_DO_1661(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1663(MACRO, ...) \
+MACRO(1663, __VA_ARGS__) \
+MU_DO_1662(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1664(MACRO, ...) \
+MACRO(1664, __VA_ARGS__) \
+MU_DO_1663(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1665(MACRO, ...) \
+MACRO(1665, __VA_ARGS__) \
+MU_DO_1664(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1666(MACRO, ...) \
+MACRO(1666, __VA_ARGS__) \
+MU_DO_1665(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1667(MACRO, ...) \
+MACRO(1667, __VA_ARGS__) \
+MU_DO_1666(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1668(MACRO, ...) \
+MACRO(1668, __VA_ARGS__) \
+MU_DO_1667(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1669(MACRO, ...) \
+MACRO(1669, __VA_ARGS__) \
+MU_DO_1668(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1670(MACRO, ...) \
+MACRO(1670, __VA_ARGS__) \
+MU_DO_1669(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1671(MACRO, ...) \
+MACRO(1671, __VA_ARGS__) \
+MU_DO_1670(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1672(MACRO, ...) \
+MACRO(1672, __VA_ARGS__) \
+MU_DO_1671(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1673(MACRO, ...) \
+MACRO(1673, __VA_ARGS__) \
+MU_DO_1672(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1674(MACRO, ...) \
+MACRO(1674, __VA_ARGS__) \
+MU_DO_1673(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1675(MACRO, ...) \
+MACRO(1675, __VA_ARGS__) \
+MU_DO_1674(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1676(MACRO, ...) \
+MACRO(1676, __VA_ARGS__) \
+MU_DO_1675(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1677(MACRO, ...) \
+MACRO(1677, __VA_ARGS__) \
+MU_DO_1676(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1678(MACRO, ...) \
+MACRO(1678, __VA_ARGS__) \
+MU_DO_1677(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1679(MACRO, ...) \
+MACRO(1679, __VA_ARGS__) \
+MU_DO_1678(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1680(MACRO, ...) \
+MACRO(1680, __VA_ARGS__) \
+MU_DO_1679(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1681(MACRO, ...) \
+MACRO(1681, __VA_ARGS__) \
+MU_DO_1680(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1682(MACRO, ...) \
+MACRO(1682, __VA_ARGS__) \
+MU_DO_1681(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1683(MACRO, ...) \
+MACRO(1683, __VA_ARGS__) \
+MU_DO_1682(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1684(MACRO, ...) \
+MACRO(1684, __VA_ARGS__) \
+MU_DO_1683(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1685(MACRO, ...) \
+MACRO(1685, __VA_ARGS__) \
+MU_DO_1684(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1686(MACRO, ...) \
+MACRO(1686, __VA_ARGS__) \
+MU_DO_1685(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1687(MACRO, ...) \
+MACRO(1687, __VA_ARGS__) \
+MU_DO_1686(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1688(MACRO, ...) \
+MACRO(1688, __VA_ARGS__) \
+MU_DO_1687(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1689(MACRO, ...) \
+MACRO(1689, __VA_ARGS__) \
+MU_DO_1688(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1690(MACRO, ...) \
+MACRO(1690, __VA_ARGS__) \
+MU_DO_1689(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1691(MACRO, ...) \
+MACRO(1691, __VA_ARGS__) \
+MU_DO_1690(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1692(MACRO, ...) \
+MACRO(1692, __VA_ARGS__) \
+MU_DO_1691(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1693(MACRO, ...) \
+MACRO(1693, __VA_ARGS__) \
+MU_DO_1692(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1694(MACRO, ...) \
+MACRO(1694, __VA_ARGS__) \
+MU_DO_1693(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1695(MACRO, ...) \
+MACRO(1695, __VA_ARGS__) \
+MU_DO_1694(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1696(MACRO, ...) \
+MACRO(1696, __VA_ARGS__) \
+MU_DO_1695(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1697(MACRO, ...) \
+MACRO(1697, __VA_ARGS__) \
+MU_DO_1696(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1698(MACRO, ...) \
+MACRO(1698, __VA_ARGS__) \
+MU_DO_1697(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1699(MACRO, ...) \
+MACRO(1699, __VA_ARGS__) \
+MU_DO_1698(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1700(MACRO, ...) \
+MACRO(1700, __VA_ARGS__) \
+MU_DO_1699(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1701(MACRO, ...) \
+MACRO(1701, __VA_ARGS__) \
+MU_DO_1700(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1702(MACRO, ...) \
+MACRO(1702, __VA_ARGS__) \
+MU_DO_1701(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1703(MACRO, ...) \
+MACRO(1703, __VA_ARGS__) \
+MU_DO_1702(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1704(MACRO, ...) \
+MACRO(1704, __VA_ARGS__) \
+MU_DO_1703(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1705(MACRO, ...) \
+MACRO(1705, __VA_ARGS__) \
+MU_DO_1704(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1706(MACRO, ...) \
+MACRO(1706, __VA_ARGS__) \
+MU_DO_1705(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1707(MACRO, ...) \
+MACRO(1707, __VA_ARGS__) \
+MU_DO_1706(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1708(MACRO, ...) \
+MACRO(1708, __VA_ARGS__) \
+MU_DO_1707(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1709(MACRO, ...) \
+MACRO(1709, __VA_ARGS__) \
+MU_DO_1708(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1710(MACRO, ...) \
+MACRO(1710, __VA_ARGS__) \
+MU_DO_1709(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1711(MACRO, ...) \
+MACRO(1711, __VA_ARGS__) \
+MU_DO_1710(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1712(MACRO, ...) \
+MACRO(1712, __VA_ARGS__) \
+MU_DO_1711(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1713(MACRO, ...) \
+MACRO(1713, __VA_ARGS__) \
+MU_DO_1712(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1714(MACRO, ...) \
+MACRO(1714, __VA_ARGS__) \
+MU_DO_1713(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1715(MACRO, ...) \
+MACRO(1715, __VA_ARGS__) \
+MU_DO_1714(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1716(MACRO, ...) \
+MACRO(1716, __VA_ARGS__) \
+MU_DO_1715(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1717(MACRO, ...) \
+MACRO(1717, __VA_ARGS__) \
+MU_DO_1716(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1718(MACRO, ...) \
+MACRO(1718, __VA_ARGS__) \
+MU_DO_1717(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1719(MACRO, ...) \
+MACRO(1719, __VA_ARGS__) \
+MU_DO_1718(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1720(MACRO, ...) \
+MACRO(1720, __VA_ARGS__) \
+MU_DO_1719(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1721(MACRO, ...) \
+MACRO(1721, __VA_ARGS__) \
+MU_DO_1720(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1722(MACRO, ...) \
+MACRO(1722, __VA_ARGS__) \
+MU_DO_1721(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1723(MACRO, ...) \
+MACRO(1723, __VA_ARGS__) \
+MU_DO_1722(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1724(MACRO, ...) \
+MACRO(1724, __VA_ARGS__) \
+MU_DO_1723(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1725(MACRO, ...) \
+MACRO(1725, __VA_ARGS__) \
+MU_DO_1724(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1726(MACRO, ...) \
+MACRO(1726, __VA_ARGS__) \
+MU_DO_1725(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1727(MACRO, ...) \
+MACRO(1727, __VA_ARGS__) \
+MU_DO_1726(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1728(MACRO, ...) \
+MACRO(1728, __VA_ARGS__) \
+MU_DO_1727(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1729(MACRO, ...) \
+MACRO(1729, __VA_ARGS__) \
+MU_DO_1728(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1730(MACRO, ...) \
+MACRO(1730, __VA_ARGS__) \
+MU_DO_1729(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1731(MACRO, ...) \
+MACRO(1731, __VA_ARGS__) \
+MU_DO_1730(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1732(MACRO, ...) \
+MACRO(1732, __VA_ARGS__) \
+MU_DO_1731(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1733(MACRO, ...) \
+MACRO(1733, __VA_ARGS__) \
+MU_DO_1732(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1734(MACRO, ...) \
+MACRO(1734, __VA_ARGS__) \
+MU_DO_1733(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1735(MACRO, ...) \
+MACRO(1735, __VA_ARGS__) \
+MU_DO_1734(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1736(MACRO, ...) \
+MACRO(1736, __VA_ARGS__) \
+MU_DO_1735(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1737(MACRO, ...) \
+MACRO(1737, __VA_ARGS__) \
+MU_DO_1736(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1738(MACRO, ...) \
+MACRO(1738, __VA_ARGS__) \
+MU_DO_1737(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1739(MACRO, ...) \
+MACRO(1739, __VA_ARGS__) \
+MU_DO_1738(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1740(MACRO, ...) \
+MACRO(1740, __VA_ARGS__) \
+MU_DO_1739(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1741(MACRO, ...) \
+MACRO(1741, __VA_ARGS__) \
+MU_DO_1740(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1742(MACRO, ...) \
+MACRO(1742, __VA_ARGS__) \
+MU_DO_1741(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1743(MACRO, ...) \
+MACRO(1743, __VA_ARGS__) \
+MU_DO_1742(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1744(MACRO, ...) \
+MACRO(1744, __VA_ARGS__) \
+MU_DO_1743(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1745(MACRO, ...) \
+MACRO(1745, __VA_ARGS__) \
+MU_DO_1744(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1746(MACRO, ...) \
+MACRO(1746, __VA_ARGS__) \
+MU_DO_1745(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1747(MACRO, ...) \
+MACRO(1747, __VA_ARGS__) \
+MU_DO_1746(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1748(MACRO, ...) \
+MACRO(1748, __VA_ARGS__) \
+MU_DO_1747(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1749(MACRO, ...) \
+MACRO(1749, __VA_ARGS__) \
+MU_DO_1748(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1750(MACRO, ...) \
+MACRO(1750, __VA_ARGS__) \
+MU_DO_1749(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1751(MACRO, ...) \
+MACRO(1751, __VA_ARGS__) \
+MU_DO_1750(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1752(MACRO, ...) \
+MACRO(1752, __VA_ARGS__) \
+MU_DO_1751(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1753(MACRO, ...) \
+MACRO(1753, __VA_ARGS__) \
+MU_DO_1752(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1754(MACRO, ...) \
+MACRO(1754, __VA_ARGS__) \
+MU_DO_1753(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1755(MACRO, ...) \
+MACRO(1755, __VA_ARGS__) \
+MU_DO_1754(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1756(MACRO, ...) \
+MACRO(1756, __VA_ARGS__) \
+MU_DO_1755(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1757(MACRO, ...) \
+MACRO(1757, __VA_ARGS__) \
+MU_DO_1756(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1758(MACRO, ...) \
+MACRO(1758, __VA_ARGS__) \
+MU_DO_1757(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1759(MACRO, ...) \
+MACRO(1759, __VA_ARGS__) \
+MU_DO_1758(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1760(MACRO, ...) \
+MACRO(1760, __VA_ARGS__) \
+MU_DO_1759(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1761(MACRO, ...) \
+MACRO(1761, __VA_ARGS__) \
+MU_DO_1760(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1762(MACRO, ...) \
+MACRO(1762, __VA_ARGS__) \
+MU_DO_1761(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1763(MACRO, ...) \
+MACRO(1763, __VA_ARGS__) \
+MU_DO_1762(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1764(MACRO, ...) \
+MACRO(1764, __VA_ARGS__) \
+MU_DO_1763(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1765(MACRO, ...) \
+MACRO(1765, __VA_ARGS__) \
+MU_DO_1764(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1766(MACRO, ...) \
+MACRO(1766, __VA_ARGS__) \
+MU_DO_1765(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1767(MACRO, ...) \
+MACRO(1767, __VA_ARGS__) \
+MU_DO_1766(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1768(MACRO, ...) \
+MACRO(1768, __VA_ARGS__) \
+MU_DO_1767(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1769(MACRO, ...) \
+MACRO(1769, __VA_ARGS__) \
+MU_DO_1768(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1770(MACRO, ...) \
+MACRO(1770, __VA_ARGS__) \
+MU_DO_1769(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1771(MACRO, ...) \
+MACRO(1771, __VA_ARGS__) \
+MU_DO_1770(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1772(MACRO, ...) \
+MACRO(1772, __VA_ARGS__) \
+MU_DO_1771(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1773(MACRO, ...) \
+MACRO(1773, __VA_ARGS__) \
+MU_DO_1772(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1774(MACRO, ...) \
+MACRO(1774, __VA_ARGS__) \
+MU_DO_1773(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1775(MACRO, ...) \
+MACRO(1775, __VA_ARGS__) \
+MU_DO_1774(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1776(MACRO, ...) \
+MACRO(1776, __VA_ARGS__) \
+MU_DO_1775(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1777(MACRO, ...) \
+MACRO(1777, __VA_ARGS__) \
+MU_DO_1776(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1778(MACRO, ...) \
+MACRO(1778, __VA_ARGS__) \
+MU_DO_1777(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1779(MACRO, ...) \
+MACRO(1779, __VA_ARGS__) \
+MU_DO_1778(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1780(MACRO, ...) \
+MACRO(1780, __VA_ARGS__) \
+MU_DO_1779(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1781(MACRO, ...) \
+MACRO(1781, __VA_ARGS__) \
+MU_DO_1780(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1782(MACRO, ...) \
+MACRO(1782, __VA_ARGS__) \
+MU_DO_1781(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1783(MACRO, ...) \
+MACRO(1783, __VA_ARGS__) \
+MU_DO_1782(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1784(MACRO, ...) \
+MACRO(1784, __VA_ARGS__) \
+MU_DO_1783(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1785(MACRO, ...) \
+MACRO(1785, __VA_ARGS__) \
+MU_DO_1784(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1786(MACRO, ...) \
+MACRO(1786, __VA_ARGS__) \
+MU_DO_1785(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1787(MACRO, ...) \
+MACRO(1787, __VA_ARGS__) \
+MU_DO_1786(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1788(MACRO, ...) \
+MACRO(1788, __VA_ARGS__) \
+MU_DO_1787(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1789(MACRO, ...) \
+MACRO(1789, __VA_ARGS__) \
+MU_DO_1788(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1790(MACRO, ...) \
+MACRO(1790, __VA_ARGS__) \
+MU_DO_1789(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1791(MACRO, ...) \
+MACRO(1791, __VA_ARGS__) \
+MU_DO_1790(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1792(MACRO, ...) \
+MACRO(1792, __VA_ARGS__) \
+MU_DO_1791(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1793(MACRO, ...) \
+MACRO(1793, __VA_ARGS__) \
+MU_DO_1792(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1794(MACRO, ...) \
+MACRO(1794, __VA_ARGS__) \
+MU_DO_1793(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1795(MACRO, ...) \
+MACRO(1795, __VA_ARGS__) \
+MU_DO_1794(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1796(MACRO, ...) \
+MACRO(1796, __VA_ARGS__) \
+MU_DO_1795(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1797(MACRO, ...) \
+MACRO(1797, __VA_ARGS__) \
+MU_DO_1796(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1798(MACRO, ...) \
+MACRO(1798, __VA_ARGS__) \
+MU_DO_1797(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1799(MACRO, ...) \
+MACRO(1799, __VA_ARGS__) \
+MU_DO_1798(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1800(MACRO, ...) \
+MACRO(1800, __VA_ARGS__) \
+MU_DO_1799(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1801(MACRO, ...) \
+MACRO(1801, __VA_ARGS__) \
+MU_DO_1800(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1802(MACRO, ...) \
+MACRO(1802, __VA_ARGS__) \
+MU_DO_1801(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1803(MACRO, ...) \
+MACRO(1803, __VA_ARGS__) \
+MU_DO_1802(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1804(MACRO, ...) \
+MACRO(1804, __VA_ARGS__) \
+MU_DO_1803(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1805(MACRO, ...) \
+MACRO(1805, __VA_ARGS__) \
+MU_DO_1804(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1806(MACRO, ...) \
+MACRO(1806, __VA_ARGS__) \
+MU_DO_1805(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1807(MACRO, ...) \
+MACRO(1807, __VA_ARGS__) \
+MU_DO_1806(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1808(MACRO, ...) \
+MACRO(1808, __VA_ARGS__) \
+MU_DO_1807(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1809(MACRO, ...) \
+MACRO(1809, __VA_ARGS__) \
+MU_DO_1808(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1810(MACRO, ...) \
+MACRO(1810, __VA_ARGS__) \
+MU_DO_1809(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1811(MACRO, ...) \
+MACRO(1811, __VA_ARGS__) \
+MU_DO_1810(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1812(MACRO, ...) \
+MACRO(1812, __VA_ARGS__) \
+MU_DO_1811(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1813(MACRO, ...) \
+MACRO(1813, __VA_ARGS__) \
+MU_DO_1812(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1814(MACRO, ...) \
+MACRO(1814, __VA_ARGS__) \
+MU_DO_1813(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1815(MACRO, ...) \
+MACRO(1815, __VA_ARGS__) \
+MU_DO_1814(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1816(MACRO, ...) \
+MACRO(1816, __VA_ARGS__) \
+MU_DO_1815(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1817(MACRO, ...) \
+MACRO(1817, __VA_ARGS__) \
+MU_DO_1816(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1818(MACRO, ...) \
+MACRO(1818, __VA_ARGS__) \
+MU_DO_1817(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1819(MACRO, ...) \
+MACRO(1819, __VA_ARGS__) \
+MU_DO_1818(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1820(MACRO, ...) \
+MACRO(1820, __VA_ARGS__) \
+MU_DO_1819(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1821(MACRO, ...) \
+MACRO(1821, __VA_ARGS__) \
+MU_DO_1820(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1822(MACRO, ...) \
+MACRO(1822, __VA_ARGS__) \
+MU_DO_1821(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1823(MACRO, ...) \
+MACRO(1823, __VA_ARGS__) \
+MU_DO_1822(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1824(MACRO, ...) \
+MACRO(1824, __VA_ARGS__) \
+MU_DO_1823(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1825(MACRO, ...) \
+MACRO(1825, __VA_ARGS__) \
+MU_DO_1824(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1826(MACRO, ...) \
+MACRO(1826, __VA_ARGS__) \
+MU_DO_1825(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1827(MACRO, ...) \
+MACRO(1827, __VA_ARGS__) \
+MU_DO_1826(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1828(MACRO, ...) \
+MACRO(1828, __VA_ARGS__) \
+MU_DO_1827(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1829(MACRO, ...) \
+MACRO(1829, __VA_ARGS__) \
+MU_DO_1828(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1830(MACRO, ...) \
+MACRO(1830, __VA_ARGS__) \
+MU_DO_1829(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1831(MACRO, ...) \
+MACRO(1831, __VA_ARGS__) \
+MU_DO_1830(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1832(MACRO, ...) \
+MACRO(1832, __VA_ARGS__) \
+MU_DO_1831(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1833(MACRO, ...) \
+MACRO(1833, __VA_ARGS__) \
+MU_DO_1832(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1834(MACRO, ...) \
+MACRO(1834, __VA_ARGS__) \
+MU_DO_1833(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1835(MACRO, ...) \
+MACRO(1835, __VA_ARGS__) \
+MU_DO_1834(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1836(MACRO, ...) \
+MACRO(1836, __VA_ARGS__) \
+MU_DO_1835(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1837(MACRO, ...) \
+MACRO(1837, __VA_ARGS__) \
+MU_DO_1836(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1838(MACRO, ...) \
+MACRO(1838, __VA_ARGS__) \
+MU_DO_1837(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1839(MACRO, ...) \
+MACRO(1839, __VA_ARGS__) \
+MU_DO_1838(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1840(MACRO, ...) \
+MACRO(1840, __VA_ARGS__) \
+MU_DO_1839(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1841(MACRO, ...) \
+MACRO(1841, __VA_ARGS__) \
+MU_DO_1840(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1842(MACRO, ...) \
+MACRO(1842, __VA_ARGS__) \
+MU_DO_1841(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1843(MACRO, ...) \
+MACRO(1843, __VA_ARGS__) \
+MU_DO_1842(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1844(MACRO, ...) \
+MACRO(1844, __VA_ARGS__) \
+MU_DO_1843(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1845(MACRO, ...) \
+MACRO(1845, __VA_ARGS__) \
+MU_DO_1844(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1846(MACRO, ...) \
+MACRO(1846, __VA_ARGS__) \
+MU_DO_1845(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1847(MACRO, ...) \
+MACRO(1847, __VA_ARGS__) \
+MU_DO_1846(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1848(MACRO, ...) \
+MACRO(1848, __VA_ARGS__) \
+MU_DO_1847(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1849(MACRO, ...) \
+MACRO(1849, __VA_ARGS__) \
+MU_DO_1848(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1850(MACRO, ...) \
+MACRO(1850, __VA_ARGS__) \
+MU_DO_1849(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1851(MACRO, ...) \
+MACRO(1851, __VA_ARGS__) \
+MU_DO_1850(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1852(MACRO, ...) \
+MACRO(1852, __VA_ARGS__) \
+MU_DO_1851(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1853(MACRO, ...) \
+MACRO(1853, __VA_ARGS__) \
+MU_DO_1852(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1854(MACRO, ...) \
+MACRO(1854, __VA_ARGS__) \
+MU_DO_1853(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1855(MACRO, ...) \
+MACRO(1855, __VA_ARGS__) \
+MU_DO_1854(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1856(MACRO, ...) \
+MACRO(1856, __VA_ARGS__) \
+MU_DO_1855(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1857(MACRO, ...) \
+MACRO(1857, __VA_ARGS__) \
+MU_DO_1856(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1858(MACRO, ...) \
+MACRO(1858, __VA_ARGS__) \
+MU_DO_1857(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1859(MACRO, ...) \
+MACRO(1859, __VA_ARGS__) \
+MU_DO_1858(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1860(MACRO, ...) \
+MACRO(1860, __VA_ARGS__) \
+MU_DO_1859(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1861(MACRO, ...) \
+MACRO(1861, __VA_ARGS__) \
+MU_DO_1860(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1862(MACRO, ...) \
+MACRO(1862, __VA_ARGS__) \
+MU_DO_1861(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1863(MACRO, ...) \
+MACRO(1863, __VA_ARGS__) \
+MU_DO_1862(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1864(MACRO, ...) \
+MACRO(1864, __VA_ARGS__) \
+MU_DO_1863(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1865(MACRO, ...) \
+MACRO(1865, __VA_ARGS__) \
+MU_DO_1864(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1866(MACRO, ...) \
+MACRO(1866, __VA_ARGS__) \
+MU_DO_1865(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1867(MACRO, ...) \
+MACRO(1867, __VA_ARGS__) \
+MU_DO_1866(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1868(MACRO, ...) \
+MACRO(1868, __VA_ARGS__) \
+MU_DO_1867(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1869(MACRO, ...) \
+MACRO(1869, __VA_ARGS__) \
+MU_DO_1868(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1870(MACRO, ...) \
+MACRO(1870, __VA_ARGS__) \
+MU_DO_1869(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1871(MACRO, ...) \
+MACRO(1871, __VA_ARGS__) \
+MU_DO_1870(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1872(MACRO, ...) \
+MACRO(1872, __VA_ARGS__) \
+MU_DO_1871(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1873(MACRO, ...) \
+MACRO(1873, __VA_ARGS__) \
+MU_DO_1872(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1874(MACRO, ...) \
+MACRO(1874, __VA_ARGS__) \
+MU_DO_1873(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1875(MACRO, ...) \
+MACRO(1875, __VA_ARGS__) \
+MU_DO_1874(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1876(MACRO, ...) \
+MACRO(1876, __VA_ARGS__) \
+MU_DO_1875(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1877(MACRO, ...) \
+MACRO(1877, __VA_ARGS__) \
+MU_DO_1876(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1878(MACRO, ...) \
+MACRO(1878, __VA_ARGS__) \
+MU_DO_1877(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1879(MACRO, ...) \
+MACRO(1879, __VA_ARGS__) \
+MU_DO_1878(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1880(MACRO, ...) \
+MACRO(1880, __VA_ARGS__) \
+MU_DO_1879(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1881(MACRO, ...) \
+MACRO(1881, __VA_ARGS__) \
+MU_DO_1880(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1882(MACRO, ...) \
+MACRO(1882, __VA_ARGS__) \
+MU_DO_1881(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1883(MACRO, ...) \
+MACRO(1883, __VA_ARGS__) \
+MU_DO_1882(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1884(MACRO, ...) \
+MACRO(1884, __VA_ARGS__) \
+MU_DO_1883(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1885(MACRO, ...) \
+MACRO(1885, __VA_ARGS__) \
+MU_DO_1884(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1886(MACRO, ...) \
+MACRO(1886, __VA_ARGS__) \
+MU_DO_1885(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1887(MACRO, ...) \
+MACRO(1887, __VA_ARGS__) \
+MU_DO_1886(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1888(MACRO, ...) \
+MACRO(1888, __VA_ARGS__) \
+MU_DO_1887(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1889(MACRO, ...) \
+MACRO(1889, __VA_ARGS__) \
+MU_DO_1888(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1890(MACRO, ...) \
+MACRO(1890, __VA_ARGS__) \
+MU_DO_1889(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1891(MACRO, ...) \
+MACRO(1891, __VA_ARGS__) \
+MU_DO_1890(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1892(MACRO, ...) \
+MACRO(1892, __VA_ARGS__) \
+MU_DO_1891(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1893(MACRO, ...) \
+MACRO(1893, __VA_ARGS__) \
+MU_DO_1892(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1894(MACRO, ...) \
+MACRO(1894, __VA_ARGS__) \
+MU_DO_1893(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1895(MACRO, ...) \
+MACRO(1895, __VA_ARGS__) \
+MU_DO_1894(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1896(MACRO, ...) \
+MACRO(1896, __VA_ARGS__) \
+MU_DO_1895(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1897(MACRO, ...) \
+MACRO(1897, __VA_ARGS__) \
+MU_DO_1896(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1898(MACRO, ...) \
+MACRO(1898, __VA_ARGS__) \
+MU_DO_1897(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1899(MACRO, ...) \
+MACRO(1899, __VA_ARGS__) \
+MU_DO_1898(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1900(MACRO, ...) \
+MACRO(1900, __VA_ARGS__) \
+MU_DO_1899(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1901(MACRO, ...) \
+MACRO(1901, __VA_ARGS__) \
+MU_DO_1900(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1902(MACRO, ...) \
+MACRO(1902, __VA_ARGS__) \
+MU_DO_1901(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1903(MACRO, ...) \
+MACRO(1903, __VA_ARGS__) \
+MU_DO_1902(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1904(MACRO, ...) \
+MACRO(1904, __VA_ARGS__) \
+MU_DO_1903(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1905(MACRO, ...) \
+MACRO(1905, __VA_ARGS__) \
+MU_DO_1904(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1906(MACRO, ...) \
+MACRO(1906, __VA_ARGS__) \
+MU_DO_1905(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1907(MACRO, ...) \
+MACRO(1907, __VA_ARGS__) \
+MU_DO_1906(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1908(MACRO, ...) \
+MACRO(1908, __VA_ARGS__) \
+MU_DO_1907(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1909(MACRO, ...) \
+MACRO(1909, __VA_ARGS__) \
+MU_DO_1908(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1910(MACRO, ...) \
+MACRO(1910, __VA_ARGS__) \
+MU_DO_1909(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1911(MACRO, ...) \
+MACRO(1911, __VA_ARGS__) \
+MU_DO_1910(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1912(MACRO, ...) \
+MACRO(1912, __VA_ARGS__) \
+MU_DO_1911(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1913(MACRO, ...) \
+MACRO(1913, __VA_ARGS__) \
+MU_DO_1912(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1914(MACRO, ...) \
+MACRO(1914, __VA_ARGS__) \
+MU_DO_1913(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1915(MACRO, ...) \
+MACRO(1915, __VA_ARGS__) \
+MU_DO_1914(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1916(MACRO, ...) \
+MACRO(1916, __VA_ARGS__) \
+MU_DO_1915(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1917(MACRO, ...) \
+MACRO(1917, __VA_ARGS__) \
+MU_DO_1916(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1918(MACRO, ...) \
+MACRO(1918, __VA_ARGS__) \
+MU_DO_1917(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1919(MACRO, ...) \
+MACRO(1919, __VA_ARGS__) \
+MU_DO_1918(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1920(MACRO, ...) \
+MACRO(1920, __VA_ARGS__) \
+MU_DO_1919(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1921(MACRO, ...) \
+MACRO(1921, __VA_ARGS__) \
+MU_DO_1920(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1922(MACRO, ...) \
+MACRO(1922, __VA_ARGS__) \
+MU_DO_1921(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1923(MACRO, ...) \
+MACRO(1923, __VA_ARGS__) \
+MU_DO_1922(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1924(MACRO, ...) \
+MACRO(1924, __VA_ARGS__) \
+MU_DO_1923(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1925(MACRO, ...) \
+MACRO(1925, __VA_ARGS__) \
+MU_DO_1924(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1926(MACRO, ...) \
+MACRO(1926, __VA_ARGS__) \
+MU_DO_1925(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1927(MACRO, ...) \
+MACRO(1927, __VA_ARGS__) \
+MU_DO_1926(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1928(MACRO, ...) \
+MACRO(1928, __VA_ARGS__) \
+MU_DO_1927(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1929(MACRO, ...) \
+MACRO(1929, __VA_ARGS__) \
+MU_DO_1928(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1930(MACRO, ...) \
+MACRO(1930, __VA_ARGS__) \
+MU_DO_1929(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1931(MACRO, ...) \
+MACRO(1931, __VA_ARGS__) \
+MU_DO_1930(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1932(MACRO, ...) \
+MACRO(1932, __VA_ARGS__) \
+MU_DO_1931(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1933(MACRO, ...) \
+MACRO(1933, __VA_ARGS__) \
+MU_DO_1932(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1934(MACRO, ...) \
+MACRO(1934, __VA_ARGS__) \
+MU_DO_1933(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1935(MACRO, ...) \
+MACRO(1935, __VA_ARGS__) \
+MU_DO_1934(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1936(MACRO, ...) \
+MACRO(1936, __VA_ARGS__) \
+MU_DO_1935(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1937(MACRO, ...) \
+MACRO(1937, __VA_ARGS__) \
+MU_DO_1936(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1938(MACRO, ...) \
+MACRO(1938, __VA_ARGS__) \
+MU_DO_1937(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1939(MACRO, ...) \
+MACRO(1939, __VA_ARGS__) \
+MU_DO_1938(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1940(MACRO, ...) \
+MACRO(1940, __VA_ARGS__) \
+MU_DO_1939(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1941(MACRO, ...) \
+MACRO(1941, __VA_ARGS__) \
+MU_DO_1940(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1942(MACRO, ...) \
+MACRO(1942, __VA_ARGS__) \
+MU_DO_1941(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1943(MACRO, ...) \
+MACRO(1943, __VA_ARGS__) \
+MU_DO_1942(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1944(MACRO, ...) \
+MACRO(1944, __VA_ARGS__) \
+MU_DO_1943(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1945(MACRO, ...) \
+MACRO(1945, __VA_ARGS__) \
+MU_DO_1944(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1946(MACRO, ...) \
+MACRO(1946, __VA_ARGS__) \
+MU_DO_1945(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1947(MACRO, ...) \
+MACRO(1947, __VA_ARGS__) \
+MU_DO_1946(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1948(MACRO, ...) \
+MACRO(1948, __VA_ARGS__) \
+MU_DO_1947(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1949(MACRO, ...) \
+MACRO(1949, __VA_ARGS__) \
+MU_DO_1948(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1950(MACRO, ...) \
+MACRO(1950, __VA_ARGS__) \
+MU_DO_1949(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1951(MACRO, ...) \
+MACRO(1951, __VA_ARGS__) \
+MU_DO_1950(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1952(MACRO, ...) \
+MACRO(1952, __VA_ARGS__) \
+MU_DO_1951(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1953(MACRO, ...) \
+MACRO(1953, __VA_ARGS__) \
+MU_DO_1952(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1954(MACRO, ...) \
+MACRO(1954, __VA_ARGS__) \
+MU_DO_1953(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1955(MACRO, ...) \
+MACRO(1955, __VA_ARGS__) \
+MU_DO_1954(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1956(MACRO, ...) \
+MACRO(1956, __VA_ARGS__) \
+MU_DO_1955(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1957(MACRO, ...) \
+MACRO(1957, __VA_ARGS__) \
+MU_DO_1956(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1958(MACRO, ...) \
+MACRO(1958, __VA_ARGS__) \
+MU_DO_1957(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1959(MACRO, ...) \
+MACRO(1959, __VA_ARGS__) \
+MU_DO_1958(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1960(MACRO, ...) \
+MACRO(1960, __VA_ARGS__) \
+MU_DO_1959(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1961(MACRO, ...) \
+MACRO(1961, __VA_ARGS__) \
+MU_DO_1960(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1962(MACRO, ...) \
+MACRO(1962, __VA_ARGS__) \
+MU_DO_1961(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1963(MACRO, ...) \
+MACRO(1963, __VA_ARGS__) \
+MU_DO_1962(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1964(MACRO, ...) \
+MACRO(1964, __VA_ARGS__) \
+MU_DO_1963(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1965(MACRO, ...) \
+MACRO(1965, __VA_ARGS__) \
+MU_DO_1964(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1966(MACRO, ...) \
+MACRO(1966, __VA_ARGS__) \
+MU_DO_1965(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1967(MACRO, ...) \
+MACRO(1967, __VA_ARGS__) \
+MU_DO_1966(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1968(MACRO, ...) \
+MACRO(1968, __VA_ARGS__) \
+MU_DO_1967(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1969(MACRO, ...) \
+MACRO(1969, __VA_ARGS__) \
+MU_DO_1968(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1970(MACRO, ...) \
+MACRO(1970, __VA_ARGS__) \
+MU_DO_1969(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1971(MACRO, ...) \
+MACRO(1971, __VA_ARGS__) \
+MU_DO_1970(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1972(MACRO, ...) \
+MACRO(1972, __VA_ARGS__) \
+MU_DO_1971(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1973(MACRO, ...) \
+MACRO(1973, __VA_ARGS__) \
+MU_DO_1972(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1974(MACRO, ...) \
+MACRO(1974, __VA_ARGS__) \
+MU_DO_1973(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1975(MACRO, ...) \
+MACRO(1975, __VA_ARGS__) \
+MU_DO_1974(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1976(MACRO, ...) \
+MACRO(1976, __VA_ARGS__) \
+MU_DO_1975(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1977(MACRO, ...) \
+MACRO(1977, __VA_ARGS__) \
+MU_DO_1976(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1978(MACRO, ...) \
+MACRO(1978, __VA_ARGS__) \
+MU_DO_1977(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1979(MACRO, ...) \
+MACRO(1979, __VA_ARGS__) \
+MU_DO_1978(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1980(MACRO, ...) \
+MACRO(1980, __VA_ARGS__) \
+MU_DO_1979(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1981(MACRO, ...) \
+MACRO(1981, __VA_ARGS__) \
+MU_DO_1980(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1982(MACRO, ...) \
+MACRO(1982, __VA_ARGS__) \
+MU_DO_1981(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1983(MACRO, ...) \
+MACRO(1983, __VA_ARGS__) \
+MU_DO_1982(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1984(MACRO, ...) \
+MACRO(1984, __VA_ARGS__) \
+MU_DO_1983(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1985(MACRO, ...) \
+MACRO(1985, __VA_ARGS__) \
+MU_DO_1984(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1986(MACRO, ...) \
+MACRO(1986, __VA_ARGS__) \
+MU_DO_1985(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1987(MACRO, ...) \
+MACRO(1987, __VA_ARGS__) \
+MU_DO_1986(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1988(MACRO, ...) \
+MACRO(1988, __VA_ARGS__) \
+MU_DO_1987(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1989(MACRO, ...) \
+MACRO(1989, __VA_ARGS__) \
+MU_DO_1988(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1990(MACRO, ...) \
+MACRO(1990, __VA_ARGS__) \
+MU_DO_1989(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1991(MACRO, ...) \
+MACRO(1991, __VA_ARGS__) \
+MU_DO_1990(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1992(MACRO, ...) \
+MACRO(1992, __VA_ARGS__) \
+MU_DO_1991(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1993(MACRO, ...) \
+MACRO(1993, __VA_ARGS__) \
+MU_DO_1992(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1994(MACRO, ...) \
+MACRO(1994, __VA_ARGS__) \
+MU_DO_1993(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1995(MACRO, ...) \
+MACRO(1995, __VA_ARGS__) \
+MU_DO_1994(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1996(MACRO, ...) \
+MACRO(1996, __VA_ARGS__) \
+MU_DO_1995(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1997(MACRO, ...) \
+MACRO(1997, __VA_ARGS__) \
+MU_DO_1996(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1998(MACRO, ...) \
+MACRO(1998, __VA_ARGS__) \
+MU_DO_1997(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1999(MACRO, ...) \
+MACRO(1999, __VA_ARGS__) \
+MU_DO_1998(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_2000(MACRO, ...) \
+MACRO(2000, __VA_ARGS__) \
+MU_DO_1999(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_2001(MACRO, ...) \
+MACRO(2001, __VA_ARGS__) \
+MU_DO_2000(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_2002(MACRO, ...) \
+MACRO(2002, __VA_ARGS__) \
+MU_DO_2001(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_2003(MACRO, ...) \
+MACRO(2003, __VA_ARGS__) \
+MU_DO_2002(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_2004(MACRO, ...) \
+MACRO(2004, __VA_ARGS__) \
+MU_DO_2003(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_2005(MACRO, ...) \
+MACRO(2005, __VA_ARGS__) \
+MU_DO_2004(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_2006(MACRO, ...) \
+MACRO(2006, __VA_ARGS__) \
+MU_DO_2005(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_2007(MACRO, ...) \
+MACRO(2007, __VA_ARGS__) \
+MU_DO_2006(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_2008(MACRO, ...) \
+MACRO(2008, __VA_ARGS__) \
+MU_DO_2007(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_2009(MACRO, ...) \
+MACRO(2009, __VA_ARGS__) \
+MU_DO_2008(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_2010(MACRO, ...) \
+MACRO(2010, __VA_ARGS__) \
+MU_DO_2009(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_2011(MACRO, ...) \
+MACRO(2011, __VA_ARGS__) \
+MU_DO_2010(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_2012(MACRO, ...) \
+MACRO(2012, __VA_ARGS__) \
+MU_DO_2011(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_2013(MACRO, ...) \
+MACRO(2013, __VA_ARGS__) \
+MU_DO_2012(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_2014(MACRO, ...) \
+MACRO(2014, __VA_ARGS__) \
+MU_DO_2013(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_2015(MACRO, ...) \
+MACRO(2015, __VA_ARGS__) \
+MU_DO_2014(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_2016(MACRO, ...) \
+MACRO(2016, __VA_ARGS__) \
+MU_DO_2015(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_2017(MACRO, ...) \
+MACRO(2017, __VA_ARGS__) \
+MU_DO_2016(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_2018(MACRO, ...) \
+MACRO(2018, __VA_ARGS__) \
+MU_DO_2017(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_2019(MACRO, ...) \
+MACRO(2019, __VA_ARGS__) \
+MU_DO_2018(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_2020(MACRO, ...) \
+MACRO(2020, __VA_ARGS__) \
+MU_DO_2019(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_2021(MACRO, ...) \
+MACRO(2021, __VA_ARGS__) \
+MU_DO_2020(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_2022(MACRO, ...) \
+MACRO(2022, __VA_ARGS__) \
+MU_DO_2021(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_2023(MACRO, ...) \
+MACRO(2023, __VA_ARGS__) \
+MU_DO_2022(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_2024(MACRO, ...) \
+MACRO(2024, __VA_ARGS__) \
+MU_DO_2023(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_2025(MACRO, ...) \
+MACRO(2025, __VA_ARGS__) \
+MU_DO_2024(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_2026(MACRO, ...) \
+MACRO(2026, __VA_ARGS__) \
+MU_DO_2025(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_2027(MACRO, ...) \
+MACRO(2027, __VA_ARGS__) \
+MU_DO_2026(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_2028(MACRO, ...) \
+MACRO(2028, __VA_ARGS__) \
+MU_DO_2027(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_2029(MACRO, ...) \
+MACRO(2029, __VA_ARGS__) \
+MU_DO_2028(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_2030(MACRO, ...) \
+MACRO(2030, __VA_ARGS__) \
+MU_DO_2029(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_2031(MACRO, ...) \
+MACRO(2031, __VA_ARGS__) \
+MU_DO_2030(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_2032(MACRO, ...) \
+MACRO(2032, __VA_ARGS__) \
+MU_DO_2031(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_2033(MACRO, ...) \
+MACRO(2033, __VA_ARGS__) \
+MU_DO_2032(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_2034(MACRO, ...) \
+MACRO(2034, __VA_ARGS__) \
+MU_DO_2033(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_2035(MACRO, ...) \
+MACRO(2035, __VA_ARGS__) \
+MU_DO_2034(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_2036(MACRO, ...) \
+MACRO(2036, __VA_ARGS__) \
+MU_DO_2035(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_2037(MACRO, ...) \
+MACRO(2037, __VA_ARGS__) \
+MU_DO_2036(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_2038(MACRO, ...) \
+MACRO(2038, __VA_ARGS__) \
+MU_DO_2037(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_2039(MACRO, ...) \
+MACRO(2039, __VA_ARGS__) \
+MU_DO_2038(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_2040(MACRO, ...) \
+MACRO(2040, __VA_ARGS__) \
+MU_DO_2039(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_2041(MACRO, ...) \
+MACRO(2041, __VA_ARGS__) \
+MU_DO_2040(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_2042(MACRO, ...) \
+MACRO(2042, __VA_ARGS__) \
+MU_DO_2041(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_2043(MACRO, ...) \
+MACRO(2043, __VA_ARGS__) \
+MU_DO_2042(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_2044(MACRO, ...) \
+MACRO(2044, __VA_ARGS__) \
+MU_DO_2043(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_2045(MACRO, ...) \
+MACRO(2045, __VA_ARGS__) \
+MU_DO_2044(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_2046(MACRO, ...) \
+MACRO(2046, __VA_ARGS__) \
+MU_DO_2045(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_2047(MACRO, ...) \
+MACRO(2047, __VA_ARGS__) \
+MU_DO_2046(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_2048(MACRO, ...) \
+MACRO(2048, __VA_ARGS__) \
+MU_DO_2047(MACRO, __VA_ARGS__)
+
+
+
+#define MU_DO(TIMES, MACRO, ...) MU_C2(MU_DO_, TIMES)(MACRO, __VA_ARGS__)
+
+#endif /*MACRO_UTILS_GENERATED_H*/
Index: azure_iot_hub_f767zi/trunk/azure_iot_sdk/deps/parson/parson.c
===================================================================
--- azure_iot_hub_f767zi/trunk/azure_iot_sdk/deps/parson/parson.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/azure_iot_sdk/deps/parson/parson.c	(revision 457)
@@ -0,0 +1,2061 @@
+/*
+ SPDX-License-Identifier: MIT
+
+ Parson ( http://kgabis.github.com/parson/ )
+ Copyright (c) 2012 - 2019 Krzysztof Gabis
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+*/
+#ifdef _MSC_VER
+#ifndef _CRT_SECURE_NO_WARNINGS
+#define _CRT_SECURE_NO_WARNINGS
+#endif /* _CRT_SECURE_NO_WARNINGS */
+#endif /* _MSC_VER */
+
+#include "parson.h"
+
+#include <stdio.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <math.h>
+#include <errno.h>
+
+/* Apparently sscanf is not implemented in some "standard" libraries, so don't use it, if you
+ * don't have to. */
+#define sscanf THINK_TWICE_ABOUT_USING_SSCANF
+
+#define STARTING_CAPACITY 16
+#define MAX_NESTING       2048
+
+#define FLOAT_FORMAT "%1.17g" /* do not increase precision without incresing NUM_BUF_SIZE */
+#define NUM_BUF_SIZE 64 /* double printed with "%1.17g" shouldn't be longer than 25 bytes so let's be paranoid and use 64 */
+
+#define SIZEOF_TOKEN(a)       (sizeof(a) - 1)
+#define SKIP_CHAR(str)        ((*str)++)
+#define SKIP_WHITESPACES(str) while (isspace((unsigned char)(**str))) { SKIP_CHAR(str); }
+#define MAX(a, b)             ((a) > (b) ? (a) : (b))
+
+#undef malloc
+#undef free
+
+#if defined(isnan) && defined(isinf)
+#define IS_NUMBER_INVALID(x) (isnan((x)) || isinf((x)))
+#else
+#define IS_NUMBER_INVALID(x) (((x) * 0.0) != 0.0)
+#endif
+
+static JSON_Malloc_Function parson_malloc = malloc;
+static JSON_Free_Function parson_free = free;
+
+static int parson_escape_slashes = 1;
+
+#define IS_CONT(b) (((unsigned char)(b) & 0xC0) == 0x80) /* is utf-8 continuation byte */
+
+/* Type definitions */
+typedef union json_value_value {
+    char        *string;
+    double       number;
+    JSON_Object *object;
+    JSON_Array  *array;
+    int          boolean;
+    int          null;
+} JSON_Value_Value;
+
+struct json_value_t {
+    JSON_Value      *parent;
+    JSON_Value_Type  type;
+    JSON_Value_Value value;
+};
+
+struct json_object_t {
+    JSON_Value  *wrapping_value;
+    char       **names;
+    JSON_Value **values;
+    size_t       count;
+    size_t       capacity;
+};
+
+struct json_array_t {
+    JSON_Value  *wrapping_value;
+    JSON_Value **items;
+    size_t       count;
+    size_t       capacity;
+};
+
+/* Various */
+static char * read_file(const char *filename);
+static void   remove_comments(char *string, const char *start_token, const char *end_token);
+static char * parson_strndup(const char *string, size_t n);
+static char * parson_strdup(const char *string);
+static int    hex_char_to_int(char c);
+static int    parse_utf16_hex(const char *string, unsigned int *result);
+static int    num_bytes_in_utf8_sequence(unsigned char c);
+static int    verify_utf8_sequence(const unsigned char *string, int *len);
+static int    is_valid_utf8(const char *string, size_t string_len);
+static int    is_decimal(const char *string, size_t length);
+
+/* JSON Object */
+static JSON_Object * json_object_init(JSON_Value *wrapping_value);
+static JSON_Status   json_object_add(JSON_Object *object, const char *name, JSON_Value *value);
+static JSON_Status   json_object_addn(JSON_Object *object, const char *name, size_t name_len, JSON_Value *value);
+static JSON_Status   json_object_resize(JSON_Object *object, size_t new_capacity);
+static JSON_Value  * json_object_getn_value(const JSON_Object *object, const char *name, size_t name_len);
+static JSON_Status   json_object_remove_internal(JSON_Object *object, const char *name, int free_value);
+static JSON_Status   json_object_dotremove_internal(JSON_Object *object, const char *name, int free_value);
+static void          json_object_free(JSON_Object *object);
+
+/* JSON Array */
+static JSON_Array * json_array_init(JSON_Value *wrapping_value);
+static JSON_Status  json_array_add(JSON_Array *array, JSON_Value *value);
+static JSON_Status  json_array_resize(JSON_Array *array, size_t new_capacity);
+static void         json_array_free(JSON_Array *array);
+
+/* JSON Value */
+static JSON_Value * json_value_init_string_no_copy(char *string);
+
+/* Parser */
+static JSON_Status  skip_quotes(const char **string);
+static int          parse_utf16(const char **unprocessed, char **processed);
+static char *       process_string(const char *input, size_t len);
+static char *       get_quoted_string(const char **string);
+static JSON_Value * parse_object_value(const char **string, size_t nesting);
+static JSON_Value * parse_array_value(const char **string, size_t nesting);
+static JSON_Value * parse_string_value(const char **string);
+static JSON_Value * parse_boolean_value(const char **string);
+static JSON_Value * parse_number_value(const char **string);
+static JSON_Value * parse_null_value(const char **string);
+static JSON_Value * parse_value(const char **string, size_t nesting);
+
+/* Serialization */
+static int    json_serialize_to_buffer_r(const JSON_Value *value, char *buf, int level, int is_pretty, char *num_buf);
+static int    json_serialize_string(const char *string, char *buf);
+static int    append_indent(char *buf, int level);
+static int    append_string(char *buf, const char *string);
+
+/* Various */
+static char * parson_strndup(const char *string, size_t n) {
+    char *output_string = (char*)parson_malloc(n + 1);
+    if (!output_string) {
+        return NULL;
+    }
+    output_string[n] = '\0';
+    strncpy(output_string, string, n);
+    return output_string;
+}
+
+static char * parson_strdup(const char *string) {
+    return parson_strndup(string, strlen(string));
+}
+
+static int hex_char_to_int(char c) {
+    if (c >= '0' && c <= '9') {
+        return c - '0';
+    } else if (c >= 'a' && c <= 'f') {
+        return c - 'a' + 10;
+    } else if (c >= 'A' && c <= 'F') {
+        return c - 'A' + 10;
+    }
+    return -1;
+}
+
+static int parse_utf16_hex(const char *s, unsigned int *result) {
+    int x1, x2, x3, x4;
+    if (s[0] == '\0' || s[1] == '\0' || s[2] == '\0' || s[3] == '\0') {
+        return 0;
+    }
+    x1 = hex_char_to_int(s[0]);
+    x2 = hex_char_to_int(s[1]);
+    x3 = hex_char_to_int(s[2]);
+    x4 = hex_char_to_int(s[3]);
+    if (x1 == -1 || x2 == -1 || x3 == -1 || x4 == -1) {
+        return 0;
+    }
+    *result = (unsigned int)((x1 << 12) | (x2 << 8) | (x3 << 4) | x4);
+    return 1;
+}
+
+static int num_bytes_in_utf8_sequence(unsigned char c) {
+    if (c == 0xC0 || c == 0xC1 || c > 0xF4 || IS_CONT(c)) {
+        return 0;
+    } else if ((c & 0x80) == 0) {    /* 0xxxxxxx */
+        return 1;
+    } else if ((c & 0xE0) == 0xC0) { /* 110xxxxx */
+        return 2;
+    } else if ((c & 0xF0) == 0xE0) { /* 1110xxxx */
+        return 3;
+    } else if ((c & 0xF8) == 0xF0) { /* 11110xxx */
+        return 4;
+    }
+    return 0; /* won't happen */
+}
+
+static int verify_utf8_sequence(const unsigned char *string, int *len) {
+    unsigned int cp = 0;
+    *len = num_bytes_in_utf8_sequence(string[0]);
+
+    if (*len == 1) {
+        cp = string[0];
+    } else if (*len == 2 && IS_CONT(string[1])) {
+        cp = string[0] & 0x1F;
+        cp = (cp << 6) | (string[1] & 0x3F);
+    } else if (*len == 3 && IS_CONT(string[1]) && IS_CONT(string[2])) {
+        cp = ((unsigned char)string[0]) & 0xF;
+        cp = (cp << 6) | (string[1] & 0x3F);
+        cp = (cp << 6) | (string[2] & 0x3F);
+    } else if (*len == 4 && IS_CONT(string[1]) && IS_CONT(string[2]) && IS_CONT(string[3])) {
+        cp = string[0] & 0x7;
+        cp = (cp << 6) | (string[1] & 0x3F);
+        cp = (cp << 6) | (string[2] & 0x3F);
+        cp = (cp << 6) | (string[3] & 0x3F);
+    } else {
+        return 0;
+    }
+
+    /* overlong encodings */
+    if ((cp < 0x80    && *len > 1) ||
+        (cp < 0x800   && *len > 2) ||
+        (cp < 0x10000 && *len > 3)) {
+        return 0;
+    }
+
+    /* invalid unicode */
+    if (cp > 0x10FFFF) {
+        return 0;
+    }
+
+    /* surrogate halves */
+    if (cp >= 0xD800 && cp <= 0xDFFF) {
+        return 0;
+    }
+
+    return 1;
+}
+
+static int is_valid_utf8(const char *string, size_t string_len) {
+    int len = 0;
+    const char *string_end =  string + string_len;
+    while (string < string_end) {
+        if (!verify_utf8_sequence((const unsigned char*)string, &len)) {
+            return 0;
+        }
+        string += len;
+    }
+    return 1;
+}
+
+static int is_decimal(const char *string, size_t length) {
+    if (length > 1 && string[0] == '0' && string[1] != '.') {
+        return 0;
+    }
+    if (length > 2 && !strncmp(string, "-0", 2) && string[2] != '.') {
+        return 0;
+    }
+    while (length--) {
+        if (strchr("xX", string[length])) {
+            return 0;
+        }
+    }
+    return 1;
+}
+
+static char * read_file(const char * filename) {
+    FILE *fp = fopen(filename, "r");
+    size_t size_to_read = 0;
+    size_t size_read = 0;
+    long pos;
+    char *file_contents;
+    if (!fp) {
+        return NULL;
+    }
+    fseek(fp, 0L, SEEK_END);
+    pos = ftell(fp);
+    if (pos < 0) {
+        fclose(fp);
+        return NULL;
+    }
+    size_to_read = pos;
+    rewind(fp);
+    file_contents = (char*)parson_malloc(sizeof(char) * (size_to_read + 1));
+    if (!file_contents) {
+        fclose(fp);
+        return NULL;
+    }
+    size_read = fread(file_contents, 1, size_to_read, fp);
+    if (size_read == 0 || ferror(fp)) {
+        fclose(fp);
+        parson_free(file_contents);
+        return NULL;
+    }
+    fclose(fp);
+    file_contents[size_read] = '\0';
+    return file_contents;
+}
+
+static void remove_comments(char *string, const char *start_token, const char *end_token) {
+    int in_string = 0, escaped = 0;
+    size_t i;
+    char *ptr = NULL, current_char;
+    size_t start_token_len = strlen(start_token);
+    size_t end_token_len = strlen(end_token);
+    if (start_token_len == 0 || end_token_len == 0) {
+        return;
+    }
+    while ((current_char = *string) != '\0') {
+        if (current_char == '\\' && !escaped) {
+            escaped = 1;
+            string++;
+            continue;
+        } else if (current_char == '\"' && !escaped) {
+            in_string = !in_string;
+        } else if (!in_string && strncmp(string, start_token, start_token_len) == 0) {
+            for(i = 0; i < start_token_len; i++) {
+                string[i] = ' ';
+            }
+            string = string + start_token_len;
+            ptr = strstr(string, end_token);
+            if (!ptr) {
+                return;
+            }
+            for (i = 0; i < (ptr - string) + end_token_len; i++) {
+                string[i] = ' ';
+            }
+            string = ptr + end_token_len - 1;
+        }
+        escaped = 0;
+        string++;
+    }
+}
+
+/* JSON Object */
+static JSON_Object * json_object_init(JSON_Value *wrapping_value) {
+    JSON_Object *new_obj = (JSON_Object*)parson_malloc(sizeof(JSON_Object));
+    if (new_obj == NULL) {
+        return NULL;
+    }
+    new_obj->wrapping_value = wrapping_value;
+    new_obj->names = (char**)NULL;
+    new_obj->values = (JSON_Value**)NULL;
+    new_obj->capacity = 0;
+    new_obj->count = 0;
+    return new_obj;
+}
+
+static JSON_Status json_object_add(JSON_Object *object, const char *name, JSON_Value *value) {
+    if (name == NULL) {
+        return JSONFailure;
+    }
+    return json_object_addn(object, name, strlen(name), value);
+}
+
+static JSON_Status json_object_addn(JSON_Object *object, const char *name, size_t name_len, JSON_Value *value) {
+    size_t index = 0;
+    if (object == NULL || name == NULL || value == NULL) {
+        return JSONFailure;
+    }
+    if (json_object_getn_value(object, name, name_len) != NULL) {
+        return JSONFailure;
+    }
+    if (object->count >= object->capacity) {
+        size_t new_capacity = MAX(object->capacity * 2, STARTING_CAPACITY);
+        if (json_object_resize(object, new_capacity) == JSONFailure) {
+            return JSONFailure;
+        }
+    }
+    index = object->count;
+    object->names[index] = parson_strndup(name, name_len);
+    if (object->names[index] == NULL) {
+        return JSONFailure;
+    }
+    value->parent = json_object_get_wrapping_value(object);
+    object->values[index] = value;
+    object->count++;
+    return JSONSuccess;
+}
+
+static JSON_Status json_object_resize(JSON_Object *object, size_t new_capacity) {
+    char **temp_names = NULL;
+    JSON_Value **temp_values = NULL;
+
+    if ((object->names == NULL && object->values != NULL) ||
+        (object->names != NULL && object->values == NULL) ||
+        new_capacity == 0) {
+            return JSONFailure; /* Shouldn't happen */
+    }
+    temp_names = (char**)parson_malloc(new_capacity * sizeof(char*));
+    if (temp_names == NULL) {
+        return JSONFailure;
+    }
+    temp_values = (JSON_Value**)parson_malloc(new_capacity * sizeof(JSON_Value*));
+    if (temp_values == NULL) {
+        parson_free(temp_names);
+        return JSONFailure;
+    }
+    if (object->names != NULL && object->values != NULL && object->count > 0) {
+        memcpy(temp_names, object->names, object->count * sizeof(char*));
+        memcpy(temp_values, object->values, object->count * sizeof(JSON_Value*));
+    }
+    parson_free(object->names);
+    parson_free(object->values);
+    object->names = temp_names;
+    object->values = temp_values;
+    object->capacity = new_capacity;
+    return JSONSuccess;
+}
+
+static JSON_Value * json_object_getn_value(const JSON_Object *object, const char *name, size_t name_len) {
+    size_t i, name_length;
+    for (i = 0; i < json_object_get_count(object); i++) {
+        name_length = strlen(object->names[i]);
+        if (name_length != name_len) {
+            continue;
+        }
+        if (strncmp(object->names[i], name, name_len) == 0) {
+            return object->values[i];
+        }
+    }
+    return NULL;
+}
+
+static JSON_Status json_object_remove_internal(JSON_Object *object, const char *name, int free_value) {
+    size_t i = 0, last_item_index = 0;
+    if (object == NULL || json_object_get_value(object, name) == NULL) {
+        return JSONFailure;
+    }
+    last_item_index = json_object_get_count(object) - 1;
+    for (i = 0; i < json_object_get_count(object); i++) {
+        if (strcmp(object->names[i], name) == 0) {
+            parson_free(object->names[i]);
+            if (free_value) {
+                json_value_free(object->values[i]);
+            }
+            if (i != last_item_index) { /* Replace key value pair with one from the end */
+                object->names[i] = object->names[last_item_index];
+                object->values[i] = object->values[last_item_index];
+            }
+            object->count -= 1;
+            return JSONSuccess;
+        }
+    }
+    return JSONFailure; /* No execution path should end here */
+}
+
+static JSON_Status json_object_dotremove_internal(JSON_Object *object, const char *name, int free_value) {
+    JSON_Value *temp_value = NULL;
+    JSON_Object *temp_object = NULL;
+    const char *dot_pos = strchr(name, '.');
+    if (dot_pos == NULL) {
+        return json_object_remove_internal(object, name, free_value);
+    }
+    temp_value = json_object_getn_value(object, name, dot_pos - name);
+    if (json_value_get_type(temp_value) != JSONObject) {
+        return JSONFailure;
+    }
+    temp_object = json_value_get_object(temp_value);
+    return json_object_dotremove_internal(temp_object, dot_pos + 1, free_value);
+}
+
+static void json_object_free(JSON_Object *object) {
+    size_t i;
+    for (i = 0; i < object->count; i++) {
+        parson_free(object->names[i]);
+        json_value_free(object->values[i]);
+    }
+    parson_free(object->names);
+    parson_free(object->values);
+    parson_free(object);
+}
+
+/* JSON Array */
+static JSON_Array * json_array_init(JSON_Value *wrapping_value) {
+    JSON_Array *new_array = (JSON_Array*)parson_malloc(sizeof(JSON_Array));
+    if (new_array == NULL) {
+        return NULL;
+    }
+    new_array->wrapping_value = wrapping_value;
+    new_array->items = (JSON_Value**)NULL;
+    new_array->capacity = 0;
+    new_array->count = 0;
+    return new_array;
+}
+
+static JSON_Status json_array_add(JSON_Array *array, JSON_Value *value) {
+    if (array->count >= array->capacity) {
+        size_t new_capacity = MAX(array->capacity * 2, STARTING_CAPACITY);
+        if (json_array_resize(array, new_capacity) == JSONFailure) {
+            return JSONFailure;
+        }
+    }
+    value->parent = json_array_get_wrapping_value(array);
+    array->items[array->count] = value;
+    array->count++;
+    return JSONSuccess;
+}
+
+static JSON_Status json_array_resize(JSON_Array *array, size_t new_capacity) {
+    JSON_Value **new_items = NULL;
+    if (new_capacity == 0) {
+        return JSONFailure;
+    }
+    new_items = (JSON_Value**)parson_malloc(new_capacity * sizeof(JSON_Value*));
+    if (new_items == NULL) {
+        return JSONFailure;
+    }
+    if (array->items != NULL && array->count > 0) {
+        memcpy(new_items, array->items, array->count * sizeof(JSON_Value*));
+    }
+    parson_free(array->items);
+    array->items = new_items;
+    array->capacity = new_capacity;
+    return JSONSuccess;
+}
+
+static void json_array_free(JSON_Array *array) {
+    size_t i;
+    for (i = 0; i < array->count; i++) {
+        json_value_free(array->items[i]);
+    }
+    parson_free(array->items);
+    parson_free(array);
+}
+
+/* JSON Value */
+static JSON_Value * json_value_init_string_no_copy(char *string) {
+    JSON_Value *new_value = (JSON_Value*)parson_malloc(sizeof(JSON_Value));
+    if (!new_value) {
+        return NULL;
+    }
+    new_value->parent = NULL;
+    new_value->type = JSONString;
+    new_value->value.string = string;
+    return new_value;
+}
+
+/* Parser */
+static JSON_Status skip_quotes(const char **string) {
+    if (**string != '\"') {
+        return JSONFailure;
+    }
+    SKIP_CHAR(string);
+    while (**string != '\"') {
+        if (**string == '\0') {
+            return JSONFailure;
+        } else if (**string == '\\') {
+            SKIP_CHAR(string);
+            if (**string == '\0') {
+                return JSONFailure;
+            }
+        }
+        SKIP_CHAR(string);
+    }
+    SKIP_CHAR(string);
+    return JSONSuccess;
+}
+
+static int parse_utf16(const char **unprocessed, char **processed) {
+    unsigned int cp, lead, trail;
+    int parse_succeeded = 0;
+    char *processed_ptr = *processed;
+    const char *unprocessed_ptr = *unprocessed;
+    unprocessed_ptr++; /* skips u */
+    parse_succeeded = parse_utf16_hex(unprocessed_ptr, &cp);
+    if (!parse_succeeded) {
+        return JSONFailure;
+    }
+    if (cp < 0x80) {
+        processed_ptr[0] = (char)cp; /* 0xxxxxxx */
+    } else if (cp < 0x800) {
+        processed_ptr[0] = ((cp >> 6) & 0x1F) | 0xC0; /* 110xxxxx */
+        processed_ptr[1] = ((cp)      & 0x3F) | 0x80; /* 10xxxxxx */
+        processed_ptr += 1;
+    } else if (cp < 0xD800 || cp > 0xDFFF) {
+        processed_ptr[0] = ((cp >> 12) & 0x0F) | 0xE0; /* 1110xxxx */
+        processed_ptr[1] = ((cp >> 6)  & 0x3F) | 0x80; /* 10xxxxxx */
+        processed_ptr[2] = ((cp)       & 0x3F) | 0x80; /* 10xxxxxx */
+        processed_ptr += 2;
+    } else if (cp >= 0xD800 && cp <= 0xDBFF) { /* lead surrogate (0xD800..0xDBFF) */
+        lead = cp;
+        unprocessed_ptr += 4; /* should always be within the buffer, otherwise previous sscanf would fail */
+        if (*unprocessed_ptr++ != '\\' || *unprocessed_ptr++ != 'u') {
+            return JSONFailure;
+        }
+        parse_succeeded = parse_utf16_hex(unprocessed_ptr, &trail);
+        if (!parse_succeeded || trail < 0xDC00 || trail > 0xDFFF) { /* valid trail surrogate? (0xDC00..0xDFFF) */
+            return JSONFailure;
+        }
+        cp = ((((lead - 0xD800) & 0x3FF) << 10) | ((trail - 0xDC00) & 0x3FF)) + 0x010000;
+        processed_ptr[0] = (((cp >> 18) & 0x07) | 0xF0); /* 11110xxx */
+        processed_ptr[1] = (((cp >> 12) & 0x3F) | 0x80); /* 10xxxxxx */
+        processed_ptr[2] = (((cp >> 6)  & 0x3F) | 0x80); /* 10xxxxxx */
+        processed_ptr[3] = (((cp)       & 0x3F) | 0x80); /* 10xxxxxx */
+        processed_ptr += 3;
+    } else { /* trail surrogate before lead surrogate */
+        return JSONFailure;
+    }
+    unprocessed_ptr += 3;
+    *processed = processed_ptr;
+    *unprocessed = unprocessed_ptr;
+    return JSONSuccess;
+}
+
+
+/* Copies and processes passed string up to supplied length.
+Example: "\u006Corem ipsum" -> lorem ipsum */
+static char* process_string(const char *input, size_t len) {
+    const char *input_ptr = input;
+    size_t initial_size = (len + 1) * sizeof(char);
+    size_t final_size = 0;
+    char *output = NULL, *output_ptr = NULL, *resized_output = NULL;
+    output = (char*)parson_malloc(initial_size);
+    if (output == NULL) {
+        goto error;
+    }
+    output_ptr = output;
+    while ((*input_ptr != '\0') && (size_t)(input_ptr - input) < len) {
+        if (*input_ptr == '\\') {
+            input_ptr++;
+            switch (*input_ptr) {
+                case '\"': *output_ptr = '\"'; break;
+                case '\\': *output_ptr = '\\'; break;
+                case '/':  *output_ptr = '/';  break;
+                case 'b':  *output_ptr = '\b'; break;
+                case 'f':  *output_ptr = '\f'; break;
+                case 'n':  *output_ptr = '\n'; break;
+                case 'r':  *output_ptr = '\r'; break;
+                case 't':  *output_ptr = '\t'; break;
+                case 'u':
+                    if (parse_utf16(&input_ptr, &output_ptr) == JSONFailure) {
+                        goto error;
+                    }
+                    break;
+                default:
+                    goto error;
+            }
+        } else if ((unsigned char)*input_ptr < 0x20) {
+            goto error; /* 0x00-0x19 are invalid characters for json string (http://www.ietf.org/rfc/rfc4627.txt) */
+        } else {
+            *output_ptr = *input_ptr;
+        }
+        output_ptr++;
+        input_ptr++;
+    }
+    *output_ptr = '\0';
+    /* resize to new length */
+    final_size = (size_t)(output_ptr-output) + 1;
+    /* todo: don't resize if final_size == initial_size */
+    resized_output = (char*)parson_malloc(final_size);
+    if (resized_output == NULL) {
+        goto error;
+    }
+    memcpy(resized_output, output, final_size);
+    parson_free(output);
+    return resized_output;
+error:
+    parson_free(output);
+    return NULL;
+}
+
+/* Return processed contents of a string between quotes and
+   skips passed argument to a matching quote. */
+static char * get_quoted_string(const char **string) {
+    const char *string_start = *string;
+    size_t string_len = 0;
+    JSON_Status status = skip_quotes(string);
+    if (status != JSONSuccess) {
+        return NULL;
+    }
+    string_len = *string - string_start - 2; /* length without quotes */
+    return process_string(string_start + 1, string_len);
+}
+
+static JSON_Value * parse_value(const char **string, size_t nesting) {
+    if (nesting > MAX_NESTING) {
+        return NULL;
+    }
+    SKIP_WHITESPACES(string);
+    switch (**string) {
+        case '{':
+            return parse_object_value(string, nesting + 1);
+        case '[':
+            return parse_array_value(string, nesting + 1);
+        case '\"':
+            return parse_string_value(string);
+        case 'f': case 't':
+            return parse_boolean_value(string);
+        case '-':
+        case '0': case '1': case '2': case '3': case '4':
+        case '5': case '6': case '7': case '8': case '9':
+            return parse_number_value(string);
+        case 'n':
+            return parse_null_value(string);
+        default:
+            return NULL;
+    }
+}
+
+static JSON_Value * parse_object_value(const char **string, size_t nesting) {
+    JSON_Value *output_value = NULL, *new_value = NULL;
+    JSON_Object *output_object = NULL;
+    char *new_key = NULL;
+    output_value = json_value_init_object();
+    if (output_value == NULL) {
+        return NULL;
+    }
+    if (**string != '{') {
+        json_value_free(output_value);
+        return NULL;
+    }
+    output_object = json_value_get_object(output_value);
+    SKIP_CHAR(string);
+    SKIP_WHITESPACES(string);
+    if (**string == '}') { /* empty object */
+        SKIP_CHAR(string);
+        return output_value;
+    }
+    while (**string != '\0') {
+        new_key = get_quoted_string(string);
+        if (new_key == NULL) {
+            json_value_free(output_value);
+            return NULL;
+        }
+        SKIP_WHITESPACES(string);
+        if (**string != ':') {
+            parson_free(new_key);
+            json_value_free(output_value);
+            return NULL;
+        }
+        SKIP_CHAR(string);
+        new_value = parse_value(string, nesting);
+        if (new_value == NULL) {
+            parson_free(new_key);
+            json_value_free(output_value);
+            return NULL;
+        }
+        if (json_object_add(output_object, new_key, new_value) == JSONFailure) {
+            parson_free(new_key);
+            json_value_free(new_value);
+            json_value_free(output_value);
+            return NULL;
+        }
+        parson_free(new_key);
+        SKIP_WHITESPACES(string);
+        if (**string != ',') {
+            break;
+        }
+        SKIP_CHAR(string);
+        SKIP_WHITESPACES(string);
+    }
+    SKIP_WHITESPACES(string);
+    if (**string != '}' || /* Trim object after parsing is over */
+        json_object_resize(output_object, json_object_get_count(output_object)) == JSONFailure) {
+            json_value_free(output_value);
+            return NULL;
+    }
+    SKIP_CHAR(string);
+    return output_value;
+}
+
+static JSON_Value * parse_array_value(const char **string, size_t nesting) {
+    JSON_Value *output_value = NULL, *new_array_value = NULL;
+    JSON_Array *output_array = NULL;
+    output_value = json_value_init_array();
+    if (output_value == NULL) {
+        return NULL;
+    }
+    if (**string != '[') {
+        json_value_free(output_value);
+        return NULL;
+    }
+    output_array = json_value_get_array(output_value);
+    SKIP_CHAR(string);
+    SKIP_WHITESPACES(string);
+    if (**string == ']') { /* empty array */
+        SKIP_CHAR(string);
+        return output_value;
+    }
+    while (**string != '\0') {
+        new_array_value = parse_value(string, nesting);
+        if (new_array_value == NULL) {
+            json_value_free(output_value);
+            return NULL;
+        }
+        if (json_array_add(output_array, new_array_value) == JSONFailure) {
+            json_value_free(new_array_value);
+            json_value_free(output_value);
+            return NULL;
+        }
+        SKIP_WHITESPACES(string);
+        if (**string != ',') {
+            break;
+        }
+        SKIP_CHAR(string);
+        SKIP_WHITESPACES(string);
+    }
+    SKIP_WHITESPACES(string);
+    if (**string != ']' || /* Trim array after parsing is over */
+        json_array_resize(output_array, json_array_get_count(output_array)) == JSONFailure) {
+            json_value_free(output_value);
+            return NULL;
+    }
+    SKIP_CHAR(string);
+    return output_value;
+}
+
+static JSON_Value * parse_string_value(const char **string) {
+    JSON_Value *value = NULL;
+    char *new_string = get_quoted_string(string);
+    if (new_string == NULL) {
+        return NULL;
+    }
+    value = json_value_init_string_no_copy(new_string);
+    if (value == NULL) {
+        parson_free(new_string);
+        return NULL;
+    }
+    return value;
+}
+
+static JSON_Value * parse_boolean_value(const char **string) {
+    size_t true_token_size = SIZEOF_TOKEN("true");
+    size_t false_token_size = SIZEOF_TOKEN("false");
+    if (strncmp("true", *string, true_token_size) == 0) {
+        *string += true_token_size;
+        return json_value_init_boolean(1);
+    } else if (strncmp("false", *string, false_token_size) == 0) {
+        *string += false_token_size;
+        return json_value_init_boolean(0);
+    }
+    return NULL;
+}
+
+static JSON_Value * parse_number_value(const char **string) {
+    char *end;
+    double number = 0;
+    errno = 0;
+    number = strtod(*string, &end);
+    if (errno || !is_decimal(*string, end - *string)) {
+        return NULL;
+    }
+    *string = end;
+    return json_value_init_number(number);
+}
+
+static JSON_Value * parse_null_value(const char **string) {
+    size_t token_size = SIZEOF_TOKEN("null");
+    if (strncmp("null", *string, token_size) == 0) {
+        *string += token_size;
+        return json_value_init_null();
+    }
+    return NULL;
+}
+
+/* Serialization */
+#define APPEND_STRING(str) do { written = append_string(buf, (str));\
+                                if (written < 0) { return -1; }\
+                                if (buf != NULL) { buf += written; }\
+                                written_total += written; } while(0)
+
+#define APPEND_INDENT(level) do { written = append_indent(buf, (level));\
+                                  if (written < 0) { return -1; }\
+                                  if (buf != NULL) { buf += written; }\
+                                  written_total += written; } while(0)
+
+static int json_serialize_to_buffer_r(const JSON_Value *value, char *buf, int level, int is_pretty, char *num_buf)
+{
+    const char *key = NULL, *string = NULL;
+    JSON_Value *temp_value = NULL;
+    JSON_Array *array = NULL;
+    JSON_Object *object = NULL;
+    size_t i = 0, count = 0;
+    double num = 0.0;
+    int written = -1, written_total = 0;
+
+    switch (json_value_get_type(value)) {
+        case JSONArray:
+            array = json_value_get_array(value);
+            count = json_array_get_count(array);
+            APPEND_STRING("[");
+            if (count > 0 && is_pretty) {
+                APPEND_STRING("\n");
+            }
+            for (i = 0; i < count; i++) {
+                if (is_pretty) {
+                    APPEND_INDENT(level+1);
+                }
+                temp_value = json_array_get_value(array, i);
+                written = json_serialize_to_buffer_r(temp_value, buf, level+1, is_pretty, num_buf);
+                if (written < 0) {
+                    return -1;
+                }
+                if (buf != NULL) {
+                    buf += written;
+                }
+                written_total += written;
+                if (i < (count - 1)) {
+                    APPEND_STRING(",");
+                }
+                if (is_pretty) {
+                    APPEND_STRING("\n");
+                }
+            }
+            if (count > 0 && is_pretty) {
+                APPEND_INDENT(level);
+            }
+            APPEND_STRING("]");
+            return written_total;
+        case JSONObject:
+            object = json_value_get_object(value);
+            count  = json_object_get_count(object);
+            APPEND_STRING("{");
+            if (count > 0 && is_pretty) {
+                APPEND_STRING("\n");
+            }
+            for (i = 0; i < count; i++) {
+                key = json_object_get_name(object, i);
+                if (key == NULL) {
+                    return -1;
+                }
+                if (is_pretty) {
+                    APPEND_INDENT(level+1);
+                }
+                written = json_serialize_string(key, buf);
+                if (written < 0) {
+                    return -1;
+                }
+                if (buf != NULL) {
+                    buf += written;
+                }
+                written_total += written;
+                APPEND_STRING(":");
+                if (is_pretty) {
+                    APPEND_STRING(" ");
+                }
+                temp_value = json_object_get_value(object, key);
+                written = json_serialize_to_buffer_r(temp_value, buf, level+1, is_pretty, num_buf);
+                if (written < 0) {
+                    return -1;
+                }
+                if (buf != NULL) {
+                    buf += written;
+                }
+                written_total += written;
+                if (i < (count - 1)) {
+                    APPEND_STRING(",");
+                }
+                if (is_pretty) {
+                    APPEND_STRING("\n");
+                }
+            }
+            if (count > 0 && is_pretty) {
+                APPEND_INDENT(level);
+            }
+            APPEND_STRING("}");
+            return written_total;
+        case JSONString:
+            string = json_value_get_string(value);
+            if (string == NULL) {
+                return -1;
+            }
+            written = json_serialize_string(string, buf);
+            if (written < 0) {
+                return -1;
+            }
+            if (buf != NULL) {
+                buf += written;
+            }
+            written_total += written;
+            return written_total;
+        case JSONBoolean:
+            if (json_value_get_boolean(value)) {
+                APPEND_STRING("true");
+            } else {
+                APPEND_STRING("false");
+            }
+            return written_total;
+        case JSONNumber:
+            num = json_value_get_number(value);
+            if (buf != NULL) {
+                num_buf = buf;
+            }
+            written = sprintf(num_buf, FLOAT_FORMAT, num);
+            if (written < 0) {
+                return -1;
+            }
+            if (buf != NULL) {
+                buf += written;
+            }
+            written_total += written;
+            return written_total;
+        case JSONNull:
+            APPEND_STRING("null");
+            return written_total;
+        case JSONError:
+            return -1;
+        default:
+            return -1;
+    }
+}
+
+static int json_serialize_string(const char *string, char *buf) {
+    size_t i = 0, len = strlen(string);
+    char c = '\0';
+    int written = -1, written_total = 0;
+    APPEND_STRING("\"");
+    for (i = 0; i < len; i++) {
+        c = string[i];
+        switch (c) {
+            case '\"': APPEND_STRING("\\\""); break;
+            case '\\': APPEND_STRING("\\\\"); break;
+            case '\b': APPEND_STRING("\\b"); break;
+            case '\f': APPEND_STRING("\\f"); break;
+            case '\n': APPEND_STRING("\\n"); break;
+            case '\r': APPEND_STRING("\\r"); break;
+            case '\t': APPEND_STRING("\\t"); break;
+            case '\x00': APPEND_STRING("\\u0000"); break;
+            case '\x01': APPEND_STRING("\\u0001"); break;
+            case '\x02': APPEND_STRING("\\u0002"); break;
+            case '\x03': APPEND_STRING("\\u0003"); break;
+            case '\x04': APPEND_STRING("\\u0004"); break;
+            case '\x05': APPEND_STRING("\\u0005"); break;
+            case '\x06': APPEND_STRING("\\u0006"); break;
+            case '\x07': APPEND_STRING("\\u0007"); break;
+            /* '\x08' duplicate: '\b' */
+            /* '\x09' duplicate: '\t' */
+            /* '\x0a' duplicate: '\n' */
+            case '\x0b': APPEND_STRING("\\u000b"); break;
+            /* '\x0c' duplicate: '\f' */
+            /* '\x0d' duplicate: '\r' */
+            case '\x0e': APPEND_STRING("\\u000e"); break;
+            case '\x0f': APPEND_STRING("\\u000f"); break;
+            case '\x10': APPEND_STRING("\\u0010"); break;
+            case '\x11': APPEND_STRING("\\u0011"); break;
+            case '\x12': APPEND_STRING("\\u0012"); break;
+            case '\x13': APPEND_STRING("\\u0013"); break;
+            case '\x14': APPEND_STRING("\\u0014"); break;
+            case '\x15': APPEND_STRING("\\u0015"); break;
+            case '\x16': APPEND_STRING("\\u0016"); break;
+            case '\x17': APPEND_STRING("\\u0017"); break;
+            case '\x18': APPEND_STRING("\\u0018"); break;
+            case '\x19': APPEND_STRING("\\u0019"); break;
+            case '\x1a': APPEND_STRING("\\u001a"); break;
+            case '\x1b': APPEND_STRING("\\u001b"); break;
+            case '\x1c': APPEND_STRING("\\u001c"); break;
+            case '\x1d': APPEND_STRING("\\u001d"); break;
+            case '\x1e': APPEND_STRING("\\u001e"); break;
+            case '\x1f': APPEND_STRING("\\u001f"); break;
+            case '/':
+                if (parson_escape_slashes) {
+                    APPEND_STRING("\\/");  /* to make json embeddable in xml\/html */
+                } else {
+                    APPEND_STRING("/");
+                }
+                break;
+            default:
+                if (buf != NULL) {
+                    buf[0] = c;
+                    buf += 1;
+                }
+                written_total += 1;
+                break;
+        }
+    }
+    APPEND_STRING("\"");
+    return written_total;
+}
+
+static int append_indent(char *buf, int level) {
+    int i;
+    int written = -1, written_total = 0;
+    for (i = 0; i < level; i++) {
+        APPEND_STRING("    ");
+    }
+    return written_total;
+}
+
+static int append_string(char *buf, const char *string) {
+    if (buf == NULL) {
+        return (int)strlen(string);
+    }
+    return sprintf(buf, "%s", string);
+}
+
+#undef APPEND_STRING
+#undef APPEND_INDENT
+
+/* Parser API */
+JSON_Value * json_parse_file(const char *filename) {
+    char *file_contents = read_file(filename);
+    JSON_Value *output_value = NULL;
+    if (file_contents == NULL) {
+        return NULL;
+    }
+    output_value = json_parse_string(file_contents);
+    parson_free(file_contents);
+    return output_value;
+}
+
+JSON_Value * json_parse_file_with_comments(const char *filename) {
+    char *file_contents = read_file(filename);
+    JSON_Value *output_value = NULL;
+    if (file_contents == NULL) {
+        return NULL;
+    }
+    output_value = json_parse_string_with_comments(file_contents);
+    parson_free(file_contents);
+    return output_value;
+}
+
+JSON_Value * json_parse_string(const char *string) {
+    if (string == NULL) {
+        return NULL;
+    }
+    if (string[0] == '\xEF' && string[1] == '\xBB' && string[2] == '\xBF') {
+        string = string + 3; /* Support for UTF-8 BOM */
+    }
+    return parse_value((const char**)&string, 0);
+}
+
+JSON_Value * json_parse_string_with_comments(const char *string) {
+    JSON_Value *result = NULL;
+    char *string_mutable_copy = NULL, *string_mutable_copy_ptr = NULL;
+    string_mutable_copy = parson_strdup(string);
+    if (string_mutable_copy == NULL) {
+        return NULL;
+    }
+    remove_comments(string_mutable_copy, "/*", "*/");
+    remove_comments(string_mutable_copy, "//", "\n");
+    string_mutable_copy_ptr = string_mutable_copy;
+    result = parse_value((const char**)&string_mutable_copy_ptr, 0);
+    parson_free(string_mutable_copy);
+    return result;
+}
+
+/* JSON Object API */
+
+JSON_Value * json_object_get_value(const JSON_Object *object, const char *name) {
+    if (object == NULL || name == NULL) {
+        return NULL;
+    }
+    return json_object_getn_value(object, name, strlen(name));
+}
+
+const char * json_object_get_string(const JSON_Object *object, const char *name) {
+    return json_value_get_string(json_object_get_value(object, name));
+}
+
+double json_object_get_number(const JSON_Object *object, const char *name) {
+    return json_value_get_number(json_object_get_value(object, name));
+}
+
+JSON_Object * json_object_get_object(const JSON_Object *object, const char *name) {
+    return json_value_get_object(json_object_get_value(object, name));
+}
+
+JSON_Array * json_object_get_array(const JSON_Object *object, const char *name) {
+    return json_value_get_array(json_object_get_value(object, name));
+}
+
+int json_object_get_boolean(const JSON_Object *object, const char *name) {
+    return json_value_get_boolean(json_object_get_value(object, name));
+}
+
+JSON_Value * json_object_dotget_value(const JSON_Object *object, const char *name) {
+    const char *dot_position = strchr(name, '.');
+    if (!dot_position) {
+        return json_object_get_value(object, name);
+    }
+    object = json_value_get_object(json_object_getn_value(object, name, dot_position - name));
+    return json_object_dotget_value(object, dot_position + 1);
+}
+
+const char * json_object_dotget_string(const JSON_Object *object, const char *name) {
+    return json_value_get_string(json_object_dotget_value(object, name));
+}
+
+double json_object_dotget_number(const JSON_Object *object, const char *name) {
+    return json_value_get_number(json_object_dotget_value(object, name));
+}
+
+JSON_Object * json_object_dotget_object(const JSON_Object *object, const char *name) {
+    return json_value_get_object(json_object_dotget_value(object, name));
+}
+
+JSON_Array * json_object_dotget_array(const JSON_Object *object, const char *name) {
+    return json_value_get_array(json_object_dotget_value(object, name));
+}
+
+int json_object_dotget_boolean(const JSON_Object *object, const char *name) {
+    return json_value_get_boolean(json_object_dotget_value(object, name));
+}
+
+size_t json_object_get_count(const JSON_Object *object) {
+    return object ? object->count : 0;
+}
+
+const char * json_object_get_name(const JSON_Object *object, size_t index) {
+    if (object == NULL || index >= json_object_get_count(object)) {
+        return NULL;
+    }
+    return object->names[index];
+}
+
+JSON_Value * json_object_get_value_at(const JSON_Object *object, size_t index) {
+    if (object == NULL || index >= json_object_get_count(object)) {
+        return NULL;
+    }
+    return object->values[index];
+}
+
+JSON_Value *json_object_get_wrapping_value(const JSON_Object *object) {
+    return object->wrapping_value;
+}
+
+int json_object_has_value (const JSON_Object *object, const char *name) {
+    return json_object_get_value(object, name) != NULL;
+}
+
+int json_object_has_value_of_type(const JSON_Object *object, const char *name, JSON_Value_Type type) {
+    JSON_Value *val = json_object_get_value(object, name);
+    return val != NULL && json_value_get_type(val) == type;
+}
+
+int json_object_dothas_value (const JSON_Object *object, const char *name) {
+    return json_object_dotget_value(object, name) != NULL;
+}
+
+int json_object_dothas_value_of_type(const JSON_Object *object, const char *name, JSON_Value_Type type) {
+    JSON_Value *val = json_object_dotget_value(object, name);
+    return val != NULL && json_value_get_type(val) == type;
+}
+
+/* JSON Array API */
+JSON_Value * json_array_get_value(const JSON_Array *array, size_t index) {
+    if (array == NULL || index >= json_array_get_count(array)) {
+        return NULL;
+    }
+    return array->items[index];
+}
+
+const char * json_array_get_string(const JSON_Array *array, size_t index) {
+    return json_value_get_string(json_array_get_value(array, index));
+}
+
+double json_array_get_number(const JSON_Array *array, size_t index) {
+    return json_value_get_number(json_array_get_value(array, index));
+}
+
+JSON_Object * json_array_get_object(const JSON_Array *array, size_t index) {
+    return json_value_get_object(json_array_get_value(array, index));
+}
+
+JSON_Array * json_array_get_array(const JSON_Array *array, size_t index) {
+    return json_value_get_array(json_array_get_value(array, index));
+}
+
+int json_array_get_boolean(const JSON_Array *array, size_t index) {
+    return json_value_get_boolean(json_array_get_value(array, index));
+}
+
+size_t json_array_get_count(const JSON_Array *array) {
+    return array ? array->count : 0;
+}
+
+JSON_Value * json_array_get_wrapping_value(const JSON_Array *array) {
+    return array->wrapping_value;
+}
+
+/* JSON Value API */
+JSON_Value_Type json_value_get_type(const JSON_Value *value) {
+    return value ? value->type : JSONError;
+}
+
+JSON_Object * json_value_get_object(const JSON_Value *value) {
+    return json_value_get_type(value) == JSONObject ? value->value.object : NULL;
+}
+
+JSON_Array * json_value_get_array(const JSON_Value *value) {
+    return json_value_get_type(value) == JSONArray ? value->value.array : NULL;
+}
+
+const char * json_value_get_string(const JSON_Value *value) {
+    return json_value_get_type(value) == JSONString ? value->value.string : NULL;
+}
+
+double json_value_get_number(const JSON_Value *value) {
+    return json_value_get_type(value) == JSONNumber ? value->value.number : 0;
+}
+
+int json_value_get_boolean(const JSON_Value *value) {
+    return json_value_get_type(value) == JSONBoolean ? value->value.boolean : -1;
+}
+
+JSON_Value * json_value_get_parent (const JSON_Value *value) {
+    return value ? value->parent : NULL;
+}
+
+void json_value_free(JSON_Value *value) {
+    switch (json_value_get_type(value)) {
+        case JSONObject:
+            json_object_free(value->value.object);
+            break;
+        case JSONString:
+            parson_free(value->value.string);
+            break;
+        case JSONArray:
+            json_array_free(value->value.array);
+            break;
+        default:
+            break;
+    }
+    parson_free(value);
+}
+
+JSON_Value * json_value_init_object(void) {
+    JSON_Value *new_value = (JSON_Value*)parson_malloc(sizeof(JSON_Value));
+    if (!new_value) {
+        return NULL;
+    }
+    new_value->parent = NULL;
+    new_value->type = JSONObject;
+    new_value->value.object = json_object_init(new_value);
+    if (!new_value->value.object) {
+        parson_free(new_value);
+        return NULL;
+    }
+    return new_value;
+}
+
+JSON_Value * json_value_init_array(void) {
+    JSON_Value *new_value = (JSON_Value*)parson_malloc(sizeof(JSON_Value));
+    if (!new_value) {
+        return NULL;
+    }
+    new_value->parent = NULL;
+    new_value->type = JSONArray;
+    new_value->value.array = json_array_init(new_value);
+    if (!new_value->value.array) {
+        parson_free(new_value);
+        return NULL;
+    }
+    return new_value;
+}
+
+JSON_Value * json_value_init_string(const char *string) {
+    char *copy = NULL;
+    JSON_Value *value;
+    size_t string_len = 0;
+    if (string == NULL) {
+        return NULL;
+    }
+    string_len = strlen(string);
+    if (!is_valid_utf8(string, string_len)) {
+        return NULL;
+    }
+    copy = parson_strndup(string, string_len);
+    if (copy == NULL) {
+        return NULL;
+    }
+    value = json_value_init_string_no_copy(copy);
+    if (value == NULL) {
+        parson_free(copy);
+    }
+    return value;
+}
+
+JSON_Value * json_value_init_number(double number) {
+    JSON_Value *new_value = NULL;
+    if (IS_NUMBER_INVALID(number)) {
+        return NULL;
+    }
+    new_value = (JSON_Value*)parson_malloc(sizeof(JSON_Value));
+    if (new_value == NULL) {
+        return NULL;
+    }
+    new_value->parent = NULL;
+    new_value->type = JSONNumber;
+    new_value->value.number = number;
+    return new_value;
+}
+
+JSON_Value * json_value_init_boolean(int boolean) {
+    JSON_Value *new_value = (JSON_Value*)parson_malloc(sizeof(JSON_Value));
+    if (!new_value) {
+        return NULL;
+    }
+    new_value->parent = NULL;
+    new_value->type = JSONBoolean;
+    new_value->value.boolean = boolean ? 1 : 0;
+    return new_value;
+}
+
+JSON_Value * json_value_init_null(void) {
+    JSON_Value *new_value = (JSON_Value*)parson_malloc(sizeof(JSON_Value));
+    if (!new_value) {
+        return NULL;
+    }
+    new_value->parent = NULL;
+    new_value->type = JSONNull;
+    return new_value;
+}
+
+JSON_Value * json_value_deep_copy(const JSON_Value *value) {
+    size_t i = 0;
+    JSON_Value *return_value = NULL, *temp_value_copy = NULL, *temp_value = NULL;
+    const char *temp_string = NULL, *temp_key = NULL;
+    char *temp_string_copy = NULL;
+    JSON_Array *temp_array = NULL, *temp_array_copy = NULL;
+    JSON_Object *temp_object = NULL, *temp_object_copy = NULL;
+
+    switch (json_value_get_type(value)) {
+        case JSONArray:
+            temp_array = json_value_get_array(value);
+            return_value = json_value_init_array();
+            if (return_value == NULL) {
+                return NULL;
+            }
+            temp_array_copy = json_value_get_array(return_value);
+            for (i = 0; i < json_array_get_count(temp_array); i++) {
+                temp_value = json_array_get_value(temp_array, i);
+                temp_value_copy = json_value_deep_copy(temp_value);
+                if (temp_value_copy == NULL) {
+                    json_value_free(return_value);
+                    return NULL;
+                }
+                if (json_array_add(temp_array_copy, temp_value_copy) == JSONFailure) {
+                    json_value_free(return_value);
+                    json_value_free(temp_value_copy);
+                    return NULL;
+                }
+            }
+            return return_value;
+        case JSONObject:
+            temp_object = json_value_get_object(value);
+            return_value = json_value_init_object();
+            if (return_value == NULL) {
+                return NULL;
+            }
+            temp_object_copy = json_value_get_object(return_value);
+            for (i = 0; i < json_object_get_count(temp_object); i++) {
+                temp_key = json_object_get_name(temp_object, i);
+                temp_value = json_object_get_value(temp_object, temp_key);
+                temp_value_copy = json_value_deep_copy(temp_value);
+                if (temp_value_copy == NULL) {
+                    json_value_free(return_value);
+                    return NULL;
+                }
+                if (json_object_add(temp_object_copy, temp_key, temp_value_copy) == JSONFailure) {
+                    json_value_free(return_value);
+                    json_value_free(temp_value_copy);
+                    return NULL;
+                }
+            }
+            return return_value;
+        case JSONBoolean:
+            return json_value_init_boolean(json_value_get_boolean(value));
+        case JSONNumber:
+            return json_value_init_number(json_value_get_number(value));
+        case JSONString:
+            temp_string = json_value_get_string(value);
+            if (temp_string == NULL) {
+                return NULL;
+            }
+            temp_string_copy = parson_strdup(temp_string);
+            if (temp_string_copy == NULL) {
+                return NULL;
+            }
+            return_value = json_value_init_string_no_copy(temp_string_copy);
+            if (return_value == NULL) {
+                parson_free(temp_string_copy);
+            }
+            return return_value;
+        case JSONNull:
+            return json_value_init_null();
+        case JSONError:
+            return NULL;
+        default:
+            return NULL;
+    }
+}
+
+size_t json_serialization_size(const JSON_Value *value) {
+    char num_buf[NUM_BUF_SIZE]; /* recursively allocating buffer on stack is a bad idea, so let's do it only once */
+    int res = json_serialize_to_buffer_r(value, NULL, 0, 0, num_buf);
+    return res < 0 ? 0 : (size_t)(res + 1);
+}
+
+JSON_Status json_serialize_to_buffer(const JSON_Value *value, char *buf, size_t buf_size_in_bytes) {
+    int written = -1;
+    size_t needed_size_in_bytes = json_serialization_size(value);
+    if (needed_size_in_bytes == 0 || buf_size_in_bytes < needed_size_in_bytes) {
+        return JSONFailure;
+    }
+    written = json_serialize_to_buffer_r(value, buf, 0, 0, NULL);
+    if (written < 0) {
+        return JSONFailure;
+    }
+    return JSONSuccess;
+}
+
+JSON_Status json_serialize_to_file(const JSON_Value *value, const char *filename) {
+    JSON_Status return_code = JSONSuccess;
+    FILE *fp = NULL;
+    char *serialized_string = json_serialize_to_string(value);
+    if (serialized_string == NULL) {
+        return JSONFailure;
+    }
+    fp = fopen(filename, "w");
+    if (fp == NULL) {
+        json_free_serialized_string(serialized_string);
+        return JSONFailure;
+    }
+    if (fputs(serialized_string, fp) == EOF) {
+        return_code = JSONFailure;
+    }
+    if (fclose(fp) == EOF) {
+        return_code = JSONFailure;
+    }
+    json_free_serialized_string(serialized_string);
+    return return_code;
+}
+
+char * json_serialize_to_string(const JSON_Value *value) {
+    JSON_Status serialization_result = JSONFailure;
+    size_t buf_size_bytes = json_serialization_size(value);
+    char *buf = NULL;
+    if (buf_size_bytes == 0) {
+        return NULL;
+    }
+    buf = (char*)parson_malloc(buf_size_bytes);
+    if (buf == NULL) {
+        return NULL;
+    }
+    serialization_result = json_serialize_to_buffer(value, buf, buf_size_bytes);
+    if (serialization_result == JSONFailure) {
+        json_free_serialized_string(buf);
+        return NULL;
+    }
+    return buf;
+}
+
+size_t json_serialization_size_pretty(const JSON_Value *value) {
+    char num_buf[NUM_BUF_SIZE]; /* recursively allocating buffer on stack is a bad idea, so let's do it only once */
+    int res = json_serialize_to_buffer_r(value, NULL, 0, 1, num_buf);
+    return res < 0 ? 0 : (size_t)(res + 1);
+}
+
+JSON_Status json_serialize_to_buffer_pretty(const JSON_Value *value, char *buf, size_t buf_size_in_bytes) {
+    int written = -1;
+    size_t needed_size_in_bytes = json_serialization_size_pretty(value);
+    if (needed_size_in_bytes == 0 || buf_size_in_bytes < needed_size_in_bytes) {
+        return JSONFailure;
+    }
+    written = json_serialize_to_buffer_r(value, buf, 0, 1, NULL);
+    if (written < 0) {
+        return JSONFailure;
+    }
+    return JSONSuccess;
+}
+
+JSON_Status json_serialize_to_file_pretty(const JSON_Value *value, const char *filename) {
+    JSON_Status return_code = JSONSuccess;
+    FILE *fp = NULL;
+    char *serialized_string = json_serialize_to_string_pretty(value);
+    if (serialized_string == NULL) {
+        return JSONFailure;
+    }
+    fp = fopen(filename, "w");
+    if (fp == NULL) {
+        json_free_serialized_string(serialized_string);
+        return JSONFailure;
+    }
+    if (fputs(serialized_string, fp) == EOF) {
+        return_code = JSONFailure;
+    }
+    if (fclose(fp) == EOF) {
+        return_code = JSONFailure;
+    }
+    json_free_serialized_string(serialized_string);
+    return return_code;
+}
+
+char * json_serialize_to_string_pretty(const JSON_Value *value) {
+    JSON_Status serialization_result = JSONFailure;
+    size_t buf_size_bytes = json_serialization_size_pretty(value);
+    char *buf = NULL;
+    if (buf_size_bytes == 0) {
+        return NULL;
+    }
+    buf = (char*)parson_malloc(buf_size_bytes);
+    if (buf == NULL) {
+        return NULL;
+    }
+    serialization_result = json_serialize_to_buffer_pretty(value, buf, buf_size_bytes);
+    if (serialization_result == JSONFailure) {
+        json_free_serialized_string(buf);
+        return NULL;
+    }
+    return buf;
+}
+
+void json_free_serialized_string(char *string) {
+    parson_free(string);
+}
+
+JSON_Status json_array_remove(JSON_Array *array, size_t ix) {
+    size_t to_move_bytes = 0;
+    if (array == NULL || ix >= json_array_get_count(array)) {
+        return JSONFailure;
+    }
+    json_value_free(json_array_get_value(array, ix));
+    to_move_bytes = (json_array_get_count(array) - 1 - ix) * sizeof(JSON_Value*);
+    memmove(array->items + ix, array->items + ix + 1, to_move_bytes);
+    array->count -= 1;
+    return JSONSuccess;
+}
+
+JSON_Status json_array_replace_value(JSON_Array *array, size_t ix, JSON_Value *value) {
+    if (array == NULL || value == NULL || value->parent != NULL || ix >= json_array_get_count(array)) {
+        return JSONFailure;
+    }
+    json_value_free(json_array_get_value(array, ix));
+    value->parent = json_array_get_wrapping_value(array);
+    array->items[ix] = value;
+    return JSONSuccess;
+}
+
+JSON_Status json_array_replace_string(JSON_Array *array, size_t i, const char* string) {
+    JSON_Value *value = json_value_init_string(string);
+    if (value == NULL) {
+        return JSONFailure;
+    }
+    if (json_array_replace_value(array, i, value) == JSONFailure) {
+        json_value_free(value);
+        return JSONFailure;
+    }
+    return JSONSuccess;
+}
+
+JSON_Status json_array_replace_number(JSON_Array *array, size_t i, double number) {
+    JSON_Value *value = json_value_init_number(number);
+    if (value == NULL) {
+        return JSONFailure;
+    }
+    if (json_array_replace_value(array, i, value) == JSONFailure) {
+        json_value_free(value);
+        return JSONFailure;
+    }
+    return JSONSuccess;
+}
+
+JSON_Status json_array_replace_boolean(JSON_Array *array, size_t i, int boolean) {
+    JSON_Value *value = json_value_init_boolean(boolean);
+    if (value == NULL) {
+        return JSONFailure;
+    }
+    if (json_array_replace_value(array, i, value) == JSONFailure) {
+        json_value_free(value);
+        return JSONFailure;
+    }
+    return JSONSuccess;
+}
+
+JSON_Status json_array_replace_null(JSON_Array *array, size_t i) {
+    JSON_Value *value = json_value_init_null();
+    if (value == NULL) {
+        return JSONFailure;
+    }
+    if (json_array_replace_value(array, i, value) == JSONFailure) {
+        json_value_free(value);
+        return JSONFailure;
+    }
+    return JSONSuccess;
+}
+
+JSON_Status json_array_clear(JSON_Array *array) {
+    size_t i = 0;
+    if (array == NULL) {
+        return JSONFailure;
+    }
+    for (i = 0; i < json_array_get_count(array); i++) {
+        json_value_free(json_array_get_value(array, i));
+    }
+    array->count = 0;
+    return JSONSuccess;
+}
+
+JSON_Status json_array_append_value(JSON_Array *array, JSON_Value *value) {
+    if (array == NULL || value == NULL || value->parent != NULL) {
+        return JSONFailure;
+    }
+    return json_array_add(array, value);
+}
+
+JSON_Status json_array_append_string(JSON_Array *array, const char *string) {
+    JSON_Value *value = json_value_init_string(string);
+    if (value == NULL) {
+        return JSONFailure;
+    }
+    if (json_array_append_value(array, value) == JSONFailure) {
+        json_value_free(value);
+        return JSONFailure;
+    }
+    return JSONSuccess;
+}
+
+JSON_Status json_array_append_number(JSON_Array *array, double number) {
+    JSON_Value *value = json_value_init_number(number);
+    if (value == NULL) {
+        return JSONFailure;
+    }
+    if (json_array_append_value(array, value) == JSONFailure) {
+        json_value_free(value);
+        return JSONFailure;
+    }
+    return JSONSuccess;
+}
+
+JSON_Status json_array_append_boolean(JSON_Array *array, int boolean) {
+    JSON_Value *value = json_value_init_boolean(boolean);
+    if (value == NULL) {
+        return JSONFailure;
+    }
+    if (json_array_append_value(array, value) == JSONFailure) {
+        json_value_free(value);
+        return JSONFailure;
+    }
+    return JSONSuccess;
+}
+
+JSON_Status json_array_append_null(JSON_Array *array) {
+    JSON_Value *value = json_value_init_null();
+    if (value == NULL) {
+        return JSONFailure;
+    }
+    if (json_array_append_value(array, value) == JSONFailure) {
+        json_value_free(value);
+        return JSONFailure;
+    }
+    return JSONSuccess;
+}
+
+JSON_Status json_object_set_value(JSON_Object *object, const char *name, JSON_Value *value) {
+    size_t i = 0;
+    JSON_Value *old_value;
+    if (object == NULL || name == NULL || value == NULL || value->parent != NULL) {
+        return JSONFailure;
+    }
+    old_value = json_object_get_value(object, name);
+    if (old_value != NULL) { /* free and overwrite old value */
+        json_value_free(old_value);
+        for (i = 0; i < json_object_get_count(object); i++) {
+            if (strcmp(object->names[i], name) == 0) {
+                value->parent = json_object_get_wrapping_value(object);
+                object->values[i] = value;
+                return JSONSuccess;
+            }
+        }
+    }
+    /* add new key value pair */
+    return json_object_add(object, name, value);
+}
+
+JSON_Status json_object_set_string(JSON_Object *object, const char *name, const char *string) {
+    return json_object_set_value(object, name, json_value_init_string(string));
+}
+
+JSON_Status json_object_set_number(JSON_Object *object, const char *name, double number) {
+    return json_object_set_value(object, name, json_value_init_number(number));
+}
+
+JSON_Status json_object_set_boolean(JSON_Object *object, const char *name, int boolean) {
+    return json_object_set_value(object, name, json_value_init_boolean(boolean));
+}
+
+JSON_Status json_object_set_null(JSON_Object *object, const char *name) {
+    return json_object_set_value(object, name, json_value_init_null());
+}
+
+JSON_Status json_object_dotset_value(JSON_Object *object, const char *name, JSON_Value *value) {
+    const char *dot_pos = NULL;
+    JSON_Value *temp_value = NULL, *new_value = NULL;
+    JSON_Object *temp_object = NULL, *new_object = NULL;
+    JSON_Status status = JSONFailure;
+    size_t name_len = 0;
+    if (object == NULL || name == NULL || value == NULL) {
+        return JSONFailure;
+    }
+    dot_pos = strchr(name, '.');
+    if (dot_pos == NULL) {
+        return json_object_set_value(object, name, value);
+    }
+    name_len = dot_pos - name;
+    temp_value = json_object_getn_value(object, name, name_len);
+    if (temp_value) {
+        /* Don't overwrite existing non-object (unlike json_object_set_value, but it shouldn't be changed at this point) */
+        if (json_value_get_type(temp_value) != JSONObject) {
+            return JSONFailure;
+        }
+        temp_object = json_value_get_object(temp_value);
+        return json_object_dotset_value(temp_object, dot_pos + 1, value);
+    }
+    new_value = json_value_init_object();
+    if (new_value == NULL) {
+        return JSONFailure;
+    }
+    new_object = json_value_get_object(new_value);
+    status = json_object_dotset_value(new_object, dot_pos + 1, value);
+    if (status != JSONSuccess) {
+        json_value_free(new_value);
+        return JSONFailure;
+    }
+    status = json_object_addn(object, name, name_len, new_value);
+    if (status != JSONSuccess) {
+        json_object_dotremove_internal(new_object, dot_pos + 1, 0);
+        json_value_free(new_value);
+        return JSONFailure;
+    }
+    return JSONSuccess;
+}
+
+JSON_Status json_object_dotset_string(JSON_Object *object, const char *name, const char *string) {
+    JSON_Value *value = json_value_init_string(string);
+    if (value == NULL) {
+        return JSONFailure;
+    }
+    if (json_object_dotset_value(object, name, value) == JSONFailure) {
+        json_value_free(value);
+        return JSONFailure;
+    }
+    return JSONSuccess;
+}
+
+JSON_Status json_object_dotset_number(JSON_Object *object, const char *name, double number) {
+    JSON_Value *value = json_value_init_number(number);
+    if (value == NULL) {
+        return JSONFailure;
+    }
+    if (json_object_dotset_value(object, name, value) == JSONFailure) {
+        json_value_free(value);
+        return JSONFailure;
+    }
+    return JSONSuccess;
+}
+
+JSON_Status json_object_dotset_boolean(JSON_Object *object, const char *name, int boolean) {
+    JSON_Value *value = json_value_init_boolean(boolean);
+    if (value == NULL) {
+        return JSONFailure;
+    }
+    if (json_object_dotset_value(object, name, value) == JSONFailure) {
+        json_value_free(value);
+        return JSONFailure;
+    }
+    return JSONSuccess;
+}
+
+JSON_Status json_object_dotset_null(JSON_Object *object, const char *name) {
+    JSON_Value *value = json_value_init_null();
+    if (value == NULL) {
+        return JSONFailure;
+    }
+    if (json_object_dotset_value(object, name, value) == JSONFailure) {
+        json_value_free(value);
+        return JSONFailure;
+    }
+    return JSONSuccess;
+}
+
+JSON_Status json_object_remove(JSON_Object *object, const char *name) {
+    return json_object_remove_internal(object, name, 1);
+}
+
+JSON_Status json_object_dotremove(JSON_Object *object, const char *name) {
+    return json_object_dotremove_internal(object, name, 1);
+}
+
+JSON_Status json_object_clear(JSON_Object *object) {
+    size_t i = 0;
+    if (object == NULL) {
+        return JSONFailure;
+    }
+    for (i = 0; i < json_object_get_count(object); i++) {
+        parson_free(object->names[i]);
+        json_value_free(object->values[i]);
+    }
+    object->count = 0;
+    return JSONSuccess;
+}
+
+JSON_Status json_validate(const JSON_Value *schema, const JSON_Value *value) {
+    JSON_Value *temp_schema_value = NULL, *temp_value = NULL;
+    JSON_Array *schema_array = NULL, *value_array = NULL;
+    JSON_Object *schema_object = NULL, *value_object = NULL;
+    JSON_Value_Type schema_type = JSONError, value_type = JSONError;
+    const char *key = NULL;
+    size_t i = 0, count = 0;
+    if (schema == NULL || value == NULL) {
+        return JSONFailure;
+    }
+    schema_type = json_value_get_type(schema);
+    value_type = json_value_get_type(value);
+    if (schema_type != value_type && schema_type != JSONNull) { /* null represents all values */
+        return JSONFailure;
+    }
+    switch (schema_type) {
+        case JSONArray:
+            schema_array = json_value_get_array(schema);
+            value_array = json_value_get_array(value);
+            count = json_array_get_count(schema_array);
+            if (count == 0) {
+                return JSONSuccess; /* Empty array allows all types */
+            }
+            /* Get first value from array, rest is ignored */
+            temp_schema_value = json_array_get_value(schema_array, 0);
+            for (i = 0; i < json_array_get_count(value_array); i++) {
+                temp_value = json_array_get_value(value_array, i);
+                if (json_validate(temp_schema_value, temp_value) == JSONFailure) {
+                    return JSONFailure;
+                }
+            }
+            return JSONSuccess;
+        case JSONObject:
+            schema_object = json_value_get_object(schema);
+            value_object = json_value_get_object(value);
+            count = json_object_get_count(schema_object);
+            if (count == 0) {
+                return JSONSuccess; /* Empty object allows all objects */
+            } else if (json_object_get_count(value_object) < count) {
+                return JSONFailure; /* Tested object mustn't have less name-value pairs than schema */
+            }
+            for (i = 0; i < count; i++) {
+                key = json_object_get_name(schema_object, i);
+                temp_schema_value = json_object_get_value(schema_object, key);
+                temp_value = json_object_get_value(value_object, key);
+                if (temp_value == NULL) {
+                    return JSONFailure;
+                }
+                if (json_validate(temp_schema_value, temp_value) == JSONFailure) {
+                    return JSONFailure;
+                }
+            }
+            return JSONSuccess;
+        case JSONString: case JSONNumber: case JSONBoolean: case JSONNull:
+            return JSONSuccess; /* equality already tested before switch */
+        case JSONError: default:
+            return JSONFailure;
+    }
+}
+
+int json_value_equals(const JSON_Value *a, const JSON_Value *b) {
+    JSON_Object *a_object = NULL, *b_object = NULL;
+    JSON_Array *a_array = NULL, *b_array = NULL;
+    const char *a_string = NULL, *b_string = NULL;
+    const char *key = NULL;
+    size_t a_count = 0, b_count = 0, i = 0;
+    JSON_Value_Type a_type, b_type;
+    a_type = json_value_get_type(a);
+    b_type = json_value_get_type(b);
+    if (a_type != b_type) {
+        return 0;
+    }
+    switch (a_type) {
+        case JSONArray:
+            a_array = json_value_get_array(a);
+            b_array = json_value_get_array(b);
+            a_count = json_array_get_count(a_array);
+            b_count = json_array_get_count(b_array);
+            if (a_count != b_count) {
+                return 0;
+            }
+            for (i = 0; i < a_count; i++) {
+                if (!json_value_equals(json_array_get_value(a_array, i),
+                                       json_array_get_value(b_array, i))) {
+                    return 0;
+                }
+            }
+            return 1;
+        case JSONObject:
+            a_object = json_value_get_object(a);
+            b_object = json_value_get_object(b);
+            a_count = json_object_get_count(a_object);
+            b_count = json_object_get_count(b_object);
+            if (a_count != b_count) {
+                return 0;
+            }
+            for (i = 0; i < a_count; i++) {
+                key = json_object_get_name(a_object, i);
+                if (!json_value_equals(json_object_get_value(a_object, key),
+                                       json_object_get_value(b_object, key))) {
+                    return 0;
+                }
+            }
+            return 1;
+        case JSONString:
+            a_string = json_value_get_string(a);
+            b_string = json_value_get_string(b);
+            if (a_string == NULL || b_string == NULL) {
+                return 0; /* shouldn't happen */
+            }
+            return strcmp(a_string, b_string) == 0;
+        case JSONBoolean:
+            return json_value_get_boolean(a) == json_value_get_boolean(b);
+        case JSONNumber:
+            return fabs(json_value_get_number(a) - json_value_get_number(b)) < 0.000001; /* EPSILON */
+        case JSONError:
+            return 1;
+        case JSONNull:
+            return 1;
+        default:
+            return 1;
+    }
+}
+
+JSON_Value_Type json_type(const JSON_Value *value) {
+    return json_value_get_type(value);
+}
+
+JSON_Object * json_object (const JSON_Value *value) {
+    return json_value_get_object(value);
+}
+
+JSON_Array * json_array  (const JSON_Value *value) {
+    return json_value_get_array(value);
+}
+
+const char * json_string (const JSON_Value *value) {
+    return json_value_get_string(value);
+}
+
+double json_number (const JSON_Value *value) {
+    return json_value_get_number(value);
+}
+
+int json_boolean(const JSON_Value *value) {
+    return json_value_get_boolean(value);
+}
+
+void json_set_allocation_functions(JSON_Malloc_Function malloc_fun, JSON_Free_Function free_fun) {
+    parson_malloc = malloc_fun;
+    parson_free = free_fun;
+}
+
+void json_set_escape_slashes(int escape_slashes) {
+    parson_escape_slashes = escape_slashes;
+}
Index: azure_iot_hub_f767zi/trunk/azure_iot_sdk/deps/parson/parson.h
===================================================================
--- azure_iot_hub_f767zi/trunk/azure_iot_sdk/deps/parson/parson.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/azure_iot_sdk/deps/parson/parson.h	(revision 457)
@@ -0,0 +1,240 @@
+/*
+ SPDX-License-Identifier: MIT
+
+ Parson ( http://kgabis.github.com/parson/ )
+ Copyright (c) 2012 - 2019 Krzysztof Gabis
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+*/
+
+#ifndef parson_parson_h
+#define parson_parson_h
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include <stddef.h>   /* size_t */
+
+/* Types and enums */
+typedef struct json_object_t JSON_Object;
+typedef struct json_array_t  JSON_Array;
+typedef struct json_value_t  JSON_Value;
+
+enum json_value_type {
+    JSONError   = -1,
+    JSONNull    = 1,
+    JSONString  = 2,
+    JSONNumber  = 3,
+    JSONObject  = 4,
+    JSONArray   = 5,
+    JSONBoolean = 6
+};
+typedef int JSON_Value_Type;
+
+enum json_result_t {
+    JSONSuccess = 0,
+    JSONFailure = -1
+};
+typedef int JSON_Status;
+
+typedef void * (*JSON_Malloc_Function)(size_t);
+typedef void   (*JSON_Free_Function)(void *);
+
+/* Call only once, before calling any other function from parson API. If not called, malloc and free
+   from stdlib will be used for all allocations */
+void json_set_allocation_functions(JSON_Malloc_Function malloc_fun, JSON_Free_Function free_fun);
+
+/* Sets if slashes should be escaped or not when serializing JSON. By default slashes are escaped.
+ This function sets a global setting and is not thread safe. */
+void json_set_escape_slashes(int escape_slashes);
+
+/* Parses first JSON value in a file, returns NULL in case of error */
+JSON_Value * json_parse_file(const char *filename);
+
+/* Parses first JSON value in a file and ignores comments (/ * * / and //),
+   returns NULL in case of error */
+JSON_Value * json_parse_file_with_comments(const char *filename);
+
+/*  Parses first JSON value in a string, returns NULL in case of error */
+JSON_Value * json_parse_string(const char *string);
+
+/*  Parses first JSON value in a string and ignores comments (/ * * / and //),
+    returns NULL in case of error */
+JSON_Value * json_parse_string_with_comments(const char *string);
+
+/* Serialization */
+size_t      json_serialization_size(const JSON_Value *value); /* returns 0 on fail */
+JSON_Status json_serialize_to_buffer(const JSON_Value *value, char *buf, size_t buf_size_in_bytes);
+JSON_Status json_serialize_to_file(const JSON_Value *value, const char *filename);
+char *      json_serialize_to_string(const JSON_Value *value);
+
+/* Pretty serialization */
+size_t      json_serialization_size_pretty(const JSON_Value *value); /* returns 0 on fail */
+JSON_Status json_serialize_to_buffer_pretty(const JSON_Value *value, char *buf, size_t buf_size_in_bytes);
+JSON_Status json_serialize_to_file_pretty(const JSON_Value *value, const char *filename);
+char *      json_serialize_to_string_pretty(const JSON_Value *value);
+
+void        json_free_serialized_string(char *string); /* frees string from json_serialize_to_string and json_serialize_to_string_pretty */
+
+/* Comparing */
+int  json_value_equals(const JSON_Value *a, const JSON_Value *b);
+
+/* Validation
+   This is *NOT* JSON Schema. It validates json by checking if object have identically
+   named fields with matching types.
+   For example schema {"name":"", "age":0} will validate
+   {"name":"Joe", "age":25} and {"name":"Joe", "age":25, "gender":"m"},
+   but not {"name":"Joe"} or {"name":"Joe", "age":"Cucumber"}.
+   In case of arrays, only first value in schema is checked against all values in tested array.
+   Empty objects ({}) validate all objects, empty arrays ([]) validate all arrays,
+   null validates values of every type.
+ */
+JSON_Status json_validate(const JSON_Value *schema, const JSON_Value *value);
+
+/*
+ * JSON Object
+ */
+JSON_Value  * json_object_get_value  (const JSON_Object *object, const char *name);
+const char  * json_object_get_string (const JSON_Object *object, const char *name);
+JSON_Object * json_object_get_object (const JSON_Object *object, const char *name);
+JSON_Array  * json_object_get_array  (const JSON_Object *object, const char *name);
+double        json_object_get_number (const JSON_Object *object, const char *name); /* returns 0 on fail */
+int           json_object_get_boolean(const JSON_Object *object, const char *name); /* returns -1 on fail */
+
+/* dotget functions enable addressing values with dot notation in nested objects,
+ just like in structs or c++/java/c# objects (e.g. objectA.objectB.value).
+ Because valid names in JSON can contain dots, some values may be inaccessible
+ this way. */
+JSON_Value  * json_object_dotget_value  (const JSON_Object *object, const char *name);
+const char  * json_object_dotget_string (const JSON_Object *object, const char *name);
+JSON_Object * json_object_dotget_object (const JSON_Object *object, const char *name);
+JSON_Array  * json_object_dotget_array  (const JSON_Object *object, const char *name);
+double        json_object_dotget_number (const JSON_Object *object, const char *name); /* returns 0 on fail */
+int           json_object_dotget_boolean(const JSON_Object *object, const char *name); /* returns -1 on fail */
+
+/* Functions to get available names */
+size_t        json_object_get_count   (const JSON_Object *object);
+const char  * json_object_get_name    (const JSON_Object *object, size_t index);
+JSON_Value  * json_object_get_value_at(const JSON_Object *object, size_t index);
+JSON_Value  * json_object_get_wrapping_value(const JSON_Object *object);
+
+/* Functions to check if object has a value with a specific name. Returned value is 1 if object has
+ * a value and 0 if it doesn't. dothas functions behave exactly like dotget functions. */
+int json_object_has_value        (const JSON_Object *object, const char *name);
+int json_object_has_value_of_type(const JSON_Object *object, const char *name, JSON_Value_Type type);
+
+int json_object_dothas_value        (const JSON_Object *object, const char *name);
+int json_object_dothas_value_of_type(const JSON_Object *object, const char *name, JSON_Value_Type type);
+
+/* Creates new name-value pair or frees and replaces old value with a new one.
+ * json_object_set_value does not copy passed value so it shouldn't be freed afterwards. */
+JSON_Status json_object_set_value(JSON_Object *object, const char *name, JSON_Value *value);
+JSON_Status json_object_set_string(JSON_Object *object, const char *name, const char *string);
+JSON_Status json_object_set_number(JSON_Object *object, const char *name, double number);
+JSON_Status json_object_set_boolean(JSON_Object *object, const char *name, int boolean);
+JSON_Status json_object_set_null(JSON_Object *object, const char *name);
+
+/* Works like dotget functions, but creates whole hierarchy if necessary.
+ * json_object_dotset_value does not copy passed value so it shouldn't be freed afterwards. */
+JSON_Status json_object_dotset_value(JSON_Object *object, const char *name, JSON_Value *value);
+JSON_Status json_object_dotset_string(JSON_Object *object, const char *name, const char *string);
+JSON_Status json_object_dotset_number(JSON_Object *object, const char *name, double number);
+JSON_Status json_object_dotset_boolean(JSON_Object *object, const char *name, int boolean);
+JSON_Status json_object_dotset_null(JSON_Object *object, const char *name);
+
+/* Frees and removes name-value pair */
+JSON_Status json_object_remove(JSON_Object *object, const char *name);
+
+/* Works like dotget function, but removes name-value pair only on exact match. */
+JSON_Status json_object_dotremove(JSON_Object *object, const char *key);
+
+/* Removes all name-value pairs in object */
+JSON_Status json_object_clear(JSON_Object *object);
+
+/*
+ *JSON Array
+ */
+JSON_Value  * json_array_get_value  (const JSON_Array *array, size_t index);
+const char  * json_array_get_string (const JSON_Array *array, size_t index);
+JSON_Object * json_array_get_object (const JSON_Array *array, size_t index);
+JSON_Array  * json_array_get_array  (const JSON_Array *array, size_t index);
+double        json_array_get_number (const JSON_Array *array, size_t index); /* returns 0 on fail */
+int           json_array_get_boolean(const JSON_Array *array, size_t index); /* returns -1 on fail */
+size_t        json_array_get_count  (const JSON_Array *array);
+JSON_Value  * json_array_get_wrapping_value(const JSON_Array *array);
+    
+/* Frees and removes value at given index, does nothing and returns JSONFailure if index doesn't exist.
+ * Order of values in array may change during execution.  */
+JSON_Status json_array_remove(JSON_Array *array, size_t i);
+
+/* Frees and removes from array value at given index and replaces it with given one.
+ * Does nothing and returns JSONFailure if index doesn't exist.
+ * json_array_replace_value does not copy passed value so it shouldn't be freed afterwards. */
+JSON_Status json_array_replace_value(JSON_Array *array, size_t i, JSON_Value *value);
+JSON_Status json_array_replace_string(JSON_Array *array, size_t i, const char* string);
+JSON_Status json_array_replace_number(JSON_Array *array, size_t i, double number);
+JSON_Status json_array_replace_boolean(JSON_Array *array, size_t i, int boolean);
+JSON_Status json_array_replace_null(JSON_Array *array, size_t i);
+
+/* Frees and removes all values from array */
+JSON_Status json_array_clear(JSON_Array *array);
+
+/* Appends new value at the end of array.
+ * json_array_append_value does not copy passed value so it shouldn't be freed afterwards. */
+JSON_Status json_array_append_value(JSON_Array *array, JSON_Value *value);
+JSON_Status json_array_append_string(JSON_Array *array, const char *string);
+JSON_Status json_array_append_number(JSON_Array *array, double number);
+JSON_Status json_array_append_boolean(JSON_Array *array, int boolean);
+JSON_Status json_array_append_null(JSON_Array *array);
+
+/*
+ *JSON Value
+ */
+JSON_Value * json_value_init_object (void);
+JSON_Value * json_value_init_array  (void);
+JSON_Value * json_value_init_string (const char *string); /* copies passed string */
+JSON_Value * json_value_init_number (double number);
+JSON_Value * json_value_init_boolean(int boolean);
+JSON_Value * json_value_init_null   (void);
+JSON_Value * json_value_deep_copy   (const JSON_Value *value);
+void         json_value_free        (JSON_Value *value);
+
+JSON_Value_Type json_value_get_type   (const JSON_Value *value);
+JSON_Object *   json_value_get_object (const JSON_Value *value);
+JSON_Array  *   json_value_get_array  (const JSON_Value *value);
+const char  *   json_value_get_string (const JSON_Value *value);
+double          json_value_get_number (const JSON_Value *value);
+int             json_value_get_boolean(const JSON_Value *value);
+JSON_Value  *   json_value_get_parent (const JSON_Value *value);
+
+/* Same as above, but shorter */
+JSON_Value_Type json_type   (const JSON_Value *value);
+JSON_Object *   json_object (const JSON_Value *value);
+JSON_Array  *   json_array  (const JSON_Value *value);
+const char  *   json_string (const JSON_Value *value);
+double          json_number (const JSON_Value *value);
+int             json_boolean(const JSON_Value *value);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
Index: azure_iot_hub_f767zi/trunk/azure_iot_sdk/deps/umock-c/inc/umock_c/umock_c_prod.h
===================================================================
--- azure_iot_hub_f767zi/trunk/azure_iot_sdk/deps/umock-c/inc/umock_c/umock_c_prod.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/azure_iot_sdk/deps/umock-c/inc/umock_c/umock_c_prod.h	(revision 457)
@@ -0,0 +1,123 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+#include "azure_macro_utils/macro_utils.h"
+
+#undef MOCKABLE_FUNCTION
+#undef MOCKABLE_FUNCTION_WITH_RETURNS
+#undef MOCKABLE_FUNCTION_WITH_CODE
+#undef MOCKABLE_FUNCTION_WITH_CODE_END
+#undef IMPLEMENT_MOCKABLE_FUNCTION
+#undef MOCKABLE_INTERFACE
+
+/* This header is meant to be included by production code headers, so that the MOCKABLE_FUNCTION gets enabled. */
+/* 
+    If you are porting to a new platform and do not want to build the tests, but only the production code,
+    simply make sure that this file is in the include path (either by copying it to your inc folder or 
+    by adjusting the include paths).
+*/
+
+#define DO_NOTHING_WITH_RETURN_VALUES(success_return_value, failure_return_value) \
+
+/* These 2 macros are used to check if a type is "void" or not */
+#define UMOCK_C_PROD_TEST_void 0
+#define UMOCK_C_PROD_IS_NOT_VOID(x) \
+    MU_IF(MU_C2(UMOCK_C_PROD_TEST_,x), 1, 0)
+
+#ifdef ENABLE_MOCKS
+
+#ifdef ENABLE_MOCK_FILTERING
+#define ENABLE_MOCK_FILTERING_SWITCH 1
+#else
+#define ENABLE_MOCK_FILTERING_SWITCH 0
+#endif
+
+#define UMOCK_C_PROD_ARG_IN_SIGNATURE(count, arg_type, arg_name) arg_type arg_name MU_IFCOMMA(count)
+
+#define MOCKABLE_FUNCTION_SIGNATURE(modifiers, result, function, ...) \
+    result modifiers function(MU_IF(MU_COUNT_ARG(__VA_ARGS__),,void) MU_FOR_EACH_2_COUNTED(UMOCK_C_PROD_ARG_IN_SIGNATURE, __VA_ARGS__))
+
+#define MOCKABLE_FUNCTION_DISABLED(do_returns, modifiers, result, function, ...) \
+    result modifiers function(MU_IF(MU_COUNT_ARG(__VA_ARGS__), , void) MU_FOR_EACH_2_COUNTED(UMOCK_C_PROD_ARG_IN_SIGNATURE, __VA_ARGS__)); \
+    MU_IF(do_returns, MU_IF(UMOCK_C_PROD_IS_NOT_VOID(result), DO_NOTHING_WITH_RETURN_VALUES,), )
+
+/* Codes_SRS_UMOCK_C_LIB_01_001: [MOCKABLE_FUNCTION shall be used to wrap function definition allowing the user to declare a function that can be mocked.]*/
+#define MOCKABLE_FUNCTION(modifiers, result, function, ...) \
+    MU_IF(ENABLE_MOCK_FILTERING_SWITCH,MU_IF(MU_C2(please_mock_, function),MOCKABLE_FUNCTION_DISABLED,MOCKABLE_FUNCTION_UMOCK_INTERNAL_WITH_MOCK), MOCKABLE_FUNCTION_UMOCK_INTERNAL_WITH_MOCK) (0, modifiers, result, function, __VA_ARGS__)
+
+/* Codes_SRS_UMOCK_C_LIB_01_212: [ MOCKABLE_FUNCTION_WITH_RETURNS shall be used to wrap function definitions, allowing the user to declare a function that can be mocked and aditionally declares the values that are to be returned in case of success and failure. ]*/
+#define MOCKABLE_FUNCTION_WITH_RETURNS(modifiers, result, function, ...) \
+    MU_IF(ENABLE_MOCK_FILTERING_SWITCH,MU_IF(MU_C2(please_mock_, function),MOCKABLE_FUNCTION_DISABLED,MOCKABLE_FUNCTION_UMOCK_INTERNAL_WITH_MOCK), MOCKABLE_FUNCTION_UMOCK_INTERNAL_WITH_MOCK) (1, modifiers, result, function, __VA_ARGS__)
+
+// The below MOCKABLE_FUNCTION_WITH_CODE macros are a temporary solution and should not be used for long term
+// They will be removed once the real support is in umock_c
+#define MOCKABLE_FUNCTION_WITH_CODE(modifiers, result, function, ...) \
+    MOCKABLE_FUNCTION_INTERNAL_WITH_CODE(modifiers, result, function, __VA_ARGS__)
+
+#define MOCKABLE_FUNCTION_WITH_CODE_END(...) \
+    MOCKABLE_FUNCTION_END(__VA_ARGS__)
+
+/* Codes_SRS_UMOCK_C_LIB_01_217: [ In the presence of the ENABLE_MOCKS define, IMPLEMENT_MOCKABLE_FUNCTION shall expand to the signature of the function, but the name shall be changed to be prefix with real_. ]*/
+#define IMPLEMENT_MOCKABLE_FUNCTION(modifiers, result, function, ...) \
+    MOCKABLE_FUNCTION_SIGNATURE(modifiers, result, MU_C2(real_, function), __VA_ARGS__)
+
+#define EXPAND_ENTRY(A) \
+    MOCKABLE_##A
+
+#define REGISTER_GLOBAL_MOCK_REAL_FUNCTION(modifiers, result, function, ...) \
+    REGISTER_GLOBAL_MOCK_HOOK(function, MU_C2(real_, function));
+
+#define REGISTER_GLOBAL_MOCK_REAL(A) \
+    REGISTER_GLOBAL_MOCK_REAL_##A
+
+/* Codes_SRS_UMOCK_C_LIB_01_215: [ Each item in ... shall be an entry for one mockable function. ]*/
+/* Codes_SRS_UMOCK_C_LIB_01_216: [ Each item in ... shall be defined using a macro called FUNCTION, which shall be an alias for MOCKABLE_FUNCTION. ]*/
+#define MOCKABLE_INTERFACE(interface_name, ...) \
+    MU_FOR_EACH_1(EXPAND_ENTRY, __VA_ARGS__) \
+    static void MU_C2(register_reals_, interface_name)(void) \
+    { \
+        MU_FOR_EACH_1(REGISTER_GLOBAL_MOCK_REAL, __VA_ARGS__); \
+    } \
+
+#include "umock_c/umock_c.h"
+
+#else
+
+#define UMOCK_C_PROD_ARG_IN_SIGNATURE(count, arg_type, arg_name) arg_type arg_name MU_IFCOMMA(count)
+
+#define MOCKABLE_FUNCTION_SIGNATURE(modifiers, result, function, ...) \
+    result modifiers function(MU_IF(MU_COUNT_ARG(__VA_ARGS__),,void) MU_FOR_EACH_2_COUNTED(UMOCK_C_PROD_ARG_IN_SIGNATURE, __VA_ARGS__))
+
+/* Codes_SRS_UMOCK_C_LIB_01_002: [The macro shall generate a function signature in case ENABLE_MOCKS is not defined.] */
+/* Codes_SRS_UMOCK_C_LIB_01_005: [If ENABLE_MOCKS is not defined, MOCKABLE_FUNCTION shall only generate a declaration for the function.] */
+/* Codes_SRS_UMOCK_C_LIB_01_001: [MOCKABLE_FUNCTION shall be used to wrap function definition allowing the user to declare a function that can be mocked.]*/
+#define MOCKABLE_FUNCTION(modifiers, result, function, ...) \
+    MOCKABLE_FUNCTION_SIGNATURE(modifiers, result, function, __VA_ARGS__);
+
+/* Codes_SRS_UMOCK_C_LIB_01_213: [ The macro shall generate a function signature in case ENABLE_MOCKS is not defined. ]*/
+/* Codes_SRS_UMOCK_C_LIB_01_212: [ MOCKABLE_FUNCTION_WITH_RETURNS shall be used to wrap function definitions, allowing the user to declare a function that can be mocked and aditionally declares the values that are to be returned in case of success and failure. ]*/
+#define MOCKABLE_FUNCTION_WITH_RETURNS(modifiers, result, function, ...) \
+    result modifiers function(MU_IF(MU_COUNT_ARG(__VA_ARGS__),,void) MU_FOR_EACH_2_COUNTED(UMOCK_C_PROD_ARG_IN_SIGNATURE, __VA_ARGS__)); \
+    MU_IF(UMOCK_C_PROD_IS_NOT_VOID(result), DO_NOTHING_WITH_RETURN_VALUES,)
+
+#define UMOCK_C_PROD_ARG_IN_SIGNATURE_2(count, arg_type, arg_name) 
+
+// The below MOCKABLE_FUNCTION_WITH_CODE macros are a temporary solution and should not be used for long term
+// They will be removed once the real support is in umock_c
+#define MOCKABLE_FUNCTION_WITH_CODE(modifiers, result, function, ...) \
+    MOCKABLE_FUNCTION_SIGNATURE(modifiers, result, function, __VA_ARGS__)
+
+/* Codes_SRS_UMOCK_C_LIB_01_218: [ If ENABLE_MOCKS is not defined, IMPLEMENT_MOCKABLE_FUNCTION shall expand to the signature of the function. ]*/
+#define IMPLEMENT_MOCKABLE_FUNCTION(modifiers, result, function, ...) \
+    MOCKABLE_FUNCTION_SIGNATURE(modifiers, result, function, __VA_ARGS__)
+
+#define EXPAND_PROD_ENTRY(A) MOCKABLE_##A
+
+/* Codes_SRS_UMOCK_C_LIB_01_215: [ Each item in ... shall be an entry for one mockable function. ]*/
+/* Codes_SRS_UMOCK_C_LIB_01_216: [ Each item in ... shall be defined using a macro called FUNCTION, which shall be an alias for MOCKABLE_FUNCTION. ]*/
+#define MOCKABLE_INTERFACE(interface_name, ...) \
+    MU_FOR_EACH_1(EXPAND_PROD_ENTRY, __VA_ARGS__)
+
+#define MOCKABLE_FUNCTION_WITH_CODE_END(...) \
+
+#endif
Index: azure_iot_hub_f767zi/trunk/azure_iot_sdk/iothub_client/inc/internal/blob.h
===================================================================
--- azure_iot_hub_f767zi/trunk/azure_iot_sdk/iothub_client/inc/internal/blob.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/azure_iot_sdk/iothub_client/inc/internal/blob.h	(revision 457)
@@ -0,0 +1,81 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+/** @file blob.h
+*    @brief Contains blob APIs needed for File Upload feature of IoTHub client.
+*
+*    @details IoTHub client needs to upload a byte array by using blob storage API
+*             IoTHub service provides the complete SAS URI to execute a PUT request
+*             that will upload the data.
+*
+*/
+
+#ifndef BLOB_H
+#define BLOB_H
+
+#include "azure_macro_utils/macro_utils.h"
+#include "azure_c_shared_utility/buffer_.h"
+#include "azure_c_shared_utility/strings_types.h"
+#include "azure_c_shared_utility/httpapiex.h"
+#include "iothub_client_core_ll.h"
+#include "azure_c_shared_utility/shared_util_options.h"
+
+#ifdef __cplusplus
+#include <cstddef>
+extern "C"
+{
+#else
+#include <stddef.h>
+#endif
+
+#include "umock_c/umock_c_prod.h"
+
+/* Allow unit tests to override MAX_BLOCK_COUNT to something much smaller */
+#ifndef MAX_BLOCK_COUNT
+/* Maximum count of blocks uploaded is 50000, per server*/
+#define MAX_BLOCK_COUNT 50000
+#endif
+
+#define BLOB_RESULT_VALUES \
+    BLOB_OK,               \
+    BLOB_ERROR,            \
+    BLOB_NOT_IMPLEMENTED,  \
+    BLOB_HTTP_ERROR,       \
+    BLOB_INVALID_ARG,      \
+    BLOB_ABORTED
+
+MU_DEFINE_ENUM_WITHOUT_INVALID(BLOB_RESULT, BLOB_RESULT_VALUES)
+
+/**
+* @brief  Synchronously uploads a byte array to blob storage
+*
+* @param  SASURI            The URI to use to upload data
+* @param  getDataCallbackEx A callback to be invoked to acquire the file chunks to be uploaded, as well as to indicate the status of the upload of the previous block.
+* @param  context           Any data provided by the user to serve as context on getDataCallback.
+* @param  httpStatus        A pointer to an out argument receiving the HTTP status (available only when the return value is BLOB_OK)
+* @param  httpResponse      A BUFFER_HANDLE that receives the HTTP response from the server (available only when the return value is BLOB_OK)
+* @param  certificates      A null terminated string containing CA certificates to be used
+* @param    proxyOptions    A structure that contains optional web proxy information
+*
+* @return    A @c BLOB_RESULT. BLOB_OK means the blob has been uploaded successfully. Any other value indicates an error
+*/
+MOCKABLE_FUNCTION(, BLOB_RESULT, Blob_UploadMultipleBlocksFromSasUri, const char*, SASURI, IOTHUB_CLIENT_FILE_UPLOAD_GET_DATA_CALLBACK_EX, getDataCallbackEx, void*, context, unsigned int*, httpStatus, BUFFER_HANDLE, httpResponse, const char*, certificates, HTTP_PROXY_OPTIONS*, proxyOptions)
+
+/**
+* @brief  Synchronously uploads a byte array as a new block to blob storage
+*
+* @param  requestContent      The data to upload
+* @param  blockId             The block id (from 00000 to 49999)
+* @param  xml                 The XML file containing the blockId list
+* @param  relativePath        The destination path within the storage
+* @param  httpApiExHandle     The connection handle
+* @param  httpStatus          A pointer to an out argument receiving the HTTP status (available only when the return value is BLOB_OK)
+* @param  httpResponse        A BUFFER_HANDLE that receives the HTTP response from the server (available only when the return value is BLOB_OK)
+*/
+//MOCKABLE_FUNCTION(, BLOB_RESULT, Blob_UploadNextBlock, BUFFER_HANDLE, requestContent, unsigned int, blockID, STRING_HANDLE, xml, const char*, relativePath, HTTPAPIEX_HANDLE, httpApiExHandle, unsigned int*, httpStatus, BUFFER_HANDLE, httpResponse)
+MOCKABLE_FUNCTION(, BLOB_RESULT, Blob_UploadBlock, HTTPAPIEX_HANDLE, httpApiExHandle, const char*, relativePath, BUFFER_HANDLE, requestContent, unsigned int, blockID, STRING_HANDLE, blockIDList, unsigned int*, httpStatus, BUFFER_HANDLE, httpResponse)
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* BLOB_H */
Index: azure_iot_hub_f767zi/trunk/azure_iot_sdk/iothub_client/inc/internal/iothub_client_authorization.h
===================================================================
--- azure_iot_hub_f767zi/trunk/azure_iot_sdk/iothub_client/inc/internal/iothub_client_authorization.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/azure_iot_sdk/iothub_client/inc/internal/iothub_client_authorization.h	(revision 457)
@@ -0,0 +1,64 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+#ifndef IOTHUB_CLIENT_AUTHORIZATION_H
+#define IOTHUB_CLIENT_AUTHORIZATION_H
+
+#include "azure_macro_utils/macro_utils.h"
+#include "umock_c/umock_c_prod.h"
+#include "azure_c_shared_utility/xio.h"
+
+#ifdef __cplusplus
+extern "C" {
+#include <cstdint>
+#else
+#include <stdint.h>
+#include <stdbool.h>
+#endif /* __cplusplus */
+
+typedef struct IOTHUB_AUTHORIZATION_DATA_TAG* IOTHUB_AUTHORIZATION_HANDLE;
+
+#define IOTHUB_CREDENTIAL_TYPE_VALUES       \
+    IOTHUB_CREDENTIAL_TYPE_UNKNOWN,         \
+    IOTHUB_CREDENTIAL_TYPE_DEVICE_KEY,      \
+    IOTHUB_CREDENTIAL_TYPE_X509,            \
+    IOTHUB_CREDENTIAL_TYPE_X509_ECC,        \
+    IOTHUB_CREDENTIAL_TYPE_SAS_TOKEN,       \
+    IOTHUB_CREDENTIAL_TYPE_DEVICE_AUTH
+
+
+MU_DEFINE_ENUM_WITHOUT_INVALID(IOTHUB_CREDENTIAL_TYPE, IOTHUB_CREDENTIAL_TYPE_VALUES);
+
+#define SAS_TOKEN_STATUS_VALUES  \
+    SAS_TOKEN_STATUS_FAILED,     \
+    SAS_TOKEN_STATUS_VALID,      \
+    SAS_TOKEN_STATUS_INVALID
+
+MU_DEFINE_ENUM_WITHOUT_INVALID(SAS_TOKEN_STATUS, SAS_TOKEN_STATUS_VALUES);
+
+MOCKABLE_FUNCTION(, IOTHUB_AUTHORIZATION_HANDLE, IoTHubClient_Auth_Create, const char*, device_key, const char*, device_id, const char*, device_sas_token, const char *, module_id);
+MOCKABLE_FUNCTION(, IOTHUB_AUTHORIZATION_HANDLE, IoTHubClient_Auth_CreateFromDeviceAuth, const char*, device_id, const char*, module_id);
+MOCKABLE_FUNCTION(, void, IoTHubClient_Auth_Destroy, IOTHUB_AUTHORIZATION_HANDLE, handle);
+MOCKABLE_FUNCTION(, IOTHUB_CREDENTIAL_TYPE, IoTHubClient_Auth_Set_x509_Type, IOTHUB_AUTHORIZATION_HANDLE, handle, bool, enable_x509);
+MOCKABLE_FUNCTION(, IOTHUB_CREDENTIAL_TYPE, IoTHubClient_Auth_Get_Credential_Type, IOTHUB_AUTHORIZATION_HANDLE, handle);
+MOCKABLE_FUNCTION(, char*, IoTHubClient_Auth_Get_SasToken, IOTHUB_AUTHORIZATION_HANDLE, handle, const char*, scope, size_t, expiry_time_relative_seconds, const char*, key_name);
+MOCKABLE_FUNCTION(, int, IoTHubClient_Auth_Set_xio_Certificate, IOTHUB_AUTHORIZATION_HANDLE, handle, XIO_HANDLE, xio);
+MOCKABLE_FUNCTION(, const char*, IoTHubClient_Auth_Get_DeviceId, IOTHUB_AUTHORIZATION_HANDLE, handle);
+MOCKABLE_FUNCTION(, const char*, IoTHubClient_Auth_Get_ModuleId, IOTHUB_AUTHORIZATION_HANDLE, handle);
+MOCKABLE_FUNCTION(, const char*, IoTHubClient_Auth_Get_DeviceKey, IOTHUB_AUTHORIZATION_HANDLE, handle);
+MOCKABLE_FUNCTION(, SAS_TOKEN_STATUS, IoTHubClient_Auth_Is_SasToken_Valid, IOTHUB_AUTHORIZATION_HANDLE, handle);
+MOCKABLE_FUNCTION(, int, IoTHubClient_Auth_Get_x509_info, IOTHUB_AUTHORIZATION_HANDLE, handle, char**, x509_cert, char**, x509_key);
+MOCKABLE_FUNCTION(, int, IoTHubClient_Auth_Set_SasToken_Expiry, IOTHUB_AUTHORIZATION_HANDLE, handle, size_t, expiry_time_seconds);
+MOCKABLE_FUNCTION(, size_t, IoTHubClient_Auth_Get_SasToken_Expiry, IOTHUB_AUTHORIZATION_HANDLE, handle);
+
+
+#ifdef USE_EDGE_MODULES
+MOCKABLE_FUNCTION(, char*, IoTHubClient_Auth_Get_TrustBundle, IOTHUB_AUTHORIZATION_HANDLE, handle, const char*, certificate_file_name);
+#endif
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* IOTHUB_CLIENT_AUTHORIZATION_H */
Index: azure_iot_hub_f767zi/trunk/azure_iot_sdk/iothub_client/inc/internal/iothub_client_diagnostic.h
===================================================================
--- azure_iot_hub_f767zi/trunk/azure_iot_sdk/iothub_client/inc/internal/iothub_client_diagnostic.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/azure_iot_sdk/iothub_client/inc/internal/iothub_client_diagnostic.h	(revision 457)
@@ -0,0 +1,48 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+/** @file   iothub_client_diagnostic.h
+*    @brief  The @c diagnostic is a component that helps to add predefined diagnostic
+            properties to message for end to end diagnostic purpose
+*/
+
+#ifndef IOTHUB_CLIENT_DIAGNOSTIC_H
+#define IOTHUB_CLIENT_DIAGNOSTIC_H
+
+#include "umock_c/umock_c_prod.h"
+
+#include "iothub_message.h"
+#include <stdint.h>
+
+#ifdef __cplusplus
+#include <cstddef>
+extern "C" {
+#else
+#include <stddef.h>
+#endif
+
+/** @brief diagnostic related setting */
+typedef struct IOTHUB_DIAGNOSTIC_SETTING_DATA_TAG
+{
+    uint32_t diagSamplingPercentage;
+    uint32_t currentMessageNumber;
+} IOTHUB_DIAGNOSTIC_SETTING_DATA;
+
+/**
+    * @brief    Adds diagnostic information to message if:
+    *           a. diagSetting->diagSamplingPercentage > 0 and
+    *           b. the number of current message matches sample rule specified by diagSetting->diagSamplingPercentage
+    *
+    * @param    diagSetting        Pointer to an @c IOTHUB_DIAGNOSTIC_SETTING_DATA structure
+    *
+    * @param    messageHandle    message handle
+    *
+    * @return    0 upon success
+    */
+MOCKABLE_FUNCTION(, int, IoTHubClient_Diagnostic_AddIfNecessary, IOTHUB_DIAGNOSTIC_SETTING_DATA *, diagSetting, IOTHUB_MESSAGE_HANDLE, messageHandle);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* IOTHUB_CLIENT_DIAGNOSTIC_H */
Index: azure_iot_hub_f767zi/trunk/azure_iot_sdk/iothub_client/inc/internal/iothub_client_hsm_ll.h
===================================================================
--- azure_iot_hub_f767zi/trunk/azure_iot_sdk/iothub_client/inc/internal/iothub_client_hsm_ll.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/azure_iot_sdk/iothub_client/inc/internal/iothub_client_hsm_ll.h	(revision 457)
@@ -0,0 +1,22 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+/** @file iothub_client_version.h
+*    @brief Functions for managing the client SDK version.
+*/
+
+#ifndef IOTHUB_CLIENT_PROVISIONING_H
+#define IOTHUB_CLIENT_PROVISIONING_H
+
+#include "azure_macro_utils/macro_utils.h"
+#include "umock_c/umock_c_prod.h"
+
+#ifdef USE_PROV_MODULE
+#include "azure_prov_client/internal/iothub_auth_client.h"
+#endif
+
+#include "iothub_client_ll.h"
+
+/*This header is DEPREPCATED and mainatined only for backward compatibility*/
+
+#endif // IOTHUB_CLIENT_PROVISIONING_H
Index: azure_iot_hub_f767zi/trunk/azure_iot_sdk/iothub_client/inc/internal/iothub_client_ll_uploadtoblob.h
===================================================================
--- azure_iot_hub_f767zi/trunk/azure_iot_sdk/iothub_client/inc/internal/iothub_client_ll_uploadtoblob.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/azure_iot_sdk/iothub_client/inc/internal/iothub_client_ll_uploadtoblob.h	(revision 457)
@@ -0,0 +1,58 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+/** @file iothub_client_ll.h
+*    @brief     APIs that allow a user (usually a device) to communicate
+*             with an Azure IoTHub.
+*
+*    @details IoTHubClient_LL is a module that allows a user (usually a
+*             device) to communicate with an Azure IoTHub. It can send events
+*             and receive messages. At any given moment in time there can only
+*             be at most 1 message callback function.
+*
+*             This API surface contains a set of APIs that allows the user to
+*             interact with the lower layer portion of the IoTHubClient. These APIs
+*             contain @c _LL_ in their name, but retain the same functionality like the
+*             @c IoTHubClient_... APIs, with one difference. If the @c _LL_ APIs are
+*             used then the user is responsible for scheduling when the actual work done
+*             by the IoTHubClient happens (when the data is sent/received on/from the wire).
+*             This is useful for constrained devices where spinning a separate thread is
+*             often not desired.
+*/
+
+#ifndef DONT_USE_UPLOADTOBLOB
+
+#ifndef IOTHUB_CLIENT_LL_UPLOADTOBLOB_H
+#define IOTHUB_CLIENT_LL_UPLOADTOBLOB_H
+
+#include "iothub_client_core_ll.h"
+#include "internal/iothub_client_authorization.h"
+
+#include "umock_c/umock_c_prod.h"
+#ifdef __cplusplus
+#include <cstddef>
+extern "C"
+{
+#else
+#include <stddef.h>
+#endif
+
+    #define BLOCK_SIZE (4*1024*1024)
+
+    typedef struct IOTHUB_CLIENT_LL_UPLOADTOBLOB_HANDLE_DATA* IOTHUB_CLIENT_LL_UPLOADTOBLOB_HANDLE;
+
+    MOCKABLE_FUNCTION(, IOTHUB_CLIENT_LL_UPLOADTOBLOB_HANDLE, IoTHubClient_LL_UploadToBlob_Create, const IOTHUB_CLIENT_CONFIG*, config, IOTHUB_AUTHORIZATION_HANDLE, auth_handle);
+    MOCKABLE_FUNCTION(, IOTHUB_CLIENT_RESULT, IoTHubClient_LL_UploadToBlob_Impl, IOTHUB_CLIENT_LL_UPLOADTOBLOB_HANDLE, handle, const char*, destinationFileName, const unsigned char*, source, size_t, size);
+    MOCKABLE_FUNCTION(, IOTHUB_CLIENT_RESULT, IoTHubClient_LL_UploadMultipleBlocksToBlob_Impl, IOTHUB_CLIENT_LL_UPLOADTOBLOB_HANDLE, handle, const char*, destinationFileName, IOTHUB_CLIENT_FILE_UPLOAD_GET_DATA_CALLBACK_EX, getDataCallbackEx, void*, context);
+    MOCKABLE_FUNCTION(, IOTHUB_CLIENT_RESULT, IoTHubClient_LL_UploadToBlob_SetOption, IOTHUB_CLIENT_LL_UPLOADTOBLOB_HANDLE, handle, const char*, optionName, const void*, value);
+    MOCKABLE_FUNCTION(, void, IoTHubClient_LL_UploadToBlob_Destroy, IOTHUB_CLIENT_LL_UPLOADTOBLOB_HANDLE, handle);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* IOTHUB_CLIENT_LL_UPLOADTOBLOB_H */
+
+#else
+#error "trying to #include iothub_client_ll_uploadtoblob.h in the presence of #define DONT_USE_UPLOADTOBLOB"
+#endif /*DONT_USE_UPLOADTOBLOB*/
Index: azure_iot_hub_f767zi/trunk/azure_iot_sdk/iothub_client/inc/internal/iothub_client_private.h
===================================================================
--- azure_iot_hub_f767zi/trunk/azure_iot_sdk/iothub_client/inc/internal/iothub_client_private.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/azure_iot_sdk/iothub_client/inc/internal/iothub_client_private.h	(revision 457)
@@ -0,0 +1,76 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+#ifndef IOTHUB_CLIENT_PRIVATE_H
+#define IOTHUB_CLIENT_PRIVATE_H
+
+#include <stdbool.h>
+
+#include "azure_c_shared_utility/constbuffer.h"
+#include "azure_c_shared_utility/doublylinkedlist.h"
+#include "azure_c_shared_utility/tickcounter.h"
+#include "umock_c/umock_c_prod.h"
+
+#include "iothub_message.h"
+#include "internal/iothub_transport_ll_private.h"
+#include "iothub_client_core_common.h"
+#include "iothub_client_core_ll.h"
+
+#ifdef USE_EDGE_MODULES
+#include "internal/iothub_client_edge.h"
+#endif
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#define CLIENT_DEVICE_TYPE_PREFIX "iothubclient"
+#define CLIENT_DEVICE_BACKSLASH "/"
+
+typedef bool(*IOTHUB_CLIENT_MESSAGE_CALLBACK_ASYNC_EX)(MESSAGE_CALLBACK_INFO* messageData, void* userContextCallback);
+
+MOCKABLE_FUNCTION(, IOTHUB_CLIENT_RESULT, IoTHubClientCore_LL_SetMessageCallback_Ex, IOTHUB_CLIENT_CORE_LL_HANDLE, iotHubClientHandle, IOTHUB_CLIENT_MESSAGE_CALLBACK_ASYNC_EX, messageCallback, void*, userContextCallback);
+MOCKABLE_FUNCTION(, IOTHUB_CLIENT_RESULT, IoTHubClientCore_LL_SendMessageDisposition, IOTHUB_CLIENT_CORE_LL_HANDLE, iotHubClientHandle, MESSAGE_CALLBACK_INFO*, messageData, IOTHUBMESSAGE_DISPOSITION_RESULT, disposition);
+MOCKABLE_FUNCTION(, IOTHUB_CLIENT_RESULT, IoTHubClientCore_LL_SetInputMessageCallbackEx, IOTHUB_CLIENT_CORE_LL_HANDLE, iotHubClientHandle, const char*, inputName, IOTHUB_CLIENT_MESSAGE_CALLBACK_ASYNC_EX, eventHandlerCallbackEx, void *, userContextCallback, size_t, userContextCallbackLength);
+MOCKABLE_FUNCTION(, int, IoTHubClientCore_LL_GetTransportCallbacks, TRANSPORT_CALLBACKS_INFO*, transport_cb);
+
+#ifdef USE_EDGE_MODULES
+/* (Should be replaced after iothub_client refactor)*/
+MOCKABLE_FUNCTION(, IOTHUB_CLIENT_EDGE_HANDLE, IoTHubClientCore_LL_GetEdgeHandle, IOTHUB_CLIENT_CORE_LL_HANDLE, iotHubClientHandle);
+MOCKABLE_FUNCTION(, IOTHUB_CLIENT_RESULT, IoTHubClientCore_LL_GenericMethodInvoke, IOTHUB_CLIENT_CORE_LL_HANDLE, iotHubClientHandle, const char*, deviceId, const char*, moduleId, const char*, methodName, const char*, methodPayload, unsigned int, timeout, int*, responseStatus, unsigned char**, responsePayload, size_t*, responsePayloadSize);
+#endif
+
+typedef struct IOTHUB_MESSAGE_LIST_TAG
+{
+    IOTHUB_MESSAGE_HANDLE messageHandle;
+    IOTHUB_CLIENT_EVENT_CONFIRMATION_CALLBACK callback;
+    void* context;
+    DLIST_ENTRY entry;
+    tickcounter_ms_t ms_timesOutAfter; /* a value of "0" means "no timeout", if the IOTHUBCLIENT_LL's handle tickcounter > msTimesOutAfer then the message shall timeout*/
+    tickcounter_ms_t message_timeout_value;
+}IOTHUB_MESSAGE_LIST;
+
+typedef struct IOTHUB_DEVICE_TWIN_TAG
+{
+    uint32_t item_id;
+    tickcounter_ms_t ms_timesOutAfter; /* a value of "0" means "no timeout", if the IOTHUBCLIENT_LL's handle tickcounter > msTimesOutAfer then the message shall timeout*/
+    IOTHUB_CLIENT_REPORTED_STATE_CALLBACK reported_state_callback;
+    CONSTBUFFER_HANDLE report_data_handle;
+    void* context;
+    DLIST_ENTRY entry;
+    IOTHUB_CLIENT_CORE_LL_HANDLE client_handle;
+    IOTHUB_DEVICE_HANDLE device_handle;
+} IOTHUB_DEVICE_TWIN;
+
+union IOTHUB_IDENTITY_INFO_TAG
+{
+    IOTHUB_DEVICE_TWIN* device_twin;
+    IOTHUB_MESSAGE_LIST* iothub_message;
+};
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* IOTHUB_CLIENT_PRIVATE_H */
Index: azure_iot_hub_f767zi/trunk/azure_iot_sdk/iothub_client/inc/internal/iothub_client_retry_control.h
===================================================================
--- azure_iot_hub_f767zi/trunk/azure_iot_sdk/iothub_client/inc/internal/iothub_client_retry_control.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/azure_iot_sdk/iothub_client/inc/internal/iothub_client_retry_control.h	(revision 457)
@@ -0,0 +1,48 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+#ifndef IOTHUB_CLIENT_RETRY_CONTROL
+#define IOTHUB_CLIENT_RETRY_CONTROL
+
+#include <stdlib.h>
+#include <stdbool.h>
+#include "azure_c_shared_utility/optionhandler.h"
+#include "umock_c/umock_c_prod.h"
+#include "iothub_client_core_ll.h"
+#include "internal/iothubtransport.h"
+#include "azure_c_shared_utility/const_defines.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+static STATIC_VAR_UNUSED const char* RETRY_CONTROL_OPTION_INITIAL_WAIT_TIME_IN_SECS = "initial_wait_time_in_secs";
+static STATIC_VAR_UNUSED const char* RETRY_CONTROL_OPTION_MAX_JITTER_PERCENT = "max_jitter_percent";
+static STATIC_VAR_UNUSED const char* RETRY_CONTROL_OPTION_MAX_DELAY_IN_SECS = "max_delay_in_secs";
+static STATIC_VAR_UNUSED const char* RETRY_CONTROL_OPTION_SAVED_OPTIONS = "retry_control_saved_options";
+
+typedef enum RETRY_ACTION_TAG
+{
+    RETRY_ACTION_RETRY_NOW,
+    RETRY_ACTION_RETRY_LATER,
+    RETRY_ACTION_STOP_RETRYING
+} RETRY_ACTION;
+
+struct RETRY_CONTROL_INSTANCE_TAG;
+typedef struct RETRY_CONTROL_INSTANCE_TAG* RETRY_CONTROL_HANDLE;
+
+MOCKABLE_FUNCTION(, RETRY_CONTROL_HANDLE, retry_control_create, IOTHUB_CLIENT_RETRY_POLICY, policy, unsigned int, max_retry_time_in_secs);
+MOCKABLE_FUNCTION(, int, retry_control_should_retry, RETRY_CONTROL_HANDLE, retry_control_handle, RETRY_ACTION*, retry_action);
+MOCKABLE_FUNCTION(, void, retry_control_reset, RETRY_CONTROL_HANDLE, retry_control_handle);
+MOCKABLE_FUNCTION(, int, retry_control_set_option, RETRY_CONTROL_HANDLE, retry_control_handle, const char*, name, const void*, value);
+MOCKABLE_FUNCTION(, OPTIONHANDLER_HANDLE, retry_control_retrieve_options, RETRY_CONTROL_HANDLE, retry_control_handle);
+MOCKABLE_FUNCTION(, void, retry_control_destroy, RETRY_CONTROL_HANDLE, retry_control_handle);
+
+MOCKABLE_FUNCTION(, int, is_timeout_reached, time_t, start_time, unsigned int, timeout_in_secs, bool*, is_timed_out);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // IOTHUB_CLIENT_RETRY_CONTROL
Index: azure_iot_hub_f767zi/trunk/azure_iot_sdk/iothub_client/inc/internal/iothub_internal_consts.h
===================================================================
--- azure_iot_hub_f767zi/trunk/azure_iot_sdk/iothub_client/inc/internal/iothub_internal_consts.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/azure_iot_sdk/iothub_client/inc/internal/iothub_internal_consts.h	(revision 457)
@@ -0,0 +1,29 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+#ifndef IOTHUB_INTERNAL_CONSTS_H
+#define IOTHUB_INTERNAL_CONSTS_H
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+    static const char* IOTHUB_API_VERSION = "2019-10-01";
+    // TODO: https://github.com/Azure/azure-iot-sdk-c/issues/1547 tracks removing this preview 
+    // variable once the underlying logic is enabled on all IoTHubs.
+    static const char* IOTHUB_API_PREVIEW_VERSION = "2020-05-31-preview";
+
+    static const char* SECURITY_INTERFACE_INTERNAL_ID = "iothub-interface-internal-id";
+    static const char* SECURITY_INTERFACE_INTERNAL_ID_VALUE = "security*azureiot*com^SecurityAgent^1*0*0";
+    static const char* SECURITY_INTERFACE_ID = "iothub-interface-id";
+    static const char* SECURITY_INTERFACE_ID_MQTT = "ifid";
+    static const char* SECURITY_INTERFACE_ID_VALUE = "urn:azureiot:Security:SecurityAgent:1";
+    static const char* SECURITY_MESSAGE_SCHEMA = "iothub-message-schema";
+    static const char* SECURITY_MESSAGE_SCHEMA_VALUE = "sevent";
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* IOTHUB_INTERNAL_CONSTS_H */
Index: azure_iot_hub_f767zi/trunk/azure_iot_sdk/iothub_client/inc/internal/iothub_transport_ll_private.h
===================================================================
--- azure_iot_hub_f767zi/trunk/azure_iot_sdk/iothub_client/inc/internal/iothub_transport_ll_private.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/azure_iot_sdk/iothub_client/inc/internal/iothub_transport_ll_private.h	(revision 457)
@@ -0,0 +1,134 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+#ifndef IOTHUB_TRANSPORT_LL_PRIVATE_H
+#define IOTHUB_TRANSPORT_LL_PRIVATE_H
+
+#include "iothub_transport_ll.h"
+
+union IOTHUB_IDENTITY_INFO_TAG;
+typedef union IOTHUB_IDENTITY_INFO_TAG IOTHUB_IDENTITY_INFO;
+
+#include "azure_c_shared_utility/doublylinkedlist.h"
+#include "azure_c_shared_utility/strings.h"
+#include "azure_c_shared_utility/platform.h"
+#include "internal/iothub_client_authorization.h"
+#include "iothub_message.h"
+
+struct MESSAGE_DISPOSITION_CONTEXT_TAG;
+typedef struct MESSAGE_DISPOSITION_CONTEXT_TAG* MESSAGE_DISPOSITION_CONTEXT_HANDLE;
+typedef struct MESSAGE_CALLBACK_INFO_TAG
+{
+    IOTHUB_MESSAGE_HANDLE messageHandle;
+    MESSAGE_DISPOSITION_CONTEXT_HANDLE transportContext;
+}MESSAGE_CALLBACK_INFO;
+
+#include "iothub_client_ll.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+    typedef bool (*pfTransport_MessageCallbackFromInput)(MESSAGE_CALLBACK_INFO* messageData, void* ctx);
+    typedef bool (*pfTransport_MessageCallback)(MESSAGE_CALLBACK_INFO* messageData, void* ctx);
+    typedef void (*pfTransport_ConnectionStatusCallBack)(IOTHUB_CLIENT_CONNECTION_STATUS status, IOTHUB_CLIENT_CONNECTION_STATUS_REASON reason, void* ctx);
+    typedef void (*pfTransport_SendComplete_Callback)(PDLIST_ENTRY completed, IOTHUB_CLIENT_CONFIRMATION_RESULT result, void* ctx);
+    typedef const char* (*pfTransport_GetOption_Product_Info_Callback)(void* ctx);
+    typedef void (*pfTransport_Twin_ReportedStateComplete_Callback)(uint32_t item_id, int status_code, void* ctx);
+    typedef void (*pfTransport_Twin_RetrievePropertyComplete_Callback)(DEVICE_TWIN_UPDATE_STATE update_state, const unsigned char* payLoad, size_t size, void* ctx);
+    typedef int (*pfTransport_DeviceMethod_Complete_Callback)(const char* method_name, const unsigned char* payLoad, size_t size, METHOD_HANDLE response_id, void* ctx);
+    typedef const char* (*pfTransport_GetOption_Model_Id_Callback)(void* ctx);
+
+    /** @brief    This struct captures device configuration. */
+    typedef struct IOTHUB_DEVICE_CONFIG_TAG
+    {
+        /** @brief    A string that identifies the device. */
+        const char* deviceId;
+
+        /** @brief    The device key used to authenticate the device. */
+        const char* deviceKey;
+
+        /** @brief    The device SAS used to authenticate the device in place of using the device key. */
+        const char* deviceSasToken;
+
+        IOTHUB_AUTHORIZATION_HANDLE authorization_module; // with either SAS Token, x509 Certs, and Device SAS Token
+
+        /** @brief  A string that identifies the module.  Optional. */
+        const char* moduleId;
+    } IOTHUB_DEVICE_CONFIG;
+
+    typedef struct TRANSPORT_CALLBACKS_INFO_TAG
+    {
+        pfTransport_MessageCallbackFromInput msg_input_cb;
+        pfTransport_MessageCallback msg_cb;
+        pfTransport_ConnectionStatusCallBack connection_status_cb;
+        pfTransport_SendComplete_Callback send_complete_cb;
+        pfTransport_GetOption_Product_Info_Callback prod_info_cb;
+        pfTransport_Twin_ReportedStateComplete_Callback twin_rpt_state_complete_cb;
+        pfTransport_Twin_RetrievePropertyComplete_Callback twin_retrieve_prop_complete_cb;
+        pfTransport_DeviceMethod_Complete_Callback method_complete_cb;
+        pfTransport_GetOption_Model_Id_Callback get_model_id_cb;
+    } TRANSPORT_CALLBACKS_INFO;
+
+    typedef STRING_HANDLE (*pfIoTHubTransport_GetHostname)(TRANSPORT_LL_HANDLE handle);
+    typedef IOTHUB_CLIENT_RESULT(*pfIoTHubTransport_SetOption)(TRANSPORT_LL_HANDLE handle, const char *optionName, const void* value);
+    typedef TRANSPORT_LL_HANDLE(*pfIoTHubTransport_Create)(const IOTHUBTRANSPORT_CONFIG* config, TRANSPORT_CALLBACKS_INFO* cb_info, void* ctx);
+    typedef void (*pfIoTHubTransport_Destroy)(TRANSPORT_LL_HANDLE handle);
+    typedef IOTHUB_DEVICE_HANDLE(*pfIotHubTransport_Register)(TRANSPORT_LL_HANDLE handle, const IOTHUB_DEVICE_CONFIG* device, PDLIST_ENTRY waitingToSend);
+    typedef void(*pfIotHubTransport_Unregister)(IOTHUB_DEVICE_HANDLE deviceHandle);
+    typedef int (*pfIoTHubTransport_Subscribe)(IOTHUB_DEVICE_HANDLE handle);
+    typedef void (*pfIoTHubTransport_Unsubscribe)(IOTHUB_DEVICE_HANDLE handle);
+    typedef void (*pfIoTHubTransport_DoWork)(TRANSPORT_LL_HANDLE handle);
+    typedef int(*pfIoTHubTransport_SetRetryPolicy)(TRANSPORT_LL_HANDLE handle, IOTHUB_CLIENT_RETRY_POLICY retryPolicy, size_t retryTimeoutLimitInSeconds);
+    typedef IOTHUB_CLIENT_RESULT(*pfIoTHubTransport_GetSendStatus)(IOTHUB_DEVICE_HANDLE handle, IOTHUB_CLIENT_STATUS *iotHubClientStatus);
+    typedef int (*pfIoTHubTransport_Subscribe_DeviceTwin)(IOTHUB_DEVICE_HANDLE handle);
+    typedef void (*pfIoTHubTransport_Unsubscribe_DeviceTwin)(IOTHUB_DEVICE_HANDLE handle);
+    typedef IOTHUB_CLIENT_RESULT(*pfIoTHubTransport_GetTwinAsync)(IOTHUB_DEVICE_HANDLE handle, IOTHUB_CLIENT_DEVICE_TWIN_CALLBACK completionCallback, void* callbackContext);
+    typedef IOTHUB_CLIENT_RESULT(*pfIotHubTransport_SendMessageDisposition)(MESSAGE_CALLBACK_INFO* messageData, IOTHUBMESSAGE_DISPOSITION_RESULT disposition);
+    typedef IOTHUB_PROCESS_ITEM_RESULT(*pfIoTHubTransport_ProcessItem)(TRANSPORT_LL_HANDLE handle, IOTHUB_IDENTITY_TYPE item_type, IOTHUB_IDENTITY_INFO* iothub_item);
+    typedef int(*pfIoTHubTransport_Subscribe_DeviceMethod)(IOTHUB_DEVICE_HANDLE handle);
+    typedef void(*pfIoTHubTransport_Unsubscribe_DeviceMethod)(IOTHUB_DEVICE_HANDLE handle);
+    typedef int(*pfIoTHubTransport_DeviceMethod_Response)(IOTHUB_DEVICE_HANDLE handle, METHOD_HANDLE methodId, const unsigned char* response, size_t response_size, int status_response);
+    typedef int(*pfIoTHubTransport_Subscribe_InputQueue)(IOTHUB_DEVICE_HANDLE handle);
+    typedef void(*pfIoTHubTransport_Unsubscribe_InputQueue)(IOTHUB_DEVICE_HANDLE handle);
+    typedef int(*pfIoTHubTransport_SetCallbackContext)(TRANSPORT_LL_HANDLE handle, void* ctx);
+    typedef int(*pfIoTHubTransport_GetSupportedPlatformInfo)(TRANSPORT_LL_HANDLE handle, PLATFORM_INFO_OPTION* info);
+
+#define TRANSPORT_PROVIDER_FIELDS                                                   \
+pfIotHubTransport_SendMessageDisposition IoTHubTransport_SendMessageDisposition;    \
+pfIoTHubTransport_Subscribe_DeviceMethod IoTHubTransport_Subscribe_DeviceMethod;    \
+pfIoTHubTransport_Unsubscribe_DeviceMethod IoTHubTransport_Unsubscribe_DeviceMethod;\
+pfIoTHubTransport_DeviceMethod_Response IoTHubTransport_DeviceMethod_Response;      \
+pfIoTHubTransport_Subscribe_DeviceTwin IoTHubTransport_Subscribe_DeviceTwin;        \
+pfIoTHubTransport_Unsubscribe_DeviceTwin IoTHubTransport_Unsubscribe_DeviceTwin;    \
+pfIoTHubTransport_ProcessItem IoTHubTransport_ProcessItem;                          \
+pfIoTHubTransport_GetHostname IoTHubTransport_GetHostname;                          \
+pfIoTHubTransport_SetOption IoTHubTransport_SetOption;                              \
+pfIoTHubTransport_Create IoTHubTransport_Create;                                    \
+pfIoTHubTransport_Destroy IoTHubTransport_Destroy;                                  \
+pfIotHubTransport_Register IoTHubTransport_Register;                                \
+pfIotHubTransport_Unregister IoTHubTransport_Unregister;                            \
+pfIoTHubTransport_Subscribe IoTHubTransport_Subscribe;                              \
+pfIoTHubTransport_Unsubscribe IoTHubTransport_Unsubscribe;                          \
+pfIoTHubTransport_DoWork IoTHubTransport_DoWork;                                    \
+pfIoTHubTransport_SetRetryPolicy IoTHubTransport_SetRetryPolicy;                    \
+pfIoTHubTransport_GetSendStatus IoTHubTransport_GetSendStatus;                      \
+pfIoTHubTransport_Subscribe_InputQueue IoTHubTransport_Subscribe_InputQueue;        \
+pfIoTHubTransport_Unsubscribe_InputQueue IoTHubTransport_Unsubscribe_InputQueue;    \
+pfIoTHubTransport_SetCallbackContext IoTHubTransport_SetCallbackContext;            \
+pfIoTHubTransport_GetTwinAsync IoTHubTransport_GetTwinAsync;                        \
+pfIoTHubTransport_GetSupportedPlatformInfo IoTHubTransport_GetSupportedPlatformInfo     /*there's an intentional missing ; on this line*/
+
+    struct TRANSPORT_PROVIDER_TAG
+    {
+        TRANSPORT_PROVIDER_FIELDS;
+    };
+
+    MOCKABLE_FUNCTION(, int, IoTHub_Transport_ValidateCallbacks, const TRANSPORT_CALLBACKS_INFO*, transport_cb);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* IOTHUB_TRANSPORT_LL_PRIVATE_H */
Index: azure_iot_hub_f767zi/trunk/azure_iot_sdk/iothub_client/inc/internal/iothubtransport.h
===================================================================
--- azure_iot_hub_f767zi/trunk/azure_iot_sdk/iothub_client/inc/internal/iothubtransport.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/azure_iot_sdk/iothub_client/inc/internal/iothubtransport.h	(revision 457)
@@ -0,0 +1,49 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+#ifndef IOTHUB_TRANSPORT_H
+#define IOTHUB_TRANSPORT_H
+
+#include "azure_c_shared_utility/lock.h"
+#include "azure_c_shared_utility/crt_abstractions.h"
+#include "iothub_transport_ll.h"
+#include "iothub_client_core.h"
+#include "internal/iothub_client_private.h"
+#include "internal/iothub_transport_ll_private.h"
+#include "internal/iothub_client_authorization.h"
+
+#ifndef IOTHUB_CLIENT_CORE_INSTANCE_TYPE
+typedef struct IOTHUB_CLIENT_CORE_INSTANCE_TAG* IOTHUB_CLIENT_CORE_HANDLE;
+#define IOTHUB_CLIENT_CORE_INSTANCE_TYPE
+#endif // IOTHUB_CLIENT_CORE_INSTANCE
+
+#ifdef __cplusplus
+extern "C"
+{
+#else
+#include <stdbool.h>
+#endif
+
+#include "umock_c/umock_c_prod.h"
+
+    /** @brief  This struct captures IoTHub transport configuration. */
+    struct IOTHUBTRANSPORT_CONFIG_TAG
+    {
+        const IOTHUB_CLIENT_CONFIG* upperConfig;
+        PDLIST_ENTRY waitingToSend;
+        IOTHUB_AUTHORIZATION_HANDLE auth_module_handle;
+        const char* moduleId;
+    };
+
+    typedef void(*IOTHUB_CLIENT_MULTIPLEXED_DO_WORK)(void* iotHubClientInstance);
+
+    MOCKABLE_FUNCTION(, LOCK_HANDLE, IoTHubTransport_GetLock, TRANSPORT_HANDLE, transportHandle);
+    MOCKABLE_FUNCTION(, IOTHUB_CLIENT_RESULT, IoTHubTransport_StartWorkerThread, TRANSPORT_HANDLE, transportHandle, IOTHUB_CLIENT_CORE_HANDLE, clientHandle, IOTHUB_CLIENT_MULTIPLEXED_DO_WORK, muxDoWork);
+    MOCKABLE_FUNCTION(, bool, IoTHubTransport_SignalEndWorkerThread, TRANSPORT_HANDLE, transportHandle, IOTHUB_CLIENT_CORE_HANDLE, clientHandle);
+    MOCKABLE_FUNCTION(, void, IoTHubTransport_JoinWorkerThread, TRANSPORT_HANDLE, transportHandle, IOTHUB_CLIENT_CORE_HANDLE, clientHandle);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* IOTHUB_TRANSPORT_H */
Index: azure_iot_hub_f767zi/trunk/azure_iot_sdk/iothub_client/inc/internal/iothubtransport_mqtt_common.h
===================================================================
--- azure_iot_hub_f767zi/trunk/azure_iot_sdk/iothub_client/inc/internal/iothubtransport_mqtt_common.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/azure_iot_sdk/iothub_client/inc/internal/iothubtransport_mqtt_common.h	(revision 457)
@@ -0,0 +1,56 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+#ifndef IOTHUBTRANSPORT_MQTT_COMMON_H
+#define IOTHUBTRANSPORT_MQTT_COMMON_H
+
+#include "internal/iothub_transport_ll_private.h"
+#include "umock_c/umock_c_prod.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#include <cstdlib>
+#else
+#include <stdlib.h>
+#endif
+
+typedef struct MQTT_TRANSPORT_PROXY_OPTIONS_TAG
+{
+    const char* host_address;
+    int port;
+    const char* username;
+    const char* password;
+} MQTT_TRANSPORT_PROXY_OPTIONS;
+
+typedef XIO_HANDLE(*MQTT_GET_IO_TRANSPORT)(const char* fully_qualified_name, const MQTT_TRANSPORT_PROXY_OPTIONS* mqtt_transport_proxy_options);
+
+MOCKABLE_FUNCTION(, TRANSPORT_LL_HANDLE, IoTHubTransport_MQTT_Common_Create, const IOTHUBTRANSPORT_CONFIG*,  config, MQTT_GET_IO_TRANSPORT, get_io_transport, TRANSPORT_CALLBACKS_INFO*, cb_info, void*, ctx);
+MOCKABLE_FUNCTION(, void, IoTHubTransport_MQTT_Common_Destroy, TRANSPORT_LL_HANDLE, handle);
+MOCKABLE_FUNCTION(, int, IoTHubTransport_MQTT_Common_Subscribe, TRANSPORT_LL_HANDLE, handle);
+MOCKABLE_FUNCTION(, void, IoTHubTransport_MQTT_Common_Unsubscribe, TRANSPORT_LL_HANDLE, handle);
+MOCKABLE_FUNCTION(, int, IoTHubTransport_MQTT_Common_Subscribe_DeviceTwin, TRANSPORT_LL_HANDLE, handle);
+MOCKABLE_FUNCTION(, IOTHUB_CLIENT_RESULT, IoTHubTransport_MQTT_Common_GetTwinAsync, IOTHUB_DEVICE_HANDLE, handle, IOTHUB_CLIENT_DEVICE_TWIN_CALLBACK, completionCallback, void*, callbackContext);
+MOCKABLE_FUNCTION(, void, IoTHubTransport_MQTT_Common_Unsubscribe_DeviceTwin, TRANSPORT_LL_HANDLE, handle);
+MOCKABLE_FUNCTION(, int, IoTHubTransport_MQTT_Common_Subscribe_DeviceMethod, TRANSPORT_LL_HANDLE, handle);
+MOCKABLE_FUNCTION(, void, IoTHubTransport_MQTT_Common_Unsubscribe_DeviceMethod, TRANSPORT_LL_HANDLE, handle);
+MOCKABLE_FUNCTION(, int, IoTHubTransport_MQTT_Common_DeviceMethod_Response, TRANSPORT_LL_HANDLE, handle, METHOD_HANDLE, methodId, const unsigned char*, response, size_t, response_size, int, status_response);
+MOCKABLE_FUNCTION(, IOTHUB_PROCESS_ITEM_RESULT, IoTHubTransport_MQTT_Common_ProcessItem, TRANSPORT_LL_HANDLE, handle, IOTHUB_IDENTITY_TYPE, item_type, IOTHUB_IDENTITY_INFO*, iothub_item);
+MOCKABLE_FUNCTION(, void, IoTHubTransport_MQTT_Common_DoWork, TRANSPORT_LL_HANDLE, handle);
+MOCKABLE_FUNCTION(, IOTHUB_CLIENT_RESULT, IoTHubTransport_MQTT_Common_GetSendStatus, TRANSPORT_LL_HANDLE, handle, IOTHUB_CLIENT_STATUS*, iotHubClientStatus);
+MOCKABLE_FUNCTION(, IOTHUB_CLIENT_RESULT, IoTHubTransport_MQTT_Common_SetOption, TRANSPORT_LL_HANDLE, handle, const char*, option, const void*, value);
+MOCKABLE_FUNCTION(, TRANSPORT_LL_HANDLE, IoTHubTransport_MQTT_Common_Register, TRANSPORT_LL_HANDLE, handle, const IOTHUB_DEVICE_CONFIG*, device, PDLIST_ENTRY, waitingToSend);
+MOCKABLE_FUNCTION(, void, IoTHubTransport_MQTT_Common_Unregister, TRANSPORT_LL_HANDLE, deviceHandle);
+MOCKABLE_FUNCTION(, int, IoTHubTransport_MQTT_Common_SetRetryPolicy, TRANSPORT_LL_HANDLE, handle, IOTHUB_CLIENT_RETRY_POLICY, retryPolicy, size_t, retryTimeoutLimitInSeconds);
+MOCKABLE_FUNCTION(, STRING_HANDLE, IoTHubTransport_MQTT_Common_GetHostname, TRANSPORT_LL_HANDLE, handle);
+MOCKABLE_FUNCTION(, IOTHUB_CLIENT_RESULT, IoTHubTransport_MQTT_Common_SendMessageDisposition, MESSAGE_CALLBACK_INFO*, message_data, IOTHUBMESSAGE_DISPOSITION_RESULT, disposition);
+MOCKABLE_FUNCTION(, int, IoTHubTransport_MQTT_Common_Subscribe_InputQueue, TRANSPORT_LL_HANDLE, handle);
+MOCKABLE_FUNCTION(, void, IoTHubTransport_MQTT_Common_Unsubscribe_InputQueue, TRANSPORT_LL_HANDLE, handle);
+MOCKABLE_FUNCTION(, int, IoTHubTransport_MQTT_SetCallbackContext, TRANSPORT_LL_HANDLE, handle, void*, ctx);
+MOCKABLE_FUNCTION(, int, IoTHubTransport_MQTT_GetSupportedPlatformInfo, TRANSPORT_LL_HANDLE, handle, PLATFORM_INFO_OPTION*, info);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* IOTHUBTRANSPORT_MQTT_COMMON_H */
Index: azure_iot_hub_f767zi/trunk/azure_iot_sdk/iothub_client/inc/iothub.h
===================================================================
--- azure_iot_hub_f767zi/trunk/azure_iot_sdk/iothub_client/inc/iothub.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/azure_iot_sdk/iothub_client/inc/iothub.h	(revision 457)
@@ -0,0 +1,31 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+#ifndef IOTHUB_H
+#define IOTHUB_H
+
+#include "umock_c/umock_c_prod.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#else
+#endif
+    /**
+    * @brief    IoTHubClient_Init Initializes the IoTHub Client System.
+    *
+    * @return   int zero upon success, any other value upon failure.
+    */
+    MOCKABLE_FUNCTION(, int, IoTHub_Init);
+
+    /**
+    * @brief    IoTHubClient_Deinit Frees resources initialized in the IoTHubClient_Init function call.
+    *
+    */
+    MOCKABLE_FUNCTION(, void, IoTHub_Deinit);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* IOTHUB_H */
Index: azure_iot_hub_f767zi/trunk/azure_iot_sdk/iothub_client/inc/iothub_client.h
===================================================================
--- azure_iot_hub_f767zi/trunk/azure_iot_sdk/iothub_client/inc/iothub_client.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/azure_iot_sdk/iothub_client/inc/iothub_client.h	(revision 457)
@@ -0,0 +1,396 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+/** @file iothub_client.h
+*    @brief Extends the IoTHubCLient_LL module with additional features.
+*
+*    @note  DEPRECATED. New users use iothub_device_client.h for IoTHubClient APIs.
+*    @details IoTHubClient is a module that extends the IoTHubCLient_LL
+*             module with 2 features:
+*                - scheduling the work for the IoTHubCLient from a
+*                  thread, so that the user does not need to create their
+*                  own thread
+*                - thread-safe APIs
+*/
+
+#ifndef IOTHUB_CLIENT_H
+#define IOTHUB_CLIENT_H
+
+#include <stddef.h>
+#include <stdint.h>
+
+#include "umock_c/umock_c_prod.h"
+#include "iothub_transport_ll.h"
+#include "iothub_client_core_ll.h"
+#include "iothub_client_core.h"
+#include "iothub_client_ll.h"
+
+#ifndef IOTHUB_CLIENT_INSTANCE_TYPE
+typedef IOTHUB_CLIENT_CORE_HANDLE IOTHUB_CLIENT_HANDLE;
+#define IOTHUB_CLIENT_INSTANCE_TYPE
+#endif // IOTHUB_CLIENT_INSTANCE
+
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+    /**
+    * @brief    Creates a IoT Hub client for communication with an existing
+    *             IoT Hub using the specified connection string parameter.
+    *
+    * @param    connectionString    Pointer to a character string
+    * @param    protocol            Function pointer for protocol implementation
+    *
+    *            Sample connection string:
+    *                <blockquote>
+    *                    <pre>HostName=[IoT Hub name goes here].[IoT Hub suffix goes here, e.g., private.azure-devices-int.net];DeviceId=[Device ID goes here];SharedAccessKey=[Device key goes here];</pre>
+    *                   <pre>HostName=[IoT Hub name goes here].[IoT Hub suffix goes here, e.g., private.azure-devices-int.net];DeviceId=[Device ID goes here];SharedAccessSignature=SharedAccessSignature sr=[IoT Hub name goes here].[IoT Hub suffix goes here, e.g., private.azure-devices-int.net]/devices/[Device ID goes here]&sig=[SAS Token goes here]&se=[Expiry Time goes here];</pre>
+    *                </blockquote>
+    *
+    * @return    A non-NULL @c IOTHUB_CLIENT_HANDLE value that is used when
+    *             invoking other functions for IoT Hub client and @c NULL on failure.
+    */
+    MOCKABLE_FUNCTION(, IOTHUB_CLIENT_HANDLE, IoTHubClient_CreateFromConnectionString, const char*, connectionString, IOTHUB_CLIENT_TRANSPORT_PROVIDER, protocol);
+
+    /**
+    * @brief    Creates a IoT Hub client for communication with an existing IoT
+    *             Hub using the specified parameters.
+    *
+    * @param    config    Pointer to an @c IOTHUB_CLIENT_CONFIG structure
+    *
+    *            The API does not allow sharing of a connection across multiple
+    *            devices. This is a blocking call.
+    *
+    * @return    A non-NULL @c IOTHUB_CLIENT_HANDLE value that is used when
+    *             invoking other functions for IoT Hub client and @c NULL on failure.
+    */
+    MOCKABLE_FUNCTION(, IOTHUB_CLIENT_HANDLE, IoTHubClient_Create, const IOTHUB_CLIENT_CONFIG*, config);
+
+    /**
+    * @brief    Creates a IoT Hub client for communication with an existing IoT
+    *             Hub using the specified parameters.
+    *
+    * @param    transportHandle    TRANSPORT_HANDLE which represents a connection.
+    * @param    config    Pointer to an @c IOTHUB_CLIENT_CONFIG structure
+    *
+    *            The API allows sharing of a connection across multiple
+    *            devices. This is a blocking call.
+    *
+    * @return    A non-NULL @c IOTHUB_CLIENT_HANDLE value that is used when
+    *             invoking other functions for IoT Hub client and @c NULL on failure.
+    */
+    MOCKABLE_FUNCTION(, IOTHUB_CLIENT_HANDLE, IoTHubClient_CreateWithTransport, TRANSPORT_HANDLE, transportHandle, const IOTHUB_CLIENT_CONFIG*, config);
+
+    /**
+    * @brief    Creates a IoT Hub client for communication with an existing IoT
+    *             Hub using the device auth module.
+    *
+    * @param    iothub_uri    Pointer to an ioThub hostname received in the registration process
+    * @param    device_id    Pointer to the device Id of the device
+    * @param    protocol    Function pointer for protocol implementation
+    *
+    * @return    A non-NULL @c IOTHUB_CLIENT_LL_HANDLE value that is used when
+    *             invoking other functions for IoT Hub client and @c NULL on failure.
+    */
+    MOCKABLE_FUNCTION(, IOTHUB_CLIENT_HANDLE, IoTHubClient_CreateFromDeviceAuth, const char*, iothub_uri, const char*, device_id, IOTHUB_CLIENT_TRANSPORT_PROVIDER, protocol);
+
+    /**
+    * @brief    Disposes of resources allocated by the IoT Hub client. This is a
+    *             blocking call.
+    *
+    * @param    iotHubClientHandle    The handle created by a call to the create function.
+    */
+    MOCKABLE_FUNCTION(, void, IoTHubClient_Destroy, IOTHUB_CLIENT_HANDLE, iotHubClientHandle);
+
+    /**
+    * @brief    Asynchronous call to send the message specified by @p eventMessageHandle.
+    *
+    * @param    iotHubClientHandle               The handle created by a call to the create function.
+    * @param    eventMessageHandle               The handle to an IoT Hub message.
+    * @param    eventConfirmationCallback      The callback specified by the device for receiving
+    *                                         confirmation of the delivery of the IoT Hub message.
+    *                                         This callback can be expected to invoke the
+    *                                         ::IoTHubClient_SendEventAsync function for the
+    *                                         same message in an attempt to retry sending a failing
+    *                                         message. The user can specify a @c NULL value here to
+    *                                         indicate that no callback is required.
+    * @param    userContextCallback            User specified context that will be provided to the
+    *                                         callback. This can be @c NULL.
+    *
+    *            @b NOTE: The application behavior is undefined if the user calls
+    *            the ::IoTHubClient_Destroy function from within any callback.
+    * @remarks
+    *            The IOTHUB_MESSAGE_HANDLE instance provided as argument is copied by the function,
+    *            so this argument can be destroyed by the calling application right after IoTHubClient_SendEventAsync returns.
+    *            The copy of @c eventMessageHandle is later destroyed by the iothub client when the message is effectively sent, if a failure sending it occurs, or if the client is destroyed.
+    * @return    IOTHUB_CLIENT_OK upon success or an error code upon failure.
+    */
+    MOCKABLE_FUNCTION(, IOTHUB_CLIENT_RESULT, IoTHubClient_SendEventAsync, IOTHUB_CLIENT_HANDLE, iotHubClientHandle, IOTHUB_MESSAGE_HANDLE, eventMessageHandle, IOTHUB_CLIENT_EVENT_CONFIRMATION_CALLBACK, eventConfirmationCallback, void*, userContextCallback);
+
+    /**
+    * @brief    This function returns the current sending status for IoTHubClient.
+    *
+    * @param    iotHubClientHandle        The handle created by a call to the create function.
+    * @param    iotHubClientStatus        The sending state is populated at the address pointed
+    *                                     at by this parameter. The value will be set to
+    *                                     @c IOTHUBCLIENT_SENDSTATUS_IDLE if there is currently
+    *                                     no item to be sent and @c IOTHUBCLIENT_SENDSTATUS_BUSY
+    *                                     if there are.
+    *
+    * @return    IOTHUB_CLIENT_OK upon success or an error code upon failure.
+    */
+    MOCKABLE_FUNCTION(, IOTHUB_CLIENT_RESULT, IoTHubClient_GetSendStatus, IOTHUB_CLIENT_HANDLE, iotHubClientHandle, IOTHUB_CLIENT_STATUS*, iotHubClientStatus);
+
+    /**
+    * @brief    Sets up the message callback to be invoked when IoT Hub issues a
+    *             message to the device. This is a blocking call.
+    *
+    * @param    iotHubClientHandle               The handle created by a call to the create function.
+    * @param    messageCallback                The callback specified by the device for receiving
+    *                                         messages from IoT Hub.
+    * @param    userContextCallback            User specified context that will be provided to the
+    *                                         callback. This can be @c NULL.
+    *
+    *            @b NOTE: The application behavior is undefined if the user calls
+    *            the ::IoTHubClient_Destroy function from within any callback.
+    *
+    * @return    IOTHUB_CLIENT_OK upon success or an error code upon failure.
+    */
+    MOCKABLE_FUNCTION(, IOTHUB_CLIENT_RESULT, IoTHubClient_SetMessageCallback, IOTHUB_CLIENT_HANDLE, iotHubClientHandle, IOTHUB_CLIENT_MESSAGE_CALLBACK_ASYNC, messageCallback, void*, userContextCallback);
+
+    /**
+    * @brief    Sets up the connection status callback to be invoked representing the status of
+    * the connection to IOT Hub. This is a blocking call.
+    *
+    * @param    iotHubClientHandle                       The handle created by a call to the create function.
+    * @param    connectionStatusCallback                The callback specified by the device for receiving
+    *                                                 updates about the status of the connection to IoT Hub.
+    * @param    userContextCallback                    User specified context that will be provided to the
+    *                                                 callback. This can be @c NULL.
+    *
+    *            @b NOTE: The application behavior is undefined if the user calls
+    *            the ::IoTHubClient_LL_Destroy function from within any callback.
+    *
+    * @return    IOTHUB_CLIENT_OK upon success or an error code upon failure.
+    */
+    MOCKABLE_FUNCTION(, IOTHUB_CLIENT_RESULT, IoTHubClient_SetConnectionStatusCallback, IOTHUB_CLIENT_HANDLE, iotHubClientHandle, IOTHUB_CLIENT_CONNECTION_STATUS_CALLBACK, connectionStatusCallback, void*, userContextCallback);
+
+    /**
+    * @brief    Sets up the connection status callback to be invoked representing the status of
+    * the connection to IOT Hub. This is a blocking call.
+    *
+    * @param    iotHubClientHandle                       The handle created by a call to the create function.
+    * @param    retryPolicy                             The policy to use to reconnect to IoT Hub when a
+    *                                               connection drops.
+    * @param    retryTimeoutLimitInSeconds            Maximum amount of time(seconds) to attempt reconnection when a
+    *                                               connection drops to IOT Hub.
+    *
+    *            @b NOTE: The application behavior is undefined if the user calls
+    *            the ::IoTHubClient_LL_Destroy function from within any callback.
+    *
+    * @return    IOTHUB_CLIENT_OK upon success or an error code upon failure.
+    */
+    MOCKABLE_FUNCTION(, IOTHUB_CLIENT_RESULT, IoTHubClient_SetRetryPolicy, IOTHUB_CLIENT_HANDLE, iotHubClientHandle, IOTHUB_CLIENT_RETRY_POLICY, retryPolicy, size_t, retryTimeoutLimitInSeconds);
+
+    /**
+    * @brief    Sets up the connection status callback to be invoked representing the status of
+    * the connection to IOT Hub. This is a blocking call.
+    *
+    * @param    iotHubClientHandle                       The handle created by a call to the create function.
+    * @param    retryPolicy                             Out parameter containing the policy to use to reconnect to IoT Hub.
+    * @param    retryTimeoutLimitInSeconds            Out parameter containing maximum amount of time in seconds to attempt reconnection
+    to IOT Hub.
+    *
+    *            @b NOTE: The application behavior is undefined if the user calls
+    *            the ::IoTHubClient_LL_Destroy function from within any callback.
+    *
+    * @return    IOTHUB_CLIENT_OK upon success or an error code upon failure.
+    */
+    MOCKABLE_FUNCTION(, IOTHUB_CLIENT_RESULT, IoTHubClient_GetRetryPolicy, IOTHUB_CLIENT_HANDLE, iotHubClientHandle, IOTHUB_CLIENT_RETRY_POLICY*, retryPolicy, size_t*, retryTimeoutLimitInSeconds);
+
+    /**
+    * @brief    This function returns in the out parameter @p lastMessageReceiveTime
+    *             what was the value of the @c time function when the last message was
+    *             received at the client.
+    *
+    * @param    iotHubClientHandle                The handle created by a call to the create function.
+    * @param    lastMessageReceiveTime          Out parameter containing the value of @c time function
+    *                                             when the last message was received.
+    *
+    * @return    IOTHUB_CLIENT_OK upon success or an error code upon failure.
+    */
+    MOCKABLE_FUNCTION(, IOTHUB_CLIENT_RESULT, IoTHubClient_GetLastMessageReceiveTime, IOTHUB_CLIENT_HANDLE, iotHubClientHandle, time_t*, lastMessageReceiveTime);
+
+    /**
+    * @brief    This API sets a runtime option identified by parameter @p optionName
+    *             to a value pointed to by @p value. @p optionName and the data type
+    *             @p value is pointing to are specific for every option.
+    *
+    * @param    iotHubClientHandle    The handle created by a call to the create function.
+    * @param    optionName              Name of the option.
+    * @param    value                  The value.
+    *
+    *            The options that can be set via this API are:
+    *                - @b timeout - the maximum time in milliseconds a communication is
+    *                  allowed to use. @p value is a pointer to an @c unsigned @c int with
+    *                  the timeout value in milliseconds. This is only supported for the HTTP
+    *                  protocol as of now. When the HTTP protocol uses CURL, the meaning of
+    *                  the parameter is <em>total request time</em>. When the HTTP protocol uses
+    *                  winhttp, the meaning is the same as the @c dwSendTimeout and
+    *                  @c dwReceiveTimeout parameters of the
+    *                  <a href="https://msdn.microsoft.com/en-us/library/windows/desktop/aa384116(v=vs.85).aspx">
+    *                  WinHttpSetTimeouts</a> API.
+    *                - @b CURLOPT_LOW_SPEED_LIMIT - only available for HTTP protocol and only
+    *                  when CURL is used. It has the same meaning as CURL's option with the same
+    *                  name. @p value is pointer to a long.
+    *                - @b CURLOPT_LOW_SPEED_TIME - only available for HTTP protocol and only
+    *                  when CURL is used. It has the same meaning as CURL's option with the same
+    *                  name. @p value is pointer to a long.
+    *                - @b CURLOPT_FORBID_REUSE - only available for HTTP protocol and only
+    *                  when CURL is used. It has the same meaning as CURL's option with the same
+    *                  name. @p value is pointer to a long.
+    *                - @b CURLOPT_FRESH_CONNECT - only available for HTTP protocol and only
+    *                  when CURL is used. It has the same meaning as CURL's option with the same
+    *                  name. @p value is pointer to a long.
+    *                - @b CURLOPT_VERBOSE - only available for HTTP protocol and only
+    *                  when CURL is used. It has the same meaning as CURL's option with the same
+    *                  name. @p value is pointer to a long.
+    *                - @b messageTimeout - the maximum time in milliseconds until a message
+    *                 is timeouted. The time starts at IoTHubClient_SendEventAsync. By default,
+    *                 messages do not expire. @p is a pointer to a uint64_t
+    *                - @b svc2cl_keep_alive_timeout_secs - the AMQP service side keep alive interval in seconds.
+    *                 After the connection established the client requests the server to set the
+    *                 keep alive interval for given time.
+    *                 If it is not set then the default 240 sec applies.
+    *                 If it is set to zero the server will not send keep alive messages to the client.
+    *                - @b cl2svc_keep_alive_send_ratio - the AMQP client side keep alive interval in seconds.
+    *                 After the connection established the server requests the client to set the
+    *                 keep alive interval for given time.
+    *                 If it is not set then the default ratio of 1/2 is applied.
+    *                 The ratio has to be greater than 0.0 and equal to or less than 0.9
+
+    * @return    IOTHUB_CLIENT_OK upon success or an error code upon failure.
+    */
+    MOCKABLE_FUNCTION(, IOTHUB_CLIENT_RESULT, IoTHubClient_SetOption, IOTHUB_CLIENT_HANDLE, iotHubClientHandle, const char*, optionName, const void*, value);
+
+    /**
+    * @brief    This API specifies a call back to be used when the device receives a state update.
+    *
+    * @param    iotHubClientHandle        The handle created by a call to the create function.
+    * @param    deviceTwinCallback        The callback specified by the device client to be used for updating
+    *                                    the desired state. The callback will be called in response to a
+    *                                    request send by the IoTHub services. The payload will be passed to the
+    *                                    callback, along with two version numbers:
+    *                                        - Desired:
+    *                                        - LastSeenReported:
+    * @param    userContextCallback        User specified context that will be provided to the
+    *                                     callback. This can be @c NULL.
+    *
+    *            @b NOTE: The application behavior is undefined if the user calls
+    *            the ::IoTHubClient_Destroy function from within any callback.
+    *
+    * @return    IOTHUB_CLIENT_OK upon success or an error code upon failure.
+    */
+    MOCKABLE_FUNCTION(, IOTHUB_CLIENT_RESULT, IoTHubClient_SetDeviceTwinCallback, IOTHUB_CLIENT_HANDLE, iotHubClientHandle, IOTHUB_CLIENT_DEVICE_TWIN_CALLBACK, deviceTwinCallback, void*, userContextCallback);
+
+    /**
+    * @brief    This API sends a report of the device's properties and their current values.
+    *
+    * @param    iotHubClientHandle        The handle created by a call to the create function.
+    * @param    reportedState            The current device property values to be 'reported' to the IoTHub.
+    * @param    reportedStateCallback    The callback specified by the device client to be called with the
+    *                                    result of the transaction.
+    * @param    userContextCallback        User specified context that will be provided to the
+    *                                     callback. This can be @c NULL.
+    *
+    *            @b NOTE: The application behavior is undefined if the user calls
+    *            the ::IoTHubClient_Destroy function from within any callback.
+    *
+    * @return    IOTHUB_CLIENT_OK upon success or an error code upon failure.
+    */
+    MOCKABLE_FUNCTION(, IOTHUB_CLIENT_RESULT, IoTHubClient_SendReportedState, IOTHUB_CLIENT_HANDLE, iotHubClientHandle, const unsigned char*, reportedState, size_t, size, IOTHUB_CLIENT_REPORTED_STATE_CALLBACK, reportedStateCallback, void*, userContextCallback);
+
+    /**
+    * @brief    This API sets callback for cloud to device method call.
+    *
+    * @param    iotHubClientHandle        The handle created by a call to the create function.
+    * @param    deviceMethodCallback    The callback which will be called by IoTHub.
+    * @param    userContextCallback        User specified context that will be provided to the
+    *                                     callback. This can be @c NULL.
+    *
+    * @return    IOTHUB_CLIENT_OK upon success or an error code upon failure.
+    */
+    MOCKABLE_FUNCTION(, IOTHUB_CLIENT_RESULT, IoTHubClient_SetDeviceMethodCallback, IOTHUB_CLIENT_HANDLE, iotHubClientHandle, IOTHUB_CLIENT_DEVICE_METHOD_CALLBACK_ASYNC, deviceMethodCallback, void*, userContextCallback);
+
+    /**
+    * @brief    This API sets callback for async cloud to device method call.
+    *
+    * @param    iotHubClientHandle                The handle created by a call to the create function.
+    * @param    inboundDeviceMethodCallback     The callback which will be called by IoTHub.
+    * @param    userContextCallback                User specified context that will be provided to the
+    *                                             callback. This can be @c NULL.
+    *
+    * @return    IOTHUB_CLIENT_OK upon success or an error code upon failure.
+    */
+    MOCKABLE_FUNCTION(, IOTHUB_CLIENT_RESULT, IoTHubClient_SetDeviceMethodCallback_Ex, IOTHUB_CLIENT_HANDLE, iotHubClientHandle, IOTHUB_CLIENT_INBOUND_DEVICE_METHOD_CALLBACK, inboundDeviceMethodCallback, void*, userContextCallback);
+
+    /**
+    * @brief    This API responses to a asnyc method callback identified the methodId.
+    *
+    * @param    iotHubClientHandle      The handle created by a call to the create function.
+    * @param    methodId                The methodId of the Device Method callback.
+    * @param    response                The response data for the method callback.
+    * @param    response_size           The size of the response data buffer.
+    * @param    status_response         The status response of the method callback.
+    *
+    * @return    IOTHUB_CLIENT_OK upon success or an error code upon failure.
+    */
+    MOCKABLE_FUNCTION(, IOTHUB_CLIENT_RESULT, IoTHubClient_DeviceMethodResponse, IOTHUB_CLIENT_HANDLE, iotHubClientHandle, METHOD_HANDLE, methodId, const unsigned char*, response, size_t, response_size, int, statusCode);
+
+#ifndef DONT_USE_UPLOADTOBLOB
+    /**
+    * @brief    IoTHubClient_UploadToBlobAsync uploads data from memory to a file in Azure Blob Storage.
+    *
+    * @param    iotHubClientHandle                    The handle created by a call to the IoTHubClient_Create function.
+    * @param    destinationFileName                    The name of the file to be created in Azure Blob Storage.
+    * @param    source                              The source of data.
+    * @param    size                                The size of data.
+    * @param    iotHubClientFileUploadCallback      A callback to be invoked when the file upload operation has finished.
+    * @param    context                             A user-provided context to be passed to the file upload callback.
+    *
+    * @return    IOTHUB_CLIENT_OK upon success or an error code upon failure.
+    */
+    MOCKABLE_FUNCTION(, IOTHUB_CLIENT_RESULT, IoTHubClient_UploadToBlobAsync, IOTHUB_CLIENT_HANDLE, iotHubClientHandle, const char*, destinationFileName, const unsigned char*, source, size_t, size, IOTHUB_CLIENT_FILE_UPLOAD_CALLBACK, iotHubClientFileUploadCallback, void*, context);
+
+    /**
+    ** DEPRECATED: Use IoTHubClient_UploadMultipleBlocksToBlobAsyncEx instead **
+    * @brief                          Uploads a file to a Blob storage in chunks, fed through the callback function provided by the user.
+    * @remarks                        This function allows users to upload large files in chunks, not requiring the whole file content to be passed in memory.
+    * @param iotHubClientHandle       The handle created by a call to the IoTHubClient_Create function.
+    * @param destinationFileName      The name of the file to be created in Azure Blob Storage.
+    * @param getDataCallback          A callback to be invoked to acquire the file chunks to be uploaded, as well as to indicate the status of the upload of the previous block.
+    * @param context                  Any data provided by the user to serve as context on getDataCallback.
+    * @returns                        An IOTHUB_CLIENT_RESULT value indicating the success or failure of the API call.
+    ** DEPRECATED: Use IoTHubClient_UploadMultipleBlocksToBlobAsyncEx instead **
+    */
+    MOCKABLE_FUNCTION(, IOTHUB_CLIENT_RESULT, IoTHubClient_UploadMultipleBlocksToBlobAsync, IOTHUB_CLIENT_HANDLE, iotHubClientHandle, const char*, destinationFileName, IOTHUB_CLIENT_FILE_UPLOAD_GET_DATA_CALLBACK, getDataCallback, void*, context);
+
+    /**
+    * @brief                          Uploads a file to a Blob storage in chunks, fed through the callback function provided by the user.
+    * @remarks                        This function allows users to upload large files in chunks, not requiring the whole file content to be passed in memory.
+    * @param iotHubClientHandle       The handle created by a call to the IoTHubClient_Create function.
+    * @param destinationFileName      The name of the file to be created in Azure Blob Storage.
+    * @param getDataCallbackEx        A callback to be invoked to acquire the file chunks to be uploaded, as well as to indicate the status of the upload of the previous block.
+    * @param context                  Any data provided by the user to serve as context on getDataCallback.
+    * @returns                        An IOTHUB_CLIENT_RESULT value indicating the success or failure of the API call.*/
+    MOCKABLE_FUNCTION(, IOTHUB_CLIENT_RESULT, IoTHubClient_UploadMultipleBlocksToBlobAsyncEx, IOTHUB_CLIENT_HANDLE, iotHubClientHandle, const char*, destinationFileName, IOTHUB_CLIENT_FILE_UPLOAD_GET_DATA_CALLBACK_EX, getDataCallbackEx, void*, context);
+
+#endif /* DONT_USE_UPLOADTOBLOB */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* IOTHUB_CLIENT_H */
Index: azure_iot_hub_f767zi/trunk/azure_iot_sdk/iothub_client/inc/iothub_client_core.h
===================================================================
--- azure_iot_hub_f767zi/trunk/azure_iot_sdk/iothub_client/inc/iothub_client_core.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/azure_iot_sdk/iothub_client/inc/iothub_client_core.h	(revision 457)
@@ -0,0 +1,71 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+/** @file iothub_client_core.h
+*    @brief Extends the IoTHubClientCore_LL module with additional features.
+*
+*    @details IoTHubClientCore is a module that extends the IoTHubClientCore_LL
+*             module with 2 features:
+*                - scheduling the work for the IoTHubCLient from a
+*                  thread, so that the user does not need to create their
+*                  own thread
+*                - thread-safe APIs
+*/
+
+#ifndef IOTHUB_CLIENT_CORE_H
+#define IOTHUB_CLIENT_CORE_H
+
+#include <stddef.h>
+#include <stdint.h>
+#include "umock_c/umock_c_prod.h"
+
+#include "iothub_client_core_ll.h"
+
+#ifndef IOTHUB_CLIENT_CORE_INSTANCE_TYPE
+typedef struct IOTHUB_CLIENT_CORE_INSTANCE_TAG* IOTHUB_CLIENT_CORE_HANDLE;
+#define IOTHUB_CLIENT_CORE_INSTANCE_TYPE
+#endif // IOTHUB_CLIENT_CORE_INSTANCE
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+    MOCKABLE_FUNCTION(, IOTHUB_CLIENT_CORE_HANDLE, IoTHubClientCore_CreateFromConnectionString, const char*, connectionString, IOTHUB_CLIENT_TRANSPORT_PROVIDER, protocol);
+    MOCKABLE_FUNCTION(, IOTHUB_CLIENT_CORE_HANDLE, IoTHubClientCore_Create, const IOTHUB_CLIENT_CONFIG*, config);
+    MOCKABLE_FUNCTION(, IOTHUB_CLIENT_CORE_HANDLE, IoTHubClientCore_CreateWithTransport, TRANSPORT_HANDLE, transportHandle, const IOTHUB_CLIENT_CONFIG*, config);
+    MOCKABLE_FUNCTION(, IOTHUB_CLIENT_CORE_HANDLE, IoTHubClientCore_CreateFromDeviceAuth, const char*, iothub_uri, const char*, device_id, IOTHUB_CLIENT_TRANSPORT_PROVIDER, protocol);
+    MOCKABLE_FUNCTION(, void, IoTHubClientCore_Destroy, IOTHUB_CLIENT_CORE_HANDLE, iotHubClientHandle);
+    MOCKABLE_FUNCTION(, IOTHUB_CLIENT_RESULT, IoTHubClientCore_SendEventAsync, IOTHUB_CLIENT_CORE_HANDLE, iotHubClientHandle, IOTHUB_MESSAGE_HANDLE, eventMessageHandle, IOTHUB_CLIENT_EVENT_CONFIRMATION_CALLBACK, eventConfirmationCallback, void*, userContextCallback);
+    MOCKABLE_FUNCTION(, IOTHUB_CLIENT_RESULT, IoTHubClientCore_GetSendStatus, IOTHUB_CLIENT_CORE_HANDLE, iotHubClientHandle, IOTHUB_CLIENT_STATUS*, iotHubClientStatus);
+    MOCKABLE_FUNCTION(, IOTHUB_CLIENT_RESULT, IoTHubClientCore_SetMessageCallback, IOTHUB_CLIENT_CORE_HANDLE, iotHubClientHandle, IOTHUB_CLIENT_MESSAGE_CALLBACK_ASYNC, messageCallback, void*, userContextCallback);
+    MOCKABLE_FUNCTION(, IOTHUB_CLIENT_RESULT, IoTHubClientCore_SetConnectionStatusCallback, IOTHUB_CLIENT_CORE_HANDLE, iotHubClientHandle, IOTHUB_CLIENT_CONNECTION_STATUS_CALLBACK, connectionStatusCallback, void*, userContextCallback);
+    MOCKABLE_FUNCTION(, IOTHUB_CLIENT_RESULT, IoTHubClientCore_SetRetryPolicy, IOTHUB_CLIENT_CORE_HANDLE, iotHubClientHandle, IOTHUB_CLIENT_RETRY_POLICY, retryPolicy, size_t, retryTimeoutLimitInSeconds);
+    MOCKABLE_FUNCTION(, IOTHUB_CLIENT_RESULT, IoTHubClientCore_GetRetryPolicy, IOTHUB_CLIENT_CORE_HANDLE, iotHubClientHandle, IOTHUB_CLIENT_RETRY_POLICY*, retryPolicy, size_t*, retryTimeoutLimitInSeconds);
+    MOCKABLE_FUNCTION(, IOTHUB_CLIENT_RESULT, IoTHubClientCore_GetLastMessageReceiveTime, IOTHUB_CLIENT_CORE_HANDLE, iotHubClientHandle, time_t*, lastMessageReceiveTime);
+    MOCKABLE_FUNCTION(, IOTHUB_CLIENT_RESULT, IoTHubClientCore_SetOption, IOTHUB_CLIENT_CORE_HANDLE, iotHubClientHandle, const char*, optionName, const void*, value);
+    MOCKABLE_FUNCTION(, IOTHUB_CLIENT_RESULT, IoTHubClientCore_SetDeviceTwinCallback, IOTHUB_CLIENT_CORE_HANDLE, iotHubClientHandle, IOTHUB_CLIENT_DEVICE_TWIN_CALLBACK, deviceTwinCallback, void*, userContextCallback);
+    MOCKABLE_FUNCTION(, IOTHUB_CLIENT_RESULT, IoTHubClientCore_SendReportedState, IOTHUB_CLIENT_CORE_HANDLE, iotHubClientHandle, const unsigned char*, reportedState, size_t, size, IOTHUB_CLIENT_REPORTED_STATE_CALLBACK, reportedStateCallback, void*, userContextCallback);
+    MOCKABLE_FUNCTION(, IOTHUB_CLIENT_RESULT, IoTHubClientCore_GetTwinAsync, IOTHUB_CLIENT_CORE_HANDLE, iotHubClientHandle, IOTHUB_CLIENT_DEVICE_TWIN_CALLBACK, deviceTwinCallback, void*, userContextCallback);
+    MOCKABLE_FUNCTION(, IOTHUB_CLIENT_RESULT, IoTHubClientCore_SetDeviceMethodCallback, IOTHUB_CLIENT_CORE_HANDLE, iotHubClientHandle, IOTHUB_CLIENT_DEVICE_METHOD_CALLBACK_ASYNC, deviceMethodCallback, void*, userContextCallback);
+    MOCKABLE_FUNCTION(, IOTHUB_CLIENT_RESULT, IoTHubClientCore_SetDeviceMethodCallback_Ex, IOTHUB_CLIENT_CORE_HANDLE, iotHubClientHandle, IOTHUB_CLIENT_INBOUND_DEVICE_METHOD_CALLBACK, inboundDeviceMethodCallback, void*, userContextCallback);
+    MOCKABLE_FUNCTION(, IOTHUB_CLIENT_RESULT, IoTHubClientCore_DeviceMethodResponse, IOTHUB_CLIENT_CORE_HANDLE, iotHubClientHandle, METHOD_HANDLE, methodId, const unsigned char*, response, size_t, response_size, int, statusCode);
+
+#ifndef DONT_USE_UPLOADTOBLOB
+    MOCKABLE_FUNCTION(, IOTHUB_CLIENT_RESULT, IoTHubClientCore_UploadToBlobAsync, IOTHUB_CLIENT_CORE_HANDLE, iotHubClientHandle, const char*, destinationFileName, const unsigned char*, source, size_t, size, IOTHUB_CLIENT_FILE_UPLOAD_CALLBACK, iotHubClientFileUploadCallback, void*, context);
+    MOCKABLE_FUNCTION(, IOTHUB_CLIENT_RESULT, IoTHubClientCore_UploadMultipleBlocksToBlobAsync, IOTHUB_CLIENT_CORE_HANDLE, iotHubClientHandle, const char*, destinationFileName, IOTHUB_CLIENT_FILE_UPLOAD_GET_DATA_CALLBACK, getDataCallback, IOTHUB_CLIENT_FILE_UPLOAD_GET_DATA_CALLBACK_EX, getDataCallbackEx, void*, context);
+#endif /* DONT_USE_UPLOADTOBLOB */
+
+    MOCKABLE_FUNCTION(, IOTHUB_CLIENT_RESULT, IoTHubClientCore_SendEventToOutputAsync, IOTHUB_CLIENT_CORE_HANDLE, iotHubClientHandle, IOTHUB_MESSAGE_HANDLE, eventMessageHandle, const char*, outputName, IOTHUB_CLIENT_EVENT_CONFIRMATION_CALLBACK, eventConfirmationCallback, void*, userContextCallback);
+    MOCKABLE_FUNCTION(, IOTHUB_CLIENT_RESULT, IoTHubClientCore_SetInputMessageCallback, IOTHUB_CLIENT_CORE_HANDLE, iotHubClientHandle, const char*, inputName, IOTHUB_CLIENT_MESSAGE_CALLBACK_ASYNC, eventHandlerCallback, void*, userContextCallback);
+
+#ifdef USE_EDGE_MODULES
+    MOCKABLE_FUNCTION(, IOTHUB_CLIENT_CORE_HANDLE, IoTHubClientCore_CreateFromEnvironment, IOTHUB_CLIENT_TRANSPORT_PROVIDER, protocol);
+    MOCKABLE_FUNCTION(, IOTHUB_CLIENT_RESULT, IoTHubClientCore_GenericMethodInvoke, IOTHUB_CLIENT_CORE_HANDLE, iotHubClientHandle, const char*, deviceId, const char*, moduleId, const char*, methodName, const char*, methodPayload, unsigned int, timeout, IOTHUB_METHOD_INVOKE_CALLBACK, methodInvokeCallback, void*, context);
+#endif /* USE_EDGE_MODULES */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* IOTHUB_CLIENT_CORE_H */
Index: azure_iot_hub_f767zi/trunk/azure_iot_sdk/iothub_client/inc/iothub_client_core_common.h
===================================================================
--- azure_iot_hub_f767zi/trunk/azure_iot_sdk/iothub_client/inc/iothub_client_core_common.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/azure_iot_sdk/iothub_client/inc/iothub_client_core_common.h	(revision 457)
@@ -0,0 +1,241 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+/* Shared structures and enums for iothub convenience layer and LL layer */
+
+#ifndef IOTHUB_CLIENT_CORE_COMMON_H
+#define IOTHUB_CLIENT_CORE_COMMON_H
+
+#include "azure_macro_utils/macro_utils.h"
+#include "umock_c/umock_c_prod.h"
+
+#include "iothub_transport_ll.h"
+#include "iothub_message.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#define IOTHUB_CLIENT_FILE_UPLOAD_RESULT_VALUES \
+    FILE_UPLOAD_OK, \
+    FILE_UPLOAD_ERROR
+
+    MU_DEFINE_ENUM_WITHOUT_INVALID(IOTHUB_CLIENT_FILE_UPLOAD_RESULT, IOTHUB_CLIENT_FILE_UPLOAD_RESULT_VALUES)
+        typedef void(*IOTHUB_CLIENT_FILE_UPLOAD_CALLBACK)(IOTHUB_CLIENT_FILE_UPLOAD_RESULT result, void* userContextCallback);
+
+#define IOTHUB_CLIENT_RESULT_VALUES       \
+    IOTHUB_CLIENT_OK,                     \
+    IOTHUB_CLIENT_INVALID_ARG,            \
+    IOTHUB_CLIENT_ERROR,                  \
+    IOTHUB_CLIENT_INVALID_SIZE,           \
+    IOTHUB_CLIENT_INDEFINITE_TIME
+
+    /** @brief Enumeration specifying the status of calls to various APIs in this module.
+    */
+
+    MU_DEFINE_ENUM_WITHOUT_INVALID(IOTHUB_CLIENT_RESULT, IOTHUB_CLIENT_RESULT_VALUES);
+
+    typedef void(*IOTHUB_METHOD_INVOKE_CALLBACK)(IOTHUB_CLIENT_RESULT result, int responseStatus, unsigned char* responsePayload, size_t responsePayloadSize, void* context);
+
+#define IOTHUB_CLIENT_RETRY_POLICY_VALUES     \
+    IOTHUB_CLIENT_RETRY_NONE,                   \
+    IOTHUB_CLIENT_RETRY_IMMEDIATE,                  \
+    IOTHUB_CLIENT_RETRY_INTERVAL,      \
+    IOTHUB_CLIENT_RETRY_LINEAR_BACKOFF,      \
+    IOTHUB_CLIENT_RETRY_EXPONENTIAL_BACKOFF,                 \
+    IOTHUB_CLIENT_RETRY_EXPONENTIAL_BACKOFF_WITH_JITTER,                 \
+    IOTHUB_CLIENT_RETRY_RANDOM
+
+    /** @brief Enumeration passed in by the IoT Hub when the event confirmation
+    *           callback is invoked to indicate status of the event processing in
+    *           the hub.
+    */
+    MU_DEFINE_ENUM_WITHOUT_INVALID(IOTHUB_CLIENT_RETRY_POLICY, IOTHUB_CLIENT_RETRY_POLICY_VALUES);
+
+    struct IOTHUBTRANSPORT_CONFIG_TAG;
+    typedef struct IOTHUBTRANSPORT_CONFIG_TAG IOTHUBTRANSPORT_CONFIG;
+
+#define IOTHUB_CLIENT_STATUS_VALUES       \
+    IOTHUB_CLIENT_SEND_STATUS_IDLE,       \
+    IOTHUB_CLIENT_SEND_STATUS_BUSY
+
+    /** @brief Enumeration returned by the ::IoTHubClient_LL_GetSendStatus
+    *           API to indicate the current sending status of the IoT Hub client.
+    */
+    MU_DEFINE_ENUM_WITHOUT_INVALID(IOTHUB_CLIENT_STATUS, IOTHUB_CLIENT_STATUS_VALUES);
+
+#define IOTHUB_IDENTITY_TYPE_VALUE  \
+    IOTHUB_TYPE_TELEMETRY,          \
+    IOTHUB_TYPE_DEVICE_TWIN,        \
+    IOTHUB_TYPE_DEVICE_METHODS,     \
+    IOTHUB_TYPE_EVENT_QUEUE
+    MU_DEFINE_ENUM_WITHOUT_INVALID(IOTHUB_IDENTITY_TYPE, IOTHUB_IDENTITY_TYPE_VALUE);
+
+#define IOTHUB_PROCESS_ITEM_RESULT_VALUE    \
+    IOTHUB_PROCESS_OK,                      \
+    IOTHUB_PROCESS_ERROR,                   \
+    IOTHUB_PROCESS_NOT_CONNECTED,           \
+    IOTHUB_PROCESS_CONTINUE
+    MU_DEFINE_ENUM_WITHOUT_INVALID(IOTHUB_PROCESS_ITEM_RESULT, IOTHUB_PROCESS_ITEM_RESULT_VALUE);
+
+#define IOTHUBMESSAGE_DISPOSITION_RESULT_VALUES \
+    IOTHUBMESSAGE_ACCEPTED, \
+    IOTHUBMESSAGE_REJECTED, \
+    IOTHUBMESSAGE_ABANDONED
+
+    /** @brief Enumeration returned by the callback which is invoked whenever the
+    *           IoT Hub sends a message to the device.
+    */
+    MU_DEFINE_ENUM_WITHOUT_INVALID(IOTHUBMESSAGE_DISPOSITION_RESULT, IOTHUBMESSAGE_DISPOSITION_RESULT_VALUES);
+
+#define IOTHUB_CLIENT_IOTHUB_METHOD_STATUS_VALUES \
+    IOTHUB_CLIENT_IOTHUB_METHOD_STATUS_SUCCESS,   \
+    IOTHUB_CLIENT_IOTHUB_METHOD_STATUS_ERROR      \
+
+    /** @brief Enumeration returned by remotely executed functions
+    */
+    MU_DEFINE_ENUM_WITHOUT_INVALID(IOTHUB_CLIENT_IOTHUB_METHOD_STATUS, IOTHUB_CLIENT_IOTHUB_METHOD_STATUS_VALUES);
+
+
+#define IOTHUB_CLIENT_CONFIRMATION_RESULT_VALUES     \
+    IOTHUB_CLIENT_CONFIRMATION_OK,                   \
+    IOTHUB_CLIENT_CONFIRMATION_BECAUSE_DESTROY,      \
+    IOTHUB_CLIENT_CONFIRMATION_MESSAGE_TIMEOUT,      \
+    IOTHUB_CLIENT_CONFIRMATION_ERROR                 \
+
+    /** @brief Enumeration passed in by the IoT Hub when the event confirmation
+    *           callback is invoked to indicate status of the event processing in
+    *           the hub.
+    */
+    MU_DEFINE_ENUM_WITHOUT_INVALID(IOTHUB_CLIENT_CONFIRMATION_RESULT, IOTHUB_CLIENT_CONFIRMATION_RESULT_VALUES);
+
+#define IOTHUB_CLIENT_CONNECTION_STATUS_VALUES             \
+    IOTHUB_CLIENT_CONNECTION_AUTHENTICATED,                \
+    IOTHUB_CLIENT_CONNECTION_UNAUTHENTICATED               \
+
+
+    /** @brief Enumeration passed in by the IoT Hub when the connection status
+    *           callback is invoked to indicate status of the connection in
+    *           the hub.
+    */
+    MU_DEFINE_ENUM_WITHOUT_INVALID(IOTHUB_CLIENT_CONNECTION_STATUS, IOTHUB_CLIENT_CONNECTION_STATUS_VALUES);
+
+#define IOTHUB_CLIENT_CONNECTION_STATUS_REASON_VALUES      \
+    IOTHUB_CLIENT_CONNECTION_EXPIRED_SAS_TOKEN,            \
+    IOTHUB_CLIENT_CONNECTION_DEVICE_DISABLED,              \
+    IOTHUB_CLIENT_CONNECTION_BAD_CREDENTIAL,               \
+    IOTHUB_CLIENT_CONNECTION_RETRY_EXPIRED,                \
+    IOTHUB_CLIENT_CONNECTION_NO_NETWORK,                   \
+    IOTHUB_CLIENT_CONNECTION_COMMUNICATION_ERROR,          \
+    IOTHUB_CLIENT_CONNECTION_OK,                           \
+    IOTHUB_CLIENT_CONNECTION_NO_PING_RESPONSE              \
+
+    /** @brief Enumeration passed in by the IoT Hub when the connection status
+    *           callback is invoked to indicate status of the connection in
+    *           the hub.
+    */
+    MU_DEFINE_ENUM_WITHOUT_INVALID(IOTHUB_CLIENT_CONNECTION_STATUS_REASON, IOTHUB_CLIENT_CONNECTION_STATUS_REASON_VALUES);
+
+#define TRANSPORT_TYPE_VALUES \
+    TRANSPORT_LL, /*LL comes from "LowLevel" */ \
+    TRANSPORT_THREADED
+
+    MU_DEFINE_ENUM_WITHOUT_INVALID(TRANSPORT_TYPE, TRANSPORT_TYPE_VALUES);
+
+#define DEVICE_TWIN_UPDATE_STATE_VALUES \
+    DEVICE_TWIN_UPDATE_COMPLETE, \
+    DEVICE_TWIN_UPDATE_PARTIAL
+
+    MU_DEFINE_ENUM_WITHOUT_INVALID(DEVICE_TWIN_UPDATE_STATE, DEVICE_TWIN_UPDATE_STATE_VALUES);
+
+    typedef void(*IOTHUB_CLIENT_EVENT_CONFIRMATION_CALLBACK)(IOTHUB_CLIENT_CONFIRMATION_RESULT result, void* userContextCallback);
+    typedef void(*IOTHUB_CLIENT_CONNECTION_STATUS_CALLBACK)(IOTHUB_CLIENT_CONNECTION_STATUS result, IOTHUB_CLIENT_CONNECTION_STATUS_REASON reason, void* userContextCallback);
+    typedef IOTHUBMESSAGE_DISPOSITION_RESULT (*IOTHUB_CLIENT_MESSAGE_CALLBACK_ASYNC)(IOTHUB_MESSAGE_HANDLE message, void* userContextCallback);
+
+    typedef void(*IOTHUB_CLIENT_DEVICE_TWIN_CALLBACK)(DEVICE_TWIN_UPDATE_STATE update_state, const unsigned char* payLoad, size_t size, void* userContextCallback);
+    typedef void(*IOTHUB_CLIENT_REPORTED_STATE_CALLBACK)(int status_code, void* userContextCallback);
+    typedef int(*IOTHUB_CLIENT_DEVICE_METHOD_CALLBACK_ASYNC)(const char* method_name, const unsigned char* payload, size_t size, unsigned char** response, size_t* response_size, void* userContextCallback);
+    typedef int(*IOTHUB_CLIENT_INBOUND_DEVICE_METHOD_CALLBACK)(const char* method_name, const unsigned char* payload, size_t size, METHOD_HANDLE method_id, void* userContextCallback);
+
+
+#define IOTHUB_CLIENT_FILE_UPLOAD_GET_DATA_RESULT_VALUES \
+    IOTHUB_CLIENT_FILE_UPLOAD_GET_DATA_OK, \
+    IOTHUB_CLIENT_FILE_UPLOAD_GET_DATA_ABORT
+
+    MU_DEFINE_ENUM_WITHOUT_INVALID(IOTHUB_CLIENT_FILE_UPLOAD_GET_DATA_RESULT, IOTHUB_CLIENT_FILE_UPLOAD_GET_DATA_RESULT_VALUES);
+
+    /**
+    *  @brief           Callback invoked by IoTHubClient_UploadMultipleBlocksToBlobAsync requesting the chunks of data to be uploaded.
+    *  @param result    The result of the upload of the previous block of data provided by the user (IOTHUB_CLIENT_FILE_UPLOAD_GET_DATA_CALLBACK_EX only)
+    *  @param data      Next block of data to be uploaded, to be provided by the user when this callback is invoked.
+    *  @param size      Size of the data parameter.
+    *  @param context   User context provided on the call to IoTHubClient_UploadMultipleBlocksToBlobAsync.
+    *  @remarks         If the user wants to abort the upload, the callback should return IOTHUB_CLIENT_FILE_UPLOAD_GET_DATA_ABORT
+    *                   It should return IOTHUB_CLIENT_FILE_UPLOAD_GET_DATA_OK otherwise.
+    *                   If a NULL is provided for parameter "data" and/or zero is provided for "size", the user indicates to the client that the complete file has been uploaded.
+    *                   In such case this callback will be invoked only once more to indicate the status of the final block upload.
+    *                   If result is not FILE_UPLOAD_OK, the upload is cancelled and this callback stops being invoked.
+    *                   When this callback is called for the last time, no data or size is expected, so data and size are NULL
+    */
+    typedef void(*IOTHUB_CLIENT_FILE_UPLOAD_GET_DATA_CALLBACK)(IOTHUB_CLIENT_FILE_UPLOAD_RESULT result, unsigned char const ** data, size_t* size, void* context);
+    typedef IOTHUB_CLIENT_FILE_UPLOAD_GET_DATA_RESULT(*IOTHUB_CLIENT_FILE_UPLOAD_GET_DATA_CALLBACK_EX)(IOTHUB_CLIENT_FILE_UPLOAD_RESULT result, unsigned char const ** data, size_t* size, void* context);
+
+    /** @brief    This struct captures IoTHub client configuration. */
+    typedef struct IOTHUB_CLIENT_CONFIG_TAG
+    {
+        /** @brief A function pointer that is passed into the @c IoTHubClientCreate.
+        *    A function definition for AMQP is defined in the include @c iothubtransportamqp.h.
+        *   A function definition for HTTP is defined in the include @c iothubtransporthttp.h
+        *   A function definition for MQTT is defined in the include @c iothubtransportmqtt.h */
+        IOTHUB_CLIENT_TRANSPORT_PROVIDER protocol;
+
+        /** @brief    A string that identifies the device. */
+        const char* deviceId;
+
+        /** @brief    The device key used to authenticate the device.
+        If neither deviceSasToken nor deviceKey is present then the authentication is assumed x509.*/
+        const char* deviceKey;
+
+        /** @brief    The device SAS Token used to authenticate the device in place of device key.
+        If neither deviceSasToken nor deviceKey is present then the authentication is assumed x509.*/
+        const char* deviceSasToken;
+
+        /** @brief    The IoT Hub name to which the device is connecting. */
+        const char* iotHubName;
+
+        /** @brief    IoT Hub suffix goes here, e.g., private.azure-devices-int.net. */
+        const char* iotHubSuffix;
+
+        const char* protocolGatewayHostName;
+    } IOTHUB_CLIENT_CONFIG;
+
+    /** @brief    This struct captures IoTHub client device configuration. */
+    typedef struct IOTHUB_CLIENT_DEVICE_CONFIG_TAG
+    {
+        /** @brief A function pointer that is passed into the @c IoTHubClientCreate.
+        *    A function definition for AMQP is defined in the include @c iothubtransportamqp.h.
+        *   A function definition for HTTP is defined in the include @c iothubtransporthttp.h
+        *   A function definition for MQTT is defined in the include @c iothubtransportmqtt.h */
+        IOTHUB_CLIENT_TRANSPORT_PROVIDER protocol;
+
+        /** @brief a transport handle implementing the protocol */
+        void * transportHandle;
+
+        /** @brief    A string that identifies the device. */
+        const char* deviceId;
+
+        /** @brief    The device key used to authenticate the device.
+        x509 authentication is is not supported for multiplexed connections*/
+        const char* deviceKey;
+
+        /** @brief    The device SAS Token used to authenticate the device in place of device key.
+        x509 authentication is is not supported for multiplexed connections.*/
+        const char* deviceSasToken;
+    } IOTHUB_CLIENT_DEVICE_CONFIG;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* IOTHUB_CLIENT_CORE_COMMON_H */
Index: azure_iot_hub_f767zi/trunk/azure_iot_sdk/iothub_client/inc/iothub_client_core_ll.h
===================================================================
--- azure_iot_hub_f767zi/trunk/azure_iot_sdk/iothub_client/inc/iothub_client_core_ll.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/azure_iot_sdk/iothub_client/inc/iothub_client_core_ll.h	(revision 457)
@@ -0,0 +1,74 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+/** @file iothub_client_core_ll.h
+*    @brief     APIs that allow a user (usually a device) to communicate
+*             with an Azure IoTHub.
+*
+*    @details IoTHubClientCore_LL is a module that allows a user (usually a
+*             device) to communicate with an Azure IoTHub. It can send events
+*             and receive messages. At any given moment in time there can only
+*             be at most 1 message callback function.
+*
+*             This API surface contains a set of APIs that allows the user to
+*             interact with the lower layer portion of the IoTHubClient. These APIs
+*             contain @c _LL_ in their name, but retain the same functionality like the
+*             @c IoTHubClient_... APIs, with one difference. If the @c _LL_ APIs are
+*             used then the user is responsible for scheduling when the actual work done
+*             by the IoTHubClient happens (when the data is sent/received on/from the wire).
+*             This is useful for constrained devices where spinning a separate thread is
+*             often not desired.
+*/
+
+#ifndef IOTHUB_CLIENT_CORE_LL_H
+#define IOTHUB_CLIENT_CORE_LL_H
+
+typedef struct IOTHUB_CLIENT_CORE_LL_HANDLE_DATA_TAG* IOTHUB_CLIENT_CORE_LL_HANDLE;
+
+#include <time.h>
+#include "umock_c/umock_c_prod.h"
+#include "iothub_transport_ll.h"
+#include "iothub_client_core_common.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+     MOCKABLE_FUNCTION(, IOTHUB_CLIENT_CORE_LL_HANDLE, IoTHubClientCore_LL_CreateFromConnectionString, const char*, connectionString, IOTHUB_CLIENT_TRANSPORT_PROVIDER, protocol);
+     MOCKABLE_FUNCTION(, IOTHUB_CLIENT_CORE_LL_HANDLE, IoTHubClientCore_LL_Create, const IOTHUB_CLIENT_CONFIG*, config);
+     MOCKABLE_FUNCTION(, IOTHUB_CLIENT_CORE_LL_HANDLE, IoTHubClientCore_LL_CreateWithTransport, const IOTHUB_CLIENT_DEVICE_CONFIG*, config);
+     MOCKABLE_FUNCTION(, IOTHUB_CLIENT_CORE_LL_HANDLE, IoTHubClientCore_LL_CreateFromDeviceAuth, const char*, iothub_uri, const char*, device_id, IOTHUB_CLIENT_TRANSPORT_PROVIDER, protocol);
+     MOCKABLE_FUNCTION(, void, IoTHubClientCore_LL_Destroy, IOTHUB_CLIENT_CORE_LL_HANDLE, iotHubClientHandle);
+     MOCKABLE_FUNCTION(, IOTHUB_CLIENT_RESULT, IoTHubClientCore_LL_SendEventAsync, IOTHUB_CLIENT_CORE_LL_HANDLE, iotHubClientHandle, IOTHUB_MESSAGE_HANDLE, eventMessageHandle, IOTHUB_CLIENT_EVENT_CONFIRMATION_CALLBACK, eventConfirmationCallback, void*, userContextCallback);
+     MOCKABLE_FUNCTION(, IOTHUB_CLIENT_RESULT, IoTHubClientCore_LL_GetSendStatus, IOTHUB_CLIENT_CORE_LL_HANDLE, iotHubClientHandle, IOTHUB_CLIENT_STATUS*, iotHubClientStatus);
+     MOCKABLE_FUNCTION(, IOTHUB_CLIENT_RESULT, IoTHubClientCore_LL_SetMessageCallback, IOTHUB_CLIENT_CORE_LL_HANDLE, iotHubClientHandle, IOTHUB_CLIENT_MESSAGE_CALLBACK_ASYNC, messageCallback, void*, userContextCallback);
+     MOCKABLE_FUNCTION(, IOTHUB_CLIENT_RESULT, IoTHubClientCore_LL_SetConnectionStatusCallback, IOTHUB_CLIENT_CORE_LL_HANDLE, iotHubClientHandle, IOTHUB_CLIENT_CONNECTION_STATUS_CALLBACK, connectionStatusCallback, void*, userContextCallback);
+     MOCKABLE_FUNCTION(, IOTHUB_CLIENT_RESULT, IoTHubClientCore_LL_SetRetryPolicy, IOTHUB_CLIENT_CORE_LL_HANDLE, iotHubClientHandle, IOTHUB_CLIENT_RETRY_POLICY, retryPolicy, size_t, retryTimeoutLimitInSeconds);
+     MOCKABLE_FUNCTION(, IOTHUB_CLIENT_RESULT, IoTHubClientCore_LL_GetRetryPolicy, IOTHUB_CLIENT_CORE_LL_HANDLE, iotHubClientHandle, IOTHUB_CLIENT_RETRY_POLICY*, retryPolicy, size_t*, retryTimeoutLimitInSeconds);
+     MOCKABLE_FUNCTION(, IOTHUB_CLIENT_RESULT, IoTHubClientCore_LL_GetLastMessageReceiveTime, IOTHUB_CLIENT_CORE_LL_HANDLE, iotHubClientHandle, time_t*, lastMessageReceiveTime);
+     MOCKABLE_FUNCTION(, void, IoTHubClientCore_LL_DoWork, IOTHUB_CLIENT_CORE_LL_HANDLE, iotHubClientHandle);
+     MOCKABLE_FUNCTION(, IOTHUB_CLIENT_RESULT, IoTHubClientCore_LL_SetOption, IOTHUB_CLIENT_CORE_LL_HANDLE, iotHubClientHandle, const char*, optionName, const void*, value);
+     MOCKABLE_FUNCTION(, IOTHUB_CLIENT_RESULT, IoTHubClientCore_LL_SetDeviceTwinCallback, IOTHUB_CLIENT_CORE_LL_HANDLE, iotHubClientHandle, IOTHUB_CLIENT_DEVICE_TWIN_CALLBACK, deviceTwinCallback, void*, userContextCallback);
+     MOCKABLE_FUNCTION(, IOTHUB_CLIENT_RESULT, IoTHubClientCore_LL_SendReportedState, IOTHUB_CLIENT_CORE_LL_HANDLE, iotHubClientHandle, const unsigned char*, reportedState, size_t, size, IOTHUB_CLIENT_REPORTED_STATE_CALLBACK, reportedStateCallback, void*, userContextCallback);
+     MOCKABLE_FUNCTION(, IOTHUB_CLIENT_RESULT, IoTHubClientCore_LL_GetTwinAsync, IOTHUB_CLIENT_CORE_LL_HANDLE, iotHubClientHandle, IOTHUB_CLIENT_DEVICE_TWIN_CALLBACK, deviceTwinCallback, void*, userContextCallback);
+     MOCKABLE_FUNCTION(, IOTHUB_CLIENT_RESULT, IoTHubClientCore_LL_SetDeviceMethodCallback, IOTHUB_CLIENT_CORE_LL_HANDLE, iotHubClientHandle, IOTHUB_CLIENT_DEVICE_METHOD_CALLBACK_ASYNC, deviceMethodCallback, void*, userContextCallback);
+     MOCKABLE_FUNCTION(, IOTHUB_CLIENT_RESULT, IoTHubClientCore_LL_SetDeviceMethodCallback_Ex, IOTHUB_CLIENT_CORE_LL_HANDLE, iotHubClientHandle, IOTHUB_CLIENT_INBOUND_DEVICE_METHOD_CALLBACK, inboundDeviceMethodCallback, void*, userContextCallback);
+     MOCKABLE_FUNCTION(, IOTHUB_CLIENT_RESULT, IoTHubClientCore_LL_DeviceMethodResponse, IOTHUB_CLIENT_CORE_LL_HANDLE, iotHubClientHandle, METHOD_HANDLE, methodId, const unsigned char*, response, size_t, respSize, int, statusCode);
+     MOCKABLE_FUNCTION(, IOTHUB_CLIENT_RESULT, IoTHubClientCore_LL_SendEventToOutputAsync, IOTHUB_CLIENT_CORE_LL_HANDLE, iotHubClientHandle, IOTHUB_MESSAGE_HANDLE, eventMessageHandle, const char*, outputName, IOTHUB_CLIENT_EVENT_CONFIRMATION_CALLBACK, eventConfirmationCallback, void*, userContextCallback);
+     MOCKABLE_FUNCTION(, IOTHUB_CLIENT_RESULT, IoTHubClientCore_LL_SetInputMessageCallback, IOTHUB_CLIENT_CORE_LL_HANDLE, iotHubClientHandle, const char*, inputName, IOTHUB_CLIENT_MESSAGE_CALLBACK_ASYNC, eventHandlerCallback, void*, userContextCallback);
+
+#ifndef DONT_USE_UPLOADTOBLOB
+     MOCKABLE_FUNCTION(, IOTHUB_CLIENT_RESULT, IoTHubClientCore_LL_UploadToBlob, IOTHUB_CLIENT_CORE_LL_HANDLE, iotHubClientHandle, const char*, destinationFileName, const unsigned char*, source, size_t, size);
+     MOCKABLE_FUNCTION(, IOTHUB_CLIENT_RESULT, IoTHubClientCore_LL_UploadMultipleBlocksToBlob, IOTHUB_CLIENT_CORE_LL_HANDLE, iotHubClientHandle, const char*, destinationFileName, IOTHUB_CLIENT_FILE_UPLOAD_GET_DATA_CALLBACK, getDataCallback, void*, context);
+     MOCKABLE_FUNCTION(, IOTHUB_CLIENT_RESULT, IoTHubClientCore_LL_UploadMultipleBlocksToBlobEx, IOTHUB_CLIENT_CORE_LL_HANDLE, iotHubClientHandle, const char*, destinationFileName, IOTHUB_CLIENT_FILE_UPLOAD_GET_DATA_CALLBACK_EX, getDataCallbackEx, void*, context);
+#endif /*DONT_USE_UPLOADTOBLOB*/
+
+#ifdef USE_EDGE_MODULES
+    MOCKABLE_FUNCTION(, IOTHUB_CLIENT_CORE_LL_HANDLE, IoTHubClientCore_LL_CreateFromEnvironment, IOTHUB_CLIENT_TRANSPORT_PROVIDER, protocol);
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* IOTHUB_CLIENT_CORE_LL_H */
Index: azure_iot_hub_f767zi/trunk/azure_iot_sdk/iothub_client/inc/iothub_client_ll.h
===================================================================
--- azure_iot_hub_f767zi/trunk/azure_iot_sdk/iothub_client/inc/iothub_client_ll.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/azure_iot_sdk/iothub_client/inc/iothub_client_ll.h	(revision 457)
@@ -0,0 +1,407 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+/** @file iothub_client_ll.h
+*    @brief     APIs that allow a user (usually a device) to communicate
+*             with an Azure IoTHub.
+*
+*    @details IoTHubClient_LL is a module that allows a user (usually a
+*             device) to communicate with an Azure IoTHub. It can send events
+*             and receive messages. At any given moment in time there can only
+*             be at most 1 message callback function.
+*
+*             This API surface contains a set of APIs that allows the user to
+*             interact with the lower layer portion of the IoTHubClient. These APIs
+*             contain @c _LL_ in their name, but retain the same functionality like the
+*             @c IoTHubClient_... APIs, with one difference. If the @c _LL_ APIs are
+*             used then the user is responsible for scheduling when the actual work done
+*             by the IoTHubClient happens (when the data is sent/received on/from the wire).
+*             This is useful for constrained devices where spinning a separate thread is
+*             often not desired.
+*/
+
+#ifndef IOTHUB_CLIENT_LL_H
+#define IOTHUB_CLIENT_LL_H
+
+#include <stddef.h>
+#include <stdint.h>
+#include <time.h>
+#include "umock_c/umock_c_prod.h"
+
+#include "iothub_client_core_common.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+typedef struct IOTHUB_CLIENT_CORE_LL_HANDLE_DATA_TAG* IOTHUB_CLIENT_LL_HANDLE;
+
+
+    /**
+    * @brief    Creates a IoT Hub client for communication with an existing
+    *             IoT Hub using the specified connection string parameter.
+    *
+    * @param    connectionString    Pointer to a character string
+    * @param    protocol            Function pointer for protocol implementation
+    *
+    *            Sample connection string:
+    *                <blockquote>
+    *                    <pre>HostName=[IoT Hub name goes here].[IoT Hub suffix goes here, e.g., private.azure-devices-int.net];DeviceId=[Device ID goes here];SharedAccessKey=[Device key goes here];</pre>
+    *                </blockquote>
+    *
+    * @return    A non-NULL @c IOTHUB_CLIENT_LL_HANDLE value that is used when
+    *             invoking other functions for IoT Hub client and @c NULL on failure.
+    */
+     MOCKABLE_FUNCTION(, IOTHUB_CLIENT_LL_HANDLE, IoTHubClient_LL_CreateFromConnectionString, const char*, connectionString, IOTHUB_CLIENT_TRANSPORT_PROVIDER, protocol);
+
+    /**
+    * @brief    Creates a IoT Hub client for communication with an existing IoT
+    *             Hub using the specified parameters.
+    *
+    * @param    config    Pointer to an @c IOTHUB_CLIENT_CONFIG structure
+    *
+    *            The API does not allow sharing of a connection across multiple
+    *            devices. This is a blocking call.
+    *
+    * @return    A non-NULL @c IOTHUB_CLIENT_LL_HANDLE value that is used when
+    *             invoking other functions for IoT Hub client and @c NULL on failure.
+    */
+     MOCKABLE_FUNCTION(, IOTHUB_CLIENT_LL_HANDLE, IoTHubClient_LL_Create, const IOTHUB_CLIENT_CONFIG*, config);
+
+    /**
+    * @brief    Creates a IoT Hub client for communication with an existing IoT
+    *             Hub using an existing transport.
+    *
+    * @param    config    Pointer to an @c IOTHUB_CLIENT_DEVICE_CONFIG structure
+    *
+    *            The API *allows* sharing of a connection across multiple
+    *            devices. This is a blocking call.
+    *
+    * @return    A non-NULL @c IOTHUB_CLIENT_LL_HANDLE value that is used when
+    *             invoking other functions for IoT Hub client and @c NULL on failure.
+    */
+     MOCKABLE_FUNCTION(, IOTHUB_CLIENT_LL_HANDLE, IoTHubClient_LL_CreateWithTransport, const IOTHUB_CLIENT_DEVICE_CONFIG*, config);
+
+     /**
+     * @brief    Creates a IoT Hub client for communication with an existing IoT
+     *             Hub using the device auth module.
+     *
+     * @param    iothub_uri    Pointer to an ioThub hostname received in the registration process
+     * @param    device_id    Pointer to the device Id of the device
+     * @param    device_auth_handle    a device auth handle used to generate the connection string
+     * @param    protocol            Function pointer for protocol implementation
+     *
+     * @return    A non-NULL @c IOTHUB_CLIENT_LL_HANDLE value that is used when
+     *             invoking other functions for IoT Hub client and @c NULL on failure.
+     */
+     MOCKABLE_FUNCTION(, IOTHUB_CLIENT_LL_HANDLE, IoTHubClient_LL_CreateFromDeviceAuth, const char*, iothub_uri, const char*, device_id, IOTHUB_CLIENT_TRANSPORT_PROVIDER, protocol);
+
+    /**
+    * @brief    Disposes of resources allocated by the IoT Hub client. This is a
+    *             blocking call.
+    *
+    * @param    iotHubClientHandle    The handle created by a call to the create function.
+    */
+     MOCKABLE_FUNCTION(, void, IoTHubClient_LL_Destroy, IOTHUB_CLIENT_LL_HANDLE, iotHubClientHandle);
+
+    /**
+    * @brief    Asynchronous call to send the message specified by @p eventMessageHandle.
+    *
+    * @param    iotHubClientHandle               The handle created by a call to the create function.
+    * @param    eventMessageHandle               The handle to an IoT Hub message.
+    * @param    eventConfirmationCallback      The callback specified by the device for receiving
+    *                                         confirmation of the delivery of the IoT Hub message.
+    *                                         This callback can be expected to invoke the
+    *                                         ::IoTHubClient_LL_SendEventAsync function for the
+    *                                         same message in an attempt to retry sending a failing
+    *                                         message. The user can specify a @c NULL value here to
+    *                                         indicate that no callback is required.
+    * @param    userContextCallback            User specified context that will be provided to the
+    *                                         callback. This can be @c NULL.
+    *
+    *            @b NOTE: The application behavior is undefined if the user calls
+    *            the ::IoTHubClient_LL_Destroy function from within any callback.
+    * @remarks
+    *            The IOTHUB_MESSAGE_HANDLE instance provided as argument is copied by the function,
+    *            so this argument can be destroyed by the calling application right after IoTHubClient_LL_SendEventAsync returns.
+    *            The copy of @c eventMessageHandle is later destroyed by the iothub client when the message is effectively sent, if a failure sending it occurs, or if the client is destroyed.
+    * @return    IOTHUB_CLIENT_OK upon success or an error code upon failure.
+    */
+     MOCKABLE_FUNCTION(, IOTHUB_CLIENT_RESULT, IoTHubClient_LL_SendEventAsync, IOTHUB_CLIENT_LL_HANDLE, iotHubClientHandle, IOTHUB_MESSAGE_HANDLE, eventMessageHandle, IOTHUB_CLIENT_EVENT_CONFIRMATION_CALLBACK, eventConfirmationCallback, void*, userContextCallback);
+
+    /**
+    * @brief    This function returns the current sending status for IoTHubClient.
+    *
+    * @param    iotHubClientHandle        The handle created by a call to the create function.
+    * @param    iotHubClientStatus        The sending state is populated at the address pointed
+    *                                     at by this parameter. The value will be set to
+    *                                     @c IOTHUBCLIENT_SENDSTATUS_IDLE if there is currently
+    *                                     no item to be sent and @c IOTHUBCLIENT_SENDSTATUS_BUSY
+    *                                     if there are.
+    *
+    * @return    IOTHUB_CLIENT_OK upon success or an error code upon failure.
+    */
+     MOCKABLE_FUNCTION(, IOTHUB_CLIENT_RESULT, IoTHubClient_LL_GetSendStatus, IOTHUB_CLIENT_LL_HANDLE, iotHubClientHandle, IOTHUB_CLIENT_STATUS*, iotHubClientStatus);
+
+    /**
+    * @brief    Sets up the message callback to be invoked when IoT Hub issues a
+    *             message to the device. This is a blocking call.
+    *
+    * @param    iotHubClientHandle               The handle created by a call to the create function.
+    * @param    messageCallback                The callback specified by the device for receiving
+    *                                         messages from IoT Hub.
+    * @param    userContextCallback            User specified context that will be provided to the
+    *                                         callback. This can be @c NULL.
+    *
+    *            @b NOTE: The application behavior is undefined if the user calls
+    *            the ::IoTHubClient_LL_Destroy function from within any callback.
+    *
+    * @return    IOTHUB_CLIENT_OK upon success or an error code upon failure.
+    */
+     MOCKABLE_FUNCTION(, IOTHUB_CLIENT_RESULT, IoTHubClient_LL_SetMessageCallback, IOTHUB_CLIENT_LL_HANDLE, iotHubClientHandle, IOTHUB_CLIENT_MESSAGE_CALLBACK_ASYNC, messageCallback, void*, userContextCallback);
+
+    /**
+    * @brief    Sets up the connection status callback to be invoked representing the status of
+    * the connection to IOT Hub. This is a blocking call.
+    *
+    * @param    iotHubClientHandle                       The handle created by a call to the create function.
+    * @param    connectionStatusCallback                The callback specified by the device for receiving
+    *                                                 updates about the status of the connection to IoT Hub.
+    * @param    userContextCallback                    User specified context that will be provided to the
+    *                                                 callback. This can be @c NULL.
+    *
+    *            @b NOTE: The application behavior is undefined if the user calls
+    *            the ::IoTHubClient_LL_Destroy function from within any callback.
+    *
+    * @return    IOTHUB_CLIENT_OK upon success or an error code upon failure.
+    */
+     MOCKABLE_FUNCTION(, IOTHUB_CLIENT_RESULT, IoTHubClient_LL_SetConnectionStatusCallback, IOTHUB_CLIENT_LL_HANDLE, iotHubClientHandle, IOTHUB_CLIENT_CONNECTION_STATUS_CALLBACK, connectionStatusCallback, void*, userContextCallback);
+
+    /**
+    * @brief    Sets up the connection status callback to be invoked representing the status of
+    * the connection to IOT Hub. This is a blocking call.
+    *
+    * @param    iotHubClientHandle                       The handle created by a call to the create function.
+    * @param    retryPolicy                             The policy to use to reconnect to IoT Hub when a
+    *                                               connection drops.
+    * @param    retryTimeoutLimitInSeconds            Maximum amount of time(seconds) to attempt reconnection when a
+    *                                               connection drops to IOT Hub.
+    *
+    *            @b NOTE: The application behavior is undefined if the user calls
+    *            the ::IoTHubClient_LL_Destroy function from within any callback.
+    *
+    * @return    IOTHUB_CLIENT_OK upon success or an error code upon failure.
+    */
+     MOCKABLE_FUNCTION(, IOTHUB_CLIENT_RESULT, IoTHubClient_LL_SetRetryPolicy, IOTHUB_CLIENT_LL_HANDLE, iotHubClientHandle, IOTHUB_CLIENT_RETRY_POLICY, retryPolicy, size_t, retryTimeoutLimitInSeconds);
+
+
+    /**
+    * @brief    Sets up the connection status callback to be invoked representing the status of
+    * the connection to IOT Hub. This is a blocking call.
+    *
+    * @param    iotHubClientHandle                       The handle created by a call to the create function.
+    * @param    retryPolicy                             Out parameter containing the policy to use to reconnect to IoT Hub.
+    * @param    retryTimeoutLimitInSeconds            Out parameter containing maximum amount of time in seconds to attempt reconnection
+                                                    to IOT Hub.
+    *
+    *            @b NOTE: The application behavior is undefined if the user calls
+    *            the ::IoTHubClient_LL_Destroy function from within any callback.
+    *
+    * @return    IOTHUB_CLIENT_OK upon success or an error code upon failure.
+    */
+     MOCKABLE_FUNCTION(, IOTHUB_CLIENT_RESULT, IoTHubClient_LL_GetRetryPolicy, IOTHUB_CLIENT_LL_HANDLE, iotHubClientHandle, IOTHUB_CLIENT_RETRY_POLICY*, retryPolicy, size_t*, retryTimeoutLimitInSeconds);
+
+    /**
+    * @brief    This function returns in the out parameter @p lastMessageReceiveTime
+    *             what was the value of the @c time function when the last message was
+    *             received at the client.
+    *
+    * @param    iotHubClientHandle                The handle created by a call to the create function.
+    * @param    lastMessageReceiveTime          Out parameter containing the value of @c time function
+    *                                             when the last message was received.
+    *
+    * @return    IOTHUB_CLIENT_OK upon success or an error code upon failure.
+    */
+     MOCKABLE_FUNCTION(, IOTHUB_CLIENT_RESULT, IoTHubClient_LL_GetLastMessageReceiveTime, IOTHUB_CLIENT_LL_HANDLE, iotHubClientHandle, time_t*, lastMessageReceiveTime);
+
+    /**
+    * @brief    This function is meant to be called by the user when work
+    *             (sending/receiving) can be done by the IoTHubClient.
+    *
+    * @param    iotHubClientHandle    The handle created by a call to the create function.
+    *
+    *            All IoTHubClient interactions (in regards to network traffic
+    *            and/or user level callbacks) are the effect of calling this
+    *            function and they take place synchronously inside _DoWork.
+    */
+     MOCKABLE_FUNCTION(, void, IoTHubClient_LL_DoWork, IOTHUB_CLIENT_LL_HANDLE, iotHubClientHandle);
+
+    /**
+    * @brief    This API sets a runtime option identified by parameter @p optionName
+    *             to a value pointed to by @p value. @p optionName and the data type
+    *             @p value is pointing to are specific for every option.
+    *
+    * @param    iotHubClientHandle    The handle created by a call to the create function.
+    * @param    optionName              Name of the option.
+    * @param    value                  The value.
+    *
+    *            The options that can be set via this API are:
+    *                - @b timeout - the maximum time in milliseconds a communication is
+    *                  allowed to use. @p value is a pointer to an @c unsigned @c int with
+    *                  the timeout value in milliseconds. This is only supported for the HTTP
+    *                  protocol as of now. When the HTTP protocol uses CURL, the meaning of
+    *                  the parameter is <em>total request time</em>. When the HTTP protocol uses
+    *                  winhttp, the meaning is the same as the @c dwSendTimeout and
+    *                  @c dwReceiveTimeout parameters of the
+    *                  <a href="https://msdn.microsoft.com/en-us/library/windows/desktop/aa384116(v=vs.85).aspx">
+    *                  WinHttpSetTimeouts</a> API.
+    *                - @b CURLOPT_LOW_SPEED_LIMIT - only available for HTTP protocol and only
+    *                  when CURL is used. It has the same meaning as CURL's option with the same
+    *                  name. @p value is pointer to a long.
+    *                - @b CURLOPT_LOW_SPEED_TIME - only available for HTTP protocol and only
+    *                  when CURL is used. It has the same meaning as CURL's option with the same
+    *                  name. @p value is pointer to a long.
+    *                - @b CURLOPT_FORBID_REUSE - only available for HTTP protocol and only
+    *                  when CURL is used. It has the same meaning as CURL's option with the same
+    *                  name. @p value is pointer to a long.
+    *                - @b CURLOPT_FRESH_CONNECT - only available for HTTP protocol and only
+    *                  when CURL is used. It has the same meaning as CURL's option with the same
+    *                  name. @p value is pointer to a long.
+    *                - @b CURLOPT_VERBOSE - only available for HTTP protocol and only
+    *                  when CURL is used. It has the same meaning as CURL's option with the same
+    *                  name. @p value is pointer to a long.
+    *              - @b keepalive - available for MQTT protocol.  Integer value that sets the
+    *                interval in seconds when pings are sent to the server.
+    *              - @b logtrace - available for MQTT protocol.  Boolean value that turns on and
+    *                off the diagnostic logging.
+    *              - @b sas_token_lifetime - available for MQTT & AMQP protocol.  size_t value that that determines the
+    *                sas token timeout length.
+    *
+    * @return    IOTHUB_CLIENT_OK upon success or an error code upon failure.
+    */
+     MOCKABLE_FUNCTION(, IOTHUB_CLIENT_RESULT, IoTHubClient_LL_SetOption, IOTHUB_CLIENT_LL_HANDLE, iotHubClientHandle, const char*, optionName, const void*, value);
+
+    /**
+    * @brief    This API specifies a call back to be used when the device receives a desired state update.
+    *
+    * @param    iotHubClientHandle        The handle created by a call to the create function.
+    * @param    deviceTwinCallback        The callback specified by the device client to be used for updating
+    *                                    the desired state. The callback will be called in response to patch
+    *                                    request send by the IoTHub services. The payload will be passed to the
+    *                                    callback, along with two version numbers:
+    *                                        - Desired:
+    *                                        - LastSeenReported:
+    * @param    userContextCallback        User specified context that will be provided to the
+    *                                     callback. This can be @c NULL.
+    *
+    *            @b NOTE: The application behavior is undefined if the user calls
+    *            the ::IoTHubClient_LL_Destroy function from within any callback.
+    *
+    * @return    IOTHUB_CLIENT_OK upon success or an error code upon failure.
+    */
+     MOCKABLE_FUNCTION(, IOTHUB_CLIENT_RESULT, IoTHubClient_LL_SetDeviceTwinCallback, IOTHUB_CLIENT_LL_HANDLE, iotHubClientHandle, IOTHUB_CLIENT_DEVICE_TWIN_CALLBACK, deviceTwinCallback, void*, userContextCallback);
+
+    /**
+    * @brief    This API sneds a report of the device's properties and their current values.
+    *
+    * @param    iotHubClientHandle        The handle created by a call to the create function.
+    * @param    reportedState            The current device property values to be 'reported' to the IoTHub.
+    * @param    reportedStateCallback    The callback specified by the device client to be called with the
+    *                                    result of the transaction.
+    * @param    userContextCallback        User specified context that will be provided to the
+    *                                     callback. This can be @c NULL.
+    *
+    *            @b NOTE: The application behavior is undefined if the user calls
+    *            the ::IoTHubClient_LL_Destroy function from within any callback.
+    *
+    * @return    IOTHUB_CLIENT_OK upon success or an error code upon failure.
+    */
+     MOCKABLE_FUNCTION(, IOTHUB_CLIENT_RESULT, IoTHubClient_LL_SendReportedState, IOTHUB_CLIENT_LL_HANDLE, iotHubClientHandle, const unsigned char*, reportedState, size_t, size, IOTHUB_CLIENT_REPORTED_STATE_CALLBACK, reportedStateCallback, void*, userContextCallback);
+
+     /**
+     * @brief    This API sets callback for cloud to device method call.
+     *
+     * @param    iotHubClientHandle        The handle created by a call to the create function.
+     * @param    deviceMethodCallback    The callback which will be called by IoTHub.
+     * @param    userContextCallback        User specified context that will be provided to the
+     *                                     callback. This can be @c NULL.
+     *
+     * @return    IOTHUB_CLIENT_OK upon success or an error code upon failure.
+     */
+     MOCKABLE_FUNCTION(, IOTHUB_CLIENT_RESULT, IoTHubClient_LL_SetDeviceMethodCallback, IOTHUB_CLIENT_LL_HANDLE, iotHubClientHandle, IOTHUB_CLIENT_DEVICE_METHOD_CALLBACK_ASYNC, deviceMethodCallback, void*, userContextCallback);
+
+     /**
+     * @brief    This API sets callback for async cloud to device method call.
+     *
+     * @param    iotHubClientHandle                The handle created by a call to the create function.
+     * @param    inboundDeviceMethodCallback     The callback which will be called by IoTHub.
+     * @param    userContextCallback                User specified context that will be provided to the
+     *                                             callback. This can be @c NULL.
+     *
+     * @return    IOTHUB_CLIENT_OK upon success or an error code upon failure.
+     */
+     MOCKABLE_FUNCTION(, IOTHUB_CLIENT_RESULT, IoTHubClient_LL_SetDeviceMethodCallback_Ex, IOTHUB_CLIENT_LL_HANDLE, iotHubClientHandle, IOTHUB_CLIENT_INBOUND_DEVICE_METHOD_CALLBACK, inboundDeviceMethodCallback, void*, userContextCallback);
+
+     /**
+     * @brief    This API responses to a asnyc method callback identified the methodId.
+     *
+     * @param    iotHubClientHandle      The handle created by a call to the create function.
+     * @param    methodId                The methodId of the Device Method callback.
+     * @param    response                The response data for the method callback.
+     * @param    response_size           The size of the response data buffer.
+     * @param    status_response         The status response of the method callback.
+     *
+     * @return    IOTHUB_CLIENT_OK upon success or an error code upon failure.
+     */
+     MOCKABLE_FUNCTION(, IOTHUB_CLIENT_RESULT, IoTHubClient_LL_DeviceMethodResponse, IOTHUB_CLIENT_LL_HANDLE, iotHubClientHandle, METHOD_HANDLE, methodId, const unsigned char*, response, size_t, respSize, int, statusCode);
+
+#ifndef DONT_USE_UPLOADTOBLOB
+    /**
+    * @brief    This API uploads to Azure Storage the content pointed to by @p source having the size @p size
+    *           under the blob name devicename/@pdestinationFileName
+    *
+    * @param    iotHubClientHandle        The handle created by a call to the create function.
+    * @param    destinationFileName     name of the file.
+    * @param    source                  pointer to the source for file content (can be NULL)
+    * @param    size                    the size of the source in memory (if @p source is NULL then size needs to be 0).
+    *
+    * @return    IOTHUB_CLIENT_OK upon success or an error code upon failure.
+    */
+     MOCKABLE_FUNCTION(, IOTHUB_CLIENT_RESULT, IoTHubClient_LL_UploadToBlob, IOTHUB_CLIENT_LL_HANDLE, iotHubClientHandle, const char*, destinationFileName, const unsigned char*, source, size_t, size);
+
+     /**
+     ** DEPRECATED: Use IoTHubClient_LL_UploadMultipleBlocksToBlobAsyncEx instead **
+     * @brief    This API uploads to Azure Storage the content provided block by block by @p getDataCallback
+     *           under the blob name devicename/@pdestinationFileName
+     *
+     * @param    iotHubClientHandle      The handle created by a call to the create function.
+     * @param    destinationFileName     name of the file.
+     * @param    getDataCallback         A callback to be invoked to acquire the file chunks to be uploaded, as well as to indicate the status of the upload of the previous block.
+     * @param    context                 Any data provided by the user to serve as context on getDataCallback.
+     *
+     * @return   IOTHUB_CLIENT_OK upon success or an error code upon failure.
+     ** DEPRECATED: Use IoTHubClient_LL_UploadMultipleBlocksToBlobAsyncEx instead **
+     */
+     MOCKABLE_FUNCTION(, IOTHUB_CLIENT_RESULT, IoTHubClient_LL_UploadMultipleBlocksToBlob, IOTHUB_CLIENT_LL_HANDLE, iotHubClientHandle, const char*, destinationFileName, IOTHUB_CLIENT_FILE_UPLOAD_GET_DATA_CALLBACK, getDataCallback, void*, context);
+
+     /**
+     * @brief    This API uploads to Azure Storage the content provided block by block by @p getDataCallback
+     *           under the blob name devicename/@pdestinationFileName
+     *
+     * @param    iotHubClientHandle      The handle created by a call to the create function.
+     * @param    destinationFileName     name of the file.
+     * @param    getDataCallbackEx       A callback to be invoked to acquire the file chunks to be uploaded, as well as to indicate the status of the upload of the previous block.
+     * @param    context                 Any data provided by the user to serve as context on getDataCallback.
+     *
+     * @return   IOTHUB_CLIENT_OK upon success or an error code upon failure.
+     */
+     MOCKABLE_FUNCTION(, IOTHUB_CLIENT_RESULT, IoTHubClient_LL_UploadMultipleBlocksToBlobEx, IOTHUB_CLIENT_LL_HANDLE, iotHubClientHandle, const char*, destinationFileName, IOTHUB_CLIENT_FILE_UPLOAD_GET_DATA_CALLBACK_EX, getDataCallbackEx, void*, context);
+
+#endif /*DONT_USE_UPLOADTOBLOB*/
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* IOTHUB_CLIENT_LL_H */
Index: azure_iot_hub_f767zi/trunk/azure_iot_sdk/iothub_client/inc/iothub_client_options.h
===================================================================
--- azure_iot_hub_f767zi/trunk/azure_iot_sdk/iothub_client/inc/iothub_client_options.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/azure_iot_sdk/iothub_client/inc/iothub_client_options.h	(revision 457)
@@ -0,0 +1,93 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+#ifndef IOTHUB_CLIENT_OPTIONS_H
+#define IOTHUB_CLIENT_OPTIONS_H
+
+#include "azure_c_shared_utility/const_defines.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+    typedef struct IOTHUB_PROXY_OPTIONS_TAG
+    {
+        const char* host_address;
+        const char* username;
+        const char* password;
+    } IOTHUB_PROXY_OPTIONS;
+
+    static STATIC_VAR_UNUSED const char* OPTION_RETRY_INTERVAL_SEC = "retry_interval_sec";
+    static STATIC_VAR_UNUSED const char* OPTION_RETRY_MAX_DELAY_SECS = "retry_max_delay_secs";
+
+    static STATIC_VAR_UNUSED const char* OPTION_LOG_TRACE = "logtrace";
+    static STATIC_VAR_UNUSED const char* OPTION_X509_CERT = "x509certificate";
+    static STATIC_VAR_UNUSED const char* OPTION_X509_PRIVATE_KEY = "x509privatekey";
+    static STATIC_VAR_UNUSED const char* OPTION_KEEP_ALIVE = "keepalive";
+    static STATIC_VAR_UNUSED const char* OPTION_CONNECTION_TIMEOUT = "connect_timeout";
+
+    static STATIC_VAR_UNUSED const char* OPTION_PROXY_HOST = "proxy_address";
+    static STATIC_VAR_UNUSED const char* OPTION_PROXY_USERNAME = "proxy_username";
+    static STATIC_VAR_UNUSED const char* OPTION_PROXY_PASSWORD = "proxy_password";
+
+    static STATIC_VAR_UNUSED const char* OPTION_SAS_TOKEN_LIFETIME = "sas_token_lifetime";
+    static STATIC_VAR_UNUSED const char* OPTION_SAS_TOKEN_REFRESH_TIME = "sas_token_refresh_time";
+    static STATIC_VAR_UNUSED const char* OPTION_CBS_REQUEST_TIMEOUT = "cbs_request_timeout";
+
+    static STATIC_VAR_UNUSED const char* OPTION_MIN_POLLING_TIME = "MinimumPollingTime";
+    static STATIC_VAR_UNUSED const char* OPTION_BATCHING = "Batching";
+
+    /* DEPRECATED:: OPTION_MESSAGE_TIMEOUT is DEPRECATED! Use OPTION_SERVICE_SIDE_KEEP_ALIVE_FREQ_SECS for AMQP; MQTT has no option available. OPTION_MESSAGE_TIMEOUT legacy variable will be kept for back-compat.  */
+    static STATIC_VAR_UNUSED const char* OPTION_MESSAGE_TIMEOUT = "messageTimeout";
+    static STATIC_VAR_UNUSED const char* OPTION_BLOB_UPLOAD_TIMEOUT_SECS = "blob_upload_timeout_secs";
+    static STATIC_VAR_UNUSED const char* OPTION_PRODUCT_INFO = "product_info";
+
+    /*
+    * @brief    Specifies the Digital Twin Model Id of the connection. Only valid for use with MQTT Transport
+    */
+    static STATIC_VAR_UNUSED const char* OPTION_MODEL_ID = "model_id";
+
+    /*
+    * @brief    Turns on automatic URL encoding of message properties + system properties. Only valid for use with MQTT Transport
+    */
+    static STATIC_VAR_UNUSED const char* OPTION_AUTO_URL_ENCODE_DECODE = "auto_url_encode_decode";
+
+    /*
+    * @brief Informs the service of what is the maximum period the client will wait for a keep-alive message from the service.
+    *        The service must send keep-alives before this timeout is reached, otherwise the client will trigger its re-connection logic.
+    *        Setting this option to a low value results in more aggressive/responsive re-connection by the client.
+    *        The default value for this option is 240 seconds, and the minimum allowed is usually 5 seconds.
+    *        To virtually disable the keep-alives from the service (and consequently the keep-alive timeout control on the client-side), set this option to a high value (e.g., UINT_MAX).
+    */
+    static STATIC_VAR_UNUSED const char* OPTION_SERVICE_SIDE_KEEP_ALIVE_FREQ_SECS = "svc2cl_keep_alive_timeout_secs";
+
+    /* DEPRECATED:: OPTION_C2D_KEEP_ALIVE_FREQ_SECS is DEPRECATED!  Use OPTION_SERVICE_SIDE_KEEP_ALIVE_FREQ_SECS, but OPTION_C2D_KEEP_ALIVE_FREQ_SECS legacy variable kept for back-compat.  */
+    static STATIC_VAR_UNUSED const char* OPTION_C2D_KEEP_ALIVE_FREQ_SECS = "c2d_keep_alive_freq_secs";
+
+    /*
+    * @brief Ratio to be used for client side pings in AMQP protocol.
+    *        The client must use this ratio to send keep-alives before service side remote idle timeout is reached, otherwise the service will disconnect the client.
+    *        The default value for this option is 1/2 of the remote idle value sent by the service.
+    *        For AMQP remote idle set to 4 minutes, default client ping will be 2 minutes. For AMQP remote idle set to 25 minutes configured via per Hub basis, the default ping will be 12.5 minutes.
+    */
+    static STATIC_VAR_UNUSED const char* OPTION_REMOTE_IDLE_TIMEOUT_RATIO = "cl2svc_keep_alive_send_ratio";
+
+    /*
+    * @brief This option should be used instead of OPTION_MESSAGE_TIMEOUT if using AMQP protocol.
+    *        It defines the maximum ammount of time, in seconds, the client will wait for a telemetry message to complete sending before returning it with a IOTHUB_CLIENT_CONFIRMATION_MESSAGE_TIMEOUT error.
+    *        The default value 5 (five) minutes.
+    *        This option is applicable only to AMQP protocol.
+    */
+    static STATIC_VAR_UNUSED const char* OPTION_EVENT_SEND_TIMEOUT_SECS = "event_send_timeout_secs";
+
+    //diagnostic sampling percentage value, [0-100]
+    static STATIC_VAR_UNUSED const char* OPTION_DIAGNOSTIC_SAMPLING_PERCENTAGE = "diag_sampling_percentage";
+
+    static STATIC_VAR_UNUSED const char* OPTION_DO_WORK_FREQUENCY_IN_MS = "do_work_freq_ms";
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* IOTHUB_CLIENT_OPTIONS_H */
Index: azure_iot_hub_f767zi/trunk/azure_iot_sdk/iothub_client/inc/iothub_client_version.h
===================================================================
--- azure_iot_hub_f767zi/trunk/azure_iot_sdk/iothub_client/inc/iothub_client_version.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/azure_iot_sdk/iothub_client/inc/iothub_client_version.h	(revision 457)
@@ -0,0 +1,33 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+/** @file iothub_client_version.h
+*    @brief Functions for managing the client SDK version.
+*/
+
+#ifndef IOTHUB_CLIENT_VERSION_H
+#define IOTHUB_CLIENT_VERSION_H
+
+#define IOTHUB_SDK_VERSION "1.3.8"
+
+#include "umock_c/umock_c_prod.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+    /**
+     * @brief   Returns a pointer to a null terminated string containing the
+     *          current IoT Hub Client SDK version.
+     *
+     * @return  Pointer to a null terminated string containing the
+     *          current IoT Hub Client SDK version.
+     */
+    MOCKABLE_FUNCTION(, const char*, IoTHubClient_GetVersionString);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // IOTHUB_CLIENT_VERSION_H
Index: azure_iot_hub_f767zi/trunk/azure_iot_sdk/iothub_client/inc/iothub_device_client_ll.h
===================================================================
--- azure_iot_hub_f767zi/trunk/azure_iot_sdk/iothub_client/inc/iothub_device_client_ll.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/azure_iot_sdk/iothub_client/inc/iothub_device_client_ll.h	(revision 457)
@@ -0,0 +1,400 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+/** @file iothub_device_client_ll.h
+*    @brief     APIs that allow a user (usually a device) to communicate
+*             with an Azure IoTHub.
+*
+*    @details IoTHubDeviceClient_LL is a module that allows a user (usually a
+*             device) to communicate with an Azure IoTHub. It can send events
+*             and receive messages. At any given moment in time there can only
+*             be at most 1 message callback function.
+*
+*             This API surface contains a set of APIs that allows the user to
+*             interact with the lower layer portion of the IoTHubClient. These APIs
+*             contain @c _LL_ in their name, but retain the same functionality like the
+*             @c IoTHubDeviceClient_... APIs, with one difference. If the @c _LL_ APIs are
+*             used then the user is responsible for scheduling when the actual work done
+*             by the IoTHubClient happens (when the data is sent/received on/from the wire).
+*             This is useful for constrained devices where spinning a separate thread is
+*             often not desired.
+*/
+
+#ifndef IOTHUB_DEVICE_CLIENT_LL_H
+#define IOTHUB_DEVICE_CLIENT_LL_H
+
+#include <stddef.h>
+#include <stdint.h>
+
+#include "azure_macro_utils/macro_utils.h"
+#include "umock_c/umock_c_prod.h"
+
+#include "iothub_transport_ll.h"
+#include "iothub_client_core_ll.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+typedef struct IOTHUB_CLIENT_CORE_LL_HANDLE_DATA_TAG* IOTHUB_DEVICE_CLIENT_LL_HANDLE;
+
+
+    /**
+    * @brief    Creates a IoT Hub client for communication with an existing
+    *           IoT Hub using the specified connection string parameter.
+    *
+    * @param    connectionString    Pointer to a character string
+    * @param    protocol            Function pointer for protocol implementation
+    *
+    *            Sample connection string:
+    *                <blockquote>
+    *                    <pre>HostName=[IoT Hub name goes here].[IoT Hub suffix goes here, e.g., private.azure-devices-int.net];DeviceId=[Device ID goes here];SharedAccessKey=[Device key goes here];</pre>
+    *                </blockquote>
+    *
+    * @return    A non-NULL @c IOTHUB_DEVICE_CLIENT_LL_HANDLE value that is used when
+    *             invoking other functions for IoT Hub client and @c NULL on failure.
+    */
+     MOCKABLE_FUNCTION(, IOTHUB_DEVICE_CLIENT_LL_HANDLE, IoTHubDeviceClient_LL_CreateFromConnectionString, const char*, connectionString, IOTHUB_CLIENT_TRANSPORT_PROVIDER, protocol);
+
+    /**
+    * @brief    Creates a IoT Hub client for communication with an existing IoT
+    *           Hub using the specified parameters.
+    *
+    * @param    config    Pointer to an @c IOTHUB_CLIENT_CONFIG structure
+    *
+    *           The API does not allow sharing of a connection across multiple
+    *           devices. This is a blocking call.
+    *
+    * @return    A non-NULL @c IOTHUB_DEVICE_CLIENT_LL_HANDLE value that is used when
+    *            invoking other functions for IoT Hub client and @c NULL on failure.
+    */
+     MOCKABLE_FUNCTION(, IOTHUB_DEVICE_CLIENT_LL_HANDLE, IoTHubDeviceClient_LL_Create, const IOTHUB_CLIENT_CONFIG*, config);
+
+    /**
+    * @brief    Creates a IoT Hub client for communication with an existing IoT
+    *           Hub using an existing transport.
+    *
+    * @param    config    Pointer to an @c IOTHUB_CLIENT_DEVICE_CONFIG structure
+    *
+    *           The API *allows* sharing of a connection across multiple
+    *           devices. This is a blocking call.
+    *
+    * @return   A non-NULL @c IOTHUB_DEVICE_CLIENT_LL_HANDLE value that is used when
+    *           invoking other functions for IoT Hub client and @c NULL on failure.
+    */
+     MOCKABLE_FUNCTION(, IOTHUB_DEVICE_CLIENT_LL_HANDLE, IoTHubDeviceClient_LL_CreateWithTransport, const IOTHUB_CLIENT_DEVICE_CONFIG*, config);
+
+     /**
+     * @brief    Creates a IoT Hub client for communication with an existing IoT
+     *           Hub using the device auth module.
+     *
+     * @param    iothub_uri             Pointer to an ioThub hostname received in the registration process
+     * @param    device_id              Pointer to the device Id of the device
+     * @param    device_auth_handle     A device auth handle used to generate the connection string
+     * @param    protocol               Function pointer for protocol implementation
+     *
+     * @return   A non-NULL @c IOTHUB_DEVICE_CLIENT_LL_HANDLE value that is used when
+     *           invoking other functions for IoT Hub client and @c NULL on failure.
+     */
+     MOCKABLE_FUNCTION(, IOTHUB_DEVICE_CLIENT_LL_HANDLE, IoTHubDeviceClient_LL_CreateFromDeviceAuth, const char*, iothub_uri, const char*, device_id, IOTHUB_CLIENT_TRANSPORT_PROVIDER, protocol);
+
+    /**
+    * @brief    Disposes of resources allocated by the IoT Hub client. This is a
+    *           blocking call.
+    *
+    * @param    iotHubClientHandle    The handle created by a call to the create function.
+    */
+     MOCKABLE_FUNCTION(, void, IoTHubDeviceClient_LL_Destroy, IOTHUB_DEVICE_CLIENT_LL_HANDLE, iotHubClientHandle);
+
+    /**
+    * @brief    Asynchronous call to send the message specified by @p eventMessageHandle.
+    *
+    * @param    iotHubClientHandle              The handle created by a call to the create function.
+    * @param    eventMessageHandle              The handle to an IoT Hub message.
+    * @param    eventConfirmationCallback       The callback specified by the device for receiving
+    *                                           confirmation of the delivery of the IoT Hub message.
+    *                                           This callback can be expected to invoke the
+    *                                           ::IoTHubDeviceClient_LL_SendEventAsync function for the
+    *                                           same message in an attempt to retry sending a failing
+    *                                           message. The user can specify a @c NULL value here to
+    *                                           indicate that no callback is required.
+    * @param    userContextCallback             User specified context that will be provided to the
+    *                                           callback. This can be @c NULL.
+    *
+    *           @b NOTE: The application behavior is undefined if the user calls
+    *           the ::IoTHubDeviceClient_LL_Destroy function from within any callback.
+    * @remarks
+    *           The IOTHUB_MESSAGE_HANDLE instance provided as argument is copied by the function,
+    *           so this argument can be destroyed by the calling application right after IoTHubDeviceClient_LL_SendEventAsync returns.
+    *           The copy of @c eventMessageHandle is later destroyed by the iothub client when the message is effectively sent, if a failure sending it occurs, or if the client is destroyed.
+    * @return   IOTHUB_CLIENT_OK upon success or an error code upon failure.
+    */
+     MOCKABLE_FUNCTION(, IOTHUB_CLIENT_RESULT, IoTHubDeviceClient_LL_SendEventAsync, IOTHUB_DEVICE_CLIENT_LL_HANDLE, iotHubClientHandle, IOTHUB_MESSAGE_HANDLE, eventMessageHandle, IOTHUB_CLIENT_EVENT_CONFIRMATION_CALLBACK, eventConfirmationCallback, void*, userContextCallback);
+
+    /**
+    * @brief    This function returns the current sending status for IoTHubClient.
+    *
+    * @param    iotHubClientHandle        The handle created by a call to the create function.
+    * @param    iotHubClientStatus        The sending state is populated at the address pointed
+    *                                     at by this parameter. The value will be set to
+    *                                     @c IOTHUBCLIENT_SENDSTATUS_IDLE if there is currently
+    *                                     no item to be sent and @c IOTHUBCLIENT_SENDSTATUS_BUSY
+    *                                     if there are.
+    *
+    * @return    IOTHUB_CLIENT_OK upon success or an error code upon failure.
+    */
+     MOCKABLE_FUNCTION(, IOTHUB_CLIENT_RESULT, IoTHubDeviceClient_LL_GetSendStatus, IOTHUB_DEVICE_CLIENT_LL_HANDLE, iotHubClientHandle, IOTHUB_CLIENT_STATUS*, iotHubClientStatus);
+
+    /**
+    * @brief    Sets up the message callback to be invoked when IoT Hub issues a
+    *           message to the device. This is a blocking call.
+    *
+    * @param    iotHubClientHandle              The handle created by a call to the create function.
+    * @param    messageCallback                 The callback specified by the device for receiving
+    *                                           messages from IoT Hub.
+    * @param    userContextCallback             User specified context that will be provided to the
+    *                                           callback. This can be @c NULL.
+    *
+    *           @b NOTE: The application behavior is undefined if the user calls
+    *           the ::IoTHubDeviceClient_LL_Destroy function from within any callback.
+    *
+    * @return   IOTHUB_CLIENT_OK upon success or an error code upon failure.
+    */
+     MOCKABLE_FUNCTION(, IOTHUB_CLIENT_RESULT, IoTHubDeviceClient_LL_SetMessageCallback, IOTHUB_DEVICE_CLIENT_LL_HANDLE, iotHubClientHandle, IOTHUB_CLIENT_MESSAGE_CALLBACK_ASYNC, messageCallback, void*, userContextCallback);
+
+    /**
+    * @brief    Sets up the connection status callback to be invoked representing the status of
+    * the connection to IOT Hub. This is a blocking call.
+    *
+    * @param    iotHubClientHandle              The handle created by a call to the create function.
+    * @param    connectionStatusCallback        The callback specified by the device for receiving
+    *                                           updates about the status of the connection to IoT Hub.
+    * @param    userContextCallback             User specified context that will be provided to the
+    *                                           callback. This can be @c NULL.
+    *
+    *           @b NOTE: The application behavior is undefined if the user calls
+    *           the ::IoTHubDeviceClient_LL_Destroy function from within any callback.
+    *
+    * @return   IOTHUB_CLIENT_OK upon success or an error code upon failure.
+    */
+     MOCKABLE_FUNCTION(, IOTHUB_CLIENT_RESULT, IoTHubDeviceClient_LL_SetConnectionStatusCallback, IOTHUB_DEVICE_CLIENT_LL_HANDLE, iotHubClientHandle, IOTHUB_CLIENT_CONNECTION_STATUS_CALLBACK, connectionStatusCallback, void*, userContextCallback);
+
+    /**
+    * @brief    Sets up the connection status callback to be invoked representing the status of
+    * the connection to IOT Hub. This is a blocking call.
+    *
+    * @param    iotHubClientHandle              The handle created by a call to the create function.
+    * @param    retryPolicy                     The policy to use to reconnect to IoT Hub when a
+    *                                           connection drops.
+    * @param    retryTimeoutLimitInSeconds      Maximum amount of time(seconds) to attempt reconnection when a
+    *                                           connection drops to IOT Hub.
+    *
+    *           @b NOTE: The application behavior is undefined if the user calls
+    *           the ::IoTHubDeviceClient_LL_Destroy function from within any callback.
+    *
+    * @return   IOTHUB_CLIENT_OK upon success or an error code upon failure.
+    */
+     MOCKABLE_FUNCTION(, IOTHUB_CLIENT_RESULT, IoTHubDeviceClient_LL_SetRetryPolicy, IOTHUB_DEVICE_CLIENT_LL_HANDLE, iotHubClientHandle, IOTHUB_CLIENT_RETRY_POLICY, retryPolicy, size_t, retryTimeoutLimitInSeconds);
+
+
+    /**
+    * @brief    Sets up the connection status callback to be invoked representing the status of
+    * the connection to IOT Hub. This is a blocking call.
+    *
+    * @param    iotHubClientHandle                  The handle created by a call to the create function.
+    * @param    retryPolicy                         Out parameter containing the policy to use to reconnect to IoT Hub.
+    * @param    retryTimeoutLimitInSeconds          Out parameter containing maximum amount of time in seconds to attempt reconnection
+                                                    to IOT Hub.
+    *
+    *           @b NOTE: The application behavior is undefined if the user calls
+    *           the ::IoTHubDeviceClient_LL_Destroy function from within any callback.
+    *
+    * @return   IOTHUB_CLIENT_OK upon success or an error code upon failure.
+    */
+     MOCKABLE_FUNCTION(, IOTHUB_CLIENT_RESULT, IoTHubDeviceClient_LL_GetRetryPolicy, IOTHUB_DEVICE_CLIENT_LL_HANDLE, iotHubClientHandle, IOTHUB_CLIENT_RETRY_POLICY*, retryPolicy, size_t*, retryTimeoutLimitInSeconds);
+
+    /**
+    * @brief    This function returns in the out parameter @p lastMessageReceiveTime
+    *           what was the value of the @c time function when the last message was
+    *           received at the client.
+    *
+    * @param    iotHubClientHandle          The handle created by a call to the create function.
+    * @param    lastMessageReceiveTime      Out parameter containing the value of @c time function
+    *                                       when the last message was received.
+    *
+    * @return   IOTHUB_CLIENT_OK upon success or an error code upon failure.
+    */
+     MOCKABLE_FUNCTION(, IOTHUB_CLIENT_RESULT, IoTHubDeviceClient_LL_GetLastMessageReceiveTime, IOTHUB_DEVICE_CLIENT_LL_HANDLE, iotHubClientHandle, time_t*, lastMessageReceiveTime);
+
+    /**
+    * @brief    This function MUST be called by the user so work (sending/receiving data on the wire,
+    *           computing and enforcing timeout controls, managing the connection to the IoT Hub) can
+    *           be done by the IoTHubClient.
+    *           The recommended call frequency is at least once every 100 milliseconds.
+    *
+    * @param    iotHubClientHandle    The handle created by a call to the create function.
+    *
+    *           All IoTHubClient interactions (in regards to network traffic
+    *           and/or user level callbacks) are the effect of calling this
+    *           function and they take place synchronously inside _DoWork.
+    */
+     MOCKABLE_FUNCTION(, void, IoTHubDeviceClient_LL_DoWork, IOTHUB_DEVICE_CLIENT_LL_HANDLE, iotHubClientHandle);
+
+    /**
+    * @brief    This API sets a runtime option identified by parameter @p optionName
+    *           to a value pointed to by @p value. @p optionName and the data type
+    *           @p value is pointing to are specific for every option.
+    *
+    * @param    iotHubClientHandle      The handle created by a call to the create function.
+    * @param    optionName              Name of the option.
+    * @param    value                   The value.
+    *
+    *           The options that can be set via this API are:
+    *                - @b timeout - the maximum time in milliseconds a communication is
+    *                  allowed to use. @p value is a pointer to an @c unsigned @c int with
+    *                  the timeout value in milliseconds. This is only supported for the HTTP
+    *                  protocol as of now. When the HTTP protocol uses CURL, the meaning of
+    *                  the parameter is <em>total request time</em>. When the HTTP protocol uses
+    *                  winhttp, the meaning is the same as the @c dwSendTimeout and
+    *                  @c dwReceiveTimeout parameters of the
+    *                  <a href="https://msdn.microsoft.com/en-us/library/windows/desktop/aa384116(v=vs.85).aspx">
+    *                  WinHttpSetTimeouts</a> API.
+    *                - @b CURLOPT_LOW_SPEED_LIMIT - only available for HTTP protocol and only
+    *                  when CURL is used. It has the same meaning as CURL's option with the same
+    *                  name. @p value is pointer to a long.
+    *                - @b CURLOPT_LOW_SPEED_TIME - only available for HTTP protocol and only
+    *                  when CURL is used. It has the same meaning as CURL's option with the same
+    *                  name. @p value is pointer to a long.
+    *                - @b CURLOPT_FORBID_REUSE - only available for HTTP protocol and only
+    *                  when CURL is used. It has the same meaning as CURL's option with the same
+    *                  name. @p value is pointer to a long.
+    *                - @b CURLOPT_FRESH_CONNECT - only available for HTTP protocol and only
+    *                  when CURL is used. It has the same meaning as CURL's option with the same
+    *                  name. @p value is pointer to a long.
+    *                - @b CURLOPT_VERBOSE - only available for HTTP protocol and only
+    *                  when CURL is used. It has the same meaning as CURL's option with the same
+    *                  name. @p value is pointer to a long.
+    *                - @b keepalive - available for MQTT protocol.  Integer value that sets the
+    *                  interval in seconds when pings are sent to the server.
+    *                - @b logtrace - available for MQTT protocol.  Boolean value that turns on and
+    *                  off the diagnostic logging.
+    *                - @b sas_token_lifetime - available for MQTT & AMQP protocol.  size_t value that that determines the
+    *                  sas token timeout length.
+    *                - @b OPTION_TRUSTED_CERT - Azure Server certificate used to validate TLS connection to iothub.
+    *
+    * @return   IOTHUB_CLIENT_OK upon success or an error code upon failure.
+    */
+     MOCKABLE_FUNCTION(, IOTHUB_CLIENT_RESULT, IoTHubDeviceClient_LL_SetOption, IOTHUB_DEVICE_CLIENT_LL_HANDLE, iotHubClientHandle, const char*, optionName, const void*, value);
+
+    /**
+    * @brief   This API specifies a callback to be used when the device receives a desired state update.
+    *
+    * @param   iotHubClientHandle        The handle created by a call to the create function.
+    * @param   deviceTwinCallback        The callback specified by the device client to be used for updating
+    *                                    the desired state. The callback will be called in response to patch
+    *                                    request send by the IoTHub services. The payload will be passed to the
+    *                                    callback, along with two version numbers:
+    *                                        - Desired:
+    *                                        - LastSeenReported:
+    * @param   userContextCallback       User specified context that will be provided to the
+    *                                    callback. This can be @c NULL.
+    *
+    *           @b NOTE: The application behavior is undefined if the user calls
+    *           the ::IoTHubDeviceClient_LL_Destroy function from within any callback.
+    *
+    * @return   IOTHUB_CLIENT_OK upon success or an error code upon failure.
+    */
+     MOCKABLE_FUNCTION(, IOTHUB_CLIENT_RESULT, IoTHubDeviceClient_LL_SetDeviceTwinCallback, IOTHUB_DEVICE_CLIENT_LL_HANDLE, iotHubClientHandle, IOTHUB_CLIENT_DEVICE_TWIN_CALLBACK, deviceTwinCallback, void*, userContextCallback);
+
+    /**
+    * @brief    This API sends a report of the device's properties and their current values.
+    *
+    * @param    iotHubClientHandle        The handle created by a call to the create function.
+    * @param    reportedState             The current device property values to be 'reported' to the IoTHub.
+    * @param    reportedStateCallback     The callback specified by the device client to be called with the
+    *                                     result of the transaction.
+    * @param    userContextCallback       User specified context that will be provided to the
+    *                                     callback. This can be @c NULL.
+    *
+    *            @b NOTE: The application behavior is undefined if the user calls
+    *            the ::IoTHubDeviceClient_LL_Destroy function from within any callback.
+    *
+    * @return    IOTHUB_CLIENT_OK upon success or an error code upon failure.
+    */
+     MOCKABLE_FUNCTION(, IOTHUB_CLIENT_RESULT, IoTHubDeviceClient_LL_SendReportedState, IOTHUB_DEVICE_CLIENT_LL_HANDLE, iotHubClientHandle, const unsigned char*, reportedState, size_t, size, IOTHUB_CLIENT_REPORTED_STATE_CALLBACK, reportedStateCallback, void*, userContextCallback);
+
+     /**
+     * @brief	This API enabled the device to request the full device twin (with all the desired and reported properties) on demand.
+     *
+     * @param	iotHubClientHandle		The handle created by a call to the create function.
+     * @param	deviceTwinCallback	    The callback specified by the device client to receive the Twin document.
+     * @param	userContextCallback		User specified context that will be provided to the
+     * 									callback. This can be @c NULL.
+     *
+     *			@b NOTE: The application behavior is undefined if the user calls
+     *			the ::IoTHubClient_LL_Destroy function from within any callback.
+     *
+     * @return	IOTHUB_CLIENT_OK upon success or an error code upon failure.
+     */
+     MOCKABLE_FUNCTION(, IOTHUB_CLIENT_RESULT, IoTHubDeviceClient_LL_GetTwinAsync, IOTHUB_DEVICE_CLIENT_LL_HANDLE, iotHubClientHandle, IOTHUB_CLIENT_DEVICE_TWIN_CALLBACK, deviceTwinCallback, void*, userContextCallback);
+
+     /**
+     * @brief    This API sets the callback for async cloud to device method calls.
+     *
+     * @param    iotHubClientHandle                 The handle created by a call to the create function.
+     * @param    inboundDeviceMethodCallback        The callback which will be called by IoTHub.
+     * @param    userContextCallback                User specified context that will be provided to the
+     *                                              callback. This can be @c NULL.
+     *
+     * @return   IOTHUB_CLIENT_OK upon success or an error code upon failure.
+     */
+     MOCKABLE_FUNCTION(, IOTHUB_CLIENT_RESULT, IoTHubDeviceClient_LL_SetDeviceMethodCallback, IOTHUB_DEVICE_CLIENT_LL_HANDLE, iotHubClientHandle, IOTHUB_CLIENT_DEVICE_METHOD_CALLBACK_ASYNC, deviceMethodCallback, void*, userContextCallback);
+
+     /**
+     * @brief    This API responds to an asnyc method callback identified the methodId.
+     *
+     * @param    iotHubClientHandle      The handle created by a call to the create function.
+     * @param    methodId                The methodId of the Device Method callback.
+     * @param    response                The response data for the method callback.
+     * @param    response_size           The size of the response data buffer.
+     * @param    status_response         The status response of the method callback.
+     *
+     * @return   IOTHUB_CLIENT_OK upon success or an error code upon failure.
+     */
+     MOCKABLE_FUNCTION(, IOTHUB_CLIENT_RESULT, IoTHubDeviceClient_LL_DeviceMethodResponse, IOTHUB_DEVICE_CLIENT_LL_HANDLE, iotHubClientHandle, METHOD_HANDLE, methodId, const unsigned char*, response, size_t, respSize, int, statusCode);
+
+#ifndef DONT_USE_UPLOADTOBLOB
+    /**
+    * @brief    This API uploads to Azure Storage the content pointed to by @p source having the size @p size
+    *           under the blob name devicename/@pdestinationFileName
+    *
+    * @param    iotHubClientHandle      The handle created by a call to the create function.
+    * @param    destinationFileName     name of the file.
+    * @param    source                  pointer to the source for file content (can be NULL)
+    * @param    size                    the size of the source in memory (if @p source is NULL then size needs to be 0).
+    *
+    * @return   IOTHUB_CLIENT_OK upon success or an error code upon failure.
+    */
+     MOCKABLE_FUNCTION(, IOTHUB_CLIENT_RESULT, IoTHubDeviceClient_LL_UploadToBlob, IOTHUB_DEVICE_CLIENT_LL_HANDLE, iotHubClientHandle, const char*, destinationFileName, const unsigned char*, source, size_t, size);
+
+     /**
+     * @brief    This API uploads to Azure Storage the content provided block by block by @p getDataCallback
+     *           under the blob name devicename/@pdestinationFileName
+     *
+     * @param    iotHubClientHandle      The handle created by a call to the create function.
+     * @param    destinationFileName     name of the file.
+     * @param    getDataCallbackEx       A callback to be invoked to acquire the file chunks to be uploaded, as well as to indicate the status of the upload of the previous block.
+     * @param    context                 Any data provided by the user to serve as context on getDataCallback.
+     *
+     * @return   IOTHUB_CLIENT_OK upon success or an error code upon failure.
+     */
+     MOCKABLE_FUNCTION(, IOTHUB_CLIENT_RESULT, IoTHubDeviceClient_LL_UploadMultipleBlocksToBlob, IOTHUB_DEVICE_CLIENT_LL_HANDLE, iotHubClientHandle, const char*, destinationFileName, IOTHUB_CLIENT_FILE_UPLOAD_GET_DATA_CALLBACK_EX, getDataCallbackEx, void*, context);
+
+#endif /*DONT_USE_UPLOADTOBLOB*/
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* IOTHUB_DEVICE_CLIENT_LL_H */
Index: azure_iot_hub_f767zi/trunk/azure_iot_sdk/iothub_client/inc/iothub_message.h
===================================================================
--- azure_iot_hub_f767zi/trunk/azure_iot_sdk/iothub_client/inc/iothub_message.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/azure_iot_sdk/iothub_client/inc/iothub_message.h	(revision 457)
@@ -0,0 +1,401 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+/** @file   iothub_message.h
+*    @brief  The @c IoTHub_Message component encapsulates one message that
+*           can be transferred by an IoT hub client.
+*/
+
+#ifndef IOTHUB_MESSAGE_H
+#define IOTHUB_MESSAGE_H
+
+#include "azure_macro_utils/macro_utils.h"
+#include "azure_c_shared_utility/map.h"
+#include "umock_c/umock_c_prod.h"
+
+#ifdef __cplusplus
+#include <cstddef>
+extern "C"
+{
+#else
+#include <stddef.h>
+#endif
+
+#define IOTHUB_MESSAGE_RESULT_VALUES         \
+    IOTHUB_MESSAGE_OK,                       \
+    IOTHUB_MESSAGE_INVALID_ARG,              \
+    IOTHUB_MESSAGE_INVALID_TYPE,             \
+    IOTHUB_MESSAGE_ERROR                     \
+
+/** @brief Enumeration specifying the status of calls to various
+*  APIs in this module.
+*/
+MU_DEFINE_ENUM_WITHOUT_INVALID(IOTHUB_MESSAGE_RESULT, IOTHUB_MESSAGE_RESULT_VALUES);
+
+#define IOTHUBMESSAGE_CONTENT_TYPE_VALUES \
+IOTHUBMESSAGE_BYTEARRAY, \
+IOTHUBMESSAGE_STRING, \
+IOTHUBMESSAGE_UNKNOWN \
+
+/** @brief Enumeration specifying the content type of the a given
+* message.
+*/
+MU_DEFINE_ENUM_WITHOUT_INVALID(IOTHUBMESSAGE_CONTENT_TYPE, IOTHUBMESSAGE_CONTENT_TYPE_VALUES);
+
+typedef struct IOTHUB_MESSAGE_HANDLE_DATA_TAG* IOTHUB_MESSAGE_HANDLE;
+
+/** @brief diagnostic related data*/
+typedef struct IOTHUB_MESSAGE_DIAGNOSTIC_PROPERTY_DATA_TAG
+{
+    char* diagnosticId;
+    char* diagnosticCreationTimeUtc;
+}IOTHUB_MESSAGE_DIAGNOSTIC_PROPERTY_DATA, *IOTHUB_MESSAGE_DIAGNOSTIC_PROPERTY_DATA_HANDLE;
+
+static const char DIAG_CREATION_TIME_UTC_PROPERTY_NAME[] = "diag_creation_time_utc";
+
+/**
+* @brief   Creates a new IoT hub message from a byte array. The type of the
+*          message will be set to @c IOTHUBMESSAGE_BYTEARRAY.
+*
+* @param   byteArray   The byte array from which the message is to be created.
+* @param   size        The size of the byte array.
+*
+* @return  A valid @c IOTHUB_MESSAGE_HANDLE if the message was successfully
+*          created or @c NULL in case an error occurs.
+*/
+MOCKABLE_FUNCTION(, IOTHUB_MESSAGE_HANDLE, IoTHubMessage_CreateFromByteArray, const unsigned char*, byteArray, size_t, size);
+
+/**
+* @brief   Creates a new IoT hub message from a null terminated string.  The
+*          type of the message will be set to @c IOTHUBMESSAGE_STRING.
+*
+* @param   source  The null terminated string from which the message is to be
+*                  created.
+*
+* @return  A valid @c IOTHUB_MESSAGE_HANDLE if the message was successfully
+*          created or @c NULL in case an error occurs.
+*/
+MOCKABLE_FUNCTION(, IOTHUB_MESSAGE_HANDLE, IoTHubMessage_CreateFromString, const char*, source);
+
+/**
+* @brief   Creates a new IoT hub message with the content identical to that
+*          of the @p iotHubMessageHandle parameter.
+*
+* @param   iotHubMessageHandle Handle to the message that is to be cloned.
+*
+* @return  A valid @c IOTHUB_MESSAGE_HANDLE if the message was successfully
+*          cloned or @c NULL in case an error occurs.
+*/
+MOCKABLE_FUNCTION(, IOTHUB_MESSAGE_HANDLE, IoTHubMessage_Clone, IOTHUB_MESSAGE_HANDLE, iotHubMessageHandle);
+
+/**
+* @brief   Fetches a pointer and size for the data associated with the IoT
+*          hub message handle. If the content type of the message is not
+*          @c IOTHUBMESSAGE_BYTEARRAY then the function returns
+*          @c IOTHUB_MESSAGE_INVALID_ARG.
+*
+* @param   iotHubMessageHandle Handle to the message.
+* @param   buffer              Pointer to the memory location where the
+*                              pointer to the buffer will be written.
+* @param   size                The size of the buffer will be written to
+*                              this address.
+*
+* @return  Returns IOTHUB_MESSAGE_OK if the byte array was fetched successfully
+*          or an error code otherwise.
+*/
+MOCKABLE_FUNCTION(, IOTHUB_MESSAGE_RESULT, IoTHubMessage_GetByteArray, IOTHUB_MESSAGE_HANDLE, iotHubMessageHandle, const unsigned char**, buffer, size_t*, size);
+
+/**
+* @brief   Returns the null terminated string stored in the message.
+*          If the content type of the message is not @c IOTHUBMESSAGE_STRING
+*          then the function returns @c NULL. No new memory is allocated,
+*          the caller is not responsible for freeing the memory. The memory
+*          is valid until IoTHubMessage_Destroy is called on the message.
+*
+* @param   iotHubMessageHandle Handle to the message.
+*
+* @return  @c NULL if an error occurs or a pointer to the stored null
+*          terminated string otherwise.
+*/
+MOCKABLE_FUNCTION(, const char*, IoTHubMessage_GetString, IOTHUB_MESSAGE_HANDLE, iotHubMessageHandle);
+
+/**
+* @brief   Returns the content type of the message given by parameter
+*          @c iotHubMessageHandle.
+*
+* @param   iotHubMessageHandle Handle to the message.
+*
+* @remarks This function retrieves the standardized type of the payload, which indicates if @c iotHubMessageHandle was created using a String or a Byte Array.
+*
+* @return  An @c IOTHUBMESSAGE_CONTENT_TYPE value.
+*/
+MOCKABLE_FUNCTION(, IOTHUBMESSAGE_CONTENT_TYPE, IoTHubMessage_GetContentType, IOTHUB_MESSAGE_HANDLE, iotHubMessageHandle);
+
+/**
+* @brief   Sets the content-type of the message payload, as per supported values on RFC 2046.
+*
+* @param   iotHubMessageHandle Handle to the message.
+*
+* @param   contentType String defining the type of the payload (e.g., text/plain).
+*
+* @return  An @c IOTHUB_MESSAGE_RESULT value.
+*/
+MOCKABLE_FUNCTION(, IOTHUB_MESSAGE_RESULT, IoTHubMessage_SetContentTypeSystemProperty, IOTHUB_MESSAGE_HANDLE, iotHubMessageHandle, const char*, contentType);
+
+/**
+* @brief   Returns the content-type of the message payload, if defined. No new memory is allocated,
+*          the caller is not responsible for freeing the memory.  The memory
+*          is valid until IoTHubMessage_Destroy is called on the message.
+*
+* @param   iotHubMessageHandle Handle to the message.
+*
+* @return  A string with the content-type value if defined (or NULL otherwise).
+*/
+MOCKABLE_FUNCTION(, const char*, IoTHubMessage_GetContentTypeSystemProperty, IOTHUB_MESSAGE_HANDLE, iotHubMessageHandle);
+
+/**
+* @brief   Sets the content-encoding of the message payload, as per supported values on RFC 2616.
+*
+* @param   iotHubMessageHandle Handle to the message.
+*
+* @param   contentEncoding String defining the encoding of the payload (e.g., utf-8).
+*
+* @return  An @c IOTHUB_MESSAGE_RESULT value.
+*/
+MOCKABLE_FUNCTION(, IOTHUB_MESSAGE_RESULT, IoTHubMessage_SetContentEncodingSystemProperty, IOTHUB_MESSAGE_HANDLE, iotHubMessageHandle, const char*, contentEncoding);
+
+/**
+* @brief   Returns the content-encoding of the message payload, if defined. No new memory is allocated,
+*          the caller is not responsible for freeing the memory. The memory
+*          is valid until IoTHubMessage_Destroy is called on the message.
+*
+* @param   iotHubMessageHandle Handle to the message.
+*
+* @return  A string with the content-encoding value if defined (or NULL otherwise).
+*/
+MOCKABLE_FUNCTION(, const char*, IoTHubMessage_GetContentEncodingSystemProperty, IOTHUB_MESSAGE_HANDLE, iotHubMessageHandle);
+
+/**
+** DEPRECATED: Use IoTHubMessage_SetProperty and IoTHubMessage_GetProperty instead. **
+* @brief   Gets a handle to the message's properties map.
+*          Note that when sending messages via the HTTP transport, the key names in the map must not contain spaces.
+*
+* @param   iotHubMessageHandle Handle to the message.
+*
+* @return  A @c MAP_HANDLE pointing to the properties map for this message.
+*/
+MOCKABLE_FUNCTION(, MAP_HANDLE, IoTHubMessage_Properties, IOTHUB_MESSAGE_HANDLE, iotHubMessageHandle);
+
+/**
+* @brief   Sets a property on a Iothub Message.
+*
+* @param   iotHubMessageHandle Handle to the message.
+*
+* @param   key name of the property to set.  Note that when sending messages via the HTTP transport, this value must not contain spaces.
+*
+* @param   value of the property to set.
+*
+* @return  An @c IOTHUB_MESSAGE_RESULT value indicating the result of setting the property.
+*/
+MOCKABLE_FUNCTION(, IOTHUB_MESSAGE_RESULT, IoTHubMessage_SetProperty, IOTHUB_MESSAGE_HANDLE, iotHubMessageHandle, const char*, key, const char*, value);
+
+/**
+* @brief   Gets a IotHub Message's properties item. No new memory is allocated,
+*          the caller is not responsible for freeing the memory. The memory
+*          is valid until IoTHubMessage_Destroy is called on the message.
+*
+* @param   iotHubMessageHandle Handle to the message.
+*
+* @param   key name of the property to retrieve.
+*
+* @return  A string with the property's value, or NULL if it does not exist in the properties list.
+*/
+MOCKABLE_FUNCTION(, const char*, IoTHubMessage_GetProperty, IOTHUB_MESSAGE_HANDLE, iotHubMessageHandle, const char*, key);
+
+/**
+* @brief   Gets the MessageId from the IOTHUB_MESSAGE_HANDLE. No new memory is allocated,
+*          the caller is not responsible for freeing the memory. The memory
+*          is valid until IoTHubMessage_Destroy is called on the message.
+*
+* @param   iotHubMessageHandle Handle to the message.
+*
+* @return  A const char* pointing to the Message Id.
+*/
+MOCKABLE_FUNCTION(, const char*, IoTHubMessage_GetMessageId, IOTHUB_MESSAGE_HANDLE, iotHubMessageHandle);
+
+/**
+* @brief   Sets the MessageId for the IOTHUB_MESSAGE_HANDLE.
+*
+* @param   iotHubMessageHandle Handle to the message.
+* @param   messageId Pointer to the memory location of the messageId
+*
+* @return  Returns IOTHUB_MESSAGE_OK if the messageId was set successfully
+*          or an error code otherwise.
+*/
+MOCKABLE_FUNCTION(, IOTHUB_MESSAGE_RESULT, IoTHubMessage_SetMessageId, IOTHUB_MESSAGE_HANDLE, iotHubMessageHandle, const char*, messageId);
+
+/**
+* @brief   Gets the CorrelationId from the IOTHUB_MESSAGE_HANDLE. No new memory is allocated,
+*          the caller is not responsible for freeing the memory. The memory
+*          is valid until IoTHubMessage_Destroy is called on the message.
+*
+* @param   iotHubMessageHandle Handle to the message.
+*
+* @return  A const char* pointing to the Correlation Id.
+*/
+MOCKABLE_FUNCTION(, const char*, IoTHubMessage_GetCorrelationId, IOTHUB_MESSAGE_HANDLE, iotHubMessageHandle);
+
+/**
+* @brief   Sets the CorrelationId for the IOTHUB_MESSAGE_HANDLE.
+*
+* @param   iotHubMessageHandle Handle to the message.
+* @param   correlationId Pointer to the memory location of the messageId
+*
+* @return  Returns IOTHUB_MESSAGE_OK if the messageId was set successfully
+*          or an error code otherwise.
+*/
+MOCKABLE_FUNCTION(, IOTHUB_MESSAGE_RESULT, IoTHubMessage_SetCorrelationId, IOTHUB_MESSAGE_HANDLE, iotHubMessageHandle, const char*, correlationId);
+
+/**
+* @brief   Gets the DiagnosticData from the IOTHUB_MESSAGE_HANDLE. CAUTION: SDK user should not call it directly, it is for internal use only.
+*
+* @param   iotHubMessageHandle Handle to the message.
+*
+* @return  A const IOTHUB_MESSAGE_DIAGNOSTIC_PROPERTY_DATA* pointing to the diagnostic property data.
+*/
+MOCKABLE_FUNCTION(, const IOTHUB_MESSAGE_DIAGNOSTIC_PROPERTY_DATA*, IoTHubMessage_GetDiagnosticPropertyData, IOTHUB_MESSAGE_HANDLE, iotHubMessageHandle);
+
+/**
+* @brief   Sets the DiagnosticData for the IOTHUB_MESSAGE_HANDLE. CAUTION: SDK user should not call it directly, it is for internal use only.
+*
+* @param   iotHubMessageHandle Handle to the message.
+* @param   diagnosticData Pointer to the memory location of the diagnosticData
+*
+* @return  Returns IOTHUB_MESSAGE_OK if the DiagnosticData was set successfully
+*          or an error code otherwise.
+*/
+MOCKABLE_FUNCTION(, IOTHUB_MESSAGE_RESULT, IoTHubMessage_SetDiagnosticPropertyData, IOTHUB_MESSAGE_HANDLE, iotHubMessageHandle, const IOTHUB_MESSAGE_DIAGNOSTIC_PROPERTY_DATA*, diagnosticData);
+
+/**
+* @brief   Gets the output name from the IOTHUB_MESSAGE_HANDLE. No new memory is allocated,
+*          the caller is not responsible for freeing the memory. The memory
+*          is valid until IoTHubMessage_Destroy is called on the message.
+*
+* @param   iotHubMessageHandle Handle to the message.
+*
+* @return  A const char* pointing to the Output Id.
+*/
+MOCKABLE_FUNCTION(, const char*, IoTHubMessage_GetOutputName, IOTHUB_MESSAGE_HANDLE, iotHubMessageHandle);
+
+
+/**
+* @brief   Sets output for named queues. CAUTION: SDK user should not call it directly, it is for internal use only.
+*
+* @param   iotHubMessageHandle Handle to the message.
+* @param   outputName Pointer to the queue to output message to
+*
+* @return  Returns IOTHUB_MESSAGE_OK if the DiagnosticData was set successfully
+*          or an error code otherwise.
+*/
+MOCKABLE_FUNCTION(, IOTHUB_MESSAGE_RESULT, IoTHubMessage_SetOutputName, IOTHUB_MESSAGE_HANDLE, iotHubMessageHandle, const char*, outputName);
+
+
+/**
+* @brief   Gets the input name from the IOTHUB_MESSAGE_HANDLE. No new memory is allocated,
+*          the caller is not responsible for freeing the memory. The memory
+*          is valid until IoTHubMessage_Destroy is called on the message.
+*
+* @param   iotHubMessageHandle Handle to the message.
+*
+* @return  A const char* pointing to the Input Id.
+*/
+MOCKABLE_FUNCTION(, const char*, IoTHubMessage_GetInputName, IOTHUB_MESSAGE_HANDLE, iotHubMessageHandle);
+
+/**
+* @brief   Sets input for named queues. CAUTION: SDK user should not call it directly, it is for internal use only.
+*
+* @param   iotHubMessageHandle Handle to the message.
+* @param   inputName Pointer to the queue to input message to
+*
+* @return  Returns IOTHUB_MESSAGE_OK if the DiagnosticData was set successfully
+*          or an error code otherwise.
+*/
+MOCKABLE_FUNCTION(, IOTHUB_MESSAGE_RESULT, IoTHubMessage_SetInputName, IOTHUB_MESSAGE_HANDLE, iotHubMessageHandle, const char*, inputName);
+
+/**
+* @brief   Gets the module name from the IOTHUB_MESSAGE_HANDLE. No new memory is allocated,
+*          the caller is not responsible for freeing the memory. The memory
+*          is valid until IoTHubMessage_Destroy is called on the message.
+*
+* @param   iotHubMessageHandle Handle to the message.
+*
+* @return  A const char* pointing to the connection module Id.
+*/
+MOCKABLE_FUNCTION(, const char*, IoTHubMessage_GetConnectionModuleId, IOTHUB_MESSAGE_HANDLE, iotHubMessageHandle);
+
+/**
+* @brief   Sets connection module ID. CAUTION: SDK user should not call it directly, it is for internal use only.
+*
+* @param   iotHubMessageHandle Handle to the message.
+* @param   connectionModuleId Pointer to the module ID of connector
+*
+* @return  Returns IOTHUB_MESSAGE_OK if the DiagnosticData was set successfully
+*          or an error code otherwise.
+*/
+MOCKABLE_FUNCTION(, IOTHUB_MESSAGE_RESULT, IoTHubMessage_SetConnectionModuleId, IOTHUB_MESSAGE_HANDLE, iotHubMessageHandle, const char*, connectionModuleId);
+
+
+/**
+* @brief   Gets the connection device ID from the IOTHUB_MESSAGE_HANDLE. No new memory is allocated,
+*          the caller is not responsible for freeing the memory. The memory
+*          is valid until IoTHubMessage_Destroy is called on the message.
+*
+* @param   iotHubMessageHandle Handle to the message.
+*
+* @return  A const char* pointing to the connection device Id.
+*/
+MOCKABLE_FUNCTION(, const char*, IoTHubMessage_GetConnectionDeviceId, IOTHUB_MESSAGE_HANDLE, iotHubMessageHandle);
+
+/**
+* @brief   Sets connection device Id. CAUTION: SDK user should not call it directly, it is for internal use only.
+*
+* @param   iotHubMessageHandle Handle to the message.
+* @param   connectionDeviceId Pointer to the device ID of connector
+*
+* @return  Returns IOTHUB_MESSAGE_OK if the DiagnosticData was set successfully
+*          or an error code otherwise.
+*/
+MOCKABLE_FUNCTION(, IOTHUB_MESSAGE_RESULT, IoTHubMessage_SetConnectionDeviceId, IOTHUB_MESSAGE_HANDLE, iotHubMessageHandle, const char*, connectionDeviceId);
+
+
+/**
+* @brief   Marks a IoTHub message as a security message. CAUTION: Security messages are special messages not easily accessable by the user.
+*
+* @param   iotHubMessageHandle Handle to the message.
+*
+* @return  Returns IOTHUB_MESSAGE_OK if the Security Message was set successfully
+*          or an error code otherwise.
+*/
+MOCKABLE_FUNCTION(, IOTHUB_MESSAGE_RESULT, IoTHubMessage_SetAsSecurityMessage, IOTHUB_MESSAGE_HANDLE, iotHubMessageHandle);
+
+/**
+* @brief   returns if this message is a IoTHub security message or not
+*
+* @param   iotHubMessageHandle Handle to the message.
+*
+* @return  Returns true if the Message is a security message false otherwise.
+*/
+MOCKABLE_FUNCTION(, bool, IoTHubMessage_IsSecurityMessage, IOTHUB_MESSAGE_HANDLE, iotHubMessageHandle);
+
+/**
+* @brief   Frees all resources associated with the given message handle.
+*
+* @param   iotHubMessageHandle Handle to the message.
+*/
+MOCKABLE_FUNCTION(, void, IoTHubMessage_Destroy, IOTHUB_MESSAGE_HANDLE, iotHubMessageHandle);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* IOTHUB_MESSAGE_H */
Index: azure_iot_hub_f767zi/trunk/azure_iot_sdk/iothub_client/inc/iothub_transport_ll.h
===================================================================
--- azure_iot_hub_f767zi/trunk/azure_iot_sdk/iothub_client/inc/iothub_transport_ll.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/azure_iot_sdk/iothub_client/inc/iothub_transport_ll.h	(revision 457)
@@ -0,0 +1,41 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+#ifndef IOTHUB_TRANSPORT_LL_H
+#define IOTHUB_TRANSPORT_LL_H
+
+#ifdef __cplusplus
+#include <cstddef>
+#include <cstdint>
+extern "C"
+{
+#else
+#include <stddef.h>
+#include <stdint.h>
+#endif
+
+#include "umock_c/umock_c_prod.h"
+
+typedef void* TRANSPORT_LL_HANDLE;
+typedef void* IOTHUB_DEVICE_HANDLE;
+
+struct TRANSPORT_HANDLE_DATA_TAG;
+typedef struct TRANSPORT_HANDLE_DATA_TAG* TRANSPORT_HANDLE;
+
+typedef void* METHOD_HANDLE;
+
+struct TRANSPORT_PROVIDER_TAG;
+typedef struct TRANSPORT_PROVIDER_TAG TRANSPORT_PROVIDER;
+
+typedef const TRANSPORT_PROVIDER*(*IOTHUB_CLIENT_TRANSPORT_PROVIDER)(void);
+
+MOCKABLE_FUNCTION(, TRANSPORT_HANDLE, IoTHubTransport_Create, IOTHUB_CLIENT_TRANSPORT_PROVIDER, protocol, const char*, iotHubName, const char*, iotHubSuffix);
+MOCKABLE_FUNCTION(, void, IoTHubTransport_Destroy, TRANSPORT_HANDLE, transportHandle);
+MOCKABLE_FUNCTION(, TRANSPORT_LL_HANDLE, IoTHubTransport_GetLLTransport, TRANSPORT_HANDLE, transportHandle);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* IOTHUB_TRANSPORT_LL_H */
+
Index: azure_iot_hub_f767zi/trunk/azure_iot_sdk/iothub_client/inc/iothubtransporthttp.h
===================================================================
--- azure_iot_hub_f767zi/trunk/azure_iot_sdk/iothub_client/inc/iothubtransporthttp.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/azure_iot_sdk/iothub_client/inc/iothubtransporthttp.h	(revision 457)
@@ -0,0 +1,20 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+#ifndef IOTHUBTRANSPORTHTTP_H
+#define IOTHUBTRANSPORTHTTP_H
+
+#include "iothub_transport_ll.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+	extern const TRANSPORT_PROVIDER* HTTP_Protocol(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /*IOTHUBTRANSPORTHTTP_H*/
Index: azure_iot_hub_f767zi/trunk/azure_iot_sdk/iothub_client/inc/iothubtransportmqtt.h
===================================================================
--- azure_iot_hub_f767zi/trunk/azure_iot_sdk/iothub_client/inc/iothubtransportmqtt.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/azure_iot_sdk/iothub_client/inc/iothubtransportmqtt.h	(revision 457)
@@ -0,0 +1,19 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+#ifndef IOTHUBTRANSPORTMQTT_H
+#define IOTHUBTRANSPORTMQTT_H
+
+#include "iothub_transport_ll.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+    extern const TRANSPORT_PROVIDER* MQTT_Protocol(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /*IOTHUBTRANSPORTMQTT_H*/
Index: azure_iot_hub_f767zi/trunk/azure_iot_sdk/iothub_client/inc/iothubtransportmqtt_websockets.h
===================================================================
--- azure_iot_hub_f767zi/trunk/azure_iot_sdk/iothub_client/inc/iothubtransportmqtt_websockets.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/azure_iot_sdk/iothub_client/inc/iothubtransportmqtt_websockets.h	(revision 457)
@@ -0,0 +1,20 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+#ifndef IOTHUBTRANSPORTMQTT_WEBSOCKETS_H
+#define IOTHUBTRANSPORTMQTT_WEBSOCKETS_H
+
+#include "iothub_transport_ll.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+    extern const TRANSPORT_PROVIDER* MQTT_WebSocket_Protocol(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /*IOTHUBTRANSPORTMQTT_WEBSOCKETS_H*/
Index: azure_iot_hub_f767zi/trunk/azure_iot_sdk/iothub_client/src/blob.c
===================================================================
--- azure_iot_hub_f767zi/trunk/azure_iot_sdk/iothub_client/src/blob.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/azure_iot_sdk/iothub_client/src/blob.c	(revision 457)
@@ -0,0 +1,387 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+#include <stdlib.h>
+#include <stdint.h>
+
+#include "azure_c_shared_utility/gballoc.h"
+#include "internal/blob.h"
+#include "internal/iothub_client_ll_uploadtoblob.h"
+
+#include "azure_c_shared_utility/httpapiex.h"
+#include "azure_c_shared_utility/xlogging.h"
+#include "azure_c_shared_utility/azure_base64.h"
+#include "azure_c_shared_utility/shared_util_options.h"
+
+BLOB_RESULT Blob_UploadBlock(
+        HTTPAPIEX_HANDLE httpApiExHandle,
+        const char* relativePath,
+        BUFFER_HANDLE requestContent,
+        unsigned int blockID,
+        STRING_HANDLE blockIDList,
+        unsigned int* httpStatus,
+        BUFFER_HANDLE httpResponse)
+{
+    BLOB_RESULT result;
+
+    if (requestContent == NULL ||
+        blockIDList == NULL ||
+        relativePath == NULL ||
+        httpApiExHandle == NULL ||
+        httpStatus == NULL ||
+        httpResponse == NULL)
+    {
+        LogError("invalid argument detected requestContent=%p blockIDList=%p relativePath=%p httpApiExHandle=%p httpStatus=%p httpResponse=%p", requestContent, blockIDList, relativePath, httpApiExHandle, httpStatus, httpResponse);
+        result = BLOB_ERROR;
+    }
+    else if (blockID > 49999) /*outside the expected range of 000000... 049999*/
+    {
+        LogError("block ID too large");
+        result = BLOB_ERROR;
+    }
+    else
+    {
+        char temp[7]; /*this will contain 000000... 049999*/
+        if (sprintf(temp, "%6u", (unsigned int)blockID) != 6) /*produces 000000... 049999*/
+        {
+            /*Codes_SRS_BLOB_02_033: [ If any previous operation that doesn't have an explicit failure description fails then Blob_UploadMultipleBlocksFromSasUri shall fail and return BLOB_ERROR ]*/
+            LogError("failed to sprintf");
+            result = BLOB_ERROR;
+        }
+        else
+        {
+            STRING_HANDLE blockIdString = Azure_Base64_Encode_Bytes((const unsigned char*)temp, 6);
+            if (blockIdString == NULL)
+            {
+                /*Codes_SRS_BLOB_02_033: [ If any previous operation that doesn't have an explicit failure description fails then Blob_UploadMultipleBlocksFromSasUri shall fail and return BLOB_ERROR ]*/
+                LogError("unable to Azure_Base64_Encode_Bytes");
+                result = BLOB_ERROR;
+            }
+            else
+            {
+                /*add the blockId base64 encoded to the XML*/
+                if (!(
+                    (STRING_concat(blockIDList, "<Latest>") == 0) &&
+                    (STRING_concat_with_STRING(blockIDList, blockIdString) == 0) &&
+                    (STRING_concat(blockIDList, "</Latest>") == 0)
+                    ))
+                {
+                    /*Codes_SRS_BLOB_02_033: [ If any previous operation that doesn't have an explicit failure description fails then Blob_UploadMultipleBlocksFromSasUri shall fail and return BLOB_ERROR ]*/
+                    LogError("unable to STRING_concat");
+                    result = BLOB_ERROR;
+                }
+                else
+                {
+                    /*Codes_SRS_BLOB_02_022: [ Blob_UploadMultipleBlocksFromSasUri shall construct a new relativePath from following string: base relativePath + "&comp=block&blockid=BASE64 encoded string of blockId" ]*/
+                    STRING_HANDLE newRelativePath = STRING_construct(relativePath);
+                    if (newRelativePath == NULL)
+                    {
+                        /*Codes_SRS_BLOB_02_033: [ If any previous operation that doesn't have an explicit failure description fails then Blob_UploadMultipleBlocksFromSasUri shall fail and return BLOB_ERROR ]*/
+                        LogError("unable to STRING_construct");
+                        result = BLOB_ERROR;
+                    }
+                    else
+                    {
+                        if (!(
+                            (STRING_concat(newRelativePath, "&comp=block&blockid=") == 0) &&
+                            (STRING_concat_with_STRING(newRelativePath, blockIdString) == 0)
+                            ))
+                        {
+                            /*Codes_SRS_BLOB_02_033: [ If any previous operation that doesn't have an explicit failure description fails then Blob_UploadMultipleBlocksFromSasUri shall fail and return BLOB_ERROR ]*/
+                            LogError("unable to STRING concatenate");
+                            result = BLOB_ERROR;
+                        }
+                        else
+                        {
+                            /*Codes_SRS_BLOB_02_024: [ Blob_UploadMultipleBlocksFromSasUri shall call HTTPAPIEX_ExecuteRequest with a PUT operation, passing httpStatus and httpResponse. ]*/
+                            if (HTTPAPIEX_ExecuteRequest(
+                                httpApiExHandle,
+                                HTTPAPI_REQUEST_PUT,
+                                STRING_c_str(newRelativePath),
+                                NULL,
+                                requestContent,
+                                httpStatus,
+                                NULL,
+                                httpResponse) != HTTPAPIEX_OK
+                                )
+                            {
+                                /*Codes_SRS_BLOB_02_025: [ If HTTPAPIEX_ExecuteRequest fails then Blob_UploadMultipleBlocksFromSasUri shall fail and return BLOB_HTTP_ERROR. ]*/
+                                LogError("unable to HTTPAPIEX_ExecuteRequest");
+                                result = BLOB_HTTP_ERROR;
+                            }
+                            else if (*httpStatus >= 300)
+                            {
+                                /*Codes_SRS_BLOB_02_026: [ Otherwise, if HTTP response code is >=300 then Blob_UploadMultipleBlocksFromSasUri shall succeed and return BLOB_OK. ]*/
+                                LogError("HTTP status from storage does not indicate success (%d)", (int)*httpStatus);
+                                result = BLOB_OK;
+                            }
+                            else
+                            {
+                                /*Codes_SRS_BLOB_02_027: [ Otherwise Blob_UploadMultipleBlocksFromSasUri shall continue execution. ]*/
+                                result = BLOB_OK;
+                            }
+                        }
+                        STRING_delete(newRelativePath);
+                    }
+                }
+                STRING_delete(blockIdString);
+            }
+        }
+    }
+    return result;
+}
+
+BLOB_RESULT Blob_UploadMultipleBlocksFromSasUri(const char* SASURI, IOTHUB_CLIENT_FILE_UPLOAD_GET_DATA_CALLBACK_EX getDataCallbackEx, void* context, unsigned int* httpStatus, BUFFER_HANDLE httpResponse, const char* certificates, HTTP_PROXY_OPTIONS *proxyOptions)
+{
+    BLOB_RESULT result;
+    /*Codes_SRS_BLOB_02_001: [ If SASURI is NULL then Blob_UploadMultipleBlocksFromSasUri shall fail and return BLOB_INVALID_ARG. ]*/
+    if (SASURI == NULL)
+    {
+        LogError("parameter SASURI is NULL");
+        result = BLOB_INVALID_ARG;
+    }
+    else
+    {
+        /*Codes_SRS_BLOB_02_002: [ If getDataCallbackEx is NULL then Blob_UploadMultipleBlocksFromSasUri shall fail and return BLOB_INVALID_ARG. ]*/
+        if (getDataCallbackEx == NULL)
+        {
+            LogError("IOTHUB_CLIENT_FILE_UPLOAD_GET_DATA_CALLBACK_EX getDataCallbackEx is NULL");
+            result = BLOB_INVALID_ARG;
+        }
+        /*the below define avoid a "condition always false" on some compilers*/
+        else
+        {
+            /*Codes_SRS_BLOB_02_017: [ Blob_UploadMultipleBlocksFromSasUri shall copy from SASURI the hostname to a new const char* ]*/
+            /*to find the hostname, the following logic is applied:*/
+            /*the hostname starts at the first character after "://"*/
+            /*the hostname ends at the first character before the next "/" after "://"*/
+            const char* hostnameBegin = strstr(SASURI, "://");
+            if (hostnameBegin == NULL)
+            {
+                /*Codes_SRS_BLOB_02_005: [ If the hostname cannot be determined, then Blob_UploadMultipleBlocksFromSasUri shall fail and return BLOB_INVALID_ARG. ]*/
+                LogError("hostname cannot be determined");
+                result = BLOB_INVALID_ARG;
+            }
+            else
+            {
+                hostnameBegin += 3; /*have to skip 3 characters which are "://"*/
+                const char* hostnameEnd = strchr(hostnameBegin, '/');
+                if (hostnameEnd == NULL)
+                {
+                    /*Codes_SRS_BLOB_02_005: [ If the hostname cannot be determined, then Blob_UploadMultipleBlocksFromSasUri shall fail and return BLOB_INVALID_ARG. ]*/
+                    LogError("hostname cannot be determined");
+                    result = BLOB_INVALID_ARG;
+                }
+                else
+                {
+                    size_t hostnameSize = hostnameEnd - hostnameBegin;
+                    char* hostname = (char*)malloc(hostnameSize + 1); /*+1 because of '\0' at the end*/
+                    if (hostname == NULL)
+                    {
+                        /*Codes_SRS_BLOB_02_016: [ If the hostname copy cannot be made then then Blob_UploadMultipleBlocksFromSasUri shall fail and return BLOB_ERROR ]*/
+                        LogError("oom - out of memory");
+                        result = BLOB_ERROR;
+                    }
+                    else
+                    {
+                        HTTPAPIEX_HANDLE httpApiExHandle;
+                        (void)memcpy(hostname, hostnameBegin, hostnameSize);
+                        hostname[hostnameSize] = '\0';
+
+                        /*Codes_SRS_BLOB_02_018: [ Blob_UploadMultipleBlocksFromSasUri shall create a new HTTPAPI_EX_HANDLE by calling HTTPAPIEX_Create passing the hostname. ]*/
+                        httpApiExHandle = HTTPAPIEX_Create(hostname);
+                        if (httpApiExHandle == NULL)
+                        {
+                            /*Codes_SRS_BLOB_02_007: [ If HTTPAPIEX_Create fails then Blob_UploadMultipleBlocksFromSasUri shall fail and return BLOB_ERROR. ]*/
+                            LogError("unable to create a HTTPAPIEX_HANDLE");
+                            result = BLOB_ERROR;
+                        }
+                        else
+                        {
+                            if ((certificates != NULL)&& (HTTPAPIEX_SetOption(httpApiExHandle, "TrustedCerts", certificates) == HTTPAPIEX_ERROR))
+                            {
+                                LogError("failure in setting trusted certificates");
+                                result = BLOB_ERROR;
+                            }
+                            else if ((proxyOptions != NULL && proxyOptions->host_address != NULL) && HTTPAPIEX_SetOption(httpApiExHandle, OPTION_HTTP_PROXY, proxyOptions) == HTTPAPIEX_ERROR)
+                            {
+                                LogError("failure in setting proxy options");
+                                result = BLOB_ERROR;
+                            }
+                            else
+                            {
+                                /*Codes_SRS_BLOB_02_019: [ Blob_UploadMultipleBlocksFromSasUri shall compute the base relative path of the request from the SASURI parameter. ]*/
+                                const char* relativePath = hostnameEnd; /*this is where the relative path begins in the SasUri*/
+
+                                /*Codes_SRS_BLOB_02_028: [ Blob_UploadMultipleBlocksFromSasUri shall construct an XML string with the following content: ]*/
+                                STRING_HANDLE blockIDList = STRING_construct("<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<BlockList>"); /*the XML "build as we go"*/
+                                if (blockIDList == NULL)
+                                {
+                                    /*Codes_SRS_BLOB_02_033: [ If any previous operation that doesn't have an explicit failure description fails then Blob_UploadMultipleBlocksFromSasUri shall fail and return BLOB_ERROR ]*/
+                                    LogError("failed to STRING_construct");
+                                    result = BLOB_HTTP_ERROR;
+                                }
+                                else
+                                {
+                                    /*Codes_SRS_BLOB_02_021: [ For every block returned by `getDataCallbackEx` the following operations shall happen: ]*/
+                                    unsigned int blockID = 0; /* incremented for each new block */
+                                    unsigned int isError = 0; /* set to 1 if a block upload fails or if getDataCallbackEx returns incorrect blocks to upload */
+                                    unsigned int uploadOneMoreBlock = 1; /* set to 1 while getDataCallbackEx returns correct blocks to upload */
+                                    unsigned char const * source; /* data set by getDataCallbackEx */
+                                    size_t size; /* source size set by getDataCallbackEx */
+                                    IOTHUB_CLIENT_FILE_UPLOAD_GET_DATA_RESULT getDataReturnValue;
+
+                                    do
+                                    {
+                                        getDataReturnValue = getDataCallbackEx(FILE_UPLOAD_OK, &source, &size, context);
+                                        if (getDataReturnValue == IOTHUB_CLIENT_FILE_UPLOAD_GET_DATA_ABORT)
+                                        {
+                                            /*Codes_SRS_BLOB_99_004: [ If `getDataCallbackEx` returns `IOTHUB_CLIENT_FILE_UPLOAD_GET_DATA_RESULT_ABORT`, then `Blob_UploadMultipleBlocksFromSasUri` shall exit the loop and return `BLOB_ABORTED`. ]*/
+                                            LogInfo("Upload to blob has been aborted by the user");
+                                            uploadOneMoreBlock = 0;
+                                            result = BLOB_ABORTED;
+                                        }
+                                        else if (source == NULL || size == 0)
+                                        {
+                                            /*Codes_SRS_BLOB_99_002: [ If the size of the block returned by `getDataCallbackEx` is 0 or if the data is NULL, then `Blob_UploadMultipleBlocksFromSasUri` shall exit the loop. ]*/
+                                            uploadOneMoreBlock = 0;
+                                            result = BLOB_OK;
+                                        }
+                                        else
+                                        {
+                                            if (size > BLOCK_SIZE)
+                                            {
+                                                /*Codes_SRS_BLOB_99_001: [ If the size of the block returned by `getDataCallbackEx` is bigger than 4MB, then `Blob_UploadMultipleBlocksFromSasUri` shall fail and return `BLOB_INVALID_ARG`. ]*/
+                                                LogError("tried to upload block of size %lu, max allowed size is %d", (unsigned long)size, BLOCK_SIZE);
+                                                result = BLOB_INVALID_ARG;
+                                                isError = 1;
+                                            }
+                                            else if (blockID >= MAX_BLOCK_COUNT)
+                                            {
+                                                /*Codes_SRS_BLOB_99_003: [ If `getDataCallbackEx` returns more than 50000 blocks, then `Blob_UploadMultipleBlocksFromSasUri` shall fail and return `BLOB_INVALID_ARG`. ]*/
+                                                LogError("unable to upload more than %lu blocks in one blob", (unsigned long)MAX_BLOCK_COUNT);
+                                                result = BLOB_INVALID_ARG;
+                                                isError = 1;
+                                            }
+                                            else
+                                            {
+                                                /*Codes_SRS_BLOB_02_023: [ Blob_UploadMultipleBlocksFromSasUri shall create a BUFFER_HANDLE from source and size parameters. ]*/
+                                                BUFFER_HANDLE requestContent = BUFFER_create(source, size);
+                                                if (requestContent == NULL)
+                                                {
+                                                    /*Codes_SRS_BLOB_02_033: [ If any previous operation that doesn't have an explicit failure description fails then Blob_UploadMultipleBlocksFromSasUri shall fail and return BLOB_ERROR ]*/
+                                                    LogError("unable to BUFFER_create");
+                                                    result = BLOB_ERROR;
+                                                    isError = 1;
+                                                }
+                                                else
+                                                {
+                                                    result = Blob_UploadBlock(
+                                                            httpApiExHandle,
+                                                            relativePath,
+                                                            requestContent,
+                                                            blockID,
+                                                            blockIDList,
+                                                            httpStatus,
+                                                            httpResponse);
+
+                                                    BUFFER_delete(requestContent);
+                                                }
+
+                                                /*Codes_SRS_BLOB_02_026: [ Otherwise, if HTTP response code is >=300 then Blob_UploadMultipleBlocksFromSasUri shall succeed and return BLOB_OK. ]*/
+                                                if (result != BLOB_OK || *httpStatus >= 300)
+                                                {
+                                                    LogError("unable to Blob_UploadBlock. Returned value=%d, httpStatus=%u", result, (unsigned int)*httpStatus);
+                                                    isError = 1;
+                                                }
+                                            }
+                                            blockID++;
+                                        }
+                                    }
+                                    while(uploadOneMoreBlock && !isError);
+
+                                    if (isError || result != BLOB_OK)
+                                    {
+                                        /*do nothing, it will be reported "as is"*/
+                                    }
+                                    else
+                                    {
+                                        /*complete the XML*/
+                                        if (STRING_concat(blockIDList, "</BlockList>") != 0)
+                                        {
+                                            /*Codes_SRS_BLOB_02_033: [ If any previous operation that doesn't have an explicit failure description fails then Blob_UploadMultipleBlocksFromSasUri shall fail and return BLOB_ERROR ]*/
+                                            LogError("failed to STRING_concat");
+                                            result = BLOB_ERROR;
+                                        }
+                                        else
+                                        {
+                                            /*Codes_SRS_BLOB_02_029: [Blob_UploadMultipleBlocksFromSasUri shall construct a new relativePath from following string : base relativePath + "&comp=blocklist"]*/
+                                            STRING_HANDLE newRelativePath = STRING_construct(relativePath);
+                                            if (newRelativePath == NULL)
+                                            {
+                                                /*Codes_SRS_BLOB_02_033: [ If any previous operation that doesn't have an explicit failure description fails then Blob_UploadMultipleBlocksFromSasUri shall fail and return BLOB_ERROR ]*/
+                                                LogError("failed to STRING_construct");
+                                                result = BLOB_ERROR;
+                                            }
+                                            else
+                                            {
+                                                if (STRING_concat(newRelativePath, "&comp=blocklist") != 0)
+                                                {
+                                                    /*Codes_SRS_BLOB_02_033: [ If any previous operation that doesn't have an explicit failure description fails then Blob_UploadMultipleBlocksFromSasUri shall fail and return BLOB_ERROR ]*/
+                                                    LogError("failed to STRING_concat");
+                                                    result = BLOB_ERROR;
+                                                }
+                                                else
+                                                {
+                                                    /*Codes_SRS_BLOB_02_030: [ Blob_UploadMultipleBlocksFromSasUri shall call HTTPAPIEX_ExecuteRequest with a PUT operation, passing the new relativePath, httpStatus and httpResponse and the XML string as content. ]*/
+                                                    const char* s = STRING_c_str(blockIDList);
+                                                    BUFFER_HANDLE blockIDListAsBuffer = BUFFER_create((const unsigned char*)s, strlen(s));
+                                                    if (blockIDListAsBuffer == NULL)
+                                                    {
+                                                        /*Codes_SRS_BLOB_02_033: [ If any previous operation that doesn't have an explicit failure description fails then Blob_UploadMultipleBlocksFromSasUri shall fail and return BLOB_ERROR ]*/
+                                                        LogError("failed to BUFFER_create");
+                                                        result = BLOB_ERROR;
+                                                    }
+                                                    else
+                                                    {
+                                                        if (HTTPAPIEX_ExecuteRequest(
+                                                            httpApiExHandle,
+                                                            HTTPAPI_REQUEST_PUT,
+                                                            STRING_c_str(newRelativePath),
+                                                            NULL,
+                                                            blockIDListAsBuffer,
+                                                            httpStatus,
+                                                            NULL,
+                                                            httpResponse
+                                                        ) != HTTPAPIEX_OK)
+                                                        {
+                                                            /*Codes_SRS_BLOB_02_031: [ If HTTPAPIEX_ExecuteRequest fails then Blob_UploadMultipleBlocksFromSasUri shall fail and return BLOB_HTTP_ERROR. ]*/
+                                                            LogError("unable to HTTPAPIEX_ExecuteRequest");
+                                                            result = BLOB_HTTP_ERROR;
+                                                        }
+                                                        else
+                                                        {
+                                                            /*Codes_SRS_BLOB_02_032: [ Otherwise, Blob_UploadMultipleBlocksFromSasUri shall succeed and return BLOB_OK. ]*/
+                                                            result = BLOB_OK;
+                                                        }
+                                                        BUFFER_delete(blockIDListAsBuffer);
+                                                    }
+                                                }
+                                                STRING_delete(newRelativePath);
+                                            }
+                                        }
+                                    }
+                                    STRING_delete(blockIDList);
+                                }
+
+                            }
+                            HTTPAPIEX_Destroy(httpApiExHandle);
+                        }
+                        free(hostname);
+                    }
+                }
+            }
+        }
+    }
+    return result;
+}
Index: azure_iot_hub_f767zi/trunk/azure_iot_sdk/iothub_client/src/iothub.c
===================================================================
--- azure_iot_hub_f767zi/trunk/azure_iot_sdk/iothub_client/src/iothub.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/azure_iot_sdk/iothub_client/src/iothub.c	(revision 457)
@@ -0,0 +1,29 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+#include <stdlib.h>
+
+#include "azure_c_shared_utility/platform.h"
+#include "azure_c_shared_utility/xlogging.h"
+#include "azure_macro_utils/macro_utils.h"
+#include "iothub.h"
+
+int IoTHub_Init(void)
+{
+    int result;
+    if (platform_init() != 0)
+    {
+        LogError("Platform initialization failed");
+        result = MU_FAILURE;
+    }
+    else
+    {
+        result = 0;
+    }
+    return result;
+}
+
+void IoTHub_Deinit(void)
+{
+    platform_deinit();
+}
Index: azure_iot_hub_f767zi/trunk/azure_iot_sdk/iothub_client/src/iothub_client.c
===================================================================
--- azure_iot_hub_f767zi/trunk/azure_iot_sdk/iothub_client/src/iothub_client.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/azure_iot_sdk/iothub_client/src/iothub_client.c	(revision 457)
@@ -0,0 +1,119 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+#include <stdlib.h>
+#include "umock_c/umock_c_prod.h"
+#include "azure_c_shared_utility/gballoc.h"
+
+#include "iothub_client_core.h"
+#include "iothub_client.h"
+
+IOTHUB_CLIENT_HANDLE IoTHubClient_CreateFromConnectionString(const char* connectionString, IOTHUB_CLIENT_TRANSPORT_PROVIDER protocol)
+{
+    return (IOTHUB_CLIENT_HANDLE)IoTHubClientCore_CreateFromConnectionString(connectionString, protocol);
+}
+
+IOTHUB_CLIENT_HANDLE IoTHubClient_Create(const IOTHUB_CLIENT_CONFIG* config)
+{
+    return (IOTHUB_CLIENT_HANDLE)IoTHubClientCore_Create(config);
+}
+
+IOTHUB_CLIENT_HANDLE IoTHubClient_CreateWithTransport(TRANSPORT_HANDLE transportHandle, const IOTHUB_CLIENT_CONFIG* config)
+{
+    return (IOTHUB_CLIENT_HANDLE)IoTHubClientCore_CreateWithTransport(transportHandle, config);
+}
+
+IOTHUB_CLIENT_HANDLE IoTHubClient_CreateFromDeviceAuth(const char* iothub_uri, const char* device_id, IOTHUB_CLIENT_TRANSPORT_PROVIDER protocol)
+{
+    return (IOTHUB_CLIENT_HANDLE)IoTHubClientCore_CreateFromDeviceAuth(iothub_uri, device_id, protocol);
+}
+
+void IoTHubClient_Destroy(IOTHUB_CLIENT_HANDLE iotHubClientHandle)
+{
+    IoTHubClientCore_Destroy((IOTHUB_CLIENT_CORE_HANDLE)iotHubClientHandle);
+}
+
+IOTHUB_CLIENT_RESULT IoTHubClient_SendEventAsync(IOTHUB_CLIENT_HANDLE iotHubClientHandle, IOTHUB_MESSAGE_HANDLE eventMessageHandle, IOTHUB_CLIENT_EVENT_CONFIRMATION_CALLBACK eventConfirmationCallback, void* userContextCallback)
+{
+    return IoTHubClientCore_SendEventAsync((IOTHUB_CLIENT_CORE_HANDLE)iotHubClientHandle, eventMessageHandle, eventConfirmationCallback, userContextCallback);
+}
+
+IOTHUB_CLIENT_RESULT IoTHubClient_GetSendStatus(IOTHUB_CLIENT_HANDLE iotHubClientHandle, IOTHUB_CLIENT_STATUS *iotHubClientStatus)
+{
+    return IoTHubClientCore_GetSendStatus((IOTHUB_CLIENT_CORE_HANDLE)iotHubClientHandle, iotHubClientStatus);
+}
+
+IOTHUB_CLIENT_RESULT IoTHubClient_SetMessageCallback(IOTHUB_CLIENT_HANDLE iotHubClientHandle, IOTHUB_CLIENT_MESSAGE_CALLBACK_ASYNC messageCallback, void* userContextCallback)
+{
+    return IoTHubClientCore_SetMessageCallback((IOTHUB_CLIENT_CORE_HANDLE)iotHubClientHandle, messageCallback, userContextCallback);
+}
+
+IOTHUB_CLIENT_RESULT IoTHubClient_SetConnectionStatusCallback(IOTHUB_CLIENT_HANDLE iotHubClientHandle, IOTHUB_CLIENT_CONNECTION_STATUS_CALLBACK connectionStatusCallback, void * userContextCallback)
+{
+    return IoTHubClientCore_SetConnectionStatusCallback((IOTHUB_CLIENT_CORE_HANDLE)iotHubClientHandle, connectionStatusCallback, userContextCallback);
+}
+
+IOTHUB_CLIENT_RESULT IoTHubClient_SetRetryPolicy(IOTHUB_CLIENT_HANDLE iotHubClientHandle, IOTHUB_CLIENT_RETRY_POLICY retryPolicy, size_t retryTimeoutLimitInSeconds)
+{
+    return IoTHubClientCore_SetRetryPolicy((IOTHUB_CLIENT_CORE_HANDLE)iotHubClientHandle, retryPolicy, retryTimeoutLimitInSeconds);
+}
+
+IOTHUB_CLIENT_RESULT IoTHubClient_GetRetryPolicy(IOTHUB_CLIENT_HANDLE iotHubClientHandle, IOTHUB_CLIENT_RETRY_POLICY* retryPolicy, size_t* retryTimeoutLimitInSeconds)
+{
+    return IoTHubClientCore_GetRetryPolicy((IOTHUB_CLIENT_CORE_HANDLE)iotHubClientHandle, retryPolicy, retryTimeoutLimitInSeconds);
+}
+
+IOTHUB_CLIENT_RESULT IoTHubClient_GetLastMessageReceiveTime(IOTHUB_CLIENT_HANDLE iotHubClientHandle, time_t* lastMessageReceiveTime)
+{
+    return IoTHubClientCore_GetLastMessageReceiveTime((IOTHUB_CLIENT_CORE_HANDLE)iotHubClientHandle, lastMessageReceiveTime);
+}
+
+IOTHUB_CLIENT_RESULT IoTHubClient_SetOption(IOTHUB_CLIENT_HANDLE iotHubClientHandle, const char* optionName, const void* value)
+{
+    return IoTHubClientCore_SetOption((IOTHUB_CLIENT_CORE_HANDLE)iotHubClientHandle, optionName, value);
+}
+
+IOTHUB_CLIENT_RESULT IoTHubClient_SetDeviceTwinCallback(IOTHUB_CLIENT_HANDLE iotHubClientHandle, IOTHUB_CLIENT_DEVICE_TWIN_CALLBACK deviceTwinCallback, void* userContextCallback)
+{
+    return IoTHubClientCore_SetDeviceTwinCallback((IOTHUB_CLIENT_CORE_HANDLE)iotHubClientHandle, deviceTwinCallback, userContextCallback);
+}
+
+IOTHUB_CLIENT_RESULT IoTHubClient_SendReportedState(IOTHUB_CLIENT_HANDLE iotHubClientHandle, const unsigned char* reportedState, size_t size, IOTHUB_CLIENT_REPORTED_STATE_CALLBACK reportedStateCallback, void* userContextCallback)
+{
+    return IoTHubClientCore_SendReportedState((IOTHUB_CLIENT_CORE_HANDLE)iotHubClientHandle, reportedState, size, reportedStateCallback, userContextCallback);
+}
+
+IOTHUB_CLIENT_RESULT IoTHubClient_SetDeviceMethodCallback(IOTHUB_CLIENT_HANDLE iotHubClientHandle, IOTHUB_CLIENT_DEVICE_METHOD_CALLBACK_ASYNC deviceMethodCallback, void* userContextCallback)
+{
+    return IoTHubClientCore_SetDeviceMethodCallback((IOTHUB_CLIENT_CORE_HANDLE)iotHubClientHandle, deviceMethodCallback, userContextCallback);
+}
+
+IOTHUB_CLIENT_RESULT IoTHubClient_SetDeviceMethodCallback_Ex(IOTHUB_CLIENT_HANDLE iotHubClientHandle, IOTHUB_CLIENT_INBOUND_DEVICE_METHOD_CALLBACK inboundDeviceMethodCallback, void* userContextCallback)
+{
+    return IoTHubClientCore_SetDeviceMethodCallback_Ex((IOTHUB_CLIENT_CORE_HANDLE)iotHubClientHandle, inboundDeviceMethodCallback, userContextCallback);
+}
+
+IOTHUB_CLIENT_RESULT IoTHubClient_DeviceMethodResponse(IOTHUB_CLIENT_HANDLE iotHubClientHandle, METHOD_HANDLE methodId, const unsigned char* response, size_t respSize, int statusCode)
+{
+    return IoTHubClientCore_DeviceMethodResponse((IOTHUB_CLIENT_CORE_HANDLE)iotHubClientHandle, methodId, response, respSize, statusCode);
+}
+
+#ifndef DONT_USE_UPLOADTOBLOB
+
+IOTHUB_CLIENT_RESULT IoTHubClient_UploadToBlobAsync(IOTHUB_CLIENT_HANDLE iotHubClientHandle, const char* destinationFileName, const unsigned char* source, size_t size, IOTHUB_CLIENT_FILE_UPLOAD_CALLBACK iotHubClientFileUploadCallback, void* context)
+{
+    return IoTHubClientCore_UploadToBlobAsync((IOTHUB_CLIENT_CORE_HANDLE)iotHubClientHandle, destinationFileName, source, size, iotHubClientFileUploadCallback, context);
+}
+
+IOTHUB_CLIENT_RESULT IoTHubClient_UploadMultipleBlocksToBlobAsync(IOTHUB_CLIENT_HANDLE iotHubClientHandle, const char* destinationFileName, IOTHUB_CLIENT_FILE_UPLOAD_GET_DATA_CALLBACK getDataCallback, void* context)
+{
+    return IoTHubClientCore_UploadMultipleBlocksToBlobAsync((IOTHUB_CLIENT_CORE_HANDLE)iotHubClientHandle, destinationFileName, getDataCallback, NULL, context);
+}
+
+IOTHUB_CLIENT_RESULT IoTHubClient_UploadMultipleBlocksToBlobAsyncEx(IOTHUB_CLIENT_HANDLE iotHubClientHandle, const char* destinationFileName, IOTHUB_CLIENT_FILE_UPLOAD_GET_DATA_CALLBACK_EX getDataCallbackEx, void* context)
+{
+    return IoTHubClientCore_UploadMultipleBlocksToBlobAsync((IOTHUB_CLIENT_CORE_HANDLE)iotHubClientHandle, destinationFileName, NULL, getDataCallbackEx, context);
+}
+
+#endif /*DONT_USE_UPLOADTOBLOB*/
+
Index: azure_iot_hub_f767zi/trunk/azure_iot_sdk/iothub_client/src/iothub_client_authorization.c
===================================================================
--- azure_iot_hub_f767zi/trunk/azure_iot_sdk/iothub_client/src/iothub_client_authorization.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/azure_iot_sdk/iothub_client/src/iothub_client_authorization.c	(revision 457)
@@ -0,0 +1,728 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+#include <stdlib.h>
+#include "azure_c_shared_utility/gballoc.h"
+#include "azure_macro_utils/macro_utils.h"
+#include "umock_c/umock_c_prod.h"
+#include "azure_c_shared_utility/crt_abstractions.h"
+#include "azure_c_shared_utility/agenttime.h"
+#include "azure_c_shared_utility/xlogging.h"
+#include "azure_c_shared_utility/strings.h"
+#include "azure_c_shared_utility/sastoken.h"
+#include "azure_c_shared_utility/shared_util_options.h"
+#include "azure_c_shared_utility/azure_base64.h"
+#include "azure_c_shared_utility/buffer_.h"
+
+#ifdef USE_PROV_MODULE
+#include "azure_prov_client/internal/iothub_auth_client.h"
+#endif
+
+#include "internal/iothub_client_authorization.h"
+
+#define DEFAULT_SAS_TOKEN_EXPIRY_TIME_SECS          3600
+#define INDEFINITE_TIME                             ((time_t)(-1))
+#define MIN_SAS_EXPIRY_TIME                         5  // 5 seconds
+
+typedef struct IOTHUB_AUTHORIZATION_DATA_TAG
+{
+    char* device_sas_token;
+    char* device_key;
+    char* device_id;
+    char* module_id;
+    size_t token_expiry_time_sec;
+    IOTHUB_CREDENTIAL_TYPE cred_type;
+#ifdef USE_PROV_MODULE
+    IOTHUB_SECURITY_HANDLE device_auth_handle;
+#endif
+} IOTHUB_AUTHORIZATION_DATA;
+
+static int get_seconds_since_epoch(size_t* seconds)
+{
+    int result;
+    time_t current_time;
+    if ((current_time = get_time(NULL)) == INDEFINITE_TIME)
+    {
+        LogError("Failed getting the current local time (get_time() failed)");
+        result = MU_FAILURE;
+    }
+    else
+    {
+        *seconds = (size_t)get_difftime(current_time, (time_t)0);
+        result = 0;
+    }
+    return result;
+}
+
+static IOTHUB_AUTHORIZATION_DATA* initialize_auth_client(const char* device_id, const char* module_id)
+{
+    IOTHUB_AUTHORIZATION_DATA* result;
+
+    /* Codes_SRS_IoTHub_Authorization_07_002: [IoTHubClient_Auth_Create shall allocate a IOTHUB_AUTHORIZATION_HANDLE that is needed for subsequent calls. ] */
+    result = (IOTHUB_AUTHORIZATION_DATA*)malloc(sizeof(IOTHUB_AUTHORIZATION_DATA) );
+    if (result == NULL)
+    {
+        /* Codes_SRS_IoTHub_Authorization_07_019: [ On error IoTHubClient_Auth_Create shall return NULL. ] */
+        LogError("Failed allocating IOTHUB_AUTHORIZATION_DATA");
+        result = NULL;
+    }
+    else
+    {
+        memset(result, 0, sizeof(IOTHUB_AUTHORIZATION_DATA) );
+        if (mallocAndStrcpy_s(&result->device_id, device_id) != 0)
+        {
+            /* Codes_SRS_IoTHub_Authorization_07_019: [ On error IoTHubClient_Auth_Create shall return NULL. ] */
+            LogError("Failed allocating device_key");
+            free(result);
+            result = NULL;
+        }
+        else if (module_id != NULL && mallocAndStrcpy_s(&result->module_id, module_id) != 0)
+        {
+            /* Codes_SRS_IoTHub_Authorization_07_019: [ On error IoTHubClient_Auth_Create shall return NULL. ] */
+            LogError("Failed allocating module_id");
+            free(result->device_id);
+            free(result);
+            result = NULL;
+        }
+        else
+        {
+            result->token_expiry_time_sec = DEFAULT_SAS_TOKEN_EXPIRY_TIME_SECS;
+        }
+    }
+    return result;
+}
+
+IOTHUB_AUTHORIZATION_HANDLE IoTHubClient_Auth_Create(const char* device_key, const char* device_id, const char* device_sas_token, const char *module_id)
+{
+    IOTHUB_AUTHORIZATION_DATA* result;
+    bool is_key_valid;
+
+    if (device_key == NULL)
+    {
+        is_key_valid = true;
+    }
+    else
+    {
+        /* Codes_SRS_IoTHub_Authorization_21_021: [ If the provided key is not base64 encoded, IoTHubClient_Auth_Create shall return NULL. ] */
+        BUFFER_HANDLE key = Azure_Base64_Decode(device_key);
+        if (key != NULL)
+        {
+            is_key_valid = true;
+        }
+        else
+        {
+            is_key_valid = false;
+        }
+        BUFFER_delete(key);
+    }
+    
+    /* Codes_SRS_IoTHub_Authorization_07_001: [if device_id is NULL IoTHubClient_Auth_Create, shall return NULL. ] */
+    if ((device_id == NULL) || (!is_key_valid))
+    {
+        LogError("Invalid Parameter %s", ((device_id == NULL) ? "device_id: NULL" : "key"));
+        result = NULL;
+    }
+    else
+    {
+        result = initialize_auth_client(device_id, module_id);
+        if (result == NULL)
+        {
+            LogError("Failure initializing auth client");
+        }
+        else if (device_key != NULL && mallocAndStrcpy_s(&result->device_key, device_key) != 0)
+        {
+            /* Codes_SRS_IoTHub_Authorization_07_019: [ On error IoTHubClient_Auth_Create shall return NULL. ] */
+            LogError("Failed allocating device_key");
+            free(result->device_id);
+            free(result->module_id);
+            free(result);
+            result = NULL;
+        }
+        else
+        {
+            if (device_key != NULL)
+            {
+                /* Codes_SRS_IoTHub_Authorization_07_003: [ IoTHubClient_Auth_Create shall set the credential type to IOTHUB_CREDENTIAL_TYPE_DEVICE_KEY if the device_sas_token is NULL. ]*/
+                result->cred_type = IOTHUB_CREDENTIAL_TYPE_DEVICE_KEY;
+            }
+            else if (device_sas_token != NULL)
+            {
+                /* Codes_SRS_IoTHub_Authorization_07_020: [ else IoTHubClient_Auth_Create shall set the credential type to IOTHUB_CREDENTIAL_TYPE_SAS_TOKEN. ] */
+                result->cred_type = IOTHUB_CREDENTIAL_TYPE_SAS_TOKEN;
+                if (mallocAndStrcpy_s(&result->device_sas_token, device_sas_token) != 0)
+                {
+                    /* Codes_SRS_IoTHub_Authorization_07_019: [ On error IoTHubClient_Auth_Create shall return NULL. ] */
+                    LogError("Failed allocating device_key");
+                    free(result->device_key);
+                    free(result->device_id);
+                    free(result->module_id);
+                    free(result);
+                    result = NULL;
+                }
+            }
+            else
+            {
+                /* Codes_SRS_IoTHub_Authorization_07_024: [ if device_sas_token and device_key are NULL IoTHubClient_Auth_Create shall set the credential type to IOTHUB_CREDENTIAL_TYPE_UNKNOWN. ] */
+                result->cred_type = IOTHUB_CREDENTIAL_TYPE_UNKNOWN;
+            }
+        }
+    }
+    /* Codes_SRS_IoTHub_Authorization_07_004: [ If successful IoTHubClient_Auth_Create shall return a IOTHUB_AUTHORIZATION_HANDLE value. ] */
+    return result;
+}
+
+IOTHUB_AUTHORIZATION_HANDLE IoTHubClient_Auth_CreateFromDeviceAuth(const char* device_id, const char* module_id)
+{
+    IOTHUB_AUTHORIZATION_DATA* result;
+    if (device_id == NULL)
+    {
+        LogError("Invalid Parameter device_id: %p", device_id);
+        result = NULL;
+    }
+    else
+    {
+#ifdef USE_PROV_MODULE
+        result = initialize_auth_client(device_id, module_id);
+        if (result == NULL)
+        {
+            LogError("Failure initializing auth client");
+        }
+        else
+        {
+            result->device_auth_handle = iothub_device_auth_create();
+            if (result->device_auth_handle == NULL)
+            {
+                LogError("Failed allocating IOTHUB_AUTHORIZATION_DATA");
+                free(result->device_id);
+                free(result->module_id);
+                free(result);
+                result = NULL;
+            }
+            else
+            {
+                DEVICE_AUTH_TYPE auth_type = iothub_device_auth_get_type(result->device_auth_handle);
+                if (auth_type == AUTH_TYPE_SAS || auth_type == AUTH_TYPE_SYMM_KEY)
+                {
+                    result->cred_type = IOTHUB_CREDENTIAL_TYPE_DEVICE_AUTH;
+                }
+                else
+                {
+                    result->cred_type = IOTHUB_CREDENTIAL_TYPE_X509_ECC;
+                }
+            }
+        }
+#else
+        (void)module_id;
+        LogError("Failed HSM module is not supported");
+        result = NULL;
+#endif
+    }
+    return result;
+}
+
+void IoTHubClient_Auth_Destroy(IOTHUB_AUTHORIZATION_HANDLE handle)
+{
+    /* Codes_SRS_IoTHub_Authorization_07_005: [ if handle is NULL IoTHubClient_Auth_Destroy shall do nothing. ] */
+    if (handle != NULL)
+    {
+        /* Codes_SRS_IoTHub_Authorization_07_006: [ IoTHubClient_Auth_Destroy shall free all resources associated with the IOTHUB_AUTHORIZATION_HANDLE handle. ] */
+#ifdef USE_PROV_MODULE
+        iothub_device_auth_destroy(handle->device_auth_handle);
+#endif
+        free(handle->device_key);
+        free(handle->device_id);
+        free(handle->module_id);
+        free(handle->device_sas_token);
+        free(handle);
+    }
+}
+
+IOTHUB_CREDENTIAL_TYPE IoTHubClient_Auth_Set_x509_Type(IOTHUB_AUTHORIZATION_HANDLE handle, bool enable_x509)
+{
+    IOTHUB_CREDENTIAL_TYPE result;
+    if (handle != NULL)
+    {
+        if (enable_x509)
+        {
+            result = handle->cred_type = IOTHUB_CREDENTIAL_TYPE_X509;
+        }
+        else
+        {
+            if (handle->device_sas_token == NULL)
+            {
+                result = handle->cred_type = IOTHUB_CREDENTIAL_TYPE_DEVICE_KEY;
+            }
+            else if (handle->device_key == NULL)
+            {
+                result = handle->cred_type = IOTHUB_CREDENTIAL_TYPE_SAS_TOKEN;
+            }
+            else
+            {
+                result = handle->cred_type = IOTHUB_CREDENTIAL_TYPE_UNKNOWN;
+            }
+        }
+    }
+    else
+    {
+        result = IOTHUB_CREDENTIAL_TYPE_UNKNOWN;
+    }
+    return result;
+}
+
+int IoTHubClient_Auth_Set_xio_Certificate(IOTHUB_AUTHORIZATION_HANDLE handle, XIO_HANDLE xio)
+{
+    int result;
+    if (handle == NULL || xio == NULL)
+    {
+        LogError("Invalid Parameter handle: %p xio: %p", handle, xio);
+        result = MU_FAILURE;
+    }
+    else if (handle->cred_type != IOTHUB_CREDENTIAL_TYPE_X509_ECC)
+    {
+        LogError("Invalid credential types for this operation");
+        result = MU_FAILURE;
+    }
+    else
+    {
+#ifdef USE_PROV_MODULE
+        CREDENTIAL_RESULT* cred_result = iothub_device_auth_generate_credentials(handle->device_auth_handle, NULL);
+        if (cred_result == NULL)
+        {
+            LogError("Failure generating credentials");
+            result = MU_FAILURE;
+        }
+        else
+        {
+            if (xio_setoption(xio, OPTION_X509_ECC_CERT, cred_result->auth_cred_result.x509_result.x509_cert) != 0)
+            {
+                LogError("Failure setting x509 cert on xio");
+                result = MU_FAILURE;
+            }
+            else if (xio_setoption(xio, OPTION_X509_ECC_KEY, cred_result->auth_cred_result.x509_result.x509_alias_key) != 0)
+            {
+                LogError("Failure setting x509 key on xio");
+                result = MU_FAILURE;
+            }
+            else
+            {
+                result = 0;
+            }
+            free(cred_result);
+        }
+#else
+        LogError("Failed HSM module is not supported");
+        result = MU_FAILURE;
+#endif
+    }
+    return result;
+}
+
+int IoTHubClient_Auth_Get_x509_info(IOTHUB_AUTHORIZATION_HANDLE handle, char** x509_cert, char** x509_key)
+{
+    int result;
+    if (handle == NULL || x509_cert == NULL || x509_key == NULL)
+    {
+        LogError("Invalid Parameter handle: %p, x509_cert: %p, x509_key: %p", handle, x509_cert, x509_key);
+        result = MU_FAILURE;
+    }
+    else if (handle->cred_type != IOTHUB_CREDENTIAL_TYPE_X509_ECC)
+    {
+        LogError("Invalid credential types for this operation");
+        result = MU_FAILURE;
+    }
+    else
+    {
+#ifdef USE_PROV_MODULE
+        CREDENTIAL_RESULT* cred_result = iothub_device_auth_generate_credentials(handle->device_auth_handle, NULL);
+        if (cred_result == NULL)
+        {
+            LogError("Failure generating credentials");
+            result = MU_FAILURE;
+        }
+        else
+        {
+            if (mallocAndStrcpy_s(x509_cert, cred_result->auth_cred_result.x509_result.x509_cert) != 0)
+            {
+                LogError("Failure copying certificate");
+                result = MU_FAILURE;
+            }
+            else if (mallocAndStrcpy_s(x509_key, cred_result->auth_cred_result.x509_result.x509_alias_key) != 0)
+            {
+                LogError("Failure copying private key");
+                result = MU_FAILURE;
+                free(*x509_cert);
+            }
+            else
+            {
+                result = 0;
+            }
+            free(cred_result);
+        }
+#else
+        LogError("Failed HSM module is not supported");
+        result = MU_FAILURE;
+#endif
+    }
+    return result;
+}
+
+IOTHUB_CREDENTIAL_TYPE IoTHubClient_Auth_Get_Credential_Type(IOTHUB_AUTHORIZATION_HANDLE handle)
+{
+    IOTHUB_CREDENTIAL_TYPE result;
+    /* Codes_SRS_IoTHub_Authorization_07_007: [ if handle is NULL IoTHub_Auth_Get_Credential_Type shall return IOTHUB_CREDENTIAL_TYPE_UNKNOWN. ] */
+    if (handle == NULL)
+    {
+        LogError("Invalid Parameter handle: %p", handle);
+        result = IOTHUB_CREDENTIAL_TYPE_UNKNOWN;
+    }
+    else
+    {
+        /* Codes_SRS_IoTHub_Authorization_07_008: [ IoTHub_Auth_Get_Credential_Type shall return the credential type that is set upon creation. ] */
+        result = handle->cred_type;
+    }
+    return result;
+}
+
+char* IoTHubClient_Auth_Get_SasToken(IOTHUB_AUTHORIZATION_HANDLE handle, const char* scope, size_t expiry_time_relative_seconds, const char* key_name)
+{
+    char* result;
+    (void)expiry_time_relative_seconds;
+    /* Codes_SRS_IoTHub_Authorization_07_009: [ if handle or scope are NULL, IoTHubClient_Auth_Get_SasToken shall return NULL. ] */
+    if (handle == NULL)
+    {
+        LogError("Invalid Parameter handle: %p", handle);
+        result = NULL;
+    }
+    else
+    {
+        if (handle->cred_type == IOTHUB_CREDENTIAL_TYPE_DEVICE_AUTH)
+        {
+#ifdef USE_PROV_MODULE
+            DEVICE_AUTH_CREDENTIAL_INFO dev_auth_cred;
+            size_t sec_since_epoch;
+
+            if (get_seconds_since_epoch(&sec_since_epoch) != 0)
+            {
+                LogError("failure getting seconds from epoch");
+                result = NULL;
+            }
+            else
+            {
+                memset(&dev_auth_cred, 0, sizeof(DEVICE_AUTH_CREDENTIAL_INFO));
+                size_t expiry_time = sec_since_epoch + handle->token_expiry_time_sec;
+                dev_auth_cred.sas_info.expiry_seconds = expiry_time;
+                dev_auth_cred.sas_info.token_scope = scope;
+                dev_auth_cred.sas_info.key_name = key_name;
+                dev_auth_cred.dev_auth_type = AUTH_TYPE_SAS;
+
+                CREDENTIAL_RESULT* cred_result = iothub_device_auth_generate_credentials(handle->device_auth_handle, &dev_auth_cred);
+                if (cred_result == NULL)
+                {
+                    LogError("failure getting credentials from device auth module");
+                    result = NULL;
+                }
+                else
+                {
+                    if (mallocAndStrcpy_s(&result, cred_result->auth_cred_result.sas_result.sas_token) != 0)
+                    {
+                        LogError("failure allocating Sas Token");
+                        result = NULL;
+                    }
+                    free(cred_result);
+                }
+            }
+#else
+            LogError("Failed HSM module is not supported");
+            result = NULL;
+#endif
+        }
+        else if (handle->cred_type == IOTHUB_CREDENTIAL_TYPE_SAS_TOKEN)
+        {
+            /* Codes_SRS_IoTHub_Authorization_07_021: [If the device_sas_token is NOT NULL IoTHubClient_Auth_Get_SasToken shall return a copy of the device_sas_token. ] */
+            if (handle->device_sas_token != NULL)
+            {
+                if (mallocAndStrcpy_s(&result, handle->device_sas_token) != 0)
+                {
+                    LogError("failure allocating sas token");
+                    result = NULL;
+                }
+            }
+            else
+            {
+                LogError("failure device sas token is NULL");
+                result = NULL;
+            }
+        }
+        else if (handle->cred_type == IOTHUB_CREDENTIAL_TYPE_DEVICE_KEY)
+        {
+            /* Codes_SRS_IoTHub_Authorization_07_009: [ if handle or scope are NULL, IoTHubClient_Auth_Get_SasToken shall return NULL. ] */
+            if (scope == NULL)
+            {
+                LogError("Invalid Parameter scope: %p", scope);
+                result = NULL;
+            }
+            else
+            {
+                STRING_HANDLE sas_token;
+                size_t sec_since_epoch;
+
+                /* Codes_SRS_IoTHub_Authorization_07_010: [ IoTHubClient_Auth_Get_SasToken` shall construct the expiration time using the handle->token_expiry_time_sec added to epoch time. ] */
+                if (get_seconds_since_epoch(&sec_since_epoch) != 0)
+                {
+                    /* Codes_SRS_IoTHub_Authorization_07_020: [ If any error is encountered IoTHubClient_Auth_Get_ConnString shall return NULL. ] */
+                    LogError("failure getting seconds from epoch");
+                    result = NULL;
+                }
+                else
+                {
+                    /* Codes_SRS_IoTHub_Authorization_07_011: [ IoTHubClient_Auth_Get_ConnString shall call SASToken_CreateString to construct the sas token. ] */
+                    size_t expiry_time = sec_since_epoch + handle->token_expiry_time_sec;
+                    if ( (sas_token = SASToken_CreateString(handle->device_key, scope, key_name, expiry_time)) == NULL)
+                    {
+                        /* Codes_SRS_IoTHub_Authorization_07_020: [ If any error is encountered IoTHubClient_Auth_Get_ConnString shall return NULL. ] */
+                        LogError("Failed creating sas_token");
+                        result = NULL;
+                    }
+                    else
+                    {
+                        /* Codes_SRS_IoTHub_Authorization_07_012: [ On success IoTHubClient_Auth_Get_ConnString shall allocate and return the sas token in a char*. ] */
+                        if (mallocAndStrcpy_s(&result, STRING_c_str(sas_token) ) != 0)
+                        {
+                            /* Codes_SRS_IoTHub_Authorization_07_020: [ If any error is encountered IoTHubClient_Auth_Get_ConnString shall return NULL. ] */
+                            LogError("Failed copying result");
+                            result = NULL;
+                        }
+                        STRING_delete(sas_token);
+                    }
+                }
+            }
+        }
+        else
+        {
+            LogError("Failed getting sas token invalid credential type");
+            result = NULL;
+        }
+    }
+    return result;
+}
+
+const char* IoTHubClient_Auth_Get_DeviceId(IOTHUB_AUTHORIZATION_HANDLE handle)
+{
+    const char* result;
+    if (handle == NULL)
+    {
+        /* Codes_SRS_IoTHub_Authorization_07_013: [ if handle is NULL, IoTHubClient_Auth_Get_DeviceId shall return NULL. ] */
+        LogError("Invalid Parameter handle: %p", handle);
+        result = NULL;
+    }
+    else
+    {
+        /* Codes_SRS_IoTHub_Authorization_07_014: [ IoTHubClient_Auth_Get_DeviceId shall return the device_id specified upon creation. ] */
+        result = handle->device_id;
+    }
+    return result;
+}
+
+const char* IoTHubClient_Auth_Get_ModuleId(IOTHUB_AUTHORIZATION_HANDLE handle)
+{
+    const char* result;
+    if (handle == NULL)
+    {
+        /* Codes_SRS_IoTHub_Authorization_31_025: [ if handle is NULL, IoTHubClient_Auth_Get_ModuleId shall return NULL. ] */
+        LogError("Invalid Parameter handle: %p", handle);
+        result = NULL;
+    }
+    else
+    {
+        /* Codes_SRS_IoTHub_Authorization_31_026: [ IoTHubClient_Auth_Get_ModuleId shall return the module_id specified upon creation. ] */
+        result = handle->module_id;
+    }
+    return result;
+}
+
+const char* IoTHubClient_Auth_Get_DeviceKey(IOTHUB_AUTHORIZATION_HANDLE handle)
+{
+    const char* result;
+    if (handle == NULL)
+    {
+        /* Codes_SRS_IoTHub_Authorization_07_022: [ if handle is NULL, IoTHubClient_Auth_Get_DeviceKey shall return NULL. ] */
+        LogError("Invalid Parameter handle: %p", handle);
+        result = NULL;
+    }
+    else
+    {
+        /* Codes_SRS_IoTHub_Authorization_07_023: [ IoTHubClient_Auth_Get_DeviceKey shall return the device_key specified upon creation. ] */
+        result = handle->device_key;
+    }
+    return result;
+}
+
+SAS_TOKEN_STATUS IoTHubClient_Auth_Is_SasToken_Valid(IOTHUB_AUTHORIZATION_HANDLE handle)
+{
+    SAS_TOKEN_STATUS result;
+    if (handle == NULL)
+    {
+        /* Codes_SRS_IoTHub_Authorization_07_015: [ if handle is NULL, IoTHubClient_Auth_Is_SasToken_Valid shall return false. ] */
+        LogError("Invalid Parameter handle: %p", handle);
+        result = SAS_TOKEN_STATUS_FAILED;
+    }
+    else
+    {
+        if (handle->cred_type == IOTHUB_CREDENTIAL_TYPE_SAS_TOKEN)
+        {
+            if (handle->device_sas_token == NULL)
+            {
+                /* Codes_SRS_IoTHub_Authorization_07_017: [ If the sas_token is NULL IoTHubClient_Auth_Is_SasToken_Valid shall return false. ] */
+                LogError("Failure: device_sas_toke is NULL");
+                result = SAS_TOKEN_STATUS_FAILED;
+            }
+            else
+            {
+                /* Codes_SRS_IoTHub_Authorization_07_018: [ otherwise IoTHubClient_Auth_Is_SasToken_Valid shall return the value returned by SASToken_Validate. ] */
+                STRING_HANDLE strSasToken = STRING_construct(handle->device_sas_token);
+                if (strSasToken != NULL)
+                {
+                    if (!SASToken_Validate(strSasToken))
+                    {
+                        result = SAS_TOKEN_STATUS_INVALID;
+                    }
+                    else
+                    {
+                        result = SAS_TOKEN_STATUS_VALID;
+                    }
+                    STRING_delete(strSasToken);
+                }
+                else
+                {
+                    LogError("Failure constructing SAS Token");
+                    result = SAS_TOKEN_STATUS_FAILED;
+                }
+            }
+        }
+        else
+        {
+            /* Codes_SRS_IoTHub_Authorization_07_016: [ if credential type is not IOTHUB_CREDENTIAL_TYPE_SAS_TOKEN IoTHubClient_Auth_Is_SasToken_Valid shall return SAS_TOKEN_STATUS_VALID. ] */
+            result = SAS_TOKEN_STATUS_VALID;
+        }
+    }
+    return result;
+}
+
+#ifdef USE_EDGE_MODULES
+
+// For debugging C modules, the environment can set the environment variable 'EdgeModuleCACertificateFile' to provide
+// trusted certificates.  We'd otherwise usually get these from trusted Edge service, but this complicates debugging experience.
+// EdgeModuleCACertificateFile and the related EdgeHubConnectionString can be set either manually or by tooling (e.g. VS Code).
+static char* read_ca_certificate_from_file(const char* certificate_file_name)
+{
+    char* result;
+    FILE *file_stream = NULL;
+
+    if ((file_stream = fopen(certificate_file_name, "r")) == NULL)
+    {
+        LogError("Cannot read file %s, errno=%d", certificate_file_name, errno);
+        result = NULL;
+    }
+    else if (fseek(file_stream, 0, SEEK_END) != 0)
+    {
+        LogError("fseek on file %s fails, errno=%d", certificate_file_name, errno);
+        result = NULL;
+    }
+    else
+    {
+        long int file_size = ftell(file_stream);
+        if (file_size < 0)
+        {
+            LogError("ftell fails reading %s, errno=%d",  certificate_file_name, errno);
+            result = NULL;
+        }
+        else if (file_size == 0)
+        {
+            LogError("file %s is 0 bytes, which is not valid certificate",  certificate_file_name);
+            result = NULL;
+        }
+        else
+        {
+            rewind(file_stream);
+
+            if ((result = calloc(1, file_size + 1)) == NULL)
+            {
+                LogError("Cannot allocate %lu bytes", (unsigned long)file_size);
+            }
+            else if ((fread(result, 1, file_size, file_stream) == 0) || (ferror(file_stream) != 0))
+            {
+                LogError("fread failed on file %s, errno=%d", certificate_file_name, errno);
+                free(result);
+                result = NULL;
+            }
+        }
+    }
+
+    if (file_stream != NULL)
+    {
+        fclose(file_stream);
+    }
+
+    return result;
+}
+
+// IoTHubClient_Auth_Get_TrustBundle retrieves a trust bundle - namely a PEM indicating the certificates the client should
+// trust as root authorities - to caller.  If certificate_file_name, we read this from a local file.  This should in general
+// be limited only to debugging modules on Edge.  If certificate_file_name is NULL, we invoke into the underlying
+// HSM to retrieve this.
+char* IoTHubClient_Auth_Get_TrustBundle(IOTHUB_AUTHORIZATION_HANDLE handle, const char* certificate_file_name)
+{
+    char* result;
+    if (handle == NULL)
+    {
+        LogError("Security Handle is NULL");
+        result = NULL;
+    }
+    else if (certificate_file_name != NULL)
+    {
+        result = read_ca_certificate_from_file(certificate_file_name);
+    }
+    else
+    {
+        result = iothub_device_auth_get_trust_bundle(handle->device_auth_handle);
+    }
+    return result;
+}
+#endif
+
+int IoTHubClient_Auth_Set_SasToken_Expiry(IOTHUB_AUTHORIZATION_HANDLE handle, size_t expiry_time_seconds)
+{
+    int result;
+    if (handle == NULL)
+    {
+        LogError("Invalid handle value handle: NULL");
+        result = MU_FAILURE;
+    }
+    // Validate the expiry_time in seconds
+    else if (expiry_time_seconds < MIN_SAS_EXPIRY_TIME)
+    {
+        LogError("Failure setting expiry time to value %lu min value is %d", (unsigned long)expiry_time_seconds, MIN_SAS_EXPIRY_TIME);
+        result = MU_FAILURE;
+    }
+    else
+    {
+        handle->token_expiry_time_sec = expiry_time_seconds;
+        result = 0;
+    }
+    return result;
+}
+
+size_t IoTHubClient_Auth_Get_SasToken_Expiry(IOTHUB_AUTHORIZATION_HANDLE handle)
+{
+    size_t result;
+    if (handle == NULL)
+    {
+        LogError("Invalid handle value handle: NULL");
+        result = 0;
+    }
+    else
+    {
+        result = handle->token_expiry_time_sec;
+    }
+    return result;
+}
Index: azure_iot_hub_f767zi/trunk/azure_iot_sdk/iothub_client/src/iothub_client_core.c
===================================================================
--- azure_iot_hub_f767zi/trunk/azure_iot_sdk/iothub_client/src/iothub_client_core.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/azure_iot_sdk/iothub_client/src/iothub_client_core.c	(revision 457)
@@ -0,0 +1,2660 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+#include <stdlib.h>
+#include "umock_c/umock_c_prod.h"
+#include "azure_c_shared_utility/gballoc.h"
+
+#include <signal.h>
+#include <stddef.h>
+#include "azure_c_shared_utility/optimize_size.h"
+#include "azure_c_shared_utility/crt_abstractions.h"
+#include "iothub_client_core.h"
+#include "iothub_client_core_ll.h"
+#include "internal/iothubtransport.h"
+#include "internal/iothub_client_private.h"
+#include "internal/iothubtransport.h"
+#include "azure_c_shared_utility/threadapi.h"
+#include "azure_c_shared_utility/lock.h"
+#include "azure_c_shared_utility/xlogging.h"
+#include "azure_c_shared_utility/singlylinkedlist.h"
+#include "azure_c_shared_utility/vector.h"
+#include "iothub_client_options.h"
+#include "azure_c_shared_utility/tickcounter.h"
+#include "azure_c_shared_utility/agenttime.h"
+
+
+#define DO_WORK_FREQ_DEFAULT 1
+
+struct IOTHUB_QUEUE_CONTEXT_TAG;
+
+typedef struct IOTHUB_CLIENT_CORE_INSTANCE_TAG
+{
+    IOTHUB_CLIENT_CORE_LL_HANDLE IoTHubClientLLHandle;
+    TRANSPORT_HANDLE TransportHandle;
+    THREAD_HANDLE ThreadHandle;
+    LOCK_HANDLE LockHandle;
+    sig_atomic_t StopThread;
+    SINGLYLINKEDLIST_HANDLE httpWorkerThreadInfoList; /*list containing HTTPWORKER_THREAD_INFO*/
+    int created_with_transport_handle;
+    VECTOR_HANDLE saved_user_callback_list;
+    IOTHUB_CLIENT_DEVICE_TWIN_CALLBACK desired_state_callback;
+    IOTHUB_CLIENT_CONNECTION_STATUS_CALLBACK connection_status_callback;
+    IOTHUB_CLIENT_DEVICE_METHOD_CALLBACK_ASYNC device_method_callback;
+    IOTHUB_CLIENT_INBOUND_DEVICE_METHOD_CALLBACK inbound_device_method_callback;
+    IOTHUB_CLIENT_MESSAGE_CALLBACK_ASYNC message_callback;
+    struct IOTHUB_QUEUE_CONTEXT_TAG* devicetwin_user_context;
+    struct IOTHUB_QUEUE_CONTEXT_TAG* connection_status_user_context;
+    struct IOTHUB_QUEUE_CONTEXT_TAG* message_user_context;
+    struct IOTHUB_QUEUE_CONTEXT_TAG* method_user_context;
+    tickcounter_ms_t do_work_freq_ms;
+    tickcounter_ms_t currentMessageTimeout;
+} IOTHUB_CLIENT_CORE_INSTANCE;
+
+typedef enum HTTPWORKER_THREAD_TYPE_TAG
+{
+    HTTPWORKER_THREAD_UPLOAD_TO_BLOB,
+    HTTPWORKER_THREAD_INVOKE_METHOD
+} HTTPWORKER_THREAD_TYPE;
+
+typedef struct UPLOADTOBLOB_SAVED_DATA_TAG
+{
+    unsigned char* source;
+    size_t size;
+    IOTHUB_CLIENT_FILE_UPLOAD_CALLBACK iotHubClientFileUploadCallback;
+}UPLOADTOBLOB_SAVED_DATA;
+
+typedef struct UPLOADTOBLOB_MULTIBLOCK_SAVED_DATA_TAG
+{
+    IOTHUB_CLIENT_FILE_UPLOAD_GET_DATA_CALLBACK getDataCallback;
+    IOTHUB_CLIENT_FILE_UPLOAD_GET_DATA_CALLBACK_EX getDataCallbackEx;
+}UPLOADTOBLOB_MULTIBLOCK_SAVED_DATA;
+
+typedef struct INVOKE_METHOD_SAVED_DATA_TAG
+{
+    const char* deviceId;
+    const char* moduleId;
+    const char* methodName;
+    const char* methodPayload;
+    unsigned int timeout;
+    IOTHUB_METHOD_INVOKE_CALLBACK methodInvokeCallback;
+} INVOKE_METHOD_SAVED_DATA;
+
+typedef struct HTTPWORKER_THREAD_INFO_TAG
+{
+    HTTPWORKER_THREAD_TYPE workerThreadType;
+    char* destinationFileName;
+    THREAD_HANDLE threadHandle;
+    LOCK_HANDLE lockGarbage;
+    int canBeGarbageCollected; /*flag indicating that the structure can be freed because the thread deadling with it finished*/
+    IOTHUB_CLIENT_CORE_HANDLE iotHubClientHandle;
+    void* context;
+    UPLOADTOBLOB_SAVED_DATA uploadBlobSavedData;
+    INVOKE_METHOD_SAVED_DATA invokeMethodSavedData;
+    UPLOADTOBLOB_MULTIBLOCK_SAVED_DATA uploadBlobMultiblockSavedData;
+}HTTPWORKER_THREAD_INFO;
+
+#define USER_CALLBACK_TYPE_VALUES       \
+    CALLBACK_TYPE_DEVICE_TWIN,          \
+    CALLBACK_TYPE_EVENT_CONFIRM,        \
+    CALLBACK_TYPE_REPORTED_STATE,       \
+    CALLBACK_TYPE_CONNECTION_STATUS,    \
+    CALLBACK_TYPE_DEVICE_METHOD,        \
+    CALLBACK_TYPE_INBOUD_DEVICE_METHOD, \
+    CALLBACK_TYPE_MESSAGE,              \
+    CALLBACK_TYPE_INPUTMESSAGE
+
+MU_DEFINE_ENUM_WITHOUT_INVALID(USER_CALLBACK_TYPE, USER_CALLBACK_TYPE_VALUES)
+MU_DEFINE_ENUM_STRINGS_WITHOUT_INVALID(USER_CALLBACK_TYPE, USER_CALLBACK_TYPE_VALUES)
+
+typedef struct DEVICE_TWIN_CALLBACK_INFO_TAG
+{
+    DEVICE_TWIN_UPDATE_STATE update_state;
+    unsigned char* payLoad;
+    size_t size;
+    IOTHUB_CLIENT_DEVICE_TWIN_CALLBACK userCallback;
+    void* userContext;
+} DEVICE_TWIN_CALLBACK_INFO;
+
+typedef struct EVENT_CONFIRM_CALLBACK_INFO_TAG
+{
+    IOTHUB_CLIENT_CONFIRMATION_RESULT confirm_result;
+    IOTHUB_CLIENT_EVENT_CONFIRMATION_CALLBACK eventConfirmationCallback;
+} EVENT_CONFIRM_CALLBACK_INFO;
+
+typedef struct REPORTED_STATE_CALLBACK_INFO_TAG
+{
+    int status_code;
+    IOTHUB_CLIENT_REPORTED_STATE_CALLBACK reportedStateCallback;
+} REPORTED_STATE_CALLBACK_INFO;
+
+typedef struct CONNECTION_STATUS_CALLBACK_INFO_TAG
+{
+    IOTHUB_CLIENT_CONNECTION_STATUS connection_status;
+    IOTHUB_CLIENT_CONNECTION_STATUS_REASON status_reason;
+} CONNECTION_STATUS_CALLBACK_INFO;
+
+typedef struct METHOD_CALLBACK_INFO_TAG
+{
+    STRING_HANDLE method_name;
+    BUFFER_HANDLE payload;
+    METHOD_HANDLE method_id;
+} METHOD_CALLBACK_INFO;
+
+typedef struct INPUTMESSAGE_CALLBACK_INFO_TAG
+{
+    IOTHUB_CLIENT_MESSAGE_CALLBACK_ASYNC eventHandlerCallback;
+    MESSAGE_CALLBACK_INFO* message_cb_info;
+} INPUTMESSAGE_CALLBACK_INFO;
+
+typedef struct USER_CALLBACK_INFO_TAG
+{
+    USER_CALLBACK_TYPE type;
+    void* userContextCallback;
+    union IOTHUB_CALLBACK
+    {
+        DEVICE_TWIN_CALLBACK_INFO dev_twin_cb_info;
+        EVENT_CONFIRM_CALLBACK_INFO event_confirm_cb_info;
+        REPORTED_STATE_CALLBACK_INFO reported_state_cb_info;
+        CONNECTION_STATUS_CALLBACK_INFO connection_status_cb_info;
+        METHOD_CALLBACK_INFO method_cb_info;
+        MESSAGE_CALLBACK_INFO* message_cb_info;
+        INPUTMESSAGE_CALLBACK_INFO inputmessage_cb_info;
+    } iothub_callback;
+} USER_CALLBACK_INFO;
+
+typedef struct IOTHUB_QUEUE_CONTEXT_TAG
+{
+    IOTHUB_CLIENT_CORE_INSTANCE* iotHubClientHandle;
+    void* userContextCallback;
+    union IOTHUB_CALLBACK_FUNCTION
+    {
+        IOTHUB_CLIENT_EVENT_CONFIRMATION_CALLBACK eventConfirmationCallback;
+        IOTHUB_CLIENT_REPORTED_STATE_CALLBACK reportedStateCallback;
+    } callbackFunction;
+} IOTHUB_QUEUE_CONTEXT;
+
+typedef struct IOTHUB_QUEUE_CONSOLIDATED_CONTEXT_TAG
+{
+    IOTHUB_CLIENT_CORE_INSTANCE* iotHubClientHandle;
+
+    union USER_CALLBACK_TAG
+    {
+        IOTHUB_CLIENT_DEVICE_TWIN_CALLBACK getTwin;
+    } userCallback;
+
+    void* userContext;
+} IOTHUB_QUEUE_CONSOLIDATED_CONTEXT;
+
+typedef struct IOTHUB_INPUTMESSAGE_CALLBACK_CONTEXT_TAG
+{
+    IOTHUB_CLIENT_CORE_HANDLE iotHubClientHandle;
+    IOTHUB_CLIENT_MESSAGE_CALLBACK_ASYNC eventHandlerCallback;
+    void* userContextCallback;
+} IOTHUB_INPUTMESSAGE_CALLBACK_CONTEXT;
+
+/*used by unittests only*/
+const size_t IoTHubClientCore_ThreadTerminationOffset = offsetof(IOTHUB_CLIENT_CORE_INSTANCE, StopThread);
+
+typedef enum CREATE_HUB_INSTANCE_TYPE_TAG
+{
+    CREATE_HUB_INSTANCE_FROM_CONNECTION_STRING,
+    CREATE_HUB_INSTANCE_FROM_EDGE_ENVIRONMENT,
+    CREATE_HUB_INSTANCE_FROM_TRANSPORT,
+    CREATE_HUB_INSTANCE_FROM_CLIENT_CONFIG,
+    CREATE_HUB_INSTANCE_FROM_DEVICE_AUTH
+} CREATE_HUB_INSTANCE_TYPE;
+
+static void freeHttpWorkerThreadInfo(HTTPWORKER_THREAD_INFO* threadInfo)
+{
+    Lock_Deinit(threadInfo->lockGarbage);
+    if (threadInfo->workerThreadType == HTTPWORKER_THREAD_UPLOAD_TO_BLOB)
+    {
+        free(threadInfo->uploadBlobSavedData.source);
+        free(threadInfo->destinationFileName);
+    }
+    else if (threadInfo->workerThreadType == HTTPWORKER_THREAD_INVOKE_METHOD)
+    {
+        free((char*)threadInfo->invokeMethodSavedData.deviceId);
+        free((char*)threadInfo->invokeMethodSavedData.moduleId);
+        free((char*)threadInfo->invokeMethodSavedData.methodName);
+        free((char*)threadInfo->invokeMethodSavedData.methodPayload);
+    }
+
+    free(threadInfo);
+}
+
+/*this function is called from _Destroy and from ScheduleWork_Thread to join finished blobUpload threads and free that memory*/
+static void garbageCollectorImpl(IOTHUB_CLIENT_CORE_INSTANCE* iotHubClientInstance)
+{
+    /*see if any savedData structures can be disposed of*/
+    /*Codes_SRS_IOTHUBCLIENT_02_072: [ All threads marked as disposable (upon completion of a file upload) shall be joined and the data structures build for them shall be freed. ]*/
+    LIST_ITEM_HANDLE item = singlylinkedlist_get_head_item(iotHubClientInstance->httpWorkerThreadInfoList);
+    while (item != NULL)
+    {
+        HTTPWORKER_THREAD_INFO* threadInfo = (HTTPWORKER_THREAD_INFO*)singlylinkedlist_item_get_value(item);
+        LIST_ITEM_HANDLE old_item = item;
+        item = singlylinkedlist_get_next_item(item);
+
+        if (Lock(threadInfo->lockGarbage) != LOCK_OK)
+        {
+            LogError("unable to Lock");
+        }
+        else
+        {
+            if (threadInfo->canBeGarbageCollected == 1)
+            {
+                int notUsed;
+                if (ThreadAPI_Join(threadInfo->threadHandle, &notUsed) != THREADAPI_OK)
+                {
+                    LogError("unable to ThreadAPI_Join");
+                }
+                (void)singlylinkedlist_remove(iotHubClientInstance->httpWorkerThreadInfoList, old_item);
+
+                if (Unlock(threadInfo->lockGarbage) != LOCK_OK)
+                {
+                    LogError("unable to unlock after locking");
+                }
+                freeHttpWorkerThreadInfo(threadInfo);
+            }
+            else
+            {
+                if (Unlock(threadInfo->lockGarbage) != LOCK_OK)
+                {
+                    LogError("unable to unlock after locking");
+                }
+            }
+        }
+    }
+}
+
+
+static bool iothub_ll_message_callback(MESSAGE_CALLBACK_INFO* messageData, void* userContextCallback)
+{
+    bool result;
+    IOTHUB_QUEUE_CONTEXT* queue_context = (IOTHUB_QUEUE_CONTEXT*)userContextCallback;
+    if (queue_context == NULL)
+    {
+        LogError("invalid parameter userContextCallback(NULL)");
+        result = false;
+    }
+    else
+    {
+        USER_CALLBACK_INFO queue_cb_info;
+        queue_cb_info.type = CALLBACK_TYPE_MESSAGE;
+        queue_cb_info.userContextCallback = queue_context->userContextCallback;
+        queue_cb_info.iothub_callback.message_cb_info = messageData;
+        if (VECTOR_push_back(queue_context->iotHubClientHandle->saved_user_callback_list, &queue_cb_info, 1) == 0)
+        {
+            result = true;
+        }
+        else
+        {
+            LogError("message callback vector push failed.");
+            result = false;
+        }
+    }
+    return result;
+}
+
+static bool iothub_ll_inputmessage_callback(MESSAGE_CALLBACK_INFO* message_cb_info, void* userContextCallback)
+{
+    bool result;
+    IOTHUB_INPUTMESSAGE_CALLBACK_CONTEXT *inputMessageCallbackContext = (IOTHUB_INPUTMESSAGE_CALLBACK_CONTEXT *)userContextCallback;
+    if (inputMessageCallbackContext == NULL)
+    {
+        LogError("invalid parameter userContextCallback(NULL)");
+        result = false;
+    }
+    else
+    {
+        USER_CALLBACK_INFO queue_cb_info;
+        queue_cb_info.type = CALLBACK_TYPE_INPUTMESSAGE;
+        queue_cb_info.userContextCallback = inputMessageCallbackContext->userContextCallback;
+        queue_cb_info.iothub_callback.inputmessage_cb_info.eventHandlerCallback = inputMessageCallbackContext->eventHandlerCallback;
+        queue_cb_info.iothub_callback.inputmessage_cb_info.message_cb_info = message_cb_info;
+
+        if (VECTOR_push_back(inputMessageCallbackContext->iotHubClientHandle->saved_user_callback_list, &queue_cb_info, 1) == 0)
+        {
+            result = true;
+        }
+        else
+        {
+            LogError("message callback vector push failed.");
+            result = false;
+        }
+    }
+
+    return result;
+}
+
+static int make_method_calback_queue_context(USER_CALLBACK_INFO* queue_cb_info, const char* method_name, const unsigned char* payload, size_t size, METHOD_HANDLE method_id, IOTHUB_QUEUE_CONTEXT* queue_context)
+{
+    int result;
+    /* Codes_SRS_IOTHUB_MQTT_TRANSPORT_07_002: [ IOTHUB_CLIENT_INBOUND_DEVICE_METHOD_CALLBACK shall copy the method_name and payload. ] */
+    queue_cb_info->userContextCallback = queue_context->userContextCallback;
+    queue_cb_info->iothub_callback.method_cb_info.method_id = method_id;
+    if ((queue_cb_info->iothub_callback.method_cb_info.method_name = STRING_construct(method_name)) == NULL)
+    {
+        /* Codes_SRS_IOTHUB_MQTT_TRANSPORT_07_003: [ If a failure is encountered IOTHUB_CLIENT_INBOUND_DEVICE_METHOD_CALLBACK shall return a non-NULL value. ]*/
+        LogError("STRING_construct failed");
+        result = MU_FAILURE;
+    }
+    else
+    {
+        if ((queue_cb_info->iothub_callback.method_cb_info.payload = BUFFER_create(payload, size)) == NULL)
+        {
+            STRING_delete(queue_cb_info->iothub_callback.method_cb_info.method_name);
+            /* Codes_SRS_IOTHUB_MQTT_TRANSPORT_07_003: [ If a failure is encountered IOTHUB_CLIENT_INBOUND_DEVICE_METHOD_CALLBACK shall return a non-NULL value. ]*/
+            LogError("BUFFER_create failed");
+            result = MU_FAILURE;
+        }
+        else
+        {
+            if (VECTOR_push_back(queue_context->iotHubClientHandle->saved_user_callback_list, queue_cb_info, 1) == 0)
+            {
+                result = 0;
+            }
+            else
+            {
+                STRING_delete(queue_cb_info->iothub_callback.method_cb_info.method_name);
+                BUFFER_delete(queue_cb_info->iothub_callback.method_cb_info.payload);
+                /* Codes_SRS_IOTHUB_MQTT_TRANSPORT_07_003: [ If a failure is encountered IOTHUB_CLIENT_INBOUND_DEVICE_METHOD_CALLBACK shall return a non-NULL value. ]*/
+                LogError("VECTOR_push_back failed");
+                result = MU_FAILURE;
+            }
+        }
+    }
+    return result;
+}
+
+static int iothub_ll_device_method_callback(const char* method_name, const unsigned char* payload, size_t size, METHOD_HANDLE method_id, void* userContextCallback)
+{
+    int result;
+    /* Codes_SRS_IOTHUB_MQTT_TRANSPORT_07_001: [ if userContextCallback is NULL, IOTHUB_CLIENT_INBOUND_DEVICE_METHOD_CALLBACK shall return a nonNULL value. ] */
+    if (userContextCallback == NULL)
+    {
+        LogError("invalid parameter userContextCallback(NULL)");
+        result = MU_FAILURE;
+    }
+    else
+    {
+        IOTHUB_QUEUE_CONTEXT* queue_context = (IOTHUB_QUEUE_CONTEXT*)userContextCallback;
+
+        USER_CALLBACK_INFO queue_cb_info;
+        queue_cb_info.type = CALLBACK_TYPE_DEVICE_METHOD;
+
+        result = make_method_calback_queue_context(&queue_cb_info, method_name, payload, size, method_id, queue_context);
+        if (result != 0)
+        {
+            LogError("construction of method calback queue context failed");
+            result = MU_FAILURE;
+        }
+    }
+    return result;
+}
+
+static int iothub_ll_inbound_device_method_callback(const char* method_name, const unsigned char* payload, size_t size, METHOD_HANDLE method_id, void* userContextCallback)
+{
+    int result;
+    /* Codes_SRS_IOTHUB_MQTT_TRANSPORT_07_001: [ if userContextCallback is NULL, IOTHUB_CLIENT_INBOUND_DEVICE_METHOD_CALLBACK shall return a nonNULL value. ] */
+    if (userContextCallback == NULL)
+    {
+        LogError("invalid parameter userContextCallback(NULL)");
+        result = MU_FAILURE;
+    }
+    else
+    {
+        IOTHUB_QUEUE_CONTEXT* queue_context = (IOTHUB_QUEUE_CONTEXT*)userContextCallback;
+
+        USER_CALLBACK_INFO queue_cb_info;
+        queue_cb_info.type = CALLBACK_TYPE_INBOUD_DEVICE_METHOD;
+
+        result = make_method_calback_queue_context(&queue_cb_info, method_name, payload, size, method_id, queue_context);
+        if (result != 0)
+        {
+            LogError("construction of method calback queue context failed");
+            result = MU_FAILURE;
+        }
+    }
+    return result;
+}
+
+static void iothub_ll_connection_status_callback(IOTHUB_CLIENT_CONNECTION_STATUS result, IOTHUB_CLIENT_CONNECTION_STATUS_REASON reason, void* userContextCallback)
+{
+    IOTHUB_QUEUE_CONTEXT* queue_context = (IOTHUB_QUEUE_CONTEXT*)userContextCallback;
+    if (queue_context != NULL)
+    {
+        USER_CALLBACK_INFO queue_cb_info;
+        queue_cb_info.type = CALLBACK_TYPE_CONNECTION_STATUS;
+        queue_cb_info.userContextCallback = queue_context->userContextCallback;
+        queue_cb_info.iothub_callback.connection_status_cb_info.status_reason = reason;
+        queue_cb_info.iothub_callback.connection_status_cb_info.connection_status = result;
+        if (VECTOR_push_back(queue_context->iotHubClientHandle->saved_user_callback_list, &queue_cb_info, 1) != 0)
+        {
+            LogError("connection status callback vector push failed.");
+        }
+    }
+}
+
+static void iothub_ll_event_confirm_callback(IOTHUB_CLIENT_CONFIRMATION_RESULT result, void* userContextCallback)
+{
+    IOTHUB_QUEUE_CONTEXT* queue_context = (IOTHUB_QUEUE_CONTEXT*)userContextCallback;
+    if (queue_context != NULL)
+    {
+        USER_CALLBACK_INFO queue_cb_info;
+        queue_cb_info.type = CALLBACK_TYPE_EVENT_CONFIRM;
+        queue_cb_info.userContextCallback = queue_context->userContextCallback;
+        queue_cb_info.iothub_callback.event_confirm_cb_info.confirm_result = result;
+        queue_cb_info.iothub_callback.event_confirm_cb_info.eventConfirmationCallback = queue_context->callbackFunction.eventConfirmationCallback;
+        if (VECTOR_push_back(queue_context->iotHubClientHandle->saved_user_callback_list, &queue_cb_info, 1) != 0)
+        {
+            LogError("event confirm callback vector push failed.");
+        }
+        free(queue_context);
+    }
+}
+
+static void iothub_ll_reported_state_callback(int status_code, void* userContextCallback)
+{
+    IOTHUB_QUEUE_CONTEXT* queue_context = (IOTHUB_QUEUE_CONTEXT*)userContextCallback;
+    if (queue_context != NULL)
+    {
+        USER_CALLBACK_INFO queue_cb_info;
+        queue_cb_info.type = CALLBACK_TYPE_REPORTED_STATE;
+        queue_cb_info.userContextCallback = queue_context->userContextCallback;
+        queue_cb_info.iothub_callback.reported_state_cb_info.status_code = status_code;
+        queue_cb_info.iothub_callback.reported_state_cb_info.reportedStateCallback = queue_context->callbackFunction.reportedStateCallback;
+        if (VECTOR_push_back(queue_context->iotHubClientHandle->saved_user_callback_list, &queue_cb_info, 1) != 0)
+        {
+            LogError("reported state callback vector push failed.");
+        }
+        free(queue_context);
+    }
+}
+
+static void iothub_ll_device_twin_callback(DEVICE_TWIN_UPDATE_STATE update_state, const unsigned char* payLoad, size_t size, void* userContextCallback)
+{
+    IOTHUB_QUEUE_CONTEXT* queue_context = (IOTHUB_QUEUE_CONTEXT*)userContextCallback;
+    if (queue_context != NULL)
+    {
+        int push_to_vector;
+
+        USER_CALLBACK_INFO queue_cb_info;
+        queue_cb_info.type = CALLBACK_TYPE_DEVICE_TWIN;
+        queue_cb_info.userContextCallback = queue_context->userContextCallback;
+        queue_cb_info.iothub_callback.dev_twin_cb_info.update_state = update_state;
+        queue_cb_info.iothub_callback.dev_twin_cb_info.userCallback = NULL;
+        queue_cb_info.iothub_callback.dev_twin_cb_info.userContext = NULL;
+
+        if (payLoad == NULL)
+        {
+            queue_cb_info.iothub_callback.dev_twin_cb_info.payLoad = NULL;
+            queue_cb_info.iothub_callback.dev_twin_cb_info.size = 0;
+            push_to_vector = 0;
+        }
+        else
+        {
+            queue_cb_info.iothub_callback.dev_twin_cb_info.payLoad = (unsigned char*)malloc(size);
+            if (queue_cb_info.iothub_callback.dev_twin_cb_info.payLoad == NULL)
+            {
+                LogError("failure allocating payload in device twin callback.");
+                queue_cb_info.iothub_callback.dev_twin_cb_info.size = 0;
+                push_to_vector = MU_FAILURE;
+            }
+            else
+            {
+                (void)memcpy(queue_cb_info.iothub_callback.dev_twin_cb_info.payLoad, payLoad, size);
+                queue_cb_info.iothub_callback.dev_twin_cb_info.size = size;
+                push_to_vector = 0;
+            }
+        }
+        if (push_to_vector == 0)
+        {
+            if (VECTOR_push_back(queue_context->iotHubClientHandle->saved_user_callback_list, &queue_cb_info, 1) != 0)
+            {
+                if (queue_cb_info.iothub_callback.dev_twin_cb_info.payLoad != NULL)
+                {
+                    free(queue_cb_info.iothub_callback.dev_twin_cb_info.payLoad);
+                }
+                LogError("device twin callback userContextCallback vector push failed.");
+            }
+        }
+    }
+    else
+    {
+        LogError("device twin callback userContextCallback NULL");
+    }
+}
+
+static void iothub_ll_get_device_twin_async_callback(DEVICE_TWIN_UPDATE_STATE update_state, const unsigned char* payLoad, size_t size, void* userContextCallback)
+{
+    IOTHUB_QUEUE_CONSOLIDATED_CONTEXT* queue_context = (IOTHUB_QUEUE_CONSOLIDATED_CONTEXT*)userContextCallback;
+
+    if (queue_context != NULL)
+    {
+        USER_CALLBACK_INFO queue_cb_info;
+        queue_cb_info.type = CALLBACK_TYPE_DEVICE_TWIN;
+        queue_cb_info.userContextCallback = queue_context->userContext;
+        queue_cb_info.iothub_callback.dev_twin_cb_info.update_state = update_state;
+        queue_cb_info.iothub_callback.dev_twin_cb_info.userCallback = queue_context->userCallback.getTwin;
+        queue_cb_info.iothub_callback.dev_twin_cb_info.userContext = queue_context->userContext;
+
+        if (payLoad == NULL)
+        {
+            queue_cb_info.iothub_callback.dev_twin_cb_info.payLoad = NULL;
+            queue_cb_info.iothub_callback.dev_twin_cb_info.size = 0;
+        }
+        else
+        {
+            queue_cb_info.iothub_callback.dev_twin_cb_info.payLoad = (unsigned char*)malloc(size);
+
+            if (queue_cb_info.iothub_callback.dev_twin_cb_info.payLoad == NULL)
+            {
+                LogError("Failure allocating payload in get device twin callback.");
+                queue_cb_info.iothub_callback.dev_twin_cb_info.size = 0;
+            }
+            else
+            {
+                (void)memcpy(queue_cb_info.iothub_callback.dev_twin_cb_info.payLoad, payLoad, size);
+                queue_cb_info.iothub_callback.dev_twin_cb_info.size = size;
+            }
+        }
+
+        if (VECTOR_push_back(queue_context->iotHubClientHandle->saved_user_callback_list, &queue_cb_info, 1) != 0)
+        {
+            LogError("device twin callback userContextCallback vector push failed.");
+
+            if (queue_cb_info.iothub_callback.dev_twin_cb_info.payLoad != NULL)
+            {
+                free(queue_cb_info.iothub_callback.dev_twin_cb_info.payLoad);
+            }
+        }
+
+        free(queue_context);
+    }
+    else
+    {
+        LogError("Get device twin callback userContextCallback NULL");
+    }
+}
+
+static void dispatch_user_callbacks(IOTHUB_CLIENT_CORE_INSTANCE* iotHubClientInstance, VECTOR_HANDLE call_backs)
+{
+    size_t callbacks_length = VECTOR_size(call_backs);
+    size_t index;
+
+    IOTHUB_CLIENT_DEVICE_TWIN_CALLBACK desired_state_callback = NULL;
+    IOTHUB_CLIENT_CONNECTION_STATUS_CALLBACK connection_status_callback = NULL;
+    IOTHUB_CLIENT_DEVICE_METHOD_CALLBACK_ASYNC device_method_callback = NULL;
+    IOTHUB_CLIENT_INBOUND_DEVICE_METHOD_CALLBACK inbound_device_method_callback = NULL;
+    IOTHUB_CLIENT_MESSAGE_CALLBACK_ASYNC message_callback = NULL;
+    IOTHUB_CLIENT_CORE_HANDLE message_user_context_handle = NULL;
+    IOTHUB_CLIENT_CORE_HANDLE method_user_context_handle = NULL;
+
+    // Make a local copy of these callbacks, as we don't run with a lock held and iotHubClientInstance may change mid-run.
+    if (Lock(iotHubClientInstance->LockHandle) != LOCK_OK)
+    {
+        LogError("failed locking for dispatch_user_callbacks");
+    }
+    else
+    {
+        desired_state_callback = iotHubClientInstance->desired_state_callback;
+        connection_status_callback = iotHubClientInstance->connection_status_callback;
+        device_method_callback = iotHubClientInstance->device_method_callback;
+        inbound_device_method_callback = iotHubClientInstance->inbound_device_method_callback;
+        message_callback = iotHubClientInstance->message_callback;
+        if (iotHubClientInstance->method_user_context)
+        {
+            method_user_context_handle = iotHubClientInstance->method_user_context->iotHubClientHandle;
+        }
+        if (iotHubClientInstance->message_user_context)
+        {
+            message_user_context_handle = iotHubClientInstance->message_user_context->iotHubClientHandle;
+        }
+
+        (void)Unlock(iotHubClientInstance->LockHandle);
+    }
+
+
+    for (index = 0; index < callbacks_length; index++)
+    {
+        USER_CALLBACK_INFO* queued_cb = (USER_CALLBACK_INFO*)VECTOR_element(call_backs, index);
+        if (queued_cb == NULL)
+        {
+            LogError("VECTOR_element at index %zd is NULL.", index);
+        }
+        else
+        {
+            switch (queued_cb->type)
+            {
+            case CALLBACK_TYPE_DEVICE_TWIN:
+            {
+                // Callback if for GetTwinAsync
+                if (queued_cb->iothub_callback.dev_twin_cb_info.userCallback)
+                {
+                    queued_cb->iothub_callback.dev_twin_cb_info.userCallback(
+                        queued_cb->iothub_callback.dev_twin_cb_info.update_state,
+                        queued_cb->iothub_callback.dev_twin_cb_info.payLoad,
+                        queued_cb->iothub_callback.dev_twin_cb_info.size,
+                        queued_cb->iothub_callback.dev_twin_cb_info.userContext
+                    );
+                }
+                // Callback if for Desired properties.
+                else if (desired_state_callback)
+                {
+                    desired_state_callback(queued_cb->iothub_callback.dev_twin_cb_info.update_state, queued_cb->iothub_callback.dev_twin_cb_info.payLoad, queued_cb->iothub_callback.dev_twin_cb_info.size, queued_cb->userContextCallback);
+                }
+
+                if (queued_cb->iothub_callback.dev_twin_cb_info.payLoad)
+                {
+                    free(queued_cb->iothub_callback.dev_twin_cb_info.payLoad);
+                }
+                break;
+            }
+            case CALLBACK_TYPE_EVENT_CONFIRM:
+                if (queued_cb->iothub_callback.event_confirm_cb_info.eventConfirmationCallback)
+                {
+                    queued_cb->iothub_callback.event_confirm_cb_info.eventConfirmationCallback(queued_cb->iothub_callback.event_confirm_cb_info.confirm_result, queued_cb->userContextCallback);
+                }
+                break;
+            case CALLBACK_TYPE_REPORTED_STATE:
+                if (queued_cb->iothub_callback.reported_state_cb_info.reportedStateCallback)
+                {
+                    queued_cb->iothub_callback.reported_state_cb_info.reportedStateCallback(queued_cb->iothub_callback.reported_state_cb_info.status_code, queued_cb->userContextCallback);
+                }
+                break;
+            case CALLBACK_TYPE_CONNECTION_STATUS:
+                if (connection_status_callback)
+                {
+                    connection_status_callback(queued_cb->iothub_callback.connection_status_cb_info.connection_status, queued_cb->iothub_callback.connection_status_cb_info.status_reason, queued_cb->userContextCallback);
+                }
+                break;
+            case CALLBACK_TYPE_DEVICE_METHOD:
+                if (device_method_callback)
+                {
+                    const char* method_name = STRING_c_str(queued_cb->iothub_callback.method_cb_info.method_name);
+                    const unsigned char* payload = BUFFER_u_char(queued_cb->iothub_callback.method_cb_info.payload);
+                    size_t payload_len = BUFFER_length(queued_cb->iothub_callback.method_cb_info.payload);
+
+                    unsigned char* payload_resp = NULL;
+                    size_t response_size = 0;
+                    int status = device_method_callback(method_name, payload, payload_len, &payload_resp, &response_size, queued_cb->userContextCallback);
+
+                    if (payload_resp && (response_size > 0))
+                    {
+                        IOTHUB_CLIENT_RESULT result = IoTHubClientCore_DeviceMethodResponse(method_user_context_handle, queued_cb->iothub_callback.method_cb_info.method_id, (const unsigned char*)payload_resp, response_size, status);
+                        if (result != IOTHUB_CLIENT_OK)
+                        {
+                            LogError("IoTHubClientCore_LL_DeviceMethodResponse failed");
+                        }
+                    }
+
+                    BUFFER_delete(queued_cb->iothub_callback.method_cb_info.payload);
+                    STRING_delete(queued_cb->iothub_callback.method_cb_info.method_name);
+
+                    if (payload_resp)
+                    {
+                        free(payload_resp);
+                    }
+                }
+                break;
+            case CALLBACK_TYPE_INBOUD_DEVICE_METHOD:
+                if (inbound_device_method_callback)
+                {
+                    const char* method_name = STRING_c_str(queued_cb->iothub_callback.method_cb_info.method_name);
+                    const unsigned char* payload = BUFFER_u_char(queued_cb->iothub_callback.method_cb_info.payload);
+                    size_t payload_len = BUFFER_length(queued_cb->iothub_callback.method_cb_info.payload);
+
+                    inbound_device_method_callback(method_name, payload, payload_len, queued_cb->iothub_callback.method_cb_info.method_id, queued_cb->userContextCallback);
+
+                    BUFFER_delete(queued_cb->iothub_callback.method_cb_info.payload);
+                    STRING_delete(queued_cb->iothub_callback.method_cb_info.method_name);
+                }
+                break;
+            case CALLBACK_TYPE_MESSAGE:
+                if (message_callback && message_user_context_handle)
+                {
+                    IOTHUBMESSAGE_DISPOSITION_RESULT disposition = message_callback(queued_cb->iothub_callback.message_cb_info->messageHandle, queued_cb->userContextCallback);
+
+                    if (Lock(message_user_context_handle->LockHandle) == LOCK_OK)
+                    {
+                        IOTHUB_CLIENT_RESULT result = IoTHubClientCore_LL_SendMessageDisposition(message_user_context_handle->IoTHubClientLLHandle, queued_cb->iothub_callback.message_cb_info, disposition);
+                        (void)Unlock(message_user_context_handle->LockHandle);
+                        if (result != IOTHUB_CLIENT_OK)
+                        {
+                            LogError("IoTHubClientCore_LL_SendMessageDisposition failed");
+                        }
+                    }
+                    else
+                    {
+                        LogError("Lock failed");
+                    }
+                }
+                break;
+
+                case CALLBACK_TYPE_INPUTMESSAGE:
+                {
+                    const INPUTMESSAGE_CALLBACK_INFO *inputmessage_cb_info = &queued_cb->iothub_callback.inputmessage_cb_info;
+                    IOTHUBMESSAGE_DISPOSITION_RESULT disposition = inputmessage_cb_info->eventHandlerCallback(inputmessage_cb_info->message_cb_info->messageHandle, queued_cb->userContextCallback);
+
+                    if (Lock(iotHubClientInstance->LockHandle) == LOCK_OK)
+                    {
+                        IOTHUB_CLIENT_RESULT result = IoTHubClientCore_LL_SendMessageDisposition(iotHubClientInstance->IoTHubClientLLHandle, inputmessage_cb_info->message_cb_info, disposition);
+                        (void)Unlock(iotHubClientInstance->LockHandle);
+                        if (result != IOTHUB_CLIENT_OK)
+                        {
+                            LogError("IoTHubClient_LL_SendMessageDisposition failed");
+                        }
+                    }
+                    else
+                    {
+                        LogError("Lock failed");
+                    }
+                }
+                break;
+
+            default:
+                LogError("Invalid callback type '%s'", MU_ENUM_TO_STRING(USER_CALLBACK_TYPE, queued_cb->type));
+                break;
+            }
+        }
+    }
+    VECTOR_destroy(call_backs);
+}
+
+static void ScheduleWork_Thread_ForMultiplexing(void* iotHubClientHandle)
+{
+    IOTHUB_CLIENT_CORE_INSTANCE* iotHubClientInstance = (IOTHUB_CLIENT_CORE_INSTANCE*)iotHubClientHandle;
+
+    garbageCollectorImpl(iotHubClientInstance);
+    if (Lock(iotHubClientInstance->LockHandle) == LOCK_OK)
+    {
+        VECTOR_HANDLE call_backs = VECTOR_move(iotHubClientInstance->saved_user_callback_list);
+        (void)Unlock(iotHubClientInstance->LockHandle);
+
+        if (call_backs == NULL)
+        {
+            LogError("Failed moving user callbacks");
+        }
+        else
+        {
+            dispatch_user_callbacks(iotHubClientInstance, call_backs);
+        }
+    }
+    else
+    {
+        LogError("failed locking for ScheduleWork_Thread_ForMultiplexing");
+    }
+}
+
+static int ScheduleWork_Thread(void* threadArgument)
+{
+    IOTHUB_CLIENT_CORE_INSTANCE* iotHubClientInstance = (IOTHUB_CLIENT_CORE_INSTANCE*)threadArgument;
+    unsigned int sleeptime_in_ms = DO_WORK_FREQ_DEFAULT;
+
+    srand((unsigned int)get_time(NULL));
+
+    while (1)
+    {
+        if (Lock(iotHubClientInstance->LockHandle) == LOCK_OK)
+        {
+            /*Codes_SRS_IOTHUBCLIENT_01_038: [ The thread shall exit when IoTHubClient_Destroy is called. ]*/
+            if (iotHubClientInstance->StopThread)
+            {
+                (void)Unlock(iotHubClientInstance->LockHandle);
+                break; /*gets out of the thread*/
+            }
+            else
+            {
+                /* Codes_SRS_IOTHUBCLIENT_01_037: [The thread created by IoTHubClient_SendEvent or IoTHubClient_SetMessageCallback shall call IoTHubClientCore_LL_DoWork every 1 ms by default.] */
+                /* Codes_SRS_IOTHUBCLIENT_01_039: [All calls to IoTHubClientCore_LL_DoWork shall be protected by the lock created in IotHubClient_Create.] */
+                IoTHubClientCore_LL_DoWork(iotHubClientInstance->IoTHubClientLLHandle);
+
+                garbageCollectorImpl(iotHubClientInstance);
+                VECTOR_HANDLE call_backs = VECTOR_move(iotHubClientInstance->saved_user_callback_list);
+                sleeptime_in_ms = (unsigned int)iotHubClientInstance->do_work_freq_ms; // Update the sleepval within the locked thread.
+                (void)Unlock(iotHubClientInstance->LockHandle);
+                if (call_backs == NULL)
+                {
+                    LogError("VECTOR_move failed");
+                }
+                else
+                {
+                    dispatch_user_callbacks(iotHubClientInstance, call_backs);
+                }
+
+
+            }
+        }
+        else
+        {
+            /*Codes_SRS_IOTHUBCLIENT_01_040: [If acquiring the lock fails, IoTHubClientCore_LL_DoWork shall not be called.]*/
+            /*no code, shall retry*/
+        }
+        /* Codes_SRS_IOTHUBCLIENT_041_02: [The thread shall sleep for a specified time in ms as provided through IoTHubClientCore_SetOption, with a default of 1 ms ] */
+        (void)ThreadAPI_Sleep(sleeptime_in_ms);
+    }
+
+    ThreadAPI_Exit(0);
+    return 0;
+}
+
+static IOTHUB_CLIENT_RESULT StartWorkerThreadIfNeeded(IOTHUB_CLIENT_CORE_INSTANCE* iotHubClientInstance)
+{
+    IOTHUB_CLIENT_RESULT result;
+    if (iotHubClientInstance->TransportHandle == NULL)
+    {
+        if (iotHubClientInstance->ThreadHandle == NULL)
+        {
+            iotHubClientInstance->StopThread = 0;
+            if (ThreadAPI_Create(&iotHubClientInstance->ThreadHandle, ScheduleWork_Thread, iotHubClientInstance) != THREADAPI_OK)
+            {
+                LogError("ThreadAPI_Create failed");
+                iotHubClientInstance->ThreadHandle = NULL;
+                result = IOTHUB_CLIENT_ERROR;
+            }
+            else
+            {
+                result = IOTHUB_CLIENT_OK;
+            }
+        }
+        else
+        {
+            result = IOTHUB_CLIENT_OK;
+        }
+    }
+    else
+    {
+        /*Codes_SRS_IOTHUBCLIENT_17_012: [ If the transport connection is shared, the thread shall be started by calling IoTHubTransport_StartWorkerThread. ]*/
+        /*Codes_SRS_IOTHUBCLIENT_17_011: [ If the transport connection is shared, the thread shall be started by calling IoTHubTransport_StartWorkerThread*/
+        result = IoTHubTransport_StartWorkerThread(iotHubClientInstance->TransportHandle, iotHubClientInstance, ScheduleWork_Thread_ForMultiplexing);
+    }
+    return result;
+}
+
+static IOTHUB_CLIENT_CORE_INSTANCE* create_iothub_instance(CREATE_HUB_INSTANCE_TYPE create_hub_instance_type, const IOTHUB_CLIENT_CONFIG* config, TRANSPORT_HANDLE transportHandle, const char* connectionString, IOTHUB_CLIENT_TRANSPORT_PROVIDER protocol, const char* iothub_uri, const char* device_id)
+{
+    /* Codes_SRS_IOTHUBCLIENT_12_020: [** `IoTHubClient_CreateFromDeviceAuth` shall allocate a new `IoTHubClient` instance. **] */
+    IOTHUB_CLIENT_CORE_INSTANCE* result = (IOTHUB_CLIENT_CORE_INSTANCE*)malloc(sizeof(IOTHUB_CLIENT_CORE_INSTANCE));
+    (void)create_hub_instance_type;
+
+    /* Codes_SRS_IOTHUBCLIENT_12_021: [** If allocating memory for the new `IoTHubClient` instance fails, then `IoTHubClient_CreateFromDeviceAuth` shall return `NULL`. **] */
+    /* Codes_SRS_IOTHUBCLIENT_01_004: [If allocating memory for the new IoTHubClient instance fails, then IoTHubClient_Create shall return NULL.] */
+    if (result != NULL)
+    {
+        memset((void *)result, 0, sizeof(IOTHUB_CLIENT_CORE_INSTANCE));
+
+        /* Codes_SRS_IOTHUBCLIENT_41_02 [] */
+        result->do_work_freq_ms = DO_WORK_FREQ_DEFAULT;
+        /* Default currentMessageTimeout to NULL until it is set by SetOption */
+        result->currentMessageTimeout = 0;
+
+        /* Codes_SRS_IOTHUBCLIENT_01_029: [IoTHubClient_Create shall create a lock object to be used later for serializing IoTHubClient calls.] */
+        if ((result->saved_user_callback_list = VECTOR_create(sizeof(USER_CALLBACK_INFO))) == NULL)
+        {
+            LogError("Failed creating VECTOR");
+            free(result);
+            result = NULL;
+        }
+        else
+        {
+            /*Codes_SRS_IOTHUBCLIENT_02_060: [ IoTHubClient_Create shall create a SINGLYLINKEDLIST_HANDLE containing THREAD_HANDLE (created by future calls to IoTHubClient_UploadToBlobAsync). ]*/
+            if ((result->httpWorkerThreadInfoList = singlylinkedlist_create()) == NULL)
+            {
+                /*Codes_SRS_IOTHUBCLIENT_02_061: [ If creating the SINGLYLINKEDLIST_HANDLE fails then IoTHubClient_Create shall fail and return NULL. ]*/
+                LogError("unable to singlylinkedlist_create");
+                VECTOR_destroy(result->saved_user_callback_list);
+                free(result);
+                result = NULL;
+            }
+            else
+            {
+                result->TransportHandle = transportHandle;
+                result->created_with_transport_handle = 0;
+                if (config != NULL)
+                {
+                    if (transportHandle != NULL)
+                    {
+                        /*Codes_SRS_IOTHUBCLIENT_17_005: [ IoTHubClient_CreateWithTransport shall call IoTHubTransport_GetLock to get the transport lock to be used later for serializing IoTHubClient calls. ]*/
+                        result->LockHandle = IoTHubTransport_GetLock(transportHandle);
+                        if (result->LockHandle == NULL)
+                        {
+                            LogError("unable to IoTHubTransport_GetLock");
+                            result->IoTHubClientLLHandle = NULL;
+                        }
+                        else
+                        {
+                            IOTHUB_CLIENT_DEVICE_CONFIG deviceConfig;
+                            deviceConfig.deviceId = config->deviceId;
+                            deviceConfig.deviceKey = config->deviceKey;
+                            deviceConfig.protocol = config->protocol;
+                            deviceConfig.deviceSasToken = config->deviceSasToken;
+
+                            /*Codes_SRS_IOTHUBCLIENT_17_003: [ IoTHubClient_CreateWithTransport shall call IoTHubTransport_GetLLTransport on transportHandle to get lower layer transport. ]*/
+                            deviceConfig.transportHandle = IoTHubTransport_GetLLTransport(transportHandle);
+                            if (deviceConfig.transportHandle == NULL)
+                            {
+                                LogError("unable to IoTHubTransport_GetLLTransport");
+                                result->IoTHubClientLLHandle = NULL;
+                            }
+                            else
+                            {
+                                if (Lock(result->LockHandle) != LOCK_OK)
+                                {
+                                    LogError("unable to Lock");
+                                    result->IoTHubClientLLHandle = NULL;
+                                }
+                                else
+                                {
+                                    /*Codes_SRS_IOTHUBCLIENT_17_007: [ IoTHubClient_CreateWithTransport shall instantiate a new IoTHubClientCore_LL instance by calling IoTHubClientCore_LL_CreateWithTransport and passing the lower layer transport and config argument. ]*/
+                                    result->IoTHubClientLLHandle = IoTHubClientCore_LL_CreateWithTransport(&deviceConfig);
+                                    result->created_with_transport_handle = 1;
+                                    if (Unlock(result->LockHandle) != LOCK_OK)
+                                    {
+                                        LogError("unable to Unlock");
+                                        result->IoTHubClientLLHandle = NULL;
+                                    }
+                                }
+                            }
+                        }
+                    }
+                    else
+                    {
+                        result->LockHandle = Lock_Init();
+                        if (result->LockHandle == NULL)
+                        {
+                            /* Codes_SRS_IOTHUBCLIENT_01_030: [If creating the lock fails, then IoTHubClient_Create shall return NULL.] */
+                            /* Codes_SRS_IOTHUBCLIENT_01_031: [If IoTHubClient_Create fails, all resources allocated by it shall be freed.] */
+                            LogError("Failure creating Lock object");
+                            result->IoTHubClientLLHandle = NULL;
+                        }
+                        else
+                        {
+                            /* Codes_SRS_IOTHUBCLIENT_01_002: [IoTHubClient_Create shall instantiate a new IoTHubClientCore_LL instance by calling IoTHubClientCore_LL_Create and passing the config argument.] */
+                            result->IoTHubClientLLHandle = IoTHubClientCore_LL_Create(config);
+                        }
+                    }
+                }
+                else if (iothub_uri != NULL)
+                {
+#ifdef USE_PROV_MODULE
+                    /* Codes_SRS_IOTHUBCLIENT_12_022: [** `IoTHubClient_CreateFromDeviceAuth` shall create a lock object to be used later for serializing IoTHubClient calls. **] */
+                    result->LockHandle = Lock_Init();
+                    if (result->LockHandle == NULL)
+                    {
+                        /* Codes_SRS_IOTHUBCLIENT_12_023: [** If creating the lock fails, then IoTHubClient_CreateFromDeviceAuth shall return NULL. **] */
+                        LogError("Failure creating Lock object");
+                        result->IoTHubClientLLHandle = NULL;
+                    }
+                    else
+                    {
+                        /* Codes_SRS_IOTHUBCLIENT_12_025: [** `IoTHubClient_CreateFromDeviceAuth` shall instantiate a new `IoTHubClientCore_LL` instance by calling `IoTHubClientCore_LL_CreateFromDeviceAuth` and passing iothub_uri, device_id and protocol argument.  **] */
+                        result->IoTHubClientLLHandle = IoTHubClientCore_LL_CreateFromDeviceAuth(iothub_uri, device_id, protocol);
+                    }
+#else
+                    (void)device_id;
+                    LogError("Provisioning is not enabled for the build");
+                    result->IoTHubClientLLHandle = NULL;
+#endif
+                }
+#ifdef USE_EDGE_MODULES
+                else if (create_hub_instance_type == CREATE_HUB_INSTANCE_FROM_EDGE_ENVIRONMENT)
+                {
+                    result->LockHandle = Lock_Init();
+                    if (result->LockHandle == NULL)
+                    {
+                        /* Codes_SRS_IOTHUBCLIENT_01_030: [If creating the lock fails, then IoTHubClient_Create shall return NULL.] */
+                        /* Codes_SRS_IOTHUBCLIENT_01_031: [If IoTHubClient_Create fails, all resources allocated by it shall be freed.] */
+                        LogError("Failure creating Lock object");
+                        result->IoTHubClientLLHandle = NULL;
+                    }
+                    else
+                    {
+                        result->IoTHubClientLLHandle = IoTHubClientCore_LL_CreateFromEnvironment(protocol);
+                    }
+                }
+#endif
+                else
+                {
+                    result->LockHandle = Lock_Init();
+                    if (result->LockHandle == NULL)
+                    {
+                        /* Codes_SRS_IOTHUBCLIENT_01_030: [If creating the lock fails, then IoTHubClient_Create shall return NULL.] */
+                        /* Codes_SRS_IOTHUBCLIENT_01_031: [If IoTHubClient_Create fails, all resources allocated by it shall be freed.] */
+                        LogError("Failure creating Lock object");
+                        result->IoTHubClientLLHandle = NULL;
+                    }
+                    else
+                    {
+                        result->IoTHubClientLLHandle = IoTHubClientCore_LL_CreateFromConnectionString(connectionString, protocol);
+                    }
+                }
+
+                if (result->IoTHubClientLLHandle == NULL)
+                {
+                    /* Codes_SRS_IOTHUBCLIENT_01_003: [If IoTHubClientCore_LL_Create fails, then IoTHubClient_Create shall return NULL.] */
+                    /* Codes_SRS_IOTHUBCLIENT_01_031: [If IoTHubClient_Create fails, all resources allocated by it shall be freed.] */
+                    /* Codes_SRS_IOTHUBCLIENT_17_006: [ If IoTHubTransport_GetLock fails, then IoTHubClient_CreateWithTransport shall return NULL. ]*/
+                    if ((transportHandle == NULL) && (result->LockHandle != NULL))
+                    {
+                        Lock_Deinit(result->LockHandle);
+                    }
+                    singlylinkedlist_destroy(result->httpWorkerThreadInfoList);
+                    LogError("Failure creating iothub handle");
+                    VECTOR_destroy(result->saved_user_callback_list);
+                    free(result);
+                    result = NULL;
+                }
+                else
+                {
+                    result->ThreadHandle = NULL;
+                    result->desired_state_callback = NULL;
+                    result->devicetwin_user_context = NULL;
+                    result->connection_status_callback = NULL;
+                    result->connection_status_user_context = NULL;
+                    result->message_callback = NULL;
+                    result->message_user_context = NULL;
+                    result->method_user_context = NULL;
+                }
+            }
+        }
+    }
+    return result;
+}
+
+IOTHUB_CLIENT_CORE_HANDLE IoTHubClientCore_CreateFromConnectionString(const char* connectionString, IOTHUB_CLIENT_TRANSPORT_PROVIDER protocol)
+{
+    IOTHUB_CLIENT_CORE_INSTANCE* result;
+
+    if (connectionString == NULL)
+    {
+        LogError("Input parameter is NULL: connectionString");
+        result = NULL;
+    }
+    else if (protocol == NULL)
+    {
+        LogError("Input parameter is NULL: protocol");
+        result = NULL;
+    }
+    else
+    {
+        result = create_iothub_instance(CREATE_HUB_INSTANCE_FROM_CONNECTION_STRING, NULL, NULL, connectionString, protocol, NULL, NULL);
+    }
+    return result;
+}
+
+IOTHUB_CLIENT_CORE_HANDLE IoTHubClientCore_Create(const IOTHUB_CLIENT_CONFIG* config)
+{
+    IOTHUB_CLIENT_CORE_INSTANCE* result;
+    if (config == NULL)
+    {
+        LogError("Input parameter is NULL: IOTHUB_CLIENT_CONFIG");
+        result = NULL;
+    }
+    else
+    {
+        result = create_iothub_instance(CREATE_HUB_INSTANCE_FROM_CLIENT_CONFIG, config, NULL, NULL, NULL, NULL, NULL);
+    }
+    return result;
+}
+
+IOTHUB_CLIENT_CORE_HANDLE IoTHubClientCore_CreateWithTransport(TRANSPORT_HANDLE transportHandle, const IOTHUB_CLIENT_CONFIG* config)
+{
+    IOTHUB_CLIENT_CORE_INSTANCE* result;
+    /*Codes_SRS_IOTHUBCLIENT_17_013: [ IoTHubClient_CreateWithTransport shall return NULL if transportHandle is NULL. ]*/
+    /*Codes_SRS_IOTHUBCLIENT_17_014: [ IoTHubClient_CreateWithTransport shall return NULL if config is NULL. ]*/
+    if (transportHandle == NULL || config == NULL)
+    {
+        LogError("invalid parameter TRANSPORT_HANDLE transportHandle=%p, const IOTHUB_CLIENT_CONFIG* config=%p", transportHandle, config);
+        result = NULL;
+    }
+    else
+    {
+        result = create_iothub_instance(CREATE_HUB_INSTANCE_FROM_TRANSPORT, config, transportHandle, NULL, NULL, NULL, NULL);
+    }
+    return result;
+}
+
+IOTHUB_CLIENT_CORE_HANDLE IoTHubClientCore_CreateFromDeviceAuth(const char* iothub_uri, const char* device_id, IOTHUB_CLIENT_TRANSPORT_PROVIDER protocol)
+{
+    IOTHUB_CLIENT_CORE_INSTANCE* result;
+
+    /* Codes_SRS_IOTHUBCLIENT_12_019: [** `IoTHubClient_CreateFromDeviceAuth` shall verify the input parameters and if any of them `NULL` then return `NULL`. **] */
+    if (iothub_uri == NULL)
+    {
+        LogError("Input parameter is NULL: iothub_uri");
+        result = NULL;
+    }
+    else if (device_id == NULL)
+    {
+        LogError("Input parameter is NULL: device_id");
+        result = NULL;
+    }
+    else if (protocol == NULL)
+    {
+        LogError("Input parameter is NULL: protocol");
+        result = NULL;
+    }
+    else
+    {
+        /* Codes_SRS_IOTHUBCLIENT_12_020: [** `IoTHubClient_CreateFromDeviceAuth` shall allocate a new `IoTHubClient` instance. **] */
+        /* Codes_SRS_IOTHUBCLIENT_12_021: [** If allocating memory for the new `IoTHubClient` instance fails, then `IoTHubClient_CreateFromDeviceAuth` shall return `NULL`. **] */
+        /* Codes_SRS_IOTHUBCLIENT_12_022: [** `IoTHubClient_CreateFromDeviceAuth` shall create a lock object to be used later for serializing IoTHubClient calls. **] */
+        /* Codes_SRS_IOTHUBCLIENT_12_023: [** If creating the lock fails, then IoTHubClient_CreateFromDeviceAuth shall return NULL. **] */
+        /* Codes_SRS_IOTHUBCLIENT_12_024: [** If IoTHubClient_CreateFromDeviceAuth fails, all resources allocated by it shall be freed. **] */
+        /* Codes_SRS_IOTHUBCLIENT_12_025: [** `IoTHubClient_CreateFromDeviceAuth` shall instantiate a new `IoTHubClientCore_LL` instance by calling `IoTHubClientCore_LL_CreateFromDeviceAuth` and passing iothub_uri, device_id and protocol argument.  **] */
+        result = create_iothub_instance(CREATE_HUB_INSTANCE_FROM_DEVICE_AUTH, NULL, NULL, NULL, protocol, iothub_uri, device_id);
+    }
+    return result;
+}
+
+#ifdef USE_EDGE_MODULES
+IOTHUB_CLIENT_CORE_HANDLE IoTHubClientCore_CreateFromEnvironment(IOTHUB_CLIENT_TRANSPORT_PROVIDER protocol)
+{
+    return create_iothub_instance(CREATE_HUB_INSTANCE_FROM_EDGE_ENVIRONMENT, NULL, NULL, NULL, protocol, NULL, NULL);
+}
+#endif
+
+
+/* Codes_SRS_IOTHUBCLIENT_01_005: [IoTHubClient_Destroy shall free all resources associated with the iotHubClientHandle instance.] */
+void IoTHubClientCore_Destroy(IOTHUB_CLIENT_CORE_HANDLE iotHubClientHandle)
+{
+    /* Codes_SRS_IOTHUBCLIENT_01_008: [IoTHubClient_Destroy shall do nothing if parameter iotHubClientHandle is NULL.] */
+    if (iotHubClientHandle != NULL)
+    {
+        bool joinClientThread;
+        bool joinTransportThread;
+        size_t vector_size;
+
+        IOTHUB_CLIENT_CORE_INSTANCE* iotHubClientInstance = (IOTHUB_CLIENT_CORE_INSTANCE*)iotHubClientHandle;
+
+        if (iotHubClientInstance->TransportHandle != NULL)
+        {
+            /*Codes_SRS_IOTHUBCLIENT_01_007: [ The thread created as part of executing IoTHubClient_SendEventAsync or IoTHubClient_SetNotificationMessageCallback shall be joined. ]*/
+            joinTransportThread = IoTHubTransport_SignalEndWorkerThread(iotHubClientInstance->TransportHandle, iotHubClientHandle);
+        }
+        else
+        {
+            joinTransportThread = false;
+        }
+
+        /*Codes_SRS_IOTHUBCLIENT_02_043: [ IoTHubClient_Destroy shall lock the serializing lock and signal the worker thread (if any) to end ]*/
+        if (Lock(iotHubClientInstance->LockHandle) != LOCK_OK)
+        {
+            LogError("unable to Lock - - will still proceed to try to end the thread without locking");
+        }
+
+        if (iotHubClientInstance->ThreadHandle != NULL)
+        {
+            iotHubClientInstance->StopThread = 1;
+            joinClientThread = true;
+        }
+        else
+        {
+            joinClientThread = false;
+        }
+
+        /*Codes_SRS_IOTHUBCLIENT_02_045: [ IoTHubClient_Destroy shall unlock the serializing lock. ]*/
+        if (Unlock(iotHubClientInstance->LockHandle) != LOCK_OK)
+        {
+            LogError("unable to Unlock");
+        }
+
+        if (joinClientThread == true)
+        {
+            int res;
+            /*Codes_SRS_IOTHUBCLIENT_01_007: [ The thread created as part of executing IoTHubClient_SendEventAsync or IoTHubClient_SetNotificationMessageCallback shall be joined. ]*/
+            if (ThreadAPI_Join(iotHubClientInstance->ThreadHandle, &res) != THREADAPI_OK)
+            {
+                LogError("ThreadAPI_Join failed");
+            }
+        }
+
+        if (joinTransportThread == true)
+        {
+            /*Codes_SRS_IOTHUBCLIENT_01_007: [ The thread created as part of executing IoTHubClient_SendEventAsync or IoTHubClient_SetNotificationMessageCallback shall be joined. ]*/
+            IoTHubTransport_JoinWorkerThread(iotHubClientInstance->TransportHandle, iotHubClientHandle);
+        }
+
+        if (Lock(iotHubClientInstance->LockHandle) != LOCK_OK)
+        {
+            LogError("unable to Lock - - will still proceed to try to end the thread without locking");
+        }
+
+        /*Codes_SRS_IOTHUBCLIENT_02_069: [ IoTHubClient_Destroy shall free all data created by IoTHubClient_UploadToBlobAsync ]*/
+        /*wait for all uploading threads to finish*/
+        while (singlylinkedlist_get_head_item(iotHubClientInstance->httpWorkerThreadInfoList) != NULL)
+        {
+            garbageCollectorImpl(iotHubClientInstance);
+        }
+
+        if (iotHubClientInstance->httpWorkerThreadInfoList != NULL)
+        {
+            singlylinkedlist_destroy(iotHubClientInstance->httpWorkerThreadInfoList);
+        }
+
+        /* Codes_SRS_IOTHUBCLIENT_01_006: [That includes destroying the IoTHubClientCore_LL instance by calling IoTHubClientCore_LL_Destroy.] */
+        IoTHubClientCore_LL_Destroy(iotHubClientInstance->IoTHubClientLLHandle);
+
+        if (Unlock(iotHubClientInstance->LockHandle) != LOCK_OK)
+        {
+            LogError("unable to Unlock");
+        }
+
+
+        vector_size = VECTOR_size(iotHubClientInstance->saved_user_callback_list);
+        size_t index = 0;
+        for (index = 0; index < vector_size; index++)
+        {
+            USER_CALLBACK_INFO* queue_cb_info = (USER_CALLBACK_INFO*)VECTOR_element(iotHubClientInstance->saved_user_callback_list, index);
+            if (queue_cb_info != NULL)
+            {
+                if ((queue_cb_info->type == CALLBACK_TYPE_DEVICE_METHOD) || (queue_cb_info->type == CALLBACK_TYPE_INBOUD_DEVICE_METHOD))
+                {
+                    STRING_delete(queue_cb_info->iothub_callback.method_cb_info.method_name);
+                    BUFFER_delete(queue_cb_info->iothub_callback.method_cb_info.payload);
+                }
+                else if (queue_cb_info->type == CALLBACK_TYPE_DEVICE_TWIN)
+                {
+                    if (queue_cb_info->iothub_callback.dev_twin_cb_info.payLoad != NULL)
+                    {
+                        free(queue_cb_info->iothub_callback.dev_twin_cb_info.payLoad);
+                    }
+                }
+                else if (queue_cb_info->type == CALLBACK_TYPE_EVENT_CONFIRM)
+                {
+                    if (queue_cb_info->iothub_callback.event_confirm_cb_info.eventConfirmationCallback)
+                    {
+                        queue_cb_info->iothub_callback.event_confirm_cb_info.eventConfirmationCallback(queue_cb_info->iothub_callback.event_confirm_cb_info.confirm_result, queue_cb_info->userContextCallback);
+                    }
+                }
+                else if (queue_cb_info->type == CALLBACK_TYPE_REPORTED_STATE)
+                {
+                    if (queue_cb_info->iothub_callback.reported_state_cb_info.reportedStateCallback)
+                    {
+                        queue_cb_info->iothub_callback.reported_state_cb_info.reportedStateCallback(queue_cb_info->iothub_callback.reported_state_cb_info.status_code, queue_cb_info->userContextCallback);
+                    }
+                }
+            }
+        }
+        VECTOR_destroy(iotHubClientInstance->saved_user_callback_list);
+
+        if (iotHubClientInstance->TransportHandle == NULL)
+        {
+            /* Codes_SRS_IOTHUBCLIENT_01_032: [If the lock was allocated in IoTHubClient_Create, it shall be also freed..] */
+            Lock_Deinit(iotHubClientInstance->LockHandle);
+        }
+        if (iotHubClientInstance->devicetwin_user_context != NULL)
+        {
+            free(iotHubClientInstance->devicetwin_user_context);
+        }
+        if (iotHubClientInstance->connection_status_user_context != NULL)
+        {
+            free(iotHubClientInstance->connection_status_user_context);
+        }
+        if (iotHubClientInstance->message_user_context != NULL)
+        {
+            free(iotHubClientInstance->message_user_context);
+        }
+        if (iotHubClientInstance->method_user_context != NULL)
+        {
+            free(iotHubClientInstance->method_user_context);
+        }
+        free(iotHubClientInstance);
+    }
+}
+
+IOTHUB_CLIENT_RESULT IoTHubClientCore_SendEventAsync(IOTHUB_CLIENT_CORE_HANDLE iotHubClientHandle, IOTHUB_MESSAGE_HANDLE eventMessageHandle, IOTHUB_CLIENT_EVENT_CONFIRMATION_CALLBACK eventConfirmationCallback, void* userContextCallback)
+{
+    IOTHUB_CLIENT_RESULT result;
+
+    if (iotHubClientHandle == NULL)
+    {
+        /* Codes_SRS_IOTHUBCLIENT_01_011: [If iotHubClientHandle is NULL, IoTHubClient_SendEventAsync shall return IOTHUB_CLIENT_INVALID_ARG.] */
+        result = IOTHUB_CLIENT_INVALID_ARG;
+        LogError("NULL iothubClientHandle");
+    }
+    else
+    {
+        IOTHUB_CLIENT_CORE_INSTANCE* iotHubClientInstance = (IOTHUB_CLIENT_CORE_INSTANCE*)iotHubClientHandle;
+
+        /* Codes_SRS_IOTHUBCLIENT_01_009: [IoTHubClient_SendEventAsync shall start the worker thread if it was not previously started.] */
+        if ((result = StartWorkerThreadIfNeeded(iotHubClientInstance)) != IOTHUB_CLIENT_OK)
+        {
+            /* Codes_SRS_IOTHUBCLIENT_01_010: [If starting the thread fails, IoTHubClient_SendEventAsync shall return IOTHUB_CLIENT_ERROR.] */
+            result = IOTHUB_CLIENT_ERROR;
+            LogError("Could not start worker thread");
+        }
+        else
+        {
+            /* Codes_SRS_IOTHUBCLIENT_01_025: [IoTHubClient_SendEventAsync shall be made thread-safe by using the lock created in IoTHubClient_Create.] */
+            if (Lock(iotHubClientInstance->LockHandle) != LOCK_OK)
+            {
+                /* Codes_SRS_IOTHUBCLIENT_01_026: [If acquiring the lock fails, IoTHubClient_SendEventAsync shall return IOTHUB_CLIENT_ERROR.] */
+                result = IOTHUB_CLIENT_ERROR;
+                LogError("Could not acquire lock");
+            }
+            else
+            {
+                if (iotHubClientInstance->created_with_transport_handle != 0 || eventConfirmationCallback == NULL)
+                {
+                    result = IoTHubClientCore_LL_SendEventAsync(iotHubClientInstance->IoTHubClientLLHandle, eventMessageHandle, eventConfirmationCallback, userContextCallback);
+                }
+                else
+                {
+                    /* Codes_SRS_IOTHUBCLIENT_07_001: [ IoTHubClient_SendEventAsync shall allocate a IOTHUB_QUEUE_CONTEXT object to be sent to the IoTHubClientCore_LL_SendEventAsync function as a user context. ] */
+                    IOTHUB_QUEUE_CONTEXT* queue_context = (IOTHUB_QUEUE_CONTEXT*)malloc(sizeof(IOTHUB_QUEUE_CONTEXT));
+                    if (queue_context == NULL)
+                    {
+                        result = IOTHUB_CLIENT_ERROR;
+                        LogError("Failed allocating QUEUE_CONTEXT");
+                    }
+                    else
+                    {
+                        queue_context->iotHubClientHandle = iotHubClientInstance;
+                        queue_context->userContextCallback = userContextCallback;
+                        queue_context->callbackFunction.eventConfirmationCallback = eventConfirmationCallback;
+                        /* Codes_SRS_IOTHUBCLIENT_01_012: [IoTHubClient_SendEventAsync shall call IoTHubClientCore_LL_SendEventAsync, while passing the IoTHubClientCore_LL handle created by IoTHubClient_Create and the parameters eventMessageHandle, eventConfirmationCallback and userContextCallback.] */
+                        /* Codes_SRS_IOTHUBCLIENT_01_013: [When IoTHubClientCore_LL_SendEventAsync is called, IoTHubClient_SendEventAsync shall return the result of IoTHubClientCore_LL_SendEventAsync.] */
+                        result = IoTHubClientCore_LL_SendEventAsync(iotHubClientInstance->IoTHubClientLLHandle, eventMessageHandle, iothub_ll_event_confirm_callback, queue_context);
+                        if (result != IOTHUB_CLIENT_OK)
+                        {
+                            LogError("IoTHubClientCore_LL_SendEventAsync failed");
+                            free(queue_context);
+                        }
+                    }
+                }
+
+                /* Codes_SRS_IOTHUBCLIENT_01_025: [IoTHubClient_SendEventAsync shall be made thread-safe by using the lock created in IoTHubClient_Create.] */
+                (void)Unlock(iotHubClientInstance->LockHandle);
+            }
+        }
+    }
+
+    return result;
+}
+
+IOTHUB_CLIENT_RESULT IoTHubClientCore_GetSendStatus(IOTHUB_CLIENT_CORE_HANDLE iotHubClientHandle, IOTHUB_CLIENT_STATUS *iotHubClientStatus)
+{
+    IOTHUB_CLIENT_RESULT result;
+
+    if (iotHubClientHandle == NULL)
+    {
+        /* Codes_SRS_IOTHUBCLIENT_01_023: [If iotHubClientHandle is NULL, IoTHubClient_ GetSendStatus shall return IOTHUB_CLIENT_INVALID_ARG.] */
+        result = IOTHUB_CLIENT_INVALID_ARG;
+        LogError("NULL iothubClientHandle");
+    }
+    else
+    {
+        IOTHUB_CLIENT_CORE_INSTANCE* iotHubClientInstance = (IOTHUB_CLIENT_CORE_INSTANCE*)iotHubClientHandle;
+
+        /* Codes_SRS_IOTHUBCLIENT_01_033: [IoTHubClient_GetSendStatus shall be made thread-safe by using the lock created in IoTHubClient_Create.] */
+        if (Lock(iotHubClientInstance->LockHandle) != LOCK_OK)
+        {
+            /* Codes_SRS_IOTHUBCLIENT_01_034: [If acquiring the lock fails, IoTHubClient_GetSendStatus shall return IOTHUB_CLIENT_ERROR.] */
+            result = IOTHUB_CLIENT_ERROR;
+            LogError("Could not acquire lock");
+        }
+        else
+        {
+            /* Codes_SRS_IOTHUBCLIENT_01_022: [IoTHubClient_GetSendStatus shall call IoTHubClientCore_LL_GetSendStatus, while passing the IoTHubClientCore_LL handle created by IoTHubClient_Create and the parameter iotHubClientStatus.] */
+            /* Codes_SRS_IOTHUBCLIENT_01_024: [Otherwise, IoTHubClient_GetSendStatus shall return the result of IoTHubClientCore_LL_GetSendStatus.] */
+            result = IoTHubClientCore_LL_GetSendStatus(iotHubClientInstance->IoTHubClientLLHandle, iotHubClientStatus);
+
+            /* Codes_SRS_IOTHUBCLIENT_01_033: [IoTHubClient_GetSendStatus shall be made thread-safe by using the lock created in IoTHubClient_Create.] */
+            (void)Unlock(iotHubClientInstance->LockHandle);
+        }
+    }
+
+    return result;
+}
+
+IOTHUB_CLIENT_RESULT IoTHubClientCore_SetMessageCallback(IOTHUB_CLIENT_CORE_HANDLE iotHubClientHandle, IOTHUB_CLIENT_MESSAGE_CALLBACK_ASYNC messageCallback, void* userContextCallback)
+{
+    IOTHUB_CLIENT_RESULT result;
+
+    if (iotHubClientHandle == NULL)
+    {
+        /* Codes_SRS_IOTHUBCLIENT_01_016: [If iotHubClientHandle is NULL, IoTHubClient_SetMessageCallback shall return IOTHUB_CLIENT_INVALID_ARG.] */
+        result = IOTHUB_CLIENT_INVALID_ARG;
+        LogError("NULL iothubClientHandle");
+    }
+    else
+    {
+        IOTHUB_CLIENT_CORE_INSTANCE* iotHubClientInstance = (IOTHUB_CLIENT_CORE_INSTANCE*)iotHubClientHandle;
+
+        /* Codes_SRS_IOTHUBCLIENT_01_014: [IoTHubClient_SetMessageCallback shall start the worker thread if it was not previously started.] */
+        if ((result = StartWorkerThreadIfNeeded(iotHubClientInstance)) != IOTHUB_CLIENT_OK)
+        {
+            /* Codes_SRS_IOTHUBCLIENT_01_015: [If starting the thread fails, IoTHubClient_SetMessageCallback shall return IOTHUB_CLIENT_ERROR.] */
+            result = IOTHUB_CLIENT_ERROR;
+            LogError("Could not start worker thread");
+        }
+        else
+        {
+            /* Codes_SRS_IOTHUBCLIENT_01_027: [IoTHubClient_SetMessageCallback shall be made thread-safe by using the lock created in IoTHubClient_Create.] */
+            if (Lock(iotHubClientInstance->LockHandle) != LOCK_OK)
+            {
+                /* Codes_SRS_IOTHUBCLIENT_01_028: [If acquiring the lock fails, IoTHubClient_SetMessageCallback shall return IOTHUB_CLIENT_ERROR.] */
+                result = IOTHUB_CLIENT_ERROR;
+                LogError("Could not acquire lock");
+            }
+            else
+            {
+                if (iotHubClientInstance->created_with_transport_handle == 0)
+                {
+                    iotHubClientInstance->message_callback = messageCallback;
+                }
+                if (iotHubClientInstance->message_user_context != NULL)
+                {
+                    free(iotHubClientInstance->message_user_context);
+                    iotHubClientInstance->message_user_context = NULL;
+                }
+                if (messageCallback == NULL)
+                {
+                    result = IoTHubClientCore_LL_SetMessageCallback_Ex(iotHubClientInstance->IoTHubClientLLHandle, NULL, iotHubClientInstance->message_user_context);
+                }
+                else if (iotHubClientInstance->created_with_transport_handle != 0)
+                {
+                    result = IoTHubClientCore_LL_SetMessageCallback(iotHubClientInstance->IoTHubClientLLHandle, messageCallback, userContextCallback);
+                }
+                else
+                {
+                    iotHubClientInstance->message_user_context = (IOTHUB_QUEUE_CONTEXT*)malloc(sizeof(IOTHUB_QUEUE_CONTEXT));
+                    if (iotHubClientInstance->message_user_context == NULL)
+                    {
+                        result = IOTHUB_CLIENT_ERROR;
+                        LogError("Failed allocating QUEUE_CONTEXT");
+                    }
+                    else
+                    {
+                        iotHubClientInstance->message_user_context->iotHubClientHandle = iotHubClientHandle;
+                        iotHubClientInstance->message_user_context->userContextCallback = userContextCallback;
+
+                        /* Codes_SRS_IOTHUBCLIENT_01_017: [IoTHubClient_SetMessageCallback shall call IoTHubClientCore_LL_SetMessageCallback_Ex, while passing the IoTHubClientCore_LL handle created by IoTHubClient_Create and the local iothub_ll_message_callback wrapper of messageCallback and userContextCallback.] */
+                        /* Codes_SRS_IOTHUBCLIENT_01_018: [When IoTHubClientCore_LL_SetMessageCallback_Ex is called, IoTHubClient_SetMessageCallback shall return the result of IoTHubClientCore_LL_SetMessageCallback_Ex.] */
+                        result = IoTHubClientCore_LL_SetMessageCallback_Ex(iotHubClientInstance->IoTHubClientLLHandle, iothub_ll_message_callback, iotHubClientInstance->message_user_context);
+                        if (result != IOTHUB_CLIENT_OK)
+                        {
+                            LogError("IoTHubClientCore_LL_SetMessageCallback failed");
+                            free(iotHubClientInstance->message_user_context);
+                            iotHubClientInstance->message_user_context = NULL;
+                        }
+                    }
+                }
+
+                /* Codes_SRS_IOTHUBCLIENT_01_027: [IoTHubClient_SetMessageCallback shall be made thread-safe by using the lock created in IoTHubClient_Create.] */
+                (void)Unlock(iotHubClientInstance->LockHandle);
+            }
+        }
+    }
+
+    return result;
+}
+
+IOTHUB_CLIENT_RESULT IoTHubClientCore_SetConnectionStatusCallback(IOTHUB_CLIENT_CORE_HANDLE iotHubClientHandle, IOTHUB_CLIENT_CONNECTION_STATUS_CALLBACK connectionStatusCallback, void * userContextCallback)
+{
+    IOTHUB_CLIENT_RESULT result;
+
+    if (iotHubClientHandle == NULL)
+    {
+        /* Codes_SRS_IOTHUBCLIENT_25_076: [** If `iotHubClientHandle` is `NULL`, `IoTHubClient_SetRetryPolicy` shall return `IOTHUB_CLIENT_INVALID_ARG`. ] */
+        result = IOTHUB_CLIENT_INVALID_ARG;
+        LogError("NULL iothubClientHandle");
+    }
+    else
+    {
+        IOTHUB_CLIENT_CORE_INSTANCE* iotHubClientInstance = (IOTHUB_CLIENT_CORE_INSTANCE*)iotHubClientHandle;
+
+        /* Codes_SRS_IOTHUBCLIENT_25_081: [ `IoTHubClient_SetConnectionStatusCallback` shall start the worker thread if it was not previously started. ]*/
+        if ((result = StartWorkerThreadIfNeeded(iotHubClientInstance)) != IOTHUB_CLIENT_OK)
+        {
+            /* Codes_SRS_IOTHUBCLIENT_25_083: [ If starting the thread fails, `IoTHubClient_SetConnectionStatusCallback` shall return `IOTHUB_CLIENT_ERROR`. ]*/
+            result = IOTHUB_CLIENT_ERROR;
+            LogError("Could not start worker thread");
+        }
+        else
+        {
+            /* Codes_SRS_IOTHUBCLIENT_25_087: [ `IoTHubClient_SetConnectionStatusCallback` shall be made thread-safe by using the lock created in `IoTHubClient_Create`. ] */
+            if (Lock(iotHubClientInstance->LockHandle) != LOCK_OK)
+            {
+                /* Codes_SRS_IOTHUBCLIENT_25_088: [ If acquiring the lock fails, `IoTHubClient_SetConnectionStatusCallback` shall return `IOTHUB_CLIENT_ERROR`. ]*/
+                result = IOTHUB_CLIENT_ERROR;
+                LogError("Could not acquire lock");
+            }
+            else
+            {
+                if (iotHubClientInstance->created_with_transport_handle == 0)
+                {
+                    iotHubClientInstance->connection_status_callback = connectionStatusCallback;
+                }
+
+                if (iotHubClientInstance->created_with_transport_handle != 0 || connectionStatusCallback == NULL)
+                {
+                    /* Codes_SRS_IOTHUBCLIENT_25_085: [ `IoTHubClient_SetConnectionStatusCallback` shall call `IoTHubClientCore_LL_SetConnectionStatusCallback`, while passing the `IoTHubClientCore_LL` handle created by `IoTHubClient_Create` and the parameters `connectionStatusCallback` and `userContextCallback`. ]*/
+                    result = IoTHubClientCore_LL_SetConnectionStatusCallback(iotHubClientInstance->IoTHubClientLLHandle, connectionStatusCallback, userContextCallback);
+                }
+                else
+                {
+                    if (iotHubClientInstance->connection_status_user_context != NULL)
+                    {
+                        free(iotHubClientInstance->connection_status_user_context);
+                    }
+                    iotHubClientInstance->connection_status_user_context = (IOTHUB_QUEUE_CONTEXT*)malloc(sizeof(IOTHUB_QUEUE_CONTEXT));
+                    if (iotHubClientInstance->connection_status_user_context == NULL)
+                    {
+                        result = IOTHUB_CLIENT_ERROR;
+                        LogError("Failed allocating QUEUE_CONTEXT");
+                    }
+                    else
+                    {
+                        iotHubClientInstance->connection_status_user_context->iotHubClientHandle = iotHubClientInstance;
+                        iotHubClientInstance->connection_status_user_context->userContextCallback = userContextCallback;
+
+                        /* Codes_SRS_IOTHUBCLIENT_25_085: [ `IoTHubClient_SetConnectionStatusCallback` shall call `IoTHubClientCore_LL_SetConnectionStatusCallback`, while passing the `IoTHubClientCore_LL` handle created by `IoTHubClient_Create` and the parameters `connectionStatusCallback` and `userContextCallback`. ]*/
+                        result = IoTHubClientCore_LL_SetConnectionStatusCallback(iotHubClientInstance->IoTHubClientLLHandle, iothub_ll_connection_status_callback, iotHubClientInstance->connection_status_user_context);
+                        if (result != IOTHUB_CLIENT_OK)
+                        {
+                            LogError("IoTHubClientCore_LL_SetConnectionStatusCallback failed");
+                            free(iotHubClientInstance->connection_status_user_context);
+                            iotHubClientInstance->connection_status_user_context = NULL;
+                        }
+                    }
+                }
+                (void)Unlock(iotHubClientInstance->LockHandle);
+            }
+        }
+    }
+    return result;
+}
+
+IOTHUB_CLIENT_RESULT IoTHubClientCore_SetRetryPolicy(IOTHUB_CLIENT_CORE_HANDLE iotHubClientHandle, IOTHUB_CLIENT_RETRY_POLICY retryPolicy, size_t retryTimeoutLimitInSeconds)
+{
+    IOTHUB_CLIENT_RESULT result;
+
+    if (iotHubClientHandle == NULL)
+    {
+        /* Codes_SRS_IOTHUBCLIENT_25_076: [** If `iotHubClientHandle` is `NULL`, `IoTHubClient_SetRetryPolicy` shall return `IOTHUB_CLIENT_INVALID_ARG`. ] */
+        result = IOTHUB_CLIENT_INVALID_ARG;
+        LogError("NULL iothubClientHandle");
+    }
+    else
+    {
+        IOTHUB_CLIENT_CORE_INSTANCE* iotHubClientInstance = (IOTHUB_CLIENT_CORE_INSTANCE*)iotHubClientHandle;
+
+        /* Codes_SRS_IOTHUBCLIENT_25_073: [ `IoTHubClient_SetRetryPolicy` shall start the worker thread if it was not previously started. ] */
+        if ((result = StartWorkerThreadIfNeeded(iotHubClientInstance)) != IOTHUB_CLIENT_OK)
+        {
+            /* Codes_SRS_IOTHUBCLIENT_25_075: [ If starting the thread fails, `IoTHubClient_SetRetryPolicy` shall return `IOTHUB_CLIENT_ERROR`. ]*/
+            result = IOTHUB_CLIENT_ERROR;
+            LogError("Could not start worker thread");
+        }
+        else
+        {
+            /* Codes_SRS_IOTHUBCLIENT_25_079: [ `IoTHubClient_SetRetryPolicy` shall be made thread-safe by using the lock created in `IoTHubClient_Create`.] */
+            if (Lock(iotHubClientInstance->LockHandle) != LOCK_OK)
+            {
+                /* Codes_SRS_IOTHUBCLIENT_25_080: [ If acquiring the lock fails, `IoTHubClient_SetRetryPolicy` shall return `IOTHUB_CLIENT_ERROR`. ]*/
+                result = IOTHUB_CLIENT_ERROR;
+                LogError("Could not acquire lock");
+            }
+            else
+            {
+                /* Codes_SRS_IOTHUBCLIENT_25_077: [ `IoTHubClient_SetRetryPolicy` shall call `IoTHubClientCore_LL_SetRetryPolicy`, while passing the `IoTHubClientCore_LL` handle created by `IoTHubClient_Create` and the parameters `retryPolicy` and `retryTimeoutLimitinSeconds`.]*/
+                result = IoTHubClientCore_LL_SetRetryPolicy(iotHubClientInstance->IoTHubClientLLHandle, retryPolicy, retryTimeoutLimitInSeconds);
+                (void)Unlock(iotHubClientInstance->LockHandle);
+            }
+
+        }
+    }
+
+    return result;
+}
+
+IOTHUB_CLIENT_RESULT IoTHubClientCore_GetRetryPolicy(IOTHUB_CLIENT_CORE_HANDLE iotHubClientHandle, IOTHUB_CLIENT_RETRY_POLICY* retryPolicy, size_t* retryTimeoutLimitInSeconds)
+{
+    IOTHUB_CLIENT_RESULT result;
+
+    if (iotHubClientHandle == NULL)
+    {
+        /* Codes_SRS_IOTHUBCLIENT_25_092: [ If `iotHubClientHandle` is `NULL`, `IoTHubClient_GetRetryPolicy` shall return `IOTHUB_CLIENT_INVALID_ARG`. ]*/
+        result = IOTHUB_CLIENT_INVALID_ARG;
+        LogError("NULL iothubClientHandle");
+    }
+    else
+    {
+        IOTHUB_CLIENT_CORE_INSTANCE* iotHubClientInstance = (IOTHUB_CLIENT_CORE_INSTANCE*)iotHubClientHandle;
+
+        /* Codes_SRS_IOTHUBCLIENT_25_089: [ `IoTHubClient_GetRetryPolicy` shall start the worker thread if it was not previously started.]*/
+        if ((result = StartWorkerThreadIfNeeded(iotHubClientInstance)) != IOTHUB_CLIENT_OK)
+        {
+            /* Codes_SRS_IOTHUBCLIENT_25_091: [ If starting the thread fails, `IoTHubClient_GetRetryPolicy` shall return `IOTHUB_CLIENT_ERROR`.]*/
+            result = IOTHUB_CLIENT_ERROR;
+            LogError("Could not start worker thread");
+        }
+        else
+        {
+            /* Codes_SRS_IOTHUBCLIENT_25_095: [ `IoTHubClient_GetRetryPolicy` shall be made thread-safe by using the lock created in `IoTHubClient_Create`. ]*/
+            if (Lock(iotHubClientInstance->LockHandle) != LOCK_OK)
+            {
+                /* Codes_SRS_IOTHUBCLIENT_25_096: [ If acquiring the lock fails, `IoTHubClient_GetRetryPolicy` shall return `IOTHUB_CLIENT_ERROR`. ]*/
+                result = IOTHUB_CLIENT_ERROR;
+                LogError("Could not acquire lock");
+            }
+            else
+            {
+                /* Codes_SRS_IOTHUBCLIENT_25_093: [ `IoTHubClient_GetRetryPolicy` shall call `IoTHubClientCore_LL_GetRetryPolicy`, while passing the `IoTHubClientCore_LL` handle created by `IoTHubClient_Create` and the parameters `connectionStatusCallback` and `userContextCallback`.]*/
+                result = IoTHubClientCore_LL_GetRetryPolicy(iotHubClientInstance->IoTHubClientLLHandle, retryPolicy, retryTimeoutLimitInSeconds);
+                (void)Unlock(iotHubClientInstance->LockHandle);
+            }
+        }
+    }
+
+    return result;
+}
+
+IOTHUB_CLIENT_RESULT IoTHubClientCore_GetLastMessageReceiveTime(IOTHUB_CLIENT_CORE_HANDLE iotHubClientHandle, time_t* lastMessageReceiveTime)
+{
+    IOTHUB_CLIENT_RESULT result;
+
+    if (iotHubClientHandle == NULL)
+    {
+        /* Codes_SRS_IOTHUBCLIENT_01_020: [If iotHubClientHandle is NULL, IoTHubClient_GetLastMessageReceiveTime shall return IOTHUB_CLIENT_INVALID_ARG.] */
+        result = IOTHUB_CLIENT_INVALID_ARG;
+        LogError("NULL iothubClientHandle");
+    }
+    else
+    {
+        IOTHUB_CLIENT_CORE_INSTANCE* iotHubClientInstance = (IOTHUB_CLIENT_CORE_INSTANCE*)iotHubClientHandle;
+
+        /* Codes_SRS_IOTHUBCLIENT_01_035: [IoTHubClient_GetLastMessageReceiveTime shall be made thread-safe by using the lock created in IoTHubClient_Create.] */
+        if (Lock(iotHubClientInstance->LockHandle) != LOCK_OK)
+        {
+            /* Codes_SRS_IOTHUBCLIENT_01_036: [If acquiring the lock fails, IoTHubClient_GetLastMessageReceiveTime shall return IOTHUB_CLIENT_ERROR.] */
+            result = IOTHUB_CLIENT_ERROR;
+            LogError("Could not acquire lock");
+        }
+        else
+        {
+            /* Codes_SRS_IOTHUBCLIENT_01_019: [IoTHubClient_GetLastMessageReceiveTime shall call IoTHubClientCore_LL_GetLastMessageReceiveTime, while passing the IoTHubClientCore_LL handle created by IoTHubClient_Create and the parameter lastMessageReceiveTime.] */
+            /* Codes_SRS_IOTHUBCLIENT_01_021: [Otherwise, IoTHubClient_GetLastMessageReceiveTime shall return the result of IoTHubClientCore_LL_GetLastMessageReceiveTime.] */
+            result = IoTHubClientCore_LL_GetLastMessageReceiveTime(iotHubClientInstance->IoTHubClientLLHandle, lastMessageReceiveTime);
+
+            /* Codes_SRS_IOTHUBCLIENT_01_035: [IoTHubClient_GetLastMessageReceiveTime shall be made thread-safe by using the lock created in IoTHubClient_Create.] */
+            (void)Unlock(iotHubClientInstance->LockHandle);
+        }
+    }
+
+    return result;
+}
+
+IOTHUB_CLIENT_RESULT IoTHubClientCore_SetOption(IOTHUB_CLIENT_CORE_HANDLE iotHubClientHandle, const char* optionName, const void* value)
+{
+    IOTHUB_CLIENT_RESULT result;
+    /*Codes_SRS_IOTHUBCLIENT_02_034: [If parameter iotHubClientHandle is NULL then IoTHubClient_SetOption shall return IOTHUB_CLIENT_INVALID_ARG.] */
+    /*Codes_SRS_IOTHUBCLIENT_02_035: [ If parameter optionName is NULL then IoTHubClient_SetOption shall return IOTHUB_CLIENT_INVALID_ARG. ]*/
+    /*Codes_SRS_IOTHUBCLIENT_02_036: [ If parameter value is NULL then IoTHubClient_SetOption shall return IOTHUB_CLIENT_INVALID_ARG. ]*/
+    if (
+        (iotHubClientHandle == NULL) ||
+        (optionName == NULL) ||
+        (value == NULL)
+        )
+    {
+        result = IOTHUB_CLIENT_INVALID_ARG;
+        LogError("invalid arg (NULL)");
+    }
+    else
+    {
+        IOTHUB_CLIENT_CORE_INSTANCE* iotHubClientInstance = (IOTHUB_CLIENT_CORE_INSTANCE*)iotHubClientHandle;
+
+        /* Codes_SRS_IOTHUBCLIENT_01_041: [ IoTHubClient_SetOption shall be made thread-safe by using the lock created in IoTHubClient_Create. ]*/
+        if (Lock(iotHubClientInstance->LockHandle) != LOCK_OK)
+        {
+            /* Codes_SRS_IOTHUBCLIENT_01_042: [ If acquiring the lock fails, IoTHubClient_SetOption shall return IOTHUB_CLIENT_ERROR. ]*/
+            result = IOTHUB_CLIENT_ERROR;
+            LogError("Could not acquire lock");
+        }
+        else
+        {
+            /* Codes_SRS_IOTHUBCLIENT_41_001 [ If parameter `optionName` is `OPTION_DO_WORK_FREQUENCY_IN_MS` then `IoTHubClient_SetOption` shall set `do_work_freq_ms` parameter of `IoTHubClientInstance` ]*/
+            if (strcmp(OPTION_DO_WORK_FREQUENCY_IN_MS, optionName) == 0)
+            {
+                /* Codes_SRS_IOTHUBCLIENT_41_003: [ The value for `OPTION_DO_WORK_FREQUENCY_IN_MS` shall be limited to 100 to follow SDK best practices by not reducing the DoWork frequency below 10 Hz ]*/
+                if (0 < * (unsigned int *)value && * (unsigned int *)value <= 100)
+                {
+                    /* Codes_SRS_IOTHUBCLIENT_41_004: [ If `currentMessageTimeout` is not greater than `do_work_freq_ms`, `IotHubClientCore_SetOption` shall return `IOTHUB_CLIENT_INVALID_ARG` ]*/
+                    /* Codes_SRS_IOTHUBCLIENT_41_007: [** If parameter `optionName` is `OPTION_DO_WORK_FREQUENCY_IN_MS` then `value` should be of type `tickcounter_ms_t *`. **]*/
+                    if ((!iotHubClientInstance->currentMessageTimeout) || ( * (tickcounter_ms_t *)value < iotHubClientInstance->currentMessageTimeout))
+                    {
+                        iotHubClientInstance->do_work_freq_ms = * (tickcounter_ms_t *)value;
+                        result = IOTHUB_CLIENT_OK;
+                    }
+                    else
+                    {
+                        result = IOTHUB_CLIENT_INVALID_ARG;
+                        LogError("Invalid value: OPTION_DO_WORK_FREQUENCY_IN_MS cannot exceed that of OPTION_MESSAGE_TIMEOUT.");
+                    }
+                }
+                else
+                {
+                    result = IOTHUB_CLIENT_INVALID_ARG;
+                    LogError("Invalid value: OPTION_DO_WORK_FREQUENCY_IN_MS cannot exceed 100 ms. If you wish to reduce the frequency further, consider using the LL layer.");
+                }
+            }
+            /* Codes_SRS_IOTHUBCLIENT_41_005: [ If parameter `optionName` is `OPTION_MESSAGE_TIMEOUT` then `IoTHubClientCore_SetOption` shall set `currentMessageTimeout` parameter of `IoTHubClientInstance` ]*/
+            else if (strcmp(OPTION_MESSAGE_TIMEOUT, optionName) == 0)
+            {
+                iotHubClientInstance->currentMessageTimeout = * (tickcounter_ms_t *)value;
+
+                /* Codes_SRS_IOTHUBCLIENT_41_004: [ If `currentMessageTimeout` is not greater than `do_work_freq_ms`, `IotHubClientCore_SetOption` shall return `IOTHUB_CLIENT_INVALID_ARG` ]*/
+				if (iotHubClientInstance->do_work_freq_ms < iotHubClientInstance->currentMessageTimeout)
+                {
+                    /*Codes_SRS_IOTHUBCLIENT_41_006: [ If parameter `optionName` is `OPTION_MESSAGE_TIMEOUT` then `IoTHubClientCore_SetOption` shall call `IoTHubClientCore_LL_SetOption` passing the same parameters and return what IoTHubClientCore_LL_SetOption returns. ] */
+                    result = IoTHubClientCore_LL_SetOption(iotHubClientInstance->IoTHubClientLLHandle, optionName, value);
+                    if (result != IOTHUB_CLIENT_OK)
+                    {
+                        LogError("IoTHubClientCore_LL_SetOption failed");
+                    }
+                }
+                else
+                {
+                    result = IOTHUB_CLIENT_INVALID_ARG;
+                    LogError("invalid value: OPTION_MESSAGE_TIMEOUT cannot exceed the value of OPTION_DO_WORK_FREQUENCY_IN_MS ");
+                }
+            }
+            else
+            {
+                /*Codes_SRS_IOTHUBCLIENT_02_038: [If optionName doesn't match one of the options handled by this module then IoTHubClient_SetOption shall call IoTHubClientCore_LL_SetOption passing the same parameters and return what IoTHubClientCore_LL_SetOption returns.] */
+                result = IoTHubClientCore_LL_SetOption(iotHubClientInstance->IoTHubClientLLHandle, optionName, value);
+                if (result != IOTHUB_CLIENT_OK)
+                {
+                    LogError("IoTHubClientCore_LL_SetOption failed");
+                }
+            }
+            (void)Unlock(iotHubClientInstance->LockHandle);
+        }
+    }
+    return result;
+}
+
+IOTHUB_CLIENT_RESULT IoTHubClientCore_SetDeviceTwinCallback(IOTHUB_CLIENT_CORE_HANDLE iotHubClientHandle, IOTHUB_CLIENT_DEVICE_TWIN_CALLBACK deviceTwinCallback, void* userContextCallback)
+{
+    IOTHUB_CLIENT_RESULT result;
+
+    /*Codes_SRS_IOTHUBCLIENT_10_001: [** `IoTHubClient_SetDeviceTwinCallback` shall fail and return `IOTHUB_CLIENT_INVALID_ARG` if parameter `iotHubClientHandle` is `NULL`. ]*/
+    if (iotHubClientHandle == NULL)
+    {
+        result = IOTHUB_CLIENT_INVALID_ARG;
+        LogError("invalid arg (NULL)");
+    }
+    else
+    {
+        IOTHUB_CLIENT_CORE_INSTANCE* iotHubClientInstance = (IOTHUB_CLIENT_CORE_INSTANCE*)iotHubClientHandle;
+
+        /*Codes_SRS_IOTHUBCLIENT_10_003: [** If the transport connection is shared, the thread shall be started by calling `IoTHubTransport_StartWorkerThread`. ]*/
+        if ((result = StartWorkerThreadIfNeeded(iotHubClientInstance)) != IOTHUB_CLIENT_OK)
+        {
+            /*Codes_SRS_IOTHUBCLIENT_10_004: [** If starting the thread fails, `IoTHubClient_SetDeviceTwinCallback` shall return `IOTHUB_CLIENT_ERROR`. ]*/
+            result = IOTHUB_CLIENT_ERROR;
+            LogError("Could not start worker thread");
+        }
+        else
+        {
+            /*Codes_SRS_IOTHUBCLIENT_10_020: [** `IoTHubClient_SetDeviceTwinCallback` shall be made thread - safe by using the lock created in IoTHubClient_Create. ]*/
+            if (Lock(iotHubClientInstance->LockHandle) != LOCK_OK)
+            {
+                /*Codes_SRS_IOTHUBCLIENT_10_002: [** If acquiring the lock fails, `IoTHubClient_SetDeviceTwinCallback` shall return `IOTHUB_CLIENT_ERROR`. ]*/
+                result = IOTHUB_CLIENT_ERROR;
+                LogError("Could not acquire lock");
+            }
+            else
+            {
+                if (iotHubClientInstance->created_with_transport_handle == 0)
+                {
+                    iotHubClientInstance->desired_state_callback = deviceTwinCallback;
+                }
+
+                if (iotHubClientInstance->created_with_transport_handle != 0 || deviceTwinCallback == NULL)
+                {
+                    /*Codes_SRS_IOTHUBCLIENT_10_005: [** `IoTHubClientCore_LL_SetDeviceTwinCallback` shall call `IoTHubClientCore_LL_SetDeviceTwinCallback`, while passing the `IoTHubClientCore_LL handle` created by `IoTHubClientCore_LL_Create` along with the parameters `reportedStateCallback` and `userContextCallback`. ]*/
+                    result = IoTHubClientCore_LL_SetDeviceTwinCallback(iotHubClientInstance->IoTHubClientLLHandle, deviceTwinCallback, userContextCallback);
+                }
+                else
+                {
+                    if (iotHubClientInstance->devicetwin_user_context != NULL)
+                    {
+                        free(iotHubClientInstance->devicetwin_user_context);
+                    }
+
+                    /*Codes_SRS_IOTHUBCLIENT_07_002: [ IoTHubClient_SetDeviceTwinCallback shall allocate a IOTHUB_QUEUE_CONTEXT object to be sent to the IoTHubClientCore_LL_SetDeviceTwinCallback function as a user context. ]*/
+                    iotHubClientInstance->devicetwin_user_context = (IOTHUB_QUEUE_CONTEXT*)malloc(sizeof(IOTHUB_QUEUE_CONTEXT));
+                    if (iotHubClientInstance->devicetwin_user_context == NULL)
+                    {
+                        result = IOTHUB_CLIENT_ERROR;
+                        LogError("Failed allocating QUEUE_CONTEXT");
+                    }
+                    else
+                    {
+                        /*Codes_SRS_IOTHUBCLIENT_10_005: [** `IoTHubClientCore_LL_SetDeviceTwinCallback` shall call `IoTHubClientCore_LL_SetDeviceTwinCallback`, while passing the `IoTHubClientCore_LL handle` created by `IoTHubClientCore_LL_Create` along with the parameters `iothub_ll_device_twin_callback` and IOTHUB_QUEUE_CONTEXT variable. ]*/
+                        iotHubClientInstance->devicetwin_user_context->iotHubClientHandle = iotHubClientInstance;
+                        iotHubClientInstance->devicetwin_user_context->userContextCallback = userContextCallback;
+                        result = IoTHubClientCore_LL_SetDeviceTwinCallback(iotHubClientInstance->IoTHubClientLLHandle, iothub_ll_device_twin_callback, iotHubClientInstance->devicetwin_user_context);
+                        if (result != IOTHUB_CLIENT_OK)
+                        {
+                            LogError("IoTHubClientCore_LL_SetDeviceTwinCallback failed");
+                            free(iotHubClientInstance->devicetwin_user_context);
+                            iotHubClientInstance->devicetwin_user_context = NULL;
+                        }
+                    }
+                }
+
+                (void)Unlock(iotHubClientInstance->LockHandle);
+            }
+        }
+    }
+    return result;
+}
+
+IOTHUB_CLIENT_RESULT IoTHubClientCore_SendReportedState(IOTHUB_CLIENT_CORE_HANDLE iotHubClientHandle, const unsigned char* reportedState, size_t size, IOTHUB_CLIENT_REPORTED_STATE_CALLBACK reportedStateCallback, void* userContextCallback)
+{
+    IOTHUB_CLIENT_RESULT result;
+
+    /*Codes_SRS_IOTHUBCLIENT_10_013: [** If `iotHubClientHandle` is `NULL`, `IoTHubClient_SendReportedState` shall return `IOTHUB_CLIENT_INVALID_ARG`. ]*/
+    if (iotHubClientHandle == NULL)
+    {
+        result = IOTHUB_CLIENT_INVALID_ARG;
+        LogError("invalid arg (NULL)");
+    }
+    else
+    {
+        IOTHUB_CLIENT_CORE_INSTANCE* iotHubClientInstance = (IOTHUB_CLIENT_CORE_INSTANCE*)iotHubClientHandle;
+
+        /*Codes_SRS_IOTHUBCLIENT_10_015: [** If the transport connection is shared, the thread shall be started by calling `IoTHubTransport_StartWorkerThread`. ]*/
+        if ((result = StartWorkerThreadIfNeeded(iotHubClientInstance)) != IOTHUB_CLIENT_OK)
+        {
+            /*Codes_SRS_IOTHUBCLIENT_10_016: [** If starting the thread fails, `IoTHubClient_SendReportedState` shall return `IOTHUB_CLIENT_ERROR`. ]*/
+            result = IOTHUB_CLIENT_ERROR;
+            LogError("Could not start worker thread");
+        }
+        else
+        {
+            /*Codes_SRS_IOTHUBCLIENT_10_021: [** `IoTHubClient_SendReportedState` shall be made thread-safe by using the lock created in IoTHubClient_Create. ]*/
+            if (Lock(iotHubClientInstance->LockHandle) != LOCK_OK)
+            {
+                /*Codes_SRS_IOTHUBCLIENT_10_014: [** If acquiring the lock fails, `IoTHubClient_SendReportedState` shall return `IOTHUB_CLIENT_ERROR`. ]*/
+                result = IOTHUB_CLIENT_ERROR;
+                LogError("Could not acquire lock");
+            }
+            else
+            {
+                if (iotHubClientInstance->created_with_transport_handle != 0 || reportedStateCallback == NULL)
+                {
+                    /*Codes_SRS_IOTHUBCLIENT_10_017: [** `IoTHubClient_SendReportedState` shall call `IoTHubClientCore_LL_SendReportedState`, while passing the `IoTHubClientCore_LL handle` created by `IoTHubClientCore_LL_Create` along with the parameters `reportedState`, `size`, `reportedStateCallback`, and `userContextCallback`. ]*/
+                    /*Codes_SRS_IOTHUBCLIENT_10_018: [** When `IoTHubClientCore_LL_SendReportedState` is called, `IoTHubClient_SendReportedState` shall return the result of `IoTHubClientCore_LL_SendReportedState`. **]*/
+                    result = IoTHubClientCore_LL_SendReportedState(iotHubClientInstance->IoTHubClientLLHandle, reportedState, size, reportedStateCallback, userContextCallback);
+                }
+                else
+                {
+                    /* Codes_SRS_IOTHUBCLIENT_07_003: [ IoTHubClient_SendReportedState shall allocate a IOTHUB_QUEUE_CONTEXT object to be sent to the IoTHubClientCore_LL_SendReportedState function as a user context. ] */
+                    IOTHUB_QUEUE_CONTEXT* queue_context = (IOTHUB_QUEUE_CONTEXT*)malloc(sizeof(IOTHUB_QUEUE_CONTEXT));
+                    if (queue_context == NULL)
+                    {
+                        result = IOTHUB_CLIENT_ERROR;
+                        LogError("Failed allocating QUEUE_CONTEXT");
+                    }
+                    else
+                    {
+                        queue_context->iotHubClientHandle = iotHubClientInstance;
+                        queue_context->userContextCallback = userContextCallback;
+                        queue_context->callbackFunction.reportedStateCallback = reportedStateCallback;
+                        /*Codes_SRS_IOTHUBCLIENT_10_017: [** `IoTHubClient_SendReportedState` shall call `IoTHubClientCore_LL_SendReportedState`, while passing the `IoTHubClientCore_LL handle` created by `IoTHubClientCore_LL_Create` along with the parameters `reportedState`, `size`, `iothub_ll_reported_state_callback` and IOTHUB_QUEUE_CONTEXT variable. ]*/
+                        /*Codes_SRS_IOTHUBCLIENT_10_018: [** When `IoTHubClientCore_LL_SendReportedState` is called, `IoTHubClient_SendReportedState` shall return the result of `IoTHubClientCore_LL_SendReportedState`. **]*/
+                        result = IoTHubClientCore_LL_SendReportedState(iotHubClientInstance->IoTHubClientLLHandle, reportedState, size, iothub_ll_reported_state_callback, queue_context);
+                        if (result != IOTHUB_CLIENT_OK)
+                        {
+                            LogError("IoTHubClientCore_LL_SendReportedState failed");
+                            free(queue_context);
+                        }
+                    }
+                }
+
+                (void)Unlock(iotHubClientInstance->LockHandle);
+            }
+        }
+    }
+    return result;
+}
+
+IOTHUB_CLIENT_RESULT IoTHubClientCore_GetTwinAsync(IOTHUB_CLIENT_CORE_HANDLE iotHubClientHandle, IOTHUB_CLIENT_DEVICE_TWIN_CALLBACK deviceTwinCallback, void* userContextCallback)
+{
+    IOTHUB_CLIENT_RESULT result;
+
+    // Codes_SRS_IOTHUBCLIENT_09_009: [ If `iotHubClientHandle` or `deviceTwinCallback` are `NULL`, `IoTHubClientCore_GetTwinAsync` shall return `IOTHUB_CLIENT_INVALID_ARG`. ]
+    if (iotHubClientHandle == NULL || deviceTwinCallback == NULL)
+    {
+        result = IOTHUB_CLIENT_INVALID_ARG;
+        LogError("Invalid argument (iotHubClientHandle=%p, deviceTwinCallback=%p)", iotHubClientHandle, deviceTwinCallback);
+    }
+    else
+    {
+        IOTHUB_CLIENT_CORE_INSTANCE* iotHubClientInstance = (IOTHUB_CLIENT_CORE_INSTANCE*)iotHubClientHandle;
+
+        // Codes_SRS_IOTHUBCLIENT_09_010: [ The thread that executes the client  I/O shall be started if not running already. ]
+        if ((result = StartWorkerThreadIfNeeded(iotHubClientInstance)) != IOTHUB_CLIENT_OK)
+        {
+            // Codes_SRS_IOTHUBCLIENT_09_011: [ If starting the thread fails, `IoTHubClientCore_GetTwinAsync` shall return `IOTHUB_CLIENT_ERROR`. ]
+            result = IOTHUB_CLIENT_ERROR;
+            LogError("Could not start worker thread");
+        }
+        else
+        {
+            IOTHUB_QUEUE_CONSOLIDATED_CONTEXT* queueContext;
+
+            if ((queueContext = (IOTHUB_QUEUE_CONSOLIDATED_CONTEXT*)malloc(sizeof(IOTHUB_QUEUE_CONSOLIDATED_CONTEXT))) == NULL)
+            {
+                LogError("Failed creating queue context");
+                result = IOTHUB_CLIENT_ERROR;
+            }
+            else
+            {
+                queueContext->iotHubClientHandle = iotHubClientHandle;
+                queueContext->userCallback.getTwin = deviceTwinCallback;
+                queueContext->userContext = userContextCallback;
+
+                // Codes_SRS_IOTHUBCLIENT_09_012: [ `IoTHubClientCore_GetTwinAsync` shall be made thread-safe by using the lock created in IoTHubClient_Create. ]
+                if (Lock(iotHubClientInstance->LockHandle) != LOCK_OK)
+                {
+                    // Codes_SRS_IOTHUBCLIENT_09_013: [ If acquiring the lock fails, `IoTHubClientCore_GetTwinAsync` shall return `IOTHUB_CLIENT_ERROR`. ]
+                    result = IOTHUB_CLIENT_ERROR;
+                    LogError("Could not acquire lock");
+                    free(queueContext);
+                }
+                else
+                {
+                    // Codes_SRS_IOTHUBCLIENT_09_014: [ `IoTHubClientCore_GetTwinAsync` shall call `IoTHubClientCore_LL_GetTwinAsync`, passing the `IoTHubClient_LL handle`, `deviceTwinCallback` and `userContextCallback` as arguments ]
+                    // Codes_SRS_IOTHUBCLIENT_09_015: [ When `IoTHubClientCore_LL_GetTwinAsync` is called, `IoTHubClientCore_GetTwinAsync` shall return the result of `IoTHubClientCore_LL_GetTwinAsync`. ]
+                    result = IoTHubClientCore_LL_GetTwinAsync(iotHubClientInstance->IoTHubClientLLHandle, iothub_ll_get_device_twin_async_callback, queueContext);
+
+                    if (result != IOTHUB_CLIENT_OK)
+                    {
+                        LogError("IoTHubClientCore_LL_GetTwinAsync failed");
+                        free(queueContext);
+                    }
+
+                    (void)Unlock(iotHubClientInstance->LockHandle);
+                }
+            }
+        }
+    }
+    return result;
+}
+
+IOTHUB_CLIENT_RESULT IoTHubClientCore_SetDeviceMethodCallback(IOTHUB_CLIENT_CORE_HANDLE iotHubClientHandle, IOTHUB_CLIENT_DEVICE_METHOD_CALLBACK_ASYNC deviceMethodCallback, void* userContextCallback)
+{
+    IOTHUB_CLIENT_RESULT result;
+
+    /*Codes_SRS_IOTHUBCLIENT_12_012: [ If iotHubClientHandle is NULL, IoTHubClient_SetDeviceMethodCallback shall return IOTHUB_CLIENT_INVALID_ARG. ]*/
+    if (iotHubClientHandle == NULL)
+    {
+        result = IOTHUB_CLIENT_INVALID_ARG;
+        LogError("invalid arg (NULL)");
+    }
+    else
+    {
+        IOTHUB_CLIENT_CORE_INSTANCE* iotHubClientInstance = (IOTHUB_CLIENT_CORE_INSTANCE*)iotHubClientHandle;
+
+        /*Codes_SRS_IOTHUBCLIENT_12_014: [ If the transport handle is null and the worker thread is not initialized, the thread shall be started by calling IoTHubTransport_StartWorkerThread. ]*/
+        if ((result = StartWorkerThreadIfNeeded(iotHubClientInstance)) != IOTHUB_CLIENT_OK)
+        {
+            /*Codes_SRS_IOTHUBCLIENT_12_015: [ If starting the thread fails, IoTHubClient_SetDeviceMethodCallback shall return IOTHUB_CLIENT_ERROR. ]*/
+            result = IOTHUB_CLIENT_ERROR;
+            LogError("Could not start worker thread");
+        }
+        else
+        {
+            /*Codes_SRS_IOTHUBCLIENT_12_018: [ IoTHubClient_SetDeviceMethodCallback shall be made thread-safe by using the lock created in IoTHubClient_Create. ]*/
+            if (Lock(iotHubClientInstance->LockHandle) != LOCK_OK)
+            {
+                /*Codes_SRS_IOTHUBCLIENT_12_013: [ If acquiring the lock fails, IoTHubClient_SetDeviceMethodCallback shall return IOTHUB_CLIENT_ERROR. ]*/
+                result = IOTHUB_CLIENT_ERROR;
+                LogError("Could not acquire lock");
+            }
+            else
+            {
+                if (iotHubClientInstance->created_with_transport_handle == 0)
+                {
+                    iotHubClientInstance->device_method_callback = deviceMethodCallback;
+                }
+
+                if (iotHubClientInstance->method_user_context)
+                {
+                    free(iotHubClientInstance->method_user_context);
+                    iotHubClientInstance->method_user_context = NULL;
+                }
+                if (deviceMethodCallback == NULL)
+                {
+                    result = IoTHubClientCore_LL_SetDeviceMethodCallback_Ex(iotHubClientInstance->IoTHubClientLLHandle, NULL, NULL);
+                }
+                else
+                {
+                    iotHubClientInstance->method_user_context = (IOTHUB_QUEUE_CONTEXT*)malloc(sizeof(IOTHUB_QUEUE_CONTEXT));
+                    if (iotHubClientInstance->method_user_context == NULL)
+                    {
+                        result = IOTHUB_CLIENT_ERROR;
+                        LogError("Failed allocating QUEUE_CONTEXT");
+                    }
+                    else
+                    {
+                        iotHubClientInstance->method_user_context->iotHubClientHandle = iotHubClientHandle;
+                        iotHubClientInstance->method_user_context->userContextCallback = userContextCallback;
+
+                        /*Codes_SRS_IOTHUBCLIENT_12_016: [ IoTHubClient_SetDeviceMethodCallback shall call IoTHubClientCore_LL_SetDeviceMethodCallback, while passing the IoTHubClientCore_LL_handle created by IoTHubClientCore_LL_Create along with the parameters deviceMethodCallback and userContextCallback. ]*/
+                        /*Codes_SRS_IOTHUBCLIENT_12_017: [ When IoTHubClientCore_LL_SetDeviceMethodCallback is called, IoTHubClient_SetDeviceMethodCallback shall return the result of IoTHubClientCore_LL_SetDeviceMethodCallback. ]*/
+                        result = IoTHubClientCore_LL_SetDeviceMethodCallback_Ex(iotHubClientInstance->IoTHubClientLLHandle, iothub_ll_device_method_callback, iotHubClientInstance->method_user_context);
+                        if (result != IOTHUB_CLIENT_OK)
+                        {
+                            LogError("IoTHubClientCore_LL_SetDeviceMethodCallback_Ex failed");
+                            free(iotHubClientInstance->method_user_context);
+                            iotHubClientInstance->method_user_context = NULL;
+                        }
+                        else
+                        {
+                            iotHubClientInstance->device_method_callback = deviceMethodCallback;
+                        }
+                    }
+                }
+
+                (void)Unlock(iotHubClientInstance->LockHandle);
+            }
+
+        }
+    }
+    return result;
+}
+
+IOTHUB_CLIENT_RESULT IoTHubClientCore_SetDeviceMethodCallback_Ex(IOTHUB_CLIENT_CORE_HANDLE iotHubClientHandle, IOTHUB_CLIENT_INBOUND_DEVICE_METHOD_CALLBACK inboundDeviceMethodCallback, void* userContextCallback)
+{
+    IOTHUB_CLIENT_RESULT result;
+
+    /*Codes_SRS_IOTHUBCLIENT_07_001: [ If iotHubClientHandle is NULL, IoTHubClient_SetDeviceMethodCallback_Ex shall return IOTHUB_CLIENT_INVALID_ARG. ]*/
+    if (iotHubClientHandle == NULL)
+    {
+        result = IOTHUB_CLIENT_INVALID_ARG;
+        LogError("invalid arg (NULL)");
+    }
+    else
+    {
+        IOTHUB_CLIENT_CORE_INSTANCE* iotHubClientInstance = (IOTHUB_CLIENT_CORE_INSTANCE*)iotHubClientHandle;
+
+        /*Codes_SRS_IOTHUBCLIENT_07_003: [ If the transport handle is NULL and the worker thread is not initialized, the thread shall be started by calling IoTHubTransport_StartWorkerThread. ]*/
+        if ((result = StartWorkerThreadIfNeeded(iotHubClientInstance)) != IOTHUB_CLIENT_OK)
+        {
+            /*Codes_SRS_IOTHUBCLIENT_07_004: [ If starting the thread fails, IoTHubClient_SetDeviceMethodCallback_Ex shall return IOTHUB_CLIENT_ERROR. ]*/
+            result = IOTHUB_CLIENT_ERROR;
+            LogError("Could not start worker thread");
+        }
+        else
+        {
+            /*Codes_SRS_IOTHUBCLIENT_07_007: [ IoTHubClient_SetDeviceMethodCallback_Ex shall be made thread-safe by using the lock created in IoTHubClient_Create. ]*/
+            if (Lock(iotHubClientInstance->LockHandle) != LOCK_OK)
+            {
+                /*Codes_SRS_IOTHUBCLIENT_07_002: [ If acquiring the lock fails, IoTHubClient_SetDeviceMethodCallback_Ex shall return IOTHUB_CLIENT_ERROR. ]*/
+                result = IOTHUB_CLIENT_ERROR;
+                LogError("Could not acquire lock");
+            }
+            else
+            {
+                if (iotHubClientInstance->created_with_transport_handle == 0)
+                {
+                    iotHubClientInstance->inbound_device_method_callback = inboundDeviceMethodCallback;
+                }
+
+                if (iotHubClientInstance->method_user_context)
+                {
+                    free(iotHubClientInstance->method_user_context);
+                    iotHubClientInstance->method_user_context = NULL;
+                }
+                if (inboundDeviceMethodCallback == NULL)
+                {
+                    /* Codes_SRS_IOTHUBCLIENT_07_008: [ If inboundDeviceMethodCallback is NULL, IoTHubClient_SetDeviceMethodCallback_Ex shall call IoTHubClientCore_LL_SetDeviceMethodCallback_Ex, passing NULL for the iothub_ll_inbound_device_method_callback. ] */
+                    result = IoTHubClientCore_LL_SetDeviceMethodCallback_Ex(iotHubClientInstance->IoTHubClientLLHandle, NULL, NULL);
+                }
+                else
+                {
+                    iotHubClientInstance->method_user_context = (IOTHUB_QUEUE_CONTEXT*)malloc(sizeof(IOTHUB_QUEUE_CONTEXT));
+                    if (iotHubClientInstance->method_user_context == NULL)
+                    {
+                        result = IOTHUB_CLIENT_ERROR;
+                        LogError("Failed allocating QUEUE_CONTEXT");
+                    }
+                    else
+                    {
+                        /*Codes_SRS_IOTHUBCLIENT_07_005: [ IoTHubClient_SetDeviceMethodCallback_Ex shall call IoTHubClientCore_LL_SetDeviceMethodCallback_Ex, while passing the IoTHubClientCore_LL_handle created by IoTHubClientCore_LL_Create along with the parameters iothub_ll_inbound_device_method_callback and IOTHUB_QUEUE_CONTEXT. ]*/
+                        iotHubClientInstance->method_user_context->iotHubClientHandle = iotHubClientHandle;
+                        iotHubClientInstance->method_user_context->userContextCallback = userContextCallback;
+
+                        /* Codes_SRS_IOTHUBCLIENT_07_006: [ When IoTHubClientCore_LL_SetDeviceMethodCallback_Ex is called, IoTHubClient_SetDeviceMethodCallback_Ex shall return the result of IoTHubClientCore_LL_SetDeviceMethodCallback_Ex. ] */
+                        result = IoTHubClientCore_LL_SetDeviceMethodCallback_Ex(iotHubClientInstance->IoTHubClientLLHandle, iothub_ll_inbound_device_method_callback, iotHubClientInstance->method_user_context);
+                        if (result != IOTHUB_CLIENT_OK)
+                        {
+                            LogError("IoTHubClientCore_LL_SetDeviceMethodCallback_Ex failed");
+                            free(iotHubClientInstance->method_user_context);
+                            iotHubClientInstance->method_user_context = NULL;
+                        }
+                        else
+                        {
+                            iotHubClientInstance->inbound_device_method_callback = inboundDeviceMethodCallback;
+                        }
+                    }
+                }
+
+                (void)Unlock(iotHubClientInstance->LockHandle);
+            }
+        }
+    }
+    return result;
+}
+
+IOTHUB_CLIENT_RESULT IoTHubClientCore_DeviceMethodResponse(IOTHUB_CLIENT_CORE_HANDLE iotHubClientHandle, METHOD_HANDLE methodId, const unsigned char* response, size_t respSize, int statusCode)
+{
+    IOTHUB_CLIENT_RESULT result;
+
+    /*Codes_SRS_IOTHUBCLIENT_12_012: [ If iotHubClientHandle is NULL, IoTHubClient_SetDeviceMethodCallback shall return IOTHUB_CLIENT_INVALID_ARG. ]*/
+    if (iotHubClientHandle == NULL)
+    {
+        result = IOTHUB_CLIENT_INVALID_ARG;
+        LogError("invalid arg (NULL)");
+    }
+    else
+    {
+        IOTHUB_CLIENT_CORE_INSTANCE* iotHubClientInstance = (IOTHUB_CLIENT_CORE_INSTANCE*)iotHubClientHandle;
+
+        /*Codes_SRS_IOTHUBCLIENT_12_018: [ IoTHubClient_SetDeviceMethodCallback shall be made thread-safe by using the lock created in IoTHubClient_Create. ]*/
+        if (Lock(iotHubClientInstance->LockHandle) != LOCK_OK)
+        {
+            /*Codes_SRS_IOTHUBCLIENT_12_013: [ If acquiring the lock fails, IoTHubClient_SetDeviceMethodCallback shall return IOTHUB_CLIENT_ERROR. ]*/
+            result = IOTHUB_CLIENT_ERROR;
+            LogError("Could not acquire lock");
+        }
+        else
+        {
+            result = IoTHubClientCore_LL_DeviceMethodResponse(iotHubClientInstance->IoTHubClientLLHandle, methodId, response, respSize, statusCode);
+            if (result != IOTHUB_CLIENT_OK)
+            {
+                LogError("IoTHubClientCore_LL_DeviceMethodResponse failed");
+            }
+            (void)Unlock(iotHubClientInstance->LockHandle);
+        }
+    }
+    return result;
+}
+
+#if !defined(DONT_USE_UPLOADTOBLOB) || defined(USE_EDGE_MODULES)
+static IOTHUB_CLIENT_RESULT startHttpWorkerThread(IOTHUB_CLIENT_CORE_HANDLE iotHubClientHandle, HTTPWORKER_THREAD_INFO* threadInfo, THREAD_START_FUNC httpWorkerThreadFunc)
+{
+    IOTHUB_CLIENT_RESULT result;
+
+    LIST_ITEM_HANDLE item;
+
+    // StartWorkerThreadIfNeeded creates the "main" worker thread used for transports.  Though its not used
+    // for these HTTP based worker threads (see ThreadAPI_Create call below) the main one is needed for garbage collection.
+    if ((result = StartWorkerThreadIfNeeded(iotHubClientHandle)) != IOTHUB_CLIENT_OK)
+    {
+        /*Codes_SRS_IOTHUBCLIENT_02_053: [ If copying to the structure or spawning the thread fails, then IoTHubClient_UploadToBlobAsync shall fail and return IOTHUB_CLIENT_ERROR. ]*/
+        LogError("Could not start worker thread");
+    }
+    else if (Lock(threadInfo->iotHubClientHandle->LockHandle) != LOCK_OK)
+    {
+        LogError("Lock failed");
+        result = IOTHUB_CLIENT_ERROR;
+    }
+    else
+    {
+        if ((item = singlylinkedlist_add(threadInfo->iotHubClientHandle->httpWorkerThreadInfoList, threadInfo)) == NULL)
+        {
+            LogError("Adding item to list failed");
+            result = IOTHUB_CLIENT_ERROR;
+        }
+        else if (ThreadAPI_Create(&threadInfo->threadHandle, httpWorkerThreadFunc, threadInfo) != THREADAPI_OK)
+        {
+            /*Codes_SRS_IOTHUBCLIENT_02_053: [ If copying to the structure or spawning the thread fails, then IoTHubClient_UploadToBlobAsync shall fail and return IOTHUB_CLIENT_ERROR. ]*/
+            LogError("unable to ThreadAPI_Create");
+            // Remove the item from linked list here, while we're still under lock.  Final garbage collector also does it under lock.
+            (void)singlylinkedlist_remove(threadInfo->iotHubClientHandle->httpWorkerThreadInfoList, item);
+            result = IOTHUB_CLIENT_ERROR;
+        }
+        else
+        {
+            result = IOTHUB_CLIENT_OK;
+        }
+        (void)Unlock(threadInfo->iotHubClientHandle->LockHandle);
+    }
+
+    return result;
+}
+
+static int markThreadReadyToBeGarbageCollected(HTTPWORKER_THREAD_INFO* threadInfo)
+{
+    /*Codes_SRS_IOTHUBCLIENT_02_071: [ The thread shall mark itself as disposable. ]*/
+    if (Lock(threadInfo->lockGarbage) != LOCK_OK)
+    {
+        LogError("unable to Lock - trying anyway");
+        threadInfo->canBeGarbageCollected = 1;
+    }
+    else
+    {
+        threadInfo->canBeGarbageCollected = 1;
+
+        if (Unlock(threadInfo->lockGarbage) != LOCK_OK)
+        {
+            LogError("unable to Unlock after locking");
+        }
+    }
+
+    ThreadAPI_Exit(0);
+    return 0;
+}
+
+#endif // !defined(DONT_USE_UPLOADTOBLOB) || defined(USE_EDGE_MODULES)
+
+#if !defined(DONT_USE_UPLOADTOBLOB)
+static HTTPWORKER_THREAD_INFO* allocateUploadToBlob(const char* destinationFileName, IOTHUB_CLIENT_CORE_HANDLE iotHubClientHandle, void* context)
+{
+    HTTPWORKER_THREAD_INFO* threadInfo = (HTTPWORKER_THREAD_INFO*)malloc(sizeof(HTTPWORKER_THREAD_INFO));
+    if (threadInfo == NULL)
+    {
+        LogError("unable to allocate thread object");
+    }
+    else
+    {
+        memset(threadInfo, 0, sizeof(HTTPWORKER_THREAD_INFO));
+        threadInfo->workerThreadType = HTTPWORKER_THREAD_UPLOAD_TO_BLOB;
+        threadInfo->iotHubClientHandle = iotHubClientHandle;
+        threadInfo->context = context;
+
+        if (mallocAndStrcpy_s(&threadInfo->destinationFileName, destinationFileName) != 0)
+        {
+            /*Codes_SRS_IOTHUBCLIENT_02_053: [ If copying to the structure or spawning the thread fails, then IoTHubClient_UploadToBlobAsync shall fail and return IOTHUB_CLIENT_ERROR. ]*/
+            LogError("unable to mallocAndStrcpy_s");
+            freeHttpWorkerThreadInfo(threadInfo);
+            threadInfo = NULL;
+        }
+        else if ((threadInfo->lockGarbage = Lock_Init()) == NULL)
+        {
+            LogError("unable to allocate a lock");
+            freeHttpWorkerThreadInfo(threadInfo);
+            threadInfo = NULL;
+        }
+    }
+
+    return threadInfo;
+}
+
+
+static IOTHUB_CLIENT_RESULT initializeUploadToBlobData(HTTPWORKER_THREAD_INFO* threadInfo, const unsigned char* source, size_t size, IOTHUB_CLIENT_FILE_UPLOAD_CALLBACK iotHubClientFileUploadCallback)
+{
+    IOTHUB_CLIENT_RESULT result;
+
+    threadInfo->uploadBlobSavedData.size = size;
+    threadInfo->uploadBlobSavedData.iotHubClientFileUploadCallback = iotHubClientFileUploadCallback;
+
+    if (size != 0)
+    {
+        if ((threadInfo->uploadBlobSavedData.source = (unsigned char*)malloc(size)) == NULL)
+        {
+            LogError("Cannot allocate source field");
+            result = IOTHUB_CLIENT_ERROR;
+        }
+        else
+        {
+            memcpy(threadInfo->uploadBlobSavedData.source, source, size);
+            result = IOTHUB_CLIENT_OK;
+        }
+    }
+    else
+    {
+        result = IOTHUB_CLIENT_OK;
+    }
+
+    return result;
+}
+
+
+static int uploadingThread(void *data)
+{
+    IOTHUB_CLIENT_FILE_UPLOAD_RESULT upload_result;
+    HTTPWORKER_THREAD_INFO* threadInfo = (HTTPWORKER_THREAD_INFO*)data;
+
+    srand((unsigned int)get_time(NULL));
+
+    /*it so happens that IoTHubClientCore_LL_UploadToBlob is thread-safe because there's no saved state in the handle and there are no globals, so no need to protect it*/
+    /*not having it protected means multiple simultaneous uploads can happen*/
+    /*Codes_SRS_IOTHUBCLIENT_02_054: [ The thread shall call IoTHubClientCore_LL_UploadToBlob passing the information packed in the structure. ]*/
+    if (IoTHubClientCore_LL_UploadToBlob(threadInfo->iotHubClientHandle->IoTHubClientLLHandle, threadInfo->destinationFileName, threadInfo->uploadBlobSavedData.source, threadInfo->uploadBlobSavedData.size) == IOTHUB_CLIENT_OK)
+    {
+        upload_result = FILE_UPLOAD_OK;
+    }
+    else
+    {
+        LogError("unable to IoTHubClientCore_LL_UploadToBlob");
+        upload_result = FILE_UPLOAD_ERROR;
+    }
+
+    if (threadInfo->uploadBlobSavedData.iotHubClientFileUploadCallback != NULL)
+    {
+        /*Codes_SRS_IOTHUBCLIENT_02_055: [ If IoTHubClientCore_LL_UploadToBlob fails then the thread shall call iotHubClientFileUploadCallbackInternal passing as result FILE_UPLOAD_ERROR and as context the structure from SRS IOTHUBCLIENT 02 051. ]*/
+        threadInfo->uploadBlobSavedData.iotHubClientFileUploadCallback(upload_result, threadInfo->context);
+    }
+
+    return markThreadReadyToBeGarbageCollected(threadInfo);
+}
+
+IOTHUB_CLIENT_RESULT IoTHubClientCore_UploadToBlobAsync(IOTHUB_CLIENT_CORE_HANDLE iotHubClientHandle, const char* destinationFileName, const unsigned char* source, size_t size, IOTHUB_CLIENT_FILE_UPLOAD_CALLBACK iotHubClientFileUploadCallback, void* context)
+{
+    IOTHUB_CLIENT_RESULT result;
+    /*Codes_SRS_IOTHUBCLIENT_02_047: [ If iotHubClientHandle is NULL then IoTHubClient_UploadToBlobAsync shall fail and return IOTHUB_CLIENT_INVALID_ARG. ]*/
+    /*Codes_SRS_IOTHUBCLIENT_02_048: [ If destinationFileName is NULL then IoTHubClient_UploadToBlobAsync shall fail and return IOTHUB_CLIENT_INVALID_ARG. ]*/
+    /*Codes_SRS_IOTHUBCLIENT_02_049: [ If source is NULL and size is greated than 0 then IoTHubClient_UploadToBlobAsync shall fail and return IOTHUB_CLIENT_INVALID_ARG. ]*/
+    if (
+        (iotHubClientHandle == NULL) ||
+        (destinationFileName == NULL) ||
+        ((source == NULL) && (size > 0))
+        )
+    {
+        LogError("invalid parameters IOTHUB_CLIENT_CORE_HANDLE iotHubClientHandle = %p , const char* destinationFileName = %s, const unsigned char* source= %p, size_t size = %lu, IOTHUB_CLIENT_FILE_UPLOAD_CALLBACK iotHubClientFileUploadCallback = %p, void* context = %p",
+            iotHubClientHandle,
+            destinationFileName,
+            source,
+            (unsigned long)size,
+            iotHubClientFileUploadCallback,
+            context
+        );
+        result = IOTHUB_CLIENT_INVALID_ARG;
+    }
+    else
+    {
+        /*Codes_SRS_IOTHUBCLIENT_02_051: [IoTHubClient_UploadToBlobAsync shall copy the souce, size, iotHubClientFileUploadCallback, context into a structure.]*/
+        HTTPWORKER_THREAD_INFO *threadInfo = allocateUploadToBlob(destinationFileName, iotHubClientHandle, context);
+        if (threadInfo == NULL)
+        {
+            /*Codes_SRS_IOTHUBCLIENT_02_053: [ If copying to the structure or spawning the thread fails, then IoTHubClient_UploadToBlobAsync shall fail and return IOTHUB_CLIENT_ERROR. ]*/
+            LogError("unable to create upload thread info");
+            result = IOTHUB_CLIENT_ERROR;
+        }
+        else if ((result = initializeUploadToBlobData(threadInfo, source, size, iotHubClientFileUploadCallback)) != IOTHUB_CLIENT_OK)
+        {
+            /*Codes_SRS_IOTHUBCLIENT_02_053: [ If copying to the structure or spawning the thread fails, then IoTHubClient_UploadToBlobAsync shall fail and return IOTHUB_CLIENT_ERROR. ]*/
+            LogError("unable to initialize upload blob info");
+            result = IOTHUB_CLIENT_ERROR;
+        }
+        /*Codes_SRS_IOTHUBCLIENT_02_052: [ IoTHubClient_UploadToBlobAsync shall spawn a thread passing the structure build in SRS IOTHUBCLIENT 02 051 as thread data.]*/
+        else if ((result = startHttpWorkerThread(iotHubClientHandle, threadInfo, uploadingThread)) != IOTHUB_CLIENT_OK)
+        {
+            /*Codes_SRS_IOTHUBCLIENT_02_053: [ If copying to the structure or spawning the thread fails, then IoTHubClient_UploadToBlobAsync shall fail and return IOTHUB_CLIENT_ERROR. ]*/
+            LogError("unable to start upload thread");
+            freeHttpWorkerThreadInfo(threadInfo);
+        }
+        else
+        {
+            result = IOTHUB_CLIENT_OK;
+        }
+    }
+
+    return result;
+}
+
+static int uploadMultipleBlock_thread(void* data)
+{
+    HTTPWORKER_THREAD_INFO* threadInfo = (HTTPWORKER_THREAD_INFO*)data;
+    IOTHUB_CLIENT_CORE_LL_HANDLE llHandle = threadInfo->iotHubClientHandle->IoTHubClientLLHandle;
+
+    /*Codes_SRS_IOTHUBCLIENT_99_078: [ The thread shall call `IoTHubClientCore_LL_UploadMultipleBlocksToBlob` or `IoTHubClientCore_LL_UploadMultipleBlocksToBlobEx` passing the information packed in the structure. ]*/
+    IOTHUB_CLIENT_RESULT result;
+
+    srand((unsigned int)get_time(NULL));
+
+    if (threadInfo->uploadBlobMultiblockSavedData.getDataCallback != NULL)
+    {
+        result = IoTHubClientCore_LL_UploadMultipleBlocksToBlob(llHandle, threadInfo->destinationFileName, threadInfo->uploadBlobMultiblockSavedData.getDataCallback, threadInfo->context);
+    }
+    else
+    {
+        result = IoTHubClientCore_LL_UploadMultipleBlocksToBlobEx(llHandle, threadInfo->destinationFileName, threadInfo->uploadBlobMultiblockSavedData.getDataCallbackEx, threadInfo->context);
+    }
+    (void)markThreadReadyToBeGarbageCollected(threadInfo);
+
+    return result;
+}
+
+IOTHUB_CLIENT_RESULT IoTHubClientCore_UploadMultipleBlocksToBlobAsync(IOTHUB_CLIENT_CORE_HANDLE iotHubClientHandle, const char* destinationFileName, IOTHUB_CLIENT_FILE_UPLOAD_GET_DATA_CALLBACK getDataCallback, IOTHUB_CLIENT_FILE_UPLOAD_GET_DATA_CALLBACK_EX getDataCallbackEx, void* context)
+{
+    IOTHUB_CLIENT_RESULT result;
+
+    /*Codes_SRS_IOTHUBCLIENT_99_072: [ If `iotHubClientHandle` is `NULL` then `IoTHubClient_UploadMultipleBlocksToBlobAsync(Ex)` shall fail and return `IOTHUB_CLIENT_INVALID_ARG`. ]*/
+    /*Codes_SRS_IOTHUBCLIENT_99_073: [ If `destinationFileName` is `NULL` then `IoTHubClient_UploadMultipleBlocksToBlobAsync(Ex)` shall fail and return `IOTHUB_CLIENT_INVALID_ARG`. ]*/
+    /*Codes_SRS_IOTHUBCLIENT_99_074: [ If `getDataCallback` is `NULL` then `IoTHubClient_UploadMultipleBlocksToBlobAsync(Ex)` shall fail and return `IOTHUB_CLIENT_INVALID_ARG`. ]*/
+    if (
+        (iotHubClientHandle == NULL) ||
+        (destinationFileName == NULL) ||
+        ((getDataCallback == NULL) && (getDataCallbackEx == NULL))
+        )
+    {
+        LogError("invalid parameters iotHubClientHandle = %p , destinationFileName = %p, getDataCallback = %p, getDataCallbackEx = %p",
+            iotHubClientHandle,
+            destinationFileName,
+            getDataCallback,
+            getDataCallbackEx
+        );
+        result = IOTHUB_CLIENT_INVALID_ARG;
+    }
+    else
+    {
+        /*Codes_SRS_IOTHUBCLIENT_99_075: [ `IoTHubClient_UploadMultipleBlocksToBlobAsync(Ex)` shall copy the `destinationFileName`, `getDataCallback`, `context`  and `iotHubClientHandle` into a structure. ]*/
+        HTTPWORKER_THREAD_INFO *threadInfo = allocateUploadToBlob(destinationFileName, iotHubClientHandle, context);
+        if (threadInfo == NULL)
+        {
+            /*Codes_SRS_IOTHUBCLIENT_02_053: [ If copying to the structure or spawning the thread fails, then IoTHubClient_UploadToBlobAsync shall fail and return IOTHUB_CLIENT_ERROR. ]*/
+            LogError("unable to create upload thread info");
+            result = IOTHUB_CLIENT_ERROR;
+        }
+        else
+        {
+            /*Codes_SRS_IOTHUBCLIENT_99_075: [ `IoTHubClient_UploadMultipleBlocksToBlobAsync(Ex)` shall copy the `destinationFileName`, `getDataCallback`, `context`  and `iotHubClientHandle` into a structure. ]*/
+            threadInfo->uploadBlobMultiblockSavedData.getDataCallback = getDataCallback;
+            threadInfo->uploadBlobMultiblockSavedData.getDataCallbackEx = getDataCallbackEx;
+
+            if ((result = startHttpWorkerThread(iotHubClientHandle, threadInfo, uploadMultipleBlock_thread)) != IOTHUB_CLIENT_OK)
+            {
+                /*Codes_SRS_IOTHUBCLIENT_02_053: [ If copying to the structure or spawning the thread fails, then IoTHubClient_UploadToBlobAsync shall fail and return IOTHUB_CLIENT_ERROR. ]*/
+                LogError("unable to start upload thread");
+                freeHttpWorkerThreadInfo(threadInfo);
+            }
+            else
+            {
+                /*Codes_SRS_IOTHUBCLIENT_99_077: [ If copying to the structure and spawning the thread succeeds, then `IoTHubClient_UploadMultipleBlocksToBlobAsync(Ex)` shall return `IOTHUB_CLIENT_OK`. ]*/
+                result = IOTHUB_CLIENT_OK;
+            }
+        }
+    }
+    return result;
+}
+
+#endif /*DONT_USE_UPLOADTOBLOB*/
+
+IOTHUB_CLIENT_RESULT IoTHubClientCore_SendEventToOutputAsync(IOTHUB_CLIENT_CORE_HANDLE iotHubClientHandle, IOTHUB_MESSAGE_HANDLE eventMessageHandle, const char* outputName, IOTHUB_CLIENT_EVENT_CONFIRMATION_CALLBACK eventConfirmationCallback, void* userContextCallback)
+{
+    IOTHUB_CLIENT_RESULT result;
+
+    if ((iotHubClientHandle == NULL) || (outputName == NULL) || (eventMessageHandle == NULL))
+    {
+        // Codes_SRS_IOTHUBCLIENT_31_100: [ If `iotHubClientHandle`, `outputName`, or `eventConfirmationCallback` is `NULL`, `IoTHubClient_SendEventToOutputAsync` shall return `IOTHUB_CLIENT_INVALID_ARG`. ]
+        LogError("Invalid argument (iotHubClientHandle=%p, outputName=%p, eventMessageHandle=%p)", iotHubClientHandle, outputName, eventMessageHandle);
+        result = IOTHUB_CLIENT_INVALID_ARG;
+    }
+    else
+    {
+        // Codes_SRS_IOTHUBCLIENT_31_101: [ `IoTHubClient_SendEventToOutputAsync` shall set the outputName of the message to send. ]
+        if (IoTHubMessage_SetOutputName(eventMessageHandle, outputName) != IOTHUB_MESSAGE_OK)
+        {
+            LogError("IoTHubMessage_SetOutputName failed");
+            result = IOTHUB_CLIENT_ERROR;
+        }
+        // Codes_SRS_IOTHUBCLIENT_31_102: [ `IoTHubClient_SendEventToOutputAsync` shall invoke `IoTHubClient_SendEventAsync` to send the message. ]
+        else if ((result = IoTHubClientCore_SendEventAsync(iotHubClientHandle, eventMessageHandle, eventConfirmationCallback, userContextCallback)) != IOTHUB_CLIENT_OK)
+        {
+            LogError("Call into IoTHubClient_SendEventAsync failed, result=%d", result);
+        }
+    }
+
+    return result;
+}
+
+
+IOTHUB_CLIENT_RESULT IoTHubClientCore_SetInputMessageCallback(IOTHUB_CLIENT_CORE_HANDLE iotHubClientHandle, const char* inputName, IOTHUB_CLIENT_MESSAGE_CALLBACK_ASYNC eventHandlerCallback, void* userContextCallback)
+{
+    IOTHUB_CLIENT_RESULT result;
+
+    if (iotHubClientHandle == NULL)
+    {
+        result = IOTHUB_CLIENT_INVALID_ARG;
+        LogError("NULL iothubClientHandle");
+    }
+    else
+    {
+        IOTHUB_CLIENT_CORE_INSTANCE* iotHubClientInstance = (IOTHUB_CLIENT_CORE_INSTANCE*)iotHubClientHandle;
+
+        // Codes_SRS_IOTHUBCLIENT_31_098: [ `IoTHubClient_SetMessageCallback` shall start the worker thread if it was not previously started. ]
+        if ((result = StartWorkerThreadIfNeeded(iotHubClientInstance)) != IOTHUB_CLIENT_OK)
+        {
+            result = IOTHUB_CLIENT_ERROR;
+            LogError("Could not start worker thread");
+        }
+        else
+        {
+            if (Lock(iotHubClientInstance->LockHandle) != LOCK_OK)
+            {
+                result = IOTHUB_CLIENT_ERROR;
+                LogError("Could not acquire lock");
+            }
+            else
+            {
+                // Codes_SRS_IOTHUBCLIENT_31_099: [ `IoTHubClient_SetMessageCallback` shall call `IoTHubClient_LL_SetInputMessageCallback`, passing its input arguments ]
+                IOTHUB_INPUTMESSAGE_CALLBACK_CONTEXT inputMessageCallbackContext;
+                inputMessageCallbackContext.iotHubClientHandle = iotHubClientHandle;
+                inputMessageCallbackContext.eventHandlerCallback = eventHandlerCallback;
+                inputMessageCallbackContext.userContextCallback = userContextCallback;
+
+                result = IoTHubClientCore_LL_SetInputMessageCallbackEx(iotHubClientInstance->IoTHubClientLLHandle, inputName, iothub_ll_inputmessage_callback, (void*)&inputMessageCallbackContext, sizeof(inputMessageCallbackContext));
+                (void)Unlock(iotHubClientInstance->LockHandle);
+            }
+        }
+    }
+
+    return result;
+}
+
+#ifdef USE_EDGE_MODULES
+
+HTTPWORKER_THREAD_INFO * allocateMethodInvoke(IOTHUB_CLIENT_CORE_HANDLE iotHubClientHandle, const char* deviceId, const char* moduleId, const char* methodName, const char* methodPayload, unsigned int timeout, IOTHUB_METHOD_INVOKE_CALLBACK methodInvokeCallback, void* context)
+{
+    HTTPWORKER_THREAD_INFO* threadInfo = (HTTPWORKER_THREAD_INFO*)malloc(sizeof(HTTPWORKER_THREAD_INFO));
+    if (threadInfo == NULL)
+    {
+        LogError("unable to allocate thread object");
+    }
+    else
+    {
+        memset(threadInfo, 0, sizeof(HTTPWORKER_THREAD_INFO));
+        threadInfo->workerThreadType = HTTPWORKER_THREAD_INVOKE_METHOD;
+        threadInfo->iotHubClientHandle = iotHubClientHandle;
+        threadInfo->context = context;
+
+        threadInfo->invokeMethodSavedData.timeout = timeout;
+        threadInfo->invokeMethodSavedData.methodInvokeCallback = methodInvokeCallback;
+
+        if ((mallocAndStrcpy_s((char**)&threadInfo->invokeMethodSavedData.deviceId, deviceId) != 0) ||
+            ((moduleId != NULL) && mallocAndStrcpy_s((char**)&threadInfo->invokeMethodSavedData.moduleId, moduleId) != 0) ||
+            (mallocAndStrcpy_s((char**)&threadInfo->invokeMethodSavedData.methodName, methodName) != 0) ||
+            (mallocAndStrcpy_s((char**)&threadInfo->invokeMethodSavedData.methodPayload, methodPayload) != 0))
+        {
+            LogError("Allocating resources failed");
+            freeHttpWorkerThreadInfo(threadInfo);
+            threadInfo = NULL;
+        }
+        else if ((threadInfo->lockGarbage = Lock_Init()) == NULL)
+        {
+            LogError("unable to allocate a lock");
+            freeHttpWorkerThreadInfo(threadInfo);
+            threadInfo = NULL;
+        }
+    }
+
+    return threadInfo;
+}
+
+static int uploadMethodInvoke_thread(void* data)
+{
+    IOTHUB_CLIENT_RESULT result;
+
+    HTTPWORKER_THREAD_INFO* threadInfo = (HTTPWORKER_THREAD_INFO*)data;
+
+    srand((unsigned int)get_time(NULL));
+
+    int responseStatus;
+    unsigned char* responsePayload = NULL;
+    size_t responsePayloadSize;
+
+    result = IoTHubClientCore_LL_GenericMethodInvoke(threadInfo->iotHubClientHandle->IoTHubClientLLHandle,
+                                                     threadInfo->invokeMethodSavedData.deviceId,
+                                                     threadInfo->invokeMethodSavedData.moduleId,
+                                                     threadInfo->invokeMethodSavedData.methodName,
+                                                     threadInfo->invokeMethodSavedData.methodPayload,
+                                                     threadInfo->invokeMethodSavedData.timeout,
+                                                     &responseStatus,
+                                                     &responsePayload,
+                                                     &responsePayloadSize);
+
+    if (threadInfo->invokeMethodSavedData.methodInvokeCallback != NULL)
+    {
+        threadInfo->invokeMethodSavedData.methodInvokeCallback(result, responseStatus, responsePayload, responsePayloadSize, threadInfo->context);
+    }
+
+    if (responsePayload != NULL)
+    {
+        free(responsePayload);
+    }
+
+    (void)markThreadReadyToBeGarbageCollected(threadInfo);
+    return result;
+}
+
+
+IOTHUB_CLIENT_RESULT IoTHubClientCore_GenericMethodInvoke(IOTHUB_CLIENT_CORE_HANDLE iotHubClientHandle, const char* deviceId, const char* moduleId, const char* methodName, const char* methodPayload, unsigned int timeout, IOTHUB_METHOD_INVOKE_CALLBACK methodInvokeCallback, void* context)
+{
+    IOTHUB_CLIENT_RESULT result;
+    HTTPWORKER_THREAD_INFO *threadInfo;
+
+    if ((iotHubClientHandle == NULL) || (deviceId == NULL) || (methodName == NULL) || (methodPayload == NULL))
+    {
+        LogError("Invalid argument (iotHubClientHandle=%p, deviceId=%p, methodName=%p, methodPayload=%p)", iotHubClientHandle, deviceId, methodName, methodPayload);
+        result = IOTHUB_CLIENT_INVALID_ARG;
+    }
+    else if ((threadInfo = allocateMethodInvoke(iotHubClientHandle, deviceId, moduleId, methodName, methodPayload, timeout, methodInvokeCallback, context)) == NULL)
+    {
+        LogError("failed allocating method invoke thread info");
+        result = IOTHUB_CLIENT_ERROR;
+    }
+    else if ((result = startHttpWorkerThread(iotHubClientHandle, threadInfo, uploadMethodInvoke_thread)) != IOTHUB_CLIENT_OK)
+    {
+        LogError("unable to start method invoke thread");
+        freeHttpWorkerThreadInfo(threadInfo);
+    }
+    else
+    {
+        result = IOTHUB_CLIENT_OK;
+    }
+    return result;
+}
+#endif /* USE_EDGE_MODULES */
+
Index: azure_iot_hub_f767zi/trunk/azure_iot_sdk/iothub_client/src/iothub_client_core_ll.c
===================================================================
--- azure_iot_hub_f767zi/trunk/azure_iot_sdk/iothub_client/src/iothub_client_core_ll.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/azure_iot_sdk/iothub_client/src/iothub_client_core_ll.c	(revision 457)
@@ -0,0 +1,3064 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+#include <stdlib.h>
+#include <stdint.h>
+#include <string.h>
+#include <errno.h>
+
+#include "azure_c_shared_utility/optimize_size.h"
+#include "azure_c_shared_utility/gballoc.h"
+#include "azure_c_shared_utility/string_tokenizer.h"
+#include "azure_c_shared_utility/doublylinkedlist.h"
+#include "azure_c_shared_utility/xlogging.h"
+#include "azure_c_shared_utility/tickcounter.h"
+#include "azure_c_shared_utility/constbuffer.h"
+#include "azure_c_shared_utility/platform.h"
+#include "azure_c_shared_utility/singlylinkedlist.h"
+#include "azure_c_shared_utility/shared_util_options.h"
+#include "azure_c_shared_utility/agenttime.h"
+
+#include "iothub_client_core_ll.h"
+#include "iothub_client_options.h"
+#include "iothub_client_version.h"
+#include "iothub_transport_ll.h"
+#include "internal/iothub_client_authorization.h"
+#include "internal/iothub_client_private.h"
+#include "internal/iothub_client_diagnostic.h"
+#include "internal/iothubtransport.h"
+
+#ifndef DONT_USE_UPLOADTOBLOB
+#include "internal/iothub_client_ll_uploadtoblob.h"
+#endif
+
+#ifdef USE_EDGE_MODULES
+#include "azure_c_shared_utility/envvariable.h"
+#include "azure_prov_client/iothub_security_factory.h"
+#include "internal/iothub_client_edge.h"
+#endif
+
+#define LOG_ERROR_RESULT LogError("result = %s", MU_ENUM_TO_STRING(IOTHUB_CLIENT_RESULT, result));
+#define INDEFINITE_TIME ((time_t)(-1))
+#define ERROR_CODE_BECAUSE_DESTROY 0
+
+
+MU_DEFINE_ENUM_STRINGS_WITHOUT_INVALID(IOTHUB_CLIENT_FILE_UPLOAD_RESULT, IOTHUB_CLIENT_FILE_UPLOAD_RESULT_VALUES);
+MU_DEFINE_ENUM_STRINGS_WITHOUT_INVALID(IOTHUB_CLIENT_RESULT, IOTHUB_CLIENT_RESULT_VALUES);
+MU_DEFINE_ENUM_STRINGS_WITHOUT_INVALID(IOTHUB_CLIENT_RETRY_POLICY, IOTHUB_CLIENT_RETRY_POLICY_VALUES);
+MU_DEFINE_ENUM_STRINGS_WITHOUT_INVALID(IOTHUB_CLIENT_STATUS, IOTHUB_CLIENT_STATUS_VALUES);
+MU_DEFINE_ENUM_STRINGS_WITHOUT_INVALID(IOTHUB_IDENTITY_TYPE, IOTHUB_IDENTITY_TYPE_VALUE);
+MU_DEFINE_ENUM_STRINGS_WITHOUT_INVALID(IOTHUB_PROCESS_ITEM_RESULT, IOTHUB_PROCESS_ITEM_RESULT_VALUE);
+MU_DEFINE_ENUM_STRINGS_WITHOUT_INVALID(IOTHUB_CLIENT_IOTHUB_METHOD_STATUS, IOTHUB_CLIENT_IOTHUB_METHOD_STATUS_VALUES);
+MU_DEFINE_ENUM_STRINGS_WITHOUT_INVALID(IOTHUB_CLIENT_CONFIRMATION_RESULT, IOTHUB_CLIENT_CONFIRMATION_RESULT_VALUES);
+MU_DEFINE_ENUM_STRINGS_WITHOUT_INVALID(IOTHUB_CLIENT_CONNECTION_STATUS, IOTHUB_CLIENT_CONNECTION_STATUS_VALUES);
+MU_DEFINE_ENUM_STRINGS_WITHOUT_INVALID(IOTHUB_CLIENT_CONNECTION_STATUS_REASON, IOTHUB_CLIENT_CONNECTION_STATUS_REASON_VALUES);
+MU_DEFINE_ENUM_STRINGS_WITHOUT_INVALID(TRANSPORT_TYPE, TRANSPORT_TYPE_VALUES);
+MU_DEFINE_ENUM_STRINGS_WITHOUT_INVALID(DEVICE_TWIN_UPDATE_STATE, DEVICE_TWIN_UPDATE_STATE_VALUES);
+#ifndef DONT_USE_UPLOADTOBLOB
+MU_DEFINE_ENUM_STRINGS_WITHOUT_INVALID(IOTHUB_CLIENT_FILE_UPLOAD_GET_DATA_RESULT, IOTHUB_CLIENT_FILE_UPLOAD_GET_DATA_RESULT_VALUES);
+#endif // DONT_USE_UPLOADTOBLOB
+
+#define CALLBACK_TYPE_VALUES \
+    CALLBACK_TYPE_NONE,      \
+    CALLBACK_TYPE_SYNC,    \
+    CALLBACK_TYPE_ASYNC
+
+MU_DEFINE_ENUM(CALLBACK_TYPE, CALLBACK_TYPE_VALUES)
+MU_DEFINE_ENUM_STRINGS_WITHOUT_INVALID(CALLBACK_TYPE, CALLBACK_TYPE_VALUES)
+
+typedef struct IOTHUB_METHOD_CALLBACK_DATA_TAG
+{
+    CALLBACK_TYPE type;
+    IOTHUB_CLIENT_DEVICE_METHOD_CALLBACK_ASYNC callbackSync;
+    IOTHUB_CLIENT_INBOUND_DEVICE_METHOD_CALLBACK callbackAsync;
+    void* userContextCallback;
+}IOTHUB_METHOD_CALLBACK_DATA;
+
+typedef struct IOTHUB_EVENT_CALLBACK_TAG
+{
+    STRING_HANDLE inputName;
+    IOTHUB_CLIENT_MESSAGE_CALLBACK_ASYNC callbackAsync;
+    IOTHUB_CLIENT_MESSAGE_CALLBACK_ASYNC_EX callbackAsyncEx;
+    void* userContextCallback;
+    void* userContextCallbackEx;
+}IOTHUB_EVENT_CALLBACK;
+
+typedef struct IOTHUB_MESSAGE_CALLBACK_DATA_TAG
+{
+    CALLBACK_TYPE type;
+    IOTHUB_CLIENT_MESSAGE_CALLBACK_ASYNC callbackSync;
+    IOTHUB_CLIENT_MESSAGE_CALLBACK_ASYNC_EX callbackAsync;
+    void* userContextCallback;
+}IOTHUB_MESSAGE_CALLBACK_DATA;
+
+typedef struct GET_TWIN_CONTEXT_TAG
+{
+    IOTHUB_CLIENT_DEVICE_TWIN_CALLBACK callback;
+    void* context;
+} GET_TWIN_CONTEXT;
+
+typedef struct IOTHUB_CLIENT_CORE_LL_HANDLE_DATA_TAG
+{
+    DLIST_ENTRY waitingToSend;
+    DLIST_ENTRY iot_msg_queue;
+    DLIST_ENTRY iot_ack_queue;
+    TRANSPORT_LL_HANDLE transportHandle;
+    bool isSharedTransport;
+    IOTHUB_DEVICE_HANDLE deviceHandle;
+    TRANSPORT_PROVIDER_FIELDS;
+    IOTHUB_MESSAGE_CALLBACK_DATA messageCallback;
+    IOTHUB_METHOD_CALLBACK_DATA methodCallback;
+    IOTHUB_CLIENT_CONNECTION_STATUS_CALLBACK conStatusCallback;
+    void* conStatusUserContextCallback;
+    time_t lastMessageReceiveTime;
+    TICK_COUNTER_HANDLE tickCounter; /*shared tickcounter used to track message timeouts in waitingToSend list*/
+    tickcounter_ms_t currentMessageTimeout;
+    uint64_t current_device_twin_timeout;
+    IOTHUB_CLIENT_DEVICE_TWIN_CALLBACK deviceTwinCallback;
+    void* deviceTwinContextCallback;
+    IOTHUB_CLIENT_RETRY_POLICY retryPolicy;
+    size_t retryTimeoutLimitInSeconds;
+#ifndef DONT_USE_UPLOADTOBLOB
+    IOTHUB_CLIENT_LL_UPLOADTOBLOB_HANDLE uploadToBlobHandle;
+#endif
+#ifdef USE_EDGE_MODULES
+    IOTHUB_CLIENT_EDGE_HANDLE methodHandle;
+#endif
+    uint32_t data_msg_id;
+    bool complete_twin_update_encountered;
+    IOTHUB_AUTHORIZATION_HANDLE authorization_module;
+    STRING_HANDLE product_info;
+    IOTHUB_DIAGNOSTIC_SETTING_DATA diagnostic_setting;
+    SINGLYLINKEDLIST_HANDLE event_callbacks;  // List of IOTHUB_EVENT_CALLBACK's
+    STRING_HANDLE model_id;
+}IOTHUB_CLIENT_CORE_LL_HANDLE_DATA;
+
+static const char HOSTNAME_TOKEN[] = "HostName";
+static const char DEVICEID_TOKEN[] = "DeviceId";
+static const char X509_TOKEN[] = "x509";
+static const char X509_TOKEN_ONLY_ACCEPTABLE_VALUE[] = "true";
+static const char DEVICEKEY_TOKEN[] = "SharedAccessKey";
+static const char DEVICESAS_TOKEN[] = "SharedAccessSignature";
+static const char PROTOCOL_GATEWAY_HOST_TOKEN[] = "GatewayHostName";
+static const char MODULE_ID_TOKEN[] = "ModuleId";
+static const char PROVISIONING_TOKEN[] = "UseProvisioning";
+static const char PROVISIONING_ACCEPTABLE_VALUE[] = "true";
+
+#ifdef USE_EDGE_MODULES
+/*The following section should be moved to iothub_module_client_ll.c during impending refactor*/
+
+static const char* ENVIRONMENT_VAR_EDGEHUB_CONNECTIONSTRING = "EdgeHubConnectionString";
+static const char* ENVIRONMENT_VAR_EDGEHUB_CACERTIFICATEFILE = "EdgeModuleCACertificateFile";
+static const char* ENVIRONMENT_VAR_EDGEAUTHSCHEME = "IOTEDGE_AUTHSCHEME";
+static const char* ENVIRONMENT_VAR_EDGEDEVICEID = "IOTEDGE_DEVICEID";
+static const char* ENVIRONMENT_VAR_EDGEMODULEID = "IOTEDGE_MODULEID";
+static const char* ENVIRONMENT_VAR_EDGEHUBHOSTNAME = "IOTEDGE_IOTHUBHOSTNAME";
+static const char* ENVIRONMENT_VAR_EDGEGATEWAYHOST = "IOTEDGE_GATEWAYHOSTNAME";
+static const char* SAS_TOKEN_AUTH = "sasToken";
+
+
+typedef struct EDGE_ENVIRONMENT_VARIABLES_TAG
+{
+    const char* connection_string;
+    const char* ca_trusted_certificate_file;
+    const char* auth_scheme;
+    const char* device_id;
+    const char* iothub_name;
+    const char* iothub_suffix;
+    const char* gatewayhostname;
+    const char* module_id;
+    char* iothub_buffer;
+} EDGE_ENVIRONMENT_VARIABLES;
+
+
+static int retrieve_edge_environment_variabes(EDGE_ENVIRONMENT_VARIABLES *edge_environment_variables)
+{
+    int result;
+    const char* edgehubhostname;
+    char* edgehubhostname_separator;
+
+    if ((edge_environment_variables->connection_string = environment_get_variable(ENVIRONMENT_VAR_EDGEHUB_CONNECTIONSTRING)) != NULL)
+    {
+        if ((edge_environment_variables->ca_trusted_certificate_file = environment_get_variable(ENVIRONMENT_VAR_EDGEHUB_CACERTIFICATEFILE)) == NULL)
+        {
+            LogError("Environment variable %s is missing.  When %s is set, it is required", ENVIRONMENT_VAR_EDGEHUB_CACERTIFICATEFILE, ENVIRONMENT_VAR_EDGEHUB_CONNECTIONSTRING);
+            result = MU_FAILURE;
+        }
+        else
+        {
+            // If we can read in the connection string and trusted certs, we're done.
+            result = 0;
+        }
+    }
+    else
+    {
+        // We're NOT using pre-configured EdgeConnection string / certificates.  In this case, we use these environment variables when
+        // communicating to Edge service.
+        if ((edge_environment_variables->auth_scheme = environment_get_variable(ENVIRONMENT_VAR_EDGEAUTHSCHEME)) == NULL)
+        {
+            LogError("Environment %s not set", ENVIRONMENT_VAR_EDGEAUTHSCHEME);
+            result = MU_FAILURE;
+        }
+        else if (strcmp(edge_environment_variables->auth_scheme, SAS_TOKEN_AUTH) != 0)
+        {
+            LogError("Environment %s was set to %s, but only support for %s", ENVIRONMENT_VAR_EDGEAUTHSCHEME, edge_environment_variables->auth_scheme, SAS_TOKEN_AUTH);
+            result = MU_FAILURE;
+        }
+        else if ((edge_environment_variables->device_id = environment_get_variable(ENVIRONMENT_VAR_EDGEDEVICEID)) == NULL)
+        {
+            LogError("Environment %s not set", ENVIRONMENT_VAR_EDGEDEVICEID);
+            result = MU_FAILURE;
+        }
+        else if ((edgehubhostname = environment_get_variable(ENVIRONMENT_VAR_EDGEHUBHOSTNAME)) == NULL)
+        {
+            LogError("Environment %s not set", ENVIRONMENT_VAR_EDGEHUBHOSTNAME);
+            result = MU_FAILURE;
+        }
+        else if ((edge_environment_variables->gatewayhostname = environment_get_variable(ENVIRONMENT_VAR_EDGEGATEWAYHOST)) == NULL)
+        {
+            LogError("Environment %s not set", ENVIRONMENT_VAR_EDGEGATEWAYHOST);
+            result = MU_FAILURE;
+        }
+        else if ((edge_environment_variables->module_id = environment_get_variable(ENVIRONMENT_VAR_EDGEMODULEID)) == NULL)
+        {
+            LogError("Environment %s not set", ENVIRONMENT_VAR_EDGEMODULEID);
+            result = MU_FAILURE;
+        }
+        // Make a copy of just ENVIRONMENT_VAR_EDGEHUBHOSTNAME.  We need to make changes in place (namely inserting a '\0')
+        // and can't do this with system environment variable safely.
+        else if (mallocAndStrcpy_s(&edge_environment_variables->iothub_buffer, edgehubhostname) != 0)
+        {
+            LogError("Unable to copy buffer");
+            result = MU_FAILURE;
+        }
+        else if ((edgehubhostname_separator = strchr(edge_environment_variables->iothub_buffer, '.')) == NULL)
+        {
+            LogError("Environment edgehub %s invalid, requires '.' separator", edge_environment_variables->iothub_buffer);
+            result = MU_FAILURE;
+        }
+        else if (*(edgehubhostname_separator + 1) == 0)
+        {
+            LogError("Environment edgehub %s invalid, no content after '.' separator", edge_environment_variables->iothub_buffer);
+            result = MU_FAILURE;
+        }
+        else
+        {
+            edge_environment_variables->iothub_name = edge_environment_variables->iothub_buffer;
+            *edgehubhostname_separator = 0;
+            edge_environment_variables->iothub_suffix = edgehubhostname_separator + 1;
+            result = 0;
+        }
+    }
+
+    return result;
+}
+
+IOTHUB_CLIENT_EDGE_HANDLE IoTHubClientCore_LL_GetEdgeHandle(IOTHUB_CLIENT_CORE_LL_HANDLE iotHubClientHandle)
+{
+    IOTHUB_CLIENT_EDGE_HANDLE result;
+    if (iotHubClientHandle != NULL)
+    {
+        result = iotHubClientHandle->methodHandle;
+    }
+    else
+    {
+        result = NULL;
+    }
+
+    return result;
+}
+#endif /* USE_EDGE_MODULES */
+
+static void setTransportProtocol(IOTHUB_CLIENT_CORE_LL_HANDLE_DATA* handleData, TRANSPORT_PROVIDER* protocol)
+{
+    handleData->IoTHubTransport_SendMessageDisposition = protocol->IoTHubTransport_SendMessageDisposition;
+    handleData->IoTHubTransport_GetHostname = protocol->IoTHubTransport_GetHostname;
+    handleData->IoTHubTransport_SetOption = protocol->IoTHubTransport_SetOption;
+    handleData->IoTHubTransport_Create = protocol->IoTHubTransport_Create;
+    handleData->IoTHubTransport_Destroy = protocol->IoTHubTransport_Destroy;
+    handleData->IoTHubTransport_Register = protocol->IoTHubTransport_Register;
+    handleData->IoTHubTransport_Unregister = protocol->IoTHubTransport_Unregister;
+    handleData->IoTHubTransport_Subscribe = protocol->IoTHubTransport_Subscribe;
+    handleData->IoTHubTransport_Unsubscribe = protocol->IoTHubTransport_Unsubscribe;
+    handleData->IoTHubTransport_DoWork = protocol->IoTHubTransport_DoWork;
+    handleData->IoTHubTransport_SetRetryPolicy = protocol->IoTHubTransport_SetRetryPolicy;
+    handleData->IoTHubTransport_GetSendStatus = protocol->IoTHubTransport_GetSendStatus;
+    handleData->IoTHubTransport_ProcessItem = protocol->IoTHubTransport_ProcessItem;
+    handleData->IoTHubTransport_Subscribe_DeviceTwin = protocol->IoTHubTransport_Subscribe_DeviceTwin;
+    handleData->IoTHubTransport_Unsubscribe_DeviceTwin = protocol->IoTHubTransport_Unsubscribe_DeviceTwin;
+    handleData->IoTHubTransport_GetTwinAsync = protocol->IoTHubTransport_GetTwinAsync;
+    handleData->IoTHubTransport_Subscribe_DeviceMethod = protocol->IoTHubTransport_Subscribe_DeviceMethod;
+    handleData->IoTHubTransport_Unsubscribe_DeviceMethod = protocol->IoTHubTransport_Unsubscribe_DeviceMethod;
+    handleData->IoTHubTransport_DeviceMethod_Response = protocol->IoTHubTransport_DeviceMethod_Response;
+    handleData->IoTHubTransport_Subscribe_InputQueue = protocol->IoTHubTransport_Subscribe_InputQueue;
+    handleData->IoTHubTransport_Unsubscribe_InputQueue = protocol->IoTHubTransport_Unsubscribe_InputQueue;
+    handleData->IoTHubTransport_SetCallbackContext = protocol->IoTHubTransport_SetCallbackContext;
+    handleData->IoTHubTransport_GetSupportedPlatformInfo = protocol->IoTHubTransport_GetSupportedPlatformInfo;
+}
+
+static bool is_event_equal(IOTHUB_EVENT_CALLBACK *event_callback, const char *input_name)
+{
+    bool result;
+
+    if (event_callback != NULL)
+    {
+        const char* event_input_name = STRING_c_str(event_callback->inputName);
+        if ((event_input_name != NULL) && (input_name != NULL))
+        {
+            // Matched the input queue name of a named handler
+            result = (strcmp(event_input_name, input_name) == 0);
+        }
+        else if ((input_name == NULL) && (event_input_name == NULL))
+        {
+            // Matched the default handler
+            result = true;
+        }
+        else
+        {
+            result = false;
+        }
+    }
+    else
+    {
+        result = false;
+    }
+    return result;
+}
+
+static bool is_event_equal_for_match(LIST_ITEM_HANDLE list_item, const void* match_context)
+{
+    return is_event_equal((IOTHUB_EVENT_CALLBACK*)singlylinkedlist_item_get_value(list_item), (const char*)match_context);
+}
+
+static void device_twin_data_destroy(IOTHUB_DEVICE_TWIN* client_item)
+{
+    CONSTBUFFER_DecRef(client_item->report_data_handle);
+    free(client_item);
+}
+
+static int create_edge_handle(IOTHUB_CLIENT_CORE_LL_HANDLE_DATA* handle_data, const IOTHUB_CLIENT_CONFIG* config, const char* module_id)
+{
+    int result;
+    (void)config;
+    (void)module_id;
+#ifdef USE_EDGE_MODULES
+    /* There is no way to currently distinguish a regular module from a edge module, so this handle is created regardless of if appropriate.
+    However, as a gateway hostname is required in order to create an Edge Handle, we need to at least make sure that exists
+    in order to prevent errors.
+
+    The end result is that all edge modules will have an EdgeHandle, but only some non-edge modules will have it.
+    Regardless, non-edge modules will never be able to use the handle.
+    */
+    if (config->protocolGatewayHostName != NULL)
+    {
+        handle_data->methodHandle = IoTHubClient_EdgeHandle_Create(config, handle_data->authorization_module, module_id);
+
+        if (handle_data->methodHandle == NULL)
+        {
+            LogError("Unable to IoTHubModuleClient_LL_MethodHandle_Create");
+            result = MU_FAILURE;
+        }
+        else
+        {
+            result = 0;
+        }
+    }
+    else
+    {
+        result = 0;
+    }
+
+#else
+    (void)handle_data;
+    result = 0;
+#endif
+    return result;
+}
+
+static int create_blob_upload_module(IOTHUB_CLIENT_CORE_LL_HANDLE_DATA* handle_data, const IOTHUB_CLIENT_CONFIG* config)
+{
+    int result;
+    (void)handle_data;
+    (void)config;
+#ifndef DONT_USE_UPLOADTOBLOB
+    handle_data->uploadToBlobHandle = IoTHubClient_LL_UploadToBlob_Create(config, handle_data->authorization_module);
+    if (handle_data->uploadToBlobHandle == NULL)
+    {
+        LogError("unable to IoTHubClientCore_LL_UploadToBlob_Create");
+        result = MU_FAILURE;
+    }
+    else
+    {
+        result = 0;
+    }
+#else
+    result = 0;
+#endif
+    return result;
+}
+
+static void destroy_blob_upload_module(IOTHUB_CLIENT_CORE_LL_HANDLE_DATA* handle_data)
+{
+    (void)handle_data;
+#ifndef DONT_USE_UPLOADTOBLOB
+    /*Codes_SRS_IOTHUBCLIENT_LL_02_046: [ If creating the TICK_COUNTER_HANDLE fails then IoTHubClientCore_LL_Create shall fail and return NULL. ]*/
+    IoTHubClient_LL_UploadToBlob_Destroy(handle_data->uploadToBlobHandle);
+#endif
+}
+
+static void destroy_module_method_module(IOTHUB_CLIENT_CORE_LL_HANDLE_DATA* handle_data)
+{
+    (void)handle_data;
+#ifdef USE_EDGE_MODULES
+    IoTHubClient_EdgeHandle_Destroy(handle_data->methodHandle);
+#endif
+}
+
+static bool invoke_message_callback(IOTHUB_CLIENT_CORE_LL_HANDLE_DATA* handleData, MESSAGE_CALLBACK_INFO* messageData)
+{
+    bool result;
+    /* Codes_SRS_IOTHUBCLIENT_LL_09_004: [IoTHubClient_LL_GetLastMessageReceiveTime shall return lastMessageReceiveTime in localtime] */
+    handleData->lastMessageReceiveTime = get_time(NULL);
+
+    switch (handleData->messageCallback.type)
+    {
+        case CALLBACK_TYPE_NONE:
+        {
+            /*Codes_SRS_IOTHUBCLIENT_LL_02_032: [If the client is not subscribed to receive messages then IoTHubClient_LL_MessageCallback shall return false.] */
+            LogError("Invalid workflow - not currently set up to accept messages");
+            result = false;
+            break;
+        }
+        case CALLBACK_TYPE_SYNC:
+        {
+            /*Codes_SRS_IOTHUBCLIENT_LL_02_030: [If messageCallbackType is LEGACY then IoTHubClient_LL_MessageCallback shall invoke the last callback function (the parameter messageCallback to IoTHubClient_LL_SetMessageCallback) passing the message and the passed userContextCallback.]*/
+            IOTHUBMESSAGE_DISPOSITION_RESULT cb_result = handleData->messageCallback.callbackSync(messageData->messageHandle, handleData->messageCallback.userContextCallback);
+
+            /*Codes_SRS_IOTHUBCLIENT_LL_10_007: [If messageCallbackType is LEGACY then IoTHubClient_LL_MessageCallback shall send the message disposition as returned by the client to the underlying layer.] */
+            if (handleData->IoTHubTransport_SendMessageDisposition(messageData, cb_result) != IOTHUB_CLIENT_OK)
+            {
+                LogError("IoTHubTransport_SendMessageDisposition failed");
+            }
+            result = true;
+            break;
+        }
+        case CALLBACK_TYPE_ASYNC:
+        {
+            /* Codes_SRS_IOTHUBCLIENT_LL_10_009: [If messageCallbackType is ASYNC then IoTHubClient_LL_MessageCallback shall return what messageCallbacEx returns.] */
+            result = handleData->messageCallback.callbackAsync(messageData, handleData->messageCallback.userContextCallback);
+            if (!result)
+            {
+                LogError("messageCallbackEx failed");
+            }
+            break;
+        }
+        default:
+        {
+            LogError("Invalid state");
+            result = false;
+            break;
+        }
+    }
+
+    return result;
+}
+
+/*Codes_SRS_IOTHUBCLIENT_LL_10_032: ["product_info" - takes a char string as an argument to specify the product information(e.g. `"ProductName/ProductVersion"`). ]*/
+/*Codes_SRS_IOTHUBCLIENT_LL_10_034: ["product_info" - shall store the given string concatenated with the sdk information and the platform information in the form(ProductInfo DeviceSDKName / DeviceSDKVersion(OSName OSVersion; Architecture). ]*/
+static STRING_HANDLE make_product_info(const char* product, PLATFORM_INFO_OPTION option)
+{
+    STRING_HANDLE result;
+    STRING_HANDLE pfi = platform_get_platform_info(option);
+    if (pfi == NULL)
+    {
+        LogError("Platform get info failed");
+        result = NULL;
+    }
+    else
+    {
+        if (product == NULL)
+        {
+            result = STRING_construct_sprintf("%s %s", CLIENT_DEVICE_TYPE_PREFIX CLIENT_DEVICE_BACKSLASH IOTHUB_SDK_VERSION, STRING_c_str(pfi));
+        }
+        else
+        {
+            result = STRING_construct_sprintf("%s %s %s", product, CLIENT_DEVICE_TYPE_PREFIX CLIENT_DEVICE_BACKSLASH IOTHUB_SDK_VERSION, STRING_c_str(pfi));
+        }
+        STRING_delete(pfi);
+    }
+    return result;
+}
+
+static void IoTHubClientCore_LL_SendComplete(PDLIST_ENTRY completed, IOTHUB_CLIENT_CONFIRMATION_RESULT result, void* ctx)
+{
+    /*Codes_SRS_IOTHUBCLIENT_LL_02_022: [If parameter completed is NULL, or parameter handle is NULL then IoTHubClientCore_LL_SendBatch shall return.]*/
+    if (
+        (ctx == NULL) ||
+        (completed == NULL)
+        )
+    {
+        /*"shall return"*/
+        LogError("invalid arg");
+    }
+    else
+    {
+        /*Codes_SRS_IOTHUBCLIENT_LL_02_027: [If parameter result is IOTHUB_CLIENT_CONFIRMATION_ERROR then IoTHubClientCore_LL_SendComplete shall call all the non-NULL callbacks with the result parameter set to IOTHUB_CLIENT_CONFIRMATION_ERROR and the context set to the context passed originally in the SendEventAsync call.] */
+        /*Codes_SRS_IOTHUBCLIENT_LL_02_025: [If parameter result is IOTHUB_CLIENT_CONFIRMATION_OK then IoTHubClientCore_LL_SendComplete shall call all the non-NULL callbacks with the result parameter set to IOTHUB_CLIENT_CONFIRMATION_OK and the context set to the context passed originally in the SendEventAsync call.]*/
+        PDLIST_ENTRY oldest;
+        while ((oldest = DList_RemoveHeadList(completed)) != completed)
+        {
+            IOTHUB_MESSAGE_LIST* messageList = (IOTHUB_MESSAGE_LIST*)containingRecord(oldest, IOTHUB_MESSAGE_LIST, entry);
+            /*Codes_SRS_IOTHUBCLIENT_LL_02_026: [If any callback is NULL then there shall not be a callback call.]*/
+            if (messageList->callback != NULL)
+            {
+                messageList->callback(result, messageList->context);
+            }
+            IoTHubMessage_Destroy(messageList->messageHandle);
+            free(messageList);
+        }
+    }
+}
+
+static void IoTHubClientCore_LL_RetrievePropertyComplete(DEVICE_TWIN_UPDATE_STATE update_state, const unsigned char* payLoad, size_t size, void* ctx)
+{
+    if (ctx == NULL)
+    {
+        /* Codes_SRS_IOTHUBCLIENT_LL_07_013: [ If handle is NULL then IoTHubClientCore_LL_RetrievePropertyComplete shall do nothing.] */
+        LogError("Invalid argument ctx NULL");
+    }
+    else
+    {
+        IOTHUB_CLIENT_CORE_LL_HANDLE_DATA* handleData = (IOTHUB_CLIENT_CORE_LL_HANDLE_DATA*)ctx;
+        /* Codes_SRS_IOTHUBCLIENT_LL_07_014: [ If deviceTwinCallback is NULL then IoTHubClientCore_LL_RetrievePropertyComplete shall do nothing.] */
+        if (handleData->deviceTwinCallback)
+        {
+            /* Codes_SRS_IOTHUBCLIENT_LL_07_015: [ If the the update_state parameter is DEVICE_TWIN_UPDATE_PARTIAL and a DEVICE_TWIN_UPDATE_COMPLETE has not been previously recieved then IoTHubClientCore_LL_RetrievePropertyComplete shall do nothing.] */
+            if (update_state == DEVICE_TWIN_UPDATE_COMPLETE)
+            {
+                handleData->complete_twin_update_encountered = true;
+            }
+            if (handleData->complete_twin_update_encountered)
+            {
+                /* Codes_SRS_IOTHUBCLIENT_LL_07_016: [ If deviceTwinCallback is set and DEVICE_TWIN_UPDATE_COMPLETE has been encountered then IoTHubClientCore_LL_RetrievePropertyComplete shall call deviceTwinCallback.] */
+                handleData->deviceTwinCallback(update_state, payLoad, size, handleData->deviceTwinContextCallback);
+            }
+        }
+    }
+}
+
+static void IoTHubClientCore_LL_ReportedStateComplete(uint32_t item_id, int status_code, void* ctx)
+{
+    /* Codes_SRS_IOTHUBCLIENT_LL_07_002: [ if handle or queue_handle are NULL then IoTHubClientCore_LL_ReportedStateComplete shall do nothing. ] */
+    if (ctx == NULL)
+    {
+        /*"shall return"*/
+        LogError("Invalid argument handle=%p", ctx);
+    }
+    else
+    {
+        IOTHUB_CLIENT_CORE_LL_HANDLE_DATA* handleData = (IOTHUB_CLIENT_CORE_LL_HANDLE_DATA*)ctx;
+
+        /* Codes_SRS_IOTHUBCLIENT_LL_07_003: [ IoTHubClientCore_LL_ReportedStateComplete shall enumerate through the IOTHUB_DEVICE_TWIN structures in queue_handle. ]*/
+        DLIST_ENTRY* client_item = handleData->iot_ack_queue.Flink;
+        while (client_item != &(handleData->iot_ack_queue)) /*while we are not at the end of the list*/
+        {
+            PDLIST_ENTRY next_item = client_item->Flink;
+            IOTHUB_DEVICE_TWIN* queue_data = containingRecord(client_item, IOTHUB_DEVICE_TWIN, entry);
+            if (queue_data->item_id == item_id)
+            {
+                if (queue_data->reported_state_callback != NULL)
+                {
+                    queue_data->reported_state_callback(status_code, queue_data->context);
+                }
+                /*Codes_SRS_IOTHUBCLIENT_LL_07_009: [ IoTHubClientCore_LL_ReportedStateComplete shall remove the IOTHUB_DEVICE_TWIN item from the ack queue.]*/
+                DList_RemoveEntryList(client_item);
+                device_twin_data_destroy(queue_data);
+                break;
+            }
+            client_item = next_item;
+        }
+    }
+}
+
+static void IoTHubClientCore_LL_ConnectionStatusCallBack(IOTHUB_CLIENT_CONNECTION_STATUS status, IOTHUB_CLIENT_CONNECTION_STATUS_REASON reason, void* ctx)
+{
+    /*Codes_SRS_IOTHUBCLIENT_LL_25_113: [If parameter connectionStatus is NULL or parameter handle is NULL then IoTHubClientCore_LL_ConnectionStatusCallBack shall return.]*/
+    if (ctx == NULL)
+    {
+        /*"shall return"*/
+        LogError("invalid arg");
+    }
+    else
+    {
+        IOTHUB_CLIENT_CORE_LL_HANDLE_DATA* handleData = (IOTHUB_CLIENT_CORE_LL_HANDLE_DATA*)ctx;
+
+        /*Codes_SRS_IOTHUBCLIENT_LL_25_114: [IoTHubClientCore_LL_ConnectionStatusCallBack shall call non-callback set by the user from IoTHubClientCore_LL_SetConnectionStatusCallback passing the status, reason and the passed userContextCallback.]*/
+        if (handleData->conStatusCallback != NULL)
+        {
+            handleData->conStatusCallback(status, reason, handleData->conStatusUserContextCallback);
+        }
+    }
+
+}
+
+static const char* IoTHubClientCore_LL_GetProductInfo(void* ctx)
+{
+    const char* result;
+    if (ctx == NULL)
+    {
+        result = NULL;
+        LogError("invalid argument ctx %p", ctx);
+    }
+    else
+    {
+        IOTHUB_CLIENT_CORE_LL_HANDLE_DATA* iothub_data = (IOTHUB_CLIENT_CORE_LL_HANDLE_DATA*)ctx;
+        result = STRING_c_str(iothub_data->product_info);
+    }
+    return result;
+}
+
+static const char* IoTHubClientCore_LL_GetModelId(void* ctx)
+{
+    const char* result;
+    if (ctx == NULL)
+    {
+        result = NULL;
+        LogError("invalid argument ctx %p", ctx);
+    }
+    else
+    {
+        IOTHUB_CLIENT_CORE_LL_HANDLE_DATA* iothub_data = (IOTHUB_CLIENT_CORE_LL_HANDLE_DATA*)ctx;
+        result = STRING_c_str(iothub_data->model_id);
+    }
+    return result;
+}
+
+static bool IoTHubClientCore_LL_MessageCallbackFromInput(MESSAGE_CALLBACK_INFO* messageData, void* ctx)
+{
+    bool result;
+    IOTHUB_CLIENT_CORE_LL_HANDLE_DATA* handleData = (IOTHUB_CLIENT_CORE_LL_HANDLE_DATA*)ctx;
+
+    if ((handleData == NULL) || messageData == NULL)
+    {
+        // Codes_SRS_IOTHUBCLIENT_LL_31_137: [ If either parameter `handle` or `messageData` is `NULL` then `IoTHubClient_LL_MessageCallbackFromInput` shall return `false`.** ]
+        LogError("invalid argument: handle(%p), messageData(%p)", handleData, messageData);
+        result = false;
+    }
+    else if (messageData->messageHandle == NULL)
+    {
+        // Codes_SRS_IOTHUBCLIENT_LL_31_137: [ If either parameter `handle` or `messageData` is `NULL` then `IoTHubClient_LL_MessageCallbackFromInput` shall return `false`.** ]
+        LogError("invalid argument messageData->messageHandle(NULL)");
+        result = false;
+    }
+    else if (handleData->event_callbacks == NULL)
+    {
+        LogError("Callback from input called but no input specific callbacks registered");
+        result = false;
+    }
+    else
+    {
+        const char* inputName = IoTHubMessage_GetInputName(messageData->messageHandle);
+
+        LIST_ITEM_HANDLE item_handle = NULL;
+
+        item_handle = singlylinkedlist_find(handleData->event_callbacks, is_event_equal_for_match, (const void*)inputName);
+
+        if (item_handle == NULL)
+        {
+            // Codes_SRS_IOTHUBCLIENT_LL_31_138: [ If there is no registered handler for the inputName from `IoTHubMessage_GetInputName`, then `IoTHubClient_LL_MessageCallbackFromInput` shall attempt invoke the default handler handler.** ]
+            item_handle = singlylinkedlist_find(handleData->event_callbacks, is_event_equal_for_match, NULL);
+        }
+
+        if (item_handle == NULL)
+        {
+            LogError("Could not find callback (explicit or default) for input queue %s", inputName);
+            result = false;
+        }
+        else
+        {
+            IOTHUB_EVENT_CALLBACK* event_callback = (IOTHUB_EVENT_CALLBACK*)singlylinkedlist_item_get_value(item_handle);
+            if (NULL == event_callback)
+            {
+                LogError("singlylinkedlist_item_get_value for event_callback failed");
+                result = false;
+            }
+            else
+            {
+                // Codes_SRS_IOTHUBCLIENT_LL_09_004: [IoTHubClient_LL_GetLastMessageReceiveTime shall return lastMessageReceiveTime in localtime]
+                handleData->lastMessageReceiveTime = get_time(NULL);
+
+                if (event_callback->callbackAsyncEx != NULL)
+                {
+                    // Codes_SRS_IOTHUBCLIENT_LL_31_139: [ `IoTHubClient_LL_MessageCallbackFromInput` shall the callback from the given inputName queue if it has been registered.** ]
+                    result = event_callback->callbackAsyncEx(messageData, event_callback->userContextCallbackEx);
+                }
+                else
+                {
+                    // Codes_SRS_IOTHUBCLIENT_LL_31_139: [ `IoTHubClient_LL_MessageCallbackFromInput` shall the callback from the given inputName queue if it has been registered.** ]
+                    IOTHUBMESSAGE_DISPOSITION_RESULT cb_result = event_callback->callbackAsync(messageData->messageHandle, event_callback->userContextCallback);
+
+                    // Codes_SRS_IOTHUBCLIENT_LL_31_140: [ `IoTHubClient_LL_MessageCallbackFromInput` shall send the message disposition as returned by the client to the underlying layer and return `true` if an input queue match is found.** ]
+                    if (handleData->IoTHubTransport_SendMessageDisposition(messageData, cb_result) != IOTHUB_CLIENT_OK)
+                    {
+                        LogError("IoTHubTransport_SendMessageDisposition failed");
+                    }
+                    result = true;
+                }
+            }
+        }
+    }
+    return result;
+}
+
+static bool IoTHubClientCore_LL_MessageCallback(MESSAGE_CALLBACK_INFO* messageData, void* ctx)
+{
+    bool result;
+    if ((ctx == NULL) || messageData == NULL)
+    {
+        /*Codes_SRS_IOTHUBCLIENT_LL_02_029: [If parameter handle is NULL then IoTHubClient_LL_MessageCallback shall return IOTHUBMESSAGE_ABANDONED.] */
+        LogError("invalid argument: ctx(%p), messageData(%p)", ctx, messageData);
+        result = false;
+    }
+    else if (messageData->messageHandle == NULL)
+    {
+        /*Codes_SRS_IOTHUBCLIENT_LL_10_004: [If messageHandle field of paramger messageData is NULL then IoTHubClient_LL_MessageCallback shall return IOTHUBMESSAGE_ABANDONED.] */
+        LogError("invalid argument messageData->messageHandle(NULL)");
+        result = false;
+    }
+    else
+    {
+        IOTHUB_CLIENT_CORE_LL_HANDLE_DATA* handleData = (IOTHUB_CLIENT_CORE_LL_HANDLE_DATA*)ctx;
+        return invoke_message_callback(handleData, messageData);
+    }
+    return result;
+}
+
+static int IoTHubClientCore_LL_DeviceMethodComplete(const char* method_name, const unsigned char* payLoad, size_t size, METHOD_HANDLE response_id, void* ctx)
+{
+    int result;
+    if (ctx == NULL)
+    {
+        /* Codes_SRS_IOTHUBCLIENT_LL_07_017: [ If handle or response is NULL then IoTHubClientCore_LL_DeviceMethodComplete shall return 500. ] */
+        LogError("Invalid argument ctx=%p", ctx);
+        result = MU_FAILURE;
+    }
+    else
+    {
+        /* Codes_SRS_IOTHUBCLIENT_LL_07_018: [ If deviceMethodCallback is not NULL IoTHubClientCore_LL_DeviceMethodComplete shall execute deviceMethodCallback and return the status. ] */
+        IOTHUB_CLIENT_CORE_LL_HANDLE_DATA* handleData = (IOTHUB_CLIENT_CORE_LL_HANDLE_DATA*)ctx;
+        switch (handleData->methodCallback.type)
+        {
+            case CALLBACK_TYPE_SYNC:
+            {
+                unsigned char* payload_resp = NULL;
+                size_t response_size = 0;
+                result = handleData->methodCallback.callbackSync(method_name, payLoad, size, &payload_resp, &response_size, handleData->methodCallback.userContextCallback);
+                /* Codes_SRS_IOTHUBCLIENT_LL_07_020: [ deviceMethodCallback shall build the BUFFER_HANDLE with the response payload from the IOTHUB_CLIENT_DEVICE_METHOD_CALLBACK_ASYNC callback. ] */
+                if (payload_resp != NULL && response_size > 0)
+                {
+                    result = handleData->IoTHubTransport_DeviceMethod_Response(handleData->deviceHandle, response_id, payload_resp, response_size, result);
+                }
+                else
+                {
+                    result = MU_FAILURE;
+                }
+                if (payload_resp != NULL)
+                {
+                    free(payload_resp);
+                }
+                break;
+            }
+            case CALLBACK_TYPE_ASYNC:
+                result = handleData->methodCallback.callbackAsync(method_name, payLoad, size, response_id, handleData->methodCallback.userContextCallback);
+                break;
+            default:
+                /* Codes_SRS_IOTHUBCLIENT_LL_07_019: [ If deviceMethodCallback is NULL IoTHubClientCore_LL_DeviceMethodComplete shall return 404. ] */
+                result = 0;
+                break;
+        }
+    }
+    return result;
+}
+
+static IOTHUB_CLIENT_CORE_LL_HANDLE_DATA* initialize_iothub_client(const IOTHUB_CLIENT_CONFIG* client_config, const IOTHUB_CLIENT_DEVICE_CONFIG* device_config, bool use_dev_auth, const char* module_id)
+{
+    IOTHUB_CLIENT_CORE_LL_HANDLE_DATA* result;
+    srand((unsigned int)get_time(NULL));
+
+    result = (IOTHUB_CLIENT_CORE_LL_HANDLE_DATA*)malloc(sizeof(IOTHUB_CLIENT_CORE_LL_HANDLE_DATA));
+    if (result == NULL)
+    {
+        LogError("failure allocating IOTHUB_CLIENT_CORE_LL_HANDLE_DATA");
+    }
+    else
+    {
+        IOTHUB_CLIENT_CONFIG actual_config;
+        const IOTHUB_CLIENT_CONFIG* config = NULL;
+        char* IoTHubName = NULL;
+        char* IoTHubSuffix = NULL;
+
+        memset(result, 0, sizeof(IOTHUB_CLIENT_CORE_LL_HANDLE_DATA));
+        if (use_dev_auth)
+        {
+            if ((result->authorization_module = IoTHubClient_Auth_CreateFromDeviceAuth(client_config->deviceId, module_id)) == NULL)
+            {
+                LogError("Failed create authorization module");
+                free(result);
+                result = NULL;
+            }
+        }
+        else
+        {
+            const char* device_key;
+            const char* device_id;
+            const char* sas_token;
+            if (device_config == NULL)
+            {
+                device_key = client_config->deviceKey;
+                device_id = client_config->deviceId;
+                sas_token = client_config->deviceSasToken;
+            }
+            else
+            {
+                device_key = device_config->deviceKey;
+                device_id = device_config->deviceId;
+                sas_token = device_config->deviceSasToken;
+            }
+
+            /* Codes_SRS_IOTHUBCLIENT_LL_07_029: [ IoTHubClientCore_LL_Create shall create the Auth module with the device_key, device_id, and/or deviceSasToken values ] */
+            if ((result->authorization_module = IoTHubClient_Auth_Create(device_key, device_id, sas_token, module_id)) == NULL)
+            {
+                LogError("Failed create authorization module");
+                free(result);
+                result = NULL;
+            }
+        }
+
+        if (result != NULL)
+        {
+            TRANSPORT_CALLBACKS_INFO transport_cb;
+            memset(&transport_cb, 0, sizeof(TRANSPORT_CALLBACKS_INFO));
+            transport_cb.send_complete_cb = IoTHubClientCore_LL_SendComplete;
+            transport_cb.twin_retrieve_prop_complete_cb = IoTHubClientCore_LL_RetrievePropertyComplete;
+            transport_cb.twin_rpt_state_complete_cb = IoTHubClientCore_LL_ReportedStateComplete;
+            transport_cb.connection_status_cb = IoTHubClientCore_LL_ConnectionStatusCallBack;
+            transport_cb.prod_info_cb = IoTHubClientCore_LL_GetProductInfo;
+            transport_cb.msg_input_cb = IoTHubClientCore_LL_MessageCallbackFromInput;
+            transport_cb.msg_cb = IoTHubClientCore_LL_MessageCallback;
+            transport_cb.method_complete_cb = IoTHubClientCore_LL_DeviceMethodComplete;
+            transport_cb.get_model_id_cb = IoTHubClientCore_LL_GetModelId;
+
+            if (client_config != NULL)
+            {
+                IOTHUBTRANSPORT_CONFIG lowerLayerConfig;
+                memset(&lowerLayerConfig, 0, sizeof(IOTHUBTRANSPORT_CONFIG));
+                /*Codes_SRS_IOTHUBCLIENT_LL_02_006: [IoTHubClientCore_LL_Create shall populate a structure of type IOTHUBTRANSPORT_CONFIG with the information from config parameter and the previous DLIST and shall pass that to the underlying layer _Create function.]*/
+                lowerLayerConfig.upperConfig = client_config;
+                lowerLayerConfig.waitingToSend = &(result->waitingToSend);
+                lowerLayerConfig.auth_module_handle = result->authorization_module;
+                lowerLayerConfig.moduleId = module_id;
+
+                setTransportProtocol(result, (TRANSPORT_PROVIDER*)client_config->protocol());
+                if ((result->transportHandle = result->IoTHubTransport_Create(&lowerLayerConfig, &transport_cb, result)) == NULL)
+                {
+                    /*Codes_SRS_IOTHUBCLIENT_LL_02_007: [If the underlaying layer _Create function fails them IoTHubClientCore_LL_Create shall fail and return NULL.] */
+                    LogError("underlying transport failed");
+                    destroy_blob_upload_module(result);
+                    destroy_module_method_module(result);
+                    tickcounter_destroy(result->tickCounter);
+                    IoTHubClient_Auth_Destroy(result->authorization_module);
+                    free(result);
+                    result = NULL;
+                }
+                else
+                {
+                    /*Codes_SRS_IOTHUBCLIENT_LL_02_008: [Otherwise, IoTHubClientCore_LL_Create shall succeed and return a non-NULL handle.] */
+                    result->isSharedTransport = false;
+                    config = client_config;
+                }
+            }
+            else
+            {
+                STRING_HANDLE transport_hostname = NULL;
+
+                result->transportHandle = device_config->transportHandle;
+                setTransportProtocol(result, (TRANSPORT_PROVIDER*)device_config->protocol());
+
+                if (result->IoTHubTransport_SetCallbackContext(result->transportHandle, result) != 0)
+                {
+                    LogError("unable to set transport callbacks");
+                    IoTHubClient_Auth_Destroy(result->authorization_module);
+                    free(result);
+                    result = NULL;
+                }
+                else if ((transport_hostname = result->IoTHubTransport_GetHostname(result->transportHandle)) == NULL)
+                {
+                    /*Codes_SRS_IOTHUBCLIENT_LL_02_097: [ If creating the data structures fails or instantiating the IOTHUB_CLIENT_LL_UPLOADTOBLOB_HANDLE fails then IoTHubClientCore_LL_CreateWithTransport shall fail and return NULL. ]*/
+                    LogError("unable to determine the transport IoTHub name");
+                    IoTHubClient_Auth_Destroy(result->authorization_module);
+                    free(result);
+                    result = NULL;
+                }
+                else
+                {
+                    const char* hostname = STRING_c_str(transport_hostname);
+                    /*Codes_SRS_IOTHUBCLIENT_LL_02_096: [ IoTHubClientCore_LL_CreateWithTransport shall create the data structures needed to instantiate a IOTHUB_CLIENT_LL_UPLOADTOBLOB_HANDLE. ]*/
+                    /*the first '.' says where the iothubname finishes*/
+                    const char* whereIsDot = strchr(hostname, '.');
+                    if (whereIsDot == NULL)
+                    {
+                        /*Codes_SRS_IOTHUBCLIENT_LL_02_097: [ If creating the data structures fails or instantiating the IOTHUB_CLIENT_LL_UPLOADTOBLOB_HANDLE fails then IoTHubClientCore_LL_CreateWithTransport shall fail and return NULL. ]*/
+                        LogError("unable to determine the IoTHub name");
+                        IoTHubClient_Auth_Destroy(result->authorization_module);
+                        free(result);
+                        result = NULL;
+                    }
+                    else
+                    {
+                        size_t suffix_len = strlen(whereIsDot);
+                        /*Codes_SRS_IOTHUBCLIENT_LL_02_096: [ IoTHubClientCore_LL_CreateWithTransport shall create the data structures needed to instantiate a IOTHUB_CLIENT_LL_UPLOADTOBLOB_HANDLE. ]*/
+                        IoTHubName = (char*)malloc(whereIsDot - hostname + 1);
+                        if (IoTHubName == NULL)
+                        {
+                            /*Codes_SRS_IOTHUBCLIENT_LL_02_097: [ If creating the data structures fails or instantiating the IOTHUB_CLIENT_LL_UPLOADTOBLOB_HANDLE fails then IoTHubClientCore_LL_CreateWithTransport shall fail and return NULL. ]*/
+                            LogError("unable to malloc");
+                            IoTHubClient_Auth_Destroy(result->authorization_module);
+                            free(result);
+                            result = NULL;
+                        }
+                        else if ((IoTHubSuffix = (char*)malloc(suffix_len + 1)) == NULL)
+                        {
+                            /*Codes_SRS_IOTHUBCLIENT_LL_02_097: [ If creating the data structures fails or instantiating the IOTHUB_CLIENT_LL_UPLOADTOBLOB_HANDLE fails then IoTHubClientCore_LL_CreateWithTransport shall fail and return NULL. ]*/
+                            LogError("unable to malloc");
+                            IoTHubClient_Auth_Destroy(result->authorization_module);
+                            free(result);
+                            result = NULL;
+                        }
+                        else
+                        {
+                            memset(IoTHubName, 0, whereIsDot - hostname + 1);
+                            (void)memcpy(IoTHubName, hostname, whereIsDot - hostname);
+                            (void)strcpy(IoTHubSuffix, whereIsDot+1);
+
+                            actual_config.deviceId = device_config->deviceId;
+                            actual_config.deviceKey = device_config->deviceKey;
+                            actual_config.deviceSasToken = device_config->deviceSasToken;
+                            actual_config.iotHubName = IoTHubName;
+                            actual_config.iotHubSuffix = IoTHubSuffix;
+                            actual_config.protocol = NULL; /*irrelevant to IoTHubClientCore_LL_UploadToBlob*/
+                            actual_config.protocolGatewayHostName = NULL; /*irrelevant to IoTHubClientCore_LL_UploadToBlob*/
+
+                            config = &actual_config;
+
+                            /*Codes_SRS_IOTHUBCLIENT_LL_02_008: [Otherwise, IoTHubClientCore_LL_Create shall succeed and return a non-NULL handle.] */
+                            result->isSharedTransport = true;
+                        }
+                    }
+                }
+                STRING_delete(transport_hostname);
+            }
+        }
+        if (result != NULL)
+        {
+            if (create_blob_upload_module(result, config) != 0)
+            {
+                LogError("unable to create blob upload");
+                // Codes_SRS_IOTHUBCLIENT_LL_09_010: [ If any failure occurs `IoTHubClientCore_LL_Create` shall destroy the `transportHandle` only if it has created it ]
+                if (!result->isSharedTransport)
+                {
+                    result->IoTHubTransport_Destroy(result->transportHandle);
+                }
+                destroy_blob_upload_module(result);
+                IoTHubClient_Auth_Destroy(result->authorization_module);
+                free(result);
+                result = NULL;
+            }
+            else if ((module_id != NULL) && create_edge_handle(result, config, module_id) != 0)
+            {
+                LogError("unable to create module method handle");
+                if (!result->isSharedTransport)
+                {
+                    result->IoTHubTransport_Destroy(result->transportHandle);
+                }
+                destroy_blob_upload_module(result);
+                IoTHubClient_Auth_Destroy(result->authorization_module);
+                free(result);
+                result = NULL;
+            }
+            else
+            {
+                PLATFORM_INFO_OPTION supportedPlatformInfo;
+                if ((result->tickCounter = tickcounter_create()) == NULL)
+                {
+                    LogError("unable to get a tickcounter");
+                    // Codes_SRS_IOTHUBCLIENT_LL_09_010: [ If any failure occurs `IoTHubClientCore_LL_Create` shall destroy the `transportHandle` only if it has created it ]
+                    if (!result->isSharedTransport)
+                    {
+                        result->IoTHubTransport_Destroy(result->transportHandle);
+                    }
+                    destroy_blob_upload_module(result);
+                    destroy_module_method_module(result);
+                    IoTHubClient_Auth_Destroy(result->authorization_module);
+                    free(result);
+                    result = NULL;
+                }
+                // Add extended info to product info if required
+                else if (result->IoTHubTransport_GetSupportedPlatformInfo(result->transportHandle, &supportedPlatformInfo) != 0)
+                {
+                    LogError("failed to get supported platform info");
+                    // Codes_SRS_IOTHUBCLIENT_LL_09_010: [ If any failure occurs `IoTHubClientCore_LL_Create` shall destroy the `transportHandle` only if it has created it ]
+                    if (!result->isSharedTransport)
+                    {
+                        result->IoTHubTransport_Destroy(result->transportHandle);
+                    }
+                    tickcounter_destroy(result->tickCounter);
+                    destroy_blob_upload_module(result);
+                    destroy_module_method_module(result);
+                    IoTHubClient_Auth_Destroy(result->authorization_module);
+                    free(result);
+                    result = NULL;
+                }
+                else if ((result->product_info = make_product_info(NULL, supportedPlatformInfo)) == NULL)
+                {
+                    LogError("failed to initialize product info");
+                    // Codes_SRS_IOTHUBCLIENT_LL_09_010: [ If any failure occurs `IoTHubClientCore_LL_Create` shall destroy the `transportHandle` only if it has created it ]
+                    if (!result->isSharedTransport)
+                    {
+                        result->IoTHubTransport_Destroy(result->transportHandle);
+                    }
+                    tickcounter_destroy(result->tickCounter);
+                    destroy_blob_upload_module(result);
+                    destroy_module_method_module(result);
+                    IoTHubClient_Auth_Destroy(result->authorization_module);
+                    free(result);
+                    result = NULL;
+                }
+                else
+                {
+                    /*Codes_SRS_IOTHUBCLIENT_LL_02_004: [Otherwise IoTHubClientCore_LL_Create shall initialize a new DLIST (further called "waitingToSend") containing records with fields of the following types: IOTHUB_MESSAGE_HANDLE, IOTHUB_CLIENT_EVENT_CONFIRMATION_CALLBACK, void*.]*/
+                    DList_InitializeListHead(&(result->waitingToSend));
+                    DList_InitializeListHead(&(result->iot_msg_queue));
+                    DList_InitializeListHead(&(result->iot_ack_queue));
+                    result->messageCallback.type = CALLBACK_TYPE_NONE;
+                    result->methodCallback.type = CALLBACK_TYPE_NONE;
+                    result->lastMessageReceiveTime = INDEFINITE_TIME;
+                    result->data_msg_id = 1;
+
+                    IOTHUB_DEVICE_CONFIG deviceConfig;
+                    deviceConfig.deviceId = config->deviceId;
+                    deviceConfig.deviceKey = config->deviceKey;
+                    deviceConfig.deviceSasToken = config->deviceSasToken;
+                    deviceConfig.authorization_module = result->authorization_module;
+                    deviceConfig.moduleId = module_id;
+
+                    /*Codes_SRS_IOTHUBCLIENT_LL_17_008: [IoTHubClientCore_LL_Create shall call the transport _Register function with a populated structure of type IOTHUB_DEVICE_CONFIG and waitingToSend list.] */
+                    if ((result->deviceHandle = result->IoTHubTransport_Register(result->transportHandle, &deviceConfig, &(result->waitingToSend))) == NULL)
+                    {
+                        LogError("Registering device in transport failed");
+                        IoTHubClient_Auth_Destroy(result->authorization_module);
+                        // Codes_SRS_IOTHUBCLIENT_LL_09_010: [ If any failure occurs `IoTHubClientCore_LL_Create` shall destroy the `transportHandle` only if it has created it ]
+                        if (!result->isSharedTransport)
+                        {
+                            result->IoTHubTransport_Destroy(result->transportHandle);
+                        }
+                        destroy_blob_upload_module(result);
+                        destroy_module_method_module(result);
+                        tickcounter_destroy(result->tickCounter);
+                        STRING_delete(result->product_info);
+                        free(result);
+                        result = NULL;
+                    }
+                    else
+                    {
+                        /*Codes_SRS_IOTHUBCLIENT_LL_02_042: [ By default, messages shall not timeout. ]*/
+                        result->currentMessageTimeout = 0;
+                        result->current_device_twin_timeout = 0;
+
+                        result->diagnostic_setting.currentMessageNumber = 0;
+                        result->diagnostic_setting.diagSamplingPercentage = 0;
+                        /*Codes_SRS_IOTHUBCLIENT_LL_25_124: [ `IoTHubClientCore_LL_Create` shall set the default retry policy as Exponential backoff with jitter and if succeed and return a `non-NULL` handle. ]*/
+                        if (IoTHubClientCore_LL_SetRetryPolicy(result, IOTHUB_CLIENT_RETRY_EXPONENTIAL_BACKOFF_WITH_JITTER, 0) != IOTHUB_CLIENT_OK)
+                        {
+                            LogError("Setting default retry policy in transport failed");
+                            result->IoTHubTransport_Unregister(result->deviceHandle);
+                            IoTHubClient_Auth_Destroy(result->authorization_module);
+                            // Codes_SRS_IOTHUBCLIENT_LL_09_010: [ If any failure occurs `IoTHubClientCore_LL_Create` shall destroy the `transportHandle` only if it has created it ]
+                            if (!result->isSharedTransport)
+                            {
+                                result->IoTHubTransport_Destroy(result->transportHandle);
+                            }
+                            destroy_blob_upload_module(result);
+                            destroy_module_method_module(result);
+                            tickcounter_destroy(result->tickCounter);
+                            STRING_delete(result->product_info);
+                            free(result);
+                            result = NULL;
+                        }
+                    }
+                }
+            }
+        }
+        if (IoTHubName)
+        {
+            free(IoTHubName);
+        }
+        if (IoTHubSuffix)
+        {
+            free(IoTHubSuffix);
+        }
+    }
+    return result;
+}
+
+static uint32_t get_next_item_id(IOTHUB_CLIENT_CORE_LL_HANDLE_DATA* handleData)
+{
+    if (handleData->data_msg_id+1 >= UINT32_MAX)
+    {
+        handleData->data_msg_id = 1;
+    }
+    else
+    {
+        handleData->data_msg_id++;
+    }
+    return handleData->data_msg_id;
+}
+
+static IOTHUB_DEVICE_TWIN* dev_twin_data_create(IOTHUB_CLIENT_CORE_LL_HANDLE_DATA* handleData, uint32_t id, const unsigned char* reportedState, size_t size, IOTHUB_CLIENT_REPORTED_STATE_CALLBACK reportedStateCallback, void* userContextCallback)
+{
+    IOTHUB_DEVICE_TWIN* result = (IOTHUB_DEVICE_TWIN*)malloc(sizeof(IOTHUB_DEVICE_TWIN) );
+    if (result != NULL)
+    {
+        result->report_data_handle = CONSTBUFFER_Create(reportedState, size);
+        if (result->report_data_handle == NULL)
+        {
+            LogError("Failure allocating reported state data");
+            free(result);
+            result = NULL;
+        }
+        else
+        {
+            result->item_id = id;
+            result->ms_timesOutAfter = 0;
+            result->context = userContextCallback;
+            result->reported_state_callback = reportedStateCallback;
+            result->client_handle = handleData;
+            result->device_handle = handleData->deviceHandle;
+        }
+    }
+    else
+    {
+        LogError("Failure allocating device twin information");
+    }
+    return result;
+}
+
+static void on_get_device_twin_completed(DEVICE_TWIN_UPDATE_STATE update_state, const unsigned char* payLoad, size_t size, void* userContextCallback)
+{
+    if (userContextCallback == NULL)
+    {
+        LogError("Invalid argument (userContextCallback=NULL)");
+    }
+    else
+    {
+        GET_TWIN_CONTEXT* getTwinCtx = (GET_TWIN_CONTEXT*)userContextCallback;
+
+        getTwinCtx->callback(update_state, payLoad, size, getTwinCtx->context);
+
+        free(getTwinCtx);
+    }
+}
+
+static void delete_event(IOTHUB_EVENT_CALLBACK* event_callback)
+{
+    STRING_delete(event_callback->inputName);
+    free(event_callback->userContextCallbackEx);
+    free(event_callback);
+}
+
+static void delete_event_callback(const void* item, const void* action_context, bool* continue_processing)
+{
+    (void)action_context;
+    delete_event((IOTHUB_EVENT_CALLBACK*)item);
+    *continue_processing = true;
+}
+
+static void delete_event_callback_list(IOTHUB_CLIENT_CORE_LL_HANDLE_DATA* handleData)
+{
+    if (handleData->event_callbacks != NULL)
+    {
+        singlylinkedlist_foreach(handleData->event_callbacks, delete_event_callback, NULL);
+        singlylinkedlist_destroy(handleData->event_callbacks);
+        handleData->event_callbacks = NULL;
+    }
+}
+
+
+IOTHUB_CLIENT_CORE_LL_HANDLE IoTHubClientCore_LL_CreateFromDeviceAuth(const char* iothub_uri, const char* device_id, IOTHUB_CLIENT_TRANSPORT_PROVIDER protocol)
+{
+    IOTHUB_CLIENT_CORE_LL_HANDLE result;
+    if (iothub_uri == NULL || protocol == NULL || device_id == NULL)
+    {
+        LogError("Input parameter is NULL: iothub_uri: %p  protocol: %p device_id: %p", iothub_uri, protocol, device_id);
+        result = NULL;
+    }
+    else
+    {
+#ifdef USE_PROV_MODULE
+        IOTHUB_CLIENT_CONFIG* config = (IOTHUB_CLIENT_CONFIG*)malloc(sizeof(IOTHUB_CLIENT_CONFIG));
+        if (config == NULL)
+        {
+            /* Codes_SRS_IOTHUBCLIENT_LL_12_012: [If the allocation failed IoTHubClientCore_LL_CreateFromConnectionString  returns NULL]  */
+            LogError("Malloc failed");
+            result = NULL;
+        }
+        else
+        {
+            const char* iterator;
+            const char* initial;
+            char* iothub_name = NULL;
+            char* iothub_suffix = NULL;
+
+            memset(config, 0, sizeof(IOTHUB_CLIENT_CONFIG));
+            config->protocol = protocol;
+            config->deviceId = device_id;
+
+            // Find the iothub suffix
+            initial = iterator = iothub_uri;
+            while (iterator != NULL && *iterator != '\0')
+            {
+                if (*iterator == '.')
+                {
+                    size_t length = iterator - initial;
+                    iothub_name = (char*)malloc(length + 1);
+                    if (iothub_name != NULL)
+                    {
+                        memset(iothub_name, 0, length + 1);
+                        memcpy(iothub_name, initial, length);
+                        config->iotHubName = iothub_name;
+
+                        length = strlen(initial) - length - 1;
+                        iothub_suffix = (char*)malloc(length + 1);
+                        if (iothub_suffix != NULL)
+                        {
+                            memset(iothub_suffix, 0, length + 1);
+                            memcpy(iothub_suffix, iterator + 1, length);
+                            config->iotHubSuffix = iothub_suffix;
+                            break;
+                        }
+                        else
+                        {
+                            LogError("Failed to allocate iothub suffix");
+                            free(iothub_name);
+                            iothub_name = NULL;
+                            result = NULL;
+                        }
+                    }
+                    else
+                    {
+                        LogError("Failed to allocate iothub name");
+                        result = NULL;
+                    }
+                }
+                iterator++;
+            }
+
+            if (config->iotHubName == NULL || config->iotHubSuffix == NULL)
+            {
+                LogError("initialize iothub client");
+                result = NULL;
+            }
+            else
+            {
+                IOTHUB_CLIENT_CORE_LL_HANDLE_DATA* handleData = initialize_iothub_client(config, NULL, true, NULL);
+                if (handleData == NULL)
+                {
+                    LogError("initialize iothub client");
+                    result = NULL;
+                }
+                else
+                {
+                    result = handleData;
+                }
+            }
+
+            free(iothub_name);
+            free(iothub_suffix);
+            free(config);
+        }
+#else
+        LogError("HSM module is not included");
+        result = NULL;
+#endif
+    }
+    return result;
+}
+
+IOTHUB_CLIENT_CORE_LL_HANDLE IoTHubClientCore_LL_CreateFromConnectionString(const char* connectionString, IOTHUB_CLIENT_TRANSPORT_PROVIDER protocol)
+{
+    IOTHUB_CLIENT_CORE_LL_HANDLE result;
+
+    /* Codes_SRS_IOTHUBCLIENT_LL_12_003: [IoTHubClientCore_LL_CreateFromConnectionString shall verify the input parameter and if it is NULL then return NULL] */
+    if (connectionString == NULL)
+    {
+        LogError("Input parameter is NULL: connectionString");
+        result = NULL;
+    }
+    else if (protocol == NULL)
+    {
+        LogError("Input parameter is NULL: protocol");
+        result = NULL;
+    }
+    else
+    {
+        /* Codes_SRS_IOTHUBCLIENT_LL_12_004: [IoTHubClientCore_LL_CreateFromConnectionString shall allocate IOTHUB_CLIENT_CONFIG structure] */
+        IOTHUB_CLIENT_CONFIG* config = (IOTHUB_CLIENT_CONFIG*) malloc(sizeof(IOTHUB_CLIENT_CONFIG));
+        if (config == NULL)
+        {
+            /* Codes_SRS_IOTHUBCLIENT_LL_12_012: [If the allocation failed IoTHubClientCore_LL_CreateFromConnectionString  returns NULL]  */
+            LogError("Malloc failed");
+            result = NULL;
+        }
+        else
+        {
+            STRING_TOKENIZER_HANDLE tokenizer1 = NULL;
+            STRING_HANDLE connString = NULL;
+            STRING_HANDLE tokenString = NULL;
+            STRING_HANDLE valueString = NULL;
+            STRING_HANDLE hostNameString = NULL;
+            STRING_HANDLE hostSuffixString = NULL;
+            STRING_HANDLE deviceIdString = NULL;
+            STRING_HANDLE deviceKeyString = NULL;
+            STRING_HANDLE deviceSasTokenString = NULL;
+            STRING_HANDLE protocolGateway = NULL;
+            STRING_HANDLE moduleId = NULL;
+
+            memset(config, 0, sizeof(*config));
+            config->protocol = protocol;
+
+            /* Codes_SRS_IOTHUBCLIENT_LL_04_002: [If it does not, it shall pass the protocolGatewayHostName NULL.] */
+            config->protocolGatewayHostName = NULL;
+
+            if ((connString = STRING_construct(connectionString)) == NULL)
+            {
+                LogError("Error constructing connectiong String");
+                result = NULL;
+            }
+            else if ((tokenizer1 = STRING_TOKENIZER_create(connString)) == NULL)
+            {
+                LogError("Error creating Tokenizer");
+                result = NULL;
+            }
+            else if ((tokenString = STRING_new()) == NULL)
+            {
+                LogError("Error creating Token String");
+                result = NULL;
+            }
+            else if ((valueString = STRING_new()) == NULL)
+            {
+                LogError("Error creating Value String");
+                result = NULL;
+            }
+            else if ((hostNameString = STRING_new()) == NULL)
+            {
+                LogError("Error creating HostName String");
+                result = NULL;
+            }
+            else if ((hostSuffixString = STRING_new()) == NULL)
+            {
+                LogError("Error creating HostSuffix String");
+                result = NULL;
+            }
+            /* Codes_SRS_IOTHUBCLIENT_LL_12_005: [IoTHubClientCore_LL_CreateFromConnectionString shall try to parse the connectionString input parameter for the following structure: "Key1=value1;key2=value2;key3=value3..."] */
+            /* Codes_SRS_IOTHUBCLIENT_LL_12_006: [IoTHubClientCore_LL_CreateFromConnectionString shall verify the existence of the following Key/Value pairs in the connection string: HostName, DeviceId, SharedAccessKey, SharedAccessSignature or x509]  */
+            else
+            {
+                int isx509found = 0;
+                bool use_provisioning = false;
+                while ((STRING_TOKENIZER_get_next_token(tokenizer1, tokenString, "=") == 0))
+                {
+                    if (STRING_TOKENIZER_get_next_token(tokenizer1, valueString, ";") != 0)
+                    {
+                        LogError("Tokenizer error");
+                        break;
+                    }
+                    else
+                    {
+                        if (tokenString != NULL)
+                        {
+                            /* Codes_SRS_IOTHUBCLIENT_LL_12_010: [IoTHubClientCore_LL_CreateFromConnectionString shall fill up the IOTHUB_CLIENT_CONFIG structure using the following mapping: iotHubName = Name, iotHubSuffix = Suffix, deviceId = DeviceId, deviceKey = SharedAccessKey or deviceSasToken = SharedAccessSignature] */
+                            const char* s_token = STRING_c_str(tokenString);
+                            if (strcmp(s_token, HOSTNAME_TOKEN) == 0)
+                            {
+                                /* Codes_SRS_IOTHUBCLIENT_LL_12_009: [IoTHubClientCore_LL_CreateFromConnectionString shall split the value of HostName to Name and Suffix using the first "." as a separator] */
+                                STRING_TOKENIZER_HANDLE tokenizer2 = NULL;
+                                if ((tokenizer2 = STRING_TOKENIZER_create(valueString)) == NULL)
+                                {
+                                    LogError("Error creating Tokenizer");
+                                    break;
+                                }
+                                else
+                                {
+                                    /* Codes_SRS_IOTHUBCLIENT_LL_12_015: [If the string split failed, IoTHubClientCore_LL_CreateFromConnectionString returns NULL ] */
+                                    if (STRING_TOKENIZER_get_next_token(tokenizer2, hostNameString, ".") != 0)
+                                    {
+                                        LogError("Tokenizer error");
+                                        STRING_TOKENIZER_destroy(tokenizer2);
+                                        break;
+                                    }
+                                    else
+                                    {
+                                        config->iotHubName = STRING_c_str(hostNameString);
+                                        if (STRING_TOKENIZER_get_next_token(tokenizer2, hostSuffixString, ";") != 0)
+                                        {
+                                            LogError("Tokenizer error");
+                                            STRING_TOKENIZER_destroy(tokenizer2);
+                                            break;
+                                        }
+                                        else
+                                        {
+                                            config->iotHubSuffix = STRING_c_str(hostSuffixString);
+                                        }
+                                    }
+                                    STRING_TOKENIZER_destroy(tokenizer2);
+                                }
+                            }
+                            else if (strcmp(s_token, DEVICEID_TOKEN) == 0)
+                            {
+                                deviceIdString = STRING_clone(valueString);
+                                if (deviceIdString != NULL)
+                                {
+                                    config->deviceId = STRING_c_str(deviceIdString);
+                                }
+                                else
+                                {
+                                    LogError("Failure cloning device id string");
+                                    break;
+                                }
+                            }
+                            else if (strcmp(s_token, DEVICEKEY_TOKEN) == 0)
+                            {
+                                deviceKeyString = STRING_clone(valueString);
+                                if (deviceKeyString != NULL)
+                                {
+                                    config->deviceKey = STRING_c_str(deviceKeyString);
+                                }
+                                else
+                                {
+                                    LogError("Failure cloning device key string");
+                                    break;
+                                }
+                            }
+                            else if (strcmp(s_token, DEVICESAS_TOKEN) == 0)
+                            {
+                                deviceSasTokenString = STRING_clone(valueString);
+                                if (deviceSasTokenString != NULL)
+                                {
+                                    config->deviceSasToken = STRING_c_str(deviceSasTokenString);
+                                }
+                                else
+                                {
+                                    LogError("Failure cloning device sasToken string");
+                                    break;
+                                }
+                            }
+                            else if (strcmp(s_token, X509_TOKEN) == 0)
+                            {
+                                if (strcmp(STRING_c_str(valueString), X509_TOKEN_ONLY_ACCEPTABLE_VALUE) != 0)
+                                {
+                                    LogError("x509 option has wrong value, the only acceptable one is \"true\"");
+                                    break;
+                                }
+                                else
+                                {
+                                    isx509found = 1;
+                                }
+                            }
+                            else if (strcmp(s_token, PROVISIONING_TOKEN) == 0)
+                            {
+                                if (strcmp(STRING_c_str(valueString), PROVISIONING_ACCEPTABLE_VALUE) != 0)
+                                {
+                                    LogError("provisioning option has wrong value, the only acceptable one is \"true\"");
+                                    break;
+                                }
+                                else
+                                {
+                                    use_provisioning = 1;
+                                }
+                            }
+
+                            /* Codes_SRS_IOTHUBCLIENT_LL_04_001: [IoTHubClientCore_LL_CreateFromConnectionString shall verify the existence of key/value pair GatewayHostName. If it does exist it shall pass the value to IoTHubClientCore_LL_Create API.] */
+                            else if (strcmp(s_token, PROTOCOL_GATEWAY_HOST_TOKEN) == 0)
+                            {
+                                protocolGateway = STRING_clone(valueString);
+                                if (protocolGateway != NULL)
+                                {
+                                    config->protocolGatewayHostName = STRING_c_str(protocolGateway);
+                                }
+                                else
+                                {
+                                    LogError("Failure cloning protocol Gateway Name");
+                                    break;
+                                }
+                            }
+                            /*Codes_SRS_IOTHUBCLIENT_LL_31_126: [IoTHubClient_LL_CreateFromConnectionString shall optionally parse ModuleId, if present.] */
+                            else if (strcmp(s_token, MODULE_ID_TOKEN) == 0)
+                            {
+                                moduleId = STRING_clone(valueString);
+                                if (moduleId == NULL)
+                                {
+                                    LogError("Failure cloning moduleId string");
+                                    break;
+                                }
+                            }
+                            else
+                            {
+                                // If we get an unknown token, log it to error stream but do not cause a fatal error.
+                                LogError("Unknown token <%s> in connection string.  Ignoring error and continuing to parse", s_token);
+                            }
+                        }
+                    }
+                }
+                /* parsing is done - check the result */
+                if (config->iotHubName == NULL)
+                {
+                    LogError("iotHubName is not found");
+                    result = NULL;
+                }
+                else if (config->iotHubSuffix == NULL)
+                {
+                    LogError("iotHubSuffix is not found");
+                    result = NULL;
+                }
+                else if (config->deviceId == NULL)
+                {
+                    LogError("deviceId is not found");
+                    result = NULL;
+                }
+                else if (!(
+                    ((!use_provisioning && !isx509found) && (config->deviceSasToken == NULL) ^ (config->deviceKey == NULL)) ||
+                    ((use_provisioning || isx509found) && (config->deviceSasToken == NULL) && (config->deviceKey == NULL))
+                    ))
+                {
+                    LogError("invalid combination of x509, provisioning, deviceSasToken and deviceKey");
+                    result = NULL;
+                }
+                else
+                {
+                    /* Codes_SRS_IOTHUBCLIENT_LL_12_011: [IoTHubClientCore_LL_CreateFromConnectionString shall call into the IoTHubClientCore_LL_Create API with the current structure and returns with the return value of it] */
+                    result = initialize_iothub_client(config, NULL, use_provisioning, STRING_c_str(moduleId));
+                    if (result == NULL)
+                    {
+                        LogError("IoTHubClientCore_LL_Create failed");
+                    }
+                    else
+                    {
+                        /*return as is*/
+                    }
+                }
+            }
+            if (deviceSasTokenString != NULL)
+                STRING_delete(deviceSasTokenString);
+            if (deviceKeyString != NULL)
+                STRING_delete(deviceKeyString);
+            if (deviceIdString != NULL)
+                STRING_delete(deviceIdString);
+            if (hostSuffixString != NULL)
+                STRING_delete(hostSuffixString);
+            if (hostNameString != NULL)
+                STRING_delete(hostNameString);
+            if (valueString != NULL)
+                STRING_delete(valueString);
+            if (tokenString != NULL)
+                STRING_delete(tokenString);
+            if (connString != NULL)
+                STRING_delete(connString);
+            if (protocolGateway != NULL)
+                STRING_delete(protocolGateway);
+            if (moduleId != NULL)
+                STRING_delete(moduleId);
+
+            if (tokenizer1 != NULL)
+                STRING_TOKENIZER_destroy(tokenizer1);
+
+            free(config);
+        }
+    }
+    return result;
+}
+
+IOTHUB_CLIENT_CORE_LL_HANDLE IoTHubClientCore_LL_CreateImpl(const IOTHUB_CLIENT_CONFIG* config, const char* module_id, bool use_dev_auth)
+{
+    IOTHUB_CLIENT_CORE_LL_HANDLE result;
+    /*Codes_SRS_IOTHUBCLIENT_LL_02_001: [IoTHubClientCore_LL_Create shall return NULL if config parameter is NULL or protocol field is NULL.]*/
+    if(
+        (config == NULL) ||
+        (config->protocol == NULL)
+        )
+    {
+        result = NULL;
+        LogError("invalid configuration (NULL detected)");
+    }
+    else
+    {
+        IOTHUB_CLIENT_CORE_LL_HANDLE_DATA* handleData = initialize_iothub_client(config, NULL, use_dev_auth, module_id);
+        if (handleData == NULL)
+        {
+            LogError("initialize iothub client");
+            result = NULL;
+        }
+        else
+        {
+            result = handleData;
+        }
+    }
+
+    return result;
+}
+
+IOTHUB_CLIENT_CORE_LL_HANDLE IoTHubClientCore_LL_Create(const IOTHUB_CLIENT_CONFIG* config)
+{
+    return IoTHubClientCore_LL_CreateImpl(config, NULL, false);
+}
+
+#ifdef USE_EDGE_MODULES
+IOTHUB_CLIENT_CORE_LL_HANDLE IoTHubClientCore_LL_CreateFromEnvironment(IOTHUB_CLIENT_TRANSPORT_PROVIDER protocol)
+{
+    IOTHUB_CLIENT_CORE_LL_HANDLE_DATA* result;
+    EDGE_ENVIRONMENT_VARIABLES edge_environment_variables;
+
+    memset(&edge_environment_variables, 0, sizeof(edge_environment_variables));
+
+    if (retrieve_edge_environment_variabes(&edge_environment_variables) != 0)
+    {
+        LogError("retrieve_edge_environment_variabes failed");
+        result = NULL;
+    }
+    // The presence of a connection string environment variable means we use it, ignoring other settings
+    else if (edge_environment_variables.connection_string != NULL)
+    {
+        if ((result = IoTHubClientCore_LL_CreateFromConnectionString(edge_environment_variables.connection_string, protocol)) == NULL)
+        {
+            LogError("IoTHubClientCore_LL_CreateFromConnectionString fails");
+        }
+    }
+    else if (iothub_security_init(IOTHUB_SECURITY_TYPE_HTTP_EDGE) != 0)
+    {
+        LogError("iothub_security_init failed");
+        result = NULL;
+    }
+    else
+    {
+        IOTHUB_CLIENT_CONFIG client_config;
+
+        memset(&client_config, 0, sizeof(client_config));
+        client_config.protocol = protocol;
+        client_config.deviceId = edge_environment_variables.device_id;
+        client_config.iotHubName = edge_environment_variables.iothub_name;
+        client_config.iotHubSuffix = edge_environment_variables.iothub_suffix;
+        client_config.protocolGatewayHostName = edge_environment_variables.gatewayhostname;
+
+        if ((result = IoTHubClientCore_LL_CreateImpl(&client_config, edge_environment_variables.module_id, true)) == NULL)
+        {
+            LogError("IoTHubClientCore_LL_CreateImpl fails");
+        }
+    }
+
+    if (result != NULL)
+    {
+        // Because the Edge Hub almost always use self-signed certificates, we need to specify which certificates to trust.  We need to do
+        // this regardless of how we created the underlying IOTHUB_CLIENT_CORE_LL_HANDLE_DATA.
+        IOTHUB_CLIENT_RESULT setTrustResult;
+        char* trustedCertificate = IoTHubClient_Auth_Get_TrustBundle(result->authorization_module, edge_environment_variables.ca_trusted_certificate_file);
+
+        if (trustedCertificate == NULL)
+        {
+            LogError("IoTHubClient_Auth_Get_TrustBundle failed");
+            IoTHubClientCore_LL_Destroy(result);
+            result = NULL;
+        }
+        else if ((setTrustResult = IoTHubClientCore_LL_SetOption(result, OPTION_TRUSTED_CERT, trustedCertificate)) != IOTHUB_CLIENT_OK)
+        {
+            LogError("IoTHubClientCore_LL_SetOption failed, err = %d", setTrustResult);
+            IoTHubClientCore_LL_Destroy(result);
+            result = NULL;
+        }
+
+        free(trustedCertificate);
+    }
+
+    free(edge_environment_variables.iothub_buffer);
+    return result;
+}
+#endif
+
+
+IOTHUB_CLIENT_CORE_LL_HANDLE IoTHubClientCore_LL_CreateWithTransport(const IOTHUB_CLIENT_DEVICE_CONFIG * config)
+{
+    IOTHUB_CLIENT_CORE_LL_HANDLE result;
+    /*Codes_SRS_IOTHUBCLIENT_LL_17_001: [IoTHubClientCore_LL_CreateWithTransport shall return NULL if config parameter is NULL, or protocol field is NULL or transportHandle is NULL.]*/
+    if (
+        (config == NULL) ||
+        (config->protocol == NULL) ||
+        (config->transportHandle == NULL) ||
+        /*Codes_SRS_IOTHUBCLIENT_LL_02_098: [ IoTHubClientCore_LL_CreateWithTransport shall fail and return NULL if both config->deviceKey AND config->deviceSasToken are NULL. ]*/
+        ((config->deviceKey == NULL) && (config->deviceSasToken == NULL))
+        )
+    {
+        result = NULL;
+        LogError("invalid configuration (NULL detected)");
+    }
+    else
+    {
+        result = initialize_iothub_client(NULL, config, false, NULL);
+    }
+    return result;
+}
+
+void IoTHubClientCore_LL_Destroy(IOTHUB_CLIENT_CORE_LL_HANDLE iotHubClientHandle)
+{
+    /*Codes_SRS_IOTHUBCLIENT_LL_02_009: [IoTHubClientCore_LL_Destroy shall do nothing if parameter iotHubClientHandle is NULL.]*/
+    if (iotHubClientHandle != NULL)
+    {
+        PDLIST_ENTRY unsend;
+        /*Codes_SRS_IOTHUBCLIENT_LL_17_010: [IoTHubClientCore_LL_Destroy  shall call the underlaying layer's _Unregister function] */
+        IOTHUB_CLIENT_CORE_LL_HANDLE_DATA* handleData = (IOTHUB_CLIENT_CORE_LL_HANDLE_DATA*)iotHubClientHandle;
+        handleData->IoTHubTransport_Unregister(handleData->deviceHandle);
+        if (handleData->isSharedTransport == false)
+        {
+            /*Codes_SRS_IOTHUBCLIENT_LL_02_010: [If iotHubClientHandle was not created by IoTHubClientCore_LL_CreateWithTransport, IoTHubClientCore_LL_Destroy  shall call the underlaying layer's _Destroy function.] */
+            handleData->IoTHubTransport_Destroy(handleData->transportHandle);
+        }
+        /*if any, remove the items currently not send*/
+        while ((unsend = DList_RemoveHeadList(&(handleData->waitingToSend))) != &(handleData->waitingToSend))
+        {
+            IOTHUB_MESSAGE_LIST* temp = containingRecord(unsend, IOTHUB_MESSAGE_LIST, entry);
+            /*Codes_SRS_IOTHUBCLIENT_LL_02_033: [Otherwise, IoTHubClientCore_LL_Destroy shall complete all the event message callbacks that are in the waitingToSend list with the result IOTHUB_CLIENT_CONFIRMATION_BECAUSE_DESTROY.] */
+            if (temp->callback != NULL)
+            {
+                temp->callback(IOTHUB_CLIENT_CONFIRMATION_BECAUSE_DESTROY, temp->context);
+            }
+            IoTHubMessage_Destroy(temp->messageHandle);
+            free(temp);
+        }
+
+        /* Codes_SRS_IOTHUBCLIENT_LL_07_007: [ IoTHubClientCore_LL_Destroy shall iterate the device twin queues and destroy any remaining items. ] */
+        while ((unsend = DList_RemoveHeadList(&(handleData->iot_msg_queue))) != &(handleData->iot_msg_queue))
+        {
+            IOTHUB_DEVICE_TWIN* temp = containingRecord(unsend, IOTHUB_DEVICE_TWIN, entry);
+
+            // The Twin reported properties status codes are based on HTTP codes and provided by the service.
+            // Following design already implemented in the transport layer, the status code shall be artificially 
+            // returned as zero to indicate the report was not sent due to the client being destroyed.
+            if (temp->reported_state_callback != NULL)
+            {
+                temp->reported_state_callback(ERROR_CODE_BECAUSE_DESTROY, temp->context);
+            }  
+
+            device_twin_data_destroy(temp);
+        }
+        while ((unsend = DList_RemoveHeadList(&(handleData->iot_ack_queue))) != &(handleData->iot_ack_queue))
+        {
+            IOTHUB_DEVICE_TWIN* temp = containingRecord(unsend, IOTHUB_DEVICE_TWIN, entry);
+
+            // The Twin reported properties status codes are based on HTTP codes and provided by the service.
+            // Following design already implemented in the transport layer, the status code shall be artificially 
+            // returned as zero to indicate the report was not sent due to the client being destroyed.
+            if (temp->reported_state_callback != NULL)
+            {
+                temp->reported_state_callback(ERROR_CODE_BECAUSE_DESTROY, temp->context);
+            }
+
+            device_twin_data_destroy(temp);
+        }
+
+        /* Codes_SRS_IOTHUBCLIENT_LL_31_141: [ IoTHubClient_LL_Destroy shall iterate registered callbacks for input queues and destroy any remaining items. ] */
+        delete_event_callback_list(handleData);
+
+        /*Codes_SRS_IOTHUBCLIENT_LL_17_011: [IoTHubClientCore_LL_Destroy  shall free the resources allocated by IoTHubClient (if any).] */
+        IoTHubClient_Auth_Destroy(handleData->authorization_module);
+        tickcounter_destroy(handleData->tickCounter);
+#ifndef DONT_USE_UPLOADTOBLOB
+        IoTHubClient_LL_UploadToBlob_Destroy(handleData->uploadToBlobHandle);
+#endif
+#ifdef USE_EDGE_MODULES
+        IoTHubClient_EdgeHandle_Destroy(handleData->methodHandle);
+#endif
+        STRING_delete(handleData->product_info);
+        STRING_delete(handleData->model_id);
+        free(handleData);
+    }
+}
+
+/*Codes_SRS_IOTHUBCLIENT_LL_02_044: [ Messages already delivered to IoTHubClientCore_LL shall not have their timeouts modified by a new call to IoTHubClientCore_LL_SetOption. ]*/
+/*returns 0 on success, any other value is error*/
+static int attach_ms_timesOutAfter(IOTHUB_CLIENT_CORE_LL_HANDLE_DATA* handleData, IOTHUB_MESSAGE_LIST *newEntry)
+{
+    int result;
+    /*Codes_SRS_IOTHUBCLIENT_LL_02_043: [ Calling IoTHubClientCore_LL_SetOption with value set to "0" shall disable the timeout mechanism for all new messages. ]*/
+    if (handleData->currentMessageTimeout == 0)
+    {
+        newEntry->ms_timesOutAfter = 0; /*do not timeout*/
+        newEntry->message_timeout_value = 0;
+        result = 0;
+    }
+    else
+    {
+        /*Codes_SRS_IOTHUBCLIENT_LL_02_039: [ "messageTimeout" - once IoTHubClientCore_LL_SendEventAsync is called the message shall timeout after value miliseconds. Value is a pointer to a tickcounter_ms_t. ]*/
+        if (tickcounter_get_current_ms(handleData->tickCounter, &newEntry->ms_timesOutAfter) != 0)
+        {
+            result = MU_FAILURE;
+            LogError("unable to get the current relative tickcount");
+        }
+        else
+        {
+            newEntry->message_timeout_value = handleData->currentMessageTimeout;
+            result = 0;
+        }
+    }
+    return result;
+}
+
+IOTHUB_CLIENT_RESULT IoTHubClientCore_LL_SendEventAsync(IOTHUB_CLIENT_CORE_LL_HANDLE iotHubClientHandle, IOTHUB_MESSAGE_HANDLE eventMessageHandle, IOTHUB_CLIENT_EVENT_CONFIRMATION_CALLBACK eventConfirmationCallback, void* userContextCallback)
+{
+    IOTHUB_CLIENT_RESULT result;
+    /*Codes_SRS_IOTHUBCLIENT_LL_02_011: [IoTHubClientCore_LL_SendEventAsync shall fail and return IOTHUB_CLIENT_INVALID_ARG if parameter iotHubClientHandle or eventMessageHandle is NULL.]*/
+    if (
+        (iotHubClientHandle == NULL) ||
+        (eventMessageHandle == NULL) ||
+        /*Codes_SRS_IOTHUBCLIENT_LL_02_012: [IoTHubClientCore_LL_SendEventAsync shall fail and return IOTHUB_CLIENT_INVALID_ARG if parameter eventConfirmationCallback is NULL and userContextCallback is not NULL.] */
+        ((eventConfirmationCallback == NULL) && (userContextCallback != NULL))
+        )
+    {
+        result = IOTHUB_CLIENT_INVALID_ARG;
+        LOG_ERROR_RESULT;
+    }
+    else
+    {
+        IOTHUB_MESSAGE_LIST *newEntry = (IOTHUB_MESSAGE_LIST*)malloc(sizeof(IOTHUB_MESSAGE_LIST));
+        if (newEntry == NULL)
+        {
+            result = IOTHUB_CLIENT_ERROR;
+            LOG_ERROR_RESULT;
+        }
+        else
+        {
+            IOTHUB_CLIENT_CORE_LL_HANDLE_DATA* handleData = (IOTHUB_CLIENT_CORE_LL_HANDLE_DATA*)iotHubClientHandle;
+
+            if (attach_ms_timesOutAfter(handleData, newEntry) != 0)
+            {
+                result = IOTHUB_CLIENT_ERROR;
+                LOG_ERROR_RESULT;
+                free(newEntry);
+            }
+            else
+            {
+                /*Codes_SRS_IOTHUBCLIENT_LL_02_013: [IoTHubClientCore_LL_SendEventAsync shall add the DLIST waitingToSend a new record cloning the information from eventMessageHandle, eventConfirmationCallback, userContextCallback.]*/
+                if ((newEntry->messageHandle = IoTHubMessage_Clone(eventMessageHandle)) == NULL)
+                {
+                    result = IOTHUB_CLIENT_ERROR;
+                    free(newEntry);
+                    LOG_ERROR_RESULT;
+                }
+                else if (IoTHubClient_Diagnostic_AddIfNecessary(&handleData->diagnostic_setting, newEntry->messageHandle) != 0)
+                {
+                    /*Codes_SRS_IOTHUBCLIENT_LL_02_014: [If cloning and/or adding the information/diagnostic fails for any reason, IoTHubClientCore_LL_SendEventAsync shall fail and return IOTHUB_CLIENT_ERROR.] */
+                    result = IOTHUB_CLIENT_ERROR;
+                    IoTHubMessage_Destroy(newEntry->messageHandle);
+                    free(newEntry);
+                    LOG_ERROR_RESULT;
+                }
+                else
+                {
+                    /*Codes_SRS_IOTHUBCLIENT_LL_02_013: [IoTHubClientCore_LL_SendEventAsync shall add the DLIST waitingToSend a new record cloning the information from eventMessageHandle, eventConfirmationCallback, userContextCallback.]*/
+                    newEntry->callback = eventConfirmationCallback;
+                    newEntry->context = userContextCallback;
+                    DList_InsertTailList(&(iotHubClientHandle->waitingToSend), &(newEntry->entry));
+                    /*Codes_SRS_IOTHUBCLIENT_LL_02_015: [Otherwise IoTHubClientCore_LL_SendEventAsync shall succeed and return IOTHUB_CLIENT_OK.] */
+                    result = IOTHUB_CLIENT_OK;
+                }
+            }
+        }
+    }
+    return result;
+}
+
+IOTHUB_CLIENT_RESULT IoTHubClientCore_LL_SetMessageCallback(IOTHUB_CLIENT_CORE_LL_HANDLE iotHubClientHandle, IOTHUB_CLIENT_MESSAGE_CALLBACK_ASYNC messageCallback, void* userContextCallback)
+{
+    IOTHUB_CLIENT_RESULT result;
+    if (iotHubClientHandle == NULL)
+    {
+        /*Codes_SRS_IOTHUBCLIENT_LL_02_016: [IoTHubClientCore_LL_SetMessageCallback shall fail and return IOTHUB_CLIENT_INVALID_ARG if parameter iotHubClientHandle is NULL.] */
+        LogError("Invalid argument - iotHubClientHandle is NULL");
+        result = IOTHUB_CLIENT_INVALID_ARG;
+    }
+    else
+    {
+        IOTHUB_CLIENT_CORE_LL_HANDLE_DATA* handleData = (IOTHUB_CLIENT_CORE_LL_HANDLE_DATA*)iotHubClientHandle;
+        if (messageCallback == NULL)
+        {
+            if (handleData->messageCallback.type == CALLBACK_TYPE_NONE)
+            {
+                /*Codes_SRS_IOTHUBCLIENT_LL_10_010: [If parameter messageCallback is NULL and the _SetMessageCallback had not been called to subscribe for messages, then IoTHubClientCore_LL_SetMessageCallback shall fail and return IOTHUB_CLIENT_ERROR.] */
+                LogError("not currently set to accept or process incoming messages.");
+                result = IOTHUB_CLIENT_ERROR;
+            }
+            else if (handleData->messageCallback.type == CALLBACK_TYPE_ASYNC)
+            {
+                /*Codes_SRS_IOTHUBCLIENT_LL_10_010: [If parameter messageCallback is NULL and the _SetMessageCallback had not been called to subscribe for messages, then IoTHubClientCore_LL_SetMessageCallback shall fail and return IOTHUB_CLIENT_ERROR.] */
+                LogError("Invalid workflow sequence. Please unsubscribe using the IoTHubClientCore_LL_SetMessageCallback_Ex function.");
+                result = IOTHUB_CLIENT_ERROR;
+            }
+            else
+            {
+                /*Codes_SRS_IOTHUBCLIENT_LL_02_019: [If parameter messageCallback is NULL then IoTHubClientCore_LL_SetMessageCallback shall call the underlying layer's _Unsubscribe function and return IOTHUB_CLIENT_OK.] */
+                handleData->IoTHubTransport_Unsubscribe(handleData->deviceHandle);
+                handleData->messageCallback.type = CALLBACK_TYPE_NONE;
+                handleData->messageCallback.callbackSync = NULL;
+                handleData->messageCallback.callbackAsync = NULL;
+                handleData->messageCallback.userContextCallback = NULL;
+                result = IOTHUB_CLIENT_OK;
+            }
+        }
+        else
+        {
+            if (handleData->messageCallback.type == CALLBACK_TYPE_ASYNC)
+            {
+                /* Codes_SRS_IOTHUBCLIENT_LL_10_011: [If parameter messageCallback is non-NULL and the _SetMessageCallback_Ex had been used to susbscribe for messages, then IoTHubClientCore_LL_SetMessageCallback shall fail and return IOTHUB_CLIENT_ERROR.] */
+                LogError("Invalid workflow sequence. Please unsubscribe using the IoTHubClientCore_LL_SetMessageCallback_Ex function before subscribing with MessageCallback.");
+                result = IOTHUB_CLIENT_ERROR;
+            }
+            else
+            {
+                if (handleData->IoTHubTransport_Subscribe(handleData->deviceHandle) == 0)
+                {
+                    /*Codes_SRS_IOTHUBCLIENT_LL_02_017: [If parameter messageCallback is non-NULL then IoTHubClientCore_LL_SetMessageCallback shall call the underlying layer's _Subscribe function.]*/
+                    handleData->messageCallback.type = CALLBACK_TYPE_SYNC;
+                    handleData->messageCallback.callbackSync = messageCallback;
+                    handleData->messageCallback.userContextCallback = userContextCallback;
+                    result = IOTHUB_CLIENT_OK;
+                }
+                else
+                {
+                    /*Codes_SRS_IOTHUBCLIENT_LL_02_018: [If the underlying layer's _Subscribe function fails, then IoTHubClientCore_LL_SetMessageCallback shall fail and return IOTHUB_CLIENT_ERROR. Otherwise IoTHubClientCore_LL_SetMessageCallback shall succeed and return IOTHUB_CLIENT_OK.]*/
+                    LogError("IoTHubTransport_Subscribe failed");
+                    handleData->messageCallback.type = CALLBACK_TYPE_NONE;
+                    handleData->messageCallback.callbackSync = NULL;
+                    handleData->messageCallback.callbackAsync = NULL;
+                    handleData->messageCallback.userContextCallback = NULL;
+                    result = IOTHUB_CLIENT_ERROR;
+                }
+            }
+        }
+    }
+    return result;
+}
+
+IOTHUB_CLIENT_RESULT IoTHubClientCore_LL_SetMessageCallback_Ex(IOTHUB_CLIENT_CORE_LL_HANDLE iotHubClientHandle, IOTHUB_CLIENT_MESSAGE_CALLBACK_ASYNC_EX messageCallback, void* userContextCallback)
+{
+    IOTHUB_CLIENT_RESULT result;
+    if (iotHubClientHandle == NULL)
+    {
+        /*Codes_SRS_IOTHUBCLIENT_LL_10_021: [IoTHubClientCore_LL_SetMessageCallback_Ex shall fail and return IOTHUB_CLIENT_INVALID_ARG if parameter iotHubClientHandle is NULL.]*/
+        LogError("Invalid argument - iotHubClientHandle is NULL");
+        result = IOTHUB_CLIENT_INVALID_ARG;
+    }
+    else
+    {
+        IOTHUB_CLIENT_CORE_LL_HANDLE_DATA* handleData = (IOTHUB_CLIENT_CORE_LL_HANDLE_DATA*)iotHubClientHandle;
+        if (messageCallback == NULL)
+        {
+            if (handleData->messageCallback.type == CALLBACK_TYPE_NONE)
+            {
+                /*Codes_SRS_IOTHUBCLIENT_LL_10_018: [If parameter messageCallback is NULL and IoTHubClientCore_LL_SetMessageCallback_Ex had not been used to subscribe for messages, then IoTHubClientCore_LL_SetMessageCallback_Ex shall fail and return IOTHUB_CLIENT_ERROR.] */
+                LogError("not currently set to accept or process incoming messages.");
+                result = IOTHUB_CLIENT_ERROR;
+            }
+            else if (handleData->messageCallback.type == CALLBACK_TYPE_SYNC)
+            {
+                /*Codes_SRS_IOTHUBCLIENT_LL_10_019: [If parameter messageCallback is NULL and IoTHubClientCore_LL_SetMessageCallback had been used to subscribe for messages, then IoTHubClientCore_LL_SetMessageCallback_Ex shall fail and return IOTHUB_CLIENT_ERROR.] */
+                LogError("Invalid workflow sequence. Please unsubscribe using the IoTHubClientCore_LL_SetMessageCallback function.");
+                result = IOTHUB_CLIENT_ERROR;
+            }
+            else
+            {
+                /*Codes_SRS_IOTHUBCLIENT_LL_10_023: [If parameter messageCallback is NULL then IoTHubClientCore_LL_SetMessageCallback_Ex shall call the underlying layer's _Unsubscribe function and return IOTHUB_CLIENT_OK.] */
+                handleData->IoTHubTransport_Unsubscribe(handleData->deviceHandle);
+                handleData->messageCallback.type = CALLBACK_TYPE_NONE;
+                handleData->messageCallback.callbackSync = NULL;
+                handleData->messageCallback.callbackAsync = NULL;
+                handleData->messageCallback.userContextCallback = NULL;
+                result = IOTHUB_CLIENT_OK;
+            }
+        }
+        else
+        {
+            if (handleData->messageCallback.type == CALLBACK_TYPE_SYNC)
+            {
+                /*Codes_SRS_IOTHUBCLIENT_LL_10_020: [If parameter messageCallback is non-NULL, and IoTHubClientCore_LL_SetMessageCallback had been used to subscribe for messages, then IoTHubClientCore_LL_SetMessageCallback_Ex shall fail and return IOTHUB_CLIENT_ERROR.] */
+                LogError("Invalid workflow sequence. Please unsubscribe using the IoTHubClientCore_LL_MessageCallbackEx function before subscribing with MessageCallback.");
+                result = IOTHUB_CLIENT_ERROR;
+            }
+            else
+            {
+                if (handleData->IoTHubTransport_Subscribe(handleData->deviceHandle) == 0)
+                {
+                    /*Codes_SRS_IOTHUBCLIENT_LL_10_024: [If parameter messageCallback is non-NULL then IoTHubClientCore_LL_SetMessageCallback_Ex shall call the underlying layer's _Subscribe function.]*/
+                    handleData->messageCallback.type = CALLBACK_TYPE_ASYNC;
+                    handleData->messageCallback.callbackAsync = messageCallback;
+                    handleData->messageCallback.userContextCallback = userContextCallback;
+                    result = IOTHUB_CLIENT_OK;
+                }
+                else
+                {
+                    /*Codes_SRS_IOTHUBCLIENT_LL_10_025: [If the underlying layer's _Subscribe function fails, then IoTHubClientCore_LL_SetMessageCallback_Ex shall fail and return IOTHUB_CLIENT_ERROR. Otherwise IoTHubClientCore_LL_SetMessageCallback_Ex shall succeed and return IOTHUB_CLIENT_OK.] */
+                    LogError("IoTHubTransport_Subscribe failed");
+                    handleData->messageCallback.type = CALLBACK_TYPE_NONE;
+                    handleData->messageCallback.callbackSync = NULL;
+                    handleData->messageCallback.callbackAsync = NULL;
+                    handleData->messageCallback.userContextCallback = NULL;
+                    result = IOTHUB_CLIENT_ERROR;
+                }
+            }
+        }
+    }
+    return result;
+}
+
+IOTHUB_CLIENT_RESULT IoTHubClientCore_LL_SendMessageDisposition(IOTHUB_CLIENT_CORE_LL_HANDLE iotHubClientHandle, MESSAGE_CALLBACK_INFO* message_data, IOTHUBMESSAGE_DISPOSITION_RESULT disposition)
+{
+    IOTHUB_CLIENT_RESULT result;
+    if ((iotHubClientHandle == NULL) || (message_data == NULL))
+    {
+        /*Codes_SRS_IOTHUBCLIENT_LL_10_026: [IoTHubClientCore_LL_SendMessageDisposition shall fail and return IOTHUB_CLIENT_INVALID_ARG if parameter iotHubClientHandle is NULL.]*/
+        LogError("Invalid argument handle=%p, message=%p", iotHubClientHandle, message_data);
+        result = IOTHUB_CLIENT_INVALID_ARG;
+    }
+    else
+    {
+        IOTHUB_CLIENT_CORE_LL_HANDLE_DATA* handleData = (IOTHUB_CLIENT_CORE_LL_HANDLE_DATA*)iotHubClientHandle;
+        /*Codes_SRS_IOTHUBCLIENT_LL_10_027: [IoTHubClientCore_LL_SendMessageDisposition shall return the result from calling the underlying layer's _Send_Message_Disposition.]*/
+        result = handleData->IoTHubTransport_SendMessageDisposition(message_data, disposition);
+    }
+    return result;
+}
+
+static void DoTimeouts(IOTHUB_CLIENT_CORE_LL_HANDLE_DATA* handleData)
+{
+    tickcounter_ms_t nowTick;
+    if (tickcounter_get_current_ms(handleData->tickCounter, &nowTick) != 0)
+    {
+        LogError("unable to get the current ms, timeouts will not be processed");
+    }
+    else
+    {
+        DLIST_ENTRY* currentItemInWaitingToSend = handleData->waitingToSend.Flink;
+        while (currentItemInWaitingToSend != &(handleData->waitingToSend)) /*while we are not at the end of the list*/
+        {
+            IOTHUB_MESSAGE_LIST* fullEntry = containingRecord(currentItemInWaitingToSend, IOTHUB_MESSAGE_LIST, entry);
+            /*Codes_SRS_IOTHUBCLIENT_LL_02_041: [ If more than value miliseconds have passed since the call to IoTHubClientCore_LL_SendEventAsync then the message callback shall be called with a status code of IOTHUB_CLIENT_CONFIRMATION_TIMEOUT. ]*/
+            if ((fullEntry->ms_timesOutAfter != 0) && ((nowTick - fullEntry->ms_timesOutAfter) > fullEntry->message_timeout_value))
+            {
+                PDLIST_ENTRY theNext = currentItemInWaitingToSend->Flink; /*need to save the next item, because the below operations are destructive*/
+                DList_RemoveEntryList(currentItemInWaitingToSend);
+                if (fullEntry->callback != NULL)
+                {
+                    fullEntry->callback(IOTHUB_CLIENT_CONFIRMATION_MESSAGE_TIMEOUT, fullEntry->context);
+                }
+                IoTHubMessage_Destroy(fullEntry->messageHandle); /*because it has been cloned*/
+                free(fullEntry);
+                currentItemInWaitingToSend = theNext;
+            }
+            else
+            {
+                currentItemInWaitingToSend = currentItemInWaitingToSend->Flink;
+            }
+        }
+    }
+}
+
+void IoTHubClientCore_LL_DoWork(IOTHUB_CLIENT_CORE_LL_HANDLE iotHubClientHandle)
+{
+    /*Codes_SRS_IOTHUBCLIENT_LL_02_020: [If parameter iotHubClientHandle is NULL then IoTHubClientCore_LL_DoWork shall not perform any action.] */
+    if (iotHubClientHandle != NULL)
+    {
+        IOTHUB_CLIENT_CORE_LL_HANDLE_DATA* handleData = (IOTHUB_CLIENT_CORE_LL_HANDLE_DATA*)iotHubClientHandle;
+        DoTimeouts(handleData);
+
+        /*Codes_SRS_IOTHUBCLIENT_LL_07_008: [ IoTHubClientCore_LL_DoWork shall iterate the message queue and execute the underlying transports IoTHubTransport_ProcessItem function for each item. ] */
+        DLIST_ENTRY* client_item = handleData->iot_msg_queue.Flink;
+        while (client_item != &(handleData->iot_msg_queue)) /*while we are not at the end of the list*/
+        {
+            PDLIST_ENTRY next_item = client_item->Flink;
+
+            IOTHUB_DEVICE_TWIN* queue_data = containingRecord(client_item, IOTHUB_DEVICE_TWIN, entry);
+            IOTHUB_IDENTITY_INFO identity_info;
+            identity_info.device_twin = queue_data;
+            IOTHUB_PROCESS_ITEM_RESULT process_results =  handleData->IoTHubTransport_ProcessItem(handleData->transportHandle, IOTHUB_TYPE_DEVICE_TWIN, &identity_info);
+            if (process_results == IOTHUB_PROCESS_CONTINUE || process_results == IOTHUB_PROCESS_NOT_CONNECTED)
+            {
+                /*Codes_SRS_IOTHUBCLIENT_LL_07_010: [ If 'IoTHubTransport_ProcessItem' returns IOTHUB_PROCESS_CONTINUE or IOTHUB_PROCESS_NOT_CONNECTED IoTHubClientCore_LL_DoWork shall continue on to call the underlaying layer's _DoWork function. ]*/
+                break;
+            }
+            else
+            {
+                DList_RemoveEntryList(client_item);
+                if (process_results == IOTHUB_PROCESS_OK)
+                {
+                    /*Codes_SRS_IOTHUBCLIENT_LL_07_011: [ If 'IoTHubTransport_ProcessItem' returns IOTHUB_PROCESS_OK IoTHubClientCore_LL_DoWork shall add the IOTHUB_DEVICE_TWIN to the ack queue. ]*/
+                    DList_InsertTailList(&(iotHubClientHandle->iot_ack_queue), &(queue_data->entry));
+                }
+                else
+                {
+                    /*Codes_SRS_IOTHUBCLIENT_LL_07_012: [ If 'IoTHubTransport_ProcessItem' returns any other value IoTHubClientCore_LL_DoWork shall destroy the IOTHUB_DEVICE_TWIN item. ]*/
+                    LogError("Failure queue processing item");
+                    device_twin_data_destroy(queue_data);
+                }
+            }
+            // Move along to the next item
+            client_item = next_item;
+        }
+
+        /*Codes_SRS_IOTHUBCLIENT_LL_02_021: [Otherwise, IoTHubClientCore_LL_DoWork shall invoke the underlaying layer's _DoWork function.]*/
+        handleData->IoTHubTransport_DoWork(handleData->transportHandle);
+    }
+}
+
+IOTHUB_CLIENT_RESULT IoTHubClientCore_LL_GetSendStatus(IOTHUB_CLIENT_CORE_LL_HANDLE iotHubClientHandle, IOTHUB_CLIENT_STATUS *iotHubClientStatus)
+{
+    IOTHUB_CLIENT_RESULT result;
+
+    /* Codes_SRS_IOTHUBCLIENT_09_007: [IoTHubClient_GetSendStatus shall return IOTHUB_CLIENT_INVALID_ARG if called with NULL parameter] */
+    if (iotHubClientHandle == NULL || iotHubClientStatus == NULL)
+    {
+        result = IOTHUB_CLIENT_INVALID_ARG;
+        LOG_ERROR_RESULT;
+    }
+    else
+    {
+        IOTHUB_CLIENT_CORE_LL_HANDLE_DATA* handleData = (IOTHUB_CLIENT_CORE_LL_HANDLE_DATA*)iotHubClientHandle;
+
+        /* Codes_SRS_IOTHUBCLIENT_09_008: [IoTHubClient_GetSendStatus shall return IOTHUB_CLIENT_OK and status IOTHUB_CLIENT_SEND_STATUS_IDLE if there is currently no items to be sent] */
+        /* Codes_SRS_IOTHUBCLIENT_09_009: [IoTHubClient_GetSendStatus shall return IOTHUB_CLIENT_OK and status IOTHUB_CLIENT_SEND_STATUS_BUSY if there are currently items to be sent] */
+        result = handleData->IoTHubTransport_GetSendStatus(handleData->deviceHandle, iotHubClientStatus);
+    }
+
+    return result;
+}
+
+IOTHUB_CLIENT_RESULT IoTHubClientCore_LL_SetConnectionStatusCallback(IOTHUB_CLIENT_CORE_LL_HANDLE iotHubClientHandle, IOTHUB_CLIENT_CONNECTION_STATUS_CALLBACK connectionStatusCallback, void * userContextCallback)
+{
+    IOTHUB_CLIENT_RESULT result;
+    /*Codes_SRS_IOTHUBCLIENT_LL_25_111: [IoTHubClientCore_LL_SetConnectionStatusCallback shall return IOTHUB_CLIENT_INVALID_ARG if called with NULL parameter iotHubClientHandle**]** */
+    if (iotHubClientHandle == NULL)
+    {
+        result = IOTHUB_CLIENT_INVALID_ARG;
+        LOG_ERROR_RESULT;
+    }
+    else
+    {
+        IOTHUB_CLIENT_CORE_LL_HANDLE_DATA* handleData = (IOTHUB_CLIENT_CORE_LL_HANDLE_DATA*)iotHubClientHandle;
+        /*Codes_SRS_IOTHUBCLIENT_LL_25_112: [IoTHubClientCore_LL_SetConnectionStatusCallback shall return IOTHUB_CLIENT_OK and save the callback and userContext as a member of the handle.] */
+        handleData->conStatusCallback = connectionStatusCallback;
+        handleData->conStatusUserContextCallback = userContextCallback;
+        result = IOTHUB_CLIENT_OK;
+    }
+
+    return result;
+}
+
+IOTHUB_CLIENT_RESULT IoTHubClientCore_LL_SetRetryPolicy(IOTHUB_CLIENT_CORE_LL_HANDLE iotHubClientHandle, IOTHUB_CLIENT_RETRY_POLICY retryPolicy, size_t retryTimeoutLimitInSeconds)
+{
+    IOTHUB_CLIENT_RESULT result;
+    IOTHUB_CLIENT_CORE_LL_HANDLE_DATA* handleData = (IOTHUB_CLIENT_CORE_LL_HANDLE_DATA*)iotHubClientHandle;
+
+    /* Codes_SRS_IOTHUBCLIENT_LL_25_116: [If iotHubClientHandle, retryPolicy or retryTimeoutLimitinSeconds is NULL, IoTHubClientCore_LL_GetRetryPolicy shall return IOTHUB_CLIENT_INVALID_ARG]*/
+    if (handleData == NULL)
+    {
+        result = IOTHUB_CLIENT_INVALID_ARG;
+        LOG_ERROR_RESULT;
+    }
+    else
+    {
+        if (handleData->transportHandle == NULL)
+        {
+            result = IOTHUB_CLIENT_ERROR;
+            LOG_ERROR_RESULT;
+        }
+        else
+        {
+            if (handleData->IoTHubTransport_SetRetryPolicy(handleData->transportHandle, retryPolicy, retryTimeoutLimitInSeconds) != 0)
+            {
+                result = IOTHUB_CLIENT_ERROR;
+                LOG_ERROR_RESULT;
+            }
+            else
+            {
+                /* Codes_SRS_IOTHUBCLIENT_LL_25_118: [IoTHubClientCore_LL_SetRetryPolicy shall save connection retry policies specified by the user to retryPolicy in struct IOTHUB_CLIENT_CORE_LL_HANDLE_DATA] */
+                /* Codes_SRS_IOTHUBCLIENT_LL_25_119: [IoTHubClientCore_LL_SetRetryPolicy shall save retryTimeoutLimitInSeconds in seconds to retryTimeout in struct IOTHUB_CLIENT_CORE_LL_HANDLE_DATA] */
+                handleData->retryPolicy = retryPolicy;
+                handleData->retryTimeoutLimitInSeconds = retryTimeoutLimitInSeconds;
+                result = IOTHUB_CLIENT_OK;
+            }
+        }
+    }
+    return result;
+}
+
+IOTHUB_CLIENT_RESULT IoTHubClientCore_LL_GetRetryPolicy(IOTHUB_CLIENT_CORE_LL_HANDLE iotHubClientHandle, IOTHUB_CLIENT_RETRY_POLICY* retryPolicy, size_t* retryTimeoutLimitInSeconds)
+{
+    IOTHUB_CLIENT_RESULT result;
+
+    /* Codes_SRS_IOTHUBCLIENT_LL_09_001: [IoTHubClientCore_LL_GetLastMessageReceiveTime shall return IOTHUB_CLIENT_INVALID_ARG if any of the arguments is NULL] */
+    if (iotHubClientHandle == NULL || retryPolicy == NULL || retryTimeoutLimitInSeconds == NULL)
+    {
+        LogError("Invalid parameter IOTHUB_CLIENT_CORE_LL_HANDLE iotHubClientHandle = %p, IOTHUB_CLIENT_RETRY_POLICY* retryPolicy = %p, size_t* retryTimeoutLimitInSeconds = %p", iotHubClientHandle, retryPolicy, retryTimeoutLimitInSeconds);
+        result = IOTHUB_CLIENT_INVALID_ARG;
+    }
+    else
+    {
+        IOTHUB_CLIENT_CORE_LL_HANDLE_DATA* handleData = (IOTHUB_CLIENT_CORE_LL_HANDLE_DATA*)iotHubClientHandle;
+
+        *retryPolicy = handleData->retryPolicy;
+        *retryTimeoutLimitInSeconds = handleData->retryTimeoutLimitInSeconds;
+        result = IOTHUB_CLIENT_OK;
+    }
+
+    return result;
+}
+
+IOTHUB_CLIENT_RESULT IoTHubClientCore_LL_GetLastMessageReceiveTime(IOTHUB_CLIENT_CORE_LL_HANDLE iotHubClientHandle, time_t* lastMessageReceiveTime)
+{
+    IOTHUB_CLIENT_RESULT result;
+    IOTHUB_CLIENT_CORE_LL_HANDLE_DATA* handleData = (IOTHUB_CLIENT_CORE_LL_HANDLE_DATA*)iotHubClientHandle;
+
+    /* Codes_SRS_IOTHUBCLIENT_LL_09_001: [IoTHubClientCore_LL_GetLastMessageReceiveTime shall return IOTHUB_CLIENT_INVALID_ARG if any of the arguments is NULL] */
+    if (handleData == NULL || lastMessageReceiveTime == NULL)
+    {
+        result = IOTHUB_CLIENT_INVALID_ARG;
+        LOG_ERROR_RESULT;
+    }
+    else
+    {
+        /* Codes_SRS_IOTHUBCLIENT_LL_09_002: [IoTHubClientCore_LL_GetLastMessageReceiveTime shall return IOTHUB_CLIENT_INDEFINITE_TIME - and not set 'lastMessageReceiveTime' - if it is unable to provide the time for the last commands] */
+        if (handleData->lastMessageReceiveTime == INDEFINITE_TIME)
+        {
+            result = IOTHUB_CLIENT_INDEFINITE_TIME;
+            LOG_ERROR_RESULT;
+        }
+        else
+        {
+            /* Codes_SRS_IOTHUBCLIENT_LL_09_003: [IoTHubClientCore_LL_GetLastMessageReceiveTime shall return IOTHUB_CLIENT_OK if it wrote in the lastMessageReceiveTime the time when the last command was received] */
+            /* Codes_SRS_IOTHUBCLIENT_LL_09_004: [IoTHubClientCore_LL_GetLastMessageReceiveTime shall return lastMessageReceiveTime in localtime] */
+            *lastMessageReceiveTime = handleData->lastMessageReceiveTime;
+            result = IOTHUB_CLIENT_OK;
+        }
+    }
+
+    return result;
+}
+
+IOTHUB_CLIENT_RESULT IoTHubClientCore_LL_SetOption(IOTHUB_CLIENT_CORE_LL_HANDLE iotHubClientHandle, const char* optionName, const void* value)
+{
+
+    IOTHUB_CLIENT_RESULT result;
+    /*Codes_SRS_IOTHUBCLIENT_LL_02_034: [If iotHubClientHandle is NULL then IoTHubClientCore_LL_SetOption shall return IOTHUB_CLIENT_INVALID_ARG.]*/
+    /*Codes_SRS_IOTHUBCLIENT_LL_02_035: [If optionName is NULL then IoTHubClientCore_LL_SetOption shall return IOTHUB_CLIENT_INVALID_ARG.] */
+    /*Codes_SRS_IOTHUBCLIENT_LL_02_036: [If value is NULL then IoTHubClientCore_LL_SetOption shall return IOTHUB_CLIENT_INVALID_ARG.] */
+    if (
+        (iotHubClientHandle == NULL) ||
+        (optionName == NULL) ||
+        (value == NULL)
+        )
+    {
+        result = IOTHUB_CLIENT_INVALID_ARG;
+        LogError("invalid argument (NULL)");
+    }
+    else
+    {
+        IOTHUB_CLIENT_CORE_LL_HANDLE_DATA* handleData = (IOTHUB_CLIENT_CORE_LL_HANDLE_DATA*)iotHubClientHandle;
+
+        /*Codes_SRS_IOTHUBCLIENT_LL_02_039: [ "messageTimeout" - once IoTHubClientCore_LL_SendEventAsync is called the message shall timeout after value miliseconds. Value is a pointer to a tickcounter_ms_t. ]*/
+        if (strcmp(optionName, OPTION_MESSAGE_TIMEOUT) == 0)
+        {
+            /*this is an option handled by IoTHubClientCore_LL*/
+            /*Codes_SRS_IOTHUBCLIENT_LL_02_043: [ Calling IoTHubClientCore_LL_SetOption with value set to "0" shall disable the timeout mechanism for all new messages. ]*/
+            handleData->currentMessageTimeout = *(const tickcounter_ms_t*)value;
+            result = IOTHUB_CLIENT_OK;
+        }
+        else if (strcmp(optionName, OPTION_PRODUCT_INFO) == 0)
+        {
+            /*Codes_SRS_IOTHUBCLIENT_LL_10_033: [repeat calls with "product_info" will erase the previously set product information if applicatble. ]*/
+            if (handleData->product_info != NULL)
+            {
+                STRING_delete(handleData->product_info);
+                handleData->product_info = NULL;
+            }
+
+            PLATFORM_INFO_OPTION supportedPlatformInfo;
+            if (handleData->IoTHubTransport_GetSupportedPlatformInfo(handleData->transportHandle, &supportedPlatformInfo) != 0)
+            {
+                LogError("IoTHubTransport_GetSupportedPlatformInfo failed");
+                result = IOTHUB_CLIENT_ERROR;
+            }
+            /*Codes_SRS_IOTHUBCLIENT_LL_10_035: [If string concatenation fails, `IoTHubClientCore_LL_SetOption` shall return `IOTHUB_CLIENT_ERROR`. Otherwise, `IOTHUB_CLIENT_OK` shall be returned. ]*/
+            else if ((handleData->product_info = make_product_info((const char*)value, supportedPlatformInfo)) == NULL)
+            {
+                LogError("STRING_construct_sprintf failed");
+                result = IOTHUB_CLIENT_ERROR;
+            }
+            else
+            {
+                result = IOTHUB_CLIENT_OK;
+            }
+        }
+        else if (strcmp(optionName, OPTION_DIAGNOSTIC_SAMPLING_PERCENTAGE) == 0)
+        {
+            uint32_t percentage = *(uint32_t*)value;
+            if (percentage > 100)
+            {
+                /*Codes_SRS_IOTHUBCLIENT_LL_10_036: [Calling IoTHubClientCore_LL_SetOption with value > 100 shall return `IOTHUB_CLIENT_ERRROR`. ]*/
+                LogError("The value of diag_sampling_percentage is out of range [0, 100]: %u", percentage);
+                result = IOTHUB_CLIENT_ERROR;
+            }
+            else
+            {
+                /*Codes_SRS_IOTHUBCLIENT_LL_10_037: [Calling IoTHubClientCore_LL_SetOption with value between [0, 100] shall return `IOTHUB_CLIENT_OK`. ]*/
+                handleData->diagnostic_setting.diagSamplingPercentage = percentage;
+                handleData->diagnostic_setting.currentMessageNumber = 0;
+                result = IOTHUB_CLIENT_OK;
+            }
+        }
+        else if ((strcmp(optionName, OPTION_BLOB_UPLOAD_TIMEOUT_SECS) == 0) || (strcmp(optionName, OPTION_CURL_VERBOSE) == 0))
+        {
+#ifndef DONT_USE_UPLOADTOBLOB
+            // This option just gets passed down into IoTHubClientCore_LL_UploadToBlob
+            /*Codes_SRS_IOTHUBCLIENT_LL_30_010: [ blob_xfr_timeout - IoTHubClientCore_LL_SetOption shall pass this option to IoTHubClient_UploadToBlob_SetOption and return its result. ]*/
+            result = IoTHubClient_LL_UploadToBlob_SetOption(handleData->uploadToBlobHandle, optionName, value);
+            if(result != IOTHUB_CLIENT_OK)
+            {
+                LogError("unable to IoTHubClientCore_LL_UploadToBlob_SetOption, result=%d", result);
+            }
+#else
+            LogError("%s option being set with DONT_USE_UPLOADTOBLOB compiler switch", optionName);
+            result = IOTHUB_CLIENT_ERROR;
+#endif /*DONT_USE_UPLOADTOBLOB*/
+        }
+        // OPTION_SAS_TOKEN_REFRESH_TIME is, but may be updated in the future
+        // if this becomes necessary
+        else if (strcmp(optionName, OPTION_SAS_TOKEN_REFRESH_TIME) == 0 || strcmp(optionName, OPTION_SAS_TOKEN_LIFETIME) == 0)
+        {
+            if (IoTHubClient_Auth_Set_SasToken_Expiry(handleData->authorization_module, *(size_t*)value) != 0)
+            {
+                LogError("Failed setting the Token Expiry time");
+                result = IOTHUB_CLIENT_ERROR;
+            }
+            else
+            {
+                result = IOTHUB_CLIENT_OK;
+            }
+        }
+        else if (strcmp(optionName, OPTION_MODEL_ID) == 0)
+        {
+            if (handleData->model_id != NULL)
+            {
+                LogError("DT ModelId already specified.");
+                result = IOTHUB_CLIENT_ERROR;
+            } 
+            else if ((handleData->model_id = STRING_construct((const char*)value)) == NULL)
+            {
+                LogError("STRING_construct failed");
+                result = IOTHUB_CLIENT_ERROR;
+            }
+            else
+            {
+                result = IOTHUB_CLIENT_OK;
+            }
+        }
+        else
+        {
+            // This section is unusual for SetOption calls because it attempts to pass unhandled options
+            // to two downstream targets (IoTHubTransport_SetOption and IoTHubClientCore_LL_UploadToBlob_SetOption) instead of one.
+
+            /*Codes_SRS_IOTHUBCLIENT_LL_30_011: [ IoTHubClientCore_LL_SetOption shall always pass unhandled options to Transport_SetOption. ]*/
+            /*Codes_SRS_IOTHUBCLIENT_LL_30_012: [ If Transport_SetOption fails, IoTHubClientCore_LL_SetOption shall return that failure code. ]*/
+            result = handleData->IoTHubTransport_SetOption(handleData->transportHandle, optionName, value);
+            if(result != IOTHUB_CLIENT_OK)
+            {
+                LogError("unable to IoTHubTransport_SetOption");
+            }
+#ifndef DONT_USE_UPLOADTOBLOB
+            else
+            {
+                /*Codes_SRS_IOTHUBCLIENT_LL_30_013: [ If the DONT_USE_UPLOADTOBLOB compiler switch is undefined, IoTHubClientCore_LL_SetOption shall pass unhandled options to IoTHubClient_UploadToBlob_SetOption and ignore the result. ]*/
+                (void)IoTHubClient_LL_UploadToBlob_SetOption(handleData->uploadToBlobHandle, optionName, value);
+            }
+#endif /*DONT_USE_UPLOADTOBLOB*/
+        }
+    }
+    return result;
+}
+
+IOTHUB_CLIENT_RESULT IoTHubClientCore_LL_SetDeviceTwinCallback(IOTHUB_CLIENT_CORE_LL_HANDLE iotHubClientHandle, IOTHUB_CLIENT_DEVICE_TWIN_CALLBACK deviceTwinCallback, void* userContextCallback)
+{
+    IOTHUB_CLIENT_RESULT result;
+    /* Codes_SRS_IOTHUBCLIENT_LL_10_001: [ IoTHubClientCore_LL_SetDeviceTwinCallback shall fail and return IOTHUB_CLIENT_INVALID_ARG if parameter iotHubClientHandle is NULL.] */
+    if (iotHubClientHandle == NULL)
+    {
+        result = IOTHUB_CLIENT_INVALID_ARG;
+        LogError("Invalid argument specified iothubClientHandle=%p", iotHubClientHandle);
+    }
+    else
+    {
+        IOTHUB_CLIENT_CORE_LL_HANDLE_DATA* handleData = (IOTHUB_CLIENT_CORE_LL_HANDLE_DATA*)iotHubClientHandle;
+        if (deviceTwinCallback == NULL)
+        {
+            /* Codes_SRS_IOTHUBCLIENT_LL_10_006: [ If deviceTwinCallback is NULL, then IoTHubClientCore_LL_SetDeviceTwinCallback shall call the underlying layer's _Unsubscribe function and return IOTHUB_CLIENT_OK.] */
+            handleData->IoTHubTransport_Unsubscribe_DeviceTwin(handleData->transportHandle);
+            handleData->deviceTwinCallback = NULL;
+            result = IOTHUB_CLIENT_OK;
+        }
+        else
+        {
+            /* Codes_SRS_IOTHUBCLIENT_LL_10_002: [ If deviceTwinCallback is not NULL, then IoTHubClientCore_LL_SetDeviceTwinCallback shall call the underlying layer's _Subscribe function.] */
+            if (handleData->IoTHubTransport_Subscribe_DeviceTwin(handleData->transportHandle) == 0)
+            {
+                handleData->deviceTwinCallback = deviceTwinCallback;
+                handleData->deviceTwinContextCallback = userContextCallback;
+                /* Codes_SRS_IOTHUBCLIENT_LL_10_005: [ Otherwise IoTHubClientCore_LL_SetDeviceTwinCallback shall succeed and return IOTHUB_CLIENT_OK.] */
+                result = IOTHUB_CLIENT_OK;
+            }
+            else
+            {
+                /* Codes_SRS_IOTHUBCLIENT_LL_10_003: [ If the underlying layer's _Subscribe function fails, then IoTHubClientCore_LL_SetDeviceTwinCallback shall fail and return IOTHUB_CLIENT_ERROR.] */
+                result = IOTHUB_CLIENT_ERROR;
+            }
+        }
+    }
+    return result;
+}
+
+IOTHUB_CLIENT_RESULT IoTHubClientCore_LL_SendReportedState(IOTHUB_CLIENT_CORE_LL_HANDLE iotHubClientHandle, const unsigned char* reportedState, size_t size, IOTHUB_CLIENT_REPORTED_STATE_CALLBACK reportedStateCallback, void* userContextCallback)
+{
+    IOTHUB_CLIENT_RESULT result;
+    /* Codes_SRS_IOTHUBCLIENT_LL_10_012: [ IoTHubClientCore_LL_SendReportedState shall fail and return IOTHUB_CLIENT_INVALID_ARG if parameter iotHubClientHandle is NULL. ] */
+    /* Codes_SRS_IOTHUBCLIENT_LL_10_013: [ IoTHubClientCore_LL_SendReportedState shall fail and return IOTHUB_CLIENT_INVALID_ARG if parameter reportedState is NULL] */
+    /* Codes_SRS_IOTHUBCLIENT_LL_07_005: [ IoTHubClientCore_LL_SendReportedState shall fail and return IOTHUB_CLIENT_INVALID_ARG if parameter size is equal to 0. ] */
+    if (iotHubClientHandle == NULL || (reportedState == NULL || size == 0) )
+    {
+        result = IOTHUB_CLIENT_INVALID_ARG;
+        LogError("Invalid argument specified iothubClientHandle=%p, reportedState=%p, size=%lu", iotHubClientHandle, reportedState, (unsigned long)size);
+    }
+    else
+    {
+        IOTHUB_CLIENT_CORE_LL_HANDLE_DATA* handleData = (IOTHUB_CLIENT_CORE_LL_HANDLE_DATA*)iotHubClientHandle;
+        /* Codes_SRS_IOTHUBCLIENT_LL_10_014: [IoTHubClientCore_LL_SendReportedState shall construct and queue the reported a Device_Twin structure for transmition by the underlying transport.] */
+        IOTHUB_DEVICE_TWIN* client_data = dev_twin_data_create(handleData, get_next_item_id(handleData), reportedState, size, reportedStateCallback, userContextCallback);
+        if (client_data == NULL)
+        {
+            /* Codes_SRS_IOTHUBCLIENT_LL_10_015: [If any error is encountered IoTHubClientCore_LL_SendReportedState shall return IOTHUB_CLIENT_ERROR.] */
+            LogError("Failure constructing device twin data");
+            result = IOTHUB_CLIENT_ERROR;
+        }
+        else
+        {
+            if (handleData->IoTHubTransport_Subscribe_DeviceTwin(handleData->transportHandle) != 0)
+            {
+                LogError("Failure adding device twin data to queue");
+                device_twin_data_destroy(client_data);
+                result = IOTHUB_CLIENT_ERROR;
+            }
+            else
+            {
+                /* Codes_SRS_IOTHUBCLIENT_LL_07_001: [ IoTHubClientCore_LL_SendReportedState shall queue the constructed reportedState data to be consumed by the targeted transport. ] */
+                DList_InsertTailList(&(iotHubClientHandle->iot_msg_queue), &(client_data->entry));
+
+                /* Codes_SRS_IOTHUBCLIENT_LL_10_016: [ Otherwise IoTHubClientCore_LL_SendReportedState shall succeed and return IOTHUB_CLIENT_OK.] */
+                result = IOTHUB_CLIENT_OK;
+            }
+        }
+    }
+    return result;
+}
+
+IOTHUB_CLIENT_RESULT IoTHubClientCore_LL_GetTwinAsync(IOTHUB_CLIENT_CORE_LL_HANDLE iotHubClientHandle, IOTHUB_CLIENT_DEVICE_TWIN_CALLBACK deviceTwinCallback, void* userContextCallback)
+{
+    IOTHUB_CLIENT_RESULT result;
+
+    // Codes_SRS_IOTHUBCLIENT_LL_09_011: [ If `iotHubClientHandle` or `deviceTwinCallback` are `NULL`, `IoTHubClientCore_LL_GetTwinAsync` shall fail and return `IOTHUB_CLIENT_INVALID_ARG`. ]
+    if (iotHubClientHandle == NULL || deviceTwinCallback == NULL)
+    {
+        LogError("Invalid argument iothubClientHandle=%p, deviceTwinCallback=%p", iotHubClientHandle, deviceTwinCallback);
+        result = IOTHUB_CLIENT_INVALID_ARG;
+    }
+    else
+    {
+        if (iotHubClientHandle->IoTHubTransport_Subscribe_DeviceTwin(iotHubClientHandle->transportHandle) != 0)
+        {
+            LogError("Failure adding device twin data to queue");
+            result = IOTHUB_CLIENT_ERROR;
+        }
+        else
+        {
+            GET_TWIN_CONTEXT* getTwinCtx;
+
+            if ((getTwinCtx = (GET_TWIN_CONTEXT*)malloc(sizeof(GET_TWIN_CONTEXT))) == NULL)
+            {
+                LogError("Failed creating get-twin context");
+                result = IOTHUB_CLIENT_ERROR;
+            }
+            else
+            {
+                IOTHUB_CLIENT_CORE_LL_HANDLE_DATA* handleData = (IOTHUB_CLIENT_CORE_LL_HANDLE_DATA*)iotHubClientHandle;
+
+                getTwinCtx->callback = deviceTwinCallback;
+                getTwinCtx->context = userContextCallback;
+
+                // Codes_SRS_IOTHUBCLIENT_LL_09_012: [ IoTHubClientCore_LL_GetTwinAsync shall invoke IoTHubTransport_GetTwinAsync, passing `on_device_twin_report_received` and the user data as context  ]
+                if (handleData->IoTHubTransport_GetTwinAsync(handleData->deviceHandle, on_get_device_twin_completed, getTwinCtx) != IOTHUB_CLIENT_OK)
+                {
+                    // Codes_SRS_IOTHUBCLIENT_LL_09_013: [ If IoTHubTransport_GetTwinAsync fails, `IoTHubClientCore_LL_GetTwinAsync` shall fail and return `IOTHUB_CLIENT_ERROR`. ]
+                    LogError("Failed getting device twin document");
+                    free(getTwinCtx);
+                    result = IOTHUB_CLIENT_ERROR;
+                }
+                else
+                {
+                    // Codes_SRS_IOTHUBCLIENT_LL_09_014: [ If no errors occur IoTHubClientCore_LL_GetTwinAsync shall return `IOTHUB_CLIENT_OK`. ]
+                    handleData->complete_twin_update_encountered = true;
+                    result = IOTHUB_CLIENT_OK;
+                }
+            }
+        }
+    }
+
+    return result;
+}
+
+
+IOTHUB_CLIENT_RESULT IoTHubClientCore_LL_SetDeviceMethodCallback(IOTHUB_CLIENT_CORE_LL_HANDLE iotHubClientHandle, IOTHUB_CLIENT_DEVICE_METHOD_CALLBACK_ASYNC deviceMethodCallback, void* userContextCallback)
+{
+    IOTHUB_CLIENT_RESULT result;
+
+    /*Codes_SRS_IOTHUBCLIENT_LL_12_017: [ IoTHubClientCore_LL_SetDeviceMethodCallback shall fail and return IOTHUB_CLIENT_INVALID_ARG if parameter iotHubClientHandle is NULL. ] */
+    if (iotHubClientHandle == NULL)
+    {
+        result = IOTHUB_CLIENT_INVALID_ARG;
+        LOG_ERROR_RESULT;
+    }
+    else
+    {
+        IOTHUB_CLIENT_CORE_LL_HANDLE_DATA* handleData = (IOTHUB_CLIENT_CORE_LL_HANDLE_DATA*)iotHubClientHandle;
+        if (deviceMethodCallback == NULL)
+        {
+            if (handleData->methodCallback.type == CALLBACK_TYPE_NONE)
+            {
+                /* Codes_SRS_IOTHUBCLIENT_LL_10_029: [ If deviceMethodCallback is NULL and the client is not subscribed to receive method calls, IoTHubClientCore_LL_SetDeviceMethodCallback shall fail and return IOTHUB_CLIENT_ERROR. ] */
+                LogError("not currently set to accept or process incoming messages.");
+                result = IOTHUB_CLIENT_ERROR;
+            }
+            else if (handleData->methodCallback.type == CALLBACK_TYPE_ASYNC)
+            {
+                /* Codes_SRS_IOTHUBCLIENT_LL_10_028: [If the user has subscribed using IoTHubClientCore_LL_SetDeviceMethodCallback_Ex, IoTHubClientCore_LL_SetDeviceMethodCallback shall fail and return IOTHUB_CLIENT_ERROR. ] */
+                LogError("Invalid workflow sequence. Please unsubscribe using the IoTHubClientCore_LL_SetDeviceMethodCallback_Ex function.");
+                result = IOTHUB_CLIENT_ERROR;
+            }
+            else
+            {
+                /*Codes_SRS_IOTHUBCLIENT_LL_02_019: [If parameter messageCallback is NULL then IoTHubClientCore_LL_SetMessageCallback shall call the underlying layer's _Unsubscribe function and return IOTHUB_CLIENT_OK.] */
+                /*Codes_SRS_IOTHUBCLIENT_LL_12_018: [If deviceMethodCallback is NULL, then IoTHubClientCore_LL_SetDeviceMethodCallback shall call the underlying layer's IoTHubTransport_Unsubscribe_DeviceMethod function and return IOTHUB_CLIENT_OK. ] */
+                /*Codes_SRS_IOTHUBCLIENT_LL_12_022: [ Otherwise IoTHubClientCore_LL_SetDeviceMethodCallback shall succeed and return IOTHUB_CLIENT_OK. ]*/
+                handleData->IoTHubTransport_Unsubscribe_DeviceMethod(handleData->deviceHandle);
+                handleData->methodCallback.type = CALLBACK_TYPE_NONE;
+                handleData->methodCallback.callbackSync = NULL;
+                handleData->methodCallback.userContextCallback = NULL;
+                result = IOTHUB_CLIENT_OK;
+            }
+        }
+        else
+        {
+            if (handleData->methodCallback.type == CALLBACK_TYPE_ASYNC)
+            {
+                /* Codes_SRS_IOTHUBCLIENT_LL_10_028: [If the user has subscribed using IoTHubClientCore_LL_SetDeviceMethodCallback_Ex, IoTHubClientCore_LL_SetDeviceMethodCallback shall fail and return IOTHUB_CLIENT_ERROR. ] */
+                LogError("Invalid workflow sequence. Please unsubscribe using the IoTHubClientCore_LL_SetDeviceMethodCallback_Ex function before subscribing with IoTHubClientCore_LL_SetDeviceMethodCallback.");
+                result = IOTHUB_CLIENT_ERROR;
+            }
+            else
+            {
+                /*Codes_SRS_IOTHUBCLIENT_LL_12_019: [ If deviceMethodCallback is not NULL, then IoTHubClientCore_LL_SetDeviceMethodCallback shall call the underlying layer's IoTHubTransport_Subscribe_DeviceMethod function. ]*/
+                if (handleData->IoTHubTransport_Subscribe_DeviceMethod(handleData->deviceHandle) == 0)
+                {
+                    /*Codes_SRS_IOTHUBCLIENT_LL_12_022: [ Otherwise IoTHubClientCore_LL_SetDeviceMethodCallback shall succeed and return IOTHUB_CLIENT_OK. ]*/
+                    handleData->methodCallback.type = CALLBACK_TYPE_SYNC;
+                    handleData->methodCallback.callbackSync = deviceMethodCallback;
+                    handleData->methodCallback.callbackAsync = NULL;
+                    handleData->methodCallback.userContextCallback = userContextCallback;
+                    result = IOTHUB_CLIENT_OK;
+                }
+                else
+                {
+                    /*Codes_SRS_IOTHUBCLIENT_LL_12_020: [ If the underlying layer's IoTHubTransport_Subscribe_DeviceMethod function fails, then IoTHubClientCore_LL_SetDeviceMethodCallback shall fail and return IOTHUB_CLIENT_ERROR. ]*/
+                    /*Codes_SRS_IOTHUBCLIENT_LL_12_021: [ If adding the information fails for any reason, IoTHubClientCore_LL_SetDeviceMethodCallback shall fail and return IOTHUB_CLIENT_ERROR. ]*/
+                    LogError("IoTHubTransport_Subscribe_DeviceMethod failed");
+                    handleData->methodCallback.type = CALLBACK_TYPE_NONE;
+                    handleData->methodCallback.callbackAsync = NULL;
+                    handleData->methodCallback.callbackSync = NULL;
+                    handleData->methodCallback.userContextCallback = NULL;
+                    result = IOTHUB_CLIENT_ERROR;
+                }
+            }
+        }
+    }
+    return result;
+}
+
+IOTHUB_CLIENT_RESULT IoTHubClientCore_LL_SetDeviceMethodCallback_Ex(IOTHUB_CLIENT_CORE_LL_HANDLE iotHubClientHandle, IOTHUB_CLIENT_INBOUND_DEVICE_METHOD_CALLBACK inboundDeviceMethodCallback, void* userContextCallback)
+{
+    IOTHUB_CLIENT_RESULT result;
+    /* Codes_SRS_IOTHUBCLIENT_LL_07_021: [ If handle is NULL then IoTHubClientCore_LL_SetDeviceMethodCallback_Ex shall return IOTHUB_CLIENT_INVALID_ARG.] */
+    if (iotHubClientHandle == NULL)
+    {
+        result = IOTHUB_CLIENT_INVALID_ARG;
+        LOG_ERROR_RESULT;
+    }
+    else
+    {
+        IOTHUB_CLIENT_CORE_LL_HANDLE_DATA* handleData = (IOTHUB_CLIENT_CORE_LL_HANDLE_DATA*)iotHubClientHandle;
+        if (inboundDeviceMethodCallback == NULL)
+        {
+            if (handleData->methodCallback.type == CALLBACK_TYPE_NONE)
+            {
+                /* Codes_SRS_IOTHUBCLIENT_LL_10_030: [ If deviceMethodCallback is NULL and the client is not subscribed to receive method calls, IoTHubClientCore_LL_SetDeviceMethodCallback shall fail and return IOTHUB_CLIENT_ERROR. ] */
+                LogError("not currently set to accept or process incoming messages.");
+                result = IOTHUB_CLIENT_ERROR;
+            }
+            else if (handleData->methodCallback.type == CALLBACK_TYPE_SYNC)
+            {
+                /* Codes_SRS_IOTHUBCLIENT_LL_10_031: [If the user has subscribed using IoTHubClientCore_LL_SetDeviceMethodCallback, IoTHubClientCore_LL_SetDeviceMethodCallback_Ex shall fail and return IOTHUB_CLIENT_ERROR. ] */
+                LogError("Invalid workflow sequence. Please unsubscribe using the IoTHubClientCore_LL_SetDeviceMethodCallback function.");
+                result = IOTHUB_CLIENT_ERROR;
+            }
+            else
+            {
+                /* Codes_SRS_IOTHUBCLIENT_LL_07_022: [ If inboundDeviceMethodCallback is NULL then IoTHubClientCore_LL_SetDeviceMethodCallback_Ex shall call the underlying layer's IoTHubTransport_Unsubscribe_DeviceMethod function and return IOTHUB_CLIENT_OK.] */
+                handleData->IoTHubTransport_Unsubscribe_DeviceMethod(handleData->deviceHandle);
+                handleData->methodCallback.type = CALLBACK_TYPE_NONE;
+                handleData->methodCallback.callbackAsync = NULL;
+                handleData->methodCallback.userContextCallback = NULL;
+                result = IOTHUB_CLIENT_OK;
+            }
+        }
+        else
+        {
+            if (handleData->methodCallback.type == CALLBACK_TYPE_SYNC)
+            {
+                /* Codes_SRS_IOTHUBCLIENT_LL_10_031: [If the user has subscribed using IoTHubClientCore_LL_SetDeviceMethodCallback, IoTHubClientCore_LL_SetDeviceMethodCallback_Ex shall fail and return IOTHUB_CLIENT_ERROR. ] */
+                LogError("Invalid workflow sequence. Please unsubscribe using the IoTHubClientCore_LL_SetDeviceMethodCallback function before subscribing with IoTHubClientCore_LL_SetDeviceMethodCallback_Ex.");
+                result = IOTHUB_CLIENT_ERROR;
+            }
+            else
+            {
+                /* Codes_SRS_IOTHUBCLIENT_LL_07_023: [ If inboundDeviceMethodCallback is non-NULL then IoTHubClientCore_LL_SetDeviceMethodCallback_Ex shall call the underlying layer's IoTHubTransport_Subscribe_DeviceMethod function.]*/
+                if (handleData->IoTHubTransport_Subscribe_DeviceMethod(handleData->deviceHandle) == 0)
+                {
+                    handleData->methodCallback.type = CALLBACK_TYPE_ASYNC;
+                    handleData->methodCallback.callbackAsync = inboundDeviceMethodCallback;
+                    handleData->methodCallback.callbackSync = NULL;
+                    handleData->methodCallback.userContextCallback = userContextCallback;
+                    result = IOTHUB_CLIENT_OK;
+                }
+                else
+                {
+                    /* Codes_SRS_IOTHUBCLIENT_LL_07_025: [ If any error is encountered then IoTHubClientCore_LL_SetDeviceMethodCallback_Ex shall return IOTHUB_CLIENT_ERROR.] */
+                    LogError("IoTHubTransport_Subscribe_DeviceMethod failed");
+                    handleData->methodCallback.type = CALLBACK_TYPE_NONE;
+                    handleData->methodCallback.callbackAsync = NULL;
+                    handleData->methodCallback.callbackSync = NULL;
+                    handleData->methodCallback.userContextCallback = NULL;
+                    result = IOTHUB_CLIENT_ERROR;
+                }
+            }
+        }
+    }
+    return result;
+}
+
+IOTHUB_CLIENT_RESULT IoTHubClientCore_LL_DeviceMethodResponse(IOTHUB_CLIENT_CORE_LL_HANDLE iotHubClientHandle, METHOD_HANDLE methodId, const unsigned char* response, size_t response_size, int status_response)
+{
+    IOTHUB_CLIENT_RESULT result;
+    /* Codes_SRS_IOTHUBCLIENT_LL_07_026: [ If handle or methodId is NULL then IoTHubClientCore_LL_DeviceMethodResponse shall return IOTHUB_CLIENT_INVALID_ARG.] */
+    if (iotHubClientHandle == NULL || methodId == NULL)
+    {
+        result = IOTHUB_CLIENT_INVALID_ARG;
+        LOG_ERROR_RESULT;
+    }
+    else
+    {
+        IOTHUB_CLIENT_CORE_LL_HANDLE_DATA* handleData = (IOTHUB_CLIENT_CORE_LL_HANDLE_DATA*)iotHubClientHandle;
+        /* Codes_SRS_IOTHUBCLIENT_LL_07_027: [ IoTHubClientCore_LL_DeviceMethodResponse shall call the IoTHubTransport_DeviceMethod_Response transport function.] */
+        if (handleData->IoTHubTransport_DeviceMethod_Response(handleData->deviceHandle, methodId, response, response_size, status_response) != 0)
+        {
+            LogError("IoTHubTransport_DeviceMethod_Response failed");
+            result = IOTHUB_CLIENT_ERROR;
+        }
+        else
+        {
+            result = IOTHUB_CLIENT_OK;
+        }
+    }
+    return result;
+}
+
+#ifndef DONT_USE_UPLOADTOBLOB
+IOTHUB_CLIENT_RESULT IoTHubClientCore_LL_UploadToBlob(IOTHUB_CLIENT_CORE_LL_HANDLE iotHubClientHandle, const char* destinationFileName, const unsigned char* source, size_t size)
+{
+    IOTHUB_CLIENT_RESULT result;
+    /*Codes_SRS_IOTHUBCLIENT_LL_02_061: [ If iotHubClientHandle is NULL then IoTHubClientCore_LL_UploadToBlob shall fail and return IOTHUB_CLIENT_INVALID_ARG. ]*/
+    /*Codes_SRS_IOTHUBCLIENT_LL_02_062: [ If destinationFileName is NULL then IoTHubClientCore_LL_UploadToBlob shall fail and return IOTHUB_CLIENT_INVALID_ARG. ]*/
+    /*Codes_SRS_IOTHUBCLIENT_LL_02_063: [ If `source` is `NULL` and size is greater than 0 then `IoTHubClientCore_LL_UploadToBlob` shall fail and return `IOTHUB_CLIENT_INVALID_ARG`. ]*/
+    if (
+        (iotHubClientHandle == NULL) ||
+        (destinationFileName == NULL) ||
+        ((source == NULL) && (size >0))
+        )
+    {
+        LogError("invalid parameters IOTHUB_CLIENT_CORE_LL_HANDLE iotHubClientHandle=%p, const char* destinationFileName=%s, const unsigned char* source=%p, size_t size=%lu", iotHubClientHandle, destinationFileName, source, (unsigned long)size);
+        result = IOTHUB_CLIENT_INVALID_ARG;
+    }
+    else
+    {
+        result = IoTHubClient_LL_UploadToBlob_Impl(iotHubClientHandle->uploadToBlobHandle, destinationFileName, source, size);
+    }
+    return result;
+}
+
+typedef struct UPLOAD_MULTIPLE_BLOCKS_WRAPPER_CONTEXT_TAG
+{
+    IOTHUB_CLIENT_FILE_UPLOAD_GET_DATA_CALLBACK getDataCallback;
+    void* context;
+} UPLOAD_MULTIPLE_BLOCKS_WRAPPER_CONTEXT;
+
+
+static IOTHUB_CLIENT_FILE_UPLOAD_GET_DATA_RESULT uploadMultipleBlocksCallbackWrapper(IOTHUB_CLIENT_FILE_UPLOAD_RESULT result, unsigned char const ** data, size_t* size, void* context)
+{
+    UPLOAD_MULTIPLE_BLOCKS_WRAPPER_CONTEXT* wrapperContext = (UPLOAD_MULTIPLE_BLOCKS_WRAPPER_CONTEXT*)context;
+    wrapperContext->getDataCallback(result, data, size, wrapperContext->context);
+    return IOTHUB_CLIENT_FILE_UPLOAD_GET_DATA_OK;
+}
+
+IOTHUB_CLIENT_RESULT IoTHubClientCore_LL_UploadMultipleBlocksToBlob(IOTHUB_CLIENT_CORE_LL_HANDLE iotHubClientHandle, const char* destinationFileName, IOTHUB_CLIENT_FILE_UPLOAD_GET_DATA_CALLBACK getDataCallback, void* context)
+{
+    IOTHUB_CLIENT_RESULT result;
+    /*Codes_SRS_IOTHUBCLIENT_LL_99_005: [ If `iotHubClientHandle` is `NULL` then `IoTHubClientCore_LL_UploadMultipleBlocksToBlob(Ex)` shall fail and return `IOTHUB_CLIENT_INVALID_ARG`. ]*/
+    /*Codes_SRS_IOTHUBCLIENT_LL_99_006: [ If `destinationFileName` is `NULL` then `IoTHubClientCore_LL_UploadMultipleBlocksToBlob(Ex)` shall fail and return `IOTHUB_CLIENT_INVALID_ARG`. ]*/
+    /*Codes_SRS_IOTHUBCLIENT_LL_99_007: [ If `getDataCallback` is `NULL` then `IoTHubClientCore_LL_UploadMultipleBlocksToBlob(Ex)` shall fail and return `IOTHUB_CLIENT_INVALID_ARG`. ]*/
+    if (
+        (iotHubClientHandle == NULL) ||
+        (destinationFileName == NULL) ||
+        (getDataCallback == NULL)
+        )
+    {
+        LogError("invalid parameters IOTHUB_CLIENT_CORE_LL_HANDLE iotHubClientHandle=%p, const char* destinationFileName=%p, getDataCallback=%p", iotHubClientHandle, destinationFileName, getDataCallback);
+        result = IOTHUB_CLIENT_INVALID_ARG;
+    }
+    else
+    {
+        UPLOAD_MULTIPLE_BLOCKS_WRAPPER_CONTEXT uploadMultipleBlocksWrapperContext;
+        uploadMultipleBlocksWrapperContext.getDataCallback = getDataCallback;
+        uploadMultipleBlocksWrapperContext.context = context;
+
+        result = IoTHubClient_LL_UploadMultipleBlocksToBlob_Impl(iotHubClientHandle->uploadToBlobHandle, destinationFileName, uploadMultipleBlocksCallbackWrapper, &uploadMultipleBlocksWrapperContext);
+    }
+    return result;
+}
+
+IOTHUB_CLIENT_RESULT IoTHubClientCore_LL_UploadMultipleBlocksToBlobEx(IOTHUB_CLIENT_CORE_LL_HANDLE iotHubClientHandle, const char* destinationFileName, IOTHUB_CLIENT_FILE_UPLOAD_GET_DATA_CALLBACK_EX getDataCallbackEx, void* context)
+{
+    IOTHUB_CLIENT_RESULT result;
+    /*Codes_SRS_IOTHUBCLIENT_LL_99_005: [ If `iotHubClientHandle` is `NULL` then `IoTHubClientCore_LL_UploadMultipleBlocksToBlob(Ex)` shall fail and return `IOTHUB_CLIENT_INVALID_ARG`. ]*/
+    /*Codes_SRS_IOTHUBCLIENT_LL_99_006: [ If `destinationFileName` is `NULL` then `IoTHubClientCore_LL_UploadMultipleBlocksToBlob(Ex)` shall fail and return `IOTHUB_CLIENT_INVALID_ARG`. ]*/
+    /*Codes_SRS_IOTHUBCLIENT_LL_99_007: [ If `getDataCallback` is `NULL` then `IoTHubClientCore_LL_UploadMultipleBlocksToBlob(Ex)` shall fail and return `IOTHUB_CLIENT_INVALID_ARG`. ]*/
+    if (
+        (iotHubClientHandle == NULL) ||
+        (destinationFileName == NULL) ||
+        (getDataCallbackEx == NULL)
+        )
+    {
+        LogError("invalid parameters IOTHUB_CLIENT_CORE_LL_HANDLE iotHubClientHandle=%p, destinationFileName=%p, getDataCallbackEx=%p", iotHubClientHandle, destinationFileName, getDataCallbackEx);
+        result = IOTHUB_CLIENT_INVALID_ARG;
+    }
+    else
+    {
+        result = IoTHubClient_LL_UploadMultipleBlocksToBlob_Impl(iotHubClientHandle->uploadToBlobHandle, destinationFileName, getDataCallbackEx, context);
+    }
+    return result;
+}
+#endif // DONT_USE_UPLOADTOBLOB
+
+IOTHUB_CLIENT_RESULT IoTHubClientCore_LL_SendEventToOutputAsync(IOTHUB_CLIENT_CORE_LL_HANDLE iotHubClientHandle, IOTHUB_MESSAGE_HANDLE eventMessageHandle, const char* outputName, IOTHUB_CLIENT_EVENT_CONFIRMATION_CALLBACK eventConfirmationCallback, void* userContextCallback)
+{
+    IOTHUB_CLIENT_RESULT result;
+
+    if ((iotHubClientHandle == NULL) || (outputName == NULL) || (eventMessageHandle == NULL) || ((eventConfirmationCallback == NULL) && (userContextCallback != NULL)))
+    {
+        // Codes_SRS_IOTHUBCLIENT_LL_31_127: [ If `iotHubClientHandle`, `outputName`, or `eventConfirmationCallback` is `NULL`, `IoTHubClient_LL_SendEventToOutputAsync` shall return `IOTHUB_CLIENT_INVALID_ARG`. ]
+        LogError("Invalid argument (iotHubClientHandle=%p, outputName=%p, eventMessageHandle=%p)", iotHubClientHandle, outputName, eventMessageHandle);
+        result = IOTHUB_CLIENT_INVALID_ARG;
+    }
+    else
+    {
+        // Codes_SRS_IOTHUBCLIENT_LL_31_128: [ `IoTHubClient_LL_SendEventToOutputAsync` shall set the outputName of the message to send. ]
+        if (IoTHubMessage_SetOutputName(eventMessageHandle, outputName) != IOTHUB_MESSAGE_OK)
+        {
+            LogError("IoTHubMessage_SetOutputName failed");
+            result = IOTHUB_CLIENT_ERROR;
+        }
+        // Codes_SRS_IOTHUBCLIENT_LL_31_129: [ `IoTHubClient_LL_SendEventToOutputAsync` shall invoke `IoTHubClient_LL_SendEventAsync` to send the message. ]
+        else if ((result = IoTHubClientCore_LL_SendEventAsync(iotHubClientHandle, eventMessageHandle, eventConfirmationCallback, userContextCallback)) != IOTHUB_CLIENT_OK)
+        {
+            LogError("Call into IoTHubClient_LL_SendEventAsync failed, result=%d", result);
+        }
+    }
+
+    return result;
+}
+
+
+static IOTHUB_CLIENT_RESULT create_event_handler_callback(IOTHUB_CLIENT_CORE_LL_HANDLE_DATA* handleData, const char* inputName, IOTHUB_CLIENT_MESSAGE_CALLBACK_ASYNC callbackSync, IOTHUB_CLIENT_MESSAGE_CALLBACK_ASYNC_EX callbackSyncEx, void* userContextCallback, void* userContextCallbackEx, size_t userContextCallbackExLength)
+{
+    IOTHUB_CLIENT_RESULT result = IOTHUB_CLIENT_ERROR;
+    bool add_to_list = false;
+
+    if ((handleData->event_callbacks == NULL) && ((handleData->event_callbacks = singlylinkedlist_create()) == NULL))
+    {
+        LogError("Could not allocate linked list for callbacks");
+        result = IOTHUB_CLIENT_ERROR;
+    }
+    else
+    {
+        IOTHUB_EVENT_CALLBACK* event_callback = NULL;
+        LIST_ITEM_HANDLE item_handle = singlylinkedlist_find(handleData->event_callbacks, is_event_equal_for_match, (const void*)inputName);
+        if (item_handle == NULL)
+        {
+            // Codes_SRS_IOTHUBCLIENT_LL_31_134: [ `IoTHubClient_LL_SetInputMessageCallback` shall allocate a callback handle to associate callbacks from the transport => client if `inputName` isn't already present in the callback list. ]
+            event_callback = (IOTHUB_EVENT_CALLBACK*)malloc(sizeof(IOTHUB_EVENT_CALLBACK));
+            if (event_callback == NULL)
+            {
+                LogError("Could not allocate IOTHUB_EVENT_CALLBACK");
+                result = IOTHUB_CLIENT_ERROR;
+            }
+            else
+            {
+                memset(event_callback, 0, sizeof(*event_callback));
+                add_to_list = true;
+            }
+        }
+        else
+        {
+            // Codes_SRS_IOTHUBCLIENT_LL_31_135: [ `IoTHubClient_LL_SetInputMessageCallback` shall reuse the existing callback handle if `inputName` is already present in the callback list. ]
+            event_callback = (IOTHUB_EVENT_CALLBACK*)singlylinkedlist_item_get_value(item_handle);
+            if (event_callback == NULL)
+            {
+                LogError("singlylinkedlist_item_get_value failed looking up event callback");
+            }
+        }
+
+        if (event_callback != NULL)
+        {
+            if ((inputName != NULL) && (event_callback->inputName == NULL))
+            {
+                event_callback->inputName = STRING_construct(inputName);
+            }
+
+            if ((inputName == NULL) || (event_callback->inputName != NULL))
+            {
+                event_callback->callbackAsync = callbackSync;
+                event_callback->callbackAsyncEx = callbackSyncEx;
+
+                free(event_callback->userContextCallbackEx);
+                event_callback->userContextCallbackEx = NULL;
+
+                if (userContextCallbackEx == NULL)
+                {
+                    event_callback->userContextCallback = userContextCallback;
+                }
+
+                if ((userContextCallbackEx != NULL) &&
+                    (NULL == (event_callback->userContextCallbackEx = malloc(userContextCallbackExLength))))
+                {
+                    LogError("Unable to allocate userContextCallback");
+                    delete_event(event_callback);
+                    result = IOTHUB_CLIENT_ERROR;
+                }
+                else if ((add_to_list == true) && (NULL == singlylinkedlist_add(handleData->event_callbacks, event_callback)))
+                {
+                    LogError("Unable to add eventCallback to list");
+                    delete_event(event_callback);
+                    result = IOTHUB_CLIENT_ERROR;
+                }
+                else
+                {
+                    if (userContextCallbackEx != NULL)
+                    {
+                        // Codes_SRS_IOTHUBCLIENT_LL_31_141: [`IoTHubClient_LL_SetInputMessageCallbackEx` shall copy the data passed in extended context. ]
+                        memcpy(event_callback->userContextCallbackEx, userContextCallbackEx, userContextCallbackExLength);
+                    }
+                    result = IOTHUB_CLIENT_OK;
+                }
+            }
+            else
+            {
+                delete_event(event_callback);
+                result = IOTHUB_CLIENT_ERROR;
+            }
+        }
+    }
+
+    return result;
+}
+
+static IOTHUB_CLIENT_RESULT remove_event_unsubscribe_if_needed(IOTHUB_CLIENT_CORE_LL_HANDLE_DATA* handleData, const char* inputName)
+{
+    IOTHUB_CLIENT_RESULT result;
+
+    LIST_ITEM_HANDLE item_handle = singlylinkedlist_find(handleData->event_callbacks, is_event_equal_for_match, (const void*)inputName);
+    if (item_handle == NULL)
+    {
+        // Codes_SRS_IOTHUBCLIENT_LL_31_132: [ If `eventHandlerCallback` is NULL, `IoTHubClient_LL_SetInputMessageCallback` shall return `IOTHUB_CLIENT_ERROR` if the `inputName` is not present. ]
+        LogError("Input name %s was not present", inputName);
+        result = IOTHUB_CLIENT_ERROR;
+    }
+    else
+    {
+        IOTHUB_EVENT_CALLBACK* event_callback = (IOTHUB_EVENT_CALLBACK*)singlylinkedlist_item_get_value(item_handle);
+        if (event_callback == NULL)
+        {
+            LogError("singlylinkedlist_item_get_value failed");
+            result = IOTHUB_CLIENT_ERROR;
+        }
+        else
+        {
+            delete_event(event_callback);
+            // Codes_SRS_IOTHUBCLIENT_LL_31_131: [ If `eventHandlerCallback` is NULL, `IoTHubClient_LL_SetInputMessageCallback` shall remove the `inputName` from its callback list if present. ]
+            if (singlylinkedlist_remove(handleData->event_callbacks, item_handle) != 0)
+            {
+                LogError("singlylinkedlist_remove failed");
+                result = IOTHUB_CLIENT_ERROR;
+            }
+            else
+            {
+                if (singlylinkedlist_get_head_item(handleData->event_callbacks) == NULL)
+                {
+                    // Codes_SRS_IOTHUBCLIENT_LL_31_133: [ If `eventHandlerCallback` is NULL, `IoTHubClient_LL_SetInputMessageCallback` shall invoke `IoTHubTransport_Unsubscribe_InputQueue` if this was the last input callback. ]
+                    handleData->IoTHubTransport_Unsubscribe_InputQueue(handleData);
+                }
+                result = IOTHUB_CLIENT_OK;
+            }
+        }
+    }
+
+    return result;
+}
+
+
+IOTHUB_CLIENT_RESULT IoTHubClientCore_LL_SetInputMessageCallbackImpl(IOTHUB_CLIENT_CORE_LL_HANDLE iotHubClientHandle, const char* inputName, IOTHUB_CLIENT_MESSAGE_CALLBACK_ASYNC eventHandlerCallback, IOTHUB_CLIENT_MESSAGE_CALLBACK_ASYNC_EX eventHandlerCallbackEx, void *userContextCallback, void *userContextCallbackEx, size_t userContextCallbackExLength)
+{
+    IOTHUB_CLIENT_RESULT result;
+
+    if (iotHubClientHandle == NULL)
+    {
+        // Codes_SRS_IOTHUBCLIENT_LL_31_130: [ If `iotHubClientHandle` or `inputName` is NULL, `IoTHubClient_LL_SetInputMessageCallback` shall return IOTHUB_CLIENT_INVALID_ARG. ]
+        LogError("Invalid argument - iotHubClientHandle=%p, inputName=%p", iotHubClientHandle, inputName);
+        result = IOTHUB_CLIENT_INVALID_ARG;
+    }
+    else
+    {
+        IOTHUB_CLIENT_CORE_LL_HANDLE_DATA* handleData = (IOTHUB_CLIENT_CORE_LL_HANDLE_DATA*)iotHubClientHandle;
+        if ((eventHandlerCallback == NULL) && (eventHandlerCallbackEx == NULL))
+        {
+            result = (IOTHUB_CLIENT_RESULT)remove_event_unsubscribe_if_needed(handleData, inputName);
+        }
+        else
+        {
+            bool registered_with_transport_handler = (handleData->event_callbacks != NULL) && (singlylinkedlist_get_head_item(handleData->event_callbacks) != NULL);
+            if ((result = (IOTHUB_CLIENT_RESULT)create_event_handler_callback(handleData, inputName, eventHandlerCallback, eventHandlerCallbackEx, userContextCallback, userContextCallbackEx, userContextCallbackExLength)) != IOTHUB_CLIENT_OK)
+            {
+                LogError("create_event_handler_callback call failed, error = %d", result);
+            }
+            // Codes_SRS_IOTHUBCLIENT_LL_31_136: [ `IoTHubClient_LL_SetInputMessageCallback` shall invoke `IoTHubTransport_Subscribe_InputQueue` if this is the first callback being registered. ]
+            else if (!registered_with_transport_handler && (handleData->IoTHubTransport_Subscribe_InputQueue(handleData->deviceHandle) != 0))
+            {
+                LogError("IoTHubTransport_Subscribe_InputQueue failed");
+                delete_event_callback_list(handleData);
+                result = IOTHUB_CLIENT_ERROR;
+            }
+            else
+            {
+                result = IOTHUB_CLIENT_OK;
+            }
+        }
+    }
+    return result;
+
+}
+
+IOTHUB_CLIENT_RESULT IoTHubClientCore_LL_SetInputMessageCallbackEx(IOTHUB_CLIENT_CORE_LL_HANDLE iotHubClientHandle, const char* inputName, IOTHUB_CLIENT_MESSAGE_CALLBACK_ASYNC_EX eventHandlerCallbackEx, void *userContextCallbackEx, size_t userContextCallbackExLength)
+{
+    return IoTHubClientCore_LL_SetInputMessageCallbackImpl(iotHubClientHandle, inputName, NULL, eventHandlerCallbackEx, NULL, userContextCallbackEx, userContextCallbackExLength);
+}
+
+IOTHUB_CLIENT_RESULT IoTHubClientCore_LL_SetInputMessageCallback(IOTHUB_CLIENT_CORE_LL_HANDLE iotHubClientHandle, const char* inputName, IOTHUB_CLIENT_MESSAGE_CALLBACK_ASYNC eventHandlerCallback, void* userContextCallback)
+{
+    return IoTHubClientCore_LL_SetInputMessageCallbackImpl(iotHubClientHandle, inputName, eventHandlerCallback, NULL, userContextCallback, NULL, 0);
+}
+
+int IoTHubClientCore_LL_GetTransportCallbacks(TRANSPORT_CALLBACKS_INFO* transport_cb)
+{
+    int result;
+    if (transport_cb == NULL)
+    {
+        LogError("Invalid parameter transport callback can not be NULL");
+        result = MU_FAILURE;
+    }
+    else
+    {
+        transport_cb->send_complete_cb = IoTHubClientCore_LL_SendComplete;
+        transport_cb->twin_retrieve_prop_complete_cb = IoTHubClientCore_LL_RetrievePropertyComplete;
+        transport_cb->twin_rpt_state_complete_cb = IoTHubClientCore_LL_ReportedStateComplete;
+        transport_cb->connection_status_cb = IoTHubClientCore_LL_ConnectionStatusCallBack;
+        transport_cb->prod_info_cb = IoTHubClientCore_LL_GetProductInfo;
+        transport_cb->msg_input_cb = IoTHubClientCore_LL_MessageCallbackFromInput;
+        transport_cb->msg_cb = IoTHubClientCore_LL_MessageCallback;
+        transport_cb->method_complete_cb = IoTHubClientCore_LL_DeviceMethodComplete;
+        transport_cb->get_model_id_cb = IoTHubClientCore_LL_GetModelId;
+        result = 0;
+    }
+    return result;
+}
+
+#ifdef USE_EDGE_MODULES
+/* These should be replaced during iothub_client refactor */
+IOTHUB_CLIENT_RESULT IoTHubClientCore_LL_GenericMethodInvoke(IOTHUB_CLIENT_CORE_LL_HANDLE iotHubClientHandle, const char* deviceId, const char* moduleId, const char* methodName, const char* methodPayload, unsigned int timeout, int* responseStatus, unsigned char** responsePayload, size_t* responsePayloadSize)
+{
+    IOTHUB_CLIENT_RESULT result;
+    if (iotHubClientHandle != NULL)
+    {
+        if (moduleId != NULL)
+        {
+            result = IoTHubClient_Edge_ModuleMethodInvoke(iotHubClientHandle->methodHandle, deviceId, moduleId, methodName, methodPayload, timeout, responseStatus, responsePayload, responsePayloadSize);
+        }
+        else
+        {
+            result = IoTHubClient_Edge_DeviceMethodInvoke(iotHubClientHandle->methodHandle, deviceId, methodName, methodPayload, timeout, responseStatus, responsePayload, responsePayloadSize);
+
+        }
+    }
+    else
+    {
+        result = IOTHUB_CLIENT_INVALID_ARG;
+    }
+    return result;
+}
+#endif
+
+/*end*/
+
Index: azure_iot_hub_f767zi/trunk/azure_iot_sdk/iothub_client/src/iothub_client_diagnostic.c
===================================================================
--- azure_iot_hub_f767zi/trunk/azure_iot_sdk/iothub_client/src/iothub_client_diagnostic.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/azure_iot_sdk/iothub_client/src/iothub_client_diagnostic.c	(revision 457)
@@ -0,0 +1,199 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+#include <stdlib.h>
+#include <inttypes.h>
+#include <math.h>
+#include "azure_c_shared_utility/optimize_size.h"
+#include "azure_c_shared_utility/gballoc.h"
+#include "azure_c_shared_utility/xlogging.h"
+#include "azure_c_shared_utility/agenttime.h"
+#include "azure_c_shared_utility/buffer_.h"
+
+#include "internal/iothub_client_diagnostic.h"
+
+#define TIME_STRING_BUFFER_LEN 30
+
+static const int BASE_36 = 36;
+
+#define INDEFINITE_TIME ((time_t)-1)
+
+static char* get_epoch_time(char* timeBuffer)
+{
+    char* result;
+    time_t epochTime;
+    int timeLen = sizeof(time_t);
+
+    if ((epochTime = get_time(NULL)) == INDEFINITE_TIME)
+    {
+        LogError("Failed getting current time");
+        result = NULL;
+    }
+    else if (timeLen == sizeof(int64_t))
+    {
+        if (sprintf(timeBuffer, "%"PRIu64, (int64_t)epochTime) < 0)
+        {
+            LogError("Failed sprintf to timeBuffer with 8 bytes of time_t");
+            result = NULL;
+        }
+        else
+        {
+            result = timeBuffer;
+        }
+    }
+    else if (timeLen == sizeof(int32_t))
+    {
+        if (sprintf(timeBuffer, "%"PRIu32, (int32_t)epochTime) < 0)
+        {
+            LogError("Failed sprintf to timeBuffer with 4 bytes of time_t");
+            result = NULL;
+        }
+        else
+        {
+            result = timeBuffer;
+        }
+    }
+    else
+    {
+        LogError("Unknown size of time_t");
+        result = NULL;
+    }
+
+    return result;
+}
+
+static char get_base36_char(unsigned char value)
+{
+    return value <= 9 ? '0' + value : 'a' + value - 10;
+}
+
+static char* generate_eight_random_characters(char *randomString)
+{
+    int i;
+    char* randomStringPos = randomString;
+    for (i = 0; i < 4; ++i)
+    {
+        int rawRandom = rand();
+        int first = rawRandom % BASE_36;
+        int second = rawRandom / BASE_36 % BASE_36;
+        *randomStringPos++ = get_base36_char((unsigned char)first);
+        *randomStringPos++ = get_base36_char((unsigned char)second);
+    }
+    *randomStringPos = 0;
+
+    return randomString;
+}
+
+static bool should_add_diagnostic_info(IOTHUB_DIAGNOSTIC_SETTING_DATA* diagSetting)
+{
+    bool result = false;
+    if (diagSetting->diagSamplingPercentage > 0)
+    {
+        double number;
+        double percentage;
+
+        if (diagSetting->currentMessageNumber == UINT32_MAX)
+        {
+            diagSetting->currentMessageNumber %= diagSetting->diagSamplingPercentage * 100;
+        }
+        ++diagSetting->currentMessageNumber;
+
+        number = diagSetting->currentMessageNumber;
+        percentage = diagSetting->diagSamplingPercentage;
+        result = (floor((number - 2) * percentage / 100.0) < floor((number - 1) * percentage / 100.0));
+    }
+    return result;
+}
+
+static IOTHUB_MESSAGE_DIAGNOSTIC_PROPERTY_DATA* prepare_message_diagnostic_data()
+{
+    IOTHUB_MESSAGE_DIAGNOSTIC_PROPERTY_DATA* result = (IOTHUB_MESSAGE_DIAGNOSTIC_PROPERTY_DATA*)malloc(sizeof(IOTHUB_MESSAGE_DIAGNOSTIC_PROPERTY_DATA));
+    if (result == NULL)
+    {
+        LogError("malloc for DiagnosticData failed");
+    }
+    else
+    {
+        char* diagId = (char*)malloc(9);
+        if (diagId == NULL)
+        {
+            LogError("malloc for diagId failed");
+            free(result);
+            result = NULL;
+        }
+        else
+        {
+            char* timeBuffer;
+
+            (void)generate_eight_random_characters(diagId);
+            result->diagnosticId = diagId;
+
+            timeBuffer = (char*)malloc(TIME_STRING_BUFFER_LEN);
+            if (timeBuffer == NULL)
+            {
+                LogError("malloc for timeBuffer failed");
+                free(result->diagnosticId);
+                free(result);
+                result = NULL;
+            }
+            else if (get_epoch_time(timeBuffer) == NULL)
+            {
+                LogError("Failed getting current time");
+                free(result->diagnosticId);
+                free(result);
+                free(timeBuffer);
+                result = NULL;
+            }
+            else
+            {
+                result->diagnosticCreationTimeUtc = timeBuffer;
+            }
+        }
+    }
+    return result;
+}
+
+int IoTHubClient_Diagnostic_AddIfNecessary(IOTHUB_DIAGNOSTIC_SETTING_DATA* diagSetting, IOTHUB_MESSAGE_HANDLE messageHandle)
+{
+    int result;
+    /* Codes_SRS_IOTHUB_DIAGNOSTIC_13_001: [ IoTHubClient_Diagnostic_AddIfNecessary should return nonezero if diagSetting or messageHandle is NULL. ]*/
+    if (diagSetting == NULL || messageHandle == NULL)
+    {
+        result = MU_FAILURE;
+    }
+    /* Codes_SRS_IOTHUB_DIAGNOSTIC_13_003: [ If diagSamplingPercentage is equal to 0, message number should not be increased and no diagnostic properties added ]*/
+    else if (should_add_diagnostic_info(diagSetting))
+    {
+        /* Codes_SRS_IOTHUB_DIAGNOSTIC_13_004: [ If diagSamplingPercentage is equal to 100, diagnostic properties should be added to all messages]*/
+        /* Codes_SRS_IOTHUB_DIAGNOSTIC_13_005: [ If diagSamplingPercentage is between(0, 100), diagnostic properties should be added based on percentage]*/
+
+        IOTHUB_MESSAGE_DIAGNOSTIC_PROPERTY_DATA* diagnosticData;
+        if ((diagnosticData = prepare_message_diagnostic_data()) == NULL)
+        {
+            result = MU_FAILURE;
+        }
+        else
+        {
+            if (IoTHubMessage_SetDiagnosticPropertyData(messageHandle, diagnosticData) != IOTHUB_MESSAGE_OK)
+            {
+                /* Codes_SRS_IOTHUB_DIAGNOSTIC_13_002: [ IoTHubClient_Diagnostic_AddIfNecessary should return nonezero if failing to add diagnostic property. ]*/
+                result = MU_FAILURE;
+            }
+            else
+            {
+                result = 0;
+            }
+
+            free(diagnosticData->diagnosticCreationTimeUtc);
+            free(diagnosticData->diagnosticId);
+            free(diagnosticData);
+            diagnosticData = NULL;
+        }
+    }
+    else
+    {
+        result = 0;
+    }
+
+    return result;
+}
Index: azure_iot_hub_f767zi/trunk/azure_iot_sdk/iothub_client/src/iothub_client_ll.c
===================================================================
--- azure_iot_hub_f767zi/trunk/azure_iot_sdk/iothub_client/src/iothub_client_ll.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/azure_iot_sdk/iothub_client/src/iothub_client_ll.c	(revision 457)
@@ -0,0 +1,141 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+#include <stdlib.h>
+#include <string.h>
+#include "azure_c_shared_utility/optimize_size.h"
+#include "azure_c_shared_utility/gballoc.h"
+#include "azure_c_shared_utility/string_tokenizer.h"
+#include "azure_c_shared_utility/doublylinkedlist.h"
+#include "azure_c_shared_utility/xlogging.h"
+#include "azure_c_shared_utility/tickcounter.h"
+#include "azure_c_shared_utility/constbuffer.h"
+#include "azure_c_shared_utility/platform.h"
+
+#include "iothub_client_core_ll.h"
+#include "internal/iothub_client_authorization.h"
+#include "iothub_client_ll.h"
+#include "iothub_transport_ll.h"
+#include "iothub_device_client_ll.h"
+#include "internal/iothub_client_private.h"
+#include "iothub_client_options.h"
+#include "iothub_client_version.h"
+#include <stdint.h>
+
+#ifndef DONT_USE_UPLOADTOBLOB
+#include "internal/iothub_client_ll_uploadtoblob.h"
+#endif
+
+IOTHUB_CLIENT_LL_HANDLE IoTHubClient_LL_CreateFromConnectionString(const char* connectionString, IOTHUB_CLIENT_TRANSPORT_PROVIDER protocol)
+{
+    return (IOTHUB_CLIENT_LL_HANDLE)IoTHubClientCore_LL_CreateFromConnectionString(connectionString, protocol);
+}
+
+IOTHUB_CLIENT_LL_HANDLE IoTHubClient_LL_Create(const IOTHUB_CLIENT_CONFIG* config)
+{
+    return (IOTHUB_CLIENT_LL_HANDLE)IoTHubClientCore_LL_Create(config);
+}
+
+IOTHUB_CLIENT_LL_HANDLE IoTHubClient_LL_CreateWithTransport(const IOTHUB_CLIENT_DEVICE_CONFIG * config)
+{
+    return (IOTHUB_CLIENT_LL_HANDLE)IoTHubClientCore_LL_CreateWithTransport(config);
+}
+
+IOTHUB_CLIENT_LL_HANDLE IoTHubClient_LL_CreateFromDeviceAuth(const char* iothub_uri, const char* device_id, IOTHUB_CLIENT_TRANSPORT_PROVIDER protocol)
+{
+    return (IOTHUB_CLIENT_LL_HANDLE)IoTHubClientCore_LL_CreateFromDeviceAuth(iothub_uri, device_id, protocol);
+}
+
+void IoTHubClient_LL_Destroy(IOTHUB_CLIENT_LL_HANDLE iotHubClientHandle)
+{
+    IoTHubClientCore_LL_Destroy((IOTHUB_CLIENT_CORE_LL_HANDLE)iotHubClientHandle);
+}
+
+IOTHUB_CLIENT_RESULT IoTHubClient_LL_SendEventAsync(IOTHUB_CLIENT_LL_HANDLE iotHubClientHandle, IOTHUB_MESSAGE_HANDLE eventMessageHandle, IOTHUB_CLIENT_EVENT_CONFIRMATION_CALLBACK eventConfirmationCallback, void* userContextCallback)
+{
+    return IoTHubClientCore_LL_SendEventAsync((IOTHUB_CLIENT_CORE_LL_HANDLE)iotHubClientHandle, eventMessageHandle, eventConfirmationCallback, userContextCallback);
+}
+
+IOTHUB_CLIENT_RESULT IoTHubClient_LL_GetSendStatus(IOTHUB_CLIENT_LL_HANDLE iotHubClientHandle, IOTHUB_CLIENT_STATUS *iotHubClientStatus)
+{
+    return IoTHubClientCore_LL_GetSendStatus((IOTHUB_CLIENT_CORE_LL_HANDLE)iotHubClientHandle, iotHubClientStatus);
+}
+
+IOTHUB_CLIENT_RESULT IoTHubClient_LL_SetMessageCallback(IOTHUB_CLIENT_LL_HANDLE iotHubClientHandle, IOTHUB_CLIENT_MESSAGE_CALLBACK_ASYNC messageCallback, void* userContextCallback)
+{
+    return IoTHubClientCore_LL_SetMessageCallback((IOTHUB_CLIENT_CORE_LL_HANDLE)iotHubClientHandle, messageCallback, userContextCallback);
+}
+
+IOTHUB_CLIENT_RESULT IoTHubClient_LL_SetConnectionStatusCallback(IOTHUB_CLIENT_LL_HANDLE iotHubClientHandle, IOTHUB_CLIENT_CONNECTION_STATUS_CALLBACK connectionStatusCallback, void * userContextCallback)
+{
+    return IoTHubClientCore_LL_SetConnectionStatusCallback((IOTHUB_CLIENT_CORE_LL_HANDLE)iotHubClientHandle, connectionStatusCallback, userContextCallback);
+}
+
+IOTHUB_CLIENT_RESULT IoTHubClient_LL_SetRetryPolicy(IOTHUB_CLIENT_LL_HANDLE iotHubClientHandle, IOTHUB_CLIENT_RETRY_POLICY retryPolicy, size_t retryTimeoutLimitInSeconds)
+{
+    return IoTHubClientCore_LL_SetRetryPolicy((IOTHUB_CLIENT_CORE_LL_HANDLE)iotHubClientHandle, retryPolicy, retryTimeoutLimitInSeconds);
+}
+
+IOTHUB_CLIENT_RESULT IoTHubClient_LL_GetRetryPolicy(IOTHUB_CLIENT_LL_HANDLE iotHubClientHandle, IOTHUB_CLIENT_RETRY_POLICY* retryPolicy, size_t* retryTimeoutLimitInSeconds)
+{
+    return IoTHubClientCore_LL_GetRetryPolicy((IOTHUB_CLIENT_CORE_LL_HANDLE)iotHubClientHandle, retryPolicy, retryTimeoutLimitInSeconds);
+}
+
+IOTHUB_CLIENT_RESULT IoTHubClient_LL_GetLastMessageReceiveTime(IOTHUB_CLIENT_LL_HANDLE iotHubClientHandle, time_t* lastMessageReceiveTime)
+{
+    return IoTHubClientCore_LL_GetLastMessageReceiveTime((IOTHUB_CLIENT_CORE_LL_HANDLE)iotHubClientHandle, lastMessageReceiveTime);
+}
+
+void IoTHubClient_LL_DoWork(IOTHUB_CLIENT_LL_HANDLE iotHubClientHandle)
+{
+    IoTHubClientCore_LL_DoWork((IOTHUB_CLIENT_CORE_LL_HANDLE)iotHubClientHandle);
+}
+
+IOTHUB_CLIENT_RESULT IoTHubClient_LL_SetDeviceTwinCallback(IOTHUB_CLIENT_LL_HANDLE iotHubClientHandle, IOTHUB_CLIENT_DEVICE_TWIN_CALLBACK deviceTwinCallback, void* userContextCallback)
+{
+    return IoTHubClientCore_LL_SetDeviceTwinCallback((IOTHUB_CLIENT_CORE_LL_HANDLE)iotHubClientHandle, deviceTwinCallback, userContextCallback);
+}
+
+IOTHUB_CLIENT_RESULT IoTHubClient_LL_SetOption(IOTHUB_CLIENT_LL_HANDLE iotHubClientHandle, const char* optionName, const void* value)
+{
+    return IoTHubClientCore_LL_SetOption((IOTHUB_CLIENT_CORE_LL_HANDLE)iotHubClientHandle, optionName, value);
+}
+
+IOTHUB_CLIENT_RESULT IoTHubClient_LL_SendReportedState(IOTHUB_CLIENT_LL_HANDLE iotHubClientHandle, const unsigned char* reportedState, size_t size, IOTHUB_CLIENT_REPORTED_STATE_CALLBACK reportedStateCallback, void* userContextCallback)
+{
+    return IoTHubClientCore_LL_SendReportedState((IOTHUB_CLIENT_CORE_LL_HANDLE)iotHubClientHandle, reportedState, size, reportedStateCallback, userContextCallback);
+}
+
+IOTHUB_CLIENT_RESULT IoTHubClient_LL_SetDeviceMethodCallback(IOTHUB_CLIENT_LL_HANDLE iotHubClientHandle, IOTHUB_CLIENT_DEVICE_METHOD_CALLBACK_ASYNC deviceMethodCallback, void* userContextCallback)
+{
+    return IoTHubClientCore_LL_SetDeviceMethodCallback((IOTHUB_CLIENT_CORE_LL_HANDLE)iotHubClientHandle, deviceMethodCallback, userContextCallback);
+}
+
+IOTHUB_CLIENT_RESULT IoTHubClient_LL_SetDeviceMethodCallback_Ex(IOTHUB_CLIENT_LL_HANDLE iotHubClientHandle, IOTHUB_CLIENT_INBOUND_DEVICE_METHOD_CALLBACK inboundDeviceMethodCallback, void* userContextCallback)
+{
+    return IoTHubClientCore_LL_SetDeviceMethodCallback_Ex((IOTHUB_CLIENT_CORE_LL_HANDLE)iotHubClientHandle, inboundDeviceMethodCallback, userContextCallback);
+}
+
+IOTHUB_CLIENT_RESULT IoTHubClient_LL_DeviceMethodResponse(IOTHUB_CLIENT_LL_HANDLE iotHubClientHandle, METHOD_HANDLE methodId, const unsigned char* response, size_t response_size, int status_response)
+{
+    return IoTHubClientCore_LL_DeviceMethodResponse((IOTHUB_CLIENT_CORE_LL_HANDLE)iotHubClientHandle, methodId, response, response_size, status_response);
+}
+
+#ifndef DONT_USE_UPLOADTOBLOB
+IOTHUB_CLIENT_RESULT IoTHubClient_LL_UploadToBlob(IOTHUB_CLIENT_LL_HANDLE iotHubClientHandle, const char* destinationFileName, const unsigned char* source, size_t size)
+{
+    return IoTHubClientCore_LL_UploadToBlob((IOTHUB_CLIENT_CORE_LL_HANDLE)iotHubClientHandle, destinationFileName, source, size);
+}
+
+IOTHUB_CLIENT_RESULT IoTHubClient_LL_UploadMultipleBlocksToBlob(IOTHUB_CLIENT_LL_HANDLE iotHubClientHandle, const char* destinationFileName, IOTHUB_CLIENT_FILE_UPLOAD_GET_DATA_CALLBACK getDataCallback, void* context)
+{
+    return IoTHubClientCore_LL_UploadMultipleBlocksToBlob((IOTHUB_CLIENT_CORE_LL_HANDLE)iotHubClientHandle, destinationFileName, getDataCallback, context);
+}
+
+IOTHUB_CLIENT_RESULT IoTHubClient_LL_UploadMultipleBlocksToBlobEx(IOTHUB_CLIENT_LL_HANDLE iotHubClientHandle, const char* destinationFileName, IOTHUB_CLIENT_FILE_UPLOAD_GET_DATA_CALLBACK_EX getDataCallbackEx, void* context)
+{
+    return IoTHubClientCore_LL_UploadMultipleBlocksToBlobEx((IOTHUB_CLIENT_CORE_LL_HANDLE)iotHubClientHandle, destinationFileName, getDataCallbackEx, context);
+}
+#endif
+
+
Index: azure_iot_hub_f767zi/trunk/azure_iot_sdk/iothub_client/src/iothub_client_ll_uploadtoblob.c
===================================================================
--- azure_iot_hub_f767zi/trunk/azure_iot_sdk/iothub_client/src/iothub_client_ll_uploadtoblob.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/azure_iot_sdk/iothub_client/src/iothub_client_ll_uploadtoblob.c	(revision 457)
@@ -0,0 +1,1176 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+#ifndef DONT_USE_UPLOADTOBLOB
+
+#include <stdlib.h>
+#include <string.h>
+#include "azure_c_shared_utility/optimize_size.h"
+#include "azure_c_shared_utility/gballoc.h"
+#include "azure_c_shared_utility/string_tokenizer.h"
+#include "azure_c_shared_utility/doublylinkedlist.h"
+#include "azure_c_shared_utility/xlogging.h"
+#include "azure_c_shared_utility/tickcounter.h"
+#include "azure_c_shared_utility/httpapiexsas.h"
+#include "azure_c_shared_utility/shared_util_options.h"
+#include "azure_c_shared_utility/urlencode.h"
+
+#include "iothub_client_core_ll.h"
+#include "iothub_client_options.h"
+#include "internal/iothub_client_private.h"
+#include "iothub_client_version.h"
+#include "iothub_transport_ll.h"
+#include "parson.h"
+#include "internal/iothub_client_ll_uploadtoblob.h"
+#include "internal/iothub_client_authorization.h"
+#include "internal/blob.h"
+
+#define API_VERSION "?api-version=2016-11-14"
+
+#ifdef WINCE
+#include <stdarg.h>
+// Returns number of characters copied.
+int snprintf(char * s, size_t n, const char * format, ...)
+{
+    int result;
+    va_list args;
+    va_start(args, format);
+    result = vsnprintf(s, n, format, args);
+    va_end(args);
+    return result;
+}
+#endif
+
+/*Codes_SRS_IOTHUBCLIENT_LL_02_085: [ IoTHubClient_LL_UploadToBlob shall use the same authorization as step 1. to prepare and perform a HTTP request with the following parameters: ]*/
+static const char* const RESPONSE_BODY_FORMAT = "{\"correlationId\":\"%s\", \"isSuccess\":%s, \"statusCode\":%d, \"statusDescription\":\"%s\"}";
+static const char* const RESPONSE_BODY_ABORTED_MESSAGE = "file upload aborted";
+static const char* const RESPONSE_BODY_FAILED_MESSAGE = "client not able to connect with the server";
+static const char* const RESPONSE_BODY_ERROR_RETURN_CODE = "-1";
+static const char* const RESPONSE_BODY_ERROR_BOOLEAN_STRING = "false";
+
+#define INDEFINITE_TIME                            ((time_t)-1)
+
+static const char* const EMPTY_STRING = "";
+static const char* const HEADER_AUTHORIZATION = "Authorization";
+static const char* const HEADER_APP_JSON = "application/json";
+
+typedef struct UPLOADTOBLOB_X509_CREDENTIALS_TAG
+{
+    char* x509certificate;
+    char* x509privatekey;
+} UPLOADTOBLOB_X509_CREDENTIALS;
+
+typedef enum UPOADTOBLOB_CURL_VERBOSITY_TAG
+{
+    UPOADTOBLOB_CURL_VERBOSITY_UNSET,
+    UPOADTOBLOB_CURL_VERBOSITY_ON,
+    UPOADTOBLOB_CURL_VERBOSITY_OFF
+} UPOADTOBLOB_CURL_VERBOSITY;
+
+typedef struct IOTHUB_CLIENT_LL_UPLOADTOBLOB_HANDLE_DATA_TAG
+{
+    const char* deviceId;
+    char* hostname;
+    IOTHUB_AUTHORIZATION_HANDLE authorization_module;
+    IOTHUB_CREDENTIAL_TYPE cred_type;
+    union 
+    {
+        UPLOADTOBLOB_X509_CREDENTIALS x509_credentials;
+        char* supplied_sas_token;
+    } credentials;
+    
+    char* certificates;
+    HTTP_PROXY_OPTIONS http_proxy_options;
+    UPOADTOBLOB_CURL_VERBOSITY curl_verbosity_level;
+    size_t blob_upload_timeout_secs;
+}IOTHUB_CLIENT_LL_UPLOADTOBLOB_HANDLE_DATA;
+
+typedef struct BLOB_UPLOAD_CONTEXT_TAG
+{
+    const unsigned char* blobSource; /* source to upload */
+    size_t blobSourceSize; /* size of the source */
+    size_t remainingSizeToUpload; /* size not yet uploaded */
+} BLOB_UPLOAD_CONTEXT;
+
+static int send_http_sas_request(IOTHUB_CLIENT_LL_UPLOADTOBLOB_HANDLE_DATA* upload_client, const char* uri_resource, HTTPAPIEX_HANDLE http_api_handle, const char* relative_path, HTTP_HEADERS_HANDLE request_header, BUFFER_HANDLE blobBuffer, BUFFER_HANDLE response_buff)
+{
+    int result;
+    unsigned int statusCode;
+
+    /*Codes_SRS_IOTHUBCLIENT_LL_02_089: [ If creating the HTTPAPIEX_SAS_HANDLE fails then IoTHubClient_LL_UploadMultipleBlocksToBlob(Ex) shall fail and return IOTHUB_CLIENT_ERROR. ]*/
+    HTTPAPIEX_SAS_HANDLE http_sas_handle = HTTPAPIEX_SAS_Create_From_String(IoTHubClient_Auth_Get_DeviceKey(upload_client->authorization_module), uri_resource, EMPTY_STRING);
+    if (http_sas_handle == NULL)
+    {
+        LogError("unable to HTTPAPIEX_SAS_Create");
+        result = MU_FAILURE;
+    }
+    else
+    {
+        /*Codes_SRS_IOTHUBCLIENT_LL_32_003: [ IoTHubClient_LL_UploadMultipleBlocksToBlob(Ex) shall execute HTTPAPIEX_ExecuteRequest passing the following information for arguments: ]*/
+        if (HTTPAPIEX_SAS_ExecuteRequest(http_sas_handle, http_api_handle, HTTPAPI_REQUEST_POST, relative_path, request_header,
+            blobBuffer, &statusCode, NULL, response_buff) != HTTPAPIEX_OK)
+        {
+            /*Codes_SRS_IOTHUBCLIENT_LL_02_076: [ If HTTPAPIEX_ExecuteRequest call fails then IoTHubClient_LL_UploadMultipleBlocksToBlob(Ex) shall fail and return IOTHUB_CLIENT_ERROR. ]*/
+            result = MU_FAILURE;
+            LogError("unable to HTTPAPIEX_ExecuteRequest");
+        }
+        else if (statusCode >= 300)
+        {
+            result = MU_FAILURE;
+            LogError("HTTP code was %u", statusCode);
+        }
+        else
+        {
+            result = 0;
+        }
+        HTTPAPIEX_SAS_Destroy(http_sas_handle);
+    }
+    return result;
+}
+
+static int send_http_request(HTTPAPIEX_HANDLE http_api_handle, const char* relative_path, HTTP_HEADERS_HANDLE request_header, BUFFER_HANDLE blobBuffer, BUFFER_HANDLE response_buff)
+{
+    int result;
+    unsigned int statusCode;
+    /*Codes_SRS_IOTHUBCLIENT_LL_32_003: [ IoTHubClient_LL_UploadMultipleBlocksToBlob(Ex) shall execute HTTPAPIEX_ExecuteRequest passing the following information for arguments: ]*/
+    if (HTTPAPIEX_ExecuteRequest(http_api_handle, HTTPAPI_REQUEST_POST, relative_path, request_header,
+        blobBuffer, &statusCode, NULL, response_buff) != HTTPAPIEX_OK)
+    {
+        /*Codes_SRS_IOTHUBCLIENT_LL_02_076: [ If HTTPAPIEX_ExecuteRequest call fails then IoTHubClient_LL_UploadMultipleBlocksToBlob(Ex) shall fail and return IOTHUB_CLIENT_ERROR. ]*/
+        result = MU_FAILURE;
+        LogError("unable to HTTPAPIEX_ExecuteRequest");
+    }
+    else if (statusCode >= 300)
+    {
+        result = MU_FAILURE;
+        LogError("HTTP code was %u", statusCode);
+    }
+    else
+    {
+        result = 0;
+    }
+    return result;
+}
+
+static int parse_result_json(const char* json_response, STRING_HANDLE correlation_id, STRING_HANDLE sas_uri)
+{
+    int result;
+
+    JSON_Object* json_obj;
+    /*Codes_SRS_IOTHUBCLIENT_LL_02_081: [ Otherwise, IoTHubClient_LL_UploadMultipleBlocksToBlob(Ex) shall use parson to extract and save the following information from the response buffer: correlationID and SasUri. ]*/
+    JSON_Value* json = json_parse_string(json_response);
+    if (json == NULL)
+    {
+        /*Codes_SRS_IOTHUBCLIENT_LL_02_082: [ If extracting and saving the correlationId or SasUri fails then IoTHubClient_LL_UploadMultipleBlocksToBlob(Ex) shall fail and return IOTHUB_CLIENT_ERROR. ]*/
+        LogError("unable to json_parse_string");
+        result = MU_FAILURE;
+
+    }
+    else
+    {
+        if ((json_obj = json_value_get_object(json)) == NULL)
+        {
+            LogError("unable to get json_value_get_object");
+            result = MU_FAILURE;
+        }
+        else
+        {
+            const char* json_corr_id;
+            const char* json_hostname;
+            const char* json_container_name;
+            const char* json_blob_name;
+            const char* json_sas_token;
+            STRING_HANDLE filename;
+            if ((json_corr_id = json_object_get_string(json_obj, "correlationId")) == NULL)
+            {
+                LogError("unable to retrieve correlation Id from json");
+                result = MU_FAILURE;
+            }
+            else if ((json_hostname = json_object_get_string(json_obj, "hostName")) == NULL)
+            {
+                LogError("unable to retrieve hostname Id from json");
+                result = MU_FAILURE;
+            }
+            else if ((json_container_name = json_object_get_string(json_obj, "containerName")) == NULL)
+            {
+                LogError("unable to retrieve container name Id from json");
+                result = MU_FAILURE;
+            }
+            else if ((json_blob_name = json_object_get_string(json_obj, "blobName")) == NULL)
+            {
+                LogError("unable to retrieve blob name Id from json");
+                result = MU_FAILURE;
+            }
+            else if ((json_sas_token = json_object_get_string(json_obj, "sasToken")) == NULL)
+            {
+                LogError("unable to retrieve sas token from json");
+                result = MU_FAILURE;
+            }
+            /*Codes_SRS_IOTHUBCLIENT_LL_32_008: [ The returned file name shall be URL encoded before passing back to the cloud. ]*/
+            else if ((filename = URL_EncodeString(json_blob_name)) == NULL)
+            {
+                /*Codes_SRS_IOTHUBCLIENT_LL_32_009: [ If URL_EncodeString fails then IoTHubClient_LL_UploadMultipleBlocksToBlob(Ex) shall fail and return IOTHUB_CLIENT_ERROR. ]*/
+                LogError("unable to URL encode of filename");
+                result = MU_FAILURE;
+            }
+            else
+            {
+                if (STRING_sprintf(sas_uri, "https://%s/%s/%s%s", json_hostname, json_container_name, STRING_c_str(filename), json_sas_token) != 0)
+                {
+                    /*Codes_SRS_IOTHUBCLIENT_LL_02_082: [ If extracting and saving the correlationId or SasUri fails then IoTHubClient_LL_UploadMultipleBlocksToBlob(Ex) shall fail and return IOTHUB_CLIENT_ERROR. ]*/
+                    LogError("unable to construct uri string");
+                    result = MU_FAILURE;
+                }
+                else if (STRING_copy(correlation_id, json_corr_id) != 0)
+                {
+                    /*Codes_SRS_IOTHUBCLIENT_LL_02_082: [ If extracting and saving the correlationId or SasUri fails then IoTHubClient_LL_UploadMultipleBlocksToBlob(Ex) shall fail and return IOTHUB_CLIENT_ERROR. ]*/
+                    LogError("unable to copy correlation Id");
+                    result = MU_FAILURE;
+                    STRING_empty(sas_uri);
+                }
+                else
+                {
+                    result = 0;
+                }
+                STRING_delete(filename);
+            }
+        }
+        json_value_free(json);
+    }
+    return result;
+}
+
+IOTHUB_CLIENT_LL_UPLOADTOBLOB_HANDLE IoTHubClient_LL_UploadToBlob_Create(const IOTHUB_CLIENT_CONFIG* config, IOTHUB_AUTHORIZATION_HANDLE auth_handle)
+{
+    IOTHUB_CLIENT_LL_UPLOADTOBLOB_HANDLE_DATA* upload_data;
+    if (auth_handle == NULL || config == NULL)
+    {
+        LogError("Invalid arguments auth_handle: %p, config: %p", auth_handle, config);
+        upload_data = NULL;
+    }
+    else
+    {
+        upload_data = malloc(sizeof(IOTHUB_CLIENT_LL_UPLOADTOBLOB_HANDLE_DATA));
+        if (upload_data == NULL)
+        {
+            LogError("Failed malloc allocation");
+            /*return as is*/
+        }
+        else
+        {
+            memset(upload_data, 0, sizeof(IOTHUB_CLIENT_LL_UPLOADTOBLOB_HANDLE_DATA));
+
+            upload_data->authorization_module = auth_handle;
+
+            size_t iotHubNameLength = strlen(config->iotHubName);
+            size_t iotHubSuffixLength = strlen(config->iotHubSuffix);
+            upload_data->hostname = malloc(iotHubNameLength + 1 + iotHubSuffixLength + 1); /*first +1 is because "." the second +1 is because \0*/
+            if (upload_data->hostname == NULL)
+            {
+                LogError("Failed malloc allocation");
+                free(upload_data);
+                upload_data = NULL;
+            }
+            else if ((upload_data->deviceId = IoTHubClient_Auth_Get_DeviceId(upload_data->authorization_module)) == NULL)
+            {
+                LogError("Failed retrieving device ID");
+                free(upload_data->hostname);
+                free(upload_data);
+                upload_data = NULL;
+            }
+            else
+            {
+                char* insert_pos = (char*)upload_data->hostname;
+                (void)memcpy((char*)insert_pos, config->iotHubName, iotHubNameLength);
+                insert_pos += iotHubNameLength;
+                *insert_pos = '.';
+                insert_pos += 1;
+                (void)memcpy(insert_pos, config->iotHubSuffix, iotHubSuffixLength); /*+1 will copy the \0 too*/
+                insert_pos += iotHubSuffixLength;
+                *insert_pos = '\0';
+
+                upload_data->cred_type = IoTHubClient_Auth_Get_Credential_Type(upload_data->authorization_module);
+                // If the credential type is unknown then it means that we are using x509 because the certs need to get
+                // passed down later in the process.
+                if (upload_data->cred_type == IOTHUB_CREDENTIAL_TYPE_UNKNOWN || upload_data->cred_type == IOTHUB_CREDENTIAL_TYPE_X509)
+                {
+                    upload_data->cred_type = IOTHUB_CREDENTIAL_TYPE_X509;
+                    upload_data->credentials.x509_credentials.x509certificate = NULL;
+                    upload_data->credentials.x509_credentials.x509privatekey = NULL;
+                }
+                else if (upload_data->cred_type == IOTHUB_CREDENTIAL_TYPE_X509_ECC)
+                {
+                    if (IoTHubClient_Auth_Get_x509_info(upload_data->authorization_module, &upload_data->credentials.x509_credentials.x509certificate, &upload_data->credentials.x509_credentials.x509privatekey) != 0)
+                    {
+                        LogError("Failed getting x509 certificate information");
+                        free(upload_data->hostname);
+                        free(upload_data);
+                        upload_data = NULL;
+                    }
+                }
+                else if (upload_data->cred_type == IOTHUB_CREDENTIAL_TYPE_SAS_TOKEN)
+                {
+                    upload_data->credentials.supplied_sas_token = IoTHubClient_Auth_Get_SasToken(upload_data->authorization_module, NULL, 0, EMPTY_STRING);
+                    if (upload_data->credentials.supplied_sas_token == NULL)
+                    {
+                        LogError("Failed retrieving supplied sas token");
+                        free(upload_data->hostname);
+                        free(upload_data);
+                        upload_data = NULL;
+                    }
+                }
+            }
+        }
+    }
+    return (IOTHUB_CLIENT_LL_UPLOADTOBLOB_HANDLE)upload_data;
+
+}
+
+/*returns 0 when correlationId, sasUri contain data*/
+static int IoTHubClient_LL_UploadToBlob_step1and2(IOTHUB_CLIENT_LL_UPLOADTOBLOB_HANDLE_DATA* upload_data, HTTPAPIEX_HANDLE iotHubHttpApiExHandle, HTTP_HEADERS_HANDLE requestHttpHeaders, const char* destinationFileName, STRING_HANDLE correlationId, STRING_HANDLE sasUri)
+{
+    int result;
+
+    /*Codes_SRS_IOTHUBCLIENT_LL_02_066: [ IoTHubClient_LL_UploadMultipleBlocksToBlob(Ex) shall create an HTTP relative path formed from "/devices/" + deviceId + "/files/" + "?api-version=API_VERSION". ]*/
+    STRING_HANDLE relativePath = STRING_construct_sprintf("/devices/%s/files/%s", upload_data->deviceId, API_VERSION);
+    if (relativePath == NULL)
+    {
+        /*Codes_SRS_IOTHUBCLIENT_LL_02_067: [ If creating the relativePath fails then IoTHubClient_LL_UploadMultipleBlocksToBlob(Ex) shall fail and return IOTHUB_CLIENT_ERROR. ]*/
+        LogError("Failure constructing string");
+        result = MU_FAILURE;
+    }
+    else
+    {
+        /*Codes_SRS_IOTHUBCLIENT_LL_32_001: [ IoTHubClient_LL_UploadMultipleBlocksToBlob(Ex) shall create a JSON string formed from "{ \"blobName\": \" + destinationFileName + "\" }" */
+        STRING_HANDLE blobName = STRING_construct_sprintf("{ \"blobName\": \"%s\" }", destinationFileName);
+        if (blobName == NULL)
+        {
+            /*Codes_SRS_IOTHUBCLIENT_LL_32_002: [ If creating the JSON string fails then IoTHubClient_LL_UploadMultipleBlocksToBlob(Ex) shall fail and return IOTHUB_CLIENT_ERROR. ]*/
+            LogError("Failure constructing string");
+            result = MU_FAILURE;
+        }
+        else
+        {
+            BUFFER_HANDLE responseContent;
+            size_t len = STRING_length(blobName);
+            BUFFER_HANDLE blobBuffer = BUFFER_create((const unsigned char *)STRING_c_str(blobName), len);
+            if (blobBuffer == NULL)
+            {
+                /*Codes_SRS_IOTHUBCLIENT_LL_32_002: [ If creating the JSON string fails then IoTHubClient_LL_UploadMultipleBlocksToBlob(Ex) shall fail and return IOTHUB_CLIENT_ERROR. ]*/
+                LogError("unable to create BUFFER");
+                result = MU_FAILURE;
+            }
+            else
+            {
+                /*Codes_SRS_IOTHUBCLIENT_LL_02_068: [ IoTHubClient_LL_UploadMultipleBlocksToBlob(Ex) shall create an HTTP responseContent BUFFER_HANDLE. ]*/
+                if ((responseContent = BUFFER_new()) == NULL)
+                {
+                    /*Codes_SRS_IOTHUBCLIENT_LL_02_069: [ If creating the HTTP response buffer handle fails then IoTHubClient_LL_UploadMultipleBlocksToBlob(Ex) shall fail and return IOTHUB_CLIENT_ERROR. ]*/
+                    result = MU_FAILURE;
+                    LogError("unable to BUFFER_new");
+                }
+                else
+                {
+                    /*Codes_SRS_IOTHUBCLIENT_LL_02_072: [ IoTHubClient_LL_UploadMultipleBlocksToBlob(Ex) shall add the following name:value to request HTTP headers: ] "Content-Type": "application/json" "Accept": "application/json" "User-Agent": "iothubclient/" IOTHUB_SDK_VERSION*/
+                    /*Codes_SRS_IOTHUBCLIENT_LL_02_107: [ - "Authorization" header shall not be build. ]*/
+                    if (!(
+                        (HTTPHeaders_AddHeaderNameValuePair(requestHttpHeaders, "Content-Type", HEADER_APP_JSON) == HTTP_HEADERS_OK) &&
+                        (HTTPHeaders_AddHeaderNameValuePair(requestHttpHeaders, "Accept", HEADER_APP_JSON) == HTTP_HEADERS_OK) &&
+                        (HTTPHeaders_AddHeaderNameValuePair(requestHttpHeaders, "User-Agent", "iothubclient/" IOTHUB_SDK_VERSION) == HTTP_HEADERS_OK) &&
+                        ((upload_data->cred_type == IOTHUB_CREDENTIAL_TYPE_X509 || upload_data->cred_type == IOTHUB_CREDENTIAL_TYPE_X509_ECC) ||
+                        (HTTPHeaders_AddHeaderNameValuePair(requestHttpHeaders, HEADER_AUTHORIZATION, EMPTY_STRING) == HTTP_HEADERS_OK))
+                        ))
+                    {
+                        /*Codes_SRS_IOTHUBCLIENT_LL_02_071: [ If creating the HTTP headers fails then IoTHubClient_LL_UploadMultipleBlocksToBlob(Ex) shall fail and return IOTHUB_CLIENT_ERROR. ]*/
+                        LogError("unable to HTTPHeaders_AddHeaderNameValuePair");
+                        result = MU_FAILURE;
+                    }
+                    else
+                    {
+                        int wasIoTHubRequestSuccess = 0; /*!=0 means responseContent has a buffer that should be parsed by parson after executing the below switch*/
+                        /* set the result to error by default */
+                        result = MU_FAILURE;
+                        switch (upload_data->cred_type)
+                        {
+                            default:
+                            {
+                                /*wasIoTHubRequestSuccess takes care of the return value*/
+                                LogError("Internal Error: unexpected value in auth schema = %d", upload_data->cred_type);
+                                result = MU_FAILURE;
+                                break;
+                            }
+                            case IOTHUB_CREDENTIAL_TYPE_X509_ECC:
+                            case IOTHUB_CREDENTIAL_TYPE_X509:
+                            {
+                                if (send_http_request(iotHubHttpApiExHandle, STRING_c_str(relativePath), requestHttpHeaders, blobBuffer, responseContent) != 0)
+                                {
+                                    /*Codes_SRS_IOTHUBCLIENT_LL_02_076: [ If HTTPAPIEX_ExecuteRequest call fails then IoTHubClient_LL_UploadMultipleBlocksToBlob(Ex) shall fail and return IOTHUB_CLIENT_ERROR. ]*/
+                                    result = MU_FAILURE;
+                                    LogError("unable to HTTPAPIEX_ExecuteRequest");
+                                }
+                                else
+                                {
+                                    wasIoTHubRequestSuccess = 1;
+                                }
+                                break;
+                            }
+                            case IOTHUB_CREDENTIAL_TYPE_DEVICE_KEY:
+                            case IOTHUB_CREDENTIAL_TYPE_DEVICE_AUTH:
+                            {
+                                STRING_HANDLE uri_resource = STRING_construct_sprintf("%s/devices/%s", upload_data->hostname, upload_data->deviceId);
+                                if (uri_resource == NULL)
+                                {
+                                    /*Codes_SRS_IOTHUBCLIENT_LL_02_089: [ If creating the HTTPAPIEX_SAS_HANDLE fails then IoTHubClient_LL_UploadMultipleBlocksToBlob(Ex) shall fail and return IOTHUB_CLIENT_ERROR. ]*/
+                                    result = MU_FAILURE;
+                                    LogError("Failure constructing string");
+                                }
+                                else
+                                {
+                                    if (upload_data->cred_type == IOTHUB_CREDENTIAL_TYPE_DEVICE_AUTH)
+                                    {
+                                        time_t curr_time;
+                                        if ((curr_time = get_time(NULL)) == INDEFINITE_TIME)
+                                        {
+                                            result = MU_FAILURE;
+                                            LogError("failure retrieving time");
+                                        }
+                                        else
+                                        {
+                                            size_t expiry = (size_t)(difftime(curr_time, 0) + 3600);
+                                            char* sas_token = IoTHubClient_Auth_Get_SasToken(upload_data->authorization_module, STRING_c_str(uri_resource), expiry, EMPTY_STRING);
+                                            if (sas_token == NULL)
+                                            {
+                                                result = MU_FAILURE;
+                                                LogError("unable to retrieve sas token");
+                                            }
+                                            else
+                                            {
+                                                if (HTTPHeaders_ReplaceHeaderNameValuePair(requestHttpHeaders, HEADER_AUTHORIZATION, sas_token) != HTTP_HEADERS_OK)
+                                                {
+                                                    /*Codes_SRS_IOTHUBCLIENT_LL_02_074: [ If adding "Authorization" fails then IoTHubClient_LL_UploadMultipleBlocksToBlob(Ex) shall fail and return IOTHUB_CLIENT_ERROR ]*/
+                                                    result = MU_FAILURE;
+                                                    LogError("unable to HTTPHeaders_AddHeaderNameValuePair");
+                                                }
+                                                else if (send_http_request(iotHubHttpApiExHandle, STRING_c_str(relativePath), requestHttpHeaders, blobBuffer, responseContent) != 0)
+                                                {
+                                                    /*Codes_SRS_IOTHUBCLIENT_LL_02_076: [ If HTTPAPIEX_ExecuteRequest call fails then IoTHubClient_LL_UploadMultipleBlocksToBlob(Ex) shall fail and return IOTHUB_CLIENT_ERROR. ]*/
+                                                    result = MU_FAILURE;
+                                                    LogError("unable to HTTPAPIEX_ExecuteRequest");
+                                                }
+                                                else
+                                                {
+                                                    wasIoTHubRequestSuccess = 1;
+                                                }
+                                            }
+                                            free(sas_token);
+                                        }
+                                    }
+                                    else
+                                    {
+                                        if (send_http_sas_request(upload_data, STRING_c_str(uri_resource), iotHubHttpApiExHandle, STRING_c_str(relativePath), requestHttpHeaders, blobBuffer, responseContent) != 0)
+                                        {
+                                            /*Codes_SRS_IOTHUBCLIENT_LL_02_076: [ If HTTPAPIEX_ExecuteRequest call fails then IoTHubClient_LL_UploadMultipleBlocksToBlob(Ex) shall fail and return IOTHUB_CLIENT_ERROR. ]*/
+                                            result = MU_FAILURE;
+                                            LogError("unable to HTTPAPIEX_ExecuteRequest");
+                                        }
+                                        else
+                                        {
+                                            wasIoTHubRequestSuccess = 1;
+                                        }
+                                    }
+                                    STRING_delete(uri_resource);
+                                }
+                                break;
+                            }
+                            case IOTHUB_CREDENTIAL_TYPE_SAS_TOKEN:
+                            {
+                                /*Codes_SRS_IOTHUBCLIENT_LL_02_073: [ If the credentials used to create handle have "sasToken" then IoTHubClient_LL_UploadMultipleBlocksToBlob(Ex) shall add the following HTTP request headers: ]*/
+                                if (HTTPHeaders_ReplaceHeaderNameValuePair(requestHttpHeaders, HEADER_AUTHORIZATION, upload_data->credentials.supplied_sas_token) != HTTP_HEADERS_OK)
+                                {
+                                    /*Codes_SRS_IOTHUBCLIENT_LL_02_074: [ If adding "Authorization" fails then IoTHubClient_LL_UploadMultipleBlocksToBlob(Ex) shall fail and return IOTHUB_CLIENT_ERROR ]*/
+                                    result = MU_FAILURE;
+                                    LogError("unable to HTTPHeaders_AddHeaderNameValuePair");
+                                }
+                                else if (send_http_request(iotHubHttpApiExHandle, STRING_c_str(relativePath), requestHttpHeaders, blobBuffer, responseContent) != 0)
+                                {
+                                    /*Codes_SRS_IOTHUBCLIENT_LL_02_076: [ If HTTPAPIEX_ExecuteRequest call fails then IoTHubClient_LL_UploadMultipleBlocksToBlob(Ex) shall fail and return IOTHUB_CLIENT_ERROR. ]*/
+                                    result = MU_FAILURE;
+                                    LogError("unable to HTTPAPIEX_ExecuteRequest");
+                                }
+                                else
+                                {
+                                    wasIoTHubRequestSuccess = 1;
+                                }
+                                break;
+                            }
+                        }
+                        if (wasIoTHubRequestSuccess == 1)
+                        {
+                            const unsigned char*responseContent_u_char = BUFFER_u_char(responseContent);
+                            size_t responseContent_length = BUFFER_length(responseContent);
+                            STRING_HANDLE responseAsString = STRING_from_byte_array(responseContent_u_char, responseContent_length);
+                            if (responseAsString == NULL)
+                            {
+                                result = MU_FAILURE;
+                                LogError("unable to get the response as string");
+                            }
+                            else
+                            {
+                                if (parse_result_json(STRING_c_str(responseAsString), correlationId, sasUri) != 0)
+                                {
+                                    /*Codes_SRS_IOTHUBCLIENT_LL_02_082: [ If extracting and saving the correlationId or SasUri fails then IoTHubClient_LL_UploadMultipleBlocksToBlob(Ex) shall fail and return IOTHUB_CLIENT_ERROR. ]*/
+                                    LogError("unable to parse json result");
+                                    result = MU_FAILURE;
+                                }
+                                else
+                                {
+                                    result = 0;
+                                }
+                                STRING_delete(responseAsString);
+                            }
+                        }
+                    }
+                    BUFFER_delete(responseContent);
+                }
+                BUFFER_delete(blobBuffer);
+            }
+            STRING_delete(blobName);
+        }
+        STRING_delete(relativePath);
+    }
+    return result;
+}
+
+/*returns 0 when the IoTHub has been informed about the file upload status*/
+static int IoTHubClient_LL_UploadToBlob_step3(IOTHUB_CLIENT_LL_UPLOADTOBLOB_HANDLE_DATA* upload_data, HTTPAPIEX_HANDLE iotHubHttpApiExHandle, HTTP_HEADERS_HANDLE requestHttpHeaders, BUFFER_HANDLE messageBody)
+{
+    int result;
+    /*here is step 3. depending on the outcome of step 2 it needs to inform IoTHub about the file upload status*/
+    /*if step 1 failed, there's nothing that step 3 needs to report.*/
+    /*this POST "tries" to happen*/
+
+    /*Codes_SRS_IOTHUBCLIENT_LL_02_085: [ IoTHubClient_LL_UploadMultipleBlocksToBlob(Ex) shall use the same authorization as step 1. to prepare and perform a HTTP request with the following parameters: ]*/
+    STRING_HANDLE relativePathNotification = STRING_construct_sprintf("/devices/%s/files/notifications/%s", upload_data->deviceId, API_VERSION);
+    if (relativePathNotification == NULL)
+    {
+        result = MU_FAILURE;
+        LogError("Failure constructing string");
+    }
+    else
+    {
+        /*Codes_SRS_IOTHUBCLIENT_LL_02_086: [ If performing the HTTP request fails then IoTHubClient_LL_UploadMultipleBlocksToBlob(Ex) shall fail and return IOTHUB_CLIENT_ERROR. ]*/
+        switch (upload_data->cred_type)
+        {
+            default:
+            {
+                LogError("internal error: unknown authorization Scheme");
+                result = MU_FAILURE;
+                break;
+            }
+            case IOTHUB_CREDENTIAL_TYPE_SAS_TOKEN:
+            case IOTHUB_CREDENTIAL_TYPE_X509:
+            case IOTHUB_CREDENTIAL_TYPE_X509_ECC:
+            case IOTHUB_CREDENTIAL_TYPE_DEVICE_AUTH:
+            {
+                if (send_http_request(iotHubHttpApiExHandle, STRING_c_str(relativePathNotification), requestHttpHeaders, messageBody, NULL) != 0)
+                {
+                    LogError("unable to execute HTTPAPIEX_ExecuteRequest");
+                    result = MU_FAILURE;
+                }
+                else
+                {
+                    result = 0;
+                }
+                break;
+            }
+            case IOTHUB_CREDENTIAL_TYPE_DEVICE_KEY:
+            {
+                STRING_HANDLE uriResource = STRING_construct_sprintf("%s/devices/%s/files/notifications", upload_data->hostname, upload_data->deviceId);
+                if (uriResource == NULL)
+                {
+                    LogError("Failure constructing string");
+                    result = MU_FAILURE;
+                }
+                else
+                {
+                    if (send_http_sas_request(upload_data, STRING_c_str(uriResource), iotHubHttpApiExHandle, STRING_c_str(relativePathNotification), requestHttpHeaders, messageBody, NULL) != 0)
+                    {
+                        LogError("unable to execute HTTPAPIEX_ExecuteRequest");
+                        result = MU_FAILURE;
+                    }
+                    else
+                    {
+                        result = 0;
+                    }
+                    STRING_delete(uriResource);
+                }
+                break;
+            }
+        }
+        STRING_delete(relativePathNotification);
+    }
+    return result;
+}
+
+// this callback splits the source data into blocks to be fed to IoTHubClient_LL_UploadMultipleBlocksToBlob(Ex)_Impl
+static IOTHUB_CLIENT_FILE_UPLOAD_GET_DATA_RESULT FileUpload_GetData_Callback(IOTHUB_CLIENT_FILE_UPLOAD_RESULT result, unsigned char const ** data, size_t* size, void* context)
+{
+    BLOB_UPLOAD_CONTEXT* uploadContext = (BLOB_UPLOAD_CONTEXT*) context;
+
+    if (data == NULL || size == NULL)
+    {
+        // This is the last call, nothing to do
+    }
+    else if (result != FILE_UPLOAD_OK)
+    {
+        // Last call failed
+        *data = NULL;
+        *size = 0;
+    }
+    else if (uploadContext->remainingSizeToUpload == 0)
+    {
+        // Everything has been uploaded
+        *data = NULL;
+        *size = 0;
+    }
+    else
+    {
+        // Upload next block
+        size_t thisBlockSize = (uploadContext->remainingSizeToUpload > BLOCK_SIZE) ? BLOCK_SIZE : uploadContext->remainingSizeToUpload;
+        *data = (unsigned char*)uploadContext->blobSource + (uploadContext->blobSourceSize - uploadContext->remainingSizeToUpload);
+        *size = thisBlockSize;
+        uploadContext->remainingSizeToUpload -= thisBlockSize;
+    }
+
+    return IOTHUB_CLIENT_FILE_UPLOAD_GET_DATA_OK;
+}
+
+static HTTPAPIEX_RESULT set_transfer_timeout(IOTHUB_CLIENT_LL_UPLOADTOBLOB_HANDLE_DATA* upload_data, HTTPAPIEX_HANDLE iotHubHttpApiExHandle)
+{
+    HTTPAPIEX_RESULT result;
+    if (upload_data->blob_upload_timeout_secs != 0)
+    {
+        // Convert the timeout to milliseconds for curl
+        long http_timeout = (long)upload_data->blob_upload_timeout_secs * 1000;
+        result = HTTPAPIEX_SetOption(iotHubHttpApiExHandle, OPTION_HTTP_TIMEOUT, &http_timeout);
+    }
+    else
+    {
+        result = HTTPAPIEX_OK;
+    }
+    return result;
+}
+
+IOTHUB_CLIENT_RESULT IoTHubClient_LL_UploadMultipleBlocksToBlob_Impl(IOTHUB_CLIENT_LL_UPLOADTOBLOB_HANDLE handle, const char* destinationFileName, IOTHUB_CLIENT_FILE_UPLOAD_GET_DATA_CALLBACK_EX getDataCallbackEx, void* context)
+{
+    IOTHUB_CLIENT_RESULT result;
+
+    /*Codes_SRS_IOTHUBCLIENT_LL_02_061: [ If handle is NULL then IoTHubClient_LL_UploadMultipleBlocksToBlob(Ex) shall fail and return IOTHUB_CLIENT_INVALID_ARG. ]*/
+    /*Codes_SRS_IOTHUBCLIENT_LL_02_062: [ If destinationFileName is NULL then IoTHubClient_LL_UploadMultipleBlocksToBlob(Ex) shall fail and return IOTHUB_CLIENT_INVALID_ARG. ]*/
+
+    if (handle == NULL || destinationFileName == NULL || getDataCallbackEx == NULL)
+    {
+        LogError("invalid argument detected handle=%p destinationFileName=%p getDataCallbackEx=%p", handle, destinationFileName, getDataCallbackEx);
+        result = IOTHUB_CLIENT_INVALID_ARG;
+    }
+    else
+    {
+        IOTHUB_CLIENT_LL_UPLOADTOBLOB_HANDLE_DATA* upload_data = (IOTHUB_CLIENT_LL_UPLOADTOBLOB_HANDLE_DATA*)handle;
+
+        /*Codes_SRS_IOTHUBCLIENT_LL_02_064: [ IoTHubClient_LL_UploadMultipleBlocksToBlob(Ex) shall create an HTTPAPIEX_HANDLE to the IoTHub hostname. ]*/
+        HTTPAPIEX_HANDLE iotHubHttpApiExHandle = HTTPAPIEX_Create(upload_data->hostname);
+        /*Codes_SRS_IOTHUBCLIENT_LL_02_065: [ If creating the HTTPAPIEX_HANDLE fails then IoTHubClient_LL_UploadMultipleBlocksToBlob(Ex) shall fail and return IOTHUB_CLIENT_ERROR. ]*/
+        if (iotHubHttpApiExHandle == NULL)
+        {
+            LogError("unable to HTTPAPIEX_Create");
+            result = IOTHUB_CLIENT_ERROR;
+        }
+        /*Codes_SRS_IOTHUBCLIENT_LL_30_020: [ If the blob_upload_timeout_secs option has been set to non-zero, IoTHubClient_LL_UploadMultipleBlocksToBlob(Ex) shall set the timeout on the underlying transport accordingly. ]*/
+        else if (set_transfer_timeout(upload_data, iotHubHttpApiExHandle) != HTTPAPIEX_OK)
+        {
+            LogError("unable to set blob transfer timeout");
+            result = IOTHUB_CLIENT_ERROR;
+        }
+        else
+        {
+            if (upload_data->curl_verbosity_level != UPOADTOBLOB_CURL_VERBOSITY_UNSET)
+            {
+                size_t curl_verbose = (upload_data->curl_verbosity_level == UPOADTOBLOB_CURL_VERBOSITY_ON);
+                (void)HTTPAPIEX_SetOption(iotHubHttpApiExHandle, OPTION_CURL_VERBOSE, &curl_verbose);
+            }
+
+            /*transmit the x509certificate and x509privatekey*/
+            /*Codes_SRS_IOTHUBCLIENT_LL_02_106: [ - x509certificate and x509privatekey saved options shall be passed on the HTTPAPIEX_SetOption ]*/
+            if ((upload_data->cred_type == IOTHUB_CREDENTIAL_TYPE_X509 || upload_data->cred_type == IOTHUB_CREDENTIAL_TYPE_X509_ECC) &&
+                ((HTTPAPIEX_SetOption(iotHubHttpApiExHandle, OPTION_X509_CERT, upload_data->credentials.x509_credentials.x509certificate) != HTTPAPIEX_OK) ||
+                (HTTPAPIEX_SetOption(iotHubHttpApiExHandle, OPTION_X509_PRIVATE_KEY, upload_data->credentials.x509_credentials.x509privatekey) != HTTPAPIEX_OK))
+                )
+            {
+                LogError("unable to HTTPAPIEX_SetOption for x509 certificate");
+                result = IOTHUB_CLIENT_ERROR;
+            }
+            else
+            {
+                /*Codes_SRS_IOTHUBCLIENT_LL_02_111: [ If certificates is non-NULL then certificates shall be passed to HTTPAPIEX_SetOption with optionName TrustedCerts. ]*/
+                if ((upload_data->certificates != NULL) && (HTTPAPIEX_SetOption(iotHubHttpApiExHandle, OPTION_TRUSTED_CERT, upload_data->certificates) != HTTPAPIEX_OK))
+                {
+                    LogError("unable to set TrustedCerts!");
+                    result = IOTHUB_CLIENT_ERROR;
+                }
+                else
+                {
+
+                    if (upload_data->http_proxy_options.host_address != NULL)
+                    {
+                        HTTP_PROXY_OPTIONS proxy_options;
+                        proxy_options = upload_data->http_proxy_options;
+
+                        if (HTTPAPIEX_SetOption(iotHubHttpApiExHandle, OPTION_HTTP_PROXY, &proxy_options) != HTTPAPIEX_OK)
+                        {
+                            LogError("unable to set http proxy!");
+                            result = IOTHUB_CLIENT_ERROR;
+                        }
+                        else
+                        {
+                            result = IOTHUB_CLIENT_OK;
+                        }
+                    }
+                    else
+                    {
+                        result = IOTHUB_CLIENT_OK;
+                    }
+
+                    if (result != IOTHUB_CLIENT_ERROR)
+                    {
+                        STRING_HANDLE sasUri;
+                        STRING_HANDLE correlationId;
+                        if ((correlationId = STRING_new()) == NULL)
+                        {
+                            LogError("unable to STRING_new");
+                            result = IOTHUB_CLIENT_ERROR;
+                        }
+                        else if ((sasUri = STRING_new()) == NULL)
+                        {
+                            LogError("unable to create sas uri");
+                            result = IOTHUB_CLIENT_ERROR;
+                            STRING_delete(correlationId);
+                        }
+                        else
+                        {
+                            /*Codes_SRS_IOTHUBCLIENT_LL_02_070: [ IoTHubClient_LL_UploadMultipleBlocksToBlob(Ex) shall create request HTTP headers. ]*/
+                            HTTP_HEADERS_HANDLE requestHttpHeaders = HTTPHeaders_Alloc(); /*these are build by step 1 and used by step 3 too*/
+                            if (requestHttpHeaders == NULL)
+                            {
+                                LogError("unable to HTTPHeaders_Alloc");
+                                result = IOTHUB_CLIENT_ERROR;
+                            }
+                            else
+                            {
+                                /*do step 1*/
+                                if (IoTHubClient_LL_UploadToBlob_step1and2(upload_data, iotHubHttpApiExHandle, requestHttpHeaders, destinationFileName, correlationId, sasUri) != 0)
+                                {
+                                    LogError("error in IoTHubClient_LL_UploadToBlob_step1");
+                                    result = IOTHUB_CLIENT_ERROR;
+                                }
+                                else
+                                {
+                                    /*do step 2.*/
+
+                                    unsigned int httpResponse;
+                                    BUFFER_HANDLE responseToIoTHub = BUFFER_new();
+                                    if (responseToIoTHub == NULL)
+                                    {
+                                        result = IOTHUB_CLIENT_ERROR;
+                                        LogError("unable to BUFFER_new");
+                                    }
+                                    else
+                                    {
+                                        /*Codes_SRS_IOTHUBCLIENT_LL_02_083: [ IoTHubClient_LL_UploadMultipleBlocksToBlob(Ex) shall call Blob_UploadFromSasUri and capture the HTTP return code and HTTP body. ]*/
+                                        BLOB_RESULT uploadMultipleBlocksResult = Blob_UploadMultipleBlocksFromSasUri(STRING_c_str(sasUri), getDataCallbackEx, context, &httpResponse, responseToIoTHub, upload_data->certificates, &(upload_data->http_proxy_options));
+                                        if (uploadMultipleBlocksResult == BLOB_ABORTED)
+                                        {
+                                            /*Codes_SRS_IOTHUBCLIENT_LL_99_008: [ If step 2 is aborted by the client, then the HTTP message body shall look like:  ]*/
+                                            LogInfo("Blob_UploadFromSasUri aborted file upload");
+
+                                            STRING_HANDLE aborted_response = STRING_construct_sprintf(RESPONSE_BODY_FORMAT,
+                                                                                        STRING_c_str(correlationId),
+                                                                                        RESPONSE_BODY_ERROR_BOOLEAN_STRING,
+                                                                                        RESPONSE_BODY_ERROR_RETURN_CODE,
+                                                                                        RESPONSE_BODY_ABORTED_MESSAGE);
+                                            if(aborted_response == NULL)
+                                            {
+                                                LogError("STRING_construct_sprintf failed");
+                                                result = IOTHUB_CLIENT_ERROR;
+                                            }
+                                            else
+                                            {
+                                                size_t response_length = STRING_length(aborted_response);
+                                                if (BUFFER_build(responseToIoTHub, (const unsigned char*)STRING_c_str(aborted_response), response_length) == 0)
+                                                {
+                                                    if (IoTHubClient_LL_UploadToBlob_step3(upload_data, iotHubHttpApiExHandle, requestHttpHeaders, responseToIoTHub) != 0)
+                                                    {
+                                                        LogError("IoTHubClient_LL_UploadToBlob_step3 failed");
+                                                        result = IOTHUB_CLIENT_ERROR;
+                                                    }
+                                                    else
+                                                    {
+                                                        /*Codes_SRS_IOTHUBCLIENT_LL_99_009: [ If step 2 is aborted by the client and if step 3 succeeds, then `IoTHubClient_LL_UploadMultipleBlocksToBlob(Ex)` shall return `IOTHUB_CLIENT_OK`. ] */
+                                                        result = IOTHUB_CLIENT_OK;
+                                                    }
+                                                }
+                                                else
+                                                {
+                                                    LogError("Unable to BUFFER_build, can't perform IoTHubClient_LL_UploadToBlob_step3");
+                                                    result = IOTHUB_CLIENT_ERROR;
+                                                }
+                                                STRING_delete(aborted_response);
+                                            }
+                                        }
+                                        else if (uploadMultipleBlocksResult != BLOB_OK)
+                                        {
+                                            /*Codes_SRS_IOTHUBCLIENT_LL_02_084: [ If Blob_UploadFromSasUri fails then IoTHubClient_LL_UploadMultipleBlocksToBlob(Ex) shall fail and return IOTHUB_CLIENT_ERROR. ]*/
+                                            LogError("unable to Blob_UploadFromSasUri");
+
+                                            /*do step 3*/ /*try*/
+                                            /*Codes_SRS_IOTHUBCLIENT_LL_02_091: [ If step 2 fails without establishing an HTTP dialogue, then the HTTP message body shall look like: ]*/
+                                            STRING_HANDLE failed_response = STRING_construct_sprintf(RESPONSE_BODY_FORMAT, 
+                                                                                        STRING_c_str(correlationId), 
+                                                                                        RESPONSE_BODY_ERROR_BOOLEAN_STRING,
+                                                                                        RESPONSE_BODY_ERROR_RETURN_CODE,
+                                                                                        RESPONSE_BODY_FAILED_MESSAGE);
+                                            if(failed_response == NULL)
+                                            {
+                                                LogError("STRING_construct_sprintf failed");
+                                                result = IOTHUB_CLIENT_ERROR;
+                                            }
+                                            else
+                                            {
+                                                size_t response_length = STRING_length(failed_response);
+                                                if (BUFFER_build(responseToIoTHub, (const unsigned char*)STRING_c_str(failed_response), response_length) == 0)
+                                                {
+                                                    if (IoTHubClient_LL_UploadToBlob_step3(upload_data, iotHubHttpApiExHandle, requestHttpHeaders, responseToIoTHub) != 0)
+                                                    {
+                                                        LogError("IoTHubClient_LL_UploadToBlob_step3 failed");
+                                                    }
+                                                }
+                                                STRING_delete(failed_response);
+                                                result = IOTHUB_CLIENT_ERROR;
+                                            }
+                                        }
+                                        else
+                                        {
+                                            /*must make a json*/
+                                            unsigned char * response = BUFFER_u_char(responseToIoTHub);
+                                            STRING_HANDLE req_string;
+                                            req_string = STRING_construct_sprintf(RESPONSE_BODY_FORMAT,
+                                                                                        STRING_c_str(correlationId),
+                                                                                        ((httpResponse < 300) ? "true" : "false"),
+                                                                                        httpResponse, 
+                                                                                        (response == NULL ? (const unsigned char*)"" : response));
+                                            if (req_string == NULL)
+                                            {
+                                                LogError("Failure constructing string");
+                                                result = IOTHUB_CLIENT_ERROR;
+                                            }
+                                            else
+                                            {
+                                                /*do again snprintf*/
+                                                BUFFER_HANDLE toBeTransmitted = NULL;
+                                                size_t req_string_len = STRING_length(req_string);
+                                                const char* required_string = STRING_c_str(req_string);
+                                                if ((toBeTransmitted = BUFFER_create((const unsigned char*)required_string, req_string_len)) == NULL)
+                                                {
+                                                    LogError("unable to BUFFER_create");
+                                                    result = IOTHUB_CLIENT_ERROR;
+                                                }
+                                                else
+                                                {
+                                                    if (IoTHubClient_LL_UploadToBlob_step3(upload_data, iotHubHttpApiExHandle, requestHttpHeaders, toBeTransmitted) != 0)
+                                                    {
+                                                        LogError("IoTHubClient_LL_UploadToBlob_step3 failed");
+                                                        result = IOTHUB_CLIENT_ERROR;
+                                                    }
+                                                    else
+                                                    {
+                                                        result = (httpResponse < 300) ? IOTHUB_CLIENT_OK : IOTHUB_CLIENT_ERROR;
+                                                    }
+                                                    BUFFER_delete(toBeTransmitted);
+                                                }
+                                                STRING_delete(req_string);
+                                            }
+                                        }
+                                        BUFFER_delete(responseToIoTHub);
+                                    }
+                                }
+                                HTTPHeaders_Free(requestHttpHeaders);
+                            }
+                            STRING_delete(sasUri);
+                            STRING_delete(correlationId);
+                        }
+                    }
+                }
+            }
+            HTTPAPIEX_Destroy(iotHubHttpApiExHandle);
+        }
+
+        /*Codes_SRS_IOTHUBCLIENT_LL_99_003: [ If `IoTHubClient_LL_UploadMultipleBlocksToBlob(Ex)` return `IOTHUB_CLIENT_OK`, it shall call `getDataCallbackEx` with `result` set to `FILE_UPLOAD_OK`, and `data` and `size` set to NULL. ]*/
+        /*Codes_SRS_IOTHUBCLIENT_LL_99_004: [ If `IoTHubClient_LL_UploadMultipleBlocksToBlob(Ex)` does not return `IOTHUB_CLIENT_OK`, it shall call `getDataCallbackEx` with `result` set to `FILE_UPLOAD_ERROR`, and `data` and `size` set to NULL. ]*/
+        (void)getDataCallbackEx(result == IOTHUB_CLIENT_OK ? FILE_UPLOAD_OK : FILE_UPLOAD_ERROR, NULL, NULL, context);
+    }
+    return result;
+}
+
+IOTHUB_CLIENT_RESULT IoTHubClient_LL_UploadToBlob_Impl(IOTHUB_CLIENT_LL_UPLOADTOBLOB_HANDLE handle, const char* destinationFileName, const unsigned char* source, size_t size)
+{
+    IOTHUB_CLIENT_RESULT result;
+
+    if (handle == NULL || destinationFileName == NULL)
+    {
+        LogError("Invalid parameter handle:%p destinationFileName:%p", handle, destinationFileName);
+        result = IOTHUB_CLIENT_INVALID_ARG;
+    }
+    /*Codes_SRS_IOTHUBCLIENT_LL_02_063: [ If source is NULL and size is greater than 0 then IoTHubClient_LL_UploadToBlob shall fail and return IOTHUB_CLIENT_INVALID_ARG. ]*/
+    else if (source == NULL && size > 0)
+    {
+        LogError("Invalid source and size combination: source=%p size=%lu", source, (unsigned long)size);
+        result = IOTHUB_CLIENT_INVALID_ARG;
+    }
+    else
+    {
+        /*Codes_SRS_IOTHUBCLIENT_LL_99_001: [ `IoTHubClient_LL_UploadToBlob` shall create a struct containing the `source`, the `size`, and the remaining size to upload.]*/
+        BLOB_UPLOAD_CONTEXT context;
+        context.blobSource = source;
+        context.blobSourceSize = size;
+        context.remainingSizeToUpload = size;
+
+        /*Codes_SRS_IOTHUBCLIENT_LL_99_002: [ `IoTHubClient_LL_UploadToBlob` shall call `IoTHubClient_LL_UploadMultipleBlocksToBlob_Impl` with `FileUpload_GetData_Callback` as `getDataCallbackEx` and pass the struct created at step SRS_IOTHUBCLIENT_LL_99_001 as `context` ]*/
+        result = IoTHubClient_LL_UploadMultipleBlocksToBlob_Impl(handle, destinationFileName, FileUpload_GetData_Callback, &context);
+    }
+    return result;
+}
+
+void IoTHubClient_LL_UploadToBlob_Destroy(IOTHUB_CLIENT_LL_UPLOADTOBLOB_HANDLE handle)
+{
+    if (handle == NULL)
+    {
+        LogError("unexpected NULL argument");
+    }
+    else
+    {
+        IOTHUB_CLIENT_LL_UPLOADTOBLOB_HANDLE_DATA* upload_data = (IOTHUB_CLIENT_LL_UPLOADTOBLOB_HANDLE_DATA*)handle;
+
+        if (upload_data->cred_type == IOTHUB_CREDENTIAL_TYPE_X509 || upload_data->cred_type == IOTHUB_CREDENTIAL_TYPE_X509_ECC)
+        {
+            free(upload_data->credentials.x509_credentials.x509certificate);
+            free(upload_data->credentials.x509_credentials.x509privatekey);
+        }
+        else if (upload_data->cred_type == IOTHUB_CREDENTIAL_TYPE_SAS_TOKEN)
+        {
+            free(upload_data->credentials.supplied_sas_token);
+        }
+
+        free((void*)upload_data->hostname);
+        if (upload_data->certificates != NULL)
+        {
+            free(upload_data->certificates);
+        }
+        if (upload_data->http_proxy_options.host_address != NULL)
+        {
+            free((char *)upload_data->http_proxy_options.host_address);
+        }
+        if (upload_data->http_proxy_options.username != NULL)
+        {
+            free((char *)upload_data->http_proxy_options.username);
+        }
+        if (upload_data->http_proxy_options.password != NULL)
+        {
+            free((char *)upload_data->http_proxy_options.password);
+        }
+        free(upload_data);
+    }
+}
+
+IOTHUB_CLIENT_RESULT IoTHubClient_LL_UploadToBlob_SetOption(IOTHUB_CLIENT_LL_UPLOADTOBLOB_HANDLE handle, const char* optionName, const void* value)
+{
+    IOTHUB_CLIENT_RESULT result;
+    /*Codes_SRS_IOTHUBCLIENT_LL_02_110: [ If parameter handle is NULL then IoTHubClient_LL_UploadToBlob_SetOption shall fail and return IOTHUB_CLIENT_ERROR. ]*/
+    if (handle == NULL)
+    {
+        LogError("invalid argument detected: IOTHUB_CLIENT_LL_UPLOADTOBLOB_HANDLE handle=%p, const char* optionName=%s, const void* value=%p", handle, optionName, value);
+        result = IOTHUB_CLIENT_ERROR;
+    }
+    else
+    {
+        IOTHUB_CLIENT_LL_UPLOADTOBLOB_HANDLE_DATA* upload_data = (IOTHUB_CLIENT_LL_UPLOADTOBLOB_HANDLE_DATA*)handle;
+
+        /*Codes_SRS_IOTHUBCLIENT_LL_02_100: [ x509certificate - then value then is a null terminated string that contains the x509 certificate. ]*/
+        if (strcmp(optionName, OPTION_X509_CERT) == 0)
+        {
+            /*Codes_SRS_IOTHUBCLIENT_LL_02_109: [ If the authentication scheme is NOT x509 then IoTHubClient_LL_UploadToBlob_SetOption shall return IOTHUB_CLIENT_INVALID_ARG. ]*/
+            if (upload_data->cred_type != IOTHUB_CREDENTIAL_TYPE_X509)
+            {
+                LogError("trying to set a x509 certificate while the authentication scheme is not x509");
+                result = IOTHUB_CLIENT_INVALID_ARG;
+            }
+            else
+            {
+                /*Codes_SRS_IOTHUBCLIENT_LL_02_103: [ The options shall be saved. ]*/
+                /*try to make a copy of the certificate*/
+                char* temp;
+                if (mallocAndStrcpy_s(&temp, value) != 0)
+                {
+                    /*Codes_SRS_IOTHUBCLIENT_LL_02_104: [ If saving fails, then IoTHubClient_LL_UploadToBlob_SetOption shall fail and return IOTHUB_CLIENT_ERROR. ]*/
+                    LogError("unable to mallocAndStrcpy_s");
+                    result = IOTHUB_CLIENT_ERROR;
+                }
+                else
+                {
+                    /*Codes_SRS_IOTHUBCLIENT_LL_02_105: [ Otherwise IoTHubClient_LL_UploadToBlob_SetOption shall succeed and return IOTHUB_CLIENT_OK. ]*/
+                    if (upload_data->credentials.x509_credentials.x509certificate != NULL) /*free any previous values, if any*/
+                    {
+                        free(upload_data->credentials.x509_credentials.x509certificate);
+                    }
+                    upload_data->credentials.x509_credentials.x509certificate = temp;
+                    result = IOTHUB_CLIENT_OK;
+                }
+            }
+        }
+        /*Codes_SRS_IOTHUBCLIENT_LL_02_101: [ x509privatekey - then value is a null terminated string that contains the x509 privatekey. ]*/
+        else if (strcmp(optionName, OPTION_X509_PRIVATE_KEY) == 0)
+        {
+            /*Codes_SRS_IOTHUBCLIENT_LL_02_109: [ If the authentication scheme is NOT x509 then IoTHubClient_LL_UploadToBlob_SetOption shall return IOTHUB_CLIENT_INVALID_ARG. ]*/
+            if (upload_data->cred_type != IOTHUB_CREDENTIAL_TYPE_X509)
+            {
+                LogError("trying to set a x509 privatekey while the authentication scheme is not x509");
+                result = IOTHUB_CLIENT_INVALID_ARG;
+            }
+            else
+            {
+                /*Codes_SRS_IOTHUBCLIENT_LL_02_103: [ The options shall be saved. ]*/
+                /*try to make a copy of the privatekey*/
+                char* temp;
+                if (mallocAndStrcpy_s(&temp, value) != 0)
+                {
+                    /*Codes_SRS_IOTHUBCLIENT_LL_02_104: [ If saving fails, then IoTHubClient_LL_UploadToBlob_SetOption shall fail and return IOTHUB_CLIENT_ERROR. ]*/
+                    LogError("unable to mallocAndStrcpy_s");
+                    result = IOTHUB_CLIENT_ERROR;
+                }
+                else
+                {
+                    /*Codes_SRS_IOTHUBCLIENT_LL_02_105: [ Otherwise IoTHubClient_LL_UploadToBlob_SetOption shall succeed and return IOTHUB_CLIENT_OK. ]*/
+                    if (upload_data->credentials.x509_credentials.x509privatekey != NULL) /*free any previous values, if any*/
+                    {
+                        free(upload_data->credentials.x509_credentials.x509privatekey);
+                    }
+                    upload_data->credentials.x509_credentials.x509privatekey = temp;
+                    result = IOTHUB_CLIENT_OK;
+                }
+            }
+        }
+        else if (strcmp(OPTION_TRUSTED_CERT, optionName) == 0)
+        {
+            if (value == NULL)
+            {
+                LogError("NULL is a not a valid value for TrustedCerts");
+                result = IOTHUB_CLIENT_INVALID_ARG;
+            }
+            else
+            {
+                char* tempCopy;
+                if (mallocAndStrcpy_s(&tempCopy, value) != 0)
+                {
+                    LogError("failure in mallocAndStrcpy_s");
+                    result = IOTHUB_CLIENT_ERROR;
+                }
+                else
+                {
+                    if (upload_data->certificates != NULL)
+                    {
+                        free(upload_data->certificates);
+                    }
+                    upload_data->certificates = tempCopy;
+                    result = IOTHUB_CLIENT_OK;
+                }
+            }
+        }
+        /*Codes_SRS_IOTHUBCLIENT_LL_32_008: [ OPTION_HTTP_PROXY - then the value will be a pointer to HTTP_PROXY_OPTIONS structure. ]*/
+        else if (strcmp(optionName, OPTION_HTTP_PROXY) == 0)
+        {
+            HTTP_PROXY_OPTIONS* proxy_options = (HTTP_PROXY_OPTIONS *)value;
+
+            if (proxy_options->host_address == NULL)
+            {
+                /* Codes_SRS_IOTHUBCLIENT_LL_32_006: [ If `host_address` is NULL, `IoTHubClient_LL_UploadToBlob_SetOption` shall fail and return `IOTHUB_CLIENT_INVALID_ARG`. ]*/
+                LogError("NULL host_address in proxy options");
+                result = IOTHUB_CLIENT_INVALID_ARG;
+            }
+            /* Codes_SRS_IOTHUBCLIENT_LL_32_007: [ If only one of `username` and `password` is NULL, `IoTHubClient_LL_UploadToBlob_SetOption` shall fail and return `IOTHUB_CLIENT_INVALID_ARG`. ]*/
+            else if (((proxy_options->username == NULL) || (proxy_options->password == NULL)) &&
+                (proxy_options->username != proxy_options->password))
+            {
+                LogError("Only one of username and password for proxy settings was NULL");
+                result = IOTHUB_CLIENT_INVALID_ARG;
+            }
+            else
+            {
+                if (upload_data->http_proxy_options.host_address != NULL)
+                {
+                    free((char *)upload_data->http_proxy_options.host_address);
+                    upload_data->http_proxy_options.host_address = NULL;
+                }
+                if (upload_data->http_proxy_options.username != NULL)
+                {
+                    free((char *)upload_data->http_proxy_options.username);
+                    upload_data->http_proxy_options.username = NULL;
+                }
+                if (upload_data->http_proxy_options.password != NULL)
+                {
+                    free((char *)upload_data->http_proxy_options.password);
+                    upload_data->http_proxy_options.password = NULL;
+                }
+
+                upload_data->http_proxy_options.port = proxy_options->port;
+
+                if (mallocAndStrcpy_s((char **)(&upload_data->http_proxy_options.host_address), proxy_options->host_address) != 0)
+                {
+                    LogError("failure in mallocAndStrcpy_s - upload_data->http_proxy_options.host_address");
+                    result = IOTHUB_CLIENT_ERROR;
+                }
+                else if (proxy_options->username != NULL && mallocAndStrcpy_s((char **)(&upload_data->http_proxy_options.username), proxy_options->username) != 0)
+                {
+                    LogError("failure in mallocAndStrcpy_s - upload_data->http_proxy_options.username");
+                    result = IOTHUB_CLIENT_ERROR;
+                }
+                else if (proxy_options->password != NULL && mallocAndStrcpy_s((char **)(&upload_data->http_proxy_options.password), proxy_options->password) != 0)
+                {
+                    LogError("failure in mallocAndStrcpy_s - upload_data->http_proxy_options.password");
+                    result = IOTHUB_CLIENT_ERROR;
+                }
+                else
+                {
+                    result = IOTHUB_CLIENT_OK;
+                }
+            }
+        }
+        else if (strcmp(optionName, OPTION_CURL_VERBOSE) == 0)
+        {
+            upload_data->curl_verbosity_level = ((*(bool*)value) == 0) ? UPOADTOBLOB_CURL_VERBOSITY_OFF : UPOADTOBLOB_CURL_VERBOSITY_ON;
+            result = IOTHUB_CLIENT_OK;
+        }
+        else if (strcmp(optionName, OPTION_BLOB_UPLOAD_TIMEOUT_SECS) == 0)
+        {
+            upload_data->blob_upload_timeout_secs = *(size_t*)value;
+            result = IOTHUB_CLIENT_OK;
+        }
+        else
+        {
+            /*Codes_SRS_IOTHUBCLIENT_LL_02_102: [ If an unknown option is presented then IoTHubClient_LL_UploadToBlob_SetOption shall return IOTHUB_CLIENT_INVALID_ARG. ]*/
+            result = IOTHUB_CLIENT_INVALID_ARG;
+        }
+    }
+    return result;
+}
+
+#endif /*DONT_USE_UPLOADTOBLOB*/
+
+
Index: azure_iot_hub_f767zi/trunk/azure_iot_sdk/iothub_client/src/iothub_client_retry_control.c
===================================================================
--- azure_iot_hub_f767zi/trunk/azure_iot_sdk/iothub_client/src/iothub_client_retry_control.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/azure_iot_sdk/iothub_client/src/iothub_client_retry_control.c	(revision 457)
@@ -0,0 +1,544 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+#include "internal/iothub_client_retry_control.h"
+
+#include <math.h>
+
+#include "azure_c_shared_utility/gballoc.h"
+#include "azure_c_shared_utility/agenttime.h"
+#include "azure_c_shared_utility/optimize_size.h"
+#include "azure_c_shared_utility/xlogging.h"
+
+#define RESULT_OK                 0
+#define INDEFINITE_TIME           ((time_t)-1)
+#define DEFAULT_MAX_DELAY_IN_SECS 30
+
+typedef struct RETRY_CONTROL_INSTANCE_TAG
+{
+    IOTHUB_CLIENT_RETRY_POLICY policy;
+    unsigned int max_retry_time_in_secs;
+
+    unsigned int initial_wait_time_in_secs;
+    unsigned int max_jitter_percent;
+    unsigned int max_delay_in_secs;
+
+    unsigned int retry_count;
+    time_t first_retry_time;
+    time_t last_retry_time;
+    unsigned int current_wait_time_in_secs;
+} RETRY_CONTROL_INSTANCE;
+
+typedef int (*RETRY_ACTION_EVALUATION_FUNCTION)(RETRY_CONTROL_INSTANCE* retry_state, RETRY_ACTION* retry_action);
+
+
+// ========== Helper Functions ========== //
+
+// ---------- Set/Retrieve Options Helpers ----------//
+
+static void* retry_control_clone_option(const char* name, const void* value)
+{
+    void* result;
+
+    if ((name == NULL) || (value == NULL))
+    {
+        LogError("Failed to clone option (either name (%p) or value (%p) are NULL)", name, value);
+        result = NULL;
+    }
+    else if (strcmp(RETRY_CONTROL_OPTION_INITIAL_WAIT_TIME_IN_SECS, name) == 0 ||
+            strcmp(RETRY_CONTROL_OPTION_MAX_JITTER_PERCENT, name) == 0)
+    {
+        unsigned int* cloned_value;
+
+        if ((cloned_value = (unsigned int*)malloc(sizeof(unsigned int))) == NULL)
+        {
+            LogError("Failed to clone option '%p' (malloc failed)", name);
+            result = NULL;
+        }
+        else
+        {
+            *cloned_value = *(unsigned int*)value;
+
+            result = (void*)cloned_value;
+        }
+    }
+    else
+    {
+        LogError("Failed to clone option (option with name '%s' is not suppported)", name);
+        result = NULL;
+    }
+
+    return result;
+}
+
+static void retry_control_destroy_option(const char* name, const void* value)
+{
+    if ((name == NULL) || (value == NULL))
+    {
+        LogError("Failed to destroy option (either name (%p) or value (%p) are NULL)", name, value);
+    }
+    else if (strcmp(RETRY_CONTROL_OPTION_INITIAL_WAIT_TIME_IN_SECS, name) == 0 ||
+        strcmp(RETRY_CONTROL_OPTION_MAX_JITTER_PERCENT, name) == 0)
+    {
+        free((void*)value);
+    }
+    else
+    {
+        LogError("Failed to destroy option (option with name '%s' is not suppported)", name);
+    }
+}
+
+// ========== _should_retry() Auxiliary Functions ========== //
+
+static int evaluate_retry_action(RETRY_CONTROL_INSTANCE* retry_control, RETRY_ACTION* retry_action)
+{
+    int result;
+
+    // Codes_SRS_IOTHUB_CLIENT_RETRY_CONTROL_09_019: [If `retry_control->retry_count` is 0, `retry_action` shall be set to RETRY_ACTION_RETRY_NOW]
+    if (retry_control->retry_count == 0)
+    {
+        *retry_action = RETRY_ACTION_RETRY_NOW;
+        result = RESULT_OK;
+    }
+    // Codes_SRS_IOTHUB_CLIENT_RETRY_CONTROL_09_020: [If `retry_control->last_retry_time` is INDEFINITE_TIME and policy is not IOTHUB_CLIENT_RETRY_IMMEDIATE, the evaluation function shall return non-zero]
+    else if (retry_control->last_retry_time == INDEFINITE_TIME &&
+             retry_control->policy != IOTHUB_CLIENT_RETRY_IMMEDIATE)
+    {
+        LogError("Failed to evaluate retry action (last_retry_time is INDEFINITE_TIME)");
+        result = MU_FAILURE;
+    }
+    else
+    {
+        time_t current_time;
+
+        // Codes_SRS_IOTHUB_CLIENT_RETRY_CONTROL_09_021: [`current_time` shall be set using get_time()]
+        if ((current_time = get_time(NULL)) == INDEFINITE_TIME)
+        {
+            // Codes_SRS_IOTHUB_CLIENT_RETRY_CONTROL_09_022: [If get_time() fails, the evaluation function shall return non-zero]
+            LogError("Failed to evaluate retry action (get_time() failed)");
+            result = MU_FAILURE;
+        }
+        // Codes_SRS_IOTHUB_CLIENT_RETRY_CONTROL_09_023: [If `retry_control->max_retry_time_in_secs` is not 0 and (`current_time` - `retry_control->first_retry_time`) is greater than or equal to `retry_control->max_retry_time_in_secs`, `retry_action` shall be set to RETRY_ACTION_STOP_RETRYING]
+        else if (retry_control->max_retry_time_in_secs > 0 &&
+            get_difftime(current_time, retry_control->first_retry_time) >= retry_control->max_retry_time_in_secs)
+        {
+            *retry_action = RETRY_ACTION_STOP_RETRYING;
+
+            // Codes_SRS_IOTHUB_CLIENT_RETRY_CONTROL_09_026: [If no errors occur, the evaluation function shall return 0]
+            result = RESULT_OK;
+        }
+        // Codes_SRS_IOTHUB_CLIENT_RETRY_CONTROL_09_028: [If `retry_control->policy` is IOTHUB_CLIENT_RETRY_IMMEDIATE, retry_action shall be set to RETRY_ACTION_RETRY_NOW]
+        else if (retry_control->policy == IOTHUB_CLIENT_RETRY_IMMEDIATE)
+        {
+            *retry_action = RETRY_ACTION_RETRY_NOW;
+
+            // Codes_SRS_IOTHUB_CLIENT_RETRY_CONTROL_09_026: [If no errors occur, the evaluation function shall return 0]
+            result = RESULT_OK;
+        }
+        // Codes_SRS_IOTHUB_CLIENT_RETRY_CONTROL_09_024: [Otherwise, if (`current_time` - `retry_control->last_retry_time`) is less than `retry_control->current_wait_time_in_secs`, `retry_action` shall be set to RETRY_ACTION_RETRY_LATER]
+        else if (get_difftime(current_time, retry_control->last_retry_time) < retry_control->current_wait_time_in_secs)
+        {
+            *retry_action = RETRY_ACTION_RETRY_LATER;
+
+            // Codes_SRS_IOTHUB_CLIENT_RETRY_CONTROL_09_026: [If no errors occur, the evaluation function shall return 0]
+            result = RESULT_OK;
+        }
+        // Codes_SRS_IOTHUB_CLIENT_RETRY_CONTROL_09_025: [Otherwise, if (`current_time` - `retry_control->last_retry_time`) is greater or equal to `retry_control->current_wait_time_in_secs`, `retry_action` shall be set to RETRY_ACTION_RETRY_NOW]
+        else
+        {
+            *retry_action = RETRY_ACTION_RETRY_NOW;
+
+            // Codes_SRS_IOTHUB_CLIENT_RETRY_CONTROL_09_026: [If no errors occur, the evaluation function shall return 0]
+            result = RESULT_OK;
+        }
+    }
+
+    return result;
+}
+
+static unsigned int calculate_next_wait_time(RETRY_CONTROL_INSTANCE* retry_control)
+{
+    unsigned int result;
+
+    // Codes_SRS_IOTHUB_CLIENT_RETRY_CONTROL_09_029: [If `retry_control->policy` is IOTHUB_CLIENT_RETRY_INTERVAL, `calculate_next_wait_time` shall return `retry_control->initial_wait_time_in_secs`]
+    if (retry_control->policy == IOTHUB_CLIENT_RETRY_INTERVAL)
+    {
+        result = retry_control->initial_wait_time_in_secs;
+    }
+    // Codes_SRS_IOTHUB_CLIENT_RETRY_CONTROL_09_030: [If `retry_control->policy` is IOTHUB_CLIENT_RETRY_LINEAR_BACKOFF, `calculate_next_wait_time` shall return (`retry_control->initial_wait_time_in_secs` * (`retry_control->retry_count`))]
+    else if (retry_control->policy == IOTHUB_CLIENT_RETRY_LINEAR_BACKOFF)
+    {
+        unsigned int base_delay = retry_control->initial_wait_time_in_secs * (retry_control->retry_count);
+
+        if (base_delay > retry_control->max_delay_in_secs) 
+        {
+            base_delay = retry_control->max_delay_in_secs;
+        }        
+        
+        result = base_delay;
+    }
+    // Codes_SRS_IOTHUB_CLIENT_RETRY_CONTROL_09_031: [If `retry_control->policy` is IOTHUB_CLIENT_RETRY_EXPONENTIAL_BACKOFF, `calculate_next_wait_time` shall return (pow(2, `retry_control->retry_count` - 1) * `retry_control->initial_wait_time_in_secs`)]
+    else if (retry_control->policy == IOTHUB_CLIENT_RETRY_EXPONENTIAL_BACKOFF)
+    {
+        double base_delay = pow(2, retry_control->retry_count - 1) * retry_control->initial_wait_time_in_secs;
+
+        if (base_delay > retry_control->max_delay_in_secs) 
+        {
+            base_delay = retry_control->max_delay_in_secs;
+        }
+
+        result = (unsigned int)base_delay;
+    }
+    // Codes_SRS_IOTHUB_CLIENT_RETRY_CONTROL_09_032: [If `retry_control->policy` is IOTHUB_CLIENT_RETRY_EXPONENTIAL_BACKOFF_WITH_JITTER, `calculate_next_wait_time` shall return ((pow(2, `retry_control->retry_count` - 1) * `retry_control->initial_wait_time_in_secs`) * (1 + (`retry_control->max_jitter_percent` / 100) * (rand() / RAND_MAX)))]
+    else if (retry_control->policy == IOTHUB_CLIENT_RETRY_EXPONENTIAL_BACKOFF_WITH_JITTER)
+    {
+        double jitter_percent = (retry_control->max_jitter_percent / 100.0) * (rand() / ((double)RAND_MAX));
+
+        double base_delay = pow(2, retry_control->retry_count - 1) * retry_control->initial_wait_time_in_secs;
+
+        if (base_delay > retry_control->max_delay_in_secs) 
+        {
+            base_delay = retry_control->max_delay_in_secs;
+        }
+
+        result =  (unsigned int)(base_delay * (1 + jitter_percent));
+    }
+    // Codes_SRS_IOTHUB_CLIENT_RETRY_CONTROL_09_033: [If `retry_control->policy` is IOTHUB_CLIENT_RETRY_RANDOM, `calculate_next_wait_time` shall return (`retry_control->initial_wait_time_in_secs` * (rand() / RAND_MAX))]
+    else if (retry_control->policy == IOTHUB_CLIENT_RETRY_RANDOM)
+    {
+        double random_percent = ((double)rand() / (double)RAND_MAX);
+        result = (unsigned int)(retry_control->initial_wait_time_in_secs * random_percent);
+    }
+    else
+    {
+        LogError("Failed to calculate the next wait time (policy %d is not expected)", retry_control->policy);
+
+        result = 0;
+    }
+
+    return result;
+}
+
+
+// ========== Public API ========== //
+
+int is_timeout_reached(time_t start_time, unsigned int timeout_in_secs, bool* is_timed_out)
+{
+    int result;
+
+    // Codes_SRS_IOTHUB_CLIENT_RETRY_CONTROL_09_057: [If `start_time` is INDEFINITE_TIME, `is_timeout_reached` shall fail and return non-zero]
+    if (start_time == INDEFINITE_TIME)
+    {
+        LogError("Failed to verify timeout (start_time is INDEFINITE)");
+        result = MU_FAILURE;
+    }
+    // Codes_SRS_IOTHUB_CLIENT_RETRY_CONTROL_09_058: [If `is_timed_out` is NULL, `is_timeout_reached` shall fail and return non-zero]
+    else if (is_timed_out == NULL)
+    {
+        LogError("Failed to verify timeout (is_timed_out is NULL)");
+        result = MU_FAILURE;
+    }
+    else
+    {
+        time_t current_time;
+
+        // Codes_SRS_IOTHUB_CLIENT_RETRY_CONTROL_09_059: [`is_timeout_reached` shall obtain the `current_time` using get_time()]
+        if ((current_time = get_time(NULL)) == INDEFINITE_TIME)
+        {
+            // Codes_SRS_IOTHUB_CLIENT_RETRY_CONTROL_09_060: [If get_time() fails, `is_timeout_reached` shall fail and return non-zero]
+            LogError("Failed to verify timeout (get_time failed)");
+            result = MU_FAILURE;
+        }
+        else
+        {
+            // Codes_SRS_IOTHUB_CLIENT_RETRY_CONTROL_09_061: [If (`current_time` - `start_time`) is greater or equal to `timeout_in_secs`, `is_timed_out` shall be set to true]
+            if (get_difftime(current_time, start_time) >= timeout_in_secs)
+            {
+                *is_timed_out = true;
+            }
+            // Codes_SRS_IOTHUB_CLIENT_RETRY_CONTROL_09_062: [If (`current_time` - `start_time`) is less than `timeout_in_secs`, `is_timed_out` shall be set to false]
+            else
+            {
+                *is_timed_out = false;
+            }
+
+            // Codes_SRS_IOTHUB_CLIENT_RETRY_CONTROL_09_063: [If no errors occur, `is_timeout_reached` shall return 0]
+            result = RESULT_OK;
+        }
+    }
+
+    return result;
+}
+
+void retry_control_reset(RETRY_CONTROL_HANDLE retry_control_handle)
+{
+    // Codes_SRS_IOTHUB_CLIENT_RETRY_CONTROL_09_034: [If `retry_control_handle` is NULL, `retry_control_reset` shall return]
+    if (retry_control_handle == NULL)
+    {
+        LogError("Failed to reset the retry control (retry_state_handle is NULL)");
+    }
+    else
+    {
+        RETRY_CONTROL_INSTANCE* retry_control = (RETRY_CONTROL_INSTANCE*)retry_control_handle;
+
+        // Codes_SRS_IOTHUB_CLIENT_RETRY_CONTROL_09_035: [`retry_control` shall have fields `retry_count` and `current_wait_time_in_secs` set to 0 (zero), `first_retry_time` and `last_retry_time` set to INDEFINITE_TIME]
+        retry_control->retry_count = 0;
+        retry_control->current_wait_time_in_secs = 0;
+        retry_control->first_retry_time = INDEFINITE_TIME;
+        retry_control->last_retry_time = INDEFINITE_TIME;
+    }
+}
+
+RETRY_CONTROL_HANDLE retry_control_create(IOTHUB_CLIENT_RETRY_POLICY policy, unsigned int max_retry_time_in_secs)
+{
+    RETRY_CONTROL_INSTANCE* retry_control;
+
+    // Codes_SRS_IOTHUB_CLIENT_RETRY_CONTROL_09_002: [`retry_control_create` shall allocate memory for the retry control instance structure (a.k.a. `retry_control`)]
+    if ((retry_control = (RETRY_CONTROL_INSTANCE*)malloc(sizeof(RETRY_CONTROL_INSTANCE))) == NULL)
+    {
+        // Codes_SRS_IOTHUB_CLIENT_RETRY_CONTROL_09_003: [If malloc fails, `retry_control_create` shall fail and return NULL]
+        LogError("Failed creating the retry control (malloc failed)");
+    }
+    else
+    {
+        // Codes_SRS_IOTHUB_CLIENT_RETRY_CONTROL_09_004: [The parameters passed to `retry_control_create` shall be saved into `retry_control`]
+        memset(retry_control, 0, sizeof(RETRY_CONTROL_INSTANCE));
+        retry_control->policy = policy;
+        retry_control->max_retry_time_in_secs = max_retry_time_in_secs;
+
+        // Codes_SRS_IOTHUB_CLIENT_RETRY_CONTROL_09_005: [If `policy` is IOTHUB_CLIENT_RETRY_EXPONENTIAL_BACKOFF or IOTHUB_CLIENT_RETRY_EXPONENTIAL_BACKOFF_WITH_JITTER, `retry_control->initial_wait_time_in_secs` shall be set to 1]
+        if (retry_control->policy == IOTHUB_CLIENT_RETRY_EXPONENTIAL_BACKOFF ||
+            retry_control->policy == IOTHUB_CLIENT_RETRY_EXPONENTIAL_BACKOFF_WITH_JITTER)
+        {
+            retry_control->initial_wait_time_in_secs = 1;
+        }
+        // Codes_SRS_IOTHUB_CLIENT_RETRY_CONTROL_09_006: [Otherwise `retry_control->initial_wait_time_in_secs` shall be set to 5]
+        else
+        {
+            retry_control->initial_wait_time_in_secs = 5;
+        }
+
+        // Codes_SRS_IOTHUB_CLIENT_RETRY_CONTROL_09_007: [`retry_control->max_jitter_percent` shall be set to 5]
+        retry_control->max_jitter_percent = 5;
+        retry_control->max_delay_in_secs = DEFAULT_MAX_DELAY_IN_SECS;
+
+        // Codes_SRS_IOTHUB_CLIENT_RETRY_CONTROL_09_008: [The remaining fields in `retry_control` shall be initialized according to retry_control_reset()]
+        retry_control_reset(retry_control);
+    }
+
+    // Codes_SRS_IOTHUB_CLIENT_RETRY_CONTROL_09_009: [If no errors occur, `retry_control_create` shall return a handle to `retry_control`]
+    return (RETRY_CONTROL_HANDLE)retry_control;
+}
+
+void retry_control_destroy(RETRY_CONTROL_HANDLE retry_control_handle)
+{
+    // Codes_SRS_IOTHUB_CLIENT_RETRY_CONTROL_09_055: [If `retry_control_handle` is NULL, `retry_control_destroy` shall return]
+    if (retry_control_handle == NULL)
+    {
+        LogError("Failed to destroy the retry control (retry_control_handle is NULL)");
+    }
+    else
+    {
+        // Codes_SRS_IOTHUB_CLIENT_RETRY_CONTROL_09_056: [`retry_control_destroy` shall destroy `retry_control_handle` using free()]
+        free(retry_control_handle);
+    }
+}
+
+int retry_control_should_retry(RETRY_CONTROL_HANDLE retry_control_handle, RETRY_ACTION* retry_action)
+{
+    int result;
+
+    // Codes_SRS_IOTHUB_CLIENT_RETRY_CONTROL_09_010: [If `retry_control_handle` or `retry_action` are NULL, `retry_control_should_retry` shall fail and return non-zero]
+    if ((retry_control_handle == NULL) || (retry_action == NULL))
+    {
+        LogError("Failed to evaluate if retry should be attempted (either retry_control_handle (%p) or retry_action (%p) are NULL)", retry_control_handle, retry_action);
+        result = MU_FAILURE;
+    }
+    else
+    {
+        RETRY_CONTROL_INSTANCE* retry_control = (RETRY_CONTROL_INSTANCE*)retry_control_handle;
+
+        // Codes_SRS_IOTHUB_CLIENT_RETRY_CONTROL_09_027: [If `retry_control->policy` is IOTHUB_CLIENT_RETRY_NONE, retry_action shall be set to RETRY_ACTION_STOP_RETRYING and return immediatelly with result 0]
+        if (retry_control->policy == IOTHUB_CLIENT_RETRY_NONE)
+        {
+            *retry_action = RETRY_ACTION_STOP_RETRYING;
+            result = RESULT_OK;
+        }
+        // Codes_SRS_IOTHUB_CLIENT_RETRY_CONTROL_09_011: [If `retry_control->first_retry_time` is INDEFINITE_TIME, it shall be set using get_time()]
+        else if (retry_control->first_retry_time == INDEFINITE_TIME && (retry_control->first_retry_time = get_time(NULL)) == INDEFINITE_TIME)
+        {
+            // Codes_SRS_IOTHUB_CLIENT_RETRY_CONTROL_09_012: [If get_time() fails, `retry_control_should_retry` shall fail and return non-zero]
+            LogError("Failed to evaluate if retry should be attempted (get_time() failed)");
+            result = MU_FAILURE;
+        }
+        // Codes_SRS_IOTHUB_CLIENT_RETRY_CONTROL_09_013: [evaluate_retry_action() shall be invoked]
+        else if (evaluate_retry_action(retry_control, retry_action) != RESULT_OK)
+        {
+            // Codes_SRS_IOTHUB_CLIENT_RETRY_CONTROL_09_014: [If evaluate_retry_action() fails, `retry_control_should_retry` shall fail and return non-zero]
+            LogError("Failed to evaluate if retry should be attempted (evaluate_retry_action() failed)");
+            result = MU_FAILURE;
+        }
+        else
+        {
+            if (*retry_action == RETRY_ACTION_RETRY_NOW)
+            {
+                // Codes_SRS_IOTHUB_CLIENT_RETRY_CONTROL_09_015: [If `retry_action` is set to RETRY_ACTION_RETRY_NOW, `retry_control->retry_count` shall be incremented by 1]
+                retry_control->retry_count++;
+
+                if (retry_control->policy != IOTHUB_CLIENT_RETRY_IMMEDIATE)
+                {
+                    // Codes_SRS_IOTHUB_CLIENT_RETRY_CONTROL_09_016: [If `retry_action` is set to RETRY_ACTION_RETRY_NOW and policy is not IOTHUB_CLIENT_RETRY_IMMEDIATE, `retry_control->last_retry_time` shall be set using get_time()]
+                    retry_control->last_retry_time = get_time(NULL);
+
+                    // Codes_SRS_IOTHUB_CLIENT_RETRY_CONTROL_09_017: [If `retry_action` is set to RETRY_ACTION_RETRY_NOW and policy is not IOTHUB_CLIENT_RETRY_IMMEDIATE, `retry_control->current_wait_time_in_secs` shall be set using calculate_next_wait_time()]
+                    retry_control->current_wait_time_in_secs = calculate_next_wait_time(retry_control);
+                }
+            }
+
+            // Codes_SRS_IOTHUB_CLIENT_RETRY_CONTROL_09_018: [If no errors occur, `retry_control_should_retry` shall return 0]
+            result = RESULT_OK;
+        }
+    }
+
+    return result;
+}
+
+int retry_control_set_option(RETRY_CONTROL_HANDLE retry_control_handle, const char* name, const void* value)
+{
+    int result;
+
+    // Codes_SRS_IOTHUB_CLIENT_RETRY_CONTROL_09_036: [If `retry_control_handle`, `name` or `value` are NULL, `retry_control_set_option` shall fail and return non-zero]
+    if (retry_control_handle == NULL || name == NULL || value == NULL)
+    {
+        LogError("Failed to set option (either retry_state_handle (%p), name (%p) or value (%p) are NULL)", retry_control_handle, name, value);
+        result = MU_FAILURE;
+    }
+    else
+    {
+        RETRY_CONTROL_INSTANCE* retry_control = (RETRY_CONTROL_INSTANCE*)retry_control_handle;
+
+        if (strcmp(RETRY_CONTROL_OPTION_INITIAL_WAIT_TIME_IN_SECS, name) == 0)
+        {
+            unsigned int cast_value = *((unsigned int*)value);
+
+            // Codes_SRS_IOTHUB_CLIENT_RETRY_CONTROL_09_037: [If `name` is "initial_wait_time_in_secs" and `value` is less than 1, `retry_control_set_option` shall fail and return non-zero]
+            if (cast_value < 1)
+            {
+                LogError("Failed to set option '%s' (value must be equal or greater to 1)", name);
+                result = MU_FAILURE;
+            }
+            else
+            {
+                // Codes_SRS_IOTHUB_CLIENT_RETRY_CONTROL_09_038: [If `name` is "initial_wait_time_in_secs", `value` shall be saved on `retry_control->initial_wait_time_in_secs`]
+                retry_control->initial_wait_time_in_secs = cast_value;
+
+                // Codes_SRS_IOTHUB_CLIENT_RETRY_CONTROL_09_044: [If no errors occur, retry_control_set_option shall return 0]
+                result = RESULT_OK;
+            }
+        }
+        else if (strcmp(RETRY_CONTROL_OPTION_MAX_JITTER_PERCENT, name) == 0)
+        {
+            unsigned int cast_value = *((unsigned int*)value);
+
+            // Codes_SRS_IOTHUB_CLIENT_RETRY_CONTROL_09_039: [If `name` is "max_jitter_percent" and `value` is less than 0 or greater than 100, `retry_control_set_option` shall fail and return non-zero]
+            if (cast_value > 100) // it's unsigned int, it doesn't need to be checked for less than zero.
+            {
+                LogError("Failed to set option '%s' (value must be in the range 0 to 100)", name);
+                result = MU_FAILURE;
+            }
+            else
+            {
+                // Codes_SRS_IOTHUB_CLIENT_RETRY_CONTROL_09_040: [If `name` is "max_jitter_percent", value shall be saved on `retry_control->max_jitter_percent`]
+                retry_control->max_jitter_percent = cast_value;
+
+                // Codes_SRS_IOTHUB_CLIENT_RETRY_CONTROL_09_044: [If no errors occur, retry_control_set_option shall return 0]
+                result = RESULT_OK;
+            }
+        }
+        else if (strcmp(RETRY_CONTROL_OPTION_MAX_DELAY_IN_SECS, name) == 0)
+        {
+            retry_control->max_delay_in_secs = *((unsigned int*)value);
+
+            result = RESULT_OK;
+        }
+        else if (strcmp(RETRY_CONTROL_OPTION_SAVED_OPTIONS, name) == 0)
+        {
+            // Codes_SRS_IOTHUB_CLIENT_RETRY_CONTROL_09_041: [If `name` is "retry_control_options", value shall be fed to `retry_control` using OptionHandler_FeedOptions]
+            if (OptionHandler_FeedOptions((OPTIONHANDLER_HANDLE)value, retry_control_handle) != OPTIONHANDLER_OK)
+            {
+                // Codes_SRS_IOTHUB_CLIENT_RETRY_CONTROL_09_042: [If OptionHandler_FeedOptions fails, `retry_control_set_option` shall fail and return non-zero]
+                LogError("messenger_set_option failed (OptionHandler_FeedOptions failed)");
+                result = MU_FAILURE;
+            }
+            else
+            {
+                // Codes_SRS_IOTHUB_CLIENT_RETRY_CONTROL_09_044: [If no errors occur, `retry_control_set_option` shall return 0]
+                result = RESULT_OK;
+            }
+        }
+        // Codes_SRS_IOTHUB_CLIENT_RETRY_CONTROL_09_043: [If `name` is not a supported option, `retry_control_set_option` shall fail and return non-zero]
+        else
+        {
+            LogError("messenger_set_option failed (option with name '%s' is not suppported)", name);
+            result = MU_FAILURE;
+        }
+    }
+
+    return result;
+}
+
+OPTIONHANDLER_HANDLE retry_control_retrieve_options(RETRY_CONTROL_HANDLE retry_control_handle)
+{
+    OPTIONHANDLER_HANDLE result;
+
+    // Codes_SRS_IOTHUB_CLIENT_RETRY_CONTROL_09_045: [If `retry_control_handle`, `retry_control_retrieve_options` shall fail and return NULL]
+    if (retry_control_handle == NULL)
+    {
+        LogError("Failed to retrieve options (retry_state_handle is NULL)");
+        result = NULL;
+    }
+    else
+    {
+        // Codes_SRS_IOTHUB_CLIENT_RETRY_CONTROL_09_046: [An instance of OPTIONHANDLER_HANDLE (a.k.a. `options`) shall be created using OptionHandler_Create]
+        OPTIONHANDLER_HANDLE options = OptionHandler_Create(retry_control_clone_option, retry_control_destroy_option, (pfSetOption)retry_control_set_option);
+
+        if (options == NULL)
+        {
+            // Codes_SRS_IOTHUB_CLIENT_RETRY_CONTROL_09_047: [If OptionHandler_Create fails, `retry_control_retrieve_options` shall fail and return NULL]
+            LogError("Failed to retrieve options (OptionHandler_Create failed)");
+            result = NULL;
+        }
+        else
+        {
+            RETRY_CONTROL_INSTANCE* retry_control = (RETRY_CONTROL_INSTANCE*)retry_control_handle;
+
+            // Codes_SRS_IOTHUB_CLIENT_RETRY_CONTROL_09_050: [`retry_control->initial_wait_time_in_secs` shall be added to `options` using OptionHandler_Add]
+            if (OptionHandler_AddOption(options, RETRY_CONTROL_OPTION_INITIAL_WAIT_TIME_IN_SECS, (void*)&retry_control->initial_wait_time_in_secs) != OPTIONHANDLER_OK)
+            {
+                // Codes_SRS_IOTHUB_CLIENT_RETRY_CONTROL_09_052: [If any call to OptionHandler_Add fails, `retry_control_retrieve_options` shall fail and return NULL]
+                LogError("Failed to retrieve options (OptionHandler_Create failed for option '%s')", RETRY_CONTROL_OPTION_INITIAL_WAIT_TIME_IN_SECS);
+                result = NULL;
+            }
+            // Codes_SRS_IOTHUB_CLIENT_RETRY_CONTROL_09_051: [`retry_control->max_jitter_percent` shall be added to `options` using OptionHandler_Add]
+            else if (OptionHandler_AddOption(options, RETRY_CONTROL_OPTION_MAX_JITTER_PERCENT, (void*)&retry_control->max_jitter_percent) != OPTIONHANDLER_OK)
+            {
+                // Codes_SRS_IOTHUB_CLIENT_RETRY_CONTROL_09_052: [If any call to OptionHandler_Add fails, `retry_control_retrieve_options` shall fail and return NULL]
+                LogError("Failed to retrieve options (OptionHandler_Create failed for option '%s')", RETRY_CONTROL_OPTION_INITIAL_WAIT_TIME_IN_SECS);
+                result = NULL;
+            }
+            else
+            {
+                // Codes_SRS_IOTHUB_CLIENT_RETRY_CONTROL_09_054: [If no errors occur, `retry_control_retrieve_options` shall return the OPTIONHANDLER_HANDLE instance]
+                result = options;
+            }
+
+            if (result == NULL)
+            {
+                // Codes_SRS_IOTHUB_CLIENT_RETRY_CONTROL_09_053: [If any failures occur, `retry_control_retrieve_options` shall release any memory it has allocated]
+                OptionHandler_Destroy(options);
+            }
+        }
+    }
+
+    return result;
+}
Index: azure_iot_hub_f767zi/trunk/azure_iot_sdk/iothub_client/src/iothub_device_client_ll.c
===================================================================
--- azure_iot_hub_f767zi/trunk/azure_iot_sdk/iothub_client/src/iothub_device_client_ll.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/azure_iot_sdk/iothub_client/src/iothub_device_client_ll.c	(revision 457)
@@ -0,0 +1,135 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+#include <stdlib.h>
+#include <string.h>
+#include "azure_c_shared_utility/optimize_size.h"
+#include "azure_c_shared_utility/gballoc.h"
+#include "azure_c_shared_utility/string_tokenizer.h"
+#include "azure_c_shared_utility/doublylinkedlist.h"
+#include "azure_c_shared_utility/xlogging.h"
+#include "azure_c_shared_utility/tickcounter.h"
+#include "azure_c_shared_utility/constbuffer.h"
+#include "azure_c_shared_utility/platform.h"
+
+#include "iothub_client_core_ll.h"
+#include "internal/iothub_client_authorization.h"
+#include "iothub_device_client_ll.h"
+#include "iothub_transport_ll.h"
+#include "internal/iothub_client_private.h"
+#include "iothub_client_options.h"
+#include "iothub_client_version.h"
+#include "internal/iothub_client_diagnostic.h"
+#include <stdint.h>
+
+#ifndef DONT_USE_UPLOADTOBLOB
+#include "internal/iothub_client_ll_uploadtoblob.h"
+#endif
+
+IOTHUB_DEVICE_CLIENT_LL_HANDLE IoTHubDeviceClient_LL_CreateFromConnectionString(const char* connectionString, IOTHUB_CLIENT_TRANSPORT_PROVIDER protocol)
+{
+    return (IOTHUB_DEVICE_CLIENT_LL_HANDLE)IoTHubClientCore_LL_CreateFromConnectionString(connectionString, protocol);
+}
+
+IOTHUB_DEVICE_CLIENT_LL_HANDLE IoTHubDeviceClient_LL_Create(const IOTHUB_CLIENT_CONFIG* config)
+{
+    return (IOTHUB_DEVICE_CLIENT_LL_HANDLE)IoTHubClientCore_LL_Create(config);
+}
+
+IOTHUB_DEVICE_CLIENT_LL_HANDLE IoTHubDeviceClient_LL_CreateWithTransport(const IOTHUB_CLIENT_DEVICE_CONFIG * config)
+{
+    return (IOTHUB_DEVICE_CLIENT_LL_HANDLE)IoTHubClientCore_LL_CreateWithTransport(config);
+}
+
+IOTHUB_DEVICE_CLIENT_LL_HANDLE IoTHubDeviceClient_LL_CreateFromDeviceAuth(const char* iothub_uri, const char* device_id, IOTHUB_CLIENT_TRANSPORT_PROVIDER protocol)
+{
+    return (IOTHUB_DEVICE_CLIENT_LL_HANDLE)IoTHubClientCore_LL_CreateFromDeviceAuth(iothub_uri, device_id, protocol);
+}
+
+void IoTHubDeviceClient_LL_Destroy(IOTHUB_DEVICE_CLIENT_LL_HANDLE iotHubClientHandle)
+{
+    IoTHubClientCore_LL_Destroy((IOTHUB_CLIENT_CORE_LL_HANDLE)iotHubClientHandle);
+}
+
+IOTHUB_CLIENT_RESULT IoTHubDeviceClient_LL_SendEventAsync(IOTHUB_DEVICE_CLIENT_LL_HANDLE iotHubClientHandle, IOTHUB_MESSAGE_HANDLE eventMessageHandle, IOTHUB_CLIENT_EVENT_CONFIRMATION_CALLBACK eventConfirmationCallback, void* userContextCallback)
+{
+    return IoTHubClientCore_LL_SendEventAsync((IOTHUB_CLIENT_CORE_LL_HANDLE)iotHubClientHandle, eventMessageHandle, eventConfirmationCallback, userContextCallback);
+}
+
+IOTHUB_CLIENT_RESULT IoTHubDeviceClient_LL_GetSendStatus(IOTHUB_DEVICE_CLIENT_LL_HANDLE iotHubClientHandle, IOTHUB_CLIENT_STATUS *iotHubClientStatus)
+{
+    return IoTHubClientCore_LL_GetSendStatus((IOTHUB_CLIENT_CORE_LL_HANDLE)iotHubClientHandle, iotHubClientStatus);
+}
+
+IOTHUB_CLIENT_RESULT IoTHubDeviceClient_LL_SetMessageCallback(IOTHUB_DEVICE_CLIENT_LL_HANDLE iotHubClientHandle, IOTHUB_CLIENT_MESSAGE_CALLBACK_ASYNC messageCallback, void* userContextCallback)
+{
+    return IoTHubClientCore_LL_SetMessageCallback((IOTHUB_CLIENT_CORE_LL_HANDLE)iotHubClientHandle, messageCallback, userContextCallback);
+}
+
+IOTHUB_CLIENT_RESULT IoTHubDeviceClient_LL_SetConnectionStatusCallback(IOTHUB_DEVICE_CLIENT_LL_HANDLE iotHubClientHandle, IOTHUB_CLIENT_CONNECTION_STATUS_CALLBACK connectionStatusCallback, void * userContextCallback)
+{
+    return IoTHubClientCore_LL_SetConnectionStatusCallback((IOTHUB_CLIENT_CORE_LL_HANDLE)iotHubClientHandle, connectionStatusCallback, userContextCallback);
+}
+
+IOTHUB_CLIENT_RESULT IoTHubDeviceClient_LL_SetRetryPolicy(IOTHUB_DEVICE_CLIENT_LL_HANDLE iotHubClientHandle, IOTHUB_CLIENT_RETRY_POLICY retryPolicy, size_t retryTimeoutLimitInSeconds)
+{
+    return IoTHubClientCore_LL_SetRetryPolicy((IOTHUB_CLIENT_CORE_LL_HANDLE)iotHubClientHandle, retryPolicy, retryTimeoutLimitInSeconds);
+}
+
+IOTHUB_CLIENT_RESULT IoTHubDeviceClient_LL_GetRetryPolicy(IOTHUB_DEVICE_CLIENT_LL_HANDLE iotHubClientHandle, IOTHUB_CLIENT_RETRY_POLICY* retryPolicy, size_t* retryTimeoutLimitInSeconds)
+{
+    return IoTHubClientCore_LL_GetRetryPolicy((IOTHUB_CLIENT_CORE_LL_HANDLE)iotHubClientHandle, retryPolicy, retryTimeoutLimitInSeconds);
+}
+
+IOTHUB_CLIENT_RESULT IoTHubDeviceClient_LL_GetLastMessageReceiveTime(IOTHUB_DEVICE_CLIENT_LL_HANDLE iotHubClientHandle, time_t* lastMessageReceiveTime)
+{
+    return IoTHubClientCore_LL_GetLastMessageReceiveTime((IOTHUB_CLIENT_CORE_LL_HANDLE)iotHubClientHandle, lastMessageReceiveTime);
+}
+
+void IoTHubDeviceClient_LL_DoWork(IOTHUB_DEVICE_CLIENT_LL_HANDLE iotHubClientHandle)
+{
+    IoTHubClientCore_LL_DoWork((IOTHUB_CLIENT_CORE_LL_HANDLE)iotHubClientHandle);
+}
+
+IOTHUB_CLIENT_RESULT IoTHubDeviceClient_LL_SetOption(IOTHUB_DEVICE_CLIENT_LL_HANDLE iotHubClientHandle, const char* optionName, const void* value)
+{
+    return IoTHubClientCore_LL_SetOption((IOTHUB_CLIENT_CORE_LL_HANDLE)iotHubClientHandle, optionName, value);
+}
+
+IOTHUB_CLIENT_RESULT IoTHubDeviceClient_LL_SetDeviceTwinCallback(IOTHUB_DEVICE_CLIENT_LL_HANDLE iotHubClientHandle, IOTHUB_CLIENT_DEVICE_TWIN_CALLBACK deviceTwinCallback, void* userContextCallback)
+{
+    return IoTHubClientCore_LL_SetDeviceTwinCallback((IOTHUB_CLIENT_CORE_LL_HANDLE)iotHubClientHandle, deviceTwinCallback, userContextCallback);
+}
+
+IOTHUB_CLIENT_RESULT IoTHubDeviceClient_LL_GetTwinAsync(IOTHUB_DEVICE_CLIENT_LL_HANDLE iotHubClientHandle, IOTHUB_CLIENT_DEVICE_TWIN_CALLBACK deviceTwinCallback, void* userContextCallback)
+{
+    return IoTHubClientCore_LL_GetTwinAsync((IOTHUB_CLIENT_CORE_LL_HANDLE)iotHubClientHandle, deviceTwinCallback, userContextCallback);
+}
+
+IOTHUB_CLIENT_RESULT IoTHubDeviceClient_LL_SendReportedState(IOTHUB_DEVICE_CLIENT_LL_HANDLE iotHubClientHandle, const unsigned char* reportedState, size_t size, IOTHUB_CLIENT_REPORTED_STATE_CALLBACK reportedStateCallback, void* userContextCallback)
+{
+    return IoTHubClientCore_LL_SendReportedState((IOTHUB_CLIENT_CORE_LL_HANDLE)iotHubClientHandle, reportedState, size, reportedStateCallback, userContextCallback);
+}
+
+IOTHUB_CLIENT_RESULT IoTHubDeviceClient_LL_SetDeviceMethodCallback(IOTHUB_DEVICE_CLIENT_LL_HANDLE iotHubClientHandle, IOTHUB_CLIENT_DEVICE_METHOD_CALLBACK_ASYNC deviceMethodCallback, void* userContextCallback)
+{
+    return IoTHubClientCore_LL_SetDeviceMethodCallback((IOTHUB_CLIENT_CORE_LL_HANDLE)iotHubClientHandle, deviceMethodCallback, userContextCallback);
+}
+
+IOTHUB_CLIENT_RESULT IoTHubDeviceClient_LL_DeviceMethodResponse(IOTHUB_DEVICE_CLIENT_LL_HANDLE iotHubClientHandle, METHOD_HANDLE methodId, const unsigned char* response, size_t response_size, int status_response)
+{
+    return IoTHubClientCore_LL_DeviceMethodResponse((IOTHUB_CLIENT_CORE_LL_HANDLE)iotHubClientHandle, methodId, response, response_size, status_response);
+}
+
+#ifndef DONT_USE_UPLOADTOBLOB
+IOTHUB_CLIENT_RESULT IoTHubDeviceClient_LL_UploadToBlob(IOTHUB_DEVICE_CLIENT_LL_HANDLE iotHubClientHandle, const char* destinationFileName, const unsigned char* source, size_t size)
+{
+    return IoTHubClientCore_LL_UploadToBlob((IOTHUB_CLIENT_CORE_LL_HANDLE)iotHubClientHandle, destinationFileName, source, size);
+}
+
+IOTHUB_CLIENT_RESULT IoTHubDeviceClient_LL_UploadMultipleBlocksToBlob(IOTHUB_DEVICE_CLIENT_LL_HANDLE iotHubClientHandle, const char* destinationFileName, IOTHUB_CLIENT_FILE_UPLOAD_GET_DATA_CALLBACK_EX getDataCallbackEx, void* context)
+{
+    return IoTHubClientCore_LL_UploadMultipleBlocksToBlobEx((IOTHUB_CLIENT_CORE_LL_HANDLE)iotHubClientHandle, destinationFileName, getDataCallbackEx, context);
+}
+
+#endif
Index: azure_iot_hub_f767zi/trunk/azure_iot_sdk/iothub_client/src/iothub_message.c
===================================================================
--- azure_iot_hub_f767zi/trunk/azure_iot_sdk/iothub_client/src/iothub_message.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/azure_iot_sdk/iothub_client/src/iothub_message.c	(revision 457)
@@ -0,0 +1,1081 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+#include <stdlib.h>
+#include "azure_c_shared_utility/optimize_size.h"
+#include "azure_c_shared_utility/gballoc.h"
+#include "azure_c_shared_utility/xlogging.h"
+#include "azure_c_shared_utility/buffer_.h"
+
+#include "iothub_message.h"
+
+MU_DEFINE_ENUM_STRINGS_WITHOUT_INVALID(IOTHUB_MESSAGE_RESULT, IOTHUB_MESSAGE_RESULT_VALUES);
+MU_DEFINE_ENUM_STRINGS_WITHOUT_INVALID(IOTHUBMESSAGE_CONTENT_TYPE, IOTHUBMESSAGE_CONTENT_TYPE_VALUES);
+
+static const char* SECURITY_CLIENT_JSON_ENCODING = "application/json";
+
+typedef struct IOTHUB_MESSAGE_HANDLE_DATA_TAG
+{
+    IOTHUBMESSAGE_CONTENT_TYPE contentType;
+    union
+    {
+        BUFFER_HANDLE byteArray;
+        STRING_HANDLE string;
+    } value;
+    MAP_HANDLE properties;
+    char* messageId;
+    char* correlationId;
+    char* userDefinedContentType;
+    char* contentEncoding;
+    char* outputName;
+    char* inputName;
+    char* connectionModuleId;
+    char* connectionDeviceId;
+    IOTHUB_MESSAGE_DIAGNOSTIC_PROPERTY_DATA_HANDLE diagnosticData;
+    bool is_security_message;
+}IOTHUB_MESSAGE_HANDLE_DATA;
+
+static bool ContainsOnlyUsAscii(const char* asciiValue)
+{
+    bool result = true;
+    const char* iterator = asciiValue;
+    while (iterator != NULL && *iterator != '\0')
+    {
+        // Allow only printable ascii char
+        if (*iterator < ' ' || *iterator > '~')
+        {
+            result = false;
+            break;
+        }
+        iterator++;
+    }
+    return result;
+}
+
+/* Codes_SRS_IOTHUBMESSAGE_07_008: [ValidateAsciiCharactersFilter shall loop through the mapKey and mapValue strings to ensure that they only contain valid US-Ascii characters Ascii value 32 - 126.] */
+static int ValidateAsciiCharactersFilter(const char* mapKey, const char* mapValue)
+{
+    int result;
+    if (!ContainsOnlyUsAscii(mapKey) || !ContainsOnlyUsAscii(mapValue))
+    {
+        result = MU_FAILURE;
+    }
+    else
+    {
+        result = 0;
+    }
+    return result;
+}
+
+static void DestroyDiagnosticPropertyData(IOTHUB_MESSAGE_DIAGNOSTIC_PROPERTY_DATA_HANDLE diagnosticHandle)
+{
+    if (diagnosticHandle != NULL)
+    {
+        free(diagnosticHandle->diagnosticId);
+        free(diagnosticHandle->diagnosticCreationTimeUtc);
+    }
+    free(diagnosticHandle);
+}
+
+static void DestroyMessageData(IOTHUB_MESSAGE_HANDLE_DATA* handleData)
+{
+    if (handleData->contentType == IOTHUBMESSAGE_BYTEARRAY)
+    {
+        BUFFER_delete(handleData->value.byteArray);
+    }
+    else if (handleData->contentType == IOTHUBMESSAGE_STRING)
+    {
+        STRING_delete(handleData->value.string);
+    }
+
+    Map_Destroy(handleData->properties);
+    free(handleData->messageId);
+    handleData->messageId = NULL;
+    free(handleData->correlationId);
+    handleData->correlationId = NULL;
+    free(handleData->userDefinedContentType);
+    free(handleData->contentEncoding);
+    DestroyDiagnosticPropertyData(handleData->diagnosticData);
+    free(handleData->outputName);
+    free(handleData->inputName);
+    free(handleData->connectionModuleId);
+    free(handleData->connectionDeviceId);
+    free(handleData);
+}
+
+static int set_content_encoding(IOTHUB_MESSAGE_HANDLE_DATA* handleData, const char* encoding)
+{
+    int result;
+    char* tmp_encoding;
+
+    if (mallocAndStrcpy_s(&tmp_encoding, encoding) != 0)
+    {
+        LogError("Failed saving a copy of contentEncoding");
+        // Codes_SRS_IOTHUBMESSAGE_09_008: [If the allocation or the copying of `contentEncoding` fails, then IoTHubMessage_SetContentEncodingSystemProperty shall return IOTHUB_MESSAGE_ERROR.]
+        result = MU_FAILURE;
+    }
+    else
+    {
+        // Codes_SRS_IOTHUBMESSAGE_09_007: [If the IOTHUB_MESSAGE_HANDLE `contentEncoding` is not NULL it shall be deallocated.]
+        if (handleData->contentEncoding != NULL)
+        {
+            free(handleData->contentEncoding);
+        }
+        handleData->contentEncoding = tmp_encoding;
+        result = 0;
+    }
+    return result;
+}
+
+static IOTHUB_MESSAGE_DIAGNOSTIC_PROPERTY_DATA_HANDLE CloneDiagnosticPropertyData(const IOTHUB_MESSAGE_DIAGNOSTIC_PROPERTY_DATA* source)
+{
+    IOTHUB_MESSAGE_DIAGNOSTIC_PROPERTY_DATA_HANDLE result = NULL;
+    if (source == NULL)
+    {
+        LogError("Invalid argument - source is NULL");
+    }
+    else
+    {
+        result = (IOTHUB_MESSAGE_DIAGNOSTIC_PROPERTY_DATA_HANDLE)malloc(sizeof(IOTHUB_MESSAGE_DIAGNOSTIC_PROPERTY_DATA));
+        if (result == NULL)
+        {
+            LogError("malloc failed");
+        }
+        else
+        {
+            result->diagnosticCreationTimeUtc = NULL;
+            result->diagnosticId = NULL;
+            if (source->diagnosticCreationTimeUtc != NULL && mallocAndStrcpy_s(&result->diagnosticCreationTimeUtc, source->diagnosticCreationTimeUtc) != 0)
+            {
+                LogError("mallocAndStrcpy_s for diagnosticCreationTimeUtc failed");
+                free(result);
+                result = NULL;
+            }
+            else if (source->diagnosticId != NULL && mallocAndStrcpy_s(&result->diagnosticId, source->diagnosticId) != 0)
+            {
+                LogError("mallocAndStrcpy_s for diagnosticId failed");
+                free(result->diagnosticCreationTimeUtc);
+                free(result);
+                result = NULL;
+            }
+        }
+    }
+    return result;
+}
+
+IOTHUB_MESSAGE_HANDLE IoTHubMessage_CreateFromByteArray(const unsigned char* byteArray, size_t size)
+{
+    IOTHUB_MESSAGE_HANDLE_DATA* result;
+    if ((byteArray == NULL) && (size != 0))
+    {
+        LogError("Invalid argument - byteArray is NULL");
+        result = NULL;
+    }
+    else
+    {
+        result = (IOTHUB_MESSAGE_HANDLE_DATA*)malloc(sizeof(IOTHUB_MESSAGE_HANDLE_DATA));
+        if (result == NULL)
+        {
+            LogError("unable to malloc");
+            /*Codes_SRS_IOTHUBMESSAGE_02_024: [If there are any errors then IoTHubMessage_CreateFromByteArray shall return NULL.] */
+            /*let it go through*/
+        }
+        else
+        {
+            const unsigned char* source;
+            unsigned char temp = 0x00;
+
+            memset(result, 0, sizeof(*result));
+            /*Codes_SRS_IOTHUBMESSAGE_02_026: [The type of the new message shall be IOTHUBMESSAGE_BYTEARRAY.] */
+            result->contentType = IOTHUBMESSAGE_BYTEARRAY;
+
+            if (size != 0)
+            {
+                /*Codes_SRS_IOTHUBMESSAGE_06_002: [If size is NOT zero then byteArray MUST NOT be NULL*/
+                if (byteArray == NULL)
+                {
+                    LogError("Attempted to create a Hub Message from a NULL pointer!");
+                    DestroyMessageData(result);
+                    result = NULL;
+                    source = NULL;
+                }
+                else
+                {
+                    source = byteArray;
+                }
+            }
+            else
+            {
+                /*Codes_SRS_IOTHUBMESSAGE_06_001: [If size is zero then byteArray may be NULL.]*/
+                source = &temp;
+            }
+            if (result != NULL)
+            {
+                /*Codes_SRS_IOTHUBMESSAGE_02_022: [IoTHubMessage_CreateFromByteArray shall call BUFFER_create passing byteArray and size as parameters.] */
+                if ((result->value.byteArray = BUFFER_create(source, size)) == NULL)
+                {
+                    LogError("BUFFER_create failed");
+                    /*Codes_SRS_IOTHUBMESSAGE_02_024: [If there are any errors then IoTHubMessage_CreateFromByteArray shall return NULL.] */
+                    DestroyMessageData(result);
+                    result = NULL;
+                }
+                /*Codes_SRS_IOTHUBMESSAGE_02_023: [IoTHubMessage_CreateFromByteArray shall call Map_Create to create the message properties.] */
+                else if ((result->properties = Map_Create(ValidateAsciiCharactersFilter)) == NULL)
+                {
+                    LogError("Map_Create for properties failed");
+                    /*Codes_SRS_IOTHUBMESSAGE_02_024: [If there are any errors then IoTHubMessage_CreateFromByteArray shall return NULL.] */
+                    DestroyMessageData(result);
+                    result = NULL;
+                }
+                /*Codes_SRS_IOTHUBMESSAGE_02_025: [Otherwise, IoTHubMessage_CreateFromByteArray shall return a non-NULL handle.] */
+            }
+        }
+    }
+    return result;
+}
+
+IOTHUB_MESSAGE_HANDLE IoTHubMessage_CreateFromString(const char* source)
+{
+    IOTHUB_MESSAGE_HANDLE_DATA* result;
+    if (source == NULL)
+    {
+        LogError("Invalid argument - source is NULL");
+        result = NULL;
+    }
+    else
+    {
+        result = (IOTHUB_MESSAGE_HANDLE_DATA*)malloc(sizeof(IOTHUB_MESSAGE_HANDLE_DATA));
+        if (result == NULL)
+        {
+            LogError("malloc failed");
+            /*Codes_SRS_IOTHUBMESSAGE_02_029: [If there are any encountered in the execution of IoTHubMessage_CreateFromString then IoTHubMessage_CreateFromString shall return NULL.] */
+            /*let it go through*/
+        }
+        else
+        {
+            memset(result, 0, sizeof(*result));
+            /*Codes_SRS_IOTHUBMESSAGE_02_032: [The type of the new message shall be IOTHUBMESSAGE_STRING.] */
+            result->contentType = IOTHUBMESSAGE_STRING;
+
+            /*Codes_SRS_IOTHUBMESSAGE_02_027: [IoTHubMessage_CreateFromString shall call STRING_construct passing source as parameter.] */
+            if ((result->value.string = STRING_construct(source)) == NULL)
+            {
+                LogError("STRING_construct failed");
+                /*Codes_SRS_IOTHUBMESSAGE_02_029: [If there are any encountered in the execution of IoTHubMessage_CreateFromString then IoTHubMessage_CreateFromString shall return NULL.] */
+                DestroyMessageData(result);
+                result = NULL;
+            }
+            /*Codes_SRS_IOTHUBMESSAGE_02_028: [IoTHubMessage_CreateFromString shall call Map_Create to create the message properties.] */
+            else if ((result->properties = Map_Create(ValidateAsciiCharactersFilter)) == NULL)
+            {
+                LogError("Map_Create for properties failed");
+                /*Codes_SRS_IOTHUBMESSAGE_02_029: [If there are any encountered in the execution of IoTHubMessage_CreateFromString then IoTHubMessage_CreateFromString shall return NULL.] */
+                DestroyMessageData(result);
+                result = NULL;
+            }
+            /*Codes_SRS_IOTHUBMESSAGE_02_031: [Otherwise, IoTHubMessage_CreateFromString shall return a non-NULL handle.] */
+        }
+    }
+    return result;
+}
+
+/*Codes_SRS_IOTHUBMESSAGE_03_001: [IoTHubMessage_Clone shall create a new IoT hub message with data content identical to that of the iotHubMessageHandle parameter.]*/
+IOTHUB_MESSAGE_HANDLE IoTHubMessage_Clone(IOTHUB_MESSAGE_HANDLE iotHubMessageHandle)
+{
+    IOTHUB_MESSAGE_HANDLE_DATA* result;
+    const IOTHUB_MESSAGE_HANDLE_DATA* source = (const IOTHUB_MESSAGE_HANDLE_DATA*)iotHubMessageHandle;
+    /* Codes_SRS_IOTHUBMESSAGE_03_005: [IoTHubMessage_Clone shall return NULL if iotHubMessageHandle is NULL.] */
+    if (source == NULL)
+    {
+        result = NULL;
+        LogError("iotHubMessageHandle parameter cannot be NULL for IoTHubMessage_Clone");
+    }
+    else
+    {
+        result = (IOTHUB_MESSAGE_HANDLE_DATA*)malloc(sizeof(IOTHUB_MESSAGE_HANDLE_DATA));
+        /*Codes_SRS_IOTHUBMESSAGE_03_004: [IoTHubMessage_Clone shall return NULL if it fails for any reason.]*/
+        if (result == NULL)
+        {
+            /*Codes_SRS_IOTHUBMESSAGE_03_004: [IoTHubMessage_Clone shall return NULL if it fails for any reason.]*/
+            /*do nothing and return as is*/
+            LogError("unable to malloc");
+        }
+        else
+        {
+            memset(result, 0, sizeof(*result));
+            result->contentType = source->contentType;
+            result->is_security_message = source->is_security_message;
+
+            if (source->messageId != NULL && mallocAndStrcpy_s(&result->messageId, source->messageId) != 0)
+            {
+                LogError("unable to Copy messageId");
+                DestroyMessageData(result);
+                result = NULL;
+            }
+            else if (source->correlationId != NULL && mallocAndStrcpy_s(&result->correlationId, source->correlationId) != 0)
+            {
+                LogError("unable to Copy correlationId");
+                DestroyMessageData(result);
+                result = NULL;
+            }
+            else if (source->userDefinedContentType != NULL && mallocAndStrcpy_s(&result->userDefinedContentType, source->userDefinedContentType) != 0)
+            {
+                LogError("unable to copy contentType");
+                DestroyMessageData(result);
+                result = NULL;
+            }
+            else if (source->contentEncoding != NULL && mallocAndStrcpy_s(&result->contentEncoding, source->contentEncoding) != 0)
+            {
+                LogError("unable to copy contentEncoding");
+                DestroyMessageData(result);
+                result = NULL;
+            }
+            else if (source->diagnosticData != NULL && (result->diagnosticData = CloneDiagnosticPropertyData(source->diagnosticData)) == NULL)
+            {
+                LogError("unable to copy CloneDiagnosticPropertyData");
+                DestroyMessageData(result);
+                result = NULL;
+            }
+            else if (source->outputName != NULL && mallocAndStrcpy_s(&result->outputName, source->outputName) != 0)
+            {
+                LogError("unable to copy outputName");
+                DestroyMessageData(result);
+                result = NULL;
+            }
+            else if (source->inputName != NULL && mallocAndStrcpy_s(&result->inputName, source->inputName) != 0)
+            {
+                LogError("unable to copy inputName");
+                DestroyMessageData(result);
+                result = NULL;
+            }
+            else if (source->connectionModuleId != NULL && mallocAndStrcpy_s(&result->connectionModuleId, source->connectionModuleId) != 0)
+            {
+                LogError("unable to copy inputName");
+                DestroyMessageData(result);
+                result = NULL;
+            }
+            else if (source->connectionDeviceId != NULL && mallocAndStrcpy_s(&result->connectionDeviceId, source->connectionDeviceId) != 0)
+            {
+                LogError("unable to copy inputName");
+                DestroyMessageData(result);
+                result = NULL;
+            }
+            else if (source->contentType == IOTHUBMESSAGE_BYTEARRAY)
+            {
+                /*Codes_SRS_IOTHUBMESSAGE_02_006: [IoTHubMessage_Clone shall clone to content by a call to BUFFER_clone] */
+                if ((result->value.byteArray = BUFFER_clone(source->value.byteArray)) == NULL)
+                {
+                    /*Codes_SRS_IOTHUBMESSAGE_03_004: [IoTHubMessage_Clone shall return NULL if it fails for any reason.]*/
+                    LogError("unable to BUFFER_clone");
+                    DestroyMessageData(result);
+                    result = NULL;
+                }
+                /*Codes_SRS_IOTHUBMESSAGE_02_005: [IoTHubMessage_Clone shall clone the properties map by using Map_Clone.] */
+                else if ((result->properties = Map_Clone(source->properties)) == NULL)
+                {
+                    /*Codes_SRS_IOTHUBMESSAGE_03_004: [IoTHubMessage_Clone shall return NULL if it fails for any reason.]*/
+                    LogError("unable to Map_Clone");
+                    DestroyMessageData(result);
+                    result = NULL;
+                }
+                /*Codes_SRS_IOTHUBMESSAGE_03_002: [IoTHubMessage_Clone shall return upon success a non-NULL handle to the newly created IoT hub message.]*/
+            }
+            else /*can only be STRING*/
+            {
+                /*Codes_SRS_IOTHUBMESSAGE_02_006: [IoTHubMessage_Clone shall clone the content by a call to BUFFER_clone or STRING_clone] */
+                if ((result->value.string = STRING_clone(source->value.string)) == NULL)
+                {
+                    /*Codes_SRS_IOTHUBMESSAGE_03_004: [IoTHubMessage_Clone shall return NULL if it fails for any reason.]*/
+                    LogError("failed to STRING_clone");
+                    DestroyMessageData(result);
+                    result = NULL;
+                }
+                /*Codes_SRS_IOTHUBMESSAGE_02_005: [IoTHubMessage_Clone shall clone the properties map by using Map_Clone.] */
+                else if ((result->properties = Map_Clone(source->properties)) == NULL)
+                {
+                    /*Codes_SRS_IOTHUBMESSAGE_03_004: [IoTHubMessage_Clone shall return NULL if it fails for any reason.]*/
+                    LogError("unable to Map_Clone");
+                    DestroyMessageData(result);
+                    result = NULL;
+                }
+            }
+        }
+    }
+    return result;
+}
+
+IOTHUB_MESSAGE_RESULT IoTHubMessage_GetByteArray(IOTHUB_MESSAGE_HANDLE iotHubMessageHandle, const unsigned char** buffer, size_t* size)
+{
+    IOTHUB_MESSAGE_RESULT result;
+    if (
+        (iotHubMessageHandle == NULL) ||
+        (buffer == NULL) ||
+        (size == NULL)
+        )
+    {
+        /*Codes_SRS_IOTHUBMESSAGE_01_014: [If any of the arguments passed to IoTHubMessage_GetByteArray  is NULL IoTHubMessage_GetByteArray shall return IOTHUBMESSAGE_INVALID_ARG.] */
+        LogError("invalid parameter (NULL) to IoTHubMessage_GetByteArray IOTHUB_MESSAGE_HANDLE iotHubMessageHandle=%p, const unsigned char** buffer=%p, size_t* size=%p", iotHubMessageHandle, buffer, size);
+        result = IOTHUB_MESSAGE_INVALID_ARG;
+    }
+    else
+    {
+        IOTHUB_MESSAGE_HANDLE_DATA* handleData = iotHubMessageHandle;
+        if (handleData->contentType != IOTHUBMESSAGE_BYTEARRAY)
+        {
+            /*Codes_SRS_IOTHUBMESSAGE_02_021: [If iotHubMessageHandle is not a iothubmessage containing BYTEARRAY data, then IoTHubMessage_GetData shall write in *buffer NULL and shall set *size to 0.] */
+            result = IOTHUB_MESSAGE_INVALID_ARG;
+            LogError("invalid type of message %s", MU_ENUM_TO_STRING(IOTHUBMESSAGE_CONTENT_TYPE, handleData->contentType));
+        }
+        else
+        {
+            /*Codes_SRS_IOTHUBMESSAGE_01_011: [The pointer shall be obtained by using BUFFER_u_char and it shall be copied in the buffer argument.]*/
+            *buffer = BUFFER_u_char(handleData->value.byteArray);
+            /*Codes_SRS_IOTHUBMESSAGE_01_012: [The size of the associated data shall be obtained by using BUFFER_length and it shall be copied to the size argument.]*/
+            *size = BUFFER_length(handleData->value.byteArray);
+            result = IOTHUB_MESSAGE_OK;
+        }
+    }
+    return result;
+}
+
+const char* IoTHubMessage_GetString(IOTHUB_MESSAGE_HANDLE iotHubMessageHandle)
+{
+    const char* result;
+    if (iotHubMessageHandle == NULL)
+    {
+        /*Codes_SRS_IOTHUBMESSAGE_02_016: [If any parameter is NULL then IoTHubMessage_GetString  shall return NULL.] */
+        result = NULL;
+    }
+    else
+    {
+        IOTHUB_MESSAGE_HANDLE_DATA* handleData = iotHubMessageHandle;
+        if (handleData->contentType != IOTHUBMESSAGE_STRING)
+        {
+            /*Codes_SRS_IOTHUBMESSAGE_02_017: [IoTHubMessage_GetString shall return NULL if the iotHubMessageHandle does not refer to a IOTHUBMESSAGE of type STRING.] */
+            result = NULL;
+        }
+        else
+        {
+            /*Codes_SRS_IOTHUBMESSAGE_02_018: [IoTHubMessage_GetStringData shall return the currently stored null terminated string.] */
+            result = STRING_c_str(handleData->value.string);
+        }
+    }
+    return result;
+}
+
+IOTHUBMESSAGE_CONTENT_TYPE IoTHubMessage_GetContentType(IOTHUB_MESSAGE_HANDLE iotHubMessageHandle)
+{
+    IOTHUBMESSAGE_CONTENT_TYPE result;
+    /*Codes_SRS_IOTHUBMESSAGE_02_008: [If any parameter is NULL then IoTHubMessage_GetContentType shall return IOTHUBMESSAGE_UNKNOWN.] */
+    if (iotHubMessageHandle == NULL)
+    {
+        result = IOTHUBMESSAGE_UNKNOWN;
+    }
+    else
+    {
+        /*Codes_SRS_IOTHUBMESSAGE_02_009: [Otherwise IoTHubMessage_GetContentType shall return the type of the message.] */
+        IOTHUB_MESSAGE_HANDLE_DATA* handleData = iotHubMessageHandle;
+        result = handleData->contentType;
+    }
+    return result;
+}
+
+MAP_HANDLE IoTHubMessage_Properties(IOTHUB_MESSAGE_HANDLE iotHubMessageHandle)
+{
+    MAP_HANDLE result;
+    /*Codes_SRS_IOTHUBMESSAGE_02_001: [If iotHubMessageHandle is NULL then IoTHubMessage_Properties shall return NULL.]*/
+    if (iotHubMessageHandle == NULL)
+    {
+        LogError("invalid arg (NULL) passed to IoTHubMessage_Properties");
+        result = NULL;
+    }
+    else
+    {
+        /*Codes_SRS_IOTHUBMESSAGE_02_002: [Otherwise, for any non-NULL iotHubMessageHandle it shall return a non-NULL MAP_HANDLE.]*/
+        IOTHUB_MESSAGE_HANDLE_DATA* handleData = (IOTHUB_MESSAGE_HANDLE_DATA*)iotHubMessageHandle;
+        result = handleData->properties;
+    }
+    return result;
+}
+
+IOTHUB_MESSAGE_RESULT IoTHubMessage_SetProperty(IOTHUB_MESSAGE_HANDLE msg_handle, const char* key, const char* value)
+{
+    IOTHUB_MESSAGE_RESULT result;
+    if (msg_handle == NULL || key == NULL || value == NULL)
+    {
+        LogError("invalid parameter (NULL) to IoTHubMessage_SetProperty iotHubMessageHandle=%p, key=%p, value=%p", msg_handle, key, value);
+        result = IOTHUB_MESSAGE_INVALID_ARG;
+    }
+    else
+    {
+        if (Map_AddOrUpdate(msg_handle->properties, key, value) != MAP_OK)
+        {
+            LogError("Failure adding property to internal map");
+            result = IOTHUB_MESSAGE_ERROR;
+        }
+        else
+        {
+            result = IOTHUB_MESSAGE_OK;
+        }
+    }
+    return result;
+}
+
+const char* IoTHubMessage_GetProperty(IOTHUB_MESSAGE_HANDLE msg_handle, const char* key)
+{
+    const char* result;
+    if (msg_handle == NULL || key == NULL)
+    {
+        LogError("invalid parameter (NULL) to IoTHubMessage_GetProperty iotHubMessageHandle=%p, key=%p", msg_handle, key);
+        result = NULL;
+    }
+    else
+    {
+        bool key_exists = false;
+        // The return value is not neccessary, just check the key_exist variable
+        if ((Map_ContainsKey(msg_handle->properties, key, &key_exists) == MAP_OK) && key_exists)
+        {
+            result = Map_GetValueFromKey(msg_handle->properties, key);
+        }
+        else
+        {
+            result = NULL;
+        }
+    }
+    return result;
+}
+
+const char* IoTHubMessage_GetCorrelationId(IOTHUB_MESSAGE_HANDLE iotHubMessageHandle)
+{
+    const char* result;
+    /* Codes_SRS_IOTHUBMESSAGE_07_016: [if the iotHubMessageHandle parameter is NULL then IoTHubMessage_GetCorrelationId shall return a NULL value.] */
+    if (iotHubMessageHandle == NULL)
+    {
+        LogError("invalid arg (NULL) passed to IoTHubMessage_GetCorrelationId");
+        result = NULL;
+    }
+    else
+    {
+        /* Codes_SRS_IOTHUBMESSAGE_07_017: [IoTHubMessage_GetCorrelationId shall return the correlationId as a const char*.] */
+        IOTHUB_MESSAGE_HANDLE_DATA* handleData = iotHubMessageHandle;
+        result = handleData->correlationId;
+    }
+    return result;
+}
+
+IOTHUB_MESSAGE_RESULT IoTHubMessage_SetCorrelationId(IOTHUB_MESSAGE_HANDLE iotHubMessageHandle, const char* correlationId)
+{
+    IOTHUB_MESSAGE_RESULT result;
+    /* Codes_SRS_IOTHUBMESSAGE_07_018: [if any of the parameters are NULL then IoTHubMessage_SetCorrelationId shall return a IOTHUB_MESSAGE_INVALID_ARG value.]*/
+    if (iotHubMessageHandle == NULL || correlationId == NULL)
+    {
+        LogError("invalid arg (NULL) passed to IoTHubMessage_SetCorrelationId");
+        result = IOTHUB_MESSAGE_INVALID_ARG;
+    }
+    else
+    {
+        IOTHUB_MESSAGE_HANDLE_DATA* handleData = iotHubMessageHandle;
+        /* Codes_SRS_IOTHUBMESSAGE_07_019: [If the IOTHUB_MESSAGE_HANDLE correlationId is not NULL, then the IOTHUB_MESSAGE_HANDLE correlationId will be deallocated.] */
+        if (handleData->correlationId != NULL)
+        {
+            free(handleData->correlationId);
+            handleData->correlationId = NULL;
+        }
+
+        if (mallocAndStrcpy_s(&handleData->correlationId, correlationId) != 0)
+        {
+            /* Codes_SRS_IOTHUBMESSAGE_07_020: [If the allocation or the copying of the correlationId fails, then IoTHubMessage_SetCorrelationId shall return IOTHUB_MESSAGE_ERROR.] */
+            result = IOTHUB_MESSAGE_ERROR;
+        }
+        else
+        {
+            /* Codes_SRS_IOTHUBMESSAGE_07_021: [IoTHubMessage_SetCorrelationId finishes successfully it shall return IOTHUB_MESSAGE_OK.] */
+            result = IOTHUB_MESSAGE_OK;
+        }
+    }
+    return result;
+}
+
+IOTHUB_MESSAGE_RESULT IoTHubMessage_SetMessageId(IOTHUB_MESSAGE_HANDLE iotHubMessageHandle, const char* messageId)
+{
+    IOTHUB_MESSAGE_RESULT result;
+    /* Codes_SRS_IOTHUBMESSAGE_07_012: [if any of the parameters are NULL then IoTHubMessage_SetMessageId shall return a IOTHUB_MESSAGE_INVALID_ARG value.] */
+    if (iotHubMessageHandle == NULL || messageId == NULL)
+    {
+        LogError("invalid arg (NULL) passed to IoTHubMessage_SetMessageId");
+        result = IOTHUB_MESSAGE_INVALID_ARG;
+    }
+    else
+    {
+        IOTHUB_MESSAGE_HANDLE_DATA* handleData = iotHubMessageHandle;
+        /* Codes_SRS_IOTHUBMESSAGE_07_013: [If the IOTHUB_MESSAGE_HANDLE messageId is not NULL, then the IOTHUB_MESSAGE_HANDLE messageId will be freed] */
+        if (handleData->messageId != NULL)
+        {
+            free(handleData->messageId);
+            handleData->messageId = NULL;
+        }
+
+        /* Codes_SRS_IOTHUBMESSAGE_07_014: [If the allocation or the copying of the messageId fails, then IoTHubMessage_SetMessageId shall return IOTHUB_MESSAGE_ERROR.] */
+        if (mallocAndStrcpy_s(&handleData->messageId, messageId) != 0)
+        {
+            result = IOTHUB_MESSAGE_ERROR;
+        }
+        else
+        {
+            result = IOTHUB_MESSAGE_OK;
+        }
+    }
+    return result;
+}
+
+const char* IoTHubMessage_GetMessageId(IOTHUB_MESSAGE_HANDLE iotHubMessageHandle)
+{
+    const char* result;
+    /* Codes_SRS_IOTHUBMESSAGE_07_010: [if the iotHubMessageHandle parameter is NULL then IoTHubMessage_MessageId shall return a NULL value.] */
+    if (iotHubMessageHandle == NULL)
+    {
+        LogError("invalid arg (NULL) passed to IoTHubMessage_GetMessageId");
+        result = NULL;
+    }
+    else
+    {
+        /* Codes_SRS_IOTHUBMESSAGE_07_011: [IoTHubMessage_MessageId shall return the messageId as a const char*.] */
+        IOTHUB_MESSAGE_HANDLE_DATA* handleData = iotHubMessageHandle;
+        result = handleData->messageId;
+    }
+    return result;
+}
+
+IOTHUB_MESSAGE_RESULT IoTHubMessage_SetContentTypeSystemProperty(IOTHUB_MESSAGE_HANDLE iotHubMessageHandle, const char* contentType)
+{
+    IOTHUB_MESSAGE_RESULT result;
+
+    // Codes_SRS_IOTHUBMESSAGE_09_001: [If any of the parameters are NULL then IoTHubMessage_SetContentTypeSystemProperty shall return a IOTHUB_MESSAGE_INVALID_ARG value.]
+    if (iotHubMessageHandle == NULL || contentType == NULL)
+    {
+        LogError("Invalid argument (iotHubMessageHandle=%p, contentType=%p)", iotHubMessageHandle, contentType);
+        result = IOTHUB_MESSAGE_INVALID_ARG;
+    }
+    else
+    {
+        IOTHUB_MESSAGE_HANDLE_DATA* handleData = (IOTHUB_MESSAGE_HANDLE_DATA*)iotHubMessageHandle;
+
+        // Codes_SRS_IOTHUBMESSAGE_09_002: [If the IOTHUB_MESSAGE_HANDLE `contentType` is not NULL it shall be deallocated.]
+        if (handleData->userDefinedContentType != NULL)
+        {
+            free(handleData->userDefinedContentType);
+            handleData->userDefinedContentType = NULL;
+        }
+
+        if (mallocAndStrcpy_s(&handleData->userDefinedContentType, contentType) != 0)
+        {
+            LogError("Failed saving a copy of contentType");
+            // Codes_SRS_IOTHUBMESSAGE_09_003: [If the allocation or the copying of `contentType` fails, then IoTHubMessage_SetContentTypeSystemProperty shall return IOTHUB_MESSAGE_ERROR.]
+            result = IOTHUB_MESSAGE_ERROR;
+        }
+        else
+        {
+            // Codes_SRS_IOTHUBMESSAGE_09_004: [If IoTHubMessage_SetContentTypeSystemProperty finishes successfully it shall return IOTHUB_MESSAGE_OK.]
+            result = IOTHUB_MESSAGE_OK;
+        }
+    }
+
+    return result;
+}
+
+const char* IoTHubMessage_GetContentTypeSystemProperty(IOTHUB_MESSAGE_HANDLE iotHubMessageHandle)
+{
+    const char* result;
+
+    // Codes_SRS_IOTHUBMESSAGE_09_005: [If any of the parameters are NULL then IoTHubMessage_GetContentTypeSystemProperty shall return a IOTHUB_MESSAGE_INVALID_ARG value.]
+    if (iotHubMessageHandle == NULL)
+    {
+        LogError("Invalid argument (iotHubMessageHandle is NULL)");
+        result = NULL;
+    }
+    else
+    {
+        IOTHUB_MESSAGE_HANDLE_DATA* handleData = iotHubMessageHandle;
+
+        // Codes_SRS_IOTHUBMESSAGE_09_006: [IoTHubMessage_GetContentTypeSystemProperty shall return the `contentType` as a const char* ]
+        result = (const char*)handleData->userDefinedContentType;
+    }
+
+    return result;
+}
+
+IOTHUB_MESSAGE_RESULT IoTHubMessage_SetContentEncodingSystemProperty(IOTHUB_MESSAGE_HANDLE iotHubMessageHandle, const char* contentEncoding)
+{
+    IOTHUB_MESSAGE_RESULT result;
+
+    // Codes_SRS_IOTHUBMESSAGE_09_006: [If any of the parameters are NULL then IoTHubMessage_SetContentEncodingSystemProperty shall return a IOTHUB_MESSAGE_INVALID_ARG value.]
+    if (iotHubMessageHandle == NULL || contentEncoding == NULL)
+    {
+        LogError("Invalid argument (iotHubMessageHandle=%p, contentEncoding=%p)", iotHubMessageHandle, contentEncoding);
+        result = IOTHUB_MESSAGE_INVALID_ARG;
+    }
+    else
+    {
+        if (set_content_encoding(iotHubMessageHandle, contentEncoding) != 0)
+        {
+            LogError("Failed saving a copy of contentEncoding");
+            // Codes_SRS_IOTHUBMESSAGE_09_008: [If the allocation or the copying of `contentEncoding` fails, then IoTHubMessage_SetContentEncodingSystemProperty shall return IOTHUB_MESSAGE_ERROR.]
+            result = IOTHUB_MESSAGE_ERROR;
+        }
+        else
+        {
+            // Codes_SRS_IOTHUBMESSAGE_09_009: [If IoTHubMessage_SetContentEncodingSystemProperty finishes successfully it shall return IOTHUB_MESSAGE_OK.]
+            result = IOTHUB_MESSAGE_OK;
+        }
+    }
+    return result;
+}
+
+const char* IoTHubMessage_GetContentEncodingSystemProperty(IOTHUB_MESSAGE_HANDLE iotHubMessageHandle)
+{
+    const char* result;
+
+    // Codes_SRS_IOTHUBMESSAGE_09_010: [If any of the parameters are NULL then IoTHubMessage_GetContentEncodingSystemProperty shall return a IOTHUB_MESSAGE_INVALID_ARG value.]
+    if (iotHubMessageHandle == NULL)
+    {
+        LogError("Invalid argument (iotHubMessageHandle is NULL)");
+        result = NULL;
+    }
+    else
+    {
+        IOTHUB_MESSAGE_HANDLE_DATA* handleData = iotHubMessageHandle;
+
+        // Codes_SRS_IOTHUBMESSAGE_09_011: [IoTHubMessage_GetContentEncodingSystemProperty shall return the `contentEncoding` as a const char* ]
+        result = (const char*)handleData->contentEncoding;
+    }
+
+    return result;
+}
+
+const IOTHUB_MESSAGE_DIAGNOSTIC_PROPERTY_DATA* IoTHubMessage_GetDiagnosticPropertyData(IOTHUB_MESSAGE_HANDLE iotHubMessageHandle)
+{
+    const IOTHUB_MESSAGE_DIAGNOSTIC_PROPERTY_DATA* result;
+    // Codes_SRS_IOTHUBMESSAGE_10_001: [If any of the parameters are NULL then IoTHubMessage_GetDiagnosticPropertyData shall return a NULL value.]
+    if (iotHubMessageHandle == NULL)
+    {
+        LogError("Invalid argument (iotHubMessageHandle is NULL)");
+        result = NULL;
+    }
+    else
+    {
+        /* Codes_SRS_IOTHUBMESSAGE_10_002: [IoTHubMessage_GetDiagnosticPropertyData shall return the diagnosticData as a const IOTHUB_MESSAGE_DIAGNOSTIC_PROPERTY_DATA*.] */
+        result = iotHubMessageHandle->diagnosticData;
+    }
+    return result;
+}
+
+IOTHUB_MESSAGE_RESULT IoTHubMessage_SetDiagnosticPropertyData(IOTHUB_MESSAGE_HANDLE iotHubMessageHandle, const IOTHUB_MESSAGE_DIAGNOSTIC_PROPERTY_DATA* diagnosticData)
+{
+    IOTHUB_MESSAGE_RESULT result;
+    // Codes_SRS_IOTHUBMESSAGE_10_003: [If any of the parameters are NULL then IoTHubMessage_SetDiagnosticId shall return a IOTHUB_MESSAGE_INVALID_ARG value.]
+    if (iotHubMessageHandle == NULL ||
+        diagnosticData == NULL ||
+        diagnosticData->diagnosticCreationTimeUtc == NULL ||
+        diagnosticData->diagnosticId == NULL)
+    {
+        LogError("Invalid argument (iotHubMessageHandle=%p, diagnosticData=%p, diagnosticData->diagnosticId=%p, diagnosticData->diagnosticCreationTimeUtc=%p)",
+            iotHubMessageHandle, diagnosticData,
+            diagnosticData == NULL ? NULL : diagnosticData->diagnosticId,
+            diagnosticData == NULL ? NULL : diagnosticData->diagnosticCreationTimeUtc);
+        result = IOTHUB_MESSAGE_INVALID_ARG;
+    }
+    else
+    {
+        // Codes_SRS_IOTHUBMESSAGE_10_004: [If the IOTHUB_MESSAGE_HANDLE `diagnosticData` is not NULL it shall be deallocated.]
+        if (iotHubMessageHandle->diagnosticData != NULL)
+        {
+            DestroyDiagnosticPropertyData(iotHubMessageHandle->diagnosticData);
+            iotHubMessageHandle->diagnosticData = NULL;
+        }
+
+        // Codes_SRS_IOTHUBMESSAGE_10_005: [If the allocation or the copying of `diagnosticData` fails, then IoTHubMessage_SetDiagnosticPropertyData shall return IOTHUB_MESSAGE_ERROR.]
+        if ((iotHubMessageHandle->diagnosticData = CloneDiagnosticPropertyData(diagnosticData)) == NULL)
+        {
+            LogError("Failed saving a copy of diagnosticData");
+            result = IOTHUB_MESSAGE_ERROR;
+        }
+        else
+        {
+            // Codes_SRS_IOTHUBMESSAGE_10_006: [If IoTHubMessage_SetDiagnosticPropertyData finishes successfully it shall return IOTHUB_MESSAGE_OK.]
+            result = IOTHUB_MESSAGE_OK;
+        }
+    }
+    return result;
+}
+
+
+const char* IoTHubMessage_GetOutputName(IOTHUB_MESSAGE_HANDLE iotHubMessageHandle)
+{
+    const char* result;
+    // Codes_SRS_IOTHUBMESSAGE_31_034: [If the iotHubMessageHandle parameter is NULL then IoTHubMessage_GetOutputName shall return a NULL value.]
+    if (iotHubMessageHandle == NULL)
+    {
+        LogError("Invalid argument (iotHubMessageHandle is NULL)");
+        result = NULL;
+    }
+    else
+    {
+        // Codes_SRS_IOTHUBMESSAGE_31_035: [IoTHubMessage_GetOutputName shall return the OutputName as a const char*.]
+        result = iotHubMessageHandle->outputName;
+    }
+    return result;
+}
+
+IOTHUB_MESSAGE_RESULT IoTHubMessage_SetOutputName(IOTHUB_MESSAGE_HANDLE iotHubMessageHandle, const char* outputName)
+{
+    IOTHUB_MESSAGE_RESULT result;
+
+    // Codes_SRS_IOTHUBMESSAGE_31_036: [If any of the parameters are NULL then IoTHubMessage_SetOutputName shall return a IOTHUB_MESSAGE_INVALID_ARG value.]
+    if ((iotHubMessageHandle == NULL) || (outputName == NULL))
+    {
+        LogError("Invalid argument (iotHubMessageHandle=%p, outputName=%p)", iotHubMessageHandle, outputName);
+        result = IOTHUB_MESSAGE_INVALID_ARG;
+    }
+    else
+    {
+        IOTHUB_MESSAGE_HANDLE_DATA* handleData = (IOTHUB_MESSAGE_HANDLE_DATA*)iotHubMessageHandle;
+
+        // Codes_SRS_IOTHUBMESSAGE_31_037: [If the IOTHUB_MESSAGE_HANDLE OutputName is not NULL, then the IOTHUB_MESSAGE_HANDLE OutputName will be deallocated.]
+        if (handleData->outputName != NULL)
+        {
+            free(handleData->outputName);
+            handleData->outputName = NULL;
+        }
+
+        if (mallocAndStrcpy_s(&handleData->outputName, outputName) != 0)
+        {
+            // Codes_SRS_IOTHUBMESSAGE_31_038: [If the allocation or the copying of the OutputName fails, then IoTHubMessage_SetOutputName shall return IOTHUB_MESSAGE_ERROR.]
+            LogError("Failed saving a copy of outputName");
+            result = IOTHUB_MESSAGE_ERROR;
+        }
+        else
+        {
+            // Codes_SRS_IOTHUBMESSAGE_31_039: [IoTHubMessage_SetOutputName finishes successfully it shall return IOTHUB_MESSAGE_OK.]
+            result = IOTHUB_MESSAGE_OK;
+        }
+
+    }
+
+    return result;
+}
+
+const char* IoTHubMessage_GetInputName(IOTHUB_MESSAGE_HANDLE iotHubMessageHandle)
+{
+    const char* result;
+    // Codes_SRS_IOTHUBMESSAGE_31_040: [if the iotHubMessageHandle parameter is NULL then IoTHubMessage_GetInputName shall return a NULL value.]
+    if (iotHubMessageHandle == NULL)
+    {
+        LogError("Invalid argument (iotHubMessageHandle is NULL)");
+        result = NULL;
+    }
+    else
+    {
+        // Codes_SRS_IOTHUBMESSAGE_31_041: [IoTHubMessage_GetInputName shall return the InputName as a const char*.]
+        result = iotHubMessageHandle->inputName;
+    }
+    return result;
+}
+
+IOTHUB_MESSAGE_RESULT IoTHubMessage_SetInputName(IOTHUB_MESSAGE_HANDLE iotHubMessageHandle, const char* inputName)
+{
+    IOTHUB_MESSAGE_RESULT result;
+
+    // Codes_SRS_IOTHUBMESSAGE_31_042: [if any of the parameters are NULL then IoTHubMessage_SetInputName shall return a IOTHUB_MESSAGE_INVALID_ARG value.]
+    if ((iotHubMessageHandle == NULL) || (inputName == NULL))
+    {
+        LogError("Invalid argument (iotHubMessageHandle=%p, inputName=%p)", iotHubMessageHandle, inputName);
+        result = IOTHUB_MESSAGE_INVALID_ARG;
+    }
+    else
+    {
+        IOTHUB_MESSAGE_HANDLE_DATA* handleData = (IOTHUB_MESSAGE_HANDLE_DATA*)iotHubMessageHandle;
+
+        // Codes_SRS_IOTHUBMESSAGE_31_043: [If the IOTHUB_MESSAGE_HANDLE InputName is not NULL, then the IOTHUB_MESSAGE_HANDLE InputName will be deallocated.]
+        if (handleData->inputName != NULL)
+        {
+            free(handleData->inputName);
+            handleData->inputName = NULL;
+        }
+
+        if (mallocAndStrcpy_s(&handleData->inputName, inputName) != 0)
+        {
+            // Codes_SRS_IOTHUBMESSAGE_31_044: [If the allocation or the copying of the InputName fails, then IoTHubMessage_SetInputName shall return IOTHUB_MESSAGE_ERROR.]
+            LogError("Failed saving a copy of inputName");
+            result = IOTHUB_MESSAGE_ERROR;
+        }
+        else
+        {
+            // Codes_SRS_IOTHUBMESSAGE_31_045: [IoTHubMessage_SetInputName finishes successfully it shall return IOTHUB_MESSAGE_OK.]
+            result = IOTHUB_MESSAGE_OK;
+        }
+
+    }
+
+    return result;
+}
+
+
+const char* IoTHubMessage_GetConnectionModuleId(IOTHUB_MESSAGE_HANDLE iotHubMessageHandle)
+{
+    const char* result;
+    // Codes_SRS_IOTHUBMESSAGE_31_046: [if the iotHubMessageHandle parameter is NULL then IoTHubMessage_GetConnectionModuleId shall return a NULL value.]
+    if (iotHubMessageHandle == NULL)
+    {
+        LogError("Invalid argument (iotHubMessageHandle is NULL)");
+        result = NULL;
+    }
+    else
+    {
+        // Codes_SRS_IOTHUBMESSAGE_31_047: [IoTHubMessage_GetConnectionModuleId shall return the ConnectionModuleId as a const char*.]
+        result = iotHubMessageHandle->connectionModuleId;
+    }
+    return result;
+}
+
+IOTHUB_MESSAGE_RESULT IoTHubMessage_SetConnectionModuleId(IOTHUB_MESSAGE_HANDLE iotHubMessageHandle, const char* connectionModuleId)
+{
+    IOTHUB_MESSAGE_RESULT result;
+
+    // Codes_SRS_IOTHUBMESSAGE_31_048: [if any of the parameters are NULL then IoTHubMessage_SetConnectionModuleId shall return a IOTHUB_MESSAGE_INVALID_ARG value.]
+    if ((iotHubMessageHandle == NULL) || (connectionModuleId == NULL))
+    {
+        LogError("Invalid argument (iotHubMessageHandle=%p, connectionModuleId=%p)", iotHubMessageHandle, connectionModuleId);
+        result = IOTHUB_MESSAGE_INVALID_ARG;
+    }
+    else
+    {
+        IOTHUB_MESSAGE_HANDLE_DATA* handleData = (IOTHUB_MESSAGE_HANDLE_DATA*)iotHubMessageHandle;
+
+        // Codes_SRS_IOTHUBMESSAGE_31_049: [If the IOTHUB_MESSAGE_HANDLE ConnectionModuleId is not NULL, then the IOTHUB_MESSAGE_HANDLE ConnectionModuleId will be deallocated.]
+        if (handleData->connectionModuleId != NULL)
+        {
+            free(handleData->connectionModuleId);
+            handleData->connectionModuleId = NULL;
+        }
+
+        if (mallocAndStrcpy_s(&handleData->connectionModuleId, connectionModuleId) != 0)
+        {
+            // Codes_SRS_IOTHUBMESSAGE_31_050: [If the allocation or the copying of the ConnectionModuleId fails, then IoTHubMessage_SetConnectionModuleId shall return IOTHUB_MESSAGE_ERROR.]
+            LogError("Failed saving a copy of connectionModuleId");
+            result = IOTHUB_MESSAGE_ERROR;
+        }
+        else
+        {
+            // Codes_SRS_IOTHUBMESSAGE_31_051: [IoTHubMessage_SetConnectionModuleId finishes successfully it shall return IOTHUB_MESSAGE_OK.]
+            result = IOTHUB_MESSAGE_OK;
+        }
+
+    }
+
+    return result;
+}
+
+
+const char* IoTHubMessage_GetConnectionDeviceId(IOTHUB_MESSAGE_HANDLE iotHubMessageHandle)
+{
+    const char* result;
+    // Codes_SRS_IOTHUBMESSAGE_31_052: [if the iotHubMessageHandle parameter is NULL then IoTHubMessage_GetConnectionDeviceId shall return a NULL value.]
+    if (iotHubMessageHandle == NULL)
+    {
+        LogError("Invalid argument (iotHubMessageHandle is NULL)");
+        result = NULL;
+    }
+    else
+    {
+        // Codes_SRS_IOTHUBMESSAGE_31_053: [IoTHubMessage_GetConnectionDeviceId shall return the ConnectionDeviceId as a const char*.]
+        result = iotHubMessageHandle->connectionDeviceId;
+    }
+    return result;
+}
+
+IOTHUB_MESSAGE_RESULT IoTHubMessage_SetConnectionDeviceId(IOTHUB_MESSAGE_HANDLE iotHubMessageHandle, const char* connectionDeviceId)
+{
+    IOTHUB_MESSAGE_RESULT result;
+
+    // Codes_SRS_IOTHUBMESSAGE_31_054: [if any of the parameters are NULL then IoTHubMessage_SetConnectionDeviceId shall return a IOTHUB_MESSAGE_INVALID_ARG value.]
+    if ((iotHubMessageHandle == NULL) || (connectionDeviceId == NULL))
+    {
+        LogError("Invalid argument (iotHubMessageHandle=%p, connectionDeviceId=%p)", iotHubMessageHandle, connectionDeviceId);
+        result = IOTHUB_MESSAGE_INVALID_ARG;
+    }
+    else
+    {
+        IOTHUB_MESSAGE_HANDLE_DATA* handleData = (IOTHUB_MESSAGE_HANDLE_DATA*)iotHubMessageHandle;
+
+        // Codes_SRS_IOTHUBMESSAGE_31_055: [If the IOTHUB_MESSAGE_HANDLE ConnectionDeviceId is not NULL, then the IOTHUB_MESSAGE_HANDLE ConnectionDeviceId will be deallocated.]
+        if (handleData->connectionDeviceId != NULL)
+        {
+            free(handleData->connectionDeviceId);
+            handleData->connectionDeviceId = NULL;
+        }
+
+        if (mallocAndStrcpy_s(&handleData->connectionDeviceId, connectionDeviceId) != 0)
+        {
+            // Codes_SRS_IOTHUBMESSAGE_31_056: [If the allocation or the copying of the ConnectionDeviceId fails, then IoTHubMessage_SetConnectionDeviceId shall return IOTHUB_MESSAGE_ERROR.]
+            LogError("Failed saving a copy of connectionDeviceId");
+            result = IOTHUB_MESSAGE_ERROR;
+        }
+        else
+        {
+            // Codes_SRS_IOTHUBMESSAGE_31_057: [IoTHubMessage_SetConnectionDeviceId finishes successfully it shall return IOTHUB_MESSAGE_OK.]
+            result = IOTHUB_MESSAGE_OK;
+        }
+
+    }
+
+    return result;
+}
+
+IOTHUB_MESSAGE_RESULT IoTHubMessage_SetAsSecurityMessage(IOTHUB_MESSAGE_HANDLE iotHubMessageHandle)
+{
+    IOTHUB_MESSAGE_RESULT result;
+    if (iotHubMessageHandle == NULL)
+    {
+        LogError("Invalid argument (iotHubMessageHandle is NULL)");
+        result = IOTHUB_MESSAGE_INVALID_ARG;
+    }
+    else
+    {
+        if (set_content_encoding(iotHubMessageHandle, SECURITY_CLIENT_JSON_ENCODING) != 0)
+        {
+            LogError("Failure setting security message content encoding");
+            result = IOTHUB_MESSAGE_ERROR;
+        }
+        else
+        {
+            iotHubMessageHandle->is_security_message = true;
+            result = IOTHUB_MESSAGE_OK;
+        }
+    }
+    return result;
+}
+
+bool IoTHubMessage_IsSecurityMessage(IOTHUB_MESSAGE_HANDLE iotHubMessageHandle)
+{
+    bool result;
+    if (iotHubMessageHandle == NULL)
+    {
+        LogError("Invalid argument (iotHubMessageHandle is NULL)");
+        result = false;
+    }
+    else
+    {
+        result = iotHubMessageHandle->is_security_message;
+    }
+    return result;
+}
+
+void IoTHubMessage_Destroy(IOTHUB_MESSAGE_HANDLE iotHubMessageHandle)
+{
+    /*Codes_SRS_IOTHUBMESSAGE_01_004: [If iotHubMessageHandle is NULL, IoTHubMessage_Destroy shall do nothing.] */
+    if (iotHubMessageHandle != NULL)
+    {
+        /*Codes_SRS_IOTHUBMESSAGE_01_003: [IoTHubMessage_Destroy shall free all resources associated with iotHubMessageHandle.]  */
+        DestroyMessageData((IOTHUB_MESSAGE_HANDLE_DATA*)iotHubMessageHandle);
+    }
+}
Index: azure_iot_hub_f767zi/trunk/azure_iot_sdk/iothub_client/src/iothub_transport_ll_private.c
===================================================================
--- azure_iot_hub_f767zi/trunk/azure_iot_sdk/iothub_client/src/iothub_transport_ll_private.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/azure_iot_sdk/iothub_client/src/iothub_transport_ll_private.c	(revision 457)
@@ -0,0 +1,32 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+#include <stdlib.h>
+
+#include "azure_c_shared_utility/xlogging.h"
+#include "internal/iothub_transport_ll_private.h"
+
+int IoTHub_Transport_ValidateCallbacks(const TRANSPORT_CALLBACKS_INFO* transport_cb)
+{
+    int result;
+    if (
+        transport_cb == NULL ||
+        transport_cb->connection_status_cb == NULL ||
+        transport_cb->msg_input_cb == NULL ||
+        transport_cb->msg_cb == NULL ||
+        transport_cb->send_complete_cb == NULL ||
+        transport_cb->prod_info_cb == NULL ||
+        transport_cb->twin_rpt_state_complete_cb == NULL ||
+        transport_cb->twin_retrieve_prop_complete_cb == NULL ||
+        transport_cb->method_complete_cb == NULL
+        )
+    {
+        LogError("Failure callback function NULL");
+        result = MU_FAILURE;
+    }
+    else
+    {
+        result = 0;
+    }
+    return result;
+}
Index: azure_iot_hub_f767zi/trunk/azure_iot_sdk/iothub_client/src/iothubtransport.c
===================================================================
--- azure_iot_hub_f767zi/trunk/azure_iot_sdk/iothub_client/src/iothubtransport.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/azure_iot_sdk/iothub_client/src/iothubtransport.c	(revision 457)
@@ -0,0 +1,465 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+#include <stdlib.h>
+#include <signal.h>
+#include <stddef.h>
+#include "azure_c_shared_utility/gballoc.h"
+#include "azure_c_shared_utility/crt_abstractions.h"
+#include "internal/iothubtransport.h"
+#include "iothub_client_core.h"
+#include "internal/iothub_client_private.h"
+#include "azure_c_shared_utility/threadapi.h"
+#include "azure_c_shared_utility/lock.h"
+#include "azure_c_shared_utility/xlogging.h"
+#include "azure_c_shared_utility/vector.h"
+
+#include "internal/iothubtransport.h"
+#include "internal/iothub_client_private.h"
+#include "iothub_transport_ll.h"
+#include "iothub_client_core.h"
+
+typedef struct TRANSPORT_HANDLE_DATA_TAG
+{
+    TRANSPORT_LL_HANDLE transportLLHandle;
+    THREAD_HANDLE workerThreadHandle;
+    LOCK_HANDLE lockHandle;
+    sig_atomic_t stopThread;
+    TRANSPORT_PROVIDER_FIELDS;
+    VECTOR_HANDLE clients;
+    LOCK_HANDLE clientsLockHandle;
+    IOTHUB_CLIENT_MULTIPLEXED_DO_WORK clientDoWork;
+} TRANSPORT_HANDLE_DATA;
+
+/* Used for Unit test */
+const size_t IoTHubTransport_ThreadTerminationOffset = offsetof(TRANSPORT_HANDLE_DATA, stopThread);
+
+TRANSPORT_HANDLE IoTHubTransport_Create(IOTHUB_CLIENT_TRANSPORT_PROVIDER protocol, const char* iotHubName, const char* iotHubSuffix)
+{
+    TRANSPORT_HANDLE_DATA *result;
+    TRANSPORT_CALLBACKS_INFO transport_cb;
+
+    if (protocol == NULL || iotHubName == NULL || iotHubSuffix == NULL)
+    {
+        /*Codes_SRS_IOTHUBTRANSPORT_17_002: [ If protocol is NULL, this function shall return NULL. ]*/
+        /*Codes_SRS_IOTHUBTRANSPORT_17_003: [ If iotHubName is NULL, this function shall return NULL. ]*/
+        /*Codes_SRS_IOTHUBTRANSPORT_17_004: [ If iotHubSuffix is NULL, this function shall return NULL. ]*/
+        LogError("Invalid NULL argument, protocol [%p], name [%p], suffix [%p].", protocol, iotHubName, iotHubSuffix);
+        result = NULL;
+    }
+    else if (IoTHubClientCore_LL_GetTransportCallbacks(&transport_cb) != 0)
+    {
+        LogError("Failure getting transport callbacks");
+        result = NULL;
+    }
+    else
+    {
+        /*Codes_SRS_IOTHUBTRANSPORT_17_032: [ IoTHubTransport_Create shall allocate memory for the transport data. ]*/
+        result = (TRANSPORT_HANDLE_DATA*)malloc(sizeof(TRANSPORT_HANDLE_DATA));
+        if (result == NULL)
+        {
+            /*Codes_SRS_IOTHUBTRANSPORT_17_040: [ If memory allocation fails, IoTHubTransport_Create shall return NULL. ]*/
+            LogError("Transport handle was not allocated.");
+        }
+        else
+        {
+            TRANSPORT_PROVIDER * transportProtocol = (TRANSPORT_PROVIDER*)(protocol());
+            IOTHUB_CLIENT_CONFIG upperConfig;
+            upperConfig.deviceId = NULL;
+            upperConfig.deviceKey = NULL;
+            upperConfig.iotHubName = iotHubName;
+            upperConfig.iotHubSuffix = iotHubSuffix;
+            upperConfig.protocol = protocol;
+            upperConfig.protocolGatewayHostName = NULL;
+
+            IOTHUBTRANSPORT_CONFIG transportLLConfig;
+            memset(&transportLLConfig, 0, sizeof(IOTHUBTRANSPORT_CONFIG));
+            transportLLConfig.upperConfig = &upperConfig;
+            transportLLConfig.waitingToSend = NULL;
+
+            /*Codes_SRS_IOTHUBTRANSPORT_17_005: [ IoTHubTransport_Create shall create the lower layer transport by calling the protocol's IoTHubTransport_Create function. ]*/
+            result->transportLLHandle = transportProtocol->IoTHubTransport_Create(&transportLLConfig, &transport_cb, NULL);
+            if (result->transportLLHandle == NULL)
+            {
+                /*Codes_SRS_IOTHUBTRANSPORT_17_006: [ If the creation of the transport fails, IoTHubTransport_Create shall return NULL. ]*/
+                LogError("Lower Layer transport not created.");
+                free(result);
+                result = NULL;
+            }
+            else
+            {
+                /*Codes_SRS_IOTHUBTRANSPORT_17_007: [ IoTHubTransport_Create shall create the transport lock by Calling Lock_Init. ]*/
+                result->lockHandle = Lock_Init();
+                if (result->lockHandle == NULL)
+                {
+                    /*Codes_SRS_IOTHUBTRANSPORT_17_008: [ If the lock creation fails, IoTHubTransport_Create shall return NULL. ]*/
+                    LogError("transport Lock not created.");
+                    transportProtocol->IoTHubTransport_Destroy(result->transportLLHandle);
+                    free(result);
+                    result = NULL;
+                }
+                else if ((result->clientsLockHandle = Lock_Init()) == NULL)
+                {
+                    LogError("clients Lock not created.");
+                    Lock_Deinit(result->lockHandle);
+                    transportProtocol->IoTHubTransport_Destroy(result->transportLLHandle);
+                    free(result);
+                    result = NULL;
+                }
+                else
+                {
+                    /*Codes_SRS_IOTHUBTRANSPORT_17_038: [ IoTHubTransport_Create shall call VECTOR_Create to make a list of IOTHUB_CLIENT_CORE_HANDLE using this transport. ]*/
+                    result->clients = VECTOR_create(sizeof(IOTHUB_CLIENT_CORE_HANDLE));
+                    if (result->clients == NULL)
+                    {
+                        /*Codes_SRS_IOTHUBTRANSPORT_17_039: [ If the Vector creation fails, IoTHubTransport_Create shall return NULL. ]*/
+                        /*Codes_SRS_IOTHUBTRANSPORT_17_009: [ IoTHubTransport_Create shall clean up any resources it creates if the function does not succeed. ]*/
+                        LogError("clients list not created.");
+                        Lock_Deinit(result->clientsLockHandle);
+                        Lock_Deinit(result->lockHandle);
+                        transportProtocol->IoTHubTransport_Destroy(result->transportLLHandle);
+                        free(result);
+                        result = NULL;
+                    }
+                    else
+                    {
+                        /*Codes_SRS_IOTHUBTRANSPORT_17_001: [ IoTHubTransport_Create shall return a non-NULL handle on success.]*/
+                        result->stopThread = 1;
+                        result->clientDoWork = NULL;
+                        result->workerThreadHandle = NULL; /* create thread when work needs to be done */
+                        result->IoTHubTransport_GetHostname = transportProtocol->IoTHubTransport_GetHostname;
+                        result->IoTHubTransport_SetOption = transportProtocol->IoTHubTransport_SetOption;
+                        result->IoTHubTransport_Create = transportProtocol->IoTHubTransport_Create;
+                        result->IoTHubTransport_Destroy = transportProtocol->IoTHubTransport_Destroy;
+                        result->IoTHubTransport_Register = transportProtocol->IoTHubTransport_Register;
+                        result->IoTHubTransport_Unregister = transportProtocol->IoTHubTransport_Unregister;
+                        result->IoTHubTransport_Subscribe = transportProtocol->IoTHubTransport_Subscribe;
+                        result->IoTHubTransport_Unsubscribe = transportProtocol->IoTHubTransport_Unsubscribe;
+                        result->IoTHubTransport_DoWork = transportProtocol->IoTHubTransport_DoWork;
+                        result->IoTHubTransport_SetRetryPolicy = transportProtocol->IoTHubTransport_SetRetryPolicy;
+                        result->IoTHubTransport_GetSendStatus = transportProtocol->IoTHubTransport_GetSendStatus;
+                    }
+                }
+            }
+        }
+    }
+
+    return result;
+}
+
+static void multiplexed_client_do_work(TRANSPORT_HANDLE_DATA* transportData)
+{
+    if (Lock(transportData->clientsLockHandle) != LOCK_OK)
+    {
+        LogError("failed to lock for multiplexed_client_do_work");
+    }
+    else
+    {
+        size_t numberOfClients;
+        size_t iterator;
+
+        numberOfClients = VECTOR_size(transportData->clients);
+        for (iterator = 0; iterator < numberOfClients; iterator++)
+        {
+            IOTHUB_CLIENT_CORE_HANDLE* clientHandle = (IOTHUB_CLIENT_CORE_HANDLE*)VECTOR_element(transportData->clients, iterator);
+
+            if (clientHandle != NULL)
+            {
+                transportData->clientDoWork(*clientHandle);
+            }
+        }
+
+        if (Unlock(transportData->clientsLockHandle) != LOCK_OK)
+        {
+            LogError("failed to unlock on multiplexed_client_do_work");
+        }
+    }
+}
+
+static int transport_worker_thread(void* threadArgument)
+{
+    TRANSPORT_HANDLE_DATA* transportData = (TRANSPORT_HANDLE_DATA*)threadArgument;
+
+    while (1)
+    {
+        /*Codes_SRS_IOTHUBTRANSPORT_17_030: [ All calls to lower layer transport DoWork shall be protected by the lock created in IoTHubTransport_Create. ]*/
+        if (Lock(transportData->lockHandle) == LOCK_OK)
+        {
+            /*Codes_SRS_IOTHUBTRANSPORT_17_031: [ If acquiring the lock fails, lower layer transport DoWork shall not be called. ]*/
+            if (transportData->stopThread)
+            {
+                /*Codes_SRS_IOTHUBTRANSPORT_17_028: [ The thread shall exit when IoTHubTransport_EndWorkerThread has been called for each clientHandle which invoked IoTHubTransport_StartWorkerThread. ]*/
+                (void)Unlock(transportData->lockHandle);
+                break;
+            }
+            else
+            {
+                (transportData->IoTHubTransport_DoWork)(transportData->transportLLHandle);
+
+                (void)Unlock(transportData->lockHandle);
+            }
+        }
+
+        multiplexed_client_do_work(transportData);
+
+        /*Codes_SRS_IOTHUBTRANSPORT_17_029: [ The thread shall call lower layer transport DoWork every 1 ms. ]*/
+        ThreadAPI_Sleep(1);
+    }
+
+    ThreadAPI_Exit(0);
+    return 0;
+}
+
+static bool find_by_handle(const void* element, const void* value)
+{
+    /* data stored at element is device handle */
+    const IOTHUB_CLIENT_CORE_HANDLE * guess = (const IOTHUB_CLIENT_CORE_HANDLE *)element;
+    const IOTHUB_CLIENT_CORE_HANDLE match = (const IOTHUB_CLIENT_CORE_HANDLE)value;
+    return (*guess == match);
+}
+
+static IOTHUB_CLIENT_RESULT start_worker_if_needed(TRANSPORT_HANDLE_DATA * transportData, IOTHUB_CLIENT_CORE_HANDLE clientHandle)
+{
+    IOTHUB_CLIENT_RESULT result;
+    if (transportData->workerThreadHandle == NULL)
+    {
+        /*Codes_SRS_IOTHUBTRANSPORT_17_018: [ If the worker thread does not exist, IoTHubTransport_StartWorkerThread shall start the thread using ThreadAPI_Create. ]*/
+        transportData->stopThread = 0;
+        if (ThreadAPI_Create(&transportData->workerThreadHandle, transport_worker_thread, transportData) != THREADAPI_OK)
+        {
+            transportData->workerThreadHandle = NULL;
+        }
+    }
+    if (transportData->workerThreadHandle != NULL)
+    {
+        if (Lock(transportData->clientsLockHandle) != LOCK_OK)
+        {
+            LogError("failed to lock for start_worker_if_needed");
+            result = IOTHUB_CLIENT_ERROR;
+        }
+        else
+        {
+            /*Codes_SRS_IOTHUBTRANSPORT_17_020: [ IoTHubTransport_StartWorkerThread shall search for IoTHubClient clientHandle in the list of IoTHubClient handles. ]*/
+            bool addToList = ((VECTOR_size(transportData->clients) == 0) || (VECTOR_find_if(transportData->clients, find_by_handle, clientHandle) == NULL));
+            if (addToList)
+            {
+                /*Codes_SRS_IOTHUBTRANSPORT_17_021: [ If handle is not found, then clientHandle shall be added to the list. ]*/
+                if (VECTOR_push_back(transportData->clients, &clientHandle, 1) != 0)
+                {
+                    LogError("Failed adding device to list (VECTOR_push_back failed)");
+                    /*Codes_SRS_IOTHUBTRANSPORT_17_042: [ If Adding to the client list fails, IoTHubTransport_StartWorkerThread shall return IOTHUB_CLIENT_ERROR. ]*/
+                    result = IOTHUB_CLIENT_ERROR;
+                }
+                else
+                {
+                    result = IOTHUB_CLIENT_OK;
+                }
+            }
+            else
+            {
+                result = IOTHUB_CLIENT_OK;
+            }
+
+            if (Unlock(transportData->clientsLockHandle) != LOCK_OK)
+            {
+                LogError("failed to unlock on start_worker_if_needed");
+            }
+        }
+    }
+    else
+    {
+        result = IOTHUB_CLIENT_ERROR;
+    }
+    return result;
+}
+
+static void stop_worker_thread(TRANSPORT_HANDLE_DATA* transportData)
+{
+    /*Codes_SRS_IOTHUBTRANSPORT_17_043: [** IoTHubTransport_SignalEndWorkerThread shall signal the worker thread to end.*/
+    if (Lock(transportData->lockHandle) != LOCK_OK)
+    {
+        // Need to setup a critical error function here to inform the user that an critical error
+        // has occured.
+        LogError("Unable to lock - will still attempt to end thread without thread safety");
+        transportData->stopThread = 1;
+    }
+    else
+    {
+        transportData->stopThread = 1;
+        (void)Unlock(transportData->lockHandle);
+    }
+
+}
+
+static void wait_worker_thread(TRANSPORT_HANDLE_DATA * transportData)
+{
+    if (transportData->workerThreadHandle != NULL)
+    {
+        int res;
+        /*Codes_SRS_IOTHUBTRANSPORT_17_027: [ If handle list is empty, IoTHubTransport_EndWorkerThread shall be joined. ]*/
+        if (ThreadAPI_Join(transportData->workerThreadHandle, &res) != THREADAPI_OK)
+        {
+            LogError("ThreadAPI_Join failed");
+        }
+        else
+        {
+            transportData->workerThreadHandle = NULL;
+        }
+    }
+}
+
+static bool signal_end_worker_thread(TRANSPORT_HANDLE_DATA * transportData, IOTHUB_CLIENT_CORE_HANDLE clientHandle)
+{
+    bool okToJoin;
+
+    if (Lock(transportData->clientsLockHandle) != LOCK_OK)
+    {
+        LogError("failed to lock for signal_end_worker_thread");
+        okToJoin = false;
+    }
+    else
+    {
+        void* element = VECTOR_find_if(transportData->clients, find_by_handle, clientHandle);
+        if (element != NULL)
+        {
+            /*Codes_SRS_IOTHUBTRANSPORT_17_026: [ IoTHubTransport_EndWorkerThread shall remove clientHandlehandle from handle list. ]*/
+            VECTOR_erase(transportData->clients, element, 1);
+        }
+        /*Codes_SRS_IOTHUBTRANSPORT_17_025: [ If the worker thread does not exist, then IoTHubTransport_EndWorkerThread shall return. ]*/
+        if (transportData->workerThreadHandle != NULL)
+        {
+            if (VECTOR_size(transportData->clients) == 0)
+            {
+                stop_worker_thread(transportData);
+                okToJoin = true;
+            }
+            else
+            {
+                okToJoin = false;
+            }
+        }
+        else
+        {
+            okToJoin = false;
+        }
+
+        if (Unlock(transportData->clientsLockHandle) != LOCK_OK)
+        {
+            LogError("failed to unlock on signal_end_worker_thread");
+        }
+    }
+    return okToJoin;
+}
+
+void IoTHubTransport_Destroy(TRANSPORT_HANDLE transportHandle)
+{
+    /*Codes_SRS_IOTHUBTRANSPORT_17_011: [ IoTHubTransport_Destroy shall do nothing if transportHandle is NULL. ]*/
+    if (transportHandle != NULL)
+    {
+        TRANSPORT_HANDLE_DATA * transportData = (TRANSPORT_HANDLE_DATA*)transportHandle;
+        /*Codes_SRS_IOTHUBTRANSPORT_17_033: [ IoTHubTransport_Destroy shall lock the transport lock. ]*/
+        stop_worker_thread(transportData);
+        wait_worker_thread(transportData);
+        /*Codes_SRS_IOTHUBTRANSPORT_17_010: [ IoTHubTransport_Destroy shall free all resources. ]*/
+        Lock_Deinit(transportData->lockHandle);
+        (transportData->IoTHubTransport_Destroy)(transportData->transportLLHandle);
+        VECTOR_destroy(transportData->clients);
+        Lock_Deinit(transportData->clientsLockHandle);
+        free(transportHandle);
+    }
+}
+
+LOCK_HANDLE IoTHubTransport_GetLock(TRANSPORT_HANDLE transportHandle)
+{
+    LOCK_HANDLE lock;
+    if (transportHandle == NULL)
+    {
+        /*Codes_SRS_IOTHUBTRANSPORT_17_013: [ If transportHandle is NULL, IoTHubTransport_GetLock shall return NULL. ]*/
+        lock = NULL;
+    }
+    else
+    {
+        /*Codes_SRS_IOTHUBTRANSPORT_17_012: [ IoTHubTransport_GetLock shall return a handle to the transport lock. ]*/
+        TRANSPORT_HANDLE_DATA * transportData = (TRANSPORT_HANDLE_DATA*)transportHandle;
+        lock = transportData->lockHandle;
+    }
+    return lock;
+}
+
+TRANSPORT_LL_HANDLE IoTHubTransport_GetLLTransport(TRANSPORT_HANDLE transportHandle)
+{
+    TRANSPORT_LL_HANDLE llTransport;
+    if (transportHandle == NULL)
+    {
+        /*Codes_SRS_IOTHUBTRANSPORT_17_015: [ If transportHandle is NULL, IoTHubTransport_GetLLTransport shall return NULL. ]*/
+        llTransport = NULL;
+    }
+    else
+    {
+        /*Codes_SRS_IOTHUBTRANSPORT_17_014: [ IoTHubTransport_GetLLTransport shall return a handle to the lower layer transport. ]*/
+        TRANSPORT_HANDLE_DATA * transportData = (TRANSPORT_HANDLE_DATA*)transportHandle;
+        llTransport = transportData->transportLLHandle;
+    }
+    return llTransport;
+}
+
+IOTHUB_CLIENT_RESULT IoTHubTransport_StartWorkerThread(TRANSPORT_HANDLE transportHandle, IOTHUB_CLIENT_CORE_HANDLE clientHandle, IOTHUB_CLIENT_MULTIPLEXED_DO_WORK muxDoWork)
+{
+    IOTHUB_CLIENT_RESULT result;
+    if (transportHandle == NULL || clientHandle == NULL)
+    {
+        /*Codes_SRS_IOTHUBTRANSPORT_17_016: [ If transportHandle is NULL, IoTHubTransport_StartWorkerThread shall return IOTHUB_CLIENT_INVALID_ARG. ]*/
+        /*Codes_SRS_IOTHUBTRANSPORT_17_017: [ If clientHandle is NULL, IoTHubTransport_StartWorkerThread shall return IOTHUB_CLIENT_INVALID_ARG. ]*/
+        result = IOTHUB_CLIENT_INVALID_ARG;
+    }
+    else
+    {
+        TRANSPORT_HANDLE_DATA * transportData = (TRANSPORT_HANDLE_DATA*)transportHandle;
+
+        if (transportData->clientDoWork == NULL)
+        {
+            transportData->clientDoWork = muxDoWork;
+        }
+
+        if ((result = start_worker_if_needed(transportData, clientHandle)) != IOTHUB_CLIENT_OK)
+        {
+            /*Codes_SRS_IOTHUBTRANSPORT_17_019: [ If thread creation fails, IoTHubTransport_StartWorkerThread shall return IOTHUB_CLIENT_ERROR. */
+            LogError("Unable to start thread safely");
+        }
+        else
+        {
+            /*Codes_SRS_IOTHUBTRANSPORT_17_022: [ Upon success, IoTHubTransport_StartWorkerThread shall return IOTHUB_CLIENT_OK. ]*/
+            result = IOTHUB_CLIENT_OK;
+        }
+    }
+    return result;
+}
+
+bool IoTHubTransport_SignalEndWorkerThread(TRANSPORT_HANDLE transportHandle, IOTHUB_CLIENT_CORE_HANDLE clientHandle)
+{
+    bool okToJoin;
+    /*Codes_SRS_IOTHUBTRANSPORT_17_023: [ If transportHandle is NULL, IoTHubTransport_EndWorkerThread shall return. ]*/
+    /*Codes_SRS_IOTHUBTRANSPORT_17_024: [ If clientHandle is NULL, IoTHubTransport_EndWorkerThread shall return. ]*/
+    if (!(transportHandle == NULL || clientHandle == NULL))
+    {
+        TRANSPORT_HANDLE_DATA * transportData = (TRANSPORT_HANDLE_DATA*)transportHandle;
+        okToJoin = signal_end_worker_thread(transportData, clientHandle);
+    }
+    else
+    {
+        okToJoin = false;
+    }
+    return okToJoin;
+}
+
+void IoTHubTransport_JoinWorkerThread(TRANSPORT_HANDLE transportHandle, IOTHUB_CLIENT_CORE_HANDLE clientHandle)
+{
+    /*Codes_SRS_IOTHUBTRANSPORT_17_044: [ If transportHandle is NULL, IoTHubTransport_JoinWorkerThread shall do nothing. ]*/
+    /*Codes_SRS_IOTHUBTRANSPORT_17_045: [ If clientHandle is NULL, IoTHubTransport_JoinWorkerThread shall do nothing. ]*/
+    if (!(transportHandle == NULL || clientHandle == NULL))
+    {
+        TRANSPORT_HANDLE_DATA * transportData = (TRANSPORT_HANDLE_DATA*)transportHandle;
+        /*Codes_SRS_IOTHUBTRANSPORT_17_027: [ The worker thread shall be joined. ]*/
+        wait_worker_thread(transportData);
+    }
+}
Index: azure_iot_hub_f767zi/trunk/azure_iot_sdk/iothub_client/src/iothubtransport_mqtt_common.c
===================================================================
--- azure_iot_hub_f767zi/trunk/azure_iot_sdk/iothub_client/src/iothubtransport_mqtt_common.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/azure_iot_sdk/iothub_client/src/iothubtransport_mqtt_common.c	(revision 457)
@@ -0,0 +1,3700 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+#include <stdlib.h>
+#include <ctype.h>
+
+#include "azure_c_shared_utility/optimize_size.h"
+#include "azure_c_shared_utility/gballoc.h"
+#include "azure_c_shared_utility/xlogging.h"
+#include "azure_c_shared_utility/strings.h"
+#include "azure_c_shared_utility/doublylinkedlist.h"
+#include "azure_c_shared_utility/crt_abstractions.h"
+#include "azure_c_shared_utility/agenttime.h"
+#include "azure_c_shared_utility/threadapi.h"
+#include "azure_c_shared_utility/sastoken.h"
+#include "azure_c_shared_utility/tickcounter.h"
+#include "azure_c_shared_utility/tlsio.h"
+#include "azure_c_shared_utility/platform.h"
+#include "azure_c_shared_utility/string_tokenizer.h"
+#include "azure_c_shared_utility/shared_util_options.h"
+#include "azure_c_shared_utility/urlencode.h"
+
+#include "internal/iothub_client_private.h"
+#include "internal/iothub_client_retry_control.h"
+#include "internal/iothub_transport_ll_private.h"
+#include "internal/iothubtransport_mqtt_common.h"
+#include "internal/iothubtransport.h"
+#include "internal/iothub_internal_consts.h"
+
+#include "azure_umqtt_c/mqtt_client.h"
+
+#include "iothub_client_options.h"
+#include "iothub_client_version.h"
+
+#include <stdarg.h>
+#include <stdio.h>
+
+#include <limits.h>
+#include <inttypes.h>
+
+#define SAS_REFRESH_MULTIPLIER              .8
+#define EPOCH_TIME_T_VALUE                  0
+#define DEFAULT_MQTT_KEEPALIVE              4*60 // 4 min
+#define DEFAULT_CONNACK_TIMEOUT             30 // 30 seconds
+#define BUILD_CONFIG_USERNAME               24
+#define SAS_TOKEN_DEFAULT_LEN               10
+#define RESEND_TIMEOUT_VALUE_MIN            1*60
+#define MAX_SEND_RECOUNT_LIMIT              2
+#define DEFAULT_CONNECTION_INTERVAL         30
+#define FAILED_CONN_BACKOFF_VALUE           5
+#define STATUS_CODE_FAILURE_VALUE           500
+#define STATUS_CODE_TIMEOUT_VALUE           408
+
+#define DEFAULT_RETRY_POLICY                IOTHUB_CLIENT_RETRY_EXPONENTIAL_BACKOFF_WITH_JITTER
+#define DEFAULT_RETRY_TIMEOUT_IN_SECONDS    0
+#define MAX_DISCONNECT_VALUE                50
+
+#define ON_DEMAND_GET_TWIN_REQUEST_TIMEOUT_SECS    60
+#define TWIN_REPORT_UPDATE_TIMEOUT_SECS           (60*5)
+
+static const char TOPIC_DEVICE_TWIN_PREFIX[] = "$iothub/twin";
+static const char TOPIC_DEVICE_METHOD_PREFIX[] = "$iothub/methods";
+
+static const char* TOPIC_GET_DESIRED_STATE = "$iothub/twin/res/#";
+static const char* TOPIC_NOTIFICATION_STATE = "$iothub/twin/PATCH/properties/desired/#";
+
+static const char* TOPIC_DEVICE_MSG = "devices/%s/messages/devicebound/#";
+static const char* TOPIC_DEVICE_MODULE_MSG = "devices/%s/modules/%s/messages/devicebound/#";
+static const char* TOPIC_DEVICE_DEVICE = "devices/%s/messages/events/";
+static const char* TOPIC_DEVICE_DEVICE_MODULE = "devices/%s/modules/%s/messages/events/";
+
+static const char* TOPIC_INPUT_QUEUE_NAME = "devices/%s/modules/%s/#";
+
+static const char* TOPIC_DEVICE_METHOD_SUBSCRIBE = "$iothub/methods/POST/#";
+
+static const char* PROPERTY_SEPARATOR = "&";
+static const char* REPORTED_PROPERTIES_TOPIC = "$iothub/twin/PATCH/properties/reported/?$rid=%"PRIu16;
+static const char* GET_PROPERTIES_TOPIC = "$iothub/twin/GET/?$rid=%"PRIu16;
+static const char* DEVICE_METHOD_RESPONSE_TOPIC = "$iothub/methods/res/%d/?$rid=%s";
+
+static const char* REQUEST_ID_PROPERTY = "?$rid=";
+
+static const char* MESSAGE_ID_PROPERTY = "mid";
+static const char* CORRELATION_ID_PROPERTY = "cid";
+static const char* CONTENT_TYPE_PROPERTY = "ct";
+static const char* CONTENT_ENCODING_PROPERTY = "ce";
+static const char* DIAGNOSTIC_ID_PROPERTY = "diagid";
+static const char* DIAGNOSTIC_CONTEXT_PROPERTY = "diagctx";
+static const char* CONNECTION_DEVICE_ID = "cdid";
+static const char* CONNECTION_MODULE_ID_PROPERTY = "cmid";
+
+static const char* DIAGNOSTIC_CONTEXT_CREATION_TIME_UTC_PROPERTY = "creationtimeutc";
+
+static const char DT_MODEL_ID_TOKEN[] = "model-id";
+
+static const char DEFAULT_IOTHUB_PRODUCT_IDENTIFIER[] = CLIENT_DEVICE_TYPE_PREFIX "/" IOTHUB_SDK_VERSION;
+
+#define TOLOWER(c) (((c>='A') && (c<='Z'))?c-'A'+'a':c)
+
+#define UNSUBSCRIBE_FROM_TOPIC                  0x0000
+#define SUBSCRIBE_GET_REPORTED_STATE_TOPIC      0x0001
+#define SUBSCRIBE_NOTIFICATION_STATE_TOPIC      0x0002
+#define SUBSCRIBE_TELEMETRY_TOPIC               0x0004
+#define SUBSCRIBE_DEVICE_METHOD_TOPIC           0x0008
+#define SUBSCRIBE_INPUT_QUEUE_TOPIC             0x0010
+#define SUBSCRIBE_TOPIC_COUNT                   5
+
+MU_DEFINE_ENUM_STRINGS_WITHOUT_INVALID(MQTT_CLIENT_EVENT_ERROR, MQTT_CLIENT_EVENT_ERROR_VALUES)
+
+typedef struct SYSTEM_PROPERTY_INFO_TAG
+{
+    const char* propName;
+    size_t propLength;
+} SYSTEM_PROPERTY_INFO;
+
+static SYSTEM_PROPERTY_INFO sysPropList[] = {
+    { "%24.exp", 7 },
+    { "%24.mid", 7 },
+    { "%24.uid", 7 },
+    { "%24.to", 6 },
+    { "%24.cid", 7 },
+    { "%24.ct", 6 },
+    { "%24.ce", 6 },
+    { "devices/", 8 },
+    { "iothub-operation", 16 },
+    { "iothub-ack", 10 },
+    { "%24.on", 6 },
+    { "%24.cdid", 8 },
+    { "%24.cmid", 8 }
+};
+
+static const int slashes_to_reach_input_name = 5;
+
+typedef enum DEVICE_TWIN_MSG_TYPE_TAG
+{
+    REPORTED_STATE,
+    RETRIEVE_PROPERTIES
+} DEVICE_TWIN_MSG_TYPE;
+
+typedef enum MQTT_TRANSPORT_CREDENTIAL_TYPE_TAG
+{
+    CREDENTIAL_NOT_BUILD,
+    X509,
+    SAS_TOKEN_FROM_USER,
+    DEVICE_KEY,
+} MQTT_TRANSPORT_CREDENTIAL_TYPE;
+
+typedef enum MQTT_CLIENT_STATUS_TAG
+{
+    MQTT_CLIENT_STATUS_NOT_CONNECTED,
+    MQTT_CLIENT_STATUS_CONNECTING,
+    MQTT_CLIENT_STATUS_CONNECTED,
+    MQTT_CLIENT_STATUS_PENDING_CLOSE,
+    MQTT_CLIENT_STATUS_EXECUTE_DISCONNECT
+} MQTT_CLIENT_STATUS;
+
+typedef struct MQTTTRANSPORT_HANDLE_DATA_TAG
+{
+    // Topic control
+    STRING_HANDLE topic_MqttEvent;
+    STRING_HANDLE topic_MqttMessage;
+    STRING_HANDLE topic_GetState;
+    STRING_HANDLE topic_NotifyState;
+    STRING_HANDLE topic_InputQueue;
+
+    STRING_HANDLE topic_DeviceMethods;
+
+    uint32_t topics_ToSubscribe;
+
+    // Connection related constants
+    STRING_HANDLE hostAddress;
+    STRING_HANDLE device_id;
+    STRING_HANDLE module_id;
+    STRING_HANDLE devicesAndModulesPath;
+    int portNum;
+    // conn_attempted indicates whether a connection has *ever* been attempted on the lifetime
+    // of this handle.  Even if a given xio transport is added/removed, this always stays true.
+    bool conn_attempted;
+
+    MQTT_GET_IO_TRANSPORT get_io_transport;
+
+    // The current mqtt iothub implementation requires that the hub name and the domain suffix be passed as the first of a series of segments
+    // passed through the username portion of the connection frame.
+    // The second segment will contain the device id.  The two segments are delemited by a "/".
+    // The first segment can be a maximum 256 characters.
+    // The second segment can be a maximum 128 characters.
+    // With the / delimeter you have 384 chars (Plus a terminator of 0).
+    STRING_HANDLE configPassedThroughUsername;
+
+    // Protocol
+    MQTT_CLIENT_HANDLE mqttClient;
+    XIO_HANDLE xioTransport;
+
+    // Session - connection
+    uint16_t packetId;
+    uint16_t twin_resp_packet_id;
+
+    // Connection state control
+    bool isRegistered;
+    MQTT_CLIENT_STATUS mqttClientStatus;
+    bool isDestroyCalled;
+    bool isRetryExpiredCallbackSet;
+    bool device_twin_get_sent;
+    bool twin_resp_sub_recv;
+    bool isRecoverableError;
+    uint16_t keepAliveValue;
+    uint16_t connect_timeout_in_sec;
+    tickcounter_ms_t mqtt_connect_time;
+    size_t connectFailCount;
+    tickcounter_ms_t connectTick;
+    bool log_trace;
+    bool raw_trace;
+    TICK_COUNTER_HANDLE msgTickCounter;
+    OPTIONHANDLER_HANDLE saved_tls_options; // Here are the options from the xio layer if any is saved.
+
+    // Internal lists for message tracking
+    PDLIST_ENTRY waitingToSend;
+    DLIST_ENTRY ack_waiting_queue;
+
+    DLIST_ENTRY pending_get_twin_queue;
+
+    // Message tracking
+    CONTROL_PACKET_TYPE currPacketState;
+
+    // Telemetry specific
+    DLIST_ENTRY telemetry_waitingForAck;
+    bool auto_url_encode_decode;
+
+    // Controls frequency of reconnection logic.
+    RETRY_CONTROL_HANDLE retry_control_handle;
+
+    // Auth module used to generating handle authorization
+    // with either SAS Token, x509 Certs, and Device SAS Token
+    IOTHUB_AUTHORIZATION_HANDLE authorization_module;
+
+    TRANSPORT_CALLBACKS_INFO transport_callbacks;
+    void* transport_ctx;
+
+    char* http_proxy_hostname;
+    int http_proxy_port;
+    char* http_proxy_username;
+    char* http_proxy_password;
+    bool isConnectUsernameSet;
+    int disconnect_recv_flag;
+} MQTTTRANSPORT_HANDLE_DATA, *PMQTTTRANSPORT_HANDLE_DATA;
+
+typedef struct MQTT_DEVICE_TWIN_ITEM_TAG
+{
+    tickcounter_ms_t msgCreationTime;
+    tickcounter_ms_t msgPublishTime;
+    size_t retryCount;
+    uint16_t packet_id;
+    uint32_t iothub_msg_id;
+    IOTHUB_DEVICE_TWIN* device_twin_data;
+    DEVICE_TWIN_MSG_TYPE device_twin_msg_type;
+    DLIST_ENTRY entry;
+    IOTHUB_CLIENT_DEVICE_TWIN_CALLBACK userCallback;
+    void* userContext;
+} MQTT_DEVICE_TWIN_ITEM;
+
+typedef struct MQTT_MESSAGE_DETAILS_LIST_TAG
+{
+    tickcounter_ms_t msgPublishTime;
+    size_t retryCount;
+    IOTHUB_MESSAGE_LIST* iotHubMessageEntry;
+    void* context;
+    uint16_t packet_id;
+    DLIST_ENTRY entry;
+} MQTT_MESSAGE_DETAILS_LIST, *PMQTT_MESSAGE_DETAILS_LIST;
+
+typedef struct DEVICE_METHOD_INFO_TAG
+{
+    STRING_HANDLE request_id;
+} DEVICE_METHOD_INFO;
+
+static void free_proxy_data(MQTTTRANSPORT_HANDLE_DATA* mqtt_transport_instance)
+{
+    if (mqtt_transport_instance->http_proxy_hostname != NULL)
+    {
+        free(mqtt_transport_instance->http_proxy_hostname);
+        mqtt_transport_instance->http_proxy_hostname = NULL;
+    }
+
+    if (mqtt_transport_instance->http_proxy_username != NULL)
+    {
+        free(mqtt_transport_instance->http_proxy_username);
+        mqtt_transport_instance->http_proxy_username = NULL;
+    }
+
+    if (mqtt_transport_instance->http_proxy_password != NULL)
+    {
+        free(mqtt_transport_instance->http_proxy_password);
+        mqtt_transport_instance->http_proxy_password = NULL;
+    }
+}
+
+// Destroys xio transport associated with MQTT handle and resets appropriate state
+static void DestroyXioTransport(PMQTTTRANSPORT_HANDLE_DATA transport_data)
+{
+    xio_destroy(transport_data->xioTransport);
+    transport_data->xioTransport = NULL;
+}
+
+static void set_saved_tls_options(PMQTTTRANSPORT_HANDLE_DATA transport, OPTIONHANDLER_HANDLE new_options)
+{
+    if (transport->saved_tls_options != NULL)
+    {
+        OptionHandler_Destroy(transport->saved_tls_options);
+    }
+    transport->saved_tls_options = new_options;
+}
+
+static void free_transport_handle_data(MQTTTRANSPORT_HANDLE_DATA* transport_data)
+{
+    if (transport_data->mqttClient != NULL)
+    {
+        mqtt_client_deinit(transport_data->mqttClient);
+    }
+
+    if (transport_data->retry_control_handle != NULL)
+    {
+        retry_control_destroy(transport_data->retry_control_handle);
+    }
+
+    set_saved_tls_options(transport_data, NULL);
+
+    tickcounter_destroy(transport_data->msgTickCounter);
+
+    free_proxy_data(transport_data);
+
+    STRING_delete(transport_data->devicesAndModulesPath);
+    STRING_delete(transport_data->topic_MqttEvent);
+    STRING_delete(transport_data->topic_MqttMessage);
+    STRING_delete(transport_data->device_id);
+    STRING_delete(transport_data->module_id);
+    STRING_delete(transport_data->hostAddress);
+    STRING_delete(transport_data->configPassedThroughUsername);
+    STRING_delete(transport_data->topic_GetState);
+    STRING_delete(transport_data->topic_NotifyState);
+    STRING_delete(transport_data->topic_DeviceMethods);
+    STRING_delete(transport_data->topic_InputQueue);
+
+    DestroyXioTransport(transport_data);
+
+    free(transport_data);
+}
+
+int IoTHubTransport_MQTT_Common_SetRetryPolicy(TRANSPORT_LL_HANDLE handle, IOTHUB_CLIENT_RETRY_POLICY retryPolicy, size_t retryTimeoutLimitInSeconds)
+{
+    int result;
+
+    if (handle == NULL)
+    {
+        /* Codes_SRS_IOTHUB_TRANSPORT_MQTT_COMMON_25_041: [**If any handle is NULL then IoTHubTransport_MQTT_Common_SetRetryPolicy shall return resultant line.] */
+        LogError("Invalid handle parameter. NULL.");
+        result = MU_FAILURE;
+    }
+    else
+    {
+        RETRY_CONTROL_HANDLE new_retry_control_handle;
+
+        // Codes_SRS_IOTHUB_TRANSPORT_MQTT_COMMON_09_006: [ IoTHubTransport_MQTT_Common_SetRetryPolicy shall set the retry logic by calling retry_control_create() with retry policy and retryTimeout as parameters]
+        // Codes_SRS_IOTHUB_TRANSPORT_MQTT_COMMON_09_009: [ If retry_control_create() fails then IoTHubTransport_MQTT_Common_SetRetryPolicy shall revert to previous retry policy and return non-zero value ]
+        if ((new_retry_control_handle = retry_control_create(retryPolicy, (unsigned int)retryTimeoutLimitInSeconds)) == NULL)
+        {
+            LogError("Failed creating new retry control handle");
+            result = MU_FAILURE;
+        }
+        else
+        {
+            PMQTTTRANSPORT_HANDLE_DATA transport_data = (PMQTTTRANSPORT_HANDLE_DATA)handle;
+            RETRY_CONTROL_HANDLE previous_retry_control_handle = transport_data->retry_control_handle;
+
+            transport_data->retry_control_handle = new_retry_control_handle;
+            retry_control_destroy(previous_retry_control_handle);
+
+            /*Codes_SRS_IOTHUB_TRANSPORT_MQTT_COMMON_25_045: [**If retry logic for specified parameters of retry policy and retryTimeoutLimitInSeconds is created successfully then IoTHubTransport_MQTT_Common_SetRetryPolicy shall return 0]*/
+            result = 0;
+        }
+    }
+
+    return result;
+}
+
+static uint16_t get_next_packet_id(PMQTTTRANSPORT_HANDLE_DATA transport_data)
+{
+    if (transport_data->packetId + 1 >= USHRT_MAX)
+    {
+        transport_data->packetId = 1;
+    }
+    else
+    {
+        transport_data->packetId++;
+    }
+    return transport_data->packetId;
+}
+
+#ifndef NO_LOGGING
+static const char* retrieve_mqtt_return_codes(CONNECT_RETURN_CODE rtn_code)
+{
+    switch (rtn_code)
+    {
+        case CONNECTION_ACCEPTED:
+            return "Accepted";
+        case CONN_REFUSED_UNACCEPTABLE_VERSION:
+            return "Unacceptable Version";
+        case CONN_REFUSED_ID_REJECTED:
+            return "Id Rejected";
+        case CONN_REFUSED_SERVER_UNAVAIL:
+            return "Server Unavailable";
+        case CONN_REFUSED_BAD_USERNAME_PASSWORD:
+            return "Bad Username/Password";
+        case CONN_REFUSED_NOT_AUTHORIZED:
+            return "Not Authorized";
+        case CONN_REFUSED_UNKNOWN:
+        default:
+            return "Unknown";
+    }
+}
+#endif // NO_LOGGING
+
+static int retrieve_device_method_rid_info(const char* resp_topic, STRING_HANDLE method_name, STRING_HANDLE request_id)
+{
+    int result;
+
+    STRING_TOKENIZER_HANDLE token_handle = STRING_TOKENIZER_create_from_char(resp_topic);
+    if (token_handle == NULL)
+    {
+        LogError("Failed creating token from device twin topic.");
+        result = MU_FAILURE;
+    }
+    else
+    {
+        STRING_HANDLE token_value;
+        if ((token_value = STRING_new()) == NULL)
+        {
+            LogError("Failed allocating new string .");
+            result = MU_FAILURE;
+        }
+        else
+        {
+            size_t token_index = 0;
+            size_t request_id_length = strlen(REQUEST_ID_PROPERTY);
+            result = MU_FAILURE;
+            while (STRING_TOKENIZER_get_next_token(token_handle, token_value, "/") == 0)
+            {
+                if (token_index == 3)
+                {
+                    if (STRING_concat_with_STRING(method_name, token_value) != 0)
+                    {
+                        LogError("Failed STRING_concat_with_STRING.");
+                        result = MU_FAILURE;
+                        break;
+                    }
+                }
+                else if (token_index == 4)
+                {
+                    if (STRING_length(token_value) >= request_id_length)
+                    {
+                        const char* request_id_value = STRING_c_str(token_value);
+                        if (memcmp(request_id_value, REQUEST_ID_PROPERTY, request_id_length) == 0)
+                        {
+                            if (STRING_concat(request_id, request_id_value + request_id_length) != 0)
+                            {
+                                LogError("Failed STRING_concat failed.");
+                                result = MU_FAILURE;
+                            }
+                            else
+                            {
+                                result = 0;
+                            }
+                            break;
+                        }
+                    }
+                }
+                token_index++;
+            }
+            STRING_delete(token_value);
+        }
+        STRING_TOKENIZER_destroy(token_handle);
+    }
+
+    return result;
+}
+
+static int parse_device_twin_topic_info(const char* resp_topic, bool* patch_msg, size_t* request_id, int* status_code)
+{
+    int result;
+    STRING_TOKENIZER_HANDLE token_handle = STRING_TOKENIZER_create_from_char(resp_topic);
+    if (token_handle == NULL)
+    {
+        LogError("Failed creating token from device twin topic.");
+        result = MU_FAILURE;
+        *status_code = 0;
+        *request_id = 0;
+        *patch_msg = false;
+    }
+    else
+    {
+        STRING_HANDLE token_value;
+        if ((token_value = STRING_new()) == NULL)
+        {
+            LogError("Failed allocating new string .");
+            result = MU_FAILURE;
+            *status_code = 0;
+            *request_id = 0;
+            *patch_msg = false;
+        }
+        else
+        {
+            result = MU_FAILURE;
+            size_t token_count = 0;
+            while (STRING_TOKENIZER_get_next_token(token_handle, token_value, "/") == 0)
+            {
+                if (token_count == 2)
+                {
+                    if (strcmp(STRING_c_str(token_value), "PATCH") == 0)
+                    {
+                        *patch_msg = true;
+                        *status_code = 0;
+                        *request_id = 0;
+                        result = 0;
+                        break;
+                    }
+                    else
+                    {
+                        *patch_msg = false;
+                    }
+                }
+                else if (token_count == 3)
+                {
+                    *status_code = (int)atol(STRING_c_str(token_value));
+                    if (STRING_TOKENIZER_get_next_token(token_handle, token_value, "/?$rid=") == 0)
+                    {
+                        *request_id = (size_t)atol(STRING_c_str(token_value));
+                    }
+                    *patch_msg = false;
+                    result = 0;
+                    break;
+                }
+                token_count++;
+            }
+            STRING_delete(token_value);
+        }
+        STRING_TOKENIZER_destroy(token_handle);
+    }
+    return result;
+}
+
+static int InternStrnicmp(const char* s1, const char* s2, size_t n)
+{
+    int result;
+
+    if (s1 == NULL) result = -1;
+    else if (s2 == NULL) result = 1;
+    else
+    {
+        result = 0;
+
+        while (n-- && result == 0)
+        {
+            if (*s1 == 0) result = -1;
+            else if (*s2 == 0) result = 1;
+            else
+            {
+
+                result = TOLOWER(*s1) - TOLOWER(*s2);
+                ++s1;
+                ++s2;
+            }
+        }
+    }
+    return result;
+}
+
+static IOTHUB_IDENTITY_TYPE retrieve_topic_type(const char* topic_resp, const char* input_queue)
+{
+    IOTHUB_IDENTITY_TYPE type;
+    if (InternStrnicmp(topic_resp, TOPIC_DEVICE_TWIN_PREFIX, sizeof(TOPIC_DEVICE_TWIN_PREFIX) - 1) == 0)
+    {
+        type = IOTHUB_TYPE_DEVICE_TWIN;
+    }
+    else if (InternStrnicmp(topic_resp, TOPIC_DEVICE_METHOD_PREFIX, sizeof(TOPIC_DEVICE_METHOD_PREFIX) - 1) == 0)
+    {
+        type = IOTHUB_TYPE_DEVICE_METHODS;
+    }
+    // input_queue contains additional "#" from subscribe, which we strip off on comparing incoming.
+    else if ((input_queue != NULL) && InternStrnicmp(topic_resp, input_queue, strlen(input_queue) - 1) == 0)
+    {
+        type = IOTHUB_TYPE_EVENT_QUEUE;
+    }
+    else
+    {
+        type = IOTHUB_TYPE_TELEMETRY;
+    }
+    return type;
+
+}
+
+static void sendMsgComplete(IOTHUB_MESSAGE_LIST* iothubMsgList, PMQTTTRANSPORT_HANDLE_DATA transport_data, IOTHUB_CLIENT_CONFIRMATION_RESULT confirmResult)
+{
+    DLIST_ENTRY messageCompleted;
+    DList_InitializeListHead(&messageCompleted);
+    DList_InsertTailList(&messageCompleted, &(iothubMsgList->entry));
+    transport_data->transport_callbacks.send_complete_cb(&messageCompleted, confirmResult, transport_data->transport_ctx);
+}
+
+static int addUserPropertiesTouMqttMessage(IOTHUB_MESSAGE_HANDLE iothub_message_handle, STRING_HANDLE topic_string, size_t* index_ptr, bool urlencode)
+{
+    int result = 0;
+    const char* const* propertyKeys;
+    const char* const* propertyValues;
+    size_t propertyCount;
+    size_t index = *index_ptr;
+    MAP_HANDLE properties_map = IoTHubMessage_Properties(iothub_message_handle);
+    if (properties_map != NULL)
+    {
+        if (Map_GetInternals(properties_map, &propertyKeys, &propertyValues, &propertyCount) != MAP_OK)
+        {
+            LogError("Failed to get the internals of the property map.");
+            result = MU_FAILURE;
+        }
+        else
+        {
+            if (propertyCount != 0)
+            {
+                for (index = 0; index < propertyCount && result == 0; index++)
+                {
+                    if (urlencode)
+                    {
+                        STRING_HANDLE property_key = URL_EncodeString(propertyKeys[index]);
+                        STRING_HANDLE property_value = URL_EncodeString(propertyValues[index]);
+                        if ((property_key == NULL) || (property_value == NULL))
+                        {
+                            LogError("Failed URL Encoding properties");
+                            result = MU_FAILURE;
+                        }
+                        else if (STRING_sprintf(topic_string, "%s=%s%s", STRING_c_str(property_key), STRING_c_str(property_value), propertyCount - 1 == index ? "" : PROPERTY_SEPARATOR) != 0)
+                        {
+                            LogError("Failed constructing property string.");
+                            result = MU_FAILURE;
+                        }
+                        STRING_delete(property_key);
+                        STRING_delete(property_value);
+                    }
+                    else
+                    {
+                        if (STRING_sprintf(topic_string, "%s=%s%s", propertyKeys[index], propertyValues[index], propertyCount - 1 == index ? "" : PROPERTY_SEPARATOR) != 0)
+                        {
+                            LogError("Failed constructing property string.");
+                            result = MU_FAILURE;
+                        }
+                    }
+                }
+            }
+        }
+    }
+    *index_ptr = index;
+    return result;
+}
+
+static int addSystemPropertyToTopicString(STRING_HANDLE topic_string, size_t index, const char* property_key, const char* property_value, bool urlencode)
+{
+    int result = 0;
+
+    if (urlencode)
+    {
+        STRING_HANDLE encoded_property_value = URL_EncodeString(property_value);
+        if (encoded_property_value == NULL)
+        {
+            LogError("Failed URL encoding %s.", property_key);
+            result = MU_FAILURE;
+        }
+        else if (STRING_sprintf(topic_string, "%s%%24.%s=%s", index == 0 ? "" : PROPERTY_SEPARATOR, property_key, STRING_c_str(encoded_property_value)) != 0)
+        {
+            LogError("Failed setting %s.", property_key);
+            result = MU_FAILURE;
+        }
+        STRING_delete(encoded_property_value);
+    }
+    else
+    {
+        if (STRING_sprintf(topic_string, "%s%%24.%s=%s", index == 0 ? "" : PROPERTY_SEPARATOR, property_key, property_value) != 0)
+        {
+            LogError("Failed setting %s.", property_key);
+            result = MU_FAILURE;
+        }
+    }
+    return result;
+}
+
+static int addSystemPropertiesTouMqttMessage(IOTHUB_MESSAGE_HANDLE iothub_message_handle, STRING_HANDLE topic_string, size_t* index_ptr, bool urlencode)
+{
+    int result = 0;
+    size_t index = *index_ptr;
+
+    bool is_security_msg = IoTHubMessage_IsSecurityMessage(iothub_message_handle);
+    /* Codes_SRS_IOTHUB_TRANSPORT_MQTT_COMMON_07_052: [ IoTHubTransport_MQTT_Common_DoWork shall check for the CorrelationId property and if found add the value as a system property in the format of $.cid=<id> ] */
+    const char* correlation_id = IoTHubMessage_GetCorrelationId(iothub_message_handle);
+    if (correlation_id != NULL)
+    {
+        result = addSystemPropertyToTopicString(topic_string, index, CORRELATION_ID_PROPERTY, correlation_id, urlencode);
+        index++;
+    }
+    /* Codes_SRS_IOTHUB_TRANSPORT_MQTT_COMMON_07_053: [ IoTHubTransport_MQTT_Common_DoWork shall check for the MessageId property and if found add the value as a system property in the format of $.mid=<id> ] */
+    if (result == 0)
+    {
+        const char* msg_id = IoTHubMessage_GetMessageId(iothub_message_handle);
+        if (msg_id != NULL)
+        {
+            result = addSystemPropertyToTopicString(topic_string, index, MESSAGE_ID_PROPERTY, msg_id, urlencode);
+            index++;
+        }
+    }
+    // Codes_SRS_IOTHUB_TRANSPORT_MQTT_COMMON_09_010: [ `IoTHubTransport_MQTT_Common_DoWork` shall check for the ContentType property and if found add the `value` as a system property in the format of `$.ct=<value>` ]
+    if (result == 0)
+    {
+        const char* content_type = IoTHubMessage_GetContentTypeSystemProperty(iothub_message_handle);
+        if (content_type != NULL)
+        {
+            result = addSystemPropertyToTopicString(topic_string, index, CONTENT_TYPE_PROPERTY, content_type, urlencode);
+            index++;
+        }
+    }
+    // Codes_SRS_IOTHUB_TRANSPORT_MQTT_COMMON_09_011: [ `IoTHubTransport_MQTT_Common_DoWork` shall check for the ContentEncoding property and if found add the `value` as a system property in the format of `$.ce=<value>` ]
+    if (result == 0)
+    {
+        const char* content_encoding = IoTHubMessage_GetContentEncodingSystemProperty(iothub_message_handle);
+        if (content_encoding != NULL)
+        {
+            // Security message require content encoding
+            result = addSystemPropertyToTopicString(topic_string, index, CONTENT_ENCODING_PROPERTY, content_encoding, is_security_msg ? true : urlencode);
+            index++;
+        }
+    }
+    if (result == 0)
+    {
+        if (is_security_msg)
+        {
+            // The Security interface Id value must be encoded
+            if (addSystemPropertyToTopicString(topic_string, index++, SECURITY_INTERFACE_ID_MQTT, SECURITY_INTERFACE_ID_VALUE, true) != 0)
+            {
+                LogError("Failed setting Security interface id");
+                result = MU_FAILURE;
+            }
+            else
+            {
+                result = 0;
+            }
+        }
+    }
+    *index_ptr = index;
+    return result;
+}
+
+static int addDiagnosticPropertiesTouMqttMessage(IOTHUB_MESSAGE_HANDLE iothub_message_handle, STRING_HANDLE topic_string, size_t* index_ptr)
+{
+    int result = 0;
+    size_t index = *index_ptr;
+
+    // Codes_SRS_IOTHUB_TRANSPORT_MQTT_COMMON_09_014: [ `IoTHubTransport_MQTT_Common_DoWork` shall check for the diagnostic properties including diagid and diagCreationTimeUtc and if found both add them as system property in the format of `$.diagid` and `$.diagctx` respectively]
+    const IOTHUB_MESSAGE_DIAGNOSTIC_PROPERTY_DATA* diagnosticData = IoTHubMessage_GetDiagnosticPropertyData(iothub_message_handle);
+    if (diagnosticData != NULL)
+    {
+        const char* diag_id = diagnosticData->diagnosticId;
+        const char* creation_time_utc = diagnosticData->diagnosticCreationTimeUtc;
+        //diagid and creationtimeutc must be present/unpresent simultaneously
+        if (diag_id != NULL && creation_time_utc != NULL)
+        {
+            if (STRING_sprintf(topic_string, "%s%%24.%s=%s", index == 0 ? "" : PROPERTY_SEPARATOR, DIAGNOSTIC_ID_PROPERTY, diag_id) != 0)
+            {
+                LogError("Failed setting diagnostic id");
+                result = MU_FAILURE;
+            }
+            index++;
+
+            if (result == 0)
+            {
+                //construct diagnostic context, it should be urlencode(key1=value1,key2=value2)
+                STRING_HANDLE diagContextHandle = STRING_construct_sprintf("%s=%s", DIAGNOSTIC_CONTEXT_CREATION_TIME_UTC_PROPERTY, creation_time_utc);
+                if (diagContextHandle == NULL)
+                {
+                    LogError("Failed constructing diagnostic context");
+                    result = MU_FAILURE;
+                }
+                else
+                {
+                    //Add other diagnostic context properties here if have more
+                    STRING_HANDLE encodedContextValueHandle = URL_Encode(diagContextHandle);
+                    const char* encodedContextValueString = NULL;
+                    if (encodedContextValueHandle != NULL &&
+                        (encodedContextValueString = STRING_c_str(encodedContextValueHandle)) != NULL)
+                    {
+                        if (STRING_sprintf(topic_string, "%s%%24.%s=%s", index == 0 ? "" : PROPERTY_SEPARATOR, DIAGNOSTIC_CONTEXT_PROPERTY, encodedContextValueString) != 0)
+                        {
+                            LogError("Failed setting diagnostic context");
+                            result = MU_FAILURE;
+                        }
+                        STRING_delete(encodedContextValueHandle);
+                        encodedContextValueHandle = NULL;
+                    }
+                    else
+                    {
+                        LogError("Failed encoding diagnostic context value");
+                        result = MU_FAILURE;
+                    }
+                    STRING_delete(diagContextHandle);
+                    diagContextHandle = NULL;
+                    index++;
+                }
+            }
+        }
+        else if (diag_id != NULL || creation_time_utc != NULL)
+        {
+            // Codes_SRS_IOTHUB_TRANSPORT_MQTT_COMMON_09_015: [ `IoTHubTransport_MQTT_Common_DoWork` shall check whether diagid and diagCreationTimeUtc be present simultaneously, treat as error if not]
+            LogError("diagid and diagcreationtimeutc must be present simultaneously.");
+            result = MU_FAILURE;
+        }
+    }
+    return result;
+}
+
+
+static STRING_HANDLE addPropertiesTouMqttMessage(IOTHUB_MESSAGE_HANDLE iothub_message_handle, const char* eventTopic, bool urlencode)
+{
+    size_t index = 0;
+    STRING_HANDLE result = STRING_construct(eventTopic);
+    if (result == NULL)
+    {
+        LogError("Failed to create event topic string handle");
+    }
+    else if (addUserPropertiesTouMqttMessage(iothub_message_handle, result, &index, urlencode) != 0)
+    {
+        LogError("Failed adding Properties to uMQTT Message");
+        STRING_delete(result);
+        result = NULL;
+    }
+    else if (addSystemPropertiesTouMqttMessage(iothub_message_handle, result, &index, urlencode) != 0)
+    {
+        LogError("Failed adding System Properties to uMQTT Message");
+        STRING_delete(result);
+        result = NULL;
+    }
+    else if (addDiagnosticPropertiesTouMqttMessage(iothub_message_handle, result, &index) != 0)
+    {
+        LogError("Failed adding Diagnostic Properties to uMQTT Message");
+        STRING_delete(result);
+        result = NULL;
+    }
+
+    // Codes_SRS_IOTHUB_TRANSPORT_MQTT_COMMON_31_060: [ `IoTHubTransport_MQTT_Common_DoWork` shall check for the OutputName property and if found add the value as a system property in the format of $.on=<value> ]
+    if (result != NULL)
+    {
+        const char* output_name = IoTHubMessage_GetOutputName(iothub_message_handle);
+        if (output_name != NULL)
+        {
+            if (STRING_sprintf(result, "%s%%24.on=%s/", index == 0 ? "" : PROPERTY_SEPARATOR, output_name) != 0)
+            {
+                LogError("Failed setting output name.");
+                STRING_delete(result);
+                result = NULL;
+            }
+            index++;
+        }
+    }
+
+    return result;
+}
+
+static int publish_mqtt_telemetry_msg(PMQTTTRANSPORT_HANDLE_DATA transport_data, MQTT_MESSAGE_DETAILS_LIST* mqttMsgEntry, const unsigned char* payload, size_t len)
+{
+    int result;
+    STRING_HANDLE msgTopic = addPropertiesTouMqttMessage(mqttMsgEntry->iotHubMessageEntry->messageHandle, STRING_c_str(transport_data->topic_MqttEvent), transport_data->auto_url_encode_decode);
+    if (msgTopic == NULL)
+    {
+        LogError("Failed adding properties to mqtt message");
+        result = MU_FAILURE;
+    }
+    else
+    {
+        MQTT_MESSAGE_HANDLE mqttMsg = mqttmessage_create_in_place(mqttMsgEntry->packet_id, STRING_c_str(msgTopic), DELIVER_AT_LEAST_ONCE, payload, len);
+        if (mqttMsg == NULL)
+        {
+            LogError("Failed creating mqtt message");
+            result = MU_FAILURE;
+        }
+        else
+        {
+            if (tickcounter_get_current_ms(transport_data->msgTickCounter, &mqttMsgEntry->msgPublishTime) != 0)
+            {
+                LogError("Failed retrieving tickcounter info");
+                result = MU_FAILURE;
+            }
+            else
+            {
+                if (mqtt_client_publish(transport_data->mqttClient, mqttMsg) != 0)
+                {
+                    LogError("Failed attempting to publish mqtt message");
+                    result = MU_FAILURE;
+                }
+                else
+                {
+                    mqttMsgEntry->retryCount++;
+                    result = 0;
+                }
+            }
+            mqttmessage_destroy(mqttMsg);
+        }
+        STRING_delete(msgTopic);
+    }
+    return result;
+}
+
+static int publish_device_method_message(MQTTTRANSPORT_HANDLE_DATA* transport_data, int status_code, STRING_HANDLE request_id, const unsigned char* response, size_t response_size)
+{
+    int result;
+    uint16_t packet_id = get_next_packet_id(transport_data);
+
+    STRING_HANDLE msg_topic = STRING_construct_sprintf(DEVICE_METHOD_RESPONSE_TOPIC, status_code, STRING_c_str(request_id));
+    if (msg_topic == NULL)
+    {
+        LogError("Failed constructing message topic.");
+        result = MU_FAILURE;
+    }
+    else
+    {
+        MQTT_MESSAGE_HANDLE mqtt_get_msg = mqttmessage_create_in_place(packet_id, STRING_c_str(msg_topic), DELIVER_AT_MOST_ONCE, response, response_size);
+        if (mqtt_get_msg == NULL)
+        {
+            LogError("Failed constructing mqtt message.");
+            result = MU_FAILURE;
+        }
+        else
+        {
+            if (mqtt_client_publish(transport_data->mqttClient, mqtt_get_msg) != 0)
+            {
+                LogError("Failed publishing to mqtt client.");
+                result = MU_FAILURE;
+            }
+            else
+            {
+                result = 0;
+            }
+            mqttmessage_destroy(mqtt_get_msg);
+        }
+        STRING_delete(msg_topic);
+    }
+    return result;
+}
+
+
+static void destroy_device_twin_get_message(MQTT_DEVICE_TWIN_ITEM* msg_entry)
+{
+    free(msg_entry);
+}
+
+static MQTT_DEVICE_TWIN_ITEM* create_device_twin_message(MQTTTRANSPORT_HANDLE_DATA* transport_data, DEVICE_TWIN_MSG_TYPE device_twin_msg_type, uint32_t iothub_msg_id)
+{
+    MQTT_DEVICE_TWIN_ITEM* result;
+    tickcounter_ms_t current_time;
+
+    if (tickcounter_get_current_ms(transport_data->msgTickCounter, &current_time) != 0)
+    {
+        LogError("Failed retrieving tickcounter info");
+        result = NULL;
+    }
+    else if ((result = (MQTT_DEVICE_TWIN_ITEM*)malloc(sizeof(MQTT_DEVICE_TWIN_ITEM))) == NULL)
+    {
+        LogError("Failed allocating device twin data.");
+        result = NULL;
+    }
+    else
+    {
+        memset(result, 0, sizeof(*result));
+        result->msgCreationTime = current_time;
+        result->packet_id = get_next_packet_id(transport_data);
+        result->iothub_msg_id = iothub_msg_id;
+        result->device_twin_msg_type = device_twin_msg_type;
+    }
+
+    return result;
+}
+
+static int publish_device_twin_get_message(MQTTTRANSPORT_HANDLE_DATA* transport_data, MQTT_DEVICE_TWIN_ITEM* mqtt_info)
+{
+    int result;
+
+    STRING_HANDLE msg_topic = STRING_construct_sprintf(GET_PROPERTIES_TOPIC, mqtt_info->packet_id);
+    if (msg_topic == NULL)
+    {
+        LogError("Failed constructing get Prop topic.");
+        result = MU_FAILURE;
+    }
+    else
+    {
+        MQTT_MESSAGE_HANDLE mqtt_get_msg = mqttmessage_create(mqtt_info->packet_id, STRING_c_str(msg_topic), DELIVER_AT_MOST_ONCE, NULL, 0);
+        if (mqtt_get_msg == NULL)
+        {
+            LogError("Failed constructing mqtt message.");
+            result = MU_FAILURE;
+        }
+        else
+        {
+            if (mqtt_client_publish(transport_data->mqttClient, mqtt_get_msg) != 0)
+            {
+                LogError("Failed publishing to mqtt client.");
+                result = MU_FAILURE;
+            }
+            else
+            {
+                DList_InsertTailList(&transport_data->ack_waiting_queue, &mqtt_info->entry);
+                result = 0;
+            }
+            mqttmessage_destroy(mqtt_get_msg);
+        }
+        STRING_delete(msg_topic);
+    }
+
+    return result;
+}
+
+static void sendPendingGetTwinRequests(PMQTTTRANSPORT_HANDLE_DATA transportData)
+{
+    PDLIST_ENTRY dev_twin_item = transportData->pending_get_twin_queue.Flink;
+
+    while (dev_twin_item != &transportData->pending_get_twin_queue)
+    {
+        DLIST_ENTRY saveListEntry;
+        saveListEntry.Flink = dev_twin_item->Flink;
+        MQTT_DEVICE_TWIN_ITEM* msg_entry = containingRecord(dev_twin_item, MQTT_DEVICE_TWIN_ITEM, entry);
+        (void)DList_RemoveEntryList(dev_twin_item);
+
+        if (publish_device_twin_get_message(transportData, msg_entry) != 0)
+        {
+            LogError("Failed sending pending get twin request");
+            destroy_device_twin_get_message(msg_entry);
+        }
+        else
+        {
+            transportData->device_twin_get_sent = true;
+        }
+
+        dev_twin_item = saveListEntry.Flink;
+    }
+}
+
+
+static void removeExpiredTwinRequestsFromList(PMQTTTRANSPORT_HANDLE_DATA transport_data, tickcounter_ms_t current_ms, DLIST_ENTRY* twin_list)
+{
+    PDLIST_ENTRY list_item = twin_list->Flink;
+    
+    while (list_item != twin_list)
+    {
+        DLIST_ENTRY next_list_item;
+        next_list_item.Flink = list_item->Flink;
+        MQTT_DEVICE_TWIN_ITEM* msg_entry = containingRecord(list_item, MQTT_DEVICE_TWIN_ITEM, entry);
+        bool item_timed_out = false;
+
+        if ((msg_entry->device_twin_msg_type == RETRIEVE_PROPERTIES) &&
+            (((current_ms - msg_entry->msgCreationTime) / 1000) >= ON_DEMAND_GET_TWIN_REQUEST_TIMEOUT_SECS))
+        {
+            item_timed_out = true;
+            if (msg_entry->userCallback != NULL)
+            {
+                msg_entry->userCallback(DEVICE_TWIN_UPDATE_COMPLETE, NULL, 0, msg_entry->userContext);
+            }
+        }
+        else if ((msg_entry->device_twin_msg_type == REPORTED_STATE) &&
+                 (((current_ms - msg_entry->msgCreationTime) / 1000) >= TWIN_REPORT_UPDATE_TIMEOUT_SECS))
+        {
+            item_timed_out = true;
+            transport_data->transport_callbacks.twin_rpt_state_complete_cb(msg_entry->iothub_msg_id, STATUS_CODE_TIMEOUT_VALUE, transport_data->transport_ctx);
+        }
+
+        if (item_timed_out)
+        {
+            (void)DList_RemoveEntryList(list_item);
+            destroy_device_twin_get_message(msg_entry);
+        }
+
+        list_item = next_list_item.Flink;
+    }
+
+}
+
+static void removeExpiredTwinRequests(PMQTTTRANSPORT_HANDLE_DATA transport_data)
+{
+    tickcounter_ms_t current_ms;
+
+    if (tickcounter_get_current_ms(transport_data->msgTickCounter, &current_ms) == 0)
+    {
+        removeExpiredTwinRequestsFromList(transport_data, current_ms, &transport_data->pending_get_twin_queue);
+        removeExpiredTwinRequestsFromList(transport_data, current_ms, &transport_data->ack_waiting_queue);
+    }
+}
+
+static int publish_device_twin_message(MQTTTRANSPORT_HANDLE_DATA* transport_data, IOTHUB_DEVICE_TWIN* device_twin_info, MQTT_DEVICE_TWIN_ITEM* mqtt_info)
+{
+    int result;
+
+    STRING_HANDLE msgTopic = STRING_construct_sprintf(REPORTED_PROPERTIES_TOPIC, mqtt_info->packet_id);
+    if (msgTopic == NULL)
+    {
+        LogError("Failed constructing reported prop topic.");
+        result = MU_FAILURE;
+    }
+    else
+    {
+        const CONSTBUFFER* data_buff;
+        if ((data_buff = CONSTBUFFER_GetContent(device_twin_info->report_data_handle)) == NULL)
+        {
+            LogError("Failed retrieving buffer content");
+            result = MU_FAILURE;
+        }
+        else
+        {
+            MQTT_MESSAGE_HANDLE mqtt_rpt_msg = mqttmessage_create_in_place(mqtt_info->packet_id, STRING_c_str(msgTopic), DELIVER_AT_MOST_ONCE, data_buff->buffer, data_buff->size);
+            if (mqtt_rpt_msg == NULL)
+            {
+                LogError("Failed creating mqtt message");
+                result = MU_FAILURE;
+            }
+            else
+            {
+                if (tickcounter_get_current_ms(transport_data->msgTickCounter, &mqtt_info->msgPublishTime) != 0)
+                {
+                    LogError("Failed retrieving tickcounter info");
+                    result = MU_FAILURE;
+                }
+                else
+                {
+                    if (mqtt_client_publish(transport_data->mqttClient, mqtt_rpt_msg) != 0)
+                    {
+                        LogError("Failed publishing mqtt message");
+                        result = MU_FAILURE;
+                    }
+                    else
+                    {
+                        mqtt_info->retryCount++;
+                        result = 0;
+                    }
+                }
+                mqttmessage_destroy(mqtt_rpt_msg);
+            }
+        }
+        STRING_delete(msgTopic);
+    }
+    return result;
+}
+
+static void changeStateToSubscribeIfAllowed(PMQTTTRANSPORT_HANDLE_DATA transport_data)
+{
+    if (transport_data->currPacketState != CONNACK_TYPE &&
+        transport_data->currPacketState != CONNECT_TYPE &&
+        transport_data->currPacketState != DISCONNECT_TYPE &&
+        transport_data->currPacketState != PACKET_TYPE_ERROR)
+    {
+        transport_data->currPacketState = SUBSCRIBE_TYPE;
+    }
+}
+
+static int subscribeToNotifyStateIfNeeded(PMQTTTRANSPORT_HANDLE_DATA transport_data)
+{
+    int result;
+
+    if (transport_data->topic_NotifyState == NULL)
+    {
+        transport_data->topic_NotifyState = STRING_construct(TOPIC_NOTIFICATION_STATE);
+        if (transport_data->topic_NotifyState == NULL)
+        {
+            LogError("Failure: unable constructing notify state topic");
+            result = MU_FAILURE;
+        }
+        else
+        {
+            transport_data->topics_ToSubscribe |= SUBSCRIBE_NOTIFICATION_STATE_TOPIC;
+            result = 0;
+        }
+    }
+    else
+    {
+        result = 0;
+    }
+
+    if (result == 0)
+    {
+        changeStateToSubscribeIfAllowed(transport_data);
+    }
+
+    return result;
+}
+
+
+static bool isSystemProperty(const char* tokenData)
+{
+    bool result = false;
+    size_t propCount = sizeof(sysPropList) / sizeof(sysPropList[0]);
+    size_t index = 0;
+    for (index = 0; index < propCount; index++)
+    {
+        if (memcmp(tokenData, sysPropList[index].propName, sysPropList[index].propLength) == 0)
+        {
+            result = true;
+            break;
+        }
+    }
+    return result;
+}
+
+// Codes_SRS_IOTHUB_TRANSPORT_MQTT_COMMON_31_061: [ If the message is sent to an input queue, `IoTHubTransport_MQTT_Common_DoWork` shall parse out to the input queue name and store it in the message with IoTHubMessage_SetInputName ]
+// Codes_SRS_IOTHUB_TRANSPORT_MQTT_COMMON_31_062: [ If IoTHubTransport_MQTT_Common_DoWork receives a malformatted inputQueue, it shall fail ]
+static int addInputNamePropertyToMessage(IOTHUB_MESSAGE_HANDLE IoTHubMessage, const char* topic_name)
+{
+    int result = MU_FAILURE;
+    int number_tokens_read = 0;
+
+    STRING_TOKENIZER_HANDLE token_handle = STRING_TOKENIZER_create_from_char(topic_name);
+    if (token_handle == NULL)
+    {
+        LogError("STRING_TOKENIZER_create_from_char failed\n");
+        result = MU_FAILURE;
+    }
+    else
+    {
+        STRING_HANDLE token_value;
+        if ((token_value = STRING_new()) == NULL)
+        {
+            LogError("Failed allocating token_value");
+        }
+        else
+        {
+            while (STRING_TOKENIZER_get_next_token(token_handle, token_value, "/") == 0)
+            {
+                number_tokens_read++;
+                if (number_tokens_read == (slashes_to_reach_input_name + 1))
+                {
+                    if ((IOTHUB_MESSAGE_OK != IoTHubMessage_SetInputName(IoTHubMessage, STRING_c_str(token_value))))
+                    {
+                        LogError("Failed adding input name to msg");
+                        result = MU_FAILURE;
+                    }
+                    else
+                    {
+                        result = 0;
+                    }
+                    break;
+                }
+            }
+        }
+        STRING_delete(token_value);
+
+        if (number_tokens_read != (slashes_to_reach_input_name + 1))
+        {
+            LogError("Not enough '/' to contain input name.  Got %d, need at least %d", number_tokens_read, (slashes_to_reach_input_name + 1));
+            result = MU_FAILURE;
+        }
+        STRING_TOKENIZER_destroy(token_handle);
+    }
+
+    return result;
+}
+
+static int setMqttMessagePropertyIfPossible(IOTHUB_MESSAGE_HANDLE IoTHubMessage, const char* propName, const char* propValue, size_t nameLen)
+{
+    // Not finding a system property to map to isn't an error.
+    int result = 0;
+
+    if (nameLen > 4)
+    {
+        if (strcmp((const char*)&propName[nameLen - 4], CONNECTION_DEVICE_ID) == 0)
+        {
+            // Codes_SRS_IOTHUB_TRANSPORT_MQTT_COMMON_31_063: [ If type is IOTHUB_TYPE_TELEMETRY and the system property `$.cdid` is defined, its value shall be set on the IOTHUB_MESSAGE_HANDLE's ConnectionDeviceId property ]
+            if (IoTHubMessage_SetConnectionDeviceId(IoTHubMessage, propValue) != IOTHUB_MESSAGE_OK)
+            {
+                LogError("Failed to set IOTHUB_MESSAGE_HANDLE 'messageId' property.");
+                result = MU_FAILURE;
+            }
+            return result;
+        }
+        if (strcmp((const char*)&propName[nameLen - 4], CONNECTION_MODULE_ID_PROPERTY) == 0)
+        {
+            // Codes_SRS_IOTHUB_TRANSPORT_MQTT_COMMON_31_064: [ If type is IOTHUB_TYPE_TELEMETRY and the system property `$.cmid` is defined, its value shall be set on the IOTHUB_MESSAGE_HANDLE's ConnectionModuleId property ]
+            if (IoTHubMessage_SetConnectionModuleId(IoTHubMessage, propValue) != IOTHUB_MESSAGE_OK)
+            {
+                LogError("Failed to set IOTHUB_MESSAGE_HANDLE 'correlationId' property.");
+                result = MU_FAILURE;
+            }
+            return result;
+        }
+    }
+    if (nameLen > 3)
+    {
+        if (strcmp((const char*)&propName[nameLen - 3], MESSAGE_ID_PROPERTY) == 0)
+        {
+            if (IoTHubMessage_SetMessageId(IoTHubMessage, propValue) != IOTHUB_MESSAGE_OK)
+            {
+                LogError("Failed to set IOTHUB_MESSAGE_HANDLE 'messageId' property.");
+                result = MU_FAILURE;
+            }
+            return result;
+        }
+        else if (strcmp((const char*)&propName[nameLen - 3], CORRELATION_ID_PROPERTY) == 0)
+        {
+            if (IoTHubMessage_SetCorrelationId(IoTHubMessage, propValue) != IOTHUB_MESSAGE_OK)
+            {
+                LogError("Failed to set IOTHUB_MESSAGE_HANDLE 'correlationId' property.");
+                result = MU_FAILURE;
+            }
+            return result;
+        }
+    }
+
+    if (nameLen > 2)
+    {
+        // Codes_SRS_IOTHUB_TRANSPORT_MQTT_COMMON_09_012: [ If type is IOTHUB_TYPE_TELEMETRY and the system property `$.ct` is defined, its value shall be set on the IOTHUB_MESSAGE_HANDLE's ContentType property ]
+        if (strcmp((const char*)&propName[nameLen - 2], CONTENT_TYPE_PROPERTY) == 0)
+        {
+            if (IoTHubMessage_SetContentTypeSystemProperty(IoTHubMessage, propValue) != IOTHUB_MESSAGE_OK)
+            {
+                LogError("Failed to set IOTHUB_MESSAGE_HANDLE 'customContentType' property.");
+                result = MU_FAILURE;
+            }
+            return result;
+        }
+        // Codes_SRS_IOTHUB_TRANSPORT_MQTT_COMMON_09_013: [ If type is IOTHUB_TYPE_TELEMETRY and the system property `$.ce` is defined, its value shall be set on the IOTHUB_MESSAGE_HANDLE's ContentEncoding property ]
+        else if (strcmp((const char*)&propName[nameLen - 2], CONTENT_ENCODING_PROPERTY) == 0)
+        {
+            if (IoTHubMessage_SetContentEncodingSystemProperty(IoTHubMessage, propValue) != IOTHUB_MESSAGE_OK)
+            {
+                LogError("Failed to set IOTHUB_MESSAGE_HANDLE 'contentEncoding' property.");
+                result = MU_FAILURE;
+            }
+            return result;
+        }
+    }
+
+    return result;
+}
+
+static int extractMqttProperties(IOTHUB_MESSAGE_HANDLE IoTHubMessage, const char* topic_name, bool urldecode)
+{
+    int result;
+    STRING_TOKENIZER_HANDLE token = STRING_TOKENIZER_create_from_char(topic_name);
+    if (token != NULL)
+    {
+        MAP_HANDLE propertyMap = IoTHubMessage_Properties(IoTHubMessage);
+        if (propertyMap == NULL)
+        {
+            LogError("Failure to retrieve IoTHubMessage_properties.");
+            result = MU_FAILURE;
+        }
+        else
+        {
+            STRING_HANDLE output = STRING_new();
+            if (output == NULL)
+            {
+                LogError("Failure to allocate STRING_new.");
+                result = MU_FAILURE;
+            }
+            else
+            {
+                result = 0;
+
+                while (STRING_TOKENIZER_get_next_token(token, output, PROPERTY_SEPARATOR) == 0 && result == 0)
+                {
+                    const char* tokenData = STRING_c_str(output);
+                    size_t tokenLen = strlen(tokenData);
+                    if (tokenData == NULL || tokenLen == 0)
+                    {
+                        break;
+                    }
+                    else
+                    {
+                        if (isSystemProperty(tokenData))
+                        {
+                            const char* iterator = tokenData;
+                            while (iterator != NULL && *iterator != '\0' && result == 0)
+                            {
+                                if (*iterator == '=')
+                                {
+                                    char* propName = NULL;
+                                    char* propValue = NULL;
+                                    size_t nameLen = iterator - tokenData;
+                                    size_t valLen = tokenLen - (nameLen + 1) + 1;
+
+                                    if ((propName = malloc(nameLen + 1)) == NULL || (propValue = malloc(valLen + 1)) == NULL)
+                                    {
+                                        LogError("Failed allocating property name (%p) and/or value (%p)", propName, propValue);
+                                        free(propName);
+                                        result = MU_FAILURE;
+                                    }
+                                    else
+                                    {
+                                        memcpy(propName, tokenData, nameLen);
+                                        propName[nameLen] = '\0';
+
+                                        memcpy(propValue, iterator + 1, valLen);
+                                        propValue[valLen] = '\0';
+
+                                        if (urldecode)
+                                        {
+                                            STRING_HANDLE propValue_decoded;
+                                            if ((propValue_decoded = URL_DecodeString(propValue)) == NULL)
+                                            {
+                                                LogError("Failed to URL decode property value");
+                                                result = MU_FAILURE;
+                                            }
+                                            else if (setMqttMessagePropertyIfPossible(IoTHubMessage, propName, STRING_c_str(propValue_decoded), nameLen) != 0)
+                                            {
+                                                LogError("Unable to set message property");
+                                                result = MU_FAILURE;
+                                            }
+                                            STRING_delete(propValue_decoded);
+                                        }
+                                        else
+                                        {
+                                            if (setMqttMessagePropertyIfPossible(IoTHubMessage, propName, propValue, nameLen) != 0)
+                                            {
+                                                LogError("Unable to set message property");
+                                                result = MU_FAILURE;
+                                            }
+                                        }
+                                        free(propName);
+                                        free(propValue);
+                                    }
+                                    break;
+                                }
+                                iterator++;
+                            }
+                        }
+                        else //User Properties
+                        {
+                            const char* iterator = tokenData;
+                            while (iterator != NULL && *iterator != '\0' && result == 0)
+                            {
+                                if (*iterator == '=')
+                                {
+                                    char* propName = NULL;
+                                    char* propValue = NULL;
+                                    size_t nameLen = iterator - tokenData;
+                                    size_t valLen = tokenLen - (nameLen + 1) + 1;
+
+                                    if ((propName = (char*)malloc(nameLen + 1)) == NULL || (propValue = (char*)malloc(valLen + 1)) == NULL)
+                                    {
+                                        free(propName);
+                                        LogError("Failed allocating property information");
+                                        result = MU_FAILURE;
+                                    }
+                                    else
+                                    {
+                                        memcpy(propName, tokenData, nameLen);
+                                        propName[nameLen] = '\0';
+
+                                        memcpy(propValue, iterator + 1, valLen);
+                                        propValue[valLen] = '\0';
+
+                                        if (urldecode)
+                                        {
+                                            STRING_HANDLE propName_decoded = URL_DecodeString(propName);
+                                            STRING_HANDLE propValue_decoded = URL_DecodeString(propValue);
+                                            if (propName_decoded == NULL || propValue_decoded == NULL)
+                                            {
+                                                LogError("Failed to URL decode property");
+                                                result = MU_FAILURE;
+                                            }
+                                            else if (Map_AddOrUpdate(propertyMap, STRING_c_str(propName_decoded), STRING_c_str(propValue_decoded)) != MAP_OK)
+                                            {
+                                                LogError("Map_AddOrUpdate failed.");
+                                                result = MU_FAILURE;
+                                            }
+                                            STRING_delete(propName_decoded);
+                                            STRING_delete(propValue_decoded);
+                                        }
+                                        else
+                                        {
+                                            if (Map_AddOrUpdate(propertyMap, propName, propValue) != MAP_OK)
+                                            {
+                                                LogError("Map_AddOrUpdate failed.");
+                                                result = MU_FAILURE;
+                                            }
+                                        }
+                                        free(propName);
+                                        free(propValue);
+                                    }
+                                    break;
+                                }
+                                iterator++;
+                            }
+                        }
+                    }
+                }
+                STRING_delete(output);
+            }
+        }
+        STRING_TOKENIZER_destroy(token);
+    }
+    else
+    {
+        LogError("Unable to create Tokenizer object.");
+        result = MU_FAILURE;
+    }
+    return result;
+}
+
+static void mqtt_notification_callback(MQTT_MESSAGE_HANDLE msgHandle, void* callbackCtx)
+{
+    /* Tests_SRS_IOTHUB_MQTT_TRANSPORT_07_051: [ If msgHandle or callbackCtx is NULL, mqtt_notification_callback shall do nothing. ] */
+    if (msgHandle != NULL && callbackCtx != NULL)
+    {
+        /* Tests_SRS_IOTHUB_MQTT_TRANSPORT_07_052: [ mqtt_notification_callback shall extract the topic Name from the MQTT_MESSAGE_HANDLE. ] */
+        const char* topic_resp = mqttmessage_getTopicName(msgHandle);
+        if (topic_resp == NULL)
+        {
+            LogError("Failure: NULL topic name encountered");
+        }
+        else
+        {
+            PMQTTTRANSPORT_HANDLE_DATA transportData = (PMQTTTRANSPORT_HANDLE_DATA)callbackCtx;
+
+            IOTHUB_IDENTITY_TYPE type = retrieve_topic_type(topic_resp, STRING_c_str(transportData->topic_InputQueue));
+            if (type == IOTHUB_TYPE_DEVICE_TWIN)
+            {
+                size_t request_id;
+                int status_code;
+                bool notification_msg;
+                if (parse_device_twin_topic_info(topic_resp, &notification_msg, &request_id, &status_code) != 0)
+                {
+                    LogError("Failure: parsing device topic info");
+                }
+                else
+                {
+                    const APP_PAYLOAD* payload = mqttmessage_getApplicationMsg(msgHandle);
+                    if (notification_msg)
+                    {
+                        transportData->transport_callbacks.twin_retrieve_prop_complete_cb(DEVICE_TWIN_UPDATE_PARTIAL, payload->message, payload->length, transportData->transport_ctx);
+                    }
+                    else
+                    {
+                        PDLIST_ENTRY dev_twin_item = transportData->ack_waiting_queue.Flink;
+                        while (dev_twin_item != &transportData->ack_waiting_queue)
+                        {
+                            DLIST_ENTRY saveListEntry;
+                            saveListEntry.Flink = dev_twin_item->Flink;
+                            MQTT_DEVICE_TWIN_ITEM* msg_entry = containingRecord(dev_twin_item, MQTT_DEVICE_TWIN_ITEM, entry);
+                            if (request_id == msg_entry->packet_id)
+                            {
+                                (void)DList_RemoveEntryList(dev_twin_item);
+                                if (msg_entry->device_twin_msg_type == RETRIEVE_PROPERTIES)
+                                {
+                                    if (msg_entry->userCallback == NULL)
+                                    {
+                                        /* Codes_SRS_IOTHUB_MQTT_TRANSPORT_07_054: [ If type is IOTHUB_TYPE_DEVICE_TWIN, then on success if msg_type is RETRIEVE_PROPERTIES then mqtt_notification_callback shall call IoTHubClientCore_LL_RetrievePropertyComplete... ] */
+                                        transportData->transport_callbacks.twin_retrieve_prop_complete_cb(DEVICE_TWIN_UPDATE_COMPLETE, payload->message, payload->length, transportData->transport_ctx);
+                                        // Only after receiving device twin request should we start listening for patches.
+                                        (void)subscribeToNotifyStateIfNeeded(transportData);
+                                    }
+                                    else
+                                    {
+                                        // This is a on-demand get twin request.
+                                        msg_entry->userCallback(DEVICE_TWIN_UPDATE_COMPLETE, payload->message, payload->length, msg_entry->userContext);
+                                    }
+                                }
+                                else
+                                {
+                                    /* Codes_SRS_IOTHUB_MQTT_TRANSPORT_07_055: [ if device_twin_msg_type is not RETRIEVE_PROPERTIES then mqtt_notification_callback shall call IoTHubClientCore_LL_ReportedStateComplete ] */
+                                    transportData->transport_callbacks.twin_rpt_state_complete_cb(msg_entry->iothub_msg_id, status_code, transportData->transport_ctx);
+                                    // Only after receiving device twin request should we start listening for patches.
+                                    (void)subscribeToNotifyStateIfNeeded(transportData);
+                                }
+
+                                destroy_device_twin_get_message(msg_entry);
+                                break;
+                            }
+                            dev_twin_item = saveListEntry.Flink;
+                        }
+                    }
+                }
+            }
+            else if (type == IOTHUB_TYPE_DEVICE_METHODS)
+            {
+                STRING_HANDLE method_name = STRING_new();
+                if (method_name == NULL)
+                {
+                    LogError("Failure: allocating method_name string value");
+                }
+                else
+                {
+                    DEVICE_METHOD_INFO* dev_method_info = malloc(sizeof(DEVICE_METHOD_INFO));
+                    if (dev_method_info == NULL)
+                    {
+                        LogError("Failure: allocating DEVICE_METHOD_INFO object");
+                    }
+                    else
+                    {
+                        dev_method_info->request_id = STRING_new();
+                        if (dev_method_info->request_id == NULL)
+                        {
+                            LogError("Failure constructing request_id string");
+                            free(dev_method_info);
+                        }
+                        else if (retrieve_device_method_rid_info(topic_resp, method_name, dev_method_info->request_id) != 0)
+                        {
+                            LogError("Failure: retrieve device topic info");
+                            STRING_delete(dev_method_info->request_id);
+                            free(dev_method_info);
+                        }
+                        else
+                        {
+                            /* CodesSRS_IOTHUB_MQTT_TRANSPORT_07_053: [ If type is IOTHUB_TYPE_DEVICE_METHODS, then on success mqtt_notification_callback shall call IoTHubClientCore_LL_DeviceMethodComplete. ] */
+                            const APP_PAYLOAD* payload = mqttmessage_getApplicationMsg(msgHandle);
+                            if (transportData->transport_callbacks.method_complete_cb(STRING_c_str(method_name), payload->message, payload->length, (void*)dev_method_info, transportData->transport_ctx) != 0)
+                            {
+                                LogError("Failure: IoTHubClientCore_LL_DeviceMethodComplete");
+                                STRING_delete(dev_method_info->request_id);
+                                free(dev_method_info);
+                            }
+                        }
+                    }
+                    STRING_delete(method_name);
+                }
+            }
+            else
+            {
+                const APP_PAYLOAD* appPayload = mqttmessage_getApplicationMsg(msgHandle);
+                IOTHUB_MESSAGE_HANDLE IoTHubMessage = IoTHubMessage_CreateFromByteArray(appPayload->message, appPayload->length);
+                if (IoTHubMessage == NULL)
+                {
+                    LogError("Failure: IotHub Message creation has failed.");
+                }
+                else
+                {
+                    if ((type == IOTHUB_TYPE_EVENT_QUEUE) && (addInputNamePropertyToMessage(IoTHubMessage, topic_resp) != 0))
+                    {
+                        LogError("failure adding input name to property.");
+                    }
+                    // Will need to update this when the service has messages that can be rejected
+                    else if (extractMqttProperties(IoTHubMessage, topic_resp, transportData->auto_url_encode_decode) != 0)
+                    {
+                        LogError("failure extracting mqtt properties.");
+                    }
+                    else
+                    {
+                        MESSAGE_CALLBACK_INFO* messageData = (MESSAGE_CALLBACK_INFO*)malloc(sizeof(MESSAGE_CALLBACK_INFO));
+                        if (messageData == NULL)
+                        {
+                            LogError("malloc failed");
+                        }
+                        else
+                        {
+                            messageData->messageHandle = IoTHubMessage;
+                            messageData->transportContext = NULL;
+
+                            if (type == IOTHUB_TYPE_EVENT_QUEUE)
+                            {
+                                // Codes_SRS_IOTHUB_MQTT_TRANSPORT_31_065: [ If type is IOTHUB_TYPE_TELEMETRY and sent to an input queue, then on success `mqtt_notification_callback` shall call `IoTHubClient_LL_MessageCallback`. ]
+                                if (!transportData->transport_callbacks.msg_input_cb(messageData, transportData->transport_ctx))
+                                {
+                                    LogError("IoTHubClientCore_LL_MessageCallbackreturned false");
+
+                                    IoTHubMessage_Destroy(IoTHubMessage);
+                                    free(messageData);
+                                }
+                            }
+                            else
+                            {
+                                /* Codes_SRS_IOTHUB_MQTT_TRANSPORT_07_056: [ If type is IOTHUB_TYPE_TELEMETRY, then on success mqtt_notification_callback shall call IoTHubClientCore_LL_MessageCallback. ] */
+                                if (!transportData->transport_callbacks.msg_cb(messageData, transportData->transport_ctx))
+                                {
+                                    LogError("IoTHubClientCore_LL_MessageCallback returned false");
+                                    IoTHubMessage_Destroy(IoTHubMessage);
+                                    free(messageData);
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+        }
+    }
+}
+
+static void mqtt_operation_complete_callback(MQTT_CLIENT_HANDLE handle, MQTT_CLIENT_EVENT_RESULT actionResult, const void* msgInfo, void* callbackCtx)
+{
+    (void)handle;
+    if (callbackCtx != NULL)
+    {
+        PMQTTTRANSPORT_HANDLE_DATA transport_data = (PMQTTTRANSPORT_HANDLE_DATA)callbackCtx;
+
+        switch (actionResult)
+        {
+            case MQTT_CLIENT_ON_PUBLISH_ACK:
+            case MQTT_CLIENT_ON_PUBLISH_COMP:
+            {
+                const PUBLISH_ACK* puback = (const PUBLISH_ACK*)msgInfo;
+                if (puback != NULL)
+                {
+                    PDLIST_ENTRY currentListEntry = transport_data->telemetry_waitingForAck.Flink;
+                    while (currentListEntry != &transport_data->telemetry_waitingForAck)
+                    {
+                        MQTT_MESSAGE_DETAILS_LIST* mqttMsgEntry = containingRecord(currentListEntry, MQTT_MESSAGE_DETAILS_LIST, entry);
+                        DLIST_ENTRY saveListEntry;
+                        saveListEntry.Flink = currentListEntry->Flink;
+
+                        if (puback->packetId == mqttMsgEntry->packet_id)
+                        {
+                            (void)DList_RemoveEntryList(currentListEntry); //First remove the item from Waiting for Ack List.
+                            sendMsgComplete(mqttMsgEntry->iotHubMessageEntry, transport_data, IOTHUB_CLIENT_CONFIRMATION_OK);
+                            free(mqttMsgEntry);
+                        }
+                        currentListEntry = saveListEntry.Flink;
+                    }
+                }
+                else
+                {
+                    LogError("Failure: MQTT_CLIENT_ON_PUBLISH_ACK publish_ack structure NULL.");
+                }
+                break;
+            }
+            case MQTT_CLIENT_ON_CONNACK:
+            {
+                const CONNECT_ACK* connack = (const CONNECT_ACK*)msgInfo;
+                if (connack != NULL)
+                {
+                    if (connack->returnCode == CONNECTION_ACCEPTED)
+                    {
+                        // The connect packet has been acked
+                        transport_data->currPacketState = CONNACK_TYPE;
+                        transport_data->isRecoverableError = true;
+                        transport_data->mqttClientStatus = MQTT_CLIENT_STATUS_CONNECTED;
+
+                        // Codes_SRS_IOTHUB_TRANSPORT_MQTT_COMMON_09_008: [ Upon successful connection the retry control shall be reset using retry_control_reset() ]
+                        retry_control_reset(transport_data->retry_control_handle);
+
+                        transport_data->transport_callbacks.connection_status_cb(IOTHUB_CLIENT_CONNECTION_AUTHENTICATED, IOTHUB_CLIENT_CONNECTION_OK, transport_data->transport_ctx);
+                    }
+                    else
+                    {
+                        if (connack->returnCode == CONN_REFUSED_SERVER_UNAVAIL)
+                        {
+                            transport_data->transport_callbacks.connection_status_cb(IOTHUB_CLIENT_CONNECTION_UNAUTHENTICATED, IOTHUB_CLIENT_CONNECTION_DEVICE_DISABLED, transport_data->transport_ctx);
+                        }
+                        else if (connack->returnCode == CONN_REFUSED_BAD_USERNAME_PASSWORD || connack->returnCode == CONN_REFUSED_ID_REJECTED)
+                        {
+                            transport_data->isRecoverableError = false;
+                            transport_data->transport_callbacks.connection_status_cb(IOTHUB_CLIENT_CONNECTION_UNAUTHENTICATED, IOTHUB_CLIENT_CONNECTION_BAD_CREDENTIAL, transport_data->transport_ctx);
+                        }
+                        else if (connack->returnCode == CONN_REFUSED_NOT_AUTHORIZED)
+                        {
+                            transport_data->transport_callbacks.connection_status_cb(IOTHUB_CLIENT_CONNECTION_UNAUTHENTICATED, IOTHUB_CLIENT_CONNECTION_BAD_CREDENTIAL, transport_data->transport_ctx);
+                        }
+                        else if (connack->returnCode == CONN_REFUSED_UNACCEPTABLE_VERSION)
+                        {
+                            transport_data->isRecoverableError = false;
+                        }
+                        LogError("Connection Not Accepted: 0x%x: %s", connack->returnCode, retrieve_mqtt_return_codes(connack->returnCode));
+                        transport_data->mqttClientStatus = MQTT_CLIENT_STATUS_PENDING_CLOSE;
+                        transport_data->currPacketState = PACKET_TYPE_ERROR;
+                    }
+                }
+                else
+                {
+                    LogError("MQTT_CLIENT_ON_CONNACK CONNACK parameter is NULL.");
+                }
+                break;
+            }
+            case MQTT_CLIENT_ON_SUBSCRIBE_ACK:
+            {
+                const SUBSCRIBE_ACK* suback = (const SUBSCRIBE_ACK*)msgInfo;
+                if (suback != NULL)
+                {
+                    size_t index = 0;
+                    for (index = 0; index < suback->qosCount; index++)
+                    {
+                        if (suback->qosReturn[index] == DELIVER_FAILURE)
+                        {
+                            LogError("Subscribe delivery failure of subscribe %lu", (unsigned long)index);
+                        }
+                    }
+                    // The subscribed packet has been acked
+                    transport_data->currPacketState = SUBACK_TYPE;
+
+                    // Is this a twin message
+                    if (suback->packetId == transport_data->twin_resp_packet_id)
+                    {
+                        transport_data->twin_resp_sub_recv = true;
+                    }
+                }
+                else
+                {
+                    LogError("Failure: MQTT_CLIENT_ON_SUBSCRIBE_ACK SUBSCRIBE_ACK parameter is NULL.");
+                }
+                break;
+            }
+            case MQTT_CLIENT_ON_PUBLISH_RECV:
+            case MQTT_CLIENT_ON_PUBLISH_REL:
+            {
+                // Currently not used
+                break;
+            }
+            case MQTT_CLIENT_ON_DISCONNECT:
+            {
+                // Close the client so we can reconnect again
+                transport_data->mqttClientStatus = MQTT_CLIENT_STATUS_NOT_CONNECTED;
+                break;
+            }
+            case MQTT_CLIENT_ON_UNSUBSCRIBE_ACK:
+            case MQTT_CLIENT_ON_PING_RESPONSE:
+            default:
+            {
+                break;
+            }
+        }
+    }
+}
+
+// Prior to creating a new connection, if we have an existing xioTransport that has been connected before
+// we need to clear it now or else cached settings (especially TLS when communicating with HTTP proxies)
+// will break reconnection attempt.
+static void ResetConnectionIfNecessary(PMQTTTRANSPORT_HANDLE_DATA transport_data)
+{
+    if (transport_data->xioTransport != NULL && transport_data->conn_attempted)
+    {
+        OPTIONHANDLER_HANDLE options = xio_retrieveoptions(transport_data->xioTransport);
+        set_saved_tls_options(transport_data, options);
+        DestroyXioTransport(transport_data);
+    }
+}
+
+static void mqtt_disconnect_cb(void* ctx)
+{
+    if (ctx != NULL)
+    {
+        int* disconn_recv = (int*)ctx;
+        *disconn_recv = 1;
+    }
+}
+
+static void DisconnectFromClient(PMQTTTRANSPORT_HANDLE_DATA transport_data)
+{
+    if (transport_data->currPacketState != DISCONNECT_TYPE)
+    {
+        if (!transport_data->isDestroyCalled)
+        {
+            OPTIONHANDLER_HANDLE options = xio_retrieveoptions(transport_data->xioTransport);
+            set_saved_tls_options(transport_data, options);
+        }
+        // Ensure the disconnect message is sent
+        if (transport_data->mqttClientStatus == MQTT_CLIENT_STATUS_CONNECTED)
+        {
+            transport_data->disconnect_recv_flag = 0;
+            (void)mqtt_client_disconnect(transport_data->mqttClient, mqtt_disconnect_cb, &transport_data->disconnect_recv_flag);
+            size_t disconnect_ctr = 0;
+            do
+            {
+                mqtt_client_dowork(transport_data->mqttClient);
+                disconnect_ctr++;
+                ThreadAPI_Sleep(50);
+            } while ((disconnect_ctr < MAX_DISCONNECT_VALUE) && (transport_data->disconnect_recv_flag == 0));
+        }
+        DestroyXioTransport(transport_data);
+
+        transport_data->device_twin_get_sent = false;
+        transport_data->mqttClientStatus = MQTT_CLIENT_STATUS_NOT_CONNECTED;
+        transport_data->currPacketState = DISCONNECT_TYPE;
+    }
+}
+
+static void mqtt_error_callback(MQTT_CLIENT_HANDLE handle, MQTT_CLIENT_EVENT_ERROR error, void* callbackCtx)
+{
+    (void)handle;
+    if (callbackCtx != NULL)
+    {
+        PMQTTTRANSPORT_HANDLE_DATA transport_data = (PMQTTTRANSPORT_HANDLE_DATA)callbackCtx;
+        switch (error)
+        {
+            case MQTT_CLIENT_CONNECTION_ERROR:
+            {
+                transport_data->transport_callbacks.connection_status_cb(IOTHUB_CLIENT_CONNECTION_UNAUTHENTICATED, IOTHUB_CLIENT_CONNECTION_NO_NETWORK, transport_data->transport_ctx);
+                break;
+            }
+            case MQTT_CLIENT_COMMUNICATION_ERROR:
+            {
+                transport_data->transport_callbacks.connection_status_cb(IOTHUB_CLIENT_CONNECTION_UNAUTHENTICATED, IOTHUB_CLIENT_CONNECTION_COMMUNICATION_ERROR, transport_data->transport_ctx);
+                break;
+            }
+            case MQTT_CLIENT_NO_PING_RESPONSE:
+            {
+                LogError("Mqtt Ping Response was not encountered.  Reconnecting device...");
+                transport_data->transport_callbacks.connection_status_cb(IOTHUB_CLIENT_CONNECTION_UNAUTHENTICATED, IOTHUB_CLIENT_CONNECTION_NO_PING_RESPONSE, transport_data->transport_ctx);
+                break;
+            }
+            case MQTT_CLIENT_PARSE_ERROR:
+            case MQTT_CLIENT_MEMORY_ERROR:
+            case MQTT_CLIENT_UNKNOWN_ERROR:
+            default:
+            {
+                LogError("INTERNAL ERROR: unexpected error value received %s", MU_ENUM_TO_STRING(MQTT_CLIENT_EVENT_ERROR, error));
+                break;
+            }
+        }
+        if (transport_data->mqttClientStatus != MQTT_CLIENT_STATUS_PENDING_CLOSE)
+        {
+            // We have encountered an mqtt protocol error in an non-closing state
+            // The best course of action is to execute a shutdown of the mqtt/tls/socket
+            // layer and then attempt to reconnect
+            transport_data->mqttClientStatus = MQTT_CLIENT_STATUS_EXECUTE_DISCONNECT;
+        }
+        transport_data->currPacketState = PACKET_TYPE_ERROR;
+        transport_data->device_twin_get_sent = false;
+        if (transport_data->topic_MqttMessage != NULL)
+        {
+            transport_data->topics_ToSubscribe |= SUBSCRIBE_TELEMETRY_TOPIC;
+        }
+        if (transport_data->topic_GetState != NULL)
+        {
+            transport_data->topics_ToSubscribe |= SUBSCRIBE_GET_REPORTED_STATE_TOPIC;
+        }
+        if (transport_data->topic_NotifyState != NULL)
+        {
+            transport_data->topics_ToSubscribe |= SUBSCRIBE_NOTIFICATION_STATE_TOPIC;
+        }
+        if (transport_data->topic_DeviceMethods != NULL)
+        {
+            transport_data->topics_ToSubscribe |= SUBSCRIBE_DEVICE_METHOD_TOPIC;
+        }
+        if (transport_data->topic_InputQueue != NULL)
+        {
+            transport_data->topics_ToSubscribe |= SUBSCRIBE_INPUT_QUEUE_TOPIC;
+        }
+    }
+    else
+    {
+        LogError("Failure: mqtt called back with null context.");
+    }
+}
+
+static void SubscribeToMqttProtocol(PMQTTTRANSPORT_HANDLE_DATA transport_data)
+{
+    if (transport_data->topics_ToSubscribe != UNSUBSCRIBE_FROM_TOPIC)
+    {
+        uint32_t topic_subscription = 0;
+        size_t subscribe_count = 0;
+        uint16_t packet_id = get_next_packet_id(transport_data);
+        SUBSCRIBE_PAYLOAD subscribe[SUBSCRIBE_TOPIC_COUNT];
+        if ((transport_data->topic_MqttMessage != NULL) && (SUBSCRIBE_TELEMETRY_TOPIC & transport_data->topics_ToSubscribe))
+        {
+            subscribe[subscribe_count].subscribeTopic = STRING_c_str(transport_data->topic_MqttMessage);
+            subscribe[subscribe_count].qosReturn = DELIVER_AT_LEAST_ONCE;
+            topic_subscription |= SUBSCRIBE_TELEMETRY_TOPIC;
+            subscribe_count++;
+        }
+        if ((transport_data->topic_GetState != NULL) && (SUBSCRIBE_GET_REPORTED_STATE_TOPIC & transport_data->topics_ToSubscribe))
+        {
+            subscribe[subscribe_count].subscribeTopic = STRING_c_str(transport_data->topic_GetState);
+            subscribe[subscribe_count].qosReturn = DELIVER_AT_MOST_ONCE;
+            topic_subscription |= SUBSCRIBE_GET_REPORTED_STATE_TOPIC;
+            subscribe_count++;
+            transport_data->twin_resp_packet_id = packet_id;
+        }
+        if ((transport_data->topic_NotifyState != NULL) && (SUBSCRIBE_NOTIFICATION_STATE_TOPIC & transport_data->topics_ToSubscribe))
+        {
+            subscribe[subscribe_count].subscribeTopic = STRING_c_str(transport_data->topic_NotifyState);
+            subscribe[subscribe_count].qosReturn = DELIVER_AT_MOST_ONCE;
+            topic_subscription |= SUBSCRIBE_NOTIFICATION_STATE_TOPIC;
+            subscribe_count++;
+        }
+        if ((transport_data->topic_DeviceMethods != NULL) && (SUBSCRIBE_DEVICE_METHOD_TOPIC & transport_data->topics_ToSubscribe))
+        {
+            subscribe[subscribe_count].subscribeTopic = STRING_c_str(transport_data->topic_DeviceMethods);
+            subscribe[subscribe_count].qosReturn = DELIVER_AT_MOST_ONCE;
+            topic_subscription |= SUBSCRIBE_DEVICE_METHOD_TOPIC;
+            subscribe_count++;
+        }
+        if ((transport_data->topic_InputQueue != NULL) && (SUBSCRIBE_INPUT_QUEUE_TOPIC & transport_data->topics_ToSubscribe))
+        {
+            subscribe[subscribe_count].subscribeTopic = STRING_c_str(transport_data->topic_InputQueue);
+            subscribe[subscribe_count].qosReturn = DELIVER_AT_MOST_ONCE;
+            topic_subscription |= SUBSCRIBE_INPUT_QUEUE_TOPIC;
+            subscribe_count++;
+        }
+
+        if (subscribe_count != 0)
+        {
+            /* Codes_SRS_IOTHUB_MQTT_TRANSPORT_07_016: [IoTHubTransport_MQTT_Common_Subscribe shall call mqtt_client_subscribe to subscribe to the Message Topic.] */
+            if (mqtt_client_subscribe(transport_data->mqttClient, packet_id, subscribe, subscribe_count) != 0)
+            {
+                /* Codes_SRS_IOTHUB_MQTT_TRANSPORT_07_017: [Upon failure IoTHubTransport_MQTT_Common_Subscribe shall return a non-zero value.] */
+                LogError("Failure: mqtt_client_subscribe returned error.");
+            }
+            else
+            {
+                /* Codes_SRS_IOTHUB_MQTT_TRANSPORT_07_018: [On success IoTHubTransport_MQTT_Common_Subscribe shall return 0.] */
+                transport_data->topics_ToSubscribe &= ~topic_subscription;
+                transport_data->currPacketState = SUBSCRIBE_TYPE;
+            }
+        }
+        else
+        {
+            /* Codes_SRS_IOTHUB_MQTT_TRANSPORT_07_017: [Upon failure IoTHubTransport_MQTT_Common_Subscribe shall return a non-zero value.] */
+            LogError("Failure: subscribe_topic is empty.");
+        }
+        transport_data->currPacketState = SUBSCRIBE_TYPE;
+    }
+    else
+    {
+        transport_data->currPacketState = PUBLISH_TYPE;
+    }
+}
+
+static bool RetrieveMessagePayload(IOTHUB_MESSAGE_HANDLE messageHandle, const unsigned char** payload, size_t* length)
+{
+    bool result;
+    IOTHUBMESSAGE_CONTENT_TYPE contentType = IoTHubMessage_GetContentType(messageHandle);
+    if (contentType == IOTHUBMESSAGE_BYTEARRAY)
+    {
+        if (IoTHubMessage_GetByteArray(messageHandle, &(*payload), length) != IOTHUB_MESSAGE_OK)
+        {
+            LogError("Failure result from IoTHubMessage_GetByteArray");
+            result = false;
+            *length = 0;
+        }
+        else
+        {
+            result = true;
+        }
+    }
+    else if (contentType == IOTHUBMESSAGE_STRING)
+    {
+        *payload = (const unsigned char*)IoTHubMessage_GetString(messageHandle);
+        if (*payload == NULL)
+        {
+            LogError("Failure result from IoTHubMessage_GetString");
+            result = false;
+            *length = 0;
+        }
+        else
+        {
+            *length = strlen((const char*)*payload);
+            result = true;
+        }
+    }
+    else
+    {
+        result = false;
+        *length = 0;
+    }
+    return result;
+}
+
+static void process_queued_ack_messages(PMQTTTRANSPORT_HANDLE_DATA transport_data)
+{
+    PDLIST_ENTRY current_entry = transport_data->telemetry_waitingForAck.Flink;
+    tickcounter_ms_t current_ms;
+    (void)tickcounter_get_current_ms(transport_data->msgTickCounter, &current_ms);
+    while (current_entry != &transport_data->telemetry_waitingForAck)
+    {
+        MQTT_MESSAGE_DETAILS_LIST* msg_detail_entry = containingRecord(current_entry, MQTT_MESSAGE_DETAILS_LIST, entry);
+        DLIST_ENTRY nextListEntry;
+        nextListEntry.Flink = current_entry->Flink;
+
+        if (((current_ms - msg_detail_entry->msgPublishTime) / 1000) > RESEND_TIMEOUT_VALUE_MIN)
+        {
+            if (msg_detail_entry->retryCount >= MAX_SEND_RECOUNT_LIMIT)
+            {
+                sendMsgComplete(msg_detail_entry->iotHubMessageEntry, transport_data, IOTHUB_CLIENT_CONFIRMATION_MESSAGE_TIMEOUT);
+                (void)DList_RemoveEntryList(current_entry);
+                free(msg_detail_entry);
+
+                DisconnectFromClient(transport_data);
+            }
+            else
+            {
+                // Ensure that the packet state is PUBLISH_TYPE and then attempt to send the message
+                // again
+                if (transport_data->currPacketState == PUBLISH_TYPE)
+                {
+                    size_t messageLength;
+                    const unsigned char* messagePayload = NULL;
+                    if (!RetrieveMessagePayload(msg_detail_entry->iotHubMessageEntry->messageHandle, &messagePayload, &messageLength))
+                    {
+                        (void)DList_RemoveEntryList(current_entry);
+                        sendMsgComplete(msg_detail_entry->iotHubMessageEntry, transport_data, IOTHUB_CLIENT_CONFIRMATION_ERROR);
+                    }
+                    else
+                    {
+                        if (publish_mqtt_telemetry_msg(transport_data, msg_detail_entry, messagePayload, messageLength) != 0)
+                        {
+                            (void)DList_RemoveEntryList(current_entry);
+                            sendMsgComplete(msg_detail_entry->iotHubMessageEntry, transport_data, IOTHUB_CLIENT_CONFIRMATION_ERROR);
+                            free(msg_detail_entry);
+                        }
+                    }
+                }
+                else
+                {
+                    msg_detail_entry->retryCount++;
+                    msg_detail_entry->msgPublishTime = current_ms;
+                }
+            }
+        }
+        current_entry = nextListEntry.Flink;
+    }
+}
+
+static int GetTransportProviderIfNecessary(PMQTTTRANSPORT_HANDLE_DATA transport_data)
+{
+    int result;
+
+    if (transport_data->xioTransport == NULL)
+    {
+        // construct address
+        const char* hostAddress = STRING_c_str(transport_data->hostAddress);
+        MQTT_TRANSPORT_PROXY_OPTIONS mqtt_proxy_options;
+
+        /* Codes_SRS_IOTHUB_TRANSPORT_MQTT_COMMON_01_011: [ If no `proxy_data` option has been set, NULL shall be passed as the argument `mqtt_transport_proxy_options` when calling the function `get_io_transport` passed in `IoTHubTransport_MQTT_Common__Create`. ]*/
+        mqtt_proxy_options.host_address = transport_data->http_proxy_hostname;
+        mqtt_proxy_options.port = transport_data->http_proxy_port;
+        mqtt_proxy_options.username = transport_data->http_proxy_username;
+        mqtt_proxy_options.password = transport_data->http_proxy_password;
+
+        /* Codes_SRS_IOTHUB_TRANSPORT_MQTT_COMMON_01_010: [ If the `proxy_data` option has been set, the proxy options shall be filled in the argument `mqtt_transport_proxy_options` when calling the function `get_io_transport` passed in `IoTHubTransport_MQTT_Common__Create` to obtain the underlying IO handle. ]*/
+        transport_data->xioTransport = transport_data->get_io_transport(hostAddress, (transport_data->http_proxy_hostname == NULL) ? NULL : &mqtt_proxy_options);
+        if (transport_data->xioTransport == NULL)
+        {
+            LogError("Unable to create the lower level TLS layer.");
+            result = MU_FAILURE;
+        }
+        else
+        {
+            if (transport_data->saved_tls_options != NULL)
+            {
+                if (OptionHandler_FeedOptions(transport_data->saved_tls_options, transport_data->xioTransport) != OPTIONHANDLER_OK)
+                {
+                    LogError("Failed feeding existing options to new TLS instance.");
+                    result = MU_FAILURE;
+                }
+                else
+                {
+                    // The tlsio has the options, so our copy can be deleted
+                    set_saved_tls_options(transport_data, NULL);
+                    result = 0;
+                }
+            }
+            else if (IoTHubClient_Auth_Get_Credential_Type(transport_data->authorization_module) == IOTHUB_CREDENTIAL_TYPE_X509_ECC)
+            {
+                if (IoTHubClient_Auth_Set_xio_Certificate(transport_data->authorization_module, transport_data->xioTransport) != 0)
+                {
+                    LogError("Unable to create the lower level TLS layer.");
+                    result = MU_FAILURE;
+                }
+                else
+                {
+                    result = 0;
+                }
+            }
+            else
+            {
+                result = 0;
+            }
+        }
+    }
+    else
+    {
+        result = 0;
+    }
+    return result;
+}
+
+static STRING_HANDLE buildClientId(const char* device_id, const char* module_id)
+{
+    if (module_id == NULL)
+    {
+        return STRING_construct_sprintf("%s", device_id);
+    }
+    else
+    {
+        return STRING_construct_sprintf("%s/%s", device_id, module_id);
+    }
+}
+
+static int buildConfigForUsernameStep2IfNeeded(PMQTTTRANSPORT_HANDLE_DATA transport_data)
+{
+    int result;
+
+    if (!transport_data->isConnectUsernameSet)
+    {
+        STRING_HANDLE userName = NULL;
+        STRING_HANDLE modelIdParameter = NULL;
+        STRING_HANDLE urlEncodedModelId = NULL;
+        const char* modelId = transport_data->transport_callbacks.get_model_id_cb(transport_data->transport_ctx);
+        // TODO: The preview API version in SDK is only scoped to scenarios that require the modelId to be set.
+        // https://github.com/Azure/azure-iot-sdk-c/issues/1547 tracks removing this once non-preview API versions support modelId.
+        const char* apiVersion = (modelId != NULL) ? IOTHUB_API_PREVIEW_VERSION : IOTHUB_API_VERSION;
+        const char* appSpecifiedProductInfo = transport_data->transport_callbacks.prod_info_cb(transport_data->transport_ctx);
+        STRING_HANDLE productInfoEncoded = NULL; 
+
+        if ((productInfoEncoded = URL_EncodeString((appSpecifiedProductInfo != NULL) ? appSpecifiedProductInfo : DEFAULT_IOTHUB_PRODUCT_IDENTIFIER)) == NULL)
+        {
+            LogError("Unable to UrlEncode productInfo");
+            result = MU_FAILURE;
+        }
+        else if ((userName = STRING_construct_sprintf("%s?api-version=%s&DeviceClientType=%s", STRING_c_str(transport_data->configPassedThroughUsername), apiVersion, STRING_c_str(productInfoEncoded))) == NULL)
+        {
+            LogError("Failed constructing string");
+            result = 0;
+        }
+        else if (modelId != NULL)
+        {
+            if ((urlEncodedModelId = URL_EncodeString(modelId)) == NULL)
+            {
+                LogError("Failed to URL encode the modelID string");
+                result = MU_FAILURE;
+            }
+            else if ((modelIdParameter = STRING_construct_sprintf("&%s=%s", DT_MODEL_ID_TOKEN, STRING_c_str(urlEncodedModelId))) == NULL)
+            {
+                LogError("Cannot build modelID string");
+                result = MU_FAILURE;
+            }
+            else if (STRING_concat_with_STRING(userName, modelIdParameter) != 0)
+            {
+                LogError("Failed to set modelID parameter in connect");
+                result = MU_FAILURE;
+            }
+            else
+            {
+                result = 0;
+            }
+        }
+        else
+        {
+            result = 0;
+        }
+
+        if (result == 0)
+        {
+            STRING_delete(transport_data->configPassedThroughUsername);
+            transport_data->configPassedThroughUsername = userName;
+            userName = NULL;
+            // setting connect string is only allowed once in the lifetime of the device client.
+            transport_data->isConnectUsernameSet = true;
+        }
+
+        STRING_delete(userName);
+        STRING_delete(modelIdParameter);
+        STRING_delete(urlEncodedModelId);
+        STRING_delete(productInfoEncoded);
+    }
+    else
+    {
+        result = 0;
+    }
+
+    return result;
+}
+
+static int SendMqttConnectMsg(PMQTTTRANSPORT_HANDLE_DATA transport_data)
+{
+    int result;
+
+    char* sasToken = NULL;
+    result = 0;
+
+    IOTHUB_CREDENTIAL_TYPE cred_type = IoTHubClient_Auth_Get_Credential_Type(transport_data->authorization_module);
+    if (cred_type == IOTHUB_CREDENTIAL_TYPE_DEVICE_KEY || cred_type == IOTHUB_CREDENTIAL_TYPE_DEVICE_AUTH)
+    {
+        sasToken = IoTHubClient_Auth_Get_SasToken(transport_data->authorization_module, STRING_c_str(transport_data->devicesAndModulesPath), 0, NULL);
+        if (sasToken == NULL)
+        {
+            LogError("failure getting sas token from IoTHubClient_Auth_Get_SasToken.");
+            result = MU_FAILURE;
+        }
+    }
+    else if (cred_type == IOTHUB_CREDENTIAL_TYPE_SAS_TOKEN)
+    {
+        SAS_TOKEN_STATUS token_status = IoTHubClient_Auth_Is_SasToken_Valid(transport_data->authorization_module);
+        if (token_status == SAS_TOKEN_STATUS_INVALID)
+        {
+            transport_data->transport_callbacks.connection_status_cb(IOTHUB_CLIENT_CONNECTION_UNAUTHENTICATED, IOTHUB_CLIENT_CONNECTION_EXPIRED_SAS_TOKEN, transport_data->transport_ctx);
+            result = MU_FAILURE;
+        }
+        else if (token_status == SAS_TOKEN_STATUS_FAILED)
+        {
+            transport_data->transport_callbacks.connection_status_cb(IOTHUB_CLIENT_CONNECTION_UNAUTHENTICATED, IOTHUB_CLIENT_CONNECTION_BAD_CREDENTIAL, transport_data->transport_ctx);
+            result = MU_FAILURE;
+        }
+        else
+        {
+            sasToken = IoTHubClient_Auth_Get_SasToken(transport_data->authorization_module, NULL, 0, NULL);
+            if (sasToken == NULL)
+            {
+                LogError("failure getting sas Token.");
+                result = MU_FAILURE;
+            }
+        }
+    }
+
+    if (result == 0)
+    {
+        STRING_HANDLE clientId;
+        if (buildConfigForUsernameStep2IfNeeded(transport_data) != 0)
+        {
+            LogError("Failed to add optional connect parameters.");
+            result = MU_FAILURE;
+        }
+        else if ((clientId = buildClientId(STRING_c_str(transport_data->device_id), STRING_c_str(transport_data->module_id))) == NULL)
+        {
+            LogError("Unable to allocate clientId");
+            result = MU_FAILURE;
+        }
+        else
+        {
+            MQTT_CLIENT_OPTIONS options = { 0 };
+            options.clientId = (char*)STRING_c_str(clientId);
+            options.willMessage = NULL;
+            options.username = (char*)STRING_c_str(transport_data->configPassedThroughUsername);
+            if (sasToken != NULL)
+            {
+                options.password = sasToken;
+            }
+            options.keepAliveInterval = transport_data->keepAliveValue;
+            options.useCleanSession = false;
+            options.qualityOfServiceValue = DELIVER_AT_LEAST_ONCE;
+
+            if (GetTransportProviderIfNecessary(transport_data) == 0)
+            {
+                transport_data->conn_attempted = true;
+                if (mqtt_client_connect(transport_data->mqttClient, transport_data->xioTransport, &options) != 0)
+                {
+                    LogError("failure connecting to address %s.", STRING_c_str(transport_data->hostAddress));
+                    result = MU_FAILURE;
+                }
+                else
+                {
+                    transport_data->currPacketState = CONNECT_TYPE;
+                    transport_data->isRetryExpiredCallbackSet = false;
+                    (void)tickcounter_get_current_ms(transport_data->msgTickCounter, &transport_data->mqtt_connect_time);
+                    result = 0;
+                }
+            }
+            else
+            {
+                result = MU_FAILURE;
+            }
+
+            if (sasToken != NULL)
+            {
+                free(sasToken);
+            }
+            STRING_delete(clientId);
+        }
+    }
+    return result;
+}
+
+static int InitializeConnection(PMQTTTRANSPORT_HANDLE_DATA transport_data)
+{
+    int result = 0;
+
+    // Make sure we're not destroying the object
+    if (!transport_data->isDestroyCalled)
+    {
+        RETRY_ACTION retry_action = RETRY_ACTION_RETRY_LATER;
+
+        // Codes_SRS_IOTHUB_TRANSPORT_MQTT_COMMON_09_007: [ IoTHubTransport_MQTT_Common_DoWork shall try to reconnect according to the current retry policy set ]
+        if (transport_data->mqttClientStatus == MQTT_CLIENT_STATUS_NOT_CONNECTED && transport_data->isRecoverableError)
+        {
+            // Note: in case retry_control_should_retry fails, the reconnection shall be attempted anyway (defaulting to policy IOTHUB_CLIENT_RETRY_IMMEDIATE).
+            if (!transport_data->conn_attempted || retry_control_should_retry(transport_data->retry_control_handle, &retry_action) != 0 || retry_action == RETRY_ACTION_RETRY_NOW)
+            {
+                if (tickcounter_get_current_ms(transport_data->msgTickCounter, &transport_data->connectTick) != 0)
+                {
+                    transport_data->connectFailCount++;
+                    result = MU_FAILURE;
+                }
+                else
+                {
+                    ResetConnectionIfNecessary(transport_data);
+
+                    if (SendMqttConnectMsg(transport_data) != 0)
+                    {
+                        transport_data->connectFailCount++;
+                        result = MU_FAILURE;
+                    }
+                    else
+                    {
+                        transport_data->mqttClientStatus = MQTT_CLIENT_STATUS_CONNECTING;
+                        transport_data->connectFailCount = 0;
+                        result = 0;
+                    }
+                }
+            }
+            else if (retry_action == RETRY_ACTION_STOP_RETRYING)
+            {
+                // Set callback if retry expired
+                if (!transport_data->isRetryExpiredCallbackSet)
+                {
+                    transport_data->transport_callbacks.connection_status_cb(IOTHUB_CLIENT_CONNECTION_UNAUTHENTICATED, IOTHUB_CLIENT_CONNECTION_RETRY_EXPIRED, transport_data->transport_ctx);
+                    transport_data->isRetryExpiredCallbackSet = true;
+                }
+                result = MU_FAILURE;
+            }
+            else if (retry_action == RETRY_ACTION_RETRY_LATER)
+            {
+                result = MU_FAILURE;
+            }
+        }
+        else if (transport_data->mqttClientStatus == MQTT_CLIENT_STATUS_EXECUTE_DISCONNECT)
+        {
+            // Need to disconnect from client
+            DisconnectFromClient(transport_data);
+            result = 0;
+        }
+        // Codes_SRS_IOTHUB_TRANSPORT_MQTT_COMMON_09_001: [ IoTHubTransport_MQTT_Common_DoWork shall trigger reconnection if the mqtt_client_connect does not complete within `keepalive` seconds]
+        else if (transport_data->mqttClientStatus == MQTT_CLIENT_STATUS_CONNECTING)
+        {
+            tickcounter_ms_t current_time;
+            if (tickcounter_get_current_ms(transport_data->msgTickCounter, &current_time) != 0)
+            {
+                LogError("failed verifying MQTT_CLIENT_STATUS_CONNECTING timeout");
+                result = MU_FAILURE;
+            }
+            else if ((current_time - transport_data->mqtt_connect_time) / 1000 > transport_data->connect_timeout_in_sec)
+            {
+                LogError("mqtt_client timed out waiting for CONNACK");
+                transport_data->currPacketState = PACKET_TYPE_ERROR;
+                DisconnectFromClient(transport_data);
+                result = MU_FAILURE;
+            }
+        }
+        else if (transport_data->mqttClientStatus == MQTT_CLIENT_STATUS_CONNECTED)
+        {
+            // We are connected and not being closed, so does SAS need to reconnect?
+            tickcounter_ms_t current_time;
+            if (tickcounter_get_current_ms(transport_data->msgTickCounter, &current_time) != 0)
+            {
+                transport_data->connectFailCount++;
+                result = MU_FAILURE;
+            }
+            else
+            {
+                IOTHUB_CREDENTIAL_TYPE cred_type = IoTHubClient_Auth_Get_Credential_Type(transport_data->authorization_module);
+                // If the credential type is not an x509 certificate then we shall renew the Sas_Token
+                if (cred_type != IOTHUB_CREDENTIAL_TYPE_X509 && cred_type != IOTHUB_CREDENTIAL_TYPE_X509_ECC)
+                {
+                    size_t sas_token_expiry = IoTHubClient_Auth_Get_SasToken_Expiry(transport_data->authorization_module);
+                    if ((current_time - transport_data->mqtt_connect_time) / 1000 > (sas_token_expiry*SAS_REFRESH_MULTIPLIER))
+                    {
+                        /* Codes_SRS_IOTHUB_TRANSPORT_MQTT_COMMON_07_058: [ If the sas token has timed out IoTHubTransport_MQTT_Common_DoWork shall disconnect from the mqtt client and destroy the transport information and wait for reconnect. ] */
+                        DisconnectFromClient(transport_data);
+
+                        transport_data->transport_callbacks.connection_status_cb(IOTHUB_CLIENT_CONNECTION_UNAUTHENTICATED, IOTHUB_CLIENT_CONNECTION_EXPIRED_SAS_TOKEN, transport_data->transport_ctx);
+                        transport_data->currPacketState = UNKNOWN_TYPE;
+                        if (transport_data->topic_MqttMessage != NULL)
+                        {
+                            transport_data->topics_ToSubscribe |= SUBSCRIBE_TELEMETRY_TOPIC;
+                        }
+                        if (transport_data->topic_GetState != NULL)
+                        {
+                            transport_data->topics_ToSubscribe |= SUBSCRIBE_GET_REPORTED_STATE_TOPIC;
+                        }
+                        if (transport_data->topic_NotifyState != NULL)
+                        {
+                            transport_data->topics_ToSubscribe |= SUBSCRIBE_NOTIFICATION_STATE_TOPIC;
+                        }
+                        if (transport_data->topic_DeviceMethods != NULL)
+                        {
+                            transport_data->topics_ToSubscribe |= SUBSCRIBE_DEVICE_METHOD_TOPIC;
+                        }
+                        if (transport_data->topic_InputQueue != NULL)
+                        {
+                            transport_data->topics_ToSubscribe |= SUBSCRIBE_INPUT_QUEUE_TOPIC;
+                        }
+                    }
+                }
+            }
+        }
+    }
+    return result;
+}
+
+// At handle creation time, we don't have all the fields required for building up the user name (e.g. productID)
+// We build up as much of the string as we can at this point because we do not store upperConfig after initialization.
+// In buildConfigForUsernameStep2IfNeeded, only immediately before we do CONNECT itself, do we complete building up this string.
+static STRING_HANDLE buildConfigForUsernameStep1(const IOTHUB_CLIENT_CONFIG* upperConfig, const char* moduleId)
+{
+    if (moduleId == NULL)
+    {
+        return STRING_construct_sprintf("%s.%s/%s/", upperConfig->iotHubName, upperConfig->iotHubSuffix, upperConfig->deviceId);
+    }
+    else
+    {
+        return STRING_construct_sprintf("%s.%s/%s/%s/", upperConfig->iotHubName, upperConfig->iotHubSuffix, upperConfig->deviceId, moduleId);
+    }
+}
+
+static STRING_HANDLE buildMqttEventString(const char* device_id, const char* module_id)
+{
+    if (module_id == NULL)
+    {
+        return STRING_construct_sprintf(TOPIC_DEVICE_DEVICE, device_id);
+    }
+    else
+    {
+        return STRING_construct_sprintf(TOPIC_DEVICE_DEVICE_MODULE, device_id, module_id);
+    }
+}
+
+static STRING_HANDLE buildDevicesAndModulesPath(const IOTHUB_CLIENT_CONFIG* upperConfig, const char* moduleId)
+{
+    if (moduleId == NULL)
+    {
+        return STRING_construct_sprintf("%s.%s/devices/%s", upperConfig->iotHubName, upperConfig->iotHubSuffix, upperConfig->deviceId);
+    }
+    else
+    {
+        return STRING_construct_sprintf("%s.%s/devices/%s/modules/%s", upperConfig->iotHubName, upperConfig->iotHubSuffix, upperConfig->deviceId, moduleId);
+    }
+}
+
+static PMQTTTRANSPORT_HANDLE_DATA InitializeTransportHandleData(const IOTHUB_CLIENT_CONFIG* upperConfig, PDLIST_ENTRY waitingToSend, IOTHUB_AUTHORIZATION_HANDLE auth_module, const char* moduleId)
+{
+    PMQTTTRANSPORT_HANDLE_DATA state = (PMQTTTRANSPORT_HANDLE_DATA)malloc(sizeof(MQTTTRANSPORT_HANDLE_DATA));
+    if (state == NULL)
+    {
+        LogError("Could not create MQTT transport state. Memory allocation failed.");
+    }
+    else
+    {
+        memset(state, 0, sizeof(MQTTTRANSPORT_HANDLE_DATA));
+        if ((state->msgTickCounter = tickcounter_create()) == NULL)
+        {
+            LogError("Invalid Argument: iotHubName is empty");
+            free_transport_handle_data(state);
+            state = NULL;
+        }
+        // Codes_SRS_IOTHUB_TRANSPORT_MQTT_COMMON_09_005: [ MQTT transport shall use EXPONENTIAL_WITH_BACK_OFF as default retry policy ]
+        else if ((state->retry_control_handle = retry_control_create(DEFAULT_RETRY_POLICY, DEFAULT_RETRY_TIMEOUT_IN_SECONDS)) == NULL)
+        {
+            LogError("Failed creating default retry control");
+            free_transport_handle_data(state);
+            state = NULL;
+        }
+        else if ((state->device_id = STRING_construct(upperConfig->deviceId)) == NULL)
+        {
+            LogError("failure constructing device_id.");
+            free_transport_handle_data(state);
+            state = NULL;
+        }
+        else if ((moduleId != NULL) && ((state->module_id = STRING_construct(moduleId)) == NULL))
+        {
+            LogError("failure constructing module_id.");
+            free_transport_handle_data(state);
+            state = NULL;
+        }
+        else if ((state->devicesAndModulesPath = buildDevicesAndModulesPath(upperConfig, moduleId)) == NULL)
+        {
+            LogError("failure constructing devicesPath.");
+            free_transport_handle_data(state);
+            state = NULL;
+        }
+        else
+        {
+            if ((state->topic_MqttEvent = buildMqttEventString(upperConfig->deviceId, moduleId)) == NULL)
+            {
+                LogError("Could not create topic_MqttEvent for MQTT");
+                free_transport_handle_data(state);
+                state = NULL;
+            }
+            else
+            {
+                state->mqttClient = mqtt_client_init(mqtt_notification_callback, mqtt_operation_complete_callback, state, mqtt_error_callback, state);
+                if (state->mqttClient == NULL)
+                {
+                    LogError("failure initializing mqtt client.");
+                    free_transport_handle_data(state);
+                    state = NULL;
+                }
+                else
+                {
+                    /* Codes_SRS_IOTHUB_MQTT_TRANSPORT_07_008: [If the upperConfig contains a valid protocolGatewayHostName value this shall be used for the hostname, otherwise the hostname shall be constructed using the iothubName and iothubSuffix.] */
+                    if (upperConfig->protocolGatewayHostName == NULL)
+                    {
+                        state->hostAddress = STRING_construct_sprintf("%s.%s", upperConfig->iotHubName, upperConfig->iotHubSuffix);
+                    }
+                    else
+                    {
+                        state->hostAddress = STRING_construct(upperConfig->protocolGatewayHostName);
+                    }
+
+                    if (state->hostAddress == NULL)
+                    {
+                        LogError("failure constructing host address.");
+                        free_transport_handle_data(state);
+                        state = NULL;
+                    }
+                    else if ((state->configPassedThroughUsername = buildConfigForUsernameStep1(upperConfig, moduleId)) == NULL)
+                    {
+                        free_transport_handle_data(state);
+                        state = NULL;
+                    }
+                    else
+                    {
+                        /* Codes_SRS_IOTHUB_MQTT_TRANSPORT_07_010: [IoTHubTransport_MQTT_Common_Create shall allocate memory to save its internal state where all topics, hostname, device_id, device_key, sasTokenSr and client handle shall be saved.] */
+                        DList_InitializeListHead(&(state->telemetry_waitingForAck));
+                        DList_InitializeListHead(&(state->ack_waiting_queue));
+                        DList_InitializeListHead(&(state->pending_get_twin_queue));
+                        state->mqttClientStatus = MQTT_CLIENT_STATUS_NOT_CONNECTED;
+                        state->isRecoverableError = true;
+                        state->packetId = 1;
+                        state->waitingToSend = waitingToSend;
+                        state->currPacketState = CONNECT_TYPE;
+                        state->keepAliveValue = DEFAULT_MQTT_KEEPALIVE;
+                        state->connect_timeout_in_sec = DEFAULT_CONNACK_TIMEOUT;
+                        state->topics_ToSubscribe = UNSUBSCRIBE_FROM_TOPIC;
+                        srand((unsigned int)get_time(NULL));
+                        state->authorization_module = auth_module;
+
+                        state->isDestroyCalled = false;
+                        state->isRetryExpiredCallbackSet = false;
+                        state->isRegistered = false;
+                        state->device_twin_get_sent = false;
+                        state->xioTransport = NULL;
+                        state->portNum = 0;
+                        state->connectFailCount = 0;
+                        state->connectTick = 0;
+                        state->topic_MqttMessage = NULL;
+                        state->topic_GetState = NULL;
+                        state->topic_NotifyState = NULL;
+                        state->topic_DeviceMethods = NULL;
+                        state->topic_InputQueue = NULL;
+                        state->log_trace = state->raw_trace = false;
+                        state->isConnectUsernameSet = false;
+                        state->auto_url_encode_decode = false;
+                        state->conn_attempted = false;
+                    }
+                }
+            }
+        }
+    }
+    return state;
+}
+
+TRANSPORT_LL_HANDLE IoTHubTransport_MQTT_Common_Create(const IOTHUBTRANSPORT_CONFIG* config, MQTT_GET_IO_TRANSPORT get_io_transport, TRANSPORT_CALLBACKS_INFO* cb_info, void* ctx)
+{
+    PMQTTTRANSPORT_HANDLE_DATA result;
+    size_t deviceIdSize;
+
+    /* Codes_SRS_IOTHUB_MQTT_TRANSPORT_07_001: [If parameter config is NULL then IoTHubTransport_MQTT_Common_Create shall return NULL.] */
+    /* Codes_SRS_IOTHUB_TRANSPORT_MQTT_COMMON_07_041: [ if get_io_transport is NULL then IoTHubTransport_MQTT_Common_Create shall return NULL. ] */
+    if (config == NULL || get_io_transport == NULL || cb_info == NULL)
+    {
+        LogError("Invalid Argument config: %p, get_io_transport: %p, cb_info: %p", config, get_io_transport, cb_info);
+        result = NULL;
+    }
+    /* Codes_SRS_IOTHUB_MQTT_TRANSPORT_07_002: [If the parameter config's variables upperConfig, auth_module_handle or waitingToSend are NULL then IoTHubTransport_MQTT_Common_Create shall return NULL.] */
+    else if (config->auth_module_handle == NULL)
+    {
+        LogError("Invalid Argument: auth_module_handle is NULL)");
+        result = NULL;
+    }
+    /* Codes_SRS_IOTHUB_MQTT_TRANSPORT_07_002: [If the parameter config's variables upperConfig or waitingToSend are NULL then IoTHubTransport_MQTT_Common_Create shall return NULL.] */
+    /* Codes_SRS_IOTHUB_MQTT_TRANSPORT_07_003: [If the upperConfig's variables deviceId, both deviceKey and deviceSasToken, iotHubName, protocol, or iotHubSuffix are NULL then IoTHubTransport_MQTT_Common_Create shall return NULL.] */
+    /* Codes_SRS_IOTHUB_MQTT_TRANSPORT_03_003: [If both deviceKey & deviceSasToken fields are NOT NULL then IoTHubTransport_MQTT_Common_Create shall return NULL.] */
+    else if (config->upperConfig == NULL ||
+        config->upperConfig->protocol == NULL ||
+        config->upperConfig->deviceId == NULL ||
+        ((config->upperConfig->deviceKey != NULL) && (config->upperConfig->deviceSasToken != NULL)) ||
+        config->upperConfig->iotHubName == NULL ||
+        config->upperConfig->iotHubSuffix == NULL)
+    {
+        LogError("Invalid Argument: upperConfig structure contains an invalid parameter");
+        result = NULL;
+    }
+    /* Codes_SRS_IOTHUB_MQTT_TRANSPORT_07_002: [If the parameter config's variables upperConfig, auth_module_handle or waitingToSend are NULL then IoTHubTransport_MQTT_Common_Create shall return NULL.] */
+    else if (config->waitingToSend == NULL)
+    {
+        LogError("Invalid Argument: waitingToSend is NULL)");
+        result = NULL;
+    }
+    /* Codes_SRS_IOTHUB_MQTT_TRANSPORT_07_006: [If the upperConfig's variables deviceId is an empty strings or length is greater then 128 then IoTHubTransport_MQTT_Common_Create shall return NULL.] */
+    else if (((deviceIdSize = strlen(config->upperConfig->deviceId)) > 128U) || (deviceIdSize == 0))
+    {
+        LogError("Invalid Argument: DeviceId is of an invalid size");
+        result = NULL;
+    }
+    /* Codes_SRS_IOTHUB_MQTT_TRANSPORT_07_003: [If the upperConfig's variables deviceId, both deviceKey and deviceSasToken, iotHubName, protocol, or iotHubSuffix are NULL then IoTHubTransport_MQTT_Common_Create shall return NULL.] */
+    else if ((config->upperConfig->deviceKey != NULL) && (strlen(config->upperConfig->deviceKey) == 0))
+    {
+        LogError("Invalid Argument: deviceKey is empty");
+        result = NULL;
+    }
+    /* Codes_SRS_IOTHUB_MQTT_TRANSPORT_07_003: [If the upperConfig's variables deviceId, both deviceKey and deviceSasToken, iotHubName, protocol, or iotHubSuffix are NULL then IoTHubTransport_MQTT_Common_Create shall return NULL.] */
+    else if ((config->upperConfig->deviceSasToken != NULL) && (strlen(config->upperConfig->deviceSasToken) == 0))
+    {
+        LogError("Invalid Argument: deviceSasToken is empty");
+        result = NULL;
+    }
+    /* Codes_SRS_IOTHUB_MQTT_TRANSPORT_07_003: [If the upperConfig's variables deviceId, deviceKey, iotHubName, protocol, or iotHubSuffix are NULL then IoTHubTransport_MQTT_Common_Create shall return NULL.] */
+    else if (strlen(config->upperConfig->iotHubName) == 0)
+    {
+        LogError("Invalid Argument: iotHubName is empty");
+        result = NULL;
+    }
+    else if (IoTHub_Transport_ValidateCallbacks(cb_info) != 0)
+    {
+        LogError("failure checking transport callbacks");
+        result = NULL;
+    }
+    else
+    {
+        result = InitializeTransportHandleData(config->upperConfig, config->waitingToSend, config->auth_module_handle, config->moduleId);
+        if (result != NULL)
+        {
+            result->get_io_transport = get_io_transport;
+            result->http_proxy_hostname = NULL;
+            result->http_proxy_username = NULL;
+            result->http_proxy_password = NULL;
+
+            result->transport_ctx = ctx;
+            memcpy(&result->transport_callbacks, cb_info, sizeof(TRANSPORT_CALLBACKS_INFO));
+        }
+    }
+    /* Codes_SRS_IOTHUB_MQTT_TRANSPORT_07_009: [If any error is encountered then IoTHubTransport_MQTT_Common_Create shall return NULL.] */
+    /* Codes_SRS_IOTHUB_MQTT_TRANSPORT_07_011: [On Success IoTHubTransport_MQTT_Common_Create shall return a non-NULL value.] */
+    return result;
+}
+
+void IoTHubTransport_MQTT_Common_Destroy(TRANSPORT_LL_HANDLE handle)
+{
+    /* Codes_SRS_IOTHUB_MQTT_TRANSPORT_07_012: [IoTHubTransport_MQTT_Common_Destroy shall do nothing if parameter handle is NULL.] */
+    PMQTTTRANSPORT_HANDLE_DATA transport_data = (PMQTTTRANSPORT_HANDLE_DATA)handle;
+    if (transport_data != NULL)
+    {
+        transport_data->isDestroyCalled = true;
+
+        DisconnectFromClient(transport_data);
+
+        //Empty the Waiting for Ack Messages.
+        while (!DList_IsListEmpty(&transport_data->telemetry_waitingForAck))
+        {
+            PDLIST_ENTRY currentEntry = DList_RemoveHeadList(&transport_data->telemetry_waitingForAck);
+            MQTT_MESSAGE_DETAILS_LIST* mqttMsgEntry = containingRecord(currentEntry, MQTT_MESSAGE_DETAILS_LIST, entry);
+            sendMsgComplete(mqttMsgEntry->iotHubMessageEntry, transport_data, IOTHUB_CLIENT_CONFIRMATION_BECAUSE_DESTROY);
+            free(mqttMsgEntry);
+        }
+        while (!DList_IsListEmpty(&transport_data->ack_waiting_queue))
+        {
+            PDLIST_ENTRY currentEntry = DList_RemoveHeadList(&transport_data->ack_waiting_queue);
+            MQTT_DEVICE_TWIN_ITEM* mqtt_device_twin = containingRecord(currentEntry, MQTT_DEVICE_TWIN_ITEM, entry);
+
+            if (mqtt_device_twin->userCallback == NULL)
+            {
+                transport_data->transport_callbacks.twin_rpt_state_complete_cb(mqtt_device_twin->iothub_msg_id, STATUS_CODE_TIMEOUT_VALUE, transport_data->transport_ctx);
+            }
+            else
+            {
+                mqtt_device_twin->userCallback(DEVICE_TWIN_UPDATE_COMPLETE, NULL, 0, mqtt_device_twin->userContext);
+            }
+
+            destroy_device_twin_get_message(mqtt_device_twin);
+        }
+        while (!DList_IsListEmpty(&transport_data->pending_get_twin_queue))
+        {
+            PDLIST_ENTRY currentEntry = DList_RemoveHeadList(&transport_data->pending_get_twin_queue);
+
+            MQTT_DEVICE_TWIN_ITEM* mqtt_device_twin = containingRecord(currentEntry, MQTT_DEVICE_TWIN_ITEM, entry);
+
+            mqtt_device_twin->userCallback(DEVICE_TWIN_UPDATE_COMPLETE, NULL, 0, mqtt_device_twin->userContext);
+
+            destroy_device_twin_get_message(mqtt_device_twin);
+        }
+
+        /* Codes_SRS_IOTHUB_MQTT_TRANSPORT_07_014: [IoTHubTransport_MQTT_Common_Destroy shall free all the resources currently in use.] */
+        /* Codes_SRS_IOTHUB_TRANSPORT_MQTT_COMMON_01_012: [ `IoTHubTransport_MQTT_Common_Destroy` shall free the stored proxy options. ]*/
+        free_transport_handle_data(transport_data);
+    }
+}
+
+int IoTHubTransport_MQTT_Common_Subscribe_DeviceTwin(TRANSPORT_LL_HANDLE handle)
+{
+    int result;
+    PMQTTTRANSPORT_HANDLE_DATA transport_data = (PMQTTTRANSPORT_HANDLE_DATA)handle;
+    if (transport_data == NULL)
+    {
+        /* Codes_SRS_IOTHUB_MQTT_TRANSPORT_07_042: [If the parameter handle is NULL than IoTHubTransport_MQTT_Common_Subscribe shall return a non-zero value.] */
+        LogError("Invalid handle parameter. NULL.");
+        result = MU_FAILURE;
+    }
+    else
+    {
+        if (transport_data->topic_GetState == NULL)
+        {
+            /* Codes_SRS_IOTHUB_MQTT_TRANSPORT_07_044: [IoTHubTransport_MQTT_Common_Subscribe_DeviceTwin shall construct the get state topic string and the notify state topic string.] */
+            transport_data->topic_GetState = STRING_construct(TOPIC_GET_DESIRED_STATE);
+            if (transport_data->topic_GetState == NULL)
+            {
+                /* Codes_SRS_IOTHUB_MQTT_TRANSPORT_07_046: [Upon failure IoTHubTransport_MQTT_Common_Subscribe_DeviceTwin shall return a non-zero value.] */
+                LogError("Failure: unable constructing reported state topic");
+                result = MU_FAILURE;
+            }
+            else
+            {
+                /* Codes_SRS_IOTHUB_MQTT_TRANSPORT_07_047: [On success IoTHubTransport_MQTT_Common_Subscribe_DeviceTwin shall return 0.] */
+                transport_data->topics_ToSubscribe |= SUBSCRIBE_GET_REPORTED_STATE_TOPIC;
+                result = 0;
+            }
+        }
+        else
+        {
+            result = 0;
+        }
+        if (result == 0)
+        {
+            changeStateToSubscribeIfAllowed(transport_data);
+        }
+    }
+    return result;
+}
+
+void IoTHubTransport_MQTT_Common_Unsubscribe_DeviceTwin(TRANSPORT_LL_HANDLE handle)
+{
+    PMQTTTRANSPORT_HANDLE_DATA transport_data = (PMQTTTRANSPORT_HANDLE_DATA)handle;
+    /* Codes_SRS_IOTHUB_MQTT_TRANSPORT_07_048: [If the parameter handle is NULL than IoTHubTransport_MQTT_Common_Unsubscribe_DeviceTwin shall do nothing.] */
+    if (transport_data != NULL)
+    {
+        if (transport_data->topic_GetState != NULL)
+        {
+            /* Codes_SRS_IOTHUB_MQTT_TRANSPORT_07_049: [If subscribe_state is set to IOTHUB_DEVICE_TWIN_DESIRED_STATE then IoTHubTransport_MQTT_Common_Unsubscribe_DeviceTwin shall unsubscribe from the topic_GetState to the mqtt client.] */
+            transport_data->topics_ToSubscribe &= ~SUBSCRIBE_GET_REPORTED_STATE_TOPIC;
+            STRING_delete(transport_data->topic_GetState);
+            transport_data->topic_GetState = NULL;
+        }
+        if (transport_data->topic_NotifyState != NULL)
+        {
+            /* Codes_SRS_IOTHUB_MQTT_TRANSPORT_07_050: [If subscribe_state is set to IOTHUB_DEVICE_TWIN_NOTIFICATION_STATE then IoTHubTransport_MQTT_Common_Unsubscribe_DeviceTwin shall unsubscribe from the topic_NotifyState to the mqtt client.] */
+            transport_data->topics_ToSubscribe &= ~SUBSCRIBE_NOTIFICATION_STATE_TOPIC;
+            STRING_delete(transport_data->topic_NotifyState);
+            transport_data->topic_NotifyState = NULL;
+        }
+    }
+    else
+    {
+        LogError("Invalid argument to unsubscribe (handle is NULL).");
+    }
+}
+
+IOTHUB_CLIENT_RESULT IoTHubTransport_MQTT_Common_GetTwinAsync(IOTHUB_DEVICE_HANDLE handle, IOTHUB_CLIENT_DEVICE_TWIN_CALLBACK completionCallback, void* callbackContext)
+{
+    IOTHUB_CLIENT_RESULT result;
+
+    // Codes_SRS_IOTHUB_MQTT_TRANSPORT_09_001: [ If `handle` or `completionCallback` are `NULL` than `IoTHubTransport_MQTT_Common_GetTwinAsync` shall return IOTHUB_CLIENT_INVALID_ARG. ]
+    if (handle == NULL || completionCallback == NULL)
+    {
+        LogError("Invalid argument (handle=%p, completionCallback=%p)", handle, completionCallback);
+        result = IOTHUB_CLIENT_INVALID_ARG;
+    }
+    else
+    {
+        PMQTTTRANSPORT_HANDLE_DATA transport_data = (PMQTTTRANSPORT_HANDLE_DATA)handle;
+        MQTT_DEVICE_TWIN_ITEM* mqtt_info;
+
+        if ((mqtt_info = create_device_twin_message(transport_data, RETRIEVE_PROPERTIES, 0)) == NULL)
+        {
+            LogError("Failed creating the device twin get request message");
+            // Codes_SRS_IOTHUB_MQTT_TRANSPORT_09_003: [ If any failure occurs, IoTHubTransport_MQTT_Common_GetTwinAsync shall return IOTHUB_CLIENT_ERROR ]
+            result = IOTHUB_CLIENT_ERROR;
+        }
+        else if (tickcounter_get_current_ms(transport_data->msgTickCounter, &mqtt_info->msgCreationTime) != 0)
+        {
+            LogError("Failed setting the get twin request enqueue time");
+            destroy_device_twin_get_message(mqtt_info);
+            // Codes_SRS_IOTHUB_MQTT_TRANSPORT_09_003: [ If any failure occurs, IoTHubTransport_MQTT_Common_GetTwinAsync shall return IOTHUB_CLIENT_ERROR ]
+            result = IOTHUB_CLIENT_ERROR;
+        }
+        else
+        {
+            mqtt_info->userCallback = completionCallback;
+            mqtt_info->userContext = callbackContext;
+
+            // Codes_SRS_IOTHUB_MQTT_TRANSPORT_09_002: [ The request shall be queued to be sent when the transport is connected, through DoWork ]
+            DList_InsertTailList(&transport_data->pending_get_twin_queue, &mqtt_info->entry);
+
+            // Codes_SRS_IOTHUB_MQTT_TRANSPORT_09_004: [ If no failure occurs, IoTHubTransport_MQTT_Common_GetTwinAsync shall return IOTHUB_CLIENT_OK ]
+            result = IOTHUB_CLIENT_OK;
+        }
+    }
+
+    return result;
+}
+
+int IoTHubTransport_MQTT_Common_Subscribe_DeviceMethod(IOTHUB_DEVICE_HANDLE handle)
+{
+    int result;
+    PMQTTTRANSPORT_HANDLE_DATA transport_data = (PMQTTTRANSPORT_HANDLE_DATA)handle;
+
+    if (transport_data == NULL)
+    {
+        /*Codes_SRS_IOTHUB_MQTT_TRANSPORT_12_001 : [If the parameter handle is NULL than IoTHubTransport_MQTT_Common_Subscribe_DeviceMethod shall return a non - zero value.]*/
+        LogError("Invalid handle parameter. NULL.");
+        result = MU_FAILURE;
+    }
+    else
+    {
+        if (transport_data->topic_DeviceMethods == NULL)
+        {
+            /*Codes_SRS_IOTHUB_MQTT_TRANSPORT_12_004 : [IoTHubTransport_MQTT_Common_Subscribe_DeviceMethod shall construct the DEVICE_METHOD topic string for subscribe.]*/
+            transport_data->topic_DeviceMethods = STRING_construct(TOPIC_DEVICE_METHOD_SUBSCRIBE);
+            if (transport_data->topic_DeviceMethods == NULL)
+            {
+                /*Codes_SRS_IOTHUB_MQTT_TRANSPORT_12_006 : [Upon failure IoTHubTransport_MQTT_Common_Subscribe_DeviceMethod shall return a non - zero value.]*/
+                LogError("Failure: unable constructing device method subscribe topic");
+                result = MU_FAILURE;
+            }
+            else
+            {
+                /*Codes_SRS_IOTHUB_MQTT_TRANSPORT_12_003 : [IoTHubTransport_MQTT_Common_Subscribe_DeviceMethod shall set the signaling flag for DEVICE_METHOD topic for the receiver's topic list. ]*/
+                transport_data->topics_ToSubscribe |= SUBSCRIBE_DEVICE_METHOD_TOPIC;
+                result = 0;
+            }
+        }
+        else
+        {
+            /*Codes_SRS_IOTHUB_MQTT_TRANSPORT_12_002 : [If the MQTT transport has been previously subscribed to DEVICE_METHOD topic IoTHubTransport_MQTT_Common_Subscribe_DeviceMethod shall do nothing and return 0.]*/
+            result = 0;
+        }
+
+        if (result == 0)
+        {
+            /*Codes_SRS_IOTHUB_MQTT_TRANSPORT_12_005 : [IoTHubTransport_MQTT_Common_Subscribe_DeviceMethod shall schedule the send of the subscription.]*/
+            /*Codes_SRS_IOTHUB_MQTT_TRANSPORT_12_007 : [On success IoTHubTransport_MQTT_Common_Subscribe_DeviceMethod shall return 0.]*/
+            changeStateToSubscribeIfAllowed(transport_data);
+        }
+    }
+    return result;
+}
+
+void IoTHubTransport_MQTT_Common_Unsubscribe_DeviceMethod(TRANSPORT_LL_HANDLE handle)
+{
+    PMQTTTRANSPORT_HANDLE_DATA transport_data = (PMQTTTRANSPORT_HANDLE_DATA)handle;
+    /*Codes_SRS_IOTHUB_MQTT_TRANSPORT_12_008 : [If the parameter handle is NULL than IoTHubTransport_MQTT_Common_Unsubscribe_DeviceMethod shall do nothing and return.]*/
+    if (transport_data != NULL)
+    {
+        /*Codes_SRS_IOTHUB_MQTT_TRANSPORT_12_009 : [If the MQTT transport has not been subscribed to DEVICE_METHOD topic IoTHubTransport_MQTT_Common_Unsubscribe_DeviceMethod shall do nothing and return.]*/
+        if (transport_data->topic_DeviceMethods != NULL)
+        {
+            /*Codes_SRS_IOTHUB_MQTT_TRANSPORT_12_010 : [IoTHubTransport_MQTT_Common_Unsubscribe_DeviceMethod shall construct the DEVICE_METHOD topic string for unsubscribe.]*/
+            const char* unsubscribe[1];
+            unsubscribe[0] = STRING_c_str(transport_data->topic_DeviceMethods);
+
+            /*Codes_SRS_IOTHUB_MQTT_TRANSPORT_12_011 : [IoTHubTransport_MQTT_Common_Unsubscribe_DeviceMethod shall send the unsubscribe.]*/
+            if (mqtt_client_unsubscribe(transport_data->mqttClient, get_next_packet_id(transport_data), unsubscribe, 1) != 0)
+            {
+                LogError("Failure calling mqtt_client_unsubscribe");
+            }
+
+            /*Codes_SRS_IOTHUB_MQTT_TRANSPORT_12_012 : [IoTHubTransport_MQTT_Common_Unsubscribe_DeviceMethod shall removes the signaling flag for DEVICE_METHOD topic from the receiver's topic list. ]*/
+            STRING_delete(transport_data->topic_DeviceMethods);
+            transport_data->topic_DeviceMethods = NULL;
+            transport_data->topics_ToSubscribe &= ~SUBSCRIBE_DEVICE_METHOD_TOPIC;
+        }
+    }
+    else
+    {
+        LogError("Invalid argument to unsubscribe (NULL).");
+    }
+}
+
+int IoTHubTransport_MQTT_Common_DeviceMethod_Response(TRANSPORT_LL_HANDLE handle, METHOD_HANDLE methodId, const unsigned char* response, size_t respSize, int status)
+{
+    int result;
+    MQTTTRANSPORT_HANDLE_DATA* transport_data = (MQTTTRANSPORT_HANDLE_DATA*)handle;
+    if (transport_data != NULL)
+    {
+        /* Codes_SRS_IOTHUB_TRANSPORT_MQTT_COMMON_07_042: [ IoTHubTransport_MQTT_Common_DeviceMethod_Response shall publish an mqtt message for the device method response. ] */
+        DEVICE_METHOD_INFO* dev_method_info = (DEVICE_METHOD_INFO*)methodId;
+        if (dev_method_info == NULL)
+        {
+            LogError("Failure: DEVICE_METHOD_INFO was NULL");
+            result = MU_FAILURE;
+        }
+        else
+        {
+            if (publish_device_method_message(transport_data, status, dev_method_info->request_id, response, respSize) != 0)
+            {
+                /* Codes_SRS_IOTHUB_TRANSPORT_MQTT_COMMON_07_051: [ If any error is encountered, IoTHubTransport_MQTT_Common_DeviceMethod_Response shall return a non-zero value. ] */
+                LogError("Failure: publishing device method response");
+                result = MU_FAILURE;
+            }
+            else
+            {
+                result = 0;
+            }
+            STRING_delete(dev_method_info->request_id);
+            free(dev_method_info);
+        }
+    }
+    else
+    {
+        /* Codes_SRS_IOTHUB_TRANSPORT_MQTT_COMMON_07_041: [ If the parameter handle is NULL than IoTHubTransport_MQTT_Common_DeviceMethod_Response shall return a non-zero value. ] */
+        result = MU_FAILURE;
+        LogError("Failure: invalid TRANSPORT_LL_HANDLE parameter specified");
+    }
+    return result;
+}
+
+static STRING_HANDLE buildTopicMqttMessage(const char* device_id, const char* module_id)
+{
+    if (module_id == NULL)
+    {
+        return STRING_construct_sprintf(TOPIC_DEVICE_MSG, device_id);
+    }
+    else
+    {
+        return STRING_construct_sprintf(TOPIC_DEVICE_MODULE_MSG, device_id, module_id);
+    }
+}
+
+int IoTHubTransport_MQTT_Common_Subscribe(TRANSPORT_LL_HANDLE handle)
+{
+    int result;
+    PMQTTTRANSPORT_HANDLE_DATA transport_data = (PMQTTTRANSPORT_HANDLE_DATA)handle;
+    if (transport_data == NULL)
+    {
+        /* Codes_SRS_IOTHUB_MQTT_TRANSPORT_07_015: [If parameter handle is NULL than IoTHubTransport_MQTT_Common_Subscribe shall return a non-zero value.] */
+        LogError("Invalid handle parameter. NULL.");
+        result = MU_FAILURE;
+    }
+    else
+    {
+        /* Code_SRS_IOTHUB_MQTT_TRANSPORT_07_016: [IoTHubTransport_MQTT_Common_Subscribe shall set a flag to enable mqtt_client_subscribe to be called to subscribe to the Message Topic.] */
+        transport_data->topic_MqttMessage = buildTopicMqttMessage(STRING_c_str(transport_data->device_id), STRING_c_str(transport_data->module_id));
+        if (transport_data->topic_MqttMessage == NULL)
+        {
+            LogError("Failure constructing Message Topic");
+            result = MU_FAILURE;
+        }
+        else
+        {
+            transport_data->topics_ToSubscribe |= SUBSCRIBE_TELEMETRY_TOPIC;
+            /* Code_SRS_IOTHUB_MQTT_TRANSPORT_07_035: [If current packet state is not CONNACT, DISCONNECT_TYPE, or PACKET_TYPE_ERROR then IoTHubTransport_MQTT_Common_Subscribe shall set the packet state to SUBSCRIBE_TYPE.]*/
+            changeStateToSubscribeIfAllowed(transport_data);
+            result = 0;
+        }
+    }
+    return result;
+}
+
+void IoTHubTransport_MQTT_Common_Unsubscribe(TRANSPORT_LL_HANDLE handle)
+{
+    PMQTTTRANSPORT_HANDLE_DATA transport_data = (PMQTTTRANSPORT_HANDLE_DATA)handle;
+    /* Codes_SRS_IOTHUB_MQTT_TRANSPORT_07_019: [If parameter handle is NULL then IoTHubTransport_MQTT_Common_Unsubscribe shall do nothing.] */
+    if (transport_data != NULL)
+    {
+        /* Codes_SRS_IOTHUB_MQTT_TRANSPORT_07_020: [IoTHubTransport_MQTT_Common_Unsubscribe shall call mqtt_client_unsubscribe to unsubscribe the mqtt message topic.] */
+        const char* unsubscribe[1];
+        unsubscribe[0] = STRING_c_str(transport_data->topic_MqttMessage);
+        if (mqtt_client_unsubscribe(transport_data->mqttClient, get_next_packet_id(transport_data), unsubscribe, 1) != 0)
+        {
+            LogError("Failure calling mqtt_client_unsubscribe");
+        }
+        STRING_delete(transport_data->topic_MqttMessage);
+        transport_data->topic_MqttMessage = NULL;
+        transport_data->topics_ToSubscribe &= ~SUBSCRIBE_TELEMETRY_TOPIC;
+    }
+    else
+    {
+        LogError("Invalid argument to unsubscribe (NULL).");
+    }
+}
+
+IOTHUB_PROCESS_ITEM_RESULT IoTHubTransport_MQTT_Common_ProcessItem(TRANSPORT_LL_HANDLE handle, IOTHUB_IDENTITY_TYPE item_type, IOTHUB_IDENTITY_INFO* iothub_item)
+{
+    IOTHUB_PROCESS_ITEM_RESULT result;
+    /* Codes_SRS_IOTHUBCLIENT_LL_07_001: [ If handle or iothub_item are NULL then IoTHubTransport_MQTT_Common_ProcessItem shall return IOTHUB_PROCESS_ERROR. ]*/
+    if (handle == NULL || iothub_item == NULL)
+    {
+        LogError("Invalid handle parameter iothub_item=%p", iothub_item);
+        result = IOTHUB_PROCESS_ERROR;
+    }
+    else
+    {
+        PMQTTTRANSPORT_HANDLE_DATA transport_data = (PMQTTTRANSPORT_HANDLE_DATA)handle;
+
+        if (transport_data->currPacketState == PUBLISH_TYPE)
+        {
+            // Ensure the reported property suback has been received
+            if (item_type == IOTHUB_TYPE_DEVICE_TWIN && transport_data->twin_resp_sub_recv)
+            {
+                MQTT_DEVICE_TWIN_ITEM* mqtt_info = create_device_twin_message(transport_data, REPORTED_STATE, iothub_item->device_twin->item_id);
+                if (mqtt_info == NULL)
+                {
+                    /* Codes_SRS_IOTHUBCLIENT_LL_07_004: [ If any errors are encountered IoTHubTransport_MQTT_Common_ProcessItem shall return IOTHUB_PROCESS_ERROR. ]*/
+                    result = IOTHUB_PROCESS_ERROR;
+                }
+                else
+                {
+                    /*Codes_SRS_IOTHUBCLIENT_LL_07_003: [ IoTHubTransport_MQTT_Common_ProcessItem shall publish a message to the mqtt protocol with the message topic for the message type.]*/
+                    /* Codes_SRS_IOTHUBCLIENT_LL_07_005: [ If successful IoTHubTransport_MQTT_Common_ProcessItem shall add mqtt info structure acknowledgement queue. ] */
+                    DList_InsertTailList(&transport_data->ack_waiting_queue, &mqtt_info->entry);
+
+                    if (publish_device_twin_message(transport_data, iothub_item->device_twin, mqtt_info) != 0)
+                    {
+                        DList_RemoveEntryList(&mqtt_info->entry);
+
+                        free(mqtt_info);
+                        /* Codes_SRS_IOTHUBCLIENT_LL_07_004: [ If any errors are encountered IoTHubTransport_MQTT_Common_ProcessItem shall return IOTHUB_PROCESS_ERROR. ]*/
+                        result = IOTHUB_PROCESS_ERROR;
+                    }
+                    else
+                    {
+                        result = IOTHUB_PROCESS_OK;
+                    }
+                }
+            }
+            else
+            {
+                /* Codes_SRS_IOTHUBCLIENT_LL_07_006: [ If the item_type is not a supported type IoTHubTransport_MQTT_Common_ProcessItem shall return IOTHUB_PROCESS_CONTINUE. ]*/
+                result = IOTHUB_PROCESS_CONTINUE;
+            }
+        }
+        else
+        {
+            /* Codes_SRS_IOTHUBCLIENT_LL_07_002: [ If the mqtt is not ready to publish messages IoTHubTransport_MQTT_Common_ProcessItem shall return IOTHUB_PROCESS_NOT_CONNECTED. ] */
+            result = IOTHUB_PROCESS_NOT_CONNECTED;
+        }
+    }
+    return result;
+}
+
+/* Codes_SRS_IOTHUB_MQTT_TRANSPORT_07_054: [ IoTHubTransport_MQTT_Common_DoWork shall subscribe to the Notification and get_state Topics if they are defined. ] */
+void IoTHubTransport_MQTT_Common_DoWork(TRANSPORT_LL_HANDLE handle)
+{
+    /* Codes_SRS_IOTHUB_MQTT_TRANSPORT_07_026: [IoTHubTransport_MQTT_Common_DoWork shall do nothing if parameter handle and/or iotHubClientHandle is NULL.] */
+    PMQTTTRANSPORT_HANDLE_DATA transport_data = (PMQTTTRANSPORT_HANDLE_DATA)handle;
+    if (transport_data != NULL)
+    {
+        if (InitializeConnection(transport_data) == 0)
+        {
+            if (transport_data->mqttClientStatus == MQTT_CLIENT_STATUS_PENDING_CLOSE)
+            {
+                mqtt_client_disconnect(transport_data->mqttClient, NULL, NULL);
+                transport_data->mqttClientStatus = MQTT_CLIENT_STATUS_NOT_CONNECTED;
+            }
+            else if (transport_data->currPacketState == CONNACK_TYPE || transport_data->currPacketState == SUBSCRIBE_TYPE)
+            {
+                SubscribeToMqttProtocol(transport_data);
+            }
+            else if (transport_data->currPacketState == SUBACK_TYPE)
+            {
+                if ((transport_data->topic_NotifyState != NULL || transport_data->topic_GetState != NULL) &&
+                    !transport_data->device_twin_get_sent)
+                {
+                    /* Codes_SRS_IOTHUB_MQTT_TRANSPORT_07_055: [ IoTHubTransport_MQTT_Common_DoWork shall send a device twin get property message upon successfully retrieving a SUBACK on device twin topics. ] */
+                    MQTT_DEVICE_TWIN_ITEM* mqtt_info;
+
+                    if ((mqtt_info = create_device_twin_message(transport_data, RETRIEVE_PROPERTIES, 0)) == NULL)
+                    {
+                        LogError("Failure: could not create message for twin get command");
+                    }
+                    else if (publish_device_twin_get_message(transport_data, mqtt_info) == 0)
+                    {
+                        transport_data->device_twin_get_sent = true;
+                    }
+                    else
+                    {
+                        LogError("Failure: sending device twin get property command.");
+                        destroy_device_twin_get_message(mqtt_info);
+                    }
+                }
+                // Publish can be called now
+                transport_data->currPacketState = PUBLISH_TYPE;
+            }
+            else if (transport_data->currPacketState == PUBLISH_TYPE)
+            {
+                PDLIST_ENTRY currentListEntry = transport_data->waitingToSend->Flink;
+                /* Codes_SRS_IOTHUB_MQTT_TRANSPORT_07_027: [IoTHubTransport_MQTT_Common_DoWork shall inspect the "waitingToSend" DLIST passed in config structure.] */
+                while (currentListEntry != transport_data->waitingToSend)
+                {
+                    IOTHUB_MESSAGE_LIST* iothubMsgList = containingRecord(currentListEntry, IOTHUB_MESSAGE_LIST, entry);
+                    DLIST_ENTRY savedFromCurrentListEntry;
+                    savedFromCurrentListEntry.Flink = currentListEntry->Flink;
+
+                    /* Codes_SRS_IOTHUB_MQTT_TRANSPORT_07_027: [IoTHubTransport_MQTT_Common_DoWork shall inspect the "waitingToSend" DLIST passed in config structure.] */
+                    size_t messageLength;
+                    const unsigned char* messagePayload = NULL;
+                    if (!RetrieveMessagePayload(iothubMsgList->messageHandle, &messagePayload, &messageLength))
+                    {
+                        (void)(DList_RemoveEntryList(currentListEntry));
+                        sendMsgComplete(iothubMsgList, transport_data, IOTHUB_CLIENT_CONFIRMATION_ERROR);
+                        LogError("Failure result from IoTHubMessage_GetData");
+                    }
+                    else
+                    {
+                        /* Codes_SRS_IOTHUB_MQTT_TRANSPORT_07_029: [IoTHubTransport_MQTT_Common_DoWork shall create a MQTT_MESSAGE_HANDLE and pass this to a call to mqtt_client_publish.] */
+                        MQTT_MESSAGE_DETAILS_LIST* mqttMsgEntry = (MQTT_MESSAGE_DETAILS_LIST*)malloc(sizeof(MQTT_MESSAGE_DETAILS_LIST));
+                        if (mqttMsgEntry == NULL)
+                        {
+                            LogError("Allocation Error: Failure allocating MQTT Message Detail List.");
+                        }
+                        else
+                        {
+                            mqttMsgEntry->retryCount = 0;
+                            mqttMsgEntry->iotHubMessageEntry = iothubMsgList;
+                            mqttMsgEntry->packet_id = get_next_packet_id(transport_data);
+                            if (publish_mqtt_telemetry_msg(transport_data, mqttMsgEntry, messagePayload, messageLength) != 0)
+                            {
+                                (void)(DList_RemoveEntryList(currentListEntry));
+                                sendMsgComplete(iothubMsgList, transport_data, IOTHUB_CLIENT_CONFIRMATION_ERROR);
+                                free(mqttMsgEntry);
+                            }
+                            else
+                            {
+                                // Remove the message from the waiting queue ...
+                                (void)(DList_RemoveEntryList(currentListEntry));
+                                // and add it to the ack queue
+                                DList_InsertTailList(&(transport_data->telemetry_waitingForAck), &(mqttMsgEntry->entry));
+                            }
+                        }
+                    }
+                    currentListEntry = savedFromCurrentListEntry.Flink;
+                }
+
+                if (transport_data->twin_resp_sub_recv)
+                {
+                    sendPendingGetTwinRequests(transport_data);
+                }
+            }
+            /* Codes_SRS_IOTHUB_MQTT_TRANSPORT_07_030: [IoTHubTransport_MQTT_Common_DoWork shall call mqtt_client_dowork everytime it is called if it is connected.] */
+            mqtt_client_dowork(transport_data->mqttClient);
+        }
+
+        // Check the ack messages timeouts
+        process_queued_ack_messages(transport_data);
+        removeExpiredTwinRequests(transport_data);
+    }
+}
+
+IOTHUB_CLIENT_RESULT IoTHubTransport_MQTT_Common_GetSendStatus(TRANSPORT_LL_HANDLE handle, IOTHUB_CLIENT_STATUS *iotHubClientStatus)
+{
+    IOTHUB_CLIENT_RESULT result;
+
+    if (handle == NULL || iotHubClientStatus == NULL)
+    {
+    /* Codes_SRS_IOTHUB_MQTT_TRANSPORT_07_023: [IoTHubTransport_MQTT_Common_GetSendStatus shall return IOTHUB_CLIENT_INVALID_ARG if called with NULL parameter.] */
+    LogError("invalid arument.");
+    result = IOTHUB_CLIENT_INVALID_ARG;
+    }
+    else
+    {
+    MQTTTRANSPORT_HANDLE_DATA* handleData = (MQTTTRANSPORT_HANDLE_DATA*)handle;
+    if (!DList_IsListEmpty(handleData->waitingToSend) || !DList_IsListEmpty(&(handleData->telemetry_waitingForAck)))
+    {
+        /* Codes_SRS_IOTHUB_MQTT_TRANSPORT_07_025: [IoTHubTransport_MQTT_Common_GetSendStatus shall return IOTHUB_CLIENT_OK and status IOTHUB_CLIENT_SEND_STATUS_BUSY if there are currently event items to be sent or being sent.] */
+        *iotHubClientStatus = IOTHUB_CLIENT_SEND_STATUS_BUSY;
+    }
+    else
+    {
+        /* Codes_SRS_IOTHUB_MQTT_TRANSPORT_07_024: [IoTHubTransport_MQTT_Common_GetSendStatus shall return IOTHUB_CLIENT_OK and status IOTHUB_CLIENT_SEND_STATUS_IDLE if there are currently no event items to be sent or being sent.] */
+        *iotHubClientStatus = IOTHUB_CLIENT_SEND_STATUS_IDLE;
+    }
+    result = IOTHUB_CLIENT_OK;
+    }
+    return result;
+}
+
+IOTHUB_CLIENT_RESULT IoTHubTransport_MQTT_Common_SetOption(TRANSPORT_LL_HANDLE handle, const char* option, const void* value)
+{
+    /* Codes_SRS_IOTHUB_MQTT_TRANSPORT_07_021: [If any parameter is NULL then IoTHubTransport_MQTT_Common_SetOption shall return IOTHUB_CLIENT_INVALID_ARG.] */
+    IOTHUB_CLIENT_RESULT result;
+    if (
+        (handle == NULL) ||
+        (option == NULL) ||
+        (value == NULL)
+        )
+    {
+        result = IOTHUB_CLIENT_INVALID_ARG;
+        LogError("invalid parameter (NULL) passed to IoTHubTransport_MQTT_Common_SetOption.");
+    }
+    else
+    {
+        MQTTTRANSPORT_HANDLE_DATA* transport_data = (MQTTTRANSPORT_HANDLE_DATA*)handle;
+
+        IOTHUB_CREDENTIAL_TYPE cred_type = IoTHubClient_Auth_Get_Credential_Type(transport_data->authorization_module);
+
+        /* Codes_SRS_IOTHUB_MQTT_TRANSPORT_07_031: [If the option parameter is set to "logtrace" then the value shall be a bool_ptr and the value will determine if the mqtt client log is on or off.] */
+        if (strcmp(OPTION_LOG_TRACE, option) == 0)
+        {
+            transport_data->log_trace = *((bool*)value);
+            mqtt_client_set_trace(transport_data->mqttClient, transport_data->log_trace, transport_data->raw_trace);
+            result = IOTHUB_CLIENT_OK;
+        }
+        else if (strcmp("rawlogtrace", option) == 0)
+        {
+            transport_data->raw_trace = *((bool*)value);
+            mqtt_client_set_trace(transport_data->mqttClient, transport_data->log_trace, transport_data->raw_trace);
+            result = IOTHUB_CLIENT_OK;
+        }
+        else if (strcmp(OPTION_AUTO_URL_ENCODE_DECODE, option) == 0)
+        {
+            transport_data->auto_url_encode_decode = *((bool*)value);
+            result = IOTHUB_CLIENT_OK;
+        }
+        else if (strcmp(OPTION_CONNECTION_TIMEOUT, option) == 0)
+        {
+            int* connection_time = (int*)value;
+            if (*connection_time != transport_data->connect_timeout_in_sec)
+            {
+                transport_data->connect_timeout_in_sec = (uint16_t)(*connection_time);
+            }
+            result = IOTHUB_CLIENT_OK;
+        }
+        else if (strcmp(OPTION_KEEP_ALIVE, option) == 0)
+        {
+            /* Codes_SRS_IOTHUB_MQTT_TRANSPORT_07_036: [If the option parameter is set to "keepalive" then the value shall be a int_ptr and the value will determine the mqtt keepalive time that is set for pings.] */
+            int* keepAliveOption = (int*)value;
+            /* Codes_SRS_IOTHUB_MQTT_TRANSPORT_07_037 : [If the option parameter is set to supplied int_ptr keepalive is the same value as the existing keepalive then IoTHubTransport_MQTT_Common_SetOption shall do nothing.] */
+            if (*keepAliveOption != transport_data->keepAliveValue)
+            {
+                transport_data->keepAliveValue = (uint16_t)(*keepAliveOption);
+                if (transport_data->mqttClientStatus != MQTT_CLIENT_STATUS_NOT_CONNECTED)
+                {
+                    /* Codes_SRS_IOTHUB_MQTT_TRANSPORT_07_038: [If the client is connected when the keepalive is set then IoTHubTransport_MQTT_Common_SetOption shall disconnect and reconnect with the specified keepalive value.] */
+                    DisconnectFromClient(transport_data);
+                }
+            }
+            result = IOTHUB_CLIENT_OK;
+        }
+        /* Codes_SRS_IOTHUB_MQTT_TRANSPORT_07_039: [If the option parameter is set to "x509certificate" then the value shall be a const char of the certificate to be used for x509.] */
+        else if ((strcmp(OPTION_X509_CERT, option) == 0) && (cred_type != IOTHUB_CREDENTIAL_TYPE_X509 && cred_type != IOTHUB_CREDENTIAL_TYPE_UNKNOWN))
+        {
+            LogError("x509certificate specified, but authentication method is not x509");
+            result = IOTHUB_CLIENT_INVALID_ARG;
+        }
+        /* Codes_SRS_IOTHUB_MQTT_TRANSPORT_07_040: [If the option parameter is set to "x509privatekey" then the value shall be a const char of the RSA Private Key to be used for x509.] */
+        else if ((strcmp(OPTION_X509_PRIVATE_KEY, option) == 0) && (cred_type != IOTHUB_CREDENTIAL_TYPE_X509 && cred_type != IOTHUB_CREDENTIAL_TYPE_UNKNOWN))
+        {
+            LogError("x509privatekey specified, but authentication method is not x509");
+            result = IOTHUB_CLIENT_INVALID_ARG;
+        }
+        else if (strcmp(OPTION_RETRY_INTERVAL_SEC, option) == 0)
+        {
+            if (retry_control_set_option(transport_data->retry_control_handle, RETRY_CONTROL_OPTION_INITIAL_WAIT_TIME_IN_SECS, value) != 0)
+            {
+                LogError("Failure setting retry interval option");
+                result = IOTHUB_CLIENT_ERROR;
+            }
+            else
+            {
+                result = IOTHUB_CLIENT_OK;
+            }
+        }
+        else if (strcmp(OPTION_RETRY_MAX_DELAY_SECS, option) == 0)
+        {
+            if (retry_control_set_option(transport_data->retry_control_handle, RETRY_CONTROL_OPTION_MAX_DELAY_IN_SECS, value) != 0)
+            {
+                LogError("Failure setting retry max delay option");
+                result = IOTHUB_CLIENT_ERROR;
+            }
+            else
+            {
+                result = IOTHUB_CLIENT_OK;
+            }
+        }
+        else if (strcmp(OPTION_HTTP_PROXY, option) == 0)
+        {
+            /* Codes_SRS_IOTHUB_TRANSPORT_MQTT_COMMON_01_001: [ If `option` is `proxy_data`, `value` shall be used as an `HTTP_PROXY_OPTIONS*`. ]*/
+            HTTP_PROXY_OPTIONS* proxy_options = (HTTP_PROXY_OPTIONS*)value;
+
+            if (transport_data->xioTransport != NULL)
+            {
+                /* Codes_SRS_IOTHUB_TRANSPORT_MQTT_COMMON_01_007: [ If the underlying IO has already been created, then `IoTHubTransport_MQTT_Common_SetOption` shall fail and return `IOTHUB_CLIENT_ERROR`. ]*/
+                LogError("Cannot set proxy option once the underlying IO is created");
+                result = IOTHUB_CLIENT_ERROR;
+            }
+            else if (proxy_options->host_address == NULL)
+            {
+                /* Codes_SRS_IOTHUB_TRANSPORT_MQTT_COMMON_01_003: [ If `host_address` is NULL, `IoTHubTransport_MQTT_Common_SetOption` shall fail and return `IOTHUB_CLIENT_INVALID_ARG`. ]*/
+                LogError("NULL host_address in proxy options");
+                result = IOTHUB_CLIENT_INVALID_ARG;
+            }
+            /* Codes_SRS_IOTHUB_TRANSPORT_MQTT_COMMON_01_006: [ If only one of `username` and `password` is NULL, `IoTHubTransport_MQTT_Common_SetOption` shall fail and return `IOTHUB_CLIENT_INVALID_ARG`. ]*/
+            else if (((proxy_options->username == NULL) || (proxy_options->password == NULL)) &&
+                (proxy_options->username != proxy_options->password))
+            {
+                LogError("Only one of username and password for proxy settings was NULL");
+                result = IOTHUB_CLIENT_INVALID_ARG;
+            }
+            else
+            {
+                char* copied_proxy_hostname = NULL;
+                char* copied_proxy_username = NULL;
+                char* copied_proxy_password = NULL;
+
+                /* Codes_SRS_IOTHUB_TRANSPORT_MQTT_COMMON_01_002: [ The fields `host_address`, `port`, `username` and `password` shall be saved for later used (needed when creating the underlying IO to be used by the transport). ]*/
+                transport_data->http_proxy_port = proxy_options->port;
+                if (mallocAndStrcpy_s(&copied_proxy_hostname, proxy_options->host_address) != 0)
+                {
+                    /* Codes_SRS_IOTHUB_TRANSPORT_MQTT_COMMON_01_004: [ If copying `host_address`, `username` or `password` fails, `IoTHubTransport_MQTT_Common_SetOption` shall fail and return `IOTHUB_CLIENT_ERROR`. ]*/
+                    LogError("Cannot copy HTTP proxy hostname");
+                    result = IOTHUB_CLIENT_ERROR;
+                }
+                /* Codes_SRS_IOTHUB_TRANSPORT_MQTT_COMMON_01_005: [ `username` and `password` shall be allowed to be NULL. ]*/
+                else if ((proxy_options->username != NULL) && (mallocAndStrcpy_s(&copied_proxy_username, proxy_options->username) != 0))
+                {
+                    /* Codes_SRS_IOTHUB_TRANSPORT_MQTT_COMMON_01_004: [ If copying `host_address`, `username` or `password` fails, `IoTHubTransport_MQTT_Common_SetOption` shall fail and return `IOTHUB_CLIENT_ERROR`. ]*/
+                    free(copied_proxy_hostname);
+                    LogError("Cannot copy HTTP proxy username");
+                    result = IOTHUB_CLIENT_ERROR;
+                }
+                /* Codes_SRS_IOTHUB_TRANSPORT_MQTT_COMMON_01_005: [ `username` and `password` shall be allowed to be NULL. ]*/
+                else if ((proxy_options->password != NULL) && (mallocAndStrcpy_s(&copied_proxy_password, proxy_options->password) != 0))
+                {
+                    /* Codes_SRS_IOTHUB_TRANSPORT_MQTT_COMMON_01_004: [ If copying `host_address`, `username` or `password` fails, `IoTHubTransport_MQTT_Common_SetOption` shall fail and return `IOTHUB_CLIENT_ERROR`. ]*/
+                    if (copied_proxy_username != NULL)
+                    {
+                        free(copied_proxy_username);
+                    }
+                    free(copied_proxy_hostname);
+                    LogError("Cannot copy HTTP proxy password");
+                    result = IOTHUB_CLIENT_ERROR;
+                }
+                else
+                {
+                    /* Codes_SRS_IOTHUB_TRANSPORT_MQTT_COMMON_01_009: [ When setting the proxy options succeeds any previously saved proxy options shall be freed. ]*/
+                    free_proxy_data(transport_data);
+
+                    transport_data->http_proxy_hostname = copied_proxy_hostname;
+                    transport_data->http_proxy_username = copied_proxy_username;
+                    transport_data->http_proxy_password = copied_proxy_password;
+
+                    /* Codes_SRS_IOTHUB_TRANSPORT_MQTT_COMMON_01_008: [ If setting the `proxy_data` option suceeds, `IoTHubTransport_MQTT_Common_SetOption` shall return `IOTHUB_CLIENT_OK` ]*/
+                    result = IOTHUB_CLIENT_OK;
+                }
+            }
+        }
+        else
+        {
+            /* Codes_SRS_IOTHUB_MQTT_TRANSPORT_07_039: [If the option parameter is set to "x509certificate" then the value shall be a const char of the certificate to be used for x509.] */
+            if (((strcmp(OPTION_X509_CERT, option) == 0) || (strcmp(OPTION_X509_PRIVATE_KEY, option) == 0)) && (cred_type != IOTHUB_CREDENTIAL_TYPE_X509))
+            {
+                IoTHubClient_Auth_Set_x509_Type(transport_data->authorization_module, true);
+            }
+
+            /* Codes_SRS_IOTHUB_MQTT_TRANSPORT_07_032: [IoTHubTransport_MQTT_Common_SetOption shall pass down the option to xio_setoption if the option parameter is not a known option string for the MQTT transport.] */
+            if (GetTransportProviderIfNecessary(transport_data) == 0)
+            {
+                if (xio_setoption(transport_data->xioTransport, option, value) == 0)
+                {
+                    result = IOTHUB_CLIENT_OK;
+                }
+                else
+                {
+                    /* Codes_SRS_IOTHUB_MQTT_TRANSPORT_07_132: [IoTHubTransport_MQTT_Common_SetOption shall return IOTHUB_CLIENT_INVALID_ARG xio_setoption fails] */
+                    result = IOTHUB_CLIENT_INVALID_ARG;
+                }
+            }
+            else
+            {
+                result = IOTHUB_CLIENT_ERROR;
+            }
+        }
+    }
+    return result;
+}
+
+static bool check_module_ids_equal(const char* transportModuleId, const char* deviceModuleId)
+{
+    if ((transportModuleId != NULL) && (deviceModuleId == NULL))
+    {
+        return false;
+    }
+    else if ((transportModuleId == NULL) && (deviceModuleId != NULL))
+    {
+        return false;
+    }
+    else if ((transportModuleId == NULL) && (deviceModuleId == NULL))
+    {
+        return true;
+    }
+    else
+    {
+        return (0 == strcmp(transportModuleId, deviceModuleId));
+    }
+}
+
+TRANSPORT_LL_HANDLE IoTHubTransport_MQTT_Common_Register(TRANSPORT_LL_HANDLE handle, const IOTHUB_DEVICE_CONFIG* device, PDLIST_ENTRY waitingToSend)
+{
+    TRANSPORT_LL_HANDLE result = NULL;
+
+    // Codes_SRS_IOTHUB_MQTT_TRANSPORT_17_001: [ IoTHubTransport_MQTT_Common_Register shall return NULL if the TRANSPORT_LL_HANDLE is NULL.]
+    // Codes_SRS_IOTHUB_MQTT_TRANSPORT_17_002: [ IoTHubTransport_MQTT_Common_Register shall return NULL if device or waitingToSend are NULL.]
+    if ((handle == NULL) || (device == NULL) || (waitingToSend == NULL))
+    {
+        LogError("IoTHubTransport_MQTT_Common_Register: handle, device or waitingToSend is NULL.");
+        result = NULL;
+    }
+    else
+    {
+        MQTTTRANSPORT_HANDLE_DATA* transport_data = (MQTTTRANSPORT_HANDLE_DATA*)handle;
+
+        // Codes_SRS_IOTHUB_MQTT_TRANSPORT_03_001: [ IoTHubTransport_MQTT_Common_Register shall return NULL if deviceId, or both deviceKey and deviceSasToken are NULL.]
+        if (device->deviceId == NULL)
+        {
+            LogError("IoTHubTransport_MQTT_Common_Register: deviceId is NULL.");
+            result = NULL;
+        }
+        // Codes_SRS_IOTHUB_MQTT_TRANSPORT_03_002: [ IoTHubTransport_MQTT_Common_Register shall return NULL if both deviceKey and deviceSasToken are provided.]
+        else if ((device->deviceKey != NULL) && (device->deviceSasToken != NULL))
+        {
+            LogError("IoTHubTransport_MQTT_Common_Register: Both deviceKey and deviceSasToken are defined. Only one can be used.");
+            result = NULL;
+        }
+        else
+        {
+            // Codes_SRS_IOTHUB_MQTT_TRANSPORT_17_003: [ IoTHubTransport_MQTT_Common_Register shall return NULL if deviceId or deviceKey do not match the deviceId and deviceKey passed in during IoTHubTransport_MQTT_Common_Create.]
+            if (strcmp(STRING_c_str(transport_data->device_id), device->deviceId) != 0)
+            {
+                LogError("IoTHubTransport_MQTT_Common_Register: deviceId does not match.");
+                result = NULL;
+            }
+            else if (!check_module_ids_equal(STRING_c_str(transport_data->module_id), device->moduleId))
+            {
+                LogError("IoTHubTransport_MQTT_Common_Register: moduleId does not match.");
+                result = NULL;
+            }
+            // Codes_SRS_IOTHUB_TRANSPORT_MQTT_COMMON_43_001: [ IoTHubTransport_MQTT_Common_Register shall return NULL if deviceKey is NULL when credential type is IOTHUB_CREDENTIAL_TYPE_DEVICE_KEY ]
+            else if (IoTHubClient_Auth_Get_Credential_Type(transport_data->authorization_module) == IOTHUB_CREDENTIAL_TYPE_DEVICE_KEY &&
+                ((device->deviceKey == NULL) || (strcmp(IoTHubClient_Auth_Get_DeviceKey(transport_data->authorization_module), device->deviceKey) != 0)))
+            {
+                LogError("IoTHubTransport_MQTT_Common_Register: deviceKey does not match.");
+                result = NULL;
+            }
+            else
+            {
+                if (transport_data->isRegistered == true)
+                {
+                    LogError("Transport already has device registered by id: [%s]", device->deviceId);
+                    result = NULL;
+                }
+                else
+                {
+                    transport_data->isRegistered = true;
+                    // Codes_SRS_IOTHUB_MQTT_TRANSPORT_17_004: [ IoTHubTransport_MQTT_Common_Register shall return the TRANSPORT_LL_HANDLE as the TRANSPORT_LL_HANDLE. ]
+                    result = (TRANSPORT_LL_HANDLE)handle;
+                }
+            }
+        }
+    }
+
+    return result;
+}
+
+void IoTHubTransport_MQTT_Common_Unregister(TRANSPORT_LL_HANDLE deviceHandle)
+{
+    // Codes_SRS_IOTHUB_MQTT_TRANSPORT_17_005: [ If deviceHandle is NULL `IoTHubTransport_MQTT_Common_Unregister` shall do nothing. ]
+    if (deviceHandle != NULL)
+    {
+        MQTTTRANSPORT_HANDLE_DATA* transport_data = (MQTTTRANSPORT_HANDLE_DATA*)deviceHandle;
+
+        transport_data->isRegistered = false;
+    }
+}
+
+STRING_HANDLE IoTHubTransport_MQTT_Common_GetHostname(TRANSPORT_LL_HANDLE handle)
+{
+    STRING_HANDLE result;
+    /*Codes_SRS_IOTHUB_MQTT_TRANSPORT_02_001: [ If handle is NULL then IoTHubTransport_MQTT_Common_GetHostname shall fail and return NULL. ]*/
+    if (handle == NULL)
+    {
+        result = NULL;
+    }
+    /*Codes_SRS_IOTHUB_MQTT_TRANSPORT_02_002: [ Otherwise IoTHubTransport_MQTT_Common_GetHostname shall return a non-NULL STRING_HANDLE containg the hostname. ]*/
+    else if ((result = STRING_clone(((MQTTTRANSPORT_HANDLE_DATA*)(handle))->hostAddress)) == NULL)
+    {
+        LogError("Cannot provide the target host name (STRING_clone failed).");
+    }
+
+    return result;
+}
+
+IOTHUB_CLIENT_RESULT IoTHubTransport_MQTT_Common_SendMessageDisposition(MESSAGE_CALLBACK_INFO* message_data, IOTHUBMESSAGE_DISPOSITION_RESULT disposition)
+{
+    (void)disposition;
+
+    IOTHUB_CLIENT_RESULT result;
+    if (message_data)
+    {
+        if (message_data->messageHandle)
+        {
+            IoTHubMessage_Destroy(message_data->messageHandle);
+            result = IOTHUB_CLIENT_OK;
+        }
+        else
+        {
+            /*Codes_SRS_IOTHUB_MQTT_TRANSPORT_10_002: [If any of the messageData fields are NULL, IoTHubTransport_MQTT_Common_SendMessageDisposition shall fail and return IOTHUB_CLIENT_ERROR. ]*/
+            LogError("message handle is NULL");
+            result = IOTHUB_CLIENT_ERROR;
+        }
+        free(message_data);
+    }
+    else
+    {
+        /*Codes_SRS_IOTHUB_MQTT_TRANSPORT_10_001: [If messageData is NULL, IoTHubTransport_MQTT_Common_SendMessageDisposition shall fail and return IOTHUB_CLIENT_ERROR. ]*/
+        LogError("message_data is NULL");
+        result = IOTHUB_CLIENT_ERROR;
+    }
+    return result;
+}
+
+
+int IoTHubTransport_MQTT_Common_Subscribe_InputQueue(TRANSPORT_LL_HANDLE handle)
+{
+    int result;
+    PMQTTTRANSPORT_HANDLE_DATA transport_data = (PMQTTTRANSPORT_HANDLE_DATA)handle;
+    if (transport_data == NULL)
+    {
+        // Codes_SRS_IOTHUB_TRANSPORT_MQTT_COMMON_31_066: [ If parameter handle is NULL than IoTHubTransport_MQTT_Common_Subscribe_InputQueue shall return a non-zero value.]
+        LogError("Invalid handle parameter. NULL.");
+        result = MU_FAILURE;
+    }
+    else if (transport_data->module_id == NULL)
+    {
+        // Codes_SRS_IOTHUB_TRANSPORT_MQTT_COMMON_31_073: [ If module ID is not set on the transpont, IoTHubTransport_MQTT_Common_Unsubscribe_InputQueue shall fail.]
+        LogError("ModuleID must be specified for input queues. NULL.");
+        result = MU_FAILURE;
+    }
+    else if ((transport_data->topic_InputQueue == NULL) &&
+        (transport_data->topic_InputQueue = STRING_construct_sprintf(TOPIC_INPUT_QUEUE_NAME, STRING_c_str(transport_data->device_id), STRING_c_str(transport_data->module_id))) == NULL)
+    {
+        LogError("Failure constructing Message Topic");
+        result = MU_FAILURE;
+    }
+    else
+    {
+        // Codes_SRS_IOTHUB_TRANSPORT_MQTT_COMMON_31_067: [ IoTHubTransport_MQTT_Common_Subscribe_InputQueue shall set a flag to enable mqtt_client_subscribe to be called to subscribe to the input queue Message Topic.]
+        transport_data->topics_ToSubscribe |= SUBSCRIBE_INPUT_QUEUE_TOPIC;
+        changeStateToSubscribeIfAllowed(transport_data);
+        // Codes_SRS_IOTHUB_TRANSPORT_MQTT_COMMON_31_070: [ On success IoTHubTransport_MQTT_Common_Subscribe_InputQueue shall return 0.]
+        result = 0;
+    }
+    return result;
+}
+
+void IoTHubTransport_MQTT_Common_Unsubscribe_InputQueue(TRANSPORT_LL_HANDLE handle)
+{
+    PMQTTTRANSPORT_HANDLE_DATA transport_data = (PMQTTTRANSPORT_HANDLE_DATA)handle;
+    if ((transport_data != NULL) && (transport_data->topic_InputQueue != NULL))
+    {
+        // Codes_SRS_IOTHUB_TRANSPORT_MQTT_COMMON_31_072: [ IoTHubTransport_MQTT_Common_Unsubscribe_InputQueue shall call mqtt_client_unsubscribe to unsubscribe the mqtt input queue message topic.]
+        const char* unsubscribe[1];
+        unsubscribe[0] = STRING_c_str(transport_data->topic_InputQueue);
+        if (mqtt_client_unsubscribe(transport_data->mqttClient, get_next_packet_id(transport_data), unsubscribe, 1) != 0)
+        {
+            LogError("Failure calling mqtt_client_unsubscribe");
+        }
+        STRING_delete(transport_data->topic_InputQueue);
+        transport_data->topic_InputQueue = NULL;
+        transport_data->topics_ToSubscribe &= ~SUBSCRIBE_INPUT_QUEUE_TOPIC;
+    }
+    else
+    {
+        // Codes_SRS_IOTHUB_TRANSPORT_MQTT_COMMON_31_071: [ If parameter handle is NULL then IoTHubTransport_MQTT_Common_Unsubscribe_InputQueue shall do nothing.]
+        LogError("Invalid argument to unsubscribe input queue (NULL).");
+    }
+}
+
+int IoTHubTransport_MQTT_SetCallbackContext(TRANSPORT_LL_HANDLE handle, void* ctx)
+{
+    int result;
+    if (handle == NULL)
+    {
+        LogError("Invalid parameter specified handle: %p", handle);
+        result = MU_FAILURE;
+    }
+    else
+    {
+        MQTTTRANSPORT_HANDLE_DATA* transport_data = (MQTTTRANSPORT_HANDLE_DATA*)handle;
+        transport_data->transport_ctx = ctx;
+        result = 0;
+    }
+    return result;
+}
+
+int IoTHubTransport_MQTT_GetSupportedPlatformInfo(TRANSPORT_LL_HANDLE handle, PLATFORM_INFO_OPTION* info)
+{
+    int result;
+
+    if (handle == NULL || info == NULL)
+    {
+        LogError("Invalid parameter specified (handle: %p, info: %p)", handle, info);
+        result = MU_FAILURE;
+    }
+    else
+    {
+        *info = PLATFORM_INFO_OPTION_RETRIEVE_SQM;
+        result = 0;
+    }
+
+    return result;
+}
Index: azure_iot_hub_f767zi/trunk/azure_iot_sdk/iothub_client/src/iothubtransporthttp.c
===================================================================
--- azure_iot_hub_f767zi/trunk/azure_iot_sdk/iothub_client/src/iothubtransporthttp.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/azure_iot_sdk/iothub_client/src/iothubtransporthttp.c	(revision 457)
@@ -0,0 +1,2572 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+#include <stdlib.h>
+#include "azure_c_shared_utility/gballoc.h"
+
+#include <time.h>
+#include "iothub_client_options.h"
+#include "iothub_client_version.h"
+#include "iothub_transport_ll.h"
+#include "iothubtransporthttp.h"
+#include "internal/iothub_client_private.h"
+#include "internal/iothubtransport.h"
+#include "internal/iothub_transport_ll_private.h"
+#include "internal/iothub_internal_consts.h"
+
+#include "azure_c_shared_utility/optimize_size.h"
+#include "azure_c_shared_utility/httpapiexsas.h"
+#include "azure_c_shared_utility/urlencode.h"
+#include "azure_c_shared_utility/xlogging.h"
+#include "azure_c_shared_utility/httpapiex.h"
+#include "azure_c_shared_utility/httpapiexsas.h"
+#include "azure_c_shared_utility/strings.h"
+#include "azure_c_shared_utility/azure_base64.h"
+#include "azure_c_shared_utility/doublylinkedlist.h"
+#include "azure_c_shared_utility/vector.h"
+#include "azure_c_shared_utility/httpheaders.h"
+#include "azure_c_shared_utility/agenttime.h"
+
+#define IOTHUB_APP_PREFIX "iothub-app-"
+static const char* IOTHUB_MESSAGE_ID = "iothub-messageid";
+static const char* IOTHUB_CORRELATION_ID = "iothub-correlationid";
+static const char* IOTHUB_CONTENT_TYPE_D2C = "iothub-contenttype";
+static const char* IOTHUB_CONTENT_ENCODING_D2C = "iothub-contentencoding";
+static const char* IOTHUB_CONTENT_TYPE_C2D = "ContentType";
+static const char* IOTHUB_CONTENT_ENCODING_C2D = "ContentEncoding";
+
+static const char* IOTHUB_AUTH_HEADER_VALUE = "Authorization";
+
+#define CONTENT_TYPE "Content-Type"
+#define APPLICATION_OCTET_STREAM "application/octet-stream"
+#define APPLICATION_VND_MICROSOFT_IOTHUB_JSON "application/vnd.microsoft.iothub.json"
+#define API_VERSION "?api-version=2016-11-14"
+#define EVENT_ENDPOINT "/messages/events"
+#define MESSAGE_ENDPOINT_HTTP "/messages/devicebound"
+#define MESSAGE_ENDPOINT_HTTP_ETAG "/messages/devicebound/"
+
+/*DEFAULT_GETMINIMUMPOLLINGTIME is the minimum time in seconds allowed between 2 consecutive GET issues to the service (GET=fetch messages)*/
+/*the default is 25 minutes*/
+#define DEFAULT_GETMINIMUMPOLLINGTIME ((unsigned int)25*60)
+
+#define MAXIMUM_MESSAGE_SIZE (255*1024-1)
+#define MAXIMUM_PAYLOAD_OVERHEAD 384
+#define MAXIMUM_PROPERTY_OVERHEAD 16
+
+/*forward declaration*/
+static int appendMapToJSON(STRING_HANDLE existing, const char* const* keys, const char* const* values, size_t count);
+
+typedef struct HTTPTRANSPORT_HANDLE_DATA_TAG
+{
+    STRING_HANDLE hostName;
+    HTTPAPIEX_HANDLE httpApiExHandle;
+    bool doBatchedTransfers;
+    unsigned int getMinimumPollingTime;
+    VECTOR_HANDLE perDeviceList;
+
+    TRANSPORT_CALLBACKS_INFO transport_callbacks;
+    void* transport_ctx;
+
+}HTTPTRANSPORT_HANDLE_DATA;
+
+typedef struct HTTPTRANSPORT_PERDEVICE_DATA_TAG
+{
+    HTTPTRANSPORT_HANDLE_DATA* transportHandle;
+
+    STRING_HANDLE deviceId;
+    STRING_HANDLE deviceKey;
+    STRING_HANDLE deviceSasToken;
+    STRING_HANDLE eventHTTPrelativePath;
+    STRING_HANDLE messageHTTPrelativePath;
+    HTTP_HEADERS_HANDLE eventHTTPrequestHeaders;
+    HTTP_HEADERS_HANDLE messageHTTPrequestHeaders;
+    STRING_HANDLE abandonHTTPrelativePathBegin;
+    HTTPAPIEX_SAS_HANDLE sasObject;
+    bool DoWork_PullMessage;
+    time_t lastPollTime;
+    bool isFirstPoll;
+
+    void* device_transport_ctx;
+    PDLIST_ENTRY waitingToSend;
+    DLIST_ENTRY eventConfirmations; /*holds items for event confirmations*/
+} HTTPTRANSPORT_PERDEVICE_DATA;
+
+typedef struct MESSAGE_DISPOSITION_CONTEXT_TAG
+{
+    HTTPTRANSPORT_HANDLE_DATA* handleData;
+    HTTPTRANSPORT_PERDEVICE_DATA* deviceData;
+    char* etagValue;
+} MESSAGE_DISPOSITION_CONTEXT;
+
+MU_DEFINE_ENUM_STRINGS_WITHOUT_INVALID(IOTHUBMESSAGE_DISPOSITION_RESULT, IOTHUBMESSAGE_DISPOSITION_RESULT_VALUES);
+
+static void destroy_eventHTTPrelativePath(HTTPTRANSPORT_PERDEVICE_DATA* handleData)
+{
+    STRING_delete(handleData->eventHTTPrelativePath);
+    handleData->eventHTTPrelativePath = NULL;
+}
+
+static bool create_eventHTTPrelativePath(HTTPTRANSPORT_PERDEVICE_DATA* handleData, const char * deviceId)
+{
+    /*Codes_SRS_TRANSPORTMULTITHTTP_17_017: [ IoTHubTransportHttp_Register shall create an immutable string (further called "event HTTP relative path") from the following pieces: "/devices/" + URL_ENCODED(deviceId) + "/messages/events" + APIVERSION. ]*/
+    bool result;
+    STRING_HANDLE urlEncodedDeviceId;
+    handleData->eventHTTPrelativePath = STRING_construct("/devices/");
+    if (handleData->eventHTTPrelativePath == NULL)
+    {
+        LogError("STRING_construct failed.");
+        result = false;
+    }
+    else
+    {
+        if (!(
+            ((urlEncodedDeviceId = URL_EncodeString(deviceId)) != NULL) &&
+            (STRING_concat_with_STRING(handleData->eventHTTPrelativePath, urlEncodedDeviceId) == 0) &&
+            (STRING_concat(handleData->eventHTTPrelativePath, EVENT_ENDPOINT API_VERSION) == 0)
+            ))
+        {
+            /*Codes_SRS_TRANSPORTMULTITHTTP_17_018: [ If creating the string fail for any reason then IoTHubTransportHttp_Register shall fail and return NULL. ]*/
+            destroy_eventHTTPrelativePath(handleData);
+            LogError("Creating HTTP event relative path failed.");
+            result = false;
+        }
+        else
+        {
+            result = true;
+        }
+        STRING_delete(urlEncodedDeviceId);
+    }
+    return result;
+}
+
+static int retrieve_message_properties(HTTP_HEADERS_HANDLE resp_header, IOTHUB_MESSAGE_HANDLE recv_msg)
+{
+    int result = 0;
+    /*Codes_SRS_TRANSPORTMULTITHTTP_17_090: [All the HTTP headers of the form iothub-app-name:somecontent shall be transformed in message properties {name, somecontent}.]*/
+    /*Codes_SRS_TRANSPORTMULTITHTTP_17_091: [The HTTP header of iothub-messageid shall be set in the MessageId.]*/
+    size_t nHeaders;
+    if (HTTPHeaders_GetHeaderCount(resp_header, &nHeaders) != HTTP_HEADERS_OK)
+    {
+        LogError("unable to get the count of HTTP headers");
+        result = MU_FAILURE;
+    }
+    else
+    {
+        MAP_HANDLE properties = (nHeaders > 0) ? IoTHubMessage_Properties(recv_msg) : NULL;
+        for (size_t index = 0; index < nHeaders; index++)
+        {
+            char* completeHeader;
+            if (HTTPHeaders_GetHeader(resp_header, index, &completeHeader) != HTTP_HEADERS_OK)
+            {
+                LogError("Failed getting header %lu", (unsigned long)index);
+                result = MU_FAILURE;
+                break;
+            }
+            else
+            {
+                char* colon_pos;
+                if (strncmp(IOTHUB_APP_PREFIX, completeHeader, strlen(IOTHUB_APP_PREFIX)) == 0)
+                {
+                    /*looks like a property headers*/
+                    /*there's a guaranteed ':' in the completeHeader, by HTTP_HEADERS module*/
+                    colon_pos = strchr(completeHeader, ':');
+                    if (colon_pos != NULL)
+                    {
+                        *colon_pos = '\0'; /*cut it down*/
+                        if (Map_AddOrUpdate(properties, completeHeader + strlen(IOTHUB_APP_PREFIX), colon_pos + 2) != MAP_OK) /*whereIsColon+1 is a space because HTTPEHADERS outputs a ": " between name and value*/
+                        {
+                            free(completeHeader);
+                            result = MU_FAILURE;
+                            break;
+                        }
+                    }
+                }
+                else if (strncmp(IOTHUB_MESSAGE_ID, completeHeader, strlen(IOTHUB_MESSAGE_ID)) == 0)
+                {
+                    char* whereIsColon = strchr(completeHeader, ':');
+                    if (whereIsColon != NULL)
+                    {
+                        *whereIsColon = '\0'; /*cut it down*/
+                        if (IoTHubMessage_SetMessageId(recv_msg, whereIsColon + 2) != IOTHUB_MESSAGE_OK)
+                        {
+                            free(completeHeader);
+                            result = MU_FAILURE;
+                            break;
+                        }
+                    }
+                }
+                else if (strncmp(IOTHUB_CORRELATION_ID, completeHeader, strlen(IOTHUB_CORRELATION_ID)) == 0)
+                {
+                    char* whereIsColon = strchr(completeHeader, ':');
+                    if (whereIsColon != NULL)
+                    {
+                        *whereIsColon = '\0'; /*cut it down*/
+                        if (IoTHubMessage_SetCorrelationId(recv_msg, whereIsColon + 2) != IOTHUB_MESSAGE_OK)
+                        {
+                            free(completeHeader);
+                            result = MU_FAILURE;
+                            break;
+                        }
+                    }
+                }
+                // Codes_SRS_TRANSPORTMULTITHTTP_09_003: [ The HTTP header value of `ContentType` shall be set in the `IoTHubMessage_SetContentTypeSystemProperty`. ]
+                else if (strncmp(IOTHUB_CONTENT_TYPE_C2D, completeHeader, strlen(IOTHUB_CONTENT_TYPE_C2D)) == 0)
+                {
+                    char* whereIsColon = strchr(completeHeader, ':');
+                    if (whereIsColon != NULL)
+                    {
+                        *whereIsColon = '\0'; /*cut it down*/
+                        if (IoTHubMessage_SetContentTypeSystemProperty(recv_msg, whereIsColon + 2) != IOTHUB_MESSAGE_OK)
+                        {
+                            LogError("Failed setting IoTHubMessage content-type");
+                            result = MU_FAILURE;
+                            break;
+                        }
+                    }
+                }
+                // Codes_SRS_TRANSPORTMULTITHTTP_09_004: [ The HTTP header value of `ContentEncoding` shall be set in the `IoTHub_SetContentEncoding`. ]
+                else if (strncmp(IOTHUB_CONTENT_ENCODING_C2D, completeHeader, strlen(IOTHUB_CONTENT_ENCODING_C2D)) == 0)
+                {
+                    char* whereIsColon = strchr(completeHeader, ':');
+                    if (whereIsColon != NULL)
+                    {
+                        *whereIsColon = '\0'; /*cut it down*/
+                        if (IoTHubMessage_SetContentEncodingSystemProperty(recv_msg, whereIsColon + 2) != IOTHUB_MESSAGE_OK)
+                        {
+                            LogError("Failed setting IoTHubMessage content-encoding");
+                            break;
+                        }
+                    }
+                }
+                free(completeHeader);
+            }
+        }
+    }
+    return result;
+}
+
+static int set_system_properties(IOTHUB_MESSAGE_LIST* message, HTTP_HEADERS_HANDLE headers)
+{
+    int result;
+    const char* msgId;
+    const char* corrId;
+    const char* content_type;
+    const char* contentEncoding;
+
+    // Add the Message Id and the Correlation Id
+    msgId = IoTHubMessage_GetMessageId(message->messageHandle);
+    if (msgId != NULL && HTTPHeaders_ReplaceHeaderNameValuePair(headers, IOTHUB_MESSAGE_ID, msgId) != HTTP_HEADERS_OK)
+    {
+        LogError("unable to HTTPHeaders_ReplaceHeaderNameValuePair");
+        result = MU_FAILURE;
+    }
+    else if ((corrId = IoTHubMessage_GetCorrelationId(message->messageHandle)) != NULL && HTTPHeaders_ReplaceHeaderNameValuePair(headers, IOTHUB_CORRELATION_ID, corrId) != HTTP_HEADERS_OK)
+    {
+        LogError("unable to HTTPHeaders_ReplaceHeaderNameValuePair");
+        result = MU_FAILURE;
+    }
+    // Codes_SRS_TRANSPORTMULTITHTTP_09_001: [ If the IoTHubMessage being sent contains property `content-type` it shall be added to the HTTP headers as "iothub-contenttype":"value". ]
+    else if ((content_type = IoTHubMessage_GetContentTypeSystemProperty(message->messageHandle)) != NULL && HTTPHeaders_ReplaceHeaderNameValuePair(headers, IOTHUB_CONTENT_TYPE_D2C, content_type) != HTTP_HEADERS_OK)
+    {
+        LogError("unable to HTTPHeaders_ReplaceHeaderNameValuePair (content-type)");
+        result = MU_FAILURE;
+    }
+    // Codes_SRS_TRANSPORTMULTITHTTP_09_002: [ If the IoTHubMessage being sent contains property `content-encoding` it shall be added to the HTTP headers as "iothub-contentencoding":"value". ]
+    else if ((contentEncoding = IoTHubMessage_GetContentEncodingSystemProperty(message->messageHandle)) != NULL && HTTPHeaders_ReplaceHeaderNameValuePair(headers, IOTHUB_CONTENT_ENCODING_D2C, contentEncoding) != HTTP_HEADERS_OK)
+    {
+        LogError("unable to HTTPHeaders_ReplaceHeaderNameValuePair (content-encoding)");
+        result = MU_FAILURE;
+    }
+    else if (IoTHubMessage_IsSecurityMessage(message->messageHandle) && HTTPHeaders_ReplaceHeaderNameValuePair(headers, SECURITY_INTERFACE_ID, SECURITY_INTERFACE_ID_VALUE) != HTTP_HEADERS_OK)
+    {
+        LogError("unable to set security message header info");
+        result = MU_FAILURE;
+    }
+    else
+    {
+        result = 0;
+    }
+    return result;
+}
+
+static bool set_message_properties(IOTHUB_MESSAGE_LIST* message, size_t* msg_size, HTTP_HEADERS_HANDLE headers, HTTPTRANSPORT_HANDLE_DATA* handleData, HTTPTRANSPORT_PERDEVICE_DATA* deviceData)
+{
+    bool result = true;
+
+    /*Codes_SRS_TRANSPORTMULTITHTTP_17_078: [Every message property "property":"value" shall be added to the HTTP headers as an individual header "iothub-app-property":"value".] */
+    MAP_HANDLE map = IoTHubMessage_Properties(message->messageHandle);
+    const char*const* keys;
+    const char*const* values;
+    size_t count;
+    if (Map_GetInternals(map, &keys, &values, &count) != MAP_OK)
+    {
+        /*Codes_SRS_TRANSPORTMULTITHTTP_17_079: [If any HTTP header operation fails, _DoWork shall advance to the next action.] */
+        LogError("unable to Map_GetInternals");
+        result = false;
+    }
+    else
+    {
+        for (size_t index = 0; index < count; index++)
+        {
+            /*Codes_SRS_TRANSPORTMULTITHTTP_17_074: [Every property name shall add  to the message size the length of the property name + the length of the property value + 16 bytes.] */
+            *msg_size += (strlen(values[index]) + strlen(keys[index]) + MAXIMUM_PROPERTY_OVERHEAD);
+            if (*msg_size > MAXIMUM_MESSAGE_SIZE)
+            {
+                /*Codes_SRS_TRANSPORTMULTITHTTP_17_072: [The message size shall be limited to 255KB -1 bytes.] */
+                PDLIST_ENTRY head = DList_RemoveHeadList(deviceData->waitingToSend); /*actually this is the same as "actual", but now it is removed*/
+                DList_InsertTailList(&(deviceData->eventConfirmations), head);
+                handleData->transport_callbacks.send_complete_cb(&(deviceData->eventConfirmations), IOTHUB_CLIENT_CONFIRMATION_ERROR, deviceData->device_transport_ctx); // takes care of emptying the list too
+                result = false;
+                break;
+            }
+            else
+            {
+                STRING_HANDLE app_construct = STRING_construct_sprintf("%s%s", IOTHUB_APP_PREFIX, keys[index]);
+                if (app_construct == NULL)
+                {
+                    /*Codes_SRS_TRANSPORTMULTITHTTP_17_079: [If any HTTP header operation fails, _DoWork shall advance to the next action.] */
+                    LogError("Unable to construct app header");
+                    result = false;
+                    break;
+                }
+                else
+                {
+                    if (HTTPHeaders_ReplaceHeaderNameValuePair(headers, STRING_c_str(app_construct), values[index]) != HTTP_HEADERS_OK)
+                    {
+                        /*Codes_SRS_TRANSPORTMULTITHTTP_17_079: [If any HTTP header operation fails, _DoWork shall advance to the next action.] */
+                        LogError("Unable to add app properties to http header");
+                        result = false;
+                        break;
+                    }
+                    STRING_delete(app_construct);
+                }
+            }
+        }
+    }
+    return result;
+}
+
+static void destroy_messageHTTPrelativePath(HTTPTRANSPORT_PERDEVICE_DATA* handleData)
+{
+    STRING_delete(handleData->messageHTTPrelativePath);
+    handleData->messageHTTPrelativePath = NULL;
+}
+
+static bool create_messageHTTPrelativePath(HTTPTRANSPORT_PERDEVICE_DATA* handleData, const char * deviceId)
+{
+    bool result;
+    handleData->messageHTTPrelativePath = STRING_construct("/devices/");
+    if (handleData->messageHTTPrelativePath == NULL)
+    {
+        LogError("STRING_construct failed.");
+        result = false;
+    }
+    else
+    {
+        STRING_HANDLE urlEncodedDeviceId;
+        /*Codes_SRS_TRANSPORTMULTITHTTP_17_019: [ IoTHubTransportHttp_Register shall create an immutable string (further called "message HTTP relative path") from the following pieces: "/devices/" + URL_ENCODED(deviceId) + "/messages/devicebound" + APIVERSION. ]*/
+        if (!(
+            ((urlEncodedDeviceId = URL_EncodeString(deviceId)) != NULL) &&
+            (STRING_concat_with_STRING(handleData->messageHTTPrelativePath, urlEncodedDeviceId) == 0) &&
+            (STRING_concat(handleData->messageHTTPrelativePath, MESSAGE_ENDPOINT_HTTP API_VERSION) == 0)
+            ))
+        {
+            /*Codes_SRS_TRANSPORTMULTITHTTP_17_020: [ If creating the message HTTP relative path fails, then IoTHubTransportHttp_Register shall fail and return NULL. ]*/
+            LogError("Creating HTTP message relative path failed.");
+            result = false;
+            destroy_messageHTTPrelativePath(handleData);
+        }
+        else
+        {
+            result = true;
+        }
+        STRING_delete(urlEncodedDeviceId);
+    }
+
+    return result;
+}
+
+static void destroy_eventHTTPrequestHeaders(HTTPTRANSPORT_PERDEVICE_DATA* handleData)
+{
+    HTTPHeaders_Free(handleData->eventHTTPrequestHeaders);
+    handleData->eventHTTPrequestHeaders = NULL;
+}
+
+static HTTP_HEADERS_RESULT addUserAgentHeaderInfo(HTTPTRANSPORT_HANDLE_DATA* transport_data, HTTP_HEADERS_HANDLE eventHTTPrequestHeaders)
+{
+    HTTP_HEADERS_RESULT result;
+    const char* product_info = transport_data->transport_callbacks.prod_info_cb(transport_data->transport_ctx);
+    if (product_info == NULL)
+    {
+        result = HTTPHeaders_AddHeaderNameValuePair(eventHTTPrequestHeaders, "User-Agent", CLIENT_DEVICE_TYPE_PREFIX CLIENT_DEVICE_BACKSLASH IOTHUB_SDK_VERSION);
+    }
+    else
+    {
+        result = HTTPHeaders_AddHeaderNameValuePair(eventHTTPrequestHeaders, "User-Agent", product_info);
+    }
+    return result;
+}
+
+static bool create_eventHTTPrequestHeaders(HTTPTRANSPORT_PERDEVICE_DATA* handleData, HTTPTRANSPORT_HANDLE_DATA* transport_data, const char * deviceId, bool is_x509_used)
+{
+    /*Codes_SRS_TRANSPORTMULTITHTTP_17_021: [ IoTHubTransportHttp_Register shall create a set of HTTP headers (further called "event HTTP request headers") consisting of the following fixed field names and values: "iothub-to":"/devices/" + URL_ENCODED(deviceId) + "/messages/events"; "Authorization":""
+    "Accept":"application/json"
+    "Connection":"Keep-Alive" ]*/
+    bool result;
+    handleData->eventHTTPrequestHeaders = HTTPHeaders_Alloc();
+    if (handleData->eventHTTPrequestHeaders == NULL)
+    {
+        LogError("HTTPHeaders_Alloc failed.");
+        result = false;
+    }
+    else
+    {
+        STRING_HANDLE temp = STRING_construct("/devices/");
+        if (temp == NULL)
+        {
+            LogError("STRING_construct failed.");
+            result = false;
+            destroy_eventHTTPrequestHeaders(handleData);
+        }
+        else
+        {
+            STRING_HANDLE urlEncodedDeviceId;
+            if (!(
+                ((urlEncodedDeviceId = URL_EncodeString(deviceId)) != NULL) &&
+                (STRING_concat_with_STRING(temp, urlEncodedDeviceId) == 0) &&
+                (STRING_concat(temp, EVENT_ENDPOINT) == 0)
+                ))
+            {
+                LogError("deviceId construction failed.");
+                result = false;
+                destroy_eventHTTPrequestHeaders(handleData);
+            }
+            else
+            {
+                if (!(
+                    (HTTPHeaders_AddHeaderNameValuePair(handleData->eventHTTPrequestHeaders, "iothub-to", STRING_c_str(temp)) == HTTP_HEADERS_OK) &&
+                    (is_x509_used || (HTTPHeaders_AddHeaderNameValuePair(handleData->eventHTTPrequestHeaders, IOTHUB_AUTH_HEADER_VALUE, " ") == HTTP_HEADERS_OK)) &&
+                    (HTTPHeaders_AddHeaderNameValuePair(handleData->eventHTTPrequestHeaders, "Accept", "application/json") == HTTP_HEADERS_OK) &&
+                    (HTTPHeaders_AddHeaderNameValuePair(handleData->eventHTTPrequestHeaders, "Connection", "Keep-Alive") == HTTP_HEADERS_OK) &&
+                    (addUserAgentHeaderInfo(transport_data, handleData->eventHTTPrequestHeaders) == HTTP_HEADERS_OK)
+                    ))
+                {
+                    /*Codes_SRS_TRANSPORTMULTITHTTP_17_022: [ If creating the event HTTP request headers fails, then IoTHubTransportHttp_Register shall fail and return NULL.] */
+                    LogError("adding header properties failed.");
+                    result = false;
+                    destroy_eventHTTPrequestHeaders(handleData);
+                }
+                else
+                {
+                    result = true;
+                }
+            }
+            STRING_delete(urlEncodedDeviceId);
+            STRING_delete(temp);
+        }
+    }
+    return result;
+}
+
+static void destroy_messageHTTPrequestHeaders(HTTPTRANSPORT_PERDEVICE_DATA* handleData)
+{
+    HTTPHeaders_Free(handleData->messageHTTPrequestHeaders);
+    handleData->messageHTTPrequestHeaders = NULL;
+}
+
+static bool create_messageHTTPrequestHeaders(HTTPTRANSPORT_PERDEVICE_DATA* handleData, HTTPTRANSPORT_HANDLE_DATA* transport_data, bool is_x509_used)
+{
+    /*Codes_SRS_TRANSPORTMULTITHTTP_17_132: [ IoTHubTransportHttp_Register shall create a set of HTTP headers (further called "message HTTP request headers") consisting of the following fixed field names and values:
+    "Authorization": "" ]*/
+    bool result;
+    handleData->messageHTTPrequestHeaders = HTTPHeaders_Alloc();
+    if (handleData->messageHTTPrequestHeaders == NULL)
+    {
+        LogError("HTTPHeaders_Alloc failed.");
+        result = false;
+    }
+    else
+    {
+        if (!(
+            (addUserAgentHeaderInfo(transport_data, handleData->messageHTTPrequestHeaders) == HTTP_HEADERS_OK) &&
+            (is_x509_used || (HTTPHeaders_AddHeaderNameValuePair(handleData->messageHTTPrequestHeaders, IOTHUB_AUTH_HEADER_VALUE, " ") == HTTP_HEADERS_OK))
+            ))
+        {
+            /*Codes_SRS_TRANSPORTMULTITHTTP_17_023: [ If creating message HTTP request headers then IoTHubTransportHttp_Register shall fail and return NULL. ]*/
+            destroy_messageHTTPrequestHeaders(handleData);
+            LogError("adding header properties failed.");
+            result = false;
+        }
+        else
+        {
+            result = true;
+        }
+    }
+    return result;
+}
+
+static void destroy_abandonHTTPrelativePathBegin(HTTPTRANSPORT_PERDEVICE_DATA* handleData)
+{
+    STRING_delete(handleData->abandonHTTPrelativePathBegin);
+    handleData->abandonHTTPrelativePathBegin = NULL;
+}
+
+static bool create_abandonHTTPrelativePathBegin(HTTPTRANSPORT_PERDEVICE_DATA* handleData, const char * deviceId)
+{
+    /*Codes_SRS_TRANSPORTMULTITHTTP_17_024: [ IoTHubTransportHttp_Register shall create a STRING containing: "/devices/" + URL_ENCODED(device id) +"/messages/deviceBound/" called abandonHTTPrelativePathBegin. ]*/
+    bool result;
+    handleData->abandonHTTPrelativePathBegin = STRING_construct("/devices/");
+    if (handleData->abandonHTTPrelativePathBegin == NULL)
+    {
+        result = false;
+    }
+    else
+    {
+        STRING_HANDLE urlEncodedDeviceId;
+        if (!(
+            ((urlEncodedDeviceId = URL_EncodeString(deviceId)) != NULL) &&
+            (STRING_concat_with_STRING(handleData->abandonHTTPrelativePathBegin, urlEncodedDeviceId) == 0) &&
+            (STRING_concat(handleData->abandonHTTPrelativePathBegin, MESSAGE_ENDPOINT_HTTP_ETAG) == 0)
+            ))
+        {
+            /*Codes_SRS_TRANSPORTMULTITHTTP_17_025: [ If creating the abandonHTTPrelativePathBegin fails then IoTHubTransportHttp_Register shall fail and return NULL. ]*/
+            LogError("unable to create abandon path string.");
+            STRING_delete(handleData->abandonHTTPrelativePathBegin);
+            result = false;
+        }
+        else
+        {
+            result = true;
+        }
+        STRING_delete(urlEncodedDeviceId);
+    }
+    return result;
+}
+
+static void destroy_SASObject(HTTPTRANSPORT_PERDEVICE_DATA* handleData)
+{
+    HTTPAPIEX_SAS_Destroy(handleData->sasObject);
+    handleData->sasObject = NULL;
+}
+
+static bool create_deviceSASObject(HTTPTRANSPORT_PERDEVICE_DATA* handleData, STRING_HANDLE hostName, const char * deviceId, const char * deviceKey)
+{
+    STRING_HANDLE keyName;
+    bool result;
+    /*Codes_SRS_TRANSPORTMULTITHTTP_17_026: [IoTHubTransportHttp_Create shall invoke URL_EncodeString with an argument of device id.]*/
+    keyName = URL_EncodeString(deviceId);
+    if (keyName == NULL)
+    {
+        /*Codes_SRS_TRANSPORTMULTITHTTP_17_027: [If the encode fails then IoTHubTransportHttp_Create shall fail and return NULL.]*/
+        LogError("URL_EncodeString keyname failed");
+        result = false;
+    }
+    else
+    {
+        STRING_HANDLE uriResource;
+        /*Codes_SRS_TRANSPORTMULTITHTTP_17_028: [IoTHubTransportHttp_Create shall invoke STRING_clone using the previously created hostname.]*/
+        uriResource = STRING_clone(hostName);
+        /*Codes_SRS_TRANSPORTMULTITHTTP_17_029: [If the clone fails then IoTHubTransportHttp_Create shall fail and return NULL.]*/
+        if (uriResource != NULL)
+        {
+            /*Codes_SRS_TRANSPORTMULTITHTTP_17_030: [IoTHubTransportHttp_Create shall invoke STRING_concat with arguments uriResource and the string "/devices/".]*/
+            /*Codes_SRS_TRANSPORTMULTITHTTP_17_141: [If the concat fails then IoTHubTransportHttp_Create shall fail and return NULL.]*/
+            /*Codes_SRS_TRANSPORTMULTITHTTP_17_031: [IoTHubTransportHttp_Create shall invoke STRING_concat_with_STRING with arguments uriResource and keyName.]*/
+            /*Codes_SRS_TRANSPORTMULTITHTTP_17_032: [If the STRING_concat_with_STRING fails then IoTHubTransportHttp_Create shall fail and return NULL.]*/
+            if ((STRING_concat(uriResource, "/devices/") == 0) &&
+                (STRING_concat_with_STRING(uriResource, keyName) == 0))
+            {
+                /*Codes_SRS_TRANSPORTMULTITHTTP_17_033: [IoTHubTransportHttp_Create shall invoke STRING_construct with an argument of config->upperConfig->deviceKey.]*/
+                /*Codes_SRS_TRANSPORTMULTITHTTP_17_034: [If the STRING_construct fails then IoTHubTransportHttp_Create shall fail and return NULL.]*/
+                STRING_HANDLE key = STRING_construct(deviceKey);
+                if (key != NULL)
+                {
+                    /*Codes_SRS_TRANSPORTMULTITHTTP_17_035: [The keyName is shortened to zero length, if that fails then IoTHubTransportHttp_Create shall fail and return NULL.]*/
+                    if (STRING_empty(keyName) != 0)
+                    {
+                        LogError("Unable to form the device key name for the SAS");
+                        result = false;
+                    }
+                    else
+                    {
+                        /*Codes_SRS_TRANSPORTMULTITHTTP_17_036: [IoTHubTransportHttp_Create shall invoke HTTPAPIEX_SAS_Create with arguments key, uriResource, and zero length keyName.]*/
+                        /*Codes_SRS_TRANSPORTMULTITHTTP_17_037: [If the HTTPAPIEX_SAS_Create fails then IoTHubTransportHttp_Create shall fail and return NULL.]*/
+                        handleData->sasObject = HTTPAPIEX_SAS_Create(key, uriResource, keyName);
+                        result = (handleData->sasObject != NULL) ? (true) : (false);
+                    }
+                    STRING_delete(key);
+                }
+                else
+                {
+                    LogError("STRING_construct Key failed");
+                    result = false;
+                }
+            }
+            else
+            {
+                LogError("STRING_concat uri resource failed");
+                result = false;
+            }
+            STRING_delete(uriResource);
+        }
+        else
+        {
+            LogError("STRING_staticclone uri resource failed");
+            result = false;
+        }
+        STRING_delete(keyName);
+    }
+    return result;
+}
+
+static void destroy_deviceId(HTTPTRANSPORT_PERDEVICE_DATA* handleData)
+{
+    STRING_delete(handleData->deviceId);
+    handleData->deviceId = NULL;
+}
+
+static bool create_deviceId(HTTPTRANSPORT_PERDEVICE_DATA* handleData, const char * deviceId)
+{
+    /*Codes_SRS_TRANSPORTMULTITHTTP_17_133: [ IoTHubTransportHttp_Register shall create an immutable string (further called "deviceId") from config->deviceConfig->deviceId. ]*/
+    bool result;
+    handleData->deviceId = STRING_construct(deviceId);
+    if (handleData->deviceId == NULL)
+    {
+        /*Codes_SRS_TRANSPORTMULTITHTTP_17_134: [ If deviceId is not created, then IoTHubTransportHttp_Register shall fail and return NULL. */
+        LogError("STRING_construct deviceId failed");
+        result = false;
+    }
+    else
+    {
+        result = true;
+    }
+    return result;
+}
+
+static void destroy_deviceKey(HTTPTRANSPORT_PERDEVICE_DATA* handleData)
+{
+    STRING_delete(handleData->deviceKey);
+    handleData->deviceKey = NULL;
+}
+
+static void destroy_deviceSas(HTTPTRANSPORT_PERDEVICE_DATA* handleData)
+{
+    STRING_delete(handleData->deviceSasToken);
+    handleData->deviceSasToken = NULL;
+}
+
+static bool create_deviceKey(HTTPTRANSPORT_PERDEVICE_DATA* handleData, const char * deviceKey)
+{
+    /*Codes_SRS_TRANSPORTMULTITHTTP_17_135: [ IoTHubTransportHttp_Register shall create an immutable string (further called "deviceKey") from deviceKey. ]*/
+    bool result;
+    handleData->deviceKey = STRING_construct(deviceKey);
+    if (handleData->deviceKey == NULL)
+    {
+        /*Codes_SRS_TRANSPORTMULTITHTTP_17_136: [ If deviceKey is not created, then IoTHubTransportHttp_Register shall fail and return NULL. ]*/
+        LogError("STRING_construct deviceKey failed");
+        result = false;
+    }
+    else
+    {
+        result = true;
+    }
+    return result;
+}
+
+static void destroy_deviceSasToken(HTTPTRANSPORT_PERDEVICE_DATA* handleData)
+{
+    STRING_delete(handleData->deviceSasToken);
+    handleData->deviceSasToken = NULL;
+}
+
+static bool create_deviceSasToken(HTTPTRANSPORT_PERDEVICE_DATA* handleData, const char * deviceSasToken)
+{
+    /*Codes_SRS_TRANSPORTMULTITHTTP_03_135: [ IoTHubTransportHttp_Register shall create an immutable string (further called "deviceSasToken") from deviceSasToken. ]*/
+    bool result;
+    handleData->deviceSasToken = STRING_construct(deviceSasToken);
+    if (handleData->deviceSasToken == NULL)
+    {
+        /*Codes_SRS_TRANSPORTMULTITHTTP_03_136: [ If deviceSasToken is not created, then IoTHubTransportHttp_Register shall fail and return NULL. ]*/
+        LogError("STRING_construct deviceSasToken failed");
+        result = false;
+    }
+    else
+    {
+        result = true;
+    }
+    return result;
+}
+
+/*
+* List queries  Find by handle and find by device name
+*/
+
+/*Codes_SRS_TRANSPORTMULTITHTTP_17_137: [ IoTHubTransportHttp_Register shall search the devices list for any device matching name deviceId. If deviceId is found it shall return NULL. ]*/
+static bool findDeviceHandle(const void* element, const void* value)
+{
+    bool result;
+    /* data stored at element is device handle */
+    const IOTHUB_DEVICE_HANDLE * guess = (const IOTHUB_DEVICE_HANDLE *)element;
+    IOTHUB_DEVICE_HANDLE match = (IOTHUB_DEVICE_HANDLE)value;
+    result = (*guess == match) ? true : false;
+    return result;
+}
+
+static bool findDeviceById(const void* element, const void* value)
+{
+    bool result;
+    const char* deviceId = (const char *)value;
+    const HTTPTRANSPORT_PERDEVICE_DATA * perDeviceElement = *(const HTTPTRANSPORT_PERDEVICE_DATA **)element;
+
+    result = (strcmp(STRING_c_str(perDeviceElement->deviceId), deviceId) == 0);
+
+    return result;
+}
+
+static IOTHUB_DEVICE_HANDLE IoTHubTransportHttp_Register(TRANSPORT_LL_HANDLE handle, const IOTHUB_DEVICE_CONFIG* device, PDLIST_ENTRY waitingToSend)
+{
+    HTTPTRANSPORT_PERDEVICE_DATA* result;
+    if (handle == NULL || device == NULL)
+    {
+        /*Codes_SRS_TRANSPORTMULTITHTTP_17_142: [ If handle is NULL or device is NULL, then IoTHubTransportHttp_Register shall return NULL. ]*/
+        LogError("Transport handle is NULL");
+        result = NULL;
+    }
+    else if (device->deviceId == NULL || ((device->deviceKey != NULL) && (device->deviceSasToken != NULL)) || waitingToSend == NULL)
+    {
+        /*Codes_SRS_TRANSPORTMULTITHTTP_17_015: [ If IOTHUB_DEVICE_CONFIG fields deviceKey and deviceSasToken are NULL, then IoTHubTransportHttp_Register shall assume a x509 authentication. ]*/
+        /*Codes_SRS_TRANSPORTMULTITHTTP_17_014: [ If IOTHUB_DEVICE_CONFIG field deviceId is NULL, then IoTHubTransportHttp_Register shall return NULL. ]*/
+        /*Codes_SRS_TRANSPORTMULTITHTTP_17_016: [ If parameter waitingToSend is NULL, then IoTHubTransportHttp_Register shall return NULL. ]*/
+        LogError("invalid parameters detected TRANSPORT_LL_HANDLE handle=%p, const IOTHUB_DEVICE_CONFIG* device=%p, PDLIST_ENTRY waitingToSend=%p",
+            handle, device, waitingToSend);
+        result = NULL;
+    }
+    else
+    {
+        HTTPTRANSPORT_HANDLE_DATA* handleData = (HTTPTRANSPORT_HANDLE_DATA*)handle;
+        /*Codes_SRS_TRANSPORTMULTITHTTP_17_137: [ IoTHubTransportHttp_Register shall search the devices list for any device matching name deviceId. If deviceId is found it shall return NULL. ]*/
+        void* listItem = VECTOR_find_if(handleData->perDeviceList, findDeviceById, device->deviceId);
+        if (listItem != NULL)
+        {
+            /*Codes_SRS_TRANSPORTMULTITHTTP_17_137: [ IoTHubTransportHttp_Register shall search the devices list for any device matching name deviceId. If deviceId is found it shall return NULL. ]*/
+            LogError("Transport already has device registered by id: [%s]", device->deviceId);
+            result = NULL;
+        }
+        else
+        {
+            bool was_create_deviceKey_ok = false;
+            bool was_create_deviceSasToken_ok = false;
+            bool was_sasObject_ok = false;
+            bool was_x509_ok = false; /*there's nothing "created" in the case of x509, it is a flag indicating that x509 is used*/
+
+            /*Codes_SRS_TRANSPORTMULTITHTTP_17_038: [ Otherwise, IoTHubTransportHttp_Register shall allocate the IOTHUB_DEVICE_HANDLE structure. ]*/
+            bool was_resultCreated_ok = ((result = (HTTPTRANSPORT_PERDEVICE_DATA *)malloc(sizeof(HTTPTRANSPORT_PERDEVICE_DATA))) != NULL);
+            bool was_create_deviceId_ok = was_resultCreated_ok && create_deviceId(result, device->deviceId);
+
+            if (was_create_deviceId_ok)
+            {
+                if (device->deviceSasToken != NULL)
+                {
+                    /*device->deviceKey is certainly NULL (because of the validation condition (else if (device->deviceId == NULL || ((device->deviceKey != NULL) && (device->deviceSasToken != NULL)) || waitingToSend == NULL))that does not accept that both satoken AND devicekey are non-NULL*/
+                    was_create_deviceSasToken_ok = create_deviceSasToken(result, device->deviceSasToken);
+                    result->deviceKey = NULL;
+                    result->sasObject = NULL;
+                }
+                else /*when deviceSasToken == NULL*/
+                {
+                    if (device->deviceKey != NULL)
+                    {
+                        was_create_deviceKey_ok = create_deviceKey(result, device->deviceKey);
+                        result->deviceSasToken = NULL;
+                    }
+                    else
+                    {
+                        /*when both of them are NULL*/
+                        was_x509_ok = true;
+                        result->deviceKey = NULL;
+                        result->deviceSasToken = NULL;
+                    }
+                }
+            }
+
+            bool was_eventHTTPrelativePath_ok = (was_create_deviceKey_ok || was_create_deviceSasToken_ok || was_x509_ok) && create_eventHTTPrelativePath(result, device->deviceId);
+            bool was_messageHTTPrelativePath_ok = was_eventHTTPrelativePath_ok && create_messageHTTPrelativePath(result, device->deviceId);
+            bool was_eventHTTPrequestHeaders_ok;
+            if (was_messageHTTPrelativePath_ok)
+            {
+                result->device_transport_ctx = handleData->transport_ctx;
+                was_eventHTTPrequestHeaders_ok = create_eventHTTPrequestHeaders(result, handleData, device->deviceId, was_x509_ok);
+            }
+            else
+            {
+                was_eventHTTPrequestHeaders_ok = false;
+            }
+            bool was_messageHTTPrequestHeaders_ok = was_eventHTTPrequestHeaders_ok && create_messageHTTPrequestHeaders(result, handleData, was_x509_ok);
+            bool was_abandonHTTPrelativePathBegin_ok = was_messageHTTPrequestHeaders_ok && create_abandonHTTPrelativePathBegin(result, device->deviceId);
+
+            if (was_x509_ok)
+            {
+                result->sasObject = NULL; /**/
+                was_sasObject_ok = true;
+            }
+            else
+            {
+                if (!was_create_deviceSasToken_ok)
+                {
+                    was_sasObject_ok = was_abandonHTTPrelativePathBegin_ok && create_deviceSASObject(result, handleData->hostName, device->deviceId, device->deviceKey);
+                }
+            }
+
+            /*Codes_SRS_TRANSPORTMULTITHTTP_17_041: [ IoTHubTransportHttp_Register shall call VECTOR_push_back to store the new device information. ]*/
+            bool was_list_add_ok = (was_sasObject_ok || was_create_deviceSasToken_ok || was_x509_ok) && (VECTOR_push_back(handleData->perDeviceList, &result, 1) == 0);
+
+            if (was_list_add_ok)
+            {
+                /*Codes_SRS_TRANSPORTMULTITHTTP_17_043: [ Upon success, IoTHubTransportHttp_Register shall store the transport handle, and the waitingToSend queue in the device handle return a non-NULL value. ]*/
+                /*Codes_SRS_TRANSPORTMULTITHTTP_17_040: [ IoTHubTransportHttp_Register shall put event HTTP relative path, message HTTP relative path, event HTTP request headers, message HTTP request headers, abandonHTTPrelativePathBegin, HTTPAPIEX_SAS_HANDLE, and the device handle into a device structure. ]*/
+                /*Codes_SRS_TRANSPORTMULTITHTTP_17_128: [ IoTHubTransportHttp_Register shall mark this device as unsubscribed. ]*/
+                result->DoWork_PullMessage = false;
+                result->isFirstPoll = true;
+                result->waitingToSend = waitingToSend;
+                DList_InitializeListHead(&(result->eventConfirmations));
+                result->transportHandle = (HTTPTRANSPORT_HANDLE_DATA *)handle;
+            }
+            else
+            {
+                /*Codes_SRS_TRANSPORTMULTITHTTP_17_042: [ If the singlylinkedlist_add fails then IoTHubTransportHttp_Register shall fail and return NULL. ]*/
+                if (was_sasObject_ok) destroy_SASObject(result);
+                if (was_abandonHTTPrelativePathBegin_ok) destroy_abandonHTTPrelativePathBegin(result);
+                if (was_messageHTTPrelativePath_ok) destroy_messageHTTPrelativePath(result);
+                if (was_eventHTTPrequestHeaders_ok) destroy_eventHTTPrequestHeaders(result);
+                if (was_messageHTTPrequestHeaders_ok) destroy_messageHTTPrequestHeaders(result);
+                if (was_eventHTTPrelativePath_ok) destroy_eventHTTPrelativePath(result);
+                if (was_create_deviceId_ok) destroy_deviceId(result);
+                if (was_create_deviceKey_ok) destroy_deviceKey(result);
+                if (was_create_deviceSasToken_ok) destroy_deviceSasToken(result);
+                /*Codes_SRS_TRANSPORTMULTITHTTP_17_039: [ If the allocating the device handle fails then IoTHubTransportHttp_Register shall fail and return NULL. ] */
+                if (was_resultCreated_ok) free(result);
+                result = NULL;
+            }
+        }
+
+    }
+    return (IOTHUB_DEVICE_HANDLE)result;
+}
+
+
+static void destroy_perDeviceData(HTTPTRANSPORT_PERDEVICE_DATA * perDeviceItem)
+{
+    destroy_deviceId(perDeviceItem);
+    destroy_deviceKey(perDeviceItem);
+    destroy_deviceSas(perDeviceItem);
+    destroy_eventHTTPrelativePath(perDeviceItem);
+    destroy_messageHTTPrelativePath(perDeviceItem);
+    destroy_eventHTTPrequestHeaders(perDeviceItem);
+    destroy_messageHTTPrequestHeaders(perDeviceItem);
+    destroy_abandonHTTPrelativePathBegin(perDeviceItem);
+    destroy_SASObject(perDeviceItem);
+}
+
+static IOTHUB_DEVICE_HANDLE* get_perDeviceDataItem(IOTHUB_DEVICE_HANDLE deviceHandle)
+{
+    HTTPTRANSPORT_PERDEVICE_DATA* deviceHandleData = (HTTPTRANSPORT_PERDEVICE_DATA*)deviceHandle;
+    IOTHUB_DEVICE_HANDLE* listItem;
+
+    HTTPTRANSPORT_HANDLE_DATA* handleData = deviceHandleData->transportHandle;
+
+    listItem = (IOTHUB_DEVICE_HANDLE *)VECTOR_find_if(handleData->perDeviceList, findDeviceHandle, deviceHandle);
+    if (listItem == NULL)
+    {
+        LogError("device handle not found in transport device list");
+        listItem = NULL;
+    }
+    else
+    {
+        /* sucessfully found device in list. */
+    }
+
+    return listItem;
+}
+
+static void IoTHubTransportHttp_Unregister(IOTHUB_DEVICE_HANDLE deviceHandle)
+{
+    if (deviceHandle == NULL)
+    {
+        /*Codes_SRS_TRANSPORTMULTITHTTP_17_044: [ If deviceHandle is NULL, then IoTHubTransportHttp_Unregister shall do nothing. ]*/
+        LogError("Unregister a NULL device handle");
+    }
+    else
+    {
+        HTTPTRANSPORT_PERDEVICE_DATA* deviceHandleData = (HTTPTRANSPORT_PERDEVICE_DATA*)deviceHandle;
+        HTTPTRANSPORT_HANDLE_DATA* handleData = deviceHandleData->transportHandle;
+        /*Codes_SRS_TRANSPORTMULTITHTTP_17_045: [ IoTHubTransportHttp_Unregister shall locate deviceHandle in the transport device list by calling list_find_if. ]*/
+        IOTHUB_DEVICE_HANDLE* listItem = get_perDeviceDataItem(deviceHandle);
+        if (listItem == NULL)
+        {
+            /*Codes_SRS_TRANSPORTMULTITHTTP_17_046: [ If the device structure is not found, then this function shall fail and do nothing. ]*/
+            LogError("Device Handle [%p] not found in transport", deviceHandle);
+        }
+        else
+        {
+            HTTPTRANSPORT_PERDEVICE_DATA * perDeviceItem = (HTTPTRANSPORT_PERDEVICE_DATA *)(*listItem);
+
+            /*Codes_SRS_TRANSPORTMULTITHTTP_17_047: [ IoTHubTransportHttp_Unregister shall free all the resources used in the device structure. ]*/
+            destroy_perDeviceData(perDeviceItem);
+            /*Codes_SRS_TRANSPORTMULTITHTTP_17_048: [ IoTHubTransportHttp_Unregister shall call singlylinkedlist_remove to remove device from devices list. ]*/
+            VECTOR_erase(handleData->perDeviceList, listItem, 1);
+            free(deviceHandleData);
+        }
+    }
+
+    return;
+}
+
+/*Codes_SRS_TRANSPORTMULTITHTTP_17_005: [If config->upperConfig->protocolGatewayHostName is NULL, `IoTHubTransportHttp_Create` shall create an immutable string (further called hostname) containing `config->transportConfig->iotHubName + config->transportConfig->iotHubSuffix`.]  */
+/*Codes_SRS_TRANSPORTMULTITHTTP_20_001: [If config->upperConfig->protocolGatewayHostName is not NULL, IoTHubTransportHttp_Create shall use it as hostname] */
+static void destroy_hostName(HTTPTRANSPORT_HANDLE_DATA* handleData)
+{
+    STRING_delete(handleData->hostName);
+    handleData->hostName = NULL;
+}
+
+static bool create_hostName(HTTPTRANSPORT_HANDLE_DATA* handleData, const IOTHUBTRANSPORT_CONFIG* config)
+{
+    bool result;
+    if (config->upperConfig->protocolGatewayHostName != NULL)
+    {
+        /*Codes_SRS_TRANSPORTMULTITHTTP_20_001: [If config->upperConfig->protocolGatewayHostName is not NULL, IoTHubTransportHttp_Create shall use it as hostname] */
+        handleData->hostName = STRING_construct(config->upperConfig->protocolGatewayHostName);
+        result = (handleData->hostName != NULL);
+    }
+    else
+    {
+        /*Codes_SRS_TRANSPORTMULTITHTTP_17_005: [If config->upperConfig->protocolGatewayHostName is NULL, `IoTHubTransportHttp_Create` shall create an immutable string (further called hostname) containing `config->transportConfig->iotHubName + config->transportConfig->iotHubSuffix`.]  */
+        handleData->hostName = STRING_construct(config->upperConfig->iotHubName);
+
+        if (handleData->hostName == NULL)
+        {
+            result = false;
+        }
+        else
+        {
+            if ((STRING_concat(handleData->hostName, ".") != 0) ||
+                (STRING_concat(handleData->hostName, config->upperConfig->iotHubSuffix) != 0))
+            {
+                /*Codes_SRS_TRANSPORTMULTITHTTP_17_006: [ If creating the hostname fails then IoTHubTransportHttp_Create shall fail and return NULL. ] */
+                destroy_hostName(handleData);
+                result = false;
+            }
+            else
+            {
+                result = true;
+            }
+        }
+    }
+    return result;
+}
+
+/*Codes_SRS_TRANSPORTMULTITHTTP_17_007: [Otherwise, IoTHubTransportHttp_Create shall create a HTTPAPIEX_HANDLE by a call to HTTPAPIEX_Create passing for hostName the hostname so far constructed by IoTHubTransportHttp_Create.]*/
+static void destroy_httpApiExHandle(HTTPTRANSPORT_HANDLE_DATA* handleData)
+{
+    HTTPAPIEX_Destroy(handleData->httpApiExHandle);
+    handleData->httpApiExHandle = NULL;
+}
+
+/*Codes_SRS_TRANSPORTMULTITHTTP_17_007: [ IoTHubTransportHttp_Create shall create a HTTPAPIEX_HANDLE by a call to HTTPAPIEX_Create passing for hostName the hostname so far constructed by IoTHubTransportHttp_Create. ]*/
+static bool create_httpApiExHandle(HTTPTRANSPORT_HANDLE_DATA* handleData, const IOTHUBTRANSPORT_CONFIG* config)
+{
+    bool result;
+    (void)config;
+    handleData->httpApiExHandle = HTTPAPIEX_Create(STRING_c_str(handleData->hostName));
+    if (handleData->httpApiExHandle == NULL)
+    {
+        /*Codes_SRS_TRANSPORTMULTITHTTP_17_008: [ If creating the HTTPAPIEX_HANDLE fails then IoTHubTransportHttp_Create shall fail and return NULL. ] */
+        result = false;
+    }
+    else
+    {
+        result = true;
+    }
+    return result;
+}
+
+static void destroy_perDeviceList(HTTPTRANSPORT_HANDLE_DATA* handleData)
+{
+    VECTOR_destroy(handleData->perDeviceList);
+    handleData->perDeviceList = NULL;
+}
+
+/*Codes_SRS_TRANSPORTMULTITHTTP_17_009: [ IoTHubTransportHttp_Create shall call singlylinkedlist_create to create a list of registered devices. ]*/
+static bool create_perDeviceList(HTTPTRANSPORT_HANDLE_DATA* handleData)
+{
+    bool result;
+    handleData->perDeviceList = VECTOR_create(sizeof(IOTHUB_DEVICE_HANDLE));
+    if (handleData == NULL || handleData->perDeviceList == NULL)
+    {
+        /*Codes_SRS_TRANSPORTMULTITHTTP_17_010: [ If creating the list fails, then IoTHubTransportHttp_Create shall fail and return NULL. ]*/
+        result = false;
+    }
+    else
+    {
+        result = true;
+    }
+    return result;
+}
+
+static TRANSPORT_LL_HANDLE IoTHubTransportHttp_Create(const IOTHUBTRANSPORT_CONFIG* config, TRANSPORT_CALLBACKS_INFO* cb_info, void* ctx)
+{
+    HTTPTRANSPORT_HANDLE_DATA* result;
+    if (config == NULL)
+    {
+        /*Codes_SRS_TRANSPORTMULTITHTTP_17_001: [If parameter config is NULL, then IoTHubTransportHttp_Create shall return NULL.]*/
+        LogError("invalid arg (configuration is missing)");
+        result = NULL;
+    }
+    else if (config->upperConfig == NULL)
+    {
+        /*Codes_SRS_TRANSPORTMULTITHTTP_17_002: [ If field transportConfig is NULL, then IoTHubTransportHttp_Create shall return NULL. ]*/
+        LogError("invalid arg (upperConfig is NULL)");
+        result = NULL;
+    }
+    else if (config->upperConfig->protocol == NULL)
+    {
+        /*Codes_SRS_TRANSPORTMULTITHTTP_17_003: [ If fields protocol, iotHubName or iotHubSuffix in transportConfig are NULL, then IoTHubTransportHttp_Create shall return NULL. ]*/
+        LogError("invalid arg (protocol is NULL)");
+        result = NULL;
+    }
+    else if (config->upperConfig->iotHubName == NULL)
+    {
+        /*Codes_SRS_TRANSPORTMULTITHTTP_17_003: [ If fields protocol, iotHubName or iotHubSuffix in transportConfig are NULL, then IoTHubTransportHttp_Create shall return NULL. ]*/
+        LogError("invalid arg (iotHubName is NULL)");
+        result = NULL;
+    }
+    else if (config->upperConfig->iotHubSuffix == NULL)
+    {
+        /*Codes_SRS_TRANSPORTMULTITHTTP_17_003: [ If fields protocol, iotHubName or iotHubSuffix in transportConfig are NULL, then IoTHubTransportHttp_Create shall return NULL. ]*/
+        LogError("invalid arg (iotHubSuffix is NULL)");
+        result = NULL;
+    }
+    else if (IoTHub_Transport_ValidateCallbacks(cb_info) != 0)
+    {
+        LogError("Invalid transport callback information");
+        result = NULL;
+    }
+    else
+    {
+        /*Codes_SRS_TRANSPORTMULTITHTTP_17_130: [ IoTHubTransportHttp_Create shall allocate memory for the handle. ]*/
+        result = (HTTPTRANSPORT_HANDLE_DATA*)malloc(sizeof(HTTPTRANSPORT_HANDLE_DATA));
+        if (result == NULL)
+        {
+            /*Codes_SRS_TRANSPORTMULTITHTTP_17_131: [ If allocation fails, IoTHubTransportHttp_Create shall fail and return NULL. ]*/
+            LogError("unable to malloc");
+        }
+        else if (HTTPAPIEX_Init() == HTTPAPIEX_ERROR)
+        {
+            /*Codes_SRS_TRANSPORTMULTITHTTP_21_143: [ If HTTPAPIEX_Init fails, IoTHubTransportHttp_Create shall fail and return NULL. ]*/
+            LogError("Error initializing HTTP");
+            free(result);
+            result = NULL;
+        }
+        else
+        {
+            bool was_hostName_ok = create_hostName(result, config);
+            bool was_httpApiExHandle_ok = was_hostName_ok && create_httpApiExHandle(result, config);
+            bool was_perDeviceList_ok = was_httpApiExHandle_ok && create_perDeviceList(result);
+
+            if (was_perDeviceList_ok)
+            {
+                /*Codes_SRS_TRANSPORTMULTITHTTP_17_011: [ Otherwise, IoTHubTransportHttp_Create shall succeed and return a non-NULL value. ]*/
+                result->doBatchedTransfers = false;
+                result->getMinimumPollingTime = DEFAULT_GETMINIMUMPOLLINGTIME;
+
+                result->transport_ctx = ctx;
+                memcpy(&result->transport_callbacks, cb_info, sizeof(TRANSPORT_CALLBACKS_INFO));
+            }
+            else
+            {
+                if (was_httpApiExHandle_ok) destroy_httpApiExHandle(result);
+                if (was_hostName_ok) destroy_hostName(result);
+                HTTPAPIEX_Deinit();
+
+                free(result);
+                result = NULL;
+            }
+        }
+    }
+    return result;
+}
+
+static void IoTHubTransportHttp_Destroy(TRANSPORT_LL_HANDLE handle)
+{
+    /*Codes_SRS_TRANSPORTMULTITHTTP_17_012: [ IoTHubTransportHttp_Destroy shall do nothing is handle is NULL. ]*/
+    if (handle != NULL)
+    {
+        HTTPTRANSPORT_HANDLE_DATA* handleData = (HTTPTRANSPORT_HANDLE_DATA*)handle;
+        IOTHUB_DEVICE_HANDLE* listItem;
+
+        size_t deviceListSize = VECTOR_size(handleData->perDeviceList);
+
+        /*Codes_SRS_TRANSPORTMULTITHTTP_17_013: [ Otherwise, IoTHubTransportHttp_Destroy shall free all the resources currently in use. ]*/
+        for (size_t i = 0; i < deviceListSize; i++)
+        {
+            listItem = (IOTHUB_DEVICE_HANDLE *)VECTOR_element(handleData->perDeviceList, i);
+            HTTPTRANSPORT_PERDEVICE_DATA* perDeviceItem = (HTTPTRANSPORT_PERDEVICE_DATA*)(*listItem);
+            destroy_perDeviceData(perDeviceItem);
+            free(perDeviceItem);
+        }
+
+        destroy_hostName((HTTPTRANSPORT_HANDLE_DATA *)handle);
+        destroy_httpApiExHandle((HTTPTRANSPORT_HANDLE_DATA *)handle);
+        destroy_perDeviceList((HTTPTRANSPORT_HANDLE_DATA *)handle);
+        HTTPAPIEX_Deinit();
+        free(handle);
+    }
+}
+
+static int IoTHubTransportHttp_Subscribe(IOTHUB_DEVICE_HANDLE handle)
+{
+    int result;
+    if (handle == NULL)
+    {
+        /*Codes_SRS_TRANSPORTMULTITHTTP_17_103: [ If parameter deviceHandle is NULL then IoTHubTransportHttp_Subscribe shall fail and return a non-zero value. ]*/
+        LogError("invalid arg passed to IoTHubTransportHttp_Subscribe");
+        result = MU_FAILURE;
+    }
+    else
+    {
+        /*Codes_SRS_TRANSPORTMULTITHTTP_17_104: [ IoTHubTransportHttp_Subscribe shall locate deviceHandle in the transport device list by calling list_find_if. ]*/
+        IOTHUB_DEVICE_HANDLE* listItem = get_perDeviceDataItem(handle);
+
+        if (listItem == NULL)
+        {
+            /*Codes_SRS_TRANSPORTMULTITHTTP_17_105: [ If the device structure is not found, then this function shall fail and return a non-zero value. ]*/
+            LogError("did not find device in transport handle");
+            result = MU_FAILURE;
+        }
+        else
+        {
+            HTTPTRANSPORT_PERDEVICE_DATA * perDeviceItem;
+
+            perDeviceItem = (HTTPTRANSPORT_PERDEVICE_DATA *)(*listItem);
+            /*Codes_SRS_TRANSPORTMULTITHTTP_17_106: [ Otherwise, IoTHubTransportHttp_Subscribe shall set the device so that subsequent calls to DoWork should execute HTTP requests. ]*/
+            perDeviceItem->DoWork_PullMessage = true;
+        }
+        result = 0;
+    }
+    return result;
+}
+
+static void IoTHubTransportHttp_Unsubscribe(IOTHUB_DEVICE_HANDLE handle)
+{
+    /*Codes_SRS_TRANSPORTMULTITHTTP_17_107: [ If parameter deviceHandle is NULL then IoTHubTransportHttp_Unsubscribe shall fail do nothing. ]*/
+    if (handle != NULL)
+    {
+        /*Codes_SRS_TRANSPORTMULTITHTTP_17_108: [ IoTHubTransportHttp_Unsubscribe shall locate deviceHandle in the transport device list by calling list_find_if. ]*/
+        IOTHUB_DEVICE_HANDLE* listItem = get_perDeviceDataItem(handle);
+        /*Codes_SRS_TRANSPORTMULTITHTTP_17_109: [ If the device structure is not found, then this function shall fail and do nothing. ]*/
+        if (listItem != NULL)
+        {
+            HTTPTRANSPORT_PERDEVICE_DATA * perDeviceItem = (HTTPTRANSPORT_PERDEVICE_DATA *)(*listItem);
+            /*Codes_SRS_TRANSPORTMULTITHTTP_17_110: [ Otherwise, IoTHubTransportHttp_Subscribe shall set the device so that subsequent calls to DoWork shall not execute HTTP requests. ]*/
+            perDeviceItem->DoWork_PullMessage = false;
+        }
+        else
+        {
+            LogError("Device not found to unsuscribe.");
+        }
+    }
+    else
+    {
+        LogError("Null handle passed to Unsuscribe.");
+    }
+}
+
+static int IoTHubTransportHttp_Subscribe_DeviceTwin(IOTHUB_DEVICE_HANDLE handle)
+{
+    /*Codes_SRS_TRANSPORTMULTITHTTP_02_003: [ IoTHubTransportHttp_Subscribe_DeviceTwin shall return a non-zero value. ]*/
+    (void)handle;
+    int result = MU_FAILURE;
+    LogError("IoTHubTransportHttp_Subscribe_DeviceTwin Not supported");
+    return result;
+}
+
+static void IoTHubTransportHttp_Unsubscribe_DeviceTwin(IOTHUB_DEVICE_HANDLE handle)
+{
+    (void)handle;
+    /*Codes_SRS_TRANSPORTMULTITHTTP_02_004: [ IoTHubTransportHttp_Unsubscribe_DeviceTwin shall return ]*/
+    LogError("IoTHubTransportHttp_Unsubscribe_DeviceTwin Not supported");
+}
+
+static IOTHUB_CLIENT_RESULT IoTHubTransportHttp_GetTwinAsync(IOTHUB_DEVICE_HANDLE handle, IOTHUB_CLIENT_DEVICE_TWIN_CALLBACK completionCallback, void* callbackContext)
+{
+    (void)handle;
+    (void)completionCallback;
+    (void)callbackContext;
+    LogError("Currently Not Supported.");
+    // Codes_SRS_TRANSPORTMULTITHTTP_09_005: [ `IoTHubTransportHttp_GetTwinAsync` shall return IOTHUB_CLIENT_ERROR]
+    return IOTHUB_CLIENT_ERROR;
+}
+
+static int IoTHubTransportHttp_Subscribe_DeviceMethod(IOTHUB_DEVICE_HANDLE handle)
+{
+    (void)handle;
+    int result = MU_FAILURE;
+    LogError("not implemented (yet)");
+    return result;
+}
+
+static void IoTHubTransportHttp_Unsubscribe_DeviceMethod(IOTHUB_DEVICE_HANDLE handle)
+{
+    (void)handle;
+    LogError("not implemented (yet)");
+}
+
+static int IoTHubTransportHttp_DeviceMethod_Response(IOTHUB_DEVICE_HANDLE handle, METHOD_HANDLE methodId, const unsigned char* response, size_t response_size, int status_response)
+{
+    (void)handle;
+    (void)methodId;
+    (void)response;
+    (void)response_size;
+    (void)status_response;
+    LogError("not implemented (yet)");
+    return MU_FAILURE;
+}
+
+/*produces a representation of the properties, if they exist*/
+/*if they do not exist, produces ""*/
+static int concat_Properties(STRING_HANDLE existing, MAP_HANDLE map, size_t* propertiesMessageSizeContribution)
+{
+    int result;
+    const char*const* keys;
+    const char*const* values;
+    size_t count;
+    if (Map_GetInternals(map, &keys, &values, &count) != MAP_OK)
+    {
+        result = MU_FAILURE;
+        LogError("error while Map_GetInternals");
+    }
+    else
+    {
+
+        if (count == 0)
+        {
+            /*Codes_SRS_TRANSPORTMULTITHTTP_17_064: [If IoTHubMessage does not have properties, then "properties":{...} shall be missing from the payload*/
+            /*no properties - do nothing with existing*/
+            result = 0;
+            *propertiesMessageSizeContribution = 0;
+        }
+        else
+        {
+            /*Codes_SRS_TRANSPORTMULTITHTTP_17_058: [If IoTHubMessage has properties, then they shall be serialized at the same level as "body" using the following pattern: "properties":{"iothub-app-name1":"value1","iothub-app-name2":"value2*/
+            if (STRING_concat(existing, ",\"properties\":") != 0)
+            {
+                /*go ahead and return it*/
+                result = MU_FAILURE;
+                LogError("failed STRING_concat");
+            }
+            else if (appendMapToJSON(existing, keys, values, count) != 0)
+            {
+                result = MU_FAILURE;
+                LogError("unable to append the properties");
+            }
+            else
+            {
+                /*all is fine*/
+                size_t i;
+                *propertiesMessageSizeContribution = 0;
+                for (i = 0; i < count; i++)
+                {
+                    /*Codes_SRS_TRANSPORTMULTITHTTP_17_063: [Every property name shall add to the message size the length of the property name + the length of the property value + 16 bytes.] */
+                    *propertiesMessageSizeContribution += (strlen(keys[i]) + strlen(values[i]) + MAXIMUM_PROPERTY_OVERHEAD);
+                }
+                result = 0;
+            }
+        }
+    }
+    return result;
+}
+
+/*produces a JSON representation of the map : {"a": "value_of_a","b":"value_of_b"}*/
+static int appendMapToJSON(STRING_HANDLE existing, const char* const* keys, const char* const* values, size_t count) /*under consideration: move to MAP module when it has more than 1 user*/
+{
+    int result;
+    if (STRING_concat(existing, "{") != 0)
+    {
+        /*go on and return it*/
+        LogError("STRING_construct failed");
+        result = MU_FAILURE;
+    }
+    else
+    {
+        size_t i;
+        for (i = 0; i < count; i++)
+        {
+            if (!(
+                (STRING_concat(existing, (i == 0) ? "\"" IOTHUB_APP_PREFIX : ",\"" IOTHUB_APP_PREFIX) == 0) &&
+                (STRING_concat(existing, keys[i]) == 0) &&
+                (STRING_concat(existing, "\":\"") == 0) &&
+                (STRING_concat(existing, values[i]) == 0) &&
+                (STRING_concat(existing, "\"") == 0)
+                ))
+            {
+                LogError("unable to STRING_concat");
+                break;
+            }
+        }
+
+        if (i < count)
+        {
+            result = MU_FAILURE;
+            /*error, let it go through*/
+        }
+        else if (STRING_concat(existing, "}") != 0)
+        {
+            LogError("unable to STRING_concat");
+            result = MU_FAILURE;
+        }
+        else
+        {
+            /*all is fine*/
+            result = 0;
+        }
+    }
+    return result;
+}
+
+/*makes the following string:{"body":"base64 encoding of the message content"[,"properties":{"a":"valueOfA"}]}*/
+/*return NULL if there was a failure, or a non-NULL STRING_HANDLE that contains the intended data*/
+static STRING_HANDLE make1EventJSONitem(PDLIST_ENTRY item, size_t *messageSizeContribution)
+{
+    STRING_HANDLE result; /*temp wants to contain :{"body":"base64 encoding of the message content"[,"properties":{"a":"valueOfA"}]}*/
+    IOTHUB_MESSAGE_LIST* message = containingRecord(item, IOTHUB_MESSAGE_LIST, entry);
+    IOTHUBMESSAGE_CONTENT_TYPE contentType = IoTHubMessage_GetContentType(message->messageHandle);
+
+    switch (contentType)
+    {
+    case IOTHUBMESSAGE_BYTEARRAY:
+    {
+        result = STRING_construct("{\"body\":\"");
+        if (result == NULL)
+        {
+            LogError("unable to STRING_construct");
+        }
+        else
+        {
+            const unsigned char* source;
+            size_t size;
+
+            if (IoTHubMessage_GetByteArray(message->messageHandle, &source, &size) != IOTHUB_MESSAGE_OK)
+            {
+                LogError("unable to get the data for the message.");
+                STRING_delete(result);
+                result = NULL;
+            }
+            else
+            {
+                STRING_HANDLE encoded = Azure_Base64_Encode_Bytes(source, size);
+                if (encoded == NULL)
+                {
+                    LogError("unable to Azure_Base64_Encode_Bytes.");
+                    STRING_delete(result);
+                    result = NULL;
+                }
+                else
+                {
+                    size_t propertiesSize = 0;
+                    if (!(
+                        (STRING_concat_with_STRING(result, encoded) == 0) &&
+                        (STRING_concat(result, "\"") == 0) && /*\" because closing value*/
+                        (concat_Properties(result, IoTHubMessage_Properties(message->messageHandle), &propertiesSize) == 0) &&
+                        (STRING_concat(result, "},") == 0) /*the last comma shall be replaced by a ']' by DaCr's suggestion (which is awesome enough to receive credits in the source code)*/
+                        ))
+                    {
+                        STRING_delete(result);
+                        result = NULL;
+                        LogError("unable to STRING_concat_with_STRING.");
+                    }
+                    else
+                    {
+                        /*all is fine... */
+                        /*Codes_SRS_TRANSPORTMULTITHTTP_17_062: [The message size is computed from the length of the payload + 384.] */
+                        *messageSizeContribution = size + MAXIMUM_PAYLOAD_OVERHEAD + propertiesSize;
+                    }
+                    STRING_delete(encoded);
+                }
+            }
+        }
+        break;
+    }
+    /*Codes_SRS_TRANSPORTMULTITHTTP_17_057: [If a messages to be send has type IOTHUBMESSAGE_STRING, then its serialization shall be {"body":"JSON encoding of the string", "base64Encoded":false}] */
+    case IOTHUBMESSAGE_STRING:
+    {
+        result = STRING_construct("{\"body\":");
+        if (result == NULL)
+        {
+            LogError("unable to STRING_construct");
+        }
+        else
+        {
+            const char* source = IoTHubMessage_GetString(message->messageHandle);
+            if (source == NULL)
+            {
+                LogError("unable to IoTHubMessage_GetString");
+                STRING_delete(result);
+                result = NULL;
+            }
+            else
+            {
+                STRING_HANDLE asJson = STRING_new_JSON(source);
+                if (asJson == NULL)
+                {
+                    LogError("unable to STRING_new_JSON");
+                    STRING_delete(result);
+                    result = NULL;
+                }
+                else
+                {
+                    size_t propertiesSize = 0;
+                    if (!(
+                        (STRING_concat_with_STRING(result, asJson) == 0) &&
+                        (STRING_concat(result, ",\"base64Encoded\":false") == 0) &&
+                        (concat_Properties(result, IoTHubMessage_Properties(message->messageHandle), &propertiesSize) == 0) &&
+                        (STRING_concat(result, "},") == 0) /*the last comma shall be replaced by a ']' by DaCr's suggestion (which is awesome enough to receive credits in the source code)*/
+                        ))
+                    {
+                        LogError("unable to STRING_concat_with_STRING");
+                        STRING_delete(result);
+                        result = NULL;
+                    }
+                    else
+                    {
+                        /*result has the intended content*/
+                        /*Codes_SRS_TRANSPORTMULTITHTTP_17_062: [The message size is computed from the length of the payload + 384.] */
+                        *messageSizeContribution = strlen(source) + MAXIMUM_PAYLOAD_OVERHEAD + propertiesSize;
+                    }
+                    STRING_delete(asJson);
+                }
+            }
+        }
+        break;
+    }
+    default:
+    {
+        LogError("an unknown message type was encountered (%d)", contentType);
+        result = NULL; /*unknown message type*/
+        break;
+    }
+    }
+    return result;
+}
+
+#define MAKE_PAYLOAD_RESULT_VALUES \
+    MAKE_PAYLOAD_OK, /*returned when there is a payload to be later send by HTTP*/ \
+    MAKE_PAYLOAD_NO_ITEMS, /*returned when there are no items to be send*/ \
+    MAKE_PAYLOAD_ERROR, /*returned when there were errors*/ \
+    MAKE_PAYLOAD_FIRST_ITEM_DOES_NOT_FIT /*returned when the first item doesn't fit*/
+
+MU_DEFINE_ENUM(MAKE_PAYLOAD_RESULT, MAKE_PAYLOAD_RESULT_VALUES);
+
+/*this function assembles several {"body":"base64 encoding of the message content"," base64Encoded": true} into 1 payload*/
+/*Codes_SRS_TRANSPORTMULTITHTTP_17_056: [IoTHubTransportHttp_DoWork shall build the following string:[{"body":"base64 encoding of the message1 content"},{"body":"base64 encoding of the message2 content"}...]]*/
+static MAKE_PAYLOAD_RESULT makePayload(HTTPTRANSPORT_PERDEVICE_DATA* deviceData, STRING_HANDLE* payload)
+{
+    MAKE_PAYLOAD_RESULT result;
+    size_t allMessagesSize = 0;
+    *payload = STRING_construct("[");
+    if (*payload == NULL)
+    {
+        LogError("unable to STRING_construct");
+        result = MAKE_PAYLOAD_ERROR;
+    }
+    else
+    {
+        bool isFirst = true;
+        PDLIST_ENTRY actual;
+        bool keepGoing = true; /*keepGoing gets sometimes to false from within the loop*/
+                               /*either all the items enter the list or only some*/
+        result = MAKE_PAYLOAD_OK; /*optimistically initializing it*/
+        while (keepGoing && ((actual = deviceData->waitingToSend->Flink) != deviceData->waitingToSend))
+        {
+            size_t messageSize;
+            STRING_HANDLE temp = make1EventJSONitem(actual, &messageSize);
+            if (isFirst)
+            {
+                isFirst = false;
+                /*Codes_SRS_TRANSPORTMULTITHTTP_17_067: [If there is no valid payload, IoTHubTransportHttp_DoWork shall advance to the next activity.]*/
+                if (temp == NULL) /*first item failed to create, nothing to send*/
+                {
+                    result = MAKE_PAYLOAD_ERROR;
+                    STRING_delete(*payload);
+                    *payload = NULL;
+                    keepGoing = false;
+                }
+                else
+                {
+                    /*Codes_SRS_TRANSPORTMULTITHTTP_17_065: [If the oldest message in waitingToSend causes the message size to exceed the message size limit then it shall be removed from waitingToSend, and IoTHubClientCore_LL_SendComplete shall be called. Parameter PDLIST_ENTRY completed shall point to a list containing only the oldest item, and parameter IOTHUB_CLIENT_CONFIRMATION_RESULT result shall be set to IOTHUB_CLIENT_CONFIRMATION_BATCHSTATE_FAILED.]*/
+                    /*Codes_SRS_TRANSPORTMULTITHTTP_17_061: [The message size shall be limited to 255KB - 1 byte.]*/
+                    if (messageSize > MAXIMUM_MESSAGE_SIZE)
+                    {
+                        PDLIST_ENTRY head = DList_RemoveHeadList(deviceData->waitingToSend); /*actually this is the same as "actual", but now it is removed*/
+                        DList_InsertTailList(&(deviceData->eventConfirmations), head);
+                        result = MAKE_PAYLOAD_FIRST_ITEM_DOES_NOT_FIT;
+                        STRING_delete(*payload);
+                        *payload = NULL;
+                        keepGoing = false;
+                    }
+                    else
+                    {
+                        if (STRING_concat_with_STRING(*payload, temp) != 0)
+                        {
+                            /*Codes_SRS_TRANSPORTMULTITHTTP_17_067: [If there is no valid payload, IoTHubTransportHttp_DoWork shall advance to the next activity.]*/
+                            result = MAKE_PAYLOAD_ERROR;
+                            STRING_delete(*payload);
+                            *payload = NULL;
+                            keepGoing = false;
+                        }
+                        else
+                        {
+                            /*first item was put nicely in the payload*/
+                            PDLIST_ENTRY head = DList_RemoveHeadList(deviceData->waitingToSend); /*actually this is the same as "actual", but now it is removed*/
+                            DList_InsertTailList(&(deviceData->eventConfirmations), head);
+                            allMessagesSize += messageSize;
+                        }
+                    }
+                    STRING_delete(temp);
+                }
+            }
+            else
+            {
+                /*there is at least 1 item already in the payload*/
+                if (temp == NULL)
+                {
+                    /*there are multiple payloads encoded, the last one had an internal error, just go with those - closing the payload happens "after the loop"*/
+                    /*Codes_SRS_TRANSPORTMULTITHTTP_17_066: [If at any point during construction of the string there are errors, IoTHubTransportHttp_DoWork shall use the so far constructed string as payload.]*/
+                    result = MAKE_PAYLOAD_OK;
+                    keepGoing = false;
+                }
+                else
+                {
+                    if (allMessagesSize + messageSize > MAXIMUM_MESSAGE_SIZE)
+                    {
+                        /*this item doesn't make it to the payload, but the payload is valid so far*/
+                        /*Codes_SRS_TRANSPORTMULTITHTTP_17_066: [If at any point during construction of the string there are errors, IoTHubTransportHttp_DoWork shall use the so far constructed string as payload.]*/
+                        result = MAKE_PAYLOAD_OK;
+                        keepGoing = false;
+                    }
+                    else if (STRING_concat_with_STRING(*payload, temp) != 0)
+                    {
+                        /*should still send what there is so far...*/
+                        /*Codes_SRS_TRANSPORTMULTITHTTP_17_066: [If at any point during construction of the string there are errors, IoTHubTransportHttp_DoWork shall use the so far constructed string as payload.]*/
+                        result = MAKE_PAYLOAD_OK;
+                        keepGoing = false;
+                    }
+                    else
+                    {
+                        /*cool, the payload made it there, let's continue... */
+                        PDLIST_ENTRY head = DList_RemoveHeadList(deviceData->waitingToSend); /*actually this is the same as "actual", but now it is removed*/
+                        DList_InsertTailList(&(deviceData->eventConfirmations), head);
+                        allMessagesSize += messageSize;
+                    }
+                    STRING_delete(temp);
+                }
+            }
+        }
+
+        /*closing the payload*/
+        if (result == MAKE_PAYLOAD_OK)
+        {
+            ((char*)STRING_c_str(*payload))[STRING_length(*payload) - 1] = ']'; /*TODO - do this in STRING_HANDLE*/
+        }
+        else
+        {
+            /*no need to close anything*/
+        }
+    }
+    return result;
+}
+
+static void reversePutListBackIn(PDLIST_ENTRY source, PDLIST_ENTRY destination)
+{
+    /*this function takes a list, and inserts it in another list. When done in the context of this file, it reverses the effects of a not-able-to-send situation*/
+    DList_AppendTailList(destination->Flink, source);
+    DList_RemoveEntryList(source);
+    DList_InitializeListHead(source);
+}
+
+static void DoEvent(HTTPTRANSPORT_HANDLE_DATA* handleData, HTTPTRANSPORT_PERDEVICE_DATA* deviceData)
+{
+
+    if (DList_IsListEmpty(deviceData->waitingToSend))
+    {
+        /*Codes_SRS_TRANSPORTMULTITHTTP_17_060: [If the list is empty then IoTHubTransportHttp_DoWork shall proceed to the following action.] */
+    }
+    else
+    {
+        /*Codes_SRS_TRANSPORTMULTITHTTP_17_053: [If option SetBatching is true then _Dowork shall send batched event message as specced below.] */
+        if (handleData->doBatchedTransfers)
+        {
+            /*Codes_SRS_TRANSPORTMULTITHTTP_17_054: [Request HTTP headers shall have the value of "Content-Type" created or updated to "application/vnd.microsoft.iothub.json" by a call to HTTPHeaders_ReplaceHeaderNameValuePair.] */
+            if (HTTPHeaders_ReplaceHeaderNameValuePair(deviceData->eventHTTPrequestHeaders, CONTENT_TYPE, APPLICATION_VND_MICROSOFT_IOTHUB_JSON) != HTTP_HEADERS_OK)
+            {
+                /*Codes_SRS_TRANSPORTMULTITHTTP_17_055: [If updating Content-Type fails for any reason, then _DoWork shall advance to the next action.] */
+                LogError("unable to HTTPHeaders_ReplaceHeaderNameValuePair");
+            }
+            else
+            {
+                /*Codes_SRS_TRANSPORTMULTITHTTP_17_059: [It shall inspect the "waitingToSend" DLIST passed in config structure.] */
+                STRING_HANDLE payload;
+                switch (makePayload(deviceData, &payload))
+                {
+                case MAKE_PAYLOAD_OK:
+                {
+                    /*Codes_SRS_TRANSPORTMULTITHTTP_17_068: [Once a final payload has been obtained, IoTHubTransportHttp_DoWork shall call HTTPAPIEX_SAS_ExecuteRequest passing the following parameters:] */
+                    BUFFER_HANDLE temp = BUFFER_new();
+                    if (temp == NULL)
+                    {
+                        LogError("unable to BUFFER_new");
+                        /*Codes_SRS_TRANSPORTMULTITHTTP_17_067: [If there is no valid payload, IoTHubTransportHttp_DoWork shall advance to the next activity.]*/
+                        reversePutListBackIn(&(deviceData->eventConfirmations), deviceData->waitingToSend);
+                    }
+                    else
+                    {
+                        if (BUFFER_build(temp, (const unsigned char*)STRING_c_str(payload), STRING_length(payload)) != 0)
+                        {
+                            LogError("unable to BUFFER_build");
+                            //items go back to waitingToSend
+                            /*Codes_SRS_TRANSPORTMULTITHTTP_17_067: [If there is no valid payload, IoTHubTransportHttp_DoWork shall advance to the next activity.]*/
+                            reversePutListBackIn(&(deviceData->eventConfirmations), deviceData->waitingToSend);
+                        }
+                        else
+                        {
+                            unsigned int statusCode;
+                            if (HTTPAPIEX_SAS_ExecuteRequest(
+                                deviceData->sasObject,
+                                handleData->httpApiExHandle,
+                                HTTPAPI_REQUEST_POST,
+                                STRING_c_str(deviceData->eventHTTPrelativePath),
+                                deviceData->eventHTTPrequestHeaders,
+                                temp,
+                                &statusCode,
+                                NULL,
+                                NULL
+                            ) != HTTPAPIEX_OK)
+                            {
+                                LogError("unable to HTTPAPIEX_ExecuteRequest");
+                                //items go back to waitingToSend
+                                /*Codes_SRS_TRANSPORTMULTITHTTP_17_069: [if HTTPAPIEX_SAS_ExecuteRequest fails or the http status code >=300 then IoTHubTransportHttp_DoWork shall not do any other action (it is assumed at the next _DoWork it shall be retried).] */
+                                reversePutListBackIn(&(deviceData->eventConfirmations), deviceData->waitingToSend);
+                            }
+                            else
+                            {
+                                if (statusCode < 300)
+                                {
+                                    /*Codes_SRS_TRANSPORTMULTITHTTP_17_070: [If HTTPAPIEX_SAS_ExecuteRequest does not fail and http status code <300 then IoTHubTransportHttp_DoWork shall call IoTHubClientCore_LL_SendComplete. Parameter PDLIST_ENTRY completed shall point to a list containing all the items batched, and parameter IOTHUB_CLIENT_CONFIRMATION_RESULT result shall be set to IOTHUB_CLIENT_CONFIRMATION_OK. The batched items shall be removed from waitingToSend.] */
+                                    handleData->transport_callbacks.send_complete_cb(&(deviceData->eventConfirmations), IOTHUB_CLIENT_CONFIRMATION_OK, deviceData->device_transport_ctx);
+                                }
+                                else
+                                {
+                                    //items go back to waitingToSend
+                                    /*Codes_SRS_TRANSPORTMULTITHTTP_17_069: [if HTTPAPIEX_SAS_ExecuteRequest fails or the http status code >=300 then IoTHubTransportHttp_DoWork shall not do any other action (it is assumed at the next _DoWork it shall be retried).] */
+                                    LogError("unexpected HTTP status code (%u)", statusCode);
+                                    reversePutListBackIn(&(deviceData->eventConfirmations), deviceData->waitingToSend);
+                                }
+                            }
+                        }
+                        BUFFER_delete(temp);
+                    }
+                    STRING_delete(payload);
+                    break;
+                }
+                case MAKE_PAYLOAD_FIRST_ITEM_DOES_NOT_FIT:
+                {
+                    handleData->transport_callbacks.send_complete_cb(&(deviceData->eventConfirmations), IOTHUB_CLIENT_CONFIRMATION_ERROR, deviceData->device_transport_ctx); // takes care of emptying the list too
+                    break;
+                }
+                case MAKE_PAYLOAD_ERROR:
+                {
+                    LogError("unrecoverable errors while building a batch message");
+                    break;
+                }
+                case MAKE_PAYLOAD_NO_ITEMS:
+                {
+                    /*do nothing*/
+                    break;
+                }
+                default:
+                {
+                    LogError("internal error: switch's default branch reached when never intended");
+                    break;
+                }
+                }
+            }
+        }
+        else
+        {
+            const unsigned char* messageContent = NULL;
+            size_t messageSize = 0;
+            size_t originalMessageSize = 0;
+            IOTHUB_MESSAGE_LIST* message = containingRecord(deviceData->waitingToSend->Flink, IOTHUB_MESSAGE_LIST, entry);
+            IOTHUBMESSAGE_CONTENT_TYPE contentType = IoTHubMessage_GetContentType(message->messageHandle);
+
+            /*Codes_SRS_TRANSPORTMULTITHTTP_17_073: [The message size is computed from the length of the payload + 384.]*/
+            if (!(
+                (((contentType == IOTHUBMESSAGE_BYTEARRAY) &&
+                (IoTHubMessage_GetByteArray(message->messageHandle, &messageContent, &originalMessageSize) == IOTHUB_MESSAGE_OK))
+                    ? ((void)(messageSize = originalMessageSize + MAXIMUM_PAYLOAD_OVERHEAD), 1)
+                    : 0)
+
+                ||
+
+                ((contentType == IOTHUBMESSAGE_STRING) &&
+                ((void)(messageContent = (const unsigned char*)IoTHubMessage_GetString(message->messageHandle)),
+                    ((void)(messageSize = MAXIMUM_PAYLOAD_OVERHEAD + (originalMessageSize = ((messageContent == NULL)
+                        ? 0
+                        : strlen((const char*)messageContent))))),
+                    messageContent != NULL)
+                    )
+                ))
+            {
+                LogError("unable to get the message content");
+                /*go on...*/
+            }
+            else
+            {
+                /*Codes_SRS_TRANSPORTMULTITHTTP_17_075: [If the oldest message in waitingToSend causes the message to exceed the message size limit then it shall be removed from waitingToSend, and IoTHubClientCore_LL_SendComplete shall be called. Parameter PDLIST_ENTRY completed shall point to a list containing only the oldest item, and parameter IOTHUB_CLIENT_CONFIRMATION_RESULT result shall be set to IOTHUB_CLIENT_CONFIRMATION_BATCHSTATE_FAILED.]*/
+                /*Codes_SRS_TRANSPORTMULTITHTTP_17_072: [The message size shall be limited to 255KB -1 bytes.] */
+                if (messageSize > MAXIMUM_MESSAGE_SIZE)
+                {
+                    PDLIST_ENTRY head = DList_RemoveHeadList(deviceData->waitingToSend); /*actually this is the same as "actual", but now it is removed*/
+                    DList_InsertTailList(&(deviceData->eventConfirmations), head);
+                    handleData->transport_callbacks.send_complete_cb(&(deviceData->eventConfirmations), IOTHUB_CLIENT_CONFIRMATION_ERROR, deviceData->device_transport_ctx); // takes care of emptying the list too
+                }
+                else
+                {
+                    /*Codes_SRS_TRANSPORTMULTITHTTP_17_071: [If option SetBatching is false then _Dowork shall send individual event message as specced below.] */
+                    /*Codes_SRS_TRANSPORTMULTITHTTP_17_076: [A clone of the event HTTP request headers shall be created.]*/
+                    HTTP_HEADERS_HANDLE clonedEventHTTPrequestHeaders = HTTPHeaders_Clone(deviceData->eventHTTPrequestHeaders);
+                    if (clonedEventHTTPrequestHeaders == NULL)
+                    {
+                        /*Codes_SRS_TRANSPORTMULTITHTTP_17_079: [If any HTTP header operation fails, _DoWork shall advance to the next action.] */
+                        LogError("HTTPHeaders_Clone failed");
+                    }
+                    else
+                    {
+                        /*Codes_SRS_TRANSPORTMULTITHTTP_17_077: [The cloned HTTP headers shall have the HTTP header "Content-Type" set to "application/octet-stream".] */
+                        if (HTTPHeaders_ReplaceHeaderNameValuePair(clonedEventHTTPrequestHeaders, CONTENT_TYPE, APPLICATION_OCTET_STREAM) != HTTP_HEADERS_OK)
+                        {
+                            /*Codes_SRS_TRANSPORTMULTITHTTP_17_079: [If any HTTP header operation fails, _DoWork shall advance to the next action.] */
+                            LogError("HTTPHeaders_ReplaceHeaderNameValuePair failed");
+                        }
+                        else
+                        {
+                            // set_message_properties returning false does not necessarily mean the the function failed, it just means
+                            // the the adding of messages should not continue and should try the next time.  So you should not log if this
+                            // returns false
+                            if (set_message_properties(message, &messageSize, clonedEventHTTPrequestHeaders, handleData, deviceData))
+                            {
+
+                                if (set_system_properties(message, clonedEventHTTPrequestHeaders) != 0)
+                                {
+                                    /*Codes_SRS_TRANSPORTMULTITHTTP_17_079: [If any HTTP header operation fails, _DoWork shall advance to the next action.] */
+                                }
+                                else
+                                {
+                                    BUFFER_HANDLE toBeSend = BUFFER_create(messageContent, originalMessageSize);
+                                    if (toBeSend == NULL)
+                                    {
+                                        LogError("unable to BUFFER_new");
+                                    }
+                                    else
+                                    {
+                                        unsigned int statusCode = 0;
+                                        HTTPAPIEX_RESULT r;
+                                        if (deviceData->deviceSasToken != NULL)
+                                        {
+                                            /*Codes_SRS_TRANSPORTMULTITHTTP_03_001: [if a deviceSasToken exists, HTTPHeaders_ReplaceHeaderNameValuePair shall be invoked with "Authorization" as its second argument and STRING_c_str (deviceSasToken) as its third argument.]*/
+                                            if (HTTPHeaders_ReplaceHeaderNameValuePair(clonedEventHTTPrequestHeaders, IOTHUB_AUTH_HEADER_VALUE, STRING_c_str(deviceData->deviceSasToken)) != HTTP_HEADERS_OK)
+                                            {
+                                                r = HTTPAPIEX_ERROR;
+                                                /*Codes_SRS_TRANSPORTMULTITHTTP_03_002: [If the result of the invocation of HTTPHeaders_ReplaceHeaderNameValuePair is NOT HTTP_HEADERS_OK then fallthrough.]*/
+                                                LogError("Unable to replace the old SAS Token.");
+                                            }
+                                            /*Codes_SRS_TRANSPORTMULTITHTTP_03_003: [If a deviceSasToken exists, IoTHubTransportHttp_DoWork shall call HTTPAPIEX_ExecuteRequest passing the following parameters] */
+                                            else if ((r = HTTPAPIEX_ExecuteRequest(
+                                                handleData->httpApiExHandle, HTTPAPI_REQUEST_POST, STRING_c_str(deviceData->eventHTTPrelativePath),
+                                                clonedEventHTTPrequestHeaders, toBeSend, &statusCode, NULL, NULL)) != HTTPAPIEX_OK)
+                                            {
+                                                LogError("Unable to HTTPAPIEX_ExecuteRequest.");
+                                            }
+                                        }
+                                        else
+                                        {
+                                            /*Codes_SRS_TRANSPORTMULTITHTTP_17_080: [If a deviceSasToken does not exist, IoTHubTransportHttp_DoWork shall call HTTPAPIEX_SAS_ExecuteRequest passing the following parameters] */
+                                            if ((r = HTTPAPIEX_SAS_ExecuteRequest(deviceData->sasObject, handleData->httpApiExHandle, HTTPAPI_REQUEST_POST, STRING_c_str(deviceData->eventHTTPrelativePath),
+                                                clonedEventHTTPrequestHeaders, toBeSend, &statusCode, NULL, NULL )) != HTTPAPIEX_OK)
+                                            {
+                                                LogError("unable to HTTPAPIEX_SAS_ExecuteRequest");
+                                            }
+                                        }
+                                        if (r == HTTPAPIEX_OK)
+                                        {
+                                            if (statusCode < 300)
+                                            {
+                                                /*Codes_SRS_TRANSPORTMULTITHTTP_17_082: [If HTTPAPIEX_SAS_ExecuteRequest does not fail and http status code <300 then IoTHubTransportHttp_DoWork shall call IoTHubClientCore_LL_SendComplete. Parameter PDLIST_ENTRY completed shall point to a list the item send, and parameter IOTHUB_CLIENT_CONFIRMATION_RESULT result shall be set to IOTHUB_CLIENT_CONFIRMATION_OK. The item shall be removed from waitingToSend.] */
+                                                PDLIST_ENTRY justSent = DList_RemoveHeadList(deviceData->waitingToSend); /*actually this is the same as "actual", but now it is removed*/
+                                                DList_InsertTailList(&(deviceData->eventConfirmations), justSent);
+                                                handleData->transport_callbacks.send_complete_cb(&(deviceData->eventConfirmations), IOTHUB_CLIENT_CONFIRMATION_OK, deviceData->device_transport_ctx); // takes care of emptying the list too
+                                            }
+                                            else
+                                            {
+                                                /*Codes_SRS_TRANSPORTMULTITHTTP_17_081: [If HTTPAPIEX_SAS_ExecuteRequest fails or the http status code >=300 then IoTHubTransportHttp_DoWork shall not do any other action (it is assumed at the next _DoWork it shall be retried).] */
+                                                LogError("unexpected HTTP status code (%u)", statusCode);
+                                            }
+                                        }
+                                        else if (r == HTTPAPIEX_RECOVERYFAILED)
+                                        {
+                                            PDLIST_ENTRY justSent = DList_RemoveHeadList(deviceData->waitingToSend); /*actually this is the same as "actual", but now it is removed*/
+                                            DList_InsertTailList(&(deviceData->eventConfirmations), justSent);
+                                            handleData->transport_callbacks.send_complete_cb(&(deviceData->eventConfirmations), IOTHUB_CLIENT_CONFIRMATION_ERROR, deviceData->device_transport_ctx); // takes care of emptying the list too
+                                        }
+                                    }
+                                    BUFFER_delete(toBeSend);
+                                }
+                            }
+                        }
+                        HTTPHeaders_Free(clonedEventHTTPrequestHeaders);
+                    }
+                }
+            }
+        }
+    }
+}
+
+static bool abandonOrAcceptMessage(HTTPTRANSPORT_HANDLE_DATA* handleData, HTTPTRANSPORT_PERDEVICE_DATA* deviceData, const char* ETag, IOTHUBMESSAGE_DISPOSITION_RESULT action)
+{
+    /*Codes_SRS_TRANSPORTMULTITHTTP_17_097: [_DoWork shall call HTTPAPIEX_SAS_ExecuteRequest with the following parameters:
+    -requestType: POST
+    -relativePath: abandon relative path begin (as created by _Create) + value of ETag + "/abandon?api-version=2016-11-14"
+    - requestHttpHeadersHandle: an HTTP headers instance containing the following
+    Authorization: " "
+    If-Match: value of ETag
+    - requestContent: NULL
+    - statusCode: a pointer to unsigned int which might be examined for logging
+    - responseHeadearsHandle: NULL
+    - responseContent: NULL]*/
+    /*Codes_SRS_TRANSPORTMULTITHTTP_17_099: [_DoWork shall call HTTPAPIEX_SAS_ExecuteRequest with the following parameters:
+    -requestType: DELETE
+    -relativePath: abandon relative path begin + value of ETag + "?api-version=2016-11-14"
+    - requestHttpHeadersHandle: an HTTP headers instance containing the following
+    Authorization: " "
+    If-Match: value of ETag
+    - requestContent: NULL
+    - statusCode: a pointer to unsigned int which might be used by logging
+    - responseHeadearsHandle: NULL
+    - responseContent: NULL]*/
+    /*Codes_SRS_TRANSPORTMULTITHTTP_17_101: [_DoWork shall call HTTPAPIEX_SAS_ExecuteRequest with the following parameters:
+    -requestType: DELETE
+    -relativePath: abandon relative path begin + value of ETag +"?api-version=2016-11-14" + "&reject"
+    - requestHttpHeadersHandle: an HTTP headers instance containing the following
+    Authorization: " "
+    If-Match: value of ETag
+    - requestContent: NULL
+    - statusCode: a pointer to unsigned int which might be used by logging
+    - responseHeadearsHandle: NULL
+    - responseContent: NULL]*/
+
+    bool result;
+    STRING_HANDLE fullAbandonRelativePath = STRING_clone(deviceData->abandonHTTPrelativePathBegin);
+    if (fullAbandonRelativePath == NULL)
+    {
+        /*Codes_SRS_TRANSPORTMULTITHTTP_17_098: [Abandoning the message is considered successful if the HTTPAPIEX_SAS_ExecuteRequest doesn't fail and the statusCode is 204.]*/
+        /*Codes_SRS_TRANSPORTMULTITHTTP_17_100: [Accepting a message is successful when HTTPAPIEX_SAS_ExecuteRequest completes successfully and the status code is 204.] */
+        /*Codes_SRS_TRANSPORTMULTITHTTP_17_102: [Rejecting a message is successful when HTTPAPIEX_SAS_ExecuteRequest completes successfully and the status code is 204.] */
+        LogError("unable to STRING_clone");
+        result = false;
+    }
+    else
+    {
+        STRING_HANDLE ETagUnquoted = STRING_construct_n(ETag + 1, strlen(ETag) - 2); /*skip first character which is '"' and the last one (which is also '"')*/
+        if (ETagUnquoted == NULL)
+        {
+            /*Codes_SRS_TRANSPORTMULTITHTTP_17_098: [Abandoning the message is considered successful if the HTTPAPIEX_SAS_ExecuteRequest doesn't fail and the statusCode is 204.]*/
+            /*Codes_SRS_TRANSPORTMULTITHTTP_17_100: [Accepting a message is successful when HTTPAPIEX_SAS_ExecuteRequest completes successfully and the status code is 204.] */
+            /*Codes_SRS_TRANSPORTMULTITHTTP_17_102: [Rejecting a message is successful when HTTPAPIEX_SAS_ExecuteRequest completes successfully and the status code is 204.] */
+            LogError("unable to STRING_construct_n");
+            result = false;
+        }
+        else
+        {
+            if (!(
+                (STRING_concat_with_STRING(fullAbandonRelativePath, ETagUnquoted) == 0) &&
+                (STRING_concat(fullAbandonRelativePath, (action == IOTHUBMESSAGE_ABANDONED) ? "/abandon" API_VERSION : ((action == IOTHUBMESSAGE_REJECTED) ? API_VERSION "&reject" : API_VERSION)) == 0)
+                ))
+            {
+                /*Codes_SRS_TRANSPORTMULTITHTTP_17_098: [Abandoning the message is considered successful if the HTTPAPIEX_SAS_ExecuteRequest doesn't fail and the statusCode is 204.]*/
+                /*Codes_SRS_TRANSPORTMULTITHTTP_17_100: [Accepting a message is successful when HTTPAPIEX_SAS_ExecuteRequest completes successfully and the status code is 204.] */
+                /*Codes_SRS_TRANSPORTMULTITHTTP_17_102: [Rejecting a message is successful when HTTPAPIEX_SAS_ExecuteRequest completes successfully and the status code is 204.] */
+                LogError("unable to STRING_concat");
+                result = false;
+            }
+            else
+            {
+                HTTP_HEADERS_HANDLE abandonRequestHttpHeaders = HTTPHeaders_Alloc();
+                if (abandonRequestHttpHeaders == NULL)
+                {
+                    /*Codes_SRS_TRANSPORTMULTITHTTP_17_098: [Abandoning the message is considered successful if the HTTPAPIEX_SAS_ExecuteRequest doesn't fail and the statusCode is 204.]*/
+                    /*Codes_SRS_TRANSPORTMULTITHTTP_17_100: [Accepting a message is successful when HTTPAPIEX_SAS_ExecuteRequest completes successfully and the status code is 204.] */
+                    /*Codes_SRS_TRANSPORTMULTITHTTP_17_102: [Rejecting a message is successful when HTTPAPIEX_SAS_ExecuteRequest completes successfully and the status code is 204.] */
+                    LogError("unable to HTTPHeaders_Alloc");
+                    result = false;
+                }
+                else
+                {
+                    if (!(
+                        (addUserAgentHeaderInfo(handleData, abandonRequestHttpHeaders) == HTTP_HEADERS_OK) &&
+                        (HTTPHeaders_AddHeaderNameValuePair(abandonRequestHttpHeaders, IOTHUB_AUTH_HEADER_VALUE, " ") == HTTP_HEADERS_OK) &&
+                        (HTTPHeaders_AddHeaderNameValuePair(abandonRequestHttpHeaders, "If-Match", ETag) == HTTP_HEADERS_OK)
+                        ))
+                    {
+                        /*Codes_SRS_TRANSPORTMULTITHTTP_17_098: [Abandoning the message is considered successful if the HTTPAPIEX_SAS_ExecuteRequest doesn't fail and the statusCode is 204.]*/
+                        /*Codes_SRS_TRANSPORTMULTITHTTP_17_100: [Accepting a message is successful when HTTPAPIEX_SAS_ExecuteRequest completes successfully and the status code is 204.] */
+                        /*Codes_SRS_TRANSPORTMULTITHTTP_17_102: [Rejecting a message is successful when HTTPAPIEX_SAS_ExecuteRequest completes successfully and the status code is 204.] */
+                        LogError("unable to HTTPHeaders_AddHeaderNameValuePair");
+                        result = false;
+                    }
+                    else
+                    {
+                        unsigned int statusCode = 0;
+                        HTTPAPIEX_RESULT r;
+                        if (deviceData->deviceSasToken != NULL)
+                        {
+                            /*Codes_SRS_TRANSPORTMULTITHTTP_03_001: [if a deviceSasToken exists, HTTPHeaders_ReplaceHeaderNameValuePair shall be invoked with "Authorization" as its second argument and STRING_c_str (deviceSasToken) as its third argument.]*/
+                            if (HTTPHeaders_ReplaceHeaderNameValuePair(abandonRequestHttpHeaders, IOTHUB_AUTH_HEADER_VALUE, STRING_c_str(deviceData->deviceSasToken)) != HTTP_HEADERS_OK)
+                            {
+                                r = HTTPAPIEX_ERROR;
+                                /*Codes_SRS_TRANSPORTMULTITHTTP_03_002: [If the result of the invocation of HTTPHeaders_ReplaceHeaderNameValuePair is NOT HTTP_HEADERS_OK then fallthrough.]*/
+                                LogError("Unable to replace the old SAS Token.");
+                                result = false;
+                            }
+                            else if ((r = HTTPAPIEX_ExecuteRequest(
+                                handleData->httpApiExHandle,
+                                (action == IOTHUBMESSAGE_ABANDONED) ? HTTPAPI_REQUEST_POST : HTTPAPI_REQUEST_DELETE,                               /*-requestType: POST                                                                                                       */
+                                STRING_c_str(fullAbandonRelativePath),              /*-relativePath: abandon relative path begin (as created by _Create) + value of ETag + "/abandon?api-version=2016-11-14"   */
+                                abandonRequestHttpHeaders,                          /*- requestHttpHeadersHandle: an HTTP headers instance containing the following                                            */
+                                NULL,                                               /*- requestContent: NULL                                                                                                   */
+                                &statusCode,                                         /*- statusCode: a pointer to unsigned int which might be examined for logging                                              */
+                                NULL,                                               /*- responseHeadearsHandle: NULL                                                                                           */
+                                NULL                                                /*- responseContent: NULL]                                                                                                 */
+                            )) != HTTPAPIEX_OK)
+                            {
+                                /*Codes_SRS_TRANSPORTMULTITHTTP_17_098: [Abandoning the message is considered successful if the HTTPAPIEX_SAS_ExecuteRequest doesn't fail and the statusCode is 204.]*/
+                                /*Codes_SRS_TRANSPORTMULTITHTTP_17_100: [Accepting a message is successful when HTTPAPIEX_SAS_ExecuteRequest completes successfully and the status code is 204.] */
+                                /*Codes_SRS_TRANSPORTMULTITHTTP_17_102: [Rejecting a message is successful when HTTPAPIEX_SAS_ExecuteRequest completes successfully and the status code is 204.] */
+                                LogError("Unable to HTTPAPIEX_ExecuteRequest.");
+                                result = false;
+                            }
+                        }
+                        else if ((r = HTTPAPIEX_SAS_ExecuteRequest(
+                            deviceData->sasObject,
+                            handleData->httpApiExHandle,
+                            (action == IOTHUBMESSAGE_ABANDONED) ? HTTPAPI_REQUEST_POST : HTTPAPI_REQUEST_DELETE,                               /*-requestType: POST                                                                                                       */
+                            STRING_c_str(fullAbandonRelativePath),              /*-relativePath: abandon relative path begin (as created by _Create) + value of ETag + "/abandon?api-version=2016-11-14"   */
+                            abandonRequestHttpHeaders,                          /*- requestHttpHeadersHandle: an HTTP headers instance containing the following                                            */
+                            NULL,                                               /*- requestContent: NULL                                                                                                   */
+                            &statusCode,                                         /*- statusCode: a pointer to unsigned int which might be examined for logging                                              */
+                            NULL,                                               /*- responseHeadearsHandle: NULL                                                                                           */
+                            NULL                                                /*- responseContent: NULL]                                                                                                 */
+                        )) != HTTPAPIEX_OK)
+                        {
+                            /*Codes_SRS_TRANSPORTMULTITHTTP_17_098: [Abandoning the message is considered successful if the HTTPAPIEX_SAS_ExecuteRequest doesn't fail and the statusCode is 204.]*/
+                            /*Codes_SRS_TRANSPORTMULTITHTTP_17_100: [Accepting a message is successful when HTTPAPIEX_SAS_ExecuteRequest completes successfully and the status code is 204.] */
+                            /*Codes_SRS_TRANSPORTMULTITHTTP_17_102: [Rejecting a message is successful when HTTPAPIEX_SAS_ExecuteRequest completes successfully and the status code is 204.] */
+                            LogError("unable to HTTPAPIEX_SAS_ExecuteRequest");
+                            result = false;
+                        }
+                        if (r == HTTPAPIEX_OK)
+                        {
+                            if (statusCode != 204)
+                            {
+                                /*Codes_SRS_TRANSPORTMULTITHTTP_17_098: [Abandoning the message is considered successful if the HTTPAPIEX_SAS_ExecuteRequest doesn't fail and the statusCode is 204.]*/
+                                /*Codes_SRS_TRANSPORTMULTITHTTP_17_100: [Accepting a message is successful when HTTPAPIEX_SAS_ExecuteRequest completes successfully and the status code is 204.] */
+                                /*Codes_SRS_TRANSPORTMULTITHTTP_17_102: [Rejecting a message is successful when HTTPAPIEX_SAS_ExecuteRequest completes successfully and the status code is 204.] */
+                                LogError("unexpected status code returned %u (was expecting 204)", statusCode);
+                                result = false;
+                            }
+                            else
+                            {
+                                /*Codes_SRS_TRANSPORTMULTITHTTP_17_098: [Abandoning the message is considered successful if the HTTPAPIEX_SAS_ExecuteRequest doesn't fail and the statusCode is 204.]*/
+                                /*Codes_SRS_TRANSPORTMULTITHTTP_17_100: [Accepting a message is successful when HTTPAPIEX_SAS_ExecuteRequest completes successfully and the status code is 204.] */
+                                /*Codes_SRS_TRANSPORTMULTITHTTP_17_102: [Rejecting a message is successful when HTTPAPIEX_SAS_ExecuteRequest completes successfully and the status code is 204.] */
+                                /*all is fine*/
+                                result = true;
+                            }
+                        }
+                        else
+                        {
+                            result = false;
+                        }
+                    }
+                    HTTPHeaders_Free(abandonRequestHttpHeaders);
+                }
+            }
+            STRING_delete(ETagUnquoted);
+        }
+        STRING_delete(fullAbandonRelativePath);
+    }
+    return result;
+}
+
+static IOTHUB_CLIENT_RESULT IoTHubTransportHttp_SendMessageDisposition(MESSAGE_CALLBACK_INFO* message_data, IOTHUBMESSAGE_DISPOSITION_RESULT disposition)
+{
+    IOTHUB_CLIENT_RESULT result;
+    if (message_data == NULL)
+    {
+        /* Codes_SRS_TRANSPORTMULTITHTTP_10_001: [If messageData is NULL, IoTHubTransportHttp_SendMessageDisposition shall fail and return IOTHUB_CLIENT_ERROR.] */
+        LogError("invalid argument messageData is NULL");
+        result = IOTHUB_CLIENT_ERROR;
+    }
+    else
+    {
+        if (message_data->messageHandle == NULL)
+        {
+            /* Codes_SRS_TRANSPORTMULTITHTTP_10_002: [If any of the messageData fields are NULL, IoTHubTransportHttp_SendMessageDisposition shall fail and return IOTHUB_CLIENT_ERROR.] */
+            LogError("invalid message handle");
+            result = IOTHUB_CLIENT_ERROR;
+        }
+        else
+        {
+            MESSAGE_DISPOSITION_CONTEXT* tc = (MESSAGE_DISPOSITION_CONTEXT*)(message_data->transportContext);
+            if (tc == NULL)
+            {
+                /* Codes_SRS_TRANSPORTMULTITHTTP_10_002: [If any of the messageData fields are NULL, IoTHubTransportHttp_SendMessageDisposition shall fail and return IOTHUB_CLIENT_ERROR.] */
+                LogError("invalid transport context data");
+                result = IOTHUB_CLIENT_ERROR;
+            }
+            else
+            {
+                if ((tc->handleData == NULL) || (tc->deviceData == NULL) || (tc->etagValue == NULL))
+                {
+                    /* Codes_SRS_TRANSPORTMULTITHTTP_10_002: [If any of the messageData fields are NULL, IoTHubTransportHttp_SendMessageDisposition shall fail and return IOTHUB_CLIENT_ERROR.] */
+                    LogError("invalid transport context data");
+                    result = IOTHUB_CLIENT_ERROR;
+                }
+                else
+                {
+                    if (abandonOrAcceptMessage(tc->handleData, tc->deviceData, tc->etagValue, disposition))
+                    {
+                        result = IOTHUB_CLIENT_OK;
+                    }
+                    else
+                    {
+                        /* Codes_SRS_TRANSPORTMULTITHTTP_10_003: [IoTHubTransportHttp_SendMessageDisposition shall fail and return IOTHUB_CLIENT_ERROR if the POST message fails, otherwise return IOTHUB_CLIENT_OK.] */
+                        LogError("HTTP Transport layer failed to report %s disposition", MU_ENUM_TO_STRING(IOTHUBMESSAGE_DISPOSITION_RESULT, disposition));
+                        result = IOTHUB_CLIENT_ERROR;
+                    }
+                }
+                free(tc->etagValue);
+                free(tc);
+            }
+            IoTHubMessage_Destroy(message_data->messageHandle);
+        }
+        free(message_data);
+    }
+    return result;
+}
+
+static MESSAGE_CALLBACK_INFO* MESSAGE_CALLBACK_INFO_Create(IOTHUB_MESSAGE_HANDLE received_message, HTTPTRANSPORT_HANDLE_DATA* handleData, HTTPTRANSPORT_PERDEVICE_DATA* deviceData, const char* etagValue)
+{
+    MESSAGE_CALLBACK_INFO* result = (MESSAGE_CALLBACK_INFO*)malloc(sizeof(MESSAGE_CALLBACK_INFO));
+    if (result == NULL)
+    {
+        /*Codes_SRS_TRANSPORTMULTITHTTP_10_006: [If assembling the transport context fails, _DoWork shall "abandon" the message.] */
+        LogError("malloc failed");
+    }
+    else
+    {
+        MESSAGE_DISPOSITION_CONTEXT* tc = (MESSAGE_DISPOSITION_CONTEXT*)malloc(sizeof(MESSAGE_DISPOSITION_CONTEXT));
+        if (tc == NULL)
+        {
+            /*Codes_SRS_TRANSPORTMULTITHTTP_10_006: [If assembling the transport context fails, _DoWork shall "abandon" the message.] */
+            LogError("malloc failed");
+            free(result);
+            result = NULL;
+        }
+        else
+        {
+            result->messageHandle = IoTHubMessage_Clone(received_message);
+            if (result->messageHandle == NULL)
+            {
+                /*Codes_SRS_TRANSPORTMULTITHTTP_10_007: [If assembling a message clone, _DoWork shall "abandon" the message.]*/
+                LogError("IoTHubMessage_Clone failed");
+                free(tc);
+                free(result);
+                result = NULL;
+            }
+            else
+            {
+                if (mallocAndStrcpy_s(&tc->etagValue, etagValue) != 0)
+                {
+                    LogError("mallocAndStrcpy_s failed");
+                    free(tc);
+                    free(result);
+                    result = NULL;
+                }
+                else
+                {
+                    tc->handleData = handleData;
+                    tc->deviceData = deviceData;
+
+                    result->transportContext = tc;
+                }
+            }
+        }
+    }
+    return result;
+}
+
+static void DoMessages(HTTPTRANSPORT_HANDLE_DATA* handleData, HTTPTRANSPORT_PERDEVICE_DATA* deviceData)
+{
+    /*Codes_SRS_TRANSPORTMULTITHTTP_17_083: [ If device is not subscribed then _DoWork shall advance to the next action. ] */
+    if (deviceData->DoWork_PullMessage)
+    {
+        /*Codes_SRS_TRANSPORTMULTITHTTP_17_123: [After client creation, the first GET shall be allowed no matter what the value of GetMinimumPollingTime.] */
+        /*Codes_SRS_TRANSPORTMULTITHTTP_17_124: [If time is not available then all calls shall be treated as if they are the first one.] */
+        /*Codes_SRS_TRANSPORTMULTITHTTP_17_122: [A GET request that happens earlier than GetMinimumPollingTime shall be ignored.] */
+        time_t timeNow = get_time(NULL);
+        bool isPollingAllowed = deviceData->isFirstPoll || (timeNow == (time_t)(-1)) || (get_difftime(timeNow, deviceData->lastPollTime) > handleData->getMinimumPollingTime);
+        if (isPollingAllowed)
+        {
+            HTTP_HEADERS_HANDLE responseHTTPHeaders = HTTPHeaders_Alloc();
+            if (responseHTTPHeaders == NULL)
+            {
+                /*Codes_SRS_TRANSPORTMULTITHTTP_17_085: [If the call to HTTPAPIEX_SAS_ExecuteRequest did not executed successfully or building any part of the prerequisites of the call fails, then _DoWork shall advance to the next action in this description.] */
+                LogError("unable to HTTPHeaders_Alloc");
+            }
+            else
+            {
+                BUFFER_HANDLE responseContent = BUFFER_new();
+                if (responseContent == NULL)
+                {
+                    /*Codes_SRS_TRANSPORTMULTITHTTP_17_085: [If the call to HTTPAPIEX_SAS_ExecuteRequest did not executed successfully or building any part of the prerequisites of the call fails, then _DoWork shall advance to the next action in this description.] */
+                    LogError("unable to BUFFER_new");
+                }
+                else
+                {
+                    unsigned int statusCode = 0;
+                    HTTPAPIEX_RESULT r;
+                    if (deviceData->deviceSasToken != NULL)
+                    {
+                        /*Codes_SRS_TRANSPORTMULTITHTTP_03_001: [if a deviceSasToken exists, HTTPHeaders_ReplaceHeaderNameValuePair shall be invoked with "Authorization" as its second argument and STRING_c_str (deviceSasToken) as its third argument.]*/
+                        if (HTTPHeaders_ReplaceHeaderNameValuePair(deviceData->messageHTTPrequestHeaders, IOTHUB_AUTH_HEADER_VALUE, STRING_c_str(deviceData->deviceSasToken)) != HTTP_HEADERS_OK)
+                        {
+                            r = HTTPAPIEX_ERROR;
+                            /*Codes_SRS_TRANSPORTMULTITHTTP_03_002: [If the result of the invocation of HTTPHeaders_ReplaceHeaderNameValuePair is NOT HTTP_HEADERS_OK then fallthrough.]*/
+                            LogError("Unable to replace the old SAS Token.");
+                        }
+                        else if ((r = HTTPAPIEX_ExecuteRequest(
+                            handleData->httpApiExHandle,
+                            HTTPAPI_REQUEST_GET,                                            /*requestType: GET*/
+                            STRING_c_str(deviceData->messageHTTPrelativePath),         /*relativePath: the message HTTP relative path*/
+                            deviceData->messageHTTPrequestHeaders,                     /*requestHttpHeadersHandle: message HTTP request headers created by _Create*/
+                            NULL,                                                           /*requestContent: NULL*/
+                            &statusCode,                                                    /*statusCode: a pointer to unsigned int which shall be later examined*/
+                            responseHTTPHeaders,                                            /*responseHeadearsHandle: a new instance of HTTP headers*/
+                            responseContent                                                 /*responseContent: a new instance of buffer*/
+                        )) != HTTPAPIEX_OK)
+                        {
+                            /*Codes_SRS_TRANSPORTMULTITHTTP_17_085: [If the call to HTTPAPIEX_SAS_ExecuteRequest did not executed successfully or building any part of the prerequisites of the call fails, then _DoWork shall advance to the next action in this description.] */
+                            LogError("Unable to HTTPAPIEX_ExecuteRequest.");
+                        }
+                    }
+
+                    /*Codes_SRS_TRANSPORTMULTITHTTP_17_084: [Otherwise, IoTHubTransportHttp_DoWork shall call HTTPAPIEX_SAS_ExecuteRequest passing the following parameters
+                    requestType: GET
+                    relativePath: the message HTTP relative path
+                    requestHttpHeadersHandle: message HTTP request headers created by _Create
+                    requestContent: NULL
+                    statusCode: a pointer to unsigned int which shall be later examined
+                    responseHeadearsHandle: a new instance of HTTP headers
+                    responseContent: a new instance of buffer]
+                    */
+                    else if ((r = HTTPAPIEX_SAS_ExecuteRequest(
+                        deviceData->sasObject,
+                        handleData->httpApiExHandle,
+                        HTTPAPI_REQUEST_GET,                                            /*requestType: GET*/
+                        STRING_c_str(deviceData->messageHTTPrelativePath),         /*relativePath: the message HTTP relative path*/
+                        deviceData->messageHTTPrequestHeaders,                     /*requestHttpHeadersHandle: message HTTP request headers created by _Create*/
+                        NULL,                                                           /*requestContent: NULL*/
+                        &statusCode,                                                    /*statusCode: a pointer to unsigned int which shall be later examined*/
+                        responseHTTPHeaders,                                            /*responseHeadearsHandle: a new instance of HTTP headers*/
+                        responseContent                                                 /*responseContent: a new instance of buffer*/
+                    )) != HTTPAPIEX_OK)
+                    {
+                        /*Codes_SRS_TRANSPORTMULTITHTTP_17_085: [If the call to HTTPAPIEX_SAS_ExecuteRequest did not executed successfully or building any part of the prerequisites of the call fails, then _DoWork shall advance to the next action in this description.] */
+                        LogError("unable to HTTPAPIEX_SAS_ExecuteRequest");
+                    }
+                    if (r == HTTPAPIEX_OK)
+                    {
+                        /*HTTP dialogue was succesfull*/
+                        if (timeNow == (time_t)(-1))
+                        {
+                            deviceData->isFirstPoll = true;
+                        }
+                        else
+                        {
+                            deviceData->isFirstPoll = false;
+                            deviceData->lastPollTime = timeNow;
+                        }
+                        if (statusCode == 204)
+                        {
+                            /*Codes_SRS_TRANSPORTMULTITHTTP_17_086: [If the HTTPAPIEX_SAS_ExecuteRequest executed successfully then status code shall be examined. Any status code different than 200 causes _DoWork to advance to the next action.] */
+                            /*this is an expected status code, means "no commands", but logging that creates panic*/
+
+                            /*do nothing, advance to next action*/
+                        }
+                        else if (statusCode != 200)
+                        {
+                            /*Codes_SRS_TRANSPORTMULTITHTTP_17_086: [If the HTTPAPIEX_SAS_ExecuteRequest executed successfully then status code shall be examined. Any status code different than 200 causes _DoWork to advance to the next action.] */
+                            LogError("expected status code was 200, but actually was received %u... moving on", statusCode);
+                        }
+                        else
+                        {
+                            /*Codes_SRS_TRANSPORTMULTITHTTP_17_087: [If status code is 200, then _DoWork shall make a copy of the value of the "ETag" http header.]*/
+                            const char* etagValue = HTTPHeaders_FindHeaderValue(responseHTTPHeaders, "ETag");
+                            if (etagValue == NULL)
+                            {
+                                LogError("unable to find a received header called \"E-Tag\"");
+                            }
+                            else
+                            {
+                                /*Codes_SRS_TRANSPORTMULTITHTTP_17_088: [If no such header is found or is invalid, then _DoWork shall advance to the next action.]*/
+                                size_t etagsize = strlen(etagValue);
+                                if (
+                                    (etagsize < 2) ||
+                                    (etagValue[0] != '"') ||
+                                    (etagValue[etagsize - 1] != '"')
+                                    )
+                                {
+                                    LogError("ETag is not a valid quoted string");
+                                }
+                                else
+                                {
+                                    const unsigned char* resp_content;
+                                    size_t resp_len;
+                                    /*Codes_SRS_TRANSPORTMULTITHTTP_17_089: [_DoWork shall assemble an IOTHUBMESSAGE_HANDLE from the received HTTP content (using the responseContent buffer).] */
+                                    resp_content = BUFFER_u_char(responseContent);
+                                    resp_len = BUFFER_length(responseContent);
+                                    IOTHUB_MESSAGE_HANDLE receivedMessage = IoTHubMessage_CreateFromByteArray(resp_content, resp_len);
+                                    if (receivedMessage == NULL)
+                                    {
+                                        /*Codes_SRS_TRANSPORTMULTITHTTP_17_092: [If assembling the message fails in any way, then _DoWork shall "abandon" the message.]*/
+                                        LogError("unable to IoTHubMessage_CreateFromByteArray, trying to abandon the message... ");
+                                        if (!abandonOrAcceptMessage(handleData, deviceData, etagValue, IOTHUBMESSAGE_ABANDONED))
+                                        {
+                                            LogError("HTTP Transport layer failed to report ABANDON disposition");
+                                        }
+                                    }
+                                    else
+                                    {
+                                        if (retrieve_message_properties(responseHTTPHeaders, receivedMessage) != 0)
+                                        {
+                                            if (!abandonOrAcceptMessage(handleData, deviceData, etagValue, IOTHUBMESSAGE_ABANDONED))
+                                            {
+                                                LogError("HTTP Transport layer failed to report ABANDON disposition");
+                                            }
+                                        }
+                                        else
+                                        {
+                                            MESSAGE_CALLBACK_INFO* messageData = MESSAGE_CALLBACK_INFO_Create(receivedMessage, handleData, deviceData, etagValue);
+                                            if (messageData == NULL)
+                                            {
+                                                /*Codes_SRS_TRANSPORTMULTITHTTP_10_006: [If assembling the transport context fails, _DoWork shall "abandon" the message.] */
+                                                LogError("failed to assemble callback info");
+                                                if (!abandonOrAcceptMessage(handleData, deviceData, etagValue, IOTHUBMESSAGE_ABANDONED))
+                                                {
+                                                    LogError("HTTP Transport layer failed to report ABANDON disposition");
+                                                }
+                                            }
+                                            else
+                                            {
+                                                bool abandon;
+                                                if (handleData->transport_callbacks.msg_cb(messageData, deviceData->device_transport_ctx))
+                                                {
+                                                    abandon = false;
+                                                }
+                                                else
+                                                {
+                                                    LogError("IoTHubClientCore_LL_MessageCallback failed");
+                                                    abandon = true;
+                                                }
+
+                                                /*Codes_SRS_TRANSPORTMULTITHTTP_17_096: [If IoTHubClientCore_LL_MessageCallback returns false then _DoWork shall "abandon" the message.] */
+                                                if (abandon)
+                                                {
+                                                    (void)IoTHubTransportHttp_SendMessageDisposition(messageData, IOTHUBMESSAGE_ABANDONED);
+                                                }
+                                            }
+                                        }
+                                        IoTHubMessage_Destroy(receivedMessage);
+                                    }
+                                }
+                            }
+                        }
+                    }
+                    BUFFER_delete(responseContent);
+                }
+                HTTPHeaders_Free(responseHTTPHeaders);
+            }
+        }
+        else
+        {
+            /*isPollingAllowed is false... */
+            /*do nothing "shall be ignored*/
+        }
+    }
+}
+
+static IOTHUB_PROCESS_ITEM_RESULT IoTHubTransportHttp_ProcessItem(TRANSPORT_LL_HANDLE handle, IOTHUB_IDENTITY_TYPE item_type, IOTHUB_IDENTITY_INFO* iothub_item)
+{
+    (void)handle;
+    (void)item_type;
+    (void)iothub_item;
+    LogError("Currently Not Supported.");
+    return IOTHUB_PROCESS_ERROR;
+}
+
+static void IoTHubTransportHttp_DoWork(TRANSPORT_LL_HANDLE handle)
+{
+    /*Codes_SRS_TRANSPORTMULTITHTTP_17_049: [ If handle is NULL, then IoTHubTransportHttp_DoWork shall do nothing. ]*/
+    if (handle != NULL)
+    {
+        HTTPTRANSPORT_HANDLE_DATA* handleData = (HTTPTRANSPORT_HANDLE_DATA*)handle;
+        IOTHUB_DEVICE_HANDLE* listItem;
+        size_t deviceListSize = VECTOR_size(handleData->perDeviceList);
+        /*Codes_SRS_TRANSPORTMULTITHTTP_17_052: [ IoTHubTransportHttp_DoWork shall perform a round-robin loop through every deviceHandle in the transport device list. ]*/
+        /*Codes_SRS_TRANSPORTMULTITHTTP_17_050: [ IoTHubTransportHttp_DoWork shall call loop through the device list. ] */
+        /*Codes_SRS_TRANSPORTMULTITHTTP_17_051: [ IF the list is empty, then IoTHubTransportHttp_DoWork shall do nothing. ]*/
+        for (size_t i = 0; i < deviceListSize; i++)
+        {
+            listItem = (IOTHUB_DEVICE_HANDLE *)VECTOR_element(handleData->perDeviceList, i);
+            HTTPTRANSPORT_PERDEVICE_DATA* perDeviceItem = *(HTTPTRANSPORT_PERDEVICE_DATA**)(listItem);
+            DoEvent(handleData, perDeviceItem);
+            DoMessages(handleData, perDeviceItem);
+        }
+    }
+    else
+    {
+        LogError("Invalid Argument NULL call on DoWork.");
+    }
+}
+
+static IOTHUB_CLIENT_RESULT IoTHubTransportHttp_GetSendStatus(IOTHUB_DEVICE_HANDLE handle, IOTHUB_CLIENT_STATUS *iotHubClientStatus)
+{
+    IOTHUB_CLIENT_RESULT result;
+
+    if (handle == NULL)
+    {
+        /*Codes_SRS_TRANSPORTMULTITHTTP_17_111: [ IoTHubTransportHttp_GetSendStatus shall return IOTHUB_CLIENT_INVALID_ARG if called with NULL parameter. ]*/
+        result = IOTHUB_CLIENT_INVALID_ARG;
+        LogError("Invalid handle to IoTHubClient HTTP transport instance.");
+    }
+    else if (iotHubClientStatus == NULL)
+    {
+        result = IOTHUB_CLIENT_INVALID_ARG;
+        LogError("Invalid pointer to output parameter IOTHUB_CLIENT_STATUS.");
+    }
+    else
+    {
+        /*Codes_SRS_TRANSPORTMULTITHTTP_17_138: [ IoTHubTransportHttp_GetSendStatus shall locate deviceHandle in the transport device list by calling list_find_if. ]*/
+        IOTHUB_DEVICE_HANDLE* listItem = get_perDeviceDataItem(handle);
+        if (listItem == NULL)
+        {
+            /*Codes_SRS_TRANSPORTMULTITHTTP_17_139: [ If the device structure is not found, then this function shall fail and return with IOTHUB_CLIENT_INVALID_ARG. ]*/
+            result = IOTHUB_CLIENT_INVALID_ARG;
+            LogError("Device not found in transport list.");
+        }
+        else
+        {
+            HTTPTRANSPORT_PERDEVICE_DATA* deviceData = (HTTPTRANSPORT_PERDEVICE_DATA*)(*listItem);
+            /* Codes_SRS_TRANSPORTMULTITHTTP_17_113: [ IoTHubTransportHttp_GetSendStatus shall return IOTHUB_CLIENT_OK and status IOTHUB_CLIENT_SEND_STATUS_BUSY if there are currently event items to be sent or being sent. ] */
+            if (!DList_IsListEmpty(deviceData->waitingToSend))
+            {
+                *iotHubClientStatus = IOTHUB_CLIENT_SEND_STATUS_BUSY;
+            }
+            /* Codes_SRS_TRANSPORTMULTITHTTP_17_112: [ IoTHubTransportHttp_GetSendStatus shall return IOTHUB_CLIENT_OK and status IOTHUB_CLIENT_SEND_STATUS_IDLE if there are currently no event items to be sent or being sent. ] */
+            else
+            {
+                *iotHubClientStatus = IOTHUB_CLIENT_SEND_STATUS_IDLE;
+            }
+            result = IOTHUB_CLIENT_OK;
+        }
+    }
+
+    return result;
+}
+
+static IOTHUB_CLIENT_RESULT IoTHubTransportHttp_SetOption(TRANSPORT_LL_HANDLE handle, const char* option, const void* value)
+{
+    IOTHUB_CLIENT_RESULT result;
+    /*Codes_SRS_TRANSPORTMULTITHTTP_17_114: [If handle parameter is NULL then IoTHubTransportHttp_SetOption shall return IOTHUB_CLIENT_INVALID_ARG.] */
+    /*Codes_SRS_TRANSPORTMULTITHTTP_17_115: [If option parameter is NULL then IoTHubTransportHttp_SetOption shall return IOTHUB_CLIENT_INVALID_ARG.] */
+    /*Codes_SRS_TRANSPORTMULTITHTTP_17_116: [If value parameter is NULL then IoTHubTransportHttp_SetOption shall return IOTHUB_CLIENT_INVALID_ARG.] */
+    if (
+        (handle == NULL) ||
+        (option == NULL) ||
+        (value == NULL)
+        )
+    {
+        result = IOTHUB_CLIENT_INVALID_ARG;
+        LogError("invalid parameter (NULL) passed to IoTHubTransportHttp_SetOption");
+    }
+    else
+    {
+        HTTPTRANSPORT_HANDLE_DATA* handleData = (HTTPTRANSPORT_HANDLE_DATA*)handle;
+        /*Codes_SRS_TRANSPORTMULTITHTTP_17_120: ["Batching"] */
+        if (strcmp(OPTION_BATCHING, option) == 0)
+        {
+            /*Codes_SRS_TRANSPORTMULTITHTTP_17_117: [If optionName is an option handled by IoTHubTransportHttp then it shall be set.] */
+            handleData->doBatchedTransfers = *(bool*)value;
+            result = IOTHUB_CLIENT_OK;
+        }
+        /*Codes_SRS_TRANSPORTMULTITHTTP_17_121: ["MinimumPollingTime"] */
+        else if (strcmp(OPTION_MIN_POLLING_TIME, option) == 0)
+        {
+            handleData->getMinimumPollingTime = *(unsigned int*)value;
+            result = IOTHUB_CLIENT_OK;
+        }
+        else
+        {
+            /*Codes_SRS_TRANSPORTMULTITHTTP_17_126: [ "TrustedCerts"] */
+            /*Codes_SRS_TRANSPORTMULTITHTTP_17_127: [ NULL shall be allowed. ]*/
+            /*Codes_SRS_TRANSPORTMULTITHTTP_17_129: [ This option shall passed down to the lower layer by calling HTTPAPIEX_SetOption. ]*/
+            /*Codes_SRS_TRANSPORTMULTITHTTP_17_118: [Otherwise, IoTHubTransport_Http shall call HTTPAPIEX_SetOption with the same parameters and return the translated code.] */
+            HTTPAPIEX_RESULT HTTPAPIEX_result = HTTPAPIEX_SetOption(handleData->httpApiExHandle, option, value);
+            /*Codes_SRS_TRANSPORTMULTITHTTP_17_119: [The following table translates HTTPAPIEX return codes to IOTHUB_CLIENT_RESULT return codes:] */
+            if (HTTPAPIEX_result == HTTPAPIEX_OK)
+            {
+                result = IOTHUB_CLIENT_OK;
+            }
+            else if (HTTPAPIEX_result == HTTPAPIEX_INVALID_ARG)
+            {
+                result = IOTHUB_CLIENT_INVALID_ARG;
+                LogError("HTTPAPIEX_SetOption failed");
+            }
+            else
+            {
+                result = IOTHUB_CLIENT_ERROR;
+                LogError("HTTPAPIEX_SetOption failed");
+            }
+        }
+    }
+    return result;
+}
+
+static STRING_HANDLE IoTHubTransportHttp_GetHostname(TRANSPORT_LL_HANDLE handle)
+{
+    STRING_HANDLE result;
+    /*Codes_SRS_TRANSPORTMULTITHTTP_02_001: [ If handle is NULL then IoTHubTransportHttp_GetHostname shall fail and return NULL. ]*/
+    if (handle == NULL)
+    {
+        LogError("invalid parameter handle=%p", handle);
+        result = NULL;
+    }
+    /*Codes_SRS_TRANSPORTMULTITHTTP_02_002: [ Otherwise IoTHubTransportHttp_GetHostname shall return a non-NULL STRING_HANDLE containing the hostname. ]*/
+    else if ((result = STRING_clone(((HTTPTRANSPORT_HANDLE_DATA*)(handle))->hostName)) == NULL)
+    {
+        LogError("Cannot provide the target host name (STRING_clone failed).");
+    }
+
+    return result;
+}
+
+static int IoTHubTransportHttp_SetRetryPolicy(TRANSPORT_LL_HANDLE handle, IOTHUB_CLIENT_RETRY_POLICY retryPolicy, size_t retryTimeoutLimitInSeconds)
+{
+    int result;
+    (void)handle;
+    (void)retryPolicy;
+    (void)retryTimeoutLimitInSeconds;
+
+    /* Retry Policy is not currently not available for HTTP */
+
+    result = 0;
+    return result;
+}
+
+static int IotHubTransportHttp_Subscribe_InputQueue(IOTHUB_DEVICE_HANDLE handle)
+{
+    (void)handle;
+    LogError("HTTP does not support input queues");
+    return MU_FAILURE;
+}
+
+static void IotHubTransportHttp_Unsubscribe_InputQueue(IOTHUB_DEVICE_HANDLE handle)
+{
+    (void)handle;
+    LogError("HTTP does not support input queues");
+}
+
+int IoTHubTransportHttp_SetCallbackContext(TRANSPORT_LL_HANDLE handle, void* ctx)
+{
+    int result;
+    if (handle == NULL)
+    {
+        LogError("Invalid parameter specified handle: %p", handle);
+        result = MU_FAILURE;
+    }
+    else
+    {
+        HTTPTRANSPORT_HANDLE_DATA* handleData = (HTTPTRANSPORT_HANDLE_DATA*)handle;
+        handleData->transport_ctx = ctx;
+        result = 0;
+    }
+    return result;
+}
+
+static int IoTHubTransportHttp_GetSupportedPlatformInfo(TRANSPORT_LL_HANDLE handle, PLATFORM_INFO_OPTION* info)
+{
+    int result;
+    if (handle == NULL)
+    {
+        result = MU_FAILURE;
+    }
+    else
+    {
+        *info = PLATFORM_INFO_OPTION_DEFAULT;
+        result = 0;
+    }
+
+    return result;
+}
+
+/*Codes_SRS_TRANSPORTMULTITHTTP_17_125: [This function shall return a pointer to a structure of type TRANSPORT_PROVIDER having the following values for its fields:] */
+static TRANSPORT_PROVIDER thisTransportProvider =
+{
+    IoTHubTransportHttp_SendMessageDisposition,     /*pfIotHubTransport_SendMessageDisposition IoTHubTransport_SendMessageDisposition;*/
+    IoTHubTransportHttp_Subscribe_DeviceMethod,     /*pfIoTHubTransport_Subscribe_DeviceMethod IoTHubTransport_Subscribe_DeviceMethod;*/
+    IoTHubTransportHttp_Unsubscribe_DeviceMethod,   /*pfIoTHubTransport_Unsubscribe_DeviceMethod IoTHubTransport_Unsubscribe_DeviceMethod;*/
+    IoTHubTransportHttp_DeviceMethod_Response,      /*pfIoTHubTransport_DeviceMethod_Response IoTHubTransport_DeviceMethod_Response;*/
+    IoTHubTransportHttp_Subscribe_DeviceTwin,       /*pfIoTHubTransport_Subscribe_DeviceTwin IoTHubTransport_Subscribe_DeviceTwin;*/
+    IoTHubTransportHttp_Unsubscribe_DeviceTwin,     /*pfIoTHubTransport_Unsubscribe_DeviceTwin IoTHubTransport_Unsubscribe_DeviceTwin;*/
+    IoTHubTransportHttp_ProcessItem,                /*pfIoTHubTransport_ProcessItem IoTHubTransport_ProcessItem;*/
+    IoTHubTransportHttp_GetHostname,                /*pfIoTHubTransport_GetHostname IoTHubTransport_GetHostname;*/
+    IoTHubTransportHttp_SetOption,                  /*pfIoTHubTransport_SetOption IoTHubTransport_SetOption;*/
+    IoTHubTransportHttp_Create,                     /*pfIoTHubTransport_Create IoTHubTransport_Create;*/
+    IoTHubTransportHttp_Destroy,                    /*pfIoTHubTransport_Destroy IoTHubTransport_Destroy;*/
+    IoTHubTransportHttp_Register,                   /*pfIotHubTransport_Register IoTHubTransport_Register;*/
+    IoTHubTransportHttp_Unregister,                 /*pfIotHubTransport_Unregister IoTHubTransport_Unegister;*/
+    IoTHubTransportHttp_Subscribe,                  /*pfIoTHubTransport_Subscribe IoTHubTransport_Subscribe;*/
+    IoTHubTransportHttp_Unsubscribe,                /*pfIoTHubTransport_Unsubscribe IoTHubTransport_Unsubscribe;*/
+    IoTHubTransportHttp_DoWork,                     /*pfIoTHubTransport_DoWork IoTHubTransport_DoWork;*/
+    IoTHubTransportHttp_SetRetryPolicy,             /*pfIoTHubTransport_DoWork IoTHubTransport_SetRetryPolicy;*/
+    IoTHubTransportHttp_GetSendStatus,              /*pfIoTHubTransport_GetSendStatus IoTHubTransport_GetSendStatus;*/
+    IotHubTransportHttp_Subscribe_InputQueue,       /*pfIoTHubTransport_Subscribe_InputQueue IoTHubTransport_Subscribe_InputQueue; */
+    IotHubTransportHttp_Unsubscribe_InputQueue,     /*pfIoTHubTransport_Unsubscribe_InputQueue IoTHubTransport_Unsubscribe_InputQueue; */
+    IoTHubTransportHttp_SetCallbackContext,         /*pfIoTHubTransport_SetTransportCallbacks IoTHubTransport_SetTransportCallbacks; */
+    IoTHubTransportHttp_GetTwinAsync,               /*pfIoTHubTransport_GetTwinAsync IoTHubTransport_GetTwinAsync;*/
+    IoTHubTransportHttp_GetSupportedPlatformInfo      /*pfIoTHubTransport_GetSupportedPlatformInfo IoTHubTransport_GetSupportedPlatformInfo;*/
+};
+
+const TRANSPORT_PROVIDER* HTTP_Protocol(void)
+{
+    return &thisTransportProvider;
+}
Index: azure_iot_hub_f767zi/trunk/azure_iot_sdk/iothub_client/src/iothubtransportmqtt.c
===================================================================
--- azure_iot_hub_f767zi/trunk/azure_iot_sdk/iothub_client/src/iothubtransportmqtt.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/azure_iot_sdk/iothub_client/src/iothubtransportmqtt.c	(revision 457)
@@ -0,0 +1,213 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+#include <stdlib.h>
+#include "iothubtransportmqtt.h"
+#include "azure_c_shared_utility/xio.h"
+#include "azure_c_shared_utility/tlsio.h"
+#include "azure_c_shared_utility/platform.h"
+#include "internal/iothubtransport_mqtt_common.h"
+#include "azure_c_shared_utility/xlogging.h"
+
+static XIO_HANDLE getIoTransportProvider(const char* fully_qualified_name, const MQTT_TRANSPORT_PROXY_OPTIONS* mqtt_transport_proxy_options)
+{
+    XIO_HANDLE result;
+
+    /* Codes_SRS_IOTHUB_MQTT_TRANSPORT_01_001: [ `getIoTransportProvider` shall obtain the TLS IO interface handle by calling `platform_get_default_tlsio`. ]*/
+    const IO_INTERFACE_DESCRIPTION* io_interface_description = platform_get_default_tlsio();
+    (void)mqtt_transport_proxy_options;
+
+    if (io_interface_description == NULL)
+    {
+        /* Codes_SRS_IOTHUB_MQTT_TRANSPORT_07_013: [ If `platform_get_default_tlsio` returns NULL, `getIoTransportProvider` shall return NULL. ] */
+        LogError("Failure constructing the provider interface");
+        result = NULL;
+    }
+    else
+    {
+        /* Codes_SRS_IOTHUB_MQTT_TRANSPORT_01_002: [ The TLS IO parameters shall be a `TLSIO_CONFIG` structure filled as below: ]*/
+        TLSIO_CONFIG tls_io_config;
+
+        /* Codes_SRS_IOTHUB_MQTT_TRANSPORT_01_003: [ - `hostname` shall be set to `fully_qualified_name`. ]*/
+        tls_io_config.hostname = fully_qualified_name;
+        /* Codes_SRS_IOTHUB_MQTT_TRANSPORT_01_004: [ - `port` shall be set to 8883. ]*/
+        tls_io_config.port = 8883;
+        /* Codes_SRS_IOTHUB_MQTT_TRANSPORT_01_005: [ - `underlying_io_interface` shall be set to NULL. ]*/
+        tls_io_config.underlying_io_interface = NULL;
+        /* Codes_SRS_IOTHUB_MQTT_TRANSPORT_01_006: [ - `underlying_io_parameters` shall be set to NULL. ]*/
+        tls_io_config.underlying_io_parameters = NULL;
+
+        /* Codes_SRS_IOTHUB_MQTT_TRANSPORT_07_012: [ `getIoTransportProvider` shall return the `XIO_HANDLE` returned by `xio_create`. ] */
+        result = xio_create(io_interface_description, &tls_io_config);
+    }
+    return result;
+}
+
+static TRANSPORT_LL_HANDLE IoTHubTransportMqtt_Create(const IOTHUBTRANSPORT_CONFIG* config, TRANSPORT_CALLBACKS_INFO* cb_info, void* ctx)
+{
+    /* Codes_SRS_IOTHUB_MQTT_TRANSPORT_07_001: [IoTHubTransportMqtt_Create shall create a TRANSPORT_LL_HANDLE by calling into the IoTHubMqttAbstract_Create function.] */
+    return IoTHubTransport_MQTT_Common_Create(config, getIoTransportProvider, cb_info, ctx);
+}
+
+static void IoTHubTransportMqtt_Destroy(TRANSPORT_LL_HANDLE handle)
+{
+    /* Codes_SRS_IOTHUB_MQTT_TRANSPORT_07_002: [ IoTHubTransportMqtt_Destroy shall destroy the TRANSPORT_LL_HANDLE by calling into the IoTHubMqttAbstract_Destroy function. ] */
+    IoTHubTransport_MQTT_Common_Destroy(handle);
+}
+
+static int IoTHubTransportMqtt_Subscribe(IOTHUB_DEVICE_HANDLE handle)
+{
+    /* Codes_SRS_IOTHUB_MQTT_TRANSPORT_07_005: [ IoTHubTransportMqtt_Subscribe shall subscribe the TRANSPORT_LL_HANDLE by calling into the IoTHubMqttAbstract_Subscribe function. ] */
+    return IoTHubTransport_MQTT_Common_Subscribe(handle);
+}
+
+static void IoTHubTransportMqtt_Unsubscribe(IOTHUB_DEVICE_HANDLE handle)
+{
+    /* Codes_SRS_IOTHUB_MQTT_TRANSPORT_07_006: [ IoTHubTransportMqtt_Unsubscribe shall unsubscribe the TRANSPORT_LL_HANDLE by calling into the IoTHubMqttAbstract_Unsubscribe function. ] */
+    IoTHubTransport_MQTT_Common_Unsubscribe(handle);
+}
+
+/* Codes_SRS_IOTHUB_MQTT_TRANSPORT_07_026: [ IoTHubTransportMqtt_Subscribe_DeviceMethod shall subscribe the TRANSPORT_LL_HANDLE by calling into the IoTHubMqttAbstract_Subscribe_DeviceMethod function. ] */
+static int IoTHubTransportMqtt_Subscribe_DeviceMethod(IOTHUB_DEVICE_HANDLE handle)
+{
+    return IoTHubTransport_MQTT_Common_Subscribe_DeviceMethod(handle);
+}
+
+/* Codes_SRS_IOTHUB_MQTT_TRANSPORT_07_027: [ IoTHubTransportMqtt_Unsubscribe_DeviceMethod shall call into the IoTHubMqttAbstract_Unsubscribe_DeviceMethod function. ] */
+static void IoTHubTransportMqtt_Unsubscribe_DeviceMethod(IOTHUB_DEVICE_HANDLE handle)
+{
+    IoTHubTransport_MQTT_Common_Unsubscribe_DeviceMethod(handle);
+}
+
+/* Codes_SRS_IOTHUB_MQTT_TRANSPORT_07_025: [ IoTHubTransportMqtt_Subscribe_DeviceTwin shall call into the IoTHubMqttAbstract_Subscribe_DeviceTwin function. ] */
+static int IoTHubTransportMqtt_Subscribe_DeviceTwin(IOTHUB_DEVICE_HANDLE handle)
+{
+    return IoTHubTransport_MQTT_Common_Subscribe_DeviceTwin(handle);
+}
+
+/* Codes_SRS_IOTHUB_MQTT_TRANSPORT_07_024: [ IoTHubTransportMqtt_Unsubscribe_DeviceTwin shall shall call into the IoTHubMqttAbstract_Unsubscribe_DeviceTwin function. ] */
+static void IoTHubTransportMqtt_Unsubscribe_DeviceTwin(IOTHUB_DEVICE_HANDLE handle)
+{
+    IoTHubTransport_MQTT_Common_Unsubscribe_DeviceTwin(handle);
+}
+
+static IOTHUB_CLIENT_RESULT IoTHubTransportMqtt_GetTwinAsync(IOTHUB_DEVICE_HANDLE handle, IOTHUB_CLIENT_DEVICE_TWIN_CALLBACK completionCallback, void* callbackContext)
+{
+    // Codes_SRS_IOTHUB_MQTT_TRANSPORT_09_001: [ IoTHubTransportMqtt_GetTwinAsync shall call into the IoTHubTransport_MQTT_Common_GetTwinAsync function. ]
+    return IoTHubTransport_MQTT_Common_GetTwinAsync(handle, completionCallback, callbackContext);
+}
+
+/* Codes_SRS_IOTHUB_MQTT_TRANSPORT_07_023: [ IoTHubTransportMqtt_DeviceMethod_Response shall call into the IoTHubMqttAbstract_DeviceMethod_Response function. ] */
+static int IoTHubTransportMqtt_DeviceMethod_Response(IOTHUB_DEVICE_HANDLE handle, METHOD_HANDLE methodId, const unsigned char* response, size_t response_size, int status_response)
+{
+    return IoTHubTransport_MQTT_Common_DeviceMethod_Response(handle, methodId, response, response_size, status_response);
+}
+
+/* Codes_SRS_IOTHUB_MQTT_TRANSPORT_10_001: [IoTHubTransportMqtt_SendMessageDisposition shall send the message disposition by calling into the IoTHubMqttAbstract_SendMessageDisposition function.] */
+static IOTHUB_CLIENT_RESULT IoTHubTransportMqtt_SendMessageDisposition(MESSAGE_CALLBACK_INFO* message_data, IOTHUBMESSAGE_DISPOSITION_RESULT disposition)
+{
+    return IoTHubTransport_MQTT_Common_SendMessageDisposition(message_data, disposition);
+}
+
+static IOTHUB_PROCESS_ITEM_RESULT IoTHubTransportMqtt_ProcessItem(TRANSPORT_LL_HANDLE handle, IOTHUB_IDENTITY_TYPE item_type, IOTHUB_IDENTITY_INFO* iothub_item)
+{
+    return IoTHubTransport_MQTT_Common_ProcessItem(handle, item_type, iothub_item);
+}
+
+/* Codes_SRS_IOTHUB_MQTT_TRANSPORT_07_054: [ IoTHubTransportMqtt_DoWork shall subscribe to the Notification and get_state Topics if they are defined. ] */
+static void IoTHubTransportMqtt_DoWork(TRANSPORT_LL_HANDLE handle)
+{
+    /* Codes_SRS_IOTHUB_MQTT_TRANSPORT_07_007: [ IoTHubTransportMqtt_DoWork shall call into the IoTHubMqttAbstract_DoWork function. ] */
+    IoTHubTransport_MQTT_Common_DoWork(handle);
+}
+
+static int IoTHubTransportMqtt_SetRetryPolicy(TRANSPORT_LL_HANDLE handle, IOTHUB_CLIENT_RETRY_POLICY retryPolicy, size_t retryTimeoutLimitInSeconds)
+{
+    /* Codes_SRS_IOTHUB_MQTT_TRANSPORT_25_012: [** IoTHubTransportMqtt_SetRetryPolicy shall call into the IoTHubMqttAbstract_SetRetryPolicy function. ] */
+    return IoTHubTransport_MQTT_Common_SetRetryPolicy(handle, retryPolicy, retryTimeoutLimitInSeconds);
+}
+
+static IOTHUB_CLIENT_RESULT IoTHubTransportMqtt_GetSendStatus(IOTHUB_DEVICE_HANDLE handle, IOTHUB_CLIENT_STATUS *iotHubClientStatus)
+{
+    /* Codes_SRS_IOTHUB_MQTT_TRANSPORT_07_008: [ IoTHubTransportMqtt_GetSendStatus shall get the send status by calling into the IoTHubMqttAbstract_GetSendStatus function. ] */
+    return IoTHubTransport_MQTT_Common_GetSendStatus(handle, iotHubClientStatus);
+}
+
+static IOTHUB_CLIENT_RESULT IoTHubTransportMqtt_SetOption(TRANSPORT_LL_HANDLE handle, const char* option, const void* value)
+{
+    /* Codes_SRS_IOTHUB_MQTT_TRANSPORT_07_009: [ IoTHubTransportMqtt_SetOption shall set the options by calling into the IoTHubMqttAbstract_SetOption function. ] */
+    return IoTHubTransport_MQTT_Common_SetOption(handle, option, value);
+}
+
+static IOTHUB_DEVICE_HANDLE IoTHubTransportMqtt_Register(TRANSPORT_LL_HANDLE handle, const IOTHUB_DEVICE_CONFIG* device, PDLIST_ENTRY waitingToSend)
+{
+    /* Codes_SRS_IOTHUB_MQTT_TRANSPORT_07_003: [ IoTHubTransportMqtt_Register shall register the TRANSPORT_LL_HANDLE by calling into the IoTHubMqttAbstract_Register function. ] */
+    return IoTHubTransport_MQTT_Common_Register(handle, device, waitingToSend);
+}
+
+static void IoTHubTransportMqtt_Unregister(IOTHUB_DEVICE_HANDLE deviceHandle)
+{
+    /* Codes_SRS_IOTHUB_MQTT_TRANSPORT_07_004: [ IoTHubTransportMqtt_Unregister shall register the TRANSPORT_LL_HANDLE by calling into the IoTHubMqttAbstract_Unregister function. ] */
+    IoTHubTransport_MQTT_Common_Unregister(deviceHandle);
+}
+
+static STRING_HANDLE IoTHubTransportMqtt_GetHostname(TRANSPORT_LL_HANDLE handle)
+{
+    /* Codes_SRS_IOTHUB_MQTT_TRANSPORT_07_010: [ IoTHubTransportMqtt_GetHostname shall get the hostname by calling into the IoTHubMqttAbstract_GetHostname function. ] */
+    return IoTHubTransport_MQTT_Common_GetHostname(handle);
+}
+
+static int IotHubTransportMqtt_Subscribe_InputQueue(IOTHUB_DEVICE_HANDLE handle)
+{
+    /* Codes_SRS_IOTHUB_MQTT_TRANSPORT_31_14: [ IoTHubTransportMqtt_Subscribe shall subscribe the TRANSPORT_LL_HANDLE by calling into IoTHubTransport_MQTT_Common_Subscribe_InputQueue. ] */
+    return IoTHubTransport_MQTT_Common_Subscribe_InputQueue(handle);
+}
+
+static void IotHubTransportMqtt_Unsubscribe_InputQueue(IOTHUB_DEVICE_HANDLE handle)
+{
+    /* Codes_SRS_IOTHUBTRANSPORTAMQP_31_015: [IotHubTransportMQTT_Unsubscribe_InputQueue shall unsubscribe by calling into IoTHubTransport_MQTT_Common_Unsubscribe_InputQueue. ] */
+    IoTHubTransport_MQTT_Common_Unsubscribe_InputQueue(handle);
+}
+
+static int IotHubTransportMqtt_SetCallbackContext(TRANSPORT_LL_HANDLE handle, void* ctx)
+{
+    return IoTHubTransport_MQTT_SetCallbackContext(handle, ctx);
+}
+
+static int IotHubTransportMqtt_GetSupportedPlatformInfo(TRANSPORT_LL_HANDLE handle, PLATFORM_INFO_OPTION* info)
+{
+    return IoTHubTransport_MQTT_GetSupportedPlatformInfo(handle, info);
+}
+
+static TRANSPORT_PROVIDER myfunc =
+{
+    IoTHubTransportMqtt_SendMessageDisposition,     /*pfIotHubTransport_SendMessageDisposition IoTHubTransport_SendMessageDisposition;*/
+    IoTHubTransportMqtt_Subscribe_DeviceMethod,     /*pfIoTHubTransport_Subscribe_DeviceMethod IoTHubTransport_Subscribe_DeviceMethod;*/
+    IoTHubTransportMqtt_Unsubscribe_DeviceMethod,   /*pfIoTHubTransport_Unsubscribe_DeviceMethod IoTHubTransport_Unsubscribe_DeviceMethod;*/
+    IoTHubTransportMqtt_DeviceMethod_Response,      /*pfIoTHubTransport_DeviceMethod_Response IoTHubTransport_DeviceMethod_Response;*/
+    IoTHubTransportMqtt_Subscribe_DeviceTwin,       /*pfIoTHubTransport_Subscribe_DeviceTwin IoTHubTransport_Subscribe_DeviceTwin;*/
+    IoTHubTransportMqtt_Unsubscribe_DeviceTwin,     /*pfIoTHubTransport_Unsubscribe_DeviceTwin IoTHubTransport_Unsubscribe_DeviceTwin;*/
+    IoTHubTransportMqtt_ProcessItem,                /*pfIoTHubTransport_ProcessItem IoTHubTransport_ProcessItem;*/
+    IoTHubTransportMqtt_GetHostname,                /*pfIoTHubTransport_GetHostname IoTHubTransport_GetHostname;*/
+    IoTHubTransportMqtt_SetOption,                  /*pfIoTHubTransport_SetOption IoTHubTransport_SetOption;*/
+    IoTHubTransportMqtt_Create,                     /*pfIoTHubTransport_Create IoTHubTransport_Create;*/
+    IoTHubTransportMqtt_Destroy,                    /*pfIoTHubTransport_Destroy IoTHubTransport_Destroy;*/
+    IoTHubTransportMqtt_Register,                   /*pfIotHubTransport_Register IoTHubTransport_Register;*/
+    IoTHubTransportMqtt_Unregister,                 /*pfIotHubTransport_Unregister IoTHubTransport_Unegister;*/
+    IoTHubTransportMqtt_Subscribe,                  /*pfIoTHubTransport_Subscribe IoTHubTransport_Subscribe;*/
+    IoTHubTransportMqtt_Unsubscribe,                /*pfIoTHubTransport_Unsubscribe IoTHubTransport_Unsubscribe;*/
+    IoTHubTransportMqtt_DoWork,                     /*pfIoTHubTransport_DoWork IoTHubTransport_DoWork;*/
+    IoTHubTransportMqtt_SetRetryPolicy,             /*pfIoTHubTransport_DoWork IoTHubTransport_SetRetryPolicy;*/
+    IoTHubTransportMqtt_GetSendStatus,              /*pfIoTHubTransport_GetSendStatus IoTHubTransport_GetSendStatus;*/
+    IotHubTransportMqtt_Subscribe_InputQueue,       /*pfIoTHubTransport_Subscribe_InputQueue IoTHubTransport_Subscribe_InputQueue; */
+    IotHubTransportMqtt_Unsubscribe_InputQueue,     /*pfIoTHubTransport_Unsubscribe_InputQueue IoTHubTransport_Unsubscribe_InputQueue; */
+    IotHubTransportMqtt_SetCallbackContext,         /*pfIoTHubTransport_SetCallbackContext IoTHubTransport_SetCallbackContext; */
+    IoTHubTransportMqtt_GetTwinAsync,               /*pfIoTHubTransport_GetTwinAsync IoTHubTransport_GetTwinAsync;*/
+    IotHubTransportMqtt_GetSupportedPlatformInfo      /*pfIoTHubTransport_GetSupportedPlatformInfo IoTHubTransport_GetSupportedPlatformInfo;*/
+};
+
+/* Codes_SRS_IOTHUB_MQTT_TRANSPORT_07_022: [This function shall return a pointer to a structure of type TRANSPORT_PROVIDER */
+extern const TRANSPORT_PROVIDER* MQTT_Protocol(void)
+{
+    return &myfunc;
+}
Index: azure_iot_hub_f767zi/trunk/azure_iot_sdk/iothub_client/src/iothubtransportmqtt_websockets.c
===================================================================
--- azure_iot_hub_f767zi/trunk/azure_iot_sdk/iothub_client/src/iothubtransportmqtt_websockets.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/azure_iot_sdk/iothub_client/src/iothubtransportmqtt_websockets.c	(revision 457)
@@ -0,0 +1,282 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+#include <stdlib.h>
+#include "azure_c_shared_utility/xio.h"
+#include "azure_c_shared_utility/wsio.h"
+#include "azure_c_shared_utility/tlsio.h"
+#include "azure_c_shared_utility/platform.h"
+#include "azure_c_shared_utility/http_proxy_io.h"
+#include "iothubtransportmqtt_websockets.h"
+#include "internal/iothubtransport_mqtt_common.h"
+
+static XIO_HANDLE getWebSocketsIOTransport(const char* fully_qualified_name, const MQTT_TRANSPORT_PROXY_OPTIONS* mqtt_transport_proxy_options)
+{
+    XIO_HANDLE result;
+    /* Codes_SRS_IOTHUB_MQTT_WEBSOCKET_TRANSPORT_01_001: [ `getIoTransportProvider` shall obtain the WebSocket IO interface handle by calling `wsio_get_interface_description`. ]*/
+    const IO_INTERFACE_DESCRIPTION* io_interface_description = wsio_get_interface_description();
+    TLSIO_CONFIG tls_io_config;
+    HTTP_PROXY_IO_CONFIG http_proxy_io_config;
+
+    if (io_interface_description == NULL)
+    {
+        /* Codes_SRS_IOTHUB_MQTT_WEBSOCKET_TRANSPORT_07_013: [ If `wsio_get_interface_description` returns NULL `getIoTransportProvider` shall return NULL. ] */
+        LogError("Failure constructing the provider interface");
+        result = NULL;
+    }
+    else
+    {
+        WSIO_CONFIG ws_io_config;
+
+        /* Codes_SRS_IOTHUB_MQTT_WEBSOCKET_TRANSPORT_01_003: [ - `hostname` shall be set to `fully_qualified_name`. ]*/
+        ws_io_config.hostname = fully_qualified_name;
+        /* Codes_SRS_IOTHUB_MQTT_WEBSOCKET_TRANSPORT_01_004: [ - `port` shall be set to 443. ]*/
+        ws_io_config.port = 443;
+        /* Codes_SRS_IOTHUB_MQTT_WEBSOCKET_TRANSPORT_01_005: [ - `protocol` shall be set to `MQTT`. ]*/
+        ws_io_config.protocol = "MQTT";
+        /* Codes_SRS_IOTHUB_MQTT_WEBSOCKET_TRANSPORT_01_006: [ - `resource_name` shall be set to `/$iothub/websocket`. ]*/
+        ws_io_config.resource_name = "/$iothub/websocket";
+        /* Codes_SRS_IOTHUB_MQTT_WEBSOCKET_TRANSPORT_01_007: [ - `underlying_io_interface` shall be set to the TLS IO interface description. ]*/
+        /* Codes_SRS_IOTHUB_MQTT_WEBSOCKET_TRANSPORT_01_009: [ `getIoTransportProvider` shall obtain the TLS IO interface handle by calling `platform_get_default_tlsio`. ]*/
+        ws_io_config.underlying_io_interface = platform_get_default_tlsio();
+
+        /* Codes_SRS_IOTHUB_MQTT_WEBSOCKET_TRANSPORT_01_029: [ If `platform_get_default_tlsio` returns NULL, NULL shall be set in the WebSocket IO parameters structure for the interface description and parameters. ]*/
+        if (ws_io_config.underlying_io_interface == NULL)
+        {
+            ws_io_config.underlying_io_parameters = NULL;
+        }
+        else
+        {
+            /* Codes_SRS_IOTHUB_MQTT_WEBSOCKET_TRANSPORT_01_008: [ - `underlying_io_parameters` shall be set to the TLS IO arguments. ]*/
+            /* Codes_SRS_IOTHUB_MQTT_WEBSOCKET_TRANSPORT_01_010: [ The TLS IO parameters shall be a TLSIO_CONFIG structure filled as below: ]*/
+            ws_io_config.underlying_io_parameters = &tls_io_config;
+
+            /* Codes_SRS_IOTHUB_MQTT_WEBSOCKET_TRANSPORT_01_011: [ - `hostname` shall be set to `fully_qualified_name`. ]*/
+            tls_io_config.hostname = fully_qualified_name;
+            /* Codes_SRS_IOTHUB_MQTT_WEBSOCKET_TRANSPORT_01_012: [ - `port` shall be set to 443. ]*/
+            tls_io_config.port = 443;
+
+            if (mqtt_transport_proxy_options != NULL)
+            {
+                /* Codes_SRS_IOTHUB_MQTT_WEBSOCKET_TRANSPORT_01_015: [ - If `mqtt_transport_proxy_options` is not NULL, `underlying_io_interface` shall be set to the HTTP proxy IO interface description. ]*/
+                /* Codes_SRS_IOTHUB_MQTT_WEBSOCKET_TRANSPORT_01_022: [ `getIoTransportProvider` shall obtain the HTTP proxy IO interface handle by calling `http_proxy_io_get_interface_description`. ]*/
+                tls_io_config.underlying_io_interface = http_proxy_io_get_interface_description();
+
+                /* Codes_SRS_IOTHUB_MQTT_WEBSOCKET_TRANSPORT_01_028: [ If `http_proxy_io_get_interface_description` returns NULL, NULL shall be set in the TLS IO parameters structure for the interface description and parameters. ]*/
+                if (tls_io_config.underlying_io_interface == NULL)
+                {
+                    tls_io_config.underlying_io_parameters = NULL;
+                }
+                else
+                {
+                    /* Codes_SRS_IOTHUB_MQTT_WEBSOCKET_TRANSPORT_01_016: [ - If `mqtt_transport_proxy_options` is not NULL `underlying_io_parameters` shall be set to the HTTP proxy IO arguments. ]*/
+                    tls_io_config.underlying_io_parameters = &http_proxy_io_config;
+
+                    /* Codes_SRS_IOTHUB_MQTT_WEBSOCKET_TRANSPORT_01_023: [ The HTTP proxy IO arguments shall be an `HTTP_PROXY_IO_CONFIG` structure, filled as below: ]*/
+                    /* Codes_SRS_IOTHUB_MQTT_WEBSOCKET_TRANSPORT_01_026: [ - `proxy_hostname`, `proxy_port`, `username` and `password` shall be copied from the `mqtt_transport_proxy_options` argument. ]*/
+                    http_proxy_io_config.proxy_hostname = mqtt_transport_proxy_options->host_address;
+                    http_proxy_io_config.proxy_port = mqtt_transport_proxy_options->port;
+                    http_proxy_io_config.username = mqtt_transport_proxy_options->username;
+                    http_proxy_io_config.password = mqtt_transport_proxy_options->password;
+                    /* Codes_SRS_IOTHUB_MQTT_WEBSOCKET_TRANSPORT_01_024: [ - `hostname` shall be set to `fully_qualified_name`. ]*/
+                    http_proxy_io_config.hostname = fully_qualified_name;
+                    /* Codes_SRS_IOTHUB_MQTT_WEBSOCKET_TRANSPORT_01_025: [ - `port` shall be set to 443. ]*/
+                    http_proxy_io_config.port = 443;
+                }
+            }
+            else
+            {
+                /* Codes_SRS_IOTHUB_MQTT_WEBSOCKET_TRANSPORT_01_013: [ - If `mqtt_transport_proxy_options` is NULL, `underlying_io_interface` shall be set to NULL ]*/
+                tls_io_config.underlying_io_interface = NULL;
+                /* Codes_SRS_IOTHUB_MQTT_WEBSOCKET_TRANSPORT_01_014: [ - If `mqtt_transport_proxy_options` is NULL `underlying_io_parameters` shall be set to NULL. ]*/
+                tls_io_config.underlying_io_parameters = NULL;
+            }
+        }
+
+        /* Codes_SRS_IOTHUB_MQTT_WEBSOCKET_TRANSPORT_07_012: [ `getIoTransportProvider` shall return the `XIO_HANDLE` returned by `xio_create`. ] */
+        /* Codes_SRS_IOTHUB_MQTT_WEBSOCKET_TRANSPORT_01_002: [ `getIoTransportProvider` shall call `xio_create` while passing the WebSocket IO interface description to it and the WebSocket configuration as a WSIO_CONFIG structure, filled as below ]*/
+        result = xio_create(io_interface_description, &ws_io_config);
+    }
+    return result;
+}
+
+/* Codes_SRS_IOTHUB_MQTT_WEBSOCKET_TRANSPORT_07_001: [ IoTHubTransportMqtt_WS_Create shall create a TRANSPORT_LL_HANDLE by calling into the IoTHubMqttAbstract_Create function. ] */
+static TRANSPORT_LL_HANDLE IoTHubTransportMqtt_WS_Create(const IOTHUBTRANSPORT_CONFIG* config, TRANSPORT_CALLBACKS_INFO* cb_info, void* ctx)
+{
+    return IoTHubTransport_MQTT_Common_Create(config, getWebSocketsIOTransport, cb_info, ctx);
+}
+
+/* Codes_SRS_IOTHUB_MQTT_WEBSOCKET_TRANSPORT_07_002: [ IoTHubTransportMqtt_WS_Destroy shall destroy the TRANSPORT_LL_HANDLE by calling into the IoTHubMqttAbstract_Destroy function. ] */
+static void IoTHubTransportMqtt_WS_Destroy(TRANSPORT_LL_HANDLE handle)
+{
+    IoTHubTransport_MQTT_Common_Destroy(handle);
+}
+
+/* Codes_SRS_IOTHUB_MQTT_WEBSOCKET_TRANSPORT_07_005: [ IoTHubTransportMqtt_WS_Subscribe shall subscribe the TRANSPORT_LL_HANDLE by calling into the IoTHubMqttAbstract_Subscribe function. ] */
+static int IoTHubTransportMqtt_WS_Subscribe(IOTHUB_DEVICE_HANDLE handle)
+{
+    return IoTHubTransport_MQTT_Common_Subscribe(handle);
+}
+
+/* Codes_SRS_IOTHUB_MQTT_WEBSOCKET_TRANSPORT_07_006: [ IoTHubTransportMqtt_WS_Unsubscribe shall unsubscribe the TRANSPORT_LL_HANDLE by calling into the IoTHubMqttAbstract_Unsubscribe function. ] */
+static void IoTHubTransportMqtt_WS_Unsubscribe(IOTHUB_DEVICE_HANDLE handle)
+{
+    IoTHubTransport_MQTT_Common_Unsubscribe(handle);
+}
+
+/* Codes_SRS_IOTHUB_MQTT_WEBSOCKET_TRANSPORT_07_015: [ IoTHubTransportMqtt_WS_Subscribe_DeviceMethod shall call into the IoTHubTransport_MQTT_Common_Subscribe_DeviceMethod function ] */
+static int IoTHubTransportMqtt_WS_Subscribe_DeviceMethod(IOTHUB_DEVICE_HANDLE handle)
+{
+    return IoTHubTransport_MQTT_Common_Subscribe_DeviceMethod(handle);
+}
+
+/* Codes_SRS_IOTHUB_MQTT_WEBSOCKET_TRANSPORT_07_016: [ IoTHubTransportMqtt_WS_Unsubscribe_DeviceMethod shall call into the IoTHubTransport_MQTT_Common_Unsubscribe_DeviceMethod ] */
+static void IoTHubTransportMqtt_WS_Unsubscribe_DeviceMethod(IOTHUB_DEVICE_HANDLE handle)
+{
+    IoTHubTransport_MQTT_Common_Unsubscribe_DeviceMethod(handle);
+}
+
+static int IoTHubTransportMqtt_WS_DeviceMethod_Response(IOTHUB_DEVICE_HANDLE handle, METHOD_HANDLE methodId, const unsigned char* response, size_t response_size, int status_response)
+{
+    return IoTHubTransport_MQTT_Common_DeviceMethod_Response(handle, methodId, response, response_size, status_response);
+}
+
+/* Codes_SRS_IOTHUB_MQTT_WEBSOCKET_TRANSPORT_07_017: [ IoTHubTransportMqtt_WS_Subscribe_DeviceTwin shall call into the IoTHubTransport_MQTT_Common_Subscribe_DeviceTwin ] */
+static int IoTHubTransportMqtt_WS_Subscribe_DeviceTwin(IOTHUB_DEVICE_HANDLE handle)
+{
+    return IoTHubTransport_MQTT_Common_Subscribe_DeviceTwin(handle);
+}
+
+/* Codes_SRS_IOTHUB_MQTT_WEBSOCKET_TRANSPORT_07_018: [ IoTHubTransportMqtt_WS_Unsubscribe_DeviceTwin shall call into the IoTHubTransport_MQTT_Common_Unsubscribe_DeviceTwin ] */
+static void IoTHubTransportMqtt_WS_Unsubscribe_DeviceTwin(IOTHUB_DEVICE_HANDLE handle)
+{
+    IoTHubTransport_MQTT_Common_Unsubscribe_DeviceTwin(handle);
+}
+
+// Codes_SRS_IOTHUB_MQTT_WEBSOCKET_TRANSPORT_09_001: [ IoTHubTransportMqtt_WS_GetTwinAsync shall call into the IoTHubTransport_MQTT_Common_GetTwinAsync ]
+static IOTHUB_CLIENT_RESULT IoTHubTransportMqtt_WS_GetTwinAsync(IOTHUB_DEVICE_HANDLE handle, IOTHUB_CLIENT_DEVICE_TWIN_CALLBACK completionCallback, void* callbackContext)
+{
+    return IoTHubTransport_MQTT_Common_GetTwinAsync(handle, completionCallback, callbackContext);
+}
+
+/* Codes_SRS_IOTHUB_MQTT_WEBSOCKET_TRANSPORT_07_014: [ IoTHubTransportMqtt_WS_ProcessItem shall call into the IoTHubTransport_MQTT_Common_DoWork function ] */
+static IOTHUB_PROCESS_ITEM_RESULT IoTHubTransportMqtt_WS_ProcessItem(TRANSPORT_LL_HANDLE handle, IOTHUB_IDENTITY_TYPE item_type, IOTHUB_IDENTITY_INFO* iothub_item)
+{
+    return IoTHubTransport_MQTT_Common_ProcessItem(handle, item_type, iothub_item);
+}
+
+/* Codes_SRS_IOTHUB_MQTT_WEBSOCKET_TRANSPORT_07_007: [ IoTHubTransportMqtt_WS_DoWork shall call into the IoTHubMqttAbstract_DoWork function. ] */
+static void IoTHubTransportMqtt_WS_DoWork(TRANSPORT_LL_HANDLE handle)
+{
+    IoTHubTransport_MQTT_Common_DoWork(handle);
+}
+
+/* Codes_SRS_IOTHUB_MQTT_WEBSOCKET_TRANSPORT_07_008: [ IoTHubTransportMqtt_WS_GetSendStatus shall get the send status by calling into the IoTHubMqttAbstract_GetSendStatus function. ] */
+static IOTHUB_CLIENT_RESULT IoTHubTransportMqtt_WS_GetSendStatus(IOTHUB_DEVICE_HANDLE handle, IOTHUB_CLIENT_STATUS *iotHubClientStatus)
+{
+    return IoTHubTransport_MQTT_Common_GetSendStatus(handle, iotHubClientStatus);
+}
+
+/* Codes_SRS_IOTHUB_MQTT_WEBSOCKET_TRANSPORT_07_009: [ IoTHubTransportMqtt_WS_SetOption shall set the options by calling into the IoTHubMqttAbstract_SetOption function. ] */
+static IOTHUB_CLIENT_RESULT IoTHubTransportMqtt_WS_SetOption(TRANSPORT_LL_HANDLE handle, const char* option, const void* value)
+{
+    return IoTHubTransport_MQTT_Common_SetOption(handle, option, value);
+}
+
+/* Codes_SRS_IOTHUB_MQTT_WEBSOCKET_TRANSPORT_07_003: [ IoTHubTransportMqtt_WS_Register shall register the TRANSPORT_LL_HANDLE by calling into the IoTHubMqttAbstract_Register function. ]*/
+static IOTHUB_DEVICE_HANDLE IoTHubTransportMqtt_WS_Register(TRANSPORT_LL_HANDLE handle, const IOTHUB_DEVICE_CONFIG* device, PDLIST_ENTRY waitingToSend)
+{
+    return IoTHubTransport_MQTT_Common_Register(handle, device, waitingToSend);
+}
+
+/* Codes_SRS_IOTHUB_MQTT_WEBSOCKET_TRANSPORT_07_004: [ IoTHubTransportMqtt_WS_Unregister shall register the TRANSPORT_LL_HANDLE by calling into the IoTHubMqttAbstract_Unregister function. ] */
+static void IoTHubTransportMqtt_WS_Unregister(IOTHUB_DEVICE_HANDLE deviceHandle)
+{
+    IoTHubTransport_MQTT_Common_Unregister(deviceHandle);
+}
+
+/* Codes_SRS_IOTHUB_MQTT_WEBSOCKET_TRANSPORT_07_010: [ IoTHubTransportMqtt_WS_GetHostname shall get the hostname by calling into the IoTHubMqttAbstract_GetHostname function. ] */
+static STRING_HANDLE IoTHubTransportMqtt_WS_GetHostname(TRANSPORT_LL_HANDLE handle)
+{
+    return IoTHubTransport_MQTT_Common_GetHostname(handle);
+}
+
+static int IoTHubTransportMqtt_WS_SetRetryPolicy(TRANSPORT_LL_HANDLE handle, IOTHUB_CLIENT_RETRY_POLICY retryPolicy, size_t retryTimeoutLimitinSeconds)
+{
+    /* Codes_SRS_IOTHUB_MQTT_WEBSOCKET_TRANSPORT_25_012: [** IoTHubTransportMqtt_WS_SetRetryPolicy shall call into the IoTHubMqttAbstract_SetRetryPolicy function.]*/
+    return IoTHubTransport_MQTT_Common_SetRetryPolicy(handle, retryPolicy, retryTimeoutLimitinSeconds);
+}
+
+static IOTHUB_CLIENT_RESULT IoTHubTransportMqtt_WS_SendMessageDisposition(MESSAGE_CALLBACK_INFO* message_data, IOTHUBMESSAGE_DISPOSITION_RESULT disposition)
+{
+    /* Codes_SRS_IOTHUB_MQTT_WEBSOCKET_TRANSPORT_10_001: [IoTHubTransportMqtt_WS_SendMessageDisposition shall send the message disposition by calling into the IoTHubTransport_MQTT_Common_SendMessageDisposition()]*/
+    return IoTHubTransport_MQTT_Common_SendMessageDisposition(message_data, disposition);
+}
+
+static int IoTHubTransportMqtt_WS_Subscribe_InputQueue(IOTHUB_DEVICE_HANDLE handle)
+{
+    (void)handle;
+    LogError("IoTHubTransportMqtt_WS_Subscribe_InputQueue not implemented\n");
+    return MU_FAILURE;
+}
+
+static void IoTHubTransportMqtt_WS_Unsubscribe_InputQueue(IOTHUB_DEVICE_HANDLE handle)
+{
+    LogError("IoTHubTransportMqtt_WS_Unsubscribe_InputQueue not implemented\n");
+    (void)handle;
+}
+
+static int IotHubTransportMqtt_WS_SetCallbackContext(TRANSPORT_LL_HANDLE handle, void* ctx)
+{
+    return IoTHubTransport_MQTT_SetCallbackContext(handle, ctx);
+}
+
+static int IotHubTransportMqtt_WS_GetSupportedPlatformInfo(TRANSPORT_LL_HANDLE handle, PLATFORM_INFO_OPTION* info)
+{
+    return IoTHubTransport_MQTT_GetSupportedPlatformInfo(handle, info);
+}
+
+/* Codes_SRS_IOTHUB_MQTT_WEBSOCKET_TRANSPORT_07_011: [ This function shall return a pointer to a structure of type TRANSPORT_PROVIDER having the following values for its fields:
+IoTHubTransport_SendMessageDisposition = IoTHubTransport_WS_SendMessageDisposition
+IoTHubTransport_Subscribe_DeviceMethod = IoTHubTransport_WS_Subscribe_DeviceMethod
+IoTHubTransport_Unsubscribe_DeviceMethod IoTHubTransport_WS_Unsubscribe_DeviceMethod
+IoTHubTransport_Subscribe_DeviceTwin IoTHubTransport_WS_Subscribe_DeviceTwin
+IoTHubTransport_Unsubscribe_DeviceTwin IoTHubTransport_WS_Unsubscribe_DeviceTwin
+IoTHubTransport_GetHostname = IoTHubTransportMqtt_WS_GetHostname
+IoTHubTransport_Create = IoTHubTransportMqtt_WS_Create
+IoTHubTransport_Destroy = IoTHubTransportMqtt_WS_Destroy
+IoTHubTransport_Subscribe = IoTHubTransportMqtt_WS_Subscribe
+IoTHubTransport_Unsubscribe = IoTHubTransportMqtt_WS_Unsubscribe
+IoTHubTransport_DoWork = IoTHubTransportMqtt_WS_DoWork
+IoTHubTransport_SetOption = IoTHubTransportMqtt_WS_SetOption 
+IoTHubTransport_GetSupportedPlatformInfo = IoTHubTransportMqtt_WS_GetSupportedPlatformInfo ] */
+static TRANSPORT_PROVIDER thisTransportProvider_WebSocketsOverTls = {
+    IoTHubTransportMqtt_WS_SendMessageDisposition,
+    IoTHubTransportMqtt_WS_Subscribe_DeviceMethod,
+    IoTHubTransportMqtt_WS_Unsubscribe_DeviceMethod,
+    IoTHubTransportMqtt_WS_DeviceMethod_Response,
+    IoTHubTransportMqtt_WS_Subscribe_DeviceTwin,
+    IoTHubTransportMqtt_WS_Unsubscribe_DeviceTwin,
+    IoTHubTransportMqtt_WS_ProcessItem,
+    IoTHubTransportMqtt_WS_GetHostname,
+    IoTHubTransportMqtt_WS_SetOption,
+    IoTHubTransportMqtt_WS_Create,
+    IoTHubTransportMqtt_WS_Destroy,
+    IoTHubTransportMqtt_WS_Register,
+    IoTHubTransportMqtt_WS_Unregister,
+    IoTHubTransportMqtt_WS_Subscribe,
+    IoTHubTransportMqtt_WS_Unsubscribe,
+    IoTHubTransportMqtt_WS_DoWork,
+    IoTHubTransportMqtt_WS_SetRetryPolicy,
+    IoTHubTransportMqtt_WS_GetSendStatus,
+    IoTHubTransportMqtt_WS_Subscribe_InputQueue,
+    IoTHubTransportMqtt_WS_Unsubscribe_InputQueue,
+    IotHubTransportMqtt_WS_SetCallbackContext,
+    IoTHubTransportMqtt_WS_GetTwinAsync,
+    IotHubTransportMqtt_WS_GetSupportedPlatformInfo
+};
+
+const TRANSPORT_PROVIDER* MQTT_WebSocket_Protocol(void)
+{
+    return &thisTransportProvider_WebSocketsOverTls;
+}
Index: azure_iot_hub_f767zi/trunk/azure_iot_sdk/iothub_client/src/version.c
===================================================================
--- azure_iot_hub_f767zi/trunk/azure_iot_sdk/iothub_client/src/version.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/azure_iot_sdk/iothub_client/src/version.c	(revision 457)
@@ -0,0 +1,10 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+#include "iothub_client_version.h"
+
+const char* IoTHubClient_GetVersionString(void)
+{
+    /*Codes_SRS_IOTHUBCLIENT_05_001: [IoTHubClient_GetVersionString shall return a pointer to a constant string which indicates the version of IoTHubClient API.]*/
+    return IOTHUB_SDK_VERSION;
+}
Index: azure_iot_hub_f767zi/trunk/azure_iot_sdk/provisioning_client/adapters/hsm_client_data.c
===================================================================
--- azure_iot_hub_f767zi/trunk/azure_iot_sdk/provisioning_client/adapters/hsm_client_data.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/azure_iot_sdk/provisioning_client/adapters/hsm_client_data.c	(revision 457)
@@ -0,0 +1,61 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+#include <stdlib.h>
+
+#include "azure_c_shared_utility/xlogging.h"
+#include "hsm_client_data.h"
+
+#if defined(HSM_TYPE_SAS_TOKEN)  || defined(HSM_AUTH_TYPE_CUSTOM)
+#include "hsm_client_tpm.h"
+#endif
+
+#if defined(HSM_TYPE_X509) || defined(HSM_AUTH_TYPE_CUSTOM)
+#include "hsm_client_riot.h"
+#endif
+
+#if defined(HSM_TYPE_SYMM_KEY) || defined(HSM_AUTH_TYPE_CUSTOM)
+#include "hsm_client_key.h"
+#endif
+
+int initialize_hsm_system()
+{
+    int result = 0;
+#if defined(HSM_TYPE_X509) || defined(HSM_AUTH_TYPE_CUSTOM)
+    // Initialize x509
+    if ((result == 0) && (hsm_client_x509_init() != 0))
+    {
+        LogError("Failure initializing x509 system");
+        result = __LINE__;
+    }
+#endif
+#if defined(HSM_TYPE_SAS_TOKEN)  || defined(HSM_AUTH_TYPE_CUSTOM)
+    if ((result == 0) && (hsm_client_tpm_init() != 0))
+    {
+        LogError("Failure initializing tpm system");
+        result = __LINE__;
+    }
+#endif
+#ifdef HSM_TYPE_HTTP_EDGE
+    if ((result == 0) && (hsm_client_http_edge_init() != 0))
+    {
+        LogError("Failure initializing http edge system");
+        result = __LINE__;
+    }
+#endif
+
+    return result;
+}
+
+void deinitialize_hsm_system()
+{
+#ifdef HSM_TYPE_HTTP_EDGE
+    hsm_client_http_edge_deinit();
+#endif
+#if defined(HSM_TYPE_X509) || defined(HSM_AUTH_TYPE_CUSTOM)
+    hsm_client_x509_deinit();
+#endif
+#if defined(HSM_TYPE_SAS_TOKEN)  || defined(HSM_AUTH_TYPE_CUSTOM)
+    hsm_client_tpm_deinit();
+#endif
+}
Index: azure_iot_hub_f767zi/trunk/azure_iot_sdk/provisioning_client/adapters/hsm_client_data.h
===================================================================
--- azure_iot_hub_f767zi/trunk/azure_iot_sdk/provisioning_client/adapters/hsm_client_data.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/azure_iot_sdk/provisioning_client/adapters/hsm_client_data.h	(revision 457)
@@ -0,0 +1,101 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+#ifndef HSM_CLIENT_DATA_H
+#define HSM_CLIENT_DATA_H
+
+#ifdef __cplusplus
+#include <cstddef>
+extern "C" {
+#else
+#include <stddef.h>
+#endif /* __cplusplus */
+
+typedef void* HSM_CLIENT_HANDLE;
+
+typedef HSM_CLIENT_HANDLE (*HSM_CLIENT_CREATE)();
+typedef void (*HSM_CLIENT_DESTROY)(HSM_CLIENT_HANDLE handle);
+
+// TPM
+typedef int (*HSM_CLIENT_ACTIVATE_IDENTITY_KEY)(HSM_CLIENT_HANDLE handle, const unsigned char* key, size_t key_len);
+typedef int (*HSM_CLIENT_GET_ENDORSEMENT_KEY)(HSM_CLIENT_HANDLE handle, unsigned char** key, size_t* key_len);
+typedef int (*HSM_CLIENT_GET_STORAGE_ROOT_KEY)(HSM_CLIENT_HANDLE handle, unsigned char** key, size_t* key_len);
+typedef int (*HSM_CLIENT_SIGN_WITH_IDENTITY)(HSM_CLIENT_HANDLE handle, const unsigned char* data, size_t data_len, unsigned char** key, size_t* key_len);
+
+// x509
+typedef char* (*HSM_CLIENT_GET_CERTIFICATE)(HSM_CLIENT_HANDLE handle);
+typedef char* (*HSM_CLIENT_GET_ALIAS_KEY)(HSM_CLIENT_HANDLE handle);
+typedef char* (*HSM_CLIENT_GET_COMMON_NAME)(HSM_CLIENT_HANDLE handle);
+
+// Edge
+typedef char* (*HSM_CLIENT_GET_TRUST_BUNDLE)(HSM_CLIENT_HANDLE handle);
+
+// Symmetrical Keys
+typedef char* (*HSM_CLIENT_GET_SYMMETRICAL_KEY)(HSM_CLIENT_HANDLE handle);
+typedef char* (*HSM_CLIENT_GET_REGISTRATION_NAME)(HSM_CLIENT_HANDLE handle);
+typedef int (*HSM_CLIENT_SET_SYMMETRICAL_KEY_INFO)(HSM_CLIENT_HANDLE handle, const char* reg_name, const char* symm_key);
+
+typedef struct HSM_CLIENT_TPM_INTERFACE_TAG
+{
+    HSM_CLIENT_CREATE hsm_client_tpm_create;
+    HSM_CLIENT_DESTROY hsm_client_tpm_destroy;
+
+    HSM_CLIENT_ACTIVATE_IDENTITY_KEY hsm_client_activate_identity_key;
+    HSM_CLIENT_GET_ENDORSEMENT_KEY hsm_client_get_ek;
+    HSM_CLIENT_GET_STORAGE_ROOT_KEY hsm_client_get_srk;
+    HSM_CLIENT_SIGN_WITH_IDENTITY hsm_client_sign_with_identity;
+} HSM_CLIENT_TPM_INTERFACE;
+
+typedef struct HSM_CLIENT_X509_INTERFACE_TAG
+{
+    HSM_CLIENT_CREATE hsm_client_x509_create;
+    HSM_CLIENT_DESTROY hsm_client_x509_destroy;
+
+    HSM_CLIENT_GET_CERTIFICATE hsm_client_get_cert;
+    HSM_CLIENT_GET_ALIAS_KEY hsm_client_get_key;
+    HSM_CLIENT_GET_COMMON_NAME hsm_client_get_common_name;
+} HSM_CLIENT_X509_INTERFACE;
+
+#ifdef HSM_TYPE_HTTP_EDGE
+typedef struct HSM_CLIENT_HTTP_EDGE_INTERFACE_TAG
+{
+    HSM_CLIENT_CREATE hsm_client_http_edge_create;
+    HSM_CLIENT_DESTROY hsm_client_http_edge_destroy;
+    HSM_CLIENT_SIGN_WITH_IDENTITY hsm_client_sign_with_identity;
+    HSM_CLIENT_GET_TRUST_BUNDLE hsm_client_get_trust_bundle;
+} HSM_CLIENT_HTTP_EDGE_INTERFACE;
+#endif
+
+typedef struct HSM_CLIENT_KEY_INTERFACE_TAG
+{
+    HSM_CLIENT_CREATE hsm_client_key_create;
+    HSM_CLIENT_DESTROY hsm_client_key_destroy;
+
+    HSM_CLIENT_GET_SYMMETRICAL_KEY hsm_client_get_symm_key;
+    HSM_CLIENT_GET_REGISTRATION_NAME hsm_client_get_registration_name;
+    HSM_CLIENT_SET_SYMMETRICAL_KEY_INFO hsm_client_set_symm_key_info;
+} HSM_CLIENT_KEY_INTERFACE;
+
+extern int initialize_hsm_system();
+extern void deinitialize_hsm_system();
+
+extern const HSM_CLIENT_TPM_INTERFACE* hsm_client_tpm_interface();
+extern const HSM_CLIENT_X509_INTERFACE* hsm_client_x509_interface();
+extern const HSM_CLIENT_KEY_INTERFACE* hsm_client_key_interface();
+
+extern int hsm_client_x509_init();
+extern void hsm_client_x509_deinit();
+extern int hsm_client_tpm_init();
+extern void hsm_client_tpm_deinit();
+
+#ifdef HSM_TYPE_HTTP_EDGE
+extern int hsm_client_http_edge_init();
+extern void hsm_client_http_edge_deinit(void);
+extern const HSM_CLIENT_HTTP_EDGE_INTERFACE* hsm_client_http_edge_interface();
+#endif
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif // HSM_CLIENT_DATA_H
Index: azure_iot_hub_f767zi/trunk/azure_iot_sdk/provisioning_client/adapters/hsm_client_key.c
===================================================================
--- azure_iot_hub_f767zi/trunk/azure_iot_sdk/provisioning_client/adapters/hsm_client_key.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/azure_iot_sdk/provisioning_client/adapters/hsm_client_key.c	(revision 457)
@@ -0,0 +1,151 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+#include <stdlib.h>
+#include "umock_c/umock_c_prod.h"
+#include "azure_c_shared_utility/gballoc.h"
+#include "azure_c_shared_utility/urlencode.h"
+#include "azure_c_shared_utility/xlogging.h"
+#include "azure_c_shared_utility/crt_abstractions.h"
+
+#include "hsm_client_data.h"
+#include "hsm_client_key.h"
+
+typedef struct HSM_CLIENT_KEY_INFO_TAG
+{
+    char* symmetrical_key;
+    char* registration_name;
+} HSM_CLIENT_KEY_INFO;
+
+HSM_CLIENT_HANDLE hsm_client_key_create(void)
+{
+    HSM_CLIENT_KEY_INFO* result;
+    result = malloc(sizeof(HSM_CLIENT_KEY_INFO) );
+    if (result == NULL)
+    {
+        LogError("Failure: malloc HSM_CLIENT_KEY_INFO.");
+    }
+    else
+    {
+        memset(result, 0, sizeof(HSM_CLIENT_KEY_INFO));
+    }
+    return result;
+}
+
+void hsm_client_key_destroy(HSM_CLIENT_HANDLE handle)
+{
+    if (handle != NULL)
+    {
+        HSM_CLIENT_KEY_INFO* key_client = (HSM_CLIENT_KEY_INFO*)handle;
+        if (key_client->symmetrical_key != NULL)
+        {
+            free(key_client->symmetrical_key);
+            key_client->symmetrical_key = NULL;
+        }
+        if (key_client->registration_name != NULL)
+        {
+            free(key_client->registration_name);
+            key_client->registration_name = NULL;
+        }
+        free(key_client);
+    }
+}
+
+char* hsm_client_get_symmetric_key(HSM_CLIENT_HANDLE handle)
+{
+    char* result;
+    if (handle == NULL)
+    {
+        /* Codes_SRS_HSM_CLIENT_RIOT_07_010: [ if handle is NULL, hsm_client_riot_get_certificate shall return NULL. ] */
+        LogError("Invalid handle value specified");
+        result = NULL;
+    }
+    else
+    {
+        HSM_CLIENT_KEY_INFO* key_client = (HSM_CLIENT_KEY_INFO*)handle;
+        if (mallocAndStrcpy_s(&result, key_client->symmetrical_key) != 0)
+        {
+            LogError("Failed to allocate symmetrical_key.");
+            result = NULL;
+        }
+    }
+    return result;
+}
+
+char* hsm_client_get_registration_name(HSM_CLIENT_HANDLE handle)
+{
+    char* result;
+    if (handle == NULL)
+    {
+        /* Codes_SRS_HSM_CLIENT_RIOT_07_026: [ if handle is NULL, hsm_client_riot_get_common_name shall return NULL. ] */
+        LogError("Invalid handle value specified");
+        result = NULL;
+    }
+    else
+    {
+        HSM_CLIENT_KEY_INFO* key_client = (HSM_CLIENT_KEY_INFO*)handle;
+        if (mallocAndStrcpy_s(&result, key_client->registration_name) != 0)
+        {
+            LogError("Failure allocating registration_name");
+            result = NULL;
+        }
+    }
+    return result;
+}
+
+int hsm_client_set_key_info(HSM_CLIENT_HANDLE handle, const char* reg_name, const char* symm_key)
+{
+    int result;
+    if (handle == NULL || reg_name == NULL || symm_key == NULL)
+    {
+        LogError("Invalid parameter specified handle: %p, reg_name: %p, symm_key: %p", handle, reg_name, symm_key);
+        result = MU_FAILURE;
+    }
+    else
+    {
+        HSM_CLIENT_KEY_INFO* key_client = (HSM_CLIENT_KEY_INFO*)handle;
+
+        char* temp_reg_name;
+        char* temp_key;
+        if (mallocAndStrcpy_s(&temp_reg_name, reg_name) != 0)
+        {
+            LogError("Failure allocating registration name");
+            result = MU_FAILURE;
+        }
+        else if (mallocAndStrcpy_s(&temp_key, symm_key) != 0)
+        {
+            LogError("Failure allocating symmetric key");
+            free(temp_reg_name);
+            result = MU_FAILURE;
+        }
+        else
+        {
+            if (key_client->symmetrical_key != NULL)
+            {
+                free(key_client->symmetrical_key);
+            }
+            if (key_client->registration_name != NULL)
+            {
+                free(key_client->registration_name);
+            }
+            key_client->symmetrical_key = temp_key;
+            key_client->registration_name = temp_reg_name;
+            result = 0;
+        }
+    }
+    return result;
+}
+
+static const HSM_CLIENT_KEY_INTERFACE key_interface =
+{
+    hsm_client_key_create,
+    hsm_client_key_destroy,
+    hsm_client_get_symmetric_key,
+    hsm_client_get_registration_name,
+    hsm_client_set_key_info
+};
+
+const HSM_CLIENT_KEY_INTERFACE* hsm_client_key_interface(void)
+{
+    return &key_interface;
+}
Index: azure_iot_hub_f767zi/trunk/azure_iot_sdk/provisioning_client/adapters/hsm_client_key.h
===================================================================
--- azure_iot_hub_f767zi/trunk/azure_iot_sdk/provisioning_client/adapters/hsm_client_key.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/azure_iot_sdk/provisioning_client/adapters/hsm_client_key.h	(revision 457)
@@ -0,0 +1,27 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+#ifndef HSM_CLIENT_KEY_H
+#define HSM_CLIENT_KEY_H
+
+#ifdef __cplusplus
+extern "C" {
+#include <cstddef>
+#else
+#include <stddef.h>
+#endif /* __cplusplus */
+
+#include "umock_c/umock_c_prod.h"
+#include "hsm_client_data.h"
+
+MOCKABLE_FUNCTION(, HSM_CLIENT_HANDLE, hsm_client_key_create);
+MOCKABLE_FUNCTION(, void, hsm_client_key_destroy, HSM_CLIENT_HANDLE, handle);
+MOCKABLE_FUNCTION(, char*, hsm_client_get_symmetric_key, HSM_CLIENT_HANDLE, handle);
+MOCKABLE_FUNCTION(, char*, hsm_client_get_registration_name, HSM_CLIENT_HANDLE, handle);
+MOCKABLE_FUNCTION(, int, hsm_client_set_key_info, HSM_CLIENT_HANDLE, handle, const char*, reg_name, const char*, symm_key);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif // HSM_CLIENT_RIOT
Index: azure_iot_hub_f767zi/trunk/azure_iot_sdk/provisioning_client/inc/azure_prov_client/internal/iothub_auth_client.h
===================================================================
--- azure_iot_hub_f767zi/trunk/azure_iot_sdk/provisioning_client/inc/azure_prov_client/internal/iothub_auth_client.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/azure_iot_sdk/provisioning_client/inc/azure_prov_client/internal/iothub_auth_client.h	(revision 457)
@@ -0,0 +1,78 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+#ifndef DEVICE_AUTH_H
+#define DEVICE_AUTH_H
+
+#ifdef __cplusplus
+extern "C" {
+#include <cstdint>
+#include <cstddef>
+#else
+#include <stdint.h>
+#include <stddef.h>
+#endif /* __cplusplus */
+
+#include "umock_c/umock_c_prod.h"
+#include "azure_macro_utils/macro_utils.h"
+
+typedef struct IOTHUB_SECURITY_INFO_TAG* IOTHUB_SECURITY_HANDLE;
+
+#define DEVICE_AUTH_TYPE_VALUES \
+    AUTH_TYPE_UNKNOWN,          \
+    AUTH_TYPE_SAS,              \
+    AUTH_TYPE_X509,             \
+    AUTH_TYPE_SYMM_KEY
+
+MU_DEFINE_ENUM_WITHOUT_INVALID(DEVICE_AUTH_TYPE, DEVICE_AUTH_TYPE_VALUES);
+
+typedef struct DEVICE_AUTH_SAS_INFO_TAG
+{
+    uint64_t expiry_seconds;
+    const char* token_scope;
+    const char* key_name;
+} DEVICE_AUTH_SAS_INFO;
+
+typedef struct DEVICE_AUTH_SAS_RESULT_TAG
+{
+    const char* sas_token;
+} DEVICE_AUTH_SAS_RESULT;
+
+typedef struct DEVICE_AUTH_X509_RESULT_TAG
+{
+    const char* x509_cert;
+    const char* x509_alias_key;
+} DEVICE_AUTH_X509_RESULT;
+
+typedef struct DEVICE_AUTH_CREDENTIAL_INFO_TAG
+{
+    DEVICE_AUTH_TYPE dev_auth_type;
+    DEVICE_AUTH_SAS_INFO sas_info;
+} DEVICE_AUTH_CREDENTIAL_INFO;
+
+typedef struct CREDENTIAL_RESULT_TAG
+{
+    DEVICE_AUTH_TYPE dev_auth_type;
+    union
+    {
+        DEVICE_AUTH_SAS_RESULT sas_result;
+        DEVICE_AUTH_X509_RESULT x509_result;
+    } auth_cred_result;
+} CREDENTIAL_RESULT;
+
+
+MOCKABLE_FUNCTION(, IOTHUB_SECURITY_HANDLE, iothub_device_auth_create);
+MOCKABLE_FUNCTION(, void, iothub_device_auth_destroy, IOTHUB_SECURITY_HANDLE, handle);
+MOCKABLE_FUNCTION(, DEVICE_AUTH_TYPE, iothub_device_auth_get_type, IOTHUB_SECURITY_HANDLE, handle);
+MOCKABLE_FUNCTION(, CREDENTIAL_RESULT*, iothub_device_auth_generate_credentials, IOTHUB_SECURITY_HANDLE, handle, const DEVICE_AUTH_CREDENTIAL_INFO*, dev_auth_cred);
+
+#ifdef USE_EDGE_MODULES
+MOCKABLE_FUNCTION(, char*, iothub_device_auth_get_trust_bundle, IOTHUB_SECURITY_HANDLE, handle);
+#endif
+
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif // DEVICE_AUTH
Index: azure_iot_hub_f767zi/trunk/azure_iot_sdk/provisioning_client/inc/azure_prov_client/internal/prov_auth_client.h
===================================================================
--- azure_iot_hub_f767zi/trunk/azure_iot_sdk/provisioning_client/inc/azure_prov_client/internal/prov_auth_client.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/azure_iot_sdk/provisioning_client/inc/azure_prov_client/internal/prov_auth_client.h	(revision 457)
@@ -0,0 +1,59 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+#ifndef PROV_AUTH_CLIENT_H
+#define PROV_AUTH_CLIENT_H
+
+#ifdef __cplusplus
+extern "C" {
+#include <cstdint>
+#include <cstddef>
+#else
+#include <stdint.h>
+#include <stddef.h>
+#endif /* __cplusplus */
+
+#include "umock_c/umock_c_prod.h"
+#include "azure_macro_utils/macro_utils.h"
+#include "azure_c_shared_utility/buffer_.h"
+
+typedef struct PROV_AUTH_INFO_TAG* PROV_AUTH_HANDLE;
+
+#define PROV_AUTH_RESULT_VALUES   \
+    PROV_AUTH_SUCCESS,            \
+    PROV_AUTH_INVALID_ARG,        \
+    PROV_AUTH_ERROR,              \
+    PROV_AUTH_STATUS_UNASSIGNED,   \
+    PROV_AUTH_STATUS_ASSIGNING
+
+MU_DEFINE_ENUM_WITHOUT_INVALID(PROV_AUTH_RESULT, PROV_AUTH_RESULT_VALUES);
+
+#define PROV_AUTH_TYPE_VALUES \
+    PROV_AUTH_TYPE_UNKNOWN,   \
+    PROV_AUTH_TYPE_TPM,       \
+    PROV_AUTH_TYPE_X509,      \
+    PROV_AUTH_TYPE_KEY
+
+MU_DEFINE_ENUM_WITHOUT_INVALID(PROV_AUTH_TYPE, PROV_AUTH_TYPE_VALUES);
+
+MOCKABLE_FUNCTION(, PROV_AUTH_HANDLE, prov_auth_create);
+MOCKABLE_FUNCTION(, void, prov_auth_destroy, PROV_AUTH_HANDLE, handle);
+MOCKABLE_FUNCTION(, PROV_AUTH_TYPE, prov_auth_get_type, PROV_AUTH_HANDLE, handle);
+MOCKABLE_FUNCTION(, char*, prov_auth_get_registration_id, PROV_AUTH_HANDLE, handle);
+MOCKABLE_FUNCTION(, int, prov_auth_set_registration_id, PROV_AUTH_HANDLE, handle, const char*, registration_id);
+
+// TPM
+MOCKABLE_FUNCTION(, BUFFER_HANDLE, prov_auth_get_endorsement_key, PROV_AUTH_HANDLE, handle);
+MOCKABLE_FUNCTION(, BUFFER_HANDLE, prov_auth_get_storage_key, PROV_AUTH_HANDLE, handle);
+MOCKABLE_FUNCTION(, int, prov_auth_import_key, PROV_AUTH_HANDLE, handle, const unsigned char*, key, size_t, key_len);
+MOCKABLE_FUNCTION(, char*, prov_auth_construct_sas_token, PROV_AUTH_HANDLE, handle, const char*, token_scope, const char*, key_name, size_t, expiry_time);
+
+// X509
+MOCKABLE_FUNCTION(, char*, prov_auth_get_certificate, PROV_AUTH_HANDLE, handle);
+MOCKABLE_FUNCTION(, char*, prov_auth_get_alias_key, PROV_AUTH_HANDLE, handle);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif // PROV_AUTH_CLIENT_H
Index: azure_iot_hub_f767zi/trunk/azure_iot_sdk/provisioning_client/inc/azure_prov_client/internal/prov_transport_mqtt_common.h
===================================================================
--- azure_iot_hub_f767zi/trunk/azure_iot_sdk/provisioning_client/inc/azure_prov_client/internal/prov_transport_mqtt_common.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/azure_iot_sdk/provisioning_client/inc/azure_prov_client/internal/prov_transport_mqtt_common.h	(revision 457)
@@ -0,0 +1,42 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+#ifndef PROV_TRANSPORT_AMQP_COMMON_H
+#define PROV_TRANSPORT_AMQP_COMMON_H
+
+#ifdef __cplusplus
+extern "C" {
+#include <cstdint>
+#include <cstddef>
+#else
+#include <stdint.h>
+#include <stddef.h>
+#include <stdbool.h>
+#endif /* __cplusplus */
+
+#include "umock_c/umock_c_prod.h"
+#include "azure_macro_utils/macro_utils.h"
+#include "azure_prov_client/prov_transport.h"
+#include "azure_prov_client/internal/prov_transport_private.h"
+#include "azure_c_shared_utility/http_proxy_io.h"
+
+typedef XIO_HANDLE(*PROV_MQTT_TRANSPORT_IO)(const char* fully_qualified_name, const HTTP_PROXY_OPTIONS* proxy_info);
+
+MOCKABLE_FUNCTION(, PROV_DEVICE_TRANSPORT_HANDLE, prov_transport_common_mqtt_create, const char*, uri, TRANSPORT_HSM_TYPE, type, const char*, scope_id, const char*, api_version, PROV_MQTT_TRANSPORT_IO, transport_io, PROV_TRANSPORT_ERROR_CALLBACK, error_cb, void*, error_ctx);
+MOCKABLE_FUNCTION(, void, prov_transport_common_mqtt_destroy, PROV_DEVICE_TRANSPORT_HANDLE, handle);
+MOCKABLE_FUNCTION(, int, prov_transport_common_mqtt_open, PROV_DEVICE_TRANSPORT_HANDLE, handle, const char*, registration_id, BUFFER_HANDLE, ek, BUFFER_HANDLE, srk, PROV_DEVICE_TRANSPORT_REGISTER_CALLBACK, data_callback, void*, user_ctx, PROV_DEVICE_TRANSPORT_STATUS_CALLBACK, status_cb, void*, status_ctx, PROV_TRANSPORT_CHALLENGE_CALLBACK, reg_challenge_cb, void*, challenge_ctx);
+MOCKABLE_FUNCTION(, int, prov_transport_common_mqtt_close, PROV_DEVICE_TRANSPORT_HANDLE, handle);
+MOCKABLE_FUNCTION(, int, prov_transport_common_mqtt_register_device, PROV_DEVICE_TRANSPORT_HANDLE, handle, PROV_TRANSPORT_JSON_PARSE, json_parse_cb, PROV_TRANSPORT_CREATE_JSON_PAYLOAD, json_create_cb, void*, json_ctx);
+MOCKABLE_FUNCTION(, int, prov_transport_common_mqtt_get_operation_status, PROV_DEVICE_TRANSPORT_HANDLE, handle);
+MOCKABLE_FUNCTION(, void, prov_transport_common_mqtt_dowork, PROV_DEVICE_TRANSPORT_HANDLE, handle);
+MOCKABLE_FUNCTION(, int, prov_transport_common_mqtt_set_trace, PROV_DEVICE_TRANSPORT_HANDLE, handle, bool, trace_on);
+MOCKABLE_FUNCTION(, int, prov_transport_common_mqtt_set_proxy, PROV_DEVICE_TRANSPORT_HANDLE, handle, const HTTP_PROXY_OPTIONS*, proxy_options);
+MOCKABLE_FUNCTION(, int, prov_transport_common_mqtt_set_trusted_cert, PROV_DEVICE_TRANSPORT_HANDLE, handle, const char*, certificate);
+MOCKABLE_FUNCTION(, int, prov_transport_common_mqtt_x509_cert, PROV_DEVICE_TRANSPORT_HANDLE, handle, const char*, certificate, const char*, private_key);
+MOCKABLE_FUNCTION(, int, prov_transport_common_mqtt_set_option, PROV_DEVICE_TRANSPORT_HANDLE, handle, const char*, option, const void*, value);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif // PROV_TRANSPORT_AMQP_COMMON_H
Index: azure_iot_hub_f767zi/trunk/azure_iot_sdk/provisioning_client/inc/azure_prov_client/internal/prov_transport_private.h
===================================================================
--- azure_iot_hub_f767zi/trunk/azure_iot_sdk/provisioning_client/inc/azure_prov_client/internal/prov_transport_private.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/azure_iot_sdk/provisioning_client/inc/azure_prov_client/internal/prov_transport_private.h	(revision 457)
@@ -0,0 +1,93 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+#ifndef PROV_TRANSPORT_PRIVATE_H
+#define PROV_TRANSPORT_PRIVATE_H
+
+#include "umock_c/umock_c_prod.h"
+#include "azure_macro_utils/macro_utils.h"
+#include "azure_c_shared_utility/shared_util_options.h"
+#include "azure_c_shared_utility/buffer_.h"
+#include "azure_prov_client/prov_transport.h"
+
+#ifdef __cplusplus
+extern "C" {
+#else
+#include <stdint.h>
+#include <stdbool.h>
+#endif /* __cplusplus */
+
+    #define PROV_STATUS_CODE_TRANSIENT_ERROR    429
+
+    #define PROV_DEVICE_TRANSPORT_STATUS_VALUES     \
+        PROV_DEVICE_TRANSPORT_STATUS_CONNECTED,     \
+        PROV_DEVICE_TRANSPORT_STATUS_AUTHENTICATED, \
+        PROV_DEVICE_TRANSPORT_STATUS_UNASSIGNED,    \
+        PROV_DEVICE_TRANSPORT_STATUS_ASSIGNING,     \
+        PROV_DEVICE_TRANSPORT_STATUS_ASSIGNED,      \
+        PROV_DEVICE_TRANSPORT_STATUS_BLACKLISTED,   \
+        PROV_DEVICE_TRANSPORT_STATUS_TRANSIENT,     \
+        PROV_DEVICE_TRANSPORT_STATUS_ERROR,         \
+        PROV_DEVICE_TRANSPORT_STATUS_DISABLED
+
+    MU_DEFINE_ENUM_WITHOUT_INVALID(PROV_DEVICE_TRANSPORT_STATUS, PROV_DEVICE_TRANSPORT_STATUS_VALUES);
+
+    #define PROV_DEVICE_TRANSPORT_ERROR_VALUE   \
+        PROV_DEVICE_ERROR_KEY_FAIL,             \
+        PROV_DEVICE_ERROR_KEY_UNAUTHORIZED,     \
+        PROV_DEVICE_ERROR_MEMORY
+
+    MU_DEFINE_ENUM_WITHOUT_INVALID(PROV_DEVICE_TRANSPORT_ERROR, PROV_DEVICE_TRANSPORT_ERROR_VALUE);
+
+    typedef struct PROV_JSON_INFO_TAG
+    {
+        PROV_DEVICE_TRANSPORT_STATUS prov_status;
+        char* operation_id;
+        BUFFER_HANDLE authorization_key;
+        char* key_name;
+        char* iothub_uri;
+        char* device_id;
+    } PROV_JSON_INFO;
+
+    typedef void(*PROV_DEVICE_TRANSPORT_REGISTER_CALLBACK)(PROV_DEVICE_TRANSPORT_RESULT transport_result, BUFFER_HANDLE iothub_key, const char* assigned_hub, const char* device_id, void* user_ctx);
+    typedef void(*PROV_DEVICE_TRANSPORT_STATUS_CALLBACK)(PROV_DEVICE_TRANSPORT_STATUS transport_status, uint32_t retry_interval, void* user_ctx);
+    typedef char*(*PROV_TRANSPORT_CHALLENGE_CALLBACK)(const unsigned char* nonce, size_t nonce_len, const char* key_name, void* user_ctx);
+    typedef PROV_JSON_INFO*(*PROV_TRANSPORT_JSON_PARSE)(const char* json_document, void* user_ctx);
+    typedef char*(*PROV_TRANSPORT_CREATE_JSON_PAYLOAD)(const char* ek_value, const char* srk_value, void* user_ctx);
+    typedef void(*PROV_TRANSPORT_ERROR_CALLBACK)(PROV_DEVICE_TRANSPORT_ERROR transport_error, void* user_context);
+
+    typedef PROV_DEVICE_TRANSPORT_HANDLE(*pfprov_transport_create)(const char* uri, TRANSPORT_HSM_TYPE type, const char* scope_id, const char* api_version, PROV_TRANSPORT_ERROR_CALLBACK error_cb, void* error_ctx);
+    typedef void(*pfprov_transport_destroy)(PROV_DEVICE_TRANSPORT_HANDLE handle);
+    typedef int(*pfprov_transport_open)(PROV_DEVICE_TRANSPORT_HANDLE handle, const char* registration_id, BUFFER_HANDLE ek, BUFFER_HANDLE srk, PROV_DEVICE_TRANSPORT_REGISTER_CALLBACK data_callback, void* user_ctx, PROV_DEVICE_TRANSPORT_STATUS_CALLBACK status_cb, void* status_ctx, PROV_TRANSPORT_CHALLENGE_CALLBACK reg_challenge_cb, void* challenge_ctx);
+    typedef int(*pfprov_transport_close)(PROV_DEVICE_TRANSPORT_HANDLE handle);
+
+    typedef int(*pfprov_transport_register_device)(PROV_DEVICE_TRANSPORT_HANDLE handle, PROV_TRANSPORT_JSON_PARSE json_parse_cb, PROV_TRANSPORT_CREATE_JSON_PAYLOAD json_create_cb, void* json_ctx);
+    typedef int(*pfprov_transport_get_operation_status)(PROV_DEVICE_TRANSPORT_HANDLE handle);
+    typedef void(*pfprov_transport_dowork)(PROV_DEVICE_TRANSPORT_HANDLE handle);
+    typedef int(*pfprov_transport_set_trace)(PROV_DEVICE_TRANSPORT_HANDLE handle, bool trace_on);
+    typedef int(*pfprov_transport_set_x509_cert)(PROV_DEVICE_TRANSPORT_HANDLE handle, const char* certificate, const char* private_key);
+    typedef int(*pfprov_transport_set_trusted_cert)(PROV_DEVICE_TRANSPORT_HANDLE handle, const char* certificate);
+    typedef int(*pfprov_transport_set_proxy)(PROV_DEVICE_TRANSPORT_HANDLE handle, const HTTP_PROXY_OPTIONS* proxy_option);
+    typedef int(*pfprov_transport_set_option)(PROV_DEVICE_TRANSPORT_HANDLE handle, const char* option_name, const void* value);
+
+    struct PROV_DEVICE_TRANSPORT_PROVIDER_TAG
+    {
+        pfprov_transport_create prov_transport_create;
+        pfprov_transport_destroy prov_transport_destroy;
+        pfprov_transport_open prov_transport_open;
+        pfprov_transport_close prov_transport_close;
+        pfprov_transport_register_device prov_transport_register;
+        pfprov_transport_get_operation_status prov_transport_get_op_status;
+        pfprov_transport_dowork prov_transport_dowork;
+        pfprov_transport_set_trace prov_transport_set_trace;
+        pfprov_transport_set_x509_cert prov_transport_x509_cert;
+        pfprov_transport_set_trusted_cert prov_transport_trusted_cert;
+        pfprov_transport_set_proxy prov_transport_set_proxy;
+        pfprov_transport_set_option prov_transport_set_option;
+    };
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif // PROV_TRANSPORT_PRIVATE_H
Index: azure_iot_hub_f767zi/trunk/azure_iot_sdk/provisioning_client/inc/azure_prov_client/iothub_security_factory.h
===================================================================
--- azure_iot_hub_f767zi/trunk/azure_iot_sdk/provisioning_client/inc/azure_prov_client/iothub_security_factory.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/azure_iot_sdk/provisioning_client/inc/azure_prov_client/iothub_security_factory.h	(revision 457)
@@ -0,0 +1,43 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+#ifndef IOTHUB_SECURITY_FACTORY_H
+#define IOTHUB_SECURITY_FACTORY_H
+
+#ifdef __cplusplus
+#include <cstddef>
+extern "C" {
+#else
+#include <stddef.h>
+#endif /* __cplusplus */
+
+#include "umock_c/umock_c_prod.h"
+#include "azure_macro_utils/macro_utils.h"
+#include "azure_c_shared_utility/buffer_.h"
+
+#define IOTHUB_SECURITY_TYPE_VALUES \
+    IOTHUB_SECURITY_TYPE_UNKNOWN,   \
+    IOTHUB_SECURITY_TYPE_SAS,       \
+    IOTHUB_SECURITY_TYPE_X509,      \
+    IOTHUB_SECURITY_TYPE_HTTP_EDGE, \
+    IOTHUB_SECURITY_TYPE_SYMMETRIC_KEY
+
+
+MU_DEFINE_ENUM_WITHOUT_INVALID(IOTHUB_SECURITY_TYPE, IOTHUB_SECURITY_TYPE_VALUES);
+
+MOCKABLE_FUNCTION(, int, iothub_security_init, IOTHUB_SECURITY_TYPE, sec_type);
+MOCKABLE_FUNCTION(, void, iothub_security_deinit);
+
+MOCKABLE_FUNCTION(, const void*, iothub_security_interface);
+MOCKABLE_FUNCTION(, IOTHUB_SECURITY_TYPE, iothub_security_type);
+
+// Symmetric key information
+MOCKABLE_FUNCTION(, int, iothub_security_set_symmetric_key_info, const char*, registration_name, const char*, symmetric_key);
+MOCKABLE_FUNCTION(, const char*, iothub_security_get_symmetric_key);
+MOCKABLE_FUNCTION(, const char*, iothub_security_get_symm_registration_name);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif // IOTHUB_SECURITY_FACTORY_H
Index: azure_iot_hub_f767zi/trunk/azure_iot_sdk/provisioning_client/inc/azure_prov_client/prov_client_const.h
===================================================================
--- azure_iot_hub_f767zi/trunk/azure_iot_sdk/provisioning_client/inc/azure_prov_client/prov_client_const.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/azure_iot_sdk/provisioning_client/inc/azure_prov_client/prov_client_const.h	(revision 457)
@@ -0,0 +1,20 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+#ifndef PROV_CLIENT_CONST_H
+#define PROV_CLIENT_CONST_H
+
+#define PROV_DEVICE_CLIENT_VERSION "1.3.8"
+#define PROV_GET_THROTTLE_TIME      1
+#define MAX_PROV_GET_THROTTLE_TIME  5*60
+
+static const char* const PROV_ASSIGNED_STATUS = "assigned";
+static const char* const PROV_ASSIGNING_STATUS = "assigning";
+static const char* const PROV_UNASSIGNED_STATUS = "unassigned";
+static const char* const PROV_DISABLE_STATUS = "disabled";
+
+static const char* const RETRY_AFTER_KEY_VALUE = "retry-after";
+
+static const char* const PROV_API_VERSION = "2019-03-31";
+
+#endif // PROV_CLIENT_CONST_H
Index: azure_iot_hub_f767zi/trunk/azure_iot_sdk/provisioning_client/inc/azure_prov_client/prov_device_client.h
===================================================================
--- azure_iot_hub_f767zi/trunk/azure_iot_sdk/provisioning_client/inc/azure_prov_client/prov_device_client.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/azure_iot_sdk/provisioning_client/inc/azure_prov_client/prov_device_client.h	(revision 457)
@@ -0,0 +1,64 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+/** @file prov_device_client.h
+*    @brief Extends the Prov_Device_LL module with additional features.
+*
+*    @details Prov_Device is a module that extends the Prov_Device_LL
+*             module with 2 features:
+*                - scheduling the work for the IoTHubCLient from a
+*                  thread, so that the user does not need to create their
+*                  own thread
+*                - thread-safe APIs
+*/
+
+#ifndef PROV_DEVICE_CLIENT_H
+#define PROV_DEVICE_CLIENT_H
+
+#ifndef PROV_DEVICE_CLIENT_INSTANCE_TYPE
+typedef struct PROV_DEVICE_INSTANCE_TAG* PROV_DEVICE_HANDLE;
+#define PROV_DEVICE_CLIENT_INSTANCE_TYPE
+#endif // PROV_DEVICE_CLIENT_INSTANCE_TYPE
+
+#include <stddef.h>
+#include <stdint.h>
+#include "prov_device_ll_client.h"
+#include "umock_c/umock_c_prod.h"
+#include "azure_macro_utils/macro_utils.h"
+#include "azure_prov_client/prov_transport.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+MOCKABLE_FUNCTION(, PROV_DEVICE_HANDLE, Prov_Device_Create, const char*, uri, const char*, scope_id, PROV_DEVICE_TRANSPORT_PROVIDER_FUNCTION, protocol);
+MOCKABLE_FUNCTION(, void, Prov_Device_Destroy, PROV_DEVICE_HANDLE, prov_device_handle);
+MOCKABLE_FUNCTION(, PROV_DEVICE_RESULT, Prov_Device_Register_Device, PROV_DEVICE_HANDLE, prov_device_handle, PROV_DEVICE_CLIENT_REGISTER_DEVICE_CALLBACK, register_callback, void*, user_context, PROV_DEVICE_CLIENT_REGISTER_STATUS_CALLBACK, register_status_callback, void*, status_user_context);
+MOCKABLE_FUNCTION(, PROV_DEVICE_RESULT, Prov_Device_SetOption, PROV_DEVICE_HANDLE, prov_device_handle, const char*, optionName, const void*, value);
+MOCKABLE_FUNCTION(, const char*, Prov_Device_GetVersionString);
+
+/**
+* @brief    Sets the Provisioning Data that is sent to the Provisioning service
+*
+* @param    handle          The handle created by a call to the create function.
+* @param    json            The json payload field that is sent to the service.  Setting json to NULL will unset the value previously set
+*
+* @return PROV_DEVICE_RESULT_OK upon success or an error code upon failure
+*/
+MOCKABLE_FUNCTION(, PROV_DEVICE_RESULT, Prov_Device_Set_Provisioning_Payload, PROV_DEVICE_HANDLE, handle, const char*, json);
+
+/**
+* @brief    Retrieves the Provisioning Data that is sent from the Provisioning service
+*
+* @param    handle          The handle created by a call to the create function.
+*
+* @return The data that was specified by the service
+*/
+MOCKABLE_FUNCTION(, const char*, Prov_Device_Get_Provisioning_Payload, PROV_DEVICE_HANDLE, handle);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif // PROV_DEVICE_CLIENT_H
Index: azure_iot_hub_f767zi/trunk/azure_iot_sdk/provisioning_client/inc/azure_prov_client/prov_device_ll_client.h
===================================================================
--- azure_iot_hub_f767zi/trunk/azure_iot_sdk/provisioning_client/inc/azure_prov_client/prov_device_ll_client.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/azure_iot_sdk/provisioning_client/inc/azure_prov_client/prov_device_ll_client.h	(revision 457)
@@ -0,0 +1,137 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+#ifndef PROV_DEVICE_LL_CLIENT_H
+#define PROV_DEVICE_LL_CLIENT_H
+
+#include "umock_c/umock_c_prod.h"
+#include "azure_macro_utils/macro_utils.h"
+#include "azure_prov_client/prov_transport.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+typedef struct PROV_INSTANCE_INFO_TAG* PROV_DEVICE_LL_HANDLE;
+
+#define PROV_DEVICE_RESULT_VALUE            \
+    PROV_DEVICE_RESULT_OK,                  \
+    PROV_DEVICE_RESULT_INVALID_ARG,         \
+    PROV_DEVICE_RESULT_SUCCESS,             \
+    PROV_DEVICE_RESULT_MEMORY,              \
+    PROV_DEVICE_RESULT_PARSING,             \
+    PROV_DEVICE_RESULT_TRANSPORT,           \
+    PROV_DEVICE_RESULT_INVALID_STATE,       \
+    PROV_DEVICE_RESULT_DEV_AUTH_ERROR,      \
+    PROV_DEVICE_RESULT_TIMEOUT,             \
+    PROV_DEVICE_RESULT_KEY_ERROR,           \
+    PROV_DEVICE_RESULT_ERROR,               \
+    PROV_DEVICE_RESULT_HUB_NOT_SPECIFIED,   \
+    PROV_DEVICE_RESULT_UNAUTHORIZED,        \
+    PROV_DEVICE_RESULT_DISABLED
+
+MU_DEFINE_ENUM_WITHOUT_INVALID(PROV_DEVICE_RESULT, PROV_DEVICE_RESULT_VALUE);
+
+#define PROV_DEVICE_REG_STATUS_VALUES      \
+    PROV_DEVICE_REG_STATUS_CONNECTED,      \
+    PROV_DEVICE_REG_STATUS_REGISTERING,    \
+    PROV_DEVICE_REG_STATUS_ASSIGNING,      \
+    PROV_DEVICE_REG_STATUS_ASSIGNED,       \
+    PROV_DEVICE_REG_STATUS_ERROR,          \
+    PROV_DEVICE_REG_HUB_NOT_SPECIFIED
+
+MU_DEFINE_ENUM_WITHOUT_INVALID(PROV_DEVICE_REG_STATUS, PROV_DEVICE_REG_STATUS_VALUES);
+
+static const char* const PROV_REGISTRATION_ID = "registration_id";
+static const char* const PROV_OPTION_LOG_TRACE = "logtrace";
+static const char* const PROV_OPTION_TIMEOUT = "provisioning_timeout";
+
+typedef void(*PROV_DEVICE_CLIENT_REGISTER_DEVICE_CALLBACK)(PROV_DEVICE_RESULT register_result, const char* iothub_uri, const char* device_id, void* user_context);
+typedef void(*PROV_DEVICE_CLIENT_REGISTER_STATUS_CALLBACK)(PROV_DEVICE_REG_STATUS reg_status, void* user_context);
+
+typedef const PROV_DEVICE_TRANSPORT_PROVIDER*(*PROV_DEVICE_TRANSPORT_PROVIDER_FUNCTION)(void);
+
+/**
+* @brief    Creates a Provisioning Client for communications with the Device Provisioning Client Service
+*
+* @param    uri         The URI of the Device Provisioning Service
+* @param    scope_id    The customer specific Id Scope
+* @param    protocol    Function pointer for protocol implementation
+*
+* @return   A non-NULL PROV_DEVICE_LL_HANDLE value that is used when invoking other functions
+*           and NULL on Failure
+*/
+MOCKABLE_FUNCTION(, PROV_DEVICE_LL_HANDLE, Prov_Device_LL_Create, const char*, uri, const char*, scope_id, PROV_DEVICE_TRANSPORT_PROVIDER_FUNCTION, protocol);
+
+/**
+* @brief    Disposes of resources allocated by the provisioning Client.
+*
+* @param    handle  The handle created by a call to the create function
+*
+*/
+MOCKABLE_FUNCTION(, void, Prov_Device_LL_Destroy, PROV_DEVICE_LL_HANDLE, handle);
+
+/**
+* @brief    Asynchronous call initiates the registration of a device.
+*
+* @param    handle              The handle created by a call to the create function.
+* @param    register_callback   The callback that gets called on registration or if an error is encountered
+* @param    user_context        User specified context that will be provided to the callback
+* @param    reg_status_cb       An optional registration status callback used to inform the caller of registration status
+* @param    status_user_ctext   User specified context that will be provided to the registration status callback
+*
+* @return PROV_DEVICE_RESULT_OK upon success or an error code upon failure
+*/
+MOCKABLE_FUNCTION(, PROV_DEVICE_RESULT, Prov_Device_LL_Register_Device, PROV_DEVICE_LL_HANDLE, handle, PROV_DEVICE_CLIENT_REGISTER_DEVICE_CALLBACK, register_callback, void*, user_context, PROV_DEVICE_CLIENT_REGISTER_STATUS_CALLBACK, reg_status_cb, void*, status_user_ctext);
+
+/**
+* @brief    Api to be called by user when work (registering device) can be done
+*
+* @param    handle  The handle created by a call to the create function.
+*
+*/
+MOCKABLE_FUNCTION(, void, Prov_Device_LL_DoWork, PROV_DEVICE_LL_HANDLE, handle);
+
+/**
+* @brief    API sets a runtime option identified by parameter optionName to a value pointed to by value
+*
+* @param    handle          The handle created by a call to the create function.
+* @param    optionName      The name of the option to be set
+* @param    value           A pointer to the value of the option to be set
+*
+* @return PROV_DEVICE_RESULT_OK upon success or an error code upon failure
+*/
+MOCKABLE_FUNCTION(, PROV_DEVICE_RESULT, Prov_Device_LL_SetOption, PROV_DEVICE_LL_HANDLE, handle, const char*, optionName, const void*, value);
+
+/**
+* @brief    API to get the version of the provisioning client
+*
+* @return The version number of the provisioning client
+*/
+MOCKABLE_FUNCTION(, const char*, Prov_Device_LL_GetVersionString);
+
+
+/**
+* @brief    Sets the Provisioning Data that is sent to the Provisioning service
+*
+* @param    handle          The handle created by a call to the create function.
+* @param    json            The data field that is sent to the service.  Setting json to NULL will unset the value previously set
+*
+* @return PROV_DEVICE_RESULT_OK upon success or an error code upon failure
+*/
+MOCKABLE_FUNCTION(, PROV_DEVICE_RESULT, Prov_Device_LL_Set_Provisioning_Payload, PROV_DEVICE_LL_HANDLE, handle, const char*, json);
+
+/**
+* @brief    Retrieves the Provisioning Data that is sent from the Provisioning service
+*
+* @param    handle          The handle created by a call to the create function.
+*
+* @return The data that was specified by the service
+*/
+MOCKABLE_FUNCTION(, const char*, Prov_Device_LL_Get_Provisioning_Payload, PROV_DEVICE_LL_HANDLE, handle);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif // PROV_DEVICE_LL_CLIENT_H
Index: azure_iot_hub_f767zi/trunk/azure_iot_sdk/provisioning_client/inc/azure_prov_client/prov_edge_trusted_certificates.h
===================================================================
--- azure_iot_hub_f767zi/trunk/azure_iot_sdk/provisioning_client/inc/azure_prov_client/prov_edge_trusted_certificates.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/azure_iot_sdk/provisioning_client/inc/azure_prov_client/prov_edge_trusted_certificates.h	(revision 457)
@@ -0,0 +1,21 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+#ifndef PROV_EDGE_TRUSTED_CERTIFICATES_H
+#define PROV_EDGE_TRUSTED_CERTIFICATES_H
+
+#ifdef __cplusplus
+extern "C" {
+#else
+#endif /* __cplusplus */
+
+
+MOCKABLE_FUNCTION(, const char*, prov_get_edge_trusted_certificates);
+
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+
+#endif // PROV_EDGE_TRUSTED_CERTIFICATES_H
Index: azure_iot_hub_f767zi/trunk/azure_iot_sdk/provisioning_client/inc/azure_prov_client/prov_security_factory.h
===================================================================
--- azure_iot_hub_f767zi/trunk/azure_iot_sdk/provisioning_client/inc/azure_prov_client/prov_security_factory.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/azure_iot_sdk/provisioning_client/inc/azure_prov_client/prov_security_factory.h	(revision 457)
@@ -0,0 +1,40 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+#ifndef PROV_SECURITY_FACTORY_H
+#define PROV_SECURITY_FACTORY_H
+
+#ifdef __cplusplus
+#include <cstddef>
+extern "C" {
+#else
+#include <stddef.h>
+#endif /* __cplusplus */
+
+#include "umock_c/umock_c_prod.h"
+#include "azure_macro_utils/macro_utils.h"
+
+#define SECURE_DEVICE_TYPE_VALUES \
+    SECURE_DEVICE_TYPE_UNKNOWN,   \
+    SECURE_DEVICE_TYPE_TPM,       \
+    SECURE_DEVICE_TYPE_X509,      \
+    SECURE_DEVICE_TYPE_HTTP_EDGE, \
+    SECURE_DEVICE_TYPE_SYMMETRIC_KEY
+
+MU_DEFINE_ENUM_WITHOUT_INVALID(SECURE_DEVICE_TYPE, SECURE_DEVICE_TYPE_VALUES);
+
+
+MOCKABLE_FUNCTION(, int, prov_dev_security_init, SECURE_DEVICE_TYPE, hsm_type);
+MOCKABLE_FUNCTION(, void, prov_dev_security_deinit);
+MOCKABLE_FUNCTION(, SECURE_DEVICE_TYPE, prov_dev_security_get_type);
+
+// Symmetric key information
+MOCKABLE_FUNCTION(, int, prov_dev_set_symmetric_key_info, const char*, registration_name, const char*, symmetric_key);
+MOCKABLE_FUNCTION(, const char*, prov_dev_get_symmetric_key);
+MOCKABLE_FUNCTION(, const char*, prov_dev_get_symm_registration_name);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif // PROV_SECURITY_FACTORY_H
Index: azure_iot_hub_f767zi/trunk/azure_iot_sdk/provisioning_client/inc/azure_prov_client/prov_transport.h
===================================================================
--- azure_iot_hub_f767zi/trunk/azure_iot_sdk/provisioning_client/inc/azure_prov_client/prov_transport.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/azure_iot_sdk/provisioning_client/inc/azure_prov_client/prov_transport.h	(revision 457)
@@ -0,0 +1,78 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+#ifndef PROV_TRANSPORT_H
+#define PROV_TRANSPORT_H
+
+#include "umock_c/umock_c_prod.h"
+#include "azure_macro_utils/macro_utils.h"
+#include "azure_c_shared_utility/shared_util_options.h"
+#include "azure_c_shared_utility/buffer_.h"
+#include "azure_prov_client/prov_client_const.h"
+
+#ifdef __cplusplus
+extern "C" {
+#include <cstdint>
+#include <cstdlib>
+#else
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdlib.h>
+#endif /* __cplusplus */
+
+    struct PROV_DEVICE_TRANSPORT_PROVIDER_TAG;
+    typedef struct PROV_DEVICE_TRANSPORT_PROVIDER_TAG PROV_DEVICE_TRANSPORT_PROVIDER;
+
+    typedef void* PROV_DEVICE_TRANSPORT_HANDLE;
+
+#define TRANSPORT_HSM_TYPE_VALUES   \
+    TRANSPORT_HSM_TYPE_TPM,         \
+    TRANSPORT_HSM_TYPE_X509,        \
+    TRANSPORT_HSM_TYPE_SYMM_KEY
+
+    MU_DEFINE_ENUM_WITHOUT_INVALID(TRANSPORT_HSM_TYPE, TRANSPORT_HSM_TYPE_VALUES);
+
+#define PROV_DEVICE_TRANSPORT_RESULT_VALUES     \
+    PROV_DEVICE_TRANSPORT_RESULT_OK,            \
+    PROV_DEVICE_TRANSPORT_RESULT_UNAUTHORIZED,  \
+    PROV_DEVICE_TRANSPORT_RESULT_ERROR
+
+    MU_DEFINE_ENUM_WITHOUT_INVALID(PROV_DEVICE_TRANSPORT_RESULT, PROV_DEVICE_TRANSPORT_RESULT_VALUES);
+
+    // Snippit from RFC 7231 https://tools.ietf.org/html/rfc7231
+    // The value of this field can be either an HTTP - date or a number of
+    // seconds to delay after the response is received.
+
+    // Retry - After = HTTP - date / delay - seconds
+
+    // A delay - seconds value is a non - negative decimal integer, representing
+    // time in seconds.
+
+    // delay - seconds = 1 * DIGIT
+    // Two examples of its use are
+
+    // Retry-After: Fri, 31 Dec 1999 23 : 59 : 59 GMT
+    // Retry-After : 120
+    static inline uint32_t parse_retry_after_value(const char* retry_after)
+    {
+        uint32_t result = PROV_GET_THROTTLE_TIME;
+        if (retry_after != NULL)
+        {
+            // Is the retry after a number
+            if (retry_after[0] >= 0x30 && retry_after[0] <= 0x39)
+            {
+                result = atol(retry_after);
+                if (result < PROV_GET_THROTTLE_TIME || result > MAX_PROV_GET_THROTTLE_TIME)
+                {
+                    result = PROV_GET_THROTTLE_TIME;
+                }
+            }
+            // Will need to parse the retry after for date information
+        }
+        return result;
+    }
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif // PROV_TRANSPORT
Index: azure_iot_hub_f767zi/trunk/azure_iot_sdk/provisioning_client/inc/azure_prov_client/prov_transport_http_client.h
===================================================================
--- azure_iot_hub_f767zi/trunk/azure_iot_sdk/provisioning_client/inc/azure_prov_client/prov_transport_http_client.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/azure_iot_sdk/provisioning_client/inc/azure_prov_client/prov_transport_http_client.h	(revision 457)
@@ -0,0 +1,26 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+#ifndef PROV_TRANSPORT_HTTP_CLIENT_H
+#define PROV_TRANSPORT_HTTP_CLIENT_H
+
+#ifdef __cplusplus
+extern "C" {
+#include <cstdint>
+#include <cstddef>
+#else
+#include <stdint.h>
+#include <stddef.h>
+#endif /* __cplusplus */
+
+#include "umock_c/umock_c_prod.h"
+#include "azure_macro_utils/macro_utils.h"
+#include "azure_prov_client/prov_transport.h"
+
+MOCKABLE_FUNCTION(, const PROV_DEVICE_TRANSPORT_PROVIDER*, Prov_Device_HTTP_Protocol);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif // PROV_TRANSPORT_HTTP_CLIENT_H
Index: azure_iot_hub_f767zi/trunk/azure_iot_sdk/provisioning_client/inc/azure_prov_client/prov_transport_mqtt_client.h
===================================================================
--- azure_iot_hub_f767zi/trunk/azure_iot_sdk/provisioning_client/inc/azure_prov_client/prov_transport_mqtt_client.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/azure_iot_sdk/provisioning_client/inc/azure_prov_client/prov_transport_mqtt_client.h	(revision 457)
@@ -0,0 +1,26 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+#ifndef PROV_TRANSPORT_MQTT_CLIENT_H
+#define PROV_TRANSPORT_MQTT_CLIENT_H
+
+#ifdef __cplusplus
+extern "C" {
+#include <cstdint>
+#include <cstddef>
+#else
+#include <stdint.h>
+#include <stddef.h>
+#endif /* __cplusplus */
+
+#include "umock_c/umock_c_prod.h"
+#include "azure_macro_utils/macro_utils.h"
+#include "azure_prov_client/prov_transport.h"
+
+MOCKABLE_FUNCTION(, const PROV_DEVICE_TRANSPORT_PROVIDER*, Prov_Device_MQTT_Protocol);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif // PROV_TRANSPORT_MQTT_CLIENT_H
Index: azure_iot_hub_f767zi/trunk/azure_iot_sdk/provisioning_client/inc/azure_prov_client/prov_transport_mqtt_ws_client.h
===================================================================
--- azure_iot_hub_f767zi/trunk/azure_iot_sdk/provisioning_client/inc/azure_prov_client/prov_transport_mqtt_ws_client.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/azure_iot_sdk/provisioning_client/inc/azure_prov_client/prov_transport_mqtt_ws_client.h	(revision 457)
@@ -0,0 +1,26 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+#ifndef PROV_TRANSPORT_MQTT_WS_CLIENT_H
+#define PROV_TRANSPORT_MQTT_WS_CLIENT_H
+
+#ifdef __cplusplus
+extern "C" {
+#include <cstdint>
+#include <cstddef>
+#else
+#include <stdint.h>
+#include <stddef.h>
+#endif /* __cplusplus */
+
+#include "umock_c/umock_c_prod.h"
+#include "azure_macro_utils/macro_utils.h"
+#include "azure_prov_client/prov_transport.h"
+
+MOCKABLE_FUNCTION(, const PROV_DEVICE_TRANSPORT_PROVIDER*, Prov_Device_MQTT_WS_Protocol);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif // PROV_TRANSPORT_MQTT_WS_CLIENT_H
Index: azure_iot_hub_f767zi/trunk/azure_iot_sdk/provisioning_client/src/iothub_auth_client.c
===================================================================
--- azure_iot_hub_f767zi/trunk/azure_iot_sdk/provisioning_client/src/iothub_auth_client.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/azure_iot_sdk/provisioning_client/src/iothub_auth_client.c	(revision 457)
@@ -0,0 +1,484 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+#include <stdlib.h>
+#include "umock_c/umock_c_prod.h"
+#include "azure_c_shared_utility/gballoc.h"
+#include "azure_c_shared_utility/sastoken.h"
+#include "azure_c_shared_utility/azure_base64.h"
+#include "azure_c_shared_utility/sha.h"
+#include "azure_c_shared_utility/urlencode.h"
+#include "azure_c_shared_utility/strings.h"
+#include "azure_c_shared_utility/xlogging.h"
+#include "azure_c_shared_utility/crt_abstractions.h"
+#include "azure_c_shared_utility/hmacsha256.h"
+
+#include "azure_prov_client/internal/iothub_auth_client.h"
+#include "azure_prov_client/iothub_security_factory.h"
+#include "hsm_client_data.h"
+
+typedef struct IOTHUB_SECURITY_INFO_TAG
+{
+    DEVICE_AUTH_TYPE cred_type;
+
+    HSM_CLIENT_HANDLE hsm_client_handle;
+
+    HSM_CLIENT_CREATE hsm_client_create;
+    HSM_CLIENT_DESTROY hsm_client_destroy;
+
+    HSM_CLIENT_SIGN_WITH_IDENTITY hsm_client_sign_data;
+
+    HSM_CLIENT_GET_CERTIFICATE hsm_client_get_cert;
+    HSM_CLIENT_GET_ALIAS_KEY hsm_client_get_alias_key;
+
+    HSM_CLIENT_GET_TRUST_BUNDLE hsm_client_get_trust_bundle;
+    HSM_CLIENT_GET_SYMMETRICAL_KEY hsm_client_get_symm_key;
+    HSM_CLIENT_SET_SYMMETRICAL_KEY_INFO hsm_client_set_symm_key_info;
+
+    char* sas_token;
+    char* x509_certificate;
+    char* x509_alias_key;
+    bool base64_encode_signature;
+    bool urlencode_token_scope;
+} IOTHUB_SECURITY_INFO;
+
+#define HMAC_LENGTH                 32
+static const char* const SAS_TOKEN_FORMAT = "SharedAccessSignature sr=%s&sig=%s&se=%s%s%s";
+static const char* const SKN_SECTION_FORMAT = "&skn=";
+
+static int sign_sas_data(IOTHUB_SECURITY_INFO* security_info, const char* payload, unsigned char** output, size_t* len)
+{
+    int result;
+    size_t payload_len = strlen(payload);
+    if (security_info->cred_type == AUTH_TYPE_SAS)
+    {
+        if (security_info->hsm_client_sign_data(security_info->hsm_client_handle, (const unsigned char*)payload, strlen(payload), output, len) != 0)
+        {
+            LogError("Failed signing data");
+            result = MU_FAILURE;
+        }
+        else
+        {
+            result = 0;
+        }
+    }
+    else
+    {
+        char* symmetrical_key = security_info->hsm_client_get_symm_key(security_info->hsm_client_handle);
+        if (symmetrical_key == NULL)
+        {
+            LogError("Failed getting asymmetrical key");
+            result = MU_FAILURE;
+        }
+        else
+        {
+            BUFFER_HANDLE decoded_key;
+            BUFFER_HANDLE output_hash;
+
+            if ((decoded_key = Azure_Base64_Decode(symmetrical_key)) == NULL)
+            {
+                LogError("Failed decoding symmetrical key");
+                result = MU_FAILURE;
+            }
+            else if ((output_hash = BUFFER_new()) == NULL)
+            {
+                LogError("Failed allocating output hash buffer");
+                BUFFER_delete(decoded_key);
+                result = MU_FAILURE;
+            }
+            else
+            {
+                if (HMACSHA256_ComputeHash(BUFFER_u_char(decoded_key), BUFFER_length(decoded_key), (const unsigned char*)payload, payload_len, output_hash) != HMACSHA256_OK)
+                {
+                    LogError("Failed computing HMAC Hash");
+                    result = MU_FAILURE;
+                }
+                else
+                {
+                    *len = BUFFER_length(output_hash);
+                    if ((*output = malloc(*len)) == NULL)
+                    {
+                        LogError("Failed allocating output buffer");
+                        result = MU_FAILURE;
+                    }
+                    else
+                    {
+                        const unsigned char* output_data = BUFFER_u_char(output_hash);
+                        memcpy(*output, output_data, *len);
+                        result = 0;
+                    }
+                }
+                BUFFER_delete(decoded_key);
+                BUFFER_delete(output_hash);
+            }
+            free(symmetrical_key);
+        }
+    }
+    return result;
+}
+
+IOTHUB_SECURITY_HANDLE iothub_device_auth_create()
+{
+    IOTHUB_SECURITY_INFO* result;
+
+    IOTHUB_SECURITY_TYPE iothub_security_t = iothub_security_type();
+
+    if ((result = (IOTHUB_SECURITY_INFO*)malloc(sizeof(IOTHUB_SECURITY_INFO))) == NULL)
+    {
+        /* Codes_IOTHUB_DEV_AUTH_07_001: [ if any failure is encountered iothub_device_auth_create shall return NULL. ] */
+        LogError("Failed allocating IOTHUB_SECURITY_INFO.");
+    }
+    else
+    {
+        memset(result, 0, sizeof(IOTHUB_SECURITY_INFO) );
+#if defined(HSM_TYPE_SAS_TOKEN)  || defined(HSM_AUTH_TYPE_CUSTOM)
+        if (iothub_security_t == IOTHUB_SECURITY_TYPE_SAS)
+        {
+            result->cred_type = AUTH_TYPE_SAS;
+            result->base64_encode_signature = true;
+            result->urlencode_token_scope = false;
+            const HSM_CLIENT_TPM_INTERFACE* tpm_interface = hsm_client_tpm_interface();
+            if ((tpm_interface == NULL) ||
+                ((result->hsm_client_create = tpm_interface->hsm_client_tpm_create) == NULL) ||
+                ((result->hsm_client_destroy = tpm_interface->hsm_client_tpm_destroy) == NULL) ||
+                ((result->hsm_client_sign_data = tpm_interface->hsm_client_sign_with_identity) == NULL)
+                )
+            {
+                /* Codes_IOTHUB_DEV_AUTH_07_034: [ if any of the iothub_security_interface function are NULL iothub_device_auth_create shall return NULL. ] */
+                LogError("Invalid secure device interface");
+                free(result);
+                result = NULL;
+            }
+        }
+#endif
+#if defined(HSM_TYPE_X509) || defined(HSM_AUTH_TYPE_CUSTOM)
+        if (result != NULL && iothub_security_t == IOTHUB_SECURITY_TYPE_X509)
+        {
+            result->cred_type = AUTH_TYPE_X509;
+            result->base64_encode_signature = true;
+            result->urlencode_token_scope = false;
+            const HSM_CLIENT_X509_INTERFACE* x509_interface = hsm_client_x509_interface();
+            if ((x509_interface == NULL) ||
+                ((result->hsm_client_create = x509_interface->hsm_client_x509_create) == NULL) ||
+                ((result->hsm_client_destroy = x509_interface->hsm_client_x509_destroy) == NULL) ||
+                ((result->hsm_client_get_cert = x509_interface->hsm_client_get_cert) == NULL) ||
+                ((result->hsm_client_get_alias_key = x509_interface->hsm_client_get_key) == NULL)
+                )
+            {
+                /* Codes_IOTHUB_DEV_AUTH_07_034: [ if any of the iothub_security_interface function are NULL iothub_device_auth_create shall return NULL. ] */
+                LogError("Invalid handle parameter: DEVICE_AUTH_CREATION_INFO is NULL");
+                free(result);
+                result = NULL;
+            }
+        }
+#endif
+#if defined(HSM_TYPE_SYMM_KEY) || defined(HSM_AUTH_TYPE_CUSTOM)
+        if (result != NULL && iothub_security_t == IOTHUB_SECURITY_TYPE_SYMMETRIC_KEY)
+        {
+            result->cred_type = AUTH_TYPE_SYMM_KEY;
+            result->base64_encode_signature = true;
+            result->urlencode_token_scope = false;
+            const HSM_CLIENT_KEY_INTERFACE* key_interface = hsm_client_key_interface();
+            if ((key_interface == NULL) ||
+                ((result->hsm_client_create = key_interface->hsm_client_key_create) == NULL) ||
+                ((result->hsm_client_destroy = key_interface->hsm_client_key_destroy) == NULL) ||
+                ((result->hsm_client_get_symm_key = key_interface->hsm_client_get_symm_key) == NULL) ||
+                ((result->hsm_client_set_symm_key_info = key_interface->hsm_client_set_symm_key_info) == NULL)
+                )
+            {
+                LogError("Invalid x509 secure device interface was specified");
+                free(result);
+                result = NULL;
+            }
+        }
+#endif
+#ifdef HSM_TYPE_HTTP_EDGE
+        if (result != NULL && iothub_security_t == IOTHUB_SECURITY_TYPE_HTTP_EDGE)
+        {
+            result->cred_type = AUTH_TYPE_SAS;
+            // Because HTTP_edge operates over HTTP, the server has already base64 encoded signature its returning to us.
+            result->base64_encode_signature = false;
+            result->urlencode_token_scope = true;
+            const HSM_CLIENT_HTTP_EDGE_INTERFACE* http_edge_interface = hsm_client_http_edge_interface();
+            if ((http_edge_interface == NULL) ||
+                ((result->hsm_client_create = http_edge_interface->hsm_client_http_edge_create) == NULL) ||
+                ((result->hsm_client_destroy = http_edge_interface->hsm_client_http_edge_destroy) == NULL) ||
+                ((result->hsm_client_sign_data = http_edge_interface->hsm_client_sign_with_identity) == NULL) ||
+                ((result->hsm_client_get_trust_bundle = http_edge_interface->hsm_client_get_trust_bundle) == NULL))
+            {
+                LogError("Invalid secure device interface");
+                free(result);
+                result = NULL;
+            }
+        }
+#endif
+        if (result == NULL)
+        {
+            LogError("Error allocating result or else unsupported security type %d", iothub_security_t);
+        }
+        else if (result->hsm_client_create == NULL)
+        {
+            LogError("hsm_client_create is not a valid address");
+            free(result);
+            result = NULL;
+        }
+        else
+        {
+            /* Codes_IOTHUB_DEV_AUTH_07_025: [ iothub_device_auth_create shall call the concrete_iothub_device_auth_create function associated with the interface_desc. ] */
+            /* Codes_IOTHUB_DEV_AUTH_07_026: [ if concrete_iothub_device_auth_create fails iothub_device_auth_create shall return NULL. ] */
+            if ((result->hsm_client_handle = result->hsm_client_create()) == NULL)
+            {
+                /* Codes_IOTHUB_DEV_AUTH_07_002: [ iothub_device_auth_create shall allocate the IOTHUB_SECURITY_INFO and shall fail if the allocation fails. ]*/
+                LogError("failed create device auth module.");
+                free(result);
+                result = NULL;
+            }
+            else if (result->cred_type == AUTH_TYPE_SYMM_KEY && result->hsm_client_set_symm_key_info(result->hsm_client_handle, iothub_security_get_symm_registration_name(), iothub_security_get_symmetric_key()) != 0)
+            {
+                LogError("Invalid x509 secure device interface was specified");
+                result->hsm_client_destroy(result->hsm_client_handle);
+                free(result);
+                result = NULL;
+            }
+        }
+    }
+    /* Codes_IOTHUB_DEV_AUTH_07_003: [ If the function succeeds iothub_device_auth_create shall return a IOTHUB_SECURITY_HANDLE. ] */
+    return result;
+}
+
+void iothub_device_auth_destroy(IOTHUB_SECURITY_HANDLE handle)
+{
+    /* Codes_IOTHUB_DEV_AUTH_07_006: [ If the argument handle is NULL, iothub_device_auth_destroy shall do nothing ] */
+    if (handle != NULL)
+    {
+        /* Codes_IOTHUB_DEV_AUTH_07_005: [ iothub_device_auth_destroy shall call the concrete_iothub_device_auth_destroy function associated with the XDA_INTERFACE_DESCRIPTION. ] */
+        free(handle->x509_certificate);
+        free(handle->x509_alias_key);
+        free(handle->sas_token);
+        handle->hsm_client_destroy(handle->hsm_client_handle);
+        /* Codes_IOTHUB_DEV_AUTH_07_004: [ iothub_device_auth_destroy shall free all resources associated with the IOTHUB_SECURITY_HANDLE handle ] */
+        free(handle);
+    }
+}
+
+DEVICE_AUTH_TYPE iothub_device_auth_get_type(IOTHUB_SECURITY_HANDLE handle)
+{
+    DEVICE_AUTH_TYPE result;
+    /* Codes_IOTHUB_DEV_AUTH_07_007: [ If the argument handle is NULL, iothub_device_auth_get_auth_type shall return AUTH_TYPE_UNKNOWN. ] */
+    if (handle == NULL)
+    {
+        LogError("Invalid handle specified");
+        result = AUTH_TYPE_UNKNOWN;
+    }
+    else
+    {
+        /* Codes_IOTHUB_DEV_AUTH_07_008: [ iothub_device_auth_get_auth_type shall call concrete_iothub_device_auth_type function associated with the XDA_INTERFACE_DESCRIPTION. ] */
+        /* Codes_IOTHUB_DEV_AUTH_07_009: [ iothub_device_auth_get_auth_type shall return the DEVICE_AUTH_TYPE returned by the concrete_iothub_device_auth_type function. ] */
+        result = handle->cred_type;
+    }
+    return result;
+}
+
+CREDENTIAL_RESULT* iothub_device_auth_generate_credentials(IOTHUB_SECURITY_HANDLE handle, const DEVICE_AUTH_CREDENTIAL_INFO* dev_auth_cred)
+{
+    CREDENTIAL_RESULT* result;
+    /* Codes_IOTHUB_DEV_AUTH_07_010: [ If the argument handle or dev_auth_cred is NULL, iothub_device_auth_generate_credentials shall return a NULL value. ] */
+    if (handle == NULL)
+    {
+        LogError("Invalid handle parameter: handle");
+        result = NULL;
+    }
+    else
+    {
+        if (handle->cred_type == AUTH_TYPE_SAS || handle->cred_type == AUTH_TYPE_SYMM_KEY)
+        {
+            char expire_token[64] = { 0 };
+            if (handle->sas_token != NULL)
+            {
+                free(handle->sas_token);
+                handle->sas_token = NULL;
+            }
+            if (dev_auth_cred == NULL || dev_auth_cred->sas_info.token_scope == NULL)
+            {
+                LogError("Invalid handle parameter: dev_auth_cred");
+                result = NULL;
+            }
+            else if (dev_auth_cred->dev_auth_type != AUTH_TYPE_SAS && dev_auth_cred->dev_auth_type != AUTH_TYPE_SYMM_KEY)
+            {
+                LogError("Invalid handle parameter: dev_auth_cred.dev_auth_type");
+                result = NULL;
+            }
+            else if (size_tToString(expire_token, sizeof(expire_token), (size_t)dev_auth_cred->sas_info.expiry_seconds) != 0)
+            {
+                result = NULL;
+                LogError("Failure creating expire token");
+            }
+            else
+            {
+                size_t len = strlen(dev_auth_cred->sas_info.token_scope)+strlen(expire_token)+3;
+                char* payload = malloc(len+1);
+                if (payload == NULL)
+                {
+                    result = NULL;
+                    LogError("Failure allocating payload.");
+                }
+                else
+                {
+                    unsigned char* data_value;
+                    size_t data_len;
+
+                    size_t total_len = sprintf(payload, "%s\n%s", dev_auth_cred->sas_info.token_scope, expire_token);
+                    if (total_len <= 0)
+                    {
+                        result = NULL;
+                        LogError("Failure constructing hash payload.");
+                    }
+                    /* Codes_IOTHUB_DEV_AUTH_07_035: [ For tpm type iothub_device_auth_generate_credentials shall call the concrete_dev_auth_sign_data function to hash the data. ] */
+                    else if (sign_sas_data(handle, payload, &data_value, &data_len) == 0)
+                    {
+                        STRING_HANDLE urlEncodedSignature = NULL;
+                        STRING_HANDLE signature = NULL;
+                        if (handle->base64_encode_signature == true)
+                        {
+                            signature = Azure_Base64_Encode_Bytes(data_value, data_len);
+                        }
+                        else
+                        {
+                            signature = STRING_construct((const char*)data_value);
+                        }
+
+                        if (signature == NULL)
+                        {
+                            result = NULL;
+                            LogError("Failure constructing encoding.");
+                        }
+                        else if ((urlEncodedSignature = URL_Encode(signature)) == NULL)
+                        {
+                            result = NULL;
+                            LogError("Failure constructing url Signature.");
+                            STRING_delete(signature);
+                        }
+                        else
+                        {
+                            const char* skn_key = "";
+                            const char* skn_value = "";
+
+                            if ((dev_auth_cred->sas_info.key_name != NULL) && (strlen(dev_auth_cred->sas_info.key_name) > 0))
+                            {
+                                // If the key name is valid then add to the sas token
+                                skn_key = SKN_SECTION_FORMAT;
+                                skn_value = dev_auth_cred->sas_info.key_name;
+                            }
+
+                            STRING_HANDLE sas_token_handle = NULL;
+
+                            if (handle->urlencode_token_scope == true)
+                            {
+                                STRING_HANDLE url_encoded = URL_EncodeString(dev_auth_cred->sas_info.token_scope);
+                                if (url_encoded == NULL)
+                                {
+                                    LogError("failed to url string %s", dev_auth_cred->sas_info.token_scope);
+                                }
+                                else
+                                {
+                                    sas_token_handle = STRING_construct_sprintf(SAS_TOKEN_FORMAT, STRING_c_str(url_encoded), STRING_c_str(urlEncodedSignature), expire_token, skn_key, skn_value);
+                                }
+
+                                STRING_delete(url_encoded);
+                            }
+                            else
+                            {
+                                sas_token_handle = STRING_construct_sprintf(SAS_TOKEN_FORMAT, dev_auth_cred->sas_info.token_scope, STRING_c_str(urlEncodedSignature), expire_token, skn_key, skn_value);
+                            }
+
+                            if (sas_token_handle == NULL)
+                            {
+                                result = NULL;
+                                LogError("Failure constructing url Signature.");
+                            }
+                            else if ((result = malloc(sizeof(CREDENTIAL_RESULT))) == NULL)
+                            {
+                                STRING_delete(sas_token_handle);
+                                LogError("Failure allocating credential result.");
+                            }
+                            else
+                            {
+                                const char* temp_sas_token = STRING_c_str(sas_token_handle);
+                                if (mallocAndStrcpy_s(&handle->sas_token, temp_sas_token) != 0)
+                                {
+                                    free(result);
+                                    result = NULL;
+                                    LogError("Failure allocating and copying string.");
+                                }
+                                else
+                                {
+                                    result->auth_cred_result.sas_result.sas_token = handle->sas_token;
+                                }
+                                STRING_delete(sas_token_handle);
+                            }
+                            STRING_delete(signature);
+                            STRING_delete(urlEncodedSignature);
+                        }
+                        free(data_value);
+                    }
+                    else
+                    {
+                        result = NULL;
+                        LogError("Failure generate hash from tpm.");
+                    }
+                    free(payload);
+                }
+            }
+        }
+        else
+        {
+            if (handle->x509_certificate != NULL)
+            {
+                free(handle->x509_certificate);
+                handle->x509_certificate = NULL;
+            }
+            if (handle->x509_alias_key != NULL)
+            {
+                free(handle->x509_alias_key);
+                handle->x509_alias_key = NULL;
+            }
+
+            if ((result = malloc(sizeof(CREDENTIAL_RESULT))) == NULL)
+            {
+                LogError("Failure allocating credential result.");
+            }
+            else if ((handle->x509_certificate = handle->hsm_client_get_cert(handle->hsm_client_handle)) == NULL)
+            {
+                LogError("Failure allocating device credential result.");
+                free(result);
+                result = NULL;
+            }
+            else if ((handle->x509_alias_key = handle->hsm_client_get_alias_key(handle->hsm_client_handle)) == NULL)
+            {
+                LogError("Failure allocating device credential result.");
+                free(handle->x509_certificate);
+                handle->x509_certificate = NULL;
+                free(result);
+                result = NULL;
+            }
+            else
+            {
+                result->auth_cred_result.x509_result.x509_cert = handle->x509_certificate;
+                result->auth_cred_result.x509_result.x509_alias_key = handle->x509_alias_key;
+            }
+        }
+    }
+    return result;
+}
+
+#ifdef USE_EDGE_MODULES
+char* iothub_device_auth_get_trust_bundle(IOTHUB_SECURITY_HANDLE handle)
+{
+    if (handle->hsm_client_get_trust_bundle == NULL)
+    {
+        LogError("This authentication type does not support getting trusted certificates");
+        return NULL;
+    }
+    return handle->hsm_client_get_trust_bundle(handle->hsm_client_handle);
+}
+#endif
Index: azure_iot_hub_f767zi/trunk/azure_iot_sdk/provisioning_client/src/iothub_security_factory.c
===================================================================
--- azure_iot_hub_f767zi/trunk/azure_iot_sdk/provisioning_client/src/iothub_security_factory.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/azure_iot_sdk/provisioning_client/src/iothub_security_factory.c	(revision 457)
@@ -0,0 +1,181 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+#include <stdlib.h>
+#include "azure_prov_client/iothub_security_factory.h"
+#include "azure_prov_client/prov_security_factory.h"
+#include "azure_c_shared_utility/xlogging.h"
+#include "azure_c_shared_utility/crt_abstractions.h"
+
+#include "hsm_client_data.h"
+
+static IOTHUB_SECURITY_TYPE g_security_type = IOTHUB_SECURITY_TYPE_UNKNOWN;
+static char* g_symm_key = NULL;
+static char* g_symm_key_reg_name = NULL;
+
+static SECURE_DEVICE_TYPE get_secure_device_type(IOTHUB_SECURITY_TYPE sec_type)
+{
+    SECURE_DEVICE_TYPE ret;
+
+    switch (sec_type)
+    {
+#if defined(HSM_TYPE_SAS_TOKEN)  || defined(HSM_AUTH_TYPE_CUSTOM)
+        case IOTHUB_SECURITY_TYPE_SAS:
+            ret = SECURE_DEVICE_TYPE_TPM;
+            break;
+#endif
+
+#if defined(HSM_TYPE_X509) || defined(HSM_AUTH_TYPE_CUSTOM)
+        case IOTHUB_SECURITY_TYPE_X509:
+            ret = SECURE_DEVICE_TYPE_X509;
+            break;
+#endif
+
+#if defined(HSM_TYPE_SYMM_KEY) || defined(HSM_AUTH_TYPE_CUSTOM)
+        case IOTHUB_SECURITY_TYPE_SYMMETRIC_KEY:
+            ret = SECURE_DEVICE_TYPE_SYMMETRIC_KEY;
+            break;
+#endif
+
+#ifdef HSM_TYPE_HTTP_EDGE
+        case IOTHUB_SECURITY_TYPE_HTTP_EDGE:
+            ret = SECURE_DEVICE_TYPE_HTTP_EDGE;
+            break;
+#endif
+
+        default:
+            ret = SECURE_DEVICE_TYPE_UNKNOWN;
+            break;
+    }
+
+    return ret;
+}
+
+int iothub_security_init(IOTHUB_SECURITY_TYPE sec_type)
+{
+    int result;
+
+    SECURE_DEVICE_TYPE secure_device_type_from_caller = get_secure_device_type(sec_type);
+
+    if (secure_device_type_from_caller == SECURE_DEVICE_TYPE_UNKNOWN)
+    {
+        LogError("Security type %d is not supported in this SDK build", sec_type);
+        result = MU_FAILURE;
+    }
+    else
+    {
+        g_security_type = sec_type;
+        SECURE_DEVICE_TYPE security_device_type_from_prov = prov_dev_security_get_type();
+        if (security_device_type_from_prov == SECURE_DEVICE_TYPE_UNKNOWN)
+        {
+            result = prov_dev_security_init(secure_device_type_from_caller);
+        }
+        else if (secure_device_type_from_caller != security_device_type_from_prov)
+        {
+            LogError("Security type from caller %d (which maps to security device type %d) does not match already specified security device type %d", sec_type, secure_device_type_from_caller, security_device_type_from_prov);
+            result = MU_FAILURE;
+        }
+        else
+        {
+            result = 0;
+        }
+
+        if (result == 0)
+        {
+            result = initialize_hsm_system();
+        }
+    }
+    return result;
+}
+
+void iothub_security_deinit()
+{
+    if (g_symm_key != NULL)
+    {
+        free(g_symm_key);
+        g_symm_key = NULL;
+    }
+    if (g_symm_key_reg_name != NULL)
+    {
+        free(g_symm_key_reg_name);
+        g_symm_key_reg_name = NULL;
+    }
+    deinitialize_hsm_system();
+    if (prov_dev_get_symmetric_key() != NULL || prov_dev_get_symm_registration_name() != NULL)
+    {
+        prov_dev_security_deinit();
+    }
+}
+
+IOTHUB_SECURITY_TYPE iothub_security_type()
+{
+    return g_security_type;
+}
+
+int iothub_security_set_symmetric_key_info(const char* registration_name, const char* symmetric_key)
+{
+    int result;
+    if (registration_name == NULL || symmetric_key == NULL)
+    {
+        LogError("Invalid parameter specified reg_name: %p, symm_key: %p", registration_name, symmetric_key);
+        result = MU_FAILURE;
+    }
+    else
+    {
+        char* temp_key;
+        char* temp_name;
+        if (mallocAndStrcpy_s(&temp_name, registration_name) != 0)
+        {
+            LogError("Failure allocating registration name");
+            result = MU_FAILURE;
+        }
+        else if (mallocAndStrcpy_s(&temp_key, symmetric_key) != 0)
+        {
+            LogError("Failure allocating symmetric key");
+            free(temp_name);
+            result = MU_FAILURE;
+        }
+        else
+        {
+            if (g_symm_key != NULL)
+            {
+                free(g_symm_key);
+            }
+            if (g_symm_key_reg_name != NULL)
+            {
+                free(g_symm_key_reg_name);
+            }
+            g_symm_key_reg_name = temp_name;
+            g_symm_key = temp_key;
+
+            // Sync iothub with dps
+            if (prov_dev_get_symmetric_key() == NULL || prov_dev_get_symm_registration_name() == NULL)
+            {
+                if (prov_dev_set_symmetric_key_info(g_symm_key_reg_name, g_symm_key) != 0)
+                {
+                    LogError("Failure syncing dps & IoThub key information");
+                    result = MU_FAILURE;
+                }
+                else
+                {
+                    result = 0;
+                }
+            }
+            else
+            {
+                result = 0;
+            }
+        }
+    }
+    return result;
+}
+
+const char* iothub_security_get_symmetric_key()
+{
+    return g_symm_key;
+}
+
+const char* iothub_security_get_symm_registration_name()
+{
+    return g_symm_key_reg_name;
+}
Index: azure_iot_hub_f767zi/trunk/azure_iot_sdk/provisioning_client/src/prov_auth_client.c
===================================================================
--- azure_iot_hub_f767zi/trunk/azure_iot_sdk/provisioning_client/src/prov_auth_client.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/azure_iot_sdk/provisioning_client/src/prov_auth_client.c	(revision 457)
@@ -0,0 +1,666 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+#include <stdlib.h>
+#include "umock_c/umock_c_prod.h"
+#include "azure_c_shared_utility/gballoc.h"
+#include "azure_c_shared_utility/xlogging.h"
+#include "azure_c_shared_utility/azure_base64.h"
+#include "azure_c_shared_utility/azure_base32.h"
+#include "azure_c_shared_utility/urlencode.h"
+#include "azure_c_shared_utility/sha.h"
+#include "azure_c_shared_utility/strings.h"
+#include "azure_c_shared_utility/crt_abstractions.h"
+#include "azure_c_shared_utility/sastoken.h"
+#include "azure_c_shared_utility/hmacsha256.h"
+
+#include "azure_prov_client/internal/prov_auth_client.h"
+#include "hsm_client_data.h"
+
+#include "azure_prov_client/prov_security_factory.h"
+
+typedef struct PROV_AUTH_INFO_TAG
+{
+    HSM_CLIENT_HANDLE hsm_client_handle;
+
+    PROV_AUTH_TYPE sec_type;
+
+    char* registration_id;
+
+    HSM_CLIENT_CREATE hsm_client_create;
+    HSM_CLIENT_DESTROY hsm_client_destroy;
+
+    HSM_CLIENT_ACTIVATE_IDENTITY_KEY hsm_client_import_key;
+    HSM_CLIENT_GET_ENDORSEMENT_KEY hsm_client_get_endorsement_key;
+    HSM_CLIENT_GET_STORAGE_ROOT_KEY hsm_client_get_srk;
+    HSM_CLIENT_SIGN_WITH_IDENTITY hsm_client_sign_data;
+
+    HSM_CLIENT_GET_CERTIFICATE hsm_client_get_cert;
+    HSM_CLIENT_GET_ALIAS_KEY hsm_client_get_alias_key;
+    HSM_CLIENT_GET_COMMON_NAME hsm_client_get_common_name;
+
+    HSM_CLIENT_GET_SYMMETRICAL_KEY hsm_client_get_symm_key;
+    HSM_CLIENT_SET_SYMMETRICAL_KEY_INFO hsm_client_set_symm_key_info;
+} PROV_AUTH_INFO;
+
+static char* encode_value(const uint8_t* msg_digest, size_t digest_len)
+{
+    char* result;
+
+    char* encoded_hash = Azure_Base32_Encode_Bytes(msg_digest, digest_len);
+    if (encoded_hash == NULL)
+    {
+        LogError("Failure encoded Base32");
+        result = NULL;
+    }
+    else
+    {
+        size_t encode_len = strlen(encoded_hash);
+        char* iterator = encoded_hash + encode_len - 1;
+
+        while (iterator != encoded_hash)
+        {
+            if (*iterator != '=')
+            {
+                *(iterator+1) = '\0';
+                break;
+            }
+            iterator--;
+        }
+
+        if (mallocAndStrcpy_s(&result, encoded_hash) != 0)
+        {
+            LogError("Failure allocating encoded base32 result");
+            result = NULL;
+        }
+        free(encoded_hash);
+    }
+    return result;
+}
+
+static int load_registration_id(PROV_AUTH_INFO* handle)
+{
+    int result;
+    if (handle->sec_type == PROV_AUTH_TYPE_TPM)
+    {
+        SHA256Context sha_ctx;
+        uint8_t msg_digest[SHA256HashSize];
+        unsigned char* endorsement_key;
+        size_t ek_len;
+
+        if (handle->hsm_client_get_endorsement_key(handle->hsm_client_handle, &endorsement_key, &ek_len) != 0)
+        {
+            LogError("Failed getting device reg id");
+            result = MU_FAILURE;
+        }
+        else
+        {
+            if (SHA256Reset(&sha_ctx) != 0)
+            {
+                LogError("Failed sha256 reset");
+                result = MU_FAILURE;
+            }
+            else if (SHA256Input(&sha_ctx, endorsement_key, (unsigned int)ek_len) != 0)
+            {
+                LogError("Failed SHA256Input");
+                result = MU_FAILURE;
+            }
+            else if (SHA256Result(&sha_ctx, msg_digest) != 0)
+            {
+                LogError("Failed SHA256Result");
+                result = MU_FAILURE;
+            }
+            else
+            {
+                handle->registration_id = encode_value(msg_digest, SHA256HashSize);
+                if (handle->registration_id == NULL)
+                {
+                    LogError("Failed allocating registration Id");
+                    result = MU_FAILURE;
+                }
+                else
+                {
+                    result = 0;
+                }
+            }
+            free(endorsement_key);
+        }
+    }
+    else
+    {
+        handle->registration_id = handle->hsm_client_get_common_name(handle->hsm_client_handle);
+        if (handle->registration_id == NULL)
+        {
+            LogError("Failed getting common name from certificate");
+            result = MU_FAILURE;
+        }
+        else
+        {
+            result = 0;
+        }
+    }
+    return result;
+}
+
+static int sign_sas_data(PROV_AUTH_INFO* auth_info, const char* payload, unsigned char** output, size_t* len)
+{
+    int result;
+    size_t payload_len = strlen(payload);
+    if (auth_info->sec_type == PROV_AUTH_TYPE_TPM)
+    {
+        if (auth_info->hsm_client_sign_data(auth_info->hsm_client_handle, (const unsigned char*)payload, strlen(payload), output, len) != 0)
+        {
+            LogError("Failed signing data");
+            result = MU_FAILURE;
+        }
+        else
+        {
+            result = 0;
+        }
+    }
+    else
+    {
+        char* symmetrical_key = auth_info->hsm_client_get_symm_key(auth_info->hsm_client_handle);
+        if (symmetrical_key == NULL)
+        {
+            LogError("Failed getting asymmetrical key");
+            result = MU_FAILURE;
+        }
+        else
+        {
+            BUFFER_HANDLE decoded_key;
+            BUFFER_HANDLE output_hash;
+            if ((decoded_key = Azure_Base64_Decode(symmetrical_key)) == NULL)
+            {
+                LogError("Failed decoding symmetrical key");
+                result = MU_FAILURE;
+            }
+            else if ((output_hash = BUFFER_new()) == NULL)
+            {
+                LogError("Failed allocating output hash buffer");
+                BUFFER_delete(decoded_key);
+                result = MU_FAILURE;
+            }
+            else
+            {
+                size_t decoded_key_len = BUFFER_length(decoded_key);
+                const unsigned char* decoded_key_bytes = BUFFER_u_char(decoded_key);
+
+                if (HMACSHA256_ComputeHash(decoded_key_bytes, decoded_key_len, (const unsigned char*)payload, payload_len, output_hash) != HMACSHA256_OK)
+                {
+                    LogError("Failed computing HMAC Hash");
+                    result = MU_FAILURE;
+                }
+                else
+                {
+                    *len = BUFFER_length(output_hash);
+                    if ((*output = malloc(*len)) == NULL)
+                    {
+                        LogError("Failed allocating output buffer");
+                        result = MU_FAILURE;
+                    }
+                    else
+                    {
+                        const unsigned char* output_data = BUFFER_u_char(output_hash);
+                        memcpy(*output, output_data, *len);
+                        result = 0;
+                    }
+                }
+                BUFFER_delete(decoded_key);
+                BUFFER_delete(output_hash);
+            }
+        }
+        free(symmetrical_key);
+    }
+    return result;
+}
+
+PROV_AUTH_HANDLE prov_auth_create(void)
+{
+    PROV_AUTH_INFO* result;
+    /* Codes_SRS_PROV_AUTH_CLIENT_07_001: [ prov_auth_create shall allocate the PROV_AUTH_INFO. ] */
+    if ((result = (PROV_AUTH_INFO*)malloc(sizeof(PROV_AUTH_INFO))) == NULL)
+    {
+        LogError("Failed allocating PROV_AUTH_INFO.");
+    }
+    else
+    {
+        memset(result, 0, sizeof(PROV_AUTH_INFO) );
+        SECURE_DEVICE_TYPE sec_type = prov_dev_security_get_type();
+#if defined(HSM_TYPE_SAS_TOKEN)  || defined(HSM_AUTH_TYPE_CUSTOM)
+        if (sec_type == SECURE_DEVICE_TYPE_TPM)
+        {
+            /* Codes_SRS_PROV_AUTH_CLIENT_07_003: [ prov_auth_create shall validate the specified secure enclave interface to ensure. ] */
+            result->sec_type = PROV_AUTH_TYPE_TPM;
+            const HSM_CLIENT_TPM_INTERFACE* tpm_interface = hsm_client_tpm_interface();
+            if ((tpm_interface == NULL) ||
+                ((result->hsm_client_create = tpm_interface->hsm_client_tpm_create) == NULL) ||
+                ((result->hsm_client_destroy = tpm_interface->hsm_client_tpm_destroy) == NULL) ||
+                ((result->hsm_client_import_key = tpm_interface->hsm_client_activate_identity_key) == NULL) ||
+                ((result->hsm_client_get_endorsement_key = tpm_interface->hsm_client_get_ek) == NULL) ||
+                ((result->hsm_client_get_srk = tpm_interface->hsm_client_get_srk) == NULL) ||
+                ((result->hsm_client_sign_data = tpm_interface->hsm_client_sign_with_identity) == NULL)
+                )
+            {
+                /* Codes_SRS_PROV_AUTH_CLIENT_07_002: [ If any failure is encountered prov_auth_create shall return NULL ] */
+                LogError("Invalid TPM secure device interface was specified");
+                free(result);
+                result = NULL;
+            }
+        }
+#endif
+#if defined(HSM_TYPE_X509) || defined(HSM_AUTH_TYPE_CUSTOM)
+        if (sec_type == SECURE_DEVICE_TYPE_X509)
+        {
+            /* Codes_SRS_PROV_AUTH_CLIENT_07_003: [ prov_auth_create shall validate the specified secure enclave interface to ensure. ] */
+            result->sec_type = PROV_AUTH_TYPE_X509;
+            const HSM_CLIENT_X509_INTERFACE* x509_interface = hsm_client_x509_interface();
+            if ((x509_interface == NULL) ||
+                ((result->hsm_client_create = x509_interface->hsm_client_x509_create) == NULL) ||
+                ((result->hsm_client_destroy = x509_interface->hsm_client_x509_destroy) == NULL) ||
+                ((result->hsm_client_get_cert = x509_interface->hsm_client_get_cert) == NULL) ||
+                ((result->hsm_client_get_common_name = x509_interface->hsm_client_get_common_name) == NULL) ||
+                ((result->hsm_client_get_alias_key = x509_interface->hsm_client_get_key) == NULL)
+                )
+            {
+                LogError("Invalid x509 secure device interface was specified");
+                free(result);
+                result = NULL;
+            }
+        }
+#endif
+#if defined(HSM_TYPE_SYMM_KEY) || defined(HSM_AUTH_TYPE_CUSTOM)
+        if (sec_type == SECURE_DEVICE_TYPE_SYMMETRIC_KEY)
+        {
+            result->sec_type = PROV_AUTH_TYPE_KEY;
+            const HSM_CLIENT_KEY_INTERFACE* key_interface = hsm_client_key_interface();
+            if ((key_interface == NULL) ||
+                ((result->hsm_client_create = key_interface->hsm_client_key_create) == NULL) ||
+                ((result->hsm_client_destroy = key_interface->hsm_client_key_destroy) == NULL) ||
+                ((result->hsm_client_get_common_name = key_interface->hsm_client_get_registration_name) == NULL) ||
+                ((result->hsm_client_get_symm_key = key_interface->hsm_client_get_symm_key) == NULL) ||
+                ((result->hsm_client_set_symm_key_info = key_interface->hsm_client_set_symm_key_info) == NULL)
+                )
+            {
+                LogError("Invalid symmetric key secure device interface was specified");
+                free(result);
+                result = NULL;
+            }
+        }
+#endif
+
+        if (result == NULL)
+        {
+            LogError("Error allocating result or else unsupported security type %d", sec_type);
+        }
+        else if (result->hsm_client_create == NULL)
+        {
+            LogError("hsm_client_create is not a valid address");
+            free(result);
+            result = NULL;
+        }
+        else
+        {
+            /* Codes_SRS_PROV_AUTH_CLIENT_07_004: [ prov_auth_create shall call hsm_client_create on the secure enclave interface. ] */
+            if ((result->hsm_client_handle = result->hsm_client_create() ) == NULL)
+            {
+                LogError("failed create device auth module.");
+                free(result);
+                result = NULL;
+            }
+            else if (result->sec_type == PROV_AUTH_TYPE_KEY && result->hsm_client_set_symm_key_info(result->hsm_client_handle, prov_dev_get_symm_registration_name(), prov_dev_get_symmetric_key()) != 0)
+            {
+                LogError("failed create device auth module.");
+                result->hsm_client_destroy(result->hsm_client_handle);
+                free(result);
+                result = NULL;
+            }
+        }
+    }
+    return result;
+}
+
+void prov_auth_destroy(PROV_AUTH_HANDLE handle)
+{
+    /* Codes_SRS_PROV_AUTH_CLIENT_07_005: [ if handle is NULL, prov_auth_destroy shall do nothing. ] */
+    if (handle != NULL)
+    {
+        /* Codes_SRS_PROV_AUTH_CLIENT_07_007: [ prov_auth_destroy shall free all resources allocated in this module. ] */
+        free(handle->registration_id);
+        handle->hsm_client_destroy(handle->hsm_client_handle);
+        /* Codes_SRS_PROV_AUTH_CLIENT_07_006: [ prov_auth_destroy shall free the PROV_AUTH_HANDLE instance. ] */
+        free(handle);
+    }
+}
+
+PROV_AUTH_TYPE prov_auth_get_type(PROV_AUTH_HANDLE handle)
+{
+    PROV_AUTH_TYPE result;
+    /* Codes_SRS_PROV_AUTH_CLIENT_07_008: [ if handle is NULL prov_auth_get_type shall return PROV_AUTH_TYPE_UNKNOWN ] */
+    if (handle == NULL)
+    {
+        LogError("Invalid handle specified");
+        result = PROV_AUTH_TYPE_UNKNOWN;
+    }
+    else
+    {
+        /* Codes_SRS_PROV_AUTH_CLIENT_07_009: [ prov_auth_get_type shall return the PROV_AUTH_TYPE of the underlying secure enclave. ] */
+        result = handle->sec_type;
+    }
+    return result;
+}
+
+char* prov_auth_get_registration_id(PROV_AUTH_HANDLE handle)
+{
+    char* result;
+    if (handle == NULL)
+    {
+        /* Codes_SRS_PROV_AUTH_CLIENT_07_010: [ if handle is NULL prov_auth_get_registration_id shall return NULL. ] */
+        LogError("Invalid handle parameter");
+        result = NULL;
+    }
+    else
+    {
+        int load_result = 0;
+        int reg_id_allocated = 0;
+        if (handle->registration_id == NULL)
+        {
+            /* Codes_SRS_PROV_AUTH_CLIENT_07_011: [ prov_auth_get_registration_id shall load the registration id if it has not been previously loaded. ] */
+            load_result = load_registration_id(handle);
+            if (load_result == 0)
+            {
+                reg_id_allocated = 1;
+            }
+        }
+
+        if (load_result != 0)
+        {
+            /* Codes_SRS_PROV_AUTH_CLIENT_07_012: [ If a failure is encountered, prov_auth_get_registration_id shall return NULL. ] */
+            LogError("Failed loading registration key");
+            result = NULL;
+        }
+        /* Codes_SRS_PROV_AUTH_CLIENT_07_013: [ Upon success prov_auth_get_registration_id shall return the registration id of the secure enclave. ] */
+        else if (mallocAndStrcpy_s(&result, handle->registration_id) != 0)
+        {
+            /* Codes_SRS_PROV_AUTH_CLIENT_07_012: [ If a failure is encountered, prov_auth_get_registration_id shall return NULL. ] */
+            LogError("Failed allocating registration key");
+            if (reg_id_allocated == 1)
+            {
+                free(handle->registration_id);
+                handle->registration_id = NULL;
+            }
+            result = NULL;
+        }
+    }
+    return result;
+}
+
+int prov_auth_set_registration_id(PROV_AUTH_HANDLE handle, const char* registration_id)
+{
+    int result;
+    if (handle == NULL || registration_id == NULL)
+    {
+        LogError("Invalid parameter handle: %p, registration_id: %p", handle, registration_id);
+        result = MU_FAILURE;
+    }
+    else
+    {
+        if (handle->registration_id != NULL)
+        {
+            LogError("Registration_id has been previously set, registration can not be changed");
+            result = MU_FAILURE;
+        }
+        else if (mallocAndStrcpy_s(&handle->registration_id, registration_id) != 0)
+        {
+            LogError("Failed allocating registration key");
+            result = MU_FAILURE;
+        }
+        else
+        {
+            result = 0;
+        }
+    }
+    return result;
+}
+
+BUFFER_HANDLE prov_auth_get_endorsement_key(PROV_AUTH_HANDLE handle)
+{
+    BUFFER_HANDLE result;
+    if (handle == NULL)
+    {
+        /* Codes_SRS_SECURE_ENCLAVE_CLIENT_07_021: [ If handle is NULL prov_auth_get_endorsement_key shall return NULL. ] */
+        LogError("Invalid handle parameter");
+        result = NULL;
+    }
+    else if (handle->sec_type != PROV_AUTH_TYPE_TPM)
+    {
+        /* Codes_SRS_SECURE_ENCLAVE_CLIENT_07_023: [ If the sec_type is PROV_AUTH_TYPE_X509, prov_auth_get_endorsement_key shall return NULL. ] */
+        LogError("Invalid type for operation");
+        result = NULL;
+    }
+    else
+    {
+        unsigned char* ek_value;
+        size_t ek_len;
+
+        if (handle->hsm_client_get_endorsement_key(handle->hsm_client_handle, &ek_value, &ek_len) != 0)
+        {
+            LogError("Failed getting endorsement key");
+            result = NULL;
+        }
+        else
+        {
+            /* Codes_SRS_SECURE_ENCLAVE_CLIENT_07_022: [ prov_auth_get_endorsement_key shall return the endorsement key returned by the hsm_client_get_ek secure enclave function. ] */
+            result = BUFFER_create(ek_value, ek_len);
+            if (result == NULL)
+            {
+                LogError("Failed creating BUFFER HANDLE");
+            }
+            free(ek_value);
+        }
+    }
+    return result;
+}
+
+BUFFER_HANDLE prov_auth_get_storage_key(PROV_AUTH_HANDLE handle)
+{
+    BUFFER_HANDLE result;
+    /* Codes_SRS_SECURE_ENCLAVE_CLIENT_07_024: [ If handle is NULL prov_auth_get_storage_key shall return NULL. ] */
+    if (handle == NULL)
+    {
+        LogError("Invalid handle parameter");
+        result = NULL;
+    }
+    else if (handle->sec_type != PROV_AUTH_TYPE_TPM)
+    {
+        /* Codes_SRS_SECURE_ENCLAVE_CLIENT_07_026: [ If the sec_type is PROV_AUTH_TYPE_X509, prov_auth_get_storage_key shall return NULL. ] */
+        LogError("Invalid type for operation");
+        result = NULL;
+    }
+    else
+    {
+        unsigned char* srk_value;
+        size_t srk_len;
+
+        if (handle->hsm_client_get_srk(handle->hsm_client_handle, &srk_value, &srk_len) != 0)
+        {
+            LogError("Failed getting storage root key");
+            result = NULL;
+        }
+        else
+        {
+            /* Codes_SRS_SECURE_ENCLAVE_CLIENT_07_025: [ prov_auth_get_storage_key shall return the endorsement key returned by the hsm_client_get_srk secure enclave function. ] */
+            result = BUFFER_create(srk_value, srk_len);
+            if (result == NULL)
+            {
+                LogError("Failed creating BUFFER HANDLE");
+            }
+            free(srk_value);
+        }
+    }
+    return result;
+}
+
+int prov_auth_import_key(PROV_AUTH_HANDLE handle, const unsigned char* key_value, size_t key_len)
+{
+    int result;
+    if (handle == NULL || key_value == NULL || key_len == 0)
+    {
+        /* Codes_SRS_SECURE_ENCLAVE_CLIENT_07_027: [ If handle or key are NULL prov_auth_import_key shall return a non-zero value. ] */
+        LogError("Invalid handle parameter");
+        result = MU_FAILURE;
+    }
+    else if (handle->sec_type != PROV_AUTH_TYPE_TPM)
+    {
+        /* Codes_SRS_SECURE_ENCLAVE_CLIENT_07_029: [ If the sec_type is not SECURE_ENCLAVE_TYPE_TPM, prov_auth_import_key shall return NULL. ] */
+        LogError("Invalid type for operation");
+        result = MU_FAILURE;
+    }
+    else
+    {
+        /* Codes_SRS_SECURE_ENCLAVE_CLIENT_07_028: [ prov_auth_import_key shall import the specified key into the tpm using hsm_client_import_key secure enclave function. ] */
+        if (handle->hsm_client_import_key(handle->hsm_client_handle, key_value, key_len) != 0)
+        {
+            /* SRS_SECURE_ENCLAVE_CLIENT_07_040: [ If hsm_client_import_key returns an error prov_auth_import_key shall return a non-zero value. ]*/
+            LogError("failure importing key into tpm");
+            result = MU_FAILURE;
+        }
+        else
+        {
+            result = 0;
+        }
+    }
+    return result;
+}
+
+char* prov_auth_construct_sas_token(PROV_AUTH_HANDLE handle, const char* token_scope, const char* key_name, size_t expiry_time)
+{
+    char* result;
+    char expire_token[64] = { 0 };
+
+    if (handle == NULL || token_scope == NULL || key_name == NULL)
+    {
+        LogError("Invalid handle parameter handle: %p, token_scope: %p, key_name: %p", handle, token_scope, key_name);
+        result = NULL;
+    }
+    else if (handle->sec_type == PROV_AUTH_TYPE_X509)
+    {
+        LogError("Invalid type for operation");
+        result = NULL;
+    }
+    else if (size_tToString(expire_token, sizeof(expire_token), expiry_time) != 0)
+    {
+        result = NULL;
+        LogError("Failure creating expire token");
+    }
+    else
+    {
+        size_t len = strlen(token_scope) + strlen(expire_token) + 3;
+        char* payload = malloc(len + 1);
+        if (payload == NULL)
+        {
+            result = NULL;
+            LogError("Failure allocating payload for sas token.");
+        }
+        else
+        {
+            unsigned char* data_value;
+            size_t data_len;
+            (void)sprintf(payload, "%s\n%s", token_scope, expire_token);
+
+            /* Codes_SRS_SECURE_ENCLAVE_CLIENT_07_031: [ prov_auth_get_certificate shall import the specified cert into the client using hsm_client_get_cert secure enclave function. ] */
+            if (sign_sas_data(handle, payload, &data_value, &data_len) == 0)
+            {
+                STRING_HANDLE urlEncodedSignature;
+                STRING_HANDLE base64Signature;
+                STRING_HANDLE sas_token_handle;
+                if ((base64Signature = Azure_Base64_Encode_Bytes(data_value, data_len)) == NULL)
+                {
+                    result = NULL;
+                    LogError("Failure constructing base64 encoding.");
+                }
+                else if ((urlEncodedSignature = URL_Encode(base64Signature)) == NULL)
+                {
+                    result = NULL;
+                    LogError("Failure constructing url Signature.");
+                    STRING_delete(base64Signature);
+                }
+                else
+                {
+                    sas_token_handle = STRING_construct_sprintf("SharedAccessSignature sr=%s&sig=%s&se=%s&skn=%s", token_scope, STRING_c_str(urlEncodedSignature), expire_token, key_name);
+                    if (sas_token_handle == NULL)
+                    {
+                        result = NULL;
+                        LogError("Failure constructing url Signature.");
+                    }
+                    else
+                    {
+                        const char* temp_sas_token = STRING_c_str(sas_token_handle);
+                        if (mallocAndStrcpy_s(&result, temp_sas_token) != 0)
+                        {
+                            LogError("Failure allocating and copying string.");
+                            result = NULL;
+                        }
+                        STRING_delete(sas_token_handle);
+                    }
+                    STRING_delete(base64Signature);
+                    STRING_delete(urlEncodedSignature);
+                }
+                free(data_value);
+            }
+            else
+            {
+                result = NULL;
+                LogError("Failure generate sas token.");
+            }
+            free(payload);
+        }
+    }
+    return result;
+}
+
+char* prov_auth_get_certificate(PROV_AUTH_HANDLE handle)
+{
+    char* result;
+    if (handle == NULL)
+    {
+        /* Codes_SRS_SECURE_ENCLAVE_CLIENT_07_030: [ If handle or key are NULL prov_auth_get_certificate shall return a non-zero value. ] */
+        LogError("Invalid handle parameter");
+        result = NULL;
+    }
+    else if (handle->sec_type != PROV_AUTH_TYPE_X509)
+    {
+        /* Codes_SRS_SECURE_ENCLAVE_CLIENT_07_032: [ If the sec_type is not PROV_AUTH_TYPE_X509, prov_auth_get_certificate shall return NULL. ] */
+        LogError("Invalid type for operation");
+        result = NULL;
+    }
+    else
+    {
+        /* Codes_SRS_SECURE_ENCLAVE_CLIENT_07_031: [ prov_auth_get_certificate shall import the specified cert into the client using hsm_client_get_cert secure enclave function. ] */
+        result = handle->hsm_client_get_cert(handle->hsm_client_handle);
+    }
+    return result;
+}
+
+char* prov_auth_get_alias_key(PROV_AUTH_HANDLE handle)
+{
+    char* result;
+    if (handle == NULL)
+    {
+        /* Codes_SRS_SECURE_ENCLAVE_CLIENT_07_033: [ If handle or key are NULL prov_auth_get_alias_key shall return a non-zero value. ] */
+        LogError("Invalid handle parameter");
+        result = NULL;
+    }
+    else if (handle->sec_type != PROV_AUTH_TYPE_X509)
+    {
+        /* Codes_SRS_SECURE_ENCLAVE_CLIENT_07_035: [ If the sec_type is not PROV_AUTH_TYPE_X509, prov_auth_get_alias_key shall return NULL. ] */
+        LogError("Invalid type for operation");
+        result = NULL;
+    }
+    else
+    {
+        /* Codes_SRS_SECURE_ENCLAVE_CLIENT_07_034: [ prov_auth_get_alias_key shall import the specified alias key into the client using hsm_client_get_ak secure enclave function. ] */
+        result = handle->hsm_client_get_alias_key(handle->hsm_client_handle);
+    }
+    return result;
+}
Index: azure_iot_hub_f767zi/trunk/azure_iot_sdk/provisioning_client/src/prov_device_client.c
===================================================================
--- azure_iot_hub_f767zi/trunk/azure_iot_sdk/provisioning_client/src/prov_device_client.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/azure_iot_sdk/provisioning_client/src/prov_device_client.c	(revision 457)
@@ -0,0 +1,316 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+#include <stdlib.h>
+
+#include <signal.h>
+#include "azure_c_shared_utility/gballoc.h"
+#include "azure_c_shared_utility/threadapi.h"
+#include "azure_c_shared_utility/lock.h"
+#include "azure_c_shared_utility/xlogging.h"
+
+#include "azure_prov_client/prov_device_ll_client.h"
+#include "azure_prov_client/prov_device_client.h"
+#include "azure_c_shared_utility/vector.h"
+
+#define DO_WORK_FREQ_DEFAULT 1
+
+static const char* const OPTION_DO_WORK_FREQUENCY_IN_MS = "do_work_freq_ms";
+
+typedef struct PROV_DEVICE_INSTANCE_TAG
+{
+    PROV_DEVICE_LL_HANDLE ProvDeviceLLHandle;
+    THREAD_HANDLE ThreadHandle;
+    LOCK_HANDLE LockHandle;
+    sig_atomic_t StopThread;
+    uint16_t do_work_freq_ms;
+} PROV_DEVICE_INSTANCE;
+
+static int ScheduleWork_Thread(void* threadArgument)
+{
+    PROV_DEVICE_INSTANCE* prov_device_instance = (PROV_DEVICE_INSTANCE*)threadArgument;
+    uint16_t sleeptime_in_ms = DO_WORK_FREQ_DEFAULT;
+
+    srand((unsigned int)get_time(NULL));
+
+    while (1)
+    {
+        if (Lock(prov_device_instance->LockHandle) == LOCK_OK)
+        {
+            if (prov_device_instance->StopThread)
+            {
+                (void)Unlock(prov_device_instance->LockHandle);
+                break; /*gets out of the thread*/
+            }
+            else
+            {
+                Prov_Device_LL_DoWork(prov_device_instance->ProvDeviceLLHandle);
+                sleeptime_in_ms = prov_device_instance->do_work_freq_ms; // Update the sleepval within the locked thread. 
+                (void)Unlock(prov_device_instance->LockHandle);
+            }
+        }
+        else
+        {
+            LogError("Lock failed, shall retry");
+        }
+        (void)ThreadAPI_Sleep(sleeptime_in_ms);
+    }
+
+    ThreadAPI_Exit(0);
+    return 0;
+}
+
+static PROV_DEVICE_RESULT StartWorkerThreadIfNeeded(PROV_DEVICE_INSTANCE* prov_device_instance)
+{
+    PROV_DEVICE_RESULT result;
+    if (prov_device_instance->ThreadHandle == NULL)
+    {
+        prov_device_instance->StopThread = 0;
+        if (ThreadAPI_Create(&prov_device_instance->ThreadHandle, ScheduleWork_Thread, prov_device_instance) != THREADAPI_OK)
+        {
+            LogError("ThreadAPI_Create failed");
+            result = PROV_DEVICE_RESULT_ERROR;
+        }
+        else
+        {
+            result = PROV_DEVICE_RESULT_OK;
+        }
+    }
+    else
+    {
+        result = PROV_DEVICE_RESULT_OK;
+    }
+    return result;
+}
+
+PROV_DEVICE_HANDLE Prov_Device_Create(const char* uri, const char* id_scope, PROV_DEVICE_TRANSPORT_PROVIDER_FUNCTION protocol)
+{
+    PROV_DEVICE_INSTANCE* result;
+
+    /* Codes_SRS_PROV_DEVICE_CLIENT_12_001: [ If any of the input parameter is NULL `Prov_Device_Create` shall return NULL.] */
+    if (uri == NULL || id_scope == NULL || protocol == NULL)
+    {
+        LogError("Invalid parameter specified uri: %p, id_scope: %p, protocol: %p", uri, id_scope, protocol);
+        result = NULL;
+    }
+    else
+    {
+        /* Codes_SRS_PROV_DEVICE_CLIENT_12_002: [ The function shall allocate memory for PROV_DEVICE_INSTANCE data structure. ] */
+        result = (PROV_DEVICE_INSTANCE*)malloc(sizeof(PROV_DEVICE_INSTANCE));
+        if (result == NULL)
+        {
+            /* Codes_SRS_PROV_DEVICE_CLIENT_12_003: [ If the memory allocation failed the function shall return NULL. ] */
+            LogError("Unable to allocate Instance Info");
+        }
+        else
+        {
+            memset(result, 0, sizeof(PROV_DEVICE_INSTANCE) );
+            /* Codes_SRS_PROV_DEVICE_CLIENT_12_004: [ The function shall initialize the Lock. ] */
+            result->LockHandle = Lock_Init();
+            if (result->LockHandle == NULL)
+            {
+                /* Codes_SRS_PROV_DEVICE_CLIENT_12_005: [ If the Lock initialization failed the function shall clean up the all resources and return NULL. ] */
+                LogError("Lock_Init failed");
+                free(result);
+                result = NULL;
+            }
+            else
+            {
+                /* Codes_SRS_PROV_DEVICE_CLIENT_12_006: [ The function shall call the LL layer Prov_Device_LL_Create function and return with it's result. ] */
+                result->ProvDeviceLLHandle = Prov_Device_LL_Create(uri, id_scope, protocol);
+                if (result->ProvDeviceLLHandle == NULL)
+                {
+                    /* Codes_SRS_PROV_DEVICE_CLIENT_12_025: [ If the Client initialization failed the function shall clean up the all resources and return NULL. ] */
+                    LogError("Prov_Device_LL_Create failed");
+                    free(result);
+                    result = NULL;
+                }
+                else
+                {
+                    /* Codes_SRS_PROV_DEVICE_CLIENT_12_007: [ The function shall initialize the result datastructure. ] */
+                    result->ThreadHandle = NULL;
+                    result->StopThread = 0;
+                    result->do_work_freq_ms = DO_WORK_FREQ_DEFAULT;
+                }
+            }
+        }
+    }
+
+    return result;
+}
+
+void Prov_Device_Destroy(PROV_DEVICE_HANDLE prov_device_handle)
+{
+    /* Codes_SRS_PROV_DEVICE_CLIENT_12_008: [ If the input parameter is NULL `Prov_Device_Destroy` shall return. ] */
+    if (prov_device_handle == NULL)
+    {
+        LogError("NULL prov_device_handle");
+    }
+    else
+    {
+        PROV_DEVICE_INSTANCE* prov_device_instance = (PROV_DEVICE_INSTANCE*)prov_device_handle;
+
+        if (Lock(prov_device_handle->LockHandle) != LOCK_OK)
+        {
+            /* Codes_SRS_PROV_DEVICE_CLIENT_12_009: [ The function shall check the Lock status and if it is not OK set the thread signal to stop. ] */
+            LogError("Could not acquire lock");
+            prov_device_handle->StopThread = 1; /*setting it even when Lock fails*/
+        }
+        else
+        {
+            /* Codes_SRS_PROV_DEVICE_CLIENT_12_010: [ The function shall check the Lock status and if it is OK set the thread signal to stop and unlock the Lock. ] */
+            prov_device_handle->StopThread = 1;
+
+            (void)Unlock(prov_device_handle->LockHandle);
+        }
+
+        /* Codes_SRS_PROV_DEVICE_CLIENT_12_011: [ If there is a running worker thread the function shall call join to finish. ] */
+        if (prov_device_handle->ThreadHandle != NULL)
+        {
+            int res;
+            if (ThreadAPI_Join(prov_device_handle->ThreadHandle, &res) != THREADAPI_OK)
+            {
+                LogError("ThreadAPI_Join failed");
+            }
+        }
+
+        /* Codes_SRS_PROV_DEVICE_CLIENT_12_012: [ The function shall call the LL layer Prov_Device_LL_Destroy with the given handle. ] */
+        Prov_Device_LL_Destroy(prov_device_instance->ProvDeviceLLHandle);
+
+        /* Codes_SRS_PROV_DEVICE_CLIENT_12_013: [ The function shall free the Lock resource with de-init. ] */
+        Lock_Deinit(prov_device_instance->LockHandle);
+
+        /* Codes_SRS_PROV_DEVICE_CLIENT_12_014: [ The function shall free the device handle resource. ] */
+        free(prov_device_instance);
+    }
+}
+
+PROV_DEVICE_RESULT Prov_Device_Register_Device(PROV_DEVICE_HANDLE prov_device_handle, PROV_DEVICE_CLIENT_REGISTER_DEVICE_CALLBACK register_callback, void* user_context, PROV_DEVICE_CLIENT_REGISTER_STATUS_CALLBACK register_status_callback, void* status_user_context)
+{
+    PROV_DEVICE_RESULT result;
+
+    /* Codes_SRS_PROV_DEVICE_CLIENT_12_015: [ If the prov_device_handle or register_callback input parameter is NULL `Prov_Device_Register_Device` shall return with invalid argument error. ] */
+    if (prov_device_handle == NULL || register_callback == NULL)
+    {
+        LogError("Invalid parameter specified prov_device_handle: %p, register_callback: %p", prov_device_handle, register_callback);
+        result = PROV_DEVICE_RESULT_INVALID_ARG;
+    }
+    else
+    {
+        PROV_DEVICE_INSTANCE* prov_device_instance = (PROV_DEVICE_INSTANCE*)prov_device_handle;
+
+        /* Codes_SRS_PROV_DEVICE_CLIENT_12_018: [ The function shall try to lock the Lock. ] */
+        if (Lock(prov_device_instance->LockHandle) != LOCK_OK)
+        {
+            /* Codes_SRS_PROV_DEVICE_CLIENT_12_019: [ If the locking failed the function shall return with error. ] */
+            LogError("Could not acquire lock");
+            result = PROV_DEVICE_RESULT_ERROR;
+        }
+        else
+        {
+            /* Codes_SRS_PROV_DEVICE_CLIENT_12_020: [ The function shall call the LL layer Prov_Device_LL_Register_Device with the given parameters and return with the result. ] */
+            result = Prov_Device_LL_Register_Device(prov_device_instance->ProvDeviceLLHandle, register_callback, user_context, register_status_callback, status_user_context);
+
+            /* Codes_SRS_PROV_DEVICE_CLIENT_12_021: [ The function shall unlock the Lock. ] */
+            (void)Unlock(prov_device_instance->LockHandle);
+
+            if (result == PROV_DEVICE_RESULT_OK)
+            {
+                /* Codes_SRS_PROV_DEVICE_CLIENT_12_016: [ The function shall start a worker thread with the device instance. ] */
+                if ((result = StartWorkerThreadIfNeeded(prov_device_instance)) != PROV_DEVICE_RESULT_OK)
+                {
+                    /* Codes_SRS_PROV_DEVICE_CLIENT_12_017: [ If the thread initialization failed the function shall return error. ] */
+                    LogError("Could not start worker thread");
+                    result = PROV_DEVICE_RESULT_ERROR;
+                }
+            }
+        }
+    }
+
+    return result;
+}
+
+PROV_DEVICE_RESULT Prov_Device_SetOption(PROV_DEVICE_HANDLE prov_device_handle, const char* optionName, const void* value)
+{
+    PROV_DEVICE_RESULT result;
+
+    /* Codes_SRS_PROV_DEVICE_CLIENT_12_022: [ If any of the input parameter is NULL `Prov_Device_SetOption` shall return with invalid argument error. ] */
+    if (
+        (prov_device_handle == NULL) || 
+        (optionName == NULL) || 
+        (value == NULL)
+        )
+    {
+        result = PROV_DEVICE_RESULT_INVALID_ARG;
+        LogError("Invalid parameter specified prov_device_handle: %p, optionName: %p, value: %p", prov_device_handle, optionName, value);
+    }
+    else 
+    {
+        /* Codes_SRS_PROV_DEVICE_CLIENT_12_023: [ The function shall call the LL layer Prov_Device_LL_SetOption with the given parameters and return with the result. ] */
+        PROV_DEVICE_INSTANCE* prov_device_instance = (PROV_DEVICE_INSTANCE*)prov_device_handle;
+
+        /* Codes_SRS_PROV_DEVICE_CLIENT_41_002: [ `Prov_Device_SetOption` shall be made thread-safe by using the lock created in `Prov_Device_Create`. ] */
+        if (Lock(prov_device_instance->LockHandle) != LOCK_OK)
+        {
+            /* Codes_SRS_PROV_DEVICE_CLIENT_41_003: [ If acquiring the lock fails, `Prov_Device_SetOption` shall return `IOTHUB_CLIENT_ERROR`. ] */
+            result = PROV_DEVICE_RESULT_ERROR;
+            LogError("Could not acquire lock");
+        }
+        else 
+        {
+            /* Codes_SRS_PROV_DEVICE_CLIENT_41_001: [ If parameter `optionName` is `OPTION_DO_WORK_FREQUENCY_IN_MS` then `IoTHubClientCore_SetOption` shall set `do_work_freq_ms` parameter of `prov_device_instance` ] */
+            if (strcmp(OPTION_DO_WORK_FREQUENCY_IN_MS, optionName) == 0)
+            {
+                prov_device_instance->do_work_freq_ms = *((uint16_t *)value);
+                result = PROV_DEVICE_RESULT_OK;  
+            }
+            else 
+            {
+                result = Prov_Device_LL_SetOption(prov_device_instance->ProvDeviceLLHandle, optionName, value);
+                if (result != PROV_DEVICE_RESULT_OK)
+                {
+                    LogError("Prov_Device_LL_SetOption failed");
+                }
+            }
+            (void)Unlock(prov_device_instance->LockHandle);
+        }
+    }
+    return result;
+}
+
+const char* Prov_Device_GetVersionString(void)
+{
+    /* Codes_SRS_PROV_DEVICE_CLIENT_12_024: [ The function shall call the LL layer Prov_Device_LL_GetVersionString and return with the result. ] */
+    return Prov_Device_LL_GetVersionString();
+}
+
+PROV_DEVICE_RESULT Prov_Device_Set_Provisioning_Payload(PROV_DEVICE_HANDLE handle, const char* json)
+{
+    PROV_DEVICE_RESULT result;
+    if (handle == NULL)
+    {
+        LogError("Invalid parameter specified handle: %p", handle);
+        result = PROV_DEVICE_RESULT_INVALID_ARG;
+    }
+    else
+    {
+        result = Prov_Device_LL_Set_Provisioning_Payload(handle->ProvDeviceLLHandle, json);
+    }
+    return result;
+}
+
+const char* Prov_Device_Get_Provisioning_Payload(PROV_DEVICE_HANDLE handle)
+{
+    const char* result;
+    if (handle == NULL)
+    {
+        LogError("Invalid parameter specified handle: %p", handle);
+        result = NULL;
+    }
+    else
+    {
+        result = Prov_Device_LL_Get_Provisioning_Payload(handle->ProvDeviceLLHandle);
+    }
+    return result;
+}
+
Index: azure_iot_hub_f767zi/trunk/azure_iot_sdk/provisioning_client/src/prov_device_ll_client.c
===================================================================
--- azure_iot_hub_f767zi/trunk/azure_iot_sdk/provisioning_client/src/prov_device_ll_client.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/azure_iot_sdk/provisioning_client/src/prov_device_ll_client.c	(revision 457)
@@ -0,0 +1,1391 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+#include <stdlib.h>
+#include <stdbool.h>
+#include <stdint.h>
+
+#include "parson.h"
+
+#include "azure_c_shared_utility/gballoc.h"
+#include "azure_c_shared_utility/xlogging.h"
+#include "azure_c_shared_utility/strings.h"
+#include "azure_c_shared_utility/buffer_.h"
+#include "azure_c_shared_utility/uniqueid.h"
+#include "azure_c_shared_utility/sastoken.h"
+#include "azure_c_shared_utility/crt_abstractions.h"
+#include "azure_c_shared_utility/azure_base64.h"
+#include "azure_c_shared_utility/urlencode.h"
+#include "azure_c_shared_utility/shared_util_options.h"
+#include "azure_c_shared_utility/tickcounter.h"
+
+#include "azure_prov_client/internal/prov_auth_client.h"
+#include "azure_prov_client/internal/prov_transport_private.h"
+#include "azure_prov_client/prov_device_ll_client.h"
+#include "azure_prov_client/prov_client_const.h"
+
+static const char* const OPTION_LOG_TRACE = "logtrace";
+
+static const char* const JSON_NODE_STATUS = "status";
+static const char* const JSON_NODE_REG_STATUS = "registrationState";
+static const char* const JSON_NODE_AUTH_KEY = "authenticationKey";
+static const char* const JSON_NODE_DEVICE_ID = "deviceId";
+static const char* const JSON_NODE_KEY_NAME = "keyName";
+static const char* const JSON_NODE_OPERATION_ID = "operationId";
+static const char* const JSON_NODE_ASSIGNED_HUB = "assignedHub";
+static const char* const JSON_NODE_TPM_NODE = "tpm";
+static const char* const JSON_NODE_DATE_TIME = "lastUpdatedDateTimeUtc";
+static const char* const JSON_NODE_ERROR_MSG = "errorMessage";
+static const char* const JSON_NODE_ERROR_CODE = "errorCode";
+static const char* const PROV_FAILED_STATUS = "failed";
+static const char* const PROV_BLACKLISTED_STATUS = "blacklisted";
+static const char* const JSON_CUSTOM_DATA_TAG = "payload";
+static const char* const JSON_NODE_RETURNED_DATA = "payload";
+
+static const char* const SAS_TOKEN_SCOPE_FMT = "%s/registrations/%s";
+
+static const char* const REGISTRATION_ID = "registrationId";
+static const char* const JSON_ENDORSMENT_KEY_NODE = "endorsementKey";
+static const char* const JSON_STORAGE_ROOT_KEY_NODE = "storageRootKey";
+
+#define DPS_HUB_ERROR_NO_HUB        400208
+#define DPS_HUB_ERROR_UNAUTH        400209
+
+#define SAS_TOKEN_DEFAULT_LIFETIME  2400
+#define EPOCH_TIME_T_VALUE          (time_t)0
+#define MAX_AUTH_ATTEMPTS           3
+#define PROV_DEFAULT_TIMEOUT        60
+
+typedef enum CLIENT_STATE_TAG
+{
+    CLIENT_STATE_READY,
+
+    CLIENT_STATE_REGISTER_SEND,
+    CLIENT_STATE_REGISTER_SENT,
+    CLIENT_STATE_REGISTER_RECV,
+
+    CLIENT_STATE_STATUS_SEND,
+    CLIENT_STATE_STATUS_SENT,
+    CLIENT_STATE_STATUS_RECV,
+
+    CLIENT_STATE_ERROR
+} CLIENT_STATE;
+
+typedef struct IOTHUB_REQ_INFO_TAG
+{
+    char* iothub_url;
+    char* iothub_key;
+    char* device_id;
+} IOTHUB_REQ_INFO;
+
+typedef struct PROV_INSTANCE_INFO_TAG
+{
+    PROV_DEVICE_CLIENT_REGISTER_DEVICE_CALLBACK register_callback;
+    void* user_context;
+    PROV_DEVICE_CLIENT_REGISTER_STATUS_CALLBACK register_status_cb;
+    void* status_user_ctx;
+    PROV_DEVICE_RESULT error_reason;
+
+    const PROV_DEVICE_TRANSPORT_PROVIDER* prov_transport_protocol;
+    PROV_DEVICE_TRANSPORT_HANDLE transport_handle;
+    bool transport_open;
+
+    TICK_COUNTER_HANDLE tick_counter;
+
+    tickcounter_ms_t status_throttle;
+    tickcounter_ms_t timeout_value;
+    uint32_t retry_after_value;
+
+    uint8_t prov_timeout;
+
+    char* registration_id;
+    bool user_supplied_reg_id;
+
+    PROV_AUTH_HANDLE prov_auth_handle;
+
+    bool is_connected;
+
+    PROV_AUTH_TYPE hsm_type;
+
+    IOTHUB_REQ_INFO iothub_info;
+
+    CLIENT_STATE prov_state;
+
+    size_t auth_attempts_made;
+
+    char* scope_id;
+
+    char* custom_request_data;
+    char* custom_response_data;
+} PROV_INSTANCE_INFO;
+
+static char* prov_transport_challenge_callback(const unsigned char* nonce, size_t nonce_len, const char* key_name, void* user_ctx)
+{
+    char* result;
+    if (user_ctx == NULL)
+    {
+        LogError("Bad argument user_ctx is NULL");
+        result = NULL;
+    }
+    else
+    {
+        PROV_INSTANCE_INFO* prov_info = (PROV_INSTANCE_INFO*)user_ctx;
+        if ((prov_info->hsm_type == PROV_AUTH_TYPE_TPM) && nonce == NULL)
+        {
+            LogError("Bad argument nonce is NULL");
+            result = NULL;
+        }
+        else
+        {
+            char* token_scope;
+            size_t token_scope_len;
+
+            size_t sec_since_epoch = (size_t)(difftime(get_time(NULL), EPOCH_TIME_T_VALUE) + 0);
+            size_t expiry_time = sec_since_epoch + SAS_TOKEN_DEFAULT_LIFETIME;
+
+            // Construct Token scope
+            token_scope_len = strlen(SAS_TOKEN_SCOPE_FMT) + strlen(prov_info->scope_id) + strlen(prov_info->registration_id);
+
+            token_scope = malloc(token_scope_len + 1);
+            if (token_scope == NULL)
+            {
+                LogError("Failure to allocate token scope");
+                result = NULL;
+            }
+            else if (sprintf(token_scope, SAS_TOKEN_SCOPE_FMT, prov_info->scope_id, prov_info->registration_id) <= 0)
+            {
+                LogError("Failure to constructing token_scope");
+                free(token_scope);
+                result = NULL;
+            }
+            else
+            {
+                STRING_HANDLE encoded_token = URL_EncodeString(token_scope);
+                if (encoded_token == NULL)
+                {
+                    LogError("Failure to url encoding string");
+                    result = NULL;
+                }
+                else
+                {
+                    if (prov_info->hsm_type == PROV_AUTH_TYPE_TPM && (prov_auth_import_key(prov_info->prov_auth_handle, nonce, nonce_len) != 0))
+                    {
+                        LogError("Failure to import the provisioning key");
+                        result = NULL;
+                    }
+                    else
+                    {
+                        if ((result = prov_auth_construct_sas_token(prov_info->prov_auth_handle, STRING_c_str(encoded_token), key_name, expiry_time)) == NULL)
+                        {
+                            LogError("Failure to import the provisioning key");
+                            result = NULL;
+                        }
+                    }
+                    STRING_delete(encoded_token);
+                }
+                free(token_scope);
+            }
+        }
+    }
+    return result;
+}
+
+static void on_transport_error(PROV_DEVICE_TRANSPORT_ERROR transport_error, void* user_ctx)
+{
+    if (user_ctx != NULL)
+    {
+        PROV_INSTANCE_INFO* prov_info = (PROV_INSTANCE_INFO*)user_ctx;
+        switch (transport_error)
+        {
+            case PROV_DEVICE_ERROR_KEY_FAIL:
+                prov_info->error_reason = PROV_DEVICE_RESULT_KEY_ERROR;
+                break;
+            case PROV_DEVICE_ERROR_KEY_UNAUTHORIZED:
+                prov_info->error_reason = PROV_DEVICE_RESULT_DEV_AUTH_ERROR;
+                break;
+
+            case PROV_DEVICE_ERROR_MEMORY:
+                prov_info->error_reason = PROV_DEVICE_RESULT_MEMORY;
+                break;
+        }
+    }
+}
+
+static PROV_DEVICE_TRANSPORT_STATUS retrieve_status_type(const char* prov_status)
+{
+    PROV_DEVICE_TRANSPORT_STATUS result;
+    if (strcmp(prov_status, PROV_UNASSIGNED_STATUS) == 0)
+    {
+        result = PROV_DEVICE_TRANSPORT_STATUS_UNASSIGNED;
+    }
+    else if (strcmp(prov_status, PROV_ASSIGNING_STATUS) == 0)
+    {
+        result = PROV_DEVICE_TRANSPORT_STATUS_ASSIGNING;
+    }
+    else if (strcmp(prov_status, PROV_ASSIGNED_STATUS) == 0)
+    {
+        result = PROV_DEVICE_TRANSPORT_STATUS_ASSIGNED;
+    }
+    else if (strcmp(prov_status, PROV_FAILED_STATUS) == 0)
+    {
+        result = PROV_DEVICE_TRANSPORT_STATUS_ERROR;
+    }
+    else if (strcmp(prov_status, PROV_BLACKLISTED_STATUS) == 0)
+    {
+        result = PROV_DEVICE_TRANSPORT_STATUS_BLACKLISTED;
+    }
+    else if (strcmp(prov_status, PROV_DISABLE_STATUS) == 0)
+    {
+        result = PROV_DEVICE_TRANSPORT_STATUS_DISABLED;
+    }
+    else
+    {
+        result = PROV_DEVICE_TRANSPORT_STATUS_ERROR;
+    }
+    return result;
+}
+
+static int retrieve_json_number(JSON_Object* json_object, const char* field_name)
+{
+    int result;
+    JSON_Value* json_field;
+    if ((json_field = json_object_get_value(json_object, field_name)) == NULL)
+    {
+        LogError("failure retrieving json operation id");
+        result = 0;
+    }
+    else
+    {
+        result = (int)json_value_get_number(json_field);
+    }
+    return result;
+}
+
+static void retrieve_json_payload(JSON_Object* json_object, PROV_INSTANCE_INFO* prov_info)
+{
+    JSON_Value* json_field;
+
+    // Returned Data is not available
+    if ((json_field = json_object_get_value(json_object, JSON_NODE_RETURNED_DATA)) != NULL)
+    {
+        prov_info->custom_response_data = json_serialize_to_string(json_field);
+    }
+}
+
+static char* retrieve_json_string(JSON_Object* json_object, const char* field_name, bool is_required)
+{
+    char* result;
+    JSON_Value* json_field;
+    if ((json_field = json_object_get_value(json_object, field_name)) == NULL)
+    {
+        if (is_required)
+        {
+            LogError("failure retrieving json object value %s", field_name);
+        }
+        result = NULL;
+    }
+    else
+    {
+        const char* json_item = json_value_get_string(json_field);
+        if (json_item != NULL)
+        {
+            if (mallocAndStrcpy_s(&result, json_item) != 0)
+            {
+                LogError("failure retrieving operation id");
+                result = NULL;
+            }
+        }
+        else
+        {
+            result = NULL;
+        }
+    }
+    return result;
+}
+
+static JSON_Value* construct_security_type_json(PROV_INSTANCE_INFO* prov_info, const char* ek_value, const char* srk_value)
+{
+    JSON_Value* result;
+
+    JSON_Object* json_object;
+    result = json_value_init_object();
+    if (result == NULL)
+    {
+        LogError("Failure constructing json information");
+    }
+    else if ((json_object = json_value_get_object(result)) == NULL)
+    {
+        LogError("failure retrieving node root object");
+        json_value_free(result);
+        result = NULL;
+    }
+    else
+    {
+        if (json_object_set_string(json_object, REGISTRATION_ID, prov_info->registration_id) != JSONSuccess)
+        {
+            LogError("failure setting registration Id json node");
+            json_value_free(result);
+            result = NULL;
+        }
+        else
+        {
+            if (prov_info->hsm_type == PROV_AUTH_TYPE_TPM)
+            {
+                // tpm_node value only gets released on failure
+                JSON_Object* tpm_object;
+                JSON_Value* tpm_node = json_value_init_object();
+                if (tpm_node == NULL)
+                {
+                    LogError("failure constructing json tpm object");
+                    json_value_free(tpm_node);
+                    json_value_free(result);
+                    result = NULL;
+                }
+                else if ((tpm_object = json_value_get_object(tpm_node)) == NULL)
+                {
+                    LogError("failure retrieving node root object");
+                    json_value_free(tpm_node);
+                    json_value_free(result);
+                    result = NULL;
+                }
+                else if (json_object_set_string(tpm_object, JSON_ENDORSMENT_KEY_NODE, ek_value) != JSONSuccess)
+                {
+                    LogError("failure setting endorsement key node");
+                    json_value_free(tpm_node);
+                    json_value_free(result);
+                    result = NULL;
+                }
+                else if (json_object_set_string(tpm_object, JSON_STORAGE_ROOT_KEY_NODE, srk_value) != JSONSuccess)
+                {
+                    LogError("failure setting tpm storage root key node");
+                    json_value_free(tpm_node);
+                    json_value_free(result);
+                    result = NULL;
+                }
+                else if (json_object_set_value(json_object, JSON_NODE_TPM_NODE, tpm_node) != JSONSuccess)
+                {
+                    LogError("failure constructing json tpm object");
+                    json_value_free(tpm_node);
+                    json_value_free(result);
+                    result = NULL;
+                }
+            }
+        }
+    }
+    return result;
+}
+
+static char* prov_transport_create_json_payload(const char* ek_value, const char* srk_value, void* user_ctx)
+{
+    char* result = NULL;
+    if (user_ctx == NULL)
+    {
+        LogError("failure user_ctx is NULL");
+    }
+    else
+    {
+        PROV_INSTANCE_INFO* prov_info = (PROV_INSTANCE_INFO*)user_ctx;
+
+        JSON_Value* json_root = construct_security_type_json(prov_info, ek_value, srk_value);
+        if (json_root == NULL)
+        {
+            LogError("Failure constructing security json");
+        }
+        else
+        {
+            bool error_encountered = false;
+            if (prov_info->custom_request_data != NULL)
+            {
+                JSON_Object* json_object;
+                JSON_Value* json_custom_data = NULL;
+
+                if ((json_object = json_value_get_object(json_root)) == NULL)
+                {
+                    LogError("failure retrieving node root object");
+                    error_encountered = true;
+                }
+                else if ((json_custom_data = json_parse_string(prov_info->custom_request_data)) == NULL)
+                {
+                    LogError("failure parsing custom info.  This custom info MUST be valid json");
+                    error_encountered = true;
+                }
+                // Success on json_object_set_value transfers ownership of json_custom_data to json_object, so do not
+                // explicitly free json_custom_data after this point.
+                else if (json_object_set_value(json_object, JSON_CUSTOM_DATA_TAG, json_custom_data) != JSONSuccess)
+                {
+                    LogError("failure setting %s value", JSON_CUSTOM_DATA_TAG);
+                    json_value_free(json_custom_data);
+                    error_encountered = true;
+                }
+            }
+
+            if (!error_encountered)
+            {
+                char* json_string = json_serialize_to_string(json_root);
+                if (json_string == NULL)
+                {
+                    LogError("failure serializing json to string");
+                }
+                else
+                {
+                    if (mallocAndStrcpy_s(&result, json_string) != 0)
+                    {
+                        LogError("failure constructing json result value");
+                    }
+                    json_free_serialized_string(json_string);
+                }
+            }
+            json_value_free(json_root);
+        }
+    }
+
+    return result;
+}
+
+static PROV_JSON_INFO* prov_transport_process_json_reply(const char* json_document, void* user_ctx)
+{
+    PROV_JSON_INFO* result;
+    JSON_Value* root_value;
+    JSON_Object* json_object;
+    if (user_ctx == NULL)
+    {
+        LogError("failure user_ctx is NULL");
+        result = NULL;
+    }
+    else if ((root_value = json_parse_string(json_document)) == NULL)
+    {
+        LogError("failure calling json_parse_string");
+        result = NULL;
+    }
+    else if ((json_object = json_value_get_object(root_value)) == NULL)
+    {
+        LogError("failure retrieving node root object");
+        json_value_free(root_value);
+        result = NULL;
+    }
+    else if ((result = malloc(sizeof(PROV_JSON_INFO))) == NULL)
+    {
+        LogError("failure allocating PROV_JSON_INFO");
+        json_value_free(root_value);
+    }
+    else
+    {
+        memset(result, 0, sizeof(PROV_JSON_INFO));
+        PROV_INSTANCE_INFO* prov_info = (PROV_INSTANCE_INFO*)user_ctx;
+        JSON_Value* json_status = json_object_get_value(json_object, JSON_NODE_STATUS);
+
+        if (json_status == NULL)
+        {
+            // Under TPM the status will be error if this is an authorization request.  We need to make it unassigned.
+            if (prov_info->hsm_type == PROV_AUTH_TYPE_TPM)
+            {
+                result->prov_status = PROV_DEVICE_TRANSPORT_STATUS_UNASSIGNED;
+            }
+            else
+            {
+                result->prov_status = PROV_DEVICE_TRANSPORT_STATUS_ERROR;
+            }
+        }
+        else
+        {
+            // status can be NULL
+            const char* json_string = json_value_get_string(json_status);
+            if (json_string == NULL)
+            {
+                result->prov_status = PROV_DEVICE_TRANSPORT_STATUS_ERROR;
+            }
+            else
+            {
+                result->prov_status = retrieve_status_type(json_string);
+            }
+        }
+        switch (result->prov_status)
+        {
+            case PROV_DEVICE_TRANSPORT_STATUS_UNASSIGNED:
+            {
+                JSON_Value* auth_key;
+                if ((auth_key = json_object_get_value(json_object, JSON_NODE_AUTH_KEY)) == NULL)
+                {
+                    LogError("failure retrieving json auth key value");
+                    prov_info->error_reason = PROV_DEVICE_RESULT_PARSING;
+                    free(result);
+                    result = NULL;
+                }
+                else
+                {
+                    const char* nonce_field = json_value_get_string(auth_key);
+                    if ((result->authorization_key = Azure_Base64_Decode(nonce_field)) == NULL)
+                    {
+                        LogError("failure creating buffer nonce field");
+                        prov_info->error_reason = PROV_DEVICE_RESULT_MEMORY;
+                        free(result);
+                        result = NULL;
+                    }
+                    else
+                    {
+                        result->key_name = retrieve_json_string(json_object, JSON_NODE_KEY_NAME, true);
+                        if (result->key_name == NULL)
+                        {
+                            LogError("failure retrieving keyname field");
+                            prov_info->error_reason = PROV_DEVICE_RESULT_PARSING;
+                            BUFFER_delete(result->authorization_key);
+                            free(result);
+                            result = NULL;
+                        }
+                    }
+                }
+                break;
+            }
+
+            case PROV_DEVICE_TRANSPORT_STATUS_ASSIGNING:
+                if ((result->operation_id = retrieve_json_string(json_object, JSON_NODE_OPERATION_ID, true)) == NULL)
+                {
+                    LogError("Failure: operation_id node is mising");
+                    prov_info->error_reason = PROV_DEVICE_RESULT_PARSING;
+                    free(result);
+                    result = NULL;
+                }
+                break;
+
+            case PROV_DEVICE_TRANSPORT_STATUS_ASSIGNED:
+            {
+                JSON_Object* json_reg_status_node;
+                if ((json_reg_status_node = json_object_get_object(json_object, JSON_NODE_REG_STATUS)) == NULL)
+                {
+                    LogError("failure retrieving json registration status node");
+                    prov_info->error_reason = PROV_DEVICE_RESULT_PARSING;
+                    free(result);
+                    result = NULL;
+                }
+                else
+                {
+                    if (prov_info->hsm_type == PROV_AUTH_TYPE_TPM)
+                    {
+                        JSON_Object* json_tpm_node;
+                        JSON_Value* auth_key;
+
+                        if ((json_tpm_node = json_object_get_object(json_reg_status_node, JSON_NODE_TPM_NODE)) == NULL)
+                        {
+                            LogError("failure retrieving tpm node json_tpm_node: %p, auth key: %p", json_tpm_node, result->authorization_key);
+                            free(result);
+                            prov_info->error_reason = PROV_DEVICE_RESULT_PARSING;
+                            result = NULL;
+                        }
+                        else if ((auth_key = json_object_get_value(json_tpm_node, JSON_NODE_AUTH_KEY)) == NULL)
+                        {
+                            LogError("failure retrieving json auth key value");
+                            free(result);
+                            prov_info->error_reason = PROV_DEVICE_RESULT_PARSING;
+                            result = NULL;
+                        }
+                        else
+                        {
+                            const char* nonce_field = json_value_get_string(auth_key);
+                            if (nonce_field == NULL)
+                            {
+                                LogError("failure getting nonce field from json");
+                                prov_info->error_reason = PROV_DEVICE_RESULT_MEMORY;
+                                free(result);
+                                result = NULL;
+                            }
+                            else if ((result->authorization_key = Azure_Base64_Decode(nonce_field)) == NULL)
+                            {
+                                LogError("failure creating buffer nonce field");
+                                prov_info->error_reason = PROV_DEVICE_RESULT_MEMORY;
+                                free(result);
+                                result = NULL;
+                            }
+                        }
+                    }
+
+                    if (result != NULL)
+                    {
+                        if (
+                            ((result->iothub_uri = retrieve_json_string(json_reg_status_node, JSON_NODE_ASSIGNED_HUB, true)) == NULL) ||
+                            ((result->device_id = retrieve_json_string(json_reg_status_node, JSON_NODE_DEVICE_ID, true)) == NULL)
+                            )
+                        {
+                            LogError("failure retrieving json value assigned_hub: %p, device_id: %p", result->iothub_uri, result->device_id);
+                            prov_info->error_reason = PROV_DEVICE_RESULT_PARSING;
+                            free(result->iothub_uri);
+                            free(result->authorization_key);
+                            free(result);
+                            result = NULL;
+                        }
+                        else
+                        {
+                            // Get the returned Data from the payload if it's there
+                            retrieve_json_payload(json_reg_status_node, prov_info);
+                        }
+                    }
+                }
+                break;
+            }
+
+            case PROV_DEVICE_TRANSPORT_STATUS_BLACKLISTED:
+                LogError("The device is unauthorized with service");
+                prov_info->error_reason = PROV_DEVICE_RESULT_ERROR;
+                free(result);
+                result = NULL;
+                break;
+
+            case PROV_DEVICE_TRANSPORT_STATUS_ERROR:
+            {
+                char* json_operation_id = NULL;
+                JSON_Object* json_reg_state = NULL;
+                if ((json_reg_state = json_object_get_object(json_object, JSON_NODE_REG_STATUS)) != NULL &&
+                    (json_operation_id = retrieve_json_string(json_object, JSON_NODE_OPERATION_ID, true)) != NULL)
+                {
+                    int error_code = retrieve_json_number(json_reg_state, JSON_NODE_ERROR_CODE);
+                    switch (error_code)
+                    {
+                        case DPS_HUB_ERROR_NO_HUB:
+                            prov_info->error_reason = PROV_DEVICE_RESULT_HUB_NOT_SPECIFIED;
+                            break;
+                        case DPS_HUB_ERROR_UNAUTH:
+                            prov_info->error_reason = PROV_DEVICE_RESULT_UNAUTHORIZED;
+                            break;
+                        default:
+                            prov_info->error_reason = PROV_DEVICE_RESULT_DEV_AUTH_ERROR;
+                            break;
+                    }
+#ifndef NO_LOGGING
+                    JSON_Value* json_error_date_time = NULL;
+                    JSON_Value* json_error_msg = NULL;
+                    if ((json_error_msg = json_object_get_value(json_reg_state, JSON_NODE_ERROR_MSG)) != NULL &&
+                        (json_error_date_time = json_object_get_value(json_reg_state, JSON_NODE_DATE_TIME)) != NULL)
+                    {
+                        LogError("Provisioning Failure: OperationId: %s - Date: %s - Msg: %s", json_operation_id, json_value_get_string(json_error_date_time), json_value_get_string(json_error_msg) );
+                    }
+                    else
+                    {
+                        LogError("Unsuccessful json encountered: %s", json_document);
+                    }
+                    free(json_operation_id);
+#endif
+                }
+                else
+                {
+                    prov_info->error_reason = PROV_DEVICE_RESULT_DEV_AUTH_ERROR;
+                    LogError("Unsuccessful json encountered: %s", json_document);
+                }
+                free(result);
+                result = NULL;
+                break;
+            }
+
+            case PROV_DEVICE_TRANSPORT_STATUS_DISABLED:
+                LogError("The device has been disabled by DPS service");
+                prov_info->error_reason = PROV_DEVICE_RESULT_DISABLED;
+                free(result);
+                result = NULL;
+                break;
+
+            default:
+                LogError("invalid json status specified %d", result->prov_status);
+                free(result);
+                result = NULL;
+                break;
+        }
+        json_value_free(root_value);
+    }
+    return result;
+}
+
+static void cleanup_prov_info(PROV_INSTANCE_INFO* prov_info)
+{
+    if (prov_info->transport_open)
+    {
+        prov_info->prov_transport_protocol->prov_transport_close(prov_info->transport_handle);
+        prov_info->transport_open = false;
+        prov_info->is_connected = false;
+    }
+    free(prov_info->registration_id);
+    prov_info->registration_id = NULL;
+    free(prov_info->iothub_info.device_id);
+    prov_info->iothub_info.device_id = NULL;
+    free(prov_info->iothub_info.iothub_key);
+    prov_info->iothub_info.iothub_key = NULL;
+    free(prov_info->iothub_info.iothub_url);
+    prov_info->iothub_info.iothub_url = NULL;
+    prov_info->auth_attempts_made = 0;
+}
+
+static void on_transport_registration_data(PROV_DEVICE_TRANSPORT_RESULT transport_result, BUFFER_HANDLE iothub_key, const char* assigned_hub, const char* device_id, void* user_ctx)
+{
+    if (user_ctx == NULL)
+    {
+        LogError("user context was unexpectantly NULL");
+    }
+    else
+    {
+        PROV_INSTANCE_INFO* prov_info = (PROV_INSTANCE_INFO*)user_ctx;
+        if (transport_result == PROV_DEVICE_TRANSPORT_RESULT_OK)
+        {
+            if (prov_info->hsm_type == PROV_AUTH_TYPE_TPM)
+            {
+                if (iothub_key == NULL)
+                {
+                    prov_info->prov_state = CLIENT_STATE_ERROR;
+                    if (prov_info->error_reason == PROV_DEVICE_RESULT_OK)
+                    {
+                        prov_info->error_reason = PROV_DEVICE_RESULT_KEY_ERROR;
+                    }
+                    LogError("invalid iothub device key");
+                }
+                else
+                {
+                    const unsigned char* key_value = BUFFER_u_char(iothub_key);
+                    size_t key_len = BUFFER_length(iothub_key);
+
+                    /* Codes_SRS_SECURE_ENCLAVE_CLIENT_07_028: [ prov_auth_import_key shall import the specified key into the tpm using secure_device_import_key secure enclave function. ] */
+                    if (prov_auth_import_key(prov_info->prov_auth_handle, key_value, key_len) != 0)
+                    {
+                        prov_info->prov_state = CLIENT_STATE_ERROR;
+                        prov_info->error_reason = PROV_DEVICE_RESULT_KEY_ERROR;
+                        LogError("Failure to import the provisioning key");
+                    }
+                }
+            }
+
+            if (prov_info->prov_state != CLIENT_STATE_ERROR)
+            {
+                prov_info->register_callback(PROV_DEVICE_RESULT_OK, assigned_hub, device_id, prov_info->user_context);
+                prov_info->prov_state = CLIENT_STATE_READY;
+                cleanup_prov_info(prov_info);
+            }
+        }
+        else if (transport_result == PROV_DEVICE_TRANSPORT_RESULT_UNAUTHORIZED)
+        {
+            prov_info->prov_state = CLIENT_STATE_ERROR;
+            prov_info->error_reason = PROV_DEVICE_RESULT_DEV_AUTH_ERROR;
+            LogError("provisioning result is unauthorized");
+        }
+        else
+        {
+            prov_info->prov_state = CLIENT_STATE_ERROR;
+            if (prov_info->error_reason == PROV_DEVICE_RESULT_OK)
+            {
+                prov_info->error_reason = PROV_DEVICE_RESULT_TRANSPORT;
+            }
+            LogError("Failure retrieving data from the provisioning service");
+        }
+    }
+}
+
+static void on_transport_status(PROV_DEVICE_TRANSPORT_STATUS transport_status, uint32_t retry_interval, void* user_ctx)
+{
+    if (user_ctx == NULL)
+    {
+        LogError("user_ctx was unexpectatly NULL");
+    }
+    else
+    {
+        PROV_INSTANCE_INFO* prov_info = (PROV_INSTANCE_INFO*)user_ctx;
+
+        prov_info->retry_after_value = retry_interval;
+
+        switch (transport_status)
+        {
+            case PROV_DEVICE_TRANSPORT_STATUS_CONNECTED:
+                prov_info->is_connected = true;
+                if (prov_info->register_status_cb != NULL)
+                {
+                    prov_info->register_status_cb(PROV_DEVICE_REG_STATUS_CONNECTED, prov_info->status_user_ctx);
+                }
+                break;
+            case PROV_DEVICE_TRANSPORT_STATUS_AUTHENTICATED:
+            case PROV_DEVICE_TRANSPORT_STATUS_ASSIGNING:
+            case PROV_DEVICE_TRANSPORT_STATUS_UNASSIGNED:
+                prov_info->prov_state = CLIENT_STATE_STATUS_SEND;
+                if (transport_status == PROV_DEVICE_TRANSPORT_STATUS_UNASSIGNED)
+                {
+                    if (prov_info->register_status_cb != NULL)
+                    {
+                        prov_info->register_status_cb(PROV_DEVICE_REG_STATUS_REGISTERING, prov_info->status_user_ctx);
+                    }
+                }
+                else if (transport_status == PROV_DEVICE_TRANSPORT_STATUS_ASSIGNING)
+                {
+                    if (prov_info->register_status_cb != NULL)
+                    {
+                        prov_info->register_status_cb(PROV_DEVICE_REG_STATUS_ASSIGNING, prov_info->status_user_ctx);
+                    }
+                }
+                break;
+            case PROV_DEVICE_TRANSPORT_STATUS_TRANSIENT:
+                if (prov_info->prov_state == CLIENT_STATE_REGISTER_SENT)
+                {
+                    prov_info->prov_state = CLIENT_STATE_REGISTER_SEND;
+                }
+                else if (prov_info->prov_state == CLIENT_STATE_STATUS_SENT)
+                {
+                    prov_info->prov_state = CLIENT_STATE_STATUS_SEND;
+                }
+                else
+                {
+                    // Ideally this should not happen
+                    LogError("State Error: Transient Error occured in the %d state", (int)transport_status);
+                }
+                break;
+            default:
+                LogError("Unknown status encountered");
+                break;
+        }
+    }
+}
+
+static void destroy_instance(PROV_INSTANCE_INFO* prov_info)
+{
+    cleanup_prov_info(prov_info);
+    // Clean custom request data
+    free(prov_info->custom_request_data);
+    prov_info->custom_request_data = NULL;
+    if (prov_info->custom_response_data != NULL)
+    {
+        json_free_serialized_string(prov_info->custom_response_data);
+        prov_info->custom_response_data = NULL;
+    }
+    prov_info->prov_transport_protocol->prov_transport_destroy(prov_info->transport_handle);
+    prov_info->transport_handle = NULL;
+    free(prov_info->scope_id);
+    prov_auth_destroy(prov_info->prov_auth_handle);
+    tickcounter_destroy(prov_info->tick_counter);
+    free(prov_info);
+}
+
+PROV_DEVICE_LL_HANDLE Prov_Device_LL_Create(const char* uri, const char* id_scope, PROV_DEVICE_TRANSPORT_PROVIDER_FUNCTION protocol)
+{
+    PROV_INSTANCE_INFO* result;
+    /* Codes_SRS_PROV_CLIENT_07_001: [If uri is NULL Prov_Device_LL_CreateFromUri shall return NULL.] */
+    if (uri == NULL || id_scope == NULL || protocol == NULL)
+    {
+        LogError("Invalid parameter specified uri: %p, id_scope: %p, protocol: %p", uri, id_scope, protocol);
+        result = NULL;
+    }
+    else
+    {
+        srand((unsigned int)get_time(NULL));
+
+        /* Codes_SRS_PROV_CLIENT_07_002: [ Prov_Device_LL_CreateFromUri shall allocate a PROV_DEVICE_LL_HANDLE and initialize all members. ] */
+        result = (PROV_INSTANCE_INFO*)malloc(sizeof(PROV_INSTANCE_INFO));
+        if (result == NULL)
+        {
+            LogError("unable to allocate Instance Info");
+        }
+        else
+        {
+            memset(result, 0, sizeof(PROV_INSTANCE_INFO));
+
+            /* Codes_SRS_PROV_CLIENT_07_028: [ CLIENT_STATE_READY is the initial state after the object is created which will send a uhttp_client_open call to the http endpoint. ] */
+            result->prov_state = CLIENT_STATE_READY;
+            result->retry_after_value = PROV_GET_THROTTLE_TIME;
+            result->prov_transport_protocol = protocol();
+            result->error_reason = PROV_DEVICE_RESULT_OK;
+
+            /* Codes_SRS_PROV_CLIENT_07_034: [ Prov_Device_LL_Create shall construct a id_scope by base64 encoding the uri. ] */
+            if (mallocAndStrcpy_s(&result->scope_id, id_scope) != 0)
+            {
+                /* Codes_SRS_PROV_CLIENT_07_003: [ If any error is encountered, Prov_Device_LL_CreateFromUri shall return NULL. ] */
+                LogError("failed to construct id_scope");
+                free(result);
+                result = NULL;
+            }
+            else if ((result->prov_auth_handle = prov_auth_create()) == NULL)
+            {
+                /* Codes_SRS_PROV_CLIENT_07_003: [ If any error is encountered, Prov_Device_LL_CreateFromUri shall return NULL. ] */
+                LogError("failed calling prov_auth_create\r\n");
+                destroy_instance(result);
+                result = NULL;
+            }
+            else if ((result->tick_counter = tickcounter_create()) == NULL)
+            {
+                LogError("failure: allocating tickcounter");
+                destroy_instance(result);
+                result = NULL;
+            }
+            else
+            {
+                TRANSPORT_HSM_TYPE hsm_type;
+                if ((result->hsm_type = prov_auth_get_type(result->prov_auth_handle)) == PROV_AUTH_TYPE_TPM)
+                {
+                    hsm_type = TRANSPORT_HSM_TYPE_TPM;
+                }
+                else if (result->hsm_type == PROV_AUTH_TYPE_KEY)
+                {
+                    hsm_type = TRANSPORT_HSM_TYPE_SYMM_KEY;
+                }
+                else
+                {
+                    hsm_type = TRANSPORT_HSM_TYPE_X509;
+                }
+
+                if ((result->transport_handle = result->prov_transport_protocol->prov_transport_create(uri, hsm_type, result->scope_id, PROV_API_VERSION, on_transport_error, result)) == NULL)
+                {
+                    /* Codes_SRS_PROV_CLIENT_07_003: [ If any error is encountered, Prov_Device_LL_CreateFromUri shall return NULL. ] */
+                    LogError("failed calling into transport create");
+                    destroy_instance(result);
+                    result = NULL;
+                }
+                else
+                {
+                    // Ensure that we are passed the throttling time and send on the first send
+                    (void)tickcounter_get_current_ms(result->tick_counter, &result->status_throttle);
+                    result->status_throttle += (result->retry_after_value * 1000);
+                }
+            }
+        }
+    }
+    return (PROV_DEVICE_LL_HANDLE)result;
+}
+
+void Prov_Device_LL_Destroy(PROV_DEVICE_LL_HANDLE handle)
+{
+    /* Codes_SRS_PROV_CLIENT_07_005: [ If handle is NULL Prov_Device_LL_Destroy shall do nothing. ] */
+    if (handle != NULL)
+    {
+        /* Codes_SRS_PROV_CLIENT_07_006: [ Prov_Device_LL_Destroy shall destroy resources associated with the IoTHub_client ] */
+        destroy_instance(handle);
+    }
+}
+
+PROV_DEVICE_RESULT Prov_Device_LL_Register_Device(PROV_DEVICE_LL_HANDLE handle, PROV_DEVICE_CLIENT_REGISTER_DEVICE_CALLBACK register_callback, void* user_context, PROV_DEVICE_CLIENT_REGISTER_STATUS_CALLBACK reg_status_cb, void* status_ctx)
+{
+    PROV_DEVICE_RESULT result;
+    /* Codes_SRS_PROV_CLIENT_07_007: [ If handle or register_callback is NULL, Prov_Device_LL_Register_Device shall return PROV_CLIENT_INVALID_ARG. ] */
+    if (handle == NULL || register_callback == NULL)
+    {
+        LogError("Invalid parameter specified handle: %p register_callback: %p", handle, register_callback);
+        result = PROV_DEVICE_RESULT_INVALID_ARG;
+    }
+    /* Codes_SRS_PROV_CLIENT_07_035: [ Prov_Device_LL_Create shall store the registration_id from the security module. ] */
+    else if (handle->registration_id == NULL && (handle->registration_id = prov_auth_get_registration_id(handle->prov_auth_handle)) == NULL)
+    {
+        /* Codes_SRS_PROV_CLIENT_07_003: [ If any error is encountered, Prov_Device_LL_CreateFromUri shall return NULL. ] */
+        LogError("failure: Unable to retrieve registration Id from device auth.");
+        result = PROV_DEVICE_RESULT_ERROR;
+    }
+    else
+    {
+        BUFFER_HANDLE ek_value = NULL;
+        BUFFER_HANDLE srk_value = NULL;
+
+        if (handle->prov_state != CLIENT_STATE_READY)
+        {
+            LogError("state is invalid");
+            if (!handle->user_supplied_reg_id)
+            {
+                free(handle->registration_id);
+                handle->registration_id = NULL;
+            }
+            result = PROV_DEVICE_RESULT_ERROR;
+        }
+        else
+        {
+            if (handle->hsm_type == PROV_AUTH_TYPE_TPM)
+            {
+                if ((ek_value = prov_auth_get_endorsement_key(handle->prov_auth_handle)) == NULL)
+                {
+                    LogError("Could not get endorsement key from tpm");
+                    if (!handle->user_supplied_reg_id)
+                    {
+                        free(handle->registration_id);
+                        handle->registration_id = NULL;
+                    }
+                    result = PROV_DEVICE_RESULT_ERROR;
+                }
+                else if ((srk_value = prov_auth_get_storage_key(handle->prov_auth_handle)) == NULL)
+                {
+                    LogError("Could not get storage root key from tpm");
+                    if (!handle->user_supplied_reg_id)
+                    {
+                        free(handle->registration_id);
+                        handle->registration_id = NULL;
+                    }
+                    result = PROV_DEVICE_RESULT_ERROR;
+                    BUFFER_delete(ek_value);
+                }
+                else
+                {
+                    result = PROV_DEVICE_RESULT_OK;
+                }
+            }
+            else if (handle->hsm_type == PROV_AUTH_TYPE_X509)
+            {
+                char* x509_cert;
+                char* x509_private_key;
+                if ((x509_cert = prov_auth_get_certificate(handle->prov_auth_handle)) == NULL)
+                {
+                    LogError("Could not get the x509 certificate");
+                    if (!handle->user_supplied_reg_id)
+                    {
+                        free(handle->registration_id);
+                        handle->registration_id = NULL;
+                    }
+                    result = PROV_DEVICE_RESULT_ERROR;
+                }
+                else if ((x509_private_key = prov_auth_get_alias_key(handle->prov_auth_handle)) == NULL)
+                {
+                    LogError("Could not get the x509 alias key");
+                    if (!handle->user_supplied_reg_id)
+                    {
+                        free(handle->registration_id);
+                        handle->registration_id = NULL;
+                    }
+                    free(x509_cert);
+                    result = PROV_DEVICE_RESULT_ERROR;
+                }
+                else
+                {
+                    if (handle->prov_transport_protocol->prov_transport_x509_cert(handle->transport_handle, x509_cert, x509_private_key) != 0)
+                    {
+                        LogError("unable to set the x509 certificate information on transport");
+                        if (!handle->user_supplied_reg_id)
+                        {
+                            free(handle->registration_id);
+                            handle->registration_id = NULL;
+                        }
+                        result = PROV_DEVICE_RESULT_ERROR;
+                    }
+                    else
+                    {
+                        result = PROV_DEVICE_RESULT_OK;
+                    }
+                    free(x509_cert);
+                    free(x509_private_key);
+                }
+            }
+            else
+            {
+                result = PROV_DEVICE_RESULT_OK;
+            }
+        }
+        if (result == PROV_DEVICE_RESULT_OK)
+        {
+            /* Codes_SRS_PROV_CLIENT_07_008: [ Prov_Device_LL_Register_Device shall set the state to send the registration request to on subsequent DoWork calls. ] */
+            handle->register_callback = register_callback;
+            handle->user_context = user_context;
+
+            handle->register_status_cb = reg_status_cb;
+            handle->status_user_ctx = status_ctx;
+            
+            // Free the custom data if its been allocated
+            if (handle->custom_response_data != NULL)
+            {
+                json_free_serialized_string(handle->custom_response_data);
+                handle->custom_response_data = NULL;
+            }
+
+            if (handle->prov_transport_protocol->prov_transport_open(handle->transport_handle, handle->registration_id, ek_value, srk_value, on_transport_registration_data, handle, on_transport_status, handle, prov_transport_challenge_callback, handle) != 0)
+            {
+                LogError("Failure establishing  connection");
+                if (!handle->user_supplied_reg_id)
+                {
+                    free(handle->registration_id);
+                    handle->registration_id = NULL;
+                }
+                handle->register_callback = NULL;
+                handle->user_context = NULL;
+
+                handle->register_status_cb = NULL;
+                handle->status_user_ctx = NULL;
+                result = PROV_DEVICE_RESULT_ERROR;
+            }
+            else
+            {
+                handle->transport_open = true;
+                handle->prov_state = CLIENT_STATE_REGISTER_SEND;
+                /* Codes_SRS_PROV_CLIENT_07_009: [ Upon success Prov_Device_LL_Register_Device shall return PROV_CLIENT_OK. ] */
+                result = PROV_DEVICE_RESULT_OK;
+            }
+            BUFFER_delete(ek_value);
+            BUFFER_delete(srk_value);
+        }
+    }
+    return result;
+}
+
+void Prov_Device_LL_DoWork(PROV_DEVICE_LL_HANDLE handle)
+{
+    /* Codes_SRS_PROV_CLIENT_07_010: [ If handle is NULL, Prov_Device_LL_DoWork shall do nothing. ] */
+    if (handle != NULL)
+    {
+        PROV_INSTANCE_INFO* prov_info = (PROV_INSTANCE_INFO*)handle;
+        /* Codes_SRS_PROV_CLIENT_07_011: [ Prov_Device_LL_DoWork shall call the underlying http_client_dowork function ] */
+        if (prov_info->prov_state != CLIENT_STATE_ERROR)
+        {
+            prov_info->prov_transport_protocol->prov_transport_dowork(prov_info->transport_handle);
+        }
+        if (prov_info->is_connected || prov_info->prov_state == CLIENT_STATE_ERROR)
+        {
+            switch (prov_info->prov_state)
+            {
+                case CLIENT_STATE_REGISTER_SEND:
+                    /* Codes_SRS_PROV_CLIENT_07_013: [ CLIENT_STATE_REGISTER_SEND which shall construct an initial call to the service with endorsement information ] */
+                    if (prov_info->prov_transport_protocol->prov_transport_register(prov_info->transport_handle, prov_transport_process_json_reply, prov_transport_create_json_payload, prov_info) != 0)
+                    {
+                        LogError("Failure registering device");
+                        if (prov_info->error_reason == PROV_DEVICE_RESULT_OK)
+                        {
+                            prov_info->error_reason = PROV_DEVICE_RESULT_TRANSPORT;
+                        }
+                        prov_info->prov_state = CLIENT_STATE_ERROR;
+                    }
+                    else
+                    {
+                        (void)tickcounter_get_current_ms(prov_info->tick_counter, &prov_info->timeout_value);
+                        prov_info->prov_state = CLIENT_STATE_REGISTER_SENT;
+                    }
+                    break;
+
+                case CLIENT_STATE_STATUS_SEND:
+                {
+                    tickcounter_ms_t current_time = 0;
+                    if (tickcounter_get_current_ms(prov_info->tick_counter, &current_time) != 0)
+                    {
+                        LogError("Failure getting the current time");
+                        prov_info->error_reason = PROV_DEVICE_RESULT_ERROR;
+                        prov_info->prov_state = CLIENT_STATE_ERROR;
+                    }
+                    else
+                    {
+                        if ((current_time - prov_info->status_throttle) / 1000 > prov_info->retry_after_value)
+                        {
+                            /* Codes_SRS_PROV_CLIENT_07_026: [ Upon receiving the reply of the CLIENT_STATE_URL_REQ_SEND message from  iothub_client shall process the the reply of the CLIENT_STATE_URL_REQ_SEND state ] */
+                            if (prov_info->prov_transport_protocol->prov_transport_get_op_status(prov_info->transport_handle) != 0)
+                            {
+                                LogError("Failure sending operation status");
+                                if (prov_info->error_reason == PROV_DEVICE_RESULT_OK)
+                                {
+                                    prov_info->error_reason = PROV_DEVICE_RESULT_TRANSPORT;
+                                }
+                                prov_info->prov_state = CLIENT_STATE_ERROR;
+                            }
+                            else
+                            {
+                                prov_info->prov_state = CLIENT_STATE_STATUS_SENT;
+                                if (tickcounter_get_current_ms(prov_info->tick_counter, &prov_info->timeout_value) != 0)
+                                {
+                                    LogError("Failure getting the current time");
+                                    prov_info->error_reason = PROV_DEVICE_RESULT_ERROR;
+                                    prov_info->prov_state = CLIENT_STATE_ERROR;
+                                }
+                            }
+                            prov_info->status_throttle = current_time;
+                        }
+                    }
+                    break;
+                }
+
+                case CLIENT_STATE_REGISTER_SENT:
+                case CLIENT_STATE_STATUS_SENT:
+                {
+                    if (prov_info->prov_timeout > 0)
+                    {
+                        tickcounter_ms_t current_time = 0;
+                        (void)tickcounter_get_current_ms(prov_info->tick_counter, &current_time);
+                        if ((current_time - prov_info->timeout_value) / 1000 > prov_info->prov_timeout)
+                        {
+                            LogError("Timeout waiting for reply");
+                            prov_info->error_reason = PROV_DEVICE_RESULT_TIMEOUT;
+                            prov_info->prov_state = CLIENT_STATE_ERROR;
+                        }
+                    }
+                    break;
+                }
+
+                case CLIENT_STATE_READY:
+                    break;
+
+                case CLIENT_STATE_ERROR:
+                default:
+                    prov_info->register_callback(prov_info->error_reason, NULL, NULL, prov_info->user_context);
+                    prov_info->prov_state = CLIENT_STATE_READY;
+                    cleanup_prov_info(prov_info);
+                    break;
+            }
+        }
+        else
+        {
+            // Check the connection
+            if ((prov_info->prov_state != CLIENT_STATE_READY) && (prov_info->prov_timeout > 0))
+            {
+                tickcounter_ms_t current_time = 0;
+                (void)tickcounter_get_current_ms(prov_info->tick_counter, &current_time);
+                if ((current_time - prov_info->timeout_value) / 1000 > prov_info->prov_timeout)
+                {
+                    LogError("Timed out connecting to provisioning service");
+                    prov_info->error_reason = PROV_DEVICE_RESULT_TIMEOUT;
+                    prov_info->prov_state = CLIENT_STATE_ERROR;
+                }
+            }
+        }
+    }
+}
+
+PROV_DEVICE_RESULT Prov_Device_LL_SetOption(PROV_DEVICE_LL_HANDLE handle, const char* option_name, const void* value)
+{
+    PROV_DEVICE_RESULT result;
+    if (handle == NULL || option_name == NULL)
+    {
+        LogError("Invalid parameter specified handle: %p option_name: %p", handle, option_name);
+        result = PROV_DEVICE_RESULT_INVALID_ARG;
+    }
+    else
+    {
+        if (strcmp(option_name, OPTION_TRUSTED_CERT) == 0)
+        {
+            const char* cert_info = (const char*)value;
+            if (handle->prov_transport_protocol->prov_transport_trusted_cert(handle->transport_handle, cert_info) != 0)
+            {
+                result = PROV_DEVICE_RESULT_ERROR;
+                LogError("failure allocating certificate");
+            }
+            else
+            {
+                result = PROV_DEVICE_RESULT_OK;
+            }
+        }
+        else if (strcmp(OPTION_LOG_TRACE, option_name) == 0)
+        {
+            bool log_trace = *((bool*)value);
+            if (handle->prov_transport_protocol->prov_transport_set_trace(handle->transport_handle, log_trace) != 0)
+            {
+                result = PROV_DEVICE_RESULT_ERROR;
+                LogError("failure setting trace option");
+            }
+            else
+            {
+                result = PROV_DEVICE_RESULT_OK;
+            }
+        }
+        else if (strcmp(OPTION_HTTP_PROXY, option_name) == 0)
+        {
+            /* Codes_SRS_IOTHUB_TRANSPORT_MQTT_COMMON_01_001: [ If `option` is `proxy_data`, `value` shall be used as an `HTTP_PROXY_OPTIONS*`. ]*/
+            HTTP_PROXY_OPTIONS* proxy_options = (HTTP_PROXY_OPTIONS*)value;
+
+            if (handle->prov_transport_protocol->prov_transport_set_proxy(handle->transport_handle, proxy_options) != 0)
+            {
+                LogError("setting proxy options");
+                result = PROV_DEVICE_RESULT_ERROR;
+            }
+            else
+            {
+                result = PROV_DEVICE_RESULT_OK;
+            }
+        }
+        else if (strcmp(PROV_OPTION_TIMEOUT, option_name) == 0)
+        {
+            if (value == NULL)
+            {
+                LogError("setting proxy options");
+                result = PROV_DEVICE_RESULT_ERROR;
+            }
+            else
+            {
+                handle->prov_timeout = *((uint8_t*)value);
+                result = PROV_DEVICE_RESULT_OK;
+            }
+        }
+        else if (strcmp(PROV_REGISTRATION_ID, option_name) == 0)
+        {
+            if (handle->prov_state != CLIENT_STATE_READY)
+            {
+                LogError("registration id cannot be set after registration has begun");
+                result = PROV_DEVICE_RESULT_ERROR;
+            }
+            else if (value == NULL)
+            {
+                LogError("value must be set to the correct registration id");
+                result = PROV_DEVICE_RESULT_ERROR;
+            }
+            else
+            {
+                char* temp_reg;
+                if (mallocAndStrcpy_s(&temp_reg, (const char*)value) != 0)
+                {
+                    LogError("Failure allocating setting registration id");
+                    result = PROV_DEVICE_RESULT_ERROR;
+                }
+                else if (prov_auth_set_registration_id(handle->prov_auth_handle, temp_reg) != 0)
+                {
+                    LogError("Failure setting registration id");
+                    free(temp_reg);
+                    result = PROV_DEVICE_RESULT_ERROR;
+                }
+                else
+                {
+                    if (handle->registration_id != NULL)
+                    {
+                        free(handle->registration_id);
+                    }
+                    handle->registration_id = temp_reg;
+                    handle->user_supplied_reg_id = true;
+                    result = PROV_DEVICE_RESULT_OK;
+                }
+            }
+        }
+        else
+        {
+            if (handle->prov_transport_protocol->prov_transport_set_option(handle->transport_handle, option_name, value) != 0)
+            {
+                LogError("Failure in prov transport set option\n");
+                result = PROV_DEVICE_RESULT_ERROR;
+            }
+            else
+            {
+                result = PROV_DEVICE_RESULT_OK;
+            }
+        }
+    }
+    return result;
+}
+
+const char* Prov_Device_LL_GetVersionString(void)
+{
+    return PROV_DEVICE_CLIENT_VERSION;
+}
+
+PROV_DEVICE_RESULT Prov_Device_LL_Set_Provisioning_Payload(PROV_DEVICE_LL_HANDLE handle, const char* jsonDataField)
+{
+    PROV_DEVICE_RESULT result;
+    if (handle == NULL)
+    {
+        LogError("Invalid parameter specified handle: %p", handle);
+        result = PROV_DEVICE_RESULT_INVALID_ARG;
+    }
+    else
+    {
+        char* temp_data;
+        if (mallocAndStrcpy_s(&temp_data, jsonDataField) != 0)
+        {
+            LogError("Failure setting custom provisioning data");
+            result = PROV_DEVICE_RESULT_ERROR;
+        }
+        else
+        {
+            if (handle->custom_request_data != NULL)
+            {
+                free(handle->custom_request_data);
+            }
+            handle->custom_request_data = temp_data;
+            result = PROV_DEVICE_RESULT_OK;
+        }
+    }
+    return result;
+}
+
+const char* Prov_Device_LL_Get_Provisioning_Payload(PROV_DEVICE_LL_HANDLE handle)
+{
+    const char* result;
+    if (handle == NULL)
+    {
+        LogError("Invalid parameter specified handle: %p", handle);
+        result = NULL;
+    }
+    else
+    {
+        result = handle->custom_response_data;
+    }
+    return result;
+}
Index: azure_iot_hub_f767zi/trunk/azure_iot_sdk/provisioning_client/src/prov_security_factory.c
===================================================================
--- azure_iot_hub_f767zi/trunk/azure_iot_sdk/provisioning_client/src/prov_security_factory.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/azure_iot_sdk/provisioning_client/src/prov_security_factory.c	(revision 457)
@@ -0,0 +1,184 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+#include <stdlib.h>
+#include "azure_c_shared_utility/gballoc.h"
+#include "azure_c_shared_utility/xlogging.h"
+#include "azure_c_shared_utility/crt_abstractions.h"
+#include "azure_prov_client/prov_security_factory.h"
+#include "azure_prov_client/iothub_security_factory.h"
+
+#include "hsm_client_data.h"
+
+static SECURE_DEVICE_TYPE g_device_hsm_type = SECURE_DEVICE_TYPE_UNKNOWN;
+static char* g_symm_key = NULL;
+static char* g_symm_key_reg_name = NULL;
+
+static IOTHUB_SECURITY_TYPE get_iothub_security_type(SECURE_DEVICE_TYPE sec_type)
+{
+    IOTHUB_SECURITY_TYPE ret;
+
+    switch (sec_type)
+    {
+#if defined(HSM_TYPE_SAS_TOKEN)  || defined(HSM_AUTH_TYPE_CUSTOM)
+        case SECURE_DEVICE_TYPE_TPM:
+            ret = IOTHUB_SECURITY_TYPE_SAS;
+            break;
+#endif
+
+#if defined(HSM_TYPE_X509) || defined(HSM_AUTH_TYPE_CUSTOM)
+        case SECURE_DEVICE_TYPE_X509:
+            ret = IOTHUB_SECURITY_TYPE_X509;
+            break;
+#endif
+
+#if defined(HSM_TYPE_SYMM_KEY) || defined(HSM_AUTH_TYPE_CUSTOM)
+        case SECURE_DEVICE_TYPE_SYMMETRIC_KEY:
+            ret = IOTHUB_SECURITY_TYPE_SYMMETRIC_KEY;
+            break;
+#endif
+
+#ifdef HSM_TYPE_HTTP_EDGE
+        case SECURE_DEVICE_TYPE_HTTP_EDGE:
+            ret = IOTHUB_SECURITY_TYPE_HTTP_EDGE;
+            break;
+#endif
+
+        default:
+            ret = IOTHUB_SECURITY_TYPE_UNKNOWN;
+            break;
+    }
+
+    return ret;
+}
+
+int prov_dev_security_init(SECURE_DEVICE_TYPE hsm_type)
+{
+    int result;
+
+    IOTHUB_SECURITY_TYPE security_type_from_caller = get_iothub_security_type(hsm_type);
+
+    if (security_type_from_caller == IOTHUB_SECURITY_TYPE_UNKNOWN)
+    {
+        LogError("HSM type %d is not supported on this SDK build", hsm_type);
+        result = MU_FAILURE;
+    }
+    else
+    {
+        g_device_hsm_type = hsm_type;
+        IOTHUB_SECURITY_TYPE security_type_from_iot = iothub_security_type();
+        if (security_type_from_iot == IOTHUB_SECURITY_TYPE_UNKNOWN)
+        {
+            // Initialize iothub_security layer if not currently
+            result = iothub_security_init(security_type_from_caller);
+        }
+        else if (security_type_from_iot != security_type_from_caller)
+        {
+            LogError("Security HSM from caller %d (which maps to security type %d) does not match already specified security type %d", hsm_type, security_type_from_caller, security_type_from_iot);
+            result = MU_FAILURE;
+        }
+        else
+        {
+            result = 0;
+        }
+
+        if (result == 0)
+        {
+            result = initialize_hsm_system();
+        }
+    }
+    return result;
+}
+
+void prov_dev_security_deinit(void)
+{
+    if (g_symm_key != NULL)
+    {
+        free(g_symm_key);
+        g_symm_key = NULL;
+    }
+    if (g_symm_key_reg_name != NULL)
+    {
+        free(g_symm_key_reg_name);
+        g_symm_key_reg_name = NULL;
+    }
+    deinitialize_hsm_system();
+    if (iothub_security_get_symmetric_key() != NULL || iothub_security_get_symm_registration_name() != NULL)
+    {
+        // Clear out iothub info
+        iothub_security_deinit();
+    }
+}
+
+SECURE_DEVICE_TYPE prov_dev_security_get_type(void)
+{
+    return g_device_hsm_type;
+}
+
+int prov_dev_set_symmetric_key_info(const char* registration_name, const char* symmetric_key)
+{
+    int result;
+    if (registration_name == NULL || symmetric_key == NULL)
+    {
+        LogError("Invalid parameter specified reg_name: %p, symm_key: %p", registration_name, symmetric_key);
+        result = MU_FAILURE;
+    }
+    else
+    {
+        char* temp_key;
+        char* temp_name;
+        if (mallocAndStrcpy_s(&temp_name, registration_name) != 0)
+        {
+            LogError("Failure allocating registration name");
+            result = MU_FAILURE;
+        }
+        else if (mallocAndStrcpy_s(&temp_key, symmetric_key) != 0)
+        {
+            LogError("Failure allocating symmetric key");
+            free(temp_name);
+            result = MU_FAILURE;
+        }
+        else
+        {
+            if (g_symm_key != NULL)
+            {
+                free(g_symm_key);
+            }
+            if (g_symm_key_reg_name != NULL)
+            {
+                free(g_symm_key_reg_name);
+            }
+            g_symm_key_reg_name = temp_name;
+            g_symm_key = temp_key;
+
+            // Sync dps with iothub only if it is NULL
+            if (iothub_security_get_symmetric_key() == NULL || iothub_security_get_symm_registration_name() == NULL)
+            {
+                if (iothub_security_set_symmetric_key_info(g_symm_key_reg_name, g_symm_key) != 0)
+                {
+                    LogError("Failure syncing dps & IoThub key information");
+                    result = MU_FAILURE;
+                }
+                else
+                {
+                    result = 0;
+                }
+            }
+            else
+            {
+                result = 0;
+            }
+        }
+    }
+    return result;
+}
+
+const char* prov_dev_get_symmetric_key(void)
+{
+    return g_symm_key;
+}
+
+const char* prov_dev_get_symm_registration_name(void)
+{
+    return g_symm_key_reg_name;
+}
Index: azure_iot_hub_f767zi/trunk/azure_iot_sdk/provisioning_client/src/prov_transport_http_client.c
===================================================================
--- azure_iot_hub_f767zi/trunk/azure_iot_sdk/provisioning_client/src/prov_transport_http_client.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/azure_iot_sdk/provisioning_client/src/prov_transport_http_client.c	(revision 457)
@@ -0,0 +1,1259 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+#include <stdlib.h>
+#include <stdint.h>
+#include <stdbool.h>
+#include "azure_c_shared_utility/gballoc.h"
+#include "azure_c_shared_utility/platform.h"
+#include "azure_c_shared_utility/xlogging.h"
+#include "azure_c_shared_utility/crt_abstractions.h"
+#include "azure_c_shared_utility/tlsio.h"
+#include "azure_c_shared_utility/shared_util_options.h"
+#include "azure_c_shared_utility/http_proxy_io.h"
+#include "azure_c_shared_utility/urlencode.h"
+#include "azure_c_shared_utility/azure_base64.h"
+
+#include "azure_prov_client/prov_transport_http_client.h"
+#include "azure_prov_client/internal/prov_transport_private.h"
+#include "azure_prov_client/prov_client_const.h"
+
+#include "azure_uhttp_c/uhttp.h"
+#include "parson.h"
+
+#define HTTP_PORT_NUM                       443
+#define HTTP_STATUS_CODE_OK                 200
+#define HTTP_STATUS_CODE_OK_MAX             226
+#define HTTP_STATUS_CODE_UNAUTHORIZED       401
+
+static const char* const PROV_REGISTRATION_URI_FMT = "/%s/registrations/%s/register?api-version=%s";
+static const char* const PROV_OP_STATUS_URI_FMT = "/%s/registrations/%s/operations/%s?api-version=%s";
+static const char* const HEADER_KEY_AUTHORIZATION = "Authorization";
+static const char* const HEADER_USER_AGENT = "UserAgent";
+static const char* const HEADER_ACCEPT = "Accept";
+static const char* const HEADER_CONTENT_TYPE = "Content-Type";
+static const char* const HEADER_CONNECTION = "Connection";
+static const char* const USER_AGENT_VALUE = "prov_device_client/1.0";
+static const char* const ACCEPT_VALUE = "application/json";
+static const char* const CONTENT_TYPE_VALUE = "application/json; charset=utf-8";
+static const char* const KEEP_ALIVE_VALUE = "keep-alive";
+static const char* const KEY_NAME_VALUE = "registration";
+
+MU_DEFINE_ENUM_STRINGS_WITHOUT_INVALID(HTTP_CALLBACK_REASON, HTTP_CALLBACK_REASON_VALUES);
+
+typedef enum PROV_TRANSPORT_STATE_TAG
+{
+    TRANSPORT_CLIENT_STATE_IDLE,
+
+    TRANSPORT_CLIENT_STATE_REG_SEND,
+    TRANSPORT_CLIENT_STATE_REG_SENT,
+    TRANSPORT_CLIENT_STATE_REG_RECV,
+
+    TRANSPORT_CLIENT_STATE_STATUS_SENT,
+    TRANSPORT_CLIENT_STATE_STATUS_RECV,
+
+    TRANSPORT_CLIENT_STATE_TRANSIENT,
+
+    TRANSPORT_CLIENT_STATE_ERROR
+} PROV_TRANSPORT_STATE;
+
+typedef struct PROV_TRANSPORT_HTTP_INFO_TAG
+{
+    PROV_DEVICE_TRANSPORT_REGISTER_CALLBACK register_data_cb;
+    void* user_ctx;
+    PROV_DEVICE_TRANSPORT_STATUS_CALLBACK status_cb;
+    void* status_ctx;
+    PROV_TRANSPORT_CHALLENGE_CALLBACK challenge_cb;
+    void* challenge_ctx;
+    PROV_TRANSPORT_CREATE_JSON_PAYLOAD json_create_cb;
+    PROV_TRANSPORT_JSON_PARSE json_parse_cb;
+    void* json_ctx;
+
+    char* hostname;
+    char* proxy_host;
+    int proxy_port;
+    char* username;
+    char* password;
+
+    char* x509_cert;
+    char* private_key;
+
+    char* certificate;
+
+    BUFFER_HANDLE ek;
+    BUFFER_HANDLE srk;
+    char* registration_id;
+    char* scope_id;
+    char* sas_token;
+
+    BUFFER_HANDLE nonce;
+
+    char* operation_id;
+
+    char* api_version;
+
+    char* payload_data;
+    unsigned int http_status_code;
+
+    bool http_connected;
+    bool log_trace;
+    PROV_TRANSPORT_STATE transport_state;
+    TRANSPORT_HSM_TYPE hsm_type;
+
+    HTTP_CLIENT_HANDLE http_client;
+    uint32_t retry_after_value;
+
+    PROV_TRANSPORT_ERROR_CALLBACK error_cb;
+    void* error_ctx;
+} PROV_TRANSPORT_HTTP_INFO;
+
+static void on_http_error(void* callback_ctx, HTTP_CALLBACK_REASON error_result)
+{
+    (void)error_result;
+    if (callback_ctx != NULL)
+    {
+        PROV_TRANSPORT_HTTP_INFO* http_info = (PROV_TRANSPORT_HTTP_INFO*)callback_ctx;
+        http_info->transport_state = TRANSPORT_CLIENT_STATE_ERROR;
+        LogError("http error encountered: %s", MU_ENUM_TO_STRING(HTTP_CALLBACK_REASON, error_result));
+    }
+    else
+    {
+        LogError("callback_ctx NULL.  http error encountered: %s", MU_ENUM_TO_STRING(HTTP_CALLBACK_REASON, error_result));
+    }
+}
+
+static void on_http_reply_recv(void* callback_ctx, HTTP_CALLBACK_REASON request_result, const unsigned char* content, size_t content_len, unsigned int status_code, HTTP_HEADERS_HANDLE responseHeadersHandle)
+{
+    (void)responseHeadersHandle;
+    if (callback_ctx != NULL)
+    {
+        PROV_TRANSPORT_HTTP_INFO* http_info = (PROV_TRANSPORT_HTTP_INFO*)callback_ctx;
+        http_info->http_status_code = status_code;
+        if (request_result != HTTP_CALLBACK_REASON_OK)
+        {
+            LogError("Failure http reply %s", MU_ENUM_TO_STRING(HTTP_CALLBACK_REASON, request_result));
+            http_info->transport_state = TRANSPORT_CLIENT_STATE_ERROR;
+        }
+        else if ((status_code >= HTTP_STATUS_CODE_OK && status_code <= HTTP_STATUS_CODE_OK_MAX) || status_code == HTTP_STATUS_CODE_UNAUTHORIZED)
+        {
+            if (content != NULL && content_len > 0)
+            {
+                /* Codes_PROV_TRANSPORT_HTTP_CLIENT_07_038: [ prov_transport_http_dowork shall free the payload_data ] */
+                if (http_info->payload_data != NULL)
+                {
+                    free(http_info->payload_data);
+                }
+                http_info->payload_data = malloc(content_len + 1);
+                if (http_info->payload_data == NULL)
+                {
+                    LogError("Failure sending http request");
+                    http_info->transport_state = TRANSPORT_CLIENT_STATE_ERROR;
+                }
+                else
+                {
+                    memset(http_info->payload_data, 0, content_len + 1);
+                    memcpy(http_info->payload_data, content, content_len);
+                    if (http_info->transport_state == TRANSPORT_CLIENT_STATE_REG_SENT)
+                    {
+                        http_info->transport_state = TRANSPORT_CLIENT_STATE_REG_RECV;
+                    }
+                    else
+                    {
+                        http_info->transport_state = TRANSPORT_CLIENT_STATE_STATUS_RECV;
+                    }
+                }
+            }
+            else
+            {
+                if (http_info->transport_state == TRANSPORT_CLIENT_STATE_REG_SENT)
+                {
+                    http_info->transport_state = TRANSPORT_CLIENT_STATE_REG_RECV;
+                }
+                else
+                {
+                    http_info->transport_state = TRANSPORT_CLIENT_STATE_STATUS_RECV;
+                }
+            }
+        }
+        else if (status_code >= PROV_STATUS_CODE_TRANSIENT_ERROR)
+        {
+            // On transient error reset the transport to send state
+            http_info->transport_state = TRANSPORT_CLIENT_STATE_TRANSIENT;
+        }
+        else
+        {
+            LogError("Failure status code sent from the server: %u", status_code);
+            http_info->transport_state = TRANSPORT_CLIENT_STATE_ERROR;
+        }
+        // The call to parse_retry_after_value can not fail
+        http_info->retry_after_value = parse_retry_after_value(HTTPHeaders_FindHeaderValue(responseHeadersHandle, RETRY_AFTER_KEY_VALUE));
+    }
+    else
+    {
+        LogError("Null callback_ctx specified");
+    }
+}
+
+static void on_http_connected(void* callback_ctx, HTTP_CALLBACK_REASON open_result)
+{
+    if (callback_ctx != NULL)
+    {
+        PROV_TRANSPORT_HTTP_INFO* http_info = (PROV_TRANSPORT_HTTP_INFO*)callback_ctx;
+        if (open_result == HTTP_CALLBACK_REASON_OK)
+        {
+            if (http_info->status_cb != NULL)
+            {
+                http_info->status_cb(PROV_DEVICE_TRANSPORT_STATUS_CONNECTED, http_info->retry_after_value, http_info->status_ctx);
+            }
+            http_info->http_connected = true;
+        }
+        else
+        {
+            LogError("Http connection failed to connect");
+            http_info->transport_state = TRANSPORT_CLIENT_STATE_ERROR;
+            http_info->http_connected = false;
+        }
+    }
+    else
+    {
+        LogError("Null callback_ctx specified");
+    }
+}
+
+static HTTP_HEADERS_HANDLE construct_http_headers(const char* sas_token)
+{
+    HTTP_HEADERS_HANDLE result;
+    if ((result = HTTPHeaders_Alloc()) == NULL)
+    {
+        LogError("failure sending request");
+    }
+    else
+    {
+        if ((HTTPHeaders_AddHeaderNameValuePair(result, HEADER_USER_AGENT, USER_AGENT_VALUE) != HTTP_HEADERS_OK) ||
+            (HTTPHeaders_AddHeaderNameValuePair(result, HEADER_ACCEPT, ACCEPT_VALUE) != HTTP_HEADERS_OK) ||
+            (HTTPHeaders_AddHeaderNameValuePair(result, HEADER_CONNECTION, KEEP_ALIVE_VALUE) != HTTP_HEADERS_OK) ||
+            (HTTPHeaders_AddHeaderNameValuePair(result, HEADER_CONTENT_TYPE, CONTENT_TYPE_VALUE) != HTTP_HEADERS_OK))
+        {
+            LogError("failure adding header value");
+            HTTPHeaders_Free(result);
+            result = NULL;
+        }
+        else
+        {
+            if (sas_token != NULL)
+            {
+                if (HTTPHeaders_AddHeaderNameValuePair(result, HEADER_KEY_AUTHORIZATION, sas_token) != HTTP_HEADERS_OK)
+                {
+                    LogError("failure adding sas_token header value");
+                    HTTPHeaders_Free(result);
+                    result = NULL;
+                }
+            }
+        }
+    }
+    return result;
+}
+
+static char* construct_json_data(PROV_TRANSPORT_HTTP_INFO* http_info)
+{
+    char* result;
+    bool data_success = true;
+    STRING_HANDLE encoded_srk = NULL;
+    STRING_HANDLE encoded_ek = NULL;
+    const char* ek_value = NULL;
+    const char* srk_value = NULL;
+
+    // For TPM we need to add tpm encoded values
+    if (http_info->hsm_type == TRANSPORT_HSM_TYPE_TPM)
+    {
+        if ((encoded_ek = Azure_Base64_Encode(http_info->ek)) == NULL)
+        {
+            LogError("Failure encoding ek");
+            data_success = false;
+        }
+        else if ((encoded_srk = Azure_Base64_Encode(http_info->srk)) == NULL)
+        {
+            LogError("Failure encoding srk");
+            data_success = false;
+        }
+        else
+        {
+            ek_value = STRING_c_str(encoded_ek);
+            srk_value = STRING_c_str(encoded_srk);
+        }
+    }
+
+    if (data_success)
+    {
+        result = http_info->json_create_cb(ek_value, srk_value, http_info->json_ctx);
+    }
+    else
+    {
+        result = NULL;
+    }
+
+    if (encoded_srk != NULL)
+    {
+        STRING_delete(encoded_srk);
+    }
+    if (encoded_ek != NULL)
+    {
+        STRING_delete(encoded_ek);
+    }
+    return result;
+}
+
+static char* construct_url_path(PROV_TRANSPORT_HTTP_INFO* http_info)
+{
+    char* result;
+    size_t path_len;
+    STRING_HANDLE encoded_scope;
+
+    STRING_HANDLE encoded_reg_id = URL_EncodeString(http_info->registration_id);
+    if (encoded_reg_id == NULL)
+    {
+        LogError("Failure encoding reg id");
+        result = NULL;
+    }
+    else if ((encoded_scope = URL_EncodeString(http_info->scope_id)) == NULL)
+    {
+        LogError("Failure encoding string value");
+        STRING_delete(encoded_reg_id);
+        result = NULL;
+    }
+    else
+    {
+        if (http_info->operation_id == NULL)
+        {
+            path_len = strlen(PROV_REGISTRATION_URI_FMT) + STRING_length(encoded_scope) + STRING_length(encoded_reg_id) + strlen(http_info->api_version);
+            if ((result = malloc(path_len + 1)) == NULL)
+            {
+                LogError("Failure allocating url path");
+            }
+            else
+            {
+                if (sprintf(result, PROV_REGISTRATION_URI_FMT, STRING_c_str(encoded_scope), STRING_c_str(encoded_reg_id), http_info->api_version) == 0)
+                {
+                    LogError("Failure constructing url path");
+                    free(result);
+                    result = NULL;
+                }
+            }
+        }
+        else
+        {
+            STRING_HANDLE encoded_op_id = URL_EncodeString(http_info->operation_id);
+            if (encoded_op_id == NULL)
+            {
+                LogError("Failure encoding operation id");
+                result = NULL;
+            }
+            else
+            {
+                path_len = strlen(PROV_OP_STATUS_URI_FMT) + STRING_length(encoded_scope) + STRING_length(encoded_reg_id) + STRING_length(encoded_op_id) + strlen(http_info->api_version);
+                if ((result = malloc(path_len + 1)) == NULL)
+                {
+                    LogError("failure allocating retrieval path");
+                }
+                else
+                {
+                    if (sprintf(result, PROV_OP_STATUS_URI_FMT, STRING_c_str(encoded_scope), STRING_c_str(encoded_reg_id), STRING_c_str(encoded_op_id), http_info->api_version) == 0)
+                    {
+                        LogError("failure allocating retrieval path");
+                        free(result);
+                        result = NULL;
+                    }
+                }
+                STRING_delete(encoded_op_id);
+            }
+        }
+        STRING_delete(encoded_scope);
+        STRING_delete(encoded_reg_id);
+    }
+    return result;
+}
+
+static int send_registration_info(PROV_TRANSPORT_HTTP_INFO* http_info)
+{
+    int result;
+    char* uri_path;
+    char* json_data;
+    HTTP_HEADERS_HANDLE http_headers;
+
+    /* Codes_PROV_TRANSPORT_HTTP_CLIENT_07_018: [ prov_transport_http_register_device shall construct the http headers for anonymous communication to the service. ] */
+    if ((http_headers = construct_http_headers(http_info->sas_token)) == NULL)
+    {
+        /* Codes_PROV_TRANSPORT_HTTP_CLIENT_07_021: [ If any error is encountered prov_transport_http_register_device shall return a non-zero value. ] */
+        LogError("failure constructing http headers");
+        result = MU_FAILURE;
+    }
+    /* Codes_PROV_TRANSPORT_HTTP_CLIENT_07_019: [ prov_transport_http_register_device shall construct the path to the service in the following format: /<scope_id>/registrations/<url_encoded_registration_id>/register-me?api-version=<api_version> ] */
+    else if ((uri_path = construct_url_path(http_info)) == NULL)
+    {
+        /* Codes_PROV_TRANSPORT_HTTP_CLIENT_07_021: [ If any error is encountered prov_transport_http_register_device shall return a non-zero value. ] */
+        LogError("Failure constructing uri path");
+        HTTPHeaders_Free(http_headers);
+        result = MU_FAILURE;
+    }
+    else if ((json_data = construct_json_data(http_info)) == NULL)
+    {
+        /* Codes_PROV_TRANSPORT_HTTP_CLIENT_07_021: [ If any error is encountered prov_transport_http_register_device shall return a non-zero value. ] */
+        LogError("Failure constructing json payload");
+        HTTPHeaders_Free(http_headers);
+        free(uri_path);
+        result = MU_FAILURE;
+    }
+    else
+    {
+        /* Codes_PROV_TRANSPORT_HTTP_CLIENT_07_020: [ prov_transport_http_register_device shall send the request using the http client. ] */
+        if (uhttp_client_execute_request(http_info->http_client, HTTP_CLIENT_REQUEST_PUT, uri_path, http_headers, (const unsigned char*)json_data, strlen(json_data), on_http_reply_recv, http_info) != HTTP_CLIENT_OK)
+        {
+            /* Codes_PROV_TRANSPORT_HTTP_CLIENT_07_021: [ If any error is encountered prov_transport_http_register_device shall return a non-zero value. ] */
+            LogError("Failure sending http request");
+            result = MU_FAILURE;
+        }
+        else
+        {
+            result = 0;
+        }
+        free(uri_path);
+        free(json_data);
+        HTTPHeaders_Free(http_headers);
+    }
+    return result;
+}
+
+static int send_challenge_response(PROV_TRANSPORT_HTTP_INFO* http_info)
+{
+    int result;
+    HTTP_HEADERS_HANDLE http_headers;
+    char* uri_path;
+    char* json_data;
+
+    if ((http_headers = construct_http_headers(http_info->sas_token)) == NULL)
+    {
+        LogError("failure constructing http headers");
+        result = MU_FAILURE;
+    }
+    else if ((uri_path = construct_url_path(http_info)) == NULL)
+    {
+        LogError("Failure constructing uri path");
+        HTTPHeaders_Free(http_headers);
+        result = MU_FAILURE;
+    }
+    else if ((json_data = construct_json_data(http_info)) == NULL)
+    {
+        /* Codes_PROV_TRANSPORT_HTTP_CLIENT_07_021: [ If any error is encountered prov_transport_http_register_device shall return a non-zero value. ] */
+        LogError("Failure constructing uri path");
+        HTTPHeaders_Free(http_headers);
+        free(uri_path);
+        result = MU_FAILURE;
+    }
+    else
+    {
+        if (uhttp_client_execute_request(http_info->http_client, HTTP_CLIENT_REQUEST_PUT, uri_path, http_headers, (const unsigned char*)json_data, strlen(json_data), on_http_reply_recv, http_info) != HTTP_CLIENT_OK)
+        {
+            LogError("Failure sending http request");
+            result = MU_FAILURE;
+        }
+        else
+        {
+            result = 0;
+        }
+        free(json_data);
+        free(uri_path);
+        HTTPHeaders_Free(http_headers);
+    }
+    return result;
+}
+
+static void free_json_parse_info(PROV_JSON_INFO* parse_info)
+{
+    switch (parse_info->prov_status)
+    {
+        case PROV_DEVICE_TRANSPORT_STATUS_UNASSIGNED:
+            BUFFER_delete(parse_info->authorization_key);
+            free(parse_info->key_name);
+            break;
+        case PROV_DEVICE_TRANSPORT_STATUS_ASSIGNED:
+            BUFFER_delete(parse_info->authorization_key);
+            free(parse_info->iothub_uri);
+            free(parse_info->device_id);
+            break;
+        case PROV_DEVICE_TRANSPORT_STATUS_ASSIGNING:
+            free(parse_info->operation_id);
+            break;
+        default:
+            break;
+    }
+    free(parse_info);
+}
+
+static void free_allocated_data(PROV_TRANSPORT_HTTP_INFO* http_info)
+{
+    free(http_info->hostname);
+    free(http_info->registration_id);
+    free(http_info->api_version);
+    free(http_info->scope_id);
+    free(http_info->certificate);
+    free(http_info->proxy_host);
+    free(http_info->x509_cert);
+    free(http_info->private_key);
+    free(http_info->username);
+    free(http_info->password);
+    free(http_info->payload_data);
+    free(http_info->sas_token);
+    free(http_info->operation_id);
+    BUFFER_delete(http_info->ek);
+    BUFFER_delete(http_info->srk);
+    BUFFER_delete(http_info->nonce);
+    if (http_info->http_client != NULL)
+    {
+        uhttp_client_destroy(http_info->http_client);
+    }
+    free(http_info);
+}
+
+static int create_transport_io_object(PROV_TRANSPORT_HTTP_INFO* http_info)
+{
+    int result;
+    if (http_info->http_client == NULL)
+    {
+        TLSIO_CONFIG tls_io_config;
+        HTTP_PROXY_IO_CONFIG http_proxy;
+        memset(&tls_io_config, 0, sizeof(TLSIO_CONFIG));
+        tls_io_config.hostname = http_info->hostname;
+        tls_io_config.port = HTTP_PORT_NUM;
+
+        // Setup proxy
+        if (http_info->proxy_host != NULL)
+        {
+            memset(&http_proxy, 0, sizeof(HTTP_PROXY_IO_CONFIG));
+            http_proxy.hostname = http_info->hostname;
+            http_proxy.port = HTTP_PORT_NUM;
+            http_proxy.proxy_hostname = http_info->proxy_host;
+            http_proxy.proxy_port = http_info->proxy_port;
+            http_proxy.username = http_info->username;
+            http_proxy.password = http_info->password;
+
+            tls_io_config.underlying_io_interface = http_proxy_io_get_interface_description();
+            tls_io_config.underlying_io_parameters = &http_proxy;
+        }
+        /* Codes_PROV_TRANSPORT_HTTP_CLIENT_07_009: [ prov_transport_http_open shall create the http client adding any proxy and certificate information that is presented. ] */
+        const IO_INTERFACE_DESCRIPTION* interface_desc;
+
+        if ((interface_desc = platform_get_default_tlsio()) == NULL)
+        {
+            LogError("failgetting tls interface description");
+            result = MU_FAILURE;
+        }
+        else if ((http_info->http_client = uhttp_client_create(interface_desc, &tls_io_config, on_http_error, http_info)) == NULL)
+        {
+            LogError("failed to create http client");
+            result = MU_FAILURE;
+        }
+        else
+        {
+            result = 0;
+        }
+    }
+    else
+    {
+        result = 0;
+    }
+    return result;
+}
+
+static int create_connection(PROV_TRANSPORT_HTTP_INFO* http_info)
+{
+    int result;
+    /* Codes_PROV_TRANSPORT_HTTP_CLIENT_07_009: [ prov_transport_http_open shall create the http client adding any proxy and certificate information that is presented. ] */
+    if (create_transport_io_object(http_info) != 0)
+    {
+        LogError("Failure setting transport object");
+        result = MU_FAILURE;
+    }
+    else
+    {
+        (void)uhttp_client_set_trace(http_info->http_client, http_info->log_trace, true);
+
+        if (http_info->certificate != NULL && uhttp_client_set_trusted_cert(http_info->http_client, http_info->certificate) != HTTP_CLIENT_OK)
+        {
+            LogError("fail to set the trusted certificate in the http client");
+            uhttp_client_destroy(http_info->http_client);
+            http_info->http_client = NULL;
+            result = MU_FAILURE;
+        }
+        else
+        {
+            if (http_info->hsm_type == TRANSPORT_HSM_TYPE_X509)
+            {
+                if (http_info->x509_cert == NULL || http_info->private_key == NULL)
+                {
+                    LogError("x509 certificate information was not properly set");
+                    result = MU_FAILURE;
+                }
+                else if (uhttp_client_set_X509_cert(http_info->http_client, true, http_info->x509_cert, http_info->private_key) != HTTP_CLIENT_OK)
+                {
+                    LogError("failed to set x509 certificate information");
+                    result = MU_FAILURE;
+                }
+                else
+                {
+                    result = 0;
+                }
+            }
+            else
+            {
+                result = 0;
+            }
+        }
+    }
+    if (result == 0 && !http_info->http_connected)
+    {
+        /* Codes_PROV_TRANSPORT_HTTP_CLIENT_07_010: [ prov_transport_http_open shall opening the http communications with the service. ] */
+        if (uhttp_client_open(http_info->http_client, http_info->hostname, HTTP_PORT_NUM, on_http_connected, http_info) != HTTP_CLIENT_OK)
+        {
+            LogError("failed to open http client");
+            if (http_info->error_cb != NULL)
+            {
+                http_info->error_cb(PROV_DEVICE_ERROR_KEY_FAIL, http_info->error_ctx);
+            }
+            uhttp_client_destroy(http_info->http_client);
+            http_info->http_client = NULL;
+            result = MU_FAILURE;
+        }
+        else
+        {
+            result = 0;
+        }
+    }
+    return result;
+}
+
+PROV_DEVICE_TRANSPORT_HANDLE prov_transport_http_create(const char* uri, TRANSPORT_HSM_TYPE type, const char* scope_id, const char* api_version, PROV_TRANSPORT_ERROR_CALLBACK error_cb, void* error_ctx)
+{
+    PROV_TRANSPORT_HTTP_INFO* result;
+    if (uri == NULL || scope_id == NULL || api_version == NULL)
+    {
+        /* Codes_PROV_TRANSPORT_HTTP_CLIENT_07_001: [ If uri, scope_id, registration_id or api_version are NULL prov_transport_http_create shall return NULL. ] */
+        LogError("Invalid parameter specified uri: %p, scope_id: %p, api_version: %p", uri, scope_id, api_version);
+        result = NULL;
+    }
+    else
+    {
+        /* Codes_PROV_TRANSPORT_HTTP_CLIENT_07_002: [ prov_transport_http_create shall allocate the memory for the PROV_DEVICE_TRANSPORT_HANDLE variables. ] */
+        result = malloc(sizeof(PROV_TRANSPORT_HTTP_INFO));
+        if (result == NULL)
+        {
+            /* Codes_PROV_TRANSPORT_HTTP_CLIENT_07_003: [ If any error is encountered prov_transport_http_create shall return NULL. ] */
+            LogError("Unable to allocate PROV_TRANSPORT_HTTP_INFO");
+        }
+        else
+        {
+            memset(result, 0, sizeof(PROV_TRANSPORT_HTTP_INFO));
+            if (mallocAndStrcpy_s(&result->hostname, uri) != 0)
+            {
+                /* Codes_PROV_TRANSPORT_HTTP_CLIENT_07_003: [ If any error is encountered prov_transport_http_create shall return NULL. ] */
+                LogError("Failure allocating hostname");
+                free(result);
+                result = NULL;
+            }
+            else if (mallocAndStrcpy_s(&result->api_version, api_version) != 0)
+            {
+                /* Codes_PROV_TRANSPORT_HTTP_CLIENT_07_003: [ If any error is encountered prov_transport_http_create shall return NULL. ] */
+                LogError("Failure allocating api_version");
+                free_allocated_data(result);
+                result = NULL;
+            }
+            else if (mallocAndStrcpy_s(&result->scope_id, scope_id) != 0)
+            {
+                /* Codes_PROV_TRANSPORT_HTTP_CLIENT_07_003: [ If any error is encountered prov_transport_http_create shall return NULL. ] */
+                LogError("Failure allocating scope Id");
+                free_allocated_data(result);
+                result = NULL;
+            }
+            else
+            {
+                result->retry_after_value = PROV_GET_THROTTLE_TIME;
+                result->hsm_type = type;
+                result->error_cb = error_cb;
+                result->error_ctx = error_ctx;
+            }
+        }
+    }
+    /* Codes_PROV_TRANSPORT_HTTP_CLIENT_07_004: [ On success prov_transport_http_create shall return a PROV_DEVICE_TRANSPORT_HANDLE. ] */
+    return result;
+}
+
+void prov_transport_http_destroy(PROV_DEVICE_TRANSPORT_HANDLE handle)
+{
+    /* Codes_PROV_TRANSPORT_HTTP_CLIENT_07_007: [ If the argument handle is NULL, prov_transport_http_destroy shall do nothing ] */
+    if (handle != NULL)
+    {
+        /* Codes_PROV_TRANSPORT_HTTP_CLIENT_07_005: [ prov_transport_http_destroy shall free all resources associated with the PROV_DEVICE_TRANSPORT_HANDLE handle ] */
+        PROV_TRANSPORT_HTTP_INFO* http_info = (PROV_TRANSPORT_HTTP_INFO*)handle;
+        free_allocated_data(http_info);
+    }
+}
+
+int prov_transport_http_open(PROV_DEVICE_TRANSPORT_HANDLE handle, const char* registration_id, BUFFER_HANDLE ek, BUFFER_HANDLE srk, PROV_DEVICE_TRANSPORT_REGISTER_CALLBACK data_callback, void* user_ctx, PROV_DEVICE_TRANSPORT_STATUS_CALLBACK status_cb, void* status_ctx, PROV_TRANSPORT_CHALLENGE_CALLBACK reg_challenge_cb, void* challenge_ctx)
+{
+    int result;
+    PROV_TRANSPORT_HTTP_INFO* http_info = (PROV_TRANSPORT_HTTP_INFO*)handle;
+    if (http_info == NULL || data_callback == NULL || status_cb == NULL || registration_id == NULL)
+    {
+        /* Codes_PROV_TRANSPORT_HTTP_CLIENT_07_008: [ If the argument handle, data_callback, or status_cb are NULL, prov_transport_http_open shall return a non-zero value. ] */
+        LogError("Invalid parameter specified handle: %p, data_callback: %p, status_cb: %p, registration_id: %p", handle, data_callback, status_cb, registration_id);
+        result = MU_FAILURE;
+    }
+    else if ((http_info->hsm_type == TRANSPORT_HSM_TYPE_TPM || http_info->hsm_type == TRANSPORT_HSM_TYPE_SYMM_KEY) && reg_challenge_cb == NULL)
+    {
+        LogError("registration challenge callback must be set");
+        result = MU_FAILURE;
+    }
+    else if (http_info->hsm_type == TRANSPORT_HSM_TYPE_TPM && (ek == NULL || srk == NULL))
+    {
+        LogError("Invalid parameter specified ek: %p, srk: %p", ek, srk);
+        result = MU_FAILURE;
+    }
+    else if (ek != NULL && (http_info->ek = BUFFER_clone(ek)) == NULL)
+    {
+        LogError("Unable to allocate endorsement key");
+        result = MU_FAILURE;
+    }
+    else if (srk != NULL && (http_info->srk = BUFFER_clone(srk)) == NULL)
+    {
+        LogError("Unable to allocate storage root key");
+        BUFFER_delete(http_info->ek);
+        http_info->ek = NULL;
+        result = MU_FAILURE;
+    }
+    else if (mallocAndStrcpy_s(&http_info->registration_id, registration_id) != 0)
+    {
+        /* Codes_PROV_TRANSPORT_HTTP_CLIENT_07_003: [ If any error is encountered prov_transport_http_create shall return NULL. ] */
+        LogError("failure constructing registration Id");
+        BUFFER_delete(http_info->ek);
+        http_info->ek = NULL;
+        BUFFER_delete(http_info->srk);
+        http_info->srk = NULL;
+        result = MU_FAILURE;
+    }
+    else if ((http_info->hsm_type == TRANSPORT_HSM_TYPE_SYMM_KEY) && (http_info->sas_token = reg_challenge_cb(NULL, 0, KEY_NAME_VALUE, challenge_ctx)) == NULL)
+    {
+        LogError("failure constructing challenge value");
+        BUFFER_delete(http_info->ek);
+        http_info->ek = NULL;
+        BUFFER_delete(http_info->srk);
+        http_info->srk = NULL;
+        result = MU_FAILURE;
+    }
+    else
+    {
+        http_info->register_data_cb = data_callback;
+        http_info->user_ctx = user_ctx;
+        http_info->status_cb = status_cb;
+        http_info->status_ctx = status_ctx;
+        http_info->challenge_cb = reg_challenge_cb;
+        http_info->challenge_ctx = challenge_ctx;
+
+        if (create_connection(http_info) != 0)
+        {
+            /* Codes_PROV_TRANSPORT_HTTP_CLIENT_07_013: [ If an error is encountered prov_transport_http_open shall return a non-zero value. ] */
+            LogError("Failure creating http connection");
+            if (http_info->ek != NULL)
+            {
+                BUFFER_delete(http_info->ek);
+                http_info->ek = NULL;
+            }
+            if (http_info->srk != NULL)
+            {
+                BUFFER_delete(http_info->srk);
+                http_info->srk = NULL;
+            }
+            http_info->register_data_cb = NULL;
+            http_info->user_ctx = NULL;
+            http_info->status_cb = NULL;
+            http_info->status_ctx = NULL;
+            free(http_info->registration_id);
+            http_info->registration_id = NULL;
+            result = MU_FAILURE;
+        }
+        else
+        {
+            result = 0;
+        }
+    }
+    /* Codes_PROV_TRANSPORT_HTTP_CLIENT_07_012: [ If successful prov_transport_http_open shall return 0. ] */
+    return result;
+}
+
+int prov_transport_http_close(PROV_DEVICE_TRANSPORT_HANDLE handle)
+{
+    int result;
+    if (handle == NULL)
+    {
+        /* Codes_PROV_TRANSPORT_HTTP_CLIENT_07_014: [ If the argument handle is NULL, prov_transport_http_close shall return a non-zero value. ] */
+        LogError("Invalid parameter specified handle: %p", handle);
+        result = MU_FAILURE;
+    }
+    else
+    {
+        /* Codes_PROV_TRANSPORT_HTTP_CLIENT_07_015: [ prov_transport_http_close shall attempt to close the http communication with the service. ] */
+        PROV_TRANSPORT_HTTP_INFO* http_info = (PROV_TRANSPORT_HTTP_INFO*)handle;
+        if (http_info->http_client != NULL)
+        {
+            BUFFER_delete(http_info->ek);
+            http_info->ek = NULL;
+            BUFFER_delete(http_info->srk);
+            http_info->srk = NULL;
+            free(http_info->registration_id);
+            http_info->registration_id = NULL;
+
+            uhttp_client_close(http_info->http_client, NULL, NULL);
+            uhttp_client_dowork(http_info->http_client);
+
+            /* Codes_PROV_TRANSPORT_HTTP_CLIENT_07_006: [ prov_transport_http_close shall call the uhttp_client_destroy function function associated with the http_client ] */
+            uhttp_client_destroy(http_info->http_client);
+            http_info->http_client = NULL;
+        }
+        http_info->http_connected = false;
+        /* Codes_PROV_TRANSPORT_HTTP_CLIENT_07_016: [ On success prov_transport_http_close shall return 0. ] */
+        result = 0;
+    }
+    return result;
+}
+
+int prov_transport_http_register_device(PROV_DEVICE_TRANSPORT_HANDLE handle, PROV_TRANSPORT_JSON_PARSE json_parse_cb, PROV_TRANSPORT_CREATE_JSON_PAYLOAD json_create_cb, void* json_ctx)
+{
+    int result;
+    PROV_TRANSPORT_HTTP_INFO* http_info = (PROV_TRANSPORT_HTTP_INFO*)handle;
+    if (http_info == NULL || json_parse_cb == NULL || json_create_cb == NULL)
+    {
+        /* Codes_PROV_TRANSPORT_HTTP_CLIENT_07_017: [ If the argument handle or json_data is NULL, prov_transport_http_register_device shall return a non-zero value. ] */
+        LogError("Invalid parameter specified handle: %p, json_parse_cb: %p", handle, json_parse_cb);
+        result = MU_FAILURE;
+    }
+    else if (http_info->transport_state == TRANSPORT_CLIENT_STATE_ERROR)
+    {
+        LogError("Provisioning is in an error state, close the connection and try again.");
+        result = MU_FAILURE;
+    }
+    else
+    {
+        /* Codes_PROV_TRANSPORT_HTTP_CLIENT_07_022: [ On success prov_transport_http_register_device shall return 0. ] */
+        http_info->transport_state = TRANSPORT_CLIENT_STATE_REG_SEND;
+        http_info->json_parse_cb = json_parse_cb;
+        http_info->json_create_cb = json_create_cb;
+        http_info->json_ctx = json_ctx;
+
+        result = 0;
+    }
+    return result;
+}
+
+int prov_transport_http_get_operation_status(PROV_DEVICE_TRANSPORT_HANDLE handle)
+{
+    int result;
+    if (handle == NULL)
+    {
+        /* Codes_PROV_TRANSPORT_HTTP_CLIENT_07_029: [ If the argument handle, or operation_id is NULL, prov_transport_http_get_operation_status shall return a non-zero value. ] */
+        LogError("Invalid parameter specified handle: %p", handle);
+        result = MU_FAILURE;
+    }
+    else
+    {
+        PROV_TRANSPORT_HTTP_INFO* http_info = (PROV_TRANSPORT_HTTP_INFO*)handle;
+        HTTP_HEADERS_HANDLE http_headers;
+        char* uri_path;
+
+        if (http_info->operation_id == NULL)
+        {
+            LogError("operation_id was not previously set in the challenge method");
+            result = MU_FAILURE;
+        }
+        /* Codes_PROV_TRANSPORT_HTTP_CLIENT_07_030: [ prov_transport_http_get_operation_status shall construct the http headers with SAS_TOKEN as Authorization header. ] */
+        else if ((http_headers = construct_http_headers(http_info->sas_token)) == NULL)
+        {
+            /* Codes_PROV_TRANSPORT_HTTP_CLIENT_07_033: [ If any error is encountered prov_transport_http_get_operation_status shall return a non-zero value. ] */
+            LogError("failure constructing http headers");
+            result = MU_FAILURE;
+        }
+        /* Codes_PROV_TRANSPORT_HTTP_CLIENT_07_031: [ prov_transport_http_get_operation_status shall construct the path to the service in the following format: /<scope_id>/registrations/<url_encoded_registration_id>/operations<url_encoded_operation_id>?api-version=<api_version> ] */
+        else if ((uri_path = construct_url_path(http_info)) == NULL)
+        {
+            /* Codes_PROV_TRANSPORT_HTTP_CLIENT_07_033: [ If any error is encountered prov_transport_http_get_operation_status shall return a non-zero value. ] */
+            LogError("Failure constructing uri path");
+            result = MU_FAILURE;
+        }
+        else
+        {
+            /* Codes_PROV_TRANSPORT_HTTP_CLIENT_07_032: [ prov_transport_http_get_operation_status shall send the request using the http client. ] */
+            if (uhttp_client_execute_request(http_info->http_client, HTTP_CLIENT_REQUEST_GET, uri_path, http_headers, NULL, 0, on_http_reply_recv, http_info) != HTTP_CLIENT_OK)
+            {
+                /* Codes_PROV_TRANSPORT_HTTP_CLIENT_07_033: [ If any error is encountered prov_transport_http_get_operation_status shall return a non-zero value. ] */
+                LogError("Failure sending data to server");
+                result = MU_FAILURE;
+            }
+            else
+            {
+                http_info->transport_state = TRANSPORT_CLIENT_STATE_STATUS_SENT;
+                /* Codes_PROV_TRANSPORT_HTTP_CLIENT_07_034: [ On success prov_transport_http_get_operation_status shall return 0. ] */
+                result = 0;
+            }
+            HTTPHeaders_Free(http_headers);
+            free(uri_path);
+        }
+    }
+    return result;
+}
+
+void prov_transport_http_dowork(PROV_DEVICE_TRANSPORT_HANDLE handle)
+{
+    if (handle != NULL)
+    {
+        PROV_TRANSPORT_HTTP_INFO* http_info = (PROV_TRANSPORT_HTTP_INFO*)handle;
+        /* Codes_PROV_TRANSPORT_HTTP_CLIENT_07_036: [ prov_transport_http_dowork shall call the underlying http client do work method. ] */
+        uhttp_client_dowork(http_info->http_client);
+
+        if (http_info->http_connected || http_info->transport_state == TRANSPORT_CLIENT_STATE_ERROR)
+        {
+            switch (http_info->transport_state)
+            {
+            case TRANSPORT_CLIENT_STATE_REG_SEND:
+                if (send_registration_info(http_info) != 0)
+                {
+                    LogError("NULL sas_token provided in challenge callback.");
+                    http_info->transport_state = TRANSPORT_CLIENT_STATE_ERROR;
+                }
+                else
+                {
+                    http_info->transport_state = TRANSPORT_CLIENT_STATE_REG_SENT;
+                }
+                break;
+            case TRANSPORT_CLIENT_STATE_STATUS_RECV:
+            case TRANSPORT_CLIENT_STATE_REG_RECV:
+            {
+                /* Codes_PROV_TRANSPORT_HTTP_CLIENT_07_037: [ If the prov_transport_http_dowork state is Message received prov_transport_http_dowork shall call the calling process registration_data callback ] */
+                PROV_JSON_INFO* parse_info = http_info->json_parse_cb(http_info->payload_data, http_info->json_ctx);
+                if (parse_info == NULL)
+                {
+                    LogError("Unable to process registration reply.");
+                    http_info->transport_state = TRANSPORT_CLIENT_STATE_ERROR;
+                }
+                else
+                {
+                    switch (parse_info->prov_status)
+                    {
+                        case PROV_DEVICE_TRANSPORT_STATUS_ASSIGNED:
+                            http_info->register_data_cb(PROV_DEVICE_TRANSPORT_RESULT_OK, parse_info->authorization_key, parse_info->iothub_uri, parse_info->device_id, http_info->user_ctx);
+                            http_info->transport_state = TRANSPORT_CLIENT_STATE_IDLE;
+                            break;
+
+                        case PROV_DEVICE_TRANSPORT_STATUS_UNASSIGNED:
+                        {
+                            const unsigned char* nonce = BUFFER_u_char(parse_info->authorization_key);
+                            size_t nonce_len = BUFFER_length(parse_info->authorization_key);
+
+                            http_info->sas_token = http_info->challenge_cb(nonce, nonce_len, parse_info->key_name, http_info->user_ctx);
+                            if (http_info->sas_token == NULL)
+                            {
+                                LogError("NULL sas_token provided in challenge callback.");
+                                http_info->transport_state = TRANSPORT_CLIENT_STATE_ERROR;
+                            }
+                            else
+                            {
+                                send_challenge_response(http_info);
+                                http_info->transport_state = TRANSPORT_CLIENT_STATE_REG_SENT;
+                            }
+                            break;
+                        }
+
+                        case PROV_DEVICE_TRANSPORT_STATUS_ASSIGNING:
+                            if (parse_info->operation_id == NULL)
+                            {
+                                LogError("Failure operation Id invalid");
+                                http_info->transport_state = TRANSPORT_CLIENT_STATE_ERROR;
+                            }
+                            else if (http_info->operation_id == NULL && mallocAndStrcpy_s(&http_info->operation_id, parse_info->operation_id) != 0)
+                            {
+                                LogError("Failure copying operation Id");
+                                http_info->transport_state = TRANSPORT_CLIENT_STATE_ERROR;
+                            }
+                            else
+                            {
+                                if (http_info->status_cb != NULL)
+                                {
+                                    http_info->status_cb(parse_info->prov_status, http_info->retry_after_value, http_info->status_ctx);
+                                }
+                                http_info->transport_state = TRANSPORT_CLIENT_STATE_IDLE;
+                            }
+                            break;
+
+                        default:
+                        case PROV_DEVICE_TRANSPORT_STATUS_ERROR:
+                            LogError("Unable to process status reply");
+                            http_info->transport_state = TRANSPORT_CLIENT_STATE_ERROR;
+                            break;
+                    }
+                    free_json_parse_info(parse_info);
+                }
+                break;
+            }
+
+            case TRANSPORT_CLIENT_STATE_TRANSIENT:
+                if (http_info->status_cb != NULL)
+                {
+                    http_info->status_cb(PROV_DEVICE_TRANSPORT_STATUS_TRANSIENT, http_info->retry_after_value, http_info->status_ctx);
+                }
+                http_info->transport_state = TRANSPORT_CLIENT_STATE_IDLE;
+                break;
+
+            case TRANSPORT_CLIENT_STATE_ERROR:
+                /* Codes_PROV_TRANSPORT_HTTP_CLIENT_07_039: [ If the state is Error, prov_transport_http_dowork shall call the registration_data callback with PROV_DEVICE_TRANSPORT_RESULT_ERROR and NULL payload_data. ] */
+                http_info->register_data_cb(PROV_DEVICE_TRANSPORT_RESULT_ERROR, NULL, NULL, NULL, http_info->user_ctx);
+                http_info->transport_state = TRANSPORT_CLIENT_STATE_IDLE;
+                break;
+
+            case TRANSPORT_CLIENT_STATE_REG_SENT:
+            case TRANSPORT_CLIENT_STATE_STATUS_SENT:
+            case TRANSPORT_CLIENT_STATE_IDLE:
+            default:
+                break;
+            }
+        }
+    }
+}
+
+int prov_transport_http_set_trace(PROV_DEVICE_TRANSPORT_HANDLE handle, bool trace_on)
+{
+    int result;
+    if (handle == NULL)
+    {
+        /* Codes_PROV_TRANSPORT_HTTP_CLIENT_07_040: [ If the argument handle, is NULL, prov_transport_http_set_trace shall return a non-zero value. ] */
+        LogError("Invalid parameter specified handle: %p", handle);
+        result = MU_FAILURE;
+    }
+    else
+    {
+        PROV_TRANSPORT_HTTP_INFO* http_info = (PROV_TRANSPORT_HTTP_INFO*)handle;
+        if (http_info->hsm_type == TRANSPORT_HSM_TYPE_X509)
+        {
+            http_info->log_trace = trace_on;
+            if (http_info->http_client != NULL)
+            {
+                /* Codes_PROV_TRANSPORT_HTTP_CLIENT_07_041: [ If the http client is not NULL, prov_transport_http_set_trace shall set the http client log trace function with the specified trace_on flag. ] */
+                (void)uhttp_client_set_trace(http_info->http_client, http_info->log_trace, http_info->log_trace);
+            }
+            /* Codes_PROV_TRANSPORT_HTTP_CLIENT_07_042: [ On success prov_transport_http_set_trace shall return zero. ] */
+            result = 0;
+        }
+        else
+        {
+            LogError("Unable to enable logging when not using x509 certificates");
+                result = MU_FAILURE;
+        }
+    }
+    return result;
+}
+
+static int prov_transport_http_x509_cert(PROV_DEVICE_TRANSPORT_HANDLE handle, const char* certificate, const char* private_key)
+{
+    int result;
+    if (handle == NULL || certificate == NULL || private_key == NULL)
+    {
+        /* Codes_PROV_TRANSPORT_HTTP_CLIENT_07_043: [ If the argument handle, private_key or certificate is NULL, prov_transport_http_x509_cert shall return a non-zero value. ] */
+        LogError("Invalid parameter specified handle: %p, certificate: %p, private_key: %p", handle, certificate, private_key);
+        result = MU_FAILURE;
+    }
+    else
+    {
+        PROV_TRANSPORT_HTTP_INFO* http_info = (PROV_TRANSPORT_HTTP_INFO*)handle;
+        if (http_info->x509_cert != NULL)
+        {
+            free(http_info->x509_cert);
+        }
+        if (http_info->private_key != NULL)
+        {
+            free(http_info->private_key);
+        }
+
+        /* Codes_PROV_TRANSPORT_HTTP_CLIENT_07_045: [ prov_transport_http_x509_cert shall store the certificate and private_key for use when the http client connects. ] */
+        if (mallocAndStrcpy_s(&http_info->x509_cert, certificate) != 0)
+        {
+            /* Codes_PROV_TRANSPORT_HTTP_CLIENT_07_044: [ If any error is encountered prov_transport_http_x509_cert shall return a non-zero value. ] */
+            result = MU_FAILURE;
+            LogError("failure allocating certificate");
+        }
+        else if (mallocAndStrcpy_s(&http_info->private_key, private_key) != 0)
+        {
+            /* Codes_PROV_TRANSPORT_HTTP_CLIENT_07_044: [ If any error is encountered prov_transport_http_x509_cert shall return a non-zero value. ] */
+            free(http_info->x509_cert);
+            http_info->x509_cert = NULL;
+            result = MU_FAILURE;
+            LogError("failure allocating certificate");
+        }
+        else
+        {
+            /* Codes_PROV_TRANSPORT_HTTP_CLIENT_07_046: [ On success prov_transport_http_set_trace shall return zero. ] */
+            result = 0;
+        }
+    }
+    return result;
+}
+
+static int prov_transport_http_set_trusted_cert(PROV_DEVICE_TRANSPORT_HANDLE handle, const char* certificate)
+{
+    int result;
+    if (handle == NULL || certificate == NULL)
+    {
+        /* Codes_PROV_TRANSPORT_HTTP_CLIENT_07_047: [ If the argument handle, certificate is NULL, prov_transport_http_set_trusted_cert shall return a non-zero value. ] */
+        LogError("Invalid parameter specified handle: %p, certificate: %p", handle, certificate);
+        result = MU_FAILURE;
+    }
+    else
+    {
+        PROV_TRANSPORT_HTTP_INFO* http_info = (PROV_TRANSPORT_HTTP_INFO*)handle;
+        if (http_info->certificate != NULL)
+        {
+            free(http_info->certificate);
+        }
+
+        /* Codes_PROV_TRANSPORT_HTTP_CLIENT_07_049: [ prov_transport_http_set_trusted_cert shall store the certificate for use when the http client connects. ] */
+        if (mallocAndStrcpy_s(&http_info->certificate, certificate) != 0)
+        {
+            /* Codes_PROV_TRANSPORT_HTTP_CLIENT_07_048: [ If any error is encountered prov_transport_http_set_trusted_cert shall return a non-zero value. ] */
+            result = MU_FAILURE;
+            LogError("failure allocating certificate");
+        }
+        else
+        {
+            /* Codes_PROV_TRANSPORT_HTTP_CLIENT_07_050: [ On success prov_transport_http_set_trusted_cert shall return zero. ] */
+            result = 0;
+        }
+    }
+    return result;
+}
+
+static int prov_transport_http_set_proxy(PROV_DEVICE_TRANSPORT_HANDLE handle, const HTTP_PROXY_OPTIONS* proxy_options)
+{
+    int result;
+    if (handle == NULL || proxy_options == NULL)
+    {
+        /* Codes_PROV_TRANSPORT_HTTP_CLIENT_07_051: [ If the argument handle or proxy_options is NULL, prov_transport_http_set_proxy shall return a non-zero value. ] */
+        LogError("Invalid parameter specified handle: %p, proxy_options: %p", handle, proxy_options);
+        result = MU_FAILURE;
+    }
+    else
+    {
+        PROV_TRANSPORT_HTTP_INFO* http_info = (PROV_TRANSPORT_HTTP_INFO*)handle;
+        if (proxy_options->host_address == NULL)
+        {
+            /* Codes_PROV_TRANSPORT_HTTP_CLIENT_07_055: [ If proxy_options host_name is NULL prov_transport_http_set_proxy shall return a non-zero value. ] */
+            LogError("NULL host_address in proxy options");
+            result = MU_FAILURE;
+        }
+        else if (((proxy_options->username == NULL) || (proxy_options->password == NULL)) &&
+            (proxy_options->username != proxy_options->password))
+        {
+            /* Codes_PROV_TRANSPORT_HTTP_CLIENT_07_053: [ If proxy_options username is NULL and proxy_options::password is not NULL prov_transport_http_set_proxy shall return a non-zero value. ] */
+            LogError("Only one of username and password for proxy settings was NULL");
+            result = MU_FAILURE;
+        }
+        else
+        {
+            if (http_info->proxy_host != NULL)
+            {
+                free(http_info->proxy_host);
+            }
+            if (http_info->username != NULL)
+            {
+                free(http_info->username);
+                http_info->username = NULL;
+            }
+            if (http_info->password != NULL)
+            {
+                free(http_info->password);
+                http_info->password = NULL;
+            }
+
+            http_info->proxy_port = proxy_options->port;
+            if (mallocAndStrcpy_s(&http_info->proxy_host, proxy_options->host_address) != 0)
+            {
+                /* Codes_PROV_TRANSPORT_HTTP_CLIENT_07_052: [ If any error is encountered prov_transport_http_set_proxy shall return a non-zero value. ] */
+                LogError("Failure setting proxy_host name");
+                result = MU_FAILURE;
+            }
+            else if (proxy_options->username != NULL && mallocAndStrcpy_s(&http_info->username, proxy_options->username) != 0)
+            {
+                /* Codes_PROV_TRANSPORT_HTTP_CLIENT_07_052: [ If any error is encountered prov_transport_http_set_proxy shall return a non-zero value. ] */
+                free(http_info->proxy_host);
+                http_info->proxy_host = NULL;
+                LogError("Failure setting proxy username");
+                result = MU_FAILURE;
+            }
+            else if (proxy_options->password != NULL && mallocAndStrcpy_s(&http_info->password, proxy_options->password) != 0)
+            {
+                /* Codes_PROV_TRANSPORT_HTTP_CLIENT_07_052: [ If any error is encountered prov_transport_http_set_proxy shall return a non-zero value. ] */
+                LogError("Failure setting proxy password");
+                free(http_info->proxy_host);
+                http_info->proxy_host = NULL;
+                free(http_info->username);
+                http_info->username = NULL;
+                result = MU_FAILURE;
+            }
+            else
+            {
+                /* Codes_PROV_TRANSPORT_HTTP_CLIENT_07_054: [ On success prov_transport_http_set_proxy shall return zero. ] */
+                result = 0;
+            }
+        }
+    }
+    return result;
+}
+
+static int prov_transport_http_set_option(PROV_DEVICE_TRANSPORT_HANDLE handle, const char* option, const void* value)
+{
+    int result;
+    // needs to invoke correct behavior
+    if (handle == NULL || option == NULL)
+    {
+        LogError("Invalid parameter specified handle: %p, option: %p", handle, option);
+        result = MU_FAILURE;
+    }
+    else
+    {
+        PROV_TRANSPORT_HTTP_INFO* http_info = (PROV_TRANSPORT_HTTP_INFO*)handle;
+        if (http_info->http_client == NULL && create_transport_io_object(http_info) != 0)
+        {
+            LogError("Failure creating transport io object");
+            result = MU_FAILURE;
+        }
+        else
+        {
+            result = uhttp_client_set_option(http_info->http_client, option, value);
+        }
+    }
+    return result;
+}
+
+static PROV_DEVICE_TRANSPORT_PROVIDER prov_http_func =
+{
+    prov_transport_http_create,
+    prov_transport_http_destroy,
+    prov_transport_http_open,
+    prov_transport_http_close,
+    prov_transport_http_register_device,
+    prov_transport_http_get_operation_status,
+    prov_transport_http_dowork,
+    prov_transport_http_set_trace,
+    prov_transport_http_x509_cert,
+    prov_transport_http_set_trusted_cert,
+    prov_transport_http_set_proxy,
+    prov_transport_http_set_option
+};
+
+const PROV_DEVICE_TRANSPORT_PROVIDER* Prov_Device_HTTP_Protocol(void)
+{
+    return &prov_http_func;
+}
Index: azure_iot_hub_f767zi/trunk/azure_iot_sdk/provisioning_client/src/prov_transport_mqtt_client.c
===================================================================
--- azure_iot_hub_f767zi/trunk/azure_iot_sdk/provisioning_client/src/prov_transport_mqtt_client.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/azure_iot_sdk/provisioning_client/src/prov_transport_mqtt_client.c	(revision 457)
@@ -0,0 +1,151 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+#include <stdlib.h>
+#include "azure_c_shared_utility/gballoc.h"
+#include "azure_prov_client/prov_transport_mqtt_client.h"
+#include "azure_prov_client/internal/prov_transport_mqtt_common.h"
+#include "azure_c_shared_utility/xio.h"
+#include "azure_c_shared_utility/tlsio.h"
+#include "azure_c_shared_utility/http_proxy_io.h"
+#include "azure_c_shared_utility/platform.h"
+#include "azure_c_shared_utility/xlogging.h"
+#include "azure_c_shared_utility/shared_util_options.h"
+
+#define MQTT_PORT_NUM               8883
+
+static XIO_HANDLE mqtt_transport_io(const char* fqdn, const HTTP_PROXY_OPTIONS* proxy_info)
+{
+    XIO_HANDLE result;
+    HTTP_PROXY_IO_CONFIG proxy_config;
+    TLSIO_CONFIG tls_io_config;
+
+    memset(&tls_io_config, 0, sizeof(TLSIO_CONFIG));
+    tls_io_config.hostname = fqdn;
+    tls_io_config.port = MQTT_PORT_NUM;
+    if (proxy_info != NULL)
+    {
+        /* Codes_PROV_TRANSPORT_MQTT_CLIENT_07_012: [ If proxy_info is not NULL, amqp_transport_io shall construct a HTTP_PROXY_IO_CONFIG object and assign it to TLSIO_CONFIG underlying_io_parameters ] */
+        proxy_config.hostname = tls_io_config.hostname;
+        proxy_config.port = MQTT_PORT_NUM;
+        proxy_config.proxy_hostname = proxy_info->host_address;
+        proxy_config.proxy_port = proxy_info->port;
+        proxy_config.username = proxy_info->username;
+        proxy_config.password = proxy_info->password;
+
+        tls_io_config.underlying_io_interface = http_proxy_io_get_interface_description();
+        tls_io_config.underlying_io_parameters = &proxy_config;
+    }
+
+    const IO_INTERFACE_DESCRIPTION* tlsio_interface = platform_get_default_tlsio();
+    if (tlsio_interface == NULL)
+    {
+        /* Codes_PROV_TRANSPORT_MQTT_CLIENT_07_013: [ If any failure is encountered amqp_transport_io shall return NULL ]*/
+        LogError("platform_get_default_tlsio return NULL IO Interface");
+        result = NULL;
+    }
+    else
+    {
+        result = xio_create(tlsio_interface, &tls_io_config);
+        if (result == NULL)
+        {
+            /* Codes_PROV_TRANSPORT_MQTT_CLIENT_07_013: [ If any failure is encountered amqp_transport_io shall return NULL ]*/
+            LogError("failed calling xio_create on underlying io");
+            result = NULL;
+        }
+    }
+    /* Codes_PROV_TRANSPORT_MQTT_CLIENT_07_014: [ On success mqtt_transport_io shall return allocated XIO_HANDLE. ] */
+    return result;
+}
+
+PROV_DEVICE_TRANSPORT_HANDLE prov_transport_mqtt_create(const char* uri, TRANSPORT_HSM_TYPE type, const char* scope_id, const char* api_version, PROV_TRANSPORT_ERROR_CALLBACK error_cb, void* error_ctx)
+{
+    /* Codes_PROV_TRANSPORT_MQTT_CLIENT_07_001: [ prov_transport_mqtt_create shall call the prov_transport_common_mqtt_create function with mqtt_transport_io transport IO estabishment. ] */
+    return prov_transport_common_mqtt_create(uri, type, scope_id, api_version, mqtt_transport_io, error_cb, error_ctx);
+}
+
+void prov_transport_mqtt_destroy(PROV_DEVICE_TRANSPORT_HANDLE handle)
+{
+    /* Codes_PROV_TRANSPORT_MQTT_CLIENT_07_002: [ prov_transport_mqtt_destroy shall invoke the prov_transport_common_mqtt_destroy method ] */
+    prov_transport_common_mqtt_destroy(handle);
+}
+
+int prov_transport_mqtt_open(PROV_DEVICE_TRANSPORT_HANDLE handle, const char* registration_id, BUFFER_HANDLE ek, BUFFER_HANDLE srk, PROV_DEVICE_TRANSPORT_REGISTER_CALLBACK data_callback, void* user_ctx, PROV_DEVICE_TRANSPORT_STATUS_CALLBACK status_cb, void* status_ctx, PROV_TRANSPORT_CHALLENGE_CALLBACK reg_challenge_cb, void* challenge_ctx)
+{
+    /* Codes_PROV_TRANSPORT_MQTT_CLIENT_07_003: [ prov_transport_mqtt_open shall invoke the prov_transport_common_mqtt_open method ] */
+    return prov_transport_common_mqtt_open(handle, registration_id, ek, srk, data_callback, user_ctx, status_cb, status_ctx, reg_challenge_cb, challenge_ctx);
+}
+
+int prov_transport_mqtt_close(PROV_DEVICE_TRANSPORT_HANDLE handle)
+{
+    /* Codes_PROV_TRANSPORT_MQTT_CLIENT_07_004: [ prov_transport_mqtt_close shall invoke the prov_transport_common_mqtt_close method ] */
+    return prov_transport_common_mqtt_close(handle);
+}
+
+int prov_transport_mqtt_register_device(PROV_DEVICE_TRANSPORT_HANDLE handle, PROV_TRANSPORT_JSON_PARSE json_parse_cb, PROV_TRANSPORT_CREATE_JSON_PAYLOAD json_create_cb, void* json_ctx)
+{
+    /* Codes_PROV_TRANSPORT_MQTT_CLIENT_07_005: [ prov_transport_mqtt_register_device shall invoke the prov_transport_common_mqtt_register_device method ] */
+    return prov_transport_common_mqtt_register_device(handle, json_parse_cb, json_create_cb, json_ctx);
+}
+
+int prov_transport_mqtt_get_operation_status(PROV_DEVICE_TRANSPORT_HANDLE handle)
+{
+    /* Codes_PROV_TRANSPORT_MQTT_CLIENT_07_006: [ prov_transport_mqtt_get_operation_status shall invoke the prov_transport_common_mqtt_get_operation_status method ] */
+    return prov_transport_common_mqtt_get_operation_status(handle);
+}
+
+void prov_transport_mqtt_dowork(PROV_DEVICE_TRANSPORT_HANDLE handle)
+{
+    /* Codes_PROV_TRANSPORT_MQTT_CLIENT_07_007: [ prov_transport_mqtt_dowork shall invoke the prov_transport_common_mqtt_dowork method ] */
+    prov_transport_common_mqtt_dowork(handle);
+}
+
+int prov_transport_mqtt_set_trace(PROV_DEVICE_TRANSPORT_HANDLE handle, bool trace_on)
+{
+    /* Codes_PROV_TRANSPORT_MQTT_CLIENT_07_008: [ prov_transport_mqtt_set_trace shall invoke the prov_transport_common_mqtt_set_trace method ] */
+    return prov_transport_common_mqtt_set_trace(handle, trace_on);
+}
+
+static int prov_transport_mqtt_x509_cert(PROV_DEVICE_TRANSPORT_HANDLE handle, const char* certificate, const char* private_key)
+{
+    /* Codes_PROV_TRANSPORT_MQTT_CLIENT_07_009: [ prov_transport_mqtt_x509_cert shall invoke the prov_trans_common_mqtt_x509_cert method ]*/
+    return prov_transport_common_mqtt_x509_cert(handle, certificate, private_key);
+}
+
+static int prov_transport_mqtt_set_trusted_cert(PROV_DEVICE_TRANSPORT_HANDLE handle, const char* certificate)
+{
+    /* Codes_PROV_TRANSPORT_MQTT_CLIENT_07_010: [ prov_transport_mqtt_set_trusted_cert shall invoke the prov_transport_common_mqtt_set_trusted_cert method ] */
+    return prov_transport_common_mqtt_set_trusted_cert(handle, certificate);
+}
+
+static int prov_transport_mqtt_set_proxy(PROV_DEVICE_TRANSPORT_HANDLE handle, const HTTP_PROXY_OPTIONS* proxy_options)
+{
+    /* Codes_PROV_TRANSPORT_MQTT_CLIENT_07_011: [ prov_transport_mqtt_set_proxy shall invoke the prov_transport_common_mqtt_set_proxy method ] */
+    return prov_transport_common_mqtt_set_proxy(handle, proxy_options);
+}
+
+static int prov_transport_mqtt_set_option(PROV_DEVICE_TRANSPORT_HANDLE handle, const char* option, const void* value)
+{
+    return prov_transport_common_mqtt_set_option(handle, option, value);
+}
+
+static PROV_DEVICE_TRANSPORT_PROVIDER prov_mqtt_func =
+{
+    prov_transport_mqtt_create,
+    prov_transport_mqtt_destroy,
+    prov_transport_mqtt_open,
+    prov_transport_mqtt_close,
+    prov_transport_mqtt_register_device,
+    prov_transport_mqtt_get_operation_status,
+    prov_transport_mqtt_dowork,
+    prov_transport_mqtt_set_trace,
+    prov_transport_mqtt_x509_cert,
+    prov_transport_mqtt_set_trusted_cert,
+    prov_transport_mqtt_set_proxy,
+    prov_transport_mqtt_set_option
+};
+
+const PROV_DEVICE_TRANSPORT_PROVIDER* Prov_Device_MQTT_Protocol(void)
+{
+    return &prov_mqtt_func;
+}
Index: azure_iot_hub_f767zi/trunk/azure_iot_sdk/provisioning_client/src/prov_transport_mqtt_common.c
===================================================================
--- azure_iot_hub_f767zi/trunk/azure_iot_sdk/provisioning_client/src/prov_transport_mqtt_common.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/azure_iot_sdk/provisioning_client/src/prov_transport_mqtt_common.c	(revision 457)
@@ -0,0 +1,1303 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+#include <stdlib.h>
+#include <stdint.h>
+#include <stdbool.h>
+#include <ctype.h>
+#include <limits.h>
+#include <inttypes.h>
+
+#include "azure_c_shared_utility/gballoc.h"
+#include "azure_c_shared_utility/platform.h"
+#include "azure_c_shared_utility/xlogging.h"
+#include "azure_c_shared_utility/crt_abstractions.h"
+#include "azure_c_shared_utility/tlsio.h"
+#include "azure_c_shared_utility/shared_util_options.h"
+#include "azure_c_shared_utility/http_proxy_io.h"
+#include "azure_c_shared_utility/urlencode.h"
+#include "azure_c_shared_utility/http_proxy_io.h"
+
+#include "azure_prov_client/internal/prov_transport_mqtt_common.h"
+#include "azure_umqtt_c/mqtt_client.h"
+
+#include "azure_prov_client/prov_client_const.h"
+
+#define SUBSCRIBE_TOPIC_COUNT       1
+
+static const char* const MQTT_SUBSCRIBE_TOPIC = "$dps/registrations/res/#";
+static const char* const MQTT_USERNAME_FMT = "%s/registrations/%s/api-version=%s&ClientVersion=%s";
+static const char* const MQTT_REGISTER_MESSAGE_FMT = "$dps/registrations/PUT/iotdps-register/?$rid=%d";
+static const char* const MQTT_STATUS_MESSAGE_FMT = "$dps/registrations/GET/iotdps-get-operationstatus/?$rid=%d&operationId=%s";
+static const char* const MQTT_TOPIC_STATUS_PREFIX = "$dps/registrations/res/";
+static const char* const KEY_NAME_VALUE = "registration";
+
+typedef enum MQTT_TRANSPORT_STATE_TAG
+{
+    MQTT_STATE_IDLE,
+    MQTT_STATE_DISCONNECTED,
+    MQTT_STATE_CONNECTING,
+    MQTT_STATE_CONNECTED,
+
+    MQTT_STATE_SUBSCRIBING,
+    MQTT_STATE_SUBSCRIBED,
+
+    MQTT_STATE_ERROR
+} MQTT_TRANSPORT_STATE;
+
+typedef enum PROV_TRANSPORT_STATE_TAG
+{
+    TRANSPORT_CLIENT_STATE_IDLE,
+
+    TRANSPORT_CLIENT_STATE_REG_SEND,
+    TRANSPORT_CLIENT_STATE_REG_SENT,
+    TRANSPORT_CLIENT_STATE_REG_RECV,
+
+    TRANSPORT_CLIENT_STATE_STATUS_SEND,
+    TRANSPORT_CLIENT_STATE_STATUS_SENT,
+    TRANSPORT_CLIENT_STATE_STATUS_RECV,
+
+    TRANSPORT_CLIENT_STATE_TRANSIENT,
+    TRANSPORT_CLIENT_STATE_ERROR
+} PROV_TRANSPORT_STATE;
+
+typedef struct PROV_TRANSPORT_MQTT_INFO_TAG
+{
+    PROV_DEVICE_TRANSPORT_REGISTER_CALLBACK register_data_cb;
+    void* user_ctx;
+    PROV_DEVICE_TRANSPORT_STATUS_CALLBACK status_cb;
+    void* status_ctx;
+    PROV_TRANSPORT_CHALLENGE_CALLBACK challenge_cb;
+    void* challenge_ctx;
+    PROV_TRANSPORT_JSON_PARSE json_parse_cb;
+    PROV_TRANSPORT_CREATE_JSON_PAYLOAD json_create_cb;
+    void* json_ctx;
+
+    MQTT_CLIENT_HANDLE mqtt_client;
+
+    char* hostname;
+
+    HTTP_PROXY_OPTIONS proxy_option;
+
+    char* x509_cert;
+    char* private_key;
+
+    char* certificate;
+
+    BUFFER_HANDLE ek;
+    BUFFER_HANDLE srk;
+    char* registration_id;
+    char* scope_id;
+    char* sas_token;
+
+    char* operation_id;
+
+    char* api_version;
+    char* payload_data;
+
+    bool log_trace;
+
+    uint16_t packet_id;
+
+    TRANSPORT_HSM_TYPE hsm_type;
+
+    PROV_MQTT_TRANSPORT_IO transport_io_cb;
+
+    PROV_TRANSPORT_STATE transport_state;
+    MQTT_TRANSPORT_STATE mqtt_state;
+
+    XIO_HANDLE transport_io;
+    uint32_t retry_after_value;
+
+    PROV_TRANSPORT_ERROR_CALLBACK error_cb;
+    void* error_ctx;
+} PROV_TRANSPORT_MQTT_INFO;
+
+static uint16_t get_next_packet_id(PROV_TRANSPORT_MQTT_INFO* mqtt_info)
+{
+    if (mqtt_info->packet_id + 1 >= USHRT_MAX)
+    {
+        mqtt_info->packet_id = 1;
+    }
+    else
+    {
+        mqtt_info->packet_id++;
+    }
+    return mqtt_info->packet_id;
+}
+
+static void mqtt_error_callback(MQTT_CLIENT_HANDLE handle, MQTT_CLIENT_EVENT_ERROR error, void* user_ctx)
+{
+    (void)handle;
+    if (user_ctx != NULL)
+    {
+        PROV_TRANSPORT_MQTT_INFO* mqtt_info = (PROV_TRANSPORT_MQTT_INFO*)user_ctx;
+        switch (error)
+        {
+            case MQTT_CLIENT_CONNECTION_ERROR:
+            case MQTT_CLIENT_COMMUNICATION_ERROR:
+                LogError("MQTT communication error");
+                break;
+            case MQTT_CLIENT_NO_PING_RESPONSE:
+                LogError("Mqtt Ping Response was not encountered.  Reconnecting device...");
+                break;
+
+            case MQTT_CLIENT_PARSE_ERROR:
+            case MQTT_CLIENT_MEMORY_ERROR:
+            case MQTT_CLIENT_UNKNOWN_ERROR:
+            default:
+            {
+                LogError("INTERNAL ERROR: unexpected error value received %d", error);
+                break;
+            }
+        }
+        mqtt_info->transport_state = TRANSPORT_CLIENT_STATE_ERROR;
+        mqtt_info->mqtt_state = MQTT_STATE_ERROR;
+    }
+    else
+    {
+        LogError("mqtt_error_callback was invoked with a NULL context");
+    }
+}
+
+#ifndef NO_LOGGING
+static const char* retrieve_mqtt_return_codes(CONNECT_RETURN_CODE rtn_code)
+{
+    switch (rtn_code)
+    {
+    case CONNECTION_ACCEPTED:
+        return "Accepted";
+    case CONN_REFUSED_UNACCEPTABLE_VERSION:
+        return "Unacceptable Version";
+    case CONN_REFUSED_ID_REJECTED:
+        return "Id Rejected";
+    case CONN_REFUSED_SERVER_UNAVAIL:
+        return "Server Unavailable";
+    case CONN_REFUSED_BAD_USERNAME_PASSWORD:
+        return "Bad Username/Password";
+    case CONN_REFUSED_NOT_AUTHORIZED:
+        return "Not Authorized";
+    case CONN_REFUSED_UNKNOWN:
+    default:
+        return "Unknown";
+    }
+}
+#endif // NO_LOGGING
+
+static void mqtt_operation_complete_callback(MQTT_CLIENT_HANDLE handle, MQTT_CLIENT_EVENT_RESULT event_result, const void* msg_info, void* user_ctx)
+{
+    (void)handle;
+    (void)msg_info;
+    if (user_ctx != NULL)
+    {
+        PROV_TRANSPORT_MQTT_INFO* mqtt_info = (PROV_TRANSPORT_MQTT_INFO*)user_ctx;
+        switch (event_result)
+        {
+            case MQTT_CLIENT_ON_CONNACK:
+            {
+                const CONNECT_ACK* connack = (const CONNECT_ACK*)msg_info;
+                if (connack != NULL)
+                {
+                    if (connack->returnCode == CONNECTION_ACCEPTED)
+                    {
+                        /* Tests_PROV_TRANSPORT_MQTT_COMMON_07_052: [ Once the mqtt CONNACK is recieved prov_transport_common_mqtt_dowork shall set mqtt_state to MQTT_STATE_CONNECTED ] */
+                        mqtt_info->mqtt_state = MQTT_STATE_CONNECTED;
+                    }
+                    else
+                    {
+                        LogError("Connection Not Accepted: 0x%x: %s", connack->returnCode, retrieve_mqtt_return_codes(connack->returnCode));
+                        mqtt_info->transport_state = TRANSPORT_CLIENT_STATE_ERROR;
+                        mqtt_info->mqtt_state = MQTT_STATE_ERROR;
+                        if (mqtt_info->error_cb != NULL)
+                        {
+                            mqtt_info->error_cb(PROV_DEVICE_ERROR_KEY_UNAUTHORIZED, mqtt_info->error_ctx);
+                        }
+                    }
+                }
+                else
+                {
+                    mqtt_info->transport_state = TRANSPORT_CLIENT_STATE_ERROR;
+                    mqtt_info->mqtt_state = MQTT_STATE_ERROR;
+                    LogError("CONNECT_ACK packet is NULL");
+                }
+                break;
+            }
+            case MQTT_CLIENT_ON_SUBSCRIBE_ACK:
+            {
+                const SUBSCRIBE_ACK* suback = (const SUBSCRIBE_ACK*)msg_info;
+                if (suback != NULL)
+                {
+                    size_t index = 0;
+                    for (index = 0; index < suback->qosCount; index++)
+                    {
+                        if (suback->qosReturn[index] == DELIVER_FAILURE)
+                        {
+                            LogError("Subscribe delivery failure of subscribe %lu", (unsigned long)index);
+                            break;
+                        }
+                    }
+
+                    if (index == suback->qosCount)
+                    {
+                        mqtt_info->mqtt_state = MQTT_STATE_SUBSCRIBED;
+                    }
+                    else
+                    {
+                        mqtt_info->transport_state = TRANSPORT_CLIENT_STATE_ERROR;
+                        mqtt_info->mqtt_state = MQTT_STATE_ERROR;
+                    }
+                }
+                else
+                {
+                    mqtt_info->transport_state = TRANSPORT_CLIENT_STATE_ERROR;
+                    mqtt_info->mqtt_state = MQTT_STATE_ERROR;
+                    LogError("SUBSCRIBE_ACK packet is NULL");
+                }
+                break;
+            }
+            case MQTT_CLIENT_ON_PUBLISH_ACK:
+            case MQTT_CLIENT_ON_PUBLISH_COMP:
+            case MQTT_CLIENT_ON_PUBLISH_RECV:
+            case MQTT_CLIENT_ON_PUBLISH_REL:
+            case MQTT_CLIENT_ON_DISCONNECT:
+            case MQTT_CLIENT_ON_UNSUBSCRIBE_ACK:
+                break;
+            default:
+                LogError("Unknown MQTT_CLIENT_EVENT_RESULT item %d", (int)event_result);
+                break;
+        }
+    }
+    else
+    {
+        LogError("mqtt_operation_complete_callback was invoked with a NULL context");
+    }
+}
+
+static int get_retry_after_property(const char* topic_name, PROV_TRANSPORT_MQTT_INFO* mqtt_info)
+{
+    int result = MU_FAILURE;
+
+    const char* iterator = topic_name;
+
+    size_t topic_len = strlen(iterator);
+    size_t retry_len = strlen(RETRY_AFTER_KEY_VALUE);
+    while (iterator != NULL && *iterator != '\0')
+    {
+        if (topic_len > retry_len)
+        {
+            if (memcmp(iterator, RETRY_AFTER_KEY_VALUE, retry_len) == 0)
+            {
+                // send the retry-after value to parse
+                mqtt_info->retry_after_value = parse_retry_after_value(iterator + retry_len + 1);
+                result = 0;
+                break;
+            }
+        }
+        else
+        {
+            // Topic string is not there
+            result = MU_FAILURE;
+            break;
+        }
+        iterator++;
+        topic_len--;
+    }
+    return result;
+}
+
+static void mqtt_notification_callback(MQTT_MESSAGE_HANDLE handle, void* user_ctx)
+{
+    if (user_ctx != NULL)
+    {
+        PROV_TRANSPORT_MQTT_INFO* mqtt_info = (PROV_TRANSPORT_MQTT_INFO*)user_ctx;
+
+        bool is_transient_error = false;
+        const char* topic_resp = mqttmessage_getTopicName(handle);
+        if (topic_resp != NULL)
+        {
+            // Extract the registration status
+            size_t status_pos = strlen(MQTT_TOPIC_STATUS_PREFIX);
+            if (memcmp(MQTT_TOPIC_STATUS_PREFIX, topic_resp, status_pos) == 0)
+            {
+                // If the status code is > 429 then this is a transient error
+                long status_code = atol(topic_resp + status_pos);
+                if (status_code >= PROV_STATUS_CODE_TRANSIENT_ERROR)
+                {
+                    // On transient error reset the transport to send state
+                    mqtt_info->transport_state = TRANSPORT_CLIENT_STATE_TRANSIENT;
+                    is_transient_error = true;
+                }
+            }
+
+            // Get the retry after field on failures this value will
+            // be set to the default value
+            (void)get_retry_after_property(topic_resp, mqtt_info);
+        }
+        else
+        {
+            LogError("failure topic name is NULL");
+            mqtt_info->transport_state = TRANSPORT_CLIENT_STATE_ERROR;
+            mqtt_info->mqtt_state = MQTT_STATE_ERROR;
+        }
+
+        if (!is_transient_error)
+        {
+            const APP_PAYLOAD* payload = mqttmessage_getApplicationMsg(handle);
+            if (payload != NULL)
+            {
+                if (mqtt_info->payload_data != NULL)
+                {
+                    free(mqtt_info->payload_data);
+                    mqtt_info->payload_data = NULL;
+                }
+
+                if ((mqtt_info->payload_data = malloc(payload->length + 1)) == NULL)
+                {
+                    LogError("failure allocating payload data");
+                    mqtt_info->transport_state = TRANSPORT_CLIENT_STATE_ERROR;
+                    mqtt_info->mqtt_state = MQTT_STATE_ERROR;
+                }
+                else
+                {
+                    memset(mqtt_info->payload_data, 0, payload->length + 1);
+                    memcpy(mqtt_info->payload_data, payload->message, payload->length);
+                    if (mqtt_info->transport_state == TRANSPORT_CLIENT_STATE_REG_SENT)
+                    {
+                        mqtt_info->transport_state = TRANSPORT_CLIENT_STATE_REG_RECV;
+                    }
+                    else
+                    {
+                        mqtt_info->transport_state = TRANSPORT_CLIENT_STATE_STATUS_RECV;
+                    }
+                }
+            }
+            else
+            {
+                LogError("failure NULL message encountered from umqtt");
+                mqtt_info->transport_state = TRANSPORT_CLIENT_STATE_ERROR;
+                mqtt_info->mqtt_state = MQTT_STATE_ERROR;
+            }
+        }
+    }
+    else
+    {
+        LogError("mqtt_notification_callback was invoked with a NULL context");
+    }
+}
+
+static int send_mqtt_message(PROV_TRANSPORT_MQTT_INFO* mqtt_info, const char* msg_topic)
+{
+    int result;
+    MQTT_MESSAGE_HANDLE msg_handle = NULL;
+    char* prov_payload;
+
+    if ((prov_payload = mqtt_info->json_create_cb(NULL, NULL, mqtt_info->json_ctx)) == NULL)
+    {
+        LogError("Failed creating json mqtt payload");
+        result = MU_FAILURE;
+    }
+    else if ((msg_handle = mqttmessage_create_in_place(get_next_packet_id(mqtt_info), msg_topic, DELIVER_AT_MOST_ONCE, (const uint8_t*)prov_payload, strlen(prov_payload))) == NULL)
+    {
+        LogError("Failed creating mqtt message");
+        result = MU_FAILURE;
+        free(prov_payload);
+    }
+    else
+    {
+        if (mqtt_client_publish(mqtt_info->mqtt_client, msg_handle) != 0)
+        {
+            LogError("Failed publishing client message");
+            result = MU_FAILURE;
+        }
+        else
+        {
+            result = 0;
+        }
+        mqttmessage_destroy(msg_handle);
+        free(prov_payload);
+    }
+    return result;
+}
+
+static int send_register_message(PROV_TRANSPORT_MQTT_INFO* mqtt_info)
+{
+    int result;
+    char* msg_topic;
+
+    size_t length = strlen(MQTT_REGISTER_MESSAGE_FMT) + 8;
+    if ((msg_topic = malloc(length + 1)) == NULL)
+    {
+        LogError("Failed allocating mqtt registration message");
+        result = MU_FAILURE;
+    }
+    else if (sprintf(msg_topic, MQTT_REGISTER_MESSAGE_FMT, mqtt_info->packet_id) <= 0)
+    {
+        LogError("Failed setting registration message");
+        free(msg_topic);
+        result = MU_FAILURE;
+    }
+    else
+    {
+        result = send_mqtt_message(mqtt_info, msg_topic);
+        free(msg_topic);
+    }
+    return result;
+}
+
+static int send_operation_status_message(PROV_TRANSPORT_MQTT_INFO* mqtt_info)
+{
+    int result;
+    char* msg_topic;
+
+    size_t length = strlen(MQTT_STATUS_MESSAGE_FMT) + strlen(mqtt_info->operation_id) + 8;
+    if ((msg_topic = malloc(length + 1)) == NULL)
+    {
+        LogError("Failed allocating mqtt status message");
+        result = MU_FAILURE;
+    }
+    else if (sprintf(msg_topic, MQTT_STATUS_MESSAGE_FMT, mqtt_info->packet_id, mqtt_info->operation_id) <= 0)
+    {
+        LogError("Failed creating mqtt status message");
+        free(msg_topic);
+        result = MU_FAILURE;
+    }
+    else
+    {
+        result = send_mqtt_message(mqtt_info, msg_topic);
+        free(msg_topic);
+    }
+    return result;
+}
+
+static int subscribe_to_topic(PROV_TRANSPORT_MQTT_INFO* mqtt_info)
+{
+    int result;
+    SUBSCRIBE_PAYLOAD subscribe[SUBSCRIBE_TOPIC_COUNT];
+    subscribe[0].subscribeTopic = MQTT_SUBSCRIBE_TOPIC;
+    subscribe[0].qosReturn = DELIVER_AT_LEAST_ONCE;
+
+    if (mqtt_client_subscribe(mqtt_info->mqtt_client, get_next_packet_id(mqtt_info), subscribe, SUBSCRIBE_TOPIC_COUNT) != 0)
+    {
+        LogError("Failed subscribing to topic.");
+        result = MU_FAILURE;
+    }
+    else
+    {
+        result = 0;
+    }
+    return result;
+}
+
+static char* construct_username(PROV_TRANSPORT_MQTT_INFO* mqtt_info)
+{
+    char* result;
+    size_t length;
+
+    length = strlen(MQTT_USERNAME_FMT) + strlen(mqtt_info->registration_id) + strlen(mqtt_info->scope_id) + strlen(mqtt_info->api_version) + strlen(PROV_DEVICE_CLIENT_VERSION);
+    if ((result = malloc(length + 1)) == NULL)
+    {
+        LogError("Failure allocating username");
+        result = NULL;
+    }
+    else if (sprintf(result, MQTT_USERNAME_FMT, mqtt_info->scope_id, mqtt_info->registration_id, mqtt_info->api_version, PROV_DEVICE_CLIENT_VERSION) <= 0)
+    {
+        LogError("Failure creating mqtt username");
+        free(result);
+        result = NULL;
+    }
+    return result;
+}
+
+static int create_transport_io_object(PROV_TRANSPORT_MQTT_INFO* mqtt_info)
+{
+    int result;
+    if (mqtt_info->transport_io == NULL)
+    {
+        HTTP_PROXY_OPTIONS* transport_proxy;
+        if (mqtt_info->proxy_option.host_address != NULL)
+        {
+            transport_proxy = &mqtt_info->proxy_option;
+        }
+        else
+        {
+            transport_proxy = NULL;
+        }
+
+        if ((mqtt_info->transport_io = mqtt_info->transport_io_cb(mqtt_info->hostname, transport_proxy)) == NULL)
+        {
+            LogError("Failure calling transport_io callback");
+            result = MU_FAILURE;
+        }
+        else
+        {
+            result = 0;
+        }
+    }
+    else
+    {
+        result = 0;
+    }
+    return result;
+}
+
+static int construct_transport(PROV_TRANSPORT_MQTT_INFO* mqtt_info)
+{
+    int result;
+
+    if (create_transport_io_object(mqtt_info) != 0)
+    {
+        LogError("Failed constructing transport io");
+        result = MU_FAILURE;
+    }
+    else
+    {
+        if (mqtt_info->certificate != NULL && xio_setoption(mqtt_info->transport_io, OPTION_TRUSTED_CERT, mqtt_info->certificate) != 0)
+        {
+            LogError("Failure setting trusted certs");
+            result = MU_FAILURE;
+            xio_destroy(mqtt_info->transport_io);
+            mqtt_info->transport_io = NULL;
+        }
+        else if (mqtt_info->hsm_type == TRANSPORT_HSM_TYPE_X509)
+        {
+            if (mqtt_info->x509_cert != NULL && mqtt_info->private_key != NULL)
+            {
+                if (xio_setoption(mqtt_info->transport_io, OPTION_X509_ECC_CERT, mqtt_info->x509_cert) != 0)
+                {
+                    LogError("Failure setting x509 cert on xio");
+                    xio_destroy(mqtt_info->transport_io);
+                    mqtt_info->transport_io = NULL;
+                    result = MU_FAILURE;
+                }
+                else if (xio_setoption(mqtt_info->transport_io, OPTION_X509_ECC_KEY, mqtt_info->private_key) != 0)
+                {
+                    LogError("Failure setting x509 key on xio");
+                    if (mqtt_info->error_cb != NULL)
+                    {
+                        mqtt_info->error_cb(PROV_DEVICE_ERROR_KEY_FAIL, mqtt_info->error_ctx);
+                    }
+                    xio_destroy(mqtt_info->transport_io);
+                    mqtt_info->transport_io = NULL;
+                    result = MU_FAILURE;
+                }
+                else
+                {
+                    result = 0;
+                }
+            }
+            else
+            {
+                LogError("x509 certificate is NULL");
+                xio_destroy(mqtt_info->transport_io);
+                mqtt_info->transport_io = NULL;
+                result = MU_FAILURE;
+            }
+        }
+        else
+        {
+            result = 0;
+        }
+    }
+    return result;
+}
+
+static int create_connection(PROV_TRANSPORT_MQTT_INFO* mqtt_info)
+{
+    int result;
+    MQTT_CLIENT_OPTIONS options;
+    memset(&options, 0, sizeof(MQTT_CLIENT_OPTIONS));
+
+    char* username_info;
+
+    if ((username_info = construct_username(mqtt_info)) == NULL)
+    {
+        LogError("Failure creating username info");
+        result = MU_FAILURE;
+    }
+    else if (construct_transport(mqtt_info) != 0)
+    {
+        LogError("Failure constructing transport");
+        free(username_info);
+        result = MU_FAILURE;
+    }
+    else if ((mqtt_info->hsm_type == TRANSPORT_HSM_TYPE_SYMM_KEY) && (options.password = mqtt_info->challenge_cb(NULL, 0, KEY_NAME_VALUE, mqtt_info->challenge_ctx)) == NULL)
+    {
+        LogError("Failure retrieving sas token from key");
+        xio_destroy(mqtt_info->transport_io);
+        mqtt_info->transport_io = NULL;
+        free(username_info);
+        result = MU_FAILURE;
+    }
+    else
+    {
+        (void)mqtt_client_set_trace(mqtt_info->mqtt_client, mqtt_info->log_trace, false);
+
+        options.username = username_info;
+        options.clientId = mqtt_info->registration_id;
+        options.useCleanSession = 1;
+        options.log_trace = mqtt_info->log_trace;
+        options.qualityOfServiceValue = DELIVER_AT_LEAST_ONCE;
+        if (mqtt_client_connect(mqtt_info->mqtt_client, mqtt_info->transport_io, &options) != 0)
+        {
+            xio_destroy(mqtt_info->transport_io);
+            mqtt_info->transport_io = NULL;
+            LogError("Failure connecting to mqtt server");
+            result = MU_FAILURE;
+        }
+        else
+        {
+            result = 0;
+        }
+        if (options.password != NULL)
+        {
+            free(options.password);
+        }
+        free(username_info);
+    }
+    return result;
+}
+
+static void free_json_parse_info(PROV_JSON_INFO* parse_info)
+{
+    switch (parse_info->prov_status)
+    {
+        case PROV_DEVICE_TRANSPORT_STATUS_UNASSIGNED:
+            BUFFER_delete(parse_info->authorization_key);
+            free(parse_info->key_name);
+            break;
+        case PROV_DEVICE_TRANSPORT_STATUS_ASSIGNED:
+            BUFFER_delete(parse_info->authorization_key);
+            free(parse_info->iothub_uri);
+            free(parse_info->device_id);
+            break;
+        case PROV_DEVICE_TRANSPORT_STATUS_ASSIGNING:
+            free(parse_info->operation_id);
+            break;
+        default:
+            break;
+    }
+    free(parse_info);
+}
+
+void cleanup_mqtt_data(PROV_TRANSPORT_MQTT_INFO* mqtt_info)
+{
+    free(mqtt_info->hostname);
+    free(mqtt_info->registration_id);
+    free(mqtt_info->operation_id);
+    free(mqtt_info->api_version);
+    free(mqtt_info->scope_id);
+    free(mqtt_info->certificate);
+    free((char*)mqtt_info->proxy_option.host_address);
+    free((char*)mqtt_info->proxy_option.username);
+    free((char*)mqtt_info->proxy_option.password);
+    free(mqtt_info->x509_cert);
+    free(mqtt_info->private_key);
+    free(mqtt_info->sas_token);
+    free(mqtt_info->payload_data);
+    if (mqtt_info->transport_io != NULL)
+    {
+        xio_destroy(mqtt_info->transport_io);
+    }
+    free(mqtt_info);
+}
+
+PROV_DEVICE_TRANSPORT_HANDLE prov_transport_common_mqtt_create(const char* uri, TRANSPORT_HSM_TYPE type, const char* scope_id, const char* api_version, PROV_MQTT_TRANSPORT_IO transport_io, PROV_TRANSPORT_ERROR_CALLBACK error_cb, void* error_ctx)
+{
+    PROV_TRANSPORT_MQTT_INFO* result;
+    if (uri == NULL || scope_id == NULL || api_version == NULL || transport_io == NULL)
+    {
+        /* Codes_PROV_TRANSPORT_MQTT_COMMON_07_001: [ If uri, scope_id, registration_id, api_version, or transport_io is NULL, prov_transport_common_mqtt_create shall return NULL. ] */
+        LogError("Invalid parameter specified uri: %p, scope_id: %p, api_version: %p, transport_io: %p", uri, scope_id, api_version, transport_io);
+        result = NULL;
+    }
+    else if (type == TRANSPORT_HSM_TYPE_TPM)
+    {
+        /* Codes_PROV_TRANSPORT_MQTT_COMMON_07_062: [ If TRANSPORT_HSM_TYPE is TRANSPORT_HSM_TYPE_TPM prov_transport_common_mqtt_create shall return NULL (currently TPM is not supported). ] */
+        LogError("HSM type of TPM is not supported");
+        result = NULL;
+    }
+    else
+    {
+        /* Codes_PROV_TRANSPORT_MQTT_COMMON_07_003: [ prov_transport_common_mqtt_create shall allocate a PROV_TRANSPORT_MQTT_INFO and initialize the containing fields. ] */
+        result = malloc(sizeof(PROV_TRANSPORT_MQTT_INFO));
+        if (result == NULL)
+        {
+            /* Codes_PROV_TRANSPORT_MQTT_COMMON_07_002: [ If any error is encountered, prov_transport_common_mqtt_create shall return NULL. ] */
+            LogError("Unable to allocate PROV_TRANSPORT_MQTT_INFO");
+        }
+        else
+        {
+            memset(result, 0, sizeof(PROV_TRANSPORT_MQTT_INFO));
+            if (mallocAndStrcpy_s(&result->hostname, uri) != 0)
+            {
+                /* Codes_PROV_TRANSPORT_MQTT_COMMON_07_002: [ If any error is encountered, prov_transport_common_mqtt_create shall return NULL. ] */
+                LogError("Failure allocating hostname");
+                free(result);
+                result = NULL;
+            }
+            else if (mallocAndStrcpy_s(&result->api_version, api_version) != 0)
+            {
+                /* Codes_PROV_TRANSPORT_MQTT_COMMON_07_002: [ If any error is encountered, prov_transport_common_mqtt_create shall return NULL. ] */
+                LogError("Failure allocating api_version");
+                cleanup_mqtt_data(result);
+                result = NULL;
+            }
+            else if (mallocAndStrcpy_s(&result->scope_id, scope_id) != 0)
+            {
+                /* Codes_PROV_TRANSPORT_MQTT_COMMON_07_002: [ If any error is encountered, prov_transport_common_mqtt_create shall return NULL. ] */
+                LogError("Failure allocating scope_id");
+                cleanup_mqtt_data(result);
+                result = NULL;
+            }
+            else if ((result->mqtt_client = mqtt_client_init(mqtt_notification_callback, mqtt_operation_complete_callback, result, mqtt_error_callback, result)) == NULL)
+            {
+                /* Codes_PROV_TRANSPORT_MQTT_COMMON_07_002: [ If any error is encountered, prov_transport_common_mqtt_create shall return NULL. ] */
+                LogError("Failed initializing mqtt client.");
+                cleanup_mqtt_data(result);
+                result = NULL;
+            }
+            else
+            {
+                result->transport_io_cb = transport_io;
+                result->hsm_type = type;
+                result->error_cb = error_cb;
+                result->error_ctx = error_ctx;
+                result->retry_after_value = PROV_GET_THROTTLE_TIME;
+            }
+        }
+    }
+    /* Codes_PROV_TRANSPORT_MQTT_COMMON_07_004: [ On success prov_transport_common_mqtt_create shall return a new instance of PROV_DEVICE_TRANSPORT_HANDLE. ] */
+    return result;
+}
+
+void prov_transport_common_mqtt_destroy(PROV_DEVICE_TRANSPORT_HANDLE handle)
+{
+    /* Tests_PROV_TRANSPORT_MQTT_COMMON_07_005: [ If handle is NULL, prov_transport_common_mqtt_destroy shall do nothing. ] */
+    if (handle != NULL)
+    {
+        /* Tests_PROV_TRANSPORT_MQTT_COMMON_07_006: [ prov_transport_common_mqtt_destroy shall free all resources used in this module. ] */
+        PROV_TRANSPORT_MQTT_INFO* mqtt_info = (PROV_TRANSPORT_MQTT_INFO*)handle;
+        mqtt_client_deinit(mqtt_info->mqtt_client);
+        mqtt_info->mqtt_client = NULL;
+        cleanup_mqtt_data(mqtt_info);
+    }
+}
+
+int prov_transport_common_mqtt_open(PROV_DEVICE_TRANSPORT_HANDLE handle, const char* registration_id, BUFFER_HANDLE ek, BUFFER_HANDLE srk, PROV_DEVICE_TRANSPORT_REGISTER_CALLBACK data_callback, void* user_ctx, PROV_DEVICE_TRANSPORT_STATUS_CALLBACK status_cb, void* status_ctx, PROV_TRANSPORT_CHALLENGE_CALLBACK reg_challenge_cb, void* challenge_ctx)
+{
+    int result;
+    PROV_TRANSPORT_MQTT_INFO* mqtt_info = (PROV_TRANSPORT_MQTT_INFO*)handle;
+    if (mqtt_info == NULL || data_callback == NULL || status_cb == NULL || registration_id == NULL)
+    {
+        /* Tests_PROV_TRANSPORT_MQTT_COMMON_07_007: [ If handle, data_callback, or status_cb is NULL, prov_transport_common_mqtt_open shall return a non-zero value. ] */
+        LogError("Invalid parameter specified handle: %p, data_callback: %p, status_cb: %p, registration_id: %p", handle, data_callback, status_cb, registration_id);
+        result = MU_FAILURE;
+    }
+    else if ((mqtt_info->hsm_type == TRANSPORT_HSM_TYPE_TPM || mqtt_info->hsm_type == TRANSPORT_HSM_TYPE_SYMM_KEY) && reg_challenge_cb == NULL)
+    {
+        LogError("registration challenge callback must be set");
+        result = MU_FAILURE;
+    }
+    // Should never be here since TPM is not supported, so I'm going to check to ensure compliance
+    else if (ek != NULL || srk != NULL)
+    {
+        /* Codes_PROV_TRANSPORT_MQTT_COMMON_07_008: [ If hsm_type is TRANSPORT_HSM_TYPE_TPM and ek or srk is NULL, prov_transport_common_mqtt_open shall return a non-zero value. ] */
+        LogError("Invalid parameter specified ek: %p, srk: %p", ek, srk);
+        result = MU_FAILURE;
+    }
+    else if (mallocAndStrcpy_s(&mqtt_info->registration_id, registration_id) != 0)
+    {
+        /* Codes_PROV_TRANSPORT_HTTP_CLIENT_07_003: [ If any error is encountered prov_transport_http_create shall return NULL. ] */
+        LogError("failure constructing registration Id");
+        result = MU_FAILURE;
+    }
+    else
+    {
+        mqtt_info->register_data_cb = data_callback;
+        mqtt_info->user_ctx = user_ctx;
+        mqtt_info->status_cb = status_cb;
+        mqtt_info->status_ctx = status_ctx;
+        mqtt_info->mqtt_state = MQTT_STATE_DISCONNECTED;
+        // Must add a false connect here due to the protocol quirk
+        //mqtt_info->status_cb(PROV_DEVICE_TRANSPORT_STATUS_CONNECTED, mqtt_info->status_ctx);
+        mqtt_info->challenge_cb = reg_challenge_cb;
+        mqtt_info->challenge_ctx = challenge_ctx;
+
+        result = 0;
+    }
+    return result;
+}
+
+int prov_transport_common_mqtt_close(PROV_DEVICE_TRANSPORT_HANDLE handle)
+{
+    int result;
+    if (handle == NULL)
+    {
+        /* Tests_PROV_TRANSPORT_MQTT_COMMON_07_011: [ If handle is NULL, prov_transport_common_mqtt_close shall return a non-zero value. ] */
+        LogError("Invalid parameter specified handle: %p", handle);
+        result = MU_FAILURE;
+    }
+    else
+    {
+        PROV_TRANSPORT_MQTT_INFO* mqtt_info = (PROV_TRANSPORT_MQTT_INFO*)handle;
+        BUFFER_delete(mqtt_info->ek);
+        mqtt_info->ek = NULL;
+        BUFFER_delete(mqtt_info->srk);
+        mqtt_info->srk = NULL;
+        free(mqtt_info->registration_id);
+        mqtt_info->registration_id = NULL;
+
+        /* Tests_PROV_TRANSPORT_MQTT_COMMON_07_012: [ prov_transport_common_mqtt_close shall close all connection associated with mqtt communication. ] */
+        if (mqtt_client_disconnect(mqtt_info->mqtt_client, NULL, NULL) == 0)
+        {
+            mqtt_client_dowork(mqtt_info->mqtt_client);
+        }
+        xio_destroy(mqtt_info->transport_io);
+        mqtt_info->transport_io = NULL;
+
+        /* Tests_PROV_TRANSPORT_MQTT_COMMON_07_013: [ On success prov_transport_common_mqtt_close shall return a zero value. ] */
+        mqtt_info->mqtt_state = MQTT_STATE_IDLE;
+        result = 0;
+    }
+    return result;
+}
+
+int prov_transport_common_mqtt_register_device(PROV_DEVICE_TRANSPORT_HANDLE handle, PROV_TRANSPORT_JSON_PARSE json_parse_cb, PROV_TRANSPORT_CREATE_JSON_PAYLOAD json_create_cb, void* json_ctx)
+{
+    int result;
+    PROV_TRANSPORT_MQTT_INFO* mqtt_info = (PROV_TRANSPORT_MQTT_INFO*)handle;
+    if (mqtt_info == NULL || json_parse_cb == NULL || json_create_cb == NULL)
+    {
+        /* Tests_PROV_TRANSPORT_MQTT_COMMON_07_014: [ If handle is NULL, prov_transport_common_mqtt_register_device shall return a non-zero value. ] */
+        LogError("Invalid parameter specified handle: %p, json_parse_cb: %p", handle, json_parse_cb);
+        result = MU_FAILURE;
+    }
+    /* Tests_PROV_TRANSPORT_MQTT_COMMON_07_061: [ If the transport_state is TRANSPORT_CLIENT_STATE_REG_SEND or the the operation_id is NULL, prov_transport_common_mqtt_register_device shall return a non-zero value. ] */
+    else if (mqtt_info->transport_state == TRANSPORT_CLIENT_STATE_REG_SEND || mqtt_info->operation_id != NULL)
+    {
+        LogError("Failure: device is currently in the registration process");
+        result = MU_FAILURE;
+    }
+    else if (mqtt_info->transport_state == TRANSPORT_CLIENT_STATE_ERROR)
+    {
+        LogError("Provisioning is in an error state, close the connection and try again.");
+        result = MU_FAILURE;
+    }
+    else
+    {
+        mqtt_info->transport_state = TRANSPORT_CLIENT_STATE_REG_SEND;
+        mqtt_info->json_parse_cb = json_parse_cb;
+        mqtt_info->json_create_cb = json_create_cb;
+        mqtt_info->json_ctx = json_ctx;
+
+        /* Tests_PROV_TRANSPORT_MQTT_COMMON_07_017: [ On success prov_transport_common_mqtt_register_device shall return a zero value. ] */
+        result = 0;
+    }
+    return result;
+}
+
+int prov_transport_common_mqtt_get_operation_status(PROV_DEVICE_TRANSPORT_HANDLE handle)
+{
+    int result;
+    if (handle == NULL)
+    {
+        /* Tests_PROV_TRANSPORT_MQTT_COMMON_07_018: [ If handle is NULL, prov_transport_common_mqtt_get_operation_status shall return a non-zero value. ] */
+        LogError("Invalid parameter specified handle: %p", handle);
+        result = MU_FAILURE;
+    }
+    else
+    {
+        PROV_TRANSPORT_MQTT_INFO* mqtt_info = (PROV_TRANSPORT_MQTT_INFO*)handle;
+        if (mqtt_info->operation_id == NULL)
+        {
+            /* Tests_PROV_TRANSPORT_MQTT_COMMON_07_019: [ If the operation_id is NULL, prov_transport_common_mqtt_get_operation_status shall return a non-zero value. ] */
+            LogError("operation_id was not previously set in the challenge method");
+            result = MU_FAILURE;
+        }
+        else if (mqtt_info->transport_state == TRANSPORT_CLIENT_STATE_ERROR)
+        {
+            LogError("Provisioning is in an error state, close the connection and try again.");
+            result = MU_FAILURE;
+        }
+        else
+        {
+            /* Tests_PROV_TRANSPORT_MQTT_COMMON_07_021: [ prov_transport_common_mqtt_get_operation_status shall set the transport_state to TRANSPORT_CLIENT_STATE_STATUS_SEND. ] */
+            mqtt_info->transport_state = TRANSPORT_CLIENT_STATE_STATUS_SEND;
+            /* Tests_PROV_TRANSPORT_MQTT_COMMON_07_022: [ On success prov_transport_common_mqtt_get_operation_status shall return a zero value. ] */
+            result = 0;
+        }
+    }
+    return result;
+}
+
+void prov_transport_common_mqtt_dowork(PROV_DEVICE_TRANSPORT_HANDLE handle)
+{
+    /* Tests_PROV_TRANSPORT_MQTT_COMMON_07_046: [ If handle is NULL, prov_transport_common_mqtt_dowork shall do nothing. ] */
+    if (handle != NULL)
+    {
+        PROV_TRANSPORT_MQTT_INFO* mqtt_info = (PROV_TRANSPORT_MQTT_INFO*)handle;
+        if (mqtt_info->mqtt_state == MQTT_STATE_DISCONNECTED)
+        {
+            /* Tests_PROV_TRANSPORT_MQTT_COMMON_07_047: [ If the mqtt_state is MQTT_STATE_DISCONNECTED prov_transport_common_mqtt_dowork shall attempt to connect the mqtt connections. ] */
+            if (create_connection(mqtt_info) != 0)
+            {
+                /* Tests_PROV_TRANSPORT_MQTT_COMMON_07_049: [ If any error is encountered prov_transport_common_mqtt_dowork shall set the mqtt_state to MQTT_STATE_ERROR and the transport_state to TRANSPORT_CLIENT_STATE_ERROR. ] */
+                LogError("unable to create mqtt connection");
+                mqtt_info->mqtt_state = MQTT_STATE_ERROR;
+                mqtt_info->transport_state = TRANSPORT_CLIENT_STATE_ERROR;
+            }
+            else
+            {
+                mqtt_info->mqtt_state = MQTT_STATE_CONNECTING;
+            }
+        }
+        else if (mqtt_info->mqtt_state == MQTT_STATE_CONNECTED)
+        {
+            mqtt_client_dowork(mqtt_info->mqtt_client);
+            /* Tests_PROV_TRANSPORT_MQTT_COMMON_07_050: [ When the mqtt_state is MQTT_STATE_CONNECTED, prov_transport_common_mqtt_dowork shall subscribe to the topic $dps/registrations/res/# ] */
+            if (subscribe_to_topic(mqtt_info) != 0)
+            {
+                /* Tests_PROV_TRANSPORT_MQTT_COMMON_07_049: [ If any error is encountered prov_transport_common_mqtt_dowork shall set the mqtt_state to MQTT_STATE_ERROR and the transport_state to TRANSPORT_CLIENT_STATE_ERROR. ] */
+                LogError("Failure subscribing to topic");
+                mqtt_info->mqtt_state = MQTT_STATE_ERROR;
+                mqtt_info->transport_state = TRANSPORT_CLIENT_STATE_ERROR;
+            }
+            else
+            {
+                mqtt_info->status_cb(PROV_DEVICE_TRANSPORT_STATUS_CONNECTED, mqtt_info->retry_after_value, mqtt_info->status_ctx);
+                mqtt_info->mqtt_state = MQTT_STATE_SUBSCRIBING;
+            }
+        }
+        else if (mqtt_info->mqtt_state != MQTT_STATE_IDLE)
+        {
+            mqtt_client_dowork(mqtt_info->mqtt_client);
+            if (mqtt_info->mqtt_state == MQTT_STATE_SUBSCRIBED || mqtt_info->mqtt_state == MQTT_STATE_ERROR)
+            {
+                switch (mqtt_info->transport_state)
+                {
+                    case TRANSPORT_CLIENT_STATE_REG_SEND:
+                        /* Tests_PROV_TRANSPORT_MQTT_COMMON_07_053: [ When then transport_state is set to TRANSPORT_CLIENT_STATE_REG_SEND, prov_transport_common_mqtt_dowork shall send a REGISTER_ME message ] */
+                        if (send_register_message(mqtt_info) != 0)
+                        {
+                            /* Tests_PROV_TRANSPORT_MQTT_COMMON_07_049: [ If any error is encountered prov_transport_common_mqtt_dowork shall set the mqtt_state to MQTT_STATE_ERROR and the transport_state to TRANSPORT_CLIENT_STATE_ERROR. ] */
+                            mqtt_info->transport_state = TRANSPORT_CLIENT_STATE_ERROR;
+                            mqtt_info->mqtt_state = MQTT_STATE_ERROR;
+                        }
+                        else
+                        {
+                            /* Codes_PROV_TRANSPORT_MQTT_COMMON_07_054: [ Upon successful sending of a TRANSPORT_CLIENT_STATE_REG_SEND message, prov_transport_common_mqtt_dowork shall set the transport_state to TRANSPORT_CLIENT_STATE_REG_SENT ] */
+                            mqtt_info->transport_state = TRANSPORT_CLIENT_STATE_REG_SENT;
+                        }
+                        break;
+                    case TRANSPORT_CLIENT_STATE_STATUS_SEND:
+                        /* Codes_PROV_TRANSPORT_MQTT_COMMON_07_055: [ When then transport_state is set to TRANSPORT_CLIENT_STATE_STATUS_SEND, prov_transport_common_mqtt_dowork shall send a AMQP_OPERATION_STATUS message ] */
+                        if (send_operation_status_message(mqtt_info) != 0)
+                        {
+                            /* Tests_PROV_TRANSPORT_MQTT_COMMON_07_049: [ If any error is encountered prov_transport_common_mqtt_dowork shall set the mqtt_state to MQTT_STATE_ERROR and the transport_state to TRANSPORT_CLIENT_STATE_ERROR. ] */
+                            mqtt_info->transport_state = TRANSPORT_CLIENT_STATE_ERROR;
+                            mqtt_info->mqtt_state = MQTT_STATE_ERROR;
+                        }
+                        else
+                        {
+                            /* Codes_PROV_TRANSPORT_MQTT_COMMON_07_056: [ Upon successful sending of a AMQP_OPERATION_STATUS message, prov_transport_common_mqtt_dowork shall set the transport_state to TRANSPORT_CLIENT_STATE_STATUS_SENT ] */
+                            mqtt_info->transport_state = TRANSPORT_CLIENT_STATE_STATUS_SENT;
+                        }
+                        break;
+
+                    case TRANSPORT_CLIENT_STATE_REG_RECV:
+                    case TRANSPORT_CLIENT_STATE_STATUS_RECV:
+                    {
+                        PROV_JSON_INFO* parse_info = mqtt_info->json_parse_cb(mqtt_info->payload_data, mqtt_info->json_ctx);
+                        if (parse_info == NULL)
+                        {
+                            /* Tests_PROV_TRANSPORT_MQTT_COMMON_07_049: [ If any error is encountered prov_transport_common_mqtt_dowork shall set the mqtt_state to MQTT_STATE_ERROR and the transport_state to TRANSPORT_CLIENT_STATE_ERROR. ] */
+                            LogError("Unable to process registration reply.");
+                            mqtt_info->transport_state = TRANSPORT_CLIENT_STATE_ERROR;
+                            mqtt_info->mqtt_state = MQTT_STATE_ERROR;
+                        }
+                        else
+                        {
+                            switch (parse_info->prov_status)
+                            {
+                                case PROV_DEVICE_TRANSPORT_STATUS_UNASSIGNED:
+                                case PROV_DEVICE_TRANSPORT_STATUS_ASSIGNING:
+                                    if (parse_info->operation_id == NULL)
+                                    {
+                                        /* Tests_PROV_TRANSPORT_MQTT_COMMON_07_049: [ If any error is encountered prov_transport_common_mqtt_dowork shall set the mqtt_state to MQTT_STATE_ERROR and the transport_state to TRANSPORT_CLIENT_STATE_ERROR. ] */
+                                        LogError("Failure operation Id invalid");
+                                        mqtt_info->transport_state = TRANSPORT_CLIENT_STATE_ERROR;
+                                        mqtt_info->mqtt_state = MQTT_STATE_ERROR;
+                                    }
+                                    else if (mqtt_info->operation_id == NULL && mallocAndStrcpy_s(&mqtt_info->operation_id, parse_info->operation_id) != 0)
+                                    {
+                                        /* Tests_PROV_TRANSPORT_MQTT_COMMON_07_049: [ If any error is encountered prov_transport_common_mqtt_dowork shall set the mqtt_state to MQTT_STATE_ERROR and the transport_state to TRANSPORT_CLIENT_STATE_ERROR. ] */
+                                        LogError("Failure copying operation Id");
+                                        mqtt_info->transport_state = TRANSPORT_CLIENT_STATE_ERROR;
+                                        mqtt_info->mqtt_state = MQTT_STATE_ERROR;
+                                    }
+                                    else
+                                    {
+                                        if (mqtt_info->status_cb != NULL)
+                                        {
+                                            mqtt_info->status_cb(parse_info->prov_status, mqtt_info->retry_after_value, mqtt_info->status_ctx);
+                                        }
+                                        mqtt_info->transport_state = TRANSPORT_CLIENT_STATE_IDLE;
+                                    }
+                                    break;
+                                case PROV_DEVICE_TRANSPORT_STATUS_ASSIGNED:
+                                    mqtt_info->register_data_cb(PROV_DEVICE_TRANSPORT_RESULT_OK, parse_info->authorization_key, parse_info->iothub_uri, parse_info->device_id, mqtt_info->user_ctx);
+                                    mqtt_info->transport_state = TRANSPORT_CLIENT_STATE_IDLE;
+                                    break;
+                                case PROV_DEVICE_TRANSPORT_STATUS_TRANSIENT:
+                                    break;
+                                case PROV_DEVICE_TRANSPORT_STATUS_ERROR:
+                                default:
+                                    /* Tests_PROV_TRANSPORT_MQTT_COMMON_07_049: [ If any error is encountered prov_transport_common_mqtt_dowork shall set the mqtt_state to MQTT_STATE_ERROR and the transport_state to TRANSPORT_CLIENT_STATE_ERROR. ] */
+                                    LogError("Unable to process message reply.");
+                                    mqtt_info->transport_state = TRANSPORT_CLIENT_STATE_ERROR;
+                                    mqtt_info->mqtt_state = MQTT_STATE_ERROR;
+                                    break;
+
+                            }
+                            free_json_parse_info(parse_info);
+                        }
+                        break;
+                    }
+                    case TRANSPORT_CLIENT_STATE_TRANSIENT:
+                        if (mqtt_info->status_cb != NULL)
+                        {
+                            mqtt_info->status_cb(PROV_DEVICE_TRANSPORT_STATUS_TRANSIENT, mqtt_info->retry_after_value, mqtt_info->status_ctx);
+                        }
+                        mqtt_info->transport_state = TRANSPORT_CLIENT_STATE_IDLE;
+                        break;
+
+                    case TRANSPORT_CLIENT_STATE_ERROR:
+                        /* Codes_PROV_TRANSPORT_MQTT_COMMON_07_057: [ If transport_state is set to TRANSPORT_CLIENT_STATE_ERROR, prov_transport_common_mqtt_dowork shall call the register_data_cb function with PROV_DEVICE_TRANSPORT_RESULT_ERROR setting the transport_state to TRANSPORT_CLIENT_STATE_IDLE ] */
+                        mqtt_info->register_data_cb(PROV_DEVICE_TRANSPORT_RESULT_ERROR, NULL, NULL, NULL, mqtt_info->user_ctx);
+                        mqtt_info->transport_state = TRANSPORT_CLIENT_STATE_IDLE;
+                        mqtt_info->mqtt_state = MQTT_STATE_IDLE;
+                        break;
+                    case TRANSPORT_CLIENT_STATE_REG_SENT:
+                    case TRANSPORT_CLIENT_STATE_STATUS_SENT:
+                        break;
+
+                    case TRANSPORT_CLIENT_STATE_IDLE:
+                    default:
+                        break;
+                }
+            }
+        }
+    }
+}
+
+int prov_transport_common_mqtt_set_trace(PROV_DEVICE_TRANSPORT_HANDLE handle, bool trace_on)
+{
+    int result;
+    if (handle == NULL)
+    {
+        /* Tests_PROV_TRANSPORT_MQTT_COMMON_07_023: [ If handle is NULL, prov_transport_common_mqtt_set_trace shall return a non-zero value. ] */
+        LogError("Invalid parameter specified handle: %p", handle);
+        result = MU_FAILURE;
+    }
+    else
+    {
+        PROV_TRANSPORT_MQTT_INFO* mqtt_info = (PROV_TRANSPORT_MQTT_INFO*)handle;
+        /* Tests_PROV_TRANSPORT_MQTT_COMMON_07_024: [ prov_transport_common_mqtt_set_trace shall set the log_trace variable to trace_on. ]*/
+        mqtt_info->log_trace = trace_on;
+        if (mqtt_info->mqtt_client != NULL)
+        {
+            /* Tests_PROV_TRANSPORT_MQTT_COMMON_07_059: [ If the umqtt connection is not NULL, prov_transport_common_mqtt_set_trace shall set the trace option on that connection. ] */
+            mqtt_client_set_trace(mqtt_info->mqtt_client, mqtt_info->log_trace, false);
+        }
+        result = 0;
+    }
+    return result;
+}
+
+int prov_transport_common_mqtt_x509_cert(PROV_DEVICE_TRANSPORT_HANDLE handle, const char* certificate, const char* private_key)
+{
+    int result;
+    if (handle == NULL || certificate == NULL)
+    {
+        /* Tests_PROV_TRANSPORT_MQTT_COMMON_07_026: [ If handle or certificate is NULL, prov_transport_common_mqtt_x509_cert shall return a non-zero value. ] */
+        LogError("Invalid parameter specified handle: %p, certificate: %p", handle, certificate);
+        result = MU_FAILURE;
+    }
+    else
+    {
+        PROV_TRANSPORT_MQTT_INFO* mqtt_info = (PROV_TRANSPORT_MQTT_INFO*)handle;
+
+        if (mqtt_info->x509_cert != NULL)
+        {
+            free(mqtt_info->x509_cert);
+            mqtt_info->x509_cert = NULL;
+        }
+        if (mqtt_info->private_key != NULL)
+        {
+            free(mqtt_info->private_key);
+            mqtt_info->private_key = NULL;
+        }
+
+        /* Tests_PROV_TRANSPORT_MQTT_COMMON_07_027: [ prov_transport_common_mqtt_x509_cert shall copy the certificate and private_key values. ] */
+        if (mallocAndStrcpy_s(&mqtt_info->x509_cert, certificate) != 0)
+        {
+            /* Tests_PROV_TRANSPORT_MQTT_COMMON_07_028: [ On any failure prov_transport_common_mqtt_x509_cert, shall return a non-zero value. ] */
+            result = MU_FAILURE;
+            LogError("failure allocating certificate");
+        }
+        else if (mallocAndStrcpy_s(&mqtt_info->private_key, private_key) != 0)
+        {
+            /* Tests_PROV_TRANSPORT_MQTT_COMMON_07_028: [ On any failure prov_transport_common_mqtt_x509_cert, shall return a non-zero value. ] */
+            LogError("failure allocating certificate");
+            free(mqtt_info->x509_cert);
+            mqtt_info->x509_cert = NULL;
+            result = MU_FAILURE;
+        }
+        else
+        {
+            /* Tests_PROV_TRANSPORT_MQTT_COMMON_07_029: [ On success prov_transport_common_mqtt_x509_cert shall return a zero value. ] */
+            result = 0;
+        }
+    }
+    return result;
+}
+
+int prov_transport_common_mqtt_set_trusted_cert(PROV_DEVICE_TRANSPORT_HANDLE handle, const char* certificate)
+{
+    int result;
+    if (handle == NULL || certificate == NULL)
+    {
+        /* Tests_PROV_TRANSPORT_MQTT_COMMON_07_030: [ If handle or certificate is NULL, prov_transport_common_mqtt_set_trusted_cert shall return a non-zero value. ] */
+        LogError("Invalid parameter specified handle: %p, certificate: %p", handle, certificate);
+        result = MU_FAILURE;
+    }
+    else
+    {
+        PROV_TRANSPORT_MQTT_INFO* mqtt_info = (PROV_TRANSPORT_MQTT_INFO*)handle;
+
+        if (mqtt_info->certificate != NULL)
+        {
+            free(mqtt_info->certificate);
+            mqtt_info->certificate = NULL;
+        }
+
+        /* Tests_PROV_TRANSPORT_MQTT_COMMON_07_031: [ prov_transport_common_mqtt_set_trusted_cert shall copy the certificate value. ] */
+        if (mallocAndStrcpy_s(&mqtt_info->certificate, certificate) != 0)
+        {
+            /* Tests_PROV_TRANSPORT_MQTT_COMMON_07_032: [ On any failure prov_transport_common_mqtt_set_trusted_cert, shall return a non-zero value. ] */
+            result = MU_FAILURE;
+            LogError("failure allocating certificate");
+        }
+        else
+        {
+            /* Tests_PROV_TRANSPORT_MQTT_COMMON_07_033: [ On success prov_transport_common_mqtt_set_trusted_cert shall return a zero value. ] */
+            result = 0;
+        }
+    }
+    return result;
+}
+
+int prov_transport_common_mqtt_set_proxy(PROV_DEVICE_TRANSPORT_HANDLE handle, const HTTP_PROXY_OPTIONS* proxy_options)
+{
+    int result;
+    if (handle == NULL || proxy_options == NULL)
+    {
+        /* Tests_PROV_TRANSPORT_MQTT_COMMON_07_034: [ If handle or proxy_options is NULL, prov_transport_common_mqtt_set_proxy shall return a non-zero value. ]*/
+        LogError("Invalid parameter specified handle: %p, proxy_options: %p", handle, proxy_options);
+        result = MU_FAILURE;
+    }
+    else
+    {
+        PROV_TRANSPORT_MQTT_INFO* mqtt_info = (PROV_TRANSPORT_MQTT_INFO*)handle;
+        if (proxy_options->host_address == NULL)
+        {
+            /* Tests_PROV_TRANSPORT_MQTT_COMMON_07_035: [ If HTTP_PROXY_OPTIONS host_address is NULL, prov_transport_common_mqtt_set_proxy shall return a non-zero value. ] */
+            LogError("NULL host_address in proxy options");
+            result = MU_FAILURE;
+        }
+        /* Tests_PROV_TRANSPORT_MQTT_COMMON_07_036: [ If HTTP_PROXY_OPTIONS password is not NULL and username is NULL, prov_transport_common_mqtt_set_proxy shall return a non-zero value. ] */
+        else if (((proxy_options->username == NULL) || (proxy_options->password == NULL)) &&
+            (proxy_options->username != proxy_options->password))
+        {
+            /* Tests_PROV_TRANSPORT_MQTT_COMMON_07_039: [ On any failure prov_transport_common_mqtt_set_proxy, shall return a non-zero value. ] */
+            LogError("Only one of username and password for proxy settings was NULL");
+            result = MU_FAILURE;
+        }
+        else
+        {
+            /* Tests_PROV_TRANSPORT_MQTT_COMMON_07_037: [ If any of the host_addess, username, or password variables are non-NULL, prov_transport_common_mqtt_set_proxy shall free the memory. ] */
+            if (mqtt_info->proxy_option.host_address != NULL)
+            {
+                free((char*)mqtt_info->proxy_option.host_address);
+                mqtt_info->proxy_option.host_address = NULL;
+            }
+            if (mqtt_info->proxy_option.username != NULL)
+            {
+                free((char*)mqtt_info->proxy_option.username);
+                mqtt_info->proxy_option.username = NULL;
+            }
+            if (mqtt_info->proxy_option.password != NULL)
+            {
+                free((char*)mqtt_info->proxy_option.password);
+                mqtt_info->proxy_option.password = NULL;
+            }
+
+            /* Tests_PROV_TRANSPORT_MQTT_COMMON_07_038: [ prov_transport_common_mqtt_set_proxy shall copy the host_addess, username, or password variables ] */
+            mqtt_info->proxy_option.port = proxy_options->port;
+            if (mallocAndStrcpy_s((char**)&mqtt_info->proxy_option.host_address, proxy_options->host_address) != 0)
+            {
+                /* Tests_PROV_TRANSPORT_MQTT_COMMON_07_039: [ On any failure prov_transport_common_mqtt_set_proxy, shall return a non-zero value. ] */
+                LogError("Failure setting proxy_host name");
+                result = MU_FAILURE;
+            }
+            else if (proxy_options->username != NULL && mallocAndStrcpy_s((char**)&mqtt_info->proxy_option.username, proxy_options->username) != 0)
+            {
+                /* Tests_PROV_TRANSPORT_MQTT_COMMON_07_039: [ On any failure prov_transport_common_mqtt_set_proxy, shall return a non-zero value. ] */
+                LogError("Failure setting proxy username");
+                free((char*)mqtt_info->proxy_option.host_address);
+                mqtt_info->proxy_option.host_address = NULL;
+                result = MU_FAILURE;
+            }
+            else if (proxy_options->password != NULL && mallocAndStrcpy_s((char**)&mqtt_info->proxy_option.password, proxy_options->password) != 0)
+            {
+                /* Tests_PROV_TRANSPORT_MQTT_COMMON_07_039: [ On any failure prov_transport_common_mqtt_set_proxy, shall return a non-zero value. ] */
+                LogError("Failure setting proxy password");
+                free((char*)mqtt_info->proxy_option.host_address);
+                mqtt_info->proxy_option.host_address = NULL;
+                free((char*)mqtt_info->proxy_option.username);
+                mqtt_info->proxy_option.username = NULL;
+                result = MU_FAILURE;
+            }
+            else
+            {
+                /* Tests_PROV_TRANSPORT_MQTT_COMMON_07_040: [ On success prov_transport_common_mqtt_set_proxy shall return a zero value. ] */
+                result = 0;
+            }
+        }
+    }
+    return result;
+}
+
+int prov_transport_common_mqtt_set_option(PROV_DEVICE_TRANSPORT_HANDLE handle, const char* option, const void* value)
+{
+    int result;
+    if (handle == NULL || option == NULL)
+    {
+        LogError("Invalid parameter specified handle: %p, option: %p", handle, option);
+        result = MU_FAILURE;
+    }
+    else
+    {
+        PROV_TRANSPORT_MQTT_INFO* mqtt_info = (PROV_TRANSPORT_MQTT_INFO*)handle;
+        if (mqtt_info->transport_io == NULL && create_transport_io_object(mqtt_info) != 0)
+        {
+            LogError("Failure creating transport io object");
+            result = MU_FAILURE;
+        }
+        else
+        {
+            result = xio_setoption(mqtt_info->transport_io, option, value);
+        }
+    }
+    return result;
+}
Index: azure_iot_hub_f767zi/trunk/azure_iot_sdk/provisioning_client/src/prov_transport_mqtt_ws_client.c
===================================================================
--- azure_iot_hub_f767zi/trunk/azure_iot_sdk/provisioning_client/src/prov_transport_mqtt_ws_client.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/azure_iot_sdk/provisioning_client/src/prov_transport_mqtt_ws_client.c	(revision 457)
@@ -0,0 +1,167 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+#include <stdlib.h>
+#include "azure_c_shared_utility/gballoc.h"
+#include "azure_c_shared_utility/wsio.h"
+#include "azure_prov_client/prov_transport_mqtt_client.h"
+#include "azure_prov_client/internal/prov_transport_mqtt_common.h"
+#include "azure_c_shared_utility/xio.h"
+#include "azure_c_shared_utility/tlsio.h"
+#include "azure_c_shared_utility/http_proxy_io.h"
+#include "azure_c_shared_utility/platform.h"
+#include "azure_c_shared_utility/shared_util_options.h"
+
+#define MQTT_WS_PORT_NUM               443
+#define MQTT_WS_PROTOCOL_NAME "MQTT"
+#define MQTT_WS_RELATIVE_PATH "/$iothub/websocket"
+
+static XIO_HANDLE mqtt_transport_ws_io(const char* fqdn, const HTTP_PROXY_OPTIONS* proxy_info)
+{
+    XIO_HANDLE result;
+    HTTP_PROXY_IO_CONFIG proxy_config;
+    TLSIO_CONFIG tls_io_config;
+    WSIO_CONFIG ws_io_config;
+    const IO_INTERFACE_DESCRIPTION* ws_io_interface;
+    const IO_INTERFACE_DESCRIPTION* tlsio_interface;
+
+    if ((ws_io_interface = wsio_get_interface_description()) == NULL)
+    {
+        /* Codes_PROV_TRANSPORT_MQTT_WS_CLIENT_07_013: [ If any failure is encountered amqp_transport_ws_io shall return NULL ] */
+        LogError("wsio_get_interface_description return NULL IO Interface");
+        result = NULL;
+    }
+    else if ((tlsio_interface = platform_get_default_tlsio()) == NULL)
+    {
+        /* Codes_PROV_TRANSPORT_MQTT_WS_CLIENT_07_013: [ If any failure is encountered amqp_transport_ws_io shall return NULL ] */
+        LogError("platform_get_default_tlsio return NULL IO Interface");
+        result = NULL;
+    }
+    else
+    {
+        memset(&tls_io_config, 0, sizeof(TLSIO_CONFIG));
+
+        ws_io_config.hostname = fqdn;
+        ws_io_config.port = MQTT_WS_PORT_NUM;
+        ws_io_config.protocol = MQTT_WS_PROTOCOL_NAME;
+        ws_io_config.resource_name = MQTT_WS_RELATIVE_PATH;
+        ws_io_config.underlying_io_interface = tlsio_interface;
+        ws_io_config.underlying_io_parameters = &tls_io_config;
+
+        tls_io_config.hostname = fqdn;
+        tls_io_config.port = MQTT_WS_PORT_NUM;
+        if (proxy_info != NULL)
+        {
+            /* Codes_PROV_TRANSPORT_MQTT_CLIENT_07_012: [ If proxy_info is not NULL, amqp_transport_io shall construct a HTTP_PROXY_IO_CONFIG object and assign it to TLSIO_CONFIG underlying_io_parameters ] */
+            proxy_config.hostname = tls_io_config.hostname;
+            proxy_config.port = MQTT_WS_PORT_NUM;
+            proxy_config.proxy_hostname = proxy_info->host_address;
+            proxy_config.proxy_port = proxy_info->port;
+            proxy_config.username = proxy_info->username;
+            proxy_config.password = proxy_info->password;
+
+            tls_io_config.underlying_io_interface = http_proxy_io_get_interface_description();
+            tls_io_config.underlying_io_parameters = &proxy_config;
+        }
+
+        result = xio_create(ws_io_interface, &ws_io_config);
+        if (result == NULL)
+        {
+            LogError("failed calling xio_create on underlying io");
+        }
+    }
+    /* Codes_PROV_TRANSPORT_MQTT_WS_CLIENT_07_014: [ On success mqtt_transport_ws_io shall return an allocated XIO_HANDLE. ] */
+    return result;
+}
+
+PROV_DEVICE_TRANSPORT_HANDLE prov_transport_mqtt_ws_create(const char* uri, TRANSPORT_HSM_TYPE type, const char* scope_id, const char* api_version, PROV_TRANSPORT_ERROR_CALLBACK error_cb, void* error_ctx)
+{
+    /* Codes_PROV_TRANSPORT_MQTT_WS_CLIENT_07_001: [ prov_transport_mqtt_ws_create shall call the prov_trans_common_mqtt_create function with mqtt_transport_ws_io transport IO estabishment. ] */
+    return prov_transport_common_mqtt_create(uri, type, scope_id, api_version, mqtt_transport_ws_io, error_cb, error_ctx);
+}
+
+void prov_transport_mqtt_ws_destroy(PROV_DEVICE_TRANSPORT_HANDLE handle)
+{
+    /* Codes_PROV_TRANSPORT_MQTT_WS_CLIENT_07_002: [ prov_transport_mqtt_ws_destroy shall invoke the prov_transport_common_mqtt_destroy method ] */
+    prov_transport_common_mqtt_destroy(handle);
+}
+
+int prov_transport_mqtt_ws_open(PROV_DEVICE_TRANSPORT_HANDLE handle, const char* registration_id, BUFFER_HANDLE ek, BUFFER_HANDLE srk, PROV_DEVICE_TRANSPORT_REGISTER_CALLBACK data_callback, void* user_ctx, PROV_DEVICE_TRANSPORT_STATUS_CALLBACK status_cb, void* status_ctx, PROV_TRANSPORT_CHALLENGE_CALLBACK reg_challenge_cb, void* challenge_ctx)
+{
+    /* Codes_PROV_TRANSPORT_MQTT_WS_CLIENT_07_003: [ prov_transport_mqtt_ws_open shall invoke the prov_transport_common_mqtt_open method ] */
+    return prov_transport_common_mqtt_open(handle, registration_id, ek, srk, data_callback, user_ctx, status_cb, status_ctx, reg_challenge_cb, challenge_ctx);
+}
+
+int prov_transport_mqtt_ws_close(PROV_DEVICE_TRANSPORT_HANDLE handle)
+{
+    /* Codes_PROV_TRANSPORT_MQTT_WS_CLIENT_07_004: [ prov_transport_mqtt_ws_close shall invoke the prov_transport_common_mqtt_close method ] */
+    return prov_transport_common_mqtt_close(handle);
+}
+
+int prov_transport_mqtt_ws_register_device(PROV_DEVICE_TRANSPORT_HANDLE handle, PROV_TRANSPORT_JSON_PARSE json_parse_cb, PROV_TRANSPORT_CREATE_JSON_PAYLOAD json_create_cb, void* json_ctx)
+{
+    /* Codes_PROV_TRANSPORT_MQTT_WS_CLIENT_07_005: [ prov_transport_mqtt_ws_register_device shall invoke the prov_transport_common_mqtt_register_device method ] */
+    return prov_transport_common_mqtt_register_device(handle, json_parse_cb, json_create_cb, json_ctx);
+}
+
+int prov_transport_mqtt_ws_get_operation_status(PROV_DEVICE_TRANSPORT_HANDLE handle)
+{
+    /* Codes_PROV_TRANSPORT_MQTT_WS_CLIENT_07_006: [ prov_transport_mqtt_ws_get_operation_status shall invoke the prov_transport_common_mqtt_get_operation_status method ] */
+    return prov_transport_common_mqtt_get_operation_status(handle);
+}
+
+void prov_transport_mqtt_ws_dowork(PROV_DEVICE_TRANSPORT_HANDLE handle)
+{
+    /* Codes_PROV_TRANSPORT_MQTT_WS_CLIENT_07_007: [ prov_transport_mqtt_ws_dowork shall invoke the prov_transport_common_mqtt_dowork method ] */
+    prov_transport_common_mqtt_dowork(handle);
+}
+
+int prov_transport_mqtt_ws_set_trace(PROV_DEVICE_TRANSPORT_HANDLE handle, bool trace_on)
+{
+    /* Codes_PROV_TRANSPORT_MQTT_WS_CLIENT_07_008: [ prov_transport_mqtt_ws_set_trace shall invoke the prov_transport_common_mqtt_set_trace method ] */
+    return prov_transport_common_mqtt_set_trace(handle, trace_on);
+}
+
+static int prov_transport_mqtt_ws_x509_cert(PROV_DEVICE_TRANSPORT_HANDLE handle, const char* certificate, const char* private_key)
+{
+    /* Codes_PROV_TRANSPORT_MQTT_WS_CLIENT_07_009: [ prov_transport_mqtt_ws_x509_cert shall invoke the prov_trans_common_mqtt_x509_cert method ] */
+    return prov_transport_common_mqtt_x509_cert(handle, certificate, private_key);
+}
+
+static int prov_transport_mqtt_ws_set_trusted_cert(PROV_DEVICE_TRANSPORT_HANDLE handle, const char* certificate)
+{
+    /* Codes_PROV_TRANSPORT_MQTT_WS_CLIENT_07_010: [ prov_transport_mqtt_ws_set_trusted_cert shall invoke the prov_transport_common_mqtt_set_trusted_cert method ] */
+    return prov_transport_common_mqtt_set_trusted_cert(handle, certificate);
+}
+
+static int prov_transport_mqtt_ws_set_proxy(PROV_DEVICE_TRANSPORT_HANDLE handle, const HTTP_PROXY_OPTIONS* proxy_options)
+{
+    /* Codes_PROV_TRANSPORT_MQTT_WS_CLIENT_07_011: [ prov_transport_mqtt_ws_set_proxy shall invoke the prov_transport_common_mqtt_set_proxy method ] */
+    return prov_transport_common_mqtt_set_proxy(handle, proxy_options);
+}
+
+static int prov_transport_mqtt_ws_set_option(PROV_DEVICE_TRANSPORT_HANDLE handle, const char* option, const void* value)
+{
+    return prov_transport_common_mqtt_set_option(handle, option, value);
+}
+
+static PROV_DEVICE_TRANSPORT_PROVIDER prov_mqtt_func =
+{
+    prov_transport_mqtt_ws_create,
+    prov_transport_mqtt_ws_destroy,
+    prov_transport_mqtt_ws_open,
+    prov_transport_mqtt_ws_close,
+    prov_transport_mqtt_ws_register_device,
+    prov_transport_mqtt_ws_get_operation_status,
+    prov_transport_mqtt_ws_dowork,
+    prov_transport_mqtt_ws_set_trace,
+    prov_transport_mqtt_ws_x509_cert,
+    prov_transport_mqtt_ws_set_trusted_cert,
+    prov_transport_mqtt_ws_set_proxy,
+    prov_transport_mqtt_ws_set_option
+};
+
+const PROV_DEVICE_TRANSPORT_PROVIDER* Prov_Device_MQTT_WS_Protocol(void)
+{
+    return &prov_mqtt_func;
+}
Index: azure_iot_hub_f767zi/trunk/azure_iot_sdk/serializer/inc/agenttypesystem.h
===================================================================
--- azure_iot_hub_f767zi/trunk/azure_iot_sdk/serializer/inc/agenttypesystem.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/azure_iot_sdk/serializer/inc/agenttypesystem.h	(revision 457)
@@ -0,0 +1,718 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+#ifndef AGENT_DATA_TYPES_H
+#define AGENT_DATA_TYPES_H
+
+#ifdef __cplusplus
+#include <cstdint>
+#include <ctime>
+#include <cstddef>
+#else
+#if ((defined _WIN32_WCE) && _WIN32_WCE==0x0600)
+#include "stdint_ce6.h"
+#else
+#include <stdint.h>
+#endif
+#include <stddef.h>
+#endif
+
+#include "azure_c_shared_utility/agenttime.h"
+#include "azure_macro_utils/macro_utils.h"
+#include "azure_c_shared_utility/strings.h"
+
+/*Codes_SRS_AGENT_TYPE_SYSTEM_99_001:[ AGENT_TYPE_SYSTEM shall have the following interface]*/
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/*the following forward declarations the closest implementation to "interface" in OOP*/
+struct AGENT_DATA_TYPE_TAG;
+typedef struct AGENT_DATA_TYPE_TAG AGENT_DATA_TYPE;
+
+/*this file contains the definitions of the data types of EDM*/
+/*the types are taken from */
+/*http://docs.oasis-open.org/odata/odata/v4.0/cos01/part3-csdl/odata-v4.0-cos01-part3-csdl.html*/
+/*chapter 4.4 - "Primitive Data Types" */
+
+/*the C implementation of these types follows:*/
+/*even the simpler types are encapsulated in structs to purposely avoid compiler promotions/casts etc*/
+
+/*Binary data.*/
+typedef struct EDM_BINARY_TAG
+{
+    size_t size;
+    unsigned char* data;
+}EDM_BINARY;
+
+#define EDM_BOOLEANS_VALUES \
+    EDM_TRUE, \
+    EDM_FALSE
+
+MU_DEFINE_ENUM_WITHOUT_INVALID(EDM_BOOLEANS, EDM_BOOLEANS_VALUES);
+
+/*ispositiveinfinity*/
+
+#ifdef _MSC_VER
+#define ISPOSITIVEINFINITY(x) ((_finite((x))==0) && ((_fpclass((x)) & _FPCLASS_PINF) == _FPCLASS_PINF))
+#else
+#if defined __STDC_VERSION__
+#if ((__STDC_VERSION__  == 199901L) || (__STDC_VERSION__ == 201112L) || (__STDC_VERSION__ == 201710L))
+/*C99, C11 or C18 compiler*/
+#define ISPOSITIVEINFINITY(x) (isinf((x)) && (signbit((x))==0))
+#else
+#error update this file to contain the latest C standard.
+#endif
+#else
+#ifdef __cplusplus
+#define ISPOSITIVEINFINITY(x) (std::isinf((x)) && (signbit((x))==0))
+#else
+#error unknown (or C89) compiler, must provide a definition for ISPOSITIVEINFINITY
+#endif
+#endif
+#endif
+
+#ifdef _MSC_VER
+/*not exactly signbit*/
+#define ISNEGATIVEINFINITY(x) ((_finite((x))==0) && ((_fpclass((x)) & _FPCLASS_NINF) == _FPCLASS_NINF))
+#else
+#if defined __STDC_VERSION__
+#if ((__STDC_VERSION__  == 199901L) || (__STDC_VERSION__ == 201112L) || (__STDC_VERSION__ == 201710L))
+/*C99, C11 or C18 compiler*/
+#define ISNEGATIVEINFINITY(x) (isinf((x)) && (signbit((x))!=0))
+#else
+#error update this file to contain the latest C standard.
+#endif
+#else
+#ifdef __cplusplus
+#define ISNEGATIVEINFINITY(x) (std::isinf((x)) && (signbit((x)) != 0))
+#else
+#error unknown (or C89) compiler, must provide a definition for ISNEGATIVEINFINITY
+#endif
+#endif
+#endif
+
+/*Binary-valued logic.*/
+typedef struct EDM_BOOLEAN_TAG
+{
+    EDM_BOOLEANS value;
+}EDM_BOOLEAN;
+
+/*Unsigned 8-bit integer*/
+typedef struct EDM_BYTE_TAG
+{
+    uint8_t value;
+} EDM_BYTE;
+
+/*Date without a time-zone offset*/
+/*The edm:Date expression evaluates to a primitive date value. A date expression MUST be assigned a
+value of type xs:date, see [XML-Schema-2], section 3.3.9. The value MUST also conform to rule
+dateValue in [OData-ABNF], i.e. it MUST NOT contain a time-zone offset.*/
+/*section 3.3.9: date uses the date/timeSevenPropertyModel, with hour, minute, and second required to be absent.*/
+/*dateValue in OData-ABNF is : dateValue = year "-" month "-" day */
+/*year  = [ "-" ] ( "0" 3DIGIT / oneToNine 3*DIGIT )
+month = "0" oneToNine
+/ "1" ( "0" / "1" / "2" )
+day   = "0" oneToNine
+/ ( "1" / "2" ) DIGIT
+/ "3" ( "0" / "1" )*/
+typedef struct EDM_DATE_TAG
+{
+    int16_t year; /*can represent all values for a year*/ /*they can be between -9999 and 9999*/
+    uint8_t month;
+    uint8_t day;
+} EDM_DATE;
+
+
+/*The edm:DateTimeOffset expression evaluates to a primitive date/time value with a time-zone offset.
+A date/time expression MUST be assigned a value of type xs:dateTimeStamp, see [XML-Schema-2],
+section 3.4.28. The value MUST also conform to rule dateTimeOffsetValue in [OData-ABNF], i.e. it
+MUST NOT contain an end-of-day fragment (24:00:00).*/
+/*section 3.4.28 says : dateTimeStampLexicalRep ::= yearFrag '-' monthFrag '-' dayFrag 'T' ((hourFrag ':' minuteFrag ':' secondFrag) | endOfDayFrag) timezoneFrag?*/
+/*[OData-ABNF] says: dateTimeOffsetValue = year "-" month "-" day "T" hour ":" minute [ ":" second [ "." fractionalSeconds ] ] ( "Z" / sign hour ":" minute )*/
+/*fractionalSeconds = 1*12DIGIT, FYI*/
+typedef struct EDM_DATE_TIME_OFFSET_TAG
+{
+    struct tm dateTime;
+    uint8_t hasFractionalSecond;
+    uint64_t fractionalSecond; /*because UINT32 only has 10 digits*/
+    uint8_t hasTimeZone;
+    int8_t timeZoneHour;
+    uint8_t timeZoneMinute;
+}EDM_DATE_TIME_OFFSET;
+
+/*Edm.Guid*/
+/*16-byte (128-bit) unique identifier*/
+/*The edm:Guid expression evaluates to a primitive 32-character string value. A guid expression MUST be
+assigned a value conforming to the rule guidValue in [OData-ABNF].*/
+/*guidValue is 8HEXDIG "-" 4HEXDIG "-" 4HEXDIG "-" 4HEXDIG "-" 12HEXDIG*/
+typedef struct EDM_GUID_TAG
+{
+    uint8_t GUID[16];
+}EDM_GUID;
+
+
+/*Edm.Decimal*/
+/*The edm:Decimal expression evaluates to a primitive decimal value. A decimal expression MUST be
+assigned a value conforming to the rule decimalValue in [OData-ABNF].*/
+/*[OData-ABNF] says: decimalValue = [SIGN] 1*DIGIT ["." 1*DIGIT] */
+/* this is binary coded decimal style then*/
+typedef struct EDM_DECIMAL_TAG
+{
+    STRING_HANDLE value;
+} EDM_DECIMAL;
+
+/*Edm.Double*/
+/*IEEE 754 binary64 floating-point number (15-17 decimal digits)*/
+
+typedef struct EDM_DOUBLE_TAG
+{
+    double value;
+} EDM_DOUBLE;
+
+
+/*Edm.Duration*/
+/*Signed duration in days, hours, minutes, and (sub)seconds*/
+/*The edm:Duration expression evaluates to a primitive duration value. A duration expression MUST be
+assigned a value of type xs:dayTimeDuration, see [XML-Schema-2], section 3.4.27.*/
+/*XML-Schema section 3.4.27 says: "[...]leaving only those with day, hour, minutes, and/or seconds fields." */
+/*day is "unsignedNoDecimalPtNumeral" and that can have as many digits... ?*/
+typedef struct EDM_DURATION_TAG
+{
+    size_t nDigits;
+    char* digits;
+}
+EDM_DURATION;
+
+
+/*Edm.Int16*/
+/*Signed 16-bit integer*/
+/*[OData=ABNF] says about Int16:  numbers in the range from -32768 to 32767 */
+/*this is not C compliant, because C89 has for (read:guarantees) short SHRT_MIN -32767... (notice how it misses -32768)*/
+/*C99 has the same*/
+/*C11 has the same*/
+/*platform types has to check for -32768 compliance*/
+typedef struct EDM_INT16_TAG
+{
+    int16_t value;
+} EDM_INT16;
+
+/*Edm.Int32*/
+/*Signed 32-bit integer*/
+/*OData-ABNF has for int32Value = [ sign ] 1*10DIGIT ; numbers in the range from -2147483648 to 2147483647*/
+/*same issue as for EDM_16*/
+/*platform types has to check compliance based on LONG_MIN #define*/
+typedef struct EDM_INT32_TAG
+{
+    int32_t value;
+} EDM_INT32;
+
+/*Edm.Int64*/
+/*Signed 64-bit integer*/
+/*OData=ABNF: int64Value = [ sign ] 1*19DIGIT ; numbers in the range from -9223372036854775808 to 9223372036854775807*/
+/*C89 has no mention of anything on 64bits*/
+/*C99 mention LLONG_MIN as -9223372036854775807 and LLONG_MAX as 9223372036854775807*/
+/*C11 is the same as C99*/
+typedef struct EDM_INT64_TAG
+{
+    int64_t value; /*SINT64 might be a single type or s truct provided by platformTypes, depending on C compiler support*/
+} EDM_INT64;
+
+/*Edm.SByte*/
+/*Signed 8-bit integer*/
+/*OData=ABNF: sbyteValue = [ sign ] 1*3DIGIT  ; numbers in the range from -128 to 127*/
+/*C89, C99, C11 all have SCHAR_MIN, SCHAR_MAX between -127 and 127 (guaranteed)*/
+/*so platformTypes.h has to check that -128 is attainable*/
+typedef struct EDM_SBYTE_TAG
+{
+    int8_t value;
+} EDM_SBYTE;
+
+/*Edm.Single*/
+/*IEEE 754 binary32 floating-point number (6-9 decimal digits)*/
+/*with the same "fears" as for Edm.Double*/
+typedef struct EDM_SINGLE_TAG
+{
+    float value;
+} EDM_SINGLE;
+
+/*not clear what this is
+typedef EDM_STREAM_TAG
+{
+
+}EDM_STREAM;
+*/
+
+/*Edm.String*/
+/*Sequence of UTF-8 characters*/
+typedef struct EDM_STRING_TAG
+{
+    size_t length; /*number of unsigned char* in the string*/
+    char* chars;
+} EDM_STRING;
+
+/*Edm.TimeOfDay*/
+/*Clock time 00:00-23:59:59.999999999999*/
+/*The edm:TimeOfDay expression evaluates to a primitive time value. A time-of-day expression MUST be
+assigned a value conforming to the rule timeOfDayValue in [OData-ABNF].*/
+/*timeOfDayValue = hour ":" minute [ ":" second [ "." fractionalSeconds ] ]*/
+typedef struct EDM_TIME_OF_DAY_TAG
+{
+    uint8_t hour;
+    uint8_t minute;
+    uint8_t second;
+    uint64_t fractionalSecond;
+}EDM_TIME_OF_DAY;
+
+/*positionLiteral  = doubleValue SP doubleValue  ; longitude, then latitude*/
+typedef struct EDM_POSITION_LITERAL_TAG
+{
+    double longitude;
+    double latitude;
+}EDM_POSITION_LITERAL;
+
+
+/*sridLiteral      = "SRID" EQ 1*5DIGIT SEMI*/
+typedef struct EDM_SRID_LITERAL_TAG
+{
+    uint16_t digits;
+} EDM_SRID_LITERAL;
+
+/*lineStringData        = OPEN positionLiteral 1*( COMMA positionLiteral ) CLOSE*/
+typedef struct EDM_LINE_STRING_DATA_TAG
+{
+    size_t nPositionLiterals;
+    EDM_POSITION_LITERAL *positionLiterals;
+}EDM_LINE_STRING_DATA;
+
+/*pointData        = OPEN positionLiteral CLOSE*/
+typedef struct EDM_POINT_DATA_TAG
+{
+    EDM_POSITION_LITERAL positionLiteral;
+}EDM_POINT_DATA;
+
+/*ringLiteral        = OPEN positionLiteral *( COMMA positionLiteral ) CLOSE*/
+typedef struct EDM_RING_LITERAL_TAG
+{
+    size_t nPositionLiterals;
+    EDM_POSITION_LITERAL *positionLiterals;
+}EDM_RING_LITERAL;
+
+/*pointLiteral     ="Point" pointData*/
+typedef struct EDM_POINT_LITERAL_TAG
+{
+    EDM_POINT_DATA pointData;
+} EDM_POINT_LITERAL;
+
+/*polygonData        = OPEN ringLiteral *( COMMA ringLiteral ) CLOSE*/
+typedef struct EDM_POLYGON_DATA_TAG
+{
+    size_t nRingLiterals;
+    EDM_RING_LITERAL *ringLiterals;
+}EDM_POLYGON_DATA;
+
+/*polygonLiteral     = "Polygon" polygonData*/
+typedef struct EDM_POLYGON_LITERAL_TAG
+{
+    EDM_POLYGON_DATA polygonData;
+}EDM_POLYGON_LITERAL;
+
+/*fullPolygonLiteral = sridLiteral polygonLiteral*/
+typedef struct EDM_FULL_POLYGON_LITERAL_TAG
+{
+    EDM_SRID_LITERAL srid;
+    EDM_POLYGON_LITERAL polygonLiteral;
+}EDM_FULL_POLYGON_LITERAL;
+
+/*fullPointLiteral = sridLiteral pointLiteral*/
+typedef struct EDM_FULL_POINT_LITERAL_TAG
+{
+    EDM_SRID_LITERAL srid;
+    EDM_POINT_LITERAL pointLiteral;
+} EDM_FULL_POINT_LITERAL;
+
+/*geographyPoint   = geographyPrefix SQUOTE fullPointLiteral SQUOTE*/
+typedef struct EDM_GEOGRAPHY_POINT_TAG
+{
+    EDM_FULL_POINT_LITERAL fullPointLiteral;
+}EDM_GEOGRAPHY_POINT;
+
+/*multiPolygonLiteral     = "MultiPolygon(" [ polygonData *( COMMA polygonData ) ] CLOSE*/
+typedef struct EDM_MULTI_POLYGON_LITERAL_TAG
+{
+    size_t nPolygonDatas;
+    EDM_POLYGON_DATA * polygonDatas;
+}EDM_MULTI_POLYGON_LITERAL;
+
+/*fullMultiPolygonLiteral = sridLiteral multiPolygonLiteral*/
+typedef struct EDM_FULL_MULTI_POLYGON_LITERAL_TAG
+{
+    EDM_SRID_LITERAL srid;
+    EDM_MULTI_POLYGON_LITERAL multiPolygonLiteral;
+}EDM_FULL_MULTI_POLYGON_LITERAL;
+
+/*multiPointLiteral     = "MultiPoint(" [ pointData *( COMMA pointData ) ] CLOSE*/
+typedef struct EDM_MULTI_POINT_LITERAL_TAG
+{
+    size_t nPointDatas;
+    EDM_POINT_DATA *pointDatas;
+}EDM_MULTI_POINT_LITERAL;
+
+/*fullMultiPointLiteral = sridLiteral multiPointLiteral*/
+typedef struct EDM_FULL_MULTI_POINT_LITERAL_TAG
+{
+    EDM_SRID_LITERAL srid;
+    EDM_MULTI_POINT_LITERAL multiPointLiteral;
+}EDM_FULL_MULTI_POINT_LITERAL;
+
+/*lineStringLiteral     = "LineString" lineStringData*/
+typedef struct EDM_LINE_STRING_LITERAL_TAG
+{
+    EDM_LINE_STRING_DATA lineStringData;
+}EDM_LINE_STRING_LITERAL;
+
+/*fullLineStringLiteral = sridLiteral lineStringLiteral*/
+typedef struct EDM_FULL_LINE_STRING_LITERAL_TAG
+{
+    EDM_SRID_LITERAL srid;
+    EDM_LINE_STRING_LITERAL lineStringLiteral;
+} EDM_FULL_LINE_STRING_LITERAL;
+
+/*multiLineStringLiteral     = "MultiLineString(" [ lineStringData *( COMMA lineStringData ) ] CLOSE*/
+typedef struct EDM_MULTI_LINE_STRING_LITERAL_TAG
+{
+    size_t nLineStringDatas;
+    EDM_LINE_STRING_DATA lineStringData;
+}EDM_MULTI_LINE_STRING_LITERAL;
+
+/*fullMultiLineStringLiteral = sridLiteral multiLineStringLiteral*/
+typedef struct EDM_FULL_MULTI_LINE_STRING_LITERAL_TAG
+{
+    EDM_SRID_LITERAL srid;
+    EDM_MULTI_LINE_STRING_LITERAL multiLineStringLiteral;
+}EDM_FULL_MULTI_LINE_STRING_LITERAL;
+
+
+
+/*forward defines*/
+struct EDM_GEO_LITERAL_TAG;
+typedef struct EDM_GEO_LITERAL_TAG EDM_GEO_LITERAL;
+
+/*collectionLiteral     = "Collection(" geoLiteral *( COMMA geoLiteral ) CLOSE*/
+typedef struct EDM_COLLECTION_LITERAL_TAG
+{
+    size_t nGeoLiterals;
+    EDM_GEO_LITERAL* geoLiterals;
+} EDM_COLLECTION_LITERAL;
+
+/*geoLiteral            = collectionLiteral
+/ lineStringLiteral
+/ multiPointLiteral
+/ multiLineStringLiteral
+/ multiPolygonLiteral
+/ pointLiteral
+/ polygonLiteral
+*/
+typedef enum EDM_GEO_LITERAL_TYPE_TAG
+{
+    EDM_COLLECTION_LITERAL_TYPE,
+    EDM_LINE_STRING_LITERAL_TYPE,
+    EDM_MULTI_POINT_LITERAL_TYPE,
+    EDM_MULTI_LINE_STRING_LITERAL_TYPE,
+    EDM_MULTI_POLIGON_LITERAL_TYPE,
+    EDM_POINT_LITERAL_TYPE,
+    EDM_POLYGON_LITERAL_TYPE
+}EDM_GEO_LITERAL_TYPE;
+
+struct EDM_GEO_LITERAL_TAG
+{
+    EDM_GEO_LITERAL_TYPE literalType;
+    union
+    {
+        EDM_COLLECTION_LITERAL collectionLiteral;
+        EDM_LINE_STRING_LITERAL lineStringLiteral;
+        EDM_MULTI_POINT_LITERAL multiPointLiteral;
+        EDM_MULTI_LINE_STRING_LITERAL multiLineStringLiteral;
+        EDM_MULTI_POLYGON_LITERAL multiPolygonLiteral;
+        EDM_POINT_LITERAL pointLiteral;
+        EDM_POLYGON_LITERAL polygonLiteral;
+    } u;
+};
+
+/*fullCollectionLiteral = sridLiteral collectionLiteral*/
+typedef struct EDM_FULL_COLLECTION_LITERAL_TAG
+{
+    EDM_SRID_LITERAL srid;
+    EDM_COLLECTION_LITERAL collectionLiteral;
+}EDM_FULL_COLLECTION_LITERAL;
+
+/*now geography stuff*/
+
+/*geographyCollection   = geographyPrefix SQUOTE fullCollectionLiteral SQUOTE*/
+typedef struct EDM_GEOGRAPHY_COLLECTION_TAG
+{
+    EDM_FULL_COLLECTION_LITERAL fullCollectionLiteral;
+}EDM_GEOGRAPHY_COLLECTION;
+
+/*geographyLineString   = geographyPrefix SQUOTE fullLineStringLiteral SQUOTE*/
+typedef struct EDM_GEOGRAPHY_LINE_STRING_TAG
+{
+    EDM_FULL_LINE_STRING_LITERAL fullLineStringLiteral;
+}EDM_GEOGRAPHY_LINE_STRING;
+
+/*geographyMultiLineString   = geographyPrefix SQUOTE fullMultiLineStringLiteral SQUOTE*/
+typedef struct EDM_GEOGRAPHY_MULTI_LINE_STRING_TAG
+{
+    EDM_FULL_MULTI_LINE_STRING_LITERAL fullMultiLineStringLiteral;
+}EDM_GEOGRAPHY_MULTI_LINE_STRING;
+
+/*geographyMultiPoint   = geographyPrefix SQUOTE fullMultiPointLiteral SQUOTE*/
+typedef struct EDM_GEOGRAPHY_MULTI_POINT_TAG
+{
+    EDM_FULL_MULTI_POINT_LITERAL fullMultiPointLiteral;
+}EDM_GEOGRAPHY_MULTI_POINT;
+
+/*geographyMultiPolygon   = geographyPrefix SQUOTE fullMultiPolygonLiteral SQUOTE*/
+typedef struct EDM_GEOGRAPHY_MULTI_POLYGON_TAG
+{
+    EDM_FULL_MULTI_POLYGON_LITERAL fullMultiPolygonLiteral;
+}EDM_GEOGRAPHY_MULTI_POLYGON;
+
+/*geographyPolygon   = geographyPrefix SQUOTE fullPolygonLiteral SQUOTE*/
+typedef struct EDM_GEOGRAPHY_POLYGON_TAG
+{
+    EDM_FULL_POLYGON_LITERAL fullPolygonLiteral;
+}EDM_GEOGRAPHY_POLYGON;
+
+/*geometryCollection      = geometryPrefix SQUOTE fullCollectionLiteral      SQUOTE*/
+/*forward defines*/
+
+
+/*geometryPolygon         = geometryPrefix SQUOTE fullPolygonLiteral         SQUOTE*/
+typedef struct EDM_GEOMETRY_POLYGON_TAG
+{
+    EDM_FULL_POLYGON_LITERAL fullPolygonLiteral;
+}EDM_GEOMETRY_POLYGON;
+
+/*geometryPoint           = geometryPrefix SQUOTE fullPointLiteral           SQUOTE*/
+typedef struct EDM_GEOMETRY_POINT_TAG
+{
+    EDM_FULL_POINT_LITERAL fullPointLiteral;
+}EDM_GEOMETRY_POINT;
+
+/*geometryMultiPolygon    = geometryPrefix SQUOTE fullMultiPolygonLiteral    SQUOTE*/
+typedef struct EDM_GEOMETRY_MULTI_POLYGON_TAG
+{
+    EDM_FULL_MULTI_POLYGON_LITERAL fullMultiPolygonLiteral;
+}
+EDM_GEOMETRY_MULTI_POLYGON;
+
+/*geometryMultiPoint      = geometryPrefix SQUOTE fullMultiPointLiteral      SQUOTE*/
+typedef struct EDM_GEOMETRY_MULTI_POINT_TAG
+{
+    EDM_FULL_MULTI_POINT_LITERAL fullMultiPointLiteral;
+}EDM_GEOMETRY_MULTI_POINT;
+
+/*geometryMultiLineString = geometryPrefix SQUOTE fullMultiLineStringLiteral SQUOTE*/
+typedef struct EDM_GEOMETRY_MULTI_LINE_STRING_TAG
+{
+    EDM_FULL_MULTI_LINE_STRING_LITERAL fullMultiLineStringLiteral;
+}EDM_GEOMETRY_MULTI_LINE_STRING;
+
+/*geometryLineString      = geometryPrefix SQUOTE fullLineStringLiteral      SQUOTE*/
+typedef struct EDM_GEOMETRY_LINE_STRING_TAG
+{
+    EDM_FULL_LINE_STRING_LITERAL fullLineStringLiteral;
+}EDM_GEOMETRY_LINE_STRING;
+
+/*geometryCollection      = geometryPrefix SQUOTE fullCollectionLiteral      SQUOTE*/
+typedef struct EDM_GEOMETRY_COLLECTION_TAG
+{
+    EDM_FULL_COLLECTION_LITERAL fullCollectionLiteral;
+}EDM_GEOMETRY_COLLECTION;
+
+/*holds the name and the value of a COMPLEX_TYPE... field*/
+typedef struct COMPLEX_TYPE_FIELD_TAG
+{
+    const char* fieldName;
+    AGENT_DATA_TYPE* value;
+}COMPLEX_TYPE_FIELD_TYPE;
+
+/*EDM_COMPLEX_TYPE - this type doesn't exist in EDMX as a primitive type*/
+typedef struct EDM_COMPLEX_TYPE_TAG
+{
+    size_t nMembers;
+    COMPLEX_TYPE_FIELD_TYPE *fields;
+}EDM_COMPLEX_TYPE;
+
+#define AGENT_DATA_TYPES_RESULT_VALUES \
+    AGENT_DATA_TYPES_OK, \
+    AGENT_DATA_TYPES_ERROR, \
+    AGENT_DATA_TYPES_INVALID_ARG, \
+    AGENT_DATA_TYPES_NOT_IMPLEMENTED, \
+    AGENT_DATA_TYPES_JSON_ENCODER_ERRROR
+
+MU_DEFINE_ENUM_WITHOUT_INVALID(AGENT_DATA_TYPES_RESULT, AGENT_DATA_TYPES_RESULT_VALUES);
+
+#define AGENT_DATA_TYPE_TYPE_VALUES\
+    EDM_NO_TYPE,                                                                   \
+    EDM_BINARY_TYPE,                                                               \
+    EDM_BOOLEAN_TYPE,                                                              \
+    EDM_BYTE_TYPE,                                                                 \
+    EDM_DATE_TYPE,                                                                 \
+    EDM_DATE_TIME_OFFSET_TYPE,                                                     \
+    EDM_DECIMAL_TYPE,                                                              \
+    EDM_DOUBLE_TYPE,                                                               \
+    EDM_DURATION_TYPE,                                                             \
+    EDM_GUID_TYPE,                                                                 \
+    EDM_INT16_TYPE,                                                                \
+    EDM_INT32_TYPE,                                                                \
+    EDM_INT64_TYPE,                                                                \
+    EDM_SBYTE_TYPE,                                                                \
+    EDM_SINGLE_TYPE,                                                               \
+    EDM_STREAM, /*not supported, because what is stream?*/                         \
+    EDM_STRING_TYPE,                                                               \
+    EDM_TIME_OF_DAY_TYPE,                                                          \
+    EDM_GEOGRAPHY_TYPE, /*not supported because what is "abstract base type"*/     \
+    EDM_GEOGRAPHY_POINT_TYPE,                                                      \
+    EDM_GEOGRAPHY_LINE_STRING_TYPE,                                                \
+    EDM_GEOGRAPHY_POLYGON_TYPE,                                                    \
+    EDM_GEOGRAPHY_MULTI_POINT_TYPE,                                                \
+    EDM_GEOGRAPHY_MULTI_LINE_STRING_TYPE,                                          \
+    EDM_GEOGRAPHY_MULTI_POLYGON_TYPE,                                              \
+    EDM_GEOGRAPHY_COLLECTION_TYPE,                                                 \
+    EDM_GEOMETRY_TYPE, /*not supported because what is "abstract base type"*/      \
+    EDM_GEOMETRY_POINT_TYPE,                                                       \
+    EDM_GEOMETRY_LINE_STRING_TYPE,                                                 \
+    EDM_GEOMETRY_POLYGON_TYPE,                                                     \
+    EDM_GEOMETRY_MULTI_POINT_TYPE,                                                 \
+    EDM_GEOMETRY_MULTI_LINE_STRING_TYPE,                                           \
+    EDM_GEOMETRY_MULTI_POLYGON_TYPE,                                               \
+    EDM_GEOMETRY_COLLECTION_TYPE,                                                  \
+    EDM_COMPLEX_TYPE_TYPE,                                                         \
+    EDM_NULL_TYPE,                                                                 \
+    EDM_ENTITY_TYPE_TYPE,                                                          \
+    EDM_STRING_NO_QUOTES_TYPE                                                      \
+
+
+MU_DEFINE_ENUM_WITHOUT_INVALID(AGENT_DATA_TYPE_TYPE, AGENT_DATA_TYPE_TYPE_VALUES);
+
+struct AGENT_DATA_TYPE_TAG
+{
+    AGENT_DATA_TYPE_TYPE type;
+    union
+    {
+        EDM_BINARY edmBinary;
+        EDM_BOOLEAN edmBoolean;
+        EDM_BYTE edmByte;
+        EDM_DATE edmDate;
+        EDM_DATE_TIME_OFFSET edmDateTimeOffset;
+        EDM_DECIMAL edmDecimal;
+        EDM_DOUBLE edmDouble;
+        EDM_DURATION edmDuration;
+        EDM_GUID edmGuid;
+        EDM_INT16 edmInt16;
+        EDM_INT32 edmInt32;
+        EDM_INT64 edmInt64;
+        EDM_SBYTE edmSbyte;
+        EDM_SINGLE edmSingle;
+        /*EDM_STREAM, not supported, because what is stream?*/
+        EDM_STRING edmString;
+        EDM_STRING edmStringNoQuotes;
+        EDM_TIME_OF_DAY edmTimeOfDay;
+        /*EDM_GEOGRAPHY_, not supported because what is "abstract base type"*/
+        EDM_GEOGRAPHY_POINT edmGeographyPoint;
+        EDM_GEOGRAPHY_LINE_STRING edmGeographyLineString;
+        EDM_GEOGRAPHY_POLYGON edmGeographyPolygon;
+        EDM_GEOGRAPHY_MULTI_POINT edmGeographyMultiPoint;
+        EDM_GEOGRAPHY_MULTI_LINE_STRING edmGeographyMultiLineString;
+        EDM_GEOGRAPHY_MULTI_POLYGON edmGeographyMultiPolygon;
+        EDM_GEOGRAPHY_COLLECTION edmGeographyCollection;
+        /* EDM_GEOMETRY_, not supported because what is "abstract base type"*/
+        EDM_GEOMETRY_POINT edmGeometryPoint;
+        EDM_GEOMETRY_LINE_STRING edmGeometryLineString;
+        EDM_GEOMETRY_POLYGON edmGeometryPolygon;
+        EDM_GEOMETRY_MULTI_POINT edmGeometryMultiPoint;
+        EDM_GEOMETRY_MULTI_LINE_STRING edmGeoemtryMultiLineString;
+        EDM_GEOMETRY_MULTI_POLYGON edmGeometryMultiPolygon;
+        EDM_GEOMETRY_COLLECTION edmGeometryCollection;
+        EDM_COMPLEX_TYPE edmComplexType;
+    } value;
+};
+
+#include "umock_c/umock_c_prod.h"
+
+MOCKABLE_FUNCTION(, AGENT_DATA_TYPES_RESULT, AgentDataTypes_ToString, STRING_HANDLE, destination, const AGENT_DATA_TYPE*, value);
+
+/*Create/Destroy work in pairs. For some data type not calling Uncreate might be ok. For some, it will lead to memory leaks*/
+
+/*creates an AGENT_DATA_TYPE containing a EDM_BOOLEAN from a int*/
+MOCKABLE_FUNCTION(, AGENT_DATA_TYPES_RESULT, Create_EDM_BOOLEAN_from_int, AGENT_DATA_TYPE*, agentData, int, v);
+
+/*creates an AGENT_DATA_TYPE containing a UINT8*/
+MOCKABLE_FUNCTION(, AGENT_DATA_TYPES_RESULT, Create_AGENT_DATA_TYPE_from_UINT8, AGENT_DATA_TYPE*, agentData, uint8_t, v);
+
+/*creates an AGENT_DATA_TYPE containing a EDM_DATE */
+MOCKABLE_FUNCTION(, AGENT_DATA_TYPES_RESULT, Create_AGENT_DATA_TYPE_from_date, AGENT_DATA_TYPE*, agentData, int16_t, year, uint8_t, month, uint8_t, day);
+
+/*create an AGENT_DATA_TYPE containing an EDM_DECIMAL from a string representation*/
+MOCKABLE_FUNCTION(, AGENT_DATA_TYPES_RESULT, Create_EDM_DECIMAL_from_charz, AGENT_DATA_TYPE*, agentData, const char*, v);
+
+/*create an AGENT_DATA_TYPE containing an EDM_DOUBLE from a double*/
+MOCKABLE_FUNCTION(, AGENT_DATA_TYPES_RESULT, Create_AGENT_DATA_TYPE_from_DOUBLE, AGENT_DATA_TYPE*, agentData, double, v);
+
+/*create an AGENT_DATA_TYPE from INT16_T*/
+MOCKABLE_FUNCTION(, AGENT_DATA_TYPES_RESULT, Create_AGENT_DATA_TYPE_from_SINT16, AGENT_DATA_TYPE*, agentData, int16_t, v);
+
+/*create an AGENT_DATA_TYPE from INT32_T*/
+MOCKABLE_FUNCTION(, AGENT_DATA_TYPES_RESULT, Create_AGENT_DATA_TYPE_from_SINT32, AGENT_DATA_TYPE*, agentData, int32_t, v);
+
+/*create an AGENT_DATA_TYPE from INT64_T*/
+MOCKABLE_FUNCTION(, AGENT_DATA_TYPES_RESULT, Create_AGENT_DATA_TYPE_from_SINT64, AGENT_DATA_TYPE*, agentData, int64_t, v);
+
+/*create an AGENT_DATA_TYPE from int8_t*/
+MOCKABLE_FUNCTION(, AGENT_DATA_TYPES_RESULT, Create_AGENT_DATA_TYPE_from_SINT8, AGENT_DATA_TYPE*, agentData, int8_t, v);
+
+/*Codes_SRS_AGENT_TYPE_SYSTEM_99_091:[Creates an AGENT_DATA_TYPE containing an Edm.DateTimeOffset from an EDM_DATE_TIME_OFFSET.]*/
+MOCKABLE_FUNCTION(, AGENT_DATA_TYPES_RESULT, Create_AGENT_DATA_TYPE_from_EDM_DATE_TIME_OFFSET, AGENT_DATA_TYPE*, agentData, EDM_DATE_TIME_OFFSET, v);
+
+/*creates an AGENT_DATA_TYPE containing a EDM_GUID*/
+MOCKABLE_FUNCTION(, AGENT_DATA_TYPES_RESULT, Create_AGENT_DATA_TYPE_from_EDM_GUID, AGENT_DATA_TYPE*, agentData, EDM_GUID, v);
+
+/*creates an AGENT_DATA_TYPE containing a EDM_BINARY*/
+MOCKABLE_FUNCTION(, AGENT_DATA_TYPES_RESULT, Create_AGENT_DATA_TYPE_from_EDM_BINARY, AGENT_DATA_TYPE*, agentData, EDM_BINARY, v);
+
+/*create an AGENT_DATA_TYPE from SINGLE*/
+MOCKABLE_FUNCTION(, AGENT_DATA_TYPES_RESULT, Create_AGENT_DATA_TYPE_from_FLOAT, AGENT_DATA_TYPE*, agentData, float, v);
+
+/*create an AGENT_DATA_TYPE from ANSI zero terminated string*/
+MOCKABLE_FUNCTION(, AGENT_DATA_TYPES_RESULT, Create_AGENT_DATA_TYPE_from_charz, AGENT_DATA_TYPE*, agentData, const char*, v);
+
+/*create an AGENT_DATA_TYPE from ANSI zero terminated string (no quotes)*/
+MOCKABLE_FUNCTION(, AGENT_DATA_TYPES_RESULT, Create_AGENT_DATA_TYPE_from_charz_no_quotes, AGENT_DATA_TYPE*, agentData, const char*, v);
+
+/*create an AGENT_DATA_TYPE of type EDM_NULL_TYPE */
+MOCKABLE_FUNCTION(, AGENT_DATA_TYPES_RESULT, Create_NULL_AGENT_DATA_TYPE, AGENT_DATA_TYPE*, agentData);
+
+/*create an AGENT_DATA_TYPE that holds a structs from its fields*/
+MOCKABLE_FUNCTION(, AGENT_DATA_TYPES_RESULT, Create_AGENT_DATA_TYPE_from_Members, AGENT_DATA_TYPE*,agentData, const char*, typeName, size_t, nMembers, const char* const *, memberNames, const AGENT_DATA_TYPE*, memberValues);
+
+/*create a complex AGENT_DATA_TYPE from pointers to AGENT_DATA_TYPE fields*/
+MOCKABLE_FUNCTION(, AGENT_DATA_TYPES_RESULT, Create_AGENT_DATA_TYPE_from_MemberPointers, AGENT_DATA_TYPE*, agentData, const char*, typeName, size_t, nMembers, const char* const *, memberNames, const AGENT_DATA_TYPE** ,memberPointerValues);
+
+/*creates a copy of the AGENT_DATA_TYPE*/
+MOCKABLE_FUNCTION(, AGENT_DATA_TYPES_RESULT, Create_AGENT_DATA_TYPE_from_AGENT_DATA_TYPE, AGENT_DATA_TYPE*, dest, const AGENT_DATA_TYPE*, src);
+
+MOCKABLE_FUNCTION(, void, Destroy_AGENT_DATA_TYPE, AGENT_DATA_TYPE*, agentData);
+
+MOCKABLE_FUNCTION(, AGENT_DATA_TYPES_RESULT, CreateAgentDataType_From_String, const char*, source, AGENT_DATA_TYPE_TYPE, type, AGENT_DATA_TYPE*, agentData);
+
+MOCKABLE_FUNCTION(, COMPLEX_TYPE_FIELD_TYPE*, AgentDataType_GetComplexTypeField, AGENT_DATA_TYPE*, agentData, size_t, index);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
Index: azure_iot_hub_f767zi/trunk/azure_iot_sdk/serializer/inc/codefirst.h
===================================================================
--- azure_iot_hub_f767zi/trunk/azure_iot_sdk/serializer/inc/codefirst.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/azure_iot_sdk/serializer/inc/codefirst.h	(revision 457)
@@ -0,0 +1,191 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+#ifndef CODEFIRST_H
+#define CODEFIRST_H
+
+#include "methodreturn.h"
+#include "agenttypesystem.h"
+#include "schema.h"
+#include "azure_macro_utils/macro_utils.h"
+#include "azure_c_shared_utility/strings.h"
+#include "iotdevice.h"
+
+#ifdef __cplusplus
+#include <cstddef>
+#include <cstdarg>
+extern "C" {
+#else
+#include <stddef.h>
+#include <stdarg.h>
+#include <stdbool.h>
+#endif
+
+typedef char* ascii_char_ptr;
+typedef char* ascii_char_ptr_no_quotes;
+
+typedef enum REFLECTION_TYPE_TAG
+{
+    REFLECTION_METHOD_TYPE,
+    REFLECTION_DESIRED_PROPERTY_TYPE,
+    REFLECTION_REPORTED_PROPERTY_TYPE,
+    REFLECTION_STRUCT_TYPE,
+    REFLECTION_FIELD_TYPE,
+    REFLECTION_PROPERTY_TYPE,
+    REFLECTION_ACTION_TYPE,
+    REFLECTION_MODEL_TYPE,
+    REFLECTION_NOTHING
+}REFLECTION_TYPE;
+
+typedef EXECUTE_COMMAND_RESULT (*actionWrapper)(void* device, size_t ParameterCount, const AGENT_DATA_TYPE* values);
+
+typedef METHODRETURN_HANDLE (*methodWrapper)(void* device, size_t ParameterCount, const AGENT_DATA_TYPE* values);
+
+typedef struct REFLECTION_STRUCT_TAG
+{
+    const char* name;
+}REFLECTION_STRUCT;
+
+typedef struct WRAPPER_ARGUMENT_TAG
+{
+    const char* type;
+    const char* name;
+}WRAPPER_ARGUMENT;
+
+typedef struct REFLECTION_ACTION_TAG
+{
+    const char* name;
+    size_t nArguments;
+    const WRAPPER_ARGUMENT* arguments;
+    actionWrapper wrapper;
+    const char* modelName;
+}REFLECTION_ACTION;
+
+typedef struct REFLECTION_METHOD_TAG
+{
+    const char* name;
+    size_t nArguments;
+    const WRAPPER_ARGUMENT* arguments;
+    methodWrapper wrapper;
+    const char* modelName;
+}REFLECTION_METHOD;
+
+typedef struct REFLECTION_FIELD_TAG
+{
+    const char* fieldName;
+    const char* fieldType;
+    const char* structName;
+}REFLECTION_FIELD;
+
+typedef struct REFLECTION_PROPERTY_TAG
+{
+    const char* name;
+    const char* type;
+    int(*Create_AGENT_DATA_TYPE_from_Ptr)(void* param, AGENT_DATA_TYPE* dest);
+    size_t offset;
+    size_t size;
+    const char* modelName;
+} REFLECTION_PROPERTY;
+
+
+typedef struct REFLECTION_REPORTED_PROPERTY_TAG
+{
+    const char* name;
+    const char* type;
+    int(*Create_AGENT_DATA_TYPE_from_Ptr)(void* param, AGENT_DATA_TYPE* dest);
+    size_t offset;
+    size_t size;
+    const char* modelName;
+} REFLECTION_REPORTED_PROPERTY;
+
+typedef struct REFLECTION_DESIRED_PROPERTY_TAG
+{
+    pfOnDesiredProperty onDesiredProperty;
+    void(*desiredPropertInitialize)(void* destination);
+    void(*desiredPropertDeinitialize)(void* destination);
+    const char* name;
+    const char* type;
+    int(*FromAGENT_DATA_TYPE)(const AGENT_DATA_TYPE* source, void* dest); /*destination is "something" everytime. When the DESIRED_PROPERTY is a MODEL, the function is empty*/
+    size_t offset;
+    size_t size;
+    const char* modelName;
+} REFLECTION_DESIRED_PROPERTY;
+
+typedef struct REFLECTION_MODEL_TAG
+{
+    const char* name;
+} REFLECTION_MODEL;
+
+typedef struct REFLECTED_SOMETHING_TAG
+{
+    REFLECTION_TYPE type;
+    const struct REFLECTED_SOMETHING_TAG* next;
+    struct what
+    {
+        REFLECTION_METHOD method;
+        REFLECTION_DESIRED_PROPERTY desiredProperty;
+        REFLECTION_REPORTED_PROPERTY reportedProperty;
+        REFLECTION_STRUCT structure;
+        REFLECTION_FIELD field;
+        REFLECTION_PROPERTY property;
+        REFLECTION_ACTION action;
+        REFLECTION_MODEL model;
+    } what;
+} REFLECTED_SOMETHING;
+
+typedef struct REFLECTED_DATA_FROM_DATAPROVIDER_TAG
+{
+    const REFLECTED_SOMETHING* reflectedData;
+}REFLECTED_DATA_FROM_DATAPROVIDER;
+
+#define ALL_SOMETHING_REFLECTED(schemaNamespace) MU_C2(schemaNamespace, _allSomethingReflected)
+#define ALL_REFLECTED(schemaNamespace) MU_C2(schemaNamespace, _allReflected)
+#define ADDRESS_OF_ALL_REFLECTED(schemaNamespace) & MU_C2(schemaNamespace, _allReflected),
+#define DECLARE_EXTERN_CONST_DATAPROVIDER_DATA(x) extern const REFLECTED_DATA_FROM_DATAPROVIDER ALL_REFLECTED(x);
+
+#define CODEFIRST_RESULT_VALUES                \
+CODEFIRST_OK,                                  \
+CODEFIRST_INVALID_ARG,                         \
+CODEFIRST_ALREADY_INIT,                        \
+CODEFIRST_NOT_INIT,                            \
+CODEFIRST_ERROR,                               \
+CODEFIRST_NOT_ENOUGH_MEMORY,                   \
+CODEFIRST_ACTION_NOT_FOUND,                    \
+CODEFIRST_ACTION_EXECUTION_ERROR,              \
+CODEFIRST_SCHEMA_ERROR,                        \
+CODEFIRST_AGENT_DATA_TYPE_ERROR,               \
+CODEFIRST_VALUES_FROM_DIFFERENT_DEVICES_ERROR, \
+CODEFIRST_DEVICE_FAILED,                       \
+CODEFIRST_DEVICE_PUBLISH_FAILED,               \
+CODEFIRST_NOT_A_PROPERTY
+
+MU_DEFINE_ENUM_WITHOUT_INVALID(CODEFIRST_RESULT, CODEFIRST_RESULT_VALUES)
+
+#include "umock_c/umock_c_prod.h"
+MOCKABLE_FUNCTION(, CODEFIRST_RESULT, CodeFirst_Init, const char*, overrideSchemaNamespace);
+MOCKABLE_FUNCTION(, void, CodeFirst_Deinit);
+MOCKABLE_FUNCTION(, SCHEMA_HANDLE, CodeFirst_RegisterSchema, const char*, schemaNamespace, const REFLECTED_DATA_FROM_DATAPROVIDER*, metadata);
+
+MOCKABLE_FUNCTION(, EXECUTE_COMMAND_RESULT, CodeFirst_InvokeAction, DEVICE_HANDLE, deviceHandle, void*, callbackUserContext, const char*, relativeActionPath, const char*, actionName, size_t, parameterCount, const AGENT_DATA_TYPE*, parameterValues);
+
+MOCKABLE_FUNCTION(, METHODRETURN_HANDLE, CodeFirst_InvokeMethod, DEVICE_HANDLE, deviceHandle, void*, callbackUserContext, const char*, relativeMethodPath, const char*, methodName, size_t, parameterCount, const AGENT_DATA_TYPE*, parameterValues);
+
+MOCKABLE_FUNCTION(, EXECUTE_COMMAND_RESULT, CodeFirst_ExecuteCommand, void*, device, const char*, command);
+
+MOCKABLE_FUNCTION(, METHODRETURN_HANDLE, CodeFirst_ExecuteMethod, void*, device, const char*, methodName, const char*, methodPayload);
+
+MOCKABLE_FUNCTION(, void*, CodeFirst_CreateDevice, SCHEMA_MODEL_TYPE_HANDLE, model, const REFLECTED_DATA_FROM_DATAPROVIDER*, metadata, size_t, dataSize, bool, includePropertyPath);
+MOCKABLE_FUNCTION(, void, CodeFirst_DestroyDevice, void*, device);
+
+extern CODEFIRST_RESULT CodeFirst_SendAsync(unsigned char** destination, size_t* destinationSize, size_t numProperties, ...);
+extern CODEFIRST_RESULT CodeFirst_SendAsyncReported(unsigned char** destination, size_t* destinationSize, size_t numReportedProperties, ...);
+
+MOCKABLE_FUNCTION(, CODEFIRST_RESULT, CodeFirst_IngestDesiredProperties, void*, device, const char*, jsonPayload, bool, parseDesiredNode);
+
+MOCKABLE_FUNCTION(, AGENT_DATA_TYPE_TYPE, CodeFirst_GetPrimitiveType, const char*, typeName);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* CODEFIRST_H */
Index: azure_iot_hub_f767zi/trunk/azure_iot_sdk/serializer/inc/commanddecoder.h
===================================================================
--- azure_iot_hub_f767zi/trunk/azure_iot_sdk/serializer/inc/commanddecoder.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/azure_iot_sdk/serializer/inc/commanddecoder.h	(revision 457)
@@ -0,0 +1,55 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+#ifndef COMMAND_DECODER_H
+#define COMMAND_DECODER_H
+
+#include "multitree.h"
+#include "schema.h"
+#include "agenttypesystem.h"
+#include "azure_macro_utils/macro_utils.h"
+#include "methodreturn.h"
+
+#ifdef __cplusplus
+extern "C" {
+#else
+#include <stdbool.h>
+#endif
+
+#define COMMANDDECODER_RESULT_VALUES \
+    COMMANDDECODER_OK, \
+    COMMANDDECODER_ERROR, \
+    COMMANDDECODER_INVALID_ARG
+
+MU_DEFINE_ENUM_WITHOUT_INVALID(COMMANDDECODER_RESULT, COMMANDDECODER_RESULT_VALUES)
+
+#define EXECUTE_COMMAND_RESULT_VALUES \
+EXECUTE_COMMAND_SUCCESS, /*when the final recipient of the command indicates a successful execution*/ \
+EXECUTE_COMMAND_FAILED, /*when the final recipient of the command indicates a failure*/ \
+EXECUTE_COMMAND_ERROR /*when a transient error either in the final recipient or until the final recipient*/
+
+MU_DEFINE_ENUM_WITHOUT_INVALID(EXECUTE_COMMAND_RESULT, EXECUTE_COMMAND_RESULT_VALUES)
+
+
+
+
+/* Codes_SRS_COMMAND_DECODER_99_001:[ The CommandDecoder module shall expose the following API:] */
+
+typedef struct COMMAND_DECODER_HANDLE_DATA_TAG* COMMAND_DECODER_HANDLE;
+typedef EXECUTE_COMMAND_RESULT(*ACTION_CALLBACK_FUNC)(void* actionCallbackContext, const char* relativeActionPath, const char* actionName, size_t argCount, const AGENT_DATA_TYPE* args);
+typedef METHODRETURN_HANDLE(*METHOD_CALLBACK_FUNC)(void* methodCallbackContext, const char* relativeMethodPath, const char* methodName, size_t argCount, const AGENT_DATA_TYPE* args);
+
+#include "umock_c/umock_c_prod.h"
+
+MOCKABLE_FUNCTION(,COMMAND_DECODER_HANDLE, CommandDecoder_Create, SCHEMA_MODEL_TYPE_HANDLE, modelHandle, ACTION_CALLBACK_FUNC, actionCallback, void*, actionCallbackContext, METHOD_CALLBACK_FUNC, methodCallback, void*, methodCallbackContext);
+MOCKABLE_FUNCTION(,EXECUTE_COMMAND_RESULT, CommandDecoder_ExecuteCommand, COMMAND_DECODER_HANDLE, handle, const char*, command);
+MOCKABLE_FUNCTION(,METHODRETURN_HANDLE, CommandDecoder_ExecuteMethod, COMMAND_DECODER_HANDLE, handle, const char*, fullMethodName, const char*, methodPayload);
+MOCKABLE_FUNCTION(,void, CommandDecoder_Destroy, COMMAND_DECODER_HANDLE, commandDecoderHandle);
+
+MOCKABLE_FUNCTION(, EXECUTE_COMMAND_RESULT, CommandDecoder_IngestDesiredProperties, void*, startAddress, COMMAND_DECODER_HANDLE, handle, const char*, jsonPayload, bool, parseDesiredNode);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* COMMAND_DECODER_H */
Index: azure_iot_hub_f767zi/trunk/azure_iot_sdk/serializer/inc/datamarshaller.h
===================================================================
--- azure_iot_hub_f767zi/trunk/azure_iot_sdk/serializer/inc/datamarshaller.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/azure_iot_sdk/serializer/inc/datamarshaller.h	(revision 457)
@@ -0,0 +1,51 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+#ifndef DATAMARSHALLER_H
+#define DATAMARSHALLER_H
+
+#include <stdbool.h>
+#include "agenttypesystem.h"
+#include "schema.h"
+#include "azure_macro_utils/macro_utils.h"
+#include "azure_c_shared_utility/vector.h"
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/*Codes_SRS_DATA_MARSHALLER_99_002:[ DataMarshaller shall have the following interface]*/
+#define DATA_MARSHALLER_RESULT_VALUES           \
+DATA_MARSHALLER_OK,                             \
+DATA_MARSHALLER_INVALID_ARG,                    \
+DATA_MARSHALLER_NO_DEVICE_IDENTITY,             \
+DATA_MARSHALLER_SCHEMA_FAILED,                  \
+DATA_MARSHALLER_INVALID_MODEL_PROPERTY,         \
+DATA_MARSHALLER_JSON_ENCODER_ERROR,             \
+DATA_MARSHALLER_ERROR,                          \
+DATA_MARSHALLER_AGENT_DATA_TYPES_ERROR,         \
+DATA_MARSHALLER_MULTITREE_ERROR,                \
+DATA_MARSHALLER_ONLY_ONE_VALUE_ALLOWED          \
+
+MU_DEFINE_ENUM_WITHOUT_INVALID(DATA_MARSHALLER_RESULT, DATA_MARSHALLER_RESULT_VALUES);
+
+typedef struct DATA_MARSHALLER_VALUE_TAG
+{
+    const char* PropertyPath;
+    const AGENT_DATA_TYPE* Value;
+} DATA_MARSHALLER_VALUE;
+
+typedef struct DATA_MARSHALLER_HANDLE_DATA_TAG* DATA_MARSHALLER_HANDLE;
+#include "umock_c/umock_c_prod.h"
+
+MOCKABLE_FUNCTION(,DATA_MARSHALLER_HANDLE, DataMarshaller_Create, SCHEMA_MODEL_TYPE_HANDLE, modelHandle, bool, includePropertyPath);
+MOCKABLE_FUNCTION(,void, DataMarshaller_Destroy, DATA_MARSHALLER_HANDLE, dataMarshallerHandle);
+MOCKABLE_FUNCTION(,DATA_MARSHALLER_RESULT, DataMarshaller_SendData, DATA_MARSHALLER_HANDLE, dataMarshallerHandle, size_t, valueCount, const DATA_MARSHALLER_VALUE*, values, unsigned char**, destination, size_t*, destinationSize);
+
+MOCKABLE_FUNCTION(, DATA_MARSHALLER_RESULT, DataMarshaller_SendData_ReportedProperties, DATA_MARSHALLER_HANDLE, dataMarshallerHandle, VECTOR_HANDLE, values, unsigned char**, destination, size_t*, destinationSize);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* DATAMARSHALLER_H */
Index: azure_iot_hub_f767zi/trunk/azure_iot_sdk/serializer/inc/datapublisher.h
===================================================================
--- azure_iot_hub_f767zi/trunk/azure_iot_sdk/serializer/inc/datapublisher.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/azure_iot_sdk/serializer/inc/datapublisher.h	(revision 457)
@@ -0,0 +1,54 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+#ifndef DATA_PUBLISHER_H
+#define DATA_PUBLISHER_H
+
+#include "agenttypesystem.h"
+#include "schema.h"
+/* Normally we could include <stdbool> for cpp, but some toolchains are not well behaved and simply don't have it - ARM CC for example */
+#include <stdbool.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define DATA_PUBLISHER_RESULT_VALUES    \
+DATA_PUBLISHER_OK,                      \
+DATA_PUBLISHER_INVALID_ARG,             \
+DATA_PUBLISHER_MARSHALLER_ERROR,        \
+DATA_PUBLISHER_EMPTY_TRANSACTION,       \
+DATA_PUBLISHER_AGENT_DATA_TYPES_ERROR,  \
+DATA_PUBLISHER_SCHEMA_FAILED,           \
+DATA_PUBLISHER_BUFFER_STORAGE_ERROR,    \
+DATA_PUBLISHER_ERROR
+
+MU_DEFINE_ENUM_WITHOUT_INVALID(DATA_PUBLISHER_RESULT, DATA_PUBLISHER_RESULT_VALUES);
+
+#include "umock_c/umock_c_prod.h"
+
+typedef struct TRANSACTION_HANDLE_DATA_TAG* TRANSACTION_HANDLE;
+typedef struct REPORTED_PROPERTIES_TRANSACTION_HANDLE_DATA_TAG* REPORTED_PROPERTIES_TRANSACTION_HANDLE;
+typedef struct DATA_PUBLISHER_HANDLE_DATA_TAG* DATA_PUBLISHER_HANDLE;
+
+MOCKABLE_FUNCTION(,DATA_PUBLISHER_HANDLE, DataPublisher_Create, SCHEMA_MODEL_TYPE_HANDLE, modelHandle, bool, includePropertyPath);
+MOCKABLE_FUNCTION(,void, DataPublisher_Destroy, DATA_PUBLISHER_HANDLE, dataPublisherHandle);
+
+MOCKABLE_FUNCTION(,TRANSACTION_HANDLE, DataPublisher_StartTransaction, DATA_PUBLISHER_HANDLE, dataPublisherHandle);
+MOCKABLE_FUNCTION(,DATA_PUBLISHER_RESULT, DataPublisher_PublishTransacted, TRANSACTION_HANDLE, transactionHandle, const char*, propertyPath, const AGENT_DATA_TYPE*, data);
+MOCKABLE_FUNCTION(,DATA_PUBLISHER_RESULT, DataPublisher_EndTransaction, TRANSACTION_HANDLE, transactionHandle, unsigned char**, destination, size_t*, destinationSize);
+MOCKABLE_FUNCTION(,DATA_PUBLISHER_RESULT, DataPublisher_CancelTransaction, TRANSACTION_HANDLE, transactionHandle);
+MOCKABLE_FUNCTION(,void, DataPublisher_SetMaxBufferSize, size_t, value);
+MOCKABLE_FUNCTION(,size_t, DataPublisher_GetMaxBufferSize);
+
+MOCKABLE_FUNCTION(, REPORTED_PROPERTIES_TRANSACTION_HANDLE, DataPublisher_CreateTransaction_ReportedProperties, DATA_PUBLISHER_HANDLE, dataPublisherHandle);
+MOCKABLE_FUNCTION(, DATA_PUBLISHER_RESULT, DataPublisher_PublishTransacted_ReportedProperty, REPORTED_PROPERTIES_TRANSACTION_HANDLE, transactionHandle, const char*, reportedPropertyPath, const AGENT_DATA_TYPE*, data);
+MOCKABLE_FUNCTION(, DATA_PUBLISHER_RESULT, DataPublisher_CommitTransaction_ReportedProperties, REPORTED_PROPERTIES_TRANSACTION_HANDLE, transactionHandle, unsigned char**, destination, size_t*, destinationSize);
+MOCKABLE_FUNCTION(, void, DataPublisher_DestroyTransaction_ReportedProperties, REPORTED_PROPERTIES_TRANSACTION_HANDLE, transactionHandle);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* DATA_PUBLISHER_H */
Index: azure_iot_hub_f767zi/trunk/azure_iot_sdk/serializer/inc/dataserializer.h
===================================================================
--- azure_iot_hub_f767zi/trunk/azure_iot_sdk/serializer/inc/dataserializer.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/azure_iot_sdk/serializer/inc/dataserializer.h	(revision 457)
@@ -0,0 +1,42 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+#ifndef DATASERIALIZER_H
+#define DATASERIALIZER_H
+
+#include "azure_macro_utils/macro_utils.h"
+#include "multitree.h"
+#include "azure_c_shared_utility/buffer_.h"
+
+#ifdef __cplusplus
+#include <cstddef>
+extern "C"
+{
+#else
+#include <stddef.h>
+#endif
+
+/*Codes_SRS_DATA_SERIALIZER_07_001: [DataSerializer will have the following interface]*/
+#define DATA_SERIALIZER_RESULT_VALUES           \
+DATA_SERIALIZER_INVALID_ARG,                    \
+DATA_SERIALIZER_ERROR                            \
+
+MU_DEFINE_ENUM_WITHOUT_INVALID(DATA_SERIALIZER_RESULT, DATA_SERIALIZER_RESULT_VALUES);
+
+#define DATA_SERIALIZER_MULTITREE_TYPE_VALUES   \
+    DATA_SERIALIZER_TYPE_CHAR_PTR,              \
+    DATA_SERIALIZER_TYPE_AGENT_DATA             \
+
+MU_DEFINE_ENUM_WITHOUT_INVALID(DATA_SERIALIZER_MULTITREE_TYPE, DATA_SERIALIZER_MULTITREE_TYPE_VALUES);
+
+typedef BUFFER_HANDLE (*DATA_SERIALIZER_ENCODE_FUNC)(MULTITREE_HANDLE multiTreeHandle, DATA_SERIALIZER_MULTITREE_TYPE dataType);
+typedef MULTITREE_HANDLE (*DATA_SERIALIZER_DECODE_FUNC)(BUFFER_HANDLE decodeData);
+
+extern BUFFER_HANDLE DataSerializer_Encode(MULTITREE_HANDLE multiTreeHandle, DATA_SERIALIZER_MULTITREE_TYPE dataType, DATA_SERIALIZER_ENCODE_FUNC encodeFunc);
+extern MULTITREE_HANDLE DataSerializer_Decode(BUFFER_HANDLE data, DATA_SERIALIZER_DECODE_FUNC decodeFunc);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // DATASERIALIZER_H
Index: azure_iot_hub_f767zi/trunk/azure_iot_sdk/serializer/inc/iotdevice.h
===================================================================
--- azure_iot_hub_f767zi/trunk/azure_iot_sdk/serializer/inc/iotdevice.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/azure_iot_sdk/serializer/inc/iotdevice.h	(revision 457)
@@ -0,0 +1,58 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+#ifndef IOTDEVICE_H
+#define IOTDEVICE_H
+
+#include <stdbool.h>
+#include "azure_macro_utils/macro_utils.h"
+#include "schema.h"
+#include "datapublisher.h"
+#include "commanddecoder.h"
+#include "methodreturn.h"
+
+#ifdef __cplusplus
+#include <cstddef>
+extern "C" {
+#else
+#include <stddef.h>
+#endif
+
+#define DEVICE_RESULT_VALUES            \
+    DEVICE_OK,                            \
+    DEVICE_INVALID_ARG,                    \
+    DEVICE_DATA_PUBLISHER_FAILED,        \
+    DEVICE_COMMAND_DECODER_FAILED,        \
+    DEVICE_ERROR
+
+MU_DEFINE_ENUM_WITHOUT_INVALID(DEVICE_RESULT, DEVICE_RESULT_VALUES)
+
+#include "umock_c/umock_c_prod.h"
+
+typedef struct DEVICE_HANDLE_DATA_TAG* DEVICE_HANDLE;
+typedef EXECUTE_COMMAND_RESULT (*pfDeviceActionCallback)(DEVICE_HANDLE deviceHandle, void* callbackUserContext, const char* relativeActionPath, const char* actionName, size_t argCount, const AGENT_DATA_TYPE* args);
+typedef METHODRETURN_HANDLE    (*pfDeviceMethodCallback)(DEVICE_HANDLE deviceHandle, void* callbackUserContext, const char* relativeMethodPath, const char* methodName, size_t argCount, const AGENT_DATA_TYPE* args);
+
+MOCKABLE_FUNCTION(,DEVICE_RESULT, Device_Create, SCHEMA_MODEL_TYPE_HANDLE, modelHandle, pfDeviceActionCallback, deviceActionCallback, void*, callbackUserContext, pfDeviceMethodCallback, methodCallback, void*, methodCallbackContext, bool, includePropertyPath, DEVICE_HANDLE*, deviceHandle);
+MOCKABLE_FUNCTION(, void, Device_Destroy, DEVICE_HANDLE, deviceHandle);
+
+MOCKABLE_FUNCTION(,TRANSACTION_HANDLE, Device_StartTransaction, DEVICE_HANDLE, deviceHandle);
+MOCKABLE_FUNCTION(,DEVICE_RESULT, Device_PublishTransacted, TRANSACTION_HANDLE, transactionHandle, const char*, propertyPath, const AGENT_DATA_TYPE*, data);
+MOCKABLE_FUNCTION(,DEVICE_RESULT, Device_EndTransaction, TRANSACTION_HANDLE, transactionHandle, unsigned char**, destination, size_t*, destinationSize);
+MOCKABLE_FUNCTION(,DEVICE_RESULT, Device_CancelTransaction, TRANSACTION_HANDLE, transactionHandle);
+
+MOCKABLE_FUNCTION(, REPORTED_PROPERTIES_TRANSACTION_HANDLE, Device_CreateTransaction_ReportedProperties, DEVICE_HANDLE, deviceHandle);
+MOCKABLE_FUNCTION(, DEVICE_RESULT, Device_PublishTransacted_ReportedProperty, REPORTED_PROPERTIES_TRANSACTION_HANDLE, transactionHandle, const char*, reportedPropertyPath, const AGENT_DATA_TYPE*, data);
+MOCKABLE_FUNCTION(, DEVICE_RESULT, Device_CommitTransaction_ReportedProperties, REPORTED_PROPERTIES_TRANSACTION_HANDLE, transactionHandle, unsigned char**, destination, size_t*, destinationSize);
+MOCKABLE_FUNCTION(, void, Device_DestroyTransaction_ReportedProperties, REPORTED_PROPERTIES_TRANSACTION_HANDLE, transactionHandle);
+
+MOCKABLE_FUNCTION(, EXECUTE_COMMAND_RESULT, Device_ExecuteCommand, DEVICE_HANDLE, deviceHandle, const char*, command);
+MOCKABLE_FUNCTION(, METHODRETURN_HANDLE, Device_ExecuteMethod, DEVICE_HANDLE, deviceHandle, const char*, methodName, const char*, methodPayload);
+
+MOCKABLE_FUNCTION(, DEVICE_RESULT, Device_IngestDesiredProperties, void*, startAddress, DEVICE_HANDLE, deviceHandle, const char*, jsonPayload, bool, parseDesiredNode);
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* IOTDEVICE_H */
+
Index: azure_iot_hub_f767zi/trunk/azure_iot_sdk/serializer/inc/jsondecoder.h
===================================================================
--- azure_iot_hub_f767zi/trunk/azure_iot_sdk/serializer/inc/jsondecoder.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/azure_iot_sdk/serializer/inc/jsondecoder.h	(revision 457)
@@ -0,0 +1,33 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+#ifndef JSONDECODER_H
+#define JSONDECODER_H
+
+#include "multitree.h"
+
+#ifdef __cplusplus
+#include <cstddef>
+extern "C" {
+#else
+#include <stddef.h>
+#endif
+
+#include "umock_c/umock_c_prod.h"
+
+#define JSON_DECODER_RESULT_VALUES      \
+    JSON_DECODER_OK,                    \
+    JSON_DECODER_INVALID_ARG,           \
+    JSON_DECODER_PARSE_ERROR,           \
+    JSON_DECODER_MULTITREE_FAILED,      \
+    JSON_DECODER_ERROR                  \
+
+MU_DEFINE_ENUM_WITHOUT_INVALID(JSON_DECODER_RESULT, JSON_DECODER_RESULT_VALUES);
+
+MOCKABLE_FUNCTION(, JSON_DECODER_RESULT, JSONDecoder_JSON_To_MultiTree, char*, json, MULTITREE_HANDLE*, multiTreeHandle);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* JSONDECODER_H */
Index: azure_iot_hub_f767zi/trunk/azure_iot_sdk/serializer/inc/jsonencoder.h
===================================================================
--- azure_iot_hub_f767zi/trunk/azure_iot_sdk/serializer/inc/jsonencoder.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/azure_iot_sdk/serializer/inc/jsonencoder.h	(revision 457)
@@ -0,0 +1,48 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+#ifndef JSONENCODER_H
+#define JSONENCODER_H
+
+#include "azure_macro_utils/macro_utils.h"
+#include "azure_c_shared_utility/strings.h"
+
+#ifdef __cplusplus
+#include "cstddef"
+extern "C" {
+#else
+#include "stddef.h"
+#endif
+
+#include "multitree.h"
+
+#define JSON_ENCODER_RESULT_VALUES           \
+JSON_ENCODER_OK,                             \
+JSON_ENCODER_INVALID_ARG,                    \
+JSON_ENCODER_ALREADY_EXISTS,                 \
+JSON_ENCODER_MULTITREE_ERROR,                \
+JSON_ENCODER_TOSTRING_FUNCTION_ERROR,        \
+JSON_ENCODER_ERROR
+
+MU_DEFINE_ENUM_WITHOUT_INVALID(JSON_ENCODER_RESULT, JSON_ENCODER_RESULT_VALUES);
+
+#define JSON_ENCODER_TOSTRING_RESULT_VALUES  \
+JSON_ENCODER_TOSTRING_OK,                    \
+JSON_ENCODER_TOSTRING_INVALID_ARG,           \
+JSON_ENCODER_TOSTRING_ERROR
+
+MU_DEFINE_ENUM_WITHOUT_INVALID(JSON_ENCODER_TOSTRING_RESULT, JSON_ENCODER_TOSTRING_RESULT_VALUES);
+
+typedef JSON_ENCODER_TOSTRING_RESULT(*JSON_ENCODER_TOSTRING_FUNC)(STRING_HANDLE, const void* value);
+
+#include "umock_c/umock_c_prod.h"
+
+MOCKABLE_FUNCTION(, JSON_ENCODER_TOSTRING_RESULT, JSONEncoder_CharPtr_ToString, STRING_HANDLE, destination, const void*, value);
+MOCKABLE_FUNCTION(, JSON_ENCODER_RESULT, JSONEncoder_EncodeTree, MULTITREE_HANDLE, treeHandle, STRING_HANDLE, destination, JSON_ENCODER_TOSTRING_FUNC, toStringFunc);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif /* JSONENCODER_H */
Index: azure_iot_hub_f767zi/trunk/azure_iot_sdk/serializer/inc/methodreturn.h
===================================================================
--- azure_iot_hub_f767zi/trunk/azure_iot_sdk/serializer/inc/methodreturn.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/azure_iot_sdk/serializer/inc/methodreturn.h	(revision 457)
@@ -0,0 +1,34 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+#ifndef METHODRETURN_H
+#define METHODRETURN_H
+
+typedef struct METHODRETURN_HANDLE_DATA_TAG* METHODRETURN_HANDLE;
+
+#include "azure_macro_utils/macro_utils.h"
+
+typedef struct METHODRETURN_DATA_TAG
+{
+    int statusCode;
+    char* jsonValue;
+}METHODRETURN_DATA;
+
+#include "umock_c/umock_c_prod.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+MOCKABLE_FUNCTION(, METHODRETURN_HANDLE, MethodReturn_Create, int, statusCode, const char*, jsonValue);
+MOCKABLE_FUNCTION(, void, MethodReturn_Destroy, METHODRETURN_HANDLE, handle);
+MOCKABLE_FUNCTION(, const METHODRETURN_DATA*, MethodReturn_GetReturn, METHODRETURN_HANDLE, handle);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif /*METHODRETURN_H*/
+
Index: azure_iot_hub_f767zi/trunk/azure_iot_sdk/serializer/inc/multitree.h
===================================================================
--- azure_iot_hub_f767zi/trunk/azure_iot_sdk/serializer/inc/multitree.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/azure_iot_sdk/serializer/inc/multitree.h	(revision 457)
@@ -0,0 +1,54 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+#ifndef MULTITREE_H
+#define MULTITREE_H
+
+#include "azure_c_shared_utility/strings.h"
+#include "azure_macro_utils/macro_utils.h"
+
+#ifdef __cplusplus
+#include <cstddef>
+extern "C"
+{
+#else
+#include <stddef.h>
+#include <stdbool.h>
+#endif
+
+typedef struct MULTITREE_HANDLE_DATA_TAG* MULTITREE_HANDLE;
+
+#define MULTITREE_RESULT_VALUES           \
+    MULTITREE_OK,                         \
+    MULTITREE_INVALID_ARG,                \
+    MULTITREE_ALREADY_HAS_A_VALUE,        \
+    MULTITREE_EMPTY_CHILD_NAME,           \
+    MULTITREE_EMPTY_VALUE,                \
+    MULTITREE_OUT_OF_RANGE_INDEX,         \
+    MULTITREE_ERROR,                      \
+    MULTITREE_CHILD_NOT_FOUND             \
+
+MU_DEFINE_ENUM_WITHOUT_INVALID(MULTITREE_RESULT, MULTITREE_RESULT_VALUES);
+
+typedef void (*MULTITREE_FREE_FUNCTION)(void* value);
+typedef int (*MULTITREE_CLONE_FUNCTION)(void** destination, const void* source);
+
+#include "umock_c/umock_c_prod.h"
+MOCKABLE_FUNCTION(, MULTITREE_HANDLE, MultiTree_Create, MULTITREE_CLONE_FUNCTION, cloneFunction, MULTITREE_FREE_FUNCTION, freeFunction);
+MOCKABLE_FUNCTION(, MULTITREE_RESULT, MultiTree_AddLeaf, MULTITREE_HANDLE, treeHandle, const char*, destinationPath, const void*, value);
+MOCKABLE_FUNCTION(, MULTITREE_RESULT, MultiTree_AddChild, MULTITREE_HANDLE, treeHandle, const char*, childName, MULTITREE_HANDLE*, childHandle);
+MOCKABLE_FUNCTION(, MULTITREE_RESULT, MultiTree_GetChildCount, MULTITREE_HANDLE, treeHandle, size_t*, count);
+MOCKABLE_FUNCTION(, MULTITREE_RESULT, MultiTree_GetChild, MULTITREE_HANDLE, treeHandle, size_t, index, MULTITREE_HANDLE*, childHandle);
+MOCKABLE_FUNCTION(, MULTITREE_RESULT, MultiTree_GetChildByName, MULTITREE_HANDLE, treeHandle, const char*, childName, MULTITREE_HANDLE*, childHandle);
+MOCKABLE_FUNCTION(, MULTITREE_RESULT, MultiTree_GetName, MULTITREE_HANDLE, treeHandle, STRING_HANDLE, destination);
+MOCKABLE_FUNCTION(, MULTITREE_RESULT, MultiTree_GetValue, MULTITREE_HANDLE, treeHandle, const void**, destination);
+MOCKABLE_FUNCTION(, MULTITREE_RESULT, MultiTree_GetLeafValue, MULTITREE_HANDLE, treeHandle, const char*, leafPath, const void**, destination);
+MOCKABLE_FUNCTION(, MULTITREE_RESULT, MultiTree_SetValue, MULTITREE_HANDLE, treeHandle, void*, value);
+MOCKABLE_FUNCTION(, void, MultiTree_Destroy, MULTITREE_HANDLE, treeHandle);
+MOCKABLE_FUNCTION(, MULTITREE_RESULT, MultiTree_DeleteChild, MULTITREE_HANDLE, treeHandle, const char*, childName);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
Index: azure_iot_hub_f767zi/trunk/azure_iot_sdk/serializer/inc/schema.h
===================================================================
--- azure_iot_hub_f767zi/trunk/azure_iot_sdk/serializer/inc/schema.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/azure_iot_sdk/serializer/inc/schema.h	(revision 457)
@@ -0,0 +1,178 @@
+// Copyright (c) Microsoft. All rights reserved.MOCKABLE_FUNCTION(,
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+#ifndef SCHEMA_H
+#define SCHEMA_H
+
+#include "azure_macro_utils/macro_utils.h"
+#include "azure_c_shared_utility/crt_abstractions.h"
+#include "agenttypesystem.h"
+
+#include "umock_c/umock_c_prod.h"
+
+#ifdef __cplusplus
+#include <cstddef>
+extern "C" {
+#else
+#include <stddef.h>
+#endif
+
+/* Codes_SRS_SCHEMA_99_095: [Schema shall expose the following API:] */
+
+typedef struct SCHEMA_HANDLE_DATA_TAG* SCHEMA_HANDLE;
+typedef struct SCHEMA_MODEL_TYPE_HANDLE_DATA_TAG* SCHEMA_MODEL_TYPE_HANDLE;
+typedef struct SCHEMA_STRUCT_TYPE_HANDLE_DATA_TAG* SCHEMA_STRUCT_TYPE_HANDLE;
+typedef struct SCHEMA_PROPERTY_HANDLE_DATA_TAG* SCHEMA_PROPERTY_HANDLE;
+typedef struct SCHEMA_REPORTED_PROPERTY_HANDLE_DATA_TAG* SCHEMA_REPORTED_PROPERTY_HANDLE;
+typedef struct SCHEMA_DESIRED_PROPERTY_HANDLE_DATA_TAG* SCHEMA_DESIRED_PROPERTY_HANDLE;
+typedef struct SCHEMA_ACTION_HANDLE_DATA_TAG* SCHEMA_ACTION_HANDLE;
+typedef struct SCHEMA_ACTION_ARGUMENT_HANDLE_DATA_TAG* SCHEMA_ACTION_ARGUMENT_HANDLE;
+typedef struct SCHEMA_METHOD_ARGUMENT_HANDLE_DATA_TAG* SCHEMA_METHOD_ARGUMENT_HANDLE;
+typedef struct SCHEMA_METHOD_HANDLE_DATA_TAG* SCHEMA_METHOD_HANDLE;
+
+
+typedef void(*pfOnDesiredProperty)(void* model);
+typedef int(*pfDesiredPropertyFromAGENT_DATA_TYPE)(const AGENT_DATA_TYPE* source, void* dest);
+typedef void(*pfDesiredPropertyInitialize)(void* destination);
+typedef void(*pfDesiredPropertyDeinitialize)(void* destination);
+
+
+#define SCHEMA_RESULT_VALUES    \
+SCHEMA_OK,                      \
+SCHEMA_INVALID_ARG,             \
+SCHEMA_DUPLICATE_ELEMENT,       \
+SCHEMA_ELEMENT_NOT_FOUND,       \
+SCHEMA_MODEL_IN_USE,            \
+SCHEMA_DEVICE_COUNT_ZERO,       \
+SCHEMA_ERROR
+
+MU_DEFINE_ENUM_WITHOUT_INVALID(SCHEMA_RESULT, SCHEMA_RESULT_VALUES)
+
+#define SCHEMA_ELEMENT_TYPE_VALUES \
+SCHEMA_NOT_FOUND, \
+SCHEMA_SEARCH_INVALID_ARG, \
+SCHEMA_PROPERTY, \
+SCHEMA_REPORTED_PROPERTY, \
+SCHEMA_DESIRED_PROPERTY, \
+SCHEMA_MODEL_ACTION, \
+SCHEMA_MODEL_IN_MODEL
+
+MU_DEFINE_ENUM_WITHOUT_INVALID(SCHEMA_ELEMENT_TYPE, SCHEMA_ELEMENT_TYPE_VALUES);
+
+typedef struct SCHEMA_MODEL_ELEMENT_TAG
+{
+    SCHEMA_ELEMENT_TYPE elementType;
+    union ELEMENT_HANDLE_UNION_TAG
+    {
+        SCHEMA_DESIRED_PROPERTY_HANDLE desiredPropertyHandle;
+        SCHEMA_PROPERTY_HANDLE propertyHandle;
+        SCHEMA_REPORTED_PROPERTY_HANDLE reportedPropertyHandle;
+        SCHEMA_ACTION_HANDLE actionHandle;
+        SCHEMA_MODEL_TYPE_HANDLE modelHandle;
+    } elementHandle;
+}SCHEMA_MODEL_ELEMENT;
+
+MOCKABLE_FUNCTION(, SCHEMA_HANDLE, Schema_Create, const char*, schemaNamespace, void*, metadata);
+MOCKABLE_FUNCTION(, void*, Schema_GetMetadata, SCHEMA_HANDLE, schemaHandle);
+MOCKABLE_FUNCTION(, size_t, Schema_GetSchemaCount);
+MOCKABLE_FUNCTION(, SCHEMA_HANDLE, Schema_GetSchemaByNamespace, const char*, schemaNamespace);
+MOCKABLE_FUNCTION(, SCHEMA_HANDLE, Schema_GetSchemaForModel, const char*, modelName);
+MOCKABLE_FUNCTION(, const char*, Schema_GetSchemaNamespace, SCHEMA_HANDLE, schemaHandle);
+MOCKABLE_FUNCTION(, SCHEMA_RESULT, Schema_AddDeviceRef, SCHEMA_MODEL_TYPE_HANDLE, modelTypeHandle);
+MOCKABLE_FUNCTION(, SCHEMA_RESULT, Schema_ReleaseDeviceRef, SCHEMA_MODEL_TYPE_HANDLE, modelTypeHandle);
+
+MOCKABLE_FUNCTION(, SCHEMA_MODEL_TYPE_HANDLE, Schema_CreateModelType, SCHEMA_HANDLE, schemaHandle, const char*, modelName);
+MOCKABLE_FUNCTION(, SCHEMA_HANDLE, Schema_GetSchemaForModelType, SCHEMA_MODEL_TYPE_HANDLE, modelTypeHandle);
+MOCKABLE_FUNCTION(, const char*, Schema_GetModelName, SCHEMA_MODEL_TYPE_HANDLE, modelTypeHandle);
+
+MOCKABLE_FUNCTION(, SCHEMA_STRUCT_TYPE_HANDLE, Schema_CreateStructType, SCHEMA_HANDLE, schemaHandle, const char*, structTypeName);
+
+MOCKABLE_FUNCTION(, const char*, Schema_GetStructTypeName, SCHEMA_STRUCT_TYPE_HANDLE, structTypeHandle);
+
+MOCKABLE_FUNCTION(, SCHEMA_RESULT, Schema_AddStructTypeProperty, SCHEMA_STRUCT_TYPE_HANDLE, structTypeHandle, const char*, propertyName, const char*, propertyType);
+
+MOCKABLE_FUNCTION(, SCHEMA_RESULT, Schema_AddModelProperty, SCHEMA_MODEL_TYPE_HANDLE, modelTypeHandle, const char*, propertyName, const char*, propertyType);
+MOCKABLE_FUNCTION(, SCHEMA_RESULT, Schema_AddModelReportedProperty, SCHEMA_MODEL_TYPE_HANDLE, modelTypeHandle, const char*, reportedPropertyName, const char*, reportedPropertyType);
+MOCKABLE_FUNCTION(, SCHEMA_RESULT, Schema_AddModelDesiredProperty, SCHEMA_MODEL_TYPE_HANDLE, modelTypeHandle, const char*, desiredPropertyName, const char*, desiredPropertyType, pfDesiredPropertyFromAGENT_DATA_TYPE, desiredPropertyFromAGENT_DATA_TYPE, pfDesiredPropertyInitialize, desiredPropertyInitialize, pfDesiredPropertyDeinitialize, desiredPropertyDeinitialize, size_t, offset, pfOnDesiredProperty, onDesiredProperty);
+MOCKABLE_FUNCTION(, SCHEMA_RESULT, Schema_AddModelModel, SCHEMA_MODEL_TYPE_HANDLE, modelTypeHandle, const char*, propertyName, SCHEMA_MODEL_TYPE_HANDLE, modelType, size_t, offset, pfOnDesiredProperty, onDesiredProperty);
+MOCKABLE_FUNCTION(, SCHEMA_ACTION_HANDLE, Schema_CreateModelAction, SCHEMA_MODEL_TYPE_HANDLE, modelTypeHandle, const char*, actionName);
+MOCKABLE_FUNCTION(, SCHEMA_METHOD_HANDLE, Schema_CreateModelMethod, SCHEMA_MODEL_TYPE_HANDLE, modelTypeHandle, const char*, methodName);
+MOCKABLE_FUNCTION(, SCHEMA_RESULT, Schema_AddModelActionArgument, SCHEMA_ACTION_HANDLE, actionHandle, const char*, argumentName, const char*, argumentType);
+MOCKABLE_FUNCTION(, SCHEMA_RESULT, Schema_AddModelMethodArgument, SCHEMA_METHOD_HANDLE, methodHandle, const char*, argumentName, const char*, argumentType);
+MOCKABLE_FUNCTION(, pfDesiredPropertyFromAGENT_DATA_TYPE, Schema_GetModelDesiredProperty_pfDesiredPropertyFromAGENT_DATA_TYPE, SCHEMA_DESIRED_PROPERTY_HANDLE, desiredPropertyHandle);
+MOCKABLE_FUNCTION(, pfOnDesiredProperty, Schema_GetModelDesiredProperty_pfOnDesiredProperty, SCHEMA_DESIRED_PROPERTY_HANDLE, desiredPropertyHandle);
+
+
+MOCKABLE_FUNCTION(, size_t, Schema_GetModelModelByName_Offset, SCHEMA_MODEL_TYPE_HANDLE, modelTypeHandle, const char*, propertyName);
+MOCKABLE_FUNCTION(, pfOnDesiredProperty, Schema_GetModelModelByName_OnDesiredProperty, SCHEMA_MODEL_TYPE_HANDLE, modelTypeHandle, const char*, propertyName);
+
+MOCKABLE_FUNCTION(, size_t, Schema_GetModelModelByIndex_Offset, SCHEMA_MODEL_TYPE_HANDLE, modelTypeHandle, size_t, index);
+
+MOCKABLE_FUNCTION(, size_t, Schema_GetModelDesiredProperty_offset, SCHEMA_DESIRED_PROPERTY_HANDLE, desiredPropertyHandle);
+MOCKABLE_FUNCTION(, const char*, Schema_GetModelDesiredPropertyType, SCHEMA_DESIRED_PROPERTY_HANDLE, desiredPropertyHandle);
+MOCKABLE_FUNCTION(, pfDesiredPropertyDeinitialize, Schema_GetModelDesiredProperty_pfDesiredPropertyDeinitialize, SCHEMA_DESIRED_PROPERTY_HANDLE, desiredPropertyHandle);
+MOCKABLE_FUNCTION(, pfDesiredPropertyInitialize, Schema_GetModelDesiredProperty_pfDesiredPropertyInitialize, SCHEMA_DESIRED_PROPERTY_HANDLE, desiredPropertyHandle);
+
+MOCKABLE_FUNCTION(, SCHEMA_MODEL_ELEMENT, Schema_GetModelElementByName, SCHEMA_MODEL_TYPE_HANDLE, modelTypeHandle, const char*, elementName);
+
+MOCKABLE_FUNCTION(, SCHEMA_RESULT, Schema_GetModelCount, SCHEMA_HANDLE, schemaHandle, size_t*, modelCount);
+MOCKABLE_FUNCTION(, SCHEMA_MODEL_TYPE_HANDLE, Schema_GetModelByName, SCHEMA_HANDLE, schemaHandle, const char*, modelName);
+MOCKABLE_FUNCTION(, SCHEMA_MODEL_TYPE_HANDLE, Schema_GetModelByIndex, SCHEMA_HANDLE, schemaHandle, size_t, index);
+
+MOCKABLE_FUNCTION(, SCHEMA_RESULT, Schema_GetModelPropertyCount, SCHEMA_MODEL_TYPE_HANDLE, modelTypeHandle, size_t*, propertyCount);
+MOCKABLE_FUNCTION(, SCHEMA_PROPERTY_HANDLE, Schema_GetModelPropertyByName, SCHEMA_MODEL_TYPE_HANDLE, modelTypeHandle, const char*, propertyName);
+MOCKABLE_FUNCTION(, SCHEMA_PROPERTY_HANDLE, Schema_GetModelPropertyByIndex, SCHEMA_MODEL_TYPE_HANDLE, modelTypeHandle, size_t, index);
+
+MOCKABLE_FUNCTION(, SCHEMA_RESULT, Schema_GetModelReportedPropertyCount, SCHEMA_MODEL_TYPE_HANDLE, modelTypeHandle, size_t*, reportedPropertyCount);
+MOCKABLE_FUNCTION(, SCHEMA_REPORTED_PROPERTY_HANDLE, Schema_GetModelReportedPropertyByName, SCHEMA_MODEL_TYPE_HANDLE, modelTypeHandle, const char*, reportedPropertyName);
+MOCKABLE_FUNCTION(, SCHEMA_REPORTED_PROPERTY_HANDLE, Schema_GetModelReportedPropertyByIndex, SCHEMA_MODEL_TYPE_HANDLE, modelTypeHandle, size_t, index);
+
+MOCKABLE_FUNCTION(, SCHEMA_RESULT, Schema_GetModelDesiredPropertyCount, SCHEMA_MODEL_TYPE_HANDLE, modelTypeHandle, size_t*, desiredPropertyCount);
+MOCKABLE_FUNCTION(, SCHEMA_DESIRED_PROPERTY_HANDLE, Schema_GetModelDesiredPropertyByName, SCHEMA_MODEL_TYPE_HANDLE, modelTypeHandle, const char*, desiredPropertyName);
+MOCKABLE_FUNCTION(, SCHEMA_DESIRED_PROPERTY_HANDLE, Schema_GetModelDesiredPropertyByIndex, SCHEMA_MODEL_TYPE_HANDLE, modelTypeHandle, size_t, index);
+
+MOCKABLE_FUNCTION(, SCHEMA_RESULT, Schema_GetModelModelCount, SCHEMA_MODEL_TYPE_HANDLE, modelTypeHandle, size_t*, modelCount);
+MOCKABLE_FUNCTION(, SCHEMA_MODEL_TYPE_HANDLE, Schema_GetModelModelByName, SCHEMA_MODEL_TYPE_HANDLE, modelTypeHandle, const char*, propertyName);
+MOCKABLE_FUNCTION(, SCHEMA_MODEL_TYPE_HANDLE, Schema_GetModelModelyByIndex, SCHEMA_MODEL_TYPE_HANDLE, modelTypeHandle, size_t, index);
+MOCKABLE_FUNCTION(, const char*, Schema_GetModelModelPropertyNameByIndex, SCHEMA_MODEL_TYPE_HANDLE, modelTypeHandle, size_t, index);
+
+MOCKABLE_FUNCTION(, bool, Schema_ModelPropertyByPathExists, SCHEMA_MODEL_TYPE_HANDLE, modelTypeHandle, const char*, propertyPath);
+
+MOCKABLE_FUNCTION(, bool, Schema_ModelReportedPropertyByPathExists, SCHEMA_MODEL_TYPE_HANDLE, modelTypeHandle, const char*, reportedPropertyPath);
+MOCKABLE_FUNCTION(, bool, Schema_ModelDesiredPropertyByPathExists, SCHEMA_MODEL_TYPE_HANDLE, modelTypeHandle, const char*, desiredPropertyPath);
+
+MOCKABLE_FUNCTION(, SCHEMA_RESULT, Schema_GetModelActionCount, SCHEMA_MODEL_TYPE_HANDLE, modelTypeHandle, size_t*, actionCount);
+MOCKABLE_FUNCTION(, SCHEMA_ACTION_HANDLE, Schema_GetModelActionByName, SCHEMA_MODEL_TYPE_HANDLE, modelTypeHandle, const char*, actionName);
+MOCKABLE_FUNCTION(, SCHEMA_METHOD_HANDLE, Schema_GetModelMethodByName, SCHEMA_MODEL_TYPE_HANDLE, modelTypeHandle, const char*, methodName);
+MOCKABLE_FUNCTION(, SCHEMA_ACTION_HANDLE, Schema_GetModelActionByIndex, SCHEMA_MODEL_TYPE_HANDLE, modelTypeHandle, size_t, index);
+
+MOCKABLE_FUNCTION(, SCHEMA_RESULT, Schema_GetModelActionArgumentCount, SCHEMA_ACTION_HANDLE, actionHandle, size_t*, argumentCount);
+MOCKABLE_FUNCTION(, SCHEMA_RESULT, Schema_GetModelMethodArgumentCount, SCHEMA_METHOD_HANDLE, methodHandle, size_t*, argumentCount);
+MOCKABLE_FUNCTION(, const char*, Schema_GetModelActionName, SCHEMA_ACTION_HANDLE, actionHandle);
+
+MOCKABLE_FUNCTION(, SCHEMA_ACTION_ARGUMENT_HANDLE, Schema_GetModelActionArgumentByName, SCHEMA_ACTION_HANDLE, actionHandle, const char*, actionArgumentName);
+MOCKABLE_FUNCTION(, SCHEMA_ACTION_ARGUMENT_HANDLE, Schema_GetModelActionArgumentByIndex, SCHEMA_ACTION_HANDLE, actionHandle, size_t, argumentIndex);
+MOCKABLE_FUNCTION(, SCHEMA_METHOD_ARGUMENT_HANDLE, Schema_GetModelMethodArgumentByIndex, SCHEMA_METHOD_HANDLE, actionHandle, size_t, argumentIndex);
+MOCKABLE_FUNCTION(, const char*, Schema_GetActionArgumentName, SCHEMA_ACTION_ARGUMENT_HANDLE, actionArgumentHandle);
+MOCKABLE_FUNCTION(, const char*, Schema_GetMethodArgumentName, SCHEMA_METHOD_ARGUMENT_HANDLE, methodArgumentHandle);
+MOCKABLE_FUNCTION(, const char*, Schema_GetActionArgumentType, SCHEMA_ACTION_ARGUMENT_HANDLE, actionArgumentHandle);
+MOCKABLE_FUNCTION(, const char*, Schema_GetMethodArgumentType, SCHEMA_METHOD_ARGUMENT_HANDLE, methodArgumentHandle);
+
+MOCKABLE_FUNCTION(, SCHEMA_RESULT, Schema_GetStructTypeCount, SCHEMA_HANDLE, schemaHandle, size_t*, structTypeCount);
+MOCKABLE_FUNCTION(, SCHEMA_STRUCT_TYPE_HANDLE, Schema_GetStructTypeByName, SCHEMA_HANDLE, schemaHandle, const char*, structTypeName);
+MOCKABLE_FUNCTION(, SCHEMA_STRUCT_TYPE_HANDLE, Schema_GetStructTypeByIndex, SCHEMA_HANDLE, schemaHandle, size_t, index);
+
+MOCKABLE_FUNCTION(, SCHEMA_RESULT, Schema_GetStructTypePropertyCount, SCHEMA_STRUCT_TYPE_HANDLE, structTypeHandle, size_t*, propertyCount);
+MOCKABLE_FUNCTION(, SCHEMA_PROPERTY_HANDLE, Schema_GetStructTypePropertyByName, SCHEMA_STRUCT_TYPE_HANDLE, structTypeHandle, const char*, propertyName);
+MOCKABLE_FUNCTION(, SCHEMA_PROPERTY_HANDLE, Schema_GetStructTypePropertyByIndex, SCHEMA_STRUCT_TYPE_HANDLE, structTypeHandle, size_t, index);
+MOCKABLE_FUNCTION(, const char*, Schema_GetPropertyName, SCHEMA_PROPERTY_HANDLE, propertyHandle);
+MOCKABLE_FUNCTION(, const char*, Schema_GetPropertyType, SCHEMA_PROPERTY_HANDLE, propertyHandle);
+
+MOCKABLE_FUNCTION(, void, Schema_Destroy, SCHEMA_HANDLE, schemaHandle);
+MOCKABLE_FUNCTION(, SCHEMA_RESULT, Schema_DestroyIfUnused,SCHEMA_MODEL_TYPE_HANDLE, modelHandle);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* SCHEMA_H */
Index: azure_iot_hub_f767zi/trunk/azure_iot_sdk/serializer/inc/schemalib.h
===================================================================
--- azure_iot_hub_f767zi/trunk/azure_iot_sdk/serializer/inc/schemalib.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/azure_iot_sdk/serializer/inc/schemalib.h	(revision 457)
@@ -0,0 +1,84 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+/** @file   schemalib.h
+ *    @brief    The IoT Hub Serializer APIs allows developers to define models for
+*            their devices
+ */
+
+#ifndef SCHEMALIB_H
+#define SCHEMALIB_H
+
+#include "azure_macro_utils/macro_utils.h"
+#include "azure_c_shared_utility/strings.h"
+#include "iotdevice.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Codes_SRS_SCHEMALIB__99_001:[ IoTHubSchema_Client shall expose the following API: ... ] */
+#define SERIALIZER_RESULT_VALUES                   \
+    SERIALIZER_OK,                                 \
+    SERIALIZER_INVALID_ARG,                        \
+    SERIALIZER_CODEFIRST_INIT_FAILED,              \
+    SERIALIZER_SCHEMA_FAILED,                      \
+    SERIALIZER_HTTP_API_INIT_FAILED,               \
+    SERIALIZER_ALREADY_INIT,                       \
+    SERIALIZER_ERROR,                              \
+    SERIALIZER_NOT_INITIALIZED,                    \
+    SERIALIZER_ALREADY_STARTED,                    \
+    SERIALIZER_DEVICE_CREATE_FAILED,               \
+    SERIALIZER_GET_MODEL_HANDLE_FAILED,            \
+    SERIALIZER_SERVICEBUS_FAILED
+
+/** @brief Enumeration specifying the status of calls to various APIs in this
+ * module.
+ */
+MU_DEFINE_ENUM_WITHOUT_INVALID(SERIALIZER_RESULT, SERIALIZER_RESULT_VALUES);
+
+#define SERIALIZER_CONFIG_VALUES  \
+    CommandPollingInterval,     \
+    SerializeDelayedBufferMaxSize
+
+/** @brief Enumeration specifying the option to set on the serializer when
+ * calling ::serializer_setconfig.
+ */
+MU_DEFINE_ENUM_WITHOUT_INVALID(SERIALIZER_CONFIG, SERIALIZER_CONFIG_VALUES);
+
+/**
+ * @brief   Initializes the library.
+ *
+ * @param   overrideSchemaNamespace An override schema namespace to use for all
+ *                                  models. Optional, can be @c NULL.
+ *
+ *          If @p schemaNamespace is not @c NULL, its value shall be used
+ *          instead of the namespace defined for each model by using the
+ *          @c DECLARE_XXX macro.
+ *
+ * @return  @c SERIALIZER_OK on success and any other error on failure.
+ */
+extern SERIALIZER_RESULT serializer_init(const char* overrideSchemaNamespace);
+
+/** @brief  Shuts down the IOT library.
+ *
+ *          The library will track all created devices and upon a call to
+ *          ::serializer_deinit it will de-initialize all devices.
+ */
+extern void serializer_deinit(void);
+
+/**
+ * @brief   Set serializer options.
+ *
+ * @param   which   The option to be set.
+ * @param   value   The value to set for the given option.
+ *
+ * @return  @c SERIALIZER_OK on success and any other error on failure.
+ */
+extern SERIALIZER_RESULT serializer_setconfig(SERIALIZER_CONFIG which, void* value);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* SCHEMALIB_H */
Index: azure_iot_hub_f767zi/trunk/azure_iot_sdk/serializer/inc/schemaserializer.h
===================================================================
--- azure_iot_hub_f767zi/trunk/azure_iot_sdk/serializer/inc/schemaserializer.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/azure_iot_sdk/serializer/inc/schemaserializer.h	(revision 457)
@@ -0,0 +1,27 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+#ifndef SCHEMASERIALIZER_H
+#define SCHEMASERIALIZER_H
+
+#include "schema.h"
+#include "azure_c_shared_utility/strings.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define SCHEMA_SERIALIZER_RESULT_VALUES    \
+    SCHEMA_SERIALIZER_OK,            \
+    SCHEMA_SERIALIZER_INVALID_ARG,  \
+    SCHEMA_SERIALIZER_ERROR
+
+MU_DEFINE_ENUM_WITHOUT_INVALID(SCHEMA_SERIALIZER_RESULT, SCHEMA_SERIALIZER_RESULT_VALUES)
+
+extern SCHEMA_SERIALIZER_RESULT SchemaSerializer_SerializeCommandMetadata(SCHEMA_MODEL_TYPE_HANDLE modelHandle, STRING_HANDLE schemaText);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* SCHEMASERIALIZER_H */
Index: azure_iot_hub_f767zi/trunk/azure_iot_sdk/serializer/inc/serializer.h
===================================================================
--- azure_iot_hub_f767zi/trunk/azure_iot_sdk/serializer/inc/serializer.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/azure_iot_sdk/serializer/inc/serializer.h	(revision 457)
@@ -0,0 +1,1520 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+/** @file   serializer.h
+*    @brief    The IoT Hub Serializer APIs allows developers to define models for
+*            their devices
+*
+*    @details    The IoT Hub Serializer APIs allows developers to quickly and easily define
+*                models for their devices directly as code, while supporting the required
+*                features for modeling devices (including multiple models and multiple
+*                devices within the same application). For example:
+*
+*        <pre>
+*       BEGIN_NAMESPACE(Contoso);
+*
+*           DECLARE_STRUCT(SystemProperties,
+*               ascii_char_ptr, DeviceID,
+*               _Bool, Enabled
+*           );
+*
+*           DECLARE_MODEL(VendingMachine,
+*
+*               WITH_DATA(int, SensorValue),
+*
+*               WITH_DATA(ascii_char_ptr, ObjectName),
+*               WITH_DATA(ascii_char_ptr, ObjectType),
+*               WITH_DATA(ascii_char_ptr, Version),
+*               WITH_DATA(SystemProperties, SystemProperties),
+*               WITH_DATA(ascii_char_ptr_no_quotes, Commands),
+*
+*               WITH_ACTION(SetItemPrice, ascii_char_ptr, itemId, ascii_char_ptr, price)
+*           );
+*
+*       END_NAMESPACE(Contoso);
+*       </pre>
+*/
+
+#ifndef SERIALIZER_H
+#define SERIALIZER_H
+
+#ifdef __cplusplus
+#include <cstdlib>
+#include <cstdarg>
+
+#else
+#include <stdlib.h>
+#include <stdarg.h>
+#endif
+
+#include "azure_c_shared_utility/gballoc.h"
+#include "azure_macro_utils/macro_utils.h"
+#include "iotdevice.h"
+#include "azure_c_shared_utility/crt_abstractions.h"
+#include "azure_c_shared_utility/xlogging.h"
+#include "methodreturn.h"
+#include "schemalib.h"
+#include "codefirst.h"
+#include "agenttypesystem.h"
+#include "schema.h"
+
+
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+    /* IOT Agent Macros */
+
+    /**
+     * @def BEGIN_NAMESPACE(schemaNamespace)
+     * This macro marks the start of a section that declares IOT model
+     * elements (like complex types, etc.). Declarations are typically
+     * placed in header files, so that they can be shared between
+     * translation units.
+     */
+     /* Codes_SRS_SERIALIZER_99_001:[For each completed schema declaration block, a unique storage container for schema metadata shall be available in the translation unit at runtime.] */
+#define BEGIN_NAMESPACE(schemaNamespace) \
+    REFLECTED_END_OF_LIST
+
+/**
+* @def END_NAMESPACE(schemaNamespace)
+* This macro marks the end of a section that declares IOT model
+* elements.
+*/
+#define END_NAMESPACE(schemaNamespace) \
+    REFLECTED_LIST_HEAD(schemaNamespace)
+
+#define GLOBAL_INITIALIZE_STRUCT_FIELD(structType, destination, type, name) GlobalInitialize_##type((char*)destination+offsetof(structType, name));
+#define GLOBAL_DEINITIALIZE_STRUCT_FIELD(structType, destination, type, name) GlobalDeinitialize_##type((char*)destination+offsetof(structType, name));
+/**
+* @def DECLARE_STRUCT(name, ...)
+* This macro allows the definition of a struct type that can then be used as
+* part of a model definition.
+*
+* @param name                      Name of the struct
+* @param element1, element2...     Specifies a list of struct members
+*/
+/* Codes_SRS_SERIALIZER_99_080:[ The DECLARE_STRUCT declaration shall insert metadata describing a complex data type.] */
+#define DECLARE_STRUCT(name, ...) \
+    /* Codes_SRS_SERIALIZER_99_096:[ DECLARE_STRUCT shall declare a matching C struct data type named name, which can be referenced from any code that can access the declaration.] */ \
+    typedef struct name##_TAG { \
+        MU_FOR_EACH_2(INSERT_FIELD_INTO_STRUCT, __VA_ARGS__) \
+    } name; \
+    /* Codes_SRS_SERIALIZER_99_081:[ DECLARE_STRUCT's name argument shall uniquely identify the struct within the schema.] */ \
+    REFLECTED_STRUCT(name) \
+    /* Codes_SRS_SERIALIZER_99_082:[ DECLARE_STRUCT's field<n>Name argument shall uniquely name a field within the struct.] */ \
+    MU_FOR_EACH_2_KEEP_1(REFLECTED_FIELD, name, __VA_ARGS__) \
+    TO_AGENT_DATA_TYPE(name, __VA_ARGS__) \
+    /*Codes_SRS_SERIALIZER_99_042:[ The parameter types are either predefined parameter types (specs SRS_SERIALIZER_99_004-SRS_SERIALIZER_99_014) or a type introduced by DECLARE_STRUCT.]*/ \
+    static AGENT_DATA_TYPES_RESULT FromAGENT_DATA_TYPE_##name(const AGENT_DATA_TYPE* source, name* destination) \
+    { \
+        AGENT_DATA_TYPES_RESULT result; \
+        if(source->type != EDM_COMPLEX_TYPE_TYPE) \
+        { \
+            result = AGENT_DATA_TYPES_INVALID_ARG; \
+        } \
+        else if(MU_DIV2(MU_COUNT_ARG(__VA_ARGS__)) != source->value.edmComplexType.nMembers) \
+        { \
+            /*too many or too few fields*/ \
+            result = AGENT_DATA_TYPES_INVALID_ARG; \
+        } \
+        else \
+        { \
+            result = AGENT_DATA_TYPES_OK; \
+            MU_FOR_EACH_2(BUILD_DESTINATION_FIELD, __VA_ARGS__); \
+        } \
+        return result; \
+    } \
+    static void MU_C2(destroyLocalParameter, name)(name * value) \
+    { \
+        MU_FOR_EACH_2_KEEP_1(UNBUILD_DESTINATION_FIELD, value, __VA_ARGS__); \
+    } \
+    static void MU_C2(GlobalInitialize_, name)(void* destination) \
+    { \
+        MU_FOR_EACH_2_KEEP_2(GLOBAL_INITIALIZE_STRUCT_FIELD, name, destination, __VA_ARGS__); \
+    } \
+    static void MU_C2(GlobalDeinitialize_, name)(void* destination) \
+    { \
+        MU_FOR_EACH_2_KEEP_2(GLOBAL_DEINITIALIZE_STRUCT_FIELD, name, destination, __VA_ARGS__); \
+    } \
+
+
+/**
+ * @def     DECLARE_MODEL(name, ...)
+ * This macro allows declaring a model that can be later used to instantiate
+ * a device.
+ *
+ * @param   name                        Specifies the model name
+ * @param   element1, element2...       Specifies a model element which can be
+ *                                         a property or an action.
+ *                                             - A property is described in a
+ *                                               model by using the WITH_DATA
+ *                                             - An action is described in a
+ *                                               model by using the ::WITH_ACTION
+ *                                               macro.
+ *
+ */
+ /* WITH_DATA's name argument shall be one of the following data types: */
+ /* Codes_SRS_SERIALIZER_99_133:[a model type introduced previously by DECLARE_MODEL] */
+
+#define CREATE_DESIRED_PROPERTY_CALLBACK_MODEL_ACTION(...)
+#define CREATE_DESIRED_PROPERTY_CALLBACK_MODEL_METHOD(...)
+#define CREATE_DESIRED_PROPERTY_CALLBACK_MODEL_DESIRED_PROPERTY(type, name, ...) MU_IF(MU_COUNT_ARG(__VA_ARGS__), void __VA_ARGS__ (void*);, )
+#define CREATE_DESIRED_PROPERTY_CALLBACK_MODEL_PROPERTY(...)
+#define CREATE_DESIRED_PROPERTY_CALLBACK_MODEL_REPORTED_PROPERTY(...)
+
+#define CREATE_DESIRED_PROPERTY_CALLBACK(...) CREATE_DESIRED_PROPERTY_CALLBACK_##__VA_ARGS__
+
+#define SERIALIZER_REGISTER_NAMESPACE(NAMESPACE) CodeFirst_RegisterSchema(#NAMESPACE, & ALL_REFLECTED(NAMESPACE))
+
+#define DECLARE_MODEL(name, ...)                                                             \
+    REFLECTED_MODEL(name)                                                                    \
+    MU_FOR_EACH_1(CREATE_DESIRED_PROPERTY_CALLBACK, __VA_ARGS__)                                \
+    typedef struct name { int :1; MU_FOR_EACH_1(BUILD_MODEL_STRUCT, __VA_ARGS__) } name;        \
+    MU_FOR_EACH_1_KEEP_1(CREATE_MODEL_ELEMENT, name, __VA_ARGS__)                               \
+    TO_AGENT_DATA_TYPE(name, DROP_FIRST_COMMA_FROM_ARGS(EXPAND_MODEL_ARGS(__VA_ARGS__)))     \
+    int FromAGENT_DATA_TYPE_##name(const AGENT_DATA_TYPE* source, void* destination)         \
+    {                                                                                        \
+        (void)source;                                                                        \
+        (void)destination;                                                                   \
+        LogError("SHOULD NOT GET CALLED... EVER");                                           \
+        return 0;                                                                            \
+    }                                                                                        \
+    static void MU_C2(GlobalInitialize_, name)(void* destination)                               \
+    {                                                                                        \
+        (void)destination;                                                                   \
+        MU_FOR_EACH_1_KEEP_1(CREATE_MODEL_ELEMENT_GLOBAL_INITIALIZE, name, __VA_ARGS__)         \
+    }                                                                                        \
+    static void MU_C2(GlobalDeinitialize_, name)(void* destination)                             \
+    {                                                                                        \
+        (void)destination;                                                                   \
+        MU_FOR_EACH_1_KEEP_1(CREATE_MODEL_ELEMENT_GLOBAL_DEINITIALIZE, name, __VA_ARGS__)       \
+    }                                                                                        \
+
+
+
+/**
+ * @def   WITH_DATA(type, name)
+ * The ::WITH_DATA macro allows declaring a model property in a model. A
+ * property can be published by using the ::SERIALIZE macro.
+ *
+ * @param   type    Specifies the property type. Can be any of the following
+ *                  types:
+ *                   - int
+ *                   - double
+ *                   - float
+ *                   - long
+ *                   - int8_t
+ *                   - uint8_t
+ *                   - int16_t
+ *                   - int32_t
+ *                   - int64_t
+ *                   - bool
+ *                   - ascii_char_ptr
+ *                   - EDM_DATE_TIME_OFFSET
+ *                   - EDM_GUID
+ *                   - EDM_BINARY
+ *                   - Any struct type previously introduced by another ::DECLARE_STRUCT.
+ *
+ * @param   name    Specifies the property name
+ */
+#define WITH_DATA(type, name) MODEL_PROPERTY(type, name)
+
+
+#define WITH_REPORTED_PROPERTY(type, name) MODEL_REPORTED_PROPERTY(type, name)
+
+#define WITH_DESIRED_PROPERTY(type, name, ...) MODEL_DESIRED_PROPERTY(type, name, __VA_ARGS__)
+
+/**
+ * @def   WITH_ACTION(name, ...)
+ * The ::WITH_ACTION macro allows declaring a model action.
+ *
+ * @param   name                    Specifies the action name.
+ * @param   argXtype, argXName...   Defines the type and name for the X<sup>th</sup>
+ *                                  argument of the action. The type can be any of
+ *                                  the primitive types or a struct type.
+ */
+/*Codes_SRS_SERIALIZER_99_039:[WITH_ACTION shall declare an action of the current data provider called as the first macro parameter(name) and having the first parameter called parameter1Name of type parameter1Type, the second parameter named parameter2Name having the type parameter2Type and so on.]*/
+#define WITH_ACTION(name, ...)  MODEL_ACTION(name, __VA_ARGS__)
+
+
+/**
+* @def   WITH_METHOD(name, ...)
+* The ::WITH_METHOD macro allows declaring a model method.
+*
+* @param   name                    Specifies the method name.
+* @param   argXtype, argXName...   Defines the type and name for the X<sup>th</sup>
+*                                  argument of the method. The type can be any of
+*                                  the primitive types or a struct type.
+*/
+/*Codes_SRS_SERIALIZER_H_02_029: [ WITH_METHOD shall declare a function with the signature 'METHODRETURN_HANDLE name(param1Type param1Name, ...)', which the developer can define to receive corresponding commands from the IoT service. ]*/
+#define WITH_METHOD(name, ...)  MODEL_METHOD(name, __VA_ARGS__)
+
+
+/**
+ * @def   GET_MODEL_HANDLE(schemaNamespace, modelName)
+ * The ::GET_MODEL_HANDLE macro returns a model handle that can be used in
+ * subsequent operations like generating the CSDL schema for the model,
+ * uploading the schema, creating a device, etc.
+ *
+ * @param   schemaNamespace The namespace to which the model belongs.
+ * @param   modelName       The name of the model.
+ */
+/* Codes_SRS_SERIALIZER_99_110:[ The GET_MODEL_HANDLE function macro shall first register the schema by calling CodeFirst_RegisterSchema, passing schemaNamespace and a pointer to the metadata generated in the schema declaration block.] */
+/* Codes_SRS_SERIALIZER_99_094:[ GET_MODEL_HANDLE shall then call Schema_GetModelByName, passing the schemaHandle obtained from CodeFirst_RegisterSchema and modelName arguments, to retrieve the SCHEMA_MODEL_TYPE_HANDLE corresponding to the modelName argument.] */
+/* Codes_SRS_SERIALIZER_99_112:[ GET_MODEL_HANDLE will return the handle for the named model.] */
+#define GET_MODEL_HANDLE(schemaNamespace, modelName) \
+    Schema_GetModelByName(CodeFirst_RegisterSchema(MU_TOSTRING(schemaNamespace), &ALL_REFLECTED(schemaNamespace)), #modelName)
+
+/* Codes_SRS_SERIALIZER_01_002: [If the argument serializerIncludePropertyPath is specified, its value shall be passed to CodeFirst_Create.] */
+#define CREATE_DEVICE_WITH_INCLUDE_PROPERTY_PATH(schemaNamespace, modelName, serializerIncludePropertyPath) \
+    (modelName*)CodeFirst_CreateDevice(GET_MODEL_HANDLE(schemaNamespace, modelName), &ALL_REFLECTED(schemaNamespace), sizeof(modelName), serializerIncludePropertyPath)
+
+/* Codes_SRS_SERIALIZER_01_003: [If the argument serializerIncludePropertyPath is not specified, CREATE_MODEL_INSTANCE shall pass false to CodeFirst_Create.] */
+#define CREATE_DEVICE_WITHOUT_INCLUDE_PROPERTY_PATH(schemaNamespace, modelName) \
+    (modelName*)CodeFirst_CreateDevice(GET_MODEL_HANDLE(schemaNamespace, modelName), &ALL_REFLECTED(schemaNamespace), sizeof(modelName), false)
+
+/* Codes_SRS_SERIALIZER_99_104:[ CREATE_MODEL_INSTANCE shall call GET_MODEL_HANDLE, passing schemaNamespace and modelName, to get a model handle representing the model defined in the corresponding schema declaration block.] */
+/* Codes_SRS_SERIALIZER_99_106:[ CREATE_MODEL_INSTANCE shall call CodeFirst_CreateDevice, passing the model handle (SCHEMA_MODEL_TYPE_HANDLE]*/
+/* Codes_SRS_SERIALIZER_99_107:[ If CodeFirst_CreateDevice fails, CREATE_MODEL_INSTANCE shall return NULL.] */
+/* Codes_SRS_SERIALIZER_99_108:[ If CodeFirst_CreateDevice succeeds, CREATE_MODEL_INSTANCE shall return a pointer to an instance of the C struct representing the model for the device.] */
+#define CREATE_MODEL_INSTANCE(schemaNamespace, ...) \
+    MU_IF(MU_DIV2(MU_COUNT_ARG(__VA_ARGS__)), CREATE_DEVICE_WITH_INCLUDE_PROPERTY_PATH, CREATE_DEVICE_WITHOUT_INCLUDE_PROPERTY_PATH) (schemaNamespace, __VA_ARGS__)
+
+/* Codes_SRS_SERIALIZER_99_109:[ DESTROY_MODEL_INSTANCE shall call CodeFirst_DestroyDevice, passing the pointer returned from CREATE_MODEL_INSTANCE, to release all resources associated with the device.] */
+#define DESTROY_MODEL_INSTANCE(deviceData) \
+    CodeFirst_DestroyDevice(deviceData)
+
+/**
+ * @def      SERIALIZE(destination, destinationSize,...)
+ * This macro produces JSON serialized representation of the properties.
+ *
+ * @param   destination                  Pointer to an @c unsigned @c char* that
+ *                                       will receive the serialized data.
+ * @param   destinationSize              Pointer to a @c size_t that gets
+ *                                       written with the size in bytes of the
+ *                                       serialized data
+ * @param    property1, property2...     A list of property values to send. The
+ *                                       order in which the properties appear in
+ *                                       the list does not matter, all values
+ *                                       will be sent together.
+ *
+ */
+/*Codes_SRS_SERIALIZER_99_113:[ SERIALIZE shall call CodeFirst_SendAsync, passing a destination, destinationSize, the number of properties to publish, and pointers to the values for each property.] */
+/*Codes_SRS_SERIALIZER_99_117:[ If CodeFirst_SendAsync succeeds, SEND will return IOT_AGENT_OK.] */
+/*Codes_SRS_SERIALIZER_99_114:[ If CodeFirst_SendAsync fails, SEND shall return IOT_AGENT_SERIALIZE_FAILED.] */
+#define SERIALIZE(destination, destinationSize,...) CodeFirst_SendAsync(destination, destinationSize, MU_COUNT_ARG(__VA_ARGS__) MU_FOR_EACH_1(ADDRESS_MACRO, __VA_ARGS__))
+
+#define SERIALIZE_REPORTED_PROPERTIES(destination, destinationSize,...) CodeFirst_SendAsyncReported(destination, destinationSize, MU_COUNT_ARG(__VA_ARGS__) MU_FOR_EACH_1(ADDRESS_MACRO, __VA_ARGS__))
+
+
+#define IDENTITY_MACRO(x) ,x
+#define SERIALIZE_REPORTED_PROPERTIES_FROM_POINTERS(destination, destinationSize, ...) CodeFirst_SendAsyncReported(destination, destinationSize, MU_COUNT_ARG(__VA_ARGS__) MU_FOR_EACH_1(IDENTITY_MACRO, __VA_ARGS__))
+
+/**
+ * @def   EXECUTE_COMMAND(device, command)
+ * Any action that is declared in a model must also have an implementation as
+ * a C function.
+ *
+ * @param   device      Pointer to device data.
+ * @param   command     Values that match the arguments declared in the model
+ *                      action.
+ */
+/*Codes_SRS_SERIALIZER_02_018: [EXECUTE_COMMAND macro shall call CodeFirst_ExecuteCommand passing device, commandBuffer and commandBufferSize.]*/
+#define EXECUTE_COMMAND(device, command) (CodeFirst_ExecuteCommand(device, command))
+
+/**
+* @def   EXECUTE_METHOD(device, methodName, methodPayload)
+* Any method that is declared in a model must also have an implementation as
+* a C function.
+*
+* @param   device      Pointer to device data.
+* @param   methodName       The method name.
+* @param   methodPayload    The method payload.
+*/
+#define EXECUTE_METHOD(device, methodName, methodPayload) CodeFirst_ExecuteMethod(device, methodName, methodPayload)
+
+/**
+* @def   INGEST_DESIRED_PROPERTIES(device, desiredProperties)
+*
+* @param   device                return of CodeFirst_CreateDevice.
+* @param   desiredProperties     a null terminated string containing in JSON format the desired properties
+*/
+#define INGEST_DESIRED_PROPERTIES(device, jsonPayload, parseDesiredNode) (CodeFirst_IngestDesiredProperties(device, jsonPayload, parseDesiredNode))
+
+/* Helper macros */
+
+/* These macros remove a useless comma from the beginning of an argument list that looks like:
+,x1,y1,x2,y2 */
+#ifdef _MSC_VER
+
+#define DROP_FIRST_COMMA(N, x) \
+x MU_IFCOMMA_NOFIRST(N)
+
+#define DROP_IF_EMPTY(N, x) \
+MU_IF(MU_COUNT_ARG(x),DROP_FIRST_COMMA(N,x),x)
+
+#define DROP_FIRST_COMMA_FROM_ARGS(...) \
+MU_FOR_EACH_1_COUNTED(DROP_IF_EMPTY, MU_C1(__VA_ARGS__))
+
+#else
+
+#define DROP_FIRST_COMMA_0(N, x) \
+    x MU_IFCOMMA_NOFIRST(N)
+
+#define DROP_FIRST_COMMA_1(N, x) \
+    x
+
+#define DROP_FIRST_COMMA(empty, N, x) \
+    MU_C2(DROP_FIRST_COMMA_,empty)(N,x)
+
+#define DROP_IF_EMPTY(N, x) \
+    DROP_FIRST_COMMA(MU_ISEMPTY(x),N,x)
+
+#define DROP_FIRST_COMMA_FROM_ARGS(...) \
+    MU_FOR_EACH_1_COUNTED(DROP_IF_EMPTY, __VA_ARGS__)
+
+#endif
+
+/* These macros expand a sequence of arguments for DECLARE_MODEL that looks like
+WITH_DATA(x, y), WITH_DATA(x2, y2) to a list of arguments consumed by the macro that marshalls a struct, like:
+x, y, x2, y2
+Actions are discarded, since no marshalling will be done for those when sending state data */
+#define TO_AGENT_DT_EXPAND_MODEL_PROPERTY(x, y) ,x,y
+
+#define TO_AGENT_DT_EXPAND_MODEL_REPORTED_PROPERTY(x, y) ,x,y
+
+#define TO_AGENT_DT_EXPAND_MODEL_DESIRED_PROPERTY(x, y, ...) ,x,y
+
+#define TO_AGENT_DT_EXPAND_MODEL_ACTION(...)
+
+#define TO_AGENT_DT_EXPAND_MODEL_METHOD(...)
+
+#define TO_AGENT_DT_EXPAND_ELEMENT_ARGS(N, ...) TO_AGENT_DT_EXPAND_##__VA_ARGS__
+
+#define EXPAND_MODEL_ARGS(...) \
+    MU_FOR_EACH_1_COUNTED(TO_AGENT_DT_EXPAND_ELEMENT_ARGS, __VA_ARGS__)
+
+#define TO_AGENT_DATA_TYPE(name, ...) \
+    static AGENT_DATA_TYPES_RESULT ToAGENT_DATA_TYPE_##name(AGENT_DATA_TYPE *destination, const name value) \
+    { \
+        AGENT_DATA_TYPES_RESULT result = AGENT_DATA_TYPES_OK; \
+        size_t iMember = 0; \
+        DEFINITION_THAT_CAN_SUSTAIN_A_COMMA_STEAL(phantomName, 1); \
+        const char* memberNames[MU_IF(MU_DIV2(MU_C1(MU_COUNT_ARG(__VA_ARGS__))), MU_DIV2(MU_C1(MU_COUNT_ARG(__VA_ARGS__))), 1)] = { 0 }; \
+        size_t memberCount = sizeof(memberNames) / sizeof(memberNames[0]); \
+        (void)value; \
+        if (memberCount == 0) \
+        { \
+            result = AGENT_DATA_TYPES_OK; \
+        } \
+        else \
+        { \
+            AGENT_DATA_TYPE members[sizeof(memberNames) / sizeof(memberNames[0])]; \
+            DEFINITION_THAT_CAN_SUSTAIN_A_COMMA_STEAL(phantomName, 2); \
+            MU_FOR_EACH_2(FIELD_AS_STRING, MU_EXPAND_TWICE(__VA_ARGS__)) \
+            iMember = 0; \
+            { \
+                DEFINITION_THAT_CAN_SUSTAIN_A_COMMA_STEAL(phantomName, 3); \
+                MU_FOR_EACH_2(CREATE_AGENT_DATA_TYPE, MU_EXPAND_TWICE(__VA_ARGS__)) \
+                {DEFINITION_THAT_CAN_SUSTAIN_A_COMMA_STEAL(phantomName, 4); } \
+                result = ((result == AGENT_DATA_TYPES_OK) && (Create_AGENT_DATA_TYPE_from_Members(destination, #name, sizeof(memberNames) / sizeof(memberNames[0]), memberNames, members) == AGENT_DATA_TYPES_OK)) \
+                            ? AGENT_DATA_TYPES_OK \
+                            : AGENT_DATA_TYPES_ERROR; \
+                { \
+                    size_t jMember; \
+                    for (jMember = 0; jMember < iMember; jMember++) \
+                    { \
+                        Destroy_AGENT_DATA_TYPE(&members[jMember]); \
+                    } \
+                } \
+            } \
+        } \
+        return result; \
+    }
+
+#define FIELD_AS_STRING(x,y) memberNames[iMember++] = #y;
+
+#define REFLECTED_LIST_HEAD(name) \
+    static const REFLECTED_DATA_FROM_DATAPROVIDER ALL_REFLECTED(name) = { &MU_C2(REFLECTED_, MU_C1(MU_DEC(__COUNTER__))) };
+#define REFLECTED_STRUCT(name) \
+    static const REFLECTED_SOMETHING MU_C2(REFLECTED_, MU_C1(MU_INC(__COUNTER__))) = { REFLECTION_STRUCT_TYPE,               &MU_C2(REFLECTED_, MU_C1(MU_DEC(MU_DEC(__COUNTER__)))), { {0}, {0}, {0}, {MU_TOSTRING(name)}, {0}, {0}, {0}, {0}} };
+#define REFLECTED_FIELD(XstructName, XfieldType, XfieldName) \
+    static const REFLECTED_SOMETHING MU_C2(REFLECTED_, MU_C1(MU_INC(__COUNTER__))) = { REFLECTION_FIELD_TYPE,                &MU_C2(REFLECTED_, MU_C1(MU_DEC(MU_DEC(__COUNTER__)))), { {0}, {0}, {0}, {0}, {MU_TOSTRING(XfieldName), MU_TOSTRING(XfieldType), MU_TOSTRING(XstructName)}, {0}, {0}, {0} } };
+#define REFLECTED_MODEL(name) \
+    static const REFLECTED_SOMETHING MU_C2(REFLECTED_, MU_C1(MU_INC(__COUNTER__))) = { REFLECTION_MODEL_TYPE,                &MU_C2(REFLECTED_, MU_C1(MU_DEC(MU_DEC(__COUNTER__)))), { {0}, {0}, {0}, {0}, {0}, {0}, {0}, {MU_TOSTRING(name)} } };
+#define REFLECTED_PROPERTY(type, name, modelName) \
+    static const REFLECTED_SOMETHING MU_C2(REFLECTED_, MU_C1(MU_INC(__COUNTER__))) = { REFLECTION_PROPERTY_TYPE,             &MU_C2(REFLECTED_, MU_C1(MU_DEC(MU_DEC(__COUNTER__)))), { {0}, {0}, {0}, {0}, {0}, {MU_TOSTRING(name), MU_TOSTRING(type), Create_AGENT_DATA_TYPE_From_Ptr_##modelName##name, offsetof(modelName, name), sizeof(type), MU_TOSTRING(modelName)}, {0}, {0} } };
+#define REFLECTED_REPORTED_PROPERTY(type, name, modelName) \
+    static const REFLECTED_SOMETHING MU_C2(REFLECTED_, MU_C1(MU_INC(__COUNTER__))) = { REFLECTION_REPORTED_PROPERTY_TYPE,    &MU_C2(REFLECTED_, MU_C1(MU_DEC(MU_DEC(__COUNTER__)))), { {0}, {0}, {MU_TOSTRING(name), MU_TOSTRING(type), Create_AGENT_DATA_TYPE_From_Ptr_##modelName##name, offsetof(modelName, name), sizeof(type), MU_TOSTRING(modelName)}, {0}, {0}, {0}, {0}, {0} } };
+
+
+#define REFLECTED_DESIRED_PROPERTY_WITH_ON_DESIRED_PROPERTY_CHANGE(type, name, modelName, COUNTER, onDesiredPropertyChange) \
+    static const REFLECTED_SOMETHING MU_C2(REFLECTED_, MU_C1(MU_INC(COUNTER))) =      { REFLECTION_DESIRED_PROPERTY_TYPE,     &MU_C2(REFLECTED_, MU_C1(MU_DEC(COUNTER))),         { {0}, {onDesiredPropertyChange, DesiredPropertyInitialize_##modelName##name, DesiredPropertyDeinitialize_##modelName##name, MU_TOSTRING(name), MU_TOSTRING(type), (int(*)(const AGENT_DATA_TYPE*, void*))FromAGENT_DATA_TYPE_##type, offsetof(modelName, name), sizeof(type), MU_TOSTRING(modelName)}, {0}, {0}, {0}, {0}, {0}, {0}} };
+
+#define REFLECTED_DESIRED_PROPERTY(type, name, modelName, ...)                                                              \
+    MU_IF(MU_COUNT_ARG(__VA_ARGS__),                                                                                              \
+        MACRO_UTILS_DELAY(REFLECTED_DESIRED_PROPERTY_WITH_ON_DESIRED_PROPERTY_CHANGE)(type, name, modelName,__COUNTER__, __VA_ARGS__),  \
+        MACRO_UTILS_DELAY(REFLECTED_DESIRED_PROPERTY_WITH_ON_DESIRED_PROPERTY_CHANGE)(type, name, modelName,MU_DEC(__COUNTER__), NULL)     \
+    )                                                                                                                       \
+
+#define REFLECTED_ACTION(name, argc, argv, fn, modelName) \
+    static const REFLECTED_SOMETHING MU_C2(REFLECTED_, MU_C1(MU_INC(__COUNTER__))) = { REFLECTION_ACTION_TYPE,               &MU_C2(REFLECTED_, MU_C1(MU_DEC(MU_DEC(__COUNTER__)))), { {0}, {0}, {0}, {0}, {0}, {0}, {MU_TOSTRING(name), argc, argv, fn, MU_TOSTRING(modelName)}, {0}} };
+
+#define REFLECTED_METHOD(name, argc, argv, fn, modelName) \
+    static const REFLECTED_SOMETHING MU_C2(REFLECTED_, MU_C1(MU_INC(__COUNTER__))) = { REFLECTION_METHOD_TYPE,               &MU_C2(REFLECTED_, MU_C1(MU_DEC(MU_DEC(__COUNTER__)))), { {MU_TOSTRING(name), argc, argv, fn, MU_TOSTRING(modelName)}, {0}, {0}, {0}, {0}, {0}, {0}, {0}} };
+
+
+#define REFLECTED_END_OF_LIST \
+    static const REFLECTED_SOMETHING MU_C2(REFLECTED_, __COUNTER__) = {          REFLECTION_NOTHING,                   NULL,                                       { {0},{0}, {0}, {0}, {0}, {0}, {0}, {0}} };
+
+#define EXPAND_MODEL_PROPERTY(type, name) MU_EXPAND_ARGS(MODEL_PROPERTY, type, name)
+
+#define EXPAND_MODEL_REPORTED_PROPERTY(type, name) MU_EXPAND_ARGS(MODEL_REPORTED_PROPERTY, type, name)
+
+#define EXPAND_MODEL_DESIRED_PROPERTY(type, name, ...) MU_EXPAND_ARGS(MODEL_DESIRED_PROPERTY, type, name, __VA_ARGS__)
+
+#define EXPAND_MODEL_ACTION(...) MU_EXPAND_ARGS(MODEL_ACTION, __VA_ARGS__)
+
+#define EXPAND_MODEL_METHOD(...) MU_EXPAND_ARGS(MODEL_METHOD, __VA_ARGS__)
+
+#define BUILD_MODEL_STRUCT(elem) INSERT_FIELD_FOR_##elem
+
+#define CREATE_MODEL_ENTITY(modelName, callType, ...) MU_EXPAND_ARGS(CREATE_##callType(modelName, __VA_ARGS__))
+#define CREATE_SOMETHING(modelName, ...) MU_EXPAND_ARGS(CREATE_MODEL_ENTITY(modelName, __VA_ARGS__))
+#define CREATE_ELEMENT(modelName, elem) MU_EXPAND_ARGS(CREATE_SOMETHING(modelName, MU_EXPAND_ARGS(EXPAND_##elem)))
+
+#define CREATE_MODEL_ELEMENT(modelName, elem) MU_EXPAND_ARGS(CREATE_ELEMENT(modelName, elem))
+
+
+#define CREATE_MODEL_ENTITY_GLOBAL_INITIALIZATION(modelName, callType, ...) MU_EXPAND_ARGS(CREATE_GLOBAL_INITIALIZE_##callType(modelName, __VA_ARGS__))
+#define CREATE_SOMETHING_GLOBAL_INITIALIZATION(modelName, ...) MU_EXPAND_ARGS(CREATE_MODEL_ENTITY_GLOBAL_INITIALIZATION(modelName, __VA_ARGS__))
+#define CREATE_ELEMENT_GLOBAL_INITIALIZATION(modelName, elem) MU_EXPAND_ARGS(CREATE_SOMETHING_GLOBAL_INITIALIZATION(modelName, MU_EXPAND_ARGS(EXPAND_##elem)))
+#define CREATE_MODEL_ELEMENT_GLOBAL_INITIALIZE(modelName, elem) MU_EXPAND_ARGS(CREATE_ELEMENT_GLOBAL_INITIALIZATION(modelName, elem))
+
+#define CREATE_MODEL_ENTITY_GLOBAL_DEINITIALIZATION(modelName, callType, ...) MU_EXPAND_ARGS(CREATE_GLOBAL_DEINITIALIZE_##callType(modelName, __VA_ARGS__))
+#define CREATE_SOMETHING_GLOBAL_DEINITIALIZATION(modelName, ...) MU_EXPAND_ARGS(CREATE_MODEL_ENTITY_GLOBAL_DEINITIALIZATION(modelName, __VA_ARGS__))
+#define CREATE_ELEMENT_GLOBAL_DEINITIALIZATION(modelName, elem) MU_EXPAND_ARGS(CREATE_SOMETHING_GLOBAL_DEINITIALIZATION(modelName, MU_EXPAND_ARGS(EXPAND_##elem)))
+#define CREATE_MODEL_ELEMENT_GLOBAL_DEINITIALIZE(modelName, elem) MU_EXPAND_ARGS(CREATE_ELEMENT_GLOBAL_DEINITIALIZATION(modelName, elem))
+
+#define INSERT_FIELD_INTO_STRUCT(x, y) x y;
+
+
+#define INSERT_FIELD_FOR_MODEL_PROPERTY(type, name) INSERT_FIELD_INTO_STRUCT(type, name)
+#define CREATE_GLOBAL_INITIALIZE_MODEL_PROPERTY(modelName, type, name) /*do nothing, this is written by user*/
+#define CREATE_GLOBAL_DEINITIALIZE_MODEL_PROPERTY(modelName, type, name) /*do nothing, this is user's stuff*/
+
+/*REPORTED_PROPERTY is not different than regular WITH_DATA*/
+#define INSERT_FIELD_FOR_MODEL_REPORTED_PROPERTY(type, name) INSERT_FIELD_INTO_STRUCT(type, name)
+#define CREATE_GLOBAL_INITIALIZE_MODEL_REPORTED_PROPERTY(modelName, type,name) GlobalInitialize_##type((char*)destination+offsetof(modelName, name));
+#define CREATE_GLOBAL_DEINITIALIZE_MODEL_REPORTED_PROPERTY(modelName, type,name) GlobalDeinitialize_##type((char*)destination+offsetof(modelName, name));
+
+/*DESIRED_PROPERTY is not different than regular WITH_DATA*/
+#define INSERT_FIELD_FOR_MODEL_DESIRED_PROPERTY(type, name, ...) INSERT_FIELD_INTO_STRUCT(type, name)
+#define CREATE_GLOBAL_INITIALIZE_MODEL_DESIRED_PROPERTY(modelName, type, name, ...) /*do nothing*/
+#define CREATE_GLOBAL_DEINITIALIZE_MODEL_DESIRED_PROPERTY(modelName, type, name, ...) /*do nothing*/
+
+#define INSERT_FIELD_FOR_MODEL_ACTION(name, ...) /* action isn't a part of the model struct */
+#define INSERT_FIELD_FOR_MODEL_METHOD(name, ...) /* method isn't a part of the model struct */
+
+#define CREATE_GLOBAL_INITIALIZE_MODEL_ACTION(...) /*do nothing*/
+#define CREATE_GLOBAL_DEINITIALIZE_MODEL_ACTION(...) /*do nothing*/
+
+#define CREATE_GLOBAL_INITIALIZE_MODEL_METHOD(...) /*do nothing*/
+#define CREATE_GLOBAL_DEINITIALIZE_MODEL_METHOD(...) /*do nothing*/
+
+#define CREATE_MODEL_PROPERTY(modelName, type, name) \
+    IMPL_PROPERTY(type, name, modelName)
+
+#define CREATE_MODEL_REPORTED_PROPERTY(modelName, type, name) \
+    IMPL_REPORTED_PROPERTY(type, name, modelName)
+
+#define CREATE_MODEL_DESIRED_PROPERTY(modelName, type, name, ...) \
+    IMPL_DESIRED_PROPERTY(type, name, modelName, __VA_ARGS__)
+
+#define IMPL_PROPERTY(propertyType, propertyName, modelName) \
+    static int Create_AGENT_DATA_TYPE_From_Ptr_##modelName##propertyName(void* param, AGENT_DATA_TYPE* dest) \
+    { \
+        return MU_C1(ToAGENT_DATA_TYPE_##propertyType)(dest, *(propertyType*)param); \
+    } \
+    REFLECTED_PROPERTY(propertyType, propertyName, modelName)
+
+#define IMPL_REPORTED_PROPERTY(propertyType, propertyName, modelName) \
+    static int Create_AGENT_DATA_TYPE_From_Ptr_##modelName##propertyName(void* param, AGENT_DATA_TYPE* dest) \
+    { \
+        return MU_C1(ToAGENT_DATA_TYPE_##propertyType)(dest, *(propertyType*)param); \
+    } \
+    REFLECTED_REPORTED_PROPERTY(propertyType, propertyName, modelName)
+
+#define IMPL_DESIRED_PROPERTY(propertyType, propertyName, modelName, ...)           \
+    static void DesiredPropertyInitialize_##modelName##propertyName(void* destination)                             \
+    {                                                                                                   \
+        GlobalInitialize_##propertyType(destination);                                                   \
+    }                                                                                                   \
+    static void DesiredPropertyDeinitialize_##modelName##propertyName(void* destination)                           \
+    {                                                                                                   \
+       GlobalDeinitialize_##propertyType(destination);                                                  \
+    }                                                                                                   \
+    REFLECTED_DESIRED_PROPERTY(propertyType, propertyName, modelName, __VA_ARGS__)          \
+
+#define CREATE_MODEL_ACTION(modelName, actionName, ...) \
+    DEFINITION_THAT_CAN_SUSTAIN_A_COMMA_STEAL(modelName##actionName, 1); \
+    EXECUTE_COMMAND_RESULT actionName (modelName* device MU_FOR_EACH_2(DEFINE_FUNCTION_PARAMETER, __VA_ARGS__)); \
+    static EXECUTE_COMMAND_RESULT MU_C2(actionName, WRAPPER)(void* device, size_t ParameterCount, const AGENT_DATA_TYPE* values); \
+    /*for macro purposes, this array always has at least 1 element*/ \
+    /*Codes_SRS_SERIALIZER_99_043:[ It is valid for a method not to have any parameters.]*/ \
+    DEFINITION_THAT_CAN_SUSTAIN_A_COMMA_STEAL(actionName, 1); \
+    static const WRAPPER_ARGUMENT MU_C2(actionName, WRAPPERARGUMENTS)[MU_DIV2(MU_INC(MU_INC(MU_COUNT_ARG(__VA_ARGS__))))] = { MU_FOR_EACH_2_COUNTED(MAKE_WRAPPER_ARGUMENT, __VA_ARGS__) MU_IFCOMMA(MU_INC(MU_INC(MU_COUNT_ARG(__VA_ARGS__)))) {0} }; \
+    REFLECTED_ACTION(actionName, MU_DIV2(MU_COUNT_ARG(__VA_ARGS__)), MU_C2(actionName, WRAPPERARGUMENTS), MU_C2(actionName, WRAPPER), modelName) \
+    /*Codes_SRS_SERIALIZER_99_040:[ In addition to declaring the function, DECLARE_IOT_METHOD shall provide a definition for a wrapper that takes as parameters a size_t parameterCount and const AGENT_DATA_TYPE*.] */ \
+    /*Codes_SRS_SERIALIZER_99_041:[ This wrapper shall convert all the arguments to predefined types and then call the function written by the data provider developer.]*/ \
+    static EXECUTE_COMMAND_RESULT MU_C2(actionName, WRAPPER)(void* device, size_t ParameterCount, const AGENT_DATA_TYPE* values) \
+    { \
+        EXECUTE_COMMAND_RESULT result; \
+        DEFINITION_THAT_CAN_SUSTAIN_A_COMMA_STEAL(actionName, 2); \
+        /*Codes_SRS_SERIALIZER_99_045:[ If the number of passed parameters doesn't match the number of declared parameters, wrapper execution shall fail and return DATA_PROVIDER_INVALID_ARG;]*/ \
+        if(ParameterCount != MU_DIV2(MU_COUNT_ARG(__VA_ARGS__))) \
+        { \
+            result = EXECUTE_COMMAND_ERROR; \
+        } \
+        else \
+        { \
+            /*the below line takes care of initialized but not referenced parameter warning*/ \
+            DEFINITION_THAT_CAN_SUSTAIN_A_COMMA_STEAL(actionName, 3); \
+            MU_IF(MU_DIV2(MU_COUNT_ARG(__VA_ARGS__)), size_t iParameter = 0;, ) \
+            DEFINITION_THAT_CAN_SUSTAIN_A_COMMA_STEAL(actionName, 4); \
+            /*the below line takes care of an unused parameter when values is really never questioned*/ \
+            DEFINITION_THAT_CAN_SUSTAIN_A_COMMA_STEAL(actionName, 5); \
+            MU_FOR_EACH_2(DEFINE_LOCAL_PARAMETER, __VA_ARGS__) \
+            DEFINITION_THAT_CAN_SUSTAIN_A_COMMA_STEAL(actionName, 6); \
+            MU_IF(MU_DIV2(MU_COUNT_ARG(__VA_ARGS__)), , (void)values;) \
+            { \
+               DEFINITION_THAT_CAN_SUSTAIN_A_COMMA_STEAL(actionName, 7); \
+            } \
+            MU_FOR_EACH_2_KEEP_1(START_BUILD_LOCAL_PARAMETER, EXECUTE_COMMAND_ERROR, __VA_ARGS__) \
+            { \
+               DEFINITION_THAT_CAN_SUSTAIN_A_COMMA_STEAL(actionName, 8); \
+            } \
+            result = actionName((modelName*)device MU_FOR_EACH_2(PUSH_LOCAL_PARAMETER, __VA_ARGS__)); \
+            MU_FOR_EACH_2_REVERSE(END_BUILD_LOCAL_PARAMETER, __VA_ARGS__) \
+        } \
+        return result; \
+    }
+
+#define CREATE_MODEL_METHOD(modelName, methodName, ...) \
+    DEFINITION_THAT_CAN_SUSTAIN_A_COMMA_STEAL(modelName##methodName, 1); \
+    METHODRETURN_HANDLE methodName (modelName* device MU_FOR_EACH_2(DEFINE_FUNCTION_PARAMETER, __VA_ARGS__)); \
+    static METHODRETURN_HANDLE MU_C2(methodName, WRAPPER)(void* device, size_t ParameterCount, const AGENT_DATA_TYPE* values); \
+    /*for macro purposes, this array always has at least 1 element*/ \
+    /*Codes_SRS_SERIALIZER_H_02_030: [ It is valid for a method function not to have any parameters. ]*/ \
+    DEFINITION_THAT_CAN_SUSTAIN_A_COMMA_STEAL(methodName, 1); \
+    static const WRAPPER_ARGUMENT MU_C2(methodName, WRAPPERARGUMENTS)[MU_DIV2(MU_INC(MU_INC(MU_COUNT_ARG(__VA_ARGS__))))] = { MU_FOR_EACH_2_COUNTED(MAKE_WRAPPER_ARGUMENT, __VA_ARGS__) MU_IFCOMMA(MU_INC(MU_INC(MU_COUNT_ARG(__VA_ARGS__)))) {0} }; \
+    REFLECTED_METHOD(methodName, MU_DIV2(MU_COUNT_ARG(__VA_ARGS__)), MU_C2(methodName, WRAPPERARGUMENTS), MU_C2(methodName, WRAPPER), modelName) \
+    /*Codes_SRS_SERIALIZER_H_02_034: [ WITH_METHOD shall result in the declaration of a conversion function with the prototype METHODRETURN_HANDLE nameWRAPPER(size_t ParameterCount, const AGENT_DATA_TYPE* values)' ]*/ \
+    /*Codes_SRS_SERIALIZER_H_02_031: [ The function shall convert the input arguments to the types declared in the method parameter list and then call the user-defined method function. ]*/ \
+    static METHODRETURN_HANDLE MU_C2(methodName, WRAPPER)(void* device, size_t ParameterCount, const AGENT_DATA_TYPE* values) \
+    { \
+        METHODRETURN_HANDLE result; \
+        DEFINITION_THAT_CAN_SUSTAIN_A_COMMA_STEAL(methodName, 2); \
+        /*Codes_SRS_SERIALIZER_H_02_032: [ If the number of arguments passed to the conversion function does not match the expected count, the function shall return DATAPROVIDER_INVALID_ARG. ]*/ \
+        if(ParameterCount != MU_DIV2(MU_COUNT_ARG(__VA_ARGS__))) \
+        { \
+            LogError("expected parameter count (%lu) does not match the actual parameter count (%lu)", (unsigned long)ParameterCount, (unsigned long)MU_COUNT_ARG(__VA_ARGS__)); \
+            result = NULL; \
+        } \
+        else \
+        { \
+            /*the below line takes care of initialized but not referenced parameter warning*/ \
+            DEFINITION_THAT_CAN_SUSTAIN_A_COMMA_STEAL(methodName, 3); \
+            MU_IF(MU_DIV2(MU_COUNT_ARG(__VA_ARGS__)), size_t iParameter = 0;, ) \
+            DEFINITION_THAT_CAN_SUSTAIN_A_COMMA_STEAL(methodName, 4); \
+            /*the below line takes care of an unused parameter when values is really never questioned*/ \
+            DEFINITION_THAT_CAN_SUSTAIN_A_COMMA_STEAL(methodName, 5); \
+            MU_FOR_EACH_2(DEFINE_LOCAL_PARAMETER, __VA_ARGS__) \
+            DEFINITION_THAT_CAN_SUSTAIN_A_COMMA_STEAL(methodName, 6); \
+            MU_IF(MU_DIV2(MU_COUNT_ARG(__VA_ARGS__)), , (void)values;) \
+            { \
+               DEFINITION_THAT_CAN_SUSTAIN_A_COMMA_STEAL(actionName, 7); \
+            } \
+            MU_FOR_EACH_2_KEEP_1(START_BUILD_LOCAL_PARAMETER, NULL,__VA_ARGS__) \
+            { \
+               DEFINITION_THAT_CAN_SUSTAIN_A_COMMA_STEAL(actionName, 8); \
+            } \
+            result = methodName((modelName*)device MU_FOR_EACH_2(PUSH_LOCAL_PARAMETER, __VA_ARGS__)); \
+            MU_FOR_EACH_2_REVERSE(END_BUILD_LOCAL_PARAMETER, __VA_ARGS__) \
+        } \
+        return result; \
+    }
+
+#define CREATE_AGENT_DATA_TYPE(type, name) \
+    result = (( result==AGENT_DATA_TYPES_OK) && (ToAGENT_DATA_TYPE_##type( &(members[iMember]), value.name) == AGENT_DATA_TYPES_OK))?AGENT_DATA_TYPES_OK:AGENT_DATA_TYPES_ERROR; \
+    iMember+= ((result==AGENT_DATA_TYPES_OK)?1:0);
+
+#define BUILD_DESTINATION_FIELD(type, name) \
+    if(result == AGENT_DATA_TYPES_OK) \
+    { \
+        size_t i; \
+        bool wasFieldConverted = false; \
+        for (i = 0; i < source->value.edmComplexType.nMembers; i++) \
+        { \
+            /*the name of the field of the complex type must match the name of the field of the structure (parameter name here)*/ \
+            if (strcmp(source->value.edmComplexType.fields[i].fieldName, MU_TOSTRING(name)) == 0) \
+            { /*Codes_SRS_SERIALIZER_99_017:[ These types can either be one of the types mentioned in WITH_DATA or it can be a type introduced by a previous DECLARE_STRUCT.]*/ \
+                wasFieldConverted = (MU_C2(FromAGENT_DATA_TYPE_, type)(source->value.edmComplexType.fields[i].value, &(destination->name)) == AGENT_DATA_TYPES_OK); \
+                break; \
+            } \
+        } \
+        result = (wasFieldConverted == true)? AGENT_DATA_TYPES_OK: AGENT_DATA_TYPES_INVALID_ARG; \
+    } \
+    else \
+    { \
+        /*fallthrough*/ \
+    }
+
+#define UNBUILD_DESTINATION_FIELD(value, type, name) \
+    MU_C2(destroyLocalParameter, type)(&(value->name));
+
+
+#define ADDRESS_MACRO(x) ,&x
+
+#define KEEP_FIRST_(X, ...) X
+#ifdef _MSC_VER
+#define KEEP_FIRST(X) KEEP_FIRST_ LPAREN X)
+#else
+#define KEEP_FIRST(X) KEEP_FIRST_(X)
+#endif
+
+#define PROMOTIONMAP_float double, double
+#define PROMOTIONMAP_int8_t int, int
+#define PROMOTIONMAP_uint8_t int, int
+#define PROMOTIONMAP_int16_t int, int
+#define PROMOTIONMAP__Bool int, int
+#define PROMOTIONMAP_bool int, int
+
+#define CASTMAP_float (float), (float)
+#define CASTMAP_int8_t (int8_t), (int8_t)
+#define CASTMAP_uint8_t (uint8_t), (uint8_t)
+#define CASTMAP_int16_t (int16_t), (int16_t)
+#define CASTMAP__Bool 0!=, 0!=
+#define CASTMAP_bool 0!=, 0!=
+
+#define EMPTY_TOKEN
+
+#define ANOTHERIF(x) MU_C2(ANOTHERIF,x)
+#define ANOTHERIF0(a,b) a
+#define ANOTHERIF1(a,b) b
+#define ANOTHERIF2(a,b) b
+#define ANOTHERIF3(a,b) b
+#define ANOTHERIF4(a,b) b
+#define ANOTHERIF5(a,b) b
+#define ANOTHERIF6(a,b) b
+#define ANOTHERIF7(a,b) b
+#define ANOTHERIF8(a,b) b
+#define ANOTHERIF9(a,b) b
+#define ANOTHERIF10(a,b) b
+#define ANOTHERIF11(a,b) b
+#define ANOTHERIF12(a,b) b
+
+#define MAP_PROMOTED_TYPE(X) ANOTHERIF(MU_DEC(MU_COUNT_ARG(PROMOTIONMAP_##X))) (X, KEEP_FIRST(PROMOTIONMAP_##X))
+#define MAP_CAST_TYPE(X) ANOTHERIF(MU_DEC(MU_COUNT_ARG(CASTMAP_##X)))    (EMPTY_TOKEN, KEEP_FIRST(CASTMAP_##X)  )
+
+#define MU_IFCOMMA(N) MU_C2(MU_IFCOMMA_, N)
+#define MU_IFCOMMA_0
+#define MU_IFCOMMA_2
+#define MU_IFCOMMA_4 ,
+#define MU_IFCOMMA_6 ,
+#define MU_IFCOMMA_8 ,
+#define MU_IFCOMMA_10 ,
+#define MU_IFCOMMA_12 ,
+#define MU_IFCOMMA_14 ,
+#define MU_IFCOMMA_16 ,
+#define MU_IFCOMMA_18 ,
+#define MU_IFCOMMA_20 ,
+#define MU_IFCOMMA_22 ,
+#define MU_IFCOMMA_24 ,
+#define MU_IFCOMMA_26 ,
+#define MU_IFCOMMA_28 ,
+#define MU_IFCOMMA_30 ,
+#define MU_IFCOMMA_32 ,
+#define MU_IFCOMMA_34 ,
+#define MU_IFCOMMA_36 ,
+#define MU_IFCOMMA_38 ,
+#define MU_IFCOMMA_40 ,
+#define MU_IFCOMMA_42 ,
+#define MU_IFCOMMA_44 ,
+#define MU_IFCOMMA_46 ,
+#define MU_IFCOMMA_48 ,
+#define MU_IFCOMMA_50 ,
+#define MU_IFCOMMA_52 ,
+#define MU_IFCOMMA_54 ,
+#define MU_IFCOMMA_56 ,
+#define MU_IFCOMMA_58 ,
+#define MU_IFCOMMA_60 ,
+#define MU_IFCOMMA_62 ,
+#define MU_IFCOMMA_64 ,
+#define MU_IFCOMMA_66 ,
+#define MU_IFCOMMA_68 ,
+#define MU_IFCOMMA_70 ,
+#define MU_IFCOMMA_72 ,
+#define MU_IFCOMMA_74 ,
+#define MU_IFCOMMA_76 ,
+#define MU_IFCOMMA_78 ,
+#define MU_IFCOMMA_80 ,
+#define MU_IFCOMMA_82 ,
+#define MU_IFCOMMA_84 ,
+#define MU_IFCOMMA_86 ,
+#define MU_IFCOMMA_88 ,
+#define MU_IFCOMMA_90 ,
+#define MU_IFCOMMA_92 ,
+#define MU_IFCOMMA_94 ,
+#define MU_IFCOMMA_96 ,
+#define MU_IFCOMMA_98 ,
+#define MU_IFCOMMA_100 ,
+#define MU_IFCOMMA_102 ,
+#define MU_IFCOMMA_104 ,
+#define MU_IFCOMMA_106 ,
+#define MU_IFCOMMA_108 ,
+#define MU_IFCOMMA_110 ,
+#define MU_IFCOMMA_112 ,
+#define MU_IFCOMMA_114 ,
+#define MU_IFCOMMA_116 ,
+#define MU_IFCOMMA_118 ,
+#define MU_IFCOMMA_120 ,
+#define MU_IFCOMMA_122 ,
+#define MU_IFCOMMA_124 ,
+#define MU_IFCOMMA_126 ,
+#define MU_IFCOMMA_128 ,
+
+#define DEFINE_LOCAL_PARAMETER(type, name) type MU_C2(name,_local); GlobalInitialize_##type(& MU_C2(name, _local));
+
+#define START_BUILD_LOCAL_PARAMETER(errorWhenItFails, type, name) \
+    if (MU_C2(FromAGENT_DATA_TYPE_, type)(&values[iParameter], &MU_C2(name, _local)) != AGENT_DATA_TYPES_OK) \
+    { \
+        /*Codes_SRS_SERIALIZER_99_046:[ If the types of the parameters do not match the declared types, DATAPROVIDER_INVALID_ARG shall be returned.]*/ \
+        result = errorWhenItFails; \
+    }\
+    else \
+    { \
+        iParameter++;
+
+#define END_BUILD_LOCAL_PARAMETER(type, name) \
+    (void)MU_C2(destroyLocalParameter, type)(&MU_C2(name, _local)); \
+    }
+
+/*The following constructs have been devised to work around the precompiler bug of Visual Studio 2005, version 14.00.50727.42*/
+/* The bug is explained in https://connect.microsoft.com/VisualStudio/feedback/details/278752/comma-missing-when-using-va-args */
+/*A short description is: preprocessor is mysteriously eating commas ','.
+In order to feed the appetite of the preprocessor, several constructs have
+been devised that can sustain a missing ',' while still compiling and while still doing nothing
+and while hopefully being eliminated from the code based on "doesn't do anything" so no code size penalty
+*/
+
+/*the reason why all these constructs work is:
+if two strings separated by a comma will lose the comma (myteriously) then they will become just one string:
+"a", "b" ------Preprocessor------> "a" "b" -----Compiler----> "ab"
+*/
+
+#define LOTS_OF_COMMA_TO_BE_EATEN /*there were witnesses where as many as THREE commas have been eaten!*/ \
+"0" "1", "2", "3", "4", "5", "6", "7", "8", "9"
+#define DEFINITION_THAT_CAN_SUSTAIN_A_COMMA_STEAL(name, instance) static const char* eatThese_COMMA_##name##instance[] = {LOTS_OF_COMMA_TO_BE_EATEN}
+
+#define PUSH_LOCAL_PARAMETER(type, name) , MU_C2(name, _local)
+#define DEFINE_FUNCTION_PARAMETER(type, name) , type name
+#define MAKE_WRAPPER_ARGUMENT(N, type, name) {MU_TOSTRING(type), MU_TOSTRING(name)} MU_IFCOMMA(N)
+
+/*Codes_SRS_SERIALIZER_99_019:[ Create_AGENT_DATA_TYPE_from_DOUBLE]*/
+/*Codes_SRS_SERIALIZER_99_004:[ The propertyType can be any of the following data types: double]*/
+static AGENT_DATA_TYPES_RESULT MU_C2(ToAGENT_DATA_TYPE_, double)(AGENT_DATA_TYPE* dest, double source)
+{
+    return Create_AGENT_DATA_TYPE_from_DOUBLE(dest, source);
+}
+
+static AGENT_DATA_TYPES_RESULT MU_C2(FromAGENT_DATA_TYPE_, double)(const AGENT_DATA_TYPE* agentData, double* dest)
+{
+    AGENT_DATA_TYPES_RESULT result;
+    if (agentData->type != EDM_DOUBLE_TYPE)
+    {
+        result = AGENT_DATA_TYPES_INVALID_ARG;
+    }
+    else
+    {
+        *dest = agentData->value.edmDouble.value;
+        result = AGENT_DATA_TYPES_OK;
+    }
+    return result;
+}
+
+static void MU_C2(GlobalInitialize_, double)(void* dest)
+{
+    *(double*)dest = 0.0;
+}
+
+static void MU_C2(GlobalDeinitialize_, double)(void* dest)
+{
+    (void)(dest);
+}
+
+/*Codes_SRS_SERIALIZER_99_021:[ Create_AGENT_DATA_TYPE_from_FLOAT]*/
+/*Codes_SRS_SERIALIZER_99_006:[ float]*/
+static AGENT_DATA_TYPES_RESULT MU_C2(ToAGENT_DATA_TYPE_, float)(AGENT_DATA_TYPE* dest, float source)
+{
+    return Create_AGENT_DATA_TYPE_from_FLOAT(dest, source);
+}
+
+static AGENT_DATA_TYPES_RESULT MU_C2(FromAGENT_DATA_TYPE_, float)(const AGENT_DATA_TYPE* agentData, float* dest)
+{
+    AGENT_DATA_TYPES_RESULT result;
+    if (agentData->type != EDM_SINGLE_TYPE)
+    {
+        result = AGENT_DATA_TYPES_INVALID_ARG;
+    }
+    else
+    {
+        *dest = agentData->value.edmSingle.value;
+        result = AGENT_DATA_TYPES_OK;
+    }
+    return result;
+}
+
+static void MU_C2(GlobalInitialize_, float)(void* dest)
+{
+    *(float*)dest = 0.0f;
+}
+
+static void MU_C2(GlobalDeinitialize_, float)(void* dest)
+{
+    (void)(dest);
+}
+
+
+/*Codes_SRS_SERIALIZER_99_020:[ Create_AGENT_DATA_TYPE_from_SINT32]*/
+/*Codes_SRS_SERIALIZER_99_005:[ int], */
+static AGENT_DATA_TYPES_RESULT MU_C2(ToAGENT_DATA_TYPE_, int)(AGENT_DATA_TYPE* dest, int source)
+{
+    return Create_AGENT_DATA_TYPE_from_SINT32(dest, source);
+}
+
+static AGENT_DATA_TYPES_RESULT MU_C2(FromAGENT_DATA_TYPE_, int)(const AGENT_DATA_TYPE* agentData, int* dest)
+{
+    AGENT_DATA_TYPES_RESULT result;
+    if (agentData->type != EDM_INT32_TYPE)
+    {
+        result = AGENT_DATA_TYPES_INVALID_ARG;
+    }
+    else
+    {
+        *dest = agentData->value.edmInt32.value;
+        result = AGENT_DATA_TYPES_OK;
+    }
+    return result;
+}
+
+static void MU_C2(GlobalInitialize_, int)(void* dest)
+{
+    *(int*)dest = 0;
+}
+
+static void MU_C2(GlobalDeinitialize_, int)(void* dest)
+{
+    (void)(dest);
+}
+
+/*Codes_SRS_SERIALIZER_99_022:[ Create_AGENT_DATA_TYPE_from_SINT64]*/
+/*Codes_SRS_SERIALIZER_99_007:[ long]*/
+static AGENT_DATA_TYPES_RESULT MU_C2(ToAGENT_DATA_TYPE_, long)(AGENT_DATA_TYPE* dest, long source)
+{
+    return Create_AGENT_DATA_TYPE_from_SINT64(dest, source);
+}
+
+static AGENT_DATA_TYPES_RESULT MU_C2(FromAGENT_DATA_TYPE_, long)(const AGENT_DATA_TYPE* agentData, long* dest)
+{
+    AGENT_DATA_TYPES_RESULT result;
+    if (agentData->type != EDM_INT64_TYPE)
+    {
+        result = AGENT_DATA_TYPES_INVALID_ARG;
+    }
+    else
+    {
+        *dest = (long)agentData->value.edmInt64.value;
+        result = AGENT_DATA_TYPES_OK;
+    }
+    return result;
+}
+
+static void MU_C2(GlobalInitialize_, long)(void* dest)
+{
+    *(long*)dest = 0;
+}
+
+static void MU_C2(GlobalDeinitialize_, long)(void* dest)
+{
+    (void)(dest);
+}
+
+
+/*Codes_SRS_SERIALIZER_99_023:[ Create_AGENT_DATA_TYPE_from_SINT8]*/
+/*Codes_SRS_SERIALIZER_99_008:[ int8_t]*/
+static AGENT_DATA_TYPES_RESULT MU_C2(ToAGENT_DATA_TYPE_, int8_t)(AGENT_DATA_TYPE* dest, int8_t source)
+{
+    return Create_AGENT_DATA_TYPE_from_SINT8(dest, source);
+}
+
+static AGENT_DATA_TYPES_RESULT MU_C2(FromAGENT_DATA_TYPE_, int8_t)(const AGENT_DATA_TYPE* agentData, int8_t* dest)
+{
+    AGENT_DATA_TYPES_RESULT result;
+    if (agentData->type != EDM_SBYTE_TYPE)
+    {
+        result = AGENT_DATA_TYPES_INVALID_ARG;
+    }
+    else
+    {
+        *dest = agentData->value.edmSbyte.value;
+        result = AGENT_DATA_TYPES_OK;
+    }
+    return result;
+}
+
+static void MU_C2(GlobalInitialize_, int8_t)(void* dest)
+{
+    *(int8_t*)dest = 0;
+}
+
+static void MU_C2(GlobalDeinitialize_, int8_t)(void* dest)
+{
+    (void)(dest);
+}
+
+/*Codes_SRS_SERIALIZER_99_024:[ Create_AGENT_DATA_TYPE_from_UINT8]*/
+/*Codes_SRS_SERIALIZER_99_009:[ uint8_t]*/
+static AGENT_DATA_TYPES_RESULT MU_C2(ToAGENT_DATA_TYPE_, uint8_t)(AGENT_DATA_TYPE* dest, uint8_t source)
+{
+    return Create_AGENT_DATA_TYPE_from_UINT8(dest, source);
+}
+
+static AGENT_DATA_TYPES_RESULT MU_C2(FromAGENT_DATA_TYPE_, uint8_t)(const AGENT_DATA_TYPE* agentData, uint8_t* dest)
+{
+    AGENT_DATA_TYPES_RESULT result;
+    if (agentData->type != EDM_BYTE_TYPE)
+    {
+        result = AGENT_DATA_TYPES_INVALID_ARG;
+    }
+    else
+    {
+        *dest = agentData->value.edmByte.value;
+        result = AGENT_DATA_TYPES_OK;
+    }
+    return result;
+}
+
+static void MU_C2(GlobalInitialize_, uint8_t)(void* dest)
+{
+    *(uint8_t*)dest = 0;
+}
+
+static void MU_C2(GlobalDeinitialize_, uint8_t)(void* dest)
+{
+    (void)(dest);
+}
+
+
+/*Codes_SRS_SERIALIZER_99_025:[ Create_AGENT_DATA_TYPE_from_SINT16]*/
+/*Codes_SRS_SERIALIZER_99_010:[ int16_t]*/
+static AGENT_DATA_TYPES_RESULT MU_C2(ToAGENT_DATA_TYPE_, int16_t)(AGENT_DATA_TYPE* dest, int16_t source)
+{
+    return Create_AGENT_DATA_TYPE_from_SINT16(dest, source);
+}
+
+static AGENT_DATA_TYPES_RESULT MU_C2(FromAGENT_DATA_TYPE_, int16_t)(const AGENT_DATA_TYPE* agentData, int16_t* dest)
+{
+    AGENT_DATA_TYPES_RESULT result;
+    if (agentData->type != EDM_INT16_TYPE)
+    {
+        result = AGENT_DATA_TYPES_INVALID_ARG;
+    }
+    else
+    {
+        *dest = agentData->value.edmInt16.value;
+        result = AGENT_DATA_TYPES_OK;
+    }
+    return result;
+}
+
+static void MU_C2(GlobalInitialize_, int16_t)(void* dest)
+{
+    *(int16_t*)dest = 0;
+}
+
+static void MU_C2(GlobalDeinitialize_, int16_t)(void* dest)
+{
+    (void)(dest);
+}
+
+/*Codes_SRS_SERIALIZER_99_026:[ Create_AGENT_DATA_TYPE_from_SINT32]*/
+/*Codes_SRS_SERIALIZER_99_011:[ int32_t]*/
+static AGENT_DATA_TYPES_RESULT MU_C2(ToAGENT_DATA_TYPE_, int32_t)(AGENT_DATA_TYPE* dest, int32_t source)
+{
+    return Create_AGENT_DATA_TYPE_from_SINT32(dest, source);
+}
+
+static AGENT_DATA_TYPES_RESULT MU_C2(FromAGENT_DATA_TYPE_, int32_t)(const AGENT_DATA_TYPE* agentData, int32_t* dest)
+{
+    AGENT_DATA_TYPES_RESULT result;
+    if (agentData->type != EDM_INT32_TYPE)
+    {
+        result = AGENT_DATA_TYPES_INVALID_ARG;
+    }
+    else
+    {
+        *dest = agentData->value.edmInt32.value;
+        result = AGENT_DATA_TYPES_OK;
+    }
+    return result;
+}
+
+static void MU_C2(GlobalInitialize_, int32_t)(void* dest)
+{
+    *(int32_t*)dest = 0;
+}
+
+static void MU_C2(GlobalDeinitialize_, int32_t)(void* dest)
+{
+    (void)(dest);
+}
+
+/*Codes_SRS_SERIALIZER_99_027:[ Create_AGENT_DATA_TYPE_from_SINT64]*/
+/*Codes_SRS_SERIALIZER_99_012:[ int64_t]*/
+static AGENT_DATA_TYPES_RESULT MU_C2(ToAGENT_DATA_TYPE_, int64_t)(AGENT_DATA_TYPE* dest, int64_t source)
+{
+    return Create_AGENT_DATA_TYPE_from_SINT64(dest, source);
+}
+
+static AGENT_DATA_TYPES_RESULT MU_C2(FromAGENT_DATA_TYPE_, int64_t)(const AGENT_DATA_TYPE* agentData, int64_t* dest)
+{
+    AGENT_DATA_TYPES_RESULT result;
+    if (agentData->type != EDM_INT64_TYPE)
+    {
+        result = AGENT_DATA_TYPES_INVALID_ARG;
+    }
+    else
+    {
+        *dest = agentData->value.edmInt64.value;
+        result = AGENT_DATA_TYPES_OK;
+    }
+    return result;
+}
+
+static void MU_C2(GlobalInitialize_, int64_t)(void* dest)
+{
+    *(int64_t*)dest = 0;
+}
+
+static void MU_C2(GlobalDeinitialize_, int64_t)(void* dest)
+{
+    (void)(dest);
+}
+
+/*Codes_SRS_SERIALIZER_99_013:[ bool]*/
+static AGENT_DATA_TYPES_RESULT MU_C2(ToAGENT_DATA_TYPE_, bool)(AGENT_DATA_TYPE* dest, bool source)
+{
+    return Create_EDM_BOOLEAN_from_int(dest, source == true);
+}
+
+static AGENT_DATA_TYPES_RESULT MU_C2(FromAGENT_DATA_TYPE_, bool)(const AGENT_DATA_TYPE* agentData, bool* dest)
+{
+    AGENT_DATA_TYPES_RESULT result;
+    if (agentData->type != EDM_BOOLEAN_TYPE)
+    {
+        result = AGENT_DATA_TYPES_INVALID_ARG;
+    }
+    else
+    {
+        *dest = (agentData->value.edmBoolean.value == EDM_TRUE) ? true : false;
+        result = AGENT_DATA_TYPES_OK;
+    }
+    return result;
+}
+
+static void MU_C2(GlobalInitialize_, bool)(void* dest)
+{
+    *(bool*)dest = false;
+}
+
+static void MU_C2(GlobalDeinitialize_, bool)(void* dest)
+{
+    (void)(dest);
+}
+
+/*Codes_SRS_SERIALIZER_99_014:[ ascii_char_ptr]*/
+static AGENT_DATA_TYPES_RESULT MU_C2(ToAGENT_DATA_TYPE_, ascii_char_ptr)(AGENT_DATA_TYPE* dest, ascii_char_ptr source)
+{
+    return Create_AGENT_DATA_TYPE_from_charz(dest, source);
+}
+
+static AGENT_DATA_TYPES_RESULT MU_C2(FromAGENT_DATA_TYPE_, ascii_char_ptr)(const AGENT_DATA_TYPE* agentData, ascii_char_ptr* dest)
+{
+    AGENT_DATA_TYPES_RESULT result;
+    if (agentData->type != EDM_STRING_TYPE)
+    {
+        result = AGENT_DATA_TYPES_INVALID_ARG;
+    }
+    else
+    {
+        if (*dest != NULL)
+        {
+            free(*dest);
+            *dest = NULL;
+        }
+
+        if (mallocAndStrcpy_s(dest, agentData->value.edmString.chars) != 0)
+        {
+            LogError("failure in mallocAndStrcpy_s");
+            result = AGENT_DATA_TYPES_ERROR;
+        }
+        else
+        {
+            result = AGENT_DATA_TYPES_OK;
+        }
+
+    }
+    return result;
+}
+
+static void MU_C2(GlobalInitialize_, ascii_char_ptr)(void* dest)
+{
+    *(ascii_char_ptr*)dest = NULL;
+}
+
+static void MU_C2(GlobalDeinitialize_, ascii_char_ptr)(void* dest)
+{
+    if (*(ascii_char_ptr*)dest != NULL)
+    {
+        free(*(ascii_char_ptr*)dest);
+    }
+}
+
+static AGENT_DATA_TYPES_RESULT MU_C2(ToAGENT_DATA_TYPE_, ascii_char_ptr_no_quotes)(AGENT_DATA_TYPE* dest, ascii_char_ptr_no_quotes source)
+{
+    return Create_AGENT_DATA_TYPE_from_charz_no_quotes(dest, source);
+}
+
+static AGENT_DATA_TYPES_RESULT MU_C2(FromAGENT_DATA_TYPE_, ascii_char_ptr_no_quotes)(const AGENT_DATA_TYPE* agentData, ascii_char_ptr_no_quotes* dest)
+{
+    AGENT_DATA_TYPES_RESULT result;
+    if (agentData->type != EDM_STRING_NO_QUOTES_TYPE)
+    {
+        result = AGENT_DATA_TYPES_INVALID_ARG;
+    }
+    else
+    {
+        if (*dest != NULL)
+        {
+            free(*dest);
+            *dest = NULL;
+        }
+
+        if (mallocAndStrcpy_s(dest, agentData->value.edmStringNoQuotes.chars) != 0)
+        {
+            LogError("failure in mallocAndStrcpy_s");
+            result = AGENT_DATA_TYPES_ERROR;
+        }
+        else
+        {
+            result = AGENT_DATA_TYPES_OK;
+        }
+    }
+    return result;
+}
+
+static void MU_C2(GlobalInitialize_, ascii_char_ptr_no_quotes)(void* dest)
+{
+    *(ascii_char_ptr_no_quotes*)dest = NULL;
+}
+
+static void MU_C2(GlobalDeinitialize_, ascii_char_ptr_no_quotes)(void* dest)
+{
+    if (*(ascii_char_ptr_no_quotes*)dest != NULL)
+    {
+        free(*(ascii_char_ptr_no_quotes*)dest);
+    }
+}
+
+/*Codes_SRS_SERIALIZER_99_051:[ EDM_DATE_TIME_OFFSET*/
+/*Codes_SRS_SERIALIZER_99_053:[Create_AGENT_DATA_TYPE_from_EDM_DATE_TIME_OFFSET]*/
+static AGENT_DATA_TYPES_RESULT MU_C2(ToAGENT_DATA_TYPE_, EDM_DATE_TIME_OFFSET)(AGENT_DATA_TYPE* dest, EDM_DATE_TIME_OFFSET source)
+{
+    return Create_AGENT_DATA_TYPE_from_EDM_DATE_TIME_OFFSET(dest, source);
+}
+
+static AGENT_DATA_TYPES_RESULT MU_C2(FromAGENT_DATA_TYPE_, EDM_DATE_TIME_OFFSET)(const AGENT_DATA_TYPE* agentData, EDM_DATE_TIME_OFFSET* dest)
+{
+    AGENT_DATA_TYPES_RESULT result;
+    if (agentData->type != EDM_DATE_TIME_OFFSET_TYPE)
+    {
+        result = AGENT_DATA_TYPES_INVALID_ARG;
+    }
+    else
+    {
+        *dest = agentData->value.edmDateTimeOffset;
+        result = AGENT_DATA_TYPES_OK;
+    }
+    return result;
+}
+
+static void MU_C2(GlobalInitialize_, EDM_DATE_TIME_OFFSET)(void* dest)
+{
+    memset(dest, 0, sizeof(EDM_DATE_TIME_OFFSET));
+}
+
+static void MU_C2(GlobalDeinitialize_, EDM_DATE_TIME_OFFSET)(void* dest)
+{
+    (void)(dest);
+}
+
+/*Codes_SRS_SERIALIZER_99_072:[ EDM_GUID]*/
+/*Codes_SRS_SERIALIZER_99_073:[ Create_AGENT_DATA_TYPE_from_EDM_GUID]*/
+static AGENT_DATA_TYPES_RESULT MU_C2(ToAGENT_DATA_TYPE_, EDM_GUID)(AGENT_DATA_TYPE* dest, EDM_GUID guid)
+{
+    return Create_AGENT_DATA_TYPE_from_EDM_GUID(dest, guid);
+}
+
+static AGENT_DATA_TYPES_RESULT MU_C2(FromAGENT_DATA_TYPE_, EDM_GUID)(const AGENT_DATA_TYPE* agentData, EDM_GUID* dest)
+{
+    AGENT_DATA_TYPES_RESULT result;
+    if (agentData->type != EDM_GUID_TYPE)
+    {
+        result = AGENT_DATA_TYPES_INVALID_ARG;
+    }
+    else
+    {
+        (void)memcpy(dest->GUID, agentData->value.edmGuid.GUID, 16);
+        result = AGENT_DATA_TYPES_OK;
+    }
+    return result;
+}
+
+static void MU_C2(GlobalInitialize_, EDM_GUID)(void* dest)
+{
+    memset(dest, 0, sizeof(EDM_GUID));
+}
+
+static void MU_C2(GlobalDeinitialize_, EDM_GUID)(void* dest)
+{
+    (void)(dest);
+}
+
+
+/*Codes_SRS_SERIALIZER_99_074:[ EDM_BINARY]*/
+/*Codes_SRS_SERIALIZER_99_075:[ Create_AGENT_DATA_TYPE_from_EDM_BINARY]*/
+static AGENT_DATA_TYPES_RESULT MU_C2(ToAGENT_DATA_TYPE_, EDM_BINARY)(AGENT_DATA_TYPE* dest, EDM_BINARY edmBinary)
+{
+    return Create_AGENT_DATA_TYPE_from_EDM_BINARY(dest, edmBinary);
+}
+
+static AGENT_DATA_TYPES_RESULT MU_C2(FromAGENT_DATA_TYPE_, EDM_BINARY)(const AGENT_DATA_TYPE* agentData, EDM_BINARY* dest)
+{
+    AGENT_DATA_TYPES_RESULT result;
+    if (agentData->type != EDM_BINARY_TYPE)
+    {
+        result = AGENT_DATA_TYPES_INVALID_ARG;
+    }
+    else
+    {
+        if ((dest->data = (unsigned char *)malloc(agentData->value.edmBinary.size)) == NULL) /*cast because this get included in a C++ file.*/
+        {
+            result = AGENT_DATA_TYPES_ERROR;
+        }
+        else
+        {
+            (void)memcpy(dest->data, agentData->value.edmBinary.data, agentData->value.edmBinary.size);
+            dest->size = agentData->value.edmBinary.size;
+            result = AGENT_DATA_TYPES_OK;
+        }
+    }
+    return result;
+}
+
+static void MU_C2(GlobalInitialize_, EDM_BINARY)(void* dest)
+{
+    ((EDM_BINARY*)dest)->data = NULL;
+    ((EDM_BINARY*)dest)->size = 0;
+}
+
+static void MU_C2(GlobalDeinitialize_, EDM_BINARY)(void* dest)
+{
+    if ((((EDM_BINARY*)dest)->data) != NULL)
+    {
+        free(((EDM_BINARY*)dest)->data);
+    }
+}
+
+static void MU_C2(destroyLocalParameter, EDM_BINARY)(EDM_BINARY* value)
+{
+    if (value != NULL)
+    {
+        free(value->data);
+        value->data = NULL;
+        value->size = 0;
+    }
+}
+
+static void MU_C2(destroyLocalParameter, EDM_BOOLEAN)(EDM_BOOLEAN* value)
+{
+    (void)value;
+}
+
+static void MU_C2(destroyLocalParameter, EDM_BYTE)(EDM_BYTE* value)
+{
+    (void)value;
+}
+
+static void MU_C2(destroyLocalParameter, EDM_DATE)(EDM_DATE* value)
+{
+    (void)value;
+}
+
+static void MU_C2(destroyLocalParameter, EDM_DATE_TIME_OFFSET)(EDM_DATE_TIME_OFFSET* value)
+{
+    (void)value;
+}
+
+static void MU_C2(destroyLocalParameter, EDM_DECIMAL)(EDM_DECIMAL* value)
+{
+    if (value != NULL)
+    {
+        STRING_delete(value->value);
+        value->value = NULL;
+    }
+}
+
+static void MU_C2(destroyLocalParameter, EDM_DOUBLE)(EDM_DOUBLE* value)
+{
+    (void)value;
+}
+
+static void MU_C2(destroyLocalParameter, EDM_DURATION)(EDM_DURATION* value)
+{
+    if (value != NULL)
+    {
+        free(value->digits);
+        value->digits = NULL;
+        value->nDigits = 0;
+    }
+}
+
+static void MU_C2(destroyLocalParameter, EDM_GUID)(EDM_GUID* value)
+{
+    (void)value;
+}
+
+static void MU_C2(destroyLocalParameter, EDM_INT16)(EDM_INT16* value)
+{
+    (void)value;
+}
+
+static void MU_C2(destroyLocalParameter, EDM_INT32)(EDM_INT32* value)
+{
+    (void)value;
+}
+
+static void MU_C2(destroyLocalParameter, EDM_INT64)(EDM_INT64* value)
+{
+    (void)value;
+}
+
+static void MU_C2(destroyLocalParameter, EDM_SBYTE)(EDM_SBYTE* value)
+{
+    (void)value;
+}
+
+static void MU_C2(destroyLocalParameter, EDM_SINGLE)(EDM_SINGLE* value)
+{
+    (void)value;
+}
+
+static void MU_C2(destroyLocalParameter, EDM_STRING)(EDM_STRING* value)
+{
+    (void)value;
+}
+
+
+static void MU_C2(destroyLocalParameter, EDM_TIME_OF_DAY)(EDM_TIME_OF_DAY* value)
+{
+    (void)value;
+}
+
+static void MU_C2(destroyLocalParameter, int)(int* value)
+{
+    (void)value;
+}
+
+static void MU_C2(destroyLocalParameter, float)(float* value)
+{
+    (void)value;
+}
+
+static void MU_C2(destroyLocalParameter, double)(double* value)
+{
+    (void)value;
+}
+
+static void MU_C2(destroyLocalParameter, long)(long* value)
+{
+    (void)value;
+}
+
+static void MU_C2(destroyLocalParameter, int8_t)(int8_t* value)
+{
+    (void)value;
+}
+
+static void MU_C2(destroyLocalParameter, uint8_t)(uint8_t* value)
+{
+    (void)value;
+}
+
+static void MU_C2(destroyLocalParameter, int16_t)(int16_t* value)
+{
+    (void)value;
+}
+
+static void MU_C2(destroyLocalParameter, int32_t)(int32_t* value)
+{
+    (void)value;
+}
+
+static void MU_C2(destroyLocalParameter, int64_t)(int64_t* value)
+{
+    (void)value;
+}
+
+static void MU_C2(destroyLocalParameter, bool)(bool* value)
+{
+    (void)value;
+}
+
+static void MU_C2(destroyLocalParameter, ascii_char_ptr)(ascii_char_ptr* value)
+{
+    if (value != NULL)
+    {
+        free(*value);
+    }
+
+}
+
+static void MU_C2(destroyLocalParameter, ascii_char_ptr_no_quotes)(ascii_char_ptr_no_quotes* value)
+{
+    if (value != NULL)
+    {
+        free(*value);
+    }
+}
+
+#ifdef __cplusplus
+    }
+#endif
+
+#endif /*SERIALIZER_H*/
+
+
Index: azure_iot_hub_f767zi/trunk/azure_iot_sdk/serializer/inc/serializer_devicetwin.h
===================================================================
--- azure_iot_hub_f767zi/trunk/azure_iot_sdk/serializer/inc/serializer_devicetwin.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/azure_iot_sdk/serializer/inc/serializer_devicetwin.h	(revision 457)
@@ -0,0 +1,472 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+
+#ifndef SERIALIZER_DEVICE_TWIN_H
+#define SERIALIZER_DEVICE_TWIN_H
+
+#include "serializer.h"
+
+#include "iothub_client.h"
+#include "iothub_client_ll.h"
+#include "parson.h"
+#include "azure_c_shared_utility/optimize_size.h"
+#include "azure_c_shared_utility/vector.h"
+#include "methodreturn.h"
+
+static void serializer_ingest(DEVICE_TWIN_UPDATE_STATE update_state, const unsigned char* payLoad, size_t size, void* userContextCallback)
+{
+    /*by convention, userContextCallback is a pointer to a model instance created with CodeFirst_CreateDevice*/
+
+    /*Codes_SRS_SERIALIZERDEVICETWIN_02_001: [ serializer_ingest shall clone the payload into a null terminated string. ]*/
+    char* copyOfPayload = (char*)malloc(size + 1);
+    if (copyOfPayload == NULL)
+    {
+        /*Codes_SRS_SERIALIZERDEVICETWIN_02_008: [ If any of the above operations fail, then serializer_ingest shall return. ]*/
+        LogError("unable to malloc\n");
+    }
+    else
+    {
+        (void)memcpy(copyOfPayload, payLoad, size);
+        copyOfPayload[size] = '\0';
+
+        bool parseDesiredNode = (update_state == DEVICE_TWIN_UPDATE_COMPLETE);
+
+        if (CodeFirst_IngestDesiredProperties(userContextCallback, copyOfPayload, parseDesiredNode) != CODEFIRST_OK)
+        {
+            /*Codes_SRS_SERIALIZERDEVICETWIN_02_008: [ If any of the above operations fail, then serializer_ingest shall return. ]*/
+            LogError("failure ingesting desired properties\n");
+        }
+        else
+        {
+            /*all is fine*/
+        }
+
+        free(copyOfPayload);
+    }
+}
+
+/*both LL and convenience layer can be served by the same callback*/
+static int deviceMethodCallback(const char* method_name, const unsigned char* payload, size_t size, unsigned char** response, size_t* resp_size, void* userContextCallback)
+{
+    int result;
+    /*Codes_SRS_SERIALIZERDEVICETWIN_02_021: [ deviceMethodCallback shall transform payload and size into a null terminated string. ]*/
+    char* payloadZeroTerminated = (char*)malloc(size + 1);
+    if (payloadZeroTerminated == NULL)
+    {
+        LogError("failure in malloc");
+        /*Codes_SRS_SERIALIZERDEVICETWIN_02_026: [ If any failure occurs in the above operations, then deviceMethodCallback shall fail, return 500, set *response to NULL and '*resp_size` to 0. ]*/
+        *response = NULL;
+        *resp_size = 0;
+        result = 500;
+    }
+    else
+    {
+        (void)memcpy(payloadZeroTerminated, payload, size);
+        payloadZeroTerminated[size] = '\0';
+
+        /*Codes_SRS_SERIALIZERDEVICETWIN_02_022: [ deviceMethodCallback shall call EXECUTE_METHOD passing the userContextCallback, method_name and the null terminated string build before. ]*/
+        METHODRETURN_HANDLE mr = EXECUTE_METHOD(userContextCallback, method_name, payloadZeroTerminated);
+
+        if (mr == NULL)
+        {
+            LogError("failure in EXECUTE_METHOD");
+            /*Codes_SRS_SERIALIZERDEVICETWIN_02_026: [ If any failure occurs in the above operations, then deviceMethodCallback shall fail, return 500, set *response to NULL and '*resp_size` to 0. ]*/
+            *response = NULL;
+            *resp_size = 0;
+            result = 500;
+        }
+        else
+        {
+            /*Codes_SRS_SERIALIZERDEVICETWIN_02_023: [ deviceMethodCallback shall get the MethodReturn_Data and shall copy the response JSON value into a new byte array. ]*/
+            const METHODRETURN_DATA* data = MethodReturn_GetReturn(mr);
+
+            /*Codes_SRS_SERIALIZERDEVICETWIN_02_025: [ deviceMethodCallback returns the statusCode from the user. ]*/
+            result = data->statusCode;
+
+            if (data->jsonValue == NULL)
+            {
+                *resp_size = 0;
+                *response = NULL;
+            }
+            else
+            {
+                *resp_size = strlen(data->jsonValue);
+                *response = (unsigned char*)malloc(*resp_size);
+                if (*response == NULL)
+                {
+                    LogError("failure in malloc");
+                    /*Codes_SRS_SERIALIZERDEVICETWIN_02_026: [ If any failure occurs in the above operations, then deviceMethodCallback shall fail, return 500, set *response to NULL and '*resp_size` to 0. ]*/
+                    *response = NULL;
+                    *resp_size = 0;
+                    result = 500;
+                }
+                else
+                {
+                    /*Codes_SRS_SERIALIZERDEVICETWIN_02_024: [ deviceMethodCallback shall set *response to this new byte array, *resp_size to the size of the array. ]*/
+                    (void)memcpy(*response, data->jsonValue, *resp_size);
+                }
+            }
+            MethodReturn_Destroy(mr);
+        }
+        free(payloadZeroTerminated);
+    }
+    return result;
+}
+
+/*an enum that sets the type of the handle used to record IoTHubDeviceTwin_Create was called*/
+#define IOTHUB_CLIENT_HANDLE_TYPE_VALUES \
+    IOTHUB_CLIENT_CONVENIENCE_HANDLE_TYPE, \
+    IOTHUB_CLIENT_LL_HANDLE_TYPE
+
+MU_DEFINE_ENUM_WITHOUT_INVALID(IOTHUB_CLIENT_HANDLE_TYPE, IOTHUB_CLIENT_HANDLE_TYPE_VALUES)
+
+typedef union IOTHUB_CLIENT_HANDLE_VALUE_TAG
+{
+    IOTHUB_CLIENT_HANDLE iothubClientHandle;
+    IOTHUB_CLIENT_LL_HANDLE iothubClientLLHandle;
+} IOTHUB_CLIENT_HANDLE_VALUE;
+
+typedef struct IOTHUB_CLIENT_HANDLE_VARIANT_TAG
+{
+    IOTHUB_CLIENT_HANDLE_TYPE iothubClientHandleType;
+    IOTHUB_CLIENT_HANDLE_VALUE iothubClientHandleValue;
+} IOTHUB_CLIENT_HANDLE_VARIANT;
+
+typedef struct SERIALIZER_DEVICETWIN_PROTOHANDLE_TAG /*it is called "PROTOHANDLE" because it is a primitive type of handle*/
+{
+    IOTHUB_CLIENT_HANDLE_VARIANT iothubClientHandleVariant;
+    void* deviceAssigned;
+} SERIALIZER_DEVICETWIN_PROTOHANDLE;
+
+static VECTOR_HANDLE g_allProtoHandles=NULL; /*contains SERIALIZER_DEVICETWIN_PROTOHANDLE*/
+
+static int lazilyAddProtohandle(const SERIALIZER_DEVICETWIN_PROTOHANDLE* protoHandle)
+{
+    int result;
+    if ((g_allProtoHandles == NULL) && ((g_allProtoHandles = VECTOR_create(sizeof(SERIALIZER_DEVICETWIN_PROTOHANDLE))) == NULL))
+    {
+        LogError("failure in VECTOR_create");
+        result = MU_FAILURE;
+    }
+    else
+    {
+        if (VECTOR_push_back(g_allProtoHandles, protoHandle, 1) != 0)
+        {
+            LogError("failure in VECTOR_push_back");
+            result = MU_FAILURE;
+
+            /*leave it as it was*/
+
+            if (VECTOR_size(g_allProtoHandles) == 0)
+            {
+                VECTOR_destroy(g_allProtoHandles);
+                g_allProtoHandles = NULL;
+            }
+        }
+        else
+        {
+            result = 0;
+        }
+    }
+    return result;
+}
+
+static IOTHUB_CLIENT_RESULT Generic_IoTHubClient_SetCallbacks(const SERIALIZER_DEVICETWIN_PROTOHANDLE* protoHandle, IOTHUB_CLIENT_DEVICE_TWIN_CALLBACK deviceTwinCallback, void* userContextCallback)
+{
+    IOTHUB_CLIENT_RESULT result;
+    /*Codes_SRS_SERIALIZERDEVICETWIN_02_011: [ IoTHubDeviceTwinCreate_Impl shall set the device twin callback. ]*/
+    switch (protoHandle->iothubClientHandleVariant.iothubClientHandleType)
+    {
+    case IOTHUB_CLIENT_CONVENIENCE_HANDLE_TYPE:
+    {
+        if ((result = IoTHubClient_SetDeviceTwinCallback(protoHandle->iothubClientHandleVariant.iothubClientHandleValue.iothubClientHandle, deviceTwinCallback, userContextCallback)) != IOTHUB_CLIENT_OK)
+        {
+            LogError("failure in IoTHubClient_SetDeviceTwinCallback");
+        }
+        else
+        {
+            /*Codes_SRS_SERIALIZERDEVICETWIN_02_027: [ IoTHubDeviceTwinCreate_Impl shall set the device method callback ]*/
+            if ((result = IoTHubClient_SetDeviceMethodCallback(protoHandle->iothubClientHandleVariant.iothubClientHandleValue.iothubClientHandle, deviceMethodCallback, userContextCallback)) != IOTHUB_CLIENT_OK)
+            {
+                (void)IoTHubClient_SetDeviceTwinCallback(protoHandle->iothubClientHandleVariant.iothubClientHandleValue.iothubClientHandle, NULL, NULL);
+                LogError("failure in IoTHubClient_SetDeviceMethodCallback");
+            }
+        }
+        break;
+    }
+    case IOTHUB_CLIENT_LL_HANDLE_TYPE:
+    {
+        if ((result =IoTHubClient_LL_SetDeviceTwinCallback(protoHandle->iothubClientHandleVariant.iothubClientHandleValue.iothubClientLLHandle, deviceTwinCallback, userContextCallback)) != IOTHUB_CLIENT_OK)
+        {
+            LogError("failure in IoTHubClient_LL_SetDeviceTwinCallback");
+        }
+        else
+        {
+            /*Codes_SRS_SERIALIZERDEVICETWIN_02_027: [ IoTHubDeviceTwinCreate_Impl shall set the device method callback ]*/
+            if ((result = IoTHubClient_LL_SetDeviceMethodCallback(protoHandle->iothubClientHandleVariant.iothubClientHandleValue.iothubClientLLHandle, deviceMethodCallback, userContextCallback)) != IOTHUB_CLIENT_OK)
+            {
+                (void)IoTHubClient_LL_SetDeviceTwinCallback(protoHandle->iothubClientHandleVariant.iothubClientHandleValue.iothubClientLLHandle, NULL, NULL);
+                LogError("failure in IoTHubClient_SetDeviceMethodCallback");
+            }
+        }
+        break;
+    }
+    default:
+    {
+        result = IOTHUB_CLIENT_ERROR;
+        LogError("INTERNAL ERROR");
+    }
+    }/*switch*/
+    return result;
+}
+
+static void* IoTHubDeviceTwinCreate_Impl(const char* name, size_t sizeOfName, SERIALIZER_DEVICETWIN_PROTOHANDLE* protoHandle)
+{
+    void* result;
+    /*Codes_SRS_SERIALIZERDEVICETWIN_02_009: [ IoTHubDeviceTwinCreate_Impl shall locate the model and the metadata for name by calling Schema_GetSchemaForModel/Schema_GetMetadata/Schema_GetModelByName. ]*/
+    SCHEMA_HANDLE h = Schema_GetSchemaForModel(name);
+    if (h == NULL)
+    {
+        /*Codes_SRS_SERIALIZERDEVICETWIN_02_014: [ Otherwise, IoTHubDeviceTwinCreate_Impl shall fail and return NULL. ]*/
+        LogError("failure in Schema_GetSchemaForModel.");
+        result = NULL;
+    }
+    else
+    {
+        void* metadata = Schema_GetMetadata(h);
+        SCHEMA_MODEL_TYPE_HANDLE modelType = Schema_GetModelByName(h, name);
+        if (modelType == NULL)
+        {
+            /*Codes_SRS_SERIALIZERDEVICETWIN_02_014: [ Otherwise, IoTHubDeviceTwinCreate_Impl shall fail and return NULL. ]*/
+            LogError("failure in Schema_GetModelByName");
+            result = NULL;
+        }
+        else
+        {
+            /*Codes_SRS_SERIALIZERDEVICETWIN_02_010: [ IoTHubDeviceTwinCreate_Impl shall call CodeFirst_CreateDevice. ]*/
+            result = CodeFirst_CreateDevice(modelType, (REFLECTED_DATA_FROM_DATAPROVIDER *)metadata, sizeOfName, true);
+            if (result == NULL)
+            {
+                /*Codes_SRS_SERIALIZERDEVICETWIN_02_014: [ Otherwise, IoTHubDeviceTwinCreate_Impl shall fail and return NULL. ]*/
+                LogError("failure in CodeFirst_CreateDevice");
+                /*return as is*/
+            }
+            else
+            {
+                protoHandle->deviceAssigned = result;
+                if (Generic_IoTHubClient_SetCallbacks(protoHandle, serializer_ingest, result) != IOTHUB_CLIENT_OK)
+                {
+                    /*Codes_SRS_SERIALIZERDEVICETWIN_02_014: [ Otherwise, IoTHubDeviceTwinCreate_Impl shall fail and return NULL. ]*/
+                    LogError("failure in Generic_IoTHubClient_SetCallbacks");
+                    CodeFirst_DestroyDevice(result);
+                    result = NULL;
+                }
+                else
+                {
+                    /*lazily add the protohandle to the array of tracking handles*/
+
+                    /*Codes_SRS_SERIALIZERDEVICETWIN_02_012: [ IoTHubDeviceTwinCreate_Impl shall record the pair of (device, IoTHubClient(_LL)). ]*/
+                    if (lazilyAddProtohandle(protoHandle) != 0)
+                    {
+                        /*Codes_SRS_SERIALIZERDEVICETWIN_02_014: [ Otherwise, IoTHubDeviceTwinCreate_Impl shall fail and return NULL. ]*/
+                        LogError("unable to add the protohandle to the collection of handles");
+                        /*unsubscribe*/
+                        if (Generic_IoTHubClient_SetCallbacks(protoHandle, NULL, NULL) != IOTHUB_CLIENT_OK)
+                        {
+                            /*just log the error*/
+                            LogError("failure in Generic_IoTHubClient_SetCallbacks");
+                        }
+                        CodeFirst_DestroyDevice(result);
+                        result = NULL;
+                    }
+                    else
+                    {
+                        /*Codes_SRS_SERIALIZERDEVICETWIN_02_013: [ If all operations complete successfully then IoTHubDeviceTwinCreate_Impl shall succeeds and return a non-NULL value. ]*/
+                        /*return as is*/
+                    }
+                }
+            }
+        }
+    }
+    return result;
+}
+
+static bool protoHandleHasDeviceStartAddress(const void* element, const void* value)
+{
+    const SERIALIZER_DEVICETWIN_PROTOHANDLE* protoHandle = (const SERIALIZER_DEVICETWIN_PROTOHANDLE*)element;
+    return protoHandle->deviceAssigned == value;
+}
+
+static void IoTHubDeviceTwin_Destroy_Impl(void* model)
+{
+    /*Codes_SRS_SERIALIZERDEVICETWIN_02_020: [ If model is NULL then IoTHubDeviceTwin_Destroy_Impl shall return. ]*/
+    if (model == NULL)
+    {
+        LogError("invalid argument void* model=%p", model);
+    }
+    else
+    {
+        /*Codes_SRS_SERIALIZERDEVICETWIN_02_015: [ IoTHubDeviceTwin_Destroy_Impl shall locate the saved handle belonging to model. ]*/
+        SERIALIZER_DEVICETWIN_PROTOHANDLE* protoHandle = (SERIALIZER_DEVICETWIN_PROTOHANDLE*)VECTOR_find_if(g_allProtoHandles, protoHandleHasDeviceStartAddress, model);
+        if (protoHandle == NULL)
+        {
+            LogError("failure in VECTOR_find_if [not found]");
+        }
+        else
+        {
+            /*Codes_SRS_SERIALIZERDEVICETWIN_02_016: [ IoTHubDeviceTwin_Destroy_Impl shall set the devicetwin callback to NULL. ]*/
+            switch (protoHandle->iothubClientHandleVariant.iothubClientHandleType)
+            {
+            case IOTHUB_CLIENT_CONVENIENCE_HANDLE_TYPE:
+            {
+                if (IoTHubClient_SetDeviceTwinCallback(protoHandle->iothubClientHandleVariant.iothubClientHandleValue.iothubClientHandle, NULL, NULL) != IOTHUB_CLIENT_OK)
+                {
+                    LogError("failure in IoTHubClient_SetDeviceTwinCallback");
+                }
+                /*Codes_SRS_SERIALIZERDEVICETWIN_02_028: [ IoTHubDeviceTwin_Destroy_Impl shall set the method callback to NULL. ]*/
+                if (IoTHubClient_SetDeviceMethodCallback(protoHandle->iothubClientHandleVariant.iothubClientHandleValue.iothubClientHandle, NULL, NULL) != IOTHUB_CLIENT_OK)
+                {
+                    LogError("failure in IoTHubClient_SetDeviceMethodCallback");
+                }
+                break;
+            }
+            case IOTHUB_CLIENT_LL_HANDLE_TYPE:
+            {
+                if (IoTHubClient_LL_SetDeviceTwinCallback(protoHandle->iothubClientHandleVariant.iothubClientHandleValue.iothubClientLLHandle, NULL, NULL) != IOTHUB_CLIENT_OK)
+                {
+                    LogError("failure in IoTHubClient_LL_SetDeviceTwinCallback");
+                }
+                /*Codes_SRS_SERIALIZERDEVICETWIN_02_028: [ IoTHubDeviceTwin_Destroy_Impl shall set the method callback to NULL. ]*/
+                if (IoTHubClient_LL_SetDeviceMethodCallback(protoHandle->iothubClientHandleVariant.iothubClientHandleValue.iothubClientLLHandle, NULL, NULL) != IOTHUB_CLIENT_OK)
+                {
+                    LogError("failure in IoTHubClient_LL_SetDeviceMethodCallback");
+                }
+                break;
+            }
+            default:
+            {
+                LogError("INTERNAL ERROR");
+            }
+            }/*switch*/
+
+             /*Codes_SRS_SERIALIZERDEVICETWIN_02_017: [ IoTHubDeviceTwin_Destroy_Impl shall call CodeFirst_DestroyDevice. ]*/
+            CodeFirst_DestroyDevice(protoHandle->deviceAssigned);
+
+            /*Codes_SRS_SERIALIZERDEVICETWIN_02_018: [ IoTHubDeviceTwin_Destroy_Impl shall remove the IoTHubClient_Handle and the device handle from the recorded set. ]*/
+            VECTOR_erase(g_allProtoHandles, protoHandle, 1);
+        }
+
+        /*Codes_SRS_SERIALIZERDEVICETWIN_02_019: [ If the recorded set of IoTHubClient handles is zero size, then the set shall be destroyed. ]*/
+        if (VECTOR_size(g_allProtoHandles) == 0) /*lazy init means more work @ destroy time*/
+        {
+            VECTOR_destroy(g_allProtoHandles);
+            g_allProtoHandles = NULL;
+        }
+    }
+}
+
+/*the below function sends the reported state of a model previously created by IoTHubDeviceTwin_Create*/
+/*this function serves both the _LL and the convenience layer because of protohandles*/
+static IOTHUB_CLIENT_RESULT IoTHubDeviceTwin_SendReportedState_Impl(void* model, IOTHUB_CLIENT_REPORTED_STATE_CALLBACK deviceTwinCallback, void* context)
+{
+    unsigned char*buffer;
+    size_t bufferSize;
+
+    IOTHUB_CLIENT_RESULT result;
+
+    if (SERIALIZE_REPORTED_PROPERTIES_FROM_POINTERS(&buffer, &bufferSize, model) != CODEFIRST_OK)
+    {
+        LogError("Failed serializing reported state");
+        result = IOTHUB_CLIENT_ERROR;
+    }
+    else
+    {
+        SERIALIZER_DEVICETWIN_PROTOHANDLE* protoHandle = (SERIALIZER_DEVICETWIN_PROTOHANDLE*)VECTOR_find_if(g_allProtoHandles, protoHandleHasDeviceStartAddress, model);
+        if (protoHandle == NULL)
+        {
+            LogError("failure in VECTOR_find_if [not found]");
+            result = IOTHUB_CLIENT_ERROR;
+        }
+        else
+        {
+            switch (protoHandle->iothubClientHandleVariant.iothubClientHandleType)
+            {
+                case IOTHUB_CLIENT_CONVENIENCE_HANDLE_TYPE:
+                {
+                    if (IoTHubClient_SendReportedState(protoHandle->iothubClientHandleVariant.iothubClientHandleValue.iothubClientHandle, buffer, bufferSize, deviceTwinCallback, context) != IOTHUB_CLIENT_OK)
+                    {
+                        LogError("Failure sending data");
+                        result = IOTHUB_CLIENT_ERROR;
+                    }
+                    else
+                    {
+                        result = IOTHUB_CLIENT_OK;
+                    }
+                    break;
+                }
+                case IOTHUB_CLIENT_LL_HANDLE_TYPE:
+                {
+                    if (IoTHubClient_LL_SendReportedState(protoHandle->iothubClientHandleVariant.iothubClientHandleValue.iothubClientLLHandle, buffer, bufferSize, deviceTwinCallback, context) != IOTHUB_CLIENT_OK)
+                    {
+                        LogError("Failure sending data");
+                        result = IOTHUB_CLIENT_ERROR;
+                    }
+                    else
+                    {
+                        result = IOTHUB_CLIENT_OK;
+                    }
+                    break;
+                }
+                default:
+                {
+                    LogError("INTERNAL ERROR: unexpected value for enum (%d)", (int)protoHandle->iothubClientHandleVariant.iothubClientHandleType);
+                    result = IOTHUB_CLIENT_ERROR;
+                    break;
+                }
+            }
+        }
+        free(buffer);
+    }
+    return result;
+}
+
+#define DECLARE_DEVICETWIN_MODEL(name, ...)    \
+    DECLARE_MODEL(name, __VA_ARGS__)           \
+    static name* MU_C2(IoTHubDeviceTwin_Create, name)(IOTHUB_CLIENT_HANDLE iotHubClientHandle)                                                                                         \
+    {                                                                                                                                                                               \
+        SERIALIZER_DEVICETWIN_PROTOHANDLE protoHandle;                                                                                                                              \
+        protoHandle.iothubClientHandleVariant.iothubClientHandleType = IOTHUB_CLIENT_CONVENIENCE_HANDLE_TYPE;                                                                       \
+        protoHandle.iothubClientHandleVariant.iothubClientHandleValue.iothubClientHandle = iotHubClientHandle;                                                                      \
+        return (name*)IoTHubDeviceTwinCreate_Impl(#name, sizeof(name), &protoHandle);                                                                                               \
+    }                                                                                                                                                                               \
+                                                                                                                                                                                    \
+    static void MU_C2(IoTHubDeviceTwin_Destroy, name) (name* model)                                                                                                                    \
+    {                                                                                                                                                                               \
+        IoTHubDeviceTwin_Destroy_Impl(model);                                                                                                                                       \
+    }                                                                                                                                                                               \
+                                                                                                                                                                                    \
+    static name* MU_C2(IoTHubDeviceTwin_LL_Create, name)(IOTHUB_CLIENT_LL_HANDLE iotHubClientLLHandle)                                                                                 \
+    {                                                                                                                                                                               \
+        SERIALIZER_DEVICETWIN_PROTOHANDLE protoHandle;                                                                                                                              \
+        protoHandle.iothubClientHandleVariant.iothubClientHandleType = IOTHUB_CLIENT_LL_HANDLE_TYPE;                                                                                \
+        protoHandle.iothubClientHandleVariant.iothubClientHandleValue.iothubClientLLHandle = iotHubClientLLHandle;                                                                  \
+        return (name*)IoTHubDeviceTwinCreate_Impl(#name, sizeof(name), &protoHandle);                                                                                               \
+    }                                                                                                                                                                               \
+                                                                                                                                                                                    \
+    static void MU_C2(IoTHubDeviceTwin_LL_Destroy, name) (name* model)                                                                                                                 \
+    {                                                                                                                                                                               \
+        IoTHubDeviceTwin_Destroy_Impl(model);                                                                                                                                       \
+    }                                                                                                                                                                               \
+    static IOTHUB_CLIENT_RESULT MU_C2(IoTHubDeviceTwin_LL_SendReportedState, name) (name* model, IOTHUB_CLIENT_REPORTED_STATE_CALLBACK deviceTwinCallback, void* context)              \
+    {                                                                                                                                                                               \
+        return IoTHubDeviceTwin_SendReportedState_Impl(model, deviceTwinCallback, context);                                                                                         \
+    }                                                                                                                                                                               \
+    static IOTHUB_CLIENT_RESULT MU_C2(IoTHubDeviceTwin_SendReportedState, name) (name* model, IOTHUB_CLIENT_REPORTED_STATE_CALLBACK deviceTwinCallback, void* context)                 \
+    {                                                                                                                                                                               \
+        return IoTHubDeviceTwin_SendReportedState_Impl(model, deviceTwinCallback, context);                                                                                         \
+    }                                                                                                                                                                               \
+
+#endif /*SERIALIZER_DEVICE_TWIN_H*/
+
+
Index: azure_iot_hub_f767zi/trunk/azure_iot_sdk/serializer/src/agenttypesystem.c
===================================================================
--- azure_iot_hub_f767zi/trunk/azure_iot_sdk/serializer/src/agenttypesystem.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/azure_iot_sdk/serializer/src/agenttypesystem.c	(revision 457)
@@ -0,0 +1,4011 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+#include <stdlib.h>
+#include "azure_c_shared_utility/gballoc.h"
+
+#include "agenttypesystem.h"
+#include <inttypes.h>
+
+#ifdef _MSC_VER
+#pragma warning(disable: 4756) /* Known warning for INFINITY */
+#endif
+
+#include <stddef.h>
+
+#include <float.h>
+#include <math.h>
+#include <limits.h>
+#include <errno.h>
+
+/*if ULLONG_MAX is defined by limits.h for whatever reasons... */
+#ifndef ULLONG_MAX
+#define ULLONG_MAX 18446744073709551615
+#endif
+
+#include "azure_c_shared_utility/crt_abstractions.h"
+
+#include "jsonencoder.h"
+#include "multitree.h"
+
+#include "azure_c_shared_utility/xlogging.h"
+
+#define NaN_STRING "NaN"
+#define MINUSINF_STRING "-INF"
+#define PLUSINF_STRING "INF"
+
+#ifndef _HUGE_ENUF
+#define _HUGE_ENUF  1e+300    /* _HUGE_ENUF*_HUGE_ENUF must overflow */
+#endif /* _HUGE_ENUF */
+
+#ifndef INFINITY
+#define INFINITY   ((float)(_HUGE_ENUF * _HUGE_ENUF))  /* causes warning C4756: overflow in constant arithmetic (by design) */
+#endif /* INFINITY */
+
+#ifndef NAN
+#define NAN        ((float)(INFINITY * 0.0F))
+#endif /* NAN */
+
+#define GUID_STRING_LENGTH 38
+
+// This is an artificial upper limit on floating point string length
+// (e.g. the size of the string when printing %f). It is set to twice the
+// maximum decimal precision plus 2. 1 for the decimal point and 1 for a
+// sign (+/-)
+// Unfortunately it is quite possible to print a float larger than this.
+// An example of this would be printf("%.*f", MAX_FLOATING_POINT_STRING_LENGTH, 1.3);
+// But currently no explicit requests for this exist in the file nor are
+// any expected to reasonably occur when being used (numbers that hit
+// this limit would be experiencing significant precision loss in storage anyway.
+#define MAX_FLOATING_POINT_STRING_LENGTH (DECIMAL_DIG *2 + 2)
+
+// This maximum length is 11 for 32 bit integers (including the sign)
+// optionally increase to 21 if longs are 64 bit
+#define MAX_LONG_STRING_LENGTH ( 11 + (10 * (sizeof(long)/ 8)))
+
+// This is the maximum length for the largest 64 bit number (signed)
+#define MAX_ULONG_LONG_STRING_LENGTH 20
+
+MU_DEFINE_ENUM_STRINGS_WITHOUT_INVALID(AGENT_DATA_TYPES_RESULT, AGENT_DATA_TYPES_RESULT_VALUES);
+
+static int ValidateDate(int year, int month, int day);
+
+static int NoCloneFunction(void** destination, const void* source)
+{
+    *destination = (void*)source;
+    return 0;
+}
+
+static void NoFreeFunction(void* value)
+{
+    (void)value;
+}
+
+
+#define IS_DIGIT(a) (('0'<=(a)) &&((a)<='9'))
+#define splitInt(intVal, bytePos)   (char)((intVal >> (bytePos << 3)) & 0xFF)
+#define joinChars(a, b, c, d) (uint32_t)( (uint32_t)a + ((uint32_t)b << 8) + ((uint32_t)c << 16) + ((uint32_t)d << 24))
+
+static char base64char(unsigned char val)
+{
+    char result;
+
+    if (val < 26)
+    {
+        result = 'A' + (char)val;
+    }
+    else if (val < 52)
+    {
+        result = 'a' + ((char)val - 26);
+    }
+    else if (val < 62)
+    {
+        result = '0' + ((char)val - 52);
+    }
+    else if (val == 62)
+    {
+        result = '-';
+    }
+    else
+    {
+        result = '_';
+    }
+
+    return result;
+}
+
+static char base64b16(unsigned char val)
+{
+    const uint32_t base64b16values[4] = {
+        joinChars('A', 'E', 'I', 'M'),
+        joinChars('Q', 'U', 'Y', 'c'),
+        joinChars('g', 'k', 'o', 's'),
+        joinChars('w', '0', '4', '8')
+    };
+    return splitInt(base64b16values[val >> 2], (val & 0x03));
+}
+
+static char base64b8(unsigned char val)
+{
+    const uint32_t base64b8values = joinChars('A', 'Q', 'g', 'w');
+    return splitInt(base64b8values, val);
+};
+
+/*creates an AGENT_DATA_TYPE containing a EDM_BOOLEAN from a int*/
+AGENT_DATA_TYPES_RESULT Create_EDM_BOOLEAN_from_int(AGENT_DATA_TYPE* agentData, int v)
+{
+    AGENT_DATA_TYPES_RESULT result;
+    /*Codes_SRS_AGENT_TYPE_SYSTEM_99_013:[All the Create_... functions shall check their parameters for validity.When an invalid parameter is detected, a code of AGENT_DATA_TYPES_INVALID_ARG shall be returned]*/
+    if(agentData==NULL)
+    {
+        result = AGENT_DATA_TYPES_INVALID_ARG;
+        LogError("(result = %s)", MU_ENUM_TO_STRING(AGENT_DATA_TYPES_RESULT, result));
+    }
+    else
+    {
+        /*Codes_SRS_AGENT_TYPE_SYSTEM_99_031:[ Creates a AGENT_DATA_TYPE representing an EDM_BOOLEAN.]*/
+        agentData->type = EDM_BOOLEAN_TYPE;
+        agentData->value.edmBoolean.value = (v)?(EDM_TRUE):(EDM_FALSE);
+        result = AGENT_DATA_TYPES_OK;
+    }
+    return result;
+}
+
+/*creates an AGENT_DATA_TYPE containing a UINT8*/
+AGENT_DATA_TYPES_RESULT Create_AGENT_DATA_TYPE_from_UINT8(AGENT_DATA_TYPE* agentData, uint8_t v)
+{
+    AGENT_DATA_TYPES_RESULT result;
+    /*Codes_SRS_AGENT_TYPE_SYSTEM_99_013:[ All the Create_... functions shall check their parameters for validity. When an invalid parameter is detected, a code of AGENT_DATA_TYPES_INVALID_ARG shall be returned ].*/
+    if (agentData == NULL)
+    {
+        result = AGENT_DATA_TYPES_INVALID_ARG;
+        LogError("(result = %s)", MU_ENUM_TO_STRING(AGENT_DATA_TYPES_RESULT, result));
+    }
+    else
+    {
+        agentData->type = EDM_BYTE_TYPE;
+        agentData->value.edmByte.value = v;
+        result = AGENT_DATA_TYPES_OK;
+    }
+    return result;
+}
+
+/*Codes_SRS_AGENT_TYPE_SYSTEM_99_091:[Creates an AGENT_DATA_TYPE containing an Edm.DateTimeOffset from an EDM_DATE_TIME_OFFSET.]*/
+AGENT_DATA_TYPES_RESULT Create_AGENT_DATA_TYPE_from_EDM_DATE_TIME_OFFSET(AGENT_DATA_TYPE* agentData, EDM_DATE_TIME_OFFSET v)
+{
+    AGENT_DATA_TYPES_RESULT result;
+    /*Codes_SRS_AGENT_TYPE_SYSTEM_99_013:[ All the Create_... functions shall check their parameters for validity. When an invalid parameter is detected, a code of AGENT_DATA_TYPES_INVALID_ARG shall be returned ]*/
+    if (agentData == NULL)
+    {
+        result = AGENT_DATA_TYPES_INVALID_ARG;
+    }
+    else if (ValidateDate(v.dateTime.tm_year+1900, v.dateTime.tm_mon +1 , v.dateTime.tm_mday) != 0)
+    {
+        /*Codes_SRS_AGENT_TYPE_SYSTEM_99_092:[ The structure shall be validated to be conforming to OData specifications (odata-abnf-construction-rules, 2013), and if found invalid, AGENT_DATA_TYPES_INVALID_ARG shall be returned.]*/
+        result = AGENT_DATA_TYPES_INVALID_ARG;
+    }
+    else if (
+        (v.dateTime.tm_hour > 23) ||
+        (v.dateTime.tm_hour < 0) ||
+        (v.dateTime.tm_min > 59) ||
+        (v.dateTime.tm_min < 0) ||
+        (v.dateTime.tm_sec > 59) ||
+        (v.dateTime.tm_sec < 0)
+        )
+    {
+        /*Codes_SRS_AGENT_TYPE_SYSTEM_99_092:[ The structure shall be validated, and if found invalid, AGENT_DATA_TYPES_INVALID_ARG shall be returned.]*/
+        result = AGENT_DATA_TYPES_INVALID_ARG;
+    }
+    else if ((v.hasFractionalSecond) && (v.fractionalSecond > 999999999999))
+    {
+        /*Codes_SRS_AGENT_TYPE_SYSTEM_99_092:[ The structure shall be validated to be conforming to OData specifications (odata-abnf-construction-rules, 2013), and if found invalid, AGENT_DATA_TYPES_INVALID_ARG shall be returned.]*/
+        result = AGENT_DATA_TYPES_INVALID_ARG;
+    }
+    else if (
+        (v.hasTimeZone) &&
+        (
+            (v.timeZoneHour<-23) ||
+            (v.timeZoneHour>23) ||
+            (v.timeZoneMinute>59)
+        )
+    )
+    {
+        /*Codes_SRS_AGENT_TYPE_SYSTEM_99_092:[ The structure shall be validated to be conforming to OData specifications (odata-abnf-construction-rules, 2013), and if found invalid, AGENT_DATA_TYPES_INVALID_ARG shall be returned.]*/
+        result = AGENT_DATA_TYPES_INVALID_ARG;
+    }
+    else
+    {
+        agentData->type = EDM_DATE_TIME_OFFSET_TYPE;
+        agentData->value.edmDateTimeOffset = v;
+        result = AGENT_DATA_TYPES_OK;
+    }
+    return result;
+}
+
+/*Codes_SRS_AGENT_TYPE_SYSTEM_99_094:[ Creates and AGENT_DATA_TYPE containing a EDM_GUID from an EDM_GUID]*/
+AGENT_DATA_TYPES_RESULT Create_AGENT_DATA_TYPE_from_EDM_GUID(AGENT_DATA_TYPE* agentData, EDM_GUID v)
+{
+    AGENT_DATA_TYPES_RESULT result;
+    /*Codes_SRS_AGENT_TYPE_SYSTEM_99_013:[ All the functions shall check their parameters for validity. When an invalid parameter is detected, the value AGENT_DATA_TYPES_INVALID_ARG shall be returned ].*/
+    if (agentData == NULL)
+    {
+        result = AGENT_DATA_TYPES_INVALID_ARG;
+        LogError("result = %s ", MU_ENUM_TO_STRING(AGENT_DATA_TYPES_RESULT, result));
+    }
+    else
+    {
+        /*Codes_SRS_AGENT_TYPE_SYSTEM_99_094:[ Creates and AGENT_DATA_TYPE containing a EDM_GUID from an EDM_GUID]*/
+        agentData->type = EDM_GUID_TYPE;
+        memmove(agentData->value.edmGuid.GUID, v.GUID, 16);
+        result = AGENT_DATA_TYPES_OK;
+    }
+    return result;
+}
+
+/*Codes_SRS_AGENT_TYPE_SYSTEM_99_098:[ Creates an AGENT_DATA_TYPE containing a EDM_BINARY from a EDM_BINARY.]*/
+AGENT_DATA_TYPES_RESULT Create_AGENT_DATA_TYPE_from_EDM_BINARY(AGENT_DATA_TYPE* agentData, EDM_BINARY v)
+{
+    AGENT_DATA_TYPES_RESULT result;
+    /*Codes_SRS_AGENT_TYPE_SYSTEM_99_013:[ All the functions shall check their parameters for validity. When an invalid parameter is detected, the value AGENT_DATA_TYPES_INVALID_ARG shall be returned ].*/
+    if (agentData == NULL)
+    {
+        result = AGENT_DATA_TYPES_INVALID_ARG;
+        LogError("result = %s", MU_ENUM_TO_STRING(AGENT_DATA_TYPES_RESULT, result));
+    }
+    else
+    {
+        /*Codes_SRS_AGENT_TYPE_SYSTEM_99_098:[ Creates an AGENT_DATA_TYPE containing a EDM_BINARY from a EDM_BINARY.]*/
+        if (v.data == NULL)
+        {
+            if (v.size != 0)
+            {
+                result = AGENT_DATA_TYPES_INVALID_ARG;
+                LogError("result = %s ", MU_ENUM_TO_STRING(AGENT_DATA_TYPES_RESULT, result));
+            }
+            else
+            {
+                agentData->type = EDM_BINARY_TYPE;
+                agentData->value.edmBinary.size = 0;
+                agentData->value.edmBinary.data = NULL;
+                result = AGENT_DATA_TYPES_OK;
+            }
+        }
+        else
+        {
+            if (v.size != 0)
+            {
+                /*make a copy*/
+                if ((agentData->value.edmBinary.data = (unsigned char*)malloc(v.size)) == NULL)
+                {
+                    result = AGENT_DATA_TYPES_ERROR;
+                    LogError("result = %s", MU_ENUM_TO_STRING(AGENT_DATA_TYPES_RESULT, result));
+                }
+                else
+                {
+                    (void)memcpy(agentData->value.edmBinary.data, v.data, v.size);
+                    agentData->type = EDM_BINARY_TYPE;
+                    agentData->value.edmBinary.size = v.size;
+                    result = AGENT_DATA_TYPES_OK;
+                }
+            }
+            else
+            {
+                result = AGENT_DATA_TYPES_INVALID_ARG;
+                LogError("result = %s", MU_ENUM_TO_STRING(AGENT_DATA_TYPES_RESULT, result));
+            }
+        }
+    }
+    return result;
+}
+
+/*scans sign, if any*/
+/*if no sign, then it will set *sign to = +1*/
+/*if sign, then it will set *sign to = +/-1*/
+static void scanOptionalSign(const char* source, size_t sourceSize, size_t* position, int* sign)
+{
+    if (*position < sourceSize)
+    {
+        if (source[*position] == '-')
+        {
+
+            *sign = -1;
+            (*position)++;
+        }
+        else if (source[*position] == '+')
+        {
+            *sign = +1;
+            (*position)++;
+        }
+        else
+        {
+            *sign = +1;
+        }
+    }
+}
+
+/*scans a minus sign, if any*/
+/*if no sign, then it will set *sign to = +1*/
+/*if sign, then it will set *sign to = +/-1*/
+static void scanOptionalMinusSign(const char* source, size_t sourceSize, size_t* position, int* sign)
+{
+    if (*position < sourceSize)
+    {
+        if (source[*position] == '-')
+        {
+
+            *sign = -1;
+            (*position)++;
+        }
+        else
+        {
+            *sign = +1;
+        }
+    }
+}
+
+/*this function alawys returns 0 if it processed 1 digit*/
+/*return 1 when error (such as wrong parameters)*/
+static int scanMandatoryOneDigit(const char* source, size_t sourceSize, size_t* position)
+{
+    int result;
+    if (*position < sourceSize)
+    {
+        if (IS_DIGIT(source[*position]))
+        {
+            (*position)++;
+            result = 0;
+        }
+        else
+        {
+            result = 1;
+        }
+    }
+    else
+    {
+        result = 1;
+    }
+    return result;
+}
+
+/*scans digits, if any*/
+static void scanOptionalNDigits(const char* source, size_t sourceSize, size_t* position)
+{
+    while (*position < sourceSize)
+    {
+        if (IS_DIGIT(source[*position]))
+        {
+            (*position)++;
+        }
+        else
+        {
+            break;
+        }
+    }
+}
+
+/*from the string pointed to by source, having the size sourceSize, starting at initial position *position*/
+/*this function will attempt to read a decimal number having an optional sign(+/-) followed by precisely N digits */
+/*will return 0 if in the string there was a number and that number has been read in the *value parameter*/
+/*will update position parameter to reflect the first character not belonging to the number*/
+static int scanAndReadNDigitsInt(const char* source, size_t* position, int *value, size_t N)
+{
+    N++;
+    *value = 0;
+    while ((IS_DIGIT(source[*position])) &&
+        (N > 0))
+    {
+        *value *= 10;
+        *value += (source[*position] - '0');
+        (*position)++;
+        N--;
+    }
+
+    return N != 1;
+}
+
+/*this function alawys returns 0 if it found a dot followed by at least digit*/
+/*return 1 when error (such as wrong parameters)*/
+static int scanOptionalDotAndDigits(const char* source, size_t sourceSize, size_t* position)
+{
+    int result = 0;
+    if (*position < sourceSize)
+    {
+        if (source[*position] == '.')
+        {
+            (*position)++;
+            if (scanMandatoryOneDigit(source, sourceSize, position) != 0)
+            {
+                /* not a digit following the dot... */
+                result = 1;
+            }
+            else
+            {
+                scanOptionalNDigits(source, sourceSize, position);
+            }
+        }
+        else
+        {
+            /*not a dot, don't care*/
+        }
+    }
+    return result;
+}
+
+
+static int scanMandatory1CapitalHexDigit(const char* source, uint8_t* value)
+{
+    int result = 0;
+    if (('0' <= source[0]) && (source[0] <= '9'))
+    {
+        *value = (source[0] - '0');
+    }
+    else if (('A' <= source[0]) && (source[0] <= 'F'))
+    {
+        *value = (source[0] - 'A'+10);
+    }
+    else
+    {
+        result = 1;
+    }
+    return result;
+}
+
+/*this function alawys returns 0 if it found 2 hex digits, also updates the *value parameter*/
+/*return 1 when error (such as wrong parameters)*/
+static int scanMandatory2CapitalHexDigits(const char* source, uint8_t* value)
+{
+    int result;
+    uint8_t temp;
+    if (scanMandatory1CapitalHexDigit(source, &temp) == 0)
+    {
+        *value = temp*16;
+        if (scanMandatory1CapitalHexDigit(source + 1, &temp) == 0)
+        {
+            *value += temp;
+            result = 0;
+        }
+        else
+        {
+            result = 1;
+        }
+    }
+    else
+    {
+        result = 2;
+    }
+
+    return result;
+}
+
+static int ValidateDecimal(const char* v, size_t vlen)
+{
+    int result;
+    int sign = 0;
+    size_t validatePosition = 0;
+    scanOptionalSign(v, vlen, &validatePosition, &sign);
+    if (scanMandatoryOneDigit(v, vlen, &validatePosition) != 0)
+    {
+        result = 1;
+    }
+    else
+    {
+        scanOptionalNDigits(v, vlen, &validatePosition);
+        if (scanOptionalDotAndDigits(v, vlen, &validatePosition) != 0)
+        {
+            /*Codes_SRS_AGENT_TYPE_SYSTEM_99_067:[ If the string indicated by the parameter v does not match exactly an ODATA string representation, AGENT_DATA_TYPES_INVALID_ARG shall be returned.]*/
+            result = 1;
+        }
+        else if (validatePosition != vlen) /*Trailing wrong characters*/
+        {
+            /*Codes_SRS_AGENT_TYPE_SYSTEM_99_067:[ If the string indicated by the parameter v does not match exactly an ODATA string representation, AGENT_DATA_TYPES_INVALID_ARG shall be returned.]*/
+            result = 1;
+        }
+        else
+        {
+            result = 0;
+        }
+    }
+
+    return result;
+}
+
+/*return 0 if everything went ok*/
+/*takes 1 base64char and returns its value*/
+static int base64toValue(char base64charSource, unsigned char* value)
+{
+    int result;
+    if (('A' <= base64charSource) && (base64charSource <= 'Z'))
+    {
+        *value = base64charSource - 'A';
+        result = 0;
+    }
+    else if (('a' <= base64charSource) && (base64charSource <= 'z'))
+    {
+        *value = ('Z' - 'A') +1+ (base64charSource - 'a');
+        result = 0;
+    }
+    else if (('0' <= base64charSource) && (base64charSource <= '9'))
+    {
+        *value = ('Z' - 'A') +1+('z'-'a')+1 +(base64charSource - '0');
+        result = 0;
+    }
+    else if ('-' == base64charSource)
+    {
+        *value = 62;
+        result = 0;
+    }
+    else if ('_' == base64charSource)
+    {
+        *value = 63;
+        result = 0;
+    }
+    else
+    {
+        result = 1;
+    }
+    return result;
+}
+
+/*returns 0 if everything went ok*/
+/*scans 4 base64 characters and returns 3 usual bytes*/
+static int scan4base64char(const char* source, size_t sourceSize, unsigned char *destination0, unsigned char* destination1, unsigned char* destination2)
+{
+    int result;
+    if (sourceSize < 4)
+    {
+        result = 1;
+    }
+    else
+    {
+        unsigned char b0, b1, b2, b3;
+        if (
+            (base64toValue(source[0], &b0) == 0) &&
+            (base64toValue(source[1], &b1) == 0) &&
+            (base64toValue(source[2], &b2) == 0) &&
+            (base64toValue(source[3], &b3) == 0)
+            )
+        {
+            *destination0 = (b0 << 2) | ((b1 & 0x30) >> 4);
+            *destination1 = ((b1 & 0x0F)<<4) | ((b2 & 0x3C) >>2 );
+            *destination2 = ((b2 & 0x03) << 6) | (b3);
+            result = 0;
+        }
+        else
+        {
+            result = 2;
+        }
+    }
+    return result;
+}
+
+/*return 0 if the character is one of ( 'A' / 'E' / 'I' / 'M' / 'Q' / 'U' / 'Y' / 'c' / 'g' / 'k' / 'o' / 's' / 'w' / '0' / '4' / '8' )*/
+static int base64b16toValue(unsigned char source, unsigned char* destination)
+{
+    unsigned char i;
+    for (i = 0; i <= 15; i++)
+    {
+        if (base64b16(i) == source)
+        {
+            *destination = i;
+            return 0;
+        }
+    }
+    return 1;
+}
+
+/*return 0 if the character is one of ( 'A' / 'Q' / 'g' / 'w' )*/
+static int base64b8toValue(unsigned char source, unsigned char* destination)
+{
+    unsigned char i;
+    for (i = 0; i <= 3; i++)
+    {
+        if (base64b8(i) == source)
+        {
+            *destination = i;
+            return 0;
+        }
+    }
+    return 1;
+}
+
+
+/*returns 0 if everything went ok*/
+/*scans 2 base64 characters + 1 special + 1 optional = and returns 2 usual bytes*/
+int scanbase64b16(const char* source, size_t sourceSize, size_t *consumed, unsigned char* destination0, unsigned char* destination1)
+{
+    int result;
+    if (sourceSize < 3)
+    {
+        result = 1;
+    }
+    else
+    {
+        unsigned char c0, c1, c2;
+        *consumed = 0;
+        if (
+            (base64toValue(source[0], &c0) == 0) &&
+            (base64toValue(source[1], &c1) == 0) &&
+            (base64b16toValue(source[2], &c2) == 0)
+            )
+        {
+            *consumed = 3 + ((sourceSize>=3)&&(source[3] == '=')); /*== produce 1 or 0 ( in C )*/
+            *destination0 = (c0 << 2) | ((c1 & 0x30) >> 4);
+            *destination1 = ((c1 &0x0F) <<4) | c2;
+            result = 0;
+        }
+        else
+        {
+            result = 2;
+        }
+    }
+    return result;
+}
+
+/*return 0 if everything is ok*/
+/*Reads base64b8    = base64char ( 'A' / 'Q' / 'g' / 'w' ) [ "==" ]*/
+int scanbase64b8(const char* source, size_t sourceSize, size_t *consumed, unsigned char* destination0)
+{
+    int result;
+    if (sourceSize < 2)
+    {
+        result = 1;
+    }
+    else
+    {
+        unsigned char c0, c1;
+        if (
+            (base64toValue(source[0], &c0) == 0) &&
+            (base64b8toValue(source[1], &c1) == 0)
+            )
+        {
+            *consumed = 2 + (((sourceSize>=4) && (source[2] == '=') && (source[3] == '='))?2:0); /*== produce 1 or 0 ( in C )*/
+            *destination0 = (c0 << 2) | (c1 & 3);
+            result = 0;
+        }
+        else
+        {
+            result = 2;
+        }
+    }
+    return result;
+}
+
+/*Codes_SRS_AGENT_TYPE_SYSTEM_99_039:[ Creates an AGENT_DATA_TYPE containing an EDM_DECIMAL from a null-terminated string.]*/
+AGENT_DATA_TYPES_RESULT Create_EDM_DECIMAL_from_charz(AGENT_DATA_TYPE* agentData, const char* v)
+{
+    AGENT_DATA_TYPES_RESULT result;
+    /*Codes_SRS_AGENT_TYPE_SYSTEM_99_013:[ All the Create_... functions shall check their parameters for validity. When an invalid parameter is detected, a code of AGENT_DATA_TYPES_INVALID_ARG shall be returned ].*/
+    if (agentData == NULL)
+    {
+        result = AGENT_DATA_TYPES_INVALID_ARG;
+        LogError("(result = %s)", MU_ENUM_TO_STRING(AGENT_DATA_TYPES_RESULT, result));
+    }
+    else if (v == NULL)
+    {
+        result = AGENT_DATA_TYPES_INVALID_ARG;
+        LogError("(result = %s)", MU_ENUM_TO_STRING(AGENT_DATA_TYPES_RESULT, result));
+    }
+    else
+    {
+        size_t vlen = strlen(v);
+        /*validate that v has the form [SIGN] 1*DIGIT ["." 1*DIGIT]*/
+        if (vlen == 0)
+        {
+            /*Codes_SRS_AGENT_TYPE_SYSTEM_99_067:[ If the string indicated by the parameter v does not match exactly an ODATA string representation, AGENT_DATA_TYPES_INVALID_ARG shall be returned.]*/
+            result = AGENT_DATA_TYPES_INVALID_ARG;
+            LogError("(result = %s)", MU_ENUM_TO_STRING(AGENT_DATA_TYPES_RESULT, result));
+        }
+        else
+        {
+            if (ValidateDecimal(v, vlen) != 0)
+            {
+                /*Codes_SRS_AGENT_TYPE_SYSTEM_99_067:[ If the string indicated by the parameter v does not match exactly an ODATA string representation, AGENT_DATA_TYPES_INVALID_ARG shall be returned.]*/
+                result = AGENT_DATA_TYPES_INVALID_ARG;
+                LogError("(result = %s)", MU_ENUM_TO_STRING(AGENT_DATA_TYPES_RESULT, result));
+            }
+            else if ((agentData->value.edmDecimal.value = STRING_construct(v)) == NULL)
+            {
+                result = AGENT_DATA_TYPES_ERROR;
+                LogError("(result = %s)", MU_ENUM_TO_STRING(AGENT_DATA_TYPES_RESULT, result));
+            }
+            else
+            {
+                agentData->type = EDM_DECIMAL_TYPE;
+                result = AGENT_DATA_TYPES_OK;
+            }
+        }
+    }
+    return result;
+}
+
+/*create an AGENT_DATA_TYPE containing an EDM_DOUBLE from a double*/
+AGENT_DATA_TYPES_RESULT Create_AGENT_DATA_TYPE_from_DOUBLE(AGENT_DATA_TYPE* agentData, double v)
+{
+    AGENT_DATA_TYPES_RESULT result;
+    /*Codes_SRS_AGENT_TYPE_SYSTEM_99_013:[All the Create_... functions shall check their parameters for validity.When an invalid parameter is detected, a code of AGENT_DATA_TYPES_INVALID_ARG shall be returned]*/
+    if(agentData==NULL)
+    {
+        result = AGENT_DATA_TYPES_INVALID_ARG;
+        LogError("(result = %s)", MU_ENUM_TO_STRING(AGENT_DATA_TYPES_RESULT, result));
+    }
+    else
+    {
+        /*Codes_SRS_AGENT_TYPE_SYSTEM_99_041:[Creates an AGENT_DATA_TYPE containing an EDM_DOUBLE from double]*/
+        /*Codes_SRS_AGENT_TYPE_SYSTEM_99_042:[Values of NaN, -INF, +INF are accepted]*/
+        agentData->type = EDM_DOUBLE_TYPE;
+        agentData->value.edmDouble.value = v;
+        result = AGENT_DATA_TYPES_OK;
+    }
+    return result;
+}
+
+/*create an AGENT_DATA_TYPE from INT16_T*/
+/*Codes_SRS_AGENT_TYPE_SYSTEM_99_043:[ Creates an AGENT_DATA_TYPE containing an EDM_INT16 from int16_t]*/
+AGENT_DATA_TYPES_RESULT Create_AGENT_DATA_TYPE_from_SINT16(AGENT_DATA_TYPE* agentData, int16_t v)
+{
+    AGENT_DATA_TYPES_RESULT result;
+    /*Codes_SRS_AGENT_TYPE_SYSTEM_99_013:[ All the Create_... functions shall check their parameters for validity. When an invalid parameter is detected, a code of AGENT_DATA_TYPES_INVALID_ARG shall be returned ].*/
+    if (agentData == NULL)
+    {
+        result = AGENT_DATA_TYPES_INVALID_ARG;
+        LogError("(result = %s)", MU_ENUM_TO_STRING(AGENT_DATA_TYPES_RESULT, result));
+    }
+    else
+    {
+        agentData->type = EDM_INT16_TYPE;
+        agentData->value.edmInt16.value = v;
+        result = AGENT_DATA_TYPES_OK;
+    }
+    return result;
+}
+
+/*create an AGENT_DATA_TYPE from INT32_T*/
+AGENT_DATA_TYPES_RESULT Create_AGENT_DATA_TYPE_from_SINT32(AGENT_DATA_TYPE* agentData, int32_t v)
+{
+    AGENT_DATA_TYPES_RESULT result;
+    /*Codes_SRS_AGENT_TYPE_SYSTEM_99_013:[ All the Create_... functions shall check their parameters for validity. When an invalid parameter is detected, a code of AGENT_DATA_TYPES_INVALID_ARG shall be returned ].*/
+    if (agentData == NULL)
+    {
+        result = AGENT_DATA_TYPES_INVALID_ARG;
+        LogError("(result = %s)", MU_ENUM_TO_STRING(AGENT_DATA_TYPES_RESULT, result));
+    }
+    else
+    {
+        agentData->type = EDM_INT32_TYPE;
+        agentData->value.edmInt32.value = v;
+        result = AGENT_DATA_TYPES_OK;
+    }
+    return result;
+}
+
+/*create an AGENT_DATA_TYPE from INT64_T*/
+/*Codes_SRS_AGENT_TYPE_SYSTEM_99_045:[ Creates an AGENT_DATA_TYPE containing an EDM_INT64 from int64_t]*/
+AGENT_DATA_TYPES_RESULT Create_AGENT_DATA_TYPE_from_SINT64(AGENT_DATA_TYPE* agentData, int64_t v)
+{
+    AGENT_DATA_TYPES_RESULT result;
+    /*Codes_SRS_AGENT_TYPE_SYSTEM_99_013:[ All the Create_... functions shall check their parameters for validity. When an invalid parameter is detected, a code of AGENT_DATA_TYPES_INVALID_ARG shall be returned ].*/
+    if (agentData == NULL)
+    {
+        result = AGENT_DATA_TYPES_INVALID_ARG;
+        LogError("(result = %s)", MU_ENUM_TO_STRING(AGENT_DATA_TYPES_RESULT, result));
+
+    }
+    else
+    {
+        agentData->type = EDM_INT64_TYPE;
+        agentData->value.edmInt64.value = v;
+        result = AGENT_DATA_TYPES_OK;
+    }
+    return result;
+}
+
+/*create an AGENT_DATA_TYPE from int8_t*/
+AGENT_DATA_TYPES_RESULT Create_AGENT_DATA_TYPE_from_SINT8(AGENT_DATA_TYPE* agentData, int8_t v)
+{
+    AGENT_DATA_TYPES_RESULT result;
+    /*Codes_SRS_AGENT_TYPE_SYSTEM_99_013:[ All the Create_... functions shall check their parameters for validity. When an invalid parameter is detected, a code of AGENT_DATA_TYPES_INVALID_ARG shall be returned ].*/
+    if (agentData == NULL)
+    {
+        result = AGENT_DATA_TYPES_INVALID_ARG;
+        LogError("(result = %s)", MU_ENUM_TO_STRING(AGENT_DATA_TYPES_RESULT, result));
+
+    }
+    else
+    {
+        agentData->type = EDM_SBYTE_TYPE;
+        agentData->value.edmSbyte.value = v;
+        result = AGENT_DATA_TYPES_OK;
+    }
+    return result;
+}
+
+static int ValidateDate(int year, int month, int day)
+{
+    int result;
+
+    if ((year <= -10000) || (year >= 10000))
+    {
+        result = 1;
+    }
+    else
+    {
+        /*Codes_SRS_AGENT_TYPE_SYSTEM_99_070:[ If year-month-date does not indicate a valid day (for example 31 Feb 2013), then AGENT_DATA_TYPES_INVALID_ARG shall be returned.]*/
+        if (day <= 0)
+        {
+            result = 1;
+        }
+        else
+        {
+            /*the following data will be validated...*/
+            /*leap years are those that can be divided by 4. But if the year can be divided by 100, it is not leap. But if they year can be divided by 400 it is leap*/
+            if (
+                (month == 1) || /*these months have always 31 days*/
+                (month == 3) ||
+                (month == 5) ||
+                (month == 7) ||
+                (month == 8) ||
+                (month == 10) ||
+                (month == 12)
+                )
+            {
+                if (day <= 31)
+                {
+                    result = 0;
+                }
+                else
+                {
+                    /*Codes_SRS_AGENT_TYPE_SYSTEM_99_070:[If year - month - date does not indicate a valid day(for example 31 Feb 2013), then AGENT_DATA_TYPES_INVALID_ARG shall be returned.]*/
+                    result = 1;
+                }
+            }
+            else if (
+                (month == 4) ||
+                (month == 6) ||
+                (month == 9) ||
+                (month == 11)
+                )
+            {
+                if (day <= 30)
+                {
+                    result = 0;
+                }
+                else
+                {
+                    /*Codes_SRS_AGENT_TYPE_SYSTEM_99_070:[If year - month - date does not indicate a valid day(for example 31 Feb 2013), then AGENT_DATA_TYPES_INVALID_ARG shall be returned.]*/
+                    result = -1;
+                }
+            }
+            else if (month == 2)/*february*/
+            {
+                if ((year % 400) == 0)
+                {
+                    /*these are leap years, suchs as 2000*/
+                    if (day <= 29)
+                    {
+                        result = 0;
+                    }
+                    else
+                    {
+                        /*Codes_SRS_AGENT_TYPE_SYSTEM_99_070:[If year - month - date does not indicate a valid day(for example 31 Feb 2013), then AGENT_DATA_TYPES_INVALID_ARG shall be returned.]*/
+                        result = 1;
+                    }
+                }
+                else if ((year % 100) == 0)
+                {
+                    /*non-leap year, such as 1900*/
+                    if (day <= 28)
+                    {
+                        result = 0;
+                    }
+                    else
+                    {
+                        /*Codes_SRS_AGENT_TYPE_SYSTEM_99_070:[If year - month - date does not indicate a valid day(for example 31 Feb 2013), then AGENT_DATA_TYPES_INVALID_ARG shall be returned.]*/
+                        result = 1;
+                    }
+                }
+                else if ((year % 4) == 0)
+                {
+                    /*these are leap years, such as 2104*/
+                    if (day <= 29)
+                    {
+                        result = 0;
+                    }
+                    else
+                    {
+                        /*Codes_SRS_AGENT_TYPE_SYSTEM_99_070:[If year - month - date does not indicate a valid day(for example 31 Feb 2013), then AGENT_DATA_TYPES_INVALID_ARG shall be returned.]*/
+                        result = 1;
+                    }
+                }
+                else
+                {
+                    /*certainly not a leap year*/
+                    if (day <= 28)
+                    {
+                        result = 0;
+                    }
+                    else
+                    {
+                        /*Codes_SRS_AGENT_TYPE_SYSTEM_99_070:[If year - month - date does not indicate a valid day(for example 31 Feb 2013), then AGENT_DATA_TYPES_INVALID_ARG shall be returned.]*/
+                        result = 1;
+                    }
+                }
+            }
+            else
+            {
+                /*Codes_SRS_AGENT_TYPE_SYSTEM_99_070:[If year - month - date does not indicate a valid day(for example 31 Feb 2013), then AGENT_DATA_TYPES_INVALID_ARG shall be returned.]*/
+                result = 1;
+            }
+        }
+    }
+
+    return result;
+}
+
+/*Codes_SRS_AGENT_TYPE_SYSTEM_99_069:[ Creates an AGENT_DATA_TYPE containing an EDM_DATE from a year, a month and a day of the month.]*/
+AGENT_DATA_TYPES_RESULT Create_AGENT_DATA_TYPE_from_date(AGENT_DATA_TYPE* agentData, int16_t year, uint8_t month, uint8_t day)
+{
+    AGENT_DATA_TYPES_RESULT result;
+    /*Codes_SRS_AGENT_TYPE_SYSTEM_99_013:[ All the Create_... functions shall check their parameters for validity. When an invalid parameter is detected, a code of AGENT_DATA_TYPES_INVALID_ARG shall be returned ].*/
+    if (agentData == NULL)
+    {
+        result = AGENT_DATA_TYPES_INVALID_ARG;
+        LogError("(result = %s)", MU_ENUM_TO_STRING(AGENT_DATA_TYPES_RESULT, result));
+    }
+    /*ODATA-ABNF: year  = [ "-" ] ( "0" 3DIGIT / oneToNine 3*DIGIT )*/
+    else if (ValidateDate(year, month, day) != 0)
+    {
+        result = AGENT_DATA_TYPES_INVALID_ARG;
+        LogError("(result = %s)", MU_ENUM_TO_STRING(AGENT_DATA_TYPES_RESULT, result));
+    }
+    else
+    {
+        /*Codes_SRS_AGENT_TYPE_SYSTEM_99_069:[ Creates an AGENT_DATA_TYPE containing an EDM_DATE from a year, a month and a day of the month.]*/
+        agentData->type = EDM_DATE_TYPE;
+        agentData->value.edmDate.year = year;
+        agentData->value.edmDate.month = month;
+        agentData->value.edmDate.day = day;
+        result = AGENT_DATA_TYPES_OK;
+    }
+
+    return result;
+}
+
+
+/*create an AGENT_DATA_TYPE from SINGLE*/
+AGENT_DATA_TYPES_RESULT Create_AGENT_DATA_TYPE_from_FLOAT(AGENT_DATA_TYPE* agentData, float v)
+{
+    AGENT_DATA_TYPES_RESULT result;
+    /*Codes_SRS_AGENT_TYPE_SYSTEM_99_013:[All the Create_... functions shall check their parameters for validity.When an invalid parameter is detected, a code of AGENT_DATA_TYPES_INVALID_ARG shall be returned]*/
+    if(agentData==NULL)
+    {
+        result = AGENT_DATA_TYPES_INVALID_ARG;
+        LogError("(result = %s)", MU_ENUM_TO_STRING(AGENT_DATA_TYPES_RESULT, result));
+    }
+    else
+    {
+        agentData->type = EDM_SINGLE_TYPE;
+        agentData->value.edmSingle.value = v;
+        result = AGENT_DATA_TYPES_OK;
+    }
+    return result;
+}
+
+const char hexToASCII[16] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
+
+/*create an AGENT_DATA_TYPE from ANSI zero terminated string*/
+AGENT_DATA_TYPES_RESULT Create_AGENT_DATA_TYPE_from_charz(AGENT_DATA_TYPE* agentData, const char* v)
+{
+    AGENT_DATA_TYPES_RESULT result = AGENT_DATA_TYPES_OK;
+    /*Codes_SRS_AGENT_TYPE_SYSTEM_99_013:[ All the Create_... functions shall check their parameters for validity. When an invalid parameter is detected, a code of AGENT_DATA_TYPES_INVALID_ARG shall be returned ].*/
+    if (agentData == NULL)
+    {
+        result = AGENT_DATA_TYPES_INVALID_ARG;
+        LogError("(result = %s)", MU_ENUM_TO_STRING(AGENT_DATA_TYPES_RESULT, result));
+    }
+    else if (v == NULL)
+    {
+        result = AGENT_DATA_TYPES_INVALID_ARG;
+        LogError("(result = %s)", MU_ENUM_TO_STRING(AGENT_DATA_TYPES_RESULT, result));
+    }
+    else
+    {
+        /*Codes_SRS_AGENT_TYPE_SYSTEM_99_049:[ Creates an AGENT_DATA_TYPE containing an EDM_STRING from an ASCII zero terminated string.]*/
+        agentData->type = EDM_STRING_TYPE;
+        if (mallocAndStrcpy_s(&agentData->value.edmString.chars, v) != 0)
+        {
+            result = AGENT_DATA_TYPES_ERROR;
+            LogError("(result = %s)", MU_ENUM_TO_STRING(AGENT_DATA_TYPES_RESULT, result));
+        }
+        else
+        {
+            agentData->value.edmString.length = strlen(agentData->value.edmString.chars);
+            result = AGENT_DATA_TYPES_OK;
+        }
+    }
+    return result;
+}
+
+/*create an AGENT_DATA_TYPE from ANSI zero terminated string (without quotes) */
+AGENT_DATA_TYPES_RESULT Create_AGENT_DATA_TYPE_from_charz_no_quotes(AGENT_DATA_TYPE* agentData, const char* v)
+{
+    AGENT_DATA_TYPES_RESULT result = AGENT_DATA_TYPES_OK;
+    /*Codes_SRS_AGENT_TYPE_SYSTEM_99_013:[ All the Create_... functions shall check their parameters for validity. When an invalid parameter is detected, a code of AGENT_DATA_TYPES_INVALID_ARG shall be returned ].*/
+    if (agentData == NULL)
+    {
+        result = AGENT_DATA_TYPES_INVALID_ARG;
+        LogError("(result = %s)", MU_ENUM_TO_STRING(AGENT_DATA_TYPES_RESULT, result));
+    }
+    else if (v == NULL)
+    {
+        result = AGENT_DATA_TYPES_INVALID_ARG;
+        LogError("(result = %s)", MU_ENUM_TO_STRING(AGENT_DATA_TYPES_RESULT, result));
+    }
+    else
+    {
+        /* Codes_SRS_AGENT_TYPE_SYSTEM_01_001: [Creates an AGENT_DATA_TYPE containing an EDM_STRING from an ASCII zero terminated string.] */
+        agentData->type = EDM_STRING_NO_QUOTES_TYPE;
+        if (mallocAndStrcpy_s(&agentData->value.edmStringNoQuotes.chars, v) != 0)
+        {
+            result = AGENT_DATA_TYPES_ERROR;
+            LogError("(result = %s)", MU_ENUM_TO_STRING(AGENT_DATA_TYPES_RESULT, result));
+        }
+        else
+        {
+            agentData->value.edmStringNoQuotes.length = strlen(agentData->value.edmStringNoQuotes.chars);
+            result = AGENT_DATA_TYPES_OK;
+        }
+    }
+    return result;
+}
+
+void Destroy_AGENT_DATA_TYPE(AGENT_DATA_TYPE* agentData)
+{
+    if(agentData==NULL)
+    {
+        LogError("agentData was NULL.");
+    }
+    else
+    {
+        switch(agentData->type)
+        {
+            default:
+            {
+                LogError("invalid agentData");
+                break;
+            }
+            case(EDM_NO_TYPE):
+            {
+                LogError("invalid agentData");
+                break;
+            }
+            case(EDM_BINARY_TYPE):
+            {
+                /*destroying means maybe deallocating some memory*/
+                free(agentData->value.edmBinary.data); /* If ptr is a null pointer, no action occurs*/
+                agentData->value.edmBinary.data = NULL;
+                break;
+            }
+            case(EDM_BOOLEAN_TYPE):
+            {
+                /*nothing to do*/
+                break;
+            }
+            case(EDM_BYTE_TYPE):
+            {
+                /*nothing to do*/
+                break;
+            }
+            case(EDM_DATE_TYPE):
+            {
+                /*nothing to do*/
+                break;
+            }
+            case(EDM_DATE_TIME_OFFSET_TYPE):
+            {
+                /*nothing to do*/
+                break;
+            }
+            case(EDM_DECIMAL_TYPE):
+            {
+                STRING_delete(agentData->value.edmDecimal.value);
+                agentData->value.edmDecimal.value = NULL;
+                break;
+            }
+            case(EDM_DURATION_TYPE):
+            {
+                LogError("EDM_DURATION_TYPE not implemented");
+                break;
+            }
+            case(EDM_GUID_TYPE):
+            {
+                /*nothing to do*/
+                break;
+            }
+            case(EDM_INT16_TYPE):
+            {
+                /*nothing to do*/
+                break;
+            }
+            case(EDM_INT32_TYPE):
+            {
+                /*nothing to do*/
+                break;
+            }
+            case(EDM_INT64_TYPE):
+            {
+                /*nothing to do*/
+                break;
+            }
+            case(EDM_SBYTE_TYPE):
+            {
+                /*nothing to do*/
+                break;
+            }
+            case(EDM_STREAM):
+            {
+                LogError("EDM_STREAM not implemented");
+                break;
+            }
+            case(EDM_STRING_TYPE):
+            {
+                if (agentData->value.edmString.chars != NULL)
+                {
+                    free(agentData->value.edmString.chars);
+                    agentData->value.edmString.chars = NULL;
+                }
+                break;
+            }
+            case(EDM_STRING_NO_QUOTES_TYPE) :
+            {
+                if (agentData->value.edmStringNoQuotes.chars != NULL)
+                {
+                    free(agentData->value.edmStringNoQuotes.chars);
+                    agentData->value.edmStringNoQuotes.chars = NULL;
+                }
+                break;
+            }
+            case(EDM_TIME_OF_DAY_TYPE) :
+            {
+                LogError("EDM_TIME_OF_DAY_TYPE not implemented");
+                break;
+            }
+            case(EDM_GEOGRAPHY_TYPE):
+            {
+                LogError("EDM_GEOGRAPHY_TYPE not implemented");
+                break;
+            }
+            case(EDM_GEOGRAPHY_POINT_TYPE):
+            {
+                LogError("EDM_GEOGRAPHY_POINT_TYPE not implemented");
+                break;
+            }
+            case(EDM_GEOGRAPHY_LINE_STRING_TYPE):
+            {
+                LogError("EDM_GEOGRAPHY_LINE_STRING_TYPE not implemented");
+                break;
+            }
+            case(EDM_GEOGRAPHY_POLYGON_TYPE):
+            {
+                LogError("EDM_GEOGRAPHY_POLYGON_TYPE not implemented");
+                break;
+            }
+            case(EDM_GEOGRAPHY_MULTI_POINT_TYPE):
+            {
+                LogError("EDM_GEOGRAPHY_MULTI_POINT_TYPE not implemented");
+                break;
+            }
+            case(EDM_GEOGRAPHY_MULTI_LINE_STRING_TYPE):
+            {
+                LogError("EDM_GEOGRAPHY_MULTI_LINE_STRING_TYPE not implemented");
+                break;
+            }
+            case(EDM_GEOGRAPHY_MULTI_POLYGON_TYPE):
+            {
+                LogError("EDM_GEOGRAPHY_MULTI_POLYGON_TYPE");
+                break;
+            }
+            case(EDM_GEOGRAPHY_COLLECTION_TYPE):
+            {
+                LogError("EDM_GEOGRAPHY_COLLECTION_TYPE not implemented");
+                break;
+            }
+            case(EDM_GEOMETRY_TYPE):
+            {
+                LogError("EDM_GEOMETRY_TYPE not implemented");
+                break;
+            }
+            case(EDM_GEOMETRY_POINT_TYPE):
+            {
+                LogError("EDM_GEOMETRY_POINT_TYPE not implemented");
+                break;
+            }
+            case(EDM_GEOMETRY_LINE_STRING_TYPE):
+            {
+                LogError("EDM_GEOMETRY_LINE_STRING_TYPE not implemented");
+                break;
+            }
+            case(EDM_GEOMETRY_POLYGON_TYPE):
+            {
+                LogError("EDM_GEOMETRY_POLYGON_TYPE not implemented");
+                break;
+            }
+            case(EDM_GEOMETRY_MULTI_POINT_TYPE):
+            {
+                LogError("EDM_GEOMETRY_MULTI_POINT_TYPE not implemented");
+                break;
+            }
+            case(EDM_GEOMETRY_MULTI_LINE_STRING_TYPE):
+            {
+                LogError("EDM_GEOMETRY_MULTI_LINE_STRING_TYPE not implemented");
+                break;
+            }
+            case(EDM_GEOMETRY_MULTI_POLYGON_TYPE):
+            {
+                LogError("EDM_GEOMETRY_MULTI_POLYGON_TYPE not implemented");
+                break;
+            }
+            case(EDM_GEOMETRY_COLLECTION_TYPE):
+            {
+                LogError("EDM_GEOMETRY_COLLECTION_TYPE not implemented");
+                break;
+            }
+            case(EDM_SINGLE_TYPE):
+            {
+                break;
+            }
+            case(EDM_DOUBLE_TYPE):
+            {
+                break;
+            }
+            case (EDM_COMPLEX_TYPE_TYPE):
+            {
+                /*Codes_SRS_AGENT_TYPE_SYSTEM_99_050:[Destroy_AGENT_DATA_TYPE shall deallocate all allocated resources used to represent the type.]*/
+                size_t i;
+                for (i = 0; i < agentData->value.edmComplexType.nMembers; i++)
+                {
+                    free((void*)(agentData->value.edmComplexType.fields[i].fieldName));
+                    agentData->value.edmComplexType.fields[i].fieldName = NULL;
+                    Destroy_AGENT_DATA_TYPE(agentData->value.edmComplexType.fields[i].value);
+                    free(agentData->value.edmComplexType.fields[i].value);
+                    agentData->value.edmComplexType.fields[i].value = NULL;
+                }
+                free(agentData->value.edmComplexType.fields);
+                break;
+            }
+        }
+        agentData->type = EDM_NO_TYPE; /*mark as detroyed*/
+    }
+}
+
+static char hexDigitToChar(uint8_t hexDigit)
+{
+    if (hexDigit < 10) return '0' + hexDigit;
+    else return ('A' - 10) + hexDigit;
+}
+
+AGENT_DATA_TYPES_RESULT AgentDataTypes_ToString(STRING_HANDLE destination, const AGENT_DATA_TYPE* value)
+{
+    AGENT_DATA_TYPES_RESULT result;
+
+    /*Codes_SRS_AGENT_TYPE_SYSTEM_99_015:[If destination parameter is NULL, AgentDataTypes_ToString shall return AGENT_DATA_TYPES_INVALID_ARG.]*/
+    if(destination == NULL)
+    {
+        result = AGENT_DATA_TYPES_INVALID_ARG;
+        LogError("(result = %s)", MU_ENUM_TO_STRING(AGENT_DATA_TYPES_RESULT, result));
+    }
+    /*Codes_SRS_AGENT_TYPE_SYSTEM_99_053:[ If value is NULL or has been destroyed or otherwise doesn't contain valid data, AGENT_DATA_TYPES_INVALID_ARG shall be returned.]*/
+    else if (value == NULL)
+    {
+        result = AGENT_DATA_TYPES_INVALID_ARG;
+        LogError("(result = %s)", MU_ENUM_TO_STRING(AGENT_DATA_TYPES_RESULT, result));
+    }
+    else
+    {
+        switch(value->type)
+        {
+            default:
+            {
+                result = AGENT_DATA_TYPES_INVALID_ARG;
+                LogError("(result = %s)", MU_ENUM_TO_STRING(AGENT_DATA_TYPES_RESULT, result));
+                break;
+            }
+        case(EDM_NULL_TYPE) :
+            {
+                /*SRS_AGENT_TYPE_SYSTEM_99_101:[ EDM_NULL_TYPE shall return the unquoted string null.]*/
+                if (STRING_concat(destination, "null") != 0)
+                {
+                    /*Codes_SRS_AGENT_TYPE_SYSTEM_99_016:[ When the value cannot be converted to a string AgentDataTypes_ToString shall return AGENT_DATA_TYPES_ERROR.]*/
+                    result = AGENT_DATA_TYPES_ERROR;
+                    LogError("(result = %s)", MU_ENUM_TO_STRING(AGENT_DATA_TYPES_RESULT, result));
+                }
+                else
+                {
+                    /*Codes_SRS_AGENT_TYPE_SYSTEM_99_014:[ All functions shall return AGENT_DATA_TYPES_OK when the processing is successful.]*/
+                    result = AGENT_DATA_TYPES_OK;
+                }
+                break;
+            }
+        case(EDM_BOOLEAN_TYPE) :
+            {
+                /*Codes_SRS_AGENT_TYPE_SYSTEM_99_017:[EDM_BOOLEAN:as in(odata - abnf - construction - rules, 2013), booleanValue = "true" / "false"]*/
+                if (value->value.edmBoolean.value == EDM_TRUE)
+                {
+                    /*SRS_AGENT_TYPE_SYSTEM_99_030:[If v is different than 0 then the AGENT_DATA_TYPE shall have the value "true".]*/
+                    if (STRING_concat(destination, "true") != 0)
+                    {
+                        /*Codes_SRS_AGENT_TYPE_SYSTEM_99_016:[ When the value cannot be converted to a string AgentDataTypes_ToString shall return AGENT_DATA_TYPES_ERROR.]*/
+                        result = AGENT_DATA_TYPES_ERROR;
+                        LogError("(result = %s)", MU_ENUM_TO_STRING(AGENT_DATA_TYPES_RESULT, result));
+                    }
+                    else
+                    {
+                        /*Codes_SRS_AGENT_TYPE_SYSTEM_99_014:[ All functions shall return AGENT_DATA_TYPES_OK when the processing is successful.]*/
+                        result = AGENT_DATA_TYPES_OK;
+                    }
+                }
+                /*Codes_SRS_AGENT_TYPE_SYSTEM_99_017:[EDM_BOOLEAN:as in(odata - abnf - construction - rules, 2013), booleanValue = "true" / "false"]*/
+                else if (value->value.edmBoolean.value == EDM_FALSE)
+                {
+                    /*Codes_SRS_AGENT_TYPE_SYSTEM_99_029:[ If v 0 then the AGENT_DATA_TYPE shall have the value "false" Boolean.]*/
+                    if (STRING_concat(destination, "false") != 0)
+                    {
+                        /*Codes_SRS_AGENT_TYPE_SYSTEM_99_016:[ When the value cannot be converted to a string AgentDataTypes_ToString shall return AGENT_DATA_TYPES_ERROR.]*/
+                        result = AGENT_DATA_TYPES_ERROR;
+                        LogError("(result = %s)", MU_ENUM_TO_STRING(AGENT_DATA_TYPES_RESULT, result));
+                    }
+                    else
+                    {
+                        /*Codes_SRS_AGENT_TYPE_SYSTEM_99_014:[ All functions shall return AGENT_DATA_TYPES_OK when the processing is successful.]*/
+                        result = AGENT_DATA_TYPES_OK;
+                    }
+                }
+                else
+                {
+                    /*Codes_SRS_AGENT_TYPE_SYSTEM_99_053:[ If value contains invalid data, AgentDataTypes_ToString shall return AGENT_DATA_TYPES_INVALID_ARG.]*/
+                    result = AGENT_DATA_TYPES_INVALID_ARG;
+                    LogError("(result = %s)", MU_ENUM_TO_STRING(AGENT_DATA_TYPES_RESULT, result));
+                }
+
+                break;
+            }
+            case(EDM_BYTE_TYPE) :
+            {
+                char tempbuffer2[4]; /*because bytes can at most be 255 and that is 3 characters + 1 for '\0'*/
+                size_t pos = 0;
+                if (value->value.edmByte.value >= 100) tempbuffer2[pos++] = '0' + (value->value.edmByte.value / 100);
+                if (value->value.edmByte.value >= 10) tempbuffer2[pos++] = '0' + (value->value.edmByte.value % 100) / 10;
+                tempbuffer2[pos++] = '0' + (value->value.edmByte.value % 10);
+                tempbuffer2[pos++] = '\0';
+
+                if (STRING_concat(destination, tempbuffer2) != 0)
+                {
+                    result = AGENT_DATA_TYPES_ERROR;
+                    LogError("(result = %s)", MU_ENUM_TO_STRING(AGENT_DATA_TYPES_RESULT, result));
+                }
+                else
+                {
+                    result = AGENT_DATA_TYPES_OK;
+                }
+                break;
+            }
+            case(EDM_DATE_TYPE) :
+            {
+                size_t pos = 0;
+                char tempBuffer2[1 + 5 + 1 + 2 + 1 + 2 + 1+1];
+                int16_t year = value->value.edmDate.year;
+                tempBuffer2[pos++] = '\"';
+                /*Codes_SRS_AGENT_TYPE_SYSTEM_99_068:[ EDM_DATE: dateValue = year "-" month "-" day.]*/
+                if (year < 0)
+                {
+                    tempBuffer2[pos++] = '-';
+                    year = -year;
+                }
+
+                tempBuffer2[pos++] = '0' + (char)(year / 1000);
+                tempBuffer2[pos++] = '0' + (char)((year % 1000) / 100);
+                tempBuffer2[pos++] = '0' + (char)((year % 100) / 10);
+                tempBuffer2[pos++] = '0' + (char)(year % 10);
+                tempBuffer2[pos++] = '-';
+                tempBuffer2[pos++] = '0' + value->value.edmDate.month / 10;
+                tempBuffer2[pos++] = '0' + value->value.edmDate.month % 10;
+                tempBuffer2[pos++] = '-';
+                tempBuffer2[pos++] = '0' + value->value.edmDate.day / 10;
+                tempBuffer2[pos++] = '0' + value->value.edmDate.day % 10;
+                tempBuffer2[pos++] = '\"';
+                tempBuffer2[pos++] = '\0';
+
+                if (STRING_concat(destination, tempBuffer2) != 0)
+                {
+                    result = AGENT_DATA_TYPES_ERROR;
+                    LogError("(result = %s)", MU_ENUM_TO_STRING(AGENT_DATA_TYPES_RESULT, result));
+                }
+                else
+                {
+                    result = AGENT_DATA_TYPES_OK;
+                }
+                break;
+            }
+            case (EDM_DATE_TIME_OFFSET_TYPE):
+            {
+                /*Codes_SRS_AGENT_TYPE_SYSTEM_99_019:[ EDM_DATETIMEOFFSET: dateTimeOffsetValue = year "-" month "-" day "T" hour ":" minute [ ":" second [ "." fractionalSeconds ] ] ( "Z" / sign hour ":" minute )]*/
+                /*from ABNF seems like these numbers HAVE to be padded with zeroes*/
+                if (value->value.edmDateTimeOffset.hasTimeZone)
+                {
+                    if (value->value.edmDateTimeOffset.hasFractionalSecond)
+                    {
+                        size_t tempBufferSize = 1 + // \"
+                            MAX_LONG_STRING_LENGTH + // %.4d
+                            1 + // -
+                            MAX_LONG_STRING_LENGTH + // %.2d
+                            1 + // -
+                            MAX_LONG_STRING_LENGTH + // %.2d
+                            1 + // T
+                            MAX_LONG_STRING_LENGTH + // %.2d
+                            1 + // :
+                            MAX_LONG_STRING_LENGTH + // %.2d
+                            1 + // :
+                            MAX_LONG_STRING_LENGTH + // %.2d
+                            1 + // .
+                            MAX_ULONG_LONG_STRING_LENGTH + // %.12llu
+                            1 + MAX_LONG_STRING_LENGTH + // %+.2d
+                            1 + // :
+                            MAX_LONG_STRING_LENGTH + // %.2d
+                            1 + //\"
+                            1;  // " (terminating NULL);
+
+                        char* tempBuffer = (char*)malloc(tempBufferSize);
+                        if (tempBuffer == NULL)
+                        {
+                            result = AGENT_DATA_TYPES_ERROR;
+                            LogError("(result = %s)", MU_ENUM_TO_STRING(AGENT_DATA_TYPES_RESULT, result));
+                        }
+                        else
+                        {
+                            if (sprintf_s(tempBuffer, tempBufferSize, "\"%.4d-%.2d-%.2dT%.2d:%.2d:%.2d.%.12llu%+.2d:%.2d\"", /*+ in printf forces the sign to appear*/
+                                value->value.edmDateTimeOffset.dateTime.tm_year+1900,
+                                value->value.edmDateTimeOffset.dateTime.tm_mon+1,
+                                value->value.edmDateTimeOffset.dateTime.tm_mday,
+                                value->value.edmDateTimeOffset.dateTime.tm_hour,
+                                value->value.edmDateTimeOffset.dateTime.tm_min,
+                                value->value.edmDateTimeOffset.dateTime.tm_sec,
+                                value->value.edmDateTimeOffset.fractionalSecond,
+                                value->value.edmDateTimeOffset.timeZoneHour,
+                                value->value.edmDateTimeOffset.timeZoneMinute) < 0)
+                            {
+                                result = AGENT_DATA_TYPES_ERROR;
+                                LogError("(result = %s)", MU_ENUM_TO_STRING(AGENT_DATA_TYPES_RESULT, result));
+                            }
+                            else if (STRING_concat(destination, tempBuffer) != 0)
+                            {
+                                result = AGENT_DATA_TYPES_ERROR;
+                                LogError("(result = %s)", MU_ENUM_TO_STRING(AGENT_DATA_TYPES_RESULT, result));
+                            }
+                            else
+                            {
+                                result = AGENT_DATA_TYPES_OK;
+                            }
+
+                            // Clean up temp buffer if allocated
+                            free(tempBuffer);
+                        }
+                    }
+                    else
+                    {
+                        size_t tempBufferSize = 1 + // \"
+                            MAX_LONG_STRING_LENGTH + // %.4d
+                            1 + // -
+                            MAX_LONG_STRING_LENGTH + // %.2d
+                            1 + // -
+                            MAX_LONG_STRING_LENGTH + // %.2d
+                            1 + // T
+                            MAX_LONG_STRING_LENGTH + // %.2d
+                            1 + // :
+                            MAX_LONG_STRING_LENGTH + // %.2d
+                            1 + // :
+                            MAX_LONG_STRING_LENGTH + // %.2d
+                            1 + MAX_LONG_STRING_LENGTH + // %+.2d
+                            1 + // :
+                            MAX_LONG_STRING_LENGTH + // %.2d
+                            1 + // \"
+                            1; // " terminating NULL
+                        char* tempBuffer = (char*)malloc(tempBufferSize);
+
+                        if (tempBuffer == NULL)
+                        {
+                            result = AGENT_DATA_TYPES_ERROR;
+                            LogError("(result = %s)", MU_ENUM_TO_STRING(AGENT_DATA_TYPES_RESULT, result));
+                        }
+                        else
+                        {
+                            if (sprintf_s(tempBuffer, tempBufferSize, "\"%.4d-%.2d-%.2dT%.2d:%.2d:%.2d%+.2d:%.2d\"", /*+ in printf forces the sign to appear*/
+                                value->value.edmDateTimeOffset.dateTime.tm_year + 1900,
+                                value->value.edmDateTimeOffset.dateTime.tm_mon+1,
+                                value->value.edmDateTimeOffset.dateTime.tm_mday,
+                                value->value.edmDateTimeOffset.dateTime.tm_hour,
+                                value->value.edmDateTimeOffset.dateTime.tm_min,
+                                value->value.edmDateTimeOffset.dateTime.tm_sec,
+                                value->value.edmDateTimeOffset.timeZoneHour,
+                                value->value.edmDateTimeOffset.timeZoneMinute) < 0)
+                            {
+                                result = AGENT_DATA_TYPES_ERROR;
+                                LogError("(result = %s)", MU_ENUM_TO_STRING(AGENT_DATA_TYPES_RESULT, result));
+                            }
+                            else if (STRING_concat(destination, tempBuffer) != 0)
+                            {
+                                result = AGENT_DATA_TYPES_ERROR;
+                                LogError("(result = %s)", MU_ENUM_TO_STRING(AGENT_DATA_TYPES_RESULT, result));
+                            }
+                            else
+                            {
+                                result = AGENT_DATA_TYPES_OK;
+                            }
+
+                            // Clean up temp buffer if allocated
+                            free(tempBuffer);
+                        }
+                    }
+                }
+                else
+                {
+                    if (value->value.edmDateTimeOffset.hasFractionalSecond)
+                    {
+                        size_t tempBufferSize = 1 + //\"
+                            MAX_LONG_STRING_LENGTH + // %.4d
+                            1 + // -
+                            MAX_LONG_STRING_LENGTH + // %.2d
+                            1 + // -
+                            MAX_LONG_STRING_LENGTH + // %.2d
+                            1 + // T
+                            MAX_LONG_STRING_LENGTH + // %.2d
+                            1 + // :
+                            MAX_LONG_STRING_LENGTH + // %.2d
+                            1 + // :
+                            MAX_LONG_STRING_LENGTH + // %.2d
+                            1 + // .
+                            MAX_ULONG_LONG_STRING_LENGTH + // %.12llu
+                            1 + // Z
+                            1 + // \"
+                            1; // " (terminating NULL)
+                        char* tempBuffer = (char*)malloc(tempBufferSize);
+
+                        if (tempBuffer == NULL)
+                        {
+                            result = AGENT_DATA_TYPES_ERROR;
+                            LogError("(result = %s)", MU_ENUM_TO_STRING(AGENT_DATA_TYPES_RESULT, result));
+                        }
+                        else
+                        {
+                            if (sprintf_s(tempBuffer, tempBufferSize, "\"%.4d-%.2d-%.2dT%.2d:%.2d:%.2d.%.12lluZ\"", /*+ in printf forces the sign to appear*/
+                                value->value.edmDateTimeOffset.dateTime.tm_year + 1900,
+                                value->value.edmDateTimeOffset.dateTime.tm_mon+1,
+                                value->value.edmDateTimeOffset.dateTime.tm_mday,
+                                value->value.edmDateTimeOffset.dateTime.tm_hour,
+                                value->value.edmDateTimeOffset.dateTime.tm_min,
+                                value->value.edmDateTimeOffset.dateTime.tm_sec,
+                                value->value.edmDateTimeOffset.fractionalSecond) < 0)
+                            {
+                                result = AGENT_DATA_TYPES_ERROR;
+                                LogError("(result = %s)", MU_ENUM_TO_STRING(AGENT_DATA_TYPES_RESULT, result));
+                            }
+                            else if (STRING_concat(destination, tempBuffer) != 0)
+                            {
+                                result = AGENT_DATA_TYPES_ERROR;
+                                LogError("(result = %s)", MU_ENUM_TO_STRING(AGENT_DATA_TYPES_RESULT, result));
+                            }
+                            else
+                            {
+                                result = AGENT_DATA_TYPES_OK;
+                            }
+
+                            free(tempBuffer);
+                        }
+                    }
+                    else
+                    {
+                        size_t tempBufferSize = 1 + // \"
+                            MAX_LONG_STRING_LENGTH + // %.4d
+                            1 + // -
+                            MAX_LONG_STRING_LENGTH + // %.2d
+                            1 + // -
+                            MAX_LONG_STRING_LENGTH + // %.2d
+                            1 + // T
+                            MAX_LONG_STRING_LENGTH + // %.2d
+                            1 + // :
+                            MAX_LONG_STRING_LENGTH + // %.2d
+                            1 + // :
+                            MAX_LONG_STRING_LENGTH + // %.2d
+                            1 + // Z
+                            1 + // \"
+                            1; // " (terminating null);
+
+                        char* tempBuffer = (char*)malloc(tempBufferSize);
+
+                        if (tempBuffer == NULL)
+                        {
+                            result = AGENT_DATA_TYPES_ERROR;
+                            LogError("(result = %s)", MU_ENUM_TO_STRING(AGENT_DATA_TYPES_RESULT, result));
+                        }
+                        else
+                        {
+                            if (sprintf_s(tempBuffer, tempBufferSize, "\"%.4d-%.2d-%.2dT%.2d:%.2d:%.2dZ\"",
+                                value->value.edmDateTimeOffset.dateTime.tm_year + 1900,
+                                value->value.edmDateTimeOffset.dateTime.tm_mon+1,
+                                value->value.edmDateTimeOffset.dateTime.tm_mday,
+                                value->value.edmDateTimeOffset.dateTime.tm_hour,
+                                value->value.edmDateTimeOffset.dateTime.tm_min,
+                                value->value.edmDateTimeOffset.dateTime.tm_sec) < 0)
+                            {
+                                result = AGENT_DATA_TYPES_ERROR;
+                                LogError("(result = %s)", MU_ENUM_TO_STRING(AGENT_DATA_TYPES_RESULT, result));
+                            }
+                            else if (STRING_concat(destination, tempBuffer) != 0)
+                            {
+                                result = AGENT_DATA_TYPES_ERROR;
+                                LogError("(result = %s)", MU_ENUM_TO_STRING(AGENT_DATA_TYPES_RESULT, result));
+                            }
+                            else
+                            {
+                                result = AGENT_DATA_TYPES_OK;
+                            }
+
+                            free(tempBuffer);
+                        }
+                    }
+                }
+                break;
+            }
+            case(EDM_DECIMAL_TYPE) :
+            {
+                if (STRING_concat_with_STRING(destination, value->value.edmDecimal.value) != 0)
+                {
+                    result = AGENT_DATA_TYPES_ERROR;
+                    LogError("(result = %s)", MU_ENUM_TO_STRING(AGENT_DATA_TYPES_RESULT, result));
+                }
+                else
+                {
+                    result = AGENT_DATA_TYPES_OK;
+                }
+                break;
+            }
+            case (EDM_INT16_TYPE) :
+            {
+                /*-32768 to +32767*/
+                char buffertemp2[7]; /*because 5 digits and sign and '\0'*/
+                uint16_t positiveValue;
+                size_t pos = 0;
+                uint16_t rank = (uint16_t)10000;
+                bool foundFirstDigit = false;
+
+                if (value->value.edmInt16.value < 0)
+                {
+                    buffertemp2[pos++] = '-';
+                    positiveValue = -value->value.edmInt16.value;
+                }
+                else
+                {
+                    positiveValue = value->value.edmInt16.value;
+                }
+
+                while (rank >= 10)
+                {
+                    if ((foundFirstDigit == true) || (positiveValue / rank) > 0)
+                    {
+                        buffertemp2[pos++] = '0' + (char)(positiveValue / rank);
+                        foundFirstDigit = true;
+                    }
+                    positiveValue %= rank;
+                    rank /= 10;
+                }
+                buffertemp2[pos++] = '0' + (char)(positiveValue);
+                buffertemp2[pos++] = '\0';
+
+                if (STRING_concat(destination, buffertemp2) != 0)
+                {
+                    result = AGENT_DATA_TYPES_ERROR;
+                    LogError("(result = %s)", MU_ENUM_TO_STRING(AGENT_DATA_TYPES_RESULT, result));
+                }
+                else
+                {
+                    result = AGENT_DATA_TYPES_OK;
+                }
+                break;
+            }
+            case (EDM_INT32_TYPE) :
+            {
+                /*-2147483648 to +2147483647*/
+                char buffertemp2[12]; /*because 10 digits and sign and '\0'*/
+                uint32_t positiveValue;
+                size_t pos = 0;
+                uint32_t rank = 1000000000UL;
+                bool foundFirstDigit = false;
+
+                if (value->value.edmInt32.value < 0)
+                {
+                    buffertemp2[pos++] = '-';
+                    positiveValue = - value->value.edmInt32.value;
+                }
+                else
+                {
+                    positiveValue = value->value.edmInt32.value;
+                }
+
+                while (rank >= 10)
+                {
+                    if ((foundFirstDigit == true) || (positiveValue / rank) > 0)
+                    {
+                        buffertemp2[pos++] = '0' + (char)(positiveValue / rank);
+                        foundFirstDigit = true;
+                    }
+                    positiveValue %= rank;
+                    rank /= 10;
+                }
+                buffertemp2[pos++] = '0' + (char)(positiveValue);
+                buffertemp2[pos++] = '\0';
+
+                if (STRING_concat(destination, buffertemp2) != 0)
+                {
+                    result = AGENT_DATA_TYPES_ERROR;
+                    LogError("(result = %s)", MU_ENUM_TO_STRING(AGENT_DATA_TYPES_RESULT, result));
+                }
+                else
+                {
+                    result = AGENT_DATA_TYPES_OK;
+                }
+                break;
+            }
+            case (EDM_INT64_TYPE):
+            {
+                char buffertemp2[21]; /*because 19 digits and sign and '\0'*/
+                uint64_t positiveValue;
+                size_t pos = 0;
+                uint64_t rank = 10000000000000000000ULL;
+                bool foundFirstDigit = false;
+
+                if (value->value.edmInt64.value < 0)
+                {
+                    buffertemp2[pos++] = '-';
+                    positiveValue = -value->value.edmInt64.value;
+                }
+                else
+                {
+                    positiveValue = value->value.edmInt64.value;
+                }
+
+                while (rank >= 10)
+                {
+                    if ((foundFirstDigit == true) || (positiveValue / rank) > 0)
+                    {
+                        buffertemp2[pos++] = '0' + (char)(positiveValue / rank);
+                        foundFirstDigit = true;
+                    }
+                    positiveValue %= rank;
+                    rank /= 10;
+                }
+                buffertemp2[pos++] = '0' + (char)(positiveValue);
+                buffertemp2[pos++] = '\0';
+
+                if (STRING_concat(destination, buffertemp2) != 0)
+                {
+                    result = AGENT_DATA_TYPES_ERROR;
+                    LogError("(result = %s)", MU_ENUM_TO_STRING(AGENT_DATA_TYPES_RESULT, result));
+                }
+                else
+                {
+                    result = AGENT_DATA_TYPES_OK;
+                }
+                break;
+            }
+            case (EDM_SBYTE_TYPE) :
+            {
+                char tempbuffer2[5]; /* because '-' and 3 characters for 127 let's say and '\0'*/
+                int absValue = value->value.edmSbyte.value;
+                size_t pos=0;
+                /*Codes_SRS_AGENT_TYPE_SYSTEM_99_026:[ EDM_SBYTE: sbyteValue = [ sign ] 1*3DIGIT  ; numbers in the range from -128 to 127]*/
+
+                if (value->value.edmSbyte.value < 0)
+                {
+                    tempbuffer2[pos++] = '-';
+                    absValue = -absValue;
+                }
+
+                if (absValue >= 100 ) tempbuffer2[pos++] = '0' + (char)(absValue / 100);
+                if (absValue >=10) tempbuffer2[pos++] = '0' + (absValue % 100) / 10;
+                tempbuffer2[pos++] = '0' + (absValue % 10);
+                tempbuffer2[pos++] = '\0';
+
+
+                if (STRING_concat(destination, tempbuffer2) != 0)
+                {
+                    result = AGENT_DATA_TYPES_ERROR;
+                    LogError("(result = %s)", MU_ENUM_TO_STRING(AGENT_DATA_TYPES_RESULT, result));
+                }
+                else
+                {
+                    result = AGENT_DATA_TYPES_OK;
+                }
+                break;
+            }
+            case (EDM_STRING_TYPE):
+            {
+                size_t i;
+                size_t nControlCharacters = 0; /*counts how many characters are to be expanded from 1 character to \uxxxx (6 characters)*/
+                size_t nEscapeCharacters = 0;
+                size_t vlen = value->value.edmString.length;
+                char* v = value->value.edmString.chars;
+
+                for (i = 0; i < vlen; i++)
+                {
+                    if ((unsigned char)v[i] >= 128) /*this be a UNICODE character begin*/
+                    {
+                        break;
+                    }
+                    else
+                    {
+                        if (v[i] <= 0x1F)
+                        {
+                            nControlCharacters++;
+                        }
+                        else if (
+                            (v[i] == '"') ||
+                            (v[i] == '\\') ||
+                            (v[i] == '/')
+                            )
+                        {
+                            nEscapeCharacters++;
+                        }
+                    }
+                }
+
+                if (i < vlen)
+                {
+                    result = AGENT_DATA_TYPES_INVALID_ARG; /*don't handle those who do not copy bit by bit to UTF8*/
+                    LogError("(result = %s)", MU_ENUM_TO_STRING(AGENT_DATA_TYPES_RESULT, result));
+                }
+                else
+                {
+                    /*forward parse the string to scan for " and for \ that in JSON are \" respectively \\*/
+                    size_t tempBufferSize = vlen + 5 * nControlCharacters + nEscapeCharacters + 3 + 1;
+                    char* tempBuffer = (char*)malloc(tempBufferSize);
+                    if (tempBuffer == NULL)
+                    {
+                        result = AGENT_DATA_TYPES_ERROR;
+                        LogError("(result = %s)", MU_ENUM_TO_STRING(AGENT_DATA_TYPES_RESULT, result));
+                    }
+                    else
+                    {
+                        size_t w = 0;
+                        tempBuffer[w++] = '"';
+                        for (i = 0; i < vlen; i++)
+                        {
+                            if (v[i] <= 0x1F)
+                            {
+                                tempBuffer[w++] = '\\';
+                                tempBuffer[w++] = 'u';
+                                tempBuffer[w++] = '0';
+                                tempBuffer[w++] = '0';
+                                tempBuffer[w++] = hexToASCII[(v[i] & 0xF0) >> 4]; /*high nibble*/
+                                tempBuffer[w++] = hexToASCII[v[i] & 0x0F]; /*lowNibble nibble*/
+                            }
+                            else if (v[i] == '"')
+                            {
+                                tempBuffer[w++] = '\\';
+                                tempBuffer[w++] = '"';
+                            }
+                            else if (v[i] == '\\')
+                            {
+                                tempBuffer[w++] = '\\';
+                                tempBuffer[w++] = '\\';
+                            }
+                            else if (v[i] == '/')
+                            {
+                                tempBuffer[w++] = '\\';
+                                tempBuffer[w++] = '/';
+                            }
+                            else
+                            {
+                                tempBuffer[w++] = v[i];
+                            }
+                        }
+
+#ifdef _MSC_VER
+#pragma warning(suppress: 6386) /* The test Create_AGENT_DATA_TYPE_from_charz_With_2_Slashes_Succeeds verifies that Code Analysis is wrong here */
+#endif
+                        tempBuffer[w] = '"';
+                        /*zero terminating it*/
+                        tempBuffer[vlen + 5 * nControlCharacters + nEscapeCharacters + 3 - 1] = '\0';
+
+                        if (STRING_concat(destination, tempBuffer) != 0)
+                        {
+                            result = AGENT_DATA_TYPES_ERROR;
+                            LogError("(result = %s)", MU_ENUM_TO_STRING(AGENT_DATA_TYPES_RESULT, result));
+                        }
+                        else
+                        {
+                            result = AGENT_DATA_TYPES_OK;
+                        }
+
+                        free(tempBuffer);
+                    }
+                }
+
+                break;
+            }
+
+            /* Codes_SRS_AGENT_TYPE_SYSTEM_01_003: [EDM_STRING_no_quotes: the string is copied as given when the AGENT_DATA_TYPE was created.] */
+            case (EDM_STRING_NO_QUOTES_TYPE) :
+            {
+                /* this is a special case where we just want to copy/paste the contents, no encoding, no quotes */
+                /* Codes_SRS_AGENT_TYPE_SYSTEM_01_002: [When serialized, this type is not enclosed with quotes.] */
+                if (STRING_concat(destination, value->value.edmStringNoQuotes.chars) != 0)
+                {
+                    result = AGENT_DATA_TYPES_ERROR;
+                    LogError("(result = %s)", MU_ENUM_TO_STRING(AGENT_DATA_TYPES_RESULT, result));
+                }
+                else
+                {
+                    result = AGENT_DATA_TYPES_OK;
+                }
+
+                break;
+            }
+
+#ifndef NO_FLOATS
+            case(EDM_SINGLE_TYPE):
+            {
+                /*C89 standard says: When a float is promoted to double or long double, or a double is promoted to long double, its value is unchanged*/
+                /*I read that as : when a float is NaN or Inf, it will stay NaN or INF in double representation*/
+
+                /*The sprintf function returns the number of characters written in the array, not counting the terminating null character.*/
+
+                if(ISNAN(value->value.edmSingle.value))
+                {
+                    if (STRING_concat(destination, NaN_STRING) != 0)
+                    {
+                        result = AGENT_DATA_TYPES_ERROR;
+                        LogError("(result = %s)", MU_ENUM_TO_STRING(AGENT_DATA_TYPES_RESULT, result));
+                    }
+                    else
+                    {
+                        result = AGENT_DATA_TYPES_OK;
+                    }
+                }
+                else if (ISNEGATIVEINFINITY(value->value.edmSingle.value))
+                {
+                    if (STRING_concat(destination, MINUSINF_STRING) != 0)
+                    {
+                        result = AGENT_DATA_TYPES_ERROR;
+                        LogError("(result = %s)", MU_ENUM_TO_STRING(AGENT_DATA_TYPES_RESULT, result));
+                    }
+                    else
+                    {
+                        result = AGENT_DATA_TYPES_OK;
+                    }
+                }
+                else if (ISPOSITIVEINFINITY(value->value.edmSingle.value))
+                {
+                    if (STRING_concat(destination, PLUSINF_STRING) != 0)
+                    {
+                        result = AGENT_DATA_TYPES_ERROR;
+                        LogError("(result = %s)", MU_ENUM_TO_STRING(AGENT_DATA_TYPES_RESULT, result));
+                    }
+                    else
+                    {
+                        result = AGENT_DATA_TYPES_OK;
+                    }
+                }
+                else
+                {
+                    size_t tempBufferSize = MAX_FLOATING_POINT_STRING_LENGTH;
+                    char* tempBuffer = (char*)malloc(tempBufferSize);
+                    if (tempBuffer == NULL)
+                    {
+                        result = AGENT_DATA_TYPES_ERROR;
+                        LogError("(result = %s)", MU_ENUM_TO_STRING(AGENT_DATA_TYPES_RESULT, result));
+                    }
+                    else
+                    {
+                        if (sprintf_s(tempBuffer, tempBufferSize, "%.*f", FLT_DIG, (double)(value->value.edmSingle.value)) < 0)
+                        {
+                            result = AGENT_DATA_TYPES_ERROR;
+                            LogError("(result = %s)", MU_ENUM_TO_STRING(AGENT_DATA_TYPES_RESULT, result));
+                        }
+                        else if (STRING_concat(destination, tempBuffer) != 0)
+                        {
+                            result = AGENT_DATA_TYPES_ERROR;
+                            LogError("(result = %s)", MU_ENUM_TO_STRING(AGENT_DATA_TYPES_RESULT, result));
+                        }
+                        else
+                        {
+                            result = AGENT_DATA_TYPES_OK;
+                        }
+
+                        free(tempBuffer);
+                    }
+                }
+                break;
+            }
+            case(EDM_DOUBLE_TYPE):
+            {
+                /*The sprintf function returns the number of characters written in the array, not counting the terminating null character.*/
+                /*OData-ABNF says these can be used: nanInfinity = 'NaN' / '-INF' / 'INF'*/
+                /*C90 doesn't declare a NaN or Inf in the standard, however, values might be NaN or Inf...*/
+                /*C99 ... does*/
+                /*C11 is same as C99*/
+                /*Codes_SRS_AGENT_TYPE_SYSTEM_99_022:[ EDM_DOUBLE: doubleValue = decimalValue [ "e" [SIGN] 1*DIGIT ] / nanInfinity ; IEEE 754 binary64 floating-point number (15-17 decimal digits). The representation shall use DBL_DIG C #define*/
+                if(ISNAN(value->value.edmDouble.value))
+                {
+                    if (STRING_concat(destination, NaN_STRING) != 0)
+                    {
+                        result = AGENT_DATA_TYPES_ERROR;
+                        LogError("(result = %s)", MU_ENUM_TO_STRING(AGENT_DATA_TYPES_RESULT, result));
+                    }
+                    else
+                    {
+                        result = AGENT_DATA_TYPES_OK;
+                    }
+                }
+                /*Codes_SRS_AGENT_TYPE_SYSTEM_99_022:[ EDM_DOUBLE: doubleValue = decimalValue [ "e" [SIGN] 1*DIGIT ] / nanInfinity ; IEEE 754 binary64 floating-point number (15-17 decimal digits). The representation shall use DBL_DIG C #define*/
+                else if (ISNEGATIVEINFINITY(value->value.edmDouble.value))
+                {
+                    if (STRING_concat(destination, MINUSINF_STRING) != 0)
+                    {
+                        result = AGENT_DATA_TYPES_ERROR;
+                        LogError("(result = %s)", MU_ENUM_TO_STRING(AGENT_DATA_TYPES_RESULT, result));
+                    }
+                    else
+                    {
+                        result = AGENT_DATA_TYPES_OK;
+                    }
+                }
+                /*Codes_SRS_AGENT_TYPE_SYSTEM_99_022:[ EDM_DOUBLE: doubleValue = decimalValue [ "e" [SIGN] 1*DIGIT ] / nanInfinity ; IEEE 754 binary64 floating-point number (15-17 decimal digits). The representation shall use DBL_DIG C #define*/
+                else if (ISPOSITIVEINFINITY(value->value.edmDouble.value))
+                {
+                    if (STRING_concat(destination, PLUSINF_STRING) != 0)
+                    {
+                        result = AGENT_DATA_TYPES_ERROR;
+                        LogError("(result = %s)", MU_ENUM_TO_STRING(AGENT_DATA_TYPES_RESULT, result));
+                    }
+                    else
+                    {
+                        result = AGENT_DATA_TYPES_OK;
+                    }
+                }
+                /*Codes_SRS_AGENT_TYPE_SYSTEM_99_022:[ EDM_DOUBLE: doubleValue = decimalValue [ "e" [SIGN] 1*DIGIT ] / nanInfinity ; IEEE 754 binary64 floating-point number (15-17 decimal digits). The representation shall use DBL_DIG C #define*/
+                else
+                {
+                    size_t tempBufferSize = DECIMAL_DIG * 2;
+                    char* tempBuffer = (char*)malloc(tempBufferSize);
+                    if (tempBuffer == NULL)
+                    {
+                        result = AGENT_DATA_TYPES_ERROR;
+                        LogError("(result = %s)", MU_ENUM_TO_STRING(AGENT_DATA_TYPES_RESULT, result));
+                    }
+                    else
+                    {
+                        if (sprintf_s(tempBuffer, tempBufferSize, "%.*f", DBL_DIG, value->value.edmDouble.value) < 0)
+                        {
+                            result = AGENT_DATA_TYPES_ERROR;
+                            LogError("(result = %s)", MU_ENUM_TO_STRING(AGENT_DATA_TYPES_RESULT, result));
+                        }
+                        else if (STRING_concat(destination, tempBuffer) != 0)
+                        {
+                            result = AGENT_DATA_TYPES_ERROR;
+                            LogError("(result = %s)", MU_ENUM_TO_STRING(AGENT_DATA_TYPES_RESULT, result));
+                        }
+                        else
+                        {
+                            result = AGENT_DATA_TYPES_OK;
+                        }
+
+                        free(tempBuffer);
+                    }
+                }
+                break;
+            }
+#endif
+
+            case(EDM_COMPLEX_TYPE_TYPE) :
+            {
+                /*to produce an EDM_COMPLEX_TYPE is a recursive process*/
+                /*uses JSON encoder*/
+                /*Codes_SRS_AGENT_TYPE_SYSTEM_99_062:[ If the AGENT_DATA_TYPE represents a "complex type", then the JSON marshaller shall produce the following JSON value:[...]*/
+                MULTITREE_HANDLE treeHandle;
+                result = AGENT_DATA_TYPES_OK;
+                /*SRS_AGENT_TYPE_SYSTEM_99_016:[ When the value cannot be converted to a string AgentDataTypes_ToString shall return AGENT_DATA_TYPES_ERROR.]*/
+                treeHandle = MultiTree_Create(NoCloneFunction, NoFreeFunction);
+                if (treeHandle == NULL)
+                {
+                    result = AGENT_DATA_TYPES_ERROR;
+                    LogError("(result = %s)", MU_ENUM_TO_STRING(AGENT_DATA_TYPES_RESULT, result));
+                }
+                else
+                {
+                    size_t i;
+                    for (i = 0; i < value->value.edmComplexType.nMembers; i++)
+                    {
+                        if (MultiTree_AddLeaf(treeHandle, value->value.edmComplexType.fields[i].fieldName, value->value.edmComplexType.fields[i].value) != MULTITREE_OK)
+                        {
+                            /*SRS_AGENT_TYPE_SYSTEM_99_016:[ When the value cannot be converted to a string AgentDataTypes_ToString shall return AGENT_DATA_TYPES_ERROR.]*/
+                            result = AGENT_DATA_TYPES_ERROR;
+                            LogError("(result = %s)", MU_ENUM_TO_STRING(AGENT_DATA_TYPES_RESULT, result));
+                            break;
+                        }
+                        else
+                        {
+                            /*all is fine*/
+                        }
+                    }
+
+                    if (result == AGENT_DATA_TYPES_OK)
+                    {
+                            /*SRS_AGENT_TYPE_SYSTEM_99_016:[ When the value cannot be converted to a string AgentDataTypes_ToString shall return AGENT_DATA_TYPES_ERROR.]*/
+                            if (JSONEncoder_EncodeTree(treeHandle, destination, (JSON_ENCODER_TOSTRING_FUNC)AgentDataTypes_ToString) != JSON_ENCODER_OK)
+                            {
+                                result = AGENT_DATA_TYPES_ERROR;
+                                LogError("(result = %s)", MU_ENUM_TO_STRING(AGENT_DATA_TYPES_RESULT, result));
+                            }
+                            else
+                            {
+                                /*all is fine*/
+                            }
+
+                    }
+
+                    MultiTree_Destroy(treeHandle);
+                }
+                break;
+            }
+            case EDM_GUID_TYPE:
+            {
+                char tempBuffer2[1 + 8 + 1 + 4 + 1 + 4 + 1 + 4 + 1 + 12 + 1+ 1];
+                /*Codes_SRS_AGENT_TYPE_SYSTEM_99_093:[ EDM_GUID: 8HEXDIG "-" 4HEXDIG "-" 4HEXDIG "-" 4HEXDIG "-" 12HEXDIG]*/
+                tempBuffer2[0] = '\"';
+                tempBuffer2[1] = hexDigitToChar(value->value.edmGuid.GUID[0] / 16);
+                tempBuffer2[2] = hexDigitToChar(value->value.edmGuid.GUID[0] % 16);
+                tempBuffer2[3] = hexDigitToChar(value->value.edmGuid.GUID[1] / 16);
+                tempBuffer2[4] = hexDigitToChar(value->value.edmGuid.GUID[1] % 16);
+                tempBuffer2[5] = hexDigitToChar(value->value.edmGuid.GUID[2] / 16);
+                tempBuffer2[6] = hexDigitToChar(value->value.edmGuid.GUID[2] % 16);
+                tempBuffer2[7] = hexDigitToChar(value->value.edmGuid.GUID[3] / 16);
+                tempBuffer2[8] = hexDigitToChar(value->value.edmGuid.GUID[3] % 16);
+
+                tempBuffer2[9] = '-';
+                tempBuffer2[10] = hexDigitToChar(value->value.edmGuid.GUID[4] / 16);
+                tempBuffer2[11] = hexDigitToChar(value->value.edmGuid.GUID[4] % 16);
+                tempBuffer2[12] = hexDigitToChar(value->value.edmGuid.GUID[5] / 16);
+                tempBuffer2[13] = hexDigitToChar(value->value.edmGuid.GUID[5] % 16);
+
+                tempBuffer2[14] = '-';
+                tempBuffer2[15] = hexDigitToChar(value->value.edmGuid.GUID[6] / 16);
+                tempBuffer2[16] = hexDigitToChar(value->value.edmGuid.GUID[6] % 16);
+                tempBuffer2[17] = hexDigitToChar(value->value.edmGuid.GUID[7] / 16);
+                tempBuffer2[18] = hexDigitToChar(value->value.edmGuid.GUID[7] % 16);
+
+                tempBuffer2[19] = '-';
+                tempBuffer2[20] = hexDigitToChar(value->value.edmGuid.GUID[8] / 16);
+                tempBuffer2[21] = hexDigitToChar(value->value.edmGuid.GUID[8] % 16);
+                tempBuffer2[22] = hexDigitToChar(value->value.edmGuid.GUID[9] / 16);
+                tempBuffer2[23] = hexDigitToChar(value->value.edmGuid.GUID[9] % 16);
+
+                tempBuffer2[24] = '-';
+                tempBuffer2[25] = hexDigitToChar(value->value.edmGuid.GUID[10] / 16);
+                tempBuffer2[26] = hexDigitToChar(value->value.edmGuid.GUID[10] % 16);
+                tempBuffer2[27] = hexDigitToChar(value->value.edmGuid.GUID[11] / 16);
+                tempBuffer2[28] = hexDigitToChar(value->value.edmGuid.GUID[11] % 16);
+                tempBuffer2[29] = hexDigitToChar(value->value.edmGuid.GUID[12] / 16);
+                tempBuffer2[30] = hexDigitToChar(value->value.edmGuid.GUID[12] % 16);
+                tempBuffer2[31] = hexDigitToChar(value->value.edmGuid.GUID[13] / 16);
+                tempBuffer2[32] = hexDigitToChar(value->value.edmGuid.GUID[13] % 16);
+                tempBuffer2[33] = hexDigitToChar(value->value.edmGuid.GUID[14] / 16);
+                tempBuffer2[34] = hexDigitToChar(value->value.edmGuid.GUID[14] % 16);
+                tempBuffer2[35] = hexDigitToChar(value->value.edmGuid.GUID[15] / 16);
+                tempBuffer2[36] = hexDigitToChar(value->value.edmGuid.GUID[15] % 16);
+
+                tempBuffer2[37] = '\"';
+                tempBuffer2[38] = '\0';
+
+                if (STRING_concat(destination, tempBuffer2) != 0)
+                {
+                    result = AGENT_DATA_TYPES_ERROR;
+                    LogError("(result = %s)", MU_ENUM_TO_STRING(AGENT_DATA_TYPES_RESULT, result));
+                }
+                else
+                {
+                    result = AGENT_DATA_TYPES_OK;
+                }
+                break;
+            }
+            case EDM_BINARY_TYPE:
+            {
+                size_t currentPosition = 0;
+                char* temp;
+                /*binary types */
+                /*Codes_SRS_AGENT_TYPE_SYSTEM_99_099:[EDM_BINARY:= *(4base64char)[base64b16 / base64b8]]*/
+                /*the following will happen*/
+                /*1. the "data" of the binary shall be "eaten" 3 characters at a time and produce 4 base64 encoded characters for as long as there are more than 3 characters still to process*/
+                /*2. the remaining characters (1 or 2) shall be encoded.*/
+                /*there's a level of assumption that 'a' corresponds to 0b000000 and that '_' corresponds to 0b111111*/
+                /*the encoding will use the optional [=] or [==] at the end of the encoded string, so that other less standard aware libraries can do their work*/
+                /*these are the bits of the 3 normal bytes to be encoded*/
+                size_t neededSize = 2; /*2 because starting and ending quotes */
+                neededSize += (value->value.edmBinary.size == 0) ? (0) : ((((value->value.edmBinary.size-1) / 3) + 1) * 4);
+                neededSize += 1; /*+1 because \0 at the end of the string*/
+                if ((temp = (char*)malloc(neededSize))==NULL)
+                {
+                    result = AGENT_DATA_TYPES_ERROR;
+                }
+                else
+                {
+                    /*b0            b1(+1)          b2(+2)
+                      7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0
+                      |----c1---| |----c2---| |----c3---| |----c4---|
+                    */
+
+                    size_t destinationPointer = 0;
+                    temp[destinationPointer++] = '"';
+                    while (value->value.edmBinary.size - currentPosition >= 3)
+                    {
+                        char c1 = base64char(value->value.edmBinary.data[currentPosition] >> 2);
+                        char c2 = base64char(
+                            ((value->value.edmBinary.data[currentPosition] & 3) << 4) |
+                                (value->value.edmBinary.data[currentPosition + 1] >> 4)
+                        );
+                        char c3 = base64char(
+                            ((value->value.edmBinary.data[currentPosition + 1] & 0x0F) << 2) |
+                                ((value->value.edmBinary.data[currentPosition + 2] >> 6) & 3)
+                        );
+                        char c4 = base64char(
+                            value->value.edmBinary.data[currentPosition + 2] & 0x3F
+                        );
+                        currentPosition += 3;
+                        temp[destinationPointer++] = c1;
+                        temp[destinationPointer++] = c2;
+                        temp[destinationPointer++] = c3;
+                        temp[destinationPointer++] = c4;
+
+                    }
+                    if (value->value.edmBinary.size - currentPosition == 2)
+                    {
+                        char c1 = base64char(value->value.edmBinary.data[currentPosition] >> 2);
+                        char c2 = base64char(
+                            ((value->value.edmBinary.data[currentPosition] & 0x03) << 4) |
+                                (value->value.edmBinary.data[currentPosition + 1] >> 4)
+                        );
+                        char c3 = base64b16(value->value.edmBinary.data[currentPosition + 1] & 0x0F);
+                        temp[destinationPointer++] = c1;
+                        temp[destinationPointer++] = c2;
+                        temp[destinationPointer++] = c3;
+                        temp[destinationPointer++] = '=';
+                    }
+                    else if (value->value.edmBinary.size - currentPosition == 1)
+                    {
+                        char c1 = base64char(value->value.edmBinary.data[currentPosition] >> 2);
+                        char c2 = base64b8(value->value.edmBinary.data[currentPosition] & 0x03);
+                        temp[destinationPointer++] = c1;
+                        temp[destinationPointer++] = c2;
+                        temp[destinationPointer++] = '=';
+                        temp[destinationPointer++] = '=';
+                    }
+
+                    /*closing quote*/
+                    temp[destinationPointer++] = '"';
+                    /*null terminating the string*/
+                    temp[destinationPointer] = '\0';
+
+                    if (STRING_concat(destination, temp) != 0)
+                    {
+                        result = AGENT_DATA_TYPES_ERROR;
+                        LogError("(result = %s)", MU_ENUM_TO_STRING(AGENT_DATA_TYPES_RESULT, result));
+                    }
+                    else
+                    {
+                        result = AGENT_DATA_TYPES_OK;
+                    }
+                    free(temp);
+                }
+                break;
+            }
+        }
+    }
+    return result;
+}
+
+/*return 0 if all names are different than NULL*/
+static int isOneNameNULL(size_t nMemberNames, const char* const * memberNames)
+{
+    size_t i;
+    int result = 0;
+    for (i = 0; i < nMemberNames; i++)
+    {
+        if (memberNames[i] == NULL)
+        {
+            result = 1;
+            break;
+        }
+    }
+    return result;
+}
+
+/*return 0 if all names are different than NULL*/
+static int areThereTwoSameNames(size_t nMemberNames, const char* const * memberNames)
+{
+    size_t i, j;
+    int result = 0;
+    for (i = 0; i < nMemberNames-1; i++)
+    {
+        for (j = i + 1; j < nMemberNames; j++)
+        {
+            if (strcmp(memberNames[i], memberNames[j]) == 0)
+            {
+                result = 1;
+                goto out;
+            }
+        }
+    }
+out:
+    return result;
+}
+
+static void DestroyHalfBakedComplexType(AGENT_DATA_TYPE* agentData)
+{
+    size_t i;
+    if (agentData != NULL)
+    {
+        if (agentData->type == EDM_COMPLEX_TYPE_TYPE)
+        {
+            if (agentData->value.edmComplexType.fields != NULL)
+            {
+                for (i = 0; i < agentData->value.edmComplexType.nMembers; i++)
+                {
+                    if (agentData->value.edmComplexType.fields[i].fieldName != NULL)
+                    {
+                        free((void*)(agentData->value.edmComplexType.fields[i].fieldName));
+                        agentData->value.edmComplexType.fields[i].fieldName = NULL;
+                    }
+                    if (agentData->value.edmComplexType.fields[i].value != NULL)
+                    {
+                        Destroy_AGENT_DATA_TYPE(agentData->value.edmComplexType.fields[i].value);
+                        free(agentData->value.edmComplexType.fields[i].value);
+                        agentData->value.edmComplexType.fields[i].value = NULL;
+                    }
+                }
+                free(agentData->value.edmComplexType.fields);
+                agentData->value.edmComplexType.fields = NULL;
+            }
+            agentData->type = EDM_NO_TYPE;
+        }
+    }
+}
+
+/* Creates an object of AGENT_DATA_TYPE_TYPE EDM_NULL_TYPE*/
+AGENT_DATA_TYPES_RESULT Create_NULL_AGENT_DATA_TYPE(AGENT_DATA_TYPE* agentData)
+{
+    AGENT_DATA_TYPES_RESULT result;
+    if (agentData == NULL)
+    {
+        result = AGENT_DATA_TYPES_INVALID_ARG;
+        LogError("(result = %s)", MU_ENUM_TO_STRING(AGENT_DATA_TYPES_RESULT, result));
+    }
+    else
+    {
+        agentData->type = EDM_NULL_TYPE;
+        result = AGENT_DATA_TYPES_OK;
+    }
+    return result;
+}
+/*creates a copy of the AGENT_DATA_TYPE*/
+AGENT_DATA_TYPES_RESULT Create_AGENT_DATA_TYPE_from_AGENT_DATA_TYPE(AGENT_DATA_TYPE* dest, const AGENT_DATA_TYPE* src)
+{
+    AGENT_DATA_TYPES_RESULT result;
+    size_t i;
+    if ((dest == NULL) || (src == NULL))
+    {
+        result = AGENT_DATA_TYPES_INVALID_ARG;
+        LogError("(result = %s)", MU_ENUM_TO_STRING(AGENT_DATA_TYPES_RESULT, result));
+    }
+    else
+    {
+        switch (src->type)
+        {
+            default:
+            {
+                result = AGENT_DATA_TYPES_NOT_IMPLEMENTED;
+                LogError("(result = %s)", MU_ENUM_TO_STRING(AGENT_DATA_TYPES_RESULT, result));
+                break;
+            }
+            case(EDM_NO_TYPE) :
+            case(EDM_NULL_TYPE) :
+            {
+                dest->type = src->type;
+                result = AGENT_DATA_TYPES_OK;
+                break;
+            }
+            case(EDM_BOOLEAN_TYPE) :
+            {
+                dest->type = src->type;
+                dest->value.edmBoolean= src->value.edmBoolean;
+                result = AGENT_DATA_TYPES_OK;
+                break;
+            }
+            case(EDM_BYTE_TYPE) :
+            {
+                dest->type = src->type;
+                dest->value.edmByte= src->value.edmByte;
+                result = AGENT_DATA_TYPES_OK;
+                break;
+            }
+            case(EDM_DATE_TYPE) :
+            {
+                dest->type = src->type;
+                dest->value.edmDate = src->value.edmDate;
+                result = AGENT_DATA_TYPES_OK;
+                break;
+            }
+            case(EDM_DATE_TIME_OFFSET_TYPE) :
+            {
+                dest->type = src->type;
+                dest->value.edmDateTimeOffset = src->value.edmDateTimeOffset;
+                result = AGENT_DATA_TYPES_OK;
+                break;
+            }
+            case(EDM_DECIMAL_TYPE) :
+            {
+                if ((dest->value.edmDecimal.value = STRING_clone(src->value.edmDecimal.value)) == NULL)
+                {
+                    result = AGENT_DATA_TYPES_ERROR;
+                    LogError("(result = %s)", MU_ENUM_TO_STRING(AGENT_DATA_TYPES_RESULT, result));
+                }
+                else
+                {
+                    dest->type = src->type;
+                    result = AGENT_DATA_TYPES_OK;
+                    /*all is fine*/
+                }
+                break;
+            }
+            case(EDM_DOUBLE_TYPE) :
+            {
+                dest->type = src->type;
+                dest->value.edmDouble = src->value.edmDouble;
+                result = AGENT_DATA_TYPES_OK;
+                break;
+            }
+            case(EDM_DURATION_TYPE) :
+            {
+                result = AGENT_DATA_TYPES_NOT_IMPLEMENTED;
+                LogError("(result = %s)", MU_ENUM_TO_STRING(AGENT_DATA_TYPES_RESULT, result));
+                break;
+            }
+            case(EDM_GUID_TYPE) :
+            {
+                dest->type = src->type;
+                dest->value.edmGuid = src->value.edmGuid;
+                result = AGENT_DATA_TYPES_OK;
+                break;
+            }
+            case EDM_BINARY_TYPE:
+            {
+                if (src->value.edmBinary.size == 0)
+                {
+                    dest->value.edmBinary.size = 0;
+                    dest->value.edmBinary.data = NULL;
+                    dest->type = EDM_BINARY_TYPE;
+                    result = AGENT_DATA_TYPES_OK;
+                }
+                else
+                {
+                    if ((dest->value.edmBinary.data = (unsigned char*)malloc(src->value.edmBinary.size)) == NULL)
+                    {
+                        result = AGENT_DATA_TYPES_ERROR;
+                    }
+                    else
+                    {
+                        dest->value.edmBinary.size = src->value.edmBinary.size;
+                        (void)memcpy(dest->value.edmBinary.data, src->value.edmBinary.data, src->value.edmBinary.size);
+                        dest->type = EDM_BINARY_TYPE;
+                        result = AGENT_DATA_TYPES_OK;
+                    }
+                }
+                break;
+            }
+            case(EDM_INT16_TYPE) :
+            {
+                dest->type = src->type;
+                dest->value.edmInt16 = src->value.edmInt16;
+                result = AGENT_DATA_TYPES_OK;
+                break;
+            }
+            case(EDM_INT32_TYPE) :
+            {
+                dest->type = src->type;
+                dest->value.edmInt32 = src->value.edmInt32;
+                result = AGENT_DATA_TYPES_OK;
+                break;
+            }
+            case(EDM_INT64_TYPE) :
+            {
+                dest->type = src->type;
+                dest->value.edmInt64 = src->value.edmInt64;
+                result = AGENT_DATA_TYPES_OK;
+                break;
+            }
+            case(EDM_SBYTE_TYPE) :
+            {
+                dest->type = src->type;
+                dest->value.edmSbyte = src->value.edmSbyte;
+                result = AGENT_DATA_TYPES_OK;
+                break;
+            }
+            case(EDM_SINGLE_TYPE) :
+            {
+                dest->type = src->type;
+                dest->value.edmSingle = src->value.edmSingle;
+                result = AGENT_DATA_TYPES_OK;
+                break;
+            }
+            case(EDM_STREAM) :
+            {
+                result = AGENT_DATA_TYPES_NOT_IMPLEMENTED;
+                LogError("(result = %s)", MU_ENUM_TO_STRING(AGENT_DATA_TYPES_RESULT, result));
+                break;
+            } /*not supported, because what is stream?*/
+            case(EDM_STRING_TYPE) :
+            {
+                dest->type = src->type;
+                dest->value.edmString.length = src->value.edmString.length;
+                if (mallocAndStrcpy_s((char**)&(dest->value.edmString.chars), (char*)src->value.edmString.chars) != 0)
+                {
+                    result = AGENT_DATA_TYPES_ERROR;
+                    LogError("(result = %s)", MU_ENUM_TO_STRING(AGENT_DATA_TYPES_RESULT, result));
+                }
+                else
+                {
+                    result = AGENT_DATA_TYPES_OK;
+                    /*all is fine*/
+                }
+                break;
+            }
+            case(EDM_STRING_NO_QUOTES_TYPE) :
+            {
+                dest->type = src->type;
+                dest->value.edmStringNoQuotes.length = src->value.edmStringNoQuotes.length;
+                if (mallocAndStrcpy_s((char**)&(dest->value.edmStringNoQuotes.chars), (char*)src->value.edmStringNoQuotes.chars) != 0)
+                {
+                    result = AGENT_DATA_TYPES_ERROR;
+                    LogError("(result = %s)", MU_ENUM_TO_STRING(AGENT_DATA_TYPES_RESULT, result));
+                }
+                else
+                {
+                    result = AGENT_DATA_TYPES_OK;
+                    /*all is fine*/
+                }
+                break;
+            }
+            case(EDM_TIME_OF_DAY_TYPE) :
+            {
+                result = AGENT_DATA_TYPES_NOT_IMPLEMENTED;
+                LogError("(result = %s)", MU_ENUM_TO_STRING(AGENT_DATA_TYPES_RESULT, result));
+                break;
+            }
+            case(EDM_GEOGRAPHY_TYPE) :
+            {
+                result = AGENT_DATA_TYPES_NOT_IMPLEMENTED;
+                LogError("(result = %s)", MU_ENUM_TO_STRING(AGENT_DATA_TYPES_RESULT, result));
+                break;
+            } /*not supported because what is "abstract base type"*/
+            case(EDM_GEOGRAPHY_POINT_TYPE) :
+            {
+                result = AGENT_DATA_TYPES_NOT_IMPLEMENTED;
+                LogError("(result = %s)", MU_ENUM_TO_STRING(AGENT_DATA_TYPES_RESULT, result));
+                break;
+            }
+            case(EDM_GEOGRAPHY_LINE_STRING_TYPE) :
+            {
+                result = AGENT_DATA_TYPES_NOT_IMPLEMENTED;
+                LogError("(result = %s)", MU_ENUM_TO_STRING(AGENT_DATA_TYPES_RESULT, result));
+                break;
+            }
+            case(EDM_GEOGRAPHY_POLYGON_TYPE) :
+            {
+                result = AGENT_DATA_TYPES_NOT_IMPLEMENTED;
+                LogError("(result = %s)", MU_ENUM_TO_STRING(AGENT_DATA_TYPES_RESULT, result));
+                break;
+            }
+            case(EDM_GEOGRAPHY_MULTI_POINT_TYPE) :
+            {
+                result = AGENT_DATA_TYPES_NOT_IMPLEMENTED;
+                LogError("(result = %s)", MU_ENUM_TO_STRING(AGENT_DATA_TYPES_RESULT, result));
+                break;
+            }
+            case(EDM_GEOGRAPHY_MULTI_LINE_STRING_TYPE) :
+            {
+                result = AGENT_DATA_TYPES_NOT_IMPLEMENTED;
+                LogError("(result = %s)", MU_ENUM_TO_STRING(AGENT_DATA_TYPES_RESULT, result));
+                break;
+            }
+            case(EDM_GEOGRAPHY_MULTI_POLYGON_TYPE) :
+            {
+                result = AGENT_DATA_TYPES_NOT_IMPLEMENTED;
+                LogError("(result = %s)", MU_ENUM_TO_STRING(AGENT_DATA_TYPES_RESULT, result));
+                break;
+            }
+            case(EDM_GEOGRAPHY_COLLECTION_TYPE) :
+            {
+                result = AGENT_DATA_TYPES_NOT_IMPLEMENTED;
+                LogError("(result = %s)", MU_ENUM_TO_STRING(AGENT_DATA_TYPES_RESULT, result));
+                break;
+            }
+            case(EDM_GEOMETRY_TYPE) :
+            {
+                result = AGENT_DATA_TYPES_NOT_IMPLEMENTED;
+                LogError("(result = %s)", MU_ENUM_TO_STRING(AGENT_DATA_TYPES_RESULT, result));
+                break;
+            } /*not supported because what is "abstract base type"*/
+            case(EDM_GEOMETRY_POINT_TYPE) :
+            {
+                result = AGENT_DATA_TYPES_NOT_IMPLEMENTED;
+                LogError("(result = %s)", MU_ENUM_TO_STRING(AGENT_DATA_TYPES_RESULT, result));
+                break;
+            }
+            case(EDM_GEOMETRY_LINE_STRING_TYPE) :
+            {
+                result = AGENT_DATA_TYPES_NOT_IMPLEMENTED;
+                LogError("(result = %s)", MU_ENUM_TO_STRING(AGENT_DATA_TYPES_RESULT, result));
+                break;
+            }
+            case(EDM_GEOMETRY_POLYGON_TYPE) :
+            {
+                result = AGENT_DATA_TYPES_NOT_IMPLEMENTED;
+                LogError("(result = %s)", MU_ENUM_TO_STRING(AGENT_DATA_TYPES_RESULT, result));
+                break;
+            }
+            case(EDM_GEOMETRY_MULTI_POINT_TYPE) :
+            {
+                result = AGENT_DATA_TYPES_NOT_IMPLEMENTED;
+                LogError("(result = %s)", MU_ENUM_TO_STRING(AGENT_DATA_TYPES_RESULT, result));
+                break;
+            }
+            case(EDM_GEOMETRY_MULTI_LINE_STRING_TYPE) :
+            {
+                result = AGENT_DATA_TYPES_NOT_IMPLEMENTED;
+                LogError("(result = %s)", MU_ENUM_TO_STRING(AGENT_DATA_TYPES_RESULT, result));
+                break;
+            }
+            case(EDM_GEOMETRY_MULTI_POLYGON_TYPE) :
+            {
+                result = AGENT_DATA_TYPES_NOT_IMPLEMENTED;
+                LogError("(result = %s)", MU_ENUM_TO_STRING(AGENT_DATA_TYPES_RESULT, result));
+                break;
+            }
+            case(EDM_GEOMETRY_COLLECTION_TYPE) :
+            {
+                result = AGENT_DATA_TYPES_NOT_IMPLEMENTED;
+                LogError("(result = %s)", MU_ENUM_TO_STRING(AGENT_DATA_TYPES_RESULT, result));
+                break;
+            }
+            case(EDM_COMPLEX_TYPE_TYPE) :
+            {
+                result = AGENT_DATA_TYPES_OK;
+                /*copying a COMPLEX_TYPE means to copy all its member names and all its fields*/
+                dest->type = src->type;
+                if (src->value.edmComplexType.nMembers == 0)
+                {
+                    /*error*/
+                    result = AGENT_DATA_TYPES_INVALID_ARG;
+                    LogError("(result = %s)", MU_ENUM_TO_STRING(AGENT_DATA_TYPES_RESULT, result));
+                }
+                else
+                {
+                    dest->value.edmComplexType.nMembers = src->value.edmComplexType.nMembers;
+                    dest->value.edmComplexType.fields = (COMPLEX_TYPE_FIELD_TYPE*)malloc(dest->value.edmComplexType.nMembers * sizeof(COMPLEX_TYPE_FIELD_TYPE));
+                    if (dest->value.edmComplexType.fields == NULL)
+                    {
+                        result = AGENT_DATA_TYPES_ERROR;
+                        LogError("(result = %s)", MU_ENUM_TO_STRING(AGENT_DATA_TYPES_RESULT, result));
+                    }
+                    else
+                    {
+                        for (i = 0; i < dest->value.edmComplexType.nMembers; i++)
+                        {
+                            dest->value.edmComplexType.fields[i].fieldName = NULL;
+                            dest->value.edmComplexType.fields[i].value = NULL;
+                        }
+
+                        for (i = 0; i < dest->value.edmComplexType.nMembers; i++)
+                        {
+                            /*copy the name of this field*/
+                            if (mallocAndStrcpy_s((char**)(&(dest->value.edmComplexType.fields[i].fieldName)), src->value.edmComplexType.fields[i].fieldName) != 0)
+                            {
+                                result = AGENT_DATA_TYPES_ERROR;
+                                LogError("(result = %s)", MU_ENUM_TO_STRING(AGENT_DATA_TYPES_RESULT, result));
+                                break;
+                            }
+                            else
+                            {
+                                /*field name copied success*/
+                                /*field value copy follows*/
+                                dest->value.edmComplexType.fields[i].value = (AGENT_DATA_TYPE*)calloc(1, sizeof(AGENT_DATA_TYPE));
+                                if (dest->value.edmComplexType.fields[i].value == NULL)
+                                {
+                                    result = AGENT_DATA_TYPES_ERROR;
+                                    LogError("(result = %s)", MU_ENUM_TO_STRING(AGENT_DATA_TYPES_RESULT, result));
+                                    break;
+                                }
+                                else
+                                {
+                                    if (Create_AGENT_DATA_TYPE_from_AGENT_DATA_TYPE(dest->value.edmComplexType.fields[i].value, src->value.edmComplexType.fields[i].value) != AGENT_DATA_TYPES_OK)
+                                    {
+                                        result = AGENT_DATA_TYPES_ERROR;
+                                        LogError("(result = %s)", MU_ENUM_TO_STRING(AGENT_DATA_TYPES_RESULT, result));
+                                        break;
+                                    }
+                                    else
+                                    {
+                                        /*all is fine*/
+                                    }
+                                }
+                            }
+                        }
+
+                        if (result != AGENT_DATA_TYPES_OK)
+                        {
+                            /*unbuild*/
+                            DestroyHalfBakedComplexType(dest);
+                        }
+                    }
+                }
+                break;
+            } /*ANY CHANGE (?!) here must be reflected in the tool providing the binary file (XML2BINARY) */
+        }
+
+        if (result != AGENT_DATA_TYPES_OK)
+        {
+            dest->type = EDM_NO_TYPE;
+        }
+    }
+
+    return result;
+}
+
+AGENT_DATA_TYPES_RESULT Create_AGENT_DATA_TYPE_from_MemberPointers(AGENT_DATA_TYPE* agentData, const char* typeName, size_t nMembers, const char* const * memberNames, const AGENT_DATA_TYPE** memberPointerValues)
+{
+    AGENT_DATA_TYPES_RESULT result;
+
+    /* Codes_SRS_AGENT_TYPE_SYSTEM_99_109:[ AGENT_DATA_TYPES_INVALID_ARG shall be returned if memberPointerValues parameter is NULL.] */
+    if (memberPointerValues == NULL)
+    {
+        result = AGENT_DATA_TYPES_INVALID_ARG;
+        LogError("(result: AGENT_DATA_TYPES_INVALID_ARG)");
+    }
+    else
+    {
+        AGENT_DATA_TYPE* values = (AGENT_DATA_TYPE*)calloc(1, (nMembers* sizeof(AGENT_DATA_TYPE)));
+        if (values == NULL)
+        {
+            result = AGENT_DATA_TYPES_ERROR;
+            LogError("(result = %s)", MU_ENUM_TO_STRING(AGENT_DATA_TYPES_RESULT, result));
+        }
+        else
+        {
+            size_t i;
+            for (i = 0; i < nMembers; i++)
+            {
+                if (Create_AGENT_DATA_TYPE_from_AGENT_DATA_TYPE(values + i, memberPointerValues[i]) != AGENT_DATA_TYPES_OK)
+                {
+                    size_t j;
+                    for (j = 0; j < i; j++)
+                    {
+                        Destroy_AGENT_DATA_TYPE(values + j);
+                    }
+                    break;
+                }
+            }
+
+            if (i != nMembers)
+            {
+                result = AGENT_DATA_TYPES_ERROR;
+                LogError("(result = %s)", MU_ENUM_TO_STRING(AGENT_DATA_TYPES_RESULT, result));
+            }
+            else
+            {
+                /* SRS_AGENT_TYPE_SYSTEM_99_111:[ AGENT_DATA_TYPES_OK shall be returned upon success.] */
+                result = Create_AGENT_DATA_TYPE_from_Members(agentData, typeName, nMembers, memberNames, values);
+                if (result != AGENT_DATA_TYPES_OK)
+                {
+                    LogError("(result = %s)", MU_ENUM_TO_STRING(AGENT_DATA_TYPES_RESULT, result));
+                }
+                for (i = 0; i < nMembers; i++)
+                {
+                    Destroy_AGENT_DATA_TYPE(&values[i]);
+                }
+            }
+            free(values);
+        }
+    }
+    return result;
+}
+
+AGENT_DATA_TYPES_RESULT Create_AGENT_DATA_TYPE_from_Members(AGENT_DATA_TYPE* agentData, const char* typeName, size_t nMembers, const char* const * memberNames, const AGENT_DATA_TYPE* memberValues)
+{
+    AGENT_DATA_TYPES_RESULT result;
+    size_t i;
+    /*Codes_SRS_AGENT_TYPE_SYSTEM_99_013:[ All the functions shall check their parameters for validity. When an invalid parameter is detected, the value AGENT_DATA_TYPES_INVALID_ARG shall be returned ]*/
+    if (agentData == NULL)
+    {
+        result = AGENT_DATA_TYPES_INVALID_ARG;
+        LogError("(result: AGENT_DATA_TYPES_INVALID_ARG)");
+    }
+    /*Codes_SRS_AGENT_TYPE_SYSTEM_99_055:[ If typeName is NULL, the function shall return AGENT_DATA_TYPES_INVALID_ARG .]*/
+    else if (typeName==NULL)
+    {
+        result = AGENT_DATA_TYPES_INVALID_ARG;
+        LogError("(result: AGENT_DATA_TYPES_INVALID_ARG)");
+    }
+    /*Codes_SRS_AGENT_TYPE_SYSTEM_99_056:[If nMembers is 0, the function shall return AGENT_DATA_TYPES_INVALID_ARG .]*/
+    else if (nMembers == 0)
+    {
+        result = AGENT_DATA_TYPES_INVALID_ARG;
+        LogError("(result = %s)", MU_ENUM_TO_STRING(AGENT_DATA_TYPES_RESULT, result));
+    }
+    /*Codes_SRS_AGENT_TYPE_SYSTEM_99_057:[ If memberNames is NULL, the function shall return AGENT_DATA_TYPES_INVALID_ARG .]*/
+    else if (memberNames == NULL)
+    {
+        result = AGENT_DATA_TYPES_INVALID_ARG;
+        LogError("(result = %s)", MU_ENUM_TO_STRING(AGENT_DATA_TYPES_RESULT, result));
+    }
+    /*Codes_SRS_AGENT_TYPE_SYSTEM_99_058:[ If any of the memberNames[i] is NULL, the function shall return AGENT_DATA_TYPES_INVALID_ARG .]*/
+    else if (isOneNameNULL(nMembers, memberNames)!=0)
+    {
+        result = AGENT_DATA_TYPES_INVALID_ARG;
+        LogError("(result = %s)", MU_ENUM_TO_STRING(AGENT_DATA_TYPES_RESULT, result));
+    }
+    /*Codes_SRS_AGENT_TYPE_SYSTEM_99_059:[ If memberValues is NULL, the function shall return AGENT_DATA_TYPES_INVALID_ARG .]*/
+    else if (memberValues == NULL)
+    {
+        result = AGENT_DATA_TYPES_INVALID_ARG;
+        LogError("(result = %s)", MU_ENUM_TO_STRING(AGENT_DATA_TYPES_RESULT, result));
+    }
+    /*Codes_SRS_AGENT_TYPE_SYSTEM_99_063:[ If there are two memberNames with the same name, then the function shall return  AGENT_DATA_TYPES_INVALID_ARG.]*/
+    else if (areThereTwoSameNames(nMembers, memberNames) != 0)
+    {
+        result = AGENT_DATA_TYPES_INVALID_ARG;
+        LogError("(result = %s)", MU_ENUM_TO_STRING(AGENT_DATA_TYPES_RESULT, result));
+    }
+    else
+    {
+        agentData->value.edmComplexType.nMembers = nMembers;
+        agentData->value.edmComplexType.fields = (COMPLEX_TYPE_FIELD_TYPE*)malloc(nMembers *sizeof(COMPLEX_TYPE_FIELD_TYPE));
+        if (agentData->value.edmComplexType.fields == NULL)
+        {
+            result = AGENT_DATA_TYPES_ERROR;
+            LogError("(result = %s)", MU_ENUM_TO_STRING(AGENT_DATA_TYPES_RESULT, result));
+        }
+        else
+        {
+            result = AGENT_DATA_TYPES_OK; /*not liking this, solution might be to use a temp variable*/
+
+            /*initialize the fields*/
+            for (i = 0; i < nMembers; i++)
+            {
+                agentData->value.edmComplexType.fields[i].fieldName = NULL;
+                agentData->value.edmComplexType.fields[i].value = NULL;
+            }
+
+            for (i = 0; i < nMembers; i++)
+            {
+                /*copy the name*/
+                if (mallocAndStrcpy_s((char**)(&(agentData->value.edmComplexType.fields[i].fieldName)), memberNames[i]) != 0)
+                {
+                    result = AGENT_DATA_TYPES_ERROR;
+                    LogError("(result = %s)", MU_ENUM_TO_STRING(AGENT_DATA_TYPES_RESULT, result));
+                    break;
+                }
+                else
+                {
+                    /*field name was transferred successfully*/
+                    /*copy the rest*/
+                    agentData->value.edmComplexType.fields[i].value = (AGENT_DATA_TYPE*)calloc(1, sizeof(AGENT_DATA_TYPE));
+                    if (agentData->value.edmComplexType.fields[i].value == NULL)
+                    {
+                        /*deallocate the name*/
+                        free((void*)(agentData->value.edmComplexType.fields[i].fieldName));
+                        agentData->value.edmComplexType.fields[i].fieldName = NULL;
+                        result = AGENT_DATA_TYPES_ERROR;
+                        LogError("(result = %s)", MU_ENUM_TO_STRING(AGENT_DATA_TYPES_RESULT, result));
+                        break;
+                    }
+                    else
+                    {
+                        /*copy the values*/
+                        if (Create_AGENT_DATA_TYPE_from_AGENT_DATA_TYPE(agentData->value.edmComplexType.fields[i].value, &(memberValues[i])) != AGENT_DATA_TYPES_OK)
+                        {
+                            result = AGENT_DATA_TYPES_ERROR;
+                            LogError("(result = %s)", MU_ENUM_TO_STRING(AGENT_DATA_TYPES_RESULT, result));
+                            break;
+                        }
+                        else
+                        {
+                            /*all is fine*/
+                        }
+                    }
+                }
+
+            }
+        }
+
+        if (result != AGENT_DATA_TYPES_OK)
+        {
+            /*dealloc, something went bad*/
+            DestroyHalfBakedComplexType(agentData);
+        }
+        else
+        {
+            agentData->type = EDM_COMPLEX_TYPE_TYPE;
+        }
+    }
+    return result;
+}
+
+#define isLeapYear(y) ((((y) % 400) == 0) || (((y)%4==0)&&(!((y)%100==0))))
+
+static int daysInAllPreviousMonths(int month)
+{
+    int result = 0;
+    for (int i = 0; i < month; i++)
+    {
+        switch (i)
+        {
+        case 0:
+        case 2:
+        case 4:
+        case 6:
+        case 7:
+        case 9:
+            result += 31;
+            break;
+        case 1:
+            result += 28;
+            break;
+        default:
+            result += 30;
+        }
+    }
+    return result;
+}
+
+/*this function assumes a correctly filled in tm_year, tm_mon and tm_mday and will fill in tm_yday and tm_wday*/
+static void fill_tm_yday_and_tm_wday(struct tm* source)
+{
+    /*to fill in tm_yday the function shall add the number of days in every month, not including the current one*/
+    /*and then it will add the number of days in the current month*/
+    /*1st of Jan is day "0" in a year*/
+    int year = source->tm_year + 1900 + 10000;
+    int nLeapYearsSinceYearMinus9999 = ((year - 1) / 4) - ((year - 1) / 100) + ((year - 1) / 400);
+    source->tm_yday = (daysInAllPreviousMonths(source->tm_mon)) + (source->tm_mday - 1) + ((source->tm_mon > 1 /*1 is Feb*/) && isLeapYear(year));
+    source->tm_wday = ((365 * year + nLeapYearsSinceYearMinus9999) + source->tm_yday) % 7;
+    /*day "0" is 1st jan -9999 (this is how much odata can span*/
+    /*the function shall count days */
+}
+
+/*the following function does the same as  sscanf(pos2, ":%02d", &sec)*/
+/*this function only exists because of optimizing valgrind time, otherwise sscanf would be just as good*/
+static int sscanf2d(const char *pos2, int* sec)
+{
+    int result;
+    size_t position = 1;
+    if (
+        (pos2[0] == ':') &&
+        (scanAndReadNDigitsInt(pos2, &position, sec, 2) == 0)
+        )
+    {
+        result = 1;
+    }
+    else
+    {
+        result = EOF;
+    }
+
+    return result;
+
+}
+
+/*the following function does the same as  sscanf(pos2, "%d", &sec)*/
+/*this function only exists because of optimizing valgrind time, otherwise sscanf would be just as good*/
+static int sscanfd(const char *src, int* dst)
+{
+    int result;
+    char* next;
+    long int temp = strtol(src, &next, 10);
+    if ((src == next) || (((temp == LONG_MAX) || (temp == LONG_MIN)) && (errno != 0)))
+    {
+        result = EOF;
+    }
+    else
+    {
+        (*dst) = (int)temp;
+        result = 1;
+    }
+    return result;
+}
+
+/*the following function does the same as  sscanf(src, "%llu", &dst), but, it changes the src pointer.*/
+static int sscanfllu(const char** src, unsigned long long* dst)
+{
+    int result = 1;
+    char* next;
+    (*dst) = strtoull((*src), &next, 10);
+    if (((*src) == (const char*)next) || (((*dst) == ULLONG_MAX) && (errno != 0)))
+    {
+        result = EOF;
+    }
+    (*src) = (const char*)next;
+    return result;
+}
+
+/*the following function does the same as  sscanf(src, ".%llu", &dst)*/
+static int sscanfdotllu(const char*src, unsigned long long* dst)
+{
+    int result;
+
+    if ((*src) != '.')
+    {
+        /*doesn't start with '.' error out*/
+        result = EOF;
+    }
+    else
+    {
+        src++;
+        result = sscanfllu(&src, dst);
+    }
+
+    return result;
+}
+
+/*the following function does the same as  sscanf(src, "%u", &dst)*/
+static int sscanfu(const char* src, uint32_t* dst)
+{
+    int result;
+    char* next;
+    unsigned long int temp = strtoul(src, &next, 10);
+    if ((src == next) || ((temp == ULONG_MAX) && (errno != 0)))
+    {
+        result = EOF;
+    }
+    else
+    {
+        result = 1;
+        (*dst) = (uint32_t)temp;
+    }
+    return result;
+}
+
+/*the following function does the same as  sscanf(src, "%f", &dst)*/
+static int sscanff(const char*src, float* dst)
+{
+    int result = 1;
+    char* next;
+    (*dst) = strtof(src, &next);
+    if ((src == next) || (((*dst) == HUGE_VALF) && (errno != 0)))
+    {
+        result = EOF;
+    }
+    return result;
+}
+
+/*the following function does the same as  sscanf(src, "%lf", &dst)*/
+static int sscanflf(const char*src, double* dst)
+{
+    int result = 1;
+    char* next;
+    (*dst) = strtod(src, &next);
+    if ((src == next) || (((*dst) == HUGE_VALL) && (errno != 0)))
+    {
+        result = EOF;
+    }
+    return result;
+}
+
+
+/*the below function replaces sscanf(src, "%03d:%02d\"", &hourOffset, &minOffset)*/
+/*return 2 if success*/
+
+static int sscanf3d2d(const char* src, int* hourOffset, int* minOffset)
+{
+    size_t position = 0;
+    int result = EOF;
+    bool isNegative = false;
+
+    if (*src == '+')
+    {
+        position++;
+    }
+    else if (*src == '-')
+    {
+        isNegative = true;
+        position++;
+    }
+
+    if (
+        (scanAndReadNDigitsInt(src, &position, hourOffset, (3-position)) == 0) &&
+        (src[position++] == ':') &&
+        (scanAndReadNDigitsInt(src, &position, minOffset, 2) == 0)
+        )
+    {
+        result = 2;
+    }
+    else
+    {
+        result = 0;
+    }
+    if (isNegative)
+        *hourOffset *= -1;
+
+    return result;
+}
+
+AGENT_DATA_TYPES_RESULT CreateAgentDataType_From_String(const char* source, AGENT_DATA_TYPE_TYPE type, AGENT_DATA_TYPE* agentData)
+{
+
+    AGENT_DATA_TYPES_RESULT result;
+
+    /* Codes_SRS_AGENT_TYPE_SYSTEM_99_073:[ CreateAgentDataType_From_String shall return AGENT_DATA_TYPES_INVALID_ARG if source is NULL.] */
+    if ((source == NULL) ||
+        /* Codes_SRS_AGENT_TYPE_SYSTEM_99_074:[ CreateAgentDataType_From_String shall return AGENT_DATA_TYPES_INVALID_ARG if agentData is NULL.] */
+        (agentData == NULL))
+    {
+        result = AGENT_DATA_TYPES_INVALID_ARG;
+        LogError("(result = %s)", MU_ENUM_TO_STRING(AGENT_DATA_TYPES_RESULT, result));
+    }
+    else
+    {
+        /* Codes_SRS_AGENT_TYPE_SYSTEM_99_071:[ CreateAgentDataType_From_String shall create an AGENT_DATA_TYPE from a char* representation of the type indicated by type parameter.] */
+        /* Codes_SRS_AGENT_TYPE_SYSTEM_99_072:[ The implementation for the transformation of the char* source into AGENT_DATA_TYPE shall be type specific.] */
+        switch (type)
+        {
+            default:
+                /* Codes_SRS_AGENT_TYPE_SYSTEM_99_075:[ CreateAgentDataType_From_String shall return AGENT_DATA_TYPES_NOT_IMPLEMENTED if type is not a supported type.] */
+                result = AGENT_DATA_TYPES_NOT_IMPLEMENTED;
+                LogError("(result = %s)", MU_ENUM_TO_STRING(AGENT_DATA_TYPES_RESULT, result));
+                break;
+
+            /* Codes_SRS_AGENT_TYPE_SYSTEM_99_086:[ EDM_STRING] */
+            case EDM_BOOLEAN_TYPE:
+            {
+                if (strcmp(source, "true") == 0)
+                {
+                    agentData->type = EDM_BOOLEAN_TYPE;
+                    agentData->value.edmBoolean.value = EDM_TRUE;
+                    result = AGENT_DATA_TYPES_OK;
+                }
+                else if (strcmp(source, "false") == 0)
+                {
+                    agentData->type = EDM_BOOLEAN_TYPE;
+                    agentData->value.edmBoolean.value = EDM_FALSE;
+                    result = AGENT_DATA_TYPES_OK;
+                }
+                else
+                {
+                    /* Codes_SRS_AGENT_TYPE_SYSTEM_99_087:[ CreateAgentDataType_From_String shall return AGENT_DATA_TYPES_INVALID_ARG if source is not a valid string for a value of type type.] */
+                    result = AGENT_DATA_TYPES_INVALID_ARG;
+                    LogError("(result = %s)", MU_ENUM_TO_STRING(AGENT_DATA_TYPES_RESULT, result));
+                }
+
+                break;
+            }
+            case EDM_NULL_TYPE:
+            {
+                if (strcmp(source, "null") == 0)
+                {
+                    agentData->type = EDM_NULL_TYPE;
+                    result = AGENT_DATA_TYPES_OK;
+                }
+                else
+                {
+                    /* Codes_SRS_AGENT_TYPE_SYSTEM_99_087:[ CreateAgentDataType_From_String shall return AGENT_DATA_TYPES_INVALID_ARG if source is not a valid string for a value of type type.] */
+                    result = AGENT_DATA_TYPES_INVALID_ARG;
+                    LogError("(result = %s)", MU_ENUM_TO_STRING(AGENT_DATA_TYPES_RESULT, result));
+                }
+
+                break;
+            }
+
+            /* Codes_SRS_AGENT_TYPE_SYSTEM_99_084:[ EDM_SBYTE] */
+            case EDM_SBYTE_TYPE:
+            {
+                int sByteValue;
+                if ((sscanfd(source, &sByteValue) != 1) ||
+                    (sByteValue < -128) ||
+                    (sByteValue > 127))
+                {
+                    /* Codes_SRS_AGENT_TYPE_SYSTEM_99_087:[ CreateAgentDataType_From_String shall return AGENT_DATA_TYPES_INVALID_ARG if source is not a valid string for a value of type type.] */
+                    result = AGENT_DATA_TYPES_INVALID_ARG;
+                    LogError("(result = %s)", MU_ENUM_TO_STRING(AGENT_DATA_TYPES_RESULT, result));
+                }
+                else
+                {
+                    agentData->type = EDM_SBYTE_TYPE;
+                    agentData->value.edmSbyte.value = (int8_t)sByteValue;
+                    result = AGENT_DATA_TYPES_OK;
+                }
+
+                break;
+            }
+
+            /* Codes_SRS_AGENT_TYPE_SYSTEM_99_077:[ EDM_BYTE] */
+            case EDM_BYTE_TYPE:
+            {
+                int byteValue;
+                if ((sscanfd(source, &byteValue) != 1) ||
+                    (byteValue < 0) ||
+                    (byteValue > 255))
+                {
+                    /* Codes_SRS_AGENT_TYPE_SYSTEM_99_087:[ CreateAgentDataType_From_String shall return AGENT_DATA_TYPES_INVALID_ARG if source is not a valid string for a value of type type.] */
+                    result = AGENT_DATA_TYPES_INVALID_ARG;
+                    LogError("(result = %s)", MU_ENUM_TO_STRING(AGENT_DATA_TYPES_RESULT, result));
+                }
+                else
+                {
+                    agentData->type = EDM_BYTE_TYPE;
+                    agentData->value.edmByte.value = (uint8_t)byteValue;
+                    result = AGENT_DATA_TYPES_OK;
+                }
+
+                break;
+            }
+
+            /* Codes_SRS_AGENT_TYPE_SYSTEM_99_081:[ EDM_INT16] */
+            case EDM_INT16_TYPE:
+            {
+                int int16Value;
+                if ((sscanfd(source, &int16Value) != 1) ||
+                    (int16Value < -32768) ||
+                    (int16Value > 32767))
+                {
+                    /* Codes_SRS_AGENT_TYPE_SYSTEM_99_087:[ CreateAgentDataType_From_String shall return AGENT_DATA_TYPES_INVALID_ARG if source is not a valid string for a value of type type.] */
+                    result = AGENT_DATA_TYPES_INVALID_ARG;
+                    LogError("(result = %s)", MU_ENUM_TO_STRING(AGENT_DATA_TYPES_RESULT, result));
+                }
+                else
+                {
+                    agentData->type = EDM_INT16_TYPE;
+                    agentData->value.edmInt16.value = (int16_t)int16Value;
+                    result = AGENT_DATA_TYPES_OK;
+                }
+
+                break;
+            }
+
+            /* Codes_SRS_AGENT_TYPE_SYSTEM_99_082:[ EDM_INT32] */
+            case EDM_INT32_TYPE:
+            {
+                int32_t int32Value;
+                unsigned char isNegative;
+                uint32_t uint32Value;
+                const char* pos;
+                size_t strLength;
+
+                if (source[0] == '-')
+                {
+                    isNegative = 1;
+                    pos = &source[1];
+                }
+                else
+                {
+                    isNegative = 0;
+                    pos = &source[0];
+                }
+
+                strLength = strlen(source);
+
+                if ((sscanfu(pos, &uint32Value) != 1) ||
+                    (strLength > 11) ||
+                    ((uint32Value > 2147483648UL) && isNegative) ||
+                    ((uint32Value > 2147483647UL) && (!isNegative)))
+                {
+                    /* Codes_SRS_AGENT_TYPE_SYSTEM_99_087:[ CreateAgentDataType_From_String shall return AGENT_DATA_TYPES_INVALID_ARG if source is not a valid string for a value of type type.] */
+                    result = AGENT_DATA_TYPES_INVALID_ARG;
+                    LogError("(result = %s)", MU_ENUM_TO_STRING(AGENT_DATA_TYPES_RESULT, result));
+                }
+                else
+                {
+                    if (isNegative)
+                    {
+                        if (uint32Value == 2147483648UL)
+                        {
+                           int32Value = -2147483647L - 1L;
+                        }
+                        else
+                        {
+                            int32Value = -(int32_t)uint32Value;
+                        }
+                    }
+                    else
+                    {
+                        int32Value = uint32Value;
+                    }
+
+                    agentData->type = EDM_INT32_TYPE;
+                    agentData->value.edmInt32.value = (int32_t)int32Value;
+                    result = AGENT_DATA_TYPES_OK;
+                }
+
+                break;
+            }
+
+            /* Codes_SRS_AGENT_TYPE_SYSTEM_99_083:[ EDM_INT64] */
+            case EDM_INT64_TYPE:
+            {
+                long long int64Value;
+                unsigned char isNegative;
+                unsigned long long ullValue;
+                const char* pos;
+                size_t strLength;
+
+                if (source[0] == '-')
+                {
+                    isNegative = 1;
+                    pos = &source[1];
+                }
+                else
+                {
+                    isNegative = 0;
+                    pos = &source[0];
+                }
+
+                strLength = strlen(source);
+
+                if ((sscanfllu(&pos, &ullValue) != 1) ||
+                    (strLength > 20) ||
+                    ((ullValue > 9223372036854775808ULL) && isNegative) ||
+                    ((ullValue > 9223372036854775807ULL) && (!isNegative)))
+                {
+                    /* Codes_SRS_AGENT_TYPE_SYSTEM_99_087:[ CreateAgentDataType_From_String shall return AGENT_DATA_TYPES_INVALID_ARG if source is not a valid string for a value of type type.] */
+                    result = AGENT_DATA_TYPES_INVALID_ARG;
+                    LogError("(result = %s)", MU_ENUM_TO_STRING(AGENT_DATA_TYPES_RESULT, result));
+                }
+                else
+                {
+                    if (isNegative)
+                    {
+                        if (ullValue == 9223372036854775808ULL)
+                        {
+                            int64Value = -9223372036854775807LL - 1LL;
+                        }
+                        else
+                        {
+                            int64Value = -(long long)ullValue;
+                        }
+                    }
+                    else
+                    {
+                        int64Value = ullValue;
+                    }
+                    agentData->type = EDM_INT64_TYPE;
+                    agentData->value.edmInt64.value = (int64_t)int64Value;
+                    result = AGENT_DATA_TYPES_OK;
+                }
+
+                break;
+            }
+
+            /* Codes_SRS_AGENT_TYPE_SYSTEM_99_085:[ EDM_DATE] */
+            case EDM_DATE_TYPE:
+            {
+                int year;
+                int month;
+                int day;
+                size_t strLength = strlen(source);
+
+                if ((strLength < 2) ||
+                    (source[0] != '"') ||
+                    (source[strLength - 1] != '"'))
+                {
+                    /* Codes_SRS_AGENT_TYPE_SYSTEM_99_087:[ CreateAgentDataType_From_String shall return AGENT_DATA_TYPES_INVALID_ARG if source is not a valid string for a value of type type.] */
+                    result = AGENT_DATA_TYPES_INVALID_ARG;
+                    LogError("(result = %s)", MU_ENUM_TO_STRING(AGENT_DATA_TYPES_RESULT, result));
+                }
+                else
+                {
+                    size_t pos = 1;
+                    int sign;
+                    scanOptionalMinusSign(source, 2, &pos, &sign);
+
+                    if ((scanAndReadNDigitsInt(source, &pos, &year, 4) != 0) ||
+                        (source[pos++] != '-') ||
+                        (scanAndReadNDigitsInt(source, &pos, &month, 2) != 0) ||
+                        (source[pos++] != '-') ||
+                        (scanAndReadNDigitsInt(source, &pos, &day, 2) != 0) ||
+                        (Create_AGENT_DATA_TYPE_from_date(agentData, (int16_t)(sign*year), (uint8_t)month, (uint8_t)day) != AGENT_DATA_TYPES_OK))
+                    {
+                        /* Codes_SRS_AGENT_TYPE_SYSTEM_99_087:[ CreateAgentDataType_From_String shall return AGENT_DATA_TYPES_INVALID_ARG if source is not a valid string for a value of type type.] */
+                        result = AGENT_DATA_TYPES_INVALID_ARG;
+                        LogError("(result = %s)", MU_ENUM_TO_STRING(AGENT_DATA_TYPES_RESULT, result));
+                    }
+                    else
+                    {
+                        result = AGENT_DATA_TYPES_OK;
+                    }
+                }
+
+                break;
+            }
+
+            /* Codes_SRS_AGENT_TYPE_SYSTEM_99_078:[ EDM_DATETIMEOFFSET] */
+            case EDM_DATE_TIME_OFFSET_TYPE:
+            {
+                int year;
+                int month;
+                int day;
+                int hour;
+                int min;
+                int sec = 0;
+                int hourOffset;
+                int minOffset;
+                unsigned long long fractionalSeconds = 0;
+                size_t strLength = strlen(source);
+
+                agentData->value.edmDateTimeOffset.hasFractionalSecond = 0;
+                agentData->value.edmDateTimeOffset.hasTimeZone = 0;
+                /* The value of tm_isdst is positive if Daylight Saving Time is in effect, zero if Daylight
+                   Saving Time is not in effect, and negative if the information is not available.*/
+                agentData->value.edmDateTimeOffset.dateTime.tm_isdst = -1;
+
+                if ((strLength < 2) ||
+                    (source[0] != '"') ||
+                    (source[strLength - 1] != '"'))
+                {
+                    /* Codes_SRS_AGENT_TYPE_SYSTEM_99_087:[ CreateAgentDataType_From_String shall return AGENT_DATA_TYPES_INVALID_ARG if source is not a valid string for a value of type type.] */
+                    result = AGENT_DATA_TYPES_INVALID_ARG;
+                    LogError("(result = %s)", MU_ENUM_TO_STRING(AGENT_DATA_TYPES_RESULT, result));
+                }
+                else
+                {
+                    size_t pos = 1;
+                    int sign;
+                    scanOptionalMinusSign(source, 2, &pos, &sign);
+
+                    if ((scanAndReadNDigitsInt(source, &pos, &year, 4) != 0) ||
+                        (source[pos++] != '-') ||
+                        (scanAndReadNDigitsInt(source, &pos, &month, 2) != 0) ||
+                        (source[pos++] != '-') ||
+                        (scanAndReadNDigitsInt(source, &pos, &day, 2) != 0) ||
+                        (source[pos++] != 'T') ||
+                        (scanAndReadNDigitsInt(source, &pos, &hour, 2) != 0) ||
+                        (source[pos++] != ':') ||
+                        (scanAndReadNDigitsInt(source, &pos, &min, 2) != 0))
+                    {
+                        /* Codes_SRS_AGENT_TYPE_SYSTEM_99_087:[ CreateAgentDataType_From_String shall return AGENT_DATA_TYPES_INVALID_ARG if source is not a valid string for a value of type type.] */
+                        result = AGENT_DATA_TYPES_INVALID_ARG;
+                        LogError("(result = %s)", MU_ENUM_TO_STRING(AGENT_DATA_TYPES_RESULT, result));
+                    }
+                    else
+                    {
+                        const char* pos2;
+                        year = year*sign;
+                        if ((pos2 = strchr(source, ':')) == NULL)
+                        {
+                            /* Codes_SRS_AGENT_TYPE_SYSTEM_99_087:[ CreateAgentDataType_From_String shall return AGENT_DATA_TYPES_INVALID_ARG if source is not a valid string for a value of type type.] */
+                            result = AGENT_DATA_TYPES_INVALID_ARG;
+                            LogError("(result = %s)", MU_ENUM_TO_STRING(AGENT_DATA_TYPES_RESULT, result));
+                        }
+                        else
+                        {
+                            pos2 += 3;
+                            if (*pos2 == ':')
+                            {
+                                if (sscanf2d(pos2, &sec) != 1)
+                                {
+                                    pos2 = NULL;
+                                }
+                                else
+                                {
+                                    pos2 += 3;
+                                }
+                            }
+
+                            if ((pos2 != NULL) &&
+                                (*pos2 == '.'))
+                            {
+                                if (sscanfdotllu(pos2, &fractionalSeconds) != 1)
+                                {
+                                    pos2 = NULL;
+                                }
+                                else
+                                {
+                                    pos2++;
+
+                                    agentData->value.edmDateTimeOffset.hasFractionalSecond = 1;
+
+                                    while ((*pos2 != '\0') &&
+                                        (IS_DIGIT(*pos2)))
+                                    {
+                                        pos2++;
+                                    }
+
+                                    if (*pos2 == '\0')
+                                    {
+                                        pos2 = NULL;
+                                    }
+                                }
+                            }
+
+                            if (pos2 == NULL)
+                            {
+                                /* Codes_SRS_AGENT_TYPE_SYSTEM_99_087:[ CreateAgentDataType_From_String shall return AGENT_DATA_TYPES_INVALID_ARG if source is not a valid string for a value of type type.] */
+                                result = AGENT_DATA_TYPES_INVALID_ARG;
+                                LogError("(result = %s)", MU_ENUM_TO_STRING(AGENT_DATA_TYPES_RESULT, result));
+                            }
+                            else
+                            {
+                                hourOffset = 0;
+                                minOffset = 0;
+
+                                if (sscanf3d2d(pos2, &hourOffset, &minOffset) == 2)
+                                {
+                                    agentData->value.edmDateTimeOffset.hasTimeZone = 1;
+                                }
+
+                                if ((strcmp(pos2, "Z\"") == 0) ||
+                                    agentData->value.edmDateTimeOffset.hasTimeZone)
+                                {
+                                    if ((ValidateDate(year, month, day) != 0) ||
+                                        (hour < 0) ||
+                                        (hour > 23) ||
+                                        (min < 0) ||
+                                        (min > 59) ||
+                                        (sec < 0) ||
+                                        (sec > 59) ||
+                                        (fractionalSeconds > 999999999999) ||
+                                        (hourOffset < -23) ||
+                                        (hourOffset > 23) ||
+                                        (minOffset < 0) ||
+                                        (minOffset > 59))
+                                    {
+                                        /* Codes_SRS_AGENT_TYPE_SYSTEM_99_087:[ CreateAgentDataType_From_String shall return AGENT_DATA_TYPES_INVALID_ARG if source is not a valid string for a value of type type.] */
+                                        result = AGENT_DATA_TYPES_INVALID_ARG;
+                                        LogError("(result = %s)", MU_ENUM_TO_STRING(AGENT_DATA_TYPES_RESULT, result));
+                                    }
+                                    else
+                                    {
+                                        agentData->type = EDM_DATE_TIME_OFFSET_TYPE;
+                                        agentData->value.edmDateTimeOffset.dateTime.tm_year= year-1900;
+                                        agentData->value.edmDateTimeOffset.dateTime.tm_mon = month-1;
+                                        agentData->value.edmDateTimeOffset.dateTime.tm_mday = day;
+                                        agentData->value.edmDateTimeOffset.dateTime.tm_hour = hour;
+                                        agentData->value.edmDateTimeOffset.dateTime.tm_min = min;
+                                        agentData->value.edmDateTimeOffset.dateTime.tm_sec = sec;
+                                        /*fill in tm_wday and tm_yday*/
+                                        fill_tm_yday_and_tm_wday(&agentData->value.edmDateTimeOffset.dateTime);
+                                        agentData->value.edmDateTimeOffset.fractionalSecond = (uint64_t)fractionalSeconds;
+                                        agentData->value.edmDateTimeOffset.timeZoneHour = (int8_t)hourOffset;
+                                        agentData->value.edmDateTimeOffset.timeZoneMinute = (uint8_t)minOffset;
+                                        result = AGENT_DATA_TYPES_OK;
+                                    }
+                                }
+                                else
+                                {
+                                    /* Codes_SRS_AGENT_TYPE_SYSTEM_99_087:[ CreateAgentDataType_From_String shall return AGENT_DATA_TYPES_INVALID_ARG if source is not a valid string for a value of type type.] */
+                                    result = AGENT_DATA_TYPES_INVALID_ARG;
+                                    LogError("(result = %s)", MU_ENUM_TO_STRING(AGENT_DATA_TYPES_RESULT, result));
+                                }
+                            }
+                        }
+                    }
+                }
+
+                break;
+            }
+
+            /* Codes_SRS_AGENT_TYPE_SYSTEM_99_080:[ EDM_DOUBLE] */
+            case EDM_DOUBLE_TYPE:
+            {
+                if (strcmp(source, "\"NaN\"") == 0)
+                {
+                    agentData->type = EDM_DOUBLE_TYPE;
+                    agentData->value.edmDouble.value = NAN;
+                    result = AGENT_DATA_TYPES_OK;
+                }
+                else if (strcmp(source, "\"INF\"") == 0)
+                {
+                    agentData->type = EDM_DOUBLE_TYPE;
+                    agentData->value.edmDouble.value = INFINITY;
+                    result = AGENT_DATA_TYPES_OK;
+                }
+                else if (strcmp(source, "\"-INF\"") == 0)
+                {
+                    agentData->type = EDM_DOUBLE_TYPE;
+#ifdef _MSC_VER
+#pragma warning(push)
+#pragma warning(disable: 4056) /* Known warning for INIFNITY */
+#endif
+                    agentData->value.edmDouble.value = -INFINITY;
+#ifdef _MSC_VER
+#pragma warning(pop)
+#endif
+                    result = AGENT_DATA_TYPES_OK;
+                }
+                else if (sscanflf(source, &(agentData->value.edmDouble.value)) != 1)
+                {
+                    /* Codes_SRS_AGENT_TYPE_SYSTEM_99_087:[ CreateAgentDataType_From_String shall return AGENT_DATA_TYPES_INVALID_ARG if source is not a valid string for a value of type type.] */
+                    result = AGENT_DATA_TYPES_INVALID_ARG;
+                }
+                else
+                {
+                    agentData->type = EDM_DOUBLE_TYPE;
+                    result = AGENT_DATA_TYPES_OK;
+                }
+                break;
+            }
+
+            /* Codes_SRS_AGENT_TYPE_SYSTEM_99_089:[EDM_SINGLE] */
+            case EDM_SINGLE_TYPE:
+            {
+                if (strcmp(source, "\"NaN\"") == 0)
+                {
+                    agentData->type = EDM_SINGLE_TYPE;
+                    agentData->value.edmSingle.value = NAN;
+                    result = AGENT_DATA_TYPES_OK;
+                }
+                else if (strcmp(source, "\"INF\"") == 0)
+                {
+                    agentData->type = EDM_SINGLE_TYPE;
+                    agentData->value.edmSingle.value = INFINITY;
+                    result = AGENT_DATA_TYPES_OK;
+                }
+                else if (strcmp(source, "\"-INF\"") == 0)
+                {
+                    agentData->type = EDM_SINGLE_TYPE;
+#ifdef _MSC_VER
+#pragma warning(push)
+#pragma warning(disable: 4056) /* Known warning for INIFNITY */
+#endif
+                    agentData->value.edmSingle.value = -INFINITY;
+#ifdef _MSC_VER
+#pragma warning(pop)
+#endif
+result = AGENT_DATA_TYPES_OK;
+                }
+                else if (sscanff(source, &agentData->value.edmSingle.value) != 1)
+                {
+                    /* Codes_SRS_AGENT_TYPE_SYSTEM_99_087:[ CreateAgentDataType_From_String shall return AGENT_DATA_TYPES_INVALID_ARG if source is not a valid string for a value of type type.] */
+                    result = AGENT_DATA_TYPES_INVALID_ARG;
+                    LogError("(result = %s)", MU_ENUM_TO_STRING(AGENT_DATA_TYPES_RESULT, result));
+                }
+                else
+                {
+                    agentData->type = EDM_SINGLE_TYPE;
+                    result = AGENT_DATA_TYPES_OK;
+                }
+                break;
+            }
+
+            /* Codes_SRS_AGENT_TYPE_SYSTEM_99_079:[ EDM_DECIMAL] */
+            case EDM_DECIMAL_TYPE:
+            {
+                size_t strLength = strlen(source);
+                if ((strLength < 2) ||
+                    (source[0] != '"') ||
+                    (source[strLength - 1] != '"') ||
+                    (ValidateDecimal(source + 1, strLength - 2) != 0))
+                {
+                    /* Codes_SRS_AGENT_TYPE_SYSTEM_99_087:[ CreateAgentDataType_From_String shall return AGENT_DATA_TYPES_INVALID_ARG if source is not a valid string for a value of type type.] */
+                    result = AGENT_DATA_TYPES_INVALID_ARG;
+                    LogError("(result = %s)", MU_ENUM_TO_STRING(AGENT_DATA_TYPES_RESULT, result));
+                }
+                else
+                {
+                    agentData->type = EDM_DECIMAL_TYPE;
+                    agentData->value.edmDecimal.value = STRING_construct_n(source + 1, strLength-2);
+                    if (agentData->value.edmDecimal.value == NULL)
+                    {
+                        /* Codes_SRS_AGENT_TYPE_SYSTEM_99_088:[ CreateAgentDataType_From_String shall return AGENT_DATA_TYPES_ERROR if any other error occurs.] */
+                        result = AGENT_DATA_TYPES_ERROR;
+                        LogError("(result = %s)", MU_ENUM_TO_STRING(AGENT_DATA_TYPES_RESULT, result));
+                    }
+                    else
+                    {
+                        result = AGENT_DATA_TYPES_OK;
+                    }
+                }
+                break;
+            }
+
+            /* Codes_SRS_AGENT_TYPE_SYSTEM_99_086:[ EDM_STRING] */
+            case EDM_STRING_TYPE:
+            {
+                size_t strLength = strlen(source);
+                if ((strLength < 2) ||
+                    (source[0] != '"') ||
+                    (source[strLength - 1] != '"'))
+                {
+                    /* Codes_SRS_AGENT_TYPE_SYSTEM_99_087:[ CreateAgentDataType_From_String shall return AGENT_DATA_TYPES_INVALID_ARG if source is not a valid string for a value of type type.] */
+                    result = AGENT_DATA_TYPES_INVALID_ARG;
+                    LogError("(result = %s)", MU_ENUM_TO_STRING(AGENT_DATA_TYPES_RESULT, result));
+                }
+                else
+                {
+                    char* temp;
+                    if ((temp = (char*)malloc(strLength - 1)) == NULL)
+                    {
+                        result = AGENT_DATA_TYPES_ERROR;
+                        LogError("(result = %s)", MU_ENUM_TO_STRING(AGENT_DATA_TYPES_RESULT, result));
+                    }
+                    else if (memcpy(temp, source + 1, strLength - 2) == NULL)
+                    {
+                        free(temp);
+
+                        result = AGENT_DATA_TYPES_ERROR;
+                        LogError("(result = %s)", MU_ENUM_TO_STRING(AGENT_DATA_TYPES_RESULT, result));
+                    }
+                    else
+                    {
+                        // Removes the "
+                        temp[strLength - 2] = 0;
+                        agentData->type = EDM_STRING_TYPE;
+                        agentData->value.edmString.chars = temp;
+                        agentData->value.edmString.length = strLength - 2;
+                        result = AGENT_DATA_TYPES_OK;
+                    }
+                }
+                break;
+            }
+            /* Codes_SRS_AGENT_TYPE_SYSTEM_01_004: [EDM_STRING_NO_QUOTES] */
+            case EDM_STRING_NO_QUOTES_TYPE:
+            {
+                char* temp;
+                size_t strLength = strlen(source);
+                if (mallocAndStrcpy_s(&temp, source) != 0)
+                {
+                    result = AGENT_DATA_TYPES_ERROR;
+                    LogError("(result = %s)", MU_ENUM_TO_STRING(AGENT_DATA_TYPES_RESULT, result));
+                }
+                else
+                {
+                    agentData->type = EDM_STRING_NO_QUOTES_TYPE;
+                    agentData->value.edmStringNoQuotes.chars = temp;
+                    agentData->value.edmStringNoQuotes.length = strLength;
+                    result = AGENT_DATA_TYPES_OK;
+                }
+                break;
+            }
+            /*Codes_SRS_AGENT_TYPE_SYSTEM_99_097:[ EDM_GUID]*/
+            case EDM_GUID_TYPE:
+            {
+                if (strlen(source) != GUID_STRING_LENGTH)
+                {
+                    result = AGENT_DATA_TYPES_INVALID_ARG;
+                }
+                else
+                {
+                    if (source[0] != '"')
+                    {
+                        result = AGENT_DATA_TYPES_INVALID_ARG;
+                    }
+                    else if (scanMandatory2CapitalHexDigits(source + 1, &(agentData->value.edmGuid.GUID[0])) != 0)
+                    {
+                        result = AGENT_DATA_TYPES_INVALID_ARG;
+                    }
+                    else if (scanMandatory2CapitalHexDigits(source + 3, &(agentData->value.edmGuid.GUID[1])) != 0)
+                    {
+                        result = AGENT_DATA_TYPES_INVALID_ARG;
+                    }
+                    else if (scanMandatory2CapitalHexDigits(source + 5, &(agentData->value.edmGuid.GUID[2])) != 0)
+                    {
+                        result = AGENT_DATA_TYPES_INVALID_ARG;
+                    }
+                    else if (scanMandatory2CapitalHexDigits(source + 7, &(agentData->value.edmGuid.GUID[3])) != 0)
+                    {
+                        result = AGENT_DATA_TYPES_INVALID_ARG;
+                    }
+                    else if (source[9] != '-')
+                    {
+                        result = AGENT_DATA_TYPES_INVALID_ARG;
+                    }
+                    else if (scanMandatory2CapitalHexDigits(source + 10, &(agentData->value.edmGuid.GUID[4])) != 0)
+                    {
+                        result = AGENT_DATA_TYPES_INVALID_ARG;
+                    }
+                    else if (scanMandatory2CapitalHexDigits(source + 12, &(agentData->value.edmGuid.GUID[5])) != 0)
+                    {
+                        result = AGENT_DATA_TYPES_INVALID_ARG;
+                    }
+                    else if (source[14] != '-')
+                    {
+                        result = AGENT_DATA_TYPES_INVALID_ARG;
+                    }
+                    else if (scanMandatory2CapitalHexDigits(source + 15, &(agentData->value.edmGuid.GUID[6])) != 0)
+                    {
+                        result = AGENT_DATA_TYPES_INVALID_ARG;
+                    }
+                    else if (scanMandatory2CapitalHexDigits(source + 17, &(agentData->value.edmGuid.GUID[7])) != 0)
+                    {
+                        result = AGENT_DATA_TYPES_INVALID_ARG;
+                    }
+                    else if (source[19] != '-')
+                    {
+                        result = AGENT_DATA_TYPES_INVALID_ARG;
+                    }
+                    else if (scanMandatory2CapitalHexDigits(source + 20, &(agentData->value.edmGuid.GUID[8])) != 0)
+                    {
+                        result = AGENT_DATA_TYPES_INVALID_ARG;
+                    }
+                    else if (scanMandatory2CapitalHexDigits(source + 22, &(agentData->value.edmGuid.GUID[9])) != 0)
+                    {
+                        result = AGENT_DATA_TYPES_INVALID_ARG;
+                    }
+                    else if (source[24] != '-')
+                    {
+                        result = AGENT_DATA_TYPES_INVALID_ARG;
+                    }
+                    else if (scanMandatory2CapitalHexDigits(source + 25, &(agentData->value.edmGuid.GUID[10])) != 0)
+                    {
+                        result = AGENT_DATA_TYPES_INVALID_ARG;
+                    }
+                    else if (scanMandatory2CapitalHexDigits(source + 27, &(agentData->value.edmGuid.GUID[11])) != 0)
+                    {
+                        result = AGENT_DATA_TYPES_INVALID_ARG;
+                    }
+                    else if (scanMandatory2CapitalHexDigits(source + 29, &(agentData->value.edmGuid.GUID[12])) != 0)
+                    {
+                        result = AGENT_DATA_TYPES_INVALID_ARG;
+                    }
+                    else if (scanMandatory2CapitalHexDigits(source + 31, &(agentData->value.edmGuid.GUID[13])) != 0)
+                    {
+                        result = AGENT_DATA_TYPES_INVALID_ARG;
+                    }
+                    else if (scanMandatory2CapitalHexDigits(source + 33, &(agentData->value.edmGuid.GUID[14])) != 0)
+                    {
+                        result = AGENT_DATA_TYPES_INVALID_ARG;
+                    }
+                    else if (scanMandatory2CapitalHexDigits(source + 35, &(agentData->value.edmGuid.GUID[15])) != 0)
+                    {
+                        result = AGENT_DATA_TYPES_INVALID_ARG;
+                    }
+                    else if (source[37] != '"')
+                    {
+                        result = AGENT_DATA_TYPES_INVALID_ARG;
+                    }
+                    else
+                    {
+                        agentData->type = EDM_GUID_TYPE;
+                        result = AGENT_DATA_TYPES_OK;
+                    }
+                }
+                break;
+            }
+            case EDM_BINARY_TYPE:
+            {
+                size_t sourceLength = strlen(source);
+                if (sourceLength < 2)
+                {
+                    result = AGENT_DATA_TYPES_INVALID_ARG;
+                }
+                else if (sourceLength == 2)
+                {
+                    agentData->type = EDM_BINARY_TYPE;
+                    agentData->value.edmBinary.data = NULL;
+                    agentData->value.edmBinary.size = 0;
+                    result = AGENT_DATA_TYPES_OK;
+                }
+                else
+                {
+                    size_t sourcePosition = 0;
+                    if (source[sourcePosition++] != '"') /*if it doesn't start with a quote then... */
+                    {
+                        result = AGENT_DATA_TYPES_INVALID_ARG;
+                    }
+                    else
+                    {
+                        /*1. read groups of 4 base64 character and transfer those into groups of 3 "normal" characters.
+                        2. read the end of the string and produce from that the ending characters*/
+
+                        /*compute the amount of memory to allocate*/
+                        agentData->value.edmBinary.size = (((sourceLength - 2) + 4) / 4) * 3; /*this is overallocation, shall be trimmed later*/
+                        agentData->value.edmBinary.data = (unsigned char*)malloc(agentData->value.edmBinary.size); /*this is overallocation, shall be trimmed later*/
+                        if (agentData->value.edmBinary.data == NULL)
+                        {
+                            result = AGENT_DATA_TYPES_ERROR;
+                        }
+                        else
+                        {
+
+                            size_t destinationPosition = 0;
+                            size_t consumed;
+                            /*read and store "solid" groups of 4 base64 chars*/
+                            while (scan4base64char(source + sourcePosition, sourceLength - sourcePosition, agentData->value.edmBinary.data + destinationPosition, agentData->value.edmBinary.data + destinationPosition + 1, agentData->value.edmBinary.data + destinationPosition + 2) == 0)
+                            {
+                                sourcePosition += 4;
+                                destinationPosition += 3;
+                            }
+
+                            if (scanbase64b16(source + sourcePosition, sourceLength - sourcePosition, &consumed, agentData->value.edmBinary.data + destinationPosition, agentData->value.edmBinary.data + destinationPosition + 1) == 0)
+                            {
+                                sourcePosition += consumed;
+                                destinationPosition += 2;
+
+                            }
+                            else if (scanbase64b8(source + sourcePosition, sourceLength - sourcePosition, &consumed, agentData->value.edmBinary.data + destinationPosition) == 0)
+                            {
+                                sourcePosition += consumed;
+                                destinationPosition += 1;
+                            }
+
+                            if (source[sourcePosition++] != '"') /*if it doesn't end with " then bail out*/
+                            {
+                                free(agentData->value.edmBinary.data);
+                                agentData->value.edmBinary.data = NULL;
+                                result = AGENT_DATA_TYPES_INVALID_ARG;
+                            }
+                            else if (sourcePosition != sourceLength)
+                            {
+                                free(agentData->value.edmBinary.data);
+                                agentData->value.edmBinary.data = NULL;
+                                result = AGENT_DATA_TYPES_INVALID_ARG;
+                            }
+                            else
+                            {
+                                /*trim the result*/
+                                void* temp = realloc(agentData->value.edmBinary.data, destinationPosition);
+                                if (temp == NULL) /*this is extremely unlikely to happen, but whatever*/
+                                {
+                                    free(agentData->value.edmBinary.data);
+                                    agentData->value.edmBinary.data = NULL;
+                                    result = AGENT_DATA_TYPES_ERROR;
+                                }
+                                else
+                                {
+                                    agentData->type = EDM_BINARY_TYPE;
+                                    agentData->value.edmBinary.data = (unsigned char*)temp;
+                                    agentData->value.edmBinary.size = destinationPosition;
+                                    result = AGENT_DATA_TYPES_OK;
+                                }
+                            }
+                        }
+                    }
+                }
+                break;
+            }
+        }
+    }
+
+    return result;
+}
+
+// extern AGENT_DATA_TYPES_RESULT AgentDataType_GetComplexTypeField(AGENT_DATA_TYPE* agentData, size_t index, COMPLEX_TYPE_FIELD_TYPE* complexField);
+COMPLEX_TYPE_FIELD_TYPE* AgentDataType_GetComplexTypeField(AGENT_DATA_TYPE* agentData, size_t index)
+{
+    COMPLEX_TYPE_FIELD_TYPE* complexField = NULL;
+    if (agentData == NULL)
+    {
+        LogError("(result = %s)", MU_ENUM_TO_STRING(AGENT_DATA_TYPES_RESULT, AGENT_DATA_TYPES_INVALID_ARG));
+    }
+    else
+    {
+        if (agentData->type != EDM_COMPLEX_TYPE_TYPE)
+        {
+            LogError("(result = %s)", MU_ENUM_TO_STRING(AGENT_DATA_TYPES_RESULT, AGENT_DATA_TYPES_INVALID_ARG));
+        }
+
+        else
+        {
+            if (index >= agentData->value.edmComplexType.nMembers)
+            {
+                LogError("(result = %s)", MU_ENUM_TO_STRING(AGENT_DATA_TYPES_RESULT, AGENT_DATA_TYPES_INVALID_ARG));
+            }
+            else
+            {
+                complexField = (COMPLEX_TYPE_FIELD_TYPE*)malloc(sizeof(COMPLEX_TYPE_FIELD_TYPE));
+                if (complexField == NULL)
+                {
+                    LogError("(result = %s)", MU_ENUM_TO_STRING(AGENT_DATA_TYPES_RESULT, AGENT_DATA_TYPES_ERROR));
+                }
+                else
+                {
+                    *complexField = agentData->value.edmComplexType.fields[index];
+                }
+            }
+        }
+    }
+    return complexField;
+}
+
Index: azure_iot_hub_f767zi/trunk/azure_iot_sdk/serializer/src/codefirst.c
===================================================================
--- azure_iot_hub_f767zi/trunk/azure_iot_sdk/serializer/src/codefirst.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/azure_iot_sdk/serializer/src/codefirst.c	(revision 457)
@@ -0,0 +1,1637 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+#include <stdlib.h>
+#include <stdarg.h>
+#include "azure_c_shared_utility/gballoc.h"
+
+#include "codefirst.h"
+#include "azure_macro_utils/macro_utils.h"
+#include "azure_c_shared_utility/crt_abstractions.h"
+#include "azure_c_shared_utility/xlogging.h"
+#include <stddef.h>
+#include "azure_c_shared_utility/crt_abstractions.h"
+#include "iotdevice.h"
+
+MU_DEFINE_ENUM_STRINGS_WITHOUT_INVALID(CODEFIRST_RESULT, CODEFIRST_RESULT_VALUES)
+MU_DEFINE_ENUM_STRINGS_WITHOUT_INVALID(EXECUTE_COMMAND_RESULT, EXECUTE_COMMAND_RESULT_VALUES)
+
+#define LOG_CODEFIRST_ERROR \
+    LogError("(result = %s)", MU_ENUM_TO_STRING(CODEFIRST_RESULT, result))
+
+typedef struct DEVICE_HEADER_DATA_TAG
+{
+    DEVICE_HANDLE DeviceHandle;
+    const REFLECTED_DATA_FROM_DATAPROVIDER* ReflectedData;
+    SCHEMA_MODEL_TYPE_HANDLE ModelHandle;
+    size_t DataSize;
+    unsigned char* data;
+} DEVICE_HEADER_DATA;
+
+#define COUNT_OF(A) (sizeof(A) / sizeof((A)[0]))
+
+/*design considerations for lazy init of CodeFirst:
+    There are 2 main states: either CodeFirst is in an initialized state, or it is not initialized.
+    The initialized state means there's a g_OverrideSchemaNamespace set (even when it is set to NULL).
+    The uninitialized state means g_OverrideSchemaNamespace is not set.
+
+    To switch to Init state, either call CodeFirst_Init (that sets g_OverrideSchemaNamespace to something)
+    or call directly an API (that will set automatically g_OverrideSchemaNamespace to NULL).
+
+    To switch to NOT INIT state, depending on the method used to initialize:
+        - if CodeFirst_Init was called, then only by a call to CodeFirst_Deinit the switch will take place
+            (note how in this case g_OverrideSchemaNamespace survives destruction of all devices).
+        - if the init has been done "lazily" by an API call then the module returns to uninitialized state
+            when the number of devices reaches zero.
+
+                              +-----------------------------+
+     Start  +---------------->|                             |
+                              |  NOT INIT                   |
+            +---------------->|                             |
+            |                 +------------+----------------+
+            |                              |
+            |                              |
+            |                              | _Init | APIs
+            |                              |
+            |                              v
+            |     +---------------------------------------------------+
+            |     | Init State                                        |
+            |     | +-----------------+       +-----------------+     |
+            |     | |                 |       |                 |     |
+            |     | |  init by _Init  |       |   init by API   |     |
+            |     | +------+----------+       +---------+-------+     |
+            |     |        |                            |             |
+            |     |        |_DeInit                     | nDevices==0 |
+            |     |        |                            |             |
+            |     +--------v----------------+-----------v-------------+
+            |                               |
+            +-------------------------------+
+
+*/
+
+
+#define CODEFIRST_STATE_VALUES \
+    CODEFIRST_STATE_NOT_INIT, \
+    CODEFIRST_STATE_INIT_BY_INIT, \
+    CODEFIRST_STATE_INIT_BY_API
+
+MU_DEFINE_ENUM(CODEFIRST_STATE, CODEFIRST_STATE_VALUES)
+
+static CODEFIRST_STATE g_state = CODEFIRST_STATE_NOT_INIT;
+static const char* g_OverrideSchemaNamespace;
+static size_t g_DeviceCount = 0;
+static DEVICE_HEADER_DATA** g_Devices = NULL;
+
+static void deinitializeDesiredProperties(SCHEMA_MODEL_TYPE_HANDLE model, void* destination)
+{
+    size_t nDesiredProperties;
+    if (Schema_GetModelDesiredPropertyCount(model, &nDesiredProperties) != SCHEMA_OK)
+    {
+        LogError("unexpected error in Schema_GetModelDesiredPropertyCount");
+    }
+    else
+    {
+        size_t nProcessedDesiredProperties = 0;
+        for (size_t i = 0;i < nDesiredProperties;i++)
+        {
+            SCHEMA_DESIRED_PROPERTY_HANDLE desiredPropertyHandle = Schema_GetModelDesiredPropertyByIndex(model, i);
+            if (desiredPropertyHandle == NULL)
+            {
+                LogError("unexpected error in Schema_GetModelDesiredPropertyByIndex");
+                i = nDesiredProperties;
+            }
+            else
+            {
+                pfDesiredPropertyDeinitialize desiredPropertyDeinitialize = Schema_GetModelDesiredProperty_pfDesiredPropertyDeinitialize(desiredPropertyHandle);
+                if (desiredPropertyDeinitialize == NULL)
+                {
+                    LogError("unexpected error in Schema_GetModelDesiredProperty_pfDesiredPropertyDeinitialize");
+                    i = nDesiredProperties;
+                }
+                else
+                {
+                    size_t offset = Schema_GetModelDesiredProperty_offset(desiredPropertyHandle);
+                    desiredPropertyDeinitialize((char*)destination + offset);
+                    nProcessedDesiredProperties++;
+                }
+            }
+        }
+
+        if (nDesiredProperties == nProcessedDesiredProperties)
+        {
+            /*recursively go in the model and initialize the other fields*/
+            size_t nModelInModel;
+            if (Schema_GetModelModelCount(model, &nModelInModel) != SCHEMA_OK)
+            {
+                LogError("unexpected error in Schema_GetModelModelCount");
+            }
+            else
+            {
+                size_t nProcessedModelInModel = 0;
+                for (size_t i = 0; i < nModelInModel;i++)
+                {
+                    SCHEMA_MODEL_TYPE_HANDLE modelInModel = Schema_GetModelModelyByIndex(model, i);
+                    if (modelInModel == NULL)
+                    {
+                        LogError("unexpected failure in Schema_GetModelModelyByIndex");
+                        i = nModelInModel;
+                    }
+                    else
+                    {
+                        size_t offset = Schema_GetModelModelByIndex_Offset(model, i);
+                        deinitializeDesiredProperties(modelInModel, (char*)destination + offset);
+                        nProcessedModelInModel++;
+                    }
+                }
+
+                if (nProcessedModelInModel == nModelInModel)
+                {
+                    /*all is fine... */
+                }
+            }
+        }
+    }
+}
+
+static void DestroyDevice(DEVICE_HEADER_DATA* deviceHeader)
+{
+    /* Codes_SRS_CODEFIRST_99_085:[CodeFirst_DestroyDevice shall free all resources associated with a device.] */
+    /* Codes_SRS_CODEFIRST_99_087:[In order to release the device handle, CodeFirst_DestroyDevice shall call Device_Destroy.] */
+
+    Device_Destroy(deviceHeader->DeviceHandle);
+    free(deviceHeader->data);
+    free(deviceHeader);
+}
+
+static CODEFIRST_RESULT buildStructTypes(SCHEMA_HANDLE schemaHandle, const REFLECTED_DATA_FROM_DATAPROVIDER* reflectedData)
+{
+    CODEFIRST_RESULT result = CODEFIRST_OK;
+
+    const REFLECTED_SOMETHING* something;
+    for (something = reflectedData->reflectedData; something != NULL; something = something->next)
+    {
+        if (something->type == REFLECTION_STRUCT_TYPE)
+        {
+            SCHEMA_STRUCT_TYPE_HANDLE structTypeHandle;
+            structTypeHandle = Schema_CreateStructType(schemaHandle, something->what.structure.name);
+
+            if (structTypeHandle == NULL)
+            {
+                /*Codes_SRS_CODEFIRST_99_076:[If any Schema APIs fail, CODEFIRST_SCHEMA_ERROR shall be returned.]*/
+                result = CODEFIRST_SCHEMA_ERROR;
+                LogError("create struct failed %s", MU_ENUM_TO_STRING(CODEFIRST_RESULT, result));
+                break;
+            }
+            else
+            {
+                const REFLECTED_SOMETHING* maybeField;
+                /*look for the field... */
+                for (maybeField = reflectedData->reflectedData; maybeField != NULL; maybeField = maybeField->next)
+                {
+                    if (maybeField->type == REFLECTION_FIELD_TYPE)
+                    {
+                        if (strcmp(maybeField->what.field.structName, something->what.structure.name) == 0)
+                        {
+                            if (Schema_AddStructTypeProperty(structTypeHandle, maybeField->what.field.fieldName, maybeField->what.field.fieldType) != SCHEMA_OK)
+                            {
+                                /*Codes_SRS_CODEFIRST_99_076:[If any Schema APIs fail, CODEFIRST_SCHEMA_ERROR shall be returned.]*/
+                                result = CODEFIRST_SCHEMA_ERROR;
+                                LogError("add struct property failed %s", MU_ENUM_TO_STRING(CODEFIRST_RESULT, result));
+                                break;
+                            }
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    return result;
+}
+
+static CODEFIRST_RESULT buildModel(SCHEMA_HANDLE schemaHandle, const REFLECTED_DATA_FROM_DATAPROVIDER* reflectedData, const REFLECTED_SOMETHING* modelReflectedData)
+{
+    CODEFIRST_RESULT result = CODEFIRST_OK;
+    const REFLECTED_SOMETHING* something;
+    SCHEMA_MODEL_TYPE_HANDLE modelTypeHandle;
+
+    modelTypeHandle = Schema_GetModelByName(schemaHandle, modelReflectedData->what.model.name);
+    if (modelTypeHandle == NULL)
+    {
+        /*Codes_SRS_CODEFIRST_99_076:[If any Schema APIs fail, CODEFIRST_SCHEMA_ERROR shall be returned.]*/
+        result = CODEFIRST_SCHEMA_ERROR;
+        LogError("cannot get model %s %s", modelReflectedData->what.model.name, MU_ENUM_TO_STRING(CODEFIRST_RESULT, result));
+        goto out;
+    }
+
+    for (something = reflectedData->reflectedData; something != NULL; something = something->next)
+    {
+        /* looking for all elements that belong to a model: properties and actions */
+        if ((something->type == REFLECTION_PROPERTY_TYPE) &&
+            (strcmp(something->what.property.modelName, modelReflectedData->what.model.name) == 0))
+        {
+            SCHEMA_MODEL_TYPE_HANDLE childModelHande = Schema_GetModelByName(schemaHandle, something->what.property.type);
+
+            /* if this is a model type use the appropriate APIs for it */
+            if (childModelHande != NULL)
+            {
+                if (Schema_AddModelModel(modelTypeHandle, something->what.property.name, childModelHande, something->what.property.offset, NULL) != SCHEMA_OK)
+                {
+                    /*Codes_SRS_CODEFIRST_99_076:[If any Schema APIs fail, CODEFIRST_SCHEMA_ERROR shall be returned.]*/
+                    result = CODEFIRST_SCHEMA_ERROR;
+                    LogError("add model failed %s", MU_ENUM_TO_STRING(CODEFIRST_RESULT, result));
+                    goto out;
+                }
+            }
+            else
+            {
+                if (Schema_AddModelProperty(modelTypeHandle, something->what.property.name, something->what.property.type) != SCHEMA_OK)
+                {
+                    /*Codes_SRS_CODEFIRST_99_076:[If any Schema APIs fail, CODEFIRST_SCHEMA_ERROR shall be returned.]*/
+                    result = CODEFIRST_SCHEMA_ERROR;
+                    LogError("add property failed %s", MU_ENUM_TO_STRING(CODEFIRST_RESULT, result));
+                    goto out;
+                }
+            }
+        }
+
+        if ((something->type == REFLECTION_REPORTED_PROPERTY_TYPE) &&
+            (strcmp(something->what.reportedProperty.modelName, modelReflectedData->what.model.name) == 0))
+        {
+            SCHEMA_MODEL_TYPE_HANDLE childModelHande = Schema_GetModelByName(schemaHandle, something->what.reportedProperty.type);
+
+            /* if this is a model type use the appropriate APIs for it */
+            if (childModelHande != NULL)
+            {
+                if (Schema_AddModelModel(modelTypeHandle, something->what.reportedProperty.name, childModelHande, something->what.reportedProperty.offset, NULL) != SCHEMA_OK)
+                {
+                    /*Codes_SRS_CODEFIRST_99_076:[If any Schema APIs fail, CODEFIRST_SCHEMA_ERROR shall be returned.]*/
+                    result = CODEFIRST_SCHEMA_ERROR;
+                    LogError("add model failed %s", MU_ENUM_TO_STRING(CODEFIRST_RESULT, result));
+                    goto out;
+                }
+            }
+            else
+            {
+                if (Schema_AddModelReportedProperty(modelTypeHandle, something->what.reportedProperty.name, something->what.reportedProperty.type) != SCHEMA_OK)
+                {
+                    /*Codes_SRS_CODEFIRST_99_076:[If any Schema APIs fail, CODEFIRST_SCHEMA_ERROR shall be returned.]*/
+                    result = CODEFIRST_SCHEMA_ERROR;
+                    LogError("add reported property failed %s", MU_ENUM_TO_STRING(CODEFIRST_RESULT, result));
+                    goto out;
+                }
+            }
+        }
+
+        if ((something->type == REFLECTION_DESIRED_PROPERTY_TYPE) &&
+            (strcmp(something->what.desiredProperty.modelName, modelReflectedData->what.model.name) == 0))
+        {
+            SCHEMA_MODEL_TYPE_HANDLE childModelHande = Schema_GetModelByName(schemaHandle, something->what.desiredProperty.type);
+
+            /* if this is a model type use the appropriate APIs for it */
+            if (childModelHande != NULL)
+            {
+                if (Schema_AddModelModel(modelTypeHandle, something->what.desiredProperty.name, childModelHande, something->what.desiredProperty.offset, something->what.desiredProperty.onDesiredProperty) != SCHEMA_OK)
+                {
+                    /*Codes_SRS_CODEFIRST_99_076:[If any Schema APIs fail, CODEFIRST_SCHEMA_ERROR shall be returned.]*/
+                    result = CODEFIRST_SCHEMA_ERROR;
+                    LogError("add model failed %s", MU_ENUM_TO_STRING(CODEFIRST_RESULT, result));
+                    goto out;
+                }
+            }
+            else
+            {
+                if (Schema_AddModelDesiredProperty(modelTypeHandle,
+                    something->what.desiredProperty.name,
+                    something->what.desiredProperty.type,
+                    something->what.desiredProperty.FromAGENT_DATA_TYPE,
+                    something->what.desiredProperty.desiredPropertInitialize,
+                    something->what.desiredProperty.desiredPropertDeinitialize,
+                    something->what.desiredProperty.offset,
+                    something->what.desiredProperty.onDesiredProperty) != SCHEMA_OK)
+                {
+                    /*Codes_SRS_CODEFIRST_99_076:[If any Schema APIs fail, CODEFIRST_SCHEMA_ERROR shall be returned.]*/
+                    result = CODEFIRST_SCHEMA_ERROR;
+                    LogError("add desired property failed %s", MU_ENUM_TO_STRING(CODEFIRST_RESULT, result));
+                    goto out;
+                }
+            }
+        }
+
+        if ((something->type == REFLECTION_ACTION_TYPE) &&
+            (strcmp(something->what.action.modelName, modelReflectedData->what.model.name) == 0))
+        {
+            SCHEMA_ACTION_HANDLE actionHandle;
+            size_t i;
+
+            if ((actionHandle = Schema_CreateModelAction(modelTypeHandle, something->what.action.name)) == NULL)
+            {
+                /*Codes_SRS_CODEFIRST_99_076:[If any Schema APIs fail, CODEFIRST_SCHEMA_ERROR shall be returned.]*/
+                result = CODEFIRST_SCHEMA_ERROR;
+                LogError("add model action failed %s", MU_ENUM_TO_STRING(CODEFIRST_RESULT, result));
+                goto out;
+            }
+
+            for (i = 0; i < something->what.action.nArguments; i++)
+            {
+                if (Schema_AddModelActionArgument(actionHandle, something->what.action.arguments[i].name, something->what.action.arguments[i].type) != SCHEMA_OK)
+                {
+                    /*Codes_SRS_CODEFIRST_99_076:[If any Schema APIs fail, CODEFIRST_SCHEMA_ERROR shall be returned.]*/
+                    result = CODEFIRST_SCHEMA_ERROR;
+                    LogError("add model action argument failed %s", MU_ENUM_TO_STRING(CODEFIRST_RESULT, result));
+                    goto out;
+                }
+            }
+        }
+
+        if ((something->type == REFLECTION_METHOD_TYPE) &&
+            (strcmp(something->what.method.modelName, modelReflectedData->what.model.name) == 0))
+        {
+            SCHEMA_METHOD_HANDLE methodHandle;
+            size_t i;
+
+            if ((methodHandle = Schema_CreateModelMethod(modelTypeHandle, something->what.method.name)) == NULL)
+            {
+                /*Codes_SRS_CODEFIRST_99_076: [ If any Schema APIs fail, CodeFirst_RegisterSchema shall return NULL. ]*/
+                result = CODEFIRST_SCHEMA_ERROR;
+                LogError("add model method failed %s", MU_ENUM_TO_STRING(CODEFIRST_RESULT, result));
+                goto out;
+            }
+
+            for (i = 0; i < something->what.method.nArguments; i++)
+            {
+                if (Schema_AddModelMethodArgument(methodHandle, something->what.method.arguments[i].name, something->what.method.arguments[i].type) != SCHEMA_OK)
+                {
+                    /*Codes_SRS_CODEFIRST_99_076: [ If any Schema APIs fail, CodeFirst_RegisterSchema shall return NULL. ]*/
+                    result = CODEFIRST_SCHEMA_ERROR;
+                    LogError("add model method argument failed %s", MU_ENUM_TO_STRING(CODEFIRST_RESULT, result));
+                    goto out;
+                }
+            }
+        }
+    }
+
+out:
+    return result;
+}
+
+static CODEFIRST_RESULT buildModelTypes(SCHEMA_HANDLE schemaHandle, const REFLECTED_DATA_FROM_DATAPROVIDER* reflectedData)
+{
+    CODEFIRST_RESULT result = CODEFIRST_OK;
+    const REFLECTED_SOMETHING* something;
+
+    /* first have a pass and add all the model types */
+    for (something = reflectedData->reflectedData; something != NULL; something = something->next)
+    {
+        if (something->type == REFLECTION_MODEL_TYPE)
+        {
+            if (Schema_CreateModelType(schemaHandle, something->what.model.name) == NULL)
+            {
+                /*Codes_SRS_CODEFIRST_99_076:[If any Schema APIs fail, CODEFIRST_SCHEMA_ERROR shall be returned.]*/
+                result = CODEFIRST_SCHEMA_ERROR;
+                LogError("create model failed %s", MU_ENUM_TO_STRING(CODEFIRST_RESULT, result));
+                goto out;
+            }
+        }
+    }
+
+    for (something = reflectedData->reflectedData; something != NULL; something = something->next)
+    {
+        if (something->type == REFLECTION_MODEL_TYPE)
+        {
+            result = buildModel(schemaHandle, reflectedData, something);
+            if (result != CODEFIRST_OK)
+            {
+                break;
+            }
+        }
+    }
+
+out:
+    return result;
+}
+
+static CODEFIRST_RESULT CodeFirst_Init_impl(const char* overrideSchemaNamespace, bool calledFromCodeFirst_Init)
+{
+    /*shall build the default EntityContainer*/
+    CODEFIRST_RESULT result;
+
+    if (g_state != CODEFIRST_STATE_NOT_INIT)
+    {
+        /*Codes_SRS_CODEFIRST_99_003:[ If the module is already initialized, the initialization shall fail and the return value shall be CODEFIRST_ALREADY_INIT.]*/
+        result = CODEFIRST_ALREADY_INIT;
+        if(calledFromCodeFirst_Init) /*do not log this error when APIs attempt lazy init*/
+        {
+             LogError("CodeFirst was already init %s", MU_ENUM_TO_STRING(CODEFIRST_RESULT, result));
+        }
+    }
+    else
+    {
+        g_DeviceCount = 0;
+        g_OverrideSchemaNamespace = overrideSchemaNamespace;
+        g_Devices = NULL;
+
+        /*Codes_SRS_CODEFIRST_99_002:[ CodeFirst_Init shall initialize the CodeFirst module. If initialization is successful, it shall return CODEFIRST_OK.]*/
+        g_state = calledFromCodeFirst_Init? CODEFIRST_STATE_INIT_BY_INIT: CODEFIRST_STATE_INIT_BY_API;
+        result = CODEFIRST_OK;
+    }
+    return result;
+}
+
+/*Codes_SRS_CODEFIRST_99_002:[ CodeFirst_Init shall initialize the CodeFirst module. If initialization is successful, it shall return CODEFIRST_OK.]*/
+CODEFIRST_RESULT CodeFirst_Init(const char* overrideSchemaNamespace)
+{
+    return CodeFirst_Init_impl(overrideSchemaNamespace, true);
+}
+
+void CodeFirst_Deinit(void)
+{
+    /*Codes_SRS_CODEFIRST_99_006:[If the module is not previously initialed, CodeFirst_Deinit shall do nothing.]*/
+    if (g_state != CODEFIRST_STATE_INIT_BY_INIT)
+    {
+        LogError("CodeFirst_Deinit called when CodeFirst was not initialized by CodeFirst_Init");
+    }
+    else
+    {
+        size_t i;
+
+        /*Codes_SRS_CODEFIRST_99_005:[ CodeFirst_Deinit shall deinitialize the module, freeing all the resources and placing the module in an uninitialized state.]*/
+        for (i = 0; i < g_DeviceCount; i++)
+        {
+            DestroyDevice(g_Devices[i]);
+        }
+
+        free(g_Devices);
+        g_Devices = NULL;
+        g_DeviceCount = 0;
+
+        g_state = CODEFIRST_STATE_NOT_INIT;
+    }
+}
+
+static const REFLECTED_SOMETHING* FindModelInCodeFirstMetadata(const REFLECTED_SOMETHING* reflectedData, const char* modelName)
+{
+    const REFLECTED_SOMETHING* result;
+
+    for (result = reflectedData; result != NULL; result = result->next)
+    {
+        if ((result->type == REFLECTION_MODEL_TYPE) &&
+            (strcmp(result->what.model.name, modelName) == 0))
+        {
+            /* found model type */
+            break;
+        }
+    }
+
+    return result;
+}
+
+static const REFLECTED_SOMETHING* FindChildModelInCodeFirstMetadata(const REFLECTED_SOMETHING* reflectedData, const REFLECTED_SOMETHING* startModel, const char* relativePath, size_t* offset)
+{
+    const REFLECTED_SOMETHING* result = startModel;
+    *offset = 0;
+
+    /* Codes_SRS_CODEFIRST_99_139:[If the relativeActionPath is empty then the action shall be looked up in the device model.] */
+    while ((*relativePath != 0) && (result != NULL))
+    {
+        /* Codes_SRS_CODEFIRST_99_142:[The relativeActionPath argument shall be in the format "childModel1/childModel2/.../childModelN".] */
+        const REFLECTED_SOMETHING* childModelProperty;
+        size_t propertyNameLength;
+        const char* slashPos = strchr(relativePath, '/');
+        if (slashPos == NULL)
+        {
+            slashPos = &relativePath[strlen(relativePath)];
+        }
+
+        propertyNameLength = slashPos - relativePath;
+
+        for (childModelProperty = reflectedData; childModelProperty != NULL; childModelProperty = childModelProperty->next)
+        {
+            if ((childModelProperty->type == REFLECTION_PROPERTY_TYPE) &&
+                (strcmp(childModelProperty->what.property.modelName, result->what.model.name) == 0) &&
+                (strncmp(childModelProperty->what.property.name, relativePath, propertyNameLength) == 0) &&
+                (strlen(childModelProperty->what.property.name) == propertyNameLength))
+            {
+                /* property found, now let's find the model */
+                /* Codes_SRS_CODEFIRST_99_140:[CodeFirst_InvokeAction shall pass to the action wrapper that it calls a pointer to the model where the action is defined.] */
+                *offset += childModelProperty->what.property.offset;
+                break;
+            }
+        }
+
+        if (childModelProperty == NULL)
+        {
+            /* not found */
+            result = NULL;
+        }
+        else
+        {
+            result = FindModelInCodeFirstMetadata(reflectedData, childModelProperty->what.property.type);
+        }
+
+        relativePath = slashPos;
+    }
+
+    return result;
+}
+
+EXECUTE_COMMAND_RESULT CodeFirst_InvokeAction(DEVICE_HANDLE deviceHandle, void* callbackUserContext, const char* relativeActionPath, const char* actionName, size_t parameterCount, const AGENT_DATA_TYPE* parameterValues)
+{
+    EXECUTE_COMMAND_RESULT result;
+    DEVICE_HEADER_DATA* deviceHeader = (DEVICE_HEADER_DATA*)callbackUserContext;
+
+    /*Codes_SRS_CODEFIRST_99_068:[ If the function is called before CodeFirst is initialized then EXECUTE_COMMAND_ERROR shall be returned.] */
+    if (g_state == CODEFIRST_STATE_NOT_INIT)
+    {
+        result = EXECUTE_COMMAND_ERROR;
+        LogError("CodeFirst_InvokeAction called before init has an error %s ", MU_ENUM_TO_STRING(EXECUTE_COMMAND_RESULT, result));
+    }
+    /*Codes_SRS_CODEFIRST_99_066:[ If actionName, relativeActionPath or deviceHandle is NULL then EXECUTE_COMMAND_ERROR shall be returned*/
+    else if ((actionName == NULL) ||
+        (deviceHandle == NULL) ||
+        (relativeActionPath == NULL))
+    {
+        result = EXECUTE_COMMAND_ERROR;
+        LogError("action Name is NULL %s ", MU_ENUM_TO_STRING(EXECUTE_COMMAND_RESULT, result));
+    }
+    /*Codes_SRS_CODEFIRST_99_067:[ If parameterCount is greater than zero and parameterValues is NULL then EXECUTE_COMMAND_ERROR shall be returned.]*/
+    else if ((parameterCount > 0) && (parameterValues == NULL))
+    {
+        result = EXECUTE_COMMAND_ERROR;
+        LogError("parameterValues error %s ", MU_ENUM_TO_STRING(EXECUTE_COMMAND_RESULT, result));
+    }
+    /*Codes_SRS_CODEFIRST_99_200:[ If deviceHeader (callbackUserContext) is NULL then EXECUTE_COMMAND_ERROR shall be returned.]*/
+    else if (deviceHeader == NULL)
+    {
+        result = EXECUTE_COMMAND_ERROR;
+        LogError("callback User Context error %s ", MU_ENUM_TO_STRING(EXECUTE_COMMAND_RESULT, result));
+    }
+    else
+    {
+        const REFLECTED_SOMETHING* something;
+        const REFLECTED_SOMETHING* childModel;
+        const char* modelName;
+        size_t offset;
+
+        modelName = Schema_GetModelName(deviceHeader->ModelHandle);
+
+        if (((childModel = FindModelInCodeFirstMetadata(deviceHeader->ReflectedData->reflectedData, modelName)) == NULL) ||
+            /* Codes_SRS_CODEFIRST_99_138:[The relativeActionPath argument shall be used by CodeFirst_InvokeAction to find the child model where the action is declared.] */
+            ((childModel = FindChildModelInCodeFirstMetadata(deviceHeader->ReflectedData->reflectedData, childModel, relativeActionPath, &offset)) == NULL))
+        {
+            /*Codes_SRS_CODEFIRST_99_141:[If a child model specified in the relativeActionPath argument cannot be found by CodeFirst_InvokeAction, it shall return EXECUTE_COMMAND_ERROR.] */
+            result = EXECUTE_COMMAND_ERROR;
+            LogError("action %s was not found %s ", actionName, MU_ENUM_TO_STRING(EXECUTE_COMMAND_RESULT, result));
+        }
+        else
+        {
+            /* Codes_SRS_CODEFIRST_99_062:[ When CodeFirst_InvokeAction is called it shall look through the codefirst metadata associated with a specific device for a previously declared action (function) named actionName.]*/
+            /* Codes_SRS_CODEFIRST_99_078:[If such a function is not found then the function shall return EXECUTE_COMMAND_ERROR.]*/
+            result = EXECUTE_COMMAND_ERROR;
+            for (something = deviceHeader->ReflectedData->reflectedData; something != NULL; something = something->next)
+            {
+                if ((something->type == REFLECTION_ACTION_TYPE) &&
+                    (strcmp(actionName, something->what.action.name) == 0) &&
+                    (strcmp(childModel->what.model.name, something->what.action.modelName) == 0))
+                {
+                    /*Codes_SRS_CODEFIRST_99_063:[ If the function is found, then CodeFirst shall call the wrapper of the found function inside the data provider. The wrapper is linked in the reflected data to the function name. The wrapper shall be called with the same arguments as CodeFirst_InvokeAction has been called.]*/
+                    /*Codes_SRS_CODEFIRST_99_064:[ If the wrapper call succeeds then CODEFIRST_OK shall be returned. ]*/
+                    /*Codes_SRS_CODEFIRST_99_065:[ For all the other return values CODEFIRST_ACTION_EXECUTION_ERROR shall be returned.]*/
+                    /* Codes_SRS_CODEFIRST_99_140:[CodeFirst_InvokeAction shall pass to the action wrapper that it calls a pointer to the model where the action is defined.] */
+                    /*Codes_SRS_CODEFIRST_02_013: [The wrapper's return value shall be returned.]*/
+                    result = something->what.action.wrapper(deviceHeader->data + offset, parameterCount, parameterValues);
+                    break;
+                }
+            }
+        }
+    }
+
+    if (result == EXECUTE_COMMAND_ERROR)
+    {
+        LogError(" %s ", MU_ENUM_TO_STRING(EXECUTE_COMMAND_RESULT, result));
+    }
+    return result;
+}
+
+METHODRETURN_HANDLE CodeFirst_InvokeMethod(DEVICE_HANDLE deviceHandle, void* callbackUserContext, const char* relativeMethodPath, const char* methodName, size_t parameterCount, const AGENT_DATA_TYPE* parameterValues)
+{
+    METHODRETURN_HANDLE result;
+    DEVICE_HEADER_DATA* deviceHeader = (DEVICE_HEADER_DATA*)callbackUserContext;
+
+    if (g_state == CODEFIRST_STATE_NOT_INIT)
+    {
+        result = NULL;
+        LogError("CodeFirst_InvokeMethod called before CodeFirst_Init");
+    }
+    else if ((methodName == NULL) ||
+        (deviceHandle == NULL) ||
+        (relativeMethodPath == NULL))
+    {
+        result = NULL;
+        LogError("invalid args: DEVICE_HANDLE deviceHandle=%p, void* callbackUserContext=%p, const char* relativeMethodPath=%p, const char* methodName=%p, size_t parameterCount=%lu, const AGENT_DATA_TYPE* parameterValues=%p",
+            deviceHandle, callbackUserContext, relativeMethodPath, methodName, (unsigned long)parameterCount, parameterValues);
+    }
+    else if ((parameterCount > 0) && (parameterValues == NULL))
+    {
+        result = NULL;
+        LogError("parameterValues error ");
+    }
+    else if (deviceHeader == NULL)
+    {
+        result = NULL;
+        LogError("callback User Context error ");
+    }
+    else
+    {
+        const REFLECTED_SOMETHING* something;
+        const REFLECTED_SOMETHING* childModel;
+        const char* modelName;
+        size_t offset;
+
+        modelName = Schema_GetModelName(deviceHeader->ModelHandle);
+
+        if (((childModel = FindModelInCodeFirstMetadata(deviceHeader->ReflectedData->reflectedData, modelName)) == NULL) ||
+            ((childModel = FindChildModelInCodeFirstMetadata(deviceHeader->ReflectedData->reflectedData, childModel, relativeMethodPath, &offset)) == NULL))
+        {
+            result = NULL;
+            LogError("method %s was not found", methodName);
+        }
+        else
+        {
+            result = NULL;
+            for (something = deviceHeader->ReflectedData->reflectedData; something != NULL; something = something->next)
+            {
+                if ((something->type == REFLECTION_METHOD_TYPE) &&
+                    (strcmp(methodName, something->what.method.name) == 0) &&
+                    (strcmp(childModel->what.model.name, something->what.method.modelName) == 0))
+                {
+                    break; /*found...*/
+                }
+            }
+
+            if (something == NULL)
+            {
+                LogError("method \"%s\" not found", methodName);
+                result = NULL;
+            }
+            else
+            {
+                result = something->what.method.wrapper(deviceHeader->data + offset, parameterCount, parameterValues);
+                if (result == NULL)
+                {
+                    LogError("method \"%s\" execution error (returned NULL)", methodName);
+                }
+            }
+        }
+    }
+    return result;
+}
+
+
+/* Codes_SRS_CODEFIRST_99_002:[ CodeFirst_RegisterSchema shall create the schema information and give it to the Schema module for one schema, identified by the metadata argument. On success, it shall return a handle to the schema.] */
+SCHEMA_HANDLE CodeFirst_RegisterSchema(const char* schemaNamespace, const REFLECTED_DATA_FROM_DATAPROVIDER* metadata)
+{
+    SCHEMA_HANDLE result;
+    /*Codes_SRS_CODEFIRST_02_048: [ If schemaNamespace is NULL then CodeFirst_RegisterSchema shall fail and return NULL. ]*/
+    /*Codes_SRS_CODEFIRST_02_049: [ If metadata is NULL then CodeFirst_RegisterSchema shall fail and return NULL. ]*/
+    if (
+        (schemaNamespace == NULL) ||
+        (metadata == NULL)
+        )
+    {
+        LogError("invalid arg const char* schemaNamespace=%p, const REFLECTED_DATA_FROM_DATAPROVIDER* metadata=%p", schemaNamespace, metadata);
+        result = NULL;
+    }
+    else
+    {
+        if (g_OverrideSchemaNamespace != NULL)
+        {
+            schemaNamespace = g_OverrideSchemaNamespace;
+        }
+
+        /* Codes_SRS_CODEFIRST_99_121:[If the schema has already been registered, CodeFirst_RegisterSchema shall return its handle.] */
+        result = Schema_GetSchemaByNamespace(schemaNamespace);
+        if (result == NULL)
+        {
+            if ((result = Schema_Create(schemaNamespace, (void*)metadata)) == NULL)
+            {
+                /* Codes_SRS_CODEFIRST_99_076:[If any Schema APIs fail, CodeFirst_RegisterSchema shall return NULL.] */
+                result = NULL;
+                LogError("schema init failed %s", MU_ENUM_TO_STRING(CODEFIRST_RESULT, CODEFIRST_SCHEMA_ERROR));
+            }
+            else
+            {
+                if ((buildStructTypes(result, metadata) != CODEFIRST_OK) ||
+                    (buildModelTypes(result, metadata) != CODEFIRST_OK))
+                {
+                    Schema_Destroy(result);
+                    result = NULL;
+                }
+                else
+                {
+                    /* do nothing, everything is OK */
+                }
+            }
+        }
+    }
+
+    return result;
+}
+
+AGENT_DATA_TYPE_TYPE CodeFirst_GetPrimitiveType(const char* typeName)
+{
+#ifndef NO_FLOATS
+    if (strcmp(typeName, "double") == 0)
+    {
+        return EDM_DOUBLE_TYPE;
+    }
+    else if (strcmp(typeName, "float") == 0)
+    {
+        return EDM_SINGLE_TYPE;
+    }
+    else
+#endif
+    if (strcmp(typeName, "int") == 0)
+    {
+        return EDM_INT32_TYPE;
+    }
+    else if (strcmp(typeName, "long") == 0)
+    {
+        return EDM_INT64_TYPE;
+    }
+    else if (strcmp(typeName, "int8_t") == 0)
+    {
+        return EDM_SBYTE_TYPE;
+    }
+    else if (strcmp(typeName, "uint8_t") == 0)
+    {
+        return EDM_BYTE_TYPE;
+    }
+    else if (strcmp(typeName, "int16_t") == 0)
+    {
+        return EDM_INT16_TYPE;
+    }
+    else if (strcmp(typeName, "int32_t") == 0)
+    {
+        return EDM_INT32_TYPE;
+    }
+    else if (strcmp(typeName, "int64_t") == 0)
+    {
+        return EDM_INT64_TYPE;
+    }
+    else if (
+        (strcmp(typeName, "_Bool") == 0) ||
+        (strcmp(typeName, "bool") == 0)
+        )
+    {
+        return EDM_BOOLEAN_TYPE;
+    }
+    else if (strcmp(typeName, "ascii_char_ptr") == 0)
+    {
+        return EDM_STRING_TYPE;
+    }
+    else if (strcmp(typeName, "ascii_char_ptr_no_quotes") == 0)
+    {
+        return EDM_STRING_NO_QUOTES_TYPE;
+    }
+    else if (strcmp(typeName, "EDM_DATE_TIME_OFFSET") == 0)
+    {
+        return EDM_DATE_TIME_OFFSET_TYPE;
+    }
+    else if (strcmp(typeName, "EDM_GUID") == 0)
+    {
+        return EDM_GUID_TYPE;
+    }
+    else if (strcmp(typeName, "EDM_BINARY") == 0)
+    {
+        return EDM_BINARY_TYPE;
+    }
+    else
+    {
+        return EDM_NO_TYPE;
+    }
+}
+
+static void initializeDesiredProperties(SCHEMA_MODEL_TYPE_HANDLE model, void* destination)
+{
+    /*this function assumes that at the address given by destination there is an instance of a model*/
+    /*some constituents of the model need to be initialized - ascii_char_ptr for example should be set to NULL*/
+
+    size_t nDesiredProperties;
+    if (Schema_GetModelDesiredPropertyCount(model, &nDesiredProperties) != SCHEMA_OK)
+    {
+        LogError("unexpected error in Schema_GetModelDesiredPropertyCount");
+    }
+    else
+    {
+        size_t nProcessedDesiredProperties = 0;
+        for (size_t i = 0;i < nDesiredProperties;i++)
+        {
+            SCHEMA_DESIRED_PROPERTY_HANDLE desiredPropertyHandle = Schema_GetModelDesiredPropertyByIndex(model, i);
+            if (desiredPropertyHandle == NULL)
+            {
+                LogError("unexpected error in Schema_GetModelDesiredPropertyByIndex");
+                i = nDesiredProperties;
+            }
+            else
+            {
+                pfDesiredPropertyInitialize desiredPropertyInitialize = Schema_GetModelDesiredProperty_pfDesiredPropertyInitialize(desiredPropertyHandle);
+                if (desiredPropertyInitialize == NULL)
+                {
+                    LogError("unexpected error in Schema_GetModelDesiredProperty_pfDesiredPropertyInitialize");
+                    i = nDesiredProperties;
+                }
+                else
+                {
+                    /*Codes_SRS_CODEFIRST_02_036: [ CodeFirst_CreateDevice shall initialize all the desired properties to their default values. ]*/
+                    size_t offset = Schema_GetModelDesiredProperty_offset(desiredPropertyHandle);
+                    desiredPropertyInitialize((char*)destination + offset);
+                    nProcessedDesiredProperties++;
+                }
+            }
+        }
+
+        if (nDesiredProperties == nProcessedDesiredProperties)
+        {
+            /*recursively go in the model and initialize the other fields*/
+            size_t nModelInModel;
+            if (Schema_GetModelModelCount(model, &nModelInModel) != SCHEMA_OK)
+            {
+                LogError("unexpected error in Schema_GetModelModelCount");
+            }
+            else
+            {
+                size_t nProcessedModelInModel = 0;
+                for (size_t i = 0; i < nModelInModel;i++)
+                {
+                    SCHEMA_MODEL_TYPE_HANDLE modelInModel = Schema_GetModelModelyByIndex(model, i);
+                    if (modelInModel == NULL)
+                    {
+                        LogError("unexpected failure in Schema_GetModelModelyByIndex");
+                        i = nModelInModel;
+                    }
+                    else
+                    {
+                        size_t offset = Schema_GetModelModelByIndex_Offset(model, i);
+                        initializeDesiredProperties(modelInModel, (char*)destination + offset);
+                        nProcessedModelInModel++;
+                    }
+                }
+
+                if (nProcessedModelInModel == nModelInModel)
+                {
+                    /*all is fine... */
+                }
+            }
+        }
+    }
+}
+
+/* Codes_SRS_CODEFIRST_99_079:[CodeFirst_CreateDevice shall create a device and allocate a memory block that should hold the device data.] */
+void* CodeFirst_CreateDevice(SCHEMA_MODEL_TYPE_HANDLE model, const REFLECTED_DATA_FROM_DATAPROVIDER* metadata, size_t dataSize, bool includePropertyPath)
+{
+    void* result;
+    DEVICE_HEADER_DATA* deviceHeader;
+
+    /* Codes_SRS_CODEFIRST_99_080:[If CodeFirst_CreateDevice is invoked with a NULL model, it shall return NULL.]*/
+    if (model == NULL)
+    {
+        result = NULL;
+        LogError(" %s ", MU_ENUM_TO_STRING(CODEFIRST_RESULT, CODEFIRST_INVALID_ARG));
+    }
+    else
+    {
+        /*Codes_SRS_CODEFIRST_02_037: [ CodeFirst_CreateDevice shall call CodeFirst_Init, passing NULL for overrideSchemaNamespace. ]*/
+        (void)CodeFirst_Init_impl(NULL, false); /*lazy init*/
+
+        if ((deviceHeader = (DEVICE_HEADER_DATA*)calloc(1, sizeof(DEVICE_HEADER_DATA))) == NULL)
+        {
+            /* Codes_SRS_CODEFIRST_99_102:[On any other errors, Device_Create shall return NULL.] */
+            result = NULL;
+            LogError(" %s ", MU_ENUM_TO_STRING(CODEFIRST_RESULT, CODEFIRST_ERROR));
+        }
+        /* Codes_SRS_CODEFIRST_99_081:[CodeFirst_CreateDevice shall use Device_Create to create a device handle.] */
+        /* Codes_SRS_CODEFIRST_99_082: [ CodeFirst_CreateDevice shall pass to Device_Create the function CodeFirst_InvokeAction, action callback argument and the CodeFirst_InvokeMethod ] */
+        else
+        {
+            if ((deviceHeader->data = malloc(dataSize)) == NULL)
+            {
+                free(deviceHeader);
+                deviceHeader = NULL;
+                result = NULL;
+                LogError(" %s ", MU_ENUM_TO_STRING(CODEFIRST_RESULT, CODEFIRST_ERROR));
+            }
+            else
+            {
+                DEVICE_HEADER_DATA** newDevices;
+
+                initializeDesiredProperties(model, deviceHeader->data);
+
+                if (Device_Create(model, CodeFirst_InvokeAction, deviceHeader, CodeFirst_InvokeMethod, deviceHeader,
+                    includePropertyPath, &deviceHeader->DeviceHandle) != DEVICE_OK)
+                {
+                    free(deviceHeader->data);
+                    free(deviceHeader);
+
+                    /* Codes_SRS_CODEFIRST_99_084:[If Device_Create fails, CodeFirst_CreateDevice shall return NULL.] */
+                    result = NULL;
+                    LogError(" %s ", MU_ENUM_TO_STRING(CODEFIRST_RESULT, CODEFIRST_DEVICE_FAILED));
+                }
+                else if ((newDevices = (DEVICE_HEADER_DATA**)realloc(g_Devices, sizeof(DEVICE_HEADER_DATA*) * (g_DeviceCount + 1))) == NULL)
+                {
+                    Device_Destroy(deviceHeader->DeviceHandle);
+                    free(deviceHeader->data);
+                    free(deviceHeader);
+
+                    /* Codes_SRS_CODEFIRST_99_102:[On any other errors, Device_Create shall return NULL.] */
+                    result = NULL;
+                    LogError(" %s ", MU_ENUM_TO_STRING(CODEFIRST_RESULT, CODEFIRST_ERROR));
+                }
+                else
+                {
+                    SCHEMA_RESULT schemaResult;
+                    deviceHeader->ReflectedData = metadata;
+                    deviceHeader->DataSize = dataSize;
+                    deviceHeader->ModelHandle = model;
+                    schemaResult = Schema_AddDeviceRef(model);
+                    if (schemaResult != SCHEMA_OK)
+                    {
+                        Device_Destroy(deviceHeader->DeviceHandle);
+                        free(newDevices);
+                        free(deviceHeader->data);
+                        free(deviceHeader);
+
+                        /* Codes_SRS_CODEFIRST_99_102:[On any other errors, Device_Create shall return NULL.] */
+                        result = NULL;
+                    }
+                    else
+                    {
+                        g_Devices = newDevices;
+                        g_Devices[g_DeviceCount] = deviceHeader;
+                        g_DeviceCount++;
+
+                        /* Codes_SRS_CODEFIRST_99_101:[On success, CodeFirst_CreateDevice shall return a non NULL pointer to the device data.] */
+                        result = deviceHeader->data;
+                    }
+                }
+            }
+        }
+
+    }
+
+    return result;
+}
+
+void CodeFirst_DestroyDevice(void* device)
+{
+    /* Codes_SRS_CODEFIRST_99_086:[If the argument is NULL, CodeFirst_DestroyDevice shall do nothing.] */
+    if (device != NULL)
+    {
+        size_t i;
+
+        for (i = 0; i < g_DeviceCount; i++)
+        {
+            if (g_Devices[i]->data == device)
+            {
+                deinitializeDesiredProperties(g_Devices[i]->ModelHandle, g_Devices[i]->data);
+                Schema_ReleaseDeviceRef(g_Devices[i]->ModelHandle);
+
+                // Delete the Created Schema if all the devices are unassociated
+                Schema_DestroyIfUnused(g_Devices[i]->ModelHandle);
+
+                DestroyDevice(g_Devices[i]);
+                (void)memcpy(&g_Devices[i], &g_Devices[i + 1], (g_DeviceCount - i - 1) * sizeof(DEVICE_HEADER_DATA*));
+                g_DeviceCount--;
+                break;
+            }
+        }
+
+        /*Codes_SRS_CODEFIRST_02_039: [ If the current device count is zero then CodeFirst_DestroyDevice shall deallocate all other used resources. ]*/
+        if ((g_state == CODEFIRST_STATE_INIT_BY_API) && (g_DeviceCount == 0))
+        {
+            free(g_Devices);
+            g_Devices = NULL;
+            g_state = CODEFIRST_STATE_NOT_INIT;
+        }
+    }
+}
+
+static DEVICE_HEADER_DATA* FindDevice(void* value)
+{
+    size_t i;
+    DEVICE_HEADER_DATA* result = NULL;
+
+    for (i = 0; i < g_DeviceCount; i++)
+    {
+        if ((g_Devices[i]->data <= (unsigned char*)value) &&
+            (g_Devices[i]->data + g_Devices[i]->DataSize > (unsigned char*)value))
+        {
+            result = g_Devices[i];
+            break;
+        }
+    }
+
+    return result;
+}
+
+static const REFLECTED_SOMETHING* FindValue(DEVICE_HEADER_DATA* deviceHeader, void* value, const char* modelName, size_t startOffset, STRING_HANDLE valuePath)
+{
+    const REFLECTED_SOMETHING* result;
+    size_t valueOffset = (size_t)((unsigned char*)value - (unsigned char*)deviceHeader->data) - startOffset;
+
+    for (result = deviceHeader->ReflectedData->reflectedData; result != NULL; result = result->next)
+    {
+        if (result->type == REFLECTION_PROPERTY_TYPE &&
+            (strcmp(result->what.property.modelName, modelName) == 0) &&
+            (result->what.property.offset <= valueOffset) &&
+            (result->what.property.offset + result->what.property.size > valueOffset))
+        {
+            if (startOffset != 0)
+            {
+                STRING_concat(valuePath, "/");
+            }
+
+            STRING_concat(valuePath, result->what.property.name);
+            break;
+        }
+    }
+
+    if (result != NULL)
+    {
+        /* Codes_SRS_CODEFIRST_99_133:[CodeFirst_SendAsync shall allow sending of properties that are part of a child model.] */
+        if (result->what.property.offset < valueOffset)
+        {
+            /* find recursively the property in the inner model, if there is one */
+            result = FindValue(deviceHeader, value, result->what.property.type, startOffset + result->what.property.offset, valuePath);
+        }
+    }
+
+    return result;
+}
+
+static const REFLECTED_SOMETHING* FindReportedProperty(DEVICE_HEADER_DATA* deviceHeader, void* value, const char* modelName, size_t startOffset, STRING_HANDLE valuePath)
+{
+    const REFLECTED_SOMETHING* result;
+    size_t valueOffset = (size_t)((unsigned char*)value - (unsigned char*)deviceHeader->data) - startOffset;
+
+    for (result = deviceHeader->ReflectedData->reflectedData; result != NULL; result = result->next)
+    {
+        if (result->type == REFLECTION_REPORTED_PROPERTY_TYPE &&
+            (strcmp(result->what.reportedProperty.modelName, modelName) == 0) &&
+            (result->what.reportedProperty.offset <= valueOffset) &&
+            (result->what.reportedProperty.offset + result->what.reportedProperty.size > valueOffset))
+        {
+            if (startOffset != 0)
+            {
+                if (STRING_concat(valuePath, "/") != 0)
+                {
+                    LogError("unable to STRING_concat");
+                    result = NULL;
+                    break;
+                }
+            }
+
+            if (STRING_concat(valuePath, result->what.reportedProperty.name) != 0)
+            {
+                LogError("unable to STRING_concat");
+                result = NULL;
+                break;
+            }
+            break;
+        }
+    }
+
+    if (result != NULL)
+    {
+        /* Codes_SRS_CODEFIRST_99_133:[CodeFirst_SendAsync shall allow sending of properties that are part of a child model.] */
+        if (result->what.reportedProperty.offset < valueOffset)
+        {
+            /* find recursively the property in the inner model, if there is one */
+            result = FindReportedProperty(deviceHeader, value, result->what.reportedProperty.type, startOffset + result->what.reportedProperty.offset, valuePath);
+        }
+    }
+
+    return result;
+}
+
+/* Codes_SRS_CODEFIRST_99_130:[If a pointer to the beginning of a device block is passed to CodeFirst_SendAsync instead of a pointer to a property, CodeFirst_SendAsync shall send all the properties that belong to that device.] */
+/* Codes_SRS_CODEFIRST_99_131:[The properties shall be given to Device as one transaction, as if they were all passed as individual arguments to Code_First.] */
+static CODEFIRST_RESULT SendAllDeviceProperties(DEVICE_HEADER_DATA* deviceHeader, TRANSACTION_HANDLE transaction)
+{
+    const char* modelName = Schema_GetModelName(deviceHeader->ModelHandle);
+    const REFLECTED_SOMETHING* something;
+    unsigned char* deviceAddress = (unsigned char*)deviceHeader->data;
+    CODEFIRST_RESULT result = CODEFIRST_OK;
+
+    for (something = deviceHeader->ReflectedData->reflectedData; something != NULL; something = something->next)
+    {
+        if ((something->type == REFLECTION_PROPERTY_TYPE) &&
+            (strcmp(something->what.property.modelName, modelName) == 0))
+        {
+            AGENT_DATA_TYPE agentDataType;
+
+            /* Codes_SRS_CODEFIRST_99_097:[For each value marshalling to AGENT_DATA_TYPE shall be performed.] */
+            /* Codes_SRS_CODEFIRST_99_098:[The marshalling shall be done by calling the Create_AGENT_DATA_TYPE_from_Ptr function associated with the property.] */
+            if (something->what.property.Create_AGENT_DATA_TYPE_from_Ptr(deviceAddress + something->what.property.offset, &agentDataType) != AGENT_DATA_TYPES_OK)
+            {
+                /* Codes_SRS_CODEFIRST_99_099:[If Create_AGENT_DATA_TYPE_from_Ptr fails, CodeFirst_SendAsync shall return CODEFIRST_AGENT_DATA_TYPE_ERROR.] */
+                result = CODEFIRST_AGENT_DATA_TYPE_ERROR;
+                LOG_CODEFIRST_ERROR;
+                break;
+            }
+            else
+            {
+                /* Codes_SRS_CODEFIRST_99_092:[CodeFirst shall publish each value by using Device_PublishTransacted.] */
+                if (Device_PublishTransacted(transaction, something->what.property.name, &agentDataType) != DEVICE_OK)
+                {
+                    Destroy_AGENT_DATA_TYPE(&agentDataType);
+
+                    /* Codes_SRS_CODEFIRST_99_094:[If any Device API fail, CodeFirst_SendAsync shall return CODEFIRST_DEVICE_PUBLISH_FAILED.] */
+                    result = CODEFIRST_DEVICE_PUBLISH_FAILED;
+                    LOG_CODEFIRST_ERROR;
+                    break;
+                }
+
+                Destroy_AGENT_DATA_TYPE(&agentDataType);
+            }
+        }
+    }
+
+    return result;
+}
+
+static CODEFIRST_RESULT SendAllDeviceReportedProperties(DEVICE_HEADER_DATA* deviceHeader, REPORTED_PROPERTIES_TRANSACTION_HANDLE transaction)
+{
+    const char* modelName = Schema_GetModelName(deviceHeader->ModelHandle);
+    const REFLECTED_SOMETHING* something;
+    unsigned char* deviceAddress = (unsigned char*)deviceHeader->data;
+    CODEFIRST_RESULT result = CODEFIRST_OK;
+
+    for (something = deviceHeader->ReflectedData->reflectedData; something != NULL; something = something->next)
+    {
+        if ((something->type == REFLECTION_REPORTED_PROPERTY_TYPE) &&
+            (strcmp(something->what.reportedProperty.modelName, modelName) == 0))
+        {
+            AGENT_DATA_TYPE agentDataType;
+
+            if (something->what.reportedProperty.Create_AGENT_DATA_TYPE_from_Ptr(deviceAddress + something->what.reportedProperty.offset, &agentDataType) != AGENT_DATA_TYPES_OK)
+            {
+                result = CODEFIRST_AGENT_DATA_TYPE_ERROR;
+                LOG_CODEFIRST_ERROR;
+                break;
+            }
+            else
+            {
+                if (Device_PublishTransacted_ReportedProperty(transaction, something->what.reportedProperty.name, &agentDataType) != DEVICE_OK)
+                {
+                    Destroy_AGENT_DATA_TYPE(&agentDataType);
+                    result = CODEFIRST_DEVICE_PUBLISH_FAILED;
+                    LOG_CODEFIRST_ERROR;
+                    break;
+                }
+
+                Destroy_AGENT_DATA_TYPE(&agentDataType);
+            }
+        }
+    }
+
+    return result;
+}
+
+
+/* Codes_SRS_CODEFIRST_99_088:[CodeFirst_SendAsync shall send to the Device module a set of properties, a destination and a destinationSize.]*/
+CODEFIRST_RESULT CodeFirst_SendAsync(unsigned char** destination, size_t* destinationSize, size_t numProperties, ...)
+{
+    CODEFIRST_RESULT result;
+    va_list ap;
+
+    if (
+        (numProperties == 0) ||
+        (destination == NULL) ||
+        (destinationSize == NULL)
+        )
+    {
+        /* Codes_SRS_CODEFIRST_04_002: [If CodeFirst_SendAsync receives destination or destinationSize NULL, CodeFirst_SendAsync shall return Invalid Argument.]*/
+        /* Codes_SRS_CODEFIRST_99_103:[If CodeFirst_SendAsync is called with numProperties being zero, CODEFIRST_INVALID_ARG shall be returned.] */
+        result = CODEFIRST_INVALID_ARG;
+        LOG_CODEFIRST_ERROR;
+    }
+    else
+    {
+        /*Codes_SRS_CODEFIRST_02_040: [ CodeFirst_SendAsync shall call CodeFirst_Init, passing NULL for overrideSchemaNamespace. ]*/
+        (void)CodeFirst_Init_impl(NULL, false); /*lazy init*/
+
+        DEVICE_HEADER_DATA* deviceHeader = NULL;
+        size_t i;
+        TRANSACTION_HANDLE transaction = NULL;
+        result = CODEFIRST_OK;
+
+        /* Codes_SRS_CODEFIRST_99_105:[The properties are passed as pointers to the memory locations where the data exists in the device block allocated by CodeFirst_CreateDevice.] */
+        va_start(ap, numProperties);
+
+        /* Codes_SRS_CODEFIRST_99_089:[The numProperties argument shall indicate how many properties are to be sent.] */
+        for (i = 0; i < numProperties; i++)
+        {
+            void* value = (void*)va_arg(ap, void*);
+
+            /* Codes_SRS_CODEFIRST_99_095:[For each value passed to it, CodeFirst_SendAsync shall look up to which device the value belongs.] */
+            DEVICE_HEADER_DATA* currentValueDeviceHeader = FindDevice(value);
+            if (currentValueDeviceHeader == NULL)
+            {
+                /* Codes_SRS_CODEFIRST_99_104:[If a property cannot be associated with a device, CodeFirst_SendAsync shall return CODEFIRST_INVALID_ARG.] */
+                result = CODEFIRST_INVALID_ARG;
+                LOG_CODEFIRST_ERROR;
+                break;
+            }
+            else if ((deviceHeader != NULL) &&
+                (currentValueDeviceHeader != deviceHeader))
+            {
+                /* Codes_SRS_CODEFIRST_99_096:[All values have to belong to the same device, otherwise CodeFirst_SendAsync shall return CODEFIRST_VALUES_FROM_DIFFERENT_DEVICES_ERROR.] */
+                result = CODEFIRST_VALUES_FROM_DIFFERENT_DEVICES_ERROR;
+                LOG_CODEFIRST_ERROR;
+                break;
+            }
+            /* Codes_SRS_CODEFIRST_99_090:[All the properties shall be sent together by using the transacted APIs of the device.] */
+            /* Codes_SRS_CODEFIRST_99_091:[CodeFirst_SendAsync shall start a transaction by calling Device_StartTransaction.] */
+            else if ((deviceHeader == NULL) &&
+                ((transaction = Device_StartTransaction(currentValueDeviceHeader->DeviceHandle)) == NULL))
+            {
+                /* Codes_SRS_CODEFIRST_99_094:[If any Device API fail, CodeFirst_SendAsync shall return CODEFIRST_DEVICE_PUBLISH_FAILED.] */
+                result = CODEFIRST_DEVICE_PUBLISH_FAILED;
+                LOG_CODEFIRST_ERROR;
+                break;
+            }
+            else
+            {
+                deviceHeader = currentValueDeviceHeader;
+
+                if (value == ((unsigned char*)deviceHeader->data))
+                {
+                    /* we got a full device, send all its state data */
+                    result = SendAllDeviceProperties(deviceHeader, transaction);
+                    if (result != CODEFIRST_OK)
+                    {
+                        LOG_CODEFIRST_ERROR;
+                        break;
+                    }
+                }
+                else
+                {
+                    const REFLECTED_SOMETHING* propertyReflectedData;
+                    const char* modelName;
+                    STRING_HANDLE valuePath;
+
+                    if ((valuePath = STRING_new()) == NULL)
+                    {
+                        /* Codes_SRS_CODEFIRST_99_134:[If CodeFirst_Notify fails for any other reason it shall return CODEFIRST_ERROR.] */
+                        result = CODEFIRST_ERROR;
+                        LOG_CODEFIRST_ERROR;
+                        break;
+                    }
+                    else
+                    {
+                        if ((modelName = Schema_GetModelName(deviceHeader->ModelHandle)) == NULL)
+                        {
+                            /* Codes_SRS_CODEFIRST_99_134:[If CodeFirst_Notify fails for any other reason it shall return CODEFIRST_ERROR.] */
+                            result = CODEFIRST_ERROR;
+                            LOG_CODEFIRST_ERROR;
+                            STRING_delete(valuePath);
+                            break;
+                        }
+                        else if ((propertyReflectedData = FindValue(deviceHeader, value, modelName, 0, valuePath)) == NULL)
+                        {
+                            /* Codes_SRS_CODEFIRST_99_104:[If a property cannot be associated with a device, CodeFirst_SendAsync shall return CODEFIRST_INVALID_ARG.] */
+                            result = CODEFIRST_INVALID_ARG;
+                            LOG_CODEFIRST_ERROR;
+                            STRING_delete(valuePath);
+                            break;
+                        }
+                        else
+                        {
+                            AGENT_DATA_TYPE agentDataType;
+
+                            /* Codes_SRS_CODEFIRST_99_097:[For each value marshalling to AGENT_DATA_TYPE shall be performed.] */
+                            /* Codes_SRS_CODEFIRST_99_098:[The marshalling shall be done by calling the Create_AGENT_DATA_TYPE_from_Ptr function associated with the property.] */
+                            if (propertyReflectedData->what.property.Create_AGENT_DATA_TYPE_from_Ptr(value, &agentDataType) != AGENT_DATA_TYPES_OK)
+                            {
+                                /* Codes_SRS_CODEFIRST_99_099:[If Create_AGENT_DATA_TYPE_from_Ptr fails, CodeFirst_SendAsync shall return CODEFIRST_AGENT_DATA_TYPE_ERROR.] */
+                                result = CODEFIRST_AGENT_DATA_TYPE_ERROR;
+                                LOG_CODEFIRST_ERROR;
+                                STRING_delete(valuePath);
+                                break;
+                            }
+                            else
+                            {
+                                /* Codes_SRS_CODEFIRST_99_092:[CodeFirst shall publish each value by using Device_PublishTransacted.] */
+                                /* Codes_SRS_CODEFIRST_99_136:[CodeFirst_SendAsync shall build the full path for each property and then pass it to Device_PublishTransacted.] */
+                                if (Device_PublishTransacted(transaction, STRING_c_str(valuePath), &agentDataType) != DEVICE_OK)
+                                {
+                                    Destroy_AGENT_DATA_TYPE(&agentDataType);
+
+                                    /* Codes_SRS_CODEFIRST_99_094:[If any Device API fail, CodeFirst_SendAsync shall return CODEFIRST_DEVICE_PUBLISH_FAILED.] */
+                                    result = CODEFIRST_DEVICE_PUBLISH_FAILED;
+                                    LOG_CODEFIRST_ERROR;
+                                    STRING_delete(valuePath);
+                                    break;
+                                }
+                                else
+                                {
+                                    STRING_delete(valuePath); /*anyway*/
+                                }
+
+                                Destroy_AGENT_DATA_TYPE(&agentDataType);
+                            }
+                        }
+                    }
+                }
+            }
+        }
+
+        if (i < numProperties)
+        {
+            if (transaction != NULL)
+            {
+                (void)Device_CancelTransaction(transaction);
+            }
+        }
+        /* Codes_SRS_CODEFIRST_99_093:[After all values have been published, Device_EndTransaction shall be called.] */
+        else if (Device_EndTransaction(transaction, destination, destinationSize) != DEVICE_OK)
+        {
+            /* Codes_SRS_CODEFIRST_99_094:[If any Device API fail, CodeFirst_SendAsync shall return CODEFIRST_DEVICE_PUBLISH_FAILED.] */
+            result = CODEFIRST_DEVICE_PUBLISH_FAILED;
+            LOG_CODEFIRST_ERROR;
+        }
+        else
+        {
+            /* Codes_SRS_CODEFIRST_99_117:[On success, CodeFirst_SendAsync shall return CODEFIRST_OK.] */
+            result = CODEFIRST_OK;
+        }
+
+        va_end(ap);
+
+    }
+
+    return result;
+}
+
+CODEFIRST_RESULT CodeFirst_SendAsyncReported(unsigned char** destination, size_t* destinationSize, size_t numReportedProperties, ...)
+{
+    CODEFIRST_RESULT result;
+    if ((destination == NULL) || (destinationSize == NULL) || numReportedProperties == 0)
+    {
+        /*Codes_SRS_CODEFIRST_02_018: [ If parameter destination, destinationSize or any of the values passed through va_args is NULL then CodeFirst_SendAsyncReported shall fail and return CODEFIRST_INVALID_ARG. ]*/
+        LogError("invalid argument unsigned char** destination=%p, size_t* destinationSize=%p, size_t numReportedProperties=%lu", destination, destinationSize, (unsigned long)numReportedProperties);
+        result = CODEFIRST_INVALID_ARG;
+    }
+    else
+    {
+        /*Codes_SRS_CODEFIRST_02_046: [ CodeFirst_SendAsyncReported shall call CodeFirst_Init, passing NULL for overrideSchemaNamespace. ]*/
+        (void)CodeFirst_Init_impl(NULL, false);/*lazy init*/
+
+        DEVICE_HEADER_DATA* deviceHeader = NULL;
+        size_t i;
+        REPORTED_PROPERTIES_TRANSACTION_HANDLE transaction = NULL;
+        va_list ap;
+        result = CODEFIRST_ACTION_EXECUTION_ERROR; /*this initialization squelches a false warning about result not being initialized*/
+
+        va_start(ap, numReportedProperties);
+
+        for (i = 0; i < numReportedProperties; i++)
+        {
+            void* value = (void*)va_arg(ap, void*);
+            /*Codes_SRS_CODEFIRST_02_018: [ If parameter destination, destinationSize or any of the values passed through va_args is NULL then CodeFirst_SendAsyncReported shall fail and return CODEFIRST_INVALID_ARG. ]*/
+            if (value == NULL)
+            {
+                LogError("argument number %lu passed through variable arguments is NULL", (unsigned long)i);
+                result = CODEFIRST_INVALID_ARG;
+                break;
+            }
+            else
+            {
+                DEVICE_HEADER_DATA* currentValueDeviceHeader = FindDevice(value);
+                if (currentValueDeviceHeader == NULL)
+                {
+                    result = CODEFIRST_INVALID_ARG;
+                    LOG_CODEFIRST_ERROR;
+                    break;
+                }
+                /*Codes_SRS_CODEFIRST_02_019: [ If values passed through va_args do not belong to the same device then CodeFirst_SendAsyncReported shall fail and return CODEFIRST_VALUES_FROM_DIFFERENT_DEVICES_ERROR. ]*/
+                else if ((deviceHeader != NULL) &&
+                    (currentValueDeviceHeader != deviceHeader))
+                {
+                    result = CODEFIRST_VALUES_FROM_DIFFERENT_DEVICES_ERROR;
+                    LOG_CODEFIRST_ERROR;
+                    break;
+                }
+                /*Codes_SRS_CODEFIRST_02_022: [ CodeFirst_SendAsyncReported shall start a transaction by calling Device_CreateTransaction_ReportedProperties. ]*/
+                else if ((deviceHeader == NULL) &&
+                    ((transaction = Device_CreateTransaction_ReportedProperties(currentValueDeviceHeader->DeviceHandle)) == NULL))
+                {
+                    result = CODEFIRST_DEVICE_PUBLISH_FAILED;
+                    LOG_CODEFIRST_ERROR;
+                    break;
+                }
+                else
+                {
+                    deviceHeader = currentValueDeviceHeader;
+                    if (value == ((unsigned char*)deviceHeader->data))
+                    {
+                        /*Codes_SRS_CODEFIRST_02_021: [ If the value passed through va_args is a complete model instance, then CodeFirst_SendAsyncReported shall send all the reported properties of that device. ]*/
+                        result = SendAllDeviceReportedProperties(deviceHeader, transaction);
+                        if (result != CODEFIRST_OK)
+                        {
+                            LOG_CODEFIRST_ERROR;
+                            break;
+                        }
+                    }
+                    else
+                    {
+                        /*Codes_SRS_CODEFIRST_02_020: [ If values passed through va_args are not all of type REFLECTED_REPORTED_PROPERTY then CodeFirst_SendAsyncReported shall fail and return CODEFIRST_INVALID_ARG. ]*/
+                        const REFLECTED_SOMETHING* propertyReflectedData;
+                        const char* modelName;
+
+                        STRING_HANDLE valuePath;
+                        if ((valuePath = STRING_new()) == NULL)
+                        {
+                            result = CODEFIRST_ERROR;
+                            LOG_CODEFIRST_ERROR;
+                            break;
+                        }
+                        else
+                        {
+                            modelName = Schema_GetModelName(deviceHeader->ModelHandle);
+
+                            /*Codes_SRS_CODEFIRST_02_025: [ CodeFirst_SendAsyncReported shall compute for every AGENT_DATA_TYPE the valuePath. ]*/
+                            if ((propertyReflectedData = FindReportedProperty(deviceHeader, value, modelName, 0, valuePath)) == NULL)
+                            {
+                                result = CODEFIRST_INVALID_ARG;
+                                LOG_CODEFIRST_ERROR;
+                                STRING_delete(valuePath);
+                                break;
+                            }
+                            else
+                            {
+                                AGENT_DATA_TYPE agentDataType;
+                                /*Codes_SRS_CODEFIRST_02_023: [ CodeFirst_SendAsyncReported shall convert all REPORTED_PROPERTY model components to AGENT_DATA_TYPE. ]*/
+                                if (propertyReflectedData->what.reportedProperty.Create_AGENT_DATA_TYPE_from_Ptr(value, &agentDataType) != AGENT_DATA_TYPES_OK)
+                                {
+                                    result = CODEFIRST_AGENT_DATA_TYPE_ERROR;
+                                    LOG_CODEFIRST_ERROR;
+                                    STRING_delete(valuePath);
+                                    break;
+                                }
+                                else
+                                {
+                                    /*Codes_SRS_CODEFIRST_02_024: [ CodeFirst_SendAsyncReported shall call Device_PublishTransacted_ReportedProperty for every AGENT_DATA_TYPE converted from REPORTED_PROPERTY. ]*/
+                                    if (Device_PublishTransacted_ReportedProperty(transaction, STRING_c_str(valuePath), &agentDataType) != DEVICE_OK)
+                                    {
+                                        Destroy_AGENT_DATA_TYPE(&agentDataType);
+                                        result = CODEFIRST_DEVICE_PUBLISH_FAILED;
+                                        LOG_CODEFIRST_ERROR;
+                                        STRING_delete(valuePath);
+                                        break;
+                                    }
+                                    else
+                                    {
+                                        STRING_delete(valuePath);
+                                    }
+                                    Destroy_AGENT_DATA_TYPE(&agentDataType);
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+        }
+
+        /*Codes_SRS_CODEFIRST_02_027: [ If any error occurs, CodeFirst_SendAsyncReported shall fail and return CODEFIRST_ERROR. ]*/
+        if (i < numReportedProperties)
+        {
+            if (transaction != NULL)
+            {
+                Device_DestroyTransaction_ReportedProperties(transaction);
+            }
+        }
+        /*Codes_SRS_CODEFIRST_02_026: [ CodeFirst_SendAsyncReported shall call Device_CommitTransaction_ReportedProperties to commit the transaction. ]*/
+        else
+        {
+            if (Device_CommitTransaction_ReportedProperties(transaction, destination, destinationSize) != DEVICE_OK)
+            {
+                result = CODEFIRST_DEVICE_PUBLISH_FAILED;
+                LOG_CODEFIRST_ERROR;
+            }
+            else
+            {
+                /*Codes_SRS_CODEFIRST_02_028: [ CodeFirst_SendAsyncReported shall return CODEFIRST_OK when it succeeds. ]*/
+                result = CODEFIRST_OK;
+            }
+
+            /*Codes_SRS_CODEFIRST_02_029: [ CodeFirst_SendAsyncReported shall call Device_DestroyTransaction_ReportedProperties to destroy the transaction. ]*/
+            Device_DestroyTransaction_ReportedProperties(transaction);
+        }
+
+        va_end(ap);
+    }
+    return result;
+}
+
+EXECUTE_COMMAND_RESULT CodeFirst_ExecuteCommand(void* device, const char* command)
+{
+    EXECUTE_COMMAND_RESULT result;
+    /*Codes_SRS_CODEFIRST_02_014: [If parameter device or command is NULL then CodeFirst_ExecuteCommand shall return EXECUTE_COMMAND_ERROR.] */
+    if (
+        (device == NULL) ||
+        (command == NULL)
+        )
+    {
+        result = EXECUTE_COMMAND_ERROR;
+        LogError("invalid argument (NULL) passed to CodeFirst_ExecuteCommand void* device = %p, const char* command = %p", device, command);
+    }
+    else
+    {
+        /*Codes_SRS_CODEFIRST_02_015: [CodeFirst_ExecuteCommand shall find the device.]*/
+        DEVICE_HEADER_DATA* deviceHeader = FindDevice(device);
+        if(deviceHeader == NULL)
+        {
+            /*Codes_SRS_CODEFIRST_02_016: [If finding the device fails, then CodeFirst_ExecuteCommand shall return EXECUTE_COMMAND_ERROR.]*/
+            result = EXECUTE_COMMAND_ERROR;
+            LogError("unable to find the device given by address %p", device);
+        }
+        else
+        {
+            /*Codes_SRS_CODEFIRST_02_017: [Otherwise CodeFirst_ExecuteCommand shall call Device_ExecuteCommand and return what Device_ExecuteCommand is returning.] */
+            result = Device_ExecuteCommand(deviceHeader->DeviceHandle, command);
+        }
+    }
+    return result;
+}
+
+METHODRETURN_HANDLE CodeFirst_ExecuteMethod(void* device, const char* methodName, const char* methodPayload)
+{
+    METHODRETURN_HANDLE result;
+    if (
+        (device == NULL) ||
+        (methodName== NULL) /*methodPayload can be NULL*/
+        )
+    {
+        result = NULL;
+        LogError("invalid argument (NULL) passed to CodeFirst_ExecuteMethod void* device = %p, const char* methodName = %p", device, methodName);
+    }
+    else
+    {
+        DEVICE_HEADER_DATA* deviceHeader = FindDevice(device);
+        if (deviceHeader == NULL)
+        {
+            result = NULL;
+            LogError("unable to find the device given by address %p", device);
+        }
+        else
+        {
+            result = Device_ExecuteMethod(deviceHeader->DeviceHandle, methodName, methodPayload);
+        }
+    }
+    return result;
+}
+
+CODEFIRST_RESULT CodeFirst_IngestDesiredProperties(void* device, const char* jsonPayload, bool parseDesiredNode)
+{
+    CODEFIRST_RESULT result;
+    /*Codes_SRS_CODEFIRST_02_030: [ If argument device is NULL then CodeFirst_IngestDesiredProperties shall fail and return CODEFIRST_INVALID_ARG. ]*/
+    /*Codes_SRS_CODEFIRST_02_031: [ If argument jsonPayload is NULL then CodeFirst_IngestDesiredProperties shall fail and return CODEFIRST_INVALID_ARG. ]*/
+    if (
+        (device == NULL) ||
+        (jsonPayload == NULL)
+        )
+    {
+        LogError("invalid argument void* device=%p, const char* jsonPayload=%p", device, jsonPayload);
+        result = CODEFIRST_INVALID_ARG;
+    }
+    else
+    {
+        /*Codes_SRS_CODEFIRST_02_032: [ CodeFirst_IngestDesiredProperties shall locate the device associated with device. ]*/
+        DEVICE_HEADER_DATA* deviceHeader = FindDevice(device);
+        if (deviceHeader == NULL)
+        {
+            /*Codes_SRS_CODEFIRST_02_034: [ If there is any failure, then CodeFirst_IngestDesiredProperties shall fail and return CODEFIRST_ERROR. ]*/
+            LogError("unable to find a device having this memory address %p", device);
+            result = CODEFIRST_ERROR;
+        }
+        else
+        {
+            /*Codes_SRS_CODEFIRST_02_033: [ CodeFirst_IngestDesiredProperties shall call Device_IngestDesiredProperties. ]*/
+            if (Device_IngestDesiredProperties(device, deviceHeader->DeviceHandle, jsonPayload, parseDesiredNode) != DEVICE_OK)
+            {
+                LogError("failure in Device_IngestDesiredProperties");
+                result = CODEFIRST_ERROR;
+            }
+            else
+            {
+                /*Codes_SRS_CODEFIRST_02_035: [ Otherwise, CodeFirst_IngestDesiredProperties shall return CODEFIRST_OK. ]*/
+                result = CODEFIRST_OK;
+            }
+        }
+    }
+    return result;
+}
+
+
Index: azure_iot_hub_f767zi/trunk/azure_iot_sdk/serializer/src/commanddecoder.c
===================================================================
--- azure_iot_hub_f767zi/trunk/azure_iot_sdk/serializer/src/commanddecoder.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/azure_iot_sdk/serializer/src/commanddecoder.c	(revision 457)
@@ -0,0 +1,1040 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+#include <stdlib.h>
+#include "azure_c_shared_utility/optimize_size.h"
+#include "azure_c_shared_utility/gballoc.h"
+
+#include <stddef.h>
+
+#include "commanddecoder.h"
+#include "multitree.h"
+#include "azure_c_shared_utility/crt_abstractions.h"
+#include "azure_c_shared_utility/xlogging.h"
+#include "schema.h"
+#include "codefirst.h"
+#include "jsondecoder.h"
+
+MU_DEFINE_ENUM_STRINGS_WITHOUT_INVALID(COMMANDDECODER_RESULT, COMMANDDECODER_RESULT_VALUES);
+
+typedef struct COMMAND_DECODER_HANDLE_DATA_TAG
+{
+    METHOD_CALLBACK_FUNC methodCallback;
+    void* methodCallbackContext;
+    SCHEMA_MODEL_TYPE_HANDLE ModelHandle;
+    ACTION_CALLBACK_FUNC ActionCallback;
+    void* ActionCallbackContext;
+} COMMAND_DECODER_HANDLE_DATA;
+
+static int DecodeValueFromNode(SCHEMA_HANDLE schemaHandle, AGENT_DATA_TYPE* agentDataType, MULTITREE_HANDLE node, const char* edmTypeName)
+{
+    /* because "pottentially uninitialized variable on MS compiler" */
+    int result = 0;
+    const char* argStringValue;
+    AGENT_DATA_TYPE_TYPE primitiveType;
+
+    /* Codes_SRS_COMMAND_DECODER_99_029:[ If the argument type is complex then a complex type value shall be built from the child nodes.] */
+    if ((primitiveType = CodeFirst_GetPrimitiveType(edmTypeName)) == EDM_NO_TYPE)
+    {
+        SCHEMA_STRUCT_TYPE_HANDLE structTypeHandle;
+        size_t propertyCount;
+
+        /* Codes_SRS_COMMAND_DECODER_99_033:[ In order to determine which are the members of a complex types, Schema APIs for structure types shall be used.] */
+        if (((structTypeHandle = Schema_GetStructTypeByName(schemaHandle, edmTypeName)) == NULL) ||
+            (Schema_GetStructTypePropertyCount(structTypeHandle, &propertyCount) != SCHEMA_OK))
+        {
+            /* Codes_SRS_COMMAND_DECODER_99_010:[ If any Schema API fails then the command shall not be dispatched and it shall return EXECUTE_COMMAND_ERROR.]*/
+            result = MU_FAILURE;
+            LogError("Getting Struct information failed.");
+        }
+        else
+        {
+            if (propertyCount == 0)
+            {
+                /* Codes_SRS_COMMAND_DECODER_99_034:[ If Schema APIs indicate that a complex type has 0 members then the command shall not be dispatched and it shall return EXECUTE_COMMAND_ERROR.] */
+                result = MU_FAILURE;
+                LogError("Struct type with 0 members is not allowed");
+            }
+            else
+            {
+                AGENT_DATA_TYPE* memberValues = (AGENT_DATA_TYPE*)calloc(1, (sizeof(AGENT_DATA_TYPE)* propertyCount));
+                if (memberValues == NULL)
+                {
+                    /* Codes_SRS_COMMAND_DECODER_99_021:[ If the parsing of the command fails for any other reason the command shall not be dispatched.] */
+                    result = MU_FAILURE;
+                    LogError("Failed allocating member values for command argument");
+                }
+                else
+                {
+                    const char** memberNames = (const char**)malloc(sizeof(const char*)* propertyCount);
+                    if (memberNames == NULL)
+                    {
+                        /* Codes_SRS_COMMAND_DECODER_99_021:[ If the parsing of the command fails for any other reason the command shall not be dispatched.] */
+                        result = MU_FAILURE;
+                        LogError("Failed allocating member names for command argument.");
+                    }
+                    else
+                    {
+                        size_t j;
+                        size_t k;
+
+                        for (j = 0; j < propertyCount; j++)
+                        {
+                            SCHEMA_PROPERTY_HANDLE propertyHandle;
+                            MULTITREE_HANDLE memberNode;
+                            const char* propertyName;
+                            const char* propertyType;
+
+                            if ((propertyHandle = Schema_GetStructTypePropertyByIndex(structTypeHandle, j)) == NULL)
+                            {
+                                /* Codes_SRS_COMMAND_DECODER_99_010:[ If any Schema API fails then the command shall not be dispatched and it shall return EXECUTE_COMMAND_ERROR.]*/
+                                result = MU_FAILURE;
+                                LogError("Getting struct member failed.");
+                                break;
+                            }
+                            else if (((propertyName = Schema_GetPropertyName(propertyHandle)) == NULL) ||
+                                     ((propertyType = Schema_GetPropertyType(propertyHandle)) == NULL))
+                            {
+                                /* Codes_SRS_COMMAND_DECODER_99_010:[ If any Schema API fails then the command shall not be dispatched and it shall return EXECUTE_COMMAND_ERROR.]*/
+                                result = MU_FAILURE;
+                                LogError("Getting the struct member information failed.");
+                                break;
+                            }
+                            else
+                            {
+                                memberNames[j] = propertyName;
+
+                                /* Codes_SRS_COMMAND_DECODER_01_014: [CommandDecoder shall use the MultiTree APIs to extract a specific element from the command JSON.] */
+                                if (MultiTree_GetChildByName(node, memberNames[j], &memberNode) != MULTITREE_OK)
+                                {
+                                    /* Codes_SRS_COMMAND_DECODER_99_028:[ If decoding the argument fails then the command shall not be dispatched and it shall return EXECUTE_COMMAND_ERROR.] */
+                                    result = MU_FAILURE;
+                                    LogError("Getting child %s failed", propertyName);
+                                    break;
+                                }
+                                /* Codes_SRS_COMMAND_DECODER_99_032:[ Nesting shall be supported for complex type.] */
+                                else if ((result = DecodeValueFromNode(schemaHandle, &memberValues[j], memberNode, propertyType)) != 0)
+                                {
+                                    break;
+                                }
+                            }
+                        }
+
+                        if (j == propertyCount)
+                        {
+                            /* Codes_SRS_COMMAND_DECODER_99_031:[ The complex type value that aggregates the children shall be built by using the Create_AGENT_DATA_TYPE_from_Members.] */
+                            if (Create_AGENT_DATA_TYPE_from_Members(agentDataType, edmTypeName, propertyCount, (const char* const*)memberNames, memberValues) != AGENT_DATA_TYPES_OK)
+                            {
+                                /* Codes_SRS_COMMAND_DECODER_99_028:[ If decoding the argument fails then the command shall not be dispatched and it shall return EXECUTE_COMMAND_ERROR.] */
+                                result = MU_FAILURE;
+                                LogError("Creating the agent data type from members failed.");
+                            }
+                            else
+                            {
+                                result = 0;
+                            }
+                        }
+
+                        for (k = 0; k < j; k++)
+                        {
+                            Destroy_AGENT_DATA_TYPE(&memberValues[k]);
+                        }
+
+                        free((void*)memberNames);
+                    }
+
+                    free(memberValues);
+                }
+            }
+        }
+    }
+    else
+    {
+        /* Codes_SRS_COMMAND_DECODER_01_014: [CommandDecoder shall use the MultiTree APIs to extract a specific element from the command JSON.] */
+        if (MultiTree_GetValue(node, (const void **)&argStringValue) != MULTITREE_OK)
+        {
+            /* Codes_SRS_COMMAND_DECODER_99_012:[ If any argument is missing in the command text then the command shall not be dispatched and it shall return EXECUTE_COMMAND_ERROR.] */
+            result = MU_FAILURE;
+            LogError("Getting the string from the multitree failed.");
+        }
+        /* Codes_SRS_COMMAND_DECODER_99_027:[ The value for an argument of primitive type shall be decoded by using the CreateAgentDataType_From_String API.] */
+        else if (CreateAgentDataType_From_String(argStringValue, primitiveType, agentDataType) != AGENT_DATA_TYPES_OK)
+        {
+            /* Codes_SRS_COMMAND_DECODER_99_028:[ If decoding the argument fails then the command shall not be dispatched and it shall return EXECUTE_COMMAND_ERROR.] */
+            result = MU_FAILURE;
+            LogError("Failed parsing node %s.", argStringValue);
+        }
+    }
+
+    return result;
+}
+
+static EXECUTE_COMMAND_RESULT DecodeAndExecuteModelAction(COMMAND_DECODER_HANDLE_DATA* commandDecoderInstance, SCHEMA_HANDLE schemaHandle, SCHEMA_MODEL_TYPE_HANDLE modelHandle, const char* relativeActionPath, const char* actionName, MULTITREE_HANDLE commandNode)
+{
+    EXECUTE_COMMAND_RESULT result;
+    char tempStr[128];
+    size_t strLength = strlen(actionName);
+
+    if (strLength <= 1)
+    {
+        /* Codes_SRS_COMMAND_DECODER_99_021:[ If the parsing of the command fails for any other reason the command shall not be dispatched.] */
+        LogError("Invalid action name");
+        result = EXECUTE_COMMAND_ERROR;
+    }
+    else if (strLength >= 128)
+    {
+        /* Codes_SRS_COMMAND_DECODER_99_021:[ If the parsing of the command fails for any other reason the command shall not be dispatched.] */
+        LogError("Invalid action name length");
+        result = EXECUTE_COMMAND_ERROR;
+    }
+    else
+    {
+        /* Codes_SRS_COMMAND_DECODER_99_006:[ The action name shall be decoded from the element "Name" of the command JSON.] */
+        SCHEMA_ACTION_HANDLE modelActionHandle;
+        size_t argCount;
+        MULTITREE_HANDLE parametersTreeNode;
+
+        if (memcpy(tempStr, actionName, strLength-1) == NULL)
+        {
+            /* Codes_SRS_COMMAND_DECODER_99_021:[ If the parsing of the command fails for any other reason the command shall not be dispatched.] */
+            LogError("Invalid action name.");
+            result = EXECUTE_COMMAND_ERROR;
+        }
+        /* Codes_SRS_COMMAND_DECODER_01_014: [CommandDecoder shall use the MultiTree APIs to extract a specific element from the command JSON.] */
+        else if (MultiTree_GetChildByName(commandNode, "Parameters", &parametersTreeNode) != MULTITREE_OK)
+        {
+            /* Codes_SRS_COMMAND_DECODER_01_015: [If any MultiTree API call fails then the processing shall stop and the command shall not be dispatched and it shall return EXECUTE_COMMAND_ERROR.] */
+            LogError("Error getting Parameters node.");
+            result = EXECUTE_COMMAND_ERROR;
+        }
+        else
+        {
+            tempStr[strLength-1] = 0;
+            /* Codes_SRS_COMMAND_DECODER_99_009:[ CommandDecoder shall call Schema_GetModelActionByName to obtain the information about a specific action.] */
+            if (((modelActionHandle = Schema_GetModelActionByName(modelHandle, tempStr)) == NULL) ||
+                (Schema_GetModelActionArgumentCount(modelActionHandle, &argCount) != SCHEMA_OK))
+            {
+                /* Codes_SRS_COMMAND_DECODER_99_010:[ If any Schema API fails then the command shall not be dispatched and it shall return EXECUTE_COMMAND_ERROR.]*/
+                LogError("Failed reading action %s from the schema", tempStr);
+                result = EXECUTE_COMMAND_ERROR;
+            }
+            else
+            {
+                AGENT_DATA_TYPE* arguments = NULL;
+
+                if (argCount > 0)
+                {
+                    arguments = (AGENT_DATA_TYPE*)calloc(1, (sizeof(AGENT_DATA_TYPE)* argCount));
+                }
+
+                if ((argCount > 0) &&
+                    (arguments == NULL))
+                {
+                    /* Codes_SRS_COMMAND_DECODER_99_021:[ If the parsing of the command fails for any other reason the command shall not be dispatched.] */
+                    LogError("Failed allocating arguments array");
+                    result = EXECUTE_COMMAND_ERROR;
+                }
+                else
+                {
+                    size_t i;
+                    size_t j;
+                    result = EXECUTE_COMMAND_ERROR;
+
+                    /* Codes_SRS_COMMAND_DECODER_99_011:[ CommandDecoder shall attempt to extract from the command text the value for each action argument.] */
+                    for (i = 0; i < argCount; i++)
+                    {
+                        SCHEMA_ACTION_ARGUMENT_HANDLE actionArgumentHandle;
+                        MULTITREE_HANDLE argumentNode;
+                        const char* argName;
+                        const char* argType;
+
+                        if (((actionArgumentHandle = Schema_GetModelActionArgumentByIndex(modelActionHandle, i)) == NULL) ||
+                            ((argName = Schema_GetActionArgumentName(actionArgumentHandle)) == NULL) ||
+                            ((argType = Schema_GetActionArgumentType(actionArgumentHandle)) == NULL))
+                        {
+                            LogError("Failed getting the argument information from the schema");
+                            result = EXECUTE_COMMAND_ERROR;
+                            break;
+                        }
+                        /* Codes_SRS_COMMAND_DECODER_01_014: [CommandDecoder shall use the MultiTree APIs to extract a specific element from the command JSON.] */
+                        /* Codes_SRS_COMMAND_DECODER_01_008: [Each argument shall be looked up as a field, member of the "Parameters" node.]  */
+                        else if (MultiTree_GetChildByName(parametersTreeNode, argName, &argumentNode) != MULTITREE_OK)
+                        {
+                            /* Codes_SRS_COMMAND_DECODER_99_012:[ If any argument is missing in the command text then the command shall not be dispatched and it shall return EXECUTE_COMMAND_ERROR.] */
+                            LogError("Missing argument %s", argName);
+                            result = EXECUTE_COMMAND_ERROR;
+                            break;
+                        }
+                        else if (DecodeValueFromNode(schemaHandle, &arguments[i], argumentNode, argType) != 0)
+                        {
+                            result = EXECUTE_COMMAND_ERROR;
+                            break;
+                        }
+                    }
+
+                    if (i == argCount)
+                    {
+                        /* Codes_SRS_COMMAND_DECODER_99_005:[ If an Invoke Action is decoded successfully then the callback actionCallback shall be called, passing to it the callback action context, decoded name and arguments.] */
+                        result = commandDecoderInstance->ActionCallback(commandDecoderInstance->ActionCallbackContext, relativeActionPath, tempStr, argCount, arguments);
+                    }
+
+                    for (j = 0; j < i; j++)
+                    {
+                        Destroy_AGENT_DATA_TYPE(&arguments[j]);
+                    }
+
+                    if (arguments != NULL)
+                    {
+                        free(arguments);
+                    }
+                }
+            }
+        }
+    }
+    return result;
+}
+
+static METHODRETURN_HANDLE DecodeAndExecuteModelMethod(COMMAND_DECODER_HANDLE_DATA* commandDecoderInstance, SCHEMA_HANDLE schemaHandle, SCHEMA_MODEL_TYPE_HANDLE modelHandle, const char* relativeMethodPath, const char* methodName, MULTITREE_HANDLE methodTree)
+{
+    METHODRETURN_HANDLE result;
+    size_t strLength = strlen(methodName);
+
+    if (strLength == 0)
+    {
+        /*Codes_SRS_COMMAND_DECODER_02_023: [ If any of the previous operations fail, then CommandDecoder_ExecuteMethod shall return NULL. ]*/
+        LogError("Invalid method name");
+        result = NULL;
+    }
+    else
+    {
+        SCHEMA_METHOD_HANDLE modelMethodHandle;
+        size_t argCount;
+
+#ifdef _MSC_VER
+#pragma warning(suppress: 6324) /* We intentionally use here strncpy */
+#endif
+
+        /*Codes_SRS_COMMAND_DECODER_02_020: [ CommandDecoder_ExecuteMethod shall verify that the model has a method called methodName. ]*/
+        if (((modelMethodHandle = Schema_GetModelMethodByName(modelHandle, methodName)) == NULL) ||
+            (Schema_GetModelMethodArgumentCount(modelMethodHandle, &argCount) != SCHEMA_OK))
+        {
+            /*Codes_SRS_COMMAND_DECODER_02_023: [ If any of the previous operations fail, then CommandDecoder_ExecuteMethod shall return NULL. ]*/
+            LogError("Failed reading method %s from the schema", methodName);
+            result = NULL;
+        }
+        else
+        {
+            /*Codes_SRS_COMMAND_DECODER_02_021: [ For every argument of methodName, CommandDecoder_ExecuteMethod shall build an AGENT_DATA_TYPE from the node with the same name from the MULTITREE_HANDLE. ]*/
+
+            if (argCount == 0)
+            {
+                /*no need for any parameters*/
+                result = commandDecoderInstance->methodCallback(commandDecoderInstance->methodCallbackContext, relativeMethodPath, methodName, 0, NULL);
+            }
+            else
+            {
+                AGENT_DATA_TYPE* arguments;
+                arguments = (AGENT_DATA_TYPE*)calloc(1, (sizeof(AGENT_DATA_TYPE)* argCount));
+                if (arguments == NULL)
+                {
+                    LogError("Failed allocating arguments array");
+                    result = NULL;
+                }
+                else
+                {
+                    size_t i;
+                    size_t j;
+                    result = NULL;
+
+                    for (i = 0; i < argCount; i++)
+                    {
+                        SCHEMA_METHOD_ARGUMENT_HANDLE methodArgumentHandle;
+                        MULTITREE_HANDLE argumentNode;
+                        const char* argName;
+                        const char* argType;
+
+                        if (((methodArgumentHandle = Schema_GetModelMethodArgumentByIndex(modelMethodHandle, i)) == NULL) ||
+                            ((argName = Schema_GetMethodArgumentName(methodArgumentHandle)) == NULL) ||
+                            ((argType = Schema_GetMethodArgumentType(methodArgumentHandle)) == NULL))
+                        {
+                            /*Codes_SRS_COMMAND_DECODER_02_023: [ If any of the previous operations fail, then CommandDecoder_ExecuteMethod shall return NULL. ]*/
+                            LogError("Failed getting the argument information from the schema");
+                            result = NULL;
+                            break;
+                        }
+                        else if (MultiTree_GetChildByName(methodTree, argName, &argumentNode) != MULTITREE_OK)
+                        {
+                            /*Codes_SRS_COMMAND_DECODER_02_023: [ If any of the previous operations fail, then CommandDecoder_ExecuteMethod shall return NULL. ]*/
+                            LogError("Missing argument %s", argName);
+                            result = NULL;
+                            break;
+                        }
+                        else if (DecodeValueFromNode(schemaHandle, &arguments[i], argumentNode, argType) != 0)
+                        {
+                            /*Codes_SRS_COMMAND_DECODER_02_023: [ If any of the previous operations fail, then CommandDecoder_ExecuteMethod shall return NULL. ]*/
+                            LogError("failure in DecodeValueFromNode");
+                            result = NULL;
+                            break;
+                        }
+                    }
+
+                    if (i == argCount)
+                    {
+                        /*Codes_SRS_COMMAND_DECODER_02_022: [ CommandDecoder_ExecuteMethod shall call methodCallback passing the context, the methodName, number of arguments and the AGENT_DATA_TYPE. ]*/
+                        /*Codes_SRS_COMMAND_DECODER_02_024: [ Otherwise, CommandDecoder_ExecuteMethod shall return what methodCallback returns. ]*/
+                        result = commandDecoderInstance->methodCallback(commandDecoderInstance->methodCallbackContext, relativeMethodPath, methodName, argCount, arguments);
+                    }
+
+                    for (j = 0; j < i; j++)
+                    {
+                        Destroy_AGENT_DATA_TYPE(&arguments[j]);
+                    }
+
+                    free(arguments);
+                }
+
+            }
+        }
+
+    }
+    return result;
+}
+
+
+static EXECUTE_COMMAND_RESULT ScanActionPathAndExecuteAction(COMMAND_DECODER_HANDLE_DATA* commandDecoderInstance, SCHEMA_HANDLE schemaHandle, const char* actionPath, MULTITREE_HANDLE commandNode)
+{
+    EXECUTE_COMMAND_RESULT result;
+    char* relativeActionPath;
+    const char* actionName = actionPath;
+    SCHEMA_MODEL_TYPE_HANDLE modelHandle = commandDecoderInstance->ModelHandle;
+
+    /* Codes_SRS_COMMAND_DECODER_99_035:[ CommandDecoder_ExecuteCommand shall support paths to actions that are in child models (i.e. ChildModel/SomeAction.] */
+    do
+    {
+        /* find the slash */
+        const char* slashPos = strchr(actionName, '/');
+        if (slashPos == NULL)
+        {
+            size_t relativeActionPathLength;
+
+            /* Codes_SRS_COMMAND_DECODER_99_037:[ The relative path passed to the actionCallback shall be in the format "childModel1/childModel2/.../childModelN".] */
+            if (actionName == actionPath)
+            {
+                relativeActionPathLength = 0;
+            }
+            else
+            {
+                relativeActionPathLength = actionName - actionPath - 1;
+            }
+
+            relativeActionPath = (char*)malloc(relativeActionPathLength + 1);
+            if (relativeActionPath == NULL)
+            {
+                /* Codes_SRS_COMMAND_DECODER_99_021:[ If the parsing of the command fails for any other reason the command shall not be dispatched.] */
+                LogError("Failed allocating relative action path");
+                result = EXECUTE_COMMAND_ERROR;
+            }
+            else
+            {
+                strncpy(relativeActionPath, actionPath, relativeActionPathLength);
+                relativeActionPath[relativeActionPathLength] = 0;
+
+                /* no slash found, this must be an action */
+                result = DecodeAndExecuteModelAction(commandDecoderInstance, schemaHandle, modelHandle, relativeActionPath, actionName, commandNode);
+
+                free(relativeActionPath);
+                actionName = NULL;
+            }
+            break;
+        }
+        else
+        {
+            /* found a slash, get the child model name */
+            size_t modelLength = slashPos - actionName;
+            char* childModelName = (char*)malloc(modelLength + 1);
+            if (childModelName == NULL)
+            {
+                /* Codes_SRS_COMMAND_DECODER_99_021:[ If the parsing of the command fails for any other reason the command shall not be dispatched.] */
+                LogError("Failed allocating child model name");
+                result = EXECUTE_COMMAND_ERROR;
+                break;
+            }
+            else
+            {
+                strncpy(childModelName, actionName, modelLength);
+                childModelName[modelLength] = 0;
+
+                /* find the model */
+                modelHandle = Schema_GetModelModelByName(modelHandle, childModelName);
+                if (modelHandle == NULL)
+                {
+                    /* Codes_SRS_COMMAND_DECODER_99_036:[ If a child model cannot be found by using Schema APIs then the command shall not be dispatched and it shall return EXECUTE_COMMAND_ERROR.] */
+                    LogError("Getting the model %s failed", childModelName);
+                    free(childModelName);
+                    result = EXECUTE_COMMAND_ERROR;
+                    break;
+                }
+                else
+                {
+                    free(childModelName);
+                    actionName = slashPos + 1;
+                    result = EXECUTE_COMMAND_ERROR; /*this only exists to quench a compiler warning about returning an uninitialized variable, which is not possible by design*/
+                }
+            }
+        }
+    } while (actionName != NULL);
+    return result;
+}
+
+static METHODRETURN_HANDLE ScanMethodPathAndExecuteMethod(COMMAND_DECODER_HANDLE_DATA* commandDecoderInstance, SCHEMA_HANDLE schemaHandle, const char* fullMethodName, MULTITREE_HANDLE methodTree)
+{
+    METHODRETURN_HANDLE result;
+    char* relativeMethodPath;
+    const char* methodName = fullMethodName;
+    SCHEMA_MODEL_TYPE_HANDLE modelHandle = commandDecoderInstance->ModelHandle;
+
+    /*Codes_SRS_COMMAND_DECODER_02_018: [ CommandDecoder_ExecuteMethod shall validate that consecutive segments of the fullMethodName exist in the model. ]*/
+    /*Codes_SRS_COMMAND_DECODER_02_019: [ CommandDecoder_ExecuteMethod shall locate the final model to which the methodName applies. ]*/
+    do
+    {
+        /* find the slash */
+        const char* slashPos = strchr(methodName, '/');
+        if (slashPos == NULL)
+        {
+            size_t relativeMethodPathLength;
+
+            if (methodName == fullMethodName)
+            {
+                relativeMethodPathLength = 0;
+            }
+            else
+            {
+                relativeMethodPathLength = methodName - fullMethodName - 1;
+            }
+
+            relativeMethodPath = (char*)malloc(relativeMethodPathLength + 1);
+            if (relativeMethodPath == NULL)
+            {
+                /*Codes_SRS_COMMAND_DECODER_02_023: [ If any of the previous operations fail, then CommandDecoder_ExecuteMethod shall return NULL. ]*/
+                LogError("Failed allocating relative method path");
+                result = NULL;
+            }
+            else
+            {
+                strncpy(relativeMethodPath, fullMethodName, relativeMethodPathLength);
+                relativeMethodPath[relativeMethodPathLength] = 0;
+
+                /* no slash found, this must be an method */
+                result = DecodeAndExecuteModelMethod(commandDecoderInstance, schemaHandle, modelHandle, relativeMethodPath, methodName, methodTree);
+
+                free(relativeMethodPath);
+                methodName = NULL;
+            }
+            break;
+        }
+        else
+        {
+            /* found a slash, get the child model name */
+            size_t modelLength = slashPos - methodName;
+            char* childModelName = (char*)malloc(modelLength + 1);
+            if (childModelName == NULL)
+            {
+                /*Codes_SRS_COMMAND_DECODER_02_023: [ If any of the previous operations fail, then CommandDecoder_ExecuteMethod shall return NULL. ]*/
+                LogError("Failed allocating child model name");
+                result = NULL;
+                break;
+            }
+            else
+            {
+                strncpy(childModelName, methodName, modelLength);
+                childModelName[modelLength] = 0;
+
+                /* find the model */
+                modelHandle = Schema_GetModelModelByName(modelHandle, childModelName);
+                if (modelHandle == NULL)
+                {
+                    /*Codes_SRS_COMMAND_DECODER_02_023: [ If any of the previous operations fail, then CommandDecoder_ExecuteMethod shall return NULL. ]*/
+                    LogError("Getting the model %s failed", childModelName);
+                    free(childModelName);
+                    result = NULL;
+                    break;
+                }
+                else
+                {
+                    free(childModelName);
+                    methodName = slashPos + 1;
+                    result = NULL; /*this only exists to quench a compiler warning about returning an uninitialized variable, which is not possible by design*/
+                }
+            }
+        }
+    } while (methodName != NULL);
+    return result;
+}
+
+static EXECUTE_COMMAND_RESULT DecodeCommand(COMMAND_DECODER_HANDLE_DATA* commandDecoderInstance, MULTITREE_HANDLE commandNode)
+{
+    EXECUTE_COMMAND_RESULT result;
+    SCHEMA_HANDLE schemaHandle;
+
+    /* Codes_SRS_COMMAND_DECODER_99_022:[ CommandDecoder shall use the Schema APIs to obtain the information about the entity set name and namespace] */
+    if ((schemaHandle = Schema_GetSchemaForModelType(commandDecoderInstance->ModelHandle)) == NULL)
+    {
+        /* Codes_SRS_COMMAND_DECODER_99_010:[ If any Schema API fails then the command shall not be dispatched and it shall return EXECUTE_COMMAND_ERROR.]*/
+        LogError("Getting schema information failed");
+        result = EXECUTE_COMMAND_ERROR;
+    }
+    else
+    {
+        const char* actionName;
+        MULTITREE_HANDLE nameTreeNode;
+
+        /* Codes_SRS_COMMAND_DECODER_01_014: [CommandDecoder shall use the MultiTree APIs to extract a specific element from the command JSON.] */
+        /* Codes_SRS_COMMAND_DECODER_99_006:[ The action name shall be decoded from the element "name" of the command JSON.] */
+        if ((MultiTree_GetChildByName(commandNode, "Name", &nameTreeNode) != MULTITREE_OK) ||
+            (MultiTree_GetValue(nameTreeNode, (const void **)&actionName) != MULTITREE_OK))
+        {
+            /* Codes_SRS_COMMAND_DECODER_01_015: [If any MultiTree API call fails then the processing shall stop and the command shall not be dispatched and it shall return EXECUTE_COMMAND_ERROR.] */
+            LogError("Getting action name failed.");
+            result = EXECUTE_COMMAND_ERROR;
+        }
+        else if (strlen(actionName) < 2)
+        {
+            /* Codes_SRS_COMMAND_DECODER_99_021:[ If the parsing of the command fails for any other reason the command shall not be dispatched.] */
+            LogError("Invalid action name.");
+            result = EXECUTE_COMMAND_ERROR;
+        }
+        else
+        {
+            actionName++;
+            result = ScanActionPathAndExecuteAction(commandDecoderInstance, schemaHandle, actionName, commandNode);
+        }
+    }
+    return result;
+}
+
+static METHODRETURN_HANDLE DecodeMethod(COMMAND_DECODER_HANDLE_DATA* commandDecoderInstance, const char* fullMethodName, MULTITREE_HANDLE methodTree)
+{
+    METHODRETURN_HANDLE result;
+    SCHEMA_HANDLE schemaHandle;
+
+    /*Codes_SRS_COMMAND_DECODER_02_017: [ CommandDecoder_ExecuteMethod shall get the SCHEMA_HANDLE associated with the modelHandle passed at CommandDecoder_Create. ]*/
+    if ((schemaHandle = Schema_GetSchemaForModelType(commandDecoderInstance->ModelHandle)) == NULL)
+    {
+        LogError("Getting schema information failed");
+        result = NULL;
+    }
+    else
+    {
+        result = ScanMethodPathAndExecuteMethod(commandDecoderInstance, schemaHandle, fullMethodName, methodTree);
+
+    }
+    return result;
+}
+
+/*Codes_SRS_COMMAND_DECODER_01_009: [Whenever CommandDecoder_ExecuteCommand is the command shall be decoded and further dispatched to the actionCallback passed in CommandDecoder_Create.]*/
+EXECUTE_COMMAND_RESULT CommandDecoder_ExecuteCommand(COMMAND_DECODER_HANDLE handle, const char* command)
+{
+    EXECUTE_COMMAND_RESULT result;
+    COMMAND_DECODER_HANDLE_DATA* commandDecoderInstance = (COMMAND_DECODER_HANDLE_DATA*)handle;
+    /*Codes_SRS_COMMAND_DECODER_01_010: [If either the buffer or the receiveCallbackContext argument is NULL, the processing shall stop and the command shall not be dispatched and it shall return EXECUTE_COMMAND_ERROR.]*/
+    if (
+        (command == NULL) ||
+        (commandDecoderInstance == NULL)
+    )
+    {
+        LogError("Invalid argument, COMMAND_DECODER_HANDLE handle=%p, const char* command=%p", handle, command);
+        result = EXECUTE_COMMAND_ERROR;
+    }
+    else
+    {
+        size_t size = strlen(command);
+        char* commandJSON;
+
+        /* Codes_SRS_COMMAND_DECODER_01_011: [If the size of the command is 0 then the processing shall stop and the command shall not be dispatched and it shall return EXECUTE_COMMAND_ERROR.]*/
+        if (size == 0)
+        {
+            LogError("Failed because command size is zero");
+            result = EXECUTE_COMMAND_ERROR;
+        }
+        /*Codes_SRS_COMMAND_DECODER_01_013: [If parsing the JSON to a multi tree fails, the processing shall stop and the command shall not be dispatched and it shall return EXECUTE_COMMAND_ERROR.]*/
+        else if ((commandJSON = (char*)malloc(size + 1)) == NULL)
+        {
+            LogError("Failed to allocate temporary storage for the commands JSON");
+            result = EXECUTE_COMMAND_ERROR;
+        }
+        else
+        {
+            MULTITREE_HANDLE commandsTree;
+
+            (void)memcpy(commandJSON, command, size);
+            commandJSON[size] = '\0';
+
+            /* Codes_SRS_COMMAND_DECODER_01_012: [CommandDecoder shall decode the command JSON contained in buffer to a multi-tree by using JSONDecoder_JSON_To_MultiTree.] */
+            if (JSONDecoder_JSON_To_MultiTree(commandJSON, &commandsTree) != JSON_DECODER_OK)
+            {
+                /* Codes_SRS_COMMAND_DECODER_01_013: [If parsing the JSON to a multi tree fails, the processing shall stop and the command shall not be dispatched and it shall return EXECUTE_COMMAND_ERROR.] */
+                LogError("Decoding JSON to a multi tree failed");
+                result = EXECUTE_COMMAND_ERROR;
+            }
+            else
+            {
+                result = DecodeCommand(commandDecoderInstance, commandsTree);
+
+                /* Codes_SRS_COMMAND_DECODER_01_016: [CommandDecoder shall ensure that the multi-tree resulting from JSONDecoder_JSON_To_MultiTree is freed after the commands are executed.] */
+                MultiTree_Destroy(commandsTree);
+            }
+
+            free(commandJSON);
+        }
+    }
+    return result;
+}
+
+METHODRETURN_HANDLE CommandDecoder_ExecuteMethod(COMMAND_DECODER_HANDLE handle, const char* fullMethodName, const char* methodPayload)
+{
+    METHODRETURN_HANDLE result;
+    /*Codes_SRS_COMMAND_DECODER_02_014: [ If handle is NULL then CommandDecoder_ExecuteMethod shall fail and return NULL. ]*/
+    /*Codes_SRS_COMMAND_DECODER_02_015: [ If fulMethodName is NULL then CommandDecoder_ExecuteMethod shall fail and return NULL. ]*/
+    if (
+        (handle == NULL) ||
+        (fullMethodName == NULL) /*methodPayload can be NULL*/
+        )
+    {
+        LogError("Invalid argument, COMMAND_DECODER_HANDLE handle=%p, const char* fullMethodName=%p", handle, fullMethodName);
+        result = NULL;
+    }
+    else
+    {
+        COMMAND_DECODER_HANDLE_DATA* commandDecoderInstance = (COMMAND_DECODER_HANDLE_DATA*)handle;
+        /*Codes_SRS_COMMAND_DECODER_02_025: [ If methodCallback is NULL then CommandDecoder_ExecuteMethod shall fail and return NULL. ]*/
+        if (commandDecoderInstance->methodCallback == NULL)
+        {
+            LogError("unable to execute a method when the methodCallback passed in CommandDecoder_Create is NULL");
+            result = NULL;
+        }
+        else
+        {
+            /*Codes_SRS_COMMAND_DECODER_02_016: [ If methodPayload is not NULL then CommandDecoder_ExecuteMethod shall build a MULTITREE_HANDLE out of methodPayload. ]*/
+            if (methodPayload == NULL)
+            {
+                result = DecodeMethod(commandDecoderInstance, fullMethodName, NULL);
+            }
+            else
+            {
+                char* methodJSON;
+
+                if (mallocAndStrcpy_s(&methodJSON, methodPayload) != 0)
+                {
+                    LogError("Failed to allocate temporary storage for the method JSON");
+                    result = NULL;
+                }
+                else
+                {
+                    MULTITREE_HANDLE methodTree;
+                    if (JSONDecoder_JSON_To_MultiTree(methodJSON, &methodTree) != JSON_DECODER_OK)
+                    {
+                        LogError("Decoding JSON to a multi tree failed");
+                        result = NULL;
+                    }
+                    else
+                    {
+                        result = DecodeMethod(commandDecoderInstance, fullMethodName, methodTree);
+                        MultiTree_Destroy(methodTree);
+                    }
+                    free(methodJSON);
+                }
+            }
+        }
+    }
+    return result;
+}
+
+
+COMMAND_DECODER_HANDLE CommandDecoder_Create(SCHEMA_MODEL_TYPE_HANDLE modelHandle, ACTION_CALLBACK_FUNC actionCallback, void* actionCallbackContext, METHOD_CALLBACK_FUNC methodCallback, void* methodCallbackContext)
+{
+    COMMAND_DECODER_HANDLE_DATA* result;
+    /* Codes_SRS_COMMAND_DECODER_99_019:[ For all exposed APIs argument validity checks shall precede other checks.] */
+    /* Codes_SRS_COMMAND_DECODER_01_003: [ If modelHandle is NULL, CommandDecoder_Create shall return NULL. ]*/
+    if (modelHandle == NULL)
+    {
+        LogError("Invalid arguments: SCHEMA_MODEL_TYPE_HANDLE modelHandle=%p, ACTION_CALLBACK_FUNC actionCallback=%p, void* actionCallbackContext=%p, METHOD_CALLBACK_FUNC methodCallback=%p, void* methodCallbackContext=%p",
+            modelHandle, actionCallback, actionCallbackContext, methodCallback, methodCallbackContext);
+        result = NULL;
+    }
+    else
+    {
+        /* Codes_SRS_COMMAND_DECODER_01_001: [CommandDecoder_Create shall create a new instance of a CommandDecoder.] */
+        result = malloc(sizeof(COMMAND_DECODER_HANDLE_DATA));
+        if (result == NULL)
+        {
+            /* Codes_SRS_COMMAND_DECODER_01_004: [If any error is encountered during CommandDecoder_Create CommandDecoder_Create shall return NULL.] */
+            /*return as is*/
+        }
+        else
+        {
+            result->ModelHandle = modelHandle;
+            result->ActionCallback = actionCallback;
+            result->ActionCallbackContext = actionCallbackContext;
+            result->methodCallback = methodCallback;
+            result->methodCallbackContext = methodCallbackContext;
+        }
+    }
+
+    return result;
+}
+
+void CommandDecoder_Destroy(COMMAND_DECODER_HANDLE commandDecoderHandle)
+{
+    /* Codes_SRS_COMMAND_DECODER_01_007: [If CommandDecoder_Destroy is called with a NULL handle, CommandDecoder_Destroy shall do nothing.] */
+    if (commandDecoderHandle != NULL)
+    {
+        COMMAND_DECODER_HANDLE_DATA* commandDecoderInstance = (COMMAND_DECODER_HANDLE_DATA*)commandDecoderHandle;
+
+        /* Codes_SRS_COMMAND_DECODER_01_005: [CommandDecoder_Destroy shall free all resources associated with the commandDecoderHandle instance.] */
+        free(commandDecoderInstance);
+    }
+}
+
+MU_DEFINE_ENUM_STRINGS_WITHOUT_INVALID(AGENT_DATA_TYPE_TYPE, AGENT_DATA_TYPE_TYPE_VALUES);
+
+/*validates that the multitree (coming from a JSON) is actually a serialization of the model (complete or incomplete)*/
+/*if the serialization contains more than the model, then it fails.*/
+/*if the serialization does not contain mandatory items from the model, it fails*/
+static bool validateModel_vs_Multitree(void* startAddress, SCHEMA_MODEL_TYPE_HANDLE modelHandle, MULTITREE_HANDLE desiredPropertiesTree, size_t offset)
+{
+
+    bool result;
+    size_t nChildren;
+    size_t nProcessedChildren = 0;
+    (void)MultiTree_GetChildCount(desiredPropertiesTree, &nChildren);
+    for (size_t i = 0;i < nChildren;i++)
+    {
+        MULTITREE_HANDLE child;
+        if (MultiTree_GetChild(desiredPropertiesTree, i, &child) != MULTITREE_OK)
+        {
+            LogError("failure in MultiTree_GetChild");
+            i = nChildren;
+        }
+        else
+        {
+            STRING_HANDLE childName = STRING_new();
+            if (childName == NULL)
+            {
+                LogError("failure to STRING_new");
+                i = nChildren;
+            }
+            else
+            {
+                if (MultiTree_GetName(child, childName) != MULTITREE_OK)
+                {
+                    LogError("failure to MultiTree_GetName");
+                    i = nChildren;
+                }
+                else
+                {
+                    const char *childName_str = STRING_c_str(childName);
+                    SCHEMA_MODEL_ELEMENT elementType = Schema_GetModelElementByName(modelHandle, childName_str);
+                    switch (elementType.elementType)
+                    {
+                        default:
+                        {
+                            LogError("INTERNAL ERROR: unexpected function return");
+                            i = nChildren;
+                            break;
+                        }
+                        case (SCHEMA_PROPERTY):
+                        {
+                            LogError("cannot ingest name (WITH_DATA instead of WITH_DESIRED_PROPERTY): %s", childName_str);
+                            i = nChildren;
+                            break;
+                        }
+                        case (SCHEMA_REPORTED_PROPERTY):
+                        {
+                            LogError("cannot ingest name (WITH_REPORTED_PROPERTY instead of WITH_DESIRED_PROPERTY): %s", childName_str);
+                            i = nChildren;
+                            break;
+                        }
+                        case (SCHEMA_DESIRED_PROPERTY):
+                        {
+                            /*Codes_SRS_COMMAND_DECODER_02_007: [ If the child name corresponds to a desired property then an AGENT_DATA_TYPE shall be constructed from the MULTITREE node. ]*/
+                            SCHEMA_DESIRED_PROPERTY_HANDLE desiredPropertyHandle = elementType.elementHandle.desiredPropertyHandle;
+
+                            const char* desiredPropertyType = Schema_GetModelDesiredPropertyType(desiredPropertyHandle);
+                            AGENT_DATA_TYPE output;
+                            if (DecodeValueFromNode(Schema_GetSchemaForModelType(modelHandle), &output, child, desiredPropertyType) != 0)
+                            {
+                                LogError("failure in DecodeValueFromNode");
+                                i = nChildren;
+                            }
+                            else
+                            {
+                                /*Codes_SRS_COMMAND_DECODER_02_008: [ The desired property shall be constructed in memory by calling pfDesiredPropertyFromAGENT_DATA_TYPE. ]*/
+                                pfDesiredPropertyFromAGENT_DATA_TYPE leFunction = Schema_GetModelDesiredProperty_pfDesiredPropertyFromAGENT_DATA_TYPE(desiredPropertyHandle);
+                                if (leFunction(&output, (char*)startAddress + offset + Schema_GetModelDesiredProperty_offset(desiredPropertyHandle)) != 0)
+                                {
+                                    LogError("failure in a function that converts from AGENT_DATA_TYPE to C data");
+                                }
+                                else
+                                {
+                                    /*Codes_SRS_COMMAND_DECODER_02_013: [ If the desired property has a non-NULL pfOnDesiredProperty then it shall be called. ]*/
+                                    pfOnDesiredProperty onDesiredProperty = Schema_GetModelDesiredProperty_pfOnDesiredProperty(desiredPropertyHandle);
+                                    if (onDesiredProperty != NULL)
+                                    {
+                                        onDesiredProperty((char*)startAddress + offset);
+                                    }
+                                    nProcessedChildren++;
+                                }
+                                Destroy_AGENT_DATA_TYPE(&output);
+                            }
+
+                            break;
+                        }
+                        case(SCHEMA_MODEL_IN_MODEL):
+                        {
+                            SCHEMA_MODEL_TYPE_HANDLE modelModel = elementType.elementHandle.modelHandle;
+
+                            /*Codes_SRS_COMMAND_DECODER_02_009: [ If the child name corresponds to a model in model then the function shall call itself recursively. ]*/
+                            if (!validateModel_vs_Multitree(startAddress, modelModel, child, offset + Schema_GetModelModelByName_Offset(modelHandle, childName_str)))
+                            {
+                                LogError("failure in validateModel_vs_Multitree");
+                                i = nChildren;
+                            }
+                            else
+                            {
+                                /*if the model in model so happened to be a WITH_DESIRED_PROPERTY... (only those has non_NULL pfOnDesiredProperty) */
+                                /*Codes_SRS_COMMAND_DECODER_02_012: [ If the child model in model has a non-NULL pfOnDesiredProperty then pfOnDesiredProperty shall be called. ]*/
+                                pfOnDesiredProperty onDesiredProperty = Schema_GetModelModelByName_OnDesiredProperty(modelHandle, childName_str);
+                                if (onDesiredProperty != NULL)
+                                {
+                                    onDesiredProperty((char*)startAddress + offset);
+                                }
+
+                                nProcessedChildren++;
+                            }
+
+                            break;
+                        }
+
+                    } /*switch*/
+                }
+                STRING_delete(childName);
+            }
+        }
+    }
+
+    if(nProcessedChildren == nChildren)
+    {
+        /*Codes_SRS_COMMAND_DECODER_02_010: [ If the complete MULTITREE has been parsed then CommandDecoder_IngestDesiredProperties shall succeed and return EXECUTE_COMMAND_SUCCESS. ]*/
+        result = true;
+    }
+    else
+    {
+        /*Codes_SRS_COMMAND_DECODER_02_011: [ Otherwise CommandDecoder_IngestDesiredProperties shall fail and return EXECUTE_COMMAND_FAILED. ]*/
+        LogError("not all constituents of the JSON have been ingested");
+        result = false;
+    }
+    return result;
+}
+
+static EXECUTE_COMMAND_RESULT DecodeDesiredProperties(void* startAddress, COMMAND_DECODER_HANDLE_DATA* handle, MULTITREE_HANDLE desiredPropertiesTree)
+{
+    /*Codes_SRS_COMMAND_DECODER_02_006: [ CommandDecoder_IngestDesiredProperties shall parse the MULTITREEE recursively. ]*/
+    return validateModel_vs_Multitree(startAddress, handle->ModelHandle, desiredPropertiesTree, 0 )?EXECUTE_COMMAND_SUCCESS:EXECUTE_COMMAND_FAILED;
+}
+
+/* Raw JSON has properties we don't need; potentially nodes other than "desired" for full TWIN as well as a $version we don't pass to callees */
+static bool RemoveUnneededTwinProperties(MULTITREE_HANDLE initialParsedTree, bool parseDesiredNode, MULTITREE_HANDLE *desiredPropertiesTree)
+{
+    MULTITREE_HANDLE updateTree;
+    bool result;
+
+    if (parseDesiredNode)
+    {
+        /*Codes_SRS_COMMAND_DECODER_02_014: [ If parseDesiredNode is TRUE, parse only the `desired` part of JSON tree ]*/
+        if (MultiTree_GetChildByName(initialParsedTree, "desired", &updateTree) != MULTITREE_OK)
+        {
+            LogError("Unable to find 'desired' in tree");
+            return false;
+        }
+    }
+    else
+    {
+        // Tree already starts on node we want so just use it.
+        updateTree = initialParsedTree;
+    }
+
+    /*Codes_COMMAND_DECODER_02_015: [ Remove '$version' string from node, if it is present.  It not being present is not an error ]*/
+    MULTITREE_RESULT deleteChildResult = MultiTree_DeleteChild(updateTree, "$version");
+    if ((deleteChildResult == MULTITREE_OK) || (deleteChildResult == MULTITREE_CHILD_NOT_FOUND))
+    {
+        *desiredPropertiesTree = updateTree;
+        result = true;
+    }
+    else
+    {
+        *desiredPropertiesTree = NULL;
+        result = false;
+    }
+
+    return result;
+}
+
+EXECUTE_COMMAND_RESULT CommandDecoder_IngestDesiredProperties(void* startAddress, COMMAND_DECODER_HANDLE handle, const char* jsonPayload, bool parseDesiredNode)
+{
+    EXECUTE_COMMAND_RESULT result;
+
+    /*Codes_SRS_COMMAND_DECODER_02_001: [ If startAddress is NULL then CommandDecoder_IngestDesiredProperties shall fail and return EXECUTE_COMMAND_ERROR. ]*/
+    /*Codes_SRS_COMMAND_DECODER_02_002: [ If handle is NULL then CommandDecoder_IngestDesiredProperties shall fail and return EXECUTE_COMMAND_ERROR. ]*/
+    /*Codes_SRS_COMMAND_DECODER_02_003: [ If jsonPayload is NULL then CommandDecoder_IngestDesiredProperties shall fail and return EXECUTE_COMMAND_ERROR. ]*/
+    if(
+        (startAddress == NULL) ||
+        (handle == NULL) ||
+        (jsonPayload == NULL)
+        )
+    {
+        LogError("invalid argument COMMAND_DECODER_HANDLE handle=%p, const char* jsonPayload=%p", handle, jsonPayload);
+        result = EXECUTE_COMMAND_ERROR;
+    }
+    else
+    {
+        /*Codes_SRS_COMMAND_DECODER_02_004: [ CommandDecoder_IngestDesiredProperties shall clone desiredProperties. ]*/
+        char* copy;
+        if (mallocAndStrcpy_s(&copy, jsonPayload) != 0)
+        {
+            LogError("failure in mallocAndStrcpy_s");
+            result = EXECUTE_COMMAND_FAILED;
+        }
+        else
+        {
+            /*Codes_SRS_COMMAND_DECODER_02_005: [ CommandDecoder_IngestDesiredProperties shall create a MULTITREE_HANDLE ouf of the clone of desiredProperties. ]*/
+            MULTITREE_HANDLE initialParsedTree;
+            MULTITREE_HANDLE desiredPropertiesTree;
+
+            if (JSONDecoder_JSON_To_MultiTree(copy, &initialParsedTree) != JSON_DECODER_OK)
+            {
+                LogError("Decoding JSON to a multi tree failed");
+                result = EXECUTE_COMMAND_ERROR;
+            }
+            else
+            {
+                if (RemoveUnneededTwinProperties(initialParsedTree, parseDesiredNode, &desiredPropertiesTree) == false)
+                {
+                    LogError("Removing unneeded twin properties failed");
+                    result = EXECUTE_COMMAND_ERROR;
+                }
+                else
+                {
+                    COMMAND_DECODER_HANDLE_DATA* commandDecoderInstance = (COMMAND_DECODER_HANDLE_DATA*)handle;
+
+                    /*Codes_SRS_COMMAND_DECODER_02_006: [ CommandDecoder_IngestDesiredProperties shall parse the MULTITREEE recursively. ]*/
+                    result = DecodeDesiredProperties(startAddress, commandDecoderInstance, desiredPropertiesTree);
+
+                    // Do NOT free desiredPropertiesTree.  It is only a pointer into initialParsedTree.
+                    MultiTree_Destroy(initialParsedTree);
+                }
+            }
+            free(copy);
+        }
+    }
+    return result;
+}
Index: azure_iot_hub_f767zi/trunk/azure_iot_sdk/serializer/src/datamarshaller.c
===================================================================
--- azure_iot_hub_f767zi/trunk/azure_iot_sdk/serializer/src/datamarshaller.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/azure_iot_sdk/serializer/src/datamarshaller.c	(revision 457)
@@ -0,0 +1,365 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+#include <stdlib.h> /*for free*/
+#include "azure_c_shared_utility/gballoc.h"
+
+#include <stdbool.h>
+#include "datamarshaller.h"
+#include "azure_c_shared_utility/crt_abstractions.h"
+#include "schema.h"
+#include "jsonencoder.h"
+#include "agenttypesystem.h"
+#include "azure_c_shared_utility/xlogging.h"
+#include "parson.h"
+#include "azure_c_shared_utility/vector.h"
+
+MU_DEFINE_ENUM_STRINGS_WITHOUT_INVALID(DATA_MARSHALLER_RESULT, DATA_MARSHALLER_RESULT_VALUES);
+
+#define LOG_DATA_MARSHALLER_ERROR \
+    LogError("(result = %s)", MU_ENUM_TO_STRING(DATA_MARSHALLER_RESULT, result));
+
+typedef struct DATA_MARSHALLER_HANDLE_DATA_TAG
+{
+    SCHEMA_MODEL_TYPE_HANDLE ModelHandle;
+    bool IncludePropertyPath;
+} DATA_MARSHALLER_HANDLE_DATA;
+
+static int NoCloneFunction(void** destination, const void* source)
+{
+    *destination = (void*)source;
+    return 0;
+}
+
+static void NoFreeFunction(void* value)
+{
+    (void)value;
+}
+
+DATA_MARSHALLER_HANDLE DataMarshaller_Create(SCHEMA_MODEL_TYPE_HANDLE modelHandle, bool includePropertyPath)
+{
+    DATA_MARSHALLER_HANDLE_DATA* result;
+
+    /*Codes_SRS_DATA_MARSHALLER_99_019:[ DataMarshaller_Create shall return NULL if any argument is NULL.]*/
+    if (modelHandle == NULL)
+    {
+        result = NULL;
+        LogError("(result = %s)", MU_ENUM_TO_STRING(DATA_MARSHALLER_RESULT, DATA_MARSHALLER_INVALID_ARG));
+    }
+    else if ((result = (DATA_MARSHALLER_HANDLE_DATA*)calloc(1, sizeof(DATA_MARSHALLER_HANDLE_DATA))) == NULL)
+    {
+        /* Codes_SRS_DATA_MARSHALLER_99_048:[On any other errors not explicitly specified, DataMarshaller_Create shall return NULL.] */
+        result = NULL;
+        LogError("(result = %s)", MU_ENUM_TO_STRING(DATA_MARSHALLER_RESULT, DATA_MARSHALLER_ERROR));
+    }
+    else
+    {
+        /*everything ok*/
+        /*Codes_SRS_DATA_MARSHALLER_99_018:[ DataMarshaller_Create shall create a new DataMarshaller instance and on success it shall return a non NULL handle.]*/
+        result->ModelHandle = modelHandle;
+        result->IncludePropertyPath = includePropertyPath;
+    }
+    return result;
+}
+
+void DataMarshaller_Destroy(DATA_MARSHALLER_HANDLE dataMarshallerHandle)
+{
+    /* Codes_SRS_DATA_MARSHALLER_99_024:[ When called with a NULL handle, DataMarshaller_Destroy shall do nothing.] */
+    if (dataMarshallerHandle != NULL)
+    {
+        /* Codes_SRS_DATA_MARSHALLER_99_022:[ DataMarshaller_Destroy shall free all resources associated with the dataMarshallerHandle argument.] */
+        DATA_MARSHALLER_HANDLE_DATA* dataMarshallerInstance = (DATA_MARSHALLER_HANDLE_DATA*)dataMarshallerHandle;
+        free(dataMarshallerInstance);
+    }
+}
+
+DATA_MARSHALLER_RESULT DataMarshaller_SendData(DATA_MARSHALLER_HANDLE dataMarshallerHandle, size_t valueCount, const DATA_MARSHALLER_VALUE* values, unsigned char** destination, size_t* destinationSize)
+{
+    DATA_MARSHALLER_HANDLE_DATA* dataMarshallerInstance = (DATA_MARSHALLER_HANDLE_DATA*)dataMarshallerHandle;
+    DATA_MARSHALLER_RESULT result;
+    MULTITREE_HANDLE treeHandle;
+
+    /* Codes_SRS_DATA_MARSHALLER_99_034:[All argument checks shall be performed before calling any other modules.] */
+    /* Codes_SRS_DATA_MARSHALLER_99_004:[ DATA_MARSHALLER_INVALID_ARG shall be returned when the function has detected an invalid parameter (NULL) being passed to the function.] */
+    if ((values == NULL) ||
+        (dataMarshallerHandle == NULL) ||
+        (destination == NULL) ||
+        (destinationSize == NULL) ||
+        /* Codes_SRS_DATA_MARSHALLER_99_033:[ DATA_MARSHALLER_INVALID_ARG shall be returned if the valueCount is zero.] */
+        (valueCount == 0))
+    {
+        result = DATA_MARSHALLER_INVALID_ARG;
+        LOG_DATA_MARSHALLER_ERROR
+    }
+    else
+    {
+        size_t i;
+        bool includePropertyPath = dataMarshallerInstance->IncludePropertyPath;
+        /* VS complains wrongly that result is not initialized */
+        result = DATA_MARSHALLER_ERROR;
+
+        for (i = 0; i < valueCount; i++)
+        {
+            if ((values[i].PropertyPath == NULL) ||
+                (values[i].Value == NULL))
+            {
+                /*Codes_SRS_DATA_MARSHALLER_99_007:[ DATA_MARSHALLER_INVALID_MODEL_PROPERTY shall be returned when any of the items in values contain invalid data]*/
+                result = DATA_MARSHALLER_INVALID_MODEL_PROPERTY;
+                LOG_DATA_MARSHALLER_ERROR
+                break;
+            }
+
+            if ((!dataMarshallerInstance->IncludePropertyPath) &&
+                (values[i].Value->type == EDM_COMPLEX_TYPE_TYPE) &&
+                (valueCount > 1))
+            {
+                /* Codes_SRS_DATAMARSHALLER_01_002: [If the includePropertyPath argument passed to DataMarshaller_Create was false and the number of values passed to SendData is greater than 1 and at least one of them is a struct, DataMarshaller_SendData shall fallback to  including the complete property path in the output JSON.] */
+                includePropertyPath = true;
+            }
+        }
+
+        if (i == valueCount)
+        {
+            /* Codes_SRS_DATA_MARSHALLER_99_037:[DataMarshaller shall store as MultiTree the data to be encoded by the JSONEncoder module.] */
+            if ((treeHandle = MultiTree_Create(NoCloneFunction, NoFreeFunction)) == NULL)
+            {
+                /* Codes_SRS_DATA_MARSHALLER_99_035:[DATA_MARSHALLER_MULTITREE_ERROR shall be returned in case any MultiTree API call fails.] */
+                result = DATA_MARSHALLER_MULTITREE_ERROR;
+                LOG_DATA_MARSHALLER_ERROR
+            }
+            else
+            {
+                size_t j;
+                result = DATA_MARSHALLER_OK; /* addressing warning in VS compiler */
+                /* Codes_SRS_DATA_MARSHALLER_99_038:[For each pair in the values argument, a string : value pair shall exist in the JSON object in the form of propertyName : value.] */
+                for (j = 0; j < valueCount; j++)
+                {
+                    if ((includePropertyPath == false) && (values[j].Value->type == EDM_COMPLEX_TYPE_TYPE))
+                    {
+                        size_t k;
+
+                        /* Codes_SRS_DATAMARSHALLER_01_001: [If the includePropertyPath argument passed to DataMarshaller_Create was false and only one struct is being sent, the relative path of the value passed to DataMarshaller_SendData - including property name - shall be ignored and the value shall be placed at JSON root.] */
+                        for (k = 0; k < values[j].Value->value.edmComplexType.nMembers; k++)
+                        {
+                            /* Codes_SRS_DATAMARSHALLER_01_004: [In this case the members of the struct shall be added as leafs into the MultiTree, each leaf having the name of the struct member.] */
+                            if (MultiTree_AddLeaf(treeHandle, values[j].Value->value.edmComplexType.fields[k].fieldName, (void*)values[j].Value->value.edmComplexType.fields[k].value) != MULTITREE_OK)
+                            {
+                                break;
+                            }
+                        }
+
+                        if (k < values[j].Value->value.edmComplexType.nMembers)
+                        {
+                            /* Codes_SRS_DATA_MARSHALLER_99_035:[DATA_MARSHALLER_MULTITREE_ERROR shall be returned in case any MultiTree API call fails.] */
+                            result = DATA_MARSHALLER_MULTITREE_ERROR;
+                            LOG_DATA_MARSHALLER_ERROR
+                            break;
+                        }
+                    }
+                    else
+                    {
+                        /* Codes_SRS_DATA_MARSHALLER_99_039:[ If the includePropertyPath argument passed to DataMarshaller_Create was true each property shall be placed in the appropriate position in the JSON according to its path in the model.] */
+                        if (MultiTree_AddLeaf(treeHandle, values[j].PropertyPath, (void*)values[j].Value) != MULTITREE_OK)
+                        {
+                            /* Codes_SRS_DATA_MARSHALLER_99_035:[DATA_MARSHALLER_MULTITREE_ERROR shall be returned in case any MultiTree API call fails.] */
+                            result = DATA_MARSHALLER_MULTITREE_ERROR;
+                            LOG_DATA_MARSHALLER_ERROR
+                            break;
+                        }
+                    }
+
+                }
+
+                if (j == valueCount)
+                {
+                    STRING_HANDLE payload = STRING_new();
+                    if (payload == NULL)
+                    {
+                        result = DATA_MARSHALLER_ERROR;
+                        LOG_DATA_MARSHALLER_ERROR
+                    }
+                    else
+                    {
+                        if (JSONEncoder_EncodeTree(treeHandle, payload, (JSON_ENCODER_TOSTRING_FUNC)AgentDataTypes_ToString) != JSON_ENCODER_OK)
+                        {
+                            /* Codes_SRS_DATA_MARSHALLER_99_027:[ DATA_MARSHALLER_JSON_ENCODER_ERROR shall be returned when JSONEncoder returns an error code.] */
+                            result = DATA_MARSHALLER_JSON_ENCODER_ERROR;
+                            LOG_DATA_MARSHALLER_ERROR
+                        }
+                        else
+                        {
+                            /*Codes_SRS_DATAMARSHALLER_02_007: [DataMarshaller_SendData shall copy in the output parameters *destination, *destinationSize the content and the content length of the encoded JSON tree.] */
+                            size_t resultSize = STRING_length(payload);
+                            unsigned char* temp = malloc(resultSize);
+                            if (temp == NULL)
+                            {
+                                /*Codes_SRS_DATA_MARSHALLER_99_015:[ DATA_MARSHALLER_ERROR shall be returned in all the other error cases not explicitly defined here.]*/
+                                result = DATA_MARSHALLER_ERROR;
+                                LOG_DATA_MARSHALLER_ERROR;
+                            }
+                            else
+                            {
+                                (void)memcpy(temp, STRING_c_str(payload), resultSize);
+                                *destination = temp;
+                                *destinationSize = resultSize;
+                                result = DATA_MARSHALLER_OK;
+                            }
+                        }
+                        STRING_delete(payload);
+                    }
+                } /* if (j==valueCount)*/
+                MultiTree_Destroy(treeHandle);
+            } /* MultiTree_Create */
+        }
+    }
+
+    return result;
+}
+
+
+DATA_MARSHALLER_RESULT DataMarshaller_SendData_ReportedProperties(DATA_MARSHALLER_HANDLE dataMarshallerHandle, VECTOR_HANDLE values, unsigned char** destination, size_t* destinationSize)
+{
+    DATA_MARSHALLER_RESULT result;
+    /*Codes_SRS_DATA_MARSHALLER_02_021: [ If argument dataMarshallerHandle is NULL then DataMarshaller_SendData_ReportedProperties shall fail and return DATA_MARSHALLER_INVALID_ARG. ]*/
+    /*Codes_SRS_DATA_MARSHALLER_02_008: [ If argument values is NULL then DataMarshaller_SendData_ReportedProperties shall fail and return DATA_MARSHALLER_INVALID_ARG. ]*/
+    /*Codes_SRS_DATA_MARSHALLER_02_009: [ If argument destination NULL then DataMarshaller_SendData_ReportedProperties shall fail and return DATA_MARSHALLER_INVALID_ARG. ]*/
+    /*Codes_SRS_DATA_MARSHALLER_02_010: [ If argument destinationSize NULL then DataMarshaller_SendData_ReportedProperties shall fail and return DATA_MARSHALLER_INVALID_ARG. ]*/
+    if (
+        (dataMarshallerHandle == NULL) ||
+        (values == NULL) ||
+        (destination == NULL) ||
+        (destinationSize == NULL)
+        )
+    {
+        LogError("invalid argument DATA_MARSHALLER_HANDLE dataMarshallerHandle=%p, VECTOR_HANDLE values=%p, unsigned char** destination=%p, size_t* destinationSize=%p",
+            dataMarshallerHandle,
+            values,
+            destination,
+            destinationSize);
+        result = DATA_MARSHALLER_INVALID_ARG;
+    }
+    else
+    {
+        /*Codes_SRS_DATA_MARSHALLER_02_012: [ DataMarshaller_SendData_ReportedProperties shall create an empty JSON_Value. ]*/
+        JSON_Value* json = json_value_init_object();
+        if (json == NULL)
+        {
+            /*Codes_SRS_DATA_MARSHALLER_02_019: [ If any failure occurs, DataMarshaller_SendData_ReportedProperties shall fail and return DATA_MARSHALLER_ERROR. ]*/
+            LogError("failure calling json_value_init_object");
+            result = DATA_MARSHALLER_ERROR;
+        }
+        else
+        {
+            /*Codes_SRS_DATA_MARSHALLER_02_013: [ DataMarshaller_SendData_ReportedProperties shall get the object behind the JSON_Value by calling json_object. ]*/
+            JSON_Object* jsonObject = json_object(json);
+            if (jsonObject == NULL)
+            {
+                /*Codes_SRS_DATA_MARSHALLER_02_019: [ If any failure occurs, DataMarshaller_SendData_ReportedProperties shall fail and return DATA_MARSHALLER_ERROR. ]*/
+                LogError("failure calling json_object");
+                result = DATA_MARSHALLER_ERROR;
+            }
+            else
+            {
+                size_t nReportedProperties = VECTOR_size(values), nProcessedProperties = 0;
+
+                for (size_t i = 0;i < nReportedProperties; i++)
+                {
+                    DATA_MARSHALLER_VALUE* v = *(DATA_MARSHALLER_VALUE**)VECTOR_element(values, i);
+                    STRING_HANDLE s = STRING_new();
+                    if (s == NULL)
+                    {
+                        /*Codes_SRS_DATA_MARSHALLER_02_019: [ If any failure occurs, DataMarshaller_SendData_ReportedProperties shall fail and return DATA_MARSHALLER_ERROR. ]*/
+                        LogError("failure calling STRING_new");
+                        i = nReportedProperties;/*forces loop to break, result is set in the "if" following this for*/
+                    }
+                    else
+                    {
+                        /*Codes_SRS_DATA_MARSHALLER_02_014: [ For every reported property, DataMarshaller_SendData_ReportedProperties shall get the reported property's JSON value (as string) by calling AgentDataTypes_ToString. ]*/
+                        if (AgentDataTypes_ToString(s, v->Value) != AGENT_DATA_TYPES_OK)
+                        {
+                            /*Codes_SRS_DATA_MARSHALLER_02_019: [ If any failure occurs, DataMarshaller_SendData_ReportedProperties shall fail and return DATA_MARSHALLER_ERROR. ]*/
+                            LogError("failure calling AgentDataTypes_ToString");
+                            i = nReportedProperties;/*forces loop to break, result is set in the "if" following this for*/
+                        }
+                        else
+                        {
+                            /*Codes_SRS_DATA_MARSHALLER_02_015: [ DataMarshaller_SendData_ReportedProperties shall import the JSON value (as string) by calling json_parse_string. ]*/
+                            JSON_Value * rightSide = json_parse_string(STRING_c_str(s));
+                            if (rightSide == NULL)
+                            {
+                                /*Codes_SRS_DATA_MARSHALLER_02_019: [ If any failure occurs, DataMarshaller_SendData_ReportedProperties shall fail and return DATA_MARSHALLER_ERROR. ]*/
+                                LogError("failure calling json_parse_string");
+                                i = nReportedProperties;/*forces loop to break, result is set in the "if" following this for*/
+                            }
+                            else
+                            {
+                                char* leftSide;
+                                if (mallocAndStrcpy_s(&leftSide, v->PropertyPath) != 0)
+                                {
+                                    /*Codes_SRS_DATA_MARSHALLER_02_019: [ If any failure occurs, DataMarshaller_SendData_ReportedProperties shall fail and return DATA_MARSHALLER_ERROR. ]*/
+                                    LogError("failure calling mallocAndStrcpy_s");
+                                    json_value_free(rightSide);
+                                    i = nReportedProperties;/*forces loop to break, result is set in the "if" following this for*/
+                                }
+                                else
+                                {
+                                    /*Codes_SRS_DATA_MARSHALLER_02_016: [ DataMarshaller_SendData_ReportedProperties shall replace all the occurences of / with . in the reported property paths. ]*/
+                                    char *whereIsSlash;
+                                    while ((whereIsSlash = strchr(leftSide, '/')) != NULL)
+                                    {
+                                        *whereIsSlash = '.';
+                                    }
+
+                                    /*Codes_SRS_DATA_MARSHALLER_02_017: [ DataMarshaller_SendData_ReportedProperties shall use json_object_dotset_value passing the reported property path and the imported json value. ]*/
+                                    /*Codes_SRS_DATA_MARSHALLER_02_011: [ DataMarshaller_SendData_ReportedProperties shall ignore the value of includePropertyPath and shall consider it to be true. ]*/
+                                    if (json_object_dotset_value(jsonObject, leftSide, rightSide) != JSONSuccess)
+                                    {
+                                        /*Codes_SRS_DATA_MARSHALLER_02_019: [ If any failure occurs, DataMarshaller_SendData_ReportedProperties shall fail and return DATA_MARSHALLER_ERROR. ]*/
+                                        LogError("failure calling json_object_dotset_value");
+                                        json_value_free(rightSide);
+                                        i = nReportedProperties;/*forces loop to break, result is set in the "if" following this for*/
+                                    }
+                                    else
+                                    {
+                                        /*all is fine with this property... */
+                                        nProcessedProperties++;
+                                    }
+                                    free(leftSide);
+                                }
+                            }
+                        }
+                        STRING_delete(s);
+                    }
+                }
+
+                if (nProcessedProperties != nReportedProperties)
+                {
+                    result = DATA_MARSHALLER_ERROR;
+                    /*all properties have NOT been processed*/
+                    /*return result as is*/
+                }
+                else
+                {
+                    /*Codes_SRS_DATA_MARSHALLER_02_018: [ DataMarshaller_SendData_ReportedProperties shall use json_serialize_to_string_pretty to produce the output JSON string that fills out parameters destination and destionationSize. ]*/
+                    char* temp = json_serialize_to_string_pretty(json);
+                    if (temp == NULL)
+                    {
+                        /*Codes_SRS_DATA_MARSHALLER_02_019: [ If any failure occurs, DataMarshaller_SendData_ReportedProperties shall fail and return DATA_MARSHALLER_ERROR. ]*/
+                        LogError("failure calling json_serialize_to_string_pretty ");
+                        result = DATA_MARSHALLER_ERROR;
+                    }
+                    else
+                    {
+                        /*Codes_SRS_DATA_MARSHALLER_02_020: [ Otherwise DataMarshaller_SendData_ReportedProperties shall succeed and return DATA_MARSHALLER_OK. ]*/
+                        *destination = (unsigned char*)temp;
+                        *destinationSize = strlen(temp);
+                        result = DATA_MARSHALLER_OK;
+                        /*all is fine... */
+                    }
+                }
+            }
+            json_value_free(json);
+        }
+    }
+    return result;
+}
Index: azure_iot_hub_f767zi/trunk/azure_iot_sdk/serializer/src/datapublisher.c
===================================================================
--- azure_iot_hub_f767zi/trunk/azure_iot_sdk/serializer/src/datapublisher.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/azure_iot_sdk/serializer/src/datapublisher.c	(revision 457)
@@ -0,0 +1,571 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+#include <stdlib.h>
+#include "azure_c_shared_utility/gballoc.h"
+
+#include <stdbool.h>
+#include "datapublisher.h"
+#include "jsonencoder.h"
+#include "datamarshaller.h"
+#include "agenttypesystem.h"
+#include "schema.h"
+#include "azure_c_shared_utility/crt_abstractions.h"
+#include "azure_c_shared_utility/xlogging.h"
+#include "azure_c_shared_utility/vector.h"
+
+MU_DEFINE_ENUM_STRINGS_WITHOUT_INVALID(DATA_PUBLISHER_RESULT, DATA_PUBLISHER_RESULT_VALUES)
+
+#define LOG_DATA_PUBLISHER_ERROR \
+    LogError("(result = %s)", MU_ENUM_TO_STRING(DATA_PUBLISHER_RESULT, result))
+
+#define DEFAULT_MAX_BUFFER_SIZE 10240
+/* Codes_SRS_DATA_PUBLISHER_99_066:[ A single value shall be used by all instances of DataPublisher.] */
+/* Codes_SRS_DATA_PUBLISHER_99_067:[ Before any call to DataPublisher_SetMaxBufferSize, the default max buffer size shall be equal to 10KB.] */
+static size_t maxBufferSize_ = DEFAULT_MAX_BUFFER_SIZE;
+
+typedef struct DATA_PUBLISHER_HANDLE_DATA_TAG
+{
+    DATA_MARSHALLER_HANDLE DataMarshallerHandle;
+    SCHEMA_MODEL_TYPE_HANDLE ModelHandle;
+} DATA_PUBLISHER_HANDLE_DATA;
+
+typedef struct TRANSACTION_HANDLE_DATA_TAG
+{
+    DATA_PUBLISHER_HANDLE_DATA* DataPublisherInstance;
+    size_t ValueCount;
+    DATA_MARSHALLER_VALUE* Values;
+} TRANSACTION_HANDLE_DATA;
+
+typedef struct REPORTED_PROPERTIES_TRANSACTION_HANDLE_DATA_TAG
+{
+    DATA_PUBLISHER_HANDLE_DATA* DataPublisherInstance;
+    VECTOR_HANDLE value; /*holds (DATA_MARSHALLER_VALUE*) */
+}REPORTED_PROPERTIES_TRANSACTION_HANDLE_DATA;
+
+DATA_PUBLISHER_HANDLE DataPublisher_Create(SCHEMA_MODEL_TYPE_HANDLE modelHandle, bool includePropertyPath)
+{
+    DATA_PUBLISHER_HANDLE_DATA* result;
+
+    /* Codes_SRS_DATA_PUBLISHER_99_042:[ If a NULL argument is passed to it, DataPublisher_Create shall return NULL.] */
+    if (modelHandle == NULL)
+    {
+        result = NULL;
+        LogError("(result = %s)", MU_ENUM_TO_STRING(DATA_PUBLISHER_RESULT, DATA_PUBLISHER_INVALID_ARG));
+    }
+    else if ((result = (DATA_PUBLISHER_HANDLE_DATA*)malloc(sizeof(DATA_PUBLISHER_HANDLE_DATA))) == NULL)
+    {
+        /* Codes_SRS_DATA_PUBLISHER_99_047:[ For any other error not specified here, DataPublisher_Create shall return NULL.] */
+        result = NULL;
+        LogError("(result = %s)", MU_ENUM_TO_STRING(DATA_PUBLISHER_RESULT, DATA_PUBLISHER_ERROR));
+    }
+    else
+    {
+        /* Codes_SRS_DATA_PUBLISHER_99_043:[ DataPublisher_Create shall initialize and hold a handle to a DataMarshaller instance.] */
+        /* Codes_SRS_DATA_PUBLISHER_01_001: [DataPublisher_Create shall pass the includePropertyPath argument to DataMarshaller_Create.] */
+        if ((result->DataMarshallerHandle = DataMarshaller_Create(modelHandle, includePropertyPath)) == NULL)
+        {
+            free(result);
+
+            /* Codes_SRS_DATA_PUBLISHER_99_044:[ If the creation of the DataMarshaller instance fails, DataPublisher_Create shall return NULL.] */
+            result = NULL;
+            LogError("(result = %s)", MU_ENUM_TO_STRING(DATA_PUBLISHER_RESULT, DATA_PUBLISHER_MARSHALLER_ERROR));
+        }
+        else
+        {
+            /* Codes_SRS_DATA_PUBLISHER_99_041:[ DataPublisher_Create shall create a new DataPublisher instance and return a non-NULL handle in case of success.] */
+            result->ModelHandle = modelHandle;
+        }
+    }
+
+    return result;
+}
+
+void DataPublisher_Destroy(DATA_PUBLISHER_HANDLE dataPublisherHandle)
+{
+    if (dataPublisherHandle != NULL)
+    {
+        DATA_PUBLISHER_HANDLE_DATA* dataPublisherInstance = (DATA_PUBLISHER_HANDLE_DATA*)dataPublisherHandle;
+        DataMarshaller_Destroy(dataPublisherInstance->DataMarshallerHandle);
+
+        free(dataPublisherHandle);
+    }
+}
+
+TRANSACTION_HANDLE DataPublisher_StartTransaction(DATA_PUBLISHER_HANDLE dataPublisherHandle)
+{
+    TRANSACTION_HANDLE_DATA* transaction;
+
+    /* Codes_SRS_DATA_PUBLISHER_99_038:[ If DataPublisher_StartTransaction is called with a NULL argument it shall return NULL.] */
+    if (dataPublisherHandle == NULL)
+    {
+        transaction = NULL;
+        LogError("(Error code: %s)", MU_ENUM_TO_STRING(DATA_PUBLISHER_RESULT, DATA_PUBLISHER_INVALID_ARG));
+    }
+    else
+    {
+        /* Codes_SRS_DATA_PUBLISHER_99_007:[ A call to DataPublisher_StartTransaction shall start a new transaction.] */
+        transaction = (TRANSACTION_HANDLE_DATA*)calloc(1, sizeof(TRANSACTION_HANDLE_DATA));
+        if (transaction == NULL)
+        {
+            LogError("Allocating transaction failed (Error code: %s)", MU_ENUM_TO_STRING(DATA_PUBLISHER_RESULT, DATA_PUBLISHER_ERROR));
+        }
+        else
+        {
+            transaction->ValueCount = 0;
+            transaction->Values = NULL;
+            transaction->DataPublisherInstance = (DATA_PUBLISHER_HANDLE_DATA*)dataPublisherHandle;
+        }
+    }
+
+    /* Codes_SRS_DATA_PUBLISHER_99_008:[ DataPublisher_StartTransaction shall return a non-NULL handle upon success.] */
+    /* Codes_SRS_DATA_PUBLISHER_99_009:[ DataPublisher_StartTransaction shall return NULL upon failure.] */
+    return transaction;
+}
+
+DATA_PUBLISHER_RESULT DataPublisher_PublishTransacted(TRANSACTION_HANDLE transactionHandle, const char* propertyPath, const AGENT_DATA_TYPE* data)
+{
+    DATA_PUBLISHER_RESULT result;
+    char* propertyPathCopy;
+
+    /* Codes_SRS_DATA_PUBLISHER_99_017:[ When one or more NULL parameter(s) are specified, DataPublisher_PublishTransacted is called with a NULL transactionHandle, it shall return DATA_PUBLISHER_INVALID_ARG.] */
+    if ((transactionHandle == NULL) ||
+        (propertyPath == NULL) ||
+        (data == NULL))
+    {
+        result = DATA_PUBLISHER_INVALID_ARG;
+        LOG_DATA_PUBLISHER_ERROR;
+    }
+    else if (mallocAndStrcpy_s(&propertyPathCopy, propertyPath) != 0)
+    {
+        /* Codes_SRS_DATA_PUBLISHER_99_020:[ For any errors not explicitly mentioned here the DataPublisher APIs shall return DATA_PUBLISHER_ERROR.] */
+        result = DATA_PUBLISHER_ERROR;
+        LOG_DATA_PUBLISHER_ERROR;
+    }
+    else
+    {
+        TRANSACTION_HANDLE_DATA* transaction = (TRANSACTION_HANDLE_DATA*)transactionHandle;
+        AGENT_DATA_TYPE* propertyValue;
+
+        if (!Schema_ModelPropertyByPathExists(transaction->DataPublisherInstance->ModelHandle, propertyPath))
+        {
+            free(propertyPathCopy);
+
+            /* Codes_SRS_DATA_PUBLISHER_99_040:[ When propertyPath does not exist in the supplied model, DataPublisher_Publish shall return DATA_PUBLISHER_SCHEMA_FAILED without dispatching data.] */
+            result = DATA_PUBLISHER_SCHEMA_FAILED;
+            LOG_DATA_PUBLISHER_ERROR;
+        }
+        else if ((propertyValue = (AGENT_DATA_TYPE*)calloc(1, sizeof(AGENT_DATA_TYPE))) == NULL)
+        {
+            free(propertyPathCopy);
+
+            /* Codes_SRS_DATA_PUBLISHER_99_020:[ For any errors not explicitly mentioned here the DataPublisher APIs shall return DATA_PUBLISHER_ERROR.] */
+            result = DATA_PUBLISHER_ERROR;
+            LOG_DATA_PUBLISHER_ERROR;
+        }
+        else if (Create_AGENT_DATA_TYPE_from_AGENT_DATA_TYPE(propertyValue, data) != AGENT_DATA_TYPES_OK)
+        {
+            free(propertyPathCopy);
+            free(propertyValue);
+
+            /* Codes_SRS_DATA_PUBLISHER_99_028:[ If creating the copy fails then DATA_PUBLISHER_AGENT_DATA_TYPES_ERROR shall be returned.] */
+            result = DATA_PUBLISHER_AGENT_DATA_TYPES_ERROR;
+            LOG_DATA_PUBLISHER_ERROR;
+        }
+        else
+        {
+            size_t i;
+            DATA_MARSHALLER_VALUE* propertySlot = NULL;
+
+            /* Codes_SRS_DATA_PUBLISHER_99_019:[ If the same property is associated twice with a transaction, then the last value shall be kept associated with the transaction.] */
+            for (i = 0; i < transaction->ValueCount; i++)
+            {
+                if (strcmp(transaction->Values[i].PropertyPath, propertyPath) == 0)
+                {
+                    propertySlot = &transaction->Values[i];
+                    break;
+                }
+            }
+
+            if (propertySlot == NULL)
+            {
+                DATA_MARSHALLER_VALUE* newValues = (DATA_MARSHALLER_VALUE*)realloc(transaction->Values, sizeof(DATA_MARSHALLER_VALUE)* (transaction->ValueCount + 1));
+                if (newValues != NULL)
+                {
+                    transaction->Values = newValues;
+                    propertySlot = &transaction->Values[transaction->ValueCount];
+                    propertySlot->Value = NULL;
+                    propertySlot->PropertyPath = NULL;
+                    transaction->ValueCount++;
+                }
+            }
+
+            if (propertySlot == NULL)
+            {
+                Destroy_AGENT_DATA_TYPE((AGENT_DATA_TYPE*)propertyValue);
+                free(propertyValue);
+                free(propertyPathCopy);
+
+                /* Codes_SRS_DATA_PUBLISHER_99_020:[ For any errors not explicitly mentioned here the DataPublisher APIs shall return DATA_PUBLISHER_ERROR.] */
+                result = DATA_PUBLISHER_ERROR;
+                LOG_DATA_PUBLISHER_ERROR;
+            }
+            else
+            {
+                if (propertySlot->Value != NULL)
+                {
+                    Destroy_AGENT_DATA_TYPE((AGENT_DATA_TYPE*)propertySlot->Value);
+                    free((AGENT_DATA_TYPE*)propertySlot->Value);
+                }
+                if (propertySlot->PropertyPath != NULL)
+                {
+                    char* existingValue = (char*)propertySlot->PropertyPath;
+                    free(existingValue);
+                }
+
+                /* Codes_SRS_DATA_PUBLISHER_99_016:[ When DataPublisher_PublishTransacted is invoked, DataPublisher shall associate the data with the transaction identified by the transactionHandle argument and return DATA_PUBLISHER_OK. No data shall be dispatched at the time of the call.] */
+                propertySlot->PropertyPath = propertyPathCopy;
+                propertySlot->Value = propertyValue;
+
+                result = DATA_PUBLISHER_OK;
+            }
+        }
+    }
+
+    return result;
+}
+
+DATA_PUBLISHER_RESULT DataPublisher_EndTransaction(TRANSACTION_HANDLE transactionHandle, unsigned char** destination, size_t* destinationSize)
+{
+    DATA_PUBLISHER_RESULT result;
+
+    /*Codes_SRS_DATA_PUBLISHER_02_006: [If the destination argument is NULL, DataPublisher_EndTransaction shall return DATA_PUBLISHER_INVALID_ARG.] */
+    /*Codes_SRS_DATA_PUBLISHER_02_007: [If the destinationSize argument is NULL, DataPublisher_EndTransaction shall return DATA_PUBLISHER_INVALID_ARG.] */
+    if (
+        (transactionHandle == NULL) ||
+        (destination == NULL) ||
+        (destinationSize == NULL)
+        )
+    {
+        /* Codes_SRS_DATA_PUBLISHER_99_011:[ If the transactionHandle argument is NULL, DataPublisher_EndTransaction shall return DATA_PUBLISHER_INVALID_ARG.] */
+        result = DATA_PUBLISHER_INVALID_ARG;
+        LOG_DATA_PUBLISHER_ERROR;
+    }
+    else
+    {
+        TRANSACTION_HANDLE_DATA* transaction = (TRANSACTION_HANDLE_DATA*)transactionHandle;
+
+        if (transaction->ValueCount == 0)
+        {
+            /* Codes_SRS_DATA_PUBLISHER_99_024:[ If no values have been associated with the transaction, no data shall be dispatched
+                                            to DataMarshaller, the transaction shall be discarded and DataPublisher_EndTransaction shall return DATA_PUBLISHER_EMPTY_TRANSACTION.] */
+            result = DATA_PUBLISHER_EMPTY_TRANSACTION;
+            LOG_DATA_PUBLISHER_ERROR;
+        }
+        /* Codes_SRS_DATA_PUBLISHER_99_010:[ A call to DataPublisher_EndTransaction shall mark the end of a transaction and, trigger a dispatch of all the data grouped by that transaction.] */
+        else if (DataMarshaller_SendData(transaction->DataPublisherInstance->DataMarshallerHandle, transaction->ValueCount, transaction->Values, destination, destinationSize) != DATA_MARSHALLER_OK)
+        {
+            /* Codes_SRS_DATA_PUBLISHER_99_025:[ When the DataMarshaller_SendData call fails, DataPublisher_EndTransaction shall return DATA_PUBLISHER_MARSHALLER_ERROR.] */
+            result = DATA_PUBLISHER_MARSHALLER_ERROR;
+            LOG_DATA_PUBLISHER_ERROR;
+        }
+        else
+        {
+            /* Codes_SRS_DATA_PUBLISHER_99_026:[ On success, DataPublisher_EndTransaction shall return DATA_PUBLISHER_OK.] */
+            result = DATA_PUBLISHER_OK;
+        }
+
+        /* Codes_SRS_DATA_PUBLISHER_99_012:[ DataPublisher_EndTransaction shall dispose of any resources associated with the transaction.] */
+        (void)DataPublisher_CancelTransaction(transactionHandle);
+    }
+
+    return result;
+}
+
+DATA_PUBLISHER_RESULT DataPublisher_CancelTransaction(TRANSACTION_HANDLE transactionHandle)
+{
+    DATA_PUBLISHER_RESULT result;
+
+    if (transactionHandle == NULL)
+    {
+        /* Codes_SRS_DATA_PUBLISHER_99_014:[ If the transactionHandle argument is NULL DataPublisher_CancelTransaction shall return DATA_PUBLISHER_INVALID_ARG.] */
+        result = DATA_PUBLISHER_INVALID_ARG;
+        LOG_DATA_PUBLISHER_ERROR;
+    }
+    else
+    {
+        TRANSACTION_HANDLE_DATA* transaction = (TRANSACTION_HANDLE_DATA*)transactionHandle;
+        size_t i;
+
+        /* Codes_SRS_DATA_PUBLISHER_99_015:[ DataPublisher_CancelTransaction shall dispose of any resources associated with the transaction.] */
+        for (i = 0; i < transaction->ValueCount; i++)
+        {
+            Destroy_AGENT_DATA_TYPE((AGENT_DATA_TYPE*)transaction->Values[i].Value);
+            free((char*)transaction->Values[i].PropertyPath);
+            free((AGENT_DATA_TYPE*)transaction->Values[i].Value);
+        }
+
+        /* Codes_SRS_DATA_PUBLISHER_99_015:[ DataPublisher_CancelTransaction shall dispose of any resources associated with the transaction.] */
+        free(transaction->Values);
+        free(transaction);
+
+        /* Codes_SRS_DATA_PUBLISHER_99_013:[ A call to DataPublisher_CancelTransaction shall dispose of the transaction without dispatching
+                                        the data to the DataMarshaller module and it shall return DATA_PUBLISHER_OK.] */
+        result = DATA_PUBLISHER_OK;
+    }
+
+    return result;
+}
+
+/* Codes_SRS_DATA_PUBLISHER_99_065:[ DataPublisher_SetMaxBufferSize shall directly update the value used to limit how much data (in bytes) can be buffered in the BufferStorage instance.] */
+void DataPublisher_SetMaxBufferSize(size_t value)
+{
+    maxBufferSize_ = value;
+}
+
+/* Codes_SRS_DATA_PUBLISHER_99_069:[ DataMarshaller_GetMaxBufferSize shall return the current max buffer size value used by any new instance of DataMarshaller.] */
+size_t DataPublisher_GetMaxBufferSize(void)
+{
+    return maxBufferSize_;
+}
+
+REPORTED_PROPERTIES_TRANSACTION_HANDLE DataPublisher_CreateTransaction_ReportedProperties(DATA_PUBLISHER_HANDLE dataPublisherHandle)
+{
+    REPORTED_PROPERTIES_TRANSACTION_HANDLE_DATA* result;
+    /*Codes_SRS_DATA_PUBLISHER_02_027: [ If argument dataPublisherHandle is NULL then DataPublisher_CreateTransaction_ReportedProperties shall fail and return NULL. ]*/
+    if (dataPublisherHandle == NULL)
+    {
+        LogError("invalid argument DATA_PUBLISHER_HANDLE dataPublisherHandle=%p", dataPublisherHandle);
+        result = NULL;
+    }
+    else
+    {
+        /*Codes_SRS_DATA_PUBLISHER_02_028: [ DataPublisher_CreateTransaction_ReportedProperties shall create a VECTOR_HANDLE holding the individual elements of the transaction (DATA_MARSHALLER_VALUE). ]*/
+        result = (REPORTED_PROPERTIES_TRANSACTION_HANDLE_DATA*)malloc(sizeof(REPORTED_PROPERTIES_TRANSACTION_HANDLE_DATA));
+        if (result == NULL)
+        {
+            /*Codes_SRS_DATA_PUBLISHER_02_029: [ If any error occurs then DataPublisher_CreateTransaction_ReportedProperties shall fail and return NULL. ]*/
+            LogError("unable to malloc");
+            /*return as is */
+        }
+        else
+        {
+            result->value = VECTOR_create(sizeof(DATA_MARSHALLER_VALUE*));
+            if (result->value == NULL)
+            {
+                /*Codes_SRS_DATA_PUBLISHER_02_029: [ If any error occurs then DataPublisher_CreateTransaction_ReportedProperties shall fail and return NULL. ]*/
+                LogError("unable to VECTOR_create");
+                free(result);
+                result = NULL;
+            }
+            else
+            {
+                /*Codes_SRS_DATA_PUBLISHER_02_030: [ Otherwise DataPublisher_CreateTransaction_ReportedProperties shall succeed and return a non-NULL handle. ]*/
+                result->DataPublisherInstance = dataPublisherHandle;
+            }
+        }
+    }
+
+    return result;
+}
+
+static bool reportedPropertyExistsByPath(const void* element, const void* value)
+{
+    DATA_MARSHALLER_VALUE* dataMarshallerValue = *(DATA_MARSHALLER_VALUE**)element;
+    return (strcmp(dataMarshallerValue->PropertyPath, (const char*)value) == 0);
+}
+
+DATA_PUBLISHER_RESULT DataPublisher_PublishTransacted_ReportedProperty(REPORTED_PROPERTIES_TRANSACTION_HANDLE transactionHandle, const char* reportedPropertyPath, const AGENT_DATA_TYPE* data)
+{
+    DATA_PUBLISHER_RESULT result;
+    /*Codes_SRS_DATA_PUBLISHER_02_009: [ If argument transactionHandle is NULL then DataPublisher_PublishTransacted_ReportedProperty shall fail and return DATA_PUBLISHER_INVALID_ARG. ]*/
+    /*Codes_SRS_DATA_PUBLISHER_02_010: [ If argument reportedPropertyPath is NULL then DataPublisher_PublishTransacted_ReportedProperty shall fail and return DATA_PUBLISHER_INVALID_ARG. ]*/
+    /*Codes_SRS_DATA_PUBLISHER_02_011: [ If argument data is NULL then DataPublisher_PublishTransacted_ReportedProperty shall fail and return DATA_PUBLISHER_INVALID_ARG. ]*/
+    if (
+        (transactionHandle == NULL) ||
+        (reportedPropertyPath == NULL) ||
+        (data == NULL)
+        )
+    {
+        LogError("invalid argument REPORTED_PROPERTIES_TRANSACTION_HANDLE transactionHandle=%p, const char* reportedPropertyPath=%p, const AGENT_DATA_TYPE* data=%p", transactionHandle, reportedPropertyPath, data);
+        result = DATA_PUBLISHER_INVALID_ARG;
+    }
+    else
+    {
+        REPORTED_PROPERTIES_TRANSACTION_HANDLE_DATA* handleData = (REPORTED_PROPERTIES_TRANSACTION_HANDLE_DATA*)transactionHandle;
+        /*Codes_SRS_DATA_PUBLISHER_02_012: [ DataPublisher_PublishTransacted_ReportedProperty shall verify that a reported property having the path reportedPropertyPath exists in the model by calling Schema_ModelReportedPropertyByPathExists ]*/
+        if (!Schema_ModelReportedPropertyByPathExists(handleData->DataPublisherInstance->ModelHandle, reportedPropertyPath))
+        {
+            /*Codes_SRS_DATA_PUBLISHER_02_013: [ If a reported property with path reportedPropertyPath does not exist in the model then DataPublisher_PublishTransacted_ReportedProperty shall fail and return DATA_PUBLISHER_INVALID_ARG. ]*/
+            LogError("unable to find a reported property by path \"%s\"", reportedPropertyPath);
+            result = DATA_PUBLISHER_INVALID_ARG;
+        }
+        else
+        {
+            DATA_MARSHALLER_VALUE** existingValue = VECTOR_find_if(handleData->value, reportedPropertyExistsByPath, reportedPropertyPath);
+            if(existingValue != NULL)
+            {
+                /*Codes_SRS_DATA_PUBLISHER_02_014: [ If the same (by reportedPropertypath) reported property has already been added to the transaction, then DataPublisher_PublishTransacted_ReportedProperty shall overwrite the previous reported property. ]*/
+                AGENT_DATA_TYPE *clone = (AGENT_DATA_TYPE *)calloc(1, sizeof(AGENT_DATA_TYPE));
+                if(clone == NULL)
+                {
+                    /*Codes_SRS_DATA_PUBLISHER_02_016: [ If any error occurs then DataPublisher_PublishTransacted_ReportedProperty shall fail and return DATA_PUBLISHER_ERROR. ]*/
+                    LogError("unable to malloc");
+                    result = DATA_PUBLISHER_ERROR;
+                }
+                else
+                {
+                    if (Create_AGENT_DATA_TYPE_from_AGENT_DATA_TYPE(clone, data) != AGENT_DATA_TYPES_OK)
+                    {
+                        /*Codes_SRS_DATA_PUBLISHER_02_016: [ If any error occurs then DataPublisher_PublishTransacted_ReportedProperty shall fail and return DATA_PUBLISHER_ERROR. ]*/
+                        LogError("unable to Create_AGENT_DATA_TYPE_from_AGENT_DATA_TYPE");
+                        free(clone);
+                        result = DATA_PUBLISHER_ERROR;
+                    }
+                    else
+                    {
+                        /*Codes_SRS_DATA_PUBLISHER_02_017: [ Otherwise DataPublisher_PublishTransacted_ReportedProperty shall succeed and return DATA_PUBLISHER_OK. ]*/
+                        Destroy_AGENT_DATA_TYPE((AGENT_DATA_TYPE*)((*existingValue)->Value));
+                        free((void*)((*existingValue)->Value));
+                        (*existingValue)->Value = clone;
+                        result = DATA_PUBLISHER_OK;
+                    }
+                }
+            }
+            else
+            {
+                /*totally new reported property*/
+                DATA_MARSHALLER_VALUE* newValue = (DATA_MARSHALLER_VALUE*)malloc(sizeof(DATA_MARSHALLER_VALUE));
+                if (newValue == NULL)
+                {
+                    /*Codes_SRS_DATA_PUBLISHER_02_016: [ If any error occurs then DataPublisher_PublishTransacted_ReportedProperty shall fail and return DATA_PUBLISHER_ERROR. ]*/
+                    LogError("unable to malloc");
+                    result = DATA_PUBLISHER_ERROR;
+                }
+                else
+                {
+                    if (mallocAndStrcpy_s((char**)&(newValue->PropertyPath), reportedPropertyPath) != 0)
+                    {
+                        /*Codes_SRS_DATA_PUBLISHER_02_016: [ If any error occurs then DataPublisher_PublishTransacted_ReportedProperty shall fail and return DATA_PUBLISHER_ERROR. ]*/
+                        LogError("unable to mallocAndStrcpy_s");
+                        free(newValue);
+                        result = DATA_PUBLISHER_ERROR;
+                    }
+                    else
+                    {
+                        if ((newValue->Value = (AGENT_DATA_TYPE*)calloc(1, sizeof(AGENT_DATA_TYPE))) == NULL)
+                        {
+                            LogError("unable to malloc");
+                            free((void*)newValue->PropertyPath);
+                            free(newValue);
+                            result = DATA_PUBLISHER_ERROR;
+                        }
+                        else
+                        {
+                            if (Create_AGENT_DATA_TYPE_from_AGENT_DATA_TYPE((AGENT_DATA_TYPE*)newValue->Value, data) != AGENT_DATA_TYPES_OK)
+                            {
+                                /*Codes_SRS_DATA_PUBLISHER_02_016: [ If any error occurs then DataPublisher_PublishTransacted_ReportedProperty shall fail and return DATA_PUBLISHER_ERROR. ]*/
+                                LogError("unable to Create_AGENT_DATA_TYPE_from_AGENT_DATA_TYPE");
+                                free((void*)newValue->Value);
+                                free((void*)newValue->PropertyPath);
+                                free(newValue);
+                                result = DATA_PUBLISHER_ERROR;
+                            }
+                            else
+                            {
+                                /*Codes_SRS_DATA_PUBLISHER_02_015: [ DataPublisher_PublishTransacted_ReportedProperty shall add a new DATA_MARSHALLER_VALUE to the VECTOR_HANDLE. ]*/
+                                if (VECTOR_push_back(handleData->value, &newValue, 1) != 0)
+                                {
+                                    /*Codes_SRS_DATA_PUBLISHER_02_016: [ If any error occurs then DataPublisher_PublishTransacted_ReportedProperty shall fail and return DATA_PUBLISHER_ERROR. */
+                                    LogError("unable to VECTOR_push_back");
+                                    Destroy_AGENT_DATA_TYPE((AGENT_DATA_TYPE*)newValue->Value);
+                                    free((void*)newValue->Value);
+                                    free((void*)newValue->PropertyPath);
+                                    free(newValue);
+                                    result = DATA_PUBLISHER_ERROR;
+                                }
+                                else
+                                {
+                                    /*Codes_SRS_DATA_PUBLISHER_02_017: [ Otherwise DataPublisher_PublishTransacted_ReportedProperty shall succeed and return DATA_PUBLISHER_OK. ]*/
+                                    result = DATA_PUBLISHER_OK;
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+        }
+    }
+    return result;
+}
+
+DATA_PUBLISHER_RESULT DataPublisher_CommitTransaction_ReportedProperties(REPORTED_PROPERTIES_TRANSACTION_HANDLE transactionHandle, unsigned char** destination, size_t* destinationSize)
+{
+    DATA_PUBLISHER_RESULT result;
+    /*Codes_SRS_DATA_PUBLISHER_02_019: [ If argument transactionHandle is NULL then DataPublisher_CommitTransaction_ReportedProperties shall fail and return DATA_PUBLISHER_INVALID_ARG. ]*/
+    /*Codes_SRS_DATA_PUBLISHER_02_020: [ If argument destination is NULL then DataPublisher_CommitTransaction_ReportedProperties shall fail and return DATA_PUBLISHER_INVALID_ARG. ]*/
+    /*Codes_SRS_DATA_PUBLISHER_02_021: [ If argument destinationSize NULL then DataPublisher_CommitTransaction_ReportedProperties shall fail and return DATA_PUBLISHER_INVALID_ARG. ]*/
+    if (
+        (transactionHandle == NULL) ||
+        (destination == NULL) ||
+        (destinationSize == NULL)
+        )
+    {
+        LogError("invalid argument REPORTED_PROPERTIES_TRANSACTION_HANDLE transactionHandle=%p, unsigned char** destination=%p, size_t* destinationSize=%p", transactionHandle, destination, destinationSize);
+        result = DATA_PUBLISHER_INVALID_ARG;
+    }
+    else
+    {
+        /*Codes_SRS_DATA_PUBLISHER_02_031: [ If the transaction contains zero elements then DataPublisher_CommitTransaction_ReportedProperties shall fail and return DATA_PUBLISHER_INVALID_ARG. ]*/
+        REPORTED_PROPERTIES_TRANSACTION_HANDLE_DATA* handle = (REPORTED_PROPERTIES_TRANSACTION_HANDLE_DATA*)transactionHandle;
+        if (VECTOR_size(handle->value) == 0)
+        {
+            LogError("cannot commit empty transaction");
+            result = DATA_PUBLISHER_INVALID_ARG;
+        }
+        else
+        {
+            /*Codes_SRS_DATA_PUBLISHER_02_022: [ DataPublisher_CommitTransaction_ReportedProperties shall call DataMarshaller_SendData_ReportedProperties providing the VECTOR_HANDLE holding the transacted reported properties, destination and destinationSize. ]*/
+            if (DataMarshaller_SendData_ReportedProperties(handle->DataPublisherInstance->DataMarshallerHandle, handle->value, destination, destinationSize) != DATA_MARSHALLER_OK)
+            {
+                /*Codes_SRS_DATA_PUBLISHER_02_023: [ If any error occurs then DataPublisher_CommitTransaction_ReportedProperties shall fail and return DATA_PUBLISHER_ERROR. ]*/
+                LogError("unable to DataMarshaller_SendData_ReportedProperties");
+                result = DATA_PUBLISHER_ERROR;
+            }
+            else
+            {
+                /*Codes_SRS_DATA_PUBLISHER_02_024: [ Otherwise DataPublisher_CommitTransaction_ReportedProperties shall succeed and return DATA_PUBLISHER_OK. ]*/
+                result = DATA_PUBLISHER_OK;
+            }
+        }
+    }
+
+    return result;
+}
+
+void DataPublisher_DestroyTransaction_ReportedProperties(REPORTED_PROPERTIES_TRANSACTION_HANDLE transactionHandle)
+{
+    /*Codes_SRS_DATA_PUBLISHER_02_025: [ If argument transactionHandle is NULL then DataPublisher_DestroyTransaction_ReportedProperties shall return. ]*/
+    if (transactionHandle == NULL)
+    {
+        LogError("invalig argument REPORTED_PROPERTIES_TRANSACTION_HANDLE transactionHandle=%p", transactionHandle);
+    }
+    else
+    {
+        /*Codes_SRS_DATA_PUBLISHER_02_026: [ Otherwise DataPublisher_DestroyTransaction_ReportedProperties shall free all resources associated with the reported properties transactionHandle. ]*/
+        REPORTED_PROPERTIES_TRANSACTION_HANDLE_DATA* handleData = (REPORTED_PROPERTIES_TRANSACTION_HANDLE_DATA*)transactionHandle;
+        size_t i, nReportedProperties;
+        nReportedProperties = VECTOR_size(handleData->value);
+        for (i = 0;i < nReportedProperties;i++)
+        {
+            DATA_MARSHALLER_VALUE *value = *(DATA_MARSHALLER_VALUE**)VECTOR_element(handleData->value, i);
+            Destroy_AGENT_DATA_TYPE((AGENT_DATA_TYPE*)value->Value);
+            free((void*)value->Value);
+            free((void*)value->PropertyPath);
+            free((void*)value);
+        }
+        VECTOR_destroy(handleData->value);
+        free(handleData);
+    }
+    return;
+}
Index: azure_iot_hub_f767zi/trunk/azure_iot_sdk/serializer/src/dataserializer.c
===================================================================
--- azure_iot_hub_f767zi/trunk/azure_iot_sdk/serializer/src/dataserializer.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/azure_iot_sdk/serializer/src/dataserializer.c	(revision 457)
@@ -0,0 +1,58 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+#include "azure_c_shared_utility/gballoc.h"
+
+#include "dataserializer.h"
+#include "azure_c_shared_utility/xlogging.h"
+
+MU_DEFINE_ENUM_STRINGS_WITHOUT_INVALID(DATA_SERIALIZER_RESULT, DATA_SERIALIZER_RESULT_VALUES);
+
+BUFFER_HANDLE DataSerializer_Encode(MULTITREE_HANDLE multiTreeHandle, DATA_SERIALIZER_MULTITREE_TYPE dataType, DATA_SERIALIZER_ENCODE_FUNC encodeFunc)
+{
+    BUFFER_HANDLE pBuffer;
+
+    /* Codes_SRS_DATA_SERIALIZER_07_003: [NULL shall be returned when an invalid parameter is supplied.] */
+    if (multiTreeHandle == NULL || encodeFunc == NULL)
+    {
+        pBuffer = NULL;
+        LogError("(Error code: %s)", MU_ENUM_TO_STRING(DATA_SERIALIZER_RESULT, DATA_SERIALIZER_INVALID_ARG) );
+    }
+    else
+    {
+        /* Codes_SRS_DATA_SERIALIZER_07_009: [DataSerializer_Encode function shall call into the given DATA_SERIALIZER_ENCODE_FUNC callback with a valid BUFFER object and valid MULTITREE_HANDLE object.] */
+        pBuffer = encodeFunc(multiTreeHandle, dataType);
+        if (pBuffer == NULL)
+        {
+            /* Codes_SRS_DATA_SERIALIZER_07_010: [Upon a DATA_SERIALIZER_ENCODE_FUNC failure the DataSerializer_Encode function shall return NULL.] */
+            LogError("(Error code: %s)", MU_ENUM_TO_STRING(DATA_SERIALIZER_RESULT, DATA_SERIALIZER_ERROR) );
+        }
+    }
+    /* Codes_SRS_DATA_SERIALIZER_07_002: [DataSerializer_Encode shall return a valid BUFFER_HANDLE when the function executes successfully.] */
+    return pBuffer;
+}
+
+MULTITREE_HANDLE DataSerializer_Decode(BUFFER_HANDLE data, DATA_SERIALIZER_DECODE_FUNC decodeFunc)
+{
+    MULTITREE_HANDLE multiTreeHandle;
+
+    /* Codes_SRS_DATA_SERIALIZER_07_007: [NULL shall be returned when an invalid parameter is supplied.] */
+    if (data == NULL || decodeFunc == NULL)
+    {
+        multiTreeHandle = NULL;
+        LogError("(Error code: %s)", MU_ENUM_TO_STRING(DATA_SERIALIZER_RESULT, DATA_SERIALIZER_INVALID_ARG) );
+    }
+    else
+    {
+        /* Codes_SRS_DATA_SERIALIZER_07_012: [DataSerializer_Decode function shall call into the given DATA_SERIALIZER_DECODE_FUNC callback with a valid BUFFER object and valid MULTITREE_HANDLE object.] */
+        multiTreeHandle = decodeFunc(data);
+        if (multiTreeHandle == NULL)
+        {
+            /* Codes_SRS_DATA_SERIALIZER_07_013: [Upon a DATA_SERIALIZER_DECODE_FUNC callback failure the DataSerializer_Encode function Shall return NULL.] */
+            LogError("(Error code: %s)", MU_ENUM_TO_STRING(DATA_SERIALIZER_RESULT, DATA_SERIALIZER_ERROR) );
+        }
+    }
+
+    /* Codes_SRS_DATA_SERIALIZER_07_006: [DataSerializer_Decode shall return a valid MULTITREE_HANDLE when the function executes successfully.] */
+    return multiTreeHandle;
+}
Index: azure_iot_hub_f767zi/trunk/azure_iot_sdk/serializer/src/iotdevice.c
===================================================================
--- azure_iot_hub_f767zi/trunk/azure_iot_sdk/serializer/src/iotdevice.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/azure_iot_sdk/serializer/src/iotdevice.c	(revision 457)
@@ -0,0 +1,450 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+#include <stdlib.h>
+#include "azure_c_shared_utility/gballoc.h"
+
+#include <stdbool.h>
+#include "iotdevice.h"
+#include "datapublisher.h"
+#include "commanddecoder.h"
+#include "azure_c_shared_utility/crt_abstractions.h"
+#include "azure_c_shared_utility/xlogging.h"
+
+#define LOG_DEVICE_ERROR \
+    LogError("(result = %s)", MU_ENUM_TO_STRING(DEVICE_RESULT, result))
+
+
+
+typedef struct DEVICE_HANDLE_DATA_TAG
+{
+    SCHEMA_MODEL_TYPE_HANDLE model;
+    DATA_PUBLISHER_HANDLE dataPublisherHandle;
+    pfDeviceActionCallback deviceActionCallback;
+    void* callbackUserContext;
+    pfDeviceMethodCallback deviceMethodCallback;
+    void* methodCallbackUserContext;
+
+    COMMAND_DECODER_HANDLE commandDecoderHandle;
+} DEVICE_HANDLE_DATA;
+
+MU_DEFINE_ENUM_STRINGS_WITHOUT_INVALID(DEVICE_RESULT, DEVICE_RESULT_VALUES);
+
+static EXECUTE_COMMAND_RESULT DeviceInvokeAction(void* actionCallbackContext, const char* relativeActionPath, const char* actionName, size_t argCount, const AGENT_DATA_TYPE* args)
+{
+    EXECUTE_COMMAND_RESULT result;
+
+    /*Codes_SRS_DEVICE_02_011: [If the parameter actionCallbackContent passed the callback is NULL then the callback shall return EXECUTE_COMMAND_ERROR.] */
+    if (actionCallbackContext == NULL)
+    {
+        result = EXECUTE_COMMAND_ERROR;
+        LogError("(Error code = %s)", MU_ENUM_TO_STRING(DEVICE_RESULT, DEVICE_INVALID_ARG));
+    }
+    else
+    {
+        DEVICE_HANDLE_DATA* device = (DEVICE_HANDLE_DATA*)actionCallbackContext;
+
+        /* Codes_SRS_DEVICE_01_052: [When the action callback passed to CommandDecoder is called, Device shall call the appropriate user callback associated with the device handle.] */
+        /* Codes_SRS_DEVICE_01_055: [The value passed in callbackUserContext when creating the device shall be passed to the callback as the value for the callbackUserContext argument.] */
+        result = device->deviceActionCallback((DEVICE_HANDLE)device, device->callbackUserContext, relativeActionPath, actionName, argCount, args);
+    }
+
+    return result;
+}
+
+static METHODRETURN_HANDLE DeviceInvokeMethod(void* methodCallbackContext, const char* relativeMethodPath, const char* methodName, size_t argCount, const AGENT_DATA_TYPE* args)
+{
+    METHODRETURN_HANDLE result;
+
+    if (methodCallbackContext == NULL)
+    {
+        result = NULL;
+        LogError("(Error code = %s)", MU_ENUM_TO_STRING(DEVICE_RESULT, DEVICE_INVALID_ARG));
+    }
+    else
+    {
+        DEVICE_HANDLE_DATA* device = (DEVICE_HANDLE_DATA*)methodCallbackContext;
+
+        result = device->deviceMethodCallback((DEVICE_HANDLE)device, device->methodCallbackUserContext, relativeMethodPath, methodName, argCount, args);
+    }
+
+    return result;
+}
+
+DEVICE_RESULT Device_Create(SCHEMA_MODEL_TYPE_HANDLE modelHandle, pfDeviceActionCallback deviceActionCallback, void* callbackUserContext, pfDeviceMethodCallback methodCallback, void* methodCallbackContext, bool includePropertyPath, DEVICE_HANDLE* deviceHandle)
+{
+    DEVICE_RESULT result;
+
+    /* Codes_SRS_DEVICE_05_014: [If any of the modelHandle, deviceHandle or deviceActionCallback arguments are NULL, Device_Create shall return DEVICE_INVALID_ARG.]*/
+    if (modelHandle == NULL || deviceHandle == NULL || deviceActionCallback == NULL || methodCallback == NULL || methodCallbackContext == NULL)
+    {
+        result = DEVICE_INVALID_ARG;
+        LOG_DEVICE_ERROR;
+    }
+    else
+    {
+        DEVICE_HANDLE_DATA* device = (DEVICE_HANDLE_DATA*)malloc(sizeof(DEVICE_HANDLE_DATA));
+        if (device == NULL)
+        {
+            /* Codes_SRS_DEVICE_05_015: [If an error occurs while trying to create the device, Device_Create shall return DEVICE_ERROR.] */
+            result = DEVICE_ERROR;
+            LOG_DEVICE_ERROR;
+        }
+        else
+        {
+            /* Codes_SRS_DEVICE_01_018: [Device_Create shall create a DataPublisher instance by calling DataPublisher_Create.] */
+            /* Codes_SRS_DEVICE_01_020: [Device_Create shall pass to DataPublisher_Create the FrontDoor instance obtained earlier.] */
+            /* Codes_SRS_DEVICE_01_004: [DeviceCreate shall pass to DataPublisher_create the includePropertyPath argument.] */
+            if ((device->dataPublisherHandle = DataPublisher_Create(modelHandle, includePropertyPath)) == NULL)
+            {
+                free(device);
+
+                /* Codes_SRS_DEVICE_01_019: [If creating the DataPublisher instance fails, Device_Create shall return DEVICE_DATA_PUBLISHER_FAILED.] */
+                result = DEVICE_DATA_PUBLISHER_FAILED;
+                LOG_DEVICE_ERROR;
+            }
+            else
+            {
+                device->model = modelHandle;
+                device->deviceActionCallback = deviceActionCallback;
+                device->callbackUserContext = callbackUserContext;
+                device->deviceMethodCallback = methodCallback;
+                device->methodCallbackUserContext = methodCallbackContext;
+
+                /* Codes_SRS_DEVICE_01_001: [Device_Create shall create a CommandDecoder instance by calling CommandDecoder_Create and passing to it the model handle.] */
+                /* Codes_SRS_DEVICE_01_002: [Device_Create shall also pass to CommandDecoder_Create a callback to be invoked when a command is received and a context that shall be the device handle.] */
+                if ((device->commandDecoderHandle = CommandDecoder_Create(modelHandle, DeviceInvokeAction, device, DeviceInvokeMethod, device)) == NULL)
+                {
+                    DataPublisher_Destroy(device->dataPublisherHandle);
+                    free(device);
+
+                    /* Codes_SRS_DEVICE_01_003: [If CommandDecoder_Create fails, Device_Create shall return DEVICE_COMMAND_DECODER_FAILED.] */
+                    result = DEVICE_COMMAND_DECODER_FAILED;
+                    LOG_DEVICE_ERROR;
+                }
+                else
+                {
+                    /* Codes_SRS_DEVICE_03_003: [The DEVICE_HANDLE shall be provided via the deviceHandle out argument.] */
+                    *deviceHandle = (DEVICE_HANDLE)device;
+                    /* Codes_SRS_DEVICE_03_004: [Device_Create shall return DEVICE_OK upon success.] */
+                    result = DEVICE_OK;
+                }
+            }
+        }
+    }
+
+    return result;
+}
+
+/* Codes_SRS_DEVICE_03_006: [Device_Destroy shall free all resources associated with a device.] */
+void Device_Destroy(DEVICE_HANDLE deviceHandle)
+{
+    /* Codes_SRS_DEVICE_03_007: [Device_Destroy will not do anything if deviceHandle is NULL.] */
+    if (deviceHandle != NULL)
+    {
+        DEVICE_HANDLE_DATA* device = (DEVICE_HANDLE_DATA*)deviceHandle;
+
+        DataPublisher_Destroy(device->dataPublisherHandle);
+        CommandDecoder_Destroy(device->commandDecoderHandle);
+
+        free(device);
+    }
+}
+
+TRANSACTION_HANDLE Device_StartTransaction(DEVICE_HANDLE deviceHandle)
+{
+    TRANSACTION_HANDLE result;
+
+    /* Codes_SRS_DEVICE_01_035: [If any argument is NULL, Device_StartTransaction shall return NULL.] */
+    if (deviceHandle == NULL)
+    {
+        result = NULL;
+        LogError("(Error code = %s)", MU_ENUM_TO_STRING(DEVICE_RESULT, DEVICE_INVALID_ARG));
+    }
+    else
+    {
+        DEVICE_HANDLE_DATA* deviceInstance = (DEVICE_HANDLE_DATA*)deviceHandle;
+
+        /* Codes_SRS_DEVICE_01_034: [Device_StartTransaction shall invoke DataPublisher_StartTransaction for the DataPublisher handle associated with the deviceHandle argument.] */
+        /* Codes_SRS_DEVICE_01_043: [On success, Device_StartTransaction shall return a non NULL handle.] */
+        /* Codes_SRS_DEVICE_01_048: [When DataPublisher_StartTransaction fails, Device_StartTransaction shall return NULL.] */
+        result = DataPublisher_StartTransaction(deviceInstance->dataPublisherHandle);
+    }
+
+    return result;
+}
+
+DEVICE_RESULT Device_PublishTransacted(TRANSACTION_HANDLE transactionHandle, const char* propertyPath, const AGENT_DATA_TYPE* data)
+{
+    DEVICE_RESULT result;
+
+    /* Codes_SRS_DEVICE_01_037: [If any argument is NULL, Device_PublishTransacted shall return DEVICE_INVALID_ARG.] */
+    if (
+        (transactionHandle == NULL) ||
+        (propertyPath == NULL) ||
+        (data == NULL)
+       )
+    {
+        result = DEVICE_INVALID_ARG;
+        LOG_DEVICE_ERROR;
+    }
+    /* Codes_SRS_DEVICE_01_036: [Device_PublishTransacted shall invoke DataPublisher_PublishTransacted.] */
+    else if (DataPublisher_PublishTransacted(transactionHandle, propertyPath, data) != DATA_PUBLISHER_OK)
+    {
+        /* Codes_SRS_DEVICE_01_049: [When DataPublisher_PublishTransacted fails, Device_PublishTransacted shall return DEVICE_DATA_PUBLISHER_FAILED.] */
+        result = DEVICE_DATA_PUBLISHER_FAILED;
+        LOG_DEVICE_ERROR;
+    }
+    else
+    {
+        /* Codes_SRS_DEVICE_01_044: [On success, Device_PublishTransacted shall return DEVICE_OK.] */
+        result = DEVICE_OK;
+    }
+
+    return result;
+}
+
+DEVICE_RESULT Device_EndTransaction(TRANSACTION_HANDLE transactionHandle, unsigned char** destination, size_t* destinationSize)
+{
+    DEVICE_RESULT result;
+
+    /* Codes_SRS_DEVICE_01_039: [If any parameter is NULL, Device_EndTransaction shall return DEVICE_INVALID_ARG.]*/
+    if (
+        (transactionHandle == NULL) ||
+        (destination == NULL) ||
+        (destinationSize == NULL)
+        )
+    {
+        result = DEVICE_INVALID_ARG;
+        LOG_DEVICE_ERROR;
+    }
+    /* Codes_SRS_DEVICE_01_038: [Device_EndTransaction shall invoke DataPublisher_EndTransaction.] */
+    else if (DataPublisher_EndTransaction(transactionHandle, destination, destinationSize) != DATA_PUBLISHER_OK)
+    {
+        /* Codes_SRS_DEVICE_01_050: [When DataPublisher_EndTransaction fails, Device_EndTransaction shall return DEVICE_DATA_PUBLISHER_FAILED.] */
+        result = DEVICE_DATA_PUBLISHER_FAILED;
+        LOG_DEVICE_ERROR;
+    }
+    else
+    {
+        /* Codes_SRS_DEVICE_01_045: [On success, Device_EndTransaction shall return DEVICE_OK.] */
+        result = DEVICE_OK;
+    }
+
+    return result;
+}
+
+DEVICE_RESULT Device_CancelTransaction(TRANSACTION_HANDLE transactionHandle)
+{
+    DEVICE_RESULT result;
+
+    /* Codes_SRS_DEVICE_01_041: [If any argument is NULL, Device_CancelTransaction shall return DEVICE_INVALID_ARG.] */
+    if (transactionHandle == NULL)
+    {
+        result = DEVICE_INVALID_ARG;
+        LOG_DEVICE_ERROR;
+    }
+    /* Codes_SRS_DEVICE_01_040: [Device_CancelTransaction shall invoke DataPublisher_CancelTransaction.] */
+    else if (DataPublisher_CancelTransaction(transactionHandle) != DATA_PUBLISHER_OK)
+    {
+        /* Codes_SRS_DEVICE_01_051: [When DataPublisher_CancelTransaction fails, Device_CancelTransaction shall return DEVICE_DATA_PUBLISHER_FAILED.] */
+        result = DEVICE_DATA_PUBLISHER_FAILED;
+        LOG_DEVICE_ERROR;
+    }
+    else
+    {
+        /* Codes_SRS_DEVICE_01_046: [On success, Device_PublishTransacted shall return DEVICE_OK.] */
+        result = DEVICE_OK;
+    }
+
+    return result;
+}
+
+EXECUTE_COMMAND_RESULT Device_ExecuteCommand(DEVICE_HANDLE deviceHandle, const char* command)
+{
+    EXECUTE_COMMAND_RESULT result;
+    /*Codes_SRS_DEVICE_02_012: [If any parameters are NULL, then Device_ExecuteCommand shall return EXECUTE_COMMAND_ERROR.] */
+    if (
+        (deviceHandle == NULL) ||
+        (command == NULL)
+        )
+    {
+        result = EXECUTE_COMMAND_ERROR;
+        LogError("invalid parameter (NULL passed to Device_ExecuteCommand DEVICE_HANDLE deviceHandle=%p, const char* command=%p", deviceHandle, command);
+    }
+    else
+    {
+        /*Codes_SRS_DEVICE_02_013: [Otherwise, Device_ExecuteCommand shall call CommandDecoder_ExecuteCommand and return what CommandDecoder_ExecuteCommand is returning.] */
+        DEVICE_HANDLE_DATA* device = (DEVICE_HANDLE_DATA*)deviceHandle;
+        result = CommandDecoder_ExecuteCommand(device->commandDecoderHandle, command);
+    }
+    return result;
+}
+
+METHODRETURN_HANDLE Device_ExecuteMethod(DEVICE_HANDLE deviceHandle, const char* methodName, const char* methodPayload)
+{
+    METHODRETURN_HANDLE result;
+    if (
+        (deviceHandle == NULL) ||
+        (methodName == NULL) /*methodPayload can be NULL*/
+        )
+    {
+        result = NULL;
+        LogError("invalid parameter (NULL passed to Device_ExecuteMethod DEVICE_HANDLE deviceHandle=%p, const char* methodPayload=%p", deviceHandle, methodPayload);
+    }
+    else
+    {
+        DEVICE_HANDLE_DATA* device = (DEVICE_HANDLE_DATA*)deviceHandle;
+        result = CommandDecoder_ExecuteMethod(device->commandDecoderHandle, methodName, methodPayload);
+    }
+    return result;
+}
+
+REPORTED_PROPERTIES_TRANSACTION_HANDLE Device_CreateTransaction_ReportedProperties(DEVICE_HANDLE deviceHandle)
+{
+    REPORTED_PROPERTIES_TRANSACTION_HANDLE result;
+
+    /*Codes_SRS_DEVICE_02_014: [ If argument deviceHandle is NULL then Device_CreateTransaction_ReportedProperties shall fail and return NULL. ]*/
+    if (deviceHandle == NULL)
+    {
+        LogError("invalid argument DEVICE_HANDLE deviceHandle=%p", deviceHandle);
+        result = NULL;
+    }
+    else
+    {
+        DEVICE_HANDLE_DATA* deviceInstance = (DEVICE_HANDLE_DATA*)deviceHandle;
+        /*Codes_SRS_DEVICE_02_015: [ Otherwise, Device_CreateTransaction_ReportedProperties shall call DataPublisher_CreateTransaction_ReportedProperties. ]*/
+        /*Codes_SRS_DEVICE_02_016: [ If DataPublisher_CreateTransaction_ReportedProperties fails then Device_CreateTransaction_ReportedProperties shall fail and return NULL. ]*/
+        /*Codes_SRS_DEVICE_02_017: [ Otherwise Device_CreateTransaction_ReportedProperties shall succeed and return a non-NULL value. ]*/
+        result = DataPublisher_CreateTransaction_ReportedProperties(deviceInstance->dataPublisherHandle);
+        if (result == NULL)
+        {
+            LogError("unable to DataPublisher_CreateTransaction_ReportedProperties");
+            /*return as is*/
+        }
+        else
+        {
+            /*return as is*/
+        }
+    }
+
+    return result;
+}
+
+DEVICE_RESULT Device_PublishTransacted_ReportedProperty(REPORTED_PROPERTIES_TRANSACTION_HANDLE transactionHandle, const char* reportedPropertyPath, const AGENT_DATA_TYPE* data)
+{
+    DEVICE_RESULT result;
+    /*Codes_SRS_DEVICE_02_018: [ If argument transactionHandle is NULL then Device_PublishTransacted_ReportedProperty shall fail and return DEVICE_INVALID_ARG. ]*/
+    /*Codes_SRS_DEVICE_02_019: [ If argument reportedPropertyPath is NULL then Device_PublishTransacted_ReportedProperty shall fail and return DEVICE_INVALID_ARG. ]*/
+    /*Codes_SRS_DEVICE_02_020: [ If argument data is NULL then Device_PublishTransacted_ReportedProperty shall fail and return DEVICE_INVALID_ARG. ]*/
+    if (
+        (transactionHandle == NULL) ||
+        (reportedPropertyPath == NULL) ||
+        (data == NULL)
+        )
+    {
+        LogError("invalid argument REPORTED_PROPERTIES_TRANSACTION_HANDLE transactionHandle=%p, const char* reportedPropertyPath=%s, const AGENT_DATA_TYPE* data=%p", transactionHandle, reportedPropertyPath, data);
+        result = DEVICE_INVALID_ARG;
+    }
+    else
+    {
+        /*Codes_SRS_DEVICE_02_021: [ Device_PublishTransacted_ReportedProperty shall call DataPublisher_PublishTransacted_ReportedProperty. ]*/
+        DATA_PUBLISHER_RESULT r = DataPublisher_PublishTransacted_ReportedProperty(transactionHandle, reportedPropertyPath, data);
+        if (r != DATA_PUBLISHER_OK)
+        {
+            LogError("unable to DataPublisher_PublishTransacted_ReportedProperty");
+            /*Codes_SRS_DEVICE_02_022: [ If DataPublisher_PublishTransacted_ReportedProperty fails then Device_PublishTransacted_ReportedProperty shall fail and return DEVICE_DATA_PUBLISHER_FAILED. ]*/
+            result = DEVICE_DATA_PUBLISHER_FAILED;
+        }
+        else
+        {
+            /*Codes_SRS_DEVICE_02_023: [ Otherwise, Device_PublishTransacted_ReportedProperty shall succeed and return DEVICE_OK. ]*/
+            result = DEVICE_OK;
+        }
+    }
+    return result;
+}
+
+DEVICE_RESULT Device_CommitTransaction_ReportedProperties(REPORTED_PROPERTIES_TRANSACTION_HANDLE transactionHandle, unsigned char** destination, size_t* destinationSize)
+{
+    DEVICE_RESULT result;
+
+    /*Codes_SRS_DEVICE_02_024: [ If argument transactionHandle is NULL then Device_CommitTransaction_ReportedProperties shall fail and return DEVICE_INVALID_ARG. ]*/
+    /*Codes_SRS_DEVICE_02_025: [ If argument destination is NULL then Device_CommitTransaction_ReportedProperties shall fail and return DEVICE_INVALID_ARG. ]*/
+    /*Codes_SRS_DEVICE_02_026: [ If argument destinationSize is NULL then Device_CommitTransaction_ReportedProperties shall fail and return DEVICE_INVALID_ARG. ]*/
+    if (
+        (transactionHandle == NULL) ||
+        (destination == NULL) ||
+        (destinationSize == NULL)
+        )
+    {
+        LogError("invalid argument REPORTED_PROPERTIES_TRANSACTION_HANDLE transactionHandle=%p, unsigned char** destination=%p, size_t* destinationSize=%p", transactionHandle, destination, destinationSize);
+        result = DEVICE_INVALID_ARG;
+    }
+    else
+    {
+        /*Codes_SRS_DEVICE_02_027: [ Device_CommitTransaction_ReportedProperties shall call DataPublisher_CommitTransaction_ReportedProperties. ]*/
+        DATA_PUBLISHER_RESULT r = DataPublisher_CommitTransaction_ReportedProperties(transactionHandle, destination, destinationSize);
+
+        /*Codes_SRS_DEVICE_02_028: [ If DataPublisher_CommitTransaction_ReportedProperties fails then Device_CommitTransaction_ReportedProperties shall fail and return DEVICE_DATA_PUBLISHER_FAILED. ]*/
+        if (r != DATA_PUBLISHER_OK)
+        {
+            LogError("unable to DataPublisher_CommitTransaction_ReportedProperties");
+            result = DEVICE_DATA_PUBLISHER_FAILED;
+        }
+        else
+        {
+            /*Codes_SRS_DEVICE_02_029: [ Otherwise Device_CommitTransaction_ReportedProperties shall succeed and return DEVICE_OK. ]*/
+            result = DEVICE_OK;
+        }
+    }
+    return result;
+}
+
+void Device_DestroyTransaction_ReportedProperties(REPORTED_PROPERTIES_TRANSACTION_HANDLE transactionHandle)
+{
+    /*Codes_SRS_DEVICE_02_030: [ If argument transactionHandle is NULL then Device_DestroyTransaction_ReportedProperties shall return. ]*/
+    if (transactionHandle == NULL)
+    {
+        LogError("invalid argument REPORTED_PROPERTIES_TRANSACTION_HANDLE transactionHandle=%p", transactionHandle);
+    }
+    else
+    {
+        /*Codes_SRS_DEVICE_02_031: [ Otherwise Device_DestroyTransaction_ReportedProperties shall free all used resources. ]*/
+        DataPublisher_DestroyTransaction_ReportedProperties(transactionHandle);
+    }
+}
+
+DEVICE_RESULT Device_IngestDesiredProperties(void* startAddress, DEVICE_HANDLE deviceHandle, const char* jsonPayload, bool parseDesiredNode)
+{
+    DEVICE_RESULT result;
+    /*Codes_SRS_DEVICE_02_032: [ If deviceHandle is NULL then Device_IngestDesiredProperties shall fail and return DEVICE_INVALID_ARG. ]*/
+    /*Codes_SRS_DEVICE_02_033: [ If jsonPayload is NULL then Device_IngestDesiredProperties shall fail and return DEVICE_INVALID_ARG. ]*/
+    /*Codes_SRS_DEVICE_02_037: [ If startAddress is NULL then Device_IngestDesiredProperties shall fail and return DEVICE_INVALID_ARG. ]*/
+    if (
+        (deviceHandle == NULL) ||
+        (jsonPayload == NULL) ||
+        (startAddress == NULL)
+        )
+    {
+        LogError("invalid argument void* startAddress=%p, DEVICE_HANDLE deviceHandle=%p, const char* jsonPayload=%p\n", startAddress, deviceHandle, jsonPayload);
+        result = DEVICE_INVALID_ARG;
+    }
+    else
+    {
+        /*Codes_SRS_DEVICE_02_034: [ Device_IngestDesiredProperties shall call CommandDecoder_IngestDesiredProperties. ]*/
+        DEVICE_HANDLE_DATA* device = (DEVICE_HANDLE_DATA*)deviceHandle;
+        if (CommandDecoder_IngestDesiredProperties(startAddress, device->commandDecoderHandle, jsonPayload, parseDesiredNode) != EXECUTE_COMMAND_SUCCESS)
+        {
+            /*Codes_SRS_DEVICE_02_035: [ If any failure happens then Device_IngestDesiredProperties shall fail and return DEVICE_ERROR. ]*/
+            LogError("failure in CommandDecoder_IngestDesiredProperties");
+            result = DEVICE_ERROR;
+        }
+        else
+        {
+            /*Codes_SRS_DEVICE_02_036: [ Otherwise, Device_IngestDesiredProperties shall succeed and return DEVICE_OK. ]*/
+            result = DEVICE_OK;
+        }
+    }
+    return result;
+}
Index: azure_iot_hub_f767zi/trunk/azure_iot_sdk/serializer/src/jsondecoder.c
===================================================================
--- azure_iot_hub_f767zi/trunk/azure_iot_sdk/serializer/src/jsondecoder.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/azure_iot_sdk/serializer/src/jsondecoder.c	(revision 457)
@@ -0,0 +1,611 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+#include "azure_c_shared_utility/gballoc.h"
+#include "azure_c_shared_utility/crt_abstractions.h"
+
+#include "jsondecoder.h"
+#include <stdio.h>
+#include <string.h>
+#include <ctype.h>
+#include <stddef.h>
+
+#define IsWhiteSpace(A) (((A) == 0x20) || ((A) == 0x09) || ((A) == 0x0A) || ((A) == 0x0D))
+
+typedef struct PARSER_STATE_TAG
+{
+    char* json;
+} PARSER_STATE;
+
+static JSON_DECODER_RESULT ParseArray(PARSER_STATE* parserState, MULTITREE_HANDLE currentNode);
+static JSON_DECODER_RESULT ParseObject(PARSER_STATE* parserState, MULTITREE_HANDLE currentNode);
+
+/* Codes_SRS_JSON_DECODER_99_049:[ JSONDecoder shall not allocate new string values for the leafs, but rather point to strings in the original JSON.] */
+static void NoFreeFunction(void* value)
+{
+    (void)value;
+}
+
+static int NOPCloneFunction(void** destination, const void* source)
+{
+    *destination = (void**)source;
+    return 0;
+}
+
+void SkipWhiteSpaces(PARSER_STATE* parserState)
+{
+    while ((*(parserState->json) != '\0') && IsWhiteSpace(*(parserState->json)))
+    {
+        parserState->json++;
+    }
+}
+
+static JSON_DECODER_RESULT ParseString(PARSER_STATE* parserState, char** stringBegin)
+{
+    JSON_DECODER_RESULT result = JSON_DECODER_OK;
+    *stringBegin = parserState->json;
+
+    /* Codes_SRS_JSON_DECODER_99_028:[ A string begins and ends with quotation marks.] */
+    if (*(parserState->json) != '"')
+    {
+        /* Codes_SRS_JSON_DECODER_99_007:[ If parsing the JSON fails due to the JSON string being malformed, JSONDecoder_JSON_To_MultiTree shall return JSON_DECODER_PARSE_ERROR.] */
+        result = JSON_DECODER_PARSE_ERROR;
+    }
+    else
+    {
+        parserState->json++;
+        while ((*(parserState->json) != '"') && (*(parserState->json) != '\0'))
+        {
+            /* Codes_SRS_JSON_DECODER_99_030:[ Any character may be escaped.]  */
+            /* Codes_SRS_JSON_DECODER_99_033:[ Alternatively, there are two-character sequence escape  representations of some popular characters.  So, for example, a string containing only a single reverse solidus character may be represented more compactly as "\\".] */
+            if (*(parserState->json) == '\\')
+            {
+                parserState->json++;
+                if (
+                    /* Codes_SRS_JSON_DECODER_99_051:[ %x5C /          ; \    reverse solidus U+005C] */
+                    (*parserState->json == '\\') ||
+                    /* Codes_SRS_JSON_DECODER_99_050:[ %x22 /          ; "    quotation mark  U+0022] */
+                    (*parserState->json == '"') ||
+                    /* Codes_SRS_JSON_DECODER_99_052:[ %x2F /          ; /    solidus         U+002F] */
+                    (*parserState->json == '/') ||
+                    /* Codes_SRS_JSON_DECODER_99_053:[ %x62 /          ; b    backspace       U+0008] */
+                    (*parserState->json == 'b') ||
+                    /* Codes_SRS_JSON_DECODER_99_054:[ %x66 /          ; f    form feed       U+000C] */
+                    (*parserState->json == 'f') ||
+                    /* Codes_SRS_JSON_DECODER_99_055:[ %x6E /          ; n    line feed       U+000A] */
+                    (*parserState->json == 'n') ||
+                    /* Codes_SRS_JSON_DECODER_99_056:[ %x72 /          ; r    carriage return U+000D] */
+                    (*parserState->json == 'r') ||
+                    /* Codes_SRS_JSON_DECODER_99_057:[ %x74 /          ; t    tab             U+0009] */
+                    (*parserState->json == 't'))
+                {
+                    parserState->json++;
+                }
+                else
+                {
+                    /* Codes_SRS_JSON_DECODER_99_007:[ If parsing the JSON fails due to the JSON string being malformed, JSONDecoder_JSON_To_MultiTree shall return JSON_DECODER_PARSE_ERROR.] */
+                    result = JSON_DECODER_PARSE_ERROR;
+                    break;
+                }
+            }
+            else
+            {
+                parserState->json++;
+            }
+        }
+
+        if (*(parserState->json) != '"')
+        {
+            /* Codes_SRS_JSON_DECODER_99_007:[ If parsing the JSON fails due to the JSON string being malformed, JSONDecoder_JSON_To_MultiTree shall return JSON_DECODER_PARSE_ERROR.] */
+            result = JSON_DECODER_PARSE_ERROR;
+        }
+        else
+        {
+            parserState->json++;
+            result = JSON_DECODER_OK;
+        }
+    }
+
+    return result;
+}
+
+static JSON_DECODER_RESULT ParseNumber(PARSER_STATE* parserState)
+{
+    JSON_DECODER_RESULT result = JSON_DECODER_OK;
+    size_t digitCount = 0;
+
+    if (*(parserState->json) == '-')
+    {
+        parserState->json++;
+    }
+
+    /* Codes_SRS_JSON_DECODER_99_043:[ A number contains an integer component that may be prefixed with an optional minus sign, which may be followed by a fraction part and/or an exponent part.] */
+    while (*(parserState->json) != '\0')
+    {
+        /* Codes_SRS_JSON_DECODER_99_044:[ Octal and hex forms are not allowed.] */
+        if (ISDIGIT(*(parserState->json)))
+        {
+            digitCount++;
+            /* simply continue */
+        }
+        else
+        {
+            break;
+        }
+
+        parserState->json++;
+    }
+
+    if ((digitCount == 0) ||
+        /* Codes_SRS_JSON_DECODER_99_045:[ Leading zeros are not allowed.] */
+        ((digitCount > 1) && *(parserState->json - digitCount) == '0'))
+    {
+        /* Codes_SRS_JSON_DECODER_99_007:[ If parsing the JSON fails due to the JSON string being malformed, JSONDecoder_JSON_To_MultiTree shall return JSON_DECODER_PARSE_ERROR.] */
+        result = JSON_DECODER_PARSE_ERROR;
+    }
+    else
+    {
+        /* Codes_SRS_JSON_DECODER_99_046:[ A fraction part is a decimal point followed by one or more digits.] */
+        if (*(parserState->json) == '.')
+        {
+            /* optional fractional part */
+            parserState->json++;
+            digitCount = 0;
+
+            while (*(parserState->json) != '\0')
+            {
+                /* Codes_SRS_JSON_DECODER_99_044:[ Octal and hex forms are not allowed.] */
+                if (ISDIGIT(*(parserState->json)))
+                {
+                    digitCount++;
+                    /* simply continue */
+                }
+                else
+                {
+                    break;
+                }
+
+                parserState->json++;
+            }
+
+            if (digitCount == 0)
+            {
+                /* Codes_SRS_JSON_DECODER_99_007:[ If parsing the JSON fails due to the JSON string being malformed, JSONDecoder_JSON_To_MultiTree shall return JSON_DECODER_PARSE_ERROR.] */
+                result = JSON_DECODER_PARSE_ERROR;
+            }
+        }
+
+        /* Codes_SRS_JSON_DECODER_99_047:[ An exponent part begins with the letter E in upper or lowercase, which may be followed by a plus or minus sign.] */
+        if ((*(parserState->json) == 'e') || (*(parserState->json) == 'E'))
+        {
+            parserState->json++;
+
+            /* optional sign */
+            if ((*(parserState->json) == '-') || (*(parserState->json) == '+'))
+            {
+                parserState->json++;
+            }
+
+            digitCount = 0;
+
+            /* Codes_SRS_JSON_DECODER_99_048:[ The E and optional sign are followed by one or more digits.] */
+            while (*(parserState->json) != '\0')
+            {
+                /* Codes_SRS_JSON_DECODER_99_044:[ Octal and hex forms are not allowed.] */
+                if (ISDIGIT(*(parserState->json)))
+                {
+                    digitCount++;
+                    /* simply continue */
+                }
+                else
+                {
+                    break;
+                }
+
+                parserState->json++;
+            }
+
+            if (digitCount == 0)
+            {
+                /* Codes_SRS_JSON_DECODER_99_007:[ If parsing the JSON fails due to the JSON string being malformed, JSONDecoder_JSON_To_MultiTree shall return JSON_DECODER_PARSE_ERROR.] */
+                result = JSON_DECODER_PARSE_ERROR;
+            }
+        }
+    }
+
+    return result;
+}
+
+static JSON_DECODER_RESULT ParseValue(PARSER_STATE* parserState, MULTITREE_HANDLE currentNode, char** stringBegin)
+{
+    JSON_DECODER_RESULT result;
+
+    SkipWhiteSpaces(parserState);
+
+    if (*(parserState->json) == '"')
+    {
+        result = ParseString(parserState, stringBegin);
+    }
+    /* Codes_SRS_JSON_DECODER_99_018:[ A JSON value MUST be an object, array, number, or string, or one of the following three literal names: false null true] */
+    /* Codes_SRS_JSON_DECODER_99_019:[ The literal names MUST be lowercase.] */
+    /* Codes_SRS_JSON_DECODER_99_020:[ No other literal names are allowed.] */
+    else if (strncmp(parserState->json, "false", 5) == 0)
+    {
+        *stringBegin = parserState->json;
+        parserState->json += 5;
+        result = JSON_DECODER_OK;
+    }
+    else if (strncmp(parserState->json, "true", 4) == 0)
+    {
+        *stringBegin = parserState->json;
+        parserState->json += 4;
+        result = JSON_DECODER_OK;
+    }
+    else if (strncmp(parserState->json, "null", 4) == 0)
+    {
+        *stringBegin = parserState->json;
+        parserState->json += 4;
+        result = JSON_DECODER_OK;
+    }
+    /* Tests_SRS_JSON_DECODER_99_018:[ A JSON value MUST be an object, array, number, or string, or one of the following three literal names: false null true] */
+    else if (*(parserState->json) == '[')
+    {
+        result = ParseArray(parserState, currentNode);
+        *stringBegin = NULL;
+    }
+    else if (*(parserState->json) == '{')
+    {
+        result = ParseObject(parserState, currentNode);
+        *stringBegin = NULL;
+    }
+    else if (
+        (
+            ISDIGIT(*(parserState->json))
+        )
+        || (*(parserState->json) == '-'))
+    {
+        *stringBegin = parserState->json;
+        result = ParseNumber(parserState);
+    }
+    else
+    {
+        /* Codes_SRS_JSON_DECODER_99_007:[ If parsing the JSON fails due to the JSON string being malformed, JSONDecoder_JSON_To_MultiTree shall return JSON_DECODER_PARSE_ERROR.] */
+        result = JSON_DECODER_PARSE_ERROR;
+    }
+
+    return result;
+}
+
+static JSON_DECODER_RESULT ParseColon(PARSER_STATE* parserState)
+{
+    JSON_DECODER_RESULT result;
+
+    SkipWhiteSpaces(parserState);
+    /* Codes_SRS_JSON_DECODER_99_023:[  A single colon comes after each name, separating the name from the value.] */
+    if (*(parserState->json) != ':')
+    {
+        /* Codes_SRS_JSON_DECODER_99_007:[ If parsing the JSON fails due to the JSON string being malformed, JSONDecoder_JSON_To_MultiTree shall return JSON_DECODER_PARSE_ERROR.] */
+        result = JSON_DECODER_PARSE_ERROR;
+    }
+    else
+    {
+        parserState->json++;
+        result = JSON_DECODER_OK;
+    }
+
+    return result;
+}
+
+static JSON_DECODER_RESULT ParseOpenCurly(PARSER_STATE* parserState)
+{
+    JSON_DECODER_RESULT result = JSON_DECODER_OK;
+
+    SkipWhiteSpaces(parserState);
+
+    /* Codes_SRS_JSON_DECODER_99_021:[    An object structure is represented as a pair of curly brackets surrounding zero or more name/value pairs (or members).] */
+    if (*(parserState->json) != '{')
+    {
+        /* Codes_SRS_JSON_DECODER_99_007:[ If parsing the JSON fails due to the JSON string being malformed, JSONDecoder_JSON_To_MultiTree shall return JSON_DECODER_PARSE_ERROR.] */
+        result = JSON_DECODER_PARSE_ERROR;
+    }
+    else
+    {
+        parserState->json++;
+        result = JSON_DECODER_OK;
+    }
+
+    return result;
+}
+
+static JSON_DECODER_RESULT ParseNameValuePair(PARSER_STATE* parserState, MULTITREE_HANDLE currentNode)
+{
+    JSON_DECODER_RESULT result;
+    char* memberNameBegin;
+
+    SkipWhiteSpaces(parserState);
+
+    /* Codes_SRS_JSON_DECODER_99_022:[ A name is a string.] */
+    result = ParseString(parserState, &memberNameBegin);
+    if (result == JSON_DECODER_OK)
+    {
+        char* valueBegin;
+        MULTITREE_HANDLE childNode;
+        *(parserState->json - 1) = 0;
+
+        result = ParseColon(parserState);
+        if (result == JSON_DECODER_OK)
+        {
+            /* Codes_SRS_JSON_DECODER_99_025:[ The names within an object SHOULD be unique.] */
+            /* Multi Tree takes care of not having 2 children with the same name */
+            /* Codes_SRS_JSON_DECODER_99_002:[ JSONDecoder_JSON_To_MultiTree shall use the MultiTree APIs to create the multi tree and add leafs to the multi tree.] */
+            /* Codes_SRS_JSON_DECODER_99_003:[ When a JSON element is decoded from the JSON object then a leaf shall be added to the MultiTree.] */
+            /* Codes_SRS_JSON_DECODER_99_004:[ The leaf node name in the multi tree shall be the JSON element name.] */
+            if (MultiTree_AddChild(currentNode, memberNameBegin + 1, &childNode) != MULTITREE_OK)
+            {
+                /* Codes_SRS_JSON_DECODER_99_038:[ If any MultiTree API fails, JSONDecoder_JSON_To_MultiTree shall return JSON_DECODER_MULTITREE_FAILED.] */
+                result = JSON_DECODER_MULTITREE_FAILED;
+            }
+            else
+            {
+                result = ParseValue(parserState, childNode, &valueBegin);
+                if ((result == JSON_DECODER_OK) && (valueBegin != NULL))
+                {
+                    /* Codes_SRS_JSON_DECODER_99_005:[ The leaf node added in the multi tree shall have the value the string value of the JSON element as parsed from the JSON object.] */
+                    if (MultiTree_SetValue(childNode, valueBegin) != MULTITREE_OK)
+                    {
+                        /* Codes_SRS_JSON_DECODER_99_038:[ If any MultiTree API fails, JSONDecoder_JSON_To_MultiTree shall return JSON_DECODER_MULTITREE_FAILED.] */
+                        result = JSON_DECODER_MULTITREE_FAILED;
+                    }
+                }
+            }
+        }
+    }
+
+    return result;
+}
+
+static JSON_DECODER_RESULT ParseObject(PARSER_STATE* parserState, MULTITREE_HANDLE currentNode)
+{
+    JSON_DECODER_RESULT result = ParseOpenCurly(parserState);
+    if (result == JSON_DECODER_OK)
+    {
+        char jsonChar;
+
+        SkipWhiteSpaces(parserState);
+
+        jsonChar = *(parserState->json);
+        while ((jsonChar != '}') && (jsonChar != '\0'))
+        {
+            char* valueEnd;
+
+            /* decode each value */
+            result = ParseNameValuePair(parserState, currentNode);
+            if (result != JSON_DECODER_OK)
+            {
+                break;
+            }
+
+            valueEnd = parserState->json;
+
+            SkipWhiteSpaces(parserState);
+            jsonChar = *(parserState->json);
+            *valueEnd = 0;
+
+            /* Codes_SRS_JSON_DECODER_99_024:[ A single comma separates a value from a following name.] */
+            if (jsonChar == ',')
+            {
+                parserState->json++;
+                /* get the next name/value pair */
+            }
+        }
+
+        if (result != JSON_DECODER_OK)
+        {
+            /* already have error */
+        }
+        else
+        {
+            if (jsonChar != '}')
+            {
+                /* Codes_SRS_JSON_DECODER_99_007:[ If parsing the JSON fails due to the JSON string being malformed, JSONDecoder_JSON_To_MultiTree shall return JSON_DECODER_PARSE_ERROR.] */
+                result = JSON_DECODER_PARSE_ERROR;
+            }
+            else
+            {
+                parserState->json++;
+            }
+        }
+    }
+
+    return result;
+}
+
+static JSON_DECODER_RESULT ParseArray(PARSER_STATE* parserState, MULTITREE_HANDLE currentNode)
+{
+    JSON_DECODER_RESULT result = JSON_DECODER_OK;
+
+    SkipWhiteSpaces(parserState);
+
+    /* Codes_SRS_JSON_DECODER_99_026:[ An array structure is represented as square brackets surrounding zero or more values (or elements).] */
+    if (*(parserState->json) != '[')
+    {
+        /* Codes_SRS_JSON_DECODER_99_007:[ If parsing the JSON fails due to the JSON string being malformed, JSONDecoder_JSON_To_MultiTree shall return JSON_DECODER_PARSE_ERROR.] */
+        result = JSON_DECODER_PARSE_ERROR;
+    }
+    else
+    {
+        char* stringBegin;
+        char jsonChar;
+        int arrayIndex = 0;
+        result = JSON_DECODER_OK;
+
+        parserState->json++;
+
+        SkipWhiteSpaces(parserState);
+
+        jsonChar = *parserState->json;
+        while ((jsonChar != ']') && (jsonChar != '\0'))
+        {
+            char arrayIndexStr[22];
+            MULTITREE_HANDLE childNode;
+
+            /* Codes_SRS_JSON_DECODER_99_039:[ For array elements the multi tree node name shall be the string representation of the array index.] */
+            if (sprintf(arrayIndexStr, "%d", arrayIndex++) < 0)
+            {
+                result = JSON_DECODER_ERROR;
+                break;
+            }
+            /* Codes_SRS_JSON_DECODER_99_003:[ When a JSON element is decoded from the JSON object then a leaf shall be added to the MultiTree.] */
+            else if (MultiTree_AddChild(currentNode, arrayIndexStr, &childNode) != MULTITREE_OK)
+            {
+                /* Codes_SRS_JSON_DECODER_99_038:[ If any MultiTree API fails, JSONDecoder_JSON_To_MultiTree shall return JSON_DECODER_MULTITREE_FAILED.] */
+                result = JSON_DECODER_MULTITREE_FAILED;
+            }
+            else
+            {
+                char* valueEnd;
+
+                /* decode each value */
+                result = ParseValue(parserState, childNode, &stringBegin);
+                if (result != JSON_DECODER_OK)
+                {
+                    break;
+                }
+
+                if (stringBegin != NULL)
+                {
+                    /* Codes_SRS_JSON_DECODER_99_005:[ The leaf node added in the multi tree shall have the value the string value of the JSON element as parsed from the JSON object.] */
+                    if (MultiTree_SetValue(childNode, stringBegin) != MULTITREE_OK)
+                    {
+                        /* Codes_SRS_JSON_DECODER_99_038:[ If any MultiTree API fails, JSONDecoder_JSON_To_MultiTree shall return JSON_DECODER_MULTITREE_FAILED.] */
+                        result = JSON_DECODER_MULTITREE_FAILED;
+                        break;
+                    }
+                }
+
+                valueEnd = parserState->json;
+
+                SkipWhiteSpaces(parserState);
+                jsonChar = *(parserState->json);
+                *valueEnd = 0;
+
+                /* Codes_SRS_JSON_DECODER_99_027:[ Elements are separated by commas.] */
+                if (jsonChar == ',')
+                {
+                    parserState->json++;
+                    /* get the next value pair */
+                }
+                else if (jsonChar == ']')
+                {
+                    break;
+                }
+                else
+                {
+                    /* Codes_SRS_JSON_DECODER_99_007:[ If parsing the JSON fails due to the JSON string being malformed, JSONDecoder_JSON_To_MultiTree shall return JSON_DECODER_PARSE_ERROR.] */
+                    result = JSON_DECODER_PARSE_ERROR;
+                    break;
+                }
+            }
+        }
+
+        if (result != JSON_DECODER_OK)
+        {
+            /* already have error */
+        }
+        else
+        {
+            if (jsonChar != ']')
+            {
+                /* Codes_SRS_JSON_DECODER_99_007:[ If parsing the JSON fails due to the JSON string being malformed, JSONDecoder_JSON_To_MultiTree shall return JSON_DECODER_PARSE_ERROR.] */
+                result = JSON_DECODER_PARSE_ERROR;
+            }
+            else
+            {
+                parserState->json++;
+                SkipWhiteSpaces(parserState);
+            }
+        }
+    }
+
+    return result;
+}
+
+/* Codes_SRS_JSON_DECODER_99_012:[ A JSON text is a serialized object or array.] */
+static JSON_DECODER_RESULT ParseObjectOrArray(PARSER_STATE* parserState, MULTITREE_HANDLE currentNode)
+{
+    JSON_DECODER_RESULT result = JSON_DECODER_PARSE_ERROR;
+
+    SkipWhiteSpaces(parserState);
+
+    if (*(parserState->json) == '{')
+    {
+        result = ParseObject(parserState, currentNode);
+        SkipWhiteSpaces(parserState);
+    }
+    else if (*(parserState->json) == '[')
+    {
+        result = ParseArray(parserState, currentNode);
+        SkipWhiteSpaces(parserState);
+    }
+    else
+    {
+        /* Codes_SRS_JSON_DECODER_99_007:[ If parsing the JSON fails due to the JSON string being malformed, JSONDecoder_JSON_To_MultiTree shall return JSON_DECODER_PARSE_ERROR.] */
+        result = JSON_DECODER_PARSE_ERROR;
+    }
+
+    if ((result == JSON_DECODER_OK) &&
+        (*(parserState->json) != '\0'))
+    {
+        /* Codes_SRS_JSON_DECODER_99_007:[ If parsing the JSON fails due to the JSON string being malformed, JSONDecoder_JSON_To_MultiTree shall return JSON_DECODER_PARSE_ERROR.] */
+        result = JSON_DECODER_PARSE_ERROR;
+    }
+
+    return result;
+}
+
+static JSON_DECODER_RESULT ParseJSON(char* json, MULTITREE_HANDLE currentNode)
+{
+    /* Codes_SRS_JSON_DECODER_99_009:[ On success, JSONDecoder_JSON_To_MultiTree shall return a handle to the multi tree it created in the multiTreeHandle argument and it shall return JSON_DECODER_OK.] */
+    PARSER_STATE parseState;
+    parseState.json = json;
+    return ParseObjectOrArray(&parseState, currentNode);
+}
+
+JSON_DECODER_RESULT JSONDecoder_JSON_To_MultiTree(char* json, MULTITREE_HANDLE* multiTreeHandle)
+{
+    JSON_DECODER_RESULT result;
+
+    if ((json == NULL) ||
+        (multiTreeHandle == NULL))
+    {
+        /* Codes_SRS_JSON_DECODER_99_001:[ If any of the parameters passed to the JSONDecoder_JSON_To_MultiTree function is NULL then the function call shall return JSON_DECODER_INVALID_ARG.] */
+        result = JSON_DECODER_INVALID_ARG;
+    }
+    else if (*json == '\0')
+    {
+        /* Codes_SRS_JSON_DECODER_99_007:[ If parsing the JSON fails due to the JSON string being malformed, JSONDecoder_JSON_To_MultiTree shall return JSON_DECODER_PARSE_ERROR.] */
+        result = JSON_DECODER_PARSE_ERROR;
+    }
+    else
+    {
+        /* Codes_SRS_JSON_DECODER_99_008:[ JSONDecoder_JSON_To_MultiTree shall create a multi tree based on the json string argument.] */
+        /* Codes_SRS_JSON_DECODER_99_002:[ JSONDecoder_JSON_To_MultiTree shall use the MultiTree APIs to create the multi tree and add leafs to the multi tree.] */
+        /* Codes_SRS_JSON_DECODER_99_009:[ On success, JSONDecoder_JSON_To_MultiTree shall return a handle to the multi tree it created in the multiTreeHandle argument and it shall return JSON_DECODER_OK.] */
+        *multiTreeHandle = MultiTree_Create(NOPCloneFunction, NoFreeFunction);
+        if (*multiTreeHandle == NULL)
+        {
+            /* Codes_SRS_JSON_DECODER_99_038:[ If any MultiTree API fails, JSONDecoder_JSON_To_MultiTree shall return JSON_DECODER_MULTITREE_FAILED.] */
+            result = JSON_DECODER_MULTITREE_FAILED;
+        }
+        else
+        {
+            result = ParseJSON(json, *multiTreeHandle);
+            if (result != JSON_DECODER_OK)
+            {
+                MultiTree_Destroy(*multiTreeHandle);
+            }
+        }
+    }
+
+    return result;
+}
Index: azure_iot_hub_f767zi/trunk/azure_iot_sdk/serializer/src/jsonencoder.c
===================================================================
--- azure_iot_hub_f767zi/trunk/azure_iot_sdk/serializer/src/jsonencoder.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/azure_iot_sdk/serializer/src/jsonencoder.c	(revision 457)
@@ -0,0 +1,218 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+#include "azure_c_shared_utility/gballoc.h"
+
+#include "jsonencoder.h"
+#include "azure_c_shared_utility/crt_abstractions.h"
+#include "azure_c_shared_utility/xlogging.h"
+#include "azure_c_shared_utility/strings.h"
+
+#ifdef _MSC_VER
+#pragma warning(disable: 4701) /* potentially uninitialized local variable 'result' used */ /* the scanner cannot track variable "i" and link it to childCount*/
+#endif
+
+MU_DEFINE_ENUM_STRINGS_WITHOUT_INVALID(JSON_ENCODER_TOSTRING_RESULT, JSON_ENCODER_TOSTRING_RESULT_VALUES);
+MU_DEFINE_ENUM_STRINGS_WITHOUT_INVALID(JSON_ENCODER_RESULT, JSON_ENCODER_RESULT_VALUES);
+
+JSON_ENCODER_RESULT JSONEncoder_EncodeTree(MULTITREE_HANDLE treeHandle, STRING_HANDLE destination, JSON_ENCODER_TOSTRING_FUNC toStringFunc)
+{
+    JSON_ENCODER_RESULT result;
+
+    size_t childCount;
+
+    /* Codes_SRS_JSON_ENCODER_99_032:[If any of the arguments passed to JSONEncoder_EncodeTree is NULL then JSON_ENCODER_INVALID_ARG shall be returned.] */
+    if ((treeHandle == NULL) ||
+        (destination == NULL) ||
+        (toStringFunc == NULL))
+    {
+        result = JSON_ENCODER_INVALID_ARG;
+        LogError("(result = %s)", MU_ENUM_TO_STRING(JSON_ENCODER_RESULT, result));
+    }
+    /*Codes_SRS_JSON_ENCODER_99_035:[ JSON encoder shall inquire the number of child nodes (further called childCount) of the current node (given by parameter treeHandle.]*/
+    else if (MultiTree_GetChildCount(treeHandle, &childCount) != MULTITREE_OK)
+    {
+        result = JSON_ENCODER_MULTITREE_ERROR;
+        LogError("(result = %s)", MU_ENUM_TO_STRING(JSON_ENCODER_RESULT, result));
+    }
+    else
+    {
+        size_t i;
+        /*Codes_SRS_JSON_ENCODER_99_036:[ The string "{" shall be added to the output;]*/
+        if (STRING_concat(destination,  "{") != 0)
+        {
+            result = JSON_ENCODER_ERROR;
+            LogError("(result = %s)", MU_ENUM_TO_STRING(JSON_ENCODER_RESULT, result));
+        }
+        else
+        {
+            result = JSON_ENCODER_OK;
+            for (i = 0; (i < childCount) && (result == JSON_ENCODER_OK); i++)
+            {
+                MULTITREE_HANDLE childTreeHandle;
+
+                if ((i > 0) &&
+                    (STRING_concat(destination, ", ") != 0))
+                {
+                    result = JSON_ENCODER_ERROR;
+                    LogError("(result = %s)", MU_ENUM_TO_STRING(JSON_ENCODER_RESULT, result));
+                }
+                else if (STRING_concat(destination, "\"") != 0)
+                {
+                    result = JSON_ENCODER_ERROR;
+                    LogError("(result = %s)", MU_ENUM_TO_STRING(JSON_ENCODER_RESULT, result));
+                }
+                else
+                {
+                    STRING_HANDLE name = STRING_new();
+                    if (name == NULL)
+                    {
+                        result = JSON_ENCODER_ERROR;
+                        LogError("(result = %s)", MU_ENUM_TO_STRING(JSON_ENCODER_RESULT, result));
+                    }
+                    else
+                    {
+                        if (MultiTree_GetChild(treeHandle, i, &childTreeHandle) != MULTITREE_OK)
+                        {
+                            result = JSON_ENCODER_MULTITREE_ERROR;
+                            LogError("(result = %s)", MU_ENUM_TO_STRING(JSON_ENCODER_RESULT, result));
+                        }
+                        else if (MultiTree_GetName(childTreeHandle, name) != MULTITREE_OK)
+                        {
+                            result = JSON_ENCODER_MULTITREE_ERROR;
+                            LogError("(result = %s)", MU_ENUM_TO_STRING(JSON_ENCODER_RESULT, result));
+                        }
+                        else if (STRING_concat_with_STRING(destination, name) != 0)
+                        {
+                            result = JSON_ENCODER_ERROR;
+                            LogError("(result = %s)", MU_ENUM_TO_STRING(JSON_ENCODER_RESULT, result));
+                        }
+                        else if (STRING_concat(destination, "\":") != 0)
+                        {
+                            result = JSON_ENCODER_ERROR;
+                            LogError("(result = %s)", MU_ENUM_TO_STRING(JSON_ENCODER_RESULT, result));
+                        }
+                        else
+                        {
+                            size_t innerChildCount;
+                            if (MultiTree_GetChildCount(childTreeHandle, &innerChildCount) != MULTITREE_OK)
+                            {
+                                result = JSON_ENCODER_MULTITREE_ERROR;
+                                LogError("(result = %s)", MU_ENUM_TO_STRING(JSON_ENCODER_RESULT, result));
+                            }
+                            else
+                            {
+                                if (innerChildCount > 0)
+                                {
+                                    STRING_HANDLE child = STRING_new();
+                                    if (child == NULL)
+                                    {
+                                        result = JSON_ENCODER_ERROR;
+                                        LogError("(result = %s)", MU_ENUM_TO_STRING(JSON_ENCODER_RESULT, result));
+                                    }
+                                    else
+                                    {
+                                        if ((result = JSONEncoder_EncodeTree(childTreeHandle, child, toStringFunc)) != JSON_ENCODER_OK)
+                                        {
+                                            LogError("(result = %s)", MU_ENUM_TO_STRING(JSON_ENCODER_RESULT, result));
+                                        }
+                                        else if (STRING_concat_with_STRING(destination, child)!=0)
+                                        {
+                                            result = JSON_ENCODER_ERROR;
+                                            LogError("(result = %s)", MU_ENUM_TO_STRING(JSON_ENCODER_RESULT, result));
+                                        }
+                                        STRING_delete(child);
+                                    }
+                                }
+                                else
+                                {
+                                    const void* value;
+                                    if (MultiTree_GetValue(childTreeHandle, &value) != MULTITREE_OK)
+                                    {
+                                        result = JSON_ENCODER_MULTITREE_ERROR;
+                                        LogError("(result = %s)", MU_ENUM_TO_STRING(JSON_ENCODER_RESULT, result));
+
+                                    }
+                                    else
+                                    {
+                                        STRING_HANDLE childValue = STRING_new();
+                                        if (childValue == NULL)
+                                        {
+                                            result = JSON_ENCODER_ERROR;
+                                            LogError("(result = %s)", MU_ENUM_TO_STRING(JSON_ENCODER_RESULT, result));
+                                        }
+                                        else
+                                        {
+                                            if (toStringFunc(childValue, value) != JSON_ENCODER_TOSTRING_OK)
+                                            {
+                                                result = JSON_ENCODER_TOSTRING_FUNCTION_ERROR;
+                                                LogError("(result = %s)", MU_ENUM_TO_STRING(JSON_ENCODER_RESULT, result));
+                                            }
+                                            else if (STRING_concat_with_STRING(destination, childValue)!=0)
+                                            {
+                                                result = JSON_ENCODER_ERROR;
+                                                LogError("(result = %s)", MU_ENUM_TO_STRING(JSON_ENCODER_RESULT, result));
+                                            }
+                                            else
+                                            {
+                                                /*do nothing, result = JSON_ENCODER_OK is set above at the beginning of the FOR loop*/
+                                            }
+                                            STRING_delete(childValue);
+                                        }
+                                    }
+                                }
+                            }
+                        }
+                        STRING_delete(name);
+                    }
+                }
+            }
+
+            if ((i == childCount) && (result == JSON_ENCODER_OK))
+            {
+                if (STRING_concat(destination,  "}") != 0)
+                {
+                    result = JSON_ENCODER_ERROR;
+                    LogError("(result = %s)", MU_ENUM_TO_STRING(JSON_ENCODER_RESULT, result));
+                }
+                else
+                {
+                    /* Codes_SRS_JSON_ENCODER_99_031:[On success, JSONEncoder_EncodeTree shall return JSON_ENCODER_OK.] */
+                    result = JSON_ENCODER_OK;
+                }
+            }
+        }
+    }
+
+    return result;
+#ifdef _MSC_VER
+#pragma warning(disable: 4701) /* potentially uninitialized local variable 'result' used */ /* the scanner cannot track variable "i" and link it to childCount*/
+#endif
+}
+
+JSON_ENCODER_TOSTRING_RESULT JSONEncoder_CharPtr_ToString(STRING_HANDLE destination, const void* value)
+{
+    JSON_ENCODER_TOSTRING_RESULT result;
+
+    /*Coes_SRS_JSON_ENCODER_99_047:[ JSONEncoder_CharPtr_ToString shall return JSON_ENCODER_TOSTRING_INVALID_ARG if destination or value parameters passed to it are NULL.]*/
+    if ((destination == NULL) ||
+        (value == NULL))
+    {
+        result = JSON_ENCODER_TOSTRING_INVALID_ARG;
+        LogError("(result = %s)", MU_ENUM_TO_STRING(JSON_ENCODER_TOSTRING_RESULT, result));
+    }
+    /*Codes_SRS_JSON_ENCODER_99_048:[ JSONEncoder_CharPtr_ToString shall use strcpy_s to copy from value to destination.]*/
+    else if (STRING_concat(destination, (const char*)value) != 0)
+    {
+        /*Codes_SRS_JSON_ENCODER_99_049:[ If strcpy_s fails then JSONEncoder_CharPtr_ToString shall return JSON_ENCODER_TOSTRING_ERROR.]*/
+        result = JSON_ENCODER_TOSTRING_ERROR;
+        LogError("(result = %s)", MU_ENUM_TO_STRING(JSON_ENCODER_TOSTRING_RESULT, result));
+    }
+    else
+    {
+        /*Codes_SRS_JSON_ENCODER_99_050:[ If strcpy_s doesn't fail, then JSONEncoder_CharPtr_ToString shall return JSON_ENCODER_TOSTRING_OK]*/
+        result = JSON_ENCODER_TOSTRING_OK;
+    }
+
+    return result;
+}
Index: azure_iot_hub_f767zi/trunk/azure_iot_sdk/serializer/src/methodreturn.c
===================================================================
--- azure_iot_hub_f767zi/trunk/azure_iot_sdk/serializer/src/methodreturn.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/azure_iot_sdk/serializer/src/methodreturn.c	(revision 457)
@@ -0,0 +1,123 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+#include <stdlib.h>
+#include <limits.h>
+
+#include "azure_c_shared_utility/gballoc.h"
+#include "azure_c_shared_utility/xlogging.h"
+#include "azure_c_shared_utility/crt_abstractions.h"
+#include "azure_c_shared_utility/strings.h"
+#include "parson.h"
+
+#include "methodreturn.h"
+
+typedef struct METHODRETURN_HANDLE_DATA_TAG
+{
+    METHODRETURN_DATA data;
+}METHODRETURN_HANDLE_DATA;
+
+bool is_json_present_and_unparsable(const char* jsonValue)
+{
+    bool is_present_and_unparsable;
+    if (jsonValue == NULL)
+    {
+        // Null json is not considered invalid here
+        is_present_and_unparsable = false;
+    }
+    else
+    {
+        JSON_Value* temp = json_parse_string(jsonValue);
+        if (temp == NULL)
+        {
+            is_present_and_unparsable = true;
+        }
+        else
+        {
+            json_value_free(temp);
+            is_present_and_unparsable = false;
+        }
+    }
+    return is_present_and_unparsable;
+}
+
+METHODRETURN_HANDLE MethodReturn_Create(int statusCode, const char* jsonValue)
+{
+    METHODRETURN_HANDLE result;
+    /*Codes_SRS_METHODRETURN_02_009: [ If jsonValue is not a JSON value then MethodReturn_Create shall fail and return NULL. ]*/
+    if (is_json_present_and_unparsable(jsonValue))
+    {
+        LogError("%s is not JSON", jsonValue);
+        result = NULL;
+    }
+    else
+    {
+        result = (METHODRETURN_HANDLE_DATA*)calloc(1, sizeof(METHODRETURN_HANDLE_DATA));
+        if (result == NULL)
+        {
+            /*Codes_SRS_METHODRETURN_02_002: [ If any failure is encountered then MethodReturn_Create shall return NULL ]*/
+            LogError("unable to malloc");
+            /*return as is*/
+        }
+        else
+        {
+            if (jsonValue == NULL)
+            {
+                /*Codes_SRS_METHODRETURN_02_001: [ MethodReturn_Create shall create a non-NULL handle containing statusCode and a clone of jsonValue. ]*/
+                result->data.jsonValue = NULL;
+                result->data.statusCode = statusCode;
+            }
+            else
+            {
+                if (mallocAndStrcpy_s(&(result->data.jsonValue), jsonValue) != 0)
+                {
+                    LogError("failure in mallocAndStrcpy_s");
+                    free(result);
+                    result = NULL;
+                }
+                else
+                {
+                    /*Codes_SRS_METHODRETURN_02_001: [ MethodReturn_Create shall create a non-NULL handle containing statusCode and a clone of jsonValue. ]*/
+                    result->data.statusCode = statusCode;
+                }
+            }
+        }
+    }
+
+    return result;
+}
+
+void MethodReturn_Destroy(METHODRETURN_HANDLE handle)
+{
+    if (handle == NULL)
+    {
+        /*Codes_SRS_METHODRETURN_02_003: [ If handle is NULL then MethodReturn_Destroy shall return. ]*/
+        LogError("invalid argument METHODRETURN_HANDLE handle=%p", handle);
+    }
+    else
+    {
+        /*Codes_SRS_METHODRETURN_02_004: [ Otherwise, MethodReturn_Destroy shall free all used resources by handle. ]*/
+        if (handle->data.jsonValue != NULL)
+        {
+            free(handle->data.jsonValue);
+        }
+        free(handle);
+    }
+}
+
+
+const METHODRETURN_DATA* MethodReturn_GetReturn(METHODRETURN_HANDLE handle)
+{
+    const METHODRETURN_DATA* result;
+    if (handle == NULL)
+    {
+        /*Codes_SRS_METHODRETURN_02_010: [ If handle is NULL then MethodReturn_GetReturn shall fail and return NULL. ]*/
+        result = NULL;
+    }
+    else
+    {
+        /*Codes_SRS_METHODRETURN_02_011: [ Otherwise, MethodReturn_GetReturn shall return a non-NULL const pointer to a METHODRETURN_DATA. ]*/
+        result = &(handle->data);
+    }
+    return result;
+}
Index: azure_iot_hub_f767zi/trunk/azure_iot_sdk/serializer/src/multitree.c
===================================================================
--- azure_iot_hub_f767zi/trunk/azure_iot_sdk/serializer/src/multitree.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/azure_iot_sdk/serializer/src/multitree.c	(revision 457)
@@ -0,0 +1,835 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+#include <stdlib.h>
+#include "azure_c_shared_utility/gballoc.h"
+
+#include "multitree.h"
+#include <string.h>
+#include "azure_c_shared_utility/crt_abstractions.h"
+#include "azure_c_shared_utility/xlogging.h"
+#include "azure_macro_utils/macro_utils.h"
+#include "azure_c_shared_utility/const_defines.h"
+
+/*assume a name cannot be longer than 100 characters*/
+#define INNER_NODE_NAME_SIZE 128
+
+MU_DEFINE_ENUM_STRINGS_WITHOUT_INVALID(MULTITREE_RESULT, MULTITREE_RESULT_VALUES);
+
+typedef struct MULTITREE_HANDLE_DATA_TAG
+{
+    char* name;
+    void* value;
+    MULTITREE_CLONE_FUNCTION cloneFunction;
+    MULTITREE_FREE_FUNCTION freeFunction;
+    size_t nChildren;
+    struct MULTITREE_HANDLE_DATA_TAG** children; /*an array of nChildren count of MULTITREE_HANDLE_DATA*   */
+}MULTITREE_HANDLE_DATA;
+
+
+MULTITREE_HANDLE MultiTree_Create(MULTITREE_CLONE_FUNCTION cloneFunction, MULTITREE_FREE_FUNCTION freeFunction)
+{
+    MULTITREE_HANDLE_DATA* result;
+
+    /* Codes_SRS_MULTITREE_99_052:[If any of the arguments passed to MultiTree_Create is NULL, the call shall return NULL.]*/
+    if ((cloneFunction == NULL) ||
+        (freeFunction == NULL))
+    {
+        LogError("CloneFunction or FreeFunction is Null.");
+        result = NULL;
+    }
+    else
+    {
+        /*Codes_SRS_MULTITREE_99_005:[ MultiTree_Create creates a new tree.]*/
+        /*Codes_SRS_MULTITREE_99_006:[MultiTree_Create returns a non - NULL pointer if the tree has been successfully created.]*/
+        /*Codes_SRS_MULTITREE_99_007:[MultiTree_Create returns NULL if the tree has not been successfully created.]*/
+        result = (MULTITREE_HANDLE_DATA*)calloc(1, sizeof(MULTITREE_HANDLE_DATA));
+        if (result != NULL)
+        {
+            result->name = NULL;
+            result->value = NULL;
+            result->cloneFunction = cloneFunction;
+            result->freeFunction = freeFunction;
+            result->nChildren = 0;
+            result->children = NULL;
+        }
+        else
+        {
+            LogError("MultiTree_Create failed because malloc failed");
+        }
+    }
+
+    return (MULTITREE_HANDLE)result;
+}
+
+
+/*return NULL if a child with the name "name" doesn't exists*/
+/*returns a pointer to the existing child (if any)*/
+static MULTITREE_HANDLE_DATA* getChildByName(MULTITREE_HANDLE_DATA* node, const char* name)
+{
+    MULTITREE_HANDLE_DATA* result = NULL;
+    size_t i;
+    for (i = 0; i < node->nChildren; i++)
+    {
+        if (strcmp(node->children[i]->name, name) == 0)
+        {
+            result = node->children[i];
+            break;
+        }
+    }
+    return result;
+}
+
+/*helper function to create a child immediately under this node*/
+/*return 0 if it created it, any other number is error*/
+
+typedef enum CREATELEAF_RESULT_TAG
+{
+    CREATELEAF_OK,
+    CREATELEAF_ALREADY_EXISTS,
+    CREATELEAF_EMPTY_NAME,
+    CREATELEAF_ERROR,
+    CREATELEAF_RESULT_COUNT // Used to track the number of elements in the enum
+                            // Do not remove, or add new enum values below this one
+}CREATELEAF_RESULT;
+
+static STATIC_VAR_UNUSED const char* CreateLeaf_ResultAsString[CREATELEAF_RESULT_COUNT] =
+{
+    MU_TOSTRING(CREATELEAF_OK),
+    MU_TOSTRING(CREATELEAF_ALREADY_EXISTS),
+    MU_TOSTRING(CREATELEAF_EMPTY_NAME),
+    MU_TOSTRING(CREATELEAF_ERROR)
+};
+
+/*name cannot be empty, value can be empty or NULL*/
+#ifdef __APPLE__
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wconditional-uninitialized"
+#endif
+#ifdef _MSC_VER
+#pragma warning(disable: 4701) /* potentially uninitialized local variable 'result' used */ /* the scanner cannot track linked "newNode" and "result" therefore the warning*/
+#endif
+static CREATELEAF_RESULT createLeaf(MULTITREE_HANDLE_DATA* node, const char*name, const char*value, MULTITREE_HANDLE_DATA** childNode)
+{
+    CREATELEAF_RESULT result;
+    /*can only create it if it doesn't exist*/
+    if (strlen(name) == 0)
+    {
+        /*Codes_SRS_MULTITREE_99_024:[ if a child name is empty (such as in  "/child1//child12"), MULTITREE_EMPTY_CHILD_NAME shall be returned.]*/
+        result = CREATELEAF_EMPTY_NAME;
+        LogError("(result = %s)", CreateLeaf_ResultAsString[result]);
+    }
+    else if (getChildByName(node, name) != NULL)
+    {
+        result = CREATELEAF_ALREADY_EXISTS;
+        LogError("(result = %s)", CreateLeaf_ResultAsString[result]);
+    }
+    else
+    {
+        MULTITREE_HANDLE_DATA* newNode = (MULTITREE_HANDLE_DATA*)calloc(1, sizeof(MULTITREE_HANDLE_DATA));
+        if (newNode == NULL)
+        {
+            result = CREATELEAF_ERROR;
+            LogError("(result = %s)", CreateLeaf_ResultAsString[result]);
+        }
+        else
+        {
+            newNode->nChildren = 0;
+            newNode->children = NULL;
+            if (mallocAndStrcpy_s(&(newNode->name), name) != 0)
+            {
+                /*not nice*/
+                free(newNode);
+                newNode = NULL;
+                result = CREATELEAF_ERROR;
+                LogError("(result = %s)", CreateLeaf_ResultAsString[result]);
+            }
+            else
+            {
+                newNode->cloneFunction = node->cloneFunction;
+                newNode->freeFunction = node->freeFunction;
+
+                if (value == NULL)
+                {
+                    newNode->value = NULL;
+                }
+                else if (node->cloneFunction(&(newNode->value), value) != 0)
+                {
+                    free(newNode->name);
+                    newNode->name = NULL;
+                    free(newNode);
+                    newNode = NULL;
+                    result = CREATELEAF_ERROR;
+                    LogError("(result = %s)", CreateLeaf_ResultAsString[result]);
+                }
+                else
+                {
+                    /*all is fine until now*/
+                }
+            }
+
+
+            if (newNode!=NULL)
+            {
+                /*allocate space in the father node*/
+                MULTITREE_HANDLE_DATA** newChildren = (MULTITREE_HANDLE_DATA**)realloc(node->children, (node->nChildren + 1)*sizeof(MULTITREE_HANDLE_DATA*));
+                if (newChildren == NULL)
+                {
+                    /*no space for the new node*/
+                    newNode->value = NULL;
+                    free(newNode->name);
+                    newNode->name = NULL;
+                    free(newNode);
+                    newNode = NULL;
+                    result = CREATELEAF_ERROR;
+                    LogError("(result = %s)", CreateLeaf_ResultAsString[result]);
+                }
+                else
+                {
+                    node->children = newChildren;
+                    node->children[node->nChildren] = newNode;
+                    node->nChildren++;
+                    if (childNode != NULL)
+                    {
+                        *childNode = newNode;
+                    }
+                    result = CREATELEAF_OK;
+                }
+            }
+        }
+    }
+
+    return result;
+#ifdef _MSC_VER
+#pragma warning(default: 4701) /* potentially uninitialized local variable 'result' used */ /* the scanner cannot track linked "newNode" and "result" therefore the warning*/
+#endif
+#ifdef __APPLE__
+#pragma clang diagnostic pop
+#endif
+}
+
+MULTITREE_RESULT MultiTree_AddLeaf(MULTITREE_HANDLE treeHandle, const char* destinationPath, const void* value)
+{
+    /*codes_SRS_MULTITREE_99_018:[ If the treeHandle parameter is NULL, MULTITREE_INVALID_ARG shall be returned.]*/
+    MULTITREE_RESULT result;
+    if (treeHandle == NULL)
+    {
+        result = MULTITREE_INVALID_ARG;
+        LogError("(result = %s)", MU_ENUM_TO_STRING(MULTITREE_RESULT, result));
+    }
+    /*Codes_SRS_MULTITREE_99_019:[ If parameter destinationPath is NULL, MULTITREE_INVALID_ARG shall be returned.]*/
+    else if (destinationPath == NULL)
+    {
+        result = MULTITREE_INVALID_ARG;
+        LogError("(result = %s)", MU_ENUM_TO_STRING(MULTITREE_RESULT, result));
+    }
+    /*Codes_SRS_MULTITREE_99_020:[ If parameter value is NULL, MULTITREE_INVALID_ARG shall be returned.]*/
+    else if (value == NULL)
+    {
+        result = MULTITREE_INVALID_ARG;
+        LogError("(result = %s)", MU_ENUM_TO_STRING(MULTITREE_RESULT, result));
+    }
+    /*Codes_SRS_MULTITREE_99_050:[ If destinationPath a string with zero characters, MULTITREE_INVALID_ARG shall be returned.]*/
+    else if (strlen(destinationPath) == 0)
+    {
+        result = MULTITREE_EMPTY_CHILD_NAME;
+        LogError("(result = %s)", MU_ENUM_TO_STRING(MULTITREE_RESULT, result));
+    }
+    else
+    {
+        /*break the path into components*/
+        /*find the first child name*/
+        MULTITREE_HANDLE_DATA * node = (MULTITREE_HANDLE_DATA *)treeHandle;
+        char * whereIsDelimiter;
+        /*if first character is / then skip it*/
+        /*Codes_SRS_MULTITREE_99_014:[DestinationPath is a string in the following format: /child1/child12 or child1/child12] */
+        if (destinationPath[0] == '/')
+        {
+            destinationPath++;
+        }
+        /*if there's just a string, it needs to be created here*/
+        whereIsDelimiter = (char*)strchr(destinationPath, '/');
+        if (whereIsDelimiter == NULL)
+        {
+            /*Codes_SRS_MULTITREE_99_017:[ Subsequent names designate hierarchical children in the tree. The last child designates the child that will receive the value.]*/
+            CREATELEAF_RESULT res = createLeaf(node, destinationPath, (const char*)value, NULL);
+            switch (res)
+            {
+                default:
+                {
+                    /*Codes_SRS_MULTITREE_99_025:[The function shall return MULTITREE_ERROR to indicate any other error not specified here.]*/
+                    result = MULTITREE_ERROR;
+                    LogError("(result = %s)", MU_ENUM_TO_STRING(MULTITREE_RESULT, result));
+                    break;
+                }
+                case CREATELEAF_ALREADY_EXISTS:
+                {
+                    /*Codes_SRS_MULTITREE_99_021:[ If the node already has a value assigned to it, MULTITREE_ALREADY_HAS_A_VALUE shall be returned and the existing value shall not be changed.]*/
+                    result = MULTITREE_ALREADY_HAS_A_VALUE;
+                    LogError("(result = %s)", MU_ENUM_TO_STRING(MULTITREE_RESULT, result));
+                    break;
+                }
+                case CREATELEAF_OK:
+                {
+                    /*Codes_SRS_MULTITREE_99_034:[ The function returns MULTITREE_OK when data has been stored in the tree.]*/
+                    result = MULTITREE_OK;
+                    break;
+                }
+                case CREATELEAF_EMPTY_NAME:
+                {
+                    /*Codes_SRS_MULTITREE_99_024:[ if a child name is empty (such as in  "/child1//child12"), MULTITREE_EMPTY_CHILD_NAME shall be returned.]*/
+                    result = MULTITREE_EMPTY_CHILD_NAME;
+                    LogError("(result = %s)", MU_ENUM_TO_STRING(MULTITREE_RESULT, result));
+                    break;
+                }
+            }
+        }
+        else
+        {
+            /*if there's more or 1 delimiter in the path... */
+            /*Codes_SRS_MULTITREE_99_017:[ Subsequent names designate hierarchical children in the tree. The last child designates the child that will receive the value.]*/
+            char firstInnerNodeName[INNER_NODE_NAME_SIZE];
+            if ((whereIsDelimiter - destinationPath) >= INNER_NODE_NAME_SIZE)
+            {
+                /*Codes_SRS_MULTITREE_99_025:[ The function shall return MULTITREE_ERROR to indicate any other error not specified here.]*/
+                result = MULTITREE_ERROR;
+                LogError("Destination path is too large %lu", (unsigned long)(whereIsDelimiter - destinationPath));
+            }
+            else if (memcpy(firstInnerNodeName, destinationPath, whereIsDelimiter - destinationPath) == NULL)
+            {
+                /*Codes_SRS_MULTITREE_99_025:[ The function shall return MULTITREE_ERROR to indicate any other error not specified here.]*/
+                result = MULTITREE_ERROR;
+                LogError("(result = MULTITREE_ERROR)");
+            }
+            else
+            {
+                firstInnerNodeName[whereIsDelimiter - destinationPath] = 0;
+                MULTITREE_HANDLE_DATA *child = getChildByName(node, firstInnerNodeName);
+                if (child == NULL)
+                {
+                    /*Codes_SRS_MULTITREE_99_022:[ If a child along the path does not exist, it shall be created.] */
+                    /*Codes_SRS_MULTITREE_99_023:[ The newly created children along the path shall have a NULL value by default.]*/
+                    CREATELEAF_RESULT res = createLeaf(node, firstInnerNodeName, NULL, NULL);
+                    switch (res)
+                    {
+                        default:
+                        {
+                            result = MULTITREE_ERROR;
+                            LogError("(result = %s)", MU_ENUM_TO_STRING(MULTITREE_RESULT, result));
+                            break;
+                        }
+                        case(CREATELEAF_EMPTY_NAME):
+                        {
+                            /*Codes_SRS_MULTITREE_99_024:[ if a child name is empty (such as in  "/child1//child12"), MULTITREE_EMPTY_CHILD_NAME shall be returned.]*/
+                            result = MULTITREE_EMPTY_CHILD_NAME;
+                            LogError("(result = %s)", MU_ENUM_TO_STRING(MULTITREE_RESULT, result));
+                            break;
+                        }
+                        case(CREATELEAF_OK):
+                        {
+                            MULTITREE_HANDLE_DATA *createdChild = getChildByName(node, firstInnerNodeName);
+                            result = MultiTree_AddLeaf(createdChild, whereIsDelimiter, value);
+                            break;
+                        }
+                    };
+                }
+                else
+                {
+                    result = MultiTree_AddLeaf(child, whereIsDelimiter, value);
+                }
+            }
+        }
+    }
+    return result;
+}
+
+/* Codes_SRS_MULTITREE_99_053:[ MultiTree_AddChild shall add a new node with the name childName to the multi tree node identified by treeHandle] */
+MULTITREE_RESULT MultiTree_AddChild(MULTITREE_HANDLE treeHandle, const char* childName, MULTITREE_HANDLE* childHandle)
+{
+    MULTITREE_RESULT result;
+    /* Codes_SRS_MULTITREE_99_055:[ If any argument is NULL, MultiTree_AddChild shall return MULTITREE_INVALID_ARG.] */
+    if ((treeHandle == NULL) ||
+        (childName == NULL) ||
+        (childHandle == NULL))
+    {
+        result = MULTITREE_INVALID_ARG;
+        LogError("(result = %s)", MU_ENUM_TO_STRING(MULTITREE_RESULT, result));
+    }
+    else
+    {
+        MULTITREE_HANDLE_DATA* childNode;
+
+        /* Codes_SRS_MULTITREE_99_060:[ The value associated with the new node shall be NULL.] */
+        CREATELEAF_RESULT res = createLeaf((MULTITREE_HANDLE_DATA*)treeHandle, childName, NULL, &childNode);
+        switch (res)
+        {
+            default:
+            {
+                result = MULTITREE_ERROR;
+                LogError("(result = %s)", MU_ENUM_TO_STRING(MULTITREE_RESULT, result));
+                break;
+            }
+            case CREATELEAF_ALREADY_EXISTS:
+            {
+                /* Codes_SRS_MULTITREE_99_061:[ If a child node with the same name already exists, MultiTree_AddChild shall return MULTITREE_ALREADY_HAS_A_VALUE.] */
+                result = MULTITREE_ALREADY_HAS_A_VALUE;
+                LogError("(result = %s)", MU_ENUM_TO_STRING(MULTITREE_RESULT, result));
+                break;
+            }
+            case CREATELEAF_OK:
+            {
+                /* Codes_SRS_MULTITREE_99_062:[ The new node handle shall be returned in the childHandle argument.] */
+                *childHandle = childNode;
+
+                /* Codes_SRS_MULTITREE_99_054:[ On success, MultiTree_AddChild shall return MULTITREE_OK.] */
+                result = MULTITREE_OK;
+                break;
+            }
+            case CREATELEAF_EMPTY_NAME:
+            {
+                /* Tests_SRS_MULTITREE_99_066:[ If the childName argument is an empty string, MultiTree_AddChild shall return MULTITREE_EMPTY_CHILD_NAME.] */
+                result = MULTITREE_EMPTY_CHILD_NAME;
+                LogError("(result = %s)", MU_ENUM_TO_STRING(MULTITREE_RESULT, result));
+                break;
+            }
+        }
+    }
+
+    return result;
+}
+
+MULTITREE_RESULT MultiTree_GetChildCount(MULTITREE_HANDLE treeHandle, size_t* count)
+{
+    MULTITREE_RESULT result;
+    /*Codes_SRS_MULTITREE_99_027:[If treeHandle is NULL, the function returns MULTITREE_INVALID_ARG.]*/
+    if (treeHandle == NULL)
+    {
+        result = MULTITREE_INVALID_ARG;
+        LogError("(result = %s)", MU_ENUM_TO_STRING(MULTITREE_RESULT, result));
+    }
+    /*Codes_SRS_MULTITREE_99_028:[ If parameter count is NULL, the function returns MULTITREE_INVALID_ARG.]*/
+    else if (count == NULL)
+    {
+        result = MULTITREE_INVALID_ARG;
+        LogError("(result = %s)", MU_ENUM_TO_STRING(MULTITREE_RESULT, result));
+    }
+    else
+    {
+        /*Codes_SRS_MULTITREE_99_029:[ This function writes in *count the number of direct children for a tree node specified by the parameter treeHandle]*/
+        *count = ((MULTITREE_HANDLE_DATA*)treeHandle)->nChildren;
+        /*Codes_SRS_MULTITREE_99_035:[ The function shall return MULTITREE_OK when *count contains the number of children of the node pointed to be parameter treeHandle.]*/
+        result = MULTITREE_OK;
+    }
+    return result;
+}
+
+MULTITREE_RESULT MultiTree_GetChild(MULTITREE_HANDLE treeHandle, size_t index, MULTITREE_HANDLE *childHandle)
+{
+    MULTITREE_RESULT result;
+    /*Codes_SRS_MULTITREE_99_031:[ If parameter treeHandle is NULL, the function returns MULTITREE_INVALID_ARG.]*/
+    if (treeHandle == NULL)
+    {
+        result = MULTITREE_INVALID_ARG;
+        LogError("(result = %s)", MU_ENUM_TO_STRING(MULTITREE_RESULT, result));
+    }
+    /*Codes_SRS_MULTITREE_99_033:[ If parameter childHandle is NULL, the function shall return MULTITREE_INVALID_ARG.]*/
+    else if (childHandle == NULL)
+    {
+        result = MULTITREE_INVALID_ARG;
+        LogError("(result = %s)", MU_ENUM_TO_STRING(MULTITREE_RESULT, result));
+    }
+    else
+    {
+        MULTITREE_HANDLE_DATA * node = (MULTITREE_HANDLE_DATA *)treeHandle;
+        /*Codes_SRS_MULTITREE_99_032:[If parameter index is out of range, the function shall return MULTITREE_OUT_OF_RANGE_INDEX]*/
+        if (node->nChildren <= index)
+        {
+            result = MULTITREE_INVALID_ARG;
+            LogError("(result = %s)", MU_ENUM_TO_STRING(MULTITREE_RESULT, result));
+        }
+        else
+        {
+            /*Codes_SRS_MULTITREE_99_030:[ This function writes in *childHandle parameter the "index"th child of the node pointed to by parameter treeHandle]*/
+            /*Codes_SRS_MULTITREE_99_035:[ The function returns MULTITREE_OK when *childHandle contains a handle to the "index"th child of the tree designated by parameter treeHandle.]*/
+            *childHandle = node->children[index];
+            result = MULTITREE_OK;
+        }
+    }
+    return result;
+}
+
+MULTITREE_RESULT MultiTree_GetName(MULTITREE_HANDLE treeHandle, STRING_HANDLE destination)
+{
+    MULTITREE_RESULT result;
+    /*Codes_SRS_MULTITREE_99_037:[ If treeHandle is NULL, the function shall return MULTITREE_INVALID_ARG.]*/
+    if (treeHandle == NULL)
+    {
+        result = MULTITREE_INVALID_ARG;
+        LogError("(result = %s)", MU_ENUM_TO_STRING(MULTITREE_RESULT, result));
+    }
+    /*Codes_SRS_MULTITREE_99_038:[If destination is NULL, the function shall return MULTITREE_INVALID_ARG.]*/
+    else if (destination == NULL)
+    {
+        result = MULTITREE_INVALID_ARG;
+        LogError("(result = %s)", MU_ENUM_TO_STRING(MULTITREE_RESULT, result));
+    }
+    else
+    {
+        MULTITREE_HANDLE_DATA *node = (MULTITREE_HANDLE_DATA*)treeHandle;
+        /*Codes_SRS_MULTITREE_99_051:[ The function returns MULTITREE_EMPTY_CHILD_NAME when used with the root of the tree.]*/
+        if (node->name == NULL)
+        {
+            result = MULTITREE_EMPTY_CHILD_NAME;
+            LogError("(result = %s)", MU_ENUM_TO_STRING(MULTITREE_RESULT, result));
+        }
+        /*Codes_SRS_MULTITREE_99_036:[ This function fills the buffer pointed to by parameter destination with the name of the root node of the tree designated by parameter treeHandle.]*/
+        else if (STRING_concat(destination, node->name)!=0)
+        {
+            /*Codes_SRS_MULTITREE_99_040:[ The function returns MULTITREE_ERROR to indicate any other error.]*/
+            result = MULTITREE_ERROR;
+            LogError("(result = %s)", MU_ENUM_TO_STRING(MULTITREE_RESULT, result));
+        }
+        else
+        {
+            /*Codes_SRS_MULTITREE_99_039:[ The function returns MULTITREE_OK when destination contains the name of the root node of the tree designated by treeHandle parameter.]*/
+            result = MULTITREE_OK;
+        }
+    }
+
+    return result;
+}
+
+/* Codes_SRS_MULTITREE_99_063:[ MultiTree_GetChildByName shall retrieve the handle of the child node childName from the treeNode node.] */
+MULTITREE_RESULT MultiTree_GetChildByName(MULTITREE_HANDLE treeHandle, const char* childName, MULTITREE_HANDLE *childHandle)
+{
+    MULTITREE_RESULT result;
+
+    /* Codes_SRS_MULTITREE_99_065:[ If any argument is NULL, MultiTree_GetChildByName shall return MULTITREE_INVALID_ARG.] */
+    if ((treeHandle == NULL) ||
+        (childHandle == NULL) ||
+        (childName == NULL))
+    {
+        result = MULTITREE_INVALID_ARG;
+        LogError("(result = %s)", MU_ENUM_TO_STRING(MULTITREE_RESULT, result));
+    }
+    else
+    {
+        MULTITREE_HANDLE_DATA * node = (MULTITREE_HANDLE_DATA *)treeHandle;
+        size_t i;
+
+        for (i = 0; i < node->nChildren; i++)
+        {
+            if (strcmp(node->children[i]->name, childName) == 0)
+            {
+                break;
+            }
+        }
+
+        if (i == node->nChildren)
+        {
+            /* Codes_SRS_MULTITREE_99_068:[ If the specified child is not found, MultiTree_GetChildByName shall return MULTITREE_CHILD_NOT_FOUND.] */
+            result = MULTITREE_CHILD_NOT_FOUND;
+            LogError("(result = %s)", MU_ENUM_TO_STRING(MULTITREE_RESULT, result));
+        }
+        else
+        {
+            /* Codes_SRS_MULTITREE_99_067:[ The child node handle shall be returned in the childHandle argument.] */
+            *childHandle = node->children[i];
+
+            /* Codes_SRS_MULTITREE_99_064:[ On success, MultiTree_GetChildByName shall return MULTITREE_OK.] */
+            result = MULTITREE_OK;
+        }
+    }
+    return result;
+}
+
+MULTITREE_RESULT MultiTree_GetValue(MULTITREE_HANDLE treeHandle, const void** destination)
+{
+    MULTITREE_RESULT result;
+    /*Codes_SRS_MULTITREE_99_042:[If treeHandle is NULL, the function shall return MULTITREE_INVALID_ARG.]*/
+    if (treeHandle == NULL)
+    {
+        result = MULTITREE_INVALID_ARG;
+        LogError("(result = %s)", MU_ENUM_TO_STRING(MULTITREE_RESULT, result));
+    }
+    /*Codes_SRS_MULTITREE_99_043:[ If destination is NULL, the function shall return MULTITREE_INVALID_ARG.]*/
+    else if (destination == NULL)
+    {
+        result = MULTITREE_INVALID_ARG;
+        LogError("(result = %s)", MU_ENUM_TO_STRING(MULTITREE_RESULT, result));
+    }
+    else
+    {
+        MULTITREE_HANDLE_DATA * node = (MULTITREE_HANDLE_DATA*)treeHandle;
+        /*Codes_SRS_MULTITREE_99_044:[ If there is no value in the node then MULTITREE_EMPTY_VALUE shall be returned.]*/
+        if (node->value == NULL)
+        {
+            result = MULTITREE_EMPTY_VALUE;
+            LogError("(result = %s)", MU_ENUM_TO_STRING(MULTITREE_RESULT, result));
+        }
+        else
+        {
+            /*Codes_SRS_MULTITREE_99_041:[This function updates the *destination parameter to the internally stored value.]*/
+            *destination = node->value;
+            result = MULTITREE_OK;
+        }
+    }
+    return result;
+}
+
+MULTITREE_RESULT MultiTree_SetValue(MULTITREE_HANDLE treeHandle, void* value)
+{
+    MULTITREE_RESULT result;
+
+    /* Codes_SRS_MULTITREE_99_074:[ If any argument is NULL, MultiTree_SetValue shall return MULTITREE_INVALID_ARG.] */
+    if ((treeHandle == NULL) ||
+        (value == NULL))
+    {
+        result = MULTITREE_INVALID_ARG;
+        LogError("(result = %s)", MU_ENUM_TO_STRING(MULTITREE_RESULT, result));
+    }
+    else
+    {
+        MULTITREE_HANDLE_DATA * node = (MULTITREE_HANDLE_DATA*)treeHandle;
+        if (node->value != NULL)
+        {
+            /* Codes_SRS_MULTITREE_99_076:[ If the node already has a value then MultiTree_SetValue shall return MULTITREE_ALREADY_HAS_A_VALUE.] */
+            result = MULTITREE_ALREADY_HAS_A_VALUE;
+            LogError("(result = %s)", MU_ENUM_TO_STRING(MULTITREE_RESULT, result));
+        }
+        else
+        {
+            /* Codes_SRS_MULTITREE_99_072:[ MultiTree_SetValue shall set the value of the node indicated by the treeHandle argument to the value of the argument value.] */
+            if (node->cloneFunction(&node->value, value) != 0)
+            {
+                /* Codes_SRS_MULTITREE_99_075:[ MultiTree_SetValue shall return MULTITREE_ERROR to indicate any other error.] */
+                result = MULTITREE_ERROR;
+                LogError("(result = %s)", MU_ENUM_TO_STRING(MULTITREE_RESULT, result));
+            }
+            else
+            {
+                /* Codes_SRS_MULTITREE_99_073:[ On success, MultiTree_SetValue shall return MULTITREE_OK.] */
+                result = MULTITREE_OK;
+            }
+        }
+    }
+    return result;
+}
+
+void MultiTree_Destroy(MULTITREE_HANDLE treeHandle)
+{
+    if (treeHandle != NULL)
+    {
+        MULTITREE_HANDLE_DATA* node = (MULTITREE_HANDLE_DATA*)treeHandle;
+        size_t i;
+        for (i = 0; i < node->nChildren;i++)
+        {
+            /*Codes_SRS_MULTITREE_99_047:[ This function frees any system resource used by the tree designated by parameter treeHandle]*/
+            MultiTree_Destroy(node->children[i]);
+        }
+        /*Codes_SRS_MULTITREE_99_047:[ This function frees any system resource used by the tree designated by parameter treeHandle]*/
+        if (node->children != NULL)
+        {
+            free(node->children);
+            node->children = NULL;
+        }
+
+        /*Codes_SRS_MULTITREE_99_047:[ This function frees any system resource used by the tree designated by parameter treeHandle]*/
+        if (node->name != NULL)
+        {
+            free(node->name);
+            node->name = NULL;
+        }
+
+        /*Codes_SRS_MULTITREE_99_047:[ This function frees any system resource used by the tree designated by parameter treeHandle]*/
+        if (node->value != NULL)
+        {
+            node->freeFunction(node->value);
+            node->value = NULL;
+        }
+
+        /*Codes_SRS_MULTITREE_99_047:[ This function frees any system resource used by the tree designated by parameter treeHandle]*/
+        free(node);
+    }
+}
+
+MULTITREE_RESULT MultiTree_GetLeafValue(MULTITREE_HANDLE treeHandle, const char* leafPath, const void** destination)
+{
+    MULTITREE_RESULT result;
+
+    /* Codes_SRS_MULTITREE_99_055:[ If any argument is NULL, MultiTree_GetLeafValue shall return MULTITREE_INVALID_ARG.] */
+    if ((treeHandle == NULL) ||
+        (leafPath == NULL) ||
+        (destination == NULL))
+    {
+        result = MULTITREE_INVALID_ARG;
+        LogError("(result = %s)", MU_ENUM_TO_STRING(MULTITREE_RESULT, result));
+    }
+    /* Codes_SRS_MULTITREE_99_058:[ The last child designates the child that will receive the value. If a child name is empty (such as in  "/child1//child12"), MULTITREE_EMPTY_CHILD_NAME shall be returned.] */
+    else if (strlen(leafPath) == 0)
+    {
+        result = MULTITREE_EMPTY_CHILD_NAME;
+        LogError("(result = %s)", MU_ENUM_TO_STRING(MULTITREE_RESULT, result));
+    }
+    else
+    {
+        /*break the path into components*/
+        /*find the first child name*/
+        MULTITREE_HANDLE_DATA* node = (MULTITREE_HANDLE_DATA *)treeHandle;
+        const char* pos = leafPath;
+        const char * whereIsDelimiter;
+
+        /*if first character is / then skip it*/
+        if (*pos == '/')
+        {
+            pos++;
+        }
+
+        if (*pos == '\0')
+        {
+            /* Codes_SRS_MULTITREE_99_069:[ If a child name is empty (such as in  "/child1//child12"), MULTITREE_EMPTY_CHILD_NAME shall be returned.] */
+            result = MULTITREE_EMPTY_CHILD_NAME;
+            LogError("(result = %s)", MU_ENUM_TO_STRING(MULTITREE_RESULT, result));
+        }
+        else
+        {
+            result = MULTITREE_OK;
+
+            /* Codes_SRS_MULTITREE_99_056:[ The leafPath argument is a string in the following format: /child1/child12 or child1/child12.] */
+            /* Codes_SRS_MULTITREE_99_058:[ The last child designates the child that will receive the value.] */
+            while (*pos != '\0')
+            {
+                size_t i;
+                size_t childCount = node->nChildren;
+
+                whereIsDelimiter = pos;
+
+                while ((*whereIsDelimiter != '/') && (*whereIsDelimiter != '\0'))
+                {
+                    whereIsDelimiter++;
+                }
+
+                if (whereIsDelimiter == pos)
+                {
+                    /* Codes_SRS_MULTITREE_99_069:[ If a child name is empty (such as in  "/child1//child12"), MULTITREE_EMPTY_CHILD_NAME shall be returned.] */
+                    result = MULTITREE_EMPTY_CHILD_NAME;
+                    LogError("(result = %s)", MU_ENUM_TO_STRING(MULTITREE_RESULT, result));
+                    break;
+                }
+                else if (childCount == 0)
+                {
+                    /* Codes_SRS_MULTITREE_99_071:[ When the child node is not found, MultiTree_GetLeafValue shall return MULTITREE_CHILD_NOT_FOUND.] */
+                    result = MULTITREE_CHILD_NOT_FOUND;
+                    LogError("(result = %s)", MU_ENUM_TO_STRING(MULTITREE_RESULT, result));
+                    break;
+                }
+                else
+                {
+                    for (i = 0; i < childCount; i++)
+                    {
+                        if (strncmp(node->children[i]->name, pos, whereIsDelimiter - pos) == 0)
+                        {
+                            /* Codes_SRS_MULTITREE_99_057:[ Subsequent names designate hierarchical children in the tree.] */
+                            node = node->children[i];
+                            break;
+                        }
+                    }
+
+                    if (i == childCount)
+                    {
+                        /* Codes_SRS_MULTITREE_99_071:[ When the child node is not found, MultiTree_GetLeafValue shall return MULTITREE_CHILD_NOT_FOUND.] */
+                        result = MULTITREE_CHILD_NOT_FOUND;
+                        LogError("(result = %s)", MU_ENUM_TO_STRING(MULTITREE_RESULT, result));
+                        break;
+                    }
+                    else
+                    {
+                        if (*whereIsDelimiter == '/')
+                        {
+                            pos = whereIsDelimiter + 1;
+                        }
+                        else
+                        {
+                            /* end of path */
+                            pos = whereIsDelimiter;
+                            break;
+                        }
+                    }
+                }
+            }
+
+            if (*pos == 0)
+            {
+                if (node->value == NULL)
+                {
+                    /* Codes_SRS_MULTITREE_99_070:[ If an attempt is made to get the value for a node that does not have a value set, then MultiTree_GetLeafValue shall return MULTITREE_EMPTY_VALUE.] */
+                    result = MULTITREE_EMPTY_VALUE;
+                    LogError("(result = %s)", MU_ENUM_TO_STRING(MULTITREE_RESULT, result));
+                }
+                /*Codes_SRS_MULTITREE_99_053:[ MultiTree_GetLeafValue shall copy into the *destination argument the value of the node identified by the leafPath argument.]*/
+                else
+                {
+                    *destination = node->value;
+                    /* Codes_SRS_MULTITREE_99_054:[ On success, MultiTree_GetLeafValue shall return MULTITREE_OK.] */
+                    result = MULTITREE_OK;
+                }
+            }
+        }
+    }
+    return result;
+}
+
+/* Codes_SRS_MULTITREE_99_077:[ MultiTree_DeleteChild shall remove the direct children node (no recursive search) set by childName.] */
+MULTITREE_RESULT MultiTree_DeleteChild(MULTITREE_HANDLE treeHandle, const char* childName)
+{
+    MULTITREE_RESULT result;
+    /* Codes_SRS_MULTITREE_99_077:[ If any argument is NULL, MultiTree_DeleteChild shall return MULTITREE_INVALID_ARG.] */
+    if ((treeHandle == NULL) ||
+        (childName == NULL))
+    {
+        result = MULTITREE_INVALID_ARG;
+        LogError("(result = %s)", MU_ENUM_TO_STRING(MULTITREE_RESULT, result));
+    }
+    else
+    {
+        size_t i;
+        size_t childToRemove = treeHandle->nChildren;
+        MULTITREE_HANDLE treeToRemove = NULL;
+
+        for (i = 0; i < treeHandle->nChildren; i++)
+        {
+            if (0 == strcmp(treeHandle->children[i]->name, childName))
+            {
+                childToRemove = i;
+                treeToRemove = treeHandle->children[childToRemove];
+                break;
+            }
+        }
+
+        if (i == treeHandle->nChildren)
+        {
+            /* Codes_SRS_MULTITREE_99_079:[If childName is not found, MultiTree_DeleteChild shall return MULTITREE_CHILD_NOT_FOUND.] */
+            result = MULTITREE_CHILD_NOT_FOUND;
+            // Don't log error; this function is best effort only.  Caller will determine actual error state.
+        }
+        else
+        {
+            for (i = childToRemove; i < treeHandle->nChildren - 1; i++)
+            {
+                treeHandle->children[i] = treeHandle->children[i+1];
+            }
+
+            /* Codes_SRS_MULTITREE_99_077:[ MultiTree_DeleteChild shall remove the direct children node (no recursive search) set by childName  */
+            MultiTree_Destroy(treeToRemove);
+
+            // Even though this isn't reachable anymore after decrementing count, NULL out for cleanliness
+            treeHandle->children[treeHandle->nChildren - 1] = NULL;
+            treeHandle->nChildren = treeHandle->nChildren - 1;
+
+            result = MULTITREE_OK;
+        }
+    }
+
+    return result;
+}
+
Index: azure_iot_hub_f767zi/trunk/azure_iot_sdk/serializer/src/schema.c
===================================================================
--- azure_iot_hub_f767zi/trunk/azure_iot_sdk/serializer/src/schema.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/azure_iot_sdk/serializer/src/schema.c	(revision 457)
@@ -0,0 +1,3258 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+#include <stdlib.h>
+#include "azure_c_shared_utility/gballoc.h"
+
+#include "schema.h"
+#include "azure_c_shared_utility/crt_abstractions.h"
+#include "azure_c_shared_utility/xlogging.h"
+#include "azure_c_shared_utility/vector.h"
+
+
+MU_DEFINE_ENUM_STRINGS_WITHOUT_INVALID(SCHEMA_RESULT, SCHEMA_RESULT_VALUES);
+
+typedef struct SCHEMA_PROPERTY_HANDLE_DATA_TAG
+{
+    const char* PropertyName;
+    const char* PropertyType;
+} SCHEMA_PROPERTY_HANDLE_DATA;
+
+typedef struct SCHEMA_REPORTED_PROPERTY_HANDLE_DATA_TAG
+{
+    const char* reportedPropertyName;
+    const char* reportedPropertyType;
+} SCHEMA_REPORTED_PROPERTY_HANDLE_DATA;
+
+typedef struct SCHEMA_DESIRED_PROPERTY_HANDLE_DATA_TAG
+{
+    pfOnDesiredProperty onDesiredProperty;
+    pfDesiredPropertyInitialize desiredPropertInitialize;
+    pfDesiredPropertyDeinitialize desiredPropertDeinitialize;
+    const char* desiredPropertyName;
+    const char* desiredPropertyType;
+    pfDesiredPropertyFromAGENT_DATA_TYPE desiredPropertyFromAGENT_DATA_TYPE;
+    size_t offset;
+} SCHEMA_DESIRED_PROPERTY_HANDLE_DATA;
+
+typedef struct SCHEMA_ACTION_ARGUMENT_HANDLE_DATA_TAG
+{
+    const char* Name;
+    const char* Type;
+} SCHEMA_ACTION_ARGUMENT_HANDLE_DATA;
+
+typedef struct SCHEMA_METHOD_ARGUMENT_HANDLE_DATA_TAG
+{
+    char* Name;
+    char* Type;
+} SCHEMA_METHOD_ARGUMENT_HANDLE_DATA;
+
+typedef struct SCHEMA_ACTION_HANDLE_DATA_TAG
+{
+    const char* ActionName;
+    size_t ArgumentCount;
+    SCHEMA_ACTION_ARGUMENT_HANDLE* ArgumentHandles;
+} SCHEMA_ACTION_HANDLE_DATA;
+
+typedef struct SCHEMA_METHOD_HANDLE_DATA_TAG
+{
+    char* methodName;
+    VECTOR_HANDLE methodArguments; /*holds SCHEMA_METHOD_ARGUMENT_HANDLE*/
+} SCHEMA_METHOD_HANDLE_DATA;
+
+typedef struct MODEL_IN_MODEL_TAG
+{
+    pfOnDesiredProperty onDesiredProperty; /*is NULL if not specified or if the model in model is not WITH_DESIRED_PROPERTY*/
+    size_t offset; /*offset of the model in model (offsetof)*/
+    const char* propertyName;
+    SCHEMA_MODEL_TYPE_HANDLE modelHandle;
+} MODEL_IN_MODEL;
+
+typedef struct SCHEMA_MODEL_TYPE_HANDLE_DATA_TAG
+{
+    VECTOR_HANDLE methods; /*holds SCHEMA_METHOD_HANDLE*/
+    VECTOR_HANDLE desiredProperties; /*holds SCHEMA_DESIRED_PROPERTY_HANDLE_DATA*/
+    const char* Name;
+    SCHEMA_HANDLE SchemaHandle;
+    SCHEMA_PROPERTY_HANDLE* Properties;
+    size_t PropertyCount;
+    VECTOR_HANDLE reportedProperties; /*holds SCHEMA_REPORTED_PROPERTY_HANDLE*/
+    SCHEMA_ACTION_HANDLE* Actions;
+    size_t ActionCount;
+    VECTOR_HANDLE models;
+    size_t DeviceCount;
+} SCHEMA_MODEL_TYPE_HANDLE_DATA;
+
+typedef struct SCHEMA_STRUCT_TYPE_HANDLE_DATA_TAG
+{
+    const char* Name;
+    SCHEMA_PROPERTY_HANDLE* Properties;
+    size_t PropertyCount;
+} SCHEMA_STRUCT_TYPE_HANDLE_DATA;
+
+typedef struct SCHEMA_HANDLE_DATA_TAG
+{
+    void* metadata;
+    const char* Namespace;
+    SCHEMA_MODEL_TYPE_HANDLE* ModelTypes;
+    size_t ModelTypeCount;
+    SCHEMA_STRUCT_TYPE_HANDLE* StructTypes;
+    size_t StructTypeCount;
+} SCHEMA_HANDLE_DATA;
+
+static VECTOR_HANDLE g_schemas = NULL;
+
+static void DestroyProperty(SCHEMA_PROPERTY_HANDLE propertyHandle)
+{
+    SCHEMA_PROPERTY_HANDLE_DATA* propertyType = (SCHEMA_PROPERTY_HANDLE_DATA*)propertyHandle;
+    free((void*)propertyType->PropertyName);
+    free((void*)propertyType->PropertyType);
+    free(propertyType);
+}
+
+static void DestroyActionArgument(SCHEMA_ACTION_ARGUMENT_HANDLE actionArgumentHandle)
+{
+    SCHEMA_ACTION_ARGUMENT_HANDLE_DATA* actionArgument = (SCHEMA_ACTION_ARGUMENT_HANDLE_DATA*)actionArgumentHandle;
+    if (actionArgument != NULL)
+    {
+        free((void*)actionArgument->Name);
+        free((void*)actionArgument->Type);
+        free(actionArgument);
+    }
+}
+
+static void DestroyMethodArgument(SCHEMA_METHOD_ARGUMENT_HANDLE methodArgumentHandle)
+{
+    free(methodArgumentHandle->Name);
+    free(methodArgumentHandle->Type);
+    free(methodArgumentHandle);
+}
+
+static void DestroyAction(SCHEMA_ACTION_HANDLE actionHandle)
+{
+    SCHEMA_ACTION_HANDLE_DATA* action = (SCHEMA_ACTION_HANDLE_DATA*)actionHandle;
+    if (action != NULL)
+    {
+        size_t j;
+
+        for (j = 0; j < action->ArgumentCount; j++)
+        {
+            DestroyActionArgument(action->ArgumentHandles[j]);
+        }
+        free(action->ArgumentHandles);
+
+        free((void*)action->ActionName);
+        free(action);
+    }
+}
+
+static void DestroyMethod(SCHEMA_METHOD_HANDLE methodHandle)
+{
+    size_t nArguments = VECTOR_size(methodHandle->methodArguments);
+
+    for (size_t j = 0; j < nArguments; j++)
+    {
+        SCHEMA_METHOD_ARGUMENT_HANDLE* methodArgumentHandle = VECTOR_element(methodHandle->methodArguments, j);
+        DestroyMethodArgument(*methodArgumentHandle);
+    }
+    free(methodHandle->methodName);
+    VECTOR_destroy(methodHandle->methodArguments);
+    free(methodHandle);
+}
+
+static void DestroyMethods(SCHEMA_MODEL_TYPE_HANDLE modelHandle)
+{
+    size_t nMethods = VECTOR_size(modelHandle->methods);
+
+    for (size_t j = 0; j < nMethods; j++)
+    {
+        SCHEMA_METHOD_HANDLE* methodHandle = VECTOR_element(modelHandle->methods, j);
+        DestroyMethod(*methodHandle);
+    }
+    VECTOR_destroy(modelHandle->methods);
+}
+
+
+static void DestroyStruct(SCHEMA_STRUCT_TYPE_HANDLE structTypeHandle)
+{
+    size_t i;
+    SCHEMA_STRUCT_TYPE_HANDLE_DATA* structType = (SCHEMA_STRUCT_TYPE_HANDLE_DATA*)structTypeHandle;
+    if (structType != NULL)
+    {
+        for (i = 0; i < structType->PropertyCount; i++)
+        {
+            DestroyProperty(structType->Properties[i]);
+        }
+        free(structType->Properties);
+
+        free((void*)structType->Name);
+
+        free(structType);
+    }
+}
+
+static void DestroyModel(SCHEMA_MODEL_TYPE_HANDLE modelTypeHandle)
+{
+    SCHEMA_MODEL_TYPE_HANDLE_DATA* modelType = (SCHEMA_MODEL_TYPE_HANDLE_DATA*)modelTypeHandle;
+    size_t i, nReportedProperties;
+
+    free((void*)modelType->Name);
+    modelType->Name = NULL;
+
+    for (i = 0; i < modelType->PropertyCount; i++)
+    {
+        DestroyProperty(modelType->Properties[i]);
+    }
+
+    free(modelType->Properties);
+
+    for (i = 0; i < modelType->ActionCount; i++)
+    {
+        DestroyAction(modelType->Actions[i]);
+    }
+
+    DestroyMethods(modelType);
+
+    /*destroy the vector holding the added models. This does not destroy the said models, however, their names shall be*/
+    for (i = 0; i < VECTOR_size(modelType->models); i++)
+    {
+        MODEL_IN_MODEL* temp = (MODEL_IN_MODEL*)VECTOR_element(modelType->models, i);
+        free((void*)temp->propertyName);
+    }
+
+    nReportedProperties = VECTOR_size(modelType->reportedProperties);
+    for (i = 0;i < nReportedProperties;i++)
+    {
+        SCHEMA_REPORTED_PROPERTY_HANDLE_DATA* reportedProperty = *(SCHEMA_REPORTED_PROPERTY_HANDLE_DATA **)VECTOR_element(modelType->reportedProperties, i);
+        free((void*)reportedProperty->reportedPropertyName);
+        free((void*)reportedProperty->reportedPropertyType);
+        free(reportedProperty);
+    }
+    VECTOR_destroy(modelType->reportedProperties);
+
+    size_t nDesiredProperties = VECTOR_size(modelType->desiredProperties);
+    for (i = 0;i < nDesiredProperties;i++)
+    {
+        SCHEMA_DESIRED_PROPERTY_HANDLE_DATA* desiredProperty = *(SCHEMA_DESIRED_PROPERTY_HANDLE_DATA **)VECTOR_element(modelType->desiredProperties, i);
+        free((void*)desiredProperty->desiredPropertyName);
+        free((void*)desiredProperty->desiredPropertyType);
+        free(desiredProperty);
+    }
+    VECTOR_destroy(modelType->desiredProperties);
+
+    VECTOR_clear(modelType->models);
+    VECTOR_destroy(modelType->models);
+
+    free(modelType->Actions);
+    free(modelType);
+}
+
+static SCHEMA_RESULT AddModelProperty(SCHEMA_MODEL_TYPE_HANDLE_DATA* modelType, const char* name, const char* type)
+{
+    SCHEMA_RESULT result;
+
+    /* Codes_SRS_SCHEMA_99_013:[If any of the arguments is NULL, Schema_AddModelProperty shall return SCHEMA_INVALID_ARG.] */
+    if ((modelType == NULL) ||
+        (name == NULL) ||
+        (type == NULL))
+    {
+        result = SCHEMA_INVALID_ARG;
+        LogError("(result = %s)", MU_ENUM_TO_STRING(SCHEMA_RESULT, result));
+    }
+    else
+    {
+        size_t i;
+
+        /* Codes_SRS_SCHEMA_99_015:[The property name shall be unique per model, if the same property name is added twice to a model, SCHEMA_DUPLICATE_ELEMENT shall be returned.] */
+        for (i = 0; i < modelType->PropertyCount; i++)
+        {
+            SCHEMA_PROPERTY_HANDLE_DATA* property = (SCHEMA_PROPERTY_HANDLE_DATA*)modelType->Properties[i];
+            if (strcmp(property->PropertyName, name) == 0)
+            {
+                break;
+            }
+        }
+
+        if (i < modelType->PropertyCount)
+        {
+            result = SCHEMA_DUPLICATE_ELEMENT;
+            LogError("(result = %s)", MU_ENUM_TO_STRING(SCHEMA_RESULT, result));
+        }
+        else
+        {
+            SCHEMA_PROPERTY_HANDLE* newProperties = (SCHEMA_PROPERTY_HANDLE*)realloc(modelType->Properties, sizeof(SCHEMA_PROPERTY_HANDLE) * (modelType->PropertyCount + 1));
+            if (newProperties == NULL)
+            {
+                /* Codes_SRS_SCHEMA_99_014:[On any other error, Schema_AddModelProperty shall return SCHEMA_ERROR.] */
+                result = SCHEMA_ERROR;
+                LogError("(result = %s)", MU_ENUM_TO_STRING(SCHEMA_RESULT, result));
+            }
+            else
+            {
+                SCHEMA_PROPERTY_HANDLE_DATA* newProperty;
+
+                modelType->Properties = newProperties;
+                if ((newProperty = (SCHEMA_PROPERTY_HANDLE_DATA*)malloc(sizeof(SCHEMA_PROPERTY_HANDLE_DATA))) == NULL)
+                {
+                    /* Codes_SRS_SCHEMA_99_014:[On any other error, Schema_AddModelProperty shall return SCHEMA_ERROR.] */
+                    result = SCHEMA_ERROR;
+                    LogError("(result = %s)", MU_ENUM_TO_STRING(SCHEMA_RESULT, result));
+                }
+                else
+                {
+                    if (mallocAndStrcpy_s((char**)&newProperty->PropertyName, name) != 0)
+                    {
+                        /* Codes_SRS_SCHEMA_99_014:[On any other error, Schema_AddModelProperty shall return SCHEMA_ERROR.] */
+                        free(newProperty);
+                        result = SCHEMA_ERROR;
+                        LogError("(result = %s)", MU_ENUM_TO_STRING(SCHEMA_RESULT, result));
+                    }
+                    else if (mallocAndStrcpy_s((char**)&newProperty->PropertyType, type) != 0)
+                    {
+                        /* Codes_SRS_SCHEMA_99_014:[On any other error, Schema_AddModelProperty shall return SCHEMA_ERROR.] */
+                        free((void*)newProperty->PropertyName);
+                        free(newProperty);
+                        result = SCHEMA_ERROR;
+                        LogError("(result = %s)", MU_ENUM_TO_STRING(SCHEMA_RESULT, result));
+                    }
+                    else
+                    {
+                        modelType->Properties[modelType->PropertyCount] = (SCHEMA_PROPERTY_HANDLE)newProperty;
+                        modelType->PropertyCount++;
+
+                        /* Codes_SRS_SCHEMA_99_012:[On success, Schema_AddModelProperty shall return SCHEMA_OK.] */
+                        result = SCHEMA_OK;
+                    }
+                }
+
+                /* If possible, reduce the memory of over allocation */
+                if (result != SCHEMA_OK)
+                {
+                    if (modelType->PropertyCount > 0)
+                    {
+                        SCHEMA_PROPERTY_HANDLE *oldProperties = (SCHEMA_PROPERTY_HANDLE *)realloc(modelType->Properties, sizeof(SCHEMA_PROPERTY_HANDLE) * modelType->PropertyCount);
+                        if (oldProperties == NULL)
+                        {
+                            result = SCHEMA_ERROR;
+                            LogError("(result = %s)", MU_ENUM_TO_STRING(SCHEMA_RESULT, result));
+                        }
+                        else
+                        {
+                            modelType->Properties = oldProperties;
+                        }
+                    }
+                    else
+                    {
+                        modelType->Properties = NULL;
+                    }
+                }
+            }
+        }
+    }
+
+    return result;
+}
+
+static bool SchemaHandlesMatch(const SCHEMA_HANDLE* handle, const SCHEMA_HANDLE* otherHandle)
+{
+    return (*handle == *otherHandle);
+}
+
+static bool SchemaNamespacesMatch(const SCHEMA_HANDLE* handle, const char* schemaNamespace)
+{
+    const SCHEMA_HANDLE_DATA* schema = (SCHEMA_HANDLE_DATA*)*handle;
+    return (strcmp(schema->Namespace, schemaNamespace) == 0);
+}
+
+/* Codes_SRS_SCHEMA_99_001:[Schema_Create shall initialize a schema with a given namespace.] */
+SCHEMA_HANDLE Schema_Create(const char* schemaNamespace, void* metadata)
+{
+    SCHEMA_HANDLE_DATA* result;
+    /*Codes_SRS_SCHEMA_02_090: [ If metadata is NULL then Schema_Create shall fail and return NULL. ]*/
+    /* Codes_SRS_SCHEMA_99_004:[If schemaNamespace is NULL, Schema_Create shall fail.] */
+    if (
+        (schemaNamespace == NULL)||
+        (metadata == NULL)
+        )
+    {
+        /* Codes_SRS_SCHEMA_99_003:[On failure, NULL shall be returned.] */
+        LogError("invalid arg const char* schemaNamespace=%p, void* metadata=%p",schemaNamespace, metadata);
+        result = NULL;
+    }
+    else
+    {
+        if (g_schemas == NULL && (g_schemas = VECTOR_create(sizeof(SCHEMA_HANDLE_DATA*) ) ) == NULL)
+        {
+            /* Codes_SRS_SCHEMA_99_003:[On failure, NULL shall be returned.] */
+            result = NULL;
+            LogError("(Error code:%s)", MU_ENUM_TO_STRING(SCHEMA_RESULT, SCHEMA_ERROR));
+        }
+        else if ((result = (SCHEMA_HANDLE_DATA*)calloc(1, sizeof(SCHEMA_HANDLE_DATA))) == NULL)
+        {
+            /* Codes_SRS_SCHEMA_99_003:[On failure, NULL shall be returned.] */
+            LogError("(Error code:%s)", MU_ENUM_TO_STRING(SCHEMA_RESULT, SCHEMA_ERROR));
+        }
+        else if (mallocAndStrcpy_s((char**)&result->Namespace, schemaNamespace) != 0)
+        {
+            /* Codes_SRS_SCHEMA_99_003:[On failure, NULL shall be returned.] */
+            free(result);
+            result = NULL;
+            LogError("(Error code:%s)", MU_ENUM_TO_STRING(SCHEMA_RESULT, SCHEMA_ERROR));
+        }
+        else if (VECTOR_push_back(g_schemas, &result, 1) != 0)
+        {
+            free((void*)result->Namespace);
+            free(result);
+            result = NULL;
+            LogError("(Error code:%s)", MU_ENUM_TO_STRING(SCHEMA_RESULT, SCHEMA_ERROR));
+        }
+        else
+        {
+            /* Codes_SRS_SCHEMA_99_002:[On success a non-NULL handle to the newly created schema shall be returned.] */
+            result->ModelTypes = NULL;
+            result->ModelTypeCount = 0;
+            result->StructTypes = NULL;
+            result->StructTypeCount = 0;
+            result->metadata = metadata;
+        }
+    }
+
+    return (SCHEMA_HANDLE)result;
+}
+
+size_t Schema_GetSchemaCount(void)
+{
+    /* Codes_SRS_SCHEMA_99_153: [Schema_GetSchemaCount shall return the number of "active" schemas (all schemas created with Schema_Create
+    in the current process, for which Schema_Destroy has not been called).] */
+    return VECTOR_size(g_schemas);
+}
+
+SCHEMA_HANDLE Schema_GetSchemaByNamespace(const char* schemaNamespace)
+{
+    /* Codes_SRS_SCHEMA_99_151: [If no active schema matches the schemaNamespace argument, Schema_GetSchemaByNamespace shall return NULL.] */
+    SCHEMA_HANDLE result = NULL;
+
+    /* Codes_SRS_SCHEMA_99_150: [If the schemaNamespace argument is NULL, Schema_GetSchemaByNamespace shall return NULL.] */
+    if (schemaNamespace != NULL)
+    {
+        SCHEMA_HANDLE* handle = (g_schemas==NULL)?NULL:(SCHEMA_HANDLE*)VECTOR_find_if(g_schemas, (PREDICATE_FUNCTION)SchemaNamespacesMatch, schemaNamespace);
+        if (handle != NULL)
+        {
+            /* Codes_SRS_SCHEMA_99_148: [Schema_GetSchemaByNamespace shall search all active schemas and return the schema with the
+               namespace given by the schemaNamespace argument.] */
+            result = *handle;
+        }
+    }
+
+    return result;
+}
+
+const char* Schema_GetSchemaNamespace(SCHEMA_HANDLE schemaHandle)
+{
+    const char* result;
+
+    /* Codes_SRS_SCHEMA_99_130: [If the schemaHandle argument is NULL, Schema_GetSchemaNamespace shall return NULL.] */
+    if (schemaHandle == NULL)
+    {
+        result = NULL;
+    }
+    else
+    {
+        /* Codes_SRS_SCHEMA_99_129: [Schema_GetSchemaNamespace shall return the namespace for the schema identified by schemaHandle.] */
+        result = ((SCHEMA_HANDLE_DATA*)schemaHandle)->Namespace;
+    }
+
+    return result;
+}
+
+void Schema_Destroy(SCHEMA_HANDLE schemaHandle)
+{
+    /* Codes_SRS_SCHEMA_99_006:[If the schemaHandle is NULL, Schema_Destroy shall do nothing.] */
+    if (schemaHandle != NULL)
+    {
+        SCHEMA_HANDLE_DATA* schema = (SCHEMA_HANDLE_DATA*)schemaHandle;
+        size_t i;
+
+        /* Codes_SRS_SCHEMA_99_005:[Schema_Destroy shall free all resources associated with a schema.] */
+        for (i = 0; i < schema->ModelTypeCount; i++)
+        {
+            DestroyModel(schema->ModelTypes[i]);
+        }
+
+        free(schema->ModelTypes);
+
+        /* Codes_SRS_SCHEMA_99_005:[Schema_Destroy shall free all resources associated with a schema.] */
+        for (i = 0; i < schema->StructTypeCount; i++)
+        {
+            DestroyStruct(schema->StructTypes[i]);
+        }
+
+        free(schema->StructTypes);
+        free((void*)schema->Namespace);
+        free(schema);
+
+        schema = (SCHEMA_HANDLE_DATA*)VECTOR_find_if(g_schemas, (PREDICATE_FUNCTION)SchemaHandlesMatch, &schemaHandle);
+        if (schema != NULL)
+        {
+            VECTOR_erase(g_schemas, schema, 1);
+        }
+        // If the g_schema is empty then destroy it
+        if (VECTOR_size(g_schemas) == 0)
+        {
+            VECTOR_destroy(g_schemas);
+            g_schemas = NULL;
+        }
+    }
+}
+
+SCHEMA_RESULT Schema_DestroyIfUnused(SCHEMA_MODEL_TYPE_HANDLE modelTypeHandle)
+{
+    SCHEMA_RESULT result;
+
+    /* Codes_SRS_SCHEMA_07_189: [If modelHandle variable is NULL Schema_DestroyIfUnused shall do nothing.] */
+    if (modelTypeHandle != NULL)
+    {
+        SCHEMA_HANDLE schemaHandle = Schema_GetSchemaForModelType(modelTypeHandle);
+        if (schemaHandle == NULL)
+        {
+            result = SCHEMA_ERROR;
+        }
+        else
+        {
+            SCHEMA_HANDLE_DATA* schema = (SCHEMA_HANDLE_DATA*)schemaHandle;
+            size_t nIndex;
+
+            /* Codes_SRS_SCHEMA_07_190: [Schema_DestroyIfUnused shall iterate through the ModuleTypes objects and if all the DeviceCount variables 0 then it will delete the schemaHandle.] */
+            for (nIndex = 0; nIndex < schema->ModelTypeCount; nIndex++)
+            {
+                SCHEMA_MODEL_TYPE_HANDLE_DATA* modelType = (SCHEMA_MODEL_TYPE_HANDLE_DATA*)schema->ModelTypes[nIndex];
+                if (modelType->DeviceCount > 0)
+                    break;
+            }
+            /* Codes_SRS_SCHEMA_07_191: [If 1 or more DeviceCount variables are > 0 then Schema_DestroyIfUnused shall do nothing.] */
+            if (nIndex == schema->ModelTypeCount)
+            {
+                Schema_Destroy(schemaHandle);
+                result = SCHEMA_OK;
+            }
+            else
+            {
+                result = SCHEMA_MODEL_IN_USE;
+            }
+        }
+    }
+    else
+    {
+        result = SCHEMA_INVALID_ARG;
+    }
+    return result;
+}
+
+SCHEMA_RESULT Schema_AddDeviceRef(SCHEMA_MODEL_TYPE_HANDLE modelTypeHandle)
+{
+    SCHEMA_RESULT result;
+    if (modelTypeHandle == NULL)
+    {
+        /* Codes_SRS_SCHEMA_07_187: [Schema_AddDeviceRef shall return SCHEMA_INVALID_ARG if modelTypeHandle is NULL.] */
+        result = SCHEMA_INVALID_ARG;
+        LogError("(Error code:%s)", MU_ENUM_TO_STRING(SCHEMA_RESULT, result));
+    }
+    else
+    {
+        SCHEMA_MODEL_TYPE_HANDLE_DATA* model = (SCHEMA_MODEL_TYPE_HANDLE_DATA*)modelTypeHandle;
+        /* Codes_SRS_SCHEMA_07_188: [If the modelTypeHandle is nonNULL, Schema_AddDeviceRef shall increment the SCHEMA_MODEL_TYPE_HANDLE_DATA DeviceCount variable.] */
+        model->DeviceCount++;
+        result = SCHEMA_OK;
+    }
+    return result;
+}
+
+SCHEMA_RESULT Schema_ReleaseDeviceRef(SCHEMA_MODEL_TYPE_HANDLE modelTypeHandle)
+{
+    SCHEMA_RESULT result;
+    /* Codes_SRS_SCHEMA_07_184: [Schema_DeviceRelease shall do nothing if the supplied modelHandle is NULL.] */
+    if (modelTypeHandle == NULL)
+    {
+        result = SCHEMA_INVALID_ARG;
+        LogError("(Error code:%s)", MU_ENUM_TO_STRING(SCHEMA_RESULT, result));
+    }
+    else
+    {
+        SCHEMA_MODEL_TYPE_HANDLE_DATA* model = (SCHEMA_MODEL_TYPE_HANDLE_DATA*)modelTypeHandle;
+        if (model->DeviceCount > 0)
+        {
+            /* Codes_SRS_SCHEMA_07_186: [On a nonNULL SCHEMA_MODEL_TYPE_HANDLE if the DeviceCount variable is > 0 then the variable will be decremented.] */
+            model->DeviceCount--;
+            result = SCHEMA_OK;
+        }
+        else
+        {
+result = SCHEMA_DEVICE_COUNT_ZERO;
+LogError("(Error code:%s)", MU_ENUM_TO_STRING(SCHEMA_RESULT, result));
+        }
+    }
+    return result;
+}
+
+/* Codes_SRS_SCHEMA_99_007:[Schema_CreateModelType shall create a new model type and return a handle to it.] */
+SCHEMA_MODEL_TYPE_HANDLE Schema_CreateModelType(SCHEMA_HANDLE schemaHandle, const char* modelName)
+{
+    SCHEMA_MODEL_TYPE_HANDLE result;
+
+    /* Codes_SRS_SCHEMA_99_010:[If any of the arguments is NULL, Schema_CreateModelType shall fail.] */
+    if ((schemaHandle == NULL) ||
+        (modelName == NULL))
+    {
+        /* Codes_SRS_SCHEMA_99_009:[On failure, Schema_CreateModelType shall return NULL.] */
+        result = NULL;
+        LogError("(Error code:%s)", MU_ENUM_TO_STRING(SCHEMA_RESULT, SCHEMA_INVALID_ARG));
+    }
+    else
+    {
+        SCHEMA_HANDLE_DATA* schema = (SCHEMA_HANDLE_DATA*)schemaHandle;
+
+        /* Codes_SRS_SCHEMA_99_100: [Schema_CreateModelType shall return SCHEMA_DUPLICATE_ELEMENT if modelName already exists.] */
+        size_t i;
+        for (i = 0; i < schema->ModelTypeCount; i++)
+        {
+            SCHEMA_MODEL_TYPE_HANDLE_DATA* model = (SCHEMA_MODEL_TYPE_HANDLE_DATA*)(schema->ModelTypes[i]);
+            if (strcmp(model->Name, modelName) == 0)
+            {
+                break;
+            }
+        }
+
+        if (i < schema->ModelTypeCount)
+        {
+            /* Codes_SRS_SCHEMA_99_009:[On failure, Schema_CreateModelType shall return NULL.] */
+            result = NULL;
+            LogError("%s Model Name already exists", modelName);
+        }
+
+        else
+        {
+            SCHEMA_MODEL_TYPE_HANDLE* newModelTypes = (SCHEMA_MODEL_TYPE_HANDLE*)realloc(schema->ModelTypes, sizeof(SCHEMA_MODEL_TYPE_HANDLE) * (schema->ModelTypeCount + 1));
+            if (newModelTypes == NULL)
+            {
+                /* Codes_SRS_SCHEMA_99_009:[On failure, Schema_CreateModelType shall return NULL.] */
+                result = NULL;
+                LogError("(Error code:%s)", MU_ENUM_TO_STRING(SCHEMA_RESULT, SCHEMA_ERROR));
+            }
+            else
+            {
+                SCHEMA_MODEL_TYPE_HANDLE_DATA* modelType;
+                schema->ModelTypes = newModelTypes;
+
+                if ((modelType = (SCHEMA_MODEL_TYPE_HANDLE_DATA*)calloc(1, sizeof(SCHEMA_MODEL_TYPE_HANDLE_DATA))) == NULL)
+                {
+
+                    /* Codes_SRS_SCHEMA_99_009:[On failure, Schema_CreateModelType shall return NULL.] */
+                    result = NULL;
+                    LogError("(Error code:%s)", MU_ENUM_TO_STRING(SCHEMA_RESULT, SCHEMA_ERROR));
+                }
+                else if (mallocAndStrcpy_s((char**)&modelType->Name, modelName) != 0)
+                {
+                    /* Codes_SRS_SCHEMA_99_009:[On failure, Schema_CreateModelType shall return NULL.] */
+                    result = NULL;
+                    free(modelType);
+                    LogError("(Error code:%s)", MU_ENUM_TO_STRING(SCHEMA_RESULT, SCHEMA_ERROR));
+                }
+                else
+                {
+                    modelType->models = VECTOR_create(sizeof(MODEL_IN_MODEL));
+                    if (modelType->models == NULL)
+                    {
+                        /* Codes_SRS_SCHEMA_99_009:[On failure, Schema_CreateModelType shall return NULL.] */
+                        LogError("unable to VECTOR_create");
+                        free((void*)modelType->Name);
+                        free((void*)modelType);
+                        result = NULL;
+                    }
+                    else
+                    {
+                        if ((modelType->reportedProperties = VECTOR_create(sizeof(SCHEMA_REPORTED_PROPERTY_HANDLE))) == NULL)
+                        {
+                            /* Codes_SRS_SCHEMA_99_009:[On failure, Schema_CreateModelType shall return NULL.] */
+                            LogError("failed to VECTOR_create (reported properties)");
+                            VECTOR_destroy(modelType->models);
+                            free((void*)modelType->Name);
+                            free((void*)modelType);
+                            result = NULL;
+
+                        }
+                        else
+                        {
+                            /* Codes_SRS_SCHEMA_99_009:[On failure, Schema_CreateModelType shall return NULL.] */
+                            if ((modelType->desiredProperties = VECTOR_create(sizeof(SCHEMA_DESIRED_PROPERTY_HANDLE))) == NULL)
+                            {
+                                LogError("failure in VECTOR_create (desired properties)");
+                                VECTOR_destroy(modelType->reportedProperties);
+                                VECTOR_destroy(modelType->models);
+                                free((void*)modelType->Name);
+                                free((void*)modelType);
+                                result = NULL;
+                            }
+                            else
+                            {
+                                if ((modelType->methods = VECTOR_create(sizeof(SCHEMA_METHOD_HANDLE))) == NULL)
+                                {
+                                    LogError("failure in VECTOR_create (desired properties)");
+                                    VECTOR_destroy(modelType->desiredProperties);
+                                    VECTOR_destroy(modelType->reportedProperties);
+                                    VECTOR_destroy(modelType->models);
+                                    free((void*)modelType->Name);
+                                    free((void*)modelType);
+                                    result = NULL;
+                                }
+                                else
+                                {
+                                    modelType->PropertyCount = 0;
+                                    modelType->Properties = NULL;
+                                    modelType->ActionCount = 0;
+                                    modelType->Actions = NULL;
+                                    modelType->SchemaHandle = schemaHandle;
+                                    modelType->DeviceCount = 0;
+
+                                    schema->ModelTypes[schema->ModelTypeCount] = modelType;
+                                    schema->ModelTypeCount++;
+                                    /* Codes_SRS_SCHEMA_99_008:[On success, a non-NULL handle shall be returned.] */
+                                    result = (SCHEMA_MODEL_TYPE_HANDLE)modelType;
+                                }
+                            }
+                        }
+                    }
+                }
+
+                /* If possible, reduce the memory of over allocation */
+                if ((result == NULL) &&(schema->ModelTypeCount>0))
+                {
+                    SCHEMA_MODEL_TYPE_HANDLE* oldModelTypes = (SCHEMA_MODEL_TYPE_HANDLE*)realloc(schema->ModelTypes, sizeof(SCHEMA_MODEL_TYPE_HANDLE) * schema->ModelTypeCount);
+                    if (oldModelTypes == NULL)
+                    {
+                        LogError("(Error code:%s)", MU_ENUM_TO_STRING(SCHEMA_RESULT, SCHEMA_ERROR));
+                    }
+                    else
+                    {
+                        schema->ModelTypes = oldModelTypes;
+                    }
+                }
+            }
+        }
+    }
+
+    return result;
+}
+
+SCHEMA_HANDLE Schema_GetSchemaForModelType(SCHEMA_MODEL_TYPE_HANDLE modelTypeHandle)
+{
+    SCHEMA_HANDLE result;
+
+    if (modelTypeHandle == NULL)
+    {
+        /* Codes_SRS_SCHEMA_99_132: [If the modelTypeHandle argument is NULL, Schema_GetSchemaForModelType shall return NULL.] */
+        result = NULL;
+    }
+    else
+    {
+        /* Codes_SRS_SCHEMA_99_131: [Schema_GetSchemaForModelType returns the schema handle for a given model type.] */
+        result = ((SCHEMA_MODEL_TYPE_HANDLE_DATA*)modelTypeHandle)->SchemaHandle;
+    }
+
+    return result;
+}
+
+/* Codes_SRS_SCHEMA_99_011:[Schema_AddModelProperty shall add one property to the model type identified by modelTypeHandle.] */
+SCHEMA_RESULT Schema_AddModelProperty(SCHEMA_MODEL_TYPE_HANDLE modelTypeHandle, const char* propertyName, const char* propertyType)
+{
+    return AddModelProperty((SCHEMA_MODEL_TYPE_HANDLE_DATA*)modelTypeHandle, propertyName, propertyType);
+}
+
+static bool reportedPropertyExists(const void* element, const void* value)
+{
+    SCHEMA_REPORTED_PROPERTY_HANDLE_DATA* reportedProperty = *(SCHEMA_REPORTED_PROPERTY_HANDLE_DATA**)element;
+    return (strcmp(reportedProperty->reportedPropertyName, value) == 0);
+}
+
+SCHEMA_RESULT Schema_AddModelReportedProperty(SCHEMA_MODEL_TYPE_HANDLE modelTypeHandle, const char* reportedPropertyName, const char* reportedPropertyType)
+{
+    SCHEMA_RESULT result;
+    /*Codes_SRS_SCHEMA_02_001: [ If modelTypeHandle is NULL then Schema_AddModelReportedProperty shall fail and return SCHEMA_INVALID_ARG. ]*/
+    /*Codes_SRS_SCHEMA_02_002: [ If reportedPropertyName is NULL then Schema_AddModelReportedProperty shall fail and return SCHEMA_INVALID_ARG. ]*/
+    /*Codes_SRS_SCHEMA_02_003: [ If reportedPropertyType is NULL then Schema_AddModelReportedProperty shall fail and return SCHEMA_INVALID_ARG. ]*/
+    if (
+        (modelTypeHandle == NULL) ||
+        (reportedPropertyName == NULL) ||
+        (reportedPropertyType == NULL)
+        )
+    {
+        LogError("invalid argument SCHEMA_MODEL_TYPE_HANDLE modelTypeHandle=%p, const char* reportedPropertyName=%p, const char* reportedPropertyType=%p", modelTypeHandle, reportedPropertyName, reportedPropertyType);
+        result = SCHEMA_INVALID_ARG;
+    }
+    else
+    {
+        SCHEMA_MODEL_TYPE_HANDLE_DATA* modelType = (SCHEMA_MODEL_TYPE_HANDLE_DATA*)modelTypeHandle;
+        /*Codes_SRS_SCHEMA_02_004: [ If reportedPropertyName has already been added then Schema_AddModelReportedProperty shall fail and return SCHEMA_PROPERTY_ELEMENT_EXISTS. ]*/
+        if (VECTOR_find_if(modelType->reportedProperties, reportedPropertyExists, reportedPropertyName) != NULL)
+        {
+            LogError("unable to add reportedProperty %s because it already exists", reportedPropertyName);
+            result = SCHEMA_DUPLICATE_ELEMENT;
+        }
+        else
+        {
+            /*Codes_SRS_SCHEMA_02_005: [ Schema_AddModelReportedProperty shall record reportedPropertyName and reportedPropertyType. ]*/
+            SCHEMA_REPORTED_PROPERTY_HANDLE_DATA* reportedProperty = (SCHEMA_REPORTED_PROPERTY_HANDLE_DATA*)malloc(sizeof(SCHEMA_REPORTED_PROPERTY_HANDLE_DATA));
+            if (reportedProperty == NULL)
+            {
+                /*Codes_SRS_SCHEMA_02_006: [ If any error occurs then Schema_AddModelReportedProperty shall fail and return SCHEMA_ERROR. ]*/
+                LogError("unable to malloc");
+                result = SCHEMA_ERROR;
+            }
+            else
+            {
+                if (mallocAndStrcpy_s((char**)&reportedProperty->reportedPropertyName, reportedPropertyName) != 0)
+                {
+                    /*Codes_SRS_SCHEMA_02_006: [ If any error occurs then Schema_AddModelReportedProperty shall fail and return SCHEMA_ERROR. ]*/
+                    LogError("unable to mallocAndStrcpy_s");
+                    free(reportedProperty);
+                    result = SCHEMA_ERROR;
+                }
+                else
+                {
+                    if (mallocAndStrcpy_s((char**)&reportedProperty->reportedPropertyType, reportedPropertyType) != 0)
+                    {
+                        /*Codes_SRS_SCHEMA_02_006: [ If any error occurs then Schema_AddModelReportedProperty shall fail and return SCHEMA_ERROR. ]*/
+                        LogError("unable to mallocAndStrcpy_s");
+                        free((void*)reportedProperty->reportedPropertyName);
+                        free(reportedProperty);
+                        result = SCHEMA_ERROR;
+                    }
+                    else
+                    {
+                        if (VECTOR_push_back(modelType->reportedProperties, &reportedProperty, 1) != 0)
+                        {
+                            /*Codes_SRS_SCHEMA_02_006: [ If any error occurs then Schema_AddModelReportedProperty shall fail and return SCHEMA_ERROR. ]*/
+                            LogError("unable to VECTOR_push_back");
+                            free((void*)reportedProperty->reportedPropertyType);
+                            free((void*)reportedProperty->reportedPropertyName);
+                            free(reportedProperty);
+                            result = SCHEMA_ERROR;
+                        }
+                        else
+                        {
+                            /*Codes_SRS_SCHEMA_02_007: [ Otherwise Schema_AddModelReportedProperty shall succeed and return SCHEMA_OK. ]*/
+                            result = SCHEMA_OK;
+                        }
+                    }
+                }
+            }
+        }
+    }
+    return result;
+}
+
+SCHEMA_ACTION_HANDLE Schema_CreateModelAction(SCHEMA_MODEL_TYPE_HANDLE modelTypeHandle, const char* actionName)
+{
+    SCHEMA_ACTION_HANDLE result;
+
+    /* Codes_SRS_SCHEMA_99_104: [If any of the modelTypeHandle or actionName arguments is NULL, Schema_CreateModelAction shall return NULL.] */
+    if ((modelTypeHandle == NULL) ||
+        (actionName == NULL))
+    {
+        result = NULL;
+        LogError("(Error code:%s)", MU_ENUM_TO_STRING(SCHEMA_RESULT, SCHEMA_INVALID_ARG));
+    }
+    else
+    {
+        SCHEMA_MODEL_TYPE_HANDLE_DATA* modelType = (SCHEMA_MODEL_TYPE_HANDLE_DATA*)modelTypeHandle;
+        size_t i;
+
+        /* Codes_SRS_SCHEMA_99_105: [The action name shall be unique per model, if the same action name is added twice to a model, Schema_CreateModelAction shall return NULL.] */
+        for (i = 0; i < modelType->ActionCount; i++)
+        {
+            SCHEMA_ACTION_HANDLE_DATA* action = (SCHEMA_ACTION_HANDLE_DATA*)modelType->Actions[i];
+            if (strcmp(action->ActionName, actionName) == 0)
+            {
+                break;
+            }
+        }
+
+        if (i < modelType->ActionCount)
+        {
+            result = NULL;
+            LogError("(Error code:%s)", MU_ENUM_TO_STRING(SCHEMA_RESULT, SCHEMA_DUPLICATE_ELEMENT));
+        }
+        else
+        {
+            /* Codes_SRS_SCHEMA_99_102: [Schema_CreateModelAction shall add one action to the model type identified by modelTypeHandle.] */
+            SCHEMA_ACTION_HANDLE* newActions = (SCHEMA_ACTION_HANDLE*)realloc(modelType->Actions, sizeof(SCHEMA_ACTION_HANDLE) * (modelType->ActionCount + 1));
+            if (newActions == NULL)
+            {
+                /* Codes_SRS_SCHEMA_99_106: [On any other error, Schema_CreateModelAction shall return NULL.]*/
+                result = NULL;
+                LogError("(Error code:%s)", MU_ENUM_TO_STRING(SCHEMA_RESULT, SCHEMA_ERROR));
+            }
+            else
+            {
+                SCHEMA_ACTION_HANDLE_DATA* newAction;
+                modelType->Actions = newActions;
+
+                /* Codes_SRS_SCHEMA_99_103: [On success, Schema_CreateModelAction shall return a none-NULL SCHEMA_ACTION_HANDLE to the newly created action.] */
+                if ((newAction = (SCHEMA_ACTION_HANDLE_DATA*)calloc(1, sizeof(SCHEMA_ACTION_HANDLE_DATA))) == NULL)
+                {
+                    /* Codes_SRS_SCHEMA_99_106: [On any other error, Schema_CreateModelAction shall return NULL.]*/
+                    result = NULL;
+                    LogError("(Error code:%s)", MU_ENUM_TO_STRING(SCHEMA_RESULT, SCHEMA_ERROR));
+                }
+                else
+                {
+                    if (mallocAndStrcpy_s((char**)&newAction->ActionName, actionName) != 0)
+                    {
+                        /* Codes_SRS_SCHEMA_99_106: [On any other error, Schema_CreateModelAction shall return NULL.]*/
+                        free(newAction);
+                        result = NULL;
+                        LogError("(Error code:%s)", MU_ENUM_TO_STRING(SCHEMA_RESULT, SCHEMA_ERROR));
+                    }
+                    else
+                    {
+                        newAction->ArgumentCount = 0;
+                        newAction->ArgumentHandles = NULL;
+
+                        modelType->Actions[modelType->ActionCount] = newAction;
+                        modelType->ActionCount++;
+                        result = (SCHEMA_ACTION_HANDLE)(newAction);
+                    }
+
+                    /* If possible, reduce the memory of over allocation */
+                    if (result == NULL)
+                    {
+                        if (modelType->ActionCount > 0)
+                        {
+                            SCHEMA_ACTION_HANDLE *oldActions = (SCHEMA_ACTION_HANDLE *)realloc(modelType->Actions, sizeof(SCHEMA_ACTION_HANDLE) * modelType->ActionCount);
+                            if (oldActions == NULL)
+                            {
+                                LogError("(Error code:%s)", MU_ENUM_TO_STRING(SCHEMA_RESULT, SCHEMA_ERROR));
+                            }
+                            else
+                            {
+                                modelType->Actions = oldActions;
+                            }
+                        }
+                        else
+                        {
+                            modelType->Actions = NULL;
+                        }
+                    }
+                }
+            }
+        }
+    }
+    return result;
+}
+
+
+static bool methodExists(const void* element, const void* value)
+{
+    const SCHEMA_METHOD_HANDLE* method = (const SCHEMA_METHOD_HANDLE*)element;
+    return (strcmp((*method)->methodName, value) == 0);
+}
+
+
+SCHEMA_METHOD_HANDLE Schema_CreateModelMethod(SCHEMA_MODEL_TYPE_HANDLE modelTypeHandle, const char* methodName)
+{
+    SCHEMA_METHOD_HANDLE result;
+
+    /*Codes_SRS_SCHEMA_02_096: [ If modelTypeHandle is NULL then Schema_CreateModelMethod shall fail and return NULL. ]*/
+    /*Codes_SRS_SCHEMA_02_097: [ If methodName is NULL then Schema_CreateModelMethod shall fail and return NULL. ]*/
+    if ((modelTypeHandle == NULL) ||
+        (methodName == NULL))
+    {
+        result = NULL;
+        LogError("invalid argument: SCHEMA_MODEL_TYPE_HANDLE modelTypeHandle=%p, const char* methodName=%p", modelTypeHandle, methodName);
+    }
+    else
+    {
+        /*Codes_SRS_SCHEMA_02_103: [ If methodName already exists, then Schema_CreateModelMethod shall fail and return NULL. ]*/
+        if (VECTOR_find_if(modelTypeHandle->methods, methodExists, methodName) != NULL)
+        {
+            LogError("method %s already exists", methodName);
+            result = NULL;
+        }
+        else
+        {
+            /*Codes_SRS_SCHEMA_02_098: [ Schema_CreateModelMethod shall allocate the space for the method. ]*/
+            result = malloc(sizeof(SCHEMA_METHOD_HANDLE_DATA));
+            if (result == NULL)
+            {
+                LogError("failed to malloc");
+                /*Codes_SRS_SCHEMA_02_102: [ If any of the above fails, then Schema_CreateModelMethod shall fail and return NULL. ]*/
+                /*return as is*/
+            }
+            else
+            {
+                /*Codes_SRS_SCHEMA_02_099: [ Schema_CreateModelMethod shall create a VECTOR that will hold the method's arguments. ]*/
+                result->methodArguments = VECTOR_create(sizeof(SCHEMA_METHOD_ARGUMENT_HANDLE));
+                if (result->methodArguments == NULL)
+                {
+                    /*Codes_SRS_SCHEMA_02_102: [ If any of the above fails, then Schema_CreateModelMethod shall fail and return NULL. ]*/
+                    LogError("failure in VECTOR_create");
+                    free(result);
+                    result = NULL;
+                }
+                else
+                {
+                    /*Codes_SRS_SCHEMA_02_100: [ Schema_CreateModelMethod shall clone methodName ]*/
+                    if (mallocAndStrcpy_s(&result->methodName, methodName) != 0)
+                    {
+                        /*Codes_SRS_SCHEMA_02_102: [ If any of the above fails, then Schema_CreateModelMethod shall fail and return NULL. ]*/
+                        LogError("failure in mallocAndStrcpy_s");
+                        VECTOR_destroy(result->methodArguments);
+                        free(result);
+                        result = NULL;
+                    }
+                    else
+                    {
+                        /*Codes_SRS_SCHEMA_02_101: [ Schema_CreateModelMethod shall add the new created method to the model's list of methods. ]*/
+                        if (VECTOR_push_back(modelTypeHandle->methods, &result, 1) != 0)
+                        {
+                            /*Codes_SRS_SCHEMA_02_102: [ If any of the above fails, then Schema_CreateModelMethod shall fail and return NULL. ]*/
+                            LogError("failure in VECTOR_push_back");
+                            free(result->methodName);
+                            VECTOR_destroy(result->methodArguments);
+                            free(result);
+                            result = NULL;
+                        }
+                        else
+                        {
+                            /*Codes_SRS_SCHEMA_02_104: [ Otherwise, Schema_CreateModelMethod shall succeed and return a non-NULL SCHEMA_METHOD_HANDLE. ]*/
+                            /*return as is*/
+                        }
+                    }
+                }
+            }
+        }
+    }
+    return result;
+}
+
+
+SCHEMA_RESULT Schema_AddModelActionArgument(SCHEMA_ACTION_HANDLE actionHandle, const char* argumentName, const char* argumentType)
+{
+    SCHEMA_RESULT result;
+
+    /* Codes_SRS_SCHEMA_99_109: [If any of the arguments is NULL, Schema_AddModelActionArgument shall return SCHEMA_INVALID_ARG.] */
+    if ((actionHandle == NULL) ||
+        (argumentName == NULL) ||
+        (argumentType == NULL))
+    {
+        result = SCHEMA_INVALID_ARG;
+        LogError("(result = %s)", MU_ENUM_TO_STRING(SCHEMA_RESULT, result));
+    }
+    else
+    {
+        SCHEMA_ACTION_HANDLE_DATA* action = (SCHEMA_ACTION_HANDLE_DATA*)actionHandle;
+
+        /* Codes_SRS_SCHEMA_99_110: [The argument name shall be unique per action, if the same name is added twice to an action, SCHEMA_DUPLICATE_ELEMENT shall be returned.] */
+        /* Codes_SRS_SCHEMA_99_111: [Schema_AddModelActionArgument shall accept arguments with different names of the same type.]  */
+        size_t i;
+        for (i = 0; i < action->ArgumentCount; i++)
+        {
+            SCHEMA_ACTION_ARGUMENT_HANDLE_DATA* actionArgument = (SCHEMA_ACTION_ARGUMENT_HANDLE_DATA*)action->ArgumentHandles[i];
+            if (strcmp((actionArgument->Name), argumentName) == 0)
+            {
+                break;
+            }
+        }
+
+        if (i < action->ArgumentCount)
+        {
+            result = SCHEMA_DUPLICATE_ELEMENT;
+            LogError("(result = %s)", MU_ENUM_TO_STRING(SCHEMA_RESULT, result));
+        }
+        else
+        {
+            /* Codes_SRS_SCHEMA_99_107: [Schema_AddModelActionArgument shall add one argument name & type to an action identified by actionHandle.]  */
+            SCHEMA_ACTION_ARGUMENT_HANDLE* newArguments = (SCHEMA_ACTION_ARGUMENT_HANDLE*)realloc(action->ArgumentHandles, sizeof(SCHEMA_ACTION_ARGUMENT_HANDLE) * (action->ArgumentCount + 1));
+            if (newArguments == NULL)
+            {
+                /* Codes_SRS_SCHEMA_99_112: [On any other error, Schema_ AddModelActionArgumet shall return SCHEMA_ERROR.] */
+                result = SCHEMA_ERROR;
+                LogError("(result = %s)", MU_ENUM_TO_STRING(SCHEMA_RESULT, result));
+            }
+            else
+            {
+                action->ArgumentHandles = newArguments;
+
+                SCHEMA_ACTION_ARGUMENT_HANDLE_DATA* newActionArgument;
+
+                action->ArgumentHandles = newArguments;
+                if ((newActionArgument = (SCHEMA_ACTION_ARGUMENT_HANDLE_DATA*)malloc(sizeof(SCHEMA_ACTION_ARGUMENT_HANDLE_DATA))) == NULL)
+                {
+                    /* Codes_SRS_SCHEMA_99_112: [On any other error, Schema_ AddModelActionArgumet shall return SCHEMA_ERROR.] */
+                    result = SCHEMA_ERROR;
+                    LogError("(result = %s)", MU_ENUM_TO_STRING(SCHEMA_RESULT, result));
+                }
+                else
+                {
+                    if (mallocAndStrcpy_s((char**)&newActionArgument->Name, argumentName) != 0)
+                    {
+                        /* Codes_SRS_SCHEMA_99_112: [On any other error, Schema_ AddModelActionArgumet shall return SCHEMA_ERROR.] */
+                        free(newActionArgument);
+                        result = SCHEMA_ERROR;
+                        LogError("(result = %s)", MU_ENUM_TO_STRING(SCHEMA_RESULT, result));
+                    }
+                    else if (mallocAndStrcpy_s((char**)&newActionArgument->Type, argumentType) != 0)
+                    {
+                        /* Codes_SRS_SCHEMA_99_112: [On any other error, Schema_ AddModelActionArgumet shall return SCHEMA_ERROR.] */
+                        free((void*)newActionArgument->Name);
+                        free(newActionArgument);
+                        result = SCHEMA_ERROR;
+                        LogError("(result = %s)", MU_ENUM_TO_STRING(SCHEMA_RESULT, result));
+                    }
+                    else
+                    {
+                        /* Codes_SRS_SCHEMA_99_119: [Schema_AddModelActionArgument shall preserve the order of the action arguments according to the order in which they were added, starting with index 0 for the first added argument.] */
+                        action->ArgumentHandles[action->ArgumentCount] = newActionArgument;
+                        action->ArgumentCount++;
+
+                        /* Codes_SRS_SCHEMA_99_108: [On success, Schema_AddModelActionArgunent shall return SCHEMA_OK.] */
+                        result = SCHEMA_OK;
+                    }
+                }
+
+                /* If possible, reduce the memory of over allocation */
+                if (result == SCHEMA_ERROR)
+                {
+                    if (action->ArgumentCount > 0)
+                    {
+                        SCHEMA_ACTION_ARGUMENT_HANDLE *oldArguments = (SCHEMA_ACTION_ARGUMENT_HANDLE *)realloc(action->ArgumentHandles, sizeof(SCHEMA_ACTION_ARGUMENT_HANDLE) * action->ArgumentCount);
+                        if (oldArguments == NULL)
+                        {
+                            LogError("(result = %s)", MU_ENUM_TO_STRING(SCHEMA_RESULT, SCHEMA_ERROR));
+                        }
+                        else
+                        {
+                            action->ArgumentHandles = oldArguments;
+                        }
+                    }
+                    else
+                    {
+                        action->ArgumentHandles = NULL;
+                    }
+                }
+            }
+        }
+    }
+    return result;
+}
+
+static bool methodFindArgumentByBame(const void* element, const void* value)
+{
+    /*element is a pointer to SCHEMA_METHOD_ARGUMENT_HANDLE*/
+    const SCHEMA_METHOD_ARGUMENT_HANDLE* decodedElement = (const SCHEMA_METHOD_ARGUMENT_HANDLE*)element;
+    const char* name = (const char*)value;
+    return (strcmp((*decodedElement)->Name, name) == 0);
+}
+
+SCHEMA_RESULT Schema_AddModelMethodArgument(SCHEMA_METHOD_HANDLE methodHandle, const char* argumentName, const char* argumentType)
+{
+    SCHEMA_RESULT result;
+    /*Codes_SRS_SCHEMA_02_105: [ If methodHandle is NULL then Schema_AddModelMethodArgument shall fail and return SCHEMA_INVALID_ARG. ]*/
+    /*Codes_SRS_SCHEMA_02_106: [ If argumentName is NULL then Schema_AddModelMethodArgument shall fail and return SCHEMA_INVALID_ARG. ]*/
+    /*Codes_SRS_SCHEMA_02_107: [ If argumentType is NULL then Schema_AddModelMethodArgument shall fail and return SCHEMA_INVALID_ARG. ]*/
+    if ((methodHandle == NULL) ||
+        (argumentName == NULL) ||
+        (argumentType == NULL))
+    {
+        result = SCHEMA_INVALID_ARG;
+        LogError("(result = %s)", MU_ENUM_TO_STRING(SCHEMA_RESULT, result));
+    }
+    else
+    {
+        /*Codes_SRS_SCHEMA_02_108: [ If argumentName already exists in the list of arguments then then Schema_AddModelMethodArgument shall fail and return SCHEMA_INVALID_ARG. ]*/
+        if (VECTOR_find_if(methodHandle->methodArguments, methodFindArgumentByBame, argumentName) != NULL)
+        {
+            LogError("an argument with name %s already exists", argumentName);
+            result = SCHEMA_INVALID_ARG;
+        }
+        else
+        {
+            /*Codes_SRS_SCHEMA_02_109: [ Schema_AddModelMethodArgument shall allocate memory for the new argument. ]*/
+            SCHEMA_METHOD_ARGUMENT_HANDLE_DATA* argument = malloc(sizeof(SCHEMA_METHOD_ARGUMENT_HANDLE_DATA));
+            if (argument == NULL)
+            {
+                /*Codes_SRS_SCHEMA_02_113: [ If any of the above operations fails, then Schema_AddModelMethodArgument shall fail and return SCHEMA_ERROR. ]*/
+                LogError("failure to malloc");
+                result = SCHEMA_ERROR;
+            }
+            else
+            {
+                /*Codes_SRS_SCHEMA_02_110: [ Schema_AddModelMethodArgument shall clone methodHandle. ]*/
+                if (mallocAndStrcpy_s(&argument->Name, argumentName) != 0)
+                {
+                    /*Codes_SRS_SCHEMA_02_113: [ If any of the above operations fails, then Schema_AddModelMethodArgument shall fail and return SCHEMA_ERROR. ]*/
+                    LogError("failure in mallocAndStrcpy_s");
+                    free(argument);
+                    result = SCHEMA_ERROR;
+                }
+                else
+                {
+                    /*Codes_SRS_SCHEMA_02_111: [ Schema_AddModelMethodArgument shall clone argumentType. ]*/
+                    if (mallocAndStrcpy_s(&argument->Type, argumentType) != 0)
+                    {
+                        /*Codes_SRS_SCHEMA_02_113: [ If any of the above operations fails, then Schema_AddModelMethodArgument shall fail and return SCHEMA_ERROR. ]*/
+                        LogError("failure in mallocAndStrcpy_s");
+                        free(argument->Name);
+                        free(argument);
+                        result = SCHEMA_ERROR;
+                    }
+                    else
+                    {
+                        /*Codes_SRS_SCHEMA_02_112: [ Schema_AddModelMethodArgument shall add the created argument to the method's list of arguments. ]*/
+                        if (VECTOR_push_back(methodHandle->methodArguments, &argument, 1) != 0)
+                        {
+                            /*Codes_SRS_SCHEMA_02_113: [ If any of the above operations fails, then Schema_AddModelMethodArgument shall fail and return SCHEMA_ERROR. ]*/
+                            LogError("failure in VECTOR_push_back");
+                            free(argument->Name);
+                            free(argument->Type);
+                            free(argument);
+                            result = SCHEMA_ERROR;
+                        }
+                        else
+                        {
+                            /*Codes_SRS_SCHEMA_02_114: [ Otherwise, Schema_AddModelMethodArgument shall succeed and return SCHEMA_OK. ]*/
+                            result = SCHEMA_OK;
+                        }
+                    }
+                }
+            }
+        }
+    }
+    return result;
+}
+
+SCHEMA_PROPERTY_HANDLE Schema_GetModelPropertyByName(SCHEMA_MODEL_TYPE_HANDLE modelTypeHandle, const char* propertyName)
+{
+    SCHEMA_PROPERTY_HANDLE result;
+
+    /* Codes_SRS_SCHEMA_99_038:[Schema_GetModelPropertyByName shall return NULL if unable to find a matching property or if any of the arguments are NULL.] */
+    if ((modelTypeHandle == NULL) ||
+        (propertyName == NULL))
+    {
+        result = NULL;
+        LogError("(Error code:%s)", MU_ENUM_TO_STRING(SCHEMA_RESULT, SCHEMA_INVALID_ARG));
+    }
+    else
+    {
+        size_t i;
+        SCHEMA_MODEL_TYPE_HANDLE_DATA* modelType = (SCHEMA_MODEL_TYPE_HANDLE_DATA*)modelTypeHandle;
+
+        /* Codes_SRS_SCHEMA_99_036:[Schema_GetModelPropertyByName shall return a non-NULL SCHEMA_PROPERTY_HANDLE corresponding to the model type identified by modelTypeHandle and matching the propertyName argument value.] */
+        for (i = 0; i < modelType->PropertyCount; i++)
+        {
+            SCHEMA_PROPERTY_HANDLE_DATA* modelProperty = (SCHEMA_PROPERTY_HANDLE_DATA*)modelType->Properties[i];
+            if (strcmp(modelProperty->PropertyName, propertyName) == 0)
+            {
+                break;
+            }
+        }
+
+        if (i == modelType->PropertyCount)
+        {
+            /* Codes_SRS_SCHEMA_99_038:[Schema_GetModelPropertyByName shall return NULL if unable to find a matching property or if any of the arguments are NULL.] */
+            result = NULL;
+            LogError("(Error code:%s)", MU_ENUM_TO_STRING(SCHEMA_RESULT, SCHEMA_ELEMENT_NOT_FOUND));
+        }
+        else
+        {
+            result = (SCHEMA_PROPERTY_HANDLE)(modelType->Properties[i]);
+        }
+    }
+
+    return result;
+}
+
+SCHEMA_RESULT Schema_GetModelPropertyCount(SCHEMA_MODEL_TYPE_HANDLE modelTypeHandle, size_t* propertyCount)
+{
+    SCHEMA_RESULT result;
+
+    /* Codes_SRS_SCHEMA_99_092: [Schema_GetModelPropertyCount shall return SCHEMA_INVALID_ARG if any of the arguments is NULL.] */
+    if ((modelTypeHandle == NULL) ||
+        (propertyCount == NULL))
+    {
+        result = SCHEMA_INVALID_ARG;
+    }
+    else
+    {
+        /* Codes_SRS_SCHEMA_99_089: [Schema_GetModelPropertyCount shall provide the number of properties defined in the model type identified by modelTypeHandle.] */
+        SCHEMA_MODEL_TYPE_HANDLE_DATA* modelType = (SCHEMA_MODEL_TYPE_HANDLE_DATA*)modelTypeHandle;
+
+        /* Codes_SRS_SCHEMA_99_090: [The count shall be provided via the out argument propertyCount.]*/
+        *propertyCount = modelType->PropertyCount;
+
+        /* Codes_SRS_SCHEMA_99_091: [On success, Schema_GetModelPropertyCount shall return SCHEMA_OK.] */
+        result = SCHEMA_OK;
+    }
+
+    return result;
+}
+
+SCHEMA_RESULT Schema_GetModelReportedPropertyCount(SCHEMA_MODEL_TYPE_HANDLE modelTypeHandle, size_t* reportedPropertyCount)
+{
+    SCHEMA_RESULT result;
+    /*Codes_SRS_SCHEMA_02_008: [ If parameter modelTypeHandle is NULL then Schema_GetModelReportedPropertyCount shall fail and return SCHEMA_INVALID_ARG. ]*/
+    /*Codes_SRS_SCHEMA_02_009: [ If parameter reportedPropertyCount is NULL then Schema_GetModelReportedPropertyCount shall fail and return SCHEMA_INVALID_ARG. ]*/
+    if (
+        (modelTypeHandle == NULL)||
+        (reportedPropertyCount==NULL)
+        )
+    {
+        LogError("SCHEMA_MODEL_TYPE_HANDLE modelTypeHandle=%p, size_t* reportedPropertyCount=%p", modelTypeHandle, reportedPropertyCount);
+        result = SCHEMA_INVALID_ARG;
+    }
+    else
+    {
+        /*Codes_SRS_SCHEMA_02_010: [ Schema_GetModelReportedPropertyCount shall provide in reportedPropertyCount the number of reported properties and return SCHEMA_OK. ]*/
+        SCHEMA_MODEL_TYPE_HANDLE_DATA* modelType = (SCHEMA_MODEL_TYPE_HANDLE_DATA*)modelTypeHandle;
+        *reportedPropertyCount = VECTOR_size(modelType->reportedProperties);
+        result = SCHEMA_OK;
+    }
+    return result;
+}
+
+SCHEMA_REPORTED_PROPERTY_HANDLE Schema_GetModelReportedPropertyByName(SCHEMA_MODEL_TYPE_HANDLE modelTypeHandle, const char* reportedPropertyName)
+{
+    SCHEMA_REPORTED_PROPERTY_HANDLE result;
+    /*Codes_SRS_SCHEMA_02_011: [ If argument modelTypeHandle is NULL then Schema_GetModelReportedPropertyByName shall fail and return NULL. ]*/
+    /*Codes_SRS_SCHEMA_02_012: [ If argument reportedPropertyName is NULL then Schema_GetModelReportedPropertyByName shall fail and return NULL. ]*/
+    if(
+        (modelTypeHandle == NULL) ||
+        (reportedPropertyName == NULL)
+        )
+    {
+        LogError("invalid argument SCHEMA_MODEL_TYPE_HANDLE modelTypeHandle=%p, const char* reportedPropertyName=%p", modelTypeHandle, reportedPropertyName);
+        result = NULL;
+    }
+    else
+    {
+        SCHEMA_MODEL_TYPE_HANDLE_DATA* modelType = (SCHEMA_MODEL_TYPE_HANDLE_DATA*)modelTypeHandle;
+        /*Codes_SRS_SCHEMA_02_013: [ If reported property by the name reportedPropertyName exists then Schema_GetModelReportedPropertyByName shall succeed and return a non-NULL value. ]*/
+        /*Codes_SRS_SCHEMA_02_014: [ Otherwise Schema_GetModelReportedPropertyByName shall fail and return NULL. ]*/
+        if((result = VECTOR_find_if(modelType->reportedProperties, reportedPropertyExists, reportedPropertyName))==NULL)
+        {
+            LogError("a reported property with name \"%s\" does not exist", reportedPropertyName);
+        }
+        else
+        {
+            /*return as is*/
+        }
+    }
+    return result;
+}
+
+SCHEMA_REPORTED_PROPERTY_HANDLE Schema_GetModelReportedPropertyByIndex(SCHEMA_MODEL_TYPE_HANDLE modelTypeHandle, size_t index)
+{
+    SCHEMA_REPORTED_PROPERTY_HANDLE result;
+    /*Codes_SRS_SCHEMA_02_015: [ If argument modelTypeHandle is NULL then Schema_GetModelReportedPropertyByIndex shall fail and return NULL. ]*/
+    if (modelTypeHandle == NULL)
+    {
+        LogError("invalid argument SCHEMA_MODEL_TYPE_HANDLE modelTypeHandle=%p, size_t index=%lu", modelTypeHandle, (unsigned long)index);
+        result = NULL;
+    }
+    else
+    {
+        SCHEMA_MODEL_TYPE_HANDLE_DATA* modelType = (SCHEMA_MODEL_TYPE_HANDLE_DATA*)modelTypeHandle;
+
+        /*Codes_SRS_SCHEMA_02_016: [ If a reported property with index equal to index exists then Schema_GetModelReportedPropertyByIndex shall succeed and return the non-NULL handle of that REPORTED_PROPERTY. ]*/
+        /*Codes_SRS_SCHEMA_02_017: [ Otherwise Schema_GetModelReportedPropertyByIndex shall fail and return NULL. ]*/
+        if ((result = VECTOR_element(modelType->reportedProperties, index)) == NULL)
+        {
+            LogError("index %lu is invalid", (unsigned long)index);
+        }
+        else
+        {
+            /*return as is*/
+        }
+    }
+    return result;
+}
+
+SCHEMA_PROPERTY_HANDLE Schema_GetModelPropertyByIndex(SCHEMA_MODEL_TYPE_HANDLE modelTypeHandle, size_t index)
+{
+    SCHEMA_PROPERTY_HANDLE result;
+    SCHEMA_MODEL_TYPE_HANDLE_DATA* modelType = (SCHEMA_MODEL_TYPE_HANDLE_DATA*)modelTypeHandle;
+
+    /* Codes_SRS_SCHEMA_99_094: [Schema_GetModelProperty shall return NULL if the index specified is outside the valid range or if modelTypeHandle argument is NULL.] */
+    if ((modelTypeHandle == NULL) ||
+        (index >= modelType->PropertyCount))
+    {
+        result = NULL;
+        LogError("(Error code: %s)", MU_ENUM_TO_STRING(SCHEMA_RESULT, SCHEMA_INVALID_ARG));
+    }
+    else
+    {
+        /* Tests_SRS_SCHEMA_99_093: [Schema_GetModelProperty shall return a non-NULL SCHEMA_PROPERTY_HANDLE corresponding to the model type identified by modelTypeHandle and matching the index number provided by the index argument.] */
+        /* Codes_SRS_SCHEMA_99_097: [index is zero based, and the order in which actions were added shall be the index in which they will be retrieved.] */
+        result = modelType->Properties[index];
+    }
+
+    return result;
+}
+
+SCHEMA_ACTION_HANDLE Schema_GetModelActionByName(SCHEMA_MODEL_TYPE_HANDLE modelTypeHandle, const char* actionName)
+{
+    SCHEMA_ACTION_HANDLE result;
+
+    /* Codes_SRS_SCHEMA_99_041:[Schema_GetModelActionByName shall return NULL if unable to find a matching action, if any of the arguments are NULL.] */
+    if ((modelTypeHandle == NULL) ||
+        (actionName == NULL))
+    {
+        result = NULL;
+        LogError("(Error code:%s)", MU_ENUM_TO_STRING(SCHEMA_RESULT, SCHEMA_INVALID_ARG));
+    }
+    else
+    {
+        size_t i;
+        SCHEMA_MODEL_TYPE_HANDLE_DATA* modelType = (SCHEMA_MODEL_TYPE_HANDLE_DATA*)modelTypeHandle;
+
+        /* Codes_SRS_SCHEMA_99_040:[Schema_GetModelActionByName shall return a non-NULL SCHEMA_ACTION_HANDLE corresponding to the model type identified by modelTypeHandle and matching the actionName argument value.] */
+        for (i = 0; i < modelType->ActionCount; i++)
+        {
+            SCHEMA_ACTION_HANDLE_DATA* modelAction = (SCHEMA_ACTION_HANDLE_DATA*)modelType->Actions[i];
+            if (strcmp(modelAction->ActionName, actionName) == 0)
+            {
+                break;
+            }
+        }
+
+        if (i == modelType->ActionCount)
+        {
+            /* Codes_SRS_SCHEMA_99_041:[Schema_GetModelActionByName shall return NULL if unable to find a matching action, if any of the arguments are NULL.] */
+            result = NULL;
+            LogError("(Error code:%s)", MU_ENUM_TO_STRING(SCHEMA_RESULT, SCHEMA_ELEMENT_NOT_FOUND));
+        }
+        else
+        {
+            result = modelType->Actions[i];
+        }
+    }
+
+    return result;
+}
+
+static bool matchModelMethod(const void* element, const void* value)
+{
+    /*element is a pointer to SCHEMA_METHOD_HANDLE_DATA*/
+    const SCHEMA_METHOD_HANDLE* decodedElement = (const SCHEMA_METHOD_HANDLE* )element;
+    const char* name = (const char*)value;
+    return (strcmp((*decodedElement)->methodName, name) == 0);
+}
+
+SCHEMA_METHOD_HANDLE Schema_GetModelMethodByName(SCHEMA_MODEL_TYPE_HANDLE modelTypeHandle, const char* methodName)
+{
+    SCHEMA_METHOD_HANDLE result;
+
+    /*Codes_SRS_SCHEMA_02_115: [ If modelTypeHandle is NULL then Schema_GetModelMethodByName shall fail and return NULL. ]*/
+    /*Codes_SRS_SCHEMA_02_116: [ If methodName is NULL then Schema_GetModelMethodByName shall fail and return NULL. ]*/
+    if ((modelTypeHandle == NULL) ||
+        (methodName == NULL))
+    {
+        result = NULL;
+        LogError("invalid arguments SCHEMA_MODEL_TYPE_HANDLE modelTypeHandle=%p, const char* methodName=%p", modelTypeHandle, methodName);
+    }
+    else
+    {
+        /*Codes_SRS_SCHEMA_02_117: [ If a method with the name methodName exists then Schema_GetModelMethodByName shall succeed and returns its handle. ]*/
+        SCHEMA_METHOD_HANDLE* found = VECTOR_find_if(modelTypeHandle->methods, matchModelMethod, methodName);
+        if (found == NULL)
+        {
+            /*Codes_SRS_SCHEMA_02_118: [ Otherwise, Schema_GetModelMethodByName shall fail and return NULL. ]*/
+            LogError("no such method by name = %s", methodName);
+            result = NULL;
+        }
+        else
+        {
+            result = *found;
+        }
+    }
+
+    return result;
+}
+
+SCHEMA_RESULT Schema_GetModelActionCount(SCHEMA_MODEL_TYPE_HANDLE modelTypeHandle, size_t* actionCount)
+{
+    SCHEMA_RESULT result;
+
+    /* Codes_SRS_SCHEMA_99_045:[If any of the modelTypeHandle or actionCount arguments is NULL, Schema_GetModelActionCount shall return SCHEMA_INVALID_ARG.] */
+    if ((modelTypeHandle == NULL) ||
+        (actionCount == NULL))
+    {
+        result = SCHEMA_INVALID_ARG;
+        LogError("(result=%s)", MU_ENUM_TO_STRING(SCHEMA_RESULT, result));
+    }
+    else
+    {
+        /* Codes_SRS_SCHEMA_99_042:[Schema_GetModelActionCount shall provide the total number of actions defined in a model type identified by the modelTypeHandle.] */
+        SCHEMA_MODEL_TYPE_HANDLE_DATA* modelType = (SCHEMA_MODEL_TYPE_HANDLE_DATA*)modelTypeHandle;
+
+        /* Codes_SRS_SCHEMA_99_043:[The count shall be provided via the out argument actionCount.] */
+        *actionCount = modelType->ActionCount;
+
+        /* Codes_SRS_SCHEMA_99_044:[On success, Schema_GetModelActionCount shall return SCHEMA_OK.] */
+        result = SCHEMA_OK;
+    }
+
+    return result;
+}
+
+SCHEMA_ACTION_HANDLE Schema_GetModelActionByIndex(SCHEMA_MODEL_TYPE_HANDLE modelTypeHandle, size_t index)
+{
+    SCHEMA_ACTION_HANDLE result;
+    SCHEMA_MODEL_TYPE_HANDLE_DATA* modelType = (SCHEMA_MODEL_TYPE_HANDLE_DATA*)modelTypeHandle;
+
+    /* Codes_SRS_SCHEMA_99_048:[Schema_GetModelAction shall return NULL if the index specified is outside the valid range or if modelTypeHandle argument is NULL.] */
+    if ((modelType == NULL) ||
+        (index >= modelType->ActionCount))
+    {
+        result = NULL;
+        LogError("(Error code:%s)", MU_ENUM_TO_STRING(SCHEMA_RESULT, SCHEMA_INVALID_ARG));
+    }
+    else
+    {
+        /* Codes_SRS_SCHEMA_99_047:[Schema_GetModelAction shall return a non-NULL SCHEMA_ACTION_HANDLE corresponding to the model type identified by modelTypeHandle and matching the index number provided by the index argument.] */
+        /* Codes_SRS_SCHEMA_99_096: [index is zero based and the order in which actions were added shall be the index in which they will be retrieved.] */
+        result = modelType->Actions[index];
+    }
+
+    return result;
+}
+
+const char* Schema_GetModelActionName(SCHEMA_ACTION_HANDLE actionHandle)
+{
+    const char* result;
+
+    /* Codes_SRS_SCHEMA_99_050:[If the actionHandle is NULL, Schema_GetModelActionName shall return NULL.] */
+    if (actionHandle == NULL)
+    {
+        result = NULL;
+        LogError("(Error code:%s)", MU_ENUM_TO_STRING(SCHEMA_RESULT, SCHEMA_INVALID_ARG));
+    }
+    else
+    {
+        SCHEMA_ACTION_HANDLE_DATA* action = (SCHEMA_ACTION_HANDLE_DATA*)actionHandle;
+        /* Codes_SRS_SCHEMA_99_049:[Schema_GetModelActionName shall return the action name for a given action handle.] */
+        result = action->ActionName;
+    }
+
+    return result;
+}
+
+SCHEMA_RESULT Schema_GetModelActionArgumentCount(SCHEMA_ACTION_HANDLE actionHandle, size_t* argumentCount)
+{
+    SCHEMA_RESULT result;
+
+    /* Codes_SRS_SCHEMA_99_054:[If any argument is NULL, Schema_GetModelActionArgumentCount shall return SCHEMA_INVALID_ARG.] */
+    if ((actionHandle == NULL) ||
+        (argumentCount == NULL))
+    {
+        result = SCHEMA_INVALID_ARG;
+        LogError("(result=%s)", MU_ENUM_TO_STRING(SCHEMA_RESULT, result));
+    }
+    else
+    {
+        SCHEMA_ACTION_HANDLE_DATA* modelAction = (SCHEMA_ACTION_HANDLE_DATA*)actionHandle;
+
+        /* Codes_SRS_SCHEMA_99_051:[Schema_GetModelActionArgumentCount shall provide the number of arguments for a specific schema action identified by actionHandle.] */
+        /* Codes_SRS_SCHEMA_99_052:[The argument count shall be provided via the out argument argumentCount.] */
+        *argumentCount = modelAction->ArgumentCount;
+
+        /* Codes_SRS_SCHEMA_99_053:[On success, Schema_GetModelActionArgumentCount shall return SCHEMA_OK.] */
+        result = SCHEMA_OK;
+    }
+
+    return result;
+}
+
+SCHEMA_RESULT Schema_GetModelMethodArgumentCount(SCHEMA_METHOD_HANDLE methodHandle, size_t* argumentCount)
+{
+    SCHEMA_RESULT result;
+
+    /*Codes_SRS_SCHEMA_02_119: [ If methodHandle is NULL then Schema_GetModelMethodArgumentCount shall fail and return SCHEMA_INVALID_ARG. ]*/
+    /*Codes_SRS_SCHEMA_02_120: [ If argumentCount is NULL then Schema_GetModelMethodArgumentCount shall fail and return SCHEMA_INVALID_ARG. ]*/
+    if ((methodHandle == NULL) ||
+        (argumentCount == NULL))
+    {
+        result = SCHEMA_INVALID_ARG;
+        LogError("(result=%s)", MU_ENUM_TO_STRING(SCHEMA_RESULT, result));
+    }
+    else
+    {
+        /*Codes_SRS_SCHEMA_02_121: [ Otherwise, Schema_GetModelMethodArgumentCount shall succeed, return in argumentCount the number of arguments for the method and return SCHEMA_OK. ]*/
+        *argumentCount = VECTOR_size(methodHandle->methodArguments);
+        result = SCHEMA_OK;
+    }
+
+    return result;
+}
+
+
+SCHEMA_ACTION_ARGUMENT_HANDLE Schema_GetModelActionArgumentByName(SCHEMA_ACTION_HANDLE actionHandle, const char* actionArgumentName)
+{
+    SCHEMA_ACTION_ARGUMENT_HANDLE result;
+
+    /* Codes_SRS_SCHEMA_99_118: [Schema_GetModelActionArgumentByName shall return NULL if unable to find a matching argument or if any of the arguments are NULL.] */
+    if ((actionHandle == NULL) ||
+        (actionArgumentName == NULL))
+    {
+        result = NULL;
+        LogError("(Error code:%s)", MU_ENUM_TO_STRING(SCHEMA_RESULT, SCHEMA_INVALID_ARG));
+    }
+    else
+    {
+        /* Codes_SRS_SCHEMA_99_118: [Schema_GetModelActionArgumentByName shall return NULL if unable to find a matching argument or if any of the arguments are NULL.] */
+        SCHEMA_ACTION_HANDLE_DATA* modelAction = (SCHEMA_ACTION_HANDLE_DATA*)actionHandle;
+        size_t i;
+
+        for (i = 0; i < modelAction->ArgumentCount; i++)
+        {
+            SCHEMA_ACTION_ARGUMENT_HANDLE_DATA* actionArgument = (SCHEMA_ACTION_ARGUMENT_HANDLE_DATA*)modelAction->ArgumentHandles[i];
+            if (strcmp(actionArgument->Name, actionArgumentName) == 0)
+            {
+                break;
+            }
+        }
+
+        if (i == modelAction->ArgumentCount)
+        {
+            /* Codes_SRS_SCHEMA_99_118: [Schema_GetModelActionArgumentByName shall return NULL if unable to find a matching argument or if any of the arguments are NULL.] */
+            result = NULL;
+            LogError("(Error code:%s)", MU_ENUM_TO_STRING(SCHEMA_RESULT, SCHEMA_ELEMENT_NOT_FOUND));
+        }
+        else
+        {
+            /* Codes_SRS_SCHEMA_99_117: [Schema_GetModelActionArgumentByName shall return a non-NULL handle corresponding to an action argument identified by the actionHandle and actionArgumentName.] */
+            result = modelAction->ArgumentHandles[i];
+        }
+    }
+
+    return result;
+}
+
+SCHEMA_ACTION_ARGUMENT_HANDLE Schema_GetModelActionArgumentByIndex(SCHEMA_ACTION_HANDLE actionHandle, size_t argumentIndex)
+{
+    SCHEMA_ACTION_ARGUMENT_HANDLE result;
+    SCHEMA_ACTION_HANDLE_DATA* modelAction = (SCHEMA_ACTION_HANDLE_DATA*)actionHandle;
+
+    /* Codes_SRS_SCHEMA_99_056:[Schema_GetModelActionArgument shall return NULL if the index specified is outside the valid range or if the actionHandle argument is NULL.] */
+    if ((actionHandle == NULL) ||
+        (argumentIndex >= modelAction->ArgumentCount))
+    {
+        result = NULL;
+        LogError("(Error code:%s)", MU_ENUM_TO_STRING(SCHEMA_RESULT, SCHEMA_INVALID_ARG));
+    }
+    else
+    {
+        /* Codes_SRS_SCHEMA_99_055:[Schema_GetModelActionArgument shall return a non-NULL SCHEMA_ACTION_ARGUMENT_HANDLE corresponding to the action type identified by actionHandle and matching the index number provided by the argumentIndex argument.] */
+        result = modelAction->ArgumentHandles[argumentIndex];
+    }
+
+    return result;
+}
+
+SCHEMA_METHOD_ARGUMENT_HANDLE Schema_GetModelMethodArgumentByIndex(SCHEMA_METHOD_HANDLE methodHandle, size_t argumentIndex)
+{
+    SCHEMA_METHOD_ARGUMENT_HANDLE result;
+
+    /*Codes_SRS_SCHEMA_02_122: [ If methodHandle is NULL then Schema_GetModelMethodArgumentByIndex shall fail and return NULL. ]*/
+    if (methodHandle == NULL)
+    {
+        result = NULL;
+        LogError("(Error code:%s)", MU_ENUM_TO_STRING(SCHEMA_RESULT, SCHEMA_INVALID_ARG));
+    }
+    else
+    {
+        /*Codes_SRS_SCHEMA_02_123: [ If argumentIndex does not exist then Schema_GetModelMethodArgumentByIndex shall fail and return NULL. ]*/
+        SCHEMA_METHOD_ARGUMENT_HANDLE *temp = VECTOR_element(methodHandle->methodArguments, argumentIndex);
+        if (temp == NULL)
+        {
+            result = NULL;
+        }
+        else
+        {
+            /*Codes_SRS_SCHEMA_02_124: [ Otherwise, Schema_GetModelMethodArgumentByIndex shall succeed and return a non-NULL value. ]*/
+            result = *temp;
+        }
+    }
+
+    return result;
+}
+
+
+const char* Schema_GetActionArgumentName(SCHEMA_ACTION_ARGUMENT_HANDLE actionArgumentHandle)
+{
+    const char* result;
+    /* Codes_SRS_SCHEMA_99_114: [Schema_GetActionArgumentName shall return NULL if actionArgumentHandle is NULL.] */
+    if (actionArgumentHandle == NULL)
+    {
+        result = NULL;
+        LogError("(Error code:%s)", MU_ENUM_TO_STRING(SCHEMA_RESULT, SCHEMA_INVALID_ARG));
+    }
+    else
+    {
+        /* Codes_SRS_SCHEMA_99_113: [Schema_GetActionArgumentName shall return the argument name identified by the actionArgumentHandle.] */
+        SCHEMA_ACTION_ARGUMENT_HANDLE_DATA* actionArgument = (SCHEMA_ACTION_ARGUMENT_HANDLE_DATA*)actionArgumentHandle;
+        result = actionArgument->Name;
+    }
+    return result;
+}
+
+const char* Schema_GetMethodArgumentName(SCHEMA_METHOD_ARGUMENT_HANDLE methodArgumentHandle)
+{
+    const char* result;
+    /*Codes_SRS_SCHEMA_02_125: [ If methodArgumentHandle is NULL then Schema_GetMethodArgumentName shall fail and return NULL. ]*/
+    if (methodArgumentHandle == NULL)
+    {
+        result = NULL;
+        LogError("(Error code:%s)", MU_ENUM_TO_STRING(SCHEMA_RESULT, SCHEMA_INVALID_ARG));
+    }
+    else
+    {
+        /*Codes_SRS_SCHEMA_02_126: [ Otherwise, Schema_GetMethodArgumentName shall succeed and return a non-NULL value. ]*/
+        result = methodArgumentHandle->Name;
+    }
+    return result;
+}
+
+
+const char* Schema_GetActionArgumentType(SCHEMA_ACTION_ARGUMENT_HANDLE actionArgumentHandle)
+{
+    const char* result;
+    /* Codes_SRS_SCHEMA_99_116: [Schema_GetActionArgumentType shall return NULL if actionArgumentHandle is NULL.] */
+    if (actionArgumentHandle == NULL)
+    {
+        result = NULL;
+        LogError("(Error code:%s)", MU_ENUM_TO_STRING(SCHEMA_RESULT, SCHEMA_INVALID_ARG));
+    }
+    else
+    {
+        /* Codes_SRS_SCHEMA_99_115: [Schema_GetActionArgumentType shall return the argument type identified by the actionArgumentHandle.] */
+        SCHEMA_ACTION_ARGUMENT_HANDLE_DATA* actionArgument = (SCHEMA_ACTION_ARGUMENT_HANDLE_DATA*)actionArgumentHandle;
+        result = actionArgument->Type;
+    }
+    return result;
+}
+
+const char* Schema_GetMethodArgumentType(SCHEMA_METHOD_ARGUMENT_HANDLE methodArgumentHandle)
+{
+    const char* result;
+    /*Codes_SRS_SCHEMA_02_127: [ If methodArgumentHandle is NULL then Schema_GetMethodArgumentType shall fail and return NULL. ]*/
+    if (methodArgumentHandle == NULL)
+    {
+        result = NULL;
+        LogError("invalid argument SCHEMA_METHOD_ARGUMENT_HANDLE methodArgumentHandle=%p", methodArgumentHandle);
+    }
+    else
+    {
+        /*Codes_SRS_SCHEMA_02_128: [ Otherwise, Schema_GetMethodArgumentType shall succeed and return a non-NULL value. ]*/
+        result = methodArgumentHandle->Type;
+    }
+    return result;
+}
+
+
+SCHEMA_STRUCT_TYPE_HANDLE Schema_CreateStructType(SCHEMA_HANDLE schemaHandle, const char* typeName)
+{
+    SCHEMA_STRUCT_TYPE_HANDLE result;
+    SCHEMA_HANDLE_DATA* schema = (SCHEMA_HANDLE_DATA*)schemaHandle;
+
+    /* Codes_SRS_SCHEMA_99_060:[If any of the arguments is NULL, Schema_CreateStructType shall return NULL.] */
+    if ((schema == NULL) ||
+        (typeName == NULL))
+    {
+        result = NULL;
+        LogError("(Error code:%s)", MU_ENUM_TO_STRING(SCHEMA_RESULT, SCHEMA_INVALID_ARG));
+    }
+    else
+    {
+        SCHEMA_STRUCT_TYPE_HANDLE_DATA* structType;
+        size_t i;
+
+        /* Codes_SRS_SCHEMA_99_061:[If a struct type with the same name already exists, Schema_CreateStructType shall return NULL.] */
+        for (i = 0; i < schema->StructTypeCount; i++)
+        {
+            structType = (SCHEMA_STRUCT_TYPE_HANDLE_DATA*)schema->StructTypes[i];
+            if (strcmp(structType->Name, typeName) == 0)
+            {
+                break;
+            }
+        }
+
+        if (i < schema->StructTypeCount)
+        {
+            result = NULL;
+            LogError("(Error code:%s)", MU_ENUM_TO_STRING(SCHEMA_RESULT, SCHEMA_DUPLICATE_ELEMENT));
+        }
+        else
+        {
+            SCHEMA_STRUCT_TYPE_HANDLE* newStructTypes = (SCHEMA_STRUCT_TYPE_HANDLE*)realloc(schema->StructTypes, sizeof(SCHEMA_STRUCT_TYPE_HANDLE) * (schema->StructTypeCount + 1));
+            if (newStructTypes == NULL)
+            {
+                /* Codes_SRS_SCHEMA_99_066:[On any other error, Schema_CreateStructType shall return NULL.] */
+                result = NULL;
+                LogError("(Error code:%s)", MU_ENUM_TO_STRING(SCHEMA_RESULT, SCHEMA_ERROR));
+            }
+            else
+            {
+                schema->StructTypes = newStructTypes;
+                if ((structType = (SCHEMA_STRUCT_TYPE_HANDLE_DATA*)calloc(1, sizeof(SCHEMA_STRUCT_TYPE_HANDLE_DATA))) == NULL)
+                {
+                    /* Codes_SRS_SCHEMA_99_066:[On any other error, Schema_CreateStructType shall return NULL.] */
+                    result = NULL;
+                    LogError("(Error code:%s)", MU_ENUM_TO_STRING(SCHEMA_RESULT, SCHEMA_ERROR));
+                }
+                else if (mallocAndStrcpy_s((char**)&structType->Name, typeName) != 0)
+                {
+                    /* Codes_SRS_SCHEMA_99_066:[On any other error, Schema_CreateStructType shall return NULL.] */
+                    result = NULL;
+                    free(structType);
+                    LogError("(Error code:%s)", MU_ENUM_TO_STRING(SCHEMA_RESULT, SCHEMA_ERROR));
+                }
+                else
+                {
+                    /* Codes_SRS_SCHEMA_99_057:[Schema_CreateStructType shall create a new struct type and return a handle to it.] */
+                    schema->StructTypes[schema->StructTypeCount] = structType;
+                    schema->StructTypeCount++;
+                    structType->PropertyCount = 0;
+                    structType->Properties = NULL;
+
+                    /* Codes_SRS_SCHEMA_99_058:[On success, a non-NULL handle shall be returned.] */
+                    result = (SCHEMA_STRUCT_TYPE_HANDLE)structType;
+                }
+
+                /* If possible, reduce the memory of over allocation */
+                if (result == NULL)
+                {
+                    if (schema->StructTypeCount > 0)
+                    {
+                        SCHEMA_STRUCT_TYPE_HANDLE *oldStructTypes = (SCHEMA_STRUCT_TYPE_HANDLE *)realloc(schema->StructTypes, sizeof(SCHEMA_STRUCT_TYPE_HANDLE) * schema->StructTypeCount);
+                        if (oldStructTypes == NULL)
+                        {
+                            result = NULL;
+                            LogError("(Error code:%s)", MU_ENUM_TO_STRING(SCHEMA_RESULT, SCHEMA_ERROR));
+                        }
+                        else
+                        {
+                            schema->StructTypes = oldStructTypes;
+                        }
+                    }
+                    else
+                    {
+                        schema->StructTypes = NULL;
+                    }
+                }
+            }
+        }
+    }
+
+    return result;
+}
+
+const char* Schema_GetStructTypeName(SCHEMA_STRUCT_TYPE_HANDLE structTypeHandle)
+{
+    const char* result;
+
+    /* Codes_SRS_SCHEMA_99_136: [If structTypeHandle is NULL, Schema_GetStructTypeName shall return NULL.] */
+    if (structTypeHandle == NULL)
+    {
+        result = NULL;
+        LogError("(Error code:%s)", MU_ENUM_TO_STRING(SCHEMA_RESULT, SCHEMA_INVALID_ARG));
+    }
+    else
+    {
+        /* Codes_SRS_SCHEMA_99_135: [Schema_GetStructTypeName shall return the name of a struct type identified by the structTypeHandle argument.] */
+        result = ((SCHEMA_STRUCT_TYPE_HANDLE_DATA*)structTypeHandle)->Name;
+    }
+
+    return result;
+}
+
+SCHEMA_RESULT Schema_GetStructTypeCount(SCHEMA_HANDLE schemaHandle, size_t* structTypeCount)
+{
+    SCHEMA_RESULT result;
+
+    /* Codes_SRS_SCHEMA_99_140: [Schema_GetStructTypeCount shall return SCHEMA_INVALID_ARG if any of the arguments is NULL.] */
+    if ((schemaHandle == NULL) ||
+        (structTypeCount == NULL))
+    {
+        result = SCHEMA_INVALID_ARG;
+        LogError("(result = %s)", MU_ENUM_TO_STRING(SCHEMA_RESULT, result));
+    }
+    else
+    {
+        /* Codes_SRS_SCHEMA_99_137: [Schema_GetStructTypeCount shall provide the number of structs defined in the schema identified by schemaHandle.] */
+        SCHEMA_HANDLE_DATA* schema = (SCHEMA_HANDLE_DATA*)schemaHandle;
+        /* Codes_SRS_SCHEMA_99_138: [The count shall be provided via the out argument structTypeCount.] */
+        *structTypeCount = schema->StructTypeCount;
+        /* Codes_SRS_SCHEMA_99_139: [On success, Schema_GetStructTypeCount shall return SCHEMA_OK.] */
+        result = SCHEMA_OK;
+    }
+
+    return result;
+}
+
+SCHEMA_STRUCT_TYPE_HANDLE Schema_GetStructTypeByName(SCHEMA_HANDLE schemaHandle, const char* name)
+{
+    SCHEMA_STRUCT_TYPE_HANDLE result;
+    SCHEMA_HANDLE_DATA* schema = (SCHEMA_HANDLE_DATA*)schemaHandle;
+
+    /* Codes_SRS_SCHEMA_99_069:[Schema_GetStructTypeByName shall return NULL if unable to find a matching struct or if any of the arguments are NULL.] */
+    if ((schemaHandle == NULL) ||
+        (name == NULL))
+    {
+        result = NULL;
+        LogError("(Error code:%s)", MU_ENUM_TO_STRING(SCHEMA_RESULT, SCHEMA_INVALID_ARG));
+    }
+    else
+    {
+        size_t i;
+
+        /* Codes_SRS_SCHEMA_99_068:[Schema_GetStructTypeByName shall return a non-NULL handle corresponding to the struct type identified by the structTypeName in the schemaHandle schema.] */
+        for (i = 0; i < schema->StructTypeCount; i++)
+        {
+            SCHEMA_STRUCT_TYPE_HANDLE_DATA* structType = (SCHEMA_STRUCT_TYPE_HANDLE_DATA*)schema->StructTypes[i];
+            if (strcmp(structType->Name, name) == 0)
+            {
+                break;
+            }
+        }
+
+        if (i == schema->StructTypeCount)
+        {
+            /* Codes_SRS_SCHEMA_99_069:[Schema_GetStructTypeByName shall return NULL if unable to find a matching struct or if any of the arguments are NULL.] */
+            result = NULL;
+            LogError("(Error code:%s)", MU_ENUM_TO_STRING(SCHEMA_RESULT, SCHEMA_ELEMENT_NOT_FOUND));
+        }
+        else
+        {
+            result = schema->StructTypes[i];
+        }
+    }
+
+    return result;
+}
+
+SCHEMA_STRUCT_TYPE_HANDLE Schema_GetStructTypeByIndex(SCHEMA_HANDLE schemaHandle, size_t index)
+{
+    SCHEMA_STRUCT_TYPE_HANDLE result;
+    SCHEMA_HANDLE_DATA* schema = (SCHEMA_HANDLE_DATA*)schemaHandle;
+
+    /* Codes_SRS_SCHEMA_99_143: [Schema_GetStructTypeByIndex shall return NULL if the index specified is outside the valid range or if schemaHandle argument is NULL.] */
+    /* Codes_SRS_SCHEMA_99_142: [The index argument is zero based, and the order in which models were added shall be the index in which they will be retrieved.] */
+    if ((schemaHandle == NULL) ||
+        (index >= schema->StructTypeCount))
+    {
+        result = NULL;
+        LogError("(Error code: %s)", MU_ENUM_TO_STRING(SCHEMA_RESULT, SCHEMA_INVALID_ARG));
+    }
+    else
+    {
+
+        /* Codes_SRS_SCHEMA_99_141: [Schema_GetStructTypeByIndex shall return a non-NULL SCHEMA_STRUCT_TYPE_HANDLE corresponding to the struct type identified by schemaHandle and matching the index number provided by the index argument.] */
+        /* Codes_SRS_SCHEMA_99_142: [The index argument is zero based, and the order in which models were added shall be the index in which they will be retrieved.] */
+        result = schema->StructTypes[index];
+    }
+    return result;
+}
+
+SCHEMA_RESULT Schema_AddStructTypeProperty(SCHEMA_STRUCT_TYPE_HANDLE structTypeHandle, const char* propertyName, const char* propertyType)
+{
+    SCHEMA_RESULT result;
+
+    /* Codes_SRS_SCHEMA_99_072:[If any of the arguments is NULL, Schema_AddStructTypeProperty shall return SCHEMA_INVALID_ARG.] */
+    if ((structTypeHandle == NULL) ||
+        (propertyName == NULL) ||
+        (propertyType == NULL))
+    {
+        result = SCHEMA_INVALID_ARG;
+        LogError("(result = %s)", MU_ENUM_TO_STRING(SCHEMA_RESULT, result));
+    }
+    else
+    {
+        size_t i;
+        SCHEMA_STRUCT_TYPE_HANDLE_DATA* structType = (SCHEMA_STRUCT_TYPE_HANDLE_DATA*)structTypeHandle;
+
+        /* Codes_SRS_SCHEMA_99_074:[The property name shall be unique per struct type, if the same property name is added twice to a struct type, SCHEMA_DUPLICATE_ELEMENT shall be returned.] */
+        for (i = 0; i < structType->PropertyCount; i++)
+        {
+            SCHEMA_PROPERTY_HANDLE_DATA* property = (SCHEMA_PROPERTY_HANDLE_DATA*)structType->Properties[i];
+            if (strcmp(property->PropertyName, propertyName) == 0)
+            {
+                break;
+            }
+        }
+
+        if (i < structType->PropertyCount)
+        {
+            result = SCHEMA_DUPLICATE_ELEMENT;
+            LogError("(result = %s)", MU_ENUM_TO_STRING(SCHEMA_RESULT, result));
+        }
+        else
+        {
+            SCHEMA_PROPERTY_HANDLE* newProperties = (SCHEMA_PROPERTY_HANDLE*)realloc(structType->Properties, sizeof(SCHEMA_PROPERTY_HANDLE) * (structType->PropertyCount + 1));
+            if (newProperties == NULL)
+            {
+                result = SCHEMA_ERROR;
+                LogError("(result = %s)", MU_ENUM_TO_STRING(SCHEMA_RESULT, result));
+            }
+            else
+            {
+                SCHEMA_PROPERTY_HANDLE_DATA* newProperty;
+
+                structType->Properties = newProperties;
+                if ((newProperty = (SCHEMA_PROPERTY_HANDLE_DATA*)malloc(sizeof(SCHEMA_PROPERTY_HANDLE_DATA))) == NULL)
+                {
+                    result = SCHEMA_ERROR;
+                    LogError("(result = %s)", MU_ENUM_TO_STRING(SCHEMA_RESULT, result));
+                }
+                else
+                {
+                    if (mallocAndStrcpy_s((char**)&newProperty->PropertyName, propertyName) != 0)
+                    {
+                        free(newProperty);
+                        result = SCHEMA_ERROR;
+                        LogError("(result = %s)", MU_ENUM_TO_STRING(SCHEMA_RESULT, result));
+                    }
+                    else if (mallocAndStrcpy_s((char**)&newProperty->PropertyType, propertyType) != 0)
+                    {
+                        free((void*)newProperty->PropertyName);
+                        free(newProperty);
+                        result = SCHEMA_ERROR;
+                        LogError("(result = %s)", MU_ENUM_TO_STRING(SCHEMA_RESULT, result));
+                    }
+                    else
+                    {
+                        /* Codes_SRS_SCHEMA_99_070:[Schema_AddStructTypeProperty shall add one property to the struct type identified by structTypeHandle.] */
+                        structType->Properties[structType->PropertyCount] = (SCHEMA_PROPERTY_HANDLE)newProperty;
+                        structType->PropertyCount++;
+
+                        /* Codes_SRS_SCHEMA_99_071:[On success, Schema_AddStructTypeProperty shall return SCHEMA_OK.] */
+                        result = SCHEMA_OK;
+                    }
+                }
+
+                /* If possible, reduce the memory of over allocation */
+                if (result != SCHEMA_OK)
+                {
+                    if (structType->PropertyCount > 0)
+                    {
+                        SCHEMA_PROPERTY_HANDLE *oldProperties = (SCHEMA_PROPERTY_HANDLE *)realloc(structType->Properties, sizeof(SCHEMA_PROPERTY_HANDLE) * structType->PropertyCount);
+                        if (oldProperties == NULL)
+                        {
+                            result = SCHEMA_ERROR;
+                            LogError("(result = %s)", MU_ENUM_TO_STRING(SCHEMA_RESULT, result));
+                        }
+                        else
+                        {
+                            structType->Properties = oldProperties;
+                        }
+                    }
+                    else
+                    {
+                        structType->Properties = NULL;
+                    }
+                }
+            }
+        }
+    }
+
+    return result;
+}
+
+SCHEMA_PROPERTY_HANDLE Schema_GetStructTypePropertyByName(SCHEMA_STRUCT_TYPE_HANDLE structTypeHandle, const char* propertyName)
+{
+    SCHEMA_PROPERTY_HANDLE result;
+
+    /* Codes_SRS_SCHEMA_99_076:[Schema_GetStructTypePropertyByName shall return NULL if unable to find a matching property or if any of the arguments are NULL.] */
+    if ((structTypeHandle == NULL) ||
+        (propertyName == NULL))
+    {
+        result = NULL;
+        LogError("(Error code: %s)", MU_ENUM_TO_STRING(SCHEMA_RESULT, SCHEMA_INVALID_ARG));
+    }
+    else
+    {
+        size_t i;
+        SCHEMA_STRUCT_TYPE_HANDLE_DATA* structType = (SCHEMA_STRUCT_TYPE_HANDLE_DATA*)structTypeHandle;
+
+        for (i = 0; i < structType->PropertyCount; i++)
+        {
+            SCHEMA_PROPERTY_HANDLE_DATA* modelProperty = (SCHEMA_PROPERTY_HANDLE_DATA*)structType->Properties[i];
+            if (strcmp(modelProperty->PropertyName, propertyName) == 0)
+            {
+                break;
+            }
+        }
+
+        /* Codes_SRS_SCHEMA_99_076:[Schema_GetStructTypePropertyByName shall return NULL if unable to find a matching property or if any of the arguments are NULL.] */
+        if (i == structType->PropertyCount)
+        {
+            result = NULL;
+            LogError("(Error code: %s)", MU_ENUM_TO_STRING(SCHEMA_RESULT, SCHEMA_ELEMENT_NOT_FOUND));
+        }
+        /* Codes_SRS_SCHEMA_99_075:[Schema_GetStructTypePropertyByName shall return a non-NULL handle corresponding to a property identified by the structTypeHandle and propertyName.] */
+        else
+        {
+            result = structType->Properties[i];
+        }
+    }
+
+    return result;
+}
+
+SCHEMA_RESULT Schema_GetStructTypePropertyCount(SCHEMA_STRUCT_TYPE_HANDLE structTypeHandle, size_t* propertyCount)
+{
+    SCHEMA_RESULT result;
+
+    /* Codes_SRS_SCHEMA_99_079: [Schema_GetStructTypePropertyCount shall return SCHEMA_INVALID_ARG if any of the structlTypeHandle or propertyCount arguments is NULL.] */
+    if ((structTypeHandle == NULL) ||
+        (propertyCount == NULL))
+    {
+        result = SCHEMA_INVALID_ARG;
+        LogError("(result = %s)", MU_ENUM_TO_STRING(SCHEMA_RESULT, result));
+    }
+    else
+    {
+        SCHEMA_STRUCT_TYPE_HANDLE_DATA* structType = (SCHEMA_STRUCT_TYPE_HANDLE_DATA*)structTypeHandle;
+
+        /* Codes_SRS_SCHEMA_99_077: [Schema_GetStructTypePropertyCount shall provide the total number of properties defined in a struct type identified by structTypeHandle. The value is provided via the out argument propertyCount.] */
+        /* Codes_SRS_SCHEMA_99_081: [The count shall be provided via the out argument propertyCount.] */
+        *propertyCount = structType->PropertyCount;
+
+        /* Codes_SRS_SCHEMA_99_078: [On success, Schema_ GetStructTypePropertyCount shall return SCHEMA_OK.] */
+        result = SCHEMA_OK;
+    }
+
+    return result;
+}
+
+SCHEMA_PROPERTY_HANDLE Schema_GetStructTypePropertyByIndex(SCHEMA_STRUCT_TYPE_HANDLE structTypeHandle, size_t index)
+{
+    SCHEMA_PROPERTY_HANDLE result;
+    SCHEMA_STRUCT_TYPE_HANDLE_DATA* structType = (SCHEMA_STRUCT_TYPE_HANDLE_DATA*)structTypeHandle;
+
+    /* Codes_SRS_SCHEMA_99_083: [Schema_ GetStructTypeProperty shall return NULL if the index specified is outside the valid range, if structTypeHandle argument is NULL] */
+    if ((structTypeHandle == NULL) ||
+        (index >= structType->PropertyCount))
+    {
+        result = NULL;
+        LogError("(Error code: %s)", MU_ENUM_TO_STRING(SCHEMA_RESULT, SCHEMA_INVALID_ARG));
+    }
+    else
+    {
+        /* Codes_SRS_SCHEMA_99_082: [Schema_GetStructTypeProperty shall return a non-NULL SCHEMA_PROPERTY_HANDLE corresponding to the struct type identified by strutTypeHandle and matching the index number provided by the index argument.] */
+        /* Codes_SRS_SCHEMA_99_098: [index is zero based and the order in which actions were added shall be the index in which they will be retrieved.] */
+        result = structType->Properties[index];
+    }
+
+    return result;
+}
+
+const char* Schema_GetPropertyName(SCHEMA_PROPERTY_HANDLE propertyHandle)
+{
+    const char* result;
+
+    /* Codes_SRS_SCHEMA_99_086: [If propertyHandle is NULL, Schema_GetPropertyName shall return NULL.] */
+    if (propertyHandle == NULL)
+    {
+        result = NULL;
+        LogError("(Error code: %s)", MU_ENUM_TO_STRING(SCHEMA_RESULT, SCHEMA_INVALID_ARG));
+    }
+    else
+    {
+        SCHEMA_PROPERTY_HANDLE_DATA* propertyType = (SCHEMA_PROPERTY_HANDLE_DATA*)propertyHandle;
+
+        /* Codes_SRS_SCHEMA_99_085: [Schema_GetPropertyName shall return the property name identified by the propertyHandle.] */
+        result = propertyType->PropertyName;
+    }
+
+    return result;
+}
+
+const char* Schema_GetPropertyType(SCHEMA_PROPERTY_HANDLE propertyHandle)
+{
+    const char* result;
+
+    /* Codes_SRS_SCHEMA_99_088: [If propertyHandle is NULL, Schema_GetPropertyType shall return NULL.] */
+    if (propertyHandle == NULL)
+    {
+        result = NULL;
+        LogError("(Error code: %s)", MU_ENUM_TO_STRING(SCHEMA_RESULT, SCHEMA_INVALID_ARG));
+    }
+    else
+    {
+        SCHEMA_PROPERTY_HANDLE_DATA* modelProperty = (SCHEMA_PROPERTY_HANDLE_DATA*)propertyHandle;
+
+        /* Codes_SRS_SCHEMA_99_087: [Schema_GetPropertyType shall return the property type identified by the propertyHandle.] */
+        result = modelProperty->PropertyType;
+    }
+
+    return result;
+}
+
+SCHEMA_RESULT Schema_GetModelCount(SCHEMA_HANDLE schemaHandle, size_t* modelCount)
+{
+    SCHEMA_RESULT result;
+    /* Codes_SRS_SCHEMA_99_123: [Schema_GetModelCount shall return SCHEMA_INVALID_ARG if any of the arguments is NULL.] */
+    if ((schemaHandle == NULL) ||
+        (modelCount == NULL) )
+    {
+        result = SCHEMA_INVALID_ARG;
+        LogError("(result = %s)", MU_ENUM_TO_STRING(SCHEMA_RESULT, result));
+    }
+    else
+    {
+        /* Codes_SRS_SCHEMA_99_120: [Schema_GetModelCount shall provide the number of models defined in the schema identified by schemaHandle.] */
+        SCHEMA_HANDLE_DATA* schema = (SCHEMA_HANDLE_DATA*)schemaHandle;
+        /* Codes_SRS_SCHEMA_99_121: [The count shall be provided via the out argument modelCount.] */
+        *modelCount = schema->ModelTypeCount;
+        /* Codes_SRS_SCHEMA_99_122: [On success, Schema_GetModelCount shall return SCHEMA_OK.] */
+        result = SCHEMA_OK;
+    }
+    return result;
+}
+
+SCHEMA_MODEL_TYPE_HANDLE Schema_GetModelByName(SCHEMA_HANDLE schemaHandle, const char* modelName)
+{
+    SCHEMA_MODEL_TYPE_HANDLE result;
+
+    /* Codes_SRS_SCHEMA_99_125: [Schema_GetModelByName shall return NULL if unable to find a matching model, or if any of the arguments are NULL.] */
+    if ((schemaHandle == NULL) ||
+        (modelName == NULL))
+    {
+        result = NULL;
+        LogError("(Error code: %s)", MU_ENUM_TO_STRING(SCHEMA_RESULT, SCHEMA_INVALID_ARG));
+    }
+    else
+    {
+        /* Codes_SRS_SCHEMA_99_124: [Schema_GetModelByName shall return a non-NULL SCHEMA_MODEL_TYPE_HANDLE corresponding to the model identified by schemaHandle and matching the modelName argument value.] */
+        SCHEMA_HANDLE_DATA* schema = (SCHEMA_HANDLE_DATA*)schemaHandle;
+        size_t i;
+        for (i = 0; i < schema->ModelTypeCount; i++)
+        {
+            SCHEMA_MODEL_TYPE_HANDLE_DATA* modelType = (SCHEMA_MODEL_TYPE_HANDLE_DATA*)schema->ModelTypes[i];
+            if (strcmp(modelName, modelType->Name)==0)
+            {
+                break;
+            }
+        }
+        if (i == schema->ModelTypeCount)
+        {
+            /* Codes_SRS_SCHEMA_99_125: [Schema_GetModelByName shall return NULL if unable to find a matching model, or if any of the arguments are NULL.] */
+            result = NULL;
+        }
+        else
+        {
+            result = schema->ModelTypes[i];
+        }
+    }
+    return result;
+}
+
+SCHEMA_MODEL_TYPE_HANDLE Schema_GetModelByIndex(SCHEMA_HANDLE schemaHandle, size_t index)
+{
+    SCHEMA_MODEL_TYPE_HANDLE result;
+    SCHEMA_HANDLE_DATA* schema = (SCHEMA_HANDLE_DATA*)schemaHandle;
+
+    /* Codes_SRS_SCHEMA_99_128: [Schema_GetModelByIndex shall return NULL if the index specified is outside the valid range or if schemaHandle argument is NULL.] */
+    /* Codes_SRS_SCHEMA_99_127: [The index argument is zero based, and the order in which models were added shall be the index in which they will be retrieved.] */
+    if ((schemaHandle == NULL) ||
+        (index >= schema->ModelTypeCount))
+    {
+        result = NULL;
+        LogError("(Error code: %s)", MU_ENUM_TO_STRING(SCHEMA_RESULT, SCHEMA_INVALID_ARG));
+    }
+    else
+    {
+
+        /* Codes_SRS_SCHEMA_99_126: [Schema_GetModelByIndex shall return a non-NULL SCHEMA_MODEL_TYPE_HANDLE corresponding to the model identified by schemaHandle and matching the index number provided by the index argument.] */
+        /* Codes_SRS_SCHEMA_99_127: [The index argument is zero based, and the order in which models were added shall be the index in which they will be retrieved.] */
+        result = schema->ModelTypes[index];
+    }
+    return result;
+}
+
+/*Codes_SRS_SCHEMA_99_160: [Schema_GetModelName shall return the name of the model identified by modelTypeHandle. If the name cannot be retrieved, then NULL shall be returned.]*/
+const char* Schema_GetModelName(SCHEMA_MODEL_TYPE_HANDLE modelTypeHandle)
+{
+    const char* result;
+    if (modelTypeHandle == NULL)
+    {
+        result = NULL;
+    }
+    else
+    {
+        SCHEMA_MODEL_TYPE_HANDLE_DATA* modelType = (SCHEMA_MODEL_TYPE_HANDLE_DATA*)modelTypeHandle;
+        result = modelType->Name;
+    }
+    return result;
+}
+
+/*Codes_SRS_SCHEMA_99_163: [Schema_AddModelModel shall insert an existing model, identified by the handle modelType, into the existing model identified by modelTypeHandle under a property having the name propertyName.]*/
+SCHEMA_RESULT Schema_AddModelModel(SCHEMA_MODEL_TYPE_HANDLE modelTypeHandle, const char* propertyName, SCHEMA_MODEL_TYPE_HANDLE modelType, size_t offset, pfOnDesiredProperty onDesiredProperty)
+{
+    SCHEMA_RESULT result;
+    /*Codes_SRS_SCHEMA_99_165: [If any of the parameters is NULL then Schema_AddModelModel shall return SCHEMA_INVALID_ARG.]*/
+    if (
+        (modelTypeHandle == NULL) ||
+        (propertyName == NULL) ||
+        (modelType == NULL)
+        )
+    {
+        result = SCHEMA_INVALID_ARG;
+        LogError("(Error code: %s)", MU_ENUM_TO_STRING(SCHEMA_RESULT, SCHEMA_INVALID_ARG));
+    }
+    else
+    {
+        SCHEMA_MODEL_TYPE_HANDLE_DATA* parentModel = (SCHEMA_MODEL_TYPE_HANDLE_DATA*)modelTypeHandle;
+        MODEL_IN_MODEL temp;
+        temp.modelHandle = modelType;
+        temp.offset = offset;
+        temp.onDesiredProperty = onDesiredProperty;
+        if (mallocAndStrcpy_s((char**)&(temp.propertyName), propertyName) != 0)
+        {
+            result = SCHEMA_ERROR;
+            LogError("(Error code: %s)", MU_ENUM_TO_STRING(SCHEMA_RESULT, result));
+        }
+        else if (VECTOR_push_back(parentModel->models, &temp, 1) != 0)
+        {
+            /*Codes_SRS_SCHEMA_99_174: [The function shall return SCHEMA_ERROR if any other error occurs.]*/
+            free((void*)temp.propertyName);
+            result = SCHEMA_ERROR;
+            LogError("(Error code: %s)", MU_ENUM_TO_STRING(SCHEMA_RESULT, result));
+        }
+        else
+        {
+            /*Codes_SRS_SCHEMA_99_164: [If the function succeeds, then the return value shall be SCHEMA_OK.]*/
+
+            result = SCHEMA_OK;
+        }
+    }
+    return result;
+}
+
+
+SCHEMA_RESULT Schema_GetModelModelCount(SCHEMA_MODEL_TYPE_HANDLE modelTypeHandle, size_t* modelCount)
+{
+    SCHEMA_RESULT result;
+    /*Codes_SRS_SCHEMA_99_169: [If any of the parameters is NULL, then the function shall return SCHEMA_INVALID_ARG.]*/
+    if (
+        (modelTypeHandle == NULL) ||
+        (modelCount == NULL)
+        )
+    {
+        result = SCHEMA_INVALID_ARG;
+        LogError("(Error code: %s)", MU_ENUM_TO_STRING(SCHEMA_RESULT, result));
+    }
+    else
+    {
+        SCHEMA_MODEL_TYPE_HANDLE_DATA* model = (SCHEMA_MODEL_TYPE_HANDLE_DATA*)modelTypeHandle;
+        /*Codes_SRS_SCHEMA_99_167: [Schema_GetModelModelCount shall return in parameter modelCount the number of models inserted in the model identified by parameter modelTypeHandle.]*/
+        *modelCount = VECTOR_size(model->models);
+        /*SRS_SCHEMA_99_168: [If the function succeeds, it shall return SCHEMA_OK.]*/
+        result = SCHEMA_OK;
+    }
+    return result;
+}
+
+static bool matchModelName(const void* element, const void* value)
+{
+    MODEL_IN_MODEL* decodedElement = (MODEL_IN_MODEL*)element;
+    const char* name = (const char*)value;
+    return (strcmp(decodedElement->propertyName, name) == 0);
+}
+
+SCHEMA_MODEL_TYPE_HANDLE Schema_GetModelModelByName(SCHEMA_MODEL_TYPE_HANDLE modelTypeHandle, const char* propertyName)
+{
+    SCHEMA_MODEL_TYPE_HANDLE result;
+    if (
+        (modelTypeHandle == NULL) ||
+        (propertyName == NULL)
+        )
+    {
+        /*Codes_SRS_SCHEMA_99_171: [If Schema_GetModelModelByName is unable to provide the handle it shall return NULL.]*/
+        result = NULL;
+        LogError("error SCHEMA_INVALID_ARG");
+    }
+    else
+    {
+        SCHEMA_MODEL_TYPE_HANDLE_DATA* model = (SCHEMA_MODEL_TYPE_HANDLE_DATA*)modelTypeHandle;
+        /*Codes_SRS_SCHEMA_99_170: [Schema_GetModelModelByName shall return a handle to the model identified by the property with the name propertyName in the model identified by the handle modelTypeHandle.]*/
+        /*Codes_SRS_SCHEMA_99_171: [If Schema_GetModelModelByName is unable to provide the handle it shall return NULL.]*/
+        void* temp = VECTOR_find_if(model->models, matchModelName, propertyName);
+        if (temp == NULL)
+        {
+            LogError("specified propertyName not found (%s)", propertyName);
+            result = NULL;
+        }
+        else
+        {
+            result = ((MODEL_IN_MODEL*)temp)->modelHandle;
+        }
+    }
+    return result;
+}
+
+size_t Schema_GetModelModelByName_Offset(SCHEMA_MODEL_TYPE_HANDLE modelTypeHandle, const char* propertyName)
+{
+    size_t result;
+    /*Codes_SRS_SCHEMA_02_053: [ If modelTypeHandle is NULL then Schema_GetModelModelByName_Offset shall fail and return 0. ]*/
+    /*Codes_SRS_SCHEMA_02_054: [ If propertyName is NULL then Schema_GetModelModelByName_Offset shall fail and return 0. ]*/
+    if (
+        (modelTypeHandle == NULL) ||
+        (propertyName == NULL)
+        )
+    {
+        /*Codes_SRS_SCHEMA_99_171: [If Schema_GetModelModelByName is unable to provide the handle it shall return NULL.]*/
+        result = 0;
+        LogError("error SCHEMA_INVALID_ARG");
+    }
+    else
+    {
+        SCHEMA_MODEL_TYPE_HANDLE_DATA* model = (SCHEMA_MODEL_TYPE_HANDLE_DATA*)modelTypeHandle;
+        /*Codes_SRS_SCHEMA_02_056: [ If propertyName is not a model then Schema_GetModelModelByName_Offset shall fail and return 0. ]*/
+        void* temp = VECTOR_find_if(model->models, matchModelName, propertyName);
+        if (temp == NULL)
+        {
+            LogError("specified propertyName not found (%s)", propertyName);
+            result = 0;
+        }
+        else
+        {
+            /*Codes_SRS_SCHEMA_02_055: [ Otherwise Schema_GetModelModelByName_Offset shall succeed and return the offset. ]*/
+            result = ((MODEL_IN_MODEL*)temp)->offset;
+        }
+    }
+    return result;
+}
+
+pfOnDesiredProperty Schema_GetModelModelByName_OnDesiredProperty(SCHEMA_MODEL_TYPE_HANDLE modelTypeHandle, const char* propertyName)
+{
+    pfOnDesiredProperty result;
+    /*Codes_SRS_SCHEMA_02_086: [ If modelTypeHandle is NULL then Schema_GetModelModelByName_OnDesiredProperty shall return NULL. ]*/
+    /*Codes_SRS_SCHEMA_02_087: [ If propertyName is NULL then Schema_GetModelModelByName_OnDesiredProperty shall return NULL. ]*/
+    if (
+        (modelTypeHandle == NULL) ||
+        (propertyName == NULL)
+        )
+    {
+        result = NULL;
+        LogError("invalid argument SCHEMA_MODEL_TYPE_HANDLE modelTypeHandle=%p, const char* propertyName=%p",modelTypeHandle, propertyName);
+    }
+    else
+    {
+        SCHEMA_MODEL_TYPE_HANDLE_DATA* model = (SCHEMA_MODEL_TYPE_HANDLE_DATA*)modelTypeHandle;
+        void* temp = VECTOR_find_if(model->models, matchModelName, propertyName);
+        if (temp == NULL)
+        {
+            LogError("specified propertyName not found (%s)", propertyName);
+            result = NULL;
+        }
+        else
+        {
+            /*Codes_SRS_SCHEMA_02_089: [ Otherwise Schema_GetModelModelByName_OnDesiredProperty shall return the desired property callback. ]*/
+            result = ((MODEL_IN_MODEL*)temp)->onDesiredProperty;
+        }
+    }
+    return result;
+
+}
+
+size_t Schema_GetModelModelByIndex_Offset(SCHEMA_MODEL_TYPE_HANDLE modelTypeHandle, size_t index)
+{
+    size_t result;
+    /*Codes_SRS_SCHEMA_02_057: [ If modelTypeHandle is NULL then Schema_GetModelModelByIndex_Offset shall fail and return 0. ]*/
+    if (modelTypeHandle == NULL)
+    {
+        result = 0;
+        LogError("error SCHEMA_INVALID_ARG");
+    }
+    else
+    {
+        SCHEMA_MODEL_TYPE_HANDLE_DATA* model = (SCHEMA_MODEL_TYPE_HANDLE_DATA*)modelTypeHandle;
+        /*Codes_SRS_SCHEMA_02_058: [ If index is not valid then Schema_GetModelModelByIndex_Offset shall fail and return 0. ]*/
+        void* temp = VECTOR_element(model->models, index);
+        if (temp == 0)
+        {
+            LogError("specified index [out of bounds] (%lu)", (unsigned long)index);
+            result = 0;
+        }
+        else
+        {
+            /*Codes_SRS_SCHEMA_02_059: [ Otherwise Schema_GetModelModelByIndex_Offset shall succeed and return the offset. ]*/
+            result = ((MODEL_IN_MODEL*)temp)->offset;
+        }
+    }
+    return result;
+}
+
+SCHEMA_MODEL_TYPE_HANDLE Schema_GetModelModelyByIndex(SCHEMA_MODEL_TYPE_HANDLE modelTypeHandle, size_t index)
+{
+    SCHEMA_MODEL_TYPE_HANDLE result;
+    if (modelTypeHandle == NULL)
+    {
+        /*Codes_SRS_SCHEMA_99_173: [Schema_GetModelModelyByIndex shall return NULL in the cases when it cannot provide the handle.]*/
+        result = NULL;
+        LogError("error SCHEMA_INVALID_ARG");
+    }
+    else
+    {
+        SCHEMA_MODEL_TYPE_HANDLE_DATA* model = (SCHEMA_MODEL_TYPE_HANDLE_DATA*)modelTypeHandle;
+        size_t nModelsInModel;
+        /*Codes_SRS_SCHEMA_99_172: [ Schema_GetModelModelyByIndex shall return a handle to the "index"th model inserted in the model identified by the parameter modelTypeHandle.]*/
+        /*Codes_SRS_SCHEMA_99_173: [Schema_GetModelModelyByIndex shall return NULL in the cases when it cannot provide the handle.]*/
+        nModelsInModel = VECTOR_size(model->models);
+        if (index < nModelsInModel)
+        {
+            result = ((MODEL_IN_MODEL*)VECTOR_element(model->models, index))->modelHandle;
+        }
+        else
+        {
+            LogError("attempted out of bounds access in array.");
+            result = NULL; /*out of bounds array access*/
+        }
+    }
+    return result;
+}
+
+const char* Schema_GetModelModelPropertyNameByIndex(SCHEMA_MODEL_TYPE_HANDLE modelTypeHandle, size_t index)
+{
+    const char* result;
+    if (modelTypeHandle == NULL)
+    {
+        /*Codes_SRS_SCHEMA_99_176: [If Schema_GetModelModelPropertyNameByIndex cannot produce the property name, it shall return NULL.]*/
+        result = NULL;
+    }
+    else
+    {
+        SCHEMA_MODEL_TYPE_HANDLE_DATA* model = (SCHEMA_MODEL_TYPE_HANDLE_DATA*)modelTypeHandle;
+        size_t nModelsInModel;
+        /*Codes_SRS_SCHEMA_99_175: [Schema_GetModelModelPropertyNameByIndex shall return the name of the property for the "index"th model in the model identified by modelTypeHandle parameter.]*/
+        /*Codes_SRS_SCHEMA_99_176: [If Schema_GetModelModelPropertyNameByIndex cannot produce the property name, it shall return NULL.]*/
+        nModelsInModel = VECTOR_size(model->models);
+        if (index < nModelsInModel)
+        {
+            result = ((MODEL_IN_MODEL*)VECTOR_element(model->models, index))->propertyName;
+        }
+        else
+        {
+            LogError("attempted out of bounds access in array.");
+            result = NULL; /*out of bounds array access*/
+        }
+    }
+    return result;
+}
+
+bool Schema_ModelPropertyByPathExists(SCHEMA_MODEL_TYPE_HANDLE modelTypeHandle, const char* propertyPath)
+{
+    bool result;
+
+    /* Codes_SRS_SCHEMA_99_180: [If any of the arguments are NULL, Schema_ModelPropertyByPathExists shall return false.] */
+    if ((modelTypeHandle == NULL) ||
+        (propertyPath == NULL))
+    {
+        LogError("error SCHEMA_INVALID_ARG");
+        result = false;
+    }
+    else
+    {
+        const char* slashPos;
+        result = false;
+
+        /* Codes_SRS_SCHEMA_99_182: [A single slash ('/') at the beginning of the path shall be ignored and the path shall still be valid.] */
+        if (*propertyPath == '/')
+        {
+            propertyPath++;
+        }
+
+        do
+        {
+            const char* endPos;
+            size_t i;
+            size_t modelCount;
+            SCHEMA_MODEL_TYPE_HANDLE_DATA* modelType = (SCHEMA_MODEL_TYPE_HANDLE_DATA*)modelTypeHandle;
+
+            /* Codes_SRS_SCHEMA_99_179: [The propertyPath shall be assumed to be in the format model1/model2/.../propertyName.] */
+            slashPos = strchr(propertyPath, '/');
+            endPos = slashPos;
+            if (endPos == NULL)
+            {
+                endPos = &propertyPath[strlen(propertyPath)];
+            }
+
+            /* get the child-model */
+            modelCount = VECTOR_size(modelType->models);
+            for (i = 0; i < modelCount; i++)
+            {
+                MODEL_IN_MODEL* childModel = (MODEL_IN_MODEL*)VECTOR_element(modelType->models, i);
+                if ((strncmp(childModel->propertyName, propertyPath, endPos - propertyPath) == 0) &&
+                    (strlen(childModel->propertyName) == (size_t)(endPos - propertyPath)))
+                {
+                    /* found */
+                    modelTypeHandle = childModel->modelHandle;
+                    break;
+                }
+            }
+
+            if (i < modelCount)
+            {
+                /* model found, check if there is more in the path */
+                if (slashPos == NULL)
+                {
+                    /* this is the last one, so this is the thing we were looking for */
+                    result = true;
+                    break;
+                }
+                else
+                {
+                    /* continue looking, there's more  */
+                    propertyPath = slashPos + 1;
+                }
+            }
+            else
+            {
+                /* no model found, let's see if this is a property */
+                /* Codes_SRS_SCHEMA_99_178: [The argument propertyPath shall be used to find the leaf property.] */
+                for (i = 0; i < modelType->PropertyCount; i++)
+                {
+                    SCHEMA_PROPERTY_HANDLE_DATA* property = (SCHEMA_PROPERTY_HANDLE_DATA*)modelType->Properties[i];
+                    if ((strncmp(property->PropertyName, propertyPath, endPos - propertyPath) == 0) &&
+                        (strlen(property->PropertyName) == (size_t)(endPos - propertyPath)))
+                    {
+                        /* found property */
+                        /* Codes_SRS_SCHEMA_99_177: [Schema_ModelPropertyByPathExists shall return true if a leaf property exists in the model modelTypeHandle.] */
+                        result = true;
+                        break;
+                    }
+                }
+
+                break;
+            }
+        } while (slashPos != NULL);
+    }
+
+    return result;
+}
+
+bool Schema_ModelReportedPropertyByPathExists(SCHEMA_MODEL_TYPE_HANDLE modelTypeHandle, const char* reportedPropertyPath)
+{
+    bool result;
+
+    /*Codes_SRS_SCHEMA_02_018: [ If argument modelTypeHandle is NULL then Schema_ModelReportedPropertyByPathExists shall fail and return false. ]*/
+    /*Codes_SRS_SCHEMA_02_019: [ If argument reportedPropertyPath is NULL then Schema_ModelReportedPropertyByPathExists shall fail and return false. ]*/
+    if ((modelTypeHandle == NULL) ||
+        (reportedPropertyPath == NULL))
+    {
+        LogError("invalid argument SCHEMA_MODEL_TYPE_HANDLE modelTypeHandle=%p, const char* reportedPropertyPath=%s", modelTypeHandle, reportedPropertyPath);
+        result = false;
+    }
+    else
+    {
+        const char* slashPos;
+
+        /*Codes_SRS_SCHEMA_02_021: [ If the reported property cannot be found Schema_ModelReportedPropertyByPathExists shall fail and return false. ]*/
+        result = false;
+
+        /*Codes_SRS_SCHEMA_02_020: [ reportedPropertyPath shall be assumed to be in the format model1/model2/.../reportedPropertyName. ]*/
+        if (*reportedPropertyPath == '/')
+        {
+            reportedPropertyPath++;
+        }
+
+        do
+        {
+            const char* endPos;
+            size_t i;
+            size_t modelCount;
+            SCHEMA_MODEL_TYPE_HANDLE_DATA* modelType = (SCHEMA_MODEL_TYPE_HANDLE_DATA*)modelTypeHandle;
+
+            slashPos = strchr(reportedPropertyPath, '/');
+            endPos = slashPos;
+            if (endPos == NULL)
+            {
+                endPos = &reportedPropertyPath[strlen(reportedPropertyPath)];
+            }
+
+            modelCount = VECTOR_size(modelType->models);
+            for (i = 0; i < modelCount; i++)
+            {
+                MODEL_IN_MODEL* childModel = (MODEL_IN_MODEL*)VECTOR_element(modelType->models, i);
+                if ((strncmp(childModel->propertyName, reportedPropertyPath, endPos - reportedPropertyPath) == 0) &&
+                    (strlen(childModel->propertyName) == (size_t)(endPos - reportedPropertyPath)))
+                {
+                    /* found */
+                    modelTypeHandle = childModel->modelHandle;
+                    break;
+                }
+            }
+
+            if (i < modelCount)
+            {
+                /* model found, check if there is more in the path */
+                if (slashPos == NULL)
+                {
+                    /*Codes_SRS_SCHEMA_02_022: [ If the path reportedPropertyPath points to a sub-model, Schema_ModelReportedPropertyByPathExists shall succeed and true. ]*/
+                    /* this is the last one, so this is the thing we were looking for */
+                    result = true;
+                    break;
+                }
+                else
+                {
+                    /* continue looking, there's more  */
+                    reportedPropertyPath = slashPos + 1;
+                }
+            }
+            else
+            {
+                /* no model found, let's see if this is a property */
+                result = (VECTOR_find_if(modelType->reportedProperties, reportedPropertyExists, reportedPropertyPath) != NULL);
+                if (!result)
+                {
+                    LogError("no such reported property \"%s\"", reportedPropertyPath);
+                }
+                break;
+            }
+        } while (slashPos != NULL);
+    }
+
+    return result;
+}
+
+static bool desiredPropertyExists(const void* element, const void* value)
+{
+    SCHEMA_DESIRED_PROPERTY_HANDLE_DATA* desiredProperty = *(SCHEMA_DESIRED_PROPERTY_HANDLE_DATA**)element;
+    return (strcmp(desiredProperty->desiredPropertyName, value) == 0);
+}
+
+SCHEMA_RESULT Schema_AddModelDesiredProperty(SCHEMA_MODEL_TYPE_HANDLE modelTypeHandle, const char* desiredPropertyName, const char* desiredPropertyType, pfDesiredPropertyFromAGENT_DATA_TYPE desiredPropertyFromAGENT_DATA_TYPE, pfDesiredPropertyInitialize desiredPropertyInitialize, pfDesiredPropertyDeinitialize desiredPropertyDeinitialize, size_t offset, pfOnDesiredProperty onDesiredProperty)
+{
+    SCHEMA_RESULT result;
+    /*Codes_SRS_SCHEMA_02_024: [ If modelTypeHandle is NULL then Schema_AddModelDesiredProperty shall fail and return SCHEMA_INVALID_ARG. ]*/
+    /*Codes_SRS_SCHEMA_02_025: [ If desiredPropertyName is NULL then Schema_AddModelDesiredProperty shall fail and return SCHEMA_INVALID_ARG. ]*/
+    /*Codes_SRS_SCHEMA_02_026: [ If desiredPropertyType is NULL then Schema_AddModelDesiredProperty shall fail and return SCHEMA_INVALID_ARG. ]*/
+    /*Codes_SRS_SCHEMA_02_048: [ If desiredPropertyFromAGENT_DATA_TYPE is NULL then Schema_AddModelDesiredProperty shall fail and return SCHEMA_INVALID_ARG. ]*/
+    /*Codes_SRS_SCHEMA_02_049: [ If desiredPropertyInitialize is NULL then Schema_AddModelDesiredProperty shall fail and return SCHEMA_INVALID_ARG. ]*/
+    /*Codes_SRS_SCHEMA_02_050: [ If desiredPropertyDeinitialize is NULL then Schema_AddModelDesiredProperty shall fail and return SCHEMA_INVALID_ARG. ]*/
+    if (
+        (modelTypeHandle == NULL) ||
+        (desiredPropertyName == NULL) ||
+        (desiredPropertyType == NULL) ||
+        (desiredPropertyFromAGENT_DATA_TYPE == NULL) ||
+        (desiredPropertyInitialize == NULL) ||
+        (desiredPropertyDeinitialize== NULL)
+        )
+    {
+        LogError("invalid arg SCHEMA_MODEL_TYPE_HANDLE modelTypeHandle=%p, const char* desiredPropertyName=%p, const char* desiredPropertyType=%p, pfDesiredPropertyFromAGENT_DATA_TYPE desiredPropertyFromAGENT_DATA_TYPE=%p, pfDesiredPropertyInitialize desiredPropertyInitialize=%p, pfDesiredPropertyDeinitialize desiredPropertyDeinitialize=%p, size_t offset=%lu",
+            modelTypeHandle, desiredPropertyName, desiredPropertyType, desiredPropertyFromAGENT_DATA_TYPE, desiredPropertyInitialize, desiredPropertyDeinitialize, (unsigned long)offset);
+        result = SCHEMA_INVALID_ARG;
+    }
+    else
+    {
+        SCHEMA_MODEL_TYPE_HANDLE_DATA* handleData = (SCHEMA_MODEL_TYPE_HANDLE_DATA*)modelTypeHandle;
+        /*Codes_SRS_SCHEMA_02_027: [ Schema_AddModelDesiredProperty shall add the desired property given by the name desiredPropertyName and the type desiredPropertyType to the collection of existing desired properties. ]*/
+        if (VECTOR_find_if(handleData->desiredProperties, desiredPropertyExists, desiredPropertyName) != NULL)
+        {
+            /*Codes_SRS_SCHEMA_02_047: [ If the desired property already exists, then Schema_AddModelDesiredProperty shall fail and return SCHEMA_DUPLICATE_ELEMENT. ]*/
+            LogError("unable to Schema_AddModelDesiredProperty because a desired property with the same name (%s) already exists", desiredPropertyName);
+            result = SCHEMA_DUPLICATE_ELEMENT;
+        }
+        else
+        {
+            SCHEMA_DESIRED_PROPERTY_HANDLE_DATA* desiredProperty = (SCHEMA_DESIRED_PROPERTY_HANDLE_DATA*)calloc(1, sizeof(SCHEMA_DESIRED_PROPERTY_HANDLE_DATA));
+            if (desiredProperty == NULL)
+            {
+                /*Codes_SRS_SCHEMA_02_028: [ If any failure occurs then Schema_AddModelDesiredProperty shall fail and return SCHEMA_ERROR. ]*/
+                LogError("failure in malloc");
+                result = SCHEMA_ERROR;
+            }
+            else
+            {
+                if (mallocAndStrcpy_s((char**)&desiredProperty->desiredPropertyName, desiredPropertyName) != 0)
+                {
+                    /*Codes_SRS_SCHEMA_02_028: [ If any failure occurs then Schema_AddModelDesiredProperty shall fail and return SCHEMA_ERROR. ]*/
+                    LogError("failure in mallocAndStrcpy_s");
+                    free(desiredProperty);
+                    result = SCHEMA_ERROR;
+                }
+                else
+                {
+                    if (mallocAndStrcpy_s((char**)&desiredProperty->desiredPropertyType, desiredPropertyType) != 0)
+                    {
+                        /*Codes_SRS_SCHEMA_02_028: [ If any failure occurs then Schema_AddModelDesiredProperty shall fail and return SCHEMA_ERROR. ]*/
+                        LogError("failure in mallocAndStrcpy_s");
+                        free((void*)desiredProperty->desiredPropertyName);
+                        free(desiredProperty);
+                        result = SCHEMA_ERROR;
+                    }
+                    else
+                    {
+                        if (VECTOR_push_back(handleData->desiredProperties, &desiredProperty, 1) != 0)
+                        {
+                            /*Codes_SRS_SCHEMA_02_028: [ If any failure occurs then Schema_AddModelDesiredProperty shall fail and return SCHEMA_ERROR. ]*/
+                            LogError("failure in VECTOR_push_back");
+                            free((void*)desiredProperty->desiredPropertyType);
+                            free((void*)desiredProperty->desiredPropertyName);
+                            free(desiredProperty);
+                            result = SCHEMA_ERROR;
+                        }
+                        else
+                        {
+                            /*Codes_SRS_SCHEMA_02_029: [ Otherwise, Schema_AddModelDesiredProperty shall succeed and return SCHEMA_OK. ]*/
+                            desiredProperty->desiredPropertyFromAGENT_DATA_TYPE = desiredPropertyFromAGENT_DATA_TYPE;
+                            desiredProperty->desiredPropertInitialize = desiredPropertyInitialize;
+                            desiredProperty->desiredPropertDeinitialize = desiredPropertyDeinitialize;
+                            desiredProperty->onDesiredProperty = onDesiredProperty; /*NULL is a perfectly fine value*/
+                            desiredProperty->offset = offset;
+                            result = SCHEMA_OK;
+                        }
+                    }
+                }
+            }
+        }
+    }
+    return result;
+}
+
+
+SCHEMA_RESULT Schema_GetModelDesiredPropertyCount(SCHEMA_MODEL_TYPE_HANDLE modelTypeHandle, size_t* desiredPropertyCount)
+{
+    SCHEMA_RESULT result;
+    /*Codes_SRS_SCHEMA_02_030: [ If modelTypeHandle is NULL then Schema_GetModelDesiredPropertyCount shall fail and return SCHEMA_INVALID_ARG. ]*/
+    /*Codes_SRS_SCHEMA_02_031: [ If desiredPropertyCount is NULL then Schema_GetModelDesiredPropertyCount shall fail and return SCHEMA_INVALID_ARG. ]*/
+    if (
+        (modelTypeHandle == NULL) ||
+        (desiredPropertyCount == NULL)
+        )
+    {
+        LogError("invalid arg: SCHEMA_MODEL_TYPE_HANDLE modelTypeHandle=%p, size_t* desiredPropertyCount=%p", modelTypeHandle, desiredPropertyCount);
+        result = SCHEMA_INVALID_ARG;
+    }
+    else
+    {
+        /*Codes_SRS_SCHEMA_02_032: [ Otherwise, Schema_GetModelDesiredPropertyCount shall succeed and write in desiredPropertyCount the existing number of desired properties. ]*/
+        SCHEMA_MODEL_TYPE_HANDLE_DATA* handleData = (SCHEMA_MODEL_TYPE_HANDLE_DATA*)modelTypeHandle;
+        *desiredPropertyCount = VECTOR_size(handleData->desiredProperties);
+        result = SCHEMA_OK;
+    }
+    return result;
+}
+
+SCHEMA_DESIRED_PROPERTY_HANDLE Schema_GetModelDesiredPropertyByName(SCHEMA_MODEL_TYPE_HANDLE modelTypeHandle, const char* desiredPropertyName)
+{
+    SCHEMA_DESIRED_PROPERTY_HANDLE result;
+    /*Codes_SRS_SCHEMA_02_034: [ If modelTypeHandle is NULL then Schema_GetModelDesiredPropertyByName shall fail and return NULL. ]*/
+    /*Codes_SRS_SCHEMA_02_035: [ If desiredPropertyName is NULL then Schema_GetModelDesiredPropertyByName shall fail and return NULL. ]*/
+    if (
+        (modelTypeHandle == NULL) ||
+        (desiredPropertyName == NULL)
+        )
+    {
+        LogError("invalid arg SCHEMA_MODEL_TYPE_HANDLE modelTypeHandle=%p, const char* desiredPropertyName=%p", modelTypeHandle, desiredPropertyName);
+        result = NULL;
+    }
+    else
+    {
+        /*Codes_SRS_SCHEMA_02_036: [ If a desired property having the name desiredPropertyName exists then Schema_GetModelDesiredPropertyByName shall succeed and return a non-NULL value. ]*/
+        /*Codes_SRS_SCHEMA_02_037: [ Otherwise, Schema_GetModelDesiredPropertyByName shall fail and return NULL. ]*/
+        SCHEMA_MODEL_TYPE_HANDLE_DATA* handleData = (SCHEMA_MODEL_TYPE_HANDLE_DATA*)modelTypeHandle;
+        SCHEMA_DESIRED_PROPERTY_HANDLE* temp = VECTOR_find_if(handleData->desiredProperties, desiredPropertyExists, desiredPropertyName);
+        if (temp == NULL)
+        {
+            LogError("no such desired property by name %s", desiredPropertyName);
+            result = NULL;
+        }
+        else
+        {
+            result = *temp;
+        }
+    }
+    return result;
+}
+
+SCHEMA_DESIRED_PROPERTY_HANDLE Schema_GetModelDesiredPropertyByIndex(SCHEMA_MODEL_TYPE_HANDLE modelTypeHandle, size_t index)
+{
+    SCHEMA_DESIRED_PROPERTY_HANDLE result;
+    /*Codes_SRS_SCHEMA_02_038: [ If modelTypeHandle is NULL then Schema_GetModelDesiredPropertyByIndex shall fail and return NULL. ]*/
+    if (modelTypeHandle == NULL)
+    {
+        LogError("invalid argument SCHEMA_MODEL_TYPE_HANDLE modelTypeHandle=%p, size_t index=%lu", modelTypeHandle, (unsigned long)index);
+        result = NULL;
+    }
+    else
+    {
+        SCHEMA_MODEL_TYPE_HANDLE_DATA* handleData = (SCHEMA_MODEL_TYPE_HANDLE_DATA*)modelTypeHandle;
+        /*Codes_SRS_SCHEMA_02_039: [ If index is outside the range for existing indexes of desire properties, then Schema_GetModelDesiredPropertyByIndex shall fail and return NULL. ]*/
+        /*Codes_SRS_SCHEMA_02_040: [ Otherwise, Schema_GetModelDesiredPropertyByIndex shall succeed and return a non-NULL value. ]*/
+        SCHEMA_DESIRED_PROPERTY_HANDLE* temp = VECTOR_element(handleData->desiredProperties, index);
+        if (temp == NULL)
+        {
+            LogError("VECTOR_element produced NULL (likely out of bounds index)");
+            result = NULL;
+        }
+        else
+        {
+            result = *temp;
+        }
+    }
+    return result;
+}
+
+bool Schema_ModelDesiredPropertyByPathExists(SCHEMA_MODEL_TYPE_HANDLE modelTypeHandle, const char* desiredPropertyPath)
+{
+    bool result;
+    /*Codes_SRS_SCHEMA_02_041: [ If modelTypeHandle is NULL then Schema_ModelDesiredPropertyByPathExists shall fail and return false. ]*/
+    /*Codes_SRS_SCHEMA_02_042: [ If desiredPropertyPath is NULL then Schema_ModelDesiredPropertyByPathExists shall fail and return false. ]*/
+    if (
+        (modelTypeHandle == NULL) ||
+        (desiredPropertyPath == NULL)
+        )
+    {
+        LogError("invalid arg SCHEMA_MODEL_TYPE_HANDLE modelTypeHandle=%p, const char* desiredPropertyPath=%p", modelTypeHandle, desiredPropertyPath);
+        result = false;
+    }
+    else
+    {
+        const char* slashPos;
+
+        /*Codes_SRS_SCHEMA_02_044: [ If the desired property cannot be found Schema_ModelDesiredPropertyByPathExists shall fail and return false. ]*/
+        result = false;
+
+        /*Codes_SRS_SCHEMA_02_043: [ desiredPropertyPath shall be assumed to be in the format model1/model2/.../desiredPropertyName. ]*/
+        if (*desiredPropertyPath == '/')
+        {
+            desiredPropertyPath++;
+        }
+
+        do
+        {
+            const char* endPos;
+            size_t i;
+            size_t modelCount;
+            SCHEMA_MODEL_TYPE_HANDLE_DATA* modelType = (SCHEMA_MODEL_TYPE_HANDLE_DATA*)modelTypeHandle;
+
+            slashPos = strchr(desiredPropertyPath, '/');
+            endPos = slashPos;
+            if (endPos == NULL)
+            {
+                endPos = &desiredPropertyPath[strlen(desiredPropertyPath)];
+            }
+
+            modelCount = VECTOR_size(modelType->models);
+            for (i = 0; i < modelCount; i++)
+            {
+                MODEL_IN_MODEL* childModel = (MODEL_IN_MODEL*)VECTOR_element(modelType->models, i);
+                if ((strncmp(childModel->propertyName, desiredPropertyPath, endPos - desiredPropertyPath) == 0) &&
+                    (strlen(childModel->propertyName) == (size_t)(endPos - desiredPropertyPath)))
+                {
+                    /* found */
+                    modelTypeHandle = childModel->modelHandle;
+                    break;
+                }
+            }
+
+            if (i < modelCount)
+            {
+                /* model found, check if there is more in the path */
+                if (slashPos == NULL)
+                {
+                    /*Codes_SRS_SCHEMA_02_045: [ If the path desiredPropertyPath points to a sub-model, Schema_ModelDesiredPropertyByPathExists shall succeed and true. ]*/
+                    /* this is the last one, so this is the thing we were looking for */
+                    result = true;
+                    break;
+                }
+                else
+                {
+                    /* continue looking, there's more  */
+                    desiredPropertyPath = slashPos + 1;
+                }
+            }
+            else
+            {
+                /* no model found, let's see if this is a property */
+                result = (VECTOR_find_if(modelType->desiredProperties, desiredPropertyExists, desiredPropertyPath) != NULL);
+                if (!result)
+                {
+                    LogError("no such desired property \"%s\"", desiredPropertyPath);
+                }
+                break;
+            }
+        } while (slashPos != NULL);
+    }
+    return result;
+}
+
+const char* Schema_GetModelDesiredPropertyType(SCHEMA_DESIRED_PROPERTY_HANDLE desiredPropertyHandle)
+{
+    const char* result;
+    /*Codes_SRS_SCHEMA_02_062: [ If desiredPropertyHandle is NULL then Schema_GetModelDesiredPropertyType shall fail and return NULL. ]*/
+    if (desiredPropertyHandle == NULL)
+    {
+        LogError("invalid argument SCHEMA_DESIRED_PROPERTY_HANDLE desiredPropertyHandle=%p", desiredPropertyHandle);
+        result = NULL;
+    }
+    else
+    {
+        /*Codes_SRS_SCHEMA_02_063: [ Otherwise, Schema_GetModelDesiredPropertyType shall return the type of the desired property. ]*/
+        SCHEMA_DESIRED_PROPERTY_HANDLE_DATA* desirePropertyHandleData = (SCHEMA_DESIRED_PROPERTY_HANDLE_DATA*)desiredPropertyHandle;
+        result = desirePropertyHandleData->desiredPropertyType;
+    }
+    return result;
+}
+
+pfDesiredPropertyFromAGENT_DATA_TYPE Schema_GetModelDesiredProperty_pfDesiredPropertyFromAGENT_DATA_TYPE(SCHEMA_DESIRED_PROPERTY_HANDLE desiredPropertyHandle)
+{
+    pfDesiredPropertyFromAGENT_DATA_TYPE result;
+    if (desiredPropertyHandle == NULL)
+    {
+        LogError("invalid argument SCHEMA_DESIRED_PROPERTY_HANDLE desiredPropertyHandle=%p", desiredPropertyHandle);
+        result = NULL;
+    }
+    else
+    {
+        SCHEMA_DESIRED_PROPERTY_HANDLE_DATA* desirePropertyHandleData = (SCHEMA_DESIRED_PROPERTY_HANDLE_DATA*)desiredPropertyHandle;
+        result = desirePropertyHandleData->desiredPropertyFromAGENT_DATA_TYPE;
+    }
+    return result;
+}
+
+pfOnDesiredProperty Schema_GetModelDesiredProperty_pfOnDesiredProperty(SCHEMA_DESIRED_PROPERTY_HANDLE desiredPropertyHandle)
+{
+    pfOnDesiredProperty result;
+    /*Codes_SRS_SCHEMA_02_084: [ If desiredPropertyHandle is NULL then Schema_GetModelDesiredProperty_pfOnDesiredProperty shall return NULL. ]*/
+    if (desiredPropertyHandle == NULL)
+    {
+        LogError("invalid argument SCHEMA_DESIRED_PROPERTY_HANDLE desiredPropertyHandle=%p", desiredPropertyHandle);
+        result = NULL;
+    }
+    else
+    {
+        /*Codes_SRS_SCHEMA_02_085: [ Otherwise Schema_GetModelDesiredProperty_pfOnDesiredProperty shall return the saved desired property callback. ]*/
+        SCHEMA_DESIRED_PROPERTY_HANDLE_DATA* desirePropertyHandleData = (SCHEMA_DESIRED_PROPERTY_HANDLE_DATA*)desiredPropertyHandle;
+        result = desirePropertyHandleData->onDesiredProperty;
+    }
+    return result;
+}
+
+size_t Schema_GetModelDesiredProperty_offset(SCHEMA_DESIRED_PROPERTY_HANDLE desiredPropertyHandle)
+{
+    size_t result;
+    /*Codes_SRS_SCHEMA_02_060: [ If desiredPropertyHandle is NULL then Schema_GetModelDesiredProperty_offset shall fail and return 0. ]*/
+    if (desiredPropertyHandle == NULL)
+    {
+        LogError("invalid argument SCHEMA_DESIRED_PROPERTY_HANDLE desiredPropertyHandle=%p", desiredPropertyHandle);
+        result = 0;
+    }
+    else
+    {
+        /*Codes_SRS_SCHEMA_02_061: [ Otherwise Schema_GetModelDesiredProperty_offset shall succeed and return the offset. ]*/
+        SCHEMA_DESIRED_PROPERTY_HANDLE_DATA* desirePropertyHandleData = (SCHEMA_DESIRED_PROPERTY_HANDLE_DATA*)desiredPropertyHandle;
+        result = desirePropertyHandleData->offset;
+    }
+    return result;
+}
+
+static bool modelInModelExists(const void* element, const void* value)
+{
+    MODEL_IN_MODEL* modelInModel = (MODEL_IN_MODEL*)element;
+    return (strcmp(modelInModel->propertyName, value) == 0);
+}
+
+SCHEMA_MODEL_ELEMENT Schema_GetModelElementByName(SCHEMA_MODEL_TYPE_HANDLE modelTypeHandle, const char* elementName)
+{
+    SCHEMA_MODEL_ELEMENT result;
+    /*Codes_SRS_SCHEMA_02_076: [ If modelTypeHandle is NULL then Schema_GetModelElementByName shall fail and set SCHEMA_MODEL_ELEMENT.elementType to SCHEMA_SEARCH_INVALID_ARG. ]*/
+    /*Codes_SRS_SCHEMA_02_077: [ If elementName is NULL then Schema_GetModelElementByName shall fail and set SCHEMA_MODEL_ELEMENT.elementType to SCHEMA_SEARCH_INVALID_ARG. ]*/
+    if (
+        (modelTypeHandle == NULL) ||
+        (elementName == NULL)
+        )
+    {
+        LogError("invalid argument SCHEMA_MODEL_TYPE_HANDLE modelTypeHandle=%p, const char* elementName=%p", modelTypeHandle, elementName);
+        result.elementType = SCHEMA_SEARCH_INVALID_ARG;
+    }
+    else
+    {
+        SCHEMA_MODEL_TYPE_HANDLE_DATA* handleData = (SCHEMA_MODEL_TYPE_HANDLE_DATA*)modelTypeHandle;
+
+        SCHEMA_DESIRED_PROPERTY_HANDLE* desiredPropertyHandle = VECTOR_find_if(handleData->desiredProperties, desiredPropertyExists, elementName);
+        if (desiredPropertyHandle != NULL)
+        {
+            /*Codes_SRS_SCHEMA_02_080: [ If elementName is a desired property then Schema_GetModelElementByName shall succeed and set SCHEMA_MODEL_ELEMENT.elementType to SCHEMA_DESIRED_PROPERTY and SCHEMA_MODEL_ELEMENT.elementHandle.desiredPropertyHandle to the handle of the desired property. ]*/
+            result.elementType = SCHEMA_DESIRED_PROPERTY;
+            result.elementHandle.desiredPropertyHandle = *desiredPropertyHandle;
+        }
+        else
+        {
+            size_t nProcessedProperties = 0;
+            SCHEMA_PROPERTY_HANDLE_DATA* property = NULL;
+            for (size_t i = 0; i < handleData->PropertyCount;i++)
+            {
+                property = (SCHEMA_PROPERTY_HANDLE_DATA*)(handleData->Properties[i]);
+                if (strcmp(property->PropertyName, elementName) == 0)
+                {
+                    i = handleData->PropertyCount; /*found it*/
+                }
+                else
+                {
+                    nProcessedProperties++;
+                }
+            }
+
+            if (nProcessedProperties < handleData->PropertyCount)
+            {
+                /*Codes_SRS_SCHEMA_02_078: [ If elementName is a property then Schema_GetModelElementByName shall succeed and set SCHEMA_MODEL_ELEMENT.elementType to SCHEMA_PROPERTY and SCHEMA_MODEL_ELEMENT.elementHandle.propertyHandle to the handle of the property. ]*/
+                result.elementType = SCHEMA_PROPERTY;
+                result.elementHandle.propertyHandle = property;
+            }
+            else
+            {
+
+                SCHEMA_REPORTED_PROPERTY_HANDLE* reportedPropertyHandle = VECTOR_find_if(handleData->reportedProperties, reportedPropertyExists, elementName);
+                if (reportedPropertyHandle != NULL)
+                {
+                    /*Codes_SRS_SCHEMA_02_079: [ If elementName is a reported property then Schema_GetModelElementByName shall succeed and set SCHEMA_MODEL_ELEMENT.elementType to SCHEMA_REPORTED_PROPERTY and SCHEMA_MODEL_ELEMENT.elementHandle.reportedPropertyHandle to the handle of the reported property. ]*/
+                    result.elementType = SCHEMA_REPORTED_PROPERTY;
+                    result.elementHandle.reportedPropertyHandle = *reportedPropertyHandle;
+                }
+                else
+                {
+
+                    size_t nProcessedActions = 0;
+                    SCHEMA_ACTION_HANDLE_DATA* actionHandleData = NULL;
+                    for (size_t i = 0;i < handleData->ActionCount; i++)
+                    {
+                        actionHandleData = (SCHEMA_ACTION_HANDLE_DATA*)(handleData->Actions[i]);
+                        if (strcmp(actionHandleData->ActionName, elementName) == 0)
+                        {
+                            i = handleData->ActionCount; /*get out quickly*/
+                        }
+                        else
+                        {
+                            nProcessedActions++;
+                        }
+                    }
+
+                    if (nProcessedActions < handleData->ActionCount)
+                    {
+                        /*Codes_SRS_SCHEMA_02_081: [ If elementName is a model action then Schema_GetModelElementByName shall succeed and set SCHEMA_MODEL_ELEMENT.elementType to SCHEMA_MODEL_ACTION and SCHEMA_MODEL_ELEMENT.elementHandle.actionHandle to the handle of the action. ]*/
+                        result.elementType = SCHEMA_MODEL_ACTION;
+                        result.elementHandle.actionHandle = actionHandleData;
+                    }
+                    else
+                    {
+                        MODEL_IN_MODEL* modelInModel = VECTOR_find_if(handleData->models, modelInModelExists, elementName);
+                        if (modelInModel != NULL)
+                        {
+                            /*Codes_SRS_SCHEMA_02_082: [ If elementName is a model in model then Schema_GetModelElementByName shall succeed and set SCHEMA_MODEL_ELEMENT.elementType to SCHEMA_MODEL_IN_MODEL and SCHEMA_MODEL_ELEMENT.elementHandle.modelHandle to the handle of the model. ]*/
+                            result.elementType = SCHEMA_MODEL_IN_MODEL;
+                            result.elementHandle.modelHandle = modelInModel->modelHandle;
+                        }
+                        else
+                        {
+                            /*Codes_SRS_SCHEMA_02_083: [ Otherwise Schema_GetModelElementByName shall fail and set SCHEMA_MODEL_ELEMENT.elementType to SCHEMA_NOT_FOUND. ]*/
+                            result.elementType = SCHEMA_NOT_FOUND;
+                        }
+                    }
+                }
+            }
+        }
+    }
+    return result;
+}
+
+pfDesiredPropertyDeinitialize Schema_GetModelDesiredProperty_pfDesiredPropertyDeinitialize(SCHEMA_DESIRED_PROPERTY_HANDLE desiredPropertyHandle)
+{
+    pfDesiredPropertyDeinitialize result;
+    /*Ccodes_SRS_SCHEMA_02_064: [ If desiredPropertyHandle is NULL then Schema_GetModelDesiredProperty_pfDesiredPropertyDeinitialize shall fail and return NULL. ]*/
+    if (desiredPropertyHandle == NULL)
+    {
+        LogError("invalid argument SCHEMA_DESIRED_PROPERTY_HANDLE desiredPropertyHandle=%p", desiredPropertyHandle);
+        result = NULL;
+    }
+    else
+    {
+        /*Codes_SRS_SCHEMA_02_065: [ Otherwise Schema_GetModelDesiredProperty_pfDesiredPropertyDeinitialize shall return a non-NULL function pointer. ]*/
+        SCHEMA_DESIRED_PROPERTY_HANDLE_DATA* handleData = (SCHEMA_DESIRED_PROPERTY_HANDLE_DATA*)desiredPropertyHandle;
+        result = handleData->desiredPropertDeinitialize;
+    }
+    return result;
+}
+
+pfDesiredPropertyInitialize Schema_GetModelDesiredProperty_pfDesiredPropertyInitialize(SCHEMA_DESIRED_PROPERTY_HANDLE desiredPropertyHandle)
+{
+    pfDesiredPropertyInitialize result;
+    /*Codes_SRS_SCHEMA_02_066: [ If desiredPropertyHandle is NULL then Schema_GetModelDesiredProperty_pfDesiredPropertyInitialize shall fail and return NULL. ]*/
+    if (desiredPropertyHandle == NULL)
+    {
+        LogError("invalid argument SCHEMA_DESIRED_PROPERTY_HANDLE desiredPropertyHandle=%p", desiredPropertyHandle);
+        result = NULL;
+    }
+    else
+    {
+        /*Codes_SRS_SCHEMA_02_067: [ Otherwise Schema_GetModelDesiredProperty_pfDesiredPropertyInitialize shall return a non-NULL function pointer. ]*/
+        SCHEMA_DESIRED_PROPERTY_HANDLE_DATA* handleData = (SCHEMA_DESIRED_PROPERTY_HANDLE_DATA*)desiredPropertyHandle;
+        result = handleData->desiredPropertInitialize;
+    }
+    return result;
+}
+
+static bool SchemaHasModel(const SCHEMA_HANDLE* schemaHandle, const char* modelName)
+{
+    return (Schema_GetModelByName(*schemaHandle, modelName) != NULL);
+}
+
+
+SCHEMA_HANDLE Schema_GetSchemaForModel(const char* modelName)
+{
+    SCHEMA_HANDLE result;
+    /*Codes_SRS_SCHEMA_02_093: [ If modelName is NULL then Schema_GetSchemaForModel shall fail and return NULL. ]*/
+    if (modelName == NULL)
+    {
+        LogError("invalid arg const char* modelName=%p", modelName);
+        result = NULL;
+    }
+    else
+    {
+        /*Codes_SRS_SCHEMA_02_094: [ Schema_GetSchemaForModel shall find the SCHEMA_HANDLE that contains a model by name modelName and if found, succeed and return that. ]*/
+        SCHEMA_HANDLE* temp = VECTOR_find_if(g_schemas, (PREDICATE_FUNCTION)SchemaHasModel, modelName);
+
+        if (temp == NULL)
+        {
+            /*Codes_SRS_SCHEMA_02_095: [ If the model is not found in any schema, then Schema_GetSchemaForModel shall fail and return NULL. ]*/
+            LogError("unable to find a schema that has a model named %s", modelName);
+            result = NULL;
+        }
+        else
+        {
+            /*Codes_SRS_SCHEMA_02_094: [ Schema_GetSchemaForModel shall find the SCHEMA_HANDLE that contains a model by name modelName and if found, succeed and return that. ]*/
+            result = *temp;
+        }
+    }
+
+    return result;
+}
+
+void* Schema_GetMetadata(SCHEMA_HANDLE schemaHandle)
+{
+    void* result;
+    /*Codes_SRS_SCHEMA_02_091: [ If schemaHandle is NULL then Schema_GetMetadata shall fail and return NULL. ]*/
+    if (schemaHandle == NULL)
+    {
+        LogError("invalid arg SCHEMA_HANDLE schemaHandle=%p", schemaHandle);
+        result = NULL;
+    }
+    else
+    {
+        /*Codes_SRS_SCHEMA_02_092: [ Otherwise, Schema_GetMetadata shall succeed and return the saved metadata pointer. ]*/
+        result = ((SCHEMA_HANDLE_DATA*)schemaHandle)->metadata;
+    }
+    return result;
+}
Index: azure_iot_hub_f767zi/trunk/azure_iot_sdk/serializer/src/schemalib.c
===================================================================
--- azure_iot_hub_f767zi/trunk/azure_iot_sdk/serializer/src/schemalib.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/azure_iot_sdk/serializer/src/schemalib.c	(revision 457)
@@ -0,0 +1,94 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+#include "azure_c_shared_utility/gballoc.h"
+
+#include "schemalib.h"
+#include "codefirst.h"
+#include "schema.h"
+#include "datamarshaller.h"
+#include "datapublisher.h"
+#include <stddef.h>
+#include "azure_c_shared_utility/xlogging.h"
+#include "iotdevice.h"
+
+#define DEFAULT_CONTAINER_NAME  "Container"
+
+MU_DEFINE_ENUM_STRINGS_WITHOUT_INVALID(SERIALIZER_RESULT, SERIALIZER_RESULT_VALUES);
+
+typedef enum AGENT_STATE_TAG
+{
+    AGENT_NOT_INITIALIZED,
+    AGENT_INITIALIZED
+} AGENT_STATE;
+
+static AGENT_STATE g_AgentState = AGENT_NOT_INITIALIZED;
+
+SERIALIZER_RESULT serializer_init(const char* overrideSchemaNamespace)
+{
+    SERIALIZER_RESULT result;
+
+    /* Codes_SRS_SCHEMALIB_99_074:[serializer_init when already initialized shall return SERIALIZER_ALREADY_INIT.] */
+    if (g_AgentState != AGENT_NOT_INITIALIZED)
+    {
+        result = SERIALIZER_ALREADY_INIT;
+        LogError("(result = %s)", MU_ENUM_TO_STRING(SERIALIZER_RESULT, result));
+    }
+    else
+    {
+        /* Codes_SRS_SCHEMALIB_99_006:[ Initialize CodeFirst by a call to CodeFirst_Init.] */
+        /* Codes_SRS_SCHEMALIB_99_076:[serializer_init shall pass the value of overrideSchemaNamespace argument to CodeFirst_Init.] */
+        if (CodeFirst_Init(overrideSchemaNamespace) != CODEFIRST_OK)
+        {
+            /* Codes_SRS_SCHEMALIB_99_007:[ On error SERIALIZER_CODEFIRST_INIT_FAILED shall be returned.] */
+            result = SERIALIZER_CODEFIRST_INIT_FAILED;
+            LogError("(result = %s)", MU_ENUM_TO_STRING(SERIALIZER_RESULT, result));
+        }
+        else
+        {
+            /* Codes_SRS_SCHEMALIB_99_075:[When an serializer_init call fails for any reason the previous initialization state shall be preserved. The initialized state shall only be changed on a succesfull Init.] */
+            g_AgentState = AGENT_INITIALIZED;
+
+            /* Codes_SRS_SCHEMALIB_99_073:[On success serializer_init shall return SERIALIZER_OK.] */
+            result = SERIALIZER_OK;
+        }
+    }
+
+    return result;
+}
+
+void serializer_deinit(void)
+{
+    /* Codes_SRS_SCHEMALIB_99_025:[ serializer_deinit shall de-initialize all modules initialized by serializer_init.] */
+    if (g_AgentState == AGENT_INITIALIZED)
+    {
+        CodeFirst_Deinit();
+    }
+
+    /* Codes_SRS_SCHEMALIB_99_026:[ A subsequent call to serializer_start shall succeed.] */
+    g_AgentState = AGENT_NOT_INITIALIZED;
+}
+
+SERIALIZER_RESULT serializer_setconfig(SERIALIZER_CONFIG which, void* value)
+{
+    SERIALIZER_RESULT result;
+
+    /* Codes_SRS_SCHEMALIB_99_137:[ If the value argument is NULL, serializer_setconfig shall return SERIALIZER_INVALID_ARG.] */
+    if (value == NULL)
+    {
+        result = SERIALIZER_INVALID_ARG;
+    }
+    /* Codes_SRS_SCHEMALIB_99_142:[ When the which argument is SerializeDelayedBufferMaxSize, serializer_setconfig shall invoke DataPublisher_SetMaxBufferSize with the dereferenced value argument, and shall return SERIALIZER_OK.] */
+    else if (which == SerializeDelayedBufferMaxSize)
+    {
+        DataPublisher_SetMaxBufferSize(*(size_t*)value);
+        result = SERIALIZER_OK;
+    }
+    /* Codes_SRS_SCHEMALIB_99_138:[ If the which argument is not one of the declared members of the SERIALIZER_CONFIG enum, serializer_setconfig shall return SERIALIZER_INVALID_ARG.] */
+    else
+    {
+        result = SERIALIZER_INVALID_ARG;
+    }
+
+    return result;
+}
Index: azure_iot_hub_f767zi/trunk/azure_iot_sdk/serializer/src/schemaserializer.c
===================================================================
--- azure_iot_hub_f767zi/trunk/azure_iot_sdk/serializer/src/schemaserializer.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/azure_iot_sdk/serializer/src/schemaserializer.c	(revision 457)
@@ -0,0 +1,174 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+#include <stdlib.h>
+#include "azure_c_shared_utility/gballoc.h"
+
+#include <stddef.h>
+#include "schemaserializer.h"
+#include "azure_c_shared_utility/xlogging.h"
+#include "azure_macro_utils/macro_utils.h"
+
+MU_DEFINE_ENUM_STRINGS_WITHOUT_INVALID(SCHEMA_SERIALIZER_RESULT, SCHEMA_SERIALIZER_RESULT_VALUES);
+
+#define LOG_SCHEMA_SERIALIZER_ERROR(result) LogError("(result = %s)", MU_ENUM_TO_STRING(SCHEMA_SERIALIZER_RESULT, (result)))
+
+static const char* ConvertType(const char* sourceType)
+{
+    /* Codes_SRS_SCHEMA_SERIALIZER_01_016: ["ascii_char_ptr" shall be translated to "string".] */
+    if (strcmp(sourceType, "ascii_char_ptr") == 0)
+    {
+        return "string";
+    }
+    else
+    {
+        /* Codes_SRS_SCHEMA_SERIALIZER_01_017: [All other types shall be kept as they are.] */
+        return sourceType;
+    }
+}
+
+/* Codes_SRS_SCHEMA_SERIALIZER_01_001: [SchemaSerializer_SerializeCommandMetadata shall serialize a specific model to a string using JSON as format.] */
+SCHEMA_SERIALIZER_RESULT SchemaSerializer_SerializeCommandMetadata(SCHEMA_MODEL_TYPE_HANDLE modelHandle, STRING_HANDLE schemaText)
+{
+    SCHEMA_SERIALIZER_RESULT result;
+
+    /* Codes_SRS_SCHEMA_SERIALIZER_01_013: [If the modelHandle argument is NULL, SchemaSerializer_SerializeCommandMetadata shall return SCHEMA_SERIALIZER_INVALID_ARG.] */
+    if ((modelHandle == NULL) ||
+        /* Codes_SRS_SCHEMA_SERIALIZER_01_014: [If the schemaText argument is NULL, SchemaSerializer_SerializeCommandMetadata shall return SCHEMA_SERIALIZER_INVALID_ARG.] */
+        (schemaText == NULL))
+    {
+        result = SCHEMA_SERIALIZER_INVALID_ARG;
+        LogError("(result = %s), modelHandle = %p, schemaText = %p", MU_ENUM_TO_STRING(SCHEMA_SERIALIZER_RESULT, result), modelHandle, schemaText);
+    }
+    else
+    {
+        size_t commandCount;
+
+        /* Codes_SRS_SCHEMA_SERIALIZER_01_002: [Only commands shall be serialized, the properties of a model shall be ignored.] */
+
+        /* Codes_SRS_SCHEMA_SERIALIZER_01_003: [The output JSON shall have an array, where each array element shall represent a command.] */
+        /* Codes_SRS_SCHEMA_SERIALIZER_01_011: [The JSON text shall be built into the string indicated by the schemaText argument by using String APIs.] */
+        if ((STRING_concat(schemaText, "[") != 0) ||
+            /* Codes_SRS_SCHEMA_SERIALIZER_01_006: [The object for a command shall have a member named Name, whose value shall be the command name as obtained by using Schema APIs.] */
+            (Schema_GetModelActionCount(modelHandle, &commandCount) != SCHEMA_OK))
+        {
+            /* Codes_SRS_SCHEMA_SERIALIZER_01_015: [If any of the Schema or String APIs fail then SchemaSerializer_SerializeCommandMetadata shall return SCHEMA_SERIALIZER_ERROR.] */
+            result = SCHEMA_SERIALIZER_ERROR;
+            LOG_SCHEMA_SERIALIZER_ERROR(result);
+        }
+        else
+        {
+            size_t i;
+
+            for (i = 0; i < commandCount; i++)
+            {
+                SCHEMA_ACTION_HANDLE actionHandle = Schema_GetModelActionByIndex(modelHandle, i);
+                const char* commandName;
+                size_t argCount;
+                size_t j;
+
+                /* Codes_SRS_SCHEMA_SERIALIZER_01_005: [Each array element shall be a JSON object.] */
+                if ((actionHandle == NULL) ||
+                    (STRING_concat(schemaText, "{ \"Name\":\"") != 0) ||
+                    ((commandName = Schema_GetModelActionName(actionHandle)) == NULL) ||
+                    (STRING_concat(schemaText, commandName) != 0) ||
+                    /* Codes_SRS_SCHEMA_SERIALIZER_01_007: [The object for a command shall also have a "Parameters" member.] */
+                    (STRING_concat(schemaText, "\", \"Parameters\":[") != 0) ||
+                    (Schema_GetModelActionArgumentCount(actionHandle, &argCount) != SCHEMA_OK))
+                {
+                    /* Codes_SRS_SCHEMA_SERIALIZER_01_015: [If any of the Schema or String APIs fail then SchemaSerializer_SerializeCommandMetadata shall return SCHEMA_SERIALIZER_ERROR.] */
+                    LogError("Failed encoding action.");
+                    break;
+                }
+                else
+                {
+                    for (j = 0; j < argCount; j++)
+                    {
+                        /* Codes_SRS_SCHEMA_SERIALIZER_01_008: [The parameters member shall be an array, where each entry is a command parameter.] */
+                        SCHEMA_ACTION_ARGUMENT_HANDLE argHandle = Schema_GetModelActionArgumentByIndex(actionHandle, j);
+                        const char* argName;
+                        const char* argType;
+
+                        /* Codes_SRS_SCHEMA_SERIALIZER_01_009: [Each command parameter shall have a member named "Name", that should have as value the command argument name as obtained by using Schema APIs.] */
+                        if ((argHandle == NULL) ||
+                            (STRING_concat(schemaText, "{\"Name\":\"") != 0) ||
+                            ((argName = Schema_GetActionArgumentName(argHandle)) == NULL) ||
+                            (STRING_concat(schemaText, argName) != 0) ||
+                            /* Codes_SRS_SCHEMA_SERIALIZER_01_010: [Each command parameter shall have a member named "Type", that should have as value the command argument type as obtained by using Schema APIs.] */
+                            (STRING_concat(schemaText, "\",\"Type\":\"") != 0) ||
+                            ((argType = Schema_GetActionArgumentType(argHandle)) == NULL) ||
+                            (STRING_concat(schemaText, ConvertType(argType)) != 0))
+                        {
+                            /* Codes_SRS_SCHEMA_SERIALIZER_01_015: [If any of the Schema or String APIs fail then SchemaSerializer_SerializeCommandMetadata shall return SCHEMA_SERIALIZER_ERROR.] */
+                            LogError("Failed encoding argument.");
+                            break;
+                        }
+                        else
+                        {
+                            if (j + 1 < argCount)
+                            {
+                                if (STRING_concat(schemaText, "\"},") != 0)
+                                {
+                                    /* Codes_SRS_SCHEMA_SERIALIZER_01_015: [If any of the Schema or String APIs fail then SchemaSerializer_SerializeCommandMetadata shall return SCHEMA_SERIALIZER_ERROR.] */
+                                    LogError("Failed to concatenate arg end.");
+                                    break;
+                                }
+                            }
+                            else
+                            {
+                                if (STRING_concat(schemaText, "\"}") != 0)
+                                {
+                                    /* Codes_SRS_SCHEMA_SERIALIZER_01_015: [If any of the Schema or String APIs fail then SchemaSerializer_SerializeCommandMetadata shall return SCHEMA_SERIALIZER_ERROR.] */
+                                    LogError("Failed to concatenate arg end.");
+                                    break;
+                                }
+                            }
+                        }
+                    }
+
+                    if (j < argCount)
+                    {
+                        break;
+                    }
+
+                    if (i + 1 < commandCount)
+                    {
+                        if (STRING_concat(schemaText, "]},") != 0)
+                        {
+                            /* Codes_SRS_SCHEMA_SERIALIZER_01_015: [If any of the Schema or String APIs fail then SchemaSerializer_SerializeCommandMetadata shall return SCHEMA_SERIALIZER_ERROR.] */
+                            LogError("Failed to concatenate.");
+                            break;
+                        }
+                    }
+                    else
+                    {
+                        if (STRING_concat(schemaText, "]}") != 0)
+                        {
+                            /* Codes_SRS_SCHEMA_SERIALIZER_01_015: [If any of the Schema or String APIs fail then SchemaSerializer_SerializeCommandMetadata shall return SCHEMA_SERIALIZER_ERROR.] */
+                            LogError("Failed to concatenate.");
+                            break;
+                        }
+                    }
+                }
+            }
+
+            if (i < commandCount)
+            {
+                result = SCHEMA_SERIALIZER_ERROR;
+            }
+            else if (STRING_concat(schemaText, "]") != 0)
+            {
+                /* Codes_SRS_SCHEMA_SERIALIZER_01_015: [If any of the Schema or String APIs fail then SchemaSerializer_SerializeCommandMetadata shall return SCHEMA_SERIALIZER_ERROR.] */
+                LogError("Failed to concatenate commands object end.");
+                result = SCHEMA_SERIALIZER_ERROR;
+            }
+            else
+            {
+                /* Codes_SRS_SCHEMA_SERIALIZER_01_012: [On success SchemaSerializer_SerializeCommandMetadata shall return SCHEMA_SERIALIZER_OK.] */
+                result = SCHEMA_SERIALIZER_OK;
+            }
+        }
+    }
+
+    return result;
+}
Index: azure_iot_hub_f767zi/trunk/azure_iot_sdk/serializer/src/serializer.def
===================================================================
--- azure_iot_hub_f767zi/trunk/azure_iot_sdk/serializer/src/serializer.def	(revision 457)
+++ azure_iot_hub_f767zi/trunk/azure_iot_sdk/serializer/src/serializer.def	(revision 457)
@@ -0,0 +1,218 @@
+LIBRARY serializer
+EXPORTS
+    MethodReturn_Create
+    MethodReturn_Destroy
+    MethodReturn_GetReturn
+    SCHEMA_SERIALIZER_RESULTStringStorage
+    SCHEMA_SERIALIZER_RESULTStrings
+    SCHEMA_SERIALIZER_RESULT_FromString
+    SchemaSerializer_SerializeCommandMetadata
+    SERIALIZER_RESULTStringStorage
+    SERIALIZER_RESULTStrings
+    SERIALIZER_RESULT_FromString
+    serializer_init
+    serializer_deinit
+    serializer_setconfig
+    SCHEMA_RESULTStringStorage
+    SCHEMA_RESULTStrings
+    SCHEMA_RESULT_FromString
+    Schema_Create
+    Schema_GetMetadata
+    Schema_GetSchemaCount
+    Schema_GetSchemaByNamespace
+    Schema_GetSchemaForModel
+    Schema_GetSchemaNamespace
+    Schema_AddDeviceRef
+    Schema_ReleaseDeviceRef
+    Schema_CreateModelType
+    Schema_GetSchemaForModelType
+    Schema_GetModelName
+    Schema_CreateStructType
+    Schema_GetStructTypeName
+    Schema_AddStructTypeProperty
+    Schema_AddModelProperty
+    Schema_AddModelReportedProperty
+    Schema_AddModelDesiredProperty
+    Schema_AddModelModel
+    Schema_CreateModelAction
+    Schema_CreateModelMethod
+    Schema_AddModelActionArgument
+    Schema_AddModelMethodArgument
+    Schema_GetModelDesiredProperty_pfDesiredPropertyFromAGENT_DATA_TYPE
+    Schema_GetModelDesiredProperty_pfOnDesiredProperty
+    Schema_GetModelModelByName_Offset
+    Schema_GetModelModelByName_OnDesiredProperty
+    Schema_GetModelModelByIndex_Offset
+    Schema_GetModelDesiredProperty_offset
+    Schema_GetModelDesiredPropertyType
+    Schema_GetModelDesiredProperty_pfDesiredPropertyDeinitialize
+    Schema_GetModelDesiredProperty_pfDesiredPropertyInitialize
+    Schema_GetModelElementByName
+    Schema_GetModelCount
+    Schema_GetModelByName
+    Schema_GetModelByIndex
+    Schema_GetModelPropertyCount
+    Schema_GetModelPropertyByName
+    Schema_GetModelPropertyByIndex
+    Schema_GetModelReportedPropertyCount
+    Schema_GetModelReportedPropertyByName
+    Schema_GetModelReportedPropertyByIndex
+    Schema_GetModelDesiredPropertyCount
+    Schema_GetModelDesiredPropertyByName
+    Schema_GetModelDesiredPropertyByIndex
+    Schema_GetModelModelCount
+    Schema_GetModelModelByName
+    Schema_GetModelModelyByIndex
+    Schema_GetModelModelPropertyNameByIndex
+    Schema_ModelPropertyByPathExists
+    Schema_ModelReportedPropertyByPathExists
+    Schema_ModelDesiredPropertyByPathExists
+    Schema_GetModelActionCount
+    Schema_GetModelActionByName
+    Schema_GetModelMethodByName
+    Schema_GetModelActionByIndex
+    Schema_GetModelActionArgumentCount
+    Schema_GetModelMethodArgumentCount
+    Schema_GetModelActionName
+    Schema_GetModelActionArgumentByName
+    Schema_GetModelActionArgumentByIndex
+    Schema_GetModelMethodArgumentByIndex
+    Schema_GetActionArgumentName
+    Schema_GetMethodArgumentName
+    Schema_GetActionArgumentType
+    Schema_GetMethodArgumentType
+    Schema_GetStructTypeCount
+    Schema_GetStructTypeByName
+    Schema_GetStructTypeByIndex
+    Schema_GetStructTypePropertyCount
+    Schema_GetStructTypePropertyByName
+    Schema_GetStructTypePropertyByIndex
+    Schema_GetPropertyName
+    Schema_GetPropertyType
+    Schema_Destroy
+    Schema_DestroyIfUnused
+    MULTITREE_RESULTStringStorage
+    MULTITREE_RESULTStrings
+    MULTITREE_RESULT_FromString
+    MultiTree_Create
+    MultiTree_AddLeaf
+    MultiTree_AddChild
+    MultiTree_GetChildCount
+    MultiTree_GetChild
+    MultiTree_GetChildByName
+    MultiTree_GetName
+    MultiTree_GetValue
+    MultiTree_GetLeafValue
+    MultiTree_SetValue
+    MultiTree_Destroy
+    JSON_ENCODER_TOSTRING_RESULTStringStorage
+    JSON_ENCODER_RESULTStringStorage
+    JSON_ENCODER_RESULTStrings
+    JSON_ENCODER_RESULT_FromString
+    JSON_ENCODER_TOSTRING_RESULTStrings
+    JSON_ENCODER_TOSTRING_RESULT_FromString
+    JSONEncoder_CharPtr_ToString
+    JSONEncoder_EncodeTree
+    JSONDecoder_JSON_To_MultiTree
+    SkipWhiteSpaces
+    DEVICE_RESULTStringStorage
+    DEVICE_RESULTStrings
+    DEVICE_RESULT_FromString
+    Device_Create
+    Device_Destroy
+    Device_StartTransaction
+    Device_PublishTransacted
+    Device_EndTransaction
+    Device_CancelTransaction
+    Device_CreateTransaction_ReportedProperties
+    Device_PublishTransacted_ReportedProperty
+    Device_CommitTransaction_ReportedProperties
+    Device_DestroyTransaction_ReportedProperties
+    Device_ExecuteCommand
+    Device_ExecuteMethod
+    Device_IngestDesiredProperties
+    DATA_SERIALIZER_RESULTStringStorage
+    DATA_SERIALIZER_RESULTStrings
+    DATA_SERIALIZER_RESULT_FromString
+    DataSerializer_Encode
+    DataSerializer_Decode
+    DATA_PUBLISHER_RESULTStringStorage
+    DATA_PUBLISHER_RESULTStrings
+    DATA_PUBLISHER_RESULT_FromString
+    DataPublisher_Create
+    DataPublisher_Destroy
+    DataPublisher_StartTransaction
+    DataPublisher_PublishTransacted
+    DataPublisher_EndTransaction
+    DataPublisher_CancelTransaction
+    DataPublisher_SetMaxBufferSize
+    DataPublisher_GetMaxBufferSize
+    DataPublisher_CreateTransaction_ReportedProperties
+    DataPublisher_PublishTransacted_ReportedProperty
+    DataPublisher_CommitTransaction_ReportedProperties
+    DataPublisher_DestroyTransaction_ReportedProperties
+    DATA_MARSHALLER_RESULTStringStorage
+    DATA_MARSHALLER_RESULTStrings
+    DATA_MARSHALLER_RESULT_FromString
+    DataMarshaller_Create
+    DataMarshaller_Destroy
+    DataMarshaller_SendData
+    DataMarshaller_SendData_ReportedProperties
+    COMMANDDECODER_RESULTStringStorage
+    AGENT_DATA_TYPE_TYPEStringStorage
+    AGENT_DATA_TYPE_TYPEStrings
+    AGENT_DATA_TYPE_TYPE_FromString
+    COMMANDDECODER_RESULTStrings
+    COMMANDDECODER_RESULT_FromString
+    CommandDecoder_Create
+    CommandDecoder_ExecuteCommand
+    CommandDecoder_ExecuteMethod
+    CommandDecoder_Destroy
+    CommandDecoder_IngestDesiredProperties
+    CODEFIRST_RESULTStringStorage
+    EXECUTE_COMMAND_RESULTStringStorage
+    EXECUTE_COMMAND_RESULTStrings
+    EXECUTE_COMMAND_RESULT_FromString
+    CODEFIRST_RESULTStrings
+    CODEFIRST_RESULT_FromString
+    CodeFirst_Init
+    CodeFirst_Deinit
+    CodeFirst_RegisterSchema
+    CodeFirst_InvokeAction
+    CodeFirst_InvokeMethod
+    CodeFirst_ExecuteCommand
+    CodeFirst_ExecuteMethod
+    CodeFirst_CreateDevice
+    CodeFirst_DestroyDevice
+    CodeFirst_SendAsync
+    CodeFirst_SendAsyncReported
+    CodeFirst_IngestDesiredProperties
+    CodeFirst_GetPrimitiveType
+    hexToASCII
+    AGENT_DATA_TYPES_RESULTStringStorage
+    AGENT_DATA_TYPES_RESULTStrings
+    AGENT_DATA_TYPES_RESULT_FromString
+    AgentDataTypes_ToString
+    Create_EDM_BOOLEAN_from_int
+    Create_AGENT_DATA_TYPE_from_UINT8
+    Create_AGENT_DATA_TYPE_from_date
+    Create_EDM_DECIMAL_from_charz
+    Create_AGENT_DATA_TYPE_from_DOUBLE
+    Create_AGENT_DATA_TYPE_from_SINT16
+    Create_AGENT_DATA_TYPE_from_SINT32
+    Create_AGENT_DATA_TYPE_from_SINT64
+    Create_AGENT_DATA_TYPE_from_SINT8
+    Create_AGENT_DATA_TYPE_from_EDM_DATE_TIME_OFFSET
+    Create_AGENT_DATA_TYPE_from_EDM_GUID
+    Create_AGENT_DATA_TYPE_from_EDM_BINARY
+    Create_AGENT_DATA_TYPE_from_FLOAT
+    Create_AGENT_DATA_TYPE_from_charz
+    Create_AGENT_DATA_TYPE_from_charz_no_quotes
+    Create_NULL_AGENT_DATA_TYPE
+    Create_AGENT_DATA_TYPE_from_Members
+    Create_AGENT_DATA_TYPE_from_MemberPointers
+    Create_AGENT_DATA_TYPE_from_AGENT_DATA_TYPE
+    Destroy_AGENT_DATA_TYPE
+    CreateAgentDataType_From_String
+    AgentDataType_GetComplexTypeField
+
Index: azure_iot_hub_f767zi/trunk/azure_iot_sdk/uhttp/inc/azure_uhttp_c/uhttp.h
===================================================================
--- azure_iot_hub_f767zi/trunk/azure_iot_sdk/uhttp/inc/azure_uhttp_c/uhttp.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/azure_iot_sdk/uhttp/inc/azure_uhttp_c/uhttp.h	(revision 457)
@@ -0,0 +1,85 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+#ifndef UHTTP_H
+#define UHTTP_H
+
+#ifdef __cplusplus
+extern "C" {
+#include <cstddef>
+#else
+#include <stddef.h>
+#include <stdbool.h>
+#endif /* __cplusplus */
+
+#include "azure_c_shared_utility/httpheaders.h"
+#include "azure_macro_utils/macro_utils.h"
+#include "azure_c_shared_utility/xio.h"
+#include "umock_c/umock_c_prod.h"
+
+typedef struct HTTP_CLIENT_HANDLE_DATA_TAG* HTTP_CLIENT_HANDLE;
+
+#define HTTP_CLIENT_RESULT_VALUES       \
+    HTTP_CLIENT_OK,                     \
+    HTTP_CLIENT_INVALID_ARG,            \
+    HTTP_CLIENT_ERROR,                  \
+    HTTP_CLIENT_OPEN_FAILED,            \
+    HTTP_CLIENT_SEND_FAILED,            \
+    HTTP_CLIENT_ALREADY_INIT,           \
+    HTTP_CLIENT_HTTP_HEADERS_FAILED,    \
+    HTTP_CLIENT_INVALID_STATE           \
+
+
+/** @brief Enumeration specifying the possible return values for the APIs in
+*           this module.
+*/
+MU_DEFINE_ENUM(HTTP_CLIENT_RESULT, HTTP_CLIENT_RESULT_VALUES);
+
+#define HTTP_CLIENT_REQUEST_TYPE_VALUES \
+    HTTP_CLIENT_REQUEST_OPTIONS,        \
+    HTTP_CLIENT_REQUEST_GET,            \
+    HTTP_CLIENT_REQUEST_POST,           \
+    HTTP_CLIENT_REQUEST_PUT,            \
+    HTTP_CLIENT_REQUEST_DELETE,         \
+    HTTP_CLIENT_REQUEST_PATCH
+
+MU_DEFINE_ENUM(HTTP_CLIENT_REQUEST_TYPE, HTTP_CLIENT_REQUEST_TYPE_VALUES);
+
+#define HTTP_CALLBACK_REASON_VALUES     \
+    HTTP_CALLBACK_REASON_OK,            \
+    HTTP_CALLBACK_REASON_OPEN_FAILED,   \
+    HTTP_CALLBACK_REASON_SEND_FAILED,   \
+    HTTP_CALLBACK_REASON_ERROR,         \
+    HTTP_CALLBACK_REASON_PARSING_ERROR, \
+    HTTP_CALLBACK_REASON_DESTROY,       \
+    HTTP_CALLBACK_REASON_DISCONNECTED
+
+MU_DEFINE_ENUM(HTTP_CALLBACK_REASON, HTTP_CALLBACK_REASON_VALUES);
+
+typedef void(*ON_HTTP_OPEN_COMPLETE_CALLBACK)(void* callback_ctx, HTTP_CALLBACK_REASON open_result);
+typedef void(*ON_HTTP_ERROR_CALLBACK)(void* callback_ctx, HTTP_CALLBACK_REASON error_result);
+typedef void(*ON_HTTP_REQUEST_CALLBACK)(void* callback_ctx, HTTP_CALLBACK_REASON request_result, const unsigned char* content, size_t content_length, unsigned int status_code,
+    HTTP_HEADERS_HANDLE response_headers);
+typedef void(*ON_HTTP_CLOSED_CALLBACK)(void* callback_ctx);
+
+MOCKABLE_FUNCTION(, HTTP_CLIENT_HANDLE, uhttp_client_create, const IO_INTERFACE_DESCRIPTION*, io_interface_desc, const void*, xio_param, ON_HTTP_ERROR_CALLBACK, on_http_error, void*, callback_ctx);
+MOCKABLE_FUNCTION(, void, uhttp_client_destroy, HTTP_CLIENT_HANDLE, handle);
+MOCKABLE_FUNCTION(, HTTP_CLIENT_RESULT, uhttp_client_open, HTTP_CLIENT_HANDLE, handle, const char*, host, int, port_num, ON_HTTP_OPEN_COMPLETE_CALLBACK, on_connect, void*, callback_ctx);
+MOCKABLE_FUNCTION(, void, uhttp_client_close, HTTP_CLIENT_HANDLE, handle, ON_HTTP_CLOSED_CALLBACK, on_close_callback, void*, callback_ctx);
+MOCKABLE_FUNCTION(, HTTP_CLIENT_RESULT, uhttp_client_execute_request, HTTP_CLIENT_HANDLE, handle, HTTP_CLIENT_REQUEST_TYPE, request_type, const char*, relative_path,
+    HTTP_HEADERS_HANDLE, http_header_handle, const unsigned char*, content, size_t, content_length, ON_HTTP_REQUEST_CALLBACK, on_request_callback, void*, callback_ctx);
+
+MOCKABLE_FUNCTION(, void, uhttp_client_dowork, HTTP_CLIENT_HANDLE, handle);
+
+MOCKABLE_FUNCTION(, HTTP_CLIENT_RESULT, uhttp_client_set_trace, HTTP_CLIENT_HANDLE, handle, bool, trace_on, bool, trace_data);
+MOCKABLE_FUNCTION(, HTTP_CLIENT_RESULT, uhttp_client_set_X509_cert, HTTP_CLIENT_HANDLE, handle, bool, ecc_type, const char*, certificate, const char*, private_key);
+MOCKABLE_FUNCTION(, HTTP_CLIENT_RESULT, uhttp_client_set_trusted_cert, HTTP_CLIENT_HANDLE, handle, const char*, certificate);
+MOCKABLE_FUNCTION(, const char*, uhttp_client_get_trusted_cert, HTTP_CLIENT_HANDLE, handle);
+MOCKABLE_FUNCTION(, HTTP_CLIENT_RESULT, uhttp_client_set_option, HTTP_CLIENT_HANDLE, handle, const char*, optionName, const void*, value);
+MOCKABLE_FUNCTION(, XIO_HANDLE, uhttp_client_get_underlying_xio, HTTP_CLIENT_HANDLE, handle);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* UHTTP_H */
Index: azure_iot_hub_f767zi/trunk/azure_iot_sdk/uhttp/src/uhttp.c
===================================================================
--- azure_iot_hub_f767zi/trunk/azure_iot_sdk/uhttp/src/uhttp.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/azure_iot_sdk/uhttp/src/uhttp.c	(revision 457)
@@ -0,0 +1,1525 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+#include <stdlib.h>
+#include <stddef.h>
+#include <stdbool.h>
+#include <ctype.h>
+
+#include "umock_c/umock_c_prod.h"
+#include "azure_c_shared_utility/gballoc.h"
+
+#include <string.h>
+#include "azure_uhttp_c/uhttp.h"
+#include "azure_c_shared_utility/httpheaders.h"
+#include "azure_c_shared_utility/crt_abstractions.h"
+#include "azure_c_shared_utility/strings.h"
+#include "azure_c_shared_utility/xlogging.h"
+#include "azure_c_shared_utility/buffer_.h"
+#include "azure_c_shared_utility/singlylinkedlist.h"
+#include "azure_c_shared_utility/shared_util_options.h"
+#include "azure_c_shared_utility/optimize_size.h"
+
+#define MAX_HOSTNAME        64
+#define TIME_MAX_BUFFER     16
+#define HTTP_CRLF_LEN       2
+#define HTTP_END_TOKEN_LEN  4
+#define MAX_CONTENT_LENGTH  16
+
+static const char* HTTP_REQUEST_LINE_FMT = "%s %s HTTP/1.1\r\n";
+static const char* HTTP_HOST = "Host";
+// The following header names MUST be lowercase as they are used for HTTP response header comparison:
+static const char* HTTP_CONTENT_LEN = "content-length";
+static const char* HTTP_TRANSFER_ENCODING = "transfer-encoding";
+static const char* HTTP_CRLF_VALUE = "\r\n";
+
+typedef enum RESPONSE_MESSAGE_STATE_TAG
+{
+    state_initial,
+    state_opening,
+    state_open,
+    state_process_status_line,
+    state_process_headers,
+    state_process_body,
+    state_process_chunked_body,
+
+    state_send_user_callback,
+    state_parse_complete,
+
+    state_closing,
+    state_closed,
+    state_error
+} RESPONSE_MESSAGE_STATE;
+
+typedef struct HTTP_RECV_DATA_TAG
+{
+    ON_HTTP_REQUEST_CALLBACK on_request_callback;
+    void* user_ctx;
+    int status_code;
+    RESPONSE_MESSAGE_STATE recv_state;
+    HTTP_HEADERS_HANDLE resp_header;
+    BUFFER_HANDLE msg_body;
+    size_t total_body_len;
+    BUFFER_HANDLE accrual_buff;
+    bool chunked_reply;
+} HTTP_RECV_DATA;
+
+typedef struct HTTP_CLIENT_HANDLE_DATA_TAG
+{
+    XIO_HANDLE xio_handle;
+    ON_HTTP_OPEN_COMPLETE_CALLBACK on_connect;
+    void* connect_user_ctx;
+    ON_HTTP_ERROR_CALLBACK on_error;
+    void* error_user_ctx;
+    ON_HTTP_CLOSED_CALLBACK on_close_callback;
+    void* close_user_ctx;
+    HTTP_RECV_DATA recv_msg;
+    bool chunk_request;
+    bool trace_on;
+    bool trace_body;
+    char* host_name;
+    int port_num;
+    SINGLYLINKEDLIST_HANDLE data_list;
+    bool cert_type_ecc;
+    char* x509_cert;
+    char* x509_pk;
+    char* certificate;
+    int connected;
+} HTTP_CLIENT_HANDLE_DATA;
+
+typedef struct HTTP_SEND_DATA_TAG
+{
+    HTTP_CLIENT_REQUEST_TYPE request_type;
+    STRING_HANDLE relative_path;
+    STRING_HANDLE header_line;
+    BUFFER_HANDLE content;
+} HTTP_SEND_DATA;
+
+static void send_complete_callback(void* context, IO_SEND_RESULT send_result)
+{
+    (void)context;(void)send_result;
+}
+
+static int initialize_received_data(HTTP_CLIENT_HANDLE_DATA* http_data)
+{
+    int result = 0;
+
+    // Initialize data if necessary
+    if (http_data->recv_msg.resp_header == NULL)
+    {
+        http_data->recv_msg.resp_header = HTTPHeaders_Alloc();
+        if (http_data->recv_msg.resp_header == NULL)
+        {
+            /* Codes_SRS_UHTTP_07_048: [ If any error is encountered on_bytes_received shall set the state to error. ] */
+            LogError("Failure creating Http header.");
+            result = MU_FAILURE;
+        }
+    }
+    if (result == 0 && http_data->recv_msg.accrual_buff == NULL)
+    {
+        http_data->recv_msg.accrual_buff = BUFFER_new();
+        if (http_data->recv_msg.accrual_buff == NULL)
+        {
+            /* Codes_SRS_UHTTP_07_048: [ If any error is encountered on_bytes_received shall set the state to error. ] */
+            LogError("Failure creating accrual buffer.");
+            result = MU_FAILURE;
+        }
+    }
+    http_data->recv_msg.chunked_reply = false;
+    return result;
+}
+
+static int process_status_code_line(const unsigned char* buffer, size_t len, size_t* position, int* statusLen)
+{
+    int result = MU_FAILURE;
+    size_t index;
+    int spaceFound = 0;
+    const char* initSpace = NULL;
+    char status_code[4];
+
+    for (index = 0; index < len; index++)
+    {
+        if (buffer[index] == ' ')
+        {
+            if (spaceFound == 1)
+            {
+                (void)memcpy(status_code, initSpace, 3);
+                status_code[3] = '\0';
+            }
+            else
+            {
+                initSpace = (const char*)buffer + index + 1;
+            }
+            spaceFound++;
+        }
+        else if (buffer[index] == '\n')
+        {
+            *statusLen = (int)atol(status_code);
+            if (index < len)
+            {
+                *position = index + 1;
+            }
+            else
+            {
+                *position = index;
+            }
+            result = 0;
+            break;
+        }
+    }
+    return result;
+}
+
+static int process_header_line(const unsigned char* buffer, size_t len, size_t* position, HTTP_HEADERS_HANDLE resp_header, size_t* contentLen, bool* isChunked)
+{
+    int result = MU_FAILURE;
+    size_t index;
+    const unsigned char* targetPos = buffer;
+    bool crlfEncounted = false;
+    bool colonEncountered = false;
+    char* headerKey = NULL;
+    bool continueProcessing = true;
+
+    for (index = 0; index < len && continueProcessing; index++)
+    {
+        if (buffer[index] == ':' && !colonEncountered)
+        {
+            colonEncountered = true;
+            size_t keyLen = (&buffer[index])-targetPos;
+
+            if (headerKey != NULL)
+            {
+                free(headerKey);
+                headerKey = NULL;
+            }
+            headerKey = (char*)malloc(keyLen+1);
+            if (headerKey == NULL)
+            {
+                result = MU_FAILURE;
+                continueProcessing = false;
+            }
+            else
+            {
+                memcpy(headerKey, targetPos, keyLen);
+                headerKey[keyLen] = '\0';
+
+                // Convert to lower case
+                for (size_t inner = 0; inner < keyLen; inner++)
+                {
+                    headerKey[inner] = (char)tolower(headerKey[inner]);
+                }
+
+                targetPos = buffer+index+1;
+                crlfEncounted = false;
+            }
+        }
+        else if (buffer[index] == '\r')
+        {
+            if (headerKey != NULL)
+            {
+                // Remove leading spaces
+                while (*targetPos == 32) { targetPos++; }
+
+                size_t valueLen = (&buffer[index])-targetPos;
+                char* headerValue = (char*)malloc(valueLen+1);
+                if (headerValue == NULL)
+                {
+                    result = MU_FAILURE;
+                    continueProcessing = false;
+                }
+                else
+                {
+                    memcpy(headerValue, targetPos, valueLen);
+                    headerValue[valueLen] = '\0';
+
+                    if (HTTPHeaders_AddHeaderNameValuePair(resp_header, headerKey, headerValue) != HTTP_HEADERS_OK)
+                    {
+                        result = MU_FAILURE;
+                        continueProcessing = false;
+                    }
+                    else
+                    {
+                        if (strcmp(headerKey, HTTP_CONTENT_LEN) == 0)
+                        {
+                            *isChunked = false;
+                            *contentLen = atol(headerValue);
+                        }
+                        else if (strcmp(headerKey, HTTP_TRANSFER_ENCODING) == 0)
+                        {
+                            *isChunked = true;
+                            *contentLen = 0;
+                        }
+                        if (index < len)
+                        {
+                            *position = index;
+                        }
+                        else
+                        {
+                            *position = index-1;
+                        }
+                    }
+                }
+                free(headerKey);
+                headerKey = NULL;
+                free(headerValue);
+            }
+        }
+        else if (buffer[index] == '\n')
+        {
+            if (crlfEncounted)
+            {
+                if (index < len)
+                {
+                    *position = index+1;
+                }
+                else
+                {
+                    *position = index;
+                }
+                result = 0;
+                break;
+            }
+            else
+            {
+                colonEncountered = false;
+                crlfEncounted = true;
+                targetPos = buffer+index+1;
+            }
+        }
+        else
+        {
+            crlfEncounted = false;
+        }
+    }
+    if (headerKey != NULL)
+    {
+        free(headerKey);
+    }
+    return result;
+}
+
+static int write_text_line(HTTP_CLIENT_HANDLE_DATA* http_data, const char* text_line)
+{
+    int result;
+    if (xio_send(http_data->xio_handle, text_line, strlen(text_line), send_complete_callback, NULL) != 0)
+    {
+        LogError("Failure calling xio_send.");
+        result = MU_FAILURE;
+    }
+    else
+    {
+        result = 0;
+        if (http_data->trace_on)
+        {
+            LOG(AZ_LOG_TRACE, LOG_LINE, "%s", text_line);
+        }
+    }
+    return result;
+}
+
+static int write_data_line(HTTP_CLIENT_HANDLE_DATA* http_data, const unsigned char* data_line, size_t length)
+{
+    int result;
+    if (xio_send(http_data->xio_handle, data_line, length, send_complete_callback, NULL) != 0)
+    {
+        LogError("Failure calling xio_send.");
+        result = MU_FAILURE;
+    }
+    else
+    {
+        result = 0;
+        if (http_data->trace_on)
+        {
+            if (length > 0)
+            {
+                if (http_data->trace_body)
+                {
+                    LOG(AZ_LOG_TRACE, LOG_LINE, "len: %d\r\n%.*s\r\n", (int)length, (int)length, data_line);
+                }
+                else
+                {
+                    LOG(AZ_LOG_TRACE, LOG_LINE, "<data> len: %d\r\n", (int)length);
+                }
+            }
+            else
+            {
+                LOG(AZ_LOG_TRACE, LOG_LINE, "len: %d\r\n", (int)length);
+            }
+        }
+    }
+    return result;
+}
+
+static int convert_char_to_hex(const unsigned char* hexText, size_t len)
+{
+    int result = 0;
+    for (size_t index = 0; index < len; index++)
+    {
+        if (hexText[index] == ';')
+        {
+            break;
+        }
+        else
+        {
+            int accumulator = 0;
+            if (hexText[index] >= 48 && hexText[index] <= 57)
+            {
+                accumulator = hexText[index] - 48;
+            }
+            else if (hexText[index] >= 65 && hexText[index] <= 70)
+            {
+                accumulator = hexText[index] - 55;
+            }
+            else if (hexText[index] >= 97 && hexText[index] <= 102)
+            {
+                accumulator = hexText[index] - 87;
+            }
+            if (index > 0)
+            {
+                result = result << 4;
+            }
+            result += accumulator;
+        }
+    }
+    return result;
+}
+
+static int setup_init_recv_msg(HTTP_RECV_DATA* recv_msg)
+{
+    int result;
+    recv_msg->status_code = 0;
+    recv_msg->recv_state = state_initial;
+    recv_msg->total_body_len = 0;
+    if (recv_msg->resp_header != NULL)
+    {
+        HTTPHeaders_Free(recv_msg->resp_header);
+    }
+    if (recv_msg->msg_body != NULL)
+    {
+        BUFFER_delete(recv_msg->msg_body);
+    }
+    if ((recv_msg->resp_header = HTTPHeaders_Alloc()) == NULL)
+    {
+        /* Codes_SRS_UHTTP_07_017: [If any failure encountered http_client_execute_request shall return HTTP_CLIENT_ERROR] */
+        LogError("Failure allocating http http_data items");
+        result = HTTP_CLIENT_ERROR;
+    }
+    else if ((recv_msg->msg_body = BUFFER_new()) == NULL)
+    {
+        /* Codes_SRS_UHTTP_07_017: [If any failure encountered http_client_execute_request shall return HTTP_CLIENT_ERROR] */
+        LogError("Failure allocating http data items");
+        HTTPHeaders_Free(recv_msg->resp_header);
+        recv_msg->resp_header = NULL;
+        result = HTTP_CLIENT_ERROR;
+    }
+    else
+    {
+        result = 0;
+    }
+    return result;
+}
+
+static void on_bytes_received(void* context, const unsigned char* buffer, size_t len)
+{
+    HTTP_CLIENT_HANDLE_DATA* http_data = (HTTP_CLIENT_HANDLE_DATA*)context;
+
+    if (http_data != NULL && buffer != NULL && len > 0 && http_data->recv_msg.recv_state != state_error)
+    {
+        if (http_data->recv_msg.recv_state == state_parse_complete)
+        {
+            // The callback is getting called during a new send.
+            setup_init_recv_msg(&http_data->recv_msg);
+
+        }
+
+        if (http_data->recv_msg.recv_state == state_initial || http_data->recv_msg.recv_state == state_open)
+        {
+            if (initialize_received_data(http_data) != 0)
+            {
+                http_data->recv_msg.recv_state = state_error;
+            }
+            else
+            {
+                http_data->recv_msg.recv_state = state_process_status_line;
+            }
+        }
+
+        // Put the data in the buffer
+        if (BUFFER_append_build(http_data->recv_msg.accrual_buff, buffer, len) != 0)
+        {
+            /* Codes_SRS_UHTTP_07_048: [ If any error is encountered on_bytes_received shall set the state to error. ] */
+            LogError("Failure appending bytes to buffer.");
+            http_data->recv_msg.recv_state = state_error;
+        }
+
+        if (http_data->recv_msg.recv_state == state_process_status_line)
+        {
+            size_t index = 0;
+            const unsigned char* stored_bytes = BUFFER_u_char(http_data->recv_msg.accrual_buff);
+            size_t stored_len = BUFFER_length(http_data->recv_msg.accrual_buff);
+
+            int lineComplete = process_status_code_line(stored_bytes, stored_len, &index, &http_data->recv_msg.status_code);
+            if (lineComplete == 0 && http_data->recv_msg.status_code > 0)
+            {
+                if (BUFFER_shrink(http_data->recv_msg.accrual_buff, index, false) != 0)
+                {
+                    LogError("Failure appending bytes to buffer.");
+                    http_data->recv_msg.recv_state = state_error;
+                }
+                else
+                {
+                    http_data->recv_msg.recv_state = state_process_headers;
+                }
+            }
+        }
+
+        if (http_data->recv_msg.recv_state == state_process_headers)
+        {
+            size_t index = 0;
+            const unsigned char* stored_bytes = BUFFER_u_char(http_data->recv_msg.accrual_buff);
+            size_t stored_len = BUFFER_length(http_data->recv_msg.accrual_buff);
+
+            int headerComplete = process_header_line(stored_bytes, stored_len, &index, http_data->recv_msg.resp_header, &http_data->recv_msg.total_body_len, &http_data->recv_msg.chunked_reply);
+            if (headerComplete == 0)
+            {
+                if (http_data->recv_msg.total_body_len == 0)
+                {
+                    if (http_data->recv_msg.chunked_reply)
+                    {
+
+                        /* Codes_SRS_UHTTP_07_054: [ If the http header does not include a content length then it indicates a chunk response. ] */
+                        http_data->recv_msg.recv_state = state_process_chunked_body;
+                    }
+                    else
+                    {
+                        // Content len is 0 so we are finished with the body
+                        http_data->recv_msg.recv_state = state_send_user_callback;
+                    }
+                }
+                else
+                {
+                    http_data->recv_msg.recv_state = state_process_body;
+                }
+            }
+            if (index > 0)
+            {
+                if (BUFFER_shrink(http_data->recv_msg.accrual_buff, index, false) != 0)
+                {
+                    LogError("Failure appending bytes to buffer.");
+                    http_data->recv_msg.recv_state = state_error;
+                }
+            }
+        }
+
+        if (http_data->recv_msg.recv_state == state_process_body)
+        {
+            if (http_data->recv_msg.total_body_len != 0)
+            {
+                size_t stored_len = BUFFER_length(http_data->recv_msg.accrual_buff);
+
+                if ((http_data->recv_msg.total_body_len == stored_len) || (http_data->recv_msg.total_body_len == (stored_len - HTTP_END_TOKEN_LEN)))
+                {
+                    if (http_data->recv_msg.msg_body != NULL)
+                    {
+                        BUFFER_delete(http_data->recv_msg.msg_body);
+                    }
+                    if ((http_data->recv_msg.msg_body = BUFFER_clone(http_data->recv_msg.accrual_buff)) == NULL)
+                    {
+                        LogError("Failure cloning BUFFER.");
+                        http_data->recv_msg.recv_state = state_error;
+                    }
+                    else
+                    {
+                        http_data->recv_msg.recv_state = state_send_user_callback;
+                    }
+                }
+                else if (stored_len > http_data->recv_msg.total_body_len)
+                {
+                    LogError("Failure bytes encountered is greater then body length.");
+                    http_data->recv_msg.recv_state = state_error;
+                }
+            }
+        }
+
+        if (http_data->recv_msg.recv_state == state_process_chunked_body)
+        {
+            const unsigned char* iterator = BUFFER_u_char(http_data->recv_msg.accrual_buff);
+            const unsigned char* initial_pos = iterator;
+            const unsigned char* begin = iterator;
+            const unsigned char* end = iterator;
+            size_t accural_len = BUFFER_length(http_data->recv_msg.accrual_buff);
+
+            /* Codes_SRS_UHTTP_07_059: [ on_bytes_received shall loop throught the stored data to find the /r/n separator. ] */
+            while (iterator < (initial_pos + accural_len))
+            {
+                if (*iterator == '\r')
+                {
+                    // Don't need anything
+                    end = iterator;
+                    iterator++;
+                }
+                else if (*iterator == '\n')
+                {
+                    size_t data_length = 0;
+
+                    /* Codes_SRS_UHTTP_07_055: [ on_bytes_received shall convert the hexs length supplied in the response to the data length of the chunked data. ] */
+                    size_t hex_len = end - begin;
+                    data_length = convert_char_to_hex(begin, hex_len);
+                    if (data_length == 0)
+                    {
+                        if (accural_len - (iterator - initial_pos + 1) <= HTTP_END_TOKEN_LEN)
+                        {
+                            http_data->recv_msg.recv_state = state_send_user_callback;
+                        }
+                        else
+                        {
+                            // Need to continue parsing
+                            http_data->recv_msg.recv_state = state_process_headers;
+                        }
+                        break;
+                    }
+                    else if ((data_length + HTTP_CRLF_LEN) < accural_len - (iterator - initial_pos))
+                    {
+                        /* Codes_SRS_UHTTP_07_056: [ After the response chunk is parsed it shall be placed in a BUFFER_HANDLE. ] */
+                        iterator += 1;
+                        if (BUFFER_append_build(http_data->recv_msg.msg_body, iterator, data_length) != 0)
+                        {
+                            /* Codes_SRS_UHTTP_07_048: [ If any error is encountered on_bytes_received shall set the stop processing the request. ] */
+                            LogError("Failure building buffer for chunked data.");
+                            http_data->recv_msg.recv_state = state_error;
+                        }
+                        else
+                        {
+                            /* Codes_SRS_UHTTP_07_060: [ if the data_length specified in the chunk is beyond the amount of data recieved, the parsing shall end and wait for more data. ] */
+                            if (iterator + (data_length + HTTP_CRLF_LEN) > initial_pos + accural_len)
+                            {
+                                LogError("Invalid length specified.");
+                                http_data->recv_msg.recv_state = state_error;
+                                break;
+                            }
+                            else if (iterator + (data_length + HTTP_CRLF_LEN) == initial_pos + accural_len)
+                            {
+                                if (BUFFER_shrink(http_data->recv_msg.accrual_buff, accural_len, false) != 0)
+                                {
+                                    LogError("Failure shrinking accural buffer.");
+                                    http_data->recv_msg.recv_state = state_error;
+                                }
+                                break;
+                            }
+                            else
+                            {
+                                // Move the iterator beyond the data we read and the /r/n
+                                iterator += (data_length + HTTP_CRLF_LEN);
+                            }
+
+                            /* Codes_SRS_UHTTP_07_058: [ Once a chunk size value of 0 is encountered on_bytes_received shall call the on_request_callback with the http message ] */
+                            if (*iterator == '0' && (accural_len - (iterator - initial_pos + 1) <= HTTP_END_TOKEN_LEN))
+                            {
+                                if (accural_len - (iterator - initial_pos + 1) <= HTTP_END_TOKEN_LEN)
+                                {
+                                    http_data->recv_msg.recv_state = state_send_user_callback;
+                                }
+                                else
+                                {
+                                    // Need to continue parsing
+                                    http_data->recv_msg.recv_state = state_process_headers;
+                                }
+                                break;
+                            }
+                            else
+                            {
+                                size_t shrink_len = iterator - initial_pos;
+                                if (shrink_len > 0)
+                                {
+                                    if (BUFFER_shrink(http_data->recv_msg.accrual_buff, shrink_len, false) != 0)
+                                    {
+                                        LogError("Failure shrinking accrual buffer.");
+                                        http_data->recv_msg.recv_state = state_error;
+                                    }
+                                    else
+                                    {
+                                        accural_len = BUFFER_length(http_data->recv_msg.accrual_buff);
+                                        initial_pos = iterator = BUFFER_u_char(http_data->recv_msg.accrual_buff);
+                                    }
+                                }
+                            }
+                        }
+                        begin = end = iterator;
+                    }
+                    else
+                    {
+                        break;
+                    }
+                }
+                else
+                {
+                    end = iterator;
+                    iterator++;
+                }
+            }
+        }
+
+        if (http_data->recv_msg.recv_state == state_send_user_callback || http_data->recv_msg.recv_state == state_error)
+        {
+            const unsigned char* reply_data = NULL;
+            size_t reply_len = 0;
+            HTTP_CALLBACK_REASON http_reason = HTTP_CALLBACK_REASON_OK;
+            if (http_data->recv_msg.msg_body != NULL)
+            {
+                reply_data = BUFFER_u_char(http_data->recv_msg.msg_body);
+                reply_len = BUFFER_length(http_data->recv_msg.msg_body);
+            }
+            if (http_data->recv_msg.recv_state == state_error)
+            {
+                http_reason = HTTP_CALLBACK_REASON_PARSING_ERROR;
+            }
+            if (http_data->trace_on)
+            {
+                LOG(AZ_LOG_TRACE, LOG_LINE, "\r\nHTTP Status: %d\r\n", http_data->recv_msg.status_code);
+
+                // Loop through headers
+                size_t count;
+                if (HTTPHeaders_GetHeaderCount(http_data->recv_msg.resp_header, &count) == 0)
+                {
+                    for (size_t index = 0; index < count; index++)
+                    {
+                        char* header;
+                        if (HTTPHeaders_GetHeader(http_data->recv_msg.resp_header, index, &header) == HTTP_HEADERS_OK)
+                        {
+                            LOG(AZ_LOG_TRACE, LOG_LINE, "%s", header);
+                            free(header);
+                        }
+                    }
+                }
+                if (http_data->trace_body && reply_len > 0)
+                {
+                    LOG(AZ_LOG_TRACE, LOG_LINE, "\r\n%.*s\r\n", (int)reply_len, reply_data);
+                }
+            }
+            http_data->recv_msg.on_request_callback(http_data->recv_msg.user_ctx, http_reason, reply_data, reply_len, http_data->recv_msg.status_code, http_data->recv_msg.resp_header);
+            http_data->recv_msg.recv_state = state_parse_complete;
+        }
+
+        if (http_data->recv_msg.recv_state == state_parse_complete)
+        {
+            HTTPHeaders_Free(http_data->recv_msg.resp_header);
+            http_data->recv_msg.resp_header = NULL;
+            BUFFER_delete(http_data->recv_msg.msg_body);
+            http_data->recv_msg.msg_body = NULL;
+            BUFFER_delete(http_data->recv_msg.accrual_buff);
+            http_data->recv_msg.accrual_buff = NULL;
+        }
+    }
+}
+
+static void on_xio_close_complete(void* context)
+{
+    if (context != NULL)
+    {
+        /* Codes_SRS_UHTTP_07_045: [ If on_close_callback is not NULL, on_close_callback shall be called once the underlying xio is closed. ] */
+        HTTP_CLIENT_HANDLE_DATA* http_data = (HTTP_CLIENT_HANDLE_DATA*)context;
+        if (http_data->on_close_callback)
+        {
+            http_data->on_close_callback(http_data->close_user_ctx);
+        }
+        http_data->recv_msg.recv_state = state_closed;
+        http_data->connected = 0;
+    }
+}
+
+static void on_xio_open_complete(void* context, IO_OPEN_RESULT open_result)
+{
+    /* Codes_SRS_UHTTP_07_049: [ If not NULL uhttp_client_open shall call the on_connect callback with the callback_ctx, once the underlying xio's open is complete. ] */
+    if (context != NULL)
+    {
+        HTTP_CLIENT_HANDLE_DATA* http_data = (HTTP_CLIENT_HANDLE_DATA*)context;
+        if (open_result == IO_OPEN_OK)
+        {
+            /* Codes_SRS_UHTTP_07_042: [ If the underlying socket opens successfully the on_connect callback shall be call with HTTP_CALLBACK_REASON_OK... ] */
+            if (http_data->on_connect != NULL)
+            {
+                http_data->on_connect(http_data->connect_user_ctx, HTTP_CALLBACK_REASON_OK);
+            }
+            http_data->recv_msg.recv_state = state_open;
+            http_data->connected = 1;
+        }
+        else
+        {
+            /* Codes_SRS_UHTTP_07_043: [ Otherwise on_connect callback shall be call with HTTP_CLIENT_OPEN_REQUEST_FAILED. ] */
+            if (http_data->on_connect != NULL)
+            {
+                http_data->on_connect(http_data->connect_user_ctx, HTTP_CALLBACK_REASON_OPEN_FAILED);
+            }
+        }
+    }
+    else
+    {
+        LogError("Context on_xio_open_complete is NULL");
+    }
+}
+
+static void on_io_error(void* context)
+{
+    /* Codes_SRS_UHTTP_07_050: [ if context is NULL on_io_error shall do nothing. ] */
+    if (context != NULL)
+    {
+        HTTP_CLIENT_HANDLE_DATA* http_data = (HTTP_CLIENT_HANDLE_DATA*)context;
+        /* Codes_SRS_UHTTP_07_051: [ if on_error callback is not NULL, on_io_error shall call on_error callback. ] */
+        if (http_data->on_error)
+        {
+            http_data->on_error(http_data->error_user_ctx, HTTP_CALLBACK_REASON_ERROR);
+        }
+        http_data->connected = 0;
+    }
+    else
+    {
+        LogError("Context on_io_error is NULL");
+    }
+}
+
+static int construct_http_headers(HTTP_HEADERS_HANDLE http_header, size_t content_len, STRING_HANDLE buffData, bool chunk_data, const char* hostname, int port_num)
+{
+    (void)chunk_data;
+    int result = 0;
+    size_t headerCnt = 0;
+    if ( (http_header != NULL) && HTTPHeaders_GetHeaderCount(http_header, &headerCnt) != HTTP_HEADERS_OK)
+    {
+        LogError("Failed in HTTPHeaders_GetHeaderCount");
+        result = MU_FAILURE;
+    }
+    else
+    {
+        bool hostname_found = false;
+        for (size_t index = 0; index < headerCnt && result == 0; index++)
+        {
+            char* header;
+            if (HTTPHeaders_GetHeader(http_header, index, &header) != HTTP_HEADERS_OK)
+            {
+                result = MU_FAILURE;
+                LogError("Failed in HTTPHeaders_GetHeader");
+            }
+            else
+            {
+                size_t dataLen = strlen(header)+2;
+                char* sendData = malloc(dataLen+1);
+                if (sendData == NULL)
+                {
+                    result = MU_FAILURE;
+                    LogError("Failed in allocating header data");
+                }
+                else
+                {
+                    if (strcmp(header, HTTP_HOST) == 0)
+                    {
+                        hostname_found = true;
+                    }
+
+                    if (snprintf(sendData, dataLen+1, "%s\r\n", header) <= 0)
+                    {
+                        result = MU_FAILURE;
+                        LogError("Failed in constructing header data");
+                    }
+                    else
+                    {
+                        if (STRING_concat(buffData, sendData) != 0)
+                        {
+                            result = MU_FAILURE;
+                            LogError("Failed in building header data");
+                        }
+                    }
+                    free(sendData);
+                }
+                free(header);
+            }
+        }
+        if (!hostname_found)
+        {
+            // calculate the size of the host header
+            size_t host_len = strlen(HTTP_HOST) + strlen(hostname) + MAX_CONTENT_LENGTH + 2;
+            char* host_header = malloc(host_len + 1);
+            if (host_header == NULL)
+            {
+                LogError("Failed allocating host header");
+                result = MU_FAILURE;
+            }
+            else
+            {
+                if (snprintf(host_header, host_len + 1, "%s: %s:%d\r\n", HTTP_HOST, hostname, port_num) <= 0)
+                {
+                    LogError("Failed constructing host header");
+                    result = MU_FAILURE;
+                }
+                else if (STRING_concat(buffData, host_header) != 0)
+                {
+                    LogError("Failed adding the host header to the http item");
+                    result = MU_FAILURE;
+                }
+                free(host_header);
+            }
+        }
+
+        if (result == 0)
+        {
+            /* Codes_SRS_UHTTP_07_015: [uhttp_client_execute_request shall add the Content-Length to the request if the contentLength is > 0] */
+            size_t fmtLen = strlen(HTTP_CONTENT_LEN) + HTTP_CRLF_LEN + 8;
+            char* content = malloc(fmtLen+1);
+            if (content == NULL)
+            {
+                LogError("Failed allocating chunk header");
+                result = MU_FAILURE;
+            }
+            else
+            {
+                /* Codes_SRS_UHTTP_07_015: [on_bytes_received shall add the Content-Length http header item to the request.] */
+                if (sprintf(content, "%s: %u%s", HTTP_CONTENT_LEN, (unsigned int)content_len, HTTP_CRLF_VALUE) <= 0)
+                {
+                    result = MU_FAILURE;
+                    LogError("Failed allocating content len header data");
+                }
+                else
+                {
+                    if (STRING_concat(buffData, content) != 0)
+                    {
+                        result = MU_FAILURE;
+                        LogError("Failed building content len header data");
+                    }
+                }
+                free(content);
+            }
+
+            if (STRING_concat(buffData, "\r\n") != 0)
+            {
+                result = MU_FAILURE;
+                LogError("Failed sending header finalization data");
+            }
+        }
+    }
+    return result;
+}
+
+static STRING_HANDLE construct_http_data(HTTP_CLIENT_REQUEST_TYPE request_type, const char* relative_path, STRING_HANDLE http_line)
+{
+    STRING_HANDLE result;
+
+    const char* method = (request_type == HTTP_CLIENT_REQUEST_GET) ? "GET"
+        : (request_type == HTTP_CLIENT_REQUEST_OPTIONS) ? "OPTIONS"
+        : (request_type == HTTP_CLIENT_REQUEST_POST) ? "POST"
+        : (request_type == HTTP_CLIENT_REQUEST_PUT) ? "PUT"
+        : (request_type == HTTP_CLIENT_REQUEST_DELETE) ? "DELETE"
+        : (request_type == HTTP_CLIENT_REQUEST_PATCH) ? "PATCH"
+        : NULL;
+    /* Codes_SRS_UHTTP_07_014: [If the request_type is not a valid request http_client_execute_request shall return HTTP_CLIENT_ERROR] */
+    if (method == NULL)
+    {
+        LogError("Invalid request method %s specified", method);
+        result = NULL;
+    }
+    else
+    {
+        size_t buffLen = strlen(HTTP_REQUEST_LINE_FMT) + strlen(method) + strlen(relative_path);
+        char* request = malloc(buffLen+1);
+        if (request == NULL)
+        {
+            result = NULL;
+            LogError("Failure allocating Request data");
+        }
+        else
+        {
+            if (snprintf(request, buffLen + 1, HTTP_REQUEST_LINE_FMT, method, relative_path) <= 0)
+            {
+                result = NULL;
+                LogError("Failure writing request buffer");
+            }
+            else
+            {
+                result = STRING_construct(request);
+                if (result == NULL)
+                {
+                    LogError("Failure creating buffer object");
+                }
+                else if (STRING_concat_with_STRING(result, http_line) != 0)
+                {
+                    STRING_delete(result);
+                    result = NULL;
+                    LogError("Failure writing request buffers");
+                }
+            }
+            free(request);
+        }
+    }
+    return result;
+}
+
+static int send_http_data(HTTP_CLIENT_HANDLE_DATA* http_data, HTTP_CLIENT_REQUEST_TYPE request_type, const char* relative_path,
+    STRING_HANDLE http_line)
+{
+    int result;
+    STRING_HANDLE transmit_data = construct_http_data(request_type, relative_path, http_line);
+    if (transmit_data == NULL)
+    {
+        LogError("Failure constructing http data");
+        result = MU_FAILURE;
+    }
+    else
+    {
+        /* Tests_SRS_UHTTP_07_016: [http_client_execute_request shall transmit the http headers data through a call to xio_send;]*/
+        if (write_text_line(http_data, STRING_c_str(transmit_data) ) != 0)
+        {
+            result = MU_FAILURE;
+            LogError("Failure writing request buffer");
+        }
+        else
+        {
+            result = 0;
+        }
+        STRING_delete(transmit_data);
+    }
+    return result;
+}
+
+HTTP_CLIENT_HANDLE uhttp_client_create(const IO_INTERFACE_DESCRIPTION* io_interface_desc, const void* xio_param, ON_HTTP_ERROR_CALLBACK on_http_error, void* callback_ctx)
+{
+    HTTP_CLIENT_HANDLE_DATA* result;
+    /* Codes_SRS_UHTTP_07_002: [If io_interface_desc is NULL, uhttp_client_create shall return NULL.] */
+    if (io_interface_desc == NULL)
+    {
+        LogError("Invalid Parameter io_interface_desc is NULL");
+        result = NULL;
+    }
+    else
+    {
+        result = malloc(sizeof(HTTP_CLIENT_HANDLE_DATA));
+        if (result == NULL)
+        {
+            /* Codes_SRS_UHTTP_07_003: [If uhttp_client_create encounters any error then it shall return NULL] */
+            LogError("Failure allocating http_client_handle");
+        }
+        else
+        {
+            memset(result, 0, sizeof(HTTP_CLIENT_HANDLE_DATA) );
+            if ((result->data_list = singlylinkedlist_create() ) == NULL)
+            {
+                /* Codes_SRS_UHTTP_07_003: [If uhttp_client_create encounters any error then it shall return NULL] */
+                LogError("Failure allocating data list");
+                free(result);
+                result = NULL;
+            }
+            else if ((result->xio_handle = xio_create(io_interface_desc, xio_param) ) == NULL)
+            {
+                /* Codes_SRS_UHTTP_07_044: [ if a failure is encountered on xio_open uhttp_client_open shall return HTTP_CLIENT_OPEN_REQUEST_FAILED. ] */
+                LogError("xio create failed");
+                singlylinkedlist_destroy(result->data_list);
+                free(result);
+                result = NULL;
+            }
+            else
+            {
+                /* Codes_SRS_UHTTP_07_001: [uhttp_client_create shall return an initialize the http client handle.] */
+                result->on_error = on_http_error;
+                result->error_user_ctx = callback_ctx;
+                result->recv_msg.recv_state = state_initial;
+                result->chunk_request = false;
+                result->trace_on = false;
+            }
+        }
+    }
+    return (HTTP_CLIENT_HANDLE)result;
+}
+
+void uhttp_client_destroy(HTTP_CLIENT_HANDLE handle)
+{
+    /* Codes_SRS_UHTTP_07_004: [ If handle is NULL then uhttp_client_destroy shall do nothing ] */
+    if (handle != NULL)
+    {
+        /* Codes_SRS_UHTTP_07_005: [uhttp_client_destroy shall free any resource that is allocated in this translation unit] */
+        if(handle->host_name != NULL)
+        {
+            free(handle->host_name);
+            handle->host_name = NULL;
+        }
+        singlylinkedlist_destroy(handle->data_list);
+        xio_destroy(handle->xio_handle);
+        free(handle->certificate);
+        free(handle->x509_pk);
+        free(handle->x509_cert);
+        free(handle);
+    }
+}
+
+HTTP_CLIENT_RESULT uhttp_client_open(HTTP_CLIENT_HANDLE handle, const char* host, int port_num, ON_HTTP_OPEN_COMPLETE_CALLBACK on_connect, void* callback_ctx)
+{
+    HTTP_CLIENT_RESULT result;
+    if (handle == NULL || host == NULL)
+    {
+        /* Codes_SRS_UHTTP_07_006: [If handle, io_interface_desc or host is NULL then `uhttp_client_open` shall return HTTP_CLIENT_INVALID_ARG] */
+        LogError("Invalid handle value");
+        result = HTTP_CLIENT_INVALID_ARG;
+    }
+    else
+    {
+        HTTP_CLIENT_HANDLE_DATA* http_data = (HTTP_CLIENT_HANDLE_DATA*)handle;
+
+        if ((http_data->recv_msg.recv_state != state_initial) &&
+            (http_data->recv_msg.recv_state != state_error) &&
+            (http_data->recv_msg.recv_state != state_closed))
+        {
+            LogError("Unable to open previously open client.");
+            result = HTTP_CLIENT_INVALID_STATE;
+        }
+        else
+        {
+            if (http_data->host_name != NULL)
+            {
+                free(http_data->host_name);
+                handle->host_name = NULL;
+            }
+
+            if (mallocAndStrcpy_s(&http_data->host_name, host) != 0)
+            {
+                LogError("copying hostname has failed");
+                result = HTTP_CLIENT_ERROR;
+            }
+            /* Codes_SRS_UHTTP_07_007: [http_client_connect shall attempt to open the xio_handle. ] */
+            else
+            {
+                result = HTTP_CLIENT_OK;
+                http_data->recv_msg.recv_state = state_opening;
+                http_data->on_connect = on_connect;
+                http_data->connect_user_ctx = callback_ctx;
+                http_data->port_num = port_num;
+
+                if ((http_data->x509_cert != NULL) && (http_data->x509_pk != NULL))
+                {
+                    if ((xio_setoption(http_data->xio_handle, SU_OPTION_X509_CERT, http_data->x509_cert) != 0) ||
+                        (xio_setoption(http_data->xio_handle, SU_OPTION_X509_PRIVATE_KEY, http_data->x509_pk) != 0))
+                    {
+                        LogError("Failed setting x509 certificate");
+                        result = HTTP_CLIENT_ERROR;
+                        free(http_data->host_name);
+                        http_data->host_name = NULL;
+                        http_data->on_connect = NULL;
+                        http_data->connect_user_ctx = NULL;
+                        http_data->port_num = 0;
+                    }
+                }
+
+                if ((result == HTTP_CLIENT_OK) && (http_data->certificate != NULL))
+                {
+                    if (xio_setoption(http_data->xio_handle, OPTION_TRUSTED_CERT, http_data->certificate) != 0)
+                    {
+                        LogError("Failed setting Trusted certificate");
+                        result = HTTP_CLIENT_ERROR;
+                        free(http_data->host_name);
+                        http_data->host_name = NULL;
+                        http_data->on_connect = NULL;
+                        http_data->connect_user_ctx = NULL;
+                        http_data->port_num = 0;
+                    }
+                }
+
+                if (result == HTTP_CLIENT_OK)
+                {
+                    if (xio_open(http_data->xio_handle, on_xio_open_complete, http_data, on_bytes_received, http_data, on_io_error, http_data) != 0)
+                    {
+                        /* Codes_SRS_UHTTP_07_044: [ if a failure is encountered on xio_open uhttp_client_open shall return HTTP_CLIENT_OPEN_REQUEST_FAILED. ] */
+                        LogError("opening xio failed");
+                        free(http_data->host_name);
+                        http_data->host_name = NULL;
+                        http_data->on_connect = NULL;
+                        http_data->connect_user_ctx = NULL;
+                        http_data->port_num = 0;
+                        http_data->recv_msg.recv_state = state_error;
+
+                        result = HTTP_CLIENT_OPEN_FAILED;
+                    }
+                    else
+                    {
+                        /* Codes_SRS_UHTTP_07_008: [If http_client_connect succeeds then it shall return HTTP_CLIENT_OK] */
+                        result = HTTP_CLIENT_OK;
+                    }
+                }
+            }
+        }
+    }
+    return result;
+}
+
+void uhttp_client_close(HTTP_CLIENT_HANDLE handle, ON_HTTP_CLOSED_CALLBACK on_close_callback, void* callback_ctx)
+{
+    HTTP_CLIENT_HANDLE_DATA* http_data = (HTTP_CLIENT_HANDLE_DATA*)handle;
+    /* Codes_SRS_UHTTP_07_009: [If handle is NULL then http_client_close shall do nothing] */
+    /* Codes_SRS_UHTTP_07_049: [ If the state has been previously set to state_closed, uhttp_client_close shall do nothing. ] */
+    if (http_data != NULL && http_data->recv_msg.recv_state != state_closed && http_data->recv_msg.recv_state != state_closing)
+    {
+        http_data->on_close_callback = on_close_callback;
+        http_data->close_user_ctx = callback_ctx;
+        /* Codes_SRS_UHTTP_07_010: [If the xio_handle is NOT NULL http_client_close shall call xio_close to close the handle] */
+        (void)xio_close(http_data->xio_handle, on_xio_close_complete, http_data);
+
+        LIST_ITEM_HANDLE pending_list_item;
+        while ((pending_list_item = singlylinkedlist_get_head_item(http_data->data_list)) != NULL)
+        {
+            HTTP_SEND_DATA* send_data = (HTTP_SEND_DATA*)singlylinkedlist_item_get_value(pending_list_item);
+            if (send_data != NULL)
+            {
+                STRING_delete(send_data->relative_path);
+                BUFFER_delete(send_data->content);
+                STRING_delete(send_data->header_line);
+                free(send_data);
+            }
+            singlylinkedlist_remove(http_data->data_list, pending_list_item);
+        }
+
+        http_data->recv_msg.status_code = 0;
+        http_data->recv_msg.recv_state = state_closed;
+        http_data->recv_msg.total_body_len = 0;
+        free(http_data->host_name);
+        http_data->host_name = NULL;
+
+        /* Codes_SRS_UHTTP_07_011: [http_client_close shall free any HTTPHeader object that has not been freed] */
+        if (http_data->recv_msg.resp_header != NULL)
+        {
+            HTTPHeaders_Free(http_data->recv_msg.resp_header);
+            http_data->recv_msg.resp_header = NULL;
+        }
+        if (http_data->recv_msg.msg_body != NULL)
+        {
+            BUFFER_delete(http_data->recv_msg.msg_body);
+            http_data->recv_msg.msg_body = NULL;
+        }
+    }
+}
+
+HTTP_CLIENT_RESULT uhttp_client_execute_request(HTTP_CLIENT_HANDLE handle, HTTP_CLIENT_REQUEST_TYPE request_type, const char* relative_path,
+    HTTP_HEADERS_HANDLE http_header_handle, const unsigned char* content, size_t content_len, ON_HTTP_REQUEST_CALLBACK on_request_callback, void* callback_ctx)
+{
+    HTTP_CLIENT_RESULT result;
+    LIST_ITEM_HANDLE list_item;
+
+    /* Codes_SRS_UHTTP_07_012: [If handle, relativePath, or httpHeadersHandle is NULL then http_client_execute_request shall return HTTP_CLIENT_INVALID_ARG] */
+    if (handle == NULL || on_request_callback == NULL ||
+        (content != NULL && content_len == 0) || (content == NULL && content_len != 0) )
+    {
+        result = HTTP_CLIENT_INVALID_ARG;
+        LogError("Invalid parameter sent to execute_request");
+    }
+    else
+    {
+        HTTP_CLIENT_HANDLE_DATA* http_data = (HTTP_CLIENT_HANDLE_DATA*)handle;
+
+        http_data->recv_msg.on_request_callback = on_request_callback;
+        http_data->recv_msg.user_ctx = callback_ctx;
+        if (setup_init_recv_msg(&http_data->recv_msg) != 0)
+        {
+            /* Codes_SRS_UHTTP_07_017: [If any failure encountered http_client_execute_request shall return HTTP_CLIENT_ERROR] */
+            LogError("Failure allocating http http_data items");
+            result = HTTP_CLIENT_ERROR;
+        }
+        else
+        {
+            HTTP_SEND_DATA* send_data = (HTTP_SEND_DATA*)malloc(sizeof(HTTP_SEND_DATA));
+            if (send_data == NULL)
+            {
+                LogError("Failure allocating http data items");
+                BUFFER_delete(http_data->recv_msg.msg_body);
+                http_data->recv_msg.msg_body = NULL;
+                HTTPHeaders_Free(http_data->recv_msg.resp_header);
+                http_data->recv_msg.resp_header = NULL;
+                result = HTTP_CLIENT_ERROR;
+            }
+            else
+            {
+                memset(send_data, 0, sizeof(HTTP_SEND_DATA));
+                /* Codes_SRS_UHTTP_07_041: [HTTP_CLIENT_REQUEST_TYPE shall support all request types specified under section 9.1.2 in the spec.] */
+                send_data->request_type = request_type;
+                if ( (content_len > 0) && (send_data->content = BUFFER_create(content, content_len)) == NULL)
+                {
+                    LogError("Failure allocating content buffer");
+                    result = HTTP_CLIENT_ERROR;
+                    BUFFER_delete(http_data->recv_msg.msg_body);
+                    http_data->recv_msg.msg_body = NULL;
+                    HTTPHeaders_Free(http_data->recv_msg.resp_header);
+                    http_data->recv_msg.resp_header = NULL;
+                    free(send_data);
+                }
+                else if ((send_data->header_line = STRING_new()) == NULL)
+                {
+                    LogError("Failure allocating content buffer");
+                    result = HTTP_CLIENT_ERROR;
+                    BUFFER_delete(send_data->content);
+                    BUFFER_delete(http_data->recv_msg.msg_body);
+                    http_data->recv_msg.msg_body = NULL;
+                    HTTPHeaders_Free(http_data->recv_msg.resp_header);
+                    http_data->recv_msg.resp_header = NULL;
+                    free(send_data);
+                }
+                else if (construct_http_headers(http_header_handle, content_len, send_data->header_line, false, http_data->host_name, http_data->port_num))
+                {
+                    LogError("Failure allocating content buffer");
+                    result = HTTP_CLIENT_ERROR;
+                    BUFFER_delete(send_data->content);
+                    STRING_delete(send_data->header_line);
+                    BUFFER_delete(http_data->recv_msg.msg_body);
+                    http_data->recv_msg.msg_body = NULL;
+                    HTTPHeaders_Free(http_data->recv_msg.resp_header);
+                    http_data->recv_msg.resp_header = NULL;
+                    free(send_data);
+                }
+                else if ((list_item = singlylinkedlist_add(http_data->data_list, send_data)) == NULL)
+                {
+                    STRING_delete(send_data->header_line);
+                    BUFFER_delete(send_data->content);
+                    LogError("Failure adding send data to list");
+                    result = HTTP_CLIENT_ERROR;
+                    BUFFER_delete(http_data->recv_msg.msg_body);
+                    http_data->recv_msg.msg_body = NULL;
+                    HTTPHeaders_Free(http_data->recv_msg.resp_header);
+                    http_data->recv_msg.resp_header = NULL;
+                    free(send_data);
+                }
+                else
+                {
+                    if (relative_path != NULL)
+                    {
+                        if ((send_data->relative_path = STRING_construct(relative_path)) == NULL)
+                        {
+                            (void)singlylinkedlist_remove(http_data->data_list, list_item);
+                            STRING_delete(send_data->header_line);
+                            BUFFER_delete(send_data->content);
+                            LogError("Failure allocating relative path buffer");
+                            BUFFER_delete(http_data->recv_msg.msg_body);
+                            http_data->recv_msg.msg_body = NULL;
+                            HTTPHeaders_Free(http_data->recv_msg.resp_header);
+                            http_data->recv_msg.resp_header = NULL;
+                            free(send_data);
+                            result = HTTP_CLIENT_ERROR;
+                        }
+                        else
+                        {
+                            /* Codes_SRS_UHTTP_07_018: [upon success http_client_execute_request shall return HTTP_CLIENT_OK.] */
+                            result = HTTP_CLIENT_OK;
+                        }
+                    }
+                    else
+                    {
+                        if ((send_data->relative_path = STRING_construct("/")) == NULL)
+                        {
+                            (void)singlylinkedlist_remove(http_data->data_list, list_item);
+                            STRING_delete(send_data->header_line);
+                            BUFFER_delete(send_data->content);
+                            LogError("Failure allocating relative path buffer");
+                            BUFFER_delete(http_data->recv_msg.msg_body);
+                            http_data->recv_msg.msg_body = NULL;
+                            HTTPHeaders_Free(http_data->recv_msg.resp_header);
+                            http_data->recv_msg.resp_header = NULL;
+                            free(send_data);
+                            result = HTTP_CLIENT_ERROR;
+                        }
+                        else
+                        {
+                            /* Codes_SRS_UHTTP_07_018: [upon success http_client_execute_request shall return HTTP_CLIENT_OK.] */
+                            result = HTTP_CLIENT_OK;
+                        }
+                    }
+                }
+            }
+        }
+    }
+    return result;
+}
+
+void uhttp_client_dowork(HTTP_CLIENT_HANDLE handle)
+{
+    if (handle != NULL)
+    {
+        /* Codes_SRS_UHTTP_07_037: [http_client_dowork shall call the underlying xio_dowork function. ] */
+        HTTP_CLIENT_HANDLE_DATA* http_data = (HTTP_CLIENT_HANDLE_DATA*)handle;
+        xio_dowork(http_data->xio_handle);
+
+        // Wait till I'm connected
+        if (handle->connected == 1)
+        {
+            LIST_ITEM_HANDLE pending_list_item;
+            /* Codes_SRS_UHTTP_07_016: [http_client_dowork shall iterate through the queued Data using the xio interface to send the http request in the following ways...] */
+            while ((pending_list_item = singlylinkedlist_get_head_item(http_data->data_list)) != NULL)
+            {
+                HTTP_SEND_DATA* send_data = (HTTP_SEND_DATA*)singlylinkedlist_item_get_value(pending_list_item);
+                if (send_data != NULL)
+                {
+                    size_t content_len = BUFFER_length(send_data->content);
+                    /* Codes_SRS_UHTTP_07_052: [uhttp_client_dowork shall call xio_send to transmits the header information... ] */
+                    if (send_http_data(http_data, send_data->request_type, STRING_c_str(send_data->relative_path), send_data->header_line) != 0)
+                    {
+                        LogError("Failure writing content buffer");
+                        if (http_data->on_error)
+                        {
+                            http_data->on_error(http_data->error_user_ctx, HTTP_CALLBACK_REASON_SEND_FAILED);
+                        }
+                    }
+                    else if (content_len > 0)
+                    {
+                        /* Codes_SRS_UHTTP_07_053: [ Then uhttp_client_dowork shall use xio_send to transmit the content of the http request. ] */
+                        if (write_data_line(http_data, BUFFER_u_char(send_data->content), content_len) != 0)
+                        {
+                            LogError("Failure writing content buffer");
+                            if (http_data->on_error)
+                            {
+                                http_data->on_error(http_data->error_user_ctx, HTTP_CALLBACK_REASON_SEND_FAILED);
+                            }
+                        }
+                    }
+
+                    /* Codes_SRS_UHTTP_07_046: [ http_client_dowork shall free resouces queued to send to the http endpoint. ] */
+                    STRING_delete(send_data->relative_path);
+                    BUFFER_delete(send_data->content);
+                    STRING_delete(send_data->header_line);
+                    free(send_data);
+                }
+                (void)singlylinkedlist_remove(http_data->data_list, pending_list_item);
+            }
+        }
+    }
+}
+
+HTTP_CLIENT_RESULT uhttp_client_set_trace(HTTP_CLIENT_HANDLE handle, bool trace_on, bool trace_data)
+{
+    HTTP_CLIENT_RESULT result;
+    if (handle == NULL)
+    {
+        /* Codes_SRS_UHTTP_07_038: [If handle is NULL then http_client_set_trace shall return HTTP_CLIENT_INVALID_ARG] */
+        result = HTTP_CLIENT_INVALID_ARG;
+        LogError("invalid parameter (NULL) passed to http_client_set_trace");
+    }
+    else
+    {
+        /* Codes_SRS_UHTTP_07_039: [http_client_set_trace shall set the HTTP tracing to the trace_on variable.] */
+        handle->trace_on = trace_on;
+        handle->trace_body = trace_data;
+        /* Codes_SRS_UHTTP_07_040: [if http_client_set_trace finishes successfully then it shall return HTTP_CLIENT_OK.] */
+        result = HTTP_CLIENT_OK;
+    }
+    return result;
+}
+
+HTTP_CLIENT_RESULT uhttp_client_set_X509_cert(HTTP_CLIENT_HANDLE handle, bool ecc_type, const char* certificate, const char* private_key)
+{
+    HTTP_CLIENT_RESULT result;
+    if (handle == NULL || certificate == NULL || private_key == NULL)
+    {
+        /* Codes_SRS_UHTTP_07_038: [If handle is NULL then http_client_set_trace shall return HTTP_CLIENT_INVALID_ARG] */
+        result = HTTP_CLIENT_INVALID_ARG;
+        LogError("invalid parameter handle: %p certificate: %p private_key: %p", handle, certificate, private_key);
+    }
+    else if (handle->recv_msg.recv_state != state_initial)
+    {
+        result = HTTP_CLIENT_INVALID_STATE;
+        LogError("You must set the X509 certificates before opening the connection");
+    }
+    else
+    {
+        handle->cert_type_ecc = ecc_type;
+        if (mallocAndStrcpy_s(&handle->x509_cert, certificate) != 0)
+        {
+            result = HTTP_CLIENT_ERROR;
+            LogError("failure allocating certificate");
+        }
+        else if (mallocAndStrcpy_s(&handle->x509_pk, private_key) != 0)
+        {
+            free(handle->x509_cert);
+            handle->x509_cert = NULL;
+            result = HTTP_CLIENT_ERROR;
+            LogError("failure allocating private key");
+        }
+        else
+        {
+            result = HTTP_CLIENT_OK;
+        }
+    }
+    return result;
+}
+
+HTTP_CLIENT_RESULT uhttp_client_set_trusted_cert(HTTP_CLIENT_HANDLE handle, const char* certificate)
+{
+    HTTP_CLIENT_RESULT result;
+    if (handle == NULL || certificate == NULL)
+    {
+        /* Codes_SRS_UHTTP_07_038: [If handle is NULL then http_client_set_trace shall return HTTP_CLIENT_INVALID_ARG] */
+        result = HTTP_CLIENT_INVALID_ARG;
+        LogError("invalid parameter handle: %p certificate: %p", handle, certificate);
+    }
+    else if (handle->recv_msg.recv_state != state_initial)
+    {
+        result = HTTP_CLIENT_INVALID_STATE;
+        LogError("You must set the certificates before opening the connection");
+    }
+    else
+    {
+        if (mallocAndStrcpy_s(&handle->certificate, certificate) != 0)
+        {
+            result = HTTP_CLIENT_ERROR;
+            LogError("failure allocating certificate");
+        }
+        else
+        {
+            result = HTTP_CLIENT_OK;
+        }
+    }
+    return result;
+}
+
+const char* uhttp_client_get_trusted_cert(HTTP_CLIENT_HANDLE handle)
+{
+    const char* result;
+    if (handle == NULL)
+    {
+        result = NULL;
+        LogError("invalid parameter NULL handle");
+    }
+    else
+    {
+        result = handle->certificate;
+    }
+    return result;
+}
+
+HTTP_CLIENT_RESULT uhttp_client_set_option(HTTP_CLIENT_HANDLE handle, const char* optionName, const void* value)
+{
+    HTTP_CLIENT_RESULT result;
+    if (handle == NULL)
+    {
+        /* Codes_SRS_UHTTP_07_038: [If handle is NULL then http_client_set_trace shall return HTTP_CLIENT_INVALID_ARG] */
+        result = HTTP_CLIENT_INVALID_ARG;
+        LogError("invalid parameter handle: %p", handle);
+    }
+    else
+    {
+        int setoption_result = xio_setoption(handle->xio_handle, optionName, value);
+        if (setoption_result != 0)
+        {
+            LogError("xio_setoption fails, returns %d", setoption_result);
+            result = HTTP_CLIENT_ERROR;
+        }
+        else
+        {
+            result = HTTP_CLIENT_OK;
+        }
+
+    }
+
+    return result;
+}
+
+XIO_HANDLE uhttp_client_get_underlying_xio(HTTP_CLIENT_HANDLE handle)
+{
+    XIO_HANDLE result;
+    if (handle == NULL)
+    {
+        LogError("invalid parameter handle: %p", handle);
+        result = NULL;
+    }
+    else
+    {
+        result = handle->xio_handle;
+    }
+    return result;
+}
Index: azure_iot_hub_f767zi/trunk/azure_iot_sdk/umqtt/inc/azure_umqtt_c/mqtt_client.h
===================================================================
--- azure_iot_hub_f767zi/trunk/azure_iot_sdk/umqtt/inc/azure_umqtt_c/mqtt_client.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/azure_iot_sdk/umqtt/inc/azure_umqtt_c/mqtt_client.h	(revision 457)
@@ -0,0 +1,70 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+#ifndef MQTT_CLIENT_H
+#define MQTT_CLIENT_H
+
+#include "azure_c_shared_utility/xio.h"
+#include "azure_macro_utils/macro_utils.h"
+#include "azure_umqtt_c/mqttconst.h"
+#include "azure_umqtt_c/mqtt_message.h"
+#include "umock_c/umock_c_prod.h"
+
+#ifdef __cplusplus
+#include <cstdint>
+extern "C" {
+#else
+#include <stdint.h>
+#endif // __cplusplus
+
+
+typedef struct MQTT_CLIENT_TAG* MQTT_CLIENT_HANDLE;
+
+#define MQTT_CLIENT_EVENT_VALUES     \
+    MQTT_CLIENT_ON_CONNACK,          \
+    MQTT_CLIENT_ON_PUBLISH_ACK,      \
+    MQTT_CLIENT_ON_PUBLISH_RECV,     \
+    MQTT_CLIENT_ON_PUBLISH_REL,      \
+    MQTT_CLIENT_ON_PUBLISH_COMP,     \
+    MQTT_CLIENT_ON_SUBSCRIBE_ACK,    \
+    MQTT_CLIENT_ON_UNSUBSCRIBE_ACK,  \
+    MQTT_CLIENT_ON_PING_RESPONSE,    \
+    MQTT_CLIENT_ON_DISCONNECT
+
+MU_DEFINE_ENUM(MQTT_CLIENT_EVENT_RESULT, MQTT_CLIENT_EVENT_VALUES);
+
+#define MQTT_CLIENT_EVENT_ERROR_VALUES     \
+    MQTT_CLIENT_CONNECTION_ERROR,          \
+    MQTT_CLIENT_PARSE_ERROR,               \
+    MQTT_CLIENT_MEMORY_ERROR,              \
+    MQTT_CLIENT_COMMUNICATION_ERROR,       \
+    MQTT_CLIENT_NO_PING_RESPONSE,          \
+    MQTT_CLIENT_UNKNOWN_ERROR
+
+MU_DEFINE_ENUM(MQTT_CLIENT_EVENT_ERROR, MQTT_CLIENT_EVENT_ERROR_VALUES);
+
+typedef void(*ON_MQTT_OPERATION_CALLBACK)(MQTT_CLIENT_HANDLE handle, MQTT_CLIENT_EVENT_RESULT actionResult, const void* msgInfo, void* callbackCtx);
+typedef void(*ON_MQTT_ERROR_CALLBACK)(MQTT_CLIENT_HANDLE handle, MQTT_CLIENT_EVENT_ERROR error, void* callbackCtx);
+typedef void(*ON_MQTT_MESSAGE_RECV_CALLBACK)(MQTT_MESSAGE_HANDLE msgHandle, void* callbackCtx);
+typedef void(*ON_MQTT_DISCONNECTED_CALLBACK)(void* callbackCtx);
+
+MOCKABLE_FUNCTION(, MQTT_CLIENT_HANDLE, mqtt_client_init, ON_MQTT_MESSAGE_RECV_CALLBACK, msgRecv, ON_MQTT_OPERATION_CALLBACK, opCallback, void*, opCallbackCtx, ON_MQTT_ERROR_CALLBACK, onErrorCallBack, void*, errorCBCtx);
+MOCKABLE_FUNCTION(, void, mqtt_client_deinit, MQTT_CLIENT_HANDLE, handle);
+
+MOCKABLE_FUNCTION(, int, mqtt_client_connect, MQTT_CLIENT_HANDLE, handle, XIO_HANDLE, xioHandle, MQTT_CLIENT_OPTIONS*, mqttOptions);
+MOCKABLE_FUNCTION(, int, mqtt_client_disconnect, MQTT_CLIENT_HANDLE, handle, ON_MQTT_DISCONNECTED_CALLBACK, callback, void*, ctx);
+
+MOCKABLE_FUNCTION(, int, mqtt_client_subscribe, MQTT_CLIENT_HANDLE, handle, uint16_t, packetId, SUBSCRIBE_PAYLOAD*, subscribeList, size_t, count);
+MOCKABLE_FUNCTION(, int, mqtt_client_unsubscribe, MQTT_CLIENT_HANDLE, handle, uint16_t, packetId, const char**, unsubscribeList, size_t, count);
+
+MOCKABLE_FUNCTION(, int, mqtt_client_publish, MQTT_CLIENT_HANDLE, handle, MQTT_MESSAGE_HANDLE, msgHandle);
+
+MOCKABLE_FUNCTION(, void, mqtt_client_dowork, MQTT_CLIENT_HANDLE, handle);
+
+MOCKABLE_FUNCTION(, void, mqtt_client_set_trace, MQTT_CLIENT_HANDLE, handle, bool, traceOn, bool, rawBytesOn);
+
+#ifdef __cplusplus
+}
+#endif // __cplusplus
+
+#endif // MQTTCLIENT_H
Index: azure_iot_hub_f767zi/trunk/azure_iot_sdk/umqtt/inc/azure_umqtt_c/mqtt_codec.h
===================================================================
--- azure_iot_hub_f767zi/trunk/azure_iot_sdk/umqtt/inc/azure_umqtt_c/mqtt_codec.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/azure_iot_sdk/umqtt/inc/azure_umqtt_c/mqtt_codec.h	(revision 457)
@@ -0,0 +1,48 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+#ifndef MQTT_CODEC_H
+#define MQTT_CODEC_H
+
+#include "azure_c_shared_utility/xio.h"
+#include "azure_c_shared_utility/buffer_.h"
+#include "umock_c/umock_c_prod.h"
+#include "azure_umqtt_c/mqttconst.h"
+#include "azure_c_shared_utility/strings.h"
+
+#ifdef __cplusplus
+#include <cstdint>
+#include <cstddef>
+extern "C" {
+#else
+#include <stdint.h>
+#include <stdbool.h>
+#include <stddef.h>
+#endif // __cplusplus
+
+typedef struct MQTTCODEC_INSTANCE_TAG* MQTTCODEC_HANDLE;
+
+typedef void(*ON_PACKET_COMPLETE_CALLBACK)(void* context, CONTROL_PACKET_TYPE packet, int flags, BUFFER_HANDLE headerData);
+
+MOCKABLE_FUNCTION(, MQTTCODEC_HANDLE, mqtt_codec_create, ON_PACKET_COMPLETE_CALLBACK, packetComplete, void*, callbackCtx);
+MOCKABLE_FUNCTION(, void, mqtt_codec_destroy, MQTTCODEC_HANDLE, handle);
+
+MOCKABLE_FUNCTION(, void, mqtt_codec_reset, MQTTCODEC_HANDLE, handle);
+MOCKABLE_FUNCTION(, BUFFER_HANDLE, mqtt_codec_connect, const MQTT_CLIENT_OPTIONS*, mqttOptions, STRING_HANDLE, trace_log);
+MOCKABLE_FUNCTION(, BUFFER_HANDLE, mqtt_codec_disconnect);
+MOCKABLE_FUNCTION(, BUFFER_HANDLE, mqtt_codec_publish, QOS_VALUE, qosValue, bool, duplicateMsg, bool, serverRetain, uint16_t, packetId, const char*, topicName, const uint8_t*, msgBuffer, size_t, buffLen, STRING_HANDLE, trace_log);
+MOCKABLE_FUNCTION(, BUFFER_HANDLE, mqtt_codec_publishAck, uint16_t, packetId);
+MOCKABLE_FUNCTION(, BUFFER_HANDLE, mqtt_codec_publishReceived, uint16_t, packetId);
+MOCKABLE_FUNCTION(, BUFFER_HANDLE, mqtt_codec_publishRelease, uint16_t, packetId);
+MOCKABLE_FUNCTION(, BUFFER_HANDLE, mqtt_codec_publishComplete, uint16_t, packetId);
+MOCKABLE_FUNCTION(, BUFFER_HANDLE, mqtt_codec_ping);
+MOCKABLE_FUNCTION(, BUFFER_HANDLE, mqtt_codec_subscribe, uint16_t, packetId, SUBSCRIBE_PAYLOAD*, subscribeList, size_t, count, STRING_HANDLE, trace_log);
+MOCKABLE_FUNCTION(, BUFFER_HANDLE, mqtt_codec_unsubscribe, uint16_t, packetId, const char**, unsubscribeList, size_t, count, STRING_HANDLE, trace_log);
+
+MOCKABLE_FUNCTION(, int, mqtt_codec_bytesReceived, MQTTCODEC_HANDLE, handle, const unsigned char*, buffer, size_t, size);
+
+#ifdef __cplusplus
+}
+#endif // __cplusplus
+
+#endif // MQTT_CODEC_H
Index: azure_iot_hub_f767zi/trunk/azure_iot_sdk/umqtt/inc/azure_umqtt_c/mqtt_message.h
===================================================================
--- azure_iot_hub_f767zi/trunk/azure_iot_sdk/umqtt/inc/azure_umqtt_c/mqtt_message.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/azure_iot_sdk/umqtt/inc/azure_umqtt_c/mqtt_message.h	(revision 457)
@@ -0,0 +1,50 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+#ifndef MQTT_MESSAGE_H
+#define MQTT_MESSAGE_H
+
+#include "azure_umqtt_c/mqttconst.h"
+#include "umock_c/umock_c_prod.h"
+
+#ifdef __cplusplus
+#include <cstdint>
+#include <cstddef>
+extern "C" {
+#else
+#include <stdint.h>
+#include <stdbool.h>
+#include <stddef.h>
+#endif // __cplusplus
+
+typedef struct MQTT_MESSAGE_TAG* MQTT_MESSAGE_HANDLE;
+
+MOCKABLE_FUNCTION(, MQTT_MESSAGE_HANDLE, mqttmessage_create_in_place, uint16_t, packetId, const char*, topicName, QOS_VALUE, qosValue, const uint8_t*, appMsg, size_t, appMsgLength);
+MOCKABLE_FUNCTION(, MQTT_MESSAGE_HANDLE, mqttmessage_create, uint16_t, packetId, const char*, topicName, QOS_VALUE, qosValue, const uint8_t*, appMsg, size_t, appMsgLength);
+MOCKABLE_FUNCTION(,void, mqttmessage_destroy, MQTT_MESSAGE_HANDLE, handle);
+MOCKABLE_FUNCTION(,MQTT_MESSAGE_HANDLE, mqttmessage_clone, MQTT_MESSAGE_HANDLE, handle);
+
+MOCKABLE_FUNCTION(, uint16_t, mqttmessage_getPacketId, MQTT_MESSAGE_HANDLE, handle);
+MOCKABLE_FUNCTION(, const char*, mqttmessage_getTopicName, MQTT_MESSAGE_HANDLE, handle);
+
+/*
+*    @brief    Gets the individual names of the MQTT topic levels, in the original order.
+*    @param    handle    Handle to the MQTT message.
+*    @param    levels    Pointer the variable where to store the level names.
+*    @param    count     Number of levels in the topic name.
+*    @return   return    Zero if no failures occur, or non-zero otherwise.
+*/
+MOCKABLE_FUNCTION(, int, mqttmessage_getTopicLevels, MQTT_MESSAGE_HANDLE, handle, char***, levels, size_t*, count);
+
+MOCKABLE_FUNCTION(, QOS_VALUE, mqttmessage_getQosType, MQTT_MESSAGE_HANDLE, handle);
+MOCKABLE_FUNCTION(, bool, mqttmessage_getIsDuplicateMsg, MQTT_MESSAGE_HANDLE, handle);
+MOCKABLE_FUNCTION(, bool, mqttmessage_getIsRetained, MQTT_MESSAGE_HANDLE, handle);
+MOCKABLE_FUNCTION(, int, mqttmessage_setIsDuplicateMsg, MQTT_MESSAGE_HANDLE, handle, bool, duplicateMsg);
+MOCKABLE_FUNCTION(, int, mqttmessage_setIsRetained, MQTT_MESSAGE_HANDLE, handle, bool, retainMsg);
+MOCKABLE_FUNCTION(, const APP_PAYLOAD*, mqttmessage_getApplicationMsg, MQTT_MESSAGE_HANDLE, handle);
+
+#ifdef __cplusplus
+}
+#endif // __cplusplus
+
+#endif // MQTT_MESSAGE_H
Index: azure_iot_hub_f767zi/trunk/azure_iot_sdk/umqtt/inc/azure_umqtt_c/mqttconst.h
===================================================================
--- azure_iot_hub_f767zi/trunk/azure_iot_sdk/umqtt/inc/azure_umqtt_c/mqttconst.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/azure_iot_sdk/umqtt/inc/azure_umqtt_c/mqttconst.h	(revision 457)
@@ -0,0 +1,111 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+#ifndef MQTTCONST_H
+#define MQTTCONST_H
+
+#include "azure_c_shared_utility/crt_abstractions.h"
+#include "azure_macro_utils/macro_utils.h"
+
+#ifdef __cplusplus
+#include <cstddef>
+#include <cstdint>
+extern "C" {
+#else
+#include <stddef.h>
+#include <stdint.h>
+#endif /* __cplusplus */
+
+#define CONTROL_PACKET_TYPE_VALUES \
+    CONNECT_TYPE, 0x10, \
+    CONNACK_TYPE, 0x20, \
+    PUBLISH_TYPE, 0x30, \
+    PUBACK_TYPE, 0x40, \
+    PUBREC_TYPE, 0x50, \
+    PUBREL_TYPE, 0x60, \
+    PUBCOMP_TYPE, 0x70, \
+    SUBSCRIBE_TYPE, 0x80, \
+    SUBACK_TYPE, 0x90, \
+    UNSUBSCRIBE_TYPE, 0xA0, \
+    UNSUBACK_TYPE, 0xB0, \
+    PINGREQ_TYPE, 0xC0, \
+    PINGRESP_TYPE, 0xD0, \
+    DISCONNECT_TYPE, 0xE0, \
+    PACKET_TYPE_ERROR, 0xE1, /* 0xE1 was assigned because ENUM_2 needs it */ \
+    UNKNOWN_TYPE, 0xE2 /* 0xE2 was assigned because ENUM_2 needs it */
+
+MU_DEFINE_ENUM_2(CONTROL_PACKET_TYPE, CONTROL_PACKET_TYPE_VALUES)
+
+#define QOS_VALUE_VALUES \
+    DELIVER_AT_MOST_ONCE, 0x00, \
+    DELIVER_AT_LEAST_ONCE, 0x01, \
+    DELIVER_EXACTLY_ONCE, 0x02, \
+    DELIVER_FAILURE, 0x80
+
+MU_DEFINE_ENUM_2(QOS_VALUE, QOS_VALUE_VALUES)
+
+typedef struct APP_PAYLOAD_TAG
+{
+    uint8_t* message;
+    size_t length;
+} APP_PAYLOAD;
+
+typedef struct MQTT_CLIENT_OPTIONS_TAG
+{
+    char* clientId;
+    char* willTopic;
+    char* willMessage;
+    char* username;
+    char* password;
+    uint16_t keepAliveInterval;
+    bool messageRetain;
+    bool useCleanSession;
+    QOS_VALUE qualityOfServiceValue;
+    bool log_trace;
+} MQTT_CLIENT_OPTIONS;
+
+typedef enum CONNECT_RETURN_CODE_TAG
+{
+    CONNECTION_ACCEPTED = 0x00,
+    CONN_REFUSED_UNACCEPTABLE_VERSION = 0x01,
+    CONN_REFUSED_ID_REJECTED = 0x02,
+    CONN_REFUSED_SERVER_UNAVAIL = 0x03,
+    CONN_REFUSED_BAD_USERNAME_PASSWORD = 0x04,
+    CONN_REFUSED_NOT_AUTHORIZED = 0x05,
+    CONN_REFUSED_UNKNOWN
+} CONNECT_RETURN_CODE;
+
+typedef struct CONNECT_ACK_TAG
+{
+    bool isSessionPresent;
+    CONNECT_RETURN_CODE returnCode;
+} CONNECT_ACK;
+
+typedef struct SUBSCRIBE_PAYLOAD_TAG
+{
+    const char* subscribeTopic;
+    QOS_VALUE qosReturn;
+} SUBSCRIBE_PAYLOAD;
+
+typedef struct SUBSCRIBE_ACK_TAG
+{
+    uint16_t packetId;
+    QOS_VALUE* qosReturn;
+    size_t qosCount;
+} SUBSCRIBE_ACK;
+
+typedef struct UNSUBSCRIBE_ACK_TAG
+{
+    uint16_t packetId;
+} UNSUBSCRIBE_ACK;
+
+typedef struct PUBLISH_ACK_TAG
+{
+    uint16_t packetId;
+} PUBLISH_ACK;
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif // MQTTCONST_H
Index: azure_iot_hub_f767zi/trunk/azure_iot_sdk/umqtt/src/mqtt_client.c
===================================================================
--- azure_iot_hub_f767zi/trunk/azure_iot_sdk/umqtt/src/mqtt_client.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/azure_iot_sdk/umqtt/src/mqtt_client.c	(revision 457)
@@ -0,0 +1,1372 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+#include <stdlib.h>
+#include <stdbool.h>
+#include "azure_c_shared_utility/agenttime.h"
+#include "azure_c_shared_utility/const_defines.h"
+#include "azure_c_shared_utility/crt_abstractions.h"
+#include "azure_c_shared_utility/gballoc.h"
+#include "azure_c_shared_utility/optimize_size.h"
+#include "azure_macro_utils/macro_utils.h"
+#include "azure_c_shared_utility/platform.h"
+#include "azure_c_shared_utility/strings.h"
+#include "azure_c_shared_utility/threadapi.h"
+#include "azure_c_shared_utility/tickcounter.h"
+#include "azure_c_shared_utility/xlogging.h"
+
+#include "azure_umqtt_c/mqtt_client.h"
+#include "azure_umqtt_c/mqtt_codec.h"
+#include <inttypes.h>
+
+#define VARIABLE_HEADER_OFFSET          2
+#define RETAIN_FLAG_MASK                0x1
+#define QOS_LEAST_ONCE_FLAG_MASK        0x2
+#define QOS_EXACTLY_ONCE_FLAG_MASK      0x4
+#define DUPLICATE_FLAG_MASK             0x8
+#define CONNECT_PACKET_MASK             0xf0
+#define TIME_MAX_BUFFER                 16
+#define DEFAULT_MAX_PING_RESPONSE_TIME  80  // % of time to send pings
+#define MAX_CLOSE_RETRIES               20
+
+static const char* const TRUE_CONST = "true";
+static const char* const FALSE_CONST = "false";
+
+MU_DEFINE_ENUM_STRINGS(QOS_VALUE, QOS_VALUE_VALUES);
+
+#define MQTT_STATUS_INITIAL_STATUS      0x0000
+#define MQTT_STATUS_CLIENT_CONNECTED    0x0001
+#define MQTT_STATUS_SOCKET_CONNECTED    0x0002
+#define MQTT_STATUS_PENDING_CLOSE       0x0004
+
+#define MQTT_FLAGS_LOG_TRACE           0x0001
+#define MQTT_FLAGS_RAW_TRACE           0x0002
+
+typedef struct MQTT_CLIENT_TAG
+{
+    XIO_HANDLE xioHandle;
+    MQTTCODEC_HANDLE codec_handle;
+    CONTROL_PACKET_TYPE packetState;
+    TICK_COUNTER_HANDLE packetTickCntr;
+    tickcounter_ms_t packetSendTimeMs;
+    ON_MQTT_OPERATION_CALLBACK fnOperationCallback;
+    ON_MQTT_MESSAGE_RECV_CALLBACK fnMessageRecv;
+    void* ctx;
+    ON_MQTT_ERROR_CALLBACK fnOnErrorCallBack;
+    void* errorCBCtx;
+    ON_MQTT_DISCONNECTED_CALLBACK disconnect_cb;
+    void* disconnect_ctx;
+    QOS_VALUE qosValue;
+    uint16_t keepAliveInterval;
+    MQTT_CLIENT_OPTIONS mqttOptions;
+
+    uint16_t mqtt_status;
+    uint16_t mqtt_flags;
+
+    tickcounter_ms_t timeSincePing;
+    uint16_t maxPingRespTime;
+} MQTT_CLIENT;
+
+static bool is_trace_enabled(MQTT_CLIENT* mqtt_client)
+{
+    return (mqtt_client->mqtt_flags & MQTT_FLAGS_LOG_TRACE);
+}
+
+#ifdef ENABLE_RAW_TRACE
+static bool is_raw_trace_enabled(MQTT_CLIENT* mqtt_client)
+{
+    return (mqtt_client->mqtt_flags & MQTT_FLAGS_RAW_TRACE);
+}
+#endif // ENABLE_RAW_TRACE
+
+static void on_connection_closed(void* context)
+{
+    MQTT_CLIENT* mqtt_client = (MQTT_CLIENT*)context;
+    if (mqtt_client != NULL)
+    {
+        mqtt_client->mqtt_status &= ~MQTT_STATUS_SOCKET_CONNECTED;
+        if (mqtt_client->disconnect_cb)
+        {
+            mqtt_client->disconnect_cb(mqtt_client->disconnect_ctx);
+        }
+    }
+}
+
+static void close_connection(MQTT_CLIENT* mqtt_client)
+{
+    if (mqtt_client->mqtt_status & MQTT_STATUS_SOCKET_CONNECTED)
+    {
+        (void)xio_close(mqtt_client->xioHandle, on_connection_closed, mqtt_client);
+        if (mqtt_client->disconnect_cb == NULL)
+        {
+            size_t counter = 0;
+            do
+            {
+                xio_dowork(mqtt_client->xioHandle);
+                counter++;
+                ThreadAPI_Sleep(2);
+            } while (mqtt_client->mqtt_status & MQTT_STATUS_SOCKET_CONNECTED && counter < MAX_CLOSE_RETRIES);
+        }
+        // Clear the handle because we don't use it anymore
+        mqtt_client->xioHandle = NULL;
+    }
+    else
+    {
+        mqtt_client->mqtt_status &= ~MQTT_STATUS_SOCKET_CONNECTED;
+        if (mqtt_client->disconnect_cb)
+        {
+            mqtt_client->disconnect_cb(mqtt_client->disconnect_ctx);
+        }
+    }
+}
+
+static void set_error_callback(MQTT_CLIENT* mqtt_client, MQTT_CLIENT_EVENT_ERROR error_type)
+{
+    if (mqtt_client->fnOnErrorCallBack)
+    {
+        mqtt_client->fnOnErrorCallBack(mqtt_client, error_type, mqtt_client->errorCBCtx);
+    }
+    close_connection(mqtt_client);
+}
+
+static STRING_HANDLE construct_trace_log_handle(MQTT_CLIENT* mqtt_client)
+{
+    STRING_HANDLE trace_log;
+    if (is_trace_enabled(mqtt_client) )
+    {
+        trace_log = STRING_new();
+    }
+    else
+    {
+        trace_log = NULL;
+    }
+    return trace_log;
+}
+
+static uint16_t byteutil_read_uint16(uint8_t** buffer, size_t byteLen)
+{
+    uint16_t result = 0;
+    if (buffer != NULL && *buffer != NULL && byteLen >= 2)
+    {
+        result = 256 * (**buffer) + (*(*buffer + 1));
+        *buffer += 2; // Move the ptr
+    }
+    else
+    {
+        LogError("byteutil_read_uint16 == NULL or less than 2");
+    }
+    return result;
+}
+
+static char* byteutil_readUTF(uint8_t** buffer, size_t* byteLen)
+{
+    char* result = NULL;
+
+    const uint8_t* bufferInitial = *buffer;
+    // Get the length of the string
+    uint16_t stringLen = byteutil_read_uint16(buffer, *byteLen);
+    // Verify that byteutil_read_uint16 succeeded (by stringLen>0) and that we're
+    // not being asked to read a string longer than buffer passed in.
+    if ((stringLen > 0) && ((size_t)(stringLen + (*buffer - bufferInitial)) <= *byteLen))
+    {
+        result = (char*)malloc(stringLen + 1);
+        if (result != NULL)
+        {
+            (void)memcpy(result, *buffer, stringLen);
+            result[stringLen] = '\0';
+            *buffer += stringLen;
+            *byteLen = stringLen;
+         }
+    }
+    else
+    {
+        LogError("String passed not a valid UTF.");
+    }
+
+    return result;
+}
+
+static uint8_t byteutil_readByte(uint8_t** buffer)
+{
+    uint8_t result = 0;
+    if (buffer != NULL)
+    {
+        result = **buffer;
+        (*buffer)++;
+    }
+    else
+    {
+        LogError("readByte buffer == NULL.");
+    }
+    return result;
+}
+
+static void sendComplete(void* context, IO_SEND_RESULT send_result)
+{
+    MQTT_CLIENT* mqtt_client = (MQTT_CLIENT*)context;
+    if (mqtt_client != NULL)
+    {
+        if (send_result == IO_SEND_OK)
+        {
+            if (mqtt_client->packetState == DISCONNECT_TYPE)
+            {
+                /*Codes_SRS_MQTT_CLIENT_07_032: [If the actionResult parameter is of type MQTT_CLIENT_ON_DISCONNECT the the msgInfo value shall be NULL.]*/
+                if (mqtt_client->fnOperationCallback != NULL)
+                {
+                    mqtt_client->fnOperationCallback(mqtt_client, MQTT_CLIENT_ON_DISCONNECT, NULL, mqtt_client->ctx);
+                }
+
+                // Mark to close
+                mqtt_client->mqtt_status |= MQTT_STATUS_PENDING_CLOSE;
+            }
+        }
+        else if (send_result == IO_SEND_ERROR)
+        {
+            LogError("MQTT Send Complete Failure send_result: %d", (int)send_result);
+            set_error_callback(mqtt_client, MQTT_CLIENT_COMMUNICATION_ERROR);
+        }
+    }
+    else
+    {
+        LogError("MQTT Send Complete Failure with NULL mqtt_client");
+    }
+}
+
+#ifndef NO_LOGGING
+static void getLogTime(char* timeResult, size_t len)
+{
+    if (timeResult != NULL)
+    {
+        time_t agent_time = get_time(NULL);
+        if (agent_time == (time_t)-1)
+        {
+            timeResult[0] = '\0';
+        }
+        else
+        {
+            struct tm* tmInfo = localtime(&agent_time);
+            if (tmInfo == NULL)
+            {
+                timeResult[0] = '\0';
+            }
+            else
+            {
+                if (strftime(timeResult, len, "%H:%M:%S", tmInfo) == 0)
+                {
+                    timeResult[0] = '\0';
+                }
+            }
+        }
+    }
+}
+
+#ifdef ENABLE_RAW_TRACE
+static const char* retrievePacketType(CONTROL_PACKET_TYPE packet)
+{
+    switch (packet&CONNECT_PACKET_MASK)
+    {
+        case CONNECT_TYPE: return "CONNECT";
+        case CONNACK_TYPE:  return "CONNACK";
+        case PUBLISH_TYPE:  return "PUBLISH";
+        case PUBACK_TYPE:  return "PUBACK";
+        case PUBREC_TYPE:  return "PUBREC";
+        case PUBREL_TYPE:  return "PUBREL";
+        case SUBSCRIBE_TYPE:  return "SUBSCRIBE";
+        case SUBACK_TYPE:  return "SUBACK";
+        case UNSUBSCRIBE_TYPE:  return "UNSUBSCRIBE";
+        case UNSUBACK_TYPE:  return "UNSUBACK";
+        case PINGREQ_TYPE:  return "PINGREQ";
+        case PINGRESP_TYPE:  return "PINGRESP";
+        case DISCONNECT_TYPE:  return "DISCONNECT";
+        default:
+        case PACKET_TYPE_ERROR:
+        case UNKNOWN_TYPE:
+            return "UNKNOWN";
+    }
+}
+
+static void logOutgoingRawTrace(MQTT_CLIENT* mqtt_client, const uint8_t* data, size_t length)
+{
+    if (mqtt_client != NULL && data != NULL && length > 0 && is_raw_trace_enabled(mqtt_client))
+    {
+        char tmBuffer[TIME_MAX_BUFFER];
+        getLogTime(tmBuffer, TIME_MAX_BUFFER);
+
+        LOG(AZ_LOG_TRACE, 0, "-> %s %s: ", tmBuffer, retrievePacketType((unsigned char)data[0]));
+        size_t index = 0;
+        for (index = 0; index < length; index++)
+        {
+            LOG(AZ_LOG_TRACE, 0, "0x%02x ", data[index]);
+        }
+        LOG(AZ_LOG_TRACE, LOG_LINE, " ");
+    }
+}
+
+static void logIncomingRawTrace(MQTT_CLIENT* mqtt_client, CONTROL_PACKET_TYPE packet, uint8_t flags, const uint8_t* data, size_t length)
+{
+    if (mqtt_client != NULL && is_raw_trace_enabled(mqtt_client))
+    {
+        if (data != NULL && length > 0)
+        {
+            char tmBuffer[TIME_MAX_BUFFER];
+            getLogTime(tmBuffer, TIME_MAX_BUFFER);
+
+            LOG(AZ_LOG_TRACE, 0, "<- %s %s: 0x%02x 0x%02x ", tmBuffer, retrievePacketType((CONTROL_PACKET_TYPE)packet), (unsigned int)(packet | flags), (unsigned int)length);
+            size_t index = 0;
+            for (index = 0; index < length; index++)
+            {
+                LOG(AZ_LOG_TRACE, 0, "0x%02x ", data[index]);
+            }
+            LOG(AZ_LOG_TRACE, LOG_LINE, " ");
+        }
+        else if (packet == PINGRESP_TYPE)
+        {
+            char tmBuffer[TIME_MAX_BUFFER];
+            getLogTime(tmBuffer, TIME_MAX_BUFFER);
+            LOG(AZ_LOG_TRACE, LOG_LINE, "<- %s %s: 0x%02x 0x%02x ", tmBuffer, retrievePacketType((CONTROL_PACKET_TYPE)packet), (unsigned int)(packet | flags), (unsigned int)length);
+        }
+    }
+}
+#endif // ENABLE_RAW_TRACE
+
+static void log_outgoing_trace(MQTT_CLIENT* mqtt_client, STRING_HANDLE trace_log)
+{
+    if (mqtt_client != NULL && is_trace_enabled(mqtt_client) && trace_log != NULL)
+    {
+        char tmBuffer[TIME_MAX_BUFFER];
+        getLogTime(tmBuffer, TIME_MAX_BUFFER);
+        LOG(AZ_LOG_TRACE, LOG_LINE, "-> %s %s", tmBuffer, STRING_c_str(trace_log));
+    }
+}
+
+static void log_incoming_trace(MQTT_CLIENT* mqtt_client, STRING_HANDLE trace_log)
+{
+    if (mqtt_client != NULL && is_trace_enabled(mqtt_client) && trace_log != NULL)
+    {
+        char tmBuffer[TIME_MAX_BUFFER];
+        getLogTime(tmBuffer, TIME_MAX_BUFFER);
+        LOG(AZ_LOG_TRACE, LOG_LINE, "<- %s %s", tmBuffer, STRING_c_str(trace_log) );
+    }
+}
+#else // NO_LOGGING
+static void logOutgoingRawTrace(MQTT_CLIENT* mqtt_client, const uint8_t* data, size_t length)
+{
+    AZURE_UNREFERENCED_PARAMETER(mqtt_client);
+    AZURE_UNREFERENCED_PARAMETER(data);
+    AZURE_UNREFERENCED_PARAMETER(length);
+}
+
+static void log_outgoing_trace(MQTT_CLIENT* mqtt_client, STRING_HANDLE trace_log)
+{
+    AZURE_UNREFERENCED_PARAMETER(mqtt_client);
+    AZURE_UNREFERENCED_PARAMETER(trace_log);
+}
+
+static void log_incoming_trace(MQTT_CLIENT* mqtt_client, STRING_HANDLE trace_log)
+{
+    AZURE_UNREFERENCED_PARAMETER(mqtt_client);
+    AZURE_UNREFERENCED_PARAMETER(trace_log);
+}
+
+static void logIncomingRawTrace(MQTT_CLIENT* mqtt_client, CONTROL_PACKET_TYPE packet, uint8_t flags, const uint8_t* data, size_t length)
+{
+    AZURE_UNREFERENCED_PARAMETER(mqtt_client);
+    AZURE_UNREFERENCED_PARAMETER(packet);
+    AZURE_UNREFERENCED_PARAMETER(flags);
+    AZURE_UNREFERENCED_PARAMETER(data);
+    AZURE_UNREFERENCED_PARAMETER(length);
+}
+#endif // NO_LOGGING
+
+static int sendPacketItem(MQTT_CLIENT* mqtt_client, const unsigned char* data, size_t length)
+{
+    int result;
+
+    if (tickcounter_get_current_ms(mqtt_client->packetTickCntr, &mqtt_client->packetSendTimeMs) != 0)
+    {
+        LogError("Failure getting current ms tickcounter");
+        result = MU_FAILURE;
+    }
+    else
+    {
+        result = xio_send(mqtt_client->xioHandle, (const void*)data, length, sendComplete, mqtt_client);
+        if (result != 0)
+        {
+            LogError("Failure sending control packet data");
+            result = MU_FAILURE;
+        }
+        else
+        {
+#ifdef ENABLE_RAW_TRACE
+            logOutgoingRawTrace(mqtt_client, (const uint8_t*)data, length);
+#endif
+        }
+    }
+    return result;
+}
+
+static void onOpenComplete(void* context, IO_OPEN_RESULT open_result)
+{
+    MQTT_CLIENT* mqtt_client = (MQTT_CLIENT*)context;
+    if (mqtt_client != NULL)
+    {
+        if (open_result == IO_OPEN_OK && !(mqtt_client->mqtt_status & MQTT_STATUS_SOCKET_CONNECTED))
+        {
+            mqtt_client->packetState = CONNECT_TYPE;
+            mqtt_client->mqtt_status |= MQTT_STATUS_SOCKET_CONNECTED;
+
+            STRING_HANDLE trace_log = construct_trace_log_handle(mqtt_client);
+
+            // Send the Connect packet
+            BUFFER_HANDLE connPacket = mqtt_codec_connect(&mqtt_client->mqttOptions, trace_log);
+            if (connPacket == NULL)
+            {
+                LogError("Error: mqtt_codec_connect failed");
+            }
+            else
+            {
+                size_t size = BUFFER_length(connPacket);
+                /*Codes_SRS_MQTT_CLIENT_07_009: [On success mqtt_client_connect shall send the MQTT CONNECT to the endpoint.]*/
+                if (sendPacketItem(mqtt_client, BUFFER_u_char(connPacket), size) != 0)
+                {
+                    LogError("Error: failure sending connect packet");
+                    // Set the status to pending close because we connot continue
+                    // with CONN failing to send
+                    if (mqtt_client->fnOnErrorCallBack)
+                    {
+                        mqtt_client->fnOnErrorCallBack(mqtt_client, MQTT_CLIENT_CONNECTION_ERROR, mqtt_client->errorCBCtx);
+                    }
+                    mqtt_client->mqtt_status |= MQTT_STATUS_PENDING_CLOSE;
+                }
+                else
+                {
+                    log_outgoing_trace(mqtt_client, trace_log);
+                }
+                BUFFER_delete(connPacket);
+            }
+            if (trace_log != NULL)
+            {
+                STRING_delete(trace_log);
+            }
+        }
+        else
+        {
+            LogError("Error: failure opening connection to endpoint");
+            if (!(mqtt_client->mqtt_status & MQTT_STATUS_SOCKET_CONNECTED) && mqtt_client->fnOnErrorCallBack)
+            {
+                mqtt_client->fnOnErrorCallBack(mqtt_client, MQTT_CLIENT_CONNECTION_ERROR, mqtt_client->errorCBCtx);
+            }
+            mqtt_client->mqtt_status |= MQTT_STATUS_PENDING_CLOSE;
+        }
+    }
+    else
+    {
+        LogError("Error: mqtt_client is NULL");
+    }
+}
+
+static void onBytesReceived(void* context, const unsigned char* buffer, size_t size)
+{
+    MQTT_CLIENT* mqtt_client = (MQTT_CLIENT*)context;
+    if (mqtt_client != NULL)
+    {
+        if (mqtt_codec_bytesReceived(mqtt_client->codec_handle, buffer, size) != 0)
+        {
+            mqtt_codec_reset(mqtt_client->codec_handle);
+            set_error_callback(mqtt_client, MQTT_CLIENT_PARSE_ERROR);
+        }
+    }
+    else
+    {
+        LogError("Error: mqtt_client is NULL");
+    }
+}
+
+static void onIoError(void* context)
+{
+    MQTT_CLIENT* mqtt_client = (MQTT_CLIENT*)context;
+    if (mqtt_client != NULL && mqtt_client->fnOperationCallback)
+    {
+        /*Codes_SRS_MQTT_CLIENT_07_032: [If the actionResult parameter is of type MQTT_CLIENT_ON_DISCONNECT the the msgInfo value shall be NULL.]*/
+        /* Codes_SRS_MQTT_CLIENT_07_036: [ If an error is encountered by the ioHandle the mqtt_client shall call xio_close. ] */
+        set_error_callback(mqtt_client, MQTT_CLIENT_CONNECTION_ERROR);
+    }
+    else
+    {
+        LogError("Error invalid parameter: mqtt_client: %p", mqtt_client);
+    }
+}
+
+static void clear_mqtt_options(MQTT_CLIENT* mqtt_client)
+{
+    if (mqtt_client->mqttOptions.clientId != NULL)
+    {
+        free(mqtt_client->mqttOptions.clientId);
+        mqtt_client->mqttOptions.clientId = NULL;
+    }
+
+    if (mqtt_client->mqttOptions.willTopic != NULL)
+    {
+        free(mqtt_client->mqttOptions.willTopic);
+        mqtt_client->mqttOptions.willTopic = NULL;
+    }
+
+    if (mqtt_client->mqttOptions.willMessage != NULL)
+    {
+        free(mqtt_client->mqttOptions.willMessage);
+        mqtt_client->mqttOptions.willMessage = NULL;
+    }
+
+    if (mqtt_client->mqttOptions.username != NULL)
+    {
+        free(mqtt_client->mqttOptions.username);
+        mqtt_client->mqttOptions.username = NULL;
+    }
+
+    if (mqtt_client->mqttOptions.password != NULL)
+    {
+        free(mqtt_client->mqttOptions.password);
+        mqtt_client->mqttOptions.password = NULL;
+    }
+}
+
+static int cloneMqttOptions(MQTT_CLIENT* mqtt_client, const MQTT_CLIENT_OPTIONS* mqttOptions)
+{
+    int result = 0;
+    char* temp_option;
+
+    if (mqttOptions->clientId != NULL)
+    {
+        if (mallocAndStrcpy_s(&temp_option, mqttOptions->clientId) != 0)
+        {
+            result = MU_FAILURE;
+            LogError("mallocAndStrcpy_s clientId");
+        }
+        else
+        {
+            if (mqtt_client->mqttOptions.clientId != NULL)
+            {
+                free(mqtt_client->mqttOptions.clientId);
+            }
+            mqtt_client->mqttOptions.clientId = temp_option;
+        }
+    }
+    if (result == 0 && mqttOptions->willTopic != NULL)
+    {
+        temp_option = NULL;
+        if (mallocAndStrcpy_s(&temp_option, mqttOptions->willTopic) != 0)
+        {
+            result = MU_FAILURE;
+            LogError("mallocAndStrcpy_s willTopic");
+        }
+        else
+        {
+            if (mqtt_client->mqttOptions.willTopic != NULL)
+            {
+                free(mqtt_client->mqttOptions.willTopic);
+            }
+            mqtt_client->mqttOptions.willTopic = temp_option;
+        }
+    }
+    if (result == 0 && mqttOptions->willMessage != NULL)
+    {
+        temp_option = NULL;
+        if (mallocAndStrcpy_s(&temp_option, mqttOptions->willMessage) != 0)
+        {
+            LogError("mallocAndStrcpy_s willMessage");
+            result = MU_FAILURE;
+        }
+        else
+        {
+            if (mqtt_client->mqttOptions.willMessage != NULL)
+            {
+                free(mqtt_client->mqttOptions.willMessage);
+            }
+            mqtt_client->mqttOptions.willMessage = temp_option;
+        }
+    }
+    if (result == 0 && mqttOptions->username != NULL)
+    {
+        temp_option = NULL;
+        if (mallocAndStrcpy_s(&temp_option, mqttOptions->username) != 0)
+        {
+            LogError("mallocAndStrcpy_s username");
+            result = MU_FAILURE;
+        }
+        else
+        {
+            if (mqtt_client->mqttOptions.username != NULL)
+            {
+                free(mqtt_client->mqttOptions.username);
+            }
+            mqtt_client->mqttOptions.username = temp_option;
+        }
+    }
+    if (result == 0 && mqttOptions->password != NULL)
+    {
+        temp_option = NULL;
+        if (mallocAndStrcpy_s(&temp_option, mqttOptions->password) != 0)
+        {
+            LogError("mallocAndStrcpy_s password");
+            result = MU_FAILURE;
+        }
+        else
+        {
+            if (mqtt_client->mqttOptions.password != NULL)
+            {
+                free(mqtt_client->mqttOptions.password);
+            }
+            mqtt_client->mqttOptions.password = temp_option;
+        }
+    }
+    if (result == 0)
+    {
+        mqtt_client->mqttOptions.keepAliveInterval = mqttOptions->keepAliveInterval;
+        mqtt_client->mqttOptions.messageRetain = mqttOptions->messageRetain;
+        mqtt_client->mqttOptions.useCleanSession = mqttOptions->useCleanSession;
+        mqtt_client->mqttOptions.qualityOfServiceValue = mqttOptions->qualityOfServiceValue;
+    }
+    else
+    {
+        clear_mqtt_options(mqtt_client);
+    }
+    return result;
+}
+
+static void ProcessPublishMessage(MQTT_CLIENT* mqtt_client, uint8_t* initialPos, size_t packetLength, int flags)
+{
+    bool isDuplicateMsg = (flags & DUPLICATE_FLAG_MASK) ? true : false;
+    bool isRetainMsg = (flags & RETAIN_FLAG_MASK) ? true : false;
+    QOS_VALUE qosValue = (flags == 0) ? DELIVER_AT_MOST_ONCE : (flags & QOS_LEAST_ONCE_FLAG_MASK) ? DELIVER_AT_LEAST_ONCE : DELIVER_EXACTLY_ONCE;
+
+    uint8_t* iterator = initialPos;
+    size_t numberOfBytesToBeRead = packetLength;
+    size_t lengthOfTopicName = numberOfBytesToBeRead;
+    char* topicName = byteutil_readUTF(&iterator, &lengthOfTopicName);
+    if (topicName == NULL)
+    {
+        LogError("Publish MSG: failure reading topic name");
+        set_error_callback(mqtt_client, MQTT_CLIENT_PARSE_ERROR);
+    }
+    else
+    {
+        STRING_HANDLE trace_log = NULL;
+
+#ifndef NO_LOGGING
+        if (is_trace_enabled(mqtt_client))
+        {
+            trace_log = STRING_construct_sprintf("PUBLISH | IS_DUP: %s | RETAIN: %d | QOS: %s | TOPIC_NAME: %s", isDuplicateMsg ? TRUE_CONST : FALSE_CONST,
+                isRetainMsg ? 1 : 0, MU_ENUM_TO_STRING(QOS_VALUE, qosValue), topicName);
+        }
+#endif
+        uint16_t packetId = 0;
+        numberOfBytesToBeRead = packetLength - (iterator - initialPos);
+        if (qosValue != DELIVER_AT_MOST_ONCE)
+        {
+            packetId = byteutil_read_uint16(&iterator, numberOfBytesToBeRead);
+#ifndef NO_LOGGING
+            if (is_trace_enabled(mqtt_client))
+            {
+                STRING_sprintf(trace_log, " | PACKET_ID: %"PRIu16, packetId);
+            }
+#endif
+        }
+        if ((qosValue != DELIVER_AT_MOST_ONCE) && (packetId == 0))
+        {
+            LogError("Publish MSG: packetId=0, invalid");
+            set_error_callback(mqtt_client, MQTT_CLIENT_PARSE_ERROR);
+        }
+        else
+        {
+            numberOfBytesToBeRead = packetLength - (iterator - initialPos);
+
+            MQTT_MESSAGE_HANDLE msgHandle = mqttmessage_create_in_place(packetId, topicName, qosValue, iterator, numberOfBytesToBeRead);
+            if (msgHandle == NULL)
+            {
+                LogError("failure in mqttmessage_create");
+                set_error_callback(mqtt_client, MQTT_CLIENT_MEMORY_ERROR);
+            }
+            else if (mqttmessage_setIsDuplicateMsg(msgHandle, isDuplicateMsg) != 0 ||
+                     mqttmessage_setIsRetained(msgHandle, isRetainMsg) != 0)
+            {
+                LogError("failure setting mqtt message property");
+                set_error_callback(mqtt_client, MQTT_CLIENT_MEMORY_ERROR);
+            }
+            else
+            {
+#ifndef NO_LOGGING
+                if (is_trace_enabled(mqtt_client))
+                {
+                    STRING_sprintf(trace_log, " | PAYLOAD_LEN: %lu", (unsigned long)numberOfBytesToBeRead);
+                    log_incoming_trace(mqtt_client, trace_log);
+                }
+#endif
+                mqtt_client->fnMessageRecv(msgHandle, mqtt_client->ctx);
+
+                BUFFER_HANDLE pubRel = NULL;
+                if (qosValue == DELIVER_EXACTLY_ONCE)
+                {
+                    pubRel = mqtt_codec_publishReceived(packetId);
+                    if (pubRel == NULL)
+                    {
+                        LogError("Failed to allocate publish receive message.");
+                        set_error_callback(mqtt_client, MQTT_CLIENT_MEMORY_ERROR);
+                    }
+                }
+                else if (qosValue == DELIVER_AT_LEAST_ONCE)
+                {
+                    pubRel = mqtt_codec_publishAck(packetId);
+                    if (pubRel == NULL)
+                    {
+                        LogError("Failed to allocate publish ack message.");
+                        set_error_callback(mqtt_client, MQTT_CLIENT_MEMORY_ERROR);
+                    }
+                }
+                if (pubRel != NULL)
+                {
+                    size_t size = BUFFER_length(pubRel);
+                    if (sendPacketItem(mqtt_client, BUFFER_u_char(pubRel), size) != 0)
+                    {
+                        LogError("Failed sending publish reply.");
+                        set_error_callback(mqtt_client, MQTT_CLIENT_COMMUNICATION_ERROR);
+                    }
+                    BUFFER_delete(pubRel);
+                }
+            }
+            mqttmessage_destroy(msgHandle);
+        }
+
+        if (trace_log != NULL)
+        {
+            STRING_delete(trace_log);
+        }
+
+        free(topicName);
+    }
+}
+
+static void recvCompleteCallback(void* context, CONTROL_PACKET_TYPE packet, int flags, BUFFER_HANDLE headerData)
+{
+    MQTT_CLIENT* mqtt_client = (MQTT_CLIENT*)context;
+    if (mqtt_client != NULL)
+    {
+        size_t packetLength = 0;
+        uint8_t* iterator = NULL;
+        if (headerData != NULL)
+        {
+            packetLength = BUFFER_length(headerData);
+            iterator = BUFFER_u_char(headerData);
+        }
+
+#ifdef ENABLE_RAW_TRACE
+        logIncomingRawTrace(mqtt_client, packet, (uint8_t)flags, iterator, packetLength);
+#endif
+        if ((iterator != NULL && packetLength > 0) || packet == PINGRESP_TYPE)
+        {
+            switch (packet)
+            {
+                case CONNACK_TYPE:
+                {
+                    /*Codes_SRS_MQTT_CLIENT_07_028: [If the actionResult parameter is of type CONNECT_ACK then the msgInfo value shall be a CONNECT_ACK structure.]*/
+                    CONNECT_ACK connack = { 0 };
+                    connack.isSessionPresent = (byteutil_readByte(&iterator) == 0x1) ? true : false;
+                    uint8_t rc = byteutil_readByte(&iterator);
+                    connack.returnCode =
+                        (rc < ((uint8_t)CONN_REFUSED_UNKNOWN)) ?
+                        (CONNECT_RETURN_CODE)rc : CONN_REFUSED_UNKNOWN;
+
+#ifndef NO_LOGGING
+                    if (is_trace_enabled(mqtt_client))
+                    {
+                        STRING_HANDLE trace_log = STRING_construct_sprintf("CONNACK | SESSION_PRESENT: %s | RETURN_CODE: 0x%x", connack.isSessionPresent ? TRUE_CONST : FALSE_CONST, connack.returnCode);
+                        log_incoming_trace(mqtt_client, trace_log);
+                        STRING_delete(trace_log);
+                    }
+#endif
+                    mqtt_client->fnOperationCallback(mqtt_client, MQTT_CLIENT_ON_CONNACK, (void*)&connack, mqtt_client->ctx);
+
+                    if (connack.returnCode == CONNECTION_ACCEPTED)
+                    {
+                        mqtt_client->mqtt_status |= MQTT_STATUS_CLIENT_CONNECTED;
+                    }
+                    break;
+                }
+                case PUBLISH_TYPE:
+                {
+                    ProcessPublishMessage(mqtt_client, iterator, packetLength, flags);
+                    break;
+                }
+                case PUBACK_TYPE:
+                case PUBREC_TYPE:
+                case PUBREL_TYPE:
+                case PUBCOMP_TYPE:
+                {
+                    /*Codes_SRS_MQTT_CLIENT_07_029: [If the actionResult parameter are of types PUBACK_TYPE, PUBREC_TYPE, PUBREL_TYPE or PUBCOMP_TYPE then the msgInfo value shall be a PUBLISH_ACK structure.]*/
+                    MQTT_CLIENT_EVENT_RESULT action = (packet == PUBACK_TYPE) ? MQTT_CLIENT_ON_PUBLISH_ACK :
+                        (packet == PUBREC_TYPE) ? MQTT_CLIENT_ON_PUBLISH_RECV :
+                        (packet == PUBREL_TYPE) ? MQTT_CLIENT_ON_PUBLISH_REL : MQTT_CLIENT_ON_PUBLISH_COMP;
+
+                    PUBLISH_ACK publish_ack = { 0 };
+                    publish_ack.packetId = byteutil_read_uint16(&iterator, packetLength);
+
+#ifndef NO_LOGGING
+                    if (is_trace_enabled(mqtt_client))
+                    {
+                        STRING_HANDLE trace_log = STRING_construct_sprintf("%s | PACKET_ID: %"PRIu16, packet == PUBACK_TYPE ? "PUBACK" : (packet == PUBREC_TYPE) ? "PUBREC" : (packet == PUBREL_TYPE) ? "PUBREL" : "PUBCOMP",
+                            publish_ack.packetId);
+
+                        log_incoming_trace(mqtt_client, trace_log);
+                        STRING_delete(trace_log);
+                    }
+#endif
+                    BUFFER_HANDLE pubRel = NULL;
+                    mqtt_client->fnOperationCallback(mqtt_client, action, (void*)&publish_ack, mqtt_client->ctx);
+                    if (packet == PUBREC_TYPE)
+                    {
+                        pubRel = mqtt_codec_publishRelease(publish_ack.packetId);
+                        if (pubRel == NULL)
+                        {
+                            LogError("Failed to allocate publish release message.");
+                            set_error_callback(mqtt_client, MQTT_CLIENT_MEMORY_ERROR);
+                        }
+                    }
+                    else if (packet == PUBREL_TYPE)
+                    {
+                        pubRel = mqtt_codec_publishComplete(publish_ack.packetId);
+                        if (pubRel == NULL)
+                        {
+                            LogError("Failed to allocate publish complete message.");
+                            set_error_callback(mqtt_client, MQTT_CLIENT_MEMORY_ERROR);
+                        }
+                    }
+                    if (pubRel != NULL)
+                    {
+                        size_t size = BUFFER_length(pubRel);
+                        if (sendPacketItem(mqtt_client, BUFFER_u_char(pubRel), size) != 0)
+                        {
+                            LogError("Failed sending publish reply.");
+                            set_error_callback(mqtt_client, MQTT_CLIENT_COMMUNICATION_ERROR);
+                        }
+                        BUFFER_delete(pubRel);
+                    }
+                    break;
+                }
+                case SUBACK_TYPE:
+                {
+
+                    /*Codes_SRS_MQTT_CLIENT_07_030: [If the actionResult parameter is of type SUBACK_TYPE then the msgInfo value shall be a SUBSCRIBE_ACK structure.]*/
+                    SUBSCRIBE_ACK suback = { 0 };
+
+                    size_t remainLen = packetLength;
+                    suback.packetId = byteutil_read_uint16(&iterator, packetLength);
+                    remainLen -= 2;
+
+#ifndef NO_LOGGING
+                    STRING_HANDLE trace_log = NULL;
+                    if (is_trace_enabled(mqtt_client))
+                    {
+                        trace_log = STRING_construct_sprintf("SUBACK | PACKET_ID: %"PRIu16, suback.packetId);
+                    }
+#endif
+                    // Allocate the remaining len
+                    suback.qosReturn = (QOS_VALUE*)malloc(sizeof(QOS_VALUE)*remainLen);
+                    if (suback.qosReturn != NULL)
+                    {
+                        while (remainLen > 0)
+                        {
+                            uint8_t qosRet = byteutil_readByte(&iterator);
+                            suback.qosReturn[suback.qosCount++] =
+                                (qosRet <= ((uint8_t)DELIVER_EXACTLY_ONCE)) ?
+                                (QOS_VALUE)qosRet :  DELIVER_FAILURE;
+                            remainLen--;
+#ifndef NO_LOGGING
+                            if (is_trace_enabled(mqtt_client))
+                            {
+                                STRING_sprintf(trace_log, " | RETURN_CODE: %"PRIu16, suback.qosReturn[suback.qosCount-1]);
+                            }
+#endif
+                        }
+
+#ifndef NO_LOGGING
+                        if (is_trace_enabled(mqtt_client))
+                        {
+                            log_incoming_trace(mqtt_client, trace_log);
+                            STRING_delete(trace_log);
+                        }
+#endif
+                        mqtt_client->fnOperationCallback(mqtt_client, MQTT_CLIENT_ON_SUBSCRIBE_ACK, (void*)&suback, mqtt_client->ctx);
+                        free(suback.qosReturn);
+                    }
+                    else
+                    {
+                        LogError("allocation of quality of service value failed.");
+                        set_error_callback(mqtt_client, MQTT_CLIENT_MEMORY_ERROR);
+                    }
+                    break;
+                }
+                case UNSUBACK_TYPE:
+                {
+                    /*Codes_SRS_MQTT_CLIENT_07_031: [If the actionResult parameter is of type UNSUBACK_TYPE then the msgInfo value shall be a UNSUBSCRIBE_ACK structure.]*/
+                    UNSUBSCRIBE_ACK unsuback = { 0 };
+                    unsuback.packetId = byteutil_read_uint16(&iterator, packetLength);
+
+#ifndef NO_LOGGING
+                    if (is_trace_enabled(mqtt_client))
+                    {
+                        STRING_HANDLE trace_log = STRING_construct_sprintf("UNSUBACK | PACKET_ID: %"PRIu16, unsuback.packetId);
+                        log_incoming_trace(mqtt_client, trace_log);
+                        STRING_delete(trace_log);
+                    }
+#endif
+                    mqtt_client->fnOperationCallback(mqtt_client, MQTT_CLIENT_ON_UNSUBSCRIBE_ACK, (void*)&unsuback, mqtt_client->ctx);
+                    break;
+                }
+                case PINGRESP_TYPE:
+                    mqtt_client->timeSincePing = 0;
+#ifndef NO_LOGGING
+                    if (is_trace_enabled(mqtt_client))
+                    {
+                        STRING_HANDLE trace_log = STRING_construct_sprintf("PINGRESP");
+                        log_incoming_trace(mqtt_client, trace_log);
+                        STRING_delete(trace_log);
+                    }
+#endif
+                    // Forward ping response to operation callback
+                    mqtt_client->fnOperationCallback(mqtt_client, MQTT_CLIENT_ON_PING_RESPONSE, NULL, mqtt_client->ctx);
+                    break;
+                default:
+                    break;
+            }
+        }
+    }
+    else
+    {
+        LogError("recvCompleteCallback context failed.");
+    }
+}
+
+MQTT_CLIENT_HANDLE mqtt_client_init(ON_MQTT_MESSAGE_RECV_CALLBACK msgRecv, ON_MQTT_OPERATION_CALLBACK operation_cb, void* opCallbackCtx, ON_MQTT_ERROR_CALLBACK onErrorCallBack, void* errorCBCtx)
+{
+    MQTT_CLIENT* result;
+    /*Codes_SRS_MQTT_CLIENT_07_001: [If the parameters ON_MQTT_MESSAGE_RECV_CALLBACK is NULL then mqttclient_init shall return NULL.]*/
+    if (msgRecv == NULL || operation_cb == NULL)
+    {
+        LogError("Invalid parameter specified msgRecv: %p, operation_cb: %p", msgRecv, operation_cb);
+        result = NULL;
+    }
+    else
+    {
+        result = malloc(sizeof(MQTT_CLIENT));
+        if (result == NULL)
+        {
+            /*Codes_SRS_MQTT_CLIENT_07_002: [If any failure is encountered then mqttclient_init shall return NULL.]*/
+            LogError("mqtt_client_init failure: Allocation Failure");
+        }
+        else
+        {
+            memset(result, 0, sizeof(MQTT_CLIENT));
+            /*Codes_SRS_MQTT_CLIENT_07_003: [mqttclient_init shall allocate MQTTCLIENT_DATA_INSTANCE and return the MQTTCLIENT_HANDLE on success.]*/
+            result->packetState = UNKNOWN_TYPE;
+            result->fnOperationCallback = operation_cb;
+            result->ctx = opCallbackCtx;
+            result->fnMessageRecv = msgRecv;
+            result->fnOnErrorCallBack = onErrorCallBack;
+            result->errorCBCtx = errorCBCtx;
+            result->qosValue = DELIVER_AT_MOST_ONCE;
+            result->packetTickCntr = tickcounter_create();
+            result->maxPingRespTime = DEFAULT_MAX_PING_RESPONSE_TIME;
+            if (result->packetTickCntr == NULL)
+            {
+                /*Codes_SRS_MQTT_CLIENT_07_002: [If any failure is encountered then mqttclient_init shall return NULL.]*/
+                LogError("mqtt_client_init failure: tickcounter_create failure");
+                free(result);
+                result = NULL;
+            }
+            else
+            {
+                result->codec_handle = mqtt_codec_create(recvCompleteCallback, result);
+                if (result->codec_handle == NULL)
+                {
+                    /*Codes_SRS_MQTT_CLIENT_07_002: [If any failure is encountered then mqttclient_init shall return NULL.]*/
+                    LogError("mqtt_client_init failure: mqtt_codec_create failure");
+                    tickcounter_destroy(result->packetTickCntr);
+                    free(result);
+                    result = NULL;
+                }
+            }
+        }
+    }
+    return result;
+}
+
+void mqtt_client_deinit(MQTT_CLIENT_HANDLE handle)
+{
+    /*Codes_SRS_MQTT_CLIENT_07_004: [If the parameter handle is NULL then function mqtt_client_deinit shall do nothing.]*/
+    if (handle != NULL)
+    {
+        /*Codes_SRS_MQTT_CLIENT_07_005: [mqtt_client_deinit shall deallocate all memory allocated in this unit.]*/
+        MQTT_CLIENT* mqtt_client = (MQTT_CLIENT*)handle;
+        tickcounter_destroy(mqtt_client->packetTickCntr);
+        mqtt_codec_destroy(mqtt_client->codec_handle);
+        clear_mqtt_options(mqtt_client);
+        free(mqtt_client);
+    }
+}
+
+int mqtt_client_connect(MQTT_CLIENT_HANDLE handle, XIO_HANDLE xioHandle, MQTT_CLIENT_OPTIONS* mqttOptions)
+{
+    int result;
+    /*SRS_MQTT_CLIENT_07_006: [If any of the parameters handle, ioHandle, or mqttOptions are NULL then mqtt_client_connect shall return a non-zero value.]*/
+    if (handle == NULL || mqttOptions == NULL || xioHandle == NULL)
+    {
+        LogError("mqtt_client_connect: NULL argument (handle = %p, mqttOptions = %p, xioHandle: %p)", handle, mqttOptions, xioHandle);
+        result = MU_FAILURE;
+    }
+    else
+    {
+        MQTT_CLIENT* mqtt_client = (MQTT_CLIENT*)handle;
+        mqtt_client->xioHandle = xioHandle;
+        mqtt_client->packetState = UNKNOWN_TYPE;
+        mqtt_client->qosValue = mqttOptions->qualityOfServiceValue;
+        mqtt_client->keepAliveInterval = mqttOptions->keepAliveInterval;
+        mqtt_client->maxPingRespTime = (DEFAULT_MAX_PING_RESPONSE_TIME < mqttOptions->keepAliveInterval/2) ? DEFAULT_MAX_PING_RESPONSE_TIME : mqttOptions->keepAliveInterval/2;
+        if (cloneMqttOptions(mqtt_client, mqttOptions) != 0)
+        {
+            LogError("Error: Clone Mqtt Options failed");
+            result = MU_FAILURE;
+        }
+        /*Codes_SRS_MQTT_CLIENT_07_008: [mqtt_client_connect shall open the XIO_HANDLE by calling into the xio_open interface.]*/
+        else if (xio_open(xioHandle, onOpenComplete, mqtt_client, onBytesReceived, mqtt_client, onIoError, mqtt_client) != 0)
+        {
+            /*Codes_SRS_MQTT_CLIENT_07_007: [If any failure is encountered then mqtt_client_connect shall return a non-zero value.]*/
+            LogError("Error: io_open failed");
+            result = MU_FAILURE;
+            mqtt_client->xioHandle = NULL;
+            // Remove cloned options
+            clear_mqtt_options(mqtt_client);
+        }
+        else
+        {
+            result = 0;
+        }
+    }
+    return result;
+}
+
+int mqtt_client_publish(MQTT_CLIENT_HANDLE handle, MQTT_MESSAGE_HANDLE msgHandle)
+{
+    int result;
+    MQTT_CLIENT* mqtt_client = (MQTT_CLIENT*)handle;
+    if (mqtt_client == NULL || msgHandle == NULL)
+    {
+        /*Codes_SRS_MQTT_CLIENT_07_019: [If one of the parameters handle or msgHandle is NULL then mqtt_client_publish shall return a non-zero value.]*/
+        LogError("Invalid parameter specified mqtt_client: %p, msgHandle: %p", mqtt_client, msgHandle);
+        result = MU_FAILURE;
+    }
+    else
+    {
+        /*Codes_SRS_MQTT_CLIENT_07_021: [mqtt_client_publish shall get the message information from the MQTT_MESSAGE_HANDLE.]*/
+        const APP_PAYLOAD* payload = mqttmessage_getApplicationMsg(msgHandle);
+        if (payload == NULL)
+        {
+            /*Codes_SRS_MQTT_CLIENT_07_020: [If any failure is encountered then mqtt_client_unsubscribe shall return a non-zero value.]*/
+            LogError("Error: mqttmessage_getApplicationMsg failed");
+            result = MU_FAILURE;
+        }
+        else
+        {
+            STRING_HANDLE trace_log = construct_trace_log_handle(mqtt_client);
+
+            QOS_VALUE qos = mqttmessage_getQosType(msgHandle);
+            bool isDuplicate = mqttmessage_getIsDuplicateMsg(msgHandle);
+            bool isRetained = mqttmessage_getIsRetained(msgHandle);
+            uint16_t packetId = mqttmessage_getPacketId(msgHandle);
+            const char* topicName = mqttmessage_getTopicName(msgHandle);
+            BUFFER_HANDLE publishPacket = mqtt_codec_publish(qos, isDuplicate, isRetained, packetId, topicName, payload->message, payload->length, trace_log);
+            if (publishPacket == NULL)
+            {
+                /*Codes_SRS_MQTT_CLIENT_07_020: [If any failure is encountered then mqtt_client_unsubscribe shall return a non-zero value.]*/
+                LogError("Error: mqtt_codec_publish failed");
+                result = MU_FAILURE;
+            }
+            else
+            {
+                mqtt_client->packetState = PUBLISH_TYPE;
+
+                /*Codes_SRS_MQTT_CLIENT_07_022: [On success mqtt_client_publish shall send the MQTT SUBCRIBE packet to the endpoint.]*/
+                size_t size = BUFFER_length(publishPacket);
+                if (sendPacketItem(mqtt_client, BUFFER_u_char(publishPacket), size) != 0)
+                {
+                    /*Codes_SRS_MQTT_CLIENT_07_020: [If any failure is encountered then mqtt_client_unsubscribe shall return a non-zero value.]*/
+                    LogError("Error: mqtt_client_publish send failed");
+                    result = MU_FAILURE;
+                }
+                else
+                {
+                    log_outgoing_trace(mqtt_client, trace_log);
+                    result = 0;
+                }
+                BUFFER_delete(publishPacket);
+            }
+            if (trace_log != NULL)
+            {
+                STRING_delete(trace_log);
+            }
+        }
+    }
+    return result;
+}
+
+int mqtt_client_subscribe(MQTT_CLIENT_HANDLE handle, uint16_t packetId, SUBSCRIBE_PAYLOAD* subscribeList, size_t count)
+{
+    int result;
+    MQTT_CLIENT* mqtt_client = (MQTT_CLIENT*)handle;
+    if (mqtt_client == NULL || subscribeList == NULL || count == 0 || packetId == 0)
+    {
+        /*Codes_SRS_MQTT_CLIENT_07_013: [If any of the parameters handle, subscribeList is NULL or count is 0 then mqtt_client_subscribe shall return a non-zero value.]*/
+        LogError("Invalid parameter specified mqtt_client: %p, subscribeList: %p, count: %lu, packetId: %d", mqtt_client, subscribeList, (unsigned long)count, packetId);
+        result = MU_FAILURE;
+    }
+    else
+    {
+        STRING_HANDLE trace_log = construct_trace_log_handle(mqtt_client);
+
+        BUFFER_HANDLE subPacket = mqtt_codec_subscribe(packetId, subscribeList, count, trace_log);
+        if (subPacket == NULL)
+        {
+            /*Codes_SRS_MQTT_CLIENT_07_014: [If any failure is encountered then mqtt_client_subscribe shall return a non-zero value.]*/
+            LogError("Error: mqtt_codec_subscribe failed");
+            result = MU_FAILURE;
+        }
+        else
+        {
+            mqtt_client->packetState = SUBSCRIBE_TYPE;
+
+            size_t size = BUFFER_length(subPacket);
+            /*Codes_SRS_MQTT_CLIENT_07_015: [On success mqtt_client_subscribe shall send the MQTT SUBCRIBE packet to the endpoint.]*/
+            if (sendPacketItem(mqtt_client, BUFFER_u_char(subPacket), size) != 0)
+            {
+                /*Codes_SRS_MQTT_CLIENT_07_014: [If any failure is encountered then mqtt_client_subscribe shall return a non-zero value.]*/
+                LogError("Error: mqtt_client_subscribe send failed");
+                result = MU_FAILURE;
+            }
+            else
+            {
+                log_outgoing_trace(mqtt_client, trace_log);
+                result = 0;
+            }
+            BUFFER_delete(subPacket);
+        }
+        if (trace_log != NULL)
+        {
+            STRING_delete(trace_log);
+        }
+    }
+    return result;
+}
+
+int mqtt_client_unsubscribe(MQTT_CLIENT_HANDLE handle, uint16_t packetId, const char** unsubscribeList, size_t count)
+{
+    int result;
+    MQTT_CLIENT* mqtt_client = (MQTT_CLIENT*)handle;
+    if (mqtt_client == NULL || unsubscribeList == NULL || count == 0 || packetId == 0)
+    {
+        /*Codes_SRS_MQTT_CLIENT_07_016: [If any of the parameters handle, unsubscribeList is NULL or count is 0 then mqtt_client_unsubscribe shall return a non-zero value.]*/
+        LogError("Invalid parameter specified mqtt_client: %p, unsubscribeList: %p, count: %lu, packetId: %d", mqtt_client, unsubscribeList, (unsigned long)count, packetId);
+        result = MU_FAILURE;
+    }
+    else
+    {
+        STRING_HANDLE trace_log = construct_trace_log_handle(mqtt_client);
+
+        BUFFER_HANDLE unsubPacket = mqtt_codec_unsubscribe(packetId, unsubscribeList, count, trace_log);
+        if (unsubPacket == NULL)
+        {
+            /*Codes_SRS_MQTT_CLIENT_07_017: [If any failure is encountered then mqtt_client_unsubscribe shall return a non-zero value.]*/
+            LogError("Error: mqtt_codec_unsubscribe failed");
+            result = MU_FAILURE;
+        }
+        else
+        {
+            mqtt_client->packetState = UNSUBSCRIBE_TYPE;
+
+            size_t size = BUFFER_length(unsubPacket);
+            /*Codes_SRS_MQTT_CLIENT_07_018: [On success mqtt_client_unsubscribe shall send the MQTT SUBCRIBE packet to the endpoint.]*/
+            if (sendPacketItem(mqtt_client, BUFFER_u_char(unsubPacket), size) != 0)
+            {
+                /*Codes_SRS_MQTT_CLIENT_07_017: [If any failure is encountered then mqtt_client_unsubscribe shall return a non-zero value.].]*/
+                LogError("Error: mqtt_client_unsubscribe send failed");
+                result = MU_FAILURE;
+            }
+            else
+            {
+                log_outgoing_trace(mqtt_client, trace_log);
+                result = 0;
+            }
+            BUFFER_delete(unsubPacket);
+        }
+        if (trace_log != NULL)
+        {
+            STRING_delete(trace_log);
+        }
+    }
+    return result;
+}
+
+int mqtt_client_disconnect(MQTT_CLIENT_HANDLE handle, ON_MQTT_DISCONNECTED_CALLBACK callback, void* ctx)
+{
+    int result;
+    MQTT_CLIENT* mqtt_client = (MQTT_CLIENT*)handle;
+    if (mqtt_client == NULL)
+    {
+        /*Codes_SRS_MQTT_CLIENT_07_010: [If the parameters handle is NULL then mqtt_client_disconnect shall return a non-zero value.]*/
+        result = MU_FAILURE;
+    }
+    else
+    {
+        if (mqtt_client->mqtt_status & MQTT_STATUS_CLIENT_CONNECTED)
+        {
+            BUFFER_HANDLE disconnectPacket = mqtt_codec_disconnect();
+            if (disconnectPacket == NULL)
+            {
+                /*Codes_SRS_MQTT_CLIENT_07_011: [If any failure is encountered then mqtt_client_disconnect shall return a non-zero value.]*/
+                LogError("Error: mqtt_client_disconnect failed");
+                mqtt_client->packetState = PACKET_TYPE_ERROR;
+                result = MU_FAILURE;
+            }
+            else
+            {
+                /* Codes_SRS_MQTT_CLIENT_07_037: [ if callback is not NULL callback shall be called once the mqtt connection has been disconnected ] */
+                mqtt_client->disconnect_cb = callback;
+                mqtt_client->disconnect_ctx = ctx;
+                mqtt_client->packetState = DISCONNECT_TYPE;
+
+                size_t size = BUFFER_length(disconnectPacket);
+                /*Codes_SRS_MQTT_CLIENT_07_012: [On success mqtt_client_disconnect shall send the MQTT DISCONNECT packet to the endpoint.]*/
+                if (sendPacketItem(mqtt_client, BUFFER_u_char(disconnectPacket), size) != 0)
+                {
+                    /*Codes_SRS_MQTT_CLIENT_07_011: [If any failure is encountered then mqtt_client_disconnect shall return a non-zero value.]*/
+                    LogError("Error: mqtt_client_disconnect send failed");
+                    result = MU_FAILURE;
+                }
+                else
+                {
+                    if (is_trace_enabled(mqtt_client))
+                    {
+                        STRING_HANDLE trace_log = STRING_construct("DISCONNECT");
+                        log_outgoing_trace(mqtt_client, trace_log);
+                        STRING_delete(trace_log);
+                    }
+                    result = 0;
+                }
+                BUFFER_delete(disconnectPacket);
+            }
+            clear_mqtt_options(mqtt_client);
+        }
+        else
+        {
+            // If the client is not connected then just close the underlying socket
+            mqtt_client->disconnect_cb = callback;
+            mqtt_client->disconnect_ctx = ctx;
+
+            close_connection(mqtt_client);
+            clear_mqtt_options(mqtt_client);
+            result = 0;
+        }
+    }
+    return result;
+}
+
+void mqtt_client_dowork(MQTT_CLIENT_HANDLE handle)
+{
+    MQTT_CLIENT* mqtt_client = (MQTT_CLIENT*)handle;
+    /*Codes_SRS_MQTT_CLIENT_18_001: [If the client is disconnected, mqtt_client_dowork shall do nothing.]*/
+    /*Codes_SRS_MQTT_CLIENT_07_023: [If the parameter handle is NULL then mqtt_client_dowork shall do nothing.]*/
+    if (mqtt_client != NULL && mqtt_client->xioHandle != NULL)
+    {
+        if (mqtt_client->mqtt_status & MQTT_STATUS_PENDING_CLOSE)
+        {
+            close_connection(mqtt_client);
+            // turn off pending close
+            mqtt_client->mqtt_status &= ~MQTT_STATUS_PENDING_CLOSE;
+        }
+        else
+        {
+            /*Codes_SRS_MQTT_CLIENT_07_024: [mqtt_client_dowork shall call the xio_dowork function to complete operations.]*/
+            xio_dowork(mqtt_client->xioHandle);
+
+            /*Codes_SRS_MQTT_CLIENT_07_025: [mqtt_client_dowork shall retrieve the the last packet send value and ...]*/
+            if (mqtt_client->mqtt_status & MQTT_STATUS_SOCKET_CONNECTED &&
+                mqtt_client->mqtt_status & MQTT_STATUS_CLIENT_CONNECTED &&
+                mqtt_client->keepAliveInterval > 0)
+            {
+                tickcounter_ms_t current_ms;
+                if (tickcounter_get_current_ms(mqtt_client->packetTickCntr, &current_ms) != 0)
+                {
+                    LogError("Error: tickcounter_get_current_ms failed");
+                }
+                else
+                {
+                    /* Codes_SRS_MQTT_CLIENT_07_035: [If the timeSincePing has expired past the maxPingRespTime then mqtt_client_dowork shall call the Error Callback function with the message MQTT_CLIENT_NO_PING_RESPONSE] */
+                    if (mqtt_client->timeSincePing > 0 && ((current_ms - mqtt_client->timeSincePing)/1000) > mqtt_client->maxPingRespTime)
+                    {
+                        // We haven't gotten a ping response in the alloted time
+                        set_error_callback(mqtt_client, MQTT_CLIENT_NO_PING_RESPONSE);
+                        mqtt_client->timeSincePing = 0;
+                        mqtt_client->packetSendTimeMs = 0;
+                        mqtt_client->packetState = UNKNOWN_TYPE;
+                    }
+                    else if (((current_ms - mqtt_client->packetSendTimeMs) / 1000) >= mqtt_client->keepAliveInterval)
+                    {
+                        /*Codes_SRS_MQTT_CLIENT_07_026: [if keepAliveInternal is > 0 and the send time is greater than the MQTT KeepAliveInterval then it shall construct an MQTT PINGREQ packet.]*/
+                        BUFFER_HANDLE pingPacket = mqtt_codec_ping();
+                        if (pingPacket != NULL)
+                        {
+                            size_t size = BUFFER_length(pingPacket);
+                            (void)sendPacketItem(mqtt_client, BUFFER_u_char(pingPacket), size);
+                            BUFFER_delete(pingPacket);
+                            (void)tickcounter_get_current_ms(mqtt_client->packetTickCntr, &mqtt_client->timeSincePing);
+
+                            if (is_trace_enabled(mqtt_client))
+                            {
+                                STRING_HANDLE trace_log = STRING_construct("PINGREQ");
+                                log_outgoing_trace(mqtt_client, trace_log);
+                                STRING_delete(trace_log);
+                            }
+                        }
+                    }
+                }
+            }
+        }
+    }
+}
+
+void mqtt_client_set_trace(MQTT_CLIENT_HANDLE handle, bool traceOn, bool rawBytesOn)
+{
+    AZURE_UNREFERENCED_PARAMETER(handle);
+    AZURE_UNREFERENCED_PARAMETER(traceOn);
+    AZURE_UNREFERENCED_PARAMETER(rawBytesOn);
+#ifndef NO_LOGGING
+    if (handle != NULL)
+    {
+        if (traceOn)
+        {
+            handle->mqtt_flags |= MQTT_FLAGS_LOG_TRACE;
+        }
+        else
+        {
+            handle->mqtt_flags &= ~MQTT_FLAGS_LOG_TRACE;
+        }
+#ifdef ENABLE_RAW_TRACE
+        if (rawBytesOn)
+        {
+            handle->mqtt_flags |= MQTT_FLAGS_RAW_TRACE;
+        }
+        else
+        {
+            handle->mqtt_flags &= ~MQTT_FLAGS_RAW_TRACE;
+        }
+#endif
+    }
+#endif
+}
Index: azure_iot_hub_f767zi/trunk/azure_iot_sdk/umqtt/src/mqtt_codec.c
===================================================================
--- azure_iot_hub_f767zi/trunk/azure_iot_sdk/umqtt/src/mqtt_codec.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/azure_iot_sdk/umqtt/src/mqtt_codec.c	(revision 457)
@@ -0,0 +1,1124 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+#include <stdlib.h>
+#include <limits.h>
+#include "azure_c_shared_utility/optimize_size.h"
+#include "azure_c_shared_utility/gballoc.h"
+#include "azure_c_shared_utility/buffer_.h"
+#include "azure_c_shared_utility/strings.h"
+#include "azure_macro_utils/macro_utils.h"
+#include "azure_c_shared_utility/xlogging.h"
+#include "azure_umqtt_c/mqtt_codec.h"
+#include <inttypes.h>
+
+#define PAYLOAD_OFFSET                      5
+#define PACKET_TYPE_BYTE(p)                 (CONTROL_PACKET_TYPE)((uint8_t)(((uint8_t)(p)) & 0xf0))
+#define FLAG_VALUE_BYTE(p)                  ((uint8_t)(((uint8_t)(p)) & 0xf))
+
+#define USERNAME_FLAG                       0x80
+#define PASSWORD_FLAG                       0x40
+#define WILL_RETAIN_FLAG                    0x20
+#define WILL_QOS_FLAG_                      0x18
+#define WILL_FLAG_FLAG                      0x04
+#define CLEAN_SESSION_FLAG                  0x02
+
+#define NEXT_128_CHUNK                      0x80
+#define PUBLISH_DUP_FLAG                    0x8
+#define PUBLISH_QOS_EXACTLY_ONCE            0x4
+#define PUBLISH_QOS_AT_LEAST_ONCE           0x2
+#define PUBLISH_QOS_RETAIN                  0x1
+
+#define PROTOCOL_NUMBER                     4
+#define CONN_FLAG_BYTE_OFFSET               7
+
+#define CONNECT_FIXED_HEADER_SIZE           2
+#define CONNECT_VARIABLE_HEADER_SIZE        10
+#define SUBSCRIBE_FIXED_HEADER_FLAG         0x2
+#define UNSUBSCRIBE_FIXED_HEADER_FLAG       0x2
+
+#define MAX_SEND_SIZE                       0xFFFFFF7F // 268435455
+
+// This captures the maximum packet size for 3 digits.
+// If it's above this value then we bail out of the loop
+#define MAX_3_DIGIT_PACKET_SIZE             2097152
+
+#define CODEC_STATE_VALUES      \
+    CODEC_STATE_FIXED_HEADER,   \
+    CODEC_STATE_VAR_HEADER,     \
+    CODEC_STATE_PAYLOAD
+
+static const char* const TRUE_CONST = "true";
+static const char* const FALSE_CONST = "false";
+
+MU_DEFINE_ENUM(CODEC_STATE_RESULT, CODEC_STATE_VALUES);
+
+typedef struct MQTTCODEC_INSTANCE_TAG
+{
+    CONTROL_PACKET_TYPE currPacket;
+    CODEC_STATE_RESULT codecState;
+    size_t bufferOffset;
+    int headerFlags;
+    BUFFER_HANDLE headerData;
+    ON_PACKET_COMPLETE_CALLBACK packetComplete;
+    void* callContext;
+    uint8_t storeRemainLen[4];
+    size_t remainLenIndex;
+} MQTTCODEC_INSTANCE;
+
+typedef struct PUBLISH_HEADER_INFO_TAG
+{
+    const char* topicName;
+    uint16_t packetId;
+    const char* msgBuffer;
+    QOS_VALUE qualityOfServiceValue;
+} PUBLISH_HEADER_INFO;
+
+static const char* retrieve_qos_value(QOS_VALUE value)
+{
+    switch (value)
+    {
+        case DELIVER_AT_MOST_ONCE:
+            return "DELIVER_AT_MOST_ONCE";
+        case DELIVER_AT_LEAST_ONCE:
+            return "DELIVER_AT_LEAST_ONCE";
+        case DELIVER_EXACTLY_ONCE:
+        default:
+            return "DELIVER_EXACTLY_ONCE";
+    }
+}
+
+static void byteutil_writeByte(uint8_t** buffer, uint8_t value)
+{
+    if (buffer != NULL)
+    {
+        **buffer = value;
+        (*buffer)++;
+    }
+}
+
+static void byteutil_writeInt(uint8_t** buffer, uint16_t value)
+{
+    if (buffer != NULL)
+    {
+        **buffer = (char)(value / 256);
+        (*buffer)++;
+        **buffer = (char)(value % 256);
+        (*buffer)++;
+    }
+}
+
+static void byteutil_writeUTF(uint8_t** buffer, const char* stringData, uint16_t len)
+{
+    if (buffer != NULL)
+    {
+        byteutil_writeInt(buffer, len);
+        (void)memcpy(*buffer, stringData, len);
+        *buffer += len;
+    }
+}
+
+static CONTROL_PACKET_TYPE processControlPacketType(uint8_t pktByte, int* flags)
+{
+    CONTROL_PACKET_TYPE result;
+    result = PACKET_TYPE_BYTE(pktByte);
+    if (flags != NULL)
+    {
+        *flags = FLAG_VALUE_BYTE(pktByte);
+    }
+    return result;
+}
+
+static int addListItemsToUnsubscribePacket(BUFFER_HANDLE ctrlPacket, const char** payloadList, size_t payloadCount, STRING_HANDLE trace_log)
+{
+    int result = 0;
+    size_t index = 0;
+    for (index = 0; index < payloadCount && result == 0; index++)
+    {
+        // Add the Payload
+        size_t offsetLen = BUFFER_length(ctrlPacket);
+        size_t topicLen = strlen(payloadList[index]);
+        if (topicLen > USHRT_MAX)
+        {
+            result = MU_FAILURE;
+        }
+        else if (BUFFER_enlarge(ctrlPacket, topicLen + 2) != 0)
+        {
+            result = MU_FAILURE;
+        }
+        else
+        {
+            uint8_t* iterator = BUFFER_u_char(ctrlPacket);
+            iterator += offsetLen;
+            byteutil_writeUTF(&iterator, payloadList[index], (uint16_t)topicLen);
+        }
+        if (trace_log != NULL)
+        {
+            STRING_sprintf(trace_log, " | TOPIC_NAME: %s", payloadList[index]);
+        }
+    }
+    return result;
+}
+
+static int addListItemsToSubscribePacket(BUFFER_HANDLE ctrlPacket, SUBSCRIBE_PAYLOAD* payloadList, size_t payloadCount, STRING_HANDLE trace_log)
+{
+    int result = 0;
+    size_t index = 0;
+    for (index = 0; index < payloadCount && result == 0; index++)
+    {
+        // Add the Payload
+        size_t offsetLen = BUFFER_length(ctrlPacket);
+        size_t topicLen = strlen(payloadList[index].subscribeTopic);
+        if (topicLen > USHRT_MAX)
+        {
+            result = MU_FAILURE;
+        }
+        else if (BUFFER_enlarge(ctrlPacket, topicLen + 2 + 1) != 0)
+        {
+            result = MU_FAILURE;
+        }
+        else
+        {
+            uint8_t* iterator = BUFFER_u_char(ctrlPacket);
+            iterator += offsetLen;
+            byteutil_writeUTF(&iterator, payloadList[index].subscribeTopic, (uint16_t)topicLen);
+            *iterator = payloadList[index].qosReturn;
+
+            if (trace_log != NULL)
+            {
+                STRING_sprintf(trace_log, " | TOPIC_NAME: %s | QOS: %d", payloadList[index].subscribeTopic, (int)payloadList[index].qosReturn);
+            }
+        }
+    }
+    return result;
+}
+
+static int constructConnectVariableHeader(BUFFER_HANDLE ctrlPacket, const MQTT_CLIENT_OPTIONS* mqttOptions, STRING_HANDLE trace_log)
+{
+    int result = 0;
+    if (BUFFER_enlarge(ctrlPacket, CONNECT_VARIABLE_HEADER_SIZE) != 0)
+    {
+        result = MU_FAILURE;
+    }
+    else
+    {
+        uint8_t* iterator = BUFFER_u_char(ctrlPacket);
+        if (iterator == NULL)
+        {
+            result = MU_FAILURE;
+        }
+        else
+        {
+            if (trace_log != NULL)
+            {
+                STRING_sprintf(trace_log, " | VER: %d | KEEPALIVE: %d | FLAGS:", PROTOCOL_NUMBER, mqttOptions->keepAliveInterval);
+            }
+            byteutil_writeUTF(&iterator, "MQTT", 4);
+            byteutil_writeByte(&iterator, PROTOCOL_NUMBER);
+            byteutil_writeByte(&iterator, 0); // Flags will be entered later
+            byteutil_writeInt(&iterator, mqttOptions->keepAliveInterval);
+            result = 0;
+        }
+    }
+    return result;
+}
+
+static int constructPublishVariableHeader(BUFFER_HANDLE ctrlPacket, const PUBLISH_HEADER_INFO* publishHeader, STRING_HANDLE trace_log)
+{
+    int result = 0;
+    size_t topicLen = 0;
+    size_t spaceLen = 0;
+    size_t idLen = 0;
+
+    size_t currLen = BUFFER_length(ctrlPacket);
+
+    topicLen = strlen(publishHeader->topicName);
+    spaceLen += 2;
+
+    if (publishHeader->qualityOfServiceValue != DELIVER_AT_MOST_ONCE)
+    {
+        // Packet Id is only set if the QOS is not 0
+        idLen = 2;
+    }
+
+    if (topicLen > USHRT_MAX)
+    {
+        result = MU_FAILURE;
+    }
+    else if (BUFFER_enlarge(ctrlPacket, topicLen + idLen + spaceLen) != 0)
+    {
+        result = MU_FAILURE;
+    }
+    else
+    {
+        uint8_t* iterator = BUFFER_u_char(ctrlPacket);
+        if (iterator == NULL)
+        {
+            result = MU_FAILURE;
+        }
+        else
+        {
+            iterator += currLen;
+            /* The Topic Name MUST be present as the first field in the PUBLISH Packet Variable header.It MUST be 792 a UTF-8 encoded string [MQTT-3.3.2-1] as defined in section 1.5.3.*/
+            byteutil_writeUTF(&iterator, publishHeader->topicName, (uint16_t)topicLen);
+            if (trace_log != NULL)
+            {
+                STRING_sprintf(trace_log, " | TOPIC_NAME: %s", publishHeader->topicName);
+            }
+            if (idLen > 0)
+            {
+                if (trace_log != NULL)
+                {
+                    STRING_sprintf(trace_log, " | PACKET_ID: %"PRIu16, publishHeader->packetId);
+                }
+                byteutil_writeInt(&iterator, publishHeader->packetId);
+            }
+            result = 0;
+        }
+    }
+    return result;
+}
+
+static int constructSubscibeTypeVariableHeader(BUFFER_HANDLE ctrlPacket, uint16_t packetId)
+{
+    int result = 0;
+    if (BUFFER_enlarge(ctrlPacket, 2) != 0)
+    {
+        result = MU_FAILURE;
+    }
+    else
+    {
+        uint8_t* iterator = BUFFER_u_char(ctrlPacket);
+        if (iterator == NULL)
+        {
+            result = MU_FAILURE;
+        }
+        else
+        {
+            byteutil_writeInt(&iterator, packetId);
+            result = 0;
+        }
+    }
+    return result;
+}
+
+static BUFFER_HANDLE constructPublishReply(CONTROL_PACKET_TYPE type, uint8_t flags, uint16_t packetId)
+{
+    BUFFER_HANDLE result = BUFFER_new();
+    if (result != NULL)
+    {
+        if (BUFFER_pre_build(result, 4) != 0)
+        {
+            BUFFER_delete(result);
+            result = NULL;
+        }
+        else
+        {
+            uint8_t* iterator = BUFFER_u_char(result);
+            if (iterator == NULL)
+            {
+                BUFFER_delete(result);
+                result = NULL;
+            }
+            else
+            {
+                *iterator = (uint8_t)type | flags;
+                iterator++;
+                *iterator = 0x2;
+                iterator++;
+                byteutil_writeInt(&iterator, packetId);
+            }
+        }
+    }
+    return result;
+}
+
+static int constructFixedHeader(BUFFER_HANDLE ctrlPacket, CONTROL_PACKET_TYPE packetType, uint8_t flags)
+{
+    int result;
+    size_t packetLen = BUFFER_length(ctrlPacket);
+    uint8_t remainSize[4] ={ 0 };
+    size_t index = 0;
+
+    // Calculate the length of packet
+    do
+    {
+        uint8_t encode = packetLen % 128;
+        packetLen /= 128;
+        // if there are more data to encode, set the top bit of this byte
+        if (packetLen > 0)
+        {
+            encode |= NEXT_128_CHUNK;
+        }
+        remainSize[index++] = encode;
+    } while (packetLen > 0);
+
+    BUFFER_HANDLE fixedHeader = BUFFER_new();
+    if (fixedHeader == NULL)
+    {
+        result = MU_FAILURE;
+    }
+    else if (BUFFER_pre_build(fixedHeader, index + 1) != 0)
+    {
+        BUFFER_delete(fixedHeader);
+        result = MU_FAILURE;
+    }
+    else
+    {
+        uint8_t* iterator = BUFFER_u_char(fixedHeader);
+        *iterator = (uint8_t)packetType | flags;
+        iterator++;
+        (void)memcpy(iterator, remainSize, index);
+
+        result = BUFFER_prepend(ctrlPacket, fixedHeader);
+        BUFFER_delete(fixedHeader);
+    }
+    return result;
+}
+
+static int constructConnPayload(BUFFER_HANDLE ctrlPacket, const MQTT_CLIENT_OPTIONS* mqttOptions, STRING_HANDLE trace_log)
+{
+    int result = 0;
+    size_t clientLen = 0;
+    size_t usernameLen = 0;
+    size_t passwordLen = 0;
+    size_t willMessageLen = 0;
+    size_t willTopicLen = 0;
+    size_t spaceLen = 0;
+    size_t currLen = 0;
+    size_t totalLen = 0;
+
+    if (mqttOptions->clientId != NULL)
+    {
+        spaceLen += 2;
+        clientLen = strlen(mqttOptions->clientId);
+    }
+    if (mqttOptions->username != NULL)
+    {
+        spaceLen += 2;
+        usernameLen = strlen(mqttOptions->username);
+    }
+    if (mqttOptions->password != NULL)
+    {
+        spaceLen += 2;
+        passwordLen = strlen(mqttOptions->password);
+    }
+    if (mqttOptions->willMessage != NULL)
+    {
+        spaceLen += 2;
+        willMessageLen = strlen(mqttOptions->willMessage);
+    }
+    if (mqttOptions->willTopic != NULL)
+    {
+        spaceLen += 2;
+        willTopicLen = strlen(mqttOptions->willTopic);
+    }
+
+    currLen = BUFFER_length(ctrlPacket);
+    totalLen = clientLen + usernameLen + passwordLen + willMessageLen + willTopicLen + spaceLen;
+
+    // Validate the Username & Password
+    if (clientLen > USHRT_MAX)
+    {
+        result = MU_FAILURE;
+    }
+    else if (usernameLen == 0 && passwordLen > 0)
+    {
+        result = MU_FAILURE;
+    }
+    else if ((willMessageLen > 0 && willTopicLen == 0) || (willTopicLen > 0 && willMessageLen == 0))
+    {
+        result = MU_FAILURE;
+    }
+    else if (BUFFER_enlarge(ctrlPacket, totalLen) != 0)
+    {
+        result = MU_FAILURE;
+    }
+    else
+    {
+        uint8_t* packet = BUFFER_u_char(ctrlPacket);
+        uint8_t* iterator = packet;
+
+        iterator += currLen;
+        byteutil_writeUTF(&iterator, mqttOptions->clientId, (uint16_t)clientLen);
+
+        // TODO: Read on the Will Topic
+        if (willMessageLen > USHRT_MAX || willTopicLen > USHRT_MAX || usernameLen > USHRT_MAX || passwordLen > USHRT_MAX)
+        {
+            result = MU_FAILURE;
+        }
+        else
+        {
+            STRING_HANDLE connect_payload_trace = NULL;
+            if (trace_log != NULL)
+            {
+                connect_payload_trace = STRING_new();
+            }
+            if (willMessageLen > 0 && willTopicLen > 0)
+            {
+                if (trace_log != NULL)
+                {
+                    (void)STRING_sprintf(connect_payload_trace, " | WILL_TOPIC: %s", mqttOptions->willTopic);
+                }
+                packet[CONN_FLAG_BYTE_OFFSET] |= WILL_FLAG_FLAG;
+                byteutil_writeUTF(&iterator, mqttOptions->willTopic, (uint16_t)willTopicLen);
+                packet[CONN_FLAG_BYTE_OFFSET] |= (mqttOptions->qualityOfServiceValue << 3);
+                if (mqttOptions->messageRetain)
+                {
+                    packet[CONN_FLAG_BYTE_OFFSET] |= WILL_RETAIN_FLAG;
+                }
+                byteutil_writeUTF(&iterator, mqttOptions->willMessage, (uint16_t)willMessageLen);
+            }
+            if (usernameLen > 0)
+            {
+                packet[CONN_FLAG_BYTE_OFFSET] |= USERNAME_FLAG;
+                byteutil_writeUTF(&iterator, mqttOptions->username, (uint16_t)usernameLen);
+                if (trace_log != NULL)
+                {
+                    (void)STRING_sprintf(connect_payload_trace, " | USERNAME: %s", mqttOptions->username);
+                }
+            }
+            if (passwordLen > 0)
+            {
+                packet[CONN_FLAG_BYTE_OFFSET] |= PASSWORD_FLAG;
+                byteutil_writeUTF(&iterator, mqttOptions->password, (uint16_t)passwordLen);
+                if (trace_log != NULL)
+                {
+                    (void)STRING_sprintf(connect_payload_trace, " | PWD: XXXX");
+                }
+            }
+            // TODO: Get the rest of the flags
+            if (trace_log != NULL)
+            {
+                (void)STRING_sprintf(connect_payload_trace, " | CLEAN: %s", mqttOptions->useCleanSession ? "1" : "0");
+            }
+            if (mqttOptions->useCleanSession)
+            {
+                packet[CONN_FLAG_BYTE_OFFSET] |= CLEAN_SESSION_FLAG;
+            }
+            if (trace_log != NULL)
+            {
+                (void)STRING_sprintf(trace_log, " %lu", packet[CONN_FLAG_BYTE_OFFSET]);
+                (void)STRING_concat_with_STRING(trace_log, connect_payload_trace);
+                STRING_delete(connect_payload_trace);
+            }
+            result = 0;
+        }
+    }
+    return result;
+}
+
+static int prepareheaderDataInfo(MQTTCODEC_INSTANCE* codecData, uint8_t remainLen)
+{
+    int result;
+    result = 0;
+    codecData->storeRemainLen[codecData->remainLenIndex++] = remainLen;
+    if (remainLen <= 0x7f)
+    {
+        int multiplier = 1;
+        int totalLen = 0;
+        size_t index = 0;
+        uint8_t encodeByte = 0;
+        do
+        {
+            encodeByte = codecData->storeRemainLen[index++];
+            totalLen += (encodeByte & 127) * multiplier;
+            multiplier *= NEXT_128_CHUNK;
+
+            if (multiplier > MAX_3_DIGIT_PACKET_SIZE)
+            {
+                result = MU_FAILURE;
+                break;
+            }
+        } while ((encodeByte & NEXT_128_CHUNK) != 0);
+
+        if (result != 0 || totalLen > MAX_SEND_SIZE)
+        {
+            LogError("Receive buffer too large for MQTT packet");
+            result = MU_FAILURE;
+        }
+        else
+        {
+            codecData->codecState = CODEC_STATE_VAR_HEADER;
+
+            // Reset remainLen Index
+            codecData->remainLenIndex = 0;
+            memset(codecData->storeRemainLen, 0, 4 * sizeof(uint8_t));
+
+            if (totalLen > 0)
+            {
+                codecData->bufferOffset = 0;
+                codecData->headerData = BUFFER_new();
+                if (codecData->headerData == NULL)
+                {
+                    /* Codes_SRS_MQTT_CODEC_07_035: [ If any error is encountered then the packet state will be marked as error and mqtt_codec_bytesReceived shall return a non-zero value. ] */
+                    LogError("Failed BUFFER_new");
+                    result = MU_FAILURE;
+                }
+                else
+                {
+                    if (BUFFER_pre_build(codecData->headerData, totalLen) != 0)
+                    {
+                        /* Codes_SRS_MQTT_CODEC_07_035: [ If any error is encountered then the packet state will be marked as error and mqtt_codec_bytesReceived shall return a non-zero value. ] */
+                        LogError("Failed BUFFER_pre_build");
+                        result = MU_FAILURE;
+                    }
+
+                }
+            }
+        }
+    }
+    return result;
+}
+
+static void completePacketData(MQTTCODEC_INSTANCE* codecData)
+{
+    if (codecData->packetComplete != NULL)
+    {
+        codecData->packetComplete(codecData->callContext, codecData->currPacket, codecData->headerFlags, codecData->headerData);
+    }
+
+    // Clean up data
+    codecData->currPacket = UNKNOWN_TYPE;
+    codecData->codecState = CODEC_STATE_FIXED_HEADER;
+    codecData->headerFlags = 0;
+    BUFFER_delete(codecData->headerData);
+    codecData->headerData = NULL;
+}
+
+static void clear_codec_data(MQTTCODEC_INSTANCE* codec_data)
+{
+    // Clear the code instance data
+    codec_data->currPacket = UNKNOWN_TYPE;
+    codec_data->codecState = CODEC_STATE_FIXED_HEADER;
+    codec_data->headerFlags = 0;
+    codec_data->bufferOffset = 0;
+    codec_data->headerData = NULL;
+    memset(codec_data->storeRemainLen, 0, 4 * sizeof(uint8_t));
+    codec_data->remainLenIndex = 0;
+}
+
+void mqtt_codec_reset(MQTTCODEC_HANDLE handle)
+{
+    if (handle != NULL)
+    {
+        clear_codec_data(handle);
+    }
+}
+
+MQTTCODEC_HANDLE mqtt_codec_create(ON_PACKET_COMPLETE_CALLBACK packetComplete, void* callbackCtx)
+{
+    MQTTCODEC_HANDLE result;
+    result = malloc(sizeof(MQTTCODEC_INSTANCE));
+    /* Codes_SRS_MQTT_CODEC_07_001: [If a failure is encountered then mqtt_codec_create shall return NULL.] */
+    if (result != NULL)
+    {
+        /* Codes_SRS_MQTT_CODEC_07_002: [On success mqtt_codec_create shall return a MQTTCODEC_HANDLE value.] */
+        clear_codec_data(result);
+        result->packetComplete = packetComplete;
+        result->callContext = callbackCtx;
+    }
+    return result;
+}
+
+void mqtt_codec_destroy(MQTTCODEC_HANDLE handle)
+{
+    /* Codes_SRS_MQTT_CODEC_07_003: [If the handle parameter is NULL then mqtt_codec_destroy shall do nothing.] */
+    if (handle != NULL)
+    {
+        MQTTCODEC_INSTANCE* codecData = (MQTTCODEC_INSTANCE*)handle;
+        /* Codes_SRS_MQTT_CODEC_07_004: [mqtt_codec_destroy shall deallocate all memory that has been allocated by this object.] */
+        BUFFER_delete(codecData->headerData);
+        free(codecData);
+    }
+}
+
+BUFFER_HANDLE mqtt_codec_connect(const MQTT_CLIENT_OPTIONS* mqttOptions, STRING_HANDLE trace_log)
+{
+    BUFFER_HANDLE result;
+    /* Codes_SRS_MQTT_CODEC_07_008: [If the parameters mqttOptions is NULL then mqtt_codec_connect shall return a null value.] */
+    if (mqttOptions == NULL)
+    {
+        result = NULL;
+    }
+    else
+    {
+        /* Codes_SRS_MQTT_CODEC_07_009: [mqtt_codec_connect shall construct a BUFFER_HANDLE that represents a MQTT CONNECT packet.] */
+        result = BUFFER_new();
+        if (result != NULL)
+        {
+            STRING_HANDLE varible_header_log = NULL;
+            if (trace_log != NULL)
+            {
+                varible_header_log = STRING_new();
+            }
+            // Add Variable Header Information
+            if (constructConnectVariableHeader(result, mqttOptions, varible_header_log) != 0)
+            {
+                /* Codes_SRS_MQTT_CODEC_07_010: [If any error is encountered then mqtt_codec_connect shall return NULL.] */
+                BUFFER_delete(result);
+                result = NULL;
+            }
+            else
+            {
+                if (constructConnPayload(result, mqttOptions, varible_header_log) != 0)
+                {
+                    /* Codes_SRS_MQTT_CODEC_07_010: [If any error is encountered then mqtt_codec_connect shall return NULL.] */
+                    BUFFER_delete(result);
+                    result = NULL;
+                }
+                else
+                {
+                    if (trace_log != NULL)
+                    {
+                        (void)STRING_copy(trace_log, "CONNECT");
+                    }
+                    if (constructFixedHeader(result, CONNECT_TYPE, 0) != 0)
+                    {
+                        /* Codes_SRS_MQTT_CODEC_07_010: [If any error is encountered then mqtt_codec_connect shall return NULL.] */
+                        BUFFER_delete(result);
+                        result = NULL;
+                    }
+                    else
+                    {
+                        if (trace_log != NULL)
+                        {
+                            (void)STRING_concat_with_STRING(trace_log, varible_header_log);
+                        }
+                    }
+                }
+                if (varible_header_log != NULL)
+                {
+                    STRING_delete(varible_header_log);
+                }
+            }
+        }
+    }
+    return result;
+}
+
+BUFFER_HANDLE mqtt_codec_disconnect()
+{
+    /* Codes_SRS_MQTT_CODEC_07_011: [On success mqtt_codec_disconnect shall construct a BUFFER_HANDLE that represents a MQTT DISCONNECT packet.] */
+    BUFFER_HANDLE result = BUFFER_new();
+    if (result != NULL)
+    {
+        if (BUFFER_enlarge(result, 2) != 0)
+        {
+            /* Codes_SRS_MQTT_CODEC_07_012: [If any error is encountered mqtt_codec_disconnect shall return NULL.] */
+            BUFFER_delete(result);
+            result = NULL;
+        }
+        else
+        {
+            uint8_t* iterator = BUFFER_u_char(result);
+            if (iterator == NULL)
+            {
+                /* Codes_SRS_MQTT_CODEC_07_012: [If any error is encountered mqtt_codec_disconnect shall return NULL.] */
+                BUFFER_delete(result);
+                result = NULL;
+            }
+            else
+            {
+                iterator[0] = DISCONNECT_TYPE;
+                iterator[1] = 0;
+            }
+        }
+    }
+    return result;
+}
+
+BUFFER_HANDLE mqtt_codec_publish(QOS_VALUE qosValue, bool duplicateMsg, bool serverRetain, uint16_t packetId, const char* topicName, const uint8_t* msgBuffer, size_t buffLen, STRING_HANDLE trace_log)
+{
+    BUFFER_HANDLE result;
+    /* Codes_SRS_MQTT_CODEC_07_005: [If the parameters topicName is NULL then mqtt_codec_publish shall return NULL.] */
+    if (topicName == NULL)
+    {
+        result = NULL;
+    }
+    /* Codes_SRS_MQTT_CODEC_07_036: [mqtt_codec_publish shall return NULL if the buffLen variable is greater than the MAX_SEND_SIZE (0xFFFFFF7F).] */
+    else if (buffLen > MAX_SEND_SIZE)
+    {
+        /* Codes_SRS_MQTT_CODEC_07_006: [If any error is encountered then mqtt_codec_publish shall return NULL.] */
+        result = NULL;
+    }
+    else
+    {
+        PUBLISH_HEADER_INFO publishInfo ={ 0 };
+        publishInfo.topicName = topicName;
+        publishInfo.packetId = packetId;
+        publishInfo.qualityOfServiceValue = qosValue;
+
+        uint8_t headerFlags = 0;
+        if (duplicateMsg) headerFlags |= PUBLISH_DUP_FLAG;
+        if (serverRetain) headerFlags |= PUBLISH_QOS_RETAIN;
+        if (qosValue != DELIVER_AT_MOST_ONCE)
+        {
+            if (qosValue == DELIVER_AT_LEAST_ONCE)
+            {
+                headerFlags |= PUBLISH_QOS_AT_LEAST_ONCE;
+            }
+            else
+            {
+                headerFlags |= PUBLISH_QOS_EXACTLY_ONCE;
+            }
+        }
+
+        /* Codes_SRS_MQTT_CODEC_07_007: [mqtt_codec_publish shall return a BUFFER_HANDLE that represents a MQTT PUBLISH message.] */
+        result = BUFFER_new();
+        if (result != NULL)
+        {
+            STRING_HANDLE varible_header_log = NULL;
+            if (trace_log != NULL)
+            {
+                varible_header_log = STRING_construct_sprintf(" | IS_DUP: %s | RETAIN: %d | QOS: %s", duplicateMsg ? TRUE_CONST : FALSE_CONST,
+                    serverRetain ? 1 : 0,
+                    retrieve_qos_value(publishInfo.qualityOfServiceValue) );
+            }
+
+            if (constructPublishVariableHeader(result, &publishInfo, varible_header_log) != 0)
+            {
+                /* Codes_SRS_MQTT_CODEC_07_006: [If any error is encountered then mqtt_codec_publish shall return NULL.] */
+                BUFFER_delete(result);
+                result = NULL;
+            }
+            else
+            {
+                size_t payloadOffset = BUFFER_length(result);
+                if (buffLen > 0)
+                {
+                    if (BUFFER_enlarge(result, buffLen) != 0)
+                    {
+                        /* Codes_SRS_MQTT_CODEC_07_006: [If any error is encountered then mqtt_codec_publish shall return NULL.] */
+                        BUFFER_delete(result);
+                        result = NULL;
+                    }
+                    else
+                    {
+                        uint8_t* iterator = BUFFER_u_char(result);
+                        if (iterator == NULL)
+                        {
+                            /* Codes_SRS_MQTT_CODEC_07_006: [If any error is encountered then mqtt_codec_publish shall return NULL.] */
+                            BUFFER_delete(result);
+                            result = NULL;
+                        }
+                        else
+                        {
+                            iterator += payloadOffset;
+                            // Write Message
+                            (void)memcpy(iterator, msgBuffer, buffLen);
+                            if (trace_log)
+                            {
+                                STRING_sprintf(varible_header_log, " | PAYLOAD_LEN: %lu", (unsigned long)buffLen);
+                            }
+                        }
+                    }
+                }
+
+                if (result != NULL)
+                {
+                    if (trace_log != NULL)
+                    {
+                        (void)STRING_copy(trace_log, "PUBLISH");
+                    }
+                    if (constructFixedHeader(result, PUBLISH_TYPE, headerFlags) != 0)
+                    {
+                        /* Codes_SRS_MQTT_CODEC_07_006: [If any error is encountered then mqtt_codec_publish shall return NULL.] */
+                        BUFFER_delete(result);
+                        result = NULL;
+                    }
+                    else
+                    {
+                        if (trace_log != NULL)
+                        {
+                            (void)STRING_concat_with_STRING(trace_log, varible_header_log);
+                        }
+                    }
+                }
+            }
+            if (varible_header_log != NULL)
+            {
+                STRING_delete(varible_header_log);
+            }
+        }
+    }
+    return result;
+}
+
+BUFFER_HANDLE mqtt_codec_publishAck(uint16_t packetId)
+{
+    /* Codes_SRS_MQTT_CODEC_07_013: [On success mqtt_codec_publishAck shall return a BUFFER_HANDLE representation of a MQTT PUBACK packet.] */
+    /* Codes_SRS_MQTT_CODEC_07_014 : [If any error is encountered then mqtt_codec_publishAck shall return NULL.] */
+    BUFFER_HANDLE result = constructPublishReply(PUBACK_TYPE, 0, packetId);
+    return result;
+}
+
+BUFFER_HANDLE mqtt_codec_publishReceived(uint16_t packetId)
+{
+    /* Codes_SRS_MQTT_CODEC_07_015: [On success mqtt_codec_publishRecieved shall return a BUFFER_HANDLE representation of a MQTT PUBREC packet.] */
+    /* Codes_SRS_MQTT_CODEC_07_016 : [If any error is encountered then mqtt_codec_publishRecieved shall return NULL.] */
+    BUFFER_HANDLE result = constructPublishReply(PUBREC_TYPE, 0, packetId);
+    return result;
+}
+
+BUFFER_HANDLE mqtt_codec_publishRelease(uint16_t packetId)
+{
+    /* Codes_SRS_MQTT_CODEC_07_017: [On success mqtt_codec_publishRelease shall return a BUFFER_HANDLE representation of a MQTT PUBREL packet.] */
+    /* Codes_SRS_MQTT_CODEC_07_018 : [If any error is encountered then mqtt_codec_publishRelease shall return NULL.] */
+    BUFFER_HANDLE result = constructPublishReply(PUBREL_TYPE, 2, packetId);
+    return result;
+}
+
+BUFFER_HANDLE mqtt_codec_publishComplete(uint16_t packetId)
+{
+    /* Codes_SRS_MQTT_CODEC_07_019: [On success mqtt_codec_publishComplete shall return a BUFFER_HANDLE representation of a MQTT PUBCOMP packet.] */
+    /* Codes_SRS_MQTT_CODEC_07_020 : [If any error is encountered then mqtt_codec_publishComplete shall return NULL.] */
+    BUFFER_HANDLE result = constructPublishReply(PUBCOMP_TYPE, 0, packetId);
+    return result;
+}
+
+BUFFER_HANDLE mqtt_codec_ping()
+{
+    /* Codes_SRS_MQTT_CODEC_07_021: [On success mqtt_codec_ping shall construct a BUFFER_HANDLE that represents a MQTT PINGREQ packet.] */
+    BUFFER_HANDLE result = BUFFER_new();
+    if (result != NULL)
+    {
+        if (BUFFER_enlarge(result, 2) != 0)
+        {
+            /* Codes_SRS_MQTT_CODEC_07_022: [If any error is encountered mqtt_codec_ping shall return NULL.] */
+            BUFFER_delete(result);
+            result = NULL;
+        }
+        else
+        {
+            uint8_t* iterator = BUFFER_u_char(result);
+            if (iterator == NULL)
+            {
+                /* Codes_SRS_MQTT_CODEC_07_022: [If any error is encountered mqtt_codec_ping shall return NULL.] */
+                BUFFER_delete(result);
+                result = NULL;
+            }
+            else
+            {
+                iterator[0] = PINGREQ_TYPE;
+                iterator[1] = 0;
+            }
+        }
+    }
+    return result;
+}
+
+BUFFER_HANDLE mqtt_codec_subscribe(uint16_t packetId, SUBSCRIBE_PAYLOAD* subscribeList, size_t count, STRING_HANDLE trace_log)
+{
+    BUFFER_HANDLE result;
+    /* Codes_SRS_MQTT_CODEC_07_023: [If the parameters subscribeList is NULL or if count is 0 then mqtt_codec_subscribe shall return NULL.] */
+    if (subscribeList == NULL || count == 0)
+    {
+        result = NULL;
+    }
+    else
+    {
+        /* Codes_SRS_MQTT_CODEC_07_026: [mqtt_codec_subscribe shall return a BUFFER_HANDLE that represents a MQTT SUBSCRIBE message.]*/
+        result = BUFFER_new();
+        if (result != NULL)
+        {
+            if (constructSubscibeTypeVariableHeader(result, packetId) != 0)
+            {
+                /* Codes_SRS_MQTT_CODEC_07_025: [If any error is encountered then mqtt_codec_subscribe shall return NULL.] */
+                BUFFER_delete(result);
+                result = NULL;
+            }
+            else
+            {
+                STRING_HANDLE sub_trace = NULL;
+                if (trace_log != NULL)
+                {
+                    sub_trace = STRING_construct_sprintf(" | PACKET_ID: %"PRIu16, packetId);
+                }
+                /* Codes_SRS_MQTT_CODEC_07_024: [mqtt_codec_subscribe shall iterate through count items in the subscribeList.] */
+                if (addListItemsToSubscribePacket(result, subscribeList, count, sub_trace) != 0)
+                {
+                    /* Codes_SRS_MQTT_CODEC_07_025: [If any error is encountered then mqtt_codec_subscribe shall return NULL.] */
+                    BUFFER_delete(result);
+                    result = NULL;
+                }
+                else
+                {
+
+                    if (trace_log != NULL)
+                    {
+                        STRING_concat(trace_log, "SUBSCRIBE");
+                    }
+                    if (constructFixedHeader(result, SUBSCRIBE_TYPE, SUBSCRIBE_FIXED_HEADER_FLAG) != 0)
+                    {
+                        /* Codes_SRS_MQTT_CODEC_07_025: [If any error is encountered then mqtt_codec_subscribe shall return NULL.] */
+                        BUFFER_delete(result);
+                        result = NULL;
+                    }
+                    else
+                    {
+                        if (trace_log != NULL)
+                        {
+                            (void)STRING_concat_with_STRING(trace_log, sub_trace);
+                        }
+                    }
+                }
+                if (sub_trace != NULL)
+                {
+                    STRING_delete(sub_trace);
+                }
+            }
+        }
+    }
+    return result;
+}
+
+BUFFER_HANDLE mqtt_codec_unsubscribe(uint16_t packetId, const char** unsubscribeList, size_t count, STRING_HANDLE trace_log)
+{
+    BUFFER_HANDLE result;
+    /* Codes_SRS_MQTT_CODEC_07_027: [If the parameters unsubscribeList is NULL or if count is 0 then mqtt_codec_unsubscribe shall return NULL.] */
+    if (unsubscribeList == NULL || count == 0)
+    {
+        result = NULL;
+    }
+    else
+    {
+        /* Codes_SRS_MQTT_CODEC_07_030: [mqtt_codec_unsubscribe shall return a BUFFER_HANDLE that represents a MQTT SUBSCRIBE message.] */
+        result = BUFFER_new();
+        if (result != NULL)
+        {
+            if (constructSubscibeTypeVariableHeader(result, packetId) != 0)
+            {
+                /* Codes_SRS_MQTT_CODEC_07_029: [If any error is encountered then mqtt_codec_unsubscribe shall return NULL.] */
+                BUFFER_delete(result);
+                result = NULL;
+            }
+            else
+            {
+                STRING_HANDLE unsub_trace = NULL;
+                if (trace_log != NULL)
+                {
+                    unsub_trace = STRING_construct_sprintf(" | PACKET_ID: %"PRIu16, packetId);
+                }
+                /* Codes_SRS_MQTT_CODEC_07_028: [mqtt_codec_unsubscribe shall iterate through count items in the unsubscribeList.] */
+                if (addListItemsToUnsubscribePacket(result, unsubscribeList, count, unsub_trace) != 0)
+                {
+                    /* Codes_SRS_MQTT_CODEC_07_029: [If any error is encountered then mqtt_codec_unsubscribe shall return NULL.] */
+                    BUFFER_delete(result);
+                    result = NULL;
+                }
+                else
+                {
+                    if (trace_log != NULL)
+                    {
+                        (void)STRING_copy(trace_log, "UNSUBSCRIBE");
+                    }
+                    if (constructFixedHeader(result, UNSUBSCRIBE_TYPE, UNSUBSCRIBE_FIXED_HEADER_FLAG) != 0)
+                    {
+                        /* Codes_SRS_MQTT_CODEC_07_029: [If any error is encountered then mqtt_codec_unsubscribe shall return NULL.] */
+                        BUFFER_delete(result);
+                        result = NULL;
+                    }
+                    else
+                    {
+                        if (trace_log != NULL)
+                        {
+                            (void)STRING_concat_with_STRING(trace_log, unsub_trace);
+                        }
+                    }
+                }
+                if (unsub_trace != NULL)
+                {
+                    STRING_delete(unsub_trace);
+                }
+            }
+        }
+    }
+    return result;
+}
+
+int mqtt_codec_bytesReceived(MQTTCODEC_HANDLE handle, const unsigned char* buffer, size_t size)
+{
+    int result;
+    MQTTCODEC_INSTANCE* codec_Data = (MQTTCODEC_INSTANCE*)handle;
+    /* Codes_SRS_MQTT_CODEC_07_031: [If the parameters handle or buffer is NULL then mqtt_codec_bytesReceived shall return a non-zero value.] */
+    if (codec_Data == NULL)
+    {
+        result = MU_FAILURE;
+    }
+    /* Codes_SRS_MQTT_CODEC_07_031: [If the parameters handle or buffer is NULL then mqtt_codec_bytesReceived shall return a non-zero value.] */
+    /* Codes_SRS_MQTT_CODEC_07_032: [If the parameters size is zero then mqtt_codec_bytesReceived shall return a non-zero value.] */
+    else if (buffer == NULL || size == 0)
+    {
+        codec_Data->currPacket = PACKET_TYPE_ERROR;
+        result = MU_FAILURE;
+    }
+    else
+    {
+        /* Codes_SRS_MQTT_CODEC_07_033: [mqtt_codec_bytesReceived constructs a sequence of bytes into the corresponding MQTT packets and on success returns zero.] */
+        result = 0;
+        size_t index = 0;
+        for (index = 0; index < size && result == 0; index++)
+        {
+            uint8_t iterator = ((int8_t*)buffer)[index];
+            if (codec_Data->codecState == CODEC_STATE_FIXED_HEADER)
+            {
+                if (codec_Data->currPacket == UNKNOWN_TYPE)
+                {
+                    codec_Data->currPacket = processControlPacketType(iterator, &codec_Data->headerFlags);
+                }
+                else
+                {
+                    if (prepareheaderDataInfo(codec_Data, iterator) != 0)
+                    {
+                        /* Codes_SRS_MQTT_CODEC_07_035: [If any error is encountered then the packet state will be marked as error and mqtt_codec_bytesReceived shall return a non-zero value.] */
+                        codec_Data->currPacket = PACKET_TYPE_ERROR;
+                        result = MU_FAILURE;
+                    }
+                    else if (codec_Data->currPacket == PINGRESP_TYPE)
+                    {
+                        /* Codes_SRS_MQTT_CODEC_07_034: [Upon a constructing a complete MQTT packet mqtt_codec_bytesReceived shall call the ON_PACKET_COMPLETE_CALLBACK function.] */
+                        completePacketData(codec_Data);
+                    }
+                }
+            }
+            else if (codec_Data->codecState == CODEC_STATE_VAR_HEADER)
+            {
+                if (codec_Data->headerData == NULL)
+                {
+                    codec_Data->codecState = CODEC_STATE_PAYLOAD;
+                }
+                else
+                {
+                    uint8_t* dataBytes = BUFFER_u_char(codec_Data->headerData);
+                    if (dataBytes == NULL)
+                    {
+                        /* Codes_SRS_MQTT_CODEC_07_035: [If any error is encountered then the packet state will be marked as error and mqtt_codec_bytesReceived shall return a non-zero value.] */
+                        codec_Data->currPacket = PACKET_TYPE_ERROR;
+                        result = MU_FAILURE;
+                    }
+                    else
+                    {
+                        // Increment the data
+                        dataBytes += codec_Data->bufferOffset++;
+                        *dataBytes = iterator;
+
+                        size_t totalLen = BUFFER_length(codec_Data->headerData);
+                        if (codec_Data->bufferOffset >= totalLen)
+                        {
+                            /* Codes_SRS_MQTT_CODEC_07_034: [Upon a constructing a complete MQTT packet mqtt_codec_bytesReceived shall call the ON_PACKET_COMPLETE_CALLBACK function.] */
+                            completePacketData(codec_Data);
+                        }
+                    }
+                }
+            }
+            else
+            {
+                /* Codes_SRS_MQTT_CODEC_07_035: [If any error is encountered then the packet state will be marked as error and mqtt_codec_bytesReceived shall return a non-zero value.] */
+                codec_Data->currPacket = PACKET_TYPE_ERROR;
+                result = MU_FAILURE;
+            }
+        }
+    }
+    return result;
+}
Index: azure_iot_hub_f767zi/trunk/azure_iot_sdk/umqtt/src/mqtt_message.c
===================================================================
--- azure_iot_hub_f767zi/trunk/azure_iot_sdk/umqtt/src/mqtt_message.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/azure_iot_sdk/umqtt/src/mqtt_message.c	(revision 457)
@@ -0,0 +1,372 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+#include <stdlib.h>
+#include "azure_umqtt_c/mqtt_message.h"
+#include "azure_c_shared_utility/optimize_size.h"
+#include "azure_c_shared_utility/gballoc.h"
+#include "azure_c_shared_utility/xlogging.h"
+#include "azure_c_shared_utility/string_token.h"
+#include "azure_macro_utils/macro_utils.h"
+
+typedef struct MQTT_MESSAGE_TAG
+{
+    uint16_t packetId;
+    QOS_VALUE qosInfo;
+
+    char* topicName;
+    APP_PAYLOAD appPayload;
+
+    const char* const_topic_name;
+    APP_PAYLOAD const_payload;
+
+    bool isDuplicateMsg;
+    bool isMessageRetained;
+} MQTT_MESSAGE;
+
+static MQTT_MESSAGE* create_msg_object(uint16_t packetId, QOS_VALUE qosValue)
+{
+    MQTT_MESSAGE* result;
+    result = (MQTT_MESSAGE*)malloc(sizeof(MQTT_MESSAGE));
+    if (result != NULL)
+    {
+        memset(result, 0, sizeof(MQTT_MESSAGE));
+        result->packetId = packetId;
+        result->isDuplicateMsg = false;
+        result->isMessageRetained = false;
+        result->qosInfo = qosValue;
+    }
+    else
+    {
+        LogError("Failure unable to allocate MQTT Message.");
+    }
+    return result;
+}
+
+MQTT_MESSAGE_HANDLE mqttmessage_create_in_place(uint16_t packetId, const char* topicName, QOS_VALUE qosValue, const uint8_t* appMsg, size_t appMsgLength)
+{
+    /* Codes_SRS_MQTTMESSAGE_07_026: [If the parameters topicName is NULL then mqttmessage_create_in_place shall return NULL.].] */
+    MQTT_MESSAGE* result;
+    if (topicName == NULL)
+    {
+        LogError("Invalid Parameter topicName: %p, packetId: %d.", topicName, packetId);
+        result = NULL;
+    }
+    else
+    {
+        result = create_msg_object(packetId, qosValue);
+        if (result == NULL)
+        {
+            /* Codes_SRS_MQTTMESSAGE_07_028: [If any memory allocation fails mqttmessage_create_in_place shall free any allocated memory and return NULL.] */
+            LogError("Failure creating message object");
+        }
+        else
+        {
+            /* Codes_SRS_MQTTMESSAGE_07_027: [mqttmessage_create_in_place shall use the a pointer to topicName or appMsg .] */
+            result->const_topic_name = topicName;
+            result->const_payload.length = appMsgLength;
+            if (result->const_payload.length > 0)
+            {
+                result->const_payload.message = (uint8_t*)appMsg;
+            }
+        }
+    }
+    /* Codes_SRS_MQTTMESSAGE_07_029: [ Upon success, mqttmessage_create_in_place shall return a NON-NULL MQTT_MESSAGE_HANDLE value.] */
+    return (MQTT_MESSAGE_HANDLE)result;
+}
+
+MQTT_MESSAGE_HANDLE mqttmessage_create(uint16_t packetId, const char* topicName, QOS_VALUE qosValue, const uint8_t* appMsg, size_t appMsgLength)
+{
+    /* Codes_SRS_MQTTMESSAGE_07_001:[If the parameters topicName is NULL is zero then mqttmessage_create shall return NULL.] */
+    MQTT_MESSAGE* result;
+    if (topicName == NULL)
+    {
+        LogError("Invalid Parameter topicName: %p, packetId: %d.", topicName, packetId);
+        result = NULL;
+    }
+    else
+    {
+        /* Codes_SRS_MQTTMESSAGE_07_002: [mqttmessage_create shall allocate and copy the topicName and appMsg parameters.] */
+        result = create_msg_object(packetId, qosValue);
+        if (result == NULL)
+        {
+            /* Codes_SRS_MQTTMESSAGE_07_028: [If any memory allocation fails mqttmessage_create_in_place shall free any allocated memory and return NULL.] */
+            LogError("Failure creating message object");
+        }
+        else
+        {
+            if (mallocAndStrcpy_s(&result->topicName, topicName) != 0)
+            {
+                /* Codes_SRS_MQTTMESSAGE_07_003: [If any memory allocation fails mqttmessage_create shall free any allocated memory and return NULL.] */
+                LogError("Failure allocating topic name");
+                free(result);
+                result = NULL;
+            }
+            else
+            {
+                /* Codes_SRS_MQTTMESSAGE_07_002: [mqttmessage_create shall allocate and copy the topicName and appMsg parameters.] */
+                result->appPayload.length = appMsgLength;
+                if (result->appPayload.length > 0)
+                {
+                    result->appPayload.message = malloc(appMsgLength);
+                    if (result->appPayload.message == NULL)
+                    {
+                        /* Codes_SRS_MQTTMESSAGE_07_003: [If any memory allocation fails mqttmessage_create shall free any allocated memory and return NULL.] */
+                        LogError("Failure allocating message value of %lu", (unsigned long)appMsgLength);
+                        free(result->topicName);
+                        free(result);
+                        result = NULL;
+                    }
+                    else
+                    {
+                        (void)memcpy(result->appPayload.message, appMsg, appMsgLength);
+                    }
+                }
+                else
+                {
+                    result->appPayload.message = NULL;
+                }
+            }
+        }
+    }
+    /* Codes_SRS_MQTTMESSAGE_07_004: [If mqttmessage_createMessage succeeds the it shall return a NON-NULL MQTT_MESSAGE_HANDLE value.] */
+    return (MQTT_MESSAGE_HANDLE)result;
+}
+
+void mqttmessage_destroy(MQTT_MESSAGE_HANDLE handle)
+{
+    /* Codes_SRS_MQTTMESSAGE_07_005: [If the handle parameter is NULL then mqttmessage_destroyMessage shall do nothing] */
+    if (handle != NULL)
+    {
+        /* Codes_SRS_MQTTMESSAGE_07_006: [mqttmessage_destroyMessage shall free all resources associated with the MQTT_MESSAGE_HANDLE value] */
+        if (handle->topicName != NULL)
+        {
+            free(handle->topicName);
+        }
+        if (handle->appPayload.message != NULL)
+        {
+            free(handle->appPayload.message);
+        }
+        free(handle);
+    }
+}
+
+MQTT_MESSAGE_HANDLE mqttmessage_clone(MQTT_MESSAGE_HANDLE handle)
+{
+    MQTT_MESSAGE_HANDLE result;
+    if (handle == NULL)
+    {
+        /* Codes_SRS_MQTTMESSAGE_07_007: [If handle parameter is NULL then mqttmessage_clone shall return NULL.] */
+        LogError("Invalid Parameter handle: %p.", handle);
+        result = NULL;
+    }
+    else
+    {
+        /* Codes_SRS_MQTTMESSAGE_07_008: [mqttmessage_clone shall create a new MQTT_MESSAGE_HANDLE with data content identical of the handle value.] */
+        result = mqttmessage_create(handle->packetId, handle->topicName, handle->qosInfo, handle->appPayload.message, handle->appPayload.length);
+        if (result != NULL)
+        {
+            result->isDuplicateMsg = handle->isDuplicateMsg;
+            result->isMessageRetained = handle->isMessageRetained;
+        }
+    }
+    return result;
+}
+
+uint16_t mqttmessage_getPacketId(MQTT_MESSAGE_HANDLE handle)
+{
+    uint16_t result;
+    if (handle == NULL)
+    {
+        /* Codes_SRS_MQTTMESSAGE_07_010: [If handle is NULL then mqttmessage_getPacketId shall return 0.] */
+        LogError("Invalid Parameter handle: %p.", handle);
+        result = 0;
+    }
+    else
+    {
+        /* Codes_SRS_MQTTMESSAGE_07_011: [mqttmessage_getPacketId shall return the packetId value contained in MQTT_MESSAGE_HANDLE handle.] */
+        result = handle->packetId;
+    }
+    return result;
+}
+
+const char* mqttmessage_getTopicName(MQTT_MESSAGE_HANDLE handle)
+{
+    const char* result;
+    if (handle == NULL)
+    {
+        /* Codes_SRS_MQTTMESSAGE_07_012: [If handle is NULL then mqttmessage_getTopicName shall return a NULL string.] */
+        LogError("Invalid Parameter handle: %p.", handle);
+        result = NULL;
+    }
+    else
+    {
+        /* Codes_SRS_MQTTMESSAGE_07_013: [mqttmessage_getTopicName shall return the topicName contained in MQTT_MESSAGE_HANDLE handle.] */
+        if (handle->topicName == NULL)
+        {
+            result = handle->const_topic_name;
+        }
+        else
+        {
+            result = handle->topicName;
+        }
+    }
+    return result;
+}
+
+int mqttmessage_getTopicLevels(MQTT_MESSAGE_HANDLE handle, char*** levels, size_t* count)
+{
+    int result;
+
+    // Codes_SRS_MQTTMESSAGE_09_001: [ If `handle`, `levels` or `count` are NULL the function shall return a non-zero value. ]
+    if (handle == NULL || levels == NULL || count == NULL)
+    {
+        LogError("Invalid Parameter handle: %p, levels: %p, count: %p", handle, levels, count);
+        result = MU_FAILURE;
+    }
+    else
+    {
+        MQTT_MESSAGE* msgInfo = (MQTT_MESSAGE*)handle;
+
+        const char* topic_name = msgInfo->topicName != NULL ? msgInfo->topicName : msgInfo->const_topic_name;
+
+        if (topic_name == NULL)
+        {
+            LogError("Topic name is NULL");
+            result = MU_FAILURE;
+        }
+        else
+        {
+            const char* delimiters[1];
+
+            delimiters[0] = "/";
+
+            // Codes_SRS_MQTTMESSAGE_09_002: [ The topic name, excluding the property bag, shall be split into individual tokens using "/" as separator ]
+            // Codes_SRS_MQTTMESSAGE_09_004: [ The split tokens shall be stored in `levels` and its count in `count` ]
+            if (StringToken_Split(topic_name, strlen(topic_name), delimiters, 1, false, levels, count) != 0)
+            {
+                // Codes_SRS_MQTTMESSAGE_09_003: [ If splitting fails the function shall return a non-zero value. ]
+                LogError("Failed splitting topic levels");
+                result = MU_FAILURE;
+            }
+            else
+            {
+                // Codes_SRS_MQTTMESSAGE_09_005: [ If no failures occur the function shall return zero. ]
+                result = 0;
+            }
+        }
+    }
+
+    return result;
+}
+
+QOS_VALUE mqttmessage_getQosType(MQTT_MESSAGE_HANDLE handle)
+{
+    QOS_VALUE result;
+    if (handle == NULL)
+    {
+        /* Codes_SRS_MQTTMESSAGE_07_014: [If handle is NULL then mqttmessage_getQosType shall return the default DELIVER_AT_MOST_ONCE value.] */
+        LogError("Invalid Parameter handle: %p.", handle);
+        result = DELIVER_AT_MOST_ONCE;
+    }
+    else
+    {
+        /* Codes_SRS_MQTTMESSAGE_07_015: [mqttmessage_getQosType shall return the QOS Type value contained in MQTT_MESSAGE_HANDLE handle.] */
+        result = handle->qosInfo;
+    }
+    return result;
+}
+
+bool mqttmessage_getIsDuplicateMsg(MQTT_MESSAGE_HANDLE handle)
+{
+    bool result;
+    if (handle == NULL)
+    {
+        /* Codes_SRS_MQTTMESSAGE_07_016: [If handle is NULL then mqttmessage_getIsDuplicateMsg shall return false.] */
+        LogError("Invalid Parameter handle: %p.", handle);
+        result = false;
+    }
+    else
+    {
+        /* Codes_SRS_MQTTMESSAGE_07_017: [mqttmessage_getIsDuplicateMsg shall return the isDuplicateMsg value contained in MQTT_MESSAGE_HANDLE handle.] */
+        result = handle->isDuplicateMsg;
+    }
+    return result;
+}
+
+bool mqttmessage_getIsRetained(MQTT_MESSAGE_HANDLE handle)
+{
+    bool result;
+    if (handle == NULL)
+    {
+        /* Codes_SRS_MQTTMESSAGE_07_018: [If handle is NULL then mqttmessage_getIsRetained shall return false.] */
+        LogError("Invalid Parameter handle: %p.", handle);
+        result = false;
+    }
+    else
+    {
+        /* Codes_SRS_MQTTMESSAGE_07_019: [mqttmessage_getIsRetained shall return the isRetained value contained in MQTT_MESSAGE_HANDLE handle.] */
+        result = handle->isMessageRetained;
+    }
+    return result;
+}
+
+int mqttmessage_setIsDuplicateMsg(MQTT_MESSAGE_HANDLE handle, bool duplicateMsg)
+{
+    int result;
+    /* Codes_SRS_MQTTMESSAGE_07_022: [If handle is NULL then mqttmessage_setIsDuplicateMsg shall return a non-zero value.] */
+    if (handle == NULL)
+    {
+        LogError("Invalid Parameter handle: %p.", handle);
+        result = MU_FAILURE;
+    }
+    else
+    {
+        /* Codes_SRS_MQTTMESSAGE_07_023: [mqttmessage_setIsDuplicateMsg shall store the duplicateMsg value in the MQTT_MESSAGE_HANDLE handle.] */
+        handle->isDuplicateMsg = duplicateMsg;
+        result = 0;
+    }
+    return result;
+}
+
+int mqttmessage_setIsRetained(MQTT_MESSAGE_HANDLE handle, bool retainMsg)
+{
+    int result;
+    /* Codes_SRS_MQTTMESSAGE_07_024: [If handle is NULL then mqttmessage_setIsRetained shall return a non-zero value.] */
+    if (handle == NULL)
+    {
+        LogError("Invalid Parameter handle: %p.", handle);
+        result = MU_FAILURE;
+    }
+    else
+    {
+        /* Codes_SRS_MQTTMESSAGE_07_025: [mqttmessage_setIsRetained shall store the retainMsg value in the MQTT_MESSAGE_HANDLE handle.] */
+        handle->isMessageRetained = retainMsg;
+        result = 0;
+    }
+    return result;
+}
+
+const APP_PAYLOAD* mqttmessage_getApplicationMsg(MQTT_MESSAGE_HANDLE handle)
+{
+    const APP_PAYLOAD* result;
+    if (handle == NULL)
+    {
+        /* Codes_SRS_MQTTMESSAGE_07_020: [If handle is NULL or if msgLen is 0 then mqttmessage_getApplicationMsg shall return NULL.] */
+        LogError("Invalid Parameter handle: %p.", handle);
+        result = NULL;
+    }
+    else
+    {
+        /* Codes_SRS_MQTTMESSAGE_07_021: [mqttmessage_getApplicationMsg shall return the applicationMsg value contained in MQTT_MESSAGE_HANDLE handle and the length of the appMsg in the msgLen parameter.] */
+        if (handle->const_payload.length > 0)
+        {
+            result = &handle->const_payload;
+        }
+        else
+        {
+            result = &handle->appPayload;
+        }
+    }
+    return result;
+}
Index: azure_iot_hub_f767zi/trunk/azure_iothub.code-workspace
===================================================================
--- azure_iot_hub_f767zi/trunk/azure_iothub.code-workspace	(revision 457)
+++ azure_iot_hub_f767zi/trunk/azure_iothub.code-workspace	(revision 457)
@@ -0,0 +1,32 @@
+{
+	"folders": [
+		{
+			"path": "app_iothub_client"
+		},
+		{
+			"path": "asp_baseplatform"
+		},
+		{
+			"path": "azure_iot_sdk"
+		},
+		{
+			"path": "wolfssl-4.4.0"
+		},
+		{
+			"path": "zlib-1.2.11"
+		}
+	],
+	"settings": {
+		"terminal.integrated.shell.windows": "C:\\msys64\\usr\\bin\\bash.exe",
+		"terminal.integrated.shellArgs.windows": [
+			"--login",
+			"-i"
+		],
+		"terminal.integrated.env.windows": {
+			"PATH": "C:\\Program Files (x86)\\GNU Tools ARM Embedded\\9 2019-q4-major\\bin",
+			"CHERE_INVOKING": "1",
+			"MSYS2_PATH_TYPE": "inherit",
+			"MSYSTEM": "MINGW64"
+		}
+	}
+}
Index: azure_iot_hub_f767zi/trunk/wolfssl-4.4.0/.vscode/c_cpp_properties.json
===================================================================
--- azure_iot_hub_f767zi/trunk/wolfssl-4.4.0/.vscode/c_cpp_properties.json	(revision 457)
+++ azure_iot_hub_f767zi/trunk/wolfssl-4.4.0/.vscode/c_cpp_properties.json	(revision 457)
@@ -0,0 +1,21 @@
+{
+    "configurations": [
+        {
+            "name": "STM32F767 NUCLEO-144",
+            "includePath": [
+                "${workspaceFolder}/../zlib-1.2.11/src",
+                "${workspaceFolder}/../wolfssl-4.4.0"
+            ],
+            "defines": [
+                "HAVE_CONFIG_H",
+                "WOLFSSL_USER_SETTINGS"
+            ],
+            "windowsSdkVersion": "10.0.17763.0",
+            "compilerPath": "C:\\Program Files (x86)\\GNU Tools ARM Embedded\\9 2019-q4-major\\bin\\arm-none-eabi-gcc.exe",
+            "cStandard": "c11",
+            "cppStandard": "c++17",
+            "intelliSenseMode": "gcc-x64"
+        }
+    ],
+    "version": 4
+}
Index: azure_iot_hub_f767zi/trunk/wolfssl-4.4.0/.vscode/settings.json
===================================================================
--- azure_iot_hub_f767zi/trunk/wolfssl-4.4.0/.vscode/settings.json	(revision 457)
+++ azure_iot_hub_f767zi/trunk/wolfssl-4.4.0/.vscode/settings.json	(revision 457)
@@ -0,0 +1,17 @@
+// Place your settings in this file to overwrite default and user settings.
+{
+    "terminal.integrated.setLocaleVariables": true,
+    "terminal.integrated.shell.windows": "C:\\msys64\\usr\\bin\\bash.exe",
+    "terminal.integrated.shellArgs.windows": [
+        "--login",
+        "-i"
+    ],
+    "terminal.integrated.env.windows": {
+        "PATH": "C:\\Program Files (x86)\\GNU Tools ARM Embedded\\9 2019-q4-major\\bin",
+        "CHERE_INVOKING": "1",
+        "MSYS2_PATH_TYPE": "inherit",
+        "MSYSTEM": "MINGW64"
+    },
+    "C_Cpp.intelliSenseEngine": "Tag Parser",
+    "C_Cpp.default.intelliSenseMode": "gcc-x64"
+}
Index: azure_iot_hub_f767zi/trunk/wolfssl-4.4.0/.vscode/tasks.json
===================================================================
--- azure_iot_hub_f767zi/trunk/wolfssl-4.4.0/.vscode/tasks.json	(revision 457)
+++ azure_iot_hub_f767zi/trunk/wolfssl-4.4.0/.vscode/tasks.json	(revision 457)
@@ -0,0 +1,57 @@
+{
+    // See https://go.microsoft.com/fwlink/?LinkId=733558
+    // for the documentation about the tasks.json format
+    "version": "2.0.0",
+    "name": "make",
+    "type": "shell",
+    "problemMatcher": {
+        "owner": "cpp",
+        "fileLocation": [
+            "relative",
+            "${workspaceFolder}/Debug"
+        ],
+        "pattern": {
+            "regexp": "^(.*):(\\d+):(\\d+):\\s+(warning|error|fatal error):\\s+(.*)$",
+            "file": 1,
+            "line": 2,
+            "column": 3,
+            "severity": 4,
+            "message": 5
+        }
+    },
+    "tasks": [
+        {
+            "label": "build wolfssl",
+            "args": [
+                "-j",
+                "all"
+            ],
+            "linux": {
+                "command": "make"
+            },
+            "osx": {
+                "command": "make"
+            },
+            "windows": {
+                "command": "make.exe"
+            },
+            "group": "build"
+        },
+        {
+            "label": "clean wolfssl",
+            "args": [
+                "clean"
+            ],
+            "linux": {
+                "command": "make"
+            },
+            "osx": {
+                "command": "make"
+            },
+            "windows": {
+                "command": "make.exe"
+            },
+            "group": "build"
+        }
+    ]
+}
Index: azure_iot_hub_f767zi/trunk/wolfssl-4.4.0/COPYING
===================================================================
--- azure_iot_hub_f767zi/trunk/wolfssl-4.4.0/COPYING	(revision 457)
+++ azure_iot_hub_f767zi/trunk/wolfssl-4.4.0/COPYING	(revision 457)
@@ -0,0 +1,339 @@
+                    GNU GENERAL PUBLIC LICENSE
+                       Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+                            Preamble
+
+  The licenses for most software are designed to take away your
+freedom to share and change it.  By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users.  This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it.  (Some other Free Software Foundation software is covered by
+the GNU Lesser General Public License instead.)  You can apply it to
+your programs, too.
+
+  When we speak of free software, we are referring to freedom, not
+price.  Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+  To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+  For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have.  You must make sure that they, too, receive or can get the
+source code.  And you must show them these terms so they know their
+rights.
+
+  We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+  Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software.  If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+  Finally, any free program is threatened constantly by software
+patents.  We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary.  To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.
+
+                    GNU GENERAL PUBLIC LICENSE
+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+  0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License.  The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language.  (Hereinafter, translation is included without limitation in
+the term "modification".)  Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope.  The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+  1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+  2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+    a) You must cause the modified files to carry prominent notices
+    stating that you changed the files and the date of any change.
+
+    b) You must cause any work that you distribute or publish, that in
+    whole or in part contains or is derived from the Program or any
+    part thereof, to be licensed as a whole at no charge to all third
+    parties under the terms of this License.
+
+    c) If the modified program normally reads commands interactively
+    when run, you must cause it, when started running for such
+    interactive use in the most ordinary way, to print or display an
+    announcement including an appropriate copyright notice and a
+    notice that there is no warranty (or else, saying that you provide
+    a warranty) and that users may redistribute the program under
+    these conditions, and telling the user how to view a copy of this
+    License.  (Exception: if the Program itself is interactive but
+    does not normally print such an announcement, your work based on
+    the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole.  If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works.  But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+  3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+    a) Accompany it with the complete corresponding machine-readable
+    source code, which must be distributed under the terms of Sections
+    1 and 2 above on a medium customarily used for software interchange; or,
+
+    b) Accompany it with a written offer, valid for at least three
+    years, to give any third party, for a charge no more than your
+    cost of physically performing source distribution, a complete
+    machine-readable copy of the corresponding source code, to be
+    distributed under the terms of Sections 1 and 2 above on a medium
+    customarily used for software interchange; or,
+
+    c) Accompany it with the information you received as to the offer
+    to distribute corresponding source code.  (This alternative is
+    allowed only for noncommercial distribution and only if you
+    received the program in object code or executable form with such
+    an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it.  For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable.  However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+  4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License.  Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+  5. You are not required to accept this License, since you have not
+signed it.  However, nothing else grants you permission to modify or
+distribute the Program or its derivative works.  These actions are
+prohibited by law if you do not accept this License.  Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+  6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions.  You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+  7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all.  For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices.  Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+  8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded.  In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+  9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time.  Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number.  If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation.  If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+  10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission.  For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this.  Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+                            NO WARRANTY
+
+  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+                     END OF TERMS AND CONDITIONS
+
+            How to Apply These Terms to Your New Programs
+
+  If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+  To do so, attach the following notices to the program.  It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the program's name and a brief idea of what it does.>
+    Copyright (C) <year>  <name of author>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License along
+    with this program; if not, write to the Free Software Foundation, Inc.,
+    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+    Gnomovision version 69, Copyright (C) year name of author
+    Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+    This is free software, and you are welcome to redistribute it
+    under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License.  Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary.  Here is a sample; alter the names:
+
+  Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+  `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+  <signature of Ty Coon>, 1 April 1989
+  Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs.  If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library.  If this is what you want to do, use the GNU Lesser General
+Public License instead of this License.
Index: azure_iot_hub_f767zi/trunk/wolfssl-4.4.0/LICENSING
===================================================================
--- azure_iot_hub_f767zi/trunk/wolfssl-4.4.0/LICENSING	(revision 457)
+++ azure_iot_hub_f767zi/trunk/wolfssl-4.4.0/LICENSING	(revision 457)
@@ -0,0 +1,11 @@
+
+wolfSSL (formerly known as CyaSSL) and wolfCrypt are either licensed for use
+under the GPLv2 or a standard commercial license. For our users who cannot use
+wolfSSL under GPLv2, a commercial license to wolfSSL and wolfCrypt is available.
+Please contact wolfSSL Inc. directly at:
+
+Email: licensing@wolfssl.com
+Phone: +1 425 245-8247
+
+More information can be found on the wolfSSL website at www.wolfssl.com.
+
Index: azure_iot_hub_f767zi/trunk/wolfssl-4.4.0/Makefile
===================================================================
--- azure_iot_hub_f767zi/trunk/wolfssl-4.4.0/Makefile	(revision 457)
+++ azure_iot_hub_f767zi/trunk/wolfssl-4.4.0/Makefile	(revision 457)
@@ -0,0 +1,234 @@
+# This file was automagically generated by mbed.org. For more information, 
+# see http://mbed.org/handbook/Exporting-to-GCC-ARM-Embedded
+
+###############################################################################
+# Boiler-plate
+
+# cross-platform directory manipulation
+ifeq ($(shell echo $$OS),$$OS)
+    MAKEDIR = if not exist "$(1)" mkdir "$(1)"
+    RM = rmdir /S /Q "$(1)"
+else
+    MAKEDIR = '$(SHELL)' -c "mkdir -p \"$(1)\""
+    RM = '$(SHELL)' -c "rm -rf \"$(1)\""
+endif
+
+OBJDIR := Debug
+# Move to the build directory
+ifeq (,$(filter $(OBJDIR),$(notdir $(CURDIR))))
+.SUFFIXES:
+mkfile_path := $(abspath $(lastword $(MAKEFILE_LIST)))
+MAKETARGET = '$(MAKE)' --no-print-directory -C $(OBJDIR) -f '$(mkfile_path)' \
+		'SRCDIR=$(CURDIR)' $(MAKECMDGOALS)
+.PHONY: $(OBJDIR) clean
+all:
+	+@$(call MAKEDIR,$(OBJDIR))
+	+@$(MAKETARGET)
+$(OBJDIR): all
+Makefile : ;
+% :: $(OBJDIR) ; :
+clean :
+	$(call RM,$(OBJDIR))
+
+else
+
+# trick rules into thinking we are in the root, when we are in the bulid dir
+VPATH = ../../wolfssl-4.4.0
+
+# Boiler-plate
+###############################################################################
+# Project settings
+
+PROJECT := wolfssl
+
+
+# Project settings
+###############################################################################
+# Objects and Paths
+
+OBJECTS += src/crl.o
+OBJECTS += src/internal.o
+OBJECTS += src/keys.o
+OBJECTS += src/ocsp.o
+OBJECTS += src/sniffer.o
+OBJECTS += src/ssl.o
+OBJECTS += src/tls.o
+OBJECTS += src/tls13.o
+OBJECTS += src/wolfio.o
+OBJECTS += wolfcrypt/src/aes.o
+OBJECTS += wolfcrypt/src/arc4.o
+OBJECTS += wolfcrypt/src/asn.o
+OBJECTS += wolfcrypt/src/blake2b.o
+OBJECTS += wolfcrypt/src/camellia.o
+OBJECTS += wolfcrypt/src/coding.o
+OBJECTS += wolfcrypt/src/des3.o
+OBJECTS += wolfcrypt/src/dh.o
+OBJECTS += wolfcrypt/src/dsa.o
+OBJECTS += wolfcrypt/src/ecc.o
+OBJECTS += wolfcrypt/src/error.o
+OBJECTS += wolfcrypt/src/hash.o
+OBJECTS += wolfcrypt/src/hc128.o
+OBJECTS += wolfcrypt/src/hmac.o
+OBJECTS += wolfcrypt/src/integer.o
+OBJECTS += wolfcrypt/src/logging.o
+OBJECTS += wolfcrypt/src/md4.o
+OBJECTS += wolfcrypt/src/md5.o
+OBJECTS += wolfcrypt/src/memory.o
+OBJECTS += wolfcrypt/src/misc.o
+OBJECTS += wolfcrypt/src/pwdbased.o
+OBJECTS += wolfcrypt/src/rabbit.o
+OBJECTS += wolfcrypt/src/random.o
+OBJECTS += wolfcrypt/src/ripemd.o
+OBJECTS += wolfcrypt/src/rsa.o
+OBJECTS += wolfcrypt/src/sha.o
+OBJECTS += wolfcrypt/src/sha256.o
+OBJECTS += wolfcrypt/src/sha512.o
+OBJECTS += wolfcrypt/src/wc_encrypt.o
+OBJECTS += wolfcrypt/src/wc_port.o
+OBJECTS += wolfcrypt/src/wolfmath.o
+
+INCLUDE_PATHS += -I../../asp_baseplatform
+INCLUDE_PATHS += -I../../asp_baseplatform/include
+INCLUDE_PATHS += -I../../asp_baseplatform/arch
+INCLUDE_PATHS += -I../../asp_baseplatform/arch/arm_m_gcc/common
+INCLUDE_PATHS += -I../../asp_baseplatform/arch/arm_m_gcc/stm32f7xx
+INCLUDE_PATHS += -I../../asp_baseplatform/target/stm32f767nucleo144_gcc
+INCLUDE_PATHS += -I../../asp_baseplatform/lwip/lwip-2.1.2/src/include
+INCLUDE_PATHS += -I../../asp_baseplatform/lwip/contrib-2.1.0/ports/toppers/include
+INCLUDE_PATHS += -I../../asp_baseplatform/lwip/contrib-2.1.0
+INCLUDE_PATHS += -I../../asp_baseplatform/OBJ/STM32F767NUCLEO144_GCC/MAC
+INCLUDE_PATHS += -I../../asp_baseplatform/monitor
+INCLUDE_PATHS += -I../../asp_baseplatform/files
+INCLUDE_PATHS += -I../../zlib-1.2.11/src
+INCLUDE_PATHS += -I../../wolfssl-4.4.0
+INCLUDE_PATHS += -I../../wolfssl-4.4.0/src
+
+# Objects and Paths
+###############################################################################
+# Tools and Flags
+
+AS      = arm-none-eabi-gcc
+CC      = arm-none-eabi-gcc
+CPP     = arm-none-eabi-g++
+AR      = arm-none-eabi-ar
+RANLIB  = arm-none-eabi-ranlib
+
+
+C_FLAGS += -std=gnu11
+C_FLAGS += -mcpu=cortex-m4
+C_FLAGS += -march=armv7e-m
+C_FLAGS += -mthumb
+C_FLAGS += -mlittle-endian
+C_FLAGS += -mfloat-abi=hard
+C_FLAGS += -mfpu=fpv4-sp-d16
+C_FLAGS += -Os
+C_FLAGS += -fmessage-length=0
+C_FLAGS += -fsigned-char
+C_FLAGS += -ffunction-sections
+C_FLAGS += -fdata-sections
+C_FLAGS += -Wall
+C_FLAGS += -Wextra
+C_FLAGS += -Wno-unused-parameter
+C_FLAGS += -Wno-missing-field-initializers
+C_FLAGS += -Wnull-dereference
+
+C_FLAGS += -g3
+C_FLAGS += -Wstack-usage=256
+
+C_FLAGS += -DHAVE_CONFIG_H
+C_FLAGS += -DWOLFSSL_USER_SETTINGS
+C_FLAGS += -DCYASSL_USER_SETTINGS
+
+CXX_FLAGS += -std=gnu++11
+CXX_FLAGS += -mcpu=cortex-m4
+CXX_FLAGS += -march=armv7e-m
+CXX_FLAGS += -mthumb
+CXX_FLAGS += -mlittle-endian
+CXX_FLAGS += -mfloat-abi=hard
+CXX_FLAGS += -mfpu=fpv4-sp-d16
+CXX_FLAGS += -Os
+CXX_FLAGS += -fmessage-length=0
+CXX_FLAGS += -fsigned-char
+CXX_FLAGS += -ffunction-sections
+CXX_FLAGS += -fdata-sections
+CXX_FLAGS += -Wall
+CXX_FLAGS += -Wextra
+CXX_FLAGS += -Wno-unused-parameter
+CXX_FLAGS += -Wno-missing-field-initializers
+CXX_FLAGS += -Wnull-dereference
+
+CXX_FLAGS += -g3
+CXX_FLAGS += -Wstack-usage=256
+
+CXX_FLAGS += -DHAVE_CONFIG_H
+CXX_FLAGS += -DWOLFSSL_USER_SETTINGS
+CXX_FLAGS += -DCYASSL_USER_SETTINGS
+
+ASM_FLAGS += -x
+ASM_FLAGS += assembler-with-cpp
+ASM_FLAGS += -mcpu=cortex-m4
+ASM_FLAGS += -march=armv7e-m
+ASM_FLAGS += -mthumb
+ASM_FLAGS += -mlittle-endian
+ASM_FLAGS += -mfloat-abi=hard
+ASM_FLAGS += -mfpu=fpv4-sp-d16
+ASM_FLAGS += -Os
+ASM_FLAGS += -fmessage-length=0
+ASM_FLAGS += -fsigned-char
+ASM_FLAGS += -ffunction-sections
+ASM_FLAGS += -fdata-sections
+ASM_FLAGS += -Wall
+ASM_FLAGS += -Wextra
+ASM_FLAGS += -Wno-unused-parameter
+ASM_FLAGS += -Wno-missing-field-initializers
+ASM_FLAGS += -Wnull-dereference
+ASM_FLAGS += -g3
+ASM_FLAGS += -Wstack-usage=256
+
+
+# Tools and Flags
+###############################################################################
+# Rules
+
+.PHONY: all lst size
+
+
+all: lib$(PROJECT).a
+
+
+.s.o:
+	+@$(call MAKEDIR,$(dir $@))
+	+@echo "Assemble: $(notdir $<)"
+	@$(AS) -c $(ASM_FLAGS) -o $@ $<
+
+.S.o:
+	+@$(call MAKEDIR,$(dir $@))
+	+@echo "Assemble: $(notdir $<)"
+	@$(AS) -c $(ASM_FLAGS) -o $@ $<
+
+.c.o:
+	+@$(call MAKEDIR,$(dir $@))
+	+@echo "Compile: $(notdir $<)"
+	@$(CC) $(C_FLAGS) $(INCLUDE_PATHS) -MMD -MP -MF"$(@:%.o=%.d)" -MT"$(@)" -c -o "$@" "$<"
+
+.cpp.o:
+	+@$(call MAKEDIR,$(dir $@))
+	+@echo "Compile: $(notdir $<)"
+	@$(CPP) $(CXX_FLAGS) $(INCLUDE_PATHS) -MMD -MP -MF"$(@:%.o=%.d)" -MT"$(@)" -c -o "$@" "$<"
+
+lib$(PROJECT).a: $(OBJECTS)
+	rm -f lib$(PROJECT).a
+	$(AR) -rcs lib$(PROJECT).a $(OBJECTS)
+	$(RANLIB) lib$(PROJECT).a
+
+
+# Rules
+###############################################################################
+# Dependencies
+
+DEPS = $(OBJECTS:.o=.d) $(SYS_OBJECTS:.o=.d)
+-include $(DEPS)
+endif
+
+# Dependencies
+###############################################################################
Index: azure_iot_hub_f767zi/trunk/wolfssl-4.4.0/README
===================================================================
--- azure_iot_hub_f767zi/trunk/wolfssl-4.4.0/README	(revision 457)
+++ azure_iot_hub_f767zi/trunk/wolfssl-4.4.0/README	(revision 457)
@@ -0,0 +1,222 @@
+*** Description ***
+
+The wolfSSL embedded SSL library (formerly CyaSSL) is a lightweight SSL/TLS
+library written in ANSI C and targeted for embedded, RTOS, and
+resource-constrained environments - primarily because of its small size, speed,
+and feature set.  It is commonly used in standard operating environments as well
+because of its royalty-free pricing and excellent cross platform support.
+wolfSSL supports industry standards up to the current TLS 1.3 and DTLS 1.2
+levels, is up to 20 times smaller than OpenSSL, and offers progressive ciphers
+such as ChaCha20, Curve25519, NTRU, and Blake2b. User benchmarking and feedback
+reports dramatically better performance when using wolfSSL over OpenSSL.
+
+wolfSSL is powered by the wolfCrypt library. Two versions of the wolfCrypt
+cryptography library have been FIPS 140-2 validated (Certificate #2425 and
+certificate #3389). For additional information, visit the wolfCrypt FIPS FAQ
+(https://www.wolfssl.com/license/fips/) or contact fips@wolfssl.com
+
+*** Why choose wolfSSL? ***
+
+There are many reasons to choose wolfSSL as your embedded SSL solution. Some of
+the top reasons include size (typical footprint sizes range from 20-100 kB),
+support for the newest standards (SSL 3.0, TLS 1.0, TLS 1.1, TLS 1.2, TLS 1.3,
+DTLS 1.0, and DTLS 1.2), current and progressive cipher support (including
+stream ciphers), multi-platform, royalty free, and an OpenSSL compatibility API
+to ease porting into existing applications which have previously used the
+OpenSSL package. For a complete feature list, see chapter 4 of the wolfSSL
+manual. (https://www.wolfssl.com/docs/wolfssl-manual/ch4/)
+
+*** Notes, Please read ***
+
+Note 1)
+wolfSSL as of 3.6.6 no longer enables SSLv3 by default.  wolfSSL also no longer
+supports static key cipher suites with PSK, RSA, or ECDH. This means if you
+plan to use TLS cipher suites you must enable DH (DH is on by default), or
+enable ECC (ECC is on by default), or you must enable static key cipher suites
+with
+
+    WOLFSSL_STATIC_DH
+    WOLFSSL_STATIC_RSA
+      or
+    WOLFSSL_STATIC_PSK
+
+though static key cipher suites are deprecated and will be removed from future
+versions of TLS.  They also lower your security by removing PFS.  Since current
+NTRU suites available do not use ephemeral keys, WOLFSSL_STATIC_RSA needs to be
+used in order to build with NTRU suites.
+
+When compiling ssl.c, wolfSSL will now issue a compiler error if no cipher
+suites are available. You can remove this error by defining
+WOLFSSL_ALLOW_NO_SUITES in the event that you desire that, i.e., you're not
+using TLS cipher suites.
+
+Note 2)
+wolfSSL takes a different approach to certificate verification than OpenSSL
+does. The default policy for the client is to verify the server, this means
+that if you don't load CAs to verify the server you'll get a connect error,
+no signer error to confirm failure (-188).
+
+If you want to mimic OpenSSL behavior of having SSL_connect succeed even if
+verifying the server fails and reducing security you can do this by calling:
+
+    wolfSSL_CTX_set_verify(ctx, SSL_VERIFY_NONE, 0);
+
+before calling wolfSSL_new();. Though it's not recommended.
+
+Note 3)
+The enum values SHA, SHA256, SHA384, SHA512 are no longer available when
+wolfSSL is built with --enable-opensslextra (OPENSSL_EXTRA) or with the macro
+NO_OLD_SHA_NAMES. These names get mapped to the OpenSSL API for a single call
+hash function. Instead the name WC_SHA, WC_SHA256, WC_SHA384 and WC_SHA512
+should be used for the enum name.
+
+*** end Notes ***
+
+
+# wolfSSL Release 4.4.0 (04/22/2020)
+
+If you have questions about this release, feel free to contact us on our
+info@ address.
+
+Release 4.4.0 of wolfSSL embedded TLS has bug fixes and new features including:
+
+## New Feature Additions
+
+* Hexagon support.
+* DSP builds to offload ECC verify operations.
+* Certificate Manager callback support.
+* New APIs for running updates to ChaCha20/Poly1305 AEAD.
+* Support for use with Apache.
+* Add support for IBM s390x.
+* PKCS8 support for ED25519.
+* OpenVPN support.
+* Add P384 curve support to SP.
+* Add BIO and EVP API.
+* Add AES-OFB mode.
+* Add AES-CFB mode.
+* Add Curve448, X448, and Ed448.
+* Add Renesas Synergy S7G2 build and hardware acceleration.
+
+## Fixes
+
+* Fix for RSA public encrypt / private sign with RSA key sizes over 2048-bit.
+* Correct misspellings.
+* Secure renegotiation fix.
+* Fix memory leak when using ATECC and non-SECP256R1 curves for sign, verify,
+  or shared secret.
+* Fix for K64 MMCAU with `WOLFSSL_SMALL_STACK_CACHE`.
+* Fix the RSA verify only build.
+* Fix in SP C implementation for small stack.
+* Fix using the auth key id extension is set, hash might not be present.
+* Fix when flattening certificate structure to include the subject alt names.
+* Fixes for building with ECC sign/verify only.
+* Fix for ECC and no cache resistance.
+* Fix memory leak in DSA.
+* Fix build on minGW.
+* Fix `PemToDer()` call in `ProcessBuffer()` to set more than ECC.
+* Fix for using RSA without SHA-512.
+* Add some close tags to the echoserver HTTP example output.
+* Miscellaneous fixes and updates for static analysis reports.
+* Fixes for time structure support.
+* Fixes for VxWorks support.
+* Fixes for Async crypto support.
+* Fix cache resist compile to work with SP C code.
+* Fixes for Curve25519 x64 asm.
+* Fix for SP x64 div.
+* Fix for DTLS edge case where CCS and Finished come out of order and the
+  retransmit pool gets flushed.
+* Fix for infinite loop in SHA-1 with small inputs. Thanks to Peter W.
+* Fix for FIPS Hmac where `wc_HmacInit()` isn't used. `wc_HmacSetKey()` needs
+  to initialize the Hmac structure. Type is set to NONE, and checked against
+  NONE, not 0.
+* Fixes for SP RSA private operations.
+* Fixes for Xilinx SDK and Zynq UltraScale+ MPSoC
+* Fix leak when building with HAVE_AESGCM and NO_AES_DECRYPT. Thanks G.G.
+* Fixes for building ECC without ASN.
+* Fix for async TLSv1.3 issues.
+* Fix `wc_KeyPemToDer()` with PKCS1 and empty key.
+* Omit `-fomit-frame-pointer` from CFLAGS in configure.ac.
+
+## Improvements/Optimizations
+
+* Qt 5.12 and 5.13 support.
+* Added more digest types to Cryptocell RSA sign/verify.
+* Some memory usage improvements.
+* Speed improvements for mp_rand.
+* Improvements to CRL and OCSP support.
+* Refactor Poly1305 AEAD/MAC to reduce duplicate code.
+* Add blinding to RSA key gen.
+* Improvements to blinding.
+* Improvement and expansion of OpenSSL Compatibility Layer.
+* Improvements to ChaCha20.
+* Improvements to X.509 processing.
+* Improvements to ECC support.
+* Improvement in detecting 64-bit support.
+* Refactor to combine duplicate ECC parameter parsing code.
+* Improve keyFormat to be set by algId and let later key parsing produce fail.
+* Add test cases for 3072-bit and 4096-bit RSA keys.
+* Improve signature wrapper and DH test cases.
+* Improvements to the configure.ac script.
+* Added constant time RSA q modinv p.
+* Improve performance of SP Intel 64-bit asm.
+* Added a few more functions to the ABI list.
+* Improve TLS bidirectional shutdown behavior.
+* OpenSSH 8.1 support.
+* Improve performance of RSA/DH operations on x64.
+* Add support for PKCS7/CMS Enveloped data with fragmented encrypted content.
+* Example linker description for FIPS builds to enforce object ordering.
+* C# wrapper improvements. Added TLS client example and TLSv1.3 methods.
+* Allow setting MTU in DTLS.
+* Improve PKCS12 create for outputting encrypted bundles.
+* Constant time EC map to affine for private operations.
+* Improve performance of RSA public key ops with TFM.
+* Smaller table version of AES encrypt/decrypt.
+* Support IAR with position independent code (ROPI).
+* Improve speed of AArch64 assembly.
+* Support AES-CTR with AES-NI.
+* Support AES-CTR on esp32.
+* Add a no malloc option for small SP math.
+
+## This release of wolfSSL includes fixes for 2 security vulnerabilities.
+
+* For fast math, use a constant time modular inverse when mapping to affine
+  when operation involves a private key - keygen, calc shared secret, sign.
+  Thank you to Alejandro Cabrera Aldaya, Cesar Pereida Garc鱈a and
+  Billy Bob Brumley from the Network and Information Security Group (NISEC)
+  at Tampere University for the report.
+
+* Change constant time and cache resistant ECC mulmod. Ensure points being
+  operated on change to make constant time. Thank you to Pietro Borrello at
+  Sapienza University of Rome.
+
+For additional vulnerability information visit the vulnerability page at
+https://www.wolfssl.com/docs/security-vulnerabilities/
+
+See INSTALL file for build instructions.
+More info can be found on-line at https://wolfssl.com/wolfSSL/Docs.html
+
+
+
+*** Resources ***
+
+
+[wolfSSL Website](https://www.wolfssl.com/)
+
+[wolfSSL Wiki](https://github.com/wolfSSL/wolfssl/wiki)
+
+[FIPS FAQ](https://wolfssl.com/license/fips)
+
+[wolfSSL Documents](https://wolfssl.com/wolfSSL/Docs.html)
+
+[wolfSSL Manual](https://wolfssl.com/wolfSSL/Docs-wolfssl-manual-toc.html)
+
+[wolfSSL API Reference]
+(https://wolfssl.com/wolfSSL/Docs-wolfssl-manual-17-wolfssl-api-reference.html)
+
+[wolfCrypt API Reference]
+(https://wolfssl.com/wolfSSL/Docs-wolfssl-manual-18-wolfcrypt-api-reference.html)
+
+[TLS 1.3](https://www.wolfssl.com/docs/tls13/)
+
+[wolfSSL Vulnerabilities]
+(https://www.wolfssl.com/docs/security-vulnerabilities/)
Index: azure_iot_hub_f767zi/trunk/wolfssl-4.4.0/cyassl/ctaocrypt/random.h
===================================================================
--- azure_iot_hub_f767zi/trunk/wolfssl-4.4.0/cyassl/ctaocrypt/random.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/wolfssl-4.4.0/cyassl/ctaocrypt/random.h	(revision 457)
@@ -0,0 +1,39 @@
+/* random.h
+ *
+ * Copyright (C) 2006-2020 wolfSSL Inc.
+ *
+ * This file is part of wolfSSL.
+ *
+ * wolfSSL is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * wolfSSL is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
+ */
+
+
+
+#ifndef CTAO_CRYPT_RANDOM_H
+#define CTAO_CRYPT_RANDOM_H
+
+    /* for random.h compatibility */
+    #include <wolfssl/wolfcrypt/random.h>
+    #define InitRng           wc_InitRng
+    #define RNG_GenerateBlock wc_RNG_GenerateBlock
+    #define RNG_GenerateByte  wc_RNG_GenerateByte
+    #define FreeRng        wc_FreeRng
+
+	#if defined(HAVE_HASHDRBG) || defined(NO_RC4)
+	    #define RNG_HealthTest wc_RNG_HealthTest
+	#endif /* HAVE_HASHDRBG || NO_RC4 */
+
+#endif /* CTAO_CRYPT_RANDOM_H */
+
Index: azure_iot_hub_f767zi/trunk/wolfssl-4.4.0/cyassl/ctaocrypt/settings.h
===================================================================
--- azure_iot_hub_f767zi/trunk/wolfssl-4.4.0/cyassl/ctaocrypt/settings.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/wolfssl-4.4.0/cyassl/ctaocrypt/settings.h	(revision 457)
@@ -0,0 +1,723 @@
+/* settings.h
+ *
+ * Copyright (C) 2006-2020 wolfSSL Inc.
+ *
+ * This file is part of wolfSSL.
+ *
+ * wolfSSL is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * wolfSSL is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
+ */
+
+
+/* Place OS specific preprocessor flags, defines, includes here, will be
+   included into every file because types.h includes it */
+
+
+#ifndef CTAO_CRYPT_SETTINGS_H
+#define CTAO_CRYPT_SETTINGS_H
+
+#ifdef __cplusplus
+    extern "C" {
+#endif
+
+/* Uncomment next line if using IPHONE */
+/* #define IPHONE */
+
+/* Uncomment next line if using ThreadX */
+/* #define THREADX */
+
+/* Uncomment next line if using Micrium ucOS */
+/* #define MICRIUM */
+
+/* Uncomment next line if using Mbed */
+/* #define MBED */
+
+/* Uncomment next line if using Microchip PIC32 ethernet starter kit */
+/* #define MICROCHIP_PIC32 */
+
+/* Uncomment next line if using Microchip TCP/IP stack, version 5 */
+/* #define MICROCHIP_TCPIP_V5 */
+
+/* Uncomment next line if using Microchip TCP/IP stack, version 6 or later */
+/* #define MICROCHIP_TCPIP */
+
+/* Uncomment next line if using PIC32MZ Crypto Engine */
+/* #define CYASSL_MICROCHIP_PIC32MZ */
+
+/* Uncomment next line if using FreeRTOS */
+/* #define FREERTOS */
+
+/* Uncomment next line if using FreeRTOS Windows Simulator */
+/* #define FREERTOS_WINSIM */
+
+/* Uncomment next line if using RTIP */
+/* #define EBSNET */
+
+/* Uncomment next line if using lwip */
+/* #define CYASSL_LWIP */
+
+/* Uncomment next line if building CyaSSL for a game console */
+/* #define CYASSL_GAME_BUILD */
+
+/* Uncomment next line if building CyaSSL for LSR */
+/* #define CYASSL_LSR */
+
+/* Uncomment next line if building CyaSSL for Freescale MQX/RTCS/MFS */
+/* #define FREESCALE_MQX */
+
+/* Uncomment next line if using STM32F2 */
+/* #define CYASSL_STM32F2 */
+
+/* Uncomment next line if using QL SEP settings */
+/* #define CYASSL_QL */
+
+/* Uncomment next line if building for EROAD */
+/* #define CYASSL_EROAD */
+
+/* Uncomment next line if building for IAR EWARM */
+/* #define CYASSL_IAR_ARM */
+
+/* Uncomment next line if using TI-RTOS settings */
+/* #define CYASSL_TIRTOS */
+
+/* Uncomment next line if building with PicoTCP */
+/* #define CYASSL_PICOTCP */
+
+/* Uncomment next line if building for PicoTCP demo bundle */
+/* #define CYASSL_PICOTCP_DEMO */
+
+#include <cyassl/ctaocrypt/visibility.h>
+
+#ifdef IPHONE
+    #define SIZEOF_LONG_LONG 8
+#endif
+
+
+#ifdef CYASSL_USER_SETTINGS
+    #include <user_settings.h>
+#endif
+
+/* for reverse compatibility after name change */
+#include <cyassl/ctaocrypt/settings_comp.h>
+
+#ifdef THREADX
+    #define SIZEOF_LONG_LONG 8
+#endif
+
+#ifdef HAVE_NETX
+    #include "nx_api.h"
+#endif
+
+#if defined(HAVE_LWIP_NATIVE) /* using LwIP native TCP socket */
+    #define CYASSL_LWIP
+    #define NO_WRITEV
+    #define SINGLE_THREADED
+    #define CYASSL_USER_IO
+    #define NO_FILESYSTEM
+#endif
+
+#if defined(CYASSL_IAR_ARM)
+    #define NO_MAIN_DRIVER
+    #define SINGLE_THREADED
+    #define USE_CERT_BUFFERS_1024
+    #define BENCH_EMBEDDED
+    #define NO_FILESYSTEM
+    #define NO_WRITEV
+    #define CYASSL_USER_IO
+    #define  BENCH_EMBEDDED
+#endif
+
+#ifdef MICROCHIP_PIC32
+    /* #define CYASSL_MICROCHIP_PIC32MZ */
+    #define SIZEOF_LONG_LONG 8
+    #define SINGLE_THREADED
+    #define CYASSL_USER_IO
+    #define NO_WRITEV
+    #define NO_DEV_RANDOM
+    #define NO_FILESYSTEM
+    #define USE_FAST_MATH
+    #define TFM_TIMING_RESISTANT
+#endif
+
+#if defined(CYASSL_MICROCHIP_PIC32MZ) || defined(WOLFSSL_MICROCHIP_PIC32MZ)
+    #ifndef NO_PIC32MZ_CRYPT
+        #define WOLFSSL_PIC32MZ_CRYPT
+    #endif
+    #ifndef NO_PIC32MZ_RNG
+        #define WOLFSSL_PIC32MZ_RNG
+    #endif
+    #ifndef NO_PIC32MZ_HASH
+        #define WOLFSSL_PIC32MZ_HASH
+    #endif
+
+    #define CYASSL_AES_COUNTER
+    #define HAVE_AESGCM
+    #define NO_BIG_INT
+#endif
+
+#ifdef MICROCHIP_TCPIP_V5
+    /* include timer functions */
+    #include "TCPIP Stack/TCPIP.h"
+#endif
+
+#ifdef MICROCHIP_TCPIP
+    /* include timer, NTP functions */
+    #ifdef MICROCHIP_MPLAB_HARMONY
+        #include "tcpip/tcpip.h"
+    #else
+        #include "system/system_services.h"
+        #include "tcpip/sntp.h"
+    #endif
+#endif
+
+#ifdef MBED
+    #define CYASSL_USER_IO
+    #define NO_FILESYSTEM
+    #define NO_CERTS
+    #define USE_CERT_BUFFERS_1024
+    #define NO_WRITEV
+    #define NO_DEV_RANDOM
+    #define NO_SHA512
+    #define NO_DH
+    #define NO_DSA
+    #define NO_HC128
+    #define HAVE_ECC
+    #define NO_SESSION_CACHE
+    #define CYASSL_CMSIS_RTOS
+#endif
+
+
+#ifdef CYASSL_EROAD
+    #define FREESCALE_MQX
+    #define FREESCALE_MMCAU
+    #define SINGLE_THREADED
+    #define NO_STDIO_FILESYSTEM
+    #define CYASSL_LEANPSK
+    #define HAVE_NULL_CIPHER
+    #define NO_OLD_TLS
+    #define NO_ASN
+    #define NO_BIG_INT
+    #define NO_RSA
+    #define NO_DSA
+    #define NO_DH
+    #define NO_CERTS
+    #define NO_PWDBASED
+    #define NO_DES3
+    #define NO_MD4
+    #define NO_RC4
+    #define NO_MD5
+    #define NO_SESSION_CACHE
+    #define NO_MAIN_DRIVER
+#endif
+
+#ifdef CYASSL_PICOTCP
+    #define errno pico_err
+    #include "pico_defines.h"
+    #include "pico_stack.h"
+    #include "pico_constants.h"
+    #define CUSTOM_RAND_GENERATE pico_rand
+#endif
+
+#ifdef CYASSL_PICOTCP_DEMO
+    #define CYASSL_STM32
+    #define USE_FAST_MATH
+    #define TFM_TIMING_RESISTANT
+    #define XMALLOC(s, h, type)  PICO_ZALLOC((s))
+    #define XFREE(p, h, type)    PICO_FREE((p))
+    #define SINGLE_THREADED
+    #define NO_WRITEV
+    #define CYASSL_USER_IO
+    #define NO_DEV_RANDOM
+    #define NO_FILESYSTEM
+#endif
+
+#ifdef FREERTOS_WINSIM
+    #define FREERTOS
+    #define USE_WINDOWS_API
+#endif
+
+
+/* Micrium will use Visual Studio for compilation but not the Win32 API */
+#if defined(_WIN32) && !defined(MICRIUM) && !defined(FREERTOS) \
+        && !defined(EBSNET) && !defined(CYASSL_EROAD) && !defined(INTIME_RTOS)
+    #define USE_WINDOWS_API
+#endif
+
+
+#if defined(CYASSL_LEANPSK) && !defined(XMALLOC_USER)
+    #include <stdlib.h>
+    #define XMALLOC(s, h, type)  malloc((s))
+    #define XFREE(p, h, type)    free((p))
+    #define XREALLOC(p, n, h, t) realloc((p), (n))
+#endif
+
+#if defined(XMALLOC_USER) && defined(SSN_BUILDING_LIBYASSL)
+    #undef  XMALLOC
+    #define XMALLOC     yaXMALLOC
+    #undef  XFREE
+    #define XFREE       yaXFREE
+    #undef  XREALLOC
+    #define XREALLOC    yaXREALLOC
+#endif
+
+
+#ifdef FREERTOS
+    #ifndef NO_WRITEV
+        #define NO_WRITEV
+    #endif
+    #ifndef NO_SHA512
+        #define NO_SHA512
+    #endif
+    #ifndef NO_DH
+        #define NO_DH
+    #endif
+    #ifndef NO_DSA
+        #define NO_DSA
+    #endif
+    #ifndef NO_HC128
+        #define NO_HC128
+    #endif
+
+    #ifndef SINGLE_THREADED
+        #include "FreeRTOS.h"
+        #include "semphr.h"
+    #endif
+#endif
+
+#ifdef CYASSL_TIRTOS
+    #define SIZEOF_LONG_LONG 8
+    #define NO_WRITEV
+    #define NO_CYASSL_DIR
+    #define USE_FAST_MATH
+    #define TFM_TIMING_RESISTANT
+    #define NO_DEV_RANDOM
+    #define NO_FILESYSTEM
+    #define USE_CERT_BUFFERS_2048
+    #define NO_ERROR_STRINGS
+    #define USER_TIME
+
+    #ifdef __IAR_SYSTEMS_ICC__
+        #pragma diag_suppress=Pa089
+    #elif !defined(__GNUC__)
+        /* Suppress the sslpro warning */
+        #pragma diag_suppress=11
+    #endif
+
+    #include <ti/ndk/nettools/mytime/mytime.h>
+#endif
+
+#ifdef EBSNET
+    #include "rtip.h"
+
+    /* #define DEBUG_CYASSL */
+    #define NO_CYASSL_DIR  /* tbd */
+
+    #if (POLLOS)
+        #define SINGLE_THREADED
+    #endif
+
+    #if (RTPLATFORM)
+        #if (!RTP_LITTLE_ENDIAN)
+            #define BIG_ENDIAN_ORDER
+        #endif
+    #else
+        #if (!KS_LITTLE_ENDIAN)
+            #define BIG_ENDIAN_ORDER
+        #endif
+    #endif
+
+    #if (WINMSP3)
+        #undef SIZEOF_LONG
+        #define SIZEOF_LONG_LONG 8
+    #else
+        #sslpro: settings.h - please implement SIZEOF_LONG and SIZEOF_LONG_LONG
+    #endif
+
+    #define XMALLOC(s, h, type) ((void *)rtp_malloc((s), SSL_PRO_MALLOC))
+    #define XFREE(p, h, type) (rtp_free(p))
+    #define XREALLOC(p, n, h, t) realloc((p), (n))
+
+#endif /* EBSNET */
+
+#ifdef CYASSL_GAME_BUILD
+    #define SIZEOF_LONG_LONG 8
+    #if defined(__PPU) || defined(__XENON)
+        #define BIG_ENDIAN_ORDER
+    #endif
+#endif
+
+#ifdef CYASSL_LSR
+    #define HAVE_WEBSERVER
+    #define SIZEOF_LONG_LONG 8
+    #define CYASSL_LOW_MEMORY
+    #define NO_WRITEV
+    #define NO_SHA512
+    #define NO_DH
+    #define NO_DSA
+    #define NO_HC128
+    #define NO_DEV_RANDOM
+    #define NO_CYASSL_DIR
+    #define NO_RABBIT
+    #ifndef NO_FILESYSTEM
+        #define LSR_FS
+        #include "inc/hw_types.h"
+        #include "fs.h"
+    #endif
+    #define CYASSL_LWIP
+    #include <errno.h>  /* for tcp errno */
+    #define CYASSL_SAFERTOS
+    #if defined(__IAR_SYSTEMS_ICC__)
+        /* enum uses enum */
+        #pragma diag_suppress=Pa089
+    #endif
+#endif
+
+#ifdef CYASSL_SAFERTOS
+    #ifndef SINGLE_THREADED
+        #include "SafeRTOS/semphr.h"
+    #endif
+
+    #include "SafeRTOS/heap.h"
+    #define XMALLOC(s, h, type)  pvPortMalloc((s))
+    #define XFREE(p, h, type)    vPortFree((p))
+    #define XREALLOC(p, n, h, t) pvPortRealloc((p), (n))
+#endif
+
+#ifdef CYASSL_LOW_MEMORY
+    #undef  RSA_LOW_MEM
+    #define RSA_LOW_MEM
+    #undef  CYASSL_SMALL_STACK
+    #define CYASSL_SMALL_STACK
+    #undef  TFM_TIMING_RESISTANT
+    #define TFM_TIMING_RESISTANT
+#endif
+
+#ifdef FREESCALE_MQX
+    #define SIZEOF_LONG_LONG 8
+    #define NO_WRITEV
+    #define NO_DEV_RANDOM
+    #define NO_RABBIT
+    #define NO_CYASSL_DIR
+    #define USE_FAST_MATH
+    #define TFM_TIMING_RESISTANT
+    #define FREESCALE_K70_RNGA
+    /* #define FREESCALE_K53_RNGB */
+    #include "mqx.h"
+    #ifndef NO_FILESYSTEM
+        #include "mfs.h"
+        #include "fio.h"
+    #endif
+    #ifndef SINGLE_THREADED
+        #include "mutex.h"
+    #endif
+
+    #define XMALLOC(s, h, t)    (void *)_mem_alloc_system((s))
+    #define XFREE(p, h, t)      {void* xp = (p); if ((xp)) _mem_free((xp));}
+    /* Note: MQX has no realloc, using fastmath above */
+#endif
+
+#ifdef CYASSL_STM32F2
+    #define SIZEOF_LONG_LONG 8
+    #define NO_DEV_RANDOM
+    #define NO_CYASSL_DIR
+    #define NO_RABBIT
+    #define STM32F2_RNG
+    #define STM32F2_CRYPTO
+    #define KEIL_INTRINSICS
+#endif
+
+#ifdef MICRIUM
+
+    #include "stdlib.h"
+    #include "net_cfg.h"
+    #include "ssl_cfg.h"
+    #include "net_secure_os.h"
+
+    #define CYASSL_TYPES
+
+    typedef CPU_INT08U byte;
+    typedef CPU_INT16U word16;
+    typedef CPU_INT32U word32;
+
+    #if (NET_SECURE_MGR_CFG_WORD_SIZE == CPU_WORD_SIZE_32)
+        #define SIZEOF_LONG        4
+        #undef  SIZEOF_LONG_LONG
+    #else
+        #undef  SIZEOF_LONG
+        #define SIZEOF_LONG_LONG   8
+    #endif
+
+    #define STRING_USER
+
+    #define XSTRLEN(pstr) ((CPU_SIZE_T)Str_Len((CPU_CHAR *)(pstr)))
+    #define XSTRNCPY(pstr_dest, pstr_src, len_max) \
+                    ((CPU_CHAR *)Str_Copy_N((CPU_CHAR *)(pstr_dest), \
+                     (CPU_CHAR *)(pstr_src), (CPU_SIZE_T)(len_max)))
+    #define XSTRNCMP(pstr_1, pstr_2, len_max) \
+                    ((CPU_INT16S)Str_Cmp_N((CPU_CHAR *)(pstr_1), \
+                     (CPU_CHAR *)(pstr_2), (CPU_SIZE_T)(len_max)))
+    #define XSTRSTR(pstr, pstr_srch) \
+                    ((CPU_CHAR *)Str_Str((CPU_CHAR *)(pstr), \
+                     (CPU_CHAR *)(pstr_srch)))
+    #define XMEMSET(pmem, data_val, size) \
+                    ((void)Mem_Set((void *)(pmem), (CPU_INT08U) (data_val), \
+                    (CPU_SIZE_T)(size)))
+    #define XMEMCPY(pdest, psrc, size) ((void)Mem_Copy((void *)(pdest), \
+                     (void *)(psrc), (CPU_SIZE_T)(size)))
+    #define XMEMCMP(pmem_1, pmem_2, size) \
+                   (((CPU_BOOLEAN)Mem_Cmp((void *)(pmem_1), (void *)(pmem_2), \
+                     (CPU_SIZE_T)(size))) ? DEF_NO : DEF_YES)
+    #define XMEMMOVE XMEMCPY
+
+#if (NET_SECURE_MGR_CFG_EN == DEF_ENABLED)
+    #define MICRIUM_MALLOC
+    #define XMALLOC(s, h, type) ((void *)NetSecure_BlkGet((CPU_INT08U)(type), \
+                                 (CPU_SIZE_T)(s), (void *)0))
+    #define XFREE(p, h, type)   (NetSecure_BlkFree((CPU_INT08U)(type), \
+                                 (p), (void *)0))
+    #define XREALLOC(p, n, h, t) realloc((p), (n))
+#endif
+
+    #if (NET_SECURE_MGR_CFG_FS_EN == DEF_ENABLED)
+        #undef  NO_FILESYSTEM
+    #else
+        #define NO_FILESYSTEM
+    #endif
+
+    #if (SSL_CFG_TRACE_LEVEL == CYASSL_TRACE_LEVEL_DBG)
+        #define DEBUG_CYASSL
+    #else
+        #undef  DEBUG_CYASSL
+    #endif
+
+    #if (SSL_CFG_OPENSSL_EN == DEF_ENABLED)
+        #define OPENSSL_EXTRA
+    #else
+        #undef  OPENSSL_EXTRA
+    #endif
+
+    #if (SSL_CFG_MULTI_THREAD_EN == DEF_ENABLED)
+        #undef  SINGLE_THREADED
+    #else
+        #define SINGLE_THREADED
+    #endif
+
+    #if (SSL_CFG_DH_EN == DEF_ENABLED)
+        #undef  NO_DH
+    #else
+        #define NO_DH
+    #endif
+
+    #if (SSL_CFG_DSA_EN == DEF_ENABLED)
+        #undef  NO_DSA
+    #else
+        #define NO_DSA
+    #endif
+
+    #if (SSL_CFG_PSK_EN == DEF_ENABLED)
+        #undef  NO_PSK
+    #else
+        #define NO_PSK
+    #endif
+
+    #if (SSL_CFG_3DES_EN == DEF_ENABLED)
+        #undef  NO_DES
+    #else
+        #define NO_DES
+    #endif
+
+    #if (SSL_CFG_AES_EN == DEF_ENABLED)
+        #undef  NO_AES
+    #else
+        #define NO_AES
+    #endif
+
+    #if (SSL_CFG_RC4_EN == DEF_ENABLED)
+        #undef  NO_RC4
+    #else
+        #define NO_RC4
+    #endif
+
+    #if (SSL_CFG_RABBIT_EN == DEF_ENABLED)
+        #undef  NO_RABBIT
+    #else
+        #define NO_RABBIT
+    #endif
+
+    #if (SSL_CFG_HC128_EN == DEF_ENABLED)
+        #undef  NO_HC128
+    #else
+        #define NO_HC128
+    #endif
+
+    #if (CPU_CFG_ENDIAN_TYPE == CPU_ENDIAN_TYPE_BIG)
+        #define BIG_ENDIAN_ORDER
+    #else
+        #undef  BIG_ENDIAN_ORDER
+        #define LITTLE_ENDIAN_ORDER
+    #endif
+
+    #if (SSL_CFG_MD4_EN == DEF_ENABLED)
+        #undef  NO_MD4
+    #else
+        #define NO_MD4
+    #endif
+
+    #if (SSL_CFG_WRITEV_EN == DEF_ENABLED)
+        #undef  NO_WRITEV
+    #else
+        #define NO_WRITEV
+    #endif
+
+    #if (SSL_CFG_USER_RNG_SEED_EN == DEF_ENABLED)
+        #define NO_DEV_RANDOM
+    #else
+        #undef  NO_DEV_RANDOM
+    #endif
+
+    #if (SSL_CFG_USER_IO_EN == DEF_ENABLED)
+        #define CYASSL_USER_IO
+    #else
+        #undef  CYASSL_USER_IO
+    #endif
+
+    #if (SSL_CFG_DYNAMIC_BUFFERS_EN == DEF_ENABLED)
+        #undef  LARGE_STATIC_BUFFERS
+        #undef  STATIC_CHUNKS_ONLY
+    #else
+        #define LARGE_STATIC_BUFFERS
+        #define STATIC_CHUNKS_ONLY
+    #endif
+
+    #if (SSL_CFG_DER_LOAD_EN == DEF_ENABLED)
+        #define  CYASSL_DER_LOAD
+    #else
+        #undef   CYASSL_DER_LOAD
+    #endif
+
+    #if (SSL_CFG_DTLS_EN == DEF_ENABLED)
+        #define  CYASSL_DTLS
+    #else
+        #undef   CYASSL_DTLS
+    #endif
+
+    #if (SSL_CFG_CALLBACKS_EN == DEF_ENABLED)
+         #define CYASSL_CALLBACKS
+    #else
+         #undef  CYASSL_CALLBACKS
+    #endif
+
+    #if (SSL_CFG_FAST_MATH_EN == DEF_ENABLED)
+         #define USE_FAST_MATH
+    #else
+         #undef  USE_FAST_MATH
+    #endif
+
+    #if (SSL_CFG_TFM_TIMING_RESISTANT_EN == DEF_ENABLED)
+         #define TFM_TIMING_RESISTANT
+    #else
+         #undef  TFM_TIMING_RESISTANT
+    #endif
+
+#endif /* MICRIUM */
+
+
+#ifdef CYASSL_QL
+    #ifndef CYASSL_SEP
+        #define CYASSL_SEP
+    #endif
+    #ifndef OPENSSL_EXTRA
+        #define OPENSSL_EXTRA
+    #endif
+    #ifndef SESSION_CERTS
+        #define SESSION_CERTS
+    #endif
+    #ifndef HAVE_AESCCM
+        #define HAVE_AESCCM
+    #endif
+    #ifndef ATOMIC_USER
+        #define ATOMIC_USER
+    #endif
+    #ifndef CYASSL_DER_LOAD
+        #define CYASSL_DER_LOAD
+    #endif
+    #ifndef KEEP_PEER_CERT
+        #define KEEP_PEER_CERT
+    #endif
+    #ifndef HAVE_ECC
+        #define HAVE_ECC
+    #endif
+    #ifndef SESSION_INDEX
+        #define SESSION_INDEX
+    #endif
+#endif /* CYASSL_QL */
+
+
+#if !defined(XMALLOC_USER) && !defined(MICRIUM_MALLOC) && \
+    !defined(CYASSL_LEANPSK) && !defined(NO_CYASSL_MEMORY)
+    #define USE_CYASSL_MEMORY
+#endif
+
+
+#if defined(OPENSSL_EXTRA) && !defined(NO_CERTS)
+    #undef  KEEP_PEER_CERT
+    #define KEEP_PEER_CERT
+#endif
+
+
+/* stream ciphers except arc4 need 32bit alignment, intel ok without */
+#ifndef XSTREAM_ALIGNMENT
+    #if defined(__x86_64__) || defined(__ia64__) || defined(__i386__)
+        #define NO_XSTREAM_ALIGNMENT
+    #else
+        #define XSTREAM_ALIGNMENT
+    #endif
+#endif
+
+
+/* FreeScale MMCAU hardware crypto has 4 byte alignment */
+#ifdef FREESCALE_MMCAU
+    #define CYASSL_MMCAU_ALIGNMENT 4
+#endif
+
+/* if using hardware crypto and have alignment requirements, specify the
+   requirement here.  The record header of SSL/TLS will prvent easy alignment.
+   This hint tries to help as much as possible.  */
+#ifndef CYASSL_GENERAL_ALIGNMENT
+    #ifdef CYASSL_AESNI
+        #define CYASSL_GENERAL_ALIGNMENT 16
+    #elif defined(XSTREAM_ALIGNMENT)
+        #define CYASSL_GENERAL_ALIGNMENT  4
+    #elif defined(FREESCALE_MMCAU)
+        #define CYASSL_GENERAL_ALIGNMENT  CYASSL_MMCAU_ALIGNMENT
+    #else
+        #define CYASSL_GENERAL_ALIGNMENT  0
+    #endif
+#endif
+
+
+#ifdef __INTEL_COMPILER
+    #pragma warning(disable:2259) /* explicit casts to smaller sizes, disable */
+#endif
+
+
+/* Place any other flags or defines here */
+
+
+#ifdef __cplusplus
+    }   /* extern "C" */
+#endif
+
+
+#endif /* CTAO_CRYPT_SETTINGS_H */
Index: azure_iot_hub_f767zi/trunk/wolfssl-4.4.0/cyassl/ctaocrypt/settings_comp.h
===================================================================
--- azure_iot_hub_f767zi/trunk/wolfssl-4.4.0/cyassl/ctaocrypt/settings_comp.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/wolfssl-4.4.0/cyassl/ctaocrypt/settings_comp.h	(revision 457)
@@ -0,0 +1,72 @@
+/* settings_comp.h
+ *
+ * Copyright (C) 2006-2020 wolfSSL Inc.
+ *
+ * This file is part of wolfSSL.
+ *
+ * wolfSSL is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * wolfSSL is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
+ */
+
+
+#ifndef CTAO_CRYPT_SETTINGS_C_H
+#define CTAO_CRYPT_SETTINGS_C_H
+
+
+/* since fips overrides rsa.h map compatibility here */
+#if !defined(NO_RSA)
+	#ifdef WOLFSSL_KEY_GEN
+	    #define RsaKeyToDer wc_RsaKeyToDer
+	#endif
+
+	#define RsaPrivateKeyDecode   wc_RsaPrivateKeyDecode
+	#define RsaPublicKeyDecode    wc_RsaPublicKeyDecode
+	#define RsaPublicKeyDecodeRaw wc_RsaPublicKeyDecodeRaw
+#endif /* have rsa and HAVE_FIPS */
+
+/* Macro redefinitions for compatibility */
+#ifdef HAVE_NTRU
+    #define MakeNtruCert wc_MakeNtruCert
+#endif
+#if defined(WOLFSSL_SHA512) && !defined(CYASSL_SHA512)
+    #define CYASSL_SHA512
+#endif
+#if defined(WOLFSSL_SHA384) && !defined(CYASSL_SHA384)
+    #define CYASSL_SHA384
+#endif
+#if defined(WOLFSSL_LEANPSK) && !defined(CYASSL_LEANPSK)
+    #define CYASSL_LEANPSK
+#endif
+#if defined(NO_WOLFSSL_MEMORY) && !defined(NO_CYASSL_MEMORY)
+    #define NO_CYASSL_MEMORY
+#endif
+#if defined(WOLFSSL_KEY_GEN) && !defined(CYASSL_KEY_GEN)
+    #define CYASSL_KEY_GEN
+#endif
+
+/* AES */
+#if defined(WOLFSSL_AES_DIRECT) && !defined(CYASSL_AES_DIRECT)
+    #define CYASSL_AES_DIRECT
+#endif
+#if defined(WOLFSSL_AES_COUNTER) && !defined(CYASSL_AES_COUNTER)
+    #define CYASSL_AES_COUNTER
+#endif
+
+/* DES */
+#if defined(WOLFSSL_DES_ECB) && !defined(CYASSL_DES_ECB)
+    #define CYASSL_DES_ECB
+#endif
+
+#endif /* CTAO_CRYPT_SETTINGS_C_H */
+
Index: azure_iot_hub_f767zi/trunk/wolfssl-4.4.0/cyassl/ctaocrypt/sha256.h
===================================================================
--- azure_iot_hub_f767zi/trunk/wolfssl-4.4.0/cyassl/ctaocrypt/sha256.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/wolfssl-4.4.0/cyassl/ctaocrypt/sha256.h	(revision 457)
@@ -0,0 +1,46 @@
+/* sha256.h
+ *
+ * Copyright (C) 2006-2020 wolfSSL Inc.
+ *
+ * This file is part of wolfSSL.
+ *
+ * wolfSSL is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * wolfSSL is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
+ */
+
+
+
+
+
+#ifndef NO_SHA256
+
+#ifndef CTAO_CRYPT_SHA256_H
+#define CTAO_CRYPT_SHA256_H
+
+#include <wolfssl/wolfcrypt/sha256.h>
+#define InitSha256   wc_InitSha256
+#define Sha256Update wc_Sha256Update
+#define Sha256Final  wc_Sha256Final
+#define Sha256Hash   wc_Sha256Hash
+
+#ifdef WOLFSSL_SHA224
+    #define InitSha224   wc_InitSha224
+    #define Sha224Update wc_Sha224Update
+    #define Sha224Final  wc_Sha224Final
+    #define Sha224Hash   wc_Sha224Hash
+#endif
+
+#endif /* CTAO_CRYPT_SHA256_H */
+#endif /* NO_SHA256 */
+
Index: azure_iot_hub_f767zi/trunk/wolfssl-4.4.0/cyassl/ctaocrypt/types.h
===================================================================
--- azure_iot_hub_f767zi/trunk/wolfssl-4.4.0/cyassl/ctaocrypt/types.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/wolfssl-4.4.0/cyassl/ctaocrypt/types.h	(revision 457)
@@ -0,0 +1,39 @@
+/* types.h
+ *
+ * Copyright (C) 2006-2020 wolfSSL Inc.
+ *
+ * This file is part of wolfSSL.
+ *
+ * wolfSSL is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * wolfSSL is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
+ */
+
+
+
+#ifndef CTAO_CRYPT_TYPES_H
+#define CTAO_CRYPT_TYPES_H
+
+#include <cyassl/ctaocrypt/wc_port.h>
+#include <cyassl/ctaocrypt/settings.h>
+#include <wolfssl/wolfcrypt/types.h>
+
+/* compatibility macros */
+#define CYASSL_WORD_SIZE    WOLFSSL_WORD_SIZE
+#define CYASSL_BIT_SIZE     WOLFSSL_BIT_SIZE
+#define CYASSL_MAX_16BIT    WOLFSSL_MAX_16BIT
+#define CYASSL_MAX_ERROR_SZ WOLFSSL_MAX_ERROR_SZ
+#define cyassl_word         wolfssl_word
+
+#endif /* CTAO_CRYPT_TYPES_H */
+
Index: azure_iot_hub_f767zi/trunk/wolfssl-4.4.0/cyassl/ctaocrypt/visibility.h
===================================================================
--- azure_iot_hub_f767zi/trunk/wolfssl-4.4.0/cyassl/ctaocrypt/visibility.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/wolfssl-4.4.0/cyassl/ctaocrypt/visibility.h	(revision 457)
@@ -0,0 +1,73 @@
+/* visibility.h
+ *
+ * Copyright (C) 2006-2020 wolfSSL Inc.
+ *
+ * This file is part of wolfSSL.
+ *
+ * wolfSSL is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * wolfSSL is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
+ */
+
+
+/* Visibility control macros */
+
+#ifndef CTAO_CRYPT_VISIBILITY_H
+#define CTAO_CRYPT_VISIBILITY_H
+
+/* fips compatibility @wc_fips */
+#ifndef HAVE_FIPS
+    #include <wolfssl/wolfcrypt/visibility.h>
+    #define CYASSL_API   WOLFSSL_API
+	#define CYASSL_LOCAL WOLFSSL_LOCAL
+#else
+/* CYASSL_API is used for the public API symbols.
+        It either imports or exports (or does nothing for static builds)
+
+   CYASSL_LOCAL is used for non-API symbols (private).
+*/
+
+#if defined(BUILDING_WOLFSSL)
+    #if defined(HAVE_VISIBILITY) && HAVE_VISIBILITY
+        #define CYASSL_API   __attribute__ ((visibility("default")))
+        #define CYASSL_LOCAL __attribute__ ((visibility("hidden")))
+    #elif defined(__SUNPRO_C) && (__SUNPRO_C >= 0x550)
+        #define CYASSL_API   __global
+        #define CYASSL_LOCAL __hidden
+    #elif defined(_MSC_VER)
+        #ifdef CYASSL_DLL
+            #define CYASSL_API extern __declspec(dllexport)
+        #else
+            #define CYASSL_API
+        #endif
+        #define CYASSL_LOCAL
+    #else
+        #define CYASSL_API
+        #define CYASSL_LOCAL
+    #endif /* HAVE_VISIBILITY */
+#else /* BUILDING_WOLFSSL */
+    #if defined(_MSC_VER)
+        #ifdef CYASSL_DLL
+            #define CYASSL_API extern __declspec(dllimport)
+        #else
+            #define CYASSL_API
+        #endif
+        #define CYASSL_LOCAL
+    #else
+        #define CYASSL_API
+        #define CYASSL_LOCAL
+    #endif
+#endif /* BUILDING_WOLFSSL */
+#endif /* HAVE_FIPS */
+#endif /* CTAO_CRYPT_VISIBILITY_H */
+
Index: azure_iot_hub_f767zi/trunk/wolfssl-4.4.0/cyassl/ctaocrypt/wc_port.h
===================================================================
--- azure_iot_hub_f767zi/trunk/wolfssl-4.4.0/cyassl/ctaocrypt/wc_port.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/wolfssl-4.4.0/cyassl/ctaocrypt/wc_port.h	(revision 457)
@@ -0,0 +1,32 @@
+/* port.h
+ *
+ * Copyright (C) 2006-2020 wolfSSL Inc.
+ *
+ * This file is part of wolfSSL.
+ *
+ * wolfSSL is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * wolfSSL is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
+ */
+
+
+
+#ifndef CTAO_CRYPT_PORT_H
+#define CTAO_CRYPT_PORT_H
+
+#include <cyassl/ctaocrypt/visibility.h>
+#include <wolfssl/wolfcrypt/wc_port.h>
+#define CyaSSL_Mutex wolfSSL_Mutex
+
+#endif /* CTAO_CRYPT_PORT_H */
+
Index: azure_iot_hub_f767zi/trunk/wolfssl-4.4.0/cyassl/error-ssl.h
===================================================================
--- azure_iot_hub_f767zi/trunk/wolfssl-4.4.0/cyassl/error-ssl.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/wolfssl-4.4.0/cyassl/error-ssl.h	(revision 457)
@@ -0,0 +1,23 @@
+/* error-ssl.h
+ *
+ * Copyright (C) 2006-2020 wolfSSL Inc.
+ *
+ * This file is part of wolfSSL.
+ *
+ * wolfSSL is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * wolfSSL is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
+ */
+
+
+#include <wolfssl/error-ssl.h>
Index: azure_iot_hub_f767zi/trunk/wolfssl-4.4.0/cyassl/openssl/evp.h
===================================================================
--- azure_iot_hub_f767zi/trunk/wolfssl-4.4.0/cyassl/openssl/evp.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/wolfssl-4.4.0/cyassl/openssl/evp.h	(revision 457)
@@ -0,0 +1,41 @@
+/* evp.h
+ *
+ * Copyright (C) 2006-2020 wolfSSL Inc.
+ *
+ * This file is part of wolfSSL.
+ *
+ * wolfSSL is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * wolfSSL is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
+ */
+
+
+
+/*  evp.h defines mini evp openssl compatibility layer
+ *
+ */
+
+#ifndef CYASSL_OPENSSL_EVP
+#define CYASSL_OPENSSL_EVP
+
+#define CyaSSL_StoreExternalIV       wolfSSL_StoreExternalIV
+#define CyaSSL_SetInternalIV         wolfSSL_SetInternalIV
+#define CYASSL_EVP_MD                WOLFSSL_EVP_MD
+#define CyaSSL_EVP_X_STATE           wolfSSL_EVP_X_STATE
+#define CyaSSL_EVP_X_STATE_LEN       wolfSSL_EVP_X_STATE_LEN
+#define CyaSSL_3des_iv               wolfSSL_3des_iv
+#define CyaSSL_aes_ctr_iv            wolfSSL_aes_ctr_iv
+
+#include <wolfssl/openssl/evp.h>
+#endif
+
Index: azure_iot_hub_f767zi/trunk/wolfssl-4.4.0/cyassl/openssl/ssl.h
===================================================================
--- azure_iot_hub_f767zi/trunk/wolfssl-4.4.0/cyassl/openssl/ssl.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/wolfssl-4.4.0/cyassl/openssl/ssl.h	(revision 457)
@@ -0,0 +1,34 @@
+/* ssl.h
+ *
+ * Copyright (C) 2006-2020 wolfSSL Inc.
+ *
+ * This file is part of wolfSSL.
+ *
+ * wolfSSL is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * wolfSSL is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
+ */
+
+
+
+/*  ssl.h defines openssl compatibility layer
+ *
+ */
+#ifndef CYASSL_OPENSSL_H_
+#define CYASSL_OPENSSL_H_
+
+#include <cyassl/ssl.h>
+#include <wolfssl/openssl/ssl.h>
+
+#endif
+
Index: azure_iot_hub_f767zi/trunk/wolfssl-4.4.0/cyassl/ssl.h
===================================================================
--- azure_iot_hub_f767zi/trunk/wolfssl-4.4.0/cyassl/ssl.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/wolfssl-4.4.0/cyassl/ssl.h	(revision 457)
@@ -0,0 +1,721 @@
+/* ssl.h
+ *
+ * Copyright (C) 2006-2020 wolfSSL Inc.
+ *
+ * This file is part of wolfSSL.
+ *
+ * wolfSSL is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * wolfSSL is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
+ */
+
+
+/*
+ * ssl.h makes wolfssl backwards compatible with cyassl
+ */
+
+#ifndef WOLFSSL_CYASSL_H_
+#define WOLFSSL_CYASSL_H_
+/*
+ * Name change
+ * include the new ssl.h
+ */
+#include <wolfssl/ssl.h>
+#include <cyassl/ctaocrypt/types.h>
+#include <cyassl/ctaocrypt/settings.h>
+
+#ifdef __cplusplus
+    extern "C" {
+#endif
+
+#ifdef _WIN32
+    /* wincrypt.h clashes */
+    #undef X509_NAME
+#endif
+
+#ifdef CYASSL_TIRTOS
+    #undef CYASSL_TIRTOS
+    #define CYASSL_TIRTOS WOLFSSL_TIRTOS
+#endif
+
+#define CYASSL          WOLFSSL
+#define DEBUG_CYASSL    DEBUG_WOLFSSL
+#define CYASSL_CTX      WOLFSSL_CTX
+#define CYASSL_METHOD   WOLFSSL_METHOD
+#define CYASSL_SESSION  WOLFSSL_SESSION
+
+#define CYASSL_X509       WOLFSSL_X509
+#define CYASSL_X509_NAME  WOLFSSL_X509_NAME
+#define CYASSL_X509_CHAIN WOLFSSL_X509_CHAIN
+#ifdef WOLFSSL_SNIFFER
+    #define CYASSL_SNIFFER    WOLFSSL_SNIFFER
+#endif
+
+/* redeclare guard */
+#define CYASSL_TYPES_DEFINED WOLFSSL_TYPES_DEFINED
+
+/* legacy defines */
+#define yasslIP          wolfSSLIP                                         /**/
+#define yasslPort        wolfSSLPort                                       /**/
+
+/* cyassl/ssl.h (structs) */
+#define CYASSL_RSA                WOLFSSL_RSA
+#define CYASSL_DSA                WOLFSSL_DSA
+#define CYASSL_BIO                WOLFSSL_BIO
+#define CYASSL_CIPHER             WOLFSSL_CIPHER
+#define CYASSL_MD4_CTX            WOLFSSL_MD4_CTX
+#define CYASSL_MFL_2_9            WOLFSSL_MFL_2_9                          /**/
+#define CYASSL_MFL_2_13           WOLFSSL_MFL_2_13                         /**/
+#define CYASSL_EVP_PKEY           WOLFSSL_EVP_PKEY
+#define CYASSL_X509_CRL           WOLFSSL_X509_CRL
+#define CYASSL_ASN1_TIME          WOLFSSL_ASN1_TIME
+#define CYASSL_BIO_METHOD         WOLFSSL_BIO_METHOD
+#define CYASSL_X509_STORE         WOLFSSL_X509_STORE
+#define CYASSL_X509_OBJECT        WOLFSSL_X509_OBJECT
+#define CYASSL_X509_LOOKUP        WOLFSSL_X509_LOOKUP
+#define CYASSL_ASN1_OBJECT        WOLFSSL_ASN1_OBJECT
+#define CYASSL_ASN1_STRING        WOLFSSL_ASN1_STRING
+#define CYASSL_COMP_METHOD        WOLFSSL_COMP_METHOD
+#define CYASSL_CRL_CHECKALL       WOLFSSL_CRL_CHECKALL
+#define CYASSL_ASN1_INTEGER       WOLFSSL_ASN1_INTEGER
+#define CYASSL_X509_REVOKED       WOLFSSL_X509_REVOKED
+#define CYASSL_dynlock_value      WOLFSSL_dynlock_value
+#define CYASSL_X509_EXTENSION     WOLFSSL_X509_EXTENSION
+#define CYASSL_X509_STORE_CTX     WOLFSSL_X509_STORE_CTX
+#define CYASSL_X509_LOOKUP_METHOD WOLFSSL_X509_LOOKUP_METHOD
+
+#define CyaSSL_LoadCRL            wolfSSL_LoadCRL
+#define CyaSSL_EnableCRL          wolfSSL_EnableCRL
+#define CyaSSL_SetCRL_Cb          wolfSSL_SetCRL_Cb
+
+/* cyassl/test.h */
+#ifdef CyaSSL_TEST_H
+    #define CYASSL_THREAD         WOLFSSL_THREAD
+#endif
+
+/* src/ssl.c */
+#define CYASSL_CRL                       WOLFSSL_CRL
+#define CYASSL_SSLV3                     WOLFSSL_SSLV3
+#define CYASSL_TLSV1                     WOLFSSL_TLSV1
+#define CYASSL_TLSV1_1                   WOLFSSL_TLSV1_1
+#define CYASSL_TLSV1_2                   WOLFSSL_TLSV1_2
+#define CYASSL_USER_CA                   WOLFSSL_USER_CA
+#define CYASSL_CLIENT_END                WOLFSSL_CLIENT_END
+#define CYASSL_CERT_MANAGER              WOLFSSL_CERT_MANAGER
+#define MAX_CYASSL_FILE_SIZE             MAX_WOLFSSL_FILE_SIZE
+
+#define CyaSSL_get_cipher                wolfSSL_get_cipher
+#define CyaSSL_get_ciphers               wolfSSL_get_ciphers
+#define CyaSSL_KeyPemToDer               wolfSSL_KeyPemToDer
+#define CyaSSL_get_version               wolfSSL_get_version
+#define CyaSSL_SetServerID               wolfSSL_SetServerID
+#define CyaSSL_use_old_poly              wolfSSL_use_old_poly
+#define CyaSSL_SetCertCbCtx              wolfSSL_SetCertCbCtx
+#define CyaSSL_CertPemToDer              wolfSSL_CertPemToDer
+#define CyaSSL_get_shutdown              wolfSSL_get_shutdown
+#define CyaSSL_SetMinVersion             wolfSSL_SetMinVersion
+#define CyaSSL_CTX_UnloadCAs             wolfSSL_CTX_UnloadCAs
+#define CyaSSL_session_reused            wolfSSL_session_reused
+#define CyaSSL_UnloadCertsKeys           wolfSSL_UnloadCertsKeys
+#define CyaSSL_CIPHER_get_name           wolfSSL_CIPHER_get_name
+#define CyaSSL_is_init_finished          wolfSSL_is_init_finished
+#define CyaSSL_get_alert_history         wolfSSL_get_alert_history
+#define CyaSSL_get_current_cipher        wolfSSL_get_current_cipher
+#define CyaSSL_CertManagerUnloadCAs      wolfSSL_CertManagerUnloadCAs
+#define CyaSSL_CertManagerEnableOCSP     wolfSSL_CertManagerEnableOCSP
+#define CyaSSL_CTX_check_private_key     wolfSSL_CTX_check_private_key
+#define CyaSSL_CertManagerDisableOCSP    wolfSSL_CertManagerDisableOCSP
+#define CyaSSL_get_current_cipher_suite  wolfSSL_get_current_cipher_suite
+#define CyaSSL_CTX_load_verify_locations wolfSSL_CTX_load_verify_locations
+#define CyaSSL_CTX_set_default_passwd_cb wolfSSL_CTX_set_default_passwd_cb
+
+#define CyaSSL_save_session_cache        wolfSSL_save_session_cache
+#define CyaSSL_restore_session_cache     wolfSSL_restore_session_cache
+#define CyaSSL_memsave_session_cache     wolfSSL_memsave_session_cache
+#define CyaSSL_memrestore_session_cache  wolfSSL_memrestore_session_cache
+#define CyaSSL_get_session_cache_memsize wolfSSL_get_session_cache_memsize
+
+/* certificate cache persistence, uses ctx since certs are per ctx */
+#define CyaSSL_CTX_save_cert_cache        wolfSSL_CTX_save_cert_cache
+#define CyaSSL_CTX_restore_cert_cache     wolfSSL_CTX_restore_cert_cache
+#define CyaSSL_CTX_memsave_cert_cache     wolfSSL_CTX_memsave_cert_cache
+#define CyaSSL_CTX_memrestore_cert_cache  wolfSSL_CTX_memrestore_cert_cache
+#define CyaSSL_CTX_get_cert_cache_memsize wolfSSL_CTX_get_cert_cache_memsize
+
+/* wolfSSL extensions */
+/* get wolfSSL peer X509_CHAIN */
+#define CyaSSL_get_chain_count wolfSSL_get_chain_count
+/* index cert length */
+#define CyaSSL_get_chain_length wolfSSL_get_chain_length
+/* index cert in X509 */
+#define CyaSSL_get_chain_X509 wolfSSL_get_chain_X509
+/* free X509 */
+#define CyaSSL_FreeX509 wolfSSL_FreeX509
+/* get index cert in PEM */
+#define CyaSSL_X509_get_subjectCN wolfSSL_X509_get_subjectCN
+#define CyaSSL_X509_get_der       wolfSSL_X509_get_der
+#define CyaSSL_X509_notBefore     wolfSSL_X509_notBefore
+#define CyaSSL_X509_notAfter      wolfSSL_X509_notAfter
+#define CyaSSL_X509_get_notBefore wolfSSL_X509_get_notBefore
+#define CyaSSL_X509_get_notAfter  wolfSSL_X509_get_notAfter
+#define CyaSSL_X509_version       wolfSSL_X509_version
+
+#define CyaSSL_cmp_peer_cert_to_file wolfSSL_cmp_peer_cert_to_file
+
+#define CyaSSL_X509_get_next_altname wolfSSL_X509_get_next_altname
+
+#define CyaSSL_X509_d2i wolfSSL_X509_d2i
+#ifndef NO_FILESYSTEM
+    #ifndef NO_STDIO_FILESYSTEM
+        #define CyaSSL_X509_d2i_fp wolfSSL_X509_d2i_fp
+    #endif
+#define CyaSSL_X509_load_certificate_file wolfSSL_X509_load_certificate_file
+#endif
+
+#ifdef WOLFSSL_SEP
+#define CyaSSL_X509_get_device_type      wolfSSL_X509_get_device_type
+#define CyaSSL_X509_get_hw_type          wolfSSL_X509_get_hw_type
+#define CyaSSL_X509_get_hw_serial_number wolfSSL_X509_get_hw_serial_number
+#endif
+
+#define CyaSSL_CTX_SetGenCookie wolfSSL_CTX_SetGenCookie
+#define CyaSSL_SetCookieCtx     wolfSSL_SetCookieCtx
+#define CyaSSL_GetCookieCtx     wolfSSL_GetCookieCtx
+#define CyaSSL_ERR_get_error_line_data wolfSSL_ERR_get_error_line_data
+#define CyaSSL_ERR_get_error           wolfSSL_ERR_get_error
+#define CyaSSL_ERR_clear_error         wolfSSL_ERR_clear_error
+#define CyaSSL_RAND_status             wolfSSL_RAND_status
+#define CyaSSL_RAND_bytes              wolfSSL_RAND_bytes
+#define CyaSSL_CTX_set_options         wolfSSL_CTX_set_options
+#define CyaSSL_ERR_free_strings        wolfSSL_ERR_free_strings
+#define CyaSSL_ERR_remove_state        wolfSSL_ERR_remove_state
+#define CyaSSL_EVP_cleanup             wolfSSL_EVP_cleanup
+#define CyaSSL_cleanup_all_ex_data     wolfSSL_cleanup_all_ex_data
+#define CyaSSL_CTX_set_mode            wolfSSL_CTX_set_mode
+#define CyaSSL_CTX_get_mode            wolfSSL_CTX_get_mode
+#define CyaSSL_CTX_set_default_read_ahead   wolfSSL_CTX_set_default_read_ahead
+#define CyaSSL_CTX_sess_set_cache_size      wolfSSL_CTX_sess_set_cache_size
+#define CyaSSL_CTX_set_default_verify_paths wolfSSL_CTX_set_default_verify_paths
+#define CyaSSL_CTX_set_session_id_context   wolfSSL_CTX_set_session_id_context
+#define CyaSSL_get_peer_certificate         wolfSSL_get_peer_certificate
+#define CyaSSL_BIO_printf                   wolfSSL_BIO_printf
+#define CyaSSL_ASN1_UTCTIME_print           wolfSSL_ASN1_UTCTIME_print
+#define CyaSSL_sk_num                       wolfSSL_sk_num
+#define CyaSSL_sk_value                     wolfSSL_sk_value
+
+/* stunnel 4.28 needs */
+#define CyaSSL_CTX_get_ex_data        wolfSSL_CTX_get_ex_data
+#define CyaSSL_CTX_set_ex_data        wolfSSL_CTX_set_ex_data
+#define CyaSSL_CTX_sess_set_get_cb    wolfSSL_CTX_sess_set_get_cb
+#define CyaSSL_CTX_sess_set_new_cb    wolfSSL_CTX_sess_set_new_cb
+#define CyaSSL_CTX_sess_set_remove_cb wolfSSL_CTX_sess_set_remove_cb
+
+#define CyaSSL_i2d_SSL_SESSION wolfSSL_i2d_SSL_SESSION
+#define CyaSSL_d2i_SSL_SESSION wolfSSL_d2i_SSL_SESSION
+
+#define CyaSSL_SESSION_get_timeout  wolfSSL_SESSION_get_timeout
+#define CyaSSL_SESSION_get_time     wolfSSL_SESSION_get_time
+#define CyaSSL_CTX_get_ex_new_index wolfSSL_CTX_get_ex_new_index
+
+
+/* wolfio.c */
+#define CYASSL_CBIO_ERR_ISR        WOLFSSL_CBIO_ERR_ISR
+#define CYASSL_CBIO_ERR_TIMEOUT    WOLFSSL_CBIO_ERR_TIMEOUT
+#define CYASSL_CBIO_ERR_GENERAL    WOLFSSL_CBIO_ERR_GENERAL
+#define CYASSL_CBIO_ERR_CONN_RST   WOLFSSL_CBIO_ERR_CONN_RST
+#define CYASSL_CBIO_ERR_WANT_READ  WOLFSSL_CBIO_ERR_WANT_READ
+#define CYASSL_CBIO_ERR_WANT_WRITE WOLFSSL_CBIO_ERR_WANT_WRITE
+#define CYASSL_CBIO_ERR_CONN_CLOSE WOLFSSL_CBIO_ERR_CONN_CLOSE
+
+#define CyaSSL_GetIOReadCtx        wolfSSL_GetIOReadCtx
+#define CyaSSL_GetIOWriteCtx       wolfSSL_GetIOWriteCtx
+
+/* src/tls.c */
+#define CYASSL_SERVER_END          WOLFSSL_SERVER_END
+#define CYASSL_TLS_HMAC_INNER_SZ   WOLFSSL_TLS_HMAC_INNER_SZ
+
+#define CyaSSL_DeriveTlsKeys       wolfSSL_DeriveTlsKeys
+#define CyaSSL_make_eap_keys       wolfSSL_make_eap_keys
+#define CyaSSL_MakeTlsMasterSecret wolfSSL_MakeTlsMasterSecret
+
+/* src/internal.c */
+#define CYASSL_CHAIN_CA                WOLFSSL_CHAIN_CA
+#define CYASSL_ALERT_HISTORY           WOLFSSL_ALERT_HISTORY
+#define CYASSL_SESSION_TIMEOUT         WOLFSSL_SESSION_TIMEOUT
+#define CYASSL_CBIO_ERR_CONN_RST       WOLFSSL_CBIO_ERR_CONN_RST
+
+#define cyassl_rc4                     wolfssl_rc4
+#define cyassl_aes                     wolfssl_aes
+#define cyassl_chacha                  wolfssl_chacha
+#define CyaSSL_ERR_reason_error_string wolfSSL_ERR_reason_error_string
+
+#define CyaSSL_set_ex_data  wolfSSL_set_ex_data
+#define CyaSSL_get_shutdown wolfSSL_get_shutdown
+#define CyaSSL_set_rfd      wolfSSL_set_rfd
+#define CyaSSL_set_wfd      wolfSSL_set_wfd
+#define CyaSSL_set_shutdown wolfSSL_set_shutdown
+#define CyaSSL_set_session_id_context wolfSSL_set_session_id_context
+#define CyaSSL_set_connect_state      wolfSSL_set_connect_state
+#define CyaSSL_set_accept_state       wolfSSL_set_accept_state
+#define CyaSSL_session_reused         wolfSSL_session_reused
+#define CyaSSL_SESSION_free           wolfSSL_SESSION_free
+#define CyaSSL_is_init_finished       wolfSSL_is_init_finished
+
+#define CyaSSL_get_version              wolfSSL_get_version
+#define CyaSSL_get_current_cipher_suite wolfSSL_get_current_cipher_suite
+#define CyaSSL_get_current_cipher       wolfSSL_get_current_cipher
+#define CyaSSL_CIPHER_description       wolfSSL_CIPHER_description
+#define CyaSSL_CIPHER_get_name          wolfSSL_CIPHER_get_name
+#define CyaSSL_get_cipher               wolfSSL_get_cipher
+#define CyaSSL_get1_session             wolfSSL_get1_session
+
+#define CyaSSL_X509_free      wolfSSL_X509_free
+#define CyaSSL_OPENSSL_free   wolfSSL_OPENSSL_free
+#define CyaSSL_OCSP_parse_url wolfSSL_OCSP_parse_url
+
+#define CyaSSLv23_client_method wolfSSLv23_client_method
+#define CyaSSLv2_client_method  wolfSSLv2_client_method
+#define CyaSSLv2_server_method  wolfSSLv2_server_method
+
+#define CyaSSL_MD4_Init     wolfSSL_MD4_Init
+#define CyaSSL_MD4_Update   wolfSSL_MD4_Update
+#define CyaSSL_MD4_Final    wolfSSL_MD4_Final
+
+
+#define CyaSSL_BIO_new      wolfSSL_BIO_new
+#define CyaSSL_BIO_free     wolfSSL_BIO_free
+#define CyaSSL_BIO_free_all wolfSSL_BIO_free_all
+#define CyaSSL_BIO_read     wolfSSL_BIO_read
+#define CyaSSL_BIO_write    wolfSSL_BIO_write
+#define CyaSSL_BIO_push     wolfSSL_BIO_push
+#define CyaSSL_BIO_pop      wolfSSL_BIO_pop
+#define CyaSSL_BIO_flush    wolfSSL_BIO_flush
+#define CyaSSL_BIO_pending  wolfSSL_BIO_pending
+
+#define CyaSSL_BIO_f_buffer              wolfSSL_BIO_f_buffer
+#define CyaSSL_BIO_set_write_buffer_size wolfSSL_BIO_set_write_buffer_size
+#define CyaSSL_BIO_f_ssl                 wolfSSL_BIO_f_ssl
+#define CyaSSL_BIO_new_socket            wolfSSL_BIO_new_socket
+#define CyaSSL_BIO_eof                   wolfSSL_BIO_eof
+
+#define CyaSSL_BIO_s_mem        wolfSSL_BIO_s_mem
+#define CyaSSL_BIO_f_base64     wolfSSL_BIO_f_base64
+#define CyaSSL_BIO_set_flags    wolfSSL_BIO_set_flags
+#define CyaSSL_BIO_get_mem_data wolfSSL_BIO_get_mem_data
+#define CyaSSL_BIO_new_mem_buf  wolfSSL_BIO_new_mem_buf
+
+
+#define CyaSSL_BIO_set_ssl wolfSSL_BIO_set_ssl
+#define CyaSSL_set_bio     wolfSSL_set_bio
+
+#define CyaSSL_add_all_algorithms wolfSSL_add_all_algorithms
+#define CyaSSL_RAND_screen        wolfSSL_RAND_screen
+#define CyaSSL_RAND_file_name     wolfSSL_RAND_file_name
+#define CyaSSL_RAND_write_file    wolfSSL_RAND_write_file
+#define CyaSSL_RAND_load_file     wolfSSL_RAND_load_file
+#define CyaSSL_RAND_egd           wolfSSL_RAND_egd
+#define CyaSSL_RAND_seed          wolfSSL_RAND_seed
+#define CyaSSL_RAND_add           wolfSSL_RAND_add
+
+#define CyaSSL_COMP_zlib wolfSSL_COMP_zlib
+#define CyaSSL_COMP_rle  wolfSSL_COMP_rle
+#define CyaSSL_COMP_add_compression_method  wolfSSL_COMP_add_compression_method
+#define CyaSSL_set_dynlock_create_callback  wolfSSL_set_dynlock_create_callback
+#define CyaSSL_set_dynlock_lock_callback    wolfSSL_set_dynlock_lock_callback
+#define CyaSSL_set_dynlock_destroy_callback wolfSSL_set_dynlock_destroy_callback
+#define CyaSSL_get_ex_new_index     wolfSSL_get_ex_new_index
+#define CyaSSL_set_id_callback      wolfSSL_set_id_callback
+#define CyaSSL_set_locking_callback wolfSSL_set_locking_callback
+#define CyaSSL_num_locks            wolfSSL_num_locks
+
+#define CyaSSL_X509_STORE_CTX_get_current_cert wolfSSL_X509_STORE_CTX_get_current_cert
+#define CyaSSL_X509_STORE_CTX_get_error        wolfSSL_X509_STORE_CTX_get_error
+#define CyaSSL_X509_STORE_CTX_get_error_depth  wolfSSL_X509_STORE_CTX_get_error_depth
+
+#define CyaSSL_X509_NAME_oneline            wolfSSL_X509_NAME_oneline
+#define CyaSSL_X509_get_issuer_name         wolfSSL_X509_get_issuer_name
+#define CyaSSL_X509_get_subject_name        wolfSSL_X509_get_subject_name
+#define CyaSSL_X509_ext_isSet_by_NID        wolfSSL_X509_ext_isSet_by_NID
+#define CyaSSL_X509_ext_get_critical_by_NID wolfSSL_X509_ext_get_critical_by_NID
+#define CyaSSL_X509_get_isCA                wolfSSL_X509_get_isCA
+#define CyaSSL_X509_get_isSet_pathLength    wolfSSL_X509_get_isSet_pathLength
+#define CyaSSL_X509_get_pathLength          wolfSSL_X509_get_pathLength
+#define CyaSSL_X509_get_keyUsage            wolfSSL_X509_get_keyUsage
+#define CyaSSL_X509_get_authorityKeyID      wolfSSL_X509_get_authorityKeyID
+#define CyaSSL_X509_get_subjectKeyID        wolfSSL_X509_get_subjectKeyID
+#define CyaSSL_X509_NAME_entry_count        wolfSSL_X509_NAME_entry_count
+#define CyaSSL_X509_NAME_get_text_by_NID    wolfSSL_X509_NAME_get_text_by_NID
+#define CyaSSL_X509_verify_cert             wolfSSL_X509_verify_cert
+#define CyaSSL_X509_verify_cert_error_string wolfSSL_X509_verify_cert_error_string
+#define CyaSSL_X509_get_signature_type      wolfSSL_X509_get_signature_type
+#define CyaSSL_X509_get_signature           wolfSSL_X509_get_signature
+
+#define CyaSSL_X509_LOOKUP_add_dir   wolfSSL_X509_LOOKUP_add_dir
+#define CyaSSL_X509_LOOKUP_load_file wolfSSL_X509_LOOKUP_load_file
+#define CyaSSL_X509_LOOKUP_hash_dir  wolfSSL_X509_LOOKUP_hash_dir
+#define CyaSSL_X509_LOOKUP_file      wolfSSL_X509_LOOKUP_file
+
+#define CyaSSL_X509_STORE_add_lookup wolfSSL_X509_STORE_add_lookup
+#define CyaSSL_X509_STORE_new        wolfSSL_X509_STORE_new
+#define CyaSSL_X509_STORE_free       wolfSSL_X509_STORE_free
+#define CyaSSL_X509_STORE_add_cert   wolfSSL_X509_STORE_add_cert
+#define CyaSSL_X509_STORE_set_default_paths wolfSSL_X509_STORE_set_default_paths
+#define CyaSSL_X509_STORE_get_by_subject    wolfSSL_X509_STORE_get_by_subject
+#define CyaSSL_X509_STORE_CTX_new           wolfSSL_X509_STORE_CTX_new
+#define CyaSSL_X509_STORE_CTX_init          wolfSSL_X509_STORE_CTX_init
+#define CyaSSL_X509_STORE_CTX_free          wolfSSL_X509_STORE_CTX_free
+#define CyaSSL_X509_STORE_CTX_cleanup       wolfSSL_X509_STORE_CTX_cleanup
+
+#define CyaSSL_X509_CRL_get_lastUpdate wolfSSL_X509_CRL_get_lastUpdate
+#define CyaSSL_X509_CRL_get_nextUpdate wolfSSL_X509_CRL_get_nextUpdate
+
+#define CyaSSL_X509_get_pubkey wolfSSL_X509_get_pubkey
+#define CyaSSL_X509_CRL_verify wolfSSL_X509_CRL_verify
+#define CyaSSL_X509_STORE_CTX_set_error  wolfSSL_X509_STORE_CTX_set_error
+#define CyaSSL_X509_OBJECT_free_contents wolfSSL_X509_OBJECT_free_contents
+#define CyaSSL_EVP_PKEY_free             wolfSSL_EVP_PKEY_free
+#define CyaSSL_X509_cmp_current_time     wolfSSL_X509_cmp_current_time
+#define CyaSSL_sk_X509_REVOKED_num       wolfSSL_sk_X509_REVOKED_num
+
+#define CyaSSL_X509_CRL_get_REVOKED     wolfSSL_X509_CRL_get_REVOKED
+#define CyaSSL_sk_X509_REVOKED_value    wolfSSL_sk_X509_REVOKED_value
+#define CyaSSL_X509_get_serialNumber    wolfSSL_X509_get_serialNumber
+#define CyaSSL_ASN1_TIME_print          wolfSSL_ASN1_TIME_print
+#define CyaSSL_ASN1_INTEGER_cmp         wolfSSL_ASN1_INTEGER_cmp
+#define CyaSSL_ASN1_INTEGER_get         wolfSSL_ASN1_INTEGER_get
+#define CyaSSL_load_client_CA_file      wolfSSL_load_client_CA_file
+#define CyaSSL_CTX_set_client_CA_list   wolfSSL_CTX_set_client_CA_list
+#define CyaSSL_X509_STORE_CTX_get_ex_data     wolfSSL_X509_STORE_CTX_get_ex_data
+#define CyaSSL_get_ex_data_X509_STORE_CTX_idx wolfSSL_get_ex_data_X509_STORE_CTX_idx
+#define CyaSSL_get_ex_data                    wolfSSL_get_ex_data
+
+#define CyaSSL_CTX_set_default_passwd_cb_userdata wolfSSL_CTX_set_default_passwd_cb_userdata
+#define CyaSSL_CTX_set_default_passwd_cb          wolfSSL_CTX_set_default_passwd_cb
+#define CyaSSL_CTX_set_info_callback  wolfSSL_CTX_set_info_callback
+#define CyaSSL_ERR_peek_error         wolfSSL_ERR_peek_error
+#define CyaSSL_GET_REASON             wolfSSL_GET_REASON
+#define CyaSSL_alert_type_string_long wolfSSL_alert_type_string_long
+#define CyaSSL_alert_desc_string_long wolfSSL_alert_desc_string_long
+#define CyaSSL_state_string_long      wolfSSL_state_string_long
+
+#define CyaSSL_RSA_generate_key         wolfSSL_RSA_generate_key
+#define CyaSSL_CTX_set_tmp_rsa_callback wolfSSL_CTX_set_tmp_rsa_callback
+#define CyaSSL_PEM_def_callback         wolfSSL_PEM_def_callback
+#define CyaSSL_CTX_sess_accept          wolfSSL_CTX_sess_accept
+#define CyaSSL_CTX_sess_connect         wolfSSL_CTX_sess_connect
+#define CyaSSL_CTX_sess_accept_good     wolfSSL_CTX_sess_accept_good
+#define CyaSSL_CTX_sess_connect_good    wolfSSL_CTX_sess_connect_good
+#define CyaSSL_CTX_sess_accept_renegotiate  wolfSSL_CTX_sess_accept_renegotiate
+#define CyaSSL_CTX_sess_connect_renegotiate wolfSSL_CTX_sess_connect_renegotiate
+#define CyaSSL_CTX_sess_hits                wolfSSL_CTX_sess_hits
+#define CyaSSL_CTX_sess_cb_hits             wolfSSL_CTX_sess_cb_hits
+#define CyaSSL_CTX_sess_cache_full          wolfSSL_CTX_sess_cache_full
+#define CyaSSL_CTX_sess_misses              wolfSSL_CTX_sess_misses
+#define CyaSSL_CTX_sess_timeouts            wolfSSL_CTX_sess_timeouts
+#define CyaSSL_CTX_sess_number              wolfSSL_CTX_sess_number
+#define CyaSSL_CTX_sess_get_cache_size      wolfSSL_CTX_sess_get_cache_size
+
+
+
+/* src/keys.c */
+#define cyassl_triple_des wolfssl_triple_des
+
+/* Initialization and Shutdown */
+#define CyaSSL_Init         wolfSSL_Init
+#define CyaSSL_library_init wolfSSL_library_init
+#define CyaSSL_Cleanup      wolfSSL_Cleanup
+#define CyaSSL_shutdown     wolfSSL_shutdown
+
+/* Certs and keys */
+#define CyaSSL_SetTmpDH                     wolfSSL_SetTmpDH
+#define CyaSSL_KeepArrays                   wolfSSL_KeepArrays
+#define CyaSSL_FreeArrays                   wolfSSL_FreeArrays
+#define CyaSSL_SetTmpDH_file                wolfSSL_SetTmpDH_file
+#define CyaSSL_use_PrivateKey_buffer        wolfSSL_use_PrivateKey_buffer
+#define CyaSSL_use_certificate_buffer       wolfSSL_use_certificate_buffer
+#define CyaSSL_CTX_load_verify_buffer       wolfSSL_CTX_load_verify_buffer
+#define CyaSSL_CTX_use_PrivateKey_file      wolfSSL_CTX_use_PrivateKey_file
+#define CyaSSL_CTX_use_certificate_file     wolfSSL_CTX_use_certificate_file
+#define CyaSSL_CTX_use_PrivateKey_buffer    wolfSSL_CTX_use_PrivateKey_buffer
+#define CyaSSL_CTX_use_certificate_buffer   wolfSSL_CTX_use_certificate_buffer
+#define CyaSSL_CTX_use_NTRUPrivateKey_file  wolfSSL_CTX_use_NTRUPrivateKey_file
+#define CyaSSL_use_certificate_chain_buffer wolfSSL_use_certificate_chain_buffer
+#define CyaSSL_CTX_der_load_verify_locations    \
+                                            wolfSSL_CTX_der_load_verify_locations
+#define CyaSSL_CTX_use_certificate_chain_file   \
+                                            wolfSSL_CTX_use_certificate_chain_file
+#define CyaSSL_CTX_use_certificate_chain_buffer \
+                                            wolfSSL_CTX_use_certificate_chain_buffer
+
+/* Context and Session Setup*/
+#define CyaSSL_new                        wolfSSL_new
+#define CyaSSL_free                       wolfSSL_free
+#define CyaSSL_set_fd                     wolfSSL_set_fd
+#define CyaSSL_CTX_new                    wolfSSL_CTX_new
+#define CyaSSL_CTX_free                   wolfSSL_CTX_free
+#define CyaSSL_SetVersion                 wolfSSL_SetVersion
+#define CyaSSL_set_verify                 wolfSSL_set_verify
+#define CyaSSL_set_session                wolfSSL_set_session
+#define CyaSSL_set_timeout                wolfSSL_set_timeout
+#define CyaSSL_CTX_set_verify             wolfSSL_CTX_set_verify
+#define CyaSSL_CTX_set_timeout            wolfSSL_CTX_set_timeout
+#define CyaSSL_set_cipher_list            wolfSSL_set_cipher_list
+#define CyaSSL_set_compression            wolfSSL_set_compression
+#define CyaTLSv1_client_method            wolfTLSv1_client_method
+#define CyaTLSv1_server_method            wolfTLSv1_server_method
+#define CyaSSLv3_client_method            wolfSSLv3_client_method
+#define CyaSSLv3_server_method            wolfSSLv3_server_method
+#define CyaSSLv23_client_method           wolfSSLv23_client_method
+#define CyaSSLv23_server_method           wolfSSLv23_server_method
+#define CyaDTLSv1_client_method           wolfDTLSv1_client_method
+#define CyaDTLSv1_server_method           wolfDTLSv1_server_method
+#define CyaSSL_check_domain_name          wolfSSL_check_domain_name
+#define CyaTLSv1_1_client_method          wolfTLSv1_1_client_method
+#define CyaTLSv1_1_server_method          wolfTLSv1_1_server_method
+#define CyaTLSv1_2_client_method          wolfTLSv1_2_client_method
+#define CyaTLSv1_2_server_method          wolfTLSv1_2_server_method
+#define CyaDTLSv1_2_client_method         wolfDTLSv1_2_client_method
+#define CyaDTLSv1_2_server_method         wolfDTLSv1_2_server_method
+#define CyaSSL_set_group_messages         wolfSSL_set_group_messages
+#define CyaSSL_CTX_set_cipher_list        wolfSSL_CTX_set_cipher_list
+#define CyaSSL_CTX_set_group_messages     wolfSSL_CTX_set_group_messages
+#define CyaSSL_CTX_set_session_cache_mode wolfSSL_CTX_set_session_cache_mode
+
+/* Callbacks */
+
+/*
+ * Empty comment denotes not listed in CyaSSL Manual
+ * (soon to be wolfSSL Manual)
+ */
+
+#define CyaSSL_accept_ex              wolfSSL_accept_ex
+#define CyaSSL_SetIORecv              wolfSSL_CTX_SetIORecv
+#define CyaSSL_SetIOSend              wolfSSL_CTX_SetIOSend
+#define CyaSSL_connect_ex             wolfSSL_connect_ex
+#define CyaSSL_CTX_SetCACb            wolfSSL_CTX_SetCACb
+#define CyaSSL_SetIOReadCtx           wolfSSL_SetIOReadCtx
+#define CyaSSL_SetRsaEncCtx           wolfSSL_SetRsaEncCtx
+#define CyaSSL_GetRsaEncCtx           wolfSSL_GetRsaEncCtx
+#define CyaSSL_SetRsaDecCtx           wolfSSL_SetRsaDecCtx
+#define CyaSSL_GetRsaDecCtx           wolfSSL_GetRsaDecCtx
+#define CyaSSL_SetLoggingCb           wolfSSL_SetLoggingCb
+#define CyaSSL_SetEccSignCtx          wolfSSL_SetEccSignCtx
+#define CyaSSL_GetEccSignCtx          wolfSSL_GetEccSignCtx
+#define CyaSSL_SetRsaSignCtx          wolfSSL_SetRsaSignCtx
+#define CyaSSL_GetRsaSignCtx          wolfSSL_GetRsaSignCtx
+#define CyaSSL_SetIOWriteCtx          wolfSSL_SetIOWriteCtx
+#define CyaSSL_SetIOReadFlags         wolfSSL_SetIOReadFlags
+#define CyaSSL_SetEccVerifyCtx        wolfSSL_SetEccVerifyCtx
+#define CyaSSL_GetEccVerifyCtx        wolfSSL_GetEccVerifyCtx
+#define CyaSSL_SetRsaVerifyCtx        wolfSSL_SetRsaVerifyCtx
+#define CyaSSL_GetRsaVerifyCtx        wolfSSL_GetRsaVerifyCtx
+#define CyaSSL_CTX_SetRsaEncCb        wolfSSL_CTX_SetRsaEncCb
+#define CyaSSL_CTX_SetRsaDecCb        wolfSSL_CTX_SetRsaDecCb
+#define CyaSSL_SetIOWriteFlags        wolfSSL_SetIOWriteFlags
+#define CyaSSL_SetTlsHmacInner        wolfSSL_SetTlsHmacInner
+#define CyaSSL_SetMacEncryptCtx       wolfSSL_SetMacEncryptCtx
+#define CyaSSL_GetMacEncryptCtx       wolfSSL_GetMacEncryptCtx
+#define CyaSSL_CTX_SetEccSignCb       wolfSSL_CTX_SetEccSignCb
+#define CyaSSL_CTX_SetRsaSignCb       wolfSSL_CTX_SetRsaSignCb
+#define CyaSSL_CTX_SetEccVerifyCb     wolfSSL_CTX_SetEccVerifyCb
+#define CyaSSL_CTX_SetRsaVerifyCb     wolfSSL_CTX_SetRsaVerifyCb
+#define CyaSSL_CTX_SetMacEncryptCb    wolfSSL_CTX_SetMacEncryptCb
+#define CyaSSL_SetDecryptVerifyCtx    wolfSSL_SetDecryptVerifyCtx
+#define CyaSSL_GetDecryptVerifyCtx    wolfSSL_GetDecryptVerifyCtx
+#define CyaSSL_CTX_SetDecryptVerifyCb wolfSSL_CTX_SetDecryptVerifyCb
+
+/* psk specific */
+#ifndef NO_PSK
+
+#define CyaSSL_get_psk_identity          wolfSSL_get_psk_identity          /**/
+#define CyaSSL_get_psk_identity_hint     wolfSSL_get_psk_identity_hint     /**/
+#define CyaSSL_use_psk_identity_hint     wolfSSL_use_psk_identity_hint     /**/
+#define CyaSSL_set_psk_client_callback   wolfSSL_set_psk_client_callback   /**/
+#define CyaSSL_set_psk_server_callback   wolfSSL_set_psk_server_callback   /**/
+#define CyaSSL_CTX_use_psk_identity_hint wolfSSL_CTX_use_psk_identity_hint /**/
+#define CyaSSL_CTX_set_psk_client_callback \
+                                      wolfSSL_CTX_set_psk_client_callback  /**/
+#define CyaSSL_CTX_set_psk_server_callback \
+                                      wolfSSL_CTX_set_psk_server_callback  /**/
+
+#endif
+/* end psk specific */
+
+/* Anonymous */
+#define CyaSSL_CTX_allow_anon_cipher wolfSSL_CTX_allow_anon_cipher         /**/
+
+/* Error Handling and Debugging*/
+#define CyaSSL_get_error           wolfSSL_get_error
+#define CyaSSL_want_read           wolfSSL_want_read
+#define CyaSSL_want_write          wolfSSL_want_write
+#define CyaSSL_Debugging_ON        wolfSSL_Debugging_ON
+#define CyaSSL_Debugging_OFF       wolfSSL_Debugging_OFF
+#define CyaSSL_ERR_error_string    wolfSSL_ERR_error_string
+#define CyaSSL_load_error_strings  wolfSSL_load_error_strings
+#define CyaSSL_ERR_error_string_n  wolfSSL_ERR_error_string_n
+#define CyaSSL_ERR_print_errors_fp wolfSSL_ERR_print_errors_fp
+
+/* OCSP and CRL */
+
+/*
+ * Empty comment denotes not listed in CyaSSL Manual
+ * (soon to be wolfSSL Manual)
+ */
+
+#define CYASSL_CRL_MONITOR               WOLFSSL_CRL_MONITOR               /**/
+#define CYASSL_CRL_START_MON             WOLFSSL_CRL_START_MON             /**/
+#define CYASSL_OCSP_NO_NONCE             WOLFSSL_OCSP_NO_NONCE             /**/
+#define CYASSL_OCSP_URL_OVERRIDE         WOLFSSL_OCSP_URL_OVERRIDE
+#define CYASSL_OCSP_CHECKALL             WOLFSSL_OCSP_CHECKALL
+
+#define CyaSSL_CTX_EnableOCSP            wolfSSL_CTX_EnableOCSP
+#define CyaSSL_CTX_OCSP_set_options      wolfSSL_CTX_OCSP_set_options      /**/
+#define CyaSSL_CTX_SetOCSP_OverrideURL   wolfSSL_CTX_SetOCSP_OverrideURL   /**/
+#define CyaSSL_CTX_OCSP_set_override_url wolfSSL_CTX_OCSP_set_override_url /**/
+
+/* Informational */
+#define CyaSSL_GetSide            wolfSSL_GetSide
+#define CyaSSL_IsTLSv1_1          wolfSSL_IsTLSv1_1
+#define CyaSSL_GetKeySize         wolfSSL_GetKeySize
+#define CyaSSL_GetHmacSize        wolfSSL_GetHmacSize
+#define CyaSSL_GetHmacType        wolfSSL_GetHmacType
+#define CyaSSL_GetMacSecret       wolfSSL_GetMacSecret
+#define CyaSSL_GetObjectSize      wolfSSL_GetObjectSize
+#define CyaSSL_GetBulkCipher      wolfSSL_GetBulkCipher
+#define CyaSSL_GetCipherType      wolfSSL_GetCipherType
+#define CyaSSL_GetAeadMacSize     wolfSSL_GetAeadMacSize
+#define CyaSSL_GetClientWriteIV   wolfSSL_GetClientWriteIV
+#define CyaSSL_GetServerWriteIV   wolfSSL_GetServerWriteIV
+#define CyaSSL_GetClientWriteKey  wolfSSL_GetClientWriteKey
+#define CyaSSL_GetServerWriteKey  wolfSSL_GetServerWriteKey
+#define CyaSSL_GetCipherBlockSize wolfSSL_GetCipherBlockSize
+
+/* Connection, Session, and I/O */
+#define CyaSSL_peek               wolfSSL_peek
+#define CyaSSL_read               wolfSSL_read
+#define CyaSSL_recv               wolfSSL_recv
+#define CyaSSL_send               wolfSSL_send
+#define CyaSSL_write              wolfSSL_write
+#define CyaSSL_writev             wolfSSL_writev
+#define CyaSSL_accept             wolfSSL_accept
+#define CyaSSL_get_fd             wolfSSL_get_fd
+#define CyaSSL_connect            wolfSSL_connect
+#define CyaSSL_pending            wolfSSL_pending
+#define CyaSSL_negotiate          wolfSSL_negotiate
+#define CyaSSL_get_session        wolfSSL_get_session
+#define CyaSSL_connect_cert       wolfSSL_connect_cert
+#define CyaSSL_flush_sessions     wolfSSL_flush_sessions
+#define CyaSSL_get_using_nonblock wolfSSL_get_using_nonblock
+#define CyaSSL_PrintSessionStats  wolfSSL_PrintSessionStats
+
+/* DTLS Specific */
+#define CyaSSL_dtls                     wolfSSL_dtls
+#define CyaSSL_dtls_set_peer            wolfSSL_dtls_set_peer
+#define CyaSSL_dtls_get_peer            wolfSSL_dtls_get_peer
+#define CyaSSL_dtls_got_timeout         wolfSSL_dtls_got_timeout
+#define CyaSSL_dtls_get_current_timeout wolfSSL_dtls_get_current_timeout
+#define CyaSSL_set_using_nonblock       wolfSSL_dtls_set_using_nonblock
+
+/* Certificate Manager */
+#define CyaSSL_CertManagerNew          wolfSSL_CertManagerNew
+#define CyaSSL_CertManagerFree         wolfSSL_CertManagerFree
+#define CyaSSL_CertManagerLoadCA       wolfSSL_CertManagerLoadCA
+#define CyaSSL_CertManagerVerify       wolfSSL_CertManagerVerify
+#define CyaSSL_CertManagerEnableCRL    wolfSSL_CertManagerEnableCRL
+#define CyaSSL_CertManagerDisableCRL   wolfSSL_CertManagerDisableCRL
+#define CyaSSL_CertManagerVerifyBuffer wolfSSL_CertManagerVerifyBuffer
+#ifndef NO_CERTS
+	#define CyaSSL_CertManagerCheckCRL   wolfSSL_CertManagerCheckCRL
+	#define CyaSSL_CertManagerLoadCRL    wolfSSL_CertManagerLoadCRL
+	#define CyaSSL_CertManagerSetCRL_Cb  wolfSSL_CertManagerSetCRL_Cb
+	#define CyaSSL_CertManagerCheckOCSP  wolfSSL_CertManagerCheckOCSP
+	#define CyaSSL_CertManagerSetOCSP_Cb wolfSSL_CertManagerSetOCSP_Cb
+	#define CyaSSL_CertManagerSetOCSPOverrideURL \
+                                          wolfSSL_CertManagerSetOCSPOverrideURL
+
+	#define CyaSSL_DisableCRL          wolfSSL_DisableCRL
+	#define CyaSSL_EnableOCSP          wolfSSL_EnableOCSP
+	#define CyaSSL_DisableOCSP         wolfSSL_DisableOCSP
+	#define CyaSSL_SetOCSP_OverrideURL wolfSSL_SetOCSP_OverrideURL
+	#define CyaSSL_SetOCSP_Cb          wolfSSL_SetOCSP_Cb
+
+	#define CyaSSL_CTX_EnableCRL   wolfSSL_CTX_EnableCRL
+	#define CyaSSL_CTX_DisableCRL  wolfSSL_CTX_DisableCRL
+	#define CyaSSL_CTX_LoadCRL     wolfSSL_CTX_LoadCRL
+	#define CyaSSL_CTX_SetCRL_Cb   wolfSSL_CTX_SetCRL_Cb
+	#define CyaSSL_CTX_DisableOCSP wolfSSL_CTX_DisableOCSP
+	#define CyaSSL_CTX_SetOCSP_Cb  wolfSSL_CTX_SetOCSP_Cb
+#endif /* !NO_CERTS */
+
+
+/* OpenSSL Compatibility Layer */
+#define CyaSSL_get_sessionID              wolfSSL_get_sessionID
+#define CyaSSL_get_peer_count             wolfSSL_get_peer_count
+#define CyaSSL_get_chain_cert             wolfSSL_get_chain_cert
+#define CyaSSL_get_peer_chain             wolfSSL_get_peer_chain
+#define CyaSSL_get_peer_length            wolfSSL_get_peer_length
+#define CyaSSL_get_chain_cert_pem         wolfSSL_get_chain_cert_pem
+#define CyaSSL_use_PrivateKey_file        wolfSSL_use_PrivateKey_file
+#define CyaSSL_use_certificate_file       wolfSSL_use_certificate_file
+#define CyaSSL_use_RSAPrivateKey_file     wolfSSL_use_RSAPrivateKey_file
+#define CyaSSL_X509_get_serial_number     wolfSSL_X509_get_serial_number
+#define CyaSSL_CTX_use_RSAPrivateKey_file wolfSSL_CTX_use_RSAPrivateKey_file
+#define CyaSSL_use_certificate_chain_file wolfSSL_use_certificate_chain_file
+
+/* TLS Extensions */
+#define CYASSL_SNI_HOST_NAME         WOLFSSL_SNI_HOST_NAME
+
+#define CyaSSL_UseSNI                wolfSSL_UseSNI
+#define CyaSSL_CTX_UseSNI            wolfSSL_CTX_UseSNI
+#define CyaSSL_SNI_SetOptions        wolfSSL_SNI_SetOptions
+#define CyaSSL_SNI_GetRequest        wolfSSL_SNI_GetRequest
+#define CyaSSL_UseMaxFragment        wolfSSL_UseMaxFragment
+#define CyaSSL_UseTruncatedHMAC      wolfSSL_UseTruncatedHMAC
+#define CyaSSL_UseSupportedCurve     wolfSSL_UseSupportedCurve
+#define CyaSSL_SNI_GetFromBuffer     wolfSSL_SNI_GetFromBuffer
+#define CyaSSL_CTX_SNI_SetOptions    wolfSSL_CTX_SNI_SetOptions
+#define CyaSSL_CTX_UseMaxFragment    wolfSSL_CTX_UseMaxFragment
+#define CyaSSL_CTX_UseTruncatedHMAC  wolfSSL_CTX_UseTruncatedHMAC
+#define CyaSSL_CTX_UseSupportedCurve wolfSSL_CTX_UseSupportedCurve
+
+/* End wolfssl -> cyassl -> openssl compatibility */
+
+/* JRB macro redefinitions and api calls for cryptography for reverse compat. */
+
+#ifdef WOLFSSL_SMALL_STACK
+    #define CYASSL_SMALL_STACK
+#endif
+
+
+/*
+ * wrapper around macros until they are changed in cyassl code
+ * needs investigation in regards to macros in fips
+ */
+#define NO_WOLFSSL_ALLOC_ALIGN NO_CYASSL_ALLOC_ALIGN /* @TODO */
+
+
+/* examples/client/client.h */
+#define CYASSL_THREAD WOLFSSL_THREAD
+#ifdef WOLFSSL_DTLS
+    #define CYASSL_DTLS   WOLFSSL_DTLS
+#endif
+
+/* examples/client/client.c */
+#define LIBCYASSL_VERSION_STRING LIBWOLFSSL_VERSION_STRING
+
+#ifdef __cplusplus
+    } /* extern "C" */
+#endif
+
+
+#endif /* CyaSSL_openssl_h__ */
Index: azure_iot_hub_f767zi/trunk/wolfssl-4.4.0/cyassl/version.h
===================================================================
--- azure_iot_hub_f767zi/trunk/wolfssl-4.4.0/cyassl/version.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/wolfssl-4.4.0/cyassl/version.h	(revision 457)
@@ -0,0 +1,27 @@
+/* cyassl/version.h
+ *
+ * Copyright (C) 2006-2020 wolfSSL Inc.
+ *
+ * This file is part of wolfSSL.
+ *
+ * wolfSSL is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * wolfSSL is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
+ */
+
+
+#include <wolfssl/version.h>
+
+#define LIBCYASSL_VERSION_STRING LIBWOLFSSL_VERSION_STRING
+#define LIBCYASSL_VERSION_HEX LIBWOLFSSL_VERSION_HEX
+
Index: azure_iot_hub_f767zi/trunk/wolfssl-4.4.0/src/bio.c
===================================================================
--- azure_iot_hub_f767zi/trunk/wolfssl-4.4.0/src/bio.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/wolfssl-4.4.0/src/bio.c	(revision 457)
@@ -0,0 +1,1705 @@
+/* bio.c
+ *
+ * Copyright (C) 2006-2020 wolfSSL Inc.
+ *
+ * This file is part of wolfSSL.
+ *
+ * wolfSSL is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * wolfSSL is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
+ */
+
+#include <wolfssl/wolfcrypt/settings.h>
+
+#if !defined(WOLFSSL_BIO_INCLUDED)
+    #ifndef WOLFSSL_IGNORE_FILE_WARN
+        #warning bio.c does not need to be compiled separately from ssl.c
+    #endif
+#else
+
+
+/* Helper function to decode a base64 input
+ *
+ * returns size of resulting buffer on success
+ */
+static int wolfSSL_BIO_BASE64_read(WOLFSSL_BIO* bio, void* buf, int len)
+{
+    word32 frmtSz = len;
+
+    WOLFSSL_ENTER("wolfSSL_BIO_BASE64_read");
+
+    if (Base64_Decode((const byte*)buf, (word32)len, (byte*)buf, &frmtSz) !=0) {
+        WOLFSSL_MSG("Err doing base64 decode");
+        return SSL_FATAL_ERROR;
+    }
+
+    (void)bio;
+    return (int)frmtSz;
+}
+
+
+/* Helper function to read from WOLFSSL_BIO_BIO type
+ *
+ * returns amount in bytes read on success
+ */
+static int wolfSSL_BIO_BIO_read(WOLFSSL_BIO* bio, void* buf, int len)
+{
+    int   sz;
+    char* pt;
+
+    sz = wolfSSL_BIO_nread(bio, &pt, len);
+
+    if (sz > 0) {
+        XMEMCPY(buf, pt, sz);
+    }
+
+    return sz;
+}
+
+
+/* Handles reading from a memory type BIO and advancing the state.
+ *
+ * bio  WOLFSSL_BIO to read from
+ * buf  buffer to put data from bio in
+ * len  amount of data to be read
+ *
+ * returns size read on success
+ */
+static int wolfSSL_BIO_MEMORY_read(WOLFSSL_BIO* bio, void* buf, int len)
+{
+    int   sz;
+    WOLFSSL_ENTER("wolfSSL_BIO_MEMORY_read");
+
+    sz = wolfSSL_BIO_pending(bio);
+    if (sz > 0) {
+        const unsigned char* pt = NULL;
+        int memSz;
+
+        if (sz > len) {
+            sz = len;
+        }
+        memSz = wolfSSL_BIO_get_mem_data(bio, (void*)&pt);
+        if (memSz >= sz && pt != NULL) {
+            byte* tmp;
+
+            XMEMCPY(buf, (void*)pt, sz);
+            if (memSz - sz > 0) {
+                tmp = (byte*)XMALLOC(memSz-sz, bio->heap, DYNAMIC_TYPE_OPENSSL);
+                if (tmp == NULL) {
+                    WOLFSSL_MSG("Memory error");
+                    return WOLFSSL_BIO_ERROR;
+                }
+                XMEMCPY(tmp, (void*)(pt + sz), memSz - sz);
+
+                /* reset internal bio->mem */
+                XFREE(bio->ptr, bio->heap, DYNAMIC_TYPE_OPENSSL);
+                bio->ptr    = tmp;
+                bio->num = memSz-sz;
+                if (bio->mem_buf != NULL) {
+                    bio->mem_buf->data = (char*)bio->ptr;
+                    bio->mem_buf->length = bio->num;
+                }
+            }
+            bio->wrSz  -= sz;
+        }
+        else {
+            WOLFSSL_MSG("Issue with getting bio mem pointer");
+            return 0;
+        }
+    }
+    else {
+        return WOLFSSL_BIO_ERROR;
+    }
+
+    return sz;
+}
+
+#ifndef WOLFCRYPT_ONLY
+/* Helper function to read from WOLFSSL_BIO_SSL type
+ *
+ * returns the number of bytes read on success
+ */
+static int wolfSSL_BIO_SSL_read(WOLFSSL_BIO* bio, void* buf,
+        int len, WOLFSSL_BIO* front)
+{
+    int ret;
+
+    WOLFSSL_ENTER("wolfSSL_BIO_SSL_read");
+
+    /* already got eof, again is error */
+    if ((front == NULL) || front->eof)
+        return WOLFSSL_FATAL_ERROR;
+
+    bio->flags &= ~(WOLFSSL_BIO_FLAG_RETRY); /* default no retry */
+    ret = wolfSSL_read((WOLFSSL*)bio->ptr, buf, len);
+    if (ret == 0)
+        front->eof = 1;
+    else if (ret < 0) {
+        int err = wolfSSL_get_error((WOLFSSL*)bio->ptr, 0);
+        if ( !(err == SSL_ERROR_WANT_READ || err == SSL_ERROR_WANT_WRITE) ) {
+            front->eof = 1;
+        }
+        else {
+            bio->flags |= WOLFSSL_BIO_FLAG_RETRY; /* should retry */
+        }
+    }
+
+    return ret;
+}
+
+static int wolfSSL_BIO_MD_read(WOLFSSL_BIO* bio, void* buf, int sz)
+{
+    int ret = sz;
+
+    if (wolfSSL_EVP_MD_CTX_type((WOLFSSL_EVP_MD_CTX*)bio->ptr) == NID_hmac) {
+        if (wolfSSL_EVP_DigestSignUpdate((WOLFSSL_EVP_MD_CTX*)bio->ptr, buf,
+                        sz) != WOLFSSL_SUCCESS)
+        {
+            ret = WOLFSSL_FATAL_ERROR;
+        }
+    }
+    else {
+        if (wolfSSL_EVP_DigestUpdate((WOLFSSL_EVP_MD_CTX*)bio->ptr, buf, ret)
+                != WOLFSSL_SUCCESS) {
+            ret = WOLFSSL_FATAL_ERROR;
+        }
+    }
+    return ret;
+}
+#endif /* WOLFCRYPT_ONLY */
+
+
+/* Used to read data from a WOLFSSL_BIO structure
+ *
+ * bio  structure to read data from
+ * buf  buffer to hold the result
+ * len  length of buf buffer
+ *
+ * returns the number of bytes read on success
+ */
+int wolfSSL_BIO_read(WOLFSSL_BIO* bio, void* buf, int len)
+{
+    int  ret = 0;
+    WOLFSSL_BIO* front = bio;
+    int  sz  = 0;
+
+    WOLFSSL_ENTER("wolfSSL_BIO_read");
+
+    /* info cb, abort if user returns <= 0*/
+    if (front != NULL && front->infoCb != NULL) {
+        ret = (int)front->infoCb(front, WOLFSSL_BIO_CB_READ, (const char*)buf,
+                                                                     len, 0, 1);
+        if (ret <= 0) {
+            return ret;
+        }
+    }
+
+    /* start at end of list and work backwards */
+    while ((bio != NULL) && (bio->next != NULL)) {
+        bio = bio->next;
+    }
+
+    while (bio != NULL && ret >= 0) {
+        /* check for custom read */
+        if (bio->method && bio->method->readCb) {
+            ret = bio->method->readCb(bio, (char*)buf, len);
+        }
+
+        /* formatting data */
+        if (bio->type == WOLFSSL_BIO_BASE64 && ret > 0 && sz > 0) {
+            ret = wolfSSL_BIO_BASE64_read(bio, buf, sz);
+        }
+
+        /* write BIOs */
+        if (bio && bio->type == WOLFSSL_BIO_BIO) {
+            ret = wolfSSL_BIO_BIO_read(bio, buf, len);
+        }
+
+        if (bio && bio->type == WOLFSSL_BIO_MEMORY) {
+            ret = wolfSSL_BIO_MEMORY_read(bio, buf, len);
+        }
+
+    #ifndef NO_FILESYSTEM
+        if (bio && bio->type == WOLFSSL_BIO_FILE) {
+            ret = (int)XFREAD(buf, 1, len, (XFILE)bio->ptr);
+        }
+    #endif
+
+    #ifndef WOLFCRYPT_ONLY
+        if (bio && bio->type == WOLFSSL_BIO_SSL) {
+            ret = wolfSSL_BIO_SSL_read(bio, buf, len, front);
+        }
+
+        /* data passing through BIO MD wrapper */
+        if (bio && bio->type == WOLFSSL_BIO_MD && ret > 0) {
+            ret = wolfSSL_BIO_MD_read(bio, buf, ret);
+        }
+    #endif
+
+        /* case where front of list is done */
+        if (bio == front) {
+            break; /* at front of list so be done */
+        }
+
+        if (ret > 0) {
+            sz = ret; /* adjust size for formatting */
+        }
+
+        /* previous WOLFSSL_BIO in list working towards head of list */
+        bio = bio->prev;
+    }
+
+    /* info cb, user can override return value */
+    if (front != NULL && front->infoCb != NULL) {
+        ret = (int)front->infoCb(front,
+                                 WOLFSSL_BIO_CB_READ | WOLFSSL_BIO_CB_RETURN,
+                                 (const char*)buf, len, 0, ret);
+    }
+
+    return ret;
+}
+
+
+/* Converts data into base64 output
+ *
+ * returns the resulting buffer size on success.
+ */
+static int wolfSSL_BIO_BASE64_write(WOLFSSL_BIO* bio, const void* data,
+        word32 inLen, byte* out, word32* outLen)
+{
+    byte* tmp = NULL;
+    int ret   = 0;
+
+    WOLFSSL_ENTER("wolfSSL_BIO_BASE64_write");
+
+    if (bio == NULL || data == NULL || out == NULL || outLen == NULL) {
+        return BAD_FUNC_ARG;
+    }
+
+#if defined(WOLFSSL_BASE64_ENCODE)
+    tmp = (byte*)XMALLOC(*outLen, bio->heap, DYNAMIC_TYPE_TMP_BUFFER);
+    if (tmp == NULL) {
+        return WOLFSSL_FATAL_ERROR;
+    }
+
+    if ((bio->flags & WOLFSSL_BIO_FLAG_BASE64_NO_NL) ==
+            WOLFSSL_BIO_FLAG_BASE64_NO_NL) {
+        if (Base64_Encode_NoNl((const byte*)data, inLen,
+                tmp, outLen) < 0) {
+            ret = WOLFSSL_FATAL_ERROR;
+        }
+    }
+    else {
+        if (Base64_Encode((const byte*)data, inLen,
+                tmp, outLen) < 0) {
+            ret = WOLFSSL_FATAL_ERROR;
+        }
+    }
+
+    if (ret != WOLFSSL_FATAL_ERROR) {
+        ret = (int) inLen;
+        XMEMCPY(out, tmp, *outLen);
+
+    }
+    XFREE(tmp, bio->heap, DYNAMIC_TYPE_TMP_BUFFER);
+#else
+    (void)bio;
+    (void)data;
+    (void)inLen;
+    (void)out;
+    (void)outLen;
+    (void)tmp;
+    WOLFSSL_MSG("BASE64 encoding not compiled in");
+#endif
+    return ret;
+}
+
+
+#ifndef WOLFCRYPT_ONLY
+/* Helper function for writing to a WOLFSSL_BIO_SSL type
+ *
+ * returns the amount written in bytes on success
+ */
+static int wolfSSL_BIO_SSL_write(WOLFSSL_BIO* bio, const void* data,
+        int len, WOLFSSL_BIO* front)
+{
+    int ret;
+
+    WOLFSSL_ENTER("wolfSSL_BIO_SSL_write");
+
+    if (bio->ptr == NULL) {
+        return BAD_FUNC_ARG;
+    }
+
+    bio->flags &= ~(WOLFSSL_BIO_FLAG_RETRY); /* default no retry */
+    ret = wolfSSL_write((WOLFSSL*)bio->ptr, data, len);
+    if (ret == 0)
+        front->eof = 1;
+    else if (ret < 0) {
+        int err = wolfSSL_get_error((WOLFSSL*)bio->ptr, 0);
+        if ( !(err == SSL_ERROR_WANT_READ || err == SSL_ERROR_WANT_WRITE) ) {
+            front->eof = 1;
+        }
+        else {
+            bio->flags |= WOLFSSL_BIO_FLAG_RETRY; /* should retry */
+        }
+    }
+    return ret;
+}
+#endif /* WOLFCRYPT_ONLY */
+
+
+/* Writes to a WOLFSSL_BIO_BIO type.
+ *
+ * returns the amount written on success
+ */
+static int wolfSSL_BIO_BIO_write(WOLFSSL_BIO* bio, const void* data,
+        int len)
+{
+    int   sz;
+    char* buf;
+
+    WOLFSSL_ENTER("wolfSSL_BIO_BIO_write");
+
+    /* adding in sanity checks for static analysis tools */
+    if (bio == NULL || data == NULL) {
+        return BAD_FUNC_ARG;
+    }
+
+    sz = wolfSSL_BIO_nwrite(bio, &buf, len);
+
+    /* test space for write */
+    if (sz <= 0) {
+        WOLFSSL_MSG("No room left to write");
+        return sz;
+    }
+
+    XMEMCPY(buf, data, sz);
+
+    return sz;
+}
+
+
+/* for complete compatibility a bio memory write allocs its own memory
+ * until the application runs out ....
+ *
+ * bio  structure to hold incoming data
+ * data buffer holding the data to be written
+ * len  length of data buffer
+ *
+ * returns the amount of data written on success and WOLFSSL_FAILURE or
+ *         WOLFSSL_BIO_ERROR for failure cases.
+ */
+static int wolfSSL_BIO_MEMORY_write(WOLFSSL_BIO* bio, const void* data,
+        int len)
+{
+    int   sz;
+    const unsigned char* buf;
+
+    WOLFSSL_ENTER("wolfSSL_BIO_MEMORY_write");
+
+    if (bio == NULL || data == NULL) {
+        return BAD_FUNC_ARG;
+    }
+
+    sz = wolfSSL_BIO_pending(bio);
+    if (sz < 0) {
+        WOLFSSL_MSG("Error getting memory data");
+        return sz;
+    }
+
+    if (bio->ptr == NULL) {
+        bio->ptr = (byte*)XMALLOC(len, bio->heap, DYNAMIC_TYPE_OPENSSL);
+        if (bio->ptr == NULL) {
+            WOLFSSL_MSG("Error on malloc");
+            return WOLFSSL_FAILURE;
+        }
+        bio->num = len;
+        if (bio->mem_buf != NULL) {
+            bio->mem_buf->data = (char*)bio->ptr;
+            bio->mem_buf->length = bio->num;
+        }
+    }
+
+    /* check if will fit in current buffer size */
+    if (wolfSSL_BIO_get_mem_data(bio, (void*)&buf) < 0) {
+        return WOLFSSL_BIO_ERROR;
+    }
+    if (bio->num < sz + len) {
+        bio->ptr = (byte*)XREALLOC(bio->ptr, sz + len, bio->heap,
+            DYNAMIC_TYPE_OPENSSL);
+        if (bio->ptr == NULL) {
+            WOLFSSL_MSG("Error on realloc");
+            return WOLFSSL_FAILURE;
+        }
+        bio->num = sz + len;
+        if (bio->mem_buf != NULL) {
+            bio->mem_buf->data = (char*)bio->ptr;
+            bio->mem_buf->length = bio->num;
+        }
+    }
+
+    XMEMCPY((byte*)bio->ptr + sz, data, len);
+    bio->wrSz += len;
+
+    return len;
+}
+
+
+#ifndef WOLFCRYPT_ONLY
+/* Helper function for writing to a WOLFSSL_BIO_MD type
+ *
+ * returns the amount written in bytes on success (0)
+ */
+static int wolfSSL_BIO_MD_write(WOLFSSL_BIO* bio, const void* data, int len)
+{
+    int ret = 0;
+
+    if (bio == NULL || data == NULL) {
+        return BAD_FUNC_ARG;
+    }
+
+    if (wolfSSL_EVP_MD_CTX_type((WOLFSSL_EVP_MD_CTX*)bio->ptr) == NID_hmac) {
+        if (wolfSSL_EVP_DigestSignUpdate((WOLFSSL_EVP_MD_CTX*)bio->ptr, data,
+                    len) != WOLFSSL_SUCCESS) {
+            ret = WOLFSSL_BIO_ERROR;
+        }
+    }
+    else {
+        if (wolfSSL_EVP_DigestUpdate((WOLFSSL_EVP_MD_CTX*)bio->ptr, data, len)
+                != WOLFSSL_SUCCESS) {
+            ret =  WOLFSSL_BIO_ERROR;
+        }
+    }
+    return ret;
+}
+#endif /* WOLFCRYPT_ONLY */
+
+
+/* Writes data to a WOLFSSL_BIO structure
+ *
+ * bio  structure to write to
+ * data holds the data to be written
+ * len  length of data buffer
+ *
+ * returns the amount written in bytes on success
+ */
+int wolfSSL_BIO_write(WOLFSSL_BIO* bio, const void* data, int len)
+{
+    int  ret = 0;
+    int  retB64 = 0;
+    WOLFSSL_BIO* front = bio;
+    void*  frmt   = NULL;
+    word32 frmtSz = 0;
+
+    WOLFSSL_ENTER("wolfSSL_BIO_write");
+
+    /* info cb, abort if user returns <= 0*/
+    if (front != NULL && front->infoCb != NULL) {
+        ret = (int)front->infoCb(front, WOLFSSL_BIO_CB_WRITE,
+                (const char*)data, len, 0, 1);
+        if (ret <= 0) {
+            return ret;
+        }
+    }
+
+    while (bio != NULL && ret >= 0) {
+        /* check for custom write */
+        if (bio->method && bio->method->writeCb) {
+            ret = bio->method->writeCb(bio, (const char*)data, len);
+        }
+
+        /* check for formatting */
+        if (bio->type == WOLFSSL_BIO_BASE64) {
+#if defined(WOLFSSL_BASE64_ENCODE)
+            word32 sz = 0;
+
+            if (bio->flags & WOLFSSL_BIO_FLAG_BASE64_NO_NL) {
+                if (Base64_Encode_NoNl((const byte*)data, len, NULL,
+                            &sz) != LENGTH_ONLY_E) {
+                    WOLFSSL_MSG("Error with base 64 get length");
+                    ret = SSL_FATAL_ERROR;
+                }
+            }
+            else {
+                if (Base64_Encode((const byte*)data, len, NULL, &sz) !=
+                    LENGTH_ONLY_E) {
+                    WOLFSSL_MSG("Error with base 64 get length");
+                    ret = SSL_FATAL_ERROR;
+                }
+            }
+
+            if (frmt == NULL && sz > 0 && ret != SSL_FATAL_ERROR) {
+                frmt = (void*)XMALLOC(sz, front->heap,
+                        DYNAMIC_TYPE_TMP_BUFFER);
+                if (frmt == NULL) {
+                    WOLFSSL_MSG("Memory error");
+                    ret = SSL_FATAL_ERROR;
+                }
+                frmtSz = sz;
+            }
+            else if (sz > frmtSz) {
+                frmt = (void*)XREALLOC(frmt, sz, front->heap,
+                        DYNAMIC_TYPE_TMP_BUFFER);
+                if (frmt == NULL) {
+                    WOLFSSL_MSG("Memory error");
+                    ret = SSL_FATAL_ERROR;
+                }
+                /* since frmt already existed then data should point to knew
+                   formatted buffer */
+                data = frmt;
+                len  = frmtSz;
+                frmtSz = sz;
+            }
+#endif /* defined(WOLFSSL_BASE64_ENCODE) */
+
+            if (ret >= 0) {
+                /* change so that data is formatted buffer */
+                retB64 = wolfSSL_BIO_BASE64_write(bio, data, (word32)len,
+                         (byte*)frmt, &frmtSz);
+                data = frmt;
+                len  = frmtSz;
+            }
+        }
+
+        /* write bios */
+        if (bio && bio->type == WOLFSSL_BIO_BIO) {
+            ret = wolfSSL_BIO_BIO_write(bio, data, len);
+        }
+
+        if (bio && bio->type == WOLFSSL_BIO_MEMORY) {
+            ret = wolfSSL_BIO_MEMORY_write(bio, data, len);
+        }
+
+    #ifndef NO_FILESYSTEM
+        if (bio && bio->type == WOLFSSL_BIO_FILE) {
+            ret = (int)XFWRITE(data, 1, len, (XFILE)bio->ptr);
+        }
+    #endif
+
+    #ifndef WOLFCRYPT_ONLY
+        if (bio && bio->type == WOLFSSL_BIO_SSL) {
+            /* already got eof, again is error */
+            if (front->eof) {
+                ret = SSL_FATAL_ERROR;
+            }
+            else {
+                ret = wolfSSL_BIO_SSL_write(bio, data, len, front);
+            }
+        }
+
+        if (bio && bio->type == WOLFSSL_BIO_MD) {
+            if (bio->next != NULL) { /* data passing through MD BIO */
+                ret = wolfSSL_BIO_MD_write(bio, data, len);
+            }
+        }
+    #endif /* WOLFCRYPT_ONLY */
+
+        /* advance to the next bio in list */
+        bio = bio->next;
+    }
+
+    if (frmt != NULL) {
+        XFREE(frmt, front->heap, DYNAMIC_TYPE_TMP_BUFFER);
+    }
+
+    /* info cb, user can override return value */
+    if (front != NULL && front->infoCb != NULL) {
+        ret = (int)front->infoCb(front,
+                                 WOLFSSL_BIO_CB_WRITE | WOLFSSL_BIO_CB_RETURN,
+                                 (const char*)data, 0, 0, ret);
+    }
+
+    if (retB64 != 0)
+        return retB64;
+    else
+        return ret;
+}
+
+
+/* Wrapper for other BIO type functions, expected to grow as OpenSSL compatibility
+ * layer grows.
+ *
+ * return info. specific to the cmd that is passed in.
+ */
+#if defined(OPENSSL_ALL) || defined(OPENSSL_EXTRA)
+long wolfSSL_BIO_ctrl(WOLFSSL_BIO *bio, int cmd, long larg, void *parg)
+{
+    long ret;
+
+    (void)larg; /* not currently used */
+
+    WOLFSSL_ENTER("wolfSSL_BIO_ctrl");
+
+    if (bio && bio->method && bio->method->ctrlCb) {
+        return bio->method->ctrlCb(bio, cmd, larg, parg);
+    }
+
+    switch(cmd) {
+        case BIO_CTRL_PENDING:
+        case BIO_CTRL_WPENDING:
+            ret = (long)wolfSSL_BIO_ctrl_pending(bio);
+            break;
+        case BIO_CTRL_INFO:
+            ret = (long)wolfSSL_BIO_get_mem_data(bio, parg);
+            break;
+        case BIO_CTRL_FLUSH:
+            ret = (long)wolfSSL_BIO_flush(bio);
+            break;
+        case BIO_CTRL_RESET:
+            ret = (long)wolfSSL_BIO_reset(bio);
+            break;
+        default:
+            WOLFSSL_MSG("CMD not yet implemented");
+            ret = WOLFSSL_FAILURE;
+            break;
+    }
+    return ret;
+}
+#endif
+
+
+/* helper function for wolfSSL_BIO_gets
+ * size till a newline is hit
+ * returns the number of bytes including the new line character
+ */
+static int wolfSSL_getLineLength(char* in, int inSz)
+{
+    int i;
+
+    for (i = 0; i < inSz; i++) {
+        if (in[i] == '\n') {
+            return i + 1; /* includes new line character */
+        }
+    }
+
+    return inSz; /* rest of buffer is all one line */
+}
+
+
+/* Gets the next line from bio. Goes until a new line character or end of
+ * buffer is reached.
+ *
+ * bio  the structure to read a new line from
+ * buf  buffer to hold the result
+ * sz   the size of "buf" buffer
+ *
+ * returns the size of the result placed in buf on success and a 0 or negative
+ *         value in an error case.
+ */
+int wolfSSL_BIO_gets(WOLFSSL_BIO* bio, char* buf, int sz)
+{
+    int ret = WOLFSSL_BIO_UNSET;
+
+    WOLFSSL_ENTER("wolfSSL_BIO_gets");
+
+    if (bio == NULL || buf == NULL) {
+        return WOLFSSL_FAILURE;
+    }
+
+    /* not enough space for character plus terminator */
+    if (sz <= 1) {
+        return 0;
+    }
+
+    /* info cb, abort if user returns <= 0*/
+    if (bio->infoCb != NULL) {
+        ret = (int)bio->infoCb(bio, WOLFSSL_BIO_CB_GETS, buf, sz, 0, 1);
+        if (ret <= 0) {
+            return ret;
+        }
+    }
+
+    /* check if is custom method */
+    if (bio->method && bio->method->getsCb) {
+        return bio->method->getsCb(bio, buf, sz);
+    }
+
+    switch (bio->type) {
+#ifndef NO_FILESYSTEM
+        case WOLFSSL_BIO_FILE:
+            if (((XFILE)bio->ptr) == XBADFILE) {
+                return WOLFSSL_BIO_ERROR;
+            }
+
+            #if defined(MICRIUM) || defined(LSR_FS) || defined(EBSNET)
+            WOLFSSL_MSG("XFGETS not ported for this system yet");
+            ret = XFGETS(buf, sz, (XFILE)bio->ptr);
+            #else
+            if (XFGETS(buf, sz, (XFILE)bio->ptr) != NULL) {
+                ret = (int)XSTRLEN(buf);
+            }
+            else {
+                ret = WOLFSSL_BIO_ERROR;
+            }
+            #endif
+            break;
+#endif /* NO_FILESYSTEM */
+        case WOLFSSL_BIO_MEMORY:
+            {
+                const byte* c;
+                int   cSz;
+                cSz = wolfSSL_BIO_pending(bio);
+                if (cSz == 0) {
+                    ret = 0; /* Nothing to read */
+                    buf[0] = '\0';
+                    break;
+                }
+
+                if (wolfSSL_BIO_get_mem_data(bio, (void*)&c) <= 0) {
+                    ret = WOLFSSL_BIO_ERROR;
+                    break;
+                }
+
+                cSz = wolfSSL_getLineLength((char*)c, cSz);
+                /* check case where line was bigger then buffer and buffer
+                 * needs end terminator */
+                if (cSz >= sz) {
+                    cSz = sz - 1;
+                    buf[cSz] = '\0';
+                }
+                else {
+                    /* not minus 1 here because placing terminator after
+                       msg and have checked that sz is large enough */
+                    buf[cSz] = '\0';
+                }
+
+                ret = wolfSSL_BIO_MEMORY_read(bio, (void*)buf, cSz);
+                /* ret is read after the switch statement */
+                break;
+            }
+        case WOLFSSL_BIO_BIO:
+            {
+                char* c;
+                int   cSz;
+                cSz = wolfSSL_BIO_nread0(bio, &c);
+                if (cSz == 0) {
+                    ret = 0; /* Nothing to read */
+                    buf[0] = '\0';
+                    break;
+                }
+
+                cSz = wolfSSL_getLineLength(c, cSz);
+                /* check case where line was bigger then buffer and buffer
+                 * needs end terminator */
+                if (cSz >= sz) {
+                    cSz = sz - 1;
+                    buf[cSz] = '\0';
+                }
+                else {
+                    /* not minus 1 here because placing terminator after
+                       msg and have checked that sz is large enough */
+                    buf[cSz] = '\0';
+                }
+
+                ret = wolfSSL_BIO_nread(bio, &c, cSz);
+                if (ret > 0 && ret < sz) {
+                    XMEMCPY(buf, c, ret);
+                }
+                break;
+            }
+
+#ifndef WOLFCRYPT_ONLY
+        /* call final on hash */
+        case WOLFSSL_BIO_MD:
+            if (wolfSSL_EVP_MD_CTX_size((WOLFSSL_EVP_MD_CTX*)bio->ptr) > sz) {
+                WOLFSSL_MSG("Output buffer was too small for digest");
+                ret = WOLFSSL_FAILURE;
+            }
+            else {
+                unsigned int szOut = 0;
+                ret = wolfSSL_EVP_DigestFinal((WOLFSSL_EVP_MD_CTX*)bio->ptr,
+                        (unsigned char*)buf, &szOut);
+                if (ret == WOLFSSL_SUCCESS) {
+                    ret = szOut;
+                }
+            }
+            break;
+#endif /* WOLFCRYPT_ONLY */
+
+        default:
+            WOLFSSL_MSG("BIO type not supported yet with wolfSSL_BIO_gets");
+    }
+
+    /* info cb, user can override return value */
+    if (bio->infoCb != NULL) {
+        ret = (int)bio->infoCb(bio, WOLFSSL_BIO_CB_GETS | WOLFSSL_BIO_CB_RETURN,
+                               buf, sz, 0, ret);
+    }
+
+    return ret;
+}
+
+
+/* Writes a null terminated string to bio.
+ *
+ * bio  the structure to write to
+ * buf  buffer to holding input string
+ *
+ * returns the size of the result placed in bio on success and a 0 or negative
+ *         value in an error case. -2 is returned if the implementation is not
+ *         supported for the BIO type.
+ */
+int wolfSSL_BIO_puts(WOLFSSL_BIO* bio, const char* buf)
+{
+    int sz;
+
+    if (bio == NULL || buf == NULL) {
+        return WOLFSSL_FATAL_ERROR;
+    }
+
+    /* check if is custom method */
+    if (bio->method && bio->method->putsCb) {
+        return bio->method->putsCb(bio, buf);
+    }
+
+    sz = (int)XSTRLEN(buf);
+    if (sz <= 0) {
+        return WOLFSSL_FATAL_ERROR;
+    }
+
+    return wolfSSL_BIO_write(bio, buf, sz);
+}
+
+
+/* searches through bio list for a BIO of type "type"
+ * returns NULL on failure to find a given type */
+WOLFSSL_BIO* wolfSSL_BIO_find_type(WOLFSSL_BIO* bio, int type)
+{
+    WOLFSSL_BIO* local = NULL;
+    WOLFSSL_BIO* current;
+
+    WOLFSSL_ENTER("wolfSSL_BIO_find_type");
+
+    if (bio == NULL) {
+        return local;
+    }
+
+    current = bio;
+    while (current != NULL) {
+        if (current->type == type) {
+            WOLFSSL_MSG("Found matching WOLFSSL_BIO type");
+            local = current;
+            break;
+        }
+        current = current->next;
+    }
+
+    return local;
+}
+
+
+/* returns a pointer to the next WOLFSSL_BIO in the chain on success.
+ * If a failure case then NULL is returned */
+WOLFSSL_BIO* wolfSSL_BIO_next(WOLFSSL_BIO* bio)
+{
+    WOLFSSL_ENTER("wolfSSL_BIO_next");
+
+    if (bio == NULL) {
+        WOLFSSL_MSG("Bad argument passed in");
+        return NULL;
+    }
+
+    return bio->next;
+}
+
+/* BIO_wpending returns the number of bytes pending to be written. */
+size_t wolfSSL_BIO_wpending(const WOLFSSL_BIO *bio)
+{
+    WOLFSSL_ENTER("BIO_wpending");
+
+    if (bio == NULL)
+        return 0;
+
+    if (bio->type == WOLFSSL_BIO_MEMORY) {
+        return bio->wrSz;
+    }
+
+    /* type BIO_BIO then check paired buffer */
+    if (bio->type == WOLFSSL_BIO_BIO && bio->pair != NULL) {
+        WOLFSSL_BIO* pair = bio->pair;
+        return pair->wrIdx;
+    }
+
+    return 0;
+}
+
+/* Return the number of pending bytes in read and write buffers */
+size_t wolfSSL_BIO_ctrl_pending(WOLFSSL_BIO *bio)
+{
+    WOLFSSL_ENTER("wolfSSL_BIO_ctrl_pending");
+    if (bio == NULL) {
+        return 0;
+    }
+
+    if (bio->type == WOLFSSL_BIO_MD) {
+        /* MD is a wrapper only get next bio */
+        while (bio->next != NULL) {
+            bio = bio->next;
+            if (bio->type != WOLFSSL_BIO_MD) {
+                break;
+            }
+        }
+    }
+
+#ifndef WOLFCRYPT_ONLY
+    if (bio->type == WOLFSSL_BIO_SSL && bio->ptr != NULL) {
+        return (long)wolfSSL_pending((WOLFSSL*)bio->ptr);
+    }
+#endif
+
+    if (bio->type == WOLFSSL_BIO_MEMORY) {
+        return bio->wrSz;
+    }
+
+    /* type BIO_BIO then check paired buffer */
+    if (bio->type == WOLFSSL_BIO_BIO && bio->pair != NULL) {
+        WOLFSSL_BIO* pair = bio->pair;
+        if (pair->wrIdx > 0 && pair->wrIdx <= pair->rdIdx) {
+            /* in wrap around state where beginning of buffer is being
+             * overwritten */
+            return pair->wrSz - pair->rdIdx + pair->wrIdx;
+        }
+        else {
+            /* simple case where has not wrapped around */
+            return pair->wrIdx - pair->rdIdx;
+        }
+    }
+    return 0;
+}
+
+
+long wolfSSL_BIO_get_mem_ptr(WOLFSSL_BIO *bio, WOLFSSL_BUF_MEM **ptr)
+{
+    WOLFSSL_BIO* front = bio;
+    long ret = WOLFSSL_FAILURE;
+
+    WOLFSSL_ENTER("wolfSSL_BIO_get_mem_ptr");
+
+    if (bio == NULL || ptr == NULL) {
+        return WOLFSSL_FAILURE;
+    }
+
+    /* start at end and work backwards to find a memory BIO in the BIO chain */
+    while ((bio != NULL) && (bio->next != NULL)) {
+        bio = bio->next;
+    }
+
+    while (bio != NULL) {
+
+        if (bio->type == WOLFSSL_BIO_MEMORY) {
+            *ptr = bio->mem_buf;
+            ret = WOLFSSL_SUCCESS;
+        }
+
+        if (bio == front) {
+            break;
+        }
+        bio = bio->prev;
+    }
+
+    return ret;
+}
+
+WOLFSSL_API long wolfSSL_BIO_int_ctrl(WOLFSSL_BIO *bp, int cmd, long larg, int iarg)
+{
+    (void) bp;
+    (void) cmd;
+    (void) larg;
+    (void) iarg;
+    WOLFSSL_STUB("BIO_int_ctrl");
+    return 0;
+}
+
+
+int wolfSSL_BIO_set_write_buf_size(WOLFSSL_BIO *bio, long size)
+{
+    WOLFSSL_ENTER("wolfSSL_BIO_set_write_buf_size");
+
+    if (bio == NULL || bio->type != WOLFSSL_BIO_BIO || size < 0) {
+        return WOLFSSL_FAILURE;
+    }
+
+    /* if already in pair then do not change size */
+    if (bio->pair != NULL) {
+        WOLFSSL_MSG("WOLFSSL_BIO is paired, free from pair before changing");
+        return WOLFSSL_FAILURE;
+    }
+
+    bio->wrSz  = (int)size;
+    if (bio->wrSz < 0) {
+        WOLFSSL_MSG("Unexpected negative size value");
+        return WOLFSSL_FAILURE;
+    }
+
+    if (bio->ptr != NULL) {
+        XFREE(bio->ptr, bio->heap, DYNAMIC_TYPE_OPENSSL);
+    }
+
+    bio->ptr = (byte*)XMALLOC(bio->wrSz, bio->heap, DYNAMIC_TYPE_OPENSSL);
+    if (bio->ptr == NULL) {
+        WOLFSSL_MSG("Memory allocation error");
+        return WOLFSSL_FAILURE;
+    }
+    bio->num = bio->wrSz;
+    bio->wrIdx = 0;
+    bio->rdIdx = 0;
+    if (bio->mem_buf != NULL) {
+        bio->mem_buf->data = (char*)bio->ptr;
+        bio->mem_buf->length = bio->num;
+    }
+
+    return WOLFSSL_SUCCESS;
+}
+
+
+/* Joins two BIO_BIO types. The write of b1 goes to the read of b2 and vice
+ * versa. Creating something similar to a two way pipe.
+ * Reading and writing between the two BIOs is not thread safe, they are
+ * expected to be used by the same thread. */
+int wolfSSL_BIO_make_bio_pair(WOLFSSL_BIO *b1, WOLFSSL_BIO *b2)
+{
+    WOLFSSL_ENTER("wolfSSL_BIO_make_bio_pair");
+
+    if (b1 == NULL || b2 == NULL) {
+        WOLFSSL_LEAVE("wolfSSL_BIO_make_bio_pair", BAD_FUNC_ARG);
+        return WOLFSSL_FAILURE;
+    }
+
+    /* both are expected to be of type BIO and not already paired */
+    if (b1->type != WOLFSSL_BIO_BIO || b2->type != WOLFSSL_BIO_BIO ||
+        b1->pair != NULL || b2->pair != NULL) {
+        WOLFSSL_MSG("Expected type BIO and not already paired");
+        return WOLFSSL_FAILURE;
+    }
+
+    /* set default write size if not already set */
+    if (b1->ptr == NULL && wolfSSL_BIO_set_write_buf_size(b1,
+                            WOLFSSL_BIO_SIZE) != WOLFSSL_SUCCESS) {
+        return WOLFSSL_FAILURE;
+    }
+
+    if (b2->ptr == NULL && wolfSSL_BIO_set_write_buf_size(b2,
+                            WOLFSSL_BIO_SIZE) != WOLFSSL_SUCCESS) {
+        return WOLFSSL_FAILURE;
+    }
+
+    b1->pair = b2;
+    b2->pair = b1;
+
+    return WOLFSSL_SUCCESS;
+}
+
+
+int wolfSSL_BIO_ctrl_reset_read_request(WOLFSSL_BIO *b)
+{
+    WOLFSSL_ENTER("wolfSSL_BIO_ctrl_reset_read_request");
+
+    if (b == NULL || b->type == WOLFSSL_BIO_MEMORY) {
+        return SSL_FAILURE;
+    }
+
+    b->readRq = 0;
+
+    return WOLFSSL_SUCCESS;
+}
+
+
+/* Does not advance read index pointer */
+int wolfSSL_BIO_nread0(WOLFSSL_BIO *bio, char **buf)
+{
+    WOLFSSL_ENTER("wolfSSL_BIO_nread0");
+
+    if (bio == NULL || buf == NULL) {
+        WOLFSSL_MSG("NULL argument passed in");
+        return 0;
+    }
+
+    /* if paired read from pair */
+    if (bio->pair != NULL) {
+        WOLFSSL_BIO* pair = bio->pair;
+
+        /* case where have wrapped around write buffer */
+        *buf = (char*)pair->ptr + pair->rdIdx;
+        if (pair->wrIdx > 0 && pair->rdIdx >= pair->wrIdx) {
+            return pair->wrSz - pair->rdIdx;
+        }
+        else {
+            return pair->wrIdx - pair->rdIdx;
+        }
+    }
+
+    return 0;
+}
+
+
+/* similar to wolfSSL_BIO_nread0 but advances the read index */
+int wolfSSL_BIO_nread(WOLFSSL_BIO *bio, char **buf, int num)
+{
+    int sz = WOLFSSL_BIO_UNSET;
+
+    WOLFSSL_ENTER("wolfSSL_BIO_nread");
+
+    if (bio == NULL || buf == NULL) {
+        WOLFSSL_MSG("NULL argument passed in");
+        return WOLFSSL_FAILURE;
+    }
+
+    if (bio->type == WOLFSSL_BIO_MEMORY) {
+        return SSL_FAILURE;
+    }
+
+    if (bio->pair != NULL) {
+        /* special case if asking to read 0 bytes */
+        if (num == 0) {
+            *buf = (char*)bio->pair->ptr + bio->pair->rdIdx;
+            return 0;
+        }
+
+        /* get amount able to read and set buffer pointer */
+        sz = wolfSSL_BIO_nread0(bio, buf);
+        if (sz == 0) {
+            return WOLFSSL_BIO_ERROR;
+        }
+
+        if (num < sz) {
+            sz = num;
+        }
+        bio->pair->rdIdx += sz;
+
+        /* check if have read to the end of the buffer and need to reset */
+        if (bio->pair->rdIdx == bio->pair->wrSz) {
+            bio->pair->rdIdx = 0;
+            if (bio->pair->wrIdx == bio->pair->wrSz) {
+                bio->pair->wrIdx = 0;
+            }
+        }
+
+        /* check if read up to write index, if so then reset index */
+        if (bio->pair->rdIdx == bio->pair->wrIdx) {
+            bio->pair->rdIdx = 0;
+            bio->pair->wrIdx = 0;
+        }
+    }
+
+    return sz;
+}
+
+
+int wolfSSL_BIO_nwrite(WOLFSSL_BIO *bio, char **buf, int num)
+{
+    int sz = WOLFSSL_BIO_UNSET;
+
+    WOLFSSL_ENTER("wolfSSL_BIO_nwrite");
+
+    if (bio == NULL || buf == NULL) {
+        WOLFSSL_MSG("NULL argument passed in");
+        return 0;
+    }
+
+    if (bio->type != WOLFSSL_BIO_BIO) {
+        return SSL_FAILURE;
+    }
+
+    if (bio->pair != NULL) {
+        if (num == 0) {
+            *buf = (char*)bio->ptr + bio->wrIdx;
+            return 0;
+        }
+
+        if (bio->wrIdx < bio->rdIdx) {
+            /* if wrapped around only write up to read index. In this case
+             * rdIdx is always greater then wrIdx so sz will not be negative. */
+            sz = bio->rdIdx - bio->wrIdx;
+        }
+        else if (bio->rdIdx > 0 && bio->wrIdx == bio->rdIdx) {
+            return WOLFSSL_BIO_ERROR; /* no more room to write */
+        }
+        else {
+            /* write index is past read index so write to end of buffer */
+            sz = bio->wrSz - bio->wrIdx;
+
+            if (sz <= 0) {
+                /* either an error has occurred with write index or it is at the
+                 * end of the write buffer. */
+                if (bio->rdIdx == 0) {
+                    /* no more room, nothing has been read */
+                    return WOLFSSL_BIO_ERROR;
+                }
+
+                bio->wrIdx = 0;
+
+                /* check case where read index is not at 0 */
+                if (bio->rdIdx > 0) {
+                    sz = bio->rdIdx; /* can write up to the read index */
+                }
+                else {
+                    sz = bio->wrSz; /* no restriction other then buffer size */
+                }
+            }
+        }
+
+        if (num < sz) {
+            sz = num;
+        }
+        *buf = (char*)bio->ptr + bio->wrIdx;
+        bio->wrIdx += sz;
+
+        /* if at the end of the buffer and space for wrap around then set
+         * write index back to 0 */
+        if (bio->wrIdx == bio->wrSz && bio->rdIdx > 0) {
+            bio->wrIdx = 0;
+        }
+    }
+
+    return sz;
+}
+
+
+/* Reset BIO to initial state */
+int wolfSSL_BIO_reset(WOLFSSL_BIO *bio)
+{
+    WOLFSSL_ENTER("wolfSSL_BIO_reset");
+
+    if (bio == NULL) {
+        WOLFSSL_MSG("NULL argument passed in");
+        /* -1 is consistent failure even for FILE type */
+        return WOLFSSL_BIO_ERROR;
+    }
+
+    switch (bio->type) {
+        #ifndef NO_FILESYSTEM
+        case WOLFSSL_BIO_FILE:
+            XREWIND((XFILE)bio->ptr);
+            return 0;
+        #endif
+
+        case WOLFSSL_BIO_BIO:
+            bio->rdIdx = 0;
+            bio->wrIdx = 0;
+            return 0;
+
+        case WOLFSSL_BIO_MEMORY:
+            bio->rdIdx = 0;
+            bio->wrIdx = 0;
+            bio->wrSz  = 0;
+            XFREE(bio->ptr, bio->heap, DYNAMIC_TYPE_OPENSSL);
+            bio->ptr = NULL;
+            bio->num = 0;
+            if (bio->mem_buf != NULL) {
+                bio->mem_buf->data = (char*)bio->ptr;
+                bio->mem_buf->length = bio->num;
+            }
+            return 0;
+
+#ifndef WOLFCRYPT_ONLY
+        case WOLFSSL_BIO_MD:
+            if (bio->ptr != NULL) {
+                const WOLFSSL_EVP_MD* md =
+                    wolfSSL_EVP_MD_CTX_md((WOLFSSL_EVP_MD_CTX*)bio->ptr);
+                wolfSSL_EVP_MD_CTX_init((WOLFSSL_EVP_MD_CTX*)bio->ptr);
+                wolfSSL_EVP_DigestInit((WOLFSSL_EVP_MD_CTX*)bio->ptr, md);
+            }
+            return 0;
+#endif /* WOLFCRYPT_ONLY */
+
+        default:
+            WOLFSSL_MSG("Unknown BIO type needs added to reset function");
+    }
+
+    return WOLFSSL_BIO_ERROR;
+}
+
+#ifndef NO_FILESYSTEM
+long wolfSSL_BIO_set_fp(WOLFSSL_BIO *bio, XFILE fp, int c)
+{
+    WOLFSSL_ENTER("wolfSSL_BIO_set_fp");
+
+    if (bio == NULL || fp == XBADFILE) {
+        WOLFSSL_LEAVE("wolfSSL_BIO_set_fp", BAD_FUNC_ARG);
+        return WOLFSSL_FAILURE;
+    }
+
+    if (bio->type != WOLFSSL_BIO_FILE) {
+        return WOLFSSL_FAILURE;
+    }
+
+    bio->shutdown = (byte)c;
+    bio->ptr = (XFILE)fp;
+
+    return WOLFSSL_SUCCESS;
+}
+
+
+long wolfSSL_BIO_get_fp(WOLFSSL_BIO *bio, XFILE* fp)
+{
+    WOLFSSL_ENTER("wolfSSL_BIO_get_fp");
+
+    if (bio == NULL || fp == XBADFILE) {
+        return WOLFSSL_FAILURE;
+    }
+
+    if (bio->type != WOLFSSL_BIO_FILE) {
+        return SSL_FAILURE;
+    }
+
+    *fp = (XFILE)bio->ptr;
+
+    return WOLFSSL_SUCCESS;
+}
+
+/* overwrites file */
+int wolfSSL_BIO_write_filename(WOLFSSL_BIO *bio, char *name)
+{
+    WOLFSSL_ENTER("wolfSSL_BIO_write_filename");
+
+    if (bio == NULL || name == NULL) {
+        return WOLFSSL_FAILURE;
+    }
+
+    if (bio->type == WOLFSSL_BIO_FILE) {
+        if (((XFILE)bio->ptr) != XBADFILE && bio->shutdown == BIO_CLOSE) {
+            XFCLOSE((XFILE)bio->ptr);
+        }
+
+        bio->ptr = XFOPEN(name, "w");
+        if (((XFILE)bio->ptr) == XBADFILE) {
+            return WOLFSSL_FAILURE;
+        }
+        bio->shutdown = BIO_CLOSE;
+
+        return WOLFSSL_SUCCESS;
+    }
+
+    return WOLFSSL_FAILURE;
+}
+
+
+int wolfSSL_BIO_seek(WOLFSSL_BIO *bio, int ofs)
+{
+      WOLFSSL_ENTER("wolfSSL_BIO_seek");
+
+      if (bio == NULL) {
+          return -1;
+      }
+
+      /* offset ofs from beginning of file */
+      if (bio->type == WOLFSSL_BIO_FILE &&
+              XFSEEK((XFILE)bio->ptr, ofs, SEEK_SET) < 0) {
+          return -1;
+      }
+
+      return 0;
+}
+#endif /* NO_FILESYSTEM */
+
+
+long wolfSSL_BIO_set_mem_eof_return(WOLFSSL_BIO *bio, int v)
+{
+      WOLFSSL_ENTER("wolfSSL_BIO_set_mem_eof_return");
+
+      if (bio != NULL) {
+        bio->eof = v;
+      }
+
+      return 0;
+}
+
+int wolfSSL_BIO_get_len(WOLFSSL_BIO *bio)
+{
+    int len;
+#ifndef NO_FILESYSTEM
+    long memSz = 0, curr = 0;
+    XFILE file;
+#endif
+
+    WOLFSSL_ENTER("wolfSSL_BIO_get_len");
+
+    if ((len = wolfSSL_BIO_pending(bio)) > 0) {
+    }
+#ifndef NO_FILESYSTEM
+    else if (bio->type == WOLFSSL_BIO_FILE) {
+        if (wolfSSL_BIO_get_fp(bio, &file) != WOLFSSL_SUCCESS)
+            len = BAD_FUNC_ARG;
+        if (len == 0) {
+            curr = XFTELL(file);
+            if (curr < 0) {
+                len = WOLFSSL_BAD_FILE;
+            }
+            if (XFSEEK(file, 0, XSEEK_END) != 0)
+                len = WOLFSSL_BAD_FILE;
+        }
+        if (len == 0) {
+            memSz = XFTELL(file);
+            if (memSz > MAX_WOLFSSL_FILE_SIZE || memSz < 0)
+                len = WOLFSSL_BAD_FILE;
+        }
+        if (len == 0) {
+            memSz -= curr;
+            len = (int)memSz;
+            if (XFSEEK(file, curr, SEEK_SET) != 0)
+                len = WOLFSSL_BAD_FILE;
+        }
+    }
+#endif
+    return len;
+}
+
+
+void wolfSSL_BIO_set_callback(WOLFSSL_BIO *bio, wolf_bio_info_cb callback_func)
+{
+    WOLFSSL_ENTER("wolfSSL_BIO_set_callback");
+
+    if (bio != NULL) {
+        bio->infoCb = callback_func;
+    }
+}
+
+
+wolf_bio_info_cb wolfSSL_BIO_get_callback(WOLFSSL_BIO *bio)
+{
+    WOLFSSL_ENTER("wolfSSL_BIO_get_callback");
+
+    if (bio != NULL) {
+        return bio->infoCb;
+    }
+
+    return NULL;
+}
+
+
+void wolfSSL_BIO_set_callback_arg(WOLFSSL_BIO *bio, char *arg)
+{
+    WOLFSSL_ENTER("wolfSSL_BIO_set_callback_arg");
+
+    if (bio != NULL) {
+        bio->infoArg = arg;
+    }
+}
+
+
+char* wolfSSL_BIO_get_callback_arg(const WOLFSSL_BIO *bio)
+{
+    WOLFSSL_ENTER("wolfSSL_BIO_get_callback_arg");
+
+    if (bio != NULL) {
+        return bio->infoArg;
+    }
+
+    return NULL;
+}
+
+
+/* store a user pointer in the WOLFSSL_BIO structure */
+void wolfSSL_BIO_set_data(WOLFSSL_BIO* bio, void *ptr)
+{
+    WOLFSSL_ENTER("wolfSSL_BIO_set_data");
+
+    if (bio != NULL) {
+        bio->usrCtx = ptr;
+    }
+}
+
+
+void* wolfSSL_BIO_get_data(WOLFSSL_BIO* bio)
+{
+    WOLFSSL_ENTER("wolfSSL_BIO_get_data");
+
+    if (bio != NULL)
+        return bio->usrCtx;
+
+    WOLFSSL_MSG("WOLFSSL_BIO was null");
+    return NULL;
+}
+
+/* If flag is 0 then blocking is set, if 1 then non blocking.
+ * Always returns 1
+ */
+long wolfSSL_BIO_set_nbio(WOLFSSL_BIO* bio, long on)
+{
+    #ifndef WOLFSSL_DTLS
+    (void)on;
+    #endif
+    WOLFSSL_ENTER("wolfSSL_BIO_set_nbio");
+
+    switch (bio->type) {
+        case WOLFSSL_BIO_SOCKET:
+        #ifdef XFCNTL
+            {
+                int flag = XFCNTL(bio->num, F_GETFL, 0);
+                if (on)
+                    XFCNTL(bio->num, F_SETFL, flag | O_NONBLOCK);
+                else
+                    XFCNTL(bio->num, F_SETFL, flag & ~O_NONBLOCK);
+            }
+        #endif
+            break;
+        case WOLFSSL_BIO_SSL:
+        #ifdef WOLFSSL_DTLS
+            wolfSSL_dtls_set_using_nonblock((WOLFSSL*)bio->ptr, (int)on);
+        #endif
+            break;
+
+        default:
+            WOLFSSL_MSG("Unsupported bio type for non blocking");
+            break;
+    }
+
+    return 1;
+}
+
+
+
+/* creates a new custom WOLFSSL_BIO_METHOD */
+WOLFSSL_BIO_METHOD *wolfSSL_BIO_meth_new(int type, const char *name)
+{
+    WOLFSSL_BIO_METHOD* meth;
+
+    WOLFSSL_ENTER("wolfSSL_BIO_meth_new");
+
+    meth = (WOLFSSL_BIO_METHOD*)XMALLOC(sizeof(WOLFSSL_BIO_METHOD), NULL,
+            DYNAMIC_TYPE_OPENSSL);
+    if (meth == NULL) {
+        WOLFSSL_MSG("Error allocating memory for WOLFSSL_BIO_METHOD");
+        return NULL;
+    }
+    XMEMSET(meth, 0, sizeof(WOLFSSL_BIO_METHOD));
+    meth->type = (byte)type;
+    XSTRNCPY(meth->name, name, MAX_BIO_METHOD_NAME - 1);
+
+    return meth;
+}
+
+
+void wolfSSL_BIO_meth_free(WOLFSSL_BIO_METHOD *biom)
+{
+    WOLFSSL_ENTER("wolfSSL_BIO_meth_free");
+    if (biom) {
+        XFREE(biom, NULL, DYNAMIC_TYPE_OPENSSL);
+    }
+}
+
+
+int wolfSSL_BIO_meth_set_write(WOLFSSL_BIO_METHOD *biom,
+        wolfSSL_BIO_meth_write_cb biom_write)
+{
+    WOLFSSL_ENTER("wolfSSL_BIO_meth_set_write");
+    if (biom) {
+        biom->writeCb = biom_write;
+        return WOLFSSL_SUCCESS;
+    }
+    return WOLFSSL_FAILURE;
+}
+
+
+int wolfSSL_BIO_meth_set_read(WOLFSSL_BIO_METHOD *biom,
+        wolfSSL_BIO_meth_read_cb biom_read)
+{
+    WOLFSSL_ENTER("wolfSSL_BIO_meth_set_read");
+    if (biom) {
+        biom->readCb = biom_read;
+        return WOLFSSL_SUCCESS;
+    }
+    return WOLFSSL_FAILURE;
+}
+
+
+int wolfSSL_BIO_meth_set_puts(WOLFSSL_BIO_METHOD *biom,
+        wolfSSL_BIO_meth_puts_cb biom_puts)
+{
+    WOLFSSL_ENTER("wolfSSL_BIO_meth_set_puts");
+    if (biom) {
+        biom->putsCb = biom_puts;
+        return WOLFSSL_SUCCESS;
+    }
+    return WOLFSSL_FAILURE;
+}
+
+
+int wolfSSL_BIO_meth_set_gets(WOLFSSL_BIO_METHOD *biom,
+        wolfSSL_BIO_meth_gets_cb biom_gets)
+{
+    WOLFSSL_ENTER("wolfSSL_BIO_meth_set_gets");
+    if (biom) {
+        biom->getsCb = biom_gets;
+        return WOLFSSL_SUCCESS;
+    }
+    return WOLFSSL_FAILURE;
+}
+
+
+int wolfSSL_BIO_meth_set_ctrl(WOLFSSL_BIO_METHOD *biom,
+        wolfSSL_BIO_meth_ctrl_get_cb biom_ctrl)
+{
+    WOLFSSL_ENTER("wolfSSL_BIO_meth_set_ctrl");
+    if (biom) {
+        biom->ctrlCb = biom_ctrl;
+        return WOLFSSL_SUCCESS;
+    }
+    return WOLFSSL_FAILURE;
+}
+
+
+int wolfSSL_BIO_meth_set_create(WOLFSSL_BIO_METHOD *biom,
+        wolfSSL_BIO_meth_create_cb biom_create)
+{
+    WOLFSSL_ENTER("wolfSSL_BIO_meth_set_create");
+    if (biom) {
+        biom->createCb = biom_create;
+        return WOLFSSL_SUCCESS;
+    }
+    return WOLFSSL_FAILURE;
+}
+
+
+int wolfSSL_BIO_meth_set_destroy(WOLFSSL_BIO_METHOD *biom,
+        wolfSSL_BIO_meth_destroy_cb biom_destroy)
+{
+    WOLFSSL_STUB("wolfSSL_BIO_meth_set_destroy");
+    if (biom) {
+        biom->freeCb = biom_destroy;
+        return WOLFSSL_SUCCESS;
+    }
+    return WOLFSSL_FAILURE;
+}
+
+
+/* this compatibility function can be used for multiple BIO types */
+int wolfSSL_BIO_get_mem_data(WOLFSSL_BIO* bio, void* p)
+{
+    WOLFSSL_ENTER("wolfSSL_BIO_get_mem_data");
+
+    if (bio == NULL)
+        return WOLFSSL_FATAL_ERROR;
+
+    if (p) {
+        *(byte**)p = (byte*)bio->ptr;
+    }
+
+    return bio->num;
+}
+
+int wolfSSL_BIO_pending(WOLFSSL_BIO* bio)
+{
+    return (int)wolfSSL_BIO_ctrl_pending(bio);
+}
+
+
+int wolfSSL_BIO_flush(WOLFSSL_BIO* bio)
+{
+    /* for wolfSSL no flushing needed */
+    WOLFSSL_ENTER("BIO_flush");
+    (void)bio;
+    return 1;
+}
+#endif /* WOLFSSL_BIO_INCLUDED */
Index: azure_iot_hub_f767zi/trunk/wolfssl-4.4.0/src/config.h
===================================================================
--- azure_iot_hub_f767zi/trunk/wolfssl-4.4.0/src/config.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/wolfssl-4.4.0/src/config.h	(revision 457)
@@ -0,0 +1,193 @@
+/* config.h.  Generated from config.in by configure.  */
+/* config.in.  Generated from configure.ac by autoheader.  */
+
+/* Define if building universal (internal helper macro) */
+/* #undef AC_APPLE_UNIVERSAL_BUILD */
+
+/* User RSA is being defined */
+#define BUILD_USER_RSA /**/
+
+/* Define to 1 to enable debugging code. */
+#define DEBUG 0
+
+/* Define to 1 if you have the <arpa/inet.h> header file. */
+#define HAVE_ARPA_INET_H 1
+
+/* Define to 1 if you have the <dlfcn.h> header file. */
+#define HAVE_DLFCN_H 1
+
+/* Define to 1 if you have the <errno.h> header file. */
+#define HAVE_ERRNO_H 1
+
+/* Define to 1 if you have the <fcntl.h> header file. */
+#define HAVE_FCNTL_H 1
+
+/* Define to 1 if you have the `getaddrinfo' function. */
+#define HAVE_GETADDRINFO 1
+
+/* Define to 1 if you have the `gethostbyname' function. */
+#define HAVE_GETHOSTBYNAME 1
+
+/* Define to 1 if you have the `gettimeofday' function. */
+#define HAVE_GETTIMEOFDAY 1
+
+/* Define to 1 if you have the `gmtime_r' function. */
+#define HAVE_GMTIME_R 1
+
+/* Define to 1 if you have the `inet_ntoa' function. */
+#define HAVE_INET_NTOA 1
+
+/* Define to 1 if you have the <inttypes.h> header file. */
+#define HAVE_INTTYPES_H 1
+
+/* Define to 1 if you have the <ippcp.h> header file. */
+/* #undef HAVE_IPPCP_H */
+
+/* Define to 1 if you have the `network' library (-lnetwork). */
+/* #undef HAVE_LIBNETWORK */
+
+/* Define to 1 if you have the `pthread' library (-lpthread). */
+/* #undef HAVE_LIBPTHREAD */
+
+/* Define to 1 if you have the <limits.h> header file. */
+#define HAVE_LIMITS_H 1
+
+/* Define to 1 if you have the <memory.h> header file. */
+#define HAVE_MEMORY_H 1
+
+/* Define to 1 if you have the `memset' function. */
+#define HAVE_MEMSET 1
+
+/* Define to 1 if you have the <netdb.h> header file. */
+#define HAVE_NETDB_H 1
+
+/* Define to 1 if you have the <netinet/in.h> header file. */
+#define HAVE_NETINET_IN_H 1
+
+/* Define to 1 if you have the <pcap/pcap.h> header file. */
+/* #undef HAVE_PCAP_PCAP_H */
+
+/* Define if you have POSIX threads libraries and header files. */
+#define HAVE_PTHREAD 1
+
+/* Have PTHREAD_PRIO_INHERIT. */
+#define HAVE_PTHREAD_PRIO_INHERIT 1
+
+/* Define to 1 if you have the `socket' function. */
+#define HAVE_SOCKET 1
+
+/* Define to 1 if you have the <stddef.h> header file. */
+#define HAVE_STDDEF_H 1
+
+/* Define to 1 if you have the <stdint.h> header file. */
+#define HAVE_STDINT_H 1
+
+/* Define to 1 if you have the <stdlib.h> header file. */
+#define HAVE_STDLIB_H 1
+
+/* Define to 1 if you have the <strings.h> header file. */
+#define HAVE_STRINGS_H 1
+
+/* Define to 1 if you have the <string.h> header file. */
+#define HAVE_STRING_H 1
+
+/* Define to 1 if you have the <sys/ioctl.h> header file. */
+#define HAVE_SYS_IOCTL_H 1
+
+/* Define to 1 if you have the <sys/socket.h> header file. */
+#define HAVE_SYS_SOCKET_H 1
+
+/* Define to 1 if you have the <sys/stat.h> header file. */
+#define HAVE_SYS_STAT_H 1
+
+/* Define to 1 if you have the <sys/time.h> header file. */
+#define HAVE_SYS_TIME_H 1
+
+/* Define to 1 if you have the <sys/types.h> header file. */
+#define HAVE_SYS_TYPES_H 1
+
+/* Define to 1 if you have the <unistd.h> header file. */
+#define HAVE_UNISTD_H 1
+
+/* Define to 1 or 0, depending whether the compiler supports simple visibility
+   declarations. */
+#define HAVE_VISIBILITY 1
+
+/* Define to 1 if the system has the type `__uint128_t'. */
+/* #undef HAVE___UINT128_T */
+
+/* Define to the sub-directory where libtool stores uninstalled libraries. */
+#define LT_OBJDIR ".libs/"
+
+/* Define to 1 if your C compiler doesn't accept -c and -o together. */
+/* #undef NO_MINUS_C_MINUS_O */
+
+/* Define to the address where bug reports for this package should be sent. */
+#define PACKAGE_BUGREPORT "https://github.com/wolfssl/wolfssl/issues"
+
+/* Define to the full name of this package. */
+#define PACKAGE_NAME "wolfssl"
+
+/* Define to the full name and version of this package. */
+#define PACKAGE_STRING "wolfssl 3.15.7"
+
+/* Define to the one symbol short name of this package. */
+#define PACKAGE_TARNAME "wolfssl"
+
+/* Define to the home page for this package. */
+#define PACKAGE_URL "https://www.wolfssl.com"
+
+/* Define to the version of this package. */
+#define PACKAGE_VERSION "3.15.7"
+
+/* Define to necessary symbol if this constant uses a non-standard name on
+   your system. */
+/* #undef PTHREAD_CREATE_JOINABLE */
+
+/* The size of `long', as computed by sizeof. */
+#define SIZEOF_LONG 4
+
+/* The size of `long long', as computed by sizeof. */
+#define SIZEOF_LONG_LONG 8
+
+/* The size of `time_t', as computed by sizeof. */
+#define SIZEOF_TIME_T 8
+
+/* Define to 1 if you have the ANSI C header files. */
+#define STDC_HEADERS 1
+
+/* If the compiler supports a TLS storage class define it to that here */
+#define TLS __thread
+
+/* Define if the code was built from VCS. */
+#define VCS_CHECKOUT 0
+
+/* VCS system */
+#define VCS_SYSTEM "none"
+
+/* Use __declspec(dllexport) when building library */
+/* #undef WOLFSSL_DLL */
+
+/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most
+   significant byte first (like Motorola and SPARC, unlike Intel). */
+#if defined AC_APPLE_UNIVERSAL_BUILD
+# if defined __BIG_ENDIAN__
+#  define WORDS_BIGENDIAN 1
+# endif
+#else
+# ifndef WORDS_BIGENDIAN
+/* #  undef WORDS_BIGENDIAN */
+# endif
+#endif
+
+/* Define for Solaris 2.5.1 so the uint8_t typedef from <sys/synch.h>,
+   <pthread.h>, or <semaphore.h> is not used. If the typedef were allowed, the
+   #define below would cause a syntax error. */
+/* #undef _UINT8_T */
+
+/* Define to `unsigned int' if <sys/types.h> does not define. */
+/* #undef size_t */
+
+/* Define to the type of an unsigned integer type of width exactly 8 bits if
+   such a type exists and the standard includes do not define it. */
+/* #undef uint8_t */
Index: azure_iot_hub_f767zi/trunk/wolfssl-4.4.0/src/crl.c
===================================================================
--- azure_iot_hub_f767zi/trunk/wolfssl-4.4.0/src/crl.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/wolfssl-4.4.0/src/crl.c	(revision 457)
@@ -0,0 +1,1093 @@
+/* crl.c
+ *
+ * Copyright (C) 2006-2020 wolfSSL Inc.
+ *
+ * This file is part of wolfSSL.
+ *
+ * wolfSSL is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * wolfSSL is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
+ */
+
+
+  /* Name change compatibility layer no longer needs included here */
+
+#ifdef HAVE_CONFIG_H
+    #include <config.h>
+#endif
+
+#include <wolfssl/wolfcrypt/settings.h>
+
+#ifndef WOLFCRYPT_ONLY
+#ifdef HAVE_CRL
+
+#include <wolfssl/internal.h>
+#include <wolfssl/error-ssl.h>
+
+#include <string.h>
+
+#ifdef HAVE_CRL_MONITOR
+    #if (defined(__MACH__) || defined(__FreeBSD__) || defined(__linux__))
+        static int StopMonitor(int mfd);
+    #else
+        #error "CRL monitor only currently supported on linux or mach"
+    #endif
+#endif /* HAVE_CRL_MONITOR */
+
+
+/* Initialize CRL members */
+int InitCRL(WOLFSSL_CRL* crl, WOLFSSL_CERT_MANAGER* cm)
+{
+    WOLFSSL_ENTER("InitCRL");
+    if(cm != NULL)
+        crl->heap = cm->heap;
+    else
+        crl->heap = NULL;
+    crl->cm = cm;
+    crl->crlList = NULL;
+    crl->monitors[0].path = NULL;
+    crl->monitors[1].path = NULL;
+#ifdef HAVE_CRL_MONITOR
+    crl->tid   =  0;
+    crl->mfd   = -1;    /* mfd for bsd is kqueue fd, eventfd for linux */
+    crl->setup = 0;     /* thread setup done predicate */
+    if (pthread_cond_init(&crl->cond, 0) != 0) {
+        WOLFSSL_MSG("Pthread condition init failed");
+        return BAD_COND_E;
+    }
+#endif
+    if (wc_InitMutex(&crl->crlLock) != 0) {
+        WOLFSSL_MSG("Init Mutex failed");
+        return BAD_MUTEX_E;
+    }
+
+    return 0;
+}
+
+
+/* Initialize CRL Entry */
+static int InitCRL_Entry(CRL_Entry* crle, DecodedCRL* dcrl, const byte* buff,
+                         int verified, void* heap)
+{
+    WOLFSSL_ENTER("InitCRL_Entry");
+
+    XMEMCPY(crle->issuerHash, dcrl->issuerHash, CRL_DIGEST_SIZE);
+    /* XMEMCPY(crle->crlHash, dcrl->crlHash, CRL_DIGEST_SIZE);
+     * copy the hash here if needed for optimized comparisons */
+    XMEMCPY(crle->lastDate, dcrl->lastDate, MAX_DATE_SIZE);
+    XMEMCPY(crle->nextDate, dcrl->nextDate, MAX_DATE_SIZE);
+    crle->lastDateFormat = dcrl->lastDateFormat;
+    crle->nextDateFormat = dcrl->nextDateFormat;
+
+    crle->certs = dcrl->certs;   /* take ownsership */
+    dcrl->certs = NULL;
+    crle->totalCerts = dcrl->totalCerts;
+    crle->verified = verified;
+    if (!verified) {
+        crle->tbsSz = dcrl->sigIndex - dcrl->certBegin;
+        crle->signatureSz = dcrl->sigLength;
+        crle->signatureOID = dcrl->signatureOID;
+        crle->toBeSigned = (byte*)XMALLOC(crle->tbsSz, heap,
+                                          DYNAMIC_TYPE_CRL_ENTRY);
+        if (crle->toBeSigned == NULL)
+            return -1;
+        crle->signature = (byte*)XMALLOC(crle->signatureSz, heap,
+                                         DYNAMIC_TYPE_CRL_ENTRY);
+        if (crle->signature == NULL) {
+            XFREE(crle->toBeSigned, heap, DYNAMIC_TYPE_CRL_ENTRY);
+            return -1;
+        }
+        XMEMCPY(crle->toBeSigned, buff + dcrl->certBegin, crle->tbsSz);
+        XMEMCPY(crle->signature, dcrl->signature, crle->signatureSz);
+    #ifndef NO_SKID
+        crle->extAuthKeyIdSet = dcrl->extAuthKeyIdSet;
+        if (crle->extAuthKeyIdSet)
+            XMEMCPY(crle->extAuthKeyId, dcrl->extAuthKeyId, KEYID_SIZE);
+    #endif
+    }
+    else {
+        crle->toBeSigned = NULL;
+        crle->signature = NULL;
+    }
+
+    (void)verified;
+    (void)heap;
+
+    return 0;
+}
+
+
+/* Free all CRL Entry resources */
+static void FreeCRL_Entry(CRL_Entry* crle, void* heap)
+{
+    RevokedCert* tmp = crle->certs;
+    RevokedCert* next;
+
+    WOLFSSL_ENTER("FreeCRL_Entry");
+
+    while (tmp) {
+        next = tmp->next;
+        XFREE(tmp, heap, DYNAMIC_TYPE_REVOKED);
+        tmp = next;
+    }
+    if (crle->signature != NULL)
+        XFREE(crle->signature, heap, DYNAMIC_TYPE_REVOKED);
+    if (crle->toBeSigned != NULL)
+        XFREE(crle->toBeSigned, heap, DYNAMIC_TYPE_REVOKED);
+
+    (void)heap;
+}
+
+
+
+/* Free all CRL resources */
+void FreeCRL(WOLFSSL_CRL* crl, int dynamic)
+{
+    CRL_Entry* tmp = crl->crlList;
+
+    WOLFSSL_ENTER("FreeCRL");
+    if (crl->monitors[0].path)
+        XFREE(crl->monitors[0].path, crl->heap, DYNAMIC_TYPE_CRL_MONITOR);
+
+    if (crl->monitors[1].path)
+        XFREE(crl->monitors[1].path, crl->heap, DYNAMIC_TYPE_CRL_MONITOR);
+
+    while(tmp) {
+        CRL_Entry* next = tmp->next;
+        FreeCRL_Entry(tmp, crl->heap);
+        XFREE(tmp, crl->heap, DYNAMIC_TYPE_CRL_ENTRY);
+        tmp = next;
+    }
+
+#ifdef HAVE_CRL_MONITOR
+    if (crl->tid != 0) {
+        WOLFSSL_MSG("stopping monitor thread");
+        if (StopMonitor(crl->mfd) == 0)
+            pthread_join(crl->tid, NULL);
+        else {
+            WOLFSSL_MSG("stop monitor failed");
+        }
+    }
+    pthread_cond_destroy(&crl->cond);
+#endif
+    wc_FreeMutex(&crl->crlLock);
+    if (dynamic)   /* free self */
+        XFREE(crl, crl->heap, DYNAMIC_TYPE_CRL);
+}
+
+
+static int CheckCertCRLList(WOLFSSL_CRL* crl, DecodedCert* cert, int *pFoundEntry)
+{
+    CRL_Entry* crle;
+    int        foundEntry = 0;
+    int        ret = 0;
+
+    if (wc_LockMutex(&crl->crlLock) != 0) {
+        WOLFSSL_MSG("wc_LockMutex failed");
+        return BAD_MUTEX_E;
+    }
+
+    crle = crl->crlList;
+
+    while (crle) {
+        if (XMEMCMP(crle->issuerHash, cert->issuerHash, CRL_DIGEST_SIZE) == 0) {
+            WOLFSSL_MSG("Found CRL Entry on list");
+
+            if (crle->verified == 0) {
+                Signer* ca = NULL;
+            #ifndef NO_SKID
+                byte extAuthKeyId[KEYID_SIZE];
+            #endif
+                byte issuerHash[CRL_DIGEST_SIZE];
+                byte* tbs;
+                word32 tbsSz = crle->tbsSz;
+                byte* sig = NULL;
+                word32 sigSz = crle->signatureSz;
+                word32 sigOID = crle->signatureOID;
+                SignatureCtx sigCtx;
+
+                tbs = (byte*)XMALLOC(tbsSz, crl->heap, DYNAMIC_TYPE_CRL_ENTRY);
+                if (tbs == NULL) {
+                    wc_UnLockMutex(&crl->crlLock);
+                    return MEMORY_E;
+                }
+                sig = (byte*)XMALLOC(sigSz, crl->heap, DYNAMIC_TYPE_CRL_ENTRY);
+                if (sig == NULL) {
+                    XFREE(tbs, crl->heap, DYNAMIC_TYPE_CRL_ENTRY);
+                    wc_UnLockMutex(&crl->crlLock);
+                    return MEMORY_E;
+                }
+
+                XMEMCPY(tbs, crle->toBeSigned, tbsSz);
+                XMEMCPY(sig, crle->signature, sigSz);
+            #ifndef NO_SKID
+                XMEMCPY(extAuthKeyId, crle->extAuthKeyId,
+                                                          sizeof(extAuthKeyId));
+            #endif
+                XMEMCPY(issuerHash, crle->issuerHash, sizeof(issuerHash));
+
+                wc_UnLockMutex(&crl->crlLock);
+
+            #ifndef NO_SKID
+                if (crle->extAuthKeyIdSet)
+                    ca = GetCA(crl->cm, extAuthKeyId);
+                if (ca == NULL)
+                    ca = GetCAByName(crl->cm, issuerHash);
+            #else /* NO_SKID */
+                ca = GetCA(crl->cm, issuerHash);
+            #endif /* NO_SKID */
+                if (ca == NULL) {
+                    XFREE(sig, crl->heap, DYNAMIC_TYPE_CRL_ENTRY);
+                    XFREE(tbs, crl->heap, DYNAMIC_TYPE_CRL_ENTRY);
+                    WOLFSSL_MSG("Did NOT find CRL issuer CA");
+                    return ASN_CRL_NO_SIGNER_E;
+                }
+
+                ret = VerifyCRL_Signature(&sigCtx, tbs, tbsSz, sig, sigSz,
+                                          sigOID, ca, crl->heap);
+
+                XFREE(sig, crl->heap, DYNAMIC_TYPE_CRL_ENTRY);
+                XFREE(tbs, crl->heap, DYNAMIC_TYPE_CRL_ENTRY);
+
+                if (wc_LockMutex(&crl->crlLock) != 0) {
+                    WOLFSSL_MSG("wc_LockMutex failed");
+                    return BAD_MUTEX_E;
+                }
+
+                crle = crl->crlList;
+                while (crle) {
+                    if (XMEMCMP(crle->issuerHash, cert->issuerHash,
+                        CRL_DIGEST_SIZE) == 0) {
+
+                        if (ret == 0)
+                            crle->verified = 1;
+                        else
+                            crle->verified = ret;
+
+                        XFREE(crle->toBeSigned, crl->heap,
+                                                        DYNAMIC_TYPE_CRL_ENTRY);
+                        crle->toBeSigned = NULL;
+                        XFREE(crle->signature, crl->heap,
+                                                        DYNAMIC_TYPE_CRL_ENTRY);
+                        crle->signature = NULL;
+                        break;
+                    }
+                    crle = crle->next;
+                }
+                if (crle == NULL || crle->verified < 0)
+                    break;
+            }
+            else if (crle->verified < 0) {
+                WOLFSSL_MSG("Cannot use CRL as it didn't verify");
+                ret = crle->verified;
+                break;
+            }
+
+            WOLFSSL_MSG("Checking next date validity");
+
+        #ifdef WOLFSSL_NO_CRL_NEXT_DATE
+            if (crle->nextDateFormat != ASN_OTHER_TYPE)
+        #endif
+            {
+            #ifndef NO_ASN_TIME
+                if (!XVALIDATE_DATE(crle->nextDate,crle->nextDateFormat, AFTER)) {
+                    WOLFSSL_MSG("CRL next date is no longer valid");
+                    ret = ASN_AFTER_DATE_E;
+                }
+            #endif
+            }
+            if (ret == 0) {
+                foundEntry = 1;
+            }
+            break;
+        }
+        crle = crle->next;
+    }
+
+    if (foundEntry) {
+        RevokedCert* rc = crle->certs;
+
+        while (rc) {
+            if (rc->serialSz == cert->serialSz &&
+                   XMEMCMP(rc->serialNumber, cert->serial, rc->serialSz) == 0) {
+                WOLFSSL_MSG("Cert revoked");
+                ret = CRL_CERT_REVOKED;
+                break;
+            }
+            rc = rc->next;
+        }
+    }
+
+    wc_UnLockMutex(&crl->crlLock);
+
+    *pFoundEntry = foundEntry;
+
+    return ret;
+}
+
+/* Is the cert ok with CRL, return 0 on success */
+int CheckCertCRL(WOLFSSL_CRL* crl, DecodedCert* cert)
+{
+    int        foundEntry = 0;
+    int        ret = 0;
+
+    WOLFSSL_ENTER("CheckCertCRL");
+
+    ret = CheckCertCRLList(crl, cert, &foundEntry);
+
+#ifdef HAVE_CRL_IO
+    if (foundEntry == 0) {
+        /* perform embedded lookup */
+        if (crl->crlIOCb) {
+            ret = crl->crlIOCb(crl, (const char*)cert->extCrlInfo,
+                                                        cert->extCrlInfoSz);
+            if (ret == WOLFSSL_CBIO_ERR_WANT_READ) {
+                ret = WANT_READ;
+            }
+            else if (ret >= 0) {
+                /* try again */
+                ret = CheckCertCRLList(crl, cert, &foundEntry);
+            }
+        }
+    }
+#endif
+
+    if (foundEntry == 0) {
+        WOLFSSL_MSG("Couldn't find CRL for status check");
+        ret = CRL_MISSING;
+
+        if (crl->cm->cbMissingCRL) {
+            char url[256];
+
+            WOLFSSL_MSG("Issuing missing CRL callback");
+            url[0] = '\0';
+            if (cert->extCrlInfo) {
+                if (cert->extCrlInfoSz < (int)sizeof(url) -1 ) {
+                    XMEMCPY(url, cert->extCrlInfo, cert->extCrlInfoSz);
+                    url[cert->extCrlInfoSz] = '\0';
+                }
+                else  {
+                    WOLFSSL_MSG("CRL url too long");
+                }
+            }
+
+            crl->cm->cbMissingCRL(url);
+        }
+    }
+
+    return ret;
+}
+
+
+/* Add Decoded CRL, 0 on success */
+static int AddCRL(WOLFSSL_CRL* crl, DecodedCRL* dcrl, const byte* buff,
+                  int verified)
+{
+    CRL_Entry* crle;
+
+    WOLFSSL_ENTER("AddCRL");
+
+    crle = (CRL_Entry*)XMALLOC(sizeof(CRL_Entry), crl->heap, DYNAMIC_TYPE_CRL_ENTRY);
+    if (crle == NULL) {
+        WOLFSSL_MSG("alloc CRL Entry failed");
+        return -1;
+    }
+
+    if (InitCRL_Entry(crle, dcrl, buff, verified, crl->heap) < 0) {
+        WOLFSSL_MSG("Init CRL Entry failed");
+        XFREE(crle, crl->heap, DYNAMIC_TYPE_CRL_ENTRY);
+        return -1;
+    }
+
+    if (wc_LockMutex(&crl->crlLock) != 0) {
+        WOLFSSL_MSG("wc_LockMutex failed");
+        FreeCRL_Entry(crle, crl->heap);
+        XFREE(crle, crl->heap, DYNAMIC_TYPE_CRL_ENTRY);
+        return BAD_MUTEX_E;
+    }
+    crle->next = crl->crlList;
+    crl->crlList = crle;
+    wc_UnLockMutex(&crl->crlLock);
+
+    return 0;
+}
+
+
+/* Load CRL File of type, WOLFSSL_SUCCESS on ok */
+int BufferLoadCRL(WOLFSSL_CRL* crl, const byte* buff, long sz, int type,
+                  int verify)
+{
+    int          ret = WOLFSSL_SUCCESS;
+    const byte*  myBuffer = buff;    /* if DER ok, otherwise switch */
+    DerBuffer*   der = NULL;
+#ifdef WOLFSSL_SMALL_STACK
+    DecodedCRL*  dcrl;
+#else
+    DecodedCRL   dcrl[1];
+#endif
+
+    WOLFSSL_ENTER("BufferLoadCRL");
+
+    if (crl == NULL || buff == NULL || sz == 0)
+        return BAD_FUNC_ARG;
+
+    if (type == WOLFSSL_FILETYPE_PEM) {
+    #ifdef WOLFSSL_PEM_TO_DER
+        ret = PemToDer(buff, sz, CRL_TYPE, &der, NULL, NULL, NULL);
+        if (ret == 0) {
+            myBuffer = der->buffer;
+            sz = der->length;
+        }
+        else {
+            WOLFSSL_MSG("Pem to Der failed");
+            FreeDer(&der);
+            return -1;
+        }
+    #else
+        ret = NOT_COMPILED_IN;
+    #endif
+    }
+
+#ifdef WOLFSSL_SMALL_STACK
+    dcrl = (DecodedCRL*)XMALLOC(sizeof(DecodedCRL), NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    if (dcrl == NULL) {
+        FreeDer(&der);
+        return MEMORY_E;
+    }
+#endif
+
+    InitDecodedCRL(dcrl, crl->heap);
+    ret = ParseCRL(dcrl, myBuffer, (word32)sz, crl->cm);
+    if (ret != 0 && !(ret == ASN_CRL_NO_SIGNER_E && verify == NO_VERIFY)) {
+        WOLFSSL_MSG("ParseCRL error");
+    }
+    else {
+        ret = AddCRL(crl, dcrl, myBuffer, ret != ASN_CRL_NO_SIGNER_E);
+        if (ret != 0) {
+            WOLFSSL_MSG("AddCRL error");
+        }
+    }
+
+    FreeDecodedCRL(dcrl);
+
+#ifdef WOLFSSL_SMALL_STACK
+    XFREE(dcrl, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+#endif
+
+    FreeDer(&der);
+
+    return ret ? ret : WOLFSSL_SUCCESS; /* convert 0 to WOLFSSL_SUCCESS */
+}
+
+#if defined(OPENSSL_EXTRA) && defined(HAVE_CRL)
+int wolfSSL_X509_STORE_add_crl(WOLFSSL_X509_STORE *store, WOLFSSL_X509_CRL *newcrl)
+{
+    CRL_Entry   *crle;
+    WOLFSSL_CRL *crl;
+
+    WOLFSSL_ENTER("wolfSSL_X509_STORE_add_crl");
+    if (store == NULL || newcrl == NULL)
+        return BAD_FUNC_ARG;
+
+    crl = store->crl;
+    crle = newcrl->crlList;
+
+    if (wc_LockMutex(&crl->crlLock) != 0)
+    {
+        WOLFSSL_MSG("wc_LockMutex failed");
+        return BAD_MUTEX_E;
+    }
+    crle->next = crl->crlList;
+    crl->crlList = crle;
+    newcrl->crlList = NULL;
+    wc_UnLockMutex(&crl->crlLock);
+
+    WOLFSSL_LEAVE("wolfSSL_X509_STORE_add_crl", WOLFSSL_SUCCESS);
+
+    return WOLFSSL_SUCCESS;
+}
+#endif
+
+#ifdef HAVE_CRL_MONITOR
+
+
+/* Signal Monitor thread is setup, save status to setup flag, 0 on success */
+static int SignalSetup(WOLFSSL_CRL* crl, int status)
+{
+    int ret;
+
+    /* signal to calling thread we're setup */
+    if (wc_LockMutex(&crl->crlLock) != 0) {
+        WOLFSSL_MSG("wc_LockMutex crlLock failed");
+        return BAD_MUTEX_E;
+    }
+
+        crl->setup = status;
+        ret = pthread_cond_signal(&crl->cond);
+
+    wc_UnLockMutex(&crl->crlLock);
+
+    if (ret != 0)
+        return BAD_COND_E;
+
+    return 0;
+}
+
+
+/* read in new CRL entries and save new list */
+static int SwapLists(WOLFSSL_CRL* crl)
+{
+    int        ret;
+    CRL_Entry* newList;
+#ifdef WOLFSSL_SMALL_STACK
+    WOLFSSL_CRL* tmp;
+#else
+    WOLFSSL_CRL tmp[1];
+#endif
+
+#ifdef WOLFSSL_SMALL_STACK
+    tmp = (WOLFSSL_CRL*)XMALLOC(sizeof(WOLFSSL_CRL), NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    if (tmp == NULL)
+        return MEMORY_E;
+#endif
+
+    if (InitCRL(tmp, crl->cm) < 0) {
+        WOLFSSL_MSG("Init tmp CRL failed");
+#ifdef WOLFSSL_SMALL_STACK
+        XFREE(tmp, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+#endif
+        return -1;
+    }
+
+    if (crl->monitors[0].path) {
+        ret = LoadCRL(tmp, crl->monitors[0].path, WOLFSSL_FILETYPE_PEM, 0);
+        if (ret != WOLFSSL_SUCCESS) {
+            WOLFSSL_MSG("PEM LoadCRL on dir change failed");
+            FreeCRL(tmp, 0);
+#ifdef WOLFSSL_SMALL_STACK
+            XFREE(tmp, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+#endif
+            return -1;
+        }
+    }
+
+    if (crl->monitors[1].path) {
+        ret = LoadCRL(tmp, crl->monitors[1].path, WOLFSSL_FILETYPE_ASN1, 0);
+        if (ret != WOLFSSL_SUCCESS) {
+            WOLFSSL_MSG("DER LoadCRL on dir change failed");
+            FreeCRL(tmp, 0);
+#ifdef WOLFSSL_SMALL_STACK
+            XFREE(tmp, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+#endif
+            return -1;
+        }
+    }
+
+    if (wc_LockMutex(&crl->crlLock) != 0) {
+        WOLFSSL_MSG("wc_LockMutex failed");
+        FreeCRL(tmp, 0);
+#ifdef WOLFSSL_SMALL_STACK
+        XFREE(tmp, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+#endif
+        return -1;
+    }
+
+    newList = tmp->crlList;
+
+    /* swap lists */
+    tmp->crlList  = crl->crlList;
+    crl->crlList = newList;
+
+    wc_UnLockMutex(&crl->crlLock);
+
+    FreeCRL(tmp, 0);
+
+#ifdef WOLFSSL_SMALL_STACK
+    XFREE(tmp, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+#endif
+
+    return 0;
+}
+
+
+#if (defined(__MACH__) || defined(__FreeBSD__))
+
+#include <sys/types.h>
+#include <sys/event.h>
+#include <sys/time.h>
+#include <fcntl.h>
+#include <unistd.h>
+
+#ifdef __MACH__
+    #define XEVENT_MODE O_EVTONLY
+#elif defined(__FreeBSD__)
+    #define XEVENT_MODE EVFILT_VNODE
+#endif
+
+
+/* we need a unique kqueue user filter fd for crl in case user is doing custom
+ * events too */
+#ifndef CRL_CUSTOM_FD
+    #define CRL_CUSTOM_FD 123456
+#endif
+
+
+/* shutdown monitor thread, 0 on success */
+static int StopMonitor(int mfd)
+{
+    struct kevent change;
+
+    /* trigger custom shutdown */
+    EV_SET(&change, CRL_CUSTOM_FD, EVFILT_USER, 0, NOTE_TRIGGER, 0, NULL);
+    if (kevent(mfd, &change, 1, NULL, 0, NULL) < 0) {
+        WOLFSSL_MSG("kevent trigger customer event failed");
+        return -1;
+    }
+
+    return 0;
+}
+
+
+/* OS X  monitoring */
+static void* DoMonitor(void* arg)
+{
+    int fPEM, fDER;
+    struct kevent change;
+
+    WOLFSSL_CRL* crl = (WOLFSSL_CRL*)arg;
+
+    WOLFSSL_ENTER("DoMonitor");
+
+    crl->mfd = kqueue();
+    if (crl->mfd == -1) {
+        WOLFSSL_MSG("kqueue failed");
+        SignalSetup(crl, MONITOR_SETUP_E);
+        return NULL;
+    }
+
+    /* listen for custom shutdown event */
+    EV_SET(&change, CRL_CUSTOM_FD, EVFILT_USER, EV_ADD, 0, 0, NULL);
+    if (kevent(crl->mfd, &change, 1, NULL, 0, NULL) < 0) {
+        WOLFSSL_MSG("kevent monitor customer event failed");
+        SignalSetup(crl, MONITOR_SETUP_E);
+        close(crl->mfd);
+        return NULL;
+    }
+
+    fPEM = -1;
+    fDER = -1;
+
+    if (crl->monitors[0].path) {
+        fPEM = open(crl->monitors[0].path, XEVENT_MODE);
+        if (fPEM == -1) {
+            WOLFSSL_MSG("PEM event dir open failed");
+            SignalSetup(crl, MONITOR_SETUP_E);
+            close(crl->mfd);
+            return NULL;
+        }
+    }
+
+    if (crl->monitors[1].path) {
+        fDER = open(crl->monitors[1].path, XEVENT_MODE);
+        if (fDER == -1) {
+            WOLFSSL_MSG("DER event dir open failed");
+            if (fPEM != -1)
+                close(fPEM);
+            close(crl->mfd);
+            SignalSetup(crl, MONITOR_SETUP_E);
+            return NULL;
+        }
+    }
+
+    if (fPEM != -1)
+        EV_SET(&change, fPEM, EVFILT_VNODE, EV_ADD | EV_ENABLE | EV_ONESHOT,
+                NOTE_DELETE | NOTE_EXTEND | NOTE_WRITE | NOTE_ATTRIB, 0, 0);
+
+    if (fDER != -1)
+        EV_SET(&change, fDER, EVFILT_VNODE, EV_ADD | EV_ENABLE | EV_ONESHOT,
+                NOTE_DELETE | NOTE_EXTEND | NOTE_WRITE | NOTE_ATTRIB, 0, 0);
+
+    /* signal to calling thread we're setup */
+    if (SignalSetup(crl, 1) != 0) {
+        if (fPEM != -1)
+            close(fPEM);
+        if (fDER != -1)
+            close(fDER);
+        close(crl->mfd);
+        return NULL;
+    }
+
+    for (;;) {
+        struct kevent event;
+        int           numEvents = kevent(crl->mfd, &change, 1, &event, 1, NULL);
+
+        WOLFSSL_MSG("Got kevent");
+
+        if (numEvents == -1) {
+            WOLFSSL_MSG("kevent problem, continue");
+            continue;
+        }
+
+        if (event.filter == EVFILT_USER) {
+            WOLFSSL_MSG("Got user shutdown event, breaking out");
+            break;
+        }
+
+        if (SwapLists(crl) < 0) {
+            WOLFSSL_MSG("SwapLists problem, continue");
+        }
+    }
+
+    if (fPEM != -1)
+        close(fPEM);
+    if (fDER != -1)
+        close(fDER);
+
+    close(crl->mfd);
+
+    return NULL;
+}
+
+
+#elif defined(__linux__)
+
+#include <sys/types.h>
+#include <sys/inotify.h>
+#include <sys/eventfd.h>
+#include <unistd.h>
+
+
+#ifndef max
+    static WC_INLINE int max(int a, int b)
+    {
+        return a > b ? a : b;
+    }
+#endif /* max */
+
+
+/* shutdown monitor thread, 0 on success */
+static int StopMonitor(int mfd)
+{
+    word64 w64 = 1;
+
+    /* write to our custom event */
+    if (write(mfd, &w64, sizeof(w64)) < 0) {
+        WOLFSSL_MSG("StopMonitor write failed");
+        return -1;
+    }
+
+    return 0;
+}
+
+
+/* linux monitoring */
+static void* DoMonitor(void* arg)
+{
+    int         notifyFd;
+    int         wd  = -1;
+    WOLFSSL_CRL* crl = (WOLFSSL_CRL*)arg;
+#ifdef WOLFSSL_SMALL_STACK
+    char*       buff;
+#else
+    char        buff[8192];
+#endif
+
+    WOLFSSL_ENTER("DoMonitor");
+
+    crl->mfd = eventfd(0, 0);  /* our custom shutdown event */
+    if (crl->mfd < 0) {
+        WOLFSSL_MSG("eventfd failed");
+        SignalSetup(crl, MONITOR_SETUP_E);
+        return NULL;
+    }
+
+    notifyFd = inotify_init();
+    if (notifyFd < 0) {
+        WOLFSSL_MSG("inotify failed");
+        close(crl->mfd);
+        SignalSetup(crl, MONITOR_SETUP_E);
+        return NULL;
+    }
+
+    if (crl->monitors[0].path) {
+        wd = inotify_add_watch(notifyFd, crl->monitors[0].path, IN_CLOSE_WRITE |
+                                                                IN_DELETE);
+        if (wd < 0) {
+            WOLFSSL_MSG("PEM notify add watch failed");
+            close(crl->mfd);
+            close(notifyFd);
+            SignalSetup(crl, MONITOR_SETUP_E);
+            return NULL;
+        }
+    }
+
+    if (crl->monitors[1].path) {
+        wd = inotify_add_watch(notifyFd, crl->monitors[1].path, IN_CLOSE_WRITE |
+                                                                IN_DELETE);
+        if (wd < 0) {
+            WOLFSSL_MSG("DER notify add watch failed");
+            close(crl->mfd);
+            close(notifyFd);
+            SignalSetup(crl, MONITOR_SETUP_E);
+            return NULL;
+        }
+    }
+
+#ifdef WOLFSSL_SMALL_STACK
+    buff = (char*)XMALLOC(8192, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    if (buff == NULL)
+        return NULL;
+#endif
+
+    /* signal to calling thread we're setup */
+    if (SignalSetup(crl, 1) != 0) {
+        #ifdef WOLFSSL_SMALL_STACK
+            XFREE(buff, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+        #endif
+
+        if (wd > 0)
+            inotify_rm_watch(notifyFd, wd);
+        close(crl->mfd);
+        close(notifyFd);
+        return NULL;
+    }
+
+    for (;;) {
+        fd_set readfds;
+        int    result;
+        int    length;
+
+        FD_ZERO(&readfds);
+        FD_SET(notifyFd, &readfds);
+        FD_SET(crl->mfd, &readfds);
+
+        result = select(max(notifyFd, crl->mfd) + 1, &readfds, NULL, NULL,NULL);
+
+        WOLFSSL_MSG("Got notify event");
+
+        if (result < 0) {
+            WOLFSSL_MSG("select problem, continue");
+            continue;
+        }
+
+        if (FD_ISSET(crl->mfd, &readfds)) {
+            WOLFSSL_MSG("got custom shutdown event, breaking out");
+            break;
+        }
+
+        length = (int) read(notifyFd, buff, 8192);
+        if (length < 0) {
+            WOLFSSL_MSG("notify read problem, continue");
+            continue;
+        }
+
+        if (SwapLists(crl) < 0) {
+            WOLFSSL_MSG("SwapLists problem, continue");
+        }
+    }
+
+#ifdef WOLFSSL_SMALL_STACK
+    XFREE(buff, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+#endif
+
+    if (wd > 0)
+        inotify_rm_watch(notifyFd, wd);
+    close(crl->mfd);
+    close(notifyFd);
+
+    return NULL;
+}
+
+#endif /* MACH or linux */
+
+
+/* Start Monitoring the CRL path(s) in a thread */
+static int StartMonitorCRL(WOLFSSL_CRL* crl)
+{
+    int ret = WOLFSSL_SUCCESS;
+
+    WOLFSSL_ENTER("StartMonitorCRL");
+
+    if (crl == NULL)
+        return BAD_FUNC_ARG;
+
+    if (crl->tid != 0) {
+        WOLFSSL_MSG("Monitor thread already running");
+        return ret;  /* that's ok, someone already started */
+    }
+
+    if (pthread_create(&crl->tid, NULL, DoMonitor, crl) != 0) {
+        WOLFSSL_MSG("Thread creation error");
+        return THREAD_CREATE_E;
+    }
+
+    /* wait for setup to complete */
+    if (wc_LockMutex(&crl->crlLock) != 0) {
+        WOLFSSL_MSG("wc_LockMutex crlLock error");
+        return BAD_MUTEX_E;
+    }
+
+        while (crl->setup == 0) {
+            if (pthread_cond_wait(&crl->cond, &crl->crlLock) != 0) {
+                ret = BAD_COND_E;
+                break;
+            }
+        }
+
+        if (crl->setup < 0)
+            ret = crl->setup;  /* store setup error */
+
+    wc_UnLockMutex(&crl->crlLock);
+
+    if (ret < 0) {
+        WOLFSSL_MSG("DoMonitor setup failure");
+        crl->tid = 0;  /* thread already done */
+    }
+
+    return ret;
+}
+
+
+#else /* HAVE_CRL_MONITOR */
+
+#ifndef NO_FILESYSTEM
+
+static int StartMonitorCRL(WOLFSSL_CRL* crl)
+{
+    (void)crl;
+
+    WOLFSSL_ENTER("StartMonitorCRL");
+    WOLFSSL_MSG("Not compiled in");
+
+    return NOT_COMPILED_IN;
+}
+
+#endif /* NO_FILESYSTEM */
+
+#endif  /* HAVE_CRL_MONITOR */
+
+#if !defined(NO_FILESYSTEM) && !defined(NO_WOLFSSL_DIR)
+
+/* Load CRL path files of type, WOLFSSL_SUCCESS on ok */
+int LoadCRL(WOLFSSL_CRL* crl, const char* path, int type, int monitor)
+{
+    int         ret = WOLFSSL_SUCCESS;
+    char*       name = NULL;
+#ifdef WOLFSSL_SMALL_STACK
+    ReadDirCtx* readCtx = NULL;
+#else
+    ReadDirCtx  readCtx[1];
+#endif
+
+    WOLFSSL_ENTER("LoadCRL");
+    if (crl == NULL)
+        return BAD_FUNC_ARG;
+
+#ifdef WOLFSSL_SMALL_STACK
+    readCtx = (ReadDirCtx*)XMALLOC(sizeof(ReadDirCtx), crl->heap,
+                                                       DYNAMIC_TYPE_TMP_BUFFER);
+    if (readCtx == NULL)
+        return MEMORY_E;
+#endif
+
+    /* try to load each regular file in path */
+    ret = wc_ReadDirFirst(readCtx, path, &name);
+    while (ret == 0 && name) {
+        int skip = 0;
+        if (type == WOLFSSL_FILETYPE_PEM) {
+            if (XSTRSTR(name, ".pem") == NULL) {
+                WOLFSSL_MSG("not .pem file, skipping");
+                skip = 1;
+            }
+        }
+        else {
+            if (XSTRSTR(name, ".der") == NULL &&
+                XSTRSTR(name, ".crl") == NULL)
+            {
+                WOLFSSL_MSG("not .der or .crl file, skipping");
+                skip = 1;
+            }
+        }
+
+        if (!skip && ProcessFile(NULL, name, type, CRL_TYPE, NULL, 0, crl,
+                                 VERIFY) != WOLFSSL_SUCCESS) {
+            WOLFSSL_MSG("CRL file load failed, continuing");
+        }
+
+        ret = wc_ReadDirNext(readCtx, path, &name);
+    }
+    wc_ReadDirClose(readCtx);
+    ret = WOLFSSL_SUCCESS; /* load failures not reported, for backwards compat */
+
+#ifdef WOLFSSL_SMALL_STACK
+    XFREE(readCtx, crl->heap, DYNAMIC_TYPE_TMP_BUFFER);
+#endif
+
+    if (monitor & WOLFSSL_CRL_MONITOR) {
+        word32 pathLen;
+        char* pathBuf;
+
+        WOLFSSL_MSG("monitor path requested");
+
+        pathLen = (word32)XSTRLEN(path);
+        pathBuf = (char*)XMALLOC(pathLen+1, crl->heap,DYNAMIC_TYPE_CRL_MONITOR);
+        if (pathBuf) {
+            XSTRNCPY(pathBuf, path, pathLen+1);
+
+            if (type == WOLFSSL_FILETYPE_PEM) {
+                /* free old path before setting a new one */
+                if (crl->monitors[0].path) {
+                    XFREE(crl->monitors[0].path, crl->heap,
+                            DYNAMIC_TYPE_CRL_MONITOR);
+                }
+                crl->monitors[0].path = pathBuf;
+                crl->monitors[0].type = WOLFSSL_FILETYPE_PEM;
+            } else {
+                /* free old path before setting a new one */
+                if (crl->monitors[1].path) {
+                    XFREE(crl->monitors[1].path, crl->heap,
+                            DYNAMIC_TYPE_CRL_MONITOR);
+                }
+                crl->monitors[1].path = pathBuf;
+                crl->monitors[1].type = WOLFSSL_FILETYPE_ASN1;
+            }
+
+            if (monitor & WOLFSSL_CRL_START_MON) {
+                WOLFSSL_MSG("start monitoring requested");
+
+                ret = StartMonitorCRL(crl);
+            }
+        }
+        else {
+            ret = MEMORY_E;
+        }
+    }
+
+    return ret;
+}
+
+#else
+int LoadCRL(WOLFSSL_CRL* crl, const char* path, int type, int monitor)
+{
+	(void)crl;
+	(void)path;
+	(void)type;
+	(void)monitor;
+
+    /* stub for scenario where file system is not supported */
+    return NOT_COMPILED_IN;
+}
+#endif /* !NO_FILESYSTEM && !NO_WOLFSSL_DIR */
+
+#endif /* HAVE_CRL */
+#endif /* !WOLFCRYPT_ONLY */
Index: azure_iot_hub_f767zi/trunk/wolfssl-4.4.0/src/internal.c
===================================================================
--- azure_iot_hub_f767zi/trunk/wolfssl-4.4.0/src/internal.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/wolfssl-4.4.0/src/internal.c	(revision 457)
@@ -0,0 +1,29425 @@
+/* internal.c
+ *
+ * Copyright (C) 2006-2020 wolfSSL Inc.
+ *
+ * This file is part of wolfSSL.
+ *
+ * wolfSSL is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * wolfSSL is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
+ */
+
+
+
+#ifdef HAVE_CONFIG_H
+    #include <config.h>
+#endif
+
+#include <wolfssl/wolfcrypt/settings.h>
+
+/*
+ * WOLFSSL_SMALL_CERT_VERIFY:
+ *     Verify the certificate signature without using DecodedCert. Doubles up
+ *     on some code but allows smaller peak heap memory usage.
+ *     Cannot be used with WOLFSSL_NONBLOCK_OCSP.
+ * WOLFSSL_ALT_CERT_CHAINS:
+ *     Allows CA's to be presented by peer, but not part of a valid chain.
+ *     Default wolfSSL behavior is to require validation of all presented peer
+ *     certificates. This also allows loading intermediate CA's as trusted
+ *     and ignoring no signer failures for CA's up the chain to root.
+ */
+
+
+#ifdef EXTERNAL_OPTS_OPENVPN
+#error EXTERNAL_OPTS_OPENVPN should not be defined\
+    when building wolfSSL
+#endif
+
+#ifndef WOLFCRYPT_ONLY
+
+#include <wolfssl/internal.h>
+#include <wolfssl/error-ssl.h>
+#include <wolfssl/wolfcrypt/asn.h>
+#include <wolfssl/wolfcrypt/dh.h>
+#ifdef NO_INLINE
+    #include <wolfssl/wolfcrypt/misc.h>
+#else
+    #define WOLFSSL_MISC_INCLUDED
+    #include <wolfcrypt/src/misc.c>
+#endif
+#if defined(OPENSSL_EXTRA) && defined(WOLFCRYPT_HAVE_SRP) && !defined(NO_SHA)
+    #include <wolfssl/wolfcrypt/srp.h>
+#endif
+
+#ifdef HAVE_LIBZ
+    #include "zlib.h"
+#endif
+
+#ifdef HAVE_NTRU
+    #include "libntruencrypt/ntru_crypto.h"
+#endif
+
+#if defined(DEBUG_WOLFSSL) || defined(SHOW_SECRETS) || \
+    defined(CHACHA_AEAD_TEST) || defined(WOLFSSL_SESSION_EXPORT_DEBUG)
+    #ifndef NO_STDIO_FILESYSTEM
+        #include <stdio.h>
+    #endif
+#endif
+
+#ifdef __sun
+    #include <sys/filio.h>
+#endif
+
+
+#define ERROR_OUT(err, eLabel) { ret = (err); goto eLabel; }
+
+#ifdef _MSC_VER
+    /* disable for while(0) cases at the .c level for now */
+    #pragma warning(disable:4127)
+#endif
+
+#if defined(WOLFSSL_CALLBACKS) && !defined(LARGE_STATIC_BUFFERS)
+    #error \
+WOLFSSL_CALLBACKS needs LARGE_STATIC_BUFFERS, please add LARGE_STATIC_BUFFERS
+#endif
+
+#if defined(HAVE_SECURE_RENEGOTIATION) && defined(HAVE_RENEGOTIATION_INDICATION)
+    #error Cannot use both secure-renegotiation and renegotiation-indication
+#endif
+
+#ifndef WOLFSSL_NO_TLS12
+
+#ifndef NO_WOLFSSL_CLIENT
+    static int DoHelloVerifyRequest(WOLFSSL* ssl, const byte* input, word32*,
+                                                                        word32);
+    static int DoServerKeyExchange(WOLFSSL* ssl, const byte* input, word32*,
+                                                                        word32);
+    #ifndef NO_CERTS
+        static int DoCertificateRequest(WOLFSSL* ssl, const byte* input, word32*,
+                                                                        word32);
+    #endif
+    #ifdef HAVE_SESSION_TICKET
+        static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32*,
+                                                                        word32);
+    #endif
+#endif
+
+
+#ifndef NO_WOLFSSL_SERVER
+    static int DoClientKeyExchange(WOLFSSL* ssl, byte* input, word32*, word32);
+    #if (!defined(NO_RSA) || defined(HAVE_ECC) || defined(HAVE_ED25519) || \
+                        defined(HAVE_ED448)) && !defined(WOLFSSL_NO_CLIENT_AUTH)
+        static int DoCertificateVerify(WOLFSSL* ssl, byte*, word32*, word32);
+    #endif
+    #ifdef WOLFSSL_DTLS
+        static int SendHelloVerifyRequest(WOLFSSL*, const byte*, byte);
+    #endif /* WOLFSSL_DTLS */
+#endif
+
+#endif /* !WOLFSSL_NO_TLS12 */
+
+#ifdef WOLFSSL_DTLS
+    static WC_INLINE int DtlsCheckWindow(WOLFSSL* ssl);
+    static WC_INLINE int DtlsUpdateWindow(WOLFSSL* ssl);
+#endif
+
+
+enum processReply {
+    doProcessInit = 0,
+#ifndef NO_WOLFSSL_SERVER
+    runProcessOldClientHello,
+#endif
+    getRecordLayerHeader,
+    getData,
+    verifyEncryptedMessage,
+    decryptMessage,
+    verifyMessage,
+    runProcessingOneMessage
+};
+
+
+#ifndef WOLFSSL_NO_TLS12
+#if !defined(NO_WOLFSSL_SERVER) || !defined(NO_WOLFSSL_CLIENT)
+
+/* Server random bytes for TLS v1.3 described downgrade protection mechanism. */
+static const byte tls13Downgrade[7] = {
+    0x44, 0x4f, 0x57, 0x4e, 0x47, 0x52, 0x44
+};
+#define TLS13_DOWNGRADE_SZ  sizeof(tls13Downgrade)
+
+#endif /* !NO_WOLFSSL_SERVER || !NO_WOLFSSL_CLIENT */
+
+#if !defined(NO_OLD_TLS) && !defined(WOLFSSL_AEAD_ONLY)
+static int SSL_hmac(WOLFSSL* ssl, byte* digest, const byte* in, word32 sz,
+                    int padSz, int content, int verify);
+
+#endif
+
+#endif /* !WOLFSSL_NO_TLS12 */
+
+#ifdef HAVE_QSH
+    int QSH_Init(WOLFSSL* ssl);
+#endif
+
+#ifdef WOLFSSL_RENESAS_TSIP_TLS
+    int tsip_useable(const WOLFSSL *ssl);
+    int tsip_generatePremasterSecret();
+    int tsip_generateEncryptPreMasterSecret(WOLFSSL *ssl, byte *out, word32 *outSz);
+#endif
+int IsTLS(const WOLFSSL* ssl)
+{
+    if (ssl->version.major == SSLv3_MAJOR && ssl->version.minor >=TLSv1_MINOR)
+        return 1;
+
+    return 0;
+}
+
+
+int IsAtLeastTLSv1_2(const WOLFSSL* ssl)
+{
+    if (ssl->version.major == SSLv3_MAJOR && ssl->version.minor >=TLSv1_2_MINOR)
+        return 1;
+#ifdef WOLFSSL_DTLS
+    if (ssl->version.major == DTLS_MAJOR && ssl->version.minor <= DTLSv1_2_MINOR)
+        return 1;
+#endif
+
+    return 0;
+}
+
+int IsAtLeastTLSv1_3(const ProtocolVersion pv)
+{
+    return (pv.major == SSLv3_MAJOR && pv.minor >= TLSv1_3_MINOR);
+}
+
+static WC_INLINE int IsEncryptionOn(WOLFSSL* ssl, int isSend)
+{
+    (void)isSend;
+
+    #ifdef WOLFSSL_DTLS
+    /* For DTLS, epoch 0 is always not encrypted. */
+    if (ssl->options.dtls && !isSend && ssl->keys.curEpoch == 0)
+        return 0;
+    #endif /* WOLFSSL_DTLS */
+
+#ifdef WOLFSSL_TLS13
+    if (isSend)
+        return ssl->encrypt.setup;
+    else
+        return ssl->decrypt.setup;
+#else
+    return ssl->keys.encryptionOn;
+#endif
+}
+
+
+#if defined(WOLFSSL_DTLS) || !defined(WOLFSSL_NO_TLS12)
+/* If SCTP is not enabled returns the state of the dtls option.
+ * If SCTP is enabled returns dtls && !sctp. */
+static WC_INLINE int IsDtlsNotSctpMode(WOLFSSL* ssl)
+{
+    int result = ssl->options.dtls;
+
+    if (result) {
+#ifdef WOLFSSL_SCTP
+        result = !ssl->options.dtlsSctp;
+#endif
+    }
+
+    return result;
+}
+#endif /* DTLS || !WOLFSSL_NO_TLS12 */
+
+
+#ifdef HAVE_QSH
+/* free all structs that where used with QSH */
+static int QSH_FreeAll(WOLFSSL* ssl)
+{
+    QSHKey* key        = ssl->QSH_Key;
+    QSHKey* preKey     = NULL;
+    QSHSecret* secret  = ssl->QSH_secret;
+    QSHScheme* list    = NULL;
+    QSHScheme* preList = NULL;
+
+    /* free elements in struct */
+    while (key) {
+        preKey = key;
+        if (key->pri.buffer) {
+            ForceZero(key->pri.buffer, key->pri.length);
+            XFREE(key->pri.buffer, ssl->heap, DYNAMIC_TYPE_PRIVATE_KEY);
+        }
+        if (key->pub.buffer)
+            XFREE(key->pub.buffer, ssl->heap, DYNAMIC_TYPE_PUBLIC_KEY);
+        key = (QSHKey*)key->next;
+
+        /* free struct */
+        XFREE(preKey, ssl->heap, DYNAMIC_TYPE_QSH);
+    }
+
+
+    /* free all of peers QSH keys */
+    key = ssl->peerQSHKey;
+    while (key) {
+        preKey = key;
+        if (key->pri.buffer) {
+            ForceZero(key->pri.buffer, key->pri.length);
+            XFREE(key->pri.buffer, ssl->heap, DYNAMIC_TYPE_PRIVATE_KEY);
+        }
+        if (key->pub.buffer)
+            XFREE(key->pub.buffer, ssl->heap, DYNAMIC_TYPE_PUBLIC_KEY);
+        key = (QSHKey*)key->next;
+
+        /* free struct */
+        XFREE(preKey, ssl->heap, DYNAMIC_TYPE_QSH);
+    }
+    key = NULL;
+
+    /* free secret information */
+    if (secret) {
+        /* free up the QSHScheme list in QSHSecret */
+        if (secret->list)
+            list = secret->list;
+        while (list) {
+            preList = list;
+            if (list->PK)
+                XFREE(list->PK, ssl->heap, DYNAMIC_TYPE_SECRET);
+            list = (QSHScheme*)list->next;
+            XFREE(preList, ssl->heap, DYNAMIC_TYPE_QSH);
+        }
+
+        /* free secret buffers */
+        if (secret->SerSi) {
+            if (secret->SerSi->buffer) {
+                /* clear extra secret material that supplemented Master Secret*/
+                ForceZero(secret->SerSi->buffer, secret->SerSi->length);
+                XFREE(secret->SerSi->buffer, ssl->heap, DYNAMIC_TYPE_SECRET);
+            }
+            XFREE(secret->SerSi, ssl->heap, DYNAMIC_TYPE_SECRET);
+        }
+        if (secret->CliSi) {
+            if (secret->CliSi->buffer) {
+                /* clear extra secret material that supplemented Master Secret*/
+                ForceZero(secret->CliSi->buffer, secret->CliSi->length);
+                XFREE(secret->CliSi->buffer, ssl->heap, DYNAMIC_TYPE_SECRET);
+            }
+            XFREE(secret->CliSi, ssl->heap, DYNAMIC_TYPE_SECRET);
+        }
+    }
+    XFREE(secret, ssl->heap, DYNAMIC_TYPE_QSH);
+    secret = NULL;
+
+    return 0;
+}
+#endif
+
+
+#ifdef HAVE_NTRU
+static WOLFSSL_GLOBAL WC_RNG* rng;
+static WOLFSSL_GLOBAL wolfSSL_Mutex* rngMutex;
+
+static word32 GetEntropy(unsigned char* out, word32 num_bytes)
+{
+    int ret = 0;
+
+    if (rng == NULL) {
+        if ((rng = (WC_RNG*)XMALLOC(sizeof(WC_RNG), 0,
+                                                    DYNAMIC_TYPE_RNG)) == NULL)
+            return DRBG_OUT_OF_MEMORY;
+        wc_InitRng(rng);
+    }
+
+    if (rngMutex == NULL) {
+        if ((rngMutex = (wolfSSL_Mutex*)XMALLOC(sizeof(wolfSSL_Mutex), 0,
+                        DYNAMIC_TYPE_MUTEX)) == NULL)
+            return DRBG_OUT_OF_MEMORY;
+        wc_InitMutex(rngMutex);
+    }
+
+    ret |= wc_LockMutex(rngMutex);
+    ret |= wc_RNG_GenerateBlock(rng, out, num_bytes);
+    ret |= wc_UnLockMutex(rngMutex);
+
+    if (ret != 0)
+        return DRBG_ENTROPY_FAIL;
+
+    return DRBG_OK;
+}
+#endif /* HAVE_NTRU */
+
+#ifdef HAVE_LIBZ
+
+    /* alloc user allocs to work with zlib */
+    static void* myAlloc(void* opaque, unsigned int item, unsigned int size)
+    {
+        (void)opaque;
+        return XMALLOC(item * size, opaque, DYNAMIC_TYPE_LIBZ);
+    }
+
+
+    static void myFree(void* opaque, void* memory)
+    {
+        (void)opaque;
+        XFREE(memory, opaque, DYNAMIC_TYPE_LIBZ);
+    }
+
+
+    /* init zlib comp/decomp streams, 0 on success */
+    static int InitStreams(WOLFSSL* ssl)
+    {
+        ssl->c_stream.zalloc = (alloc_func)myAlloc;
+        ssl->c_stream.zfree  = (free_func)myFree;
+        ssl->c_stream.opaque = (voidpf)ssl->heap;
+
+        if (deflateInit(&ssl->c_stream, Z_DEFAULT_COMPRESSION) != Z_OK)
+            return ZLIB_INIT_ERROR;
+
+        ssl->didStreamInit = 1;
+
+        ssl->d_stream.zalloc = (alloc_func)myAlloc;
+        ssl->d_stream.zfree  = (free_func)myFree;
+        ssl->d_stream.opaque = (voidpf)ssl->heap;
+
+        if (inflateInit(&ssl->d_stream) != Z_OK) return ZLIB_INIT_ERROR;
+
+        return 0;
+    }
+
+
+    static void FreeStreams(WOLFSSL* ssl)
+    {
+        if (ssl->didStreamInit) {
+            deflateEnd(&ssl->c_stream);
+            inflateEnd(&ssl->d_stream);
+        }
+    }
+
+
+    /* compress in to out, return out size or error */
+    static int myCompress(WOLFSSL* ssl, byte* in, int inSz, byte* out, int outSz)
+    {
+        int    err;
+        int    currTotal = (int)ssl->c_stream.total_out;
+
+        ssl->c_stream.next_in   = in;
+        ssl->c_stream.avail_in  = inSz;
+        ssl->c_stream.next_out  = out;
+        ssl->c_stream.avail_out = outSz;
+
+        err = deflate(&ssl->c_stream, Z_SYNC_FLUSH);
+        if (err != Z_OK && err != Z_STREAM_END) return ZLIB_COMPRESS_ERROR;
+
+        return (int)ssl->c_stream.total_out - currTotal;
+    }
+
+
+    /* decompress in to out, return out size or error */
+    static int myDeCompress(WOLFSSL* ssl, byte* in,int inSz, byte* out,int outSz)
+    {
+        int    err;
+        int    currTotal = (int)ssl->d_stream.total_out;
+
+        ssl->d_stream.next_in   = in;
+        ssl->d_stream.avail_in  = inSz;
+        ssl->d_stream.next_out  = out;
+        ssl->d_stream.avail_out = outSz;
+
+        err = inflate(&ssl->d_stream, Z_SYNC_FLUSH);
+        if (err != Z_OK && err != Z_STREAM_END) return ZLIB_DECOMPRESS_ERROR;
+
+        return (int)ssl->d_stream.total_out - currTotal;
+    }
+
+#endif /* HAVE_LIBZ */
+
+
+#ifdef WOLFSSL_SESSION_EXPORT
+#ifdef WOLFSSL_DTLS
+/* serializes the cipher specs struct for exporting */
+static int ExportCipherSpecState(WOLFSSL* ssl, byte* exp, word32 len, byte ver)
+{
+    word32 idx = 0;
+    CipherSpecs* specs;
+
+    WOLFSSL_ENTER("ExportCipherSpecState");
+
+    if (exp == NULL || ssl == NULL) {
+        return BAD_FUNC_ARG;
+    }
+
+    specs= &(ssl->specs);
+
+    if (DTLS_EXPORT_SPC_SZ > len) {
+        return BUFFER_E;
+    }
+
+    XMEMSET(exp, 0, DTLS_EXPORT_SPC_SZ);
+
+    c16toa(specs->key_size, exp + idx);      idx += OPAQUE16_LEN;
+    c16toa(specs->iv_size, exp + idx);       idx += OPAQUE16_LEN;
+    c16toa(specs->block_size, exp + idx);    idx += OPAQUE16_LEN;
+    c16toa(specs->aead_mac_size, exp + idx); idx += OPAQUE16_LEN;
+    exp[idx++] = specs->bulk_cipher_algorithm;
+    exp[idx++] = specs->cipher_type;
+    exp[idx++] = specs->mac_algorithm;
+    exp[idx++] = specs->kea;
+    exp[idx++] = specs->sig_algo;
+    exp[idx++] = specs->hash_size;
+    exp[idx++] = specs->pad_size;
+    exp[idx++] = specs->static_ecdh;
+
+    if (idx != DTLS_EXPORT_SPC_SZ) {
+        WOLFSSL_MSG("DTLS_EXPORT_SPC_SZ needs updated and export version");
+        return DTLS_EXPORT_VER_E;
+    }
+
+    WOLFSSL_LEAVE("ExportCipherSpecState", idx);
+    (void)ver;
+    return idx;
+}
+
+
+/* serializes the key struct for exporting */
+static int ExportKeyState(WOLFSSL* ssl, byte* exp, word32 len, byte ver,
+        byte small)
+{
+    word32 idx = 0;
+    byte   sz;
+    Keys* keys;
+
+    WOLFSSL_ENTER("ExportKeyState");
+
+    if (exp == NULL || ssl == NULL) {
+        return BAD_FUNC_ARG;
+    }
+
+    keys = &(ssl->keys);
+
+    if (DTLS_EXPORT_MIN_KEY_SZ > len) {
+        WOLFSSL_MSG("Buffer not large enough for minimum key struct size");
+        return BUFFER_E;
+    }
+
+    XMEMSET(exp, 0, DTLS_EXPORT_MIN_KEY_SZ);
+
+    c32toa(keys->peer_sequence_number_hi, exp + idx); idx += OPAQUE32_LEN;
+    c32toa(keys->peer_sequence_number_lo, exp + idx); idx += OPAQUE32_LEN;
+    c32toa(keys->sequence_number_hi, exp + idx);      idx += OPAQUE32_LEN;
+    c32toa(keys->sequence_number_lo, exp + idx);      idx += OPAQUE32_LEN;
+
+    c16toa(keys->peerSeq[0].nextEpoch, exp + idx);  idx += OPAQUE16_LEN;
+    c16toa(keys->peerSeq[0].nextSeq_hi, exp + idx); idx += OPAQUE16_LEN;
+    c32toa(keys->peerSeq[0].nextSeq_lo, exp + idx); idx += OPAQUE32_LEN;
+    c16toa(keys->curEpoch, exp + idx);   idx += OPAQUE16_LEN;
+    c16toa(keys->curSeq_hi, exp + idx);  idx += OPAQUE16_LEN;
+    c32toa(keys->curSeq_lo, exp + idx);  idx += OPAQUE32_LEN;
+    c16toa(keys->peerSeq[0].prevSeq_hi, exp + idx); idx += OPAQUE16_LEN;
+    c32toa(keys->peerSeq[0].prevSeq_lo, exp + idx); idx += OPAQUE32_LEN;
+
+    c16toa(keys->dtls_peer_handshake_number, exp + idx); idx += OPAQUE16_LEN;
+    c16toa(keys->dtls_expected_peer_handshake_number, exp + idx);
+    idx += OPAQUE16_LEN;
+
+    c16toa(keys->dtls_sequence_number_hi, exp + idx);      idx += OPAQUE16_LEN;
+    c32toa(keys->dtls_sequence_number_lo, exp + idx);      idx += OPAQUE32_LEN;
+    c16toa(keys->dtls_prev_sequence_number_hi, exp + idx); idx += OPAQUE16_LEN;
+    c32toa(keys->dtls_prev_sequence_number_lo, exp + idx); idx += OPAQUE32_LEN;
+    c16toa(keys->dtls_epoch, exp + idx);                   idx += OPAQUE16_LEN;
+    c16toa(keys->dtls_handshake_number, exp + idx);        idx += OPAQUE16_LEN;
+    c32toa(keys->encryptSz, exp + idx);                    idx += OPAQUE32_LEN;
+    c32toa(keys->padSz, exp + idx);                        idx += OPAQUE32_LEN;
+    exp[idx++] = keys->encryptionOn;
+    exp[idx++] = keys->decryptedCur;
+
+    /* from here on the buffer needs checked because is variable length that
+     * can be larger than DTLS_EXPORT_MIN_KEY_SZ */
+    {
+        word32 i;
+        if ((OPAQUE16_LEN * 2) + idx +
+                (2 * (WOLFSSL_DTLS_WINDOW_WORDS * OPAQUE32_LEN)) > len) {
+            WOLFSSL_MSG("Buffer not large enough for WOLFSSL_DTLS_WINDOW_WORDS");
+            return BUFFER_E;
+        }
+
+        c16toa(WOLFSSL_DTLS_WINDOW_WORDS, exp + idx); idx += OPAQUE16_LEN;
+        for (i = 0; i < WOLFSSL_DTLS_WINDOW_WORDS; i++) {
+            c32toa(keys->peerSeq[0].window[i], exp + idx);
+            idx += OPAQUE32_LEN;
+        }
+        c16toa(WOLFSSL_DTLS_WINDOW_WORDS, exp + idx); idx += OPAQUE16_LEN;
+        for (i = 0; i < WOLFSSL_DTLS_WINDOW_WORDS; i++) {
+            c32toa(keys->peerSeq[0].prevWindow[i], exp + idx);
+            idx += OPAQUE32_LEN;
+        }
+    }
+
+    if (idx >= len) {
+        WOLFSSL_MSG("Buffer not large enough for truncated hmac flag");
+        return BUFFER_E;
+    }
+
+#ifdef HAVE_TRUNCATED_HMAC
+    sz         = ssl->truncated_hmac ? TRUNCATED_HMAC_SZ: ssl->specs.hash_size;
+    exp[idx++] = ssl->truncated_hmac;
+#else
+    sz         = ssl->specs.hash_size;
+    exp[idx++] = 0; /* no truncated hmac */
+#endif
+
+    sz = (small)? 0: sz;
+    if (idx + (sz * 2) + OPAQUE8_LEN > len) {
+        WOLFSSL_MSG("Buffer not large enough for MAC secret");
+        return BUFFER_E;
+    }
+
+    exp[idx++] = sz;
+    if (sz > 0) {
+    #ifndef WOLFSSL_AEAD_ONLY
+        XMEMCPY(exp + idx, keys->client_write_MAC_secret, sz); idx += sz;
+        XMEMCPY(exp + idx, keys->server_write_MAC_secret, sz); idx += sz;
+    #else
+        XMEMSET(exp + idx, 0, sz); idx += sz;
+        XMEMSET(exp + idx, 0, sz); idx += sz;
+    #endif
+    }
+
+    sz = (small)? 0: ssl->specs.key_size;
+    if (idx + (sz * 2) + OPAQUE8_LEN > len) {
+        WOLFSSL_MSG("Buffer not large enough for write key");
+        return BUFFER_E;
+    }
+
+    exp[idx++] = sz;
+    if (sz > 0) {
+        XMEMCPY(exp + idx, keys->client_write_key, sz); idx += sz;
+        XMEMCPY(exp + idx, keys->server_write_key, sz); idx += sz;
+    }
+
+    sz = (small)? 0: ssl->specs.iv_size;
+    if (idx + (sz * 2) + OPAQUE8_LEN + AEAD_MAX_EXP_SZ > len) {
+        WOLFSSL_MSG("Buffer not large enough for IVs");
+        return BUFFER_E;
+    }
+
+    exp[idx++] = sz;
+    if (sz > 0) {
+        XMEMCPY(exp + idx, keys->client_write_IV, sz); idx += sz;
+        XMEMCPY(exp + idx, keys->server_write_IV, sz); idx += sz;
+    }
+    XMEMCPY(exp + idx, keys->aead_exp_IV, AEAD_MAX_EXP_SZ);
+    idx += AEAD_MAX_EXP_SZ;
+
+    sz = (small)? 0: AEAD_MAX_IMP_SZ;
+    if (idx + (sz * 2) + OPAQUE8_LEN > len) {
+        WOLFSSL_MSG("Buffer not large enough for imp IVs");
+        return BUFFER_E;
+    }
+    exp[idx++] = sz;
+    if (sz > 0) {
+        XMEMCPY(exp + idx, keys->aead_enc_imp_IV, sz); idx += sz;
+        XMEMCPY(exp + idx, keys->aead_dec_imp_IV, sz); idx += sz;
+    }
+
+    /* DTLS_EXPORT_KEY_SZ is max value. idx size can vary */
+    if (idx > DTLS_EXPORT_KEY_SZ) {
+        WOLFSSL_MSG("DTLS_EXPORT_KEY_SZ needs updated and export version");
+        return DTLS_EXPORT_VER_E;
+    }
+
+    WOLFSSL_LEAVE("ExportKeyState", idx);
+    (void)ver;
+    return idx;
+}
+
+static int ImportCipherSpecState(WOLFSSL* ssl, byte* exp, word32 len, byte ver)
+{
+    word32 idx = 0;
+    CipherSpecs* specs;
+
+    WOLFSSL_ENTER("ImportCipherSpecState");
+
+    if (exp == NULL || ssl == NULL) {
+        return BAD_FUNC_ARG;
+    }
+
+    specs= &(ssl->specs);
+
+    if (DTLS_EXPORT_SPC_SZ > len) {
+        WOLFSSL_MSG("Buffer not large enough for max spec struct size");
+        return BUFFER_E;
+    }
+
+    ato16(exp + idx, &specs->key_size);      idx += OPAQUE16_LEN;
+    ato16(exp + idx, &specs->iv_size);       idx += OPAQUE16_LEN;
+    ato16(exp + idx, &specs->block_size);    idx += OPAQUE16_LEN;
+    ato16(exp + idx, &specs->aead_mac_size); idx += OPAQUE16_LEN;
+    specs->bulk_cipher_algorithm = exp[idx++];
+    specs->cipher_type           = exp[idx++];
+    specs->mac_algorithm         = exp[idx++];
+    specs->kea                   = exp[idx++];
+    specs->sig_algo              = exp[idx++];
+    specs->hash_size             = exp[idx++];
+    specs->pad_size              = exp[idx++];
+    specs->static_ecdh           = exp[idx++];
+
+    WOLFSSL_LEAVE("ImportCipherSpecState", idx);
+    (void)ver;
+    return idx;
+}
+
+
+static int ImportKeyState(WOLFSSL* ssl, byte* exp, word32 len, byte ver)
+{
+    word32 idx = 0;
+    byte  sz;
+    Keys* keys;
+
+    WOLFSSL_ENTER("ImportKeyState");
+
+    if (exp == NULL || ssl == NULL) {
+        return BAD_FUNC_ARG;
+    }
+
+    keys = &(ssl->keys);
+
+    /* check minimum length -- includes byte used for size indicators */
+    if (len < DTLS_EXPORT_MIN_KEY_SZ) {
+        WOLFSSL_MSG("Buffer not large enough for minimum expected size");
+        return BUFFER_E;
+    }
+    ato32(exp + idx, &keys->peer_sequence_number_hi); idx += OPAQUE32_LEN;
+    ato32(exp + idx, &keys->peer_sequence_number_lo); idx += OPAQUE32_LEN;
+    ato32(exp + idx, &keys->sequence_number_hi);      idx += OPAQUE32_LEN;
+    ato32(exp + idx, &keys->sequence_number_lo);      idx += OPAQUE32_LEN;
+
+    ato16(exp + idx, &keys->peerSeq[0].nextEpoch);  idx += OPAQUE16_LEN;
+    ato16(exp + idx, &keys->peerSeq[0].nextSeq_hi); idx += OPAQUE16_LEN;
+    ato32(exp + idx, &keys->peerSeq[0].nextSeq_lo); idx += OPAQUE32_LEN;
+    ato16(exp + idx, &keys->curEpoch);   idx += OPAQUE16_LEN;
+    ato16(exp + idx, &keys->curSeq_hi);  idx += OPAQUE16_LEN;
+    ato32(exp + idx, &keys->curSeq_lo);  idx += OPAQUE32_LEN;
+    ato16(exp + idx, &keys->peerSeq[0].prevSeq_hi); idx += OPAQUE16_LEN;
+    ato32(exp + idx, &keys->peerSeq[0].prevSeq_lo); idx += OPAQUE32_LEN;
+
+    ato16(exp + idx, &keys->dtls_peer_handshake_number); idx += OPAQUE16_LEN;
+    ato16(exp + idx, &keys->dtls_expected_peer_handshake_number);
+    idx += OPAQUE16_LEN;
+
+    ato16(exp + idx, &keys->dtls_sequence_number_hi);      idx += OPAQUE16_LEN;
+    ato32(exp + idx, &keys->dtls_sequence_number_lo);      idx += OPAQUE32_LEN;
+    ato16(exp + idx, &keys->dtls_prev_sequence_number_hi); idx += OPAQUE16_LEN;
+    ato32(exp + idx, &keys->dtls_prev_sequence_number_lo); idx += OPAQUE32_LEN;
+    ato16(exp + idx, &keys->dtls_epoch);                   idx += OPAQUE16_LEN;
+    ato16(exp + idx, &keys->dtls_handshake_number);        idx += OPAQUE16_LEN;
+    ato32(exp + idx, &keys->encryptSz);                    idx += OPAQUE32_LEN;
+    ato32(exp + idx, &keys->padSz);                        idx += OPAQUE32_LEN;
+    keys->encryptionOn = exp[idx++];
+    keys->decryptedCur = exp[idx++];
+
+    {
+        word16 i, wordCount, wordAdj = 0;
+
+        /* do window */
+        ato16(exp + idx, &wordCount);
+        idx += OPAQUE16_LEN;
+
+        if (wordCount > WOLFSSL_DTLS_WINDOW_WORDS) {
+            wordCount = WOLFSSL_DTLS_WINDOW_WORDS;
+            wordAdj = (WOLFSSL_DTLS_WINDOW_WORDS - wordCount) * sizeof(word32);
+        }
+
+        XMEMSET(keys->peerSeq[0].window, 0xFF, DTLS_SEQ_SZ);
+        for (i = 0; i < wordCount; i++) {
+            ato32(exp + idx, &keys->peerSeq[0].window[i]);
+            idx += OPAQUE32_LEN;
+        }
+        idx += wordAdj;
+
+        /* do prevWindow */
+        ato16(exp + idx, &wordCount);
+        idx += OPAQUE16_LEN;
+
+        if (wordCount > WOLFSSL_DTLS_WINDOW_WORDS) {
+            wordCount = WOLFSSL_DTLS_WINDOW_WORDS;
+            wordAdj = (WOLFSSL_DTLS_WINDOW_WORDS - wordCount) * sizeof(word32);
+        }
+
+        XMEMSET(keys->peerSeq[0].prevWindow, 0xFF, DTLS_SEQ_SZ);
+        for (i = 0; i < wordCount; i++) {
+            ato32(exp + idx, &keys->peerSeq[0].prevWindow[i]);
+            idx += OPAQUE32_LEN;
+        }
+        idx += wordAdj;
+
+    }
+
+#ifdef HAVE_TRUNCATED_HMAC
+    ssl->truncated_hmac = exp[idx++];
+#else
+    idx++; /* no truncated hmac */
+#endif
+    sz = exp[idx++];
+#ifndef WOLFSSL_AEAD_ONLY
+    if (sz > sizeof(keys->client_write_MAC_secret) || (sz * 2) + idx > len) {
+        WOLFSSL_MSG("Buffer not large enough for MAC import");
+        return BUFFER_E;
+    }
+    if (sz > 0) {
+        XMEMCPY(keys->client_write_MAC_secret, exp + idx, sz); idx += sz;
+        XMEMCPY(keys->server_write_MAC_secret, exp + idx, sz); idx += sz;
+    }
+#else
+    if (sz + idx > len) {
+        return BUFFER_E;
+    }
+    idx += sz; idx += sz;
+#endif
+
+    sz = exp[idx++];
+    if (sz > sizeof(keys->client_write_key) || (sz * 2) + idx > len) {
+        WOLFSSL_MSG("Buffer not large enough for key import");
+        return BUFFER_E;
+    }
+    if (sz > 0) {
+        XMEMCPY(keys->client_write_key, exp + idx, sz); idx += sz;
+        XMEMCPY(keys->server_write_key, exp + idx, sz); idx += sz;
+    }
+
+    sz = exp[idx++];
+    if (sz > sizeof(keys->client_write_IV) || (sz * 2) + idx > len) {
+        WOLFSSL_MSG("Buffer not large enough for write IV import");
+        return BUFFER_E;
+    }
+    if (sz > 0) {
+        XMEMCPY(keys->client_write_IV, exp + idx, sz); idx += sz;
+        XMEMCPY(keys->server_write_IV, exp + idx, sz); idx += sz;
+    }
+    XMEMCPY(keys->aead_exp_IV, exp + idx, AEAD_MAX_EXP_SZ);
+    idx += AEAD_MAX_EXP_SZ;
+
+    sz = exp[idx++];
+    if (sz > sizeof(keys->aead_enc_imp_IV) || (sz * 2) + idx > len) {
+        WOLFSSL_MSG("Buffer not large enough for imp IV import");
+        return BUFFER_E;
+    }
+    if (sz > 0) {
+        XMEMCPY(keys->aead_enc_imp_IV, exp + idx, sz); idx += sz;
+        XMEMCPY(keys->aead_dec_imp_IV, exp + idx, sz); idx += sz;
+    }
+
+    WOLFSSL_LEAVE("ImportKeyState", idx);
+    (void)ver;
+    return idx;
+}
+
+
+/* copy over necessary information from Options struct to buffer
+ * On success returns size of buffer used on failure returns a negative value */
+static int dtls_export_new(WOLFSSL* ssl, byte* exp, word32 len, byte ver)
+{
+    int idx = 0;
+    word16 zero = 0;
+    Options* options = &ssl->options;
+
+    WOLFSSL_ENTER("dtls_export_new");
+
+    if (exp == NULL || options == NULL || len < DTLS_EXPORT_OPT_SZ) {
+        return BAD_FUNC_ARG;
+    }
+
+    XMEMSET(exp, 0, DTLS_EXPORT_OPT_SZ);
+
+    /* these options are kept and sent to indicate verify status and strength
+     * of handshake */
+    exp[idx++] = options->sendVerify;
+    exp[idx++] = options->verifyPeer;
+    exp[idx++] = options->verifyNone;
+    exp[idx++] = options->downgrade;
+#ifndef NO_DH
+    c16toa(options->minDhKeySz, exp + idx); idx += OPAQUE16_LEN;
+    c16toa(options->maxDhKeySz, exp + idx); idx += OPAQUE16_LEN;
+    c16toa(options->dhKeySz, exp + idx);    idx += OPAQUE16_LEN;
+#else
+    c16toa(zero, exp + idx); idx += OPAQUE16_LEN;
+    c16toa(zero, exp + idx); idx += OPAQUE16_LEN;
+    c16toa(zero, exp + idx); idx += OPAQUE16_LEN;
+#endif
+#ifndef NO_RSA
+    c16toa((word16)(options->minRsaKeySz), exp + idx); idx += OPAQUE16_LEN;
+#else
+    c16toa(zero, exp + idx); idx += OPAQUE16_LEN;
+#endif
+#ifdef HAVE_ECC
+    c16toa((word16)(options->minEccKeySz), exp + idx); idx += OPAQUE16_LEN;
+#else
+    c16toa(zero, exp + idx); idx += OPAQUE16_LEN;
+#endif
+
+    /* these options are kept to indicate state and behavior */
+#ifndef NO_PSK
+    exp[idx++] = options->havePSK;
+#else
+    exp[idx++] = 0;
+#endif
+    exp[idx++] = options->sessionCacheOff;
+    exp[idx++] = options->sessionCacheFlushOff;
+    exp[idx++] = options->side;
+    exp[idx++] = options->resuming;
+    exp[idx++] = options->haveSessionId;
+    exp[idx++] = options->tls;
+    exp[idx++] = options->tls1_1;
+    exp[idx++] = options->dtls;
+    exp[idx++] = options->connReset;
+    exp[idx++] = options->isClosed;
+    exp[idx++] = options->closeNotify;
+    exp[idx++] = options->sentNotify;
+    exp[idx++] = options->usingCompression;
+    exp[idx++] = options->haveRSA;
+    exp[idx++] = options->haveECC;
+    exp[idx++] = options->haveDH;
+    exp[idx++] = options->haveNTRU;
+    exp[idx++] = options->haveQSH;
+    exp[idx++] = options->haveECDSAsig;
+    exp[idx++] = options->haveStaticECC;
+    exp[idx++] = options->havePeerVerify;
+    exp[idx++] = options->usingPSK_cipher;
+    exp[idx++] = options->usingAnon_cipher;
+    exp[idx++] = options->sendAlertState;
+    exp[idx++] = options->partialWrite;
+    exp[idx++] = options->quietShutdown;
+    exp[idx++] = options->groupMessages;
+#ifdef HAVE_POLY1305
+    exp[idx++] = options->oldPoly;
+#else
+    exp[idx++] = 0;
+#endif
+#ifdef HAVE_ANON
+    exp[idx++] = options->haveAnon;
+#else
+    exp[idx++] = 0;
+#endif
+#ifdef HAVE_SESSION_TICKET
+    exp[idx++] = options->createTicket;
+    exp[idx++] = options->useTicket;
+#ifdef WOLFSSL_TLS13
+    if (ver > DTLS_EXPORT_VERSION_3) {
+        exp[idx++] = options->noTicketTls13;
+    }
+#else
+    if (ver > DTLS_EXPORT_VERSION_3) {
+        exp[idx++] = 0;
+    }
+#endif
+#else
+    exp[idx++] = 0;
+    exp[idx++] = 0;
+    if (ver > DTLS_EXPORT_VERSION_3) {
+        exp[idx++] = 0;
+    }
+#endif
+    exp[idx++] = options->processReply;
+    exp[idx++] = options->cipherSuite0;
+    exp[idx++] = options->cipherSuite;
+    exp[idx++] = options->serverState;
+    exp[idx++] = options->clientState;
+    exp[idx++] = options->handShakeState;
+    exp[idx++] = options->handShakeDone;
+    exp[idx++] = options->minDowngrade;
+    exp[idx++] = options->connectState;
+    exp[idx++] = options->acceptState;
+    exp[idx++] = options->asyncState;
+
+    /* version of connection */
+    exp[idx++] = ssl->version.major;
+    exp[idx++] = ssl->version.minor;
+
+    (void)zero;
+
+    /* check if changes were made and notify of need to update export version */
+    switch (ver) {
+        case DTLS_EXPORT_VERSION_3:
+            if (idx != DTLS_EXPORT_OPT_SZ_3) {
+                WOLFSSL_MSG("Update DTLS_EXPORT_OPT_SZ and version of export");
+                return DTLS_EXPORT_VER_E;
+            }
+            break;
+
+        case DTLS_EXPORT_VERSION:
+            if (idx != DTLS_EXPORT_OPT_SZ) {
+                WOLFSSL_MSG("Update DTLS_EXPORT_OPT_SZ and version of export");
+                return DTLS_EXPORT_VER_E;
+            }
+            break;
+
+       default:
+            WOLFSSL_MSG("New version case needs added to wolfSSL export");
+            return DTLS_EXPORT_VER_E;
+    }
+
+    WOLFSSL_LEAVE("dtls_export_new", idx);
+
+    return idx;
+}
+
+
+/* copy items from Export struct to Options struct
+ * On success returns size of buffer used on failure returns a negative value */
+static int dtls_export_load(WOLFSSL* ssl, byte* exp, word32 len, byte ver)
+{
+    int idx = 0;
+    Options* options = &ssl->options;
+
+    switch (ver) {
+        case DTLS_EXPORT_VERSION:
+            if (len < DTLS_EXPORT_OPT_SZ) {
+                WOLFSSL_MSG("Sanity check on buffer size failed");
+                return BAD_FUNC_ARG;
+            }
+            break;
+
+        case DTLS_EXPORT_VERSION_3:
+            if (len < DTLS_EXPORT_OPT_SZ_3) {
+                WOLFSSL_MSG("Sanity check on buffer size failed");
+                return BAD_FUNC_ARG;
+            }
+            break;
+
+        default:
+            WOLFSSL_MSG("Export version not supported");
+            return BAD_FUNC_ARG;
+    }
+
+    if (exp == NULL || options == NULL) {
+        return BAD_FUNC_ARG;
+    }
+
+
+    /* these options are kept and sent to indicate verify status and strength
+     * of handshake */
+    options->sendVerify = exp[idx++];
+    options->verifyPeer = exp[idx++];
+    options->verifyNone = exp[idx++];
+    options->downgrade  = exp[idx++];
+#ifndef NO_DH
+    ato16(exp + idx, &(options->minDhKeySz)); idx += OPAQUE16_LEN;
+    ato16(exp + idx, &(options->maxDhKeySz)); idx += OPAQUE16_LEN;
+    ato16(exp + idx, &(options->dhKeySz));    idx += OPAQUE16_LEN;
+#else
+    idx += OPAQUE16_LEN;
+    idx += OPAQUE16_LEN;
+    idx += OPAQUE16_LEN;
+#endif
+#ifndef NO_RSA
+    ato16(exp + idx, (word16*)&(options->minRsaKeySz)); idx += OPAQUE16_LEN;
+#else
+    idx += OPAQUE16_LEN;
+#endif
+#ifdef HAVE_ECC
+    ato16(exp + idx, (word16*)&(options->minEccKeySz)); idx += OPAQUE16_LEN;
+#else
+    idx += OPAQUE16_LEN;
+#endif
+
+    /* these options are kept to indicate state and behavior */
+#ifndef NO_PSK
+    options->havePSK = exp[idx++];
+#else
+    idx++;
+#endif
+    options->sessionCacheOff      = exp[idx++];
+    options->sessionCacheFlushOff = exp[idx++];
+    options->side                 = exp[idx++];
+    options->resuming             = exp[idx++];
+    options->haveSessionId    = exp[idx++];
+    options->tls              = exp[idx++];
+    options->tls1_1           = exp[idx++];
+    options->dtls             = exp[idx++];
+    options->connReset        = exp[idx++];
+    options->isClosed         = exp[idx++];
+    options->closeNotify      = exp[idx++];
+    options->sentNotify       = exp[idx++];
+    options->usingCompression = exp[idx++];
+    options->haveRSA          = exp[idx++];
+    options->haveECC          = exp[idx++];
+    options->haveDH           = exp[idx++];
+    options->haveNTRU         = exp[idx++];
+    options->haveQSH          = exp[idx++];
+    options->haveECDSAsig     = exp[idx++];
+    options->haveStaticECC    = exp[idx++];
+    options->havePeerVerify   = exp[idx++];
+    options->usingPSK_cipher  = exp[idx++];
+    options->usingAnon_cipher = exp[idx++];
+    options->sendAlertState   = exp[idx++];
+    options->partialWrite     = exp[idx++];
+    options->quietShutdown    = exp[idx++];
+    options->groupMessages    = exp[idx++];
+#ifdef HAVE_POLY1305
+    options->oldPoly = exp[idx++];      /* set when to use old rfc way of poly*/
+#else
+    idx++;
+#endif
+#ifdef HAVE_ANON
+    options->haveAnon = exp[idx++];     /* User wants to allow Anon suites */
+#else
+    idx++;
+#endif
+#ifdef HAVE_SESSION_TICKET
+    options->createTicket  = exp[idx++]; /* Server to create new Ticket */
+    options->useTicket     = exp[idx++]; /* Use Ticket not session cache */
+#ifdef WOLFSSL_TLS13
+    if (ver > DTLS_EXPORT_VERSION_3) {
+        options->noTicketTls13 = exp[idx++];/* Server won't create new Ticket */
+    }
+#else
+    if (ver > DTLS_EXPORT_VERSION_3) {
+        exp[idx++] = 0;
+    }
+#endif
+#else
+    idx++;
+    idx++;
+    if (ver > DTLS_EXPORT_VERSION_3) {
+        idx++;
+    }
+#endif
+    options->processReply   = exp[idx++];
+    options->cipherSuite0   = exp[idx++];
+    options->cipherSuite    = exp[idx++];
+    options->serverState    = exp[idx++];
+    options->clientState    = exp[idx++];
+    options->handShakeState = exp[idx++];
+    options->handShakeDone  = exp[idx++];
+    options->minDowngrade   = exp[idx++];
+    options->connectState   = exp[idx++];
+    options->acceptState    = exp[idx++];
+    options->asyncState     = exp[idx++];
+
+    /* version of connection */
+    if (ssl->version.major != exp[idx++] || ssl->version.minor != exp[idx++]) {
+        WOLFSSL_MSG("Version mismatch ie DTLS v1 vs v1.2");
+        return VERSION_ERROR;
+    }
+
+    return idx;
+}
+
+#ifndef WOLFSSL_SESSION_EXPORT_NOPEER
+static int ExportPeerInfo(WOLFSSL* ssl, byte* exp, word32 len, byte ver)
+{
+    int    idx  = 0;
+    int    ipSz = DTLS_EXPORT_IP; /* start as max size */
+    int    fam  = 0;
+    word16 port = 0;
+    char   ip[DTLS_EXPORT_IP];
+
+    if (ver != DTLS_EXPORT_VERSION) {
+        WOLFSSL_MSG("Export version not supported");
+        return BAD_FUNC_ARG;
+    }
+
+    if (ssl == NULL || exp == NULL || len < sizeof(ip) + 3 * DTLS_EXPORT_LEN) {
+        return BAD_FUNC_ARG;
+    }
+
+    if (ssl->ctx->CBGetPeer == NULL) {
+        WOLFSSL_MSG("No get peer call back set");
+        return BAD_FUNC_ARG;
+    }
+    if (ssl->ctx->CBGetPeer(ssl, ip, &ipSz, &port, &fam) != WOLFSSL_SUCCESS) {
+        WOLFSSL_MSG("Get peer callback error");
+        return SOCKET_ERROR_E;
+    }
+
+    /* check that ipSz/fam is not negative or too large since user can set cb */
+    if (ipSz < 0 || ipSz > DTLS_EXPORT_IP || fam < 0) {
+        WOLFSSL_MSG("Bad ipSz or fam returned from get peer callback");
+        return SOCKET_ERROR_E;
+    }
+
+    c16toa((word16)fam, exp + idx);  idx += DTLS_EXPORT_LEN;
+    c16toa((word16)ipSz, exp + idx); idx += DTLS_EXPORT_LEN;
+    XMEMCPY(exp + idx, ip, ipSz);    idx += ipSz;
+    c16toa(port, exp + idx);         idx += DTLS_EXPORT_LEN;
+
+    return idx;
+}
+#endif /* !WOLFSSL_SESSION_EXPORT_NOPEER */
+
+
+static int ImportPeerInfo(WOLFSSL* ssl, byte* buf, word32 len, byte ver)
+{
+    word16 idx = 0;
+    word16 ipSz;
+    word16 fam;
+    word16 port;
+    char   ip[DTLS_EXPORT_IP];
+
+    if (ver != DTLS_EXPORT_VERSION && ver != DTLS_EXPORT_VERSION_3) {
+        WOLFSSL_MSG("Export version not supported");
+        return BAD_FUNC_ARG;
+    }
+
+    if (len == 0) {
+        WOLFSSL_MSG("No peer info sent");
+        return 0;
+    }
+
+    if (ssl == NULL || buf == NULL || len < 3 * DTLS_EXPORT_LEN) {
+        return BAD_FUNC_ARG;
+    }
+
+    /* import sin family */
+    ato16(buf + idx, &fam); idx += DTLS_EXPORT_LEN;
+
+    /* import ip address idx, and ipSz are unsigned but cast for enum */
+    ato16(buf + idx, &ipSz); idx += DTLS_EXPORT_LEN;
+    if (ipSz >= sizeof(ip) || (word16)(idx + ipSz + DTLS_EXPORT_LEN) > len) {
+        return BUFFER_E;
+    }
+    XMEMSET(ip, 0, sizeof(ip));
+    XMEMCPY(ip, buf + idx, ipSz); idx += ipSz;
+    ip[ipSz] = '\0'; /* with check that ipSz less than ip this is valid */
+    ato16(buf + idx, &port); idx += DTLS_EXPORT_LEN;
+
+    /* sanity check for a function to call, then use it to import peer info */
+    if (ssl->ctx->CBSetPeer == NULL) {
+        WOLFSSL_MSG("No set peer function");
+        return BAD_FUNC_ARG;
+    }
+    if (ssl->ctx->CBSetPeer(ssl, ip, ipSz, port, fam) != WOLFSSL_SUCCESS) {
+        WOLFSSL_MSG("Error setting peer info");
+        return SOCKET_ERROR_E;
+    }
+
+    return idx;
+}
+
+
+/* WOLFSSL_LOCAL function that serializes the current WOLFSSL session state only
+ * buf is used to hold the serialized WOLFSSL struct and sz is the size of buf
+ * passed in.
+ * On success returns the size of serialized session state.*/
+int wolfSSL_dtls_export_state_internal(WOLFSSL* ssl, byte* buf, word32 sz)
+{
+    int ret;
+    word32 idx      = 0;
+    word32 totalLen = 0;
+
+    WOLFSSL_ENTER("wolfSSL_dtls_export_state_internal");
+
+    if (buf == NULL || ssl == NULL) {
+        WOLFSSL_LEAVE("wolfSSL_dtls_export_state_internal", BAD_FUNC_ARG);
+        return BAD_FUNC_ARG;
+    }
+
+    totalLen += DTLS_EXPORT_LEN * 2; /* 2 protocol bytes and 2 length bytes */
+    /* each of the following have a 2 byte length before data */
+    totalLen += DTLS_EXPORT_LEN + DTLS_EXPORT_MIN_KEY_SZ;
+    if (totalLen > sz) {
+        WOLFSSL_LEAVE("wolfSSL_dtls_export_state_internal", BUFFER_E);
+        return BUFFER_E;
+    }
+
+    buf[idx++] =  (byte)DTLS_EXPORT_STATE_PRO;
+    buf[idx++] = ((byte)DTLS_EXPORT_STATE_PRO & 0xF0) |
+                 ((byte)DTLS_EXPORT_VERSION & 0X0F);
+    idx += DTLS_EXPORT_LEN; /* leave room for total length */
+
+    /* export keys struct and dtls state -- variable length stored in ret */
+    idx += DTLS_EXPORT_LEN; /* leave room for length */
+    if ((ret = ExportKeyState(ssl, buf + idx, sz - idx,
+                                                 DTLS_EXPORT_VERSION, 1)) < 0) {
+        WOLFSSL_LEAVE("wolfSSL_dtls_export_state_internal", ret);
+        return ret;
+    }
+    c16toa((word16)ret, buf + idx - DTLS_EXPORT_LEN); idx += ret;
+
+    /* place total length of exported buffer minus 2 bytes protocol/version */
+    c16toa((word16)(idx - DTLS_EXPORT_LEN), buf + DTLS_EXPORT_LEN);
+
+#ifdef WOLFSSL_SESSION_EXPORT_DEBUG
+    /* if compiled with debug options then print the version, protocol, size */
+    {
+        char debug[256];
+        XSNPRINTF(debug, sizeof(debug), "Exporting DTLS session state\n"
+                   "\tVersion  : %d\n\tProtocol : %02X%01X\n\tLength of: %d\n\n"
+               , (int)DTLS_EXPORT_VERSION, buf[0], (buf[1] >> 4), idx - 2);
+        WOLFSSL_MSG(debug);
+    }
+#endif /* WOLFSSL_SESSION_EXPORT_DEBUG */
+
+    WOLFSSL_LEAVE("wolfSSL_dtls_export_state_internal", idx);
+    return idx;
+}
+
+
+/* WOLFSSL_LOCAL function that serializes the current WOLFSSL session
+ * buf is used to hold the serialized WOLFSSL struct and sz is the size of buf
+ * passed in.
+ * On success returns the size of serialized session.*/
+int wolfSSL_dtls_export_internal(WOLFSSL* ssl, byte* buf, word32 sz)
+{
+    int ret;
+    word32 idx      = 0;
+    word32 totalLen = 0;
+
+    WOLFSSL_ENTER("wolfSSL_dtls_export_internal");
+
+    if (buf == NULL || ssl == NULL) {
+        WOLFSSL_LEAVE("wolfSSL_dtls_export_internal", BAD_FUNC_ARG);
+        return BAD_FUNC_ARG;
+    }
+
+    totalLen += DTLS_EXPORT_LEN * 2; /* 2 protocol bytes and 2 length bytes */
+    /* each of the following have a 2 byte length before data */
+    totalLen += DTLS_EXPORT_LEN + DTLS_EXPORT_OPT_SZ;
+    totalLen += DTLS_EXPORT_LEN + DTLS_EXPORT_KEY_SZ;
+    totalLen += DTLS_EXPORT_LEN + DTLS_EXPORT_SPC_SZ;
+    totalLen += DTLS_EXPORT_LEN + ssl->buffers.dtlsCtx.peer.sz;
+
+    if (totalLen > sz) {
+        WOLFSSL_LEAVE("wolfSSL_dtls_export_internal", BUFFER_E);
+        return BUFFER_E;
+    }
+
+    buf[idx++] =  (byte)DTLS_EXPORT_PRO;
+    buf[idx++] = ((byte)DTLS_EXPORT_PRO & 0xF0) |
+                 ((byte)DTLS_EXPORT_VERSION & 0X0F);
+
+    idx += DTLS_EXPORT_LEN; /* leave spot for length */
+
+    c16toa((word16)DTLS_EXPORT_OPT_SZ, buf + idx); idx += DTLS_EXPORT_LEN;
+    if ((ret = dtls_export_new(ssl, buf + idx, sz - idx,
+                                                    DTLS_EXPORT_VERSION)) < 0) {
+        WOLFSSL_LEAVE("wolfSSL_dtls_export_internal", ret);
+        return ret;
+    }
+    idx += ret;
+
+    /* export keys struct and dtls state -- variable length stored in ret */
+    idx += DTLS_EXPORT_LEN; /* leave room for length */
+    if ((ret = ExportKeyState(ssl, buf + idx, sz - idx,
+                                                 DTLS_EXPORT_VERSION, 0)) < 0) {
+        WOLFSSL_LEAVE("wolfSSL_dtls_export_internal", ret);
+        return ret;
+    }
+    c16toa((word16)ret, buf + idx - DTLS_EXPORT_LEN); idx += ret;
+
+    /* export of cipher specs struct */
+    c16toa((word16)DTLS_EXPORT_SPC_SZ, buf + idx); idx += DTLS_EXPORT_LEN;
+    if ((ret = ExportCipherSpecState(ssl, buf + idx, sz - idx,
+                                                    DTLS_EXPORT_VERSION)) < 0) {
+        WOLFSSL_LEAVE("wolfSSL_dtls_export_internal", ret);
+        return ret;
+    }
+    idx += ret;
+
+    /* export of dtls peer information */
+    idx += DTLS_EXPORT_LEN;
+#ifdef WOLFSSL_SESSION_EXPORT_NOPEER
+    ret = 0; /* not saving peer port/ip information */
+#else
+    if ((ret = ExportPeerInfo(ssl, buf + idx, sz - idx,
+                                                    DTLS_EXPORT_VERSION)) < 0) {
+        WOLFSSL_LEAVE("wolfSSL_dtls_export_internal", ret);
+        return ret;
+    }
+#endif
+    c16toa(ret, buf + idx - DTLS_EXPORT_LEN);
+    idx += ret;
+
+    /* place total length of exported buffer minus 2 bytes protocol/version */
+    c16toa((word16)(idx - DTLS_EXPORT_LEN), buf + DTLS_EXPORT_LEN);
+
+    /* if compiled with debug options then print the version, protocol, size */
+#ifdef WOLFSSL_SESSION_EXPORT_DEBUG
+    {
+        char debug[256];
+        XSNPRINTF(debug, sizeof(debug), "Exporting DTLS session\n"
+                   "\tVersion  : %d\n\tProtocol : %02X%01X\n\tLength of: %d\n\n"
+               , (int)DTLS_EXPORT_VERSION, buf[0], (buf[1] >> 4), idx - 2);
+        WOLFSSL_MSG(debug);
+    }
+#endif /* WOLFSSL_SESSION_EXPORT_DEBUG */
+
+    WOLFSSL_LEAVE("wolfSSL_dtls_export_internal", idx);
+    return idx;
+}
+
+
+/* On success return amount of buffer consumed */
+int wolfSSL_dtls_import_state_internal(WOLFSSL* ssl, byte* buf, word32 sz)
+{
+    word32 idx    = 0;
+    word16 length = 0;
+    int version;
+    int ret;
+
+    WOLFSSL_ENTER("wolfSSL_dtls_import_state_internal");
+    /* check at least enough room for protocol and length */
+    if (sz < DTLS_EXPORT_LEN * 2 || ssl == NULL) {
+        WOLFSSL_LEAVE("wolfSSL_dtls_import_state_internal", BAD_FUNC_ARG);
+        return BAD_FUNC_ARG;
+    }
+
+    if (buf[idx++] !=  (byte)DTLS_EXPORT_STATE_PRO ||
+            (buf[idx] & 0xF0) != ((byte)DTLS_EXPORT_PRO & 0xF0)) {
+        WOLFSSL_MSG("Incorrect protocol");
+        return BAD_FUNC_ARG;
+    }
+    version = buf[idx++] & 0x0F;
+
+    ato16(buf + idx, &length); idx += DTLS_EXPORT_LEN;
+    if (length > sz - DTLS_EXPORT_LEN) { /* subtract 2 for protocol */
+        WOLFSSL_MSG("Buffer size sanity check failed");
+        return BUFFER_E;
+    }
+
+#ifdef WOLFSSL_SESSION_EXPORT_DEBUG
+    /* if compiled with debug options then print the version, protocol, size */
+    {
+        char debug[256];
+        XSNPRINTF(debug, sizeof(debug), "Importing DTLS session state\n"
+                   "\tVersion  : %d\n\tProtocol : %02X%01X\n\tLength of: %d\n\n"
+               , (int)version, buf[0], (buf[1] >> 4), length);
+        WOLFSSL_MSG(debug);
+    }
+#endif /* WOLFSSL_SESSION_EXPORT_DEBUG */
+
+    /* perform sanity checks and extract Options information used */
+    switch (version) {
+        case DTLS_EXPORT_VERSION:
+            break;
+
+        default:
+            WOLFSSL_MSG("Bad export state version");
+            return BAD_FUNC_ARG;
+
+    }
+
+    /* perform sanity checks and extract Keys struct */
+    if (DTLS_EXPORT_LEN + idx > sz) {
+        WOLFSSL_MSG("Import Key struct error");
+        return BUFFER_E;
+    }
+    ato16(buf + idx, &length); idx += DTLS_EXPORT_LEN;
+    if (length > DTLS_EXPORT_KEY_SZ || length + idx > sz) {
+        WOLFSSL_MSG("Import Key struct error");
+        return BUFFER_E;
+    }
+    if ((ret = ImportKeyState(ssl, buf + idx, length, version)) < 0) {
+        WOLFSSL_MSG("Import Key struct error");
+        WOLFSSL_LEAVE("wolfSSL_dtls_import_state_internal", ret);
+        return ret;
+    }
+    idx += ret;
+
+    WOLFSSL_LEAVE("wolfSSL_dtls_import_state_internal", ret);
+    return ret;
+}
+
+
+/* On success return amount of buffer consumed */
+int wolfSSL_dtls_import_internal(WOLFSSL* ssl, byte* buf, word32 sz)
+{
+    word32 idx    = 0;
+    word16 length = 0;
+    int version;
+    int ret;
+    int optSz;
+
+    WOLFSSL_ENTER("wolfSSL_dtls_import_internal");
+    /* check at least enough room for protocol and length */
+    if (sz < DTLS_EXPORT_LEN * 2 || ssl == NULL) {
+        return BAD_FUNC_ARG;
+    }
+
+    /* sanity check on protocol ID and size of buffer */
+    if (buf[idx++]       !=  (byte)DTLS_EXPORT_PRO ||
+       (buf[idx] & 0xF0) != ((byte)DTLS_EXPORT_PRO & 0xF0)) {
+        /* don't increment on second idx to next get version */
+
+        /* check if importing state only */
+        return wolfSSL_dtls_import_state_internal(ssl, buf, sz);
+    }
+    version = buf[idx++] & 0x0F;
+
+    ato16(buf + idx, &length); idx += DTLS_EXPORT_LEN;
+    if (length > sz - DTLS_EXPORT_LEN) { /* subtract 2 for protocol */
+        return BUFFER_E;
+    }
+
+    /* if compiled with debug options then print the version, protocol, size */
+#ifdef WOLFSSL_SESSION_EXPORT_DEBUG
+    {
+        char debug[256];
+        XSNPRINTF(debug, sizeof(debug), "Importing DTLS session\n"
+                   "\tVersion  : %d\n\tProtocol : %02X%01X\n\tLength of: %d\n\n"
+               , (int)version, buf[0], (buf[1] >> 4), length);
+        WOLFSSL_MSG(debug);
+    }
+#endif /* WOLFSSL_SESSION_EXPORT_DEBUG */
+
+    /* perform sanity checks and extract Options information used */
+    switch (version) {
+        case DTLS_EXPORT_VERSION:
+            optSz = DTLS_EXPORT_OPT_SZ;
+            break;
+
+        case DTLS_EXPORT_VERSION_3:
+            WOLFSSL_MSG("Importing older version 3");
+            optSz = DTLS_EXPORT_OPT_SZ_3;
+            break;
+
+        default:
+            WOLFSSL_MSG("Bad export version");
+            return BAD_FUNC_ARG;
+
+    }
+
+    if (DTLS_EXPORT_LEN + optSz + idx > sz) {
+        WOLFSSL_MSG("Import Options struct error");
+        return BUFFER_E;
+    }
+    ato16(buf + idx, &length); idx += DTLS_EXPORT_LEN;
+    if (length != optSz) {
+        WOLFSSL_MSG("Import Options struct error");
+        return BUFFER_E;
+    }
+    if ((ret = dtls_export_load(ssl, buf + idx, length, version)) < 0) {
+        WOLFSSL_MSG("Import Options struct error");
+        return ret;
+    }
+    idx += length;
+
+    /* perform sanity checks and extract Keys struct */
+    if (DTLS_EXPORT_LEN + idx > sz) {
+        WOLFSSL_MSG("Import Key struct error");
+        return BUFFER_E;
+    }
+    ato16(buf + idx, &length); idx += DTLS_EXPORT_LEN;
+    if (length > DTLS_EXPORT_KEY_SZ || length + idx > sz) {
+        WOLFSSL_MSG("Import Key struct error");
+        return BUFFER_E;
+    }
+    if ((ret = ImportKeyState(ssl, buf + idx, length, version)) < 0) {
+        WOLFSSL_MSG("Import Key struct error");
+        return ret;
+    }
+    idx += ret;
+
+    /* perform sanity checks and extract CipherSpecs struct */
+    if (DTLS_EXPORT_LEN + DTLS_EXPORT_SPC_SZ + idx > sz) {
+        WOLFSSL_MSG("Import CipherSpecs struct error");
+        return BUFFER_E;
+    }
+    ato16(buf + idx, &length); idx += DTLS_EXPORT_LEN;
+    if ( length != DTLS_EXPORT_SPC_SZ) {
+        WOLFSSL_MSG("Import CipherSpecs struct error");
+        return BUFFER_E;
+    }
+    if ((ret = ImportCipherSpecState(ssl, buf + idx, length, version)) < 0) {
+        WOLFSSL_MSG("Import CipherSpecs struct error");
+        return ret;
+    }
+    idx += ret;
+
+    /* perform sanity checks and extract DTLS peer info */
+    if (DTLS_EXPORT_LEN + idx > sz) {
+        WOLFSSL_MSG("Import DTLS peer info error");
+        return BUFFER_E;
+    }
+    ato16(buf + idx, &length); idx += DTLS_EXPORT_LEN;
+    if (idx + length > sz) {
+        WOLFSSL_MSG("Import DTLS peer info error");
+        return BUFFER_E;
+    }
+    if ((ret = ImportPeerInfo(ssl, buf + idx, length, version)) < 0) {
+        WOLFSSL_MSG("Import Peer Addr error");
+        return ret;
+    }
+    idx += ret;
+
+    SetKeysSide(ssl, ENCRYPT_AND_DECRYPT_SIDE);
+
+    /* set hmac function to use when verifying */
+    if (ssl->options.tls == 1 || ssl->options.tls1_1 == 1 ||
+            ssl->options.dtls == 1) {
+        ssl->hmac = TLS_hmac;
+    }
+
+    /* make sure is a valid suite used */
+    if (wolfSSL_get_cipher(ssl) == NULL) {
+        WOLFSSL_MSG("Can not match cipher suite imported");
+        return MATCH_SUITE_ERROR;
+    }
+
+    /* do not allow stream ciphers with DTLS, except for NULL cipher */
+    if (ssl->specs.cipher_type == stream &&
+        ssl->specs.bulk_cipher_algorithm != wolfssl_cipher_null) {
+        WOLFSSL_MSG("Can not import stream ciphers for DTLS");
+        return SANITY_CIPHER_E;
+    }
+
+    return idx;
+}
+#endif /* WOLFSSL_DTLS */
+#endif /* WOLFSSL_SESSION_EXPORT */
+
+
+void InitSSL_Method(WOLFSSL_METHOD* method, ProtocolVersion pv)
+{
+    method->version    = pv;
+    method->side       = WOLFSSL_CLIENT_END;
+    method->downgrade  = 0;
+}
+
+#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_EITHER_SIDE)
+int InitSSL_Side(WOLFSSL* ssl, word16 side)
+{
+    if (ssl == NULL)
+        return BAD_FUNC_ARG;
+
+    /* set side */
+    ssl->options.side = side;
+
+    /* reset options that are side specific */
+#ifdef HAVE_NTRU
+    if (ssl->options.side == WOLFSSL_CLIENT_END) {
+        ssl->options.haveNTRU = 1;      /* always on client side */
+                                        /* server can turn on by loading key */
+    }
+#endif
+#ifdef HAVE_ECC
+    if (ssl->options.side == WOLFSSL_CLIENT_END) {
+        ssl->options.haveECDSAsig  = 1; /* always on client side */
+        ssl->options.haveECC = 1;       /* server turns on with ECC key cert */
+        ssl->options.haveStaticECC = 1; /* server can turn on by loading key */
+    }
+#elif defined(HAVE_ED25519) || defined(HAVE_ED448)
+    if (ssl->options.side == WOLFSSL_CLIENT_END) {
+        ssl->options.haveECDSAsig  = 1; /* always on client side */
+        ssl->options.haveECC  = 1;      /* server turns on with ECC key cert */
+    }
+#endif
+
+#if defined(HAVE_EXTENDED_MASTER) && !defined(NO_WOLFSSL_CLIENT)
+    if (ssl->options.side == WOLFSSL_CLIENT_END) {
+        if ((ssl->ctx->method->version.major == SSLv3_MAJOR) &&
+             (ssl->ctx->method->version.minor >= TLSv1_MINOR)) {
+            ssl->options.haveEMS = 1;
+        }
+    #ifdef WOLFSSL_DTLS
+        if (ssl->ctx->method->version.major == DTLS_MAJOR)
+            ssl->options.haveEMS = 1;
+    #endif /* WOLFSSL_DTLS */
+    }
+#endif /* HAVE_EXTENDED_MASTER && !NO_WOLFSSL_CLIENT */
+
+#if defined(WOLFSSL_DTLS) && !defined(NO_WOLFSSL_SERVER)
+    if (ssl->options.dtls && ssl->options.side == WOLFSSL_SERVER_END) {
+        int ret;
+        ret = wolfSSL_DTLS_SetCookieSecret(ssl, NULL, 0);
+        if (ret != 0) {
+            WOLFSSL_MSG("DTLS Cookie Secret error");
+            return ret;
+        }
+    }
+#endif /* WOLFSSL_DTLS && !NO_WOLFSSL_SERVER */
+
+    return InitSSL_Suites(ssl);
+}
+#endif /* OPENSSL_EXTRA || WOLFSSL_EITHER_SIDE */
+
+/* Initialize SSL context, return 0 on success */
+int InitSSL_Ctx(WOLFSSL_CTX* ctx, WOLFSSL_METHOD* method, void* heap)
+{
+    int ret = 0;
+
+    XMEMSET(ctx, 0, sizeof(WOLFSSL_CTX));
+
+    ctx->method   = method;
+    ctx->refCount = 1;          /* so either CTX_free or SSL_free can release */
+    ctx->heap     = ctx;        /* defaults to self */
+    ctx->timeout  = WOLFSSL_SESSION_TIMEOUT;
+    ctx->minDowngrade = WOLFSSL_MIN_DOWNGRADE; /* current default: TLSv1_MINOR */
+
+    if (wc_InitMutex(&ctx->countMutex) < 0) {
+        WOLFSSL_MSG("Mutex error on CTX init");
+        ctx->err = CTX_INIT_MUTEX_E;
+        return BAD_MUTEX_E;
+    }
+
+#ifndef NO_DH
+    ctx->minDhKeySz  = MIN_DHKEY_SZ;
+    ctx->maxDhKeySz  = MAX_DHKEY_SZ;
+#endif
+#ifndef NO_RSA
+    ctx->minRsaKeySz = MIN_RSAKEY_SZ;
+#endif
+#ifdef HAVE_ECC
+    ctx->minEccKeySz  = MIN_ECCKEY_SZ;
+    ctx->eccTempKeySz = ECDHE_SIZE;
+#endif
+#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
+    ctx->verifyDepth = MAX_CHAIN_DEPTH;
+#endif
+#ifdef OPENSSL_EXTRA
+    ctx->cbioFlag = WOLFSSL_CBIO_NONE;
+#endif
+
+#ifndef WOLFSSL_USER_IO
+    #ifdef MICRIUM
+        ctx->CBIORecv = MicriumReceive;
+        ctx->CBIOSend = MicriumSend;
+        #ifdef WOLFSSL_DTLS
+            if (method->version.major == DTLS_MAJOR) {
+                ctx->CBIORecv   = MicriumReceiveFrom;
+                ctx->CBIOSend   = MicriumSendTo;
+            }
+            #ifdef WOLFSSL_SESSION_EXPORT
+                #error Micrium port does not support DTLS session export yet
+            #endif
+        #endif
+    #elif defined WOLFSSL_UIP
+        ctx->CBIORecv = uIPReceive;
+        ctx->CBIOSend = uIPSend;
+        #ifdef WOLFSSL_DTLS
+        if (method->version.major == DTLS_MAJOR) {
+            ctx->CBIOSendTo = uIPSendTo;
+            ctx->CBIORecvFrom = uIPRecvFrom;
+        }
+        #endif
+    #else
+        ctx->CBIORecv = EmbedReceive;
+        ctx->CBIOSend = EmbedSend;
+        #ifdef WOLFSSL_DTLS
+            if (method->version.major == DTLS_MAJOR) {
+                ctx->CBIORecv   = EmbedReceiveFrom;
+                ctx->CBIOSend   = EmbedSendTo;
+            }
+            #ifdef WOLFSSL_SESSION_EXPORT
+            ctx->CBGetPeer = EmbedGetPeer;
+            ctx->CBSetPeer = EmbedSetPeer;
+            #endif
+        #endif
+    #endif /* MICRIUM */
+#endif /* WOLFSSL_USER_IO */
+
+#ifdef HAVE_NETX
+    ctx->CBIORecv = NetX_Receive;
+    ctx->CBIOSend = NetX_Send;
+#elif defined(WOLFSSL_APACHE_MYNEWT) && !defined(WOLFSSL_LWIP)
+    ctx->CBIORecv = Mynewt_Receive;
+    ctx->CBIOSend = Mynewt_Send;
+#elif defined(WOLFSSL_GNRC)
+    ctx->CBIORecv = GNRC_ReceiveFrom;
+    ctx->CBIOSend = GNRC_SendTo;
+#endif
+
+#ifdef HAVE_NTRU
+    if (method->side == WOLFSSL_CLIENT_END)
+        ctx->haveNTRU = 1;           /* always on client side */
+                                     /* server can turn on by loading key */
+#endif
+#ifdef HAVE_ECC
+    if (method->side == WOLFSSL_CLIENT_END) {
+        ctx->haveECDSAsig  = 1;        /* always on client side */
+        ctx->haveECC  = 1;             /* server turns on with ECC key cert */
+        ctx->haveStaticECC = 1;        /* server can turn on by loading key */
+    }
+#elif defined(HAVE_ED25519) || defined(HAVE_ED448)
+    if (method->side == WOLFSSL_CLIENT_END) {
+        ctx->haveECDSAsig  = 1;        /* always on client side */
+        ctx->haveECC  = 1;             /* server turns on with ECC key cert */
+    }
+#endif
+
+    ctx->devId = INVALID_DEVID;
+
+#if defined(WOLFSSL_DTLS)
+    #ifdef WOLFSSL_SCTP
+        ctx->dtlsMtuSz = MAX_RECORD_SIZE;
+    #elif defined(WOLFSSL_DTLS_MTU)
+        ctx->dtlsMtuSz = MAX_MTU;
+    #endif
+#endif
+
+#ifndef NO_CERTS
+    ctx->cm = wolfSSL_CertManagerNew_ex(heap);
+    if (ctx->cm == NULL) {
+        WOLFSSL_MSG("Bad Cert Manager New");
+        return BAD_CERT_MANAGER_ERROR;
+    }
+    #ifdef OPENSSL_EXTRA
+    /* setup WOLFSSL_X509_STORE */
+    ctx->x509_store.cm = ctx->cm;
+    #endif
+#endif
+
+#if defined(HAVE_EXTENDED_MASTER) && !defined(NO_WOLFSSL_CLIENT)
+    if (method->side == WOLFSSL_CLIENT_END) {
+        if ((method->version.major == SSLv3_MAJOR) &&
+             (method->version.minor >= TLSv1_MINOR)) {
+
+            ctx->haveEMS = 1;
+        }
+#ifdef WOLFSSL_DTLS
+        if (method->version.major == DTLS_MAJOR)
+            ctx->haveEMS = 1;
+#endif /* WOLFSSL_DTLS */
+    }
+#endif /* HAVE_EXTENDED_MASTER && !NO_WOLFSSL_CLIENT */
+
+#if defined(HAVE_SESSION_TICKET) && !defined(NO_WOLFSSL_SERVER)
+    ctx->ticketHint = SESSION_TICKET_HINT_DEFAULT;
+#endif
+
+#ifdef HAVE_WOLF_EVENT
+    ret = wolfEventQueue_Init(&ctx->event_queue);
+#endif /* HAVE_WOLF_EVENT */
+
+#ifdef WOLFSSL_EARLY_DATA
+    ctx->maxEarlyDataSz = MAX_EARLY_DATA_SZ;
+#endif
+
+    ctx->heap = heap; /* wolfSSL_CTX_load_static_memory sets */
+    ctx->verifyDepth = MAX_CHAIN_DEPTH;
+
+    return ret;
+}
+
+
+/* In case contexts are held in array and don't want to free actual ctx */
+void SSL_CtxResourceFree(WOLFSSL_CTX* ctx)
+{
+#if defined(HAVE_CERTIFICATE_STATUS_REQUEST_V2) && \
+                     defined(HAVE_TLS_EXTENSIONS) && !defined(NO_WOLFSSL_SERVER)
+    int i;
+#endif
+
+#ifdef HAVE_WOLF_EVENT
+    wolfEventQueue_Free(&ctx->event_queue);
+#endif /* HAVE_WOLF_EVENT */
+
+#ifdef WOLFSSL_STATIC_MEMORY
+    if (ctx->onHeap == 1) {
+        XFREE(ctx->method, ctx->heap, DYNAMIC_TYPE_METHOD);
+    }
+    else {
+        XFREE(ctx->method, NULL, DYNAMIC_TYPE_METHOD);
+    }
+#else
+    XFREE(ctx->method, ctx->heap, DYNAMIC_TYPE_METHOD);
+#endif
+    ctx->method = NULL;
+    if (ctx->suites) {
+        XFREE(ctx->suites, ctx->heap, DYNAMIC_TYPE_SUITES);
+        ctx->suites = NULL;
+    }
+
+#ifndef NO_DH
+    XFREE(ctx->serverDH_G.buffer, ctx->heap, DYNAMIC_TYPE_PUBLIC_KEY);
+    ctx->serverDH_G.buffer = NULL;
+    XFREE(ctx->serverDH_P.buffer, ctx->heap, DYNAMIC_TYPE_PUBLIC_KEY);
+    ctx->serverDH_P.buffer = NULL;
+#endif /* !NO_DH */
+
+#ifdef SINGLE_THREADED
+    if (ctx->rng) {
+        wc_FreeRng(ctx->rng);
+        XFREE(ctx->rng, ctx->heap, DYNAMIC_TYPE_RNG);
+        ctx->rng = NULL;
+    }
+#endif /* SINGLE_THREADED */
+
+#ifndef NO_CERTS
+    FreeDer(&ctx->privateKey);
+    FreeDer(&ctx->certificate);
+    #ifdef KEEP_OUR_CERT
+        if (ctx->ourCert && ctx->ownOurCert) {
+            FreeX509(ctx->ourCert);
+            XFREE(ctx->ourCert, ctx->heap, DYNAMIC_TYPE_X509);
+            ctx->ourCert = NULL;
+        }
+    #endif /* KEEP_OUR_CERT */
+    FreeDer(&ctx->certChain);
+    wolfSSL_CertManagerFree(ctx->cm);
+    ctx->cm = NULL;
+    #ifdef OPENSSL_EXTRA
+    /* ctx->cm was free'd so cm of x509 store should now be NULL */
+        if (ctx->x509_store_pt != NULL) {
+            ctx->x509_store_pt->cm = NULL;
+        }
+        wolfSSL_X509_STORE_free(ctx->x509_store_pt);
+        while (ctx->ca_names != NULL) {
+            WOLFSSL_STACK *next = ctx->ca_names->next;
+            wolfSSL_X509_NAME_free(ctx->ca_names->data.name);
+            XFREE(ctx->ca_names, NULL, DYNAMIC_TYPE_OPENSSL);
+            ctx->ca_names = next;
+        }
+    #endif
+    #if defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY)
+        while (ctx->x509Chain != NULL) {
+            WOLFSSL_STACK *next = ctx->x509Chain->next;
+            wolfSSL_X509_free(ctx->x509Chain->data.x509);
+            XFREE(ctx->x509Chain, NULL, DYNAMIC_TYPE_OPENSSL);
+            ctx->x509Chain = next;
+        }
+    #endif
+#endif /* !NO_CERTS */
+
+#ifdef HAVE_TLS_EXTENSIONS
+    TLSX_FreeAll(ctx->extensions, ctx->heap);
+
+#ifndef NO_WOLFSSL_SERVER
+#if defined(HAVE_CERTIFICATE_STATUS_REQUEST) \
+ || defined(HAVE_CERTIFICATE_STATUS_REQUEST_V2)
+    if (ctx->certOcspRequest) {
+        FreeOcspRequest(ctx->certOcspRequest);
+        XFREE(ctx->certOcspRequest, ctx->heap, DYNAMIC_TYPE_OCSP_REQUEST);
+    }
+#endif
+
+#ifdef HAVE_CERTIFICATE_STATUS_REQUEST_V2
+    for (i = 0; i < MAX_CHAIN_DEPTH; i++) {
+        if (ctx->chainOcspRequest[i]) {
+            FreeOcspRequest(ctx->chainOcspRequest[i]);
+            XFREE(ctx->chainOcspRequest[i], ctx->heap, DYNAMIC_TYPE_OCSP_REQUEST);
+            ctx->chainOcspRequest[i] = NULL;
+        }
+    }
+#endif /* HAVE_CERTIFICATE_STATUS_REQUEST_V2 */
+#endif /* !NO_WOLFSSL_SERVER */
+
+#endif /* HAVE_TLS_EXTENSIONS */
+#ifdef OPENSSL_EXTRA
+    if(ctx->alpn_cli_protos) {
+        XFREE((void *)ctx->alpn_cli_protos, NULL, DYNAMIC_TYPE_OPENSSL);
+        ctx->alpn_cli_protos = NULL;
+    }
+#endif
+#ifdef WOLFSSL_STATIC_MEMORY
+    if (ctx->heap != NULL) {
+#ifdef WOLFSSL_HEAP_TEST
+        /* avoid dereferencing a test value */
+        if (ctx->heap != (void*)WOLFSSL_HEAP_TEST)
+#endif
+        {
+            WOLFSSL_HEAP_HINT* hint = (WOLFSSL_HEAP_HINT*)(ctx->heap);
+            wc_FreeMutex(&((WOLFSSL_HEAP*)(hint->memory))->memory_mutex);
+        }
+    }
+#endif /* WOLFSSL_STATIC_MEMORY */
+}
+
+
+void FreeSSL_Ctx(WOLFSSL_CTX* ctx)
+{
+    int refCount;
+
+    /* decrement CTX reference count */
+    if ((refCount = SSL_CTX_RefCount(ctx, -1)) < 0) {
+        /* check error state, if mutex error code then mutex init failed but
+         * CTX was still malloc'd */
+        if (ctx->err == CTX_INIT_MUTEX_E) {
+            SSL_CtxResourceFree(ctx);
+            XFREE(ctx, ctx->heap, DYNAMIC_TYPE_CTX);
+        }
+        return;
+    }
+
+    if (refCount == 0) {
+        void* heap = ctx->heap;
+        WOLFSSL_MSG("CTX ref count down to 0, doing full free");
+        SSL_CtxResourceFree(ctx);
+        wc_FreeMutex(&ctx->countMutex);
+#ifdef WOLFSSL_STATIC_MEMORY
+        if (ctx->onHeap == 0) {
+            heap = NULL;
+        }
+#endif
+        XFREE(ctx, heap, DYNAMIC_TYPE_CTX);
+        (void)heap; /* not used in some builds */
+    }
+    else {
+        (void)ctx;
+        WOLFSSL_MSG("CTX ref count not 0 yet, no free");
+    }
+}
+
+
+/* Set cipher pointers to null */
+void InitCiphers(WOLFSSL* ssl)
+{
+#ifdef BUILD_ARC4
+    ssl->encrypt.arc4 = NULL;
+    ssl->decrypt.arc4 = NULL;
+#endif
+#ifdef BUILD_DES3
+    ssl->encrypt.des3 = NULL;
+    ssl->decrypt.des3 = NULL;
+#endif
+#ifdef BUILD_AES
+    ssl->encrypt.aes = NULL;
+    ssl->decrypt.aes = NULL;
+#endif
+#ifdef HAVE_CAMELLIA
+    ssl->encrypt.cam = NULL;
+    ssl->decrypt.cam = NULL;
+#endif
+#ifdef HAVE_HC128
+    ssl->encrypt.hc128 = NULL;
+    ssl->decrypt.hc128 = NULL;
+#endif
+#ifdef BUILD_RABBIT
+    ssl->encrypt.rabbit = NULL;
+    ssl->decrypt.rabbit = NULL;
+#endif
+#ifdef HAVE_CHACHA
+    ssl->encrypt.chacha = NULL;
+    ssl->decrypt.chacha = NULL;
+#endif
+#if defined(HAVE_POLY1305) && defined(HAVE_ONE_TIME_AUTH)
+    ssl->auth.poly1305 = NULL;
+#endif
+    ssl->encrypt.setup = 0;
+    ssl->decrypt.setup = 0;
+#ifdef HAVE_ONE_TIME_AUTH
+    ssl->auth.setup    = 0;
+#endif
+#ifdef HAVE_IDEA
+    ssl->encrypt.idea = NULL;
+    ssl->decrypt.idea = NULL;
+#endif
+}
+
+
+/* Free ciphers */
+void FreeCiphers(WOLFSSL* ssl)
+{
+    (void)ssl;
+#ifdef BUILD_ARC4
+    wc_Arc4Free(ssl->encrypt.arc4);
+    wc_Arc4Free(ssl->decrypt.arc4);
+    XFREE(ssl->encrypt.arc4, ssl->heap, DYNAMIC_TYPE_CIPHER);
+    XFREE(ssl->decrypt.arc4, ssl->heap, DYNAMIC_TYPE_CIPHER);
+#endif
+#ifdef BUILD_DES3
+    wc_Des3Free(ssl->encrypt.des3);
+    wc_Des3Free(ssl->decrypt.des3);
+    XFREE(ssl->encrypt.des3, ssl->heap, DYNAMIC_TYPE_CIPHER);
+    XFREE(ssl->decrypt.des3, ssl->heap, DYNAMIC_TYPE_CIPHER);
+#endif
+#if defined(BUILD_AES) || defined(BUILD_AESGCM) /* See: InitKeys() in keys.c
+                                                 * on addition of BUILD_AESGCM
+                                                 * check (enc->aes, dec->aes) */
+    wc_AesFree(ssl->encrypt.aes);
+    wc_AesFree(ssl->decrypt.aes);
+    #if (defined(BUILD_AESGCM) || defined(HAVE_AESCCM)) && \
+                                                      !defined(WOLFSSL_NO_TLS12)
+        XFREE(ssl->decrypt.additional, ssl->heap, DYNAMIC_TYPE_AES_BUFFER);
+        XFREE(ssl->encrypt.additional, ssl->heap, DYNAMIC_TYPE_AES_BUFFER);
+    #endif
+    XFREE(ssl->encrypt.aes, ssl->heap, DYNAMIC_TYPE_CIPHER);
+    XFREE(ssl->decrypt.aes, ssl->heap, DYNAMIC_TYPE_CIPHER);
+#endif
+#ifdef CIPHER_NONCE
+    XFREE(ssl->decrypt.nonce, ssl->heap, DYNAMIC_TYPE_AES_BUFFER);
+    XFREE(ssl->encrypt.nonce, ssl->heap, DYNAMIC_TYPE_AES_BUFFER);
+#endif
+#ifdef HAVE_CAMELLIA
+    XFREE(ssl->encrypt.cam, ssl->heap, DYNAMIC_TYPE_CIPHER);
+    XFREE(ssl->decrypt.cam, ssl->heap, DYNAMIC_TYPE_CIPHER);
+#endif
+#ifdef HAVE_HC128
+    XFREE(ssl->encrypt.hc128, ssl->heap, DYNAMIC_TYPE_CIPHER);
+    XFREE(ssl->decrypt.hc128, ssl->heap, DYNAMIC_TYPE_CIPHER);
+#endif
+#ifdef BUILD_RABBIT
+    XFREE(ssl->encrypt.rabbit, ssl->heap, DYNAMIC_TYPE_CIPHER);
+    XFREE(ssl->decrypt.rabbit, ssl->heap, DYNAMIC_TYPE_CIPHER);
+#endif
+#ifdef HAVE_CHACHA
+    XFREE(ssl->encrypt.chacha, ssl->heap, DYNAMIC_TYPE_CIPHER);
+    XFREE(ssl->decrypt.chacha, ssl->heap, DYNAMIC_TYPE_CIPHER);
+#endif
+#if defined(HAVE_POLY1305) && defined(HAVE_ONE_TIME_AUTH)
+    XFREE(ssl->auth.poly1305, ssl->heap, DYNAMIC_TYPE_CIPHER);
+#endif
+#ifdef HAVE_IDEA
+    XFREE(ssl->encrypt.idea, ssl->heap, DYNAMIC_TYPE_CIPHER);
+    XFREE(ssl->decrypt.idea, ssl->heap, DYNAMIC_TYPE_CIPHER);
+#endif
+#if defined(WOLFSSL_TLS13) && defined(HAVE_NULL_CIPHER)
+    wc_HmacFree(ssl->encrypt.hmac);
+    wc_HmacFree(ssl->decrypt.hmac);
+    XFREE(ssl->encrypt.hmac, ssl->heap, DYNAMIC_TYPE_CIPHER);
+    XFREE(ssl->decrypt.hmac, ssl->heap, DYNAMIC_TYPE_CIPHER);
+#endif
+}
+
+
+void InitCipherSpecs(CipherSpecs* cs)
+{
+    XMEMSET(cs, 0, sizeof(CipherSpecs));
+
+    cs->bulk_cipher_algorithm = INVALID_BYTE;
+    cs->cipher_type           = INVALID_BYTE;
+    cs->mac_algorithm         = INVALID_BYTE;
+    cs->kea                   = INVALID_BYTE;
+    cs->sig_algo              = INVALID_BYTE;
+}
+
+#if defined(USE_ECDSA_KEYSZ_HASH_ALGO) || (defined(WOLFSSL_TLS13) && \
+                                                              defined(HAVE_ECC))
+static int GetMacDigestSize(byte macAlgo)
+{
+    switch (macAlgo) {
+    #ifndef NO_SHA
+        case sha_mac:
+            return WC_SHA_DIGEST_SIZE;
+    #endif
+    #ifndef NO_SHA256
+        case sha256_mac:
+            return WC_SHA256_DIGEST_SIZE;
+    #endif
+    #ifdef WOLFSSL_SHA384
+        case sha384_mac:
+            return WC_SHA384_DIGEST_SIZE;
+    #endif
+    #ifdef WOLFSSL_SHA512
+        case sha512_mac:
+            return WC_SHA512_DIGEST_SIZE;
+    #endif
+        default:
+            break;
+    }
+    return NOT_COMPILED_IN;
+}
+#endif /* USE_ECDSA_KEYSZ_HASH_ALGO */
+
+static WC_INLINE void AddSuiteHashSigAlgo(Suites* suites, byte macAlgo, byte sigAlgo,
+    int keySz, word16* inOutIdx)
+{
+    int addSigAlgo = 1;
+
+#ifdef USE_ECDSA_KEYSZ_HASH_ALGO
+    if (sigAlgo == ecc_dsa_sa_algo) {
+        int digestSz = GetMacDigestSize(macAlgo);
+        /* do not add sig/algos with digest size larger than key size */
+        if (digestSz <= 0 || (keySz > 0 && digestSz > keySz)) {
+            addSigAlgo = 0;
+        }
+    }
+#else
+    (void)keySz;
+#endif /* USE_ECDSA_KEYSZ_HASH_ALGO */
+
+    if (addSigAlgo) {
+#ifdef WC_RSA_PSS
+        if (sigAlgo == rsa_pss_sa_algo) {
+            /* RSA PSS is sig then mac */
+            suites->hashSigAlgo[*inOutIdx] = sigAlgo;
+            *inOutIdx += 1;
+            suites->hashSigAlgo[*inOutIdx] = macAlgo;
+            *inOutIdx += 1;
+    #ifdef WOLFSSL_TLS13
+            /* Add the certificate algorithm as well */
+            suites->hashSigAlgo[*inOutIdx] = sigAlgo;
+            *inOutIdx += 1;
+            suites->hashSigAlgo[*inOutIdx] = PSS_RSAE_TO_PSS_PSS(macAlgo);
+            *inOutIdx += 1;
+    #endif
+        }
+        else
+#endif
+        {
+            suites->hashSigAlgo[*inOutIdx] = macAlgo;
+            *inOutIdx += 1;
+            suites->hashSigAlgo[*inOutIdx] = sigAlgo;
+            *inOutIdx += 1;
+        }
+    }
+}
+
+void InitSuitesHashSigAlgo(Suites* suites, int haveECDSAsig, int haveRSAsig,
+                           int haveAnon, int tls1_2, int keySz)
+{
+    word16 idx = 0;
+
+    (void)tls1_2;
+    (void)keySz;
+
+#if defined(HAVE_ECC) || defined(HAVE_ED25519) || defined(HAVE_ED448)
+    if (haveECDSAsig) {
+#ifdef HAVE_ECC
+    #ifdef WOLFSSL_SHA512
+        AddSuiteHashSigAlgo(suites, sha512_mac, ecc_dsa_sa_algo, keySz, &idx);
+    #endif
+    #ifdef WOLFSSL_SHA384
+        AddSuiteHashSigAlgo(suites, sha384_mac, ecc_dsa_sa_algo, keySz, &idx);
+    #endif
+    #ifndef NO_SHA256
+        AddSuiteHashSigAlgo(suites, sha256_mac, ecc_dsa_sa_algo, keySz, &idx);
+    #endif
+    #if !defined(NO_SHA) && (!defined(NO_OLD_TLS) || \
+                                            defined(WOLFSSL_ALLOW_TLS_SHA1))
+        AddSuiteHashSigAlgo(suites, sha_mac, ecc_dsa_sa_algo, keySz, &idx);
+    #endif
+#endif
+    #ifdef HAVE_ED25519
+        AddSuiteHashSigAlgo(suites, ED25519_SA_MAJOR, ED25519_SA_MINOR, keySz,
+                                                                          &idx);
+    #endif
+    #ifdef HAVE_ED448
+        AddSuiteHashSigAlgo(suites, ED448_SA_MAJOR, ED448_SA_MINOR, keySz,
+                                                                          &idx);
+    #endif
+    }
+#endif /* HAVE_ECC || HAVE_ED25519 || defined(HAVE_ED448 */
+
+    if (haveRSAsig) {
+    #ifdef WC_RSA_PSS
+        if (tls1_2) {
+        #ifdef WOLFSSL_SHA512
+            AddSuiteHashSigAlgo(suites, sha512_mac, rsa_pss_sa_algo, keySz,
+                                                                          &idx);
+        #endif
+        #ifdef WOLFSSL_SHA384
+            AddSuiteHashSigAlgo(suites, sha384_mac, rsa_pss_sa_algo, keySz,
+                                                                          &idx);
+        #endif
+        #ifndef NO_SHA256
+            AddSuiteHashSigAlgo(suites, sha256_mac, rsa_pss_sa_algo, keySz,
+                                                                          &idx);
+        #endif
+        }
+    #endif
+    #ifdef WOLFSSL_SHA512
+        AddSuiteHashSigAlgo(suites, sha512_mac, rsa_sa_algo, keySz, &idx);
+    #endif
+    #ifdef WOLFSSL_SHA384
+        AddSuiteHashSigAlgo(suites, sha384_mac, rsa_sa_algo, keySz, &idx);
+    #endif
+    #ifndef NO_SHA256
+        AddSuiteHashSigAlgo(suites, sha256_mac, rsa_sa_algo, keySz, &idx);
+    #endif
+    #ifdef WOLFSSL_SHA224
+        AddSuiteHashSigAlgo(suites, sha224_mac, rsa_sa_algo, keySz, &idx);
+    #endif
+    #if !defined(NO_SHA) && (!defined(NO_OLD_TLS) || \
+                                            defined(WOLFSSL_ALLOW_TLS_SHA1))
+        AddSuiteHashSigAlgo(suites, sha_mac, rsa_sa_algo, keySz, &idx);
+    #endif
+    }
+
+#ifdef HAVE_ANON
+    if (haveAnon) {
+        AddSuiteHashSigAlgo(suites, sha_mac, anonymous_sa_algo, keySz, &idx);
+    }
+#endif
+
+    (void)haveAnon;
+    (void)haveECDSAsig;
+    suites->hashSigAlgoSz = idx;
+}
+
+void InitSuites(Suites* suites, ProtocolVersion pv, int keySz, word16 haveRSA,
+                word16 havePSK, word16 haveDH, word16 haveNTRU,
+                word16 haveECDSAsig, word16 haveECC,
+                word16 haveStaticECC, int side)
+{
+    word16 idx = 0;
+    int    tls    = pv.major == SSLv3_MAJOR && pv.minor >= TLSv1_MINOR;
+    int    tls1_2 = pv.major == SSLv3_MAJOR && pv.minor >= TLSv1_2_MINOR;
+#ifdef WOLFSSL_TLS13
+    int    tls1_3 = IsAtLeastTLSv1_3(pv);
+#endif
+    int    dtls   = 0;
+    int    haveRSAsig = 1;
+
+    (void)tls;  /* shut up compiler */
+    (void)tls1_2;
+    (void)dtls;
+    (void)haveDH;
+    (void)havePSK;
+    (void)haveNTRU;
+    (void)haveStaticECC;
+    (void)haveECC;
+    (void)side;
+    (void)haveRSA;    /* some builds won't read */
+    (void)haveRSAsig; /* non ecc builds won't read */
+
+    if (suites == NULL) {
+        WOLFSSL_MSG("InitSuites pointer error");
+        return;
+    }
+
+    if (suites->setSuites)
+        return;      /* trust user settings, don't override */
+
+#ifdef WOLFSSL_TLS13
+#ifdef BUILD_TLS_AES_128_GCM_SHA256
+    if (tls1_3) {
+        suites->suites[idx++] = TLS13_BYTE;
+        suites->suites[idx++] = TLS_AES_128_GCM_SHA256;
+    }
+#endif
+
+#ifdef BUILD_TLS_AES_256_GCM_SHA384
+    if (tls1_3) {
+        suites->suites[idx++] = TLS13_BYTE;
+        suites->suites[idx++] = TLS_AES_256_GCM_SHA384;
+    }
+#endif
+
+#ifdef BUILD_TLS_CHACHA20_POLY1305_SHA256
+    if (tls1_3) {
+        suites->suites[idx++] = TLS13_BYTE;
+        suites->suites[idx++] = TLS_CHACHA20_POLY1305_SHA256;
+    }
+#endif
+
+#ifdef BUILD_TLS_AES_128_CCM_SHA256
+    if (tls1_3) {
+        suites->suites[idx++] = TLS13_BYTE;
+        suites->suites[idx++] = TLS_AES_128_CCM_SHA256;
+    }
+#endif
+
+#ifdef BUILD_TLS_AES_128_CCM_8_SHA256
+    if (tls1_3) {
+        suites->suites[idx++] = TLS13_BYTE;
+        suites->suites[idx++] = TLS_AES_128_CCM_8_SHA256;
+    }
+#endif
+
+#ifdef HAVE_NULL_CIPHER
+    #ifdef BUILD_TLS_SHA256_SHA256
+        if (tls1_3) {
+            suites->suites[idx++] = ECC_BYTE;
+            suites->suites[idx++] = TLS_SHA256_SHA256;
+        }
+    #endif
+
+    #ifdef BUILD_TLS_SHA384_SHA384
+        if (tls1_3) {
+            suites->suites[idx++] = ECC_BYTE;
+            suites->suites[idx++] = TLS_SHA384_SHA384;
+        }
+    #endif
+#endif
+#endif /* WOLFSSL_TLS13 */
+
+#ifndef WOLFSSL_NO_TLS12
+
+#if !defined(NO_WOLFSSL_SERVER) && !defined(NO_RSA)
+    if (side == WOLFSSL_SERVER_END && haveStaticECC) {
+        haveRSA = 0;   /* can't do RSA with ECDSA key */
+    }
+
+    if (side == WOLFSSL_SERVER_END && haveECDSAsig) {
+        haveRSAsig = 0;     /* can't have RSA sig if signed by ECDSA */
+    }
+#endif /* !NO_WOLFSSL_SERVER */
+
+#ifdef WOLFSSL_DTLS
+    if (pv.major == DTLS_MAJOR) {
+        dtls   = 1;
+        tls    = 1;
+        /* May be dead assignments dependent upon configuration */
+        (void) dtls;
+        (void) tls;
+        tls1_2 = pv.minor <= DTLSv1_2_MINOR;
+    }
+#endif
+
+#ifdef HAVE_RENEGOTIATION_INDICATION
+    if (side == WOLFSSL_CLIENT_END) {
+        suites->suites[idx++] = CIPHER_BYTE;
+        suites->suites[idx++] = TLS_EMPTY_RENEGOTIATION_INFO_SCSV;
+    }
+#endif
+
+#ifdef BUILD_TLS_QSH
+    if (tls) {
+        suites->suites[idx++] = QSH_BYTE;
+        suites->suites[idx++] = TLS_QSH;
+    }
+#endif
+
+#ifdef BUILD_TLS_NTRU_RSA_WITH_AES_256_CBC_SHA
+   if (tls && haveNTRU && haveRSA) {
+        suites->suites[idx++] = CIPHER_BYTE;
+        suites->suites[idx++] = TLS_NTRU_RSA_WITH_AES_256_CBC_SHA;
+   }
+#endif
+
+#ifdef BUILD_TLS_NTRU_RSA_WITH_AES_128_CBC_SHA
+    if (tls && haveNTRU && haveRSA) {
+        suites->suites[idx++] = CIPHER_BYTE;
+        suites->suites[idx++] = TLS_NTRU_RSA_WITH_AES_128_CBC_SHA;
+    }
+#endif
+
+#ifdef BUILD_TLS_NTRU_RSA_WITH_RC4_128_SHA
+    if (!dtls && tls && haveNTRU && haveRSA) {
+        suites->suites[idx++] = CIPHER_BYTE;
+        suites->suites[idx++] = TLS_NTRU_RSA_WITH_RC4_128_SHA;
+    }
+#endif
+
+#ifdef BUILD_TLS_NTRU_RSA_WITH_3DES_EDE_CBC_SHA
+    if (tls && haveNTRU && haveRSA) {
+        suites->suites[idx++] = CIPHER_BYTE;
+        suites->suites[idx++] = TLS_NTRU_RSA_WITH_3DES_EDE_CBC_SHA;
+    }
+#endif
+
+#ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384
+    if (tls1_2 && haveECC) {
+        suites->suites[idx++] = ECC_BYTE;
+        suites->suites[idx++] = TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384;
+    }
+#endif
+
+#ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
+    if (tls1_2 && haveECC) {
+        suites->suites[idx++] = ECC_BYTE;
+        suites->suites[idx++] = TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256;
+    }
+#endif
+
+#ifdef BUILD_TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
+    if (tls1_2 && haveRSA) {
+        suites->suites[idx++] = ECC_BYTE;
+        suites->suites[idx++] = TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384;
+    }
+#endif
+
+#ifdef BUILD_TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
+    if (tls1_2 && haveRSA) {
+        suites->suites[idx++] = ECC_BYTE;
+        suites->suites[idx++] = TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256;
+    }
+#endif
+
+#ifdef BUILD_TLS_DHE_RSA_WITH_AES_256_GCM_SHA384
+    if (tls1_2 && haveDH && haveRSA) {
+        suites->suites[idx++] = CIPHER_BYTE;
+        suites->suites[idx++] = TLS_DHE_RSA_WITH_AES_256_GCM_SHA384;
+    }
+#endif
+
+#ifdef BUILD_TLS_DHE_RSA_WITH_AES_128_GCM_SHA256
+    if (tls1_2 && haveDH && haveRSA) {
+        suites->suites[idx++] = CIPHER_BYTE;
+        suites->suites[idx++] = TLS_DHE_RSA_WITH_AES_128_GCM_SHA256;
+    }
+#endif
+
+#ifdef BUILD_TLS_RSA_WITH_AES_256_GCM_SHA384
+    if (tls1_2 && haveRSA) {
+        suites->suites[idx++] = CIPHER_BYTE;
+        suites->suites[idx++] = TLS_RSA_WITH_AES_256_GCM_SHA384;
+    }
+#endif
+
+#ifdef BUILD_TLS_RSA_WITH_AES_128_GCM_SHA256
+    if (tls1_2 && haveRSA) {
+        suites->suites[idx++] = CIPHER_BYTE;
+        suites->suites[idx++] = TLS_RSA_WITH_AES_128_GCM_SHA256;
+    }
+#endif
+
+#ifdef BUILD_TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384
+    if (tls1_2 && haveECC && haveStaticECC) {
+        suites->suites[idx++] = ECC_BYTE;
+        suites->suites[idx++] = TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384;
+    }
+#endif
+
+#ifdef BUILD_TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256
+    if (tls1_2 && haveECC && haveStaticECC) {
+        suites->suites[idx++] = ECC_BYTE;
+        suites->suites[idx++] = TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256;
+    }
+#endif
+
+#ifdef BUILD_TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384
+    if (tls1_2 && haveRSAsig && haveStaticECC) {
+        suites->suites[idx++] = ECC_BYTE;
+        suites->suites[idx++] = TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384;
+    }
+#endif
+
+#ifdef BUILD_TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256
+    if (tls1_2 && haveRSAsig && haveStaticECC) {
+        suites->suites[idx++] = ECC_BYTE;
+        suites->suites[idx++] = TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256;
+    }
+#endif
+
+#ifdef BUILD_TLS_DHE_PSK_WITH_AES_256_GCM_SHA384
+    if (tls1_2 && haveDH && havePSK) {
+        suites->suites[idx++] = CIPHER_BYTE;
+        suites->suites[idx++] = TLS_DHE_PSK_WITH_AES_256_GCM_SHA384;
+    }
+#endif
+
+#ifdef BUILD_TLS_DH_anon_WITH_AES_128_CBC_SHA
+    if (tls1_2 && haveDH) {
+      suites->suites[idx++] = CIPHER_BYTE;
+      suites->suites[idx++] = TLS_DH_anon_WITH_AES_128_CBC_SHA;
+    }
+#endif
+
+#ifdef BUILD_TLS_DH_anon_WITH_AES_256_GCM_SHA384
+    if (tls1_2 && haveDH) {
+      suites->suites[idx++] = CIPHER_BYTE;
+      suites->suites[idx++] = TLS_DH_anon_WITH_AES_256_GCM_SHA384;
+    }
+#endif
+
+#ifdef BUILD_TLS_DHE_PSK_WITH_AES_128_GCM_SHA256
+    if (tls1_2 && haveDH && havePSK) {
+        suites->suites[idx++] = CIPHER_BYTE;
+        suites->suites[idx++] = TLS_DHE_PSK_WITH_AES_128_GCM_SHA256;
+    }
+#endif
+
+#ifdef BUILD_TLS_PSK_WITH_AES_256_GCM_SHA384
+    if (tls1_2 && havePSK) {
+        suites->suites[idx++] = CIPHER_BYTE;
+        suites->suites[idx++] = TLS_PSK_WITH_AES_256_GCM_SHA384;
+    }
+#endif
+
+#ifdef BUILD_TLS_PSK_WITH_AES_128_GCM_SHA256
+    if (tls1_2 && havePSK) {
+        suites->suites[idx++] = CIPHER_BYTE;
+        suites->suites[idx++] = TLS_PSK_WITH_AES_128_GCM_SHA256;
+    }
+#endif
+
+#ifdef BUILD_TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256
+    if (tls1_2 && haveECC) {
+        suites->suites[idx++] = CHACHA_BYTE;
+        suites->suites[idx++] = TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256;
+    }
+#endif
+
+#ifdef BUILD_TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256
+    if (tls1_2 && haveRSA) {
+        suites->suites[idx++] = CHACHA_BYTE;
+        suites->suites[idx++] = TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256;
+    }
+#endif
+
+#ifdef BUILD_TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256
+    if (tls1_2 && haveRSA) {
+        suites->suites[idx++] = CHACHA_BYTE;
+        suites->suites[idx++] = TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256;
+    }
+#endif
+
+/* Place as higher priority for MYSQL */
+#if defined(WOLFSSL_MYSQL_COMPATIBLE)
+#ifdef BUILD_TLS_DHE_RSA_WITH_AES_256_CBC_SHA
+    if (tls && haveDH && haveRSA) {
+        suites->suites[idx++] = CIPHER_BYTE;
+        suites->suites[idx++] = TLS_DHE_RSA_WITH_AES_256_CBC_SHA;
+    }
+#endif
+#endif
+
+#ifdef BUILD_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256
+    if (tls1_2 && haveRSA) {
+        suites->suites[idx++] = ECC_BYTE;
+        suites->suites[idx++] = TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256;
+    }
+#endif
+
+#ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256
+    if (tls1_2 && haveECC) {
+        suites->suites[idx++] = ECC_BYTE;
+        suites->suites[idx++] = TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256;
+    }
+#endif
+
+#ifdef BUILD_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256
+    if (tls1_2 && haveRSAsig && haveStaticECC) {
+        suites->suites[idx++] = ECC_BYTE;
+        suites->suites[idx++] = TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256;
+    }
+#endif
+
+#ifdef BUILD_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256
+    if (tls1_2 && haveECC && haveStaticECC) {
+        suites->suites[idx++] = ECC_BYTE;
+        suites->suites[idx++] = TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256;
+    }
+#endif
+
+#ifdef BUILD_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384
+    if (tls1_2 && haveRSA) {
+        suites->suites[idx++] = ECC_BYTE;
+        suites->suites[idx++] = TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384;
+    }
+#endif
+
+#ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384
+    if (tls1_2 && haveECC) {
+        suites->suites[idx++] = ECC_BYTE;
+        suites->suites[idx++] = TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384;
+    }
+#endif
+
+#ifdef BUILD_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384
+    if (tls1_2 && haveRSAsig && haveStaticECC) {
+        suites->suites[idx++] = ECC_BYTE;
+        suites->suites[idx++] = TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384;
+    }
+#endif
+
+#ifdef BUILD_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384
+    if (tls1_2 && haveECC && haveStaticECC) {
+        suites->suites[idx++] = ECC_BYTE;
+        suites->suites[idx++] = TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384;
+    }
+#endif
+
+#ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA
+    if (tls && haveECC) {
+        suites->suites[idx++] = ECC_BYTE;
+        suites->suites[idx++] = TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA;
+    }
+#endif
+
+#ifdef BUILD_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA
+    if (tls && haveECC && haveStaticECC) {
+        suites->suites[idx++] = ECC_BYTE;
+        suites->suites[idx++] = TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA;
+    }
+#endif
+
+#ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA
+    if (tls && haveECC) {
+        suites->suites[idx++] = ECC_BYTE;
+        suites->suites[idx++] = TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA;
+    }
+#endif
+
+#ifdef BUILD_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA
+    if (tls && haveECC && haveStaticECC) {
+        suites->suites[idx++] = ECC_BYTE;
+        suites->suites[idx++] = TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA;
+    }
+#endif
+
+#ifdef BUILD_TLS_ECDHE_ECDSA_WITH_RC4_128_SHA
+    if (!dtls && tls && haveECC) {
+        suites->suites[idx++] = ECC_BYTE;
+        suites->suites[idx++] = TLS_ECDHE_ECDSA_WITH_RC4_128_SHA;
+    }
+#endif
+
+#ifdef BUILD_TLS_ECDH_ECDSA_WITH_RC4_128_SHA
+    if (!dtls && tls && haveECC && haveStaticECC) {
+        suites->suites[idx++] = ECC_BYTE;
+        suites->suites[idx++] = TLS_ECDH_ECDSA_WITH_RC4_128_SHA;
+    }
+#endif
+
+#ifdef BUILD_TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA
+    if (tls && haveECC) {
+        suites->suites[idx++] = ECC_BYTE;
+        suites->suites[idx++] = TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA;
+    }
+#endif
+
+#ifdef BUILD_TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA
+    if (tls && haveECC && haveStaticECC) {
+        suites->suites[idx++] = ECC_BYTE;
+        suites->suites[idx++] = TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA;
+    }
+#endif
+
+#ifdef BUILD_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA
+    if (tls && haveRSA) {
+        suites->suites[idx++] = ECC_BYTE;
+        suites->suites[idx++] = TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA;
+    }
+#endif
+
+#ifdef BUILD_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA
+    if (tls && haveRSAsig && haveStaticECC) {
+        suites->suites[idx++] = ECC_BYTE;
+        suites->suites[idx++] = TLS_ECDH_RSA_WITH_AES_256_CBC_SHA;
+    }
+#endif
+
+#ifdef BUILD_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA
+    if (tls && haveRSA) {
+        suites->suites[idx++] = ECC_BYTE;
+        suites->suites[idx++] = TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA;
+    }
+#endif
+
+#ifdef BUILD_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA
+    if (tls && haveRSAsig && haveStaticECC) {
+        suites->suites[idx++] = ECC_BYTE;
+        suites->suites[idx++] = TLS_ECDH_RSA_WITH_AES_128_CBC_SHA;
+    }
+#endif
+
+#ifdef BUILD_TLS_ECDHE_RSA_WITH_RC4_128_SHA
+    if (!dtls && tls && haveRSA) {
+        suites->suites[idx++] = ECC_BYTE;
+        suites->suites[idx++] = TLS_ECDHE_RSA_WITH_RC4_128_SHA;
+    }
+#endif
+
+#ifdef BUILD_TLS_ECDH_RSA_WITH_RC4_128_SHA
+    if (!dtls && tls && haveRSAsig && haveStaticECC) {
+        suites->suites[idx++] = ECC_BYTE;
+        suites->suites[idx++] = TLS_ECDH_RSA_WITH_RC4_128_SHA;
+    }
+#endif
+
+#ifdef BUILD_TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA
+    if (tls && haveRSA) {
+        suites->suites[idx++] = ECC_BYTE;
+        suites->suites[idx++] = TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA;
+    }
+#endif
+
+#ifdef BUILD_TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA
+    if (tls && haveRSAsig && haveStaticECC) {
+        suites->suites[idx++] = ECC_BYTE;
+        suites->suites[idx++] = TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA;
+    }
+#endif
+
+#ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_128_CCM
+    if (tls1_2 && haveECC) {
+        suites->suites[idx++] = ECC_BYTE;
+        suites->suites[idx++] = TLS_ECDHE_ECDSA_WITH_AES_128_CCM;
+    }
+#endif
+
+#ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8
+    if (tls1_2 && haveECC) {
+        suites->suites[idx++] = ECC_BYTE;
+        suites->suites[idx++] = TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8;
+    }
+#endif
+
+#ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8
+    if (tls1_2 && haveECC) {
+        suites->suites[idx++] = ECC_BYTE;
+        suites->suites[idx++] = TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8;
+    }
+#endif
+
+#ifdef BUILD_TLS_RSA_WITH_AES_128_CCM_8
+    if (tls1_2 && haveRSA) {
+        suites->suites[idx++] = ECC_BYTE;
+        suites->suites[idx++] = TLS_RSA_WITH_AES_128_CCM_8;
+    }
+#endif
+
+#ifdef BUILD_TLS_RSA_WITH_AES_256_CCM_8
+    if (tls1_2 && haveRSA) {
+        suites->suites[idx++] = ECC_BYTE;
+        suites->suites[idx++] = TLS_RSA_WITH_AES_256_CCM_8;
+    }
+#endif
+
+#ifdef BUILD_TLS_DHE_RSA_WITH_AES_256_CBC_SHA256
+#ifndef WOLFSSL_OLDTLS_SHA2_CIPHERSUITES
+    if (tls1_2 && haveDH && haveRSA)
+#else
+    if (tls && haveDH && haveRSA)
+#endif
+    {
+        suites->suites[idx++] = CIPHER_BYTE;
+        suites->suites[idx++] = TLS_DHE_RSA_WITH_AES_256_CBC_SHA256;
+    }
+#endif
+
+#ifdef BUILD_TLS_DHE_RSA_WITH_AES_128_CBC_SHA256
+#ifndef WOLFSSL_OLDTLS_SHA2_CIPHERSUITES
+    if (tls1_2 && haveDH && haveRSA)
+#else
+    if (tls && haveDH && haveRSA)
+#endif
+    {
+        suites->suites[idx++] = CIPHER_BYTE;
+        suites->suites[idx++] = TLS_DHE_RSA_WITH_AES_128_CBC_SHA256;
+    }
+#endif
+
+/* Place as higher priority for MYSQL testing */
+#if !defined(WOLFSSL_MYSQL_COMPATIBLE)
+#ifdef BUILD_TLS_DHE_RSA_WITH_AES_256_CBC_SHA
+    if (tls && haveDH && haveRSA) {
+        suites->suites[idx++] = CIPHER_BYTE;
+        suites->suites[idx++] = TLS_DHE_RSA_WITH_AES_256_CBC_SHA;
+    }
+#endif
+#endif
+
+#ifdef BUILD_TLS_DHE_RSA_WITH_AES_128_CBC_SHA
+    if (tls && haveDH && haveRSA) {
+        suites->suites[idx++] = CIPHER_BYTE;
+        suites->suites[idx++] = TLS_DHE_RSA_WITH_AES_128_CBC_SHA;
+    }
+#endif
+
+#ifdef BUILD_TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA
+    if (tls && haveDH && haveRSA) {
+        suites->suites[idx++] = CIPHER_BYTE;
+        suites->suites[idx++] = TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA;
+    }
+#endif
+
+#ifdef BUILD_TLS_RSA_WITH_AES_256_CBC_SHA256
+#ifndef WOLFSSL_OLDTLS_SHA2_CIPHERSUITES
+    if (tls1_2 && haveRSA)
+#else
+    if (tls && haveRSA)
+#endif
+    {
+        suites->suites[idx++] = CIPHER_BYTE;
+        suites->suites[idx++] = TLS_RSA_WITH_AES_256_CBC_SHA256;
+    }
+#endif
+
+#ifdef BUILD_TLS_RSA_WITH_AES_128_CBC_SHA256
+#ifndef WOLFSSL_OLDTLS_SHA2_CIPHERSUITES
+    if (tls1_2 && haveRSA)
+#else
+    if (tls && haveRSA)
+#endif
+    {
+        suites->suites[idx++] = CIPHER_BYTE;
+        suites->suites[idx++] = TLS_RSA_WITH_AES_128_CBC_SHA256;
+    }
+#endif
+
+#ifdef BUILD_TLS_RSA_WITH_AES_256_CBC_SHA
+    if (tls && haveRSA) {
+        suites->suites[idx++] = CIPHER_BYTE;
+        suites->suites[idx++] = TLS_RSA_WITH_AES_256_CBC_SHA;
+    }
+#endif
+
+#ifdef BUILD_TLS_RSA_WITH_AES_128_CBC_SHA
+    if (tls && haveRSA) {
+        suites->suites[idx++] = CIPHER_BYTE;
+        suites->suites[idx++] = TLS_RSA_WITH_AES_128_CBC_SHA;
+    }
+#endif
+
+#ifdef BUILD_TLS_ECDHE_ECDSA_WITH_CHACHA20_OLD_POLY1305_SHA256
+    if (tls1_2 && haveECC) {
+        suites->suites[idx++] = CHACHA_BYTE;
+        suites->suites[idx++] =
+                              TLS_ECDHE_ECDSA_WITH_CHACHA20_OLD_POLY1305_SHA256;
+    }
+#endif
+
+#ifdef BUILD_TLS_ECDHE_RSA_WITH_CHACHA20_OLD_POLY1305_SHA256
+    if (tls1_2 && haveRSA) {
+        suites->suites[idx++] = CHACHA_BYTE;
+        suites->suites[idx++] = TLS_ECDHE_RSA_WITH_CHACHA20_OLD_POLY1305_SHA256;
+    }
+#endif
+
+#ifdef BUILD_TLS_DHE_RSA_WITH_CHACHA20_OLD_POLY1305_SHA256
+    if (tls1_2 && haveRSA) {
+        suites->suites[idx++] = CHACHA_BYTE;
+        suites->suites[idx++] = TLS_DHE_RSA_WITH_CHACHA20_OLD_POLY1305_SHA256;
+    }
+#endif
+
+#ifdef BUILD_TLS_ECDHE_ECDSA_WITH_NULL_SHA
+    if (tls && haveECC) {
+        suites->suites[idx++] = ECC_BYTE;
+        suites->suites[idx++] = TLS_ECDHE_ECDSA_WITH_NULL_SHA;
+    }
+#endif
+
+#ifdef BUILD_TLS_RSA_WITH_NULL_MD5
+    if (tls && haveRSA) {
+        suites->suites[idx++] = CIPHER_BYTE;
+        suites->suites[idx++] = TLS_RSA_WITH_NULL_MD5;
+    }
+#endif
+
+#ifdef BUILD_TLS_RSA_WITH_NULL_SHA
+    if (tls && haveRSA) {
+        suites->suites[idx++] = CIPHER_BYTE;
+        suites->suites[idx++] = TLS_RSA_WITH_NULL_SHA;
+    }
+#endif
+
+#ifdef BUILD_TLS_RSA_WITH_NULL_SHA256
+#ifndef WOLFSSL_OLDTLS_SHA2_CIPHERSUITES
+    if (tls1_2 && haveRSA)
+#else
+    if (tls && haveRSA)
+#endif
+    {
+        suites->suites[idx++] = CIPHER_BYTE;
+        suites->suites[idx++] = TLS_RSA_WITH_NULL_SHA256;
+    }
+#endif
+
+#ifdef BUILD_TLS_PSK_WITH_AES_256_CBC_SHA
+    if (tls && havePSK) {
+        suites->suites[idx++] = CIPHER_BYTE;
+        suites->suites[idx++] = TLS_PSK_WITH_AES_256_CBC_SHA;
+    }
+#endif
+
+#ifdef BUILD_TLS_DHE_PSK_WITH_AES_256_CBC_SHA384
+#ifndef WOLFSSL_OLDTLS_SHA2_CIPHERSUITES
+    if (tls1_2 && haveDH && havePSK)
+#else
+    if (tls && haveDH && havePSK)
+#endif
+    {
+        suites->suites[idx++] = CIPHER_BYTE;
+        suites->suites[idx++] = TLS_DHE_PSK_WITH_AES_256_CBC_SHA384;
+    }
+#endif
+
+#ifdef BUILD_TLS_PSK_WITH_AES_256_CBC_SHA384
+#ifndef WOLFSSL_OLDTLS_SHA2_CIPHERSUITES
+    if (tls1_2 && havePSK)
+#else
+    if (tls && havePSK)
+#endif
+    {
+        suites->suites[idx++] = CIPHER_BYTE;
+        suites->suites[idx++] = TLS_PSK_WITH_AES_256_CBC_SHA384;
+    }
+#endif
+
+#ifdef BUILD_TLS_DHE_PSK_WITH_AES_128_CBC_SHA256
+#ifndef WOLFSSL_OLDTLS_SHA2_CIPHERSUITES
+    if (tls1_2 && haveDH && havePSK)
+#else
+    if (tls && haveDH && havePSK)
+#endif
+    {
+        suites->suites[idx++] = CIPHER_BYTE;
+        suites->suites[idx++] = TLS_DHE_PSK_WITH_AES_128_CBC_SHA256;
+    }
+#endif
+
+#ifdef BUILD_TLS_PSK_WITH_AES_128_CBC_SHA256
+#ifndef WOLFSSL_OLDTLS_SHA2_CIPHERSUITES
+    if (tls1_2 && havePSK)
+#else
+    if (tls1 && havePSK)
+#endif
+    {
+        suites->suites[idx++] = CIPHER_BYTE;
+        suites->suites[idx++] = TLS_PSK_WITH_AES_128_CBC_SHA256;
+    }
+#endif
+
+#ifdef BUILD_TLS_PSK_WITH_AES_128_CBC_SHA
+    if (tls && havePSK) {
+        suites->suites[idx++] = CIPHER_BYTE;
+        suites->suites[idx++] = TLS_PSK_WITH_AES_128_CBC_SHA;
+    }
+#endif
+
+#ifdef BUILD_TLS_DHE_PSK_WITH_AES_128_CCM
+    if (tls && haveDH && havePSK) {
+        suites->suites[idx++] = ECC_BYTE;
+        suites->suites[idx++] = TLS_DHE_PSK_WITH_AES_128_CCM;
+    }
+#endif
+
+#ifdef BUILD_TLS_DHE_PSK_WITH_AES_256_CCM
+    if (tls && haveDH && havePSK) {
+        suites->suites[idx++] = ECC_BYTE;
+        suites->suites[idx++] = TLS_DHE_PSK_WITH_AES_256_CCM;
+    }
+#endif
+
+#ifdef BUILD_TLS_PSK_WITH_CHACHA20_POLY1305_SHA256
+#ifndef WOLFSSL_OLDTLS_SHA2_CIPHERSUITES
+    if (tls1_2 && havePSK)
+#else
+    if (tls && havePSK)
+#endif
+    {
+        suites->suites[idx++] = CHACHA_BYTE;
+        suites->suites[idx++] = TLS_PSK_WITH_CHACHA20_POLY1305_SHA256;
+    }
+#endif
+
+#ifdef BUILD_TLS_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256
+#ifndef WOLFSSL_OLDTLS_SHA2_CIPHERSUITES
+    if (tls1_2 && havePSK)
+#else
+    if (tls && havePSK)
+#endif
+    {
+        suites->suites[idx++] = CHACHA_BYTE;
+        suites->suites[idx++] = TLS_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256;
+    }
+#endif
+
+#ifdef BUILD_TLS_DHE_PSK_WITH_CHACHA20_POLY1305_SHA256
+#ifndef WOLFSSL_OLDTLS_SHA2_CIPHERSUITES
+    if (tls1_2 && havePSK)
+#else
+    if (tls && havePSK)
+#endif
+    {
+        suites->suites[idx++] = CHACHA_BYTE;
+        suites->suites[idx++] = TLS_DHE_PSK_WITH_CHACHA20_POLY1305_SHA256;
+    }
+#endif
+
+#ifdef BUILD_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256
+#ifndef WOLFSSL_OLDTLS_SHA2_CIPHERSUITES
+    if (tls1_2 && havePSK)
+#else
+    if (tls && havePSK)
+#endif
+    {
+        suites->suites[idx++] = ECC_BYTE;
+        suites->suites[idx++] = TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256;
+    }
+#endif
+
+#ifdef BUILD_TLS_PSK_WITH_AES_128_CCM
+    if (tls && havePSK) {
+        suites->suites[idx++] = ECC_BYTE;
+        suites->suites[idx++] = TLS_PSK_WITH_AES_128_CCM;
+    }
+#endif
+
+#ifdef BUILD_TLS_PSK_WITH_AES_256_CCM
+    if (tls && havePSK) {
+        suites->suites[idx++] = ECC_BYTE;
+        suites->suites[idx++] = TLS_PSK_WITH_AES_256_CCM;
+    }
+#endif
+
+#ifdef BUILD_TLS_PSK_WITH_AES_128_CCM_8
+    if (tls && havePSK) {
+        suites->suites[idx++] = ECC_BYTE;
+        suites->suites[idx++] = TLS_PSK_WITH_AES_128_CCM_8;
+    }
+#endif
+
+#ifdef BUILD_TLS_PSK_WITH_AES_256_CCM_8
+    if (tls && havePSK) {
+        suites->suites[idx++] = ECC_BYTE;
+        suites->suites[idx++] = TLS_PSK_WITH_AES_256_CCM_8;
+    }
+#endif
+
+#ifdef BUILD_TLS_DHE_PSK_WITH_NULL_SHA384
+#ifndef WOLFSSL_OLDTLS_SHA2_CIPHERSUITES
+    if (tls1_2 && haveDH && havePSK)
+#else
+    if (tls && haveDH && havePSK)
+#endif
+    {
+        suites->suites[idx++] = CIPHER_BYTE;
+        suites->suites[idx++] = TLS_DHE_PSK_WITH_NULL_SHA384;
+    }
+#endif
+
+#ifdef BUILD_TLS_PSK_WITH_NULL_SHA384
+#ifndef WOLFSSL_OLDTLS_SHA2_CIPHERSUITES
+    if (tls1_2 && havePSK)
+#else
+    if (tls && havePSK)
+#endif
+    {
+        suites->suites[idx++] = CIPHER_BYTE;
+        suites->suites[idx++] = TLS_PSK_WITH_NULL_SHA384;
+    }
+#endif
+
+#ifdef BUILD_TLS_ECDHE_PSK_WITH_NULL_SHA256
+#ifndef WOLFSSL_OLDTLS_SHA2_CIPHERSUITES
+    if (tls1_2 && havePSK)
+#else
+    if (tls && havePSK)
+#endif
+    {
+        suites->suites[idx++] = ECC_BYTE;
+        suites->suites[idx++] = TLS_ECDHE_PSK_WITH_NULL_SHA256;
+    }
+#endif
+
+#ifdef BUILD_TLS_DHE_PSK_WITH_NULL_SHA256
+#ifndef WOLFSSL_OLDTLS_SHA2_CIPHERSUITES
+    if (tls1_2 && haveDH && havePSK)
+#else
+    if (tls && haveDH && havePSK)
+#endif
+    {
+        suites->suites[idx++] = CIPHER_BYTE;
+        suites->suites[idx++] = TLS_DHE_PSK_WITH_NULL_SHA256;
+    }
+#endif
+
+#ifdef BUILD_TLS_PSK_WITH_NULL_SHA256
+#ifndef WOLFSSL_OLDTLS_SHA2_CIPHERSUITES
+    if (tls1_2 && havePSK)
+#else
+    if (tls && havePSK)
+#endif
+    {
+        suites->suites[idx++] = CIPHER_BYTE;
+        suites->suites[idx++] = TLS_PSK_WITH_NULL_SHA256;
+    }
+#endif
+
+#ifdef BUILD_TLS_PSK_WITH_NULL_SHA
+    if (tls && havePSK) {
+        suites->suites[idx++] = CIPHER_BYTE;
+        suites->suites[idx++] = TLS_PSK_WITH_NULL_SHA;
+    }
+#endif
+
+#ifdef BUILD_SSL_RSA_WITH_RC4_128_SHA
+    if (!dtls && haveRSA) {
+        suites->suites[idx++] = CIPHER_BYTE;
+        suites->suites[idx++] = SSL_RSA_WITH_RC4_128_SHA;
+    }
+#endif
+
+#ifdef BUILD_SSL_RSA_WITH_RC4_128_MD5
+    if (!dtls && haveRSA) {
+        suites->suites[idx++] = CIPHER_BYTE;
+        suites->suites[idx++] = SSL_RSA_WITH_RC4_128_MD5;
+    }
+#endif
+
+#ifdef BUILD_SSL_RSA_WITH_3DES_EDE_CBC_SHA
+    if (haveRSA ) {
+        suites->suites[idx++] = CIPHER_BYTE;
+        suites->suites[idx++] = SSL_RSA_WITH_3DES_EDE_CBC_SHA;
+    }
+#endif
+
+#ifdef BUILD_TLS_RSA_WITH_HC_128_MD5
+    if (!dtls && tls && haveRSA) {
+        suites->suites[idx++] = CIPHER_BYTE;
+        suites->suites[idx++] = TLS_RSA_WITH_HC_128_MD5;
+    }
+#endif
+
+#ifdef BUILD_TLS_RSA_WITH_HC_128_SHA
+    if (!dtls && tls && haveRSA) {
+        suites->suites[idx++] = CIPHER_BYTE;
+        suites->suites[idx++] = TLS_RSA_WITH_HC_128_SHA;
+    }
+#endif
+
+#ifdef BUILD_TLS_RSA_WITH_RABBIT_SHA
+    if (!dtls && tls && haveRSA) {
+        suites->suites[idx++] = CIPHER_BYTE;
+        suites->suites[idx++] = TLS_RSA_WITH_RABBIT_SHA;
+    }
+#endif
+
+#ifdef BUILD_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA
+    if (tls && haveRSA) {
+        suites->suites[idx++] = CIPHER_BYTE;
+        suites->suites[idx++] = TLS_RSA_WITH_CAMELLIA_128_CBC_SHA;
+    }
+#endif
+
+#ifdef BUILD_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA
+    if (tls && haveDH && haveRSA) {
+        suites->suites[idx++] = CIPHER_BYTE;
+        suites->suites[idx++] = TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA;
+    }
+#endif
+
+#ifdef BUILD_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA
+    if (tls && haveRSA) {
+        suites->suites[idx++] = CIPHER_BYTE;
+        suites->suites[idx++] = TLS_RSA_WITH_CAMELLIA_256_CBC_SHA;
+    }
+#endif
+
+#ifdef BUILD_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA
+    if (tls && haveDH && haveRSA) {
+        suites->suites[idx++] = CIPHER_BYTE;
+        suites->suites[idx++] = TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA;
+    }
+#endif
+
+#ifdef BUILD_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256
+#ifndef WOLFSSL_OLDTLS_SHA2_CIPHERSUITES
+    if (tls1_2 && haveRSA)
+#else
+    if (tls && haveRSA)
+#endif
+    {
+        suites->suites[idx++] = CIPHER_BYTE;
+        suites->suites[idx++] = TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256;
+    }
+#endif
+
+#ifdef BUILD_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256
+#ifndef WOLFSSL_OLDTLS_SHA2_CIPHERSUITES
+    if (tls1_2 && haveDH && haveRSA)
+#else
+    if (tls && haveDH && haveRSA)
+#endif
+    {
+        suites->suites[idx++] = CIPHER_BYTE;
+        suites->suites[idx++] = TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256;
+    }
+#endif
+
+#ifdef BUILD_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256
+#ifndef WOLFSSL_OLDTLS_SHA2_CIPHERSUITES
+    if (tls1_2 && haveRSA)
+#else
+    if (tls && haveRSA)
+#endif
+    {
+        suites->suites[idx++] = CIPHER_BYTE;
+        suites->suites[idx++] = TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256;
+    }
+#endif
+
+#ifdef BUILD_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256
+#ifndef WOLFSSL_OLDTLS_SHA2_CIPHERSUITES
+    if (tls1_2 && haveDH && haveRSA)
+#else
+    if (tls && haveDH && haveRSA)
+#endif
+    {
+        suites->suites[idx++] = CIPHER_BYTE;
+        suites->suites[idx++] = TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256;
+    }
+#endif
+
+#ifdef BUILD_SSL_RSA_WITH_IDEA_CBC_SHA
+    if (haveRSA) {
+        suites->suites[idx++] = CIPHER_BYTE;
+        suites->suites[idx++] = SSL_RSA_WITH_IDEA_CBC_SHA;
+    }
+#endif
+
+#endif /* !WOLFSSL_NO_TLS12 */
+
+    suites->suiteSz = idx;
+
+    InitSuitesHashSigAlgo(suites, haveECDSAsig | haveECC, haveRSAsig | haveRSA,
+                                                              0, tls1_2, keySz);
+}
+
+#if !defined(NO_WOLFSSL_SERVER) || !defined(NO_CERTS) || \
+    (!defined(NO_WOLFSSL_CLIENT) && (!defined(NO_DH) || defined(HAVE_ECC)))
+
+/* Decode the signature algorithm.
+ *
+ * input     The encoded signature algorithm.
+ * hashalgo  The hash algorithm.
+ * hsType    The signature type.
+ */
+static WC_INLINE void DecodeSigAlg(const byte* input, byte* hashAlgo, byte* hsType)
+{
+    switch (input[0]) {
+        case NEW_SA_MAJOR:
+    #ifdef HAVE_ED25519
+            /* ED25519: 0x0807 */
+            if (input[1] == ED25519_SA_MINOR) {
+                *hsType = ed25519_sa_algo;
+                /* Hash performed as part of sign/verify operation. */
+                *hashAlgo = sha512_mac;
+            }
+            else
+    #endif
+    #ifdef HAVE_ED448
+            /* ED448: 0x0808 */
+            if (input[1] == ED448_SA_MINOR) {
+                *hsType = ed448_sa_algo;
+                /* Hash performed as part of sign/verify operation. */
+                *hashAlgo = sha512_mac;
+            }
+            else
+    #endif
+    #ifdef WC_RSA_PSS
+            /* PSS PSS signatures: 0x080[9-b] */
+            if (input[1] >= pss_sha256 && input[1] <= pss_sha512) {
+                *hsType   = rsa_pss_pss_algo;
+                *hashAlgo = PSS_PSS_HASH_TO_MAC(input[1]);
+            }
+            else
+    #endif
+            {
+                *hsType   = input[0];
+                *hashAlgo = input[1];
+            }
+            break;
+        default:
+            *hashAlgo = input[0];
+            *hsType   = input[1];
+            break;
+    }
+}
+#endif /* !NO_WOLFSSL_SERVER || !NO_CERTS */
+
+#ifndef WOLFSSL_NO_TLS12
+#if !defined(NO_WOLFSSL_SERVER) || !defined(NO_WOLFSSL_CLIENT)
+#if !defined(NO_DH) || defined(HAVE_ECC) || defined(HAVE_CURVE25519) || \
+             defined(HAVE_CURVE448) || (!defined(NO_RSA) && defined(WC_RSA_PSS))
+
+static enum wc_HashType HashAlgoToType(int hashAlgo)
+{
+    switch (hashAlgo) {
+    #ifdef WOLFSSL_SHA512
+        case sha512_mac:
+            return WC_HASH_TYPE_SHA512;
+    #endif
+    #ifdef WOLFSSL_SHA384
+        case sha384_mac:
+            return WC_HASH_TYPE_SHA384;
+    #endif
+    #ifndef NO_SHA256
+        case sha256_mac:
+            return WC_HASH_TYPE_SHA256;
+    #endif
+    #ifdef WOLFSSL_SHA224
+        case sha224_mac:
+            return WC_HASH_TYPE_SHA224;
+    #endif
+    #if !defined(NO_SHA) && (!defined(NO_OLD_TLS) || \
+                             defined(WOLFSSL_ALLOW_TLS_SHA1))
+        case sha_mac:
+            return WC_HASH_TYPE_SHA;
+    #endif
+        default:
+            WOLFSSL_MSG("Bad hash sig algo");
+            break;
+    }
+
+    return WC_HASH_TYPE_NONE;
+}
+#endif /* !NO_DH || HAVE_ECC || (!NO_RSA && WC_RSA_PSS) */
+#endif /* !NO_WOLFSSL_SERVER || !NO_WOLFSSL_CLIENT */
+#endif /* !WOLFSSL_NO_TLS12 */
+
+#ifndef NO_CERTS
+
+void InitX509Name(WOLFSSL_X509_NAME* name, int dynamicFlag)
+{
+    (void)dynamicFlag;
+
+    if (name != NULL) {
+        name->name        = name->staticName;
+        name->dynamicName = 0;
+        name->sz = 0;
+#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
+        XMEMSET(&name->fullName, 0, sizeof(DecodedName));
+        XMEMSET(&name->cnEntry,  0, sizeof(WOLFSSL_X509_NAME_ENTRY));
+        XMEMSET(&name->extra,    0, sizeof(name->extra));
+        name->cnEntry.value = &(name->cnEntry.data); /* point to internal data*/
+        name->cnEntry.nid = ASN_COMMON_NAME;
+        name->x509 = NULL;
+#endif /* OPENSSL_EXTRA */
+    }
+}
+
+
+void FreeX509Name(WOLFSSL_X509_NAME* name, void* heap)
+{
+    if (name != NULL) {
+        if (name->dynamicName) {
+            XFREE(name->name, heap, DYNAMIC_TYPE_SUBJECT_CN);
+            name->name = NULL;
+        }
+#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
+        {
+            int i;
+            if (name->fullName.fullName != NULL) {
+                XFREE(name->fullName.fullName, heap, DYNAMIC_TYPE_X509);
+                name->fullName.fullName = NULL;
+            }
+            for (i = 0; i < MAX_NAME_ENTRIES; i++) {
+                /* free ASN1 string data */
+                if (name->extra[i].set && name->extra[i].data.data != NULL) {
+                    XFREE(name->extra[i].data.data, heap, DYNAMIC_TYPE_OPENSSL);
+                }
+            }
+            wolfSSL_ASN1_OBJECT_free(&name->cnEntry.object);
+        }
+#endif /* OPENSSL_EXTRA || OPENSSL_EXTRA_X509_SMALL */
+    }
+    (void)heap;
+}
+
+
+/* Initialize wolfSSL X509 type */
+void InitX509(WOLFSSL_X509* x509, int dynamicFlag, void* heap)
+{
+    if (x509 == NULL) {
+        WOLFSSL_MSG("Null parameter passed in!");
+        return;
+    }
+
+    XMEMSET(x509, 0, sizeof(WOLFSSL_X509));
+
+    x509->heap = heap;
+    InitX509Name(&x509->issuer, 0);
+    InitX509Name(&x509->subject, 0);
+    x509->dynamicMemory  = (byte)dynamicFlag;
+    #if defined(OPENSSL_EXTRA) || defined(OPENSSL_ALL)
+        x509->refCount = 1;
+        (void)wc_InitMutex(&x509->refMutex);
+    #endif
+}
+
+
+/* Free wolfSSL X509 type */
+void FreeX509(WOLFSSL_X509* x509)
+{
+    if (x509 == NULL)
+        return;
+
+    FreeX509Name(&x509->issuer, x509->heap);
+    FreeX509Name(&x509->subject, x509->heap);
+    if (x509->pubKey.buffer) {
+        XFREE(x509->pubKey.buffer, x509->heap, DYNAMIC_TYPE_PUBLIC_KEY);
+        x509->pubKey.buffer = NULL;
+    }
+    FreeDer(&x509->derCert);
+    XFREE(x509->sig.buffer, x509->heap, DYNAMIC_TYPE_SIGNATURE);
+    x509->sig.buffer = NULL;
+    #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
+        XFREE(x509->authKeyId, x509->heap, DYNAMIC_TYPE_X509_EXT);
+        x509->authKeyId = NULL;
+        XFREE(x509->subjKeyId, x509->heap, DYNAMIC_TYPE_X509_EXT);
+        x509->subjKeyId = NULL;
+        if (x509->authInfo != NULL) {
+            XFREE(x509->authInfo, x509->heap, DYNAMIC_TYPE_X509_EXT);
+            x509->authInfo = NULL;
+        }
+        #if defined(OPENSSL_ALL) || defined(WOLFSSL_QT)
+        if (x509->authInfoCaIssuer != NULL) {
+            XFREE(x509->authInfoCaIssuer, x509->heap, DYNAMIC_TYPE_X509_EXT);
+        }
+        if (x509->ext_sk != NULL) {
+            wolfSSL_sk_X509_EXTENSION_free(x509->ext_sk);
+        }
+        #endif /* OPENSSL_ALL || WOLFSSL_QT */
+        #ifdef OPENSSL_EXTRA
+        /* Free serialNumber that was set by wolfSSL_X509_get_serialNumber */
+        if (x509->serialNumber != NULL) {
+            wolfSSL_ASN1_INTEGER_free(x509->serialNumber);
+        }
+        #endif
+        if (x509->extKeyUsageSrc != NULL) {
+            XFREE(x509->extKeyUsageSrc, x509->heap, DYNAMIC_TYPE_X509_EXT);
+            x509->extKeyUsageSrc= NULL;
+        }
+    #endif /* OPENSSL_EXTRA || OPENSSL_EXTRA_X509_SMALL */
+    #if defined(OPENSSL_ALL)
+        if (x509->algor.algorithm) {
+            wolfSSL_ASN1_OBJECT_free(x509->algor.algorithm);
+            x509->algor.algorithm = NULL;
+        }
+        if (x509->key.algor) {
+            wolfSSL_X509_ALGOR_free(x509->key.algor);
+            x509->key.algor = NULL;
+        }
+        if (x509->key.pkey) {
+            wolfSSL_EVP_PKEY_free(x509->key.pkey);
+            x509->key.pkey = NULL;
+        }
+    #endif /* OPENSSL_ALL */
+    if (x509->altNames) {
+        FreeAltNames(x509->altNames, x509->heap);
+        x509->altNames = NULL;
+    }
+
+    #if defined(OPENSSL_EXTRA) || defined(OPENSSL_ALL)
+        wc_FreeMutex(&x509->refMutex);
+    #endif
+}
+
+
+#if !defined(NO_WOLFSSL_SERVER) || !defined(NO_WOLFSSL_CLIENT)
+#if !defined(WOLFSSL_NO_TLS12)
+/* Encode the signature algorithm into buffer.
+ *
+ * hashalgo  The hash algorithm.
+ * hsType   The signature type.
+ * output    The buffer to encode into.
+ */
+static WC_INLINE void EncodeSigAlg(byte hashAlgo, byte hsType, byte* output)
+{
+    switch (hsType) {
+#ifdef HAVE_ECC
+        case ecc_dsa_sa_algo:
+            output[0] = hashAlgo;
+            output[1] = ecc_dsa_sa_algo;
+            break;
+#endif
+#ifdef HAVE_ED25519
+        case ed25519_sa_algo:
+            output[0] = ED25519_SA_MAJOR;
+            output[1] = ED25519_SA_MINOR;
+            (void)hashAlgo;
+            break;
+#endif
+#ifdef HAVE_ED448
+        case ed448_sa_algo:
+            output[0] = ED448_SA_MAJOR;
+            output[1] = ED448_SA_MINOR;
+            (void)hashAlgo;
+            break;
+#endif
+#ifndef NO_RSA
+        case rsa_sa_algo:
+            output[0] = hashAlgo;
+            output[1] = rsa_sa_algo;
+            break;
+    #ifdef WC_RSA_PSS
+        /* PSS signatures: 0x080[4-6] */
+        case rsa_pss_sa_algo:
+            output[0] = rsa_pss_sa_algo;
+            output[1] = hashAlgo;
+            break;
+    #endif
+#endif
+    }
+    (void)hashAlgo;
+    (void)output;
+}
+#endif
+
+#if !defined(WOLFSSL_NO_TLS12) && !defined(WOLFSSL_NO_CLIENT_AUTH)
+static void SetDigest(WOLFSSL* ssl, int hashAlgo)
+{
+    switch (hashAlgo) {
+    #ifndef NO_SHA
+        case sha_mac:
+            ssl->buffers.digest.buffer = ssl->hsHashes->certHashes.sha;
+            ssl->buffers.digest.length = WC_SHA_DIGEST_SIZE;
+            break;
+    #endif /* !NO_SHA */
+    #ifndef NO_SHA256
+        case sha256_mac:
+            ssl->buffers.digest.buffer = ssl->hsHashes->certHashes.sha256;
+            ssl->buffers.digest.length = WC_SHA256_DIGEST_SIZE;
+            break;
+    #endif /* !NO_SHA256 */
+    #ifdef WOLFSSL_SHA384
+        case sha384_mac:
+            ssl->buffers.digest.buffer = ssl->hsHashes->certHashes.sha384;
+            ssl->buffers.digest.length = WC_SHA384_DIGEST_SIZE;
+            break;
+    #endif /* WOLFSSL_SHA384 */
+    #ifdef WOLFSSL_SHA512
+        case sha512_mac:
+            ssl->buffers.digest.buffer = ssl->hsHashes->certHashes.sha512;
+            ssl->buffers.digest.length = WC_SHA512_DIGEST_SIZE;
+            break;
+    #endif /* WOLFSSL_SHA512 */
+    } /* switch */
+}
+#endif /* !WOLFSSL_NO_TLS12 && !WOLFSSL_NO_CLIENT_AUTH */
+#endif /* !NO_WOLFSSL_SERVER || !NO_WOLFSSL_CLIENT */
+#endif /* !NO_CERTS */
+
+#if defined(HAVE_ENCRYPT_THEN_MAC) && !defined(WOLFSSL_AEAD_ONLY)
+static word32 MacSize(WOLFSSL* ssl)
+{
+#ifdef HAVE_TRUNCATED_HMAC
+    word32 digestSz = ssl->truncated_hmac ? (byte)TRUNCATED_HMAC_SZ
+                                          : ssl->specs.hash_size;
+#else
+    word32 digestSz = ssl->specs.hash_size;
+#endif
+
+    return digestSz;
+}
+#endif /* HAVE_ENCRYPT_THEN_MAC && !WOLFSSL_AEAD_ONLY */
+
+#ifndef NO_RSA
+#ifndef WOLFSSL_NO_TLS12
+#if !defined(NO_WOLFSSL_SERVER) || (!defined(NO_WOLFSSL_CLIENT) && \
+                                               !defined(WOLFSSL_NO_CLIENT_AUTH))
+static int TypeHash(int hashAlgo)
+{
+    switch (hashAlgo) {
+    #ifdef WOLFSSL_SHA512
+        case sha512_mac:
+            return SHA512h;
+    #endif
+    #ifdef WOLFSSL_SHA384
+        case sha384_mac:
+            return SHA384h;
+    #endif
+    #ifndef NO_SHA256
+        case sha256_mac:
+            return SHA256h;
+    #endif
+    #ifdef WOLFSSL_SHA224
+        case sha224_mac:
+            return SHA224h;
+    #endif
+    #ifndef NO_SHA
+        case sha_mac:
+            return SHAh;
+    #endif
+    }
+
+    return 0;
+}
+#endif /* !NO_WOLFSSL_SERVER && !NO_WOLFSSL_CLIENT */
+#endif /* !WOLFSSL_NO_TLS12 */
+
+#if defined(WC_RSA_PSS)
+int ConvertHashPss(int hashAlgo, enum wc_HashType* hashType, int* mgf)
+{
+    switch (hashAlgo) {
+        #ifdef WOLFSSL_SHA512
+        case sha512_mac:
+            *hashType = WC_HASH_TYPE_SHA512;
+            if (mgf != NULL)
+                *mgf = WC_MGF1SHA512;
+            break;
+        #endif
+        #ifdef WOLFSSL_SHA384
+        case sha384_mac:
+            *hashType = WC_HASH_TYPE_SHA384;
+            if (mgf != NULL)
+                *mgf = WC_MGF1SHA384;
+            break;
+        #endif
+        #ifndef NO_SHA256
+        case sha256_mac:
+            *hashType = WC_HASH_TYPE_SHA256;
+            if (mgf != NULL)
+                *mgf = WC_MGF1SHA256;
+            break;
+        #endif
+        default:
+            return BAD_FUNC_ARG;
+    }
+
+    return 0;
+}
+#endif
+
+#if !defined(NO_WOLFSSL_SERVER) || !defined(WOLFSSL_NO_CLIENT_AUTH)
+int RsaSign(WOLFSSL* ssl, const byte* in, word32 inSz, byte* out,
+            word32* outSz, int sigAlgo, int hashAlgo, RsaKey* key,
+            DerBuffer* keyBufInfo)
+{
+    int ret;
+#ifdef HAVE_PK_CALLBACKS
+    const byte* keyBuf = NULL;
+    word32 keySz = 0;
+
+    if (keyBufInfo) {
+        keyBuf = keyBufInfo->buffer;
+        keySz = keyBufInfo->length;
+    }
+#endif
+
+    (void)ssl;
+    (void)keyBufInfo;
+    (void)sigAlgo;
+    (void)hashAlgo;
+
+    WOLFSSL_ENTER("RsaSign");
+
+#ifdef WOLFSSL_ASYNC_CRYPT
+    /* initialize event */
+    if (key) {
+        ret = wolfSSL_AsyncInit(ssl, &key->asyncDev, WC_ASYNC_FLAG_CALL_AGAIN);
+        if (ret != 0)
+            return ret;
+    }
+#endif
+
+#if defined(WC_RSA_PSS)
+    if (sigAlgo == rsa_pss_sa_algo) {
+        enum wc_HashType hashType = WC_HASH_TYPE_NONE;
+        int mgf = 0;
+
+        ret = ConvertHashPss(hashAlgo, &hashType, &mgf);
+        if (ret != 0)
+            return ret;
+
+    #if defined(HAVE_PK_CALLBACKS)
+        if (ssl->ctx->RsaPssSignCb) {
+            void* ctx = wolfSSL_GetRsaPssSignCtx(ssl);
+            ret = ssl->ctx->RsaPssSignCb(ssl, in, inSz, out, outSz,
+                                         TypeHash(hashAlgo), mgf,
+                                         keyBuf, keySz, ctx);
+        }
+        else
+    #endif
+        {
+            ret = wc_RsaPSS_Sign(in, inSz, out, *outSz, hashType, mgf, key,
+                                                                      ssl->rng);
+        }
+    }
+    else
+#endif
+#if defined(HAVE_PK_CALLBACKS)
+    if (ssl->ctx->RsaSignCb) {
+        void* ctx = wolfSSL_GetRsaSignCtx(ssl);
+        ret = ssl->ctx->RsaSignCb(ssl, in, inSz, out, outSz, keyBuf, keySz,
+                                                                          ctx);
+    }
+    else
+#endif /*HAVE_PK_CALLBACKS */
+        ret = wc_RsaSSL_Sign(in, inSz, out, *outSz, key, ssl->rng);
+
+    /* Handle async pending response */
+#ifdef WOLFSSL_ASYNC_CRYPT
+    if (key && ret == WC_PENDING_E) {
+        ret = wolfSSL_AsyncPush(ssl, &key->asyncDev);
+    }
+#endif /* WOLFSSL_ASYNC_CRYPT */
+
+    /* For positive response return in outSz */
+    if (ret > 0) {
+        *outSz = ret;
+        ret = 0;
+    }
+
+    WOLFSSL_LEAVE("RsaSign", ret);
+
+    return ret;
+}
+#endif
+
+int RsaVerify(WOLFSSL* ssl, byte* in, word32 inSz, byte** out, int sigAlgo,
+              int hashAlgo, RsaKey* key, buffer* keyBufInfo)
+{
+    int ret;
+#ifdef HAVE_PK_CALLBACKS
+    const byte* keyBuf = NULL;
+    word32 keySz = 0;
+
+    if (keyBufInfo) {
+        keyBuf = keyBufInfo->buffer;
+        keySz = keyBufInfo->length;
+    }
+#endif
+
+    (void)ssl;
+    (void)keyBufInfo;
+    (void)sigAlgo;
+    (void)hashAlgo;
+
+    WOLFSSL_ENTER("RsaVerify");
+
+#ifdef WOLFSSL_ASYNC_CRYPT
+    /* initialize event */
+    ret = wolfSSL_AsyncInit(ssl, &key->asyncDev, WC_ASYNC_FLAG_CALL_AGAIN);
+    if (ret != 0)
+        return ret;
+#endif
+
+#if defined(WC_RSA_PSS)
+    if (sigAlgo == rsa_pss_sa_algo) {
+        enum wc_HashType hashType = WC_HASH_TYPE_NONE;
+        int mgf = 0;
+
+        ret = ConvertHashPss(hashAlgo, &hashType, &mgf);
+        if (ret != 0)
+            return ret;
+#ifdef HAVE_PK_CALLBACKS
+        if (ssl->ctx->RsaPssVerifyCb) {
+            void* ctx = wolfSSL_GetRsaPssVerifyCtx(ssl);
+            ret = ssl->ctx->RsaPssVerifyCb(ssl, in, inSz, out,
+                                           TypeHash(hashAlgo), mgf,
+                                           keyBuf, keySz, ctx);
+        }
+        else
+#endif /*HAVE_PK_CALLBACKS */
+            ret = wc_RsaPSS_VerifyInline(in, inSz, out, hashType, mgf, key);
+    }
+    else
+#endif
+#ifdef HAVE_PK_CALLBACKS
+    if (ssl->ctx->RsaVerifyCb) {
+        void* ctx = wolfSSL_GetRsaVerifyCtx(ssl);
+        ret = ssl->ctx->RsaVerifyCb(ssl, in, inSz, out, keyBuf, keySz, ctx);
+    }
+    else
+#endif /*HAVE_PK_CALLBACKS */
+    {
+        ret = wc_RsaSSL_VerifyInline(in, inSz, out, key);
+    }
+
+    /* Handle async pending response */
+#ifdef WOLFSSL_ASYNC_CRYPT
+    if (ret == WC_PENDING_E) {
+        ret = wolfSSL_AsyncPush(ssl, &key->asyncDev);
+    }
+#endif /* WOLFSSL_ASYNC_CRYPT */
+
+    WOLFSSL_LEAVE("RsaVerify", ret);
+
+    return ret;
+}
+
+/* Verify RSA signature, 0 on success */
+/* This function is used to check the sign result */
+int VerifyRsaSign(WOLFSSL* ssl, byte* verifySig, word32 sigSz,
+    const byte* plain, word32 plainSz, int sigAlgo, int hashAlgo, RsaKey* key,
+    DerBuffer* keyBufInfo)
+{
+    byte* out = NULL;  /* inline result */
+    int   ret;
+#ifdef HAVE_PK_CALLBACKS
+    const byte* keyBuf = NULL;
+    word32 keySz = 0;
+
+    if (keyBufInfo) {
+        keyBuf = keyBufInfo->buffer;
+        keySz = keyBufInfo->length;
+    }
+#endif
+
+    (void)ssl;
+    (void)keyBufInfo;
+    (void)sigAlgo;
+    (void)hashAlgo;
+
+    WOLFSSL_ENTER("VerifyRsaSign");
+
+    if (verifySig == NULL || plain == NULL) {
+        return BAD_FUNC_ARG;
+    }
+
+    if (sigSz > ENCRYPT_LEN) {
+        WOLFSSL_MSG("Signature buffer too big");
+        return BUFFER_E;
+    }
+
+#ifdef WOLFSSL_ASYNC_CRYPT
+    /* initialize event */
+    if (key) {
+        ret = wolfSSL_AsyncInit(ssl, &key->asyncDev, WC_ASYNC_FLAG_CALL_AGAIN);
+        if (ret != 0)
+            return ret;
+    }
+#endif
+
+#if defined(WC_RSA_PSS)
+    if (sigAlgo == rsa_pss_sa_algo) {
+        enum wc_HashType hashType = WC_HASH_TYPE_NONE;
+        int mgf = 0;
+
+        ret = ConvertHashPss(hashAlgo, &hashType, &mgf);
+        if (ret != 0)
+            return ret;
+    #ifdef HAVE_PK_CALLBACKS
+        if (ssl->ctx->RsaPssSignCheckCb) {
+            /* The key buffer includes private/public portion,
+                but only public is used */
+            /* If HSM hardware is checking the signature result you can
+                optionally skip the sign check and return 0 */
+            /* The ctx here is the RsaSignCtx set using wolfSSL_SetRsaSignCtx */
+            void* ctx = wolfSSL_GetRsaPssSignCtx(ssl);
+            ret = ssl->ctx->RsaPssSignCheckCb(ssl, verifySig, sigSz, &out,
+                                           TypeHash(hashAlgo), mgf,
+                                           keyBuf, keySz, ctx);
+            if (ret > 0) {
+                ret = wc_RsaPSS_CheckPadding(plain, plainSz, out, ret,
+                                             hashType);
+                if (ret != 0)
+                    ret = VERIFY_CERT_ERROR;
+            }
+        }
+        else
+    #endif /* HAVE_PK_CALLBACKS */
+        {
+            ret = wc_RsaPSS_VerifyInline(verifySig, sigSz, &out, hashType, mgf,
+                                         key);
+            if (ret > 0) {
+    #ifdef HAVE_SELFTEST
+                ret = wc_RsaPSS_CheckPadding(plain, plainSz, out, ret,
+                                             hashType);
+    #else
+                ret = wc_RsaPSS_CheckPadding_ex(plain, plainSz, out, ret,
+                                                hashType, -1,
+                                                mp_count_bits(&key->n));
+    #endif
+                if (ret != 0)
+                    ret = VERIFY_CERT_ERROR;
+            }
+        }
+
+    }
+    else
+#endif /* WC_RSA_PSS */
+    {
+    #ifdef HAVE_PK_CALLBACKS
+        if (ssl->ctx->RsaSignCheckCb) {
+            /* The key buffer includes private/public portion,
+                but only public is used */
+            /* If HSM hardware is checking the signature result you can
+                optionally skip the sign check and return 0 */
+            /* The ctx here is the RsaSignCtx set using wolfSSL_SetRsaSignCtx */
+            void* ctx = wolfSSL_GetRsaSignCtx(ssl);
+            ret = ssl->ctx->RsaSignCheckCb(ssl, verifySig, sigSz, &out,
+                keyBuf, keySz, ctx);
+        }
+        else
+    #endif /* HAVE_PK_CALLBACKS */
+        {
+            ret = wc_RsaSSL_VerifyInline(verifySig, sigSz, &out, key);
+        }
+
+        if (ret > 0) {
+            if (ret != (int)plainSz || !out ||
+                                            XMEMCMP(plain, out, plainSz) != 0) {
+                WOLFSSL_MSG("RSA Signature verification failed");
+                ret = RSA_SIGN_FAULT;
+            } else {
+                ret = 0;  /* RSA reset */
+            }
+        }
+    }
+
+    /* Handle async pending response */
+#ifdef WOLFSSL_ASYNC_CRYPT
+    if (key && ret == WC_PENDING_E) {
+        ret = wolfSSL_AsyncPush(ssl, &key->asyncDev);
+    }
+#endif /* WOLFSSL_ASYNC_CRYPT */
+
+    WOLFSSL_LEAVE("VerifyRsaSign", ret);
+
+    return ret;
+}
+
+#ifndef WOLFSSL_NO_TLS12
+
+#if !defined(NO_WOLFSSL_SERVER) || !defined(WOLFSSL_NO_CLIENT_AUTH)
+int RsaDec(WOLFSSL* ssl, byte* in, word32 inSz, byte** out, word32* outSz,
+    RsaKey* key, DerBuffer* keyBufInfo)
+{
+    int ret;
+#ifdef HAVE_PK_CALLBACKS
+    const byte* keyBuf = NULL;
+    word32 keySz = 0;
+
+    if (keyBufInfo) {
+        keyBuf = keyBufInfo->buffer;
+        keySz = keyBufInfo->length;
+    }
+#endif
+
+    (void)ssl;
+    (void)keyBufInfo;
+
+    WOLFSSL_ENTER("RsaDec");
+
+#ifdef WOLFSSL_ASYNC_CRYPT
+    /* initialize event */
+    ret = wolfSSL_AsyncInit(ssl, &key->asyncDev, WC_ASYNC_FLAG_CALL_AGAIN);
+    if (ret != 0)
+        return ret;
+#endif
+
+#ifdef HAVE_PK_CALLBACKS
+    if (ssl->ctx->RsaDecCb) {
+        void* ctx = wolfSSL_GetRsaDecCtx(ssl);
+        ret = ssl->ctx->RsaDecCb(ssl, in, inSz, out, keyBuf, keySz, ctx);
+    }
+    else
+#endif /* HAVE_PK_CALLBACKS */
+    {
+        #ifdef WC_RSA_BLINDING
+            ret = wc_RsaSetRNG(key, ssl->rng);
+            if (ret != 0)
+                return ret;
+        #endif
+        ret = wc_RsaPrivateDecryptInline(in, inSz, out, key);
+    }
+
+    /* Handle async pending response */
+#ifdef WOLFSSL_ASYNC_CRYPT
+    if (ret == WC_PENDING_E) {
+        ret = wolfSSL_AsyncPush(ssl, &key->asyncDev);
+    }
+#endif /* WOLFSSL_ASYNC_CRYPT */
+
+    /* For positive response return in outSz */
+    if (ret > 0) {
+        *outSz = ret;
+        ret = 0;
+    }
+
+    WOLFSSL_LEAVE("RsaDec", ret);
+
+    return ret;
+}
+#endif /* !NO_WOLFSSL_SERVER) || !WOLFSSL_NO_CLIENT_AUTH */
+
+int RsaEnc(WOLFSSL* ssl, const byte* in, word32 inSz, byte* out, word32* outSz,
+    RsaKey* key, buffer* keyBufInfo)
+{
+    int ret;
+#ifdef HAVE_PK_CALLBACKS
+    const byte* keyBuf = NULL;
+    word32 keySz = 0;
+
+    if (keyBufInfo) {
+        keyBuf = keyBufInfo->buffer;
+        keySz = keyBufInfo->length;
+    }
+#endif
+
+    (void)ssl;
+    (void)keyBufInfo;
+
+    WOLFSSL_ENTER("RsaEnc");
+
+#ifdef WOLFSSL_ASYNC_CRYPT
+    /* initialize event */
+    ret = wolfSSL_AsyncInit(ssl, &key->asyncDev, WC_ASYNC_FLAG_CALL_AGAIN);
+    if (ret != 0)
+        return ret;
+#endif
+
+#ifdef HAVE_PK_CALLBACKS
+    if (ssl->ctx->RsaEncCb) {
+        void* ctx = wolfSSL_GetRsaEncCtx(ssl);
+        ret = ssl->ctx->RsaEncCb(ssl, in, inSz, out, outSz, keyBuf, keySz, ctx);
+    }
+    else
+#endif /* HAVE_PK_CALLBACKS */
+    {
+        ret = wc_RsaPublicEncrypt(in, inSz, out, *outSz, key, ssl->rng);
+    }
+
+    /* Handle async pending response */
+#ifdef WOLFSSL_ASYNC_CRYPT
+    if (ret == WC_PENDING_E) {
+        ret = wolfSSL_AsyncPush(ssl, &key->asyncDev);
+    }
+#endif /* WOLFSSL_ASYNC_CRYPT */
+
+    /* For positive response return in outSz */
+    if (ret > 0) {
+        *outSz = ret;
+        ret = 0;
+    }
+
+    WOLFSSL_LEAVE("RsaEnc", ret);
+
+    return ret;
+}
+
+#endif /* !WOLFSSL_NO_TLS12 */
+
+#endif /* NO_RSA */
+
+#ifdef HAVE_ECC
+
+int EccSign(WOLFSSL* ssl, const byte* in, word32 inSz, byte* out,
+    word32* outSz, ecc_key* key, DerBuffer* keyBufInfo)
+{
+    int ret;
+#ifdef HAVE_PK_CALLBACKS
+    const byte* keyBuf = NULL;
+    word32 keySz = 0;
+
+    if (keyBufInfo) {
+        keyBuf = keyBufInfo->buffer;
+        keySz = keyBufInfo->length;
+    }
+#endif
+
+    (void)ssl;
+    (void)keyBufInfo;
+
+    WOLFSSL_ENTER("EccSign");
+
+#ifdef WOLFSSL_ASYNC_CRYPT
+    /* initialize event */
+    if (key) {
+        ret = wolfSSL_AsyncInit(ssl, &key->asyncDev, WC_ASYNC_FLAG_CALL_AGAIN);
+        if (ret != 0)
+            return ret;
+    }
+#endif
+
+#if defined(HAVE_PK_CALLBACKS)
+    if (ssl->ctx->EccSignCb) {
+        void* ctx = wolfSSL_GetEccSignCtx(ssl);
+        ret = ssl->ctx->EccSignCb(ssl, in, inSz, out, outSz, keyBuf,
+            keySz, ctx);
+    }
+    else
+#endif /* HAVE_PK_CALLBACKS */
+    {
+        ret = wc_ecc_sign_hash(in, inSz, out, outSz, ssl->rng, key);
+    }
+
+    /* Handle async pending response */
+#ifdef WOLFSSL_ASYNC_CRYPT
+    if (key && ret == WC_PENDING_E) {
+        ret = wolfSSL_AsyncPush(ssl, &key->asyncDev);
+    }
+#endif /* WOLFSSL_ASYNC_CRYPT */
+
+    WOLFSSL_LEAVE("EccSign", ret);
+
+    return ret;
+}
+
+int EccVerify(WOLFSSL* ssl, const byte* in, word32 inSz, const byte* out,
+    word32 outSz, ecc_key* key, buffer* keyBufInfo)
+{
+    int ret;
+#ifdef HAVE_PK_CALLBACKS
+    const byte* keyBuf = NULL;
+    word32 keySz = 0;
+
+    if (keyBufInfo) {
+        keyBuf = keyBufInfo->buffer;
+        keySz = keyBufInfo->length;
+    }
+#endif
+
+    (void)ssl;
+    (void)keyBufInfo;
+
+    WOLFSSL_ENTER("EccVerify");
+
+#ifdef WOLFSSL_ASYNC_CRYPT
+    /* initialize event */
+    ret = wolfSSL_AsyncInit(ssl, &key->asyncDev, WC_ASYNC_FLAG_CALL_AGAIN);
+    if (ret != 0)
+        return ret;
+#endif
+
+#ifdef HAVE_PK_CALLBACKS
+    if (ssl->ctx->EccVerifyCb) {
+        void* ctx = wolfSSL_GetEccVerifyCtx(ssl);
+        ret = ssl->ctx->EccVerifyCb(ssl, in, inSz, out, outSz, keyBuf, keySz,
+            &ssl->eccVerifyRes, ctx);
+    }
+    else
+#endif /* HAVE_PK_CALLBACKS  */
+    {
+        ret = wc_ecc_verify_hash(in, inSz, out, outSz, &ssl->eccVerifyRes, key);
+    }
+
+    /* Handle async pending response */
+#ifdef WOLFSSL_ASYNC_CRYPT
+    if (ret == WC_PENDING_E) {
+        ret = wolfSSL_AsyncPush(ssl, &key->asyncDev);
+    }
+    else
+#endif /* WOLFSSL_ASYNC_CRYPT */
+    {
+        ret = (ret != 0 || ssl->eccVerifyRes == 0) ? VERIFY_SIGN_ERROR : 0;
+    }
+
+    WOLFSSL_LEAVE("EccVerify", ret);
+
+    return ret;
+}
+
+#ifdef HAVE_PK_CALLBACKS
+    /* Gets ECC key for shared secret callback testing
+     * Client side: returns peer key
+     * Server side: returns private key
+     */
+    static int EccGetKey(WOLFSSL* ssl, ecc_key** otherKey)
+    {
+        int ret = NO_PEER_KEY;
+        ecc_key* tmpKey = NULL;
+
+        if (ssl == NULL || otherKey == NULL) {
+            return BAD_FUNC_ARG;
+        }
+
+        if (ssl->options.side == WOLFSSL_CLIENT_END) {
+            if (ssl->specs.static_ecdh) {
+                if (!ssl->peerEccDsaKey || !ssl->peerEccDsaKeyPresent ||
+                                           !ssl->peerEccDsaKey->dp) {
+                    return NO_PEER_KEY;
+                }
+                tmpKey = (struct ecc_key*)ssl->peerEccDsaKey;
+            }
+            else {
+                if (!ssl->peerEccKey || !ssl->peerEccKeyPresent ||
+                                        !ssl->peerEccKey->dp) {
+                    return NO_PEER_KEY;
+                }
+                tmpKey = (struct ecc_key*)ssl->peerEccKey;
+            }
+        }
+        else if (ssl->options.side == WOLFSSL_SERVER_END) {
+            if (ssl->specs.static_ecdh) {
+                if (ssl->hsKey == NULL) {
+                    return NO_PRIVATE_KEY;
+                }
+                tmpKey = (struct ecc_key*)ssl->hsKey;
+            }
+            else {
+                if (!ssl->eccTempKeyPresent) {
+                    return NO_PRIVATE_KEY;
+                }
+                tmpKey = (struct ecc_key*)ssl->eccTempKey;
+            }
+        }
+
+        if (tmpKey) {
+            *otherKey = tmpKey;
+            ret = 0;
+        }
+
+        return ret;
+    }
+#endif /* HAVE_PK_CALLBACKS */
+
+int EccSharedSecret(WOLFSSL* ssl, ecc_key* priv_key, ecc_key* pub_key,
+        byte* pubKeyDer, word32* pubKeySz, byte* out, word32* outlen,
+        int side)
+{
+    int ret;
+#ifdef HAVE_PK_CALLBACKS
+    ecc_key* otherKey = NULL;
+#endif
+#ifdef WOLFSSL_ASYNC_CRYPT
+    WC_ASYNC_DEV* asyncDev = &priv_key->asyncDev;
+#endif
+
+    (void)ssl;
+    (void)pubKeyDer;
+    (void)pubKeySz;
+    (void)side;
+
+    WOLFSSL_ENTER("EccSharedSecret");
+
+#ifdef HAVE_PK_CALLBACKS
+    if (ssl->ctx->EccSharedSecretCb) {
+        ret = EccGetKey(ssl, &otherKey);
+        if (ret != 0)
+            return ret;
+    #ifdef WOLFSSL_ASYNC_CRYPT
+        asyncDev = &otherKey->asyncDev;
+    #endif
+    }
+#endif
+
+#ifdef WOLFSSL_ASYNC_CRYPT
+    /* initialize event */
+    ret = wolfSSL_AsyncInit(ssl, asyncDev, WC_ASYNC_FLAG_CALL_AGAIN);
+    if (ret != 0)
+        return ret;
+#endif
+
+#ifdef HAVE_PK_CALLBACKS
+    if (ssl->ctx->EccSharedSecretCb) {
+        void* ctx = wolfSSL_GetEccSharedSecretCtx(ssl);
+        ret = ssl->ctx->EccSharedSecretCb(ssl, otherKey, pubKeyDer,
+            pubKeySz, out, outlen, side, ctx);
+    }
+    else
+#endif
+    {
+        ret = wc_ecc_shared_secret(priv_key, pub_key, out, outlen);
+    }
+
+    /* Handle async pending response */
+#ifdef WOLFSSL_ASYNC_CRYPT
+    if (ret == WC_PENDING_E) {
+        ret = wolfSSL_AsyncPush(ssl, asyncDev);
+    }
+#endif /* WOLFSSL_ASYNC_CRYPT */
+
+    WOLFSSL_LEAVE("EccSharedSecret", ret);
+
+    return ret;
+}
+
+int EccMakeKey(WOLFSSL* ssl, ecc_key* key, ecc_key* peer)
+{
+    int ret = 0;
+    int keySz = 0;
+    int ecc_curve = ECC_CURVE_DEF;
+
+    WOLFSSL_ENTER("EccMakeKey");
+
+#ifdef WOLFSSL_ASYNC_CRYPT
+    /* initialize event */
+    ret = wolfSSL_AsyncInit(ssl, &key->asyncDev, WC_ASYNC_FLAG_NONE);
+    if (ret != 0)
+        return ret;
+#endif
+
+    /* get key size */
+    if (peer == NULL) {
+        keySz = ssl->eccTempKeySz;
+    }
+    else {
+        keySz = peer->dp->size;
+    }
+
+    /* get curve type */
+    if (ssl->ecdhCurveOID > 0) {
+        ecc_curve = wc_ecc_get_oid(ssl->ecdhCurveOID, NULL, NULL);
+    }
+
+#ifdef HAVE_PK_CALLBACKS
+    if (ssl->ctx->EccKeyGenCb) {
+        void* ctx = wolfSSL_GetEccKeyGenCtx(ssl);
+        ret = ssl->ctx->EccKeyGenCb(ssl, key, keySz, ecc_curve, ctx);
+    }
+    else
+#endif
+    {
+        ret = wc_ecc_make_key_ex(ssl->rng, keySz, key, ecc_curve);
+    }
+
+    /* make sure the curve is set for TLS */
+    if (ret == 0 && key->dp) {
+        ssl->ecdhCurveOID = key->dp->oidSum;
+    #if defined(WOLFSSL_TLS13) || defined(HAVE_FFDHE)
+        ssl->namedGroup = 0;
+    #endif
+    }
+
+    /* Handle async pending response */
+#ifdef WOLFSSL_ASYNC_CRYPT
+    if (ret == WC_PENDING_E) {
+        ret = wolfSSL_AsyncPush(ssl, &key->asyncDev);
+    }
+#endif /* WOLFSSL_ASYNC_CRYPT */
+
+    WOLFSSL_LEAVE("EccMakeKey", ret);
+
+    return ret;
+}
+#endif /* HAVE_ECC */
+
+#ifdef HAVE_ED25519
+/* Check whether the key contains a public key.
+ * If not then pull it out of the leaf certificate.
+ *
+ * ssl  SSL/TLS object.
+ * returns MEMORY_E when unable to allocate memory, a parsing error, otherwise
+ * 0 on success.
+ */
+int Ed25519CheckPubKey(WOLFSSL* ssl)
+{
+    ed25519_key* key = (ed25519_key*)ssl->hsKey;
+    int ret = 0;
+
+    /* Public key required for signing. */
+    if (!key->pubKeySet) {
+        DerBuffer* leaf = ssl->buffers.certificate;
+        DecodedCert* cert = (DecodedCert*)XMALLOC(sizeof(*cert),
+                                     ssl->heap, DYNAMIC_TYPE_DCERT);
+        if (cert == NULL)
+            ret = MEMORY_E;
+
+        if (ret == 0) {
+            InitDecodedCert(cert, leaf->buffer, leaf->length, ssl->heap);
+            ret = DecodeToKey(cert, 0);
+        }
+        if (ret == 0) {
+            ret = wc_ed25519_import_public(cert->publicKey, cert->pubKeySize,
+                                                                           key);
+        }
+        if (cert != NULL) {
+            FreeDecodedCert(cert);
+            XFREE(cert, ssl->heap, DYNAMIC_TYPE_DCERT);
+        }
+    }
+
+    return ret;
+}
+
+/* Sign the data using EdDSA and key using Ed25519.
+ *
+ * ssl    SSL object.
+ * in     Data or message to sign.
+ * inSz   Length of the data.
+ * out    Buffer to hold signature.
+ * outSz  On entry, size of the buffer. On exit, the size of the signature.
+ * key    The private Ed25519 key data.
+ * keySz  The length of the private key data in bytes.
+ * ctx    The callback context.
+ * returns 0 on success, otherwise the value is an error.
+ */
+int Ed25519Sign(WOLFSSL* ssl, const byte* in, word32 inSz, byte* out,
+                word32* outSz, ed25519_key* key, DerBuffer* keyBufInfo)
+{
+    int ret;
+#ifdef HAVE_PK_CALLBACKS
+    const byte* keyBuf = NULL;
+    word32 keySz = 0;
+
+    if (keyBufInfo) {
+        keyBuf = keyBufInfo->buffer;
+        keySz = keyBufInfo->length;
+    }
+#endif
+
+    (void)ssl;
+    (void)keyBufInfo;
+
+    WOLFSSL_ENTER("Ed25519Sign");
+
+#ifdef WOLFSSL_ASYNC_CRYPT
+    /* initialize event */
+    ret = wolfSSL_AsyncInit(ssl, &key->asyncDev, WC_ASYNC_FLAG_CALL_AGAIN);
+    if (ret != 0)
+        return ret;
+#endif
+
+#if defined(HAVE_PK_CALLBACKS)
+    if (ssl->ctx->Ed25519SignCb) {
+        void* ctx = wolfSSL_GetEd25519SignCtx(ssl);
+        ret = ssl->ctx->Ed25519SignCb(ssl, in, inSz, out, outSz, keyBuf,
+            keySz, ctx);
+    }
+    else
+#endif /* HAVE_PK_CALLBACKS */
+    {
+        ret = wc_ed25519_sign_msg(in, inSz, out, outSz, key);
+    }
+
+    /* Handle async pending response */
+#ifdef WOLFSSL_ASYNC_CRYPT
+    if (ret == WC_PENDING_E) {
+        ret = wolfSSL_AsyncPush(ssl, &key->asyncDev);
+    }
+#endif /* WOLFSSL_ASYNC_CRYPT */
+
+    WOLFSSL_LEAVE("Ed25519Sign", ret);
+
+    return ret;
+}
+
+/* Verify the data using EdDSA and key using Ed25519.
+ *
+ * ssl    SSL object.
+ * in     Signature data.
+ * inSz   Length of the signature data in bytes.
+ * msg    Message to verify.
+ * outSz  Length of message in bytes.
+ * key    The public Ed25519 key data.
+ * keySz  The length of the private key data in bytes.
+ * ctx    The callback context.
+ * returns 0 on success, otherwise the value is an error.
+ */
+int Ed25519Verify(WOLFSSL* ssl, const byte* in, word32 inSz, const byte* msg,
+                  word32 msgSz, ed25519_key* key, buffer* keyBufInfo)
+{
+    int ret;
+#ifdef HAVE_PK_CALLBACKS
+    const byte* keyBuf = NULL;
+    word32 keySz = 0;
+
+    if (keyBufInfo) {
+        keyBuf = keyBufInfo->buffer;
+        keySz = keyBufInfo->length;
+    }
+#endif
+
+    (void)ssl;
+    (void)keyBufInfo;
+
+    WOLFSSL_ENTER("Ed25519Verify");
+
+#ifdef WOLFSSL_ASYNC_CRYPT
+    /* initialize event */
+    ret = wolfSSL_AsyncInit(ssl, &key->asyncDev, WC_ASYNC_FLAG_CALL_AGAIN);
+    if (ret != 0)
+        return ret;
+#endif
+
+#ifdef HAVE_PK_CALLBACKS
+    if (ssl->ctx->Ed25519VerifyCb) {
+        void* ctx = wolfSSL_GetEd25519VerifyCtx(ssl);
+        ret = ssl->ctx->Ed25519VerifyCb(ssl, in, inSz, msg, msgSz, keyBuf,
+                                        keySz, &ssl->eccVerifyRes, ctx);
+    }
+    else
+#endif /* HAVE_PK_CALLBACKS  */
+    {
+        ret = wc_ed25519_verify_msg(in, inSz, msg, msgSz,
+                                    &ssl->eccVerifyRes, key);
+    }
+
+    /* Handle async pending response */
+#ifdef WOLFSSL_ASYNC_CRYPT
+    if (ret == WC_PENDING_E) {
+        ret = wolfSSL_AsyncPush(ssl, &key->asyncDev);
+    }
+    else
+#endif /* WOLFSSL_ASYNC_CRYPT */
+    {
+        ret = (ret != 0 || ssl->eccVerifyRes == 0) ? VERIFY_SIGN_ERROR : 0;
+    }
+
+    WOLFSSL_LEAVE("Ed25519Verify", ret);
+
+    return ret;
+}
+#endif /* HAVE_ED25519 */
+
+#ifndef WOLFSSL_NO_TLS12
+
+#ifdef HAVE_CURVE25519
+#ifdef HAVE_PK_CALLBACKS
+    /* Gets X25519 key for shared secret callback testing
+     * Client side: returns peer key
+     * Server side: returns private key
+     */
+    static int X25519GetKey(WOLFSSL* ssl, curve25519_key** otherKey)
+    {
+        int ret = NO_PEER_KEY;
+        struct curve25519_key* tmpKey = NULL;
+
+        if (ssl == NULL || otherKey == NULL) {
+            return BAD_FUNC_ARG;
+        }
+
+        if (ssl->options.side == WOLFSSL_CLIENT_END) {
+            if (!ssl->peerX25519Key || !ssl->peerX25519KeyPresent ||
+                                       !ssl->peerX25519Key->dp) {
+                return NO_PEER_KEY;
+            }
+            tmpKey = (struct curve25519_key*)ssl->peerX25519Key;
+        }
+        else if (ssl->options.side == WOLFSSL_SERVER_END) {
+            if (!ssl->eccTempKeyPresent) {
+                return NO_PRIVATE_KEY;
+            }
+            tmpKey = (struct curve25519_key*)ssl->eccTempKey;
+        }
+
+        if (tmpKey) {
+            *otherKey = (curve25519_key *)tmpKey;
+            ret = 0;
+        }
+
+        return ret;
+    }
+#endif /* HAVE_PK_CALLBACKS */
+
+static int X25519SharedSecret(WOLFSSL* ssl, curve25519_key* priv_key,
+        curve25519_key* pub_key, byte* pubKeyDer, word32* pubKeySz,
+        byte* out, word32* outlen, int side)
+{
+    int ret;
+
+    (void)ssl;
+    (void)pubKeyDer;
+    (void)pubKeySz;
+    (void)side;
+
+    WOLFSSL_ENTER("X25519SharedSecret");
+
+#ifdef WOLFSSL_ASYNC_CRYPT
+    /* initialize event */
+    ret = wolfSSL_AsyncInit(ssl, &priv_key->asyncDev, WC_ASYNC_FLAG_CALL_AGAIN);
+    if (ret != 0)
+        return ret;
+#endif
+
+#ifdef HAVE_PK_CALLBACKS
+    if (ssl->ctx->X25519SharedSecretCb) {
+        curve25519_key* otherKey = NULL;
+
+        ret = X25519GetKey(ssl, &otherKey);
+        if (ret == 0) {
+            void* ctx = wolfSSL_GetX25519SharedSecretCtx(ssl);
+            ret = ssl->ctx->X25519SharedSecretCb(ssl, otherKey, pubKeyDer,
+                pubKeySz, out, outlen, side, ctx);
+        }
+    }
+    else
+#endif
+    {
+        ret = wc_curve25519_shared_secret_ex(priv_key, pub_key, out, outlen,
+                                             EC25519_LITTLE_ENDIAN);
+    }
+
+    /* Handle async pending response */
+#ifdef WOLFSSL_ASYNC_CRYPT
+    if (ret == WC_PENDING_E) {
+        ret = wolfSSL_AsyncPush(ssl, &priv_key->asyncDev);
+    }
+#endif /* WOLFSSL_ASYNC_CRYPT */
+
+    WOLFSSL_LEAVE("X25519SharedSecret", ret);
+
+    return ret;
+}
+
+static int X25519MakeKey(WOLFSSL* ssl, curve25519_key* key,
+        curve25519_key* peer)
+{
+    int ret = 0;
+
+    (void)peer;
+
+    WOLFSSL_ENTER("X25519MakeKey");
+
+#ifdef WOLFSSL_ASYNC_CRYPT
+    /* initialize event */
+    ret = wolfSSL_AsyncInit(ssl, &key->asyncDev, WC_ASYNC_FLAG_NONE);
+    if (ret != 0)
+        return ret;
+#endif
+
+#ifdef HAVE_PK_CALLBACKS
+    if (ssl->ctx->X25519KeyGenCb) {
+        void* ctx = wolfSSL_GetX25519KeyGenCtx(ssl);
+        ret = ssl->ctx->X25519KeyGenCb(ssl, key, CURVE25519_KEYSIZE, ctx);
+    }
+    else
+#endif
+    {
+        ret = wc_curve25519_make_key(ssl->rng, CURVE25519_KEYSIZE, key);
+    }
+
+    if (ret == 0) {
+        ssl->ecdhCurveOID = ECC_X25519_OID;
+    #if defined(WOLFSSL_TLS13) || defined(HAVE_FFDHE)
+        ssl->namedGroup = 0;
+    #endif
+    }
+
+    /* Handle async pending response */
+#ifdef WOLFSSL_ASYNC_CRYPT
+    if (ret == WC_PENDING_E) {
+        ret = wolfSSL_AsyncPush(ssl, &key->asyncDev);
+    }
+#endif /* WOLFSSL_ASYNC_CRYPT */
+
+    WOLFSSL_LEAVE("X25519MakeKey", ret);
+
+    return ret;
+}
+#endif /* HAVE_CURVE25519 */
+
+#ifdef HAVE_ED448
+/* Check whether the key contains a public key.
+ * If not then pull it out of the leaf certificate.
+ *
+ * ssl  SSL/TLS object.
+ * returns MEMORY_E when unable to allocate memory, a parsing error, otherwise
+ * 0 on success.
+ */
+int Ed448CheckPubKey(WOLFSSL* ssl)
+{
+    ed448_key* key = (ed448_key*)ssl->hsKey;
+    int ret = 0;
+
+    /* Public key required for signing. */
+    if (!key->pubKeySet) {
+        DerBuffer* leaf = ssl->buffers.certificate;
+        DecodedCert* cert = (DecodedCert*)XMALLOC(sizeof(*cert), ssl->heap,
+            DYNAMIC_TYPE_DCERT);
+        if (cert == NULL)
+            ret = MEMORY_E;
+
+        if (ret == 0) {
+            InitDecodedCert(cert, leaf->buffer, leaf->length, ssl->heap);
+            ret = DecodeToKey(cert, 0);
+        }
+        if (ret == 0) {
+            ret = wc_ed448_import_public(cert->publicKey, cert->pubKeySize,
+                key);
+        }
+        if (cert != NULL) {
+            FreeDecodedCert(cert);
+            XFREE(cert, ssl->heap, DYNAMIC_TYPE_DCERT);
+        }
+    }
+
+    return ret;
+}
+
+/* Sign the data using EdDSA and key using Ed448.
+ *
+ * ssl    SSL object.
+ * in     Data or message to sign.
+ * inSz   Length of the data.
+ * out    Buffer to hold signature.
+ * outSz  On entry, size of the buffer. On exit, the size of the signature.
+ * key    The private Ed448 key data.
+ * keySz  The length of the private key data in bytes.
+ * ctx    The callback context.
+ * returns 0 on success, otherwise the value is an error.
+ */
+int Ed448Sign(WOLFSSL* ssl, const byte* in, word32 inSz, byte* out,
+              word32* outSz, ed448_key* key, DerBuffer* keyBufInfo)
+{
+    int ret;
+#ifdef HAVE_PK_CALLBACKS
+    const byte* keyBuf = NULL;
+    word32 keySz = 0;
+
+    if (keyBufInfo) {
+        keyBuf = keyBufInfo->buffer;
+        keySz = keyBufInfo->length;
+    }
+#endif
+
+    (void)ssl;
+    (void)keyBufInfo;
+
+    WOLFSSL_ENTER("Ed448Sign");
+
+#ifdef WOLFSSL_ASYNC_CRYPT
+    /* initialize event */
+    ret = wolfSSL_AsyncInit(ssl, &key->asyncDev, WC_ASYNC_FLAG_CALL_AGAIN);
+    if (ret != 0)
+        return ret;
+#endif
+
+#if defined(HAVE_PK_CALLBACKS)
+    if (ssl->ctx->Ed448SignCb) {
+        void* ctx = wolfSSL_GetEd448SignCtx(ssl);
+        ret = ssl->ctx->Ed448SignCb(ssl, in, inSz, out, outSz, keyBuf, keySz,
+            ctx);
+    }
+    else
+#endif /* HAVE_PK_CALLBACKS */
+    {
+        ret = wc_ed448_sign_msg(in, inSz, out, outSz, key, NULL, 0);
+    }
+
+    /* Handle async pending response */
+#ifdef WOLFSSL_ASYNC_CRYPT
+    if (ret == WC_PENDING_E) {
+        ret = wolfSSL_AsyncPush(ssl, &key->asyncDev);
+    }
+#endif /* WOLFSSL_ASYNC_CRYPT */
+
+    WOLFSSL_LEAVE("Ed448Sign", ret);
+
+    return ret;
+}
+
+/* Verify the data using EdDSA and key using Ed448.
+ *
+ * ssl    SSL object.
+ * in     Signature data.
+ * inSz   Length of the signature data in bytes.
+ * msg    Message to verify.
+ * outSz  Length of message in bytes.
+ * key    The public Ed448 key data.
+ * keySz  The length of the private key data in bytes.
+ * ctx    The callback context.
+ * returns 0 on success, otherwise the value is an error.
+ */
+int Ed448Verify(WOLFSSL* ssl, const byte* in, word32 inSz, const byte* msg,
+                word32 msgSz, ed448_key* key, buffer* keyBufInfo)
+{
+    int ret;
+#ifdef HAVE_PK_CALLBACKS
+    const byte* keyBuf = NULL;
+    word32 keySz = 0;
+
+    if (keyBufInfo) {
+        keyBuf = keyBufInfo->buffer;
+        keySz = keyBufInfo->length;
+    }
+#endif
+
+    (void)ssl;
+    (void)keyBufInfo;
+
+    WOLFSSL_ENTER("Ed448Verify");
+
+#ifdef WOLFSSL_ASYNC_CRYPT
+    /* initialize event */
+    ret = wolfSSL_AsyncInit(ssl, &key->asyncDev, WC_ASYNC_FLAG_CALL_AGAIN);
+    if (ret != 0)
+        return ret;
+#endif
+
+#ifdef HAVE_PK_CALLBACKS
+    if (ssl->ctx->Ed448VerifyCb) {
+        void* ctx = wolfSSL_GetEd448VerifyCtx(ssl);
+        ret = ssl->ctx->Ed448VerifyCb(ssl, in, inSz, msg, msgSz, keyBuf, keySz,
+             &ssl->eccVerifyRes, ctx);
+    }
+    else
+#endif /* HAVE_PK_CALLBACKS  */
+    {
+        ret = wc_ed448_verify_msg(in, inSz, msg, msgSz, &ssl->eccVerifyRes, key,
+            NULL, 0);
+    }
+
+    /* Handle async pending response */
+#ifdef WOLFSSL_ASYNC_CRYPT
+    if (ret == WC_PENDING_E) {
+        ret = wolfSSL_AsyncPush(ssl, &key->asyncDev);
+    }
+    else
+#endif /* WOLFSSL_ASYNC_CRYPT */
+    {
+        ret = (ret != 0 || ssl->eccVerifyRes == 0) ? VERIFY_SIGN_ERROR : 0;
+    }
+
+    WOLFSSL_LEAVE("Ed448Verify", ret);
+
+    return ret;
+}
+#endif /* HAVE_ED448 */
+
+#ifdef HAVE_CURVE448
+#ifdef HAVE_PK_CALLBACKS
+    /* Gets X448 key for shared secret callback testing
+     * Client side: returns peer key
+     * Server side: returns private key
+     */
+    static int X448GetKey(WOLFSSL* ssl, curve448_key** otherKey)
+    {
+        int ret = NO_PEER_KEY;
+        struct curve448_key* tmpKey = NULL;
+
+        if (ssl == NULL || otherKey == NULL) {
+            return BAD_FUNC_ARG;
+        }
+
+        if (ssl->options.side == WOLFSSL_CLIENT_END) {
+            if (!ssl->peerX448Key || !ssl->peerX448KeyPresent) {
+                return NO_PEER_KEY;
+            }
+            tmpKey = (struct curve448_key*)ssl->peerX448Key;
+        }
+        else if (ssl->options.side == WOLFSSL_SERVER_END) {
+            if (!ssl->eccTempKeyPresent) {
+                return NO_PRIVATE_KEY;
+            }
+            tmpKey = (struct curve448_key*)ssl->eccTempKey;
+        }
+
+        if (tmpKey) {
+            *otherKey = (curve448_key *)tmpKey;
+            ret = 0;
+        }
+
+        return ret;
+    }
+#endif /* HAVE_PK_CALLBACKS */
+
+static int X448SharedSecret(WOLFSSL* ssl, curve448_key* priv_key,
+                            curve448_key* pub_key, byte* pubKeyDer,
+                            word32* pubKeySz, byte* out, word32* outlen,
+                            int side)
+{
+    int ret;
+
+    (void)ssl;
+    (void)pubKeyDer;
+    (void)pubKeySz;
+    (void)side;
+
+    WOLFSSL_ENTER("X448SharedSecret");
+
+#ifdef WOLFSSL_ASYNC_CRYPT
+    /* initialize event */
+    ret = wolfSSL_AsyncInit(ssl, &priv_key->asyncDev, WC_ASYNC_FLAG_CALL_AGAIN);
+    if (ret != 0)
+        return ret;
+#endif
+
+#ifdef HAVE_PK_CALLBACKS
+    if (ssl->ctx->X448SharedSecretCb) {
+        curve448_key* otherKey = NULL;
+
+        ret = X448GetKey(ssl, &otherKey);
+        if (ret == 0) {
+            void* ctx = wolfSSL_GetX448SharedSecretCtx(ssl);
+            ret = ssl->ctx->X448SharedSecretCb(ssl, otherKey, pubKeyDer,
+                pubKeySz, out, outlen, side, ctx);
+        }
+    }
+    else
+#endif
+    {
+        ret = wc_curve448_shared_secret_ex(priv_key, pub_key, out, outlen,
+            EC448_LITTLE_ENDIAN);
+    }
+
+    /* Handle async pending response */
+#ifdef WOLFSSL_ASYNC_CRYPT
+    if (ret == WC_PENDING_E) {
+        ret = wolfSSL_AsyncPush(ssl, &priv_key->asyncDev);
+    }
+#endif /* WOLFSSL_ASYNC_CRYPT */
+
+    WOLFSSL_LEAVE("X448SharedSecret", ret);
+
+    return ret;
+}
+
+static int X448MakeKey(WOLFSSL* ssl, curve448_key* key, curve448_key* peer)
+{
+    int ret = 0;
+
+    (void)peer;
+
+    WOLFSSL_ENTER("X448MakeKey");
+
+#ifdef WOLFSSL_ASYNC_CRYPT
+    /* initialize event */
+    ret = wolfSSL_AsyncInit(ssl, &key->asyncDev, WC_ASYNC_FLAG_NONE);
+    if (ret != 0)
+        return ret;
+#endif
+
+#ifdef HAVE_PK_CALLBACKS
+    if (ssl->ctx->X448KeyGenCb) {
+        void* ctx = wolfSSL_GetX448KeyGenCtx(ssl);
+        ret = ssl->ctx->X448KeyGenCb(ssl, key, CURVE448_KEY_SIZE, ctx);
+    }
+    else
+#endif
+    {
+        ret = wc_curve448_make_key(ssl->rng, CURVE448_KEY_SIZE, key);
+    }
+
+    if (ret == 0) {
+        ssl->ecdhCurveOID = ECC_X448_OID;
+    #if defined(WOLFSSL_TLS13) || defined(HAVE_FFDHE)
+        ssl->namedGroup = 0;
+    #endif
+    }
+
+    /* Handle async pending response */
+#ifdef WOLFSSL_ASYNC_CRYPT
+    if (ret == WC_PENDING_E) {
+        ret = wolfSSL_AsyncPush(ssl, &key->asyncDev);
+    }
+#endif /* WOLFSSL_ASYNC_CRYPT */
+
+    WOLFSSL_LEAVE("X448MakeKey", ret);
+
+    return ret;
+}
+#endif /* HAVE_CURVE448 */
+
+#if !defined(NO_CERTS) || !defined(NO_PSK)
+#if !defined(NO_DH)
+
+int DhGenKeyPair(WOLFSSL* ssl, DhKey* dhKey,
+    byte* priv, word32* privSz,
+    byte* pub, word32* pubSz)
+{
+    int ret;
+
+    WOLFSSL_ENTER("DhGenKeyPair");
+
+#ifdef WOLFSSL_ASYNC_CRYPT
+    /* initialize event */
+    ret = wolfSSL_AsyncInit(ssl, &dhKey->asyncDev, WC_ASYNC_FLAG_NONE);
+    if (ret != 0)
+        return ret;
+#endif
+
+    ret = wc_DhGenerateKeyPair(dhKey, ssl->rng, priv, privSz, pub, pubSz);
+
+    /* Handle async pending response */
+#ifdef WOLFSSL_ASYNC_CRYPT
+    if (ret == WC_PENDING_E) {
+        ret = wolfSSL_AsyncPush(ssl, &dhKey->asyncDev);
+    }
+#endif /* WOLFSSL_ASYNC_CRYPT */
+
+    WOLFSSL_LEAVE("DhGenKeyPair", ret);
+
+    return ret;
+}
+
+int DhAgree(WOLFSSL* ssl, DhKey* dhKey,
+    const byte* priv, word32 privSz,
+    const byte* otherPub, word32 otherPubSz,
+    byte* agree, word32* agreeSz)
+{
+    int ret;
+
+    (void)ssl;
+
+    WOLFSSL_ENTER("DhAgree");
+
+#ifdef WOLFSSL_ASYNC_CRYPT
+    /* initialize event */
+    ret = wolfSSL_AsyncInit(ssl, &dhKey->asyncDev, WC_ASYNC_FLAG_NONE);
+    if (ret != 0)
+        return ret;
+#endif
+
+#ifdef HAVE_PK_CALLBACKS
+    if (ssl->ctx->DhAgreeCb) {
+        void* ctx = wolfSSL_GetDhAgreeCtx(ssl);
+
+        WOLFSSL_MSG("Calling DhAgree Callback Function");
+        ret = ssl->ctx->DhAgreeCb(ssl, dhKey, priv, privSz,
+                    otherPub, otherPubSz, agree, agreeSz, ctx);
+    }
+    else
+#endif
+    {
+#if !defined(HAVE_FIPS) && !defined(HAVE_SELFTEST)
+        ret = wc_DhCheckPubValue(ssl->buffers.serverDH_P.buffer,
+                    ssl->buffers.serverDH_P.length, otherPub, otherPubSz);
+        if (ret != 0) {
+    #ifdef OPENSSL_EXTRA
+            SendAlert(ssl, alert_fatal, illegal_parameter);
+    #endif
+        }
+        else
+#endif
+        {
+            ret = wc_DhAgree(dhKey, agree, agreeSz, priv, privSz, otherPub,
+                    otherPubSz);
+        }
+    }
+
+    /* Handle async pending response */
+#ifdef WOLFSSL_ASYNC_CRYPT
+    if (ret == WC_PENDING_E) {
+        ret = wolfSSL_AsyncPush(ssl, &dhKey->asyncDev);
+    }
+#endif /* WOLFSSL_ASYNC_CRYPT */
+
+    WOLFSSL_LEAVE("DhAgree", ret);
+
+    return ret;
+}
+#endif /* !NO_DH */
+#endif /* !NO_CERTS || !NO_PSK */
+
+#endif /* !WOLFSSL_NO_TLS12 */
+
+
+#ifdef HAVE_PK_CALLBACKS
+int wolfSSL_IsPrivatePkSet(WOLFSSL* ssl)
+{
+    int pkcbset = 0;
+    (void)ssl;
+
+#if defined(HAVE_ECC) || defined(HAVE_ED25519) || defined(HAVE_ED448) || \
+                                                                !defined(NO_RSA)
+    if (0
+    #ifdef HAVE_ECC
+        || (ssl->ctx->EccSignCb != NULL &&
+                                        ssl->buffers.keyType == ecc_dsa_sa_algo)
+    #endif
+    #ifdef HAVE_ED25519
+        || (ssl->ctx->Ed25519SignCb != NULL &&
+                                        ssl->buffers.keyType == ed25519_sa_algo)
+    #endif
+    #ifdef HAVE_ED448
+        || (ssl->ctx->Ed448SignCb != NULL &&
+                                          ssl->buffers.keyType == ed448_sa_algo)
+    #endif
+    #ifndef NO_RSA
+        || (ssl->ctx->RsaSignCb != NULL && ssl->buffers.keyType == rsa_sa_algo)
+        || (ssl->ctx->RsaDecCb != NULL && ssl->buffers.keyType == rsa_kea)
+        #ifdef WC_RSA_PSS
+        || (ssl->ctx->RsaPssSignCb != NULL &&
+                                        ssl->buffers.keyType == rsa_pss_sa_algo)
+        #endif
+    #endif
+    ) {
+        pkcbset = 1;
+    }
+#endif
+    return pkcbset;
+}
+
+int wolfSSL_CTX_IsPrivatePkSet(WOLFSSL_CTX* ctx)
+{
+    int pkcbset = 0;
+    (void)ctx;
+#if defined(HAVE_ECC) || defined(HAVE_ED25519) || defined(HAVE_ED448) || \
+                                                                !defined(NO_RSA)
+    if (0
+    #ifdef HAVE_ECC
+        || ctx->EccSignCb != NULL
+    #endif
+    #ifdef HAVE_ED25519
+        || ctx->Ed25519SignCb != NULL
+    #endif
+    #ifdef HAVE_ED448
+        || ctx->Ed448SignCb != NULL
+    #endif
+    #ifndef NO_RSA
+        || ctx->RsaSignCb != NULL
+        || ctx->RsaDecCb != NULL
+        #ifdef WC_RSA_PSS
+        || ctx->RsaPssSignCb != NULL
+        #endif
+    #endif
+    ) {
+        pkcbset = 1;
+    }
+#endif
+    return pkcbset;
+}
+#endif /* HAVE_PK_CALLBACKS */
+
+
+int InitSSL_Suites(WOLFSSL* ssl)
+{
+    int keySz = 0;
+    byte havePSK = 0;
+    byte haveAnon = 0;
+    byte haveRSA = 0;
+    byte haveMcast = 0;
+
+    (void)haveAnon; /* Squash unused var warnings */
+    (void)haveMcast;
+
+    if (!ssl)
+        return BAD_FUNC_ARG;
+
+#ifndef NO_RSA
+    haveRSA = 1;
+#endif
+#ifndef NO_PSK
+    havePSK = (byte)ssl->options.havePSK;
+#endif /* NO_PSK */
+#ifdef HAVE_ANON
+    haveAnon = (byte)ssl->options.haveAnon;
+#endif /* HAVE_ANON*/
+#ifdef WOLFSSL_MULTICAST
+    haveMcast = (byte)ssl->options.haveMcast;
+#endif /* WOLFSSL_MULTICAST */
+
+#ifdef WOLFSSL_EARLY_DATA
+    if (ssl->options.side == WOLFSSL_SERVER_END)
+        ssl->options.maxEarlyDataSz = ssl->ctx->maxEarlyDataSz;
+#endif
+#if !defined(WOLFSSL_NO_CLIENT_AUTH) && \
+               ((defined(HAVE_ED25519) && !defined(NO_ED25519_CLIENT_AUTH)) || \
+                (defined(HAVE_ED448) && !defined(NO_ED448_CLIENT_AUTH)))
+    ssl->options.cacheMessages = ssl->options.side == WOLFSSL_SERVER_END ||
+                                      ssl->buffers.keyType == ed25519_sa_algo ||
+                                      ssl->buffers.keyType == ed448_sa_algo;
+#endif
+
+#ifndef NO_CERTS
+    keySz = ssl->buffers.keySz;
+#endif
+
+    /* make sure server has DH parms, and add PSK if there, add NTRU too */
+    if (ssl->options.side == WOLFSSL_SERVER_END) {
+        InitSuites(ssl->suites, ssl->version, keySz, haveRSA, havePSK,
+                   ssl->options.haveDH, ssl->options.haveNTRU,
+                   ssl->options.haveECDSAsig, ssl->options.haveECC,
+                   ssl->options.haveStaticECC, ssl->options.side);
+    }
+    else {
+        InitSuites(ssl->suites, ssl->version, keySz, haveRSA, havePSK,
+                   TRUE, ssl->options.haveNTRU,
+                   ssl->options.haveECDSAsig, ssl->options.haveECC,
+                   ssl->options.haveStaticECC, ssl->options.side);
+    }
+
+#if !defined(NO_CERTS) && !defined(WOLFSSL_SESSION_EXPORT)
+    /* make sure server has cert and key unless using PSK, Anon, or
+     * Multicast. This should be true even if just switching ssl ctx */
+    if (ssl->options.side == WOLFSSL_SERVER_END &&
+            !havePSK && !haveAnon && !haveMcast) {
+
+        /* server certificate must be loaded */
+        if (!ssl->buffers.certificate || !ssl->buffers.certificate->buffer) {
+            WOLFSSL_MSG("Server missing certificate");
+            return NO_PRIVATE_KEY;
+        }
+
+        /* allow no private key if using PK callbacks and CB is set */
+    #ifdef HAVE_PK_CALLBACKS
+        if (wolfSSL_CTX_IsPrivatePkSet(ssl->ctx)) {
+            WOLFSSL_MSG("Using PK for server private key");
+        }
+        else
+    #endif
+        if (!ssl->buffers.key || !ssl->buffers.key->buffer) {
+            WOLFSSL_MSG("Server missing private key");
+            return NO_PRIVATE_KEY;
+        }
+    }
+#endif
+
+    return WOLFSSL_SUCCESS;
+}
+
+/* returns new reference count. Arg incr positive=up or negative=down */
+int SSL_CTX_RefCount(WOLFSSL_CTX* ctx, int incr)
+{
+    int refCount;
+
+    if (ctx == NULL) {
+        return BAD_FUNC_ARG;
+    }
+
+    if (wc_LockMutex(&ctx->countMutex) != 0) {
+        WOLFSSL_MSG("Couldn't lock CTX count mutex");
+        return BAD_MUTEX_E;
+    }
+
+    ctx->refCount += incr;
+    /* make sure refCount is never negative */
+    if (ctx->refCount < 0) {
+        ctx->refCount = 0;
+    }
+    refCount = ctx->refCount;
+
+    wc_UnLockMutex(&ctx->countMutex);
+
+    return refCount;
+}
+
+/* This function inherits a WOLFSSL_CTX's fields into an SSL object.
+   It is used during initialization and to switch an ssl's CTX with
+   wolfSSL_Set_SSL_CTX.  Requires ssl->suites alloc and ssl-arrays with PSK
+   unless writeDup is on.
+
+   ssl      object to initialize
+   ctx      parent factory
+   writeDup flag indicating this is a write dup only
+
+   WOLFSSL_SUCCESS return value on success */
+int SetSSL_CTX(WOLFSSL* ssl, WOLFSSL_CTX* ctx, int writeDup)
+{
+    int ret;
+    byte newSSL;
+
+    if (!ssl || !ctx)
+        return BAD_FUNC_ARG;
+
+#ifndef SINGLE_THREADED
+    if (ssl->suites == NULL && !writeDup)
+        return BAD_FUNC_ARG;
+#endif
+
+    newSSL = ssl->ctx == NULL; /* Assign after null check */
+
+#ifndef NO_PSK
+    if (ctx->server_hint[0] && ssl->arrays == NULL && !writeDup) {
+        return BAD_FUNC_ARG;  /* needed for copy below */
+    }
+#endif
+
+    /* decrement previous CTX reference count if exists.
+     * This should only happen if switching ctxs!*/
+    if (!newSSL) {
+        WOLFSSL_MSG("freeing old ctx to decrement reference count. Switching ctx.");
+        wolfSSL_CTX_free(ssl->ctx);
+    }
+
+    /* increment CTX reference count */
+    if ((ret = SSL_CTX_RefCount(ctx, 1)) < 0) {
+        return ret;
+    }
+    ret = WOLFSSL_SUCCESS; /* set default ret */
+
+    ssl->ctx     = ctx; /* only for passing to calls, options could change */
+    ssl->version = ctx->method->version;
+
+#ifdef HAVE_ECC
+    ssl->eccTempKeySz = ctx->eccTempKeySz;
+    ssl->ecdhCurveOID = ctx->ecdhCurveOID;
+#endif
+#if defined(HAVE_ECC) || defined(HAVE_ED25519) || defined(HAVE_ED448)
+    ssl->pkCurveOID = ctx->pkCurveOID;
+#endif
+
+#ifdef OPENSSL_EXTRA
+    ssl->options.mask = ctx->mask;
+    ssl->CBIS         = ctx->CBIS;
+#endif
+    ssl->timeout = ctx->timeout;
+    ssl->verifyCallback    = ctx->verifyCallback;
+    ssl->options.side      = ctx->method->side;
+    ssl->options.downgrade    = ctx->method->downgrade;
+    ssl->options.minDowngrade = ctx->minDowngrade;
+
+    ssl->options.haveDH        = ctx->haveDH;
+    ssl->options.haveNTRU      = ctx->haveNTRU;
+    ssl->options.haveECDSAsig  = ctx->haveECDSAsig;
+    ssl->options.haveECC       = ctx->haveECC;
+    ssl->options.haveStaticECC = ctx->haveStaticECC;
+
+#ifndef NO_PSK
+    ssl->options.havePSK   = ctx->havePSK;
+    ssl->options.client_psk_cb = ctx->client_psk_cb;
+    ssl->options.server_psk_cb = ctx->server_psk_cb;
+#ifdef WOLFSSL_TLS13
+    ssl->options.client_psk_tls13_cb = ctx->client_psk_tls13_cb;
+    ssl->options.server_psk_tls13_cb = ctx->server_psk_tls13_cb;
+#endif
+#endif /* NO_PSK */
+#ifdef WOLFSSL_EARLY_DATA
+    if (ssl->options.side == WOLFSSL_SERVER_END)
+        ssl->options.maxEarlyDataSz = ctx->maxEarlyDataSz;
+#endif
+
+#ifdef HAVE_ANON
+    ssl->options.haveAnon = ctx->haveAnon;
+#endif
+#ifndef NO_DH
+    ssl->options.minDhKeySz = ctx->minDhKeySz;
+    ssl->options.maxDhKeySz = ctx->maxDhKeySz;
+#endif
+#ifndef NO_RSA
+    ssl->options.minRsaKeySz = ctx->minRsaKeySz;
+#endif
+#ifdef HAVE_ECC
+    ssl->options.minEccKeySz = ctx->minEccKeySz;
+#endif
+#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
+    ssl->options.verifyDepth = ctx->verifyDepth;
+#endif
+
+    ssl->options.sessionCacheOff      = ctx->sessionCacheOff;
+    ssl->options.sessionCacheFlushOff = ctx->sessionCacheFlushOff;
+#ifdef HAVE_EXT_CACHE
+    ssl->options.internalCacheOff     = ctx->internalCacheOff;
+#endif
+
+    ssl->options.verifyPeer     = ctx->verifyPeer;
+    ssl->options.verifyNone     = ctx->verifyNone;
+    ssl->options.failNoCert     = ctx->failNoCert;
+    ssl->options.failNoCertxPSK = ctx->failNoCertxPSK;
+    ssl->options.sendVerify     = ctx->sendVerify;
+
+    ssl->options.partialWrite  = ctx->partialWrite;
+    ssl->options.quietShutdown = ctx->quietShutdown;
+    ssl->options.groupMessages = ctx->groupMessages;
+
+#ifndef NO_DH
+    #if !defined(WOLFSSL_OLD_PRIME_CHECK) && !defined(HAVE_FIPS) && \
+        !defined(HAVE_SELFTEST)
+        ssl->options.dhKeyTested = ctx->dhKeyTested;
+    #endif
+    ssl->buffers.serverDH_P = ctx->serverDH_P;
+    ssl->buffers.serverDH_G = ctx->serverDH_G;
+#endif
+
+#ifndef NO_CERTS
+    /* ctx still owns certificate, certChain, key, dh, and cm */
+    ssl->buffers.certificate = ctx->certificate;
+    ssl->buffers.certChain = ctx->certChain;
+#ifdef WOLFSSL_TLS13
+    ssl->buffers.certChainCnt = ctx->certChainCnt;
+#endif
+    ssl->buffers.key      = ctx->privateKey;
+    ssl->buffers.keyType  = ctx->privateKeyType;
+    ssl->buffers.keyId    = ctx->privateKeyId;
+    ssl->buffers.keySz    = ctx->privateKeySz;
+    ssl->buffers.keyDevId = ctx->privateKeyDevId;
+#endif
+#if !defined(WOLFSSL_NO_CLIENT_AUTH) && \
+               ((defined(HAVE_ED25519) && !defined(NO_ED25519_CLIENT_AUTH)) || \
+                (defined(HAVE_ED448) && !defined(NO_ED448_CLIENT_AUTH)))
+    ssl->options.cacheMessages = ssl->options.side == WOLFSSL_SERVER_END ||
+                                      ssl->buffers.keyType == ed25519_sa_algo ||
+                                      ssl->buffers.keyType == ed448_sa_algo;
+#endif
+
+
+#ifdef WOLFSSL_ASYNC_CRYPT
+    ssl->devId = ctx->devId;
+#endif
+
+    if (writeDup == 0) {
+#ifndef NO_PSK
+        if (ctx->server_hint[0]) {   /* set in CTX */
+            XSTRNCPY(ssl->arrays->server_hint, ctx->server_hint,
+                                    sizeof(ssl->arrays->server_hint));
+            ssl->arrays->server_hint[MAX_PSK_ID_LEN] = '\0'; /* null term */
+        }
+#endif /* NO_PSK */
+
+        if (ctx->suites) {
+#ifndef SINGLE_THREADED
+            *ssl->suites = *ctx->suites;
+#else
+            ssl->suites = ctx->suites;
+#endif
+        }
+        else {
+            XMEMSET(ssl->suites, 0, sizeof(Suites));
+        }
+
+        if (ssl->options.side != WOLFSSL_NEITHER_END) {
+            /* Defer initializing suites until accept or connect */
+            ret = InitSSL_Suites(ssl);
+        }
+    }  /* writeDup check */
+
+#ifdef WOLFSSL_SESSION_EXPORT
+    #ifdef WOLFSSL_DTLS
+    ssl->dtls_export = ctx->dtls_export; /* export function for session */
+    #endif
+#endif
+
+    ssl->CBIORecv = ctx->CBIORecv;
+    ssl->CBIOSend = ctx->CBIOSend;
+#ifdef OPENSSL_EXTRA
+    ssl->readAhead = ctx->readAhead;
+#endif
+    ssl->verifyDepth = ctx->verifyDepth;
+
+    return ret;
+}
+
+int InitHandshakeHashes(WOLFSSL* ssl)
+{
+    int ret;
+
+    /* make sure existing handshake hashes are free'd */
+    if (ssl->hsHashes != NULL) {
+        FreeHandshakeHashes(ssl);
+    }
+
+    /* allocate handshake hashes */
+    ssl->hsHashes = (HS_Hashes*)XMALLOC(sizeof(HS_Hashes), ssl->heap,
+                                                           DYNAMIC_TYPE_HASHES);
+    if (ssl->hsHashes == NULL) {
+        WOLFSSL_MSG("HS_Hashes Memory error");
+        return MEMORY_E;
+    }
+    XMEMSET(ssl->hsHashes, 0, sizeof(HS_Hashes));
+
+#ifndef NO_OLD_TLS
+#ifndef NO_MD5
+    ret = wc_InitMd5_ex(&ssl->hsHashes->hashMd5, ssl->heap, ssl->devId);
+    if (ret != 0)
+        return ret;
+    #if defined(WOLFSSL_HASH_FLAGS) || defined(WOLF_CRYPTO_CB)
+        wc_Md5SetFlags(&ssl->hsHashes->hashMd5, WC_HASH_FLAG_WILLCOPY);
+    #endif
+#endif
+#ifndef NO_SHA
+    ret = wc_InitSha_ex(&ssl->hsHashes->hashSha, ssl->heap, ssl->devId);
+    if (ret != 0)
+        return ret;
+    #if defined(WOLFSSL_HASH_FLAGS) || defined(WOLF_CRYPTO_CB)
+        wc_ShaSetFlags(&ssl->hsHashes->hashSha, WC_HASH_FLAG_WILLCOPY);
+    #endif
+#endif
+#endif /* !NO_OLD_TLS */
+#ifndef NO_SHA256
+    ret = wc_InitSha256_ex(&ssl->hsHashes->hashSha256, ssl->heap, ssl->devId);
+    if (ret != 0)
+        return ret;
+    #if defined(WOLFSSL_HASH_FLAGS) || defined(WOLF_CRYPTO_CB)
+        wc_Sha256SetFlags(&ssl->hsHashes->hashSha256, WC_HASH_FLAG_WILLCOPY);
+    #endif
+#endif
+#ifdef WOLFSSL_SHA384
+    ret = wc_InitSha384_ex(&ssl->hsHashes->hashSha384, ssl->heap, ssl->devId);
+    if (ret != 0)
+        return ret;
+    #if defined(WOLFSSL_HASH_FLAGS) || defined(WOLF_CRYPTO_CB)
+        wc_Sha384SetFlags(&ssl->hsHashes->hashSha384, WC_HASH_FLAG_WILLCOPY);
+    #endif
+#endif
+#ifdef WOLFSSL_SHA512
+    ret = wc_InitSha512_ex(&ssl->hsHashes->hashSha512, ssl->heap, ssl->devId);
+    if (ret != 0)
+        return ret;
+    #if defined(WOLFSSL_HASH_FLAGS) || defined(WOLF_CRYPTO_CB)
+        wc_Sha512SetFlags(&ssl->hsHashes->hashSha512, WC_HASH_FLAG_WILLCOPY);
+    #endif
+#endif
+
+    return ret;
+}
+
+void FreeHandshakeHashes(WOLFSSL* ssl)
+{
+    if (ssl->hsHashes) {
+#ifndef NO_OLD_TLS
+    #ifndef NO_MD5
+        wc_Md5Free(&ssl->hsHashes->hashMd5);
+    #endif
+    #ifndef NO_SHA
+        wc_ShaFree(&ssl->hsHashes->hashSha);
+    #endif
+#endif /* !NO_OLD_TLS */
+    #ifndef NO_SHA256
+        wc_Sha256Free(&ssl->hsHashes->hashSha256);
+    #endif
+    #ifdef WOLFSSL_SHA384
+        wc_Sha384Free(&ssl->hsHashes->hashSha384);
+    #endif
+    #ifdef WOLFSSL_SHA512
+        wc_Sha512Free(&ssl->hsHashes->hashSha512);
+    #endif
+    #if (defined(HAVE_ED25519) || defined(HAVE_ED448)) && \
+                                                !defined(WOLFSSL_NO_CLIENT_AUTH)
+        if (ssl->hsHashes->messages != NULL) {
+            XFREE(ssl->hsHashes->messages, ssl->heap, DYNAMIC_TYPE_HASHES);
+            ssl->hsHashes->messages = NULL;
+         }
+    #endif
+
+        XFREE(ssl->hsHashes, ssl->heap, DYNAMIC_TYPE_HASHES);
+        ssl->hsHashes = NULL;
+    }
+}
+
+
+/* init everything to 0, NULL, default values before calling anything that may
+   fail so that destructor has a "good" state to cleanup
+
+   ssl      object to initialize
+   ctx      parent factory
+   writeDup flag indicating this is a write dup only
+
+   0 on success */
+int InitSSL(WOLFSSL* ssl, WOLFSSL_CTX* ctx, int writeDup)
+{
+    int  ret;
+
+    XMEMSET(ssl, 0, sizeof(WOLFSSL));
+
+#if defined(WOLFSSL_STATIC_MEMORY)
+    if (ctx->heap != NULL) {
+        WOLFSSL_HEAP_HINT* ssl_hint;
+        WOLFSSL_HEAP_HINT* ctx_hint;
+
+        /* avoid dereferencing a test value */
+    #ifdef WOLFSSL_HEAP_TEST
+        if (ctx->heap == (void*)WOLFSSL_HEAP_TEST) {
+            ssl->heap = ctx->heap;
+        }
+        else {
+    #endif
+        ssl->heap = (WOLFSSL_HEAP_HINT*)XMALLOC(sizeof(WOLFSSL_HEAP_HINT),
+                                               ctx->heap, DYNAMIC_TYPE_SSL);
+        if (ssl->heap == NULL) {
+            return MEMORY_E;
+        }
+        XMEMSET(ssl->heap, 0, sizeof(WOLFSSL_HEAP_HINT));
+        ssl_hint = ((WOLFSSL_HEAP_HINT*)(ssl->heap));
+        ctx_hint = ((WOLFSSL_HEAP_HINT*)(ctx->heap));
+
+        /* lock and check IO count / handshake count */
+        if (wc_LockMutex(&(ctx_hint->memory->memory_mutex)) != 0) {
+            WOLFSSL_MSG("Bad memory_mutex lock");
+            XFREE(ssl->heap, ctx->heap, DYNAMIC_TYPE_SSL);
+            ssl->heap = NULL; /* free and set to NULL for IO counter */
+            return BAD_MUTEX_E;
+        }
+        if (ctx_hint->memory->maxHa > 0 &&
+                           ctx_hint->memory->maxHa <= ctx_hint->memory->curHa) {
+            WOLFSSL_MSG("At max number of handshakes for static memory");
+            wc_UnLockMutex(&(ctx_hint->memory->memory_mutex));
+            XFREE(ssl->heap, ctx->heap, DYNAMIC_TYPE_SSL);
+            ssl->heap = NULL; /* free and set to NULL for IO counter */
+            return MEMORY_E;
+        }
+
+        if (ctx_hint->memory->maxIO > 0 &&
+                           ctx_hint->memory->maxIO <= ctx_hint->memory->curIO) {
+            WOLFSSL_MSG("At max number of IO allowed for static memory");
+            wc_UnLockMutex(&(ctx_hint->memory->memory_mutex));
+            XFREE(ssl->heap, ctx->heap, DYNAMIC_TYPE_SSL);
+            ssl->heap = NULL; /* free and set to NULL for IO counter */
+            return MEMORY_E;
+        }
+        ctx_hint->memory->curIO++;
+        ctx_hint->memory->curHa++;
+        ssl_hint->memory = ctx_hint->memory;
+        ssl_hint->haFlag = 1;
+        wc_UnLockMutex(&(ctx_hint->memory->memory_mutex));
+
+        /* check if tracking stats */
+        if (ctx_hint->memory->flag & WOLFMEM_TRACK_STATS) {
+            ssl_hint->stats = (WOLFSSL_MEM_CONN_STATS*)XMALLOC(
+               sizeof(WOLFSSL_MEM_CONN_STATS), ctx->heap, DYNAMIC_TYPE_SSL);
+            if (ssl_hint->stats == NULL) {
+                return MEMORY_E;
+            }
+            XMEMSET(ssl_hint->stats, 0, sizeof(WOLFSSL_MEM_CONN_STATS));
+        }
+
+        /* check if using fixed IO buffers */
+        if (ctx_hint->memory->flag & WOLFMEM_IO_POOL_FIXED) {
+            if (wc_LockMutex(&(ctx_hint->memory->memory_mutex)) != 0) {
+                WOLFSSL_MSG("Bad memory_mutex lock");
+                return BAD_MUTEX_E;
+            }
+            if (SetFixedIO(ctx_hint->memory, &(ssl_hint->inBuf)) != 1) {
+                wc_UnLockMutex(&(ctx_hint->memory->memory_mutex));
+                return MEMORY_E;
+            }
+            if (SetFixedIO(ctx_hint->memory, &(ssl_hint->outBuf)) != 1) {
+                wc_UnLockMutex(&(ctx_hint->memory->memory_mutex));
+                return MEMORY_E;
+            }
+            if (ssl_hint->outBuf == NULL || ssl_hint->inBuf == NULL) {
+                WOLFSSL_MSG("Not enough memory to create fixed IO buffers");
+                wc_UnLockMutex(&(ctx_hint->memory->memory_mutex));
+                return MEMORY_E;
+            }
+            wc_UnLockMutex(&(ctx_hint->memory->memory_mutex));
+        }
+    #ifdef WOLFSSL_HEAP_TEST
+        }
+    #endif
+    }
+    else {
+        ssl->heap = ctx->heap;
+    }
+#else
+    ssl->heap = ctx->heap; /* carry over user heap without static memory */
+#endif /* WOLFSSL_STATIC_MEMORY */
+
+    ssl->buffers.inputBuffer.buffer = ssl->buffers.inputBuffer.staticBuffer;
+    ssl->buffers.inputBuffer.bufferSize  = STATIC_BUFFER_LEN;
+
+    ssl->buffers.outputBuffer.buffer = ssl->buffers.outputBuffer.staticBuffer;
+    ssl->buffers.outputBuffer.bufferSize  = STATIC_BUFFER_LEN;
+
+#ifdef KEEP_PEER_CERT
+    InitX509(&ssl->peerCert, 0, ssl->heap);
+#endif
+
+    ssl->rfd = -1;   /* set to invalid descriptor */
+    ssl->wfd = -1;
+    ssl->devId = ctx->devId; /* device for async HW (from wolfAsync_DevOpen) */
+
+    ssl->IOCB_ReadCtx  = &ssl->rfd;  /* prevent invalid pointer access if not */
+    ssl->IOCB_WriteCtx = &ssl->wfd;  /* correctly set */
+
+#ifdef HAVE_NETX
+    ssl->IOCB_ReadCtx  = &ssl->nxCtx;  /* default NetX IO ctx, same for read */
+    ssl->IOCB_WriteCtx = &ssl->nxCtx;  /* and write */
+#elif defined(WOLFSSL_APACHE_MYNEWT) && !defined(WOLFSSL_LWIP)
+    ssl->mnCtx = mynewt_ctx_new();
+    if(!ssl->mnCtx) {
+        return MEMORY_E;
+    }
+    ssl->IOCB_ReadCtx  = ssl->mnCtx;  /* default Mynewt IO ctx, same for read */
+    ssl->IOCB_WriteCtx = ssl->mnCtx;  /* and write */
+#elif defined (WOLFSSL_GNRC)
+    ssl->IOCB_ReadCtx = ssl->gnrcCtx;
+    ssl->IOCB_WriteCtx = ssl->gnrcCtx;
+#endif
+    /* initialize states */
+    ssl->options.serverState = NULL_STATE;
+    ssl->options.clientState = NULL_STATE;
+    ssl->options.connectState = CONNECT_BEGIN;
+    ssl->options.acceptState  = ACCEPT_BEGIN;
+    ssl->options.handShakeState  = NULL_STATE;
+    ssl->options.processReply = doProcessInit;
+    ssl->options.asyncState = TLS_ASYNC_BEGIN;
+    ssl->options.buildMsgState = BUILD_MSG_BEGIN;
+    ssl->encrypt.state = CIPHER_STATE_BEGIN;
+    ssl->decrypt.state = CIPHER_STATE_BEGIN;
+#ifndef NO_DH
+    #if !defined(WOLFSSL_OLD_PRIME_CHECK) && !defined(HAVE_FIPS) && \
+        !defined(HAVE_SELFTEST)
+        ssl->options.dhDoKeyTest = 1;
+    #endif
+#endif
+
+#ifdef WOLFSSL_DTLS
+    #ifdef WOLFSSL_SCTP
+        ssl->options.dtlsSctp           = ctx->dtlsSctp;
+    #endif
+    #if defined(WOLFSSL_SCTP) || defined(WOLFSSL_DTLS_MTU)
+        ssl->dtlsMtuSz                  = ctx->dtlsMtuSz;
+        ssl->dtls_expected_rx           = ssl->dtlsMtuSz;
+    #else
+        ssl->dtls_expected_rx = MAX_MTU;
+    #endif
+    ssl->dtls_timeout_init              = DTLS_TIMEOUT_INIT;
+    ssl->dtls_timeout_max               = DTLS_TIMEOUT_MAX;
+    ssl->dtls_timeout                   = ssl->dtls_timeout_init;
+    ssl->buffers.dtlsCtx.rfd            = -1;
+    ssl->buffers.dtlsCtx.wfd            = -1;
+#endif
+
+#ifndef WOLFSSL_AEAD_ONLY
+    #ifndef NO_OLD_TLS
+        ssl->hmac = SSL_hmac; /* default to SSLv3 */
+    #elif !defined(WOLFSSL_NO_TLS12)
+        ssl->hmac = TLS_hmac;
+    #endif
+#endif
+
+
+    ssl->cipher.ssl = ssl;
+
+#ifdef HAVE_EXTENDED_MASTER
+    ssl->options.haveEMS = ctx->haveEMS;
+#endif
+    ssl->options.useClientOrder = ctx->useClientOrder;
+    ssl->options.mutualAuth = ctx->mutualAuth;
+
+#ifdef WOLFSSL_TLS13
+    #ifdef HAVE_SESSION_TICKET
+        ssl->options.noTicketTls13 = ctx->noTicketTls13;
+    #endif
+    ssl->options.noPskDheKe = ctx->noPskDheKe;
+    #if defined(WOLFSSL_POST_HANDSHAKE_AUTH)
+        ssl->options.postHandshakeAuth = ctx->postHandshakeAuth;
+    #endif
+
+    if (ctx->numGroups > 0) {
+        XMEMCPY(ssl->group, ctx->group, sizeof(*ctx->group) * ctx->numGroups);
+        ssl->numGroups = ctx->numGroups;
+    }
+#endif
+
+#ifdef HAVE_TLS_EXTENSIONS
+#ifdef HAVE_MAX_FRAGMENT
+    ssl->max_fragment = MAX_RECORD_SIZE;
+#endif
+#ifdef HAVE_ALPN
+    ssl->alpn_client_list = NULL;
+    #if defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY)
+        ssl->alpnSelect    = ctx->alpnSelect;
+        ssl->alpnSelectArg = ctx->alpnSelectArg;
+    #endif
+#endif
+#ifdef HAVE_SUPPORTED_CURVES
+    ssl->options.userCurves = ctx->userCurves;
+#endif
+#endif /* HAVE_TLS_EXTENSIONS */
+
+#if defined(HAVE_ENCRYPT_THEN_MAC) && !defined(WOLFSSL_AEAD_ONLY)
+    ssl->options.disallowEncThenMac = ctx->disallowEncThenMac;
+#endif
+
+    /* default alert state (none) */
+    ssl->alert_history.last_rx.code  = -1;
+    ssl->alert_history.last_rx.level = -1;
+    ssl->alert_history.last_tx.code  = -1;
+    ssl->alert_history.last_tx.level = -1;
+
+#ifdef OPENSSL_EXTRA
+    /* copy over application session context ID */
+    ssl->sessionCtxSz = ctx->sessionCtxSz;
+    XMEMCPY(ssl->sessionCtx, ctx->sessionCtx, ctx->sessionCtxSz);
+    ssl->cbioFlag = ctx->cbioFlag;
+
+#endif
+
+    InitCiphers(ssl);
+    InitCipherSpecs(&ssl->specs);
+
+    /* all done with init, now can return errors, call other stuff */
+
+    if (!writeDup) {
+        /* arrays */
+        ssl->arrays = (Arrays*)XMALLOC(sizeof(Arrays), ssl->heap,
+                                                           DYNAMIC_TYPE_ARRAYS);
+        if (ssl->arrays == NULL) {
+            WOLFSSL_MSG("Arrays Memory error");
+            return MEMORY_E;
+        }
+        XMEMSET(ssl->arrays, 0, sizeof(Arrays));
+#if defined(WOLFSSL_TLS13) || defined(WOLFSSL_SNIFFER)
+        ssl->arrays->preMasterSz = ENCRYPT_LEN;
+        ssl->arrays->preMasterSecret = (byte*)XMALLOC(ENCRYPT_LEN, ssl->heap,
+            DYNAMIC_TYPE_SECRET);
+        if (ssl->arrays->preMasterSecret == NULL) {
+            return MEMORY_E;
+        }
+        XMEMSET(ssl->arrays->preMasterSecret, 0, ENCRYPT_LEN);
+#endif
+
+#ifdef OPENSSL_EXTRA
+    if ((ssl->param = (WOLFSSL_X509_VERIFY_PARAM*)XMALLOC(
+                           sizeof(WOLFSSL_X509_VERIFY_PARAM),
+                           ssl->heap, DYNAMIC_TYPE_OPENSSL)) == NULL) {
+        WOLFSSL_MSG("ssl->param memory error");
+        return MEMORY_E;
+    }
+    XMEMSET(ssl->param, 0, sizeof(WOLFSSL_X509_VERIFY_PARAM));
+#endif
+
+#ifdef SINGLE_THREADED
+        if (ctx->suites == NULL)
+#endif
+        {
+            /* suites */
+            ssl->suites = (Suites*)XMALLOC(sizeof(Suites), ssl->heap,
+                                       DYNAMIC_TYPE_SUITES);
+            if (ssl->suites == NULL) {
+                WOLFSSL_MSG("Suites Memory error");
+                return MEMORY_E;
+            }
+        #ifdef OPENSSL_ALL
+            ssl->suites->stack = NULL;
+        #endif
+#ifdef SINGLE_THREADED
+            ssl->options.ownSuites = 1;
+#endif
+        }
+#ifdef SINGLE_THREADED
+        else {
+            ssl->options.ownSuites = 0;
+        }
+#endif
+    }
+
+    /* Initialize SSL with the appropriate fields from it's ctx */
+    /* requires valid arrays and suites unless writeDup ing */
+    if ((ret =  SetSSL_CTX(ssl, ctx, writeDup)) != WOLFSSL_SUCCESS)
+        return ret;
+
+    ssl->options.dtls = ssl->version.major == DTLS_MAJOR;
+
+#ifdef SINGLE_THREADED
+    ssl->rng = ctx->rng;   /* CTX may have one, if so use it */
+#endif
+
+    if (ssl->rng == NULL) {
+        /* RNG */
+        ssl->rng = (WC_RNG*)XMALLOC(sizeof(WC_RNG), ssl->heap,DYNAMIC_TYPE_RNG);
+        if (ssl->rng == NULL) {
+            WOLFSSL_MSG("RNG Memory error");
+            return MEMORY_E;
+        }
+        XMEMSET(ssl->rng, 0, sizeof(WC_RNG));
+        ssl->options.weOwnRng = 1;
+
+        /* FIPS RNG API does not accept a heap hint */
+#ifndef HAVE_FIPS
+        if ( (ret = wc_InitRng_ex(ssl->rng, ssl->heap, ssl->devId)) != 0) {
+            WOLFSSL_MSG("RNG Init error");
+            return ret;
+        }
+#else
+        if ( (ret = wc_InitRng(ssl->rng)) != 0) {
+            WOLFSSL_MSG("RNG Init error");
+            return ret;
+        }
+#endif
+    }
+
+#ifdef HAVE_WRITE_DUP
+    if (writeDup) {
+        /* all done */
+        return 0;
+    }
+#endif
+
+    /* hsHashes */
+    ret = InitHandshakeHashes(ssl);
+    if (ret != 0)
+        return ret;
+
+#if defined(WOLFSSL_DTLS) && !defined(NO_WOLFSSL_SERVER)
+    if (ssl->options.dtls && ssl->options.side == WOLFSSL_SERVER_END) {
+        ret = wolfSSL_DTLS_SetCookieSecret(ssl, NULL, 0);
+        if (ret != 0) {
+            WOLFSSL_MSG("DTLS Cookie Secret error");
+            return ret;
+        }
+    }
+#endif /* WOLFSSL_DTLS && !NO_WOLFSSL_SERVER */
+
+#ifdef HAVE_SECRET_CALLBACK
+    ssl->sessionSecretCb  = NULL;
+    ssl->sessionSecretCtx = NULL;
+#ifdef WOLFSSL_TLS13
+    ssl->tls13SecretCb  = NULL;
+    ssl->tls13SecretCtx = NULL;
+#endif
+#endif
+
+#ifdef HAVE_SESSION_TICKET
+    ssl->session.ticket = ssl->session.staticTicket;
+#endif
+
+#ifdef WOLFSSL_MULTICAST
+    if (ctx->haveMcast) {
+        int i;
+
+        ssl->options.haveMcast = 1;
+        ssl->options.mcastID = ctx->mcastID;
+
+        /* Force the state to look like handshake has completed. */
+        /* Keying material is supplied externally. */
+        ssl->options.serverState = SERVER_FINISHED_COMPLETE;
+        ssl->options.clientState = CLIENT_FINISHED_COMPLETE;
+        ssl->options.connectState = SECOND_REPLY_DONE;
+        ssl->options.acceptState = ACCEPT_THIRD_REPLY_DONE;
+        ssl->options.handShakeState = HANDSHAKE_DONE;
+        ssl->options.handShakeDone = 1;
+
+        for (i = 0; i < WOLFSSL_DTLS_PEERSEQ_SZ; i++)
+            ssl->keys.peerSeq[i].peerId = INVALID_PEER_ID;
+    }
+#endif
+
+#ifdef HAVE_SECURE_RENEGOTIATION
+    if (ssl->options.side == WOLFSSL_CLIENT_END) {
+        int useSecureReneg = ssl->ctx->useSecureReneg;
+        /* use secure renegotiation by default (not recommend) */
+    #ifdef WOLFSSL_SECURE_RENEGOTIATION_ON_BY_DEFAULT
+        useSecureReneg = 1;
+    #endif
+        if (useSecureReneg) {
+            ret = wolfSSL_UseSecureRenegotiation(ssl);
+            if (ret != WOLFSSL_SUCCESS)
+                return ret;
+            }
+    }
+#endif /* HAVE_SECURE_RENEGOTIATION */
+
+    return 0;
+}
+
+
+/* free use of temporary arrays */
+void FreeArrays(WOLFSSL* ssl, int keep)
+{
+    if (ssl->arrays) {
+        if (keep) {
+            /* keeps session id for user retrieval */
+            XMEMCPY(ssl->session.sessionID, ssl->arrays->sessionID, ID_LEN);
+            ssl->session.sessionIDSz = ssl->arrays->sessionIDSz;
+        }
+        if (ssl->arrays->preMasterSecret) {
+            XFREE(ssl->arrays->preMasterSecret, ssl->heap, DYNAMIC_TYPE_SECRET);
+            ssl->arrays->preMasterSecret = NULL;
+        }
+        XFREE(ssl->arrays->pendingMsg, ssl->heap, DYNAMIC_TYPE_ARRAYS);
+        ssl->arrays->pendingMsg = NULL;
+        ForceZero(ssl->arrays, sizeof(Arrays)); /* clear arrays struct */
+    }
+    XFREE(ssl->arrays, ssl->heap, DYNAMIC_TYPE_ARRAYS);
+    ssl->arrays = NULL;
+}
+
+void FreeKey(WOLFSSL* ssl, int type, void** pKey)
+{
+    if (ssl && pKey && *pKey) {
+        switch (type) {
+        #ifndef NO_RSA
+            case DYNAMIC_TYPE_RSA:
+                wc_FreeRsaKey((RsaKey*)*pKey);
+                break;
+        #endif /* ! NO_RSA */
+        #ifdef HAVE_ECC
+            case DYNAMIC_TYPE_ECC:
+                wc_ecc_free((ecc_key*)*pKey);
+                break;
+        #endif /* HAVE_ECC */
+        #ifdef HAVE_ED25519
+            case DYNAMIC_TYPE_ED25519:
+                wc_ed25519_free((ed25519_key*)*pKey);
+                break;
+        #endif /* HAVE_ED25519 */
+        #ifdef HAVE_CURVE25519
+            case DYNAMIC_TYPE_CURVE25519:
+                wc_curve25519_free((curve25519_key*)*pKey);
+                break;
+        #endif /* HAVE_CURVE25519 */
+        #ifdef HAVE_ED448
+            case DYNAMIC_TYPE_ED448:
+                wc_ed448_free((ed448_key*)*pKey);
+                break;
+        #endif /* HAVE_ED448 */
+        #ifdef HAVE_CURVE448
+            case DYNAMIC_TYPE_CURVE448:
+                wc_curve448_free((curve448_key*)*pKey);
+                break;
+        #endif /* HAVE_CURVE448 */
+        #ifndef NO_DH
+            case DYNAMIC_TYPE_DH:
+                wc_FreeDhKey((DhKey*)*pKey);
+                break;
+        #endif /* !NO_DH */
+            default:
+                break;
+        }
+        XFREE(*pKey, ssl->heap, type);
+
+        /* Reset pointer */
+        *pKey = NULL;
+    }
+}
+
+int AllocKey(WOLFSSL* ssl, int type, void** pKey)
+{
+    int ret = BAD_FUNC_ARG;
+    int sz = 0;
+
+    if (ssl == NULL || pKey == NULL) {
+        return BAD_FUNC_ARG;
+    }
+
+    /* Sanity check key destination */
+    if (*pKey != NULL) {
+        WOLFSSL_MSG("Key already present!");
+        return BAD_STATE_E;
+    }
+
+    /* Determine size */
+    switch (type) {
+    #ifndef NO_RSA
+        case DYNAMIC_TYPE_RSA:
+            sz = sizeof(RsaKey);
+            break;
+    #endif /* ! NO_RSA */
+    #ifdef HAVE_ECC
+        case DYNAMIC_TYPE_ECC:
+            sz = sizeof(ecc_key);
+            break;
+    #endif /* HAVE_ECC */
+    #ifdef HAVE_ED25519
+        case DYNAMIC_TYPE_ED25519:
+            sz = sizeof(ed25519_key);
+            break;
+    #endif /* HAVE_ED25519 */
+    #ifdef HAVE_CURVE25519
+        case DYNAMIC_TYPE_CURVE25519:
+            sz = sizeof(curve25519_key);
+            break;
+    #endif /* HAVE_CURVE25519 */
+    #ifdef HAVE_ED448
+        case DYNAMIC_TYPE_ED448:
+            sz = sizeof(ed448_key);
+            break;
+    #endif /* HAVE_ED448 */
+    #ifdef HAVE_CURVE448
+        case DYNAMIC_TYPE_CURVE448:
+            sz = sizeof(curve448_key);
+            break;
+    #endif /* HAVE_CURVE448 */
+    #ifndef NO_DH
+        case DYNAMIC_TYPE_DH:
+            sz = sizeof(DhKey);
+            break;
+    #endif /* !NO_DH */
+        default:
+            return BAD_FUNC_ARG;
+    }
+
+    if (sz == 0) {
+        return NOT_COMPILED_IN;
+    }
+
+    /* Allocate memory for key */
+    *pKey = XMALLOC(sz, ssl->heap, type);
+    if (*pKey == NULL) {
+        return MEMORY_E;
+    }
+
+    /* Initialize key */
+    switch (type) {
+    #ifndef NO_RSA
+        case DYNAMIC_TYPE_RSA:
+            ret = wc_InitRsaKey_ex((RsaKey*)*pKey, ssl->heap, ssl->devId);
+            break;
+    #endif /* ! NO_RSA */
+    #ifdef HAVE_ECC
+        case DYNAMIC_TYPE_ECC:
+            ret = wc_ecc_init_ex((ecc_key*)*pKey, ssl->heap, ssl->devId);
+            break;
+    #endif /* HAVE_ECC */
+    #ifdef HAVE_ED25519
+        case DYNAMIC_TYPE_ED25519:
+            wc_ed25519_init((ed25519_key*)*pKey);
+            ret = 0;
+            break;
+    #endif /* HAVE_CURVE25519 */
+    #ifdef HAVE_CURVE25519
+        case DYNAMIC_TYPE_CURVE25519:
+            wc_curve25519_init((curve25519_key*)*pKey);
+            ret = 0;
+            break;
+    #endif /* HAVE_CURVE25519 */
+    #ifdef HAVE_ED448
+        case DYNAMIC_TYPE_ED448:
+            wc_ed448_init((ed448_key*)*pKey);
+            ret = 0;
+            break;
+    #endif /* HAVE_CURVE448 */
+    #ifdef HAVE_CURVE448
+        case DYNAMIC_TYPE_CURVE448:
+            wc_curve448_init((curve448_key*)*pKey);
+            ret = 0;
+            break;
+    #endif /* HAVE_CURVE448 */
+    #ifndef NO_DH
+        case DYNAMIC_TYPE_DH:
+            ret = wc_InitDhKey_ex((DhKey*)*pKey, ssl->heap, ssl->devId);
+            break;
+    #endif /* !NO_DH */
+        default:
+            return BAD_FUNC_ARG;
+    }
+
+    /* On error free handshake key */
+    if (ret != 0) {
+        FreeKey(ssl, type, pKey);
+    }
+
+    return ret;
+}
+
+#if !defined(NO_RSA) || defined(HAVE_ECC) || defined(HAVE_ED25519) || \
+    defined(HAVE_CURVE25519) || defined(HHAVE_ED448) || defined(HAVE_CURVE448)
+static int ReuseKey(WOLFSSL* ssl, int type, void* pKey)
+{
+    int ret = 0;
+
+    (void)ssl;
+
+    switch (type) {
+    #ifndef NO_RSA
+        case DYNAMIC_TYPE_RSA:
+            wc_FreeRsaKey((RsaKey*)pKey);
+            ret = wc_InitRsaKey_ex((RsaKey*)pKey, ssl->heap, ssl->devId);
+            break;
+    #endif /* ! NO_RSA */
+    #ifdef HAVE_ECC
+        case DYNAMIC_TYPE_ECC:
+            wc_ecc_free((ecc_key*)pKey);
+            ret = wc_ecc_init_ex((ecc_key*)pKey, ssl->heap, ssl->devId);
+            break;
+    #endif /* HAVE_ECC */
+    #ifdef HAVE_ED25519
+        case DYNAMIC_TYPE_ED25519:
+            wc_ed25519_free((ed25519_key*)pKey);
+            ret = wc_ed25519_init((ed25519_key*)pKey);
+            break;
+    #endif /* HAVE_CURVE25519 */
+    #ifdef HAVE_CURVE25519
+        case DYNAMIC_TYPE_CURVE25519:
+            wc_curve25519_free((curve25519_key*)pKey);
+            ret = wc_curve25519_init((curve25519_key*)pKey);
+            break;
+    #endif /* HAVE_CURVE25519 */
+    #ifdef HAVE_ED448
+        case DYNAMIC_TYPE_ED448:
+            wc_ed448_free((ed448_key*)pKey);
+            ret = wc_ed448_init((ed448_key*)pKey);
+            break;
+    #endif /* HAVE_CURVE448 */
+    #ifdef HAVE_CURVE448
+        case DYNAMIC_TYPE_CURVE448:
+            wc_curve448_free((curve448_key*)pKey);
+            ret = wc_curve448_init((curve448_key*)pKey);
+            break;
+    #endif /* HAVE_CURVE448 */
+    #ifndef NO_DH
+        case DYNAMIC_TYPE_DH:
+            wc_FreeDhKey((DhKey*)pKey);
+            ret = wc_InitDhKey_ex((DhKey*)pKey, ssl->heap, ssl->devId);
+            break;
+    #endif /* !NO_DH */
+        default:
+            return BAD_FUNC_ARG;
+    }
+
+    return ret;
+}
+#endif
+
+void FreeKeyExchange(WOLFSSL* ssl)
+{
+    /* Cleanup signature buffer */
+    if (ssl->buffers.sig.buffer) {
+        XFREE(ssl->buffers.sig.buffer, ssl->heap, DYNAMIC_TYPE_SIGNATURE);
+        ssl->buffers.sig.buffer = NULL;
+        ssl->buffers.sig.length = 0;
+    }
+
+    /* Cleanup digest buffer */
+    if (ssl->buffers.digest.buffer) {
+        XFREE(ssl->buffers.digest.buffer, ssl->heap, DYNAMIC_TYPE_DIGEST);
+        ssl->buffers.digest.buffer = NULL;
+        ssl->buffers.digest.length = 0;
+    }
+
+    /* Free handshake key */
+    FreeKey(ssl, ssl->hsType, &ssl->hsKey);
+
+#ifndef NO_DH
+    /* Free temp DH key */
+    FreeKey(ssl, DYNAMIC_TYPE_DH, (void**)&ssl->buffers.serverDH_Key);
+#endif
+
+    /* Cleanup async */
+#ifdef WOLFSSL_ASYNC_CRYPT
+    if (ssl->async.freeArgs) {
+        ssl->async.freeArgs(ssl, ssl->async.args);
+        ssl->async.freeArgs = NULL;
+    }
+#endif
+}
+
+
+/* Free up all memory used by Suites structure from WOLFSSL */
+void FreeSuites(WOLFSSL* ssl)
+{
+#ifdef SINGLE_THREADED
+    if (ssl->options.ownSuites)
+#endif
+    {
+    #ifdef OPENSSL_ALL
+        wolfSSL_sk_SSL_CIPHER_free(ssl->suites->stack);
+    #endif
+        XFREE(ssl->suites, ssl->heap, DYNAMIC_TYPE_SUITES);
+    }
+    ssl->suites = NULL;
+}
+
+
+/* In case holding SSL object in array and don't want to free actual ssl */
+void SSL_ResourceFree(WOLFSSL* ssl)
+{
+    /* Note: any resources used during the handshake should be released in the
+     * function FreeHandshakeResources(). Be careful with the special cases
+     * like the RNG which may optionally be kept for the whole session. (For
+     * example with the RNG, it isn't used beyond the handshake except when
+     * using stream ciphers where it is retained. */
+
+    FreeCiphers(ssl);
+    FreeArrays(ssl, 0);
+    FreeKeyExchange(ssl);
+    if (ssl->options.weOwnRng) {
+        wc_FreeRng(ssl->rng);
+        XFREE(ssl->rng, ssl->heap, DYNAMIC_TYPE_RNG);
+    }
+    FreeSuites(ssl);
+    FreeHandshakeHashes(ssl);
+    XFREE(ssl->buffers.domainName.buffer, ssl->heap, DYNAMIC_TYPE_DOMAIN);
+
+    /* clear keys struct after session */
+    ForceZero(&ssl->keys, sizeof(Keys));
+
+#ifdef WOLFSSL_TLS13
+    if (ssl->options.tls1_3) {
+        ForceZero(&ssl->clientSecret, sizeof(ssl->clientSecret));
+        ForceZero(&ssl->serverSecret, sizeof(ssl->serverSecret));
+    }
+#endif
+
+#ifndef NO_DH
+    if (ssl->buffers.serverDH_Priv.buffer) {
+        ForceZero(ssl->buffers.serverDH_Priv.buffer,
+                                             ssl->buffers.serverDH_Priv.length);
+    }
+    XFREE(ssl->buffers.serverDH_Priv.buffer, ssl->heap, DYNAMIC_TYPE_PRIVATE_KEY);
+    XFREE(ssl->buffers.serverDH_Pub.buffer, ssl->heap, DYNAMIC_TYPE_PUBLIC_KEY);
+    /* parameters (p,g) may be owned by ctx */
+    if (ssl->buffers.weOwnDH) {
+        XFREE(ssl->buffers.serverDH_G.buffer, ssl->heap, DYNAMIC_TYPE_PUBLIC_KEY);
+        XFREE(ssl->buffers.serverDH_P.buffer, ssl->heap, DYNAMIC_TYPE_PUBLIC_KEY);
+    }
+#endif /* !NO_DH */
+#ifndef NO_CERTS
+    ssl->keepCert = 0; /* make sure certificate is free'd */
+    wolfSSL_UnloadCertsKeys(ssl);
+#endif
+#ifndef NO_RSA
+    FreeKey(ssl, DYNAMIC_TYPE_RSA, (void**)&ssl->peerRsaKey);
+    ssl->peerRsaKeyPresent = 0;
+#endif
+#ifdef WOLFSSL_RENESAS_TSIP_TLS
+    XFREE(ssl->peerTsipEncRsaKeyIndex, ssl->heap, DYNAMIC_TYPE_RSA);
+#endif
+    if (ssl->buffers.inputBuffer.dynamicFlag)
+        ShrinkInputBuffer(ssl, FORCED_FREE);
+    if (ssl->buffers.outputBuffer.dynamicFlag)
+        ShrinkOutputBuffer(ssl);
+#if defined(WOLFSSL_SEND_HRR_COOKIE) && !defined(NO_WOLFSSL_SERVER)
+    XFREE(ssl->buffers.tls13CookieSecret.buffer, ssl->heap,
+          DYNAMIC_TYPE_COOKIE_PWD);
+#endif
+#ifdef WOLFSSL_DTLS
+    DtlsMsgPoolReset(ssl);
+    if (ssl->dtls_rx_msg_list != NULL) {
+        DtlsMsgListDelete(ssl->dtls_rx_msg_list, ssl->heap);
+        ssl->dtls_rx_msg_list = NULL;
+        ssl->dtls_rx_msg_list_sz = 0;
+    }
+    XFREE(ssl->buffers.dtlsCtx.peer.sa, ssl->heap, DYNAMIC_TYPE_SOCKADDR);
+    ssl->buffers.dtlsCtx.peer.sa = NULL;
+#ifndef NO_WOLFSSL_SERVER
+    XFREE(ssl->buffers.dtlsCookieSecret.buffer, ssl->heap,
+          DYNAMIC_TYPE_COOKIE_PWD);
+#endif
+#endif /* WOLFSSL_DTLS */
+#ifdef OPENSSL_EXTRA
+    if (ssl->biord != ssl->biowr)        /* only free write if different */
+        wolfSSL_BIO_free(ssl->biowr);
+    wolfSSL_BIO_free(ssl->biord);        /* always free read bio */
+    ssl->biowr = NULL;
+    ssl->biord = NULL;
+#endif
+#ifdef HAVE_LIBZ
+    FreeStreams(ssl);
+#endif
+#ifdef HAVE_ECC
+    FreeKey(ssl, DYNAMIC_TYPE_ECC, (void**)&ssl->peerEccKey);
+    ssl->peerEccKeyPresent = 0;
+    FreeKey(ssl, DYNAMIC_TYPE_ECC, (void**)&ssl->peerEccDsaKey);
+    ssl->peerEccDsaKeyPresent = 0;
+#endif
+#if defined(HAVE_ECC) || defined(HAVE_CURVE25519) ||defined(HAVE_CURVE448)
+    {
+        int dtype = 0;
+    #ifdef HAVE_ECC
+        dtype = DYNAMIC_TYPE_ECC;
+    #endif
+    #ifdef HAVE_CURVE25519
+        if (ssl->peerX25519KeyPresent
+    #ifdef HAVE_ECC
+                           || ssl->eccTempKeyPresent == DYNAMIC_TYPE_CURVE25519
+    #endif /* HAVE_ECC */
+           )
+        {
+            dtype = DYNAMIC_TYPE_CURVE25519;
+        }
+    #endif /* HAVE_CURVE25519 */
+    #ifdef HAVE_CURVE448
+        if (ssl->peerX448KeyPresent
+    #ifdef HAVE_ECC
+                             || ssl->eccTempKeyPresent == DYNAMIC_TYPE_CURVE448
+    #endif /* HAVE_ECC */
+           )
+        {
+            dtype = DYNAMIC_TYPE_CURVE448;
+        }
+    #endif /* HAVE_CURVE448 */
+        FreeKey(ssl, dtype, (void**)&ssl->eccTempKey);
+        ssl->eccTempKeyPresent = 0;
+    }
+#endif /* HAVE_ECC || HAVE_CURVE25519 || HAVE_CURVE448 */
+#ifdef HAVE_CURVE25519
+    FreeKey(ssl, DYNAMIC_TYPE_CURVE25519, (void**)&ssl->peerX25519Key);
+    ssl->peerX25519KeyPresent = 0;
+#endif
+#ifdef HAVE_ED25519
+    FreeKey(ssl, DYNAMIC_TYPE_ED25519, (void**)&ssl->peerEd25519Key);
+    ssl->peerEd25519KeyPresent = 0;
+    #ifdef HAVE_PK_CALLBACKS
+        if (ssl->buffers.peerEd25519Key.buffer != NULL) {
+            XFREE(ssl->buffers.peerEd25519Key.buffer, ssl->heap,
+                                                          DYNAMIC_TYPE_ED25519);
+            ssl->buffers.peerEd25519Key.buffer = NULL;
+        }
+    #endif
+#endif
+#ifdef HAVE_CURVE448
+    FreeKey(ssl, DYNAMIC_TYPE_CURVE448, (void**)&ssl->peerX448Key);
+    ssl->peerX448KeyPresent = 0;
+#endif
+#ifdef HAVE_ED448
+    FreeKey(ssl, DYNAMIC_TYPE_ED448, (void**)&ssl->peerEd448Key);
+    ssl->peerEd448KeyPresent = 0;
+    #ifdef HAVE_PK_CALLBACKS
+        if (ssl->buffers.peerEd448Key.buffer != NULL) {
+            XFREE(ssl->buffers.peerEd448Key.buffer, ssl->heap,
+                                                            DYNAMIC_TYPE_ED448);
+            ssl->buffers.peerEd448Key.buffer = NULL;
+        }
+    #endif
+#endif
+#ifdef HAVE_PK_CALLBACKS
+    #ifdef HAVE_ECC
+        XFREE(ssl->buffers.peerEccDsaKey.buffer, ssl->heap, DYNAMIC_TYPE_ECC);
+    #endif /* HAVE_ECC */
+    #ifndef NO_RSA
+        XFREE(ssl->buffers.peerRsaKey.buffer, ssl->heap, DYNAMIC_TYPE_RSA);
+    #endif /* NO_RSA */
+#endif /* HAVE_PK_CALLBACKS */
+#ifdef HAVE_TLS_EXTENSIONS
+    TLSX_FreeAll(ssl->extensions, ssl->heap);
+
+#ifdef HAVE_ALPN
+    if (ssl->alpn_client_list != NULL) {
+        XFREE(ssl->alpn_client_list, ssl->heap, DYNAMIC_TYPE_ALPN);
+        ssl->alpn_client_list = NULL;
+    }
+#endif
+#endif /* HAVE_TLS_EXTENSIONS */
+#if defined(WOLFSSL_APACHE_MYNEWT) && !defined(WOLFSSL_LWIP)
+    if (ssl->mnCtx) {
+        mynewt_ctx_clear(ssl->mnCtx);
+        ssl->mnCtx = NULL;
+    }
+#endif
+#ifdef HAVE_NETX
+    if (ssl->nxCtx.nxPacket)
+        nx_packet_release(ssl->nxCtx.nxPacket);
+#endif
+#ifdef KEEP_PEER_CERT
+    FreeX509(&ssl->peerCert);
+#endif
+
+#ifdef HAVE_SESSION_TICKET
+    if (ssl->session.isDynamic) {
+        XFREE(ssl->session.ticket, ssl->heap, DYNAMIC_TYPE_SESSION_TICK);
+        ssl->session.ticket = ssl->session.staticTicket;
+        ssl->session.isDynamic = 0;
+        ssl->session.ticketLen = 0;
+    }
+#endif
+#ifdef HAVE_EXT_CACHE
+    wolfSSL_SESSION_free(ssl->extSession);
+#endif
+#ifdef HAVE_WRITE_DUP
+    if (ssl->dupWrite) {
+        FreeWriteDup(ssl);
+    }
+#endif
+#ifdef OPENSSL_EXTRA
+    if (ssl->param) {
+        XFREE(ssl->param, ssl->heap, DYNAMIC_TYPE_OPENSSL);
+    }
+#endif
+#if defined(WOLFSSL_TLS13) && defined(WOLFSSL_POST_HANDSHAKE_AUTH)
+    while (ssl->certReqCtx != NULL) {
+        CertReqCtx* curr = ssl->certReqCtx;
+        ssl->certReqCtx = curr->next;
+        XFREE(curr, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER);
+    }
+#endif
+
+#ifdef WOLFSSL_STATIC_MEMORY
+    /* check if using fixed io buffers and free them */
+    if (ssl->heap != NULL) {
+    #ifdef WOLFSSL_HEAP_TEST
+    /* avoid dereferencing a test value */
+    if (ssl->heap != (void*)WOLFSSL_HEAP_TEST) {
+    #endif
+        WOLFSSL_HEAP_HINT* ssl_hint = (WOLFSSL_HEAP_HINT*)ssl->heap;
+        WOLFSSL_HEAP*      ctx_heap;
+        void* heap = ssl->ctx ? ssl->ctx->heap : ssl->heap;
+
+        ctx_heap = ssl_hint->memory;
+        if (wc_LockMutex(&(ctx_heap->memory_mutex)) != 0) {
+            WOLFSSL_MSG("Bad memory_mutex lock");
+        }
+        ctx_heap->curIO--;
+        if (FreeFixedIO(ctx_heap, &(ssl_hint->outBuf)) != 1) {
+            WOLFSSL_MSG("Error freeing fixed output buffer");
+        }
+        if (FreeFixedIO(ctx_heap, &(ssl_hint->inBuf)) != 1) {
+            WOLFSSL_MSG("Error freeing fixed output buffer");
+        }
+        if (ssl_hint->haFlag) { /* check if handshake count has been decreased*/
+            ctx_heap->curHa--;
+        }
+        wc_UnLockMutex(&(ctx_heap->memory_mutex));
+
+        /* check if tracking stats */
+        if (ctx_heap->flag & WOLFMEM_TRACK_STATS) {
+            XFREE(ssl_hint->stats, heap, DYNAMIC_TYPE_SSL);
+        }
+        XFREE(ssl->heap, heap, DYNAMIC_TYPE_SSL);
+    #ifdef WOLFSSL_HEAP_TEST
+    }
+    #endif
+    }
+#endif /* WOLFSSL_STATIC_MEMORY */
+#if defined(OPENSSL_ALL) || defined(WOLFSSL_QT)
+    wolfSSL_sk_CIPHER_free(ssl->supportedCiphers);
+    wolfSSL_sk_X509_free(ssl->peerCertChain);
+#endif
+}
+
+/* Free any handshake resources no longer needed */
+void FreeHandshakeResources(WOLFSSL* ssl)
+{
+
+#ifdef HAVE_SECURE_RENEGOTIATION
+    if (ssl->secure_renegotiation && ssl->secure_renegotiation->enabled) {
+        WOLFSSL_MSG("Secure Renegotiation needs to retain handshake resources");
+        return;
+    }
+#endif
+
+    /* input buffer */
+    if (ssl->buffers.inputBuffer.dynamicFlag)
+        ShrinkInputBuffer(ssl, NO_FORCED_FREE);
+
+#if defined(WOLFSSL_TLS13) && defined(WOLFSSL_POST_HANDSHAKE_AUTH)
+    if (!ssl->options.tls1_3)
+#endif
+    {
+    #ifndef OPENSSL_ALL
+        /* free suites unless using compatibility layer */
+        FreeSuites(ssl);
+    #endif
+        /* hsHashes */
+        FreeHandshakeHashes(ssl);
+    }
+
+    /* RNG */
+    if (ssl->options.tls1_1 == 0
+#ifndef WOLFSSL_AEAD_ONLY
+        || ssl->specs.cipher_type == stream
+#endif
+#if defined(WOLFSSL_TLS13)
+    #if !defined(WOLFSSL_POST_HANDSHAKE_AUTH)
+        || ssl->options.tls1_3
+    #elif !defined(HAVE_SESSION_TICKET)
+        || (ssl->options.tls1_3 && ssl->options.side == WOLFSSL_SERVER_END)
+    #endif
+#endif
+    ) {
+        if (ssl->options.weOwnRng) {
+            wc_FreeRng(ssl->rng);
+            XFREE(ssl->rng, ssl->heap, DYNAMIC_TYPE_RNG);
+            ssl->rng = NULL;
+            ssl->options.weOwnRng = 0;
+        }
+    }
+
+#ifdef WOLFSSL_DTLS
+    /* DTLS_POOL */
+    if (ssl->options.dtls) {
+        DtlsMsgPoolReset(ssl);
+        DtlsMsgListDelete(ssl->dtls_rx_msg_list, ssl->heap);
+        ssl->dtls_rx_msg_list = NULL;
+        ssl->dtls_rx_msg_list_sz = 0;
+    }
+#endif
+
+#if defined(WOLFSSL_TLS13) && defined(WOLFSSL_POST_HANDSHAKE_AUTH) && \
+                                                    defined(HAVE_SESSION_TICKET)
+    if (!ssl->options.tls1_3)
+#endif
+        /* arrays */
+        if (ssl->options.saveArrays == 0)
+            FreeArrays(ssl, 1);
+
+#if defined(WOLFSSL_TLS13) && defined(WOLFSSL_POST_HANDSHAKE_AUTH)
+    if (!ssl->options.tls1_3 || ssl->options.side == WOLFSSL_CLIENT_END)
+#endif
+    {
+#ifndef NO_RSA
+        /* peerRsaKey */
+        FreeKey(ssl, DYNAMIC_TYPE_RSA, (void**)&ssl->peerRsaKey);
+        ssl->peerRsaKeyPresent = 0;
+#endif
+#ifdef HAVE_ECC
+        FreeKey(ssl, DYNAMIC_TYPE_ECC, (void**)&ssl->peerEccDsaKey);
+        ssl->peerEccDsaKeyPresent = 0;
+#endif /* HAVE_ECC */
+#ifdef HAVE_ED25519
+        FreeKey(ssl, DYNAMIC_TYPE_ED25519, (void**)&ssl->peerEd25519Key);
+        ssl->peerEd25519KeyPresent = 0;
+#endif /* HAVE_ED25519 */
+#ifdef HAVE_ED448
+        FreeKey(ssl, DYNAMIC_TYPE_ED448, (void**)&ssl->peerEd448Key);
+        ssl->peerEd448KeyPresent = 0;
+#endif /* HAVE_ED448 */
+    }
+
+#ifdef HAVE_ECC
+    FreeKey(ssl, DYNAMIC_TYPE_ECC, (void**)&ssl->peerEccKey);
+    ssl->peerEccKeyPresent = 0;
+#endif
+#if defined(HAVE_ECC) || defined(HAVE_CURVE25519) || defined(HAVE_CURVE448)
+    {
+        int dtype;
+    #ifdef HAVE_ECC
+        dtype = DYNAMIC_TYPE_ECC;
+    #endif
+    #ifdef HAVE_CURVE25519
+    #ifdef HAVE_ECC
+        if (ssl->peerX25519KeyPresent ||
+                              ssl->eccTempKeyPresent == DYNAMIC_TYPE_CURVE25519)
+    #endif /* HAVE_ECC */
+         {
+            dtype = DYNAMIC_TYPE_CURVE25519;
+         }
+    #endif /* HAVE_CURVE25519 */
+    #ifdef HAVE_CURVE448
+    #ifdef HAVE_ECC
+        if (ssl->peerX448KeyPresent ||
+                                ssl->eccTempKeyPresent == DYNAMIC_TYPE_CURVE448)
+    #endif /* HAVE_ECC */
+         {
+            dtype = DYNAMIC_TYPE_CURVE448;
+         }
+    #endif /* HAVE_CURVE448 */
+        FreeKey(ssl, dtype, (void**)&ssl->eccTempKey);
+        ssl->eccTempKeyPresent = 0;
+    }
+#endif /* HAVE_ECC || HAVE_CURVE25519 || HAVE_CURVE448 */
+#ifdef HAVE_CURVE25519
+    FreeKey(ssl, DYNAMIC_TYPE_CURVE25519, (void**)&ssl->peerX25519Key);
+    ssl->peerX25519KeyPresent = 0;
+#endif
+#ifdef HAVE_CURVE448
+    FreeKey(ssl, DYNAMIC_TYPE_CURVE448, (void**)&ssl->peerX448Key);
+    ssl->peerX448KeyPresent = 0;
+#endif
+
+#ifndef NO_DH
+    if (ssl->buffers.serverDH_Priv.buffer) {
+        ForceZero(ssl->buffers.serverDH_Priv.buffer,
+                                             ssl->buffers.serverDH_Priv.length);
+    }
+    XFREE(ssl->buffers.serverDH_Priv.buffer, ssl->heap, DYNAMIC_TYPE_PRIVATE_KEY);
+    ssl->buffers.serverDH_Priv.buffer = NULL;
+    XFREE(ssl->buffers.serverDH_Pub.buffer, ssl->heap, DYNAMIC_TYPE_PUBLIC_KEY);
+    ssl->buffers.serverDH_Pub.buffer = NULL;
+    /* parameters (p,g) may be owned by ctx */
+    if (ssl->buffers.weOwnDH) {
+        XFREE(ssl->buffers.serverDH_G.buffer, ssl->heap, DYNAMIC_TYPE_PUBLIC_KEY);
+        ssl->buffers.serverDH_G.buffer = NULL;
+        XFREE(ssl->buffers.serverDH_P.buffer, ssl->heap, DYNAMIC_TYPE_PUBLIC_KEY);
+        ssl->buffers.serverDH_P.buffer = NULL;
+    }
+#endif /* !NO_DH */
+
+#ifndef NO_CERTS
+    wolfSSL_UnloadCertsKeys(ssl);
+#endif
+#ifdef HAVE_PK_CALLBACKS
+#if defined(WOLFSSL_TLS13) && defined(WOLFSSL_POST_HANDSHAKE_AUTH)
+    if (!ssl->options.tls1_3 || ssl->options.side == WOLFSSL_CLIENT_END)
+#endif
+    {
+    #ifdef HAVE_ECC
+        XFREE(ssl->buffers.peerEccDsaKey.buffer, ssl->heap, DYNAMIC_TYPE_ECC);
+        ssl->buffers.peerEccDsaKey.buffer = NULL;
+    #endif /* HAVE_ECC */
+    #ifndef NO_RSA
+        XFREE(ssl->buffers.peerRsaKey.buffer, ssl->heap, DYNAMIC_TYPE_RSA);
+        ssl->buffers.peerRsaKey.buffer = NULL;
+    #endif /* NO_RSA */
+    #ifdef HAVE_ED25519
+        XFREE(ssl->buffers.peerEd25519Key.buffer, ssl->heap,
+                                                          DYNAMIC_TYPE_ED25519);
+        ssl->buffers.peerEd25519Key.buffer = NULL;
+    #endif
+    #ifdef HAVE_ED448
+        XFREE(ssl->buffers.peerEd448Key.buffer, ssl->heap, DYNAMIC_TYPE_ED448);
+        ssl->buffers.peerEd448Key.buffer = NULL;
+    #endif
+    }
+#endif /* HAVE_PK_CALLBACKS */
+
+#ifdef HAVE_QSH
+    QSH_FreeAll(ssl);
+#endif
+
+#ifdef HAVE_SESSION_TICKET
+    if (ssl->session.isDynamic) {
+        XFREE(ssl->session.ticket, ssl->heap, DYNAMIC_TYPE_SESSION_TICK);
+        ssl->session.ticket = ssl->session.staticTicket;
+        ssl->session.isDynamic = 0;
+        ssl->session.ticketLen = 0;
+    }
+#endif
+
+#if defined(HAVE_TLS_EXTENSIONS) && !defined(HAVE_SNI) && \
+                    !defined(HAVE_ALPN) && !defined(WOLFSSL_POST_HANDSHAKE_AUTH)
+    /* Some extensions need to be kept for post-handshake querying. */
+    TLSX_FreeAll(ssl->extensions, ssl->heap);
+    ssl->extensions = NULL;
+#endif
+
+#ifdef WOLFSSL_STATIC_MEMORY
+    /* when done with handshake decrement current handshake count */
+    if (ssl->heap != NULL) {
+    #ifdef WOLFSSL_HEAP_TEST
+    /* avoid dereferencing a test value */
+    if (ssl->heap != (void*)WOLFSSL_HEAP_TEST) {
+    #endif
+        WOLFSSL_HEAP_HINT* ssl_hint = (WOLFSSL_HEAP_HINT*)ssl->heap;
+        WOLFSSL_HEAP*      ctx_heap;
+
+        ctx_heap = ssl_hint->memory;
+        if (wc_LockMutex(&(ctx_heap->memory_mutex)) != 0) {
+            WOLFSSL_MSG("Bad memory_mutex lock");
+        }
+        ctx_heap->curHa--;
+        ssl_hint->haFlag = 0; /* set to zero since handshake has been dec */
+        wc_UnLockMutex(&(ctx_heap->memory_mutex));
+    #ifdef WOLFSSL_HEAP_TEST
+    }
+    #endif
+    }
+#endif /* WOLFSSL_STATIC_MEMORY */
+}
+
+
+/* heap argument is the heap hint used when creating SSL */
+void FreeSSL(WOLFSSL* ssl, void* heap)
+{
+    if (ssl->ctx) {
+        FreeSSL_Ctx(ssl->ctx); /* will decrement and free underlying CTX if 0 */
+    }
+    SSL_ResourceFree(ssl);
+    XFREE(ssl, heap, DYNAMIC_TYPE_SSL);
+    (void)heap;
+}
+
+#if !defined(NO_OLD_TLS) || defined(WOLFSSL_DTLS) || \
+    ((defined(HAVE_CHACHA) || defined(HAVE_AESCCM) || defined(HAVE_AESGCM)) \
+     && defined(HAVE_AEAD))
+
+#if defined(WOLFSSL_DTLS) || !defined(WOLFSSL_NO_TLS12)
+static WC_INLINE void GetSEQIncrement(WOLFSSL* ssl, int verify, word32 seq[2])
+{
+    if (verify) {
+        seq[0] = ssl->keys.peer_sequence_number_hi;
+        seq[1] = ssl->keys.peer_sequence_number_lo++;
+        if (seq[1] > ssl->keys.peer_sequence_number_lo) {
+            /* handle rollover */
+            ssl->keys.peer_sequence_number_hi++;
+        }
+    }
+    else {
+        seq[0] = ssl->keys.sequence_number_hi;
+        seq[1] = ssl->keys.sequence_number_lo++;
+        if (seq[1] > ssl->keys.sequence_number_lo) {
+            /* handle rollover */
+            ssl->keys.sequence_number_hi++;
+        }
+    }
+}
+#endif /* WOLFSSL_DTLS || !WOLFSSL_NO_TLS12 */
+
+
+#ifdef WOLFSSL_DTLS
+static WC_INLINE void DtlsGetSEQ(WOLFSSL* ssl, int order, word32 seq[2])
+{
+    if (order == PREV_ORDER) {
+        /* Previous epoch case */
+        if (ssl->options.haveMcast) {
+        #ifdef WOLFSSL_MULTICAST
+            seq[0] = (((word32)ssl->keys.dtls_epoch - 1) << 16) |
+                     (ssl->options.mcastID << 8) |
+                     (ssl->keys.dtls_prev_sequence_number_hi & 0xFF);
+        #endif
+        }
+        else
+            seq[0] = (((word32)ssl->keys.dtls_epoch - 1) << 16) |
+                     (ssl->keys.dtls_prev_sequence_number_hi & 0xFFFF);
+        seq[1] = ssl->keys.dtls_prev_sequence_number_lo;
+    }
+    else if (order == PEER_ORDER) {
+        if (ssl->options.haveMcast) {
+        #ifdef WOLFSSL_MULTICAST
+            seq[0] = ((word32)ssl->keys.curEpoch << 16) |
+                     (ssl->keys.curPeerId << 8) |
+                     (ssl->keys.curSeq_hi & 0xFF);
+        #endif
+        }
+        else
+            seq[0] = ((word32)ssl->keys.curEpoch << 16) |
+                     (ssl->keys.curSeq_hi & 0xFFFF);
+        seq[1] = ssl->keys.curSeq_lo; /* explicit from peer */
+    }
+    else {
+        if (ssl->options.haveMcast) {
+        #ifdef WOLFSSL_MULTICAST
+            seq[0] = ((word32)ssl->keys.dtls_epoch << 16) |
+                     (ssl->options.mcastID << 8) |
+                     (ssl->keys.dtls_sequence_number_hi & 0xFF);
+        #endif
+        }
+        else
+            seq[0] = ((word32)ssl->keys.dtls_epoch << 16) |
+                     (ssl->keys.dtls_sequence_number_hi & 0xFFFF);
+        seq[1] = ssl->keys.dtls_sequence_number_lo;
+    }
+}
+
+static WC_INLINE void DtlsSEQIncrement(WOLFSSL* ssl, int order)
+{
+    word32 seq;
+
+    if (order == PREV_ORDER) {
+        seq = ssl->keys.dtls_prev_sequence_number_lo++;
+        if (seq > ssl->keys.dtls_prev_sequence_number_lo) {
+            /* handle rollover */
+            ssl->keys.dtls_prev_sequence_number_hi++;
+        }
+    }
+    else if (order == PEER_ORDER) {
+        seq = ssl->keys.peer_sequence_number_lo++;
+        if (seq > ssl->keys.peer_sequence_number_lo) {
+            /* handle rollover */
+            ssl->keys.peer_sequence_number_hi++;
+        }
+    }
+    else {
+        seq = ssl->keys.dtls_sequence_number_lo++;
+        if (seq > ssl->keys.dtls_sequence_number_lo) {
+            /* handle rollover */
+            ssl->keys.dtls_sequence_number_hi++;
+        }
+    }
+}
+#endif /* WOLFSSL_DTLS */
+
+#if defined(WOLFSSL_DTLS) || !defined(WOLFSSL_NO_TLS12)
+static WC_INLINE void WriteSEQ(WOLFSSL* ssl, int verifyOrder, byte* out)
+{
+    word32 seq[2] = {0, 0};
+
+    if (!ssl->options.dtls) {
+        GetSEQIncrement(ssl, verifyOrder, seq);
+    }
+    else {
+#ifdef WOLFSSL_DTLS
+        DtlsGetSEQ(ssl, verifyOrder, seq);
+#endif
+    }
+
+    c32toa(seq[0], out);
+    c32toa(seq[1], out + OPAQUE32_LEN);
+}
+#endif /* WOLFSSL_DTLS || !WOLFSSL_NO_TLS12 */
+#endif /* !NO_OLD_TLS || WOLFSSL_DTLS ||
+        *     ((HAVE_CHACHA || HAVE_AESCCM || HAVE_AESGCM) && HAVE_AEAD) */
+
+#ifdef WOLFSSL_DTLS
+
+/* functions for managing DTLS datagram reordering */
+
+/* Need to allocate space for the handshake message header. The hashing
+ * routines assume the message pointer is still within the buffer that
+ * has the headers, and will include those headers in the hash. The store
+ * routines need to take that into account as well. New will allocate
+ * extra space for the headers. */
+DtlsMsg* DtlsMsgNew(word32 sz, void* heap)
+{
+    DtlsMsg* msg;
+
+    (void)heap;
+    msg = (DtlsMsg*)XMALLOC(sizeof(DtlsMsg), heap, DYNAMIC_TYPE_DTLS_MSG);
+
+    if (msg != NULL) {
+        XMEMSET(msg, 0, sizeof(DtlsMsg));
+        msg->buf = (byte*)XMALLOC(sz + DTLS_HANDSHAKE_HEADER_SZ,
+                                                heap, DYNAMIC_TYPE_DTLS_BUFFER);
+        if (msg->buf != NULL) {
+            msg->sz = sz;
+            msg->type = no_shake;
+            msg->msg = msg->buf + DTLS_HANDSHAKE_HEADER_SZ;
+        }
+        else {
+            XFREE(msg, heap, DYNAMIC_TYPE_DTLS_MSG);
+            msg = NULL;
+        }
+    }
+
+    return msg;
+}
+
+void DtlsMsgDelete(DtlsMsg* item, void* heap)
+{
+    (void)heap;
+
+    if (item != NULL) {
+        DtlsFrag* cur = item->fragList;
+        while (cur != NULL) {
+            DtlsFrag* next = cur->next;
+            XFREE(cur, heap, DYNAMIC_TYPE_DTLS_FRAG);
+            cur = next;
+        }
+        if (item->buf != NULL)
+            XFREE(item->buf, heap, DYNAMIC_TYPE_DTLS_BUFFER);
+        XFREE(item, heap, DYNAMIC_TYPE_DTLS_MSG);
+    }
+}
+
+
+void DtlsMsgListDelete(DtlsMsg* head, void* heap)
+{
+    DtlsMsg* next;
+    while (head) {
+        next = head->next;
+        DtlsMsgDelete(head, heap);
+        head = next;
+    }
+}
+
+
+/* Create a DTLS Fragment from *begin - end, adjust new *begin and bytesLeft */
+static DtlsFrag* CreateFragment(word32* begin, word32 end, const byte* data,
+                                byte* buf, word32* bytesLeft, void* heap)
+{
+    DtlsFrag* newFrag;
+    word32 added = end - *begin + 1;
+
+    (void)heap;
+    newFrag = (DtlsFrag*)XMALLOC(sizeof(DtlsFrag), heap,
+                                 DYNAMIC_TYPE_DTLS_FRAG);
+    if (newFrag != NULL) {
+        newFrag->next = NULL;
+        newFrag->begin = *begin;
+        newFrag->end = end;
+
+        XMEMCPY(buf + *begin, data, added);
+        *bytesLeft -= added;
+        *begin = newFrag->end + 1;
+    }
+
+    return newFrag;
+}
+
+
+int DtlsMsgSet(DtlsMsg* msg, word32 seq, const byte* data, byte type,
+                                   word32 fragOffset, word32 fragSz, void* heap)
+{
+    if (msg != NULL && data != NULL && msg->fragSz <= msg->sz &&
+                                             (fragOffset + fragSz) <= msg->sz) {
+        DtlsFrag* cur = msg->fragList;
+        DtlsFrag* prev = cur;
+        DtlsFrag* newFrag;
+        word32 bytesLeft = fragSz; /* could be overlapping fragment */
+        word32 startOffset = fragOffset;
+        word32 added;
+
+        msg->seq = seq;
+        msg->type = type;
+
+        if (fragOffset == 0) {
+            XMEMCPY(msg->buf, data - DTLS_HANDSHAKE_HEADER_SZ,
+                    DTLS_HANDSHAKE_HEADER_SZ);
+            c32to24(msg->sz, msg->msg - DTLS_HANDSHAKE_FRAG_SZ);
+        }
+
+        /* if no message data, just return */
+        if (fragSz == 0)
+            return 0;
+
+        /* if list is empty add full fragment to front */
+        if (cur == NULL) {
+            newFrag = CreateFragment(&fragOffset, fragOffset + fragSz - 1, data,
+                                     msg->msg, &bytesLeft, heap);
+            if (newFrag == NULL)
+                return MEMORY_E;
+
+            msg->fragSz = fragSz;
+            msg->fragList = newFrag;
+
+            return 0;
+        }
+
+        /* add to front if before current front, up to next->begin */
+        if (fragOffset < cur->begin) {
+            word32 end = fragOffset + fragSz - 1;
+
+            if (end >= cur->begin)
+                end = cur->begin - 1;
+
+            added = end - fragOffset + 1;
+            newFrag = CreateFragment(&fragOffset, end, data, msg->msg,
+                                     &bytesLeft, heap);
+            if (newFrag == NULL)
+                return MEMORY_E;
+
+            msg->fragSz += added;
+
+            newFrag->next = cur;
+            msg->fragList = newFrag;
+        }
+
+        /* while we have bytes left, try to find a gap to fill */
+        while (bytesLeft > 0) {
+            /* get previous packet in list */
+            while (cur && (fragOffset >= cur->begin)) {
+                prev = cur;
+                cur = cur->next;
+            }
+
+            /* don't add duplicate data */
+            if (prev->end >= fragOffset) {
+                if ( (fragOffset + bytesLeft - 1) <= prev->end)
+                    return 0;
+                fragOffset = prev->end + 1;
+                bytesLeft = startOffset + fragSz - fragOffset;
+            }
+
+            if (cur == NULL)
+                /* we're at the end */
+                added = bytesLeft;
+            else
+                /* we're in between two frames */
+                added = min(bytesLeft, cur->begin - fragOffset);
+
+            /* data already there */
+            if (added == 0)
+                continue;
+
+            newFrag = CreateFragment(&fragOffset, fragOffset + added - 1,
+                                     data + fragOffset - startOffset,
+                                     msg->msg, &bytesLeft, heap);
+            if (newFrag == NULL)
+                return MEMORY_E;
+
+            msg->fragSz += added;
+
+            newFrag->next = prev->next;
+            prev->next = newFrag;
+        }
+    }
+
+    return 0;
+}
+
+
+DtlsMsg* DtlsMsgFind(DtlsMsg* head, word32 seq)
+{
+    while (head != NULL && head->seq != seq) {
+        head = head->next;
+    }
+    return head;
+}
+
+
+void DtlsMsgStore(WOLFSSL* ssl, word32 seq, const byte* data,
+        word32 dataSz, byte type, word32 fragOffset, word32 fragSz, void* heap)
+{
+    /* See if seq exists in the list. If it isn't in the list, make
+     * a new item of size dataSz, copy fragSz bytes from data to msg->msg
+     * starting at offset fragOffset, and add fragSz to msg->fragSz. If
+     * the seq is in the list and it isn't full, copy fragSz bytes from
+     * data to msg->msg starting at offset fragOffset, and add fragSz to
+     * msg->fragSz. Insertions take into account data already in the list
+     * in case there are overlaps in the handshake message due to retransmit
+     * messages. The new item should be inserted into the list in its
+     * proper position.
+     *
+     * 1. Find seq in list, or where seq should go in list. If seq not in
+     *    list, create new item and insert into list. Either case, keep
+     *    pointer to item.
+     * 2. Copy the data from the message to the stored message where it
+     *    belongs without overlaps.
+     */
+
+    DtlsMsg* head = ssl->dtls_rx_msg_list;
+
+    if (head != NULL) {
+        DtlsMsg* cur = DtlsMsgFind(head, seq);
+        if (cur == NULL) {
+            cur = DtlsMsgNew(dataSz, heap);
+            if (cur != NULL) {
+                if (DtlsMsgSet(cur, seq, data, type,
+                                                fragOffset, fragSz, heap) < 0) {
+                    DtlsMsgDelete(cur, heap);
+                }
+                else {
+                    ssl->dtls_rx_msg_list_sz++;
+                    head = DtlsMsgInsert(head, cur);
+                }
+            }
+        }
+        else {
+            /* If this fails, the data is just dropped. */
+            DtlsMsgSet(cur, seq, data, type, fragOffset, fragSz, heap);
+        }
+    }
+    else {
+        head = DtlsMsgNew(dataSz, heap);
+        if (DtlsMsgSet(head, seq, data, type, fragOffset, fragSz, heap) < 0) {
+            DtlsMsgDelete(head, heap);
+            head = NULL;
+        }
+        else {
+            ssl->dtls_rx_msg_list_sz++;
+        }
+    }
+
+    ssl->dtls_rx_msg_list = head;
+}
+
+
+/* DtlsMsgInsert() is an in-order insert. */
+DtlsMsg* DtlsMsgInsert(DtlsMsg* head, DtlsMsg* item)
+{
+    if (head == NULL || item->seq < head->seq) {
+        item->next = head;
+        head = item;
+    }
+    else if (head->next == NULL) {
+        head->next = item;
+    }
+    else {
+        DtlsMsg* cur = head->next;
+        DtlsMsg* prev = head;
+        while (cur) {
+            if (item->seq < cur->seq) {
+                item->next = cur;
+                prev->next = item;
+                break;
+            }
+            prev = cur;
+            cur = cur->next;
+        }
+        if (cur == NULL) {
+            prev->next = item;
+        }
+    }
+
+    return head;
+}
+
+
+/* DtlsMsgPoolSave() adds the message to the end of the stored transmit list. */
+int DtlsMsgPoolSave(WOLFSSL* ssl, const byte* data, word32 dataSz)
+{
+    DtlsMsg* item;
+    int ret = 0;
+
+    WOLFSSL_ENTER("DtlsMsgPoolSave()");
+
+    if (ssl->dtls_tx_msg_list_sz > DTLS_POOL_SZ) {
+        WOLFSSL_ERROR(DTLS_POOL_SZ_E);
+        return DTLS_POOL_SZ_E;
+    }
+
+    item = DtlsMsgNew(dataSz, ssl->heap);
+
+    if (item != NULL) {
+        DtlsMsg* cur = ssl->dtls_tx_msg_list;
+
+        XMEMCPY(item->buf, data, dataSz);
+        item->sz = dataSz;
+        item->seq = ssl->keys.dtls_epoch;
+
+        if (cur == NULL)
+            ssl->dtls_tx_msg_list = item;
+        else {
+            while (cur->next)
+                cur = cur->next;
+            cur->next = item;
+        }
+        ssl->dtls_tx_msg_list_sz++;
+    }
+    else
+        ret = MEMORY_E;
+
+    WOLFSSL_LEAVE("DtlsMsgPoolSave()", ret);
+    return ret;
+}
+
+
+/* DtlsMsgPoolTimeout() updates the timeout time. */
+int DtlsMsgPoolTimeout(WOLFSSL* ssl)
+{
+    int result = -1;
+    if (ssl->dtls_timeout <  ssl->dtls_timeout_max) {
+        ssl->dtls_timeout *= DTLS_TIMEOUT_MULTIPLIER;
+        result = 0;
+    }
+    WOLFSSL_LEAVE("DtlsMsgPoolTimeout()", result);
+    return result;
+}
+
+
+/* DtlsMsgPoolReset() deletes the stored transmit list and resets the timeout
+ * value. */
+void DtlsMsgPoolReset(WOLFSSL* ssl)
+{
+    WOLFSSL_ENTER("DtlsMsgPoolReset()");
+    if (ssl->dtls_tx_msg_list) {
+        DtlsMsgListDelete(ssl->dtls_tx_msg_list, ssl->heap);
+        ssl->dtls_tx_msg_list = NULL;
+        ssl->dtls_tx_msg = NULL;
+        ssl->dtls_tx_msg_list_sz = 0;
+        ssl->dtls_timeout = ssl->dtls_timeout_init;
+    }
+}
+
+
+int VerifyForDtlsMsgPoolSend(WOLFSSL* ssl, byte type, word32 fragOffset)
+{
+    /**
+     * only the first message from previous flight should be valid
+     * to be used for triggering retransmission of whole DtlsMsgPool.
+     * change cipher suite type is not verified here
+     */
+    return ((fragOffset == 0) &&
+           (((ssl->options.side == WOLFSSL_SERVER_END) &&
+             ((type == client_hello) ||
+             ((ssl->options.verifyPeer) && (type == certificate)) ||
+             ((!ssl->options.verifyPeer) && (type == client_key_exchange)))) ||
+            ((ssl->options.side == WOLFSSL_CLIENT_END) &&
+             (type == server_hello))));
+}
+
+
+/* DtlsMsgPoolSend() will send the stored transmit list. The stored list is
+ * updated with new sequence numbers, and will be re-encrypted if needed. */
+int DtlsMsgPoolSend(WOLFSSL* ssl, int sendOnlyFirstPacket)
+{
+    int ret = 0;
+    DtlsMsg* pool;
+
+    WOLFSSL_ENTER("DtlsMsgPoolSend()");
+
+    pool = ssl->dtls_tx_msg == NULL ? ssl->dtls_tx_msg_list : ssl->dtls_tx_msg;
+
+    if (pool != NULL) {
+        if ((ssl->options.side == WOLFSSL_SERVER_END &&
+             !(ssl->options.acceptState == SERVER_HELLO_DONE ||
+               ssl->options.acceptState == ACCEPT_FINISHED_DONE ||
+               ssl->options.acceptState == ACCEPT_THIRD_REPLY_DONE)) ||
+            (ssl->options.side == WOLFSSL_CLIENT_END &&
+             !(ssl->options.connectState == CLIENT_HELLO_SENT ||
+               ssl->options.connectState == HELLO_AGAIN_REPLY ||
+               ssl->options.connectState == FINISHED_DONE ||
+               ssl->options.connectState == SECOND_REPLY_DONE))) {
+
+            WOLFSSL_ERROR(DTLS_RETX_OVER_TX);
+            ssl->error = DTLS_RETX_OVER_TX;
+            return WOLFSSL_FATAL_ERROR;
+        }
+
+        while (pool != NULL) {
+            if (pool->seq == 0) {
+                DtlsRecordLayerHeader* dtls;
+                int epochOrder;
+
+                dtls = (DtlsRecordLayerHeader*)pool->buf;
+                /* If the stored record's epoch is 0, and the currently set
+                 * epoch is 0, use the "current order" sequence number.
+                 * If the stored record's epoch is 0 and the currently set
+                 * epoch is not 0, the stored record is considered a "previous
+                 * order" sequence number. */
+                epochOrder = (ssl->keys.dtls_epoch == 0) ?
+                             CUR_ORDER : PREV_ORDER;
+
+                WriteSEQ(ssl, epochOrder, dtls->sequence_number);
+                DtlsSEQIncrement(ssl, epochOrder);
+                if ((ret = CheckAvailableSize(ssl, pool->sz)) != 0) {
+                    WOLFSSL_ERROR(ret);
+                    return ret;
+                }
+
+                XMEMCPY(ssl->buffers.outputBuffer.buffer,
+                        pool->buf, pool->sz);
+                ssl->buffers.outputBuffer.idx = 0;
+                ssl->buffers.outputBuffer.length = pool->sz;
+            }
+            else if (pool->seq == ssl->keys.dtls_epoch) {
+                byte*  input;
+                byte*  output;
+                int    inputSz, sendSz;
+
+                input = pool->buf;
+                inputSz = pool->sz;
+                sendSz = inputSz + MAX_MSG_EXTRA;
+
+                if ((ret = CheckAvailableSize(ssl, sendSz)) != 0) {
+                    WOLFSSL_ERROR(ret);
+                    return ret;
+                }
+
+                output = ssl->buffers.outputBuffer.buffer +
+                         ssl->buffers.outputBuffer.length;
+                sendSz = BuildMessage(ssl, output, sendSz, input, inputSz,
+                                      handshake, 0, 0, 0);
+                if (sendSz < 0) {
+                    WOLFSSL_ERROR(BUILD_MSG_ERROR);
+                    return BUILD_MSG_ERROR;
+                }
+
+                ssl->buffers.outputBuffer.length += sendSz;
+            }
+
+            ret = SendBuffered(ssl);
+            if (ret < 0) {
+                WOLFSSL_ERROR(ret);
+                return ret;
+            }
+
+            /**
+             * on server side, retransmission is being triggered only by sending
+             * first message of given flight, in order to trigger client
+             * to retransmit its whole flight. Sending the whole previous flight
+             * could lead to retransmission of previous client flight for each
+             * server message from previous flight. Therefore one message should
+             * be enough to do the trick.
+             */
+            if (sendOnlyFirstPacket &&
+                ssl->options.side == WOLFSSL_SERVER_END) {
+
+                pool = NULL;
+            }
+            else
+                pool = pool->next;
+            ssl->dtls_tx_msg = pool;
+        }
+    }
+
+    WOLFSSL_LEAVE("DtlsMsgPoolSend()", ret);
+    return ret;
+}
+
+#endif /* WOLFSSL_DTLS */
+
+#if defined(WOLFSSL_ALLOW_SSLV3) && !defined(NO_OLD_TLS)
+
+ProtocolVersion MakeSSLv3(void)
+{
+    ProtocolVersion pv;
+    pv.major = SSLv3_MAJOR;
+    pv.minor = SSLv3_MINOR;
+
+    return pv;
+}
+
+#endif /* WOLFSSL_ALLOW_SSLV3 && !NO_OLD_TLS */
+
+
+#ifdef WOLFSSL_DTLS
+
+ProtocolVersion MakeDTLSv1(void)
+{
+    ProtocolVersion pv;
+    pv.major = DTLS_MAJOR;
+    pv.minor = DTLS_MINOR;
+
+    return pv;
+}
+
+#ifndef WOLFSSL_NO_TLS12
+
+ProtocolVersion MakeDTLSv1_2(void)
+{
+    ProtocolVersion pv;
+    pv.major = DTLS_MAJOR;
+    pv.minor = DTLSv1_2_MINOR;
+
+    return pv;
+}
+
+#endif /* !WOLFSSL_NO_TLS12 */
+
+#endif /* WOLFSSL_DTLS */
+
+
+#ifndef NO_ASN_TIME
+#if defined(USER_TICKS)
+#if 0
+    word32 LowResTimer(void)
+    {
+        /*
+        write your own clock tick function if don't want time(0)
+        needs second accuracy but doesn't have to correlated to EPOCH
+        */
+    }
+#endif
+
+#elif defined(TIME_OVERRIDES)
+
+    /* use same asn time overrides unless user wants tick override above */
+
+    #ifndef HAVE_TIME_T_TYPE
+        typedef long time_t;
+    #endif
+    extern time_t XTIME(time_t * timer);
+
+    word32 LowResTimer(void)
+    {
+        return (word32) XTIME(0);
+    }
+
+#elif defined(USE_WINDOWS_API)
+
+    word32 LowResTimer(void)
+    {
+        static int           init = 0;
+        static LARGE_INTEGER freq;
+        LARGE_INTEGER        count;
+
+        if (!init) {
+            QueryPerformanceFrequency(&freq);
+            init = 1;
+        }
+
+        QueryPerformanceCounter(&count);
+
+        return (word32)(count.QuadPart / freq.QuadPart);
+    }
+
+#elif defined(HAVE_RTP_SYS)
+
+    #include "rtptime.h"
+
+    word32 LowResTimer(void)
+    {
+        return (word32)rtp_get_system_sec();
+    }
+
+#elif defined(WOLFSSL_DEOS)
+
+    word32 LowResTimer(void)
+    {
+        const uint32_t systemTickTimeInHz = 1000000 / systemTickInMicroseconds();
+        uint32_t *systemTickPtr = systemTickPointer();
+
+        return (word32) *systemTickPtr/systemTickTimeInHz;
+    }
+
+#elif defined(MICRIUM)
+
+    word32 LowResTimer(void)
+    {
+        OS_TICK ticks = 0;
+        OS_ERR  err;
+
+        ticks = OSTimeGet(&err);
+
+        return (word32) (ticks / OSCfg_TickRate_Hz);
+    }
+
+
+#elif defined(MICROCHIP_TCPIP_V5)
+
+    word32 LowResTimer(void)
+    {
+        return (word32) (TickGet() / TICKS_PER_SECOND);
+    }
+
+
+#elif defined(MICROCHIP_TCPIP)
+
+    #if defined(MICROCHIP_MPLAB_HARMONY)
+
+        #include <system/tmr/sys_tmr.h>
+
+        word32 LowResTimer(void)
+        {
+            return (word32) (SYS_TMR_TickCountGet() /
+                             SYS_TMR_TickCounterFrequencyGet());
+        }
+
+    #else
+
+        word32 LowResTimer(void)
+        {
+            return (word32) (SYS_TICK_Get() / SYS_TICK_TicksPerSecondGet());
+        }
+
+    #endif
+
+#elif defined(FREESCALE_MQX) || defined(FREESCALE_KSDK_MQX)
+
+    word32 LowResTimer(void)
+    {
+        TIME_STRUCT mqxTime;
+
+        _time_get_elapsed(&mqxTime);
+
+        return (word32) mqxTime.SECONDS;
+    }
+#elif defined(FREESCALE_FREE_RTOS) || defined(FREESCALE_KSDK_FREERTOS)
+
+    #include "include/task.h"
+
+    unsigned int LowResTimer(void)
+    {
+        return (unsigned int)(((float)xTaskGetTickCount())/configTICK_RATE_HZ);
+    }
+
+#elif defined(FREERTOS)
+
+    #include "task.h"
+
+    unsigned int LowResTimer(void)
+    {
+        return (unsigned int)(((float)xTaskGetTickCount())/configTICK_RATE_HZ);
+    }
+
+#elif defined(FREESCALE_KSDK_BM)
+
+    #include "lwip/sys.h" /* lwIP */
+    word32 LowResTimer(void)
+    {
+        return sys_now()/1000;
+    }
+
+#elif defined(WOLFSSL_TIRTOS)
+
+    word32 LowResTimer(void)
+    {
+        return (word32) Seconds_get();
+    }
+#elif defined(WOLFSSL_XILINX)
+    #include "xrtcpsu.h"
+
+    word32 LowResTimer(void)
+    {
+        XRtcPsu_Config* con;
+        XRtcPsu         rtc;
+
+        con = XRtcPsu_LookupConfig(XPAR_XRTCPSU_0_DEVICE_ID);
+        if (con != NULL) {
+            if (XRtcPsu_CfgInitialize(&rtc, con, con->BaseAddr)
+                    == XST_SUCCESS) {
+                return (word32)XRtcPsu_GetCurrentTime(&rtc);
+            }
+            else {
+                WOLFSSL_MSG("Unable to initialize RTC");
+            }
+        }
+
+        return 0;
+    }
+
+#elif defined(WOLFSSL_UTASKER)
+
+    word32 LowResTimer(void)
+    {
+        return (word32)(uTaskerSystemTick / TICK_RESOLUTION);
+    }
+
+#elif defined(WOLFSSL_NUCLEUS_1_2)
+
+    #define NU_TICKS_PER_SECOND 100
+
+    word32 LowResTimer(void)
+    {
+        /* returns number of 10ms ticks, so 100 ticks/sec */
+        return NU_Retrieve_Clock() / NU_TICKS_PER_SECOND;
+    }
+#elif defined(WOLFSSL_APACHE_MYNEWT)
+
+    #include "os/os_time.h"
+    word32 LowResTimer(void)
+    {
+        word32 now;
+        struct os_timeval tv;
+        os_gettimeofday(&tv, NULL);
+        now = (word32)tv.tv_sec;
+        return now;
+    }
+
+#elif defined(WOLFSSL_ZEPHYR)
+
+    word32 LowResTimer(void)
+    {
+        return k_uptime_get() / 1000;
+    }
+
+#else
+    /* Posix style time */
+    #if !defined(USER_TIME) && !defined(USE_WOLF_TM)
+    #include <time.h>
+    #endif
+
+    word32 LowResTimer(void)
+    {
+        return (word32)XTIME(0);
+    }
+#endif
+#endif /* !NO_ASN_TIME */
+#if !defined(WOLFSSL_NO_CLIENT_AUTH) && \
+               ((defined(HAVE_ED25519) && !defined(NO_ED25519_CLIENT_AUTH)) || \
+                (defined(HAVE_ED448) && !defined(NO_ED448_CLIENT_AUTH)))
+/* Store the message for use with CertificateVerify using EdDSA.
+ *
+ * ssl   SSL/TLS object.
+ * data  Message to store.
+ * sz    Size of message to store.
+ * returns MEMORY_E if not able to reallocate, otherwise 0.
+ */
+static int EdDSA_Update(WOLFSSL* ssl, const byte* data, int sz)
+{
+    int   ret = 0;
+    byte* msgs;
+
+    if (ssl->options.cacheMessages) {
+        msgs = (byte*)XREALLOC(ssl->hsHashes->messages,
+                                                ssl->hsHashes->length + sz,
+                                                ssl->heap, DYNAMIC_TYPE_HASHES);
+        if (msgs == NULL)
+            ret = MEMORY_E;
+        if (ret == 0) {
+            ssl->hsHashes->messages = msgs;
+            XMEMCPY(msgs + ssl->hsHashes->length, data, sz);
+            ssl->hsHashes->prevLen = ssl->hsHashes->length;
+            ssl->hsHashes->length += sz;
+        }
+    }
+
+    return ret;
+}
+#endif /* (HAVE_ED25519 || HAVE_ED448) && !WOLFSSL_NO_CLIENT_AUTH */
+
+#ifndef NO_CERTS
+int HashOutputRaw(WOLFSSL* ssl, const byte* output, int sz)
+{
+    int ret = 0;
+
+    (void)output;
+    (void)sz;
+
+    if (ssl->hsHashes == NULL)
+        return BAD_FUNC_ARG;
+
+#ifdef HAVE_FUZZER
+    if (ssl->fuzzerCb)
+        ssl->fuzzerCb(ssl, output, sz, FUZZ_HASH, ssl->fuzzerCtx);
+#endif
+#ifndef NO_OLD_TLS
+    #ifndef NO_SHA
+        wc_ShaUpdate(&ssl->hsHashes->hashSha, output, sz);
+    #endif
+    #ifndef NO_MD5
+        wc_Md5Update(&ssl->hsHashes->hashMd5, output, sz);
+    #endif
+#endif /* NO_OLD_TLS */
+
+    if (IsAtLeastTLSv1_2(ssl)) {
+    #ifndef NO_SHA256
+        ret = wc_Sha256Update(&ssl->hsHashes->hashSha256, output, sz);
+        if (ret != 0)
+            return ret;
+    #endif
+    #ifdef WOLFSSL_SHA384
+        ret = wc_Sha384Update(&ssl->hsHashes->hashSha384, output, sz);
+        if (ret != 0)
+            return ret;
+    #endif
+    #ifdef WOLFSSL_SHA512
+        ret = wc_Sha512Update(&ssl->hsHashes->hashSha512, output, sz);
+        if (ret != 0)
+            return ret;
+    #endif
+    #if !defined(WOLFSSL_NO_CLIENT_AUTH) && \
+               ((defined(HAVE_ED25519) && !defined(NO_ED25519_CLIENT_AUTH)) || \
+                (defined(HAVE_ED448) && !defined(NO_ED448_CLIENT_AUTH)))
+        ret = EdDSA_Update(ssl, output, sz);
+        if (ret != 0)
+            return ret;
+    #endif
+    }
+
+    return ret;
+}
+#endif /* NO_CERTS */
+
+
+/* add output to md5 and sha handshake hashes, exclude record header */
+int HashOutput(WOLFSSL* ssl, const byte* output, int sz, int ivSz)
+{
+    int ret = 0;
+    const byte* adj;
+
+    if (ssl->hsHashes == NULL)
+        return BAD_FUNC_ARG;
+
+    adj = output + RECORD_HEADER_SZ + ivSz;
+    sz -= RECORD_HEADER_SZ;
+
+#ifdef HAVE_FUZZER
+    if (ssl->fuzzerCb)
+        ssl->fuzzerCb(ssl, output, sz, FUZZ_HASH, ssl->fuzzerCtx);
+#endif
+#ifdef WOLFSSL_DTLS
+    if (ssl->options.dtls) {
+        adj += DTLS_RECORD_EXTRA;
+        sz  -= DTLS_RECORD_EXTRA;
+    }
+#endif
+#ifndef NO_OLD_TLS
+    #ifndef NO_SHA
+        wc_ShaUpdate(&ssl->hsHashes->hashSha, adj, sz);
+    #endif
+    #ifndef NO_MD5
+        wc_Md5Update(&ssl->hsHashes->hashMd5, adj, sz);
+    #endif
+#endif
+
+    if (IsAtLeastTLSv1_2(ssl)) {
+    #ifndef NO_SHA256
+        ret = wc_Sha256Update(&ssl->hsHashes->hashSha256, adj, sz);
+        if (ret != 0)
+            return ret;
+    #endif
+    #ifdef WOLFSSL_SHA384
+        ret = wc_Sha384Update(&ssl->hsHashes->hashSha384, adj, sz);
+        if (ret != 0)
+            return ret;
+    #endif
+    #ifdef WOLFSSL_SHA512
+        ret = wc_Sha512Update(&ssl->hsHashes->hashSha512, adj, sz);
+        if (ret != 0)
+            return ret;
+    #endif
+    #if !defined(WOLFSSL_NO_CLIENT_AUTH) && \
+               ((defined(HAVE_ED25519) && !defined(NO_ED25519_CLIENT_AUTH)) || \
+                (defined(HAVE_ED448) && !defined(NO_ED448_CLIENT_AUTH)))
+        ret = EdDSA_Update(ssl, adj, sz);
+        if (ret != 0)
+            return ret;
+    #endif
+    }
+
+    return ret;
+}
+
+
+/* add input to md5 and sha handshake hashes, include handshake header */
+int HashInput(WOLFSSL* ssl, const byte* input, int sz)
+{
+    int ret = 0;
+    const byte* adj;
+
+    adj = input - HANDSHAKE_HEADER_SZ;
+    sz += HANDSHAKE_HEADER_SZ;
+
+    (void)adj;
+
+#ifdef WOLFSSL_DTLS
+    if (ssl->options.dtls) {
+        adj -= DTLS_HANDSHAKE_EXTRA;
+        sz  += DTLS_HANDSHAKE_EXTRA;
+    }
+#endif
+
+    if (ssl->hsHashes == NULL) {
+        return BAD_FUNC_ARG;
+    }
+
+#ifndef NO_OLD_TLS
+    #ifndef NO_SHA
+        wc_ShaUpdate(&ssl->hsHashes->hashSha, adj, sz);
+    #endif
+    #ifndef NO_MD5
+        wc_Md5Update(&ssl->hsHashes->hashMd5, adj, sz);
+    #endif
+#endif
+
+    if (IsAtLeastTLSv1_2(ssl)) {
+    #ifndef NO_SHA256
+        ret = wc_Sha256Update(&ssl->hsHashes->hashSha256, adj, sz);
+        if (ret != 0)
+            return ret;
+    #endif
+    #ifdef WOLFSSL_SHA384
+        ret = wc_Sha384Update(&ssl->hsHashes->hashSha384, adj, sz);
+        if (ret != 0)
+            return ret;
+    #endif
+    #ifdef WOLFSSL_SHA512
+        ret = wc_Sha512Update(&ssl->hsHashes->hashSha512, adj, sz);
+        if (ret != 0)
+            return ret;
+    #endif
+    #if !defined(WOLFSSL_NO_CLIENT_AUTH) && \
+               ((defined(HAVE_ED25519) && !defined(NO_ED25519_CLIENT_AUTH)) || \
+                (defined(HAVE_ED448) && !defined(NO_ED448_CLIENT_AUTH)))
+        ret = EdDSA_Update(ssl, adj, sz);
+        if (ret != 0)
+            return ret;
+    #endif
+    }
+
+    return ret;
+}
+
+
+/* add record layer header for message */
+static void AddRecordHeader(byte* output, word32 length, byte type, WOLFSSL* ssl)
+{
+    RecordLayerHeader* rl;
+
+    /* record layer header */
+    rl = (RecordLayerHeader*)output;
+    if (rl == NULL) {
+        return;
+    }
+    rl->type    = type;
+    rl->pvMajor = ssl->version.major;       /* type and version same in each */
+#ifdef WOLFSSL_TLS13
+    if (IsAtLeastTLSv1_3(ssl->version)) {
+#ifdef WOLFSSL_TLS13_DRAFT_18
+        rl->pvMinor = TLSv1_MINOR;
+#else
+        rl->pvMinor = TLSv1_2_MINOR;
+#endif
+    }
+    else
+#endif
+        rl->pvMinor = ssl->version.minor;
+
+#ifdef WOLFSSL_ALTERNATIVE_DOWNGRADE
+    if (ssl->options.side == WOLFSSL_CLIENT_END
+    &&  ssl->options.connectState == CONNECT_BEGIN
+    && !ssl->options.resuming) {
+        rl->pvMinor = ssl->options.downgrade ? ssl->options.minDowngrade
+                                             : ssl->version.minor;
+    }
+#endif
+
+    if (!ssl->options.dtls) {
+        c16toa((word16)length, rl->length);
+    }
+    else {
+#ifdef WOLFSSL_DTLS
+        DtlsRecordLayerHeader* dtls;
+
+        /* dtls record layer header extensions */
+        dtls = (DtlsRecordLayerHeader*)output;
+        WriteSEQ(ssl, 0, dtls->sequence_number);
+        c16toa((word16)length, dtls->length);
+#endif
+    }
+}
+
+
+#if !defined(WOLFSSL_NO_TLS12) || (defined(HAVE_SESSION_TICKET) && \
+                                                    !defined(NO_WOLFSSL_SERVER))
+/* add handshake header for message */
+static void AddHandShakeHeader(byte* output, word32 length,
+                               word32 fragOffset, word32 fragLength,
+                               byte type, WOLFSSL* ssl)
+{
+    HandShakeHeader* hs;
+    (void)fragOffset;
+    (void)fragLength;
+    (void)ssl;
+
+    /* handshake header */
+    hs = (HandShakeHeader*)output;
+    if (hs == NULL)
+        return;
+
+    hs->type = type;
+    c32to24(length, hs->length);         /* type and length same for each */
+#ifdef WOLFSSL_DTLS
+    if (ssl->options.dtls) {
+        DtlsHandShakeHeader* dtls;
+
+        /* dtls handshake header extensions */
+        dtls = (DtlsHandShakeHeader*)output;
+        c16toa(ssl->keys.dtls_handshake_number++, dtls->message_seq);
+        c32to24(fragOffset, dtls->fragment_offset);
+        c32to24(fragLength, dtls->fragment_length);
+    }
+#endif
+}
+
+/* add both headers for handshake message */
+static void AddHeaders(byte* output, word32 length, byte type, WOLFSSL* ssl)
+{
+    word32 lengthAdj = HANDSHAKE_HEADER_SZ;
+    word32 outputAdj = RECORD_HEADER_SZ;
+
+#ifdef WOLFSSL_DTLS
+    if (ssl->options.dtls) {
+        lengthAdj += DTLS_HANDSHAKE_EXTRA;
+        outputAdj += DTLS_RECORD_EXTRA;
+    }
+#endif
+
+    AddRecordHeader(output, length + lengthAdj, handshake, ssl);
+    AddHandShakeHeader(output + outputAdj, length, 0, length, type, ssl);
+}
+#endif /* !WOLFSSL_NO_TLS12 || (HAVE_SESSION_TICKET && !NO_WOLFSSL_SERVER) */
+
+
+#ifndef WOLFSSL_NO_TLS12
+#if !defined(NO_CERTS) && (!defined(NO_WOLFSSL_SERVER) || \
+                                               !defined(WOLFSSL_NO_CLIENT_AUTH))
+static void AddFragHeaders(byte* output, word32 fragSz, word32 fragOffset,
+                           word32 length, byte type, WOLFSSL* ssl)
+{
+    word32 lengthAdj = HANDSHAKE_HEADER_SZ;
+    word32 outputAdj = RECORD_HEADER_SZ;
+    (void)fragSz;
+
+#ifdef WOLFSSL_DTLS
+    if (ssl->options.dtls) {
+        lengthAdj += DTLS_HANDSHAKE_EXTRA;
+        outputAdj += DTLS_RECORD_EXTRA;
+    }
+#endif
+
+    AddRecordHeader(output, fragSz + lengthAdj, handshake, ssl);
+    AddHandShakeHeader(output + outputAdj, length, fragOffset, fragSz, type, ssl);
+}
+#endif /* NO_CERTS */
+#endif /* !WOLFSSL_NO_TLS12 */
+
+
+/* return bytes received, -1 on error */
+static int wolfSSLReceive(WOLFSSL* ssl, byte* buf, word32 sz)
+{
+    int recvd;
+
+    if (ssl->CBIORecv == NULL) {
+        WOLFSSL_MSG("Your IO Recv callback is null, please set");
+        return -1;
+    }
+
+retry:
+    recvd = ssl->CBIORecv(ssl, (char *)buf, (int)sz, ssl->IOCB_ReadCtx);
+    if (recvd < 0) {
+        switch (recvd) {
+            case WOLFSSL_CBIO_ERR_GENERAL:        /* general/unknown error */
+                #if defined(OPENSSL_ALL) || defined(WOLFSSL_APACHE_HTTPD)
+                    if (ssl->biord) {
+                        /* If retry and read flags are set, return WANT_READ */
+                        if ((ssl->biord->flags & WOLFSSL_BIO_FLAG_READ) &&
+                            (ssl->biord->flags & WOLFSSL_BIO_FLAG_RETRY)) {
+                            return WANT_READ;
+                        }
+                    }
+                #endif
+                return -1;
+
+            case WOLFSSL_CBIO_ERR_WANT_READ:      /* want read, would block */
+                return WANT_READ;
+
+            case WOLFSSL_CBIO_ERR_CONN_RST:       /* connection reset */
+                #ifdef USE_WINDOWS_API
+                if (ssl->options.dtls) {
+                    goto retry;
+                }
+                #endif
+                ssl->options.connReset = 1;
+                return -1;
+
+            case WOLFSSL_CBIO_ERR_ISR:            /* interrupt */
+                /* see if we got our timeout */
+                #ifdef WOLFSSL_CALLBACKS
+                    if (ssl->toInfoOn) {
+                        struct itimerval timeout;
+                        getitimer(ITIMER_REAL, &timeout);
+                        if (timeout.it_value.tv_sec == 0 &&
+                                                timeout.it_value.tv_usec == 0) {
+                            XSTRNCPY(ssl->timeoutInfo.timeoutName,
+                                    "recv() timeout", MAX_TIMEOUT_NAME_SZ);
+                            ssl->timeoutInfo.timeoutName[
+                                MAX_TIMEOUT_NAME_SZ] = '\0';
+
+                            WOLFSSL_MSG("Got our timeout");
+                            return WANT_READ;
+                        }
+                    }
+                #endif
+                goto retry;
+
+            case WOLFSSL_CBIO_ERR_CONN_CLOSE:     /* peer closed connection */
+                ssl->options.isClosed = 1;
+                return -1;
+
+            case WOLFSSL_CBIO_ERR_TIMEOUT:
+            #ifdef WOLFSSL_DTLS
+                if (IsDtlsNotSctpMode(ssl) &&
+                    !ssl->options.handShakeDone &&
+                    DtlsMsgPoolTimeout(ssl) == 0 &&
+                    DtlsMsgPoolSend(ssl, 0) == 0) {
+
+                    /* retry read for DTLS during handshake only */
+                    goto retry;
+                }
+            #endif
+                return -1;
+
+            default:
+                WOLFSSL_MSG("Unexpected recv return code");
+                return recvd;
+        }
+    }
+
+    return recvd;
+}
+
+
+/* Switch dynamic output buffer back to static, buffer is assumed clear */
+void ShrinkOutputBuffer(WOLFSSL* ssl)
+{
+    WOLFSSL_MSG("Shrinking output buffer\n");
+    XFREE(ssl->buffers.outputBuffer.buffer - ssl->buffers.outputBuffer.offset,
+          ssl->heap, DYNAMIC_TYPE_OUT_BUFFER);
+    ssl->buffers.outputBuffer.buffer = ssl->buffers.outputBuffer.staticBuffer;
+    ssl->buffers.outputBuffer.bufferSize  = STATIC_BUFFER_LEN;
+    ssl->buffers.outputBuffer.dynamicFlag = 0;
+    ssl->buffers.outputBuffer.offset      = 0;
+}
+
+
+/* Switch dynamic input buffer back to static, keep any remaining input */
+/* forced free means cleaning up */
+void ShrinkInputBuffer(WOLFSSL* ssl, int forcedFree)
+{
+    int usedLength = ssl->buffers.inputBuffer.length -
+                     ssl->buffers.inputBuffer.idx;
+    if (!forcedFree && usedLength > STATIC_BUFFER_LEN)
+        return;
+
+    WOLFSSL_MSG("Shrinking input buffer\n");
+
+    if (!forcedFree && usedLength > 0)
+        XMEMCPY(ssl->buffers.inputBuffer.staticBuffer,
+               ssl->buffers.inputBuffer.buffer + ssl->buffers.inputBuffer.idx,
+               usedLength);
+
+    XFREE(ssl->buffers.inputBuffer.buffer - ssl->buffers.inputBuffer.offset,
+          ssl->heap, DYNAMIC_TYPE_IN_BUFFER);
+    ssl->buffers.inputBuffer.buffer = ssl->buffers.inputBuffer.staticBuffer;
+    ssl->buffers.inputBuffer.bufferSize  = STATIC_BUFFER_LEN;
+    ssl->buffers.inputBuffer.dynamicFlag = 0;
+    ssl->buffers.inputBuffer.offset      = 0;
+    ssl->buffers.inputBuffer.idx = 0;
+    ssl->buffers.inputBuffer.length = usedLength;
+}
+
+int SendBuffered(WOLFSSL* ssl)
+{
+    if (ssl->CBIOSend == NULL) {
+        WOLFSSL_MSG("Your IO Send callback is null, please set");
+        return SOCKET_ERROR_E;
+    }
+
+#ifdef WOLFSSL_DEBUG_TLS
+    if (ssl->buffers.outputBuffer.idx == 0) {
+        WOLFSSL_MSG("Data to send");
+        WOLFSSL_BUFFER(ssl->buffers.outputBuffer.buffer,
+                       ssl->buffers.outputBuffer.length);
+    }
+#endif
+
+    while (ssl->buffers.outputBuffer.length > 0) {
+        int sent = ssl->CBIOSend(ssl,
+                                      (char*)ssl->buffers.outputBuffer.buffer +
+                                      ssl->buffers.outputBuffer.idx,
+                                      (int)ssl->buffers.outputBuffer.length,
+                                      ssl->IOCB_WriteCtx);
+        if (sent < 0) {
+            switch (sent) {
+
+                case WOLFSSL_CBIO_ERR_WANT_WRITE:        /* would block */
+                    return WANT_WRITE;
+
+                case WOLFSSL_CBIO_ERR_CONN_RST:          /* connection reset */
+                    ssl->options.connReset = 1;
+                    break;
+
+                case WOLFSSL_CBIO_ERR_ISR:               /* interrupt */
+                    /* see if we got our timeout */
+                    #ifdef WOLFSSL_CALLBACKS
+                        if (ssl->toInfoOn) {
+                            struct itimerval timeout;
+                            getitimer(ITIMER_REAL, &timeout);
+                            if (timeout.it_value.tv_sec == 0 &&
+                                                timeout.it_value.tv_usec == 0) {
+                                XSTRNCPY(ssl->timeoutInfo.timeoutName,
+                                        "send() timeout", MAX_TIMEOUT_NAME_SZ);
+                                ssl->timeoutInfo.timeoutName[
+                                    MAX_TIMEOUT_NAME_SZ] = '\0';
+
+                                WOLFSSL_MSG("Got our timeout");
+                                return WANT_WRITE;
+                            }
+                        }
+                    #endif
+                    continue;
+
+                case WOLFSSL_CBIO_ERR_CONN_CLOSE: /* epipe / conn closed */
+                    ssl->options.connReset = 1;  /* treat same as reset */
+                    break;
+
+                default:
+                    return SOCKET_ERROR_E;
+            }
+
+            return SOCKET_ERROR_E;
+        }
+
+        if (sent > (int)ssl->buffers.outputBuffer.length) {
+            WOLFSSL_MSG("SendBuffered() out of bounds read");
+            return SEND_OOB_READ_E;
+        }
+
+        ssl->buffers.outputBuffer.idx += sent;
+        ssl->buffers.outputBuffer.length -= sent;
+    }
+
+    ssl->buffers.outputBuffer.idx = 0;
+
+    if (ssl->buffers.outputBuffer.dynamicFlag)
+        ShrinkOutputBuffer(ssl);
+
+    return 0;
+}
+
+
+/* Grow the output buffer */
+static WC_INLINE int GrowOutputBuffer(WOLFSSL* ssl, int size)
+{
+    byte* tmp;
+#if WOLFSSL_GENERAL_ALIGNMENT > 0
+    byte  hdrSz = ssl->options.dtls ? DTLS_RECORD_HEADER_SZ :
+                                      RECORD_HEADER_SZ;
+    byte align = WOLFSSL_GENERAL_ALIGNMENT;
+#else
+    const byte align = WOLFSSL_GENERAL_ALIGNMENT;
+#endif
+
+#if WOLFSSL_GENERAL_ALIGNMENT > 0
+    /* the encrypted data will be offset from the front of the buffer by
+       the header, if the user wants encrypted alignment they need
+       to define their alignment requirement */
+
+    if (align) {
+       while (align < hdrSz)
+           align *= 2;
+    }
+#endif
+
+    tmp = (byte*)XMALLOC(size + ssl->buffers.outputBuffer.length + align,
+                             ssl->heap, DYNAMIC_TYPE_OUT_BUFFER);
+    WOLFSSL_MSG("growing output buffer\n");
+
+    if (tmp == NULL)
+        return MEMORY_E;
+
+#if WOLFSSL_GENERAL_ALIGNMENT > 0
+    if (align)
+        tmp += align - hdrSz;
+#endif
+
+#ifdef WOLFSSL_STATIC_MEMORY
+    /* can be from IO memory pool which does not need copy if same buffer */
+    if (ssl->buffers.outputBuffer.length &&
+            tmp == ssl->buffers.outputBuffer.buffer) {
+        ssl->buffers.outputBuffer.bufferSize =
+            size + ssl->buffers.outputBuffer.length;
+        return 0;
+    }
+#endif
+
+    if (ssl->buffers.outputBuffer.length)
+        XMEMCPY(tmp, ssl->buffers.outputBuffer.buffer,
+               ssl->buffers.outputBuffer.length);
+
+    if (ssl->buffers.outputBuffer.dynamicFlag)
+        XFREE(ssl->buffers.outputBuffer.buffer -
+              ssl->buffers.outputBuffer.offset, ssl->heap,
+              DYNAMIC_TYPE_OUT_BUFFER);
+    ssl->buffers.outputBuffer.dynamicFlag = 1;
+
+#if WOLFSSL_GENERAL_ALIGNMENT > 0
+    if (align)
+        ssl->buffers.outputBuffer.offset = align - hdrSz;
+    else
+#endif
+        ssl->buffers.outputBuffer.offset = 0;
+
+    ssl->buffers.outputBuffer.buffer = tmp;
+    ssl->buffers.outputBuffer.bufferSize = size +
+                                           ssl->buffers.outputBuffer.length;
+    return 0;
+}
+
+
+/* Grow the input buffer, should only be to read cert or big app data */
+int GrowInputBuffer(WOLFSSL* ssl, int size, int usedLength)
+{
+    byte* tmp;
+#if defined(WOLFSSL_DTLS) || WOLFSSL_GENERAL_ALIGNMENT > 0
+    byte  align = ssl->options.dtls ? WOLFSSL_GENERAL_ALIGNMENT : 0;
+    byte  hdrSz = DTLS_RECORD_HEADER_SZ;
+#else
+    const byte align = WOLFSSL_GENERAL_ALIGNMENT;
+#endif
+
+#if defined(WOLFSSL_DTLS) || WOLFSSL_GENERAL_ALIGNMENT > 0
+    /* the encrypted data will be offset from the front of the buffer by
+       the dtls record header, if the user wants encrypted alignment they need
+       to define their alignment requirement. in tls we read record header
+       to get size of record and put actual data back at front, so don't need */
+
+    if (align) {
+       while (align < hdrSz)
+           align *= 2;
+    }
+#endif
+
+    if (usedLength < 0 || size < 0) {
+        WOLFSSL_MSG("GrowInputBuffer() called with negative number");
+        return BAD_FUNC_ARG;
+    }
+
+    tmp = (byte*)XMALLOC(size + usedLength + align,
+                             ssl->heap, DYNAMIC_TYPE_IN_BUFFER);
+    WOLFSSL_MSG("growing input buffer\n");
+
+    if (tmp == NULL)
+        return MEMORY_E;
+
+#if defined(WOLFSSL_DTLS) || WOLFSSL_GENERAL_ALIGNMENT > 0
+    if (align)
+        tmp += align - hdrSz;
+#endif
+
+#ifdef WOLFSSL_STATIC_MEMORY
+    /* can be from IO memory pool which does not need copy if same buffer */
+    if (usedLength && tmp == ssl->buffers.inputBuffer.buffer) {
+        ssl->buffers.inputBuffer.bufferSize = size + usedLength;
+        ssl->buffers.inputBuffer.idx    = 0;
+        ssl->buffers.inputBuffer.length = usedLength;
+        return 0;
+    }
+#endif
+
+    if (usedLength)
+        XMEMCPY(tmp, ssl->buffers.inputBuffer.buffer +
+                    ssl->buffers.inputBuffer.idx, usedLength);
+
+    if (ssl->buffers.inputBuffer.dynamicFlag)
+        XFREE(ssl->buffers.inputBuffer.buffer - ssl->buffers.inputBuffer.offset,
+              ssl->heap,DYNAMIC_TYPE_IN_BUFFER);
+
+    ssl->buffers.inputBuffer.dynamicFlag = 1;
+#if defined(WOLFSSL_DTLS) || WOLFSSL_GENERAL_ALIGNMENT > 0
+    if (align)
+        ssl->buffers.inputBuffer.offset = align - hdrSz;
+    else
+#endif
+        ssl->buffers.inputBuffer.offset = 0;
+
+    ssl->buffers.inputBuffer.buffer = tmp;
+    ssl->buffers.inputBuffer.bufferSize = size + usedLength;
+    ssl->buffers.inputBuffer.idx    = 0;
+    ssl->buffers.inputBuffer.length = usedLength;
+
+    return 0;
+}
+
+
+/* check available size into output buffer, make room if needed */
+int CheckAvailableSize(WOLFSSL *ssl, int size)
+{
+    if (size < 0) {
+        WOLFSSL_MSG("CheckAvailableSize() called with negative number");
+        return BAD_FUNC_ARG;
+    }
+
+    if (ssl->buffers.outputBuffer.bufferSize - ssl->buffers.outputBuffer.length
+                                             < (word32)size) {
+        if (GrowOutputBuffer(ssl, size) < 0)
+            return MEMORY_E;
+    }
+
+    return 0;
+}
+
+
+/* do all verify and sanity checks on record header */
+static int GetRecordHeader(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
+                           RecordLayerHeader* rh, word16 *size)
+{
+    if (!ssl->options.dtls) {
+#ifdef HAVE_FUZZER
+        if (ssl->fuzzerCb)
+            ssl->fuzzerCb(ssl, input + *inOutIdx, RECORD_HEADER_SZ, FUZZ_HEAD,
+                    ssl->fuzzerCtx);
+#endif
+        XMEMCPY(rh, input + *inOutIdx, RECORD_HEADER_SZ);
+        *inOutIdx += RECORD_HEADER_SZ;
+        ato16(rh->length, size);
+    }
+    else {
+#ifdef WOLFSSL_DTLS
+#ifdef HAVE_FUZZER
+        if (ssl->fuzzerCb)
+            ssl->fuzzerCb(ssl, input + *inOutIdx, DTLS_RECORD_HEADER_SZ,
+                           FUZZ_HEAD, ssl->fuzzerCtx);
+#endif
+        /* type and version in same sport */
+        XMEMCPY(rh, input + *inOutIdx, ENUM_LEN + VERSION_SZ);
+        *inOutIdx += ENUM_LEN + VERSION_SZ;
+        ato16(input + *inOutIdx, &ssl->keys.curEpoch);
+        *inOutIdx += OPAQUE16_LEN;
+        if (ssl->options.haveMcast) {
+        #ifdef WOLFSSL_MULTICAST
+            ssl->keys.curPeerId = input[*inOutIdx];
+            ssl->keys.curSeq_hi = input[*inOutIdx+1];
+        #endif
+        }
+        else
+            ato16(input + *inOutIdx, &ssl->keys.curSeq_hi);
+        *inOutIdx += OPAQUE16_LEN;
+        ato32(input + *inOutIdx, &ssl->keys.curSeq_lo);
+        *inOutIdx += OPAQUE32_LEN;  /* advance past rest of seq */
+        ato16(input + *inOutIdx, size);
+        *inOutIdx += LENGTH_SZ;
+#endif
+    }
+
+#ifdef WOLFSSL_DTLS
+    if (IsDtlsNotSctpMode(ssl) && !DtlsCheckWindow(ssl)) {
+            WOLFSSL_LEAVE("GetRecordHeader()", SEQUENCE_ERROR);
+            return SEQUENCE_ERROR;
+    }
+#endif
+
+    /* catch version mismatch */
+#ifndef WOLFSSL_TLS13
+    if (rh->pvMajor != ssl->version.major || rh->pvMinor != ssl->version.minor)
+#else
+    if (rh->pvMajor != ssl->version.major ||
+        (rh->pvMinor != ssl->version.minor &&
+#ifdef WOLFSSL_TLS13_DRAFT_18
+         (!IsAtLeastTLSv1_3(ssl->version) || rh->pvMinor != TLSv1_MINOR)
+#else
+         (!IsAtLeastTLSv1_3(ssl->version) || rh->pvMinor != TLSv1_2_MINOR)
+#endif
+        ))
+#endif
+    {
+        if (ssl->options.side == WOLFSSL_SERVER_END &&
+            ssl->options.acceptState < ACCEPT_FIRST_REPLY_DONE)
+
+            WOLFSSL_MSG("Client attempting to connect with different version");
+        else if (ssl->options.side == WOLFSSL_CLIENT_END &&
+                                 ssl->options.downgrade &&
+                                 ssl->options.connectState < FIRST_REPLY_DONE)
+            WOLFSSL_MSG("Server attempting to accept with different version");
+        else if (ssl->options.dtls && rh->type == handshake)
+            /* Check the DTLS handshake message RH version later. */
+            WOLFSSL_MSG("DTLS handshake, skip RH version number check");
+        else {
+            WOLFSSL_MSG("SSL version error");
+            /* send alert per RFC5246 Appendix E. Backward Compatibility */
+            if (ssl->options.side == WOLFSSL_CLIENT_END) {
+#ifdef WOLFSSL_MYSQL_COMPATIBLE
+                SendAlert(ssl, alert_fatal, wc_protocol_version);
+#else
+                SendAlert(ssl, alert_fatal, protocol_version);
+#endif
+            }
+            return VERSION_ERROR;              /* only use requested version */
+        }
+    }
+
+    /* record layer length check */
+#ifdef HAVE_MAX_FRAGMENT
+    if (*size > (ssl->max_fragment + MAX_COMP_EXTRA + MAX_MSG_EXTRA)) {
+        SendAlert(ssl, alert_fatal, record_overflow);
+        return LENGTH_ERROR;
+    }
+#else
+    if (*size > (MAX_RECORD_SIZE + MAX_COMP_EXTRA + MAX_MSG_EXTRA))
+        return LENGTH_ERROR;
+#endif
+
+    /* verify record type here as well */
+    switch (rh->type) {
+        case handshake:
+        case change_cipher_spec:
+        case application_data:
+        case alert:
+            break;
+        case no_type:
+        default:
+            WOLFSSL_MSG("Unknown Record Type");
+            return UNKNOWN_RECORD_TYPE;
+    }
+
+    /* haven't decrypted this record yet */
+    ssl->keys.decryptedCur = 0;
+
+    return 0;
+}
+
+#ifndef WOLFSSL_NO_TLS12
+static int GetHandShakeHeader(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
+                              byte *type, word32 *size, word32 totalSz)
+{
+    const byte *ptr = input + *inOutIdx;
+    (void)ssl;
+
+    *inOutIdx += HANDSHAKE_HEADER_SZ;
+    if (*inOutIdx > totalSz)
+        return BUFFER_E;
+
+    *type = ptr[0];
+    c24to32(&ptr[1], size);
+
+    return 0;
+}
+#endif
+
+#ifdef WOLFSSL_DTLS
+static int GetDtlsHandShakeHeader(WOLFSSL* ssl, const byte* input,
+                                  word32* inOutIdx, byte *type, word32 *size,
+                                  word32 *fragOffset, word32 *fragSz,
+                                  word32 totalSz)
+{
+    word32 idx = *inOutIdx;
+
+    *inOutIdx += HANDSHAKE_HEADER_SZ + DTLS_HANDSHAKE_EXTRA;
+    if (*inOutIdx > totalSz) {
+        WOLFSSL_ERROR(BUFFER_E);
+        return BUFFER_E;
+    }
+
+    *type = input[idx++];
+    c24to32(input + idx, size);
+    idx += OPAQUE24_LEN;
+
+    ato16(input + idx, &ssl->keys.dtls_peer_handshake_number);
+    idx += DTLS_HANDSHAKE_SEQ_SZ;
+
+    c24to32(input + idx, fragOffset);
+    idx += DTLS_HANDSHAKE_FRAG_SZ;
+    c24to32(input + idx, fragSz);
+
+    if (ssl->curRL.pvMajor != ssl->version.major ||
+        ssl->curRL.pvMinor != ssl->version.minor) {
+
+        if (*type != client_hello && *type != hello_verify_request) {
+            WOLFSSL_ERROR(VERSION_ERROR);
+            return VERSION_ERROR;
+        }
+        else {
+            WOLFSSL_MSG("DTLS Handshake ignoring hello or verify version");
+        }
+    }
+    return 0;
+}
+#endif
+
+
+#if !defined(NO_OLD_TLS) || \
+    (defined(NO_OLD_TLS) && defined(WOLFSSL_ALLOW_TLS_SHA1))
+/* fill with MD5 pad size since biggest required */
+static const byte PAD1[PAD_MD5] =
+                              { 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+                                0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+                                0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+                                0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+                                0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+                                0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36
+                              };
+static const byte PAD2[PAD_MD5] =
+                              { 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
+                                0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
+                                0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
+                                0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
+                                0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
+                                0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c
+                              };
+#endif /* !NO_OLD_TLS || (NO_OLD_TLS && WOLFSSL_ALLOW_TLS_SHA1) */
+
+#ifndef NO_OLD_TLS
+
+/* calculate MD5 hash for finished */
+#ifdef WOLFSSL_TI_HASH
+#include <wolfssl/wolfcrypt/hash.h>
+#endif
+
+static int BuildMD5(WOLFSSL* ssl, Hashes* hashes, const byte* sender)
+{
+    int ret;
+    byte md5_result[WC_MD5_DIGEST_SIZE];
+#ifdef WOLFSSL_SMALL_STACK
+    wc_Md5* md5 = (wc_Md5*)XMALLOC(sizeof(wc_Md5), ssl->heap, DYNAMIC_TYPE_HASHCTX);
+    if (md5 == NULL)
+        return MEMORY_E;
+#else
+    wc_Md5  md5[1];
+#endif
+
+    /* make md5 inner */
+    ret = wc_Md5Copy(&ssl->hsHashes->hashMd5, md5);
+    if (ret == 0)
+        ret = wc_Md5Update(md5, sender, SIZEOF_SENDER);
+    if (ret == 0)
+        ret = wc_Md5Update(md5, ssl->arrays->masterSecret,SECRET_LEN);
+    if (ret == 0)
+        ret = wc_Md5Update(md5, PAD1, PAD_MD5);
+    if (ret == 0)
+        ret = wc_Md5Final(md5, md5_result);
+
+    /* make md5 outer */
+    if (ret == 0) {
+        ret = wc_InitMd5_ex(md5, ssl->heap, ssl->devId);
+        if (ret == 0) {
+            ret = wc_Md5Update(md5, ssl->arrays->masterSecret,SECRET_LEN);
+            if (ret == 0)
+                ret = wc_Md5Update(md5, PAD2, PAD_MD5);
+            if (ret == 0)
+                ret = wc_Md5Update(md5, md5_result, WC_MD5_DIGEST_SIZE);
+            if (ret == 0)
+                ret = wc_Md5Final(md5, hashes->md5);
+            wc_Md5Free(md5);
+        }
+    }
+
+#ifdef WOLFSSL_SMALL_STACK
+    XFREE(md5, ssl->heap, DYNAMIC_TYPE_HASHCTX);
+#endif
+
+    return ret;
+}
+
+
+/* calculate SHA hash for finished */
+static int BuildSHA(WOLFSSL* ssl, Hashes* hashes, const byte* sender)
+{
+    int ret;
+    byte sha_result[WC_SHA_DIGEST_SIZE];
+#ifdef WOLFSSL_SMALL_STACK
+    wc_Sha* sha = (wc_Sha*)XMALLOC(sizeof(wc_Sha), ssl->heap, DYNAMIC_TYPE_HASHCTX);
+    if (sha == NULL)
+        return MEMORY_E;
+#else
+    wc_Sha  sha[1];
+#endif
+    /* make sha inner */
+    ret = wc_ShaCopy(&ssl->hsHashes->hashSha, sha); /* Save current position */
+    if (ret == 0)
+        ret = wc_ShaUpdate(sha, sender, SIZEOF_SENDER);
+    if (ret == 0)
+        ret = wc_ShaUpdate(sha, ssl->arrays->masterSecret,SECRET_LEN);
+    if (ret == 0)
+        ret = wc_ShaUpdate(sha, PAD1, PAD_SHA);
+    if (ret == 0)
+        ret = wc_ShaFinal(sha, sha_result);
+
+    /* make sha outer */
+    if (ret == 0) {
+        ret = wc_InitSha_ex(sha, ssl->heap, ssl->devId);
+        if (ret == 0) {
+            ret = wc_ShaUpdate(sha, ssl->arrays->masterSecret,SECRET_LEN);
+            if (ret == 0)
+                ret = wc_ShaUpdate(sha, PAD2, PAD_SHA);
+            if (ret == 0)
+                ret = wc_ShaUpdate(sha, sha_result, WC_SHA_DIGEST_SIZE);
+            if (ret == 0)
+                ret = wc_ShaFinal(sha, hashes->sha);
+            wc_ShaFree(sha);
+        }
+    }
+
+#ifdef WOLFSSL_SMALL_STACK
+    XFREE(sha, ssl->heap, DYNAMIC_TYPE_HASHCTX);
+#endif
+
+    return ret;
+}
+#endif
+
+#ifndef WOLFSSL_NO_TLS12
+
+/* Finished doesn't support SHA512, not SHA512 cipher suites yet */
+static int BuildFinished(WOLFSSL* ssl, Hashes* hashes, const byte* sender)
+{
+    int ret = 0;
+
+    if (ssl == NULL)
+        return BAD_FUNC_ARG;
+
+#ifndef NO_TLS
+    if (ssl->options.tls) {
+        ret = BuildTlsFinished(ssl, hashes, sender);
+    }
+#endif
+#ifndef NO_OLD_TLS
+    if (!ssl->options.tls) {
+        ret = BuildMD5(ssl, hashes, sender);
+        if (ret == 0) {
+            ret = BuildSHA(ssl, hashes, sender);
+        }
+    }
+#endif
+
+    return ret;
+}
+
+#endif /* WOLFSSL_NO_TLS12 */
+
+#if !defined(NO_WOLFSSL_SERVER) || !defined(NO_WOLFSSL_CLIENT)
+    /* cipher requirements */
+    enum {
+        REQUIRES_RSA,
+        REQUIRES_DHE,
+        REQUIRES_ECC,
+        REQUIRES_ECC_STATIC,
+        REQUIRES_PSK,
+        REQUIRES_NTRU,
+        REQUIRES_RSA_SIG,
+        REQUIRES_AEAD
+    };
+
+
+
+    /* Does this cipher suite (first, second) have the requirement
+       an ephemeral key exchange will still require the key for signing
+       the key exchange so ECHDE_RSA requires an rsa key thus rsa_kea */
+    static int CipherRequires(byte first, byte second, int requirement)
+    {
+
+        (void)requirement;
+
+#ifndef WOLFSSL_NO_TLS12
+
+#ifdef HAVE_CHACHA
+        if (first == CHACHA_BYTE) {
+
+        switch (second) {
+        case TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 :
+            if (requirement == REQUIRES_RSA)
+                return 1;
+            break;
+
+        case TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 :
+            if (requirement == REQUIRES_ECC)
+                return 1;
+            break;
+
+        case TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256 :
+            if (requirement == REQUIRES_RSA)
+                return 1;
+            if (requirement == REQUIRES_DHE)
+                return 1;
+            break;
+
+        case TLS_ECDHE_RSA_WITH_CHACHA20_OLD_POLY1305_SHA256 :
+            if (requirement == REQUIRES_RSA)
+                return 1;
+            break;
+
+        case TLS_ECDHE_ECDSA_WITH_CHACHA20_OLD_POLY1305_SHA256 :
+            if (requirement == REQUIRES_ECC)
+                return 1;
+            break;
+
+        case TLS_DHE_RSA_WITH_CHACHA20_OLD_POLY1305_SHA256 :
+            if (requirement == REQUIRES_RSA)
+                return 1;
+            if (requirement == REQUIRES_DHE)
+                return 1;
+            break;
+
+
+        case TLS_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256 :
+            if (requirement == REQUIRES_PSK)
+                return 1;
+            break;
+
+        case TLS_PSK_WITH_CHACHA20_POLY1305_SHA256 :
+            if (requirement == REQUIRES_PSK)
+                return 1;
+            break;
+
+        case TLS_DHE_PSK_WITH_CHACHA20_POLY1305_SHA256 :
+            if (requirement == REQUIRES_PSK)
+                return 1;
+            if (requirement == REQUIRES_DHE)
+                return 1;
+            break;
+            }
+
+        if (requirement == REQUIRES_AEAD)
+            return 1;
+
+        }
+#endif /* HAVE_CHACHA */
+
+        /* ECC extensions */
+        if (first == ECC_BYTE) {
+
+        switch (second) {
+#if defined(HAVE_ECC) || defined(HAVE_CURVE25519) || defined(HAVE_CURVE448)
+    #ifndef NO_RSA
+        case TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA :
+            if (requirement == REQUIRES_RSA)
+                return 1;
+            break;
+
+        case TLS_ECDH_RSA_WITH_AES_128_CBC_SHA :
+            if (requirement == REQUIRES_ECC_STATIC)
+                return 1;
+            if (requirement == REQUIRES_RSA_SIG)
+                return 1;
+            break;
+
+    #ifndef NO_DES3
+        case TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA :
+            if (requirement == REQUIRES_RSA)
+                return 1;
+            break;
+
+        case TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA :
+            if (requirement == REQUIRES_ECC_STATIC)
+                return 1;
+            if (requirement == REQUIRES_RSA_SIG)
+                return 1;
+            break;
+    #endif /* !NO_DES3 */
+
+    #ifndef NO_RC4
+        case TLS_ECDHE_RSA_WITH_RC4_128_SHA :
+            if (requirement == REQUIRES_RSA)
+                return 1;
+            break;
+
+        case TLS_ECDH_RSA_WITH_RC4_128_SHA :
+            if (requirement == REQUIRES_ECC_STATIC)
+                return 1;
+            if (requirement == REQUIRES_RSA_SIG)
+                return 1;
+            break;
+    #endif /* !NO_RC4 */
+    #endif /* NO_RSA */
+
+    #ifndef NO_DES3
+        case TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA :
+            if (requirement == REQUIRES_ECC)
+                return 1;
+            break;
+
+        case TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA :
+            if (requirement == REQUIRES_ECC_STATIC)
+                return 1;
+            break;
+    #endif /* !NO_DES3  */
+    #ifndef NO_RC4
+        case TLS_ECDHE_ECDSA_WITH_RC4_128_SHA :
+            if (requirement == REQUIRES_ECC)
+                return 1;
+            break;
+
+        case TLS_ECDH_ECDSA_WITH_RC4_128_SHA :
+            if (requirement == REQUIRES_ECC_STATIC)
+                return 1;
+            break;
+    #endif /* !NO_RC4 */
+    #ifndef NO_RSA
+        case TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA :
+            if (requirement == REQUIRES_RSA)
+                return 1;
+            break;
+
+        case TLS_ECDH_RSA_WITH_AES_256_CBC_SHA :
+            if (requirement == REQUIRES_ECC_STATIC)
+                return 1;
+            if (requirement == REQUIRES_RSA_SIG)
+                return 1;
+            break;
+    #endif /* !NO_RSA */
+
+        case TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA :
+            if (requirement == REQUIRES_ECC)
+                return 1;
+            break;
+
+        case TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA :
+            if (requirement == REQUIRES_ECC_STATIC)
+                return 1;
+            break;
+
+        case TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA :
+            if (requirement == REQUIRES_ECC)
+                return 1;
+            break;
+
+        case TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA :
+            if (requirement == REQUIRES_ECC_STATIC)
+                return 1;
+            break;
+
+        case TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 :
+            if (requirement == REQUIRES_ECC)
+                return 1;
+            if (requirement == REQUIRES_AEAD)
+                return 1;
+            break;
+
+        case TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 :
+            if (requirement == REQUIRES_ECC)
+                return 1;
+            if (requirement == REQUIRES_AEAD)
+                return 1;
+            break;
+
+        case TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256 :
+            if (requirement == REQUIRES_ECC_STATIC)
+                return 1;
+            if (requirement == REQUIRES_AEAD)
+                return 1;
+            break;
+
+        case TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384 :
+            if (requirement == REQUIRES_ECC_STATIC)
+                return 1;
+            if (requirement == REQUIRES_AEAD)
+                return 1;
+            break;
+#endif /* HAVE_ECC || HAVE_CURVE25519 || HAVE_CURVE448 */
+
+#ifndef NO_RSA
+    #if defined(HAVE_ECC) || defined(HAVE_CURVE25519) || defined(HAVE_CURVE448)
+        case TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 :
+            if (requirement == REQUIRES_RSA)
+                return 1;
+            if (requirement == REQUIRES_AEAD)
+                return 1;
+            break;
+
+        case TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 :
+            if (requirement == REQUIRES_RSA)
+                return 1;
+            if (requirement == REQUIRES_AEAD)
+                return 1;
+            break;
+
+        case TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256 :
+            if (requirement == REQUIRES_ECC_STATIC)
+                return 1;
+            if (requirement == REQUIRES_RSA_SIG)
+                return 1;
+            if (requirement == REQUIRES_AEAD)
+                return 1;
+            break;
+
+        case TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384 :
+            if (requirement == REQUIRES_ECC_STATIC)
+                return 1;
+            if (requirement == REQUIRES_RSA_SIG)
+                return 1;
+            if (requirement == REQUIRES_AEAD)
+                return 1;
+            break;
+    #endif /* HAVE_ECC || HAVE_CURVE25519 || HAVE_CURVE448 */
+    #ifdef HAVE_AESCCM
+        case TLS_RSA_WITH_AES_128_CCM_8 :
+        case TLS_RSA_WITH_AES_256_CCM_8 :
+            if (requirement == REQUIRES_RSA)
+                return 1;
+            if (requirement == REQUIRES_RSA_SIG)
+                return 1;
+            if (requirement == REQUIRES_AEAD)
+                return 1;
+            break;
+    #endif /* HAVE_AESCCM */
+    #if defined(HAVE_ECC) || defined(HAVE_CURVE25519) || defined(HAVE_CURVE448)
+
+        case TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 :
+        case TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 :
+            if (requirement == REQUIRES_RSA)
+                return 1;
+            break;
+
+        case TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256 :
+        case TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384 :
+            if (requirement == REQUIRES_RSA_SIG)
+                return 1;
+            if (requirement == REQUIRES_ECC_STATIC)
+                return 1;
+            break;
+    #endif /* HAVE_ECC || HAVE_CURVE25519 || HAVE_CURVE448 */
+#endif /* !NO_RSA */
+
+#if defined(HAVE_ECC) || defined(HAVE_CURVE25519) || defined(HAVE_CURVE448)
+        case TLS_ECDHE_ECDSA_WITH_AES_128_CCM :
+        case TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8 :
+        case TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8 :
+            if (requirement == REQUIRES_ECC)
+                return 1;
+            if (requirement == REQUIRES_AEAD)
+                return 1;
+            break;
+
+        case TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 :
+        case TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 :
+            if (requirement == REQUIRES_ECC)
+                return 1;
+            break;
+
+        case TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256 :
+        case TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384 :
+            if (requirement == REQUIRES_ECC)
+                return 1;
+            if (requirement == REQUIRES_ECC_STATIC)
+                return 1;
+            break;
+#endif /* HAVE_ECC || HAVE_CURVE25519 || HAVE_CURVE448 */
+
+#ifndef NO_PSK
+        case TLS_PSK_WITH_AES_128_CCM:
+        case TLS_PSK_WITH_AES_256_CCM:
+        case TLS_PSK_WITH_AES_128_CCM_8:
+        case TLS_PSK_WITH_AES_256_CCM_8:
+            if (requirement == REQUIRES_PSK)
+                return 1;
+            if (requirement == REQUIRES_AEAD)
+                return 1;
+            break;
+
+        case TLS_DHE_PSK_WITH_AES_128_CCM:
+        case TLS_DHE_PSK_WITH_AES_256_CCM:
+            if (requirement == REQUIRES_PSK)
+                return 1;
+            if (requirement == REQUIRES_DHE)
+                return 1;
+            if (requirement == REQUIRES_AEAD)
+                return 1;
+            break;
+#endif /* !NO_PSK */
+#if defined(HAVE_ECC) || defined(HAVE_CURVE25519) || defined(HAVE_CURVE448)
+        case TLS_ECDHE_ECDSA_WITH_NULL_SHA :
+            if (requirement == REQUIRES_ECC)
+                return 1;
+            break;
+
+        case TLS_ECDHE_PSK_WITH_NULL_SHA256 :
+            if (requirement == REQUIRES_PSK)
+                return 1;
+            break;
+
+        case TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256 :
+            if (requirement == REQUIRES_PSK)
+                return 1;
+            break;
+#endif /* HAVE_ECC || HAVE_CURVE25519 || HAVE_CURVE448 */
+
+#if defined(WOLFSSL_TLS13) && defined(HAVE_NULL_CIPHER)
+        case TLS_SHA256_SHA256:
+            break;
+        case TLS_SHA384_SHA384:
+            break;
+#endif
+
+        default:
+            WOLFSSL_MSG("Unsupported cipher suite, CipherRequires ECC");
+            return 0;
+        }   /* switch */
+        }   /* if     */
+
+#endif /* !WOLFSSL_NO_TLS12 */
+
+        /* Distinct TLS v1.3 cipher suites with cipher and digest only. */
+        if (first == TLS13_BYTE) {
+
+            switch (second) {
+#ifdef WOLFSSL_TLS13
+            case TLS_AES_128_GCM_SHA256:
+            case TLS_AES_256_GCM_SHA384:
+            case TLS_CHACHA20_POLY1305_SHA256:
+            case TLS_AES_128_CCM_SHA256:
+            case TLS_AES_128_CCM_8_SHA256:
+                break;
+#endif
+
+            default:
+                WOLFSSL_MSG("Unsupported cipher suite, CipherRequires "
+                            "TLS v1.3");
+                return 0;
+            }
+        }
+
+#ifndef WOLFSSL_NO_TLS12
+
+        if (first != ECC_BYTE && first != CHACHA_BYTE &&
+            first != TLS13_BYTE) {   /* normal suites */
+        switch (second) {
+
+#ifndef NO_RSA
+    #ifndef NO_RC4
+        case SSL_RSA_WITH_RC4_128_SHA :
+            if (requirement == REQUIRES_RSA)
+                return 1;
+            break;
+
+        case SSL_RSA_WITH_RC4_128_MD5 :
+            if (requirement == REQUIRES_RSA)
+                return 1;
+            break;
+    #endif /* NO_RC4 */
+
+        case SSL_RSA_WITH_3DES_EDE_CBC_SHA :
+            if (requirement == REQUIRES_RSA)
+                return 1;
+            break;
+
+    #ifdef HAVE_NTRU
+        case TLS_NTRU_RSA_WITH_RC4_128_SHA :
+            if (requirement == REQUIRES_NTRU)
+                return 1;
+            break;
+    #endif /* HAVE_NTRU */
+
+        case TLS_RSA_WITH_AES_128_CBC_SHA :
+            if (requirement == REQUIRES_RSA)
+                return 1;
+            break;
+
+        case TLS_RSA_WITH_AES_128_CBC_SHA256 :
+            if (requirement == REQUIRES_RSA)
+                return 1;
+            break;
+
+    #ifdef HAVE_NTRU
+        case TLS_NTRU_RSA_WITH_3DES_EDE_CBC_SHA :
+            if (requirement == REQUIRES_NTRU)
+                return 1;
+            break;
+    #endif /* HAVE_NTRU */
+
+        case TLS_RSA_WITH_AES_256_CBC_SHA :
+            if (requirement == REQUIRES_RSA)
+                return 1;
+            break;
+
+    #ifdef HAVE_NTRU
+        case TLS_NTRU_RSA_WITH_AES_128_CBC_SHA :
+            if (requirement == REQUIRES_NTRU)
+                return 1;
+            break;
+    #endif /* HAVE_NTRU */
+
+        case TLS_RSA_WITH_AES_256_CBC_SHA256 :
+            if (requirement == REQUIRES_RSA)
+                return 1;
+            break;
+
+        case TLS_RSA_WITH_NULL_MD5 :
+        case TLS_RSA_WITH_NULL_SHA :
+        case TLS_RSA_WITH_NULL_SHA256 :
+            if (requirement == REQUIRES_RSA)
+                return 1;
+            break;
+
+    #ifdef HAVE_NTRU
+        case TLS_NTRU_RSA_WITH_AES_256_CBC_SHA :
+            if (requirement == REQUIRES_NTRU)
+                return 1;
+            break;
+    #endif /* HAVE_NTRU */
+
+    #ifdef HAVE_IDEA
+        case SSL_RSA_WITH_IDEA_CBC_SHA :
+            if (requirement == REQUIRES_RSA)
+                return 1;
+            break;
+    #endif /* HAVE_IDEA */
+#endif /* !NO_RSA */
+
+#ifndef NO_PSK
+        case TLS_PSK_WITH_AES_128_GCM_SHA256 :
+            if (requirement == REQUIRES_PSK)
+                return 1;
+            if (requirement == REQUIRES_AEAD)
+                return 1;
+            break;
+
+        case TLS_PSK_WITH_AES_256_GCM_SHA384 :
+            if (requirement == REQUIRES_PSK)
+                return 1;
+            if (requirement == REQUIRES_AEAD)
+                return 1;
+            break;
+
+        case TLS_PSK_WITH_AES_128_CBC_SHA256 :
+        case TLS_PSK_WITH_AES_256_CBC_SHA384 :
+        case TLS_PSK_WITH_AES_128_CBC_SHA :
+        case TLS_PSK_WITH_AES_256_CBC_SHA :
+        case TLS_PSK_WITH_NULL_SHA384 :
+        case TLS_PSK_WITH_NULL_SHA256 :
+        case TLS_PSK_WITH_NULL_SHA :
+            if (requirement == REQUIRES_PSK)
+                return 1;
+            break;
+
+        case TLS_DHE_PSK_WITH_AES_128_GCM_SHA256 :
+        case TLS_DHE_PSK_WITH_AES_256_GCM_SHA384 :
+            if (requirement == REQUIRES_DHE)
+                return 1;
+            if (requirement == REQUIRES_PSK)
+                return 1;
+            if (requirement == REQUIRES_AEAD)
+                return 1;
+            break;
+
+        case TLS_DHE_PSK_WITH_AES_128_CBC_SHA256 :
+        case TLS_DHE_PSK_WITH_AES_256_CBC_SHA384 :
+        case TLS_DHE_PSK_WITH_NULL_SHA384 :
+        case TLS_DHE_PSK_WITH_NULL_SHA256 :
+            if (requirement == REQUIRES_DHE)
+                return 1;
+            if (requirement == REQUIRES_PSK)
+                return 1;
+            break;
+#endif /* NO_PSK */
+
+#ifndef NO_RSA
+        case TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 :
+            if (requirement == REQUIRES_RSA)
+                return 1;
+            if (requirement == REQUIRES_DHE)
+                return 1;
+            break;
+
+        case TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 :
+            if (requirement == REQUIRES_RSA)
+                return 1;
+            if (requirement == REQUIRES_DHE)
+                return 1;
+            break;
+
+        case TLS_DHE_RSA_WITH_AES_128_CBC_SHA :
+            if (requirement == REQUIRES_RSA)
+                return 1;
+            if (requirement == REQUIRES_DHE)
+                return 1;
+            break;
+
+        case TLS_DHE_RSA_WITH_AES_256_CBC_SHA :
+            if (requirement == REQUIRES_RSA)
+                return 1;
+            if (requirement == REQUIRES_DHE)
+                return 1;
+            break;
+
+#ifndef NO_HC128
+        case TLS_RSA_WITH_HC_128_MD5 :
+            if (requirement == REQUIRES_RSA)
+                return 1;
+            break;
+
+        case TLS_RSA_WITH_HC_128_SHA :
+            if (requirement == REQUIRES_RSA)
+                return 1;
+            break;
+#endif /* NO_HC128 */
+
+#ifndef NO_RABBIT
+        case TLS_RSA_WITH_RABBIT_SHA :
+            if (requirement == REQUIRES_RSA)
+                return 1;
+            break;
+#endif /* !NO_RABBIT */
+
+        case TLS_RSA_WITH_AES_128_GCM_SHA256 :
+        case TLS_RSA_WITH_AES_256_GCM_SHA384 :
+            if (requirement == REQUIRES_RSA)
+                return 1;
+            if (requirement == REQUIRES_AEAD)
+                return 1;
+            break;
+
+        case TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 :
+        case TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 :
+            if (requirement == REQUIRES_RSA)
+                return 1;
+            if (requirement == REQUIRES_DHE)
+                return 1;
+            if (requirement == REQUIRES_AEAD)
+                return 1;
+            break;
+
+#ifdef HAVE_CAMELLIA
+        case TLS_RSA_WITH_CAMELLIA_128_CBC_SHA :
+        case TLS_RSA_WITH_CAMELLIA_256_CBC_SHA :
+        case TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256 :
+        case TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256 :
+            if (requirement == REQUIRES_RSA)
+                return 1;
+            break;
+
+        case TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA :
+        case TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA :
+        case TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256 :
+        case TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256 :
+            if (requirement == REQUIRES_RSA)
+                return 1;
+            if (requirement == REQUIRES_RSA_SIG)
+                return 1;
+            if (requirement == REQUIRES_DHE)
+                return 1;
+            break;
+#endif /* HAVE_CAMELLIA */
+
+        case TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA:
+            if (requirement == REQUIRES_RSA)
+                return 1;
+            if (requirement == REQUIRES_RSA_SIG)
+                return 1;
+            if (requirement == REQUIRES_DHE)
+                return 1;
+            break;
+#endif
+#ifdef HAVE_ANON
+        case TLS_DH_anon_WITH_AES_128_CBC_SHA :
+            if (requirement == REQUIRES_DHE)
+                return 1;
+            break;
+        case TLS_DH_anon_WITH_AES_256_GCM_SHA384:
+            if (requirement == REQUIRES_DHE)
+                return 1;
+            if (requirement == REQUIRES_AEAD)
+                return 1;
+            break;
+#endif
+#ifdef WOLFSSL_MULTICAST
+        case WDM_WITH_NULL_SHA256 :
+            break;
+#endif
+
+        default:
+            WOLFSSL_MSG("Unsupported cipher suite, CipherRequires");
+            return 0;
+        }  /* switch */
+        }  /* if ECC / Normal suites else */
+
+#endif /* !WOLFSSL_NO_TLS12 */
+
+        return 0;
+    }
+
+#endif /* !NO_WOLFSSL_SERVER && !NO_WOLFSSL_CLIENT */
+
+
+#ifndef NO_CERTS
+
+
+/* Match names with wildcards, each wildcard can represent a single name
+   component or fragment but not multiple names, i.e.,
+   *.z.com matches y.z.com but not x.y.z.com
+
+   return 1 on success */
+int MatchDomainName(const char* pattern, int len, const char* str)
+{
+    int ret = 0;
+    char p, s;
+
+    if (pattern == NULL || str == NULL || len <= 0)
+        return 0;
+
+    while (len > 0) {
+
+        p = (char)XTOLOWER((unsigned char)*pattern++);
+        if (p == '\0')
+            break;
+
+        if (p == '*') {
+            while (--len > 0 &&
+                (p = (char)XTOLOWER((unsigned char)*pattern++)) == '*') {
+            }
+
+            if (len == 0)
+                p = '\0';
+
+            while ( (s = (char)XTOLOWER((unsigned char) *str)) != '\0') {
+                if (s == p)
+                    break;
+                if (s == '.')
+                    return 0;
+                str++;
+            }
+        }
+        else {
+            if (p != (char)XTOLOWER((unsigned char) *str))
+                return 0;
+        }
+
+
+        if (len > 0) {
+            str++;
+            len--;
+        }
+    }
+
+    if (*str == '\0' && len == 0) {
+        ret = 1; /* success */
+    }
+
+    return ret;
+}
+
+
+/* try to find an altName match to domain, return 1 on success */
+int CheckAltNames(DecodedCert* dCert, char* domain)
+{
+    int        match = 0;
+    DNS_entry* altName = NULL;
+
+    WOLFSSL_MSG("Checking AltNames");
+
+    if (dCert)
+        altName = dCert->altNames;
+
+    while (altName) {
+        WOLFSSL_MSG("\tindividual AltName check");
+
+        if (MatchDomainName(altName->name, altName->len, domain)){
+            match = 1;
+            break;
+        }
+
+        altName = altName->next;
+    }
+
+    return match;
+}
+
+#ifdef OPENSSL_EXTRA
+/* Check that alternative names, if they exists, match the domain.
+ * Fail if there are wild patterns and they didn't match.
+ * Check the common name if no alternative names matched.
+ *
+ * dCert    Decoded cert to get the alternative names from.
+ * domain   Domain name to compare against.
+ * checkCN  Whether to check the common name.
+ * returns whether there was a problem in matching.
+ */
+static int CheckForAltNames(DecodedCert* dCert, char* domain, int* checkCN)
+{
+    int        match;
+    DNS_entry* altName = NULL;
+
+    WOLFSSL_MSG("Checking AltNames");
+
+    if (dCert)
+        altName = dCert->altNames;
+
+    *checkCN = altName == NULL;
+    match = 0;
+    while (altName) {
+        WOLFSSL_MSG("\tindividual AltName check");
+
+        if (MatchDomainName(altName->name, altName->len, domain)) {
+            match = 1;
+            *checkCN = 0;
+            break;
+        }
+        /* No matches and wild pattern match failed. */
+        else if (altName->name && altName->len >=1 &&
+                altName->name[0] == '*' && match == 0) {
+            match = -1;
+        }
+
+        altName = altName->next;
+    }
+
+    return match != -1;
+}
+
+/* Check the domain name matches the subject alternative name or the subject
+ * name.
+ *
+ * dcert          Decoded certificate.
+ * domainName     The domain name.
+ * domainNameLen  The length of the domain name.
+ * returns DOMAIN_NAME_MISMATCH when no match found and 0 on success.
+ */
+int CheckHostName(DecodedCert* dCert, char *domainName, size_t domainNameLen)
+{
+    int checkCN;
+
+    /* Assume name is NUL terminated. */
+    (void)domainNameLen;
+
+    if (CheckForAltNames(dCert, domainName, &checkCN) == 0) {
+        WOLFSSL_MSG("DomainName match on alt names failed too");
+        return DOMAIN_NAME_MISMATCH;
+    }
+    if (checkCN == 1) {
+        if (MatchDomainName(dCert->subjectCN, dCert->subjectCNLen,
+                            domainName) == 0) {
+            WOLFSSL_MSG("DomainName match on common name failed");
+            return DOMAIN_NAME_MISMATCH;
+        }
+    }
+
+    return 0;
+}
+
+int CheckIPAddr(DecodedCert* dCert, char* ipasc)
+{
+    WOLFSSL_MSG("Checking IPAddr");
+
+    return CheckHostName(dCert, ipasc, (size_t)XSTRLEN(ipasc));
+}
+#endif
+
+#ifdef SESSION_CERTS
+static void AddSessionCertToChain(WOLFSSL_X509_CHAIN* chain,
+    byte* certBuf, word32 certSz)
+{
+   if (chain->count < MAX_CHAIN_DEPTH &&
+                               certSz < MAX_X509_SIZE) {
+        chain->certs[chain->count].length = certSz;
+        XMEMCPY(chain->certs[chain->count].buffer, certBuf, certSz);
+        chain->count++;
+    }
+    else {
+        WOLFSSL_MSG("Couldn't store chain cert for session");
+    }
+}
+#endif
+
+#if defined(KEEP_PEER_CERT) || defined(SESSION_CERTS) || \
+    defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
+/* Copy parts X509 needs from Decoded cert, 0 on success */
+/* The same DecodedCert cannot be copied to WOLFSSL_X509 twice otherwise the
+ * altNames pointers could be free'd by second x509 still active by first */
+int CopyDecodedToX509(WOLFSSL_X509* x509, DecodedCert* dCert)
+{
+    int ret = 0;
+
+    if (x509 == NULL || dCert == NULL ||
+        dCert->subjectCNLen < 0)
+        return BAD_FUNC_ARG;
+
+    x509->version = dCert->version + 1;
+
+    XSTRNCPY(x509->issuer.name, dCert->issuer, ASN_NAME_MAX);
+    x509->issuer.name[ASN_NAME_MAX - 1] = '\0';
+    x509->issuer.sz = (int)XSTRLEN(x509->issuer.name) + 1;
+#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
+    if (dCert->issuerName.fullName != NULL) {
+        XMEMCPY(&x509->issuer.fullName,
+                                       &dCert->issuerName, sizeof(DecodedName));
+        x509->issuer.fullName.fullName = (char*)XMALLOC(
+                        dCert->issuerName.fullNameLen, x509->heap,
+                        DYNAMIC_TYPE_X509);
+        if (x509->issuer.fullName.fullName != NULL)
+            XMEMCPY(x509->issuer.fullName.fullName,
+                     dCert->issuerName.fullName, dCert->issuerName.fullNameLen);
+    }
+    x509->issuer.x509 = x509;
+#endif /* OPENSSL_EXTRA || OPENSSL_EXTRA_X509_SMALL */
+
+    XSTRNCPY(x509->subject.name, dCert->subject, ASN_NAME_MAX);
+    x509->subject.name[ASN_NAME_MAX - 1] = '\0';
+    x509->subject.sz = (int)XSTRLEN(x509->subject.name) + 1;
+#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
+    if (dCert->subjectName.fullName != NULL) {
+        XMEMCPY(&x509->subject.fullName,
+                                      &dCert->subjectName, sizeof(DecodedName));
+        x509->subject.fullName.fullName = (char*)XMALLOC(
+                 dCert->subjectName.fullNameLen, x509->heap, DYNAMIC_TYPE_X509);
+        if (x509->subject.fullName.fullName != NULL)
+            XMEMCPY(x509->subject.fullName.fullName,
+                   dCert->subjectName.fullName, dCert->subjectName.fullNameLen);
+    }
+    x509->subject.x509 = x509;
+#endif /* OPENSSL_EXTRA || OPENSSL_EXTRA_X509_SMALL */
+#if defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX)
+    x509->subject.rawLen = min(dCert->subjectRawLen, sizeof(x509->subject.raw));
+    XMEMCPY(x509->subject.raw, dCert->subjectRaw, x509->subject.rawLen);
+#ifdef WOLFSSL_CERT_EXT
+    x509->issuer.rawLen = min(dCert->issuerRawLen, sizeof(x509->issuer.raw));
+    XMEMCPY(x509->issuer.raw, dCert->issuerRaw, x509->issuer.rawLen);
+#endif
+#endif
+
+    XMEMCPY(x509->serial, dCert->serial, EXTERNAL_SERIAL_SIZE);
+    x509->serialSz = dCert->serialSz;
+    if (dCert->subjectCN && dCert->subjectCNLen < ASN_NAME_MAX) {
+        XMEMCPY(x509->subjectCN, dCert->subjectCN, dCert->subjectCNLen);
+        x509->subjectCN[dCert->subjectCNLen] = '\0';
+    }
+    else
+        x509->subjectCN[0] = '\0';
+
+#ifdef WOLFSSL_SEP
+    {
+        int minSz = min(dCert->deviceTypeSz, EXTERNAL_SERIAL_SIZE);
+        if (minSz > 0) {
+            x509->deviceTypeSz = minSz;
+            XMEMCPY(x509->deviceType, dCert->deviceType, minSz);
+        }
+        else
+            x509->deviceTypeSz = 0;
+        minSz = min(dCert->hwTypeSz, EXTERNAL_SERIAL_SIZE);
+        if (minSz > 0) {
+            x509->hwTypeSz = minSz;
+            XMEMCPY(x509->hwType, dCert->hwType, minSz);
+        }
+        else
+            x509->hwTypeSz = 0;
+        minSz = min(dCert->hwSerialNumSz, EXTERNAL_SERIAL_SIZE);
+        if (minSz > 0) {
+            x509->hwSerialNumSz = minSz;
+            XMEMCPY(x509->hwSerialNum, dCert->hwSerialNum, minSz);
+        }
+        else
+            x509->hwSerialNumSz = 0;
+    }
+#endif /* WOLFSSL_SEP */
+    {
+        int minSz;
+        if (dCert->beforeDateLen > 0) {
+            minSz = min(dCert->beforeDate[1], MAX_DATE_SZ);
+            x509->notBefore.type = dCert->beforeDate[0];
+            x509->notBefore.length = minSz;
+            XMEMCPY(x509->notBefore.data, &dCert->beforeDate[2], minSz);
+        }
+        else
+            x509->notBefore.length = 0;
+        if (dCert->afterDateLen > 0) {
+            minSz = min(dCert->afterDate[1], MAX_DATE_SZ);
+            x509->notAfter.type = dCert->afterDate[0];
+            x509->notAfter.length = minSz;
+            XMEMCPY(x509->notAfter.data, &dCert->afterDate[2], minSz);
+        }
+        else
+            x509->notAfter.length = 0;
+    }
+
+    if (dCert->publicKey != NULL && dCert->pubKeySize != 0) {
+        x509->pubKey.buffer = (byte*)XMALLOC(
+                        dCert->pubKeySize, x509->heap, DYNAMIC_TYPE_PUBLIC_KEY);
+        if (x509->pubKey.buffer != NULL) {
+            x509->pubKeyOID = dCert->keyOID;
+            x509->pubKey.length = dCert->pubKeySize;
+            XMEMCPY(x509->pubKey.buffer, dCert->publicKey, dCert->pubKeySize);
+        }
+        else
+            ret = MEMORY_E;
+#if defined(OPENSSL_ALL)
+        if (ret == 0) {
+            x509->key.pubKeyOID = dCert->keyOID;
+
+            if (!x509->key.algor) {
+                x509->key.algor = wolfSSL_X509_ALGOR_new();
+            } else {
+                wolfSSL_ASN1_OBJECT_free(x509->key.algor->algorithm);
+            }
+            if (!(x509->key.algor->algorithm =
+                    wolfSSL_OBJ_nid2obj(dCert->keyOID))) {
+                ret = PUBLIC_KEY_E;
+            }
+
+            wolfSSL_EVP_PKEY_free(x509->key.pkey);
+            if (!(x509->key.pkey = wolfSSL_d2i_PUBKEY(NULL,
+                                                      &dCert->publicKey,
+                                                      dCert->pubKeySize))) {
+                ret = PUBLIC_KEY_E;
+            }
+        }
+#endif
+    }
+
+    if (dCert->signature != NULL && dCert->sigLength != 0 &&
+            dCert->sigLength <= MAX_ENCODED_SIG_SZ) {
+        x509->sig.buffer = (byte*)XMALLOC(
+                          dCert->sigLength, x509->heap, DYNAMIC_TYPE_SIGNATURE);
+        if (x509->sig.buffer == NULL) {
+            ret = MEMORY_E;
+        }
+        else {
+            XMEMCPY(x509->sig.buffer, dCert->signature, dCert->sigLength);
+            x509->sig.length = dCert->sigLength;
+            x509->sigOID = dCert->signatureOID;
+        }
+#if defined(OPENSSL_ALL)
+        wolfSSL_ASN1_OBJECT_free(x509->algor.algorithm);
+        if (!(x509->algor.algorithm =
+                wolfSSL_OBJ_nid2obj(dCert->signatureOID))) {
+            ret = PUBLIC_KEY_E;
+        }
+#endif
+    }
+
+    /* store cert for potential retrieval */
+    if (AllocDer(&x509->derCert, dCert->maxIdx, CERT_TYPE, x509->heap) == 0) {
+        XMEMCPY(x509->derCert->buffer, dCert->source, dCert->maxIdx);
+    }
+    else {
+        ret = MEMORY_E;
+    }
+
+    x509->altNames       = dCert->altNames;
+    dCert->weOwnAltNames = 0;
+    x509->altNamesNext   = x509->altNames;  /* index hint */
+
+#if (defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)) && \
+    !defined(IGNORE_NAME_CONSTRAINTS)
+    /* add copies of alternate emails from dCert to X509 */
+    if (dCert->altEmailNames != NULL) {
+        DNS_entry* cur = dCert->altEmailNames;
+
+        while (cur != NULL) {
+            if (cur->type == ASN_RFC822_TYPE) {
+                DNS_entry* dnsEntry;
+                int strLen = cur->len;
+
+                dnsEntry = (DNS_entry*)XMALLOC(sizeof(DNS_entry), x509->heap,
+                                        DYNAMIC_TYPE_ALTNAME);
+                if (dnsEntry == NULL) {
+                    WOLFSSL_MSG("\tOut of Memory");
+                    return MEMORY_E;
+                }
+
+                dnsEntry->type = ASN_RFC822_TYPE;
+                dnsEntry->name = (char*)XMALLOC(strLen + 1, x509->heap,
+                                         DYNAMIC_TYPE_ALTNAME);
+                if (dnsEntry->name == NULL) {
+                    WOLFSSL_MSG("\tOut of Memory");
+                    XFREE(dnsEntry, x509->heap, DYNAMIC_TYPE_ALTNAME);
+                    return MEMORY_E;
+                }
+                dnsEntry->len = strLen;
+                XMEMCPY(dnsEntry->name, cur->name, strLen);
+                dnsEntry->name[strLen] = '\0';
+
+                dnsEntry->next = x509->altNames;
+                x509->altNames = dnsEntry;
+            }
+            cur = cur->next;
+        }
+    }
+#endif /* OPENSSL_EXTRA || OPENSSL_EXTRA_X509_SMALL */
+
+    x509->isCa = dCert->isCA;
+#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
+    x509->pathLength = dCert->pathLength;
+    x509->keyUsage = dCert->extKeyUsage;
+
+    x509->CRLdistSet = dCert->extCRLdistSet;
+    x509->CRLdistCrit = dCert->extCRLdistCrit;
+    x509->CRLInfo = dCert->extCrlInfo;
+    x509->CRLInfoSz = dCert->extCrlInfoSz;
+    x509->authInfoSet = dCert->extAuthInfoSet;
+    x509->authInfoCrit = dCert->extAuthInfoCrit;
+    if (dCert->extAuthInfo != NULL && dCert->extAuthInfoSz > 0) {
+        x509->authInfo = (byte*)XMALLOC(dCert->extAuthInfoSz, x509->heap,
+                DYNAMIC_TYPE_X509_EXT);
+        if (x509->authInfo != NULL) {
+            XMEMCPY(x509->authInfo, dCert->extAuthInfo, dCert->extAuthInfoSz);
+            x509->authInfoSz = dCert->extAuthInfoSz;
+        }
+        else {
+            ret = MEMORY_E;
+        }
+    }
+    #if defined(OPENSSL_ALL) || defined(WOLFSSL_QT)
+    if (dCert->extAuthInfoCaIssuer != NULL && dCert->extAuthInfoCaIssuerSz > 0) {
+        x509->authInfoCaIssuer = (byte*)XMALLOC(dCert->extAuthInfoCaIssuerSz, x509->heap,
+                DYNAMIC_TYPE_X509_EXT);
+        if (x509->authInfoCaIssuer != NULL) {
+            XMEMCPY(x509->authInfoCaIssuer, dCert->extAuthInfoCaIssuer, dCert->extAuthInfoCaIssuerSz);
+            x509->authInfoCaIssuerSz = dCert->extAuthInfoCaIssuerSz;
+        }
+        else {
+            ret = MEMORY_E;
+        }
+    }
+    #endif
+    x509->basicConstSet = dCert->extBasicConstSet;
+    x509->basicConstCrit = dCert->extBasicConstCrit;
+    x509->basicConstPlSet = dCert->pathLengthSet;
+    x509->subjAltNameSet = dCert->extSubjAltNameSet;
+    x509->subjAltNameCrit = dCert->extSubjAltNameCrit;
+    x509->authKeyIdSet = dCert->extAuthKeyIdSet;
+    x509->authKeyIdCrit = dCert->extAuthKeyIdCrit;
+    if (dCert->extAuthKeyIdSrc != NULL && dCert->extAuthKeyIdSz != 0) {
+        x509->authKeyId = (byte*)XMALLOC(dCert->extAuthKeyIdSz, x509->heap,
+                                         DYNAMIC_TYPE_X509_EXT);
+        if (x509->authKeyId != NULL) {
+            XMEMCPY(x509->authKeyId,
+                                 dCert->extAuthKeyIdSrc, dCert->extAuthKeyIdSz);
+            x509->authKeyIdSz = dCert->extAuthKeyIdSz;
+        }
+        else
+            ret = MEMORY_E;
+    }
+    x509->subjKeyIdSet = dCert->extSubjKeyIdSet;
+    x509->subjKeyIdCrit = dCert->extSubjKeyIdCrit;
+    if (dCert->extSubjKeyIdSrc != NULL && dCert->extSubjKeyIdSz != 0) {
+        x509->subjKeyId = (byte*)XMALLOC(dCert->extSubjKeyIdSz, x509->heap,
+                                         DYNAMIC_TYPE_X509_EXT);
+        if (x509->subjKeyId != NULL) {
+            XMEMCPY(x509->subjKeyId,
+                                 dCert->extSubjKeyIdSrc, dCert->extSubjKeyIdSz);
+            x509->subjKeyIdSz = dCert->extSubjKeyIdSz;
+        }
+        else
+            ret = MEMORY_E;
+    }
+    x509->keyUsageSet = dCert->extKeyUsageSet;
+    x509->keyUsageCrit = dCert->extKeyUsageCrit;
+    if (dCert->extExtKeyUsageSrc != NULL && dCert->extExtKeyUsageSz > 0) {
+        x509->extKeyUsageSrc = (byte*)XMALLOC(dCert->extExtKeyUsageSz,
+                x509->heap, DYNAMIC_TYPE_X509_EXT);
+        if (x509->extKeyUsageSrc != NULL) {
+            XMEMCPY(x509->extKeyUsageSrc, dCert->extExtKeyUsageSrc,
+                                                       dCert->extExtKeyUsageSz);
+            x509->extKeyUsageSz    = dCert->extExtKeyUsageSz;
+            x509->extKeyUsageCrit  = dCert->extExtKeyUsageCrit;
+            x509->extKeyUsageCount = dCert->extExtKeyUsageCount;
+        }
+        else {
+            ret = MEMORY_E;
+        }
+    }
+    #if defined(WOLFSSL_SEP) || defined(WOLFSSL_QT)
+        x509->certPolicySet = dCert->extCertPolicySet;
+        x509->certPolicyCrit = dCert->extCertPolicyCrit;
+    #endif /* WOLFSSL_SEP || WOLFSSL_QT */
+    #ifdef WOLFSSL_CERT_EXT
+        {
+            int i;
+            for (i = 0; i < dCert->extCertPoliciesNb && i < MAX_CERTPOL_NB; i++)
+                XMEMCPY(x509->certPolicies[i], dCert->extCertPolicies[i],
+                                                                MAX_CERTPOL_SZ);
+            x509->certPoliciesNb = dCert->extCertPoliciesNb;
+        }
+    #endif /* WOLFSSL_CERT_EXT */
+#endif /* OPENSSL_EXTRA || OPENSSL_EXTRA_X509_SMALL */
+#if defined(HAVE_ECC) || defined(HAVE_ED25519) || defined(HAVE_ED448)
+    x509->pkCurveOID = dCert->pkCurveOID;
+#endif /* HAVE_ECC || HAVE_CURVE25519 || HAVE_CURVE448 */
+
+    return ret;
+}
+
+#endif /* KEEP_PEER_CERT || SESSION_CERTS */
+
+#if defined(HAVE_CERTIFICATE_STATUS_REQUEST) || \
+     (defined(HAVE_CERTIFICATE_STATUS_REQUEST_V2) && !defined(WOLFSSL_NO_TLS12))
+static int ProcessCSR(WOLFSSL* ssl, byte* input, word32* inOutIdx,
+                      word32 status_length)
+{
+    int ret = 0;
+    OcspRequest* request;
+
+    #ifdef WOLFSSL_SMALL_STACK
+        CertStatus* status;
+        OcspResponse* response;
+    #else
+        CertStatus status[1];
+        OcspResponse response[1];
+    #endif
+
+    do {
+        #ifdef HAVE_CERTIFICATE_STATUS_REQUEST
+            if (ssl->status_request) {
+                request = (OcspRequest*)TLSX_CSR_GetRequest(ssl->extensions);
+                ssl->status_request = 0;
+                break;
+            }
+        #endif
+
+        #ifdef HAVE_CERTIFICATE_STATUS_REQUEST_V2
+            if (ssl->status_request_v2) {
+                request = (OcspRequest*)TLSX_CSR2_GetRequest(ssl->extensions,
+                                                          WOLFSSL_CSR2_OCSP, 0);
+                ssl->status_request_v2 = 0;
+                break;
+            }
+        #endif
+
+        return BUFFER_ERROR;
+    } while(0);
+
+    if (request == NULL)
+        return BAD_CERTIFICATE_STATUS_ERROR; /* not expected */
+
+    #ifdef WOLFSSL_SMALL_STACK
+        status = (CertStatus*)XMALLOC(sizeof(CertStatus), ssl->heap,
+                                                      DYNAMIC_TYPE_OCSP_STATUS);
+        response = (OcspResponse*)XMALLOC(sizeof(OcspResponse), ssl->heap,
+                                                     DYNAMIC_TYPE_OCSP_REQUEST);
+
+        if (status == NULL || response == NULL) {
+            if (status)
+                XFREE(status, NULL, DYNAMIC_TYPE_OCSP_STATUS);
+            if (response)
+                XFREE(response, NULL, DYNAMIC_TYPE_OCSP_REQUEST);
+
+            return MEMORY_ERROR;
+        }
+    #endif
+
+    InitOcspResponse(response, status, input +*inOutIdx, status_length);
+
+    if (OcspResponseDecode(response, ssl->ctx->cm, ssl->heap, 0) != 0)
+        ret = BAD_CERTIFICATE_STATUS_ERROR;
+    else if (CompareOcspReqResp(request, response) != 0)
+        ret = BAD_CERTIFICATE_STATUS_ERROR;
+    else if (response->responseStatus != OCSP_SUCCESSFUL)
+        ret = BAD_CERTIFICATE_STATUS_ERROR;
+    else if (response->status->status == CERT_REVOKED)
+        ret = OCSP_CERT_REVOKED;
+    else if (response->status->status != CERT_GOOD)
+        ret = BAD_CERTIFICATE_STATUS_ERROR;
+
+    *inOutIdx += status_length;
+
+    #ifdef WOLFSSL_SMALL_STACK
+        XFREE(status,   ssl->heap, DYNAMIC_TYPE_OCSP_STATUS);
+        XFREE(response, ssl->heap, DYNAMIC_TYPE_OCSP_REQUEST);
+    #endif
+
+    return ret;
+}
+#endif
+
+
+
+#ifdef HAVE_PK_CALLBACKS
+
+#ifdef HAVE_ECC
+    static int SigPkCbEccVerify(const unsigned char* sig, unsigned int sigSz,
+       const unsigned char* hash, unsigned int hashSz,
+       const unsigned char* keyDer, unsigned int keySz,
+       int* result, void* ctx)
+    {
+        int ret = NOT_COMPILED_IN;
+        WOLFSSL* ssl = (WOLFSSL*)ctx;
+
+        if (ssl && ssl->ctx->EccVerifyCb) {
+            ret = ssl->ctx->EccVerifyCb(ssl, sig, sigSz, hash, hashSz,
+                keyDer, keySz, result, ssl->EccVerifyCtx);
+        }
+        return ret;
+    }
+#endif
+#ifndef NO_RSA
+    static int SigPkCbRsaVerify(unsigned char* sig, unsigned int sigSz,
+       unsigned char** out, const unsigned char* keyDer, unsigned int keySz,
+       void* ctx)
+    {
+        int ret = NOT_COMPILED_IN;
+        WOLFSSL* ssl = (WOLFSSL*)ctx;
+
+        if (ssl && ssl->ctx->RsaVerifyCb) {
+            ret = ssl->ctx->RsaVerifyCb(ssl, sig, sigSz, out, keyDer, keySz,
+                ssl->RsaVerifyCtx);
+        }
+        return ret;
+    }
+#endif
+
+int InitSigPkCb(WOLFSSL* ssl, SignatureCtx* sigCtx)
+{
+    if (ssl == NULL || sigCtx == NULL)
+        return BAD_FUNC_ARG;
+
+    /* only setup the verify callback if a PK is set */
+#ifdef HAVE_ECC
+    if (ssl->ctx->EccVerifyCb) {
+        sigCtx->pkCbEcc = SigPkCbEccVerify;
+        sigCtx->pkCtxEcc = ssl;
+    }
+#endif
+#ifndef NO_RSA
+    /* only setup the verify callback if a PK is set */
+    if (ssl->ctx->RsaVerifyCb) {
+        sigCtx->pkCbRsa = SigPkCbRsaVerify;
+        sigCtx->pkCtxRsa = ssl;
+    }
+#endif
+
+    return 0;
+}
+
+#endif /* HAVE_PK_CALLBACKS */
+
+
+#if !defined(NO_WOLFSSL_CLIENT) || !defined(WOLFSSL_NO_CLIENT_AUTH)
+static void DoCertFatalAlert(WOLFSSL* ssl, int ret)
+{
+    int alertWhy;
+    if (ssl == NULL || ret == 0) {
+        return;
+    }
+
+    /* Determine alert reason */
+    alertWhy = bad_certificate;
+    if (ret == ASN_AFTER_DATE_E || ret == ASN_BEFORE_DATE_E) {
+        alertWhy = certificate_expired;
+    }
+#if (defined(OPENSSL_ALL) || defined(WOLFSSL_APACHE_HTTPD))
+    else if (ret == CRL_CERT_REVOKED) {
+        alertWhy = certificate_revoked;
+    }
+#endif
+    else if (ret == NO_PEER_CERT) {
+#ifdef WOLFSSL_TLS13
+        if (ssl->options.tls1_3) {
+            alertWhy = certificate_required;
+        }
+        else
+#endif
+        {
+            alertWhy = handshake_failure;
+        }
+    }
+
+    /* send fatal alert and mark connection closed */
+    SendAlert(ssl, alert_fatal, alertWhy); /* try to send */
+    ssl->options.isClosed = 1;
+}
+
+/* WOLFSSL_ALWAYS_VERIFY_CB: Use verify callback for success or failure cases */
+/* WOLFSSL_VERIFY_CB_ALL_CERTS: Issue callback for all intermediate certificates */
+
+/* Callback is issued for certificate presented in TLS Certificate (11) packet.
+ * The intermediates are done first then peer leaf cert last. Use the
+ * store->error_depth member to determine index (0=peer, >1 intermediates)
+ */
+
+int DoVerifyCallback(WOLFSSL_CERT_MANAGER* cm, WOLFSSL* ssl, int ret,
+                                                        ProcPeerCertArgs* args)
+{
+    int verify_ok = 0, use_cb = 0;
+    void *heap = (ssl != NULL) ? ssl->heap : cm->heap;
+
+    /* Determine if verify was okay */
+    if (ret == 0) {
+        verify_ok = 1;
+    }
+
+    /* Determine if verify callback should be used */
+    if (ret != 0) {
+        if ((ssl != NULL) && (!ssl->options.verifyNone)) {
+            use_cb = 1; /* always report errors */
+        }
+    }
+#ifdef WOLFSSL_ALWAYS_VERIFY_CB
+    /* always use verify callback on peer leaf cert */
+    if (args->certIdx == 0) {
+        use_cb = 1;
+    }
+#endif
+#ifdef WOLFSSL_VERIFY_CB_ALL_CERTS
+    /* perform verify callback on other intermediate certs (not just peer) */
+    if (args->certIdx > 0) {
+        use_cb = 1;
+    }
+#endif
+#if defined(OPENSSL_EXTRA)
+    /* perform domain name check on the peer certificate */
+    if (args->dCertInit && args->dCert && (ssl != NULL) &&
+            ssl->param && ssl->param->hostName[0]) {
+        /* If altNames names is present, then subject common name is ignored */
+        if (args->dCert->altNames != NULL) {
+            if (CheckAltNames(args->dCert, ssl->param->hostName) == 0 ) {
+                if (ret == 0) {
+                    ret = DOMAIN_NAME_MISMATCH;
+                }
+            }
+        }
+        else {
+            if (args->dCert->subjectCN) {
+                if (MatchDomainName(args->dCert->subjectCN,
+                                    args->dCert->subjectCNLen,
+                                    ssl->param->hostName) == 0) {
+                    if (ret == 0) {
+                        ret = DOMAIN_NAME_MISMATCH;
+                    }
+                }
+            }
+        }
+    }
+
+    /* perform IP address check on the peer certificate */
+    if ((args->dCertInit != 0) && (args->dCert != NULL) && (ssl != NULL) &&
+        (ssl->param != NULL) && (XSTRLEN(ssl->param->ipasc) > 0)) {
+        if (CheckIPAddr(args->dCert, ssl->param->ipasc) != 0) {
+            if (ret == 0) {
+                ret = IPADDR_MISMATCH;
+            }
+        }
+    }
+#endif
+    /* if verify callback has been set */
+    if ((use_cb && (ssl != NULL) && ((ssl->verifyCallback != NULL)
+    #ifdef OPENSSL_ALL
+        || (ssl->ctx->verifyCertCb != NULL)
+    #endif
+        ))
+    #ifndef NO_WOLFSSL_CM_VERIFY
+        || (cm->verifyCallback != NULL)
+    #endif
+        ) {
+        int verifyFail = 0;
+    #ifdef WOLFSSL_SMALL_STACK
+        WOLFSSL_X509_STORE_CTX* store;
+        #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
+        WOLFSSL_X509* x509;
+        #endif
+        char* domain = NULL;
+    #else
+        WOLFSSL_X509_STORE_CTX store[1];
+        #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
+        WOLFSSL_X509           x509[1];
+        #endif
+        char domain[ASN_NAME_MAX];
+    #endif
+
+    #ifdef WOLFSSL_SMALL_STACK
+        store = (WOLFSSL_X509_STORE_CTX*)XMALLOC(
+            sizeof(WOLFSSL_X509_STORE_CTX), heap, DYNAMIC_TYPE_X509_STORE);
+        if (store == NULL) {
+            return MEMORY_E;
+        }
+        #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
+        x509 = (WOLFSSL_X509*)XMALLOC(sizeof(WOLFSSL_X509), heap,
+            DYNAMIC_TYPE_X509);
+        if (x509 == NULL) {
+            XFREE(store, heap, DYNAMIC_TYPE_X509);
+            return MEMORY_E;
+        }
+        #endif
+        domain = (char*)XMALLOC(ASN_NAME_MAX, heap, DYNAMIC_TYPE_STRING);
+        if (domain == NULL) {
+            XFREE(store, heap, DYNAMIC_TYPE_X509);
+            #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
+            XFREE(x509, heap, DYNAMIC_TYPE_X509);
+            #endif
+            return MEMORY_E;
+        }
+    #endif /* WOLFSSL_SMALL_STACK */
+
+        XMEMSET(store, 0, sizeof(WOLFSSL_X509_STORE_CTX));
+    #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
+        XMEMSET(x509, 0, sizeof(WOLFSSL_X509));
+    #endif
+        domain[0] = '\0';
+
+        /* build subject CN as string to return in store */
+        if (args->dCertInit && args->dCert && args->dCert->subjectCN) {
+            int subjectCNLen = args->dCert->subjectCNLen;
+            if (subjectCNLen > ASN_NAME_MAX-1)
+                subjectCNLen = ASN_NAME_MAX-1;
+            if (subjectCNLen > 0) {
+                XMEMCPY(domain, args->dCert->subjectCN, subjectCNLen);
+                domain[subjectCNLen] = '\0';
+            }
+        }
+
+        store->error = ret;
+        store->error_depth = args->certIdx;
+        store->discardSessionCerts = 0;
+        store->domain = domain;
+        store->userCtx = (ssl != NULL) ? ssl->verifyCbCtx : cm;
+        store->certs = args->certs;
+        store->totalCerts = args->totalCerts;
+    #if defined(HAVE_EX_DATA) || defined(FORTRESS)
+        if (wolfSSL_CRYPTO_set_ex_data(&store->ex_data, 0, ssl)
+                != WOLFSSL_SUCCESS) {
+            WOLFSSL_MSG("Failed to store ssl context in WOLFSSL_X509_STORE_CTX");
+        }
+    #endif
+
+        if (ssl != NULL) {
+    #if defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER)
+            if (ssl->ctx->x509_store_pt != NULL) {
+                store->store = ssl->ctx->x509_store_pt;
+            }
+            else {
+                store->store = &ssl->ctx->x509_store;
+            }
+    #if defined(OPENSSL_EXTRA)
+            store->depth = args->count;
+            store->param = (WOLFSSL_X509_VERIFY_PARAM*)XMALLOC(
+                            sizeof(WOLFSSL_X509_VERIFY_PARAM),
+                            heap, DYNAMIC_TYPE_OPENSSL);
+            if (store->param == NULL) {
+        #ifdef WOLFSSL_SMALL_STACK
+                XFREE(domain, heap, DYNAMIC_TYPE_STRING);
+            #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
+                XFREE(x509, heap, DYNAMIC_TYPE_X509);
+            #endif
+                XFREE(store, heap, DYNAMIC_TYPE_X509_STORE);
+        #endif
+                return MEMORY_E;
+            }
+            XMEMSET(store->param, 0, sizeof(WOLFSSL_X509_VERIFY_PARAM));
+            /* Overwrite with non-default param values in SSL */
+            if (ssl->param) {
+                if (ssl->param->check_time)
+                    store->param->check_time = ssl->param->check_time;
+
+                if (ssl->param->flags)
+                    store->param->flags = ssl->param->flags;
+
+                if (ssl->param->hostName[0])
+                    XMEMCPY(store->param->hostName, ssl->param->hostName,
+                            WOLFSSL_HOST_NAME_MAX);
+
+            }
+    #endif /* defined(OPENSSL_EXTRA) */
+    #endif /* defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER)*/
+    #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
+        #ifdef KEEP_PEER_CERT
+            if (args->certIdx == 0) {
+                store->current_cert = &ssl->peerCert; /* use existing X509 */
+            }
+            else
+        #endif
+            {
+                InitX509(x509, 0, heap);
+                if (CopyDecodedToX509(x509, args->dCert) == 0) {
+                    store->current_cert = x509;
+                }
+                else {
+                    FreeX509(x509);
+                }
+            }
+    #endif
+    #ifdef SESSION_CERTS
+            store->sesChain = &ssl->session.chain;
+    #endif
+        }
+    #ifndef NO_WOLFSSL_CM_VERIFY
+        /* non-zero return code indicates failure override */
+        if ((cm != NULL) && (cm->verifyCallback != NULL)) {
+            store->userCtx = cm;
+            if (cm->verifyCallback(verify_ok, store)) {
+                if (ret != 0) {
+                    WOLFSSL_MSG("Verify CM callback overriding error!");
+                    ret = 0;
+                }
+            }
+            else {
+                verifyFail = 1;
+            }
+        }
+    #endif
+
+        if (ssl != NULL) {
+    #ifdef OPENSSL_ALL
+            /* non-zero return code indicates failure override */
+            if (ssl->ctx->verifyCertCb) {
+                if (ssl->ctx->verifyCertCb(store, ssl->ctx->verifyCertCbArg)) {
+                    if (ret != 0) {
+                        WOLFSSL_MSG("Verify Cert callback overriding error!");
+                        ret = 0;
+                    }
+                }
+                else {
+                    verifyFail = 1;
+                }
+            }
+    #endif
+
+            /* non-zero return code indicates failure override */
+            if (ssl->verifyCallback) {
+                if (ssl->verifyCallback(verify_ok, store)) {
+                    if (ret != 0) {
+                        WOLFSSL_MSG("Verify callback overriding error!");
+                        ret = 0;
+                    }
+                }
+                else {
+                    verifyFail = 1;
+                }
+            }
+        }
+
+        if (verifyFail) {
+            /* induce error if one not present */
+            if (ret == 0) {
+                ret = VERIFY_CERT_ERROR;
+            }
+
+            /* mark as verify error */
+            args->verifyErr = 1;
+        }
+    #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
+        if (args->certIdx > 0)
+            FreeX509(x509);
+    #endif
+    #if defined(SESSION_CERTS) && defined(OPENSSL_EXTRA)
+        wolfSSL_sk_X509_free(store->chain);
+        store->chain = NULL;
+    #endif
+    #ifdef SESSION_CERTS
+        if ((ssl != NULL) && (store->discardSessionCerts)) {
+            WOLFSSL_MSG("Verify callback requested discard sess certs");
+            ssl->session.chain.count = 0;
+        #ifdef WOLFSSL_ALT_CERT_CHAINS
+            ssl->session.altChain.count = 0;
+        #endif
+        }
+    #endif /* SESSION_CERTS */
+#ifdef OPENSSL_EXTRA
+        if ((ssl != NULL) && (store->param)) {
+            XFREE(store->param, heap, DYNAMIC_TYPE_OPENSSL);
+        }
+#endif
+    #ifdef WOLFSSL_SMALL_STACK
+        XFREE(domain, heap, DYNAMIC_TYPE_STRING);
+        #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
+        XFREE(x509, heap, DYNAMIC_TYPE_X509);
+        #endif
+        XFREE(store, heap, DYNAMIC_TYPE_X509_STORE);
+    #endif
+    }
+
+    (void)heap;
+
+    return ret;
+}
+
+static void FreeProcPeerCertArgs(WOLFSSL* ssl, void* pArgs)
+{
+    ProcPeerCertArgs* args = (ProcPeerCertArgs*)pArgs;
+
+    (void)ssl;
+
+    if (args->certs) {
+        XFREE(args->certs, ssl->heap, DYNAMIC_TYPE_DER);
+        args->certs = NULL;
+    }
+#ifdef WOLFSSL_TLS13
+    if (args->exts) {
+        XFREE(args->exts, ssl->heap, DYNAMIC_TYPE_CERT_EXT);
+        args->exts = NULL;
+    }
+#endif
+    if (args->dCert) {
+        if (args->dCertInit) {
+            FreeDecodedCert(args->dCert);
+            args->dCertInit = 0;
+        }
+        XFREE(args->dCert, ssl->heap, DYNAMIC_TYPE_DCERT);
+        args->dCert = NULL;
+    }
+}
+
+static int ProcessPeerCertParse(WOLFSSL* ssl, ProcPeerCertArgs* args,
+    int certType, int verify, byte** pSubjectHash, int* pAlreadySigner)
+{
+    int ret = 0;
+    buffer* cert;
+    byte* subjectHash = NULL;
+    int alreadySigner = 0;
+#ifdef WOLFSSL_SMALL_CERT_VERIFY
+    int sigRet = 0;
+#endif
+
+    if (ssl == NULL || args == NULL)
+        return BAD_FUNC_ARG;
+
+    /* check to make sure certificate index is valid */
+    if (args->certIdx > args->count)
+        return BUFFER_E;
+
+    /* check if returning from non-blocking OCSP */
+    /* skip this section because cert is already initialized and parsed */
+#ifdef WOLFSSL_NONBLOCK_OCSP
+    if (args->lastErr == OCSP_WANT_READ) {
+        args->lastErr = 0; /* clear error */
+        return 0;
+    }
+#endif
+
+#ifdef WOLFSSL_TRUST_PEER_CERT
+    /* we have trusted peer */
+    if (args->haveTrustPeer) {
+        return 0;
+    }
+#endif
+
+    /* get certificate buffer */
+    cert = &args->certs[args->certIdx];
+
+#ifdef WOLFSSL_SMALL_CERT_VERIFY
+    if (verify == VERIFY) {
+        /* for small cert verify, release decoded cert during signature check to
+            reduce peak memory usage */
+        if (args->dCert != NULL) {
+            if (args->dCertInit) {
+                FreeDecodedCert(args->dCert);
+                args->dCertInit = 0;
+            }
+            XFREE(args->dCert, ssl->heap, DYNAMIC_TYPE_DCERT);
+            args->dCert = NULL;
+        }
+
+        /* perform cert parsing and signature check */
+        sigRet = CheckCertSignature(cert->buffer, cert->length,
+                                         ssl->heap, ssl->ctx->cm);
+        /* fail on errors here after the ParseCertRelative call, so dCert is populated */
+
+        /* verify name only in ParseCertRelative below, signature check done */
+        verify = VERIFY_NAME;
+    }
+#endif /* WOLFSSL_SMALL_CERT_VERIFY */
+
+    /* make sure the decoded cert structure is allocated and initialized */
+    if (!args->dCertInit
+    #ifdef WOLFSSL_SMALL_CERT_VERIFY
+        || args->dCert == NULL
+    #endif
+    ) {
+    #ifdef WOLFSSL_SMALL_CERT_VERIFY
+        if (args->dCert == NULL) {
+            args->dCert = (DecodedCert*)XMALLOC(
+                                 sizeof(DecodedCert), ssl->heap,
+                                 DYNAMIC_TYPE_DCERT);
+            if (args->dCert == NULL) {
+                return MEMORY_E;
+            }
+        }
+    #endif
+
+        InitDecodedCert(args->dCert, cert->buffer, cert->length, ssl->heap);
+
+        args->dCertInit = 1;
+        args->dCert->sigCtx.devId = ssl->devId;
+    #ifdef WOLFSSL_ASYNC_CRYPT
+        args->dCert->sigCtx.asyncCtx = ssl;
+    #endif
+
+    #ifdef HAVE_PK_CALLBACKS
+        /* setup the PK callback context */
+        ret = InitSigPkCb(ssl, &args->dCert->sigCtx);
+        if (ret != 0)
+            return ret;
+    #endif
+    }
+
+    /* Parse Certificate */
+    ret = ParseCertRelative(args->dCert, certType, verify, ssl->ctx->cm);
+    /* perform below checks for date failure cases */
+    if (ret == 0 || ret == ASN_BEFORE_DATE_E || ret == ASN_AFTER_DATE_E) {
+        /* get subject and determine if already loaded */
+    #ifndef NO_SKID
+        if (args->dCert->extAuthKeyIdSet)
+            subjectHash = args->dCert->extSubjKeyId;
+        else
+    #endif
+            subjectHash = args->dCert->subjectHash;
+        alreadySigner = AlreadySigner(ssl->ctx->cm, subjectHash);
+    }
+
+#ifdef WOLFSSL_SMALL_CERT_VERIFY
+    /* get signature check failures from above */
+    if (ret == 0)
+        ret = sigRet;
+#endif
+
+    if (pSubjectHash)
+        *pSubjectHash = subjectHash;
+    if (pAlreadySigner)
+        *pAlreadySigner = alreadySigner;
+
+#ifdef WOLFSSL_ASYNC_CRYPT
+    if (ret == WC_PENDING_E) {
+        ret = wolfSSL_AsyncPush(ssl,
+            args->dCert->sigCtx.asyncDev);
+    }
+#endif
+
+    return ret;
+}
+
+/* Check key sizes for certs. Is redundant check since
+   ProcessBuffer also performs this check. */
+static int ProcessPeerCertCheckKey(WOLFSSL* ssl, ProcPeerCertArgs* args)
+{
+    int ret = 0;
+
+    if (ssl->options.verifyNone) {
+        return ret;
+    }
+
+    switch (args->dCert->keyOID) {
+    #ifndef NO_RSA
+        case RSAk:
+            if (ssl->options.minRsaKeySz < 0 ||
+                    args->dCert->pubKeySize <
+                     (word16)ssl->options.minRsaKeySz) {
+                WOLFSSL_MSG(
+                    "RSA key size in cert chain error");
+                ret = RSA_KEY_SIZE_E;
+            }
+            break;
+    #endif /* !NO_RSA */
+    #ifdef HAVE_ECC
+        case ECDSAk:
+            if (ssl->options.minEccKeySz < 0 ||
+                    args->dCert->pubKeySize <
+                     (word16)ssl->options.minEccKeySz) {
+                WOLFSSL_MSG(
+                    "ECC key size in cert chain error");
+                ret = ECC_KEY_SIZE_E;
+            }
+            break;
+    #endif /* HAVE_ECC */
+    #ifdef HAVE_ED25519
+        case ED25519k:
+            if (ssl->options.minEccKeySz < 0 ||
+                    ED25519_KEY_SIZE < (word16)ssl->options.minEccKeySz) {
+                WOLFSSL_MSG(
+                    "ECC key size in cert chain error");
+                ret = ECC_KEY_SIZE_E;
+            }
+            break;
+    #endif /* HAVE_ED25519 */
+    #ifdef HAVE_ED448
+        case ED448k:
+            if (ssl->options.minEccKeySz < 0 ||
+                    ED448_KEY_SIZE < (word16)ssl->options.minEccKeySz) {
+                WOLFSSL_MSG(
+                    "ECC key size in cert chain error");
+                ret = ECC_KEY_SIZE_E;
+            }
+            break;
+    #endif /* HAVE_ED448 */
+        default:
+            WOLFSSL_MSG("Key size not checked");
+            /* key not being checked for size if not in
+               switch */
+            break;
+    }
+
+    return ret;
+}
+
+int ProcessPeerCerts(WOLFSSL* ssl, byte* input, word32* inOutIdx,
+                     word32 totalSz)
+{
+    int ret = 0;
+#ifdef WOLFSSL_ASYNC_CRYPT
+    ProcPeerCertArgs* args = (ProcPeerCertArgs*)ssl->async.args;
+    typedef char args_test[sizeof(ssl->async.args) >= sizeof(*args) ? 1 : -1];
+    (void)sizeof(args_test);
+#elif defined(WOLFSSL_NONBLOCK_OCSP)
+    ProcPeerCertArgs* args = ssl->nonblockarg;
+#elif defined(WOLFSSL_SMALL_STACK)
+    ProcPeerCertArgs* args = NULL;
+#else
+    ProcPeerCertArgs  args[1];
+#endif
+    byte* subjectHash = NULL;
+    int alreadySigner = 0;
+
+    WOLFSSL_ENTER("ProcessPeerCerts");
+
+#ifdef WOLFSSL_ASYNC_CRYPT
+    ret = wolfSSL_AsyncPop(ssl, &ssl->options.asyncState);
+    if (ret != WC_NOT_PENDING_E) {
+        /* Check for error */
+        if (ret < 0)
+            goto exit_ppc;
+    }
+    else
+#elif defined(WOLFSSL_NONBLOCK_OCSP)
+    if (args == NULL) {
+        args = (ProcPeerCertArgs*)XMALLOC(
+            sizeof(ProcPeerCertArgs), ssl->heap, DYNAMIC_TYPE_TMP_BUFFER);
+        if (args == NULL) {
+            ERROR_OUT(MEMORY_E, exit_ppc);
+        }
+    }
+    if (ssl->nonblockarg == NULL) /* new args */
+#elif defined(WOLFSSL_SMALL_STACK)
+    args = (ProcPeerCertArgs*)XMALLOC(
+        sizeof(ProcPeerCertArgs), ssl->heap, DYNAMIC_TYPE_TMP_BUFFER);
+    if (args == NULL) {
+        ERROR_OUT(MEMORY_E, exit_ppc);
+    }
+#endif
+    {
+        /* Reset state */
+        ret = 0;
+        ssl->options.asyncState = TLS_ASYNC_BEGIN;
+        XMEMSET(args, 0, sizeof(ProcPeerCertArgs));
+        args->idx = *inOutIdx;
+        args->begin = *inOutIdx;
+    #ifdef WOLFSSL_ASYNC_CRYPT
+        ssl->async.freeArgs = FreeProcPeerCertArgs;
+    #elif defined(WOLFSSL_NONBLOCK_OCSP)
+        ssl->nonblockarg = args;
+    #endif
+    }
+
+    switch (ssl->options.asyncState)
+    {
+        case TLS_ASYNC_BEGIN:
+        {
+            word32 listSz;
+
+        #ifdef WOLFSSL_CALLBACKS
+            if (ssl->hsInfoOn)
+                AddPacketName(ssl, "Certificate");
+            if (ssl->toInfoOn)
+                AddLateName("Certificate", &ssl->timeoutInfo);
+        #endif
+
+        #ifdef WOLFSSL_TLS13
+            if (ssl->options.tls1_3) {
+                byte ctxSz;
+
+                /* Certificate Request Context */
+                if ((args->idx - args->begin) + OPAQUE8_LEN > totalSz)
+                    ERROR_OUT(BUFFER_ERROR, exit_ppc);
+                ctxSz = *(input + args->idx);
+                args->idx++;
+                if ((args->idx - args->begin) + ctxSz > totalSz)
+                    ERROR_OUT(BUFFER_ERROR, exit_ppc);
+            #ifndef NO_WOLFSSL_CLIENT
+                /* Must be empty when received from server. */
+                if (ssl->options.side == WOLFSSL_CLIENT_END) {
+                    if (ctxSz != 0) {
+                        ERROR_OUT(INVALID_CERT_CTX_E, exit_ppc);
+                    }
+                }
+            #endif
+            #ifndef NO_WOLFSSL_SERVER
+                /* Must contain value sent in request. */
+                if (ssl->options.side == WOLFSSL_SERVER_END) {
+                    if (ssl->options.handShakeState != HANDSHAKE_DONE &&
+                                                                   ctxSz != 0) {
+                        ERROR_OUT(INVALID_CERT_CTX_E, exit_ppc);
+                    }
+                    else if (ssl->options.handShakeState == HANDSHAKE_DONE) {
+                #ifdef WOLFSSL_POST_HANDSHAKE_AUTH
+                         CertReqCtx* curr = ssl->certReqCtx;
+                         CertReqCtx* prev = NULL;
+                         while (curr != NULL) {
+                             if ((ctxSz == curr->len) &&
+                                 XMEMCMP(&curr->ctx, input + args->idx, ctxSz)
+                                                                         == 0) {
+                                     if (prev != NULL)
+                                         prev->next = curr->next;
+                                     else
+                                         ssl->certReqCtx = curr->next;
+                                     XFREE(curr, ssl->heap,
+                                           DYNAMIC_TYPE_TMP_BUFFER);
+                                     break;
+                             }
+                             prev = curr;
+                             curr = curr->next;
+                        }
+                        if (curr == NULL)
+                #endif
+                            ERROR_OUT(INVALID_CERT_CTX_E, exit_ppc);
+                    }
+                }
+            #endif
+                args->idx += ctxSz;
+
+            #ifdef OPENSSL_EXTRA
+                /* allocate buffer for cert extensions */
+                args->exts = (buffer*)XMALLOC(sizeof(buffer) *
+                     (ssl->verifyDepth + 1), ssl->heap, DYNAMIC_TYPE_CERT_EXT);
+                if (args->exts == NULL) {
+                    ERROR_OUT(MEMORY_E, exit_ppc);
+                }
+            #else
+                /* allocate buffer for cert extensions */
+                args->exts = (buffer*)XMALLOC(sizeof(buffer) * MAX_CHAIN_DEPTH,
+                                            ssl->heap, DYNAMIC_TYPE_CERT_EXT);
+                if (args->exts == NULL) {
+                    ERROR_OUT(MEMORY_E, exit_ppc);
+                }
+            #endif
+            }
+        #endif
+
+            /* allocate buffer for certs */
+        #ifdef OPENSSL_EXTRA
+            args->certs = (buffer*)XMALLOC(sizeof(buffer) *
+                    (ssl->verifyDepth + 1), ssl->heap, DYNAMIC_TYPE_DER);
+            if (args->certs == NULL) {
+                ERROR_OUT(MEMORY_E, exit_ppc);
+            }
+            XMEMSET(args->certs, 0, sizeof(buffer) * (ssl->verifyDepth + 1));
+        #else
+            args->certs = (buffer*)XMALLOC(sizeof(buffer) * MAX_CHAIN_DEPTH,
+                                            ssl->heap, DYNAMIC_TYPE_DER);
+            if (args->certs == NULL) {
+                ERROR_OUT(MEMORY_E, exit_ppc);
+            }
+            XMEMSET(args->certs, 0, sizeof(buffer) * MAX_CHAIN_DEPTH);
+        #endif /* OPENSSL_EXTRA */
+
+            /* Certificate List */
+            if ((args->idx - args->begin) + OPAQUE24_LEN > totalSz) {
+                ERROR_OUT(BUFFER_ERROR, exit_ppc);
+            }
+            c24to32(input + args->idx, &listSz);
+            args->idx += OPAQUE24_LEN;
+            if (listSz > MAX_CERTIFICATE_SZ) {
+                ERROR_OUT(BUFFER_ERROR, exit_ppc);
+            }
+            if ((args->idx - args->begin) + listSz != totalSz) {
+                ERROR_OUT(BUFFER_ERROR, exit_ppc);
+            }
+
+            WOLFSSL_MSG("Loading peer's cert chain");
+            /* first put cert chain into buffer so can verify top down
+               we're sent bottom up */
+            while (listSz) {
+                word32 certSz;
+
+            #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
+                if (args->totalCerts > ssl->verifyDepth) {
+                    ssl->peerVerifyRet = X509_V_ERR_CERT_CHAIN_TOO_LONG;
+                    ERROR_OUT(MAX_CHAIN_ERROR, exit_ppc);
+                }
+            #else
+                if (args->totalCerts >= ssl->verifyDepth ||
+                        args->totalCerts >= MAX_CHAIN_DEPTH) {
+                    ERROR_OUT(MAX_CHAIN_ERROR, exit_ppc);
+                }
+            #endif
+
+                if ((args->idx - args->begin) + OPAQUE24_LEN > totalSz) {
+                    ERROR_OUT(BUFFER_ERROR, exit_ppc);
+                }
+
+                c24to32(input + args->idx, &certSz);
+                args->idx += OPAQUE24_LEN;
+
+                if ((args->idx - args->begin) + certSz > totalSz) {
+                    ERROR_OUT(BUFFER_ERROR, exit_ppc);
+                }
+
+                args->certs[args->totalCerts].length = certSz;
+                args->certs[args->totalCerts].buffer = input + args->idx;
+
+            #ifdef SESSION_CERTS
+                AddSessionCertToChain(&ssl->session.chain,
+                    input + args->idx, certSz);
+            #endif /* SESSION_CERTS */
+
+                args->idx += certSz;
+                listSz -= certSz + CERT_HEADER_SZ;
+
+            #ifdef WOLFSSL_TLS13
+                /* Extensions */
+                if (ssl->options.tls1_3) {
+                    word16 extSz;
+
+                    if ((args->idx - args->begin) + OPAQUE16_LEN > totalSz) {
+                        ERROR_OUT(BUFFER_ERROR, exit_ppc);
+                    }
+                    ato16(input + args->idx, &extSz);
+                    args->idx += OPAQUE16_LEN;
+                    if ((args->idx - args->begin) + extSz > totalSz) {
+                        ERROR_OUT(BUFFER_ERROR, exit_ppc);
+                    }
+                    /* Store extension data info for later processing. */
+                    args->exts[args->totalCerts].length = extSz;
+                    args->exts[args->totalCerts].buffer = input + args->idx;
+                    args->idx += extSz;
+                    listSz -= extSz + OPAQUE16_LEN;
+                    ret = TLSX_Parse(ssl, args->exts[args->totalCerts].buffer,
+                        args->exts[args->totalCerts].length, certificate, NULL);
+                    if (ret < 0) {
+                        ERROR_OUT(ret, exit_ppc);
+                    }
+                }
+            #endif
+
+                args->totalCerts++;
+                WOLFSSL_MSG("\tPut another cert into chain");
+            } /* while (listSz) */
+
+            args->count = args->totalCerts;
+            args->certIdx = 0; /* select peer cert (first one) */
+
+            if (args->count == 0 && ssl->options.mutualAuth &&
+                                      ssl->options.side == WOLFSSL_SERVER_END) {
+                ret = NO_PEER_CERT;
+                DoCertFatalAlert(ssl, ret);
+            }
+
+            args->dCertInit = 0;
+        #ifndef WOLFSSL_SMALL_CERT_VERIFY
+            args->dCert = (DecodedCert*)XMALLOC(sizeof(DecodedCert), ssl->heap,
+                                                       DYNAMIC_TYPE_DCERT);
+            if (args->dCert == NULL) {
+                ERROR_OUT(MEMORY_E, exit_ppc);
+            }
+            XMEMSET(args->dCert, 0, sizeof(DecodedCert));
+        #endif
+
+            /* Advance state and proceed */
+            ssl->options.asyncState = TLS_ASYNC_BUILD;
+        } /* case TLS_ASYNC_BEGIN */
+        FALL_THROUGH;
+
+        case TLS_ASYNC_BUILD:
+        {
+            if (args->count > 0) {
+
+                /* check for trusted peer and get untrustedDepth */
+            #if defined(WOLFSSL_TRUST_PEER_CERT) || defined(OPENSSL_EXTRA)
+                if (args->certIdx == 0) {
+                #ifdef WOLFSSL_TRUST_PEER_CERT
+                    TrustedPeerCert* tp;
+                    int matchType = WC_MATCH_NAME;
+                #endif
+
+                    ret = ProcessPeerCertParse(ssl, args, CERT_TYPE, NO_VERIFY,
+                        &subjectHash, &alreadySigner);
+                    if (ret != 0)
+                        goto exit_ppc;
+
+                #ifdef OPENSSL_EXTRA
+                    /* Determine untrusted depth */
+                    if (!alreadySigner && (!args->dCert ||
+                            !args->dCertInit || !args->dCert->selfSigned)) {
+                        args->untrustedDepth = 1;
+                    }
+                #endif
+
+                #ifdef WOLFSSL_TRUST_PEER_CERT
+                    #ifndef NO_SKID
+                    if (args->dCert->extAuthKeyIdSet)
+                        matchType = WC_MATCH_SKID;
+                    #endif
+                    tp = GetTrustedPeer(ssl->ctx->cm, subjectHash, matchType);
+                    WOLFSSL_MSG("Checking for trusted peer cert");
+
+                    if (tp && MatchTrustedPeer(tp, args->dCert)) {
+                        WOLFSSL_MSG("Found matching trusted peer cert");
+                        args->haveTrustPeer = 1;
+                    }
+                    else if (tp == NULL) {
+                        /* no trusted peer cert */
+                        WOLFSSL_MSG("No matching trusted peer cert. Checking CAs");
+                    }
+                    else {
+                        WOLFSSL_MSG("Trusted peer cert did not match!");
+                    }
+                    if (!args->haveTrustPeer)
+                #endif
+                    {
+                        /* free cert if not trusted peer */
+                        FreeDecodedCert(args->dCert);
+                        args->dCertInit = 0;
+                    }
+                }
+            #endif /* WOLFSSL_TRUST_PEER_CERT || OPENSSL_EXTRA */
+
+                /* check certificate up to peer's first */
+                /* do not verify chain if trusted peer cert found */
+                while (args->count > 1
+                #ifdef WOLFSSL_TRUST_PEER_CERT
+                    && !args->haveTrustPeer
+                #endif /* WOLFSSL_TRUST_PEER_CERT */
+                ) {
+                    int skipAddCA = 0;
+
+                    /* select last certificate */
+                    args->certIdx = args->count - 1;
+
+                    ret = ProcessPeerCertParse(ssl, args, CERT_TYPE,
+                        !ssl->options.verifyNone ? VERIFY : NO_VERIFY,
+                        &subjectHash, &alreadySigner);
+                #ifdef WOLFSSL_ASYNC_CRYPT
+                    if (ret == WC_PENDING_E)
+                        goto exit_ppc;
+                #endif
+                    if (ret == 0) {
+                        ret = ProcessPeerCertCheckKey(ssl, args);
+                    }
+
+                    if (ret == 0 && args->dCert->isCA == 0) {
+                        WOLFSSL_MSG("Chain cert is not a CA, not adding as one");
+                    }
+                    else if (ret == 0 && ssl->options.verifyNone) {
+                        WOLFSSL_MSG("Chain cert not verified by option, "
+                            "not adding as CA");
+                    }
+                    else if (ret == 0) {
+                    #ifdef OPENSSL_EXTRA
+                        if (args->certIdx > args->untrustedDepth) {
+                            args->untrustedDepth = (char)args->certIdx + 1;
+                        }
+                    #endif
+
+                        if (alreadySigner) {
+                            WOLFSSL_MSG("Verified CA from chain and already had it");
+                        }
+                    }
+                    else {
+                        WOLFSSL_MSG("Failed to verify CA from chain");
+                    #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
+                        ssl->peerVerifyRet = X509_V_ERR_INVALID_CA;
+                    #endif
+                    }
+
+            #if defined(HAVE_OCSP) || defined(HAVE_CRL)
+                    if (ret == 0) {
+                        int doCrlLookup = 1;
+                #ifdef HAVE_OCSP
+                    #ifdef HAVE_CERTIFICATE_STATUS_REQUEST_V2
+                        if (ssl->status_request_v2) {
+                            ret = TLSX_CSR2_InitRequests(ssl->extensions,
+                                                    args->dCert, 0, ssl->heap);
+                        }
+                        else /* skips OCSP and force CRL check */
+                    #endif /* HAVE_CERTIFICATE_STATUS_REQUEST_V2 */
+                        if (ssl->ctx->cm->ocspEnabled &&
+                                            ssl->ctx->cm->ocspCheckAll) {
+                            WOLFSSL_MSG("Doing Non Leaf OCSP check");
+                            ret = CheckCertOCSP_ex(ssl->ctx->cm->ocsp,
+                                                    args->dCert, NULL, ssl);
+                        #ifdef WOLFSSL_NONBLOCK_OCSP
+                            if (ret == OCSP_WANT_READ) {
+                                args->lastErr = ret;
+                                goto exit_ppc;
+                            }
+                        #endif
+                            doCrlLookup = (ret == OCSP_CERT_UNKNOWN);
+                            if (ret != 0) {
+                                doCrlLookup = 0;
+                                WOLFSSL_MSG("\tOCSP Lookup not ok");
+                            }
+                        }
+                #endif /* HAVE_OCSP */
+
+                #ifdef HAVE_CRL
+                        if (ret == 0 && doCrlLookup &&
+                                    ssl->ctx->cm->crlEnabled &&
+                                                ssl->ctx->cm->crlCheckAll) {
+                            WOLFSSL_MSG("Doing Non Leaf CRL check");
+                            ret = CheckCertCRL(ssl->ctx->cm->crl, args->dCert);
+                        #ifdef WOLFSSL_NONBLOCK_OCSP
+                            if (ret == OCSP_WANT_READ) {
+                                args->lastErr = ret;
+                                goto exit_ppc;
+                            }
+                        #endif
+                            if (ret != 0) {
+                                WOLFSSL_MSG("\tCRL check not ok");
+                            }
+                        }
+                #endif /* HAVE_CRL */
+                        (void)doCrlLookup;
+                    }
+            #endif /* HAVE_OCSP || HAVE_CRL */
+
+                    /* Do verify callback */
+                    ret = DoVerifyCallback(ssl->ctx->cm, ssl, ret, args);
+
+                #ifdef WOLFSSL_ALT_CERT_CHAINS
+                    /* For alternate cert chain, its okay for a CA cert to fail
+                        with ASN_NO_SIGNER_E here. The "alternate" certificate
+                        chain mode only requires that the peer certificate
+                        validate to a trusted CA */
+                    if (ret != 0 && args->dCert->isCA) {
+                        if (ret == ASN_NO_SIGNER_E) {
+                            if (!ssl->options.usingAltCertChain) {
+                                WOLFSSL_MSG("Trying alternate cert chain");
+                                ssl->options.usingAltCertChain = 1;
+                            }
+
+                            ret = 0; /* clear error and continue */
+                        }
+
+                        /* do not add to certificate manager */
+                        skipAddCA = 1;
+                    }
+                #endif /* WOLFSSL_ALT_CERT_CHAINS */
+
+                    /* If valid CA then add to Certificate Manager */
+                    if (ret == 0 && args->dCert->isCA &&
+                            !ssl->options.verifyNone && !skipAddCA) {
+                        buffer* cert = &args->certs[args->certIdx];
+
+                        /* Is valid CA */
+                    #if defined(SESSION_CERTS) && defined(WOLFSSL_ALT_CERT_CHAINS)
+                        /* if using alternate chain, store the cert used */
+                        if (ssl->options.usingAltCertChain) {
+                            AddSessionCertToChain(&ssl->session.altChain,
+                                cert->buffer, cert->length);
+                        }
+                    #endif /* SESSION_CERTS && WOLFSSL_ALT_CERT_CHAINS */
+                        if (!alreadySigner) {
+                            DerBuffer* add = NULL;
+                            ret = AllocDer(&add, cert->length, CA_TYPE, ssl->heap);
+                            if (ret < 0)
+                                goto exit_ppc;
+
+                            XMEMCPY(add->buffer, cert->buffer, cert->length);
+
+                            /* CA already verified above in ParseCertRelative */
+                            WOLFSSL_MSG("Adding CA from chain");
+                            ret = AddCA(ssl->ctx->cm, &add, WOLFSSL_CHAIN_CA,
+                                NO_VERIFY);
+                            if (ret == WOLFSSL_SUCCESS) {
+                                ret = 0;
+                            }
+                        }
+                    }
+
+                    /* Handle error codes */
+                    if (ret != 0) {
+                        if (!ssl->options.verifyNone) {
+                            DoCertFatalAlert(ssl, ret);
+                        }
+                        ssl->error = ret; /* Report SSL error */
+
+                        if (args->lastErr == 0) {
+                            args->lastErr = ret; /* save error from last time */
+                            ret = 0; /* reset error */
+                        }
+                    }
+
+                    FreeDecodedCert(args->dCert);
+                    args->dCertInit = 0;
+                    args->count--;
+                } /* while (count > 0 && !args->haveTrustPeer) */
+            } /* if (count > 0) */
+
+            /* Check for error */
+            if (ret != 0) {
+                goto exit_ppc;
+            }
+
+            /* Advance state and proceed */
+            ssl->options.asyncState = TLS_ASYNC_DO;
+        } /* case TLS_ASYNC_BUILD */
+        FALL_THROUGH;
+
+        case TLS_ASYNC_DO:
+        {
+            /* peer's, may not have one if blank client cert sent by TLSv1.2 */
+            if (args->count > 0) {
+                WOLFSSL_MSG("Verifying Peer's cert");
+
+                /* select peer cert (first one) */
+                args->certIdx = 0;
+
+                ret = ProcessPeerCertParse(ssl, args, CERT_TYPE,
+                        !ssl->options.verifyNone ? VERIFY : NO_VERIFY,
+                        &subjectHash, &alreadySigner);
+            #ifdef WOLFSSL_ASYNC_CRYPT
+                if (ret == WC_PENDING_E)
+                    goto exit_ppc;
+            #endif
+                if (ret == 0) {
+                    WOLFSSL_MSG("Verified Peer's cert");
+                #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
+                    ssl->peerVerifyRet = X509_V_OK;
+                #endif
+                #if defined(SESSION_CERTS) && defined(WOLFSSL_ALT_CERT_CHAINS)
+                    /* if using alternate chain, store the cert used */
+                    if (ssl->options.usingAltCertChain) {
+                        buffer* cert = &args->certs[args->certIdx];
+                        AddSessionCertToChain(&ssl->session.altChain,
+                            cert->buffer, cert->length);
+                    }
+                #endif /* SESSION_CERTS && WOLFSSL_ALT_CERT_CHAINS */
+
+                    /* check if fatal error */
+                    if (args->verifyErr) {
+                        args->fatal = 1;
+                        if (ret == 0) {
+                            ret = args->lastErr;
+                        }
+                    }
+                    else {
+                        args->fatal = 0;
+                    }
+                }
+                else if (ret == ASN_PARSE_E || ret == BUFFER_E) {
+                    WOLFSSL_MSG("Got Peer cert ASN PARSE or BUFFER ERROR");
+                #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
+                    SendAlert(ssl, alert_fatal, bad_certificate);
+                    ssl->peerVerifyRet = X509_V_ERR_CERT_REJECTED;
+                #endif
+                    args->fatal = 1;
+                }
+                else {
+                    WOLFSSL_MSG("Failed to verify Peer's cert");
+                #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
+                    ssl->peerVerifyRet = X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE;
+                #endif
+                    if (ssl->verifyCallback) {
+                        WOLFSSL_MSG(
+                            "\tCallback override available, will continue");
+                        /* check if fatal error */
+                        args->fatal = (args->verifyErr) ? 1 : 0;
+                    }
+                    else {
+                        WOLFSSL_MSG("\tNo callback override available, fatal");
+                        args->fatal = 1;
+                    #ifdef OPENSSL_EXTRA
+                        SendAlert(ssl, alert_fatal, bad_certificate);
+                    #endif
+                    }
+                }
+
+            #ifdef HAVE_SECURE_RENEGOTIATION
+                if (args->fatal == 0 && !IsAtLeastTLSv1_3(ssl->version)
+                                     && ssl->secure_renegotiation
+                                     && ssl->secure_renegotiation->enabled) {
+
+                    if (IsEncryptionOn(ssl, 0)) {
+                        /* compare against previous time */
+                        if (ssl->secure_renegotiation->subject_hash_set) {
+                            if (XMEMCMP(args->dCert->subjectHash,
+                                        ssl->secure_renegotiation->subject_hash,
+                                        KEYID_SIZE) != 0) {
+                                WOLFSSL_MSG(
+                                  "Peer sent different cert during scr, fatal");
+                                args->fatal = 1;
+                                ret = SCR_DIFFERENT_CERT_E;
+                            }
+                        }
+                    }
+
+                    /* cache peer's hash */
+                    if (args->fatal == 0) {
+                        XMEMCPY(ssl->secure_renegotiation->subject_hash,
+                                args->dCert->subjectHash, KEYID_SIZE);
+                        ssl->secure_renegotiation->subject_hash_set = 1;
+                    }
+                }
+            #endif /* HAVE_SECURE_RENEGOTIATION */
+            } /* if (count > 0) */
+
+            /* Check for error */
+            if (args->fatal && ret != 0) {
+                goto exit_ppc;
+            }
+
+            /* Advance state and proceed */
+            ssl->options.asyncState = TLS_ASYNC_VERIFY;
+        } /* case TLS_ASYNC_DO */
+        FALL_THROUGH;
+
+        case TLS_ASYNC_VERIFY:
+        {
+            if (args->count > 0) {
+            #if defined(HAVE_OCSP) || defined(HAVE_CRL)
+                if (args->fatal == 0) {
+                    int doLookup = 1;
+
+                    if (ssl->options.side == WOLFSSL_CLIENT_END) {
+                #ifdef HAVE_CERTIFICATE_STATUS_REQUEST
+                        if (ssl->status_request) {
+                            args->fatal = TLSX_CSR_InitRequest(ssl->extensions,
+                                                    args->dCert, ssl->heap);
+                            doLookup = 0;
+                        #if defined(WOLFSSL_TLS13) && !defined(NO_WOLFSSL_SERVER)
+                            if (ssl->options.tls1_3) {
+                                TLSX* ext = TLSX_Find(ssl->extensions,
+                                                           TLSX_STATUS_REQUEST);
+                                if (ext != NULL) {
+                                    word32 idx = 0;
+                                    CertificateStatusRequest* csr =
+                                           (CertificateStatusRequest*)ext->data;
+                                    ret = ProcessCSR(ssl, csr->response.buffer,
+                                                    &idx, csr->response.length);
+                                    if (ret < 0)
+                                        goto exit_ppc;
+                                }
+                            }
+                        #endif
+                        }
+                #endif /* HAVE_CERTIFICATE_STATUS_REQUEST */
+                #ifdef HAVE_CERTIFICATE_STATUS_REQUEST_V2
+                        if (ssl->status_request_v2) {
+                            args->fatal = TLSX_CSR2_InitRequests(ssl->extensions,
+                                                    args->dCert, 1, ssl->heap);
+                            doLookup = 0;
+                        }
+                #endif /* HAVE_CERTIFICATE_STATUS_REQUEST_V2 */
+                    }
+
+                #ifdef HAVE_OCSP
+                    if (doLookup && ssl->ctx->cm->ocspEnabled) {
+                        WOLFSSL_MSG("Doing Leaf OCSP check");
+                        ret = CheckCertOCSP_ex(ssl->ctx->cm->ocsp,
+                                                    args->dCert, NULL, ssl);
+                    #ifdef WOLFSSL_NONBLOCK_OCSP
+                        if (ret == OCSP_WANT_READ) {
+                            goto exit_ppc;
+                        }
+                    #endif
+                        doLookup = (ret == OCSP_CERT_UNKNOWN);
+                        if (ret != 0) {
+                            WOLFSSL_MSG("\tOCSP Lookup not ok");
+                            args->fatal = 0;
+                        #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
+                            ssl->peerVerifyRet = X509_V_ERR_CERT_REJECTED;
+                        #endif
+                        }
+                    }
+                #endif /* HAVE_OCSP */
+
+                #ifdef HAVE_CRL
+                    if (doLookup && ssl->ctx->cm->crlEnabled) {
+                        WOLFSSL_MSG("Doing Leaf CRL check");
+                        ret = CheckCertCRL(ssl->ctx->cm->crl, args->dCert);
+                    #ifdef WOLFSSL_NONBLOCK_OCSP
+                        if (ret == OCSP_WANT_READ) {
+                            goto exit_ppc;
+                        }
+                    #endif
+                        if (ret != 0) {
+                            WOLFSSL_MSG("\tCRL check not ok");
+                            args->fatal = 0;
+                        #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
+                            ssl->peerVerifyRet = X509_V_ERR_CERT_REJECTED;
+                        #endif
+                        }
+                    }
+                #endif /* HAVE_CRL */
+                    (void)doLookup;
+                }
+            #endif /* HAVE_OCSP || HAVE_CRL */
+
+            #ifdef KEEP_PEER_CERT
+                if (args->fatal == 0) {
+                    int copyRet = 0;
+
+                    #ifdef HAVE_SECURE_RENEGOTIATION
+                        if (ssl->secure_renegotiation &&
+                                           ssl->secure_renegotiation->enabled) {
+                            /* free old peer cert */
+                            FreeX509(&ssl->peerCert);
+                        }
+                    #endif
+
+                    /* set X509 format for peer cert */
+                    copyRet = CopyDecodedToX509(&ssl->peerCert, args->dCert);
+                    if (copyRet == MEMORY_E) {
+                        args->fatal = 1;
+                    }
+                }
+            #endif /* KEEP_PEER_CERT */
+
+            #ifndef IGNORE_KEY_EXTENSIONS
+                #if defined(OPENSSL_EXTRA)
+                  /* when compatibility layer is turned on and no verify is
+                   * set then ignore the certificate key extension */
+                    if (args->dCert->extKeyUsageSet &&
+                          args->dCert->extKeyUsageCrit == 0 &&
+                          ssl->options.verifyNone) {
+                        WOLFSSL_MSG("Not verifying certificate key usage");
+                    }
+                    else
+                #endif
+                if (args->dCert->extKeyUsageSet) {
+                    if ((ssl->specs.kea == rsa_kea) &&
+                        (ssl->options.side == WOLFSSL_CLIENT_END) &&
+                        (args->dCert->extKeyUsage & KEYUSE_KEY_ENCIPHER) == 0) {
+                        ret = KEYUSE_ENCIPHER_E;
+                    }
+                    if ((ssl->specs.sig_algo == rsa_sa_algo ||
+                            (ssl->specs.sig_algo == ecc_dsa_sa_algo &&
+                                 !ssl->specs.static_ecdh)) &&
+                        (args->dCert->extKeyUsage & KEYUSE_DIGITAL_SIG) == 0) {
+                        WOLFSSL_MSG("KeyUse Digital Sig not set");
+                        ret = KEYUSE_SIGNATURE_E;
+                    }
+                }
+
+                #if defined(OPENSSL_EXTRA)
+                    /* when compatibility layer is turned on and no verify is
+                     * set then ignore the certificate key extension */
+                    if (args->dCert->extExtKeyUsageSet &&
+                            args->dCert->extExtKeyUsageCrit == 0 &&
+                          ssl->options.verifyNone) {
+                                WOLFSSL_MSG("Not verifying certificate ext key usage");
+                    }
+                    else
+                #endif
+                if (args->dCert->extExtKeyUsageSet) {
+                    if (ssl->options.side == WOLFSSL_CLIENT_END) {
+                        if ((args->dCert->extExtKeyUsage &
+                                (EXTKEYUSE_ANY | EXTKEYUSE_SERVER_AUTH)) == 0) {
+                            WOLFSSL_MSG("ExtKeyUse Server Auth not set");
+                            ret = EXTKEYUSE_AUTH_E;
+                        }
+                    }
+                    else {
+                        if ((args->dCert->extExtKeyUsage &
+                                (EXTKEYUSE_ANY | EXTKEYUSE_CLIENT_AUTH)) == 0) {
+                            WOLFSSL_MSG("ExtKeyUse Client Auth not set");
+                            ret = EXTKEYUSE_AUTH_E;
+                        }
+                    }
+                }
+            #endif /* IGNORE_KEY_EXTENSIONS */
+
+                if (args->fatal) {
+                    ssl->error = ret;
+                #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
+                    SendAlert(ssl, alert_fatal, bad_certificate);
+                    ssl->peerVerifyRet = X509_V_ERR_CERT_REJECTED;
+                #endif
+                    goto exit_ppc;
+                }
+
+                ssl->options.havePeerCert = 1;
+
+                if (!ssl->options.verifyNone && ssl->buffers.domainName.buffer) {
+                #ifndef WOLFSSL_ALLOW_NO_CN_IN_SAN
+                    /* Per RFC 5280 section 4.2.1.6, "Whenever such identities
+                     * are to be bound into a certificate, the subject
+                     * alternative name extension MUST be used." */
+                    if (args->dCert->altNames) {
+                        if (CheckAltNames(args->dCert,
+                                (char*)ssl->buffers.domainName.buffer) == 0 ) {
+                            WOLFSSL_MSG("DomainName match on alt names failed");
+                            /* try to get peer key still */
+                            ret = DOMAIN_NAME_MISMATCH;
+                        }
+                    }
+                    else {
+                        if (MatchDomainName(
+                                 args->dCert->subjectCN,
+                                 args->dCert->subjectCNLen,
+                                 (char*)ssl->buffers.domainName.buffer) == 0) {
+                            WOLFSSL_MSG("DomainName match on common name failed");
+                            ret = DOMAIN_NAME_MISMATCH;
+                        }
+                    }
+                #else /* WOLFSSL_ALL_NO_CN_IN_SAN */
+                    /* Old behavior. */
+                    if (MatchDomainName(args->dCert->subjectCN,
+                                args->dCert->subjectCNLen,
+                                (char*)ssl->buffers.domainName.buffer) == 0) {
+                        WOLFSSL_MSG("DomainName match on common name failed");
+                        if (CheckAltNames(args->dCert,
+                                 (char*)ssl->buffers.domainName.buffer) == 0 ) {
+                            WOLFSSL_MSG(
+                                "DomainName match on alt names failed too");
+                            /* try to get peer key still */
+                            ret = DOMAIN_NAME_MISMATCH;
+                        }
+                    }
+                #endif /* WOLFSSL_ALL_NO_CN_IN_SAN */
+                }
+
+                /* decode peer key */
+                switch (args->dCert->keyOID) {
+                #ifndef NO_RSA
+                    case RSAk:
+                    {
+                        word32 keyIdx = 0;
+                        int keyRet = 0;
+
+                        if (ssl->peerRsaKey == NULL) {
+                            keyRet = AllocKey(ssl, DYNAMIC_TYPE_RSA,
+                                                (void**)&ssl->peerRsaKey);
+                        } else if (ssl->peerRsaKeyPresent) {
+                            keyRet = ReuseKey(ssl, DYNAMIC_TYPE_RSA,
+                                              ssl->peerRsaKey);
+                            ssl->peerRsaKeyPresent = 0;
+                        }
+
+                        if (keyRet != 0 || wc_RsaPublicKeyDecode(
+                               args->dCert->publicKey, &keyIdx, ssl->peerRsaKey,
+                                                args->dCert->pubKeySize) != 0) {
+                            ret = PEER_KEY_ERROR;
+                        }
+                        else {
+                            ssl->peerRsaKeyPresent = 1;
+                    #ifdef WOLFSSL_RENESAS_TSIP_TLS
+                        /* copy encrypted tsip key index into ssl object */
+                        if (args->dCert->tsip_encRsaKeyIdx) {
+                            if (!ssl->peerTsipEncRsaKeyIndex) {
+                                ssl->peerTsipEncRsaKeyIndex = (byte*)XMALLOC(
+                                    TSIP_TLS_ENCPUBKEY_SZ_BY_CERTVRFY,
+                                    ssl->heap, DYNAMIC_TYPE_RSA);
+                                if (!ssl->peerTsipEncRsaKeyIndex) {
+                                    args->lastErr = MEMORY_E;
+                                    goto exit_ppc;
+                                }
+                            }
+
+                            XMEMCPY(ssl->peerTsipEncRsaKeyIndex,
+                                        args->dCert->tsip_encRsaKeyIdx,
+                                        TSIP_TLS_ENCPUBKEY_SZ_BY_CERTVRFY);
+                         }
+                    #endif
+                    #ifdef HAVE_PK_CALLBACKS
+                        #ifndef NO_RSA
+                            #ifdef HAVE_SECURE_RENEGOTIATION
+                            if (ssl->buffers.peerRsaKey.buffer) {
+                                XFREE(ssl->buffers.peerRsaKey.buffer,
+                                        ssl->heap, DYNAMIC_TYPE_RSA);
+                                ssl->buffers.peerRsaKey.buffer = NULL;
+                            }
+                            #endif
+
+
+                            ssl->buffers.peerRsaKey.buffer =
+                                   (byte*)XMALLOC(args->dCert->pubKeySize,
+                                                ssl->heap, DYNAMIC_TYPE_RSA);
+                            if (ssl->buffers.peerRsaKey.buffer == NULL) {
+                                ret = MEMORY_ERROR;
+                            }
+                            else {
+                                XMEMCPY(ssl->buffers.peerRsaKey.buffer,
+                                        args->dCert->publicKey,
+                                        args->dCert->pubKeySize);
+                                ssl->buffers.peerRsaKey.length =
+                                    args->dCert->pubKeySize;
+                            }
+                        #endif /* NO_RSA */
+                    #endif /* HAVE_PK_CALLBACKS */
+                        }
+
+                        /* check size of peer RSA key */
+                        if (ret == 0 && ssl->peerRsaKeyPresent &&
+                                          !ssl->options.verifyNone &&
+                                          wc_RsaEncryptSize(ssl->peerRsaKey)
+                                              < ssl->options.minRsaKeySz) {
+                            ret = RSA_KEY_SIZE_E;
+                            WOLFSSL_MSG("Peer RSA key is too small");
+                        }
+                        break;
+                    }
+                #endif /* NO_RSA */
+                #ifdef HAVE_NTRU
+                    case NTRUk:
+                    {
+                        if (args->dCert->pubKeySize > sizeof(ssl->peerNtruKey)) {
+                            ret = PEER_KEY_ERROR;
+                        }
+                        else {
+                            XMEMCPY(ssl->peerNtruKey, args->dCert->publicKey,
+                                                      args->dCert->pubKeySize);
+                            ssl->peerNtruKeyLen =
+                                (word16)args->dCert->pubKeySize;
+                            ssl->peerNtruKeyPresent = 1;
+                        }
+                        break;
+                    }
+                #endif /* HAVE_NTRU */
+                #ifdef HAVE_ECC
+                    case ECDSAk:
+                    {
+                        int keyRet = 0;
+                        word32 idx = 0;
+
+                        if (ssl->peerEccDsaKey == NULL) {
+                            /* alloc/init on demand */
+                            keyRet = AllocKey(ssl, DYNAMIC_TYPE_ECC,
+                                    (void**)&ssl->peerEccDsaKey);
+                        } else if (ssl->peerEccDsaKeyPresent) {
+                            keyRet = ReuseKey(ssl, DYNAMIC_TYPE_ECC,
+                                              ssl->peerEccDsaKey);
+                            ssl->peerEccDsaKeyPresent = 0;
+                        }
+
+                        if (keyRet != 0 ||
+                            wc_EccPublicKeyDecode(args->dCert->publicKey, &idx,
+                                                ssl->peerEccDsaKey,
+                                                args->dCert->pubKeySize) != 0) {
+                            ret = PEER_KEY_ERROR;
+                        }
+                        else {
+                            ssl->peerEccDsaKeyPresent = 1;
+                    #ifdef HAVE_PK_CALLBACKS
+                            ssl->buffers.peerEccDsaKey.buffer =
+                                   (byte*)XMALLOC(args->dCert->pubKeySize,
+                                           ssl->heap, DYNAMIC_TYPE_ECC);
+                            if (ssl->buffers.peerEccDsaKey.buffer == NULL) {
+                                ERROR_OUT(MEMORY_ERROR, exit_ppc);
+                            }
+                            else {
+                                XMEMCPY(ssl->buffers.peerEccDsaKey.buffer,
+                                        args->dCert->publicKey,
+                                        args->dCert->pubKeySize);
+                                ssl->buffers.peerEccDsaKey.length =
+                                        args->dCert->pubKeySize;
+                            }
+                    #endif /* HAVE_PK_CALLBACKS */
+                        }
+
+                        /* check size of peer ECC key */
+                        if (ret == 0 && ssl->peerEccDsaKeyPresent &&
+                                              !ssl->options.verifyNone &&
+                                              wc_ecc_size(ssl->peerEccDsaKey)
+                                              < ssl->options.minEccKeySz) {
+                            ret = ECC_KEY_SIZE_E;
+                            WOLFSSL_MSG("Peer ECC key is too small");
+                        }
+                        break;
+                    }
+                #endif /* HAVE_ECC */
+                #ifdef HAVE_ED25519
+                    case ED25519k:
+                    {
+                        int keyRet = 0;
+                        if (ssl->peerEd25519Key == NULL) {
+                            /* alloc/init on demand */
+                            keyRet = AllocKey(ssl, DYNAMIC_TYPE_ED25519,
+                                    (void**)&ssl->peerEd25519Key);
+                        } else if (ssl->peerEd25519KeyPresent) {
+                            keyRet = ReuseKey(ssl, DYNAMIC_TYPE_ED25519,
+                                              ssl->peerEd25519Key);
+                            ssl->peerEd25519KeyPresent = 0;
+                        }
+
+                        if (keyRet != 0 ||
+                            wc_ed25519_import_public(args->dCert->publicKey,
+                                                     args->dCert->pubKeySize,
+                                                     ssl->peerEd25519Key)
+                                                                         != 0) {
+                            ret = PEER_KEY_ERROR;
+                        }
+                        else {
+                            ssl->peerEd25519KeyPresent = 1;
+                    #ifdef HAVE_PK_CALLBACKS
+                            ssl->buffers.peerEd25519Key.buffer =
+                                   (byte*)XMALLOC(args->dCert->pubKeySize,
+                                           ssl->heap, DYNAMIC_TYPE_ED25519);
+                            if (ssl->buffers.peerEd25519Key.buffer == NULL) {
+                                ERROR_OUT(MEMORY_ERROR, exit_ppc);
+                            }
+                            else {
+                                XMEMCPY(ssl->buffers.peerEd25519Key.buffer,
+                                        args->dCert->publicKey,
+                                        args->dCert->pubKeySize);
+                                ssl->buffers.peerEd25519Key.length =
+                                        args->dCert->pubKeySize;
+                            }
+                    #endif /*HAVE_PK_CALLBACKS */
+                        }
+
+                        /* check size of peer ECC key */
+                        if (ret == 0 && ssl->peerEd25519KeyPresent &&
+                                  !ssl->options.verifyNone &&
+                                  ED25519_KEY_SIZE < ssl->options.minEccKeySz) {
+                            ret = ECC_KEY_SIZE_E;
+                            WOLFSSL_MSG("Peer ECC key is too small");
+                        }
+                        break;
+                    }
+                #endif /* HAVE_ED25519 */
+                #ifdef HAVE_ED448
+                    case ED448k:
+                    {
+                        int keyRet = 0;
+                        if (ssl->peerEd448Key == NULL) {
+                            /* alloc/init on demand */
+                            keyRet = AllocKey(ssl, DYNAMIC_TYPE_ED448,
+                                    (void**)&ssl->peerEd448Key);
+                        } else if (ssl->peerEd448KeyPresent) {
+                            keyRet = ReuseKey(ssl, DYNAMIC_TYPE_ED448,
+                                    ssl->peerEd448Key);
+                            ssl->peerEd448KeyPresent = 0;
+                        }
+
+                        if (keyRet != 0 ||
+                            wc_ed448_import_public(args->dCert->publicKey,
+                                    args->dCert->pubKeySize,
+                                    ssl->peerEd448Key) != 0) {
+                            ret = PEER_KEY_ERROR;
+                        }
+                        else {
+                            ssl->peerEd448KeyPresent = 1;
+                    #ifdef HAVE_PK_CALLBACKS
+                            ssl->buffers.peerEd448Key.buffer =
+                                   (byte*)XMALLOC(args->dCert->pubKeySize,
+                                           ssl->heap, DYNAMIC_TYPE_ED448);
+                            if (ssl->buffers.peerEd448Key.buffer == NULL) {
+                                ERROR_OUT(MEMORY_ERROR, exit_ppc);
+                            }
+                            else {
+                                XMEMCPY(ssl->buffers.peerEd448Key.buffer,
+                                        args->dCert->publicKey,
+                                        args->dCert->pubKeySize);
+                                ssl->buffers.peerEd448Key.length =
+                                        args->dCert->pubKeySize;
+                            }
+                    #endif /*HAVE_PK_CALLBACKS */
+                        }
+
+                        /* check size of peer ECC key */
+                        if (ret == 0 && ssl->peerEd448KeyPresent &&
+                               !ssl->options.verifyNone &&
+                               ED448_KEY_SIZE < ssl->options.minEccKeySz) {
+                            ret = ECC_KEY_SIZE_E;
+                            WOLFSSL_MSG("Peer ECC key is too small");
+                        }
+                        break;
+                    }
+                #endif /* HAVE_ED448 */
+                    default:
+                        break;
+                }
+
+                /* args->dCert free'd in function cleanup after callback */
+            } /* if (count > 0) */
+
+            /* Check for error */
+            if (args->fatal && ret != 0) {
+                goto exit_ppc;
+            }
+
+            /* Advance state and proceed */
+            ssl->options.asyncState = TLS_ASYNC_FINALIZE;
+        } /* case TLS_ASYNC_VERIFY */
+        FALL_THROUGH;
+
+        case TLS_ASYNC_FINALIZE:
+        {
+            /* load last error */
+            if (args->lastErr != 0 && ret == 0) {
+                ret = args->lastErr;
+            }
+
+        #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
+            if (args->untrustedDepth > ssl->options.verifyDepth) {
+                ssl->peerVerifyRet = X509_V_ERR_CERT_CHAIN_TOO_LONG;
+                ret = MAX_CHAIN_ERROR;
+            }
+        #endif
+
+            /* Do verify callback */
+            ret = DoVerifyCallback(ssl->ctx->cm, ssl, ret, args);
+
+            if (ssl->options.verifyNone &&
+                              (ret == CRL_MISSING || ret == CRL_CERT_REVOKED)) {
+                WOLFSSL_MSG("Ignoring CRL problem based on verify setting");
+                ret = ssl->error = 0;
+            }
+
+            if (ret != 0) {
+                if (!ssl->options.verifyNone) {
+                    DoCertFatalAlert(ssl, ret);
+                }
+                ssl->error = ret; /* Report SSL error */
+            }
+
+            if (ret == 0 && ssl->options.side == WOLFSSL_CLIENT_END) {
+                ssl->options.serverState = SERVER_CERT_COMPLETE;
+            }
+
+            if (IsEncryptionOn(ssl, 0)) {
+                args->idx += ssl->keys.padSz;
+            #if defined(HAVE_ENCRYPT_THEN_MAC) && !defined(WOLFSSL_AEAD_ONLY)
+                if (ssl->options.startedETMRead)
+                    args->idx += MacSize(ssl);
+            #endif
+            }
+
+            /* Advance state and proceed */
+            ssl->options.asyncState = TLS_ASYNC_END;
+        } /* case TLS_ASYNC_FINALIZE */
+        FALL_THROUGH;
+
+        case TLS_ASYNC_END:
+        {
+            /* Set final index */
+            *inOutIdx = args->idx;
+
+            break;
+        }
+        default:
+            ret = INPUT_CASE_ERROR;
+            break;
+    } /* switch(ssl->options.asyncState) */
+
+exit_ppc:
+
+    WOLFSSL_LEAVE("ProcessPeerCerts", ret);
+
+
+#if defined(WOLFSSL_ASYNC_CRYPT) || defined(WOLFSSL_NONBLOCK_OCSP)
+    if (ret == WC_PENDING_E || ret == OCSP_WANT_READ) {
+        /* Mark message as not received so it can process again */
+        ssl->msgsReceived.got_certificate = 0;
+
+        return ret;
+    }
+#endif /* WOLFSSL_ASYNC_CRYPT || WOLFSSL_NONBLOCK_OCSP */
+
+    FreeProcPeerCertArgs(ssl, args);
+
+#if defined(WOLFSSL_ASYNC_CRYPT)
+#elif defined(WOLFSSL_NONBLOCK_OCSP)
+    XFREE(args, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER);
+    ssl->nonblockarg = NULL;
+#elif defined(WOLFSSL_SMALL_STACK)
+    XFREE(args, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER);
+#endif
+
+    FreeKeyExchange(ssl);
+
+    return ret;
+}
+#endif
+
+#ifndef WOLFSSL_NO_TLS12
+#if !defined(NO_WOLFSSL_CLIENT) || !defined(WOLFSSL_NO_CLIENT_AUTH)
+
+/* handle processing of certificate (11) */
+static int DoCertificate(WOLFSSL* ssl, byte* input, word32* inOutIdx,
+                                                                word32 size)
+{
+    int ret;
+
+    WOLFSSL_START(WC_FUNC_CERTIFICATE_DO);
+    WOLFSSL_ENTER("DoCertificate");
+
+#ifdef SESSION_CERTS
+    /* Reset the session cert chain count in case the session resume failed. */
+    ssl->session.chain.count = 0;
+    #ifdef WOLFSSL_ALT_CERT_CHAINS
+        ssl->session.altChain.count = 0;
+    #endif
+#endif /* SESSION_CERTS */
+
+    ret = ProcessPeerCerts(ssl, input, inOutIdx, size);
+#ifdef WOLFSSL_EXTRA_ALERTS
+    if (ret == BUFFER_ERROR || ret == ASN_PARSE_E)
+        SendAlert(ssl, alert_fatal, decode_error);
+#endif
+
+#ifdef OPENSSL_EXTRA
+    ssl->options.serverState = SERVER_CERT_COMPLETE;
+#endif
+
+    WOLFSSL_LEAVE("DoCertificate", ret);
+    WOLFSSL_END(WC_FUNC_CERTIFICATE_DO);
+
+    return ret;
+}
+
+/* handle processing of certificate_status (22) */
+static int DoCertificateStatus(WOLFSSL* ssl, byte* input, word32* inOutIdx,
+                                                                    word32 size)
+{
+    int    ret = 0;
+    byte   status_type;
+    word32 status_length;
+
+    WOLFSSL_START(WC_FUNC_CERTIFICATE_STATUS_DO);
+    WOLFSSL_ENTER("DoCertificateStatus");
+
+    if (size < ENUM_LEN + OPAQUE24_LEN)
+        return BUFFER_ERROR;
+
+    status_type = input[(*inOutIdx)++];
+
+    c24to32(input + *inOutIdx, &status_length);
+    *inOutIdx += OPAQUE24_LEN;
+
+    if (size != ENUM_LEN + OPAQUE24_LEN + status_length)
+        return BUFFER_ERROR;
+
+    switch (status_type) {
+
+    #if defined(HAVE_CERTIFICATE_STATUS_REQUEST) \
+     || defined(HAVE_CERTIFICATE_STATUS_REQUEST_V2)
+
+        /* WOLFSSL_CSR_OCSP overlaps with WOLFSSL_CSR2_OCSP */
+        case WOLFSSL_CSR2_OCSP:
+            ret = ProcessCSR(ssl, input, inOutIdx, status_length);
+            break;
+
+    #endif
+
+    #if defined(HAVE_CERTIFICATE_STATUS_REQUEST_V2)
+
+        case WOLFSSL_CSR2_OCSP_MULTI: {
+            OcspRequest* request;
+            word32 list_length = status_length;
+            byte   idx = 0;
+
+            #ifdef WOLFSSL_SMALL_STACK
+                CertStatus* status;
+                OcspResponse* response;
+            #else
+                CertStatus status[1];
+                OcspResponse response[1];
+            #endif
+
+            do {
+                if (ssl->status_request_v2) {
+                    ssl->status_request_v2 = 0;
+                    break;
+                }
+
+                return BUFFER_ERROR;
+            } while(0);
+
+            #ifdef WOLFSSL_SMALL_STACK
+                status = (CertStatus*)XMALLOC(sizeof(CertStatus), ssl->heap,
+                                                       DYNAMIC_TYPE_OCSP_STATUS);
+                response = (OcspResponse*)XMALLOC(sizeof(OcspResponse), ssl->heap,
+                                                       DYNAMIC_TYPE_OCSP_REQUEST);
+
+                if (status == NULL || response == NULL) {
+                    if (status)
+                        XFREE(status, ssl->heap, DYNAMIC_TYPE_OCSP_STATUS);
+                    if (response)
+                        XFREE(response, ssl->heap, DYNAMIC_TYPE_OCSP_REQUEST);
+
+                    return MEMORY_ERROR;
+                }
+            #endif
+
+            while (list_length && ret == 0) {
+                if (OPAQUE24_LEN > list_length) {
+                    ret = BUFFER_ERROR;
+                    break;
+                }
+
+                c24to32(input + *inOutIdx, &status_length);
+                *inOutIdx   += OPAQUE24_LEN;
+                list_length -= OPAQUE24_LEN;
+
+                if (status_length > list_length) {
+                    ret = BUFFER_ERROR;
+                    break;
+                }
+
+                if (status_length) {
+                    InitOcspResponse(response, status, input +*inOutIdx,
+                                                                 status_length);
+
+                    if ((OcspResponseDecode(response, ssl->ctx->cm, ssl->heap,
+                                                                        0) != 0)
+                    ||  (response->responseStatus != OCSP_SUCCESSFUL)
+                    ||  (response->status->status != CERT_GOOD))
+                        ret = BAD_CERTIFICATE_STATUS_ERROR;
+
+                    while (ret == 0) {
+                        request = (OcspRequest*)TLSX_CSR2_GetRequest(
+                                ssl->extensions, status_type, idx++);
+
+                        if (request == NULL)
+                            ret = BAD_CERTIFICATE_STATUS_ERROR;
+                        else if (CompareOcspReqResp(request, response) == 0)
+                            break;
+                        else if (idx == 1) /* server cert must be OK */
+                            ret = BAD_CERTIFICATE_STATUS_ERROR;
+                    }
+
+                    *inOutIdx   += status_length;
+                    list_length -= status_length;
+                }
+            }
+
+            #if defined(HAVE_CERTIFICATE_STATUS_REQUEST_V2)
+                ssl->status_request_v2 = 0;
+            #endif
+
+            #ifdef WOLFSSL_SMALL_STACK
+                XFREE(status,   NULL, DYNAMIC_TYPE_OCSP_STATUS);
+                XFREE(response, NULL, DYNAMIC_TYPE_OCSP_REQUEST);
+            #endif
+
+        }
+        break;
+
+    #endif
+
+        default:
+            ret = BUFFER_ERROR;
+    }
+
+    if (ret != 0)
+        SendAlert(ssl, alert_fatal, bad_certificate_status_response);
+
+    if (IsEncryptionOn(ssl, 0)) {
+    #if defined(HAVE_ENCRYPT_THEN_MAC) && !defined(WOLFSSL_AEAD_ONLY)
+        if (ssl->options.startedETMRead) {
+            word32 digestSz = MacSize(ssl);
+            if (*inOutIdx + ssl->keys.padSz + digestSz > size)
+                return BUFFER_E;
+            *inOutIdx += ssl->keys.padSz + digestSz;
+        }
+        else
+    #endif
+        {
+            if (*inOutIdx + ssl->keys.padSz > size)
+                return BUFFER_E;
+            *inOutIdx += ssl->keys.padSz;
+        }
+    }
+
+    WOLFSSL_LEAVE("DoCertificateStatus", ret);
+    WOLFSSL_END(WC_FUNC_CERTIFICATE_STATUS_DO);
+
+    return ret;
+}
+
+#endif
+
+#endif /* !WOLFSSL_NO_TLS12 */
+
+#endif /* !NO_CERTS */
+
+#ifndef WOLFSSL_NO_TLS12
+
+static int DoHelloRequest(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
+                                                    word32 size, word32 totalSz)
+{
+    (void)input;
+
+    WOLFSSL_START(WC_FUNC_HELLO_REQUEST_DO);
+    WOLFSSL_ENTER("DoHelloRequest");
+
+    if (size) /* must be 0 */
+        return BUFFER_ERROR;
+
+    if (IsEncryptionOn(ssl, 0)) {
+    #if defined(HAVE_ENCRYPT_THEN_MAC) && !defined(WOLFSSL_AEAD_ONLY)
+        if (ssl->options.startedETMRead) {
+            word32 digestSz = MacSize(ssl);
+            if (*inOutIdx + ssl->keys.padSz + digestSz > totalSz)
+                return BUFFER_E;
+            *inOutIdx += ssl->keys.padSz + digestSz;
+        }
+        else
+    #endif
+        {
+            /* access beyond input + size should be checked against totalSz */
+            if (*inOutIdx + ssl->keys.padSz > totalSz)
+                return BUFFER_E;
+
+            *inOutIdx += ssl->keys.padSz;
+        }
+    }
+
+    if (ssl->options.side == WOLFSSL_SERVER_END) {
+        SendAlert(ssl, alert_fatal, unexpected_message); /* try */
+        return FATAL_ERROR;
+    }
+#ifdef HAVE_SECURE_RENEGOTIATION
+    else if (ssl->secure_renegotiation && ssl->secure_renegotiation->enabled) {
+        ssl->secure_renegotiation->startScr = 1;
+        WOLFSSL_LEAVE("DoHelloRequest", 0);
+        WOLFSSL_END(WC_FUNC_HELLO_REQUEST_DO);
+        return 0;
+    }
+#endif
+    else {
+        return SendAlert(ssl, alert_warning, no_renegotiation);
+    }
+}
+
+
+int DoFinished(WOLFSSL* ssl, const byte* input, word32* inOutIdx, word32 size,
+                                                      word32 totalSz, int sniff)
+{
+    word32 finishedSz = (ssl->options.tls ? TLS_FINISHED_SZ : FINISHED_SZ);
+
+    WOLFSSL_START(WC_FUNC_FINISHED_DO);
+    WOLFSSL_ENTER("DoFinished");
+
+    if (finishedSz != size)
+        return BUFFER_ERROR;
+
+    /* check against totalSz */
+    #if defined(HAVE_ENCRYPT_THEN_MAC) && !defined(WOLFSSL_AEAD_ONLY)
+        if (ssl->options.startedETMRead) {
+            if (*inOutIdx + size + ssl->keys.padSz + MacSize(ssl) > totalSz)
+                return BUFFER_E;
+        }
+        else
+    #endif
+        {
+            if (*inOutIdx + size + ssl->keys.padSz > totalSz)
+                return BUFFER_E;
+        }
+
+    #ifdef WOLFSSL_CALLBACKS
+        if (ssl->hsInfoOn) AddPacketName(ssl, "Finished");
+        if (ssl->toInfoOn) AddLateName("Finished", &ssl->timeoutInfo);
+    #endif
+
+    if (sniff == NO_SNIFF) {
+        if (XMEMCMP(input + *inOutIdx, &ssl->hsHashes->verifyHashes,size) != 0){
+            WOLFSSL_MSG("Verify finished error on hashes");
+    #ifdef WOLFSSL_EXTRA_ALERTS
+            SendAlert(ssl, alert_fatal, decrypt_error);
+    #endif
+            return VERIFY_FINISHED_ERROR;
+        }
+    }
+
+#ifdef HAVE_SECURE_RENEGOTIATION
+    if (ssl->secure_renegotiation) {
+        /* save peer's state */
+        if (ssl->options.side == WOLFSSL_CLIENT_END)
+            XMEMCPY(ssl->secure_renegotiation->server_verify_data,
+                    input + *inOutIdx, TLS_FINISHED_SZ);
+        else
+            XMEMCPY(ssl->secure_renegotiation->client_verify_data,
+                    input + *inOutIdx, TLS_FINISHED_SZ);
+        ssl->secure_renegotiation->verifySet = 1;
+    }
+#endif
+
+    /* force input exhaustion at ProcessReply consuming padSz */
+    *inOutIdx += size + ssl->keys.padSz;
+#if defined(HAVE_ENCRYPT_THEN_MAC) && !defined(WOLFSSL_AEAD_ONLY)
+    if (ssl->options.startedETMRead)
+        *inOutIdx += MacSize(ssl);
+#endif
+
+    if (ssl->options.side == WOLFSSL_CLIENT_END) {
+        ssl->options.serverState = SERVER_FINISHED_COMPLETE;
+#ifdef OPENSSL_EXTRA
+        ssl->cbmode = SSL_CB_MODE_WRITE;
+        ssl->options.clientState = CLIENT_FINISHED_COMPLETE;
+#endif
+        if (!ssl->options.resuming) {
+#ifdef OPENSSL_EXTRA
+            if (ssl->CBIS != NULL) {
+                ssl->CBIS(ssl, SSL_CB_CONNECT_LOOP, SSL_SUCCESS);
+            }
+#endif
+            ssl->options.handShakeState = HANDSHAKE_DONE;
+            ssl->options.handShakeDone  = 1;
+        }
+    }
+    else {
+        ssl->options.clientState = CLIENT_FINISHED_COMPLETE;
+#ifdef OPENSSL_EXTRA
+        ssl->cbmode = SSL_CB_MODE_READ;
+        ssl->options.serverState = SERVER_FINISHED_COMPLETE;
+#endif
+        if (ssl->options.resuming) {
+#ifdef OPENSSL_EXTRA
+            if (ssl->CBIS != NULL) {
+                ssl->CBIS(ssl, SSL_CB_ACCEPT_LOOP, SSL_SUCCESS);
+            }
+#endif
+            ssl->options.handShakeState = HANDSHAKE_DONE;
+            ssl->options.handShakeDone  = 1;
+        }
+    }
+#ifdef WOLFSSL_DTLS
+    if (ssl->options.dtls) {
+        DtlsMsgPoolReset(ssl);
+    }
+#endif
+
+    WOLFSSL_LEAVE("DoFinished", 0);
+    WOLFSSL_END(WC_FUNC_FINISHED_DO);
+
+    return 0;
+}
+
+
+/* Make sure no duplicates, no fast forward, or other problems; 0 on success */
+static int SanityCheckMsgReceived(WOLFSSL* ssl, byte type)
+{
+    /* verify not a duplicate, mark received, check state */
+    switch (type) {
+
+#ifndef NO_WOLFSSL_CLIENT
+        case hello_request:
+            if (ssl->msgsReceived.got_hello_request) {
+                WOLFSSL_MSG("Duplicate HelloRequest received");
+                return DUPLICATE_MSG_E;
+            }
+            ssl->msgsReceived.got_hello_request = 1;
+
+            break;
+#endif
+
+#ifndef NO_WOLFSSL_SERVER
+        case client_hello:
+            if (ssl->msgsReceived.got_client_hello) {
+                WOLFSSL_MSG("Duplicate ClientHello received");
+    #ifdef WOLFSSL_EXTRA_ALERTS
+                SendAlert(ssl, alert_fatal, unexpected_message);
+    #endif
+                return DUPLICATE_MSG_E;
+            }
+            ssl->msgsReceived.got_client_hello = 1;
+
+            break;
+#endif
+
+#ifndef NO_WOLFSSL_CLIENT
+        case server_hello:
+            if (ssl->msgsReceived.got_server_hello) {
+                WOLFSSL_MSG("Duplicate ServerHello received");
+                return DUPLICATE_MSG_E;
+            }
+            ssl->msgsReceived.got_server_hello = 1;
+
+            break;
+#endif
+
+#ifndef NO_WOLFSSL_CLIENT
+        case hello_verify_request:
+            if (ssl->msgsReceived.got_hello_verify_request) {
+                WOLFSSL_MSG("Duplicate HelloVerifyRequest received");
+                return DUPLICATE_MSG_E;
+            }
+            ssl->msgsReceived.got_hello_verify_request = 1;
+
+            break;
+#endif
+
+#ifndef NO_WOLFSSL_CLIENT
+        case session_ticket:
+            if (ssl->msgsReceived.got_session_ticket) {
+                WOLFSSL_MSG("Duplicate SessionTicket received");
+                return DUPLICATE_MSG_E;
+            }
+            ssl->msgsReceived.got_session_ticket = 1;
+
+            break;
+#endif
+
+        case certificate:
+            if (ssl->msgsReceived.got_certificate) {
+                WOLFSSL_MSG("Duplicate Certificate received");
+                return DUPLICATE_MSG_E;
+            }
+            ssl->msgsReceived.got_certificate = 1;
+
+#ifndef NO_WOLFSSL_CLIENT
+            if (ssl->options.side == WOLFSSL_CLIENT_END) {
+                if ( ssl->msgsReceived.got_server_hello == 0) {
+                    WOLFSSL_MSG("No ServerHello before Cert");
+                    return OUT_OF_ORDER_E;
+                }
+            }
+#endif
+#ifndef NO_WOLFSSL_SERVER
+            if (ssl->options.side == WOLFSSL_SERVER_END) {
+                if ( ssl->msgsReceived.got_client_hello == 0) {
+                    WOLFSSL_MSG("No ClientHello before Cert");
+                    return OUT_OF_ORDER_E;
+                }
+            }
+#endif
+            break;
+
+#ifndef NO_WOLFSSL_CLIENT
+        case certificate_status:
+            if (ssl->msgsReceived.got_certificate_status) {
+                WOLFSSL_MSG("Duplicate CertificateSatatus received");
+                return DUPLICATE_MSG_E;
+            }
+            ssl->msgsReceived.got_certificate_status = 1;
+
+            if (ssl->msgsReceived.got_certificate == 0) {
+                WOLFSSL_MSG("No Certificate before CertificateStatus");
+                return OUT_OF_ORDER_E;
+            }
+            if (ssl->msgsReceived.got_server_key_exchange != 0) {
+                WOLFSSL_MSG("CertificateStatus after ServerKeyExchange");
+                return OUT_OF_ORDER_E;
+            }
+
+            break;
+#endif
+
+#ifndef NO_WOLFSSL_CLIENT
+        case server_key_exchange:
+            if (ssl->msgsReceived.got_server_key_exchange) {
+                WOLFSSL_MSG("Duplicate ServerKeyExchange received");
+                return DUPLICATE_MSG_E;
+            }
+            ssl->msgsReceived.got_server_key_exchange = 1;
+
+            if (ssl->msgsReceived.got_server_hello == 0) {
+                WOLFSSL_MSG("No ServerHello before ServerKeyExchange");
+                return OUT_OF_ORDER_E;
+            }
+            if (ssl->msgsReceived.got_certificate_status == 0) {
+#ifdef HAVE_CERTIFICATE_STATUS_REQUEST
+                if (ssl->status_request) {
+                    int ret;
+
+                    WOLFSSL_MSG("No CertificateStatus before ServerKeyExchange");
+                    if ((ret = TLSX_CSR_ForceRequest(ssl)) != 0)
+                        return ret;
+                }
+#endif
+#ifdef HAVE_CERTIFICATE_STATUS_REQUEST_V2
+                if (ssl->status_request_v2) {
+                    int ret;
+
+                    WOLFSSL_MSG("No CertificateStatus before ServerKeyExchange");
+                    if ((ret = TLSX_CSR2_ForceRequest(ssl)) != 0)
+                        return ret;
+                }
+#endif
+            }
+
+            break;
+#endif
+
+#ifndef NO_WOLFSSL_CLIENT
+        case certificate_request:
+            if (ssl->msgsReceived.got_certificate_request) {
+                WOLFSSL_MSG("Duplicate CertificateRequest received");
+                return DUPLICATE_MSG_E;
+            }
+            ssl->msgsReceived.got_certificate_request = 1;
+
+            break;
+#endif
+
+#ifndef NO_WOLFSSL_CLIENT
+        case server_hello_done:
+            if (ssl->msgsReceived.got_server_hello_done) {
+                WOLFSSL_MSG("Duplicate ServerHelloDone received");
+                return DUPLICATE_MSG_E;
+            }
+            ssl->msgsReceived.got_server_hello_done = 1;
+
+            if (ssl->msgsReceived.got_certificate == 0) {
+                if (ssl->specs.kea == psk_kea ||
+                    ssl->specs.kea == dhe_psk_kea ||
+                    ssl->specs.kea == ecdhe_psk_kea ||
+                    ssl->options.usingAnon_cipher) {
+                    WOLFSSL_MSG("No Cert required");
+                } else {
+                    WOLFSSL_MSG("No Certificate before ServerHelloDone");
+                    return OUT_OF_ORDER_E;
+                }
+            }
+            if (ssl->msgsReceived.got_server_key_exchange == 0) {
+                int pskNoServerHint = 0;  /* not required in this case */
+
+                #ifndef NO_PSK
+                    if (ssl->specs.kea == psk_kea &&
+                        ssl->arrays != NULL &&
+                        ssl->arrays->server_hint[0] == 0)
+                        pskNoServerHint = 1;
+                #endif
+                if (ssl->specs.static_ecdh == 1 ||
+                    ssl->specs.kea == rsa_kea ||
+                    ssl->specs.kea == ntru_kea ||
+                    pskNoServerHint) {
+                    WOLFSSL_MSG("No KeyExchange required");
+                } else {
+                    WOLFSSL_MSG("No ServerKeyExchange before ServerDone");
+                    return OUT_OF_ORDER_E;
+                }
+            }
+            break;
+#endif
+
+#ifndef NO_WOLFSSL_SERVER
+        case certificate_verify:
+            if (ssl->msgsReceived.got_certificate_verify) {
+                WOLFSSL_MSG("Duplicate CertificateVerify received");
+                return DUPLICATE_MSG_E;
+            }
+            ssl->msgsReceived.got_certificate_verify = 1;
+
+            if ( ssl->msgsReceived.got_certificate == 0) {
+                WOLFSSL_MSG("No Cert before CertVerify");
+                return OUT_OF_ORDER_E;
+            }
+            break;
+#endif
+
+#ifndef NO_WOLFSSL_SERVER
+        case client_key_exchange:
+            if (ssl->msgsReceived.got_client_key_exchange) {
+                WOLFSSL_MSG("Duplicate ClientKeyExchange received");
+    #ifdef WOLFSSL_EXTRA_ALERTS
+                SendAlert(ssl, alert_fatal, unexpected_message);
+    #endif
+                return DUPLICATE_MSG_E;
+            }
+            ssl->msgsReceived.got_client_key_exchange = 1;
+
+            if (ssl->msgsReceived.got_client_hello == 0) {
+                WOLFSSL_MSG("No ClientHello before ClientKeyExchange");
+                return OUT_OF_ORDER_E;
+            }
+            break;
+#endif
+
+        case finished:
+            if (ssl->msgsReceived.got_finished) {
+                WOLFSSL_MSG("Duplicate Finished received");
+                return DUPLICATE_MSG_E;
+            }
+            ssl->msgsReceived.got_finished = 1;
+
+            if (ssl->msgsReceived.got_change_cipher == 0) {
+                WOLFSSL_MSG("Finished received before ChangeCipher");
+    #ifdef WOLFSSL_EXTRA_ALERTS
+                SendAlert(ssl, alert_fatal, unexpected_message);
+    #endif
+                return NO_CHANGE_CIPHER_E;
+            }
+            break;
+
+        case change_cipher_hs:
+            if (ssl->msgsReceived.got_change_cipher) {
+                WOLFSSL_MSG("Duplicate ChangeCipher received");
+    #ifdef WOLFSSL_EXTRA_ALERTS
+                SendAlert(ssl, alert_fatal, unexpected_message);
+    #endif
+                return DUPLICATE_MSG_E;
+            }
+            /* DTLS is going to ignore the CCS message if the client key
+             * exchange message wasn't received yet. */
+            if (!ssl->options.dtls)
+                ssl->msgsReceived.got_change_cipher = 1;
+
+#ifndef NO_WOLFSSL_CLIENT
+            if (ssl->options.side == WOLFSSL_CLIENT_END) {
+                if (!ssl->options.resuming) {
+                   if (ssl->msgsReceived.got_server_hello_done == 0) {
+                        WOLFSSL_MSG("No ServerHelloDone before ChangeCipher");
+                        return OUT_OF_ORDER_E;
+                   }
+                }
+                else {
+                    if (ssl->msgsReceived.got_server_hello == 0) {
+                        WOLFSSL_MSG("No ServerHello before ChangeCipher on Resume");
+                        return OUT_OF_ORDER_E;
+                    }
+                }
+                #ifdef HAVE_SESSION_TICKET
+                    if (ssl->expect_session_ticket) {
+                        WOLFSSL_MSG("Expected session ticket missing");
+                        #ifdef WOLFSSL_DTLS
+                            if (ssl->options.dtls)
+                                return OUT_OF_ORDER_E;
+                        #endif
+                        return SESSION_TICKET_EXPECT_E;
+                    }
+                #endif
+            }
+#endif
+#ifndef NO_WOLFSSL_SERVER
+            if (ssl->options.side == WOLFSSL_SERVER_END) {
+                if (!ssl->options.resuming &&
+                               ssl->msgsReceived.got_client_key_exchange == 0) {
+                    WOLFSSL_MSG("No ClientKeyExchange before ChangeCipher");
+    #ifdef WOLFSSL_EXTRA_ALERTS
+                    SendAlert(ssl, alert_fatal, unexpected_message);
+    #endif
+                    return OUT_OF_ORDER_E;
+                }
+                #ifndef NO_CERTS
+                    if (ssl->options.verifyPeer &&
+                        ssl->options.havePeerCert) {
+
+                        if (!ssl->options.havePeerVerify) {
+                            WOLFSSL_MSG("client didn't send cert verify");
+                            #ifdef WOLFSSL_DTLS
+                                if (ssl->options.dtls)
+                                    return OUT_OF_ORDER_E;
+                            #endif
+                            return NO_PEER_VERIFY;
+                        }
+                    }
+                #endif
+            }
+#endif
+            if (ssl->options.dtls)
+                ssl->msgsReceived.got_change_cipher = 1;
+            break;
+
+        default:
+            WOLFSSL_MSG("Unknown message type");
+            return SANITY_MSG_E;
+    }
+
+    return 0;
+}
+
+
+static int DoHandShakeMsgType(WOLFSSL* ssl, byte* input, word32* inOutIdx,
+                          byte type, word32 size, word32 totalSz)
+{
+    int ret = 0;
+    word32 expectedIdx;
+
+    WOLFSSL_ENTER("DoHandShakeMsgType");
+
+#ifdef WOLFSSL_TLS13
+    if (type == hello_retry_request) {
+        return DoTls13HandShakeMsgType(ssl, input, inOutIdx, type, size,
+                                       totalSz);
+    }
+#endif
+
+    /* make sure can read the message */
+    if (*inOutIdx + size > totalSz) {
+        WOLFSSL_MSG("Incomplete Data");
+        return INCOMPLETE_DATA;
+    }
+
+    expectedIdx = *inOutIdx + size +
+                  (ssl->keys.encryptionOn ? ssl->keys.padSz : 0);
+#if defined(HAVE_ENCRYPT_THEN_MAC) && !defined(WOLFSSL_AEAD_ONLY)
+    if (ssl->options.startedETMRead && ssl->keys.encryptionOn)
+        expectedIdx += MacSize(ssl);
+#endif
+
+#if !defined(WOLFSSL_NO_SERVER) && \
+    defined(HAVE_SECURE_RENEGOTIATION) && \
+    defined(HAVE_SERVER_RENEGOTIATION_INFO)
+    if (ssl->options.handShakeDone && type == client_hello &&
+            ssl->secure_renegotiation &&
+            ssl->secure_renegotiation->enabled)
+    {
+        WOLFSSL_MSG("Reset handshake state");
+        XMEMSET(&ssl->msgsReceived, 0, sizeof(MsgsReceived));
+        ssl->options.serverState = NULL_STATE;
+        ssl->options.clientState = NULL_STATE;
+        ssl->options.connectState = CONNECT_BEGIN;
+        ssl->options.acceptState = ACCEPT_FIRST_REPLY_DONE;
+        ssl->options.handShakeState = NULL_STATE;
+        ssl->secure_renegotiation->cache_status = SCR_CACHE_NEEDED;
+
+        ret = InitHandshakeHashes(ssl);
+        if (ret != 0)
+            return ret;
+    }
+#endif
+
+    /* sanity check msg received */
+    if ( (ret = SanityCheckMsgReceived(ssl, type)) != 0) {
+        WOLFSSL_MSG("Sanity Check on handshake message type received failed");
+        return ret;
+    }
+
+#if defined(WOLFSSL_CALLBACKS) || defined(OPENSSL_EXTRA)
+    /* add name later, add on record and handshake header part back on */
+    if (ssl->toInfoOn) {
+        int add = RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ;
+        AddPacketInfo(ssl, 0, handshake, input + *inOutIdx - add,
+                      size + add, READ_PROTO, ssl->heap);
+        #ifdef WOLFSSL_CALLBACKS
+        AddLateRecordHeader(&ssl->curRL, &ssl->timeoutInfo);
+        #endif
+    }
+#endif
+
+    if (ssl->options.handShakeState == HANDSHAKE_DONE && type != hello_request){
+        WOLFSSL_MSG("HandShake message after handshake complete");
+        SendAlert(ssl, alert_fatal, unexpected_message);
+        return OUT_OF_ORDER_E;
+    }
+
+    if (ssl->options.side == WOLFSSL_CLIENT_END && ssl->options.dtls == 0 &&
+               ssl->options.serverState == NULL_STATE && type != server_hello) {
+        WOLFSSL_MSG("First server message not server hello");
+        SendAlert(ssl, alert_fatal, unexpected_message);
+        return OUT_OF_ORDER_E;
+    }
+
+    if (ssl->options.side == WOLFSSL_CLIENT_END && ssl->options.dtls &&
+            type == server_hello_done &&
+            ssl->options.serverState < SERVER_HELLO_COMPLETE) {
+        WOLFSSL_MSG("Server hello done received before server hello in DTLS");
+        SendAlert(ssl, alert_fatal, unexpected_message);
+        return OUT_OF_ORDER_E;
+    }
+
+    if (ssl->options.side == WOLFSSL_SERVER_END &&
+               ssl->options.clientState == NULL_STATE && type != client_hello) {
+        WOLFSSL_MSG("First client message not client hello");
+        SendAlert(ssl, alert_fatal, unexpected_message);
+        return OUT_OF_ORDER_E;
+    }
+
+    /* above checks handshake state */
+    /* hello_request not hashed */
+    /* Also, skip hashing the client_hello message here for DTLS. It will be
+     * hashed later if the DTLS cookie is correct. */
+    if (type != hello_request &&
+            !(IsDtlsNotSctpMode(ssl) && type == client_hello)
+    #ifdef WOLFSSL_ASYNC_CRYPT
+            && ssl->error != WC_PENDING_E
+    #endif
+    #ifdef WOLFSSL_NONBLOCK_OCSP
+            && ssl->error != OCSP_WANT_READ
+    #endif
+    ) {
+        ret = HashInput(ssl, input + *inOutIdx, size);
+        if (ret != 0) {
+            WOLFSSL_MSG("Incomplete handshake hashes");
+            return ret;
+        }
+    }
+
+#ifdef OPENSSL_EXTRA
+    if (ssl->CBIS != NULL){
+        ssl->cbmode = SSL_CB_MODE_READ;
+        ssl->cbtype = type;
+        ssl->CBIS(ssl, SSL_CB_ACCEPT_LOOP, SSL_SUCCESS);
+    }
+#endif
+
+    switch (type) {
+
+    case hello_request:
+        WOLFSSL_MSG("processing hello request");
+        ret = DoHelloRequest(ssl, input, inOutIdx, size, totalSz);
+        break;
+
+#ifndef NO_WOLFSSL_CLIENT
+    case hello_verify_request:
+        WOLFSSL_MSG("processing hello verify request");
+        ret = DoHelloVerifyRequest(ssl, input,inOutIdx, size);
+        break;
+
+    case server_hello:
+        WOLFSSL_MSG("processing server hello");
+        ret = DoServerHello(ssl, input, inOutIdx, size);
+    #if !defined(WOLFSSL_NO_CLIENT_AUTH) && \
+               ((defined(HAVE_ED25519) && !defined(NO_ED25519_CLIENT_AUTH)) || \
+                (defined(HAVE_ED448) && !defined(NO_ED448_CLIENT_AUTH)))
+        if (ssl->options.resuming || !IsAtLeastTLSv1_2(ssl) ||
+                                               IsAtLeastTLSv1_3(ssl->version)) {
+
+        #if defined(WOLFSSL_ASYNC_CRYPT) || defined(WOLFSSL_NONBLOCK_OCSP)
+            if (ret != WC_PENDING_E && ret != OCSP_WANT_READ)
+        #endif
+            {
+                ssl->options.cacheMessages = 0;
+                if (ssl->hsHashes->messages != NULL) {
+                    XFREE(ssl->hsHashes->messages, ssl->heap,
+                        DYNAMIC_TYPE_HASHES);
+                    ssl->hsHashes->messages = NULL;
+                }
+            }
+        }
+    #endif
+        break;
+
+#ifndef NO_CERTS
+    case certificate_request:
+        WOLFSSL_MSG("processing certificate request");
+        ret = DoCertificateRequest(ssl, input, inOutIdx, size);
+        break;
+#endif
+
+    case server_key_exchange:
+        WOLFSSL_MSG("processing server key exchange");
+        ret = DoServerKeyExchange(ssl, input, inOutIdx, size);
+        break;
+
+#ifdef HAVE_SESSION_TICKET
+    case session_ticket:
+        WOLFSSL_MSG("processing session ticket");
+        ret = DoSessionTicket(ssl, input, inOutIdx, size);
+        break;
+#endif /* HAVE_SESSION_TICKET */
+#endif
+
+#if !defined(NO_CERTS) && (!defined(NO_WOLFSSL_CLIENT) || \
+                                               !defined(WOLFSSL_NO_CLIENT_AUTH))
+    case certificate:
+        WOLFSSL_MSG("processing certificate");
+        ret = DoCertificate(ssl, input, inOutIdx, size);
+        break;
+
+    case certificate_status:
+        WOLFSSL_MSG("processing certificate status");
+        ret = DoCertificateStatus(ssl, input, inOutIdx, size);
+        break;
+#endif
+
+    case server_hello_done:
+        WOLFSSL_MSG("processing server hello done");
+    #ifdef WOLFSSL_CALLBACKS
+        if (ssl->hsInfoOn)
+            AddPacketName(ssl, "ServerHelloDone");
+        if (ssl->toInfoOn)
+            AddLateName("ServerHelloDone", &ssl->timeoutInfo);
+    #endif
+        ssl->options.serverState = SERVER_HELLODONE_COMPLETE;
+        if (IsEncryptionOn(ssl, 0)) {
+            *inOutIdx += ssl->keys.padSz;
+        #if defined(HAVE_ENCRYPT_THEN_MAC) && !defined(WOLFSSL_AEAD_ONLY)
+            if (ssl->options.startedETMRead)
+                *inOutIdx += MacSize(ssl);
+        #endif
+        }
+        if (ssl->options.resuming) {
+            WOLFSSL_MSG("Not resuming as thought");
+            ssl->options.resuming = 0;
+        }
+        break;
+
+    case finished:
+        WOLFSSL_MSG("processing finished");
+        ret = DoFinished(ssl, input, inOutIdx, size, totalSz, NO_SNIFF);
+        break;
+
+#ifndef NO_WOLFSSL_SERVER
+    case client_hello:
+        WOLFSSL_MSG("processing client hello");
+        ret = DoClientHello(ssl, input, inOutIdx, size);
+    #if !defined(WOLFSSL_NO_CLIENT_AUTH) && \
+               ((defined(HAVE_ED25519) && !defined(NO_ED25519_CLIENT_AUTH)) || \
+                (defined(HAVE_ED448) && !defined(NO_ED448_CLIENT_AUTH)))
+        if (ssl->options.resuming || !ssl->options.verifyPeer || \
+                     !IsAtLeastTLSv1_2(ssl) || IsAtLeastTLSv1_3(ssl->version)) {
+        #if defined(WOLFSSL_ASYNC_CRYPT) || defined(WOLFSSL_NONBLOCK_OCSP)
+            if (ret != WC_PENDING_E && ret != OCSP_WANT_READ)
+        #endif
+            {
+                ssl->options.cacheMessages = 0;
+                if (ssl->hsHashes->messages != NULL) {
+                    XFREE(ssl->hsHashes->messages, ssl->heap, DYNAMIC_TYPE_HASHES);
+                    ssl->hsHashes->messages = NULL;
+                }
+            }
+        }
+    #endif
+        if (IsEncryptionOn(ssl, 0)) {
+        #if defined(HAVE_ENCRYPT_THEN_MAC) && !defined(WOLFSSL_AEAD_ONLY)
+            if (ssl->options.startedETMRead) {
+                word32 digestSz = MacSize(ssl);
+                if (*inOutIdx + ssl->keys.padSz + digestSz > totalSz)
+                    return BUFFER_E;
+                *inOutIdx += ssl->keys.padSz + digestSz;
+            }
+            else
+        #endif
+            {
+                /* access beyond input + size should be checked against totalSz
+                 */
+                if (*inOutIdx + ssl->keys.padSz > totalSz)
+                    return BUFFER_E;
+
+                *inOutIdx += ssl->keys.padSz;
+            }
+        }
+        break;
+
+    case client_key_exchange:
+        WOLFSSL_MSG("processing client key exchange");
+        ret = DoClientKeyExchange(ssl, input, inOutIdx, size);
+        break;
+
+#if (!defined(NO_RSA) || defined(HAVE_ECC) || defined(HAVE_ED25519) || \
+                        defined(HAVE_ED448)) && !defined(WOLFSSL_NO_CLIENT_AUTH)
+    case certificate_verify:
+        WOLFSSL_MSG("processing certificate verify");
+        ret = DoCertificateVerify(ssl, input, inOutIdx, size);
+        break;
+#endif /* (!NO_RSA || ECC || ED25519 || ED448) && !WOLFSSL_NO_CLIENT_AUTH */
+
+#endif /* !NO_WOLFSSL_SERVER */
+
+    default:
+        WOLFSSL_MSG("Unknown handshake message type");
+        ret = UNKNOWN_HANDSHAKE_TYPE;
+        break;
+    }
+    if (ret == 0 && expectedIdx != *inOutIdx) {
+        WOLFSSL_MSG("Extra data in handshake message");
+        if (!ssl->options.dtls)
+            SendAlert(ssl, alert_fatal, decode_error);
+        ret = DECODE_E;
+    }
+
+    if (ret == 0 && ssl->buffers.inputBuffer.dynamicFlag
+    #if defined(WOLFSSL_ASYNC_CRYPT) || defined(WOLFSSL_NONBLOCK_OCSP)
+        /* do not shrink input for async or non-block */
+        && ssl->error != WC_PENDING_E && ssl->error != OCSP_WANT_READ
+    #endif
+    ) {
+        ShrinkInputBuffer(ssl, NO_FORCED_FREE);
+    }
+
+#if defined(WOLFSSL_ASYNC_CRYPT) || defined(WOLFSSL_NONBLOCK_OCSP)
+    /* if async, offset index so this msg will be processed again */
+    if ((ret == WC_PENDING_E || ret == OCSP_WANT_READ) && *inOutIdx > 0) {
+        *inOutIdx -= HANDSHAKE_HEADER_SZ;
+    #ifdef WOLFSSL_DTLS
+        if (ssl->options.dtls) {
+            *inOutIdx -= DTLS_HANDSHAKE_EXTRA;
+        }
+    #endif
+    }
+
+    /* make sure async error is cleared */
+    if (ret == 0 && (ssl->error == WC_PENDING_E || ssl->error == OCSP_WANT_READ)) {
+        ssl->error = 0;
+    }
+#endif /* WOLFSSL_ASYNC_CRYPT || WOLFSSL_NONBLOCK_OCSP */
+
+    WOLFSSL_LEAVE("DoHandShakeMsgType()", ret);
+    return ret;
+}
+
+
+static int DoHandShakeMsg(WOLFSSL* ssl, byte* input, word32* inOutIdx,
+                          word32 totalSz)
+{
+    int    ret = 0;
+    word32 inputLength;
+
+    WOLFSSL_ENTER("DoHandShakeMsg()");
+
+    if (ssl->arrays == NULL) {
+        byte   type;
+        word32 size;
+
+        if (GetHandShakeHeader(ssl,input,inOutIdx,&type, &size, totalSz) != 0)
+            return PARSE_ERROR;
+
+        ssl->options.handShakeState = type;
+
+        return DoHandShakeMsgType(ssl, input, inOutIdx, type, size, totalSz);
+    }
+
+    inputLength = ssl->buffers.inputBuffer.length - *inOutIdx;
+
+    /* If there is a pending fragmented handshake message,
+     * pending message size will be non-zero. */
+    if (ssl->arrays->pendingMsgSz == 0) {
+        byte   type;
+        word32 size;
+
+        if (GetHandShakeHeader(ssl,input, inOutIdx, &type, &size, totalSz) != 0)
+            return PARSE_ERROR;
+
+        /* Cap the maximum size of a handshake message to something reasonable.
+         * By default is the maximum size of a certificate message assuming
+         * nine 2048-bit RSA certificates in the chain. */
+        if (size > MAX_HANDSHAKE_SZ) {
+            WOLFSSL_MSG("Handshake message too large");
+            return HANDSHAKE_SIZE_ERROR;
+        }
+
+        /* size is the size of the certificate message payload */
+        if (inputLength - HANDSHAKE_HEADER_SZ < size) {
+            ssl->arrays->pendingMsgType = type;
+            ssl->arrays->pendingMsgSz = size + HANDSHAKE_HEADER_SZ;
+            ssl->arrays->pendingMsg = (byte*)XMALLOC(size + HANDSHAKE_HEADER_SZ,
+                                                     ssl->heap,
+                                                     DYNAMIC_TYPE_ARRAYS);
+            if (ssl->arrays->pendingMsg == NULL)
+                return MEMORY_E;
+            XMEMCPY(ssl->arrays->pendingMsg,
+                    input + *inOutIdx - HANDSHAKE_HEADER_SZ,
+                    inputLength);
+            ssl->arrays->pendingMsgOffset = inputLength;
+            *inOutIdx += inputLength - HANDSHAKE_HEADER_SZ;
+            return 0;
+        }
+
+        ret = DoHandShakeMsgType(ssl, input, inOutIdx, type, size, totalSz);
+    }
+    else {
+        word32 pendSz =
+            ssl->arrays->pendingMsgSz - ssl->arrays->pendingMsgOffset;
+
+        /* Catch the case where there may be the remainder of a fragmented
+         * handshake message and the next handshake message in the same
+         * record. */
+        if (inputLength > pendSz)
+            inputLength = pendSz;
+
+        XMEMCPY(ssl->arrays->pendingMsg + ssl->arrays->pendingMsgOffset,
+                input + *inOutIdx, inputLength);
+        ssl->arrays->pendingMsgOffset += inputLength;
+        *inOutIdx += inputLength;
+
+        if (ssl->arrays->pendingMsgOffset == ssl->arrays->pendingMsgSz)
+        {
+            word32 idx = HANDSHAKE_HEADER_SZ;
+            ret = DoHandShakeMsgType(ssl,
+                                     ssl->arrays->pendingMsg,
+                                     &idx, ssl->arrays->pendingMsgType,
+                                     ssl->arrays->pendingMsgSz - idx,
+                                     ssl->arrays->pendingMsgSz);
+        #ifdef WOLFSSL_ASYNC_CRYPT
+            if (ret == WC_PENDING_E) {
+                /* setup to process fragment again */
+                ssl->arrays->pendingMsgOffset -= inputLength;
+                *inOutIdx -= inputLength;
+            }
+            else
+        #endif
+            {
+                XFREE(ssl->arrays->pendingMsg, ssl->heap, DYNAMIC_TYPE_ARRAYS);
+                ssl->arrays->pendingMsg = NULL;
+                ssl->arrays->pendingMsgSz = 0;
+            }
+        }
+    }
+
+    WOLFSSL_LEAVE("DoHandShakeMsg()", ret);
+    return ret;
+}
+
+#endif /* !WOLFSSL_NO_TLS12 */
+
+#ifdef WOLFSSL_DTLS
+
+static WC_INLINE int DtlsCheckWindow(WOLFSSL* ssl)
+{
+    word32* window;
+    word16 cur_hi, next_hi;
+    word32 cur_lo, next_lo, diff;
+    int curLT;
+    WOLFSSL_DTLS_PEERSEQ* peerSeq = NULL;
+
+    if (!ssl->options.haveMcast)
+        peerSeq = ssl->keys.peerSeq;
+    else {
+#ifdef WOLFSSL_MULTICAST
+        WOLFSSL_DTLS_PEERSEQ* p;
+        int i;
+
+        for (i = 0, p = ssl->keys.peerSeq;
+             i < WOLFSSL_DTLS_PEERSEQ_SZ;
+             i++, p++) {
+
+            if (p->peerId == ssl->keys.curPeerId) {
+                peerSeq = p;
+                break;
+            }
+        }
+#endif
+    }
+
+    if (peerSeq == NULL) {
+        WOLFSSL_MSG("Could not find peer sequence");
+        return 0;
+    }
+
+    if (ssl->keys.curEpoch == peerSeq->nextEpoch) {
+        next_hi = peerSeq->nextSeq_hi;
+        next_lo = peerSeq->nextSeq_lo;
+        window = peerSeq->window;
+    }
+    else if (ssl->keys.curEpoch == peerSeq->nextEpoch - 1) {
+        next_hi = peerSeq->prevSeq_hi;
+        next_lo = peerSeq->prevSeq_lo;
+        window = peerSeq->prevWindow;
+    }
+    else {
+        return 0;
+    }
+
+    cur_hi = ssl->keys.curSeq_hi;
+    cur_lo = ssl->keys.curSeq_lo;
+
+    /* If the difference between next and cur is > 2^32, way outside window. */
+    if ((cur_hi > next_hi + 1) || (next_hi > cur_hi + 1)) {
+        WOLFSSL_MSG("Current record from way too far in the future.");
+        return 0;
+    }
+
+    if (cur_hi == next_hi) {
+        curLT = cur_lo < next_lo;
+        diff = curLT ? next_lo - cur_lo : cur_lo - next_lo;
+    }
+    else {
+        curLT = cur_hi < next_hi;
+        diff = curLT ? cur_lo - next_lo : next_lo - cur_lo;
+    }
+
+    /* Check to see that the next value is greater than the number of messages
+     * trackable in the window, and that the difference between the next
+     * expected sequence number and the received sequence number is inside the
+     * window. */
+    if ((next_hi || next_lo > DTLS_SEQ_BITS) &&
+        curLT && (diff > DTLS_SEQ_BITS)) {
+
+        WOLFSSL_MSG("Current record sequence number from the past.");
+        return 0;
+    }
+#ifndef WOLFSSL_DTLS_ALLOW_FUTURE
+    else if (!curLT && (diff > DTLS_SEQ_BITS)) {
+        WOLFSSL_MSG("Rejecting message too far into the future.");
+        return 0;
+    }
+#endif
+    else if (curLT) {
+        word32 idx = diff / DTLS_WORD_BITS;
+        word32 newDiff = diff % DTLS_WORD_BITS;
+
+        /* verify idx is valid for window array */
+        if (idx >= WOLFSSL_DTLS_WINDOW_WORDS) {
+            WOLFSSL_MSG("Invalid DTLS windows index");
+            return 0;
+        }
+
+        if (window[idx] & (1 << newDiff)) {
+            WOLFSSL_MSG("Current record sequence number already received.");
+            return 0;
+        }
+    }
+
+    return 1;
+}
+
+
+#ifdef WOLFSSL_MULTICAST
+static WC_INLINE word32 UpdateHighwaterMark(word32 cur, word32 first,
+                                         word32 second, word32 max)
+{
+    word32 newCur = 0;
+
+    if (cur < first)
+        newCur = first;
+    else if (cur < second)
+        newCur = second;
+    else if (cur < max)
+        newCur = max;
+
+    return newCur;
+}
+#endif /* WOLFSSL_MULTICAST */
+
+
+static WC_INLINE int DtlsUpdateWindow(WOLFSSL* ssl)
+{
+    word32* window;
+    word32* next_lo;
+    word16* next_hi;
+    int curLT;
+    word32 cur_lo, diff;
+    word16 cur_hi;
+    WOLFSSL_DTLS_PEERSEQ* peerSeq = ssl->keys.peerSeq;
+
+    cur_hi = ssl->keys.curSeq_hi;
+    cur_lo = ssl->keys.curSeq_lo;
+
+#ifdef WOLFSSL_MULTICAST
+    if (ssl->options.haveMcast) {
+        WOLFSSL_DTLS_PEERSEQ* p;
+        int i;
+
+        peerSeq = NULL;
+        for (i = 0, p = ssl->keys.peerSeq;
+             i < WOLFSSL_DTLS_PEERSEQ_SZ;
+             i++, p++) {
+
+            if (p->peerId == ssl->keys.curPeerId) {
+                peerSeq = p;
+                break;
+            }
+        }
+
+        if (peerSeq == NULL) {
+            WOLFSSL_MSG("Couldn't find that peer ID to update window.");
+            return 0;
+        }
+
+        if (p->highwaterMark && cur_lo >= p->highwaterMark) {
+            int cbError = 0;
+
+            if (ssl->ctx->mcastHwCb)
+                cbError = ssl->ctx->mcastHwCb(p->peerId,
+                                              ssl->ctx->mcastMaxSeq,
+                                              cur_lo, ssl->mcastHwCbCtx);
+            if (cbError) {
+                WOLFSSL_MSG("Multicast highwater callback returned an error.");
+                return MCAST_HIGHWATER_CB_E;
+            }
+
+            p->highwaterMark = UpdateHighwaterMark(cur_lo,
+                                                   ssl->ctx->mcastFirstSeq,
+                                                   ssl->ctx->mcastSecondSeq,
+                                                   ssl->ctx->mcastMaxSeq);
+        }
+    }
+#endif
+
+    if (ssl->keys.curEpoch == peerSeq->nextEpoch) {
+        next_hi = &peerSeq->nextSeq_hi;
+        next_lo = &peerSeq->nextSeq_lo;
+        window = peerSeq->window;
+    }
+    else {
+        next_hi = &peerSeq->prevSeq_hi;
+        next_lo = &peerSeq->prevSeq_lo;
+        window = peerSeq->prevWindow;
+    }
+
+    if (cur_hi == *next_hi) {
+        curLT = cur_lo < *next_lo;
+        diff = curLT ? *next_lo - cur_lo : cur_lo - *next_lo;
+    }
+    else {
+        curLT = cur_hi < *next_hi;
+        diff = curLT ? cur_lo - *next_lo : *next_lo - cur_lo;
+    }
+
+    if (curLT) {
+        word32 idx = diff / DTLS_WORD_BITS;
+        word32 newDiff = diff % DTLS_WORD_BITS;
+
+        if (idx < WOLFSSL_DTLS_WINDOW_WORDS)
+            window[idx] |= (1 << newDiff);
+    }
+    else {
+        if (diff >= DTLS_SEQ_BITS)
+            XMEMSET(window, 0, DTLS_SEQ_SZ);
+        else {
+            word32 idx, newDiff, temp, i;
+            word32 oldWindow[WOLFSSL_DTLS_WINDOW_WORDS];
+
+            temp = 0;
+            diff++;
+            idx = diff / DTLS_WORD_BITS;
+            newDiff = diff % DTLS_WORD_BITS;
+
+            XMEMCPY(oldWindow, window, sizeof(oldWindow));
+
+            for (i = 0; i < WOLFSSL_DTLS_WINDOW_WORDS; i++) {
+                if (i < idx)
+                    window[i] = 0;
+                else {
+                    temp |= (oldWindow[i-idx] << newDiff);
+                    window[i] = temp;
+                    temp = oldWindow[i-idx] >> (DTLS_WORD_BITS - newDiff - 1);
+                }
+            }
+        }
+        window[0] |= 1;
+        *next_lo = cur_lo + 1;
+        if (*next_lo < cur_lo)
+            (*next_hi)++;
+    }
+
+    return 1;
+}
+
+
+static int DtlsMsgDrain(WOLFSSL* ssl)
+{
+    DtlsMsg* item = ssl->dtls_rx_msg_list;
+    int ret = 0;
+
+    WOLFSSL_ENTER("DtlsMsgDrain()");
+
+    /* While there is an item in the store list, and it is the expected
+     * message, and it is complete, and there hasn't been an error in the
+     * last message... */
+    while (item != NULL &&
+            ssl->keys.dtls_expected_peer_handshake_number == item->seq &&
+            item->fragSz == item->sz &&
+            ret == 0) {
+        word32 idx = 0;
+        ssl->keys.dtls_expected_peer_handshake_number++;
+        ret = DoHandShakeMsgType(ssl, item->msg,
+                                 &idx, item->type, item->sz, item->sz);
+    #ifdef WOLFSSL_ASYNC_CRYPT
+        if (ret == WC_PENDING_E) {
+            ssl->keys.dtls_expected_peer_handshake_number--;
+            break;
+        }
+    #endif
+        ssl->dtls_rx_msg_list = item->next;
+        DtlsMsgDelete(item, ssl->heap);
+        item = ssl->dtls_rx_msg_list;
+        ssl->dtls_rx_msg_list_sz--;
+    }
+
+    WOLFSSL_LEAVE("DtlsMsgDrain()", ret);
+    return ret;
+}
+
+
+static int DoDtlsHandShakeMsg(WOLFSSL* ssl, byte* input, word32* inOutIdx,
+                          word32 totalSz)
+{
+    byte type;
+    word32 size;
+    word32 fragOffset, fragSz;
+    int ret = 0;
+
+    WOLFSSL_ENTER("DoDtlsHandShakeMsg()");
+
+    /* process any pending DTLS messages - this flow can happen with async */
+    if (ssl->dtls_rx_msg_list != NULL) {
+        ret = DtlsMsgDrain(ssl);
+        if (ret != 0)
+            return ret;
+
+        /* if done processing fragment exit with success */
+        if (totalSz == *inOutIdx)
+            return ret;
+    }
+
+    /* parse header */
+    if (GetDtlsHandShakeHeader(ssl, input, inOutIdx, &type,
+                               &size, &fragOffset, &fragSz, totalSz) != 0) {
+        WOLFSSL_ERROR(PARSE_ERROR);
+        return PARSE_ERROR;
+    }
+
+    /* Cap the maximum size of a handshake message to something reasonable.
+     * By default is the maximum size of a certificate message assuming
+     * nine 2048-bit RSA certificates in the chain. */
+    if (size > MAX_HANDSHAKE_SZ) {
+        WOLFSSL_MSG("Handshake message too large");
+        return HANDSHAKE_SIZE_ERROR;
+    }
+
+    /* check that we have complete fragment */
+    if (*inOutIdx + fragSz > totalSz) {
+        WOLFSSL_ERROR(INCOMPLETE_DATA);
+        return INCOMPLETE_DATA;
+    }
+
+    /* Check the handshake sequence number first. If out of order,
+     * add the current message to the list. If the message is in order,
+     * but it is a fragment, add the current message to the list, then
+     * check the head of the list to see if it is complete, if so, pop
+     * it out as the current message. If the message is complete and in
+     * order, process it. Check the head of the list to see if it is in
+     * order, if so, process it. (Repeat until list exhausted.) If the
+     * head is out of order, return for more processing.
+     */
+    if (ssl->keys.dtls_peer_handshake_number >
+                                ssl->keys.dtls_expected_peer_handshake_number) {
+        /* Current message is out of order. It will get stored in the list.
+         * Storing also takes care of defragmentation. If the messages is a
+         * client hello, we need to process this out of order; the server
+         * is not supposed to keep state, but the second client hello will
+         * have a different handshake sequence number than is expected, and
+         * the server shouldn't be expecting any particular handshake sequence
+         * number. (If the cookie changes multiple times in quick succession,
+         * the client could be sending multiple new client hello messages
+         * with newer and newer cookies.) */
+        if (type != client_hello) {
+            if (ssl->dtls_rx_msg_list_sz < DTLS_POOL_SZ) {
+                DtlsMsgStore(ssl, ssl->keys.dtls_peer_handshake_number,
+                             input + *inOutIdx, size, type,
+                             fragOffset, fragSz, ssl->heap);
+            }
+            *inOutIdx += fragSz;
+            ret = 0;
+        }
+        else {
+            ret = DoHandShakeMsgType(ssl, input, inOutIdx, type, size, totalSz);
+            if (ret == 0) {
+                ssl->keys.dtls_expected_peer_handshake_number =
+                    ssl->keys.dtls_peer_handshake_number + 1;
+            }
+        }
+    }
+    else if (ssl->keys.dtls_peer_handshake_number <
+                                ssl->keys.dtls_expected_peer_handshake_number) {
+        /* Already saw this message and processed it. It can be ignored. */
+        *inOutIdx += fragSz;
+        if(type == finished ) {
+        #if defined(HAVE_ENCRYPT_THEN_MAC) && !defined(WOLFSSL_AEAD_ONLY)
+            if (ssl->options.startedETMRead) {
+                word32 digestSz = MacSize(ssl);
+                if (*inOutIdx + ssl->keys.padSz + digestSz > totalSz)
+                    return BUFFER_E;
+                *inOutIdx += ssl->keys.padSz + digestSz;
+            }
+            else
+        #endif
+            {
+                if (*inOutIdx + ssl->keys.padSz > totalSz) {
+                    WOLFSSL_ERROR(BUFFER_E);
+                    return BUFFER_E;
+                }
+                *inOutIdx += ssl->keys.padSz;
+            }
+        }
+        if (IsDtlsNotSctpMode(ssl) &&
+            VerifyForDtlsMsgPoolSend(ssl, type, fragOffset)) {
+
+            ret = DtlsMsgPoolSend(ssl, 0);
+        }
+    }
+    else if (fragSz < size) {
+        /* Since this branch is in order, but fragmented, dtls_rx_msg_list will
+         * be pointing to the message with this fragment in it. Check it to see
+         * if it is completed. */
+        if (ssl->dtls_rx_msg_list_sz < DTLS_POOL_SZ) {
+            DtlsMsgStore(ssl, ssl->keys.dtls_peer_handshake_number,
+                         input + *inOutIdx, size, type,
+                         fragOffset, fragSz, ssl->heap);
+        }
+        *inOutIdx += fragSz;
+        ret = 0;
+        if (ssl->dtls_rx_msg_list != NULL &&
+            ssl->dtls_rx_msg_list->fragSz >= ssl->dtls_rx_msg_list->sz)
+            ret = DtlsMsgDrain(ssl);
+    }
+    else {
+        /* This branch is in order next, and a complete message. */
+        ret = DoHandShakeMsgType(ssl, input, inOutIdx, type, size, totalSz);
+        if (ret == 0) {
+            if (type != client_hello || !IsDtlsNotSctpMode(ssl))
+                ssl->keys.dtls_expected_peer_handshake_number++;
+            if (ssl->dtls_rx_msg_list != NULL) {
+                ret = DtlsMsgDrain(ssl);
+            }
+        }
+    }
+
+    WOLFSSL_LEAVE("DoDtlsHandShakeMsg()", ret);
+    return ret;
+}
+#endif
+
+#ifndef WOLFSSL_NO_TLS12
+
+#ifdef HAVE_AEAD
+
+#if !defined(NO_PUBLIC_GCM_SET_IV) && \
+    (((defined(HAVE_FIPS) || defined(HAVE_SELFTEST)) && \
+    (!defined(HAVE_FIPS_VERSION) || (HAVE_FIPS_VERSION < 2))) || \
+    (defined(HAVE_POLY1305) && defined(HAVE_CHACHA)))
+static WC_INLINE void AeadIncrementExpIV(WOLFSSL* ssl)
+{
+    int i;
+    for (i = AEAD_MAX_EXP_SZ-1; i >= 0; i--) {
+        if (++ssl->keys.aead_exp_IV[i]) return;
+    }
+}
+#endif
+
+
+#if defined(HAVE_POLY1305) && defined(HAVE_CHACHA)
+/* Used for the older version of creating AEAD tags with Poly1305 */
+static int Poly1305TagOld(WOLFSSL* ssl, byte* additional, const byte* out,
+                       byte* cipher, word16 sz, byte* tag)
+{
+    int ret       = 0;
+    int msglen    = (sz - ssl->specs.aead_mac_size);
+    word32 keySz  = 32;
+    byte padding[8]; /* used to temporarily store lengths */
+
+#ifdef CHACHA_AEAD_TEST
+      printf("Using old version of poly1305 input.\n");
+#endif
+
+    if (msglen < 0)
+        return INPUT_CASE_ERROR;
+
+    if ((ret = wc_Poly1305SetKey(ssl->auth.poly1305, cipher, keySz)) != 0)
+        return ret;
+
+    if ((ret = wc_Poly1305Update(ssl->auth.poly1305, additional,
+                   AEAD_AUTH_DATA_SZ)) != 0)
+        return ret;
+
+    /* length of additional input plus padding */
+    XMEMSET(padding, 0, sizeof(padding));
+    padding[0] = AEAD_AUTH_DATA_SZ;
+    if ((ret = wc_Poly1305Update(ssl->auth.poly1305, padding,
+                    sizeof(padding))) != 0)
+        return ret;
+
+
+    /* add cipher info and then its length */
+    XMEMSET(padding, 0, sizeof(padding));
+    if ((ret = wc_Poly1305Update(ssl->auth.poly1305, out, msglen)) != 0)
+        return ret;
+
+    /* 32 bit size of cipher to 64 bit endian */
+    padding[0] =  msglen        & 0xff;
+    padding[1] = (msglen >>  8) & 0xff;
+    padding[2] = ((word32)msglen >> 16) & 0xff;
+    padding[3] = ((word32)msglen >> 24) & 0xff;
+    if ((ret = wc_Poly1305Update(ssl->auth.poly1305, padding, sizeof(padding)))
+        != 0)
+        return ret;
+
+    /* generate tag */
+    if ((ret = wc_Poly1305Final(ssl->auth.poly1305, tag)) != 0)
+        return ret;
+
+    return ret;
+}
+
+
+/* When the flag oldPoly is not set this follows RFC7905. When oldPoly is set
+ * the implementation follows an older draft for creating the nonce and MAC.
+ * The flag oldPoly gets set automatically depending on what cipher suite was
+ * negotiated in the handshake. This is able to be done because the IDs for the
+ * cipher suites was updated in RFC7905 giving unique values for the older
+ * draft in comparison to the more recent RFC.
+ *
+ * ssl   WOLFSSL structure to get cipher and TLS state from
+ * out   output buffer to hold encrypted data
+ * input data to encrypt
+ * sz    size of input
+ *
+ * Return 0 on success negative values in error case
+ */
+static int  ChachaAEADEncrypt(WOLFSSL* ssl, byte* out, const byte* input,
+                              word16 sz)
+{
+    const byte* additionalSrc = input - RECORD_HEADER_SZ;
+    int ret       = 0;
+    word32 msgLen = (sz - ssl->specs.aead_mac_size);
+    byte tag[POLY1305_AUTH_SZ];
+    byte add[AEAD_AUTH_DATA_SZ];
+    byte nonce[CHACHA20_NONCE_SZ];
+    byte poly[CHACHA20_256_KEY_SIZE]; /* generated key for poly1305 */
+    #ifdef CHACHA_AEAD_TEST
+        int i;
+    #endif
+
+    XMEMSET(tag,   0, sizeof(tag));
+    XMEMSET(nonce, 0, sizeof(nonce));
+    XMEMSET(poly,  0, sizeof(poly));
+    XMEMSET(add,   0, sizeof(add));
+
+    /* opaque SEQ number stored for AD */
+    WriteSEQ(ssl, CUR_ORDER, add);
+
+    if (ssl->options.oldPoly != 0) {
+        /* get nonce. SEQ should not be incremented again here */
+        XMEMCPY(nonce + CHACHA20_OLD_OFFSET, add, OPAQUE32_LEN * 2);
+    }
+
+    /* Store the type, version. Unfortunately, they are in
+     * the input buffer ahead of the plaintext. */
+    #ifdef WOLFSSL_DTLS
+        if (ssl->options.dtls) {
+            additionalSrc -= DTLS_HANDSHAKE_EXTRA;
+        }
+    #endif
+
+    /* add TLS message size to additional data */
+    add[AEAD_AUTH_DATA_SZ - 2] = (msgLen >> 8) & 0xff;
+    add[AEAD_AUTH_DATA_SZ - 1] =  msgLen       & 0xff;
+
+    XMEMCPY(add + AEAD_TYPE_OFFSET, additionalSrc, 3);
+
+    #ifdef CHACHA_AEAD_TEST
+        printf("Encrypt Additional : ");
+        for (i = 0; i < AEAD_AUTH_DATA_SZ; i++) {
+            printf("%02x", add[i]);
+        }
+        printf("\n\n");
+        printf("input before encryption :\n");
+        for (i = 0; i < sz; i++) {
+            printf("%02x", input[i]);
+            if ((i + 1) % 16 == 0)
+                printf("\n");
+        }
+        printf("\n");
+    #endif
+
+    if (ssl->options.oldPoly == 0) {
+        /* nonce is formed by 4 0x00 byte padded to the left followed by 8 byte
+         * record sequence number XORed with client_write_IV/server_write_IV */
+        XMEMCPY(nonce, ssl->keys.aead_enc_imp_IV, CHACHA20_IMP_IV_SZ);
+        nonce[4]  ^= add[0];
+        nonce[5]  ^= add[1];
+        nonce[6]  ^= add[2];
+        nonce[7]  ^= add[3];
+        nonce[8]  ^= add[4];
+        nonce[9]  ^= add[5];
+        nonce[10] ^= add[6];
+        nonce[11] ^= add[7];
+    }
+
+    /* set the nonce for chacha and get poly1305 key */
+    if ((ret = wc_Chacha_SetIV(ssl->encrypt.chacha, nonce, 0)) != 0) {
+        ForceZero(nonce, CHACHA20_NONCE_SZ);
+        return ret;
+    }
+
+    /* create Poly1305 key using chacha20 keystream */
+    if ((ret = wc_Chacha_Process(ssl->encrypt.chacha, poly,
+                                                    poly, sizeof(poly))) != 0) {
+        ForceZero(nonce, CHACHA20_NONCE_SZ);
+        return ret;
+    }
+
+    /* set the counter after getting poly1305 key */
+    if ((ret = wc_Chacha_SetIV(ssl->encrypt.chacha, nonce, 1)) != 0) {
+        ForceZero(nonce, CHACHA20_NONCE_SZ);
+        return ret;
+    }
+    ForceZero(nonce, CHACHA20_NONCE_SZ); /* done with nonce, clear it */
+
+    /* encrypt the plain text */
+    if ((ret = wc_Chacha_Process(ssl->encrypt.chacha, out,
+                                                         input, msgLen)) != 0) {
+        ForceZero(poly, sizeof(poly));
+        return ret;
+    }
+
+    /* get the poly1305 tag using either old padding scheme or more recent */
+    if (ssl->options.oldPoly != 0) {
+        if ((ret = Poly1305TagOld(ssl, add, (const byte* )out,
+                                                         poly, sz, tag)) != 0) {
+            ForceZero(poly, sizeof(poly));
+            return ret;
+        }
+    }
+    else {
+        if ((ret = wc_Poly1305SetKey(ssl->auth.poly1305, poly,
+                                                          sizeof(poly))) != 0) {
+            ForceZero(poly, sizeof(poly));
+            return ret;
+        }
+        if ((ret = wc_Poly1305_MAC(ssl->auth.poly1305, add,
+                            sizeof(add), out, msgLen, tag, sizeof(tag))) != 0) {
+            ForceZero(poly, sizeof(poly));
+            return ret;
+        }
+    }
+    ForceZero(poly, sizeof(poly)); /* done with poly1305 key, clear it */
+
+    /* append tag to ciphertext */
+    XMEMCPY(out + msgLen, tag, sizeof(tag));
+
+    AeadIncrementExpIV(ssl);
+
+    #ifdef CHACHA_AEAD_TEST
+       printf("mac tag :\n");
+        for (i = 0; i < 16; i++) {
+           printf("%02x", tag[i]);
+           if ((i + 1) % 16 == 0)
+               printf("\n");
+        }
+       printf("\n\noutput after encrypt :\n");
+        for (i = 0; i < sz; i++) {
+           printf("%02x", out[i]);
+           if ((i + 1) % 16 == 0)
+               printf("\n");
+        }
+        printf("\n");
+    #endif
+
+    return ret;
+}
+
+
+/* When the flag oldPoly is not set this follows RFC7905. When oldPoly is set
+ * the implementation follows an older draft for creating the nonce and MAC.
+ * The flag oldPoly gets set automatically depending on what cipher suite was
+ * negotiated in the handshake. This is able to be done because the IDs for the
+ * cipher suites was updated in RFC7905 giving unique values for the older
+ * draft in comparison to the more recent RFC.
+ *
+ * ssl   WOLFSSL structure to get cipher and TLS state from
+ * plain output buffer to hold decrypted data
+ * input data to decrypt
+ * sz    size of input
+ *
+ * Return 0 on success negative values in error case
+ */
+static int ChachaAEADDecrypt(WOLFSSL* ssl, byte* plain, const byte* input,
+                           word16 sz)
+{
+    byte add[AEAD_AUTH_DATA_SZ];
+    byte nonce[CHACHA20_NONCE_SZ];
+    byte tag[POLY1305_AUTH_SZ];
+    byte poly[CHACHA20_256_KEY_SIZE]; /* generated key for mac */
+    int ret    = 0;
+    int msgLen = (sz - ssl->specs.aead_mac_size);
+
+    #ifdef CHACHA_AEAD_TEST
+       int i;
+       printf("input before decrypt :\n");
+        for (i = 0; i < sz; i++) {
+           printf("%02x", input[i]);
+           if ((i + 1) % 16 == 0)
+               printf("\n");
+        }
+        printf("\n");
+    #endif
+
+    XMEMSET(tag,   0, sizeof(tag));
+    XMEMSET(poly,  0, sizeof(poly));
+    XMEMSET(nonce, 0, sizeof(nonce));
+    XMEMSET(add,   0, sizeof(add));
+
+    /* sequence number field is 64-bits */
+    WriteSEQ(ssl, PEER_ORDER, add);
+
+    if (ssl->options.oldPoly != 0) {
+        /* get nonce, SEQ should not be incremented again here */
+        XMEMCPY(nonce + CHACHA20_OLD_OFFSET, add, OPAQUE32_LEN * 2);
+    }
+
+    /* get AD info */
+    /* Store the type, version. */
+    add[AEAD_TYPE_OFFSET] = ssl->curRL.type;
+    add[AEAD_VMAJ_OFFSET] = ssl->curRL.pvMajor;
+    add[AEAD_VMIN_OFFSET] = ssl->curRL.pvMinor;
+
+    /* add TLS message size to additional data */
+    add[AEAD_AUTH_DATA_SZ - 2] = (msgLen >> 8) & 0xff;
+    add[AEAD_AUTH_DATA_SZ - 1] =  msgLen       & 0xff;
+
+    #ifdef CHACHA_AEAD_TEST
+        printf("Decrypt Additional : ");
+        for (i = 0; i < AEAD_AUTH_DATA_SZ; i++) {
+            printf("%02x", add[i]);
+        }
+        printf("\n\n");
+    #endif
+
+    if (ssl->options.oldPoly == 0) {
+        /* nonce is formed by 4 0x00 byte padded to the left followed by 8 byte
+         * record sequence number XORed with client_write_IV/server_write_IV */
+        XMEMCPY(nonce, ssl->keys.aead_dec_imp_IV, CHACHA20_IMP_IV_SZ);
+        nonce[4]  ^= add[0];
+        nonce[5]  ^= add[1];
+        nonce[6]  ^= add[2];
+        nonce[7]  ^= add[3];
+        nonce[8]  ^= add[4];
+        nonce[9]  ^= add[5];
+        nonce[10] ^= add[6];
+        nonce[11] ^= add[7];
+    }
+
+    /* set nonce and get poly1305 key */
+    if ((ret = wc_Chacha_SetIV(ssl->decrypt.chacha, nonce, 0)) != 0) {
+        ForceZero(nonce, CHACHA20_NONCE_SZ);
+        return ret;
+    }
+
+    /* use chacha20 keystream to get poly1305 key for tag */
+    if ((ret = wc_Chacha_Process(ssl->decrypt.chacha, poly,
+                                                    poly, sizeof(poly))) != 0) {
+        ForceZero(nonce, CHACHA20_NONCE_SZ);
+        return ret;
+    }
+
+    /* set counter after getting poly1305 key */
+    if ((ret = wc_Chacha_SetIV(ssl->decrypt.chacha, nonce, 1)) != 0) {
+        ForceZero(nonce, CHACHA20_NONCE_SZ);
+        return ret;
+    }
+    ForceZero(nonce, CHACHA20_NONCE_SZ); /* done with nonce, clear it */
+
+    /* get the tag using Poly1305 */
+    if (ssl->options.oldPoly != 0) {
+        if ((ret = Poly1305TagOld(ssl, add, input, poly, sz, tag)) != 0) {
+            ForceZero(poly, sizeof(poly));
+            return ret;
+        }
+    }
+    else {
+        if ((ret = wc_Poly1305SetKey(ssl->auth.poly1305, poly,
+                                                          sizeof(poly))) != 0) {
+            ForceZero(poly, sizeof(poly));
+            return ret;
+        }
+        if ((ret = wc_Poly1305_MAC(ssl->auth.poly1305, add,
+                   sizeof(add), (byte*)input, msgLen, tag, sizeof(tag))) != 0) {
+            ForceZero(poly, sizeof(poly));
+            return ret;
+        }
+    }
+    ForceZero(poly, sizeof(poly)); /* done with poly1305 key, clear it */
+
+    /* check tag sent along with packet */
+    if (ConstantCompare(input + msgLen, tag, ssl->specs.aead_mac_size) != 0) {
+        WOLFSSL_MSG("MAC did not match");
+        if (!ssl->options.dtls)
+            SendAlert(ssl, alert_fatal, bad_record_mac);
+        return VERIFY_MAC_ERROR;
+    }
+
+    /* if the tag was good decrypt message */
+    if ((ret = wc_Chacha_Process(ssl->decrypt.chacha, plain,
+                                                           input, msgLen)) != 0)
+        return ret;
+
+    #ifdef CHACHA_AEAD_TEST
+       printf("plain after decrypt :\n");
+        for (i = 0; i < sz; i++) {
+           printf("%02x", plain[i]);
+           if ((i + 1) % 16 == 0)
+               printf("\n");
+        }
+        printf("\n");
+    #endif
+
+    return ret;
+}
+#endif /* HAVE_CHACHA && HAVE_POLY1305 */
+#endif /* HAVE_AEAD */
+
+
+#if defined(BUILD_AESGCM) || defined(HAVE_AESCCM)
+
+#if !defined(NO_GCM_ENCRYPT_EXTRA) && \
+    ((!defined(HAVE_FIPS) && !defined(HAVE_SELFTEST)) || \
+    (defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION >= 2)))
+/* The following type is used to share code between AES-GCM and AES-CCM. */
+    typedef int (*AesAuthEncryptFunc)(Aes* aes, byte* out,
+                                       const byte* in, word32 sz,
+                                       byte* iv, word32 ivSz,
+                                       byte* authTag, word32 authTagSz,
+                                       const byte* authIn, word32 authInSz);
+    #define AES_AUTH_ENCRYPT_FUNC AesAuthEncryptFunc
+    #define AES_GCM_ENCRYPT wc_AesGcmEncrypt_ex
+    #define AES_CCM_ENCRYPT wc_AesCcmEncrypt_ex
+#else
+    #define AES_AUTH_ENCRYPT_FUNC wc_AesAuthEncryptFunc
+    #define AES_GCM_ENCRYPT wc_AesGcmEncrypt
+    #define AES_CCM_ENCRYPT wc_AesCcmEncrypt
+#endif
+
+#endif
+
+
+static WC_INLINE int EncryptDo(WOLFSSL* ssl, byte* out, const byte* input,
+    word16 sz, int asyncOkay)
+{
+    int ret = 0;
+#ifdef WOLFSSL_ASYNC_CRYPT
+    WC_ASYNC_DEV* asyncDev = NULL;
+    word32 event_flags = WC_ASYNC_FLAG_CALL_AGAIN;
+#else
+    (void)asyncOkay;
+#endif
+
+    (void)out;
+    (void)input;
+    (void)sz;
+
+    switch (ssl->specs.bulk_cipher_algorithm) {
+    #ifdef BUILD_ARC4
+        case wolfssl_rc4:
+            wc_Arc4Process(ssl->encrypt.arc4, out, input, sz);
+            break;
+    #endif
+
+    #ifdef BUILD_DES3
+        case wolfssl_triple_des:
+        #ifdef WOLFSSL_ASYNC_CRYPT
+            /* initialize event */
+            asyncDev = &ssl->encrypt.des3->asyncDev;
+            ret = wolfSSL_AsyncInit(ssl, asyncDev, event_flags);
+            if (ret != 0)
+                break;
+        #endif
+
+            ret = wc_Des3_CbcEncrypt(ssl->encrypt.des3, out, input, sz);
+        #ifdef WOLFSSL_ASYNC_CRYPT
+            if (ret == WC_PENDING_E && asyncOkay) {
+                ret = wolfSSL_AsyncPush(ssl, asyncDev);
+            }
+        #endif
+            break;
+    #endif
+
+    #if defined(BUILD_AES) && defined(HAVE_AES_CBC)
+        case wolfssl_aes:
+        #ifdef WOLFSSL_ASYNC_CRYPT
+            /* initialize event */
+            asyncDev = &ssl->encrypt.aes->asyncDev;
+            ret = wolfSSL_AsyncInit(ssl, asyncDev, event_flags);
+            if (ret != 0)
+                break;
+        #endif
+        #if defined(WOLFSSL_RENESAS_TSIP_TLS) && \
+            !defined(NO_WOLFSSL_RENESAS_TSIP_TLS_SESSION)
+            if (tsip_useable(ssl)) {
+                ret = wc_tsip_AesCbcEncrypt(ssl->encrypt.aes, out, input, sz);
+            } else
+        #endif
+            ret = wc_AesCbcEncrypt(ssl->encrypt.aes, out, input, sz);
+        #ifdef WOLFSSL_ASYNC_CRYPT
+            if (ret == WC_PENDING_E && asyncOkay) {
+                ret = wolfSSL_AsyncPush(ssl, asyncDev);
+            }
+        #endif
+            break;
+    #endif
+
+    #if defined(BUILD_AESGCM) || defined(HAVE_AESCCM)
+        case wolfssl_aes_gcm:
+        case wolfssl_aes_ccm:/* GCM AEAD macros use same size as CCM */
+        {
+            AES_AUTH_ENCRYPT_FUNC aes_auth_fn;
+            const byte* additionalSrc;
+
+        #ifdef WOLFSSL_ASYNC_CRYPT
+            /* initialize event */
+            asyncDev = &ssl->encrypt.aes->asyncDev;
+            ret = wolfSSL_AsyncInit(ssl, asyncDev, event_flags);
+            if (ret != 0)
+                break;
+        #endif
+
+        #if defined(BUILD_AESGCM) && defined(HAVE_AESCCM)
+            aes_auth_fn = (ssl->specs.bulk_cipher_algorithm == wolfssl_aes_gcm)
+                            ? AES_GCM_ENCRYPT : AES_CCM_ENCRYPT;
+        #elif defined(BUILD_AESGCM)
+            aes_auth_fn = AES_GCM_ENCRYPT;
+        #else
+            aes_auth_fn = AES_CCM_ENCRYPT;
+        #endif
+            additionalSrc = input - 5;
+
+            XMEMSET(ssl->encrypt.additional, 0, AEAD_AUTH_DATA_SZ);
+
+            /* sequence number field is 64-bits */
+            WriteSEQ(ssl, CUR_ORDER, ssl->encrypt.additional);
+
+            /* Store the type, version. Unfortunately, they are in
+             * the input buffer ahead of the plaintext. */
+        #ifdef WOLFSSL_DTLS
+            if (ssl->options.dtls) {
+                additionalSrc -= DTLS_HANDSHAKE_EXTRA;
+            }
+        #endif
+            XMEMCPY(ssl->encrypt.additional + AEAD_TYPE_OFFSET,
+                                                        additionalSrc, 3);
+
+            /* Store the length of the plain text minus the explicit
+             * IV length minus the authentication tag size. */
+            c16toa(sz - AESGCM_EXP_IV_SZ - ssl->specs.aead_mac_size,
+                                ssl->encrypt.additional + AEAD_LEN_OFFSET);
+#if !defined(NO_PUBLIC_GCM_SET_IV) && \
+    ((defined(HAVE_FIPS) || defined(HAVE_SELFTEST)) && \
+    (!defined(HAVE_FIPS_VERSION) || (HAVE_FIPS_VERSION < 2)))
+            XMEMCPY(ssl->encrypt.nonce,
+                                ssl->keys.aead_enc_imp_IV, AESGCM_IMP_IV_SZ);
+            XMEMCPY(ssl->encrypt.nonce + AESGCM_IMP_IV_SZ,
+                                ssl->keys.aead_exp_IV, AESGCM_EXP_IV_SZ);
+#endif
+            ret = aes_auth_fn(ssl->encrypt.aes,
+                    out + AESGCM_EXP_IV_SZ, input + AESGCM_EXP_IV_SZ,
+                    sz - AESGCM_EXP_IV_SZ - ssl->specs.aead_mac_size,
+                    ssl->encrypt.nonce, AESGCM_NONCE_SZ,
+                    out + sz - ssl->specs.aead_mac_size,
+                    ssl->specs.aead_mac_size,
+                    ssl->encrypt.additional, AEAD_AUTH_DATA_SZ);
+        #ifdef WOLFSSL_ASYNC_CRYPT
+            if (ret == WC_PENDING_E && asyncOkay) {
+                ret = wolfSSL_AsyncPush(ssl, asyncDev);
+            }
+        #endif
+#if !defined(NO_PUBLIC_GCM_SET_IV) && \
+    ((!defined(HAVE_FIPS) && !defined(HAVE_SELFTEST)) || \
+    (defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION >= 2)))
+            XMEMCPY(out,
+                    ssl->encrypt.nonce + AESGCM_IMP_IV_SZ, AESGCM_EXP_IV_SZ);
+#endif
+        }
+        break;
+    #endif /* BUILD_AESGCM || HAVE_AESCCM */
+
+    #ifdef HAVE_CAMELLIA
+        case wolfssl_camellia:
+            ret = wc_CamelliaCbcEncrypt(ssl->encrypt.cam, out, input, sz);
+            break;
+    #endif
+
+    #ifdef HAVE_HC128
+        case wolfssl_hc128:
+            ret = wc_Hc128_Process(ssl->encrypt.hc128, out, input, sz);
+            break;
+    #endif
+
+    #ifdef BUILD_RABBIT
+        case wolfssl_rabbit:
+            ret = wc_RabbitProcess(ssl->encrypt.rabbit, out, input, sz);
+            break;
+    #endif
+
+    #if defined(HAVE_CHACHA) && defined(HAVE_POLY1305)
+        case wolfssl_chacha:
+            ret = ChachaAEADEncrypt(ssl, out, input, sz);
+            break;
+    #endif
+
+    #ifdef HAVE_NULL_CIPHER
+        case wolfssl_cipher_null:
+            if (input != out) {
+                XMEMMOVE(out, input, sz);
+            }
+            break;
+    #endif
+
+    #ifdef HAVE_IDEA
+        case wolfssl_idea:
+            ret = wc_IdeaCbcEncrypt(ssl->encrypt.idea, out, input, sz);
+            break;
+    #endif
+
+        default:
+            WOLFSSL_MSG("wolfSSL Encrypt programming error");
+            ret = ENCRYPT_ERROR;
+    }
+
+#ifdef WOLFSSL_ASYNC_CRYPT
+    /* if async is not okay, then block */
+    if (ret == WC_PENDING_E && !asyncOkay) {
+        ret = wc_AsyncWait(ret, asyncDev, event_flags);
+    }
+#endif
+
+    return ret;
+}
+
+static WC_INLINE int Encrypt(WOLFSSL* ssl, byte* out, const byte* input, word16 sz,
+    int asyncOkay)
+{
+    int ret = 0;
+
+#ifdef WOLFSSL_ASYNC_CRYPT
+    if (ssl->error == WC_PENDING_E) {
+        ssl->error = 0; /* clear async */
+    }
+#endif
+
+    switch (ssl->encrypt.state) {
+        case CIPHER_STATE_BEGIN:
+        {
+            if (ssl->encrypt.setup == 0) {
+                WOLFSSL_MSG("Encrypt ciphers not setup");
+                return ENCRYPT_ERROR;
+            }
+
+        #ifdef HAVE_FUZZER
+            if (ssl->fuzzerCb)
+                ssl->fuzzerCb(ssl, input, sz, FUZZ_ENCRYPT, ssl->fuzzerCtx);
+        #endif
+
+        #if defined(BUILD_AESGCM) || defined(HAVE_AESCCM)
+            /* make sure AES GCM/CCM memory is allocated */
+            /* free for these happens in FreeCiphers */
+            if (ssl->specs.bulk_cipher_algorithm == wolfssl_aes_ccm ||
+                ssl->specs.bulk_cipher_algorithm == wolfssl_aes_gcm) {
+                /* make sure auth iv and auth are allocated */
+                if (ssl->encrypt.additional == NULL)
+                    ssl->encrypt.additional = (byte*)XMALLOC(AEAD_AUTH_DATA_SZ,
+                                                   ssl->heap, DYNAMIC_TYPE_AES_BUFFER);
+                if (ssl->encrypt.nonce == NULL)
+                    ssl->encrypt.nonce = (byte*)XMALLOC(AESGCM_NONCE_SZ,
+                                                   ssl->heap, DYNAMIC_TYPE_AES_BUFFER);
+                if (ssl->encrypt.additional == NULL ||
+                         ssl->encrypt.nonce == NULL) {
+                    return MEMORY_E;
+                }
+            }
+        #endif /* BUILD_AESGCM || HAVE_AESCCM */
+
+            /* Advance state and proceed */
+            ssl->encrypt.state = CIPHER_STATE_DO;
+        }
+        FALL_THROUGH;
+
+        case CIPHER_STATE_DO:
+        {
+            ret = EncryptDo(ssl, out, input, sz, asyncOkay);
+
+            /* Advance state */
+            ssl->encrypt.state = CIPHER_STATE_END;
+
+        #ifdef WOLFSSL_ASYNC_CRYPT
+            /* If pending, then leave and return will resume below */
+            if (ret == WC_PENDING_E) {
+                return ret;
+            }
+        #endif
+        }
+        FALL_THROUGH;
+
+        case CIPHER_STATE_END:
+        {
+        #if defined(BUILD_AESGCM) || defined(HAVE_AESCCM)
+            if (ssl->specs.bulk_cipher_algorithm == wolfssl_aes_ccm ||
+                ssl->specs.bulk_cipher_algorithm == wolfssl_aes_gcm)
+            {
+                /* finalize authentication cipher */
+#if !defined(NO_PUBLIC_GCM_SET_IV) && \
+    ((defined(HAVE_FIPS) || defined(HAVE_SELFTEST)) && \
+    (!defined(HAVE_FIPS_VERSION) || (HAVE_FIPS_VERSION < 2)))
+                AeadIncrementExpIV(ssl);
+#endif
+                if (ssl->encrypt.nonce)
+                    ForceZero(ssl->encrypt.nonce, AESGCM_NONCE_SZ);
+            }
+        #endif /* BUILD_AESGCM || HAVE_AESCCM */
+            break;
+        }
+    }
+
+    /* Reset state */
+    ssl->encrypt.state = CIPHER_STATE_BEGIN;
+
+    return ret;
+}
+
+
+static WC_INLINE int DecryptDo(WOLFSSL* ssl, byte* plain, const byte* input,
+                           word16 sz)
+{
+    int ret = 0;
+
+    (void)plain;
+    (void)input;
+    (void)sz;
+
+    switch (ssl->specs.bulk_cipher_algorithm)
+    {
+    #ifdef BUILD_ARC4
+        case wolfssl_rc4:
+            wc_Arc4Process(ssl->decrypt.arc4, plain, input, sz);
+            break;
+    #endif
+
+    #ifdef BUILD_DES3
+        case wolfssl_triple_des:
+        #ifdef WOLFSSL_ASYNC_CRYPT
+            /* initialize event */
+            ret = wolfSSL_AsyncInit(ssl, &ssl->decrypt.des3->asyncDev,
+                WC_ASYNC_FLAG_CALL_AGAIN);
+            if (ret != 0)
+                break;
+        #endif
+
+            ret = wc_Des3_CbcDecrypt(ssl->decrypt.des3, plain, input, sz);
+        #ifdef WOLFSSL_ASYNC_CRYPT
+            if (ret == WC_PENDING_E) {
+                ret = wolfSSL_AsyncPush(ssl, &ssl->decrypt.des3->asyncDev);
+            }
+        #endif
+            break;
+    #endif
+
+    #if defined(BUILD_AES) && defined(HAVE_AES_CBC)
+        case wolfssl_aes:
+        #ifdef WOLFSSL_ASYNC_CRYPT
+            /* initialize event */
+            ret = wolfSSL_AsyncInit(ssl, &ssl->decrypt.aes->asyncDev,
+                WC_ASYNC_FLAG_CALL_AGAIN);
+            if (ret != 0)
+                break;
+        #endif
+        #if defined(WOLFSSL_RENESAS_TSIP_TLS) && \
+            !defined(NO_WOLFSSL_RENESAS_TSIP_TLS_SESSION)
+            if (tsip_useable(ssl)) {
+                ret = wc_tsip_AesCbcDecrypt(ssl->decrypt.aes, plain, input, sz);
+            } else
+        #endif
+            ret = wc_AesCbcDecrypt(ssl->decrypt.aes, plain, input, sz);
+        #ifdef WOLFSSL_ASYNC_CRYPT
+            if (ret == WC_PENDING_E) {
+                ret = wolfSSL_AsyncPush(ssl, &ssl->decrypt.aes->asyncDev);
+            }
+        #endif
+            break;
+    #endif
+
+    #if defined(BUILD_AESGCM) || defined(HAVE_AESCCM)
+        case wolfssl_aes_gcm:
+        case wolfssl_aes_ccm: /* GCM AEAD macros use same size as CCM */
+        {
+            wc_AesAuthDecryptFunc aes_auth_fn;
+
+        #ifdef WOLFSSL_ASYNC_CRYPT
+            /* initialize event */
+            ret = wolfSSL_AsyncInit(ssl, &ssl->decrypt.aes->asyncDev,
+                WC_ASYNC_FLAG_CALL_AGAIN);
+            if (ret != 0)
+                break;
+        #endif
+
+        #if defined(BUILD_AESGCM) && defined(HAVE_AESCCM)
+            aes_auth_fn = (ssl->specs.bulk_cipher_algorithm == wolfssl_aes_gcm)
+                            ? wc_AesGcmDecrypt : wc_AesCcmDecrypt;
+        #elif defined(BUILD_AESGCM)
+            aes_auth_fn = wc_AesGcmDecrypt;
+        #else
+            aes_auth_fn = wc_AesCcmDecrypt;
+        #endif
+
+            XMEMSET(ssl->decrypt.additional, 0, AEAD_AUTH_DATA_SZ);
+
+            /* sequence number field is 64-bits */
+            WriteSEQ(ssl, PEER_ORDER, ssl->decrypt.additional);
+
+            ssl->decrypt.additional[AEAD_TYPE_OFFSET] = ssl->curRL.type;
+            ssl->decrypt.additional[AEAD_VMAJ_OFFSET] = ssl->curRL.pvMajor;
+            ssl->decrypt.additional[AEAD_VMIN_OFFSET] = ssl->curRL.pvMinor;
+
+            c16toa(sz - AESGCM_EXP_IV_SZ - ssl->specs.aead_mac_size,
+                                    ssl->decrypt.additional + AEAD_LEN_OFFSET);
+            XMEMCPY(ssl->decrypt.nonce, ssl->keys.aead_dec_imp_IV,
+                                                            AESGCM_IMP_IV_SZ);
+            XMEMCPY(ssl->decrypt.nonce + AESGCM_IMP_IV_SZ, input,
+                                                            AESGCM_EXP_IV_SZ);
+            if ((ret = aes_auth_fn(ssl->decrypt.aes,
+                        plain + AESGCM_EXP_IV_SZ,
+                        input + AESGCM_EXP_IV_SZ,
+                           sz - AESGCM_EXP_IV_SZ - ssl->specs.aead_mac_size,
+                        ssl->decrypt.nonce, AESGCM_NONCE_SZ,
+                        input + sz - ssl->specs.aead_mac_size,
+                        ssl->specs.aead_mac_size,
+                        ssl->decrypt.additional, AEAD_AUTH_DATA_SZ)) < 0) {
+            #ifdef WOLFSSL_ASYNC_CRYPT
+                if (ret == WC_PENDING_E) {
+                    ret = wolfSSL_AsyncPush(ssl, &ssl->decrypt.aes->asyncDev);
+                }
+            #endif
+            }
+        }
+        break;
+    #endif /* BUILD_AESGCM || HAVE_AESCCM */
+
+    #ifdef HAVE_CAMELLIA
+        case wolfssl_camellia:
+            ret = wc_CamelliaCbcDecrypt(ssl->decrypt.cam, plain, input, sz);
+            break;
+    #endif
+
+    #ifdef HAVE_HC128
+        case wolfssl_hc128:
+            ret = wc_Hc128_Process(ssl->decrypt.hc128, plain, input, sz);
+            break;
+    #endif
+
+    #ifdef BUILD_RABBIT
+        case wolfssl_rabbit:
+            ret = wc_RabbitProcess(ssl->decrypt.rabbit, plain, input, sz);
+            break;
+    #endif
+
+    #if defined(HAVE_CHACHA) && defined(HAVE_POLY1305)
+        case wolfssl_chacha:
+            ret = ChachaAEADDecrypt(ssl, plain, input, sz);
+            break;
+    #endif
+
+    #ifdef HAVE_NULL_CIPHER
+        case wolfssl_cipher_null:
+            if (input != plain) {
+                XMEMMOVE(plain, input, sz);
+            }
+            break;
+    #endif
+
+    #ifdef HAVE_IDEA
+        case wolfssl_idea:
+            ret = wc_IdeaCbcDecrypt(ssl->decrypt.idea, plain, input, sz);
+            break;
+    #endif
+
+        default:
+            WOLFSSL_MSG("wolfSSL Decrypt programming error");
+            ret = DECRYPT_ERROR;
+    }
+
+    return ret;
+}
+
+static WC_INLINE int Decrypt(WOLFSSL* ssl, byte* plain, const byte* input,
+                           word16 sz)
+{
+    int ret = 0;
+
+#ifdef WOLFSSL_ASYNC_CRYPT
+    ret = wolfSSL_AsyncPop(ssl, &ssl->decrypt.state);
+    if (ret != WC_NOT_PENDING_E) {
+        /* check for still pending */
+        if (ret == WC_PENDING_E)
+            return ret;
+
+        ssl->error = 0; /* clear async */
+
+        /* let failures through so CIPHER_STATE_END logic is run */
+    }
+    else
+#endif
+    {
+        /* Reset state */
+        ret = 0;
+        ssl->decrypt.state = CIPHER_STATE_BEGIN;
+    }
+
+    switch (ssl->decrypt.state) {
+        case CIPHER_STATE_BEGIN:
+        {
+            if (ssl->decrypt.setup == 0) {
+                WOLFSSL_MSG("Decrypt ciphers not setup");
+                return DECRYPT_ERROR;
+            }
+
+        #if defined(BUILD_AESGCM) || defined(HAVE_AESCCM)
+            /* make sure AES GCM/CCM memory is allocated */
+            /* free for these happens in FreeCiphers */
+            if (ssl->specs.bulk_cipher_algorithm == wolfssl_aes_ccm ||
+                ssl->specs.bulk_cipher_algorithm == wolfssl_aes_gcm) {
+                /* make sure auth iv and auth are allocated */
+                if (ssl->decrypt.additional == NULL)
+                    ssl->decrypt.additional = (byte*)XMALLOC(AEAD_AUTH_DATA_SZ,
+                                                   ssl->heap, DYNAMIC_TYPE_AES_BUFFER);
+                if (ssl->decrypt.nonce == NULL)
+                    ssl->decrypt.nonce = (byte*)XMALLOC(AESGCM_NONCE_SZ,
+                                                   ssl->heap, DYNAMIC_TYPE_AES_BUFFER);
+                if (ssl->decrypt.additional == NULL ||
+                         ssl->decrypt.nonce == NULL) {
+                    return MEMORY_E;
+                }
+            }
+        #endif /* BUILD_AESGCM || HAVE_AESCCM */
+
+            /* Advance state and proceed */
+            ssl->decrypt.state = CIPHER_STATE_DO;
+        }
+        FALL_THROUGH;
+        case CIPHER_STATE_DO:
+        {
+            ret = DecryptDo(ssl, plain, input, sz);
+
+            /* Advance state */
+            ssl->decrypt.state = CIPHER_STATE_END;
+
+        #ifdef WOLFSSL_ASYNC_CRYPT
+            /* If pending, leave and return below */
+            if (ret == WC_PENDING_E) {
+                return ret;
+            }
+        #endif
+        }
+        FALL_THROUGH;
+        case CIPHER_STATE_END:
+        {
+        #if defined(BUILD_AESGCM) || defined(HAVE_AESCCM)
+            /* make sure AES GCM/CCM nonce is cleared */
+            if (ssl->specs.bulk_cipher_algorithm == wolfssl_aes_ccm ||
+                ssl->specs.bulk_cipher_algorithm == wolfssl_aes_gcm) {
+                if (ssl->decrypt.nonce)
+                    ForceZero(ssl->decrypt.nonce, AESGCM_NONCE_SZ);
+
+                if (ret < 0)
+                    ret = VERIFY_MAC_ERROR;
+            }
+        #endif /* BUILD_AESGCM || HAVE_AESCCM */
+            break;
+        }
+    }
+
+    /* Reset state */
+    ssl->decrypt.state = CIPHER_STATE_BEGIN;
+
+    /* handle mac error case */
+    if (ret == VERIFY_MAC_ERROR) {
+        if (!ssl->options.dtls)
+            SendAlert(ssl, alert_fatal, bad_record_mac);
+
+        #ifdef WOLFSSL_DTLS_DROP_STATS
+            ssl->macDropCount++;
+        #endif /* WOLFSSL_DTLS_DROP_STATS */
+    }
+
+    return ret;
+}
+
+#endif /* !WOLFSSL_NO_TLS12 */
+
+/* Check conditions for a cipher to have an explicit IV.
+ *
+ * ssl  The SSL/TLS object.
+ * returns 1 if the cipher in use has an explicit IV and 0 otherwise.
+ */
+static WC_INLINE int CipherHasExpIV(WOLFSSL *ssl)
+{
+#ifdef WOLFSSL_TLS13
+    if (ssl->options.tls1_3)
+        return 0;
+#endif
+    return (ssl->specs.cipher_type == aead) &&
+            (ssl->specs.bulk_cipher_algorithm != wolfssl_chacha);
+}
+
+/* check cipher text size for sanity */
+static int SanityCheckCipherText(WOLFSSL* ssl, word32 encryptSz)
+{
+#ifdef HAVE_TRUNCATED_HMAC
+    word32 minLength = ssl->truncated_hmac ? (byte)TRUNCATED_HMAC_SZ
+                                           : ssl->specs.hash_size;
+#else
+    word32 minLength = ssl->specs.hash_size; /* covers stream */
+#endif
+
+#ifndef WOLFSSL_AEAD_ONLY
+    if (ssl->specs.cipher_type == block) {
+#ifdef HAVE_ENCRYPT_THEN_MAC
+        if (ssl->options.startedETMRead) {
+            if ((encryptSz - MacSize(ssl)) % ssl->specs.block_size) {
+                WOLFSSL_MSG("Block ciphertext not block size");
+                return SANITY_CIPHER_E;
+            }
+        }
+        else
+#endif
+        if (encryptSz % ssl->specs.block_size) {
+            WOLFSSL_MSG("Block ciphertext not block size");
+            return SANITY_CIPHER_E;
+        }
+
+        minLength++;  /* pad byte */
+
+        if (ssl->specs.block_size > minLength)
+            minLength = ssl->specs.block_size;
+
+        if (ssl->options.tls1_1)
+            minLength += ssl->specs.block_size;  /* explicit IV */
+    }
+    else
+#endif
+    if (ssl->specs.cipher_type == aead) {
+        minLength = ssl->specs.aead_mac_size;    /* authTag size */
+        if (CipherHasExpIV(ssl))
+            minLength += AESGCM_EXP_IV_SZ;       /* explicit IV  */
+    }
+
+    if (encryptSz < minLength) {
+        WOLFSSL_MSG("Ciphertext not minimum size");
+        return SANITY_CIPHER_E;
+    }
+
+    return 0;
+}
+
+
+#ifndef WOLFSSL_AEAD_ONLY
+/* check all length bytes for the pad value, return 0 on success */
+static int PadCheck(const byte* a, byte pad, int length)
+{
+    int i;
+    int compareSum = 0;
+
+    for (i = 0; i < length; i++) {
+        compareSum |= a[i] ^ pad;
+    }
+
+    return compareSum;
+}
+
+
+/* Mask the padding bytes with the expected values.
+ * Constant time implementation - does maximum pad size possible.
+ *
+ * data   Message data.
+ * sz     Size of the message including MAC and padding and padding length.
+ * macSz  Size of the MAC.
+ * returns 0 on success, otherwise failure.
+ */
+static byte MaskPadding(const byte* data, int sz, int macSz)
+{
+    int i;
+    int checkSz = sz - 1;
+    byte paddingSz = data[sz - 1];
+    byte mask;
+    byte good = ctMaskGT(paddingSz, sz - 1 - macSz);
+
+    if (checkSz > TLS_MAX_PAD_SZ)
+        checkSz = TLS_MAX_PAD_SZ;
+
+    for (i = 0; i < checkSz; i++) {
+        mask = ctMaskLTE(i, paddingSz);
+        good |= mask & (data[sz - 1 - i] ^ paddingSz);
+    }
+
+    return good;
+}
+
+/* Mask the MAC in the message with the MAC calculated.
+ * Constant time implementation - starts looking for MAC where maximum padding
+ * size has it.
+ *
+ * data    Message data.
+ * sz      Size of the message including MAC and padding and padding length.
+ * macSz   Size of the MAC data.
+ * expMac  Expected MAC value.
+ * returns 0 on success, otherwise failure.
+ */
+static byte MaskMac(const byte* data, int sz, int macSz, byte* expMac)
+{
+    int i, j;
+    unsigned char mac[WC_MAX_DIGEST_SIZE];
+    int scanStart = sz - 1 - TLS_MAX_PAD_SZ - macSz;
+    int macEnd = sz - 1 - data[sz - 1];
+    int macStart = macEnd - macSz;
+    int r = 0;
+    unsigned char started, notEnded;
+    unsigned char good = 0;
+
+    scanStart &= ctMaskIntGTE(scanStart, 0);
+    macStart &= ctMaskIntGTE(macStart, 0);
+
+    /* Div on Intel has different speeds depending on value.
+     * Use a bitwise AND or mod a specific value (converted to mul). */
+    if ((macSz & (macSz - 1)) == 0)
+        r = (macSz - (scanStart - macStart)) & (macSz - 1);
+#ifndef NO_SHA
+    else if (macSz == WC_SHA_DIGEST_SIZE)
+        r = (macSz - (scanStart - macStart)) % WC_SHA_DIGEST_SIZE;
+#endif
+#ifdef WOLFSSL_SHA384
+    else if (macSz == WC_SHA384_DIGEST_SIZE)
+        r = (macSz - (scanStart - macStart)) % WC_SHA384_DIGEST_SIZE;
+#endif
+
+    XMEMSET(mac, 0, macSz);
+    for (i = scanStart; i < sz; i += macSz) {
+        for (j = 0; j < macSz && j + i < sz; j++) {
+            started = ctMaskGTE(i + j, macStart);
+            notEnded = ctMaskLT(i + j, macEnd);
+            mac[j] |= started & notEnded & data[i + j];
+        }
+    }
+
+    if ((macSz & (macSz - 1)) == 0) {
+        for (i = 0; i < macSz; i++)
+            good |= expMac[i] ^ mac[(i + r) & (macSz - 1)];
+    }
+#ifndef NO_SHA
+    else if (macSz == WC_SHA_DIGEST_SIZE) {
+        for (i = 0; i < macSz; i++)
+            good |= expMac[i] ^ mac[(i + r) % WC_SHA_DIGEST_SIZE];
+    }
+#endif
+#ifdef WOLFSSL_SHA384
+    else if (macSz == WC_SHA384_DIGEST_SIZE) {
+        for (i = 0; i < macSz; i++)
+            good |= expMac[i] ^ mac[(i + r) % WC_SHA384_DIGEST_SIZE];
+    }
+#endif
+
+    return good;
+}
+
+/* timing resistant pad/verify check, return 0 on success */
+int TimingPadVerify(WOLFSSL* ssl, const byte* input, int padLen, int macSz,
+                    int pLen, int content)
+{
+    byte verify[WC_MAX_DIGEST_SIZE];
+    byte good;
+    int  ret = 0;
+
+    good = MaskPadding(input, pLen, macSz);
+    /* 4th argument has potential to underflow, ssl->hmac function should
+     * either increment the size by (macSz + padLen + 1) before use or check on
+     * the size to make sure is valid. */
+    ret = ssl->hmac(ssl, verify, input, pLen - macSz - padLen - 1, padLen,
+                                                                    content, 1);
+    good |= MaskMac(input, pLen, ssl->specs.hash_size, verify);
+
+    /* Non-zero on failure. */
+    good = (byte)~(word32)good;
+    good &= good >> 4;
+    good &= good >> 2;
+    good &= good >> 1;
+    /* Make ret negative on masking failure. */
+    ret -= 1 - good;
+
+    /* Treat any failure as verify MAC error. */
+    if (ret != 0)
+        ret = VERIFY_MAC_ERROR;
+
+    return ret;
+}
+#endif
+
+
+int DoApplicationData(WOLFSSL* ssl, byte* input, word32* inOutIdx)
+{
+    word32 msgSz   = ssl->keys.encryptSz;
+    word32 idx     = *inOutIdx;
+    int    dataSz;
+    int    ivExtra = 0;
+    byte*  rawData = input + idx;  /* keep current  for hmac */
+#ifdef HAVE_LIBZ
+    byte   *decomp = NULL;
+#endif
+
+#ifdef WOLFSSL_EARLY_DATA
+    if (ssl->options.tls1_3 && ssl->options.handShakeDone == 0) {
+        if (ssl->options.side == WOLFSSL_SERVER_END &&
+                          ssl->earlyData != no_early_data &&
+                          ssl->options.clientState < CLIENT_FINISHED_COMPLETE) {
+            ssl->earlyDataSz += ssl->curSize;
+            if (ssl->earlyDataSz <= ssl->options.maxEarlyDataSz) {
+                WOLFSSL_MSG("Ignoring EarlyData!");
+                *inOutIdx = ssl->buffers.inputBuffer.length;
+                return 0;
+            }
+            WOLFSSL_MSG("Too much EarlyData!");
+        }
+    }
+#endif
+    if (ssl->options.handShakeDone == 0) {
+        WOLFSSL_MSG("Received App data before a handshake completed");
+        SendAlert(ssl, alert_fatal, unexpected_message);
+        return OUT_OF_ORDER_E;
+    }
+
+#ifndef WOLFSSL_AEAD_ONLY
+    if (ssl->specs.cipher_type == block) {
+        if (ssl->options.tls1_1)
+            ivExtra = ssl->specs.block_size;
+    }
+    else
+#endif
+    if (ssl->specs.cipher_type == aead) {
+        if (CipherHasExpIV(ssl))
+            ivExtra = AESGCM_EXP_IV_SZ;
+    }
+
+    dataSz = msgSz - ivExtra - ssl->keys.padSz;
+#if defined(HAVE_ENCRYPT_THEN_MAC) && !defined(WOLFSSL_AEAD_ONLY)
+    if (ssl->options.startedETMRead)
+        dataSz -= MacSize(ssl);
+#endif
+    if (dataSz < 0) {
+        WOLFSSL_MSG("App data buffer error, malicious input?");
+        SendAlert(ssl, alert_fatal, unexpected_message);
+        return BUFFER_ERROR;
+    }
+#ifdef WOLFSSL_EARLY_DATA
+    if (ssl->earlyData > early_data_ext) {
+        if (ssl->earlyDataSz + dataSz > ssl->options.maxEarlyDataSz) {
+            SendAlert(ssl, alert_fatal, unexpected_message);
+            return WOLFSSL_FATAL_ERROR;
+        }
+        ssl->earlyDataSz += dataSz;
+    }
+#endif
+
+    /* read data */
+    if (dataSz) {
+        int rawSz = dataSz;       /* keep raw size for idx adjustment */
+
+#ifdef HAVE_LIBZ
+        if (ssl->options.usingCompression) {
+            int dcomp_size = MAX_RECORD_SIZE + MAX_COMP_EXTRA;
+            decomp = XMALLOC(dcomp_size, ssl->heap, DYNAMIC_TYPE_NONE);
+            if (decomp == NULL)
+                return WOLFSSL_FATAL_ERROR;
+            dataSz = myDeCompress(ssl, rawData, dataSz, decomp, dcomp_size);
+            if (dataSz < 0) return dataSz;
+        }
+#endif
+        idx += rawSz;
+
+        ssl->buffers.clearOutputBuffer.buffer = rawData;
+        ssl->buffers.clearOutputBuffer.length = dataSz;
+    }
+
+    idx += ssl->keys.padSz;
+#if defined(HAVE_ENCRYPT_THEN_MAC) && !defined(WOLFSSL_AEAD_ONLY)
+    if (ssl->options.startedETMRead)
+        idx += MacSize(ssl);
+#endif
+
+#ifdef HAVE_LIBZ
+    /* decompress could be bigger, overwrite after verify */
+    if (ssl->options.usingCompression)
+        XMEMMOVE(rawData, decomp, dataSz);
+    XFREE(decomp, ssl->heap, DYNAMIC_TYPE_NONE);
+#endif
+
+    *inOutIdx = idx;
+    return 0;
+}
+
+
+/* process alert, return level */
+static int DoAlert(WOLFSSL* ssl, byte* input, word32* inOutIdx, int* type,
+                   word32 totalSz)
+{
+    byte level;
+    byte code;
+    word32 dataSz = totalSz - *inOutIdx;
+
+    #if defined(WOLFSSL_CALLBACKS) || defined(OPENSSL_EXTRA)
+        if (ssl->hsInfoOn)
+            AddPacketName(ssl, "Alert");
+        if (ssl->toInfoOn)
+            /* add record header back on to info + alert bytes level/code */
+            AddPacketInfo(ssl, "Alert", alert, input + *inOutIdx -
+                          RECORD_HEADER_SZ, RECORD_HEADER_SZ + ALERT_SIZE,
+                          READ_PROTO, ssl->heap);
+    #endif
+
+    if (IsEncryptionOn(ssl, 0)) {
+        dataSz -= ssl->keys.padSz;
+    #if defined(HAVE_ENCRYPT_THEN_MAC) && !defined(WOLFSSL_AEAD_ONLY)
+        if (ssl->options.startedETMRead)
+            dataSz -= MacSize(ssl);
+    #endif
+    }
+
+    /* make sure can read the message */
+    if (dataSz != ALERT_SIZE) {
+#ifdef WOLFSSL_EXTRA_ALERTS
+        SendAlert(ssl, alert_fatal, unexpected_message);
+#endif
+        return BUFFER_E;
+    }
+
+    level = input[(*inOutIdx)++];
+    code  = input[(*inOutIdx)++];
+    ssl->alert_history.last_rx.code = code;
+    ssl->alert_history.last_rx.level = level;
+    *type = code;
+    if (level == alert_fatal) {
+        ssl->options.isClosed = 1;  /* Don't send close_notify */
+    }
+
+    if (++ssl->options.alertCount >= WOLFSSL_ALERT_COUNT_MAX) {
+        WOLFSSL_MSG("Alert count exceeded");
+#ifdef WOLFSSL_EXTRA_ALERTS
+        if (level != alert_warning || code != close_notify)
+            SendAlert(ssl, alert_fatal, unexpected_message);
+#endif
+        return ALERT_COUNT_E;
+    }
+
+    WOLFSSL_MSG("Got alert");
+    if (*type == close_notify) {
+        WOLFSSL_MSG("\tclose notify");
+        ssl->options.closeNotify = 1;
+    }
+#ifdef WOLFSSL_TLS13
+    if (*type == decode_error) {
+        WOLFSSL_MSG("\tdecode error");
+    }
+    if (*type == illegal_parameter) {
+        WOLFSSL_MSG("\tillegal parameter");
+    }
+#endif
+    WOLFSSL_ERROR(*type);
+    if (IsEncryptionOn(ssl, 0)) {
+        *inOutIdx += ssl->keys.padSz;
+    #if defined(HAVE_ENCRYPT_THEN_MAC) && !defined(WOLFSSL_AEAD_ONLY)
+        if (ssl->options.startedETMRead)
+            *inOutIdx += MacSize(ssl);
+    #endif
+    }
+
+    return level;
+}
+
+static int GetInputData(WOLFSSL *ssl, word32 size)
+{
+    int in;
+    int inSz;
+    int maxLength;
+    int usedLength;
+    int dtlsExtra = 0;
+
+
+    /* check max input length */
+    usedLength = ssl->buffers.inputBuffer.length - ssl->buffers.inputBuffer.idx;
+    maxLength  = ssl->buffers.inputBuffer.bufferSize - usedLength;
+    inSz       = (int)(size - usedLength);      /* from last partial read */
+
+#ifdef WOLFSSL_DTLS
+    if (ssl->options.dtls) {
+        if (size < ssl->dtls_expected_rx)
+            dtlsExtra = (int)(ssl->dtls_expected_rx - size);
+        inSz = ssl->dtls_expected_rx;
+    }
+#endif
+
+    /* check that no lengths or size values are negative */
+    if (usedLength < 0 || maxLength < 0 || inSz <= 0) {
+        return BUFFER_ERROR;
+    }
+
+    if (inSz > maxLength) {
+        if (GrowInputBuffer(ssl, size + dtlsExtra, usedLength) < 0)
+            return MEMORY_E;
+    }
+
+    /* Put buffer data at start if not there */
+    if (usedLength > 0 && ssl->buffers.inputBuffer.idx != 0)
+        XMEMMOVE(ssl->buffers.inputBuffer.buffer,
+                ssl->buffers.inputBuffer.buffer + ssl->buffers.inputBuffer.idx,
+                usedLength);
+
+    /* remove processed data */
+    ssl->buffers.inputBuffer.idx    = 0;
+    ssl->buffers.inputBuffer.length = usedLength;
+
+    /* read data from network */
+    do {
+        in = wolfSSLReceive(ssl,
+                     ssl->buffers.inputBuffer.buffer +
+                     ssl->buffers.inputBuffer.length,
+                     inSz);
+        if (in == WANT_READ)
+            return WANT_READ;
+
+        if (in < 0)
+            return SOCKET_ERROR_E;
+
+        if (in > inSz)
+            return RECV_OVERFLOW_E;
+
+        ssl->buffers.inputBuffer.length += in;
+        inSz -= in;
+
+    } while (ssl->buffers.inputBuffer.length < size);
+
+#ifdef WOLFSSL_DEBUG_TLS
+    if (ssl->buffers.inputBuffer.idx == 0) {
+        WOLFSSL_MSG("Data received");
+        WOLFSSL_BUFFER(ssl->buffers.inputBuffer.buffer,
+                       ssl->buffers.inputBuffer.length);
+    }
+#endif
+
+    return 0;
+}
+
+#if defined(HAVE_ENCRYPT_THEN_MAC) && !defined(WOLFSSL_AEAD_ONLY)
+static WC_INLINE int VerifyMacEnc(WOLFSSL* ssl, const byte* input, word32 msgSz,
+                                  int content)
+{
+    int    ret;
+#ifdef HAVE_TRUNCATED_HMAC
+    word32 digestSz = ssl->truncated_hmac ? (byte)TRUNCATED_HMAC_SZ
+                                          : ssl->specs.hash_size;
+#else
+    word32 digestSz = ssl->specs.hash_size;
+#endif
+    byte   verify[WC_MAX_DIGEST_SIZE];
+
+    WOLFSSL_MSG("Verify MAC of Encrypted Data");
+
+    if (msgSz < digestSz) {
+        return VERIFY_MAC_ERROR;
+    }
+
+    ret  = ssl->hmac(ssl, verify, input, msgSz - digestSz, -1, content, 1);
+    ret |= ConstantCompare(verify, input + msgSz - digestSz, digestSz);
+    if (ret != 0) {
+        return VERIFY_MAC_ERROR;
+    }
+
+    return 0;
+}
+#endif
+
+static WC_INLINE int VerifyMac(WOLFSSL* ssl, const byte* input, word32 msgSz,
+                            int content, word32* padSz)
+{
+#if !defined(WOLFSSL_NO_TLS12) && !defined(WOLFSSL_AEAD_ONLY)
+    int    ivExtra = 0;
+    int    ret;
+    word32 pad     = 0;
+    word32 padByte = 0;
+#ifdef HAVE_TRUNCATED_HMAC
+    word32 digestSz = ssl->truncated_hmac ? (byte)TRUNCATED_HMAC_SZ
+                                          : ssl->specs.hash_size;
+#else
+    word32 digestSz = ssl->specs.hash_size;
+#endif
+    byte   verify[WC_MAX_DIGEST_SIZE];
+
+
+    if (ssl->specs.cipher_type == block) {
+        if (ssl->options.tls1_1)
+            ivExtra = ssl->specs.block_size;
+        pad = *(input + msgSz - ivExtra - 1);
+        padByte = 1;
+
+        if (ssl->options.tls) {
+            ret = TimingPadVerify(ssl, input, pad, digestSz, msgSz - ivExtra,
+                                  content);
+            if (ret != 0)
+                return ret;
+        }
+        else {  /* sslv3, some implementations have bad padding, but don't
+                 * allow bad read */
+            int  badPadLen = 0;
+            byte dmy[sizeof(WOLFSSL) >= MAX_PAD_SIZE ? 1 : MAX_PAD_SIZE] = {0};
+            byte* dummy = sizeof(dmy) < MAX_PAD_SIZE ? (byte*) ssl : dmy;
+
+            (void)dmy;
+
+            if (pad > (msgSz - digestSz - 1)) {
+                WOLFSSL_MSG("Plain Len not long enough for pad/mac");
+                pad       = 0;  /* no bad read */
+                badPadLen = 1;
+            }
+            PadCheck(dummy, (byte)pad, MAX_PAD_SIZE);  /* timing only */
+            ret = ssl->hmac(ssl, verify, input, msgSz - digestSz - pad - 1, pad,
+                                                                    content, 1);
+            if (ConstantCompare(verify, input + msgSz - digestSz - pad - 1,
+                                digestSz) != 0)
+                return VERIFY_MAC_ERROR;
+            if (ret != 0 || badPadLen)
+                return VERIFY_MAC_ERROR;
+        }
+    }
+    else if (ssl->specs.cipher_type == stream) {
+        ret = ssl->hmac(ssl, verify, input, msgSz - digestSz, -1, content, 1);
+        if (ConstantCompare(verify, input + msgSz - digestSz, digestSz) != 0){
+            return VERIFY_MAC_ERROR;
+        }
+        if (ret != 0)
+            return VERIFY_MAC_ERROR;
+    }
+#endif /* !WOLFSSL_NO_TLS12 && !WOLFSSL_AEAD_ONLY */
+
+    if (ssl->specs.cipher_type == aead) {
+        *padSz = ssl->specs.aead_mac_size;
+    }
+#if !defined(WOLFSSL_NO_TLS12) && !defined(WOLFSSL_AEAD_ONLY)
+    else {
+        *padSz = digestSz + pad + padByte;
+    }
+#endif /* !WOLFSSL_NO_TLS12 && !WOLFSSL_AEAD_ONLY */
+
+    (void)input;
+    (void)msgSz;
+    (void)content;
+
+    return 0;
+}
+
+
+/* process input requests, return 0 is done, 1 is call again to complete, and
+   negative number is error */
+int ProcessReply(WOLFSSL* ssl)
+{
+    int    ret = 0, type, readSz;
+    int    atomicUser = 0;
+    word32 startIdx = 0;
+#if defined(WOLFSSL_DTLS)
+    int    used;
+#endif
+
+#ifdef ATOMIC_USER
+    if (ssl->ctx->DecryptVerifyCb)
+        atomicUser = 1;
+#endif
+
+    if (ssl->error != 0 && ssl->error != WANT_READ && ssl->error != WANT_WRITE
+    #ifdef WOLFSSL_ASYNC_CRYPT
+        && ssl->error != WC_PENDING_E
+    #endif
+    #ifdef WOLFSSL_NONBLOCK_OCSP
+        && ssl->error != OCSP_WANT_READ
+    #endif
+    ) {
+        WOLFSSL_MSG("ProcessReply retry in error state, not allowed");
+        return ssl->error;
+    }
+
+    for (;;) {
+        switch (ssl->options.processReply) {
+
+        /* in the WOLFSSL_SERVER case, get the first byte for detecting
+         * old client hello */
+        case doProcessInit:
+
+            readSz = RECORD_HEADER_SZ;
+
+        #ifdef WOLFSSL_DTLS
+            if (ssl->options.dtls)
+                readSz = DTLS_RECORD_HEADER_SZ;
+        #endif
+
+            /* get header or return error */
+            if (!ssl->options.dtls) {
+                if ((ret = GetInputData(ssl, readSz)) < 0)
+                    return ret;
+            } else {
+            #ifdef WOLFSSL_DTLS
+                /* read ahead may already have header */
+                used = ssl->buffers.inputBuffer.length -
+                       ssl->buffers.inputBuffer.idx;
+                if (used < readSz) {
+                    if ((ret = GetInputData(ssl, readSz)) < 0)
+                        return ret;
+                }
+            #endif
+            }
+
+#ifdef OLD_HELLO_ALLOWED
+
+            /* see if sending SSLv2 client hello */
+            if ( ssl->options.side == WOLFSSL_SERVER_END &&
+                 ssl->options.clientState == NULL_STATE &&
+                 ssl->buffers.inputBuffer.buffer[ssl->buffers.inputBuffer.idx]
+                         != handshake) {
+                byte b0, b1;
+
+                ssl->options.processReply = runProcessOldClientHello;
+
+                /* sanity checks before getting size at front */
+                if (ssl->buffers.inputBuffer.buffer[
+                          ssl->buffers.inputBuffer.idx + OPAQUE16_LEN] != OLD_HELLO_ID) {
+                    WOLFSSL_MSG("Not a valid old client hello");
+                    return PARSE_ERROR;
+                }
+
+                if (ssl->buffers.inputBuffer.buffer[
+                          ssl->buffers.inputBuffer.idx + OPAQUE24_LEN] != SSLv3_MAJOR &&
+                    ssl->buffers.inputBuffer.buffer[
+                          ssl->buffers.inputBuffer.idx + OPAQUE24_LEN] != DTLS_MAJOR) {
+                    WOLFSSL_MSG("Not a valid version in old client hello");
+                    return PARSE_ERROR;
+                }
+
+                /* how many bytes need ProcessOldClientHello */
+                b0 =
+                ssl->buffers.inputBuffer.buffer[ssl->buffers.inputBuffer.idx++];
+                b1 =
+                ssl->buffers.inputBuffer.buffer[ssl->buffers.inputBuffer.idx++];
+                ssl->curSize = (word16)(((b0 & 0x7f) << 8) | b1);
+            }
+            else {
+                ssl->options.processReply = getRecordLayerHeader;
+                continue;
+            }
+            FALL_THROUGH;
+
+        /* in the WOLFSSL_SERVER case, run the old client hello */
+        case runProcessOldClientHello:
+
+            /* get sz bytes or return error */
+            if (!ssl->options.dtls) {
+                if ((ret = GetInputData(ssl, ssl->curSize)) < 0)
+                    return ret;
+            } else {
+            #ifdef WOLFSSL_DTLS
+                /* read ahead may already have */
+                used = ssl->buffers.inputBuffer.length -
+                       ssl->buffers.inputBuffer.idx;
+                if (used < ssl->curSize)
+                    if ((ret = GetInputData(ssl, ssl->curSize)) < 0)
+                        return ret;
+            #endif  /* WOLFSSL_DTLS */
+            }
+
+            ret = ProcessOldClientHello(ssl, ssl->buffers.inputBuffer.buffer,
+                                        &ssl->buffers.inputBuffer.idx,
+                                        ssl->buffers.inputBuffer.length -
+                                        ssl->buffers.inputBuffer.idx,
+                                        ssl->curSize);
+            if (ret < 0)
+                return ret;
+
+            else if (ssl->buffers.inputBuffer.idx ==
+                     ssl->buffers.inputBuffer.length) {
+                ssl->options.processReply = doProcessInit;
+                return 0;
+            }
+
+#endif  /* OLD_HELLO_ALLOWED */
+            FALL_THROUGH;
+
+        /* get the record layer header */
+        case getRecordLayerHeader:
+
+            ret = GetRecordHeader(ssl, ssl->buffers.inputBuffer.buffer,
+                                       &ssl->buffers.inputBuffer.idx,
+                                       &ssl->curRL, &ssl->curSize);
+#ifdef WOLFSSL_DTLS
+            if (ssl->options.dtls && ret == SEQUENCE_ERROR) {
+                WOLFSSL_MSG("Silently dropping out of order DTLS message");
+                ssl->options.processReply = doProcessInit;
+                ssl->buffers.inputBuffer.length = 0;
+                ssl->buffers.inputBuffer.idx = 0;
+#ifdef WOLFSSL_DTLS_DROP_STATS
+                ssl->replayDropCount++;
+#endif /* WOLFSSL_DTLS_DROP_STATS */
+
+                if (IsDtlsNotSctpMode(ssl) && ssl->options.dtlsHsRetain) {
+                    ret = DtlsMsgPoolSend(ssl, 0);
+                    if (ret != 0)
+                        return ret;
+                }
+
+                continue;
+            }
+#endif
+            if (ret != 0)
+                return ret;
+
+#ifdef WOLFSSL_TLS13
+            if (IsAtLeastTLSv1_3(ssl->version) && IsEncryptionOn(ssl, 0) &&
+                                        ssl->curRL.type != application_data &&
+                                        ssl->curRL.type != change_cipher_spec) {
+                SendAlert(ssl, alert_fatal, unexpected_message);
+                return PARSE_ERROR;
+            }
+#endif
+
+            ssl->options.processReply = getData;
+            FALL_THROUGH;
+
+        /* retrieve record layer data */
+        case getData:
+
+            /* get sz bytes or return error */
+            if (!ssl->options.dtls) {
+                if ((ret = GetInputData(ssl, ssl->curSize)) < 0) {
+#ifdef WOLFSSL_EXTRA_ALERTS
+                    if (ret != WANT_READ)
+                        SendAlert(ssl, alert_fatal, bad_record_mac);
+#endif
+                    return ret;
+                }
+            }
+            else {
+#ifdef WOLFSSL_DTLS
+                /* read ahead may already have */
+                used = ssl->buffers.inputBuffer.length -
+                       ssl->buffers.inputBuffer.idx;
+                if (used < ssl->curSize)
+                    if ((ret = GetInputData(ssl, ssl->curSize)) < 0)
+                        return ret;
+#endif
+            }
+
+            if (IsEncryptionOn(ssl, 0)) {
+                int tooLong = 0;
+
+#ifdef WOLFSSL_TLS13
+                if (IsAtLeastTLSv1_3(ssl->version)) {
+                    tooLong  = ssl->curSize > MAX_TLS13_ENC_SZ;
+                    tooLong |= ssl->curSize - ssl->specs.aead_mac_size >
+                                                             MAX_TLS13_PLAIN_SZ;
+                }
+#endif
+#ifdef WOLFSSL_EXTRA_ALERTS
+                if (!IsAtLeastTLSv1_3(ssl->version))
+                    tooLong = ssl->curSize > MAX_TLS_CIPHER_SZ;
+#endif
+                if (tooLong) {
+                    WOLFSSL_MSG("Encrypted data too long");
+#if defined(WOLFSSL_TLS13) || defined(WOLFSSL_EXTRA_ALERTS)
+                    SendAlert(ssl, alert_fatal, record_overflow);
+#endif
+                    return BUFFER_ERROR;
+                }
+            }
+            ssl->keys.padSz = 0;
+
+            ssl->options.processReply = verifyEncryptedMessage;
+            startIdx = ssl->buffers.inputBuffer.idx;  /* in case > 1 msg per */
+            FALL_THROUGH;
+
+        /* verify digest of encrypted message */
+        case verifyEncryptedMessage:
+#if defined(HAVE_ENCRYPT_THEN_MAC) && !defined(WOLFSSL_AEAD_ONLY)
+            if (IsEncryptionOn(ssl, 0) && ssl->keys.decryptedCur == 0 &&
+                                   !atomicUser && ssl->options.startedETMRead) {
+                ret = VerifyMacEnc(ssl, ssl->buffers.inputBuffer.buffer +
+                                   ssl->buffers.inputBuffer.idx,
+                                   ssl->curSize, ssl->curRL.type);
+            #ifdef WOLFSSL_ASYNC_CRYPT
+                if (ret == WC_PENDING_E)
+                    return ret;
+            #endif
+                if (ret < 0) {
+                    WOLFSSL_MSG("VerifyMacEnc failed");
+                    WOLFSSL_ERROR(ret);
+                #ifdef WOLFSSL_DTLS
+                    /* If in DTLS mode, if the decrypt fails for any
+                     * reason, pretend the datagram never happened. */
+                    if (ssl->options.dtls) {
+                        ssl->options.processReply = doProcessInit;
+                        ssl->buffers.inputBuffer.idx =
+                                        ssl->buffers.inputBuffer.length;
+                        #ifdef WOLFSSL_DTLS_DROP_STATS
+                            ssl->macDropCount++;
+                        #endif /* WOLFSSL_DTLS_DROP_STATS */
+                    }
+                #endif /* WOLFSSL_DTLS */
+                #ifdef WOLFSSL_EXTRA_ALERTS
+                    if (!ssl->options.dtls)
+                        SendAlert(ssl, alert_fatal, bad_record_mac);
+                #endif
+                    return DECRYPT_ERROR;
+                }
+                ssl->keys.encryptSz    = ssl->curSize;
+            }
+#endif
+            ssl->options.processReply = decryptMessage;
+            FALL_THROUGH;
+
+        /* decrypt message */
+        case decryptMessage:
+
+#if !defined(WOLFSSL_TLS13) || defined(WOLFSSL_TLS13_DRAFT_18)
+            if (IsEncryptionOn(ssl, 0) && ssl->keys.decryptedCur == 0)
+#else
+            if (IsEncryptionOn(ssl, 0) && ssl->keys.decryptedCur == 0 &&
+                                        (!IsAtLeastTLSv1_3(ssl->version) ||
+                                         ssl->curRL.type != change_cipher_spec))
+#endif
+            {
+                bufferStatic* in = &ssl->buffers.inputBuffer;
+
+                ret = SanityCheckCipherText(ssl, ssl->curSize);
+                if (ret < 0) {
+                #ifdef WOLFSSL_EXTRA_ALERTS
+                    SendAlert(ssl, alert_fatal, bad_record_mac);
+                #endif
+                    return ret;
+                }
+
+                if (atomicUser) {
+        #ifdef ATOMIC_USER
+            #if defined(HAVE_ENCRYPT_THEN_MAC) && !defined(WOLFSSL_AEAD_ONLY)
+                    if (ssl->options.startedETMRead) {
+                        ret = ssl->ctx->VerifyDecryptCb(ssl,
+                                     in->buffer + in->idx, in->buffer + in->idx,
+                                     ssl->curSize - MacSize(ssl),
+                                     ssl->curRL.type, 1, &ssl->keys.padSz,
+                                     ssl->DecryptVerifyCtx);
+                    }
+                    else
+            #endif
+                    {
+                        ret = ssl->ctx->DecryptVerifyCb(ssl,
+                                      in->buffer + in->idx,
+                                      in->buffer + in->idx,
+                                      ssl->curSize, ssl->curRL.type, 1,
+                                      &ssl->keys.padSz, ssl->DecryptVerifyCtx);
+                    }
+        #endif /* ATOMIC_USER */
+                }
+                else {
+                    if (!ssl->options.tls1_3) {
+        #ifndef WOLFSSL_NO_TLS12
+            #if defined(HAVE_ENCRYPT_THEN_MAC) && !defined(WOLFSSL_AEAD_ONLY)
+                    if (ssl->options.startedETMRead) {
+                        word32 digestSz = MacSize(ssl);
+                        ret = Decrypt(ssl,
+                                      in->buffer + in->idx,
+                                      in->buffer + in->idx,
+                                      ssl->curSize - digestSz);
+                         ssl->keys.padSz =
+                              in->buffer[in->idx + ssl->curSize - digestSz - 1];
+                         ssl->keys.padSz += 1;
+                         ssl->keys.decryptedCur = 1;
+                    }
+                    else
+            #endif
+                    {
+                        ret = Decrypt(ssl,
+                                      in->buffer + in->idx,
+                                      in->buffer + in->idx,
+                                      ssl->curSize);
+                    }
+        #else
+                        ret = DECRYPT_ERROR;
+        #endif
+                    }
+                    else
+                    {
+                #ifdef WOLFSSL_TLS13
+                    #if defined(WOLFSSL_TLS13_DRAFT_18) || \
+                        defined(WOLFSSL_TLS13_DRAFT_22) || \
+                        defined(WOLFSSL_TLS13_DRAFT_23)
+                        ret = DecryptTls13(ssl,
+                                           in->buffer + in->idx,
+                                           in->buffer + in->idx,
+                                           ssl->curSize, NULL, 0);
+                    #else
+                        ret = DecryptTls13(ssl,
+                                        in->buffer + in->idx,
+                                        in->buffer + in->idx,
+                                        ssl->curSize,
+                                        (byte*)&ssl->curRL, RECORD_HEADER_SZ);
+                    #endif
+                #else
+                        ret = DECRYPT_ERROR;
+                #endif /* WOLFSSL_TLS13 */
+                    }
+                }
+
+            #ifdef WOLFSSL_ASYNC_CRYPT
+                if (ret == WC_PENDING_E)
+                    return ret;
+            #endif
+
+                if (ret >= 0) {
+            #ifndef WOLFSSL_NO_TLS12
+                    /* handle success */
+                #ifndef WOLFSSL_AEAD_ONLY
+                    if (ssl->options.tls1_1 && ssl->specs.cipher_type == block)
+                        ssl->buffers.inputBuffer.idx += ssl->specs.block_size;
+                #endif
+                        /* go past TLSv1.1 IV */
+                    if (CipherHasExpIV(ssl))
+                        ssl->buffers.inputBuffer.idx += AESGCM_EXP_IV_SZ;
+            #endif
+                }
+                else {
+                    WOLFSSL_MSG("Decrypt failed");
+                    WOLFSSL_ERROR(ret);
+                #ifdef WOLFSSL_EARLY_DATA
+                    if (ssl->options.tls1_3) {
+                         if (ssl->options.side == WOLFSSL_SERVER_END &&
+                                 ssl->earlyData != no_early_data &&
+                                 ssl->options.clientState <
+                                                     CLIENT_FINISHED_COMPLETE) {
+                            ssl->earlyDataSz += ssl->curSize;
+                            if (ssl->earlyDataSz <=
+                                                  ssl->options.maxEarlyDataSz) {
+                                WOLFSSL_MSG("Ignoring EarlyData!");
+                                if (ssl->keys.peer_sequence_number_lo-- == 0)
+                                    ssl->keys.peer_sequence_number_hi--;
+                                ssl->options.processReply = doProcessInit;
+                                ssl->buffers.inputBuffer.idx =
+                                                ssl->buffers.inputBuffer.length;
+                                return 0;
+                            }
+                            WOLFSSL_MSG("Too much EarlyData!");
+                        }
+                        SendAlert(ssl, alert_fatal, bad_record_mac);
+                    }
+                #endif
+                #ifdef WOLFSSL_DTLS
+                    /* If in DTLS mode, if the decrypt fails for any
+                     * reason, pretend the datagram never happened. */
+                    if (ssl->options.dtls) {
+                        ssl->options.processReply = doProcessInit;
+                        ssl->buffers.inputBuffer.idx =
+                                        ssl->buffers.inputBuffer.length;
+                        #ifdef WOLFSSL_DTLS_DROP_STATS
+                            ssl->macDropCount++;
+                        #endif /* WOLFSSL_DTLS_DROP_STATS */
+                    }
+                #endif /* WOLFSSL_DTLS */
+                    return DECRYPT_ERROR;
+                }
+            }
+
+            ssl->options.processReply = verifyMessage;
+            FALL_THROUGH;
+
+        /* verify digest of message */
+        case verifyMessage:
+
+#if !defined(WOLFSSL_TLS13) || defined(WOLFSSL_TLS13_DRAFT_18)
+            if (IsEncryptionOn(ssl, 0) && ssl->keys.decryptedCur == 0)
+#else
+            if (IsEncryptionOn(ssl, 0) && ssl->keys.decryptedCur == 0 &&
+                                        (!IsAtLeastTLSv1_3(ssl->version) ||
+                                         ssl->curRL.type != change_cipher_spec))
+#endif
+            {
+                if (!atomicUser
+#if defined(HAVE_ENCRYPT_THEN_MAC) && !defined(WOLFSSL_AEAD_ONLY)
+                                && !ssl->options.startedETMRead
+#endif
+                    ) {
+                    ret = VerifyMac(ssl, ssl->buffers.inputBuffer.buffer +
+                                    ssl->buffers.inputBuffer.idx,
+                                    ssl->curSize, ssl->curRL.type,
+                                    &ssl->keys.padSz);
+                #ifdef WOLFSSL_ASYNC_CRYPT
+                    if (ret == WC_PENDING_E)
+                        return ret;
+                #endif
+                    if (ret < 0) {
+                        WOLFSSL_MSG("VerifyMac failed");
+                        WOLFSSL_ERROR(ret);
+                    #ifdef WOLFSSL_DTLS
+                        /* If in DTLS mode, if the decrypt fails for any
+                         * reason, pretend the datagram never happened. */
+                        if (ssl->options.dtls) {
+                            ssl->options.processReply = doProcessInit;
+                            ssl->buffers.inputBuffer.idx =
+                                            ssl->buffers.inputBuffer.length;
+                            #ifdef WOLFSSL_DTLS_DROP_STATS
+                                ssl->macDropCount++;
+                            #endif /* WOLFSSL_DTLS_DROP_STATS */
+                        }
+                    #endif /* WOLFSSL_DTLS */
+                    #ifdef WOLFSSL_EXTRA_ALERTS
+                        if (!ssl->options.dtls)
+                            SendAlert(ssl, alert_fatal, bad_record_mac);
+                    #endif
+                        return DECRYPT_ERROR;
+                    }
+                }
+
+                ssl->keys.encryptSz    = ssl->curSize;
+                ssl->keys.decryptedCur = 1;
+#ifdef WOLFSSL_TLS13
+                if (ssl->options.tls1_3) {
+                    word16 i = (word16)(ssl->buffers.inputBuffer.length -
+                                        ssl->keys.padSz);
+                    /* Remove padding from end of plain text. */
+                    for (--i; i > ssl->buffers.inputBuffer.idx; i--) {
+                        if (ssl->buffers.inputBuffer.buffer[i] != 0)
+                            break;
+                    }
+                    /* Get the real content type from the end of the data. */
+                    ssl->curRL.type = ssl->buffers.inputBuffer.buffer[i];
+                    ssl->keys.padSz = ssl->buffers.inputBuffer.length - i;
+                }
+#endif
+            }
+
+            ssl->options.processReply = runProcessingOneMessage;
+            FALL_THROUGH;
+
+        /* the record layer is here */
+        case runProcessingOneMessage:
+
+       #if defined(HAVE_ENCRYPT_THEN_MAC) && !defined(WOLFSSL_AEAD_ONLY)
+            if (IsEncryptionOn(ssl, 0) && ssl->options.startedETMRead) {
+                if (ssl->buffers.inputBuffer.length - ssl->keys.padSz -
+                                              ssl->buffers.inputBuffer.idx -
+                                              MacSize(ssl) > MAX_PLAINTEXT_SZ) {
+                    WOLFSSL_MSG("Plaintext too long - Encrypt-Then-MAC");
+            #if defined(WOLFSSL_EXTRA_ALERTS)
+                    SendAlert(ssl, alert_fatal, record_overflow);
+            #endif
+                    return BUFFER_ERROR;
+                }
+            }
+            else
+       #endif
+            if (ssl->buffers.inputBuffer.length - ssl->keys.padSz -
+                              ssl->buffers.inputBuffer.idx > MAX_PLAINTEXT_SZ) {
+                WOLFSSL_MSG("Plaintext too long");
+#if defined(WOLFSSL_TLS13) || defined(WOLFSSL_EXTRA_ALERTS)
+                SendAlert(ssl, alert_fatal, record_overflow);
+#endif
+                return BUFFER_ERROR;
+            }
+
+        #ifdef WOLFSSL_DTLS
+            if (IsDtlsNotSctpMode(ssl)) {
+                DtlsUpdateWindow(ssl);
+            }
+        #endif /* WOLFSSL_DTLS */
+
+            WOLFSSL_MSG("received record layer msg");
+
+            switch (ssl->curRL.type) {
+                case handshake :
+                    /* debugging in DoHandShakeMsg */
+                    if (ssl->options.dtls) {
+#ifdef WOLFSSL_DTLS
+                        ret = DoDtlsHandShakeMsg(ssl,
+                                            ssl->buffers.inputBuffer.buffer,
+                                            &ssl->buffers.inputBuffer.idx,
+                                            ssl->buffers.inputBuffer.length);
+#endif
+                    }
+                    else if (!IsAtLeastTLSv1_3(ssl->version)) {
+#ifndef WOLFSSL_NO_TLS12
+                        ret = DoHandShakeMsg(ssl,
+                                            ssl->buffers.inputBuffer.buffer,
+                                            &ssl->buffers.inputBuffer.idx,
+                                            ssl->buffers.inputBuffer.length);
+#else
+                        ret = BUFFER_ERROR;
+#endif
+                    }
+                    else {
+#ifdef WOLFSSL_TLS13
+                        ret = DoTls13HandShakeMsg(ssl,
+                                            ssl->buffers.inputBuffer.buffer,
+                                            &ssl->buffers.inputBuffer.idx,
+                                            ssl->buffers.inputBuffer.length);
+    #ifdef WOLFSSL_EARLY_DATA
+                        if (ret != 0)
+                            return ret;
+                        if (ssl->options.side == WOLFSSL_SERVER_END &&
+                                ssl->earlyData > early_data_ext &&
+                                ssl->options.handShakeState == HANDSHAKE_DONE) {
+                            ssl->earlyData = no_early_data;
+                            ssl->options.processReply = doProcessInit;
+                            return ZERO_RETURN;
+                        }
+    #endif
+#else
+                        ret = BUFFER_ERROR;
+#endif
+                    }
+                    if (ret != 0) {
+                        WOLFSSL_ERROR(ret);
+                        return ret;
+                    }
+                    break;
+
+                case change_cipher_spec:
+                    WOLFSSL_MSG("got CHANGE CIPHER SPEC");
+                    #if defined(WOLFSSL_CALLBACKS) || defined(OPENSSL_EXTRA)
+                        if (ssl->hsInfoOn)
+                            AddPacketName(ssl, "ChangeCipher");
+                        /* add record header back on info */
+                        if (ssl->toInfoOn) {
+                            AddPacketInfo(ssl, "ChangeCipher",
+                                change_cipher_spec,
+                                ssl->buffers.inputBuffer.buffer +
+                                ssl->buffers.inputBuffer.idx - RECORD_HEADER_SZ,
+                                1 + RECORD_HEADER_SZ, READ_PROTO, ssl->heap);
+                            #ifdef WOLFSSL_CALLBACKS
+                            AddLateRecordHeader(&ssl->curRL, &ssl->timeoutInfo);
+                            #endif
+                        }
+                    #endif
+
+#ifdef WOLFSSL_TLS13
+    #ifdef WOLFSSL_TLS13_DRAFT_18
+                    if (IsAtLeastTLSv1_3(ssl->version)) {
+                        SendAlert(ssl, alert_fatal, illegal_parameter);
+                        return UNKNOWN_RECORD_TYPE;
+                    }
+    #else
+                    if (IsAtLeastTLSv1_3(ssl->version)) {
+                        word32 i = ssl->buffers.inputBuffer.idx;
+                        if (ssl->options.handShakeState == HANDSHAKE_DONE) {
+                            SendAlert(ssl, alert_fatal, unexpected_message);
+                            return UNKNOWN_RECORD_TYPE;
+                        }
+                        if (ssl->curSize != 1 ||
+                                      ssl->buffers.inputBuffer.buffer[i] != 1) {
+                            SendAlert(ssl, alert_fatal, illegal_parameter);
+                            return UNKNOWN_RECORD_TYPE;
+                        }
+                        ssl->buffers.inputBuffer.idx++;
+                        break;
+                    }
+    #endif
+#endif
+
+#ifndef WOLFSSL_NO_TLS12
+                    ret = SanityCheckMsgReceived(ssl, change_cipher_hs);
+                    if (ret != 0) {
+                        if (!ssl->options.dtls) {
+                            return ret;
+                        }
+                        else {
+                        #ifdef WOLFSSL_DTLS
+                        /* Check for duplicate CCS message in DTLS mode.
+                         * DTLS allows for duplicate messages, and it should be
+                         * skipped. Also skip if out of order. */
+                            if (ret != DUPLICATE_MSG_E && ret != OUT_OF_ORDER_E)
+                                return ret;
+
+                            if (IsDtlsNotSctpMode(ssl)) {
+                                ret = DtlsMsgPoolSend(ssl, 1);
+                                if (ret != 0)
+                                    return ret;
+                            }
+
+                            if (ssl->curSize != 1) {
+                                WOLFSSL_MSG("Malicious or corrupted"
+                                            " duplicate ChangeCipher msg");
+                                return LENGTH_ERROR;
+                            }
+                            ssl->buffers.inputBuffer.idx++;
+                            break;
+                        #endif /* WOLFSSL_DTLS */
+                        }
+                    }
+
+                    if (IsEncryptionOn(ssl, 0) && ssl->options.handShakeDone) {
+                        ssl->buffers.inputBuffer.idx += ssl->keys.padSz;
+                        ssl->curSize -= (word16) ssl->buffers.inputBuffer.idx;
+            #if defined(HAVE_ENCRYPT_THEN_MAC) && !defined(WOLFSSL_AEAD_ONLY)
+                        if (ssl->options.startedETMRead) {
+                            word32 digestSz = MacSize(ssl);
+                            ssl->buffers.inputBuffer.idx += digestSz;
+                            ssl->curSize -= digestSz;
+                        }
+            #endif
+                    }
+
+                    if (ssl->curSize != 1) {
+                        WOLFSSL_MSG("Malicious or corrupted ChangeCipher msg");
+                        return LENGTH_ERROR;
+                    }
+
+                    ssl->buffers.inputBuffer.idx++;
+                    ssl->keys.encryptionOn = 1;
+
+                    /* setup decrypt keys for following messages */
+                    /* XXX This might not be what we want to do when
+                     * receiving a CCS with multicast. We update the
+                     * key when the application updates them. */
+                    if ((ret = SetKeysSide(ssl, DECRYPT_SIDE_ONLY)) != 0)
+                        return ret;
+
+            #if defined(HAVE_ENCRYPT_THEN_MAC) && !defined(WOLFSSL_AEAD_ONLY)
+                    ssl->options.startedETMRead = ssl->options.encThenMac;
+            #endif
+
+                    #ifdef WOLFSSL_DTLS
+                        if (ssl->options.dtls) {
+                            WOLFSSL_DTLS_PEERSEQ* peerSeq = ssl->keys.peerSeq;
+#ifdef WOLFSSL_MULTICAST
+                            if (ssl->options.haveMcast) {
+                                peerSeq += ssl->keys.curPeerId;
+                                peerSeq->highwaterMark = UpdateHighwaterMark(0,
+                                        ssl->ctx->mcastFirstSeq,
+                                        ssl->ctx->mcastSecondSeq,
+                                        ssl->ctx->mcastMaxSeq);
+                            }
+#endif
+                            peerSeq->nextEpoch++;
+                            peerSeq->prevSeq_lo = peerSeq->nextSeq_lo;
+                            peerSeq->prevSeq_hi = peerSeq->nextSeq_hi;
+                            peerSeq->nextSeq_lo = 0;
+                            peerSeq->nextSeq_hi = 0;
+                            XMEMCPY(peerSeq->prevWindow, peerSeq->window,
+                                    DTLS_SEQ_SZ);
+                            XMEMSET(peerSeq->window, 0, DTLS_SEQ_SZ);
+                        }
+                    #endif
+
+                    #ifdef HAVE_LIBZ
+                        if (ssl->options.usingCompression)
+                            if ( (ret = InitStreams(ssl)) != 0)
+                                return ret;
+                    #endif
+                    ret = BuildFinished(ssl, &ssl->hsHashes->verifyHashes,
+                                       ssl->options.side == WOLFSSL_CLIENT_END ?
+                                       server : client);
+                    if (ret != 0)
+                        return ret;
+#endif /* !WOLFSSL_NO_TLS12 */
+                    break;
+
+                case application_data:
+                    WOLFSSL_MSG("got app DATA");
+                    #ifdef WOLFSSL_DTLS
+                        if (ssl->options.dtls && ssl->options.dtlsHsRetain) {
+                            FreeHandshakeResources(ssl);
+                            ssl->options.dtlsHsRetain = 0;
+                        }
+                    #endif
+                    #ifdef WOLFSSL_TLS13
+                        if (ssl->keys.keyUpdateRespond) {
+                            WOLFSSL_MSG("No KeyUpdate from peer seen");
+                            return SANITY_MSG_E;
+                        }
+                    #endif
+                    if ((ret = DoApplicationData(ssl,
+                                                ssl->buffers.inputBuffer.buffer,
+                                                &ssl->buffers.inputBuffer.idx))
+                                                                         != 0) {
+                        WOLFSSL_ERROR(ret);
+                        return ret;
+                    }
+                    break;
+
+                case alert:
+                    WOLFSSL_MSG("got ALERT!");
+                    ret = DoAlert(ssl, ssl->buffers.inputBuffer.buffer,
+                                  &ssl->buffers.inputBuffer.idx, &type,
+                                   ssl->buffers.inputBuffer.length);
+                    if (ret == alert_fatal)
+                        return FATAL_ERROR;
+                    else if (ret < 0)
+                        return ret;
+
+                    /* catch warnings that are handled as errors */
+                    if (type == close_notify)
+                        return ssl->error = ZERO_RETURN;
+
+                    if (type == decrypt_error)
+                        return FATAL_ERROR;
+                    break;
+
+                default:
+                    WOLFSSL_ERROR(UNKNOWN_RECORD_TYPE);
+                    return UNKNOWN_RECORD_TYPE;
+            }
+
+            ssl->options.processReply = doProcessInit;
+
+            /* input exhausted? */
+            if (ssl->buffers.inputBuffer.idx >= ssl->buffers.inputBuffer.length)
+                return 0;
+
+            /* more messages per record */
+            else if ((ssl->buffers.inputBuffer.idx - startIdx) < ssl->curSize) {
+                WOLFSSL_MSG("More messages in record");
+
+                ssl->options.processReply = runProcessingOneMessage;
+
+                if (IsEncryptionOn(ssl, 0)) {
+                    WOLFSSL_MSG("Bundled encrypted messages, remove middle pad");
+            #if defined(HAVE_ENCRYPT_THEN_MAC) && !defined(WOLFSSL_AEAD_ONLY)
+                    if (ssl->options.startedETMRead) {
+                        word32 digestSz = MacSize(ssl);
+                        if (ssl->buffers.inputBuffer.idx >=
+                                                   ssl->keys.padSz + digestSz) {
+                            ssl->buffers.inputBuffer.idx -=
+                                                     ssl->keys.padSz + digestSz;
+                        }
+                        else {
+                            WOLFSSL_MSG("\tmiddle padding error");
+                            return FATAL_ERROR;
+                        }
+                    }
+                    else
+             #endif
+                    {
+                        if (ssl->buffers.inputBuffer.idx >= ssl->keys.padSz) {
+                            ssl->buffers.inputBuffer.idx -= ssl->keys.padSz;
+                        }
+                        else {
+                            WOLFSSL_MSG("\tmiddle padding error");
+                            return FATAL_ERROR;
+                        }
+                    }
+                }
+
+                continue;
+            }
+            /* more records */
+            else {
+                WOLFSSL_MSG("More records in input");
+                ssl->options.processReply = doProcessInit;
+                continue;
+            }
+
+        default:
+            WOLFSSL_MSG("Bad process input state, programming error");
+            return INPUT_CASE_ERROR;
+        }
+    }
+    return FATAL_ERROR;
+}
+
+
+int SendChangeCipher(WOLFSSL* ssl)
+{
+    byte              *output;
+    int                sendSz = RECORD_HEADER_SZ + ENUM_LEN;
+    int                idx    = RECORD_HEADER_SZ;
+    int                ret;
+
+    #ifdef OPENSSL_EXTRA
+    ssl->cbmode = SSL_CB_MODE_WRITE;
+    if (ssl->options.side == WOLFSSL_SERVER_END){
+        ssl->options.serverState = SERVER_CHANGECIPHERSPEC_COMPLETE;
+        if (ssl->CBIS != NULL)
+            ssl->CBIS(ssl, SSL_CB_ACCEPT_LOOP, SSL_SUCCESS);
+    }
+    else{
+        ssl->options.clientState =
+            CLIENT_CHANGECIPHERSPEC_COMPLETE;
+        if (ssl->CBIS != NULL)
+            ssl->CBIS(ssl, SSL_CB_CONNECT_LOOP, SSL_SUCCESS);
+    }
+    #endif
+
+    #ifdef WOLFSSL_DTLS
+        if (ssl->options.dtls) {
+            sendSz += DTLS_RECORD_EXTRA;
+            idx    += DTLS_RECORD_EXTRA;
+        }
+    #endif
+
+    /* are we in scr */
+    if (IsEncryptionOn(ssl, 1) && ssl->options.handShakeDone) {
+        sendSz += MAX_MSG_EXTRA;
+    }
+
+    /* check for available size */
+    if ((ret = CheckAvailableSize(ssl, sendSz)) != 0)
+        return ret;
+
+    /* get output buffer */
+    output = ssl->buffers.outputBuffer.buffer +
+             ssl->buffers.outputBuffer.length;
+
+    AddRecordHeader(output, 1, change_cipher_spec, ssl);
+
+    output[idx] = 1;             /* turn it on */
+
+    if (IsEncryptionOn(ssl, 1) && ssl->options.handShakeDone) {
+        byte input[ENUM_LEN];
+        int  inputSz = ENUM_LEN;
+
+        input[0] = 1;  /* turn it on */
+        sendSz = BuildMessage(ssl, output, sendSz, input, inputSz,
+                              change_cipher_spec, 0, 0, 0);
+        if (sendSz < 0) {
+            return sendSz;
+        }
+    }
+
+    #ifdef WOLFSSL_DTLS
+        if (IsDtlsNotSctpMode(ssl)) {
+            DtlsSEQIncrement(ssl, CUR_ORDER);
+            if ((ret = DtlsMsgPoolSave(ssl, output, sendSz)) != 0)
+                return ret;
+        }
+    #endif
+    #if defined(WOLFSSL_CALLBACKS) || defined(OPENSSL_EXTRA)
+        if (ssl->hsInfoOn) AddPacketName(ssl, "ChangeCipher");
+        if (ssl->toInfoOn)
+            AddPacketInfo(ssl, "ChangeCipher", change_cipher_spec, output,
+                    sendSz, WRITE_PROTO, ssl->heap);
+    #endif
+    ssl->buffers.outputBuffer.length += sendSz;
+
+    if (ssl->options.groupMessages)
+        return 0;
+    #if defined(WOLFSSL_DTLS) && !defined(WOLFSSL_DEBUG_DTLS)
+    else if (ssl->options.dtls) {
+        /* If using DTLS, force the ChangeCipherSpec message to be in the
+         * same datagram as the finished message. */
+        return 0;
+    }
+    #endif
+    else
+        return SendBuffered(ssl);
+}
+
+
+#if !defined(NO_OLD_TLS) && !defined(WOLFSSL_AEAD_ONLY)
+static int SSL_hmac(WOLFSSL* ssl, byte* digest, const byte* in, word32 sz,
+                    int padLen, int content, int verify)
+{
+    byte   result[WC_MAX_DIGEST_SIZE];
+    word32 digestSz = ssl->specs.hash_size;            /* actual sizes */
+    word32 padSz    = ssl->specs.pad_size;
+    int    ret      = 0;
+
+    wc_Md5 md5;
+    wc_Sha sha;
+
+    /* data */
+    byte seq[SEQ_SZ];
+    byte conLen[ENUM_LEN + LENGTH_SZ];     /* content & length */
+    const byte* macSecret = wolfSSL_GetMacSecret(ssl, verify);
+
+    (void)padLen;
+
+#ifdef HAVE_FUZZER
+    if (ssl->fuzzerCb)
+        ssl->fuzzerCb(ssl, in, sz, FUZZ_HMAC, ssl->fuzzerCtx);
+#endif
+
+    XMEMSET(seq, 0, SEQ_SZ);
+    conLen[0] = (byte)content;
+    c16toa((word16)sz, &conLen[ENUM_LEN]);
+    WriteSEQ(ssl, verify, seq);
+
+    if (ssl->specs.mac_algorithm == md5_mac) {
+        ret =  wc_InitMd5_ex(&md5, ssl->heap, ssl->devId);
+        if (ret != 0)
+            return ret;
+
+        /* inner */
+        ret =  wc_Md5Update(&md5, macSecret, digestSz);
+        ret |= wc_Md5Update(&md5, PAD1, padSz);
+        ret |= wc_Md5Update(&md5, seq, SEQ_SZ);
+        ret |= wc_Md5Update(&md5, conLen, sizeof(conLen));
+        /* in buffer */
+        ret |= wc_Md5Update(&md5, in, sz);
+        if (ret != 0)
+            return VERIFY_MAC_ERROR;
+        ret = wc_Md5Final(&md5, result);
+    #ifdef WOLFSSL_ASYNC_CRYPT
+        /* TODO: Make non-blocking */
+        if (ret == WC_PENDING_E) {
+            ret = wc_AsyncWait(ret, &md5.asyncDev, WC_ASYNC_FLAG_NONE);
+        }
+    #endif
+        if (ret != 0)
+            return VERIFY_MAC_ERROR;
+
+        /* outer */
+        ret =  wc_Md5Update(&md5, macSecret, digestSz);
+        ret |= wc_Md5Update(&md5, PAD2, padSz);
+        ret |= wc_Md5Update(&md5, result, digestSz);
+        if (ret != 0)
+            return VERIFY_MAC_ERROR;
+        ret =  wc_Md5Final(&md5, digest);
+    #ifdef WOLFSSL_ASYNC_CRYPT
+        /* TODO: Make non-blocking */
+        if (ret == WC_PENDING_E) {
+            ret = wc_AsyncWait(ret, &md5.asyncDev, WC_ASYNC_FLAG_NONE);
+        }
+    #endif
+        if (ret != 0)
+            return VERIFY_MAC_ERROR;
+
+        wc_Md5Free(&md5);
+    }
+    else {
+        ret =  wc_InitSha_ex(&sha, ssl->heap, ssl->devId);
+        if (ret != 0)
+            return ret;
+
+        /* inner */
+        ret =  wc_ShaUpdate(&sha, macSecret, digestSz);
+        ret |= wc_ShaUpdate(&sha, PAD1, padSz);
+        ret |= wc_ShaUpdate(&sha, seq, SEQ_SZ);
+        ret |= wc_ShaUpdate(&sha, conLen, sizeof(conLen));
+        /* in buffer */
+        ret |= wc_ShaUpdate(&sha, in, sz);
+        if (ret != 0)
+            return VERIFY_MAC_ERROR;
+        ret = wc_ShaFinal(&sha, result);
+    #ifdef WOLFSSL_ASYNC_CRYPT
+        /* TODO: Make non-blocking */
+        if (ret == WC_PENDING_E) {
+            ret = wc_AsyncWait(ret, &sha.asyncDev, WC_ASYNC_FLAG_NONE);
+        }
+    #endif
+        if (ret != 0)
+            return VERIFY_MAC_ERROR;
+
+        /* outer */
+        ret =  wc_ShaUpdate(&sha, macSecret, digestSz);
+        ret |= wc_ShaUpdate(&sha, PAD2, padSz);
+        ret |= wc_ShaUpdate(&sha, result, digestSz);
+        if (ret != 0)
+            return VERIFY_MAC_ERROR;
+        ret =  wc_ShaFinal(&sha, digest);
+    #ifdef WOLFSSL_ASYNC_CRYPT
+        /* TODO: Make non-blocking */
+        if (ret == WC_PENDING_E) {
+            ret = wc_AsyncWait(ret, &sha.asyncDev, WC_ASYNC_FLAG_NONE);
+        }
+    #endif
+        if (ret != 0)
+            return VERIFY_MAC_ERROR;
+
+        wc_ShaFree(&sha);
+    }
+    return 0;
+}
+#endif /* !NO_OLD_TLS && !WOLFSSL_AEAD_ONLY */
+
+
+#ifndef NO_CERTS
+
+#if !defined(NO_MD5) && !defined(NO_OLD_TLS)
+static int BuildMD5_CertVerify(WOLFSSL* ssl, byte* digest)
+{
+    int ret;
+    byte md5_result[WC_MD5_DIGEST_SIZE];
+#ifdef WOLFSSL_SMALL_STACK
+    wc_Md5* md5 = (wc_Md5*)XMALLOC(sizeof(wc_Md5), ssl->heap, DYNAMIC_TYPE_HASHCTX);
+#else
+    wc_Md5  md5[1];
+#endif
+
+    /* make md5 inner */
+    ret = wc_Md5Copy(&ssl->hsHashes->hashMd5, md5); /* Save current position */
+    if (ret == 0)
+        ret = wc_Md5Update(md5, ssl->arrays->masterSecret,SECRET_LEN);
+    if (ret == 0)
+        ret = wc_Md5Update(md5, PAD1, PAD_MD5);
+    if (ret == 0)
+        ret = wc_Md5Final(md5, md5_result);
+
+    /* make md5 outer */
+    if (ret == 0) {
+        ret = wc_InitMd5_ex(md5, ssl->heap, ssl->devId);
+        if (ret == 0) {
+            ret = wc_Md5Update(md5, ssl->arrays->masterSecret, SECRET_LEN);
+            if (ret == 0)
+                ret = wc_Md5Update(md5, PAD2, PAD_MD5);
+            if (ret == 0)
+                ret = wc_Md5Update(md5, md5_result, WC_MD5_DIGEST_SIZE);
+            if (ret == 0)
+                ret = wc_Md5Final(md5, digest);
+            wc_Md5Free(md5);
+        }
+    }
+
+#ifdef WOLFSSL_SMALL_STACK
+    XFREE(md5, ssl->heap, DYNAMIC_TYPE_HASHCTX);
+#endif
+
+    return ret;
+}
+#endif /* !NO_MD5 && !NO_OLD_TLS */
+
+#if !defined(NO_SHA) && (!defined(NO_OLD_TLS) || \
+                              defined(WOLFSSL_ALLOW_TLS_SHA1))
+static int BuildSHA_CertVerify(WOLFSSL* ssl, byte* digest)
+{
+    int ret;
+    byte sha_result[WC_SHA_DIGEST_SIZE];
+#ifdef WOLFSSL_SMALL_STACK
+    wc_Sha* sha = (wc_Sha*)XMALLOC(sizeof(wc_Sha), ssl->heap, DYNAMIC_TYPE_HASHCTX);
+#else
+    wc_Sha  sha[1];
+#endif
+
+    /* make sha inner */
+    ret = wc_ShaCopy(&ssl->hsHashes->hashSha, sha); /* Save current position */
+    if (ret == 0)
+        ret = wc_ShaUpdate(sha, ssl->arrays->masterSecret,SECRET_LEN);
+    if (ret == 0)
+        ret = wc_ShaUpdate(sha, PAD1, PAD_SHA);
+    if (ret == 0)
+        ret = wc_ShaFinal(sha, sha_result);
+
+    /* make sha outer */
+    if (ret == 0) {
+        ret = wc_InitSha_ex(sha, ssl->heap, ssl->devId);
+        if (ret == 0) {
+            ret = wc_ShaUpdate(sha, ssl->arrays->masterSecret,SECRET_LEN);
+            if (ret == 0)
+                ret = wc_ShaUpdate(sha, PAD2, PAD_SHA);
+            if (ret == 0)
+                ret = wc_ShaUpdate(sha, sha_result, WC_SHA_DIGEST_SIZE);
+            if (ret == 0)
+                ret = wc_ShaFinal(sha, digest);
+            wc_ShaFree(sha);
+        }
+    }
+
+#ifdef WOLFSSL_SMALL_STACK
+    XFREE(sha, ssl->heap, DYNAMIC_TYPE_HASHCTX);
+#endif
+
+    return ret;
+}
+#endif /* !NO_SHA && (!NO_OLD_TLS || WOLFSSL_ALLOW_TLS_SHA1) */
+
+int BuildCertHashes(WOLFSSL* ssl, Hashes* hashes)
+{
+    int ret = 0;
+
+    (void)hashes;
+
+    if (ssl->options.tls) {
+    #if !defined(NO_MD5) && !defined(NO_OLD_TLS)
+        ret = wc_Md5GetHash(&ssl->hsHashes->hashMd5, hashes->md5);
+        if (ret != 0)
+            return ret;
+    #endif
+    #if !defined(NO_SHA)
+        ret = wc_ShaGetHash(&ssl->hsHashes->hashSha, hashes->sha);
+        if (ret != 0)
+            return ret;
+    #endif
+        if (IsAtLeastTLSv1_2(ssl)) {
+            #ifndef NO_SHA256
+                ret = wc_Sha256GetHash(&ssl->hsHashes->hashSha256,
+                                       hashes->sha256);
+                if (ret != 0)
+                    return ret;
+            #endif
+            #ifdef WOLFSSL_SHA384
+                ret = wc_Sha384GetHash(&ssl->hsHashes->hashSha384,
+                                       hashes->sha384);
+                if (ret != 0)
+                    return ret;
+            #endif
+            #ifdef WOLFSSL_SHA512
+                ret = wc_Sha512GetHash(&ssl->hsHashes->hashSha512,
+                                       hashes->sha512);
+                if (ret != 0)
+                    return ret;
+            #endif
+        }
+    }
+    else {
+    #if !defined(NO_MD5) && !defined(NO_OLD_TLS)
+        ret = BuildMD5_CertVerify(ssl, hashes->md5);
+        if (ret != 0)
+            return ret;
+    #endif
+    #if !defined(NO_SHA) && (!defined(NO_OLD_TLS) || \
+                              defined(WOLFSSL_ALLOW_TLS_SHA1))
+        ret = BuildSHA_CertVerify(ssl, hashes->sha);
+        if (ret != 0)
+            return ret;
+    #endif
+    }
+
+    return ret;
+}
+
+#endif /* !NO_CERTS */
+
+#ifndef WOLFSSL_NO_TLS12
+/* Persistable BuildMessage arguments */
+typedef struct BuildMsgArgs {
+    word32 digestSz;
+    word32 sz;
+    word32 pad;
+    word32 idx;
+    word32 headerSz;
+    word16 size;
+    word32 ivSz;      /* TLSv1.1  IV */
+    byte*  iv;
+} BuildMsgArgs;
+
+static void FreeBuildMsgArgs(WOLFSSL* ssl, void* pArgs)
+{
+    BuildMsgArgs* args = (BuildMsgArgs*)pArgs;
+
+    (void)ssl;
+    (void)args;
+
+    if (args->iv) {
+        XFREE(args->iv, ssl->heap, DYNAMIC_TYPE_SALT);
+        args->iv = NULL;
+    }
+}
+#endif
+
+/* Build SSL Message, encrypted */
+int BuildMessage(WOLFSSL* ssl, byte* output, int outSz, const byte* input,
+             int inSz, int type, int hashOutput, int sizeOnly, int asyncOkay)
+{
+#ifndef WOLFSSL_NO_TLS12
+    int ret = 0;
+    BuildMsgArgs* args;
+    BuildMsgArgs  lcl_args;
+#ifdef WOLFSSL_ASYNC_CRYPT
+    args = (BuildMsgArgs*)ssl->async.args;
+    typedef char args_test[sizeof(ssl->async.args) >= sizeof(*args) ? 1 : -1];
+    (void)sizeof(args_test);
+#endif
+#endif
+
+    WOLFSSL_ENTER("BuildMessage");
+
+    if (ssl == NULL) {
+        return BAD_FUNC_ARG;
+    }
+
+#ifdef WOLFSSL_NO_TLS12
+    return BuildTls13Message(ssl, output, outSz, input, inSz, type,
+                                               hashOutput, sizeOnly, asyncOkay);
+#else
+#ifdef WOLFSSL_TLS13
+    if (ssl->options.tls1_3) {
+        return BuildTls13Message(ssl, output, outSz, input, inSz, type,
+                                 hashOutput, sizeOnly, asyncOkay);
+    }
+#endif
+
+    ret = WC_NOT_PENDING_E;
+#ifdef WOLFSSL_ASYNC_CRYPT
+    if (asyncOkay) {
+        ret = wolfSSL_AsyncPop(ssl, &ssl->options.buildMsgState);
+        if (ret != WC_NOT_PENDING_E) {
+            /* Check for error */
+            if (ret < 0)
+                goto exit_buildmsg;
+        }
+    }
+    else
+#endif
+    {
+        args = &lcl_args;
+    }
+
+    /* Reset state */
+    if (ret == WC_NOT_PENDING_E) {
+        ret = 0;
+        ssl->options.buildMsgState = BUILD_MSG_BEGIN;
+        XMEMSET(args, 0, sizeof(BuildMsgArgs));
+
+        args->sz = RECORD_HEADER_SZ + inSz;
+        args->idx  = RECORD_HEADER_SZ;
+        args->headerSz = RECORD_HEADER_SZ;
+    #ifdef WOLFSSL_ASYNC_CRYPT
+        ssl->async.freeArgs = FreeBuildMsgArgs;
+    #endif
+    }
+
+    switch (ssl->options.buildMsgState) {
+        case BUILD_MSG_BEGIN:
+        {
+            /* catch mistaken sizeOnly parameter */
+            if (!sizeOnly && (output == NULL || input == NULL) ) {
+                ERROR_OUT(BAD_FUNC_ARG, exit_buildmsg);
+            }
+            if (sizeOnly && (output || input) ) {
+                WOLFSSL_MSG("BuildMessage w/sizeOnly doesn't need input/output");
+                ERROR_OUT(BAD_FUNC_ARG, exit_buildmsg);
+            }
+
+            ssl->options.buildMsgState = BUILD_MSG_SIZE;
+        }
+        FALL_THROUGH;
+        case BUILD_MSG_SIZE:
+        {
+            args->digestSz = ssl->specs.hash_size;
+        #ifdef HAVE_TRUNCATED_HMAC
+            if (ssl->truncated_hmac)
+                args->digestSz = min(TRUNCATED_HMAC_SZ, args->digestSz);
+        #endif
+            args->sz += args->digestSz;
+
+        #ifdef WOLFSSL_DTLS
+            if (ssl->options.dtls) {
+                args->sz       += DTLS_RECORD_EXTRA;
+                args->idx      += DTLS_RECORD_EXTRA;
+                args->headerSz += DTLS_RECORD_EXTRA;
+            }
+        #endif
+
+        #ifndef WOLFSSL_AEAD_ONLY
+            if (ssl->specs.cipher_type == block) {
+                word32 blockSz = ssl->specs.block_size;
+                if (ssl->options.tls1_1) {
+                    args->ivSz = blockSz;
+                    args->sz  += args->ivSz;
+
+                    if (args->ivSz > MAX_IV_SZ)
+                        ERROR_OUT(BUFFER_E, exit_buildmsg);
+                }
+                args->sz += 1;       /* pad byte */
+            #if defined(HAVE_ENCRYPT_THEN_MAC) && !defined(WOLFSSL_AEAD_ONLY)
+                if (ssl->options.startedETMWrite) {
+                    args->pad = (args->sz - args->headerSz -
+                                                      args->digestSz) % blockSz;
+                }
+                else
+            #endif
+                    args->pad = (args->sz - args->headerSz) % blockSz;
+                #ifdef OPENSSL_EXTRA
+                if(args->pad != 0)
+                #endif
+                    args->pad = blockSz - args->pad;
+                args->sz += args->pad;
+            }
+        #endif /* WOLFSSL_AEAD_ONLY */
+
+        #ifdef HAVE_AEAD
+            if (ssl->specs.cipher_type == aead) {
+                if (ssl->specs.bulk_cipher_algorithm != wolfssl_chacha)
+                    args->ivSz = AESGCM_EXP_IV_SZ;
+
+                args->sz += (args->ivSz + ssl->specs.aead_mac_size - args->digestSz);
+            }
+        #endif
+
+            /* done with size calculations */
+            if (sizeOnly)
+                goto exit_buildmsg;
+
+            if (args->sz > (word32)outSz) {
+                WOLFSSL_MSG("Oops, want to write past output buffer size");
+                ERROR_OUT(BUFFER_E, exit_buildmsg);
+            }
+
+            if (args->ivSz > 0) {
+                args->iv = (byte*)XMALLOC(args->ivSz, ssl->heap, DYNAMIC_TYPE_SALT);
+                if (args->iv == NULL)
+                    ERROR_OUT(MEMORY_E, exit_buildmsg);
+
+                ret = wc_RNG_GenerateBlock(ssl->rng, args->iv, args->ivSz);
+                if (ret != 0)
+                    goto exit_buildmsg;
+
+            }
+#if !defined(NO_PUBLIC_GCM_SET_IV) && \
+    ((defined(HAVE_FIPS) || defined(HAVE_SELFTEST)) && \
+    (!defined(HAVE_FIPS_VERSION) || (HAVE_FIPS_VERSION < 2)) && \
+    defined(HAVE_AEAD))
+            if (ssl->specs.cipher_type == aead) {
+                if (ssl->specs.bulk_cipher_algorithm != wolfssl_chacha)
+                    XMEMCPY(args->iv, ssl->keys.aead_exp_IV, AESGCM_EXP_IV_SZ);
+            }
+#endif
+
+            args->size = (word16)(args->sz - args->headerSz);    /* include mac and digest */
+            AddRecordHeader(output, args->size, (byte)type, ssl);
+
+            /* write to output */
+            if (args->ivSz > 0) {
+                XMEMCPY(output + args->idx, args->iv,
+                                        min(args->ivSz, MAX_IV_SZ));
+                args->idx += args->ivSz;
+            }
+            XMEMCPY(output + args->idx, input, inSz);
+            args->idx += inSz;
+
+            ssl->options.buildMsgState = BUILD_MSG_HASH;
+        }
+        FALL_THROUGH;
+        case BUILD_MSG_HASH:
+        {
+            if (type == handshake && hashOutput) {
+                ret = HashOutput(ssl, output, args->headerSz + inSz, args->ivSz);
+                if (ret != 0)
+                    goto exit_buildmsg;
+            }
+        #ifndef WOLFSSL_AEAD_ONLY
+            if (ssl->specs.cipher_type == block) {
+                word32 tmpIdx;
+                word32 i;
+
+            #if defined(HAVE_ENCRYPT_THEN_MAC) && !defined(WOLFSSL_AEAD_ONLY)
+                if (ssl->options.startedETMWrite)
+                    tmpIdx = args->idx;
+                else
+            #endif
+                    tmpIdx = args->idx + args->digestSz;
+
+                for (i = 0; i <= args->pad; i++)
+                    output[tmpIdx++] = (byte)args->pad; /* pad byte gets pad value */
+            }
+        #endif
+
+            ssl->options.buildMsgState = BUILD_MSG_VERIFY_MAC;
+        }
+        FALL_THROUGH;
+        case BUILD_MSG_VERIFY_MAC:
+        {
+            /* User Record Layer Callback handling */
+    #ifdef ATOMIC_USER
+        #if defined(HAVE_ENCRYPT_THEN_MAC) && !defined(WOLFSSL_AEAD_ONLY)
+            if (ssl->options.startedETMWrite) {
+                if (ssl->ctx->EncryptMacCb) {
+                    ret = ssl->ctx->EncryptMacCb(ssl, output + args->idx +
+                                                 args->pad + 1, type, 0,
+                                                 output + args->headerSz,
+                                                 output + args->headerSz,
+                                                 args->size - args->digestSz,
+                                                 ssl->MacEncryptCtx);
+                    goto exit_buildmsg;
+                }
+            }
+            else
+        #endif
+            {
+                if (ssl->ctx->MacEncryptCb) {
+                    ret = ssl->ctx->MacEncryptCb(ssl, output + args->idx,
+                                    output + args->headerSz + args->ivSz, inSz,
+                                    type, 0, output + args->headerSz,
+                                    output + args->headerSz, args->size,
+                                    ssl->MacEncryptCtx);
+                    goto exit_buildmsg;
+                }
+            }
+    #endif
+
+        #ifndef WOLFSSL_AEAD_ONLY
+            if (ssl->specs.cipher_type != aead
+            #if defined(HAVE_ENCRYPT_THEN_MAC) && !defined(WOLFSSL_AEAD_ONLY)
+                                               && !ssl->options.startedETMWrite
+            #endif
+                ) {
+            #ifdef HAVE_TRUNCATED_HMAC
+                if (ssl->truncated_hmac &&
+                                        ssl->specs.hash_size > args->digestSz) {
+                #ifdef WOLFSSL_SMALL_STACK
+                    byte* hmac;
+                #else
+                    byte  hmac[WC_MAX_DIGEST_SIZE];
+                #endif
+
+                #ifdef WOLFSSL_SMALL_STACK
+                    hmac = (byte*)XMALLOC(WC_MAX_DIGEST_SIZE, ssl->heap,
+                                                           DYNAMIC_TYPE_DIGEST);
+                    if (hmac == NULL)
+                        ERROR_OUT(MEMORY_E, exit_buildmsg);
+                #endif
+
+                    ret = ssl->hmac(ssl, hmac,
+                                     output + args->headerSz + args->ivSz, inSz,
+                                     -1, type, 0);
+                    XMEMCPY(output + args->idx, hmac, args->digestSz);
+
+                #ifdef WOLFSSL_SMALL_STACK
+                    XFREE(hmac, ssl->heap, DYNAMIC_TYPE_DIGEST);
+                #endif
+                }
+                else
+            #endif
+                {
+                    ret = ssl->hmac(ssl, output + args->idx, output +
+                                args->headerSz + args->ivSz, inSz, -1, type, 0);
+                }
+            }
+        #endif /* WOLFSSL_AEAD_ONLY */
+            if (ret != 0)
+                goto exit_buildmsg;
+
+            ssl->options.buildMsgState = BUILD_MSG_ENCRYPT;
+        }
+        FALL_THROUGH;
+        case BUILD_MSG_ENCRYPT:
+        {
+    #if defined(HAVE_ENCRYPT_THEN_MAC) && !defined(WOLFSSL_AEAD_ONLY)
+            if (ssl->options.startedETMWrite) {
+                ret = Encrypt(ssl, output + args->headerSz,
+                                        output + args->headerSz,
+                                        args->size - args->digestSz, asyncOkay);
+            }
+            else
+    #endif
+            {
+                ret = Encrypt(ssl, output + args->headerSz,
+                                output + args->headerSz, args->size, asyncOkay);
+            }
+            if (ret != 0)
+                goto exit_buildmsg;
+            ssl->options.buildMsgState = BUILD_MSG_ENCRYPTED_VERIFY_MAC;
+        }
+        FALL_THROUGH;
+        case BUILD_MSG_ENCRYPTED_VERIFY_MAC:
+        {
+        #if defined(HAVE_ENCRYPT_THEN_MAC) && !defined(WOLFSSL_AEAD_ONLY)
+            if (ssl->options.startedETMWrite) {
+                WOLFSSL_MSG("Calculate MAC of Encrypted Data");
+
+            #ifdef HAVE_TRUNCATED_HMAC
+                if (ssl->truncated_hmac &&
+                                        ssl->specs.hash_size > args->digestSz) {
+                #ifdef WOLFSSL_SMALL_STACK
+                    byte* hmac = NULL;
+                #else
+                    byte  hmac[WC_MAX_DIGEST_SIZE];
+                #endif
+
+                #ifdef WOLFSSL_SMALL_STACK
+                    hmac = (byte*)XMALLOC(WC_MAX_DIGEST_SIZE, ssl->heap,
+                                                           DYNAMIC_TYPE_DIGEST);
+                    if (hmac == NULL)
+                        ERROR_OUT(MEMORY_E, exit_buildmsg);
+                #endif
+
+                    ret = ssl->hmac(ssl, hmac, output + args->headerSz,
+                                    args->ivSz + inSz + args->pad + 1, -1, type,
+                                    0);
+                    XMEMCPY(output + args->idx + args->pad + 1, hmac,
+                                                                args->digestSz);
+
+                #ifdef WOLFSSL_SMALL_STACK
+                    XFREE(hmac, ssl->heap, DYNAMIC_TYPE_DIGEST);
+                #endif
+                }
+                else
+            #endif
+                {
+                    ret = ssl->hmac(ssl, output + args->idx + args->pad + 1,
+                                    output + args->headerSz,
+                                    args->ivSz + inSz + args->pad + 1, -1, type,
+                                    0);
+                }
+            }
+        #endif /* HAVE_ENCRYPT_THEN_MAC && !WOLFSSL_AEAD_ONLY */
+        }
+    }
+
+exit_buildmsg:
+
+    WOLFSSL_LEAVE("BuildMessage", ret);
+
+#ifdef WOLFSSL_ASYNC_CRYPT
+    if (ret == WC_PENDING_E) {
+        return ret;
+    }
+#endif
+
+    /* make sure build message state is reset */
+    ssl->options.buildMsgState = BUILD_MSG_BEGIN;
+
+    #ifdef WOLFSSL_DTLS
+        if (ret == 0 && ssl->options.dtls)
+            DtlsSEQIncrement(ssl, CUR_ORDER);
+    #endif
+
+    /* return sz on success */
+    if (ret == 0)
+        ret = args->sz;
+
+    /* Final cleanup */
+    FreeBuildMsgArgs(ssl, args);
+#ifdef WOLFSSL_ASYNC_CRYPT
+    ssl->async.freeArgs = NULL;
+#endif
+
+    return ret;
+#endif /* !WOLFSSL_NO_TLS12 */
+}
+
+#ifndef WOLFSSL_NO_TLS12
+
+int SendFinished(WOLFSSL* ssl)
+{
+    int              sendSz,
+                     finishedSz = ssl->options.tls ? TLS_FINISHED_SZ :
+                                                     FINISHED_SZ;
+    byte             input[FINISHED_SZ + DTLS_HANDSHAKE_HEADER_SZ];  /* max */
+    byte            *output;
+    Hashes*          hashes;
+    int              ret;
+    int              headerSz = HANDSHAKE_HEADER_SZ;
+    int              outputSz;
+
+    WOLFSSL_START(WC_FUNC_FINISHED_SEND);
+    WOLFSSL_ENTER("SendFinished");
+
+    /* setup encrypt keys */
+    if ((ret = SetKeysSide(ssl, ENCRYPT_SIDE_ONLY)) != 0)
+        return ret;
+
+    #if defined(HAVE_ENCRYPT_THEN_MAC) && !defined(WOLFSSL_AEAD_ONLY)
+        ssl->options.startedETMWrite = ssl->options.encThenMac;
+    #endif
+
+    /* check for available size */
+    outputSz = sizeof(input) + MAX_MSG_EXTRA;
+    if ((ret = CheckAvailableSize(ssl, outputSz)) != 0)
+        return ret;
+
+    #ifdef WOLFSSL_DTLS
+        if (ssl->options.dtls) {
+            headerSz += DTLS_HANDSHAKE_EXTRA;
+            ssl->keys.dtls_epoch++;
+            ssl->keys.dtls_prev_sequence_number_hi =
+                    ssl->keys.dtls_sequence_number_hi;
+            ssl->keys.dtls_prev_sequence_number_lo =
+                    ssl->keys.dtls_sequence_number_lo;
+            ssl->keys.dtls_sequence_number_hi = 0;
+            ssl->keys.dtls_sequence_number_lo = 0;
+        }
+    #endif
+
+    /* get output buffer */
+    output = ssl->buffers.outputBuffer.buffer +
+             ssl->buffers.outputBuffer.length;
+
+    AddHandShakeHeader(input, finishedSz, 0, finishedSz, finished, ssl);
+
+    /* make finished hashes */
+    hashes = (Hashes*)&input[headerSz];
+    ret = BuildFinished(ssl, hashes,
+                     ssl->options.side == WOLFSSL_CLIENT_END ? client : server);
+    if (ret != 0) return ret;
+
+#ifdef HAVE_SECURE_RENEGOTIATION
+    if (ssl->secure_renegotiation) {
+        if (ssl->options.side == WOLFSSL_CLIENT_END)
+            XMEMCPY(ssl->secure_renegotiation->client_verify_data, hashes,
+                    TLS_FINISHED_SZ);
+        else
+            XMEMCPY(ssl->secure_renegotiation->server_verify_data, hashes,
+                    TLS_FINISHED_SZ);
+    }
+#endif
+
+    #ifdef WOLFSSL_DTLS
+        if (IsDtlsNotSctpMode(ssl)) {
+            if ((ret = DtlsMsgPoolSave(ssl, input, headerSz + finishedSz)) != 0)
+                return ret;
+        }
+    #endif
+
+    sendSz = BuildMessage(ssl, output, outputSz, input, headerSz + finishedSz,
+                                                          handshake, 1, 0, 0);
+    if (sendSz < 0)
+        return BUILD_MSG_ERROR;
+
+    if (!ssl->options.resuming) {
+#ifndef NO_SESSION_CACHE
+        AddSession(ssl);    /* just try */
+#endif
+        if (ssl->options.side == WOLFSSL_SERVER_END) {
+        #ifdef OPENSSL_EXTRA
+            ssl->options.serverState = SERVER_FINISHED_COMPLETE;
+            ssl->cbmode = SSL_CB_MODE_WRITE;
+            if (ssl->CBIS != NULL)
+                ssl->CBIS(ssl, SSL_CB_HANDSHAKE_DONE, SSL_SUCCESS);
+        #endif
+            ssl->options.handShakeState = HANDSHAKE_DONE;
+            ssl->options.handShakeDone  = 1;
+        }
+    }
+    else {
+        if (ssl->options.side == WOLFSSL_CLIENT_END) {
+        #ifdef OPENSSL_EXTRA
+            ssl->options.clientState = CLIENT_FINISHED_COMPLETE;
+            ssl->cbmode = SSL_CB_MODE_WRITE;
+            if (ssl->CBIS != NULL)
+                ssl->CBIS(ssl, SSL_CB_HANDSHAKE_DONE, SSL_SUCCESS);
+        #endif
+            ssl->options.handShakeState = HANDSHAKE_DONE;
+            ssl->options.handShakeDone  = 1;
+        }
+    }
+
+    #if defined(WOLFSSL_CALLBACKS) || defined(OPENSSL_EXTRA)
+        if (ssl->hsInfoOn) AddPacketName(ssl, "Finished");
+        if (ssl->toInfoOn)
+            AddPacketInfo(ssl, "Finished", handshake, output, sendSz,
+                          WRITE_PROTO, ssl->heap);
+    #endif
+
+    ssl->buffers.outputBuffer.length += sendSz;
+
+    ret = SendBuffered(ssl);
+
+    WOLFSSL_LEAVE("SendFinished", ret);
+    WOLFSSL_END(WC_FUNC_FINISHED_SEND);
+
+    return ret;
+}
+#endif /* WOLFSSL_NO_TLS12 */
+
+#ifndef NO_WOLFSSL_SERVER
+#if (!defined(WOLFSSL_NO_TLS12) && \
+        (defined(HAVE_CERTIFICATE_STATUS_REQUEST) || \
+         defined(HAVE_CERTIFICATE_STATUS_REQUEST_V2))) || \
+    (defined(WOLFSSL_TLS13) && defined(HAVE_CERTIFICATE_STATUS_REQUEST))
+/* Parses and decodes the certificate then initializes "request". In the case
+ * of !ssl->buffers.weOwnCert, ssl->ctx->certOcspRequest gets set to "request".
+ *
+ * Returns 0 on success
+ */
+static int CreateOcspRequest(WOLFSSL* ssl, OcspRequest* request,
+                             DecodedCert* cert, byte* certData, word32 length)
+{
+    int ret;
+
+    if (request != NULL)
+        XMEMSET(request, 0, sizeof(OcspRequest));
+
+    InitDecodedCert(cert, certData, length, ssl->heap);
+    /* TODO: Setup async support here */
+    ret = ParseCertRelative(cert, CERT_TYPE, VERIFY, ssl->ctx->cm);
+    if (ret != 0) {
+        WOLFSSL_MSG("ParseCert failed");
+    }
+    if (ret == 0)
+        ret = InitOcspRequest(request, cert, 0, ssl->heap);
+    if (ret == 0) {
+        /* make sure ctx OCSP request is updated */
+        if (!ssl->buffers.weOwnCert) {
+            wolfSSL_Mutex* ocspLock = &ssl->ctx->cm->ocsp_stapling->ocspLock;
+            if (wc_LockMutex(ocspLock) == 0) {
+                if (ssl->ctx->certOcspRequest == NULL)
+                    ssl->ctx->certOcspRequest = request;
+                wc_UnLockMutex(ocspLock);
+            }
+        }
+    }
+
+    FreeDecodedCert(cert);
+
+    return ret;
+}
+
+
+/* Creates OCSP response and places it in variable "response". Memory
+ * management for "buffer* response" is up to the caller.
+ *
+ * Also creates an OcspRequest in the case that ocspRequest is null or that
+ * ssl->buffers.weOwnCert is set. In those cases managing ocspRequest free'ing
+ * is up to the caller. NOTE: in OcspCreateRequest ssl->ctx->certOcspRequest can
+ * be set to point to "ocspRequest" and it then should not be free'd since
+ * wolfSSL_CTX_free will take care of it.
+ *
+ * Returns 0 on success
+ */
+int CreateOcspResponse(WOLFSSL* ssl, OcspRequest** ocspRequest,
+                       buffer* response)
+{
+    int          ret = 0;
+    OcspRequest* request = NULL;
+    byte createdRequest  = 0;
+
+    if (ssl == NULL || ocspRequest == NULL || response == NULL)
+        return BAD_FUNC_ARG;
+
+    XMEMSET(response, 0, sizeof(*response));
+    request = *ocspRequest;
+
+    /* unable to fetch status. skip. */
+    if (ssl->ctx->cm == NULL || ssl->ctx->cm->ocspStaplingEnabled == 0)
+        return 0;
+
+    if (request == NULL || ssl->buffers.weOwnCert) {
+        DerBuffer* der = ssl->buffers.certificate;
+        #ifdef WOLFSSL_SMALL_STACK
+            DecodedCert* cert = NULL;
+        #else
+            DecodedCert  cert[1];
+        #endif
+
+        /* unable to fetch status. skip. */
+        if (der->buffer == NULL || der->length == 0)
+            return 0;
+
+    #ifdef WOLFSSL_SMALL_STACK
+        cert = (DecodedCert*)XMALLOC(sizeof(DecodedCert), ssl->heap,
+                                        DYNAMIC_TYPE_DCERT);
+        if (cert == NULL)
+            return MEMORY_E;
+    #endif
+        request = (OcspRequest*)XMALLOC(sizeof(OcspRequest), ssl->heap,
+                                                     DYNAMIC_TYPE_OCSP_REQUEST);
+        if (request == NULL)
+            ret = MEMORY_E;
+
+        createdRequest = 1;
+        if (ret == 0) {
+            ret = CreateOcspRequest(ssl, request, cert, der->buffer,
+                                                                   der->length);
+        }
+
+        if (ret != 0) {
+            XFREE(request, ssl->heap, DYNAMIC_TYPE_OCSP_REQUEST);
+            request = NULL;
+        }
+
+    #ifdef WOLFSSL_SMALL_STACK
+        XFREE(cert, ssl->heap, DYNAMIC_TYPE_DCERT);
+    #endif
+    }
+
+    if (ret == 0) {
+        request->ssl = ssl;
+        ret = CheckOcspRequest(ssl->ctx->cm->ocsp_stapling, request, response);
+
+        /* Suppressing, not critical */
+        if (ret == OCSP_CERT_REVOKED ||
+            ret == OCSP_CERT_UNKNOWN ||
+            ret == OCSP_LOOKUP_FAIL) {
+            ret = 0;
+        }
+    }
+
+    /* free request up if error case found otherwise return it */
+    if (ret != 0 && createdRequest) {
+        FreeOcspRequest(request);
+        XFREE(request, ssl->heap, DYNAMIC_TYPE_OCSP_REQUEST);
+    }
+
+    if (ret == 0)
+        *ocspRequest = request;
+
+    return ret;
+}
+#endif
+#endif /* !NO_WOLFSSL_SERVER */
+
+#ifndef WOLFSSL_NO_TLS12
+
+#ifndef NO_CERTS
+#if !defined(NO_WOLFSSL_SERVER) || !defined(WOLFSSL_NO_CLIENT_AUTH)
+/* handle generation of certificate (11) */
+int SendCertificate(WOLFSSL* ssl)
+{
+    int    ret = 0;
+    word32 certSz, certChainSz, headerSz, listSz, payloadSz;
+    word32 length, maxFragment;
+
+    WOLFSSL_START(WC_FUNC_CERTIFICATE_SEND);
+    WOLFSSL_ENTER("SendCertificate");
+
+    if (ssl->options.usingPSK_cipher || ssl->options.usingAnon_cipher)
+        return 0;  /* not needed */
+
+    if (ssl->options.sendVerify == SEND_BLANK_CERT) {
+    #ifdef OPENSSL_EXTRA
+        if (ssl->version.major == SSLv3_MAJOR
+            && ssl->version.minor == SSLv3_MINOR){
+            SendAlert(ssl, alert_warning, no_certificate);
+            return 0;
+        } else {
+    #endif
+            certSz = 0;
+            certChainSz = 0;
+            headerSz = CERT_HEADER_SZ;
+            length = CERT_HEADER_SZ;
+            listSz = 0;
+    #ifdef OPENSSL_EXTRA
+        }
+    #endif
+    }
+    else {
+        if (!ssl->buffers.certificate) {
+            WOLFSSL_MSG("Send Cert missing certificate buffer");
+            return BUFFER_ERROR;
+        }
+        certSz = ssl->buffers.certificate->length;
+        headerSz = 2 * CERT_HEADER_SZ;
+        /* list + cert size */
+        length = certSz + headerSz;
+        listSz = certSz + CERT_HEADER_SZ;
+
+        /* may need to send rest of chain, already has leading size(s) */
+        if (certSz && ssl->buffers.certChain) {
+            certChainSz = ssl->buffers.certChain->length;
+            length += certChainSz;
+            listSz += certChainSz;
+        }
+        else
+            certChainSz = 0;
+    }
+
+    payloadSz = length;
+
+    if (ssl->fragOffset != 0)
+        length -= (ssl->fragOffset + headerSz);
+
+    maxFragment = MAX_RECORD_SIZE;
+
+    if (ssl->options.dtls) {
+    #ifdef WOLFSSL_DTLS
+        /* The 100 bytes is used to account for the UDP and IP headers.
+           It can also include the record padding and MAC if the
+           SendCertificate is called for a secure renegotiation. */
+        maxFragment = MAX_MTU - DTLS_RECORD_HEADER_SZ
+                      - DTLS_HANDSHAKE_HEADER_SZ - 100;
+    #endif /* WOLFSSL_DTLS */
+    }
+
+    maxFragment = wolfSSL_GetMaxRecordSize(ssl, maxFragment);
+
+    while (length > 0 && ret == 0) {
+        byte*  output = NULL;
+        word32 fragSz = 0;
+        word32 i = RECORD_HEADER_SZ;
+        int    sendSz = RECORD_HEADER_SZ;
+
+        if (!ssl->options.dtls) {
+            if (ssl->fragOffset == 0)  {
+                if (headerSz + certSz + certChainSz <=
+                    maxFragment - HANDSHAKE_HEADER_SZ) {
+
+                    fragSz = headerSz + certSz + certChainSz;
+                }
+                else {
+                    fragSz = maxFragment - HANDSHAKE_HEADER_SZ;
+                }
+                sendSz += fragSz + HANDSHAKE_HEADER_SZ;
+                i += HANDSHAKE_HEADER_SZ;
+            }
+            else {
+                fragSz = min(length, maxFragment);
+                sendSz += fragSz;
+            }
+
+            if (IsEncryptionOn(ssl, 1))
+                sendSz += MAX_MSG_EXTRA;
+        }
+        else {
+        #ifdef WOLFSSL_DTLS
+            fragSz = min(length, maxFragment);
+            sendSz += fragSz + DTLS_RECORD_EXTRA + DTLS_HANDSHAKE_EXTRA
+                      + HANDSHAKE_HEADER_SZ;
+            i      += DTLS_RECORD_EXTRA + DTLS_HANDSHAKE_EXTRA
+                      + HANDSHAKE_HEADER_SZ;
+        #endif
+        }
+
+        /* check for available size */
+        if ((ret = CheckAvailableSize(ssl, sendSz)) != 0)
+            return ret;
+
+        /* get output buffer */
+        output = ssl->buffers.outputBuffer.buffer +
+                 ssl->buffers.outputBuffer.length;
+
+        if (ssl->fragOffset == 0) {
+            if (!ssl->options.dtls) {
+                AddFragHeaders(output, fragSz, 0, payloadSz, certificate, ssl);
+                if (!IsEncryptionOn(ssl, 1))
+                    HashOutputRaw(ssl, output + RECORD_HEADER_SZ,
+                                  HANDSHAKE_HEADER_SZ);
+            }
+            else {
+            #ifdef WOLFSSL_DTLS
+                AddHeaders(output, payloadSz, certificate, ssl);
+                if (!IsEncryptionOn(ssl, 1))
+                    HashOutputRaw(ssl,
+                                  output + RECORD_HEADER_SZ + DTLS_RECORD_EXTRA,
+                                  HANDSHAKE_HEADER_SZ + DTLS_HANDSHAKE_EXTRA);
+                /* Adding the headers increments these, decrement them for
+                 * actual message header. */
+                ssl->keys.dtls_handshake_number--;
+                AddFragHeaders(output, fragSz, 0, payloadSz, certificate, ssl);
+                ssl->keys.dtls_handshake_number--;
+            #endif /* WOLFSSL_DTLS */
+            }
+
+            /* list total */
+            c32to24(listSz, output + i);
+            if (!IsEncryptionOn(ssl, 1))
+                HashOutputRaw(ssl, output + i, CERT_HEADER_SZ);
+            i += CERT_HEADER_SZ;
+            length -= CERT_HEADER_SZ;
+            fragSz -= CERT_HEADER_SZ;
+            if (certSz) {
+                c32to24(certSz, output + i);
+                if (!IsEncryptionOn(ssl, 1))
+                    HashOutputRaw(ssl, output + i, CERT_HEADER_SZ);
+                i += CERT_HEADER_SZ;
+                length -= CERT_HEADER_SZ;
+                fragSz -= CERT_HEADER_SZ;
+
+                if (!IsEncryptionOn(ssl, 1)) {
+                    HashOutputRaw(ssl, ssl->buffers.certificate->buffer, certSz);
+                    if (certChainSz)
+                        HashOutputRaw(ssl, ssl->buffers.certChain->buffer,
+                                      certChainSz);
+                }
+            }
+        }
+        else {
+            if (!ssl->options.dtls) {
+                AddRecordHeader(output, fragSz, handshake, ssl);
+            }
+            else {
+            #ifdef WOLFSSL_DTLS
+                AddFragHeaders(output, fragSz, ssl->fragOffset + headerSz,
+                               payloadSz, certificate, ssl);
+                ssl->keys.dtls_handshake_number--;
+            #endif /* WOLFSSL_DTLS */
+            }
+        }
+
+        /* member */
+        if (certSz && ssl->fragOffset < certSz) {
+            word32 copySz = min(certSz - ssl->fragOffset, fragSz);
+            XMEMCPY(output + i,
+                    ssl->buffers.certificate->buffer + ssl->fragOffset, copySz);
+            i += copySz;
+            ssl->fragOffset += copySz;
+            length -= copySz;
+            fragSz -= copySz;
+        }
+        if (certChainSz && fragSz) {
+            word32 copySz = min(certChainSz + certSz - ssl->fragOffset, fragSz);
+            XMEMCPY(output + i,
+                    ssl->buffers.certChain->buffer + ssl->fragOffset - certSz,
+                    copySz);
+            i += copySz;
+            ssl->fragOffset += copySz;
+            length -= copySz;
+        }
+
+        if (IsEncryptionOn(ssl, 1)) {
+            byte* input = NULL;
+            int   inputSz = i - RECORD_HEADER_SZ; /* build msg adds rec hdr */
+
+            if (inputSz < 0) {
+                WOLFSSL_MSG("Send Cert bad inputSz");
+                return BUFFER_E;
+            }
+
+            if (inputSz > 0) {  /* clang thinks could be zero, let's help */
+                input = (byte*)XMALLOC(inputSz, ssl->heap,
+                                       DYNAMIC_TYPE_IN_BUFFER);
+                if (input == NULL)
+                    return MEMORY_E;
+                XMEMCPY(input, output + RECORD_HEADER_SZ, inputSz);
+            }
+
+            sendSz = BuildMessage(ssl, output, sendSz, input, inputSz,
+                                                          handshake, 1, 0, 0);
+
+            if (inputSz > 0)
+                XFREE(input, ssl->heap, DYNAMIC_TYPE_IN_BUFFER);
+
+            if (sendSz < 0)
+                return sendSz;
+        }
+        else {
+        #ifdef WOLFSSL_DTLS
+            if (ssl->options.dtls)
+                DtlsSEQIncrement(ssl, CUR_ORDER);
+        #endif
+        }
+
+    #ifdef WOLFSSL_DTLS
+        if (IsDtlsNotSctpMode(ssl)) {
+            if ((ret = DtlsMsgPoolSave(ssl, output, sendSz)) != 0)
+                return ret;
+        }
+    #endif
+
+    #if defined(WOLFSSL_CALLBACKS) || defined(OPENSSL_EXTRA)
+        if (ssl->hsInfoOn)
+            AddPacketName(ssl, "Certificate");
+        if (ssl->toInfoOn)
+            AddPacketInfo(ssl, "Certificate", handshake, output, sendSz,
+                           WRITE_PROTO, ssl->heap);
+    #endif
+
+        ssl->buffers.outputBuffer.length += sendSz;
+        if (!ssl->options.groupMessages)
+            ret = SendBuffered(ssl);
+    }
+
+    if (ret != WANT_WRITE) {
+        /* Clean up the fragment offset. */
+        ssl->fragOffset = 0;
+        #ifdef WOLFSSL_DTLS
+            if (ssl->options.dtls)
+                ssl->keys.dtls_handshake_number++;
+        #endif
+        if (ssl->options.side == WOLFSSL_SERVER_END){
+            ssl->options.serverState = SERVER_CERT_COMPLETE;
+        }
+    }
+
+    WOLFSSL_LEAVE("SendCertificate", ret);
+    WOLFSSL_END(WC_FUNC_CERTIFICATE_SEND);
+
+    return ret;
+}
+#endif /* !NO_WOLFSSL_SERVER || !WOLFSSL_NO_CLIENT_AUTH */
+
+/* handle generation of certificate_request (13) */
+int SendCertificateRequest(WOLFSSL* ssl)
+{
+    byte   *output;
+    int    ret;
+    int    sendSz;
+    word32 i = RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ;
+    word32 dnLen = 0;
+#if defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX)
+    WOLF_STACK_OF(WOLFSSL_X509_NAME)* names;
+#endif
+
+    int  typeTotal = 1;  /* only 1 for now */
+    int  reqSz = ENUM_LEN + typeTotal + REQ_HEADER_SZ;  /* add auth later */
+
+    WOLFSSL_START(WC_FUNC_CERTIFICATE_REQUEST_SEND);
+    WOLFSSL_ENTER("SendCertificateRequest");
+
+    if (IsAtLeastTLSv1_2(ssl))
+        reqSz += LENGTH_SZ + ssl->suites->hashSigAlgoSz;
+
+#if defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX)
+    /* Certificate Authorities */
+    names = ssl->ctx->ca_names;
+    while (names != NULL) {
+        byte seq[MAX_SEQ_SZ];
+
+        /* 16-bit length | SEQ | Len | DER of name */
+        dnLen += OPAQUE16_LEN + SetSequence(names->data.name->rawLen, seq) +
+                 names->data.name->rawLen;
+        names = names->next;
+    }
+    reqSz += dnLen;
+#endif
+
+    if (ssl->options.usingPSK_cipher || ssl->options.usingAnon_cipher)
+        return 0;  /* not needed */
+
+    sendSz = RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ + reqSz;
+
+    if (!ssl->options.dtls) {
+        if (IsEncryptionOn(ssl, 1))
+            sendSz += MAX_MSG_EXTRA;
+    }
+    else {
+    #ifdef WOLFSSL_DTLS
+        sendSz += DTLS_RECORD_EXTRA + DTLS_HANDSHAKE_EXTRA;
+        i      += DTLS_RECORD_EXTRA + DTLS_HANDSHAKE_EXTRA;
+    #endif
+    }
+    /* check for available size */
+    if ((ret = CheckAvailableSize(ssl, sendSz)) != 0)
+        return ret;
+
+    /* get output buffer */
+    output = ssl->buffers.outputBuffer.buffer +
+             ssl->buffers.outputBuffer.length;
+
+    AddHeaders(output, reqSz, certificate_request, ssl);
+
+    /* write to output */
+    output[i++] = (byte)typeTotal;  /* # of types */
+#ifdef HAVE_ECC
+    if ((ssl->options.cipherSuite0 == ECC_BYTE ||
+         ssl->options.cipherSuite0 == CHACHA_BYTE) &&
+                     ssl->specs.sig_algo == ecc_dsa_sa_algo) {
+        output[i++] = ecdsa_sign;
+    } else
+#endif /* HAVE_ECC */
+    {
+        output[i++] = rsa_sign;
+    }
+
+    /* supported hash/sig */
+    if (IsAtLeastTLSv1_2(ssl)) {
+        c16toa(ssl->suites->hashSigAlgoSz, &output[i]);
+        i += OPAQUE16_LEN;
+
+        XMEMCPY(&output[i],
+                         ssl->suites->hashSigAlgo, ssl->suites->hashSigAlgoSz);
+        i += ssl->suites->hashSigAlgoSz;
+    }
+
+    /* Certificate Authorities */
+    c16toa((word16)dnLen, &output[i]);  /* auth's */
+    i += REQ_HEADER_SZ;
+#if defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX)
+    names = ssl->ctx->ca_names;
+    while (names != NULL) {
+        byte seq[MAX_SEQ_SZ];
+
+        c16toa((word16)names->data.name->rawLen +
+               SetSequence(names->data.name->rawLen, seq), &output[i]);
+        i += OPAQUE16_LEN;
+        i += SetSequence(names->data.name->rawLen, output + i);
+        XMEMCPY(output + i, names->data.name->raw, names->data.name->rawLen);
+        i += names->data.name->rawLen;
+        names = names->next;
+    }
+#endif
+    (void)i;
+
+        if (IsEncryptionOn(ssl, 1)) {
+            byte* input;
+            int   inputSz = i - RECORD_HEADER_SZ; /* build msg adds rec hdr */
+
+            input = (byte*)XMALLOC(inputSz, ssl->heap, DYNAMIC_TYPE_IN_BUFFER);
+            if (input == NULL)
+                return MEMORY_E;
+
+            XMEMCPY(input, output + RECORD_HEADER_SZ, inputSz);
+            sendSz = BuildMessage(ssl, output, sendSz, input, inputSz,
+                                  handshake, 1, 0, 0);
+            XFREE(input, ssl->heap, DYNAMIC_TYPE_IN_BUFFER);
+
+            if (sendSz < 0)
+                return sendSz;
+        } else {
+            #ifdef WOLFSSL_DTLS
+                if (ssl->options.dtls)
+                    DtlsSEQIncrement(ssl, CUR_ORDER);
+                if (IsDtlsNotSctpMode(ssl)) {
+                    if ((ret = DtlsMsgPoolSave(ssl, output, sendSz)) != 0)
+                        return ret;
+                }
+            #endif
+            ret = HashOutput(ssl, output, sendSz, 0);
+            if (ret != 0)
+                return ret;
+        }
+
+    #if defined(WOLFSSL_CALLBACKS) || defined(OPENSSL_EXTRA)
+        if (ssl->hsInfoOn)
+            AddPacketName(ssl, "CertificateRequest");
+        if (ssl->toInfoOn)
+            AddPacketInfo(ssl, "CertificateRequest", handshake, output, sendSz,
+                    WRITE_PROTO, ssl->heap);
+    #endif
+    ssl->buffers.outputBuffer.length += sendSz;
+    if (ssl->options.groupMessages)
+        ret = 0;
+    else
+        ret = SendBuffered(ssl);
+
+    WOLFSSL_LEAVE("SendCertificateRequest", ret);
+    WOLFSSL_END(WC_FUNC_CERTIFICATE_REQUEST_SEND);
+
+    return ret;
+}
+
+#ifndef NO_WOLFSSL_SERVER
+#if defined(HAVE_CERTIFICATE_STATUS_REQUEST) \
+ || defined(HAVE_CERTIFICATE_STATUS_REQUEST_V2)
+static int BuildCertificateStatus(WOLFSSL* ssl, byte type, buffer* status,
+                                                                     byte count)
+{
+    byte*  output  = NULL;
+    word32 idx     = RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ;
+    word32 length  = ENUM_LEN;
+    int    sendSz  = 0;
+    int    ret     = 0;
+    int    i       = 0;
+
+    WOLFSSL_ENTER("BuildCertificateStatus");
+
+    switch (type) {
+        case WOLFSSL_CSR2_OCSP_MULTI:
+            length += OPAQUE24_LEN;
+            FALL_THROUGH; /* followed by */
+
+        case WOLFSSL_CSR2_OCSP:
+            for (i = 0; i < count; i++)
+                length += OPAQUE24_LEN + status[i].length;
+        break;
+
+        default:
+            return 0;
+    }
+
+    sendSz = idx + length;
+
+    if (ssl->keys.encryptionOn)
+        sendSz += MAX_MSG_EXTRA;
+
+    if ((ret = CheckAvailableSize(ssl, sendSz)) == 0) {
+        output = ssl->buffers.outputBuffer.buffer +
+                 ssl->buffers.outputBuffer.length;
+
+        AddHeaders(output, length, certificate_status, ssl);
+
+        output[idx++] = type;
+
+        if (type == WOLFSSL_CSR2_OCSP_MULTI) {
+            c32to24(length - (ENUM_LEN + OPAQUE24_LEN), output + idx);
+            idx += OPAQUE24_LEN;
+        }
+
+        for (i = 0; i < count; i++) {
+            c32to24(status[i].length, output + idx);
+            idx += OPAQUE24_LEN;
+
+            XMEMCPY(output + idx, status[i].buffer, status[i].length);
+            idx += status[i].length;
+        }
+
+        if (IsEncryptionOn(ssl, 1)) {
+            byte* input;
+            int   inputSz = idx - RECORD_HEADER_SZ;
+
+            input = (byte*)XMALLOC(inputSz, ssl->heap, DYNAMIC_TYPE_IN_BUFFER);
+            if (input == NULL)
+                return MEMORY_E;
+
+            XMEMCPY(input, output + RECORD_HEADER_SZ, inputSz);
+            sendSz = BuildMessage(ssl, output, sendSz, input, inputSz,
+                                                           handshake, 1, 0, 0);
+            XFREE(input, ssl->heap, DYNAMIC_TYPE_IN_BUFFER);
+
+            if (sendSz < 0)
+                ret = sendSz;
+        }
+        else {
+            #ifdef WOLFSSL_DTLS
+                if (ssl->options.dtls)
+                    DtlsSEQIncrement(ssl, CUR_ORDER);
+            #endif
+            ret = HashOutput(ssl, output, sendSz, 0);
+        }
+
+    #ifdef WOLFSSL_DTLS
+        if (ret == 0 && IsDtlsNotSctpMode(ssl))
+            ret = DtlsMsgPoolSave(ssl, output, sendSz);
+    #endif
+
+    #if defined(WOLFSSL_CALLBACKS) || defined(OPENSSL_EXTRA)
+        if (ret == 0 && ssl->hsInfoOn)
+            AddPacketName(ssl, "CertificateStatus");
+        if (ret == 0 && ssl->toInfoOn)
+            AddPacketInfo(ssl, "CertificateStatus", handshake, output, sendSz,
+                    WRITE_PROTO, ssl->heap);
+    #endif
+
+        if (ret == 0) {
+            ssl->buffers.outputBuffer.length += sendSz;
+            if (!ssl->options.groupMessages)
+                ret = SendBuffered(ssl);
+        }
+    }
+
+    WOLFSSL_LEAVE("BuildCertificateStatus", ret);
+    return ret;
+}
+#endif
+#endif /* NO_WOLFSSL_SERVER */
+
+/* handle generation of certificate_status (22) */
+int SendCertificateStatus(WOLFSSL* ssl)
+{
+    int ret = 0;
+    byte status_type = 0;
+
+    WOLFSSL_START(WC_FUNC_CERTIFICATE_STATUS_SEND);
+    WOLFSSL_ENTER("SendCertificateStatus");
+
+    (void) ssl;
+
+#ifdef HAVE_CERTIFICATE_STATUS_REQUEST
+    status_type = ssl->status_request;
+#endif
+
+#ifdef HAVE_CERTIFICATE_STATUS_REQUEST_V2
+    status_type = status_type ? status_type : ssl->status_request_v2;
+#endif
+
+    switch (status_type) {
+
+    #ifndef NO_WOLFSSL_SERVER
+    #if defined(HAVE_CERTIFICATE_STATUS_REQUEST) \
+     || defined(HAVE_CERTIFICATE_STATUS_REQUEST_V2)
+        /* case WOLFSSL_CSR_OCSP: */
+        case WOLFSSL_CSR2_OCSP:
+        {
+            OcspRequest* request = ssl->ctx->certOcspRequest;
+            buffer response;
+
+            ret = CreateOcspResponse(ssl, &request, &response);
+
+            /* if a request was successfully created and not stored in
+             * ssl->ctx then free it */
+            if (ret == 0 && request != ssl->ctx->certOcspRequest) {
+                FreeOcspRequest(request);
+                XFREE(request, ssl->heap, DYNAMIC_TYPE_OCSP_REQUEST);
+                request = NULL;
+            }
+
+            if (ret == 0 && response.buffer) {
+                ret = BuildCertificateStatus(ssl, status_type, &response, 1);
+
+                XFREE(response.buffer, ssl->heap, DYNAMIC_TYPE_OCSP_REQUEST);
+                response.buffer = NULL;
+            }
+            break;
+        }
+
+    #endif /* HAVE_CERTIFICATE_STATUS_REQUEST    */
+           /* HAVE_CERTIFICATE_STATUS_REQUEST_V2 */
+
+    #if defined HAVE_CERTIFICATE_STATUS_REQUEST_V2
+        case WOLFSSL_CSR2_OCSP_MULTI:
+        {
+            OcspRequest* request = ssl->ctx->certOcspRequest;
+            buffer responses[1 + MAX_CHAIN_DEPTH];
+            int i = 0;
+
+            XMEMSET(responses, 0, sizeof(responses));
+
+            ret = CreateOcspResponse(ssl, &request, &responses[0]);
+
+            /* if a request was successfully created and not stored in
+             * ssl->ctx then free it */
+            if (ret == 0 && request != ssl->ctx->certOcspRequest) {
+                FreeOcspRequest(request);
+                XFREE(request, ssl->heap, DYNAMIC_TYPE_OCSP_REQUEST);
+                request = NULL;
+            }
+
+            if (ret == 0 && (!ssl->ctx->chainOcspRequest[0]
+                                              || ssl->buffers.weOwnCertChain)) {
+                buffer der;
+                word32 idx = 0;
+            #ifdef WOLFSSL_SMALL_STACK
+                DecodedCert* cert;
+            #else
+                DecodedCert  cert[1];
+            #endif
+
+            #ifdef WOLFSSL_SMALL_STACK
+                cert = (DecodedCert*)XMALLOC(sizeof(DecodedCert), ssl->heap,
+                                                            DYNAMIC_TYPE_DCERT);
+                if (cert == NULL)
+                    return MEMORY_E;
+            #endif
+                request = (OcspRequest*)XMALLOC(sizeof(OcspRequest), ssl->heap,
+                                                     DYNAMIC_TYPE_OCSP_REQUEST);
+                if (request == NULL) {
+            #ifdef WOLFSSL_SMALL_STACK
+                    XFREE(cert, ssl->heap, DYNAMIC_TYPE_DCERT);
+            #endif
+                    return MEMORY_E;
+                }
+
+                while (idx + OPAQUE24_LEN < ssl->buffers.certChain->length) {
+                    c24to32(ssl->buffers.certChain->buffer + idx, &der.length);
+                    idx += OPAQUE24_LEN;
+
+                    der.buffer = ssl->buffers.certChain->buffer + idx;
+                    idx += der.length;
+
+                    if (idx > ssl->buffers.certChain->length)
+                        break;
+
+                    ret = CreateOcspRequest(ssl, request, cert, der.buffer,
+                                                                    der.length);
+                    if (ret == 0) {
+                        request->ssl = ssl;
+                        ret = CheckOcspRequest(ssl->ctx->cm->ocsp_stapling,
+                                                    request, &responses[i + 1]);
+
+                        /* Suppressing, not critical */
+                        if (ret == OCSP_CERT_REVOKED ||
+                            ret == OCSP_CERT_UNKNOWN ||
+                            ret == OCSP_LOOKUP_FAIL) {
+                            ret = 0;
+                        }
+
+
+                        i++;
+                        FreeOcspRequest(request);
+                    }
+                }
+
+                XFREE(request, ssl->heap, DYNAMIC_TYPE_OCSP_REQUEST);
+            #ifdef WOLFSSL_SMALL_STACK
+                XFREE(cert, ssl->heap, DYNAMIC_TYPE_DCERT);
+            #endif
+            }
+            else {
+                while (ret == 0 &&
+                            NULL != (request = ssl->ctx->chainOcspRequest[i])) {
+                    request->ssl = ssl;
+                    ret = CheckOcspRequest(ssl->ctx->cm->ocsp_stapling,
+                                                request, &responses[++i]);
+
+                    /* Suppressing, not critical */
+                    if (ret == OCSP_CERT_REVOKED ||
+                        ret == OCSP_CERT_UNKNOWN ||
+                        ret == OCSP_LOOKUP_FAIL) {
+                        ret = 0;
+                    }
+                }
+            }
+
+            if (responses[0].buffer) {
+                if (ret == 0) {
+                    ret = BuildCertificateStatus(ssl, status_type, responses,
+                                                                   (byte)i + 1);
+                }
+
+                for (i = 0; i < 1 + MAX_CHAIN_DEPTH; i++) {
+                    if (responses[i].buffer) {
+                        XFREE(responses[i].buffer, ssl->heap,
+                                                     DYNAMIC_TYPE_OCSP_REQUEST);
+                    }
+                }
+            }
+
+            break;
+        }
+    #endif /* HAVE_CERTIFICATE_STATUS_REQUEST_V2 */
+    #endif /* NO_WOLFSSL_SERVER */
+
+        default:
+            break;
+    }
+
+    WOLFSSL_LEAVE("SendCertificateStatus", ret);
+    WOLFSSL_END(WC_FUNC_CERTIFICATE_STATUS_SEND);
+
+    return ret;
+}
+
+#endif /* !NO_CERTS */
+
+#endif /* WOLFSSL_NO_TLS12 */
+
+
+/* If secure renegotiation is disabled, this will always return false.
+ * Otherwise it checks to see if we are currently renegotiating. */
+static WC_INLINE int IsSCR(WOLFSSL* ssl)
+{
+#ifndef HAVE_SECURE_RENEGOTIATION
+    (void)ssl;
+#else /* HAVE_SECURE_RENEGOTIATION */
+    if (ssl->secure_renegotiation &&
+            ssl->secure_renegotiation->enabled &&
+            ssl->options.handShakeState != HANDSHAKE_DONE)
+        return 1;
+#endif /* HAVE_SECURE_RENEGOTIATION */
+    return 0;
+}
+
+
+int SendData(WOLFSSL* ssl, const void* data, int sz)
+{
+    int sent = 0,  /* plainText size */
+        sendSz,
+        ret,
+        dtlsExtra = 0;
+    int groupMsgs = 0;
+
+    if (ssl->error == WANT_WRITE
+    #ifdef WOLFSSL_ASYNC_CRYPT
+        || ssl->error == WC_PENDING_E
+    #endif
+    ) {
+        ssl->error = 0;
+    }
+
+    /* don't allow write after decrypt or mac error */
+    if (ssl->error == VERIFY_MAC_ERROR || ssl->error == DECRYPT_ERROR) {
+        /* For DTLS allow these possible errors and allow the session
+            to continue despite them */
+        if (ssl->options.dtls) {
+            ssl->error = 0;
+        }
+        else {
+            WOLFSSL_MSG("Not allowing write after decrypt or mac error");
+            return WOLFSSL_FATAL_ERROR;
+        }
+    }
+
+#ifdef WOLFSSL_EARLY_DATA
+    if (ssl->earlyData != no_early_data) {
+        if (ssl->options.handShakeState == HANDSHAKE_DONE) {
+            WOLFSSL_MSG("handshake complete, trying to send early data");
+            return BUILD_MSG_ERROR;
+        }
+    #ifdef WOLFSSL_EARLY_DATA_GROUP
+        groupMsgs = 1;
+    #endif
+    }
+    else
+#endif
+    if (ssl->options.handShakeState != HANDSHAKE_DONE && !IsSCR(ssl)) {
+        int err;
+        WOLFSSL_MSG("handshake not complete, trying to finish");
+        if ( (err = wolfSSL_negotiate(ssl)) != WOLFSSL_SUCCESS) {
+        #ifdef WOLFSSL_ASYNC_CRYPT
+            /* if async would block return WANT_WRITE */
+            if (ssl->error == WC_PENDING_E) {
+                return WOLFSSL_CBIO_ERR_WANT_WRITE;
+            }
+        #endif
+            return  err;
+        }
+    }
+
+    /* last time system socket output buffer was full, try again to send */
+    if (!groupMsgs && ssl->buffers.outputBuffer.length > 0) {
+        WOLFSSL_MSG("output buffer was full, trying to send again");
+        if ( (ssl->error = SendBuffered(ssl)) < 0) {
+            WOLFSSL_ERROR(ssl->error);
+            if (ssl->error == SOCKET_ERROR_E && (ssl->options.connReset ||
+                                                 ssl->options.isClosed)) {
+                ssl->error = SOCKET_PEER_CLOSED_E;
+                WOLFSSL_ERROR(ssl->error);
+                return 0;  /* peer reset or closed */
+            }
+            return ssl->error;
+        }
+        else {
+            /* advance sent to previous sent + plain size just sent */
+            sent = ssl->buffers.prevSent + ssl->buffers.plainSz;
+            WOLFSSL_MSG("sent write buffered data");
+
+            if (sent > sz) {
+                WOLFSSL_MSG("error: write() after WANT_WRITE with short size");
+                return ssl->error = BAD_FUNC_ARG;
+            }
+        }
+    }
+
+#ifdef WOLFSSL_DTLS
+    if (ssl->options.dtls) {
+        dtlsExtra = DTLS_RECORD_EXTRA;
+    }
+#endif
+
+    for (;;) {
+        int   len;
+        byte* out;
+        byte* sendBuffer = (byte*)data + sent;  /* may switch on comp */
+        int   buffSz;                           /* may switch on comp */
+        int   outputSz;
+#ifdef HAVE_LIBZ
+        byte  *comp = NULL;
+#endif
+
+        if (sent == sz) break;
+
+        len = wolfSSL_GetMaxRecordSize(ssl, sz - sent);
+
+#ifdef WOLFSSL_DTLS
+        if (IsDtlsNotSctpMode(ssl)) {
+            len = min(len, MAX_UDP_SIZE);
+        }
+#endif
+        buffSz = len;
+
+        /* check for available size */
+        outputSz = len + COMP_EXTRA + dtlsExtra + MAX_MSG_EXTRA;
+        if ((ret = CheckAvailableSize(ssl, outputSz)) != 0)
+            return ssl->error = ret;
+
+        /* get output buffer */
+        out = ssl->buffers.outputBuffer.buffer +
+              ssl->buffers.outputBuffer.length;
+
+#ifdef HAVE_LIBZ
+        if (ssl->options.usingCompression) {
+            int comp_size = MAX_RECORD_SIZE + MAX_COMP_EXTRA;
+            comp = XMALLOC(comp_size, ssl->heap, DYNAMIC_TYPE_NONE);
+            if (comp == NULL)
+                return BUFFER_ERROR;
+            buffSz = myCompress(ssl, sendBuffer, buffSz, comp, comp_size);
+            if (buffSz < 0) {
+                return buffSz;
+            }
+            sendBuffer = comp;
+        }
+#endif
+        if (!ssl->options.tls1_3) {
+            sendSz = BuildMessage(ssl, out, outputSz, sendBuffer, buffSz,
+                                  application_data, 0, 0, 1);
+        }
+        else {
+#ifdef WOLFSSL_TLS13
+            sendSz = BuildTls13Message(ssl, out, outputSz, sendBuffer, buffSz,
+                                       application_data, 0, 0, 1);
+#else
+            sendSz = BUFFER_ERROR;
+#endif
+        }
+#ifdef HAVE_LIBZ
+        XFREE(comp, ssl->heap, DYNAMIC_TYPE_NONE);
+#endif
+        if (sendSz < 0) {
+        #ifdef WOLFSSL_ASYNC_CRYPT
+            if (sendSz == WC_PENDING_E)
+                ssl->error = sendSz;
+        #endif
+            return BUILD_MSG_ERROR;
+        }
+
+        ssl->buffers.outputBuffer.length += sendSz;
+
+        if ( (ssl->error = SendBuffered(ssl)) < 0) {
+            WOLFSSL_ERROR(ssl->error);
+            /* store for next call if WANT_WRITE or user embedSend() that
+               doesn't present like WANT_WRITE */
+            ssl->buffers.plainSz  = len;
+            ssl->buffers.prevSent = sent;
+            if (ssl->error == SOCKET_ERROR_E && (ssl->options.connReset ||
+                                                 ssl->options.isClosed)) {
+                ssl->error = SOCKET_PEER_CLOSED_E;
+                WOLFSSL_ERROR(ssl->error);
+                return 0;  /* peer reset or closed */
+            }
+            return ssl->error;
+        }
+
+        sent += len;
+
+        /* only one message per attempt */
+        if (ssl->options.partialWrite == 1) {
+            WOLFSSL_MSG("Partial Write on, only sending one record");
+            break;
+        }
+    }
+
+    return sent;
+}
+
+/* process input data */
+int ReceiveData(WOLFSSL* ssl, byte* output, int sz, int peek)
+{
+    int size;
+
+    WOLFSSL_ENTER("ReceiveData()");
+
+    /* reset error state */
+    if (ssl->error == WANT_READ
+    #ifdef WOLFSSL_ASYNC_CRYPT
+        || ssl->error == WC_PENDING_E
+    #endif
+    ) {
+        ssl->error = 0;
+    }
+
+#ifdef WOLFSSL_DTLS
+    if (ssl->options.dtls) {
+        /* In DTLS mode, we forgive some errors and allow the session
+         * to continue despite them. */
+        if (ssl->error == VERIFY_MAC_ERROR || ssl->error == DECRYPT_ERROR)
+            ssl->error = 0;
+    }
+#endif /* WOLFSSL_DTLS */
+
+    if (ssl->error != 0 && ssl->error != WANT_WRITE) {
+        WOLFSSL_MSG("User calling wolfSSL_read in error state, not allowed");
+        return ssl->error;
+    }
+
+#ifdef WOLFSSL_EARLY_DATA
+    if (ssl->earlyData != no_early_data) {
+    }
+    else
+#endif
+    if (ssl->options.handShakeState != HANDSHAKE_DONE) {
+        int err;
+        WOLFSSL_MSG("Handshake not complete, trying to finish");
+        if ( (err = wolfSSL_negotiate(ssl)) != WOLFSSL_SUCCESS) {
+        #ifdef WOLFSSL_ASYNC_CRYPT
+            /* if async would block return WANT_WRITE */
+            if (ssl->error == WC_PENDING_E) {
+                return WOLFSSL_CBIO_ERR_WANT_READ;
+            }
+        #endif
+            return  err;
+        }
+    }
+
+#ifdef HAVE_SECURE_RENEGOTIATION
+startScr:
+    if (ssl->secure_renegotiation && ssl->secure_renegotiation->startScr) {
+        int err;
+        WOLFSSL_MSG("Need to start scr, server requested");
+        if ( (err = wolfSSL_Rehandshake(ssl)) != WOLFSSL_SUCCESS)
+            return  err;
+        ssl->secure_renegotiation->startScr = 0;  /* only start once */
+    }
+#endif
+
+    while (ssl->buffers.clearOutputBuffer.length == 0) {
+        if ( (ssl->error = ProcessReply(ssl)) < 0) {
+            WOLFSSL_ERROR(ssl->error);
+            if (ssl->error == ZERO_RETURN) {
+                WOLFSSL_MSG("Zero return, no more data coming");
+                return 0;         /* no more data coming */
+            }
+            if (ssl->error == SOCKET_ERROR_E) {
+                if (ssl->options.connReset || ssl->options.isClosed) {
+                    WOLFSSL_MSG("Peer reset or closed, connection done");
+                    ssl->error = SOCKET_PEER_CLOSED_E;
+                    WOLFSSL_ERROR(ssl->error);
+                    return 0;     /* peer reset or closed */
+                }
+            }
+            return ssl->error;
+        }
+        #ifdef HAVE_SECURE_RENEGOTIATION
+            if (ssl->secure_renegotiation &&
+                ssl->secure_renegotiation->startScr) {
+                goto startScr;
+            }
+        #endif
+    }
+
+    if (sz < (int)ssl->buffers.clearOutputBuffer.length)
+        size = sz;
+    else
+        size = ssl->buffers.clearOutputBuffer.length;
+
+    XMEMCPY(output, ssl->buffers.clearOutputBuffer.buffer, size);
+
+    if (peek == 0) {
+        ssl->buffers.clearOutputBuffer.length -= size;
+        ssl->buffers.clearOutputBuffer.buffer += size;
+    }
+
+    if (ssl->buffers.clearOutputBuffer.length == 0 &&
+                                           ssl->buffers.inputBuffer.dynamicFlag)
+       ShrinkInputBuffer(ssl, NO_FORCED_FREE);
+
+    WOLFSSL_LEAVE("ReceiveData()", size);
+    return size;
+}
+
+
+/* send alert message */
+int SendAlert(WOLFSSL* ssl, int severity, int type)
+{
+    byte input[ALERT_SIZE];
+    byte *output;
+    int  sendSz;
+    int  ret;
+    int  outputSz;
+    int  dtlsExtra = 0;
+
+    WOLFSSL_ENTER("SendAlert");
+
+#ifdef HAVE_WRITE_DUP
+    if (ssl->dupWrite && ssl->dupSide == READ_DUP_SIDE) {
+        int notifyErr = 0;
+
+        WOLFSSL_MSG("Read dup side cannot write alerts, notifying sibling");
+
+        if (type == close_notify) {
+            notifyErr = ZERO_RETURN;
+        } else if (severity == alert_fatal) {
+            notifyErr = FATAL_ERROR;
+        }
+
+        if (notifyErr != 0) {
+            return NotifyWriteSide(ssl, notifyErr);
+        }
+
+        return 0;
+    }
+#endif
+
+    /* if sendalert is called again for nonblocking */
+    if (ssl->options.sendAlertState != 0) {
+        ret = SendBuffered(ssl);
+        if (ret == 0)
+            ssl->options.sendAlertState = 0;
+        return ret;
+    }
+
+   #ifdef OPENSSL_EXTRA
+        if (ssl->CBIS != NULL) {
+            ssl->CBIS(ssl, SSL_CB_ALERT, type);
+        }
+   #endif
+   #ifdef WOLFSSL_DTLS
+        if (ssl->options.dtls)
+           dtlsExtra = DTLS_RECORD_EXTRA;
+   #endif
+
+    /* check for available size */
+    outputSz = ALERT_SIZE + MAX_MSG_EXTRA + dtlsExtra;
+    if ((ret = CheckAvailableSize(ssl, outputSz)) != 0)
+        return ret;
+
+    /* Check output buffer */
+    if (ssl->buffers.outputBuffer.buffer == NULL)
+        return BUFFER_E;
+
+    /* get output buffer */
+    output = ssl->buffers.outputBuffer.buffer +
+             ssl->buffers.outputBuffer.length;
+
+    input[0] = (byte)severity;
+    input[1] = (byte)type;
+    ssl->alert_history.last_tx.code = type;
+    ssl->alert_history.last_tx.level = severity;
+    if (severity == alert_fatal) {
+        ssl->options.isClosed = 1;  /* Don't send close_notify */
+    }
+
+    /* only send encrypted alert if handshake actually complete, otherwise
+       other side may not be able to handle it */
+    if (IsEncryptionOn(ssl, 1) && (IsAtLeastTLSv1_3(ssl->version) ||
+                                                  ssl->options.handShakeDone)) {
+        sendSz = BuildMessage(ssl, output, outputSz, input, ALERT_SIZE, alert,
+                                                                       0, 0, 0);
+    }
+    else {
+
+        AddRecordHeader(output, ALERT_SIZE, alert, ssl);
+        output += RECORD_HEADER_SZ;
+        #ifdef WOLFSSL_DTLS
+            if (ssl->options.dtls)
+                output += DTLS_RECORD_EXTRA;
+        #endif
+        XMEMCPY(output, input, ALERT_SIZE);
+
+        sendSz = RECORD_HEADER_SZ + ALERT_SIZE;
+        #ifdef WOLFSSL_DTLS
+            if (ssl->options.dtls)
+                sendSz += DTLS_RECORD_EXTRA;
+        #endif
+    }
+    if (sendSz < 0)
+        return BUILD_MSG_ERROR;
+
+    #if defined(WOLFSSL_CALLBACKS) || defined(OPENSSL_EXTRA)
+        if (ssl->hsInfoOn)
+            AddPacketName(ssl, "Alert");
+        if (ssl->toInfoOn)
+            AddPacketInfo(ssl, "Alert", alert, output, sendSz, WRITE_PROTO,
+                    ssl->heap);
+    #endif
+
+    ssl->buffers.outputBuffer.length += sendSz;
+    ssl->options.sendAlertState = 1;
+
+    ret = SendBuffered(ssl);
+
+    WOLFSSL_LEAVE("SendAlert", ret);
+
+    return ret;
+}
+
+const char* wolfSSL_ERR_reason_error_string(unsigned long e)
+{
+#ifdef NO_ERROR_STRINGS
+
+    (void)e;
+    return "no support for error strings built in";
+
+#else
+
+    int error = (int)e;
+
+    /* pass to wolfCrypt */
+    if (error < MAX_CODE_E && error > MIN_CODE_E) {
+        return wc_GetErrorString(error);
+    }
+
+    switch (error) {
+
+#ifdef WOLFSSL_WPAS
+    case 0 :
+        return "ok";
+#endif
+
+    case UNSUPPORTED_SUITE :
+        return "unsupported cipher suite";
+
+    case INPUT_CASE_ERROR :
+        return "input state error";
+
+    case PREFIX_ERROR :
+        return "bad index to key rounds";
+
+    case MEMORY_ERROR :
+        return "out of memory";
+
+    case VERIFY_FINISHED_ERROR :
+        return "verify problem on finished";
+
+    case VERIFY_MAC_ERROR :
+        return "verify mac problem";
+
+    case PARSE_ERROR :
+        return "parse error on header";
+
+    case SIDE_ERROR :
+        return "wrong client/server type";
+
+    case NO_PEER_CERT :
+        return "peer didn't send cert";
+
+    case UNKNOWN_HANDSHAKE_TYPE :
+        return "weird handshake type";
+
+    case SOCKET_ERROR_E :
+        return "error state on socket";
+
+    case SOCKET_NODATA :
+        return "expected data, not there";
+
+    case INCOMPLETE_DATA :
+        return "don't have enough data to complete task";
+
+    case UNKNOWN_RECORD_TYPE :
+        return "unknown type in record hdr";
+
+    case DECRYPT_ERROR :
+        return "error during decryption";
+
+    case FATAL_ERROR :
+        return "received alert fatal error";
+
+    case ENCRYPT_ERROR :
+        return "error during encryption";
+
+    case FREAD_ERROR :
+        return "fread problem";
+
+    case NO_PEER_KEY :
+        return "need peer's key";
+
+    case NO_PRIVATE_KEY :
+        return "need the private key";
+
+    case NO_DH_PARAMS :
+        return "server missing DH params";
+
+    case RSA_PRIVATE_ERROR :
+        return "error during rsa priv op";
+
+    case MATCH_SUITE_ERROR :
+        return "can't match cipher suite";
+
+    case COMPRESSION_ERROR :
+        return "compression mismatch error";
+
+    case BUILD_MSG_ERROR :
+        return "build message failure";
+
+    case BAD_HELLO :
+        return "client hello malformed";
+
+    case DOMAIN_NAME_MISMATCH :
+        return "peer subject name mismatch";
+
+    case IPADDR_MISMATCH :
+        return "peer ip address mismatch";
+
+    case WANT_READ :
+    case WOLFSSL_ERROR_WANT_READ :
+        return "non-blocking socket wants data to be read";
+
+    case NOT_READY_ERROR :
+        return "handshake layer not ready yet, complete first";
+
+    case VERSION_ERROR :
+        return "record layer version error";
+
+    case WANT_WRITE :
+    case WOLFSSL_ERROR_WANT_WRITE :
+        return "non-blocking socket write buffer full";
+
+    case BUFFER_ERROR :
+        return "malformed buffer input error";
+
+    case VERIFY_CERT_ERROR :
+        return "verify problem on certificate";
+
+    case VERIFY_SIGN_ERROR :
+        return "verify problem based on signature";
+
+    case CLIENT_ID_ERROR :
+        return "psk client identity error";
+
+    case SERVER_HINT_ERROR:
+        return "psk server hint error";
+
+    case PSK_KEY_ERROR:
+        return "psk key callback error";
+
+    case NTRU_KEY_ERROR:
+        return "NTRU key error";
+
+    case NTRU_DRBG_ERROR:
+        return "NTRU drbg error";
+
+    case NTRU_ENCRYPT_ERROR:
+        return "NTRU encrypt error";
+
+    case NTRU_DECRYPT_ERROR:
+        return "NTRU decrypt error";
+
+    case GETTIME_ERROR:
+        return "gettimeofday() error";
+
+    case GETITIMER_ERROR:
+        return "getitimer() error";
+
+    case SIGACT_ERROR:
+        return "sigaction() error";
+
+    case SETITIMER_ERROR:
+        return "setitimer() error";
+
+    case LENGTH_ERROR:
+        return "record layer length error";
+
+    case PEER_KEY_ERROR:
+        return "cant decode peer key";
+
+    case ZERO_RETURN:
+    case WOLFSSL_ERROR_ZERO_RETURN:
+        return "peer sent close notify alert";
+
+    case ECC_CURVETYPE_ERROR:
+        return "Bad ECC Curve Type or unsupported";
+
+    case ECC_CURVE_ERROR:
+        return "Bad ECC Curve or unsupported";
+
+    case ECC_PEERKEY_ERROR:
+        return "Bad ECC Peer Key";
+
+    case ECC_MAKEKEY_ERROR:
+        return "ECC Make Key failure";
+
+    case ECC_EXPORT_ERROR:
+        return "ECC Export Key failure";
+
+    case ECC_SHARED_ERROR:
+        return "ECC DHE shared failure";
+
+    case NOT_CA_ERROR:
+        return "Not a CA by basic constraint error";
+
+    case HTTP_TIMEOUT:
+        return "HTTP timeout for OCSP or CRL req";
+
+    case BAD_CERT_MANAGER_ERROR:
+        return "Bad Cert Manager error";
+
+    case OCSP_CERT_REVOKED:
+        return "OCSP Cert revoked";
+
+    case CRL_CERT_REVOKED:
+        return "CRL Cert revoked";
+
+    case CRL_MISSING:
+        return "CRL missing, not loaded";
+
+    case MONITOR_SETUP_E:
+        return "CRL monitor setup error";
+
+    case THREAD_CREATE_E:
+        return "Thread creation problem";
+
+    case OCSP_NEED_URL:
+        return "OCSP need URL";
+
+    case OCSP_CERT_UNKNOWN:
+        return "OCSP Cert unknown";
+
+    case OCSP_LOOKUP_FAIL:
+        return "OCSP Responder lookup fail";
+
+    case MAX_CHAIN_ERROR:
+        return "Maximum Chain Depth Exceeded";
+
+    case COOKIE_ERROR:
+        return "DTLS Cookie Error";
+
+    case SEQUENCE_ERROR:
+        return "DTLS Sequence Error";
+
+    case SUITES_ERROR:
+        return "Suites Pointer Error";
+
+    case OUT_OF_ORDER_E:
+        return "Out of order message, fatal";
+
+    case BAD_KEA_TYPE_E:
+        return "Bad KEA type found";
+
+    case SANITY_CIPHER_E:
+        return "Sanity check on ciphertext failed";
+
+    case RECV_OVERFLOW_E:
+        return "Receive callback returned more than requested";
+
+    case GEN_COOKIE_E:
+        return "Generate Cookie Error";
+
+    case NO_PEER_VERIFY:
+        return "Need peer certificate verify Error";
+
+    case FWRITE_ERROR:
+        return "fwrite Error";
+
+    case CACHE_MATCH_ERROR:
+        return "Cache restore header match Error";
+
+    case UNKNOWN_SNI_HOST_NAME_E:
+        return "Unrecognized host name Error";
+
+    case UNKNOWN_MAX_FRAG_LEN_E:
+        return "Unrecognized max frag len Error";
+
+    case KEYUSE_SIGNATURE_E:
+        return "Key Use digitalSignature not set Error";
+
+    case KEYUSE_ENCIPHER_E:
+        return "Key Use keyEncipherment not set Error";
+
+    case EXTKEYUSE_AUTH_E:
+        return "Ext Key Use server/client auth not set Error";
+
+    case SEND_OOB_READ_E:
+        return "Send Callback Out of Bounds Read Error";
+
+    case SECURE_RENEGOTIATION_E:
+        return "Invalid Renegotiation Error";
+
+    case SESSION_TICKET_LEN_E:
+        return "Session Ticket Too Long Error";
+
+    case SESSION_TICKET_EXPECT_E:
+        return "Session Ticket Error";
+
+    case SESSION_SECRET_CB_E:
+        return "Session Secret Callback Error";
+
+    case NO_CHANGE_CIPHER_E:
+        return "Finished received from peer before Change Cipher Error";
+
+    case SANITY_MSG_E:
+        return "Sanity Check on message order Error";
+
+    case DUPLICATE_MSG_E:
+        return "Duplicate HandShake message Error";
+
+    case SNI_UNSUPPORTED:
+        return "Protocol version does not support SNI Error";
+
+    case SOCKET_PEER_CLOSED_E:
+        return "Peer closed underlying transport Error";
+
+    case BAD_TICKET_KEY_CB_SZ:
+        return "Bad user session ticket key callback Size Error";
+
+    case BAD_TICKET_MSG_SZ:
+        return "Bad session ticket message Size Error";
+
+    case BAD_TICKET_ENCRYPT:
+        return "Bad user ticket callback encrypt Error";
+
+    case DH_KEY_SIZE_E:
+        return "DH key too small Error";
+
+    case SNI_ABSENT_ERROR:
+        return "No Server Name Indication extension Error";
+
+    case RSA_SIGN_FAULT:
+        return "RSA Signature Fault Error";
+
+    case HANDSHAKE_SIZE_ERROR:
+        return "Handshake message too large Error";
+
+    case UNKNOWN_ALPN_PROTOCOL_NAME_E:
+        return "Unrecognized protocol name Error";
+
+    case BAD_CERTIFICATE_STATUS_ERROR:
+        return "Bad Certificate Status Message Error";
+
+    case OCSP_INVALID_STATUS:
+        return "Invalid OCSP Status Error";
+
+    case OCSP_WANT_READ:
+        return "OCSP nonblock wants read";
+
+    case RSA_KEY_SIZE_E:
+        return "RSA key too small";
+
+    case ECC_KEY_SIZE_E:
+        return "ECC key too small";
+
+    case DTLS_EXPORT_VER_E:
+        return "Version needs updated after code change or version mismatch";
+
+    case INPUT_SIZE_E:
+        return "Input size too large Error";
+
+    case CTX_INIT_MUTEX_E:
+        return "Initialize ctx mutex error";
+
+    case EXT_MASTER_SECRET_NEEDED_E:
+        return "Extended Master Secret must be enabled to resume EMS session";
+
+    case DTLS_POOL_SZ_E:
+        return "Maximum DTLS pool size exceeded";
+
+    case DECODE_E:
+        return "Decode handshake message error";
+
+    case WRITE_DUP_READ_E:
+        return "Write dup write side can't read error";
+
+    case WRITE_DUP_WRITE_E:
+        return "Write dup read side can't write error";
+
+    case INVALID_CERT_CTX_E:
+        return "Certificate context does not match request or not empty";
+
+    case BAD_KEY_SHARE_DATA:
+        return "The Key Share data contains group that wasn't in Client Hello";
+
+    case MISSING_HANDSHAKE_DATA:
+        return "The handshake message is missing required data";
+
+    case BAD_BINDER:
+        return "Binder value does not match value server calculated";
+
+    case EXT_NOT_ALLOWED:
+        return "Extension type not allowed in handshake message type";
+
+    case INVALID_PARAMETER:
+        return "The security parameter is invalid";
+
+    case UNSUPPORTED_EXTENSION:
+        return "TLS Extension not requested by the client";
+
+    case PRF_MISSING:
+        return "Pseudo-random function is not enabled";
+
+    case KEY_SHARE_ERROR:
+        return "Key share extension did not contain a valid named group";
+
+    case POST_HAND_AUTH_ERROR:
+        return "Client will not do post handshake authentication";
+
+    case HRR_COOKIE_ERROR:
+        return "Cookie does not match one sent in HelloRetryRequest";
+
+    case MCAST_HIGHWATER_CB_E:
+        return "Multicast highwater callback returned error";
+
+    case ALERT_COUNT_E:
+        return "Alert Count exceeded error";
+
+    case EXT_MISSING:
+        return "Required TLS extension missing";
+
+    case DTLS_RETX_OVER_TX:
+        return "DTLS interrupting flight transmit with retransmit";
+
+    case DH_PARAMS_NOT_FFDHE_E:
+        return "Server DH parameters were not from the FFDHE set as required";
+
+    case TCA_INVALID_ID_TYPE:
+        return "TLS Extension Trusted CA ID type invalid";
+
+    case TCA_ABSENT_ERROR:
+        return "TLS Extension Trusted CA ID response absent";
+
+    case TSIP_MAC_DIGSZ_E:
+        return "TSIP MAC size invalid, must be sized for SHA-1 or SHA-256";
+
+    case CLIENT_CERT_CB_ERROR:
+        return "Error importing client cert or key from callback";
+
+    case SSL_SHUTDOWN_ALREADY_DONE_E:
+        return "Shutdown has already occurred";
+
+    case TLS13_SECRET_CB_E:
+        return "TLS1.3 Secret Callback Error";
+
+    default :
+        return "unknown error number";
+    }
+
+#endif /* NO_ERROR_STRINGS */
+}
+
+void SetErrorString(int error, char* str)
+{
+    XSTRNCPY(str, wolfSSL_ERR_reason_error_string(error), WOLFSSL_MAX_ERROR_SZ);
+    str[WOLFSSL_MAX_ERROR_SZ-1] = 0;
+}
+
+#ifndef NO_ERROR_STRINGS
+    #if defined(OPENSSL_ALL) || defined(WOLFSSL_QT)
+        #define SUITE_INFO(x,y,z,w,v,u) {(x),(y),(z),(w),(v),(u)}
+    #else
+        #define SUITE_INFO(x,y,z,w,v,u) {(x),(y),(z),(w)}
+    #endif
+#else
+    #if defined(OPENSSL_ALL) || defined(WOLFSSL_QT)
+        #define SUITE_INFO(x,y,z,w,v,u) {(x),(z),(w),(v),(u)}
+    #else
+        #define SUITE_INFO(x,y,z,w,v,u) {(x),(z),(w)}
+    #endif
+#endif
+
+static const CipherSuiteInfo cipher_names[] =
+{
+
+#ifdef BUILD_TLS_AES_128_GCM_SHA256
+    SUITE_INFO("TLS13-AES128-GCM-SHA256","TLS_AES_128_GCM_SHA256",TLS13_BYTE,TLS_AES_128_GCM_SHA256, TLSv1_3_MINOR, SSLv3_MAJOR),
+#endif
+
+#ifdef BUILD_TLS_AES_256_GCM_SHA384
+    SUITE_INFO("TLS13-AES256-GCM-SHA384","TLS_AES_256_GCM_SHA384",TLS13_BYTE,TLS_AES_256_GCM_SHA384, TLSv1_3_MINOR, SSLv3_MAJOR),
+#endif
+
+#ifdef BUILD_TLS_CHACHA20_POLY1305_SHA256
+    SUITE_INFO("TLS13-CHACHA20-POLY1305-SHA256","TLS_CHACHA20_POLY1305_SHA256",TLS13_BYTE,TLS_CHACHA20_POLY1305_SHA256, TLSv1_3_MINOR, SSLv3_MAJOR),
+#endif
+
+#ifdef BUILD_TLS_AES_128_CCM_SHA256
+    SUITE_INFO("TLS13-AES128-CCM-SHA256","TLS_AES_128_CCM_SHA256",TLS13_BYTE,TLS_AES_128_CCM_SHA256, TLSv1_3_MINOR, SSLv3_MAJOR),
+#endif
+
+#ifdef BUILD_TLS_AES_128_CCM_8_SHA256
+    SUITE_INFO("TLS13-AES128-CCM-8-SHA256","TLS_AES_128_CCM_8_SHA256",TLS13_BYTE,TLS_AES_128_CCM_8_SHA256,TLSv1_3_MINOR, SSLv3_MAJOR),
+#endif
+
+#ifdef BUILD_TLS_SHA256_SHA256
+    SUITE_INFO("TLS13-SHA256-SHA256","TLS_SHA256_SHA256",ECC_BYTE,TLS_SHA256_SHA256,TLSv1_3_MINOR, SSLv3_MAJOR),
+#endif
+
+#ifdef BUILD_TLS_SHA384_SHA384
+    SUITE_INFO("TLS13-SHA384-SHA384","TLS_SHA384_SHA384",ECC_BYTE,TLS_SHA384_SHA384,TLSv1_3_MINOR, SSLv3_MAJOR),
+#endif
+
+#ifndef WOLFSSL_NO_TLS12
+
+#ifdef BUILD_SSL_RSA_WITH_RC4_128_SHA
+    SUITE_INFO("RC4-SHA","SSL_RSA_WITH_RC4_128_SHA",CIPHER_BYTE,SSL_RSA_WITH_RC4_128_SHA,SSLv3_MINOR,SSLv3_MAJOR),
+#endif
+
+#ifdef BUILD_SSL_RSA_WITH_RC4_128_MD5
+    SUITE_INFO("RC4-MD5","SSL_RSA_WITH_RC4_128_MD5",CIPHER_BYTE,SSL_RSA_WITH_RC4_128_MD5,SSLv3_MINOR,SSLv3_MAJOR),
+#endif
+
+#ifdef BUILD_SSL_RSA_WITH_3DES_EDE_CBC_SHA
+    SUITE_INFO("DES-CBC3-SHA","SSL_RSA_WITH_3DES_EDE_CBC_SHA",CIPHER_BYTE,SSL_RSA_WITH_3DES_EDE_CBC_SHA,SSLv3_MINOR,SSLv3_MAJOR),
+#endif
+
+#ifdef BUILD_TLS_RSA_WITH_AES_128_CBC_SHA
+    SUITE_INFO("AES128-SHA","TLS_RSA_WITH_AES_128_CBC_SHA",CIPHER_BYTE,TLS_RSA_WITH_AES_128_CBC_SHA,SSLv3_MINOR,SSLv3_MAJOR),
+#endif
+
+#ifdef BUILD_TLS_RSA_WITH_AES_256_CBC_SHA
+    SUITE_INFO("AES256-SHA","TLS_RSA_WITH_AES_256_CBC_SHA",CIPHER_BYTE,TLS_RSA_WITH_AES_256_CBC_SHA,SSLv3_MINOR,SSLv3_MAJOR),
+#endif
+
+#ifdef BUILD_TLS_RSA_WITH_NULL_MD5
+    SUITE_INFO("NULL-MD5","TLS_RSA_WITH_NULL_MD5",CIPHER_BYTE,TLS_RSA_WITH_NULL_MD5,SSLv3_MINOR,SSLv3_MAJOR),
+#endif
+
+#ifdef BUILD_TLS_RSA_WITH_NULL_SHA
+    SUITE_INFO("NULL-SHA","TLS_RSA_WITH_NULL_SHA",CIPHER_BYTE,TLS_RSA_WITH_NULL_SHA,SSLv3_MINOR,SSLv3_MAJOR),
+#endif
+
+#ifdef BUILD_TLS_RSA_WITH_NULL_SHA256
+    SUITE_INFO("NULL-SHA256","TLS_RSA_WITH_NULL_SHA256",CIPHER_BYTE,TLS_RSA_WITH_NULL_SHA256,TLSv1_2_MINOR,SSLv3_MAJOR),
+#endif
+
+#ifdef BUILD_TLS_DHE_RSA_WITH_AES_128_CBC_SHA
+    SUITE_INFO("DHE-RSA-AES128-SHA","TLS_DHE_RSA_WITH_AES_128_CBC_SHA",CIPHER_BYTE,TLS_DHE_RSA_WITH_AES_128_CBC_SHA,SSLv3_MINOR,SSLv3_MAJOR),
+#endif
+
+#ifdef BUILD_TLS_DHE_RSA_WITH_AES_256_CBC_SHA
+    SUITE_INFO("DHE-RSA-AES256-SHA","TLS_DHE_RSA_WITH_AES_256_CBC_SHA",CIPHER_BYTE,TLS_DHE_RSA_WITH_AES_256_CBC_SHA,SSLv3_MINOR,SSLv3_MAJOR),
+#endif
+
+#ifdef BUILD_TLS_DHE_PSK_WITH_AES_256_GCM_SHA384
+    SUITE_INFO("DHE-PSK-AES256-GCM-SHA384","TLS_DHE_PSK_WITH_AES_256_GCM_SHA384",CIPHER_BYTE,TLS_DHE_PSK_WITH_AES_256_GCM_SHA384,TLSv1_2_MINOR,SSLv3_MAJOR),
+#endif
+
+#ifdef BUILD_TLS_DHE_PSK_WITH_AES_128_GCM_SHA256
+    SUITE_INFO("DHE-PSK-AES128-GCM-SHA256","TLS_DHE_PSK_WITH_AES_128_GCM_SHA256",CIPHER_BYTE,TLS_DHE_PSK_WITH_AES_128_GCM_SHA256,TLSv1_2_MINOR,SSLv3_MAJOR),
+#endif
+
+#ifdef BUILD_TLS_PSK_WITH_AES_256_GCM_SHA384
+    SUITE_INFO("PSK-AES256-GCM-SHA384","TLS_PSK_WITH_AES_256_GCM_SHA384",CIPHER_BYTE,TLS_PSK_WITH_AES_256_GCM_SHA384,TLSv1_2_MINOR,SSLv3_MAJOR),
+#endif
+
+#ifdef BUILD_TLS_PSK_WITH_AES_128_GCM_SHA256
+    SUITE_INFO("PSK-AES128-GCM-SHA256","TLS_PSK_WITH_AES_128_GCM_SHA256",CIPHER_BYTE,TLS_PSK_WITH_AES_128_GCM_SHA256,TLSv1_2_MINOR,SSLv3_MAJOR),
+#endif
+
+#ifdef BUILD_TLS_DHE_PSK_WITH_AES_256_CBC_SHA384
+    SUITE_INFO("DHE-PSK-AES256-CBC-SHA384","TLS_DHE_PSK_WITH_AES_256_CBC_SHA384",CIPHER_BYTE,TLS_DHE_PSK_WITH_AES_256_CBC_SHA384,TLSv1_MINOR,SSLv3_MAJOR),
+#endif
+
+#ifdef BUILD_TLS_DHE_PSK_WITH_AES_128_CBC_SHA256
+    SUITE_INFO("DHE-PSK-AES128-CBC-SHA256","TLS_DHE_PSK_WITH_AES_128_CBC_SHA256",CIPHER_BYTE,TLS_DHE_PSK_WITH_AES_128_CBC_SHA256,TLSv1_MINOR,SSLv3_MAJOR),
+#endif
+
+#ifdef BUILD_TLS_PSK_WITH_AES_256_CBC_SHA384
+    SUITE_INFO("PSK-AES256-CBC-SHA384","TLS_PSK_WITH_AES_256_CBC_SHA384",CIPHER_BYTE,TLS_PSK_WITH_AES_256_CBC_SHA384,TLSv1_MINOR,SSLv3_MAJOR),
+#endif
+
+#ifdef BUILD_TLS_PSK_WITH_AES_128_CBC_SHA256
+    SUITE_INFO("PSK-AES128-CBC-SHA256","TLS_PSK_WITH_AES_128_CBC_SHA256",CIPHER_BYTE,TLS_PSK_WITH_AES_128_CBC_SHA256,TLSv1_MINOR,SSLv3_MAJOR),
+#endif
+
+#ifdef BUILD_TLS_PSK_WITH_AES_128_CBC_SHA
+    SUITE_INFO("PSK-AES128-CBC-SHA","TLS_PSK_WITH_AES_128_CBC_SHA",CIPHER_BYTE,TLS_PSK_WITH_AES_128_CBC_SHA,TLSv1_MINOR,SSLv3_MAJOR),
+#endif
+
+#ifdef BUILD_TLS_PSK_WITH_AES_256_CBC_SHA
+    SUITE_INFO("PSK-AES256-CBC-SHA","TLS_PSK_WITH_AES_256_CBC_SHA",CIPHER_BYTE,TLS_PSK_WITH_AES_256_CBC_SHA, TLSv1_MINOR, SSLv3_MAJOR),
+#endif
+
+#ifdef BUILD_TLS_DHE_PSK_WITH_AES_128_CCM
+    SUITE_INFO("DHE-PSK-AES128-CCM","TLS_DHE_PSK_WITH_AES_128_CCM",ECC_BYTE,TLS_DHE_PSK_WITH_AES_128_CCM,TLSv1_MINOR,SSLv3_MAJOR),
+#endif
+
+#ifdef BUILD_TLS_DHE_PSK_WITH_AES_256_CCM
+    SUITE_INFO("DHE-PSK-AES256-CCM","TLS_DHE_PSK_WITH_AES_256_CCM",ECC_BYTE,TLS_DHE_PSK_WITH_AES_256_CCM,TLSv1_MINOR,SSLv3_MAJOR),
+#endif
+
+#ifdef BUILD_TLS_PSK_WITH_AES_128_CCM
+    SUITE_INFO("PSK-AES128-CCM","TLS_PSK_WITH_AES_128_CCM",ECC_BYTE,TLS_PSK_WITH_AES_128_CCM,TLSv1_MINOR,SSLv3_MAJOR),
+#endif
+
+#ifdef BUILD_TLS_PSK_WITH_AES_256_CCM
+    SUITE_INFO("PSK-AES256-CCM","TLS_PSK_WITH_AES_256_CCM",ECC_BYTE,TLS_PSK_WITH_AES_256_CCM,TLSv1_MINOR,SSLv3_MAJOR),
+#endif
+
+#ifdef BUILD_TLS_PSK_WITH_AES_128_CCM_8
+    SUITE_INFO("PSK-AES128-CCM-8","TLS_PSK_WITH_AES_128_CCM_8",ECC_BYTE,TLS_PSK_WITH_AES_128_CCM_8,TLSv1_MINOR,SSLv3_MAJOR),
+#endif
+
+#ifdef BUILD_TLS_PSK_WITH_AES_256_CCM_8
+    SUITE_INFO("PSK-AES256-CCM-8","TLS_PSK_WITH_AES_256_CCM_8",ECC_BYTE,TLS_PSK_WITH_AES_256_CCM_8,TLSv1_MINOR,SSLv3_MAJOR),
+#endif
+
+#ifdef BUILD_TLS_DHE_PSK_WITH_NULL_SHA384
+    SUITE_INFO("DHE-PSK-NULL-SHA384","TLS_DHE_PSK_WITH_NULL_SHA384",CIPHER_BYTE,TLS_DHE_PSK_WITH_NULL_SHA384,TLSv1_MINOR,SSLv3_MAJOR),
+#endif
+
+#ifdef BUILD_TLS_DHE_PSK_WITH_NULL_SHA256
+    SUITE_INFO("DHE-PSK-NULL-SHA256","TLS_DHE_PSK_WITH_NULL_SHA256",CIPHER_BYTE,TLS_DHE_PSK_WITH_NULL_SHA256,TLSv1_MINOR,SSLv3_MAJOR),
+#endif
+
+#ifdef BUILD_TLS_PSK_WITH_NULL_SHA384
+    SUITE_INFO("PSK-NULL-SHA384","TLS_PSK_WITH_NULL_SHA384",CIPHER_BYTE,TLS_PSK_WITH_NULL_SHA384,TLSv1_MINOR,SSLv3_MAJOR),
+#endif
+
+#ifdef BUILD_TLS_PSK_WITH_NULL_SHA256
+    SUITE_INFO("PSK-NULL-SHA256","TLS_PSK_WITH_NULL_SHA256",CIPHER_BYTE,TLS_PSK_WITH_NULL_SHA256,TLSv1_MINOR,SSLv3_MAJOR),
+#endif
+
+#ifdef BUILD_TLS_PSK_WITH_NULL_SHA
+    SUITE_INFO("PSK-NULL-SHA","TLS_PSK_WITH_NULL_SHA",CIPHER_BYTE,TLS_PSK_WITH_NULL_SHA,TLSv1_MINOR,SSLv3_MAJOR),
+#endif
+
+#ifdef BUILD_TLS_RSA_WITH_HC_128_MD5
+    SUITE_INFO("HC128-MD5","TLS_RSA_WITH_HC_128_MD5",CIPHER_BYTE,TLS_RSA_WITH_HC_128_MD5,TLSv1_MINOR,SSLv3_MAJOR),
+#endif
+
+#ifdef BUILD_TLS_RSA_WITH_HC_128_SHA
+    SUITE_INFO("HC128-SHA","TLS_RSA_WITH_HC_128_SHA",CIPHER_BYTE,TLS_RSA_WITH_HC_128_SHA,TLSv1_MINOR,SSLv3_MAJOR),
+#endif
+
+#ifdef BUILD_TLS_RSA_WITH_RABBIT_SHA
+    SUITE_INFO("RABBIT-SHA","TLS_RSA_WITH_RABBIT_SHA",CIPHER_BYTE,TLS_RSA_WITH_RABBIT_SHA,TLSv1_MINOR,SSLv3_MAJOR),
+#endif
+
+#ifdef BUILD_TLS_NTRU_RSA_WITH_RC4_128_SHA
+    SUITE_INFO("NTRU-RC4-SHA","TLS_NTRU_RSA_WITH_RC4_128_SHA",CIPHER_BYTE,TLS_NTRU_RSA_WITH_RC4_128_SHA, TLSv1_MINOR, SSLv3_MAJOR),
+#endif
+
+#ifdef BUILD_TLS_NTRU_RSA_WITH_3DES_EDE_CBC_SHA
+    SUITE_INFO("NTRU-DES-CBC3-SHA","TLS_NTRU_RSA_WITH_3DES_EDE_CBC_SHA",CIPHER_BYTE,TLS_NTRU_RSA_WITH_3DES_EDE_CBC_SHA, TLSv1_MINOR, SSLv3_MAJOR),
+#endif
+
+#ifdef BUILD_TLS_NTRU_RSA_WITH_AES_128_CBC_SHA
+    SUITE_INFO("NTRU-AES128-SHA","TLS_NTRU_RSA_WITH_AES_128_CBC_SHA",CIPHER_BYTE,TLS_NTRU_RSA_WITH_AES_128_CBC_SHA, TLSv1_MINOR, SSLv3_MAJOR),
+#endif
+
+#ifdef BUILD_TLS_NTRU_RSA_WITH_AES_256_CBC_SHA
+    SUITE_INFO("NTRU-AES256-SHA","TLS_NTRU_RSA_WITH_AES_256_CBC_SHA",CIPHER_BYTE,TLS_NTRU_RSA_WITH_AES_256_CBC_SHA, TLSv1_MINOR, SSLv3_MAJOR),
+#endif
+
+#ifdef BUILD_TLS_RSA_WITH_AES_128_CCM_8
+    SUITE_INFO("AES128-CCM-8","TLS_RSA_WITH_AES_128_CCM_8",ECC_BYTE,TLS_RSA_WITH_AES_128_CCM_8, TLSv1_2_MINOR, SSLv3_MAJOR),
+#endif
+
+#ifdef BUILD_TLS_RSA_WITH_AES_256_CCM_8
+    SUITE_INFO("AES256-CCM-8","TLS_RSA_WITH_AES_256_CCM_8",ECC_BYTE,TLS_RSA_WITH_AES_256_CCM_8, TLSv1_2_MINOR, SSLv3_MAJOR),
+#endif
+
+#ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_128_CCM
+	SUITE_INFO("ECDHE-ECDSA-AES128-CCM","TLS_ECDHE_ECDSA_WITH_AES_128_CCM",ECC_BYTE,TLS_ECDHE_ECDSA_WITH_AES_128_CCM, TLSv1_2_MINOR, SSLv3_MAJOR),
+#endif
+
+#ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8
+    SUITE_INFO("ECDHE-ECDSA-AES128-CCM-8","TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8",ECC_BYTE,TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8, TLSv1_2_MINOR, SSLv3_MAJOR),
+#endif
+
+#ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8
+    SUITE_INFO("ECDHE-ECDSA-AES256-CCM-8","TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8",ECC_BYTE,TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8, TLSv1_2_MINOR, SSLv3_MAJOR),
+#endif
+
+#ifdef BUILD_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA
+    SUITE_INFO("ECDHE-RSA-AES128-SHA","TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA",ECC_BYTE,TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,TLSv1_MINOR,SSLv3_MAJOR),
+#endif
+
+#ifdef BUILD_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA
+    SUITE_INFO("ECDHE-RSA-AES256-SHA","TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA",ECC_BYTE,TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,TLSv1_MINOR,SSLv3_MAJOR),
+#endif
+
+#ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA
+    SUITE_INFO("ECDHE-ECDSA-AES128-SHA","TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA",ECC_BYTE,TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, TLSv1_MINOR, SSLv3_MAJOR),
+#endif
+
+#ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA
+    SUITE_INFO("ECDHE-ECDSA-AES256-SHA","TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA",ECC_BYTE,TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, TLSv1_MINOR, SSLv3_MAJOR),
+#endif
+
+#ifdef BUILD_TLS_ECDHE_RSA_WITH_RC4_128_SHA
+    SUITE_INFO("ECDHE-RSA-RC4-SHA","TLS_ECDHE_RSA_WITH_RC4_128_SHA",ECC_BYTE,TLS_ECDHE_RSA_WITH_RC4_128_SHA, TLSv1_MINOR, SSLv3_MAJOR),
+#endif
+
+#ifdef BUILD_TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA
+    SUITE_INFO("ECDHE-RSA-DES-CBC3-SHA","TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA",ECC_BYTE,TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, TLSv1_MINOR, SSLv3_MAJOR),
+#endif
+
+#ifdef BUILD_TLS_ECDHE_ECDSA_WITH_RC4_128_SHA
+    SUITE_INFO("ECDHE-ECDSA-RC4-SHA","TLS_ECDHE_ECDSA_WITH_RC4_128_SHA",ECC_BYTE,TLS_ECDHE_ECDSA_WITH_RC4_128_SHA, TLSv1_MINOR, SSLv3_MAJOR),
+#endif
+
+#ifdef BUILD_TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA
+    SUITE_INFO("ECDHE-ECDSA-DES-CBC3-SHA","TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA",ECC_BYTE,TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA, TLSv1_MINOR, SSLv3_MAJOR),
+#endif
+
+#ifdef BUILD_TLS_RSA_WITH_AES_128_CBC_SHA256
+    SUITE_INFO("AES128-SHA256","TLS_RSA_WITH_AES_128_CBC_SHA256",CIPHER_BYTE,TLS_RSA_WITH_AES_128_CBC_SHA256, TLSv1_MINOR, SSLv3_MAJOR),
+#endif
+
+#ifdef BUILD_TLS_RSA_WITH_AES_256_CBC_SHA256
+    SUITE_INFO("AES256-SHA256","TLS_RSA_WITH_AES_256_CBC_SHA256",CIPHER_BYTE,TLS_RSA_WITH_AES_256_CBC_SHA256, TLSv1_2_MINOR, SSLv3_MAJOR),
+#endif
+
+#ifdef BUILD_TLS_DHE_RSA_WITH_AES_128_CBC_SHA256
+    SUITE_INFO("DHE-RSA-AES128-SHA256","TLS_DHE_RSA_WITH_AES_128_CBC_SHA256",CIPHER_BYTE,TLS_DHE_RSA_WITH_AES_128_CBC_SHA256, TLSv1_2_MINOR, SSLv3_MAJOR),
+#endif
+
+#ifdef BUILD_TLS_DHE_RSA_WITH_AES_256_CBC_SHA256
+    SUITE_INFO("DHE-RSA-AES256-SHA256","TLS_DHE_RSA_WITH_AES_256_CBC_SHA256",CIPHER_BYTE,TLS_DHE_RSA_WITH_AES_256_CBC_SHA256, TLSv1_2_MINOR, SSLv3_MAJOR),
+#endif
+
+#ifdef BUILD_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA
+    SUITE_INFO("ECDH-RSA-AES128-SHA","TLS_ECDH_RSA_WITH_AES_128_CBC_SHA",ECC_BYTE,TLS_ECDH_RSA_WITH_AES_128_CBC_SHA, TLSv1_MINOR, SSLv3_MAJOR),
+#endif
+
+#ifdef BUILD_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA
+    SUITE_INFO("ECDH-RSA-AES256-SHA","TLS_ECDH_RSA_WITH_AES_256_CBC_SHA",ECC_BYTE,TLS_ECDH_RSA_WITH_AES_256_CBC_SHA, TLSv1_MINOR, SSLv3_MAJOR),
+#endif
+
+#ifdef BUILD_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA
+    SUITE_INFO("ECDH-ECDSA-AES128-SHA","TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA",ECC_BYTE,TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA, TLSv1_MINOR, SSLv3_MAJOR),
+#endif
+
+#ifdef BUILD_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA
+    SUITE_INFO("ECDH-ECDSA-AES256-SHA","TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA",ECC_BYTE,TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA, TLSv1_MINOR, SSLv3_MAJOR),
+#endif
+
+#ifdef BUILD_TLS_ECDH_RSA_WITH_RC4_128_SHA
+    SUITE_INFO("ECDH-RSA-RC4-SHA","TLS_ECDH_RSA_WITH_RC4_128_SHA",ECC_BYTE,TLS_ECDH_RSA_WITH_RC4_128_SHA, TLSv1_MINOR, SSLv3_MAJOR),
+#endif
+
+#ifdef BUILD_TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA
+    SUITE_INFO("ECDH-RSA-DES-CBC3-SHA","TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA",ECC_BYTE,TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA, TLSv1_MINOR, SSLv3_MAJOR),
+#endif
+
+#ifdef BUILD_TLS_ECDH_ECDSA_WITH_RC4_128_SHA
+    SUITE_INFO("ECDH-ECDSA-RC4-SHA","TLS_ECDH_ECDSA_WITH_RC4_128_SHA",ECC_BYTE,TLS_ECDH_ECDSA_WITH_RC4_128_SHA, TLSv1_MINOR, SSLv3_MAJOR),
+#endif
+
+#ifdef BUILD_TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA
+    SUITE_INFO("ECDH-ECDSA-DES-CBC3-SHA","TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA",ECC_BYTE,TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA, TLSv1_MINOR, SSLv3_MAJOR),
+#endif
+
+#ifdef BUILD_TLS_RSA_WITH_AES_128_GCM_SHA256
+    SUITE_INFO("AES128-GCM-SHA256","TLS_RSA_WITH_AES_128_GCM_SHA256",CIPHER_BYTE,TLS_RSA_WITH_AES_128_GCM_SHA256, TLSv1_2_MINOR, SSLv3_MAJOR),
+#endif
+
+#ifdef BUILD_TLS_RSA_WITH_AES_256_GCM_SHA384
+    SUITE_INFO("AES256-GCM-SHA384","TLS_RSA_WITH_AES_256_GCM_SHA384",CIPHER_BYTE,TLS_RSA_WITH_AES_256_GCM_SHA384, TLSv1_2_MINOR, SSLv3_MAJOR),
+#endif
+
+#ifdef BUILD_TLS_DHE_RSA_WITH_AES_128_GCM_SHA256
+    SUITE_INFO("DHE-RSA-AES128-GCM-SHA256","TLS_DHE_RSA_WITH_AES_128_GCM_SHA256",CIPHER_BYTE,TLS_DHE_RSA_WITH_AES_128_GCM_SHA256, TLSv1_2_MINOR, SSLv3_MAJOR),
+#endif
+
+#ifdef BUILD_TLS_DHE_RSA_WITH_AES_256_GCM_SHA384
+    SUITE_INFO("DHE-RSA-AES256-GCM-SHA384","TLS_DHE_RSA_WITH_AES_256_GCM_SHA384",CIPHER_BYTE,TLS_DHE_RSA_WITH_AES_256_GCM_SHA384, TLSv1_2_MINOR, SSLv3_MAJOR),
+#endif
+
+#ifdef BUILD_TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
+    SUITE_INFO("ECDHE-RSA-AES128-GCM-SHA256","TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256",ECC_BYTE,TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, TLSv1_2_MINOR, SSLv3_MAJOR),
+#endif
+
+#ifdef BUILD_TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
+    SUITE_INFO("ECDHE-RSA-AES256-GCM-SHA384","TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384",ECC_BYTE,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, TLSv1_2_MINOR, SSLv3_MAJOR),
+#endif
+
+#ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
+    SUITE_INFO("ECDHE-ECDSA-AES128-GCM-SHA256","TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256",ECC_BYTE,TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, TLSv1_2_MINOR, SSLv3_MAJOR),
+#endif
+
+#ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384
+    SUITE_INFO("ECDHE-ECDSA-AES256-GCM-SHA384","TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384",ECC_BYTE,TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, TLSv1_2_MINOR, SSLv3_MAJOR),
+#endif
+
+#ifdef BUILD_TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256
+    SUITE_INFO("ECDH-RSA-AES128-GCM-SHA256","TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256",ECC_BYTE,TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256, TLSv1_2_MINOR, SSLv3_MAJOR),
+#endif
+
+#ifdef BUILD_TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384
+    SUITE_INFO("ECDH-RSA-AES256-GCM-SHA384","TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384",ECC_BYTE,TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384, TLSv1_2_MINOR, SSLv3_MAJOR),
+#endif
+
+#ifdef BUILD_TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256
+    SUITE_INFO("ECDH-ECDSA-AES128-GCM-SHA256","TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256",ECC_BYTE,TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256, TLSv1_2_MINOR, SSLv3_MAJOR),
+#endif
+
+#ifdef BUILD_TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384
+    SUITE_INFO("ECDH-ECDSA-AES256-GCM-SHA384","TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384",ECC_BYTE,TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384, TLSv1_2_MINOR, SSLv3_MAJOR),
+#endif
+
+#ifdef BUILD_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA
+    SUITE_INFO("CAMELLIA128-SHA","TLS_RSA_WITH_CAMELLIA_128_CBC_SHA",CIPHER_BYTE,TLS_RSA_WITH_CAMELLIA_128_CBC_SHA,TLSv1_MINOR,SSLv3_MAJOR),
+#endif
+
+#ifdef BUILD_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA
+    SUITE_INFO("DHE-RSA-CAMELLIA128-SHA","TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA",CIPHER_BYTE,TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA,TLSv1_MINOR,SSLv3_MAJOR),
+#endif
+
+#ifdef BUILD_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA
+    SUITE_INFO("CAMELLIA256-SHA","TLS_RSA_WITH_CAMELLIA_256_CBC_SHA",CIPHER_BYTE,TLS_RSA_WITH_CAMELLIA_256_CBC_SHA,TLSv1_MINOR,SSLv3_MAJOR),
+#endif
+
+#ifdef BUILD_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA
+    SUITE_INFO("DHE-RSA-CAMELLIA256-SHA","TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA",CIPHER_BYTE,TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA,TLSv1_MINOR,SSLv3_MAJOR),
+#endif
+
+#ifdef BUILD_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256
+    SUITE_INFO("CAMELLIA128-SHA256","TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256",CIPHER_BYTE,TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256,TLSv1_MINOR,SSLv3_MAJOR),
+#endif
+
+#ifdef BUILD_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256
+    SUITE_INFO("DHE-RSA-CAMELLIA128-SHA256","TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256",CIPHER_BYTE,TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256,TLSv1_MINOR,SSLv3_MAJOR),
+#endif
+
+#ifdef BUILD_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256
+    SUITE_INFO("CAMELLIA256-SHA256","TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256",CIPHER_BYTE,TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256,TLSv1_MINOR,SSLv3_MAJOR),
+#endif
+
+#ifdef BUILD_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256
+    SUITE_INFO("DHE-RSA-CAMELLIA256-SHA256","TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256",CIPHER_BYTE,TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256,TLSv1_MINOR,SSLv3_MAJOR),
+#endif
+
+#ifdef BUILD_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256
+    SUITE_INFO("ECDHE-RSA-AES128-SHA256","TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256",ECC_BYTE,TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, TLSv1_2_MINOR, SSLv3_MAJOR),
+#endif
+
+#ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256
+    SUITE_INFO("ECDHE-ECDSA-AES128-SHA256","TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256",ECC_BYTE,TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, TLSv1_2_MINOR, SSLv3_MAJOR),
+#endif
+
+#ifdef BUILD_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256
+    SUITE_INFO("ECDH-RSA-AES128-SHA256","TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256",ECC_BYTE,TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256, TLSv1_2_MINOR, SSLv3_MAJOR),
+#endif
+
+#ifdef BUILD_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256
+    SUITE_INFO("ECDH-ECDSA-AES128-SHA256","TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256",ECC_BYTE,TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256, TLSv1_2_MINOR, SSLv3_MAJOR),
+#endif
+
+#ifdef BUILD_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384
+    SUITE_INFO("ECDHE-RSA-AES256-SHA384","TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384",ECC_BYTE,TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384, TLSv1_2_MINOR, SSLv3_MAJOR),
+#endif
+
+#ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384
+    SUITE_INFO("ECDHE-ECDSA-AES256-SHA384","TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384",ECC_BYTE,TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384, TLSv1_2_MINOR, SSLv3_MAJOR),
+#endif
+
+#ifdef BUILD_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384
+    SUITE_INFO("ECDH-RSA-AES256-SHA384","TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384",ECC_BYTE,TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384, TLSv1_2_MINOR, SSLv3_MAJOR),
+#endif
+
+#ifdef BUILD_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384
+    SUITE_INFO("ECDH-ECDSA-AES256-SHA384","TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384",ECC_BYTE,TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384, TLSv1_2_MINOR, SSLv3_MAJOR),
+#endif
+
+#ifdef BUILD_TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256
+    SUITE_INFO("ECDHE-RSA-CHACHA20-POLY1305","TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256",CHACHA_BYTE,TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, TLSv1_2_MINOR, SSLv3_MAJOR),
+#endif
+
+#ifdef BUILD_TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256
+    SUITE_INFO("ECDHE-ECDSA-CHACHA20-POLY1305","TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256",CHACHA_BYTE,TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, TLSv1_2_MINOR, SSLv3_MAJOR),
+#endif
+
+#ifdef BUILD_TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256
+    SUITE_INFO("DHE-RSA-CHACHA20-POLY1305","TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256",CHACHA_BYTE,TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256, TLSv1_2_MINOR, SSLv3_MAJOR),
+#endif
+
+#ifdef BUILD_TLS_ECDHE_RSA_WITH_CHACHA20_OLD_POLY1305_SHA256
+    SUITE_INFO("ECDHE-RSA-CHACHA20-POLY1305-OLD","TLS_ECDHE_RSA_WITH_CHACHA20_OLD_POLY1305_SHA256",CHACHA_BYTE,TLS_ECDHE_RSA_WITH_CHACHA20_OLD_POLY1305_SHA256, TLSv1_2_MINOR, SSLv3_MAJOR),
+#endif
+
+#ifdef BUILD_TLS_ECDHE_ECDSA_WITH_CHACHA20_OLD_POLY1305_SHA256
+    SUITE_INFO("ECDHE-ECDSA-CHACHA20-POLY1305-OLD","TLS_ECDHE_ECDSA_WITH_CHACHA20_OLD_POLY1305_SHA256",CHACHA_BYTE,TLS_ECDHE_ECDSA_WITH_CHACHA20_OLD_POLY1305_SHA256, TLSv1_2_MINOR, SSLv3_MAJOR),
+#endif
+
+#ifdef BUILD_TLS_DHE_RSA_WITH_CHACHA20_OLD_POLY1305_SHA256
+    SUITE_INFO("DHE-RSA-CHACHA20-POLY1305-OLD","TLS_DHE_RSA_WITH_CHACHA20_OLD_POLY1305_SHA256",CHACHA_BYTE,TLS_DHE_RSA_WITH_CHACHA20_OLD_POLY1305_SHA256, TLSv1_2_MINOR, SSLv3_MAJOR),
+#endif
+
+#ifdef BUILD_TLS_DH_anon_WITH_AES_128_CBC_SHA
+    SUITE_INFO("ADH-AES128-SHA","TLS_DH_anon_WITH_AES_128_CBC_SHA",CIPHER_BYTE,TLS_DH_anon_WITH_AES_128_CBC_SHA, TLSv1_2_MINOR, SSLv3_MAJOR),
+#endif
+
+#ifdef BUILD_TLS_DH_anon_WITH_AES_256_GCM_SHA384
+    SUITE_INFO("ADH-AES256-GCM-SHA384","TLS_DH_anon_WITH_AES_256_GCM_SHA384",CIPHER_BYTE,TLS_DH_anon_WITH_AES_256_GCM_SHA384, TLSv1_2_MINOR, SSLv3_MAJOR),
+#endif
+
+#ifdef BUILD_TLS_QSH
+    SUITE_INFO("QSH","TLS_QSH",QSH_BYTE,TLS_QSH, TLSv1_MINOR, SSLv3_MAJOR),
+#endif
+
+#ifdef HAVE_RENEGOTIATION_INDICATION
+    SUITE_INFO("RENEGOTIATION-INFO","TLS_EMPTY_RENEGOTIATION_INFO_SCSV",CIPHER_BYTE,TLS_EMPTY_RENEGOTIATION_INFO_SCSV,SSLv3_MINOR,SSLv3_MAJOR),
+#endif
+
+#ifdef BUILD_SSL_RSA_WITH_IDEA_CBC_SHA
+    SUITE_INFO("IDEA-CBC-SHA","SSL_RSA_WITH_IDEA_CBC_SHA",CIPHER_BYTE,SSL_RSA_WITH_IDEA_CBC_SHA,SSLv3_MINOR,SSLv3_MAJOR),
+#endif
+
+#ifdef BUILD_TLS_ECDHE_ECDSA_WITH_NULL_SHA
+    SUITE_INFO("ECDHE-ECDSA-NULL-SHA","TLS_ECDHE_ECDSA_WITH_NULL_SHA",ECC_BYTE,TLS_ECDHE_ECDSA_WITH_NULL_SHA, TLSv1_MINOR, SSLv3_MAJOR),
+#endif
+
+#ifdef BUILD_TLS_ECDHE_PSK_WITH_NULL_SHA256
+    SUITE_INFO("ECDHE-PSK-NULL-SHA256","TLS_ECDHE_PSK_WITH_NULL_SHA256",ECC_BYTE,TLS_ECDHE_PSK_WITH_NULL_SHA256,TLSv1_MINOR,SSLv3_MAJOR),
+#endif
+
+#ifdef BUILD_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256
+    SUITE_INFO("ECDHE-PSK-AES128-CBC-SHA256","TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256",ECC_BYTE,TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256,TLSv1_MINOR,SSLv3_MAJOR),
+#endif
+
+#ifdef BUILD_TLS_PSK_WITH_CHACHA20_POLY1305_SHA256
+    SUITE_INFO("PSK-CHACHA20-POLY1305","TLS_PSK_WITH_CHACHA20_POLY1305_SHA256",CHACHA_BYTE,TLS_PSK_WITH_CHACHA20_POLY1305_SHA256,TLSv1_2_MINOR,SSLv3_MAJOR),
+#endif
+
+#ifdef BUILD_TLS_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256
+    SUITE_INFO("ECDHE-PSK-CHACHA20-POLY1305","TLS_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256",CHACHA_BYTE,TLS_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256,TLSv1_2_MINOR,SSLv3_MAJOR),
+#endif
+
+#ifdef BUILD_TLS_DHE_PSK_WITH_CHACHA20_POLY1305_SHA256
+    SUITE_INFO("DHE-PSK-CHACHA20-POLY1305","TLS_DHE_PSK_WITH_CHACHA20_POLY1305_SHA256",CHACHA_BYTE,TLS_DHE_PSK_WITH_CHACHA20_POLY1305_SHA256,TLSv1_2_MINOR,SSLv3_MAJOR),
+#endif
+
+#ifdef BUILD_TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA
+    SUITE_INFO("EDH-RSA-DES-CBC3-SHA","TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA",CIPHER_BYTE,TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA, TLSv1_MINOR, SSLv3_MAJOR),
+#endif
+
+#ifdef BUILD_WDM_WITH_NULL_SHA256
+    SUITE_INFO("WDM-NULL-SHA256","WDM_WITH_NULL_SHA256",CIPHER_BYTE,WDM_WITH_NULL_SHA256, TLSv1_3_MINOR, SSLv3_MAJOR)
+#endif
+
+#endif /* WOLFSSL_NO_TLS12 */
+};
+
+
+/* returns the cipher_names array */
+const CipherSuiteInfo* GetCipherNames(void)
+{
+    return cipher_names;
+}
+
+
+/* returns the number of elements in the cipher_names array */
+int GetCipherNamesSize(void)
+{
+    return (int)(sizeof(cipher_names) / sizeof(CipherSuiteInfo));
+}
+
+
+const char* GetCipherNameInternal(const byte cipherSuite0, const byte cipherSuite)
+{
+    int i;
+    const char* nameInternal = "None";
+
+    for (i = 0; i < GetCipherNamesSize(); i++) {
+        if ((cipher_names[i].cipherSuite0 == cipherSuite0) &&
+            (cipher_names[i].cipherSuite  == cipherSuite)) {
+            nameInternal = cipher_names[i].name;
+            break;
+        }
+    }
+    return nameInternal;
+}
+
+#if defined(WOLFSSL_QT) || defined(OPENSSL_ALL)
+const char* GetCipherKeaStr(char n[][MAX_SEGMENT_SZ]) {
+    const char* keaStr = NULL;
+    const char *n0,*n1,*n2,*n3,*n4;
+    n0 = n[0];
+    n1 = n[1];
+    n2 = n[2];
+    n3 = n[3];
+    n4 = n[4];
+
+    if (XSTRNCMP(n0,"ECDHE",5) == 0 && XSTRNCMP(n1,"PSK",3) == 0)
+        keaStr = "ECDHEPSK";
+    else if (XSTRNCMP(n0,"ECDH",4) == 0)
+        keaStr = "ECDH";
+    else if (XSTRNCMP(n0,"DHE",3) == 0 && XSTRNCMP(n1,"PSK",3) == 0)
+        keaStr = "DHEPSK";
+    else if (XSTRNCMP(n0,"DHE",3) == 0)
+        keaStr = "DH";
+   else if (XSTRNCMP(n0,"RSA",3) == 0 && XSTRNCMP(n1,"PSK",3) == 0)
+        keaStr = "RSAPSK";
+    else if (XSTRNCMP(n0,"SRP",3) == 0)
+        keaStr = "SRP";
+    else if (XSTRNCMP(n0,"PSK",3) == 0)
+        keaStr = "PSK";
+    else if (XSTRNCMP(n0,"EDH",3) == 0)
+        keaStr = "EDH";
+    else if ((XSTRNCMP(n1,"SHA",3) == 0) || (XSTRNCMP(n2,"SHA",3) == 0) ||
+             (XSTRNCMP(n3,"SHA",3) == 0) || (XSTRNCMP(n4,"SHA",3) == 0) ||
+             (XSTRNCMP(n2,"RSA",3) == 0) || (XSTRNCMP(n0,"AES128",6) == 0) ||
+             (XSTRNCMP(n0,"AES256",6) == 0) || (XSTRNCMP(n1,"MD5",3) == 0))
+        keaStr = "RSA";
+    else
+        keaStr = "unknown";
+
+    return keaStr;
+}
+
+const char* GetCipherAuthStr(char n[][MAX_SEGMENT_SZ]) {
+
+    const char* authStr = NULL;
+    const char *n0,*n1,*n2;
+    n0 = n[0];
+    n1 = n[1];
+    n2 = n[2];
+
+    if ((XSTRNCMP(n0,"AES128",6) == 0) || (XSTRNCMP(n0,"AES256",6) == 0)  ||
+        ((XSTRNCMP(n0,"TLS13",5) == 0) && ((XSTRNCMP(n1,"AES128",6) == 0) ||
+         (XSTRNCMP(n1,"AES256",6) == 0) || (XSTRNCMP(n1,"CHACHA20",8) == 0))) ||
+        (XSTRNCMP(n0,"RSA",3) == 0) || (XSTRNCMP(n1,"RSA",3) == 0) ||
+        (XSTRNCMP(n1,"SHA",3) == 0) || (XSTRNCMP(n2,"SHA",3) == 0) ||
+        (XSTRNCMP(n1,"MD5",3) == 0))
+        authStr = "RSA";
+    else if (XSTRNCMP(n0,"PSK",3) == 0 || XSTRNCMP(n1,"PSK",3) == 0)
+        authStr = "PSK";
+    else if (XSTRNCMP(n0,"SRP",3) == 0 && XSTRNCMP(n1,"AES",3) == 0)
+        authStr = "SRP";
+    else if (XSTRNCMP(n1,"ECDSA",5) == 0)
+        authStr = "ECDSA";
+    else
+        authStr = "unknown";
+
+    return authStr;
+}
+
+const char* GetCipherEncStr(char n[][MAX_SEGMENT_SZ]) {
+    const char* encStr = NULL;
+    const char *n0,*n1,*n2,*n3;
+    n0 = n[0];
+    n1 = n[1];
+    n2 = n[2];
+    n3 = n[3];
+
+    if ((XSTRNCMP(n0,"AES256",6) == 0 && XSTRNCMP(n1,"GCM",3) == 0) ||
+        (XSTRNCMP(n1,"AES256",6) == 0 && XSTRNCMP(n2,"GCM",3) == 0) ||
+        (XSTRNCMP(n2,"AES256",6) == 0 && XSTRNCMP(n3,"GCM",3) == 0))
+        encStr = "AESGCM(256)";
+
+    else if ((XSTRNCMP(n0,"AES128",6) == 0 && XSTRNCMP(n1,"GCM",3) == 0) ||
+             (XSTRNCMP(n1,"AES128",6) == 0 && XSTRNCMP(n2,"GCM",3) == 0) ||
+             (XSTRNCMP(n2,"AES128",6) == 0 && XSTRNCMP(n3,"GCM",3) == 0))
+        encStr = "AESGCM(128)";
+
+    else if ((XSTRNCMP(n0,"AES128",6) == 0 && XSTRNCMP(n1,"CCM",3) == 0) ||
+             (XSTRNCMP(n1,"AES128",6) == 0 && XSTRNCMP(n2,"CCM",3) == 0) ||
+             (XSTRNCMP(n2,"AES128",6) == 0 && XSTRNCMP(n3,"CCM",3) == 0))
+        encStr = "AESCCM(128)";
+
+    else if ((XSTRNCMP(n0,"AES128",6) == 0) ||
+             (XSTRNCMP(n1,"AES128",6) == 0) ||
+             (XSTRNCMP(n2,"AES128",6) == 0) ||
+             (XSTRNCMP(n1,"AES",3) == 0 && XSTRNCMP(n2,"128",3) == 0) ||
+             (XSTRNCMP(n2,"AES",3) == 0 && XSTRNCMP(n3,"128",3) == 0))
+        encStr = "AES(128)";
+
+    else if ((XSTRNCMP(n0,"AES256",6) == 0) ||
+             (XSTRNCMP(n1,"AES256",6) == 0) ||
+             (XSTRNCMP(n2,"AES256",6) == 0) ||
+             (XSTRNCMP(n1,"AES",3) == 0 && XSTRNCMP(n2,"256",3) == 0) ||
+             (XSTRNCMP(n2,"AES",3) == 0 && XSTRNCMP(n3,"256",3) == 0))
+        encStr = "AES(256)";
+
+    else if ((XSTRNCMP(n0,"CAMELLIA256",11) == 0) ||
+             (XSTRNCMP(n2,"CAMELLIA256",11) == 0))
+        encStr = "CAMELLIA(256)";
+    else if ((XSTRNCMP(n0,"CAMELLIA128",11) == 0) ||
+             (XSTRNCMP(n2,"CAMELLIA128",11) == 0))
+        encStr = "CAMELLIA(128)";
+    else if ((XSTRNCMP(n0,"RC4",3) == 0) || (XSTRNCMP(n2,"RC4",3) == 0))
+        encStr = "RC4";
+    else if (((XSTRNCMP(n0,"DES",3) == 0)  || (XSTRNCMP(n2,"DES",3) == 0)) &&
+             ((XSTRNCMP(n1,"CBC3",4) == 0) || (XSTRNCMP(n3,"CBC3",4) == 0)))
+        encStr = "3DES";
+    else if ((XSTRNCMP(n1,"CHACHA20",8) == 0 && XSTRNCMP(n2,"POLY1305",8) == 0) ||
+             (XSTRNCMP(n2,"CHACHA20",8) == 0 && XSTRNCMP(n3,"POLY1305",8) == 0))
+        encStr = "CHACHA20/POLY1305(256)";
+    else if ((XSTRNCMP(n0,"NULL",4) == 0) || (XSTRNCMP(n1,"NULL",4) == 0) ||
+             (XSTRNCMP(n2,"NULL",4) == 0) ||
+             ((XSTRNCMP(n0,"TLS13",5) == 0) && (XSTRNCMP(n3,"",0) == 0)))
+        encStr = "None";
+    else if ((XSTRNCMP(n0,"IDEA",4) == 0))
+        encStr = "IDEA";
+    else if ((XSTRNCMP(n0,"RABBIT",4) == 0))
+        encStr = "RABBIT";
+    else if ((XSTRNCMP(n0,"HC128",5) == 0))
+        encStr = "HC128";
+    else
+        encStr = "unknown";
+
+    return encStr;
+}
+
+/* Returns the MAC string of a cipher or "unknown" on failure */
+const char* GetCipherMacStr(char n[][MAX_SEGMENT_SZ]) {
+
+    const char* macStr = NULL;
+    const char *n1,*n2,*n3,*n4;
+    n1 = n[1];
+    n2 = n[2];
+    n3 = n[3];
+    n4 = n[4];
+
+    if ((XSTRNCMP(n4,"SHA256",6) == 0) || (XSTRNCMP(n3,"SHA256",6) == 0) ||
+        (XSTRNCMP(n2,"SHA256",6) == 0) || (XSTRNCMP(n1,"SHA256",6) == 0))
+        macStr = "SHA256";
+    else if ((XSTRNCMP(n4,"SHA384",6) == 0) ||
+             (XSTRNCMP(n3,"SHA384",6) == 0) ||
+             (XSTRNCMP(n2,"SHA384",6) == 0) ||
+             (XSTRNCMP(n1,"SHA384",6) == 0))
+        macStr = "SHA384";
+    else if ((XSTRNCMP(n4,"SHA",3) == 0) || (XSTRNCMP(n3,"SHA",3) == 0) ||
+             (XSTRNCMP(n2,"SHA",3) == 0) || (XSTRNCMP(n1,"SHA",3) == 0) ||
+             (XSTRNCMP(n1,"MD5",3) == 0))
+        macStr = "SHA1";
+    else if ((XSTRNCMP(n3,"GCM",3) == 0) ||
+             (XSTRNCMP(n1,"CCM",3) == 0) ||
+             (XSTRNCMP(n2,"CCM",3) == 0) || (XSTRNCMP(n3,"CCM",3) == 0) ||
+             (XSTRNCMP(n1,"CHACHA20",8) == 0 && XSTRNCMP(n2,"POLY1305",8) == 0) ||
+             (XSTRNCMP(n2,"CHACHA20",8) == 0 && XSTRNCMP(n3,"POLY1305",8) == 0))
+        macStr = "AEAD";
+    else
+        macStr = "unknown";
+
+    return macStr;
+}
+
+/* Returns the number of bits based on the cipher enc string, or 0 on failure */
+int SetCipherBits(const char* enc) {
+    int ret = WOLFSSL_FAILURE;
+
+    if ((XSTRNCMP(enc,"AESGCM(256)",11) == 0) ||
+        (XSTRNCMP(enc,"AES(256)",8) == 0) ||
+        (XSTRNCMP(enc,"CAMELLIA(256)",13) == 0) ||
+        (XSTRNCMP(enc,"CHACHA20/POLY1305(256)",22) == 0))
+            ret = 256;
+    else if
+        ((XSTRNCMP(enc,"3DES",4) == 0))
+            ret = 168;
+    else if
+        ((XSTRNCMP(enc,"AESGCM(128)",11) == 0) ||
+         (XSTRNCMP(enc,"AES(128)",8) == 0) ||
+         (XSTRNCMP(enc,"CAMELLIA(128)",13) == 0) ||
+         (XSTRNCMP(enc,"IDEA",4) == 0) ||
+         (XSTRNCMP(enc,"RC4",3) == 0))
+            ret = 128;
+   else if
+        ((XSTRNCMP(enc,"DES",3) == 0))
+            ret = 56;
+
+    return ret;
+}
+#endif /* WOLFSSL_QT || OPENSSL_ALL */
+
+const char* GetCipherNameIana(const byte cipherSuite0, const byte cipherSuite)
+{
+#ifndef NO_ERROR_STRINGS
+    int i;
+    const char* nameIana = "NONE";
+
+    for (i = 0; i < GetCipherNamesSize(); i++) {
+        if ((cipher_names[i].cipherSuite0 == cipherSuite0) &&
+            (cipher_names[i].cipherSuite  == cipherSuite)) {
+            nameIana = cipher_names[i].name_iana;
+            break;
+        }
+    }
+    return nameIana;
+#else
+    (void)cipherSuite0;
+    (void)cipherSuite;
+    return NULL;
+#endif
+}
+
+const char* wolfSSL_get_cipher_name_internal(WOLFSSL* ssl)
+{
+    if (ssl == NULL) {
+        return NULL;
+    }
+
+    return GetCipherNameInternal(ssl->options.cipherSuite0, ssl->options.cipherSuite);
+}
+
+const char* wolfSSL_get_cipher_name_iana(WOLFSSL* ssl)
+{
+    if (ssl == NULL) {
+        return NULL;
+    }
+
+    return GetCipherNameIana(ssl->options.cipherSuite0, ssl->options.cipherSuite);
+}
+
+int GetCipherSuiteFromName(const char* name, byte* cipherSuite0,
+                           byte* cipherSuite)
+{
+    int           ret = BAD_FUNC_ARG;
+    int           i;
+    unsigned long len = (unsigned long)XSTRLEN(name);
+
+    for (i = 0; i < GetCipherNamesSize(); i++) {
+        if (XSTRNCMP(name, cipher_names[i].name, len) == 0) {
+            *cipherSuite0 = cipher_names[i].cipherSuite0;
+            *cipherSuite  = cipher_names[i].cipherSuite;
+            ret = 0;
+            break;
+        }
+    }
+
+    return ret;
+}
+
+/**
+Set the enabled cipher suites.
+
+@param [out] suites Suites structure.
+@param [in]  list   List of cipher suites, only supports full name from
+                    cipher_names[] delimited by ':'.
+
+@return true on success, else false.
+*/
+int SetCipherList(WOLFSSL_CTX* ctx, Suites* suites, const char* list)
+{
+    int       ret          = 0;
+    int       idx          = 0;
+    int       haveRSAsig   = 0;
+    int       haveECDSAsig = 0;
+    int       haveAnon     = 0;
+    const int suiteSz      = GetCipherNamesSize();
+    char*     next         = (char*)list;
+
+    if (suites == NULL || list == NULL) {
+        WOLFSSL_MSG("SetCipherList parameter error");
+        return 0;
+    }
+
+    if (next[0] == 0 || XSTRNCMP(next, "ALL", 3) == 0 ||
+                        XSTRNCMP(next, "DEFAULT", 7) == 0)
+        return 1; /* wolfSSL default */
+
+    do {
+        char*  current = next;
+        char   name[MAX_SUITE_NAME + 1];
+        int    i;
+        word32 length;
+
+        next   = XSTRSTR(next, ":");
+        length = min(sizeof(name), !next ? (word32)XSTRLEN(current) /* last */
+                                         : (word32)(next - current));
+
+        XSTRNCPY(name, current, length);
+        name[(length == sizeof(name)) ? length - 1 : length] = 0;
+
+        for (i = 0; i < suiteSz; i++) {
+            if (XSTRNCMP(name, cipher_names[i].name, sizeof(name)) == 0
+            #ifndef NO_ERROR_STRINGS
+                || XSTRNCMP(name, cipher_names[i].name_iana, sizeof(name)) == 0
+            #endif
+             ) {
+            #ifdef WOLFSSL_DTLS
+                /* don't allow stream ciphers with DTLS */
+                if (ctx->method->version.major == DTLS_MAJOR) {
+                    if (XSTRSTR(name, "RC4") ||
+                        XSTRSTR(name, "HC128") ||
+                        XSTRSTR(name, "RABBIT"))
+                    {
+                        WOLFSSL_MSG("Stream ciphers not supported with DTLS");
+                        continue;
+                    }
+
+                }
+            #endif /* WOLFSSL_DTLS */
+
+                if (idx + 1 >= WOLFSSL_MAX_SUITE_SZ) {
+                    WOLFSSL_MSG("WOLFSSL_MAX_SUITE_SZ set too low");
+                    return 0; /* suites buffer not large enough, error out */
+                }
+
+                suites->suites[idx++] = cipher_names[i].cipherSuite0;
+                suites->suites[idx++] = cipher_names[i].cipherSuite;
+                /* The suites are either ECDSA, RSA, PSK, or Anon. The RSA
+                 * suites don't necessarily have RSA in the name. */
+            #ifdef WOLFSSL_TLS13
+                if (cipher_names[i].cipherSuite0 == TLS13_BYTE ||
+                         (cipher_names[i].cipherSuite0 == ECC_BYTE &&
+                          (cipher_names[i].cipherSuite == TLS_SHA256_SHA256 ||
+                           cipher_names[i].cipherSuite == TLS_SHA384_SHA384))) {
+                #ifndef NO_RSA
+                    haveRSAsig = 1;
+                #endif
+                #if defined(HAVE_ECC) || defined(HAVE_ED25519) || \
+                                                             defined(HAVE_ED448)
+                    haveECDSAsig = 1;
+                #endif
+                }
+                else
+            #endif
+            #if defined(HAVE_ECC) || defined(HAVE_ED25519) || \
+                                                             defined(HAVE_ED448)
+                if ((haveECDSAsig == 0) && XSTRSTR(name, "ECDSA"))
+                    haveECDSAsig = 1;
+                else
+            #endif
+            #ifdef HAVE_ANON
+                if (XSTRSTR(name, "ADH"))
+                    haveAnon = 1;
+                else
+            #endif
+                if (haveRSAsig == 0
+                    #ifndef NO_PSK
+                        && (XSTRSTR(name, "PSK") == NULL)
+                    #endif
+                   ) {
+                    haveRSAsig = 1;
+                }
+
+                ret = 1; /* found at least one */
+                break;
+            }
+        }
+    }
+    while (next++); /* ++ needed to skip ':' */
+
+    if (ret) {
+        int keySz = 0;
+    #ifndef NO_CERTS
+        keySz = ctx->privateKeySz;
+    #endif
+        suites->setSuites = 1;
+        suites->suiteSz   = (word16)idx;
+        InitSuitesHashSigAlgo(suites, haveECDSAsig, haveRSAsig, haveAnon, 1,
+                              keySz);
+    }
+
+    (void)ctx;
+
+    return ret;
+}
+
+
+#if !defined(NO_WOLFSSL_SERVER) || !defined(NO_CERTS)
+int PickHashSigAlgo(WOLFSSL* ssl, const byte* hashSigAlgo, word32 hashSigAlgoSz)
+{
+    word32 i;
+    int ret = MATCH_SUITE_ERROR;
+
+    ssl->suites->sigAlgo = ssl->specs.sig_algo;
+
+    /* set defaults */
+    if (IsAtLeastTLSv1_3(ssl->version)) {
+        ssl->suites->hashAlgo = sha256_mac;
+    #ifndef NO_CERTS
+        ssl->suites->sigAlgo = ssl->buffers.keyType;
+    #endif
+    }
+#ifndef WOLFSSL_NO_TLS12
+    else if (IsAtLeastTLSv1_2(ssl)) {
+    #ifdef WOLFSSL_ALLOW_TLS_SHA1
+        ssl->suites->hashAlgo = sha_mac;
+    #else
+        ssl->suites->hashAlgo = sha256_mac;
+    #endif
+    }
+    else {
+        ssl->suites->hashAlgo = sha_mac;
+    }
+#endif
+
+    if (hashSigAlgoSz == 0)
+        return 0;
+
+    /* i+1 since peek a byte ahead for type */
+    for (i = 0; (i+1) < hashSigAlgoSz; i += HELLO_EXT_SIGALGO_SZ) {
+        byte hashAlgo = 0, sigAlgo = 0;
+
+        DecodeSigAlg(&hashSigAlgo[i], &hashAlgo, &sigAlgo);
+    #ifdef HAVE_ED25519
+        if (ssl->pkCurveOID == ECC_ED25519_OID) {
+            if (sigAlgo != ed25519_sa_algo)
+                continue;
+            if (sigAlgo == ed25519_sa_algo &&
+                                      ssl->suites->sigAlgo == ecc_dsa_sa_algo) {
+                ssl->suites->sigAlgo = sigAlgo;
+                ssl->suites->hashAlgo = sha512_mac;
+                ret = 0;
+                break;
+            }
+        }
+    #endif
+    #ifdef HAVE_ED448
+        if (ssl->pkCurveOID == ECC_ED448_OID) {
+            if (sigAlgo != ed448_sa_algo)
+                continue;
+
+            if (sigAlgo == ed448_sa_algo &&
+                                      ssl->suites->sigAlgo == ecc_dsa_sa_algo) {
+                ssl->suites->sigAlgo = sigAlgo;
+                ssl->suites->hashAlgo = sha512_mac;
+                ret = 0;
+                break;
+            }
+        }
+    #endif
+    #if defined(WOLFSSL_TLS13) && defined(HAVE_ECC)
+        if (IsAtLeastTLSv1_3(ssl->version) && sigAlgo == ssl->suites->sigAlgo &&
+                                                   sigAlgo == ecc_dsa_sa_algo) {
+
+            int digestSz = GetMacDigestSize(hashAlgo);
+            if (digestSz <= 0)
+                continue;
+
+            /* TLS 1.3 signature algorithms for ECDSA match hash length with
+             * key size.
+             */
+            if (digestSz != ssl->buffers.keySz)
+                continue;
+
+            ssl->suites->hashAlgo = hashAlgo;
+            ssl->suites->sigAlgo = sigAlgo;
+            ret = 0;
+            break; /* done selected sig/hash algorithms */
+        }
+        else
+    #endif
+    /* For ECDSA the `USE_ECDSA_KEYSZ_HASH_ALGO` build option will choose a hash
+     * algorithm that matches the ephemeral ECDHE key size or the next highest
+     * available. This workaround resolves issue with some peer's that do not
+     * properly support scenarios such as a P-256 key hashed with SHA512.
+     */
+    #if defined(HAVE_ECC) && defined(USE_ECDSA_KEYSZ_HASH_ALGO)
+        if (sigAlgo == ssl->suites->sigAlgo && sigAlgo == ecc_dsa_sa_algo) {
+            int digestSz = GetMacDigestSize(hashAlgo);
+            if (digestSz <= 0)
+                continue;
+
+            /* For ecc_dsa_sa_algo, pick hash algo that is curve size unless
+                algorithm in not compiled in, then choose next highest */
+            if (digestSz == ssl->eccTempKeySz) {
+                ssl->suites->hashAlgo = hashAlgo;
+                ssl->suites->sigAlgo = sigAlgo;
+            #if defined(WOLFSSL_TLS13) || defined(HAVE_FFDHE)
+                ssl->namedGroup = 0;
+            #endif
+                ret = 0;
+                break; /* done selected sig/hash algorithms */
+            }
+            /* not strong enough, so keep checking hashSigAlso list */
+            if (digestSz < ssl->eccTempKeySz)
+                continue;
+
+            /* mark as highest and check remainder of hashSigAlgo list */
+            ssl->suites->hashAlgo = hashAlgo;
+            ssl->suites->sigAlgo = sigAlgo;
+            ret = 0;
+        }
+        else
+    #endif
+    #ifdef WC_RSA_PSS
+        if (IsAtLeastTLSv1_3(ssl->version) &&
+                                          ssl->suites->sigAlgo == rsa_sa_algo &&
+                                          sigAlgo != rsa_pss_sa_algo) {
+            continue;
+        }
+        else if (sigAlgo == ssl->suites->sigAlgo ||
+                                        (sigAlgo == rsa_pss_sa_algo &&
+                                         (ssl->suites->sigAlgo == rsa_sa_algo)))
+    #else
+        if (sigAlgo == ssl->suites->sigAlgo)
+    #endif
+        {
+            /* pick highest available between both server and client */
+            switch (hashAlgo) {
+                case sha_mac:
+            #ifdef WOLFSSL_SHA224
+                case sha224_mac:
+            #endif
+            #ifndef NO_SHA256
+                case sha256_mac:
+            #endif
+            #ifdef WOLFSSL_SHA384
+                case sha384_mac:
+            #endif
+            #ifdef WOLFSSL_SHA512
+                case sha512_mac:
+            #endif
+                    /* not strong enough, so keep checking hashSigAlso list */
+                    if (hashAlgo < ssl->suites->hashAlgo) {
+                        ret = 0;
+                        continue;
+                    }
+                    /* mark as highest and check remainder of hashSigAlgo list */
+                    ssl->suites->hashAlgo = hashAlgo;
+                    ssl->suites->sigAlgo = sigAlgo;
+                    break;
+                default:
+                    continue;
+            }
+            ret = 0;
+            break;
+        }
+#if defined(WOLFSSL_TLS13)
+        else if (ssl->specs.sig_algo == 0 && IsAtLeastTLSv1_3(ssl->version)) {
+        }
+#endif
+        else if (ssl->specs.sig_algo == 0)
+        {
+            ssl->suites->hashAlgo = ssl->specs.mac_algorithm;
+            ret = 0;
+        }
+    }
+
+    return ret;
+}
+#endif /* !defined(NO_WOLFSSL_SERVER) || !defined(NO_CERTS) */
+
+#if defined(WOLFSSL_CALLBACKS) || defined(OPENSSL_EXTRA)
+
+    /* Initialize HandShakeInfo */
+    void InitHandShakeInfo(HandShakeInfo* info, WOLFSSL* ssl)
+    {
+        int i;
+
+        info->ssl = ssl;
+        info->cipherName[0] = 0;
+        for (i = 0; i < MAX_PACKETS_HANDSHAKE; i++)
+            info->packetNames[i][0] = 0;
+        info->numberPackets = 0;
+        info->negotiationError = 0;
+    }
+
+    /* Set Final HandShakeInfo parameters */
+    void FinishHandShakeInfo(HandShakeInfo* info)
+    {
+        int i;
+        int sz = GetCipherNamesSize();
+
+        for (i = 0; i < sz; i++)
+            if (info->ssl->options.cipherSuite ==
+                                            (byte)cipher_names[i].cipherSuite) {
+                if (info->ssl->options.cipherSuite0 == ECC_BYTE)
+                    continue;   /* ECC suites at end */
+                XSTRNCPY(info->cipherName, cipher_names[i].name, MAX_CIPHERNAME_SZ);
+                info->cipherName[MAX_CIPHERNAME_SZ] = '\0';
+                break;
+            }
+
+        /* error max and min are negative numbers */
+        if (info->ssl->error <= MIN_PARAM_ERR && info->ssl->error >= MAX_PARAM_ERR)
+            info->negotiationError = info->ssl->error;
+    }
+
+
+    /* Add name to info packet names, increase packet name count */
+    void AddPacketName(WOLFSSL* ssl, const char* name)
+    {
+    #ifdef WOLFSSL_CALLBACKS
+        HandShakeInfo* info = &ssl->handShakeInfo;
+        if (info->numberPackets < MAX_PACKETS_HANDSHAKE) {
+            char* packetName = info->packetNames[info->numberPackets];
+            XSTRNCPY(packetName, name, MAX_PACKETNAME_SZ);
+            packetName[MAX_PACKETNAME_SZ] = '\0';
+            info->numberPackets++;
+        }
+    #endif
+        (void)ssl;
+        (void)name;
+    }
+
+
+    #ifdef WOLFSSL_CALLBACKS
+    /* Initialize TimeoutInfo */
+    void InitTimeoutInfo(TimeoutInfo* info)
+    {
+        int i;
+
+        info->timeoutName[0] = 0;
+        info->flags          = 0;
+
+        for (i = 0; i < MAX_PACKETS_HANDSHAKE; i++) {
+            info->packets[i].packetName[0]     = 0;
+            info->packets[i].timestamp.tv_sec  = 0;
+            info->packets[i].timestamp.tv_usec = 0;
+            info->packets[i].bufferValue       = 0;
+            info->packets[i].valueSz           = 0;
+        }
+        info->numberPackets        = 0;
+        info->timeoutValue.tv_sec  = 0;
+        info->timeoutValue.tv_usec = 0;
+    }
+
+
+    /* Free TimeoutInfo */
+    void FreeTimeoutInfo(TimeoutInfo* info, void* heap)
+    {
+        int i;
+        (void)heap;
+        for (i = 0; i < MAX_PACKETS_HANDSHAKE; i++)
+            if (info->packets[i].bufferValue) {
+                XFREE(info->packets[i].bufferValue, heap, DYNAMIC_TYPE_INFO);
+                info->packets[i].bufferValue = 0;
+            }
+
+    }
+
+    /* Add packet name to previously added packet info */
+    void AddLateName(const char* name, TimeoutInfo* info)
+    {
+        /* make sure we have a valid previous one */
+        if (info->numberPackets > 0 && info->numberPackets <
+                                                        MAX_PACKETS_HANDSHAKE) {
+            char* packetName = info->packets[info->numberPackets-1].packetName;
+            XSTRNCPY(packetName, name, MAX_PACKETNAME_SZ);
+            packetName[MAX_PACKETNAME_SZ] = '\0';
+        }
+    }
+
+    /* Add record header to previously added packet info */
+    void AddLateRecordHeader(const RecordLayerHeader* rl, TimeoutInfo* info)
+    {
+        /* make sure we have a valid previous one */
+        if (info->numberPackets > 0 && info->numberPackets <
+                                                        MAX_PACKETS_HANDSHAKE) {
+            if (info->packets[info->numberPackets - 1].bufferValue)
+                XMEMCPY(info->packets[info->numberPackets - 1].bufferValue, rl,
+                       RECORD_HEADER_SZ);
+            else
+                XMEMCPY(info->packets[info->numberPackets - 1].value, rl,
+                       RECORD_HEADER_SZ);
+        }
+    }
+
+    #endif /* WOLFSSL_CALLBACKS */
+
+
+    /* Add PacketInfo to TimeoutInfo
+     *
+     * ssl   WOLFSSL structure sending or receiving packet
+     * name  name of packet being sent
+     * type  type of packet being sent
+     * data  data bing sent with packet
+     * sz    size of data buffer
+     * written 1 if this packet is being written to wire, 0 if being read
+     * heap  custom heap to use for mallocs/frees
+     */
+    void AddPacketInfo(WOLFSSL* ssl, const char* name, int type,
+            const byte* data, int sz, int written, void* heap)
+    {
+    #ifdef WOLFSSL_CALLBACKS
+        TimeoutInfo* info = &ssl->timeoutInfo;
+
+        if (info->numberPackets < (MAX_PACKETS_HANDSHAKE - 1)) {
+            WOLFSSL_TIMEVAL currTime;
+
+            /* may add name after */
+            if (name) {
+                char* packetName = info->packets[info->numberPackets].packetName;
+                XSTRNCPY(packetName, name, MAX_PACKETNAME_SZ);
+                packetName[MAX_PACKETNAME_SZ] = '\0';
+            }
+
+            /* add data, put in buffer if bigger than static buffer */
+            info->packets[info->numberPackets].valueSz = sz;
+            if (sz < MAX_VALUE_SZ)
+                XMEMCPY(info->packets[info->numberPackets].value, data, sz);
+            else {
+                info->packets[info->numberPackets].bufferValue =
+                                    (byte*)XMALLOC(sz, heap, DYNAMIC_TYPE_INFO);
+                if (!info->packets[info->numberPackets].bufferValue)
+                    /* let next alloc catch, just don't fill, not fatal here  */
+                    info->packets[info->numberPackets].valueSz = 0;
+                else
+                    XMEMCPY(info->packets[info->numberPackets].bufferValue,
+                           data, sz);
+            }
+            gettimeofday(&currTime, 0);
+            info->packets[info->numberPackets].timestamp.tv_sec  =
+                                                             currTime.tv_sec;
+            info->packets[info->numberPackets].timestamp.tv_usec =
+                                                             currTime.tv_usec;
+            info->numberPackets++;
+        }
+    #endif /* WOLFSSL_CALLBACKS */
+    #ifdef OPENSSL_EXTRA
+        if (ssl->protoMsgCb != NULL && sz > RECORD_HEADER_SZ) {
+            /* version from hex to dec  16 is 16^1, 256 from 16^2 and
+               4096 from 16^3 */
+            int version = (ssl->version.minor & 0X0F) +
+                          (ssl->version.minor & 0xF0) * 16  +
+                          (ssl->version.major & 0X0F) * 256 +
+                          (ssl->version.major & 0xF0) * 4096;
+
+            ssl->protoMsgCb(written, version, type,
+                         (const void *)(data + RECORD_HEADER_SZ),
+                         (size_t)(sz - RECORD_HEADER_SZ),
+                         ssl, ssl->protoMsgCtx);
+        }
+    #endif /* OPENSSL_EXTRA */
+        (void)written;
+        (void)name;
+        (void)heap;
+        (void)type;
+        (void)ssl;
+    }
+
+#endif /* WOLFSSL_CALLBACKS */
+
+#if !defined(NO_CERTS)
+
+/* Decode the private key - RSA/ECC/Ed25519/Ed448 - and creates a key object.
+ * The signature type is set as well.
+ * The maximum length of a signature is returned.
+ *
+ * ssl     The SSL/TLS object.
+ * length  The length of a signature.
+ * returns 0 on success, otherwise failure.
+ */
+int DecodePrivateKey(WOLFSSL *ssl, word16* length)
+{
+    int      ret = BAD_FUNC_ARG;
+    int      keySz;
+    word32   idx;
+
+#ifdef HAVE_PK_CALLBACKS
+    /* allow no private key if using PK callbacks and CB is set */
+    if (wolfSSL_IsPrivatePkSet(ssl)) {
+        *length = GetPrivateKeySigSize(ssl);
+        return 0;
+    }
+    else
+#endif
+
+    /* make sure private key exists */
+    if (ssl->buffers.key == NULL || ssl->buffers.key->buffer == NULL) {
+        WOLFSSL_MSG("Private key missing!");
+        ERROR_OUT(NO_PRIVATE_KEY, exit_dpk);
+    }
+
+#ifdef HAVE_PKCS11
+    if (ssl->buffers.keyDevId != INVALID_DEVID && ssl->buffers.keyId) {
+        if (ssl->buffers.keyType == rsa_sa_algo)
+            ssl->hsType = DYNAMIC_TYPE_RSA;
+        else if (ssl->buffers.keyType == ecc_dsa_sa_algo)
+            ssl->hsType = DYNAMIC_TYPE_ECC;
+        ret = AllocKey(ssl, ssl->hsType, &ssl->hsKey);
+        if (ret != 0) {
+            goto exit_dpk;
+        }
+
+        if (ssl->buffers.keyType == rsa_sa_algo) {
+    #ifndef NO_RSA
+            ret = wc_InitRsaKey_Id((RsaKey*)ssl->hsKey,
+                             ssl->buffers.key->buffer, ssl->buffers.key->length,
+                             ssl->heap, ssl->buffers.keyDevId);
+            if (ret == 0) {
+                if (ssl->buffers.keySz < ssl->options.minRsaKeySz) {
+                    WOLFSSL_MSG("RSA key size too small");
+                    ERROR_OUT(RSA_KEY_SIZE_E, exit_dpk);
+                }
+
+                /* Return the maximum signature length. */
+                *length = (word16)ssl->buffers.keySz;
+            }
+    #else
+            ret = NOT_COMPILED_IN;
+    #endif
+        }
+        else if (ssl->buffers.keyType == ecc_dsa_sa_algo) {
+    #ifdef HAVE_ECC
+            ret = wc_ecc_init_id((ecc_key*)ssl->hsKey, ssl->buffers.key->buffer,
+                                 ssl->buffers.key->length, ssl->heap,
+                                 ssl->buffers.keyDevId);
+            if (ret == 0) {
+                if (ssl->buffers.keySz < ssl->options.minEccKeySz) {
+                    WOLFSSL_MSG("ECC key size too small");
+                    ERROR_OUT(ECC_KEY_SIZE_E, exit_dpk);
+                }
+
+                /* Return the maximum signature length. */
+                *length = (word16)wc_ecc_sig_size_calc(ssl->buffers.keySz);
+            }
+    #else
+            ret = NOT_COMPILED_IN;
+    #endif
+        }
+        goto exit_dpk;
+    }
+#endif
+
+#ifndef NO_RSA
+    if (ssl->buffers.keyType == rsa_sa_algo || ssl->buffers.keyType == 0) {
+        ssl->hsType = DYNAMIC_TYPE_RSA;
+        ret = AllocKey(ssl, ssl->hsType, &ssl->hsKey);
+        if (ret != 0) {
+            goto exit_dpk;
+        }
+
+        WOLFSSL_MSG("Trying RSA private key");
+
+        /* Set start of data to beginning of buffer. */
+        idx = 0;
+        /* Decode the key assuming it is an RSA private key. */
+        ret = wc_RsaPrivateKeyDecode(ssl->buffers.key->buffer, &idx,
+                    (RsaKey*)ssl->hsKey, ssl->buffers.key->length);
+        if (ret == 0) {
+            WOLFSSL_MSG("Using RSA private key");
+
+            /* It worked so check it meets minimum key size requirements. */
+            keySz = wc_RsaEncryptSize((RsaKey*)ssl->hsKey);
+            if (keySz < 0) { /* check if keySz has error case */
+                ERROR_OUT(keySz, exit_dpk);
+            }
+
+            if (keySz < ssl->options.minRsaKeySz) {
+                WOLFSSL_MSG("RSA key size too small");
+                ERROR_OUT(RSA_KEY_SIZE_E, exit_dpk);
+            }
+
+            /* Return the maximum signature length. */
+            *length = (word16)keySz;
+
+            goto exit_dpk;
+        }
+    }
+#endif /* !NO_RSA */
+
+#ifdef HAVE_ECC
+#ifndef NO_RSA
+    FreeKey(ssl, ssl->hsType, (void**)&ssl->hsKey);
+#endif /* !NO_RSA */
+
+    if (ssl->buffers.keyType == ecc_dsa_sa_algo || ssl->buffers.keyType == 0) {
+        ssl->hsType = DYNAMIC_TYPE_ECC;
+        ret = AllocKey(ssl, ssl->hsType, &ssl->hsKey);
+        if (ret != 0) {
+            goto exit_dpk;
+        }
+
+    #ifndef NO_RSA
+        WOLFSSL_MSG("Trying ECC private key, RSA didn't work");
+    #else
+        WOLFSSL_MSG("Trying ECC private key");
+    #endif
+
+        /* Set start of data to beginning of buffer. */
+        idx = 0;
+        /* Decode the key assuming it is an ECC private key. */
+        ret = wc_EccPrivateKeyDecode(ssl->buffers.key->buffer, &idx,
+                                     (ecc_key*)ssl->hsKey,
+                                     ssl->buffers.key->length);
+        if (ret == 0) {
+            WOLFSSL_MSG("Using ECC private key");
+
+            /* Check it meets the minimum ECC key size requirements. */
+            keySz = wc_ecc_size((ecc_key*)ssl->hsKey);
+            if (keySz < ssl->options.minEccKeySz) {
+                WOLFSSL_MSG("ECC key size too small");
+                ERROR_OUT(ECC_KEY_SIZE_E, exit_dpk);
+            }
+
+            /* Return the maximum signature length. */
+            *length = (word16)wc_ecc_sig_size((ecc_key*)ssl->hsKey);
+
+            goto exit_dpk;
+        }
+    }
+#endif
+#ifdef HAVE_ED25519
+    #if !defined(NO_RSA) || defined(HAVE_ECC)
+        FreeKey(ssl, ssl->hsType, (void**)&ssl->hsKey);
+    #endif
+
+    if (ssl->buffers.keyType == ed25519_sa_algo || ssl->buffers.keyType == 0) {
+        ssl->hsType = DYNAMIC_TYPE_ED25519;
+        ret = AllocKey(ssl, ssl->hsType, &ssl->hsKey);
+        if (ret != 0) {
+            goto exit_dpk;
+        }
+
+        #ifdef HAVE_ECC
+            WOLFSSL_MSG("Trying ED25519 private key, ECC didn't work");
+        #elif !defined(NO_RSA)
+            WOLFSSL_MSG("Trying ED25519 private key, RSA didn't work");
+        #else
+            WOLFSSL_MSG("Trying ED25519 private key");
+        #endif
+
+        /* Set start of data to beginning of buffer. */
+        idx = 0;
+        /* Decode the key assuming it is an ED25519 private key. */
+        ret = wc_Ed25519PrivateKeyDecode(ssl->buffers.key->buffer, &idx,
+                                         (ed25519_key*)ssl->hsKey,
+                                         ssl->buffers.key->length);
+        if (ret == 0) {
+            WOLFSSL_MSG("Using ED25519 private key");
+
+            /* Check it meets the minimum ECC key size requirements. */
+            if (ED25519_KEY_SIZE < ssl->options.minEccKeySz) {
+                WOLFSSL_MSG("ED25519 key size too small");
+                ERROR_OUT(ECC_KEY_SIZE_E, exit_dpk);
+            }
+
+            /* Return the maximum signature length. */
+            *length = ED25519_SIG_SIZE;
+
+            goto exit_dpk;
+        }
+    }
+#endif /* HAVE_ED25519 */
+#ifdef HAVE_ED448
+    #if !defined(NO_RSA) || defined(HAVE_ECC)
+        FreeKey(ssl, ssl->hsType, (void**)&ssl->hsKey);
+    #endif
+
+    if (ssl->buffers.keyType == ed448_sa_algo || ssl->buffers.keyType == 0) {
+        ssl->hsType = DYNAMIC_TYPE_ED448;
+        ret = AllocKey(ssl, ssl->hsType, &ssl->hsKey);
+        if (ret != 0) {
+            goto exit_dpk;
+        }
+
+        #ifdef HAVE_ED25519
+            WOLFSSL_MSG("Trying ED448 private key, ED25519 didn't work");
+        #elif defined(HAVE_ECC)
+            WOLFSSL_MSG("Trying ED448 private key, ECC didn't work");
+        #elif !defined(NO_RSA)
+            WOLFSSL_MSG("Trying ED448 private key, RSA didn't work");
+        #else
+            WOLFSSL_MSG("Trying ED447 private key");
+        #endif
+
+        /* Set start of data to beginning of buffer. */
+        idx = 0;
+        /* Decode the key assuming it is an ED448 private key. */
+        ret = wc_Ed448PrivateKeyDecode(ssl->buffers.key->buffer, &idx,
+                                       (ed448_key*)ssl->hsKey,
+                                       ssl->buffers.key->length);
+        if (ret == 0) {
+            WOLFSSL_MSG("Using ED448 private key");
+
+            /* Check it meets the minimum ECC key size requirements. */
+            if (ED448_KEY_SIZE < ssl->options.minEccKeySz) {
+                WOLFSSL_MSG("ED448 key size too small");
+                ERROR_OUT(ECC_KEY_SIZE_E, exit_dpk);
+            }
+
+            /* Return the maximum signature length. */
+            *length = ED448_SIG_SIZE;
+
+            goto exit_dpk;
+        }
+    }
+#endif /* HAVE_ED448 */
+
+    (void)idx;
+    (void)keySz;
+    (void)length;
+exit_dpk:
+    return ret;
+}
+
+#endif /* WOLFSSL_TLS13 || !NO_WOLFSSL_CLIENT */
+
+/* client only parts */
+#ifndef NO_WOLFSSL_CLIENT
+
+#ifndef WOLFSSL_NO_TLS12
+
+    /* handle generation of client_hello (1) */
+    int SendClientHello(WOLFSSL* ssl)
+    {
+        byte              *output;
+        word32             length, idx = RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ;
+        int                sendSz;
+        int                idSz = ssl->options.resuming
+                                ? ssl->session.sessionIDSz
+                                : 0;
+        int                ret;
+        word16             extSz = 0;
+
+#ifdef WOLFSSL_TLS13
+        if (IsAtLeastTLSv1_3(ssl->version))
+            return SendTls13ClientHello(ssl);
+#endif
+
+        WOLFSSL_START(WC_FUNC_CLIENT_HELLO_SEND);
+        WOLFSSL_ENTER("SendClientHello");
+
+        if (ssl->suites == NULL) {
+            WOLFSSL_MSG("Bad suites pointer in SendClientHello");
+            return SUITES_ERROR;
+        }
+
+#ifdef HAVE_SESSION_TICKET
+        if (ssl->options.resuming && ssl->session.ticketLen > 0) {
+            SessionTicket* ticket;
+
+            ticket = TLSX_SessionTicket_Create(0, ssl->session.ticket,
+                                             ssl->session.ticketLen, ssl->heap);
+            if (ticket == NULL) return MEMORY_E;
+
+            ret = TLSX_UseSessionTicket(&ssl->extensions, ticket, ssl->heap);
+            if (ret != WOLFSSL_SUCCESS) {
+                TLSX_SessionTicket_Free(ticket, ssl->heap);
+                return ret;
+            }
+
+            idSz = 0;
+        }
+#endif
+        length = VERSION_SZ + RAN_LEN
+               + idSz + ENUM_LEN
+               + ssl->suites->suiteSz + SUITE_LEN
+               + COMP_LEN + ENUM_LEN;
+
+#ifdef HAVE_TLS_EXTENSIONS
+        /* auto populate extensions supported unless user defined */
+        if ((ret = TLSX_PopulateExtensions(ssl, 0)) != 0)
+            return ret;
+    #ifdef HAVE_QSH
+        if (QSH_Init(ssl) != 0)
+            return MEMORY_E;
+    #endif
+        extSz = 0;
+        ret = TLSX_GetRequestSize(ssl, client_hello, &extSz);
+        if (ret != 0)
+            return ret;
+        length += extSz;
+#else
+        if (IsAtLeastTLSv1_2(ssl) && ssl->suites->hashSigAlgoSz)
+            extSz += HELLO_EXT_SZ + HELLO_EXT_SIGALGO_SZ
+                   + ssl->suites->hashSigAlgoSz;
+#ifdef HAVE_EXTENDED_MASTER
+        if (ssl->options.haveEMS)
+            extSz += HELLO_EXT_SZ;
+#endif
+        if (extSz != 0)
+            length += extSz + HELLO_EXT_SZ_SZ;
+#endif
+        sendSz = length + HANDSHAKE_HEADER_SZ + RECORD_HEADER_SZ;
+
+#ifdef WOLFSSL_DTLS
+        if (ssl->options.dtls) {
+            length += ENUM_LEN;   /* cookie */
+            if (ssl->arrays->cookieSz != 0) length += ssl->arrays->cookieSz;
+            sendSz  = length + DTLS_HANDSHAKE_HEADER_SZ + DTLS_RECORD_HEADER_SZ;
+            idx    += DTLS_HANDSHAKE_EXTRA + DTLS_RECORD_EXTRA;
+        }
+#endif
+
+        if (IsEncryptionOn(ssl, 1))
+            sendSz += MAX_MSG_EXTRA;
+
+        /* check for available size */
+        if ((ret = CheckAvailableSize(ssl, sendSz)) != 0)
+            return ret;
+
+        /* get output buffer */
+        output = ssl->buffers.outputBuffer.buffer +
+                 ssl->buffers.outputBuffer.length;
+
+        AddHeaders(output, length, client_hello, ssl);
+
+        /* client hello, first version */
+        output[idx++] = ssl->version.major;
+        output[idx++] = ssl->version.minor;
+        ssl->chVersion = ssl->version;  /* store in case changed */
+
+        /* then random */
+        if (ssl->options.connectState == CONNECT_BEGIN) {
+            ret = wc_RNG_GenerateBlock(ssl->rng, output + idx, RAN_LEN);
+            if (ret != 0)
+                return ret;
+
+            /* store random */
+            XMEMCPY(ssl->arrays->clientRandom, output + idx, RAN_LEN);
+        } else {
+#ifdef WOLFSSL_DTLS
+            /* send same random on hello again */
+            XMEMCPY(output + idx, ssl->arrays->clientRandom, RAN_LEN);
+#endif
+        }
+        idx += RAN_LEN;
+
+        /* then session id */
+        output[idx++] = (byte)idSz;
+        if (idSz) {
+            XMEMCPY(output + idx, ssl->session.sessionID,
+                                                      ssl->session.sessionIDSz);
+            idx += ssl->session.sessionIDSz;
+        }
+
+        /* then DTLS cookie */
+#ifdef WOLFSSL_DTLS
+        if (ssl->options.dtls) {
+            byte cookieSz = ssl->arrays->cookieSz;
+
+            output[idx++] = cookieSz;
+            if (cookieSz) {
+                XMEMCPY(&output[idx], ssl->arrays->cookie, cookieSz);
+                idx += cookieSz;
+            }
+        }
+#endif
+        /* then cipher suites */
+        c16toa(ssl->suites->suiteSz, output + idx);
+        idx += OPAQUE16_LEN;
+        XMEMCPY(output + idx, &ssl->suites->suites, ssl->suites->suiteSz);
+        idx += ssl->suites->suiteSz;
+
+        /* last, compression */
+        output[idx++] = COMP_LEN;
+        if (ssl->options.usingCompression)
+            output[idx++] = ZLIB_COMPRESSION;
+        else
+            output[idx++] = NO_COMPRESSION;
+
+#ifdef HAVE_TLS_EXTENSIONS
+        extSz = 0;
+        ret = TLSX_WriteRequest(ssl, output + idx, client_hello, &extSz);
+        if (ret != 0)
+            return ret;
+        idx += extSz;
+
+        (void)idx; /* suppress analyzer warning, keep idx current */
+#else
+        if (extSz != 0) {
+            c16toa(extSz, output + idx);
+            idx += HELLO_EXT_SZ_SZ;
+
+            if (IsAtLeastTLSv1_2(ssl)) {
+                if (ssl->suites->hashSigAlgoSz) {
+                    word16 i;
+                    /* extension type */
+                    c16toa(HELLO_EXT_SIG_ALGO, output + idx);
+                    idx += HELLO_EXT_TYPE_SZ;
+                    /* extension data length */
+                    c16toa(HELLO_EXT_SIGALGO_SZ + ssl->suites->hashSigAlgoSz,
+                           output + idx);
+                    idx += HELLO_EXT_SZ_SZ;
+                    /* sig algos length */
+                    c16toa(ssl->suites->hashSigAlgoSz, output + idx);
+                    idx += HELLO_EXT_SIGALGO_SZ;
+                    for (i=0; i < ssl->suites->hashSigAlgoSz; i++, idx++) {
+                        output[idx] = ssl->suites->hashSigAlgo[i];
+                    }
+                }
+            }
+#ifdef HAVE_EXTENDED_MASTER
+            if (ssl->options.haveEMS) {
+                c16toa(HELLO_EXT_EXTMS, output + idx);
+                idx += HELLO_EXT_TYPE_SZ;
+                c16toa(0, output + idx);
+                idx += HELLO_EXT_SZ_SZ;
+            }
+#endif
+        }
+#endif
+
+        if (IsEncryptionOn(ssl, 1)) {
+            byte* input;
+            int   inputSz = idx - RECORD_HEADER_SZ; /* build msg adds rec hdr */
+
+            input = (byte*)XMALLOC(inputSz, ssl->heap, DYNAMIC_TYPE_IN_BUFFER);
+            if (input == NULL)
+                return MEMORY_E;
+
+            XMEMCPY(input, output + RECORD_HEADER_SZ, inputSz);
+            sendSz = BuildMessage(ssl, output, sendSz, input, inputSz,
+                                  handshake, 1, 0, 0);
+            XFREE(input, ssl->heap, DYNAMIC_TYPE_IN_BUFFER);
+
+            if (sendSz < 0)
+                return sendSz;
+        } else {
+            #ifdef WOLFSSL_DTLS
+                if (IsDtlsNotSctpMode(ssl)) {
+                    if ((ret = DtlsMsgPoolSave(ssl, output, sendSz)) != 0)
+                        return ret;
+                }
+                if (ssl->options.dtls)
+                    DtlsSEQIncrement(ssl, CUR_ORDER);
+            #endif
+            ret = HashOutput(ssl, output, sendSz, 0);
+            if (ret != 0)
+                return ret;
+        }
+
+        ssl->options.clientState = CLIENT_HELLO_COMPLETE;
+#ifdef OPENSSL_EXTRA
+        ssl->cbmode = SSL_CB_MODE_WRITE;
+        if (ssl->CBIS != NULL)
+            ssl->CBIS(ssl, SSL_CB_CONNECT_LOOP, SSL_SUCCESS);
+#endif
+
+#if defined(WOLFSSL_CALLBACKS) || defined(OPENSSL_EXTRA)
+        if (ssl->hsInfoOn) AddPacketName(ssl, "ClientHello");
+        if (ssl->toInfoOn)
+            AddPacketInfo(ssl, "ClientHello", handshake, output, sendSz,
+                          WRITE_PROTO, ssl->heap);
+#endif
+
+        ssl->buffers.outputBuffer.length += sendSz;
+
+        ret = SendBuffered(ssl);
+
+        WOLFSSL_LEAVE("SendClientHello", ret);
+        WOLFSSL_END(WC_FUNC_CLIENT_HELLO_SEND);
+
+        return ret;
+    }
+
+
+    /* handle processing of DTLS hello_verify_request (3) */
+    static int DoHelloVerifyRequest(WOLFSSL* ssl, const byte* input,
+                                    word32* inOutIdx, word32 size)
+    {
+        ProtocolVersion pv;
+        byte            cookieSz;
+        word32          begin = *inOutIdx;
+
+#ifdef WOLFSSL_CALLBACKS
+        if (ssl->hsInfoOn) AddPacketName(ssl, "HelloVerifyRequest");
+        if (ssl->toInfoOn) AddLateName("HelloVerifyRequest", &ssl->timeoutInfo);
+#endif
+
+#ifdef WOLFSSL_DTLS
+        if (ssl->options.dtls) {
+            DtlsMsgPoolReset(ssl);
+        }
+#endif
+
+        if (OPAQUE16_LEN + OPAQUE8_LEN > size)
+            return BUFFER_ERROR;
+
+        XMEMCPY(&pv, input + *inOutIdx, OPAQUE16_LEN);
+        *inOutIdx += OPAQUE16_LEN;
+
+        if (pv.major != DTLS_MAJOR ||
+                         (pv.minor != DTLS_MINOR && pv.minor != DTLSv1_2_MINOR))
+            return VERSION_ERROR;
+
+        cookieSz = input[(*inOutIdx)++];
+
+        if (cookieSz) {
+            if ((*inOutIdx - begin) + cookieSz > size)
+                return BUFFER_ERROR;
+
+#ifdef WOLFSSL_DTLS
+            if (cookieSz <= MAX_COOKIE_LEN) {
+                XMEMCPY(ssl->arrays->cookie, input + *inOutIdx, cookieSz);
+                ssl->arrays->cookieSz = cookieSz;
+            }
+#endif
+            *inOutIdx += cookieSz;
+        }
+
+        ssl->options.serverState = SERVER_HELLOVERIFYREQUEST_COMPLETE;
+        return 0;
+    }
+
+
+    static WC_INLINE int DSH_CheckSessionId(WOLFSSL* ssl)
+    {
+        int ret = 0;
+
+#ifdef HAVE_SECRET_CALLBACK
+        /* If a session secret callback exists, we are using that
+         * key instead of the saved session key. */
+        ret = ret || (ssl->sessionSecretCb != NULL);
+#endif
+
+#ifdef HAVE_SESSION_TICKET
+        /* server may send blank ticket which may not be expected to indicate
+         * existing one ok but will also be sending a new one */
+        ret = ret || (ssl->session.ticketLen > 0);
+#endif
+
+        ret = ret ||
+              (ssl->options.haveSessionId && XMEMCMP(ssl->arrays->sessionID,
+                                          ssl->session.sessionID, ID_LEN) == 0);
+
+        return ret;
+    }
+
+    /* Check the version in the received message is valid and set protocol
+     * version to use.
+     *
+     * ssl  The SSL/TLS object.
+     * pv   The protocol version from the packet.
+     * returns 0 on success, otherwise failure.
+     */
+    int CheckVersion(WOLFSSL *ssl, ProtocolVersion pv)
+    {
+    #ifdef WOLFSSL_TLS13_DRAFT
+        if (pv.major == TLS_DRAFT_MAJOR) {
+            pv.major = SSLv3_MAJOR;
+            pv.minor = TLSv1_3_MINOR;
+        }
+    #endif
+
+        #ifdef OPENSSL_EXTRA
+        if (ssl->CBIS != NULL) {
+            ssl->CBIS(ssl, SSL_CB_HANDSHAKE_START, SSL_SUCCESS);
+        }
+        #endif
+
+        if (pv.minor > ssl->version.minor) {
+            WOLFSSL_MSG("Server using higher version, fatal error");
+            return VERSION_ERROR;
+        }
+        if (pv.minor < ssl->version.minor) {
+            WOLFSSL_MSG("server using lower version");
+
+            /* Check for downgrade attack. */
+            if (!ssl->options.downgrade) {
+                WOLFSSL_MSG("\tno downgrade allowed, fatal error");
+                return VERSION_ERROR;
+            }
+            if (pv.minor < ssl->options.minDowngrade) {
+                WOLFSSL_MSG("\tversion below minimum allowed, fatal error");
+                return VERSION_ERROR;
+            }
+
+            #ifdef HAVE_SECURE_RENEGOTIATION
+                if (ssl->secure_renegotiation &&
+                                         ssl->secure_renegotiation->enabled &&
+                                         ssl->options.handShakeDone) {
+                    WOLFSSL_MSG("Server changed version during scr");
+                    return VERSION_ERROR;
+                }
+            #endif
+
+            /* Checks made - OK to downgrade. */
+            if (pv.minor == SSLv3_MINOR) {
+                /* turn off tls */
+                WOLFSSL_MSG("\tdowngrading to SSLv3");
+                ssl->options.tls    = 0;
+                ssl->options.tls1_1 = 0;
+                ssl->version.minor  = SSLv3_MINOR;
+            }
+            else if (pv.minor == TLSv1_MINOR) {
+                /* turn off tls 1.1+ */
+                WOLFSSL_MSG("\tdowngrading to TLSv1");
+                ssl->options.tls1_1 = 0;
+                ssl->version.minor  = TLSv1_MINOR;
+            }
+            else if (pv.minor == TLSv1_1_MINOR) {
+                WOLFSSL_MSG("\tdowngrading to TLSv1.1");
+                ssl->version.minor  = TLSv1_1_MINOR;
+            }
+            else if (pv.minor == TLSv1_2_MINOR) {
+                WOLFSSL_MSG("    downgrading to TLSv1.2");
+                ssl->version.minor  = TLSv1_2_MINOR;
+            }
+        }
+
+#ifdef OPENSSL_EXTRA
+        /* check if option is set to not allow the current version
+         * set from either wolfSSL_set_options or wolfSSL_CTX_set_options */
+        if (!ssl->options.dtls && ssl->options.downgrade &&
+                ssl->options.mask > 0) {
+            if (ssl->version.minor == TLSv1_2_MINOR &&
+             (ssl->options.mask & SSL_OP_NO_TLSv1_2) == SSL_OP_NO_TLSv1_2) {
+                WOLFSSL_MSG("\tOption set to not allow TLSv1.2, Downgrading");
+                ssl->version.minor = TLSv1_1_MINOR;
+            }
+            if (ssl->version.minor == TLSv1_1_MINOR &&
+             (ssl->options.mask & SSL_OP_NO_TLSv1_1) == SSL_OP_NO_TLSv1_1) {
+                WOLFSSL_MSG("\tOption set to not allow TLSv1.1, Downgrading");
+                ssl->options.tls1_1 = 0;
+                ssl->version.minor = TLSv1_MINOR;
+            }
+            if (ssl->version.minor == TLSv1_MINOR &&
+                (ssl->options.mask & SSL_OP_NO_TLSv1) == SSL_OP_NO_TLSv1) {
+                WOLFSSL_MSG("\tOption set to not allow TLSv1, Downgrading");
+                ssl->options.tls    = 0;
+                ssl->options.tls1_1 = 0;
+                ssl->version.minor = SSLv3_MINOR;
+            }
+            if (ssl->version.minor == SSLv3_MINOR &&
+                (ssl->options.mask & SSL_OP_NO_SSLv3) == SSL_OP_NO_SSLv3) {
+                WOLFSSL_MSG("\tError, option set to not allow SSLv3");
+                return VERSION_ERROR;
+            }
+
+            if (ssl->version.minor < ssl->options.minDowngrade) {
+                WOLFSSL_MSG("\tversion below minimum allowed, fatal error");
+                return VERSION_ERROR;
+            }
+        }
+#endif
+
+        return 0;
+    }
+
+    /* handle processing of server_hello (2) */
+    int DoServerHello(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
+                      word32 helloSz)
+    {
+        byte            cs0;   /* cipher suite bytes 0, 1 */
+        byte            cs1;
+        ProtocolVersion pv;
+        byte            compression;
+        word32          i = *inOutIdx;
+        word32          begin = i;
+        int             ret;
+
+        WOLFSSL_START(WC_FUNC_SERVER_HELLO_DO);
+        WOLFSSL_ENTER("DoServerHello");
+
+#ifdef WOLFSSL_CALLBACKS
+        if (ssl->hsInfoOn) AddPacketName(ssl, "ServerHello");
+        if (ssl->toInfoOn) AddLateName("ServerHello", &ssl->timeoutInfo);
+#endif
+
+        /* protocol version, random and session id length check */
+        if (OPAQUE16_LEN + RAN_LEN + OPAQUE8_LEN > helloSz)
+            return BUFFER_ERROR;
+
+        /* protocol version */
+        XMEMCPY(&pv, input + i, OPAQUE16_LEN);
+        i += OPAQUE16_LEN;
+
+        ret = CheckVersion(ssl, pv);
+        if (ret != 0)
+            return ret;
+
+#ifdef WOLFSSL_TLS13
+        if (IsAtLeastTLSv1_3(pv)) {
+            byte type = server_hello;
+            return DoTls13ServerHello(ssl, input, inOutIdx, helloSz, &type);
+        }
+#endif
+
+        /* random */
+        XMEMCPY(ssl->arrays->serverRandom, input + i, RAN_LEN);
+        i += RAN_LEN;
+
+        /* session id */
+        ssl->arrays->sessionIDSz = input[i++];
+
+        if (ssl->arrays->sessionIDSz > ID_LEN) {
+            WOLFSSL_MSG("Invalid session ID size");
+            ssl->arrays->sessionIDSz = 0;
+            return BUFFER_ERROR;
+        }
+        else if (ssl->arrays->sessionIDSz) {
+            if ((i - begin) + ssl->arrays->sessionIDSz > helloSz)
+                return BUFFER_ERROR;
+
+            XMEMCPY(ssl->arrays->sessionID, input + i,
+                                                      ssl->arrays->sessionIDSz);
+            i += ssl->arrays->sessionIDSz;
+            ssl->options.haveSessionId = 1;
+        }
+
+
+        /* suite and compression */
+        if ((i - begin) + OPAQUE16_LEN + OPAQUE8_LEN > helloSz)
+            return BUFFER_ERROR;
+
+        cs0 = input[i++];
+        cs1 = input[i++];
+
+#ifdef HAVE_SECURE_RENEGOTIATION
+        if (ssl->secure_renegotiation && ssl->secure_renegotiation->enabled &&
+                                         ssl->options.handShakeDone) {
+            if (ssl->options.cipherSuite0 != cs0 ||
+                ssl->options.cipherSuite  != cs1) {
+                WOLFSSL_MSG("Server changed cipher suite during scr");
+                return MATCH_SUITE_ERROR;
+            }
+        }
+#endif
+
+        ssl->options.cipherSuite0 = cs0;
+        ssl->options.cipherSuite  = cs1;
+        compression = input[i++];
+
+#ifndef WOLFSSL_NO_STRICT_CIPHER_SUITE
+        {
+            word32 idx, found = 0;
+            /* confirm server_hello cipher suite is one sent in client_hello */
+            for (idx = 0; idx < ssl->suites->suiteSz; idx += 2) {
+                if (ssl->suites->suites[idx]   == cs0 &&
+                    ssl->suites->suites[idx+1] == cs1) {
+                    found = 1;
+                    break;
+                }
+            }
+            if (!found) {
+                WOLFSSL_MSG("ServerHello did not use cipher suite from ClientHello");
+                return MATCH_SUITE_ERROR;
+            }
+        }
+#endif /* !WOLFSSL_NO_STRICT_CIPHER_SUITE */
+
+        if (compression != NO_COMPRESSION && !ssl->options.usingCompression) {
+            WOLFSSL_MSG("Server forcing compression w/o support");
+            return COMPRESSION_ERROR;
+        }
+
+        if (compression != ZLIB_COMPRESSION && ssl->options.usingCompression) {
+            WOLFSSL_MSG("Server refused compression, turning off");
+            ssl->options.usingCompression = 0;  /* turn off if server refused */
+        }
+
+        *inOutIdx = i;
+
+#ifdef HAVE_TLS_EXTENSIONS
+        if ( (i - begin) < helloSz) {
+            if (TLSX_SupportExtensions(ssl)) {
+                word16 totalExtSz;
+
+                if ((i - begin) + OPAQUE16_LEN > helloSz)
+                    return BUFFER_ERROR;
+
+                ato16(&input[i], &totalExtSz);
+                i += OPAQUE16_LEN;
+
+                if ((i - begin) + totalExtSz > helloSz)
+                    return BUFFER_ERROR;
+
+                if ((ret = TLSX_Parse(ssl, (byte *) input + i, totalExtSz,
+                                                           server_hello, NULL)))
+                    return ret;
+
+                i += totalExtSz;
+                *inOutIdx = i;
+            }
+            else
+                *inOutIdx = begin + helloSz; /* skip extensions */
+        }
+        else
+            ssl->options.haveEMS = 0; /* If no extensions, no EMS */
+#else
+        {
+            int allowExt = 0;
+            byte pendingEMS = 0;
+
+            if ( (i - begin) < helloSz) {
+                if (ssl->version.major == SSLv3_MAJOR &&
+                    ssl->version.minor >= TLSv1_MINOR) {
+
+                    allowExt = 1;
+                }
+#ifdef WOLFSSL_DTLS
+                if (ssl->version.major == DTLS_MAJOR)
+                    allowExt = 1;
+#endif
+
+                if (allowExt) {
+                    word16 totalExtSz;
+
+                    if ((i - begin) + OPAQUE16_LEN > helloSz)
+                        return BUFFER_ERROR;
+
+                    ato16(&input[i], &totalExtSz);
+                    i += OPAQUE16_LEN;
+
+                    if ((i - begin) + totalExtSz > helloSz)
+                        return BUFFER_ERROR;
+
+                    while (totalExtSz) {
+                        word16 extId, extSz;
+
+                        if (OPAQUE16_LEN + OPAQUE16_LEN > totalExtSz)
+                            return BUFFER_ERROR;
+
+                        ato16(&input[i], &extId);
+                        i += OPAQUE16_LEN;
+                        ato16(&input[i], &extSz);
+                        i += OPAQUE16_LEN;
+
+                        if (OPAQUE16_LEN + OPAQUE16_LEN + extSz > totalExtSz)
+                            return BUFFER_ERROR;
+
+                        if (extId == HELLO_EXT_EXTMS)
+                            pendingEMS = 1;
+                        else
+                            i += extSz;
+
+                        totalExtSz -= OPAQUE16_LEN + OPAQUE16_LEN + extSz;
+                    }
+
+                    *inOutIdx = i;
+                }
+                else
+                    *inOutIdx = begin + helloSz; /* skip extensions */
+            }
+
+            if (!pendingEMS && ssl->options.haveEMS)
+                ssl->options.haveEMS = 0;
+        }
+#endif
+
+        ssl->options.serverState = SERVER_HELLO_COMPLETE;
+
+        if (IsEncryptionOn(ssl, 0)) {
+            *inOutIdx += ssl->keys.padSz;
+        #if defined(HAVE_ENCRYPT_THEN_MAC) && !defined(WOLFSSL_AEAD_ONLY)
+            if (ssl->options.startedETMWrite &&
+                                              ssl->specs.cipher_type == block) {
+                *inOutIdx += MacSize(ssl);
+            }
+        #endif
+        }
+
+#ifdef HAVE_SECRET_CALLBACK
+        if (ssl->sessionSecretCb != NULL) {
+            int secretSz = SECRET_LEN;
+            ret = ssl->sessionSecretCb(ssl, ssl->session.masterSecret,
+                                              &secretSz, ssl->sessionSecretCtx);
+            if (ret != 0 || secretSz != SECRET_LEN)
+                return SESSION_SECRET_CB_E;
+        }
+#endif /* HAVE_SECRET_CALLBACK */
+
+        ret = CompleteServerHello(ssl);
+
+        WOLFSSL_LEAVE("DoServerHello", ret);
+        WOLFSSL_END(WC_FUNC_SERVER_HELLO_DO);
+
+        return ret;
+    }
+
+#ifdef WOLFSSL_TLS13
+    /* returns 1 if able to do TLS 1.3 otherwise 0 */
+    static int TLSv1_3_Capable(WOLFSSL* ssl)
+    {
+    #ifndef WOLFSSL_TLS13
+        return 0;
+    #else
+        int ret = 0;
+
+        if (IsAtLeastTLSv1_3(ssl->ctx->method->version)) {
+            ret = 1;
+        }
+
+        #ifdef OPENSSL_EXTRA
+        if ((wolfSSL_get_options(ssl) & SSL_OP_NO_TLSv1_3)) {
+            /* option set at run time to disable TLS 1.3 */
+            ret = 0;
+        }
+        #endif
+        return ret;
+    #endif
+    }
+#endif /* WOLFSSL_TLS13 */
+
+    int CompleteServerHello(WOLFSSL* ssl)
+    {
+        int ret;
+
+        if (!ssl->options.resuming) {
+            byte* down = ssl->arrays->serverRandom + RAN_LEN -
+                                                         TLS13_DOWNGRADE_SZ - 1;
+            byte  vers = ssl->arrays->serverRandom[RAN_LEN - 1];
+    #ifdef WOLFSSL_TLS13
+            if (TLSv1_3_Capable(ssl)) {
+                /* TLS v1.3 capable client not allowed to downgrade when
+                 * connecting to TLS v1.3 capable server unless cipher suite
+                 * demands it.
+                 */
+                if (XMEMCMP(down, tls13Downgrade, TLS13_DOWNGRADE_SZ) == 0 &&
+                                                     (vers == 0 || vers == 1)) {
+                    SendAlert(ssl, alert_fatal, illegal_parameter);
+                    return VERSION_ERROR;
+                }
+            }
+            else
+    #endif
+            if (ssl->ctx->method->version.major == SSLv3_MAJOR &&
+                             ssl->ctx->method->version.minor == TLSv1_2_MINOR) {
+                /* TLS v1.2 capable client not allowed to downgrade when
+                 * connecting to TLS v1.2 capable server.
+                 */
+                if (XMEMCMP(down, tls13Downgrade, TLS13_DOWNGRADE_SZ) == 0 &&
+                                                                    vers == 0) {
+                    SendAlert(ssl, alert_fatal, illegal_parameter);
+                    return VERSION_ERROR;
+                }
+            }
+        }
+        else {
+            if (DSH_CheckSessionId(ssl)) {
+                if (SetCipherSpecs(ssl) == 0) {
+
+                    XMEMCPY(ssl->arrays->masterSecret,
+                            ssl->session.masterSecret, SECRET_LEN);
+            #ifdef NO_OLD_TLS
+                    ret = DeriveTlsKeys(ssl);
+            #else
+                    ret = -1; /* default value */
+                #ifndef NO_TLS
+                    if (ssl->options.tls)
+                        ret = DeriveTlsKeys(ssl);
+                #endif
+                    if (!ssl->options.tls)
+                        ret = DeriveKeys(ssl);
+            #endif /* NO_OLD_TLS */
+                    ssl->options.serverState = SERVER_HELLODONE_COMPLETE;
+
+                    return ret;
+                }
+                else {
+                    WOLFSSL_MSG("Unsupported cipher suite, DoServerHello");
+                    return UNSUPPORTED_SUITE;
+                }
+            }
+            else {
+                WOLFSSL_MSG("Server denied resumption attempt");
+                ssl->options.resuming = 0; /* server denied resumption try */
+            }
+        }
+    #ifdef WOLFSSL_DTLS
+        if (ssl->options.dtls) {
+            DtlsMsgPoolReset(ssl);
+        }
+    #endif
+
+        return SetCipherSpecs(ssl);
+    }
+
+#endif /* WOLFSSL_NO_TLS12 */
+
+
+    /* Make sure client setup is valid for this suite, true on success */
+    int VerifyClientSuite(WOLFSSL* ssl)
+    {
+        int  havePSK = 0;
+        byte first   = ssl->options.cipherSuite0;
+        byte second  = ssl->options.cipherSuite;
+
+        WOLFSSL_ENTER("VerifyClientSuite");
+
+        #ifndef NO_PSK
+            havePSK = ssl->options.havePSK;
+        #endif
+
+        if (CipherRequires(first, second, REQUIRES_PSK)) {
+            WOLFSSL_MSG("Requires PSK");
+            if (havePSK == 0) {
+                WOLFSSL_MSG("Don't have PSK");
+                return 0;
+            }
+        }
+
+        return 1;  /* success */
+    }
+
+#ifndef WOLFSSL_NO_TLS12
+
+#ifndef NO_CERTS
+    /* handle processing of certificate_request (13) */
+    static int DoCertificateRequest(WOLFSSL* ssl, const byte* input, word32*
+                                    inOutIdx, word32 size)
+    {
+        word16 len;
+        word32 begin = *inOutIdx;
+    #ifdef OPENSSL_EXTRA
+        int ret;
+        WOLFSSL_X509* x509 = NULL;
+        WOLFSSL_EVP_PKEY* pkey = NULL;
+    #endif
+
+        WOLFSSL_START(WC_FUNC_CERTIFICATE_REQUEST_DO);
+        WOLFSSL_ENTER("DoCertificateRequest");
+
+        #ifdef WOLFSSL_CALLBACKS
+            if (ssl->hsInfoOn)
+                AddPacketName(ssl, "CertificateRequest");
+            if (ssl->toInfoOn)
+                AddLateName("CertificateRequest", &ssl->timeoutInfo);
+        #endif
+
+        if (OPAQUE8_LEN > size)
+            return BUFFER_ERROR;
+
+        len = input[(*inOutIdx)++];
+
+        if ((*inOutIdx - begin) + len > size)
+            return BUFFER_ERROR;
+
+        /* types, read in here */
+        *inOutIdx += len;
+
+        /* signature and hash signature algorithm */
+        if (IsAtLeastTLSv1_2(ssl)) {
+            if ((*inOutIdx - begin) + OPAQUE16_LEN > size)
+                return BUFFER_ERROR;
+
+            ato16(input + *inOutIdx, &len);
+            *inOutIdx += OPAQUE16_LEN;
+
+            if ((*inOutIdx - begin) + len > size)
+                return BUFFER_ERROR;
+
+            if (PickHashSigAlgo(ssl, input + *inOutIdx, len) != 0 &&
+                                             ssl->buffers.certificate &&
+                                             ssl->buffers.certificate->buffer) {
+            #ifdef HAVE_PK_CALLBACKS
+                if (wolfSSL_CTX_IsPrivatePkSet(ssl->ctx)) {
+                    WOLFSSL_MSG("Using PK for client private key");
+                    return INVALID_PARAMETER;
+                }
+            #endif
+                if (ssl->buffers.key && ssl->buffers.key->buffer) {
+                    return INVALID_PARAMETER;
+                }
+            }
+            *inOutIdx += len;
+    #ifdef WC_RSA_PSS
+            ssl->pssAlgo = 0;
+            if (ssl->suites->sigAlgo == rsa_pss_sa_algo)
+                ssl->pssAlgo |= 1 << ssl->suites->hashAlgo;
+    #endif
+        }
+
+        /* authorities */
+        if ((*inOutIdx - begin) + OPAQUE16_LEN > size)
+            return BUFFER_ERROR;
+
+        ato16(input + *inOutIdx, &len);
+        *inOutIdx += OPAQUE16_LEN;
+
+        if ((*inOutIdx - begin) + len > size)
+            return BUFFER_ERROR;
+
+        while (len) {
+            word16 dnSz;
+
+            if ((*inOutIdx - begin) + OPAQUE16_LEN > size)
+                return BUFFER_ERROR;
+
+            ato16(input + *inOutIdx, &dnSz);
+            *inOutIdx += OPAQUE16_LEN;
+
+            if ((*inOutIdx - begin) + dnSz > size)
+                return BUFFER_ERROR;
+
+            *inOutIdx += dnSz;
+            len -= OPAQUE16_LEN + dnSz;
+        }
+
+    #ifdef OPENSSL_EXTRA
+        /* call client cert callback if no cert has been loaded */
+        if ((ssl->ctx->CBClientCert != NULL) &&
+            (!ssl->buffers.certificate || !ssl->buffers.certificate->buffer)) {
+
+            ret = ssl->ctx->CBClientCert(ssl, &x509, &pkey);
+            if (ret == 1) {
+                if ((wolfSSL_use_certificate(ssl, x509) != WOLFSSL_SUCCESS) ||
+                    (wolfSSL_use_PrivateKey(ssl, pkey) != WOLFSSL_SUCCESS)) {
+                    return CLIENT_CERT_CB_ERROR;
+                }
+                wolfSSL_X509_free(x509);
+                wolfSSL_EVP_PKEY_free(pkey);
+
+            } else if (ret < 0) {
+                return WOLFSSL_ERROR_WANT_X509_LOOKUP;
+            }
+        }
+    #endif
+
+        /* don't send client cert or cert verify if user hasn't provided
+           cert and private key */
+        if (ssl->buffers.certificate && ssl->buffers.certificate->buffer) {
+        #ifdef HAVE_PK_CALLBACKS
+            if (wolfSSL_CTX_IsPrivatePkSet(ssl->ctx)) {
+                WOLFSSL_MSG("Using PK for client private key");
+                ssl->options.sendVerify = SEND_CERT;
+            }
+        #endif
+            if (ssl->buffers.key && ssl->buffers.key->buffer) {
+                ssl->options.sendVerify = SEND_CERT;
+            }
+        }
+    #ifdef OPENSSL_EXTRA
+        else
+    #else
+        else if (IsTLS(ssl))
+    #endif
+        {
+            ssl->options.sendVerify = SEND_BLANK_CERT;
+        }
+
+        if (IsEncryptionOn(ssl, 0)) {
+            *inOutIdx += ssl->keys.padSz;
+        #if defined(HAVE_ENCRYPT_THEN_MAC) && !defined(WOLFSSL_AEAD_ONLY)
+            if (ssl->options.startedETMRead)
+                *inOutIdx += MacSize(ssl);
+        #endif
+        }
+
+        WOLFSSL_LEAVE("DoCertificateRequest", 0);
+        WOLFSSL_END(WC_FUNC_CERTIFICATE_REQUEST_DO);
+
+        return 0;
+    }
+#endif /* !NO_CERTS */
+
+
+#if defined(HAVE_ECC) || defined(HAVE_CURVE25519) || defined(HAVE_CURVE448)
+
+    static int CheckCurveId(int tlsCurveId)
+    {
+        int ret = ECC_CURVE_ERROR;
+
+        switch (tlsCurveId) {
+    #if defined(HAVE_ECC160) || defined(HAVE_ALL_CURVES)
+        #ifndef NO_ECC_SECP
+            case WOLFSSL_ECC_SECP160R1: return ECC_SECP160R1_OID;
+        #endif /* !NO_ECC_SECP */
+        #ifdef HAVE_ECC_SECPR2
+            case WOLFSSL_ECC_SECP160R2: return ECC_SECP160R2_OID;
+        #endif /* HAVE_ECC_SECPR2 */
+        #ifdef HAVE_ECC_KOBLITZ
+            case WOLFSSL_ECC_SECP160K1: return ECC_SECP160K1_OID;
+        #endif /* HAVE_ECC_KOBLITZ */
+    #endif
+    #if defined(HAVE_ECC192) || defined(HAVE_ALL_CURVES)
+        #ifndef NO_ECC_SECP
+            case WOLFSSL_ECC_SECP192R1: return ECC_SECP192R1_OID;
+        #endif /* !NO_ECC_SECP */
+        #ifdef HAVE_ECC_KOBLITZ
+            case WOLFSSL_ECC_SECP192K1: return ECC_SECP192K1_OID;
+        #endif /* HAVE_ECC_KOBLITZ */
+    #endif
+    #if defined(HAVE_ECC224) || defined(HAVE_ALL_CURVES)
+        #ifndef NO_ECC_SECP
+            case WOLFSSL_ECC_SECP224R1: return ECC_SECP224R1_OID;
+        #endif /* !NO_ECC_SECP */
+        #ifdef HAVE_ECC_KOBLITZ
+            case WOLFSSL_ECC_SECP224K1: return ECC_SECP224K1_OID;
+        #endif /* HAVE_ECC_KOBLITZ */
+    #endif
+        #ifdef HAVE_CURVE25519
+            case WOLFSSL_ECC_X25519: return ECC_X25519_OID;
+        #endif
+    #if !defined(NO_ECC256)  || defined(HAVE_ALL_CURVES)
+        #ifndef NO_ECC_SECP
+            case WOLFSSL_ECC_SECP256R1: return ECC_SECP256R1_OID;
+        #endif /* !NO_ECC_SECP */
+        #ifdef HAVE_ECC_KOBLITZ
+            case WOLFSSL_ECC_SECP256K1: return ECC_SECP256K1_OID;
+        #endif /* HAVE_ECC_KOBLITZ */
+        #ifdef HAVE_ECC_BRAINPOOL
+            case WOLFSSL_ECC_BRAINPOOLP256R1: return ECC_BRAINPOOLP256R1_OID;
+        #endif /* HAVE_ECC_BRAINPOOL */
+    #endif
+        #ifdef HAVE_CURVE448
+            case WOLFSSL_ECC_X448: return ECC_X448_OID;
+        #endif
+    #if defined(HAVE_ECC384) || defined(HAVE_ALL_CURVES)
+        #ifndef NO_ECC_SECP
+            case WOLFSSL_ECC_SECP384R1: return ECC_SECP384R1_OID;
+        #endif /* !NO_ECC_SECP */
+        #ifdef HAVE_ECC_BRAINPOOL
+            case WOLFSSL_ECC_BRAINPOOLP384R1: return ECC_BRAINPOOLP384R1_OID;
+        #endif /* HAVE_ECC_BRAINPOOL */
+    #endif
+    #if defined(HAVE_ECC512) || defined(HAVE_ALL_CURVES)
+        #ifdef HAVE_ECC_BRAINPOOL
+            case WOLFSSL_ECC_BRAINPOOLP512R1: return ECC_BRAINPOOLP512R1_OID;
+        #endif /* HAVE_ECC_BRAINPOOL */
+    #endif
+    #if defined(HAVE_ECC521) || defined(HAVE_ALL_CURVES)
+        #ifndef NO_ECC_SECP
+            case WOLFSSL_ECC_SECP521R1: return ECC_SECP521R1_OID;
+        #endif /* !NO_ECC_SECP */
+    #endif
+        }
+
+        return ret;
+    }
+
+#endif /* HAVE_ECC */
+
+/* Persistable DoServerKeyExchange arguments */
+typedef struct DskeArgs {
+    byte*  output; /* not allocated */
+#if !defined(NO_DH) || defined(HAVE_ECC) || defined(HAVE_ED25519) || \
+                                                             defined(HAVE_ED448)
+    byte*  verifySig;
+#endif
+    word32 idx;
+    word32 begin;
+#if !defined(NO_DH) || defined(HAVE_ECC) || defined(HAVE_ED25519) || \
+                                                             defined(HAVE_ED448)
+    word16 verifySigSz;
+#endif
+    word16 sigSz;
+    byte   sigAlgo;
+    byte   hashAlgo;
+#if !defined(NO_RSA) && defined(WC_RSA_PSS)
+    int    bits;
+#endif
+} DskeArgs;
+
+static void FreeDskeArgs(WOLFSSL* ssl, void* pArgs)
+{
+    DskeArgs* args = (DskeArgs*)pArgs;
+
+    (void)ssl;
+    (void)args;
+
+#if !defined(NO_DH) || defined(HAVE_ECC) || defined(HAVE_ED25519) || \
+                                                             defined(HAVE_ED448)
+    if (args->verifySig) {
+        XFREE(args->verifySig, ssl->heap, DYNAMIC_TYPE_SIGNATURE);
+        args->verifySig = NULL;
+    }
+#endif
+}
+
+#ifndef NO_DH
+static int GetDhPublicKey(WOLFSSL* ssl, const byte* input, word32 size,
+                          DskeArgs* args)
+{
+    int             ret = 0;
+    word16          length;
+#ifdef HAVE_FFDHE
+    const DhParams* params = NULL;
+    int             group = 0;
+#endif
+
+    ssl->buffers.weOwnDH = 1;
+
+    ssl->buffers.serverDH_P.buffer = NULL;
+    ssl->buffers.serverDH_G.buffer = NULL;
+    ssl->buffers.serverDH_Pub.buffer = NULL;
+
+    /* p */
+    if ((args->idx - args->begin) + OPAQUE16_LEN > size) {
+        ERROR_OUT(BUFFER_ERROR, exit_gdpk);
+    }
+
+    ato16(input + args->idx, &length);
+    args->idx += OPAQUE16_LEN;
+
+    if ((args->idx - args->begin) + length > size) {
+        ERROR_OUT(BUFFER_ERROR, exit_gdpk);
+    }
+
+    if (length < ssl->options.minDhKeySz) {
+        WOLFSSL_MSG("Server using a DH key that is too small");
+        SendAlert(ssl, alert_fatal, handshake_failure);
+        ERROR_OUT(DH_KEY_SIZE_E, exit_gdpk);
+    }
+    if (length > ssl->options.maxDhKeySz) {
+        WOLFSSL_MSG("Server using a DH key that is too big");
+        SendAlert(ssl, alert_fatal, handshake_failure);
+        ERROR_OUT(DH_KEY_SIZE_E, exit_gdpk);
+    }
+
+    ssl->buffers.serverDH_P.buffer =
+        (byte*)XMALLOC(length, ssl->heap, DYNAMIC_TYPE_PUBLIC_KEY);
+    if (ssl->buffers.serverDH_P.buffer) {
+        ssl->buffers.serverDH_P.length = length;
+    }
+    else {
+        ERROR_OUT(MEMORY_ERROR, exit_gdpk);
+    }
+
+    XMEMCPY(ssl->buffers.serverDH_P.buffer, input + args->idx,
+                                                        length);
+    args->idx += length;
+
+    ssl->options.dhKeySz = length;
+
+    /* g */
+    if ((args->idx - args->begin) + OPAQUE16_LEN > size) {
+        ERROR_OUT(BUFFER_ERROR, exit_gdpk);
+    }
+
+    ato16(input + args->idx, &length);
+    args->idx += OPAQUE16_LEN;
+
+    if ((args->idx - args->begin) + length > size) {
+        ERROR_OUT(BUFFER_ERROR, exit_gdpk);
+    }
+
+    ssl->buffers.serverDH_G.buffer =
+        (byte*)XMALLOC(length, ssl->heap, DYNAMIC_TYPE_PUBLIC_KEY);
+    if (ssl->buffers.serverDH_G.buffer) {
+        ssl->buffers.serverDH_G.length = length;
+    }
+    else {
+        ERROR_OUT(MEMORY_ERROR, exit_gdpk);
+    }
+
+    XMEMCPY(ssl->buffers.serverDH_G.buffer, input + args->idx,
+                                                        length);
+    args->idx += length;
+
+    /* pub */
+    if ((args->idx - args->begin) + OPAQUE16_LEN > size) {
+        ERROR_OUT(BUFFER_ERROR, exit_gdpk);
+    }
+
+    ato16(input + args->idx, &length);
+    args->idx += OPAQUE16_LEN;
+
+    if ((args->idx - args->begin) + length > size) {
+        ERROR_OUT(BUFFER_ERROR, exit_gdpk);
+    }
+
+    ssl->buffers.serverDH_Pub.buffer =
+        (byte*)XMALLOC(length, ssl->heap, DYNAMIC_TYPE_PUBLIC_KEY);
+    if (ssl->buffers.serverDH_Pub.buffer) {
+        ssl->buffers.serverDH_Pub.length = length;
+    }
+    else {
+        ERROR_OUT(MEMORY_ERROR, exit_gdpk);
+    }
+
+    XMEMCPY(ssl->buffers.serverDH_Pub.buffer, input + args->idx,
+                                                        length);
+    args->idx += length;
+
+#ifdef HAVE_FFDHE
+    switch (ssl->options.dhKeySz) {
+    #ifdef HAVE_FFDHE_2048
+        case 2048/8:
+            params = wc_Dh_ffdhe2048_Get();
+            group = WOLFSSL_FFDHE_2048;
+            break;
+    #endif
+    #ifdef HAVE_FFDHE_3072
+        case 3072/8:
+            params = wc_Dh_ffdhe3072_Get();
+            group = WOLFSSL_FFDHE_3072;
+            break;
+    #endif
+    #ifdef HAVE_FFDHE_4096
+        case 4096/8:
+            params = wc_Dh_ffdhe4096_Get();
+            group = WOLFSSL_FFDHE_4096;
+            break;
+    #endif
+    #ifdef HAVE_FFDHE_6144
+        case 6144/8:
+            params = wc_Dh_ffdhe6144_Get();
+            group = WOLFSSL_FFDHE_6144;
+            break;
+    #endif
+    #ifdef HAVE_FFDHE_8192
+        case 8192/8:
+            params = wc_Dh_ffdhe8192_Get();
+            group = WOLFSSL_FFDHE_8192;
+            break;
+    #endif
+        default:
+            break;
+    }
+
+    if (params == NULL || params->g_len != ssl->buffers.serverDH_G.length ||
+            (XMEMCMP(ssl->buffers.serverDH_G.buffer, params->g,
+                    params->g_len) != 0) ||
+            (XMEMCMP(ssl->buffers.serverDH_P.buffer, params->p,
+                    params->p_len) != 0)) {
+        WOLFSSL_MSG("Server not using FFDHE parameters");
+    #ifdef WOLFSSL_REQUIRE_FFDHE
+        SendAlert(ssl, alert_fatal, handshake_failure);
+        ERROR_OUT(DH_PARAMS_NOT_FFDHE_E, exit_gdpk);
+    #endif
+    }
+    else {
+        ssl->namedGroup = group;
+    #if !defined(WOLFSSL_OLD_PRIME_CHECK) && !defined(HAVE_FIPS) && \
+        !defined(HAVE_SELFTEST)
+        ssl->options.dhDoKeyTest = 0;
+    #endif
+    }
+#endif /* HAVE_FFDHE */
+
+exit_gdpk:
+    return ret;
+}
+#endif
+
+/* handle processing of server_key_exchange (12) */
+static int DoServerKeyExchange(WOLFSSL* ssl, const byte* input,
+                               word32* inOutIdx, word32 size)
+{
+    int ret = 0;
+#ifdef WOLFSSL_ASYNC_CRYPT
+    DskeArgs* args = (DskeArgs*)ssl->async.args;
+    typedef char args_test[sizeof(ssl->async.args) >= sizeof(*args) ? 1 : -1];
+    (void)sizeof(args_test);
+#else
+    DskeArgs  args[1];
+#endif
+
+    (void)input;
+    (void)size;
+
+    WOLFSSL_START(WC_FUNC_SERVER_KEY_EXCHANGE_DO);
+    WOLFSSL_ENTER("DoServerKeyExchange");
+
+#ifdef WOLFSSL_ASYNC_CRYPT
+    ret = wolfSSL_AsyncPop(ssl, &ssl->options.asyncState);
+    if (ret != WC_NOT_PENDING_E) {
+        /* Check for error */
+        if (ret < 0)
+            goto exit_dske;
+    }
+    else
+#endif
+    {
+        /* Reset state */
+        ret = 0;
+        ssl->options.asyncState = TLS_ASYNC_BEGIN;
+        XMEMSET(args, 0, sizeof(DskeArgs));
+        args->idx = *inOutIdx;
+        args->begin = *inOutIdx;
+        args->sigAlgo = ssl->specs.sig_algo;
+        args->hashAlgo = sha_mac;
+    #ifdef WOLFSSL_ASYNC_CRYPT
+        ssl->async.freeArgs = FreeDskeArgs;
+    #endif
+    }
+
+    switch(ssl->options.asyncState)
+    {
+        case TLS_ASYNC_BEGIN:
+        {
+        #ifdef WOLFSSL_CALLBACKS
+            if (ssl->hsInfoOn)
+                AddPacketName(ssl, "ServerKeyExchange");
+            if (ssl->toInfoOn)
+                AddLateName("ServerKeyExchange", &ssl->timeoutInfo);
+        #endif
+
+            switch(ssl->specs.kea)
+            {
+            #ifndef NO_PSK
+                case psk_kea:
+                {
+                    int srvHintLen;
+                    word16 length;
+
+                    if ((args->idx - args->begin) + OPAQUE16_LEN > size) {
+                        ERROR_OUT(BUFFER_ERROR, exit_dske);
+                    }
+
+                    ato16(input + args->idx, &length);
+                    args->idx += OPAQUE16_LEN;
+
+                    if ((args->idx - args->begin) + length > size) {
+                        ERROR_OUT(BUFFER_ERROR, exit_dske);
+                    }
+
+                    /* get PSK server hint from the wire */
+                    srvHintLen = min(length, MAX_PSK_ID_LEN);
+                    XMEMCPY(ssl->arrays->server_hint, input + args->idx,
+                                                                    srvHintLen);
+                    ssl->arrays->server_hint[srvHintLen] = '\0'; /* null term */
+                    args->idx += length;
+                    break;
+                }
+            #endif /* !NO_PSK */
+            #ifndef NO_DH
+                case diffie_hellman_kea:
+                {
+                    ret = GetDhPublicKey(ssl, input, size, args);
+                    if (ret != 0)
+                        goto exit_dske;
+                    break;
+                }
+            #endif /* !NO_DH */
+            #if defined(HAVE_ECC) || defined(HAVE_CURVE25519) || \
+                                                          defined(HAVE_CURVE448)
+                case ecc_diffie_hellman_kea:
+                {
+                    byte b;
+                #ifdef HAVE_ECC
+                    int curveId;
+                #endif
+                    int curveOid;
+                    word16 length;
+
+                    if ((args->idx - args->begin) + ENUM_LEN + OPAQUE16_LEN +
+                                                        OPAQUE8_LEN > size) {
+                        ERROR_OUT(BUFFER_ERROR, exit_dske);
+                    }
+
+                    b = input[args->idx++];
+                    if (b != named_curve) {
+                        ERROR_OUT(ECC_CURVETYPE_ERROR, exit_dske);
+                    }
+
+                    args->idx += 1;   /* curve type, eat leading 0 */
+                    b = input[args->idx++];
+                    if ((curveOid = CheckCurveId(b)) < 0) {
+                        ERROR_OUT(ECC_CURVE_ERROR, exit_dske);
+                    }
+                    ssl->ecdhCurveOID = curveOid;
+                #if defined(WOLFSSL_TLS13) || defined(HAVE_FFDHE)
+                    ssl->namedGroup = 0;
+                #endif
+
+                    length = input[args->idx++];
+                    if ((args->idx - args->begin) + length > size) {
+                        ERROR_OUT(BUFFER_ERROR, exit_dske);
+                    }
+
+                #ifdef HAVE_CURVE25519
+                    if (ssl->ecdhCurveOID == ECC_X25519_OID) {
+                        if (ssl->peerX25519Key == NULL) {
+                            ret = AllocKey(ssl, DYNAMIC_TYPE_CURVE25519,
+                                           (void**)&ssl->peerX25519Key);
+                            if (ret != 0) {
+                                goto exit_dske;
+                            }
+                        } else if (ssl->peerX25519KeyPresent) {
+                            ret = ReuseKey(ssl, DYNAMIC_TYPE_CURVE25519,
+                                           ssl->peerX25519Key);
+                            ssl->peerX25519KeyPresent = 0;
+                            if (ret != 0) {
+                                goto exit_dske;
+                            }
+                        }
+
+                        if ((ret = wc_curve25519_check_public(
+                                input + args->idx, length,
+                                EC25519_LITTLE_ENDIAN)) != 0) {
+                        #ifdef WOLFSSL_EXTRA_ALERTS
+                            if (ret == BUFFER_E)
+                                SendAlert(ssl, alert_fatal, decode_error);
+                            else if (ret == ECC_OUT_OF_RANGE_E)
+                                SendAlert(ssl, alert_fatal, bad_record_mac);
+                            else {
+                                SendAlert(ssl, alert_fatal, illegal_parameter);
+                            }
+                        #endif
+                            ERROR_OUT(ECC_PEERKEY_ERROR, exit_dske);
+                        }
+
+                        if (wc_curve25519_import_public_ex(input + args->idx,
+                                length, ssl->peerX25519Key,
+                                EC25519_LITTLE_ENDIAN) != 0) {
+                            ERROR_OUT(ECC_PEERKEY_ERROR, exit_dske);
+                        }
+
+                        args->idx += length;
+                        ssl->peerX25519KeyPresent = 1;
+                        break;
+                    }
+                #endif
+                #ifdef HAVE_CURVE448
+                    if (ssl->ecdhCurveOID == ECC_X448_OID) {
+                        if (ssl->peerX448Key == NULL) {
+                            ret = AllocKey(ssl, DYNAMIC_TYPE_CURVE448,
+                                           (void**)&ssl->peerX448Key);
+                            if (ret != 0) {
+                                goto exit_dske;
+                            }
+                        } else if (ssl->peerX448KeyPresent) {
+                            ret = ReuseKey(ssl, DYNAMIC_TYPE_CURVE448,
+                                           ssl->peerX448Key);
+                            ssl->peerX448KeyPresent = 0;
+                            if (ret != 0) {
+                                goto exit_dske;
+                            }
+                        }
+
+                        if ((ret = wc_curve448_check_public(
+                                input + args->idx, length,
+                                EC448_LITTLE_ENDIAN)) != 0) {
+                        #ifdef WOLFSSL_EXTRA_ALERTS
+                            if (ret == BUFFER_E)
+                                SendAlert(ssl, alert_fatal, decode_error);
+                            else if (ret == ECC_OUT_OF_RANGE_E)
+                                SendAlert(ssl, alert_fatal, bad_record_mac);
+                            else {
+                                SendAlert(ssl, alert_fatal, illegal_parameter);
+                            }
+                        #endif
+                            ERROR_OUT(ECC_PEERKEY_ERROR, exit_dske);
+                        }
+
+                        if (wc_curve448_import_public_ex(input + args->idx,
+                                length, ssl->peerX448Key,
+                                EC448_LITTLE_ENDIAN) != 0) {
+                            ERROR_OUT(ECC_PEERKEY_ERROR, exit_dske);
+                        }
+
+                        args->idx += length;
+                        ssl->peerX448KeyPresent = 1;
+                        break;
+                    }
+                #endif
+                #ifdef HAVE_ECC
+                    if (ssl->peerEccKey == NULL) {
+                        ret = AllocKey(ssl, DYNAMIC_TYPE_ECC,
+                                       (void**)&ssl->peerEccKey);
+                        if (ret != 0) {
+                            goto exit_dske;
+                        }
+                    } else if (ssl->peerEccKeyPresent) {
+                        ret = ReuseKey(ssl, DYNAMIC_TYPE_ECC, ssl->peerEccKey);
+                        ssl->peerEccKeyPresent = 0;
+                        if (ret != 0) {
+                            goto exit_dske;
+                        }
+                    }
+
+                    curveId = wc_ecc_get_oid(curveOid, NULL, NULL);
+                    if (wc_ecc_import_x963_ex(input + args->idx, length,
+                                        ssl->peerEccKey, curveId) != 0) {
+                    #ifdef WOLFSSL_EXTRA_ALERTS
+                        SendAlert(ssl, alert_fatal, illegal_parameter);
+                    #endif
+                        ERROR_OUT(ECC_PEERKEY_ERROR, exit_dske);
+                    }
+
+                    args->idx += length;
+                    ssl->peerEccKeyPresent = 1;
+                #endif
+                    break;
+                }
+            #endif /* HAVE_ECC || HAVE_CURVE25519 || HAVE_CURVE448 */
+            #if !defined(NO_DH) && !defined(NO_PSK)
+                case dhe_psk_kea:
+                {
+                    int srvHintLen;
+                    word16 length;
+
+                    if ((args->idx - args->begin) + OPAQUE16_LEN > size) {
+                        ERROR_OUT(BUFFER_ERROR, exit_dske);
+                    }
+
+                    ato16(input + args->idx, &length);
+                    args->idx += OPAQUE16_LEN;
+
+                    if ((args->idx - args->begin) + length > size) {
+                        ERROR_OUT(BUFFER_ERROR, exit_dske);
+                    }
+
+                    /* get PSK server hint from the wire */
+                    srvHintLen = min(length, MAX_PSK_ID_LEN);
+                    XMEMCPY(ssl->arrays->server_hint, input + args->idx,
+                                                                srvHintLen);
+                    ssl->arrays->server_hint[srvHintLen] = '\0'; /* null term */
+                    args->idx += length;
+
+                    ret = GetDhPublicKey(ssl, input, size, args);
+                    if (ret != 0)
+                        goto exit_dske;
+                    break;
+                }
+            #endif /* !NO_DH && !NO_PSK */
+            #if (defined(HAVE_ECC) || defined(HAVE_CURVE25519) || \
+                                     defined(HAVE_CURVE448)) && !defined(NO_PSK)
+                case ecdhe_psk_kea:
+                {
+                    byte b;
+                    int curveOid, curveId;
+                    int srvHintLen;
+                    word16 length;
+
+                    if ((args->idx - args->begin) + OPAQUE16_LEN > size) {
+                        ERROR_OUT(BUFFER_ERROR, exit_dske);
+                    }
+
+                    ato16(input + args->idx, &length);
+                    args->idx += OPAQUE16_LEN;
+
+                    if ((args->idx - args->begin) + length > size) {
+                        ERROR_OUT(BUFFER_ERROR, exit_dske);
+                    }
+
+                    /* get PSK server hint from the wire */
+                    srvHintLen = min(length, MAX_PSK_ID_LEN);
+                    XMEMCPY(ssl->arrays->server_hint, input + args->idx,
+                                                                    srvHintLen);
+                    ssl->arrays->server_hint[srvHintLen] = '\0'; /* null term */
+
+                    args->idx += length;
+
+                    if ((args->idx - args->begin) + ENUM_LEN + OPAQUE16_LEN +
+                        OPAQUE8_LEN > size) {
+                        ERROR_OUT(BUFFER_ERROR, exit_dske);
+                    }
+
+                    /* Check curve name and ID */
+                    b = input[args->idx++];
+                    if (b != named_curve) {
+                        ERROR_OUT(ECC_CURVETYPE_ERROR, exit_dske);
+                    }
+
+                    args->idx += 1;   /* curve type, eat leading 0 */
+                    b = input[args->idx++];
+                    if ((curveOid = CheckCurveId(b)) < 0) {
+                        ERROR_OUT(ECC_CURVE_ERROR, exit_dske);
+                    }
+
+                    length = input[args->idx++];
+                    if ((args->idx - args->begin) + length > size) {
+                        ERROR_OUT(BUFFER_ERROR, exit_dske);
+                    }
+
+                #ifdef HAVE_CURVE25519
+                    if (ssl->ecdhCurveOID == ECC_X25519_OID) {
+                        if (ssl->peerX25519Key == NULL) {
+                            ret = AllocKey(ssl, DYNAMIC_TYPE_CURVE25519,
+                                           (void**)&ssl->peerX25519Key);
+                            if (ret != 0) {
+                                goto exit_dske;
+                            }
+                        } else if (ssl->peerEccKeyPresent) {
+                            ret = ReuseKey(ssl, DYNAMIC_TYPE_CURVE25519,
+                                           ssl->peerX25519Key);
+                            ssl->peerX25519KeyPresent = 0;
+                            if (ret != 0) {
+                                goto exit_dske;
+                            }
+                        }
+
+                        if ((ret = wc_curve25519_check_public(
+                                input + args->idx, length,
+                                EC25519_LITTLE_ENDIAN)) != 0) {
+                        #ifdef WOLFSSL_EXTRA_ALERTS
+                            if (ret == BUFFER_E)
+                                SendAlert(ssl, alert_fatal, decode_error);
+                            else if (ret == ECC_OUT_OF_RANGE_E)
+                                SendAlert(ssl, alert_fatal, bad_record_mac);
+                            else {
+                                SendAlert(ssl, alert_fatal, illegal_parameter);
+                            }
+                        #endif
+                            ERROR_OUT(ECC_PEERKEY_ERROR, exit_dske);
+                        }
+
+                        if (wc_curve25519_import_public_ex(input + args->idx,
+                                length, ssl->peerX25519Key,
+                                EC25519_LITTLE_ENDIAN) != 0) {
+                            ERROR_OUT(ECC_PEERKEY_ERROR, exit_dske);
+                        }
+
+                        args->idx += length;
+                        ssl->peerX25519KeyPresent = 1;
+                        break;
+                    }
+                #endif
+                #ifdef HAVE_CURVE448
+                    if (ssl->ecdhCurveOID == ECC_X448_OID) {
+                        if (ssl->peerX448Key == NULL) {
+                            ret = AllocKey(ssl, DYNAMIC_TYPE_CURVE448,
+                                           (void**)&ssl->peerX448Key);
+                            if (ret != 0) {
+                                goto exit_dske;
+                            }
+                        } else if (ssl->peerEccKeyPresent) {
+                            ret = ReuseKey(ssl, DYNAMIC_TYPE_CURVE448,
+                                           ssl->peerX448Key);
+                            ssl->peerX448KeyPresent = 0;
+                            if (ret != 0) {
+                                goto exit_dske;
+                            }
+                        }
+
+                        if ((ret = wc_curve448_check_public(
+                                input + args->idx, length,
+                                EC448_LITTLE_ENDIAN)) != 0) {
+                        #ifdef WOLFSSL_EXTRA_ALERTS
+                            if (ret == BUFFER_E)
+                                SendAlert(ssl, alert_fatal, decode_error);
+                            else if (ret == ECC_OUT_OF_RANGE_E)
+                                SendAlert(ssl, alert_fatal, bad_record_mac);
+                            else {
+                                SendAlert(ssl, alert_fatal, illegal_parameter);
+                            }
+                        #endif
+                            ERROR_OUT(ECC_PEERKEY_ERROR, exit_dske);
+                        }
+
+                        if (wc_curve448_import_public_ex(input + args->idx,
+                                length, ssl->peerX448Key,
+                                EC448_LITTLE_ENDIAN) != 0) {
+                            ERROR_OUT(ECC_PEERKEY_ERROR, exit_dske);
+                        }
+
+                        args->idx += length;
+                        ssl->peerX448KeyPresent = 1;
+                        break;
+                    }
+                #endif
+
+                    if (ssl->peerEccKey == NULL) {
+                        ret = AllocKey(ssl, DYNAMIC_TYPE_ECC,
+                                 (void**)&ssl->peerEccKey);
+                        if (ret != 0) {
+                            goto exit_dske;
+                        }
+                    } else if (ssl->peerEccKeyPresent) {
+                        ret = ReuseKey(ssl, DYNAMIC_TYPE_ECC, ssl->peerEccKey);
+                        ssl->peerEccKeyPresent = 0;
+                        if (ret != 0) {
+                            goto exit_dske;
+                        }
+                    }
+
+                    curveId = wc_ecc_get_oid(curveOid, NULL, NULL);
+                    if (wc_ecc_import_x963_ex(input + args->idx, length,
+                        ssl->peerEccKey, curveId) != 0) {
+                        ERROR_OUT(ECC_PEERKEY_ERROR, exit_dske);
+                    }
+
+                    args->idx += length;
+                    ssl->peerEccKeyPresent = 1;
+                    break;
+                }
+            #endif /* (HAVE_ECC || HAVE_CURVE25519 || HAVE_CURVE448) && !NO_PSK */
+                default:
+                    ret = BAD_KEA_TYPE_E;
+            } /* switch(ssl->specs.kea) */
+
+            /* Check for error */
+            if (ret != 0) {
+                goto exit_dske;
+            }
+
+            /* Advance state and proceed */
+            ssl->options.asyncState = TLS_ASYNC_BUILD;
+        } /* case TLS_ASYNC_BEGIN */
+        FALL_THROUGH;
+
+        case TLS_ASYNC_BUILD:
+        {
+            switch(ssl->specs.kea)
+            {
+                case psk_kea:
+                case dhe_psk_kea:
+                case ecdhe_psk_kea:
+                {
+                    /* Nothing to do in this sub-state */
+                    break;
+                }
+
+                case diffie_hellman_kea:
+                case ecc_diffie_hellman_kea:
+                {
+            #if defined(NO_DH) && !defined(HAVE_ECC) && !defined(HAVE_ED25519) \
+                                                     && !defined(HAVE_ED448)
+                    ERROR_OUT(NOT_COMPILED_IN, exit_dske);
+            #else
+                    enum wc_HashType hashType;
+                    word16  verifySz;
+
+                    if (ssl->options.usingAnon_cipher) {
+                        break;
+                    }
+
+                    verifySz = (word16)(args->idx - args->begin);
+                    if (verifySz > MAX_DH_SZ) {
+                        ERROR_OUT(BUFFER_ERROR, exit_dske);
+                    }
+
+                    if (IsAtLeastTLSv1_2(ssl)) {
+                        if ((args->idx - args->begin) + ENUM_LEN + ENUM_LEN >
+                                                                        size) {
+                            ERROR_OUT(BUFFER_ERROR, exit_dske);
+                        }
+
+                        DecodeSigAlg(&input[args->idx], &args->hashAlgo,
+                                     &args->sigAlgo);
+                        args->idx += 2;
+                        hashType = HashAlgoToType(args->hashAlgo);
+                        if (hashType == WC_HASH_TYPE_NONE) {
+                            ERROR_OUT(ALGO_ID_E, exit_dske);
+                        }
+                    } else {
+                        /* only using sha and md5 for rsa */
+                        #ifndef NO_OLD_TLS
+                            hashType = WC_HASH_TYPE_SHA;
+                            if (args->sigAlgo == rsa_sa_algo) {
+                                hashType = WC_HASH_TYPE_MD5_SHA;
+                            }
+                        #else
+                            ERROR_OUT(ALGO_ID_E, exit_dske);
+                        #endif
+                    }
+
+                    /* signature */
+                    if ((args->idx - args->begin) + OPAQUE16_LEN > size) {
+                        ERROR_OUT(BUFFER_ERROR, exit_dske);
+                    }
+
+                    ato16(input + args->idx, &args->verifySigSz);
+                    args->idx += OPAQUE16_LEN;
+
+                    if ((args->idx - args->begin) + args->verifySigSz > size) {
+                        ERROR_OUT(BUFFER_ERROR, exit_dske);
+                    }
+
+                    /* buffer for signature */
+                    ssl->buffers.sig.buffer = (byte*)XMALLOC(SEED_LEN + verifySz,
+                                            ssl->heap, DYNAMIC_TYPE_SIGNATURE);
+                    if (ssl->buffers.sig.buffer == NULL) {
+                        ERROR_OUT(MEMORY_E, exit_dske);
+                    }
+                    ssl->buffers.sig.length = SEED_LEN + verifySz;
+
+                    /* build message to hash */
+                    XMEMCPY(ssl->buffers.sig.buffer,
+                        ssl->arrays->clientRandom, RAN_LEN);
+                    XMEMCPY(&ssl->buffers.sig.buffer[RAN_LEN],
+                        ssl->arrays->serverRandom, RAN_LEN);
+                    XMEMCPY(&ssl->buffers.sig.buffer[RAN_LEN * 2],
+                        input + args->begin, verifySz); /* message */
+
+                    if (args->sigAlgo != ed25519_sa_algo) {
+                        int digest_sz = wc_HashGetDigestSize(hashType);
+                        if (digest_sz <= 0) {
+                            ERROR_OUT(BUFFER_ERROR, exit_dske);
+                        }
+                        ssl->buffers.digest.length = (unsigned int)digest_sz;
+
+                        /* buffer for hash */
+                        ssl->buffers.digest.buffer = (byte*)XMALLOC(
+                            ssl->buffers.digest.length, ssl->heap,
+                            DYNAMIC_TYPE_DIGEST);
+                        if (ssl->buffers.digest.buffer == NULL) {
+                            ERROR_OUT(MEMORY_E, exit_dske);
+                        }
+
+                        /* Perform hash */
+                        ret = wc_Hash(hashType, ssl->buffers.sig.buffer,
+                                                    ssl->buffers.sig.length,
+                                                    ssl->buffers.digest.buffer,
+                                                    ssl->buffers.digest.length);
+                        if (ret != 0) {
+                            goto exit_dske;
+                        }
+                    }
+
+                    switch (args->sigAlgo)
+                    {
+                    #ifndef NO_RSA
+                    #ifdef WC_RSA_PSS
+                        case rsa_pss_sa_algo:
+                    #endif
+                        case rsa_sa_algo:
+                        {
+                            if (ssl->peerRsaKey == NULL ||
+                                                    !ssl->peerRsaKeyPresent) {
+                                ERROR_OUT(NO_PEER_KEY, exit_dske);
+                            }
+                            break;
+                        }
+                    #endif /* !NO_RSA */
+                    #ifdef HAVE_ECC
+                        case ecc_dsa_sa_algo:
+                        {
+                            if (!ssl->peerEccDsaKeyPresent) {
+                                ERROR_OUT(NO_PEER_KEY, exit_dske);
+                            }
+                            break;
+                        }
+                    #endif /* HAVE_ECC */
+                    #if defined(HAVE_ED25519)
+                        case ed25519_sa_algo:
+                        {
+                            if (!ssl->peerEd25519KeyPresent) {
+                                ERROR_OUT(NO_PEER_KEY, exit_dske);
+                            }
+                            break;
+                        }
+                    #endif /* HAVE_ED25519 */
+                    #if defined(HAVE_ED448)
+                        case ed448_sa_algo:
+                        {
+                            if (!ssl->peerEd448KeyPresent) {
+                                ERROR_OUT(NO_PEER_KEY, exit_dske);
+                            }
+                            break;
+                        }
+                    #endif /* HAVE_ED448 */
+
+                    default:
+                        ret = ALGO_ID_E;
+                    } /* switch (args->sigAlgo) */
+
+            #endif /* NO_DH && !HAVE_ECC && !HAVE_ED25519 && !HAVE_ED448 */
+                    break;
+                }
+                default:
+                    ret = BAD_KEA_TYPE_E;
+            } /* switch(ssl->specs.kea) */
+
+            /* Check for error */
+            if (ret != 0) {
+                goto exit_dske;
+            }
+
+            /* Advance state and proceed */
+            ssl->options.asyncState = TLS_ASYNC_DO;
+        } /* case TLS_ASYNC_BUILD */
+        FALL_THROUGH;
+
+        case TLS_ASYNC_DO:
+        {
+            switch(ssl->specs.kea)
+            {
+                case psk_kea:
+                case dhe_psk_kea:
+                case ecdhe_psk_kea:
+                {
+                    /* Nothing to do in this sub-state */
+                    break;
+                }
+
+                case diffie_hellman_kea:
+                case ecc_diffie_hellman_kea:
+                {
+            #if defined(NO_DH) && !defined(HAVE_ECC) && !defined(HAVE_ED25519) \
+                                                     && !defined(HAVE_ED448)
+                    ERROR_OUT(NOT_COMPILED_IN, exit_dske);
+            #else
+                    if (ssl->options.usingAnon_cipher) {
+                        break;
+                    }
+
+                    if (args->verifySig == NULL) {
+                        args->verifySig = (byte*)XMALLOC(args->verifySigSz,
+                                            ssl->heap, DYNAMIC_TYPE_SIGNATURE);
+                        if (args->verifySig == NULL) {
+                            ERROR_OUT(MEMORY_E, exit_dske);
+                        }
+                        XMEMCPY(args->verifySig, input + args->idx,
+                                                            args->verifySigSz);
+                    }
+
+                    switch (args->sigAlgo)
+                    {
+                    #ifndef NO_RSA
+                    #ifdef WC_RSA_PSS
+                        case rsa_pss_sa_algo:
+                    #endif
+                        case rsa_sa_algo:
+                        {
+                            ret = RsaVerify(ssl,
+                                args->verifySig, args->verifySigSz,
+                                &args->output,
+                                args->sigAlgo, args->hashAlgo,
+                                ssl->peerRsaKey,
+                            #ifdef HAVE_PK_CALLBACKS
+                                &ssl->buffers.peerRsaKey
+                            #else
+                                NULL
+                            #endif
+                            );
+
+                            if (ret >= 0) {
+                                args->sigSz = (word16)ret;
+                            #ifdef WC_RSA_PSS
+                                args->bits = mp_count_bits(&ssl->peerRsaKey->n);
+                            #endif
+                                ret = 0;
+                            }
+                        #ifdef WOLFSSL_ASYNC_CRYPT
+                            if (ret != WC_PENDING_E)
+                        #endif
+                            {
+                                /* peerRsaKey */
+                                FreeKey(ssl, DYNAMIC_TYPE_RSA,
+                                                      (void**)&ssl->peerRsaKey);
+                                ssl->peerRsaKeyPresent = 0;
+                            }
+                            break;
+                        }
+                    #endif /* !NO_RSA */
+                    #ifdef HAVE_ECC
+                        case ecc_dsa_sa_algo:
+                        {
+                            ret = EccVerify(ssl,
+                                args->verifySig, args->verifySigSz,
+                                ssl->buffers.digest.buffer,
+                                ssl->buffers.digest.length,
+                                ssl->peerEccDsaKey,
+                            #ifdef HAVE_PK_CALLBACKS
+                                &ssl->buffers.peerEccDsaKey
+                            #else
+                                NULL
+                            #endif
+                            );
+
+                        #ifdef WOLFSSL_ASYNC_CRYPT
+                            if (ret != WC_PENDING_E)
+                        #endif
+                            {
+                                /* peerEccDsaKey */
+                                FreeKey(ssl, DYNAMIC_TYPE_ECC,
+                                                   (void**)&ssl->peerEccDsaKey);
+                                ssl->peerEccDsaKeyPresent = 0;
+                            }
+                            break;
+                        }
+                    #endif /* HAVE_ECC */
+                    #if defined(HAVE_ED25519)
+                        case ed25519_sa_algo:
+                        {
+                            ret = Ed25519Verify(ssl,
+                                args->verifySig, args->verifySigSz,
+                                ssl->buffers.sig.buffer,
+                                ssl->buffers.sig.length,
+                                ssl->peerEd25519Key,
+                            #ifdef HAVE_PK_CALLBACKS
+                                &ssl->buffers.peerEd25519Key
+                            #else
+                                NULL
+                            #endif
+                            );
+
+                        #ifdef WOLFSSL_ASYNC_CRYPT
+                            if (ret != WC_PENDING_E)
+                        #endif
+                            {
+                                /* peerEccDsaKey */
+                                FreeKey(ssl, DYNAMIC_TYPE_ED25519,
+                                                  (void**)&ssl->peerEd25519Key);
+                                ssl->peerEd25519KeyPresent = 0;
+                            }
+                            break;
+                        }
+                    #endif /* HAVE_ED25519 */
+                    #if defined(HAVE_ED448)
+                        case ed448_sa_algo:
+                        {
+                            ret = Ed448Verify(ssl,
+                                args->verifySig, args->verifySigSz,
+                                ssl->buffers.sig.buffer,
+                                ssl->buffers.sig.length,
+                                ssl->peerEd448Key,
+                            #ifdef HAVE_PK_CALLBACKS
+                                &ssl->buffers.peerEd448Key
+                            #else
+                                NULL
+                            #endif
+                            );
+
+                        #ifdef WOLFSSL_ASYNC_CRYPT
+                            if (ret != WC_PENDING_E)
+                        #endif
+                            {
+                                /* peerEccDsaKey */
+                                FreeKey(ssl, DYNAMIC_TYPE_ED448,
+                                                    (void**)&ssl->peerEd448Key);
+                                ssl->peerEd448KeyPresent = 0;
+                            }
+                            break;
+                        }
+                    #endif /* HAVE_ED448 */
+
+                    default:
+                        ret = ALGO_ID_E;
+                    } /* switch (sigAlgo) */
+            #endif /* NO_DH && !HAVE_ECC && !HAVE_ED25519 && !HAVE_ED448 */
+                    break;
+                }
+                default:
+                    ret = BAD_KEA_TYPE_E;
+            } /* switch(ssl->specs.kea) */
+
+            /* Check for error */
+            if (ret != 0) {
+                goto exit_dske;
+            }
+
+            /* Advance state and proceed */
+            ssl->options.asyncState = TLS_ASYNC_VERIFY;
+        } /* case TLS_ASYNC_DO */
+        FALL_THROUGH;
+
+        case TLS_ASYNC_VERIFY:
+        {
+            switch(ssl->specs.kea)
+            {
+                case psk_kea:
+                case dhe_psk_kea:
+                case ecdhe_psk_kea:
+                {
+                    /* Nothing to do in this sub-state */
+                    break;
+                }
+
+                case diffie_hellman_kea:
+                case ecc_diffie_hellman_kea:
+                {
+            #if defined(NO_DH) && !defined(HAVE_ECC) && !defined(HAVE_ED25519) \
+                                                     && !defined(HAVE_ED448)
+                    ERROR_OUT(NOT_COMPILED_IN, exit_dske);
+            #else
+                    if (ssl->options.usingAnon_cipher) {
+                        break;
+                    }
+
+                    /* increment index after verify is done */
+                    args->idx += args->verifySigSz;
+
+                    switch(args->sigAlgo)
+                    {
+                    #ifndef NO_RSA
+                    #ifdef WC_RSA_PSS
+                        case rsa_pss_sa_algo:
+                        #ifdef HAVE_SELFTEST
+                            ret = wc_RsaPSS_CheckPadding(
+                                             ssl->buffers.digest.buffer,
+                                             ssl->buffers.digest.length,
+                                             args->output, args->sigSz,
+                                             HashAlgoToType(args->hashAlgo));
+                        #else
+                            ret = wc_RsaPSS_CheckPadding_ex(
+                                             ssl->buffers.digest.buffer,
+                                             ssl->buffers.digest.length,
+                                             args->output, args->sigSz,
+                                             HashAlgoToType(args->hashAlgo),
+                                             -1, args->bits);
+                        #endif
+                            if (ret != 0)
+                                return ret;
+                            break;
+                    #endif
+                        case rsa_sa_algo:
+                        {
+                            if (IsAtLeastTLSv1_2(ssl)) {
+                            #ifdef WOLFSSL_SMALL_STACK
+                                byte*  encodedSig;
+                            #else
+                                byte   encodedSig[MAX_ENCODED_SIG_SZ];
+                            #endif
+                                word32 encSigSz;
+
+                            #ifdef WOLFSSL_SMALL_STACK
+                                encodedSig = (byte*)XMALLOC(MAX_ENCODED_SIG_SZ,
+                                                ssl->heap, DYNAMIC_TYPE_SIGNATURE);
+                                if (encodedSig == NULL) {
+                                    ERROR_OUT(MEMORY_E, exit_dske);
+                                }
+                            #endif
+
+                                encSigSz = wc_EncodeSignature(encodedSig,
+                                    ssl->buffers.digest.buffer,
+                                    ssl->buffers.digest.length,
+                                    TypeHash(args->hashAlgo));
+                                if (encSigSz != args->sigSz || !args->output ||
+                                    XMEMCMP(args->output, encodedSig,
+                                            min(encSigSz, MAX_ENCODED_SIG_SZ)) != 0) {
+                                    ret = VERIFY_SIGN_ERROR;
+                                }
+                            #ifdef WOLFSSL_SMALL_STACK
+                                XFREE(encodedSig, ssl->heap, DYNAMIC_TYPE_SIGNATURE);
+                            #endif
+                                if (ret != 0) {
+                                    goto exit_dske;
+                                }
+                            }
+                            else if (args->sigSz != FINISHED_SZ ||
+                                    !args->output ||
+                                    XMEMCMP(args->output,
+                                            ssl->buffers.digest.buffer,
+                                            FINISHED_SZ) != 0) {
+                                ERROR_OUT(VERIFY_SIGN_ERROR, exit_dske);
+                            }
+                            break;
+                        }
+                    #endif /* !NO_RSA */
+                    #ifdef HAVE_ECC
+                        case ecc_dsa_sa_algo:
+                            /* Nothing to do in this algo */
+                            break;
+                    #endif /* HAVE_ECC */
+                    #if defined(HAVE_ED25519)
+                        case ed25519_sa_algo:
+                            /* Nothing to do in this algo */
+                            break;
+                    #endif /* HAVE_ED25519 */
+                    #if defined(HAVE_ED448)
+                        case ed448_sa_algo:
+                            /* Nothing to do in this algo */
+                            break;
+                    #endif /* HAVE_ED448 */
+                        default:
+                            ret = ALGO_ID_E;
+                    } /* switch (sigAlgo) */
+            #endif /* NO_DH && !HAVE_ECC && !HAVE_ED25519 && !HAVE_ED448 */
+                    break;
+                }
+                default:
+                    ret = BAD_KEA_TYPE_E;
+            } /* switch(ssl->specs.kea) */
+
+            /* Check for error */
+            if (ret != 0) {
+                goto exit_dske;
+            }
+
+            /* Advance state and proceed */
+            ssl->options.asyncState = TLS_ASYNC_FINALIZE;
+        } /* case TLS_ASYNC_VERIFY */
+        FALL_THROUGH;
+
+        case TLS_ASYNC_FINALIZE:
+        {
+            if (IsEncryptionOn(ssl, 0)) {
+                args->idx += ssl->keys.padSz;
+            #if defined(HAVE_ENCRYPT_THEN_MAC) && !defined(WOLFSSL_AEAD_ONLY)
+                if (ssl->options.startedETMRead)
+                    args->idx += MacSize(ssl);
+            #endif
+            }
+
+            /* QSH extensions */
+        #ifdef HAVE_QSH
+            if (ssl->peerQSHKeyPresent) {
+                word16 name;
+                int    qshSz;
+
+                /* extension name */
+                ato16(input + args->idx, &name);
+                args->idx += OPAQUE16_LEN;
+
+                if (name == TLSX_QUANTUM_SAFE_HYBRID) {
+                    /* if qshSz is larger than 0 it is the length of
+                       buffer used */
+                    if ((qshSz = TLSX_QSHCipher_Parse(ssl, input + args->idx,
+                                                       size, 0)) < 0) {
+                        ERROR_OUT(qshSz, exit_dske);
+                    }
+                    args->idx += qshSz;
+                }
+                else {
+                    /* unknown extension sent server ignored handshake */
+                    ERROR_OUT(BUFFER_ERROR, exit_dske);
+                }
+            }
+        #endif
+
+            /* Advance state and proceed */
+            ssl->options.asyncState = TLS_ASYNC_END;
+        } /* case TLS_ASYNC_FINALIZE */
+        FALL_THROUGH;
+
+        case TLS_ASYNC_END:
+        {
+            /* return index */
+            *inOutIdx = args->idx;
+
+            ssl->options.serverState = SERVER_KEYEXCHANGE_COMPLETE;
+            break;
+        }
+        default:
+            ret = INPUT_CASE_ERROR;
+    } /* switch(ssl->options.asyncState) */
+
+exit_dske:
+
+    WOLFSSL_LEAVE("DoServerKeyExchange", ret);
+    WOLFSSL_END(WC_FUNC_SERVER_KEY_EXCHANGE_DO);
+
+#ifdef WOLFSSL_ASYNC_CRYPT
+    /* Handle async operation */
+    if (ret == WC_PENDING_E) {
+        /* Mark message as not received so it can process again */
+        ssl->msgsReceived.got_server_key_exchange = 0;
+
+        return ret;
+    }
+#endif /* WOLFSSL_ASYNC_CRYPT */
+
+    /* Final cleanup */
+    FreeDskeArgs(ssl, args);
+    FreeKeyExchange(ssl);
+
+    return ret;
+}
+
+
+#ifdef HAVE_QSH
+
+#ifdef HAVE_NTRU
+/* Encrypt a byte array using ntru
+   key    a struct containing the public key to use
+   bufIn  array to be encrypted
+   inSz   size of bufIn array
+   bufOut cipher text out
+   outSz  will be set to the new size of cipher text
+ */
+static int NtruSecretEncrypt(QSHKey* key, byte* bufIn, word32 inSz,
+        byte* bufOut, word16* outSz)
+{
+    int    ret;
+    DRBG_HANDLE drbg;
+
+    /* sanity checks on input arguments */
+    if (key == NULL || bufIn == NULL || bufOut == NULL || outSz == NULL)
+        return BAD_FUNC_ARG;
+
+    if (key->pub.buffer == NULL)
+        return BAD_FUNC_ARG;
+
+    switch (key->name) {
+        case WOLFSSL_NTRU_EESS439:
+        case WOLFSSL_NTRU_EESS593:
+        case WOLFSSL_NTRU_EESS743:
+            break;
+        default:
+            WOLFSSL_MSG("Unknown QSH encryption key!");
+            return -1;
+    }
+
+    /* set up ntru drbg */
+    ret = ntru_crypto_drbg_external_instantiate(GetEntropy, &drbg);
+    if (ret != DRBG_OK)
+        return NTRU_DRBG_ERROR;
+
+    /* encrypt the byte array */
+    ret = ntru_crypto_ntru_encrypt(drbg, key->pub.length, key->pub.buffer,
+        inSz, bufIn, outSz, bufOut);
+    ntru_crypto_drbg_uninstantiate(drbg);
+    if (ret != NTRU_OK)
+        return NTRU_ENCRYPT_ERROR;
+
+    return ret;
+}
+
+/* Decrypt a byte array using ntru
+   key    a struct containing the private key to use
+   bufIn  array to be decrypted
+   inSz   size of bufIn array
+   bufOut plain text out
+   outSz  will be set to the new size of plain text
+ */
+
+static int NtruSecretDecrypt(QSHKey* key, byte* bufIn, word32 inSz,
+        byte* bufOut, word16* outSz)
+{
+    int    ret;
+    DRBG_HANDLE drbg;
+
+    /* sanity checks on input arguments */
+    if (key == NULL || bufIn == NULL || bufOut == NULL || outSz == NULL)
+        return BAD_FUNC_ARG;
+
+    if (key->pri.buffer == NULL)
+        return BAD_FUNC_ARG;
+
+    switch (key->name) {
+        case WOLFSSL_NTRU_EESS439:
+        case WOLFSSL_NTRU_EESS593:
+        case WOLFSSL_NTRU_EESS743:
+            break;
+        default:
+            WOLFSSL_MSG("Unknown QSH decryption key!");
+            return -1;
+    }
+
+
+    /* set up drbg */
+    ret = ntru_crypto_drbg_external_instantiate(GetEntropy, &drbg);
+    if (ret != DRBG_OK)
+        return NTRU_DRBG_ERROR;
+
+    /* decrypt cipher text */
+    ret = ntru_crypto_ntru_decrypt(key->pri.length, key->pri.buffer,
+        inSz, bufIn, outSz, bufOut);
+    ntru_crypto_drbg_uninstantiate(drbg);
+    if (ret != NTRU_OK)
+        return NTRU_ENCRYPT_ERROR;
+
+    return ret;
+}
+#endif /* HAVE_NTRU */
+
+int QSH_Init(WOLFSSL* ssl)
+{
+    /* check so not initializing twice when running DTLS */
+    if (ssl->QSH_secret != NULL)
+        return 0;
+
+    /* malloc memory for holding generated secret information */
+    if ((ssl->QSH_secret = (QSHSecret*)XMALLOC(sizeof(QSHSecret), ssl->heap,
+                    DYNAMIC_TYPE_QSH)) == NULL)
+        return MEMORY_E;
+
+    ssl->QSH_secret->CliSi = (buffer*)XMALLOC(sizeof(buffer), ssl->heap,
+            DYNAMIC_TYPE_SECRET);
+    if (ssl->QSH_secret->CliSi == NULL)
+        return MEMORY_E;
+
+    ssl->QSH_secret->SerSi = (buffer*)XMALLOC(sizeof(buffer), ssl->heap,
+            DYNAMIC_TYPE_SECRET);
+    if (ssl->QSH_secret->SerSi == NULL)
+        return MEMORY_E;
+
+    /* initialize variables */
+    ssl->QSH_secret->list = NULL;
+    ssl->QSH_secret->CliSi->length = 0;
+    ssl->QSH_secret->CliSi->buffer = NULL;
+    ssl->QSH_secret->SerSi->length = 0;
+    ssl->QSH_secret->SerSi->buffer = NULL;
+
+    return 0;
+}
+
+
+static int QSH_Encrypt(QSHKey* key, byte* in, word32 szIn,
+                                                       byte* out, word32* szOut)
+{
+    int ret = 0;
+    word16 size = *szOut;
+
+    (void)in;
+    (void)szIn;
+    (void)out;
+    (void)szOut;
+
+    WOLFSSL_MSG("Encrypting QSH key material");
+
+    switch (key->name) {
+    #ifdef HAVE_NTRU
+        case WOLFSSL_NTRU_EESS439:
+        case WOLFSSL_NTRU_EESS593:
+        case WOLFSSL_NTRU_EESS743:
+            ret = NtruSecretEncrypt(key, in, szIn, out, &size);
+            break;
+    #endif
+        default:
+            WOLFSSL_MSG("Unknown QSH encryption key!");
+            return -1;
+    }
+
+    *szOut = size;
+
+    return ret;
+}
+
+
+/* Decrypt using Quantum Safe Handshake algorithms */
+int QSH_Decrypt(QSHKey* key, byte* in, word32 szIn, byte* out, word16* szOut)
+{
+    int ret = 0;
+    word16 size = *szOut;
+
+    (void)in;
+    (void)szIn;
+    (void)out;
+    (void)szOut;
+
+    WOLFSSL_MSG("Decrypting QSH key material");
+
+    switch (key->name) {
+    #ifdef HAVE_NTRU
+        case WOLFSSL_NTRU_EESS439:
+        case WOLFSSL_NTRU_EESS593:
+        case WOLFSSL_NTRU_EESS743:
+            ret = NtruSecretDecrypt(key, in, szIn, out, &size);
+            break;
+    #endif
+        default:
+            WOLFSSL_MSG("Unknown QSH decryption key!");
+            return -1;
+    }
+
+    *szOut = size;
+
+    return ret;
+}
+
+
+/* Get the max cipher text for corresponding encryption scheme
+   (encrypting  48 or max plain text whichever is smaller)
+ */
+static word32 QSH_MaxSecret(QSHKey* key)
+{
+    int ret = 0;
+#ifdef HAVE_NTRU
+    byte isNtru = 0;
+    word16 inSz = 48;
+    word16 outSz;
+    DRBG_HANDLE drbg = 0;
+    byte bufIn[48];
+#endif
+
+    if (key == NULL || key->pub.length == 0)
+        return 0;
+
+    switch(key->name) {
+#ifdef HAVE_NTRU
+            case WOLFSSL_NTRU_EESS439:
+                isNtru   = 1;
+                break;
+            case WOLFSSL_NTRU_EESS593:
+                isNtru   = 1;
+                break;
+            case WOLFSSL_NTRU_EESS743:
+                isNtru   = 1;
+                break;
+#endif
+        default:
+            WOLFSSL_MSG("Unknown QSH encryption scheme size!");
+            return 0;
+    }
+
+#ifdef HAVE_NTRU
+    if (isNtru) {
+        ret = ntru_crypto_drbg_external_instantiate(GetEntropy, &drbg);
+        if (ret != DRBG_OK)
+            return NTRU_DRBG_ERROR;
+        ret = ntru_crypto_ntru_encrypt(drbg, key->pub.length,
+                            key->pub.buffer, inSz, bufIn, &outSz, NULL);
+        if (ret != NTRU_OK) {
+            return NTRU_ENCRYPT_ERROR;
+        }
+        ntru_crypto_drbg_uninstantiate(drbg);
+        ret = outSz;
+    }
+#endif
+
+    return ret;
+}
+
+/* Generate the secret byte material for pms
+   returns length on success and -1 on fail
+ */
+static int QSH_GenerateSerCliSecret(WOLFSSL* ssl, byte isServer)
+{
+    int sz       = 0;
+    int plainSz  = 48; /* lesser of 48 and max plain text able to encrypt */
+    int offset   = 0;
+    word32 tmpSz = 0;
+    buffer* buf;
+    QSHKey* current;
+    QSHScheme* schmPre = NULL;
+    QSHScheme* schm    = NULL;
+
+    if (ssl == NULL)
+        return -1;
+
+    WOLFSSL_MSG("Generating QSH secret key material");
+
+    current = ssl->peerQSHKey;
+    /* get size of buffer needed */
+    while (current) {
+        if (current->pub.length != 0) {
+            sz += plainSz;
+        }
+        current = (QSHKey*)current->next;
+    }
+
+    /* allocate memory for buffer */
+    if (isServer) {
+        buf = ssl->QSH_secret->SerSi;
+    }
+    else {
+        buf = ssl->QSH_secret->CliSi;
+    }
+    buf->length = sz;
+    buf->buffer = (byte*)XMALLOC(sz, ssl->heap, DYNAMIC_TYPE_SECRET);
+    if (buf->buffer == NULL) {
+        WOLFSSL_ERROR(MEMORY_E);
+    }
+
+    /* create secret information */
+    sz = 0;
+    current = ssl->peerQSHKey;
+    while (current) {
+        schm = (QSHScheme*)XMALLOC(sizeof(QSHScheme), ssl->heap,
+                                                       DYNAMIC_TYPE_QSH);
+        if (schm == NULL)
+            return MEMORY_E;
+
+        /* initialize variables */
+        schm->name  = 0;
+        schm->PK    = NULL;
+        schm->PKLen = 0;
+        schm->next  = NULL;
+        if (ssl->QSH_secret->list == NULL) {
+            ssl->QSH_secret->list = schm;
+        }
+        else {
+            if (schmPre)
+                schmPre->next = schm;
+        }
+
+        tmpSz = QSH_MaxSecret(current);
+
+        if ((schm->PK = (byte*)XMALLOC(tmpSz, ssl->heap,
+                                              DYNAMIC_TYPE_SECRET)) == NULL)
+            return -1;
+
+        /* store info for writing extension */
+        schm->name = current->name;
+
+        /* no key to use for encryption */
+        if (tmpSz == 0) {
+            current = (QSHKey*)current->next;
+            continue;
+        }
+
+        if (wc_RNG_GenerateBlock(ssl->rng, buf->buffer + offset, plainSz)
+                                                                         != 0) {
+            return -1;
+        }
+        if (QSH_Encrypt(current, buf->buffer + offset, plainSz, schm->PK,
+                                                                 &tmpSz) != 0) {
+            return -1;
+        }
+        schm->PKLen = tmpSz;
+
+        sz += tmpSz;
+        offset += plainSz;
+        schmPre = schm;
+        current = (QSHKey*)current->next;
+    }
+
+    return sz;
+}
+
+
+static word32 QSH_KeyGetSize(WOLFSSL* ssl)
+{
+    word32 sz = 0;
+    QSHKey* current;
+
+    if (ssl == NULL)
+        return -1;
+
+    current = ssl->peerQSHKey;
+    sz += OPAQUE16_LEN; /* type of extension ie 0x00 0x18 */
+    sz += OPAQUE24_LEN;
+    /* get size of buffer needed */
+    while (current) {
+        sz += OPAQUE16_LEN; /* scheme id */
+        sz += OPAQUE16_LEN; /* encrypted key len*/
+        sz += QSH_MaxSecret(current);
+        current = (QSHKey*)current->next;
+    }
+
+    return sz;
+}
+
+
+/* handle QSH key Exchange
+   return 0 on success
+ */
+static word32 QSH_KeyExchangeWrite(WOLFSSL* ssl, byte isServer)
+{
+    int ret = 0;
+
+    WOLFSSL_ENTER("QSH KeyExchange");
+
+    ret = QSH_GenerateSerCliSecret(ssl, isServer);
+    if (ret < 0)
+        return MEMORY_E;
+
+    return 0;
+}
+
+#endif /* HAVE_QSH */
+
+
+typedef struct SckeArgs {
+    byte*  output; /* not allocated */
+    byte*  encSecret;
+    byte*  input;
+    word32 encSz;
+    word32 length;
+    int    sendSz;
+    int    inputSz;
+} SckeArgs;
+
+static void FreeSckeArgs(WOLFSSL* ssl, void* pArgs)
+{
+    SckeArgs* args = (SckeArgs*)pArgs;
+
+    (void)ssl;
+
+    if (args->encSecret) {
+        XFREE(args->encSecret, ssl->heap, DYNAMIC_TYPE_SECRET);
+        args->encSecret = NULL;
+    }
+    if (args->input) {
+        XFREE(args->input, ssl->heap, DYNAMIC_TYPE_IN_BUFFER);
+        args->input = NULL;
+    }
+}
+
+/* handle generation client_key_exchange (16) */
+int SendClientKeyExchange(WOLFSSL* ssl)
+{
+    int ret = 0;
+#ifdef WOLFSSL_ASYNC_CRYPT
+    SckeArgs* args = (SckeArgs*)ssl->async.args;
+    typedef char args_test[sizeof(ssl->async.args) >= sizeof(*args) ? 1 : -1];
+    (void)sizeof(args_test);
+#else
+    SckeArgs  args[1];
+#endif
+
+    WOLFSSL_START(WC_FUNC_CLIENT_KEY_EXCHANGE_SEND);
+    WOLFSSL_ENTER("SendClientKeyExchange");
+
+#ifdef OPENSSL_EXTRA
+    ssl->options.clientState = CLIENT_KEYEXCHANGE_COMPLETE;
+    ssl->cbmode = SSL_CB_MODE_WRITE;
+    if (ssl->CBIS != NULL)
+        ssl->CBIS(ssl, SSL_CB_CONNECT_LOOP, SSL_SUCCESS);
+#endif
+
+#ifdef WOLFSSL_ASYNC_CRYPT
+    ret = wolfSSL_AsyncPop(ssl, &ssl->options.asyncState);
+    if (ret != WC_NOT_PENDING_E) {
+        /* Check for error */
+        if (ret < 0)
+            goto exit_scke;
+    }
+    else
+#endif
+    {
+        /* Reset state */
+        ret = 0;
+        ssl->options.asyncState = TLS_ASYNC_BEGIN;
+        XMEMSET(args, 0, sizeof(SckeArgs));
+    #ifdef WOLFSSL_ASYNC_CRYPT
+        ssl->async.freeArgs = FreeSckeArgs;
+    #endif
+    }
+
+    switch(ssl->options.asyncState)
+    {
+        case TLS_ASYNC_BEGIN:
+        {
+            switch (ssl->specs.kea) {
+            #ifndef NO_RSA
+                case rsa_kea:
+                    if (ssl->peerRsaKey == NULL ||
+                        ssl->peerRsaKeyPresent == 0) {
+                        ERROR_OUT(NO_PEER_KEY, exit_scke);
+                    }
+                    break;
+            #endif
+            #ifndef NO_DH
+                case diffie_hellman_kea:
+                    if (ssl->buffers.serverDH_P.buffer == NULL ||
+                        ssl->buffers.serverDH_G.buffer == NULL ||
+                        ssl->buffers.serverDH_Pub.buffer == NULL) {
+                        ERROR_OUT(NO_PEER_KEY, exit_scke);
+                    }
+                    break;
+            #endif /* NO_DH */
+            #ifndef NO_PSK
+                case psk_kea:
+                    /* sanity check that PSK client callback has been set */
+                    if (ssl->options.client_psk_cb == NULL) {
+                        WOLFSSL_MSG("No client PSK callback set");
+                        ERROR_OUT(PSK_KEY_ERROR, exit_scke);
+                    }
+                    break;
+            #endif /* NO_PSK */
+            #if !defined(NO_DH) && !defined(NO_PSK)
+                case dhe_psk_kea:
+                    if (ssl->buffers.serverDH_P.buffer == NULL ||
+                        ssl->buffers.serverDH_G.buffer == NULL ||
+                        ssl->buffers.serverDH_Pub.buffer == NULL) {
+                        ERROR_OUT(NO_PEER_KEY, exit_scke);
+                    }
+
+                    /* sanity check that PSK client callback has been set */
+                    if (ssl->options.client_psk_cb == NULL) {
+                        WOLFSSL_MSG("No client PSK callback set");
+                        ERROR_OUT(PSK_KEY_ERROR, exit_scke);
+                    }
+                    break;
+            #endif /* !NO_DH && !NO_PSK */
+            #if (defined(HAVE_ECC) || defined(HAVE_CURVE25519) || \
+                                     defined(HAVE_CURVE448)) && !defined(NO_PSK)
+                case ecdhe_psk_kea:
+                    /* sanity check that PSK client callback has been set */
+                    if (ssl->options.client_psk_cb == NULL) {
+                        WOLFSSL_MSG("No client PSK callback set");
+                        ERROR_OUT(PSK_KEY_ERROR, exit_scke);
+                    }
+
+                #ifdef HAVE_CURVE25519
+                    if (ssl->peerX25519KeyPresent) {
+                        /* Check client ECC public key */
+                        if (!ssl->peerX25519Key || !ssl->peerX25519Key->dp) {
+                            ERROR_OUT(NO_PEER_KEY, exit_scke);
+                        }
+
+                    #ifdef HAVE_PK_CALLBACKS
+                        /* if callback then use it for shared secret */
+                        if (ssl->ctx->X25519SharedSecretCb != NULL) {
+                            break;
+                        }
+                    #endif
+
+                        /* create private key */
+                        ssl->hsType = DYNAMIC_TYPE_CURVE25519;
+                        ret = AllocKey(ssl, ssl->hsType, &ssl->hsKey);
+                        if (ret != 0) {
+                            goto exit_scke;
+                        }
+
+                        ret = X25519MakeKey(ssl, (curve25519_key*)ssl->hsKey,
+                                            ssl->peerX25519Key);
+                        break;
+                    }
+                #endif
+                #ifdef HAVE_CURVE448
+                    if (ssl->peerX448KeyPresent) {
+                        /* Check client ECC public key */
+                        if (!ssl->peerX448Key) {
+                            ERROR_OUT(NO_PEER_KEY, exit_scke);
+                        }
+
+                    #ifdef HAVE_PK_CALLBACKS
+                        /* if callback then use it for shared secret */
+                        if (ssl->ctx->X448SharedSecretCb != NULL) {
+                            break;
+                        }
+                    #endif
+
+                        /* create private key */
+                        ssl->hsType = DYNAMIC_TYPE_CURVE448;
+                        ret = AllocKey(ssl, ssl->hsType, &ssl->hsKey);
+                        if (ret != 0) {
+                            goto exit_scke;
+                        }
+
+                        ret = X448MakeKey(ssl, (curve448_key*)ssl->hsKey,
+                                          ssl->peerX448Key);
+                        break;
+                    }
+                #endif
+                    /* Check client ECC public key */
+                    if (!ssl->peerEccKey || !ssl->peerEccKeyPresent ||
+                                            !ssl->peerEccKey->dp) {
+                        ERROR_OUT(NO_PEER_KEY, exit_scke);
+                    }
+
+                #ifdef HAVE_PK_CALLBACKS
+                    /* if callback then use it for shared secret */
+                    if (ssl->ctx->EccSharedSecretCb != NULL) {
+                        break;
+                    }
+                #endif
+
+                    /* create ephemeral private key */
+                    ssl->hsType = DYNAMIC_TYPE_ECC;
+                    ret = AllocKey(ssl, ssl->hsType, &ssl->hsKey);
+                    if (ret != 0) {
+                        goto exit_scke;
+                    }
+
+                    ret = EccMakeKey(ssl, (ecc_key*)ssl->hsKey, ssl->peerEccKey);
+
+                    break;
+            #endif /* (HAVE_ECC || HAVE_CURVE25519 || HAVE_CURVE448) && !NO_PSK */
+            #ifdef HAVE_NTRU
+                case ntru_kea:
+                    if (ssl->peerNtruKeyPresent == 0) {
+                        ERROR_OUT(NO_PEER_KEY, exit_scke);
+                    }
+                    break;
+            #endif /* HAVE_NTRU */
+            #if defined(HAVE_ECC) || defined(HAVE_CURVE25519) || \
+                                                          defined(HAVE_CURVE448)
+                case ecc_diffie_hellman_kea:
+                {
+                #ifdef HAVE_ECC
+                    ecc_key* peerKey;
+                #endif
+
+            #ifdef HAVE_PK_CALLBACKS
+                    /* if callback then use it for shared secret */
+                #ifdef HAVE_CURVE25519
+                    if (ssl->ecdhCurveOID == ECC_X25519_OID) {
+                        if (ssl->ctx->X25519SharedSecretCb != NULL)
+                            break;
+                    }
+                    else
+                #endif
+                #ifdef HAVE_CURVE448
+                    if (ssl->ecdhCurveOID == ECC_X448_OID) {
+                        if (ssl->ctx->X448SharedSecretCb != NULL)
+                            break;
+                    }
+                    else
+                #endif
+                    if (ssl->ctx->EccSharedSecretCb != NULL) {
+                        break;
+                    }
+            #endif /* HAVE_PK_CALLBACKS */
+
+                #ifdef HAVE_CURVE25519
+                    if (ssl->peerX25519KeyPresent) {
+                        if (!ssl->peerX25519Key || !ssl->peerX25519Key->dp) {
+                            ERROR_OUT(NO_PEER_KEY, exit_scke);
+                        }
+
+                        /* create private key */
+                        ssl->hsType = DYNAMIC_TYPE_CURVE25519;
+                        ret = AllocKey(ssl, ssl->hsType, &ssl->hsKey);
+                        if (ret != 0) {
+                            goto exit_scke;
+                        }
+
+                        ret = X25519MakeKey(ssl, (curve25519_key*)ssl->hsKey,
+                                            ssl->peerX25519Key);
+                        break;
+                    }
+                #endif
+                #ifdef HAVE_CURVE448
+                    if (ssl->peerX448KeyPresent) {
+                        if (!ssl->peerX448Key) {
+                            ERROR_OUT(NO_PEER_KEY, exit_scke);
+                        }
+
+                        /* create private key */
+                        ssl->hsType = DYNAMIC_TYPE_CURVE448;
+                        ret = AllocKey(ssl, ssl->hsType, &ssl->hsKey);
+                        if (ret != 0) {
+                            goto exit_scke;
+                        }
+
+                        ret = X448MakeKey(ssl, (curve448_key*)ssl->hsKey,
+                                          ssl->peerX448Key);
+                        break;
+                    }
+                #endif
+                #ifdef HAVE_ECC
+                    if (ssl->specs.static_ecdh) {
+                        /* Note: EccDsa is really fixed Ecc key here */
+                        if (!ssl->peerEccDsaKey || !ssl->peerEccDsaKeyPresent) {
+                            ERROR_OUT(NO_PEER_KEY, exit_scke);
+                        }
+                        peerKey = ssl->peerEccDsaKey;
+                    }
+                    else {
+                        if (!ssl->peerEccKey || !ssl->peerEccKeyPresent) {
+                            ERROR_OUT(NO_PEER_KEY, exit_scke);
+                        }
+                        peerKey = ssl->peerEccKey;
+                    }
+                    if (peerKey == NULL) {
+                        ERROR_OUT(NO_PEER_KEY, exit_scke);
+                    }
+
+                    /* create ephemeral private key */
+                    ssl->hsType = DYNAMIC_TYPE_ECC;
+                    ret = AllocKey(ssl, ssl->hsType, &ssl->hsKey);
+                    if (ret != 0) {
+                        goto exit_scke;
+                    }
+
+                    ret = EccMakeKey(ssl, (ecc_key*)ssl->hsKey, peerKey);
+                #endif
+
+                    break;
+                }
+            #endif /* HAVE_ECC || HAVE_CURVE25519 || HAVE_CURVE448 */
+
+                default:
+                    ret = BAD_KEA_TYPE_E;
+            } /* switch(ssl->specs.kea) */
+
+            /* Check for error */
+            if (ret != 0) {
+                goto exit_scke;
+            }
+
+            /* Advance state and proceed */
+            ssl->options.asyncState = TLS_ASYNC_BUILD;
+        } /* case TLS_ASYNC_BEGIN */
+        FALL_THROUGH;
+
+        case TLS_ASYNC_BUILD:
+        {
+            args->encSz = MAX_ENCRYPT_SZ;
+            args->encSecret = (byte*)XMALLOC(args->encSz, ssl->heap,
+                                                    DYNAMIC_TYPE_SECRET);
+            if (args->encSecret == NULL) {
+                ERROR_OUT(MEMORY_E, exit_scke);
+            }
+            if (ssl->arrays->preMasterSecret == NULL) {
+                ssl->arrays->preMasterSz = ENCRYPT_LEN;
+                ssl->arrays->preMasterSecret = (byte*)XMALLOC(ENCRYPT_LEN,
+                                                ssl->heap, DYNAMIC_TYPE_SECRET);
+                if (ssl->arrays->preMasterSecret == NULL) {
+                    ERROR_OUT(MEMORY_E, exit_scke);
+                }
+                XMEMSET(ssl->arrays->preMasterSecret, 0, ENCRYPT_LEN);
+            }
+
+            switch(ssl->specs.kea)
+            {
+            #ifndef NO_RSA
+                case rsa_kea:
+                {
+                    /* build PreMasterSecret with RNG data */
+                    #if defined(WOLFSSL_RENESAS_TSIP_TLS) && \
+                       !defined(NO_WOLFSSL_RENESAS_TSIP_TLS_SESSION)
+                    if (tsip_useable(ssl)) {
+                        ret = tsip_generatePremasterSecret(
+                        &ssl->arrays->preMasterSecret[VERSION_SZ],
+                        ENCRYPT_LEN - VERSION_SZ);
+                    } else {
+                    #endif
+                        ret = wc_RNG_GenerateBlock(ssl->rng,
+                            &ssl->arrays->preMasterSecret[VERSION_SZ],
+                            SECRET_LEN - VERSION_SZ);
+                    #if defined(WOLFSSL_RENESAS_TSIP_TLS) && \
+                       !defined(NO_WOLFSSL_RENESAS_TSIP_TLS_SESSION)
+                    }
+                    #endif
+                        if (ret != 0) {
+                            goto exit_scke;
+                        }
+
+                        ssl->arrays->preMasterSecret[0] = ssl->chVersion.major;
+                        ssl->arrays->preMasterSecret[1] = ssl->chVersion.minor;
+
+                    ssl->arrays->preMasterSz = SECRET_LEN;
+
+                    break;
+                }
+            #endif /* !NO_RSA */
+            #ifndef NO_DH
+                case diffie_hellman_kea:
+                {
+                    ssl->buffers.sig.length = ENCRYPT_LEN;
+                    ssl->buffers.sig.buffer = (byte*)XMALLOC(ENCRYPT_LEN,
+                                            ssl->heap, DYNAMIC_TYPE_SIGNATURE);
+                    if (ssl->buffers.sig.buffer == NULL) {
+                        ERROR_OUT(MEMORY_E, exit_scke);
+                    }
+
+                    ret = AllocKey(ssl, DYNAMIC_TYPE_DH,
+                                            (void**)&ssl->buffers.serverDH_Key);
+                    if (ret != 0) {
+                        goto exit_scke;
+                    }
+
+                    #if !defined(HAVE_FIPS) && !defined(HAVE_SELFTEST) && \
+                        !defined(WOLFSSL_OLD_PRIME_CHECK)
+                    if (ssl->options.dhDoKeyTest &&
+                        !ssl->options.dhKeyTested)
+                    {
+                        ret = wc_DhSetCheckKey(ssl->buffers.serverDH_Key,
+                            ssl->buffers.serverDH_P.buffer,
+                            ssl->buffers.serverDH_P.length,
+                            ssl->buffers.serverDH_G.buffer,
+                            ssl->buffers.serverDH_G.length,
+                            NULL, 0, 0, ssl->rng);
+                        if (ret != 0) {
+                            goto exit_scke;
+                        }
+                        ssl->options.dhKeyTested = 1;
+                    }
+                    else
+                    #endif
+                    {
+                        ret = wc_DhSetKey(ssl->buffers.serverDH_Key,
+                            ssl->buffers.serverDH_P.buffer,
+                            ssl->buffers.serverDH_P.length,
+                            ssl->buffers.serverDH_G.buffer,
+                            ssl->buffers.serverDH_G.length);
+                        if (ret != 0) {
+                            goto exit_scke;
+                        }
+                    }
+
+                    /* for DH, encSecret is Yc, agree is pre-master */
+                    ret = DhGenKeyPair(ssl, ssl->buffers.serverDH_Key,
+                        ssl->buffers.sig.buffer, (word32*)&ssl->buffers.sig.length,
+                        args->encSecret, &args->encSz);
+
+                    /* set the max agree result size */
+                    ssl->arrays->preMasterSz = ENCRYPT_LEN;
+                    break;
+                }
+            #endif /* !NO_DH */
+            #ifndef NO_PSK
+                case psk_kea:
+                {
+                    byte* pms = ssl->arrays->preMasterSecret;
+                    ssl->arrays->psk_keySz = ssl->options.client_psk_cb(ssl,
+                        ssl->arrays->server_hint, ssl->arrays->client_identity,
+                        MAX_PSK_ID_LEN, ssl->arrays->psk_key, MAX_PSK_KEY_LEN);
+                    if (ssl->arrays->psk_keySz == 0 ||
+                        ssl->arrays->psk_keySz > MAX_PSK_KEY_LEN) {
+                        ERROR_OUT(PSK_KEY_ERROR, exit_scke);
+                    }
+                    ssl->arrays->client_identity[MAX_PSK_ID_LEN] = '\0'; /* null term */
+                    args->encSz = (word32)XSTRLEN(ssl->arrays->client_identity);
+                    if (args->encSz > MAX_PSK_ID_LEN) {
+                        ERROR_OUT(CLIENT_ID_ERROR, exit_scke);
+                    }
+                    XMEMCPY(args->encSecret, ssl->arrays->client_identity,
+                                                                args->encSz);
+
+                    /* make psk pre master secret */
+                    /* length of key + length 0s + length of key + key */
+                    c16toa((word16)ssl->arrays->psk_keySz, pms);
+                    pms += OPAQUE16_LEN;
+                    XMEMSET(pms, 0, ssl->arrays->psk_keySz);
+                    pms += ssl->arrays->psk_keySz;
+                    c16toa((word16)ssl->arrays->psk_keySz, pms);
+                    pms += OPAQUE16_LEN;
+                    XMEMCPY(pms, ssl->arrays->psk_key, ssl->arrays->psk_keySz);
+                    ssl->arrays->preMasterSz = (ssl->arrays->psk_keySz * 2) +
+                        (2 * OPAQUE16_LEN);
+                    ForceZero(ssl->arrays->psk_key, ssl->arrays->psk_keySz);
+                    ssl->arrays->psk_keySz = 0; /* No further need */
+                    break;
+                }
+            #endif /* !NO_PSK */
+            #if !defined(NO_DH) && !defined(NO_PSK)
+                case dhe_psk_kea:
+                {
+                    word32 esSz = 0;
+                    args->output = args->encSecret;
+
+                    ssl->arrays->psk_keySz = ssl->options.client_psk_cb(ssl,
+                         ssl->arrays->server_hint, ssl->arrays->client_identity,
+                         MAX_PSK_ID_LEN, ssl->arrays->psk_key, MAX_PSK_KEY_LEN);
+                    if (ssl->arrays->psk_keySz == 0 ||
+                                     ssl->arrays->psk_keySz > MAX_PSK_KEY_LEN) {
+                        ERROR_OUT(PSK_KEY_ERROR, exit_scke);
+                    }
+                    ssl->arrays->client_identity[MAX_PSK_ID_LEN] = '\0'; /* null term */
+                    esSz = (word32)XSTRLEN(ssl->arrays->client_identity);
+
+                    if (esSz > MAX_PSK_ID_LEN) {
+                        ERROR_OUT(CLIENT_ID_ERROR, exit_scke);
+                    }
+
+                    ssl->buffers.sig.length = ENCRYPT_LEN;
+                    ssl->buffers.sig.buffer = (byte*)XMALLOC(ENCRYPT_LEN,
+                                            ssl->heap, DYNAMIC_TYPE_SIGNATURE);
+                    if (ssl->buffers.sig.buffer == NULL) {
+                        ERROR_OUT(MEMORY_E, exit_scke);
+                    }
+
+                    c16toa((word16)esSz, args->output);
+                    args->output += OPAQUE16_LEN;
+                    XMEMCPY(args->output, ssl->arrays->client_identity, esSz);
+                    args->output += esSz;
+                    args->encSz = esSz + OPAQUE16_LEN;
+
+                    args->length = 0;
+
+                    ret = AllocKey(ssl, DYNAMIC_TYPE_DH,
+                                            (void**)&ssl->buffers.serverDH_Key);
+                    if (ret != 0) {
+                        goto exit_scke;
+                    }
+
+                    #if !defined(HAVE_FIPS) && !defined(HAVE_SELFTEST) && \
+                        !defined(WOLFSSL_OLD_PRIME_CHECK)
+                    if (ssl->options.dhDoKeyTest &&
+                        !ssl->options.dhKeyTested)
+                    {
+                        ret = wc_DhSetCheckKey(ssl->buffers.serverDH_Key,
+                            ssl->buffers.serverDH_P.buffer,
+                            ssl->buffers.serverDH_P.length,
+                            ssl->buffers.serverDH_G.buffer,
+                            ssl->buffers.serverDH_G.length,
+                            NULL, 0, 0, ssl->rng);
+                        if (ret != 0) {
+                            goto exit_scke;
+                        }
+                        ssl->options.dhKeyTested = 1;
+                    }
+                    else
+                    #endif
+                    {
+                        ret = wc_DhSetKey(ssl->buffers.serverDH_Key,
+                            ssl->buffers.serverDH_P.buffer,
+                            ssl->buffers.serverDH_P.length,
+                            ssl->buffers.serverDH_G.buffer,
+                            ssl->buffers.serverDH_G.length);
+                        if (ret != 0) {
+                            goto exit_scke;
+                        }
+                    }
+
+                    /* for DH, encSecret is Yc, agree is pre-master */
+                    ret = DhGenKeyPair(ssl, ssl->buffers.serverDH_Key,
+                        ssl->buffers.sig.buffer, (word32*)&ssl->buffers.sig.length,
+                        args->output + OPAQUE16_LEN, &args->length);
+                    break;
+                }
+            #endif /* !NO_DH && !NO_PSK */
+            #if (defined(HAVE_ECC) || defined(HAVE_CURVE25519) || \
+                                     defined(HAVE_CURVE448)) && !defined(NO_PSK)
+                case ecdhe_psk_kea:
+                {
+                    word32 esSz = 0;
+                    args->output = args->encSecret;
+
+                    /* Send PSK client identity */
+                    ssl->arrays->psk_keySz = ssl->options.client_psk_cb(ssl,
+                         ssl->arrays->server_hint, ssl->arrays->client_identity,
+                         MAX_PSK_ID_LEN, ssl->arrays->psk_key, MAX_PSK_KEY_LEN);
+                    if (ssl->arrays->psk_keySz == 0 ||
+                                     ssl->arrays->psk_keySz > MAX_PSK_KEY_LEN) {
+                        ERROR_OUT(PSK_KEY_ERROR, exit_scke);
+                    }
+                    ssl->arrays->client_identity[MAX_PSK_ID_LEN] = '\0'; /* null term */
+                    esSz = (word32)XSTRLEN(ssl->arrays->client_identity);
+                    if (esSz > MAX_PSK_ID_LEN) {
+                        ERROR_OUT(CLIENT_ID_ERROR, exit_scke);
+                    }
+
+                    /* place size and identity in output buffer sz:identity */
+                    c16toa((word16)esSz, args->output);
+                    args->output += OPAQUE16_LEN;
+                    XMEMCPY(args->output, ssl->arrays->client_identity, esSz);
+                    args->output += esSz;
+                    args->encSz = esSz + OPAQUE16_LEN;
+
+                    /* length is used for public key size */
+                    args->length = MAX_ENCRYPT_SZ;
+
+                    /* Create shared ECC key leaving room at the beginning
+                       of buffer for size of shared key. */
+                    ssl->arrays->preMasterSz = ENCRYPT_LEN - OPAQUE16_LEN;
+
+                #ifdef HAVE_CURVE25519
+                    if (ssl->ecdhCurveOID == ECC_X25519_OID) {
+                    #ifdef HAVE_PK_CALLBACKS
+                        /* if callback then use it for shared secret */
+                        if (ssl->ctx->X25519SharedSecretCb != NULL) {
+                            break;
+                        }
+                    #endif
+
+                        ret = wc_curve25519_export_public_ex(
+                                (curve25519_key*)ssl->hsKey,
+                                args->output + OPAQUE8_LEN, &args->length,
+                                EC25519_LITTLE_ENDIAN);
+                        if (ret != 0) {
+                            ERROR_OUT(ECC_EXPORT_ERROR, exit_scke);
+                        }
+
+                        break;
+                    }
+                #endif
+                #ifdef HAVE_CURVE448
+                    if (ssl->ecdhCurveOID == ECC_X448_OID) {
+                    #ifdef HAVE_PK_CALLBACKS
+                        /* if callback then use it for shared secret */
+                        if (ssl->ctx->X448SharedSecretCb != NULL) {
+                            break;
+                        }
+                    #endif
+
+                        ret = wc_curve448_export_public_ex(
+                                (curve448_key*)ssl->hsKey,
+                                args->output + OPAQUE8_LEN, &args->length,
+                                EC448_LITTLE_ENDIAN);
+                        if (ret != 0) {
+                            ERROR_OUT(ECC_EXPORT_ERROR, exit_scke);
+                        }
+
+                        break;
+                    }
+                #endif
+                #ifdef HAVE_PK_CALLBACKS
+                    /* if callback then use it for shared secret */
+                    if (ssl->ctx->EccSharedSecretCb != NULL) {
+                        break;
+                    }
+                #endif
+
+                    /* Place ECC key in output buffer, leaving room for size */
+                    ret = wc_ecc_export_x963((ecc_key*)ssl->hsKey,
+                                    args->output + OPAQUE8_LEN, &args->length);
+                    if (ret != 0) {
+                        ERROR_OUT(ECC_EXPORT_ERROR, exit_scke);
+                    }
+
+                    break;
+                }
+            #endif /* (HAVE_ECC || HAVE_CURVE25519 || HAVE_CURVE448) && !NO_PSK */
+            #ifdef HAVE_NTRU
+                case ntru_kea:
+                {
+                    ret = wc_RNG_GenerateBlock(ssl->rng,
+                                  ssl->arrays->preMasterSecret, SECRET_LEN);
+                    if (ret != 0) {
+                        goto exit_scke;
+                    }
+
+                    ssl->arrays->preMasterSz = SECRET_LEN;
+                    args->encSz = MAX_ENCRYPT_SZ;
+                    break;
+                }
+            #endif /* HAVE_NTRU */
+            #if defined(HAVE_ECC) || defined(HAVE_CURVE25519) || \
+                                                          defined(HAVE_CURVE448)
+                case ecc_diffie_hellman_kea:
+                {
+                    ssl->arrays->preMasterSz = ENCRYPT_LEN;
+
+                #ifdef HAVE_CURVE25519
+                    if (ssl->hsType == DYNAMIC_TYPE_CURVE25519) {
+                    #ifdef HAVE_PK_CALLBACKS
+                        /* if callback then use it for shared secret */
+                        if (ssl->ctx->X25519SharedSecretCb != NULL) {
+                            break;
+                        }
+                    #endif
+
+                        ret = wc_curve25519_export_public_ex(
+                                (curve25519_key*)ssl->hsKey,
+                                args->encSecret + OPAQUE8_LEN, &args->encSz,
+                                EC25519_LITTLE_ENDIAN);
+                        if (ret != 0) {
+                            ERROR_OUT(ECC_EXPORT_ERROR, exit_scke);
+                        }
+
+                        break;
+                    }
+                #endif
+                #ifdef HAVE_CURVE448
+                    if (ssl->hsType == DYNAMIC_TYPE_CURVE448) {
+                    #ifdef HAVE_PK_CALLBACKS
+                        /* if callback then use it for shared secret */
+                        if (ssl->ctx->X448SharedSecretCb != NULL) {
+                            break;
+                        }
+                    #endif
+
+                        ret = wc_curve448_export_public_ex(
+                                (curve448_key*)ssl->hsKey,
+                                args->encSecret + OPAQUE8_LEN, &args->encSz,
+                                EC448_LITTLE_ENDIAN);
+                        if (ret != 0) {
+                            ERROR_OUT(ECC_EXPORT_ERROR, exit_scke);
+                        }
+
+                        break;
+                    }
+                #endif
+                #if defined(HAVE_ECC) && defined(HAVE_ECC_KEY_EXPORT)
+                #ifdef HAVE_PK_CALLBACKS
+                    /* if callback then use it for shared secret */
+                    if (ssl->ctx->EccSharedSecretCb != NULL) {
+                        break;
+                    }
+                #endif
+
+                    /* Place ECC key in buffer, leaving room for size */
+                    ret = wc_ecc_export_x963((ecc_key*)ssl->hsKey,
+                                args->encSecret + OPAQUE8_LEN, &args->encSz);
+                    if (ret != 0) {
+                        ERROR_OUT(ECC_EXPORT_ERROR, exit_scke);
+                    }
+                #endif /* HAVE_ECC */
+                    break;
+                }
+            #endif /* HAVE_ECC || HAVE_CURVE25519 || HAVE_CURVE448 */
+
+                default:
+                    ret = BAD_KEA_TYPE_E;
+            } /* switch(ssl->specs.kea) */
+
+            /* Check for error */
+            if (ret != 0) {
+                goto exit_scke;
+            }
+
+            /* Advance state and proceed */
+            ssl->options.asyncState = TLS_ASYNC_DO;
+        } /* case TLS_ASYNC_BUILD */
+        FALL_THROUGH;
+
+        case TLS_ASYNC_DO:
+        {
+            switch(ssl->specs.kea)
+            {
+            #ifndef NO_RSA
+                case rsa_kea:
+                {
+                    #if defined(WOLFSSL_RENESAS_TSIP_TLS) && \
+                       !defined(NO_WOLFSSL_RENESAS_TSIP_TLS_SESSION)
+                    if (tsip_useable(ssl) &&
+                                     wc_RsaEncryptSize(ssl->peerRsaKey) == 256) {
+                        ret = tsip_generateEncryptPreMasterSecret(ssl,
+                                                            args->encSecret,
+                                                            &args->encSz);
+
+                    } else
+                    #endif
+                        ret = RsaEnc(ssl,
+                            ssl->arrays->preMasterSecret, SECRET_LEN,
+                            args->encSecret, &args->encSz,
+                            ssl->peerRsaKey,
+                        #if defined(HAVE_PK_CALLBACKS)
+                            &ssl->buffers.peerRsaKey
+                        #else
+                            NULL
+                        #endif
+                        );
+
+                    break;
+                }
+            #endif /* !NO_RSA */
+            #ifndef NO_DH
+                case diffie_hellman_kea:
+                {
+                    ret = DhAgree(ssl, ssl->buffers.serverDH_Key,
+                        ssl->buffers.sig.buffer, ssl->buffers.sig.length,
+                        ssl->buffers.serverDH_Pub.buffer,
+                        ssl->buffers.serverDH_Pub.length,
+                        ssl->arrays->preMasterSecret,
+                        &ssl->arrays->preMasterSz);
+                    break;
+                }
+            #endif /* !NO_DH */
+            #ifndef NO_PSK
+                case psk_kea:
+                {
+                    break;
+                }
+            #endif /* !NO_PSK */
+            #if !defined(NO_DH) && !defined(NO_PSK)
+                case dhe_psk_kea:
+                {
+                    ret = DhAgree(ssl, ssl->buffers.serverDH_Key,
+                        ssl->buffers.sig.buffer, ssl->buffers.sig.length,
+                        ssl->buffers.serverDH_Pub.buffer,
+                        ssl->buffers.serverDH_Pub.length,
+                        ssl->arrays->preMasterSecret + OPAQUE16_LEN,
+                        &ssl->arrays->preMasterSz);
+                    break;
+                }
+            #endif /* !NO_DH && !NO_PSK */
+            #if (defined(HAVE_ECC) || defined(HAVE_CURVE25519) || \
+                                     defined(HAVE_CURVE448)) && !defined(NO_PSK)
+                case ecdhe_psk_kea:
+                {
+                #ifdef HAVE_CURVE25519
+                    if (ssl->peerX25519KeyPresent) {
+                        ret = X25519SharedSecret(ssl,
+                            (curve25519_key*)ssl->hsKey, ssl->peerX25519Key,
+                            args->output + OPAQUE8_LEN, &args->length,
+                            ssl->arrays->preMasterSecret + OPAQUE16_LEN,
+                            &ssl->arrays->preMasterSz,
+                            WOLFSSL_CLIENT_END
+                        );
+                        if (!ssl->specs.static_ecdh
+                        #ifdef WOLFSSL_ASYNC_CRYPT
+                            && ret != WC_PENDING_E
+                        #endif
+                        ) {
+                            FreeKey(ssl, DYNAMIC_TYPE_CURVE25519,
+                                                   (void**)&ssl->peerX25519Key);
+                            ssl->peerX25519KeyPresent = 0;
+                        }
+                        break;
+                    }
+                #endif
+                #ifdef HAVE_CURVE448
+                    if (ssl->peerX448KeyPresent) {
+                        ret = X448SharedSecret(ssl,
+                            (curve448_key*)ssl->hsKey, ssl->peerX448Key,
+                            args->output + OPAQUE8_LEN, &args->length,
+                            ssl->arrays->preMasterSecret + OPAQUE16_LEN,
+                            &ssl->arrays->preMasterSz,
+                            WOLFSSL_CLIENT_END
+                        );
+                        if (!ssl->specs.static_ecdh
+                        #ifdef WOLFSSL_ASYNC_CRYPT
+                            && ret != WC_PENDING_E
+                        #endif
+                        ) {
+                            FreeKey(ssl, DYNAMIC_TYPE_CURVE448,
+                                                     (void**)&ssl->peerX448Key);
+                            ssl->peerX448KeyPresent = 0;
+                        }
+                        break;
+                    }
+                #endif
+                    ret = EccSharedSecret(ssl,
+                        (ecc_key*)ssl->hsKey, ssl->peerEccKey,
+                        args->output + OPAQUE8_LEN, &args->length,
+                        ssl->arrays->preMasterSecret + OPAQUE16_LEN,
+                        &ssl->arrays->preMasterSz,
+                        WOLFSSL_CLIENT_END
+                    );
+                #ifdef WOLFSSL_ASYNC_CRYPT
+                    if (ret != WC_PENDING_E)
+                #endif
+                    {
+                        FreeKey(ssl, DYNAMIC_TYPE_ECC,
+                                                      (void**)&ssl->peerEccKey);
+                        ssl->peerEccKeyPresent = 0;
+                    }
+                    break;
+                }
+            #endif /* (HAVE_ECC || HAVE_CURVE25519 || HAVE_CURVE448) && !NO_PSK */
+            #ifdef HAVE_NTRU
+                case ntru_kea:
+                {
+                    word32 rc;
+                    word16 tmpEncSz = (word16)args->encSz;
+                    DRBG_HANDLE drbg;
+
+                    rc = ntru_crypto_drbg_external_instantiate(GetEntropy, &drbg);
+                    if (rc != DRBG_OK) {
+                        ERROR_OUT(NTRU_DRBG_ERROR, exit_scke);
+                    }
+                    rc = ntru_crypto_ntru_encrypt(drbg, ssl->peerNtruKeyLen,
+                                                  ssl->peerNtruKey,
+                                                  ssl->arrays->preMasterSz,
+                                                  ssl->arrays->preMasterSecret,
+                                                  &tmpEncSz,
+                                                  args->encSecret);
+                    args->encSz = tmpEncSz;
+                    ntru_crypto_drbg_uninstantiate(drbg);
+                    if (rc != NTRU_OK) {
+                        ERROR_OUT(NTRU_ENCRYPT_ERROR, exit_scke);
+                    }
+                    ret = 0;
+                    break;
+                }
+            #endif /* HAVE_NTRU */
+            #if defined(HAVE_ECC) || defined(HAVE_CURVE25519) || \
+                                                          defined(HAVE_CURVE448)
+                case ecc_diffie_hellman_kea:
+                {
+                #ifdef HAVE_ECC
+                    ecc_key* peerKey;
+                #endif
+
+                #ifdef HAVE_CURVE25519
+                    if (ssl->peerX25519KeyPresent) {
+                        ret = X25519SharedSecret(ssl,
+                            (curve25519_key*)ssl->hsKey, ssl->peerX25519Key,
+                            args->encSecret + OPAQUE8_LEN, &args->encSz,
+                            ssl->arrays->preMasterSecret,
+                            &ssl->arrays->preMasterSz,
+                            WOLFSSL_CLIENT_END
+                        );
+                        if (!ssl->specs.static_ecdh
+                        #ifdef WOLFSSL_ASYNC_CRYPT
+                            && ret != WC_PENDING_E
+                        #endif
+                        ) {
+                            FreeKey(ssl, DYNAMIC_TYPE_CURVE25519,
+                                                   (void**)&ssl->peerX25519Key);
+                            ssl->peerX25519KeyPresent = 0;
+                        }
+                        break;
+                    }
+                #endif
+                #ifdef HAVE_CURVE448
+                    if (ssl->peerX448KeyPresent) {
+                        ret = X448SharedSecret(ssl,
+                            (curve448_key*)ssl->hsKey, ssl->peerX448Key,
+                            args->encSecret + OPAQUE8_LEN, &args->encSz,
+                            ssl->arrays->preMasterSecret,
+                            &ssl->arrays->preMasterSz,
+                            WOLFSSL_CLIENT_END
+                        );
+                        if (!ssl->specs.static_ecdh
+                        #ifdef WOLFSSL_ASYNC_CRYPT
+                            && ret != WC_PENDING_E
+                        #endif
+                        ) {
+                            FreeKey(ssl, DYNAMIC_TYPE_CURVE448,
+                                                     (void**)&ssl->peerX448Key);
+                            ssl->peerX448KeyPresent = 0;
+                        }
+                        break;
+                    }
+                #endif
+                #ifdef HAVE_ECC
+                    peerKey = (ssl->specs.static_ecdh) ?
+                              ssl->peerEccDsaKey : ssl->peerEccKey;
+
+                    ret = EccSharedSecret(ssl,
+                        (ecc_key*)ssl->hsKey, peerKey,
+                        args->encSecret + OPAQUE8_LEN, &args->encSz,
+                        ssl->arrays->preMasterSecret,
+                        &ssl->arrays->preMasterSz,
+                        WOLFSSL_CLIENT_END
+                    );
+                    if (!ssl->specs.static_ecdh
+                #ifdef WOLFSSL_ASYNC_CRYPT
+                        && ret != WC_PENDING_E
+                #endif
+                     && !ssl->options.keepResources) {
+                        FreeKey(ssl, DYNAMIC_TYPE_ECC,
+                                                      (void**)&ssl->peerEccKey);
+                        ssl->peerEccKeyPresent = 0;
+                    }
+                #endif
+
+                    break;
+                }
+            #endif /* HAVE_ECC || HAVE_CURVE25519 || HAVE_CURVE448 */
+
+                default:
+                    ret = BAD_KEA_TYPE_E;
+            } /* switch(ssl->specs.kea) */
+
+            /* Check for error */
+            if (ret != 0) {
+                goto exit_scke;
+            }
+
+            /* Advance state and proceed */
+            ssl->options.asyncState = TLS_ASYNC_VERIFY;
+        } /* case TLS_ASYNC_DO */
+        FALL_THROUGH;
+
+        case TLS_ASYNC_VERIFY:
+        {
+            switch(ssl->specs.kea)
+            {
+            #ifndef NO_RSA
+                case rsa_kea:
+                {
+                    break;
+                }
+            #endif /* !NO_RSA */
+            #ifndef NO_DH
+                case diffie_hellman_kea:
+                {
+                    break;
+                }
+            #endif /* !NO_DH */
+            #ifndef NO_PSK
+                case psk_kea:
+                {
+                    break;
+                }
+            #endif /* !NO_PSK */
+            #if !defined(NO_DH) && !defined(NO_PSK)
+                case dhe_psk_kea:
+                {
+                    byte* pms = ssl->arrays->preMasterSecret;
+
+                    /* validate args */
+                    if (args->output == NULL || args->length == 0) {
+                        ERROR_OUT(BAD_FUNC_ARG, exit_scke);
+                    }
+
+                    c16toa((word16)args->length, args->output);
+                    args->encSz += args->length + OPAQUE16_LEN;
+                    c16toa((word16)ssl->arrays->preMasterSz, pms);
+                    ssl->arrays->preMasterSz += OPAQUE16_LEN;
+                    pms += ssl->arrays->preMasterSz;
+
+                    /* make psk pre master secret */
+                    /* length of key + length 0s + length of key + key */
+                    c16toa((word16)ssl->arrays->psk_keySz, pms);
+                    pms += OPAQUE16_LEN;
+                    XMEMCPY(pms, ssl->arrays->psk_key, ssl->arrays->psk_keySz);
+                    ssl->arrays->preMasterSz +=
+                                         ssl->arrays->psk_keySz + OPAQUE16_LEN;
+                    ForceZero(ssl->arrays->psk_key, ssl->arrays->psk_keySz);
+                    ssl->arrays->psk_keySz = 0; /* No further need */
+                    break;
+                }
+            #endif /* !NO_DH && !NO_PSK */
+            #if (defined(HAVE_ECC) || defined(HAVE_CURVE25519) || \
+                                     defined(HAVE_CURVE448)) && !defined(NO_PSK)
+                case ecdhe_psk_kea:
+                {
+                    byte* pms = ssl->arrays->preMasterSecret;
+
+                    /* validate args */
+                    if (args->output == NULL || args->length > ENCRYPT_LEN) {
+                        ERROR_OUT(BAD_FUNC_ARG, exit_scke);
+                    }
+
+                    /* place size of public key in output buffer */
+                    *args->output = (byte)args->length;
+                    args->encSz += args->length + OPAQUE8_LEN;
+
+                    /* Create pre master secret is the concatenation of
+                       eccSize + eccSharedKey + pskSize + pskKey */
+                    c16toa((word16)ssl->arrays->preMasterSz, pms);
+                    ssl->arrays->preMasterSz += OPAQUE16_LEN;
+                    pms += ssl->arrays->preMasterSz;
+
+                    c16toa((word16)ssl->arrays->psk_keySz, pms);
+                    pms += OPAQUE16_LEN;
+                    XMEMCPY(pms, ssl->arrays->psk_key, ssl->arrays->psk_keySz);
+                    ssl->arrays->preMasterSz +=
+                                          ssl->arrays->psk_keySz + OPAQUE16_LEN;
+
+                    ForceZero(ssl->arrays->psk_key, ssl->arrays->psk_keySz);
+                    ssl->arrays->psk_keySz = 0; /* No further need */
+                    break;
+                }
+            #endif /* (HAVE_ECC || HAVE_CURVE25519 || HAVE_CURVE448) && !NO_PSK */
+            #ifdef HAVE_NTRU
+                case ntru_kea:
+                {
+                    break;
+                }
+            #endif /* HAVE_NTRU */
+            #if defined(HAVE_ECC) || defined(HAVE_CURVE25519) || \
+                                                          defined(HAVE_CURVE448)
+                case ecc_diffie_hellman_kea:
+                {
+                    /* place size of public key in buffer */
+                    *args->encSecret = (byte)args->encSz;
+                    args->encSz += OPAQUE8_LEN;
+                    break;
+                }
+            #endif /* HAVE_ECC || HAVE_CURVE25519 || HAVE_CURVE448 */
+
+                default:
+                    ret = BAD_KEA_TYPE_E;
+            } /* switch(ssl->specs.kea) */
+
+            /* Check for error */
+            if (ret != 0) {
+                goto exit_scke;
+            }
+
+            /* Advance state and proceed */
+            ssl->options.asyncState = TLS_ASYNC_FINALIZE;
+        } /* case TLS_ASYNC_VERIFY */
+        FALL_THROUGH;
+
+        case TLS_ASYNC_FINALIZE:
+        {
+            word32 tlsSz = 0;
+            word32 idx = 0;
+
+        #ifdef HAVE_QSH
+            word32 qshSz = 0;
+            if (ssl->peerQSHKeyPresent) {
+                qshSz = QSH_KeyGetSize(ssl);
+            }
+        #endif
+
+            if (ssl->options.tls || ssl->specs.kea == diffie_hellman_kea) {
+                tlsSz = 2;
+            }
+
+            if (ssl->specs.kea == ecc_diffie_hellman_kea ||
+                ssl->specs.kea == dhe_psk_kea ||
+                ssl->specs.kea == ecdhe_psk_kea) { /* always off */
+                tlsSz = 0;
+            }
+
+            idx = HANDSHAKE_HEADER_SZ + RECORD_HEADER_SZ;
+            args->sendSz = args->encSz + tlsSz + idx;
+
+        #ifdef WOLFSSL_DTLS
+            if (ssl->options.dtls) {
+                idx    += DTLS_HANDSHAKE_EXTRA + DTLS_RECORD_EXTRA;
+                args->sendSz += DTLS_HANDSHAKE_EXTRA + DTLS_RECORD_EXTRA;
+            }
+        #endif
+
+            if (IsEncryptionOn(ssl, 1)) {
+                args->sendSz += MAX_MSG_EXTRA;
+            }
+
+        #ifdef HAVE_QSH
+            args->encSz += qshSz;
+            args->sendSz += qshSz;
+        #endif
+
+            /* check for available size */
+            if ((ret = CheckAvailableSize(ssl, args->sendSz)) != 0) {
+                goto exit_scke;
+            }
+
+            /* get output buffer */
+            args->output = ssl->buffers.outputBuffer.buffer +
+                           ssl->buffers.outputBuffer.length;
+
+        #ifdef HAVE_QSH
+            if (ssl->peerQSHKeyPresent) {
+                byte idxSave = idx;
+                idx = args->sendSz - qshSz;
+
+                if (QSH_KeyExchangeWrite(ssl, 0) != 0) {
+                    ERROR_OUT(MEMORY_E, exit_scke);
+                }
+
+                /* extension type */
+                c16toa(TLSX_QUANTUM_SAFE_HYBRID, args->output + idx);
+                idx += OPAQUE16_LEN;
+
+                /* write to output and check amount written */
+                if (TLSX_QSHPK_Write(ssl->QSH_secret->list,
+                            args->output + idx) > qshSz - OPAQUE16_LEN) {
+                    ERROR_OUT(MEMORY_E, exit_scke);
+                }
+
+                idx = idxSave;
+            }
+        #endif
+
+            AddHeaders(args->output, args->encSz + tlsSz, client_key_exchange, ssl);
+
+        #ifdef HAVE_QSH
+            if (ssl->peerQSHKeyPresent) {
+                args->encSz -= qshSz;
+            }
+        #endif
+            if (tlsSz) {
+                c16toa((word16)args->encSz, &args->output[idx]);
+                idx += OPAQUE16_LEN;
+            }
+            XMEMCPY(args->output + idx, args->encSecret, args->encSz);
+            idx += args->encSz;
+
+            if (IsEncryptionOn(ssl, 1)) {
+                args->inputSz = idx - RECORD_HEADER_SZ; /* buildmsg adds rechdr */
+                args->input = (byte*)XMALLOC(args->inputSz, ssl->heap,
+                                                       DYNAMIC_TYPE_IN_BUFFER);
+                if (args->input == NULL) {
+                    ERROR_OUT(MEMORY_E, exit_scke);
+                }
+
+                XMEMCPY(args->input, args->output + RECORD_HEADER_SZ,
+                                                                args->inputSz);
+            }
+
+            /* Advance state and proceed */
+            ssl->options.asyncState = TLS_ASYNC_END;
+        } /* case TLS_ASYNC_FINALIZE */
+        FALL_THROUGH;
+
+        case TLS_ASYNC_END:
+        {
+            if (IsEncryptionOn(ssl, 1)) {
+                ret = BuildMessage(ssl, args->output, args->sendSz,
+                            args->input, args->inputSz, handshake, 1, 0, 0);
+                XFREE(args->input, ssl->heap, DYNAMIC_TYPE_IN_BUFFER);
+                args->input = NULL; /* make sure its not double free'd on cleanup */
+
+                if (ret >= 0) {
+                    args->sendSz = ret;
+                    ret = 0;
+                }
+            }
+            else {
+            #ifdef WOLFSSL_DTLS
+                if (ssl->options.dtls)
+                    DtlsSEQIncrement(ssl, CUR_ORDER);
+            #endif
+                ret = HashOutput(ssl, args->output, args->sendSz, 0);
+            }
+
+            if (ret != 0) {
+                goto exit_scke;
+            }
+
+        #ifdef WOLFSSL_DTLS
+            if (IsDtlsNotSctpMode(ssl)) {
+                if ((ret = DtlsMsgPoolSave(ssl, args->output, args->sendSz)) != 0) {
+                    goto exit_scke;
+                }
+            }
+        #endif
+
+        #if defined(WOLFSSL_CALLBACKS) || defined(OPENSSL_EXTRA)
+            if (ssl->hsInfoOn)
+                AddPacketName(ssl, "ClientKeyExchange");
+            if (ssl->toInfoOn)
+                AddPacketInfo(ssl, "ClientKeyExchange", handshake,
+                            args->output, args->sendSz, WRITE_PROTO, ssl->heap);
+        #endif
+
+            ssl->buffers.outputBuffer.length += args->sendSz;
+
+            if (!ssl->options.groupMessages) {
+                ret = SendBuffered(ssl);
+            }
+            if (ret == 0 || ret == WANT_WRITE) {
+                int tmpRet = MakeMasterSecret(ssl);
+                if (tmpRet != 0) {
+                    ret = tmpRet;   /* save WANT_WRITE unless more serious */
+                }
+                ssl->options.clientState = CLIENT_KEYEXCHANGE_COMPLETE;
+            }
+            break;
+        }
+        default:
+            ret = INPUT_CASE_ERROR;
+    } /* switch(ssl->options.asyncState) */
+
+exit_scke:
+
+    WOLFSSL_LEAVE("SendClientKeyExchange", ret);
+    WOLFSSL_END(WC_FUNC_CLIENT_KEY_EXCHANGE_SEND);
+
+#ifdef WOLFSSL_ASYNC_CRYPT
+    /* Handle async operation */
+    if (ret == WC_PENDING_E)
+        return ret;
+#endif
+
+    /* No further need for PMS */
+    if (ssl->arrays->preMasterSecret != NULL) {
+        ForceZero(ssl->arrays->preMasterSecret, ssl->arrays->preMasterSz);
+    }
+    ssl->arrays->preMasterSz = 0;
+
+    /* Final cleanup */
+    FreeSckeArgs(ssl, args);
+    FreeKeyExchange(ssl);
+
+    return ret;
+}
+
+#endif /* !WOLFSSL_NO_TLS12 */
+
+#ifndef NO_CERTS
+
+#ifdef HAVE_PK_CALLBACKS
+    int GetPrivateKeySigSize(WOLFSSL* ssl)
+    {
+        int sigSz = 0;
+
+        if (ssl == NULL)
+            return 0;
+
+        switch (ssl->buffers.keyType) {
+        #ifndef NO_RSA
+        #ifdef WC_RSA_PSS
+            case rsa_pss_sa_algo:
+        #endif
+            case rsa_sa_algo:
+                sigSz = ssl->buffers.keySz;
+                ssl->hsType = DYNAMIC_TYPE_RSA;
+                break;
+        #endif
+        #ifdef HAVE_ECC
+            case ecc_dsa_sa_algo:
+                sigSz = wc_ecc_sig_size_calc(ssl->buffers.keySz);
+                ssl->hsType = DYNAMIC_TYPE_ECC;
+                break;
+        #endif
+        #ifdef HAVE_ED25519
+            case ed25519_sa_algo:
+                sigSz = ED25519_SIG_SIZE; /* fixed known value */
+                ssl->hsType = DYNAMIC_TYPE_ED25519;
+                break;
+        #endif
+        #ifdef HAVE_ED448
+            case ed448_sa_algo:
+                sigSz = ED448_SIG_SIZE; /* fixed known value */
+                ssl->hsType = DYNAMIC_TYPE_ED448;
+                break;
+        #endif
+            default:
+                break;
+        }
+        return sigSz;
+    }
+#endif /* HAVE_PK_CALLBACKS */
+
+#ifndef WOLFSSL_NO_TLS12
+
+#ifndef WOLFSSL_NO_CLIENT_AUTH
+typedef struct ScvArgs {
+    byte*  output; /* not allocated */
+#ifndef NO_RSA
+    byte*  verifySig;
+#endif
+    byte*  verify; /* not allocated */
+    byte*  input;
+    word32 idx;
+    word32 extraSz;
+    word32 sigSz;
+    int    sendSz;
+    int    inputSz;
+    word16 length;
+    byte   sigAlgo;
+} ScvArgs;
+
+static void FreeScvArgs(WOLFSSL* ssl, void* pArgs)
+{
+    ScvArgs* args = (ScvArgs*)pArgs;
+
+    (void)ssl;
+
+#ifndef NO_RSA
+    if (args->verifySig) {
+        XFREE(args->verifySig, ssl->heap, DYNAMIC_TYPE_SIGNATURE);
+        args->verifySig = NULL;
+    }
+#endif
+    if (args->input) {
+        XFREE(args->input, ssl->heap, DYNAMIC_TYPE_IN_BUFFER);
+        args->input = NULL;
+    }
+}
+
+/* handle generation of certificate_verify (15) */
+int SendCertificateVerify(WOLFSSL* ssl)
+{
+    int ret = 0;
+#ifdef WOLFSSL_ASYNC_CRYPT
+    ScvArgs* args = (ScvArgs*)ssl->async.args;
+    typedef char args_test[sizeof(ssl->async.args) >= sizeof(*args) ? 1 : -1];
+    (void)sizeof(args_test);
+#else
+    ScvArgs  args[1];
+#endif
+
+    WOLFSSL_START(WC_FUNC_CERTIFICATE_VERIFY_SEND);
+    WOLFSSL_ENTER("SendCertificateVerify");
+
+#ifdef WOLFSSL_ASYNC_CRYPT
+    ret = wolfSSL_AsyncPop(ssl, &ssl->options.asyncState);
+    if (ret != WC_NOT_PENDING_E) {
+        /* Check for error */
+        if (ret < 0)
+            goto exit_scv;
+    }
+    else
+#endif
+    {
+        /* Reset state */
+        ret = 0;
+        ssl->options.asyncState = TLS_ASYNC_BEGIN;
+        XMEMSET(args, 0, sizeof(ScvArgs));
+    #ifdef WOLFSSL_ASYNC_CRYPT
+        ssl->async.freeArgs = FreeScvArgs;
+    #endif
+    }
+
+    switch(ssl->options.asyncState)
+    {
+        case TLS_ASYNC_BEGIN:
+        {
+            if (ssl->options.sendVerify == SEND_BLANK_CERT) {
+                return 0;  /* sent blank cert, can't verify */
+            }
+
+            args->sendSz = MAX_CERT_VERIFY_SZ + MAX_MSG_EXTRA;
+            if (IsEncryptionOn(ssl, 1)) {
+                args->sendSz += MAX_MSG_EXTRA;
+            }
+
+            /* check for available size */
+            if ((ret = CheckAvailableSize(ssl, args->sendSz)) != 0) {
+                goto exit_scv;
+            }
+
+            /* get output buffer */
+            args->output = ssl->buffers.outputBuffer.buffer +
+                           ssl->buffers.outputBuffer.length;
+
+            /* Advance state and proceed */
+            ssl->options.asyncState = TLS_ASYNC_BUILD;
+        } /* case TLS_ASYNC_BEGIN */
+        FALL_THROUGH;
+
+        case TLS_ASYNC_BUILD:
+        {
+            ret = BuildCertHashes(ssl, &ssl->hsHashes->certHashes);
+            if (ret != 0) {
+                goto exit_scv;
+            }
+
+            if (ssl->buffers.key == NULL) {
+            #ifdef HAVE_PK_CALLBACKS
+                if (wolfSSL_CTX_IsPrivatePkSet(ssl->ctx))
+                    args->length = GetPrivateKeySigSize(ssl);
+                else
+            #endif
+                    ERROR_OUT(NO_PRIVATE_KEY, exit_scv);
+            }
+            else {
+                /* Decode private key. */
+                ret = DecodePrivateKey(ssl, &args->length);
+                if (ret != 0) {
+                    goto exit_scv;
+                }
+            }
+
+            if (args->length == 0) {
+                ERROR_OUT(NO_PRIVATE_KEY, exit_scv);
+            }
+
+            /* idx is used to track verify pointer offset to output */
+            args->idx = RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ;
+            args->verify = &args->output[RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ];
+            args->extraSz = 0;  /* tls 1.2 hash/sig */
+
+            /* build encoded signature buffer */
+            ssl->buffers.sig.length = MAX_ENCODED_SIG_SZ;
+            ssl->buffers.sig.buffer = (byte*)XMALLOC(ssl->buffers.sig.length,
+                                        ssl->heap, DYNAMIC_TYPE_SIGNATURE);
+            if (ssl->buffers.sig.buffer == NULL) {
+                ERROR_OUT(MEMORY_E, exit_scv);
+            }
+
+        #ifdef WOLFSSL_DTLS
+            if (ssl->options.dtls) {
+                args->idx += DTLS_RECORD_EXTRA + DTLS_HANDSHAKE_EXTRA;
+                args->verify += DTLS_RECORD_EXTRA + DTLS_HANDSHAKE_EXTRA;
+            }
+        #endif
+
+    #ifndef NO_OLD_TLS
+        #ifndef NO_SHA
+            /* old tls default */
+            SetDigest(ssl, sha_mac);
+        #endif
+    #else
+        #ifndef NO_SHA256
+            /* new tls default */
+            SetDigest(ssl, sha256_mac);
+        #endif
+    #endif /* !NO_OLD_TLS */
+
+            if (ssl->hsType == DYNAMIC_TYPE_RSA) {
+        #ifdef WC_RSA_PSS
+                if (IsAtLeastTLSv1_2(ssl) &&
+                                (ssl->pssAlgo & (1 << ssl->suites->hashAlgo))) {
+                    args->sigAlgo = rsa_pss_sa_algo;
+                }
+                else
+        #endif
+                    args->sigAlgo = rsa_sa_algo;
+            }
+            else if (ssl->hsType == DYNAMIC_TYPE_ECC)
+                args->sigAlgo = ecc_dsa_sa_algo;
+            else if (ssl->hsType == DYNAMIC_TYPE_ED25519)
+                args->sigAlgo = ed25519_sa_algo;
+            else if (ssl->hsType == DYNAMIC_TYPE_ED448)
+                args->sigAlgo = ed448_sa_algo;
+
+            if (IsAtLeastTLSv1_2(ssl)) {
+                EncodeSigAlg(ssl->suites->hashAlgo, args->sigAlgo,
+                             args->verify);
+                args->extraSz = HASH_SIG_SIZE;
+                SetDigest(ssl, ssl->suites->hashAlgo);
+            }
+        #ifndef NO_OLD_TLS
+            else {
+                /* if old TLS load MD5 and SHA hash as value to sign */
+                XMEMCPY(ssl->buffers.sig.buffer,
+                    (byte*)ssl->hsHashes->certHashes.md5, FINISHED_SZ);
+            }
+        #endif
+
+        #ifndef NO_RSA
+            if (args->sigAlgo == rsa_sa_algo) {
+                ssl->buffers.sig.length = FINISHED_SZ;
+                args->sigSz = ENCRYPT_LEN;
+
+                if (IsAtLeastTLSv1_2(ssl)) {
+                    ssl->buffers.sig.length = wc_EncodeSignature(
+                            ssl->buffers.sig.buffer, ssl->buffers.digest.buffer,
+                            ssl->buffers.digest.length,
+                            TypeHash(ssl->suites->hashAlgo));
+                }
+
+                /* prepend hdr */
+                c16toa(args->length, args->verify + args->extraSz);
+            }
+            #ifdef WC_RSA_PSS
+            else if (args->sigAlgo == rsa_pss_sa_algo) {
+                XMEMCPY(ssl->buffers.sig.buffer, ssl->buffers.digest.buffer,
+                        ssl->buffers.digest.length);
+                ssl->buffers.sig.length = ssl->buffers.digest.length;
+                args->sigSz = ENCRYPT_LEN;
+
+                /* prepend hdr */
+                c16toa(args->length, args->verify + args->extraSz);
+            }
+            #endif
+        #endif /* !NO_RSA */
+        #if defined(HAVE_ED25519) && !defined(NO_ED25519_CLIENT_AUTH)
+            if (args->sigAlgo == ed25519_sa_algo) {
+                ret = Ed25519CheckPubKey(ssl);
+                if (ret != 0)
+                    goto exit_scv;
+            }
+        #endif /* HAVE_ED25519 && !NO_ED25519_CLIENT_AUTH */
+        #if defined(HAVE_ED448) && !defined(NO_ED448_CLIENT_AUTH)
+            if (args->sigAlgo == ed448_sa_algo) {
+                ret = Ed448CheckPubKey(ssl);
+                if (ret != 0)
+                    goto exit_scv;
+            }
+        #endif /* HAVE_ED448 && !NO_ED448_CLIENT_AUTH */
+
+            /* Advance state and proceed */
+            ssl->options.asyncState = TLS_ASYNC_DO;
+        } /* case TLS_ASYNC_BUILD */
+        FALL_THROUGH;
+
+        case TLS_ASYNC_DO:
+        {
+        #ifdef HAVE_ECC
+           if (ssl->hsType == DYNAMIC_TYPE_ECC) {
+                ecc_key* key = (ecc_key*)ssl->hsKey;
+
+                ret = EccSign(ssl,
+                    ssl->buffers.digest.buffer, ssl->buffers.digest.length,
+                    ssl->buffers.sig.buffer, (word32*)&ssl->buffers.sig.length,
+                    key,
+            #ifdef HAVE_PK_CALLBACKS
+                    ssl->buffers.key
+            #else
+                    NULL
+            #endif
+                );
+            }
+        #endif /* HAVE_ECC */
+        #if defined(HAVE_ED25519) && !defined(NO_ED25519_CLIENT_AUTH)
+           if (ssl->hsType == DYNAMIC_TYPE_ED25519) {
+                ed25519_key* key = (ed25519_key*)ssl->hsKey;
+
+                ret = Ed25519Sign(ssl,
+                    ssl->hsHashes->messages, ssl->hsHashes->length,
+                    ssl->buffers.sig.buffer, (word32*)&ssl->buffers.sig.length,
+                    key,
+            #ifdef HAVE_PK_CALLBACKS
+                    ssl->buffers.key
+            #else
+                    NULL
+            #endif
+                );
+            }
+        #endif /* HAVE_ED25519 && !NO_ED25519_CLIENT_AUTH */
+        #if defined(HAVE_ED448) && !defined(NO_ED448_CLIENT_AUTH)
+           if (ssl->hsType == DYNAMIC_TYPE_ED448) {
+                ed448_key* key = (ed448_key*)ssl->hsKey;
+
+                ret = Ed448Sign(ssl,
+                    ssl->hsHashes->messages, ssl->hsHashes->length,
+                    ssl->buffers.sig.buffer, (word32*)&ssl->buffers.sig.length,
+                    key,
+            #ifdef HAVE_PK_CALLBACKS
+                    ssl->buffers.key
+            #else
+                    NULL
+            #endif
+                );
+            }
+        #endif /* HAVE_ED448 && !NO_ED448_CLIENT_AUTH */
+        #ifndef NO_RSA
+            if (ssl->hsType == DYNAMIC_TYPE_RSA) {
+                RsaKey* key = (RsaKey*)ssl->hsKey;
+
+                /* restore verify pointer */
+                args->verify = &args->output[args->idx];
+
+                ret = RsaSign(ssl,
+                    ssl->buffers.sig.buffer, ssl->buffers.sig.length,
+                    args->verify + args->extraSz + VERIFY_HEADER, &args->sigSz,
+                    args->sigAlgo, ssl->suites->hashAlgo, key,
+                    ssl->buffers.key
+                );
+            }
+        #endif /* !NO_RSA */
+
+            /* Check for error */
+            if (ret != 0) {
+                goto exit_scv;
+            }
+
+            /* Advance state and proceed */
+            ssl->options.asyncState = TLS_ASYNC_VERIFY;
+        } /* case TLS_ASYNC_DO */
+        FALL_THROUGH;
+
+        case TLS_ASYNC_VERIFY:
+        {
+            /* restore verify pointer */
+            args->verify = &args->output[args->idx];
+
+            switch (ssl->hsType) {
+        #if defined(HAVE_ECC) || defined(HAVE_ED25519) || defined(HAVE_ED448)
+            #ifdef HAVE_ECC
+                case DYNAMIC_TYPE_ECC:
+            #endif
+            #ifdef HAVE_ED25519
+                case DYNAMIC_TYPE_ED25519:
+            #endif
+            #ifdef HAVE_ED448
+                case DYNAMIC_TYPE_ED448:
+            #endif
+                    args->length = (word16)ssl->buffers.sig.length;
+                    /* prepend hdr */
+                    c16toa(args->length, args->verify + args->extraSz);
+                    XMEMCPY(args->verify + args->extraSz + VERIFY_HEADER,
+                            ssl->buffers.sig.buffer, ssl->buffers.sig.length);
+                    break;
+        #endif
+            #ifndef NO_RSA
+                case DYNAMIC_TYPE_RSA:
+                {
+                    RsaKey* key = (RsaKey*)ssl->hsKey;
+
+                    if (args->verifySig == NULL) {
+                        args->verifySig = (byte*)XMALLOC(args->sigSz, ssl->heap,
+                                          DYNAMIC_TYPE_SIGNATURE);
+                        if (args->verifySig == NULL) {
+                            ERROR_OUT(MEMORY_E, exit_scv);
+                        }
+                        XMEMCPY(args->verifySig, args->verify + args->extraSz +
+                                                    VERIFY_HEADER, args->sigSz);
+                    }
+
+                    /* check for signature faults */
+                    ret = VerifyRsaSign(ssl,
+                        args->verifySig, args->sigSz,
+                        ssl->buffers.sig.buffer, ssl->buffers.sig.length,
+                        args->sigAlgo, ssl->suites->hashAlgo, key,
+                        ssl->buffers.key
+                    );
+                    break;
+                }
+            #endif /* !NO_RSA */
+                default:
+                    break;
+            }
+
+            /* Check for error */
+            if (ret != 0) {
+                goto exit_scv;
+            }
+
+            /* Advance state and proceed */
+            ssl->options.asyncState = TLS_ASYNC_FINALIZE;
+        } /* case TLS_ASYNC_VERIFY */
+        FALL_THROUGH;
+
+        case TLS_ASYNC_FINALIZE:
+        {
+            if (args->output == NULL) {
+                ERROR_OUT(BUFFER_ERROR, exit_scv);
+            }
+            AddHeaders(args->output, (word32)args->length + args->extraSz +
+                                        VERIFY_HEADER, certificate_verify, ssl);
+
+            args->sendSz = RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ +
+                           (word32)args->length + args->extraSz + VERIFY_HEADER;
+
+        #ifdef WOLFSSL_DTLS
+            if (ssl->options.dtls) {
+                args->sendSz += DTLS_RECORD_EXTRA + DTLS_HANDSHAKE_EXTRA;
+            }
+        #endif
+
+            if (IsEncryptionOn(ssl, 1)) {
+                args->inputSz = args->sendSz - RECORD_HEADER_SZ;
+                                /* build msg adds rec hdr */
+                args->input = (byte*)XMALLOC(args->inputSz, ssl->heap,
+                                                       DYNAMIC_TYPE_IN_BUFFER);
+                if (args->input == NULL) {
+                    ERROR_OUT(MEMORY_E, exit_scv);
+                }
+
+                XMEMCPY(args->input, args->output + RECORD_HEADER_SZ,
+                                                                args->inputSz);
+            }
+
+            /* Advance state and proceed */
+            ssl->options.asyncState = TLS_ASYNC_END;
+        } /* case TLS_ASYNC_FINALIZE */
+        FALL_THROUGH;
+
+        case TLS_ASYNC_END:
+        {
+            if (IsEncryptionOn(ssl, 1)) {
+                ret = BuildMessage(ssl, args->output,
+                                      MAX_CERT_VERIFY_SZ + MAX_MSG_EXTRA,
+                                      args->input, args->inputSz, handshake,
+                                      1, 0, 1);
+            #ifdef WOLFSSL_ASYNC_CRYPT
+                if (ret == WC_PENDING_E)
+                    goto exit_scv;
+            #endif
+
+                XFREE(args->input, ssl->heap, DYNAMIC_TYPE_IN_BUFFER);
+                args->input = NULL;  /* make sure its not double free'd on cleanup */
+
+                if (ret >= 0) {
+                    args->sendSz = ret;
+                    ret = 0;
+                }
+            }
+            else {
+            #ifdef WOLFSSL_DTLS
+                if (ssl->options.dtls)
+                    DtlsSEQIncrement(ssl, CUR_ORDER);
+            #endif
+                ret = HashOutput(ssl, args->output, args->sendSz, 0);
+            }
+
+            if (ret != 0) {
+                goto exit_scv;
+            }
+
+        #ifdef WOLFSSL_DTLS
+            if (IsDtlsNotSctpMode(ssl)) {
+                ret = DtlsMsgPoolSave(ssl, args->output, args->sendSz);
+            }
+        #endif
+
+
+        #if defined(WOLFSSL_CALLBACKS) || defined(OPENSSL_EXTRA)
+            if (ssl->hsInfoOn)
+                AddPacketName(ssl, "CertificateVerify");
+            if (ssl->toInfoOn)
+                AddPacketInfo(ssl, "CertificateVerify", handshake,
+                            args->output, args->sendSz, WRITE_PROTO, ssl->heap);
+        #endif
+
+            ssl->buffers.outputBuffer.length += args->sendSz;
+
+            if (!ssl->options.groupMessages) {
+                ret = SendBuffered(ssl);
+            }
+            break;
+        }
+        default:
+            ret = INPUT_CASE_ERROR;
+    } /* switch(ssl->options.asyncState) */
+
+exit_scv:
+
+    WOLFSSL_LEAVE("SendCertificateVerify", ret);
+    WOLFSSL_END(WC_FUNC_CERTIFICATE_VERIFY_SEND);
+
+#ifdef WOLFSSL_ASYNC_CRYPT
+    /* Handle async operation */
+    if (ret == WC_PENDING_E) {
+        return ret;
+    }
+#endif /* WOLFSSL_ASYNC_CRYPT */
+
+    /* Digest is not allocated, so do this to prevent free */
+    ssl->buffers.digest.buffer = NULL;
+    ssl->buffers.digest.length = 0;
+
+    /* Final cleanup */
+    FreeScvArgs(ssl, args);
+    FreeKeyExchange(ssl);
+
+    return ret;
+}
+#endif /* WOLFSSL_NO_CLIENT_AUTH */
+
+#endif /* WOLFSSL_NO_TLS12 */
+
+#endif /* NO_CERTS */
+
+
+#ifdef HAVE_SESSION_TICKET
+int SetTicket(WOLFSSL* ssl, const byte* ticket, word32 length)
+{
+    /* Free old dynamic ticket if we already had one */
+    if (ssl->session.isDynamic) {
+        XFREE(ssl->session.ticket, ssl->heap, DYNAMIC_TYPE_SESSION_TICK);
+        ssl->session.ticket = ssl->session.staticTicket;
+        ssl->session.isDynamic = 0;
+    }
+
+    if (length > sizeof(ssl->session.staticTicket)) {
+        byte* sessionTicket =
+                   (byte*)XMALLOC(length, ssl->heap, DYNAMIC_TYPE_SESSION_TICK);
+        if (sessionTicket == NULL)
+            return MEMORY_E;
+        ssl->session.ticket = sessionTicket;
+        ssl->session.isDynamic = 1;
+    }
+    ssl->session.ticketLen = (word16)length;
+
+    if (length > 0) {
+        XMEMCPY(ssl->session.ticket, ticket, length);
+        if (ssl->session_ticket_cb != NULL) {
+            ssl->session_ticket_cb(ssl,
+                                   ssl->session.ticket, ssl->session.ticketLen,
+                                   ssl->session_ticket_ctx);
+        }
+        /* Create a fake sessionID based on the ticket, this will
+         * supersede the existing session cache info. */
+        ssl->options.haveSessionId = 1;
+#ifdef WOLFSSL_TLS13
+        if (ssl->options.tls1_3) {
+            XMEMCPY(ssl->session.sessionID,
+                                 ssl->session.ticket + length - ID_LEN, ID_LEN);
+        }
+        else
+#endif
+            XMEMCPY(ssl->arrays->sessionID,
+                                 ssl->session.ticket + length - ID_LEN, ID_LEN);
+    }
+
+    return 0;
+}
+
+#ifndef WOLFSSL_NO_TLS12
+
+/* handle processing of session_ticket (4) */
+static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
+    word32 size)
+{
+    word32 begin = *inOutIdx;
+    word32 lifetime;
+    word16 length;
+    int    ret;
+
+    if (ssl->expect_session_ticket == 0) {
+        WOLFSSL_MSG("Unexpected session ticket");
+        return SESSION_TICKET_EXPECT_E;
+    }
+
+    if (OPAQUE32_LEN > size)
+        return BUFFER_ERROR;
+
+    ato32(input + *inOutIdx, &lifetime);
+    *inOutIdx += OPAQUE32_LEN;
+
+    if ((*inOutIdx - begin) + OPAQUE16_LEN > size)
+        return BUFFER_ERROR;
+
+    ato16(input + *inOutIdx, &length);
+    *inOutIdx += OPAQUE16_LEN;
+
+    if ((*inOutIdx - begin) + length > size)
+        return BUFFER_ERROR;
+
+    if ((ret = SetTicket(ssl, input + *inOutIdx, length)) != 0)
+        return ret;
+    *inOutIdx += length;
+    if (length > 0) {
+        ssl->timeout = lifetime;
+#ifndef NO_SESSION_CACHE
+        AddSession(ssl);
+#endif
+    }
+
+    if (IsEncryptionOn(ssl, 0)) {
+        *inOutIdx += ssl->keys.padSz;
+    #if defined(HAVE_ENCRYPT_THEN_MAC) && !defined(WOLFSSL_AEAD_ONLY)
+        if (ssl->options.startedETMRead)
+            *inOutIdx += MacSize(ssl);
+    #endif
+    }
+
+    ssl->expect_session_ticket = 0;
+
+    return 0;
+}
+
+#endif /* !WOLFSSL_NO_TLS12 */
+
+#endif /* HAVE_SESSION_TICKET */
+
+#endif /* NO_WOLFSSL_CLIENT */
+
+#ifdef HAVE_ECC
+    /* returns the WOLFSSL_* version of the curve from the OID sum */
+    word16 GetCurveByOID(int oidSum) {
+        switch(oidSum) {
+    #if defined(HAVE_ECC160) || defined(HAVE_ALL_CURVES)
+        #ifndef NO_ECC_SECP
+            case ECC_SECP160R1_OID:
+                return WOLFSSL_ECC_SECP160R1;
+        #endif /* !NO_ECC_SECP */
+        #ifdef HAVE_ECC_SECPR2
+            case ECC_SECP160R2_OID:
+                return WOLFSSL_ECC_SECP160R2;
+        #endif /* HAVE_ECC_SECPR2 */
+        #ifdef HAVE_ECC_KOBLITZ
+            case ECC_SECP160K1_OID:
+                return WOLFSSL_ECC_SECP160K1;
+        #endif /* HAVE_ECC_KOBLITZ */
+    #endif
+    #if defined(HAVE_ECC192) || defined(HAVE_ALL_CURVES)
+        #ifndef NO_ECC_SECP
+            case ECC_SECP192R1_OID:
+                return WOLFSSL_ECC_SECP192R1;
+        #endif /* !NO_ECC_SECP */
+        #ifdef HAVE_ECC_KOBLITZ
+            case ECC_SECP192K1_OID:
+                return WOLFSSL_ECC_SECP192K1;
+        #endif /* HAVE_ECC_KOBLITZ */
+    #endif
+    #if defined(HAVE_ECC224) || defined(HAVE_ALL_CURVES)
+        #ifndef NO_ECC_SECP
+            case ECC_SECP224R1_OID:
+                return WOLFSSL_ECC_SECP224R1;
+        #endif /* !NO_ECC_SECP */
+        #ifdef HAVE_ECC_KOBLITZ
+            case ECC_SECP224K1_OID:
+                return WOLFSSL_ECC_SECP224K1;
+        #endif /* HAVE_ECC_KOBLITZ */
+    #endif
+    #if !defined(NO_ECC256)  || defined(HAVE_ALL_CURVES)
+        #ifndef NO_ECC_SECP
+            case ECC_SECP256R1_OID:
+                return WOLFSSL_ECC_SECP256R1;
+        #endif /* !NO_ECC_SECP */
+        #ifdef HAVE_ECC_KOBLITZ
+            case ECC_SECP256K1_OID:
+                return WOLFSSL_ECC_SECP256K1;
+        #endif /* HAVE_ECC_KOBLITZ */
+        #ifdef HAVE_ECC_BRAINPOOL
+            case ECC_BRAINPOOLP256R1_OID:
+                return WOLFSSL_ECC_BRAINPOOLP256R1;
+        #endif /* HAVE_ECC_BRAINPOOL */
+    #endif
+    #if defined(HAVE_ECC384) || defined(HAVE_ALL_CURVES)
+        #ifndef NO_ECC_SECP
+            case ECC_SECP384R1_OID:
+                return WOLFSSL_ECC_SECP384R1;
+        #endif /* !NO_ECC_SECP */
+        #ifdef HAVE_ECC_BRAINPOOL
+            case ECC_BRAINPOOLP384R1_OID:
+                return WOLFSSL_ECC_BRAINPOOLP384R1;
+        #endif /* HAVE_ECC_BRAINPOOL */
+    #endif
+    #if defined(HAVE_ECC512) || defined(HAVE_ALL_CURVES)
+        #ifdef HAVE_ECC_BRAINPOOL
+            case ECC_BRAINPOOLP512R1_OID:
+                return WOLFSSL_ECC_BRAINPOOLP512R1;
+        #endif /* HAVE_ECC_BRAINPOOL */
+    #endif
+    #if defined(HAVE_ECC521) || defined(HAVE_ALL_CURVES)
+        #ifndef NO_ECC_SECP
+            case ECC_SECP521R1_OID:
+                return WOLFSSL_ECC_SECP521R1;
+        #endif /* !NO_ECC_SECP */
+    #endif
+            default:
+                WOLFSSL_MSG("Curve OID not compiled in or implemented");
+                return 0;
+        }
+    }
+#endif /* HAVE_ECC */
+
+
+#ifndef NO_WOLFSSL_SERVER
+
+#ifndef WOLFSSL_NO_TLS12
+
+    /* handle generation of server_hello (2) */
+    int SendServerHello(WOLFSSL* ssl)
+    {
+        int    ret;
+        byte   *output;
+        word16 length;
+        word32 idx = RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ;
+        int    sendSz;
+        byte   sessIdSz = ID_LEN;
+        byte   echoId   = 0;  /* ticket echo id flag */
+        byte   cacheOff = 0;  /* session cache off flag */
+
+        WOLFSSL_START(WC_FUNC_SERVER_HELLO_SEND);
+        WOLFSSL_ENTER("SendServerHello");
+
+        length = VERSION_SZ + RAN_LEN
+               + ID_LEN + ENUM_LEN
+               + SUITE_LEN
+               + ENUM_LEN;
+
+#ifdef HAVE_TLS_EXTENSIONS
+        ret = TLSX_GetResponseSize(ssl, server_hello, &length);
+        if (ret != 0)
+            return ret;
+    #ifdef HAVE_SESSION_TICKET
+        if (ssl->options.useTicket) {
+            /* echo session id sz can be 0,32 or bogus len in between */
+            sessIdSz = ssl->arrays->sessionIDSz;
+            if (sessIdSz > ID_LEN) {
+                WOLFSSL_MSG("Bad bogus session id len");
+                return BUFFER_ERROR;
+            }
+            if (!IsAtLeastTLSv1_3(ssl->version))
+                length -= (ID_LEN - sessIdSz);  /* adjust ID_LEN assumption */
+            echoId = 1;
+        }
+    #endif /* HAVE_SESSION_TICKET */
+#else
+        if (ssl->options.haveEMS) {
+            length += HELLO_EXT_SZ_SZ + HELLO_EXT_SZ;
+        }
+#endif
+
+        /* is the session cache off at build or runtime */
+#ifdef NO_SESSION_CACHE
+        cacheOff = 1;
+#else
+        if (ssl->options.sessionCacheOff == 1) {
+            cacheOff = 1;
+        }
+#endif
+
+        /* if no session cache don't send a session ID unless we're echoing
+         * an ID as part of session tickets */
+        if (echoId == 0 && cacheOff == 1) {
+            length -= ID_LEN;    /* adjust ID_LEN assumption */
+            sessIdSz = 0;
+        }
+
+        sendSz = length + HANDSHAKE_HEADER_SZ + RECORD_HEADER_SZ;
+        #ifdef WOLFSSL_DTLS
+        if (ssl->options.dtls) {
+            /* Server Hello should use the same sequence number as the
+             * Client Hello. */
+            ssl->keys.dtls_sequence_number_hi = ssl->keys.curSeq_hi;
+            ssl->keys.dtls_sequence_number_lo = ssl->keys.curSeq_lo;
+            idx    += DTLS_RECORD_EXTRA + DTLS_HANDSHAKE_EXTRA;
+            sendSz += DTLS_RECORD_EXTRA + DTLS_HANDSHAKE_EXTRA;
+        }
+        #endif /* WOLFSSL_DTLS */
+
+        if (IsEncryptionOn(ssl, 1))
+            sendSz += MAX_MSG_EXTRA;
+
+        /* check for available size */
+        if ((ret = CheckAvailableSize(ssl, sendSz)) != 0)
+            return ret;
+
+        /* get output buffer */
+        output = ssl->buffers.outputBuffer.buffer +
+                 ssl->buffers.outputBuffer.length;
+
+        AddHeaders(output, length, server_hello, ssl);
+
+        /* now write to output */
+        /* first version */
+        output[idx++] = (byte)ssl->version.major;
+        output[idx++] = (byte)ssl->version.minor;
+
+        /* then random and session id */
+        if (!ssl->options.resuming) {
+            /* generate random part and session id */
+            ret = wc_RNG_GenerateBlock(ssl->rng, output + idx,
+                RAN_LEN + sizeof(sessIdSz) + sessIdSz);
+            if (ret != 0)
+                return ret;
+
+#ifdef WOLFSSL_TLS13
+            if (TLSv1_3_Capable(ssl)) {
+                /* TLS v1.3 capable server downgraded. */
+                XMEMCPY(output + idx + RAN_LEN - (TLS13_DOWNGRADE_SZ + 1),
+                        tls13Downgrade, TLS13_DOWNGRADE_SZ);
+                output[idx + RAN_LEN - 1] = (byte)IsAtLeastTLSv1_2(ssl);
+            }
+            else
+#endif
+            if (ssl->ctx->method->version.major == SSLv3_MAJOR &&
+                          ssl->ctx->method->version.minor == TLSv1_2_MINOR &&
+                                                       !IsAtLeastTLSv1_2(ssl)) {
+                /* TLS v1.2 capable server downgraded. */
+                XMEMCPY(output + idx + RAN_LEN - (TLS13_DOWNGRADE_SZ + 1),
+                        tls13Downgrade, TLS13_DOWNGRADE_SZ);
+                output[idx + RAN_LEN - 1] = 0;
+            }
+
+            /* store info in SSL for later */
+            XMEMCPY(ssl->arrays->serverRandom, output + idx, RAN_LEN);
+            idx += RAN_LEN;
+            output[idx++] = sessIdSz;
+            XMEMCPY(ssl->arrays->sessionID, output + idx, sessIdSz);
+            ssl->arrays->sessionIDSz = sessIdSz;
+        }
+        else {
+            /* If resuming, use info from SSL */
+            XMEMCPY(output + idx, ssl->arrays->serverRandom, RAN_LEN);
+            idx += RAN_LEN;
+            output[idx++] = sessIdSz;
+            XMEMCPY(output + idx, ssl->arrays->sessionID, sessIdSz);
+        }
+        idx += sessIdSz;
+
+#ifdef SHOW_SECRETS
+        {
+            int j;
+            printf("server random: ");
+            for (j = 0; j < RAN_LEN; j++)
+                printf("%02x", ssl->arrays->serverRandom[j]);
+            printf("\n");
+        }
+#endif
+
+        /* then cipher suite */
+        output[idx++] = ssl->options.cipherSuite0;
+        output[idx++] = ssl->options.cipherSuite;
+
+        /* then compression */
+        if (ssl->options.usingCompression)
+            output[idx++] = ZLIB_COMPRESSION;
+        else
+            output[idx++] = NO_COMPRESSION;
+
+        /* last, extensions */
+#ifdef HAVE_TLS_EXTENSIONS
+        {
+            word16 offset = 0;
+            ret = TLSX_WriteResponse(ssl, output + idx, server_hello, &offset);
+            if (ret != 0)
+                return ret;
+            idx += offset;
+        }
+#else
+#ifdef HAVE_EXTENDED_MASTER
+        if (ssl->options.haveEMS) {
+            c16toa(HELLO_EXT_SZ, output + idx);
+            idx += HELLO_EXT_SZ_SZ;
+
+            c16toa(HELLO_EXT_EXTMS, output + idx);
+            idx += HELLO_EXT_TYPE_SZ;
+            c16toa(0, output + idx);
+            /*idx += HELLO_EXT_SZ_SZ;*/
+            /* idx is not used after this point. uncomment the line above
+             * if adding any more extensions in the future. */
+        }
+#endif
+#endif
+
+        if (IsEncryptionOn(ssl, 1)) {
+            byte* input;
+            int   inputSz = idx - RECORD_HEADER_SZ; /* build msg adds rec hdr */
+
+            input = (byte*)XMALLOC(inputSz, ssl->heap, DYNAMIC_TYPE_IN_BUFFER);
+            if (input == NULL)
+                return MEMORY_E;
+
+            XMEMCPY(input, output + RECORD_HEADER_SZ, inputSz);
+            sendSz = BuildMessage(ssl, output, sendSz, input, inputSz,
+                                  handshake, 1, 0, 0);
+            XFREE(input, ssl->heap, DYNAMIC_TYPE_IN_BUFFER);
+
+            if (sendSz < 0)
+                return sendSz;
+        } else {
+            #ifdef WOLFSSL_DTLS
+                if (ssl->options.dtls)
+                    DtlsSEQIncrement(ssl, CUR_ORDER);
+            #endif
+            ret = HashOutput(ssl, output, sendSz, 0);
+            if (ret != 0)
+                return ret;
+        }
+
+    #if defined(WOLFSSL_CALLBACKS) || defined(OPENSSL_EXTRA)
+        if (ssl->hsInfoOn)
+            AddPacketName(ssl, "ServerHello");
+        if (ssl->toInfoOn)
+            AddPacketInfo(ssl, "ServerHello", handshake, output, sendSz,
+                          WRITE_PROTO, ssl->heap);
+    #endif
+
+        ssl->options.serverState = SERVER_HELLO_COMPLETE;
+        ssl->buffers.outputBuffer.length += sendSz;
+
+    #ifdef WOLFSSL_DTLS
+        if (IsDtlsNotSctpMode(ssl)) {
+            if ((ret = DtlsMsgPoolSave(ssl, output, sendSz)) != 0)
+                return ret;
+        }
+    #endif
+
+        if (ssl->options.groupMessages)
+            ret = 0;
+        else
+            ret = SendBuffered(ssl);
+
+        WOLFSSL_LEAVE("SendServerHello", ret);
+        WOLFSSL_END(WC_FUNC_SERVER_HELLO_SEND);
+
+        return ret;
+    }
+
+
+#if defined(HAVE_ECC)
+
+    static byte SetCurveId(ecc_key* key)
+    {
+        if (key == NULL || key->dp == NULL) {
+            WOLFSSL_MSG("SetCurveId: Invalid key!");
+            return 0;
+        }
+
+        return (byte)GetCurveByOID(key->dp->oidSum);
+    }
+
+#endif /* HAVE_ECC */
+
+    typedef struct SskeArgs {
+        byte*  output; /* not allocated */
+    #if defined(HAVE_ECC) || defined(HAVE_ED25519) || defined(HAVE_ED448) || \
+                                           (!defined(NO_DH) && !defined(NO_RSA))
+        byte*  sigDataBuf;
+    #endif
+    #if defined(HAVE_ECC) || defined(HAVE_CURVE25519) || defined(HAVE_CURVE448)
+        byte*  exportBuf;
+    #endif
+    #ifndef NO_RSA
+        byte*  verifySig;
+    #endif
+        byte*  input;
+        word32 idx;
+        word32 tmpSigSz;
+        word32 length;
+        word32 sigSz;
+    #if defined(HAVE_ECC) || defined(HAVE_ED25519) || defined(HAVE_ED448) || \
+                                           (!defined(NO_DH) && !defined(NO_RSA))
+        word32 sigDataSz;
+    #endif
+    #if defined(HAVE_ECC) || defined(HAVE_CURVE25519) || defined(HAVE_CURVE448)
+        word32 exportSz;
+    #endif
+    #ifdef HAVE_QSH
+        word32 qshSz;
+    #endif
+        int    sendSz;
+        int    inputSz;
+    } SskeArgs;
+
+    static void FreeSskeArgs(WOLFSSL* ssl, void* pArgs)
+    {
+        SskeArgs* args = (SskeArgs*)pArgs;
+
+        (void)ssl;
+
+    #if defined(HAVE_ECC) || defined(HAVE_CURVE25519) || defined(HAVE_CURVE448)
+        if (args->exportBuf) {
+            XFREE(args->exportBuf, ssl->heap, DYNAMIC_TYPE_DER);
+            args->exportBuf = NULL;
+        }
+    #endif
+    #if defined(HAVE_ECC) || defined(HAVE_ED25519) || defined(HAVE_ED448) || \
+                                           (!defined(NO_DH) && !defined(NO_RSA))
+        if (args->sigDataBuf) {
+            XFREE(args->sigDataBuf, ssl->heap, DYNAMIC_TYPE_SIGNATURE);
+            args->sigDataBuf = NULL;
+        }
+    #endif
+    #ifndef NO_RSA
+        if (args->verifySig) {
+            XFREE(args->verifySig, ssl->heap, DYNAMIC_TYPE_SIGNATURE);
+            args->verifySig = NULL;
+        }
+    #endif
+        (void)args;
+    }
+
+    /* handle generation of server_key_exchange (12) */
+    int SendServerKeyExchange(WOLFSSL* ssl)
+    {
+        int ret;
+    #ifdef WOLFSSL_ASYNC_CRYPT
+        SskeArgs* args = (SskeArgs*)ssl->async.args;
+        typedef char args_test[sizeof(ssl->async.args) >= sizeof(*args) ? 1 : -1];
+        (void)sizeof(args_test);
+    #else
+        SskeArgs  args[1];
+    #endif
+
+        WOLFSSL_START(WC_FUNC_SERVER_KEY_EXCHANGE_SEND);
+        WOLFSSL_ENTER("SendServerKeyExchange");
+
+    #ifdef WOLFSSL_ASYNC_CRYPT
+        ret = wolfSSL_AsyncPop(ssl, &ssl->options.asyncState);
+        if (ret != WC_NOT_PENDING_E) {
+            /* Check for error */
+            if (ret < 0)
+                goto exit_sske;
+        }
+        else
+    #endif
+        {
+            /* Reset state */
+            ret = 0;
+            ssl->options.asyncState = TLS_ASYNC_BEGIN;
+            XMEMSET(args, 0, sizeof(SskeArgs));
+        #ifdef WOLFSSL_ASYNC_CRYPT
+            ssl->async.freeArgs = FreeSskeArgs;
+        #endif
+        }
+
+        switch(ssl->options.asyncState)
+        {
+            case TLS_ASYNC_BEGIN:
+            {
+            #ifdef HAVE_QSH
+                if (ssl->peerQSHKeyPresent && ssl->options.haveQSH) {
+                    args->qshSz = QSH_KeyGetSize(ssl);
+                }
+            #endif
+
+                /* Do some checks / debug msgs */
+                switch(ssl->specs.kea)
+                {
+                #if (defined(HAVE_ECC) || defined(HAVE_CURVE25519) || \
+                                     defined(HAVE_CURVE448)) && !defined(NO_PSK)
+                    case ecdhe_psk_kea:
+                    {
+                        WOLFSSL_MSG("Using ephemeral ECDH PSK");
+                        break;
+                    }
+                #endif /* (HAVE_ECC || CURVE25519 || CURVE448) && !NO_PSK */
+                #if defined(HAVE_ECC)
+                    case ecc_diffie_hellman_kea:
+                    {
+                        if (ssl->specs.static_ecdh) {
+                            WOLFSSL_MSG("Using Static ECDH, not sending "
+                                        "ServerKeyExchange");
+                            ERROR_OUT(0, exit_sske);
+                        }
+
+                        WOLFSSL_MSG("Using ephemeral ECDH");
+                        break;
+                    }
+                #endif /* HAVE_ECC */
+                }
+
+                /* Preparing keys */
+                switch(ssl->specs.kea)
+                {
+                #ifndef NO_PSK
+                    case psk_kea:
+                    {
+                        /* Nothing to do in this sub-state */
+                        break;
+                    }
+                #endif /* !NO_PSK */
+                #if !defined(NO_DH) && (!defined(NO_PSK) || !defined(NO_RSA))
+                #if !defined(NO_PSK)
+                    case dhe_psk_kea:
+                #endif
+                #if !defined(NO_RSA)
+                    case diffie_hellman_kea:
+                #endif
+                    {
+                        /* Allocate DH key buffers and generate key */
+                        if (ssl->buffers.serverDH_P.buffer == NULL ||
+                            ssl->buffers.serverDH_G.buffer == NULL) {
+                            ERROR_OUT(NO_DH_PARAMS, exit_sske);
+                        }
+
+                        if (ssl->buffers.serverDH_Pub.buffer == NULL) {
+                            /* Free'd in SSL_ResourceFree and FreeHandshakeResources */
+                            ssl->buffers.serverDH_Pub.buffer = (byte*)XMALLOC(
+                                    ssl->buffers.serverDH_P.length + OPAQUE16_LEN,
+                                    ssl->heap, DYNAMIC_TYPE_PUBLIC_KEY);
+                            if (ssl->buffers.serverDH_Pub.buffer == NULL) {
+                                ERROR_OUT(MEMORY_E, exit_sske);
+                            }
+                        }
+
+                        if (ssl->buffers.serverDH_Priv.buffer == NULL) {
+                            /* Free'd in SSL_ResourceFree and FreeHandshakeResources */
+                            ssl->buffers.serverDH_Priv.buffer = (byte*)XMALLOC(
+                                    ssl->buffers.serverDH_P.length + OPAQUE16_LEN,
+                                    ssl->heap, DYNAMIC_TYPE_PRIVATE_KEY);
+                            if (ssl->buffers.serverDH_Priv.buffer == NULL) {
+                                ERROR_OUT(MEMORY_E, exit_sske);
+                            }
+                        }
+
+                        ssl->options.dhKeySz =
+                                (word16)ssl->buffers.serverDH_P.length;
+
+                        ret = AllocKey(ssl, DYNAMIC_TYPE_DH,
+                                            (void**)&ssl->buffers.serverDH_Key);
+                        if (ret != 0) {
+                            goto exit_sske;
+                        }
+
+                        #if !defined(WOLFSSL_OLD_PRIME_CHECK) && \
+                            !defined(HAVE_FIPS) && \
+                            !defined(HAVE_SELFTEST)
+                        if (ssl->options.dhDoKeyTest &&
+                            !ssl->options.dhKeyTested)
+                        {
+                            ret = wc_DhSetCheckKey(
+                                ssl->buffers.serverDH_Key,
+                                ssl->buffers.serverDH_P.buffer,
+                                ssl->buffers.serverDH_P.length,
+                                ssl->buffers.serverDH_G.buffer,
+                                ssl->buffers.serverDH_G.length,
+                                NULL, 0, 0, ssl->rng);
+                            if (ret != 0) {
+                                goto exit_sske;
+                            }
+                            ssl->options.dhKeyTested = 1;
+                        }
+                        else
+                        #endif
+                        {
+                            ret = wc_DhSetKey(ssl->buffers.serverDH_Key,
+                                ssl->buffers.serverDH_P.buffer,
+                                ssl->buffers.serverDH_P.length,
+                                ssl->buffers.serverDH_G.buffer,
+                                ssl->buffers.serverDH_G.length);
+                            if (ret != 0) {
+                                goto exit_sske;
+                            }
+                        }
+
+                        ret = DhGenKeyPair(ssl, ssl->buffers.serverDH_Key,
+                            ssl->buffers.serverDH_Priv.buffer,
+                            (word32*)&ssl->buffers.serverDH_Priv.length,
+                            ssl->buffers.serverDH_Pub.buffer,
+                            (word32*)&ssl->buffers.serverDH_Pub.length);
+                        break;
+                    }
+                #endif /* !NO_DH && (!NO_PSK || !NO_RSA) */
+                #if (defined(HAVE_ECC) || defined(HAVE_CURVE25519) || \
+                                     defined(HAVE_CURVE448)) && !defined(NO_PSK)
+                    case ecdhe_psk_kea:
+                        /* Fall through to create temp ECC key */
+                #endif /* (HAVE_ECC || CURVE25519 || CURVE448) && !NO_PSK */
+                #if defined(HAVE_ECC) || defined(HAVE_CURVE25519) || \
+                                                          defined(HAVE_CURVE448)
+                    case ecc_diffie_hellman_kea:
+                    {
+                    #ifdef HAVE_CURVE25519
+                        if (ssl->ecdhCurveOID == ECC_X25519_OID) {
+                            /* need ephemeral key now, create it if missing */
+                            if (ssl->eccTempKey == NULL) {
+                                /* alloc/init on demand */
+                                ret = AllocKey(ssl, DYNAMIC_TYPE_CURVE25519,
+                                    (void**)&ssl->eccTempKey);
+                                if (ret != 0) {
+                                    goto exit_sske;
+                                }
+                            }
+
+                            if (ssl->eccTempKeyPresent == 0) {
+                                ret = X25519MakeKey(ssl,
+                                        (curve25519_key*)ssl->eccTempKey, NULL);
+                                if (ret == 0 || ret == WC_PENDING_E) {
+                                    ssl->eccTempKeyPresent =
+                                        DYNAMIC_TYPE_CURVE25519;
+                                }
+                            }
+                            break;
+                        }
+                    #endif
+                    #ifdef HAVE_CURVE448
+                        if (ssl->ecdhCurveOID == ECC_X448_OID) {
+                            /* need ephemeral key now, create it if missing */
+                            if (ssl->eccTempKey == NULL) {
+                                /* alloc/init on demand */
+                                ret = AllocKey(ssl, DYNAMIC_TYPE_CURVE448,
+                                    (void**)&ssl->eccTempKey);
+                                if (ret != 0) {
+                                    goto exit_sske;
+                                }
+                            }
+
+                            if (ssl->eccTempKeyPresent == 0) {
+                                ret = X448MakeKey(ssl,
+                                          (curve448_key*)ssl->eccTempKey, NULL);
+                                if (ret == 0 || ret == WC_PENDING_E) {
+                                    ssl->eccTempKeyPresent =
+                                        DYNAMIC_TYPE_CURVE448;
+                                }
+                            }
+                            break;
+                        }
+                    #endif
+                    #ifdef HAVE_ECC
+                        /* need ephemeral key now, create it if missing */
+                        if (ssl->eccTempKey == NULL) {
+                            /* alloc/init on demand */
+                            ret = AllocKey(ssl, DYNAMIC_TYPE_ECC,
+                                (void**)&ssl->eccTempKey);
+                            if (ret != 0) {
+                                goto exit_sske;
+                            }
+                        }
+
+                        if (ssl->eccTempKeyPresent == 0) {
+                            ret = EccMakeKey(ssl, ssl->eccTempKey, NULL);
+                            if (ret == 0 || ret == WC_PENDING_E) {
+                                ssl->eccTempKeyPresent = DYNAMIC_TYPE_ECC;
+                            }
+                        }
+                    #endif
+                        break;
+                    }
+                #endif /* HAVE_ECC || HAVE_CURVE25519 || HAVE_CURVE448 */
+                    default:
+                        /* Skip ServerKeyExchange */
+                        goto exit_sske;
+                } /* switch(ssl->specs.kea) */
+
+                /* Check for error */
+                if (ret != 0) {
+                    goto exit_sske;
+                }
+
+                /* Advance state and proceed */
+                ssl->options.asyncState = TLS_ASYNC_BUILD;
+            } /* case TLS_ASYNC_BEGIN */
+            FALL_THROUGH;
+
+            case TLS_ASYNC_BUILD:
+            {
+            #if (!defined(NO_DH) && !defined(NO_RSA)) || (defined(HAVE_ECC) || \
+                             defined(HAVE_CURVE25519) || defined(HAVE_CURVE448))
+                word32 preSigSz, preSigIdx;
+            #endif
+
+                switch(ssl->specs.kea)
+                {
+                #ifndef NO_PSK
+                    case psk_kea:
+                    {
+                        args->idx = RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ;
+
+                        if (ssl->arrays->server_hint[0] == 0) {
+                            ERROR_OUT(0, exit_sske); /* don't send */
+                        }
+
+                        /* include size part */
+                        args->length = (word32)XSTRLEN(ssl->arrays->server_hint);
+                        if (args->length > MAX_PSK_ID_LEN) {
+                            ERROR_OUT(SERVER_HINT_ERROR, exit_sske);
+                        }
+
+                        args->length += HINT_LEN_SZ;
+                        args->sendSz = args->length + HANDSHAKE_HEADER_SZ +
+                                                            RECORD_HEADER_SZ;
+
+                    #ifdef HAVE_QSH
+                        args->length += args->qshSz;
+                        args->sendSz += args->qshSz;
+                    #endif
+
+                    #ifdef WOLFSSL_DTLS
+                        if (ssl->options.dtls) {
+                            args->sendSz += DTLS_RECORD_EXTRA + DTLS_HANDSHAKE_EXTRA;
+                            args->idx    += DTLS_RECORD_EXTRA + DTLS_HANDSHAKE_EXTRA;
+                        }
+                    #endif
+
+                        if (IsEncryptionOn(ssl, 1)) {
+                            args->sendSz += MAX_MSG_EXTRA;
+                        }
+
+                        /* check for available size */
+                        if ((ret = CheckAvailableSize(ssl, args->sendSz)) != 0) {
+                            goto exit_sske;
+                        }
+
+                        /* get output buffer */
+                        args->output = ssl->buffers.outputBuffer.buffer +
+                                       ssl->buffers.outputBuffer.length;
+
+                        AddHeaders(args->output, args->length,
+                                                    server_key_exchange, ssl);
+
+                        /* key data */
+                    #ifdef HAVE_QSH
+                        c16toa((word16)(args->length - args->qshSz -
+                                        HINT_LEN_SZ), args->output + args->idx);
+                    #else
+                        c16toa((word16)(args->length - HINT_LEN_SZ),
+                                                      args->output + args->idx);
+                    #endif
+
+                        args->idx += HINT_LEN_SZ;
+                        XMEMCPY(args->output + args->idx,
+                                ssl->arrays->server_hint,
+                                args->length - HINT_LEN_SZ);
+                        break;
+                    }
+                #endif /* !NO_PSK */
+                #if !defined(NO_DH) && !defined(NO_PSK)
+                    case dhe_psk_kea:
+                    {
+                        word32 hintLen;
+
+                        args->idx = RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ;
+                        args->length = LENGTH_SZ * 3 + /* p, g, pub */
+                                 ssl->buffers.serverDH_P.length +
+                                 ssl->buffers.serverDH_G.length +
+                                 ssl->buffers.serverDH_Pub.length;
+
+                        /* include size part */
+                        hintLen = (word32)XSTRLEN(ssl->arrays->server_hint);
+                        if (hintLen > MAX_PSK_ID_LEN) {
+                            ERROR_OUT(SERVER_HINT_ERROR, exit_sske);
+                        }
+                        args->length += hintLen + HINT_LEN_SZ;
+                        args->sendSz = args->length + HANDSHAKE_HEADER_SZ +
+                                                            RECORD_HEADER_SZ;
+
+                    #ifdef HAVE_QSH
+                        args->length += args->qshSz;
+                        args->sendSz += args->qshSz;
+                    #endif
+                    #ifdef WOLFSSL_DTLS
+                        if (ssl->options.dtls) {
+                            args->sendSz += DTLS_RECORD_EXTRA + DTLS_HANDSHAKE_EXTRA;
+                            args->idx    += DTLS_RECORD_EXTRA + DTLS_HANDSHAKE_EXTRA;
+                        }
+                    #endif
+
+                        if (IsEncryptionOn(ssl, 1)) {
+                            args->sendSz += MAX_MSG_EXTRA;
+                        }
+
+                        /* check for available size */
+                        if ((ret = CheckAvailableSize(ssl, args->sendSz)) != 0) {
+                            goto exit_sske;
+                        }
+
+                        /* get output buffer */
+                        args->output = ssl->buffers.outputBuffer.buffer +
+                                       ssl->buffers.outputBuffer.length;
+
+                        AddHeaders(args->output, args->length,
+                                                    server_key_exchange, ssl);
+
+                        /* key data */
+                        c16toa((word16)hintLen, args->output + args->idx);
+                        args->idx += HINT_LEN_SZ;
+                        XMEMCPY(args->output + args->idx,
+                                            ssl->arrays->server_hint, hintLen);
+                        args->idx += hintLen;
+
+                        /* add p, g, pub */
+                        c16toa((word16)ssl->buffers.serverDH_P.length,
+                            args->output + args->idx);
+                        args->idx += LENGTH_SZ;
+                        XMEMCPY(args->output + args->idx,
+                                ssl->buffers.serverDH_P.buffer,
+                                ssl->buffers.serverDH_P.length);
+                        args->idx += ssl->buffers.serverDH_P.length;
+
+                        /*  g */
+                        c16toa((word16)ssl->buffers.serverDH_G.length,
+                            args->output + args->idx);
+                        args->idx += LENGTH_SZ;
+                        XMEMCPY(args->output + args->idx,
+                                ssl->buffers.serverDH_G.buffer,
+                                ssl->buffers.serverDH_G.length);
+                        args->idx += ssl->buffers.serverDH_G.length;
+
+                        /*  pub */
+                        c16toa((word16)ssl->buffers.serverDH_Pub.length,
+                            args->output + args->idx);
+                        args->idx += LENGTH_SZ;
+                        XMEMCPY(args->output + args->idx,
+                                ssl->buffers.serverDH_Pub.buffer,
+                                ssl->buffers.serverDH_Pub.length);
+                        /* No need to update idx, since sizes are already set */
+                        /* args->idx += ssl->buffers.serverDH_Pub.length; */
+                        break;
+                    }
+                #endif /* !defined(NO_DH) && !defined(NO_PSK) */
+                #if (defined(HAVE_ECC) || defined(HAVE_CURVE25519) || \
+                                     defined(HAVE_CURVE448)) && !defined(NO_PSK)
+                    case ecdhe_psk_kea:
+                    {
+                        word32 hintLen;
+
+                        /* curve type, named curve, length(1) */
+                        args->idx = RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ;
+                        args->length = ENUM_LEN + CURVE_LEN + ENUM_LEN;
+
+                        args->exportSz = MAX_EXPORT_ECC_SZ;
+                        args->exportBuf = (byte*)XMALLOC(args->exportSz,
+                                            ssl->heap, DYNAMIC_TYPE_DER);
+                        if (args->exportBuf == NULL) {
+                            ERROR_OUT(MEMORY_E, exit_sske);
+                        }
+                    #ifdef HAVE_CURVE25519
+                        if (ssl->ecdhCurveOID == ECC_X25519_OID) {
+                            if (wc_curve25519_export_public_ex(
+                                    (curve25519_key*)ssl->eccTempKey,
+                                    args->exportBuf, &args->exportSz,
+                                    EC25519_LITTLE_ENDIAN) != 0) {
+                                ERROR_OUT(ECC_EXPORT_ERROR, exit_sske);
+                            }
+                        }
+                        else
+                    #endif
+                    #ifdef HAVE_CURVE448
+                        if (ssl->ecdhCurveOID == ECC_X448_OID) {
+                            if (wc_curve448_export_public_ex(
+                                    (curve448_key*)ssl->eccTempKey,
+                                    args->exportBuf, &args->exportSz,
+                                    EC448_LITTLE_ENDIAN) != 0) {
+                                ERROR_OUT(ECC_EXPORT_ERROR, exit_sske);
+                            }
+                        }
+                        else
+                    #endif
+                        {
+                            if (wc_ecc_export_x963(ssl->eccTempKey,
+                                       args->exportBuf, &args->exportSz) != 0) {
+                                ERROR_OUT(ECC_EXPORT_ERROR, exit_sske);
+                            }
+                        }
+                        args->length += args->exportSz;
+
+                        /* include size part */
+                        hintLen = (word32)XSTRLEN(ssl->arrays->server_hint);
+                        if (hintLen > MAX_PSK_ID_LEN) {
+                            ERROR_OUT(SERVER_HINT_ERROR, exit_sske);
+                        }
+                        args->length += hintLen + HINT_LEN_SZ;
+                        args->sendSz = args->length + HANDSHAKE_HEADER_SZ + RECORD_HEADER_SZ;
+
+                    #ifdef HAVE_QSH
+                        args->length += args->qshSz;
+                        args->sendSz += args->qshSz;
+                    #endif
+                    #ifdef WOLFSSL_DTLS
+                        if (ssl->options.dtls) {
+                            args->sendSz += DTLS_RECORD_EXTRA + DTLS_HANDSHAKE_EXTRA;
+                            args->idx    += DTLS_RECORD_EXTRA + DTLS_HANDSHAKE_EXTRA;
+                        }
+                    #endif
+
+                        if (IsEncryptionOn(ssl, 1)) {
+                            args->sendSz += MAX_MSG_EXTRA;
+                        }
+
+                        /* check for available size */
+                        if ((ret = CheckAvailableSize(ssl, args->sendSz)) != 0) {
+                            goto exit_sske;
+                        }
+
+                        /* get output buffer */
+                        args->output = ssl->buffers.outputBuffer.buffer +
+                                       ssl->buffers.outputBuffer.length;
+
+                        /* key data */
+                        c16toa((word16)hintLen, args->output + args->idx);
+                        args->idx += HINT_LEN_SZ;
+                        XMEMCPY(args->output + args->idx,
+                                            ssl->arrays->server_hint, hintLen);
+                        args->idx += hintLen;
+
+                        /* ECC key exchange data */
+                        args->output[args->idx++] = named_curve;
+                        args->output[args->idx++] = 0x00;          /* leading zero */
+                    #ifdef HAVE_CURVE25519
+                        if (ssl->ecdhCurveOID == ECC_X25519_OID)
+                            args->output[args->idx++] = WOLFSSL_ECC_X25519;
+                        else
+                    #endif
+                    #ifdef HAVE_CURVE448
+                        if (ssl->ecdhCurveOID == ECC_X448_OID)
+                            args->output[args->idx++] = WOLFSSL_ECC_X448;
+                        else
+                    #endif
+                        {
+                    #ifdef HAVE_ECC
+                            args->output[args->idx++] =
+                                                    SetCurveId(ssl->eccTempKey);
+                    #endif
+                        }
+                        args->output[args->idx++] = (byte)args->exportSz;
+                        XMEMCPY(args->output + args->idx, args->exportBuf,
+                                                                args->exportSz);
+                        break;
+                    }
+                #endif /* (HAVE_ECC || CURVE25519 || CURVE448) && !NO_PSK */
+                #if defined(HAVE_ECC) || defined(HAVE_CURVE25519) || \
+                                                          defined(HAVE_CURVE448)
+                    case ecc_diffie_hellman_kea:
+                    {
+                        enum wc_HashType hashType;
+
+                        /* curve type, named curve, length(1) */
+                        args->idx = RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ;
+                        args->length = ENUM_LEN + CURVE_LEN + ENUM_LEN;
+
+                        /* Export temp ECC key and add to length */
+                        args->exportSz = MAX_EXPORT_ECC_SZ;
+                        args->exportBuf = (byte*)XMALLOC(args->exportSz,
+                                            ssl->heap, DYNAMIC_TYPE_DER);
+                        if (args->exportBuf == NULL) {
+                            ERROR_OUT(MEMORY_E, exit_sske);
+                        }
+                    #ifdef HAVE_CURVE25519
+                        if (ssl->ecdhCurveOID == ECC_X25519_OID) {
+                            if (wc_curve25519_export_public_ex(
+                                        (curve25519_key*)ssl->eccTempKey,
+                                        args->exportBuf, &args->exportSz,
+                                        EC25519_LITTLE_ENDIAN) != 0) {
+                                ERROR_OUT(ECC_EXPORT_ERROR, exit_sske);
+                            }
+                        }
+                        else
+                    #endif
+                    #ifdef HAVE_CURVE448
+                        if (ssl->ecdhCurveOID == ECC_X448_OID) {
+                            if (wc_curve448_export_public_ex(
+                                        (curve448_key*)ssl->eccTempKey,
+                                        args->exportBuf, &args->exportSz,
+                                        EC448_LITTLE_ENDIAN) != 0) {
+                                ERROR_OUT(ECC_EXPORT_ERROR, exit_sske);
+                            }
+                        }
+                        else
+                    #endif
+                        {
+                    #if defined(HAVE_ECC) && defined(HAVE_ECC_KEY_EXPORT)
+                            if (wc_ecc_export_x963(ssl->eccTempKey,
+                                       args->exportBuf, &args->exportSz) != 0) {
+                                ERROR_OUT(ECC_EXPORT_ERROR, exit_sske);
+                            }
+                     #endif
+                        }
+                        args->length += args->exportSz;
+
+                        preSigSz  = args->length;
+                        preSigIdx = args->idx;
+
+                        if (ssl->buffers.key == NULL) {
+                        #ifdef HAVE_PK_CALLBACKS
+                            if (wolfSSL_CTX_IsPrivatePkSet(ssl->ctx)) {
+                                args->tmpSigSz = GetPrivateKeySigSize(ssl);
+                                if (args->tmpSigSz == 0) {
+                                    ERROR_OUT(NO_PRIVATE_KEY, exit_sske);
+                                }
+                            }
+                            else
+                        #endif
+                                ERROR_OUT(NO_PRIVATE_KEY, exit_sske);
+                        }
+                        else {
+                            switch(ssl->suites->sigAlgo) {
+                        #ifndef NO_RSA
+                        #ifdef WC_RSA_PSS
+                            case rsa_pss_sa_algo:
+                        #endif
+                            case rsa_sa_algo:
+                            {
+                                word16 keySz;
+
+                                ssl->buffers.keyType = rsa_sa_algo;
+                                ret = DecodePrivateKey(ssl, &keySz);
+                                if (ret != 0) {
+                                    goto exit_sske;
+                                }
+
+                                args->tmpSigSz = (word32)keySz;
+                                break;
+                            }
+                        #endif /* !NO_RSA */
+                        #ifdef HAVE_ECC
+                            case ecc_dsa_sa_algo:
+                            {
+                                word16 keySz;
+
+                                ssl->buffers.keyType = ecc_dsa_sa_algo;
+                                ret = DecodePrivateKey(ssl, &keySz);
+                                if (ret != 0) {
+                                    goto exit_sske;
+                                }
+                                /* worst case estimate */
+                                args->tmpSigSz = keySz;
+                                break;
+                            }
+                        #endif
+                        #ifdef HAVE_ED25519
+                            case ed25519_sa_algo:
+                            {
+                                word16 keySz;
+
+                                ssl->buffers.keyType = ed25519_sa_algo;
+                                ret = DecodePrivateKey(ssl, &keySz);
+                                if (ret != 0) {
+                                    goto exit_sske;
+                                }
+
+                                /* worst case estimate */
+                                args->tmpSigSz = ED25519_SIG_SIZE;
+                                break;
+                            }
+                        #endif /* HAVE_ED25519 */
+                        #ifdef HAVE_ED448
+                            case ed448_sa_algo:
+                            {
+                                word16 keySz;
+
+                                ssl->buffers.keyType = ed448_sa_algo;
+                                ret = DecodePrivateKey(ssl, &keySz);
+                                if (ret != 0) {
+                                    goto exit_sske;
+                                }
+
+                                /* worst case estimate */
+                                args->tmpSigSz = ED448_SIG_SIZE;
+                                break;
+                            }
+                        #endif /* HAVE_ED448 */
+                            default:
+                                ERROR_OUT(ALGO_ID_E, exit_sske);  /* unsupported type */
+                            } /* switch(ssl->specs.sig_algo) */
+                        }
+
+                        /* sig length */
+                        args->length += LENGTH_SZ;
+                        args->length += args->tmpSigSz;
+
+                        if (IsAtLeastTLSv1_2(ssl)) {
+                            args->length += HASH_SIG_SIZE;
+                        }
+
+                        args->sendSz = args->length + HANDSHAKE_HEADER_SZ + RECORD_HEADER_SZ;
+
+                    #ifdef HAVE_QSH
+                        args->length += args->qshSz;
+                        args->sendSz += args->qshSz;
+                    #endif
+                    #ifdef WOLFSSL_DTLS
+                        if (ssl->options.dtls) {
+                            args->sendSz += DTLS_RECORD_EXTRA + DTLS_HANDSHAKE_EXTRA;
+                            args->idx    += DTLS_RECORD_EXTRA + DTLS_HANDSHAKE_EXTRA;
+                            preSigIdx = args->idx;
+                        }
+                    #endif
+                        if (IsEncryptionOn(ssl, 1)) {
+                            args->sendSz += MAX_MSG_EXTRA;
+                        }
+
+                        /* check for available size */
+                        if ((ret = CheckAvailableSize(ssl, args->sendSz)) != 0) {
+                            goto exit_sske;
+                        }
+
+                        /* get output buffer */
+                        args->output = ssl->buffers.outputBuffer.buffer +
+                                       ssl->buffers.outputBuffer.length;
+
+                        /* record and message headers will be added below, when we're sure
+                           of the sig length */
+
+                        /* key exchange data */
+                        args->output[args->idx++] = named_curve;
+                        args->output[args->idx++] = 0x00;          /* leading zero */
+                    #ifdef HAVE_CURVE25519
+                        if (ssl->ecdhCurveOID == ECC_X25519_OID)
+                            args->output[args->idx++] = WOLFSSL_ECC_X25519;
+                        else
+                    #endif
+                    #ifdef HAVE_CURVE448
+                        if (ssl->ecdhCurveOID == ECC_X448_OID)
+                            args->output[args->idx++] = WOLFSSL_ECC_X448;
+                        else
+                    #endif
+                        {
+                    #ifdef HAVE_ECC
+                            args->output[args->idx++] =
+                                                    SetCurveId(ssl->eccTempKey);
+                    #endif
+                        }
+                        args->output[args->idx++] = (byte)args->exportSz;
+                        XMEMCPY(args->output + args->idx, args->exportBuf, args->exportSz);
+                        args->idx += args->exportSz;
+
+                        /* Determine hash type */
+                        if (IsAtLeastTLSv1_2(ssl)) {
+                            EncodeSigAlg(ssl->suites->hashAlgo,
+                                         ssl->suites->sigAlgo,
+                                         &args->output[args->idx]);
+                            args->idx += 2;
+
+                            hashType = HashAlgoToType(ssl->suites->hashAlgo);
+                            if (hashType == WC_HASH_TYPE_NONE) {
+                                ERROR_OUT(ALGO_ID_E, exit_sske);
+                            }
+
+                        } else {
+                            /* only using sha and md5 for rsa */
+                        #ifndef NO_OLD_TLS
+                            hashType = WC_HASH_TYPE_SHA;
+                            if (ssl->suites->sigAlgo == rsa_sa_algo) {
+                                hashType = WC_HASH_TYPE_MD5_SHA;
+                            }
+                        #else
+                            ERROR_OUT(ALGO_ID_E, exit_sske);
+                        #endif
+                        }
+
+                        /* Signature length will be written later, when we're sure what it is */
+
+                    #ifdef HAVE_FUZZER
+                        if (ssl->fuzzerCb) {
+                            ssl->fuzzerCb(ssl, args->output + preSigIdx,
+                                preSigSz, FUZZ_SIGNATURE, ssl->fuzzerCtx);
+                        }
+                    #endif
+
+                        /* Assemble buffer to hash for signature */
+                        args->sigDataSz = RAN_LEN + RAN_LEN + preSigSz;
+                        args->sigDataBuf = (byte*)XMALLOC(args->sigDataSz,
+                                            ssl->heap, DYNAMIC_TYPE_SIGNATURE);
+                        if (args->sigDataBuf == NULL) {
+                            ERROR_OUT(MEMORY_E, exit_sske);
+                        }
+                        XMEMCPY(args->sigDataBuf, ssl->arrays->clientRandom,
+                                                                       RAN_LEN);
+                        XMEMCPY(args->sigDataBuf+RAN_LEN,
+                                            ssl->arrays->serverRandom, RAN_LEN);
+                        XMEMCPY(args->sigDataBuf+RAN_LEN+RAN_LEN,
+                                args->output + preSigIdx, preSigSz);
+
+                        if (ssl->suites->sigAlgo != ed25519_sa_algo &&
+                                        ssl->suites->sigAlgo != ed448_sa_algo) {
+                            ssl->buffers.sig.length =
+                                                 wc_HashGetDigestSize(hashType);
+                            if ((int)ssl->buffers.sig.length < 0) {
+                                ERROR_OUT(HASH_TYPE_E, exit_sske);
+                            }
+                            ssl->buffers.sig.buffer = (byte*)XMALLOC(
+                                            ssl->buffers.sig.length,
+                                            ssl->heap, DYNAMIC_TYPE_SIGNATURE);
+                            if (ssl->buffers.sig.buffer == NULL) {
+                                ERROR_OUT(MEMORY_E, exit_sske);
+                            }
+
+                            /* Perform hash */
+                            ret = wc_Hash(hashType, args->sigDataBuf,
+                                                       args->sigDataSz,
+                                                       ssl->buffers.sig.buffer,
+                                                       ssl->buffers.sig.length);
+                            if (ret != 0) {
+                                goto exit_sske;
+                            }
+                        }
+
+                        args->sigSz = args->tmpSigSz;
+
+                        /* Sign hash to create signature */
+                        switch (ssl->suites->sigAlgo)
+                        {
+                        #ifndef NO_RSA
+                            case rsa_sa_algo:
+                            {
+                                /* For TLS 1.2 re-encode signature */
+                                if (IsAtLeastTLSv1_2(ssl)) {
+                                    byte* encodedSig = (byte*)XMALLOC(
+                                                  MAX_ENCODED_SIG_SZ, ssl->heap,
+                                                       DYNAMIC_TYPE_SIGNATURE);
+                                    if (encodedSig == NULL) {
+                                        ERROR_OUT(MEMORY_E, exit_sske);
+                                    }
+
+                                    ssl->buffers.sig.length =
+                                        wc_EncodeSignature(encodedSig,
+                                            ssl->buffers.sig.buffer,
+                                            ssl->buffers.sig.length,
+                                            TypeHash(ssl->suites->hashAlgo));
+
+                                    /* Replace sig buffer with new one */
+                                    XFREE(ssl->buffers.sig.buffer, ssl->heap,
+                                                       DYNAMIC_TYPE_SIGNATURE);
+                                    ssl->buffers.sig.buffer = encodedSig;
+                                }
+
+                                /* write sig size here */
+                                c16toa((word16)args->sigSz,
+                                    args->output + args->idx);
+                                args->idx += LENGTH_SZ;
+                                break;
+                            }
+                        #ifdef WC_RSA_PSS
+                            case rsa_pss_sa_algo:
+                                /* write sig size here */
+                                c16toa((word16)args->sigSz,
+                                    args->output + args->idx);
+                                args->idx += LENGTH_SZ;
+                                break;
+                        #endif
+                        #endif /* !NO_RSA */
+                            case ecc_dsa_sa_algo:
+                            {
+                                break;
+                            }
+                        #ifdef  HAVE_ED25519
+                            case ed25519_sa_algo:
+                                ret = Ed25519CheckPubKey(ssl);
+                                if (ret != 0)
+                                    goto exit_sske;
+                                break;
+                        #endif /* HAVE_ED25519 */
+                        #ifdef  HAVE_ED448
+                            case ed448_sa_algo:
+                                ret = Ed448CheckPubKey(ssl);
+                                if (ret != 0)
+                                    goto exit_sske;
+                                break;
+                        #endif /* HAVE_ED448 */
+                        } /* switch(ssl->specs.sig_algo) */
+                        break;
+                    }
+                #endif /* HAVE_ECC || HAVE_CURVE25519 || HAVE_CURVE448 */
+                #if !defined(NO_DH) && !defined(NO_RSA)
+                    case diffie_hellman_kea:
+                    {
+                        enum wc_HashType hashType;
+
+                        args->idx = RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ;
+                        args->length = LENGTH_SZ * 3;  /* p, g, pub */
+                        args->length += ssl->buffers.serverDH_P.length +
+                                        ssl->buffers.serverDH_G.length +
+                                        ssl->buffers.serverDH_Pub.length;
+
+                        preSigIdx = args->idx;
+                        preSigSz  = args->length;
+
+                        if (!ssl->options.usingAnon_cipher) {
+                            word16 keySz;
+
+                            /* sig length */
+                            args->length += LENGTH_SZ;
+
+                            if (ssl->buffers.key == NULL) {
+                            #ifdef HAVE_PK_CALLBACKS
+                                if (wolfSSL_CTX_IsPrivatePkSet(ssl->ctx))
+                                    keySz = (word32)GetPrivateKeySigSize(ssl);
+                                else
+                            #endif
+                                    ERROR_OUT(NO_PRIVATE_KEY, exit_sske);
+                            }
+                            else
+                            {
+                                if (ssl->buffers.keyType == 0)
+                                    ssl->buffers.keyType = rsa_sa_algo;
+                                ret = DecodePrivateKey(ssl, &keySz);
+                                if (ret != 0) {
+                                    goto exit_sske;
+                                }
+                            }
+
+                            if (keySz == 0) { /* test if keySz has error */
+                                ERROR_OUT(keySz, exit_sske);
+                            }
+
+                            args->tmpSigSz = (word32)keySz;
+                            args->length += args->tmpSigSz;
+
+                            if (IsAtLeastTLSv1_2(ssl)) {
+                                args->length += HASH_SIG_SIZE;
+                            }
+                        }
+
+                        args->sendSz = args->length + HANDSHAKE_HEADER_SZ +
+                                                            RECORD_HEADER_SZ;
+
+                    #ifdef HAVE_QSH
+                        args->length += args->qshSz;
+                        args->sendSz += args->qshSz;
+                    #endif
+                    #ifdef WOLFSSL_DTLS
+                        if (ssl->options.dtls) {
+                            args->sendSz += DTLS_RECORD_EXTRA + DTLS_HANDSHAKE_EXTRA;
+                            args->idx    += DTLS_RECORD_EXTRA + DTLS_HANDSHAKE_EXTRA;
+                            preSigIdx = args->idx;
+                        }
+                    #endif
+
+                        if (IsEncryptionOn(ssl, 1)) {
+                            args->sendSz += MAX_MSG_EXTRA;
+                        }
+
+                        /* check for available size */
+                        if ((ret = CheckAvailableSize(ssl, args->sendSz)) != 0) {
+                            goto exit_sske;
+                        }
+
+                        /* get output buffer */
+                        args->output = ssl->buffers.outputBuffer.buffer +
+                                       ssl->buffers.outputBuffer.length;
+
+                        AddHeaders(args->output, args->length,
+                                                    server_key_exchange, ssl);
+
+                        /* add p, g, pub */
+                        c16toa((word16)ssl->buffers.serverDH_P.length,
+                                                    args->output + args->idx);
+                        args->idx += LENGTH_SZ;
+                        XMEMCPY(args->output + args->idx,
+                                              ssl->buffers.serverDH_P.buffer,
+                                              ssl->buffers.serverDH_P.length);
+                        args->idx += ssl->buffers.serverDH_P.length;
+
+                        /*  g */
+                        c16toa((word16)ssl->buffers.serverDH_G.length,
+                                                    args->output + args->idx);
+                        args->idx += LENGTH_SZ;
+                        XMEMCPY(args->output + args->idx,
+                                              ssl->buffers.serverDH_G.buffer,
+                                              ssl->buffers.serverDH_G.length);
+                        args->idx += ssl->buffers.serverDH_G.length;
+
+                        /*  pub */
+                        c16toa((word16)ssl->buffers.serverDH_Pub.length,
+                                                    args->output + args->idx);
+                        args->idx += LENGTH_SZ;
+                        XMEMCPY(args->output + args->idx,
+                                              ssl->buffers.serverDH_Pub.buffer,
+                                              ssl->buffers.serverDH_Pub.length);
+                        args->idx += ssl->buffers.serverDH_Pub.length;
+
+                    #ifdef HAVE_FUZZER
+                        if (ssl->fuzzerCb) {
+                            ssl->fuzzerCb(ssl, args->output + preSigIdx,
+                                preSigSz, FUZZ_SIGNATURE, ssl->fuzzerCtx);
+                        }
+                    #endif
+
+                        if (ssl->options.usingAnon_cipher) {
+                            break;
+                        }
+
+                        /* Determine hash type */
+                        if (IsAtLeastTLSv1_2(ssl)) {
+                            EncodeSigAlg(ssl->suites->hashAlgo,
+                                         ssl->suites->sigAlgo,
+                                         &args->output[args->idx]);
+                            args->idx += 2;
+
+                            hashType = HashAlgoToType(ssl->suites->hashAlgo);
+                            if (hashType == WC_HASH_TYPE_NONE) {
+                                ERROR_OUT(ALGO_ID_E, exit_sske);
+                            }
+                        } else {
+                            /* only using sha and md5 for rsa */
+                        #ifndef NO_OLD_TLS
+                            hashType = WC_HASH_TYPE_SHA;
+                            if (ssl->suites->sigAlgo == rsa_sa_algo) {
+                                hashType = WC_HASH_TYPE_MD5_SHA;
+                            }
+                        #else
+                            ERROR_OUT(ALGO_ID_E, exit_sske);
+                        #endif
+                        }
+
+                        /* signature size */
+                        c16toa((word16)args->tmpSigSz, args->output + args->idx);
+                        args->idx += LENGTH_SZ;
+
+                        /* Assemble buffer to hash for signature */
+                        args->sigDataSz = RAN_LEN + RAN_LEN + preSigSz;
+                        args->sigDataBuf = (byte*)XMALLOC(args->sigDataSz,
+                                            ssl->heap, DYNAMIC_TYPE_SIGNATURE);
+                        if (args->sigDataBuf == NULL) {
+                            ERROR_OUT(MEMORY_E, exit_sske);
+                        }
+                        XMEMCPY(args->sigDataBuf, ssl->arrays->clientRandom,
+                                                                    RAN_LEN);
+                        XMEMCPY(args->sigDataBuf+RAN_LEN,
+                                        ssl->arrays->serverRandom, RAN_LEN);
+                        XMEMCPY(args->sigDataBuf+RAN_LEN+RAN_LEN,
+                            args->output + preSigIdx, preSigSz);
+
+                        if (ssl->suites->sigAlgo != ed25519_sa_algo &&
+                                        ssl->suites->sigAlgo != ed448_sa_algo) {
+                            ssl->buffers.sig.length =
+                                                 wc_HashGetDigestSize(hashType);
+                            ssl->buffers.sig.buffer = (byte*)XMALLOC(
+                                             ssl->buffers.sig.length, ssl->heap,
+                                                       DYNAMIC_TYPE_SIGNATURE);
+                            if (ssl->buffers.sig.buffer == NULL) {
+                                ERROR_OUT(MEMORY_E, exit_sske);
+                            }
+
+                            /* Perform hash */
+                            ret = wc_Hash(hashType, args->sigDataBuf,
+                                                       args->sigDataSz,
+                                                       ssl->buffers.sig.buffer,
+                                                       ssl->buffers.sig.length);
+                            if (ret != 0) {
+                                goto exit_sske;
+                            }
+                        }
+
+                        args->sigSz = args->tmpSigSz;
+
+                        /* Sign hash to create signature */
+                        switch (ssl->suites->sigAlgo)
+                        {
+                        #ifndef NO_RSA
+                            case rsa_sa_algo:
+                            {
+                                /* For TLS 1.2 re-encode signature */
+                                if (IsAtLeastTLSv1_2(ssl)) {
+                                    byte* encodedSig = (byte*)XMALLOC(
+                                                  MAX_ENCODED_SIG_SZ, ssl->heap,
+                                                       DYNAMIC_TYPE_SIGNATURE);
+                                    if (encodedSig == NULL) {
+                                        ERROR_OUT(MEMORY_E, exit_sske);
+                                    }
+
+                                    ssl->buffers.sig.length =
+                                        wc_EncodeSignature(encodedSig,
+                                            ssl->buffers.sig.buffer,
+                                            ssl->buffers.sig.length,
+                                            TypeHash(ssl->suites->hashAlgo));
+
+                                    /* Replace sig buffer with new one */
+                                    XFREE(ssl->buffers.sig.buffer, ssl->heap,
+                                                       DYNAMIC_TYPE_SIGNATURE);
+                                    ssl->buffers.sig.buffer = encodedSig;
+                                }
+                                break;
+                            }
+                        #endif /* NO_RSA */
+                        } /* switch (ssl->suites->sigAlgo) */
+                        break;
+                    }
+                #endif /* !defined(NO_DH) && !defined(NO_RSA) */
+                } /* switch(ssl->specs.kea) */
+
+                /* Check for error */
+                if (ret != 0) {
+                    goto exit_sske;
+                }
+
+                /* Advance state and proceed */
+                ssl->options.asyncState = TLS_ASYNC_DO;
+            } /* case TLS_ASYNC_BUILD */
+            FALL_THROUGH;
+
+            case TLS_ASYNC_DO:
+            {
+                switch(ssl->specs.kea)
+                {
+                #ifndef NO_PSK
+                    case psk_kea:
+                    {
+                        break;
+                    }
+                #endif /* !NO_PSK */
+                #if !defined(NO_DH) && !defined(NO_PSK)
+                    case dhe_psk_kea:
+                    {
+                        break;
+                    }
+                #endif /* !defined(NO_DH) && !defined(NO_PSK) */
+                #if (defined(HAVE_ECC) || defined(HAVE_CURVE25519) || \
+                                     defined(HAVE_CURVE448)) && !defined(NO_PSK)
+                    case ecdhe_psk_kea:
+                    {
+                        break;
+                    }
+                #endif /* (HAVE_ECC || CURVE25519 || CURVE448) && !NO_PSK */
+                #if defined(HAVE_ECC) || defined(HAVE_ED25519) || \
+                                                             defined(HAVE_ED448)
+                    case ecc_diffie_hellman_kea:
+                    {
+                        /* Sign hash to create signature */
+                        switch (ssl->suites->sigAlgo)
+                        {
+                        #ifndef NO_RSA
+                        #ifdef WC_RSA_PSS
+                            case rsa_pss_sa_algo:
+                        #endif
+                            case rsa_sa_algo:
+                            {
+                                RsaKey* key = (RsaKey*)ssl->hsKey;
+
+                                ret = RsaSign(ssl,
+                                    ssl->buffers.sig.buffer,
+                                    ssl->buffers.sig.length,
+                                    args->output + args->idx,
+                                    &args->sigSz,
+                                    ssl->suites->sigAlgo, ssl->suites->hashAlgo,
+                                    key,
+                                    ssl->buffers.key
+                                );
+                                break;
+                            }
+                        #endif /* !NO_RSA */
+                        #ifdef HAVE_ECC
+                            case ecc_dsa_sa_algo:
+                            {
+                                ecc_key* key = (ecc_key*)ssl->hsKey;
+
+                                ret = EccSign(ssl,
+                                    ssl->buffers.sig.buffer,
+                                    ssl->buffers.sig.length,
+                                    args->output + LENGTH_SZ + args->idx,
+                                    &args->sigSz,
+                                    key,
+                            #ifdef HAVE_PK_CALLBACKS
+                                    ssl->buffers.key
+                            #else
+                                    NULL
+                            #endif
+                                );
+                                break;
+                            }
+                        #endif /* HAVE_ECC */
+                        #ifdef HAVE_ED25519
+                            case ed25519_sa_algo:
+                            {
+                                ed25519_key* key = (ed25519_key*)ssl->hsKey;
+
+                                ret = Ed25519Sign(ssl,
+                                    args->sigDataBuf, args->sigDataSz,
+                                    args->output + LENGTH_SZ + args->idx,
+                                    &args->sigSz,
+                                    key,
+                            #ifdef HAVE_PK_CALLBACKS
+                                    ssl->buffers.key
+                            #else
+                                    NULL
+                            #endif
+                                );
+                                break;
+                            }
+                        #endif
+                        #ifdef HAVE_ED448
+                            case ed448_sa_algo:
+                            {
+                                ed448_key* key = (ed448_key*)ssl->hsKey;
+
+                                ret = Ed448Sign(ssl,
+                                    args->sigDataBuf, args->sigDataSz,
+                                    args->output + LENGTH_SZ + args->idx,
+                                    &args->sigSz,
+                                    key,
+                            #ifdef HAVE_PK_CALLBACKS
+                                    ssl->buffers.key
+                            #else
+                                    NULL
+                            #endif
+                                );
+                                break;
+                            }
+                        #endif
+                        } /* switch(ssl->specs.sig_algo) */
+                        break;
+                    }
+                #endif /* HAVE_ECC || HAVE_CURVE25519 || HAVE_CURVE448 */
+                #if !defined(NO_DH) && !defined(NO_RSA)
+                    case diffie_hellman_kea:
+                    {
+                        /* Sign hash to create signature */
+                        switch (ssl->suites->sigAlgo)
+                        {
+                        #ifndef NO_RSA
+                        #ifdef WC_RSA_PSS
+                            case rsa_pss_sa_algo:
+                        #endif
+                            case rsa_sa_algo:
+                            {
+                                RsaKey* key = (RsaKey*)ssl->hsKey;
+
+                                if (ssl->options.usingAnon_cipher) {
+                                    break;
+                                }
+
+                                ret = RsaSign(ssl,
+                                    ssl->buffers.sig.buffer,
+                                    ssl->buffers.sig.length,
+                                    args->output + args->idx,
+                                    &args->sigSz,
+                                    ssl->suites->sigAlgo, ssl->suites->hashAlgo,
+                                    key,
+                                    ssl->buffers.key
+                                );
+                                break;
+                            }
+                        #endif /* NO_RSA */
+                        } /* switch (ssl->suites->sigAlgo) */
+
+                        break;
+                    }
+                #endif /* !defined(NO_DH) && !defined(NO_RSA) */
+                } /* switch(ssl->specs.kea) */
+
+                /* Check for error */
+                if (ret != 0) {
+                    goto exit_sske;
+                }
+
+                /* Advance state and proceed */
+                ssl->options.asyncState = TLS_ASYNC_VERIFY;
+            } /* case TLS_ASYNC_DO */
+            FALL_THROUGH;
+
+            case TLS_ASYNC_VERIFY:
+            {
+                switch(ssl->specs.kea)
+                {
+                #ifndef NO_PSK
+                    case psk_kea:
+                    {
+                        /* Nothing to do in this sub-state */
+                        break;
+                    }
+                #endif /* !NO_PSK */
+                #if !defined(NO_DH) && !defined(NO_PSK)
+                    case dhe_psk_kea:
+                    {
+                        /* Nothing to do in this sub-state */
+                        break;
+                    }
+                #endif /* !defined(NO_DH) && !defined(NO_PSK) */
+                #if (defined(HAVE_ECC) || defined(HAVE_CURVE25519) ||  \
+                                     defined(HAVE_CURVE448)) && !defined(NO_PSK)
+                    case ecdhe_psk_kea:
+                    {
+                        /* Nothing to do in this sub-state */
+                        break;
+                    }
+                #endif /* (HAVE_ECC || CURVE25519 || CURVE448) && !NO_PSK */
+                #if defined(HAVE_ECC) || defined(HAVE_CURVE25519) || \
+                                                          defined(HAVE_CURVE448)
+                    case ecc_diffie_hellman_kea:
+                    {
+                        switch(ssl->suites->sigAlgo)
+                        {
+                        #ifndef NO_RSA
+                        #ifdef WC_RSA_PSS
+                            case rsa_pss_sa_algo:
+                        #endif
+                            case rsa_sa_algo:
+                            {
+                                RsaKey* key = (RsaKey*)ssl->hsKey;
+
+                                if (args->verifySig == NULL) {
+                                    if (args->sigSz == 0) {
+                                        ERROR_OUT(BAD_COND_E, exit_sske);
+                                    }
+                                    args->verifySig = (byte*)XMALLOC(
+                                                    args->sigSz, ssl->heap,
+                                                    DYNAMIC_TYPE_SIGNATURE);
+                                    if (!args->verifySig) {
+                                        ERROR_OUT(MEMORY_E, exit_sske);
+                                    }
+                                    XMEMCPY(args->verifySig,
+                                        args->output + args->idx, args->sigSz);
+                                }
+
+                                /* check for signature faults */
+                                ret = VerifyRsaSign(ssl,
+                                    args->verifySig, args->sigSz,
+                                    ssl->buffers.sig.buffer,
+                                    ssl->buffers.sig.length,
+                                    ssl->suites->sigAlgo, ssl->suites->hashAlgo,
+                                    key, ssl->buffers.key
+                                );
+                                break;
+                            }
+                        #endif
+                            case ecc_dsa_sa_algo:
+                        #ifdef HAVE_ED25519
+                            case ed25519_sa_algo:
+                        #endif
+                        #ifdef HAVE_ED448
+                            case ed448_sa_algo:
+                        #endif
+                            {
+                                /* Now that we know the real sig size, write it. */
+                                c16toa((word16)args->sigSz,
+                                                    args->output + args->idx);
+
+                                /* And adjust length and sendSz from estimates */
+                                args->length += args->sigSz - args->tmpSigSz;
+                                args->sendSz += args->sigSz - args->tmpSigSz;
+                                break;
+                            }
+                            default:
+                                ERROR_OUT(ALGO_ID_E, exit_sske);  /* unsupported type */
+                        } /* switch(ssl->specs.sig_algo) */
+                        break;
+                    }
+                #endif /* HAVE_ECC || HAVE_CURVE25519 || HAVE_CURVE448 */
+                #if !defined(NO_DH) && !defined(NO_RSA)
+                    case diffie_hellman_kea:
+                    {
+                        switch (ssl->suites->sigAlgo)
+                        {
+                        #ifndef NO_RSA
+                        #ifndef WC_RSA_PSS
+                            case rsa_pss_sa_algo:
+                        #endif
+                            case rsa_sa_algo:
+                            {
+                                RsaKey* key = (RsaKey*)ssl->hsKey;
+
+                                if (ssl->options.usingAnon_cipher) {
+                                    break;
+                                }
+
+                                if (args->verifySig == NULL) {
+                                    if (args->sigSz == 0) {
+                                        ERROR_OUT(BAD_COND_E, exit_sske);
+                                    }
+                                    args->verifySig = (byte*)XMALLOC(
+                                                      args->sigSz, ssl->heap,
+                                                      DYNAMIC_TYPE_SIGNATURE);
+                                    if (!args->verifySig) {
+                                        ERROR_OUT(MEMORY_E, exit_sske);
+                                    }
+                                    XMEMCPY(args->verifySig,
+                                        args->output + args->idx, args->sigSz);
+                                }
+
+                                /* check for signature faults */
+                                ret = VerifyRsaSign(ssl,
+                                    args->verifySig, args->sigSz,
+                                    ssl->buffers.sig.buffer,
+                                    ssl->buffers.sig.length,
+                                    ssl->suites->sigAlgo, ssl->suites->hashAlgo,
+                                    key, ssl->buffers.key
+                                );
+                                break;
+                            }
+                        #endif
+                        } /* switch (ssl->suites->sigAlgo) */
+                        break;
+                    }
+                #endif /* !defined(NO_DH) && !defined(NO_RSA) */
+                } /* switch(ssl->specs.kea) */
+
+                /* Check for error */
+                if (ret != 0) {
+                    goto exit_sske;
+                }
+
+                /* Advance state and proceed */
+                ssl->options.asyncState = TLS_ASYNC_FINALIZE;
+            } /* case TLS_ASYNC_VERIFY */
+            FALL_THROUGH;
+
+            case TLS_ASYNC_FINALIZE:
+            {
+            #ifdef HAVE_QSH
+                if (ssl->peerQSHKeyPresent) {
+                    if (args->qshSz > 0) {
+                        args->idx = args->sendSz - args->qshSz;
+                        if (QSH_KeyExchangeWrite(ssl, 1) != 0) {
+                            ERROR_OUT(MEMORY_E, exit_sske);
+                        }
+
+                        /* extension type */
+                        c16toa(TLSX_QUANTUM_SAFE_HYBRID,
+                                                    args->output + args->idx);
+                        args->idx += OPAQUE16_LEN;
+
+                        /* write to output and check amount written */
+                        if (TLSX_QSHPK_Write(ssl->QSH_secret->list,
+                            args->output + args->idx) >
+                                                args->qshSz - OPAQUE16_LEN) {
+                            ERROR_OUT(MEMORY_E, exit_sske);
+                        }
+                    }
+                }
+            #endif
+
+            #if defined(HAVE_ECC) || defined(HAVE_CURVE25519) || \
+                                                          defined(HAVE_CURVE448)
+                if (ssl->specs.kea == ecdhe_psk_kea ||
+                    ssl->specs.kea == ecc_diffie_hellman_kea) {
+                    /* Check output to make sure it was set */
+                    if (args->output) {
+                        AddHeaders(args->output, args->length,
+                                                    server_key_exchange, ssl);
+                    }
+                    else {
+                        ERROR_OUT(BUFFER_ERROR, exit_sske);
+                    }
+                }
+            #endif /* HAVE_ECC || HAVE_CURVE25519 || HAVE_CURVE448 */
+
+                if (IsEncryptionOn(ssl, 1)) {
+                    args->inputSz = args->length + HANDSHAKE_HEADER_SZ;
+                                                     /* buildmsg adds rechdr */
+                    args->input = (byte*)XMALLOC(args->inputSz, ssl->heap,
+                                                        DYNAMIC_TYPE_IN_BUFFER);
+                    if (args->input == NULL) {
+                        ERROR_OUT(MEMORY_E, exit_sske);
+                    }
+
+                    if (args->output == NULL) {
+                        ERROR_OUT(BUFFER_ERROR, exit_sske);
+                    }
+
+                    XMEMCPY(args->input, args->output + RECORD_HEADER_SZ,
+                                                                 args->inputSz);
+                    ret = BuildMessage(ssl, args->output, args->sendSz,
+                                args->input, args->inputSz, handshake, 1, 0, 0);
+                    XFREE(args->input, ssl->heap, DYNAMIC_TYPE_IN_BUFFER);
+                    args->input = NULL;
+                        /* make sure its not double free'd on cleanup */
+
+                    if (ret >= 0) {
+                        args->sendSz = ret;
+                        ret = 0;
+                    }
+                }
+                else {
+                #ifdef WOLFSSL_DTLS
+                    if (IsDtlsNotSctpMode(ssl)) {
+                        if ((ret = DtlsMsgPoolSave(ssl,
+                                            args->output, args->sendSz)) != 0) {
+                            goto exit_sske;
+                        }
+                    }
+
+                    if (ssl->options.dtls)
+                        DtlsSEQIncrement(ssl, CUR_ORDER);
+                #endif
+
+                    ret = HashOutput(ssl, args->output, args->sendSz, 0);
+                    if (ret != 0) {
+                        goto exit_sske;
+                    }
+                }
+
+            #if defined(WOLFSSL_CALLBACKS) || defined(OPENSSL_EXTRA)
+                if (ssl->hsInfoOn) {
+                    AddPacketName(ssl, "ServerKeyExchange");
+                }
+                if (ssl->toInfoOn) {
+                    AddPacketInfo(ssl, "ServerKeyExchange", handshake,
+                        args->output, args->sendSz, WRITE_PROTO, ssl->heap);
+                }
+            #endif
+
+                /* Advance state and proceed */
+                ssl->options.asyncState = TLS_ASYNC_END;
+            } /* case TLS_ASYNC_FINALIZE */
+            FALL_THROUGH;
+
+            case TLS_ASYNC_END:
+            {
+                ssl->buffers.outputBuffer.length += args->sendSz;
+                if (!ssl->options.groupMessages) {
+                    ret = SendBuffered(ssl);
+                }
+
+                ssl->options.serverState = SERVER_KEYEXCHANGE_COMPLETE;
+                break;
+            }
+            default:
+                ret = INPUT_CASE_ERROR;
+        } /* switch(ssl->options.asyncState) */
+
+    exit_sske:
+
+        WOLFSSL_LEAVE("SendServerKeyExchange", ret);
+        WOLFSSL_END(WC_FUNC_SERVER_KEY_EXCHANGE_SEND);
+
+    #ifdef WOLFSSL_ASYNC_CRYPT
+        /* Handle async operation */
+        if (ret == WC_PENDING_E)
+            return ret;
+    #endif /* WOLFSSL_ASYNC_CRYPT */
+
+        /* Final cleanup */
+        FreeSskeArgs(ssl, args);
+        FreeKeyExchange(ssl);
+
+        return ret;
+    }
+
+#if defined(HAVE_SERVER_RENEGOTIATION_INFO) || defined(HAVE_FALLBACK_SCSV) || \
+                                                            defined(OPENSSL_ALL)
+
+    /* search suites for specific one, idx on success, negative on error */
+#ifndef WOLFSSL_TLS13
+    static
+#endif
+    int FindSuite(Suites* suites, byte first, byte second)
+    {
+        int i;
+
+        if (suites == NULL || suites->suiteSz == 0) {
+            WOLFSSL_MSG("Suites pointer error or suiteSz 0");
+            return SUITES_ERROR;
+        }
+
+        for (i = 0; i < suites->suiteSz-1; i += SUITE_LEN) {
+            if (suites->suites[i]   == first &&
+                suites->suites[i+1] == second )
+                return i;
+        }
+
+        return MATCH_SUITE_ERROR;
+    }
+
+#endif
+
+#endif /* !WOLFSSL_NO_TLS12 */
+
+    /* Make sure server cert/key are valid for this suite, true on success */
+    static int VerifyServerSuite(WOLFSSL* ssl, word16 idx)
+    {
+        int  haveRSA = !ssl->options.haveStaticECC;
+        int  havePSK = 0;
+        byte first;
+        byte second;
+
+        WOLFSSL_ENTER("VerifyServerSuite");
+
+        if (ssl->suites == NULL) {
+            WOLFSSL_MSG("Suites pointer error");
+            return 0;
+        }
+
+        first   = ssl->suites->suites[idx];
+        second  = ssl->suites->suites[idx+1];
+
+        #ifndef NO_PSK
+            havePSK = ssl->options.havePSK;
+        #endif
+
+        if (ssl->options.haveNTRU)
+            haveRSA = 0;
+
+        if (CipherRequires(first, second, REQUIRES_RSA)) {
+            WOLFSSL_MSG("Requires RSA");
+            if (haveRSA == 0) {
+                WOLFSSL_MSG("Don't have RSA");
+                return 0;
+            }
+        }
+
+        if (CipherRequires(first, second, REQUIRES_DHE)) {
+            WOLFSSL_MSG("Requires DHE");
+            if (ssl->options.haveDH == 0) {
+                WOLFSSL_MSG("Don't have DHE");
+                return 0;
+            }
+        }
+
+        if (CipherRequires(first, second, REQUIRES_ECC)) {
+            WOLFSSL_MSG("Requires ECC");
+            if (ssl->options.haveECC == 0) {
+                WOLFSSL_MSG("Don't have ECC");
+                return 0;
+            }
+        }
+
+        if (CipherRequires(first, second, REQUIRES_ECC_STATIC)) {
+            WOLFSSL_MSG("Requires static ECC");
+            if (ssl->options.haveStaticECC == 0) {
+                WOLFSSL_MSG("Don't have static ECC");
+                return 0;
+            }
+        }
+
+        if (CipherRequires(first, second, REQUIRES_PSK)) {
+            WOLFSSL_MSG("Requires PSK");
+            if (havePSK == 0) {
+                WOLFSSL_MSG("Don't have PSK");
+                return 0;
+            }
+        }
+
+        if (CipherRequires(first, second, REQUIRES_NTRU)) {
+            WOLFSSL_MSG("Requires NTRU");
+            if (ssl->options.haveNTRU == 0) {
+                WOLFSSL_MSG("Don't have NTRU");
+                return 0;
+            }
+        }
+
+        if (CipherRequires(first, second, REQUIRES_RSA_SIG)) {
+            WOLFSSL_MSG("Requires RSA Signature");
+            if (ssl->options.side == WOLFSSL_SERVER_END &&
+                                           ssl->options.haveECDSAsig == 1) {
+                WOLFSSL_MSG("Don't have RSA Signature");
+                return 0;
+            }
+        }
+
+#if !defined(WOLFSSL_OLDTLS_AEAD_CIPHERSUITES)
+        if (CipherRequires(first, second, REQUIRES_AEAD)) {
+            WOLFSSL_MSG("Requires AEAD");
+            if (ssl->version.major == SSLv3_MAJOR &&
+                                           ssl->version.minor < TLSv1_2_MINOR) {
+                WOLFSSL_MSG("Version of SSL does not support AEAD ciphers");
+                return 0;
+            }
+
+        }
+#endif
+
+#if (defined(HAVE_ECC) || defined(HAVE_CURVE25519) || \
+                       defined(HAVE_CURVE448)) && defined(HAVE_SUPPORTED_CURVES)
+        if (!TLSX_ValidateSupportedCurves(ssl, first, second)) {
+            WOLFSSL_MSG("Don't have matching curves");
+            return 0;
+        }
+#endif
+
+        /* ECCDHE is always supported if ECC on */
+
+#ifdef HAVE_QSH
+        /* need to negotiate a classic suite in addition to TLS_QSH */
+        if (first == QSH_BYTE && second == TLS_QSH) {
+            if (TLSX_SupportExtensions(ssl)) {
+                ssl->options.haveQSH = 1; /* matched TLS_QSH */
+            }
+            else {
+                WOLFSSL_MSG("Version of SSL connection does not support "
+                            "TLS_QSH");
+            }
+            return 0;
+        }
+#endif
+
+#ifdef WOLFSSL_TLS13
+        if (IsAtLeastTLSv1_3(ssl->version) &&
+            ssl->options.side == WOLFSSL_SERVER_END) {
+            /* Try to establish a key share. */
+            int ret = TLSX_KeyShare_Establish(ssl);
+            if (ret == KEY_SHARE_ERROR)
+                ssl->options.serverState = SERVER_HELLO_RETRY_REQUEST_COMPLETE;
+            else if (ret != 0)
+                return 0;
+        }
+        else if (first == TLS13_BYTE || (first == ECC_BYTE &&
+                (second == TLS_SHA256_SHA256 || second == TLS_SHA384_SHA384))) {
+            /* Can't negotiate TLS 1.3 cipher suites with lower protocol
+             * version. */
+            return 0;
+        }
+#endif
+
+        return 1;
+    }
+
+#ifndef NO_WOLFSSL_SERVER
+    static int CompareSuites(WOLFSSL* ssl, Suites* peerSuites, word16 i,
+                             word16 j)
+    {
+        if (ssl->suites->suites[i]   == peerSuites->suites[j] &&
+            ssl->suites->suites[i+1] == peerSuites->suites[j+1] ) {
+
+            if (VerifyServerSuite(ssl, i)) {
+                int result;
+                WOLFSSL_MSG("Verified suite validity");
+                ssl->options.cipherSuite0 = ssl->suites->suites[i];
+                ssl->options.cipherSuite  = ssl->suites->suites[i+1];
+                result = SetCipherSpecs(ssl);
+                if (result == 0) {
+                    result = PickHashSigAlgo(ssl, peerSuites->hashSigAlgo,
+                                                     peerSuites->hashSigAlgoSz);
+                }
+                return result;
+            }
+            else {
+                WOLFSSL_MSG("Could not verify suite validity, continue");
+            }
+        }
+
+        return MATCH_SUITE_ERROR;
+    }
+
+    int MatchSuite(WOLFSSL* ssl, Suites* peerSuites)
+    {
+        int ret;
+        word16 i, j;
+
+        WOLFSSL_ENTER("MatchSuite");
+
+        /* & 0x1 equivalent % 2 */
+        if (peerSuites->suiteSz == 0 || peerSuites->suiteSz & 0x1)
+            return BUFFER_ERROR;
+
+        if (ssl->suites == NULL)
+            return SUITES_ERROR;
+
+        if (!ssl->options.useClientOrder) {
+            /* Server order */
+            for (i = 0; i < ssl->suites->suiteSz; i += 2) {
+                for (j = 0; j < peerSuites->suiteSz; j += 2) {
+                    ret = CompareSuites(ssl, peerSuites, i, j);
+                    if (ret != MATCH_SUITE_ERROR)
+                        return ret;
+                }
+            }
+        }
+        else {
+            /* Client order */
+            for (j = 0; j < peerSuites->suiteSz; j += 2) {
+                for (i = 0; i < ssl->suites->suiteSz; i += 2) {
+                    ret = CompareSuites(ssl, peerSuites, i, j);
+                    if (ret != MATCH_SUITE_ERROR)
+                        return ret;
+                }
+            }
+        }
+
+        return MATCH_SUITE_ERROR;
+    }
+#endif
+
+#ifdef OLD_HELLO_ALLOWED
+
+    /* process old style client hello, deprecate? */
+    int ProcessOldClientHello(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
+                              word32 inSz, word16 sz)
+    {
+        word32          idx = *inOutIdx;
+        word16          sessionSz;
+        word16          randomSz;
+        word16          i, j;
+        ProtocolVersion pv;
+        Suites          clSuites;
+        int ret = -1;
+
+        (void)inSz;
+        WOLFSSL_MSG("Got old format client hello");
+#ifdef WOLFSSL_CALLBACKS
+        if (ssl->hsInfoOn)
+            AddPacketName(ssl, "ClientHello");
+        if (ssl->toInfoOn)
+            AddLateName("ClientHello", &ssl->timeoutInfo);
+#endif
+
+        /* manually hash input since different format */
+#ifndef NO_OLD_TLS
+#ifndef NO_MD5
+        wc_Md5Update(&ssl->hsHashes->hashMd5, input + idx, sz);
+#endif
+#ifndef NO_SHA
+        wc_ShaUpdate(&ssl->hsHashes->hashSha, input + idx, sz);
+#endif
+#endif
+#ifndef NO_SHA256
+        if (IsAtLeastTLSv1_2(ssl)) {
+            int shaRet = wc_Sha256Update(&ssl->hsHashes->hashSha256,
+                                         input + idx, sz);
+            if (shaRet != 0)
+                return shaRet;
+        }
+#endif
+
+        /* does this value mean client_hello? */
+        idx++;
+
+        /* version */
+        pv.major = input[idx++];
+        pv.minor = input[idx++];
+        ssl->chVersion = pv;  /* store */
+
+        if (ssl->version.minor > pv.minor) {
+            byte haveRSA = 0;
+            byte havePSK = 0;
+            int  keySz   = 0;
+
+            if (!ssl->options.downgrade) {
+                WOLFSSL_MSG("Client trying to connect with lesser version");
+                return VERSION_ERROR;
+            }
+            if (pv.minor < ssl->options.minDowngrade) {
+                WOLFSSL_MSG("\tversion below minimum allowed, fatal error");
+                return VERSION_ERROR;
+            }
+            if (pv.minor == SSLv3_MINOR) {
+                /* turn off tls */
+                WOLFSSL_MSG("\tdowngrading to SSLv3");
+                ssl->options.tls    = 0;
+                ssl->options.tls1_1 = 0;
+                ssl->version.minor  = SSLv3_MINOR;
+            }
+            else if (pv.minor == TLSv1_MINOR) {
+                WOLFSSL_MSG("\tdowngrading to TLSv1");
+                /* turn off tls 1.1+ */
+                ssl->options.tls1_1 = 0;
+                ssl->version.minor  = TLSv1_MINOR;
+            }
+            else if (pv.minor == TLSv1_1_MINOR) {
+                WOLFSSL_MSG("\tdowngrading to TLSv1.1");
+                ssl->version.minor  = TLSv1_1_MINOR;
+            }
+            else if (pv.minor == TLSv1_2_MINOR) {
+                WOLFSSL_MSG("    downgrading to TLSv1.2");
+                ssl->version.minor  = TLSv1_2_MINOR;
+            }
+#ifndef NO_RSA
+            haveRSA = 1;
+#endif
+#ifndef NO_PSK
+            havePSK = ssl->options.havePSK;
+#endif
+#ifndef NO_CERTS
+            keySz = ssl->buffers.keySz;
+#endif
+
+            InitSuites(ssl->suites, ssl->version, keySz, haveRSA, havePSK,
+                       ssl->options.haveDH, ssl->options.haveNTRU,
+                       ssl->options.haveECDSAsig, ssl->options.haveECC,
+                       ssl->options.haveStaticECC, ssl->options.side);
+        }
+
+        /* suite size */
+        ato16(&input[idx], &clSuites.suiteSz);
+        idx += OPAQUE16_LEN;
+
+        if (clSuites.suiteSz > WOLFSSL_MAX_SUITE_SZ)
+            return BUFFER_ERROR;
+        clSuites.hashSigAlgoSz = 0;
+
+        /* session size */
+        ato16(&input[idx], &sessionSz);
+        idx += OPAQUE16_LEN;
+
+        if (sessionSz > ID_LEN)
+            return BUFFER_ERROR;
+
+        /* random size */
+        ato16(&input[idx], &randomSz);
+        idx += OPAQUE16_LEN;
+
+        if (randomSz > RAN_LEN)
+            return BUFFER_ERROR;
+
+        /* suites */
+        for (i = 0, j = 0; i < clSuites.suiteSz; i += 3) {
+            byte first = input[idx++];
+            if (!first) { /* implicit: skip sslv2 type */
+                XMEMCPY(&clSuites.suites[j], &input[idx], SUITE_LEN);
+                j += SUITE_LEN;
+            }
+            idx += SUITE_LEN;
+        }
+        clSuites.suiteSz = j;
+
+        /* session id */
+        if (sessionSz) {
+            XMEMCPY(ssl->arrays->sessionID, input + idx, sessionSz);
+            ssl->arrays->sessionIDSz = (byte)sessionSz;
+            idx += sessionSz;
+            ssl->options.resuming = 1;
+        }
+
+        /* random */
+        if (randomSz < RAN_LEN)
+            XMEMSET(ssl->arrays->clientRandom, 0, RAN_LEN - randomSz);
+        XMEMCPY(&ssl->arrays->clientRandom[RAN_LEN - randomSz], input + idx,
+               randomSz);
+        idx += randomSz;
+
+        if (ssl->options.usingCompression)
+            ssl->options.usingCompression = 0;  /* turn off */
+
+        ssl->options.clientState = CLIENT_HELLO_COMPLETE;
+        ssl->cbmode = SSL_CB_MODE_WRITE;
+        *inOutIdx = idx;
+
+        ssl->options.haveSessionId = 1;
+        /* DoClientHello uses same resume code */
+        if (ssl->options.resuming) {  /* let's try */
+            WOLFSSL_SESSION* session = GetSession(ssl,
+                                                  ssl->arrays->masterSecret, 1);
+            #ifdef HAVE_SESSION_TICKET
+                if (ssl->options.useTicket == 1) {
+                    session = &ssl->session;
+                }
+            #endif
+
+            if (!session) {
+                WOLFSSL_MSG("Session lookup for resume failed");
+                ssl->options.resuming = 0;
+            } else {
+            #ifdef HAVE_EXT_CACHE
+                wolfSSL_SESSION_free(session);
+            #endif
+                if (MatchSuite(ssl, &clSuites) < 0) {
+                    WOLFSSL_MSG("Unsupported cipher suite, OldClientHello");
+                    return UNSUPPORTED_SUITE;
+                }
+
+                ret = wc_RNG_GenerateBlock(ssl->rng, ssl->arrays->serverRandom,
+                                                                       RAN_LEN);
+                if (ret != 0)
+                    return ret;
+
+                #ifdef NO_OLD_TLS
+                    ret = DeriveTlsKeys(ssl);
+                #else
+                    #ifndef NO_TLS
+                        if (ssl->options.tls)
+                            ret = DeriveTlsKeys(ssl);
+                    #endif
+                        if (!ssl->options.tls)
+                            ret = DeriveKeys(ssl);
+                #endif
+                ssl->options.clientState = CLIENT_KEYEXCHANGE_COMPLETE;
+
+                return ret;
+            }
+        }
+
+        ret = MatchSuite(ssl, &clSuites);
+        if (ret != 0)return ret;
+        return SanityCheckMsgReceived(ssl, client_hello);
+    }
+
+#endif /* OLD_HELLO_ALLOWED */
+
+#ifndef WOLFSSL_NO_TLS12
+
+    int HandleTlsResumption(WOLFSSL* ssl, int bogusID, Suites* clSuites)
+    {
+        int ret = 0;
+        WOLFSSL_SESSION* session;
+
+        (void)bogusID;
+
+        session = GetSession(ssl, ssl->arrays->masterSecret, 1);
+        #ifdef HAVE_SESSION_TICKET
+            if (ssl->options.useTicket == 1) {
+                session = &ssl->session;
+            } else if (bogusID == 1 && ssl->options.rejectTicket == 0) {
+                WOLFSSL_MSG("Bogus session ID without session ticket");
+                return BUFFER_ERROR;
+            }
+        #endif
+
+        if (!session) {
+            WOLFSSL_MSG("Session lookup for resume failed");
+            ssl->options.resuming = 0;
+        }
+        else if (session->haveEMS != ssl->options.haveEMS) {
+            /* RFC 7627, 5.3, server-side */
+            /* if old sess didn't have EMS, but new does, full handshake */
+            if (!session->haveEMS && ssl->options.haveEMS) {
+                WOLFSSL_MSG("Attempting to resume a session that didn't "
+                            "use EMS with a new session with EMS. Do full "
+                            "handshake.");
+                ssl->options.resuming = 0;
+            }
+            /* if old sess used EMS, but new doesn't, MUST abort */
+            else if (session->haveEMS && !ssl->options.haveEMS) {
+                WOLFSSL_MSG("Trying to resume a session with EMS without "
+                            "using EMS");
+            #ifdef WOLFSSL_EXTRA_ALERTS
+                SendAlert(ssl, alert_fatal, handshake_failure);
+            #endif
+                return EXT_MASTER_SECRET_NEEDED_E;
+            }
+        #ifdef HAVE_EXT_CACHE
+            wolfSSL_SESSION_free(session);
+        #endif
+        }
+        else {
+        #ifndef NO_RESUME_SUITE_CHECK
+            int j;
+
+            /* Check client suites include the one in session */
+            for (j = 0; j < clSuites->suiteSz; j += 2) {
+                if (clSuites->suites[j] == session->cipherSuite0 &&
+                                clSuites->suites[j+1] == session->cipherSuite) {
+                    break;
+                }
+            }
+            if (j == clSuites->suiteSz) {
+                WOLFSSL_MSG("Prev session's cipher suite not in ClientHello");
+            #ifdef WOLFSSL_EXTRA_ALERTS
+                SendAlert(ssl, alert_fatal, illegal_parameter);
+            #endif
+                return UNSUPPORTED_SUITE;
+            }
+        #endif
+
+        #ifdef HAVE_EXT_CACHE
+            wolfSSL_SESSION_free(session);
+        #endif
+            if (MatchSuite(ssl, clSuites) < 0) {
+                WOLFSSL_MSG("Unsupported cipher suite, ClientHello");
+                return UNSUPPORTED_SUITE;
+            }
+
+            ret = wc_RNG_GenerateBlock(ssl->rng, ssl->arrays->serverRandom,
+                                                                       RAN_LEN);
+            if (ret != 0)
+                return ret;
+
+            #ifdef NO_OLD_TLS
+                ret = DeriveTlsKeys(ssl);
+            #else
+                #ifndef NO_TLS
+                    if (ssl->options.tls)
+                        ret = DeriveTlsKeys(ssl);
+                #endif
+                    if (!ssl->options.tls)
+                        ret = DeriveKeys(ssl);
+            #endif
+            ssl->options.clientState = CLIENT_KEYEXCHANGE_COMPLETE;
+        }
+
+        return ret;
+    }
+
+
+    /* handle processing of client_hello (1) */
+    int DoClientHello(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
+                             word32 helloSz)
+    {
+        byte            b;
+        byte            bogusID = 0;   /* flag for a bogus session id */
+        ProtocolVersion pv;
+        Suites          clSuites;
+        word32          i = *inOutIdx;
+        word32          begin = i;
+        int             ret = 0;
+#ifdef WOLFSSL_DTLS
+        Hmac            cookieHmac;
+        byte            peerCookie[MAX_COOKIE_LEN];
+        byte            peerCookieSz = 0;
+        byte            cookieType;
+        byte            cookieSz = 0;
+
+        XMEMSET(&cookieHmac, 0, sizeof(Hmac));
+#endif /* WOLFSSL_DTLS */
+
+        WOLFSSL_START(WC_FUNC_CLIENT_HELLO_DO);
+        WOLFSSL_ENTER("DoClientHello");
+
+#ifdef WOLFSSL_CALLBACKS
+        if (ssl->hsInfoOn) AddPacketName(ssl, "ClientHello");
+        if (ssl->toInfoOn) AddLateName("ClientHello", &ssl->timeoutInfo);
+#endif
+        /* protocol version, random and session id length check */
+        if (OPAQUE16_LEN + RAN_LEN + OPAQUE8_LEN > helloSz)
+            return BUFFER_ERROR;
+
+        /* protocol version */
+        XMEMCPY(&pv, input + i, OPAQUE16_LEN);
+        ssl->chVersion = pv;   /* store */
+#ifdef WOLFSSL_DTLS
+        if (IsDtlsNotSctpMode(ssl)) {
+            #if defined(NO_SHA) && defined(NO_SHA256)
+                #error "DTLS needs either SHA or SHA-256"
+            #endif /* NO_SHA && NO_SHA256 */
+
+            #if !defined(NO_SHA) && defined(NO_SHA256)
+                cookieType = WC_SHA;
+                cookieSz = WC_SHA_DIGEST_SIZE;
+            #endif /* NO_SHA */
+            #ifndef NO_SHA256
+                cookieType = WC_SHA256;
+                cookieSz = WC_SHA256_DIGEST_SIZE;
+            #endif /* NO_SHA256 */
+            ret = wc_HmacSetKey(&cookieHmac, cookieType,
+                                ssl->buffers.dtlsCookieSecret.buffer,
+                                ssl->buffers.dtlsCookieSecret.length);
+            if (ret != 0) return ret;
+            ret = wc_HmacUpdate(&cookieHmac,
+                                (const byte*)ssl->buffers.dtlsCtx.peer.sa,
+                                ssl->buffers.dtlsCtx.peer.sz);
+            if (ret != 0) return ret;
+            ret = wc_HmacUpdate(&cookieHmac, input + i, OPAQUE16_LEN);
+            if (ret != 0) return ret;
+        }
+#endif /* WOLFSSL_DTLS */
+        i += OPAQUE16_LEN;
+
+        /* Legacy protocol version cannot negotiate TLS 1.3 or higher. */
+        if (pv.major == SSLv3_MAJOR && pv.minor >= TLSv1_3_MINOR)
+            pv.minor = TLSv1_2_MINOR;
+
+        if ((!ssl->options.dtls && ssl->version.minor > pv.minor) ||
+            (ssl->options.dtls && ssl->version.minor != DTLS_MINOR
+             && ssl->version.minor != DTLSv1_2_MINOR && pv.minor != DTLS_MINOR
+             && pv.minor != DTLSv1_2_MINOR)) {
+
+            word16 haveRSA = 0;
+            word16 havePSK = 0;
+            int    keySz   = 0;
+
+            if (!ssl->options.downgrade) {
+                WOLFSSL_MSG("Client trying to connect with lesser version");
+                return VERSION_ERROR;
+            }
+            if (pv.minor < ssl->options.minDowngrade) {
+                WOLFSSL_MSG("\tversion below minimum allowed, fatal error");
+                return VERSION_ERROR;
+            }
+
+            if (pv.minor == SSLv3_MINOR) {
+                /* turn off tls */
+                WOLFSSL_MSG("\tdowngrading to SSLv3");
+                ssl->options.tls    = 0;
+                ssl->options.tls1_1 = 0;
+                ssl->version.minor  = SSLv3_MINOR;
+            }
+            else if (pv.minor == TLSv1_MINOR) {
+                /* turn off tls 1.1+ */
+                WOLFSSL_MSG("\tdowngrading to TLSv1");
+                ssl->options.tls1_1 = 0;
+                ssl->version.minor  = TLSv1_MINOR;
+            }
+            else if (pv.minor == TLSv1_1_MINOR) {
+                WOLFSSL_MSG("\tdowngrading to TLSv1.1");
+                ssl->version.minor  = TLSv1_1_MINOR;
+            }
+            else if (pv.minor == TLSv1_2_MINOR) {
+                WOLFSSL_MSG("    downgrading to TLSv1.2");
+                ssl->version.minor  = TLSv1_2_MINOR;
+            }
+#ifndef NO_RSA
+            haveRSA = 1;
+#endif
+#ifndef NO_PSK
+            havePSK = ssl->options.havePSK;
+#endif
+#ifndef NO_CERTS
+            keySz = ssl->buffers.keySz;
+#endif
+            InitSuites(ssl->suites, ssl->version, keySz, haveRSA, havePSK,
+                       ssl->options.haveDH, ssl->options.haveNTRU,
+                       ssl->options.haveECDSAsig, ssl->options.haveECC,
+                       ssl->options.haveStaticECC, ssl->options.side);
+        }
+
+#ifdef OPENSSL_EXTRA
+        /* check if option is set to not allow the current version
+         * set from either wolfSSL_set_options or wolfSSL_CTX_set_options */
+        if (!ssl->options.dtls && ssl->options.downgrade &&
+                ssl->options.mask > 0) {
+            int reset = 0;
+            if (ssl->version.minor == TLSv1_2_MINOR &&
+             (ssl->options.mask & SSL_OP_NO_TLSv1_2) == SSL_OP_NO_TLSv1_2) {
+                WOLFSSL_MSG("\tOption set to not allow TLSv1.2, Downgrading");
+                ssl->version.minor = TLSv1_1_MINOR;
+                reset = 1;
+            }
+            if (ssl->version.minor == TLSv1_1_MINOR &&
+             (ssl->options.mask & SSL_OP_NO_TLSv1_1) == SSL_OP_NO_TLSv1_1) {
+                WOLFSSL_MSG("\tOption set to not allow TLSv1.1, Downgrading");
+                ssl->options.tls1_1 = 0;
+                ssl->version.minor = TLSv1_MINOR;
+                reset = 1;
+            }
+            if (ssl->version.minor == TLSv1_MINOR &&
+                (ssl->options.mask & SSL_OP_NO_TLSv1) == SSL_OP_NO_TLSv1) {
+                WOLFSSL_MSG("\tOption set to not allow TLSv1, Downgrading");
+                ssl->options.tls    = 0;
+                ssl->options.tls1_1 = 0;
+                ssl->version.minor = SSLv3_MINOR;
+                reset = 1;
+            }
+            if (ssl->version.minor == SSLv3_MINOR &&
+                (ssl->options.mask & SSL_OP_NO_SSLv3) == SSL_OP_NO_SSLv3) {
+                WOLFSSL_MSG("\tError, option set to not allow SSLv3");
+                return VERSION_ERROR;
+            }
+
+            if (ssl->version.minor < ssl->options.minDowngrade) {
+                WOLFSSL_MSG("\tversion below minimum allowed, fatal error");
+                return VERSION_ERROR;
+            }
+
+            if (reset) {
+                word16 haveRSA = 0;
+                word16 havePSK = 0;
+                int    keySz   = 0;
+
+            #ifndef NO_RSA
+                haveRSA = 1;
+            #endif
+            #ifndef NO_PSK
+                havePSK = ssl->options.havePSK;
+            #endif
+            #ifndef NO_CERTS
+                keySz = ssl->buffers.keySz;
+            #endif
+
+                /* reset cipher suites to account for TLS version change */
+                InitSuites(ssl->suites, ssl->version, keySz, haveRSA, havePSK,
+                       ssl->options.haveDH, ssl->options.haveNTRU,
+                       ssl->options.haveECDSAsig, ssl->options.haveECC,
+                       ssl->options.haveStaticECC, ssl->options.side);
+            }
+        }
+#endif
+
+        /* random */
+        XMEMCPY(ssl->arrays->clientRandom, input + i, RAN_LEN);
+#ifdef WOLFSSL_DTLS
+        if (IsDtlsNotSctpMode(ssl)) {
+            ret = wc_HmacUpdate(&cookieHmac, input + i, RAN_LEN);
+            if (ret != 0) return ret;
+        }
+#endif /* WOLFSSL_DTLS */
+        i += RAN_LEN;
+
+#ifdef SHOW_SECRETS
+        {
+            int j;
+            printf("client random: ");
+            for (j = 0; j < RAN_LEN; j++)
+                printf("%02x", ssl->arrays->clientRandom[j]);
+            printf("\n");
+        }
+#endif
+
+        /* session id */
+        b = input[i++];
+
+#ifdef HAVE_SESSION_TICKET
+        if (b > 0 && b < ID_LEN) {
+            bogusID = 1;
+            WOLFSSL_MSG("Client sent bogus session id, let's allow for echo");
+        }
+#endif
+
+        if (b == ID_LEN || bogusID) {
+            if ((i - begin) + b > helloSz)
+                return BUFFER_ERROR;
+
+            XMEMCPY(ssl->arrays->sessionID, input + i, b);
+#ifdef WOLFSSL_DTLS
+            if (IsDtlsNotSctpMode(ssl)) {
+                ret = wc_HmacUpdate(&cookieHmac, input + i - 1, b + 1);
+                if (ret != 0) return ret;
+            }
+#endif /* WOLFSSL_DTLS */
+            ssl->arrays->sessionIDSz = b;
+            i += b;
+            ssl->options.resuming = 1; /* client wants to resume */
+            WOLFSSL_MSG("Client wants to resume session");
+        }
+        else if (b) {
+            WOLFSSL_MSG("Invalid session ID size");
+            return BUFFER_ERROR; /* session ID nor 0 neither 32 bytes long */
+        }
+
+        #ifdef WOLFSSL_DTLS
+            /* cookie */
+            if (ssl->options.dtls) {
+
+                if ((i - begin) + OPAQUE8_LEN > helloSz)
+                    return BUFFER_ERROR;
+
+                peerCookieSz = input[i++];
+
+                if (peerCookieSz) {
+                    if (peerCookieSz > MAX_COOKIE_LEN)
+                        return BUFFER_ERROR;
+
+                    if ((i - begin) + peerCookieSz > helloSz)
+                        return BUFFER_ERROR;
+
+                    XMEMCPY(peerCookie, input + i, peerCookieSz);
+
+                    i += peerCookieSz;
+                }
+            }
+        #endif
+
+        /* suites */
+        if ((i - begin) + OPAQUE16_LEN > helloSz)
+            return BUFFER_ERROR;
+
+        ato16(&input[i], &clSuites.suiteSz);
+        i += OPAQUE16_LEN;
+
+        /* suites and compression length check */
+        if ((i - begin) + clSuites.suiteSz + OPAQUE8_LEN > helloSz)
+            return BUFFER_ERROR;
+
+        if (clSuites.suiteSz > WOLFSSL_MAX_SUITE_SZ)
+            return BUFFER_ERROR;
+
+        XMEMCPY(clSuites.suites, input + i, clSuites.suiteSz);
+
+#ifdef HAVE_SERVER_RENEGOTIATION_INFO
+        /* check for TLS_EMPTY_RENEGOTIATION_INFO_SCSV suite */
+        if (FindSuite(&clSuites, 0, TLS_EMPTY_RENEGOTIATION_INFO_SCSV) >= 0) {
+            TLSX* extension;
+
+            /* check for TLS_EMPTY_RENEGOTIATION_INFO_SCSV suite */
+            ret = TLSX_AddEmptyRenegotiationInfo(&ssl->extensions, ssl->heap);
+            if (ret != WOLFSSL_SUCCESS)
+                return ret;
+
+            extension = TLSX_Find(ssl->extensions, TLSX_RENEGOTIATION_INFO);
+            if (extension) {
+                ssl->secure_renegotiation =
+                                          (SecureRenegotiation*)extension->data;
+                ssl->secure_renegotiation->enabled = 1;
+            }
+        }
+#endif /* HAVE_SERVER_RENEGOTIATION_INFO */
+#if defined(HAVE_FALLBACK_SCSV) || defined(OPENSSL_ALL)
+        /* check for TLS_FALLBACK_SCSV suite */
+        if (FindSuite(&clSuites, TLS_FALLBACK_SCSV, 0) >= 0) {
+            WOLFSSL_MSG("Found Fallback SCSV");
+            if (ssl->ctx->method->version.minor > pv.minor) {
+                WOLFSSL_MSG("Client trying to connect with lesser version");
+                SendAlert(ssl, alert_fatal, inappropriate_fallback);
+                return VERSION_ERROR;
+            }
+        }
+#endif
+
+#ifdef WOLFSSL_DTLS
+        if (IsDtlsNotSctpMode(ssl)) {
+            ret = wc_HmacUpdate(&cookieHmac,
+                                    input + i - OPAQUE16_LEN,
+                                    clSuites.suiteSz + OPAQUE16_LEN);
+            if (ret != 0) return ret;
+        }
+#endif /* WOLFSSL_DTLS */
+        i += clSuites.suiteSz;
+        clSuites.hashSigAlgoSz = 0;
+
+        /* compression length */
+        b = input[i++];
+
+        if ((i - begin) + b > helloSz)
+            return BUFFER_ERROR;
+
+        if (b == 0) {
+            WOLFSSL_MSG("No compression types in list");
+#ifdef WOLFSSL_EXTRA_ALERTS
+            SendAlert(ssl, alert_fatal, decode_error);
+#endif
+            return COMPRESSION_ERROR;
+        }
+
+#ifdef WOLFSSL_DTLS
+        if (IsDtlsNotSctpMode(ssl)) {
+            byte newCookie[MAX_COOKIE_LEN];
+
+            ret = wc_HmacUpdate(&cookieHmac, input + i - 1, b + 1);
+            if (ret != 0) return ret;
+            ret = wc_HmacFinal(&cookieHmac, newCookie);
+            if (ret != 0) return ret;
+
+            /* If a cookie callback is set, call it to overwrite the cookie.
+             * This should be deprecated. The code now calculates the cookie
+             * using an HMAC as expected. */
+            if (ssl->ctx->CBIOCookie != NULL &&
+                ssl->ctx->CBIOCookie(ssl, newCookie, cookieSz,
+                                             ssl->IOCB_CookieCtx) != cookieSz) {
+                return COOKIE_ERROR;
+            }
+
+            /* Check the cookie, see if we progress the state machine. */
+            if (peerCookieSz != cookieSz ||
+                XMEMCMP(peerCookie, newCookie, cookieSz) != 0) {
+
+                /* Send newCookie to client in a HelloVerifyRequest message
+                 * and let the state machine alone. */
+                ssl->msgsReceived.got_client_hello = 0;
+                ssl->keys.dtls_handshake_number = 0;
+                ssl->keys.dtls_expected_peer_handshake_number = 0;
+                *inOutIdx += helloSz;
+                return SendHelloVerifyRequest(ssl, newCookie, cookieSz);
+            }
+
+            /* This was skipped in the DTLS case so we could handle the hello
+             * verify request. */
+            ret = HashInput(ssl, input + *inOutIdx, helloSz);
+            if (ret != 0) return ret;
+        }
+#endif /* WOLFSSL_DTLS */
+
+        {
+            /* compression match types */
+            int matchNo = 0;
+            int matchZlib = 0;
+
+            while (b--) {
+                byte comp = input[i++];
+
+                if (comp == NO_COMPRESSION) {
+                    matchNo = 1;
+                }
+                if (comp == ZLIB_COMPRESSION) {
+                    matchZlib = 1;
+                }
+            }
+
+            if (ssl->options.usingCompression == 0 && matchNo) {
+                WOLFSSL_MSG("Matched No Compression");
+            } else if (ssl->options.usingCompression && matchZlib) {
+                WOLFSSL_MSG("Matched zlib Compression");
+            } else if (ssl->options.usingCompression && matchNo) {
+                WOLFSSL_MSG("Could only match no compression, turning off");
+                ssl->options.usingCompression = 0;  /* turn off */
+            } else {
+                WOLFSSL_MSG("Could not match compression");
+#ifdef WOLFSSL_EXTRA_ALERTS
+                SendAlert(ssl, alert_fatal, illegal_parameter);
+#endif
+                return COMPRESSION_ERROR;
+            }
+        }
+
+        *inOutIdx = i;
+
+        /* tls extensions */
+        if ((i - begin) < helloSz) {
+#ifdef HAVE_TLS_EXTENSIONS
+        #ifdef HAVE_QSH
+            QSH_Init(ssl);
+        #endif
+            if (TLSX_SupportExtensions(ssl))
+#else
+            if (IsAtLeastTLSv1_2(ssl))
+#endif
+            {
+                /* Process the hello extension. Skip unsupported. */
+                word16 totalExtSz;
+
+#ifdef HAVE_TLS_EXTENSIONS
+                /* auto populate extensions supported unless user defined */
+                if ((ret = TLSX_PopulateExtensions(ssl, 1)) != 0)
+                    return ret;
+#endif
+
+                if ((i - begin) + OPAQUE16_LEN > helloSz)
+                    return BUFFER_ERROR;
+
+                ato16(&input[i], &totalExtSz);
+                i += OPAQUE16_LEN;
+
+                if ((i - begin) + totalExtSz > helloSz)
+                    return BUFFER_ERROR;
+
+#ifdef HAVE_TLS_EXTENSIONS
+                /* tls extensions */
+                if ((ret = TLSX_Parse(ssl, (byte *) input + i, totalExtSz,
+                                      client_hello, &clSuites)))
+                    return ret;
+    #ifdef WOLFSSL_TLS13
+                if (TLSX_Find(ssl->extensions,
+                                             TLSX_SUPPORTED_VERSIONS) != NULL) {
+                    WOLFSSL_MSG(
+                            "Client attempting to connect with higher version");
+                    return VERSION_ERROR;
+                }
+    #endif
+    #if defined(OPENSSL_ALL) || defined(HAVE_STUNNEL) || defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY)
+                if((ret=SNI_Callback(ssl)))
+                    return ret;
+                ssl->options.side = WOLFSSL_SERVER_END;
+    #endif
+
+                i += totalExtSz;
+#else
+                while (totalExtSz) {
+                    word16 extId, extSz;
+
+                    if (OPAQUE16_LEN + OPAQUE16_LEN > totalExtSz)
+                        return BUFFER_ERROR;
+
+                    ato16(&input[i], &extId);
+                    i += OPAQUE16_LEN;
+                    ato16(&input[i], &extSz);
+                    i += OPAQUE16_LEN;
+
+                    if (OPAQUE16_LEN + OPAQUE16_LEN + extSz > totalExtSz)
+                        return BUFFER_ERROR;
+
+                    if (extId == HELLO_EXT_SIG_ALGO) {
+                        word16 hashSigAlgoSz;
+
+                        ato16(&input[i], &hashSigAlgoSz);
+                        i += OPAQUE16_LEN;
+
+                        if (OPAQUE16_LEN + hashSigAlgoSz > extSz)
+                            return BUFFER_ERROR;
+
+                        clSuites.hashSigAlgoSz = hashSigAlgoSz;
+                        if (clSuites.hashSigAlgoSz > WOLFSSL_MAX_SIGALGO) {
+                            WOLFSSL_MSG("ClientHello SigAlgo list exceeds max, "
+                                                                  "truncating");
+                            clSuites.hashSigAlgoSz = WOLFSSL_MAX_SIGALGO;
+                        }
+
+                        XMEMCPY(clSuites.hashSigAlgo, &input[i],
+                                                      clSuites.hashSigAlgoSz);
+
+                        i += hashSigAlgoSz;
+                    }
+#ifdef HAVE_EXTENDED_MASTER
+                    else if (extId == HELLO_EXT_EXTMS)
+                        ssl->options.haveEMS = 1;
+#endif
+                    else
+                        i += extSz;
+
+                    totalExtSz -= OPAQUE16_LEN + OPAQUE16_LEN + extSz;
+                }
+#endif
+                *inOutIdx = i;
+            }
+            else
+                *inOutIdx = begin + helloSz; /* skip extensions */
+        }
+
+        ssl->options.clientState   = CLIENT_HELLO_COMPLETE;
+        ssl->options.haveSessionId = 1;
+
+        /* ProcessOld uses same resume code */
+        if (ssl->options.resuming) {
+            ret = HandleTlsResumption(ssl, bogusID, &clSuites);
+            if (ret != 0)
+                return ret;
+
+            #ifdef HAVE_SECURE_RENEGOTIATION
+            if (ssl->secure_renegotiation &&
+                    ssl->secure_renegotiation->enabled &&
+                    IsEncryptionOn(ssl, 0))
+                ssl->secure_renegotiation->startScr = 1;
+            #endif
+
+            if (ssl->options.clientState == CLIENT_KEYEXCHANGE_COMPLETE) {
+                WOLFSSL_LEAVE("DoClientHello", ret);
+                WOLFSSL_END(WC_FUNC_CLIENT_HELLO_DO);
+
+                return ret;
+            }
+        }
+
+#if defined(HAVE_TLS_EXTENSIONS) && defined(HAVE_DH_DEFAULT_PARAMS)
+    #if defined(HAVE_FFDHE) && defined(HAVE_SUPPORTED_CURVES)
+        if (TLSX_Find(ssl->extensions, TLSX_SUPPORTED_GROUPS) != NULL) {
+            /* Set FFDHE parameters or clear DHE parameters if FFDH parameters
+             * present and no matches in the server's list. */
+            ret = TLSX_SupportedFFDHE_Set(ssl);
+            if (ret != 0)
+                return ret;
+        }
+    #endif
+#endif
+
+        ret = MatchSuite(ssl, &clSuites);
+#ifdef WOLFSSL_EXTRA_ALERTS
+        if (ret == BUFFER_ERROR)
+            SendAlert(ssl, alert_fatal, decode_error);
+        else if (ret < 0)
+            SendAlert(ssl, alert_fatal, handshake_failure);
+#endif
+
+#ifdef HAVE_SECURE_RENEGOTIATION
+        if (ssl->secure_renegotiation && ssl->secure_renegotiation->enabled &&
+                IsEncryptionOn(ssl, 0)) {
+            ssl->secure_renegotiation->startScr = 1;
+        }
+#endif
+        WOLFSSL_LEAVE("DoClientHello", ret);
+        WOLFSSL_END(WC_FUNC_CLIENT_HELLO_DO);
+
+        return ret;
+    }
+
+
+#if (!defined(NO_RSA) || defined(HAVE_ECC) || defined(HAVE_ED25519) || \
+                        defined(HAVE_ED448)) && !defined(WOLFSSL_NO_CLIENT_AUTH)
+
+    typedef struct DcvArgs {
+        byte*  output; /* not allocated */
+        word32 sendSz;
+        word16 sz;
+        word32 sigSz;
+        word32 idx;
+        word32 begin;
+        byte   hashAlgo;
+        byte   sigAlgo;
+    } DcvArgs;
+
+    static void FreeDcvArgs(WOLFSSL* ssl, void* pArgs)
+    {
+        DcvArgs* args = (DcvArgs*)pArgs;
+
+        (void)ssl;
+        (void)args;
+    }
+
+    /* handle processing of certificate_verify (15) */
+    static int DoCertificateVerify(WOLFSSL* ssl, byte* input,
+                                word32* inOutIdx, word32 size)
+    {
+        int ret = 0;
+    #ifdef WOLFSSL_ASYNC_CRYPT
+        DcvArgs* args = (DcvArgs*)ssl->async.args;
+        typedef char args_test[sizeof(ssl->async.args) >= sizeof(*args) ? 1 : -1];
+        (void)sizeof(args_test);
+    #else
+        DcvArgs  args[1];
+    #endif
+
+        WOLFSSL_START(WC_FUNC_CERTIFICATE_VERIFY_DO);
+        WOLFSSL_ENTER("DoCertificateVerify");
+
+    #ifdef WOLFSSL_ASYNC_CRYPT
+        ret = wolfSSL_AsyncPop(ssl, &ssl->options.asyncState);
+        if (ret != WC_NOT_PENDING_E) {
+            /* Check for error */
+            if (ret < 0)
+                goto exit_dcv;
+        }
+        else
+    #endif
+        {
+            /* Reset state */
+            ret = 0;
+            ssl->options.asyncState = TLS_ASYNC_BEGIN;
+            XMEMSET(args, 0, sizeof(DcvArgs));
+            args->hashAlgo = sha_mac;
+            args->sigAlgo = anonymous_sa_algo;
+            args->idx = *inOutIdx;
+            args->begin = *inOutIdx;
+        #ifdef WOLFSSL_ASYNC_CRYPT
+            ssl->async.freeArgs = FreeDcvArgs;
+        #endif
+        }
+
+        switch(ssl->options.asyncState)
+        {
+            case TLS_ASYNC_BEGIN:
+            {
+            #ifdef WOLFSSL_CALLBACKS
+                if (ssl->hsInfoOn)
+                    AddPacketName(ssl, "CertificateVerify");
+                if (ssl->toInfoOn)
+                    AddLateName("CertificateVerify", &ssl->timeoutInfo);
+            #endif
+
+                /* Advance state and proceed */
+                ssl->options.asyncState = TLS_ASYNC_BUILD;
+            } /* case TLS_ASYNC_BEGIN */
+            FALL_THROUGH;
+
+            case TLS_ASYNC_BUILD:
+            {
+                if (IsAtLeastTLSv1_2(ssl)) {
+                    if ((args->idx - args->begin) + ENUM_LEN + ENUM_LEN > size) {
+                        ERROR_OUT(BUFFER_ERROR, exit_dcv);
+                    }
+
+                    DecodeSigAlg(&input[args->idx], &args->hashAlgo,
+                                 &args->sigAlgo);
+                    args->idx += 2;
+                }
+            #ifndef NO_RSA
+                else if (ssl->peerRsaKey != NULL && ssl->peerRsaKeyPresent != 0)
+                    args->sigAlgo = rsa_sa_algo;
+            #endif
+            #ifdef HAVE_ECC
+                else if (ssl->peerEccDsaKeyPresent)
+                    args->sigAlgo = ecc_dsa_sa_algo;
+            #endif
+            #if defined(HAVE_ED25519) && !defined(NO_ED25519_CLIENT_AUTH)
+                else if (ssl->peerEd25519KeyPresent)
+                    args->sigAlgo = ed25519_sa_algo;
+            #endif /* HAVE_ED25519 && !NO_ED25519_CLIENT_AUTH */
+            #if defined(HAVE_ED448) && !defined(NO_ED448_CLIENT_AUTH)
+                else if (ssl->peerEd448KeyPresent)
+                    args->sigAlgo = ed448_sa_algo;
+            #endif /* HAVE_ED448 && !NO_ED448_CLIENT_AUTH */
+
+                if ((args->idx - args->begin) + OPAQUE16_LEN > size) {
+                    ERROR_OUT(BUFFER_ERROR, exit_dcv);
+                }
+
+                ato16(input + args->idx, &args->sz);
+                args->idx += OPAQUE16_LEN;
+
+                if ((args->idx - args->begin) + args->sz > size ||
+                                                    args->sz > ENCRYPT_LEN) {
+                    ERROR_OUT(BUFFER_ERROR, exit_dcv);
+                }
+
+            #ifdef HAVE_ECC
+                if (ssl->peerEccDsaKeyPresent) {
+
+                    WOLFSSL_MSG("Doing ECC peer cert verify");
+
+                /* make sure a default is defined */
+                #if !defined(NO_SHA)
+                    SetDigest(ssl, sha_mac);
+                #elif !defined(NO_SHA256)
+                    SetDigest(ssl, sha256_mac);
+                #elif defined(WOLFSSL_SHA384)
+                    SetDigest(ssl, sha384_mac);
+                #elif defined(WOLFSSL_SHA512)
+                    SetDigest(ssl, sha512_mac);
+                #else
+                    #error No digest enabled for ECC sig verify
+                #endif
+
+                    if (IsAtLeastTLSv1_2(ssl)) {
+                        if (args->sigAlgo != ecc_dsa_sa_algo) {
+                            WOLFSSL_MSG("Oops, peer sent ECC key but not in verify");
+                        }
+
+                        SetDigest(ssl, args->hashAlgo);
+                    }
+                }
+            #endif /* HAVE_ECC */
+            #if defined(HAVE_ED25519) && !defined(NO_ED25519_CLIENT_AUTH)
+                if (ssl->peerEd25519KeyPresent) {
+                    WOLFSSL_MSG("Doing ED25519 peer cert verify");
+                    if (IsAtLeastTLSv1_2(ssl) &&
+                                             args->sigAlgo != ed25519_sa_algo) {
+                        WOLFSSL_MSG(
+                               "Oops, peer sent ED25519 key but not in verify");
+                    }
+                }
+            #endif /* HAVE_ED25519 && !NO_ED25519_CLIENT_AUTH */
+            #if defined(HAVE_ED448) && !defined(NO_ED448_CLIENT_AUTH)
+                if (ssl->peerEd448KeyPresent) {
+                    WOLFSSL_MSG("Doing ED448 peer cert verify");
+                    if (IsAtLeastTLSv1_2(ssl) &&
+                                               args->sigAlgo != ed448_sa_algo) {
+                        WOLFSSL_MSG(
+                                 "Oops, peer sent ED448 key but not in verify");
+                    }
+                }
+            #endif /* HAVE_ED448 && !NO_ED448_CLIENT_AUTH */
+
+                /* Advance state and proceed */
+                ssl->options.asyncState = TLS_ASYNC_DO;
+            } /* case TLS_ASYNC_BUILD */
+            FALL_THROUGH;
+
+            case TLS_ASYNC_DO:
+            {
+            #ifndef NO_RSA
+                if (ssl->peerRsaKey != NULL && ssl->peerRsaKeyPresent != 0) {
+                    WOLFSSL_MSG("Doing RSA peer cert verify");
+
+                    ret = RsaVerify(ssl,
+                        input + args->idx,
+                        args->sz,
+                        &args->output,
+                        args->sigAlgo, args->hashAlgo,
+                        ssl->peerRsaKey,
+                    #ifdef HAVE_PK_CALLBACKS
+                        &ssl->buffers.peerRsaKey
+                    #else
+                        NULL
+                    #endif
+                    );
+                    if (ret >= 0) {
+                        if (args->sigAlgo == rsa_sa_algo)
+                            args->sendSz = ret;
+                        else {
+                            args->sigSz = ret;
+                            args->sendSz = ssl->buffers.digest.length;
+                        }
+                        ret = 0;
+                    }
+                }
+            #endif /* !NO_RSA */
+            #ifdef HAVE_ECC
+                if (ssl->peerEccDsaKeyPresent) {
+                    WOLFSSL_MSG("Doing ECC peer cert verify");
+
+                    ret = EccVerify(ssl,
+                        input + args->idx, args->sz,
+                        ssl->buffers.digest.buffer, ssl->buffers.digest.length,
+                        ssl->peerEccDsaKey,
+                    #ifdef HAVE_PK_CALLBACKS
+                        &ssl->buffers.peerEccDsaKey
+                    #else
+                        NULL
+                    #endif
+                    );
+                }
+            #endif /* HAVE_ECC */
+            #if defined(HAVE_ED25519) && !defined(NO_ED25519_CLIENT_AUTH)
+                if (ssl->peerEd25519KeyPresent) {
+                    WOLFSSL_MSG("Doing Ed25519 peer cert verify");
+
+                    ret = Ed25519Verify(ssl,
+                        input + args->idx, args->sz,
+                        ssl->hsHashes->messages, ssl->hsHashes->prevLen,
+                        ssl->peerEd25519Key,
+                    #ifdef HAVE_PK_CALLBACKS
+                        &ssl->buffers.peerEd25519Key
+                    #else
+                        NULL
+                    #endif
+                    );
+                }
+            #endif /* HAVE_ED25519 && !NO_ED25519_CLIENT_AUTH */
+            #if defined(HAVE_ED448) && !defined(NO_ED448_CLIENT_AUTH)
+                if (ssl->peerEd448KeyPresent) {
+                    WOLFSSL_MSG("Doing Ed448 peer cert verify");
+
+                    ret = Ed448Verify(ssl,
+                        input + args->idx, args->sz,
+                        ssl->hsHashes->messages, ssl->hsHashes->prevLen,
+                        ssl->peerEd448Key,
+                    #ifdef HAVE_PK_CALLBACKS
+                        &ssl->buffers.peerEd448Key
+                    #else
+                        NULL
+                    #endif
+                    );
+                }
+            #endif /* HAVE_ED448 && !NO_ED448_CLIENT_AUTH */
+
+            #ifdef WOLFSSL_ASYNC_CRYPT
+                /* handle async pending */
+                if (ret == WC_PENDING_E)
+                    goto exit_dcv;
+            #endif
+
+                /* Check for error */
+                if (ret != 0) {
+                    ret = SIG_VERIFY_E;
+                    goto exit_dcv;
+                }
+
+                /* Advance state and proceed */
+                ssl->options.asyncState = TLS_ASYNC_VERIFY;
+            } /* case TLS_ASYNC_DO */
+            FALL_THROUGH;
+
+            case TLS_ASYNC_VERIFY:
+            {
+            #ifndef NO_RSA
+                if (ssl->peerRsaKey != NULL && ssl->peerRsaKeyPresent != 0) {
+                    if (IsAtLeastTLSv1_2(ssl)) {
+                    #ifdef WC_RSA_PSS
+                        if (args->sigAlgo == rsa_pss_sa_algo) {
+                            SetDigest(ssl, args->hashAlgo);
+
+                        #ifdef HAVE_SELFTEST
+                            ret = wc_RsaPSS_CheckPadding(
+                                            ssl->buffers.digest.buffer,
+                                            ssl->buffers.digest.length,
+                                            args->output, args->sigSz,
+                                            HashAlgoToType(args->hashAlgo));
+                        #else
+                            ret = wc_RsaPSS_CheckPadding_ex(
+                                            ssl->buffers.digest.buffer,
+                                            ssl->buffers.digest.length,
+                                            args->output, args->sigSz,
+                                            HashAlgoToType(args->hashAlgo), -1,
+                                            mp_count_bits(&ssl->peerRsaKey->n));
+                        #endif
+                            if (ret != 0) {
+                                ret = SIG_VERIFY_E;
+                                goto exit_dcv;
+                            }
+                        }
+                        else
+                    #endif
+                        {
+                        #ifdef WOLFSSL_SMALL_STACK
+                            byte* encodedSig;
+                        #else
+                            byte  encodedSig[MAX_ENCODED_SIG_SZ];
+                        #endif
+
+                        #ifdef WOLFSSL_SMALL_STACK
+                            encodedSig = (byte*)XMALLOC(MAX_ENCODED_SIG_SZ,
+                                             ssl->heap, DYNAMIC_TYPE_SIGNATURE);
+                            if (encodedSig == NULL) {
+                                ERROR_OUT(MEMORY_E, exit_dcv);
+                            }
+                        #endif
+
+                            if (args->sigAlgo != rsa_sa_algo) {
+                                WOLFSSL_MSG("Oops, peer sent RSA key but not "
+                                            "in verify");
+                            }
+
+                            SetDigest(ssl, args->hashAlgo);
+
+                            args->sigSz = wc_EncodeSignature(encodedSig,
+                                ssl->buffers.digest.buffer,
+                                ssl->buffers.digest.length,
+                                TypeHash(args->hashAlgo));
+
+                            if (args->sendSz != args->sigSz || !args->output ||
+                                XMEMCMP(args->output, encodedSig,
+                                    min(args->sigSz, MAX_ENCODED_SIG_SZ)) != 0) {
+                                ret = VERIFY_CERT_ERROR;
+                            }
+
+                        #ifdef WOLFSSL_SMALL_STACK
+                            XFREE(encodedSig, ssl->heap, DYNAMIC_TYPE_SIGNATURE);
+                        #endif
+                        }
+                    }
+                    else {
+                        if (args->sendSz != FINISHED_SZ || !args->output ||
+                            XMEMCMP(args->output,
+                                &ssl->hsHashes->certHashes, FINISHED_SZ) != 0) {
+                            ret = VERIFY_CERT_ERROR;
+                        }
+                    }
+                }
+            #endif /* !NO_RSA */
+
+                /* Advance state and proceed */
+                ssl->options.asyncState = TLS_ASYNC_FINALIZE;
+            } /* case TLS_ASYNC_VERIFY */
+            FALL_THROUGH;
+
+            case TLS_ASYNC_FINALIZE:
+            {
+                if (IsEncryptionOn(ssl, 0)) {
+                    args->idx += ssl->keys.padSz;
+            #if defined(HAVE_ENCRYPT_THEN_MAC) && !defined(WOLFSSL_AEAD_ONLY)
+                    if (ssl->options.startedETMRead)
+                        args->idx += MacSize(ssl);
+            #endif
+                }
+
+                ssl->options.havePeerVerify = 1;
+
+                /* Set final index */
+                args->idx += args->sz;
+                *inOutIdx = args->idx;
+
+                /* Advance state and proceed */
+                ssl->options.asyncState = TLS_ASYNC_END;
+            } /* case TLS_ASYNC_FINALIZE */
+
+            case TLS_ASYNC_END:
+            {
+                break;
+            }
+            default:
+                ret = INPUT_CASE_ERROR;
+        } /* switch(ssl->options.asyncState) */
+
+    exit_dcv:
+
+        WOLFSSL_LEAVE("DoCertificateVerify", ret);
+        WOLFSSL_END(WC_FUNC_CERTIFICATE_VERIFY_DO);
+
+    #ifdef WOLFSSL_ASYNC_CRYPT
+        /* Handle async operation */
+        if (ret == WC_PENDING_E) {
+            /* Mark message as not received so it can process again */
+            ssl->msgsReceived.got_certificate_verify = 0;
+
+            return ret;
+        }
+    #endif /* WOLFSSL_ASYNC_CRYPT */
+    #ifdef WOLFSSL_EXTRA_ALERTS
+        if (ret == BUFFER_ERROR)
+            SendAlert(ssl, alert_fatal, decode_error);
+        else if (ret == SIG_VERIFY_E)
+            SendAlert(ssl, alert_fatal, decrypt_error);
+        else if (ret != 0)
+            SendAlert(ssl, alert_fatal, bad_certificate);
+    #endif
+        /* Digest is not allocated, so do this to prevent free */
+        ssl->buffers.digest.buffer = NULL;
+        ssl->buffers.digest.length = 0;
+
+        /* Final cleanup */
+        FreeDcvArgs(ssl, args);
+        FreeKeyExchange(ssl);
+
+        return ret;
+    }
+
+#endif /* (!NO_RSA || ECC || ED25519 || ED448) && !WOLFSSL_NO_CLIENT_AUTH */
+
+    /* handle generation of server_hello_done (14) */
+    int SendServerHelloDone(WOLFSSL* ssl)
+    {
+        byte* output;
+        int   sendSz = RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ;
+        int   ret;
+
+        WOLFSSL_START(WC_FUNC_SERVER_HELLO_DONE_SEND);
+        WOLFSSL_ENTER("SendServerHelloDone");
+
+    #ifdef WOLFSSL_DTLS
+        if (ssl->options.dtls)
+            sendSz += DTLS_RECORD_EXTRA + DTLS_HANDSHAKE_EXTRA;
+    #endif
+
+        if (IsEncryptionOn(ssl, 1))
+            sendSz += MAX_MSG_EXTRA;
+
+        /* check for available size */
+        if ((ret = CheckAvailableSize(ssl, sendSz)) != 0)
+            return ret;
+
+        /* get output buffer */
+        output = ssl->buffers.outputBuffer.buffer +
+                 ssl->buffers.outputBuffer.length;
+
+        AddHeaders(output, 0, server_hello_done, ssl);
+
+        if (IsEncryptionOn(ssl, 1)) {
+            byte* input;
+            int   inputSz = HANDSHAKE_HEADER_SZ; /* build msg adds rec hdr */
+
+            input = (byte*)XMALLOC(inputSz, ssl->heap, DYNAMIC_TYPE_IN_BUFFER);
+            if (input == NULL)
+                return MEMORY_E;
+
+            XMEMCPY(input, output + RECORD_HEADER_SZ, inputSz);
+            sendSz = BuildMessage(ssl, output, sendSz, input, inputSz,
+                                  handshake, 1, 0, 0);
+            XFREE(input, ssl->heap, DYNAMIC_TYPE_IN_BUFFER);
+
+            if (sendSz < 0)
+                return sendSz;
+        } else {
+            #ifdef WOLFSSL_DTLS
+                if (IsDtlsNotSctpMode(ssl)) {
+                    if ((ret = DtlsMsgPoolSave(ssl, output, sendSz)) != 0)
+                        return ret;
+                }
+                if (ssl->options.dtls)
+                    DtlsSEQIncrement(ssl, CUR_ORDER);
+            #endif
+            ret = HashOutput(ssl, output, sendSz, 0);
+            if (ret != 0)
+                return ret;
+        }
+
+    #if defined(WOLFSSL_CALLBACKS) || defined(OPENSSL_EXTRA)
+        if (ssl->hsInfoOn)
+            AddPacketName(ssl, "ServerHelloDone");
+        if (ssl->toInfoOn)
+            AddPacketInfo(ssl, "ServerHelloDone", handshake, output, sendSz,
+                    WRITE_PROTO, ssl->heap);
+    #endif
+        ssl->options.serverState = SERVER_HELLODONE_COMPLETE;
+
+        ssl->buffers.outputBuffer.length += sendSz;
+
+        ret = SendBuffered(ssl);
+
+        WOLFSSL_LEAVE("SendServerHelloDone", ret);
+        WOLFSSL_END(WC_FUNC_SERVER_HELLO_DONE_SEND);
+
+        return ret;
+    }
+
+#endif /* !WOLFSSL_NO_TLS12 */
+
+#ifdef HAVE_SESSION_TICKET
+
+#define WOLFSSL_TICKET_FIXED_SZ (WOLFSSL_TICKET_NAME_SZ + \
+                WOLFSSL_TICKET_IV_SZ + WOLFSSL_TICKET_MAC_SZ + LENGTH_SZ)
+#define WOLFSSL_TICKET_ENC_SZ (SESSION_TICKET_LEN - WOLFSSL_TICKET_FIXED_SZ)
+
+    /* our ticket format */
+    typedef struct InternalTicket {
+        ProtocolVersion pv;                    /* version when ticket created */
+        byte            suite[SUITE_LEN];      /* cipher suite when created */
+        byte            msecret[SECRET_LEN];   /* master secret */
+        word32          timestamp;             /* born on */
+        word16          haveEMS;               /* have extended master secret */
+#ifdef WOLFSSL_TLS13
+        word32          ageAdd;                /* Obfuscation of age */
+        word16          namedGroup;            /* Named group used */
+    #ifndef WOLFSSL_TLS13_DRAFT_18
+        TicketNonce     ticketNonce;           /* Ticket nonce */
+    #endif
+    #ifdef WOLFSSL_EARLY_DATA
+        word32          maxEarlyDataSz;        /* Max size of early data */
+    #endif
+#endif
+    } InternalTicket;
+
+    /* fit within SESSION_TICKET_LEN */
+    typedef struct ExternalTicket {
+        byte key_name[WOLFSSL_TICKET_NAME_SZ];  /* key context name */
+        byte iv[WOLFSSL_TICKET_IV_SZ];          /* this ticket's iv */
+        byte enc_len[LENGTH_SZ];                /* encrypted length */
+        byte enc_ticket[WOLFSSL_TICKET_ENC_SZ]; /* encrypted internal ticket */
+        byte mac[WOLFSSL_TICKET_MAC_SZ];        /* total mac */
+        /* !! if add to structure, add to TICKET_FIXED_SZ !! */
+    } ExternalTicket;
+
+    /* create a new session ticket, 0 on success */
+    int CreateTicket(WOLFSSL* ssl)
+    {
+        InternalTicket  it;
+        ExternalTicket* et = (ExternalTicket*)ssl->session.ticket;
+        int encLen;
+        int ret;
+        byte zeros[WOLFSSL_TICKET_MAC_SZ];   /* biggest cmp size */
+
+        XMEMSET(&it, 0, sizeof(it));
+
+        /* build internal */
+        it.pv.major = ssl->version.major;
+        it.pv.minor = ssl->version.minor;
+
+        it.suite[0] = ssl->options.cipherSuite0;
+        it.suite[1] = ssl->options.cipherSuite;
+
+    #ifdef WOLFSSL_EARLY_DATA
+        it.maxEarlyDataSz = ssl->options.maxEarlyDataSz;
+    #endif
+
+        if (!ssl->options.tls1_3) {
+            XMEMCPY(it.msecret, ssl->arrays->masterSecret, SECRET_LEN);
+            c32toa(LowResTimer(), (byte*)&it.timestamp);
+            it.haveEMS = ssl->options.haveEMS;
+        }
+        else {
+#ifdef WOLFSSL_TLS13
+            /* Client adds to ticket age to obfuscate. */
+            ret = wc_RNG_GenerateBlock(ssl->rng, (byte*)&it.ageAdd,
+                                                             sizeof(it.ageAdd));
+            if (ret != 0)
+                return BAD_TICKET_ENCRYPT;
+            ssl->session.ticketAdd = it.ageAdd;
+            it.namedGroup = ssl->session.namedGroup;
+            it.timestamp = TimeNowInMilliseconds();
+            /* Resumption master secret. */
+            XMEMCPY(it.msecret, ssl->session.masterSecret, SECRET_LEN);
+    #ifndef WOLFSSL_TLS13_DRAFT_18
+            XMEMCPY(&it.ticketNonce, &ssl->session.ticketNonce,
+                                                           sizeof(TicketNonce));
+    #endif
+#endif
+        }
+
+        /* build external */
+        XMEMCPY(et->enc_ticket, &it, sizeof(InternalTicket));
+
+        /* encrypt */
+        encLen = WOLFSSL_TICKET_ENC_SZ;  /* max size user can use */
+        if (ssl->ctx->ticketEncCb == NULL) {
+            ret = WOLFSSL_TICKET_RET_FATAL;
+        }
+        else {
+            ret = ssl->ctx->ticketEncCb(ssl, et->key_name, et->iv, et->mac, 1,
+                                    et->enc_ticket, sizeof(InternalTicket),
+                                    &encLen, ssl->ctx->ticketEncCtx);
+        }
+        if (ret == WOLFSSL_TICKET_RET_OK) {
+            if (encLen < (int)sizeof(InternalTicket) ||
+                encLen > WOLFSSL_TICKET_ENC_SZ) {
+                WOLFSSL_MSG("Bad user ticket encrypt size");
+                return BAD_TICKET_KEY_CB_SZ;
+            }
+
+            /* sanity checks on encrypt callback */
+
+            /* internal ticket can't be the same if encrypted */
+            if (XMEMCMP(et->enc_ticket, &it, sizeof(InternalTicket)) == 0) {
+                WOLFSSL_MSG("User ticket encrypt didn't encrypt");
+                return BAD_TICKET_ENCRYPT;
+            }
+
+            XMEMSET(zeros, 0, sizeof(zeros));
+
+            /* name */
+            if (XMEMCMP(et->key_name, zeros, WOLFSSL_TICKET_NAME_SZ) == 0) {
+                WOLFSSL_MSG("User ticket encrypt didn't set name");
+                return BAD_TICKET_ENCRYPT;
+            }
+
+            /* iv */
+            if (XMEMCMP(et->iv, zeros, WOLFSSL_TICKET_IV_SZ) == 0) {
+                WOLFSSL_MSG("User ticket encrypt didn't set iv");
+                return BAD_TICKET_ENCRYPT;
+            }
+
+            /* mac */
+            if (XMEMCMP(et->mac, zeros, WOLFSSL_TICKET_MAC_SZ) == 0) {
+                WOLFSSL_MSG("User ticket encrypt didn't set mac");
+                return BAD_TICKET_ENCRYPT;
+            }
+
+            /* set size */
+            c16toa((word16)encLen, et->enc_len);
+            ssl->session.ticketLen = (word16)(encLen + WOLFSSL_TICKET_FIXED_SZ);
+            if (encLen < WOLFSSL_TICKET_ENC_SZ) {
+                /* move mac up since whole enc buffer not used */
+                XMEMMOVE(et->enc_ticket +encLen, et->mac,WOLFSSL_TICKET_MAC_SZ);
+            }
+        }
+
+        return ret;
+    }
+
+
+    /* Parse ticket sent by client, returns callback return value */
+    int DoClientTicket(WOLFSSL* ssl, const byte* input, word32 len)
+    {
+        ExternalTicket* et;
+        InternalTicket* it;
+        int             ret;
+        int             outLen;
+        word16          inLen;
+
+        WOLFSSL_START(WC_FUNC_TICKET_DO);
+        WOLFSSL_ENTER("DoClientTicket");
+
+        if (len > SESSION_TICKET_LEN ||
+             len < (word32)(sizeof(InternalTicket) + WOLFSSL_TICKET_FIXED_SZ)) {
+            return BAD_TICKET_MSG_SZ;
+        }
+
+        et = (ExternalTicket*)input;
+        it = (InternalTicket*)et->enc_ticket;
+
+        /* decrypt */
+        ato16(et->enc_len, &inLen);
+        if (inLen > (word16)(len - WOLFSSL_TICKET_FIXED_SZ)) {
+            return BAD_TICKET_MSG_SZ;
+        }
+        outLen = inLen;   /* may be reduced by user padding */
+
+        if (ssl->ctx->ticketEncCb == NULL) {
+            ret = WOLFSSL_TICKET_RET_FATAL;
+        }
+        else {
+            ret = ssl->ctx->ticketEncCb(ssl, et->key_name, et->iv,
+                                    et->enc_ticket + inLen, 0,
+                                    et->enc_ticket, inLen, &outLen,
+                                    ssl->ctx->ticketEncCtx);
+        }
+        if (ret == WOLFSSL_TICKET_RET_FATAL || ret < 0) return ret;
+        if (outLen > (int)inLen || outLen < (int)sizeof(InternalTicket)) {
+            WOLFSSL_MSG("Bad user ticket decrypt len");
+            return BAD_TICKET_KEY_CB_SZ;
+        }
+
+        /* get master secret */
+        if (ret == WOLFSSL_TICKET_RET_OK || ret == WOLFSSL_TICKET_RET_CREATE) {
+            if (ssl->version.minor < it->pv.minor) {
+                WOLFSSL_MSG("Ticket has greater version");
+                return VERSION_ERROR;
+            }
+            else if (ssl->version.minor > it->pv.minor) {
+                if (!ssl->options.downgrade) {
+                    WOLFSSL_MSG("Ticket has lesser version");
+                    return VERSION_ERROR;
+                }
+
+                WOLFSSL_MSG("Downgrading protocol due to ticket");
+
+                if (it->pv.minor < ssl->options.minDowngrade)
+                    return VERSION_ERROR;
+                ssl->version.minor = it->pv.minor;
+            }
+
+
+            if (!IsAtLeastTLSv1_3(ssl->version)) {
+                XMEMCPY(ssl->arrays->masterSecret, it->msecret, SECRET_LEN);
+                /* Copy the haveExtendedMasterSecret property from the ticket to
+                 * the saved session, so the property may be checked later. */
+                ssl->session.haveEMS = it->haveEMS;
+            #ifndef NO_RESUME_SUITE_CHECK
+                ssl->session.cipherSuite0 = it->suite[0];
+                ssl->session.cipherSuite = it->suite[1];
+            #endif
+            }
+            else {
+#ifdef WOLFSSL_TLS13
+                /* Restore information to renegotiate. */
+                ssl->session.ticketSeen = it->timestamp;
+                ssl->session.ticketAdd = it->ageAdd;
+                ssl->session.cipherSuite0 = it->suite[0];
+                ssl->session.cipherSuite = it->suite[1];
+    #ifdef WOLFSSL_EARLY_DATA
+                ssl->session.maxEarlyDataSz = it->maxEarlyDataSz;
+    #endif
+                /* Resumption master secret. */
+                XMEMCPY(ssl->session.masterSecret, it->msecret, SECRET_LEN);
+    #ifndef WOLFSSL_TLS13_DRAFT_18
+                XMEMCPY(&ssl->session.ticketNonce, &it->ticketNonce,
+                                                           sizeof(TicketNonce));
+    #endif
+                ssl->session.namedGroup = it->namedGroup;
+#endif
+            }
+        }
+
+        WOLFSSL_LEAVE("DoClientTicket", ret);
+        WOLFSSL_END(WC_FUNC_TICKET_DO);
+
+        return ret;
+    }
+
+
+    /* send Session Ticket */
+    int SendTicket(WOLFSSL* ssl)
+    {
+        byte*              output;
+        int                ret;
+        int                sendSz;
+        word32             length = SESSION_HINT_SZ + LENGTH_SZ;
+        word32             idx    = RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ;
+
+        WOLFSSL_START(WC_FUNC_TICKET_SEND);
+        WOLFSSL_ENTER("SendTicket");
+
+        if (ssl->options.createTicket) {
+            ret = CreateTicket(ssl);
+            if (ret != 0) return ret;
+        }
+
+        length += ssl->session.ticketLen;
+        sendSz = length + HANDSHAKE_HEADER_SZ + RECORD_HEADER_SZ;
+
+        if (!ssl->options.dtls) {
+            if (IsEncryptionOn(ssl, 1) && ssl->options.handShakeDone)
+                sendSz += MAX_MSG_EXTRA;
+        }
+        else {
+        #ifdef WOLFSSL_DTLS
+            sendSz += DTLS_RECORD_EXTRA + DTLS_HANDSHAKE_EXTRA;
+            idx    += DTLS_RECORD_EXTRA + DTLS_HANDSHAKE_EXTRA;
+        #endif
+        }
+        /* check for available size */
+        if ((ret = CheckAvailableSize(ssl, sendSz)) != 0)
+            return ret;
+
+        /* get output buffer */
+        output = ssl->buffers.outputBuffer.buffer +
+                 ssl->buffers.outputBuffer.length;
+
+        AddHeaders(output, length, session_ticket, ssl);
+
+        /* hint */
+        c32toa(ssl->ctx->ticketHint, output + idx);
+        idx += SESSION_HINT_SZ;
+
+        /* length */
+        c16toa(ssl->session.ticketLen, output + idx);
+        idx += LENGTH_SZ;
+
+        /* ticket */
+        XMEMCPY(output + idx, ssl->session.ticket, ssl->session.ticketLen);
+        idx += ssl->session.ticketLen;
+
+        if (IsEncryptionOn(ssl, 1) && ssl->options.handShakeDone) {
+            byte* input;
+            int   inputSz = idx - RECORD_HEADER_SZ; /* build msg adds rec hdr */
+
+            input = (byte*)XMALLOC(inputSz, ssl->heap, DYNAMIC_TYPE_IN_BUFFER);
+            if (input == NULL)
+                return MEMORY_E;
+
+            XMEMCPY(input, output + RECORD_HEADER_SZ, inputSz);
+            sendSz = BuildMessage(ssl, output, sendSz, input, inputSz,
+                                  handshake, 1, 0, 0);
+            XFREE(input, ssl->heap, DYNAMIC_TYPE_IN_BUFFER);
+
+            if (sendSz < 0)
+                return sendSz;
+        }
+        else {
+            #ifdef WOLFSSL_DTLS
+            if (ssl->options.dtls) {
+                if ((ret = DtlsMsgPoolSave(ssl, output, sendSz)) != 0)
+                    return ret;
+
+                DtlsSEQIncrement(ssl, CUR_ORDER);
+            }
+            #endif
+            ret = HashOutput(ssl, output, sendSz, 0);
+            if (ret != 0)
+                return ret;
+        }
+
+        ssl->buffers.outputBuffer.length += sendSz;
+
+        ret = SendBuffered(ssl);
+
+        WOLFSSL_LEAVE("SendTicket", ret);
+        WOLFSSL_END(WC_FUNC_TICKET_SEND);
+
+        return ret;
+    }
+
+#endif /* HAVE_SESSION_TICKET */
+
+#ifndef WOLFSSL_NO_TLS12
+
+#if defined(HAVE_SECURE_RENEGOTIATION) && \
+    defined(HAVE_SERVER_RENEGOTIATION_INFO) && \
+    !defined(WOLFSSL_NO_SERVER)
+
+    /* handle generation of server's hello_request (0) */
+    int SendHelloRequest(WOLFSSL* ssl)
+    {
+        byte* output;
+        int sendSz = RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ;
+        int ret;
+
+        WOLFSSL_START(WC_FUNC_HELLO_REQUEST_SEND);
+        WOLFSSL_ENTER("SendHelloRequest");
+
+        if (IsEncryptionOn(ssl, 1))
+            sendSz += MAX_MSG_EXTRA;
+
+        /* check for available size */
+        if ((ret = CheckAvailableSize(ssl, sendSz)) != 0)
+            return ret;
+
+        /* get output buffer */
+        output = ssl->buffers.outputBuffer.buffer +
+                 ssl->buffers.outputBuffer.length;
+
+        AddHeaders(output, 0, hello_request, ssl);
+
+        if (IsEncryptionOn(ssl, 1)) {
+            byte* input;
+            int   inputSz = HANDSHAKE_HEADER_SZ; /* build msg adds rec hdr */
+
+            input = (byte*)XMALLOC(inputSz, ssl->heap, DYNAMIC_TYPE_IN_BUFFER);
+            if (input == NULL)
+                return MEMORY_E;
+
+            XMEMCPY(input, output + RECORD_HEADER_SZ, inputSz);
+            sendSz = BuildMessage(ssl, output, sendSz, input, inputSz,
+                                  handshake, 0, 0, 0);
+            XFREE(input, ssl->heap, DYNAMIC_TYPE_IN_BUFFER);
+
+            if (sendSz < 0)
+                return sendSz;
+        }
+
+        ssl->buffers.outputBuffer.length += sendSz;
+
+        ret = SendBuffered(ssl);
+
+        WOLFSSL_LEAVE("SendHelloRequest", ret);
+        WOLFSSL_END(WC_FUNC_HELLO_REQUEST_SEND);
+
+        return ret;
+    }
+
+#endif /* HAVE_SECURE_RENEGOTIATION && HAVE_SERVER_RENEGOTIATION_INFO */
+
+#ifdef WOLFSSL_DTLS
+    /* handle generation of DTLS hello_verify_request (3) */
+    static int SendHelloVerifyRequest(WOLFSSL* ssl,
+                                      const byte* cookie, byte cookieSz)
+    {
+        byte* output;
+        int   length = VERSION_SZ + ENUM_LEN + cookieSz;
+        int   idx    = DTLS_RECORD_HEADER_SZ + DTLS_HANDSHAKE_HEADER_SZ;
+        int   sendSz = length + idx;
+        int   ret;
+
+        /* check for available size */
+        if ((ret = CheckAvailableSize(ssl, sendSz)) != 0)
+            return ret;
+
+        /* get output buffer */
+        output = ssl->buffers.outputBuffer.buffer +
+                 ssl->buffers.outputBuffer.length;
+
+        /* Hello Verify Request should use the same sequence number as the
+         * Client Hello. */
+        ssl->keys.dtls_sequence_number_hi = ssl->keys.curSeq_hi;
+        ssl->keys.dtls_sequence_number_lo = ssl->keys.curSeq_lo;
+        AddHeaders(output, length, hello_verify_request, ssl);
+
+#ifdef OPENSSL_EXTRA
+        output[idx++] = DTLS_MAJOR;
+        output[idx++] = DTLS_MINOR;
+#else
+        output[idx++] = ssl->version.major;
+        output[idx++] = ssl->version.minor;
+#endif
+
+        output[idx++] = cookieSz;
+        if (cookie == NULL || cookieSz == 0)
+            return COOKIE_ERROR;
+
+        XMEMCPY(output + idx, cookie, cookieSz);
+
+#if defined(WOLFSSL_CALLBACKS) || defined(OPENSSL_EXTRA)
+        if (ssl->hsInfoOn)
+            AddPacketName(ssl, "HelloVerifyRequest");
+        if (ssl->toInfoOn)
+            AddPacketInfo(ssl, "HelloVerifyRequest", handshake, output,
+                          sendSz, WRITE_PROTO, ssl->heap);
+#endif
+
+        ssl->buffers.outputBuffer.length += sendSz;
+
+        return SendBuffered(ssl);
+    }
+#endif /* WOLFSSL_DTLS */
+
+    typedef struct DckeArgs {
+        byte*  output; /* not allocated */
+        word32 length;
+        word32 idx;
+        word32 begin;
+        word32 sigSz;
+    #ifndef NO_RSA
+        int    lastErr;
+    #endif
+    } DckeArgs;
+
+    static void FreeDckeArgs(WOLFSSL* ssl, void* pArgs)
+    {
+        DckeArgs* args = (DckeArgs*)pArgs;
+
+        (void)ssl;
+        (void)args;
+    }
+
+    /* handle processing client_key_exchange (16) */
+    static int DoClientKeyExchange(WOLFSSL* ssl, byte* input, word32* inOutIdx,
+                                                                    word32 size)
+    {
+        int ret;
+    #ifdef WOLFSSL_ASYNC_CRYPT
+        DckeArgs* args = (DckeArgs*)ssl->async.args;
+        typedef char args_test[sizeof(ssl->async.args) >= sizeof(*args) ? 1 : -1];
+        (void)sizeof(args_test);
+    #else
+        DckeArgs  args[1];
+    #endif
+
+        (void)size;
+        (void)input;
+
+        WOLFSSL_START(WC_FUNC_CLIENT_KEY_EXCHANGE_DO);
+        WOLFSSL_ENTER("DoClientKeyExchange");
+
+    #ifdef WOLFSSL_ASYNC_CRYPT
+        ret = wolfSSL_AsyncPop(ssl, &ssl->options.asyncState);
+        if (ret != WC_NOT_PENDING_E) {
+            /* Check for error */
+            if (ret < 0)
+                goto exit_dcke;
+        }
+        else
+    #endif /* WOLFSSL_ASYNC_CRYPT */
+        {
+            /* Reset state */
+            ret = 0;
+            ssl->options.asyncState = TLS_ASYNC_BEGIN;
+            XMEMSET(args, 0, sizeof(DckeArgs));
+            args->idx = *inOutIdx;
+            args->begin = *inOutIdx;
+        #ifdef WOLFSSL_ASYNC_CRYPT
+            ssl->async.freeArgs = FreeDckeArgs;
+        #endif
+        }
+
+        /* Do Client Key Exchange State Machine */
+        switch(ssl->options.asyncState)
+        {
+            case TLS_ASYNC_BEGIN:
+            {
+                /* Sanity checks */
+                if (ssl->options.side != WOLFSSL_SERVER_END) {
+                    WOLFSSL_MSG("Client received client keyexchange, attack?");
+                    WOLFSSL_ERROR(ssl->error = SIDE_ERROR);
+                    ERROR_OUT(WOLFSSL_FATAL_ERROR, exit_dcke);
+                }
+
+                if (ssl->options.clientState < CLIENT_HELLO_COMPLETE) {
+                    WOLFSSL_MSG("Client sending keyexchange at wrong time");
+                    SendAlert(ssl, alert_fatal, unexpected_message);
+                    ERROR_OUT(OUT_OF_ORDER_E, exit_dcke);
+                }
+
+            #ifndef NO_CERTS
+                if (ssl->options.verifyPeer && ssl->options.failNoCert) {
+                    if (!ssl->options.havePeerCert) {
+                        WOLFSSL_MSG("client didn't present peer cert");
+                        ERROR_OUT(NO_PEER_CERT, exit_dcke);
+                    }
+                }
+
+                if (ssl->options.verifyPeer && ssl->options.failNoCertxPSK) {
+                    if (!ssl->options.havePeerCert &&
+                                             !ssl->options.usingPSK_cipher) {
+                        WOLFSSL_MSG("client didn't present peer cert");
+                        return NO_PEER_CERT;
+                    }
+                }
+            #endif /* !NO_CERTS */
+
+            #if defined(WOLFSSL_CALLBACKS)
+                if (ssl->hsInfoOn) {
+                    AddPacketName(ssl, "ClientKeyExchange");
+                }
+                if (ssl->toInfoOn) {
+                    AddLateName("ClientKeyExchange", &ssl->timeoutInfo);
+                }
+            #endif
+
+                if (ssl->arrays->preMasterSecret == NULL) {
+                    ssl->arrays->preMasterSz = ENCRYPT_LEN;
+                    ssl->arrays->preMasterSecret = (byte*)XMALLOC(ENCRYPT_LEN,
+                                                ssl->heap, DYNAMIC_TYPE_SECRET);
+                    if (ssl->arrays->preMasterSecret == NULL) {
+                        ERROR_OUT(MEMORY_E, exit_dcke);
+                    }
+                    XMEMSET(ssl->arrays->preMasterSecret, 0, ENCRYPT_LEN);
+                }
+
+                switch (ssl->specs.kea) {
+                #ifndef NO_RSA
+                    case rsa_kea:
+                    {
+                        break;
+                    } /* rsa_kea */
+                #endif /* !NO_RSA */
+                #ifndef NO_PSK
+                    case psk_kea:
+                    {
+                        /* sanity check that PSK server callback has been set */
+                        if (ssl->options.server_psk_cb == NULL) {
+                           WOLFSSL_MSG("No server PSK callback set");
+                           ERROR_OUT(PSK_KEY_ERROR, exit_dcke);
+                        }
+                        break;
+                    }
+                #endif /* !NO_PSK */
+                #ifdef HAVE_NTRU
+                    case ntru_kea:
+                    {
+                        /* make sure private key exists */
+                        if (ssl->buffers.key == NULL ||
+                                            ssl->buffers.key->buffer == NULL) {
+                            ERROR_OUT(NO_PRIVATE_KEY, exit_dcke);
+                        }
+                        break;
+                    }
+                #endif /* HAVE_NTRU */
+                #if defined(HAVE_ECC) || defined(HAVE_CURVE25519) || \
+                                                          defined(HAVE_CURVE448)
+                    case ecc_diffie_hellman_kea:
+                    {
+                        break;
+                    }
+                #endif /* HAVE_ECC || HAVE_CURVE25519 || HAVE_CURVE448 */
+                #ifndef NO_DH
+                    case diffie_hellman_kea:
+                    {
+                        break;
+                    }
+                #endif /* !NO_DH */
+                #if !defined(NO_DH) && !defined(NO_PSK)
+                    case dhe_psk_kea:
+                    {
+                        /* sanity check that PSK server callback has been set */
+                        if (ssl->options.server_psk_cb == NULL) {
+                            WOLFSSL_MSG("No server PSK callback set");
+                            ERROR_OUT(PSK_KEY_ERROR, exit_dcke);
+                        }
+                        break;
+                    }
+                #endif /* !NO_DH && !NO_PSK */
+                #if (defined(HAVE_ECC) || defined(HAVE_CURVE25519) || \
+                                     defined(HAVE_CURVE448)) && !defined(NO_PSK)
+                    case ecdhe_psk_kea:
+                    {
+                        /* sanity check that PSK server callback has been set */
+                        if (ssl->options.server_psk_cb == NULL) {
+                            WOLFSSL_MSG("No server PSK callback set");
+                            ERROR_OUT(PSK_KEY_ERROR, exit_dcke);
+                        }
+                        break;
+                    }
+                #endif /* (HAVE_ECC || CURVE25519 || CURVE448) && !NO_PSK */
+                    default:
+                        WOLFSSL_MSG("Bad kea type");
+                        ret = BAD_KEA_TYPE_E;
+                } /* switch (ssl->specs.kea) */
+
+                /* Check for error */
+                if (ret != 0) {
+                    goto exit_dcke;
+                }
+
+                /* Advance state and proceed */
+                ssl->options.asyncState = TLS_ASYNC_BUILD;
+            } /* TLS_ASYNC_BEGIN */
+            FALL_THROUGH;
+
+            case TLS_ASYNC_BUILD:
+            {
+                switch (ssl->specs.kea) {
+                #ifndef NO_RSA
+                    case rsa_kea:
+                    {
+                        word16 keySz;
+
+                        ssl->buffers.keyType = rsa_sa_algo;
+                        ret = DecodePrivateKey(ssl, &keySz);
+                        if (ret != 0) {
+                            goto exit_dcke;
+                        }
+                        args->length = (word32)keySz;
+                        ssl->arrays->preMasterSz = SECRET_LEN;
+
+                        if (ssl->options.tls) {
+                            word16 check;
+
+                            if ((args->idx - args->begin) + OPAQUE16_LEN > size) {
+                                ERROR_OUT(BUFFER_ERROR, exit_dcke);
+                            }
+
+                            ato16(input + args->idx, &check);
+                            args->idx += OPAQUE16_LEN;
+
+                            if ((word32)check != args->length) {
+                                WOLFSSL_MSG("RSA explicit size doesn't match");
+                        #ifdef WOLFSSL_EXTRA_ALERTS
+                                SendAlert(ssl, alert_fatal, bad_record_mac);
+                        #endif
+                                ERROR_OUT(RSA_PRIVATE_ERROR, exit_dcke);
+                            }
+                        }
+
+                        if ((args->idx - args->begin) + args->length > size) {
+                            WOLFSSL_MSG("RSA message too big");
+                            ERROR_OUT(BUFFER_ERROR, exit_dcke);
+                        }
+
+                        /* pre-load PreMasterSecret with RNG data */
+                        ret = wc_RNG_GenerateBlock(ssl->rng,
+                            &ssl->arrays->preMasterSecret[VERSION_SZ],
+                            SECRET_LEN - VERSION_SZ);
+                        if (ret != 0) {
+                            goto exit_dcke;
+                        }
+
+                        args->output = NULL;
+                        break;
+                    } /* rsa_kea */
+                #endif /* !NO_RSA */
+                #ifndef NO_PSK
+                    case psk_kea:
+                    {
+                        byte* pms = ssl->arrays->preMasterSecret;
+                        word16 ci_sz;
+
+                        if ((args->idx - args->begin) + OPAQUE16_LEN > size) {
+                            ERROR_OUT(BUFFER_ERROR, exit_dcke);
+                        }
+
+                        ato16(input + args->idx, &ci_sz);
+                        args->idx += OPAQUE16_LEN;
+
+                        if (ci_sz > MAX_PSK_ID_LEN) {
+                            ERROR_OUT(CLIENT_ID_ERROR, exit_dcke);
+                        }
+
+                        if ((args->idx - args->begin) + ci_sz > size) {
+                            ERROR_OUT(BUFFER_ERROR, exit_dcke);
+                        }
+
+                        XMEMCPY(ssl->arrays->client_identity,
+                                                    input + args->idx, ci_sz);
+                        args->idx += ci_sz;
+
+                        ssl->arrays->client_identity[ci_sz] = '\0'; /* null term */
+                        ssl->arrays->psk_keySz = ssl->options.server_psk_cb(ssl,
+                            ssl->arrays->client_identity, ssl->arrays->psk_key,
+                            MAX_PSK_KEY_LEN);
+
+                        if (ssl->arrays->psk_keySz == 0 ||
+                                ssl->arrays->psk_keySz > MAX_PSK_KEY_LEN) {
+                            ERROR_OUT(PSK_KEY_ERROR, exit_dcke);
+                        }
+
+                        /* make psk pre master secret */
+                        /* length of key + length 0s + length of key + key */
+                        c16toa((word16) ssl->arrays->psk_keySz, pms);
+                        pms += OPAQUE16_LEN;
+
+                        XMEMSET(pms, 0, ssl->arrays->psk_keySz);
+                        pms += ssl->arrays->psk_keySz;
+
+                        c16toa((word16) ssl->arrays->psk_keySz, pms);
+                        pms += OPAQUE16_LEN;
+
+                        XMEMCPY(pms, ssl->arrays->psk_key, ssl->arrays->psk_keySz);
+                        ssl->arrays->preMasterSz =
+                            (ssl->arrays->psk_keySz * 2) + (OPAQUE16_LEN * 2);
+                        break;
+                    }
+                #endif /* !NO_PSK */
+                #ifdef HAVE_NTRU
+                    case ntru_kea:
+                    {
+                        word16 cipherLen;
+                        word16 plainLen = ENCRYPT_LEN;
+
+                        if ((args->idx - args->begin) + OPAQUE16_LEN > size) {
+                            ERROR_OUT(BUFFER_ERROR, exit_dcke);
+                        }
+
+                        ato16(input + args->idx, &cipherLen);
+                        args->idx += OPAQUE16_LEN;
+
+                        if (cipherLen > MAX_NTRU_ENCRYPT_SZ) {
+                            ERROR_OUT(NTRU_KEY_ERROR, exit_dcke);
+                        }
+
+                        if ((args->idx - args->begin) + cipherLen > size) {
+                            ERROR_OUT(BUFFER_ERROR, exit_dcke);
+                        }
+
+                        if (NTRU_OK != ntru_crypto_ntru_decrypt(
+                                    (word16) ssl->buffers.key->length,
+                                    ssl->buffers.key->buffer, cipherLen,
+                                    input + args->idx, &plainLen,
+                                    ssl->arrays->preMasterSecret)) {
+                            ERROR_OUT(NTRU_DECRYPT_ERROR, exit_dcke);
+                        }
+
+                        if (plainLen != SECRET_LEN) {
+                            ERROR_OUT(NTRU_DECRYPT_ERROR, exit_dcke);
+                        }
+
+                        args->idx += cipherLen;
+                        ssl->arrays->preMasterSz = plainLen;
+                        break;
+                    }
+                #endif /* HAVE_NTRU */
+                #if defined(HAVE_ECC) || defined(HAVE_CURVE25519) || \
+                                                          defined(HAVE_CURVE448)
+                    case ecc_diffie_hellman_kea:
+                    {
+                    #ifdef HAVE_ECC
+                        ecc_key* private_key = ssl->eccTempKey;
+
+                        /* handle static private key */
+                        if (ssl->specs.static_ecdh &&
+                                          ssl->ecdhCurveOID != ECC_X25519_OID &&
+                                          ssl->ecdhCurveOID != ECC_X448_OID) {
+                            word16 keySz;
+
+                            ssl->buffers.keyType = ecc_dsa_sa_algo;
+                            ret = DecodePrivateKey(ssl, &keySz);
+                            if (ret != 0) {
+                                goto exit_dcke;
+                            }
+                            private_key = (ecc_key*)ssl->hsKey;
+                        }
+                    #endif
+
+                        /* import peer ECC key */
+                        if ((args->idx - args->begin) + OPAQUE8_LEN > size) {
+                        #ifdef WOLFSSL_EXTRA_ALERTS
+                            SendAlert(ssl, alert_fatal, decode_error);
+                        #endif
+                            ERROR_OUT(BUFFER_ERROR, exit_dcke);
+                        }
+
+                        args->length = input[args->idx++];
+
+                        if ((args->idx - args->begin) + args->length > size) {
+                        #ifdef WOLFSSL_EXTRA_ALERTS
+                            SendAlert(ssl, alert_fatal, decode_error);
+                        #endif
+                            ERROR_OUT(BUFFER_ERROR, exit_dcke);
+                        }
+
+                    #ifdef HAVE_CURVE25519
+                        if (ssl->ecdhCurveOID == ECC_X25519_OID) {
+                        #ifdef HAVE_PK_CALLBACKS
+                            /* if callback then use it for shared secret */
+                            if (ssl->ctx->X25519SharedSecretCb != NULL) {
+                                break;
+                            }
+                        #endif
+                            if (ssl->peerX25519Key == NULL) {
+                                /* alloc/init on demand */
+                                ret = AllocKey(ssl, DYNAMIC_TYPE_CURVE25519,
+                                    (void**)&ssl->peerX25519Key);
+                                if (ret != 0) {
+                                    goto exit_dcke;
+                                }
+                            } else if (ssl->peerX25519KeyPresent) {
+                                ret = ReuseKey(ssl, DYNAMIC_TYPE_CURVE25519,
+                                               ssl->peerX25519Key);
+                                ssl->peerX25519KeyPresent = 0;
+                                if (ret != 0) {
+                                    goto exit_dcke;
+                                }
+                            }
+
+                            if ((ret = wc_curve25519_check_public(
+                                    input + args->idx, args->length,
+                                    EC25519_LITTLE_ENDIAN)) != 0) {
+                        #ifdef WOLFSSL_EXTRA_ALERTS
+                                if (ret == BUFFER_E)
+                                    SendAlert(ssl, alert_fatal, decode_error);
+                                else if (ret == ECC_OUT_OF_RANGE_E)
+                                    SendAlert(ssl, alert_fatal, bad_record_mac);
+                                else {
+                                    SendAlert(ssl, alert_fatal,
+                                                             illegal_parameter);
+                                }
+                        #endif
+                                ERROR_OUT(ECC_PEERKEY_ERROR, exit_dcke);
+                            }
+
+                            if (wc_curve25519_import_public_ex(
+                                    input + args->idx, args->length,
+                                    ssl->peerX25519Key,
+                                    EC25519_LITTLE_ENDIAN)) {
+                        #ifdef WOLFSSL_EXTRA_ALERTS
+                                SendAlert(ssl, alert_fatal, illegal_parameter);
+                        #endif
+                                ERROR_OUT(ECC_PEERKEY_ERROR, exit_dcke);
+                            }
+
+                            ssl->arrays->preMasterSz = CURVE25519_KEYSIZE;
+
+                            ssl->peerX25519KeyPresent = 1;
+
+                            break;
+                        }
+                    #endif
+                    #ifdef HAVE_CURVE448
+                        if (ssl->ecdhCurveOID == ECC_X448_OID) {
+                        #ifdef HAVE_PK_CALLBACKS
+                            /* if callback then use it for shared secret */
+                            if (ssl->ctx->X448SharedSecretCb != NULL) {
+                                break;
+                            }
+                        #endif
+                            if (ssl->peerX448Key == NULL) {
+                                /* alloc/init on demand */
+                                ret = AllocKey(ssl, DYNAMIC_TYPE_CURVE448,
+                                    (void**)&ssl->peerX448Key);
+                                if (ret != 0) {
+                                    goto exit_dcke;
+                                }
+                            } else if (ssl->peerX448KeyPresent) {
+                                ret = ReuseKey(ssl, DYNAMIC_TYPE_CURVE448,
+                                               ssl->peerX448Key);
+                                ssl->peerX448KeyPresent = 0;
+                                if (ret != 0) {
+                                    goto exit_dcke;
+                                }
+                            }
+
+                            if ((ret = wc_curve448_check_public(
+                                    input + args->idx, args->length,
+                                    EC448_LITTLE_ENDIAN)) != 0) {
+                        #ifdef WOLFSSL_EXTRA_ALERTS
+                                if (ret == BUFFER_E)
+                                    SendAlert(ssl, alert_fatal, decode_error);
+                                else if (ret == ECC_OUT_OF_RANGE_E)
+                                    SendAlert(ssl, alert_fatal, bad_record_mac);
+                                else {
+                                    SendAlert(ssl, alert_fatal,
+                                                             illegal_parameter);
+                                }
+                        #endif
+                                ERROR_OUT(ECC_PEERKEY_ERROR, exit_dcke);
+                            }
+
+                            if (wc_curve448_import_public_ex(
+                                    input + args->idx, args->length,
+                                    ssl->peerX448Key,
+                                    EC448_LITTLE_ENDIAN)) {
+                        #ifdef WOLFSSL_EXTRA_ALERTS
+                                SendAlert(ssl, alert_fatal, illegal_parameter);
+                        #endif
+                                ERROR_OUT(ECC_PEERKEY_ERROR, exit_dcke);
+                            }
+
+                            ssl->arrays->preMasterSz = CURVE448_KEY_SIZE;
+
+                            ssl->peerX448KeyPresent = 1;
+
+                            break;
+                        }
+                    #endif
+                #ifdef HAVE_ECC
+                    #ifdef HAVE_PK_CALLBACKS
+                        /* if callback then use it for shared secret */
+                        if (ssl->ctx->EccSharedSecretCb != NULL) {
+                            break;
+                        }
+                    #endif
+
+                        if (!ssl->specs.static_ecdh &&
+                            ssl->eccTempKeyPresent == 0) {
+                            WOLFSSL_MSG("Ecc ephemeral key not made correctly");
+                            ERROR_OUT(ECC_MAKEKEY_ERROR, exit_dcke);
+                        }
+
+                        if (ssl->peerEccKey == NULL) {
+                            /* alloc/init on demand */
+                            ret = AllocKey(ssl, DYNAMIC_TYPE_ECC,
+                                (void**)&ssl->peerEccKey);
+                            if (ret != 0) {
+                                goto exit_dcke;
+                            }
+                        } else if (ssl->peerEccKeyPresent) {
+                            ret = ReuseKey(ssl, DYNAMIC_TYPE_ECC,
+                                           ssl->peerEccKey);
+                            ssl->peerEccKeyPresent = 0;
+                            if (ret != 0) {
+                                goto exit_dcke;
+                            }
+                        }
+
+                        if (wc_ecc_import_x963_ex(input + args->idx,
+                                                  args->length, ssl->peerEccKey,
+                                                  private_key->dp->id)) {
+                        #ifdef WOLFSSL_EXTRA_ALERTS
+                            SendAlert(ssl, alert_fatal, illegal_parameter);
+                        #endif
+                            ERROR_OUT(ECC_PEERKEY_ERROR, exit_dcke);
+                        }
+
+                        ssl->arrays->preMasterSz = private_key->dp->size;
+
+                        ssl->peerEccKeyPresent = 1;
+                #endif /* HAVE_ECC */
+
+                        break;
+                    }
+                #endif /* HAVE_ECC || HAVE_CURVE25519 || HAVE_CURVE448 */
+                #ifndef NO_DH
+                    case diffie_hellman_kea:
+                    {
+                        word16 clientPubSz;
+
+                        if ((args->idx - args->begin) + OPAQUE16_LEN > size) {
+                            ERROR_OUT(BUFFER_ERROR, exit_dcke);
+                        }
+
+                        ato16(input + args->idx, &clientPubSz);
+                        args->idx += OPAQUE16_LEN;
+
+                        if ((args->idx - args->begin) + clientPubSz > size) {
+                        #ifdef WOLFSSL_EXTRA_ALERTS
+                            SendAlert(ssl, alert_fatal, decode_error);
+                        #endif
+                            ERROR_OUT(BUFFER_ERROR, exit_dcke);
+                        }
+
+                        args->sigSz = clientPubSz;
+
+                        ret = AllocKey(ssl, DYNAMIC_TYPE_DH,
+                                            (void**)&ssl->buffers.serverDH_Key);
+                        if (ret != 0) {
+                            goto exit_dcke;
+                        }
+
+                        ret = wc_DhSetKey(ssl->buffers.serverDH_Key,
+                            ssl->buffers.serverDH_P.buffer,
+                            ssl->buffers.serverDH_P.length,
+                            ssl->buffers.serverDH_G.buffer,
+                            ssl->buffers.serverDH_G.length);
+
+                        /* set the max agree result size */
+                        ssl->arrays->preMasterSz = ENCRYPT_LEN;
+                        break;
+                    }
+                #endif /* !NO_DH */
+                #if !defined(NO_DH) && !defined(NO_PSK)
+                    case dhe_psk_kea:
+                    {
+                        word16 clientSz;
+
+                        /* Read in the PSK hint */
+                        if ((args->idx - args->begin) + OPAQUE16_LEN > size) {
+                            ERROR_OUT(BUFFER_ERROR, exit_dcke);
+                        }
+
+                        ato16(input + args->idx, &clientSz);
+                        args->idx += OPAQUE16_LEN;
+                        if (clientSz > MAX_PSK_ID_LEN) {
+                            ERROR_OUT(CLIENT_ID_ERROR, exit_dcke);
+                        }
+
+                        if ((args->idx - args->begin) + clientSz > size) {
+                            ERROR_OUT(BUFFER_ERROR, exit_dcke);
+                        }
+
+                        XMEMCPY(ssl->arrays->client_identity, input + args->idx,
+                                                                    clientSz);
+                        args->idx += clientSz;
+                        ssl->arrays->client_identity[clientSz] = '\0'; /* null term */
+
+                        /* Read in the DHE business */
+                        if ((args->idx - args->begin) + OPAQUE16_LEN > size) {
+                            ERROR_OUT(BUFFER_ERROR, exit_dcke);
+                        }
+
+                        ato16(input + args->idx, &clientSz);
+                        args->idx += OPAQUE16_LEN;
+
+                        if ((args->idx - args->begin) + clientSz > size) {
+                            ERROR_OUT(BUFFER_ERROR, exit_dcke);
+                        }
+
+                        args->sigSz = clientSz;
+
+                        ret = AllocKey(ssl, DYNAMIC_TYPE_DH,
+                                            (void**)&ssl->buffers.serverDH_Key);
+                        if (ret != 0) {
+                            goto exit_dcke;
+                        }
+
+                        ret = wc_DhSetKey(ssl->buffers.serverDH_Key,
+                            ssl->buffers.serverDH_P.buffer,
+                            ssl->buffers.serverDH_P.length,
+                            ssl->buffers.serverDH_G.buffer,
+                            ssl->buffers.serverDH_G.length);
+
+                        break;
+                    }
+                #endif /* !NO_DH && !NO_PSK */
+                #if (defined(HAVE_ECC) || defined(HAVE_CURVE25519) || \
+                                     defined(HAVE_CURVE448)) && !defined(NO_PSK)
+                    case ecdhe_psk_kea:
+                    {
+                        word16 clientSz;
+
+                        /* Read in the PSK hint */
+                        if ((args->idx - args->begin) + OPAQUE16_LEN > size) {
+                            ERROR_OUT(BUFFER_ERROR, exit_dcke);
+                        }
+
+                        ato16(input + args->idx, &clientSz);
+                        args->idx += OPAQUE16_LEN;
+                        if (clientSz > MAX_PSK_ID_LEN) {
+                            ERROR_OUT(CLIENT_ID_ERROR, exit_dcke);
+                        }
+                        if ((args->idx - args->begin) + clientSz > size) {
+                            ERROR_OUT(BUFFER_ERROR, exit_dcke);
+                        }
+
+                        XMEMCPY(ssl->arrays->client_identity,
+                                                   input + args->idx, clientSz);
+                        args->idx += clientSz;
+                        ssl->arrays->client_identity[clientSz] = '\0'; /* null term */
+
+                        /* import peer ECC key */
+                        if ((args->idx - args->begin) + OPAQUE8_LEN > size) {
+                            ERROR_OUT(BUFFER_ERROR, exit_dcke);
+                        }
+
+                        args->length = input[args->idx++];
+
+                        if ((args->idx - args->begin) + args->length > size) {
+                            ERROR_OUT(BUFFER_ERROR, exit_dcke);
+                        }
+
+                        args->sigSz = ENCRYPT_LEN - OPAQUE16_LEN;
+
+                    #ifdef HAVE_CURVE25519
+                        if (ssl->ecdhCurveOID == ECC_X25519_OID) {
+                        #ifdef HAVE_PK_CALLBACKS
+                            /* if callback then use it for shared secret */
+                            if (ssl->ctx->X25519SharedSecretCb != NULL) {
+                                break;
+                            }
+                        #endif
+
+                            if (ssl->eccTempKeyPresent == 0) {
+                                WOLFSSL_MSG(
+                                     "X25519 ephemeral key not made correctly");
+                                ERROR_OUT(ECC_MAKEKEY_ERROR, exit_dcke);
+                            }
+
+                            if (ssl->peerX25519Key == NULL) {
+                                /* alloc/init on demand */
+                                ret = AllocKey(ssl, DYNAMIC_TYPE_CURVE25519,
+                                    (void**)&ssl->peerX25519Key);
+                                if (ret != 0) {
+                                    goto exit_dcke;
+                                }
+                            } else if (ssl->peerX25519KeyPresent) {
+                                ret = ReuseKey(ssl, DYNAMIC_TYPE_CURVE25519,
+                                               ssl->peerX25519Key);
+                                ssl->peerX25519KeyPresent = 0;
+                                if (ret != 0) {
+                                    goto exit_dcke;
+                                }
+                            }
+
+                            if ((ret = wc_curve25519_check_public(
+                                    input + args->idx, args->length,
+                                    EC25519_LITTLE_ENDIAN)) != 0) {
+                        #ifdef WOLFSSL_EXTRA_ALERTS
+                                if (ret == BUFFER_E)
+                                    SendAlert(ssl, alert_fatal, decode_error);
+                                else if (ret == ECC_OUT_OF_RANGE_E)
+                                    SendAlert(ssl, alert_fatal, bad_record_mac);
+                                else {
+                                    SendAlert(ssl, alert_fatal,
+                                                             illegal_parameter);
+                                }
+                        #endif
+                                ERROR_OUT(ECC_PEERKEY_ERROR, exit_dcke);
+                            }
+
+                            if (wc_curve25519_import_public_ex(
+                                    input + args->idx, args->length,
+                                    ssl->peerX25519Key,
+                                    EC25519_LITTLE_ENDIAN)) {
+                                ERROR_OUT(ECC_PEERKEY_ERROR, exit_dcke);
+                            }
+
+                            ssl->peerX25519KeyPresent = 1;
+
+                            break;
+                        }
+                    #endif
+                    #ifdef HAVE_CURVE448
+                        if (ssl->ecdhCurveOID == ECC_X448_OID) {
+                        #ifdef HAVE_PK_CALLBACKS
+                            /* if callback then use it for shared secret */
+                            if (ssl->ctx->X448SharedSecretCb != NULL) {
+                                break;
+                            }
+                        #endif
+
+                            if (ssl->eccTempKeyPresent == 0) {
+                                WOLFSSL_MSG(
+                                       "X448 ephemeral key not made correctly");
+                                ERROR_OUT(ECC_MAKEKEY_ERROR, exit_dcke);
+                            }
+
+                            if (ssl->peerX448Key == NULL) {
+                                /* alloc/init on demand */
+                                ret = AllocKey(ssl, DYNAMIC_TYPE_CURVE448,
+                                    (void**)&ssl->peerX448Key);
+                                if (ret != 0) {
+                                    goto exit_dcke;
+                                }
+                            } else if (ssl->peerX448KeyPresent) {
+                                ret = ReuseKey(ssl, DYNAMIC_TYPE_CURVE448,
+                                               ssl->peerX448Key);
+                                ssl->peerX448KeyPresent = 0;
+                                if (ret != 0) {
+                                    goto exit_dcke;
+                                }
+                            }
+
+                            if ((ret = wc_curve448_check_public(
+                                    input + args->idx, args->length,
+                                    EC448_LITTLE_ENDIAN)) != 0) {
+                        #ifdef WOLFSSL_EXTRA_ALERTS
+                                if (ret == BUFFER_E)
+                                    SendAlert(ssl, alert_fatal, decode_error);
+                                else if (ret == ECC_OUT_OF_RANGE_E)
+                                    SendAlert(ssl, alert_fatal, bad_record_mac);
+                                else {
+                                    SendAlert(ssl, alert_fatal,
+                                                             illegal_parameter);
+                                }
+                        #endif
+                                ERROR_OUT(ECC_PEERKEY_ERROR, exit_dcke);
+                            }
+
+                            if (wc_curve448_import_public_ex(
+                                    input + args->idx, args->length,
+                                    ssl->peerX448Key,
+                                    EC448_LITTLE_ENDIAN)) {
+                                ERROR_OUT(ECC_PEERKEY_ERROR, exit_dcke);
+                            }
+
+                            ssl->peerX448KeyPresent = 1;
+
+                            break;
+                        }
+                    #endif
+                    #ifdef HAVE_PK_CALLBACKS
+                        /* if callback then use it for shared secret */
+                        if (ssl->ctx->EccSharedSecretCb != NULL) {
+                            break;
+                        }
+                    #endif
+
+                        if (ssl->eccTempKeyPresent == 0) {
+                            WOLFSSL_MSG("Ecc ephemeral key not made correctly");
+                            ERROR_OUT(ECC_MAKEKEY_ERROR, exit_dcke);
+                        }
+
+                        if (ssl->peerEccKey == NULL) {
+                            /* alloc/init on demand */
+                            ret = AllocKey(ssl, DYNAMIC_TYPE_ECC,
+                                (void**)&ssl->peerEccKey);
+                            if (ret != 0) {
+                                goto exit_dcke;
+                            }
+                        }
+                        else if (ssl->peerEccKeyPresent) {
+                            ret = ReuseKey(ssl, DYNAMIC_TYPE_ECC,
+                                           ssl->peerEccKey);
+                            ssl->peerEccKeyPresent = 0;
+                            if (ret != 0) {
+                                goto exit_dcke;
+                            }
+                        }
+                        if (wc_ecc_import_x963_ex(input + args->idx,
+                                 args->length, ssl->peerEccKey,
+                                 ssl->eccTempKey->dp->id)) {
+                            ERROR_OUT(ECC_PEERKEY_ERROR, exit_dcke);
+                        }
+
+                        ssl->peerEccKeyPresent = 1;
+                        break;
+                    }
+                #endif /* (HAVE_ECC || CURVE25519 || CURVE448) && !NO_PSK */
+                    default:
+                        ret = BAD_KEA_TYPE_E;
+                } /* switch (ssl->specs.kea) */
+
+                /* Check for error */
+                if (ret != 0) {
+                    goto exit_dcke;
+                }
+
+                /* Advance state and proceed */
+                ssl->options.asyncState = TLS_ASYNC_DO;
+            } /* TLS_ASYNC_BUILD */
+            FALL_THROUGH;
+
+            case TLS_ASYNC_DO:
+            {
+                switch (ssl->specs.kea) {
+                #ifndef NO_RSA
+                    case rsa_kea:
+                    {
+                        RsaKey* key = (RsaKey*)ssl->hsKey;
+
+                        ret = RsaDec(ssl,
+                            input + args->idx,
+                            args->length,
+                            &args->output,
+                            &args->sigSz,
+                            key,
+                        #ifdef HAVE_PK_CALLBACKS
+                            ssl->buffers.key
+                        #else
+                            NULL
+                        #endif
+                        );
+
+                        /*  Errors that can occur here that should be
+                         *  indistinguishable:
+                         *       RSA_BUFFER_E, RSA_PAD_E and RSA_PRIVATE_ERROR
+                         */
+                    #ifdef WOLFSSL_ASYNC_CRYPT
+                        if (ret == WC_PENDING_E)
+                            goto exit_dcke;
+                    #endif
+                        if (ret == BAD_FUNC_ARG)
+                            goto exit_dcke;
+
+                        args->lastErr = ret - (SECRET_LEN - args->sigSz);
+                        ret = 0;
+                        break;
+                    } /* rsa_kea */
+                #endif /* !NO_RSA */
+                #ifndef NO_PSK
+                    case psk_kea:
+                    {
+                        break;
+                    }
+                #endif /* !NO_PSK */
+                #ifdef HAVE_NTRU
+                    case ntru_kea:
+                    {
+                        break;
+                    }
+                #endif /* HAVE_NTRU */
+                #if defined(HAVE_ECC) || defined(HAVE_CURVE25519) || \
+                                                          defined(HAVE_CURVE448)
+                    case ecc_diffie_hellman_kea:
+                    {
+                        void* private_key = ssl->eccTempKey;
+                        (void)private_key;
+
+                    #ifdef HAVE_CURVE25519
+                        if (ssl->ecdhCurveOID == ECC_X25519_OID) {
+                            ret = X25519SharedSecret(ssl,
+                                (curve25519_key*)private_key,
+                                ssl->peerX25519Key,
+                                input + args->idx, &args->length,
+                                ssl->arrays->preMasterSecret,
+                                &ssl->arrays->preMasterSz,
+                                WOLFSSL_SERVER_END
+                            );
+                            break;
+                        }
+                    #endif
+                    #ifdef HAVE_CURVE448
+                        if (ssl->ecdhCurveOID == ECC_X448_OID) {
+                            ret = X448SharedSecret(ssl,
+                                (curve448_key*)private_key,
+                                ssl->peerX448Key,
+                                input + args->idx, &args->length,
+                                ssl->arrays->preMasterSecret,
+                                &ssl->arrays->preMasterSz,
+                                WOLFSSL_SERVER_END
+                            );
+                            break;
+                        }
+                    #endif
+                    #ifdef HAVE_ECC
+                        if (ssl->specs.static_ecdh) {
+                            private_key = ssl->hsKey;
+                        }
+
+                        /* Generate shared secret */
+                        ret = EccSharedSecret(ssl,
+                            (ecc_key*)private_key, ssl->peerEccKey,
+                            input + args->idx, &args->length,
+                            ssl->arrays->preMasterSecret,
+                            &ssl->arrays->preMasterSz,
+                            WOLFSSL_SERVER_END
+                        );
+                    #ifdef WOLFSSL_ASYNC_CRYPT
+                        if (ret != WC_PENDING_E)
+                    #endif
+                        {
+                            FreeKey(ssl, DYNAMIC_TYPE_ECC,
+                                                      (void**)&ssl->peerEccKey);
+                            ssl->peerEccKeyPresent = 0;
+                        }
+                    #endif
+                        break;
+                    }
+                #endif /* HAVE_ECC || HAVE_CURVE25519 || HAVE_CURVE448 */
+                #ifndef NO_DH
+                    case diffie_hellman_kea:
+                    {
+                        ret = DhAgree(ssl, ssl->buffers.serverDH_Key,
+                            ssl->buffers.serverDH_Priv.buffer,
+                            ssl->buffers.serverDH_Priv.length,
+                            input + args->idx,
+                            (word16)args->sigSz,
+                            ssl->arrays->preMasterSecret,
+                            &ssl->arrays->preMasterSz);
+                        break;
+                    }
+                #endif /* !NO_DH */
+                #if !defined(NO_DH) && !defined(NO_PSK)
+                    case dhe_psk_kea:
+                    {
+                        ret = DhAgree(ssl, ssl->buffers.serverDH_Key,
+                            ssl->buffers.serverDH_Priv.buffer,
+                            ssl->buffers.serverDH_Priv.length,
+                            input + args->idx,
+                            (word16)args->sigSz,
+                            ssl->arrays->preMasterSecret + OPAQUE16_LEN,
+                            &ssl->arrays->preMasterSz);
+                        break;
+                    }
+                #endif /* !NO_DH && !NO_PSK */
+                #if (defined(HAVE_ECC) || defined(HAVE_CURVE25519) || \
+                                     defined(HAVE_CURVE448)) && !defined(NO_PSK)
+                    case ecdhe_psk_kea:
+                    {
+                    #ifdef HAVE_CURVE25519
+                        if (ssl->ecdhCurveOID == ECC_X25519_OID) {
+                            ret = X25519SharedSecret(ssl,
+                                (curve25519_key*)ssl->eccTempKey,
+                                ssl->peerX25519Key,
+                                input + args->idx, &args->length,
+                                ssl->arrays->preMasterSecret + OPAQUE16_LEN,
+                                &args->sigSz,
+                                WOLFSSL_SERVER_END
+                            );
+                        #ifdef WOLFSSL_ASYNC_CRYPT
+                            if (ret != WC_PENDING_E)
+                        #endif
+                            {
+                                FreeKey(ssl, DYNAMIC_TYPE_CURVE25519,
+                                                   (void**)&ssl->peerX25519Key);
+                                ssl->peerX25519KeyPresent = 0;
+                            }
+                            break;
+                        }
+                    #endif
+                    #ifdef HAVE_CURVE448
+                        if (ssl->ecdhCurveOID == ECC_X448_OID) {
+                            ret = X448SharedSecret(ssl,
+                                (curve448_key*)ssl->eccTempKey,
+                                ssl->peerX448Key,
+                                input + args->idx, &args->length,
+                                ssl->arrays->preMasterSecret + OPAQUE16_LEN,
+                                &args->sigSz,
+                                WOLFSSL_SERVER_END
+                            );
+                        #ifdef WOLFSSL_ASYNC_CRYPT
+                            if (ret != WC_PENDING_E)
+                        #endif
+                            {
+                                FreeKey(ssl, DYNAMIC_TYPE_CURVE448,
+                                                     (void**)&ssl->peerX448Key);
+                                ssl->peerX448KeyPresent = 0;
+                            }
+                            break;
+                        }
+                    #endif
+                        /* Generate shared secret */
+                        ret = EccSharedSecret(ssl,
+                            ssl->eccTempKey, ssl->peerEccKey,
+                            input + args->idx, &args->length,
+                            ssl->arrays->preMasterSecret + OPAQUE16_LEN,
+                            &args->sigSz,
+                            WOLFSSL_SERVER_END
+                        );
+                        if (!ssl->specs.static_ecdh
+                    #ifdef WOLFSSL_ASYNC_CRYPT
+                            && ret != WC_PENDING_E
+                    #endif
+                        ) {
+                            FreeKey(ssl, DYNAMIC_TYPE_ECC,
+                                                      (void**)&ssl->peerEccKey);
+                            ssl->peerEccKeyPresent = 0;
+                        }
+                        break;
+                    }
+                #endif /* (HAVE_ECC || CURVE25519 || CURVE448) && !NO_PSK */
+                    default:
+                        ret = BAD_KEA_TYPE_E;
+                } /* switch (ssl->specs.kea) */
+
+                /* Check for error */
+                if (ret != 0) {
+                    goto exit_dcke;
+                }
+
+                /* Advance state and proceed */
+                ssl->options.asyncState = TLS_ASYNC_VERIFY;
+            } /* TLS_ASYNC_DO */
+            FALL_THROUGH;
+
+            case TLS_ASYNC_VERIFY:
+            {
+                switch (ssl->specs.kea) {
+                #ifndef NO_RSA
+                    case rsa_kea:
+                    {
+                        byte mask;
+                        int i;
+
+                        /* Add the signature length to idx */
+                        args->idx += args->length;
+
+                    #ifdef DEBUG_WOLFSSL
+                        /* check version (debug warning message only) */
+                        if (args->output != NULL) {
+                            if (args->output[0] != ssl->chVersion.major ||
+                                args->output[1] != ssl->chVersion.minor) {
+                                WOLFSSL_MSG("preMasterSecret version mismatch");
+                            }
+                        }
+                    #endif
+
+                        /* RFC5246 7.4.7.1:
+                         * Treat incorrectly formatted message blocks and/or
+                         * mismatched version numbers in a manner
+                         * indistinguishable from correctly formatted RSA blocks
+                         */
+
+                        ret = args->lastErr;
+                        args->lastErr = 0; /* reset */
+                        /* On error 'ret' will be negative - top bit set */
+                        mask = ((unsigned int)ret >>
+                                                   ((sizeof(ret) * 8) - 1)) - 1;
+
+                        /* build PreMasterSecret */
+                        ssl->arrays->preMasterSecret[0] = ssl->chVersion.major;
+                        ssl->arrays->preMasterSecret[1] = ssl->chVersion.minor;
+
+                        if (args->output != NULL) {
+                            /* Use random secret on error */
+                            for (i = VERSION_SZ; i < SECRET_LEN; i++) {
+                                ssl->arrays->preMasterSecret[i] =
+                                     ctMaskSel(mask, args->output[i],
+                                               ssl->arrays->preMasterSecret[i]);
+                            }
+                        }
+                        /* preMasterSecret has RNG and version set
+                         * return proper length and ignore error
+                         * error will be caught as decryption error
+                         */
+                        args->sigSz = SECRET_LEN;
+                        ret = 0;
+                        break;
+                    } /* rsa_kea */
+                #endif /* !NO_RSA */
+                #ifndef NO_PSK
+                    case psk_kea:
+                    {
+                        break;
+                    }
+                #endif /* !NO_PSK */
+                #ifdef HAVE_NTRU
+                    case ntru_kea:
+                    {
+                        break;
+                    }
+                #endif /* HAVE_NTRU */
+                #if defined(HAVE_ECC) || defined(HAVE_CURVE25519) || \
+                                                          defined(HAVE_CURVE448)
+                    case ecc_diffie_hellman_kea:
+                    {
+                        /* skip past the imported peer key */
+                        args->idx += args->length;
+                        break;
+                    }
+                #endif /* HAVE_ECC || HAVE_CURVE25519 || HAVE_CURVE448 */
+                #ifndef NO_DH
+                    case diffie_hellman_kea:
+                    {
+                        args->idx += (word16)args->sigSz;
+                        break;
+                    }
+                #endif /* !NO_DH */
+                #if !defined(NO_DH) && !defined(NO_PSK)
+                    case dhe_psk_kea:
+                    {
+                        byte* pms = ssl->arrays->preMasterSecret;
+                        word16 clientSz = (word16)args->sigSz;
+
+                        args->idx += clientSz;
+                        c16toa((word16)ssl->arrays->preMasterSz, pms);
+                        ssl->arrays->preMasterSz += OPAQUE16_LEN;
+                        pms += ssl->arrays->preMasterSz;
+
+                        /* Use the PSK hint to look up the PSK and add it to the
+                         * preMasterSecret here. */
+                        ssl->arrays->psk_keySz = ssl->options.server_psk_cb(ssl,
+                            ssl->arrays->client_identity, ssl->arrays->psk_key,
+                            MAX_PSK_KEY_LEN);
+
+                        if (ssl->arrays->psk_keySz == 0 ||
+                                ssl->arrays->psk_keySz > MAX_PSK_KEY_LEN) {
+                            ERROR_OUT(PSK_KEY_ERROR, exit_dcke);
+                        }
+
+                        c16toa((word16) ssl->arrays->psk_keySz, pms);
+                        pms += OPAQUE16_LEN;
+
+                        XMEMCPY(pms, ssl->arrays->psk_key,
+                                                    ssl->arrays->psk_keySz);
+                        ssl->arrays->preMasterSz += ssl->arrays->psk_keySz +
+                                                                OPAQUE16_LEN;
+                        break;
+                    }
+                #endif /* !NO_DH && !NO_PSK */
+                #if (defined(HAVE_ECC) || defined(HAVE_CURVE25519) || \
+                                     defined(HAVE_CURVE448)) && !defined(NO_PSK)
+                    case ecdhe_psk_kea:
+                    {
+                        byte* pms = ssl->arrays->preMasterSecret;
+                        word16 clientSz = (word16)args->sigSz;
+
+                        /* skip past the imported peer key */
+                        args->idx += args->length;
+
+                        /* Add preMasterSecret */
+                        c16toa(clientSz, pms);
+                        ssl->arrays->preMasterSz = OPAQUE16_LEN + clientSz;
+                        pms += ssl->arrays->preMasterSz;
+
+                        /* Use the PSK hint to look up the PSK and add it to the
+                         * preMasterSecret here. */
+                        ssl->arrays->psk_keySz = ssl->options.server_psk_cb(ssl,
+                            ssl->arrays->client_identity, ssl->arrays->psk_key,
+                            MAX_PSK_KEY_LEN);
+
+                        if (ssl->arrays->psk_keySz == 0 ||
+                                   ssl->arrays->psk_keySz > MAX_PSK_KEY_LEN) {
+                            ERROR_OUT(PSK_KEY_ERROR, exit_dcke);
+                        }
+
+                        c16toa((word16) ssl->arrays->psk_keySz, pms);
+                        pms += OPAQUE16_LEN;
+
+                        XMEMCPY(pms, ssl->arrays->psk_key, ssl->arrays->psk_keySz);
+                        ssl->arrays->preMasterSz +=
+                                      ssl->arrays->psk_keySz + OPAQUE16_LEN;
+                        break;
+                    }
+                #endif /* (HAVE_ECC || CURVE25519 || CURVE448) && !NO_PSK */
+                    default:
+                        ret = BAD_KEA_TYPE_E;
+                } /* switch (ssl->specs.kea) */
+
+                /* Check for error */
+                if (ret != 0) {
+                    goto exit_dcke;
+                }
+
+                /* Advance state and proceed */
+                ssl->options.asyncState = TLS_ASYNC_FINALIZE;
+            } /* TLS_ASYNC_VERIFY */
+            FALL_THROUGH;
+
+            case TLS_ASYNC_FINALIZE:
+            {
+                if (IsEncryptionOn(ssl, 0)) {
+                    args->idx += ssl->keys.padSz;
+            #if defined(HAVE_ENCRYPT_THEN_MAC) && !defined(WOLFSSL_AEAD_ONLY)
+                    if (ssl->options.startedETMRead)
+                        args->idx += MacSize(ssl);
+            #endif
+                }
+
+            #ifdef HAVE_QSH
+                word16 name;
+
+                if (ssl->options.haveQSH) {
+                    /* extension name */
+                    ato16(input + args->idx, &name);
+                    args->idx += OPAQUE16_LEN;
+
+                    if (name == TLSX_QUANTUM_SAFE_HYBRID) {
+                        int    qshSz;
+                        /* if qshSz is larger than 0 it is the
+                           length of buffer used */
+                        if ((qshSz = TLSX_QSHCipher_Parse(ssl,
+                                input + args->idx,
+                                size - args->idx + args->begin, 1)) < 0) {
+                            ERROR_OUT(qshSz, exit_dcke);
+                        }
+                        args->idx += qshSz;
+                    }
+                    else {
+                        /* unknown extension sent client ignored handshake */
+                        ERROR_OUT(BUFFER_ERROR, exit_dcke);
+                    }
+                }
+            #endif /* HAVE_QSH */
+                ret = MakeMasterSecret(ssl);
+
+                /* Check for error */
+                if (ret != 0) {
+                    goto exit_dcke;
+                }
+
+                /* Advance state and proceed */
+                ssl->options.asyncState = TLS_ASYNC_END;
+            } /* TLS_ASYNC_FINALIZE */
+            FALL_THROUGH;
+
+            case TLS_ASYNC_END:
+            {
+                /* Set final index */
+                *inOutIdx = args->idx;
+
+                ssl->options.clientState = CLIENT_KEYEXCHANGE_COMPLETE;
+            #ifndef NO_CERTS
+                if (ssl->options.verifyPeer) {
+                    ret = BuildCertHashes(ssl, &ssl->hsHashes->certHashes);
+                }
+            #endif
+                break;
+            } /* TLS_ASYNC_END */
+            default:
+                ret = INPUT_CASE_ERROR;
+        } /* switch(ssl->options.asyncState) */
+
+    exit_dcke:
+
+        WOLFSSL_LEAVE("DoClientKeyExchange", ret);
+        WOLFSSL_END(WC_FUNC_CLIENT_KEY_EXCHANGE_DO);
+
+    #ifdef WOLFSSL_ASYNC_CRYPT
+        /* Handle async operation */
+        if (ret == WC_PENDING_E) {
+            /* Mark message as not received so it can process again */
+            ssl->msgsReceived.got_client_key_exchange = 0;
+
+            return ret;
+        }
+    #endif /* WOLFSSL_ASYNC_CRYPT */
+
+        /* Cleanup PMS */
+        if (ssl->arrays->preMasterSecret != NULL) {
+            ForceZero(ssl->arrays->preMasterSecret, ssl->arrays->preMasterSz);
+        }
+        ssl->arrays->preMasterSz = 0;
+
+        /* Final cleanup */
+        FreeDckeArgs(ssl, args);
+        FreeKeyExchange(ssl);
+
+        return ret;
+    }
+
+#endif /* !WOLFSSL_NO_TLS12 */
+
+#if defined(OPENSSL_ALL) || defined(HAVE_STUNNEL) || defined(WOLFSSL_NGINX) || \
+    defined(WOLFSSL_HAPROXY)
+    int SNI_Callback(WOLFSSL* ssl)
+    {
+        /* Stunnel supports a custom sni callback to switch an SSL's ctx
+        * when SNI is received. Call it now if exists */
+        if(ssl && ssl->ctx && ssl->ctx->sniRecvCb) {
+            WOLFSSL_MSG("Calling custom sni callback");
+            if(ssl->ctx->sniRecvCb(ssl, NULL, ssl->ctx->sniRecvCbArg)
+                    == alert_fatal) {
+                WOLFSSL_MSG("Error in custom sni callback. Fatal alert");
+                SendAlert(ssl, alert_fatal, unrecognized_name);
+                return FATAL_ERROR;
+            }
+        }
+        return 0;
+    }
+#endif /* OPENSSL_ALL || HAVE_STUNNEL || WOLFSSL_NGINX || WOLFSSL_HAPROXY */
+
+#endif /* NO_WOLFSSL_SERVER */
+
+
+#ifdef WOLFSSL_ASYNC_CRYPT
+int wolfSSL_AsyncPop(WOLFSSL* ssl, byte* state)
+{
+    int ret = 0;
+    WC_ASYNC_DEV* asyncDev;
+    WOLF_EVENT* event;
+
+    if (ssl == NULL) {
+        return BAD_FUNC_ARG;
+    }
+
+    /* check for pending async */
+    asyncDev = ssl->async.dev;
+    if (asyncDev) {
+        /* grab event pointer */
+        event = &asyncDev->event;
+
+        ret = wolfAsync_EventPop(event, WOLF_EVENT_TYPE_ASYNC_WOLFSSL);
+        if (ret != WC_NOT_PENDING_E && ret != WC_PENDING_E) {
+
+            /* advance key share state if doesn't need called again */
+            if (state && (asyncDev->event.flags & WC_ASYNC_FLAG_CALL_AGAIN) == 0) {
+                (*state)++;
+            }
+
+            /* clear event */
+            XMEMSET(&asyncDev->event, 0, sizeof(WOLF_EVENT));
+
+            /* clear async dev */
+            ssl->async.dev = NULL;
+        }
+    }
+    else {
+        ret = WC_NOT_PENDING_E;
+    }
+
+    WOLFSSL_LEAVE("wolfSSL_AsyncPop", ret);
+
+    return ret;
+}
+
+int wolfSSL_AsyncInit(WOLFSSL* ssl, WC_ASYNC_DEV* asyncDev, word32 flags)
+{
+    int ret;
+    WOLF_EVENT* event;
+
+    if (ssl == NULL || asyncDev == NULL) {
+        return BAD_FUNC_ARG;
+    }
+
+    /* grab event pointer */
+    event = &asyncDev->event;
+
+    /* init event */
+    ret = wolfAsync_EventInit(event, WOLF_EVENT_TYPE_ASYNC_WOLFSSL, ssl, flags);
+
+    WOLFSSL_LEAVE("wolfSSL_AsyncInit", ret);
+
+    return ret;
+}
+
+int wolfSSL_AsyncPush(WOLFSSL* ssl, WC_ASYNC_DEV* asyncDev)
+{
+    int ret;
+    WOLF_EVENT* event;
+
+    if (ssl == NULL || asyncDev == NULL) {
+        return BAD_FUNC_ARG;
+    }
+
+    /* grab event pointer */
+    event = &asyncDev->event;
+
+    /* store reference to active async operation */
+    ssl->async.dev = asyncDev;
+
+    /* place event into queue */
+    ret = wolfAsync_EventQueuePush(&ssl->ctx->event_queue, event);
+
+    /* success means return WC_PENDING_E */
+    if (ret == 0) {
+        ret = WC_PENDING_E;
+    }
+
+    WOLFSSL_LEAVE("wolfSSL_AsyncPush", ret);
+
+    return ret;
+}
+
+#endif /* WOLFSSL_ASYNC_CRYPT */
+
+
+/* return the max record size */
+int wolfSSL_GetMaxRecordSize(WOLFSSL* ssl, int maxFragment)
+{
+    (void) ssl; /* Avoid compiler warnings */
+
+    if (maxFragment > MAX_RECORD_SIZE) {
+        maxFragment = MAX_RECORD_SIZE;
+    }
+
+#ifdef HAVE_MAX_FRAGMENT
+    if ((ssl->max_fragment != 0) && ((word16)maxFragment > ssl->max_fragment)) {
+        maxFragment = ssl->max_fragment;
+    }
+#endif /* HAVE_MAX_FRAGMENT */
+#ifdef WOLFSSL_DTLS
+    if ((ssl->options.dtls) && (maxFragment > MAX_UDP_SIZE)) {
+        maxFragment = MAX_UDP_SIZE;
+    }
+#endif
+
+    return maxFragment;
+}
+
+
+#undef ERROR_OUT
+
+#endif /* WOLFCRYPT_ONLY */
Index: azure_iot_hub_f767zi/trunk/wolfssl-4.4.0/src/keys.c
===================================================================
--- azure_iot_hub_f767zi/trunk/wolfssl-4.4.0/src/keys.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/wolfssl-4.4.0/src/keys.c	(revision 457)
@@ -0,0 +1,3607 @@
+/* keys.c
+ *
+ * Copyright (C) 2006-2020 wolfSSL Inc.
+ *
+ * This file is part of wolfSSL.
+ *
+ * wolfSSL is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * wolfSSL is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
+ */
+
+
+/* Name change compatibility layer no longer needs to be included here */
+
+#ifdef HAVE_CONFIG_H
+    #include <config.h>
+#endif
+
+#include <wolfssl/wolfcrypt/settings.h>
+
+#ifndef WOLFCRYPT_ONLY
+
+#include <wolfssl/internal.h>
+#include <wolfssl/error-ssl.h>
+#if defined(SHOW_SECRETS) || defined(CHACHA_AEAD_TEST)
+    #ifndef NO_STDIO_FILESYSTEM
+        #include <stdio.h>
+    #endif
+#endif
+
+#if defined(WOLFSSL_RENESAS_TSIP_TLS) && \
+    !defined(NO_WOLFSSL_RENESAS_TSIP_TLS_SESSION)
+ int tsip_useable(const WOLFSSL *ssl);
+#endif
+int SetCipherSpecs(WOLFSSL* ssl)
+{
+#ifndef NO_WOLFSSL_CLIENT
+    if (ssl->options.side == WOLFSSL_CLIENT_END) {
+        /* server side verified before SetCipherSpecs call */
+        if (VerifyClientSuite(ssl) != 1) {
+            WOLFSSL_MSG("SetCipherSpecs() client has an unusable suite");
+            return UNSUPPORTED_SUITE;
+        }
+    }
+#endif /* NO_WOLFSSL_CLIENT */
+
+    /* Chacha extensions, 0xcc */
+    if (ssl->options.cipherSuite0 == CHACHA_BYTE) {
+
+    switch (ssl->options.cipherSuite) {
+#ifdef BUILD_TLS_ECDHE_RSA_WITH_CHACHA20_OLD_POLY1305_SHA256
+    case TLS_ECDHE_RSA_WITH_CHACHA20_OLD_POLY1305_SHA256:
+        ssl->specs.bulk_cipher_algorithm = wolfssl_chacha;
+        ssl->specs.cipher_type           = aead;
+        ssl->specs.mac_algorithm         = sha256_mac;
+        ssl->specs.kea                   = ecc_diffie_hellman_kea;
+        ssl->specs.sig_algo              = rsa_sa_algo;
+        ssl->specs.hash_size             = WC_SHA256_DIGEST_SIZE;
+        ssl->specs.pad_size              = PAD_SHA;
+        ssl->specs.static_ecdh           = 0;
+        ssl->specs.key_size              = CHACHA20_256_KEY_SIZE;
+        ssl->specs.block_size            = CHACHA20_BLOCK_SIZE;
+        ssl->specs.iv_size               = CHACHA20_IV_SIZE;
+        ssl->specs.aead_mac_size         = POLY1305_AUTH_SZ;
+        ssl->options.oldPoly             = 1; /* use old poly1305 padding */
+
+        break;
+#endif
+
+#ifdef BUILD_TLS_ECDHE_ECDSA_WITH_CHACHA20_OLD_POLY1305_SHA256
+    case TLS_ECDHE_ECDSA_WITH_CHACHA20_OLD_POLY1305_SHA256:
+        ssl->specs.bulk_cipher_algorithm = wolfssl_chacha;
+        ssl->specs.cipher_type           = aead;
+        ssl->specs.mac_algorithm         = sha256_mac;
+        ssl->specs.kea                   = ecc_diffie_hellman_kea;
+        ssl->specs.sig_algo              = ecc_dsa_sa_algo;
+        ssl->specs.hash_size             = WC_SHA256_DIGEST_SIZE;
+        ssl->specs.pad_size              = PAD_SHA;
+        ssl->specs.static_ecdh           = 0;
+        ssl->specs.key_size              = CHACHA20_256_KEY_SIZE;
+        ssl->specs.block_size            = CHACHA20_BLOCK_SIZE;
+        ssl->specs.iv_size               = CHACHA20_IV_SIZE;
+        ssl->specs.aead_mac_size         = POLY1305_AUTH_SZ;
+        ssl->options.oldPoly             = 1; /* use old poly1305 padding */
+
+        break;
+#endif
+
+#ifdef BUILD_TLS_DHE_RSA_WITH_CHACHA20_OLD_POLY1305_SHA256
+    case TLS_DHE_RSA_WITH_CHACHA20_OLD_POLY1305_SHA256:
+        ssl->specs.bulk_cipher_algorithm = wolfssl_chacha;
+        ssl->specs.cipher_type           = aead;
+        ssl->specs.mac_algorithm         = sha256_mac;
+        ssl->specs.kea                   = diffie_hellman_kea;
+        ssl->specs.sig_algo              = rsa_sa_algo;
+        ssl->specs.hash_size             = WC_SHA256_DIGEST_SIZE;
+        ssl->specs.pad_size              = PAD_SHA;
+        ssl->specs.static_ecdh           = 0;
+        ssl->specs.key_size              = CHACHA20_256_KEY_SIZE;
+        ssl->specs.block_size            = CHACHA20_BLOCK_SIZE;
+        ssl->specs.iv_size               = CHACHA20_IV_SIZE;
+        ssl->specs.aead_mac_size         = POLY1305_AUTH_SZ;
+        ssl->options.oldPoly             = 1; /* use old poly1305 padding */
+
+        break;
+#endif
+#ifdef BUILD_TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256
+    case TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256:
+        ssl->specs.bulk_cipher_algorithm = wolfssl_chacha;
+        ssl->specs.cipher_type           = aead;
+        ssl->specs.mac_algorithm         = sha256_mac;
+        ssl->specs.kea                   = ecc_diffie_hellman_kea;
+        ssl->specs.sig_algo              = rsa_sa_algo;
+        ssl->specs.hash_size             = WC_SHA256_DIGEST_SIZE;
+        ssl->specs.pad_size              = PAD_SHA;
+        ssl->specs.static_ecdh           = 0;
+        ssl->specs.key_size              = CHACHA20_256_KEY_SIZE;
+        ssl->specs.block_size            = CHACHA20_BLOCK_SIZE;
+        ssl->specs.iv_size               = CHACHA20_IV_SIZE;
+        ssl->specs.aead_mac_size         = POLY1305_AUTH_SZ;
+        ssl->options.oldPoly             = 0; /* use recent padding RFC */
+
+        break;
+#endif
+
+#ifdef BUILD_TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256
+    case TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256:
+        ssl->specs.bulk_cipher_algorithm = wolfssl_chacha;
+        ssl->specs.cipher_type           = aead;
+        ssl->specs.mac_algorithm         = sha256_mac;
+        ssl->specs.kea                   = ecc_diffie_hellman_kea;
+        ssl->specs.sig_algo              = ecc_dsa_sa_algo;
+        ssl->specs.hash_size             = WC_SHA256_DIGEST_SIZE;
+        ssl->specs.pad_size              = PAD_SHA;
+        ssl->specs.static_ecdh           = 0;
+        ssl->specs.key_size              = CHACHA20_256_KEY_SIZE;
+        ssl->specs.block_size            = CHACHA20_BLOCK_SIZE;
+        ssl->specs.iv_size               = CHACHA20_IV_SIZE;
+        ssl->specs.aead_mac_size         = POLY1305_AUTH_SZ;
+        ssl->options.oldPoly             = 0; /* use recent padding RFC */
+
+        break;
+#endif
+
+#ifdef BUILD_TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256
+    case TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256:
+        ssl->specs.bulk_cipher_algorithm = wolfssl_chacha;
+        ssl->specs.cipher_type           = aead;
+        ssl->specs.mac_algorithm         = sha256_mac;
+        ssl->specs.kea                   = diffie_hellman_kea;
+        ssl->specs.sig_algo              = rsa_sa_algo;
+        ssl->specs.hash_size             = WC_SHA256_DIGEST_SIZE;
+        ssl->specs.pad_size              = PAD_SHA;
+        ssl->specs.static_ecdh           = 0;
+        ssl->specs.key_size              = CHACHA20_256_KEY_SIZE;
+        ssl->specs.block_size            = CHACHA20_BLOCK_SIZE;
+        ssl->specs.iv_size               = CHACHA20_IV_SIZE;
+        ssl->specs.aead_mac_size         = POLY1305_AUTH_SZ;
+        ssl->options.oldPoly             = 0; /* use recent padding RFC */
+
+        break;
+#endif
+
+#ifdef BUILD_TLS_PSK_WITH_CHACHA20_POLY1305_SHA256
+    case TLS_PSK_WITH_CHACHA20_POLY1305_SHA256:
+        ssl->specs.bulk_cipher_algorithm = wolfssl_chacha;
+        ssl->specs.cipher_type           = aead;
+        ssl->specs.mac_algorithm         = sha256_mac;
+        ssl->specs.kea                   = psk_kea;
+        ssl->specs.sig_algo              = anonymous_sa_algo;
+        ssl->specs.hash_size             = WC_SHA256_DIGEST_SIZE;
+        ssl->specs.pad_size              = PAD_SHA;
+        ssl->specs.static_ecdh           = 0;
+        ssl->specs.key_size              = CHACHA20_256_KEY_SIZE;
+        ssl->specs.block_size            = CHACHA20_BLOCK_SIZE;
+        ssl->specs.iv_size               = CHACHA20_IV_SIZE;
+        ssl->specs.aead_mac_size         = POLY1305_AUTH_SZ;
+
+        ssl->options.oldPoly             = 0; /* use recent padding RFC */
+        ssl->options.usingPSK_cipher     = 1;
+        break;
+#endif
+
+#ifdef BUILD_TLS_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256
+    case TLS_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256:
+        ssl->specs.bulk_cipher_algorithm = wolfssl_chacha;
+        ssl->specs.cipher_type           = aead;
+        ssl->specs.mac_algorithm         = sha256_mac;
+        ssl->specs.kea                   = ecdhe_psk_kea;
+        ssl->specs.sig_algo              = anonymous_sa_algo;
+        ssl->specs.hash_size             = WC_SHA256_DIGEST_SIZE;
+        ssl->specs.pad_size              = PAD_SHA;
+        ssl->specs.static_ecdh           = 0;
+        ssl->specs.key_size              = CHACHA20_256_KEY_SIZE;
+        ssl->specs.block_size            = CHACHA20_BLOCK_SIZE;
+        ssl->specs.iv_size               = CHACHA20_IV_SIZE;
+        ssl->specs.aead_mac_size         = POLY1305_AUTH_SZ;
+
+        ssl->options.oldPoly             = 0; /* use recent padding RFC */
+        ssl->options.usingPSK_cipher     = 1;
+        break;
+#endif
+
+#ifdef BUILD_TLS_DHE_PSK_WITH_CHACHA20_POLY1305_SHA256
+    case TLS_DHE_PSK_WITH_CHACHA20_POLY1305_SHA256:
+        ssl->specs.bulk_cipher_algorithm = wolfssl_chacha;
+        ssl->specs.cipher_type           = aead;
+        ssl->specs.mac_algorithm         = sha256_mac;
+        ssl->specs.kea                   = dhe_psk_kea;
+        ssl->specs.sig_algo              = anonymous_sa_algo;
+        ssl->specs.hash_size             = WC_SHA256_DIGEST_SIZE;
+        ssl->specs.pad_size              = PAD_SHA;
+        ssl->specs.static_ecdh           = 0;
+        ssl->specs.key_size              = CHACHA20_256_KEY_SIZE;
+        ssl->specs.block_size            = CHACHA20_BLOCK_SIZE;
+        ssl->specs.iv_size               = CHACHA20_IV_SIZE;
+        ssl->specs.aead_mac_size         = POLY1305_AUTH_SZ;
+
+        ssl->options.oldPoly             = 0; /* use recent padding RFC */
+        ssl->options.usingPSK_cipher     = 1;
+        break;
+#endif
+    default:
+        WOLFSSL_MSG("Unsupported cipher suite, SetCipherSpecs ChaCha");
+        return UNSUPPORTED_SUITE;
+    }
+    }
+
+    /* ECC extensions, AES-CCM or TLS 1.3 Integrity-only */
+    if (ssl->options.cipherSuite0 == ECC_BYTE) {
+
+    switch (ssl->options.cipherSuite) {
+
+#if defined(HAVE_ECC) || defined(HAVE_CURVE25519) || defined(HAVE_CURVE448)
+
+#ifdef BUILD_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256
+    case TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 :
+        ssl->specs.bulk_cipher_algorithm = wolfssl_aes;
+        ssl->specs.cipher_type           = block;
+        ssl->specs.mac_algorithm         = sha256_mac;
+        ssl->specs.kea                   = ecc_diffie_hellman_kea;
+        ssl->specs.sig_algo              = rsa_sa_algo;
+        ssl->specs.hash_size             = WC_SHA256_DIGEST_SIZE;
+        ssl->specs.pad_size              = PAD_SHA;
+        ssl->specs.static_ecdh           = 0;
+        ssl->specs.key_size              = AES_128_KEY_SIZE;
+        ssl->specs.iv_size               = AES_IV_SIZE;
+        ssl->specs.block_size            = AES_BLOCK_SIZE;
+
+        break;
+#endif
+
+#ifdef BUILD_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384
+    case TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 :
+        ssl->specs.bulk_cipher_algorithm = wolfssl_aes;
+        ssl->specs.cipher_type           = block;
+        ssl->specs.mac_algorithm         = sha384_mac;
+        ssl->specs.kea                   = ecc_diffie_hellman_kea;
+        ssl->specs.sig_algo              = rsa_sa_algo;
+        ssl->specs.hash_size             = WC_SHA384_DIGEST_SIZE;
+        ssl->specs.pad_size              = PAD_SHA;
+        ssl->specs.static_ecdh           = 0;
+        ssl->specs.key_size              = AES_256_KEY_SIZE;
+        ssl->specs.iv_size               = AES_IV_SIZE;
+        ssl->specs.block_size            = AES_BLOCK_SIZE;
+
+        break;
+#endif
+
+#ifdef BUILD_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA
+    case TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA :
+        ssl->specs.bulk_cipher_algorithm = wolfssl_aes;
+        ssl->specs.cipher_type           = block;
+        ssl->specs.mac_algorithm         = sha_mac;
+        ssl->specs.kea                   = ecc_diffie_hellman_kea;
+        ssl->specs.sig_algo              = rsa_sa_algo;
+        ssl->specs.hash_size             = WC_SHA_DIGEST_SIZE;
+        ssl->specs.pad_size              = PAD_SHA;
+        ssl->specs.static_ecdh           = 0;
+        ssl->specs.key_size              = AES_128_KEY_SIZE;
+        ssl->specs.block_size            = AES_BLOCK_SIZE;
+        ssl->specs.iv_size               = AES_IV_SIZE;
+
+        break;
+#endif
+
+#ifdef BUILD_TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA
+    case TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA :
+        ssl->specs.bulk_cipher_algorithm = wolfssl_triple_des;
+        ssl->specs.cipher_type           = block;
+        ssl->specs.mac_algorithm         = sha_mac;
+        ssl->specs.kea                   = ecc_diffie_hellman_kea;
+        ssl->specs.sig_algo              = rsa_sa_algo;
+        ssl->specs.hash_size             = WC_SHA_DIGEST_SIZE;
+        ssl->specs.pad_size              = PAD_SHA;
+        ssl->specs.static_ecdh           = 0;
+        ssl->specs.key_size              = DES3_KEY_SIZE;
+        ssl->specs.block_size            = DES_BLOCK_SIZE;
+        ssl->specs.iv_size               = DES_IV_SIZE;
+
+        break;
+#endif
+
+#ifdef BUILD_TLS_ECDHE_RSA_WITH_RC4_128_SHA
+    case TLS_ECDHE_RSA_WITH_RC4_128_SHA :
+        ssl->specs.bulk_cipher_algorithm = wolfssl_rc4;
+        ssl->specs.cipher_type           = stream;
+        ssl->specs.mac_algorithm         = sha_mac;
+        ssl->specs.kea                   = ecc_diffie_hellman_kea;
+        ssl->specs.sig_algo              = rsa_sa_algo;
+        ssl->specs.hash_size             = WC_SHA_DIGEST_SIZE;
+        ssl->specs.pad_size              = PAD_SHA;
+        ssl->specs.static_ecdh           = 0;
+        ssl->specs.key_size              = RC4_KEY_SIZE;
+        ssl->specs.iv_size               = 0;
+        ssl->specs.block_size            = 0;
+
+        break;
+#endif
+
+#ifdef BUILD_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA
+    case TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA :
+        ssl->specs.bulk_cipher_algorithm = wolfssl_aes;
+        ssl->specs.cipher_type           = block;
+        ssl->specs.mac_algorithm         = sha_mac;
+        ssl->specs.kea                   = ecc_diffie_hellman_kea;
+        ssl->specs.sig_algo              = rsa_sa_algo;
+        ssl->specs.hash_size             = WC_SHA_DIGEST_SIZE;
+        ssl->specs.pad_size              = PAD_SHA;
+        ssl->specs.static_ecdh           = 0;
+        ssl->specs.key_size              = AES_256_KEY_SIZE;
+        ssl->specs.block_size            = AES_BLOCK_SIZE;
+        ssl->specs.iv_size               = AES_IV_SIZE;
+
+        break;
+#endif
+
+#ifdef BUILD_TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
+    case TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 :
+        ssl->specs.bulk_cipher_algorithm = wolfssl_aes_gcm;
+        ssl->specs.cipher_type           = aead;
+        ssl->specs.mac_algorithm         = sha256_mac;
+        ssl->specs.kea                   = ecc_diffie_hellman_kea;
+        ssl->specs.sig_algo              = rsa_sa_algo;
+        ssl->specs.hash_size             = WC_SHA256_DIGEST_SIZE;
+        ssl->specs.pad_size              = PAD_SHA;
+        ssl->specs.static_ecdh           = 0;
+        ssl->specs.key_size              = AES_128_KEY_SIZE;
+        ssl->specs.block_size            = AES_BLOCK_SIZE;
+        ssl->specs.iv_size               = AESGCM_IMP_IV_SZ;
+        ssl->specs.aead_mac_size         = AES_GCM_AUTH_SZ;
+
+        break;
+#endif
+
+#ifdef BUILD_TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
+    case TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 :
+        ssl->specs.bulk_cipher_algorithm = wolfssl_aes_gcm;
+        ssl->specs.cipher_type           = aead;
+        ssl->specs.mac_algorithm         = sha384_mac;
+        ssl->specs.kea                   = ecc_diffie_hellman_kea;
+        ssl->specs.sig_algo              = rsa_sa_algo;
+        ssl->specs.hash_size             = WC_SHA384_DIGEST_SIZE;
+        ssl->specs.pad_size              = PAD_SHA;
+        ssl->specs.static_ecdh           = 0;
+        ssl->specs.key_size              = AES_256_KEY_SIZE;
+        ssl->specs.block_size            = AES_BLOCK_SIZE;
+        ssl->specs.iv_size               = AESGCM_IMP_IV_SZ;
+        ssl->specs.aead_mac_size         = AES_GCM_AUTH_SZ;
+
+        break;
+#endif
+
+#ifdef BUILD_TLS_ECDHE_PSK_WITH_NULL_SHA256
+    case TLS_ECDHE_PSK_WITH_NULL_SHA256 :
+        ssl->specs.bulk_cipher_algorithm = wolfssl_cipher_null;
+        ssl->specs.cipher_type           = stream;
+        ssl->specs.mac_algorithm         = sha256_mac;
+        ssl->specs.kea                   = ecdhe_psk_kea;
+        ssl->specs.sig_algo              = anonymous_sa_algo;
+        ssl->specs.hash_size             = WC_SHA256_DIGEST_SIZE;
+        ssl->specs.pad_size              = PAD_SHA;
+        ssl->specs.static_ecdh           = 0;
+        ssl->specs.key_size              = 0;
+        ssl->specs.block_size            = 0;
+        ssl->specs.iv_size               = 0;
+
+        ssl->options.usingPSK_cipher     = 1;
+        break;
+#endif
+
+#ifdef BUILD_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256
+    case TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256 :
+        ssl->specs.bulk_cipher_algorithm = wolfssl_aes;
+        ssl->specs.cipher_type           = block;
+        ssl->specs.mac_algorithm         = sha256_mac;
+        ssl->specs.kea                   = ecdhe_psk_kea;
+        ssl->specs.sig_algo              = anonymous_sa_algo;
+        ssl->specs.hash_size             = WC_SHA256_DIGEST_SIZE;
+        ssl->specs.pad_size              = PAD_SHA;
+        ssl->specs.static_ecdh           = 0;
+        ssl->specs.key_size              = AES_128_KEY_SIZE;
+        ssl->specs.block_size            = AES_BLOCK_SIZE;
+        ssl->specs.iv_size               = AES_IV_SIZE;
+
+        ssl->options.usingPSK_cipher     = 1;
+        break;
+#endif
+
+#endif /* HAVE_ECC || HAVE_CURVE25519 || HAVE_CURVE448 */
+
+#if defined(HAVE_ECC) || (defined(HAVE_CURVE25519) && defined(HAVE_ED25519)) \
+                      || (defined(HAVE_CURVE448) && defined(HAVE_ED448))
+
+#ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256
+    case TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 :
+        ssl->specs.bulk_cipher_algorithm = wolfssl_aes;
+        ssl->specs.cipher_type           = block;
+        ssl->specs.mac_algorithm         = sha256_mac;
+        ssl->specs.kea                   = ecc_diffie_hellman_kea;
+        ssl->specs.sig_algo              = ecc_dsa_sa_algo;
+        ssl->specs.hash_size             = WC_SHA256_DIGEST_SIZE;
+        ssl->specs.pad_size              = PAD_SHA;
+        ssl->specs.static_ecdh           = 0;
+        ssl->specs.key_size              = AES_128_KEY_SIZE;
+        ssl->specs.iv_size               = AES_IV_SIZE;
+        ssl->specs.block_size            = AES_BLOCK_SIZE;
+
+        break;
+#endif
+
+#ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384
+    case TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 :
+        ssl->specs.bulk_cipher_algorithm = wolfssl_aes;
+        ssl->specs.cipher_type           = block;
+        ssl->specs.mac_algorithm         = sha384_mac;
+        ssl->specs.kea                   = ecc_diffie_hellman_kea;
+        ssl->specs.sig_algo              = ecc_dsa_sa_algo;
+        ssl->specs.hash_size             = WC_SHA384_DIGEST_SIZE;
+        ssl->specs.pad_size              = PAD_SHA;
+        ssl->specs.static_ecdh           = 0;
+        ssl->specs.key_size              = AES_256_KEY_SIZE;
+        ssl->specs.iv_size               = AES_IV_SIZE;
+        ssl->specs.block_size            = AES_BLOCK_SIZE;
+
+        break;
+#endif
+
+#ifdef BUILD_TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA
+    case TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA :
+        ssl->specs.bulk_cipher_algorithm = wolfssl_triple_des;
+        ssl->specs.cipher_type           = block;
+        ssl->specs.mac_algorithm         = sha_mac;
+        ssl->specs.kea                   = ecc_diffie_hellman_kea;
+        ssl->specs.sig_algo              = ecc_dsa_sa_algo;
+        ssl->specs.hash_size             = WC_SHA_DIGEST_SIZE;
+        ssl->specs.pad_size              = PAD_SHA;
+        ssl->specs.static_ecdh           = 0;
+        ssl->specs.key_size              = DES3_KEY_SIZE;
+        ssl->specs.block_size            = DES_BLOCK_SIZE;
+        ssl->specs.iv_size               = DES_IV_SIZE;
+
+        break;
+#endif
+
+#ifdef BUILD_TLS_ECDHE_ECDSA_WITH_RC4_128_SHA
+    case TLS_ECDHE_ECDSA_WITH_RC4_128_SHA :
+        ssl->specs.bulk_cipher_algorithm = wolfssl_rc4;
+        ssl->specs.cipher_type           = stream;
+        ssl->specs.mac_algorithm         = sha_mac;
+        ssl->specs.kea                   = ecc_diffie_hellman_kea;
+        ssl->specs.sig_algo              = ecc_dsa_sa_algo;
+        ssl->specs.hash_size             = WC_SHA_DIGEST_SIZE;
+        ssl->specs.pad_size              = PAD_SHA;
+        ssl->specs.static_ecdh           = 0;
+        ssl->specs.key_size              = RC4_KEY_SIZE;
+        ssl->specs.iv_size               = 0;
+        ssl->specs.block_size            = 0;
+
+        break;
+#endif
+
+#ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA
+    case TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA :
+        ssl->specs.bulk_cipher_algorithm = wolfssl_aes;
+        ssl->specs.cipher_type           = block;
+        ssl->specs.mac_algorithm         = sha_mac;
+        ssl->specs.kea                   = ecc_diffie_hellman_kea;
+        ssl->specs.sig_algo              = ecc_dsa_sa_algo;
+        ssl->specs.hash_size             = WC_SHA_DIGEST_SIZE;
+        ssl->specs.pad_size              = PAD_SHA;
+        ssl->specs.static_ecdh           = 0;
+        ssl->specs.key_size              = AES_128_KEY_SIZE;
+        ssl->specs.block_size            = AES_BLOCK_SIZE;
+        ssl->specs.iv_size               = AES_IV_SIZE;
+
+        break;
+#endif
+
+#ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA
+    case TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA :
+        ssl->specs.bulk_cipher_algorithm = wolfssl_aes;
+        ssl->specs.cipher_type           = block;
+        ssl->specs.mac_algorithm         = sha_mac;
+        ssl->specs.kea                   = ecc_diffie_hellman_kea;
+        ssl->specs.sig_algo              = ecc_dsa_sa_algo;
+        ssl->specs.hash_size             = WC_SHA_DIGEST_SIZE;
+        ssl->specs.pad_size              = PAD_SHA;
+        ssl->specs.static_ecdh           = 0;
+        ssl->specs.key_size              = AES_256_KEY_SIZE;
+        ssl->specs.block_size            = AES_BLOCK_SIZE;
+        ssl->specs.iv_size               = AES_IV_SIZE;
+
+        break;
+#endif
+
+#ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
+    case TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 :
+        ssl->specs.bulk_cipher_algorithm = wolfssl_aes_gcm;
+        ssl->specs.cipher_type           = aead;
+        ssl->specs.mac_algorithm         = sha256_mac;
+        ssl->specs.kea                   = ecc_diffie_hellman_kea;
+        ssl->specs.sig_algo              = ecc_dsa_sa_algo;
+        ssl->specs.hash_size             = WC_SHA256_DIGEST_SIZE;
+        ssl->specs.pad_size              = PAD_SHA;
+        ssl->specs.static_ecdh           = 0;
+        ssl->specs.key_size              = AES_128_KEY_SIZE;
+        ssl->specs.block_size            = AES_BLOCK_SIZE;
+        ssl->specs.iv_size               = AESGCM_IMP_IV_SZ;
+        ssl->specs.aead_mac_size         = AES_GCM_AUTH_SZ;
+
+        break;
+#endif
+
+#ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384
+    case TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 :
+        ssl->specs.bulk_cipher_algorithm = wolfssl_aes_gcm;
+        ssl->specs.cipher_type           = aead;
+        ssl->specs.mac_algorithm         = sha384_mac;
+        ssl->specs.kea                   = ecc_diffie_hellman_kea;
+        ssl->specs.sig_algo              = ecc_dsa_sa_algo;
+        ssl->specs.hash_size             = WC_SHA384_DIGEST_SIZE;
+        ssl->specs.pad_size              = PAD_SHA;
+        ssl->specs.static_ecdh           = 0;
+        ssl->specs.key_size              = AES_256_KEY_SIZE;
+        ssl->specs.block_size            = AES_BLOCK_SIZE;
+        ssl->specs.iv_size               = AESGCM_IMP_IV_SZ;
+        ssl->specs.aead_mac_size         = AES_GCM_AUTH_SZ;
+
+        break;
+#endif
+
+#ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_128_CCM
+    case TLS_ECDHE_ECDSA_WITH_AES_128_CCM :
+        ssl->specs.bulk_cipher_algorithm = wolfssl_aes_ccm;
+        ssl->specs.cipher_type           = aead;
+        ssl->specs.mac_algorithm         = sha256_mac;
+        ssl->specs.kea                   = ecc_diffie_hellman_kea;
+        ssl->specs.sig_algo              = ecc_dsa_sa_algo;
+        ssl->specs.hash_size             = WC_SHA256_DIGEST_SIZE;
+        ssl->specs.pad_size              = PAD_SHA;
+        ssl->specs.static_ecdh           = 0;
+        ssl->specs.key_size              = AES_128_KEY_SIZE;
+        ssl->specs.block_size            = AES_BLOCK_SIZE;
+        ssl->specs.iv_size               = AESGCM_IMP_IV_SZ;
+        ssl->specs.aead_mac_size         = AES_CCM_16_AUTH_SZ;
+
+        break;
+#endif
+
+#ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8
+    case TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8 :
+        ssl->specs.bulk_cipher_algorithm = wolfssl_aes_ccm;
+        ssl->specs.cipher_type           = aead;
+        ssl->specs.mac_algorithm         = sha256_mac;
+        ssl->specs.kea                   = ecc_diffie_hellman_kea;
+        ssl->specs.sig_algo              = ecc_dsa_sa_algo;
+        ssl->specs.hash_size             = WC_SHA256_DIGEST_SIZE;
+        ssl->specs.pad_size              = PAD_SHA;
+        ssl->specs.static_ecdh           = 0;
+        ssl->specs.key_size              = AES_128_KEY_SIZE;
+        ssl->specs.block_size            = AES_BLOCK_SIZE;
+        ssl->specs.iv_size               = AESGCM_IMP_IV_SZ;
+        ssl->specs.aead_mac_size         = AES_CCM_8_AUTH_SZ;
+
+        break;
+#endif
+
+#ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8
+    case TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8 :
+        ssl->specs.bulk_cipher_algorithm = wolfssl_aes_ccm;
+        ssl->specs.cipher_type           = aead;
+        ssl->specs.mac_algorithm         = sha256_mac;
+        ssl->specs.kea                   = ecc_diffie_hellman_kea;
+        ssl->specs.sig_algo              = ecc_dsa_sa_algo;
+        ssl->specs.hash_size             = WC_SHA256_DIGEST_SIZE;
+        ssl->specs.pad_size              = PAD_SHA;
+        ssl->specs.static_ecdh           = 0;
+        ssl->specs.key_size              = AES_256_KEY_SIZE;
+        ssl->specs.block_size            = AES_BLOCK_SIZE;
+        ssl->specs.iv_size               = AESGCM_IMP_IV_SZ;
+        ssl->specs.aead_mac_size         = AES_CCM_8_AUTH_SZ;
+
+        break;
+#endif
+
+#ifdef BUILD_TLS_ECDHE_ECDSA_WITH_NULL_SHA
+    case TLS_ECDHE_ECDSA_WITH_NULL_SHA :
+        ssl->specs.bulk_cipher_algorithm = wolfssl_cipher_null;
+        ssl->specs.cipher_type           = stream;
+        ssl->specs.mac_algorithm         = sha_mac;
+        ssl->specs.kea                   = ecc_diffie_hellman_kea;
+        ssl->specs.sig_algo              = ecc_dsa_sa_algo;
+        ssl->specs.hash_size             = WC_SHA_DIGEST_SIZE;
+        ssl->specs.pad_size              = PAD_SHA;
+        ssl->specs.static_ecdh           = 0;
+        ssl->specs.key_size              = 0;
+        ssl->specs.block_size            = 0;
+        ssl->specs.iv_size               = 0;
+
+    break;
+#endif
+
+#endif /* HAVE_ECC || (CURVE25519 && ED25519) || (CURVE448 && ED448) */
+
+#if defined(HAVE_ECC)
+
+#ifdef BUILD_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256
+    case TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256 :
+        ssl->specs.bulk_cipher_algorithm = wolfssl_aes;
+        ssl->specs.cipher_type           = block;
+        ssl->specs.mac_algorithm         = sha256_mac;
+        ssl->specs.kea                   = ecc_diffie_hellman_kea;
+        ssl->specs.sig_algo              = rsa_sa_algo;
+        ssl->specs.hash_size             = WC_SHA256_DIGEST_SIZE;
+        ssl->specs.pad_size              = PAD_SHA;
+        ssl->specs.static_ecdh           = 1;
+        ssl->specs.key_size              = AES_128_KEY_SIZE;
+        ssl->specs.iv_size               = AES_IV_SIZE;
+        ssl->specs.block_size            = AES_BLOCK_SIZE;
+
+        break;
+#endif
+
+#ifdef BUILD_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256
+    case TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256 :
+        ssl->specs.bulk_cipher_algorithm = wolfssl_aes;
+        ssl->specs.cipher_type           = block;
+        ssl->specs.mac_algorithm         = sha256_mac;
+        ssl->specs.kea                   = ecc_diffie_hellman_kea;
+        ssl->specs.sig_algo              = ecc_dsa_sa_algo;
+        ssl->specs.hash_size             = WC_SHA256_DIGEST_SIZE;
+        ssl->specs.pad_size              = PAD_SHA;
+        ssl->specs.static_ecdh           = 1;
+        ssl->specs.key_size              = AES_128_KEY_SIZE;
+        ssl->specs.iv_size               = AES_IV_SIZE;
+        ssl->specs.block_size            = AES_BLOCK_SIZE;
+
+        break;
+#endif
+
+#ifdef BUILD_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384
+    case TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384 :
+        ssl->specs.bulk_cipher_algorithm = wolfssl_aes;
+        ssl->specs.cipher_type           = block;
+        ssl->specs.mac_algorithm         = sha384_mac;
+        ssl->specs.kea                   = ecc_diffie_hellman_kea;
+        ssl->specs.sig_algo              = rsa_sa_algo;
+        ssl->specs.hash_size             = WC_SHA384_DIGEST_SIZE;
+        ssl->specs.pad_size              = PAD_SHA;
+        ssl->specs.static_ecdh           = 1;
+        ssl->specs.key_size              = AES_256_KEY_SIZE;
+        ssl->specs.iv_size               = AES_IV_SIZE;
+        ssl->specs.block_size            = AES_BLOCK_SIZE;
+
+        break;
+#endif
+
+#ifdef BUILD_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384
+    case TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384 :
+        ssl->specs.bulk_cipher_algorithm = wolfssl_aes;
+        ssl->specs.cipher_type           = block;
+        ssl->specs.mac_algorithm         = sha384_mac;
+        ssl->specs.kea                   = ecc_diffie_hellman_kea;
+        ssl->specs.sig_algo              = ecc_dsa_sa_algo;
+        ssl->specs.hash_size             = WC_SHA384_DIGEST_SIZE;
+        ssl->specs.pad_size              = PAD_SHA;
+        ssl->specs.static_ecdh           = 1;
+        ssl->specs.key_size              = AES_256_KEY_SIZE;
+        ssl->specs.iv_size               = AES_IV_SIZE;
+        ssl->specs.block_size            = AES_BLOCK_SIZE;
+
+        break;
+#endif
+
+#ifdef BUILD_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA
+    case TLS_ECDH_RSA_WITH_AES_128_CBC_SHA :
+        ssl->specs.bulk_cipher_algorithm = wolfssl_aes;
+        ssl->specs.cipher_type           = block;
+        ssl->specs.mac_algorithm         = sha_mac;
+        ssl->specs.kea                   = ecc_diffie_hellman_kea;
+        ssl->specs.sig_algo              = rsa_sa_algo;
+        ssl->specs.hash_size             = WC_SHA_DIGEST_SIZE;
+        ssl->specs.pad_size              = PAD_SHA;
+        ssl->specs.static_ecdh           = 1;
+        ssl->specs.key_size              = AES_128_KEY_SIZE;
+        ssl->specs.block_size            = AES_BLOCK_SIZE;
+        ssl->specs.iv_size               = AES_IV_SIZE;
+
+        break;
+#endif
+
+#ifdef BUILD_TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA
+    case TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA :
+        ssl->specs.bulk_cipher_algorithm = wolfssl_triple_des;
+        ssl->specs.cipher_type           = block;
+        ssl->specs.mac_algorithm         = sha_mac;
+        ssl->specs.kea                   = ecc_diffie_hellman_kea;
+        ssl->specs.sig_algo              = rsa_sa_algo;
+        ssl->specs.hash_size             = WC_SHA_DIGEST_SIZE;
+        ssl->specs.pad_size              = PAD_SHA;
+        ssl->specs.static_ecdh           = 1;
+        ssl->specs.key_size              = DES3_KEY_SIZE;
+        ssl->specs.block_size            = DES_BLOCK_SIZE;
+        ssl->specs.iv_size               = DES_IV_SIZE;
+
+        break;
+#endif
+
+#ifdef BUILD_TLS_ECDH_RSA_WITH_RC4_128_SHA
+    case TLS_ECDH_RSA_WITH_RC4_128_SHA :
+        ssl->specs.bulk_cipher_algorithm = wolfssl_rc4;
+        ssl->specs.cipher_type           = stream;
+        ssl->specs.mac_algorithm         = sha_mac;
+        ssl->specs.kea                   = ecc_diffie_hellman_kea;
+        ssl->specs.sig_algo              = rsa_sa_algo;
+        ssl->specs.hash_size             = WC_SHA_DIGEST_SIZE;
+        ssl->specs.pad_size              = PAD_SHA;
+        ssl->specs.static_ecdh           = 1;
+        ssl->specs.key_size              = RC4_KEY_SIZE;
+        ssl->specs.iv_size               = 0;
+        ssl->specs.block_size            = 0;
+
+        break;
+#endif
+
+#ifdef BUILD_TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA
+    case TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA :
+        ssl->specs.bulk_cipher_algorithm = wolfssl_triple_des;
+        ssl->specs.cipher_type           = block;
+        ssl->specs.mac_algorithm         = sha_mac;
+        ssl->specs.kea                   = ecc_diffie_hellman_kea;
+        ssl->specs.sig_algo              = ecc_dsa_sa_algo;
+        ssl->specs.hash_size             = WC_SHA_DIGEST_SIZE;
+        ssl->specs.pad_size              = PAD_SHA;
+        ssl->specs.static_ecdh           = 1;
+        ssl->specs.key_size              = DES3_KEY_SIZE;
+        ssl->specs.block_size            = DES_BLOCK_SIZE;
+        ssl->specs.iv_size               = DES_IV_SIZE;
+
+        break;
+#endif
+
+#ifdef BUILD_TLS_ECDH_ECDSA_WITH_RC4_128_SHA
+    case TLS_ECDH_ECDSA_WITH_RC4_128_SHA :
+        ssl->specs.bulk_cipher_algorithm = wolfssl_rc4;
+        ssl->specs.cipher_type           = stream;
+        ssl->specs.mac_algorithm         = sha_mac;
+        ssl->specs.kea                   = ecc_diffie_hellman_kea;
+        ssl->specs.sig_algo              = ecc_dsa_sa_algo;
+        ssl->specs.hash_size             = WC_SHA_DIGEST_SIZE;
+        ssl->specs.pad_size              = PAD_SHA;
+        ssl->specs.static_ecdh           = 1;
+        ssl->specs.key_size              = RC4_KEY_SIZE;
+        ssl->specs.iv_size               = 0;
+        ssl->specs.block_size            = 0;
+
+        break;
+#endif
+
+#ifdef BUILD_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA
+    case TLS_ECDH_RSA_WITH_AES_256_CBC_SHA :
+        ssl->specs.bulk_cipher_algorithm = wolfssl_aes;
+        ssl->specs.cipher_type           = block;
+        ssl->specs.mac_algorithm         = sha_mac;
+        ssl->specs.kea                   = ecc_diffie_hellman_kea;
+        ssl->specs.sig_algo              = rsa_sa_algo;
+        ssl->specs.hash_size             = WC_SHA_DIGEST_SIZE;
+        ssl->specs.pad_size              = PAD_SHA;
+        ssl->specs.static_ecdh           = 1;
+        ssl->specs.key_size              = AES_256_KEY_SIZE;
+        ssl->specs.block_size            = AES_BLOCK_SIZE;
+        ssl->specs.iv_size               = AES_IV_SIZE;
+
+        break;
+#endif
+
+#ifdef BUILD_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA
+    case TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA :
+        ssl->specs.bulk_cipher_algorithm = wolfssl_aes;
+        ssl->specs.cipher_type           = block;
+        ssl->specs.mac_algorithm         = sha_mac;
+        ssl->specs.kea                   = ecc_diffie_hellman_kea;
+        ssl->specs.sig_algo              = ecc_dsa_sa_algo;
+        ssl->specs.hash_size             = WC_SHA_DIGEST_SIZE;
+        ssl->specs.pad_size              = PAD_SHA;
+        ssl->specs.static_ecdh           = 1;
+        ssl->specs.key_size              = AES_128_KEY_SIZE;
+        ssl->specs.block_size            = AES_BLOCK_SIZE;
+        ssl->specs.iv_size               = AES_IV_SIZE;
+
+        break;
+#endif
+
+#ifdef BUILD_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA
+    case TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA :
+        ssl->specs.bulk_cipher_algorithm = wolfssl_aes;
+        ssl->specs.cipher_type           = block;
+        ssl->specs.mac_algorithm         = sha_mac;
+        ssl->specs.kea                   = ecc_diffie_hellman_kea;
+        ssl->specs.sig_algo              = ecc_dsa_sa_algo;
+        ssl->specs.hash_size             = WC_SHA_DIGEST_SIZE;
+        ssl->specs.pad_size              = PAD_SHA;
+        ssl->specs.static_ecdh           = 1;
+        ssl->specs.key_size              = AES_256_KEY_SIZE;
+        ssl->specs.block_size            = AES_BLOCK_SIZE;
+        ssl->specs.iv_size               = AES_IV_SIZE;
+
+        break;
+#endif
+
+#ifdef BUILD_TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256
+    case TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256 :
+        ssl->specs.bulk_cipher_algorithm = wolfssl_aes_gcm;
+        ssl->specs.cipher_type           = aead;
+        ssl->specs.mac_algorithm         = sha256_mac;
+        ssl->specs.kea                   = ecc_diffie_hellman_kea;
+        ssl->specs.sig_algo              = rsa_sa_algo;
+        ssl->specs.hash_size             = WC_SHA256_DIGEST_SIZE;
+        ssl->specs.pad_size              = PAD_SHA;
+        ssl->specs.static_ecdh           = 1;
+        ssl->specs.key_size              = AES_128_KEY_SIZE;
+        ssl->specs.block_size            = AES_BLOCK_SIZE;
+        ssl->specs.iv_size               = AESGCM_IMP_IV_SZ;
+        ssl->specs.aead_mac_size         = AES_GCM_AUTH_SZ;
+
+        break;
+#endif
+
+#ifdef BUILD_TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384
+    case TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384 :
+        ssl->specs.bulk_cipher_algorithm = wolfssl_aes_gcm;
+        ssl->specs.cipher_type           = aead;
+        ssl->specs.mac_algorithm         = sha384_mac;
+        ssl->specs.kea                   = ecc_diffie_hellman_kea;
+        ssl->specs.sig_algo              = rsa_sa_algo;
+        ssl->specs.hash_size             = WC_SHA384_DIGEST_SIZE;
+        ssl->specs.pad_size              = PAD_SHA;
+        ssl->specs.static_ecdh           = 1;
+        ssl->specs.key_size              = AES_256_KEY_SIZE;
+        ssl->specs.block_size            = AES_BLOCK_SIZE;
+        ssl->specs.iv_size               = AESGCM_IMP_IV_SZ;
+        ssl->specs.aead_mac_size         = AES_GCM_AUTH_SZ;
+
+        break;
+#endif
+
+#ifdef BUILD_TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256
+    case TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256 :
+        ssl->specs.bulk_cipher_algorithm = wolfssl_aes_gcm;
+        ssl->specs.cipher_type           = aead;
+        ssl->specs.mac_algorithm         = sha256_mac;
+        ssl->specs.kea                   = ecc_diffie_hellman_kea;
+        ssl->specs.sig_algo              = ecc_dsa_sa_algo;
+        ssl->specs.hash_size             = WC_SHA256_DIGEST_SIZE;
+        ssl->specs.pad_size              = PAD_SHA;
+        ssl->specs.static_ecdh           = 1;
+        ssl->specs.key_size              = AES_128_KEY_SIZE;
+        ssl->specs.block_size            = AES_BLOCK_SIZE;
+        ssl->specs.iv_size               = AESGCM_IMP_IV_SZ;
+        ssl->specs.aead_mac_size         = AES_GCM_AUTH_SZ;
+
+        break;
+#endif
+
+#ifdef BUILD_TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384
+    case TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384 :
+        ssl->specs.bulk_cipher_algorithm = wolfssl_aes_gcm;
+        ssl->specs.cipher_type           = aead;
+        ssl->specs.mac_algorithm         = sha384_mac;
+        ssl->specs.kea                   = ecc_diffie_hellman_kea;
+        ssl->specs.sig_algo              = ecc_dsa_sa_algo;
+        ssl->specs.hash_size             = WC_SHA384_DIGEST_SIZE;
+        ssl->specs.pad_size              = PAD_SHA;
+        ssl->specs.static_ecdh           = 1;
+        ssl->specs.key_size              = AES_256_KEY_SIZE;
+        ssl->specs.block_size            = AES_BLOCK_SIZE;
+        ssl->specs.iv_size               = AESGCM_IMP_IV_SZ;
+        ssl->specs.aead_mac_size         = AES_GCM_AUTH_SZ;
+
+        break;
+#endif
+
+#endif /* HAVE_ECC */
+
+#ifdef BUILD_TLS_RSA_WITH_AES_128_CCM_8
+    case TLS_RSA_WITH_AES_128_CCM_8 :
+        ssl->specs.bulk_cipher_algorithm = wolfssl_aes_ccm;
+        ssl->specs.cipher_type           = aead;
+        ssl->specs.mac_algorithm         = sha256_mac;
+        ssl->specs.kea                   = rsa_kea;
+        ssl->specs.sig_algo              = rsa_sa_algo;
+        ssl->specs.hash_size             = WC_SHA256_DIGEST_SIZE;
+        ssl->specs.pad_size              = PAD_SHA;
+        ssl->specs.static_ecdh           = 0;
+        ssl->specs.key_size              = AES_128_KEY_SIZE;
+        ssl->specs.block_size            = AES_BLOCK_SIZE;
+        ssl->specs.iv_size               = AESGCM_IMP_IV_SZ;
+        ssl->specs.aead_mac_size         = AES_CCM_8_AUTH_SZ;
+
+        break;
+#endif
+
+#ifdef BUILD_TLS_RSA_WITH_AES_256_CCM_8
+    case TLS_RSA_WITH_AES_256_CCM_8 :
+        ssl->specs.bulk_cipher_algorithm = wolfssl_aes_ccm;
+        ssl->specs.cipher_type           = aead;
+        ssl->specs.mac_algorithm         = sha256_mac;
+        ssl->specs.kea                   = rsa_kea;
+        ssl->specs.sig_algo              = rsa_sa_algo;
+        ssl->specs.hash_size             = WC_SHA256_DIGEST_SIZE;
+        ssl->specs.pad_size              = PAD_SHA;
+        ssl->specs.static_ecdh           = 0;
+        ssl->specs.key_size              = AES_256_KEY_SIZE;
+        ssl->specs.block_size            = AES_BLOCK_SIZE;
+        ssl->specs.iv_size               = AESGCM_IMP_IV_SZ;
+        ssl->specs.aead_mac_size         = AES_CCM_8_AUTH_SZ;
+
+        break;
+#endif
+
+#ifdef BUILD_TLS_PSK_WITH_AES_128_CCM_8
+    case TLS_PSK_WITH_AES_128_CCM_8 :
+        ssl->specs.bulk_cipher_algorithm = wolfssl_aes_ccm;
+        ssl->specs.cipher_type           = aead;
+        ssl->specs.mac_algorithm         = sha256_mac;
+        ssl->specs.kea                   = psk_kea;
+        ssl->specs.sig_algo              = anonymous_sa_algo;
+        ssl->specs.hash_size             = WC_SHA256_DIGEST_SIZE;
+        ssl->specs.pad_size              = PAD_SHA;
+        ssl->specs.static_ecdh           = 0;
+        ssl->specs.key_size              = AES_128_KEY_SIZE;
+        ssl->specs.block_size            = AES_BLOCK_SIZE;
+        ssl->specs.iv_size               = AESGCM_IMP_IV_SZ;
+        ssl->specs.aead_mac_size         = AES_CCM_8_AUTH_SZ;
+
+        ssl->options.usingPSK_cipher     = 1;
+        break;
+#endif
+
+#ifdef BUILD_TLS_PSK_WITH_AES_256_CCM_8
+    case TLS_PSK_WITH_AES_256_CCM_8 :
+        ssl->specs.bulk_cipher_algorithm = wolfssl_aes_ccm;
+        ssl->specs.cipher_type           = aead;
+        ssl->specs.mac_algorithm         = sha256_mac;
+        ssl->specs.kea                   = psk_kea;
+        ssl->specs.sig_algo              = anonymous_sa_algo;
+        ssl->specs.hash_size             = WC_SHA256_DIGEST_SIZE;
+        ssl->specs.pad_size              = PAD_SHA;
+        ssl->specs.static_ecdh           = 0;
+        ssl->specs.key_size              = AES_256_KEY_SIZE;
+        ssl->specs.block_size            = AES_BLOCK_SIZE;
+        ssl->specs.iv_size               = AESGCM_IMP_IV_SZ;
+        ssl->specs.aead_mac_size         = AES_CCM_8_AUTH_SZ;
+
+        ssl->options.usingPSK_cipher     = 1;
+        break;
+#endif
+
+#ifdef BUILD_TLS_PSK_WITH_AES_128_CCM
+    case TLS_PSK_WITH_AES_128_CCM :
+        ssl->specs.bulk_cipher_algorithm = wolfssl_aes_ccm;
+        ssl->specs.cipher_type           = aead;
+        ssl->specs.mac_algorithm         = sha256_mac;
+        ssl->specs.kea                   = psk_kea;
+        ssl->specs.sig_algo              = anonymous_sa_algo;
+        ssl->specs.hash_size             = WC_SHA256_DIGEST_SIZE;
+        ssl->specs.pad_size              = PAD_SHA;
+        ssl->specs.static_ecdh           = 0;
+        ssl->specs.key_size              = AES_128_KEY_SIZE;
+        ssl->specs.block_size            = AES_BLOCK_SIZE;
+        ssl->specs.iv_size               = AESGCM_IMP_IV_SZ;
+        ssl->specs.aead_mac_size         = AES_CCM_16_AUTH_SZ;
+
+        ssl->options.usingPSK_cipher     = 1;
+        break;
+#endif
+
+#ifdef BUILD_TLS_PSK_WITH_AES_256_CCM
+    case TLS_PSK_WITH_AES_256_CCM :
+        ssl->specs.bulk_cipher_algorithm = wolfssl_aes_ccm;
+        ssl->specs.cipher_type           = aead;
+        ssl->specs.mac_algorithm         = sha256_mac;
+        ssl->specs.kea                   = psk_kea;
+        ssl->specs.sig_algo              = anonymous_sa_algo;
+        ssl->specs.hash_size             = WC_SHA256_DIGEST_SIZE;
+        ssl->specs.pad_size              = PAD_SHA;
+        ssl->specs.static_ecdh           = 0;
+        ssl->specs.key_size              = AES_256_KEY_SIZE;
+        ssl->specs.block_size            = AES_BLOCK_SIZE;
+        ssl->specs.iv_size               = AESGCM_IMP_IV_SZ;
+        ssl->specs.aead_mac_size         = AES_CCM_16_AUTH_SZ;
+
+        ssl->options.usingPSK_cipher     = 1;
+        break;
+#endif
+
+#ifdef BUILD_TLS_DHE_PSK_WITH_AES_128_CCM
+    case TLS_DHE_PSK_WITH_AES_128_CCM :
+        ssl->specs.bulk_cipher_algorithm = wolfssl_aes_ccm;
+        ssl->specs.cipher_type           = aead;
+        ssl->specs.mac_algorithm         = sha256_mac;
+        ssl->specs.kea                   = dhe_psk_kea;
+        ssl->specs.sig_algo              = anonymous_sa_algo;
+        ssl->specs.hash_size             = WC_SHA256_DIGEST_SIZE;
+        ssl->specs.pad_size              = PAD_SHA;
+        ssl->specs.static_ecdh           = 0;
+        ssl->specs.key_size              = AES_128_KEY_SIZE;
+        ssl->specs.block_size            = AES_BLOCK_SIZE;
+        ssl->specs.iv_size               = AESGCM_IMP_IV_SZ;
+        ssl->specs.aead_mac_size         = AES_CCM_16_AUTH_SZ;
+
+        ssl->options.usingPSK_cipher     = 1;
+        break;
+#endif
+
+#ifdef BUILD_TLS_DHE_PSK_WITH_AES_256_CCM
+    case TLS_DHE_PSK_WITH_AES_256_CCM :
+        ssl->specs.bulk_cipher_algorithm = wolfssl_aes_ccm;
+        ssl->specs.cipher_type           = aead;
+        ssl->specs.mac_algorithm         = sha256_mac;
+        ssl->specs.kea                   = dhe_psk_kea;
+        ssl->specs.sig_algo              = anonymous_sa_algo;
+        ssl->specs.hash_size             = WC_SHA256_DIGEST_SIZE;
+        ssl->specs.pad_size              = PAD_SHA;
+        ssl->specs.static_ecdh           = 0;
+        ssl->specs.key_size              = AES_256_KEY_SIZE;
+        ssl->specs.block_size            = AES_BLOCK_SIZE;
+        ssl->specs.iv_size               = AESGCM_IMP_IV_SZ;
+        ssl->specs.aead_mac_size         = AES_CCM_16_AUTH_SZ;
+
+        ssl->options.usingPSK_cipher     = 1;
+        break;
+#endif
+
+#if defined(WOLFSSL_TLS13) && defined(HAVE_NULL_CIPHER)
+    #ifdef BUILD_TLS_SHA256_SHA256
+    case TLS_SHA256_SHA256 :
+        ssl->specs.bulk_cipher_algorithm = wolfssl_cipher_null;
+        ssl->specs.cipher_type           = aead;
+        ssl->specs.mac_algorithm         = sha256_mac;
+        ssl->specs.kea                   = 0;
+        ssl->specs.sig_algo              = 0;
+        ssl->specs.hash_size             = WC_SHA256_DIGEST_SIZE;
+        ssl->specs.pad_size              = PAD_SHA;
+        ssl->specs.static_ecdh           = 0;
+        ssl->specs.key_size              = WC_SHA256_DIGEST_SIZE / 2;
+        ssl->specs.block_size            = 0;
+        ssl->specs.iv_size               = HMAC_NONCE_SZ;
+        ssl->specs.aead_mac_size         = WC_SHA256_DIGEST_SIZE;
+
+        break;
+    #endif
+
+    #ifdef BUILD_TLS_SHA384_SHA384
+    case TLS_SHA384_SHA384 :
+        ssl->specs.bulk_cipher_algorithm = wolfssl_cipher_null;
+        ssl->specs.cipher_type           = aead;
+        ssl->specs.mac_algorithm         = sha384_mac;
+        ssl->specs.kea                   = 0;
+        ssl->specs.sig_algo              = 0;
+        ssl->specs.hash_size             = WC_SHA384_DIGEST_SIZE;
+        ssl->specs.pad_size              = PAD_SHA;
+        ssl->specs.static_ecdh           = 0;
+        ssl->specs.key_size              = WC_SHA384_DIGEST_SIZE / 2;
+        ssl->specs.block_size            = 0;
+        ssl->specs.iv_size               = HMAC_NONCE_SZ;
+        ssl->specs.aead_mac_size         = WC_SHA384_DIGEST_SIZE;
+
+        break;
+    #endif
+#endif
+
+    default:
+        WOLFSSL_MSG("Unsupported cipher suite, SetCipherSpecs ECC");
+        return UNSUPPORTED_SUITE;
+    }   /* switch */
+    }   /* if     */
+
+    /* TLSi v1.3 cipher suites, 0x13 */
+    if (ssl->options.cipherSuite0 == TLS13_BYTE) {
+        switch (ssl->options.cipherSuite) {
+
+#ifdef WOLFSSL_TLS13
+    #ifdef BUILD_TLS_AES_128_GCM_SHA256
+        case TLS_AES_128_GCM_SHA256 :
+            ssl->specs.bulk_cipher_algorithm = wolfssl_aes_gcm;
+            ssl->specs.cipher_type           = aead;
+            ssl->specs.mac_algorithm         = sha256_mac;
+            ssl->specs.kea                   = 0;
+            ssl->specs.sig_algo              = 0;
+            ssl->specs.hash_size             = WC_SHA256_DIGEST_SIZE;
+            ssl->specs.pad_size              = PAD_SHA;
+            ssl->specs.static_ecdh           = 0;
+            ssl->specs.key_size              = AES_128_KEY_SIZE;
+            ssl->specs.block_size            = AES_BLOCK_SIZE;
+            ssl->specs.iv_size               = AESGCM_NONCE_SZ;
+            ssl->specs.aead_mac_size         = AES_GCM_AUTH_SZ;
+
+            break;
+    #endif
+
+    #ifdef BUILD_TLS_AES_256_GCM_SHA384
+        case TLS_AES_256_GCM_SHA384 :
+            ssl->specs.bulk_cipher_algorithm = wolfssl_aes_gcm;
+            ssl->specs.cipher_type           = aead;
+            ssl->specs.mac_algorithm         = sha384_mac;
+            ssl->specs.kea                   = 0;
+            ssl->specs.sig_algo              = 0;
+            ssl->specs.hash_size             = WC_SHA384_DIGEST_SIZE;
+            ssl->specs.pad_size              = PAD_SHA;
+            ssl->specs.static_ecdh           = 0;
+            ssl->specs.key_size              = AES_256_KEY_SIZE;
+            ssl->specs.block_size            = AES_BLOCK_SIZE;
+            ssl->specs.iv_size               = AESGCM_NONCE_SZ;
+            ssl->specs.aead_mac_size         = AES_GCM_AUTH_SZ;
+
+            break;
+    #endif
+
+    #ifdef BUILD_TLS_CHACHA20_POLY1305_SHA256
+        case TLS_CHACHA20_POLY1305_SHA256 :
+            ssl->specs.bulk_cipher_algorithm = wolfssl_chacha;
+            ssl->specs.cipher_type           = aead;
+            ssl->specs.mac_algorithm         = sha256_mac;
+            ssl->specs.kea                   = 0;
+            ssl->specs.sig_algo              = 0;
+            ssl->specs.hash_size             = WC_SHA256_DIGEST_SIZE;
+            ssl->specs.pad_size              = PAD_SHA;
+            ssl->specs.static_ecdh           = 0;
+            ssl->specs.key_size              = CHACHA20_256_KEY_SIZE;
+            ssl->specs.block_size            = CHACHA20_BLOCK_SIZE;
+            ssl->specs.iv_size               = CHACHA20_IV_SIZE;
+            ssl->specs.aead_mac_size         = POLY1305_AUTH_SZ;
+            ssl->options.oldPoly             = 0; /* use recent padding RFC */
+
+            break;
+    #endif
+
+    #ifdef BUILD_TLS_AES_128_CCM_SHA256
+        case TLS_AES_128_CCM_SHA256 :
+            ssl->specs.bulk_cipher_algorithm = wolfssl_aes_ccm;
+            ssl->specs.cipher_type           = aead;
+            ssl->specs.mac_algorithm         = sha256_mac;
+            ssl->specs.kea                   = 0;
+            ssl->specs.sig_algo              = 0;
+            ssl->specs.hash_size             = WC_SHA256_DIGEST_SIZE;
+            ssl->specs.pad_size              = PAD_SHA;
+            ssl->specs.static_ecdh           = 0;
+            ssl->specs.key_size              = AES_128_KEY_SIZE;
+            ssl->specs.block_size            = AES_BLOCK_SIZE;
+            ssl->specs.iv_size               = AESGCM_NONCE_SZ;
+            ssl->specs.aead_mac_size         = AES_CCM_16_AUTH_SZ;
+
+            break;
+    #endif
+
+    #ifdef BUILD_TLS_AES_128_CCM_8_SHA256
+        case TLS_AES_128_CCM_8_SHA256 :
+            ssl->specs.bulk_cipher_algorithm = wolfssl_aes_ccm;
+            ssl->specs.cipher_type           = aead;
+            ssl->specs.mac_algorithm         = sha256_mac;
+            ssl->specs.kea                   = 0;
+            ssl->specs.sig_algo              = 0;
+            ssl->specs.hash_size             = WC_SHA256_DIGEST_SIZE;
+            ssl->specs.pad_size              = PAD_SHA;
+            ssl->specs.static_ecdh           = 0;
+            ssl->specs.key_size              = AES_128_KEY_SIZE;
+            ssl->specs.block_size            = AES_BLOCK_SIZE;
+            ssl->specs.iv_size               = AESGCM_NONCE_SZ;
+            ssl->specs.aead_mac_size         = AES_CCM_8_AUTH_SZ;
+
+            break;
+    #endif
+#endif /* WOLFSSL_TLS13 */
+        }
+    }
+
+    if (ssl->options.cipherSuite0 != ECC_BYTE &&
+            ssl->options.cipherSuite0 != CHACHA_BYTE &&
+            ssl->options.cipherSuite0 != TLS13_BYTE) {   /* normal suites */
+    switch (ssl->options.cipherSuite) {
+
+#ifdef BUILD_SSL_RSA_WITH_RC4_128_SHA
+    case SSL_RSA_WITH_RC4_128_SHA :
+        ssl->specs.bulk_cipher_algorithm = wolfssl_rc4;
+        ssl->specs.cipher_type           = stream;
+        ssl->specs.mac_algorithm         = sha_mac;
+        ssl->specs.kea                   = rsa_kea;
+        ssl->specs.sig_algo              = rsa_sa_algo;
+        ssl->specs.hash_size             = WC_SHA_DIGEST_SIZE;
+        ssl->specs.pad_size              = PAD_SHA;
+        ssl->specs.static_ecdh           = 0;
+        ssl->specs.key_size              = RC4_KEY_SIZE;
+        ssl->specs.iv_size               = 0;
+        ssl->specs.block_size            = 0;
+
+        break;
+#endif
+
+#ifdef BUILD_TLS_NTRU_RSA_WITH_RC4_128_SHA
+    case TLS_NTRU_RSA_WITH_RC4_128_SHA :
+        ssl->specs.bulk_cipher_algorithm = wolfssl_rc4;
+        ssl->specs.cipher_type           = stream;
+        ssl->specs.mac_algorithm         = sha_mac;
+        ssl->specs.kea                   = ntru_kea;
+        ssl->specs.sig_algo              = rsa_sa_algo;
+        ssl->specs.hash_size             = WC_SHA_DIGEST_SIZE;
+        ssl->specs.pad_size              = PAD_SHA;
+        ssl->specs.static_ecdh           = 0;
+        ssl->specs.key_size              = RC4_KEY_SIZE;
+        ssl->specs.iv_size               = 0;
+        ssl->specs.block_size            = 0;
+
+        break;
+#endif
+
+#ifdef BUILD_SSL_RSA_WITH_RC4_128_MD5
+    case SSL_RSA_WITH_RC4_128_MD5 :
+        ssl->specs.bulk_cipher_algorithm = wolfssl_rc4;
+        ssl->specs.cipher_type           = stream;
+        ssl->specs.mac_algorithm         = md5_mac;
+        ssl->specs.kea                   = rsa_kea;
+        ssl->specs.sig_algo              = rsa_sa_algo;
+        ssl->specs.hash_size             = WC_MD5_DIGEST_SIZE;
+        ssl->specs.pad_size              = PAD_MD5;
+        ssl->specs.static_ecdh           = 0;
+        ssl->specs.key_size              = RC4_KEY_SIZE;
+        ssl->specs.iv_size               = 0;
+        ssl->specs.block_size            = 0;
+
+        break;
+#endif
+
+#ifdef BUILD_SSL_RSA_WITH_3DES_EDE_CBC_SHA
+    case SSL_RSA_WITH_3DES_EDE_CBC_SHA :
+        ssl->specs.bulk_cipher_algorithm = wolfssl_triple_des;
+        ssl->specs.cipher_type           = block;
+        ssl->specs.mac_algorithm         = sha_mac;
+        ssl->specs.kea                   = rsa_kea;
+        ssl->specs.sig_algo              = rsa_sa_algo;
+        ssl->specs.hash_size             = WC_SHA_DIGEST_SIZE;
+        ssl->specs.pad_size              = PAD_SHA;
+        ssl->specs.static_ecdh           = 0;
+        ssl->specs.key_size              = DES3_KEY_SIZE;
+        ssl->specs.block_size            = DES_BLOCK_SIZE;
+        ssl->specs.iv_size               = DES_IV_SIZE;
+
+        break;
+#endif
+
+#ifdef BUILD_TLS_NTRU_RSA_WITH_3DES_EDE_CBC_SHA
+    case TLS_NTRU_RSA_WITH_3DES_EDE_CBC_SHA :
+        ssl->specs.bulk_cipher_algorithm = wolfssl_triple_des;
+        ssl->specs.cipher_type           = block;
+        ssl->specs.mac_algorithm         = sha_mac;
+        ssl->specs.kea                   = ntru_kea;
+        ssl->specs.sig_algo              = rsa_sa_algo;
+        ssl->specs.hash_size             = WC_SHA_DIGEST_SIZE;
+        ssl->specs.pad_size              = PAD_SHA;
+        ssl->specs.static_ecdh           = 0;
+        ssl->specs.key_size              = DES3_KEY_SIZE;
+        ssl->specs.block_size            = DES_BLOCK_SIZE;
+        ssl->specs.iv_size               = DES_IV_SIZE;
+
+        break;
+#endif
+
+#ifdef BUILD_TLS_RSA_WITH_AES_128_CBC_SHA
+    case TLS_RSA_WITH_AES_128_CBC_SHA :
+        ssl->specs.bulk_cipher_algorithm = wolfssl_aes;
+        ssl->specs.cipher_type           = block;
+        ssl->specs.mac_algorithm         = sha_mac;
+        ssl->specs.kea                   = rsa_kea;
+        ssl->specs.sig_algo              = rsa_sa_algo;
+        ssl->specs.hash_size             = WC_SHA_DIGEST_SIZE;
+        ssl->specs.pad_size              = PAD_SHA;
+        ssl->specs.static_ecdh           = 0;
+        ssl->specs.key_size              = AES_128_KEY_SIZE;
+        ssl->specs.block_size            = AES_BLOCK_SIZE;
+        ssl->specs.iv_size               = AES_IV_SIZE;
+
+        break;
+#endif
+
+#ifdef BUILD_TLS_RSA_WITH_AES_128_CBC_SHA256
+    case TLS_RSA_WITH_AES_128_CBC_SHA256 :
+        ssl->specs.bulk_cipher_algorithm = wolfssl_aes;
+        ssl->specs.cipher_type           = block;
+        ssl->specs.mac_algorithm         = sha256_mac;
+        ssl->specs.kea                   = rsa_kea;
+        ssl->specs.sig_algo              = rsa_sa_algo;
+        ssl->specs.hash_size             = WC_SHA256_DIGEST_SIZE;
+        ssl->specs.pad_size              = PAD_SHA;
+        ssl->specs.static_ecdh           = 0;
+        ssl->specs.key_size              = AES_128_KEY_SIZE;
+        ssl->specs.block_size            = AES_BLOCK_SIZE;
+        ssl->specs.iv_size               = AES_IV_SIZE;
+
+        break;
+#endif
+
+#ifdef BUILD_TLS_RSA_WITH_NULL_MD5
+    case TLS_RSA_WITH_NULL_MD5 :
+        ssl->specs.bulk_cipher_algorithm = wolfssl_cipher_null;
+        ssl->specs.cipher_type           = stream;
+        ssl->specs.mac_algorithm         = md5_mac;
+        ssl->specs.kea                   = rsa_kea;
+        ssl->specs.sig_algo              = rsa_sa_algo;
+        ssl->specs.hash_size             = WC_MD5_DIGEST_SIZE;
+        ssl->specs.pad_size              = PAD_MD5;
+        ssl->specs.static_ecdh           = 0;
+        ssl->specs.key_size              = 0;
+        ssl->specs.block_size            = 0;
+        ssl->specs.iv_size               = 0;
+
+        break;
+#endif
+
+#ifdef BUILD_TLS_RSA_WITH_NULL_SHA
+    case TLS_RSA_WITH_NULL_SHA :
+        ssl->specs.bulk_cipher_algorithm = wolfssl_cipher_null;
+        ssl->specs.cipher_type           = stream;
+        ssl->specs.mac_algorithm         = sha_mac;
+        ssl->specs.kea                   = rsa_kea;
+        ssl->specs.sig_algo              = rsa_sa_algo;
+        ssl->specs.hash_size             = WC_SHA_DIGEST_SIZE;
+        ssl->specs.pad_size              = PAD_SHA;
+        ssl->specs.static_ecdh           = 0;
+        ssl->specs.key_size              = 0;
+        ssl->specs.block_size            = 0;
+        ssl->specs.iv_size               = 0;
+
+        break;
+#endif
+
+#ifdef BUILD_TLS_RSA_WITH_NULL_SHA256
+    case TLS_RSA_WITH_NULL_SHA256 :
+        ssl->specs.bulk_cipher_algorithm = wolfssl_cipher_null;
+        ssl->specs.cipher_type           = stream;
+        ssl->specs.mac_algorithm         = sha256_mac;
+        ssl->specs.kea                   = rsa_kea;
+        ssl->specs.sig_algo              = rsa_sa_algo;
+        ssl->specs.hash_size             = WC_SHA256_DIGEST_SIZE;
+        ssl->specs.pad_size              = PAD_SHA;
+        ssl->specs.static_ecdh           = 0;
+        ssl->specs.key_size              = 0;
+        ssl->specs.block_size            = 0;
+        ssl->specs.iv_size               = 0;
+
+        break;
+#endif
+
+#ifdef BUILD_TLS_NTRU_RSA_WITH_AES_128_CBC_SHA
+    case TLS_NTRU_RSA_WITH_AES_128_CBC_SHA :
+        ssl->specs.bulk_cipher_algorithm = wolfssl_aes;
+        ssl->specs.cipher_type           = block;
+        ssl->specs.mac_algorithm         = sha_mac;
+        ssl->specs.kea                   = ntru_kea;
+        ssl->specs.sig_algo              = rsa_sa_algo;
+        ssl->specs.hash_size             = WC_SHA_DIGEST_SIZE;
+        ssl->specs.pad_size              = PAD_SHA;
+        ssl->specs.static_ecdh           = 0;
+        ssl->specs.key_size              = AES_128_KEY_SIZE;
+        ssl->specs.block_size            = AES_BLOCK_SIZE;
+        ssl->specs.iv_size               = AES_IV_SIZE;
+
+        break;
+#endif
+
+#ifdef BUILD_TLS_RSA_WITH_AES_256_CBC_SHA
+    case TLS_RSA_WITH_AES_256_CBC_SHA :
+        ssl->specs.bulk_cipher_algorithm = wolfssl_aes;
+        ssl->specs.cipher_type           = block;
+        ssl->specs.mac_algorithm         = sha_mac;
+        ssl->specs.kea                   = rsa_kea;
+        ssl->specs.sig_algo              = rsa_sa_algo;
+        ssl->specs.hash_size             = WC_SHA_DIGEST_SIZE;
+        ssl->specs.pad_size              = PAD_SHA;
+        ssl->specs.static_ecdh           = 0;
+        ssl->specs.key_size              = AES_256_KEY_SIZE;
+        ssl->specs.block_size            = AES_BLOCK_SIZE;
+        ssl->specs.iv_size               = AES_IV_SIZE;
+
+        break;
+#endif
+
+#ifdef BUILD_TLS_RSA_WITH_AES_256_CBC_SHA256
+    case TLS_RSA_WITH_AES_256_CBC_SHA256 :
+        ssl->specs.bulk_cipher_algorithm = wolfssl_aes;
+        ssl->specs.cipher_type           = block;
+        ssl->specs.mac_algorithm         = sha256_mac;
+        ssl->specs.kea                   = rsa_kea;
+        ssl->specs.sig_algo              = rsa_sa_algo;
+        ssl->specs.hash_size             = WC_SHA256_DIGEST_SIZE;
+        ssl->specs.pad_size              = PAD_SHA;
+        ssl->specs.static_ecdh           = 0;
+        ssl->specs.key_size              = AES_256_KEY_SIZE;
+        ssl->specs.block_size            = AES_BLOCK_SIZE;
+        ssl->specs.iv_size               = AES_IV_SIZE;
+
+        break;
+#endif
+
+#ifdef BUILD_TLS_NTRU_RSA_WITH_AES_256_CBC_SHA
+    case TLS_NTRU_RSA_WITH_AES_256_CBC_SHA :
+        ssl->specs.bulk_cipher_algorithm = wolfssl_aes;
+        ssl->specs.cipher_type           = block;
+        ssl->specs.mac_algorithm         = sha_mac;
+        ssl->specs.kea                   = ntru_kea;
+        ssl->specs.sig_algo              = rsa_sa_algo;
+        ssl->specs.hash_size             = WC_SHA_DIGEST_SIZE;
+        ssl->specs.pad_size              = PAD_SHA;
+        ssl->specs.static_ecdh           = 0;
+        ssl->specs.key_size              = AES_256_KEY_SIZE;
+        ssl->specs.block_size            = AES_BLOCK_SIZE;
+        ssl->specs.iv_size               = AES_IV_SIZE;
+
+        break;
+#endif
+
+#ifdef BUILD_TLS_PSK_WITH_AES_128_GCM_SHA256
+    case TLS_PSK_WITH_AES_128_GCM_SHA256 :
+        ssl->specs.bulk_cipher_algorithm = wolfssl_aes_gcm;
+        ssl->specs.cipher_type           = aead;
+        ssl->specs.mac_algorithm         = sha256_mac;
+        ssl->specs.kea                   = psk_kea;
+        ssl->specs.sig_algo              = anonymous_sa_algo;
+        ssl->specs.hash_size             = WC_SHA256_DIGEST_SIZE;
+        ssl->specs.pad_size              = PAD_SHA;
+        ssl->specs.static_ecdh           = 0;
+        ssl->specs.key_size              = AES_128_KEY_SIZE;
+        ssl->specs.block_size            = AES_BLOCK_SIZE;
+        ssl->specs.iv_size               = AESGCM_IMP_IV_SZ;
+        ssl->specs.aead_mac_size         = AES_GCM_AUTH_SZ;
+
+        ssl->options.usingPSK_cipher     = 1;
+        break;
+#endif
+
+#ifdef BUILD_TLS_PSK_WITH_AES_256_GCM_SHA384
+    case TLS_PSK_WITH_AES_256_GCM_SHA384 :
+        ssl->specs.bulk_cipher_algorithm = wolfssl_aes_gcm;
+        ssl->specs.cipher_type           = aead;
+        ssl->specs.mac_algorithm         = sha384_mac;
+        ssl->specs.kea                   = psk_kea;
+        ssl->specs.sig_algo              = anonymous_sa_algo;
+        ssl->specs.hash_size             = WC_SHA384_DIGEST_SIZE;
+        ssl->specs.pad_size              = PAD_SHA;
+        ssl->specs.static_ecdh           = 0;
+        ssl->specs.key_size              = AES_256_KEY_SIZE;
+        ssl->specs.block_size            = AES_BLOCK_SIZE;
+        ssl->specs.iv_size               = AESGCM_IMP_IV_SZ;
+        ssl->specs.aead_mac_size         = AES_GCM_AUTH_SZ;
+
+        ssl->options.usingPSK_cipher     = 1;
+        break;
+#endif
+
+#ifdef BUILD_TLS_DH_anon_WITH_AES_256_GCM_SHA384
+    case TLS_DH_anon_WITH_AES_256_GCM_SHA384:
+        ssl->specs.bulk_cipher_algorithm = wolfssl_aes_gcm;
+        ssl->specs.cipher_type           = aead;
+        ssl->specs.mac_algorithm         = sha384_mac;
+        ssl->specs.kea                   = diffie_hellman_kea;
+        ssl->specs.sig_algo              = anonymous_sa_algo;
+        ssl->specs.hash_size             = WC_SHA384_DIGEST_SIZE;
+        ssl->specs.pad_size              = PAD_SHA;
+        ssl->specs.static_ecdh           = 0;
+        ssl->specs.key_size              = AES_256_KEY_SIZE;
+        ssl->specs.block_size            = AES_BLOCK_SIZE;
+        ssl->specs.iv_size               = AESGCM_IMP_IV_SZ;
+        ssl->specs.aead_mac_size         = AES_GCM_AUTH_SZ;
+
+         ssl->options.usingAnon_cipher    = 1;
+        break;
+#endif
+
+#ifdef BUILD_TLS_DHE_PSK_WITH_AES_128_GCM_SHA256
+    case TLS_DHE_PSK_WITH_AES_128_GCM_SHA256 :
+        ssl->specs.bulk_cipher_algorithm = wolfssl_aes_gcm;
+        ssl->specs.cipher_type           = aead;
+        ssl->specs.mac_algorithm         = sha256_mac;
+        ssl->specs.kea                   = dhe_psk_kea;
+        ssl->specs.sig_algo              = anonymous_sa_algo;
+        ssl->specs.hash_size             = WC_SHA256_DIGEST_SIZE;
+        ssl->specs.pad_size              = PAD_SHA;
+        ssl->specs.static_ecdh           = 0;
+        ssl->specs.key_size              = AES_128_KEY_SIZE;
+        ssl->specs.block_size            = AES_BLOCK_SIZE;
+        ssl->specs.iv_size               = AESGCM_IMP_IV_SZ;
+        ssl->specs.aead_mac_size         = AES_GCM_AUTH_SZ;
+
+        ssl->options.usingPSK_cipher     = 1;
+        break;
+#endif
+
+#ifdef BUILD_TLS_DHE_PSK_WITH_AES_256_GCM_SHA384
+    case TLS_DHE_PSK_WITH_AES_256_GCM_SHA384 :
+        ssl->specs.bulk_cipher_algorithm = wolfssl_aes_gcm;
+        ssl->specs.cipher_type           = aead;
+        ssl->specs.mac_algorithm         = sha384_mac;
+        ssl->specs.kea                   = dhe_psk_kea;
+        ssl->specs.sig_algo              = anonymous_sa_algo;
+        ssl->specs.hash_size             = WC_SHA384_DIGEST_SIZE;
+        ssl->specs.pad_size              = PAD_SHA;
+        ssl->specs.static_ecdh           = 0;
+        ssl->specs.key_size              = AES_256_KEY_SIZE;
+        ssl->specs.block_size            = AES_BLOCK_SIZE;
+        ssl->specs.iv_size               = AESGCM_IMP_IV_SZ;
+        ssl->specs.aead_mac_size         = AES_GCM_AUTH_SZ;
+
+        ssl->options.usingPSK_cipher     = 1;
+        break;
+#endif
+
+#ifdef BUILD_TLS_PSK_WITH_AES_128_CBC_SHA256
+    case TLS_PSK_WITH_AES_128_CBC_SHA256 :
+        ssl->specs.bulk_cipher_algorithm = wolfssl_aes;
+        ssl->specs.cipher_type           = block;
+        ssl->specs.mac_algorithm         = sha256_mac;
+        ssl->specs.kea                   = psk_kea;
+        ssl->specs.sig_algo              = anonymous_sa_algo;
+        ssl->specs.hash_size             = WC_SHA256_DIGEST_SIZE;
+        ssl->specs.pad_size              = PAD_SHA;
+        ssl->specs.static_ecdh           = 0;
+        ssl->specs.key_size              = AES_128_KEY_SIZE;
+        ssl->specs.block_size            = AES_BLOCK_SIZE;
+        ssl->specs.iv_size               = AES_IV_SIZE;
+
+        ssl->options.usingPSK_cipher     = 1;
+        break;
+#endif
+
+#ifdef BUILD_TLS_PSK_WITH_AES_256_CBC_SHA384
+    case TLS_PSK_WITH_AES_256_CBC_SHA384 :
+        ssl->specs.bulk_cipher_algorithm = wolfssl_aes;
+        ssl->specs.cipher_type           = block;
+        ssl->specs.mac_algorithm         = sha384_mac;
+        ssl->specs.kea                   = psk_kea;
+        ssl->specs.sig_algo              = anonymous_sa_algo;
+        ssl->specs.hash_size             = WC_SHA384_DIGEST_SIZE;
+        ssl->specs.pad_size              = PAD_SHA;
+        ssl->specs.static_ecdh           = 0;
+        ssl->specs.key_size              = AES_256_KEY_SIZE;
+        ssl->specs.block_size            = AES_BLOCK_SIZE;
+        ssl->specs.iv_size               = AES_IV_SIZE;
+
+        ssl->options.usingPSK_cipher     = 1;
+        break;
+#endif
+
+#ifdef BUILD_TLS_DHE_PSK_WITH_AES_128_CBC_SHA256
+    case TLS_DHE_PSK_WITH_AES_128_CBC_SHA256 :
+        ssl->specs.bulk_cipher_algorithm = wolfssl_aes;
+        ssl->specs.cipher_type           = block;
+        ssl->specs.mac_algorithm         = sha256_mac;
+        ssl->specs.kea                   = dhe_psk_kea;
+        ssl->specs.sig_algo              = anonymous_sa_algo;
+        ssl->specs.hash_size             = WC_SHA256_DIGEST_SIZE;
+        ssl->specs.pad_size              = PAD_SHA;
+        ssl->specs.static_ecdh           = 0;
+        ssl->specs.key_size              = AES_128_KEY_SIZE;
+        ssl->specs.block_size            = AES_BLOCK_SIZE;
+        ssl->specs.iv_size               = AES_IV_SIZE;
+
+        ssl->options.usingPSK_cipher     = 1;
+        break;
+#endif
+
+#ifdef BUILD_TLS_DHE_PSK_WITH_AES_256_CBC_SHA384
+    case TLS_DHE_PSK_WITH_AES_256_CBC_SHA384 :
+        ssl->specs.bulk_cipher_algorithm = wolfssl_aes;
+        ssl->specs.cipher_type           = block;
+        ssl->specs.mac_algorithm         = sha384_mac;
+        ssl->specs.kea                   = dhe_psk_kea;
+        ssl->specs.sig_algo              = anonymous_sa_algo;
+        ssl->specs.hash_size             = WC_SHA384_DIGEST_SIZE;
+        ssl->specs.pad_size              = PAD_SHA;
+        ssl->specs.static_ecdh           = 0;
+        ssl->specs.key_size              = AES_256_KEY_SIZE;
+        ssl->specs.block_size            = AES_BLOCK_SIZE;
+        ssl->specs.iv_size               = AES_IV_SIZE;
+
+        ssl->options.usingPSK_cipher     = 1;
+        break;
+#endif
+
+#ifdef BUILD_TLS_PSK_WITH_AES_128_CBC_SHA
+    case TLS_PSK_WITH_AES_128_CBC_SHA :
+        ssl->specs.bulk_cipher_algorithm = wolfssl_aes;
+        ssl->specs.cipher_type           = block;
+        ssl->specs.mac_algorithm         = sha_mac;
+        ssl->specs.kea                   = psk_kea;
+        ssl->specs.sig_algo              = anonymous_sa_algo;
+        ssl->specs.hash_size             = WC_SHA_DIGEST_SIZE;
+        ssl->specs.pad_size              = PAD_SHA;
+        ssl->specs.static_ecdh           = 0;
+        ssl->specs.key_size              = AES_128_KEY_SIZE;
+        ssl->specs.block_size            = AES_BLOCK_SIZE;
+        ssl->specs.iv_size               = AES_IV_SIZE;
+
+        ssl->options.usingPSK_cipher     = 1;
+        break;
+#endif
+
+#ifdef BUILD_TLS_PSK_WITH_AES_256_CBC_SHA
+    case TLS_PSK_WITH_AES_256_CBC_SHA :
+        ssl->specs.bulk_cipher_algorithm = wolfssl_aes;
+        ssl->specs.cipher_type           = block;
+        ssl->specs.mac_algorithm         = sha_mac;
+        ssl->specs.kea                   = psk_kea;
+        ssl->specs.sig_algo              = anonymous_sa_algo;
+        ssl->specs.hash_size             = WC_SHA_DIGEST_SIZE;
+        ssl->specs.pad_size              = PAD_SHA;
+        ssl->specs.static_ecdh           = 0;
+        ssl->specs.key_size              = AES_256_KEY_SIZE;
+        ssl->specs.block_size            = AES_BLOCK_SIZE;
+        ssl->specs.iv_size               = AES_IV_SIZE;
+
+        ssl->options.usingPSK_cipher     = 1;
+        break;
+#endif
+
+#ifdef BUILD_TLS_PSK_WITH_NULL_SHA256
+    case TLS_PSK_WITH_NULL_SHA256 :
+        ssl->specs.bulk_cipher_algorithm = wolfssl_cipher_null;
+        ssl->specs.cipher_type           = stream;
+        ssl->specs.mac_algorithm         = sha256_mac;
+        ssl->specs.kea                   = psk_kea;
+        ssl->specs.sig_algo              = anonymous_sa_algo;
+        ssl->specs.hash_size             = WC_SHA256_DIGEST_SIZE;
+        ssl->specs.pad_size              = PAD_SHA;
+        ssl->specs.static_ecdh           = 0;
+        ssl->specs.key_size              = 0;
+        ssl->specs.block_size            = 0;
+        ssl->specs.iv_size               = 0;
+
+        ssl->options.usingPSK_cipher     = 1;
+        break;
+#endif
+
+#ifdef BUILD_TLS_PSK_WITH_NULL_SHA384
+    case TLS_PSK_WITH_NULL_SHA384 :
+        ssl->specs.bulk_cipher_algorithm = wolfssl_cipher_null;
+        ssl->specs.cipher_type           = stream;
+        ssl->specs.mac_algorithm         = sha384_mac;
+        ssl->specs.kea                   = psk_kea;
+        ssl->specs.sig_algo              = anonymous_sa_algo;
+        ssl->specs.hash_size             = WC_SHA384_DIGEST_SIZE;
+        ssl->specs.pad_size              = PAD_SHA;
+        ssl->specs.static_ecdh           = 0;
+        ssl->specs.key_size              = 0;
+        ssl->specs.block_size            = 0;
+        ssl->specs.iv_size               = 0;
+
+        ssl->options.usingPSK_cipher     = 1;
+        break;
+#endif
+
+#ifdef BUILD_TLS_PSK_WITH_NULL_SHA
+    case TLS_PSK_WITH_NULL_SHA :
+        ssl->specs.bulk_cipher_algorithm = wolfssl_cipher_null;
+        ssl->specs.cipher_type           = stream;
+        ssl->specs.mac_algorithm         = sha_mac;
+        ssl->specs.kea                   = psk_kea;
+        ssl->specs.sig_algo              = anonymous_sa_algo;
+        ssl->specs.hash_size             = WC_SHA_DIGEST_SIZE;
+        ssl->specs.pad_size              = PAD_SHA;
+        ssl->specs.static_ecdh           = 0;
+        ssl->specs.key_size              = 0;
+        ssl->specs.block_size            = 0;
+        ssl->specs.iv_size               = 0;
+
+        ssl->options.usingPSK_cipher     = 1;
+        break;
+#endif
+
+#ifdef BUILD_TLS_DHE_PSK_WITH_NULL_SHA256
+    case TLS_DHE_PSK_WITH_NULL_SHA256 :
+        ssl->specs.bulk_cipher_algorithm = wolfssl_cipher_null;
+        ssl->specs.cipher_type           = stream;
+        ssl->specs.mac_algorithm         = sha256_mac;
+        ssl->specs.kea                   = dhe_psk_kea;
+        ssl->specs.sig_algo              = anonymous_sa_algo;
+        ssl->specs.hash_size             = WC_SHA256_DIGEST_SIZE;
+        ssl->specs.pad_size              = PAD_SHA;
+        ssl->specs.static_ecdh           = 0;
+        ssl->specs.key_size              = 0;
+        ssl->specs.block_size            = 0;
+        ssl->specs.iv_size               = 0;
+
+        ssl->options.usingPSK_cipher     = 1;
+        break;
+#endif
+
+#ifdef BUILD_TLS_DHE_PSK_WITH_NULL_SHA384
+    case TLS_DHE_PSK_WITH_NULL_SHA384 :
+        ssl->specs.bulk_cipher_algorithm = wolfssl_cipher_null;
+        ssl->specs.cipher_type           = stream;
+        ssl->specs.mac_algorithm         = sha384_mac;
+        ssl->specs.kea                   = dhe_psk_kea;
+        ssl->specs.sig_algo              = anonymous_sa_algo;
+        ssl->specs.hash_size             = WC_SHA384_DIGEST_SIZE;
+        ssl->specs.pad_size              = PAD_SHA;
+        ssl->specs.static_ecdh           = 0;
+        ssl->specs.key_size              = 0;
+        ssl->specs.block_size            = 0;
+        ssl->specs.iv_size               = 0;
+
+        ssl->options.usingPSK_cipher     = 1;
+        break;
+#endif
+
+#ifdef BUILD_TLS_DHE_RSA_WITH_AES_128_CBC_SHA256
+    case TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 :
+        ssl->specs.bulk_cipher_algorithm = wolfssl_aes;
+        ssl->specs.cipher_type           = block;
+        ssl->specs.mac_algorithm         = sha256_mac;
+        ssl->specs.kea                   = diffie_hellman_kea;
+        ssl->specs.sig_algo              = rsa_sa_algo;
+        ssl->specs.hash_size             = WC_SHA256_DIGEST_SIZE;
+        ssl->specs.pad_size              = PAD_SHA;
+        ssl->specs.static_ecdh           = 0;
+        ssl->specs.key_size              = AES_128_KEY_SIZE;
+        ssl->specs.block_size            = AES_BLOCK_SIZE;
+        ssl->specs.iv_size               = AES_IV_SIZE;
+
+        break;
+#endif
+
+#ifdef BUILD_TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA
+    case TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA :
+        ssl->specs.bulk_cipher_algorithm = wolfssl_triple_des;
+        ssl->specs.cipher_type           = block;
+        ssl->specs.mac_algorithm         = sha_mac;
+        ssl->specs.kea                   = diffie_hellman_kea;
+        ssl->specs.sig_algo              = rsa_sa_algo;
+        ssl->specs.hash_size             = WC_SHA_DIGEST_SIZE;
+        ssl->specs.pad_size              = PAD_SHA;
+        ssl->specs.static_ecdh           = 0;
+        ssl->specs.key_size              = DES3_KEY_SIZE;
+        ssl->specs.block_size            = DES_BLOCK_SIZE;
+        ssl->specs.iv_size               = DES_IV_SIZE;
+
+        break;
+#endif
+
+#ifdef BUILD_TLS_DHE_RSA_WITH_AES_256_CBC_SHA256
+    case TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 :
+        ssl->specs.bulk_cipher_algorithm = wolfssl_aes;
+        ssl->specs.cipher_type           = block;
+        ssl->specs.mac_algorithm         = sha256_mac;
+        ssl->specs.kea                   = diffie_hellman_kea;
+        ssl->specs.sig_algo              = rsa_sa_algo;
+        ssl->specs.hash_size             = WC_SHA256_DIGEST_SIZE;
+        ssl->specs.pad_size              = PAD_SHA;
+        ssl->specs.static_ecdh           = 0;
+        ssl->specs.key_size              = AES_256_KEY_SIZE;
+        ssl->specs.block_size            = AES_BLOCK_SIZE;
+        ssl->specs.iv_size               = AES_IV_SIZE;
+
+        break;
+#endif
+
+#ifdef BUILD_TLS_DHE_RSA_WITH_AES_128_CBC_SHA
+    case TLS_DHE_RSA_WITH_AES_128_CBC_SHA :
+        ssl->specs.bulk_cipher_algorithm = wolfssl_aes;
+        ssl->specs.cipher_type           = block;
+        ssl->specs.mac_algorithm         = sha_mac;
+        ssl->specs.kea                   = diffie_hellman_kea;
+        ssl->specs.sig_algo              = rsa_sa_algo;
+        ssl->specs.hash_size             = WC_SHA_DIGEST_SIZE;
+        ssl->specs.pad_size              = PAD_SHA;
+        ssl->specs.static_ecdh           = 0;
+        ssl->specs.key_size              = AES_128_KEY_SIZE;
+        ssl->specs.block_size            = AES_BLOCK_SIZE;
+        ssl->specs.iv_size               = AES_IV_SIZE;
+
+        break;
+#endif
+
+#ifdef BUILD_TLS_DHE_RSA_WITH_AES_256_CBC_SHA
+    case TLS_DHE_RSA_WITH_AES_256_CBC_SHA :
+        ssl->specs.bulk_cipher_algorithm = wolfssl_aes;
+        ssl->specs.cipher_type           = block;
+        ssl->specs.mac_algorithm         = sha_mac;
+        ssl->specs.kea                   = diffie_hellman_kea;
+        ssl->specs.sig_algo              = rsa_sa_algo;
+        ssl->specs.hash_size             = WC_SHA_DIGEST_SIZE;
+        ssl->specs.pad_size              = PAD_SHA;
+        ssl->specs.static_ecdh           = 0;
+        ssl->specs.key_size              = AES_256_KEY_SIZE;
+        ssl->specs.block_size            = AES_BLOCK_SIZE;
+        ssl->specs.iv_size               = AES_IV_SIZE;
+
+        break;
+#endif
+
+#ifdef BUILD_TLS_RSA_WITH_HC_128_MD5
+    case TLS_RSA_WITH_HC_128_MD5 :
+        ssl->specs.bulk_cipher_algorithm = wolfssl_hc128;
+        ssl->specs.cipher_type           = stream;
+        ssl->specs.mac_algorithm         = md5_mac;
+        ssl->specs.kea                   = rsa_kea;
+        ssl->specs.sig_algo              = rsa_sa_algo;
+        ssl->specs.hash_size             = WC_MD5_DIGEST_SIZE;
+        ssl->specs.pad_size              = PAD_MD5;
+        ssl->specs.static_ecdh           = 0;
+        ssl->specs.key_size              = HC_128_KEY_SIZE;
+        ssl->specs.block_size            = 0;
+        ssl->specs.iv_size               = HC_128_IV_SIZE;
+
+        break;
+#endif
+
+#ifdef BUILD_TLS_RSA_WITH_HC_128_SHA
+        case TLS_RSA_WITH_HC_128_SHA :
+            ssl->specs.bulk_cipher_algorithm = wolfssl_hc128;
+            ssl->specs.cipher_type           = stream;
+            ssl->specs.mac_algorithm         = sha_mac;
+            ssl->specs.kea                   = rsa_kea;
+            ssl->specs.sig_algo              = rsa_sa_algo;
+            ssl->specs.hash_size             = WC_SHA_DIGEST_SIZE;
+            ssl->specs.pad_size              = PAD_SHA;
+            ssl->specs.static_ecdh           = 0;
+            ssl->specs.key_size              = HC_128_KEY_SIZE;
+            ssl->specs.block_size            = 0;
+            ssl->specs.iv_size               = HC_128_IV_SIZE;
+
+            break;
+#endif
+
+#ifdef BUILD_TLS_RSA_WITH_RABBIT_SHA
+    case TLS_RSA_WITH_RABBIT_SHA :
+        ssl->specs.bulk_cipher_algorithm = wolfssl_rabbit;
+        ssl->specs.cipher_type           = stream;
+        ssl->specs.mac_algorithm         = sha_mac;
+        ssl->specs.kea                   = rsa_kea;
+        ssl->specs.sig_algo              = rsa_sa_algo;
+        ssl->specs.hash_size             = WC_SHA_DIGEST_SIZE;
+        ssl->specs.pad_size              = PAD_SHA;
+        ssl->specs.static_ecdh           = 0;
+        ssl->specs.key_size              = RABBIT_KEY_SIZE;
+        ssl->specs.block_size            = 0;
+        ssl->specs.iv_size               = RABBIT_IV_SIZE;
+
+        break;
+#endif
+
+#ifdef BUILD_TLS_RSA_WITH_AES_128_GCM_SHA256
+    case TLS_RSA_WITH_AES_128_GCM_SHA256 :
+        ssl->specs.bulk_cipher_algorithm = wolfssl_aes_gcm;
+        ssl->specs.cipher_type           = aead;
+        ssl->specs.mac_algorithm         = sha256_mac;
+        ssl->specs.kea                   = rsa_kea;
+        ssl->specs.sig_algo              = rsa_sa_algo;
+        ssl->specs.hash_size             = WC_SHA256_DIGEST_SIZE;
+        ssl->specs.pad_size              = PAD_SHA;
+        ssl->specs.static_ecdh           = 0;
+        ssl->specs.key_size              = AES_128_KEY_SIZE;
+        ssl->specs.block_size            = AES_BLOCK_SIZE;
+        ssl->specs.iv_size               = AESGCM_IMP_IV_SZ;
+        ssl->specs.aead_mac_size         = AES_GCM_AUTH_SZ;
+
+        break;
+#endif
+
+#ifdef BUILD_TLS_RSA_WITH_AES_256_GCM_SHA384
+    case TLS_RSA_WITH_AES_256_GCM_SHA384 :
+        ssl->specs.bulk_cipher_algorithm = wolfssl_aes_gcm;
+        ssl->specs.cipher_type           = aead;
+        ssl->specs.mac_algorithm         = sha384_mac;
+        ssl->specs.kea                   = rsa_kea;
+        ssl->specs.sig_algo              = rsa_sa_algo;
+        ssl->specs.hash_size             = WC_SHA384_DIGEST_SIZE;
+        ssl->specs.pad_size              = PAD_SHA;
+        ssl->specs.static_ecdh           = 0;
+        ssl->specs.key_size              = AES_256_KEY_SIZE;
+        ssl->specs.block_size            = AES_BLOCK_SIZE;
+        ssl->specs.iv_size               = AESGCM_IMP_IV_SZ;
+        ssl->specs.aead_mac_size         = AES_GCM_AUTH_SZ;
+
+        break;
+#endif
+
+#ifdef BUILD_TLS_DHE_RSA_WITH_AES_128_GCM_SHA256
+    case TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 :
+        ssl->specs.bulk_cipher_algorithm = wolfssl_aes_gcm;
+        ssl->specs.cipher_type           = aead;
+        ssl->specs.mac_algorithm         = sha256_mac;
+        ssl->specs.kea                   = diffie_hellman_kea;
+        ssl->specs.sig_algo              = rsa_sa_algo;
+        ssl->specs.hash_size             = WC_SHA256_DIGEST_SIZE;
+        ssl->specs.pad_size              = PAD_SHA;
+        ssl->specs.static_ecdh           = 0;
+        ssl->specs.key_size              = AES_128_KEY_SIZE;
+        ssl->specs.block_size            = AES_BLOCK_SIZE;
+        ssl->specs.iv_size               = AESGCM_IMP_IV_SZ;
+        ssl->specs.aead_mac_size         = AES_GCM_AUTH_SZ;
+
+        break;
+#endif
+
+#ifdef BUILD_TLS_DHE_RSA_WITH_AES_256_GCM_SHA384
+    case TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 :
+        ssl->specs.bulk_cipher_algorithm = wolfssl_aes_gcm;
+        ssl->specs.cipher_type           = aead;
+        ssl->specs.mac_algorithm         = sha384_mac;
+        ssl->specs.kea                   = diffie_hellman_kea;
+        ssl->specs.sig_algo              = rsa_sa_algo;
+        ssl->specs.hash_size             = WC_SHA384_DIGEST_SIZE;
+        ssl->specs.pad_size              = PAD_SHA;
+        ssl->specs.static_ecdh           = 0;
+        ssl->specs.key_size              = AES_256_KEY_SIZE;
+        ssl->specs.block_size            = AES_BLOCK_SIZE;
+        ssl->specs.iv_size               = AESGCM_IMP_IV_SZ;
+        ssl->specs.aead_mac_size         = AES_GCM_AUTH_SZ;
+
+        break;
+#endif
+
+#ifdef BUILD_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA
+    case TLS_RSA_WITH_CAMELLIA_128_CBC_SHA :
+        ssl->specs.bulk_cipher_algorithm = wolfssl_camellia;
+        ssl->specs.cipher_type           = block;
+        ssl->specs.mac_algorithm         = sha_mac;
+        ssl->specs.kea                   = rsa_kea;
+        ssl->specs.sig_algo              = rsa_sa_algo;
+        ssl->specs.hash_size             = WC_SHA_DIGEST_SIZE;
+        ssl->specs.pad_size              = PAD_SHA;
+        ssl->specs.static_ecdh           = 0;
+        ssl->specs.key_size              = CAMELLIA_128_KEY_SIZE;
+        ssl->specs.block_size            = CAMELLIA_BLOCK_SIZE;
+        ssl->specs.iv_size               = CAMELLIA_IV_SIZE;
+
+        break;
+#endif
+
+#ifdef BUILD_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA
+    case TLS_RSA_WITH_CAMELLIA_256_CBC_SHA :
+        ssl->specs.bulk_cipher_algorithm = wolfssl_camellia;
+        ssl->specs.cipher_type           = block;
+        ssl->specs.mac_algorithm         = sha_mac;
+        ssl->specs.kea                   = rsa_kea;
+        ssl->specs.sig_algo              = rsa_sa_algo;
+        ssl->specs.hash_size             = WC_SHA_DIGEST_SIZE;
+        ssl->specs.pad_size              = PAD_SHA;
+        ssl->specs.static_ecdh           = 0;
+        ssl->specs.key_size              = CAMELLIA_256_KEY_SIZE;
+        ssl->specs.block_size            = CAMELLIA_BLOCK_SIZE;
+        ssl->specs.iv_size               = CAMELLIA_IV_SIZE;
+
+        break;
+#endif
+
+#ifdef BUILD_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256
+    case TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256 :
+        ssl->specs.bulk_cipher_algorithm = wolfssl_camellia;
+        ssl->specs.cipher_type           = block;
+        ssl->specs.mac_algorithm         = sha256_mac;
+        ssl->specs.kea                   = rsa_kea;
+        ssl->specs.sig_algo              = rsa_sa_algo;
+        ssl->specs.hash_size             = WC_SHA256_DIGEST_SIZE;
+        ssl->specs.pad_size              = PAD_SHA;
+        ssl->specs.static_ecdh           = 0;
+        ssl->specs.key_size              = CAMELLIA_128_KEY_SIZE;
+        ssl->specs.block_size            = CAMELLIA_BLOCK_SIZE;
+        ssl->specs.iv_size               = CAMELLIA_IV_SIZE;
+
+        break;
+#endif
+
+#ifdef BUILD_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256
+    case TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256 :
+        ssl->specs.bulk_cipher_algorithm = wolfssl_camellia;
+        ssl->specs.cipher_type           = block;
+        ssl->specs.mac_algorithm         = sha256_mac;
+        ssl->specs.kea                   = rsa_kea;
+        ssl->specs.sig_algo              = rsa_sa_algo;
+        ssl->specs.hash_size             = WC_SHA256_DIGEST_SIZE;
+        ssl->specs.pad_size              = PAD_SHA;
+        ssl->specs.static_ecdh           = 0;
+        ssl->specs.key_size              = CAMELLIA_256_KEY_SIZE;
+        ssl->specs.block_size            = CAMELLIA_BLOCK_SIZE;
+        ssl->specs.iv_size               = CAMELLIA_IV_SIZE;
+
+        break;
+#endif
+
+#ifdef BUILD_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA
+    case TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA :
+        ssl->specs.bulk_cipher_algorithm = wolfssl_camellia;
+        ssl->specs.cipher_type           = block;
+        ssl->specs.mac_algorithm         = sha_mac;
+        ssl->specs.kea                   = diffie_hellman_kea;
+        ssl->specs.sig_algo              = rsa_sa_algo;
+        ssl->specs.hash_size             = WC_SHA_DIGEST_SIZE;
+        ssl->specs.pad_size              = PAD_SHA;
+        ssl->specs.static_ecdh           = 0;
+        ssl->specs.key_size              = CAMELLIA_128_KEY_SIZE;
+        ssl->specs.block_size            = CAMELLIA_BLOCK_SIZE;
+        ssl->specs.iv_size               = CAMELLIA_IV_SIZE;
+
+        break;
+#endif
+
+#ifdef BUILD_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA
+    case TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA :
+        ssl->specs.bulk_cipher_algorithm = wolfssl_camellia;
+        ssl->specs.cipher_type           = block;
+        ssl->specs.mac_algorithm         = sha_mac;
+        ssl->specs.kea                   = diffie_hellman_kea;
+        ssl->specs.sig_algo              = rsa_sa_algo;
+        ssl->specs.hash_size             = WC_SHA_DIGEST_SIZE;
+        ssl->specs.pad_size              = PAD_SHA;
+        ssl->specs.static_ecdh           = 0;
+        ssl->specs.key_size              = CAMELLIA_256_KEY_SIZE;
+        ssl->specs.block_size            = CAMELLIA_BLOCK_SIZE;
+        ssl->specs.iv_size               = CAMELLIA_IV_SIZE;
+
+        break;
+#endif
+
+#ifdef BUILD_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256
+    case TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256 :
+        ssl->specs.bulk_cipher_algorithm = wolfssl_camellia;
+        ssl->specs.cipher_type           = block;
+        ssl->specs.mac_algorithm         = sha256_mac;
+        ssl->specs.kea                   = diffie_hellman_kea;
+        ssl->specs.sig_algo              = rsa_sa_algo;
+        ssl->specs.hash_size             = WC_SHA256_DIGEST_SIZE;
+        ssl->specs.pad_size              = PAD_SHA;
+        ssl->specs.static_ecdh           = 0;
+        ssl->specs.key_size              = CAMELLIA_128_KEY_SIZE;
+        ssl->specs.block_size            = CAMELLIA_BLOCK_SIZE;
+        ssl->specs.iv_size               = CAMELLIA_IV_SIZE;
+
+        break;
+#endif
+
+#ifdef BUILD_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256
+    case TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256 :
+        ssl->specs.bulk_cipher_algorithm = wolfssl_camellia;
+        ssl->specs.cipher_type           = block;
+        ssl->specs.mac_algorithm         = sha256_mac;
+        ssl->specs.kea                   = diffie_hellman_kea;
+        ssl->specs.sig_algo              = rsa_sa_algo;
+        ssl->specs.hash_size             = WC_SHA256_DIGEST_SIZE;
+        ssl->specs.pad_size              = PAD_SHA;
+        ssl->specs.static_ecdh           = 0;
+        ssl->specs.key_size              = CAMELLIA_256_KEY_SIZE;
+        ssl->specs.block_size            = CAMELLIA_BLOCK_SIZE;
+        ssl->specs.iv_size               = CAMELLIA_IV_SIZE;
+
+        break;
+#endif
+
+#ifdef BUILD_TLS_DH_anon_WITH_AES_128_CBC_SHA
+    case TLS_DH_anon_WITH_AES_128_CBC_SHA :
+        ssl->specs.bulk_cipher_algorithm = wolfssl_aes;
+        ssl->specs.cipher_type           = block;
+        ssl->specs.mac_algorithm         = sha_mac;
+        ssl->specs.kea                   = diffie_hellman_kea;
+        ssl->specs.sig_algo              = anonymous_sa_algo;
+        ssl->specs.hash_size             = WC_SHA_DIGEST_SIZE;
+        ssl->specs.pad_size              = PAD_SHA;
+        ssl->specs.static_ecdh           = 0;
+        ssl->specs.key_size              = AES_128_KEY_SIZE;
+        ssl->specs.block_size            = AES_BLOCK_SIZE;
+        ssl->specs.iv_size               = AES_IV_SIZE;
+
+        ssl->options.usingAnon_cipher    = 1;
+        break;
+#endif
+
+#ifdef BUILD_SSL_RSA_WITH_IDEA_CBC_SHA
+        case SSL_RSA_WITH_IDEA_CBC_SHA :
+            ssl->specs.bulk_cipher_algorithm = wolfssl_idea;
+            ssl->specs.cipher_type           = block;
+            ssl->specs.mac_algorithm         = sha_mac;
+            ssl->specs.kea                   = rsa_kea;
+            ssl->specs.sig_algo              = rsa_sa_algo;
+            ssl->specs.hash_size             = WC_SHA_DIGEST_SIZE;
+            ssl->specs.pad_size              = PAD_SHA;
+            ssl->specs.static_ecdh           = 0;
+            ssl->specs.key_size              = IDEA_KEY_SIZE;
+            ssl->specs.block_size            = IDEA_BLOCK_SIZE;
+            ssl->specs.iv_size               = IDEA_IV_SIZE;
+
+            break;
+#endif
+
+#ifdef BUILD_WDM_WITH_NULL_SHA256
+        case WDM_WITH_NULL_SHA256 :
+            ssl->specs.bulk_cipher_algorithm = wolfssl_cipher_null;
+            ssl->specs.cipher_type           = stream;
+            ssl->specs.mac_algorithm         = sha256_mac;
+            ssl->specs.kea                   = no_kea;
+            ssl->specs.sig_algo              = anonymous_sa_algo;
+            ssl->specs.hash_size             = WC_SHA256_DIGEST_SIZE;
+            ssl->specs.pad_size              = PAD_SHA;
+
+            break;
+#endif
+
+    default:
+        WOLFSSL_MSG("Unsupported cipher suite, SetCipherSpecs");
+        return UNSUPPORTED_SUITE;
+    }  /* switch */
+    }  /* if ECC / Normal suites else */
+
+    /* set TLS if it hasn't been turned off */
+    if (ssl->version.major == 3 && ssl->version.minor >= 1) {
+#ifndef NO_TLS
+        ssl->options.tls = 1;
+    #if !defined(WOLFSSL_NO_TLS12) && !defined(WOLFSSL_AEAD_ONLY)
+        ssl->hmac = TLS_hmac;
+    #endif
+        if (ssl->version.minor >= 2) {
+            ssl->options.tls1_1 = 1;
+            if (ssl->version.minor >= 4)
+                ssl->options.tls1_3 = 1;
+        }
+#endif
+    }
+
+#if defined(HAVE_ENCRYPT_THEN_MAC) && !defined(WOLFSSL_AEAD_ONLY)
+    if (IsAtLeastTLSv1_3(ssl->version) || ssl->specs.cipher_type != block)
+       ssl->options.encThenMac = 0;
+#endif
+
+#if defined(WOLFSSL_DTLS) && !defined(WOLFSSL_AEAD_ONLY)
+    if (ssl->options.dtls)
+        ssl->hmac = TLS_hmac;
+#endif
+
+    return 0;
+}
+
+
+enum KeyStuff {
+    MASTER_ROUNDS = 3,
+    PREFIX        = 3,     /* up to three letters for master prefix */
+    KEY_PREFIX    = 9      /* up to 9 prefix letters for key rounds */
+
+
+};
+
+#ifndef NO_OLD_TLS
+/* true or false, zero for error */
+static int SetPrefix(byte* sha_input, int idx)
+{
+    switch (idx) {
+    case 0:
+        XMEMCPY(sha_input, "A", 1);
+        break;
+    case 1:
+        XMEMCPY(sha_input, "BB", 2);
+        break;
+    case 2:
+        XMEMCPY(sha_input, "CCC", 3);
+        break;
+    case 3:
+        XMEMCPY(sha_input, "DDDD", 4);
+        break;
+    case 4:
+        XMEMCPY(sha_input, "EEEEE", 5);
+        break;
+    case 5:
+        XMEMCPY(sha_input, "FFFFFF", 6);
+        break;
+    case 6:
+        XMEMCPY(sha_input, "GGGGGGG", 7);
+        break;
+    case 7:
+        XMEMCPY(sha_input, "HHHHHHHH", 8);
+        break;
+    case 8:
+        XMEMCPY(sha_input, "IIIIIIIII", 9);
+        break;
+    default:
+        WOLFSSL_MSG("Set Prefix error, bad input");
+        return 0;
+    }
+    return 1;
+}
+#endif
+
+
+static int SetKeys(Ciphers* enc, Ciphers* dec, Keys* keys, CipherSpecs* specs,
+                   int side, void* heap, int devId, WC_RNG* rng, int tls13)
+{
+    (void)rng;
+    (void)tls13;
+
+#ifdef BUILD_ARC4
+    if (specs->bulk_cipher_algorithm == wolfssl_rc4) {
+        word32 sz = specs->key_size;
+        if (enc && enc->arc4 == NULL) {
+            enc->arc4 = (Arc4*)XMALLOC(sizeof(Arc4), heap, DYNAMIC_TYPE_CIPHER);
+            if (enc->arc4 == NULL)
+                 return MEMORY_E;
+        }
+        if (dec && dec->arc4 == NULL) {
+            dec->arc4 = (Arc4*)XMALLOC(sizeof(Arc4), heap, DYNAMIC_TYPE_CIPHER);
+            if (dec->arc4 == NULL)
+                return MEMORY_E;
+        }
+
+        if (enc) {
+            if (wc_Arc4Init(enc->arc4, heap, devId) != 0) {
+                WOLFSSL_MSG("Arc4Init failed in SetKeys");
+                return ASYNC_INIT_E;
+            }
+        }
+        if (dec) {
+            if (wc_Arc4Init(dec->arc4, heap, devId) != 0) {
+                WOLFSSL_MSG("Arc4Init failed in SetKeys");
+                return ASYNC_INIT_E;
+            }
+        }
+
+        if (side == WOLFSSL_CLIENT_END) {
+            if (enc)
+                wc_Arc4SetKey(enc->arc4, keys->client_write_key, sz);
+            if (dec)
+                wc_Arc4SetKey(dec->arc4, keys->server_write_key, sz);
+        }
+        else {
+            if (enc)
+                wc_Arc4SetKey(enc->arc4, keys->server_write_key, sz);
+            if (dec)
+                wc_Arc4SetKey(dec->arc4, keys->client_write_key, sz);
+        }
+        if (enc)
+            enc->setup = 1;
+        if (dec)
+            dec->setup = 1;
+    }
+#endif /* BUILD_ARC4 */
+
+
+#if defined(HAVE_CHACHA) && defined(HAVE_POLY1305)
+    /* Check that the max implicit iv size is suffecient */
+    #if (AEAD_MAX_IMP_SZ < 12) /* CHACHA20_IMP_IV_SZ */
+        #error AEAD_MAX_IMP_SZ is too small for ChaCha20
+    #endif
+    #if (MAX_WRITE_IV_SZ < 12) /* CHACHA20_IMP_IV_SZ */
+        #error MAX_WRITE_IV_SZ is too small for ChaCha20
+    #endif
+
+    if (specs->bulk_cipher_algorithm == wolfssl_chacha) {
+        int chachaRet;
+        if (enc && enc->chacha == NULL)
+            enc->chacha =
+                    (ChaCha*)XMALLOC(sizeof(ChaCha), heap, DYNAMIC_TYPE_CIPHER);
+        if (enc && enc->chacha == NULL)
+            return MEMORY_E;
+        if (dec && dec->chacha == NULL)
+            dec->chacha =
+                    (ChaCha*)XMALLOC(sizeof(ChaCha), heap, DYNAMIC_TYPE_CIPHER);
+        if (dec && dec->chacha == NULL)
+            return MEMORY_E;
+        if (side == WOLFSSL_CLIENT_END) {
+            if (enc) {
+                chachaRet = wc_Chacha_SetKey(enc->chacha, keys->client_write_key,
+                                          specs->key_size);
+                XMEMCPY(keys->aead_enc_imp_IV, keys->client_write_IV,
+                        CHACHA20_IMP_IV_SZ);
+                if (chachaRet != 0) return chachaRet;
+            }
+            if (dec) {
+                chachaRet = wc_Chacha_SetKey(dec->chacha, keys->server_write_key,
+                                          specs->key_size);
+                XMEMCPY(keys->aead_dec_imp_IV, keys->server_write_IV,
+                        CHACHA20_IMP_IV_SZ);
+                if (chachaRet != 0) return chachaRet;
+            }
+        }
+        else {
+            if (enc) {
+                chachaRet = wc_Chacha_SetKey(enc->chacha, keys->server_write_key,
+                                          specs->key_size);
+                XMEMCPY(keys->aead_enc_imp_IV, keys->server_write_IV,
+                        CHACHA20_IMP_IV_SZ);
+                if (chachaRet != 0) return chachaRet;
+            }
+            if (dec) {
+                chachaRet = wc_Chacha_SetKey(dec->chacha, keys->client_write_key,
+                                          specs->key_size);
+                XMEMCPY(keys->aead_dec_imp_IV, keys->client_write_IV,
+                        CHACHA20_IMP_IV_SZ);
+                if (chachaRet != 0) return chachaRet;
+            }
+        }
+
+        if (enc)
+            enc->setup = 1;
+        if (dec)
+            dec->setup = 1;
+    }
+#endif /* HAVE_CHACHA && HAVE_POLY1305 */
+
+
+#ifdef HAVE_HC128
+    /* check that buffer sizes are sufficient */
+    #if (MAX_WRITE_IV_SZ < 16) /* HC_128_IV_SIZE */
+        #error MAX_WRITE_IV_SZ too small for HC128
+    #endif
+
+    if (specs->bulk_cipher_algorithm == wolfssl_hc128) {
+        int hcRet;
+        if (enc && enc->hc128 == NULL)
+            enc->hc128 =
+                      (HC128*)XMALLOC(sizeof(HC128), heap, DYNAMIC_TYPE_CIPHER);
+        if (enc && enc->hc128 == NULL)
+            return MEMORY_E;
+        if (dec && dec->hc128 == NULL)
+            dec->hc128 =
+                      (HC128*)XMALLOC(sizeof(HC128), heap, DYNAMIC_TYPE_CIPHER);
+        if (dec && dec->hc128 == NULL)
+            return MEMORY_E;
+        if (side == WOLFSSL_CLIENT_END) {
+            if (enc) {
+                hcRet = wc_Hc128_SetKey(enc->hc128, keys->client_write_key,
+                                     keys->client_write_IV);
+                if (hcRet != 0) return hcRet;
+            }
+            if (dec) {
+                hcRet = wc_Hc128_SetKey(dec->hc128, keys->server_write_key,
+                                     keys->server_write_IV);
+                if (hcRet != 0) return hcRet;
+            }
+        }
+        else {
+            if (enc) {
+                hcRet = wc_Hc128_SetKey(enc->hc128, keys->server_write_key,
+                                     keys->server_write_IV);
+                if (hcRet != 0) return hcRet;
+            }
+            if (dec) {
+                hcRet = wc_Hc128_SetKey(dec->hc128, keys->client_write_key,
+                                     keys->client_write_IV);
+                if (hcRet != 0) return hcRet;
+            }
+        }
+        if (enc)
+            enc->setup = 1;
+        if (dec)
+            dec->setup = 1;
+    }
+#endif /* HAVE_HC128 */
+
+#ifdef BUILD_RABBIT
+    /* check that buffer sizes are sufficient */
+    #if (MAX_WRITE_IV_SZ < 8) /* RABBIT_IV_SIZE */
+        #error MAX_WRITE_IV_SZ too small for RABBIT
+    #endif
+
+    if (specs->bulk_cipher_algorithm == wolfssl_rabbit) {
+        int rabRet;
+        if (enc && enc->rabbit == NULL)
+            enc->rabbit =
+                    (Rabbit*)XMALLOC(sizeof(Rabbit), heap, DYNAMIC_TYPE_CIPHER);
+        if (enc && enc->rabbit == NULL)
+            return MEMORY_E;
+        if (dec && dec->rabbit == NULL)
+            dec->rabbit =
+                    (Rabbit*)XMALLOC(sizeof(Rabbit), heap, DYNAMIC_TYPE_CIPHER);
+        if (dec && dec->rabbit == NULL)
+            return MEMORY_E;
+        if (side == WOLFSSL_CLIENT_END) {
+            if (enc) {
+                rabRet = wc_RabbitSetKey(enc->rabbit, keys->client_write_key,
+                                      keys->client_write_IV);
+                if (rabRet != 0) return rabRet;
+            }
+            if (dec) {
+                rabRet = wc_RabbitSetKey(dec->rabbit, keys->server_write_key,
+                                      keys->server_write_IV);
+                if (rabRet != 0) return rabRet;
+            }
+        }
+        else {
+            if (enc) {
+                rabRet = wc_RabbitSetKey(enc->rabbit, keys->server_write_key,
+                                      keys->server_write_IV);
+                if (rabRet != 0) return rabRet;
+            }
+            if (dec) {
+                rabRet = wc_RabbitSetKey(dec->rabbit, keys->client_write_key,
+                                      keys->client_write_IV);
+                if (rabRet != 0) return rabRet;
+            }
+        }
+        if (enc)
+            enc->setup = 1;
+        if (dec)
+            dec->setup = 1;
+    }
+#endif /* BUILD_RABBIT */
+
+#ifdef BUILD_DES3
+    /* check that buffer sizes are sufficient */
+    #if (MAX_WRITE_IV_SZ < 8) /* DES_IV_SIZE */
+        #error MAX_WRITE_IV_SZ too small for 3DES
+    #endif
+
+    if (specs->bulk_cipher_algorithm == wolfssl_triple_des) {
+        int desRet = 0;
+
+        if (enc) {
+            if (enc->des3 == NULL)
+                enc->des3 = (Des3*)XMALLOC(sizeof(Des3), heap, DYNAMIC_TYPE_CIPHER);
+            if (enc->des3 == NULL)
+                return MEMORY_E;
+            XMEMSET(enc->des3, 0, sizeof(Des3));
+        }
+        if (dec) {
+            if (dec->des3 == NULL)
+                dec->des3 = (Des3*)XMALLOC(sizeof(Des3), heap, DYNAMIC_TYPE_CIPHER);
+            if (dec->des3 == NULL)
+                return MEMORY_E;
+            XMEMSET(dec->des3, 0, sizeof(Des3));
+        }
+
+        if (enc) {
+            if (wc_Des3Init(enc->des3, heap, devId) != 0) {
+                WOLFSSL_MSG("Des3Init failed in SetKeys");
+                return ASYNC_INIT_E;
+            }
+        }
+        if (dec) {
+            if (wc_Des3Init(dec->des3, heap, devId) != 0) {
+                WOLFSSL_MSG("Des3Init failed in SetKeys");
+                return ASYNC_INIT_E;
+            }
+        }
+
+        if (side == WOLFSSL_CLIENT_END) {
+            if (enc) {
+                desRet = wc_Des3_SetKey(enc->des3, keys->client_write_key,
+                                     keys->client_write_IV, DES_ENCRYPTION);
+                if (desRet != 0) return desRet;
+            }
+            if (dec) {
+                desRet = wc_Des3_SetKey(dec->des3, keys->server_write_key,
+                                     keys->server_write_IV, DES_DECRYPTION);
+                if (desRet != 0) return desRet;
+            }
+        }
+        else {
+            if (enc) {
+                desRet = wc_Des3_SetKey(enc->des3, keys->server_write_key,
+                                     keys->server_write_IV, DES_ENCRYPTION);
+                if (desRet != 0) return desRet;
+            }
+            if (dec) {
+                desRet = wc_Des3_SetKey(dec->des3, keys->client_write_key,
+                                     keys->client_write_IV, DES_DECRYPTION);
+                if (desRet != 0) return desRet;
+            }
+        }
+        if (enc)
+            enc->setup = 1;
+        if (dec)
+            dec->setup = 1;
+    }
+#endif /* BUILD_DES3 */
+
+#ifdef BUILD_AES
+    /* check that buffer sizes are sufficient */
+    #if (MAX_WRITE_IV_SZ < 16) /* AES_IV_SIZE */
+        #error MAX_WRITE_IV_SZ too small for AES
+    #endif
+
+    if (specs->bulk_cipher_algorithm == wolfssl_aes) {
+        int aesRet = 0;
+
+        if (enc) {
+            if (enc->aes == NULL)
+                enc->aes = (Aes*)XMALLOC(sizeof(Aes), heap, DYNAMIC_TYPE_CIPHER);
+            if (enc->aes == NULL)
+                return MEMORY_E;
+            XMEMSET(enc->aes, 0, sizeof(Aes));
+        }
+        if (dec) {
+            if (dec->aes == NULL)
+                dec->aes = (Aes*)XMALLOC(sizeof(Aes), heap, DYNAMIC_TYPE_CIPHER);
+            if (dec->aes == NULL)
+                return MEMORY_E;
+            XMEMSET(dec->aes, 0, sizeof(Aes));
+        }
+        if (enc) {
+            if (wc_AesInit(enc->aes, heap, devId) != 0) {
+                WOLFSSL_MSG("AesInit failed in SetKeys");
+                return ASYNC_INIT_E;
+            }
+        }
+        if (dec) {
+            if (wc_AesInit(dec->aes, heap, devId) != 0) {
+                WOLFSSL_MSG("AesInit failed in SetKeys");
+                return ASYNC_INIT_E;
+            }
+        }
+
+        if (side == WOLFSSL_CLIENT_END) {
+            if (enc) {
+                aesRet = wc_AesSetKey(enc->aes, keys->client_write_key,
+                                   specs->key_size, keys->client_write_IV,
+                                   AES_ENCRYPTION);
+                if (aesRet != 0) return aesRet;
+            }
+            if (dec) {
+                aesRet = wc_AesSetKey(dec->aes, keys->server_write_key,
+                                   specs->key_size, keys->server_write_IV,
+                                   AES_DECRYPTION);
+                if (aesRet != 0) return aesRet;
+            }
+        }
+        else {
+            if (enc) {
+                aesRet = wc_AesSetKey(enc->aes, keys->server_write_key,
+                                   specs->key_size, keys->server_write_IV,
+                                   AES_ENCRYPTION);
+                if (aesRet != 0) return aesRet;
+            }
+            if (dec) {
+                aesRet = wc_AesSetKey(dec->aes, keys->client_write_key,
+                                   specs->key_size, keys->client_write_IV,
+                                   AES_DECRYPTION);
+                if (aesRet != 0) return aesRet;
+            }
+        }
+        if (enc)
+            enc->setup = 1;
+        if (dec)
+            dec->setup = 1;
+    }
+#endif /* BUILD_AES */
+
+#ifdef BUILD_AESGCM
+    /* check that buffer sizes are sufficient */
+    #if (AEAD_MAX_IMP_SZ < 4) /* AESGCM_IMP_IV_SZ */
+        #error AEAD_MAX_IMP_SZ too small for AESGCM
+    #endif
+    #if (AEAD_MAX_EXP_SZ < 8) /* AESGCM_EXP_IV_SZ */
+        #error AEAD_MAX_EXP_SZ too small for AESGCM
+    #endif
+    #if (MAX_WRITE_IV_SZ < 4) /* AESGCM_IMP_IV_SZ */
+        #error MAX_WRITE_IV_SZ too small for AESGCM
+    #endif
+
+    if (specs->bulk_cipher_algorithm == wolfssl_aes_gcm) {
+        int gcmRet;
+
+        if (enc) {
+            if (enc->aes == NULL)
+                enc->aes = (Aes*)XMALLOC(sizeof(Aes), heap, DYNAMIC_TYPE_CIPHER);
+            if (enc->aes == NULL)
+                return MEMORY_E;
+            XMEMSET(enc->aes, 0, sizeof(Aes));
+        }
+        if (dec) {
+            if (dec->aes == NULL)
+                dec->aes = (Aes*)XMALLOC(sizeof(Aes), heap, DYNAMIC_TYPE_CIPHER);
+            if (dec->aes == NULL)
+                return MEMORY_E;
+            XMEMSET(dec->aes, 0, sizeof(Aes));
+        }
+
+        if (enc) {
+            if (wc_AesInit(enc->aes, heap, devId) != 0) {
+                WOLFSSL_MSG("AesInit failed in SetKeys");
+                return ASYNC_INIT_E;
+            }
+        }
+        if (dec) {
+            if (wc_AesInit(dec->aes, heap, devId) != 0) {
+                WOLFSSL_MSG("AesInit failed in SetKeys");
+                return ASYNC_INIT_E;
+            }
+        }
+
+        if (side == WOLFSSL_CLIENT_END) {
+            if (enc) {
+                gcmRet = wc_AesGcmSetKey(enc->aes, keys->client_write_key,
+                                      specs->key_size);
+                if (gcmRet != 0) return gcmRet;
+                XMEMCPY(keys->aead_enc_imp_IV, keys->client_write_IV,
+                        AEAD_MAX_IMP_SZ);
+#if !defined(NO_PUBLIC_GCM_SET_IV) && \
+    ((!defined(HAVE_FIPS) && !defined(HAVE_SELFTEST)) || \
+    (defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION >= 2)))
+                if (!tls13) {
+                    gcmRet = wc_AesGcmSetIV(enc->aes, AESGCM_NONCE_SZ,
+                            keys->client_write_IV, AESGCM_IMP_IV_SZ, rng);
+                    if (gcmRet != 0) return gcmRet;
+                }
+#endif
+            }
+            if (dec) {
+                gcmRet = wc_AesGcmSetKey(dec->aes, keys->server_write_key,
+                                      specs->key_size);
+                if (gcmRet != 0) return gcmRet;
+                XMEMCPY(keys->aead_dec_imp_IV, keys->server_write_IV,
+                        AEAD_MAX_IMP_SZ);
+            }
+        }
+        else {
+            if (enc) {
+                gcmRet = wc_AesGcmSetKey(enc->aes, keys->server_write_key,
+                                      specs->key_size);
+                if (gcmRet != 0) return gcmRet;
+                XMEMCPY(keys->aead_enc_imp_IV, keys->server_write_IV,
+                        AEAD_MAX_IMP_SZ);
+#if !defined(NO_PUBLIC_GCM_SET_IV) && \
+    ((!defined(HAVE_FIPS) && !defined(HAVE_SELFTEST)) || \
+    (defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION >= 2)))
+                if (!tls13) {
+                    gcmRet = wc_AesGcmSetIV(enc->aes, AESGCM_NONCE_SZ,
+                            keys->server_write_IV, AESGCM_IMP_IV_SZ, rng);
+                    if (gcmRet != 0) return gcmRet;
+                }
+#endif
+            }
+            if (dec) {
+                gcmRet = wc_AesGcmSetKey(dec->aes, keys->client_write_key,
+                                      specs->key_size);
+                if (gcmRet != 0) return gcmRet;
+                XMEMCPY(keys->aead_dec_imp_IV, keys->client_write_IV,
+                        AEAD_MAX_IMP_SZ);
+            }
+        }
+        if (enc)
+            enc->setup = 1;
+        if (dec)
+            dec->setup = 1;
+    }
+#endif /* BUILD_AESGCM */
+
+#ifdef HAVE_AESCCM
+    /* check that buffer sizes are sufficient (CCM is same size as GCM) */
+    #if (AEAD_MAX_IMP_SZ < 4) /* AESGCM_IMP_IV_SZ */
+        #error AEAD_MAX_IMP_SZ too small for AESCCM
+    #endif
+    #if (AEAD_MAX_EXP_SZ < 8) /* AESGCM_EXP_IV_SZ */
+        #error AEAD_MAX_EXP_SZ too small for AESCCM
+    #endif
+    #if (MAX_WRITE_IV_SZ < 4) /* AESGCM_IMP_IV_SZ */
+        #error MAX_WRITE_IV_SZ too small for AESCCM
+    #endif
+
+    if (specs->bulk_cipher_algorithm == wolfssl_aes_ccm) {
+        int CcmRet;
+
+        if (enc) {
+            if (enc->aes == NULL)
+                enc->aes = (Aes*)XMALLOC(sizeof(Aes), heap, DYNAMIC_TYPE_CIPHER);
+            if (enc->aes == NULL)
+                return MEMORY_E;
+            XMEMSET(enc->aes, 0, sizeof(Aes));
+        }
+        if (dec) {
+            if (dec->aes == NULL)
+                dec->aes = (Aes*)XMALLOC(sizeof(Aes), heap, DYNAMIC_TYPE_CIPHER);
+            if (dec->aes == NULL)
+                return MEMORY_E;
+            XMEMSET(dec->aes, 0, sizeof(Aes));
+        }
+
+        if (enc) {
+            if (wc_AesInit(enc->aes, heap, devId) != 0) {
+                WOLFSSL_MSG("AesInit failed in SetKeys");
+                return ASYNC_INIT_E;
+            }
+        }
+        if (dec) {
+            if (wc_AesInit(dec->aes, heap, devId) != 0) {
+                WOLFSSL_MSG("AesInit failed in SetKeys");
+                return ASYNC_INIT_E;
+            }
+        }
+
+        if (side == WOLFSSL_CLIENT_END) {
+            if (enc) {
+                CcmRet = wc_AesCcmSetKey(enc->aes, keys->client_write_key,
+                                         specs->key_size);
+                if (CcmRet != 0) {
+                    return CcmRet;
+                }
+                XMEMCPY(keys->aead_enc_imp_IV, keys->client_write_IV,
+                        AEAD_MAX_IMP_SZ);
+#if !defined(NO_PUBLIC_CCM_SET_NONCE) && \
+    ((!defined(HAVE_FIPS) && !defined(HAVE_SELFTEST)) || \
+    (defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION >= 2)))
+                if (!tls13) {
+                    CcmRet = wc_AesCcmSetNonce(enc->aes, keys->client_write_IV,
+                            AEAD_MAX_IMP_SZ);
+                    if (CcmRet != 0) return CcmRet;
+                }
+#endif
+            }
+            if (dec) {
+                CcmRet = wc_AesCcmSetKey(dec->aes, keys->server_write_key,
+                                         specs->key_size);
+                if (CcmRet != 0) {
+                    return CcmRet;
+                }
+                XMEMCPY(keys->aead_dec_imp_IV, keys->server_write_IV,
+                        AEAD_MAX_IMP_SZ);
+            }
+        }
+        else {
+            if (enc) {
+                CcmRet = wc_AesCcmSetKey(enc->aes, keys->server_write_key,
+                                         specs->key_size);
+                if (CcmRet != 0) {
+                    return CcmRet;
+                }
+                XMEMCPY(keys->aead_enc_imp_IV, keys->server_write_IV,
+                        AEAD_MAX_IMP_SZ);
+#if !defined(NO_PUBLIC_CCM_SET_NONCE) && \
+    ((!defined(HAVE_FIPS) && !defined(HAVE_SELFTEST)) || \
+    (defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION >= 2)))
+                if (!tls13) {
+                    CcmRet = wc_AesCcmSetNonce(enc->aes, keys->server_write_IV,
+                            AEAD_MAX_IMP_SZ);
+                    if (CcmRet != 0) return CcmRet;
+                }
+#endif
+            }
+            if (dec) {
+                CcmRet = wc_AesCcmSetKey(dec->aes, keys->client_write_key,
+                                         specs->key_size);
+                if (CcmRet != 0) {
+                    return CcmRet;
+                }
+                XMEMCPY(keys->aead_dec_imp_IV, keys->client_write_IV,
+                        AEAD_MAX_IMP_SZ);
+            }
+        }
+        if (enc)
+            enc->setup = 1;
+        if (dec)
+            dec->setup = 1;
+    }
+#endif /* HAVE_AESCCM */
+
+#ifdef HAVE_CAMELLIA
+    /* check that buffer sizes are sufficient */
+    #if (MAX_WRITE_IV_SZ < 16) /* CAMELLIA_IV_SIZE */
+        #error MAX_WRITE_IV_SZ too small for CAMELLIA
+    #endif
+
+    if (specs->bulk_cipher_algorithm == wolfssl_camellia) {
+        int camRet;
+
+        if (enc && enc->cam == NULL)
+            enc->cam =
+                (Camellia*)XMALLOC(sizeof(Camellia), heap, DYNAMIC_TYPE_CIPHER);
+        if (enc && enc->cam == NULL)
+            return MEMORY_E;
+
+        if (dec && dec->cam == NULL)
+            dec->cam =
+                (Camellia*)XMALLOC(sizeof(Camellia), heap, DYNAMIC_TYPE_CIPHER);
+        if (dec && dec->cam == NULL)
+            return MEMORY_E;
+
+        if (side == WOLFSSL_CLIENT_END) {
+            if (enc) {
+                camRet = wc_CamelliaSetKey(enc->cam, keys->client_write_key,
+                                        specs->key_size, keys->client_write_IV);
+                if (camRet != 0) return camRet;
+            }
+            if (dec) {
+                camRet = wc_CamelliaSetKey(dec->cam, keys->server_write_key,
+                                        specs->key_size, keys->server_write_IV);
+                if (camRet != 0) return camRet;
+            }
+        }
+        else {
+            if (enc) {
+                camRet = wc_CamelliaSetKey(enc->cam, keys->server_write_key,
+                                        specs->key_size, keys->server_write_IV);
+                if (camRet != 0) return camRet;
+            }
+            if (dec) {
+                camRet = wc_CamelliaSetKey(dec->cam, keys->client_write_key,
+                                        specs->key_size, keys->client_write_IV);
+                if (camRet != 0) return camRet;
+            }
+        }
+        if (enc)
+            enc->setup = 1;
+        if (dec)
+            dec->setup = 1;
+    }
+#endif /* HAVE_CAMELLIA */
+
+#ifdef HAVE_IDEA
+    /* check that buffer sizes are sufficient */
+    #if (MAX_WRITE_IV_SZ < 8) /* IDEA_IV_SIZE */
+        #error MAX_WRITE_IV_SZ too small for IDEA
+    #endif
+
+    if (specs->bulk_cipher_algorithm == wolfssl_idea) {
+        int ideaRet;
+
+        if (enc && enc->idea == NULL)
+            enc->idea = (Idea*)XMALLOC(sizeof(Idea), heap, DYNAMIC_TYPE_CIPHER);
+        if (enc && enc->idea == NULL)
+            return MEMORY_E;
+
+        if (dec && dec->idea == NULL)
+            dec->idea = (Idea*)XMALLOC(sizeof(Idea), heap, DYNAMIC_TYPE_CIPHER);
+        if (dec && dec->idea == NULL)
+            return MEMORY_E;
+
+        if (side == WOLFSSL_CLIENT_END) {
+            if (enc) {
+                ideaRet = wc_IdeaSetKey(enc->idea, keys->client_write_key,
+                                        specs->key_size, keys->client_write_IV,
+                                        IDEA_ENCRYPTION);
+                if (ideaRet != 0) return ideaRet;
+            }
+            if (dec) {
+                ideaRet = wc_IdeaSetKey(dec->idea, keys->server_write_key,
+                                        specs->key_size, keys->server_write_IV,
+                                        IDEA_DECRYPTION);
+                if (ideaRet != 0) return ideaRet;
+            }
+        }
+        else {
+            if (enc) {
+                ideaRet = wc_IdeaSetKey(enc->idea, keys->server_write_key,
+                                        specs->key_size, keys->server_write_IV,
+                                        IDEA_ENCRYPTION);
+                if (ideaRet != 0) return ideaRet;
+            }
+            if (dec) {
+                ideaRet = wc_IdeaSetKey(dec->idea, keys->client_write_key,
+                                        specs->key_size, keys->client_write_IV,
+                                        IDEA_DECRYPTION);
+                if (ideaRet != 0) return ideaRet;
+            }
+        }
+        if (enc)
+            enc->setup = 1;
+        if (dec)
+            dec->setup = 1;
+    }
+#endif /* HAVE_IDEA */
+
+#ifdef HAVE_NULL_CIPHER
+    if (specs->bulk_cipher_algorithm == wolfssl_cipher_null) {
+    #ifdef WOLFSSL_TLS13
+        if (tls13) {
+            int hmacRet;
+            int hashType = WC_HASH_TYPE_NONE;
+
+            switch (specs->mac_algorithm) {
+                case sha256_mac:
+                    hashType = WC_SHA256;
+                    break;
+                case sha384_mac:
+                    hashType = WC_SHA384;
+                    break;
+                default:
+                    break;
+            }
+
+            if (enc && enc->hmac == NULL) {
+                enc->hmac = (Hmac*)XMALLOC(sizeof(Hmac), heap,
+                                                           DYNAMIC_TYPE_CIPHER);
+                if (enc->hmac == NULL)
+                    return MEMORY_E;
+            }
+
+            if (dec && dec->hmac == NULL) {
+                dec->hmac = (Hmac*)XMALLOC(sizeof(Hmac), heap,
+                                                           DYNAMIC_TYPE_CIPHER);
+                if (dec->hmac == NULL)
+                    return MEMORY_E;
+            }
+
+            if (enc) {
+                if (wc_HmacInit(enc->hmac, heap, devId) != 0) {
+                    WOLFSSL_MSG("HmacInit failed in SetKeys");
+                    return ASYNC_INIT_E;
+                }
+            }
+            if (dec) {
+                if (wc_HmacInit(dec->hmac, heap, devId) != 0) {
+                    WOLFSSL_MSG("HmacInit failed in SetKeys");
+                    return ASYNC_INIT_E;
+                }
+            }
+
+            if (side == WOLFSSL_CLIENT_END) {
+                if (enc) {
+                    hmacRet = wc_HmacSetKey(enc->hmac, hashType,
+                                       keys->client_write_key, specs->key_size);
+                    if (hmacRet != 0) return hmacRet;
+                }
+                if (dec) {
+                    hmacRet = wc_HmacSetKey(dec->hmac, hashType,
+                                       keys->server_write_key, specs->key_size);
+                    if (hmacRet != 0) return hmacRet;
+                }
+            }
+            else {
+                if (enc) {
+                    hmacRet = wc_HmacSetKey(enc->hmac, hashType,
+                                       keys->server_write_key, specs->key_size);
+                    if (hmacRet != 0) return hmacRet;
+                }
+                if (dec) {
+                    hmacRet = wc_HmacSetKey(dec->hmac, hashType,
+                                       keys->client_write_key, specs->key_size);
+                    if (hmacRet != 0) return hmacRet;
+                }
+            }
+        }
+    #endif
+        if (enc)
+            enc->setup = 1;
+        if (dec)
+            dec->setup = 1;
+    }
+#endif
+
+    if (enc) {
+        keys->sequence_number_hi      = 0;
+        keys->sequence_number_lo      = 0;
+    }
+    if (dec) {
+        keys->peer_sequence_number_hi = 0;
+        keys->peer_sequence_number_lo = 0;
+    }
+    (void)side;
+    (void)heap;
+    (void)enc;
+    (void)dec;
+    (void)specs;
+    (void)devId;
+
+    return 0;
+}
+
+
+#ifdef HAVE_ONE_TIME_AUTH
+/* set one time authentication keys */
+static int SetAuthKeys(OneTimeAuth* authentication, Keys* keys,
+                       CipherSpecs* specs, void* heap, int devId)
+{
+
+#ifdef HAVE_POLY1305
+        /* set up memory space for poly1305 */
+        if (authentication && authentication->poly1305 == NULL)
+            authentication->poly1305 =
+                (Poly1305*)XMALLOC(sizeof(Poly1305), heap, DYNAMIC_TYPE_CIPHER);
+        if (authentication && authentication->poly1305 == NULL)
+            return MEMORY_E;
+        if (authentication)
+            authentication->setup = 1;
+#endif
+        (void)authentication;
+        (void)heap;
+        (void)keys;
+        (void)specs;
+        (void)devId;
+
+        return 0;
+}
+#endif /* HAVE_ONE_TIME_AUTH */
+
+#ifdef HAVE_SECURE_RENEGOTIATION
+/* function name is for cache_status++
+ * This function was added because of error incrementing enum type when
+ * compiling with a C++ compiler.
+ */
+static void CacheStatusPP(SecureRenegotiation* cache)
+{
+    switch (cache->cache_status) {
+        case SCR_CACHE_NULL:
+            cache->cache_status = SCR_CACHE_NEEDED;
+            break;
+
+        case SCR_CACHE_NEEDED:
+            cache->cache_status = SCR_CACHE_COPY;
+            break;
+
+        case SCR_CACHE_COPY:
+            cache->cache_status = SCR_CACHE_PARTIAL;
+            break;
+
+        case SCR_CACHE_PARTIAL:
+            cache->cache_status = SCR_CACHE_COMPLETE;
+            break;
+
+        case SCR_CACHE_COMPLETE:
+            WOLFSSL_MSG("SCR Cache state Complete");
+            break;
+
+        default:
+            WOLFSSL_MSG("Unknown cache state!!");
+    }
+}
+#endif /* HAVE_SECURE_RENEGOTIATION */
+
+
+/* Set wc_encrypt/wc_decrypt or both sides of key setup
+ * note: use wc_encrypt to avoid shadowing global encrypt
+ * declared in unistd.h
+ */
+int SetKeysSide(WOLFSSL* ssl, enum encrypt_side side)
+{
+    int ret, copy = 0;
+    Ciphers* wc_encrypt = NULL;
+    Ciphers* wc_decrypt = NULL;
+    Keys*    keys    = &ssl->keys;
+
+    (void)copy;
+
+#ifdef HAVE_SECURE_RENEGOTIATION
+    if (ssl->secure_renegotiation && ssl->secure_renegotiation->cache_status) {
+        keys = &ssl->secure_renegotiation->tmp_keys;
+        copy = 1;
+    }
+#endif /* HAVE_SECURE_RENEGOTIATION */
+
+    switch (side) {
+        case ENCRYPT_SIDE_ONLY:
+#ifdef WOLFSSL_DEBUG_TLS
+            WOLFSSL_MSG("Provisioning ENCRYPT key");
+            if (ssl->options.side == WOLFSSL_CLIENT_END) {
+                WOLFSSL_BUFFER(ssl->keys.client_write_key, ssl->specs.key_size);
+            }
+            else {
+                WOLFSSL_BUFFER(ssl->keys.server_write_key, ssl->specs.key_size);
+            }
+#endif
+            wc_encrypt = &ssl->encrypt;
+            break;
+
+        case DECRYPT_SIDE_ONLY:
+#ifdef WOLFSSL_DEBUG_TLS
+            WOLFSSL_MSG("Provisioning DECRYPT key");
+            if (ssl->options.side == WOLFSSL_CLIENT_END) {
+                WOLFSSL_BUFFER(ssl->keys.server_write_key, ssl->specs.key_size);
+            }
+            else {
+                WOLFSSL_BUFFER(ssl->keys.client_write_key, ssl->specs.key_size);
+            }
+#endif
+            wc_decrypt = &ssl->decrypt;
+            break;
+
+        case ENCRYPT_AND_DECRYPT_SIDE:
+#ifdef WOLFSSL_DEBUG_TLS
+            WOLFSSL_MSG("Provisioning ENCRYPT key");
+            if (ssl->options.side == WOLFSSL_CLIENT_END) {
+                WOLFSSL_BUFFER(ssl->keys.client_write_key, ssl->specs.key_size);
+            }
+            else {
+                WOLFSSL_BUFFER(ssl->keys.server_write_key, ssl->specs.key_size);
+            }
+            WOLFSSL_MSG("Provisioning DECRYPT key");
+            if (ssl->options.side == WOLFSSL_CLIENT_END) {
+                WOLFSSL_BUFFER(ssl->keys.server_write_key, ssl->specs.key_size);
+            }
+            else {
+                WOLFSSL_BUFFER(ssl->keys.client_write_key, ssl->specs.key_size);
+            }
+#endif
+            wc_encrypt = &ssl->encrypt;
+            wc_decrypt = &ssl->decrypt;
+            break;
+
+        default:
+            return BAD_FUNC_ARG;
+    }
+
+#ifdef HAVE_ONE_TIME_AUTH
+    if (!ssl->auth.setup && ssl->specs.bulk_cipher_algorithm == wolfssl_chacha){
+        ret = SetAuthKeys(&ssl->auth, keys, &ssl->specs, ssl->heap, ssl->devId);
+        if (ret != 0)
+           return ret;
+    }
+#endif
+
+#if defined(WOLFSSL_RENESAS_TSIP_TLS) && \
+    !defined(NO_WOLFSSL_RENESAS_TSIP_TLS_SESSION)
+    /* check if keys for TSIP has been created */
+    if (tsip_useable(ssl) == 1)
+        ret = 0;
+    else
+#endif
+    ret = SetKeys(wc_encrypt, wc_decrypt, keys, &ssl->specs, ssl->options.side,
+                  ssl->heap, ssl->devId, ssl->rng, ssl->options.tls1_3);
+
+#ifdef HAVE_SECURE_RENEGOTIATION
+    if (copy) {
+        int clientCopy = 0;
+
+        if (ssl->options.side == WOLFSSL_CLIENT_END && wc_encrypt)
+            clientCopy = 1;
+        else if (ssl->options.side == WOLFSSL_SERVER_END && wc_decrypt)
+            clientCopy = 1;
+
+        if (clientCopy) {
+    #ifndef WOLFSSL_AEAD_ONLY
+            XMEMCPY(ssl->keys.client_write_MAC_secret,
+                    keys->client_write_MAC_secret, WC_MAX_DIGEST_SIZE);
+    #endif
+            XMEMCPY(ssl->keys.client_write_key,
+                    keys->client_write_key, AES_256_KEY_SIZE);
+            XMEMCPY(ssl->keys.client_write_IV,
+                    keys->client_write_IV, MAX_WRITE_IV_SZ);
+        } else {
+    #ifndef WOLFSSL_AEAD_ONLY
+            XMEMCPY(ssl->keys.server_write_MAC_secret,
+                    keys->server_write_MAC_secret, WC_MAX_DIGEST_SIZE);
+    #endif
+            XMEMCPY(ssl->keys.server_write_key,
+                    keys->server_write_key, AES_256_KEY_SIZE);
+            XMEMCPY(ssl->keys.server_write_IV,
+                    keys->server_write_IV, MAX_WRITE_IV_SZ);
+        }
+        if (wc_encrypt) {
+            ssl->keys.sequence_number_hi = keys->sequence_number_hi;
+            ssl->keys.sequence_number_lo = keys->sequence_number_lo;
+            #ifdef HAVE_AEAD
+                if (ssl->specs.cipher_type == aead) {
+                    /* Initialize the AES-GCM/CCM explicit IV to a zero. */
+                    XMEMCPY(ssl->keys.aead_exp_IV, keys->aead_exp_IV,
+                            AEAD_MAX_EXP_SZ);
+
+                    /* Initialize encrypt implicit IV by encrypt side */
+                    if (ssl->options.side == WOLFSSL_CLIENT_END) {
+                        XMEMCPY(ssl->keys.aead_enc_imp_IV,
+                                keys->client_write_IV, AEAD_MAX_IMP_SZ);
+                    } else {
+                        XMEMCPY(ssl->keys.aead_enc_imp_IV,
+                                keys->server_write_IV, AEAD_MAX_IMP_SZ);
+                    }
+                }
+            #endif
+        }
+        if (wc_decrypt) {
+            ssl->keys.peer_sequence_number_hi = keys->peer_sequence_number_hi;
+            ssl->keys.peer_sequence_number_lo = keys->peer_sequence_number_lo;
+            #ifdef HAVE_AEAD
+                if (ssl->specs.cipher_type == aead) {
+                    /* Initialize decrypt implicit IV by decrypt side */
+                    if (ssl->options.side == WOLFSSL_SERVER_END) {
+                        XMEMCPY(ssl->keys.aead_dec_imp_IV,
+                                keys->client_write_IV, AEAD_MAX_IMP_SZ);
+                    } else {
+                        XMEMCPY(ssl->keys.aead_dec_imp_IV,
+                                keys->server_write_IV, AEAD_MAX_IMP_SZ);
+                    }
+                }
+            #endif
+        }
+        CacheStatusPP(ssl->secure_renegotiation);
+    }
+#endif /* HAVE_SECURE_RENEGOTIATION */
+
+    return ret;
+}
+
+
+/* TLS can call too */
+int StoreKeys(WOLFSSL* ssl, const byte* keyData, int side)
+{
+    int sz, i = 0;
+    Keys* keys = &ssl->keys;
+
+#ifdef HAVE_SECURE_RENEGOTIATION
+    if (ssl->secure_renegotiation && ssl->secure_renegotiation->cache_status ==
+                                                            SCR_CACHE_NEEDED) {
+        keys = &ssl->secure_renegotiation->tmp_keys;
+        CacheStatusPP(ssl->secure_renegotiation);
+    }
+#endif /* HAVE_SECURE_RENEGOTIATION */
+
+#ifdef WOLFSSL_MULTICAST
+    if (ssl->options.haveMcast) {
+        /* Use the same keys for encrypt and decrypt. */
+        if (ssl->specs.cipher_type != aead) {
+            sz = ssl->specs.hash_size;
+    #ifndef WOLFSSL_AEAD_ONLY
+            XMEMCPY(keys->client_write_MAC_secret,&keyData[i], sz);
+            XMEMCPY(keys->server_write_MAC_secret,&keyData[i], sz);
+    #endif
+            i += sz;
+        }
+        sz = ssl->specs.key_size;
+        XMEMCPY(keys->client_write_key, &keyData[i], sz);
+        XMEMCPY(keys->server_write_key, &keyData[i], sz);
+        i += sz;
+
+        sz = ssl->specs.iv_size;
+        XMEMCPY(keys->client_write_IV, &keyData[i], sz);
+        XMEMCPY(keys->server_write_IV, &keyData[i], sz);
+
+#ifdef HAVE_AEAD
+        if (ssl->specs.cipher_type == aead) {
+            /* Initialize the AES-GCM/CCM explicit IV to a zero. */
+            XMEMSET(keys->aead_exp_IV, 0, AEAD_MAX_EXP_SZ);
+        }
+#endif /* HAVE_AEAD */
+
+        return 0;
+    }
+#endif /* WOLFSSL_MULTICAST */
+
+    if (ssl->specs.cipher_type != aead) {
+        sz = ssl->specs.hash_size;
+        if (side & PROVISION_CLIENT) {
+    #ifndef WOLFSSL_AEAD_ONLY
+            XMEMCPY(keys->client_write_MAC_secret,&keyData[i], sz);
+    #endif
+            i += sz;
+        }
+        if (side & PROVISION_SERVER) {
+    #ifndef WOLFSSL_AEAD_ONLY
+            XMEMCPY(keys->server_write_MAC_secret,&keyData[i], sz);
+    #endif
+            i += sz;
+        }
+    }
+    sz = ssl->specs.key_size;
+    if (side & PROVISION_CLIENT) {
+        XMEMCPY(keys->client_write_key, &keyData[i], sz);
+        i += sz;
+    }
+    if (side & PROVISION_SERVER) {
+        XMEMCPY(keys->server_write_key, &keyData[i], sz);
+        i += sz;
+    }
+
+    sz = ssl->specs.iv_size;
+    if (side & PROVISION_CLIENT) {
+        XMEMCPY(keys->client_write_IV, &keyData[i], sz);
+        i += sz;
+    }
+    if (side & PROVISION_SERVER)
+        XMEMCPY(keys->server_write_IV, &keyData[i], sz);
+
+#ifdef HAVE_AEAD
+    if (ssl->specs.cipher_type == aead) {
+        /* Initialize the AES-GCM/CCM explicit IV to a zero. */
+        XMEMSET(keys->aead_exp_IV, 0, AEAD_MAX_EXP_SZ);
+    }
+#endif
+
+    return 0;
+}
+
+#ifndef NO_OLD_TLS
+int DeriveKeys(WOLFSSL* ssl)
+{
+    int    length = 2 * ssl->specs.hash_size +
+                    2 * ssl->specs.key_size  +
+                    2 * ssl->specs.iv_size;
+    int    rounds = (length + WC_MD5_DIGEST_SIZE - 1 ) / WC_MD5_DIGEST_SIZE, i;
+    int    ret = 0;
+
+#ifdef WOLFSSL_SMALL_STACK
+    byte*  shaOutput;
+    byte*  md5Input;
+    byte*  shaInput;
+    byte*  keyData;
+    wc_Md5* md5;
+    wc_Sha* sha;
+#else
+    byte   shaOutput[WC_SHA_DIGEST_SIZE];
+    byte   md5Input[SECRET_LEN + WC_SHA_DIGEST_SIZE];
+    byte   shaInput[KEY_PREFIX + SECRET_LEN + 2 * RAN_LEN];
+    byte   keyData[KEY_PREFIX * WC_MD5_DIGEST_SIZE];
+    wc_Md5 md5[1];
+    wc_Sha sha[1];
+#endif
+
+#ifdef WOLFSSL_SMALL_STACK
+    shaOutput = (byte*)XMALLOC(WC_SHA_DIGEST_SIZE,
+                                            NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    md5Input  = (byte*)XMALLOC(SECRET_LEN + WC_SHA_DIGEST_SIZE,
+                                            NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    shaInput  = (byte*)XMALLOC(KEY_PREFIX + SECRET_LEN + 2 * RAN_LEN,
+                                            NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    keyData   = (byte*)XMALLOC(KEY_PREFIX * WC_MD5_DIGEST_SIZE,
+                                            NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    md5       =  (wc_Md5*)XMALLOC(sizeof(wc_Md5), NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    sha       =  (wc_Sha*)XMALLOC(sizeof(wc_Sha), NULL, DYNAMIC_TYPE_TMP_BUFFER);
+
+    if (shaOutput == NULL || md5Input == NULL || shaInput == NULL ||
+        keyData   == NULL || md5      == NULL || sha      == NULL) {
+        if (shaOutput) XFREE(shaOutput, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+        if (md5Input)  XFREE(md5Input,  NULL, DYNAMIC_TYPE_TMP_BUFFER);
+        if (shaInput)  XFREE(shaInput,  NULL, DYNAMIC_TYPE_TMP_BUFFER);
+        if (keyData)   XFREE(keyData,   NULL, DYNAMIC_TYPE_TMP_BUFFER);
+        if (md5)       XFREE(md5,       NULL, DYNAMIC_TYPE_TMP_BUFFER);
+        if (sha)       XFREE(sha,       NULL, DYNAMIC_TYPE_TMP_BUFFER);
+
+        return MEMORY_E;
+    }
+#endif
+
+    ret = wc_InitMd5(md5);
+    if (ret == 0) {
+        ret = wc_InitSha(sha);
+    }
+    if (ret == 0) {
+        XMEMCPY(md5Input, ssl->arrays->masterSecret, SECRET_LEN);
+
+        for (i = 0; i < rounds; ++i) {
+            int j   = i + 1;
+            int idx = j;
+
+            if (!SetPrefix(shaInput, i)) {
+                ret = PREFIX_ERROR;
+                break;
+            }
+
+            XMEMCPY(shaInput + idx, ssl->arrays->masterSecret, SECRET_LEN);
+            idx += SECRET_LEN;
+            XMEMCPY(shaInput + idx, ssl->arrays->serverRandom, RAN_LEN);
+            idx += RAN_LEN;
+            XMEMCPY(shaInput + idx, ssl->arrays->clientRandom, RAN_LEN);
+            if (ret == 0) {
+                ret = wc_ShaUpdate(sha, shaInput,
+                    (KEY_PREFIX + SECRET_LEN + 2 * RAN_LEN) - KEY_PREFIX + j);
+            }
+            if (ret == 0) {
+                ret = wc_ShaFinal(sha, shaOutput);
+            }
+
+            XMEMCPY(md5Input + SECRET_LEN, shaOutput, WC_SHA_DIGEST_SIZE);
+            if (ret == 0) {
+                ret = wc_Md5Update(md5, md5Input, SECRET_LEN + WC_SHA_DIGEST_SIZE);
+            }
+            if (ret == 0) {
+                ret = wc_Md5Final(md5, keyData + i * WC_MD5_DIGEST_SIZE);
+            }
+        }
+
+        if (ret == 0)
+            ret = StoreKeys(ssl, keyData, PROVISION_CLIENT_SERVER);
+    }
+
+#ifdef WOLFSSL_SMALL_STACK
+    XFREE(shaOutput, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    XFREE(md5Input,  NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    XFREE(shaInput,  NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    XFREE(keyData,   NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    XFREE(md5,       NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    XFREE(sha,       NULL, DYNAMIC_TYPE_TMP_BUFFER);
+#endif
+
+    return ret;
+}
+
+
+static int CleanPreMaster(WOLFSSL* ssl)
+{
+    int i, ret, sz = ssl->arrays->preMasterSz;
+
+    for (i = 0; i < sz; i++)
+        ssl->arrays->preMasterSecret[i] = 0;
+
+    ret = wc_RNG_GenerateBlock(ssl->rng, ssl->arrays->preMasterSecret, sz);
+    if (ret != 0)
+        return ret;
+
+    for (i = 0; i < sz; i++)
+        ssl->arrays->preMasterSecret[i] = 0;
+
+    XFREE(ssl->arrays->preMasterSecret, ssl->heap, DYNAMIC_TYPE_SECRET);
+    ssl->arrays->preMasterSecret = NULL;
+    ssl->arrays->preMasterSz = 0;
+
+    return 0;
+}
+
+
+/* Create and store the master secret see page 32, 6.1 */
+static int MakeSslMasterSecret(WOLFSSL* ssl)
+{
+    int    i, ret;
+    word32 idx;
+    word32 pmsSz = ssl->arrays->preMasterSz;
+
+#ifdef WOLFSSL_SMALL_STACK
+    byte*  shaOutput;
+    byte*  md5Input;
+    byte*  shaInput;
+    wc_Md5* md5;
+    wc_Sha* sha;
+#else
+    byte   shaOutput[WC_SHA_DIGEST_SIZE];
+    byte   md5Input[ENCRYPT_LEN + WC_SHA_DIGEST_SIZE];
+    byte   shaInput[PREFIX + ENCRYPT_LEN + 2 * RAN_LEN];
+    wc_Md5 md5[1];
+    wc_Sha sha[1];
+#endif
+
+#ifdef SHOW_SECRETS
+    {
+        word32 j;
+        printf("pre master secret: ");
+        for (j = 0; j < pmsSz; j++)
+            printf("%02x", ssl->arrays->preMasterSecret[j]);
+        printf("\n");
+    }
+#endif
+
+#ifdef WOLFSSL_SMALL_STACK
+    shaOutput = (byte*)XMALLOC(WC_SHA_DIGEST_SIZE,
+                                            NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    md5Input  = (byte*)XMALLOC(ENCRYPT_LEN + WC_SHA_DIGEST_SIZE,
+                                            NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    shaInput  = (byte*)XMALLOC(PREFIX + ENCRYPT_LEN + 2 * RAN_LEN,
+                                            NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    md5       =  (wc_Md5*)XMALLOC(sizeof(wc_Md5), NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    sha       =  (wc_Sha*)XMALLOC(sizeof(wc_Sha), NULL, DYNAMIC_TYPE_TMP_BUFFER);
+
+    if (shaOutput == NULL || md5Input == NULL || shaInput == NULL ||
+                             md5      == NULL || sha      == NULL) {
+        if (shaOutput) XFREE(shaOutput, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+        if (md5Input)  XFREE(md5Input,  NULL, DYNAMIC_TYPE_TMP_BUFFER);
+        if (shaInput)  XFREE(shaInput,  NULL, DYNAMIC_TYPE_TMP_BUFFER);
+        if (md5)       XFREE(md5,       NULL, DYNAMIC_TYPE_TMP_BUFFER);
+        if (sha)       XFREE(sha,       NULL, DYNAMIC_TYPE_TMP_BUFFER);
+
+        return MEMORY_E;
+    }
+#endif
+
+    ret = wc_InitMd5(md5);
+    if (ret == 0) {
+        ret = wc_InitSha(sha);
+    }
+    if (ret == 0) {
+        XMEMCPY(md5Input, ssl->arrays->preMasterSecret, pmsSz);
+
+        for (i = 0; i < MASTER_ROUNDS; ++i) {
+            byte prefix[KEY_PREFIX];      /* only need PREFIX bytes but static */
+            if (!SetPrefix(prefix, i)) {  /* analysis thinks will overrun      */
+                ret = PREFIX_ERROR;
+                break;
+            }
+
+            idx = 0;
+            XMEMCPY(shaInput, prefix, i + 1);
+            idx += i + 1;
+
+            XMEMCPY(shaInput + idx, ssl->arrays->preMasterSecret, pmsSz);
+            idx += pmsSz;
+            XMEMCPY(shaInput + idx, ssl->arrays->clientRandom, RAN_LEN);
+            idx += RAN_LEN;
+            XMEMCPY(shaInput + idx, ssl->arrays->serverRandom, RAN_LEN);
+            idx += RAN_LEN;
+            if (ret == 0) {
+                ret = wc_ShaUpdate(sha, shaInput, idx);
+            }
+            if (ret == 0) {
+                ret = wc_ShaFinal(sha, shaOutput);
+            }
+            idx = pmsSz;  /* preSz */
+            XMEMCPY(md5Input + idx, shaOutput, WC_SHA_DIGEST_SIZE);
+            idx += WC_SHA_DIGEST_SIZE;
+            if (ret == 0) {
+                ret = wc_Md5Update(md5, md5Input, idx);
+            }
+            if (ret == 0) {
+                ret = wc_Md5Final(md5,
+                            &ssl->arrays->masterSecret[i * WC_MD5_DIGEST_SIZE]);
+            }
+        }
+
+#ifdef SHOW_SECRETS
+        {
+            word32 j;
+            printf("master secret: ");
+            for (j = 0; j < SECRET_LEN; j++)
+                printf("%02x", ssl->arrays->masterSecret[j]);
+            printf("\n");
+        }
+#endif
+
+        if (ret == 0)
+            ret = DeriveKeys(ssl);
+    }
+
+#ifdef WOLFSSL_SMALL_STACK
+    XFREE(shaOutput, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    XFREE(md5Input,  NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    XFREE(shaInput,  NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    XFREE(md5,       NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    XFREE(sha,       NULL, DYNAMIC_TYPE_TMP_BUFFER);
+#endif
+
+    if (ret == 0)
+        ret = CleanPreMaster(ssl);
+    else
+        CleanPreMaster(ssl);
+
+    return ret;
+}
+#endif
+
+
+/* Master wrapper, doesn't use SSL stack space in TLS mode */
+int MakeMasterSecret(WOLFSSL* ssl)
+{
+    /* append secret to premaster : premaster | SerSi | CliSi */
+#ifdef HAVE_QSH
+    word32 offset = 0;
+
+    if (ssl->peerQSHKeyPresent) {
+        offset += ssl->arrays->preMasterSz;
+        ssl->arrays->preMasterSz += ssl->QSH_secret->CliSi->length +
+                                                 ssl->QSH_secret->SerSi->length;
+        /* test and set flag if QSH has been used */
+        if (ssl->QSH_secret->CliSi->length > 0 ||
+                ssl->QSH_secret->SerSi->length > 0)
+            ssl->isQSH = 1;
+
+        /* append secrets to the premaster */
+        if (ssl->QSH_secret->SerSi != NULL) {
+            XMEMCPY(ssl->arrays->preMasterSecret + offset,
+                ssl->QSH_secret->SerSi->buffer, ssl->QSH_secret->SerSi->length);
+        }
+        offset += ssl->QSH_secret->SerSi->length;
+        if (ssl->QSH_secret->CliSi != NULL) {
+            XMEMCPY(ssl->arrays->preMasterSecret + offset,
+                ssl->QSH_secret->CliSi->buffer, ssl->QSH_secret->CliSi->length);
+        }
+
+        /* show secret SerSi and CliSi */
+        #ifdef SHOW_SECRETS
+        {
+            word32 j;
+            printf("QSH generated secret material\n");
+            printf("SerSi        : ");
+            for (j = 0; j < ssl->QSH_secret->SerSi->length; j++) {
+                printf("%02x", ssl->QSH_secret->SerSi->buffer[j]);
+            }
+            printf("\n");
+            printf("CliSi        : ");
+            for (j = 0; j < ssl->QSH_secret->CliSi->length; j++) {
+                printf("%02x", ssl->QSH_secret->CliSi->buffer[j]);
+            }
+            printf("\n");
+        }
+        #endif
+    }
+#endif
+
+#ifndef NO_OLD_TLS
+    if (ssl->options.tls) return MakeTlsMasterSecret(ssl);
+    return MakeSslMasterSecret(ssl);
+#elif !defined(WOLFSSL_NO_TLS12)
+    return MakeTlsMasterSecret(ssl);
+#else
+    (void)ssl;
+    return 0;
+#endif
+}
+
+#endif /* WOLFCRYPT_ONLY */
Index: azure_iot_hub_f767zi/trunk/wolfssl-4.4.0/src/ocsp.c
===================================================================
--- azure_iot_hub_f767zi/trunk/wolfssl-4.4.0/src/ocsp.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/wolfssl-4.4.0/src/ocsp.c	(revision 457)
@@ -0,0 +1,1100 @@
+/* ocsp.c
+ *
+ * Copyright (C) 2006-2020 wolfSSL Inc.
+ *
+ * This file is part of wolfSSL.
+ *
+ * wolfSSL is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * wolfSSL is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
+ */
+
+
+  /* Name change compatibility layer no longer needs to be included here */
+
+#ifdef HAVE_CONFIG_H
+    #include <config.h>
+#endif
+
+#include <wolfssl/wolfcrypt/settings.h>
+
+#ifndef WOLFCRYPT_ONLY
+#ifdef HAVE_OCSP
+
+#include <wolfssl/error-ssl.h>
+#include <wolfssl/ocsp.h>
+#include <wolfssl/internal.h>
+
+#ifdef NO_INLINE
+    #include <wolfssl/wolfcrypt/misc.h>
+#else
+    #define WOLFSSL_MISC_INCLUDED
+    #include <wolfcrypt/src/misc.c>
+#endif
+
+
+int InitOCSP(WOLFSSL_OCSP* ocsp, WOLFSSL_CERT_MANAGER* cm)
+{
+    WOLFSSL_ENTER("InitOCSP");
+
+    ForceZero(ocsp, sizeof(WOLFSSL_OCSP));
+
+    if (wc_InitMutex(&ocsp->ocspLock) != 0)
+        return BAD_MUTEX_E;
+
+    ocsp->cm = cm;
+
+    return 0;
+}
+
+
+static int InitOcspEntry(OcspEntry* entry, OcspRequest* request)
+{
+    WOLFSSL_ENTER("InitOcspEntry");
+
+    ForceZero(entry, sizeof(OcspEntry));
+
+    XMEMCPY(entry->issuerHash,    request->issuerHash,    OCSP_DIGEST_SIZE);
+    XMEMCPY(entry->issuerKeyHash, request->issuerKeyHash, OCSP_DIGEST_SIZE);
+
+    return 0;
+}
+
+
+static void FreeOcspEntry(OcspEntry* entry, void* heap)
+{
+    CertStatus *status, *next;
+
+    WOLFSSL_ENTER("FreeOcspEntry");
+
+    for (status = entry->status; status; status = next) {
+        next = status->next;
+
+        if (status->rawOcspResponse)
+            XFREE(status->rawOcspResponse, heap, DYNAMIC_TYPE_OCSP_STATUS);
+
+        XFREE(status, heap, DYNAMIC_TYPE_OCSP_STATUS);
+    }
+
+    (void)heap;
+}
+
+
+void FreeOCSP(WOLFSSL_OCSP* ocsp, int dynamic)
+{
+    OcspEntry *entry, *next;
+
+    WOLFSSL_ENTER("FreeOCSP");
+
+    for (entry = ocsp->ocspList; entry; entry = next) {
+        next = entry->next;
+        FreeOcspEntry(entry, ocsp->cm->heap);
+        XFREE(entry, ocsp->cm->heap, DYNAMIC_TYPE_OCSP_ENTRY);
+    }
+
+    wc_FreeMutex(&ocsp->ocspLock);
+
+    if (dynamic)
+        XFREE(ocsp, ocsp->cm->heap, DYNAMIC_TYPE_OCSP);
+
+}
+
+
+static int xstat2err(int st)
+{
+    switch (st) {
+        case CERT_GOOD:
+            return 0;
+        case CERT_REVOKED:
+            return OCSP_CERT_REVOKED;
+        default:
+            return OCSP_CERT_UNKNOWN;
+    }
+}
+
+int CheckCertOCSP_ex(WOLFSSL_OCSP* ocsp, DecodedCert* cert, buffer* responseBuffer, WOLFSSL* ssl)
+{
+    int ret = OCSP_LOOKUP_FAIL;
+
+#ifdef WOLFSSL_SMALL_STACK
+    OcspRequest* ocspRequest;
+#else
+    OcspRequest ocspRequest[1];
+#endif
+
+    WOLFSSL_ENTER("CheckCertOCSP");
+
+
+#ifdef WOLFSSL_SMALL_STACK
+    ocspRequest = (OcspRequest*)XMALLOC(sizeof(OcspRequest), NULL,
+                                                       DYNAMIC_TYPE_TMP_BUFFER);
+    if (ocspRequest == NULL) {
+        WOLFSSL_LEAVE("CheckCertOCSP", MEMORY_ERROR);
+        return MEMORY_E;
+    }
+#endif
+
+    if (InitOcspRequest(ocspRequest, cert, ocsp->cm->ocspSendNonce,
+                                                         ocsp->cm->heap) == 0) {
+        ocspRequest->ssl = ssl;
+        ret = CheckOcspRequest(ocsp, ocspRequest, responseBuffer);
+
+        FreeOcspRequest(ocspRequest);
+    }
+
+#ifdef WOLFSSL_SMALL_STACK
+    XFREE(ocspRequest, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+#endif
+
+    WOLFSSL_LEAVE("CheckCertOCSP", ret);
+    return ret;
+}
+int CheckCertOCSP(WOLFSSL_OCSP* ocsp, DecodedCert* cert, buffer* responseBuffer)
+{
+    return CheckCertOCSP_ex(ocsp, cert, responseBuffer, NULL);
+}
+
+static int GetOcspEntry(WOLFSSL_OCSP* ocsp, OcspRequest* request,
+                                                              OcspEntry** entry)
+{
+    WOLFSSL_ENTER("GetOcspEntry");
+
+    *entry = NULL;
+
+    if (wc_LockMutex(&ocsp->ocspLock) != 0) {
+        WOLFSSL_LEAVE("CheckCertOCSP", BAD_MUTEX_E);
+        return BAD_MUTEX_E;
+    }
+
+    for (*entry = ocsp->ocspList; *entry; *entry = (*entry)->next)
+        if (XMEMCMP((*entry)->issuerHash,    request->issuerHash,
+                                                         OCSP_DIGEST_SIZE) == 0
+        &&  XMEMCMP((*entry)->issuerKeyHash, request->issuerKeyHash,
+                                                         OCSP_DIGEST_SIZE) == 0)
+            break;
+
+    if (*entry == NULL) {
+        *entry = (OcspEntry*)XMALLOC(sizeof(OcspEntry),
+                                       ocsp->cm->heap, DYNAMIC_TYPE_OCSP_ENTRY);
+        if (*entry) {
+            InitOcspEntry(*entry, request);
+            (*entry)->next = ocsp->ocspList;
+            ocsp->ocspList = *entry;
+        }
+    }
+
+    wc_UnLockMutex(&ocsp->ocspLock);
+
+    return *entry ? 0 : MEMORY_ERROR;
+}
+
+
+/* Mallocs responseBuffer->buffer and is up to caller to free on success
+ *
+ * Returns OCSP status
+ */
+static int GetOcspStatus(WOLFSSL_OCSP* ocsp, OcspRequest* request,
+                  OcspEntry* entry, CertStatus** status, buffer* responseBuffer)
+{
+    int ret = OCSP_INVALID_STATUS;
+
+    WOLFSSL_ENTER("GetOcspStatus");
+
+    *status = NULL;
+
+    if (wc_LockMutex(&ocsp->ocspLock) != 0) {
+        WOLFSSL_LEAVE("CheckCertOCSP", BAD_MUTEX_E);
+        return BAD_MUTEX_E;
+    }
+
+    for (*status = entry->status; *status; *status = (*status)->next)
+        if ((*status)->serialSz == request->serialSz
+        &&  !XMEMCMP((*status)->serial, request->serial, (*status)->serialSz))
+            break;
+
+    if (responseBuffer && *status && !(*status)->rawOcspResponse) {
+        /* force fetching again */
+        ret = OCSP_INVALID_STATUS;
+    }
+    else if (*status) {
+#ifndef NO_ASN_TIME
+        if (XVALIDATE_DATE((*status)->thisDate,
+                                             (*status)->thisDateFormat, BEFORE)
+        &&  ((*status)->nextDate[0] != 0)
+        &&  XVALIDATE_DATE((*status)->nextDate,
+                                             (*status)->nextDateFormat, AFTER))
+#endif
+        {
+            ret = xstat2err((*status)->status);
+
+            if (responseBuffer) {
+                responseBuffer->buffer = (byte*)XMALLOC(
+                   (*status)->rawOcspResponseSz, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+
+                if (responseBuffer->buffer) {
+                    responseBuffer->length = (*status)->rawOcspResponseSz;
+                    XMEMCPY(responseBuffer->buffer,
+                            (*status)->rawOcspResponse,
+                            (*status)->rawOcspResponseSz);
+                }
+            }
+        }
+    }
+
+    wc_UnLockMutex(&ocsp->ocspLock);
+
+    return ret;
+}
+
+/* Check that the response for validity. Store result in status.
+ *
+ * ocsp           Context object for OCSP status.
+ * response       OCSP response message data.
+ * responseSz     Length of OCSP response message data.
+ * reponseBuffer  Buffer object to return the response with.
+ * status         The certificate status object.
+ * entry          The OCSP entry for this certificate.
+ * returns OCSP_LOOKUP_FAIL when the response is bad and 0 otherwise.
+ */
+WOLFSSL_LOCAL int CheckOcspResponse(WOLFSSL_OCSP *ocsp, byte *response, int responseSz,
+                                    WOLFSSL_BUFFER_INFO *responseBuffer, CertStatus *status,
+                                    OcspEntry *entry, OcspRequest *ocspRequest)
+{
+#ifdef WOLFSSL_SMALL_STACK
+    CertStatus*   newStatus;
+    OcspResponse* ocspResponse;
+#else
+    CertStatus    newStatus[1];
+    OcspResponse  ocspResponse[1];
+#endif
+    int           ret;
+    int           validated      = 0;    /* ocsp validation flag */
+
+#ifdef WOLFSSL_SMALL_STACK
+    newStatus = (CertStatus*)XMALLOC(sizeof(CertStatus), NULL,
+                                                       DYNAMIC_TYPE_TMP_BUFFER);
+    ocspResponse = (OcspResponse*)XMALLOC(sizeof(OcspResponse), NULL,
+                                                       DYNAMIC_TYPE_TMP_BUFFER);
+
+    if (newStatus == NULL || ocspResponse == NULL) {
+        if (newStatus) XFREE(newStatus, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+        if (ocspResponse) XFREE(ocspResponse, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+
+        WOLFSSL_LEAVE("CheckCertOCSP", MEMORY_ERROR);
+        return MEMORY_E;
+    }
+#endif
+    XMEMSET(newStatus, 0, sizeof(CertStatus));
+
+    InitOcspResponse(ocspResponse, newStatus, response, responseSz);
+    ret = OcspResponseDecode(ocspResponse, ocsp->cm, ocsp->cm->heap, 0);
+    if (ret != 0) {
+        ocsp->error = ret;
+        WOLFSSL_LEAVE("OcspResponseDecode failed", ocsp->error);
+        goto end;
+    }
+
+    if (ocspResponse->responseStatus != OCSP_SUCCESSFUL) {
+        WOLFSSL_MSG("OcspResponse status bad");
+        goto end;
+    }
+    if (ocspRequest != NULL) {
+        ret = CompareOcspReqResp(ocspRequest, ocspResponse);
+        if (ret != 0) {
+            goto end;
+        }
+    }
+
+    if (responseBuffer) {
+        responseBuffer->buffer = (byte*)XMALLOC(responseSz, ocsp->cm->heap,
+                                                DYNAMIC_TYPE_TMP_BUFFER);
+
+        if (responseBuffer->buffer) {
+            responseBuffer->length = responseSz;
+            XMEMCPY(responseBuffer->buffer, response, responseSz);
+        }
+    }
+
+    ret = xstat2err(ocspResponse->status->status);
+    if (ret == 0) {
+        validated = 1;
+    }
+
+    if (wc_LockMutex(&ocsp->ocspLock) != 0) {
+        ret = BAD_MUTEX_E;
+        goto end;
+    }
+
+    if (status != NULL) {
+        if (status->rawOcspResponse) {
+            XFREE(status->rawOcspResponse, ocsp->cm->heap,
+                  DYNAMIC_TYPE_OCSP_STATUS);
+        }
+
+        /* Replace existing certificate entry with updated */
+        newStatus->next = status->next;
+        XMEMCPY(status, newStatus, sizeof(CertStatus));
+    }
+    else {
+        /* Save new certificate entry */
+        status = (CertStatus*)XMALLOC(sizeof(CertStatus),
+                                      ocsp->cm->heap, DYNAMIC_TYPE_OCSP_STATUS);
+        if (status != NULL) {
+            XMEMCPY(status, newStatus, sizeof(CertStatus));
+            status->next  = entry->status;
+            entry->status = status;
+            entry->totalStatus++;
+        }
+    }
+
+    if (status && responseBuffer && responseBuffer->buffer) {
+        status->rawOcspResponse = (byte*)XMALLOC(responseBuffer->length,
+                                                 ocsp->cm->heap,
+                                                 DYNAMIC_TYPE_OCSP_STATUS);
+
+        if (status->rawOcspResponse) {
+            status->rawOcspResponseSz = responseBuffer->length;
+            XMEMCPY(status->rawOcspResponse, responseBuffer->buffer,
+                    responseBuffer->length);
+        }
+    }
+
+    wc_UnLockMutex(&ocsp->ocspLock);
+
+end:
+    if (ret == 0 && validated == 1) {
+        WOLFSSL_MSG("New OcspResponse validated");
+    } else if (ret != OCSP_CERT_REVOKED) {
+        ret = OCSP_LOOKUP_FAIL;
+    }
+
+#ifdef WOLFSSL_SMALL_STACK
+    XFREE(newStatus,    NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    XFREE(ocspResponse, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+#endif
+    return ret;
+}
+
+/* 0 on success */
+int CheckOcspRequest(WOLFSSL_OCSP* ocsp, OcspRequest* ocspRequest,
+                                                      buffer* responseBuffer)
+{
+    OcspEntry*  entry          = NULL;
+    CertStatus* status         = NULL;
+    byte*       request        = NULL;
+    int         requestSz      = 2048;
+    int         responseSz     = 0;
+    byte*       response       = NULL;
+    const char* url            = NULL;
+    int         urlSz          = 0;
+    int         ret            = -1;
+    WOLFSSL*    ssl;
+    void*       ioCtx;
+
+    WOLFSSL_ENTER("CheckOcspRequest");
+
+    if (ocsp == NULL || ocspRequest == NULL)
+        return BAD_FUNC_ARG;
+
+    if (responseBuffer) {
+        responseBuffer->buffer = NULL;
+        responseBuffer->length = 0;
+    }
+
+    ret = GetOcspEntry(ocsp, ocspRequest, &entry);
+    if (ret != 0)
+        return ret;
+
+    ret = GetOcspStatus(ocsp, ocspRequest, entry, &status, responseBuffer);
+    if (ret != OCSP_INVALID_STATUS)
+        return ret;
+
+    /* get SSL and IOCtx */
+    ssl = (WOLFSSL*)ocspRequest->ssl;
+    ioCtx = (ssl && ssl->ocspIOCtx != NULL) ?
+                                        ssl->ocspIOCtx : ocsp->cm->ocspIOCtx;
+
+#if defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY)
+    if (ocsp->statusCb != NULL && ssl != NULL) {
+        ret = ocsp->statusCb(ssl, ioCtx);
+        if (ret == 0) {
+            ret = wolfSSL_get_ocsp_response(ssl, &response);
+            ret = CheckOcspResponse(ocsp, response, ret, responseBuffer, status,
+                                entry, NULL);
+            if (response != NULL)
+                XFREE(response, NULL, DYNAMIC_TYPE_OPENSSL);
+            return ret;
+        }
+        WOLFSSL_LEAVE("CheckOcspRequest", ocsp->error);
+        return OCSP_LOOKUP_FAIL;
+    }
+#endif
+
+    if (ocsp->cm->ocspUseOverrideURL) {
+        url = ocsp->cm->ocspOverrideURL;
+        if (url != NULL && url[0] != '\0')
+            urlSz = (int)XSTRLEN(url);
+        else
+            return OCSP_NEED_URL;
+    }
+    else if (ocspRequest->urlSz != 0 && ocspRequest->url != NULL) {
+        url = (const char *)ocspRequest->url;
+        urlSz = ocspRequest->urlSz;
+    }
+    else {
+        /* cert doesn't have extAuthInfo, assuming CERT_GOOD */
+        return 0;
+    }
+
+    request = (byte*)XMALLOC(requestSz, ocsp->cm->heap, DYNAMIC_TYPE_OCSP);
+    if (request == NULL) {
+        WOLFSSL_LEAVE("CheckCertOCSP", MEMORY_ERROR);
+        if (responseBuffer) {
+            XFREE(responseBuffer->buffer, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+            responseBuffer->buffer = NULL;
+        }
+        return MEMORY_ERROR;
+    }
+
+    requestSz = EncodeOcspRequest(ocspRequest, request, requestSz);
+    if (requestSz > 0 && ocsp->cm->ocspIOCb) {
+        responseSz = ocsp->cm->ocspIOCb(ioCtx, url, urlSz,
+                                        request, requestSz, &response);
+    }
+    if (responseSz == WOLFSSL_CBIO_ERR_WANT_READ) {
+        ret = OCSP_WANT_READ;
+    }
+
+    XFREE(request, ocsp->cm->heap, DYNAMIC_TYPE_OCSP);
+
+    if (responseSz >= 0 && response) {
+        ret = CheckOcspResponse(ocsp, response, responseSz, responseBuffer, status,
+                            entry, ocspRequest);
+    }
+
+    if (response != NULL && ocsp->cm->ocspRespFreeCb)
+        ocsp->cm->ocspRespFreeCb(ioCtx, response);
+
+    /* Keep responseBuffer in the case of getting to response check. Caller
+     * should free responseBuffer after checking OCSP return value in "ret" */
+    WOLFSSL_LEAVE("CheckOcspRequest", ret);
+    return ret;
+}
+
+#if defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY) || \
+    defined(WOLFSSL_APACHE_HTTPD)
+
+int wolfSSL_OCSP_resp_find_status(WOLFSSL_OCSP_BASICRESP *bs,
+    WOLFSSL_OCSP_CERTID* id, int* status, int* reason,
+    WOLFSSL_ASN1_TIME** revtime, WOLFSSL_ASN1_TIME** thisupd,
+    WOLFSSL_ASN1_TIME** nextupd)
+{
+    if (bs == NULL || id == NULL)
+        return WOLFSSL_FAILURE;
+
+    /* Only supporting one certificate status in asn.c. */
+    if (CompareOcspReqResp(id, bs) != 0)
+        return WOLFSSL_FAILURE;
+
+    if (status != NULL)
+        *status = bs->status->status;
+    if (thisupd != NULL)
+        *thisupd = &bs->status->thisDateParsed;
+    if (nextupd != NULL)
+        *nextupd = &bs->status->nextDateParsed;
+
+    /* TODO: Not needed for Nginx. */
+    if (reason != NULL)
+        *reason = 0;
+    if (revtime != NULL)
+        *revtime = NULL;
+
+    return WOLFSSL_SUCCESS;
+}
+
+const char *wolfSSL_OCSP_cert_status_str(long s)
+{
+    switch (s) {
+        case CERT_GOOD:
+            return "good";
+        case CERT_REVOKED:
+            return "revoked";
+        case CERT_UNKNOWN:
+            return "unknown";
+        default:
+            return "(UNKNOWN)";
+    }
+}
+
+int wolfSSL_OCSP_check_validity(WOLFSSL_ASN1_TIME* thisupd,
+    WOLFSSL_ASN1_TIME* nextupd, long sec, long maxsec)
+{
+    (void)thisupd;
+    (void)nextupd;
+    (void)sec;
+    (void)maxsec;
+    /* Dates validated in DecodeSingleResponse. */
+    return WOLFSSL_SUCCESS;
+}
+
+void wolfSSL_OCSP_CERTID_free(WOLFSSL_OCSP_CERTID* certId)
+{
+    FreeOcspRequest(certId);
+    XFREE(certId, NULL, DYNAMIC_TYPE_OPENSSL);
+}
+
+WOLFSSL_OCSP_CERTID* wolfSSL_OCSP_cert_to_id(
+    const WOLFSSL_EVP_MD *dgst, const WOLFSSL_X509 *subject,
+    const WOLFSSL_X509 *issuer)
+{
+    WOLFSSL_OCSP_CERTID* certId;
+    DecodedCert cert;
+    WOLFSSL_CERT_MANAGER* cm;
+    int ret;
+    DerBuffer* derCert = NULL;
+
+    (void)dgst;
+
+    cm = wolfSSL_CertManagerNew();
+    if (cm == NULL)
+        return NULL;
+
+    ret = AllocDer(&derCert, issuer->derCert->length,
+        issuer->derCert->type, NULL);
+    if (ret == 0) {
+        /* AddCA() frees the buffer. */
+        XMEMCPY(derCert->buffer, issuer->derCert->buffer,
+                issuer->derCert->length);
+        AddCA(cm, &derCert, WOLFSSL_USER_CA, 1);
+    }
+
+    certId = (WOLFSSL_OCSP_CERTID*)XMALLOC(sizeof(WOLFSSL_OCSP_CERTID), NULL,
+                                           DYNAMIC_TYPE_OPENSSL);
+    if (certId != NULL) {
+        InitDecodedCert(&cert, subject->derCert->buffer,
+                        subject->derCert->length, NULL);
+        if (ParseCertRelative(&cert, CERT_TYPE, VERIFY_OCSP, cm) != 0) {
+            XFREE(certId, NULL, DYNAMIC_TYPE_OPENSSL);
+            certId = NULL;
+        }
+        else {
+            ret = InitOcspRequest(certId, &cert, 0, NULL);
+            if (ret != 0) {
+                XFREE(certId, NULL, DYNAMIC_TYPE_OPENSSL);
+                certId = NULL;
+            }
+        }
+        FreeDecodedCert(&cert);
+    }
+
+    wolfSSL_CertManagerFree(cm);
+
+    return certId;
+}
+
+void wolfSSL_OCSP_BASICRESP_free(WOLFSSL_OCSP_BASICRESP* basicResponse)
+{
+    wolfSSL_OCSP_RESPONSE_free(basicResponse);
+}
+
+/* Signature verified in DecodeBasicOcspResponse.
+ * But no store available to verify certificate. */
+int wolfSSL_OCSP_basic_verify(WOLFSSL_OCSP_BASICRESP *bs,
+    WOLF_STACK_OF(WOLFSSL_X509) *certs, WOLFSSL_X509_STORE *st, unsigned long flags)
+{
+    DecodedCert cert;
+    int         ret = WOLFSSL_SUCCESS;
+
+    (void)certs;
+
+    if (flags & OCSP_NOVERIFY)
+        return WOLFSSL_SUCCESS;
+
+#ifdef OPENSSL_EXTRA
+    if (bs->verifyError != OCSP_VERIFY_ERROR_NONE)
+        return WOLFSSL_FAILURE;
+#endif
+
+    InitDecodedCert(&cert, bs->cert, bs->certSz, NULL);
+    if (ParseCertRelative(&cert, CERT_TYPE, VERIFY, st->cm) < 0)
+        ret = WOLFSSL_FAILURE;
+    FreeDecodedCert(&cert);
+
+    return ret;
+}
+
+void wolfSSL_OCSP_RESPONSE_free(OcspResponse* response)
+{
+    if (response->status != NULL)
+        XFREE(response->status, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    if (response->source != NULL)
+        XFREE(response->source, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    XFREE(response, NULL, DYNAMIC_TYPE_OPENSSL);
+}
+
+OcspResponse* wolfSSL_d2i_OCSP_RESPONSE_bio(WOLFSSL_BIO* bio,
+    OcspResponse** response)
+{
+    byte*         data;
+    byte*         p;
+    int           len;
+    int           dataAlloced = 0;
+    OcspResponse* ret = NULL;
+
+    if (bio == NULL)
+        return NULL;
+
+    if (bio->type == WOLFSSL_BIO_MEMORY) {
+        len = wolfSSL_BIO_get_mem_data(bio, &data);
+        if (len <= 0 || data == NULL) {
+            return NULL;
+        }
+    }
+#ifndef NO_FILESYSTEM
+    else if (bio->type == WOLFSSL_BIO_FILE) {
+        long fcur;
+        long flen;
+
+        if (bio->ptr == NULL)
+            return NULL;
+
+        fcur = XFTELL((XFILE)bio->ptr);
+        if (fcur < 0)
+            return NULL;
+        if(XFSEEK((XFILE)bio->ptr, 0, SEEK_END) != 0)
+            return NULL;
+        flen = XFTELL((XFILE)bio->ptr);
+        if (flen < 0)
+            return NULL;
+        if (XFSEEK((XFILE)bio->ptr, fcur, SEEK_SET) != 0)
+            return NULL;
+
+        /* check calculated length */
+        fcur = flen - fcur;
+        if (fcur > MAX_WOLFSSL_FILE_SIZE || fcur <= 0)
+            return NULL;
+
+        data = (byte*)XMALLOC(fcur, 0, DYNAMIC_TYPE_TMP_BUFFER);
+        if (data == NULL)
+            return NULL;
+        dataAlloced = 1;
+
+        len = wolfSSL_BIO_read(bio, (char *)data, (int)flen);
+    }
+#endif
+    else
+        return NULL;
+
+    if (len > 0) {
+        p = data;
+        ret = wolfSSL_d2i_OCSP_RESPONSE(response, (const unsigned char **)&p,
+            len);
+    }
+
+    if (dataAlloced)
+        XFREE(data, 0, DYNAMIC_TYPE_TMP_BUFFER);
+
+    return ret;
+}
+
+OcspResponse* wolfSSL_d2i_OCSP_RESPONSE(OcspResponse** response,
+    const unsigned char** data, int len)
+{
+    OcspResponse *resp = NULL;
+    word32 idx = 0;
+    int length = 0;
+
+    if (data == NULL)
+        return NULL;
+
+    if (response != NULL)
+        resp = *response;
+    if (resp == NULL) {
+        resp = (OcspResponse*)XMALLOC(sizeof(OcspResponse), NULL,
+                                      DYNAMIC_TYPE_OPENSSL);
+        if (resp == NULL)
+            return NULL;
+        XMEMSET(resp, 0, sizeof(OcspResponse));
+    }
+
+    resp->source = (byte*)XMALLOC(len, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    if (resp->source == NULL) {
+        XFREE(resp, NULL, DYNAMIC_TYPE_OPENSSL);
+        return NULL;
+    }
+    resp->status = (CertStatus*)XMALLOC(sizeof(CertStatus), NULL,
+                                                       DYNAMIC_TYPE_TMP_BUFFER);
+    if (resp->status == NULL) {
+        XFREE(resp->source, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+        XFREE(resp, NULL, DYNAMIC_TYPE_OPENSSL);
+        return NULL;
+    }
+
+    XMEMCPY(resp->source, *data, len);
+    resp->maxIdx = len;
+
+    if (OcspResponseDecode(resp, NULL, NULL, 1) != 0) {
+        wolfSSL_OCSP_RESPONSE_free(resp);
+        return NULL;
+    }
+
+    if (GetSequence(*data, &idx, &length, len) >= 0)
+        (*data) += idx + length;
+
+    return resp;
+}
+
+int wolfSSL_i2d_OCSP_RESPONSE(OcspResponse* response,
+    unsigned char** data)
+{
+    if (data == NULL)
+        return response->maxIdx;
+
+    XMEMCPY(*data, response->source, response->maxIdx);
+    return response->maxIdx;
+}
+
+int wolfSSL_OCSP_response_status(OcspResponse *response)
+{
+    return response->responseStatus;
+}
+
+const char *wolfSSL_OCSP_response_status_str(long s)
+{
+    switch (s) {
+        case OCSP_SUCCESSFUL:
+            return "successful";
+        case OCSP_MALFORMED_REQUEST:
+            return "malformedrequest";
+        case OCSP_INTERNAL_ERROR:
+            return "internalerror";
+        case OCSP_TRY_LATER:
+            return "trylater";
+        case OCSP_SIG_REQUIRED:
+            return "sigrequired";
+        case OCSP_UNAUTHROIZED:
+            return "unauthorized";
+        default:
+            return "(UNKNOWN)";
+    }
+}
+
+WOLFSSL_OCSP_BASICRESP* wolfSSL_OCSP_response_get1_basic(OcspResponse* response)
+{
+    WOLFSSL_OCSP_BASICRESP* bs;
+
+    bs = (WOLFSSL_OCSP_BASICRESP*)XMALLOC(sizeof(WOLFSSL_OCSP_BASICRESP), NULL,
+                                          DYNAMIC_TYPE_OPENSSL);
+    if (bs == NULL)
+        return NULL;
+
+    XMEMCPY(bs, response, sizeof(OcspResponse));
+    bs->status = (CertStatus*)XMALLOC(sizeof(CertStatus), NULL,
+                                      DYNAMIC_TYPE_TMP_BUFFER);
+    bs->source = (byte*)XMALLOC(bs->maxIdx, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    if (bs->status == NULL || bs->source == NULL) {
+        if (bs->status) XFREE(bs->status, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+        if (bs->source) XFREE(bs->source, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+        wolfSSL_OCSP_RESPONSE_free(bs);
+        bs = NULL;
+    }
+    else {
+        XMEMCPY(bs->status, response->status, sizeof(CertStatus));
+        XMEMCPY(bs->source, response->source, response->maxIdx);
+    }
+    return bs;
+}
+
+OcspRequest* wolfSSL_OCSP_REQUEST_new(void)
+{
+    OcspRequest* request;
+
+    request = (OcspRequest*)XMALLOC(sizeof(OcspRequest), NULL,
+                                    DYNAMIC_TYPE_OPENSSL);
+    if (request != NULL)
+        XMEMSET(request, 0, sizeof(OcspRequest));
+
+    return request;
+}
+
+void wolfSSL_OCSP_REQUEST_free(OcspRequest* request)
+{
+    FreeOcspRequest(request);
+    XFREE(request, NULL, DYNAMIC_TYPE_OPENSSL);
+}
+
+int wolfSSL_i2d_OCSP_REQUEST(OcspRequest* request, unsigned char** data)
+{
+    int size;
+
+    size = EncodeOcspRequest(request, NULL, 0);
+    if (size <= 0 || data == NULL)
+        return size;
+
+    return EncodeOcspRequest(request, *data, size);
+}
+
+WOLFSSL_OCSP_ONEREQ* wolfSSL_OCSP_request_add0_id(OcspRequest *req,
+    WOLFSSL_OCSP_CERTID *cid)
+{
+    if (req == NULL || cid == NULL)
+        return NULL;
+
+    FreeOcspRequest(req);
+    XMEMCPY(req, cid, sizeof(OcspRequest));
+
+    if (cid->serial != NULL) {
+        req->serial = (byte*)XMALLOC(cid->serialSz, NULL,
+                                     DYNAMIC_TYPE_OCSP_REQUEST);
+        req->url = (byte*)XMALLOC(cid->urlSz, NULL, DYNAMIC_TYPE_OCSP_REQUEST);
+        if (req->serial == NULL || req->url == NULL) {
+            FreeOcspRequest(req);
+            return NULL;
+        }
+
+        XMEMCPY(req->serial, cid->serial, cid->serialSz);
+        XMEMCPY(req->url, cid->url, cid->urlSz);
+    }
+
+    wolfSSL_OCSP_REQUEST_free(cid);
+
+    return req;
+}
+
+WOLFSSL_OCSP_CERTID* wolfSSL_OCSP_CERTID_dup(WOLFSSL_OCSP_CERTID* id)
+{
+    WOLFSSL_OCSP_CERTID* certId;
+
+    if (id == NULL) {
+        return NULL;
+    }
+
+    certId = (WOLFSSL_OCSP_CERTID*)XMALLOC(sizeof(WOLFSSL_OCSP_CERTID),
+        id->heap, DYNAMIC_TYPE_OPENSSL);
+    if (certId) {
+        XMEMCPY(certId, id, sizeof(WOLFSSL_OCSP_CERTID));
+    }
+    return certId;
+}
+#endif
+
+#if defined(OPENSSL_ALL) || defined(APACHE_HTTPD)
+int wolfSSL_i2d_OCSP_REQUEST_bio(WOLFSSL_BIO* out,
+        WOLFSSL_OCSP_REQUEST *req)
+{
+    int size = -1;
+    unsigned char* data = NULL;
+
+    WOLFSSL_ENTER("wolfSSL_i2d_OCSP_REQUEST_bio");
+    if (out == NULL || req == NULL)
+        return WOLFSSL_FAILURE;
+
+    size = wolfSSL_i2d_OCSP_REQUEST(req, NULL);
+    if (size > 0) {
+        data = (unsigned char*) XMALLOC(size, out->heap,
+                DYNAMIC_TYPE_TMP_BUFFER);
+    }
+
+    if (data != NULL) {
+        size = wolfSSL_i2d_OCSP_REQUEST(req, &data);
+    }
+
+    if (size <= 0) {
+        XFREE(data, out->heap, DYNAMIC_TYPE_TMP_BUFFER);
+        return WOLFSSL_FAILURE;
+    }
+
+    if (wolfSSL_BIO_write(out, data, size) == (int)size) {
+        XFREE(data, out->heap, DYNAMIC_TYPE_TMP_BUFFER);
+        return WOLFSSL_SUCCESS;
+    }
+
+    XFREE(data, out->heap, DYNAMIC_TYPE_TMP_BUFFER);
+    return WOLFSSL_FAILURE;
+}
+#endif /* OPENSSL_ALL || APACHE_HTTPD */
+
+#ifdef OPENSSL_EXTRA
+#ifndef NO_WOLFSSL_STUB
+int wolfSSL_OCSP_REQUEST_add_ext(OcspRequest* req, WOLFSSL_X509_EXTENSION* ext,
+        int idx)
+{
+    WOLFSSL_STUB("wolfSSL_OCSP_REQUEST_add_ext");
+    (void)req;
+    (void)ext;
+    (void)idx;
+    return WOLFSSL_FATAL_ERROR;
+}
+#endif
+
+#ifndef NO_WOLFSSL_STUB
+OcspResponse* wolfSSL_OCSP_response_create(int status,
+    WOLFSSL_OCSP_BASICRESP* bs)
+{
+    WOLFSSL_STUB("wolfSSL_OCSP_response_create");
+    (void)status;
+    (void)bs;
+    return NULL;
+}
+#endif
+
+#ifndef NO_WOLFSSL_STUB
+const char* wolfSSL_OCSP_crl_reason_str(long s)
+{
+    WOLFSSL_STUB("wolfSSL_OCSP_crl_reason_str");
+    (void)s;
+    return NULL;
+}
+#endif
+
+/* Returns elements of an OCSP_CERTID struct. Currently only supports
+ * returning the serial number, and returns an error if user requests
+ * any of name, pmd, and/or keyHash.
+ * Return 1 on success, 0 on failure */
+int wolfSSL_OCSP_id_get0_info(WOLFSSL_ASN1_STRING **name,
+  WOLFSSL_ASN1_OBJECT **pmd, WOLFSSL_ASN1_STRING **keyHash,
+  WOLFSSL_ASN1_INTEGER **serial, WOLFSSL_OCSP_CERTID *cid)
+{
+    int i = 0;
+    WOLFSSL_ASN1_INTEGER* ser;
+
+    WOLFSSL_ENTER("wolfSSL_OCSP_id_get0_info");
+
+    if (cid == NULL)
+        return 0;
+
+    /* build up ASN1_INTEGER for serial */
+    if (serial != NULL) {
+        ser = wolfSSL_ASN1_INTEGER_new();
+        if (ser == NULL)
+            return 0;
+
+        if (cid->serialSz > (WOLFSSL_ASN1_INTEGER_MAX - 2)) {
+            /* allocate data buffer, +2 for type and length */
+            ser->data = (unsigned char*)XMALLOC(cid->serialSz + 2, NULL,
+                DYNAMIC_TYPE_OPENSSL);
+            if (ser->data == NULL) {
+                wolfSSL_ASN1_INTEGER_free(ser);
+                return 0;
+            }
+            ser->dataMax = cid->serialSz + 2;
+            ser->isDynamic = 1;
+        } else {
+            /* Use array instead of dynamic memory */
+            ser->data    = ser->intData;
+            ser->dataMax = WOLFSSL_ASN1_INTEGER_MAX;
+        }
+
+        #ifdef WOLFSSL_QT
+            /* Serial number starts at 0 index of ser->data */
+            XMEMCPY(&ser->data[i], cid->serial, cid->serialSz);
+            ser->length = cid->serialSz;
+        #else
+            ser->data[i++] = ASN_INTEGER;
+            i += SetLength(cid->serialSz, ser->data + i);
+            XMEMCPY(&ser->data[i], cid->serial, cid->serialSz);
+        #endif
+
+        cid->serialInt = ser;
+        *serial = cid->serialInt;
+    }
+
+    /* Not needed for Apache, return error if user is requesting */
+    if (name != NULL || pmd != NULL || keyHash != NULL) {
+        if (name != NULL)
+            *name = NULL;
+
+        if (pmd != NULL)
+            *pmd = NULL;
+
+        if (keyHash != NULL)
+            *keyHash = NULL;
+        return 0;
+    }
+
+    return 1;
+}
+
+#ifndef NO_WOLFSSL_STUB
+int wolfSSL_OCSP_request_add1_nonce(OcspRequest* req, unsigned char* val,
+        int sz)
+{
+    WOLFSSL_STUB("wolfSSL_OCSP_request_add1_nonce");
+    (void)req;
+    (void)val;
+    (void)sz;
+    return WOLFSSL_FATAL_ERROR;
+}
+#endif
+
+/* Returns result of OCSP nonce comparison. Return values:
+ *  1 - nonces are both present and equal
+ *  2 - both nonces are absent
+ *  3 - nonce only present in response
+ * -1 - nonce only present in request
+ *  0 - both nonces present and equal
+ */
+int wolfSSL_OCSP_check_nonce(OcspRequest* req, WOLFSSL_OCSP_BASICRESP* bs)
+{
+    byte* reqNonce = NULL;
+    byte* rspNonce = NULL;
+    int reqNonceSz = 0;
+    int rspNonceSz = 0;
+
+    WOLFSSL_ENTER("wolfSSL_OCSP_check_nonce");
+
+    if (req != NULL) {
+        reqNonce = req->nonce;
+        reqNonceSz = req->nonceSz;
+    }
+
+    if (bs != NULL) {
+        rspNonce = bs->nonce;
+        rspNonceSz = bs->nonceSz;
+    }
+
+    /* nonce absent in both req and rsp */
+    if (reqNonce == NULL && rspNonce == NULL)
+        return 2;
+
+    /* nonce present in rsp only */
+    if (reqNonce == NULL && rspNonce != NULL)
+        return 3;
+
+    /* nonce present in req only */
+    if (reqNonce != NULL && rspNonce == NULL)
+        return -1;
+
+    /* nonces are present and equal, return 1. Extra NULL check for fixing
+        scan-build warning. */
+    if (reqNonceSz == rspNonceSz && reqNonce && rspNonce) {
+        if (XMEMCMP(reqNonce, rspNonce, reqNonceSz) == 0)
+            return 1;
+    }
+
+    /* nonces are present but not equal */
+    return 0;
+}
+#endif /* OPENSSL_EXTRA */
+
+#else /* HAVE_OCSP */
+
+
+#ifdef _MSC_VER
+    /* 4206 warning for blank file */
+    #pragma warning(disable: 4206)
+#endif
+
+
+#endif /* HAVE_OCSP */
+#endif /* WOLFCRYPT_ONLY */
Index: azure_iot_hub_f767zi/trunk/wolfssl-4.4.0/src/sniffer.c
===================================================================
--- azure_iot_hub_f767zi/trunk/wolfssl-4.4.0/src/sniffer.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/wolfssl-4.4.0/src/sniffer.c	(revision 457)
@@ -0,0 +1,4611 @@
+/* sniffer.c
+ *
+ * Copyright (C) 2006-2020 wolfSSL Inc.
+ *
+ * This file is part of wolfSSL.
+ *
+ * wolfSSL is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * wolfSSL is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
+ */
+
+
+#ifdef HAVE_CONFIG_H
+    #include <config.h>
+#endif
+
+#include <wolfssl/wolfcrypt/settings.h>
+
+#ifndef WOLFCRYPT_ONLY
+#ifdef WOLFSSL_SNIFFER
+
+#include <assert.h>
+#include <time.h>
+
+#ifndef _WIN32
+  #include <arpa/inet.h>
+#else
+  #include <WS2tcpip.h>
+#endif
+
+#ifdef _WIN32
+    #define SNPRINTF _snprintf
+#else
+    #define SNPRINTF snprintf
+#endif
+
+#include <wolfssl/openssl/ssl.h>
+#include <wolfssl/internal.h>
+#include <wolfssl/error-ssl.h>
+#include <wolfssl/sniffer.h>
+#include <wolfssl/sniffer_error.h>
+#ifdef NO_INLINE
+    #include <wolfssl/wolfcrypt/misc.h>
+#else
+    #define WOLFSSL_MISC_INCLUDED
+    #include <wolfcrypt/src/misc.c>
+#endif
+
+#ifdef WOLF_CRYPTO_CB
+    #include <wolfssl/wolfcrypt/cryptocb.h>
+    #ifdef HAVE_INTEL_QA_SYNC
+        #include <wolfssl/wolfcrypt/port/intel/quickassist_sync.h>
+    #endif
+    #ifdef HAVE_CAVIUM_OCTEON_SYNC
+        #include <wolfssl/wolfcrypt/port/cavium/cavium_octeon_sync.h>
+    #endif
+#endif
+
+
+#ifndef WOLFSSL_SNIFFER_TIMEOUT
+    #define WOLFSSL_SNIFFER_TIMEOUT 900
+    /* Cache unclosed Sessions for 15 minutes since last used */
+#endif
+
+/* Misc constants */
+enum {
+    MAX_SERVER_ADDRESS = 128, /* maximum server address length */
+    MAX_SERVER_NAME    = 128, /* maximum server name length */
+    MAX_ERROR_LEN      = 80,  /* maximum error length */
+    ETHER_IF_ADDR_LEN  = 6,   /* ethernet interface address length */
+    LOCAL_IF_ADDR_LEN  = 4,   /* localhost interface address length, !windows */
+    TCP_PROTO          = 6,   /* TCP_PROTOCOL */
+    IP_HDR_SZ          = 20,  /* IPv4 header length, min */
+    IP6_HDR_SZ         = 40,  /* IPv6 header length, min */
+    TCP_HDR_SZ         = 20,  /* TCP header length, min */
+    IPV4               = 4,   /* IP version 4 */
+    IPV6               = 6,   /* IP version 6 */
+    TCP_PROTOCOL       = 6,   /* TCP Protocol id */
+    NO_NEXT_HEADER     = 59,  /* IPv6 no headers follow */
+    TRACE_MSG_SZ       = 80,  /* Trace Message buffer size */
+    HASH_SIZE          = 499, /* Session Hash Table Rows */
+    PSEUDO_HDR_SZ      = 12,  /* TCP Pseudo Header size in bytes */
+    FATAL_ERROR_STATE  =  1,  /* SnifferSession fatal error state */
+    TICKET_HINT_LEN    = 4,   /* Session Ticket Hint length */
+    EXT_TYPE_SZ        = 2,   /* Extension length */
+    MAX_INPUT_SZ       = MAX_RECORD_SIZE + COMP_EXTRA + MAX_MSG_EXTRA +
+                         MTU_EXTRA,  /* Max input sz of reassembly */
+    EXT_MASTER_SECRET  = 0x17, /* Extended Master Secret Extension ID */
+    TICKET_EXT_ID      = 0x23 /* Session Ticket Extension ID */
+};
+
+
+#ifdef _WIN32
+
+static HMODULE dllModule;  /* for error string resources */
+
+BOOL APIENTRY DllMain( HMODULE hModule,
+                       DWORD  ul_reason_for_call,
+                       LPVOID lpReserved
+                     )
+{
+	static int didInit = 0;
+
+    switch (ul_reason_for_call)
+    {
+    case DLL_PROCESS_ATTACH:
+		if (didInit == 0) {
+            dllModule = hModule;
+			ssl_InitSniffer();
+			didInit = 1;
+		}
+        break;
+    case DLL_THREAD_ATTACH:
+        break;
+    case DLL_THREAD_DETACH:
+        break;
+    case DLL_PROCESS_DETACH:
+		if (didInit) {
+			ssl_FreeSniffer();
+			didInit = 0;
+		}
+        break;
+    }
+    return TRUE;
+}
+
+#endif /* _WIN32 */
+
+
+static WOLFSSL_GLOBAL int TraceOn = 0;         /* Trace is off by default */
+static WOLFSSL_GLOBAL FILE* TraceFile = 0;
+
+
+/* windows uses .rc table for this */
+#ifndef _WIN32
+
+static const char* const msgTable[] =
+{
+    /* 1 */
+    "Out of Memory",
+    "New SSL Sniffer Server Registered",
+    "Checking IP Header",
+    "SSL Sniffer Server Not Registered",
+    "Checking TCP Header",
+
+    /* 6 */
+    "SSL Sniffer Server Port Not Registered",
+    "RSA Private Decrypt Error",
+    "RSA Private Decode Error",
+    "Set Cipher Spec Error",
+    "Server Hello Input Malformed",
+
+    /* 11 */
+    "Couldn't Resume Session Error",
+    "Server Did Resumption",
+    "Client Hello Input Malformed",
+    "Client Trying to Resume",
+    "Handshake Input Malformed",
+
+    /* 16 */
+    "Got Hello Verify msg",
+    "Got Server Hello msg",
+    "Got Cert Request msg",
+    "Got Server Key Exchange msg",
+    "Got Cert msg",
+
+    /* 21 */
+    "Got Server Hello Done msg",
+    "Got Finished msg",
+    "Got Client Hello msg",
+    "Got Client Key Exchange msg",
+    "Got Cert Verify msg",
+
+    /* 26 */
+    "Got Unknown Handshake msg",
+    "New SSL Sniffer Session created",
+    "Couldn't create new SSL",
+    "Got a Packet to decode",
+    "No data present",
+
+    /* 31 */
+    "Session Not Found",
+    "Got an Old Client Hello msg",
+    "Old Client Hello Input Malformed",
+    "Old Client Hello OK",
+    "Bad Old Client Hello",
+
+    /* 36 */
+    "Bad Record Header",
+    "Record Header Input Malformed",
+    "Got a HandShake msg",
+    "Bad HandShake msg",
+    "Got a Change Cipher Spec msg",
+
+    /* 41 */
+    "Got Application Data msg",
+    "Bad Application Data",
+    "Got an Alert msg",
+    "Another msg to Process",
+    "Removing Session From Table",
+
+    /* 46 */
+    "Bad Key File",
+    "Wrong IP Version",
+    "Wrong Protocol type",
+    "Packet Short for header processing",
+    "Got Unknown Record Type",
+
+    /* 51 */
+    "Can't Open Trace File",
+    "Session in Fatal Error State",
+    "Partial SSL record received",
+    "Buffer Error, malformed input",
+    "Added to Partial Input",
+
+    /* 56 */
+    "Received a Duplicate Packet",
+    "Received an Out of Order Packet",
+    "Received an Overlap Duplicate Packet",
+    "Received an Overlap Reassembly Begin Duplicate Packet",
+    "Received an Overlap Reassembly End Duplicate Packet",
+
+    /* 61 */
+    "Missed the Client Hello Entirely",
+    "Got Hello Request msg",
+    "Got Session Ticket msg",
+    "Bad Input",
+    "Bad Decrypt Type",
+
+    /* 66 */
+    "Bad Finished Message Processing",
+    "Bad Compression Type",
+    "Bad DeriveKeys Error",
+    "Saw ACK for Missing Packet Error",
+    "Bad Decrypt Operation",
+
+    /* 71 */
+    "Decrypt Keys Not Set Up",
+    "Late Key Load Error",
+    "Got Certificate Status msg",
+    "RSA Key Missing Error",
+    "Secure Renegotiation Not Supported",
+
+    /* 76 */
+    "Get Session Stats Failure",
+    "Reassembly Buffer Size Exceeded",
+    "Dropping Lost Fragment",
+    "Dropping Partial Record",
+    "Clear ACK Fault",
+
+    /* 81 */
+    "Bad Decrypt Size",
+    "Extended Master Secret Hash Error",
+    "Handshake Message Split Across TLS Records",
+    "ECC Private Decode Error",
+    "ECC Public Decode Error",
+
+    /* 86 */
+    "Watch callback not set",
+    "Watch hash failed",
+    "Watch callback failed",
+    "Bad Certificate Message",
+    "Store data callback not set",
+
+    /* 91 */
+    "No data destination Error",
+    "Store data callback failed",
+    "Loading chain input"
+};
+
+
+/* *nix version uses table above */
+static void GetError(int idx, char* str)
+{
+    XSTRNCPY(str, msgTable[idx - 1], MAX_ERROR_LEN-1);
+    str[MAX_ERROR_LEN-1] = '\0';
+}
+
+
+#else /* _WIN32 */
+
+
+/* Windows version uses .rc table */
+static void GetError(int idx, char* buffer)
+{
+    if (!LoadStringA(dllModule, idx, buffer, MAX_ERROR_LEN))
+        buffer[0] = 0;
+}
+
+
+#endif /* _WIN32 */
+
+
+/* Packet Buffer for reassembly list and ready list */
+typedef struct PacketBuffer {
+    word32  begin;      /* relative sequence begin */
+    word32  end;        /* relative sequence end   */
+    byte*   data;       /* actual data             */
+    struct PacketBuffer* next; /* next on reassembly list or ready list */
+} PacketBuffer;
+
+
+#ifdef HAVE_SNI
+
+/* NamedKey maps a SNI name to a specific private key */
+typedef struct NamedKey {
+    char             name[MAX_SERVER_NAME];      /* server DNS name */
+    word32           nameSz;                     /* size of server DNS name */
+    byte*            key;                        /* DER private key */
+    word32           keySz;                      /* size of DER private key */
+    struct NamedKey* next;                       /* for list */
+} NamedKey;
+
+#endif
+
+
+typedef struct IpAddrInfo {
+    int version;
+    union {
+        word32 ip4;
+        byte   ip6[16];
+    };
+} IpAddrInfo;
+
+
+/* Sniffer Server holds info for each server/port monitored */
+typedef struct SnifferServer {
+    SSL_CTX*       ctx;                          /* SSL context */
+    char           address[MAX_SERVER_ADDRESS];  /* passed in server address */
+    IpAddrInfo     server;                       /* network order address */
+    int            port;                         /* server port */
+#ifdef HAVE_SNI
+    NamedKey*      namedKeys;                    /* mapping of names and keys */
+    wolfSSL_Mutex  namedKeysMutex;               /* mutex for namedKey list */
+#endif
+    struct SnifferServer* next;                  /* for list */
+} SnifferServer;
+
+
+/* Session Flags */
+typedef struct Flags {
+    byte           side;            /* which end is current packet headed */
+    byte           serverCipherOn;  /* indicates whether cipher is active */
+    byte           clientCipherOn;  /* indicates whether cipher is active */
+    byte           resuming;        /* did this session come from resumption */
+    byte           cached;          /* have we cached this session yet */
+    byte           clientHello;     /* processed client hello yet, for SSLv2 */
+    byte           finCount;        /* get both FINs before removing */
+    byte           fatalError;      /* fatal error state */
+    byte           cliAckFault;     /* client acked unseen data from server */
+    byte           srvAckFault;     /* server acked unseen data from client */
+    byte           cliSkipPartial;  /* client skips partial data to catch up */
+    byte           srvSkipPartial;  /* server skips partial data to catch up */
+#ifdef HAVE_EXTENDED_MASTER
+    byte           expectEms;       /* expect extended master secret */
+#endif
+} Flags;
+
+
+/* Out of Order FIN capture */
+typedef struct FinCaputre {
+    word32 cliFinSeq;               /* client relative sequence FIN  0 is no */
+    word32 srvFinSeq;               /* server relative sequence FIN, 0 is no */
+    byte   cliCounted;              /* did we count yet, detects duplicates */
+    byte   srvCounted;              /* did we count yet, detects duplicates */
+} FinCaputre;
+
+
+typedef struct HsHashes {
+#ifndef NO_OLD_TLS
+#ifndef NO_SHA
+    wc_Sha hashSha;
+#endif
+#ifndef NO_MD5
+    wc_Md5 hashMd5;
+#endif
+#endif
+#ifndef NO_SHA256
+    wc_Sha256 hashSha256;
+#endif
+#ifdef WOLFSSL_SHA384
+    wc_Sha384 hashSha384;
+#endif
+} HsHashes;
+
+
+/* Sniffer Session holds info for each client/server SSL/TLS session */
+typedef struct SnifferSession {
+    SnifferServer* context;         /* server context */
+    SSL*           sslServer;       /* SSL server side decode */
+    SSL*           sslClient;       /* SSL client side decode */
+    IpAddrInfo     server;          /* server address in network byte order */
+    IpAddrInfo     client;          /* client address in network byte order */
+    word16         srvPort;         /* server port */
+    word16         cliPort;         /* client port */
+    word32         cliSeqStart;     /* client start sequence */
+    word32         srvSeqStart;     /* server start sequence */
+    word32         cliExpected;     /* client expected sequence (relative) */
+    word32         srvExpected;     /* server expected sequence (relative) */
+    FinCaputre     finCaputre;      /* retain out of order FIN s */
+    Flags          flags;           /* session flags */
+    time_t         lastUsed;          /* last used ticks */
+    word32         keySz;           /* size of the private key */
+    PacketBuffer*  cliReassemblyList; /* client out of order packets */
+    PacketBuffer*  srvReassemblyList; /* server out of order packets */
+    word32         cliReassemblyMemory; /* client packet memory used */
+    word32         srvReassemblyMemory; /* server packet memory used */
+    struct SnifferSession* next;      /* for hash table list */
+    byte*          ticketID;          /* mac ID of session ticket */
+#ifdef HAVE_SNI
+    const char*    sni;             /* server name indication */
+#endif
+#ifdef HAVE_EXTENDED_MASTER
+    HsHashes*       hash;
+#endif
+} SnifferSession;
+
+
+/* Sniffer Server List and mutex */
+static WOLFSSL_GLOBAL SnifferServer* ServerList = 0;
+static WOLFSSL_GLOBAL wolfSSL_Mutex ServerListMutex;
+
+
+/* Session Hash Table, mutex, and count */
+static WOLFSSL_GLOBAL SnifferSession* SessionTable[HASH_SIZE];
+static WOLFSSL_GLOBAL wolfSSL_Mutex SessionMutex;
+static WOLFSSL_GLOBAL int SessionCount = 0;
+
+/* Recovery of missed data switches and stats */
+static WOLFSSL_GLOBAL wolfSSL_Mutex RecoveryMutex; /* for stats */
+static WOLFSSL_GLOBAL int RecoveryEnabled    = 0;  /* global switch */
+static WOLFSSL_GLOBAL int MaxRecoveryMemory  = -1;
+                                           /* per session max recovery memory */
+static WOLFSSL_GLOBAL word32 MissedDataSessions = 0;
+                                            /* # of sessions with missed data */
+
+/* Connection Info Callback */
+static WOLFSSL_GLOBAL SSLConnCb ConnectionCb;
+static WOLFSSL_GLOBAL void* ConnectionCbCtx = NULL;
+
+#ifdef WOLFSSL_SNIFFER_STATS
+/* Sessions Statistics */
+static WOLFSSL_GLOBAL SSLStats SnifferStats;
+static WOLFSSL_GLOBAL wolfSSL_Mutex StatsMutex;
+#endif
+
+#ifdef WOLFSSL_SNIFFER_WATCH
+/* Watch Key Callback */
+static WOLFSSL_GLOBAL SSLWatchCb WatchCb;
+static WOLFSSL_GLOBAL void* WatchCbCtx = NULL;
+#endif
+
+#ifdef WOLFSSL_SNIFFER_STORE_DATA_CB
+/* Store Data Callback */
+static WOLFSSL_GLOBAL SSLStoreDataCb StoreDataCb;
+#endif
+
+
+static void UpdateMissedDataSessions(void)
+{
+    wc_LockMutex(&RecoveryMutex);
+    MissedDataSessions += 1;
+    wc_UnLockMutex(&RecoveryMutex);
+}
+
+
+#ifdef WOLFSSL_SNIFFER_STATS
+#define LOCK_STAT() do { wc_LockMutex(&StatsMutex); } while (0)
+#define UNLOCK_STAT() do { wc_UnLockMutex(&StatsMutex); } while (0)
+#define NOLOCK_ADD_TO_STAT(x,y) do { TraceStat(#x, y); x += y; } while (0)
+#define NOLOCK_INC_STAT(x) NOLOCK_ADD_TO_STAT(x,1)
+#define ADD_TO_STAT(x,y) do { LOCK_STAT(); \
+    NOLOCK_ADD_TO_STAT(x,y); UNLOCK_STAT(); } while (0)
+#define INC_STAT(x) do { LOCK_STAT(); \
+    NOLOCK_INC_STAT(x); UNLOCK_STAT(); } while (0)
+#endif
+
+
+#ifdef WOLF_CRYPTO_CB
+    static WOLFSSL_GLOBAL int CryptoDeviceId = INVALID_DEVID;
+#endif
+
+
+/* Initialize overall Sniffer */
+void ssl_InitSniffer(void)
+{
+    wolfSSL_Init();
+    wc_InitMutex(&ServerListMutex);
+    wc_InitMutex(&SessionMutex);
+    wc_InitMutex(&RecoveryMutex);
+#ifdef WOLFSSL_SNIFFER_STATS
+    XMEMSET(&SnifferStats, 0, sizeof(SSLStats));
+    wc_InitMutex(&StatsMutex);
+#endif
+#ifdef WOLF_CRYPTO_CB
+    #ifdef HAVE_INTEL_QA_SYNC
+    CryptoDeviceId = wc_CryptoCb_InitIntelQa();
+    if (INVALID_DEVID == CryptoDeviceId) {
+        printf("Couldn't init the Intel QA\n");
+    }
+    #endif
+    #ifdef HAVE_CAVIUM_OCTEON_SYNC
+    CryptoDeviceId = wc_CryptoCb_InitOcteon();
+    if (INVALID_DEVID == CryptoDeviceId) {
+        printf("Couldn't init the Intel QA\n");
+    }
+    #endif
+#endif
+}
+
+
+#ifdef HAVE_SNI
+
+/* Free Named Key and the zero out the private key it holds */
+static void FreeNamedKey(NamedKey* in)
+{
+    if (in) {
+        if (in->key) {
+            ForceZero(in->key, in->keySz);
+            XFREE(in->key, NULL, DYNAMIC_TYPE_X509);
+        }
+        XFREE(in, NULL, DYNAMIC_TYPE_SNIFFER_NAMED_KEY);
+    }
+}
+
+
+static void FreeNamedKeyList(NamedKey* in)
+{
+    NamedKey* next;
+
+    while (in) {
+        next = in->next;
+        FreeNamedKey(in);
+        in = next;
+    }
+}
+
+#endif
+
+
+/* Free Sniffer Server's resources/self */
+static void FreeSnifferServer(SnifferServer* srv)
+{
+    if (srv) {
+#ifdef HAVE_SNI
+        wc_LockMutex(&srv->namedKeysMutex);
+        FreeNamedKeyList(srv->namedKeys);
+        wc_UnLockMutex(&srv->namedKeysMutex);
+        wc_FreeMutex(&srv->namedKeysMutex);
+#endif
+        SSL_CTX_free(srv->ctx);
+    }
+    XFREE(srv, NULL, DYNAMIC_TYPE_SNIFFER_SERVER);
+}
+
+
+/* free PacketBuffer's resources/self */
+static void FreePacketBuffer(PacketBuffer* del)
+{
+    if (del) {
+        XFREE(del->data, NULL, DYNAMIC_TYPE_SNIFFER_PB_BUFFER);
+        XFREE(del, NULL, DYNAMIC_TYPE_SNIFFER_PB);
+    }
+}
+
+
+/* remove PacketBuffer List */
+static void FreePacketList(PacketBuffer* in)
+{
+    if (in) {
+        PacketBuffer* del;
+        PacketBuffer* packet = in;
+
+        while (packet) {
+            del = packet;
+            packet = packet->next;
+            FreePacketBuffer(del);
+        }
+    }
+}
+
+
+/* Free Sniffer Session's resources/self */
+static void FreeSnifferSession(SnifferSession* session)
+{
+    if (session) {
+        SSL_free(session->sslClient);
+        SSL_free(session->sslServer);
+
+        FreePacketList(session->cliReassemblyList);
+        FreePacketList(session->srvReassemblyList);
+
+        XFREE(session->ticketID, NULL, DYNAMIC_TYPE_SNIFFER_TICKET_ID);
+#ifdef HAVE_EXTENDED_MASTER
+        XFREE(session->hash, NULL, DYNAMIC_TYPE_HASHES);
+#endif
+    }
+    XFREE(session, NULL, DYNAMIC_TYPE_SNIFFER_SESSION);
+}
+
+
+/* Free overall Sniffer */
+void ssl_FreeSniffer(void)
+{
+    SnifferServer*  srv;
+    SnifferServer*  removeServer;
+    SnifferSession* session;
+    SnifferSession* removeSession;
+    int i;
+
+    wc_LockMutex(&ServerListMutex);
+    wc_LockMutex(&SessionMutex);
+
+    srv = ServerList;
+    while (srv) {
+        removeServer = srv;
+        srv = srv->next;
+        FreeSnifferServer(removeServer);
+    }
+
+    for (i = 0; i < HASH_SIZE; i++) {
+        session = SessionTable[i];
+        while (session) {
+            removeSession = session;
+            session = session->next;
+            FreeSnifferSession(removeSession);
+        }
+    }
+
+    wc_UnLockMutex(&SessionMutex);
+    wc_UnLockMutex(&ServerListMutex);
+
+    wc_FreeMutex(&RecoveryMutex);
+    wc_FreeMutex(&SessionMutex);
+    wc_FreeMutex(&ServerListMutex);
+
+#ifdef WOLF_CRYPTO_CB
+#ifdef HAVE_INTEL_QA_SYNC
+    wc_CryptoCb_CleanupIntelQa(&CryptoDeviceId);
+#endif
+#ifdef HAVE_CAVIUM_OCTEON_SYNC
+    wc_CryptoCb_CleanupOcteon(&CryptoDeviceId);
+#endif
+#endif
+
+    if (TraceFile) {
+        TraceOn = 0;
+        fclose(TraceFile);
+        TraceFile = NULL;
+    }
+
+    wolfSSL_Cleanup();
+}
+
+
+#ifdef HAVE_EXTENDED_MASTER
+
+static int HashInit(HsHashes* hash)
+{
+    int ret = 0;
+
+    XMEMSET(hash, 0, sizeof(HsHashes));
+
+#ifndef NO_OLD_TLS
+#ifndef NO_SHA
+    if (ret == 0)
+        ret = wc_InitSha(&hash->hashSha);
+#endif
+#ifndef NO_MD5
+    if (ret == 0) {
+        ret = wc_InitMd5(&hash->hashMd5);
+    }
+#endif
+#endif
+#ifndef NO_SHA256
+    if (ret == 0)
+        ret = wc_InitSha256(&hash->hashSha256);
+#endif
+#ifdef WOLFSSL_SHA384
+    if (ret == 0)
+        ret = wc_InitSha384(&hash->hashSha384);
+#endif
+
+    return ret;
+}
+
+
+static int HashUpdate(HsHashes* hash, const byte* input, int sz)
+{
+    int ret = 0;
+
+    input -= HANDSHAKE_HEADER_SZ;
+    sz += HANDSHAKE_HEADER_SZ;
+
+#ifndef NO_OLD_TLS
+#ifndef NO_SHA
+    if (ret == 0)
+        ret = wc_ShaUpdate(&hash->hashSha, input, sz);
+#endif
+#ifndef NO_MD5
+    if (ret == 0) {
+        ret = wc_Md5Update(&hash->hashMd5, input, sz);
+    }
+#endif
+#endif
+#ifndef NO_SHA256
+    if (ret == 0)
+        ret = wc_Sha256Update(&hash->hashSha256, input, sz);
+#endif
+#ifdef WOLFSSL_SHA384
+    if (ret == 0)
+        ret = wc_Sha384Update(&hash->hashSha384, input, sz);
+#endif
+
+    return ret;
+}
+
+
+static int HashCopy(HS_Hashes* d, HsHashes* s)
+{
+#ifndef NO_OLD_TLS
+#ifndef NO_SHA
+        XMEMCPY(&d->hashSha, &s->hashSha, sizeof(wc_Sha));
+#endif
+#ifndef NO_MD5
+        XMEMCPY(&d->hashMd5, &s->hashMd5, sizeof(wc_Md5));
+#endif
+#endif
+
+#ifndef NO_SHA256
+        XMEMCPY(&d->hashSha256, &s->hashSha256, sizeof(wc_Sha256));
+#endif
+#ifdef WOLFSSL_SHA384
+        XMEMCPY(&d->hashSha384, &s->hashSha384, sizeof(wc_Sha384));
+#endif
+
+    return 0;
+}
+
+#endif
+
+
+/* Initialize a SnifferServer */
+static void InitSnifferServer(SnifferServer* sniffer)
+{
+    XMEMSET(sniffer, 0, sizeof(SnifferServer));
+}
+
+
+/* Initialize session flags */
+static void InitFlags(Flags* flags)
+{
+    XMEMSET(flags, 0, sizeof(Flags));
+}
+
+
+/* Initialize FIN Capture */
+static void InitFinCapture(FinCaputre* cap)
+{
+    XMEMSET(cap, 0, sizeof(FinCaputre));
+}
+
+
+/* Initialize a Sniffer Session */
+static void InitSession(SnifferSession* session)
+{
+    XMEMSET(session, 0, sizeof(SnifferSession));
+    InitFlags(&session->flags);
+    InitFinCapture(&session->finCaputre);
+}
+
+
+/* IP Info from IP Header */
+typedef struct IpInfo {
+    int    length;        /* length of this header */
+    int    total;         /* total length of fragment */
+    IpAddrInfo src;       /* network order source address */
+    IpAddrInfo dst;       /* network order destination address */
+} IpInfo;
+
+
+/* TCP Info from TCP Header */
+typedef struct TcpInfo {
+    int    srcPort;       /* source port */
+    int    dstPort;       /* source port */
+    int    length;        /* length of this header */
+    word32 sequence;      /* sequence number */
+    word32 ackNumber;     /* ack number */
+    byte   fin;           /* FIN set */
+    byte   rst;           /* RST set */
+    byte   syn;           /* SYN set */
+    byte   ack;           /* ACK set */
+} TcpInfo;
+
+
+/* Tcp Pseudo Header for Checksum calculation */
+typedef struct TcpPseudoHdr {
+    word32  src;        /* source address */
+    word32  dst;        /* destination address */
+    byte    rsv;        /* reserved, always 0 */
+    byte    protocol;   /* IP protocol */
+    word16  length;     /* tcp header length + data length (doesn't include */
+                        /* pseudo header length) network order */
+} TcpPseudoHdr;
+
+
+/* Password Setting Callback */
+static int SetPassword(char* passwd, int sz, int rw, void* userdata)
+{
+    (void)rw;
+    XSTRNCPY(passwd, (const char*)userdata, sz);
+    return (int)XSTRLEN((const char*)userdata);
+}
+
+
+/* Ethernet Header */
+typedef struct EthernetHdr {
+    byte   dst[ETHER_IF_ADDR_LEN];    /* destination host address */
+    byte   src[ETHER_IF_ADDR_LEN];    /* source  host address */
+    word16 type;                      /* IP, ARP, etc */
+} EthernetHdr;
+
+
+/* IPv4 Header */
+typedef struct IpHdr {
+    byte    ver_hl;              /* version/header length */
+    byte    tos;                 /* type of service */
+    word16  length;              /* total length */
+    word16  id;                  /* identification */
+    word16  offset;              /* fragment offset field */
+    byte    ttl;                 /* time to live */
+    byte    protocol;            /* protocol */
+    word16  sum;                 /* checksum */
+    word32  src;                 /* source address */
+    word32  dst;                 /* destination address */
+} IpHdr;
+
+
+/* IPv6 Header */
+typedef struct Ip6Hdr {
+    byte    ver_hl;              /* version/traffic class high */
+    byte    tc_fl;               /* traffic class low/flow label high */
+    word16  fl;                  /* flow label low */
+    word16  length;              /* payload length */
+    byte    next_header;         /* next header (6 for TCP, any other skip) */
+    byte    hl;                  /* hop limit */
+    byte    src[16];             /* source address */
+    byte    dst[16];             /* destination address */
+} Ip6Hdr;
+
+
+/* IPv6 extension header */
+typedef struct Ip6ExtHdr {
+    byte next_header;            /* next header (6 for TCP, any other skip) */
+    byte length;                 /* length in 8-octet units - 1 */
+    byte reserved[6];
+} Ip6ExtHdr;
+
+
+#define IP_HL(ip)      ( (((ip)->ver_hl) & 0x0f) * 4)
+#define IP_V(ip)       ( ((ip)->ver_hl) >> 4)
+
+/* TCP Header */
+typedef struct TcpHdr {
+    word16  srcPort;            /* source port */
+    word16  dstPort;            /* destination port */
+    word32  sequence;           /* sequence number */
+    word32  ack;                /* acknowledgment number */
+    byte    offset;             /* data offset, reserved */
+    byte    flags;              /* option flags */
+    word16  window;             /* window */
+    word16  sum;                /* checksum */
+    word16  urgent;             /* urgent pointer */
+} TcpHdr;
+
+#define TCP_LEN(tcp)  ( (((tcp)->offset & 0xf0) >> 4) * 4)
+#define TCP_FIN 0x01
+#define TCP_SYN 0x02
+#define TCP_RST 0x04
+#define TCP_ACK 0x10
+
+
+
+
+
+/* Use platform specific GetError to write to trace file if tracing */
+static void Trace(int idx)
+{
+    if (TraceOn) {
+        char myBuffer[MAX_ERROR_LEN];
+        GetError(idx, myBuffer);
+        fprintf(TraceFile, "\t%s\n", myBuffer);
+#ifdef DEBUG_SNIFFER
+        fprintf(stderr,    "\t%s\n", myBuffer);
+#endif
+    }
+}
+
+
+/* Show TimeStamp for beginning of packet Trace */
+static void TraceHeader(void)
+{
+    if (TraceOn) {
+        time_t ticks = time(NULL);
+        fprintf(TraceFile, "\n%s", ctime(&ticks));
+    }
+}
+
+
+/* Show Set Server info for Trace */
+static void TraceSetServer(const char* srv, int port, const char* keyFile)
+{
+    if (TraceOn) {
+        fprintf(TraceFile, "\tTrying to install a new Sniffer Server with\n");
+        fprintf(TraceFile, "\tserver: %s, port: %d, keyFile: %s\n", srv, port,
+                                                                    keyFile);
+    }
+}
+
+
+#ifdef HAVE_SNI
+
+/* Show Set Named Server info for Trace */
+static void TraceSetNamedServer(const char* name,
+                                 const char* srv, int port, const char* keyFile)
+{
+    if (TraceOn) {
+        fprintf(TraceFile, "\tTrying to install a new Sniffer Server with\n");
+        fprintf(TraceFile, "\tname: %s, server: %s, port: %d, keyFile: %s\n",
+                                                      name, srv, port, keyFile);
+    }
+}
+
+#endif
+
+
+/* Trace got packet number */
+static void TracePacket(void)
+{
+    if (TraceOn) {
+        static word32 packetNumber = 0;
+        fprintf(TraceFile, "\tGot a Packet to decode, packet %u\n",
+                ++packetNumber);
+    }
+}
+
+
+/* Convert network byte order address into human readable */
+static const char* IpToS(int version, void* src, char* dst)
+{
+    return inet_ntop(version, src, dst, TRACE_MSG_SZ);
+}
+
+
+/* Show destination and source address from Ip Hdr for packet Trace */
+static void TraceIP(IpHdr* iphdr)
+{
+    if (TraceOn) {
+        char src[TRACE_MSG_SZ];
+        char dst[TRACE_MSG_SZ];
+        fprintf(TraceFile, "\tdst:%s src:%s\n",
+                IpToS(AF_INET, &iphdr->dst, dst),
+                IpToS(AF_INET, &iphdr->src, src));
+    }
+}
+
+
+/* Show destination and source address from Ip6Hdr for packet Trace */
+static void TraceIP6(Ip6Hdr* iphdr)
+{
+    if (TraceOn) {
+        char src[TRACE_MSG_SZ];
+        char dst[TRACE_MSG_SZ];
+        fprintf(TraceFile, "\tdst: %s src: %s\n",
+                IpToS(AF_INET6, iphdr->dst, dst),
+                IpToS(AF_INET6, iphdr->src, src));
+    }
+}
+
+
+/* Show destination and source port from Tcp Hdr for packet Trace */
+static void TraceTcp(TcpHdr* tcphdr)
+{
+    if (TraceOn) {
+        fprintf(TraceFile, "\tdstPort:%u srcPort:%u\n", ntohs(tcphdr->dstPort),
+                ntohs(tcphdr->srcPort));
+    }
+}
+
+
+/* Show sequence and payload length for Trace */
+static void TraceSequence(word32 seq, int len)
+{
+    if (TraceOn) {
+        fprintf(TraceFile, "\tSequence:%u, payload length:%d\n", seq, len);
+    }
+}
+
+
+/* Show sequence and payload length for Trace */
+static void TraceAck(word32 ack, word32 expected)
+{
+    if (TraceOn) {
+        fprintf(TraceFile, "\tAck:%u Expected:%u\n", ack, expected);
+    }
+}
+
+
+/* Show relative expected and relative received sequences */
+static void TraceRelativeSequence(word32 expected, word32 got)
+{
+    if (TraceOn) {
+        fprintf(TraceFile, "\tExpected sequence:%u, received sequence:%u\n",
+                expected, got);
+    }
+}
+
+
+/* Show server sequence startup from SYN */
+static void TraceServerSyn(word32 seq)
+{
+    if (TraceOn) {
+        fprintf(TraceFile, "\tServer SYN, Sequence Start:%u\n", seq);
+    }
+}
+
+
+/* Show client sequence startup from SYN */
+static void TraceClientSyn(word32 seq)
+{
+    if (TraceOn) {
+        fprintf(TraceFile, "\tClient SYN, Sequence Start:%u\n", seq);
+    }
+}
+
+
+/* Show client FIN capture */
+static void TraceClientFin(word32 finSeq, word32 relSeq)
+{
+    if (TraceOn) {
+        fprintf(TraceFile, "\tClient FIN capture:%u, current SEQ:%u\n",
+                finSeq, relSeq);
+    }
+}
+
+
+/* Show server FIN capture */
+static void TraceServerFin(word32 finSeq, word32 relSeq)
+{
+    if (TraceOn) {
+        fprintf(TraceFile, "\tServer FIN capture:%u, current SEQ:%u\n",
+                finSeq, relSeq);
+    }
+}
+
+
+/* Show number of SSL data bytes decoded, could be 0 (ok) */
+static void TraceGotData(int bytes)
+{
+    if (TraceOn) {
+        fprintf(TraceFile, "\t%d bytes of SSL App data processed\n", bytes);
+    }
+}
+
+
+/* Show bytes added to old SSL App data */
+static void TraceAddedData(int newBytes, int existingBytes)
+{
+    if (TraceOn) {
+        fprintf(TraceFile,
+                "\t%d bytes added to %d existing bytes in User Buffer\n",
+                newBytes, existingBytes);
+    }
+}
+
+
+/* Show Stale Session */
+static void TraceStaleSession(void)
+{
+    if (TraceOn) {
+        fprintf(TraceFile, "\tFound a stale session\n");
+    }
+}
+
+
+/* Show Finding Stale Sessions */
+static void TraceFindingStale(void)
+{
+    if (TraceOn) {
+        fprintf(TraceFile, "\tTrying to find Stale Sessions\n");
+    }
+}
+
+
+/* Show Removed Session */
+static void TraceRemovedSession(void)
+{
+    if (TraceOn) {
+        fprintf(TraceFile, "\tRemoved it\n");
+    }
+}
+
+
+/* Show SSLInfo if provided and is valid. */
+static void TraceSessionInfo(SSLInfo* sslInfo)
+{
+    if (TraceOn) {
+        if (sslInfo != NULL && sslInfo->isValid) {
+            fprintf(TraceFile,
+                    "\tver:(%u %u) suiteId:(%02x %02x) suiteName:(%s) "
+                    #ifdef HAVE_SNI
+                    "sni:(%s) "
+                    #endif
+                    "keySize:(%u)\n",
+                    sslInfo->protocolVersionMajor,
+                    sslInfo->protocolVersionMinor,
+                    sslInfo->serverCipherSuite0,
+                    sslInfo->serverCipherSuite,
+                    sslInfo->serverCipherSuiteName,
+                    #ifdef HAVE_SNI
+                    sslInfo->serverNameIndication,
+                    #endif
+                    sslInfo->keySize);
+        }
+    }
+}
+
+
+#ifdef WOLFSSL_SNIFFER_STATS
+
+/* Show value added to a named statistic. */
+static void TraceStat(const char* name, int add)
+{
+    if (TraceOn) {
+        fprintf(TraceFile, "\tAdding %d to %s\n", add, name);
+    }
+}
+
+#endif
+
+
+/* Set user error string */
+static void SetError(int idx, char* error, SnifferSession* session, int fatal)
+{
+    GetError(idx, error);
+    Trace(idx);
+    if (session && fatal == FATAL_ERROR_STATE)
+        session->flags.fatalError = 1;
+}
+
+
+/* Compare IpAddrInfo structs */
+static WC_INLINE int MatchAddr(IpAddrInfo l, IpAddrInfo r)
+{
+    if (l.version == r.version) {
+        if (l.version == IPV4)
+            return (l.ip4 == r.ip4);
+        else if (l.version == IPV6)
+            return (0 == XMEMCMP(l.ip6, r.ip6, sizeof(l.ip6)));
+    }
+    return 0;
+}
+
+
+#ifndef WOLFSSL_SNIFFER_WATCH
+
+/* See if this IPV4 network order address has been registered */
+/* return 1 is true, 0 is false */
+static int IsServerRegistered(word32 addr)
+{
+    int ret = 0;     /* false */
+    SnifferServer* sniffer;
+
+    wc_LockMutex(&ServerListMutex);
+
+    sniffer = ServerList;
+    while (sniffer) {
+        if (sniffer->server.ip4 == addr) {
+            ret = 1;
+            break;
+        }
+        sniffer = sniffer->next;
+    }
+
+    wc_UnLockMutex(&ServerListMutex);
+
+    return ret;
+}
+
+
+/* See if this port has been registered to watch */
+/* See if this IPV4 network order address has been registered */
+/* return 1 is true, 0 is false */
+static int IsServerRegistered6(byte* addr)
+{
+    int ret = 0;     /* false */
+    SnifferServer* sniffer;
+
+    wc_LockMutex(&ServerListMutex);
+
+    sniffer = ServerList;
+    while (sniffer) {
+        if (sniffer->server.version == IPV6 &&
+                0 == XMEMCMP(sniffer->server.ip6, addr, sizeof(sniffer->server.ip6))) {
+            ret = 1;
+            break;
+        }
+        sniffer = sniffer->next;
+    }
+
+    wc_UnLockMutex(&ServerListMutex);
+
+    return ret;
+}
+
+
+/* See if this port has been registered to watch */
+/* return 1 is true, 0 is false */
+static int IsPortRegistered(word32 port)
+{
+    int ret = 0;    /* false */
+    SnifferServer* sniffer;
+
+    wc_LockMutex(&ServerListMutex);
+
+    sniffer = ServerList;
+    while (sniffer) {
+        if (sniffer->port == (int)port) {
+            ret = 1;
+            break;
+        }
+        sniffer = sniffer->next;
+    }
+
+    wc_UnLockMutex(&ServerListMutex);
+
+    return ret;
+}
+
+#endif
+
+
+/* Get SnifferServer from IP and Port */
+static SnifferServer* GetSnifferServer(IpInfo* ipInfo, TcpInfo* tcpInfo)
+{
+    SnifferServer* sniffer;
+
+    wc_LockMutex(&ServerListMutex);
+
+    sniffer = ServerList;
+
+#ifndef WOLFSSL_SNIFFER_WATCH
+    while (sniffer) {
+        if (sniffer->port == tcpInfo->srcPort &&
+                MatchAddr(sniffer->server, ipInfo->src))
+            break;
+        if (sniffer->port == tcpInfo->dstPort &&
+                MatchAddr(sniffer->server, ipInfo->dst))
+            break;
+
+        sniffer = sniffer->next;
+    }
+#else
+    (void)ipInfo;
+    (void)tcpInfo;
+#endif
+
+    wc_UnLockMutex(&ServerListMutex);
+
+    return sniffer;
+}
+
+
+/* Hash the Session Info, return hash row */
+static word32 SessionHash(IpInfo* ipInfo, TcpInfo* tcpInfo)
+{
+    word32 hash = 1;
+
+    if (ipInfo->src.version == IPV4) {
+        hash *= ipInfo->src.ip4 * ipInfo->dst.ip4;
+    }
+    else if (ipInfo->src.version == IPV6) {
+        word32* x;
+        word32  y;
+        x = (word32*)ipInfo->src.ip6;
+        y = x[0] ^ x[1] ^ x[2] ^ x[3];
+        hash *= y;
+        x = (word32*)ipInfo->dst.ip6;
+        y = x[0] ^ x[1] ^ x[2] ^ x[3];
+        hash *= y;
+    }
+    hash *= tcpInfo->srcPort * tcpInfo->dstPort;
+
+    return hash % HASH_SIZE;
+}
+
+
+/* Get Existing SnifferSession from IP and Port */
+static SnifferSession* GetSnifferSession(IpInfo* ipInfo, TcpInfo* tcpInfo)
+{
+    SnifferSession* session;
+    time_t          currTime = time(NULL);
+    word32          row = SessionHash(ipInfo, tcpInfo);
+
+    assert(row <= HASH_SIZE);
+
+    wc_LockMutex(&SessionMutex);
+
+    session = SessionTable[row];
+    while (session) {
+        if (MatchAddr(session->server, ipInfo->src) &&
+            MatchAddr(session->client, ipInfo->dst) &&
+                    session->srvPort == tcpInfo->srcPort &&
+                    session->cliPort == tcpInfo->dstPort)
+            break;
+
+        if (MatchAddr(session->client, ipInfo->src) &&
+            MatchAddr(session->server, ipInfo->dst) &&
+                    session->cliPort == tcpInfo->srcPort &&
+                    session->srvPort == tcpInfo->dstPort)
+            break;
+
+        session = session->next;
+    }
+
+    if (session)
+        session->lastUsed= currTime; /* keep session alive, remove stale will */
+                                     /* leave alone */
+    wc_UnLockMutex(&SessionMutex);
+
+    /* determine side */
+    if (session) {
+        if (MatchAddr(ipInfo->dst, session->server) &&
+            tcpInfo->dstPort == session->srvPort) {
+
+            session->flags.side = WOLFSSL_SERVER_END;
+        }
+        else {
+            session->flags.side = WOLFSSL_CLIENT_END;
+        }
+    }
+
+    return session;
+}
+
+
+#if defined(HAVE_SNI) || defined(WOLFSSL_SNIFFER_WATCH)
+
+static int LoadKeyFile(byte** keyBuf, word32* keyBufSz,
+                const char* keyFile, int typeKey,
+                const char* password)
+{
+    byte* loadBuf;
+    long fileSz = 0;
+    XFILE file;
+    int ret;
+
+    if (keyBuf == NULL || keyBufSz == NULL || keyFile == NULL) {
+        return -1;
+    }
+
+    file = XFOPEN(keyFile, "rb");
+    if (file == XBADFILE) return -1;
+    if(XFSEEK(file, 0, XSEEK_END) != 0) {
+        XFCLOSE(file);
+        return -1;
+    }
+    fileSz = XFTELL(file);
+    if (fileSz > MAX_WOLFSSL_FILE_SIZE || fileSz < 0) {
+        XFCLOSE(file);
+        return -1;
+    }
+    XREWIND(file);
+
+    loadBuf = (byte*)XMALLOC(fileSz, NULL, DYNAMIC_TYPE_FILE);
+    if (loadBuf == NULL) {
+        XFCLOSE(file);
+        return -1;
+    }
+
+    ret = (int)XFREAD(loadBuf, 1, fileSz, file);
+    XFCLOSE(file);
+
+    if (ret != fileSz) {
+        XFREE(loadBuf, NULL, DYNAMIC_TYPE_FILE);
+        return -1;
+    }
+
+    if (typeKey == WOLFSSL_FILETYPE_PEM) {
+        byte* saveBuf   = (byte*)XMALLOC(fileSz, NULL, DYNAMIC_TYPE_X509);
+        int   saveBufSz = 0;
+
+        ret = -1;
+        if (saveBuf != NULL) {
+            saveBufSz = wc_KeyPemToDer(loadBuf, (int)fileSz,
+                                                saveBuf, (int)fileSz, password);
+            if (saveBufSz < 0) {
+                saveBufSz = 0;
+                XFREE(saveBuf, NULL, DYNAMIC_TYPE_X509);
+                saveBuf = NULL;
+            }
+            else
+                ret = 0;
+        }
+
+        ForceZero(loadBuf, (word32)fileSz);
+        XFREE(loadBuf, NULL, DYNAMIC_TYPE_FILE);
+
+        if (saveBuf) {
+            *keyBuf = saveBuf;
+            *keyBufSz = (word32)saveBufSz;
+        }
+    }
+    else {
+        *keyBuf = loadBuf;
+        *keyBufSz = (word32)fileSz;
+    }
+
+    if (ret < 0) {
+        return -1;
+    }
+
+    return ret;
+}
+
+#endif
+
+
+#ifdef WOLFSSL_SNIFFER_WATCH
+
+static int CreateWatchSnifferServer(char* error)
+{
+    SnifferServer* sniffer;
+
+    sniffer = (SnifferServer*)XMALLOC(sizeof(SnifferServer), NULL,
+            DYNAMIC_TYPE_SNIFFER_SERVER);
+    if (sniffer == NULL) {
+        SetError(MEMORY_STR, error, NULL, 0);
+        return -1;
+    }
+    InitSnifferServer(sniffer);
+    sniffer->ctx = SSL_CTX_new(TLSv1_2_client_method());
+    if (!sniffer->ctx) {
+        SetError(MEMORY_STR, error, NULL, 0);
+        FreeSnifferServer(sniffer);
+        return -1;
+    }
+#ifdef WOLF_CRYPTO_CB
+    if (CryptoDeviceId != INVALID_DEVID)
+	    wolfSSL_CTX_SetDevId(sniffer->ctx, CryptoDeviceId);
+#endif
+    ServerList = sniffer;
+
+    return 0;
+}
+
+#endif
+
+
+static int SetNamedPrivateKey(const char* name, const char* address, int port,
+            const char* keyFile, int typeKey, const char* password, char* error)
+{
+    SnifferServer* sniffer;
+    int            ret;
+    int            type = (typeKey == FILETYPE_PEM) ? WOLFSSL_FILETYPE_PEM :
+                                                      WOLFSSL_FILETYPE_ASN1;
+    int            isNew = 0;
+    IpAddrInfo     serverIp;
+
+#ifdef HAVE_SNI
+    NamedKey* namedKey = NULL;
+#endif
+
+    (void)name;
+#ifdef HAVE_SNI
+    if (name != NULL) {
+        namedKey = (NamedKey*)XMALLOC(sizeof(NamedKey),
+                NULL, DYNAMIC_TYPE_SNIFFER_NAMED_KEY);
+        if (namedKey == NULL) {
+            SetError(MEMORY_STR, error, NULL, 0);
+            return -1;
+        }
+        XMEMSET(namedKey, 0, sizeof(NamedKey));
+
+        namedKey->nameSz = (word32)XSTRLEN(name);
+        if (namedKey->nameSz > sizeof(namedKey->name)-1)
+            namedKey->nameSz = sizeof(namedKey->name)-1;
+        XSTRNCPY(namedKey->name, name, namedKey->nameSz);
+        namedKey->name[MAX_SERVER_NAME-1] = '\0';
+
+        ret = LoadKeyFile(&namedKey->key, &namedKey->keySz,
+                          keyFile, type, password);
+        if (ret < 0) {
+            SetError(KEY_FILE_STR, error, NULL, 0);
+            FreeNamedKey(namedKey);
+            return -1;
+        }
+    }
+#endif
+
+    serverIp.version = IPV4;
+    serverIp.ip4 = inet_addr(address);
+    if (serverIp.ip4 == INADDR_NONE) {
+        if (inet_pton(AF_INET6, address, serverIp.ip6) == 1) {
+            serverIp.version = IPV6;
+        }
+    }
+    sniffer = ServerList;
+    while (sniffer != NULL &&
+            (!MatchAddr(sniffer->server, serverIp) || sniffer->port != port)) {
+        sniffer = sniffer->next;
+    }
+
+    if (sniffer == NULL) {
+        isNew = 1;
+        sniffer = (SnifferServer*)XMALLOC(sizeof(SnifferServer),
+                NULL, DYNAMIC_TYPE_SNIFFER_SERVER);
+        if (sniffer == NULL) {
+            SetError(MEMORY_STR, error, NULL, 0);
+#ifdef HAVE_SNI
+            FreeNamedKey(namedKey);
+#endif
+            return -1;
+        }
+        InitSnifferServer(sniffer);
+
+        XSTRNCPY(sniffer->address, address, MAX_SERVER_ADDRESS-1);
+        sniffer->address[MAX_SERVER_ADDRESS-1] = '\0';
+        sniffer->server = serverIp;
+        sniffer->port = port;
+
+        sniffer->ctx = SSL_CTX_new(TLSv1_2_client_method());
+        if (!sniffer->ctx) {
+            SetError(MEMORY_STR, error, NULL, 0);
+#ifdef HAVE_SNI
+            FreeNamedKey(namedKey);
+#endif
+            FreeSnifferServer(sniffer);
+            return -1;
+        }
+    }
+
+    if (name == NULL) {
+        if (password) {
+    #ifdef WOLFSSL_ENCRYPTED_KEYS
+            SSL_CTX_set_default_passwd_cb(sniffer->ctx, SetPassword);
+            SSL_CTX_set_default_passwd_cb_userdata(
+                                                 sniffer->ctx, (void*)password);
+    #endif
+        }
+        ret = SSL_CTX_use_PrivateKey_file(sniffer->ctx, keyFile, type);
+        if (ret != WOLFSSL_SUCCESS) {
+            SetError(KEY_FILE_STR, error, NULL, 0);
+            if (isNew)
+                FreeSnifferServer(sniffer);
+            return -1;
+        }
+	#ifdef WOLF_CRYPTO_CB
+		wolfSSL_CTX_SetDevId(sniffer->ctx, CryptoDeviceId);
+	#endif
+    }
+#ifdef HAVE_SNI
+    else {
+        wc_LockMutex(&sniffer->namedKeysMutex);
+        namedKey->next = sniffer->namedKeys;
+        sniffer->namedKeys = namedKey;
+        wc_UnLockMutex(&sniffer->namedKeysMutex);
+    }
+#endif
+
+    if (isNew) {
+        sniffer->next = ServerList;
+        ServerList = sniffer;
+    }
+
+    return 0;
+}
+
+
+#ifdef HAVE_SNI
+
+/* Sets the private key for a specific name, server and port  */
+/* returns 0 on success, -1 on error */
+int ssl_SetNamedPrivateKey(const char* name,
+                           const char* address, int port,
+                           const char* keyFile, int typeKey,
+                           const char* password, char* error)
+{
+    int ret;
+
+    TraceHeader();
+    TraceSetNamedServer(name, address, port, keyFile);
+
+    wc_LockMutex(&ServerListMutex);
+    ret = SetNamedPrivateKey(name, address, port, keyFile,
+                             typeKey, password, error);
+    wc_UnLockMutex(&ServerListMutex);
+
+    if (ret == 0)
+        Trace(NEW_SERVER_STR);
+
+    return ret;
+}
+
+#endif
+
+
+/* Sets the private key for a specific server and port  */
+/* returns 0 on success, -1 on error */
+int ssl_SetPrivateKey(const char* address, int port, const char* keyFile,
+                      int typeKey, const char* password, char* error)
+{
+    int ret;
+
+    TraceHeader();
+    TraceSetServer(address, port, keyFile);
+
+    wc_LockMutex(&ServerListMutex);
+    ret = SetNamedPrivateKey(NULL, address, port, keyFile,
+                             typeKey, password, error);
+    wc_UnLockMutex(&ServerListMutex);
+
+    if (ret == 0)
+        Trace(NEW_SERVER_STR);
+
+    return ret;
+}
+
+
+/* Check IP Header for IPV6, TCP, and a registered server address */
+/* returns 0 on success, -1 on error */
+static int CheckIp6Hdr(Ip6Hdr* iphdr, IpInfo* info, int length, char* error)
+{
+    int        version = IP_V(iphdr);
+    int        exthdrsz = IP6_HDR_SZ;
+
+    TraceIP6(iphdr);
+    Trace(IP_CHECK_STR);
+
+    if (version != IPV6) {
+        SetError(BAD_IPVER_STR, error, NULL, 0);
+        return -1;
+    }
+
+    /* Here, we need to move onto next header if not TCP. */
+    if (iphdr->next_header != TCP_PROTOCOL) {
+        Ip6ExtHdr* exthdr = (Ip6ExtHdr*)((byte*)iphdr + IP6_HDR_SZ);
+        do {
+            int hdrsz = (exthdr->length + 1) * 8;
+            if (hdrsz > length - exthdrsz) {
+                SetError(PACKET_HDR_SHORT_STR, error, NULL, 0);
+                return -1;
+            }
+            exthdrsz += hdrsz;
+            exthdr = (Ip6ExtHdr*)((byte*)exthdr + hdrsz);
+        }
+        while (exthdr->next_header != TCP_PROTOCOL &&
+                exthdr->next_header != NO_NEXT_HEADER);
+    }
+
+#ifndef WOLFSSL_SNIFFER_WATCH
+    if (!IsServerRegistered6(iphdr->src) && !IsServerRegistered6(iphdr->dst)) {
+        SetError(SERVER_NOT_REG_STR, error, NULL, 0);
+        return -1;
+    }
+#endif
+
+    info->length = exthdrsz;
+    info->total = ntohs(iphdr->length) + info->length;
+        /* IPv6 doesn't include its own header size in the length like v4. */
+    info->src.version = IPV6;
+    XMEMCPY(info->src.ip6, iphdr->src, sizeof(info->src.ip6));
+    info->dst.version = IPV6;
+    XMEMCPY(info->dst.ip6, iphdr->dst, sizeof(info->dst.ip6));
+
+    return 0;
+}
+
+
+/* Check IP Header for IPV4, TCP, and a registered server address */
+/* If header IPv6, pass to CheckIp6Hdr(). */
+/* returns 0 on success, -1 on error */
+static int CheckIpHdr(IpHdr* iphdr, IpInfo* info, int length, char* error)
+{
+    int    version = IP_V(iphdr);
+
+    if (version == IPV6)
+        return CheckIp6Hdr((Ip6Hdr*)iphdr, info, length, error);
+
+    TraceIP(iphdr);
+    Trace(IP_CHECK_STR);
+
+    if (version != IPV4) {
+        SetError(BAD_IPVER_STR, error, NULL, 0);
+        return -1;
+    }
+
+    if (iphdr->protocol != TCP_PROTOCOL) {
+        SetError(BAD_PROTO_STR, error, NULL, 0);
+        return -1;
+    }
+
+#ifndef WOLFSSL_SNIFFER_WATCH
+    if (!IsServerRegistered(iphdr->src) && !IsServerRegistered(iphdr->dst)) {
+        SetError(SERVER_NOT_REG_STR, error, NULL, 0);
+        return -1;
+    }
+#endif
+
+    info->length  = IP_HL(iphdr);
+    info->total   = ntohs(iphdr->length);
+    info->src.version = IPV4;
+    info->src.ip4 = iphdr->src;
+    info->dst.version = IPV4;
+    info->dst.ip4 = iphdr->dst;
+
+    if (info->total == 0)
+        info->total = length;  /* reassembled may be off */
+
+    return 0;
+}
+
+
+/* Check TCP Header for a registered port */
+/* returns 0 on success, -1 on error */
+static int CheckTcpHdr(TcpHdr* tcphdr, TcpInfo* info, char* error)
+{
+    TraceTcp(tcphdr);
+    Trace(TCP_CHECK_STR);
+    info->srcPort   = ntohs(tcphdr->srcPort);
+    info->dstPort   = ntohs(tcphdr->dstPort);
+    info->length    = TCP_LEN(tcphdr);
+    info->sequence  = ntohl(tcphdr->sequence);
+    info->fin       = tcphdr->flags & TCP_FIN;
+    info->rst       = tcphdr->flags & TCP_RST;
+    info->syn       = tcphdr->flags & TCP_SYN;
+    info->ack       = tcphdr->flags & TCP_ACK;
+    if (info->ack)
+        info->ackNumber = ntohl(tcphdr->ack);
+
+#ifndef WOLFSSL_SNIFFER_WATCH
+    if (!IsPortRegistered(info->srcPort) && !IsPortRegistered(info->dstPort)) {
+        SetError(SERVER_PORT_NOT_REG_STR, error, NULL, 0);
+        return -1;
+    }
+#else
+    (void)error;
+#endif
+
+    return 0;
+}
+
+
+/* Decode Record Layer Header */
+static int GetRecordHeader(const byte* input, RecordLayerHeader* rh, int* size)
+{
+    XMEMCPY(rh, input, RECORD_HEADER_SZ);
+    *size = (rh->length[0] << 8) | rh->length[1];
+
+    if (*size > (MAX_RECORD_SIZE + COMP_EXTRA + MAX_MSG_EXTRA))
+        return LENGTH_ERROR;
+
+    return 0;
+}
+
+
+/* Copies the session's information to the provided sslInfo. Skip copy if
+ * SSLInfo is not provided. */
+static void CopySessionInfo(SnifferSession* session, SSLInfo* sslInfo)
+{
+    if (NULL != sslInfo) {
+        XMEMSET(sslInfo, 0, sizeof(SSLInfo));
+
+        /* Pass back Session Info after we have processed the Server Hello. */
+        if (0 != session->sslServer->options.cipherSuite) {
+            const char* pCipher;
+
+            sslInfo->isValid = 1;
+            sslInfo->protocolVersionMajor = session->sslServer->version.major;
+            sslInfo->protocolVersionMinor = session->sslServer->version.minor;
+            sslInfo->serverCipherSuite0 =
+                        session->sslServer->options.cipherSuite0;
+            sslInfo->serverCipherSuite =
+                        session->sslServer->options.cipherSuite;
+
+            pCipher = wolfSSL_get_cipher(session->sslServer);
+            if (NULL != pCipher) {
+                XSTRNCPY((char*)sslInfo->serverCipherSuiteName, pCipher,
+                         sizeof(sslInfo->serverCipherSuiteName));
+                sslInfo->serverCipherSuiteName
+                         [sizeof(sslInfo->serverCipherSuiteName) - 1] = '\0';
+            }
+            sslInfo->keySize = session->keySz;
+            #ifdef HAVE_SNI
+            if (NULL != session->sni) {
+                XSTRNCPY((char*)sslInfo->serverNameIndication,
+                         session->sni, sizeof(sslInfo->serverNameIndication));
+                sslInfo->serverNameIndication
+                         [sizeof(sslInfo->serverNameIndication) - 1] = '\0';
+            }
+            #endif
+            TraceSessionInfo(sslInfo);
+        }
+    }
+}
+
+
+/* Call the session connection start callback. */
+static void CallConnectionCb(SnifferSession* session)
+{
+    if (ConnectionCb != NULL) {
+        SSLInfo info;
+        CopySessionInfo(session, &info);
+        ConnectionCb((const void*)session, &info, ConnectionCbCtx);
+    }
+}
+
+
+/* Process Client Key Exchange, RSA or static ECDH */
+static int ProcessClientKeyExchange(const byte* input, int* sslBytes,
+                                    SnifferSession* session, char* error)
+{
+    word32 idx = 0;
+    int tryEcc = 0;
+    int ret;
+
+    if (session->sslServer->buffers.key == NULL ||
+        session->sslServer->buffers.key->buffer == NULL ||
+        session->sslServer->buffers.key->length == 0) {
+
+        SetError(RSA_KEY_MISSING_STR, error, session, FATAL_ERROR_STATE);
+        return -1;
+    }
+
+    {
+        RsaKey key;
+        int length;
+
+        ret = wc_InitRsaKey(&key, 0);
+        if (ret == 0) {
+            ret = wc_RsaPrivateKeyDecode(
+                    session->sslServer->buffers.key->buffer,
+                    &idx, &key, session->sslServer->buffers.key->length);
+            if (ret != 0) {
+                tryEcc = 1;
+                #ifndef HAVE_ECC
+                    SetError(RSA_DECODE_STR, error, session, FATAL_ERROR_STATE);
+                #else
+                    /* If we can do ECC, this isn't fatal. Not loading an ECC
+                     * key will be fatal, though. */
+                    SetError(RSA_DECODE_STR, error, session, 0);
+                #endif
+            }
+        }
+
+        if (ret == 0) {
+            length = wc_RsaEncryptSize(&key);
+            if (IsTLS(session->sslServer)) {
+                input += 2;     /* tls pre length */
+            }
+
+            if (length > *sslBytes) {
+                SetError(PARTIAL_INPUT_STR, error, session, FATAL_ERROR_STATE);
+                ret = -1;
+            }
+        }
+
+        #ifdef WC_RSA_BLINDING
+        if (ret == 0) {
+            ret = wc_RsaSetRNG(&key, session->sslServer->rng);
+            if (ret != 0) {
+                SetError(RSA_DECRYPT_STR, error, session, FATAL_ERROR_STATE);
+            }
+        }
+        #endif
+
+        if (ret == 0) {
+            session->keySz = length * WOLFSSL_BIT_SIZE;
+            /* length is the key size in bytes */
+            session->sslServer->arrays->preMasterSz = SECRET_LEN;
+
+            do {
+            #ifdef WOLFSSL_ASYNC_CRYPT
+                ret = wc_AsyncWait(ret, &key.asyncDev,
+                        WC_ASYNC_FLAG_CALL_AGAIN);
+            #endif
+                if (ret >= 0) {
+                    ret = wc_RsaPrivateDecrypt(input, length,
+                          session->sslServer->arrays->preMasterSecret,
+                          session->sslServer->arrays->preMasterSz, &key);
+                }
+            } while (ret == WC_PENDING_E);
+
+            if (ret != SECRET_LEN) {
+                SetError(RSA_DECRYPT_STR, error, session, FATAL_ERROR_STATE);
+            }
+        }
+
+        wc_FreeRsaKey(&key);
+    }
+
+    if (tryEcc) {
+#ifdef HAVE_ECC
+        ecc_key key;
+        ecc_key pubKey;
+        int length, keyInit = 0, pubKeyInit = 0;
+
+        idx = 0;
+        ret = wc_ecc_init(&key);
+        if (ret == 0) {
+            keyInit = 1;
+            ret = wc_ecc_init(&pubKey);
+        }
+        if (ret == 0) {
+            pubKeyInit = 1;
+            ret = wc_EccPrivateKeyDecode(
+                    session->sslServer->buffers.key->buffer,
+                    &idx, &key, session->sslServer->buffers.key->length);
+            if (ret != 0) {
+                SetError(ECC_DECODE_STR, error, session, FATAL_ERROR_STATE);
+            }
+        }
+
+        if (ret == 0) {
+            length = wc_ecc_size(&key) * 2 + 1;
+            /* The length should be 2 times the key size (x and y), plus 1
+             * for the type byte. */
+            if (IsTLS(session->sslServer)) {
+                input += 1; /* Don't include the TLS length for the key. */
+            }
+
+            if (length + 1 > *sslBytes) {
+                SetError(PARTIAL_INPUT_STR,
+                        error, session, FATAL_ERROR_STATE);
+                ret = -1;
+            }
+        }
+
+        if (ret == 0) {
+            ret = wc_ecc_import_x963_ex(input, length, &pubKey, ECC_CURVE_DEF);
+            if (ret != 0) {
+                SetError(ECC_PUB_DECODE_STR, error, session, FATAL_ERROR_STATE);
+            }
+        }
+
+        if (ret == 0) {
+            session->keySz = ((length - 1) / 2) * WOLFSSL_BIT_SIZE;
+            /* Length is in bytes. Subtract 1 for the ECC key type. Divide
+             * by two as the key is in (x,y) coordinates, where x and y are
+             * the same size, the key size. Convert from bytes to bits. */
+            session->sslServer->arrays->preMasterSz = ENCRYPT_LEN;
+
+            do {
+            #ifdef WOLFSSL_ASYNC_CRYPT
+                ret = wc_AsyncWait(ret, &key.asyncDev,
+                        WC_ASYNC_FLAG_CALL_AGAIN);
+            #endif
+                if (ret >= 0) {
+                    ret = wc_ecc_shared_secret(&key, &pubKey,
+                          session->sslServer->arrays->preMasterSecret,
+                          &session->sslServer->arrays->preMasterSz);
+                }
+            } while (ret == WC_PENDING_E);
+        }
+
+#ifdef WOLFSSL_SNIFFER_STATS
+        if (ret != 0)
+            INC_STAT(SnifferStats.sslKeyFails);
+#endif
+
+        if (keyInit)
+            wc_ecc_free(&key);
+        if (pubKeyInit)
+            wc_ecc_free(&pubKey);
+#endif
+    }
+
+    /* store for client side as well */
+    XMEMCPY(session->sslClient->arrays->preMasterSecret,
+           session->sslServer->arrays->preMasterSecret,
+           session->sslServer->arrays->preMasterSz);
+    session->sslClient->arrays->preMasterSz =
+        session->sslServer->arrays->preMasterSz;
+
+    #ifdef SHOW_SECRETS
+    {
+        word32 i;
+        printf("pre master secret: ");
+        for (i = 0; i < session->sslServer->arrays->preMasterSz; i++)
+            printf("%02x", session->sslServer->arrays->preMasterSecret[i]);
+        printf("\n");
+    }
+    #endif
+
+    if (SetCipherSpecs(session->sslServer) != 0) {
+        SetError(BAD_CIPHER_SPEC_STR, error, session, FATAL_ERROR_STATE);
+        return -1;
+    }
+
+    if (SetCipherSpecs(session->sslClient) != 0) {
+        SetError(BAD_CIPHER_SPEC_STR, error, session, FATAL_ERROR_STATE);
+        return -1;
+    }
+
+    ret  = MakeMasterSecret(session->sslServer);
+    ret += MakeMasterSecret(session->sslClient);
+    ret += SetKeysSide(session->sslServer, ENCRYPT_AND_DECRYPT_SIDE);
+    ret += SetKeysSide(session->sslClient, ENCRYPT_AND_DECRYPT_SIDE);
+
+    if (ret != 0) {
+        SetError(BAD_DERIVE_STR, error, session, FATAL_ERROR_STATE);
+        return -1;
+    }
+
+#ifdef SHOW_SECRETS
+    {
+        int i;
+        printf("server master secret: ");
+        for (i = 0; i < SECRET_LEN; i++)
+            printf("%02x", session->sslServer->arrays->masterSecret[i]);
+        printf("\n");
+
+        printf("client master secret: ");
+        for (i = 0; i < SECRET_LEN; i++)
+            printf("%02x", session->sslClient->arrays->masterSecret[i]);
+        printf("\n");
+
+        printf("server suite = %d\n", session->sslServer->options.cipherSuite);
+        printf("client suite = %d\n", session->sslClient->options.cipherSuite);
+    }
+#endif
+
+    CallConnectionCb(session);
+
+    return ret;
+}
+
+
+/* Process Session Ticket */
+static int ProcessSessionTicket(const byte* input, int* sslBytes,
+                                SnifferSession* session, char* error)
+{
+    word16 len;
+
+    /* make sure can read through hint and len */
+    if (TICKET_HINT_LEN + LENGTH_SZ > *sslBytes) {
+        SetError(BAD_INPUT_STR, error, session, FATAL_ERROR_STATE);
+        return -1;
+    }
+
+    input     += TICKET_HINT_LEN;  /* skip over hint */
+    *sslBytes -= TICKET_HINT_LEN;
+
+    len = (word16)((input[0] << 8) | input[1]);
+    input     += LENGTH_SZ;
+    *sslBytes -= LENGTH_SZ;
+
+    /* make sure can read through ticket */
+    if (len > *sslBytes || len < ID_LEN) {
+        SetError(BAD_INPUT_STR, error, session, FATAL_ERROR_STATE);
+        return -1;
+    }
+
+    /* store session with macID as sessionID */
+    session->sslServer->options.haveSessionId = 1;
+    XMEMCPY(session->sslServer->arrays->sessionID, input + len - ID_LEN,ID_LEN);
+
+    return 0;
+}
+
+
+/* Process Server Hello */
+static int ProcessServerHello(int msgSz, const byte* input, int* sslBytes,
+                              SnifferSession* session, char* error)
+{
+    ProtocolVersion pv;
+    byte            b, b0;
+    int             toRead = VERSION_SZ + RAN_LEN + ENUM_LEN;
+    int             doResume     = 0;
+    int             initialBytes = *sslBytes;
+
+    (void)msgSz;
+    (void)initialBytes;
+
+    /* make sure we didn't miss ClientHello */
+    if (session->flags.clientHello == 0) {
+        SetError(MISSED_CLIENT_HELLO_STR, error, session, FATAL_ERROR_STATE);
+        return -1;
+    }
+
+    /* make sure can read through session len */
+    if (toRead > *sslBytes) {
+        SetError(SERVER_HELLO_INPUT_STR, error, session, FATAL_ERROR_STATE);
+        return -1;
+    }
+
+    XMEMCPY(&pv, input, VERSION_SZ);
+    input     += VERSION_SZ;
+    *sslBytes -= VERSION_SZ;
+
+    session->sslServer->version = pv;
+    session->sslClient->version = pv;
+
+    XMEMCPY(session->sslServer->arrays->serverRandom, input, RAN_LEN);
+    XMEMCPY(session->sslClient->arrays->serverRandom, input, RAN_LEN);
+    input    += RAN_LEN;
+    *sslBytes -= RAN_LEN;
+
+    b = *input++;
+    *sslBytes -= 1;
+
+    /* make sure can read through compression */
+    if ( (b + SUITE_LEN + ENUM_LEN) > *sslBytes) {
+        SetError(SERVER_HELLO_INPUT_STR, error, session, FATAL_ERROR_STATE);
+        return -1;
+    }
+    if (b) {
+        XMEMCPY(session->sslServer->arrays->sessionID, input, ID_LEN);
+        session->sslServer->options.haveSessionId = 1;
+    }
+    input     += b;
+    *sslBytes -= b;
+
+    /* cipher suite */
+    b0 = *input++;  /* first byte, ECC or not */
+    session->sslServer->options.cipherSuite0 = b0;
+    session->sslClient->options.cipherSuite0 = b0;
+    b = *input++;
+    session->sslServer->options.cipherSuite = b;
+    session->sslClient->options.cipherSuite = b;
+    *sslBytes -= SUITE_LEN;
+
+#ifdef WOLFSSL_SNIFFER_STATS
+    {
+        const CipherSuiteInfo* suites = GetCipherNames();
+        int suitesSz = GetCipherNamesSize();
+        int match = 0;
+
+        while (suitesSz) {
+            if (b0 == suites->cipherSuite0 && b == suites->cipherSuite) {
+                match = 1;
+                break;
+            }
+            suites++;
+            suitesSz--;
+        }
+        if (!match)
+            INC_STAT(SnifferStats.sslCiphersUnsupported);
+    }
+#endif /* WOLFSSL_SNIFFER_STATS */
+
+    /* compression */
+    b = *input++;
+    *sslBytes -= ENUM_LEN;
+
+    if (b) {
+        SetError(BAD_COMPRESSION_STR, error, session, FATAL_ERROR_STATE);
+        return -1;
+    }
+
+#ifdef HAVE_EXTENDED_MASTER
+    /* extensions */
+    if ((initialBytes - *sslBytes) < msgSz) {
+        word16 len;
+
+        /* skip extensions until extended master secret */
+        /* make sure can read len */
+        if (SUITE_LEN > *sslBytes) {
+            SetError(SERVER_HELLO_INPUT_STR, error, session, FATAL_ERROR_STATE);
+            return -1;
+        }
+        len = (word16)((input[0] << 8) | input[1]);
+        input     += SUITE_LEN;
+        *sslBytes -= SUITE_LEN;
+        /* make sure can read through all extensions */
+        if (len > *sslBytes) {
+            SetError(SERVER_HELLO_INPUT_STR, error, session, FATAL_ERROR_STATE);
+            return -1;
+        }
+
+        while (len >= EXT_TYPE_SZ + LENGTH_SZ) {
+            byte   extType[EXT_TYPE_SZ];
+            word16 extLen;
+
+            extType[0] = input[0];
+            extType[1] = input[1];
+            input     += EXT_TYPE_SZ;
+            *sslBytes -= EXT_TYPE_SZ;
+
+            extLen = (word16)((input[0] << 8) | input[1]);
+            input     += LENGTH_SZ;
+            *sslBytes -= LENGTH_SZ;
+
+            /* make sure can read through individual extension */
+            if (extLen > *sslBytes) {
+                SetError(SERVER_HELLO_INPUT_STR, error, session,
+                         FATAL_ERROR_STATE);
+                return -1;
+            }
+
+            if (extType[0] == 0x00 && extType[1] == EXT_MASTER_SECRET) {
+                session->flags.expectEms = 1;
+            }
+
+            input     += extLen;
+            *sslBytes -= extLen;
+            len       -= extLen + EXT_TYPE_SZ + LENGTH_SZ;
+        }
+    }
+
+    if (!session->flags.expectEms) {
+        XFREE(session->hash, NULL, DYNAMIC_TYPE_HASHES);
+        session->hash = NULL;
+    }
+#endif
+
+    if (session->sslServer->options.haveSessionId) {
+        if (XMEMCMP(session->sslServer->arrays->sessionID,
+                    session->sslClient->arrays->sessionID, ID_LEN) == 0)
+            doResume = 1;
+    }
+    else if (session->sslClient->options.haveSessionId == 0 &&
+             session->sslServer->options.haveSessionId == 0 &&
+             session->ticketID)
+        doResume = 1;
+
+    if (session->ticketID && doResume) {
+        /* use ticketID to retrieve from session, prefer over sessionID */
+        XMEMCPY(session->sslServer->arrays->sessionID,session->ticketID,ID_LEN);
+        session->sslServer->options.haveSessionId = 1;  /* may not have
+                                                           actual sessionID */
+    }
+
+    if (doResume ) {
+        int ret = 0;
+        SSL_SESSION* resume = GetSession(session->sslServer,
+                                  session->sslServer->arrays->masterSecret, 0);
+        if (resume == NULL) {
+#ifdef WOLFSSL_SNIFFER_STATS
+            INC_STAT(SnifferStats.sslResumeMisses);
+#endif
+            SetError(BAD_SESSION_RESUME_STR, error, session, FATAL_ERROR_STATE);
+            return -1;
+        }
+        /* make sure client has master secret too */
+        XMEMCPY(session->sslClient->arrays->masterSecret,
+               session->sslServer->arrays->masterSecret, SECRET_LEN);
+        session->flags.resuming = 1;
+
+        Trace(SERVER_DID_RESUMPTION_STR);
+#ifdef WOLFSSL_SNIFFER_STATS
+        INC_STAT(SnifferStats.sslResumedConns);
+        INC_STAT(SnifferStats.sslResumptionValid);
+#endif
+        if (SetCipherSpecs(session->sslServer) != 0) {
+            SetError(BAD_CIPHER_SPEC_STR, error, session, FATAL_ERROR_STATE);
+            return -1;
+        }
+
+        if (SetCipherSpecs(session->sslClient) != 0) {
+            SetError(BAD_CIPHER_SPEC_STR, error, session, FATAL_ERROR_STATE);
+            return -1;
+        }
+
+        if (session->sslServer->options.tls) {
+            ret =  DeriveTlsKeys(session->sslServer);
+            ret += DeriveTlsKeys(session->sslClient);
+        }
+        else {
+            ret =  DeriveKeys(session->sslServer);
+            ret += DeriveKeys(session->sslClient);
+        }
+        ret += SetKeysSide(session->sslServer, ENCRYPT_AND_DECRYPT_SIDE);
+        ret += SetKeysSide(session->sslClient, ENCRYPT_AND_DECRYPT_SIDE);
+
+        if (ret != 0) {
+            SetError(BAD_DERIVE_STR, error, session, FATAL_ERROR_STATE);
+            return -1;
+        }
+    }
+    else {
+#ifdef WOLFSSL_SNIFFER_STATS
+        INC_STAT(SnifferStats.sslStandardConns);
+#endif
+    }
+#ifdef SHOW_SECRETS
+    {
+        int i;
+        printf("cipher suite = 0x%02x\n",
+               session->sslServer->options.cipherSuite);
+        printf("server random: ");
+        for (i = 0; i < RAN_LEN; i++)
+            printf("%02x", session->sslServer->arrays->serverRandom[i]);
+        printf("\n");
+    }
+#endif
+    return 0;
+}
+
+
+/* Process normal Client Hello */
+static int ProcessClientHello(const byte* input, int* sslBytes,
+                              SnifferSession* session, char* error)
+{
+    byte   bLen;
+    word16 len;
+    int    toRead = VERSION_SZ + RAN_LEN + ENUM_LEN;
+
+#ifdef HAVE_SNI
+    {
+        byte name[MAX_SERVER_NAME];
+        word32 nameSz = sizeof(name);
+        int ret;
+
+        ret = wolfSSL_SNI_GetFromBuffer(
+                             input - HANDSHAKE_HEADER_SZ - RECORD_HEADER_SZ,
+                             *sslBytes + HANDSHAKE_HEADER_SZ + RECORD_HEADER_SZ,
+                             WOLFSSL_SNI_HOST_NAME, name, &nameSz);
+
+        if (ret == WOLFSSL_SUCCESS) {
+            NamedKey* namedKey;
+
+            if (nameSz > sizeof(name) - 1)
+                nameSz = sizeof(name) - 1;
+            name[nameSz] = 0;
+            wc_LockMutex(&session->context->namedKeysMutex);
+            namedKey = session->context->namedKeys;
+            while (namedKey != NULL) {
+                if (nameSz == namedKey->nameSz &&
+                           XSTRNCMP((char*)name, namedKey->name, nameSz) == 0) {
+                    if (wolfSSL_use_PrivateKey_buffer(session->sslServer,
+                                            namedKey->key, namedKey->keySz,
+                                            WOLFSSL_FILETYPE_ASN1) != WOLFSSL_SUCCESS) {
+                        wc_UnLockMutex(&session->context->namedKeysMutex);
+                        SetError(CLIENT_HELLO_LATE_KEY_STR, error, session,
+                                                             FATAL_ERROR_STATE);
+                        return -1;
+                    }
+                    session->sni = namedKey->name;
+                    break;
+                }
+                else
+                    namedKey = namedKey->next;
+            }
+            wc_UnLockMutex(&session->context->namedKeysMutex);
+        }
+    }
+#endif
+
+    session->flags.clientHello = 1;  /* don't process again */
+
+    /* make sure can read up to session len */
+    if (toRead > *sslBytes) {
+        SetError(CLIENT_HELLO_INPUT_STR, error, session, FATAL_ERROR_STATE);
+        return -1;
+    }
+
+    /* skip, get negotiated one from server hello */
+    input     += VERSION_SZ;
+    *sslBytes -= VERSION_SZ;
+
+    XMEMCPY(session->sslServer->arrays->clientRandom, input, RAN_LEN);
+    XMEMCPY(session->sslClient->arrays->clientRandom, input, RAN_LEN);
+
+    input     += RAN_LEN;
+    *sslBytes -= RAN_LEN;
+
+    /* store session in case trying to resume */
+    bLen = *input++;
+    *sslBytes -= ENUM_LEN;
+    if (bLen) {
+        if (ID_LEN > *sslBytes) {
+            SetError(CLIENT_HELLO_INPUT_STR, error, session, FATAL_ERROR_STATE);
+            return -1;
+        }
+        Trace(CLIENT_RESUME_TRY_STR);
+        XMEMCPY(session->sslClient->arrays->sessionID, input, ID_LEN);
+        session->sslClient->options.haveSessionId = 1;
+    }
+#ifdef SHOW_SECRETS
+    {
+        int i;
+        printf("client random: ");
+        for (i = 0; i < RAN_LEN; i++)
+            printf("%02x", session->sslServer->arrays->clientRandom[i]);
+        printf("\n");
+    }
+#endif
+
+    input     += bLen;
+    *sslBytes -= bLen;
+
+    /* skip cipher suites */
+    /* make sure can read len */
+    if (SUITE_LEN > *sslBytes) {
+        SetError(CLIENT_HELLO_INPUT_STR, error, session, FATAL_ERROR_STATE);
+        return -1;
+    }
+    len = (word16)((input[0] << 8) | input[1]);
+    input     += SUITE_LEN;
+    *sslBytes -= SUITE_LEN;
+    /* make sure can read suites + comp len */
+    if (len + ENUM_LEN > *sslBytes) {
+        SetError(CLIENT_HELLO_INPUT_STR, error, session, FATAL_ERROR_STATE);
+        return -1;
+    }
+    input     += len;
+    *sslBytes -= len;
+
+    /* skip compression */
+    bLen       = *input++;
+    *sslBytes -= ENUM_LEN;
+    /* make sure can read len */
+    if (bLen > *sslBytes) {
+        SetError(CLIENT_HELLO_INPUT_STR, error, session, FATAL_ERROR_STATE);
+        return -1;
+    }
+    input     += bLen;
+    *sslBytes -= bLen;
+
+    if (*sslBytes == 0) {
+        /* no extensions */
+        return 0;
+    }
+
+    /* skip extensions until session ticket */
+    /* make sure can read len */
+    if (SUITE_LEN > *sslBytes) {
+        SetError(CLIENT_HELLO_INPUT_STR, error, session, FATAL_ERROR_STATE);
+        return -1;
+    }
+    len = (word16)((input[0] << 8) | input[1]);
+    input     += SUITE_LEN;
+    *sslBytes -= SUITE_LEN;
+    /* make sure can read through all extensions */
+    if (len > *sslBytes) {
+        SetError(CLIENT_HELLO_INPUT_STR, error, session, FATAL_ERROR_STATE);
+        return -1;
+    }
+
+    while (len >= EXT_TYPE_SZ + LENGTH_SZ) {
+        byte   extType[EXT_TYPE_SZ];
+        word16 extLen;
+
+        extType[0] = input[0];
+        extType[1] = input[1];
+        input     += EXT_TYPE_SZ;
+        *sslBytes -= EXT_TYPE_SZ;
+
+        extLen = (word16)((input[0] << 8) | input[1]);
+        input     += LENGTH_SZ;
+        *sslBytes -= LENGTH_SZ;
+
+        /* make sure can read through individual extension */
+        if (extLen > *sslBytes) {
+            SetError(CLIENT_HELLO_INPUT_STR, error, session, FATAL_ERROR_STATE);
+            return -1;
+        }
+
+        if (extType[0] == 0x00 && extType[1] == TICKET_EXT_ID) {
+
+            /* make sure can read through ticket if there is a non blank one */
+            if (extLen && extLen < ID_LEN) {
+                SetError(CLIENT_HELLO_INPUT_STR, error, session,
+                         FATAL_ERROR_STATE);
+                return -1;
+            }
+
+            if (extLen) {
+                if (session->ticketID == 0) {
+                    session->ticketID = (byte*)XMALLOC(ID_LEN,
+                            NULL, DYNAMIC_TYPE_SNIFFER_TICKET_ID);
+                    if (session->ticketID == 0) {
+                        SetError(MEMORY_STR, error, session,
+                                 FATAL_ERROR_STATE);
+                        return -1;
+                    }
+                }
+                XMEMCPY(session->ticketID, input + extLen - ID_LEN, ID_LEN);
+            }
+        }
+
+        input     += extLen;
+        *sslBytes -= extLen;
+        len       -= extLen + EXT_TYPE_SZ + LENGTH_SZ;
+    }
+
+    return 0;
+}
+
+
+#ifdef WOLFSSL_SNIFFER_WATCH
+
+/* Process Certificate */
+static int ProcessCertificate(const byte* input, int* sslBytes,
+        SnifferSession* session, char* error)
+{
+    Sha256 sha;
+    const byte* certChain;
+    word32 certChainSz;
+    word32 certSz;
+    int ret;
+    byte digest[SHA256_DIGEST_SIZE];
+
+    /* If the receiver is the server, this is the client certificate message,
+     * and it should be ignored at this point. */
+    if (session->flags.side == WOLFSSL_SERVER_END)
+        return 0;
+
+    if (WatchCb == NULL) {
+        SetError(WATCH_CB_MISSING_STR, error, session, FATAL_ERROR_STATE);
+        return -1;
+    }
+
+    if (*sslBytes < CERT_HEADER_SZ) {
+        SetError(BAD_CERT_MSG_STR, error, session, FATAL_ERROR_STATE);
+        return -1;
+    }
+    ato24(input, &certChainSz);
+    *sslBytes -= CERT_HEADER_SZ;
+    input += CERT_HEADER_SZ;
+
+    if (*sslBytes < (int)certChainSz) {
+        SetError(BAD_CERT_MSG_STR, error, session, FATAL_ERROR_STATE);
+        return -1;
+    }
+    certChain = input;
+
+    ato24(input, &certSz);
+    input += OPAQUE24_LEN;
+    if (*sslBytes < (int)certSz) {
+        SetError(BAD_CERT_MSG_STR, error, session, FATAL_ERROR_STATE);
+        return -1;
+    }
+
+    *sslBytes -= certChainSz;
+
+    ret = wc_InitSha256(&sha);
+    if (ret == 0)
+        ret = wc_Sha256Update(&sha, input, certSz);
+    if (ret == 0)
+        ret = wc_Sha256Final(&sha, digest);
+    if (ret != 0) {
+        SetError(WATCH_HASH_STR, error, session, FATAL_ERROR_STATE);
+        return -1;
+    }
+
+    ret = WatchCb((void*)session, digest, sizeof(digest),
+            certChain, certChainSz, WatchCbCtx, error);
+    if (ret != 0) {
+#ifdef WOLFSSL_SNIFFER_STATS
+        INC_STAT(SnifferStats.sslKeysUnmatched);
+#endif
+        SetError(WATCH_FAIL_STR, error, session, FATAL_ERROR_STATE);
+        return -1;
+    }
+    else {
+#ifdef WOLFSSL_SNIFFER_STATS
+        INC_STAT(SnifferStats.sslKeyMatches);
+#endif
+    }
+
+    return 0;
+}
+
+#endif
+
+
+/* Process Finished */
+static int ProcessFinished(const byte* input, int size, int* sslBytes,
+                           SnifferSession* session, char* error)
+{
+    SSL*   ssl;
+    word32 inOutIdx = 0;
+    int    ret;
+
+    if (session->flags.side == WOLFSSL_SERVER_END)
+        ssl = session->sslServer;
+    else
+        ssl = session->sslClient;
+
+    ret = DoFinished(ssl, input, &inOutIdx, (word32) size, (word32) *sslBytes,
+                                                                         SNIFF);
+    *sslBytes -= (int)inOutIdx;
+
+    if (ret < 0) {
+        SetError(BAD_FINISHED_MSG, error, session, FATAL_ERROR_STATE);
+        return ret;
+    }
+
+    if (ret == 0 && session->flags.cached == 0) {
+        if (session->sslServer->options.haveSessionId) {
+            WOLFSSL_SESSION* sess = GetSession(session->sslServer, NULL, 0);
+            if (sess == NULL) {
+                AddSession(session->sslServer);  /* don't re add */
+#ifdef WOLFSSL_SNIFFER_STATS
+                INC_STAT(SnifferStats.sslResumptionInserts);
+#endif
+            }
+            session->flags.cached = 1;
+         }
+    }
+
+    /* If receiving a finished message from one side, free the resources
+     * from the other side's tracker. */
+    if (session->flags.side == WOLFSSL_SERVER_END)
+        FreeHandshakeResources(session->sslClient);
+    else
+        FreeHandshakeResources(session->sslServer);
+
+    return ret;
+}
+
+
+/* Process HandShake input */
+static int DoHandShake(const byte* input, int* sslBytes,
+                       SnifferSession* session, char* error)
+{
+    byte type;
+    int  size;
+    int  ret = 0;
+    int  startBytes;
+
+    if (*sslBytes < HANDSHAKE_HEADER_SZ) {
+        SetError(HANDSHAKE_INPUT_STR, error, session, FATAL_ERROR_STATE);
+        return -1;
+    }
+    type = input[0];
+    size = (input[1] << 16) | (input[2] << 8) | input[3];
+
+    input     += HANDSHAKE_HEADER_SZ;
+    *sslBytes -= HANDSHAKE_HEADER_SZ;
+    startBytes = *sslBytes;
+
+    if (*sslBytes < size) {
+        Trace(SPLIT_HANDSHAKE_MSG_STR);
+        *sslBytes = 0;
+        return ret;
+    }
+
+    /* A session's arrays are released when the handshake is completed. */
+    if (session->sslServer->arrays == NULL &&
+        session->sslClient->arrays == NULL) {
+
+        SetError(NO_SECURE_RENEGOTIATION, error, session, FATAL_ERROR_STATE);
+        return -1;
+    }
+
+#ifdef HAVE_EXTENDED_MASTER
+    if (session->hash) {
+        if (HashUpdate(session->hash, input, size) != 0) {
+            SetError(EXTENDED_MASTER_HASH_STR, error,
+                     session, FATAL_ERROR_STATE);
+            return -1;
+        }
+    }
+#endif
+
+    switch (type) {
+        case hello_verify_request:
+            Trace(GOT_HELLO_VERIFY_STR);
+            break;
+        case hello_request:
+            Trace(GOT_HELLO_REQUEST_STR);
+            break;
+        case session_ticket:
+            Trace(GOT_SESSION_TICKET_STR);
+            ret = ProcessSessionTicket(input, sslBytes, session, error);
+            break;
+        case server_hello:
+            Trace(GOT_SERVER_HELLO_STR);
+            ret = ProcessServerHello(size, input, sslBytes, session, error);
+            break;
+        case certificate_request:
+            Trace(GOT_CERT_REQ_STR);
+            break;
+        case server_key_exchange:
+#ifdef WOLFSSL_SNIFFER_STATS
+            INC_STAT(SnifferStats.sslEphemeralMisses);
+#endif
+            Trace(GOT_SERVER_KEY_EX_STR);
+            /* can't know temp key passively */
+            SetError(BAD_CIPHER_SPEC_STR, error, session, FATAL_ERROR_STATE);
+            ret = -1;
+            break;
+        case certificate:
+            Trace(GOT_CERT_STR);
+            if (session->flags.side == WOLFSSL_SERVER_END) {
+#ifdef WOLFSSL_SNIFFER_STATS
+                INC_STAT(SnifferStats.sslClientAuthConns);
+#endif
+            }
+#ifdef WOLFSSL_SNIFFER_WATCH
+            ret = ProcessCertificate(input, sslBytes, session, error);
+#endif
+            break;
+        case server_hello_done:
+            Trace(GOT_SERVER_HELLO_DONE_STR);
+            break;
+        case finished:
+            Trace(GOT_FINISHED_STR);
+            ret = ProcessFinished(input, size, sslBytes, session, error);
+            break;
+        case client_hello:
+            Trace(GOT_CLIENT_HELLO_STR);
+            ret = ProcessClientHello(input, sslBytes, session, error);
+            break;
+        case client_key_exchange:
+            Trace(GOT_CLIENT_KEY_EX_STR);
+#ifdef HAVE_EXTENDED_MASTER
+            if (session->flags.expectEms && session->hash != NULL) {
+                if (HashCopy(session->sslServer->hsHashes,
+                             session->hash) == 0 &&
+                    HashCopy(session->sslClient->hsHashes,
+                             session->hash) == 0) {
+
+                    session->sslServer->options.haveEMS = 1;
+                    session->sslClient->options.haveEMS = 1;
+                }
+                else {
+                    SetError(EXTENDED_MASTER_HASH_STR, error,
+                             session, FATAL_ERROR_STATE);
+                    ret = -1;
+                }
+                XMEMSET(session->hash, 0, sizeof(HsHashes));
+                XFREE(session->hash, NULL, DYNAMIC_TYPE_HASHES);
+                session->hash = NULL;
+            }
+            else {
+                session->sslServer->options.haveEMS = 0;
+                session->sslClient->options.haveEMS = 0;
+            }
+#endif
+            if (ret == 0)
+                ret = ProcessClientKeyExchange(input, sslBytes, session, error);
+            break;
+        case certificate_verify:
+            Trace(GOT_CERT_VER_STR);
+            break;
+        case certificate_status:
+            Trace(GOT_CERT_STATUS_STR);
+            break;
+        default:
+            SetError(GOT_UNKNOWN_HANDSHAKE_STR, error, session, 0);
+            return -1;
+    }
+
+    *sslBytes = startBytes - size;  /* actual bytes of full process */
+
+    return ret;
+}
+
+
+/* Decrypt input into plain output, 0 on success */
+static int Decrypt(SSL* ssl, byte* output, const byte* input, word32 sz)
+{
+    int ret = 0;
+
+    (void)output;
+    (void)input;
+    (void)sz;
+
+    switch (ssl->specs.bulk_cipher_algorithm) {
+        #ifdef BUILD_ARC4
+        case wolfssl_rc4:
+            wc_Arc4Process(ssl->decrypt.arc4, output, input, sz);
+            break;
+        #endif
+
+        #ifdef BUILD_DES3
+        case wolfssl_triple_des:
+            ret = wc_Des3_CbcDecrypt(ssl->decrypt.des3, output, input, sz);
+            break;
+        #endif
+
+        #ifdef BUILD_AES
+        case wolfssl_aes:
+            ret = wc_AesCbcDecrypt(ssl->decrypt.aes, output, input, sz);
+            break;
+        #endif
+
+        #ifdef HAVE_HC128
+        case wolfssl_hc128:
+            wc_Hc128_Process(ssl->decrypt.hc128, output, input, sz);
+            break;
+        #endif
+
+        #ifdef BUILD_RABBIT
+        case wolfssl_rabbit:
+            wc_RabbitProcess(ssl->decrypt.rabbit, output, input, sz);
+            break;
+        #endif
+
+        #ifdef HAVE_CAMELLIA
+        case wolfssl_camellia:
+            wc_CamelliaCbcDecrypt(ssl->decrypt.cam, output, input, sz);
+            break;
+        #endif
+
+        #ifdef HAVE_IDEA
+        case wolfssl_idea:
+            wc_IdeaCbcDecrypt(ssl->decrypt.idea, output, input, sz);
+            break;
+        #endif
+
+        #ifdef HAVE_AESGCM
+        case wolfssl_aes_gcm:
+            if (sz >= (word32)(AESGCM_EXP_IV_SZ + ssl->specs.aead_mac_size))
+            {
+                /* scratch buffer, sniffer ignores auth tag*/
+                byte authTag[WOLFSSL_MIN_AUTH_TAG_SZ];
+
+                byte nonce[AESGCM_NONCE_SZ];
+                XMEMCPY(nonce, ssl->keys.aead_dec_imp_IV, AESGCM_IMP_IV_SZ);
+                XMEMCPY(nonce + AESGCM_IMP_IV_SZ, input, AESGCM_EXP_IV_SZ);
+
+                if (wc_AesGcmEncrypt(ssl->decrypt.aes,
+                            output,
+                            input + AESGCM_EXP_IV_SZ,
+                            sz - AESGCM_EXP_IV_SZ - ssl->specs.aead_mac_size,
+                            nonce, AESGCM_NONCE_SZ,
+                            authTag, sizeof(authTag),
+                            NULL, 0) < 0) {
+                    Trace(BAD_DECRYPT);
+                    ret = -1;
+                }
+                ForceZero(nonce, AESGCM_NONCE_SZ);
+            }
+            else {
+                Trace(BAD_DECRYPT_SIZE);
+                ret = -1;
+            }
+            break;
+         #endif
+
+        #ifdef HAVE_NULL_CIPHER
+        case wolfssl_cipher_null:
+            XMEMCPY(output, input, sz);
+            break;
+        #endif
+
+        default:
+            Trace(BAD_DECRYPT_TYPE);
+            ret = -1;
+            break;
+    }
+
+    return ret;
+}
+
+
+/* Decrypt input message into output, adjust output steam if needed */
+static const byte* DecryptMessage(SSL* ssl, const byte* input, word32 sz,
+                                  byte* output, int* error, int* advance)
+{
+    int ivExtra = 0;
+
+    int ret = Decrypt(ssl, output, input, sz);
+    if (ret != 0) {
+        *error = ret;
+        return NULL;
+    }
+    ssl->keys.encryptSz = sz;
+    if (ssl->options.tls1_1 && ssl->specs.cipher_type == block) {
+        output += ssl->specs.block_size;     /* go past TLSv1.1 IV */
+        ivExtra = ssl->specs.block_size;
+        *advance = ssl->specs.block_size;
+    }
+
+    if (ssl->specs.cipher_type == aead) {
+        *advance = ssl->specs.aead_mac_size;
+        ssl->keys.padSz = ssl->specs.aead_mac_size;
+    }
+    else
+        ssl->keys.padSz = ssl->specs.hash_size;
+
+    if (ssl->specs.cipher_type == block)
+        ssl->keys.padSz += *(output + sz - ivExtra - 1) + 1;
+
+    return output;
+}
+
+
+/* remove session from table, use rowHint if no info (means we have a lock) */
+static void RemoveSession(SnifferSession* session, IpInfo* ipInfo,
+                        TcpInfo* tcpInfo, word32 rowHint)
+{
+    SnifferSession* previous = 0;
+    SnifferSession* current;
+    word32          row = rowHint;
+    int             haveLock = 0;
+
+    if (ipInfo && tcpInfo)
+        row = SessionHash(ipInfo, tcpInfo);
+    else
+        haveLock = 1;
+
+    assert(row <= HASH_SIZE);
+    Trace(REMOVE_SESSION_STR);
+
+    if (!haveLock)
+        wc_LockMutex(&SessionMutex);
+
+    current = SessionTable[row];
+
+    while (current) {
+        if (current == session) {
+            if (previous)
+                previous->next = current->next;
+            else
+                SessionTable[row] = current->next;
+            FreeSnifferSession(session);
+            TraceRemovedSession();
+            break;
+        }
+        previous = current;
+        current  = current->next;
+    }
+
+    if (!haveLock)
+        wc_UnLockMutex(&SessionMutex);
+}
+
+
+/* Remove stale sessions from the Session Table, have a lock */
+static void RemoveStaleSessions(void)
+{
+    word32 i;
+    SnifferSession* session;
+
+    for (i = 0; i < HASH_SIZE; i++) {
+        session = SessionTable[i];
+        while (session) {
+            SnifferSession* next = session->next;
+            if (time(NULL) >= session->lastUsed + WOLFSSL_SNIFFER_TIMEOUT) {
+                TraceStaleSession();
+                RemoveSession(session, NULL, NULL, i);
+            }
+            session = next;
+        }
+    }
+}
+
+
+/* Create a new Sniffer Session */
+static SnifferSession* CreateSession(IpInfo* ipInfo, TcpInfo* tcpInfo,
+                                     char* error)
+{
+    SnifferSession* session = 0;
+    int row;
+
+    Trace(NEW_SESSION_STR);
+    /* create a new one */
+    session = (SnifferSession*)XMALLOC(sizeof(SnifferSession),
+            NULL, DYNAMIC_TYPE_SNIFFER_SESSION);
+    if (session == NULL) {
+        SetError(MEMORY_STR, error, NULL, 0);
+        return 0;
+    }
+    InitSession(session);
+#ifdef HAVE_EXTENDED_MASTER
+    {
+        HsHashes* newHash = (HsHashes*)XMALLOC(sizeof(HsHashes),
+                NULL, DYNAMIC_TYPE_HASHES);
+        if (newHash == NULL) {
+            SetError(MEMORY_STR, error, NULL, 0);
+            XFREE(session, NULL, DYNAMIC_TYPE_SNIFFER_SESSION);
+            return 0;
+        }
+        if (HashInit(newHash) != 0) {
+            SetError(EXTENDED_MASTER_HASH_STR, error, NULL, 0);
+            XFREE(session, NULL, DYNAMIC_TYPE_SNIFFER_SESSION);
+            return 0;
+        }
+        session->hash = newHash;
+    }
+#endif
+    session->server  = ipInfo->dst;
+    session->client  = ipInfo->src;
+    session->srvPort = (word16)tcpInfo->dstPort;
+    session->cliPort = (word16)tcpInfo->srcPort;
+    session->cliSeqStart = tcpInfo->sequence;
+    session->cliExpected = 1;  /* relative */
+    session->lastUsed= time(NULL);
+    session->keySz = 0;
+#ifdef HAVE_SNI
+    session->sni = NULL;
+#endif
+
+    session->context = GetSnifferServer(ipInfo, tcpInfo);
+    if (session->context == NULL) {
+        SetError(SERVER_NOT_REG_STR, error, NULL, 0);
+        XFREE(session, NULL, DYNAMIC_TYPE_SNIFFER_SESSION);
+        return 0;
+    }
+
+    session->sslServer = SSL_new(session->context->ctx);
+    if (session->sslServer == NULL) {
+        SetError(BAD_NEW_SSL_STR, error, session, FATAL_ERROR_STATE);
+        XFREE(session, NULL, DYNAMIC_TYPE_SNIFFER_SESSION);
+        return 0;
+    }
+    session->sslClient = SSL_new(session->context->ctx);
+    if (session->sslClient == NULL) {
+        SSL_free(session->sslServer);
+        session->sslServer = 0;
+
+        SetError(BAD_NEW_SSL_STR, error, session, FATAL_ERROR_STATE);
+        XFREE(session, NULL, DYNAMIC_TYPE_SNIFFER_SESSION);
+        return 0;
+    }
+    /* put server back into server mode */
+    session->sslServer->options.side = WOLFSSL_SERVER_END;
+
+    row = SessionHash(ipInfo, tcpInfo);
+
+    /* add it to the session table */
+    wc_LockMutex(&SessionMutex);
+
+    session->next = SessionTable[row];
+    SessionTable[row] = session;
+
+    SessionCount++;
+
+    if ( (SessionCount % HASH_SIZE) == 0) {
+        TraceFindingStale();
+        RemoveStaleSessions();
+    }
+
+    wc_UnLockMutex(&SessionMutex);
+
+    /* CreateSession is called in response to a SYN packet, we know this
+     * is headed to the server. Also we know the server is one we care
+     * about as we've passed the GetSnifferServer() successfully. */
+    session->flags.side = WOLFSSL_SERVER_END;
+
+    return session;
+}
+
+
+#ifdef OLD_HELLO_ALLOWED
+
+/* Process Old Client Hello Input */
+static int DoOldHello(SnifferSession* session, const byte* sslFrame,
+                      int* rhSize, int* sslBytes, char* error)
+{
+    const byte* input = sslFrame;
+    byte        b0, b1;
+    word32      idx = 0;
+    int         ret;
+
+    Trace(GOT_OLD_CLIENT_HELLO_STR);
+    session->flags.clientHello = 1;    /* don't process again */
+    b0 = *input++;
+    b1 = *input++;
+    *sslBytes -= 2;
+    *rhSize = ((b0 & 0x7f) << 8) | b1;
+
+    if (*rhSize > *sslBytes) {
+        SetError(OLD_CLIENT_INPUT_STR, error, session, FATAL_ERROR_STATE);
+        return -1;
+    }
+
+    ret = ProcessOldClientHello(session->sslServer, input, &idx, *sslBytes,
+                                (word16)*rhSize);
+    if (ret < 0 && ret != MATCH_SUITE_ERROR) {
+        SetError(BAD_OLD_CLIENT_STR, error, session, FATAL_ERROR_STATE);
+        return -1;
+    }
+
+    Trace(OLD_CLIENT_OK_STR);
+    XMEMCPY(session->sslClient->arrays->clientRandom,
+           session->sslServer->arrays->clientRandom, RAN_LEN);
+
+    *sslBytes -= *rhSize;
+    return 0;
+}
+
+#endif /* OLD_HELLO_ALLOWED */
+
+
+#if 0
+/* Calculate the TCP checksum, see RFC 1071 */
+/* return 0 for success, -1 on error */
+/* can be called from decode() with
+   TcpChecksum(&ipInfo, &tcpInfo, sslBytes, packet + ipInfo.length);
+   could also add a 64bit version if type available and using this
+*/
+int TcpChecksum(IpInfo* ipInfo, TcpInfo* tcpInfo, int dataLen,
+                const byte* packet)
+{
+    TcpPseudoHdr  pseudo;
+    int           count = PSEUDO_HDR_SZ;
+    const word16* data = (word16*)&pseudo;
+    word32        sum = 0;
+    word16        checksum;
+
+    pseudo.src = ipInfo->src;
+    pseudo.dst = ipInfo->dst;
+    pseudo.rsv = 0;
+    pseudo.protocol = TCP_PROTO;
+    pseudo.length = htons(tcpInfo->length + dataLen);
+
+    /* pseudo header sum */
+    while (count >= 2) {
+        sum   += *data++;
+        count -= 2;
+    }
+
+    count = tcpInfo->length + dataLen;
+    data = (word16*)packet;
+
+    /* main sum */
+    while (count > 1) {
+        sum   += *data++;
+        count -=2;
+    }
+
+    /* get left-over, if any */
+    packet = (byte*)data;
+    if (count > 0) {
+        sum += *packet;
+    }
+
+    /* fold 32bit sum into 16 bits */
+    while (sum >> 16)
+        sum = (sum & 0xffff) + (sum >> 16);
+
+    checksum = (word16)~sum;
+    /* checksum should now equal 0, since included already calcd checksum */
+    /* field, but tcp checksum offloading could negate calculation */
+    if (checksum == 0)
+        return 0;
+    return -1;
+}
+#endif
+
+
+/* Check IP and TCP headers, set payload */
+/* returns 0 on success, -1 on error */
+static int CheckHeaders(IpInfo* ipInfo, TcpInfo* tcpInfo, const byte* packet,
+                  int length, const byte** sslFrame, int* sslBytes, char* error)
+{
+    TraceHeader();
+    TracePacket();
+
+    /* ip header */
+    if (length < IP_HDR_SZ) {
+        SetError(PACKET_HDR_SHORT_STR, error, NULL, 0);
+        return -1;
+    }
+    if (CheckIpHdr((IpHdr*)packet, ipInfo, length, error) != 0)
+        return -1;
+
+    /* tcp header */
+    if (length < (ipInfo->length + TCP_HDR_SZ)) {
+        SetError(PACKET_HDR_SHORT_STR, error, NULL, 0);
+        return -1;
+    }
+    if (CheckTcpHdr((TcpHdr*)(packet + ipInfo->length), tcpInfo, error) != 0)
+        return -1;
+
+    /* setup */
+    *sslFrame = packet + ipInfo->length + tcpInfo->length;
+    if (*sslFrame > packet + length) {
+        SetError(PACKET_HDR_SHORT_STR, error, NULL, 0);
+        return -1;
+    }
+    /* We only care about the data in the TCP/IP record. There may be extra
+     * data after the IP record for the FCS for Ethernet. */
+    *sslBytes = (int)(packet + ipInfo->total - *sslFrame);
+
+    return 0;
+}
+
+
+/* Create or Find existing session */
+/* returns 0 on success (continue), -1 on error, 1 on success (end) */
+static int CheckSession(IpInfo* ipInfo, TcpInfo* tcpInfo, int sslBytes,
+                        SnifferSession** session, char* error)
+{
+    /* create a new SnifferSession on client SYN */
+    if (tcpInfo->syn && !tcpInfo->ack) {
+        TraceClientSyn(tcpInfo->sequence);
+#ifdef WOLFSSL_SNIFFER_STATS
+        INC_STAT(SnifferStats.sslEncryptedConns);
+#endif
+        *session = CreateSession(ipInfo, tcpInfo, error);
+        if (*session == NULL) {
+            *session = GetSnifferSession(ipInfo, tcpInfo);
+            /* already had existing, so OK */
+            if (*session)
+                return 1;
+
+            SetError(MEMORY_STR, error, NULL, 0);
+            return -1;
+        }
+        return 1;
+    }
+    /* get existing sniffer session */
+    else {
+        *session = GetSnifferSession(ipInfo, tcpInfo);
+        if (*session == NULL) {
+            /* don't worry about extraneous RST or duplicate FINs */
+            if (tcpInfo->fin || tcpInfo->rst)
+                return 1;
+            /* don't worry about duplicate ACKs either */
+            if (sslBytes == 0 && tcpInfo->ack)
+                return 1;
+
+#ifdef WOLFSSL_SNIFFER_STATS
+            LOCK_STAT();
+            NOLOCK_INC_STAT(SnifferStats.sslDecryptedPackets);
+            NOLOCK_ADD_TO_STAT(SnifferStats.sslDecryptedBytes, sslBytes);
+            UNLOCK_STAT();
+#endif
+
+            SetError(BAD_SESSION_STR, error, NULL, 0);
+            return -1;
+        }
+    }
+    return 0;
+}
+
+
+/* Create a Packet Buffer from *begin - end, adjust new *begin and bytesLeft */
+static PacketBuffer* CreateBuffer(word32* begin, word32 end, const byte* data,
+                                  int* bytesLeft)
+{
+    PacketBuffer* pb;
+
+    int added = end - *begin + 1;
+    assert(*begin <= end);
+
+    pb = (PacketBuffer*)XMALLOC(sizeof(PacketBuffer),
+            NULL, DYNAMIC_TYPE_SNIFFER_PB);
+    if (pb == NULL) return NULL;
+
+    pb->next  = 0;
+    pb->begin = *begin;
+    pb->end   = end;
+    pb->data = (byte*)XMALLOC(added, NULL, DYNAMIC_TYPE_SNIFFER_PB_BUFFER);
+
+    if (pb->data == NULL) {
+        XFREE(pb, NULL, DYNAMIC_TYPE_SNIFFER_PB);
+        return NULL;
+    }
+    XMEMCPY(pb->data, data, added);
+
+    *bytesLeft -= added;
+    *begin      = pb->end + 1;
+
+    return pb;
+}
+
+
+/* Add sslFrame to Reassembly List */
+/* returns 1 (end) on success, -1, on error */
+static int AddToReassembly(byte from, word32 seq, const byte* sslFrame,
+                           int sslBytes, SnifferSession* session, char* error)
+{
+    PacketBuffer*  add;
+    PacketBuffer** front = (from == WOLFSSL_SERVER_END) ?
+                       &session->cliReassemblyList: &session->srvReassemblyList;
+    PacketBuffer*  curr = *front;
+    PacketBuffer*  prev = curr;
+
+    word32* reassemblyMemory = (from == WOLFSSL_SERVER_END) ?
+                  &session->cliReassemblyMemory : &session->srvReassemblyMemory;
+    word32  startSeq = seq;
+    word32  added;
+    int     bytesLeft = sslBytes;  /* could be overlapping fragment */
+
+    /* if list is empty add full frame to front */
+    if (!curr) {
+        if (MaxRecoveryMemory != -1 &&
+                      (int)(*reassemblyMemory + sslBytes) > MaxRecoveryMemory) {
+            SetError(REASSEMBLY_MAX_STR, error, session, FATAL_ERROR_STATE);
+            return -1;
+        }
+        add = CreateBuffer(&seq, seq + sslBytes - 1, sslFrame, &bytesLeft);
+        if (add == NULL) {
+            SetError(MEMORY_STR, error, session, FATAL_ERROR_STATE);
+            return -1;
+        }
+        *front = add;
+        *reassemblyMemory += sslBytes;
+        return 1;
+    }
+
+    /* add to front if before current front, up to next->begin */
+    if (seq < curr->begin) {
+        word32 end = seq + sslBytes - 1;
+
+        if (end >= curr->begin)
+            end = curr->begin - 1;
+
+        if (MaxRecoveryMemory -1 &&
+                      (int)(*reassemblyMemory + sslBytes) > MaxRecoveryMemory) {
+            SetError(REASSEMBLY_MAX_STR, error, session, FATAL_ERROR_STATE);
+            return -1;
+        }
+        add = CreateBuffer(&seq, end, sslFrame, &bytesLeft);
+        if (add == NULL) {
+            SetError(MEMORY_STR, error, session, FATAL_ERROR_STATE);
+            return -1;
+        }
+        add->next = curr;
+        *front = add;
+        *reassemblyMemory += sslBytes;
+    }
+
+    /* while we have bytes left, try to find a gap to fill */
+    while (bytesLeft > 0) {
+        /* get previous packet in list */
+        while (curr && (seq >= curr->begin)) {
+            prev = curr;
+            curr = curr->next;
+        }
+
+        /* don't add  duplicate data */
+        if (prev->end >= seq) {
+            if ( (seq + bytesLeft - 1) <= prev->end)
+                return 1;
+            seq = prev->end + 1;
+            bytesLeft = startSeq + sslBytes - seq;
+        }
+
+        if (!curr)
+            /* we're at the end */
+            added = bytesLeft;
+        else
+            /* we're in between two frames */
+            added = min((word32)bytesLeft, curr->begin - seq);
+
+        /* data already there */
+        if (added == 0)
+            continue;
+
+        if (MaxRecoveryMemory != -1 &&
+                         (int)(*reassemblyMemory + added) > MaxRecoveryMemory) {
+            SetError(REASSEMBLY_MAX_STR, error, session, FATAL_ERROR_STATE);
+            return -1;
+        }
+        add = CreateBuffer(&seq, seq + added - 1, &sslFrame[seq - startSeq],
+                           &bytesLeft);
+        if (add == NULL) {
+            SetError(MEMORY_STR, error, session, FATAL_ERROR_STATE);
+            return -1;
+        }
+        add->next  = prev->next;
+        prev->next = add;
+        *reassemblyMemory += added;
+    }
+    return 1;
+}
+
+
+/* Add out of order FIN capture */
+/* returns 1 for success (end) */
+static int AddFinCapture(SnifferSession* session, word32 sequence)
+{
+    if (session->flags.side == WOLFSSL_SERVER_END) {
+        if (session->finCaputre.cliCounted == 0)
+            session->finCaputre.cliFinSeq = sequence;
+    }
+    else {
+        if (session->finCaputre.srvCounted == 0)
+            session->finCaputre.srvFinSeq = sequence;
+    }
+    return 1;
+}
+
+
+/* Adjust incoming sequence based on side */
+/* returns 0 on success (continue), -1 on error, 1 on success (end) */
+static int AdjustSequence(TcpInfo* tcpInfo, SnifferSession* session,
+                          int* sslBytes, const byte** sslFrame, char* error)
+{
+    word32  seqStart = (session->flags.side == WOLFSSL_SERVER_END) ?
+                                     session->cliSeqStart :session->srvSeqStart;
+    word32  real     = tcpInfo->sequence - seqStart;
+    word32* expected = (session->flags.side == WOLFSSL_SERVER_END) ?
+                                  &session->cliExpected : &session->srvExpected;
+    PacketBuffer* reassemblyList = (session->flags.side == WOLFSSL_SERVER_END) ?
+                        session->cliReassemblyList : session->srvReassemblyList;
+    byte  skipPartial = (session->flags.side == WOLFSSL_SERVER_END) ?
+                                session->flags.srvSkipPartial :
+                                session->flags.cliSkipPartial;
+
+    /* handle rollover of sequence */
+    if (tcpInfo->sequence < seqStart)
+        real = 0xffffffffU - seqStart + tcpInfo->sequence;
+
+    TraceRelativeSequence(*expected, real);
+
+    if (real < *expected) {
+        Trace(DUPLICATE_STR);
+        if (real + *sslBytes > *expected) {
+            int overlap = *expected - real;
+            Trace(OVERLAP_DUPLICATE_STR);
+
+            /* adjust to expected, remove duplicate */
+            *sslFrame += overlap;
+            *sslBytes -= overlap;
+
+            /* The following conditional block is duplicated below. It is the
+             * same action but for a different setup case. If changing this
+             * block be sure to also update the block below. */
+            if (reassemblyList) {
+                word32 newEnd = *expected + *sslBytes;
+
+                if (newEnd > reassemblyList->begin) {
+                    Trace(OVERLAP_REASSEMBLY_BEGIN_STR);
+
+                    /* remove bytes already on reassembly list */
+                    *sslBytes -= newEnd - reassemblyList->begin;
+                }
+                if (newEnd > reassemblyList->end) {
+                    Trace(OVERLAP_REASSEMBLY_END_STR);
+
+                    /* may be past reassembly list end (could have more on list)
+                       so try to add what's past the front->end */
+                    AddToReassembly(session->flags.side, reassemblyList->end +1,
+                                *sslFrame + reassemblyList->end - *expected + 1,
+                                 newEnd - reassemblyList->end, session, error);
+                }
+            }
+        }
+        else
+            return 1;
+    }
+    else if (real > *expected) {
+        Trace(OUT_OF_ORDER_STR);
+        if (*sslBytes > 0) {
+            int addResult = AddToReassembly(session->flags.side, real,
+                                          *sslFrame, *sslBytes, session, error);
+            if (skipPartial) {
+                *sslBytes = 0;
+                return 0;
+            }
+            else
+                return addResult;
+        }
+        else if (tcpInfo->fin)
+            return AddFinCapture(session, real);
+    }
+    else if (*sslBytes > 0) {
+        if (skipPartial) {
+            AddToReassembly(session->flags.side, real,
+                                          *sslFrame, *sslBytes, session, error);
+            *expected += *sslBytes;
+            *sslBytes = 0;
+            if (tcpInfo->fin)
+                *expected += 1;
+            return 0;
+        }
+        /* The following conditional block is duplicated above. It is the
+         * same action but for a different setup case. If changing this
+         * block be sure to also update the block above. */
+        else if (reassemblyList) {
+            word32 newEnd = *expected + *sslBytes;
+
+            if (newEnd > reassemblyList->begin) {
+                Trace(OVERLAP_REASSEMBLY_BEGIN_STR);
+
+                /* remove bytes already on reassembly list */
+                *sslBytes -= newEnd - reassemblyList->begin;
+            }
+            if (newEnd > reassemblyList->end) {
+                Trace(OVERLAP_REASSEMBLY_END_STR);
+
+                /* may be past reassembly list end (could have more on list)
+                   so try to add what's past the front->end */
+                AddToReassembly(session->flags.side, reassemblyList->end +1,
+                            *sslFrame + reassemblyList->end - *expected + 1,
+                             newEnd - reassemblyList->end, session, error);
+            }
+        }
+    }
+    /* got expected sequence */
+    *expected += *sslBytes;
+    if (tcpInfo->fin)
+        *expected += 1;
+
+    return 0;
+}
+
+
+static int FindNextRecordInAssembly(SnifferSession* session,
+                                    const byte** sslFrame, int* sslBytes,
+                                    const byte** end, char* error)
+{
+    PacketBuffer**     front = (session->flags.side == WOLFSSL_SERVER_END) ?
+                                    &session->cliReassemblyList :
+                                    &session->srvReassemblyList;
+    PacketBuffer*       curr = *front;
+    PacketBuffer*       prev = NULL;
+    byte*        skipPartial = (session->flags.side == WOLFSSL_SERVER_END) ?
+                                    &session->flags.srvSkipPartial :
+                                    &session->flags.cliSkipPartial;
+    word32* reassemblyMemory = (session->flags.side == WOLFSSL_SERVER_END) ?
+                                    &session->cliReassemblyMemory :
+                                    &session->srvReassemblyMemory;
+    SSL*                 ssl = (session->flags.side == WOLFSSL_SERVER_END) ?
+                                    session->sslServer :
+                                    session->sslClient;
+    ProtocolVersion       pv = ssl->version;
+    word32*         expected = (session->flags.side == WOLFSSL_SERVER_END) ?
+                                    &session->cliExpected :
+                                    &session->srvExpected;
+
+    while (curr != NULL) {
+        *expected = curr->end + 1;
+
+        if (curr->data[0] == application_data &&
+            curr->data[1] == pv.major &&
+            curr->data[2] == pv.minor) {
+
+            if (ssl->buffers.inputBuffer.length > 0)
+                Trace(DROPPING_PARTIAL_RECORD);
+
+            *sslBytes = curr->end - curr->begin + 1;
+            if ( (word32)*sslBytes > ssl->buffers.inputBuffer.bufferSize) {
+                if (GrowInputBuffer(ssl, *sslBytes, 0) < 0) {
+                    SetError(MEMORY_STR, error, session, FATAL_ERROR_STATE);
+                    return -1;
+                }
+            }
+
+            XMEMCPY(ssl->buffers.inputBuffer.buffer, curr->data, *sslBytes);
+
+            *front = curr->next;
+            *reassemblyMemory -= *sslBytes;
+            FreePacketBuffer(curr);
+
+            ssl->buffers.inputBuffer.length = *sslBytes;
+            *sslFrame = ssl->buffers.inputBuffer.buffer;
+            *end = *sslFrame + *sslBytes;
+            *skipPartial = 0;
+
+            return 0;
+        }
+        else if (ssl->specs.cipher_type == block) {
+            if (ssl->specs.bulk_cipher_algorithm == wolfssl_aes) {
+#ifdef BUILD_AES
+                wc_AesSetIV(ssl->decrypt.aes,
+                            curr->data + curr->end - curr->begin
+                                       - ssl->specs.block_size + 1);
+#endif
+            }
+            else if (ssl->specs.bulk_cipher_algorithm == wolfssl_triple_des) {
+#ifdef BUILD_DES3
+                wc_Des3_SetIV(ssl->decrypt.des3,
+                              curr->data + curr->end - curr->begin
+                                         - ssl->specs.block_size + 1);
+#endif
+            }
+        }
+
+        Trace(DROPPING_LOST_FRAG_STR);
+#ifdef WOLFSSL_SNIFFER_STATS
+        INC_STAT(SnifferStats.sslDecodeFails);
+#endif
+        prev = curr;
+        curr = curr->next;
+        *reassemblyMemory -= (prev->end - prev->begin + 1);
+        FreePacketBuffer(prev);
+    }
+
+    *front = curr;
+
+    return 0;
+}
+
+
+static int FixSequence(TcpInfo* tcpInfo, SnifferSession* session)
+{
+    word32*   expected = (session->flags.side == WOLFSSL_SERVER_END) ?
+                                &session->srvExpected : &session->cliExpected;
+    PacketBuffer* list = (session->flags.side == WOLFSSL_SERVER_END) ?
+                                session->srvReassemblyList :
+                                session->cliReassemblyList;
+    byte*  skipPartial = (session->flags.side != WOLFSSL_SERVER_END) ?
+                                &session->flags.srvSkipPartial :
+                                &session->flags.cliSkipPartial;
+
+    *skipPartial = 1;
+    if (list != NULL)
+        *expected = list->begin;
+    else {
+        word32 seqStart = (session->flags.side == WOLFSSL_SERVER_END) ?
+                                session->srvSeqStart : session->cliSeqStart;
+        word32     real = tcpInfo->ackNumber - seqStart;
+
+        *expected = real;
+    }
+
+    return 1;
+}
+
+
+/* Check latest ack number for missing packets
+   return 0 ok, <0 on error */
+static int CheckAck(TcpInfo* tcpInfo, SnifferSession* session)
+{
+    if (tcpInfo->ack) {
+        word32  seqStart = (session->flags.side == WOLFSSL_SERVER_END) ?
+                                     session->srvSeqStart :session->cliSeqStart;
+        word32  real     = tcpInfo->ackNumber - seqStart;
+        word32  expected = (session->flags.side == WOLFSSL_SERVER_END) ?
+                                  session->srvExpected : session->cliExpected;
+
+        /* handle rollover of sequence */
+        if (tcpInfo->ackNumber < seqStart)
+            real = 0xffffffffU - seqStart + tcpInfo->ackNumber;
+
+        TraceAck(real, expected);
+
+        if (real > expected)
+            return -1;  /* we missed a packet, ACKing data we never saw */
+    }
+    return 0;
+}
+
+
+/* Check TCP Sequence status */
+/* returns 0 on success (continue), -1 on error, 1 on success (end) */
+static int CheckSequence(IpInfo* ipInfo, TcpInfo* tcpInfo,
+                         SnifferSession* session, int* sslBytes,
+                         const byte** sslFrame, char* error)
+{
+    int actualLen;
+    byte* ackFault = (session->flags.side == WOLFSSL_SERVER_END) ?
+                        &session->flags.cliAckFault :
+                        &session->flags.srvAckFault;
+
+    /* init SEQ from server to client */
+    if (tcpInfo->syn && tcpInfo->ack) {
+        session->srvSeqStart = tcpInfo->sequence;
+        session->srvExpected = 1;
+        TraceServerSyn(tcpInfo->sequence);
+        return 1;
+    }
+
+    /* adjust potential ethernet trailer */
+    actualLen = ipInfo->total - ipInfo->length - tcpInfo->length;
+    if (*sslBytes > actualLen) {
+        *sslBytes = actualLen;
+    }
+
+    TraceSequence(tcpInfo->sequence, *sslBytes);
+    if (CheckAck(tcpInfo, session) < 0) {
+        if (!RecoveryEnabled) {
+            UpdateMissedDataSessions();
+            SetError(ACK_MISSED_STR, error, session, FATAL_ERROR_STATE);
+            return -1;
+        }
+        else {
+            SetError(ACK_MISSED_STR, error, session, 0);
+            if (*ackFault == 0) {
+                *ackFault = 1;
+                UpdateMissedDataSessions();
+            }
+            return FixSequence(tcpInfo, session);
+        }
+    }
+
+    if (*ackFault) {
+        Trace(CLEAR_ACK_FAULT);
+        *ackFault = 0;
+    }
+
+    return AdjustSequence(tcpInfo, session, sslBytes, sslFrame, error);
+}
+
+
+/* Check Status before record processing */
+/* returns 0 on success (continue), -1 on error, 1 on success (end) */
+static int CheckPreRecord(IpInfo* ipInfo, TcpInfo* tcpInfo,
+                          const byte** sslFrame, SnifferSession** session,
+                          int* sslBytes, const byte** end,
+                          void* vChain, word32 chainSz, char* error)
+{
+    word32 length;
+    SSL*  ssl = ((*session)->flags.side == WOLFSSL_SERVER_END) ?
+                                  (*session)->sslServer : (*session)->sslClient;
+    byte  skipPartial = ((*session)->flags.side == WOLFSSL_SERVER_END) ?
+                        (*session)->flags.srvSkipPartial :
+                        (*session)->flags.cliSkipPartial;
+    /* remove SnifferSession on 2nd FIN or RST */
+    if (tcpInfo->fin || tcpInfo->rst) {
+        /* flag FIN and RST */
+        if (tcpInfo->fin)
+            (*session)->flags.finCount += 1;
+        else if (tcpInfo->rst)
+            (*session)->flags.finCount += 2;
+
+        if ((*session)->flags.finCount >= 2) {
+            RemoveSession(*session, ipInfo, tcpInfo, 0);
+            *session = NULL;
+            return 1;
+        }
+    }
+
+    if ((*session)->flags.fatalError == FATAL_ERROR_STATE) {
+        SetError(FATAL_ERROR_STR, error, NULL, 0);
+        return -1;
+    }
+
+    if (skipPartial) {
+        if (FindNextRecordInAssembly(*session,
+                                     sslFrame, sslBytes, end, error) < 0) {
+            return -1;
+        }
+    }
+
+    if (*sslBytes == 0) {
+        Trace(NO_DATA_STR);
+        return 1;
+    }
+
+    /* if current partial data, add to end of partial */
+    /* if skipping, the data is already at the end of partial */
+    if ( !skipPartial && (length = ssl->buffers.inputBuffer.length) ) {
+        Trace(PARTIAL_ADD_STR);
+
+        if ( (*sslBytes + length) > ssl->buffers.inputBuffer.bufferSize) {
+            if (GrowInputBuffer(ssl, *sslBytes, length) < 0) {
+                SetError(MEMORY_STR, error, *session, FATAL_ERROR_STATE);
+                return -1;
+            }
+        }
+        if (vChain == NULL) {
+            XMEMCPY(&ssl->buffers.inputBuffer.buffer[length],
+                    *sslFrame, *sslBytes);
+            *sslBytes += length;
+            ssl->buffers.inputBuffer.length = *sslBytes;
+            *sslFrame = ssl->buffers.inputBuffer.buffer;
+            *end = *sslFrame + *sslBytes;
+        }
+    }
+
+    if (vChain != NULL) {
+#ifdef WOLFSSL_SNIFFER_CHAIN_INPUT
+        struct iovec* chain = (struct iovec*)vChain;
+        word32 i, offset, headerSz, qty, remainder;
+
+        Trace(CHAIN_INPUT_STR);
+        headerSz = (word32)*sslFrame - (word32)chain[0].iov_base;
+        remainder = *sslBytes;
+
+        if ( (*sslBytes + length) > ssl->buffers.inputBuffer.bufferSize) {
+            if (GrowInputBuffer(ssl, *sslBytes, length) < 0) {
+                SetError(MEMORY_STR, error, *session, FATAL_ERROR_STATE);
+                return -1;
+            }
+        }
+
+        qty = min(*sslBytes, (word32)chain[0].iov_len - headerSz);
+        XMEMCPY(&ssl->buffers.inputBuffer.buffer[length],
+               (byte*)chain[0].iov_base + headerSz, qty);
+        offset = length;
+        for (i = 1; i < chainSz; i++) {
+            offset += qty;
+            remainder -= qty;
+
+            if (chain[i].iov_len > remainder)
+                qty = remainder;
+            else
+                qty = (word32)chain[i].iov_len;
+            XMEMCPY(ssl->buffers.inputBuffer.buffer + offset,
+                    chain[i].iov_base, qty);
+        }
+
+        *sslBytes += length;
+        ssl->buffers.inputBuffer.length = *sslBytes;
+        *sslFrame = ssl->buffers.inputBuffer.buffer;
+        *end = *sslFrame + *sslBytes;
+#endif
+        (void)chainSz;
+    }
+
+    if ((*session)->flags.clientHello == 0 && **sslFrame != handshake) {
+        /* Sanity check the packet for an old style client hello. */
+        int rhSize = (((*sslFrame)[0] & 0x7f) << 8) | ((*sslFrame)[1]);
+
+        if ((rhSize <= (*sslBytes - 2)) &&
+            (*sslFrame)[2] == OLD_HELLO_ID && (*sslFrame)[3] == SSLv3_MAJOR) {
+#ifdef OLD_HELLO_ALLOWED
+        int ret = DoOldHello(*session, *sslFrame, &rhSize, sslBytes, error);
+        if (ret < 0)
+            return -1;  /* error already set */
+        if (*sslBytes <= 0)
+            return 1;
+#endif
+        }
+        else {
+#ifdef STARTTLS_ALLOWED
+            if (ssl->buffers.inputBuffer.dynamicFlag) {
+                ssl->buffers.inputBuffer.length = 0;
+                ShrinkInputBuffer(ssl, NO_FORCED_FREE);
+            }
+            return 1;
+#endif
+        }
+    }
+
+    return 0;
+}
+
+
+/* See if input on the reassembly list is ready for consuming */
+/* returns 1 for TRUE, 0 for FALSE */
+static int HaveMoreInput(SnifferSession* session, const byte** sslFrame,
+                         int* sslBytes, const byte** end, char* error)
+{
+    /* sequence and reassembly based on from, not to */
+    int            moreInput = 0;
+    PacketBuffer** front = (session->flags.side == WOLFSSL_SERVER_END) ?
+                      &session->cliReassemblyList : &session->srvReassemblyList;
+    word32*        expected = (session->flags.side == WOLFSSL_SERVER_END) ?
+                                  &session->cliExpected : &session->srvExpected;
+    /* buffer is on receiving end */
+    word32*        length = (session->flags.side == WOLFSSL_SERVER_END) ?
+                               &session->sslServer->buffers.inputBuffer.length :
+                               &session->sslClient->buffers.inputBuffer.length;
+    byte**         myBuffer = (session->flags.side == WOLFSSL_SERVER_END) ?
+                               &session->sslServer->buffers.inputBuffer.buffer :
+                               &session->sslClient->buffers.inputBuffer.buffer;
+    word32*       bufferSize = (session->flags.side == WOLFSSL_SERVER_END) ?
+                           &session->sslServer->buffers.inputBuffer.bufferSize :
+                           &session->sslClient->buffers.inputBuffer.bufferSize;
+    SSL*               ssl  = (session->flags.side == WOLFSSL_SERVER_END) ?
+                            session->sslServer : session->sslClient;
+    word32*     reassemblyMemory = (session->flags.side == WOLFSSL_SERVER_END) ?
+                  &session->cliReassemblyMemory : &session->srvReassemblyMemory;
+
+    while (*front && ((*front)->begin == *expected) ) {
+        word32 room = *bufferSize - *length;
+        word32 packetLen = (*front)->end - (*front)->begin + 1;
+
+        if (packetLen > room && *bufferSize < MAX_INPUT_SZ) {
+            if (GrowInputBuffer(ssl, packetLen, *length) < 0) {
+                SetError(MEMORY_STR, error, session, FATAL_ERROR_STATE);
+                return 0;
+            }
+            room = *bufferSize - *length;   /* bufferSize is now bigger */
+        }
+
+        if (packetLen <= room) {
+            PacketBuffer* del = *front;
+            byte*         buf = *myBuffer;
+
+            XMEMCPY(&buf[*length], (*front)->data, packetLen);
+            *length   += packetLen;
+            *expected += packetLen;
+
+            /* remove used packet */
+            *front = (*front)->next;
+
+            *reassemblyMemory -= packetLen;
+            FreePacketBuffer(del);
+
+            moreInput = 1;
+        }
+        else
+            break;
+    }
+    if (moreInput) {
+        *sslFrame = *myBuffer;
+        *sslBytes = *length;
+        *end      = *myBuffer + *length;
+    }
+    return moreInput;
+}
+
+
+
+/* Process Message(s) from sslFrame */
+/* return Number of bytes on success, 0 for no data yet, and -1 on error */
+static int ProcessMessage(const byte* sslFrame, SnifferSession* session,
+                          int sslBytes, byte** data, const byte* end,
+                          void* ctx, char* error)
+{
+    const byte*       sslBegin = sslFrame;
+    const byte*       recordEnd;   /* end of record indicator */
+    const byte*       inRecordEnd; /* indicator from input stream not decrypt */
+    RecordLayerHeader rh;
+    int               rhSize = 0;
+    int               ret;
+    int               errCode = 0;
+    int               decoded = 0;      /* bytes stored for user in data */
+    int               notEnough;        /* notEnough bytes yet flag */
+    int               decrypted = 0;    /* was current msg decrypted */
+    SSL*              ssl = (session->flags.side == WOLFSSL_SERVER_END) ?
+                                        session->sslServer : session->sslClient;
+doMessage:
+    notEnough = 0;
+    if (sslBytes < 0) {
+        SetError(PACKET_HDR_SHORT_STR, error, session, FATAL_ERROR_STATE);
+        return -1;
+    }
+    if (sslBytes >= RECORD_HEADER_SZ) {
+        if (GetRecordHeader(sslFrame, &rh, &rhSize) != 0) {
+            SetError(BAD_RECORD_HDR_STR, error, session, FATAL_ERROR_STATE);
+            return -1;
+        }
+    }
+    else
+        notEnough = 1;
+
+    if (notEnough || rhSize > (sslBytes - RECORD_HEADER_SZ)) {
+        /* don't have enough input yet to process full SSL record */
+        Trace(PARTIAL_INPUT_STR);
+
+        /* store partial if not there already or we advanced */
+        if (ssl->buffers.inputBuffer.length == 0 || sslBegin != sslFrame) {
+            if (sslBytes > (int)ssl->buffers.inputBuffer.bufferSize) {
+                if (GrowInputBuffer(ssl, sslBytes, 0) < 0) {
+                    SetError(MEMORY_STR, error, session, FATAL_ERROR_STATE);
+                    return -1;
+                }
+            }
+            XMEMMOVE(ssl->buffers.inputBuffer.buffer, sslFrame, sslBytes);
+            ssl->buffers.inputBuffer.length = sslBytes;
+        }
+        if (HaveMoreInput(session, &sslFrame, &sslBytes, &end, error))
+            goto doMessage;
+        return decoded;
+    }
+    sslFrame += RECORD_HEADER_SZ;
+    sslBytes -= RECORD_HEADER_SZ;
+    recordEnd = sslFrame + rhSize;   /* may have more than one record */
+    inRecordEnd = recordEnd;
+
+    /* decrypt if needed */
+    if ((session->flags.side == WOLFSSL_SERVER_END &&
+                                               session->flags.serverCipherOn)
+     || (session->flags.side == WOLFSSL_CLIENT_END &&
+                                               session->flags.clientCipherOn)) {
+        int ivAdvance = 0;  /* TLSv1.1 advance amount */
+        if (ssl->decrypt.setup != 1) {
+            SetError(DECRYPT_KEYS_NOT_SETUP, error, session, FATAL_ERROR_STATE);
+            return -1;
+        }
+        if (CheckAvailableSize(ssl, rhSize) < 0) {
+            SetError(MEMORY_STR, error, session, FATAL_ERROR_STATE);
+            return -1;
+        }
+        sslFrame = DecryptMessage(ssl, sslFrame, rhSize,
+                                  ssl->buffers.outputBuffer.buffer, &errCode,
+                                  &ivAdvance);
+        recordEnd = sslFrame - ivAdvance + rhSize;  /* sslFrame moved so
+                                                       should recordEnd */
+        decrypted = 1;
+
+#ifdef WOLFSSL_SNIFFER_STATS
+        if (errCode != 0) {
+            INC_STAT(SnifferStats.sslKeyFails);
+        }
+        else {
+            LOCK_STAT();
+            NOLOCK_INC_STAT(SnifferStats.sslDecryptedPackets);
+            NOLOCK_ADD_TO_STAT(SnifferStats.sslDecryptedBytes, sslBytes);
+            UNLOCK_STAT();
+        }
+#endif
+        if (errCode != 0) {
+            SetError(BAD_DECRYPT, error, session, FATAL_ERROR_STATE);
+            return -1;
+        }
+    }
+
+doPart:
+
+    switch ((enum ContentType)rh.type) {
+        case handshake:
+            {
+                int startIdx = sslBytes;
+                int used;
+
+                Trace(GOT_HANDSHAKE_STR);
+                ret = DoHandShake(sslFrame, &sslBytes, session, error);
+                if (ret != 0) {
+                    if (session->flags.fatalError == 0)
+                        SetError(BAD_HANDSHAKE_STR, error, session,
+                                 FATAL_ERROR_STATE);
+                    return -1;
+                }
+
+                /* DoHandShake now fully decrements sslBytes to remaining */
+                used = startIdx - sslBytes;
+                sslFrame += used;
+                if (decrypted)
+                    sslFrame += ssl->keys.padSz;
+            }
+            break;
+        case change_cipher_spec:
+            if (session->flags.side == WOLFSSL_SERVER_END)
+                session->flags.serverCipherOn = 1;
+            else
+                session->flags.clientCipherOn = 1;
+            Trace(GOT_CHANGE_CIPHER_STR);
+            ssl->options.handShakeState = HANDSHAKE_DONE;
+            ssl->options.handShakeDone  = 1;
+
+            sslFrame += 1;
+            sslBytes -= 1;
+
+            break;
+        case application_data:
+            Trace(GOT_APP_DATA_STR);
+            {
+                word32 inOutIdx = 0;
+
+                ret = DoApplicationData(ssl, (byte*)sslFrame, &inOutIdx);
+                if (ret == 0) {
+                    ret = ssl->buffers.clearOutputBuffer.length;
+                    TraceGotData(ret);
+                    if (ret) {  /* may be blank message */
+                        if (data != NULL) {
+                            byte* tmpData;  /* don't leak on realloc free */
+                            /* add an extra byte at end of allocation in case
+                             * user wants to null terminate plaintext */
+                            tmpData = (byte*)XREALLOC(*data, decoded + ret + 1,
+                                    NULL, DYNAMIC_TYPE_TMP_BUFFER);
+                            if (tmpData == NULL) {
+                                ForceZero(*data, decoded);
+                                XFREE(*data, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+                                *data = NULL;
+                                SetError(MEMORY_STR, error, session,
+                                         FATAL_ERROR_STATE);
+                                return -1;
+                            }
+                            *data = tmpData;
+                            XMEMCPY(*data + decoded,
+                                    ssl->buffers.clearOutputBuffer.buffer, ret);
+                        }
+                        else {
+#ifdef WOLFSSL_SNIFFER_STORE_DATA_CB
+                            if (StoreDataCb) {
+                                const byte* buf;
+                                word32 offset = 0;
+                                word32 bufSz;
+                                int stored;
+
+                                buf = ssl->buffers.clearOutputBuffer.buffer;
+                                bufSz = ssl->buffers.clearOutputBuffer.length;
+                                do {
+                                    stored = StoreDataCb(buf, bufSz, offset,
+                                            ctx);
+                                    if (stored <= 0) {
+                                        return -1;
+                                    }
+                                    offset += stored;
+                                } while (offset < bufSz);
+                            }
+                            else {
+                                SetError(STORE_DATA_CB_MISSING_STR, error,
+                                        session, FATAL_ERROR_STATE);
+                                return -1;
+                            }
+#else
+                            (void)ctx;
+                            SetError(NO_DATA_DEST_STR, error, session,
+                                    FATAL_ERROR_STATE);
+                            return -1;
+#endif
+                        }
+                        TraceAddedData(ret, decoded);
+                        decoded += ret;
+                        ssl->buffers.clearOutputBuffer.length = 0;
+                    }
+                }
+                else {
+                    SetError(BAD_APP_DATA_STR, error,session,FATAL_ERROR_STATE);
+                    return -1;
+                }
+                if (ssl->buffers.outputBuffer.dynamicFlag)
+                    ShrinkOutputBuffer(ssl);
+
+                sslFrame += inOutIdx;
+                sslBytes -= inOutIdx;
+            }
+            break;
+        case alert:
+            Trace(GOT_ALERT_STR);
+#ifdef WOLFSSL_SNIFFER_STATS
+            INC_STAT(SnifferStats.sslAlerts);
+#endif
+            sslFrame += rhSize;
+            sslBytes -= rhSize;
+            break;
+        case no_type:
+        default:
+            SetError(GOT_UNKNOWN_RECORD_STR, error, session, FATAL_ERROR_STATE);
+            return -1;
+    }
+
+    /* do we have another msg in record ? */
+    if (sslFrame < recordEnd) {
+        Trace(ANOTHER_MSG_STR);
+        goto doPart;
+    }
+
+    /* back to input stream instead of potential decrypt buffer */
+    recordEnd = inRecordEnd;
+
+    /* do we have more records ? */
+    if (recordEnd < end) {
+        Trace(ANOTHER_MSG_STR);
+        sslFrame = recordEnd;
+        sslBytes = (int)(end - recordEnd);
+        goto doMessage;
+    }
+
+    /* clear used input */
+    ssl->buffers.inputBuffer.length = 0;
+
+    /* could have more input ready now */
+    if (HaveMoreInput(session, &sslFrame, &sslBytes, &end, error))
+        goto doMessage;
+
+    if (ssl->buffers.inputBuffer.dynamicFlag)
+        ShrinkInputBuffer(ssl, NO_FORCED_FREE);
+
+    return decoded;
+}
+
+
+/* See if we need to process any pending FIN captures */
+/* Return 0=normal, else = session removed */
+static int CheckFinCapture(IpInfo* ipInfo, TcpInfo* tcpInfo,
+                            SnifferSession* session)
+{
+    int ret = 0;
+    if (session->finCaputre.cliFinSeq && session->finCaputre.cliFinSeq <=
+                                         session->cliExpected) {
+        if (session->finCaputre.cliCounted == 0) {
+            session->flags.finCount += 1;
+            session->finCaputre.cliCounted = 1;
+            TraceClientFin(session->finCaputre.cliFinSeq, session->cliExpected);
+        }
+    }
+
+    if (session->finCaputre.srvFinSeq && session->finCaputre.srvFinSeq <=
+                                         session->srvExpected) {
+        if (session->finCaputre.srvCounted == 0) {
+            session->flags.finCount += 1;
+            session->finCaputre.srvCounted = 1;
+            TraceServerFin(session->finCaputre.srvFinSeq, session->srvExpected);
+        }
+    }
+
+    if (session->flags.finCount >= 2) {
+        RemoveSession(session, ipInfo, tcpInfo, 0);
+        ret = 1;
+    }
+    return ret;
+}
+
+
+/* If session is in fatal error state free resources now
+   return true if removed, 0 otherwise */
+static int RemoveFatalSession(IpInfo* ipInfo, TcpInfo* tcpInfo,
+                              SnifferSession* session, char* error)
+{
+    if (session && session->flags.fatalError == FATAL_ERROR_STATE) {
+        RemoveSession(session, ipInfo, tcpInfo, 0);
+        SetError(FATAL_ERROR_STR, error, NULL, 0);
+        return 1;
+    }
+    return 0;
+}
+
+
+/* Passes in an IP/TCP packet for decoding (ethernet/localhost frame) removed */
+/* returns Number of bytes on success, 0 for no data yet, and -1 on error */
+static int ssl_DecodePacketInternal(const byte* packet, int length,
+                                    void* vChain, word32 chainSz,
+                                    byte** data, SSLInfo* sslInfo,
+                                    void* ctx, char* error)
+{
+    TcpInfo           tcpInfo;
+    IpInfo            ipInfo;
+    const byte*       sslFrame;
+    const byte*       end;
+    int               sslBytes;                /* ssl bytes unconsumed */
+    int               ret;
+    SnifferSession*   session = 0;
+
+#ifdef WOLFSSL_SNIFFER_CHAIN_INPUT
+    if (packet == NULL && vChain != NULL) {
+        struct iovec* chain = (struct iovec*)vChain;
+        word32 i;
+
+        length = 0;
+        for (i = 0; i < chainSz; i++)
+            length += chain[i].iov_len;
+        packet = (const byte*)chain[0].iov_base;
+    }
+#endif
+
+    if (CheckHeaders(&ipInfo, &tcpInfo, packet, length, &sslFrame, &sslBytes,
+                     error) != 0)
+        return -1;
+
+    end = sslFrame + sslBytes;
+
+    ret = CheckSession(&ipInfo, &tcpInfo, sslBytes, &session, error);
+    if (RemoveFatalSession(&ipInfo, &tcpInfo, session, error)) return -1;
+    else if (ret == -1) return -1;
+    else if (ret ==  1) {
+#ifdef WOLFSSL_SNIFFER_STATS
+        if (sslBytes > 0) {
+            LOCK_STAT();
+            NOLOCK_INC_STAT(SnifferStats.sslEncryptedPackets);
+            NOLOCK_ADD_TO_STAT(SnifferStats.sslEncryptedBytes, sslBytes);
+            UNLOCK_STAT();
+        }
+        else
+            INC_STAT(SnifferStats.sslDecryptedPackets);
+#endif
+         return  0;   /* done for now */
+    }
+
+    ret = CheckSequence(&ipInfo, &tcpInfo, session, &sslBytes, &sslFrame,error);
+    if (RemoveFatalSession(&ipInfo, &tcpInfo, session, error)) return -1;
+    else if (ret == -1) return -1;
+    else if (ret ==  1) {
+#ifdef WOLFSSL_SNIFFER_STATS
+        INC_STAT(SnifferStats.sslDecryptedPackets);
+#endif
+        return  0;   /* done for now */
+    }
+
+    ret = CheckPreRecord(&ipInfo, &tcpInfo, &sslFrame, &session, &sslBytes,
+                         &end, vChain, chainSz, error);
+    if (RemoveFatalSession(&ipInfo, &tcpInfo, session, error)) return -1;
+    else if (ret == -1) return -1;
+    else if (ret ==  1) {
+#ifdef WOLFSSL_SNIFFER_STATS
+        INC_STAT(SnifferStats.sslDecryptedPackets);
+#endif
+        return  0;   /* done for now */
+    }
+
+#ifdef WOLFSSL_SNIFFER_STATS
+    if (sslBytes > 0) {
+        LOCK_STAT();
+        NOLOCK_INC_STAT(SnifferStats.sslEncryptedPackets);
+        NOLOCK_ADD_TO_STAT(SnifferStats.sslEncryptedBytes, sslBytes);
+        UNLOCK_STAT();
+    }
+    else
+        INC_STAT(SnifferStats.sslDecryptedPackets);
+#endif
+
+    ret = ProcessMessage(sslFrame, session, sslBytes, data, end, ctx, error);
+    if (RemoveFatalSession(&ipInfo, &tcpInfo, session, error)) return -1;
+    if (CheckFinCapture(&ipInfo, &tcpInfo, session) == 0) {
+        CopySessionInfo(session, sslInfo);
+    }
+
+    return ret;
+}
+
+
+/* Passes in an IP/TCP packet for decoding (ethernet/localhost frame) removed */
+/* returns Number of bytes on success, 0 for no data yet, and -1 on error */
+/* Also returns Session Info if available */
+int ssl_DecodePacketWithSessionInfo(const unsigned char* packet, int length,
+    unsigned char** data, SSLInfo* sslInfo, char* error)
+{
+    return ssl_DecodePacketInternal(packet, length, NULL, 0, data, sslInfo,
+            NULL, error);
+}
+
+
+/* Passes in an IP/TCP packet for decoding (ethernet/localhost frame) removed */
+/* returns Number of bytes on success, 0 for no data yet, and -1 on error */
+int ssl_DecodePacket(const byte* packet, int length, byte** data, char* error)
+{
+    return ssl_DecodePacketInternal(packet, length, NULL, 0, data, NULL, NULL,
+            error);
+}
+
+
+#ifdef WOLFSSL_SNIFFER_STORE_DATA_CB
+
+int ssl_DecodePacketWithSessionInfoStoreData(const unsigned char* packet,
+        int length, void* ctx, SSLInfo* sslInfo, char* error)
+{
+    return ssl_DecodePacketInternal(packet, length, NULL, 0, NULL, sslInfo,
+            ctx, error);
+}
+
+#endif
+
+
+#ifdef WOLFSSL_SNIFFER_CHAIN_INPUT
+
+int ssl_DecodePacketWithChain(void* vChain, word32 chainSz, byte** data,
+        char* error)
+{
+    return ssl_DecodePacketInternal(NULL, 0, vChain, chainSz, data, NULL, NULL,
+            error);
+}
+
+#endif
+
+
+#if defined(WOLFSSL_SNIFFER_CHAIN_INPUT) && \
+     defined(WOLFSSL_SNIFFER_STORE_DATA_CB)
+
+int ssl_DecodePacketWithChainSessionInfoStoreData(void* vChain, word32 chainSz,
+        void* ctx, SSLInfo* sslInfo, char* error)
+{
+    return ssl_DecodePacketInternal(NULL, 0, vChain, chainSz, NULL, sslInfo,
+            ctx, error);
+}
+
+#endif
+
+
+/* Deallocator for the decoded data buffer. */
+/* returns 0 on success, -1 on error */
+int ssl_FreeDecodeBuffer(byte** data, char* error)
+{
+    return ssl_FreeZeroDecodeBuffer(data, 0, error);
+}
+
+
+/* Deallocator for the decoded data buffer, zeros out buffer. */
+/* returns 0 on success, -1 on error */
+int ssl_FreeZeroDecodeBuffer(byte** data, int sz, char* error)
+{
+    (void)error;
+
+    if (sz < 0) {
+        return -1;
+    }
+
+    if (data != NULL) {
+        ForceZero(*data, (word32)sz);
+        XFREE(*data, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+        *data = NULL;
+    }
+
+    return 0;
+}
+
+
+/* Enables (if traceFile)/ Disables debug tracing */
+/* returns 0 on success, -1 on error */
+int ssl_Trace(const char* traceFile, char* error)
+{
+    if (traceFile) {
+        /* Don't try to reopen the file */
+        if (TraceFile == NULL) {
+            TraceFile = fopen(traceFile, "a");
+            if (!TraceFile) {
+                SetError(BAD_TRACE_FILE_STR, error, NULL, 0);
+                return -1;
+             }
+            TraceOn = 1;
+        }
+    }
+    else
+        TraceOn = 0;
+
+    return 0;
+}
+
+
+/* Enables/Disables Recovery of missed data if later packets allow
+ * maxMemory is number of bytes to use for reassembly buffering per session,
+ * -1 means unlimited
+ * returns 0 on success, -1 on error */
+int ssl_EnableRecovery(int onOff, int maxMemory, char* error)
+{
+    (void)error;
+
+    RecoveryEnabled = onOff;
+    if (onOff)
+        MaxRecoveryMemory = maxMemory;
+
+    return 0;
+}
+
+
+
+#ifdef WOLFSSL_SESSION_STATS
+
+int ssl_GetSessionStats(unsigned int* active,     unsigned int* total,
+                        unsigned int* peak,       unsigned int* maxSessions,
+                        unsigned int* missedData, unsigned int* reassemblyMem,
+                        char* error)
+{
+    int ret;
+
+    if (missedData) {
+        wc_LockMutex(&RecoveryMutex);
+        *missedData = MissedDataSessions;
+        wc_UnLockMutex(&RecoveryMutex);
+    }
+
+    if (reassemblyMem) {
+        SnifferSession* session;
+        int i;
+
+        *reassemblyMem = 0;
+        wc_LockMutex(&SessionMutex);
+        for (i = 0; i < HASH_SIZE; i++) {
+            session = SessionTable[i];
+            while (session) {
+                *reassemblyMem += session->cliReassemblyMemory;
+                *reassemblyMem += session->srvReassemblyMemory;
+                session = session->next;
+            }
+        }
+        wc_UnLockMutex(&SessionMutex);
+    }
+
+    ret = wolfSSL_get_session_stats(active, total, peak, maxSessions);
+
+    if (ret == WOLFSSL_SUCCESS)
+        return 0;
+    else {
+        SetError(BAD_SESSION_STATS, error, NULL, 0);
+        return -1;
+    }
+}
+
+#endif
+
+
+
+int ssl_SetConnectionCb(SSLConnCb cb)
+{
+    ConnectionCb = cb;
+    return 0;
+}
+
+
+
+int ssl_SetConnectionCtx(void* ctx)
+{
+    ConnectionCbCtx = ctx;
+    return 0;
+}
+
+
+#ifdef WOLFSSL_SNIFFER_STATS
+
+/* Resets the statistics tracking global structure.
+ * returns 0 on success, -1 on error */
+int ssl_ResetStatistics(void)
+{
+    wc_LockMutex(&StatsMutex);
+    XMEMSET(&SnifferStats, 0, sizeof(SSLStats));
+    wc_UnLockMutex(&StatsMutex);
+    return 0;
+}
+
+
+/* Copies the SSL statistics into the provided stats record.
+ * returns 0 on success, -1 on error */
+int ssl_ReadStatistics(SSLStats* stats)
+{
+    if (stats == NULL)
+        return -1;
+
+    LOCK_STAT();
+    XMEMCPY(stats, &SnifferStats, sizeof(SSLStats));
+    UNLOCK_STAT();
+    return 0;
+}
+
+/* Copies the SSL statistics into the provided stats record then
+ * resets the statistics tracking global structure.
+ * returns 0 on success, -1 on error */
+int ssl_ReadResetStatistics(SSLStats* stats)
+{
+    if (stats == NULL)
+        return -1;
+
+    LOCK_STAT();
+    XMEMCPY(stats, &SnifferStats, sizeof(SSLStats));
+    XMEMSET(&SnifferStats, 0, sizeof(SSLStats));
+    UNLOCK_STAT();
+    return 0;
+}
+
+#endif /* WOLFSSL_SNIFFER_STATS */
+
+
+#ifdef WOLFSSL_SNIFFER_WATCH
+
+int ssl_SetWatchKeyCallback_ex(SSLWatchCb cb, int devId, char* error)
+{
+    (void)devId;
+    WatchCb = cb;
+    return CreateWatchSnifferServer(error);
+}
+
+
+int ssl_SetWatchKeyCallback(SSLWatchCb cb, char* error)
+{
+    WatchCb = cb;
+    return CreateWatchSnifferServer(error);
+}
+
+
+int ssl_SetWatchKeyCtx(void* ctx, char* error)
+{
+    (void)error;
+    WatchCbCtx = ctx;
+    return 0;
+}
+
+
+int ssl_SetWatchKey_buffer(void* vSniffer, const byte* key, word32 keySz,
+        int keyType, char* error)
+{
+    SnifferSession* sniffer;
+    int ret;
+
+    if (vSniffer == NULL) {
+        return -1;
+    }
+    if (key == NULL || keySz == 0) {
+        return -1;
+    }
+
+    sniffer = (SnifferSession*)vSniffer;
+    /* Remap the keyType from what the user can use to
+     * what wolfSSL_use_PrivateKey_buffer expects. */
+    keyType = (keyType == FILETYPE_PEM) ? WOLFSSL_FILETYPE_PEM :
+                                          WOLFSSL_FILETYPE_ASN1;
+
+    ret = wolfSSL_use_PrivateKey_buffer(sniffer->sslServer,
+            key, keySz, keyType);
+    if (ret != WOLFSSL_SUCCESS) {
+        SetError(KEY_FILE_STR, error, sniffer, FATAL_ERROR_STATE);
+        return -1;
+    }
+
+    return 0;
+}
+
+
+int ssl_SetWatchKey_file(void* vSniffer, const char* keyFile, int keyType,
+        const char* password, char* error)
+{
+    byte* keyBuf = NULL;
+    word32 keyBufSz = 0;
+    int ret;
+
+    if (vSniffer == NULL) {
+        return -1;
+    }
+    if (keyFile == NULL) {
+        return -1;
+    }
+
+    /* Remap the keyType from what the user can use to
+     * what LoadKeyFile expects. */
+    keyType = (keyType == FILETYPE_PEM) ? WOLFSSL_FILETYPE_PEM :
+                                          WOLFSSL_FILETYPE_ASN1;
+
+    ret = LoadKeyFile(&keyBuf, &keyBufSz, keyFile, keyType, password);
+    if (ret < 0) {
+        SetError(KEY_FILE_STR, error, NULL, 0);
+        XFREE(keyBuf, NULL, DYNAMIC_TYPE_X509);
+        return -1;
+    }
+
+    ret = ssl_SetWatchKey_buffer(vSniffer, keyBuf, keyBufSz, FILETYPE_DER,
+            error);
+    XFREE(keyBuf, NULL, DYNAMIC_TYPE_X509);
+
+    return ret;
+}
+
+#endif /* WOLFSSL_SNIFFER_WATCH */
+
+
+#ifdef WOLFSSL_SNIFFER_STORE_DATA_CB
+
+int ssl_SetStoreDataCallback(SSLStoreDataCb cb)
+{
+    StoreDataCb = cb;
+    return 0;
+}
+
+#endif /* WOLFSSL_SNIFFER_STORE_DATA_CB */
+
+#endif /* WOLFSSL_SNIFFER */
+#endif /* WOLFCRYPT_ONLY */
Index: azure_iot_hub_f767zi/trunk/wolfssl-4.4.0/src/ssl.c
===================================================================
--- azure_iot_hub_f767zi/trunk/wolfssl-4.4.0/src/ssl.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/wolfssl-4.4.0/src/ssl.c	(revision 457)
@@ -0,0 +1,47707 @@
+/* ssl.c
+ *
+ * Copyright (C) 2006-2020 wolfSSL Inc.
+ *
+ * This file is part of wolfSSL.
+ *
+ * wolfSSL is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * wolfSSL is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
+ */
+
+
+#ifdef HAVE_CONFIG_H
+    #include <config.h>
+#endif
+
+#include <wolfssl/wolfcrypt/settings.h>
+#if defined(OPENSSL_EXTRA) && !defined(_WIN32)
+    /* turn on GNU extensions for XVASPRINTF with wolfSSL_BIO_printf */
+    #undef  _GNU_SOURCE
+    #define _GNU_SOURCE
+#endif
+
+#if !defined(WOLFCRYPT_ONLY) || defined(OPENSSL_EXTRA) || \
+    defined(OPENSSL_EXTRA_X509_SMALL)
+
+#ifdef HAVE_ERRNO_H
+    #include <errno.h>
+#endif
+
+#include <wolfssl/internal.h>
+#include <wolfssl/error-ssl.h>
+#include <wolfssl/wolfcrypt/coding.h>
+#ifdef NO_INLINE
+    #include <wolfssl/wolfcrypt/misc.h>
+#else
+    #define WOLFSSL_MISC_INCLUDED
+    #include <wolfcrypt/src/misc.c>
+#endif
+
+
+#if !defined(WOLFSSL_ALLOW_NO_SUITES) && !defined(WOLFCRYPT_ONLY)
+    #if defined(NO_DH) && !defined(HAVE_ECC) && !defined(WOLFSSL_STATIC_RSA) \
+                && !defined(WOLFSSL_STATIC_DH) && !defined(WOLFSSL_STATIC_PSK) \
+                && !defined(HAVE_ED25519) && !defined(HAVE_ED448)
+        #error "No cipher suites defined because DH disabled, ECC disabled, and no static suites defined. Please see top of README"
+    #endif
+    #ifdef WOLFSSL_CERT_GEN
+        /* need access to Cert struct for creating certificate */
+        #include <wolfssl/wolfcrypt/asn_public.h>
+    #endif
+#endif
+
+#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL) || \
+        defined(HAVE_WEBSERVER) || defined(WOLFSSL_KEY_GEN)
+    #include <wolfssl/openssl/evp.h>
+    /* openssl headers end, wolfssl internal headers next */
+#endif
+
+#include <wolfssl/wolfcrypt/wc_encrypt.h>
+
+#ifndef NO_RSA
+    #include <wolfssl/wolfcrypt/rsa.h>
+#endif
+
+#ifdef OPENSSL_EXTRA
+    /* openssl headers begin */
+    #include <wolfssl/openssl/aes.h>
+    #include <wolfssl/openssl/hmac.h>
+    #include <wolfssl/openssl/crypto.h>
+    #include <wolfssl/openssl/des.h>
+    #include <wolfssl/openssl/bn.h>
+    #include <wolfssl/openssl/buffer.h>
+    #include <wolfssl/openssl/dh.h>
+    #include <wolfssl/openssl/rsa.h>
+    #include <wolfssl/openssl/pem.h>
+    #include <wolfssl/openssl/ec.h>
+    #include <wolfssl/openssl/ec25519.h>
+    #include <wolfssl/openssl/ed25519.h>
+    #include <wolfssl/openssl/ec448.h>
+    #include <wolfssl/openssl/ed448.h>
+    #include <wolfssl/openssl/ecdsa.h>
+    #include <wolfssl/openssl/ecdh.h>
+    #include <wolfssl/openssl/err.h>
+    #include <wolfssl/openssl/opensslv.h>
+    #include <wolfssl/openssl/rc4.h>
+    #include <wolfssl/openssl/stack.h>
+    #include <wolfssl/openssl/x509v3.h>
+    #include <wolfssl/openssl/x509_vfy.h>
+    /* openssl headers end, wolfssl internal headers next */
+    #include <wolfssl/wolfcrypt/hmac.h>
+    #include <wolfssl/wolfcrypt/random.h>
+    #include <wolfssl/wolfcrypt/des3.h>
+    #include <wolfssl/wolfcrypt/md4.h>
+    #include <wolfssl/wolfcrypt/md5.h>
+    #include <wolfssl/wolfcrypt/arc4.h>
+    #include <wolfssl/wolfcrypt/idea.h>
+    #include <wolfssl/wolfcrypt/curve25519.h>
+    #include <wolfssl/wolfcrypt/ed25519.h>
+    #include <wolfssl/wolfcrypt/curve448.h>
+    #if defined(OPENSSL_ALL) || defined(HAVE_STUNNEL)
+        #include <wolfssl/openssl/ocsp.h>
+    #endif /* WITH_STUNNEL */
+    #if defined(WOLFSSL_SHA512) || defined(WOLFSSL_SHA384)
+        #include <wolfssl/wolfcrypt/sha512.h>
+    #endif
+    #if defined(WOLFCRYPT_HAVE_SRP) && !defined(NO_SHA256) \
+        && !defined(WC_NO_RNG)
+        #include <wolfssl/wolfcrypt/srp.h>
+    #endif
+    #if defined(HAVE_FIPS) || defined(HAVE_SELFTEST)
+        #include <wolfssl/wolfcrypt/pkcs7.h>
+    #endif
+    #if defined(OPENSSL_ALL) && defined(HAVE_PKCS7)
+        #include <wolfssl/openssl/pkcs7.h>
+    #endif /* OPENSSL_ALL && HAVE_PKCS7 */
+#endif
+#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
+    int SetIndividualInternal(WOLFSSL_BIGNUM* bn, mp_int* mpi);
+    int SetIndividualExternal(WOLFSSL_BIGNUM** bn, mp_int* mpi);
+    int oid2nid(word32 oid, int grp);
+#endif
+
+#if defined(WOLFSSL_QT)
+    #include <wolfssl/wolfcrypt/sha.h>
+#endif
+
+#ifdef NO_ASN
+    #include <wolfssl/wolfcrypt/dh.h>
+#endif
+#endif /* !WOLFCRYPT_ONLY || OPENSSL_EXTRA */
+
+#define WOLFSSL_EVP_INCLUDED
+#include "wolfcrypt/src/evp.c"
+
+#ifdef OPENSSL_EXTRA
+/* Global pointer to constant BN on */
+static WOLFSSL_BIGNUM* bn_one = NULL;
+#endif
+
+#ifndef WOLFCRYPT_ONLY
+
+#if defined(OPENSSL_EXTRA) && defined(HAVE_ECC)
+const WOLF_EC_NIST_NAME kNistCurves[] = {
+    {XSTR_SIZEOF("P-192"),   "P-192",   NID_X9_62_prime192v1},
+    {XSTR_SIZEOF("P-256"),   "P-256",   NID_X9_62_prime256v1},
+    {XSTR_SIZEOF("P-112"),   "P-112",   NID_secp112r1},
+    {XSTR_SIZEOF("P-112-2"), "P-112-2", NID_secp112r2},
+    {XSTR_SIZEOF("P-128"),   "P-128",   NID_secp128r1},
+    {XSTR_SIZEOF("P-128-2"), "P-128-2", NID_secp128r2},
+    {XSTR_SIZEOF("P-160"),   "P-160",   NID_secp160r1},
+    {XSTR_SIZEOF("P-160-2"), "P-160-2", NID_secp160r2},
+    {XSTR_SIZEOF("P-224"),   "P-224",   NID_secp224r1},
+    {XSTR_SIZEOF("P-384"),   "P-384",   NID_secp384r1},
+    {XSTR_SIZEOF("P-521"),   "P-521",   NID_secp521r1},
+    {XSTR_SIZEOF("K-160"),   "K-160",   NID_secp160k1},
+    {XSTR_SIZEOF("K-192"),   "K-192",   NID_secp192k1},
+    {XSTR_SIZEOF("K-224"),   "K-224",   NID_secp224k1},
+    {XSTR_SIZEOF("K-256"),   "K-256",   NID_secp256k1},
+    {XSTR_SIZEOF("B-160"),   "B-160",   NID_brainpoolP160r1},
+    {XSTR_SIZEOF("B-192"),   "B-192",   NID_brainpoolP192r1},
+    {XSTR_SIZEOF("B-224"),   "B-224",   NID_brainpoolP224r1},
+    {XSTR_SIZEOF("B-256"),   "B-256",   NID_brainpoolP256r1},
+    {XSTR_SIZEOF("B-320"),   "B-320",   NID_brainpoolP320r1},
+    {XSTR_SIZEOF("B-384"),   "B-384",   NID_brainpoolP384r1},
+    {XSTR_SIZEOF("B-512"),   "B-512",   NID_brainpoolP512r1},
+    {0,                     NULL,      0},
+};
+#endif
+
+#if defined(WOLFSSL_RENESAS_TSIP_TLS)
+    /* for root ca verification */
+int tsip_tls_RootCertVerify(const byte *cert, word32 cert_len,
+                            word32 key_n_start, word32 key_n_len,
+                            word32 key_e_start, word32 key_e_len,
+                            word32 cm_row);
+byte tsip_rootCAverified( );
+#endif
+
+#ifdef WOLFSSL_SESSION_EXPORT
+#ifdef WOLFSSL_DTLS
+int wolfSSL_dtls_import(WOLFSSL* ssl, unsigned char* buf, unsigned int sz)
+{
+    WOLFSSL_ENTER("wolfSSL_session_import");
+
+    if (ssl == NULL || buf == NULL) {
+        return BAD_FUNC_ARG;
+    }
+
+    /* sanity checks on buffer and protocol are done in internal function */
+    return wolfSSL_dtls_import_internal(ssl, buf, sz);
+}
+
+
+/* Sets the function to call for serializing the session. This function is
+ * called right after the handshake is completed. */
+int wolfSSL_CTX_dtls_set_export(WOLFSSL_CTX* ctx, wc_dtls_export func)
+{
+
+    WOLFSSL_ENTER("wolfSSL_CTX_dtls_set_export");
+
+    /* purposefully allow func to be NULL */
+    if (ctx == NULL) {
+        return BAD_FUNC_ARG;
+    }
+
+    ctx->dtls_export = func;
+
+    return WOLFSSL_SUCCESS;
+}
+
+
+/* Sets the function in WOLFSSL struct to call for serializing the session. This
+ * function is called right after the handshake is completed. */
+int wolfSSL_dtls_set_export(WOLFSSL* ssl, wc_dtls_export func)
+{
+
+    WOLFSSL_ENTER("wolfSSL_dtls_set_export");
+
+    /* purposefully allow func to be NULL */
+    if (ssl == NULL) {
+        return BAD_FUNC_ARG;
+    }
+
+    ssl->dtls_export = func;
+
+    return WOLFSSL_SUCCESS;
+}
+
+
+/* This function allows for directly serializing a session rather than using
+ * callbacks. It has less overhead by removing a temporary buffer and gives
+ * control over when the session gets serialized. When using callbacks the
+ * session is always serialized immediately after the handshake is finished.
+ *
+ * buf is the argument to contain the serialized session
+ * sz  is the size of the buffer passed in
+ * ssl is the WOLFSSL struct to serialize
+ * returns the size of serialized session on success, 0 on no action, and
+ *         negative value on error */
+int wolfSSL_dtls_export(WOLFSSL* ssl, unsigned char* buf, unsigned int* sz)
+{
+    WOLFSSL_ENTER("wolfSSL_dtls_export");
+
+    if (ssl == NULL || sz == NULL) {
+        return BAD_FUNC_ARG;
+    }
+
+    if (buf == NULL) {
+        *sz = MAX_EXPORT_BUFFER;
+        return 0;
+    }
+
+    /* if not DTLS do nothing */
+    if (!ssl->options.dtls) {
+        WOLFSSL_MSG("Currently only DTLS export is supported");
+        return 0;
+    }
+
+    /* copy over keys, options, and dtls state struct */
+    return wolfSSL_dtls_export_internal(ssl, buf, *sz);
+}
+
+
+/* This function is similar to wolfSSL_dtls_export but only exports the portion
+ * of the WOLFSSL structure related to the state of the connection, i.e. peer
+ * sequence number, epoch, AEAD state etc.
+ *
+ * buf is the argument to contain the serialized state, if null then set "sz" to
+ *     buffer size required
+ * sz  is the size of the buffer passed in
+ * ssl is the WOLFSSL struct to serialize
+ * returns the size of serialized session on success, 0 on no action, and
+ *         negative value on error */
+int wolfSSL_dtls_export_state_only(WOLFSSL* ssl, unsigned char* buf,
+        unsigned int* sz)
+{
+    WOLFSSL_ENTER("wolfSSL_dtls_export_state_only");
+
+    if (ssl == NULL || sz == NULL) {
+        return BAD_FUNC_ARG;
+    }
+
+    if (buf == NULL) {
+        *sz = MAX_EXPORT_STATE_BUFFER;
+        return 0;
+    }
+
+    /* if not DTLS do nothing */
+    if (!ssl->options.dtls) {
+        WOLFSSL_MSG("Currently only DTLS export state is supported");
+        return 0;
+    }
+
+    /* copy over keys, options, and dtls state struct */
+    return wolfSSL_dtls_export_state_internal(ssl, buf, *sz);
+}
+
+
+/* returns 0 on success */
+int wolfSSL_send_session(WOLFSSL* ssl)
+{
+    int ret;
+    byte* buf;
+    word16 bufSz = MAX_EXPORT_BUFFER;
+
+    WOLFSSL_ENTER("wolfSSL_send_session");
+
+    if (ssl == NULL) {
+        return BAD_FUNC_ARG;
+    }
+
+    buf = (byte*)XMALLOC(bufSz, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER);
+    if (buf == NULL) {
+        return MEMORY_E;
+    }
+
+    /* if not DTLS do nothing */
+    if (!ssl->options.dtls) {
+        XFREE(buf, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER);
+        WOLFSSL_MSG("Currently only DTLS export is supported");
+        return 0;
+    }
+
+    /* copy over keys, options, and dtls state struct */
+    ret = wolfSSL_dtls_export_internal(ssl, buf, bufSz);
+    if (ret < 0) {
+        XFREE(buf, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER);
+        return ret;
+    }
+
+    /* if no error ret has size of buffer */
+    ret = ssl->dtls_export(ssl, buf, ret, NULL);
+    if (ret != WOLFSSL_SUCCESS) {
+        XFREE(buf, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER);
+        return ret;
+    }
+
+    XFREE(buf, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER);
+    return 0;
+}
+#endif /* WOLFSSL_DTLS */
+#endif /* WOLFSSL_SESSION_EXPORT */
+
+/* prevent multiple mutex initializations */
+static volatile WOLFSSL_GLOBAL int initRefCount = 0;
+static WOLFSSL_GLOBAL wolfSSL_Mutex count_mutex;   /* init ref count mutex */
+
+/* Create a new WOLFSSL_CTX struct and return the pointer to created struct.
+   WOLFSSL_METHOD pointer passed in is given to ctx to manage.
+   This function frees the passed in WOLFSSL_METHOD struct on failure and on
+   success is freed when ctx is freed.
+ */
+WOLFSSL_CTX* wolfSSL_CTX_new_ex(WOLFSSL_METHOD* method, void* heap)
+{
+    WOLFSSL_CTX* ctx = NULL;
+
+    WOLFSSL_ENTER("wolfSSL_CTX_new_ex");
+
+    if (initRefCount == 0) {
+        /* user no longer forced to call Init themselves */
+        int ret = wolfSSL_Init();
+        if (ret != WOLFSSL_SUCCESS) {
+            WOLFSSL_MSG("wolfSSL_Init failed");
+            WOLFSSL_LEAVE("WOLFSSL_CTX_new", 0);
+            if (method != NULL) {
+                XFREE(method, heap, DYNAMIC_TYPE_METHOD);
+            }
+            return NULL;
+        }
+    }
+
+    if (method == NULL)
+        return ctx;
+
+    ctx = (WOLFSSL_CTX*) XMALLOC(sizeof(WOLFSSL_CTX), heap, DYNAMIC_TYPE_CTX);
+    if (ctx) {
+        int ret;
+
+        ret = InitSSL_Ctx(ctx, method, heap);
+    #ifdef WOLFSSL_STATIC_MEMORY
+        if (heap != NULL) {
+            ctx->onHeap = 1; /* free the memory back to heap when done */
+        }
+    #endif
+        if (ret < 0) {
+            WOLFSSL_MSG("Init CTX failed");
+            wolfSSL_CTX_free(ctx);
+            ctx = NULL;
+        }
+#if defined(OPENSSL_EXTRA) && defined(WOLFCRYPT_HAVE_SRP) \
+                           && !defined(NO_SHA256) && !defined(WC_NO_RNG)
+        else {
+            ctx->srp = (Srp*) XMALLOC(sizeof(Srp), heap, DYNAMIC_TYPE_SRP);
+            if (ctx->srp == NULL){
+                WOLFSSL_MSG("Init CTX failed");
+                wolfSSL_CTX_free(ctx);
+                return NULL;
+            }
+            XMEMSET(ctx->srp, 0, sizeof(Srp));
+        }
+#endif
+    }
+    else {
+        WOLFSSL_MSG("Alloc CTX failed, method freed");
+        XFREE(method, heap, DYNAMIC_TYPE_METHOD);
+    }
+
+
+    WOLFSSL_LEAVE("WOLFSSL_CTX_new", 0);
+    return ctx;
+}
+
+
+WOLFSSL_ABI
+WOLFSSL_CTX* wolfSSL_CTX_new(WOLFSSL_METHOD* method)
+{
+#ifdef WOLFSSL_HEAP_TEST
+    /* if testing the heap hint then set top level CTX to have test value */
+    return wolfSSL_CTX_new_ex(method, (void*)WOLFSSL_HEAP_TEST);
+#else
+    return wolfSSL_CTX_new_ex(method, NULL);
+#endif
+}
+
+#ifdef OPENSSL_EXTRA
+/* increases CTX reference count to track proper time to "free" */
+int wolfSSL_CTX_up_ref(WOLFSSL_CTX* ctx)
+{
+    int refCount = SSL_CTX_RefCount(ctx, 1);
+    return ((refCount > 1) ? 1 : 0);
+}
+#endif
+
+WOLFSSL_ABI
+void wolfSSL_CTX_free(WOLFSSL_CTX* ctx)
+{
+    WOLFSSL_ENTER("SSL_CTX_free");
+    if (ctx) {
+#if defined(OPENSSL_EXTRA) && defined(WOLFCRYPT_HAVE_SRP) \
+&& !defined(NO_SHA256) && !defined(WC_NO_RNG)
+        if (ctx->srp != NULL){
+            if (ctx->srp_password != NULL){
+                XFREE(ctx->srp_password, ctx->heap, DYNAMIC_TYPE_SRP);
+                ctx->srp_password = NULL;
+            }
+            wc_SrpTerm(ctx->srp);
+            XFREE(ctx->srp, ctx->heap, DYNAMIC_TYPE_SRP);
+            ctx->srp = NULL;
+        }
+#endif
+        FreeSSL_Ctx(ctx);
+    }
+
+    WOLFSSL_LEAVE("SSL_CTX_free", 0);
+}
+
+
+#ifdef HAVE_ENCRYPT_THEN_MAC
+/**
+ * Sets whether Encrypt-Then-MAC extension can be negotiated against context.
+ * The default value: enabled.
+ *
+ * ctx  SSL/TLS context.
+ * set  Whether to allow or not: 1 is allow and 0 is disallow.
+ * returns WOLFSSL_SUCCESS
+ */
+int wolfSSL_CTX_AllowEncryptThenMac(WOLFSSL_CTX *ctx, int set)
+{
+    ctx->disallowEncThenMac = !set;
+    return WOLFSSL_SUCCESS;
+}
+
+/**
+ * Sets whether Encrypt-Then-MAC extension can be negotiated against context.
+ * The default value comes from context.
+ *
+ * ctx  SSL/TLS context.
+ * set  Whether to allow or not: 1 is allow and 0 is disallow.
+ * returns WOLFSSL_SUCCESS
+ */
+int wolfSSL_AllowEncryptThenMac(WOLFSSL *ssl, int set)
+{
+    ssl->options.disallowEncThenMac = !set;
+    return WOLFSSL_SUCCESS;
+}
+#endif
+
+#ifdef SINGLE_THREADED
+/* no locking in single threaded mode, allow a CTX level rng to be shared with
+ * WOLFSSL objects, WOLFSSL_SUCCESS on ok */
+int wolfSSL_CTX_new_rng(WOLFSSL_CTX* ctx)
+{
+    WC_RNG* rng;
+    int     ret;
+
+    if (ctx == NULL) {
+        return BAD_FUNC_ARG;
+    }
+
+    rng = (WC_RNG*)XMALLOC(sizeof(WC_RNG), ctx->heap, DYNAMIC_TYPE_RNG);
+    if (rng == NULL) {
+        return MEMORY_E;
+    }
+
+#ifndef HAVE_FIPS
+    ret = wc_InitRng_ex(rng, ctx->heap, ctx->devId);
+#else
+    ret = wc_InitRng(rng);
+#endif
+    if (ret != 0) {
+        XFREE(rng, ctx->heap, DYNAMIC_TYPE_RNG);
+        return ret;
+    }
+
+    ctx->rng = rng;
+    return WOLFSSL_SUCCESS;
+}
+#endif
+
+
+WOLFSSL_ABI
+WOLFSSL* wolfSSL_new(WOLFSSL_CTX* ctx)
+{
+    WOLFSSL* ssl = NULL;
+    int ret = 0;
+
+    (void)ret;
+    WOLFSSL_ENTER("SSL_new");
+
+    if (ctx == NULL)
+        return ssl;
+
+    ssl = (WOLFSSL*) XMALLOC(sizeof(WOLFSSL), ctx->heap, DYNAMIC_TYPE_SSL);
+    if (ssl)
+        if ( (ret = InitSSL(ssl, ctx, 0)) < 0) {
+            FreeSSL(ssl, ctx->heap);
+            ssl = 0;
+        }
+
+    WOLFSSL_LEAVE("SSL_new", ret);
+    return ssl;
+}
+
+
+WOLFSSL_ABI
+void wolfSSL_free(WOLFSSL* ssl)
+{
+    WOLFSSL_ENTER("SSL_free");
+    if (ssl)
+        FreeSSL(ssl, ssl->ctx->heap);
+    WOLFSSL_LEAVE("SSL_free", 0);
+}
+
+
+int wolfSSL_is_server(WOLFSSL* ssl)
+{
+    if (ssl == NULL)
+        return BAD_FUNC_ARG;
+    return ssl->options.side == WOLFSSL_SERVER_END;
+}
+
+#ifdef HAVE_WRITE_DUP
+
+/*
+ * Release resources around WriteDup object
+ *
+ * ssl WOLFSSL object
+ *
+ * no return, destruction so make best attempt
+*/
+void FreeWriteDup(WOLFSSL* ssl)
+{
+    int doFree = 0;
+
+    WOLFSSL_ENTER("FreeWriteDup");
+
+    if (ssl->dupWrite) {
+        if (wc_LockMutex(&ssl->dupWrite->dupMutex) == 0) {
+            ssl->dupWrite->dupCount--;
+            if (ssl->dupWrite->dupCount == 0) {
+                doFree = 1;
+            } else {
+                WOLFSSL_MSG("WriteDup count not zero, no full free");
+            }
+            wc_UnLockMutex(&ssl->dupWrite->dupMutex);
+        }
+    }
+
+    if (doFree) {
+        WOLFSSL_MSG("Doing WriteDup full free, count to zero");
+        wc_FreeMutex(&ssl->dupWrite->dupMutex);
+        XFREE(ssl->dupWrite, ssl->heap, DYNAMIC_TYPE_WRITEDUP);
+    }
+}
+
+
+/*
+ * duplicate existing ssl members into dup needed for writing
+ *
+ * dup write only WOLFSSL
+ * ssl existing WOLFSSL
+ *
+ * 0 on success
+*/
+static int DupSSL(WOLFSSL* dup, WOLFSSL* ssl)
+{
+    /* shared dupWrite setup */
+    ssl->dupWrite = (WriteDup*)XMALLOC(sizeof(WriteDup), ssl->heap,
+                                       DYNAMIC_TYPE_WRITEDUP);
+    if (ssl->dupWrite == NULL) {
+        return MEMORY_E;
+    }
+    XMEMSET(ssl->dupWrite, 0, sizeof(WriteDup));
+
+    if (wc_InitMutex(&ssl->dupWrite->dupMutex) != 0) {
+        XFREE(ssl->dupWrite, ssl->heap, DYNAMIC_TYPE_WRITEDUP);
+        ssl->dupWrite = NULL;
+        return BAD_MUTEX_E;
+    }
+    ssl->dupWrite->dupCount = 2;    /* both sides have a count to start */
+    dup->dupWrite = ssl->dupWrite; /* each side uses */
+
+    /* copy write parts over to dup writer */
+    XMEMCPY(&dup->specs,   &ssl->specs,   sizeof(CipherSpecs));
+    XMEMCPY(&dup->options, &ssl->options, sizeof(Options));
+    XMEMCPY(&dup->keys,    &ssl->keys,    sizeof(Keys));
+    XMEMCPY(&dup->encrypt, &ssl->encrypt, sizeof(Ciphers));
+    /* dup side now owns encrypt/write ciphers */
+    XMEMSET(&ssl->encrypt, 0, sizeof(Ciphers));
+
+    dup->IOCB_WriteCtx = ssl->IOCB_WriteCtx;
+    dup->wfd    = ssl->wfd;
+    dup->wflags = ssl->wflags;
+    dup->hmac   = ssl->hmac;
+#ifdef HAVE_TRUNCATED_HMAC
+    dup->truncated_hmac = ssl->truncated_hmac;
+#endif
+
+    /* unique side dup setup */
+    dup->dupSide = WRITE_DUP_SIDE;
+    ssl->dupSide = READ_DUP_SIDE;
+
+    return 0;
+}
+
+
+/*
+ * duplicate a WOLFSSL object post handshake for writing only
+ * turn existing object into read only.  Allows concurrent access from two
+ * different threads.
+ *
+ * ssl existing WOLFSSL object
+ *
+ * return dup'd WOLFSSL object on success
+*/
+WOLFSSL* wolfSSL_write_dup(WOLFSSL* ssl)
+{
+    WOLFSSL* dup = NULL;
+    int ret = 0;
+
+    (void)ret;
+    WOLFSSL_ENTER("wolfSSL_write_dup");
+
+    if (ssl == NULL) {
+        return ssl;
+    }
+
+    if (ssl->options.handShakeDone == 0) {
+        WOLFSSL_MSG("wolfSSL_write_dup called before handshake complete");
+        return NULL;
+    }
+
+    if (ssl->dupWrite) {
+        WOLFSSL_MSG("wolfSSL_write_dup already called once");
+        return NULL;
+    }
+
+    dup = (WOLFSSL*) XMALLOC(sizeof(WOLFSSL), ssl->ctx->heap, DYNAMIC_TYPE_SSL);
+    if (dup) {
+        if ( (ret = InitSSL(dup, ssl->ctx, 1)) < 0) {
+            FreeSSL(dup, ssl->ctx->heap);
+            dup = NULL;
+        } else if ( (ret = DupSSL(dup, ssl)) < 0) {
+            FreeSSL(dup, ssl->ctx->heap);
+            dup = NULL;
+        }
+    }
+
+    WOLFSSL_LEAVE("wolfSSL_write_dup", ret);
+
+    return dup;
+}
+
+
+/*
+ * Notify write dup side of fatal error or close notify
+ *
+ * ssl WOLFSSL object
+ * err Notify err
+ *
+ * 0 on success
+*/
+int NotifyWriteSide(WOLFSSL* ssl, int err)
+{
+    int ret;
+
+    WOLFSSL_ENTER("NotifyWriteSide");
+
+    ret = wc_LockMutex(&ssl->dupWrite->dupMutex);
+    if (ret == 0) {
+        ssl->dupWrite->dupErr = err;
+        ret = wc_UnLockMutex(&ssl->dupWrite->dupMutex);
+    }
+
+    return ret;
+}
+
+
+#endif /* HAVE_WRITE_DUP */
+
+
+#ifdef HAVE_POLY1305
+/* set if to use old poly 1 for yes 0 to use new poly */
+int wolfSSL_use_old_poly(WOLFSSL* ssl, int value)
+{
+    (void)ssl;
+    (void)value;
+
+#ifndef WOLFSSL_NO_TLS12
+    WOLFSSL_ENTER("SSL_use_old_poly");
+    WOLFSSL_MSG("Warning SSL connection auto detects old/new and this function"
+            "is depreciated");
+    ssl->options.oldPoly = (word16)value;
+    WOLFSSL_LEAVE("SSL_use_old_poly", 0);
+#endif
+    return 0;
+}
+#endif
+
+
+WOLFSSL_ABI
+int wolfSSL_set_fd(WOLFSSL* ssl, int fd)
+{
+    int ret;
+
+    WOLFSSL_ENTER("SSL_set_fd");
+
+    if (ssl == NULL) {
+        return BAD_FUNC_ARG;
+    }
+
+    ret = wolfSSL_set_read_fd(ssl, fd);
+    if (ret == WOLFSSL_SUCCESS) {
+        ret = wolfSSL_set_write_fd(ssl, fd);
+    }
+
+    return ret;
+}
+
+
+int wolfSSL_set_read_fd(WOLFSSL* ssl, int fd)
+{
+    WOLFSSL_ENTER("SSL_set_read_fd");
+
+    if (ssl == NULL) {
+        return BAD_FUNC_ARG;
+    }
+
+    ssl->rfd = fd;      /* not used directly to allow IO callbacks */
+    ssl->IOCB_ReadCtx  = &ssl->rfd;
+
+    #ifdef WOLFSSL_DTLS
+        if (ssl->options.dtls) {
+            ssl->IOCB_ReadCtx = &ssl->buffers.dtlsCtx;
+            ssl->buffers.dtlsCtx.rfd = fd;
+        }
+    #endif
+
+    WOLFSSL_LEAVE("SSL_set_read_fd", WOLFSSL_SUCCESS);
+    return WOLFSSL_SUCCESS;
+}
+
+
+int wolfSSL_set_write_fd(WOLFSSL* ssl, int fd)
+{
+    WOLFSSL_ENTER("SSL_set_write_fd");
+
+    if (ssl == NULL) {
+        return BAD_FUNC_ARG;
+    }
+
+    ssl->wfd = fd;      /* not used directly to allow IO callbacks */
+    ssl->IOCB_WriteCtx  = &ssl->wfd;
+
+    #ifdef WOLFSSL_DTLS
+        if (ssl->options.dtls) {
+            ssl->IOCB_WriteCtx = &ssl->buffers.dtlsCtx;
+            ssl->buffers.dtlsCtx.wfd = fd;
+        }
+    #endif
+
+    WOLFSSL_LEAVE("SSL_set_write_fd", WOLFSSL_SUCCESS);
+    return WOLFSSL_SUCCESS;
+}
+
+
+/**
+  * Get the name of cipher at priority level passed in.
+  */
+char* wolfSSL_get_cipher_list(int priority)
+{
+    const CipherSuiteInfo* ciphers = GetCipherNames();
+
+    if (priority >= GetCipherNamesSize() || priority < 0) {
+        return 0;
+    }
+
+    return (char*)ciphers[priority].name;
+}
+
+
+/**
+  * Get the name of cipher at priority level passed in.
+  */
+char* wolfSSL_get_cipher_list_ex(WOLFSSL* ssl, int priority)
+{
+
+    if (ssl == NULL) {
+        return NULL;
+    }
+    else {
+        const char* cipher;
+
+        if ((cipher = wolfSSL_get_cipher_name_internal(ssl)) != NULL) {
+            if (priority == 0) {
+                return (char*)cipher;
+            }
+            else {
+                return NULL;
+            }
+        }
+        else {
+            return wolfSSL_get_cipher_list(priority);
+        }
+    }
+}
+
+
+int wolfSSL_get_ciphers(char* buf, int len)
+{
+    const CipherSuiteInfo* ciphers = GetCipherNames();
+    int ciphersSz = GetCipherNamesSize();
+    int i;
+    int cipherNameSz;
+
+    if (buf == NULL || len <= 0)
+        return BAD_FUNC_ARG;
+
+    /* Add each member to the buffer delimited by a : */
+    for (i = 0; i < ciphersSz; i++) {
+        cipherNameSz = (int)XSTRLEN(ciphers[i].name);
+        if (cipherNameSz + 1 < len) {
+            XSTRNCPY(buf, ciphers[i].name, len);
+            buf += cipherNameSz;
+
+            if (i < ciphersSz - 1)
+                *buf++ = ':';
+            *buf = 0;
+
+            len -= cipherNameSz + 1;
+        }
+        else
+            return BUFFER_E;
+    }
+    return WOLFSSL_SUCCESS;
+}
+
+
+#ifndef NO_ERROR_STRINGS
+/* places a list of all supported cipher suites in TLS_* format into "buf"
+ * return WOLFSSL_SUCCESS on success */
+int wolfSSL_get_ciphers_iana(char* buf, int len)
+{
+    const CipherSuiteInfo* ciphers = GetCipherNames();
+    int ciphersSz = GetCipherNamesSize();
+    int i;
+    int cipherNameSz;
+
+    if (buf == NULL || len <= 0)
+        return BAD_FUNC_ARG;
+
+    /* Add each member to the buffer delimited by a : */
+    for (i = 0; i < ciphersSz; i++) {
+        cipherNameSz = (int)XSTRLEN(ciphers[i].name_iana);
+        if (cipherNameSz + 1 < len) {
+            XSTRNCPY(buf, ciphers[i].name_iana, len);
+            buf += cipherNameSz;
+
+            if (i < ciphersSz - 1)
+                *buf++ = ':';
+            *buf = 0;
+
+            len -= cipherNameSz + 1;
+        }
+        else
+            return BUFFER_E;
+    }
+    return WOLFSSL_SUCCESS;
+}
+#endif /* NO_ERROR_STRINGS */
+
+
+const char* wolfSSL_get_shared_ciphers(WOLFSSL* ssl, char* buf, int len)
+{
+    const char* cipher;
+
+    if (ssl == NULL)
+        return NULL;
+
+    cipher = wolfSSL_get_cipher_name_iana(ssl);
+    len = min(len, (int)(XSTRLEN(cipher) + 1));
+    XMEMCPY(buf, cipher, len);
+    return buf;
+}
+
+int wolfSSL_get_fd(const WOLFSSL* ssl)
+{
+    int fd = -1;
+    WOLFSSL_ENTER("SSL_get_fd");
+    if (ssl) {
+        fd = ssl->rfd;
+    }
+    WOLFSSL_LEAVE("SSL_get_fd", fd);
+    return fd;
+}
+
+
+int wolfSSL_dtls(WOLFSSL* ssl)
+{
+    int dtlsOpt = 0;
+    if (ssl)
+        dtlsOpt = ssl->options.dtls;
+    return dtlsOpt;
+}
+
+#if !defined(NO_CERTS)
+/* Set whether mutual authentication is required for connections.
+ * Server side only.
+ *
+ * ctx  The SSL/TLS CTX object.
+ * req  1 to indicate required and 0 when not.
+ * returns BAD_FUNC_ARG when ctx is NULL, SIDE_ERROR when not a server and
+ * 0 on success.
+ */
+int wolfSSL_CTX_mutual_auth(WOLFSSL_CTX* ctx, int req)
+{
+    if (ctx == NULL)
+        return BAD_FUNC_ARG;
+    if (ctx->method->side == WOLFSSL_CLIENT_END)
+        return SIDE_ERROR;
+
+    ctx->mutualAuth = (byte)req;
+
+    return 0;
+}
+
+/* Set whether mutual authentication is required for the connection.
+ * Server side only.
+ *
+ * ssl  The SSL/TLS object.
+ * req  1 to indicate required and 0 when not.
+ * returns BAD_FUNC_ARG when ssl is NULL, or not using TLS v1.3,
+ * SIDE_ERROR when not a client and 0 on success.
+ */
+int wolfSSL_mutual_auth(WOLFSSL* ssl, int req)
+{
+    if (ssl == NULL)
+        return BAD_FUNC_ARG;
+    if (ssl->options.side == WOLFSSL_SERVER_END)
+        return SIDE_ERROR;
+
+    ssl->options.mutualAuth = (word16)req;
+
+    return 0;
+}
+#endif /* NO_CERTS */
+
+#ifndef WOLFSSL_LEANPSK
+int wolfSSL_dtls_set_peer(WOLFSSL* ssl, void* peer, unsigned int peerSz)
+{
+#ifdef WOLFSSL_DTLS
+    void* sa;
+
+    if (ssl == NULL)
+        return WOLFSSL_FAILURE;
+
+    sa = (void*)XMALLOC(peerSz, ssl->heap, DYNAMIC_TYPE_SOCKADDR);
+    if (sa != NULL) {
+        if (ssl->buffers.dtlsCtx.peer.sa != NULL) {
+            XFREE(ssl->buffers.dtlsCtx.peer.sa,ssl->heap,DYNAMIC_TYPE_SOCKADDR);
+            ssl->buffers.dtlsCtx.peer.sa = NULL;
+        }
+        XMEMCPY(sa, peer, peerSz);
+        ssl->buffers.dtlsCtx.peer.sa = sa;
+        ssl->buffers.dtlsCtx.peer.sz = peerSz;
+        return WOLFSSL_SUCCESS;
+    }
+    return WOLFSSL_FAILURE;
+#else
+    (void)ssl;
+    (void)peer;
+    (void)peerSz;
+    return WOLFSSL_NOT_IMPLEMENTED;
+#endif
+}
+
+int wolfSSL_dtls_get_peer(WOLFSSL* ssl, void* peer, unsigned int* peerSz)
+{
+#ifdef WOLFSSL_DTLS
+    if (ssl == NULL) {
+        return WOLFSSL_FAILURE;
+    }
+
+    if (peer != NULL && peerSz != NULL
+            && *peerSz >= ssl->buffers.dtlsCtx.peer.sz
+            && ssl->buffers.dtlsCtx.peer.sa != NULL) {
+        *peerSz = ssl->buffers.dtlsCtx.peer.sz;
+        XMEMCPY(peer, ssl->buffers.dtlsCtx.peer.sa, *peerSz);
+        return WOLFSSL_SUCCESS;
+    }
+    return WOLFSSL_FAILURE;
+#else
+    (void)ssl;
+    (void)peer;
+    (void)peerSz;
+    return WOLFSSL_NOT_IMPLEMENTED;
+#endif
+}
+
+
+#if defined(WOLFSSL_SCTP) && defined(WOLFSSL_DTLS)
+
+int wolfSSL_CTX_dtls_set_sctp(WOLFSSL_CTX* ctx)
+{
+    WOLFSSL_ENTER("wolfSSL_CTX_dtls_set_sctp()");
+
+    if (ctx == NULL)
+        return BAD_FUNC_ARG;
+
+    ctx->dtlsSctp = 1;
+    return WOLFSSL_SUCCESS;
+}
+
+
+int wolfSSL_dtls_set_sctp(WOLFSSL* ssl)
+{
+    WOLFSSL_ENTER("wolfSSL_dtls_set_sctp()");
+
+    if (ssl == NULL)
+        return BAD_FUNC_ARG;
+
+    ssl->options.dtlsSctp = 1;
+    return WOLFSSL_SUCCESS;
+}
+
+#endif /* WOLFSSL_DTLS && WOLFSSL_SCTP */
+
+#if (defined(WOLFSSL_SCTP) || defined(WOLFSSL_DTLS_MTU)) && \
+                                                           defined(WOLFSSL_DTLS)
+
+int wolfSSL_CTX_dtls_set_mtu(WOLFSSL_CTX* ctx, word16 newMtu)
+{
+    if (ctx == NULL || newMtu > MAX_RECORD_SIZE)
+        return BAD_FUNC_ARG;
+
+    ctx->dtlsMtuSz = newMtu;
+    return WOLFSSL_SUCCESS;
+}
+
+
+int wolfSSL_dtls_set_mtu(WOLFSSL* ssl, word16 newMtu)
+{
+    if (ssl == NULL)
+        return BAD_FUNC_ARG;
+
+    if (newMtu > MAX_RECORD_SIZE) {
+        ssl->error = BAD_FUNC_ARG;
+        return WOLFSSL_FAILURE;
+    }
+
+    ssl->dtlsMtuSz = newMtu;
+    return WOLFSSL_SUCCESS;
+}
+
+#endif /* WOLFSSL_DTLS && (WOLFSSL_SCTP || WOLFSSL_DTLS_MTU) */
+
+
+#ifdef WOLFSSL_DTLS_DROP_STATS
+
+int wolfSSL_dtls_get_drop_stats(WOLFSSL* ssl,
+                                word32* macDropCount, word32* replayDropCount)
+{
+    int ret;
+
+    WOLFSSL_ENTER("wolfSSL_dtls_get_drop_stats()");
+
+    if (ssl == NULL)
+        ret = BAD_FUNC_ARG;
+    else {
+        ret = WOLFSSL_SUCCESS;
+        if (macDropCount != NULL)
+            *macDropCount = ssl->macDropCount;
+        if (replayDropCount != NULL)
+            *replayDropCount = ssl->replayDropCount;
+    }
+
+    WOLFSSL_LEAVE("wolfSSL_dtls_get_drop_stats()", ret);
+    return ret;
+}
+
+#endif /* WOLFSSL_DTLS_DROP_STATS */
+
+
+#if defined(WOLFSSL_MULTICAST)
+
+int wolfSSL_CTX_mcast_set_member_id(WOLFSSL_CTX* ctx, word16 id)
+{
+    int ret = 0;
+
+    WOLFSSL_ENTER("wolfSSL_CTX_mcast_set_member_id()");
+
+    if (ctx == NULL || id > 255)
+        ret = BAD_FUNC_ARG;
+
+    if (ret == 0) {
+        ctx->haveEMS = 0;
+        ctx->haveMcast = 1;
+        ctx->mcastID = (byte)id;
+#ifndef WOLFSSL_USER_IO
+        ctx->CBIORecv = EmbedReceiveFromMcast;
+#endif /* WOLFSSL_USER_IO */
+
+        ret = WOLFSSL_SUCCESS;
+    }
+    WOLFSSL_LEAVE("wolfSSL_CTX_mcast_set_member_id()", ret);
+    return ret;
+}
+
+int wolfSSL_mcast_get_max_peers(void)
+{
+    return WOLFSSL_MULTICAST_PEERS;
+}
+
+#ifdef WOLFSSL_DTLS
+static WC_INLINE word32 UpdateHighwaterMark(word32 cur, word32 first,
+                                         word32 second, word32 max)
+{
+    word32 newCur = 0;
+
+    if (cur < first)
+        newCur = first;
+    else if (cur < second)
+        newCur = second;
+    else if (cur < max)
+        newCur = max;
+
+    return newCur;
+}
+#endif /* WOLFSSL_DTLS */
+
+
+int wolfSSL_set_secret(WOLFSSL* ssl, word16 epoch,
+                       const byte* preMasterSecret, word32 preMasterSz,
+                       const byte* clientRandom, const byte* serverRandom,
+                       const byte* suite)
+{
+    int ret = 0;
+
+    WOLFSSL_ENTER("wolfSSL_set_secret()");
+
+    if (ssl == NULL || preMasterSecret == NULL ||
+        preMasterSz == 0 || preMasterSz > ENCRYPT_LEN ||
+        clientRandom == NULL || serverRandom == NULL || suite == NULL) {
+
+        ret = BAD_FUNC_ARG;
+    }
+
+    if (ret == 0) {
+        XMEMCPY(ssl->arrays->preMasterSecret, preMasterSecret, preMasterSz);
+        ssl->arrays->preMasterSz = preMasterSz;
+        XMEMCPY(ssl->arrays->clientRandom, clientRandom, RAN_LEN);
+        XMEMCPY(ssl->arrays->serverRandom, serverRandom, RAN_LEN);
+        ssl->options.cipherSuite0 = suite[0];
+        ssl->options.cipherSuite = suite[1];
+
+        ret = SetCipherSpecs(ssl);
+    }
+
+    if (ret == 0)
+        ret = MakeTlsMasterSecret(ssl);
+
+    if (ret == 0) {
+        ssl->keys.encryptionOn = 1;
+        ret = SetKeysSide(ssl, ENCRYPT_AND_DECRYPT_SIDE);
+    }
+
+    if (ret == 0) {
+        if (ssl->options.dtls) {
+        #ifdef WOLFSSL_DTLS
+            WOLFSSL_DTLS_PEERSEQ* peerSeq;
+            int i;
+
+            ssl->keys.dtls_epoch = epoch;
+            for (i = 0, peerSeq = ssl->keys.peerSeq;
+                 i < WOLFSSL_DTLS_PEERSEQ_SZ;
+                 i++, peerSeq++) {
+
+                peerSeq->nextEpoch = epoch;
+                peerSeq->prevSeq_lo = peerSeq->nextSeq_lo;
+                peerSeq->prevSeq_hi = peerSeq->nextSeq_hi;
+                peerSeq->nextSeq_lo = 0;
+                peerSeq->nextSeq_hi = 0;
+                XMEMCPY(peerSeq->prevWindow, peerSeq->window, DTLS_SEQ_SZ);
+                XMEMSET(peerSeq->window, 0, DTLS_SEQ_SZ);
+                peerSeq->highwaterMark = UpdateHighwaterMark(0,
+                        ssl->ctx->mcastFirstSeq,
+                        ssl->ctx->mcastSecondSeq,
+                        ssl->ctx->mcastMaxSeq);
+            }
+        #else
+            (void)epoch;
+        #endif
+        }
+        FreeHandshakeResources(ssl);
+        ret = WOLFSSL_SUCCESS;
+    }
+    else {
+        if (ssl)
+            ssl->error = ret;
+        ret = WOLFSSL_FATAL_ERROR;
+    }
+    WOLFSSL_LEAVE("wolfSSL_set_secret()", ret);
+    return ret;
+}
+
+
+#ifdef WOLFSSL_DTLS
+
+int wolfSSL_mcast_peer_add(WOLFSSL* ssl, word16 peerId, int remove)
+{
+    WOLFSSL_DTLS_PEERSEQ* p = NULL;
+    int ret = WOLFSSL_SUCCESS;
+    int i;
+
+    WOLFSSL_ENTER("wolfSSL_mcast_peer_add()");
+    if (ssl == NULL || peerId > 255)
+        return BAD_FUNC_ARG;
+
+    if (!remove) {
+        /* Make sure it isn't already present, while keeping the first
+         * open spot. */
+        for (i = 0; i < WOLFSSL_DTLS_PEERSEQ_SZ; i++) {
+            if (ssl->keys.peerSeq[i].peerId == INVALID_PEER_ID)
+                p = &ssl->keys.peerSeq[i];
+            if (ssl->keys.peerSeq[i].peerId == peerId) {
+                WOLFSSL_MSG("Peer ID already in multicast peer list.");
+                p = NULL;
+            }
+        }
+
+        if (p != NULL) {
+            XMEMSET(p, 0, sizeof(WOLFSSL_DTLS_PEERSEQ));
+            p->peerId = peerId;
+            p->highwaterMark = UpdateHighwaterMark(0,
+                ssl->ctx->mcastFirstSeq,
+                ssl->ctx->mcastSecondSeq,
+                ssl->ctx->mcastMaxSeq);
+        }
+        else {
+            WOLFSSL_MSG("No room in peer list.");
+            ret = -1;
+        }
+    }
+    else {
+        for (i = 0; i < WOLFSSL_DTLS_PEERSEQ_SZ; i++) {
+            if (ssl->keys.peerSeq[i].peerId == peerId)
+                p = &ssl->keys.peerSeq[i];
+        }
+
+        if (p != NULL) {
+            p->peerId = INVALID_PEER_ID;
+        }
+        else {
+            WOLFSSL_MSG("Peer not found in list.");
+        }
+    }
+
+    WOLFSSL_LEAVE("wolfSSL_mcast_peer_add()", ret);
+    return ret;
+}
+
+
+/* If peerId is in the list of peers and its last sequence number is non-zero,
+ * return 1, otherwise return 0. */
+int wolfSSL_mcast_peer_known(WOLFSSL* ssl, unsigned short peerId)
+{
+    int known = 0;
+    int i;
+
+    WOLFSSL_ENTER("wolfSSL_mcast_peer_known()");
+
+    if (ssl == NULL || peerId > 255) {
+        return BAD_FUNC_ARG;
+    }
+
+    for (i = 0; i < WOLFSSL_DTLS_PEERSEQ_SZ; i++) {
+        if (ssl->keys.peerSeq[i].peerId == peerId) {
+            if (ssl->keys.peerSeq[i].nextSeq_hi ||
+                ssl->keys.peerSeq[i].nextSeq_lo) {
+
+                known = 1;
+            }
+            break;
+        }
+    }
+
+    WOLFSSL_LEAVE("wolfSSL_mcast_peer_known()", known);
+    return known;
+}
+
+
+int wolfSSL_CTX_mcast_set_highwater_cb(WOLFSSL_CTX* ctx, word32 maxSeq,
+                                       word32 first, word32 second,
+                                       CallbackMcastHighwater cb)
+{
+    if (ctx == NULL || (second && first > second) ||
+        first > maxSeq || second > maxSeq || cb == NULL) {
+
+        return BAD_FUNC_ARG;
+    }
+
+    ctx->mcastHwCb = cb;
+    ctx->mcastFirstSeq = first;
+    ctx->mcastSecondSeq = second;
+    ctx->mcastMaxSeq = maxSeq;
+
+    return WOLFSSL_SUCCESS;
+}
+
+
+int wolfSSL_mcast_set_highwater_ctx(WOLFSSL* ssl, void* ctx)
+{
+    if (ssl == NULL || ctx == NULL)
+        return BAD_FUNC_ARG;
+
+    ssl->mcastHwCbCtx = ctx;
+
+    return WOLFSSL_SUCCESS;
+}
+
+#endif /* WOLFSSL_DTLS */
+
+#endif /* WOLFSSL_MULTICAST */
+
+
+#endif /* WOLFSSL_LEANPSK */
+
+
+/* return underlying connect or accept, WOLFSSL_SUCCESS on ok */
+int wolfSSL_negotiate(WOLFSSL* ssl)
+{
+    int err = WOLFSSL_FATAL_ERROR;
+
+    WOLFSSL_ENTER("wolfSSL_negotiate");
+#ifndef NO_WOLFSSL_SERVER
+    if (ssl->options.side == WOLFSSL_SERVER_END) {
+#ifdef WOLFSSL_TLS13
+        if (IsAtLeastTLSv1_3(ssl->version))
+            err = wolfSSL_accept_TLSv13(ssl);
+        else
+#endif
+            err = wolfSSL_accept(ssl);
+    }
+#endif
+
+#ifndef NO_WOLFSSL_CLIENT
+    if (ssl->options.side == WOLFSSL_CLIENT_END) {
+#ifdef WOLFSSL_TLS13
+        if (IsAtLeastTLSv1_3(ssl->version))
+            err = wolfSSL_connect_TLSv13(ssl);
+        else
+#endif
+            err = wolfSSL_connect(ssl);
+    }
+#endif
+
+    (void)ssl;
+
+    WOLFSSL_LEAVE("wolfSSL_negotiate", err);
+
+    return err;
+}
+
+
+WOLFSSL_ABI
+WC_RNG* wolfSSL_GetRNG(WOLFSSL* ssl)
+{
+    if (ssl) {
+        return ssl->rng;
+    }
+
+    return NULL;
+}
+
+
+#ifndef WOLFSSL_LEANPSK
+/* object size based on build */
+int wolfSSL_GetObjectSize(void)
+{
+#ifdef SHOW_SIZES
+    printf("sizeof suites           = %lu\n", (unsigned long)sizeof(Suites));
+    printf("sizeof ciphers(2)       = %lu\n", (unsigned long)sizeof(Ciphers));
+#ifndef NO_RC4
+    printf("\tsizeof arc4         = %lu\n", (unsigned long)sizeof(Arc4));
+#endif
+    printf("\tsizeof aes          = %lu\n", (unsigned long)sizeof(Aes));
+#ifndef NO_DES3
+    printf("\tsizeof des3         = %lu\n", (unsigned long)sizeof(Des3));
+#endif
+#ifndef NO_RABBIT
+    printf("\tsizeof rabbit       = %lu\n", (unsigned long)sizeof(Rabbit));
+#endif
+#ifdef HAVE_CHACHA
+    printf("\tsizeof chacha       = %lu\n", (unsigned long)sizeof(ChaCha));
+#endif
+    printf("sizeof cipher specs     = %lu\n", (unsigned long)sizeof(CipherSpecs));
+    printf("sizeof keys             = %lu\n", (unsigned long)sizeof(Keys));
+    printf("sizeof Hashes(2)        = %lu\n", (unsigned long)sizeof(Hashes));
+#ifndef NO_MD5
+    printf("\tsizeof MD5          = %lu\n", (unsigned long)sizeof(wc_Md5));
+#endif
+#ifndef NO_SHA
+    printf("\tsizeof SHA          = %lu\n", (unsigned long)sizeof(wc_Sha));
+#endif
+#ifdef WOLFSSL_SHA224
+    printf("\tsizeof SHA224       = %lu\n", (unsigned long)sizeof(wc_Sha224));
+#endif
+#ifndef NO_SHA256
+    printf("\tsizeof SHA256       = %lu\n", (unsigned long)sizeof(wc_Sha256));
+#endif
+#ifdef WOLFSSL_SHA384
+    printf("\tsizeof SHA384       = %lu\n", (unsigned long)sizeof(wc_Sha384));
+#endif
+#ifdef WOLFSSL_SHA384
+    printf("\tsizeof SHA512       = %lu\n", (unsigned long)sizeof(wc_Sha512));
+#endif
+    printf("sizeof Buffers          = %lu\n", (unsigned long)sizeof(Buffers));
+    printf("sizeof Options          = %lu\n", (unsigned long)sizeof(Options));
+    printf("sizeof Arrays           = %lu\n", (unsigned long)sizeof(Arrays));
+#ifndef NO_RSA
+    printf("sizeof RsaKey           = %lu\n", (unsigned long)sizeof(RsaKey));
+#endif
+#ifdef HAVE_ECC
+    printf("sizeof ecc_key          = %lu\n", (unsigned long)sizeof(ecc_key));
+#endif
+    printf("sizeof WOLFSSL_CIPHER    = %lu\n", (unsigned long)sizeof(WOLFSSL_CIPHER));
+    printf("sizeof WOLFSSL_SESSION   = %lu\n", (unsigned long)sizeof(WOLFSSL_SESSION));
+    printf("sizeof WOLFSSL           = %lu\n", (unsigned long)sizeof(WOLFSSL));
+    printf("sizeof WOLFSSL_CTX       = %lu\n", (unsigned long)sizeof(WOLFSSL_CTX));
+#endif
+
+    return sizeof(WOLFSSL);
+}
+
+int wolfSSL_CTX_GetObjectSize(void)
+{
+    return sizeof(WOLFSSL_CTX);
+}
+
+int wolfSSL_METHOD_GetObjectSize(void)
+{
+    return sizeof(WOLFSSL_METHOD);
+}
+#endif
+
+
+#ifdef WOLFSSL_STATIC_MEMORY
+
+int wolfSSL_CTX_load_static_memory(WOLFSSL_CTX** ctx, wolfSSL_method_func method,
+                                   unsigned char* buf, unsigned int sz,
+                                   int flag, int max)
+{
+    WOLFSSL_HEAP*      heap;
+    WOLFSSL_HEAP_HINT* hint;
+    word32 idx = 0;
+
+    if (ctx == NULL || buf == NULL) {
+        return BAD_FUNC_ARG;
+    }
+
+    if (*ctx == NULL && method == NULL) {
+        return BAD_FUNC_ARG;
+    }
+
+    if (*ctx == NULL || (*ctx)->heap == NULL) {
+        if (sizeof(WOLFSSL_HEAP) + sizeof(WOLFSSL_HEAP_HINT) > sz - idx) {
+            return BUFFER_E; /* not enough memory for structures */
+        }
+        heap = (WOLFSSL_HEAP*)buf;
+        idx += sizeof(WOLFSSL_HEAP);
+        if (wolfSSL_init_memory_heap(heap) != 0) {
+            return WOLFSSL_FAILURE;
+        }
+        hint = (WOLFSSL_HEAP_HINT*)(buf + idx);
+        idx += sizeof(WOLFSSL_HEAP_HINT);
+        XMEMSET(hint, 0, sizeof(WOLFSSL_HEAP_HINT));
+        hint->memory = heap;
+
+        if (*ctx && (*ctx)->heap == NULL) {
+            (*ctx)->heap = (void*)hint;
+        }
+    }
+    else {
+#ifdef WOLFSSL_HEAP_TEST
+        /* do not load in memory if test has been set */
+        if ((*ctx)->heap == (void*)WOLFSSL_HEAP_TEST) {
+            return WOLFSSL_SUCCESS;
+        }
+#endif
+        hint = (WOLFSSL_HEAP_HINT*)((*ctx)->heap);
+        heap = hint->memory;
+    }
+
+    if (wolfSSL_load_static_memory(buf + idx, sz - idx, flag, heap) != 1) {
+        WOLFSSL_MSG("Error partitioning memory");
+        return WOLFSSL_FAILURE;
+    }
+
+    /* create ctx if needed */
+    if (*ctx == NULL) {
+        *ctx = wolfSSL_CTX_new_ex(method(hint), hint);
+        if (*ctx == NULL) {
+            WOLFSSL_MSG("Error creating ctx");
+            return WOLFSSL_FAILURE;
+        }
+    }
+
+    /* determine what max applies too */
+    if (flag & WOLFMEM_IO_POOL || flag & WOLFMEM_IO_POOL_FIXED) {
+        heap->maxIO = max;
+    }
+    else { /* general memory used in handshakes */
+        heap->maxHa = max;
+    }
+
+    heap->flag |= flag;
+
+    (void)max;
+    (void)method;
+
+    return WOLFSSL_SUCCESS;
+}
+
+
+int wolfSSL_is_static_memory(WOLFSSL* ssl, WOLFSSL_MEM_CONN_STATS* mem_stats)
+{
+    if (ssl == NULL) {
+        return BAD_FUNC_ARG;
+    }
+    WOLFSSL_ENTER("wolfSSL_is_static_memory");
+
+    /* fill out statistics if wanted and WOLFMEM_TRACK_STATS flag */
+    if (mem_stats != NULL && ssl->heap != NULL) {
+        WOLFSSL_HEAP_HINT* hint = ((WOLFSSL_HEAP_HINT*)(ssl->heap));
+        WOLFSSL_HEAP* heap      = hint->memory;
+        if (heap->flag & WOLFMEM_TRACK_STATS && hint->stats != NULL) {
+            XMEMCPY(mem_stats, hint->stats, sizeof(WOLFSSL_MEM_CONN_STATS));
+        }
+    }
+
+    return (ssl->heap) ? 1 : 0;
+}
+
+
+int wolfSSL_CTX_is_static_memory(WOLFSSL_CTX* ctx, WOLFSSL_MEM_STATS* mem_stats)
+{
+    if (ctx == NULL) {
+        return BAD_FUNC_ARG;
+    }
+    WOLFSSL_ENTER("wolfSSL_CTX_is_static_memory");
+
+    /* fill out statistics if wanted */
+    if (mem_stats != NULL && ctx->heap != NULL) {
+        WOLFSSL_HEAP* heap = ((WOLFSSL_HEAP_HINT*)(ctx->heap))->memory;
+        if (wolfSSL_GetMemStats(heap, mem_stats) != 1) {
+            return MEMORY_E;
+        }
+    }
+
+    return (ctx->heap) ? 1 : 0;
+}
+
+#endif /* WOLFSSL_STATIC_MEMORY */
+
+
+/* return max record layer size plaintext input size */
+int wolfSSL_GetMaxOutputSize(WOLFSSL* ssl)
+{
+    WOLFSSL_ENTER("wolfSSL_GetMaxOutputSize");
+
+    if (ssl == NULL)
+        return BAD_FUNC_ARG;
+
+    if (ssl->options.handShakeState != HANDSHAKE_DONE) {
+        WOLFSSL_MSG("Handshake not complete yet");
+        return BAD_FUNC_ARG;
+    }
+
+    return wolfSSL_GetMaxRecordSize(ssl, OUTPUT_RECORD_SIZE);
+}
+
+
+/* return record layer size of plaintext input size */
+int wolfSSL_GetOutputSize(WOLFSSL* ssl, int inSz)
+{
+    int maxSize;
+
+    WOLFSSL_ENTER("wolfSSL_GetOutputSize");
+
+    if (inSz < 0)
+        return BAD_FUNC_ARG;
+
+    maxSize = wolfSSL_GetMaxOutputSize(ssl);
+    if (maxSize < 0)
+        return maxSize;   /* error */
+    if (inSz > maxSize)
+        return INPUT_SIZE_E;
+
+    return BuildMessage(ssl, NULL, 0, NULL, inSz, application_data, 0, 1, 0);
+}
+
+
+#ifdef HAVE_ECC
+int wolfSSL_CTX_SetMinEccKey_Sz(WOLFSSL_CTX* ctx, short keySz)
+{
+    if (ctx == NULL || keySz < 0 || keySz % 8 != 0) {
+        WOLFSSL_MSG("Key size must be divisible by 8 or ctx was null");
+        return BAD_FUNC_ARG;
+    }
+
+    ctx->minEccKeySz     = keySz / 8;
+#ifndef NO_CERTS
+    ctx->cm->minEccKeySz = keySz / 8;
+#endif
+    return WOLFSSL_SUCCESS;
+}
+
+
+int wolfSSL_SetMinEccKey_Sz(WOLFSSL* ssl, short keySz)
+{
+    if (ssl == NULL || keySz < 0 || keySz % 8 != 0) {
+        WOLFSSL_MSG("Key size must be divisible by 8 or ssl was null");
+        return BAD_FUNC_ARG;
+    }
+
+    ssl->options.minEccKeySz = keySz / 8;
+    return WOLFSSL_SUCCESS;
+}
+
+#endif /* !NO_RSA */
+
+#ifndef NO_RSA
+int wolfSSL_CTX_SetMinRsaKey_Sz(WOLFSSL_CTX* ctx, short keySz)
+{
+    if (ctx == NULL || keySz < 0 || keySz % 8 != 0) {
+        WOLFSSL_MSG("Key size must be divisible by 8 or ctx was null");
+        return BAD_FUNC_ARG;
+    }
+
+    ctx->minRsaKeySz     = keySz / 8;
+    ctx->cm->minRsaKeySz = keySz / 8;
+    return WOLFSSL_SUCCESS;
+}
+
+
+int wolfSSL_SetMinRsaKey_Sz(WOLFSSL* ssl, short keySz)
+{
+    if (ssl == NULL || keySz < 0 || keySz % 8 != 0) {
+        WOLFSSL_MSG("Key size must be divisible by 8 or ssl was null");
+        return BAD_FUNC_ARG;
+    }
+
+    ssl->options.minRsaKeySz = keySz / 8;
+    return WOLFSSL_SUCCESS;
+}
+#endif /* !NO_RSA */
+
+#ifndef NO_DH
+/* server Diffie-Hellman parameters, WOLFSSL_SUCCESS on ok */
+int wolfSSL_SetTmpDH(WOLFSSL* ssl, const unsigned char* p, int pSz,
+                    const unsigned char* g, int gSz)
+{
+    WOLFSSL_ENTER("wolfSSL_SetTmpDH");
+
+    if (ssl == NULL || p == NULL || g == NULL)
+        return BAD_FUNC_ARG;
+
+    if ((word16)pSz < ssl->options.minDhKeySz)
+        return DH_KEY_SIZE_E;
+    if ((word16)pSz > ssl->options.maxDhKeySz)
+        return DH_KEY_SIZE_E;
+
+    /* this function is for server only */
+    if (ssl->options.side == WOLFSSL_CLIENT_END)
+        return SIDE_ERROR;
+
+    #if !defined(WOLFSSL_OLD_PRIME_CHECK) && !defined(HAVE_FIPS) && \
+        !defined(HAVE_SELFTEST)
+        ssl->options.dhKeyTested = 0;
+        ssl->options.dhDoKeyTest = 1;
+    #endif
+
+    if (ssl->buffers.serverDH_P.buffer && ssl->buffers.weOwnDH) {
+        XFREE(ssl->buffers.serverDH_P.buffer, ssl->heap, DYNAMIC_TYPE_PUBLIC_KEY);
+        ssl->buffers.serverDH_P.buffer = NULL;
+    }
+    if (ssl->buffers.serverDH_G.buffer && ssl->buffers.weOwnDH) {
+        XFREE(ssl->buffers.serverDH_G.buffer, ssl->heap, DYNAMIC_TYPE_PUBLIC_KEY);
+        ssl->buffers.serverDH_G.buffer = NULL;
+    }
+
+    ssl->buffers.weOwnDH = 1;  /* SSL owns now */
+    ssl->buffers.serverDH_P.buffer = (byte*)XMALLOC(pSz, ssl->heap,
+                                                    DYNAMIC_TYPE_PUBLIC_KEY);
+    if (ssl->buffers.serverDH_P.buffer == NULL)
+            return MEMORY_E;
+
+    ssl->buffers.serverDH_G.buffer = (byte*)XMALLOC(gSz, ssl->heap,
+                                                    DYNAMIC_TYPE_PUBLIC_KEY);
+    if (ssl->buffers.serverDH_G.buffer == NULL) {
+        XFREE(ssl->buffers.serverDH_P.buffer, ssl->heap, DYNAMIC_TYPE_PUBLIC_KEY);
+        ssl->buffers.serverDH_P.buffer = NULL;
+        return MEMORY_E;
+    }
+
+    ssl->buffers.serverDH_P.length = pSz;
+    ssl->buffers.serverDH_G.length = gSz;
+
+    XMEMCPY(ssl->buffers.serverDH_P.buffer, p, pSz);
+    XMEMCPY(ssl->buffers.serverDH_G.buffer, g, gSz);
+
+    ssl->options.haveDH = 1;
+
+    if (ssl->options.side != WOLFSSL_NEITHER_END) {
+        word16 havePSK;
+        word16 haveRSA;
+        int    keySz   = 0;
+
+    #ifndef NO_PSK
+        havePSK = ssl->options.havePSK;
+    #else
+        havePSK = 0;
+    #endif
+    #ifdef NO_RSA
+        haveRSA = 0;
+    #else
+        haveRSA = 1;
+    #endif
+    #ifndef NO_CERTS
+        keySz = ssl->buffers.keySz;
+    #endif
+        InitSuites(ssl->suites, ssl->version, keySz, haveRSA, havePSK,
+                   ssl->options.haveDH, ssl->options.haveNTRU,
+                   ssl->options.haveECDSAsig, ssl->options.haveECC,
+                   ssl->options.haveStaticECC, ssl->options.side);
+    }
+
+    WOLFSSL_LEAVE("wolfSSL_SetTmpDH", 0);
+
+    return WOLFSSL_SUCCESS;
+}
+
+
+#if !defined(WOLFSSL_OLD_PRIME_CHECK) && !defined(HAVE_FIPS) && \
+    !defined(HAVE_SELFTEST)
+/* Enables or disables the session's DH key prime test. */
+int wolfSSL_SetEnableDhKeyTest(WOLFSSL* ssl, int enable)
+{
+    WOLFSSL_ENTER("wolfSSL_SetEnableDhKeyTest");
+
+    if (ssl == NULL)
+        return BAD_FUNC_ARG;
+
+    if (!enable)
+        ssl->options.dhDoKeyTest = 0;
+    else
+        ssl->options.dhDoKeyTest = 1;
+
+    WOLFSSL_LEAVE("wolfSSL_SetEnableDhKeyTest", WOLFSSL_SUCCESS);
+    return WOLFSSL_SUCCESS;
+}
+#endif
+
+
+/* server ctx Diffie-Hellman parameters, WOLFSSL_SUCCESS on ok */
+int wolfSSL_CTX_SetTmpDH(WOLFSSL_CTX* ctx, const unsigned char* p, int pSz,
+                         const unsigned char* g, int gSz)
+{
+    WOLFSSL_ENTER("wolfSSL_CTX_SetTmpDH");
+    if (ctx == NULL || p == NULL || g == NULL) return BAD_FUNC_ARG;
+
+    if ((word16)pSz < ctx->minDhKeySz)
+        return DH_KEY_SIZE_E;
+    if ((word16)pSz > ctx->maxDhKeySz)
+        return DH_KEY_SIZE_E;
+
+    #if !defined(WOLFSSL_OLD_PRIME_CHECK) && !defined(HAVE_FIPS) && \
+        !defined(HAVE_SELFTEST)
+    {
+        DhKey checkKey;
+        WC_RNG rng;
+        int error, freeKey = 0;
+
+        error = wc_InitRng(&rng);
+        if (!error)
+            error = wc_InitDhKey(&checkKey);
+        if (!error) {
+            freeKey = 1;
+            error = wc_DhSetCheckKey(&checkKey,
+                                 p, pSz, g, gSz, NULL, 0, 0, &rng);
+        }
+        if (freeKey)
+            wc_FreeDhKey(&checkKey);
+        wc_FreeRng(&rng);
+        if (error)
+            return error;
+
+        ctx->dhKeyTested = 1;
+    }
+    #endif
+
+    XFREE(ctx->serverDH_P.buffer, ctx->heap, DYNAMIC_TYPE_PUBLIC_KEY);
+    ctx->serverDH_P.buffer = NULL;
+    XFREE(ctx->serverDH_G.buffer, ctx->heap, DYNAMIC_TYPE_PUBLIC_KEY);
+    ctx->serverDH_G.buffer = NULL;
+
+    ctx->serverDH_P.buffer = (byte*)XMALLOC(pSz, ctx->heap, DYNAMIC_TYPE_PUBLIC_KEY);
+    if (ctx->serverDH_P.buffer == NULL)
+       return MEMORY_E;
+
+    ctx->serverDH_G.buffer = (byte*)XMALLOC(gSz, ctx->heap, DYNAMIC_TYPE_PUBLIC_KEY);
+    if (ctx->serverDH_G.buffer == NULL) {
+        XFREE(ctx->serverDH_P.buffer, ctx->heap, DYNAMIC_TYPE_PUBLIC_KEY);
+        ctx->serverDH_P.buffer = NULL;
+        return MEMORY_E;
+    }
+
+    ctx->serverDH_P.length = pSz;
+    ctx->serverDH_G.length = gSz;
+
+    XMEMCPY(ctx->serverDH_P.buffer, p, pSz);
+    XMEMCPY(ctx->serverDH_G.buffer, g, gSz);
+
+    ctx->haveDH = 1;
+
+    WOLFSSL_LEAVE("wolfSSL_CTX_SetTmpDH", 0);
+    return WOLFSSL_SUCCESS;
+}
+
+
+int wolfSSL_CTX_SetMinDhKey_Sz(WOLFSSL_CTX* ctx, word16 keySz)
+{
+    if (ctx == NULL || keySz > 16000 || keySz % 8 != 0)
+        return BAD_FUNC_ARG;
+
+    ctx->minDhKeySz = keySz / 8;
+    return WOLFSSL_SUCCESS;
+}
+
+
+int wolfSSL_SetMinDhKey_Sz(WOLFSSL* ssl, word16 keySz)
+{
+    if (ssl == NULL || keySz > 16000 || keySz % 8 != 0)
+        return BAD_FUNC_ARG;
+
+    ssl->options.minDhKeySz = keySz / 8;
+    return WOLFSSL_SUCCESS;
+}
+
+
+int wolfSSL_CTX_SetMaxDhKey_Sz(WOLFSSL_CTX* ctx, word16 keySz)
+{
+    if (ctx == NULL || keySz > 16000 || keySz % 8 != 0)
+        return BAD_FUNC_ARG;
+
+    ctx->maxDhKeySz = keySz / 8;
+    return WOLFSSL_SUCCESS;
+}
+
+
+int wolfSSL_SetMaxDhKey_Sz(WOLFSSL* ssl, word16 keySz)
+{
+    if (ssl == NULL || keySz > 16000 || keySz % 8 != 0)
+        return BAD_FUNC_ARG;
+
+    ssl->options.maxDhKeySz = keySz / 8;
+    return WOLFSSL_SUCCESS;
+}
+
+
+int wolfSSL_GetDhKey_Sz(WOLFSSL* ssl)
+{
+    if (ssl == NULL)
+        return BAD_FUNC_ARG;
+
+    return (ssl->options.dhKeySz * 8);
+}
+
+#endif /* !NO_DH */
+
+
+WOLFSSL_ABI
+int wolfSSL_write(WOLFSSL* ssl, const void* data, int sz)
+{
+    int ret;
+
+    WOLFSSL_ENTER("SSL_write()");
+
+    if (ssl == NULL || data == NULL || sz < 0)
+        return BAD_FUNC_ARG;
+
+#ifdef WOLFSSL_EARLY_DATA
+    if (ssl->earlyData != no_early_data && (ret = wolfSSL_negotiate(ssl)) < 0) {
+        ssl->error = ret;
+        return WOLFSSL_FATAL_ERROR;
+    }
+    ssl->earlyData = no_early_data;
+#endif
+
+#ifdef HAVE_WRITE_DUP
+    { /* local variable scope */
+        int dupErr = 0;   /* local copy */
+
+        ret = 0;
+
+        if (ssl->dupWrite && ssl->dupSide == READ_DUP_SIDE) {
+            WOLFSSL_MSG("Read dup side cannot write");
+            return WRITE_DUP_WRITE_E;
+        }
+        if (ssl->dupWrite) {
+            if (wc_LockMutex(&ssl->dupWrite->dupMutex) != 0) {
+                return BAD_MUTEX_E;
+            }
+            dupErr = ssl->dupWrite->dupErr;
+            ret = wc_UnLockMutex(&ssl->dupWrite->dupMutex);
+        }
+
+        if (ret != 0) {
+            ssl->error = ret;  /* high priority fatal error */
+            return WOLFSSL_FATAL_ERROR;
+        }
+        if (dupErr != 0) {
+            WOLFSSL_MSG("Write dup error from other side");
+            ssl->error = dupErr;
+            return WOLFSSL_FATAL_ERROR;
+        }
+    }
+#endif
+
+#ifdef HAVE_ERRNO_H
+    errno = 0;
+#endif
+
+    #ifdef OPENSSL_EXTRA
+    if (ssl->CBIS != NULL) {
+        ssl->CBIS(ssl, SSL_CB_WRITE, SSL_SUCCESS);
+        ssl->cbmode = SSL_CB_WRITE;
+    }
+    #endif
+    ret = SendData(ssl, data, sz);
+
+    WOLFSSL_LEAVE("SSL_write()", ret);
+
+    if (ret < 0)
+        return WOLFSSL_FATAL_ERROR;
+    else
+        return ret;
+}
+
+static int wolfSSL_read_internal(WOLFSSL* ssl, void* data, int sz, int peek)
+{
+    int ret;
+
+    WOLFSSL_ENTER("wolfSSL_read_internal()");
+
+    if (ssl == NULL || data == NULL || sz < 0)
+        return BAD_FUNC_ARG;
+
+#ifdef HAVE_WRITE_DUP
+    if (ssl->dupWrite && ssl->dupSide == WRITE_DUP_SIDE) {
+        WOLFSSL_MSG("Write dup side cannot read");
+        return WRITE_DUP_READ_E;
+    }
+#endif
+
+#ifdef HAVE_ERRNO_H
+        errno = 0;
+#endif
+
+#ifdef WOLFSSL_DTLS
+    if (ssl->options.dtls) {
+        ssl->dtls_expected_rx = max(sz + 100, MAX_MTU);
+#ifdef WOLFSSL_SCTP
+        if (ssl->options.dtlsSctp)
+#endif
+#if defined(WOLLSSL_SCTP) || defined(WOLFSSL_DTLS_MTU)
+            ssl->dtls_expected_rx = max(ssl->dtls_expected_rx, ssl->dtlsMtuSz);
+#endif
+    }
+#endif
+
+    sz = wolfSSL_GetMaxRecordSize(ssl, sz);
+
+    ret = ReceiveData(ssl, (byte*)data, sz, peek);
+
+#ifdef HAVE_WRITE_DUP
+    if (ssl->dupWrite) {
+        if (ssl->error != 0 && ssl->error != WANT_READ
+        #ifdef WOLFSSL_ASYNC_CRYPT
+            && ssl->error != WC_PENDING_E
+        #endif
+        ) {
+            int notifyErr;
+
+            WOLFSSL_MSG("Notifying write side of fatal read error");
+            notifyErr  = NotifyWriteSide(ssl, ssl->error);
+            if (notifyErr < 0) {
+                ret = ssl->error = notifyErr;
+            }
+        }
+    }
+#endif
+
+    WOLFSSL_LEAVE("wolfSSL_read_internal()", ret);
+
+    if (ret < 0)
+        return WOLFSSL_FATAL_ERROR;
+    else
+        return ret;
+}
+
+
+int wolfSSL_peek(WOLFSSL* ssl, void* data, int sz)
+{
+    WOLFSSL_ENTER("wolfSSL_peek()");
+
+    return wolfSSL_read_internal(ssl, data, sz, TRUE);
+}
+
+
+WOLFSSL_ABI
+int wolfSSL_read(WOLFSSL* ssl, void* data, int sz)
+{
+    WOLFSSL_ENTER("wolfSSL_read()");
+
+    #ifdef OPENSSL_EXTRA
+    if (ssl->CBIS != NULL) {
+        ssl->CBIS(ssl, SSL_CB_READ, SSL_SUCCESS);
+        ssl->cbmode = SSL_CB_READ;
+    }
+    #endif
+    return wolfSSL_read_internal(ssl, data, sz, FALSE);
+}
+
+
+#ifdef WOLFSSL_MULTICAST
+
+int wolfSSL_mcast_read(WOLFSSL* ssl, word16* id, void* data, int sz)
+{
+    int ret = 0;
+
+    WOLFSSL_ENTER("wolfSSL_mcast_read()");
+
+    if (ssl == NULL)
+        return BAD_FUNC_ARG;
+
+    ret = wolfSSL_read_internal(ssl, data, sz, FALSE);
+    if (ssl->options.dtls && ssl->options.haveMcast && id != NULL)
+        *id = ssl->keys.curPeerId;
+    return ret;
+}
+
+#endif /* WOLFSSL_MULTICAST */
+
+
+/* helpers to set the device id, WOLFSSL_SUCCESS on ok */
+WOLFSSL_ABI
+int wolfSSL_SetDevId(WOLFSSL* ssl, int devId)
+{
+    if (ssl == NULL)
+        return BAD_FUNC_ARG;
+
+    ssl->devId = devId;
+
+    return WOLFSSL_SUCCESS;
+}
+
+WOLFSSL_ABI
+int wolfSSL_CTX_SetDevId(WOLFSSL_CTX* ctx, int devId)
+{
+    if (ctx == NULL)
+        return BAD_FUNC_ARG;
+
+    ctx->devId = devId;
+
+    return WOLFSSL_SUCCESS;
+}
+
+/* helpers to get device id and heap */
+WOLFSSL_ABI
+int wolfSSL_CTX_GetDevId(WOLFSSL_CTX* ctx, WOLFSSL* ssl)
+{
+    int devId = INVALID_DEVID;
+    if (ctx != NULL)
+        devId = ctx->devId;
+    else if (ssl != NULL)
+        devId = ssl->devId;
+    return devId;
+}
+void* wolfSSL_CTX_GetHeap(WOLFSSL_CTX* ctx, WOLFSSL* ssl)
+{
+    void* heap = NULL;
+    if (ctx != NULL)
+        heap = ctx->heap;
+    else if (ssl != NULL)
+        heap = ssl->heap;
+    return heap;
+}
+
+
+#ifdef HAVE_SNI
+
+WOLFSSL_ABI
+int wolfSSL_UseSNI(WOLFSSL* ssl, byte type, const void* data, word16 size)
+{
+    if (ssl == NULL)
+        return BAD_FUNC_ARG;
+
+    return TLSX_UseSNI(&ssl->extensions, type, data, size, ssl->heap);
+}
+
+
+WOLFSSL_ABI
+int wolfSSL_CTX_UseSNI(WOLFSSL_CTX* ctx, byte type, const void* data,
+                                                                    word16 size)
+{
+    if (ctx == NULL)
+        return BAD_FUNC_ARG;
+
+    return TLSX_UseSNI(&ctx->extensions, type, data, size, ctx->heap);
+}
+
+#ifndef NO_WOLFSSL_SERVER
+
+void wolfSSL_SNI_SetOptions(WOLFSSL* ssl, byte type, byte options)
+{
+    if (ssl && ssl->extensions)
+        TLSX_SNI_SetOptions(ssl->extensions, type, options);
+}
+
+
+void wolfSSL_CTX_SNI_SetOptions(WOLFSSL_CTX* ctx, byte type, byte options)
+{
+    if (ctx && ctx->extensions)
+        TLSX_SNI_SetOptions(ctx->extensions, type, options);
+}
+
+
+byte wolfSSL_SNI_Status(WOLFSSL* ssl, byte type)
+{
+    return TLSX_SNI_Status(ssl ? ssl->extensions : NULL, type);
+}
+
+
+word16 wolfSSL_SNI_GetRequest(WOLFSSL* ssl, byte type, void** data)
+{
+    if (data)
+        *data = NULL;
+
+    if (ssl && ssl->extensions)
+        return TLSX_SNI_GetRequest(ssl->extensions, type, data);
+
+    return 0;
+}
+
+
+int wolfSSL_SNI_GetFromBuffer(const byte* clientHello, word32 helloSz,
+                              byte type, byte* sni, word32* inOutSz)
+{
+    if (clientHello && helloSz > 0 && sni && inOutSz && *inOutSz > 0)
+        return TLSX_SNI_GetFromBuffer(clientHello, helloSz, type, sni, inOutSz);
+
+    return BAD_FUNC_ARG;
+}
+
+#endif /* NO_WOLFSSL_SERVER */
+
+#endif /* HAVE_SNI */
+
+
+#ifdef HAVE_TRUSTED_CA
+
+WOLFSSL_API int wolfSSL_UseTrustedCA(WOLFSSL* ssl, byte type,
+            const byte* certId, word32 certIdSz)
+{
+    if (ssl == NULL)
+        return BAD_FUNC_ARG;
+
+    if (type == WOLFSSL_TRUSTED_CA_PRE_AGREED) {
+        if (certId != NULL || certIdSz != 0)
+            return BAD_FUNC_ARG;
+    }
+    else if (type == WOLFSSL_TRUSTED_CA_X509_NAME) {
+        if (certId == NULL || certIdSz == 0)
+            return BAD_FUNC_ARG;
+    }
+    #ifndef NO_SHA
+    else if (type == WOLFSSL_TRUSTED_CA_KEY_SHA1 ||
+            type == WOLFSSL_TRUSTED_CA_CERT_SHA1) {
+        if (certId == NULL || certIdSz != WC_SHA_DIGEST_SIZE)
+            return BAD_FUNC_ARG;
+    }
+    #endif
+    else
+        return BAD_FUNC_ARG;
+
+    return TLSX_UseTrustedCA(&ssl->extensions,
+            type, certId, certIdSz, ssl->heap);
+}
+
+#endif /* HAVE_TRUSTED_CA */
+
+
+#ifdef HAVE_MAX_FRAGMENT
+#ifndef NO_WOLFSSL_CLIENT
+
+int wolfSSL_UseMaxFragment(WOLFSSL* ssl, byte mfl)
+{
+    if (ssl == NULL)
+        return BAD_FUNC_ARG;
+
+#ifdef WOLFSSL_ALLOW_MAX_FRAGMENT_ADJUST
+    /* The following is a non-standard way to reconfigure the max packet size
+        post-handshake for wolfSSL_write/woflSSL_read */
+    if (ssl->options.handShakeState == HANDSHAKE_DONE) {
+        switch (mfl) {
+            case WOLFSSL_MFL_2_8 : ssl->max_fragment =  256; break;
+            case WOLFSSL_MFL_2_9 : ssl->max_fragment =  512; break;
+            case WOLFSSL_MFL_2_10: ssl->max_fragment = 1024; break;
+            case WOLFSSL_MFL_2_11: ssl->max_fragment = 2048; break;
+            case WOLFSSL_MFL_2_12: ssl->max_fragment = 4096; break;
+            case WOLFSSL_MFL_2_13: ssl->max_fragment = 8192; break;
+            default: ssl->max_fragment = MAX_RECORD_SIZE; break;
+        }
+        return WOLFSSL_SUCCESS;
+    }
+#endif /* WOLFSSL_MAX_FRAGMENT_ADJUST */
+
+    /* This call sets the max fragment TLS extension, which gets sent to server.
+        The server_hello response is what sets the `ssl->max_fragment` in
+        TLSX_MFL_Parse */
+    return TLSX_UseMaxFragment(&ssl->extensions, mfl, ssl->heap);
+}
+
+
+int wolfSSL_CTX_UseMaxFragment(WOLFSSL_CTX* ctx, byte mfl)
+{
+    if (ctx == NULL)
+        return BAD_FUNC_ARG;
+
+    return TLSX_UseMaxFragment(&ctx->extensions, mfl, ctx->heap);
+}
+
+#endif /* NO_WOLFSSL_CLIENT */
+#endif /* HAVE_MAX_FRAGMENT */
+
+#ifdef HAVE_TRUNCATED_HMAC
+#ifndef NO_WOLFSSL_CLIENT
+
+int wolfSSL_UseTruncatedHMAC(WOLFSSL* ssl)
+{
+    if (ssl == NULL)
+        return BAD_FUNC_ARG;
+
+    return TLSX_UseTruncatedHMAC(&ssl->extensions, ssl->heap);
+}
+
+
+int wolfSSL_CTX_UseTruncatedHMAC(WOLFSSL_CTX* ctx)
+{
+    if (ctx == NULL)
+        return BAD_FUNC_ARG;
+
+    return TLSX_UseTruncatedHMAC(&ctx->extensions, ctx->heap);
+}
+
+#endif /* NO_WOLFSSL_CLIENT */
+#endif /* HAVE_TRUNCATED_HMAC */
+
+#ifdef HAVE_CERTIFICATE_STATUS_REQUEST
+
+int wolfSSL_UseOCSPStapling(WOLFSSL* ssl, byte status_type, byte options)
+{
+    if (ssl == NULL || ssl->options.side != WOLFSSL_CLIENT_END)
+        return BAD_FUNC_ARG;
+
+    return TLSX_UseCertificateStatusRequest(&ssl->extensions, status_type,
+                                          options, NULL, ssl->heap, ssl->devId);
+}
+
+
+int wolfSSL_CTX_UseOCSPStapling(WOLFSSL_CTX* ctx, byte status_type,
+                                                                   byte options)
+{
+    if (ctx == NULL || ctx->method->side != WOLFSSL_CLIENT_END)
+        return BAD_FUNC_ARG;
+
+    return TLSX_UseCertificateStatusRequest(&ctx->extensions, status_type,
+                                          options, NULL, ctx->heap, ctx->devId);
+}
+
+#endif /* HAVE_CERTIFICATE_STATUS_REQUEST */
+
+#ifdef HAVE_CERTIFICATE_STATUS_REQUEST_V2
+
+int wolfSSL_UseOCSPStaplingV2(WOLFSSL* ssl, byte status_type, byte options)
+{
+    if (ssl == NULL || ssl->options.side != WOLFSSL_CLIENT_END)
+        return BAD_FUNC_ARG;
+
+    return TLSX_UseCertificateStatusRequestV2(&ssl->extensions, status_type,
+                                                options, ssl->heap, ssl->devId);
+}
+
+
+int wolfSSL_CTX_UseOCSPStaplingV2(WOLFSSL_CTX* ctx, byte status_type,
+                                                                   byte options)
+{
+    if (ctx == NULL || ctx->method->side != WOLFSSL_CLIENT_END)
+        return BAD_FUNC_ARG;
+
+    return TLSX_UseCertificateStatusRequestV2(&ctx->extensions, status_type,
+                                                options, ctx->heap, ctx->devId);
+}
+
+#endif /* HAVE_CERTIFICATE_STATUS_REQUEST_V2 */
+
+/* Elliptic Curves */
+#if defined(HAVE_SUPPORTED_CURVES) && !defined(NO_WOLFSSL_CLIENT)
+
+int wolfSSL_UseSupportedCurve(WOLFSSL* ssl, word16 name)
+{
+    if (ssl == NULL)
+        return BAD_FUNC_ARG;
+
+    switch (name) {
+        case WOLFSSL_ECC_SECP160K1:
+        case WOLFSSL_ECC_SECP160R1:
+        case WOLFSSL_ECC_SECP160R2:
+        case WOLFSSL_ECC_SECP192K1:
+        case WOLFSSL_ECC_SECP192R1:
+        case WOLFSSL_ECC_SECP224K1:
+        case WOLFSSL_ECC_SECP224R1:
+        case WOLFSSL_ECC_SECP256K1:
+        case WOLFSSL_ECC_SECP256R1:
+        case WOLFSSL_ECC_SECP384R1:
+        case WOLFSSL_ECC_SECP521R1:
+        case WOLFSSL_ECC_BRAINPOOLP256R1:
+        case WOLFSSL_ECC_BRAINPOOLP384R1:
+        case WOLFSSL_ECC_BRAINPOOLP512R1:
+        case WOLFSSL_ECC_X25519:
+        case WOLFSSL_ECC_X448:
+
+        case WOLFSSL_FFDHE_2048:
+        case WOLFSSL_FFDHE_3072:
+        case WOLFSSL_FFDHE_4096:
+        case WOLFSSL_FFDHE_6144:
+        case WOLFSSL_FFDHE_8192:
+            break;
+
+        default:
+            return BAD_FUNC_ARG;
+    }
+
+    ssl->options.userCurves = 1;
+
+    return TLSX_UseSupportedCurve(&ssl->extensions, name, ssl->heap);
+}
+
+
+int wolfSSL_CTX_UseSupportedCurve(WOLFSSL_CTX* ctx, word16 name)
+{
+    if (ctx == NULL)
+        return BAD_FUNC_ARG;
+
+    switch (name) {
+        case WOLFSSL_ECC_SECP160K1:
+        case WOLFSSL_ECC_SECP160R1:
+        case WOLFSSL_ECC_SECP160R2:
+        case WOLFSSL_ECC_SECP192K1:
+        case WOLFSSL_ECC_SECP192R1:
+        case WOLFSSL_ECC_SECP224K1:
+        case WOLFSSL_ECC_SECP224R1:
+        case WOLFSSL_ECC_SECP256K1:
+        case WOLFSSL_ECC_SECP256R1:
+        case WOLFSSL_ECC_SECP384R1:
+        case WOLFSSL_ECC_SECP521R1:
+        case WOLFSSL_ECC_BRAINPOOLP256R1:
+        case WOLFSSL_ECC_BRAINPOOLP384R1:
+        case WOLFSSL_ECC_BRAINPOOLP512R1:
+        case WOLFSSL_ECC_X25519:
+        case WOLFSSL_ECC_X448:
+        case WOLFSSL_FFDHE_2048:
+        case WOLFSSL_FFDHE_3072:
+        case WOLFSSL_FFDHE_4096:
+        case WOLFSSL_FFDHE_6144:
+        case WOLFSSL_FFDHE_8192:
+            break;
+
+        default:
+            return BAD_FUNC_ARG;
+    }
+
+    ctx->userCurves = 1;
+
+    return TLSX_UseSupportedCurve(&ctx->extensions, name, ctx->heap);
+}
+
+#endif /* HAVE_SUPPORTED_CURVES && !NO_WOLFSSL_CLIENT */
+
+/* QSH quantum safe handshake */
+#ifdef HAVE_QSH
+/* returns 1 if QSH has been used 0 otherwise */
+int wolfSSL_isQSH(WOLFSSL* ssl)
+{
+    /* if no ssl struct than QSH was not used */
+    if (ssl == NULL)
+        return 0;
+
+    return ssl->isQSH;
+}
+
+
+int wolfSSL_UseSupportedQSH(WOLFSSL* ssl, word16 name)
+{
+    if (ssl == NULL)
+        return BAD_FUNC_ARG;
+
+    switch (name) {
+    #ifdef HAVE_NTRU
+        case WOLFSSL_NTRU_EESS439:
+        case WOLFSSL_NTRU_EESS593:
+        case WOLFSSL_NTRU_EESS743:
+            break;
+    #endif
+        default:
+            return BAD_FUNC_ARG;
+    }
+
+    ssl->user_set_QSHSchemes = 1;
+
+    return TLSX_UseQSHScheme(&ssl->extensions, name, NULL, 0, ssl->heap);
+}
+
+#ifndef NO_WOLFSSL_CLIENT
+    /* user control over sending client public key in hello
+       when flag = 1 will send keys if flag is 0 or function is not called
+       then will not send keys in the hello extension
+       return 0 on success
+     */
+    int wolfSSL_UseClientQSHKeys(WOLFSSL* ssl, unsigned char flag)
+    {
+        if (ssl == NULL)
+            return BAD_FUNC_ARG;
+
+        ssl->sendQSHKeys = flag;
+
+        return 0;
+    }
+#endif /* NO_WOLFSSL_CLIENT */
+#endif /* HAVE_QSH */
+
+/* Application-Layer Protocol Negotiation */
+#ifdef HAVE_ALPN
+
+WOLFSSL_ABI
+int wolfSSL_UseALPN(WOLFSSL* ssl, char *protocol_name_list,
+                    word32 protocol_name_listSz, byte options)
+{
+    char    *list, *ptr, *token[WOLFSSL_MAX_ALPN_NUMBER]={NULL};
+    word16  len;
+    int     idx = 0;
+    int     ret = WOLFSSL_FAILURE;
+
+    WOLFSSL_ENTER("wolfSSL_UseALPN");
+
+    if (ssl == NULL || protocol_name_list == NULL)
+        return BAD_FUNC_ARG;
+
+    if (protocol_name_listSz > (WOLFSSL_MAX_ALPN_NUMBER *
+                                WOLFSSL_MAX_ALPN_PROTO_NAME_LEN +
+                                WOLFSSL_MAX_ALPN_NUMBER)) {
+        WOLFSSL_MSG("Invalid arguments, protocol name list too long");
+        return BAD_FUNC_ARG;
+    }
+
+    if (!(options & WOLFSSL_ALPN_CONTINUE_ON_MISMATCH) &&
+        !(options & WOLFSSL_ALPN_FAILED_ON_MISMATCH)) {
+            WOLFSSL_MSG("Invalid arguments, options not supported");
+            return BAD_FUNC_ARG;
+        }
+
+
+    list = (char *)XMALLOC(protocol_name_listSz+1, ssl->heap,
+                           DYNAMIC_TYPE_ALPN);
+    if (list == NULL) {
+        WOLFSSL_MSG("Memory failure");
+        return MEMORY_ERROR;
+    }
+
+    XSTRNCPY(list, protocol_name_list, protocol_name_listSz);
+    list[protocol_name_listSz] = '\0';
+
+    /* read all protocol name from the list */
+    token[idx] = XSTRTOK(list, ",", &ptr);
+    while (idx < WOLFSSL_MAX_ALPN_NUMBER && token[idx] != NULL)
+        token[++idx] = XSTRTOK(NULL, ",", &ptr);
+
+    /* add protocol name list in the TLS extension in reverse order */
+    while ((idx--) > 0) {
+        len = (word16)XSTRLEN(token[idx]);
+
+        ret = TLSX_UseALPN(&ssl->extensions, token[idx], len, options,
+                                                                     ssl->heap);
+        if (ret != WOLFSSL_SUCCESS) {
+            WOLFSSL_MSG("TLSX_UseALPN failure");
+            break;
+        }
+    }
+
+    XFREE(list, ssl->heap, DYNAMIC_TYPE_ALPN);
+
+    return ret;
+}
+
+int wolfSSL_ALPN_GetProtocol(WOLFSSL* ssl, char **protocol_name, word16 *size)
+{
+    return TLSX_ALPN_GetRequest(ssl ? ssl->extensions : NULL,
+                               (void **)protocol_name, size);
+}
+
+int wolfSSL_ALPN_GetPeerProtocol(WOLFSSL* ssl, char **list, word16 *listSz)
+{
+    if (list == NULL || listSz == NULL)
+        return BAD_FUNC_ARG;
+
+    if (ssl->alpn_client_list == NULL)
+        return BUFFER_ERROR;
+
+    *listSz = (word16)XSTRLEN(ssl->alpn_client_list);
+    if (*listSz == 0)
+        return BUFFER_ERROR;
+
+    *list = (char *)XMALLOC((*listSz)+1, ssl->heap, DYNAMIC_TYPE_TLSX);
+    if (*list == NULL)
+        return MEMORY_ERROR;
+
+    XSTRNCPY(*list, ssl->alpn_client_list, (*listSz)+1);
+    (*list)[*listSz] = 0;
+
+    return WOLFSSL_SUCCESS;
+}
+
+
+/* used to free memory allocated by wolfSSL_ALPN_GetPeerProtocol */
+int wolfSSL_ALPN_FreePeerProtocol(WOLFSSL* ssl, char **list)
+{
+    if (ssl == NULL) {
+        return BAD_FUNC_ARG;
+    }
+
+    XFREE(*list, ssl->heap, DYNAMIC_TYPE_TLSX);
+    *list = NULL;
+
+    return WOLFSSL_SUCCESS;
+}
+
+#endif /* HAVE_ALPN */
+
+/* Secure Renegotiation */
+#ifdef HAVE_SECURE_RENEGOTIATION
+
+/* user is forcing ability to use secure renegotiation, we discourage it */
+int wolfSSL_UseSecureRenegotiation(WOLFSSL* ssl)
+{
+    int ret = BAD_FUNC_ARG;
+
+    if (ssl)
+        ret = TLSX_UseSecureRenegotiation(&ssl->extensions, ssl->heap);
+
+    if (ret == WOLFSSL_SUCCESS) {
+        TLSX* extension = TLSX_Find(ssl->extensions, TLSX_RENEGOTIATION_INFO);
+
+        if (extension)
+            ssl->secure_renegotiation = (SecureRenegotiation*)extension->data;
+    }
+
+    return ret;
+}
+
+int wolfSSL_CTX_UseSecureRenegotiation(WOLFSSL_CTX* ctx)
+{
+    if (ctx == NULL)
+        return BAD_FUNC_ARG;
+
+    ctx->useSecureReneg = 1;
+    return WOLFSSL_SUCCESS;
+}
+
+
+/* do a secure renegotiation handshake, user forced, we discourage */
+static int _Rehandshake(WOLFSSL* ssl)
+{
+    int ret;
+
+    if (ssl == NULL)
+        return BAD_FUNC_ARG;
+
+    if (ssl->secure_renegotiation == NULL) {
+        WOLFSSL_MSG("Secure Renegotiation not forced on by user");
+        return SECURE_RENEGOTIATION_E;
+    }
+
+    if (ssl->secure_renegotiation->enabled == 0) {
+        WOLFSSL_MSG("Secure Renegotiation not enabled at extension level");
+        return SECURE_RENEGOTIATION_E;
+    }
+
+    /* If the client started the renegotiation, the server will already
+     * have processed the client's hello. */
+    if (ssl->options.side != WOLFSSL_SERVER_END ||
+        ssl->options.acceptState != ACCEPT_FIRST_REPLY_DONE) {
+
+        if (ssl->options.handShakeState != HANDSHAKE_DONE) {
+            WOLFSSL_MSG("Can't renegotiate until previous handshake complete");
+            return SECURE_RENEGOTIATION_E;
+        }
+
+#ifndef NO_FORCE_SCR_SAME_SUITE
+        /* force same suite */
+        if (ssl->suites) {
+            ssl->suites->suiteSz = SUITE_LEN;
+            ssl->suites->suites[0] = ssl->options.cipherSuite0;
+            ssl->suites->suites[1] = ssl->options.cipherSuite;
+        }
+#endif
+
+        /* reset handshake states */
+        ssl->options.sendVerify = 0;
+        ssl->options.serverState = NULL_STATE;
+        ssl->options.clientState = NULL_STATE;
+        ssl->options.connectState  = CONNECT_BEGIN;
+        ssl->options.acceptState   = ACCEPT_BEGIN_RENEG;
+        ssl->options.handShakeState = NULL_STATE;
+        ssl->options.processReply  = 0;  /* TODO, move states in internal.h */
+
+        XMEMSET(&ssl->msgsReceived, 0, sizeof(ssl->msgsReceived));
+
+        ssl->secure_renegotiation->cache_status = SCR_CACHE_NEEDED;
+
+#if !defined(NO_WOLFSSL_SERVER) && defined(HAVE_SERVER_RENEGOTIATION_INFO)
+        if (ssl->options.side == WOLFSSL_SERVER_END) {
+            ret = SendHelloRequest(ssl);
+            if (ret != 0) {
+                ssl->error = ret;
+                return WOLFSSL_FATAL_ERROR;
+            }
+        }
+#endif /* NO_WOLFSSL_SERVER && HAVE_SERVER_RENEGOTIATION_INFO */
+
+        ret = InitHandshakeHashes(ssl);
+        if (ret != 0) {
+            ssl->error = ret;
+            return WOLFSSL_FATAL_ERROR;
+        }
+    }
+    ret = wolfSSL_negotiate(ssl);
+    ssl->secure_rene_count++;
+    return ret;
+}
+
+
+/* do a secure renegotiation handshake, user forced, we discourage */
+int wolfSSL_Rehandshake(WOLFSSL* ssl)
+{
+    int ret = WOLFSSL_SUCCESS;
+    WOLFSSL_ENTER("wolfSSL_Rehandshake");
+
+    if (ssl->options.side == WOLFSSL_SERVER_END) {
+        /* Reset option to send certificate verify. */
+        ssl->options.sendVerify = 0;
+    }
+    else {
+        /* Reset resuming flag to do full secure handshake. */
+        ssl->options.resuming = 0;
+        #ifdef HAVE_SESSION_TICKET
+            /* Clearing the ticket. */
+            ret = wolfSSL_UseSessionTicket(ssl);
+        #endif
+    }
+
+    if (ret == WOLFSSL_SUCCESS)
+        ret = _Rehandshake(ssl);
+
+    return ret;
+}
+
+
+#ifndef NO_WOLFSSL_CLIENT
+
+/* do a secure resumption handshake, user forced, we discourage */
+int wolfSSL_SecureResume(WOLFSSL* ssl)
+{
+    WOLFSSL_ENTER("wolfSSL_SecureResume");
+
+    if (ssl == NULL)
+        return BAD_FUNC_ARG;
+
+    if (ssl->options.side == WOLFSSL_SERVER_END) {
+        ssl->error = SIDE_ERROR;
+        return SSL_FATAL_ERROR;
+    }
+
+    return _Rehandshake(ssl);
+}
+
+#endif /* NO_WOLFSSL_CLIENT */
+
+long wolfSSL_SSL_get_secure_renegotiation_support(WOLFSSL* ssl)
+{
+    WOLFSSL_ENTER("wolfSSL_SSL_get_secure_renegotiation_support");
+
+    if (!ssl || !ssl->secure_renegotiation)
+        return WOLFSSL_FAILURE;
+    return ssl->secure_renegotiation->enabled;
+}
+
+#endif /* HAVE_SECURE_RENEGOTIATION */
+
+/* Session Ticket */
+#if !defined(NO_WOLFSSL_SERVER) && defined(HAVE_SESSION_TICKET)
+/* WOLFSSL_SUCCESS on ok */
+int wolfSSL_CTX_set_TicketEncCb(WOLFSSL_CTX* ctx, SessionTicketEncCb cb)
+{
+    if (ctx == NULL)
+        return BAD_FUNC_ARG;
+
+    ctx->ticketEncCb = cb;
+
+    return WOLFSSL_SUCCESS;
+}
+
+/* set hint interval, WOLFSSL_SUCCESS on ok */
+int wolfSSL_CTX_set_TicketHint(WOLFSSL_CTX* ctx, int hint)
+{
+    if (ctx == NULL)
+        return BAD_FUNC_ARG;
+
+    ctx->ticketHint = hint;
+
+    return WOLFSSL_SUCCESS;
+}
+
+/* set user context, WOLFSSL_SUCCESS on ok */
+int wolfSSL_CTX_set_TicketEncCtx(WOLFSSL_CTX* ctx, void* userCtx)
+{
+    if (ctx == NULL)
+        return BAD_FUNC_ARG;
+
+    ctx->ticketEncCtx = userCtx;
+
+    return WOLFSSL_SUCCESS;
+}
+
+#endif /* !defined(NO_WOLFSSL_CLIENT) && defined(HAVE_SESSION_TICKET) */
+
+/* Session Ticket */
+#if !defined(NO_WOLFSSL_CLIENT) && defined(HAVE_SESSION_TICKET)
+int wolfSSL_UseSessionTicket(WOLFSSL* ssl)
+{
+    if (ssl == NULL)
+        return BAD_FUNC_ARG;
+
+    return TLSX_UseSessionTicket(&ssl->extensions, NULL, ssl->heap);
+}
+
+int wolfSSL_CTX_UseSessionTicket(WOLFSSL_CTX* ctx)
+{
+    if (ctx == NULL)
+        return BAD_FUNC_ARG;
+
+    return TLSX_UseSessionTicket(&ctx->extensions, NULL, ctx->heap);
+}
+
+WOLFSSL_API int wolfSSL_get_SessionTicket(WOLFSSL* ssl,
+                                          byte* buf, word32* bufSz)
+{
+    if (ssl == NULL || buf == NULL || bufSz == NULL || *bufSz == 0)
+        return BAD_FUNC_ARG;
+
+    if (ssl->session.ticketLen <= *bufSz) {
+        XMEMCPY(buf, ssl->session.ticket, ssl->session.ticketLen);
+        *bufSz = ssl->session.ticketLen;
+    }
+    else
+        *bufSz = 0;
+
+    return WOLFSSL_SUCCESS;
+}
+
+WOLFSSL_API int wolfSSL_set_SessionTicket(WOLFSSL* ssl, const byte* buf,
+                                          word32 bufSz)
+{
+    if (ssl == NULL || (buf == NULL && bufSz > 0))
+        return BAD_FUNC_ARG;
+
+    if (bufSz > 0) {
+        /* Ticket will fit into static ticket */
+        if(bufSz <= SESSION_TICKET_LEN) {
+            if (ssl->session.isDynamic) {
+                XFREE(ssl->session.ticket, ssl->heap, DYNAMIC_TYPE_SESSION_TICK);
+                ssl->session.isDynamic = 0;
+                ssl->session.ticket = ssl->session.staticTicket;
+            }
+        } else { /* Ticket requires dynamic ticket storage */
+            if (ssl->session.ticketLen < bufSz) { /* is dyn buffer big enough */
+                if(ssl->session.isDynamic)
+                    XFREE(ssl->session.ticket, ssl->heap,
+                            DYNAMIC_TYPE_SESSION_TICK);
+                ssl->session.ticket = (byte*)XMALLOC(bufSz, ssl->heap,
+                        DYNAMIC_TYPE_SESSION_TICK);
+                if(!ssl->session.ticket) {
+                    ssl->session.ticket = ssl->session.staticTicket;
+                    ssl->session.isDynamic = 0;
+                    return MEMORY_ERROR;
+                }
+                ssl->session.isDynamic = 1;
+            }
+        }
+        XMEMCPY(ssl->session.ticket, buf, bufSz);
+    }
+    ssl->session.ticketLen = (word16)bufSz;
+
+    return WOLFSSL_SUCCESS;
+}
+
+
+WOLFSSL_API int wolfSSL_set_SessionTicket_cb(WOLFSSL* ssl,
+                                            CallbackSessionTicket cb, void* ctx)
+{
+    if (ssl == NULL)
+        return BAD_FUNC_ARG;
+
+    ssl->session_ticket_cb = cb;
+    ssl->session_ticket_ctx = ctx;
+
+    return WOLFSSL_SUCCESS;
+}
+#endif
+
+
+#ifdef HAVE_EXTENDED_MASTER
+#ifndef NO_WOLFSSL_CLIENT
+
+int wolfSSL_CTX_DisableExtendedMasterSecret(WOLFSSL_CTX* ctx)
+{
+    if (ctx == NULL)
+        return BAD_FUNC_ARG;
+
+    ctx->haveEMS = 0;
+
+    return WOLFSSL_SUCCESS;
+}
+
+
+int wolfSSL_DisableExtendedMasterSecret(WOLFSSL* ssl)
+{
+    if (ssl == NULL)
+        return BAD_FUNC_ARG;
+
+    ssl->options.haveEMS = 0;
+
+    return WOLFSSL_SUCCESS;
+}
+
+#endif
+#endif
+
+
+#ifndef WOLFSSL_LEANPSK
+
+int wolfSSL_send(WOLFSSL* ssl, const void* data, int sz, int flags)
+{
+    int ret;
+    int oldFlags;
+
+    WOLFSSL_ENTER("wolfSSL_send()");
+
+    if (ssl == NULL || data == NULL || sz < 0)
+        return BAD_FUNC_ARG;
+
+    oldFlags = ssl->wflags;
+
+    ssl->wflags = flags;
+    ret = wolfSSL_write(ssl, data, sz);
+    ssl->wflags = oldFlags;
+
+    WOLFSSL_LEAVE("wolfSSL_send()", ret);
+
+    return ret;
+}
+
+
+int wolfSSL_recv(WOLFSSL* ssl, void* data, int sz, int flags)
+{
+    int ret;
+    int oldFlags;
+
+    WOLFSSL_ENTER("wolfSSL_recv()");
+
+    if (ssl == NULL || data == NULL || sz < 0)
+        return BAD_FUNC_ARG;
+
+    oldFlags = ssl->rflags;
+
+    ssl->rflags = flags;
+    ret = wolfSSL_read(ssl, data, sz);
+    ssl->rflags = oldFlags;
+
+    WOLFSSL_LEAVE("wolfSSL_recv()", ret);
+
+    return ret;
+}
+#endif
+
+
+/* WOLFSSL_SUCCESS on ok */
+WOLFSSL_ABI
+int wolfSSL_shutdown(WOLFSSL* ssl)
+{
+    int  ret = WOLFSSL_FATAL_ERROR;
+    WOLFSSL_ENTER("SSL_shutdown()");
+
+    if (ssl == NULL)
+        return WOLFSSL_FATAL_ERROR;
+
+    if (ssl->options.quietShutdown) {
+        WOLFSSL_MSG("quiet shutdown, no close notify sent");
+        ret = WOLFSSL_SUCCESS;
+    }
+    else {
+        /* try to send close notify, not an error if can't */
+        if (!ssl->options.isClosed && !ssl->options.connReset &&
+                                      !ssl->options.sentNotify) {
+            ssl->error = SendAlert(ssl, alert_warning, close_notify);
+            if (ssl->error < 0) {
+                WOLFSSL_ERROR(ssl->error);
+                return WOLFSSL_FATAL_ERROR;
+            }
+            ssl->options.sentNotify = 1;  /* don't send close_notify twice */
+            if (ssl->options.closeNotify)
+                ret = WOLFSSL_SUCCESS;
+            else {
+                ret = WOLFSSL_SHUTDOWN_NOT_DONE;
+                WOLFSSL_LEAVE("SSL_shutdown()", ret);
+                return ret;
+            }
+        }
+
+#ifdef WOLFSSL_SHUTDOWNONCE
+        if (ssl->options.isClosed || ssl->options.connReset) {
+            /* Shutdown has already occurred.
+             * Caller is free to ignore this error. */
+            return SSL_SHUTDOWN_ALREADY_DONE_E;
+        }
+#endif
+
+        /* call wolfSSL_shutdown again for bidirectional shutdown */
+        if (ssl->options.sentNotify && !ssl->options.closeNotify) {
+            ret = ProcessReply(ssl);
+            if (ret == ZERO_RETURN) {
+                /* simulate OpenSSL behavior */
+                ssl->error = WOLFSSL_ERROR_SYSCALL;
+                ret = WOLFSSL_SUCCESS;
+            } else if (ssl->error == WOLFSSL_ERROR_NONE) {
+                ret = WOLFSSL_SHUTDOWN_NOT_DONE;
+            } else {
+                WOLFSSL_ERROR(ssl->error);
+                ret = WOLFSSL_FATAL_ERROR;
+            }
+        }
+    }
+
+#ifdef OPENSSL_EXTRA
+    /* reset WOLFSSL structure state for possible re-use */
+    if (ret == WOLFSSL_SUCCESS) {
+        if (wolfSSL_clear(ssl) != WOLFSSL_SUCCESS) {
+            WOLFSSL_MSG("could not clear WOLFSSL");
+            ret = WOLFSSL_FATAL_ERROR;
+        }
+    }
+#endif
+
+    WOLFSSL_LEAVE("SSL_shutdown()", ret);
+
+    return ret;
+}
+
+
+/* get current error state value */
+int wolfSSL_state(WOLFSSL* ssl)
+{
+    if (ssl == NULL) {
+        return BAD_FUNC_ARG;
+    }
+
+    return ssl->error;
+}
+
+
+WOLFSSL_ABI
+int wolfSSL_get_error(WOLFSSL* ssl, int ret)
+{
+    WOLFSSL_ENTER("SSL_get_error");
+
+    if (ret > 0)
+        return WOLFSSL_ERROR_NONE;
+    if (ssl == NULL)
+        return BAD_FUNC_ARG;
+
+    WOLFSSL_LEAVE("SSL_get_error", ssl->error);
+
+    /* make sure converted types are handled in SetErrorString() too */
+    if (ssl->error == WANT_READ)
+        return WOLFSSL_ERROR_WANT_READ;         /* convert to OpenSSL type */
+    else if (ssl->error == WANT_WRITE)
+        return WOLFSSL_ERROR_WANT_WRITE;        /* convert to OpenSSL type */
+    else if (ssl->error == ZERO_RETURN)
+        return WOLFSSL_ERROR_ZERO_RETURN;       /* convert to OpenSSL type */
+    return ssl->error;
+}
+
+
+/* retrieve alert history, WOLFSSL_SUCCESS on ok */
+int wolfSSL_get_alert_history(WOLFSSL* ssl, WOLFSSL_ALERT_HISTORY *h)
+{
+    if (ssl && h) {
+        *h = ssl->alert_history;
+    }
+    return WOLFSSL_SUCCESS;
+}
+
+#ifdef OPENSSL_EXTRA
+/* returns SSL_WRITING, SSL_READING or SSL_NOTHING */
+int wolfSSL_want(WOLFSSL* ssl)
+{
+    int rw_state = SSL_NOTHING;
+    if (ssl) {
+        if (ssl->error == WANT_READ)
+            rw_state = SSL_READING;
+        else if (ssl->error == WANT_WRITE)
+            rw_state = SSL_WRITING;
+    }
+    return rw_state;
+}
+#endif
+
+/* return TRUE if current error is want read */
+int wolfSSL_want_read(WOLFSSL* ssl)
+{
+    WOLFSSL_ENTER("SSL_want_read");
+    if (ssl->error == WANT_READ)
+        return 1;
+
+    return 0;
+}
+
+
+/* return TRUE if current error is want write */
+int wolfSSL_want_write(WOLFSSL* ssl)
+{
+    WOLFSSL_ENTER("SSL_want_write");
+    if (ssl->error == WANT_WRITE)
+        return 1;
+
+    return 0;
+}
+
+
+char* wolfSSL_ERR_error_string(unsigned long errNumber, char* data)
+{
+    static wcchar msg = "Please supply a buffer for error string";
+
+    WOLFSSL_ENTER("ERR_error_string");
+    if (data) {
+        SetErrorString((int)errNumber, data);
+        return data;
+    }
+
+    return (char*)msg;
+}
+
+
+void wolfSSL_ERR_error_string_n(unsigned long e, char* buf, unsigned long len)
+{
+    WOLFSSL_ENTER("wolfSSL_ERR_error_string_n");
+    if (len >= WOLFSSL_MAX_ERROR_SZ)
+        wolfSSL_ERR_error_string(e, buf);
+    else {
+        char tmp[WOLFSSL_MAX_ERROR_SZ];
+
+        WOLFSSL_MSG("Error buffer too short, truncating");
+        if (len) {
+            wolfSSL_ERR_error_string(e, tmp);
+            XMEMCPY(buf, tmp, len-1);
+            buf[len-1] = '\0';
+        }
+    }
+}
+
+
+/* don't free temporary arrays at end of handshake */
+void wolfSSL_KeepArrays(WOLFSSL* ssl)
+{
+    if (ssl)
+        ssl->options.saveArrays = 1;
+}
+
+
+/* user doesn't need temporary arrays anymore, Free */
+void wolfSSL_FreeArrays(WOLFSSL* ssl)
+{
+    if (ssl && ssl->options.handShakeState == HANDSHAKE_DONE) {
+        ssl->options.saveArrays = 0;
+        FreeArrays(ssl, 1);
+    }
+}
+
+/* Set option to indicate that the resources are not to be freed after
+ * handshake.
+ *
+ * ssl  The SSL/TLS object.
+ * returns BAD_FUNC_ARG when ssl is NULL and 0 on success.
+ */
+int wolfSSL_KeepHandshakeResources(WOLFSSL* ssl)
+{
+    if (ssl == NULL)
+        return BAD_FUNC_ARG;
+
+    ssl->options.keepResources = 1;
+
+    return 0;
+}
+
+/* Free the handshake resources after handshake.
+ *
+ * ssl  The SSL/TLS object.
+ * returns BAD_FUNC_ARG when ssl is NULL and 0 on success.
+ */
+int wolfSSL_FreeHandshakeResources(WOLFSSL* ssl)
+{
+    if (ssl == NULL)
+        return BAD_FUNC_ARG;
+
+    FreeHandshakeResources(ssl);
+
+    return 0;
+}
+
+/* Use the client's order of preference when matching cipher suites.
+ *
+ * ssl  The SSL/TLS context object.
+ * returns BAD_FUNC_ARG when ssl is NULL and 0 on success.
+ */
+int wolfSSL_CTX_UseClientSuites(WOLFSSL_CTX* ctx)
+{
+    if (ctx == NULL)
+        return BAD_FUNC_ARG;
+
+    ctx->useClientOrder = 1;
+
+    return 0;
+}
+
+/* Use the client's order of preference when matching cipher suites.
+ *
+ * ssl  The SSL/TLS object.
+ * returns BAD_FUNC_ARG when ssl is NULL and 0 on success.
+ */
+int wolfSSL_UseClientSuites(WOLFSSL* ssl)
+{
+    if (ssl == NULL)
+        return BAD_FUNC_ARG;
+
+    ssl->options.useClientOrder = 1;
+
+    return 0;
+}
+
+const byte* wolfSSL_GetMacSecret(WOLFSSL* ssl, int verify)
+{
+#ifndef WOLFSSL_AEAD_ONLY
+    if (ssl == NULL)
+        return NULL;
+
+    if ( (ssl->options.side == WOLFSSL_CLIENT_END && !verify) ||
+         (ssl->options.side == WOLFSSL_SERVER_END &&  verify) )
+        return ssl->keys.client_write_MAC_secret;
+    else
+        return ssl->keys.server_write_MAC_secret;
+#else
+    (void)ssl;
+    (void)verify;
+
+    return NULL;
+#endif
+}
+
+
+#ifdef ATOMIC_USER
+
+void  wolfSSL_CTX_SetMacEncryptCb(WOLFSSL_CTX* ctx, CallbackMacEncrypt cb)
+{
+    if (ctx)
+        ctx->MacEncryptCb = cb;
+}
+
+
+void  wolfSSL_SetMacEncryptCtx(WOLFSSL* ssl, void *ctx)
+{
+    if (ssl)
+        ssl->MacEncryptCtx = ctx;
+}
+
+
+void* wolfSSL_GetMacEncryptCtx(WOLFSSL* ssl)
+{
+    if (ssl)
+        return ssl->MacEncryptCtx;
+
+    return NULL;
+}
+
+
+void  wolfSSL_CTX_SetDecryptVerifyCb(WOLFSSL_CTX* ctx, CallbackDecryptVerify cb)
+{
+    if (ctx)
+        ctx->DecryptVerifyCb = cb;
+}
+
+
+void  wolfSSL_SetDecryptVerifyCtx(WOLFSSL* ssl, void *ctx)
+{
+    if (ssl)
+        ssl->DecryptVerifyCtx = ctx;
+}
+
+
+void* wolfSSL_GetDecryptVerifyCtx(WOLFSSL* ssl)
+{
+    if (ssl)
+        return ssl->DecryptVerifyCtx;
+
+    return NULL;
+}
+
+#if defined(HAVE_ENCRYPT_THEN_MAC) && !defined(WOLFSSL_AEAD_ONLY)
+/**
+ * Set the callback, against the context, that encrypts then MACs.
+ *
+ * ctx  SSL/TLS context.
+ * cb   Callback function to use with Encrypt-Then-MAC.
+ */
+void  wolfSSL_CTX_SetEncryptMacCb(WOLFSSL_CTX* ctx, CallbackEncryptMac cb)
+{
+    if (ctx)
+        ctx->EncryptMacCb = cb;
+}
+
+/**
+ * Set the context to use with callback that encrypts then MACs.
+ *
+ * ssl  SSL/TLS object.
+ * ctx  Callback function's context.
+ */
+void  wolfSSL_SetEncryptMacCtx(WOLFSSL* ssl, void *ctx)
+{
+    if (ssl)
+        ssl->EncryptMacCtx = ctx;
+}
+
+/**
+ * Get the context being used with callback that encrypts then MACs.
+ *
+ * ssl  SSL/TLS object.
+ * returns callback function's context or NULL if SSL/TLS object is NULL.
+ */
+void* wolfSSL_GetEncryptMacCtx(WOLFSSL* ssl)
+{
+    if (ssl)
+        return ssl->EncryptMacCtx;
+
+    return NULL;
+}
+
+
+/**
+ * Set the callback, against the context, that MAC verifies then decrypts.
+ *
+ * ctx  SSL/TLS context.
+ * cb   Callback function to use with Encrypt-Then-MAC.
+ */
+void  wolfSSL_CTX_SetVerifyDecryptCb(WOLFSSL_CTX* ctx, CallbackVerifyDecrypt cb)
+{
+    if (ctx)
+        ctx->VerifyDecryptCb = cb;
+}
+
+/**
+ * Set the context to use with callback that MAC verifies then decrypts.
+ *
+ * ssl  SSL/TLS object.
+ * ctx  Callback function's context.
+ */
+void  wolfSSL_SetVerifyDecryptCtx(WOLFSSL* ssl, void *ctx)
+{
+    if (ssl)
+        ssl->VerifyDecryptCtx = ctx;
+}
+
+/**
+ * Get the context being used with callback that MAC verifies then decrypts.
+ *
+ * ssl  SSL/TLS object.
+ * returns callback function's context or NULL if SSL/TLS object is NULL.
+ */
+void* wolfSSL_GetVerifyDecryptCtx(WOLFSSL* ssl)
+{
+    if (ssl)
+        return ssl->VerifyDecryptCtx;
+
+    return NULL;
+}
+#endif /* HAVE_ENCRYPT_THEN_MAC !WOLFSSL_AEAD_ONLY */
+
+
+
+const byte* wolfSSL_GetClientWriteKey(WOLFSSL* ssl)
+{
+    if (ssl)
+        return ssl->keys.client_write_key;
+
+    return NULL;
+}
+
+
+const byte* wolfSSL_GetClientWriteIV(WOLFSSL* ssl)
+{
+    if (ssl)
+        return ssl->keys.client_write_IV;
+
+    return NULL;
+}
+
+
+const byte* wolfSSL_GetServerWriteKey(WOLFSSL* ssl)
+{
+    if (ssl)
+        return ssl->keys.server_write_key;
+
+    return NULL;
+}
+
+
+const byte* wolfSSL_GetServerWriteIV(WOLFSSL* ssl)
+{
+    if (ssl)
+        return ssl->keys.server_write_IV;
+
+    return NULL;
+}
+
+int wolfSSL_GetKeySize(WOLFSSL* ssl)
+{
+    if (ssl)
+        return ssl->specs.key_size;
+
+    return BAD_FUNC_ARG;
+}
+
+
+int wolfSSL_GetIVSize(WOLFSSL* ssl)
+{
+    if (ssl)
+        return ssl->specs.iv_size;
+
+    return BAD_FUNC_ARG;
+}
+
+
+int wolfSSL_GetBulkCipher(WOLFSSL* ssl)
+{
+    if (ssl)
+        return ssl->specs.bulk_cipher_algorithm;
+
+    return BAD_FUNC_ARG;
+}
+
+
+int wolfSSL_GetCipherType(WOLFSSL* ssl)
+{
+    if (ssl == NULL)
+        return BAD_FUNC_ARG;
+
+#ifndef WOLFSSL_AEAD_ONLY
+    if (ssl->specs.cipher_type == block)
+        return WOLFSSL_BLOCK_TYPE;
+    if (ssl->specs.cipher_type == stream)
+        return WOLFSSL_STREAM_TYPE;
+#endif
+    if (ssl->specs.cipher_type == aead)
+        return WOLFSSL_AEAD_TYPE;
+
+    return -1;
+}
+
+
+int wolfSSL_GetCipherBlockSize(WOLFSSL* ssl)
+{
+    if (ssl == NULL)
+        return BAD_FUNC_ARG;
+
+    return ssl->specs.block_size;
+}
+
+
+int wolfSSL_GetAeadMacSize(WOLFSSL* ssl)
+{
+    if (ssl == NULL)
+        return BAD_FUNC_ARG;
+
+    return ssl->specs.aead_mac_size;
+}
+
+
+int wolfSSL_IsTLSv1_1(WOLFSSL* ssl)
+{
+    if (ssl == NULL)
+        return BAD_FUNC_ARG;
+
+    if (ssl->options.tls1_1)
+        return 1;
+
+    return 0;
+}
+
+
+int wolfSSL_GetSide(WOLFSSL* ssl)
+{
+    if (ssl)
+        return ssl->options.side;
+
+    return BAD_FUNC_ARG;
+}
+
+
+int wolfSSL_GetHmacSize(WOLFSSL* ssl)
+{
+    /* AEAD ciphers don't have HMAC keys */
+    if (ssl)
+        return (ssl->specs.cipher_type != aead) ? ssl->specs.hash_size : 0;
+
+    return BAD_FUNC_ARG;
+}
+
+#endif /* ATOMIC_USER */
+
+#ifndef NO_CERTS
+
+WOLFSSL_CERT_MANAGER* wolfSSL_CTX_GetCertManager(WOLFSSL_CTX* ctx)
+{
+    WOLFSSL_CERT_MANAGER* cm = NULL;
+    if (ctx)
+        cm = ctx->cm;
+    return cm;
+}
+
+WOLFSSL_CERT_MANAGER* wolfSSL_CertManagerNew_ex(void* heap)
+{
+    WOLFSSL_CERT_MANAGER* cm;
+
+    WOLFSSL_ENTER("wolfSSL_CertManagerNew");
+
+    cm = (WOLFSSL_CERT_MANAGER*) XMALLOC(sizeof(WOLFSSL_CERT_MANAGER), heap,
+                                         DYNAMIC_TYPE_CERT_MANAGER);
+    if (cm) {
+        XMEMSET(cm, 0, sizeof(WOLFSSL_CERT_MANAGER));
+
+        if (wc_InitMutex(&cm->caLock) != 0) {
+            WOLFSSL_MSG("Bad mutex init");
+            wolfSSL_CertManagerFree(cm);
+            return NULL;
+        }
+
+        #ifdef WOLFSSL_TRUST_PEER_CERT
+        if (wc_InitMutex(&cm->tpLock) != 0) {
+            WOLFSSL_MSG("Bad mutex init");
+            wolfSSL_CertManagerFree(cm);
+            return NULL;
+        }
+        #endif
+
+        /* set default minimum key size allowed */
+        #ifndef NO_RSA
+            cm->minRsaKeySz = MIN_RSAKEY_SZ;
+        #endif
+        #ifdef HAVE_ECC
+            cm->minEccKeySz = MIN_ECCKEY_SZ;
+        #endif
+            cm->heap = heap;
+    }
+
+    return cm;
+}
+
+
+WOLFSSL_CERT_MANAGER* wolfSSL_CertManagerNew(void)
+{
+    return wolfSSL_CertManagerNew_ex(NULL);
+}
+
+
+void wolfSSL_CertManagerFree(WOLFSSL_CERT_MANAGER* cm)
+{
+    WOLFSSL_ENTER("wolfSSL_CertManagerFree");
+
+    if (cm) {
+        #ifdef HAVE_CRL
+            if (cm->crl)
+                FreeCRL(cm->crl, 1);
+        #endif
+        #ifdef HAVE_OCSP
+            if (cm->ocsp)
+                FreeOCSP(cm->ocsp, 1);
+            XFREE(cm->ocspOverrideURL, cm->heap, DYNAMIC_TYPE_URL);
+        #if !defined(NO_WOLFSSL_SERVER) && \
+            (defined(HAVE_CERTIFICATE_STATUS_REQUEST) || \
+             defined(HAVE_CERTIFICATE_STATUS_REQUEST_V2))
+            if (cm->ocsp_stapling)
+                FreeOCSP(cm->ocsp_stapling, 1);
+        #endif
+        #endif
+        FreeSignerTable(cm->caTable, CA_TABLE_SIZE, cm->heap);
+        wc_FreeMutex(&cm->caLock);
+
+        #ifdef WOLFSSL_TRUST_PEER_CERT
+        FreeTrustedPeerTable(cm->tpTable, TP_TABLE_SIZE, cm->heap);
+        wc_FreeMutex(&cm->tpLock);
+        #endif
+
+        XFREE(cm, cm->heap, DYNAMIC_TYPE_CERT_MANAGER);
+    }
+
+}
+
+#if defined(OPENSSL_EXTRA) && !defined(NO_FILESYSTEM)
+#if defined(WOLFSSL_SIGNER_DER_CERT)
+/******************************************************************************
+* wolfSSL_CertManagerGetCerts - retrieve stack of X509 certificates in a
+* certificate manager (CM).
+*
+* RETURNS:
+* returns stack of X509 certs on success, otherwise returns a NULL.
+*/
+WOLFSSL_STACK* wolfSSL_CertManagerGetCerts(WOLFSSL_CERT_MANAGER* cm)
+{
+    WOLFSSL_STACK* sk = NULL;
+    Signer* signers = NULL;
+    word32  row = 0;
+    DecodedCert* dCert = NULL;
+    WOLFSSL_X509* x509 = NULL;
+    int found = 0;
+
+    if (cm == NULL)
+        return NULL;
+
+    sk = wolfSSL_sk_X509_new();
+
+    if (sk == NULL) {
+        return NULL;
+    }
+
+    if (wc_LockMutex(&cm->caLock) != 0) {
+        goto error_init;
+    }
+
+    for (row = 0; row < CA_TABLE_SIZE; row++) {
+        signers = cm->caTable[row];
+        while (signers && signers->derCert && signers->derCert->buffer) {
+
+            dCert = (DecodedCert*)XMALLOC(sizeof(DecodedCert), cm->heap,
+                                          DYNAMIC_TYPE_DCERT);
+            if (dCert == NULL) {
+                goto error;
+            }
+
+            XMEMSET(dCert, 0, sizeof(DecodedCert));
+
+            InitDecodedCert(dCert, signers->derCert->buffer,
+                            signers->derCert->length, cm->heap);
+
+            /* Parse Certificate */
+            if (ParseCert(dCert, CERT_TYPE, NO_VERIFY, cm)) {
+                goto error;
+            }
+
+            x509 = (WOLFSSL_X509*)XMALLOC(sizeof(WOLFSSL_X509), cm->heap,
+                    DYNAMIC_TYPE_X509);
+
+            if (x509 == NULL) {
+                goto error;
+            }
+
+            InitX509(x509, 1, NULL);
+
+            if (CopyDecodedToX509(x509, dCert) == 0) {
+
+                if (wolfSSL_sk_X509_push(sk, x509) != SSL_SUCCESS) {
+                    WOLFSSL_MSG("Unable to load x509 into stack");
+                    FreeX509(x509);
+                    XFREE(x509, cm->heap, DYNAMIC_TYPE_X509);
+                    goto error;
+                }
+            }
+            else {
+                goto error;
+            }
+
+            found = 1;
+
+            signers = signers->next;
+
+            FreeDecodedCert(dCert);
+            XFREE(dCert, cm->heap, DYNAMIC_TYPE_DCERT);
+            dCert = NULL;
+        }
+    }
+    wc_UnLockMutex(&cm->caLock);
+
+    if (!found) {
+       goto error_init;
+    }
+
+    return sk;
+
+error:
+    wc_UnLockMutex(&cm->caLock);
+
+error_init:
+
+    if (dCert) {
+        FreeDecodedCert(dCert);
+        XFREE(dCert, cm->heap, DYNAMIC_TYPE_DCERT);
+    }
+
+    if (sk)
+        wolfSSL_sk_X509_free(sk);
+
+    return NULL;
+}
+#endif /* WOLFSSL_SIGNER_DER_CERT */
+
+/******************************************************************************
+* wolfSSL_X509_STORE_GetCerts - retrieve stack of X509 in a certificate store ctx
+*
+* This API can be used in SSL verify callback function to view cert chain
+* See examples/client/client.c and myVerify() function in test.h
+*
+* RETURNS:
+* returns stack of X509 certs on success, otherwise returns a NULL.
+*/
+WOLFSSL_STACK* wolfSSL_X509_STORE_GetCerts(WOLFSSL_X509_STORE_CTX* s)
+{
+    int  certIdx = 0;
+    WOLFSSL_BUFFER_INFO* cert = NULL;
+    DecodedCert* dCert = NULL;
+    WOLFSSL_X509* x509 = NULL;
+    WOLFSSL_STACK* sk = NULL;
+    int found = 0;
+
+    if (s == NULL) {
+        return NULL;
+    }
+
+    sk = wolfSSL_sk_X509_new();
+
+    if (sk == NULL) {
+        return NULL;
+    }
+
+    for (certIdx = s->totalCerts - 1; certIdx >= 0; certIdx--) {
+        /* get certificate buffer */
+        cert = &s->certs[certIdx];
+
+        dCert = (DecodedCert*)XMALLOC(sizeof(DecodedCert), NULL, DYNAMIC_TYPE_DCERT);
+
+        if (dCert == NULL) {
+            goto error;
+        }
+        XMEMSET(dCert, 0, sizeof(DecodedCert));
+
+        InitDecodedCert(dCert, cert->buffer, cert->length, NULL);
+
+        /* Parse Certificate */
+        if (ParseCert(dCert, CERT_TYPE, NO_VERIFY, NULL)){
+            goto error;
+        }
+        x509 = wolfSSL_X509_new();
+
+        if (x509 == NULL) {
+            goto error;
+        }
+        InitX509(x509, 1, NULL);
+
+        if (CopyDecodedToX509(x509, dCert) == 0) {
+
+            if (wolfSSL_sk_X509_push(sk, x509) != SSL_SUCCESS) {
+                WOLFSSL_MSG("Unable to load x509 into stack");
+                wolfSSL_X509_free(x509);
+                goto error;
+            }
+        }
+        else {
+            goto error;
+        }
+        found = 1;
+
+        FreeDecodedCert(dCert);
+        XFREE(dCert, NULL, DYNAMIC_TYPE_DCERT);
+        dCert = NULL;
+    }
+
+    if (!found) {
+        wolfSSL_sk_X509_free(sk);
+        sk = NULL;
+    }
+    return sk;
+
+error:
+    if (dCert) {
+        FreeDecodedCert(dCert);
+        XFREE(dCert, NULL, DYNAMIC_TYPE_DCERT);
+    }
+
+    if (sk)
+        wolfSSL_sk_X509_free(sk);
+
+    return NULL;
+}
+#endif /* OPENSSL_EXTRA && !NO_FILESYSTEM */
+
+/* Unload the CA signer list */
+int wolfSSL_CertManagerUnloadCAs(WOLFSSL_CERT_MANAGER* cm)
+{
+    WOLFSSL_ENTER("wolfSSL_CertManagerUnloadCAs");
+
+    if (cm == NULL)
+        return BAD_FUNC_ARG;
+
+    if (wc_LockMutex(&cm->caLock) != 0)
+        return BAD_MUTEX_E;
+
+    FreeSignerTable(cm->caTable, CA_TABLE_SIZE, cm->heap);
+
+    wc_UnLockMutex(&cm->caLock);
+
+
+    return WOLFSSL_SUCCESS;
+}
+
+
+#ifdef WOLFSSL_TRUST_PEER_CERT
+int wolfSSL_CertManagerUnload_trust_peers(WOLFSSL_CERT_MANAGER* cm)
+{
+    WOLFSSL_ENTER("wolfSSL_CertManagerUnload_trust_peers");
+
+    if (cm == NULL)
+        return BAD_FUNC_ARG;
+
+    if (wc_LockMutex(&cm->tpLock) != 0)
+        return BAD_MUTEX_E;
+
+    FreeTrustedPeerTable(cm->tpTable, TP_TABLE_SIZE, cm->heap);
+
+    wc_UnLockMutex(&cm->tpLock);
+
+
+    return WOLFSSL_SUCCESS;
+}
+#endif /* WOLFSSL_TRUST_PEER_CERT */
+
+#endif /* NO_CERTS */
+
+#if !defined(NO_FILESYSTEM) && !defined(NO_STDIO_FILESYSTEM)
+
+void wolfSSL_ERR_print_errors_fp(XFILE fp, int err)
+{
+    char data[WOLFSSL_MAX_ERROR_SZ + 1];
+
+    WOLFSSL_ENTER("wolfSSL_ERR_print_errors_fp");
+    SetErrorString(err, data);
+    fprintf(fp, "%s", data);
+}
+
+#if defined(OPENSSL_EXTRA) || defined(DEBUG_WOLFSSL_VERBOSE)
+void wolfSSL_ERR_dump_errors_fp(XFILE fp)
+{
+    wc_ERR_print_errors_fp(fp);
+}
+
+void wolfSSL_ERR_print_errors_cb (int (*cb)(const char *str, size_t len,
+                                            void *u), void *u)
+{
+    wc_ERR_print_errors_cb(cb, u);
+}
+#endif
+#endif
+
+WOLFSSL_ABI
+int wolfSSL_pending(WOLFSSL* ssl)
+{
+    WOLFSSL_ENTER("SSL_pending");
+    return ssl->buffers.clearOutputBuffer.length;
+}
+
+
+#ifndef WOLFSSL_LEANPSK
+/* turn on handshake group messages for context */
+int wolfSSL_CTX_set_group_messages(WOLFSSL_CTX* ctx)
+{
+    if (ctx == NULL)
+       return BAD_FUNC_ARG;
+
+    ctx->groupMessages = 1;
+
+    return WOLFSSL_SUCCESS;
+}
+#endif
+
+
+#ifndef NO_WOLFSSL_CLIENT
+/* connect enough to get peer cert chain */
+int wolfSSL_connect_cert(WOLFSSL* ssl)
+{
+    int  ret;
+
+    if (ssl == NULL)
+        return WOLFSSL_FAILURE;
+
+    ssl->options.certOnly = 1;
+    ret = wolfSSL_connect(ssl);
+    ssl->options.certOnly   = 0;
+
+    return ret;
+}
+#endif
+
+
+#ifndef WOLFSSL_LEANPSK
+/* turn on handshake group messages for ssl object */
+int wolfSSL_set_group_messages(WOLFSSL* ssl)
+{
+    if (ssl == NULL)
+       return BAD_FUNC_ARG;
+
+    ssl->options.groupMessages = 1;
+
+    return WOLFSSL_SUCCESS;
+}
+
+
+/* make minVersion the internal equivalent SSL version */
+static int SetMinVersionHelper(byte* minVersion, int version)
+{
+#ifdef NO_TLS
+    (void)minVersion;
+#endif
+
+    switch (version) {
+#if defined(WOLFSSL_ALLOW_SSLV3) && !defined(NO_OLD_TLS)
+        case WOLFSSL_SSLV3:
+            *minVersion = SSLv3_MINOR;
+            break;
+#endif
+
+#ifndef NO_TLS
+    #ifndef NO_OLD_TLS
+        #ifdef WOLFSSL_ALLOW_TLSV10
+        case WOLFSSL_TLSV1:
+            *minVersion = TLSv1_MINOR;
+            break;
+        #endif
+
+        case WOLFSSL_TLSV1_1:
+            *minVersion = TLSv1_1_MINOR;
+            break;
+    #endif
+    #ifndef WOLFSSL_NO_TLS12
+        case WOLFSSL_TLSV1_2:
+            *minVersion = TLSv1_2_MINOR;
+            break;
+    #endif
+#endif
+    #ifdef WOLFSSL_TLS13
+        case WOLFSSL_TLSV1_3:
+            *minVersion = TLSv1_3_MINOR;
+            break;
+    #endif
+
+        default:
+            WOLFSSL_MSG("Bad function argument");
+            return BAD_FUNC_ARG;
+    }
+
+    return WOLFSSL_SUCCESS;
+}
+
+
+/* Set minimum downgrade version allowed, WOLFSSL_SUCCESS on ok */
+WOLFSSL_ABI
+int wolfSSL_CTX_SetMinVersion(WOLFSSL_CTX* ctx, int version)
+{
+    WOLFSSL_ENTER("wolfSSL_CTX_SetMinVersion");
+
+    if (ctx == NULL) {
+        WOLFSSL_MSG("Bad function argument");
+        return BAD_FUNC_ARG;
+    }
+
+    return SetMinVersionHelper(&ctx->minDowngrade, version);
+}
+
+
+/* Set minimum downgrade version allowed, WOLFSSL_SUCCESS on ok */
+int wolfSSL_SetMinVersion(WOLFSSL* ssl, int version)
+{
+    WOLFSSL_ENTER("wolfSSL_SetMinVersion");
+
+    if (ssl == NULL) {
+        WOLFSSL_MSG("Bad function argument");
+        return BAD_FUNC_ARG;
+    }
+
+    return SetMinVersionHelper(&ssl->options.minDowngrade, version);
+}
+
+
+/* Function to get version as WOLFSSL_ enum value for wolfSSL_SetVersion */
+int wolfSSL_GetVersion(WOLFSSL* ssl)
+{
+    if (ssl == NULL)
+        return BAD_FUNC_ARG;
+
+    if (ssl->version.major == SSLv3_MAJOR) {
+        switch (ssl->version.minor) {
+            case SSLv3_MINOR :
+                return WOLFSSL_SSLV3;
+            case TLSv1_MINOR :
+                return WOLFSSL_TLSV1;
+            case TLSv1_1_MINOR :
+                return WOLFSSL_TLSV1_1;
+            case TLSv1_2_MINOR :
+                return WOLFSSL_TLSV1_2;
+            case TLSv1_3_MINOR :
+                return WOLFSSL_TLSV1_3;
+            default:
+                break;
+        }
+    }
+
+    return VERSION_ERROR;
+}
+
+int wolfSSL_SetVersion(WOLFSSL* ssl, int version)
+{
+    word16 haveRSA = 1;
+    word16 havePSK = 0;
+    int    keySz   = 0;
+
+    WOLFSSL_ENTER("wolfSSL_SetVersion");
+
+    if (ssl == NULL) {
+        WOLFSSL_MSG("Bad function argument");
+        return BAD_FUNC_ARG;
+    }
+
+    switch (version) {
+#if defined(WOLFSSL_ALLOW_SSLV3) && !defined(NO_OLD_TLS)
+        case WOLFSSL_SSLV3:
+            ssl->version = MakeSSLv3();
+            break;
+#endif
+
+#ifndef NO_TLS
+    #ifndef NO_OLD_TLS
+        #ifdef WOLFSSL_ALLOW_TLSV10
+        case WOLFSSL_TLSV1:
+            ssl->version = MakeTLSv1();
+            break;
+        #endif
+
+        case WOLFSSL_TLSV1_1:
+            ssl->version = MakeTLSv1_1();
+            break;
+    #endif
+    #ifndef WOLFSSL_NO_TLS12
+        case WOLFSSL_TLSV1_2:
+            ssl->version = MakeTLSv1_2();
+            break;
+    #endif
+#endif
+#ifdef WOLFSSL_TLS13
+        case WOLFSSL_TLSV1_3:
+            ssl->version = MakeTLSv1_3();
+            break;
+
+#endif
+
+        default:
+            WOLFSSL_MSG("Bad function argument");
+            return BAD_FUNC_ARG;
+    }
+
+    #ifdef NO_RSA
+        haveRSA = 0;
+    #endif
+    #ifndef NO_PSK
+        havePSK = ssl->options.havePSK;
+    #endif
+    #ifndef NO_CERTS
+        keySz = ssl->buffers.keySz;
+    #endif
+
+    InitSuites(ssl->suites, ssl->version, keySz, haveRSA, havePSK,
+               ssl->options.haveDH, ssl->options.haveNTRU,
+               ssl->options.haveECDSAsig, ssl->options.haveECC,
+               ssl->options.haveStaticECC, ssl->options.side);
+
+    return WOLFSSL_SUCCESS;
+}
+#endif /* !leanpsk */
+
+
+#if !defined(NO_CERTS) || !defined(NO_SESSION_CACHE)
+
+/* Make a work from the front of random hash */
+static WC_INLINE word32 MakeWordFromHash(const byte* hashID)
+{
+    return ((word32)hashID[0] << 24) | ((word32)hashID[1] << 16) |
+        (hashID[2] <<  8) | hashID[3];
+}
+
+#endif /* !NO_CERTS || !NO_SESSION_CACHE */
+
+
+#ifndef NO_CERTS
+
+/* hash is the SHA digest of name, just use first 32 bits as hash */
+static WC_INLINE word32 HashSigner(const byte* hash)
+{
+    return MakeWordFromHash(hash) % CA_TABLE_SIZE;
+}
+
+
+/* does CA already exist on signer list */
+int AlreadySigner(WOLFSSL_CERT_MANAGER* cm, byte* hash)
+{
+    Signer* signers;
+    int     ret = 0;
+    word32  row;
+
+    if (cm == NULL || hash == NULL) {
+        return ret;
+    }
+
+    row = HashSigner(hash);
+
+    if (wc_LockMutex(&cm->caLock) != 0) {
+        return ret;
+    }
+    signers = cm->caTable[row];
+    while (signers) {
+        byte* subjectHash;
+
+    #ifndef NO_SKID
+        subjectHash = signers->subjectKeyIdHash;
+    #else
+        subjectHash = signers->subjectNameHash;
+    #endif
+
+        if (XMEMCMP(hash, subjectHash, SIGNER_DIGEST_SIZE) == 0) {
+            ret = 1; /* success */
+            break;
+        }
+        signers = signers->next;
+    }
+    wc_UnLockMutex(&cm->caLock);
+
+    return ret;
+}
+
+
+#ifdef WOLFSSL_TRUST_PEER_CERT
+/* hash is the SHA digest of name, just use first 32 bits as hash */
+static WC_INLINE word32 TrustedPeerHashSigner(const byte* hash)
+{
+    return MakeWordFromHash(hash) % TP_TABLE_SIZE;
+}
+
+/* does trusted peer already exist on signer list */
+int AlreadyTrustedPeer(WOLFSSL_CERT_MANAGER* cm, byte* hash)
+{
+    TrustedPeerCert* tp;
+    int     ret = 0;
+    word32  row = TrustedPeerHashSigner(hash);
+
+    if (wc_LockMutex(&cm->tpLock) != 0)
+        return  ret;
+    tp = cm->tpTable[row];
+    while (tp) {
+        byte* subjectHash;
+        #ifndef NO_SKID
+            subjectHash = tp->subjectKeyIdHash;
+        #else
+            subjectHash = tp->subjectNameHash;
+        #endif
+        if (XMEMCMP(hash, subjectHash, SIGNER_DIGEST_SIZE) == 0) {
+            ret = 1;
+            break;
+        }
+        tp = tp->next;
+    }
+    wc_UnLockMutex(&cm->tpLock);
+
+    return ret;
+}
+
+
+/* return Trusted Peer if found, otherwise NULL
+    type is what to match on
+ */
+TrustedPeerCert* GetTrustedPeer(void* vp, byte* hash, int type)
+{
+    WOLFSSL_CERT_MANAGER* cm = (WOLFSSL_CERT_MANAGER*)vp;
+    TrustedPeerCert* ret = NULL;
+    TrustedPeerCert* tp  = NULL;
+    word32  row;
+
+    if (cm == NULL || hash == NULL)
+        return NULL;
+
+    row = TrustedPeerHashSigner(hash);
+
+    if (wc_LockMutex(&cm->tpLock) != 0)
+        return ret;
+
+    tp = cm->tpTable[row];
+    while (tp) {
+        byte* subjectHash;
+        switch (type) {
+            #ifndef NO_SKID
+            case WC_MATCH_SKID:
+                subjectHash = tp->subjectKeyIdHash;
+                break;
+            #endif
+            case WC_MATCH_NAME:
+                subjectHash = tp->subjectNameHash;
+                break;
+            default:
+                WOLFSSL_MSG("Unknown search type");
+                wc_UnLockMutex(&cm->tpLock);
+                return NULL;
+        }
+        if (XMEMCMP(hash, subjectHash, SIGNER_DIGEST_SIZE) == 0) {
+            ret = tp;
+            break;
+        }
+        tp = tp->next;
+    }
+    wc_UnLockMutex(&cm->tpLock);
+
+    return ret;
+}
+
+
+int MatchTrustedPeer(TrustedPeerCert* tp, DecodedCert* cert)
+{
+    if (tp == NULL || cert == NULL)
+        return BAD_FUNC_ARG;
+
+    /* subject key id or subject hash has been compared when searching
+       tpTable for the cert from function GetTrustedPeer */
+
+    /* compare signatures */
+    if (tp->sigLen == cert->sigLength) {
+        if (XMEMCMP(tp->sig, cert->signature, cert->sigLength)) {
+            return WOLFSSL_FAILURE;
+        }
+    }
+    else {
+        return WOLFSSL_FAILURE;
+    }
+
+    return WOLFSSL_SUCCESS;
+}
+#endif /* WOLFSSL_TRUST_PEER_CERT */
+
+
+/* return CA if found, otherwise NULL */
+Signer* GetCA(void* vp, byte* hash)
+{
+    WOLFSSL_CERT_MANAGER* cm = (WOLFSSL_CERT_MANAGER*)vp;
+    Signer* ret = NULL;
+    Signer* signers;
+    word32  row = HashSigner(hash);
+
+    if (cm == NULL)
+        return NULL;
+
+    if (wc_LockMutex(&cm->caLock) != 0)
+        return ret;
+
+    signers = cm->caTable[row];
+    while (signers) {
+        byte* subjectHash;
+        #ifndef NO_SKID
+            subjectHash = signers->subjectKeyIdHash;
+        #else
+            subjectHash = signers->subjectNameHash;
+        #endif
+        if (XMEMCMP(hash, subjectHash, SIGNER_DIGEST_SIZE) == 0) {
+            ret = signers;
+            break;
+        }
+        signers = signers->next;
+    }
+    wc_UnLockMutex(&cm->caLock);
+
+    return ret;
+}
+
+
+#ifndef NO_SKID
+/* return CA if found, otherwise NULL. Walk through hash table. */
+Signer* GetCAByName(void* vp, byte* hash)
+{
+    WOLFSSL_CERT_MANAGER* cm = (WOLFSSL_CERT_MANAGER*)vp;
+    Signer* ret = NULL;
+    Signer* signers;
+    word32  row;
+
+    if (cm == NULL)
+        return NULL;
+
+    if (wc_LockMutex(&cm->caLock) != 0)
+        return ret;
+
+    for (row = 0; row < CA_TABLE_SIZE && ret == NULL; row++) {
+        signers = cm->caTable[row];
+        while (signers && ret == NULL) {
+            if (XMEMCMP(hash, signers->subjectNameHash,
+                        SIGNER_DIGEST_SIZE) == 0) {
+                ret = signers;
+            }
+            signers = signers->next;
+        }
+    }
+    wc_UnLockMutex(&cm->caLock);
+
+    return ret;
+}
+#endif
+
+
+#ifdef WOLFSSL_TRUST_PEER_CERT
+/* add a trusted peer cert to linked list */
+int AddTrustedPeer(WOLFSSL_CERT_MANAGER* cm, DerBuffer** pDer, int verify)
+{
+    int ret, row;
+    TrustedPeerCert* peerCert;
+    DecodedCert* cert;
+    DerBuffer*   der = *pDer;
+    byte* subjectHash = NULL;
+
+    WOLFSSL_MSG("Adding a Trusted Peer Cert");
+
+    cert = (DecodedCert*)XMALLOC(sizeof(DecodedCert), cm->heap,
+                                 DYNAMIC_TYPE_DCERT);
+    if (cert == NULL)
+        return MEMORY_E;
+
+    InitDecodedCert(cert, der->buffer, der->length, cm->heap);
+    if ((ret = ParseCert(cert, TRUSTED_PEER_TYPE, verify, cm)) != 0) {
+        FreeDecodedCert(cert);
+        XFREE(cert, NULL, DYNAMIC_TYPE_DCERT);
+        return ret;
+    }
+    WOLFSSL_MSG("\tParsed new trusted peer cert");
+
+    peerCert = (TrustedPeerCert*)XMALLOC(sizeof(TrustedPeerCert), cm->heap,
+                                                             DYNAMIC_TYPE_CERT);
+    if (peerCert == NULL) {
+        FreeDecodedCert(cert);
+        XFREE(cert, cm->heap, DYNAMIC_TYPE_DCERT);
+        return MEMORY_E;
+    }
+    XMEMSET(peerCert, 0, sizeof(TrustedPeerCert));
+
+#ifndef NO_SKID
+    if (cert->extAuthKeyIdSet) {
+        subjectHash = cert->extSubjKeyId;
+    }
+    else {
+        subjectHash = cert->subjectHash;
+    }
+#else
+    subjectHash = cert->subjectHash;
+#endif
+
+    #ifndef IGNORE_NAME_CONSTRAINTS
+        if (peerCert->permittedNames)
+            FreeNameSubtrees(peerCert->permittedNames, cm->heap);
+        if (peerCert->excludedNames)
+            FreeNameSubtrees(peerCert->excludedNames, cm->heap);
+    #endif
+
+    if (AlreadyTrustedPeer(cm, subjectHash)) {
+        WOLFSSL_MSG("\tAlready have this CA, not adding again");
+        FreeTrustedPeer(peerCert, cm->heap);
+        (void)ret;
+    }
+    else {
+        /* add trusted peer signature */
+        peerCert->sigLen = cert->sigLength;
+        peerCert->sig = XMALLOC(cert->sigLength, cm->heap,
+                                                        DYNAMIC_TYPE_SIGNATURE);
+        if (peerCert->sig == NULL) {
+            FreeDecodedCert(cert);
+            XFREE(cert, cm->heap, DYNAMIC_TYPE_DCERT);
+            FreeTrustedPeer(peerCert, cm->heap);
+            return MEMORY_E;
+        }
+        XMEMCPY(peerCert->sig, cert->signature, cert->sigLength);
+
+        /* add trusted peer name */
+        peerCert->nameLen = cert->subjectCNLen;
+        peerCert->name    = cert->subjectCN;
+        #ifndef IGNORE_NAME_CONSTRAINTS
+            peerCert->permittedNames = cert->permittedNames;
+            peerCert->excludedNames  = cert->excludedNames;
+        #endif
+
+        /* add SKID when available and hash of name */
+        #ifndef NO_SKID
+            XMEMCPY(peerCert->subjectKeyIdHash, cert->extSubjKeyId,
+                    SIGNER_DIGEST_SIZE);
+        #endif
+            XMEMCPY(peerCert->subjectNameHash, cert->subjectHash,
+                    SIGNER_DIGEST_SIZE);
+            peerCert->next    = NULL; /* If Key Usage not set, all uses valid. */
+            cert->subjectCN = 0;
+        #ifndef IGNORE_NAME_CONSTRAINTS
+            cert->permittedNames = NULL;
+            cert->excludedNames = NULL;
+        #endif
+
+        #ifndef NO_SKID
+            if (cert->extAuthKeyIdSet) {
+                row = TrustedPeerHashSigner(peerCert->subjectKeyIdHash);
+            }
+            else {
+                row = TrustedPeerHashSigner(peerCert->subjectNameHash);
+            }
+        #else
+            row = TrustedPeerHashSigner(peerCert->subjectNameHash);
+        #endif
+
+            if (wc_LockMutex(&cm->tpLock) == 0) {
+                peerCert->next = cm->tpTable[row];
+                cm->tpTable[row] = peerCert;   /* takes ownership */
+                wc_UnLockMutex(&cm->tpLock);
+            }
+            else {
+                WOLFSSL_MSG("\tTrusted Peer Cert Mutex Lock failed");
+                FreeDecodedCert(cert);
+                XFREE(cert, cm->heap, DYNAMIC_TYPE_DCERT);
+                FreeTrustedPeer(peerCert, cm->heap);
+                return BAD_MUTEX_E;
+            }
+        }
+
+    WOLFSSL_MSG("\tFreeing parsed trusted peer cert");
+    FreeDecodedCert(cert);
+    XFREE(cert, cm->heap, DYNAMIC_TYPE_DCERT);
+    WOLFSSL_MSG("\tFreeing der trusted peer cert");
+    FreeDer(&der);
+    WOLFSSL_MSG("\t\tOK Freeing der trusted peer cert");
+    WOLFSSL_LEAVE("AddTrustedPeer", ret);
+
+    return WOLFSSL_SUCCESS;
+}
+#endif /* WOLFSSL_TRUST_PEER_CERT */
+
+
+/* owns der, internal now uses too */
+/* type flag ids from user or from chain received during verify
+   don't allow chain ones to be added w/o isCA extension */
+int AddCA(WOLFSSL_CERT_MANAGER* cm, DerBuffer** pDer, int type, int verify)
+{
+    int         ret;
+    Signer*     signer = NULL;
+    word32      row;
+    byte*       subjectHash;
+#ifdef WOLFSSL_SMALL_STACK
+    DecodedCert* cert = NULL;
+#else
+    DecodedCert  cert[1];
+#endif
+    DerBuffer*   der = *pDer;
+
+    WOLFSSL_MSG("Adding a CA");
+
+    if (cm == NULL) {
+        FreeDer(pDer);
+        return BAD_FUNC_ARG;
+    }
+
+#ifdef WOLFSSL_SMALL_STACK
+    cert = (DecodedCert*)XMALLOC(sizeof(DecodedCert), NULL,
+                                 DYNAMIC_TYPE_DCERT);
+    if (cert == NULL) {
+        FreeDer(pDer);
+        return MEMORY_E;
+    }
+#endif
+
+    InitDecodedCert(cert, der->buffer, der->length, cm->heap);
+    ret = ParseCert(cert, CA_TYPE, verify, cm);
+    WOLFSSL_MSG("\tParsed new CA");
+
+#ifndef NO_SKID
+    subjectHash = cert->extSubjKeyId;
+#else
+    subjectHash = cert->subjectHash;
+#endif
+
+    /* check CA key size */
+    if (verify) {
+        switch (cert->keyOID) {
+            #ifndef NO_RSA
+            case RSAk:
+                if (cm->minRsaKeySz < 0 ||
+                                   cert->pubKeySize < (word16)cm->minRsaKeySz) {
+                    ret = RSA_KEY_SIZE_E;
+                    WOLFSSL_MSG("\tCA RSA key size error");
+                }
+                break;
+            #endif /* !NO_RSA */
+            #ifdef HAVE_ECC
+            case ECDSAk:
+                if (cm->minEccKeySz < 0 ||
+                                   cert->pubKeySize < (word16)cm->minEccKeySz) {
+                    ret = ECC_KEY_SIZE_E;
+                    WOLFSSL_MSG("\tCA ECC key size error");
+                }
+                break;
+            #endif /* HAVE_ECC */
+            #ifdef HAVE_ED25519
+            case ED25519k:
+                if (cm->minEccKeySz < 0 ||
+                                   ED25519_KEY_SIZE < (word16)cm->minEccKeySz) {
+                    ret = ECC_KEY_SIZE_E;
+                    WOLFSSL_MSG("\tCA ECC key size error");
+                }
+                break;
+            #endif /* HAVE_ED25519 */
+            #ifdef HAVE_ED448
+            case ED448k:
+                if (cm->minEccKeySz < 0 ||
+                                     ED448_KEY_SIZE < (word16)cm->minEccKeySz) {
+                    ret = ECC_KEY_SIZE_E;
+                    WOLFSSL_MSG("\tCA ECC key size error");
+                }
+                break;
+            #endif /* HAVE_ED448 */
+
+            default:
+                WOLFSSL_MSG("\tNo key size check done on CA");
+                break; /* no size check if key type is not in switch */
+        }
+    }
+
+    if (ret == 0 && cert->isCA == 0 && type != WOLFSSL_USER_CA) {
+        WOLFSSL_MSG("\tCan't add as CA if not actually one");
+        ret = NOT_CA_ERROR;
+    }
+#ifndef ALLOW_INVALID_CERTSIGN
+    else if (ret == 0 && cert->isCA == 1 && type != WOLFSSL_USER_CA &&
+        !cert->selfSigned && (cert->extKeyUsage & KEYUSE_KEY_CERT_SIGN) == 0) {
+        /* Intermediate CA certs are required to have the keyCertSign
+        * extension set. User loaded root certs are not. */
+        WOLFSSL_MSG("\tDoesn't have key usage certificate signing");
+        ret = NOT_CA_ERROR;
+    }
+#endif
+    else if (ret == 0 && AlreadySigner(cm, subjectHash)) {
+        WOLFSSL_MSG("\tAlready have this CA, not adding again");
+        (void)ret;
+    }
+    else if (ret == 0) {
+        /* take over signer parts */
+        signer = MakeSigner(cm->heap);
+        if (!signer)
+            ret = MEMORY_ERROR;
+    }
+    if (ret == 0 && signer != NULL) {
+    #ifdef WOLFSSL_SIGNER_DER_CERT
+        ret = AllocDer(&signer->derCert, der->length, der->type, NULL);
+    }
+    if (ret == 0 && signer != NULL) {
+        XMEMCPY(signer->derCert->buffer, der->buffer, der->length);
+    #endif
+        signer->keyOID         = cert->keyOID;
+        if (cert->pubKeyStored) {
+            signer->publicKey      = cert->publicKey;
+            signer->pubKeySize     = cert->pubKeySize;
+        }
+        if (cert->subjectCNStored) {
+            signer->nameLen        = cert->subjectCNLen;
+            signer->name           = cert->subjectCN;
+        }
+        signer->pathLength     = cert->pathLength;
+        signer->maxPathLen     = cert->maxPathLen;
+        signer->pathLengthSet  = cert->pathLengthSet;
+        signer->selfSigned     = cert->selfSigned;
+    #ifndef IGNORE_NAME_CONSTRAINTS
+        signer->permittedNames = cert->permittedNames;
+        signer->excludedNames  = cert->excludedNames;
+    #endif
+    #ifndef NO_SKID
+        XMEMCPY(signer->subjectKeyIdHash, cert->extSubjKeyId,
+                SIGNER_DIGEST_SIZE);
+    #endif
+        XMEMCPY(signer->subjectNameHash, cert->subjectHash,
+                SIGNER_DIGEST_SIZE);
+    #ifdef HAVE_OCSP
+        XMEMCPY(signer->subjectKeyHash, cert->subjectKeyHash,
+                KEYID_SIZE);
+    #endif
+        signer->keyUsage = cert->extKeyUsageSet ? cert->extKeyUsage
+                                                : 0xFFFF;
+        signer->next    = NULL; /* If Key Usage not set, all uses valid. */
+        cert->publicKey = 0;    /* in case lock fails don't free here.   */
+        cert->subjectCN = 0;
+    #ifndef IGNORE_NAME_CONSTRAINTS
+        cert->permittedNames = NULL;
+        cert->excludedNames = NULL;
+    #endif
+
+    #ifndef NO_SKID
+        row = HashSigner(signer->subjectKeyIdHash);
+    #else
+        row = HashSigner(signer->subjectNameHash);
+    #endif
+
+        if (wc_LockMutex(&cm->caLock) == 0) {
+            signer->next = cm->caTable[row];
+            cm->caTable[row] = signer;   /* takes ownership */
+            wc_UnLockMutex(&cm->caLock);
+            if (cm->caCacheCallback)
+                cm->caCacheCallback(der->buffer, (int)der->length, type);
+        }
+        else {
+            WOLFSSL_MSG("\tCA Mutex Lock failed");
+            ret = BAD_MUTEX_E;
+            FreeSigner(signer, cm->heap);
+        }
+    }
+#if defined(WOLFSSL_RENESAS_TSIP_TLS)
+    /* Verify CA by TSIP so that generated tsip key is going to be able to */
+    /* be used for peer's cert verification                                */
+    /* TSIP is only able to handle USER CA, and only one CA.               */
+    /* Therefore, it doesn't need to call TSIP again if there is already   */
+    /* verified CA.                                                        */
+    if ( ret == 0 && signer != NULL ) {
+        signer->cm_idx = row;
+        if (type == WOLFSSL_USER_CA && tsip_rootCAverified() == 0 ) {
+            if ((ret = tsip_tls_RootCertVerify(cert->source, cert->maxIdx,
+                 cert->sigCtx.pubkey_n_start, cert->sigCtx.pubkey_n_len - 1,
+                 cert->sigCtx.pubkey_e_start, cert->sigCtx.pubkey_e_len - 1,
+                 row/* cm index */))
+                != 0)
+                WOLFSSL_MSG("tsip_tls_RootCertVerify() failed");
+            else
+                WOLFSSL_MSG("tsip_tls_RootCertVerify() succeed");
+        }
+    }
+#endif
+    WOLFSSL_MSG("\tFreeing Parsed CA");
+    FreeDecodedCert(cert);
+#ifdef WOLFSSL_SMALL_STACK
+    XFREE(cert, NULL, DYNAMIC_TYPE_DCERT);
+#endif
+    WOLFSSL_MSG("\tFreeing der CA");
+    FreeDer(pDer);
+    WOLFSSL_MSG("\t\tOK Freeing der CA");
+
+    WOLFSSL_LEAVE("AddCA", ret);
+
+    return ret == 0 ? WOLFSSL_SUCCESS : ret;
+}
+
+#endif /* !NO_CERTS */
+
+
+#ifndef NO_SESSION_CACHE
+
+    /* basic config gives a cache with 33 sessions, adequate for clients and
+       embedded servers
+
+       TITAN_SESSION_CACHE allows just over 2 million sessions, for servers
+       with titanic amounts of memory with long session ID timeouts and high
+       levels of traffic.
+
+       HUGE_SESSION_CACHE yields 65,791 sessions, for servers under heavy load,
+       allows over 13,000 new sessions per minute or over 200 new sessions per
+       second
+
+       BIG_SESSION_CACHE yields 20,027 sessions
+
+       MEDIUM_SESSION_CACHE allows 1055 sessions, adequate for servers that
+       aren't under heavy load, basically allows 200 new sessions per minute
+
+       SMALL_SESSION_CACHE only stores 6 sessions, good for embedded clients
+       or systems where the default of nearly 3kB is too much RAM, this define
+       uses less than 500 bytes RAM
+
+       default SESSION_CACHE stores 33 sessions (no XXX_SESSION_CACHE defined)
+    */
+    #if defined(TITAN_SESSION_CACHE)
+        #define SESSIONS_PER_ROW 31
+        #define SESSION_ROWS 64937
+    #elif defined(HUGE_SESSION_CACHE)
+        #define SESSIONS_PER_ROW 11
+        #define SESSION_ROWS 5981
+    #elif defined(BIG_SESSION_CACHE)
+        #define SESSIONS_PER_ROW 7
+        #define SESSION_ROWS 2861
+    #elif defined(MEDIUM_SESSION_CACHE)
+        #define SESSIONS_PER_ROW 5
+        #define SESSION_ROWS 211
+    #elif defined(SMALL_SESSION_CACHE)
+        #define SESSIONS_PER_ROW 2
+        #define SESSION_ROWS 3
+    #else
+        #define SESSIONS_PER_ROW 3
+        #define SESSION_ROWS 11
+    #endif
+
+    typedef struct SessionRow {
+        int nextIdx;                           /* where to place next one   */
+        int totalCount;                        /* sessions ever on this row */
+        WOLFSSL_SESSION Sessions[SESSIONS_PER_ROW];
+    } SessionRow;
+
+    static WOLFSSL_GLOBAL SessionRow SessionCache[SESSION_ROWS];
+
+    #if defined(WOLFSSL_SESSION_STATS) && defined(WOLFSSL_PEAK_SESSIONS)
+        static WOLFSSL_GLOBAL word32 PeakSessions;
+    #endif
+
+    static WOLFSSL_GLOBAL wolfSSL_Mutex session_mutex; /* SessionCache mutex */
+
+    #ifndef NO_CLIENT_CACHE
+
+        typedef struct ClientSession {
+            word16 serverRow;            /* SessionCache Row id */
+            word16 serverIdx;            /* SessionCache Idx (column) */
+        } ClientSession;
+
+        typedef struct ClientRow {
+            int nextIdx;                /* where to place next one   */
+            int totalCount;             /* sessions ever on this row */
+            ClientSession Clients[SESSIONS_PER_ROW];
+        } ClientRow;
+
+        static WOLFSSL_GLOBAL ClientRow ClientCache[SESSION_ROWS];
+                                                     /* Client Cache */
+                                                     /* uses session mutex */
+    #endif  /* NO_CLIENT_CACHE */
+
+#endif /* NO_SESSION_CACHE */
+
+WOLFSSL_ABI
+int wolfSSL_Init(void)
+{
+    WOLFSSL_ENTER("wolfSSL_Init");
+
+    if (initRefCount == 0) {
+        /* Initialize crypto for use with TLS connection */
+        if (wolfCrypt_Init() != 0) {
+            WOLFSSL_MSG("Bad wolfCrypt Init");
+            return WC_INIT_E;
+        }
+
+#ifdef OPENSSL_EXTRA
+        if (wolfSSL_RAND_seed(NULL, 0) != WOLFSSL_SUCCESS) {
+            WOLFSSL_MSG("wolfSSL_RAND_Seed failed");
+            return WC_INIT_E;
+        }
+#endif
+
+#ifndef NO_SESSION_CACHE
+        if (wc_InitMutex(&session_mutex) != 0) {
+            WOLFSSL_MSG("Bad Init Mutex session");
+            return BAD_MUTEX_E;
+        }
+#endif
+        if (wc_InitMutex(&count_mutex) != 0) {
+            WOLFSSL_MSG("Bad Init Mutex count");
+            return BAD_MUTEX_E;
+        }
+    }
+
+    if (wc_LockMutex(&count_mutex) != 0) {
+        WOLFSSL_MSG("Bad Lock Mutex count");
+        return BAD_MUTEX_E;
+    }
+
+    initRefCount++;
+    wc_UnLockMutex(&count_mutex);
+
+    return WOLFSSL_SUCCESS;
+}
+
+
+
+#ifndef NO_CERTS
+
+/* process user cert chain to pass during the handshake */
+static int ProcessUserChain(WOLFSSL_CTX* ctx, const unsigned char* buff,
+                         long sz, int format, int type, WOLFSSL* ssl,
+                         long* used, EncryptedInfo* info, int verify)
+{
+    int ret = 0;
+    void* heap = wolfSSL_CTX_GetHeap(ctx, ssl);
+#ifdef WOLFSSL_TLS13
+    int cnt = 0;
+#endif
+
+    if ((type == CA_TYPE) && (ctx == NULL)) {
+        WOLFSSL_MSG("Need context for CA load");
+        return BAD_FUNC_ARG;
+    }
+
+    /* we may have a user cert chain, try to consume */
+    if ((type == CERT_TYPE || type == CA_TYPE) && (info->consumed < sz)) {
+    #ifdef WOLFSSL_SMALL_STACK
+        byte   staticBuffer[1];                 /* force heap usage */
+    #else
+        byte   staticBuffer[FILE_BUFFER_SIZE];  /* tmp chain buffer */
+    #endif
+        byte*  chainBuffer = staticBuffer;
+        int    dynamicBuffer = 0;
+        word32 bufferSz;
+        long   consumed = info->consumed;
+        word32 idx = 0;
+        int    gotOne = 0;
+
+        /* Calculate max possible size, including max headers */
+        bufferSz = (word32)(sz - consumed) + (CERT_HEADER_SZ * MAX_CHAIN_DEPTH);
+        if (bufferSz > sizeof(staticBuffer)) {
+            WOLFSSL_MSG("Growing Tmp Chain Buffer");
+            /* will shrink to actual size */
+            chainBuffer = (byte*)XMALLOC(bufferSz, heap, DYNAMIC_TYPE_FILE);
+            if (chainBuffer == NULL) {
+                return MEMORY_E;
+            }
+            dynamicBuffer = 1;
+        }
+
+        WOLFSSL_MSG("Processing Cert Chain");
+        while (consumed < sz) {
+            DerBuffer* part = NULL;
+            word32 remain = (word32)(sz - consumed);
+            info->consumed = 0;
+
+            if (format == WOLFSSL_FILETYPE_PEM) {
+            #ifdef WOLFSSL_PEM_TO_DER
+                ret = PemToDer(buff + consumed, remain, type, &part,
+                               heap, info, NULL);
+            #else
+                ret = NOT_COMPILED_IN;
+            #endif
+            }
+            else {
+                int length = remain;
+                if (format == WOLFSSL_FILETYPE_ASN1) {
+                    /* get length of der (read sequence) */
+                    word32 inOutIdx = 0;
+                    if (GetSequence(buff + consumed, &inOutIdx, &length,
+                            remain) < 0) {
+                        ret = ASN_NO_PEM_HEADER;
+                    }
+                    length += inOutIdx; /* include leading sequence */
+                }
+                info->consumed = length;
+                if (ret == 0) {
+                    ret = AllocDer(&part, length, type, heap);
+                    if (ret == 0) {
+                        XMEMCPY(part->buffer, buff + consumed, length);
+                    }
+                }
+            }
+            if (ret == 0) {
+                gotOne = 1;
+#ifdef WOLFSSL_TLS13
+                cnt++;
+#endif
+                if ((idx + part->length + CERT_HEADER_SZ) > bufferSz) {
+                    WOLFSSL_MSG("   Cert Chain bigger than buffer");
+                    ret = BUFFER_E;
+                }
+                else {
+                    c32to24(part->length, &chainBuffer[idx]);
+                    idx += CERT_HEADER_SZ;
+                    XMEMCPY(&chainBuffer[idx], part->buffer, part->length);
+                    idx += part->length;
+                    consumed  += info->consumed;
+                    if (used)
+                        *used += info->consumed;
+                }
+
+                /* add CA's to certificate manager */
+                if (type == CA_TYPE) {
+                    /* verify CA unless user set to no verify */
+                    ret = AddCA(ctx->cm, &part, WOLFSSL_USER_CA, verify);
+                    gotOne = 0; /* don't exit loop for CA type */
+                }
+            }
+
+            FreeDer(&part);
+
+            if (ret == ASN_NO_PEM_HEADER && gotOne) {
+                WOLFSSL_MSG("We got one good cert, so stuff at end ok");
+                break;
+            }
+
+            if (ret < 0) {
+                WOLFSSL_MSG("   Error in Cert in Chain");
+                if (dynamicBuffer)
+                    XFREE(chainBuffer, heap, DYNAMIC_TYPE_FILE);
+                return ret;
+            }
+            WOLFSSL_MSG("   Consumed another Cert in Chain");
+        }
+        WOLFSSL_MSG("Finished Processing Cert Chain");
+
+        /* only retain actual size used */
+        ret = 0;
+        if (idx > 0) {
+            if (ssl) {
+                if (ssl->buffers.weOwnCertChain) {
+                    FreeDer(&ssl->buffers.certChain);
+                }
+                ret = AllocDer(&ssl->buffers.certChain, idx, type, heap);
+                if (ret == 0) {
+                    XMEMCPY(ssl->buffers.certChain->buffer, chainBuffer,
+                            idx);
+                    ssl->buffers.weOwnCertChain = 1;
+                }
+            #ifdef WOLFSSL_TLS13
+                ssl->buffers.certChainCnt = cnt;
+            #endif
+            } else if (ctx) {
+                FreeDer(&ctx->certChain);
+                ret = AllocDer(&ctx->certChain, idx, type, heap);
+                if (ret == 0) {
+                    XMEMCPY(ctx->certChain->buffer, chainBuffer, idx);
+                }
+            #ifdef WOLFSSL_TLS13
+                ctx->certChainCnt = cnt;
+            #endif
+            }
+        }
+
+        if (dynamicBuffer)
+            XFREE(chainBuffer, heap, DYNAMIC_TYPE_FILE);
+    }
+
+    return ret;
+}
+
+static int ProcessBufferTryDecode(WOLFSSL_CTX* ctx, WOLFSSL* ssl, DerBuffer* der,
+    int* keySz, word32* idx, int* resetSuites, int* keyFormat, void* heap, int devId)
+{
+    int ret = 0;
+
+    (void)heap;
+    (void)devId;
+
+    if (ctx == NULL && ssl == NULL)
+        ret = BAD_FUNC_ARG;
+    if (!der || !keySz || !idx || !resetSuites || !keyFormat)
+        ret = BAD_FUNC_ARG;
+
+#ifndef NO_RSA
+    if (ret == 0 && (*keyFormat == 0 || *keyFormat == RSAk)) {
+        /* make sure RSA key can be used */
+    #ifdef WOLFSSL_SMALL_STACK
+        RsaKey* key;
+    #else
+        RsaKey  key[1];
+    #endif
+
+    #ifdef WOLFSSL_SMALL_STACK
+        key = (RsaKey*)XMALLOC(sizeof(RsaKey), heap, DYNAMIC_TYPE_RSA);
+        if (key == NULL)
+            return MEMORY_E;
+    #endif
+
+        ret = wc_InitRsaKey_ex(key, heap, devId);
+        if (ret == 0) {
+            *idx = 0;
+            if (wc_RsaPrivateKeyDecode(der->buffer, idx, key, der->length)
+                != 0) {
+            #if !defined(HAVE_ECC) && !defined(HAVE_ED25519) && \
+                                                            !defined(HAVE_ED448)
+                WOLFSSL_MSG("RSA decode failed and ECC/ED25519/ED448 not "
+                            "enabled to try");
+                ret = WOLFSSL_BAD_FILE;
+            #endif
+            }
+            else {
+                /* check that the size of the RSA key is enough */
+                int minRsaSz = ssl ? ssl->options.minRsaKeySz :
+                    ctx->minRsaKeySz;
+                *keySz = wc_RsaEncryptSize((RsaKey*)key);
+                if (*keySz < minRsaSz) {
+                    ret = RSA_KEY_SIZE_E;
+                    WOLFSSL_MSG("Private Key size too small");
+                }
+
+                if (ssl) {
+                    ssl->buffers.keyType = rsa_sa_algo;
+                    ssl->buffers.keySz = *keySz;
+                }
+                else {
+                    ctx->privateKeyType = rsa_sa_algo;
+                    ctx->privateKeySz = *keySz;
+                }
+
+                *keyFormat = RSAk;
+
+                if (ssl && ssl->options.side == WOLFSSL_SERVER_END) {
+                    ssl->options.haveStaticECC = 0;
+                    *resetSuites = 1;
+                }
+            }
+
+            wc_FreeRsaKey(key);
+        }
+
+    #ifdef WOLFSSL_SMALL_STACK
+        XFREE(key, heap, DYNAMIC_TYPE_RSA);
+    #endif
+    }
+#endif
+#ifdef HAVE_ECC
+    if (ret == 0 && (*keyFormat == 0 || *keyFormat == ECDSAk)) {
+        /* make sure ECC key can be used */
+    #ifdef WOLFSSL_SMALL_STACK
+        ecc_key* key;
+    #else
+        ecc_key  key[1];
+    #endif
+
+    #ifdef WOLFSSL_SMALL_STACK
+        key = (ecc_key*)XMALLOC(sizeof(ecc_key), heap, DYNAMIC_TYPE_ECC);
+        if (key == NULL)
+            return MEMORY_E;
+    #endif
+
+        if (wc_ecc_init_ex(key, heap, devId) == 0) {
+            *idx = 0;
+            if (wc_EccPrivateKeyDecode(der->buffer, idx, key,
+                                                        der->length) == 0) {
+                /* check for minimum ECC key size and then free */
+                int minKeySz = ssl ? ssl->options.minEccKeySz :
+                                                        ctx->minEccKeySz;
+                *keySz = wc_ecc_size(key);
+                if (*keySz < minKeySz) {
+                    WOLFSSL_MSG("ECC private key too small");
+                    ret = ECC_KEY_SIZE_E;
+                }
+
+                *keyFormat = ECDSAk;
+                if (ssl) {
+                    ssl->options.haveStaticECC = 1;
+                    ssl->buffers.keyType = ecc_dsa_sa_algo;
+                    ssl->buffers.keySz = *keySz;
+                }
+                else {
+                    ctx->haveStaticECC = 1;
+                    ctx->privateKeyType = ecc_dsa_sa_algo;
+                    ctx->privateKeySz = *keySz;
+                }
+
+                if (ssl && ssl->options.side == WOLFSSL_SERVER_END) {
+                    *resetSuites = 1;
+                }
+            }
+
+            wc_ecc_free(key);
+        }
+
+    #ifdef WOLFSSL_SMALL_STACK
+        XFREE(key, heap, DYNAMIC_TYPE_ECC);
+    #endif
+    }
+#endif /* HAVE_ECC */
+#ifdef HAVE_ED25519
+    if (ret == 0 && (*keyFormat == 0 || *keyFormat == ED25519k)) {
+        /* make sure Ed25519 key can be used */
+    #ifdef WOLFSSL_SMALL_STACK
+        ed25519_key* key;
+    #else
+        ed25519_key  key[1];
+    #endif
+
+    #ifdef WOLFSSL_SMALL_STACK
+        key = (ed25519_key*)XMALLOC(sizeof(ed25519_key), heap,
+                                                      DYNAMIC_TYPE_ED25519);
+        if (key == NULL)
+            return MEMORY_E;
+    #endif
+
+        ret = wc_ed25519_init(key);
+        if (ret == 0) {
+            *idx = 0;
+            if (wc_Ed25519PrivateKeyDecode(der->buffer, idx, key,
+                                                        der->length) == 0) {
+                /* check for minimum key size and then free */
+                int minKeySz = ssl ? ssl->options.minEccKeySz :
+                                                           ctx->minEccKeySz;
+                *keySz = ED25519_KEY_SIZE;
+                if (*keySz < minKeySz) {
+                    WOLFSSL_MSG("ED25519 private key too small");
+                    ret = ECC_KEY_SIZE_E;
+                }
+                if (ret == 0) {
+                    if (ssl) {
+                        ssl->buffers.keyType = ed25519_sa_algo;
+                        ssl->buffers.keySz = *keySz;
+                    }
+                    else if (ctx) {
+                        ctx->privateKeyType = ed25519_sa_algo;
+                        ctx->privateKeySz = *keySz;
+                    }
+
+                    *keyFormat = ED25519k;
+                    if (ssl && ssl->options.side == WOLFSSL_SERVER_END) {
+                        *resetSuites = 1;
+                    }
+                }
+            }
+
+            wc_ed25519_free(key);
+        }
+
+    #ifdef WOLFSSL_SMALL_STACK
+        XFREE(key, heap, DYNAMIC_TYPE_ED25519);
+    #endif
+    }
+#endif /* HAVE_ED25519 */
+#ifdef HAVE_ED448
+    if (ret == 0 && (*keyFormat == 0 || *keyFormat == ED448k)) {
+        /* make sure Ed448 key can be used */
+    #ifdef WOLFSSL_SMALL_STACK
+        ed448_key* key = NULL;
+    #else
+        ed448_key  key[1];
+    #endif
+
+    #ifdef WOLFSSL_SMALL_STACK
+        key = (ed448_key*)XMALLOC(sizeof(ed448_key), heap, DYNAMIC_TYPE_ED448);
+        if (key == NULL)
+            return MEMORY_E;
+    #endif
+
+        ret = wc_ed448_init(key);
+        if (ret == 0) {
+            *idx = 0;
+            if (wc_Ed448PrivateKeyDecode(der->buffer, idx, key,
+                                                            der->length) != 0) {
+                ret = WOLFSSL_BAD_FILE;
+            }
+
+            if (ret == 0) {
+                /* check for minimum key size and then free */
+                int minKeySz = ssl ? ssl->options.minEccKeySz :
+                                                               ctx->minEccKeySz;
+                *keySz = ED448_KEY_SIZE;
+                if (*keySz < minKeySz) {
+                    WOLFSSL_MSG("ED448 private key too small");
+                    ret = ECC_KEY_SIZE_E;
+                }
+            }
+            if (ret == 0) {
+                if (ssl) {
+                    ssl->buffers.keyType = ed448_sa_algo;
+                    ssl->buffers.keySz = *keySz;
+                }
+                else if (ctx) {
+                    ctx->privateKeyType = ed448_sa_algo;
+                    ctx->privateKeySz = *keySz;
+                }
+
+                *keyFormat = ED448k;
+                if (ssl && ssl->options.side == WOLFSSL_SERVER_END) {
+                    *resetSuites = 1;
+                }
+            }
+
+            wc_ed448_free(key);
+        }
+
+    #ifdef WOLFSSL_SMALL_STACK
+        XFREE(key, heap, DYNAMIC_TYPE_ED448);
+    #endif
+    }
+#endif /* HAVE_ED448 */
+    return ret;
+}
+
+/* process the buffer buff, length sz, into ctx of format and type
+   used tracks bytes consumed, userChain specifies a user cert chain
+   to pass during the handshake */
+int ProcessBuffer(WOLFSSL_CTX* ctx, const unsigned char* buff,
+                         long sz, int format, int type, WOLFSSL* ssl,
+                         long* used, int userChain, int verify)
+{
+    DerBuffer*    der = NULL;        /* holds DER or RAW (for NTRU) */
+    int           ret = 0;
+    int           done = 0;
+    int           keyFormat = 0;
+    int           resetSuites = 0;
+    void*         heap = wolfSSL_CTX_GetHeap(ctx, ssl);
+    int           devId = wolfSSL_CTX_GetDevId(ctx, ssl);
+    word32        idx = 0;
+    int           keySz = 0;
+#if (defined(WOLFSSL_ENCRYPTED_KEYS) && !defined(NO_PWDBASED)) || \
+     defined(HAVE_PKCS8)
+    word32        algId = 0;
+#endif
+#ifdef WOLFSSL_SMALL_STACK
+    EncryptedInfo* info = NULL;
+#else
+    EncryptedInfo  info[1];
+#endif
+
+    (void)devId;
+    (void)idx;
+    (void)keySz;
+
+    if (used)
+        *used = sz;     /* used bytes default to sz, PEM chain may shorten*/
+
+    /* check args */
+    if (format != WOLFSSL_FILETYPE_ASN1 && format != WOLFSSL_FILETYPE_PEM
+                                    && format != WOLFSSL_FILETYPE_RAW)
+        return WOLFSSL_BAD_FILETYPE;
+
+    if (ctx == NULL && ssl == NULL)
+        return BAD_FUNC_ARG;
+
+#ifdef WOLFSSL_SMALL_STACK
+    info = (EncryptedInfo*)XMALLOC(sizeof(EncryptedInfo), heap,
+                                   DYNAMIC_TYPE_ENCRYPTEDINFO);
+    if (info == NULL)
+        return MEMORY_E;
+#endif
+
+    XMEMSET(info, 0, sizeof(EncryptedInfo));
+#if defined(WOLFSSL_ENCRYPTED_KEYS) && !defined(NO_PWDBASED)
+    if (ctx) {
+        info->passwd_cb       = ctx->passwd_cb;
+        info->passwd_userdata = ctx->passwd_userdata;
+    }
+#endif
+
+    if (format == WOLFSSL_FILETYPE_PEM) {
+    #ifdef WOLFSSL_PEM_TO_DER
+        ret = PemToDer(buff, sz, type, &der, heap, info, &keyFormat);
+    #else
+        ret = NOT_COMPILED_IN;
+    #endif
+    }
+    else {
+        /* ASN1 (DER) or RAW (NTRU) */
+        int length = (int)sz;
+        if (format == WOLFSSL_FILETYPE_ASN1) {
+            /* get length of der (read sequence or octet string) */
+            word32 inOutIdx = 0;
+            if (GetSequence(buff, &inOutIdx, &length, (word32)sz) >= 0) {
+                length += inOutIdx; /* include leading sequence */
+            }
+            /* get length using octect string (allowed for private key types) */
+            else if (type == PRIVATEKEY_TYPE &&
+                    GetOctetString(buff, &inOutIdx, &length, (word32)sz) >= 0) {
+                length += inOutIdx; /* include leading oct string */
+            }
+            else {
+                ret = ASN_PARSE_E;
+            }
+        }
+
+        info->consumed = length;
+
+        if (ret == 0) {
+            ret = AllocDer(&der, (word32)length, type, heap);
+            if (ret == 0) {
+                XMEMCPY(der->buffer, buff, length);
+            }
+
+        #ifdef HAVE_PKCS8
+            /* if private key try and remove PKCS8 header */
+            if (type == PRIVATEKEY_TYPE) {
+                if ((ret = ToTraditional_ex(der->buffer, der->length, &algId)) > 0) {
+                    /* Found PKCS8 header */
+                    /* ToTraditional_ex moves buff and returns adjusted length */
+                    der->length = ret;
+                }
+                ret = 0; /* failures should be ignored */
+            }
+        #endif
+        }
+    }
+
+    if (used) {
+        *used = info->consumed;
+    }
+
+    /* process user chain */
+    if (ret >= 0) {
+        /* Chain should have server cert first, then intermediates, then root.
+         * First certificate in chain is processed below after ProcessUserChain
+         *   and is loaded into ssl->buffers.certificate.
+         * Remainder are processed using ProcessUserChain and are loaded into
+         *   ssl->buffers.certChain. */
+        if (userChain) {
+            ret = ProcessUserChain(ctx, buff, sz, format, type, ssl, used, info,
+                                   verify);
+        }
+    }
+
+    /* info is only used for private key with DER or PEM, so free now */
+    if (ret < 0 || type != PRIVATEKEY_TYPE || format == WOLFSSL_FILETYPE_RAW) {
+    #ifdef WOLFSSL_SMALL_STACK
+        XFREE(info, heap, DYNAMIC_TYPE_ENCRYPTEDINFO);
+    #endif
+    }
+
+    /* check for error */
+    if (ret < 0) {
+        FreeDer(&der);
+        done = 1;
+    }
+
+    if (done == 1) {
+        /* No operation, just skip the next section */
+    }
+    /* Handle DER owner */
+    else if (type == CA_TYPE) {
+        if (ctx == NULL) {
+            WOLFSSL_MSG("Need context for CA load");
+            FreeDer(&der);
+            return BAD_FUNC_ARG;
+        }
+        /* verify CA unless user set to no verify */
+        ret = AddCA(ctx->cm, &der, WOLFSSL_USER_CA, verify);
+        done = 1;
+    }
+#ifdef WOLFSSL_TRUST_PEER_CERT
+    else if (type == TRUSTED_PEER_TYPE) {
+        if (ctx == NULL) {
+            WOLFSSL_MSG("Need context for trusted peer cert load");
+            FreeDer(&der);
+            return BAD_FUNC_ARG;
+        }
+        /* add trusted peer cert */
+        ret = AddTrustedPeer(ctx->cm, &der, !ctx->verifyNone);
+        done = 1;
+    }
+#endif /* WOLFSSL_TRUST_PEER_CERT */
+    else if (type == CERT_TYPE) {
+        if (ssl) {
+             /* Make sure previous is free'd */
+            if (ssl->buffers.weOwnCert) {
+                FreeDer(&ssl->buffers.certificate);
+            #ifdef KEEP_OUR_CERT
+                FreeX509(ssl->ourCert);
+                if (ssl->ourCert) {
+                    XFREE(ssl->ourCert, ssl->heap, DYNAMIC_TYPE_X509);
+                    ssl->ourCert = NULL;
+                }
+            #endif
+            }
+            ssl->buffers.certificate = der;
+        #ifdef KEEP_OUR_CERT
+            ssl->keepCert = 1; /* hold cert for ssl lifetime */
+        #endif
+            ssl->buffers.weOwnCert = 1;
+        }
+        else if (ctx) {
+            FreeDer(&ctx->certificate); /* Make sure previous is free'd */
+        #ifdef KEEP_OUR_CERT
+            if (ctx->ourCert) {
+                if (ctx->ownOurCert) {
+                    FreeX509(ctx->ourCert);
+                    XFREE(ctx->ourCert, ctx->heap, DYNAMIC_TYPE_X509);
+                }
+                ctx->ourCert = NULL;
+            }
+        #endif
+            ctx->certificate = der;
+        }
+    }
+    else if (type == PRIVATEKEY_TYPE) {
+        if (ssl) {
+             /* Make sure previous is free'd */
+            if (ssl->buffers.weOwnKey) {
+                FreeDer(&ssl->buffers.key);
+            }
+            ssl->buffers.key = der;
+            ssl->buffers.weOwnKey = 1;
+        }
+        else if (ctx) {
+            FreeDer(&ctx->privateKey);
+            ctx->privateKey = der;
+        }
+    }
+    else {
+        FreeDer(&der);
+        return WOLFSSL_BAD_CERTTYPE;
+    }
+
+    if (done == 1) {
+        /* No operation, just skip the next section */
+    }
+    else if (type == PRIVATEKEY_TYPE && format != WOLFSSL_FILETYPE_RAW) {
+    #if defined(WOLFSSL_ENCRYPTED_KEYS) || defined(HAVE_PKCS8)
+        keyFormat = algId;
+    #endif
+
+        ret = ProcessBufferTryDecode(ctx, ssl, der, &keySz, &idx, &resetSuites,
+                &keyFormat, heap, devId);
+
+    #if defined(WOLFSSL_ENCRYPTED_KEYS) && !defined(NO_PWDBASED)
+        /* for WOLFSSL_FILETYPE_PEM, PemToDer manages the decryption */
+        /* If private key type PKCS8 header wasn't already removed (algoId == 0) */
+        if ((ret != 0 || keyFormat == 0)
+            && format != WOLFSSL_FILETYPE_PEM && info->passwd_cb && algId == 0)
+        {
+            int   passwordSz = NAME_SZ;
+        #ifndef WOLFSSL_SMALL_STACK
+            char  password[NAME_SZ];
+        #else
+            char* password = (char*)XMALLOC(passwordSz, heap, DYNAMIC_TYPE_STRING);
+            if (password == NULL) {
+            #ifdef WOLFSSL_SMALL_STACK
+                XFREE(info, heap, DYNAMIC_TYPE_ENCRYPTEDINFO);
+            #endif
+                FreeDer(&der);
+                return MEMORY_E;
+            }
+        #endif
+            /* get password */
+            ret = info->passwd_cb(password, passwordSz, PEM_PASS_READ,
+                info->passwd_userdata);
+            if (ret >= 0) {
+                passwordSz = ret;
+
+                /* PKCS8 decrypt */
+                ret = ToTraditionalEnc(der->buffer, der->length,
+                                       password, passwordSz, &algId);
+                if (ret >= 0) {
+                    der->length = ret;
+                }
+                /* ignore failures and try parsing as unencrypted */
+
+                ForceZero(password, passwordSz);
+            }
+
+        #ifdef WOLFSSL_SMALL_STACK
+            XFREE(password, heap, DYNAMIC_TYPE_STRING);
+        #endif
+            ret = ProcessBufferTryDecode(ctx, ssl, der, &keySz, &idx,
+                &resetSuites, &keyFormat, heap, devId);
+        }
+    #endif /* WOLFSSL_ENCRYPTED_KEYS && !NO_PWDBASED */
+
+    #ifdef WOLFSSL_SMALL_STACK
+        XFREE(info, heap, DYNAMIC_TYPE_ENCRYPTEDINFO);
+    #endif
+
+        if (ret != 0)
+            return ret;
+        if (keyFormat == 0)
+            return WOLFSSL_BAD_FILE;
+
+        (void)devId;
+    }
+    else if (type == CERT_TYPE) {
+    #ifdef WOLFSSL_SMALL_STACK
+        DecodedCert* cert;
+    #else
+        DecodedCert  cert[1];
+    #endif
+    #ifdef HAVE_PK_CALLBACKS
+        int keyType = 0;
+    #endif
+
+    #ifdef WOLFSSL_SMALL_STACK
+        cert = (DecodedCert*)XMALLOC(sizeof(DecodedCert), heap,
+                                     DYNAMIC_TYPE_DCERT);
+        if (cert == NULL)
+            return MEMORY_E;
+    #endif
+
+        WOLFSSL_MSG("Checking cert signature type");
+        InitDecodedCert(cert, der->buffer, der->length, heap);
+
+        if (DecodeToKey(cert, 0) < 0) {
+            WOLFSSL_MSG("Decode to key failed");
+            FreeDecodedCert(cert);
+        #ifdef WOLFSSL_SMALL_STACK
+            XFREE(cert, heap, DYNAMIC_TYPE_DCERT);
+        #endif
+            return WOLFSSL_BAD_FILE;
+        }
+
+        if (ssl && ssl->options.side == WOLFSSL_SERVER_END) {
+            resetSuites = 1;
+        }
+        if (ssl && ssl->ctx->haveECDSAsig) {
+            WOLFSSL_MSG("SSL layer setting cert, CTX had ECDSA, turning off");
+            ssl->options.haveECDSAsig = 0;   /* may turn back on next */
+        }
+
+        switch (cert->signatureOID) {
+            case CTC_SHAwECDSA:
+            case CTC_SHA256wECDSA:
+            case CTC_SHA384wECDSA:
+            case CTC_SHA512wECDSA:
+                WOLFSSL_MSG("ECDSA cert signature");
+                if (ssl)
+                    ssl->options.haveECDSAsig = 1;
+                else if (ctx)
+                    ctx->haveECDSAsig = 1;
+                break;
+            case CTC_ED25519:
+                WOLFSSL_MSG("ED25519 cert signature");
+                if (ssl)
+                    ssl->options.haveECDSAsig = 1;
+                else if (ctx)
+                    ctx->haveECDSAsig = 1;
+                break;
+            case CTC_ED448:
+                WOLFSSL_MSG("ED448 cert signature");
+                if (ssl)
+                    ssl->options.haveECDSAsig = 1;
+                else if (ctx)
+                    ctx->haveECDSAsig = 1;
+                break;
+            default:
+                WOLFSSL_MSG("Not ECDSA cert signature");
+                break;
+        }
+
+    #if defined(HAVE_ECC) || defined(HAVE_ED25519) || defined(HAVE_ED448)
+        if (ssl) {
+            ssl->pkCurveOID = cert->pkCurveOID;
+        #ifndef WC_STRICT_SIG
+            if (cert->keyOID == ECDSAk) {
+                ssl->options.haveECC = 1;
+            }
+            #ifdef HAVE_ED25519
+                else if (cert->keyOID == ED25519k) {
+                    ssl->options.haveECC = 1;
+                }
+            #endif
+            #ifdef HAVE_ED448
+                else if (cert->keyOID == ED448k) {
+                    ssl->options.haveECC = 1;
+                }
+            #endif
+        #else
+            ssl->options.haveECC = ssl->options.haveECDSAsig;
+        #endif
+        }
+        else if (ctx) {
+            ctx->pkCurveOID = cert->pkCurveOID;
+        #ifndef WC_STRICT_SIG
+            if (cert->keyOID == ECDSAk) {
+                ctx->haveECC = 1;
+            }
+            #ifdef HAVE_ED25519
+                else if (cert->keyOID == ED25519k) {
+                    ctx->haveECC = 1;
+                }
+            #endif
+            #ifdef HAVE_ED448
+                else if (cert->keyOID == ED448k) {
+                    ctx->haveECC = 1;
+                }
+            #endif
+        #else
+            ctx->haveECC = ctx->haveECDSAsig;
+        #endif
+        }
+    #endif
+
+        /* check key size of cert unless specified not to */
+        switch (cert->keyOID) {
+        #ifndef NO_RSA
+            case RSAk:
+            #ifdef HAVE_PK_CALLBACKS
+                keyType = rsa_sa_algo;
+            #endif
+            #ifdef HAVE_PKCS11
+                if (ctx) {
+                    ctx->privateKeyType = rsa_sa_algo;
+                }
+                else {
+                    ssl->buffers.keyType = rsa_sa_algo;
+                }
+            #endif
+                /* Determine RSA key size by parsing public key */
+                idx = 0;
+                ret = wc_RsaPublicKeyDecode_ex(cert->publicKey, &idx,
+                    cert->pubKeySize, NULL, (word32*)&keySz, NULL, NULL);
+                if (ret < 0)
+                    break;
+
+                if (ssl && !ssl->options.verifyNone) {
+                    if (ssl->options.minRsaKeySz < 0 ||
+                          keySz < (int)ssl->options.minRsaKeySz) {
+                        ret = RSA_KEY_SIZE_E;
+                        WOLFSSL_MSG("Certificate RSA key size too small");
+                    }
+                }
+                else if (ctx && !ctx->verifyNone) {
+                    if (ctx->minRsaKeySz < 0 ||
+                                  keySz < (int)ctx->minRsaKeySz) {
+                        ret = RSA_KEY_SIZE_E;
+                        WOLFSSL_MSG("Certificate RSA key size too small");
+                    }
+                }
+                break;
+        #endif /* !NO_RSA */
+        #ifdef HAVE_ECC
+            case ECDSAk:
+            #ifdef HAVE_PK_CALLBACKS
+                keyType = ecc_dsa_sa_algo;
+            #endif
+            #ifdef HAVE_PKCS11
+                if (ctx) {
+                    ctx->privateKeyType = ecc_dsa_sa_algo;
+                }
+                else {
+                    ssl->buffers.keyType = ecc_dsa_sa_algo;
+                }
+            #endif
+                /* Determine ECC key size based on curve */
+                keySz = wc_ecc_get_curve_size_from_id(
+                    wc_ecc_get_oid(cert->pkCurveOID, NULL, NULL));
+
+                if (ssl && !ssl->options.verifyNone) {
+                    if (ssl->options.minEccKeySz < 0 ||
+                          keySz < (int)ssl->options.minEccKeySz) {
+                        ret = ECC_KEY_SIZE_E;
+                        WOLFSSL_MSG("Certificate ECC key size error");
+                    }
+                }
+                else if (ctx && !ctx->verifyNone) {
+                    if (ctx->minEccKeySz < 0 ||
+                                  keySz < (int)ctx->minEccKeySz) {
+                        ret = ECC_KEY_SIZE_E;
+                        WOLFSSL_MSG("Certificate ECC key size error");
+                    }
+                }
+                break;
+        #endif /* HAVE_ECC */
+        #ifdef HAVE_ED25519
+            case ED25519k:
+            #ifdef HAVE_PK_CALLBACKS
+                keyType = ed25519_sa_algo;
+            #endif
+            #ifdef HAVE_PKCS11
+                if (ctx) {
+                    ctx->privateKeyType = ed25519_sa_algo;
+                }
+                else {
+                    ssl->buffers.keyType = ed25519_sa_algo;
+                }
+            #endif
+                /* ED25519 is fixed key size */
+                keySz = ED25519_KEY_SIZE;
+                if (ssl && !ssl->options.verifyNone) {
+                    if (ssl->options.minEccKeySz < 0 ||
+                          keySz < (int)ssl->options.minEccKeySz) {
+                        ret = ECC_KEY_SIZE_E;
+                        WOLFSSL_MSG("Certificate Ed key size error");
+                    }
+                }
+                else if (ctx && !ctx->verifyNone) {
+                    if (ctx->minEccKeySz < 0 ||
+                                  keySz < (int)ctx->minEccKeySz) {
+                        ret = ECC_KEY_SIZE_E;
+                        WOLFSSL_MSG("Certificate ECC key size error");
+                    }
+                }
+                break;
+        #endif /* HAVE_ED25519 */
+        #ifdef HAVE_ED448
+            case ED448k:
+            #ifdef HAVE_PK_CALLBACKS
+                keyType = ed448_sa_algo;
+            #endif
+            #ifdef HAVE_PKCS11
+                if (ctx) {
+                    ctx->privateKeyType = ed448_sa_algo;
+                }
+                else {
+                    ssl->buffers.keyType = ed448_sa_algo;
+                }
+            #endif
+                /* ED448 is fixed key size */
+                keySz = ED448_KEY_SIZE;
+                if (ssl && !ssl->options.verifyNone) {
+                    if (ssl->options.minEccKeySz < 0 ||
+                          keySz < (int)ssl->options.minEccKeySz) {
+                        ret = ECC_KEY_SIZE_E;
+                        WOLFSSL_MSG("Certificate Ed key size error");
+                    }
+                }
+                else if (ctx && !ctx->verifyNone) {
+                    if (ctx->minEccKeySz < 0 ||
+                                  keySz < (int)ctx->minEccKeySz) {
+                        ret = ECC_KEY_SIZE_E;
+                        WOLFSSL_MSG("Certificate ECC key size error");
+                    }
+                }
+                break;
+        #endif /* HAVE_ED448 */
+
+            default:
+                WOLFSSL_MSG("No key size check done on certificate");
+                break; /* do no check if not a case for the key */
+        }
+
+    #ifdef HAVE_PK_CALLBACKS
+        if (ssl && ssl->buffers.keyType == 0) {
+            ssl->buffers.keyType = keyType;
+            ssl->buffers.keySz = keySz;
+        }
+        else if (ctx && ctx->privateKeyType == 0) {
+            ctx->privateKeyType = keyType;
+            ctx->privateKeySz = keySz;
+        }
+    #endif
+
+        FreeDecodedCert(cert);
+    #ifdef WOLFSSL_SMALL_STACK
+        XFREE(cert, heap, DYNAMIC_TYPE_DCERT);
+    #endif
+
+        if (ret != 0) {
+            done = 1;
+        }
+    }
+
+    if (done == 1) {
+    #ifndef NO_WOLFSSL_CM_VERIFY
+        if ((type == CA_TYPE) || (type == CERT_TYPE)) {
+            /* Call to over-ride status */
+            if ((ctx != NULL) && (ctx->cm != NULL) &&
+                (ctx->cm->verifyCallback != NULL)) {
+                ret = CM_VerifyBuffer_ex(ctx->cm, buff,
+                        sz, format, (ret == WOLFSSL_SUCCESS ? 0 : ret));
+            }
+        }
+    #endif /* NO_WOLFSSL_CM_VERIFY */
+
+        return ret;
+    }
+
+
+    if (ssl && resetSuites) {
+        word16 havePSK = 0;
+        word16 haveRSA = 0;
+
+        #ifndef NO_PSK
+        if (ssl->options.havePSK) {
+            havePSK = 1;
+        }
+        #endif
+        #ifndef NO_RSA
+            haveRSA = 1;
+        #endif
+        #ifndef NO_CERTS
+            keySz = ssl->buffers.keySz;
+        #endif
+
+        /* let's reset suites */
+        InitSuites(ssl->suites, ssl->version, keySz, haveRSA,
+                   havePSK, ssl->options.haveDH, ssl->options.haveNTRU,
+                   ssl->options.haveECDSAsig, ssl->options.haveECC,
+                   ssl->options.haveStaticECC, ssl->options.side);
+    }
+
+    return WOLFSSL_SUCCESS;
+}
+
+
+/* CA PEM file for verification, may have multiple/chain certs to process */
+static int ProcessChainBuffer(WOLFSSL_CTX* ctx, const unsigned char* buff,
+                        long sz, int format, int type, WOLFSSL* ssl, int verify)
+{
+    long used   = 0;
+    int  ret    = 0;
+    int  gotOne = 0;
+
+    WOLFSSL_MSG("Processing CA PEM file");
+    while (used < sz) {
+        long consumed = 0;
+
+        ret = ProcessBuffer(ctx, buff + used, sz - used, format, type, ssl,
+                            &consumed, 0, verify);
+
+        if (ret < 0) {
+#if defined(WOLFSSL_WPAS) && defined(HAVE_CRL)
+            DerBuffer*    der = NULL;
+            EncryptedInfo info;
+
+            WOLFSSL_MSG("Trying a CRL");
+            if (PemToDer(buff + used, sz - used, CRL_TYPE, &der, NULL, &info,
+                                                                   NULL) == 0) {
+                WOLFSSL_MSG("   Processed a CRL");
+                wolfSSL_CertManagerLoadCRLBuffer(ctx->cm, der->buffer,
+                                            der->length, WOLFSSL_FILETYPE_ASN1);
+                FreeDer(&der);
+                used += info.consumed;
+                continue;
+            }
+#endif
+
+            if (consumed > 0) { /* Made progress in file */
+                WOLFSSL_ERROR(ret);
+                WOLFSSL_MSG("CA Parse failed, with progress in file.");
+                WOLFSSL_MSG("Search for other certs in file");
+            }
+            else {
+                WOLFSSL_MSG("CA Parse failed, no progress in file.");
+                WOLFSSL_MSG("Do not continue search for other certs in file");
+                break;
+            }
+        }
+        else {
+            WOLFSSL_MSG("   Processed a CA");
+            gotOne = 1;
+        }
+        used += consumed;
+    }
+
+    if (gotOne) {
+        WOLFSSL_MSG("Processed at least one valid CA. Other stuff OK");
+        return WOLFSSL_SUCCESS;
+    }
+    return ret;
+}
+
+
+static WC_INLINE WOLFSSL_METHOD* cm_pick_method(void)
+{
+    #ifndef NO_WOLFSSL_CLIENT
+        #if !defined(NO_OLD_TLS) && defined(WOLFSSL_ALLOW_SSLV3)
+            return wolfSSLv3_client_method();
+        #elif !defined(NO_OLD_TLS) && defined(WOLFSSL_ALLOW_TLSV10)
+            return wolfTLSv1_client_method();
+        #elif !defined(NO_OLD_TLS)
+            return wolfTLSv1_1_client_method();
+        #elif !defined(WOLFSSL_NO_TLS12)
+            return wolfTLSv1_2_client_method();
+        #elif defined(WOLFSSL_TLS13)
+            return wolfTLSv1_3_client_method();
+        #else
+            return NULL;
+        #endif
+    #elif !defined(NO_WOLFSSL_SERVER)
+        #if !defined(NO_OLD_TLS) && defined(WOLFSSL_ALLOW_SSLV3)
+            return wolfSSLv3_server_method();
+        #elif !defined(NO_OLD_TLS) && defined(WOLFSSL_ALLOW_TLSV10)
+            return wolfTLSv1_server_method();
+        #elif !defined(NO_OLD_TLS)
+            return wolfTLSv1_1_server_method();
+        #elif !defined(WOLFSSL_NO_TLS12)
+            return wolfTLSv1_2_server_method();
+        #elif defined(WOLFSSL_TLS13)
+            return wolfTLSv1_3_server_method();
+        #else
+            return NULL;
+        #endif
+    #else
+        return NULL;
+    #endif
+}
+
+
+/* like load verify locations, 1 for success, < 0 for error */
+int wolfSSL_CertManagerLoadCABuffer(WOLFSSL_CERT_MANAGER* cm,
+                                   const unsigned char* in, long sz, int format)
+{
+    int ret = WOLFSSL_FATAL_ERROR;
+    WOLFSSL_CTX* tmp;
+
+    WOLFSSL_ENTER("wolfSSL_CertManagerLoadCABuffer");
+
+    if (cm == NULL) {
+        WOLFSSL_MSG("No CertManager error");
+        return ret;
+    }
+    tmp = wolfSSL_CTX_new(cm_pick_method());
+
+    if (tmp == NULL) {
+        WOLFSSL_MSG("CTX new failed");
+        return ret;
+    }
+
+    /* for tmp use */
+    wolfSSL_CertManagerFree(tmp->cm);
+    tmp->cm = cm;
+
+    ret = wolfSSL_CTX_load_verify_buffer(tmp, in, sz, format);
+
+    /* don't loose our good one */
+    tmp->cm = NULL;
+    wolfSSL_CTX_free(tmp);
+
+    return ret;
+}
+
+#ifdef HAVE_CRL
+
+int wolfSSL_CertManagerLoadCRLBuffer(WOLFSSL_CERT_MANAGER* cm,
+                                   const unsigned char* buff, long sz, int type)
+{
+    WOLFSSL_ENTER("wolfSSL_CertManagerLoadCRLBuffer");
+    if (cm == NULL)
+        return BAD_FUNC_ARG;
+
+    if (cm->crl == NULL) {
+        if (wolfSSL_CertManagerEnableCRL(cm, 0) != WOLFSSL_SUCCESS) {
+            WOLFSSL_MSG("Enable CRL failed");
+            return WOLFSSL_FATAL_ERROR;
+        }
+    }
+
+    return BufferLoadCRL(cm->crl, buff, sz, type, VERIFY);
+}
+
+int wolfSSL_CertManagerFreeCRL(WOLFSSL_CERT_MANAGER* cm)
+{
+    WOLFSSL_ENTER("wolfSSL_CertManagerFreeCRL");
+    if (cm == NULL)
+        return BAD_FUNC_ARG;
+    if (cm->crl != NULL){
+        FreeCRL(cm->crl, 1);
+        cm->crl = NULL;
+    }
+    return WOLFSSL_SUCCESS;
+}
+
+int wolfSSL_CTX_LoadCRLBuffer(WOLFSSL_CTX* ctx, const unsigned char* buff,
+                              long sz, int type)
+{
+    WOLFSSL_ENTER("wolfSSL_CTX_LoadCRLBuffer");
+
+    if (ctx == NULL)
+        return BAD_FUNC_ARG;
+
+    return wolfSSL_CertManagerLoadCRLBuffer(ctx->cm, buff, sz, type);
+}
+
+
+int wolfSSL_LoadCRLBuffer(WOLFSSL* ssl, const unsigned char* buff,
+                          long sz, int type)
+{
+    WOLFSSL_ENTER("wolfSSL_LoadCRLBuffer");
+
+    if (ssl == NULL || ssl->ctx == NULL)
+        return BAD_FUNC_ARG;
+
+    return wolfSSL_CertManagerLoadCRLBuffer(ssl->ctx->cm, buff, sz, type);
+}
+
+
+#endif /* HAVE_CRL */
+
+/* turn on CRL if off and compiled in, set options */
+int wolfSSL_CertManagerEnableCRL(WOLFSSL_CERT_MANAGER* cm, int options)
+{
+    int ret = WOLFSSL_SUCCESS;
+
+    (void)options;
+
+    WOLFSSL_ENTER("wolfSSL_CertManagerEnableCRL");
+    if (cm == NULL)
+        return BAD_FUNC_ARG;
+
+    #ifdef HAVE_CRL
+        if (cm->crl == NULL) {
+            cm->crl = (WOLFSSL_CRL*)XMALLOC(sizeof(WOLFSSL_CRL), cm->heap,
+                                            DYNAMIC_TYPE_CRL);
+            if (cm->crl == NULL)
+                return MEMORY_E;
+
+            if (InitCRL(cm->crl, cm) != 0) {
+                WOLFSSL_MSG("Init CRL failed");
+                FreeCRL(cm->crl, 1);
+                cm->crl = NULL;
+                return WOLFSSL_FAILURE;
+            }
+
+        #ifdef HAVE_CRL_IO
+            cm->crl->crlIOCb = EmbedCrlLookup;
+        #endif
+        }
+
+        cm->crlEnabled = 1;
+        if (options & WOLFSSL_CRL_CHECKALL)
+            cm->crlCheckAll = 1;
+    #else
+        ret = NOT_COMPILED_IN;
+    #endif
+
+    return ret;
+}
+
+
+int wolfSSL_CertManagerDisableCRL(WOLFSSL_CERT_MANAGER* cm)
+{
+    WOLFSSL_ENTER("wolfSSL_CertManagerDisableCRL");
+    if (cm == NULL)
+        return BAD_FUNC_ARG;
+
+    cm->crlEnabled = 0;
+
+    return WOLFSSL_SUCCESS;
+}
+
+#ifndef NO_WOLFSSL_CM_VERIFY
+void wolfSSL_CertManagerSetVerify(WOLFSSL_CERT_MANAGER* cm, VerifyCallback vc)
+{
+    WOLFSSL_ENTER("wolfSSL_CertManagerSetVerify");
+    if (cm == NULL)
+        return;
+
+    cm->verifyCallback = vc;
+}
+#endif /* NO_WOLFSSL_CM_VERIFY */
+
+/* Verify the certificate, WOLFSSL_SUCCESS for ok, < 0 for error */
+int CM_VerifyBuffer_ex(WOLFSSL_CERT_MANAGER* cm, const byte* buff,
+                                    long sz, int format, int err_val)
+{
+    int ret = 0;
+    DerBuffer* der = NULL;
+#ifdef WOLFSSL_SMALL_STACK
+    DecodedCert* cert;
+#else
+    DecodedCert  cert[1];
+#endif
+
+    WOLFSSL_ENTER("wolfSSL_CertManagerVerifyBuffer");
+
+#ifdef WOLFSSL_SMALL_STACK
+    cert = (DecodedCert*)XMALLOC(sizeof(DecodedCert), cm->heap,
+                                 DYNAMIC_TYPE_DCERT);
+    if (cert == NULL)
+        return MEMORY_E;
+#endif
+
+    if (format == WOLFSSL_FILETYPE_PEM) {
+#ifdef WOLFSSL_PEM_TO_DER
+        ret = PemToDer(buff, sz, CERT_TYPE, &der, cm->heap, NULL, NULL);
+        if (ret != 0) {
+            FreeDer(&der);
+        #ifdef WOLFSSL_SMALL_STACK
+            XFREE(cert, cm->heap, DYNAMIC_TYPE_DCERT);
+        #endif
+            return ret;
+        }
+        InitDecodedCert(cert, der->buffer, der->length, cm->heap);
+#else
+        ret = NOT_COMPILED_IN;
+#endif
+    }
+    else {
+        InitDecodedCert(cert, (byte*)buff, (word32)sz, cm->heap);
+    }
+
+    if (ret == 0)
+        ret = ParseCertRelative(cert, CERT_TYPE, 1, cm);
+
+#if defined(OPENSSL_ALL) || defined(WOLFSSL_QT)
+    /* ret needs to be self-singer error for Qt compat */
+    if (ret == ASN_NO_SIGNER_E && cert->selfSigned)
+        ret = ASN_SELF_SIGNED_E;
+#endif
+
+#ifdef HAVE_CRL
+    if (ret == 0 && cm->crlEnabled)
+        ret = CheckCertCRL(cm->crl, cert);
+#endif
+
+#ifndef NO_WOLFSSL_CM_VERIFY
+    /* if verify callback has been set */
+    if (cm->verifyCallback) {
+        buffer certBuf;
+    #ifdef WOLFSSL_SMALL_STACK
+        ProcPeerCertArgs* args;
+        args = (ProcPeerCertArgs*)XMALLOC(
+            sizeof(ProcPeerCertArgs), cm->heap, DYNAMIC_TYPE_TMP_BUFFER);
+        if (args == NULL) {
+            XFREE(cert, cm->heap, DYNAMIC_TYPE_DCERT);
+            return MEMORY_E;
+        }
+    #else
+        ProcPeerCertArgs  args[1];
+    #endif
+
+        certBuf.buffer = (byte*)buff;
+        certBuf.length = (unsigned int)sz;
+        XMEMSET(args, 0, sizeof(ProcPeerCertArgs));
+
+        args->totalCerts = 1;
+        args->certs = &certBuf;
+        args->dCert = cert;
+        args->dCertInit = 1;
+
+        if (err_val != 0) {
+            ret = err_val;
+        }
+        ret = DoVerifyCallback(cm, NULL, ret, args);
+    #ifdef WOLFSSL_SMALL_STACK
+        XFREE(args, cm->heap, DYNAMIC_TYPE_TMP_BUFFER);
+    #endif
+    }
+#else
+    (void)err_val;
+#endif
+
+    FreeDecodedCert(cert);
+    FreeDer(&der);
+#ifdef WOLFSSL_SMALL_STACK
+    XFREE(cert, cm->heap, DYNAMIC_TYPE_DCERT);
+#endif
+
+    return ret == 0 ? WOLFSSL_SUCCESS : ret;
+}
+
+/* Verify the certificate, WOLFSSL_SUCCESS for ok, < 0 for error */
+int wolfSSL_CertManagerVerifyBuffer(WOLFSSL_CERT_MANAGER* cm, const byte* buff,
+                                    long sz, int format)
+{
+    return CM_VerifyBuffer_ex(cm, buff, sz, format, 0);
+}
+/* turn on OCSP if off and compiled in, set options */
+int wolfSSL_CertManagerEnableOCSP(WOLFSSL_CERT_MANAGER* cm, int options)
+{
+    int ret = WOLFSSL_SUCCESS;
+
+    (void)options;
+
+    WOLFSSL_ENTER("wolfSSL_CertManagerEnableOCSP");
+    if (cm == NULL)
+        return BAD_FUNC_ARG;
+
+    #ifdef HAVE_OCSP
+        if (cm->ocsp == NULL) {
+            cm->ocsp = (WOLFSSL_OCSP*)XMALLOC(sizeof(WOLFSSL_OCSP), cm->heap,
+                                              DYNAMIC_TYPE_OCSP);
+            if (cm->ocsp == NULL)
+                return MEMORY_E;
+
+            if (InitOCSP(cm->ocsp, cm) != 0) {
+                WOLFSSL_MSG("Init OCSP failed");
+                FreeOCSP(cm->ocsp, 1);
+                cm->ocsp = NULL;
+                return WOLFSSL_FAILURE;
+            }
+        }
+        cm->ocspEnabled = 1;
+        if (options & WOLFSSL_OCSP_URL_OVERRIDE)
+            cm->ocspUseOverrideURL = 1;
+        if (options & WOLFSSL_OCSP_NO_NONCE)
+            cm->ocspSendNonce = 0;
+        else
+            cm->ocspSendNonce = 1;
+        if (options & WOLFSSL_OCSP_CHECKALL)
+            cm->ocspCheckAll = 1;
+        #ifndef WOLFSSL_USER_IO
+            cm->ocspIOCb = EmbedOcspLookup;
+            cm->ocspRespFreeCb = EmbedOcspRespFree;
+            cm->ocspIOCtx = cm->heap;
+        #endif /* WOLFSSL_USER_IO */
+    #else
+        ret = NOT_COMPILED_IN;
+    #endif
+
+    return ret;
+}
+
+
+int wolfSSL_CertManagerDisableOCSP(WOLFSSL_CERT_MANAGER* cm)
+{
+    WOLFSSL_ENTER("wolfSSL_CertManagerDisableOCSP");
+    if (cm == NULL)
+        return BAD_FUNC_ARG;
+
+    cm->ocspEnabled = 0;
+
+    return WOLFSSL_SUCCESS;
+}
+
+/* turn on OCSP Stapling if off and compiled in, set options */
+int wolfSSL_CertManagerEnableOCSPStapling(WOLFSSL_CERT_MANAGER* cm)
+{
+    int ret = WOLFSSL_SUCCESS;
+
+    WOLFSSL_ENTER("wolfSSL_CertManagerEnableOCSPStapling");
+
+    if (cm == NULL)
+        return BAD_FUNC_ARG;
+
+#if defined(HAVE_CERTIFICATE_STATUS_REQUEST) \
+ || defined(HAVE_CERTIFICATE_STATUS_REQUEST_V2)
+    #ifndef NO_WOLFSSL_SERVER
+    if (cm->ocsp_stapling == NULL) {
+        cm->ocsp_stapling = (WOLFSSL_OCSP*)XMALLOC(sizeof(WOLFSSL_OCSP),
+                                               cm->heap, DYNAMIC_TYPE_OCSP);
+        if (cm->ocsp_stapling == NULL)
+            return MEMORY_E;
+
+        if (InitOCSP(cm->ocsp_stapling, cm) != 0) {
+            WOLFSSL_MSG("Init OCSP failed");
+            FreeOCSP(cm->ocsp_stapling, 1);
+            cm->ocsp_stapling = NULL;
+            return WOLFSSL_FAILURE;
+        }
+    }
+
+    #ifndef WOLFSSL_USER_IO
+        cm->ocspIOCb = EmbedOcspLookup;
+        cm->ocspRespFreeCb = EmbedOcspRespFree;
+        cm->ocspIOCtx = cm->heap;
+    #endif /* WOLFSSL_USER_IO */
+    #endif /* NO_WOLFSSL_SERVER */
+    cm->ocspStaplingEnabled = 1;
+#else
+    ret = NOT_COMPILED_IN;
+#endif
+
+    return ret;
+}
+
+int wolfSSL_CertManagerDisableOCSPStapling(WOLFSSL_CERT_MANAGER* cm)
+{
+    int ret = WOLFSSL_SUCCESS;
+
+    WOLFSSL_ENTER("wolfSSL_CertManagerDisableOCSPStapling");
+
+    if (cm == NULL)
+        return BAD_FUNC_ARG;
+
+#if defined(HAVE_CERTIFICATE_STATUS_REQUEST) \
+ || defined(HAVE_CERTIFICATE_STATUS_REQUEST_V2)
+    cm->ocspStaplingEnabled = 0;
+#else
+    ret = NOT_COMPILED_IN;
+#endif
+    return ret;
+}
+
+#ifdef HAVE_OCSP
+/* check CRL if enabled, WOLFSSL_SUCCESS  */
+int wolfSSL_CertManagerCheckOCSP(WOLFSSL_CERT_MANAGER* cm, byte* der, int sz)
+{
+    int ret;
+#ifdef WOLFSSL_SMALL_STACK
+    DecodedCert* cert = NULL;
+#else
+    DecodedCert  cert[1];
+#endif
+
+    WOLFSSL_ENTER("wolfSSL_CertManagerCheckOCSP");
+
+    if (cm == NULL)
+        return BAD_FUNC_ARG;
+
+    if (cm->ocspEnabled == 0)
+        return WOLFSSL_SUCCESS;
+
+#ifdef WOLFSSL_SMALL_STACK
+    cert = (DecodedCert*)XMALLOC(sizeof(DecodedCert), NULL, DYNAMIC_TYPE_DCERT);
+    if (cert == NULL)
+        return MEMORY_E;
+#endif
+
+    InitDecodedCert(cert, der, sz, NULL);
+
+    if ((ret = ParseCertRelative(cert, CERT_TYPE, VERIFY_OCSP, cm)) != 0) {
+        WOLFSSL_MSG("ParseCert failed");
+    }
+    else if ((ret = CheckCertOCSP(cm->ocsp, cert, NULL)) != 0) {
+        WOLFSSL_MSG("CheckCertOCSP failed");
+    }
+
+    FreeDecodedCert(cert);
+#ifdef WOLFSSL_SMALL_STACK
+    XFREE(cert, NULL, DYNAMIC_TYPE_DCERT);
+#endif
+
+    return ret == 0 ? WOLFSSL_SUCCESS : ret;
+}
+
+WOLFSSL_API int wolfSSL_CertManagerCheckOCSPResponse(WOLFSSL_CERT_MANAGER *cm,
+                                                    byte *response, int responseSz, buffer *responseBuffer,
+                                                    CertStatus *status, OcspEntry *entry, OcspRequest *ocspRequest)
+{
+    int ret;
+
+    WOLFSSL_ENTER("wolfSSL_CertManagerCheckOCSP_Staple");
+    if (cm == NULL || response == NULL)
+        return BAD_FUNC_ARG;
+    if (cm->ocspEnabled == 0)
+        return WOLFSSL_SUCCESS;
+
+    ret = CheckOcspResponse(cm->ocsp, response, responseSz, responseBuffer, status,
+                        entry, ocspRequest);
+
+    return ret == 0 ? WOLFSSL_SUCCESS : ret;
+}
+
+int wolfSSL_CertManagerSetOCSPOverrideURL(WOLFSSL_CERT_MANAGER* cm,
+                                          const char* url)
+{
+    WOLFSSL_ENTER("wolfSSL_CertManagerSetOCSPOverrideURL");
+    if (cm == NULL)
+        return BAD_FUNC_ARG;
+
+    XFREE(cm->ocspOverrideURL, cm->heap, DYNAMIC_TYPE_URL);
+    if (url != NULL) {
+        int urlSz = (int)XSTRLEN(url) + 1;
+        cm->ocspOverrideURL = (char*)XMALLOC(urlSz, cm->heap, DYNAMIC_TYPE_URL);
+        if (cm->ocspOverrideURL != NULL) {
+            XMEMCPY(cm->ocspOverrideURL, url, urlSz);
+        }
+        else
+            return MEMORY_E;
+    }
+    else
+        cm->ocspOverrideURL = NULL;
+
+    return WOLFSSL_SUCCESS;
+}
+
+
+int wolfSSL_CertManagerSetOCSP_Cb(WOLFSSL_CERT_MANAGER* cm,
+                        CbOCSPIO ioCb, CbOCSPRespFree respFreeCb, void* ioCbCtx)
+{
+    WOLFSSL_ENTER("wolfSSL_CertManagerSetOCSP_Cb");
+    if (cm == NULL)
+        return BAD_FUNC_ARG;
+
+    cm->ocspIOCb = ioCb;
+    cm->ocspRespFreeCb = respFreeCb;
+    cm->ocspIOCtx = ioCbCtx;
+
+    return WOLFSSL_SUCCESS;
+}
+
+
+int wolfSSL_EnableOCSP(WOLFSSL* ssl, int options)
+{
+    WOLFSSL_ENTER("wolfSSL_EnableOCSP");
+    if (ssl)
+        return wolfSSL_CertManagerEnableOCSP(ssl->ctx->cm, options);
+    else
+        return BAD_FUNC_ARG;
+}
+
+int wolfSSL_DisableOCSP(WOLFSSL* ssl)
+{
+    WOLFSSL_ENTER("wolfSSL_DisableOCSP");
+    if (ssl)
+        return wolfSSL_CertManagerDisableOCSP(ssl->ctx->cm);
+    else
+        return BAD_FUNC_ARG;
+}
+
+
+int wolfSSL_EnableOCSPStapling(WOLFSSL* ssl)
+{
+    WOLFSSL_ENTER("wolfSSL_EnableOCSPStapling");
+    if (ssl)
+        return wolfSSL_CertManagerEnableOCSPStapling(ssl->ctx->cm);
+    else
+        return BAD_FUNC_ARG;
+}
+
+int wolfSSL_DisableOCSPStapling(WOLFSSL* ssl)
+{
+    WOLFSSL_ENTER("wolfSSL_DisableOCSPStapling");
+    if (ssl)
+        return wolfSSL_CertManagerDisableOCSPStapling(ssl->ctx->cm);
+    else
+        return BAD_FUNC_ARG;
+}
+
+int wolfSSL_SetOCSP_OverrideURL(WOLFSSL* ssl, const char* url)
+{
+    WOLFSSL_ENTER("wolfSSL_SetOCSP_OverrideURL");
+    if (ssl)
+        return wolfSSL_CertManagerSetOCSPOverrideURL(ssl->ctx->cm, url);
+    else
+        return BAD_FUNC_ARG;
+}
+
+
+int wolfSSL_SetOCSP_Cb(WOLFSSL* ssl,
+                        CbOCSPIO ioCb, CbOCSPRespFree respFreeCb, void* ioCbCtx)
+{
+    WOLFSSL_ENTER("wolfSSL_SetOCSP_Cb");
+    if (ssl) {
+        ssl->ocspIOCtx = ioCbCtx; /* use SSL specific ioCbCtx */
+        return wolfSSL_CertManagerSetOCSP_Cb(ssl->ctx->cm,
+                                             ioCb, respFreeCb, NULL);
+    }
+    else
+        return BAD_FUNC_ARG;
+}
+
+
+int wolfSSL_CTX_EnableOCSP(WOLFSSL_CTX* ctx, int options)
+{
+    WOLFSSL_ENTER("wolfSSL_CTX_EnableOCSP");
+    if (ctx)
+        return wolfSSL_CertManagerEnableOCSP(ctx->cm, options);
+    else
+        return BAD_FUNC_ARG;
+}
+
+
+int wolfSSL_CTX_DisableOCSP(WOLFSSL_CTX* ctx)
+{
+    WOLFSSL_ENTER("wolfSSL_CTX_DisableOCSP");
+    if (ctx)
+        return wolfSSL_CertManagerDisableOCSP(ctx->cm);
+    else
+        return BAD_FUNC_ARG;
+}
+
+
+int wolfSSL_CTX_SetOCSP_OverrideURL(WOLFSSL_CTX* ctx, const char* url)
+{
+    WOLFSSL_ENTER("wolfSSL_SetOCSP_OverrideURL");
+    if (ctx)
+        return wolfSSL_CertManagerSetOCSPOverrideURL(ctx->cm, url);
+    else
+        return BAD_FUNC_ARG;
+}
+
+
+int wolfSSL_CTX_SetOCSP_Cb(WOLFSSL_CTX* ctx, CbOCSPIO ioCb,
+                           CbOCSPRespFree respFreeCb, void* ioCbCtx)
+{
+    WOLFSSL_ENTER("wolfSSL_CTX_SetOCSP_Cb");
+    if (ctx)
+        return wolfSSL_CertManagerSetOCSP_Cb(ctx->cm, ioCb,
+                                             respFreeCb, ioCbCtx);
+    else
+        return BAD_FUNC_ARG;
+}
+
+#if defined(HAVE_CERTIFICATE_STATUS_REQUEST) \
+ || defined(HAVE_CERTIFICATE_STATUS_REQUEST_V2)
+int wolfSSL_CTX_EnableOCSPStapling(WOLFSSL_CTX* ctx)
+{
+    WOLFSSL_ENTER("wolfSSL_CTX_EnableOCSPStapling");
+    if (ctx)
+        return wolfSSL_CertManagerEnableOCSPStapling(ctx->cm);
+    else
+        return BAD_FUNC_ARG;
+}
+
+int wolfSSL_CTX_DisableOCSPStapling(WOLFSSL_CTX* ctx)
+{
+    WOLFSSL_ENTER("wolfSSL_CTX_DisableOCSPStapling");
+    if (ctx)
+        return wolfSSL_CertManagerDisableOCSPStapling(ctx->cm);
+    else
+        return BAD_FUNC_ARG;
+}
+#endif /* HAVE_CERTIFICATE_STATUS_REQUEST || HAVE_CERTIFICATE_STATUS_REQUEST_V2 */
+
+#endif /* HAVE_OCSP */
+
+/* macro to get verify settings for AddCA */
+#define GET_VERIFY_SETTING_CTX(ctx) \
+    (ctx && ctx->verifyNone ? NO_VERIFY : VERIFY)
+#define GET_VERIFY_SETTING_SSL(ssl) \
+    (ssl && ssl->options.verifyNone ? NO_VERIFY : VERIFY)
+
+#ifndef NO_FILESYSTEM
+
+/* process a file with name fname into ctx of format and type
+   userChain specifies a user certificate chain to pass during handshake */
+int ProcessFile(WOLFSSL_CTX* ctx, const char* fname, int format, int type,
+                WOLFSSL* ssl, int userChain, WOLFSSL_CRL* crl, int verify)
+{
+#ifdef WOLFSSL_SMALL_STACK
+    byte   staticBuffer[1]; /* force heap usage */
+#else
+    byte   staticBuffer[FILE_BUFFER_SIZE];
+#endif
+    byte*  myBuffer = staticBuffer;
+    int    dynamic = 0;
+    int    ret;
+    long   sz = 0;
+    XFILE  file;
+    void*  heapHint = wolfSSL_CTX_GetHeap(ctx, ssl);
+    const char* header = NULL;
+    const char* footer = NULL;
+
+    (void)crl;
+    (void)heapHint;
+
+    if (fname == NULL) return WOLFSSL_BAD_FILE;
+
+    file = XFOPEN(fname, "rb");
+    if (file == XBADFILE) return WOLFSSL_BAD_FILE;
+    if (XFSEEK(file, 0, XSEEK_END) != 0) {
+        XFCLOSE(file);
+        return WOLFSSL_BAD_FILE;
+    }
+    sz = XFTELL(file);
+    XREWIND(file);
+
+    if (sz > MAX_WOLFSSL_FILE_SIZE || sz <= 0) {
+        WOLFSSL_MSG("ProcessFile file size error");
+        XFCLOSE(file);
+        return WOLFSSL_BAD_FILE;
+    }
+
+    if (sz > (long)sizeof(staticBuffer)) {
+        WOLFSSL_MSG("Getting dynamic buffer");
+        myBuffer = (byte*)XMALLOC(sz, heapHint, DYNAMIC_TYPE_FILE);
+        if (myBuffer == NULL) {
+            XFCLOSE(file);
+            return WOLFSSL_BAD_FILE;
+        }
+        dynamic = 1;
+    }
+
+    if ( (ret = (int)XFREAD(myBuffer, 1, sz, file)) != sz)
+        ret = WOLFSSL_BAD_FILE;
+    else {
+        /* Try to detect type by parsing cert header and footer */
+        if (type == DETECT_CERT_TYPE) {
+            if (wc_PemGetHeaderFooter(CA_TYPE, &header, &footer) == 0 &&
+               (XSTRNSTR((char*)myBuffer, header, (int)sz) != NULL)) {
+                type = CA_TYPE;
+            }
+#ifdef HAVE_CRL
+            else if (wc_PemGetHeaderFooter(CRL_TYPE, &header, &footer) == 0 &&
+                    (XSTRNSTR((char*)myBuffer, header, (int)sz) != NULL)) {
+                type = CRL_TYPE;
+            }
+#endif
+            else if (wc_PemGetHeaderFooter(CERT_TYPE, &header, &footer) == 0 &&
+                    (XSTRNSTR((char*)myBuffer, header, (int)sz) != NULL)) {
+                type = CERT_TYPE;
+            }
+            else {
+                WOLFSSL_MSG("Failed to detect certificate type");
+                if (dynamic)
+                    XFREE(myBuffer, heapHint, DYNAMIC_TYPE_FILE);
+                XFCLOSE(file);
+                return WOLFSSL_BAD_CERTTYPE;
+            }
+        }
+        if ((type == CA_TYPE || type == TRUSTED_PEER_TYPE)
+                                          && format == WOLFSSL_FILETYPE_PEM) {
+            ret = ProcessChainBuffer(ctx, myBuffer, sz, format, type, ssl,
+                                     verify);
+        }
+#ifdef HAVE_CRL
+        else if (type == CRL_TYPE)
+            ret = BufferLoadCRL(crl, myBuffer, sz, format, verify);
+#endif
+        else
+            ret = ProcessBuffer(ctx, myBuffer, sz, format, type, ssl, NULL,
+                                userChain, verify);
+    }
+
+    XFCLOSE(file);
+    if (dynamic)
+        XFREE(myBuffer, heapHint, DYNAMIC_TYPE_FILE);
+
+    return ret;
+}
+
+/* loads file then loads each file in path, no c_rehash */
+int wolfSSL_CTX_load_verify_locations_ex(WOLFSSL_CTX* ctx, const char* file,
+                                     const char* path, word32 flags)
+{
+    int ret = WOLFSSL_SUCCESS;
+#ifndef NO_WOLFSSL_DIR
+    int fileRet;
+    int successCount = 0;
+    int failCount = 0;
+#endif
+    int verify;
+
+    WOLFSSL_MSG("wolfSSL_CTX_load_verify_locations_ex");
+
+    if (ctx == NULL || (file == NULL && path == NULL)) {
+        return WOLFSSL_FAILURE;
+    }
+
+    verify = GET_VERIFY_SETTING_CTX(ctx);
+    if (flags & WOLFSSL_LOAD_FLAG_DATE_ERR_OKAY)
+        verify = VERIFY_SKIP_DATE;
+
+    if (file) {
+        ret = ProcessFile(ctx, file, WOLFSSL_FILETYPE_PEM, CA_TYPE, NULL, 0,
+                          NULL, verify);
+#ifndef NO_WOLFSSL_DIR
+        if (ret == WOLFSSL_SUCCESS)
+            successCount++;
+#endif
+    }
+
+    if (ret == WOLFSSL_SUCCESS && path) {
+#ifndef NO_WOLFSSL_DIR
+        char* name = NULL;
+    #ifdef WOLFSSL_SMALL_STACK
+        ReadDirCtx* readCtx;
+        readCtx = (ReadDirCtx*)XMALLOC(sizeof(ReadDirCtx), ctx->heap,
+                                                       DYNAMIC_TYPE_DIRCTX);
+        if (readCtx == NULL)
+            return MEMORY_E;
+    #else
+        ReadDirCtx readCtx[1];
+    #endif
+
+        /* try to load each regular file in path */
+        fileRet = wc_ReadDirFirst(readCtx, path, &name);
+        while (fileRet == 0 && name) {
+            WOLFSSL_MSG(name); /* log file name */
+            ret = ProcessFile(ctx, name, WOLFSSL_FILETYPE_PEM, CA_TYPE,
+                              NULL, 0, NULL, verify);
+            if (ret != WOLFSSL_SUCCESS) {
+                /* handle flags for ignoring errors, skipping expired certs or
+                   by PEM certificate header error */
+                if ( (flags & WOLFSSL_LOAD_FLAG_IGNORE_ERR) ||
+                    ((flags & WOLFSSL_LOAD_FLAG_PEM_CA_ONLY) &&
+                       (ret == ASN_NO_PEM_HEADER))) {
+                    /* Do not fail here if a certificate fails to load,
+                       continue to next file */
+                    ret = WOLFSSL_SUCCESS;
+                }
+                else {
+                    WOLFSSL_ERROR(ret);
+                    WOLFSSL_MSG("Load CA file failed, continuing");
+                    failCount++;
+                }
+            }
+            else {
+                successCount++;
+            }
+            fileRet = wc_ReadDirNext(readCtx, path, &name);
+        }
+        wc_ReadDirClose(readCtx);
+
+        /* pass directory read failure to response code */
+        if (fileRet != WC_READDIR_NOFILE) {
+            ret = fileRet;
+        }
+        /* report failure if no files were loaded or there were failures */
+        else if (successCount == 0 || failCount > 0) {
+            /* use existing error code if exists */
+            if (ret == WOLFSSL_SUCCESS)
+                ret = WOLFSSL_FAILURE;
+        }
+        else {
+            ret = WOLFSSL_SUCCESS;
+        }
+
+    #ifdef WOLFSSL_SMALL_STACK
+        XFREE(readCtx, ctx->heap, DYNAMIC_TYPE_DIRCTX);
+    #endif
+#else
+        ret = NOT_COMPILED_IN;
+        (void)flags;
+#endif
+    }
+
+    return ret;
+}
+
+WOLFSSL_ABI
+int wolfSSL_CTX_load_verify_locations(WOLFSSL_CTX* ctx, const char* file,
+                                     const char* path)
+{
+    return wolfSSL_CTX_load_verify_locations_ex(ctx, file, path,
+        WOLFSSL_LOAD_VERIFY_DEFAULT_FLAGS);
+}
+
+
+#ifdef WOLFSSL_TRUST_PEER_CERT
+/* Used to specify a peer cert to match when connecting
+    ctx : the ctx structure to load in peer cert
+    file: the string name of cert file
+    type: type of format such as PEM/DER
+ */
+int wolfSSL_CTX_trust_peer_cert(WOLFSSL_CTX* ctx, const char* file, int type)
+{
+    WOLFSSL_ENTER("wolfSSL_CTX_trust_peer_cert");
+
+    if (ctx == NULL || file == NULL) {
+        return WOLFSSL_FAILURE;
+    }
+
+    return ProcessFile(ctx, file, type, TRUSTED_PEER_TYPE, NULL, 0, NULL,
+                       GET_VERIFY_SETTING_CTX(ctx));
+}
+#endif /* WOLFSSL_TRUST_PEER_CERT */
+
+
+/* Verify the certificate, WOLFSSL_SUCCESS for ok, < 0 for error */
+int wolfSSL_CertManagerVerify(WOLFSSL_CERT_MANAGER* cm, const char* fname,
+                             int format)
+{
+    int    ret = WOLFSSL_FATAL_ERROR;
+#ifdef WOLFSSL_SMALL_STACK
+    byte   staticBuffer[1]; /* force heap usage */
+#else
+    byte   staticBuffer[FILE_BUFFER_SIZE];
+#endif
+    byte*  myBuffer = staticBuffer;
+    int    dynamic = 0;
+    long   sz = 0;
+    XFILE  file = XFOPEN(fname, "rb");
+
+    WOLFSSL_ENTER("wolfSSL_CertManagerVerify");
+
+    if (file == XBADFILE) return WOLFSSL_BAD_FILE;
+    if(XFSEEK(file, 0, XSEEK_END) != 0) {
+        XFCLOSE(file);
+        return WOLFSSL_BAD_FILE;
+    }
+    sz = XFTELL(file);
+    XREWIND(file);
+
+    if (sz > MAX_WOLFSSL_FILE_SIZE || sz <= 0) {
+        WOLFSSL_MSG("CertManagerVerify file size error");
+        XFCLOSE(file);
+        return WOLFSSL_BAD_FILE;
+    }
+
+    if (sz > (long)sizeof(staticBuffer)) {
+        WOLFSSL_MSG("Getting dynamic buffer");
+        myBuffer = (byte*) XMALLOC(sz, cm->heap, DYNAMIC_TYPE_FILE);
+        if (myBuffer == NULL) {
+            XFCLOSE(file);
+            return WOLFSSL_BAD_FILE;
+        }
+        dynamic = 1;
+    }
+
+    if ( (ret = (int)XFREAD(myBuffer, 1, sz, file)) != sz)
+        ret = WOLFSSL_BAD_FILE;
+    else
+        ret = wolfSSL_CertManagerVerifyBuffer(cm, myBuffer, sz, format);
+
+    XFCLOSE(file);
+    if (dynamic)
+        XFREE(myBuffer, cm->heap, DYNAMIC_TYPE_FILE);
+
+    return ret;
+}
+
+
+/* like load verify locations, 1 for success, < 0 for error */
+int wolfSSL_CertManagerLoadCA(WOLFSSL_CERT_MANAGER* cm, const char* file,
+                             const char* path)
+{
+    int ret = WOLFSSL_FATAL_ERROR;
+    WOLFSSL_CTX* tmp;
+
+    WOLFSSL_ENTER("wolfSSL_CertManagerLoadCA");
+
+    if (cm == NULL) {
+        WOLFSSL_MSG("No CertManager error");
+        return ret;
+    }
+    tmp = wolfSSL_CTX_new(cm_pick_method());
+
+    if (tmp == NULL) {
+        WOLFSSL_MSG("CTX new failed");
+        return ret;
+    }
+
+    /* for tmp use */
+    wolfSSL_CertManagerFree(tmp->cm);
+    tmp->cm = cm;
+
+    ret = wolfSSL_CTX_load_verify_locations(tmp, file, path);
+
+    /* don't lose our good one */
+    tmp->cm = NULL;
+    wolfSSL_CTX_free(tmp);
+
+    return ret;
+}
+
+#ifndef NO_CHECK_PRIVATE_KEY
+/* Check private against public in certificate for match
+ *
+ * ctx  WOLFSSL_CTX structure to check private key in
+ *
+ * Returns SSL_SUCCESS on good private key and SSL_FAILURE if miss matched. */
+int wolfSSL_CTX_check_private_key(const WOLFSSL_CTX* ctx)
+{
+#ifdef WOLFSSL_SMALL_STACK
+    DecodedCert* der = NULL;
+#else
+    DecodedCert  der[1];
+#endif
+    word32 size;
+    byte*  buff;
+    int    ret;
+
+    WOLFSSL_ENTER("wolfSSL_CTX_check_private_key");
+
+    if (ctx == NULL) {
+        return WOLFSSL_FAILURE;
+    }
+
+#ifndef NO_CERTS
+#ifdef WOLFSSL_SMALL_STACK
+    der = (DecodedCert*)XMALLOC(sizeof(DecodedCert), NULL, DYNAMIC_TYPE_DCERT);
+    if (der == NULL)
+        return MEMORY_E;
+#endif
+
+    size = ctx->certificate->length;
+    buff = ctx->certificate->buffer;
+    InitDecodedCert(der, buff, size, ctx->heap);
+    if (ParseCertRelative(der, CERT_TYPE, NO_VERIFY, NULL) != 0) {
+        FreeDecodedCert(der);
+    #ifdef WOLFSSL_SMALL_STACK
+        XFREE(der, NULL, DYNAMIC_TYPE_DCERT);
+    #endif
+        return WOLFSSL_FAILURE;
+    }
+
+    size = ctx->privateKey->length;
+    buff = ctx->privateKey->buffer;
+    ret  = wc_CheckPrivateKey(buff, size, der);
+    FreeDecodedCert(der);
+#ifdef WOLFSSL_SMALL_STACK
+    XFREE(der, NULL, DYNAMIC_TYPE_DCERT);
+#endif
+
+    if (ret == 1) {
+        return WOLFSSL_SUCCESS;
+    }
+    else {
+        return WOLFSSL_FAILURE;
+    }
+#else
+    WOLFSSL_MSG("NO_CERTS is defined, can not check private key");
+    return WOLFSSL_FAILURE;
+#endif
+}
+#endif /* !NO_CHECK_PRIVATE_KEY */
+
+
+#ifdef HAVE_CRL
+
+/* check CRL if enabled, WOLFSSL_SUCCESS  */
+int wolfSSL_CertManagerCheckCRL(WOLFSSL_CERT_MANAGER* cm, byte* der, int sz)
+{
+    int ret = 0;
+#ifdef WOLFSSL_SMALL_STACK
+    DecodedCert* cert = NULL;
+#else
+    DecodedCert  cert[1];
+#endif
+
+    WOLFSSL_ENTER("wolfSSL_CertManagerCheckCRL");
+
+    if (cm == NULL)
+        return BAD_FUNC_ARG;
+
+    if (cm->crlEnabled == 0)
+        return WOLFSSL_SUCCESS;
+
+#ifdef WOLFSSL_SMALL_STACK
+    cert = (DecodedCert*)XMALLOC(sizeof(DecodedCert), NULL, DYNAMIC_TYPE_DCERT);
+    if (cert == NULL)
+        return MEMORY_E;
+#endif
+
+    InitDecodedCert(cert, der, sz, NULL);
+
+    if ((ret = ParseCertRelative(cert, CERT_TYPE, VERIFY_CRL, cm)) != 0) {
+        WOLFSSL_MSG("ParseCert failed");
+    }
+    else if ((ret = CheckCertCRL(cm->crl, cert)) != 0) {
+        WOLFSSL_MSG("CheckCertCRL failed");
+    }
+
+    FreeDecodedCert(cert);
+#ifdef WOLFSSL_SMALL_STACK
+    XFREE(cert, NULL, DYNAMIC_TYPE_DCERT);
+#endif
+
+    return ret == 0 ? WOLFSSL_SUCCESS : ret;
+}
+
+
+int wolfSSL_CertManagerSetCRL_Cb(WOLFSSL_CERT_MANAGER* cm, CbMissingCRL cb)
+{
+    WOLFSSL_ENTER("wolfSSL_CertManagerSetCRL_Cb");
+    if (cm == NULL)
+        return BAD_FUNC_ARG;
+
+    cm->cbMissingCRL = cb;
+
+    return WOLFSSL_SUCCESS;
+}
+
+#ifdef HAVE_CRL_IO
+int wolfSSL_CertManagerSetCRL_IOCb(WOLFSSL_CERT_MANAGER* cm, CbCrlIO cb)
+{
+    if (cm == NULL)
+        return BAD_FUNC_ARG;
+
+    cm->crl->crlIOCb = cb;
+
+    return WOLFSSL_SUCCESS;
+}
+#endif
+
+int wolfSSL_CertManagerLoadCRL(WOLFSSL_CERT_MANAGER* cm, const char* path,
+                              int type, int monitor)
+{
+    WOLFSSL_ENTER("wolfSSL_CertManagerLoadCRL");
+    if (cm == NULL)
+        return BAD_FUNC_ARG;
+
+    if (cm->crl == NULL) {
+        if (wolfSSL_CertManagerEnableCRL(cm, 0) != WOLFSSL_SUCCESS) {
+            WOLFSSL_MSG("Enable CRL failed");
+            return WOLFSSL_FATAL_ERROR;
+        }
+    }
+
+    return LoadCRL(cm->crl, path, type, monitor);
+}
+
+int wolfSSL_EnableCRL(WOLFSSL* ssl, int options)
+{
+    WOLFSSL_ENTER("wolfSSL_EnableCRL");
+    if (ssl)
+        return wolfSSL_CertManagerEnableCRL(ssl->ctx->cm, options);
+    else
+        return BAD_FUNC_ARG;
+}
+
+
+int wolfSSL_DisableCRL(WOLFSSL* ssl)
+{
+    WOLFSSL_ENTER("wolfSSL_DisableCRL");
+    if (ssl)
+        return wolfSSL_CertManagerDisableCRL(ssl->ctx->cm);
+    else
+        return BAD_FUNC_ARG;
+}
+
+int wolfSSL_LoadCRL(WOLFSSL* ssl, const char* path, int type, int monitor)
+{
+    WOLFSSL_ENTER("wolfSSL_LoadCRL");
+    if (ssl)
+        return wolfSSL_CertManagerLoadCRL(ssl->ctx->cm, path, type, monitor);
+    else
+        return BAD_FUNC_ARG;
+}
+
+
+int wolfSSL_SetCRL_Cb(WOLFSSL* ssl, CbMissingCRL cb)
+{
+    WOLFSSL_ENTER("wolfSSL_SetCRL_Cb");
+    if (ssl)
+        return wolfSSL_CertManagerSetCRL_Cb(ssl->ctx->cm, cb);
+    else
+        return BAD_FUNC_ARG;
+}
+
+#ifdef HAVE_CRL_IO
+int wolfSSL_SetCRL_IOCb(WOLFSSL* ssl, CbCrlIO cb)
+{
+    WOLFSSL_ENTER("wolfSSL_SetCRL_Cb");
+    if (ssl)
+        return wolfSSL_CertManagerSetCRL_IOCb(ssl->ctx->cm, cb);
+    else
+        return BAD_FUNC_ARG;
+}
+#endif
+
+int wolfSSL_CTX_EnableCRL(WOLFSSL_CTX* ctx, int options)
+{
+    WOLFSSL_ENTER("wolfSSL_CTX_EnableCRL");
+    if (ctx)
+        return wolfSSL_CertManagerEnableCRL(ctx->cm, options);
+    else
+        return BAD_FUNC_ARG;
+}
+
+
+int wolfSSL_CTX_DisableCRL(WOLFSSL_CTX* ctx)
+{
+    WOLFSSL_ENTER("wolfSSL_CTX_DisableCRL");
+    if (ctx)
+        return wolfSSL_CertManagerDisableCRL(ctx->cm);
+    else
+        return BAD_FUNC_ARG;
+}
+
+
+int wolfSSL_CTX_LoadCRL(WOLFSSL_CTX* ctx, const char* path,
+                        int type, int monitor)
+{
+    WOLFSSL_ENTER("wolfSSL_CTX_LoadCRL");
+    if (ctx)
+        return wolfSSL_CertManagerLoadCRL(ctx->cm, path, type, monitor);
+    else
+        return BAD_FUNC_ARG;
+}
+
+
+int wolfSSL_CTX_SetCRL_Cb(WOLFSSL_CTX* ctx, CbMissingCRL cb)
+{
+    WOLFSSL_ENTER("wolfSSL_CTX_SetCRL_Cb");
+    if (ctx)
+        return wolfSSL_CertManagerSetCRL_Cb(ctx->cm, cb);
+    else
+        return BAD_FUNC_ARG;
+}
+
+#ifdef HAVE_CRL_IO
+int wolfSSL_CTX_SetCRL_IOCb(WOLFSSL_CTX* ctx, CbCrlIO cb)
+{
+    WOLFSSL_ENTER("wolfSSL_CTX_SetCRL_IOCb");
+    if (ctx)
+        return wolfSSL_CertManagerSetCRL_IOCb(ctx->cm, cb);
+    else
+        return BAD_FUNC_ARG;
+}
+#endif
+
+
+#endif /* HAVE_CRL */
+
+
+#ifdef WOLFSSL_DER_LOAD
+
+/* Add format parameter to allow DER load of CA files */
+int wolfSSL_CTX_der_load_verify_locations(WOLFSSL_CTX* ctx, const char* file,
+                                          int format)
+{
+    WOLFSSL_ENTER("wolfSSL_CTX_der_load_verify_locations");
+    if (ctx == NULL || file == NULL)
+        return WOLFSSL_FAILURE;
+
+    if (ProcessFile(ctx, file, format, CA_TYPE, NULL, 0, NULL,
+                    GET_VERIFY_SETTING_CTX(ctx)) == WOLFSSL_SUCCESS) {
+        return WOLFSSL_SUCCESS;
+    }
+
+    return WOLFSSL_FAILURE;
+}
+
+#endif /* WOLFSSL_DER_LOAD */
+
+
+
+WOLFSSL_ABI
+int wolfSSL_CTX_use_certificate_file(WOLFSSL_CTX* ctx, const char* file,
+                                     int format)
+{
+    WOLFSSL_ENTER("wolfSSL_CTX_use_certificate_file");
+
+    if (ProcessFile(ctx, file, format, CERT_TYPE, NULL, 0, NULL,
+                    GET_VERIFY_SETTING_CTX(ctx)) == WOLFSSL_SUCCESS) {
+        return WOLFSSL_SUCCESS;
+    }
+
+    return WOLFSSL_FAILURE;
+}
+
+
+WOLFSSL_ABI
+int wolfSSL_CTX_use_PrivateKey_file(WOLFSSL_CTX* ctx, const char* file,
+                                    int format)
+{
+    WOLFSSL_ENTER("wolfSSL_CTX_use_PrivateKey_file");
+
+    if (ProcessFile(ctx, file, format, PRIVATEKEY_TYPE, NULL, 0, NULL,
+                    GET_VERIFY_SETTING_CTX(ctx)) == WOLFSSL_SUCCESS) {
+        return WOLFSSL_SUCCESS;
+    }
+
+    return WOLFSSL_FAILURE;
+}
+
+
+/* Sets the max chain depth when verifying a certificate chain. Default depth
+ * is set to MAX_CHAIN_DEPTH.
+ *
+ * ctx   WOLFSSL_CTX structure to set depth in
+ * depth max depth
+ */
+void wolfSSL_CTX_set_verify_depth(WOLFSSL_CTX *ctx, int depth) {
+    WOLFSSL_ENTER("wolfSSL_CTX_set_verify_depth");
+
+    if (ctx == NULL || depth < 0 || depth > MAX_CHAIN_DEPTH) {
+        WOLFSSL_MSG("Bad depth argument, too large or less than 0");
+        return;
+    }
+
+    ctx->verifyDepth = (byte)depth;
+}
+
+
+/* get cert chaining depth using ssl struct */
+long wolfSSL_get_verify_depth(WOLFSSL* ssl)
+{
+    if(ssl == NULL) {
+        return BAD_FUNC_ARG;
+    }
+#ifndef OPENSSL_EXTRA
+    return MAX_CHAIN_DEPTH;
+#else
+    return ssl->options.verifyDepth;
+#endif
+}
+
+
+/* get cert chaining depth using ctx struct */
+long wolfSSL_CTX_get_verify_depth(WOLFSSL_CTX* ctx)
+{
+    if (ctx == NULL) {
+        return BAD_FUNC_ARG;
+    }
+#ifndef OPENSSL_EXTRA
+    return MAX_CHAIN_DEPTH;
+#else
+    return ctx->verifyDepth;
+#endif
+}
+
+
+WOLFSSL_ABI
+int wolfSSL_CTX_use_certificate_chain_file(WOLFSSL_CTX* ctx, const char* file)
+{
+    /* process up to MAX_CHAIN_DEPTH plus subject cert */
+    WOLFSSL_ENTER("wolfSSL_CTX_use_certificate_chain_file");
+
+    if (ProcessFile(ctx, file, WOLFSSL_FILETYPE_PEM, CERT_TYPE, NULL, 1, NULL,
+                    GET_VERIFY_SETTING_CTX(ctx)) == WOLFSSL_SUCCESS) {
+        return WOLFSSL_SUCCESS;
+    }
+
+   return WOLFSSL_FAILURE;
+}
+
+
+int wolfSSL_CTX_use_certificate_chain_file_format(WOLFSSL_CTX* ctx,
+                                                  const char* file, int format)
+{
+    /* process up to MAX_CHAIN_DEPTH plus subject cert */
+    WOLFSSL_ENTER("wolfSSL_CTX_use_certificate_chain_file_format");
+
+    if (ProcessFile(ctx, file, format, CERT_TYPE, NULL, 1, NULL,
+                    GET_VERIFY_SETTING_CTX(ctx)) == WOLFSSL_SUCCESS) {
+        return WOLFSSL_SUCCESS;
+    }
+
+   return WOLFSSL_FAILURE;
+}
+
+
+#ifndef NO_DH
+
+/* server Diffie-Hellman parameters */
+static int wolfSSL_SetTmpDH_file_wrapper(WOLFSSL_CTX* ctx, WOLFSSL* ssl,
+                                        const char* fname, int format)
+{
+#ifdef WOLFSSL_SMALL_STACK
+    byte   staticBuffer[1]; /* force heap usage */
+#else
+    byte   staticBuffer[FILE_BUFFER_SIZE];
+#endif
+    byte*  myBuffer = staticBuffer;
+    int    dynamic = 0;
+    int    ret;
+    long   sz = 0;
+    XFILE  file;
+
+    if (ctx == NULL || fname == NULL)
+        return BAD_FUNC_ARG;
+
+    file = XFOPEN(fname, "rb");
+    if (file == XBADFILE) return WOLFSSL_BAD_FILE;
+    if(XFSEEK(file, 0, XSEEK_END) != 0) {
+        XFCLOSE(file);
+        return WOLFSSL_BAD_FILE;
+    }
+    sz = XFTELL(file);
+    XREWIND(file);
+
+    if (sz > MAX_WOLFSSL_FILE_SIZE || sz <= 0) {
+        WOLFSSL_MSG("SetTmpDH file size error");
+        XFCLOSE(file);
+        return WOLFSSL_BAD_FILE;
+    }
+
+    if (sz > (long)sizeof(staticBuffer)) {
+        WOLFSSL_MSG("Getting dynamic buffer");
+        myBuffer = (byte*) XMALLOC(sz, ctx->heap, DYNAMIC_TYPE_FILE);
+        if (myBuffer == NULL) {
+            XFCLOSE(file);
+            return WOLFSSL_BAD_FILE;
+        }
+        dynamic = 1;
+    }
+
+    if ( (ret = (int)XFREAD(myBuffer, 1, sz, file)) != sz)
+        ret = WOLFSSL_BAD_FILE;
+    else {
+        if (ssl)
+            ret = wolfSSL_SetTmpDH_buffer(ssl, myBuffer, sz, format);
+        else
+            ret = wolfSSL_CTX_SetTmpDH_buffer(ctx, myBuffer, sz, format);
+    }
+
+    XFCLOSE(file);
+    if (dynamic)
+        XFREE(myBuffer, ctx->heap, DYNAMIC_TYPE_FILE);
+
+    return ret;
+}
+
+/* server Diffie-Hellman parameters */
+int wolfSSL_SetTmpDH_file(WOLFSSL* ssl, const char* fname, int format)
+{
+    if (ssl == NULL)
+        return BAD_FUNC_ARG;
+
+    return wolfSSL_SetTmpDH_file_wrapper(ssl->ctx, ssl, fname, format);
+}
+
+
+/* server Diffie-Hellman parameters */
+int wolfSSL_CTX_SetTmpDH_file(WOLFSSL_CTX* ctx, const char* fname, int format)
+{
+    return wolfSSL_SetTmpDH_file_wrapper(ctx, NULL, fname, format);
+}
+
+#endif /* NO_DH */
+
+#endif /* NO_FILESYSTEM */
+
+#ifdef OPENSSL_EXTRA
+/* put SSL type in extra for now, not very common */
+
+/* Converts a DER format key read from "bio" to a PKCS8 structure.
+ *
+ * bio  input bio to read DER from
+ * pkey If not NULL then this pointer will be overwritten with a new PKCS8
+ *      structure.
+ *
+ * returns a WOLFSSL_PKCS8_PRIV_KEY_INFO pointer on success and NULL in fail
+ *         case.
+ */
+WOLFSSL_PKCS8_PRIV_KEY_INFO* wolfSSL_d2i_PKCS8_PKEY_bio(WOLFSSL_BIO* bio,
+        WOLFSSL_PKCS8_PRIV_KEY_INFO** pkey)
+{
+    WOLFSSL_PKCS8_PRIV_KEY_INFO* pkcs8 = NULL;
+#ifdef WOLFSSL_PEM_TO_DER
+    unsigned char* mem = NULL;
+    int memSz;
+    int keySz;
+    word32 algId;
+
+    WOLFSSL_MSG("wolfSSL_d2i_PKCS8_PKEY_bio()");
+
+    if (bio == NULL) {
+        return NULL;
+    }
+
+    if ((memSz = wolfSSL_BIO_get_mem_data(bio, &mem)) < 0) {
+        return NULL;
+    }
+
+    if ((keySz = wc_KeyPemToDer(mem, memSz, mem, memSz, NULL)) < 0) {
+        WOLFSSL_MSG("Not PEM format");
+        keySz = memSz;
+        if ((keySz = ToTraditional_ex((byte*)mem, (word32)keySz, &algId)) < 0) {
+            return NULL;
+        }
+    }
+
+    pkcs8 = wolfSSL_EVP_PKEY_new();
+    if (pkcs8 == NULL) {
+        return NULL;
+    }
+
+    pkcs8->pkey.ptr = (char*)XMALLOC(keySz, NULL, DYNAMIC_TYPE_PUBLIC_KEY);
+    if (pkcs8->pkey.ptr == NULL) {
+        wolfSSL_EVP_PKEY_free(pkcs8);
+        return NULL;
+    }
+    XMEMCPY(pkcs8->pkey.ptr, mem, keySz);
+    pkcs8->pkey_sz = keySz;
+
+    if (pkey != NULL) {
+        *pkey = pkcs8;
+    }
+#else
+    (void)bio;
+    (void)pkey;
+#endif /* WOLFSSL_PEM_TO_DER */
+
+    return pkcs8;
+}
+
+
+/* expecting DER format public key
+ *
+ * bio  input bio to read DER from
+ * out  If not NULL then this pointer will be overwritten with a new
+ * WOLFSSL_EVP_PKEY pointer
+ *
+ * returns a WOLFSSL_EVP_PKEY pointer on success and NULL in fail case.
+ */
+WOLFSSL_EVP_PKEY* wolfSSL_d2i_PUBKEY_bio(WOLFSSL_BIO* bio,
+                                         WOLFSSL_EVP_PKEY** out)
+{
+    unsigned char* mem;
+    long memSz;
+    WOLFSSL_EVP_PKEY* pkey = NULL;
+
+    WOLFSSL_ENTER("wolfSSL_d2i_PUBKEY_bio()");
+
+    if (bio == NULL) {
+        return NULL;
+    }
+    (void)out;
+
+    memSz = wolfSSL_BIO_pending(bio);
+    if (memSz <= 0) {
+        return NULL;
+    }
+
+    mem = (unsigned char*)XMALLOC(memSz, bio->heap, DYNAMIC_TYPE_TMP_BUFFER);
+    if (mem == NULL) {
+        return NULL;
+    }
+
+    if (wolfSSL_BIO_read(bio, mem, (int)memSz) == memSz) {
+        pkey = wolfSSL_d2i_PUBKEY(NULL, (const unsigned char**)&mem, memSz);
+        if (out != NULL && pkey != NULL) {
+            *out = pkey;
+        }
+    }
+
+    XFREE(mem, bio->heap, DYNAMIC_TYPE_TMP_BUFFER);
+    return pkey;
+}
+
+
+
+/* Converts a DER encoded public key to a WOLFSSL_EVP_PKEY structure.
+ *
+ * out  pointer to new WOLFSSL_EVP_PKEY structure. Can be NULL
+ * in   DER buffer to convert
+ * inSz size of in buffer
+ *
+ * returns a pointer to a new WOLFSSL_EVP_PKEY structure on success and NULL
+ *         on fail
+ */
+WOLFSSL_EVP_PKEY* wolfSSL_d2i_PUBKEY(WOLFSSL_EVP_PKEY** out,
+                                     const unsigned char** in, long inSz)
+{
+    WOLFSSL_EVP_PKEY* pkey = NULL;
+    const unsigned char* mem;
+    long memSz = inSz;
+
+    WOLFSSL_ENTER("wolfSSL_d2i_PUBKEY");
+
+    if (in == NULL || inSz < 0) {
+        WOLFSSL_MSG("Bad argument");
+        return NULL;
+    }
+    mem = *in;
+
+    #if !defined(NO_RSA)
+    {
+        RsaKey rsa;
+        word32 keyIdx = 0;
+
+        /* test if RSA key */
+        if (wc_InitRsaKey(&rsa, NULL) == 0 &&
+            wc_RsaPublicKeyDecode(mem, &keyIdx, &rsa, (word32)memSz) == 0) {
+            wc_FreeRsaKey(&rsa);
+            pkey = wolfSSL_EVP_PKEY_new();
+            if (pkey != NULL) {
+                pkey->pkey_sz = keyIdx;
+                pkey->pkey.ptr = (char*)XMALLOC(memSz, NULL,
+                        DYNAMIC_TYPE_PUBLIC_KEY);
+                if (pkey->pkey.ptr == NULL) {
+                    wolfSSL_EVP_PKEY_free(pkey);
+                    return NULL;
+                }
+                XMEMCPY(pkey->pkey.ptr, mem, keyIdx);
+                pkey->type = EVP_PKEY_RSA;
+                if (out != NULL) {
+                    *out = pkey;
+                }
+
+                pkey->ownRsa = 1;
+                pkey->rsa = wolfSSL_RSA_new();
+                if (pkey->rsa == NULL) {
+                    wolfSSL_EVP_PKEY_free(pkey);
+                    return NULL;
+                }
+
+                if (wolfSSL_RSA_LoadDer_ex(pkey->rsa,
+                            (const unsigned char*)pkey->pkey.ptr,
+                            pkey->pkey_sz, WOLFSSL_RSA_LOAD_PUBLIC) != 1) {
+                    wolfSSL_EVP_PKEY_free(pkey);
+                    return NULL;
+                }
+
+                return pkey;
+            }
+        }
+        wc_FreeRsaKey(&rsa);
+    }
+    #endif /* NO_RSA */
+
+    #ifdef HAVE_ECC
+    {
+        word32  keyIdx = 0;
+        ecc_key ecc;
+
+        if (wc_ecc_init(&ecc) == 0 &&
+            wc_EccPublicKeyDecode(mem, &keyIdx, &ecc, (word32)memSz) == 0) {
+            wc_ecc_free(&ecc);
+            pkey = wolfSSL_EVP_PKEY_new();
+            if (pkey != NULL) {
+                pkey->pkey_sz = keyIdx;
+                pkey->pkey.ptr = (char*)XMALLOC(keyIdx, NULL,
+                        DYNAMIC_TYPE_PUBLIC_KEY);
+                if (pkey->pkey.ptr == NULL) {
+                    wolfSSL_EVP_PKEY_free(pkey);
+                    return NULL;
+                }
+                XMEMCPY(pkey->pkey.ptr, mem, keyIdx);
+                pkey->type = EVP_PKEY_EC;
+                if (out != NULL) {
+                    *out = pkey;
+                }
+
+                pkey->ownEcc = 1;
+                pkey->ecc = wolfSSL_EC_KEY_new();
+                if (pkey->ecc == NULL) {
+                    wolfSSL_EVP_PKEY_free(pkey);
+                    return NULL;
+                }
+
+                if (wolfSSL_EC_KEY_LoadDer_ex(pkey->ecc,
+                            (const unsigned char*)pkey->pkey.ptr,
+                            pkey->pkey_sz, WOLFSSL_EC_KEY_LOAD_PUBLIC) != 1) {
+                    wolfSSL_EVP_PKEY_free(pkey);
+                    return NULL;
+                }
+
+                return pkey;
+            }
+        }
+        wc_ecc_free(&ecc);
+    }
+    #endif /* HAVE_ECC */
+
+    #if !defined(NO_DSA)
+    {
+        DsaKey dsa;
+        word32 keyIdx = 0;
+
+        /* test if DSA key */
+        if (wc_InitDsaKey(&dsa) == 0 &&
+            wc_DsaPublicKeyDecode(mem, &keyIdx, &dsa, (word32)memSz) == 0) {
+            wc_FreeDsaKey(&dsa);
+            pkey = wolfSSL_EVP_PKEY_new();
+
+            if (pkey != NULL) {
+                pkey->pkey_sz = keyIdx;
+                pkey->pkey.ptr = (char*)XMALLOC(memSz, NULL,
+                        DYNAMIC_TYPE_PUBLIC_KEY);
+                if (pkey->pkey.ptr == NULL) {
+                    wolfSSL_EVP_PKEY_free(pkey);
+                    return NULL;
+                }
+                XMEMCPY(pkey->pkey.ptr, mem, keyIdx);
+                pkey->type = EVP_PKEY_DSA;
+                if (out != NULL) {
+                    *out = pkey;
+                }
+
+                pkey->ownDsa = 1;
+                pkey->dsa = wolfSSL_DSA_new();
+                if (pkey->dsa == NULL) {
+                    wolfSSL_EVP_PKEY_free(pkey);
+                    return NULL;
+                }
+
+
+                if (wolfSSL_DSA_LoadDer_ex(pkey->dsa,
+                            (const unsigned char*)pkey->pkey.ptr,
+                            pkey->pkey_sz, WOLFSSL_DSA_LOAD_PUBLIC) != 1) {
+                    wolfSSL_EVP_PKEY_free(pkey);
+                    return NULL;
+                }
+
+                return pkey;
+            }
+        }
+        wc_FreeDsaKey(&dsa);
+    }
+    #endif /* NO_DSA */
+
+    #if !defined(NO_DH) && (defined(WOLFSSL_QT) || defined(OPENSSL_ALL))
+    {
+        DhKey dh;
+        word32 keyIdx = 0;
+
+        /* test if DH key */
+        if (wc_InitDhKey(&dh) == 0 &&
+            wc_DhKeyDecode(mem, &keyIdx, &dh, (word32)memSz) == 0) {
+            wc_FreeDhKey(&dh);
+            pkey = wolfSSL_EVP_PKEY_new();
+
+            if (pkey != NULL) {
+                pkey->pkey_sz = (int)memSz;
+                pkey->pkey.ptr = (char*)XMALLOC(memSz, NULL,
+                        DYNAMIC_TYPE_PUBLIC_KEY);
+                if (pkey->pkey.ptr == NULL) {
+                    wolfSSL_EVP_PKEY_free(pkey);
+                    return NULL;
+                }
+                XMEMCPY(pkey->pkey.ptr, mem, memSz);
+                pkey->type = EVP_PKEY_DH;
+                if (out != NULL) {
+                    *out = pkey;
+                }
+
+                pkey->ownDh = 1;
+                pkey->dh = wolfSSL_DH_new();
+                if (pkey->dh == NULL) {
+                    wolfSSL_EVP_PKEY_free(pkey);
+                    return NULL;
+                }
+
+                if (wolfSSL_DH_LoadDer(pkey->dh,
+                            (const unsigned char*)pkey->pkey.ptr,
+                            pkey->pkey_sz) != WOLFSSL_SUCCESS) {
+                    wolfSSL_EVP_PKEY_free(pkey);
+                    return NULL;
+                }
+
+                return pkey;
+            }
+        }
+        wc_FreeDhKey(&dh);
+    }
+    #endif /* !NO_DH && (WOLFSSL_QT || OPENSSL_ALL) */
+
+    return pkey;
+}
+
+
+/* Reads in a DER format key. If PKCS8 headers are found they are stripped off.
+ *
+ * type  type of key
+ * out   newly created WOLFSSL_EVP_PKEY structure
+ * in    pointer to input key DER
+ * inSz  size of in buffer
+ *
+ * On success a non null pointer is returned and the pointer in is advanced the
+ * same number of bytes read.
+ */
+WOLFSSL_EVP_PKEY* wolfSSL_d2i_PrivateKey(int type, WOLFSSL_EVP_PKEY** out,
+        const unsigned char **in, long inSz)
+{
+    WOLFSSL_EVP_PKEY* local;
+    word32 idx = 0;
+    int    ret;
+    word32 algId;
+
+    WOLFSSL_ENTER("wolfSSL_d2i_PrivateKey");
+
+    if (in == NULL || inSz < 0) {
+        WOLFSSL_MSG("Bad argument");
+        return NULL;
+    }
+
+    /* Check if input buffer has PKCS8 header. In the case that it does not
+     * have a PKCS8 header then do not error out. */
+    if ((ret = ToTraditionalInline_ex((const byte*)(*in), &idx, (word32)inSz,
+                                                                 &algId)) > 0) {
+        WOLFSSL_MSG("Found and removed PKCS8 header");
+    }
+    else {
+        if (ret != ASN_PARSE_E) {
+            WOLFSSL_MSG("Unexpected error with trying to remove PKCS8 header");
+            return NULL;
+        }
+    }
+
+    if (out != NULL && *out != NULL) {
+        wolfSSL_EVP_PKEY_free(*out);
+        *out = NULL;
+    }
+    local = wolfSSL_EVP_PKEY_new();
+    if (local == NULL) {
+        return NULL;
+    }
+
+    /* sanity check on idx before use */
+    if ((int)idx > inSz) {
+        WOLFSSL_MSG("Issue with index pointer");
+        wolfSSL_EVP_PKEY_free(local);
+        local = NULL;
+        return NULL;
+    }
+
+    local->type     = type;
+    local->pkey_sz  = (int)inSz - idx;
+    local->pkey.ptr = (char*)XMALLOC(inSz - idx, NULL, DYNAMIC_TYPE_PUBLIC_KEY);
+    if (local->pkey.ptr == NULL) {
+        wolfSSL_EVP_PKEY_free(local);
+        local = NULL;
+        return NULL;
+    }
+    else {
+        XMEMCPY(local->pkey.ptr, *in + idx, inSz - idx);
+    }
+
+    switch (type) {
+#ifndef NO_RSA
+        case EVP_PKEY_RSA:
+            local->ownRsa = 1;
+            local->rsa = wolfSSL_RSA_new();
+            if (local->rsa == NULL) {
+                wolfSSL_EVP_PKEY_free(local);
+                return NULL;
+            }
+            if (wolfSSL_RSA_LoadDer_ex(local->rsa,
+                      (const unsigned char*)local->pkey.ptr, local->pkey_sz,
+                      WOLFSSL_RSA_LOAD_PRIVATE) != SSL_SUCCESS) {
+                wolfSSL_EVP_PKEY_free(local);
+                return NULL;
+            }
+            break;
+#endif /* NO_RSA */
+#ifdef HAVE_ECC
+        case EVP_PKEY_EC:
+            local->ownEcc = 1;
+            local->ecc = wolfSSL_EC_KEY_new();
+            if (local->ecc == NULL) {
+                wolfSSL_EVP_PKEY_free(local);
+                return NULL;
+            }
+            if (wolfSSL_EC_KEY_LoadDer(local->ecc,
+                      (const unsigned char*)local->pkey.ptr, local->pkey_sz)
+                      != SSL_SUCCESS) {
+                wolfSSL_EVP_PKEY_free(local);
+                return NULL;
+            }
+            break;
+#endif /* HAVE_ECC */
+#if defined(WOLFSSL_QT) || defined(OPENSSL_ALL)
+#ifndef NO_DSA
+        case EVP_PKEY_DSA:
+            local->ownDsa = 1;
+            local->dsa = wolfSSL_DSA_new();
+            if (local->dsa == NULL) {
+                wolfSSL_EVP_PKEY_free(local);
+                return NULL;
+            }
+            if (wolfSSL_DSA_LoadDer(local->dsa,
+                    (const unsigned char*)local->pkey.ptr, local->pkey_sz)
+                    != SSL_SUCCESS) {
+                wolfSSL_EVP_PKEY_free(local);
+                return NULL;
+            }
+            break;
+#endif /* NO_DSA */
+#ifndef NO_DH
+        case EVP_PKEY_DH:
+            local->ownDh = 1;
+            local->dh = wolfSSL_DH_new();
+            if (local->dh == NULL) {
+                wolfSSL_EVP_PKEY_free(local);
+                return NULL;
+            }
+            if (wolfSSL_DH_LoadDer(local->dh,
+                      (const unsigned char*)local->pkey.ptr, local->pkey_sz)
+                      != SSL_SUCCESS) {
+                wolfSSL_EVP_PKEY_free(local);
+                return NULL;
+            }
+            break;
+#endif /* HAVE_DH */
+#endif /* WOLFSSL_QT || OPENSSL_ALL */
+        default:
+            WOLFSSL_MSG("Unsupported key type");
+            wolfSSL_EVP_PKEY_free(local);
+            return NULL;
+    }
+
+    /* advance pointer with success */
+    if (local != NULL) {
+        if ((idx + local->pkey_sz) <= (word32)inSz) {
+            *in = *in + idx + local->pkey_sz;
+        }
+
+        if (out != NULL) {
+            *out = local;
+        }
+    }
+
+    return local;
+}
+
+#ifndef NO_CERTS
+
+int wolfSSL_check_private_key(const WOLFSSL* ssl)
+{
+    DecodedCert der;
+    word32 size;
+    byte*  buff;
+    int    ret;
+
+    if (ssl == NULL) {
+        return WOLFSSL_FAILURE;
+    }
+
+    size = ssl->buffers.certificate->length;
+    buff = ssl->buffers.certificate->buffer;
+    InitDecodedCert(&der, buff, size, ssl->heap);
+#ifdef HAVE_PK_CALLBACKS
+    ret = InitSigPkCb((WOLFSSL*)ssl, &der.sigCtx);
+    if (ret != 0) {
+        FreeDecodedCert(&der);
+        return ret;
+    }
+#endif
+
+    if (ParseCertRelative(&der, CERT_TYPE, NO_VERIFY, NULL) != 0) {
+        FreeDecodedCert(&der);
+        return WOLFSSL_FAILURE;
+    }
+
+    size = ssl->buffers.key->length;
+    buff = ssl->buffers.key->buffer;
+    ret  = wc_CheckPrivateKey(buff, size, &der);
+    FreeDecodedCert(&der);
+    return ret;
+}
+
+#if defined(OPENSSL_ALL)
+/* Returns the number of X509V3 extensions in X509 object, or 0 on failure */
+int wolfSSL_X509_get_ext_count(const WOLFSSL_X509* passedCert)
+{
+    int extCount = 0;
+    int length = 0;
+    int outSz = 0;
+    const byte* rawCert;
+    int sz = 0;
+    word32 idx = 0;
+    DecodedCert cert;
+    const byte* input;
+
+    WOLFSSL_ENTER("wolfSSL_X509_get_ext_count()");
+    if (passedCert == NULL) {
+        WOLFSSL_MSG("\tNot passed a certificate");
+        return WOLFSSL_FAILURE;
+    }
+
+    rawCert = wolfSSL_X509_get_der((WOLFSSL_X509*)passedCert, &outSz);
+    if (rawCert == NULL) {
+        WOLFSSL_MSG("\tpassedCert has no internal DerBuffer set.");
+        return WOLFSSL_FAILURE;
+    }
+    InitDecodedCert(&cert, rawCert, (word32)outSz, 0);
+
+    if (ParseCert(&cert, CA_TYPE, NO_VERIFY, NULL) < 0) {
+        WOLFSSL_MSG("\tCertificate parsing failed");
+        return WOLFSSL_FAILURE;
+    }
+
+    input = cert.extensions;
+    sz = cert.extensionsSz;
+
+    if (input == NULL || sz == 0) {
+        WOLFSSL_MSG("\tsz or input NULL error");
+        FreeDecodedCert(&cert);
+        return WOLFSSL_FAILURE;
+    }
+
+    if (input[idx++] != ASN_EXTENSIONS) {
+        WOLFSSL_MSG("\tfail: should be an EXTENSIONS");
+        FreeDecodedCert(&cert);
+        return WOLFSSL_FAILURE;
+    }
+
+    if (GetLength(input, &idx, &length, sz) < 0) {
+        WOLFSSL_MSG("\tfail: invalid length");
+        FreeDecodedCert(&cert);
+        return WOLFSSL_FAILURE;
+    }
+
+    if (GetSequence(input, &idx, &length, sz) < 0) {
+        WOLFSSL_MSG("\tfail: should be a SEQUENCE (1)");
+        FreeDecodedCert(&cert);
+        return WOLFSSL_FAILURE;
+    }
+
+    while (idx < (word32)sz) {
+        if (GetSequence(input, &idx, &length, sz) < 0) {
+            WOLFSSL_MSG("\tfail: should be a SEQUENCE");
+            FreeDecodedCert(&cert);
+            return WOLFSSL_FAILURE;
+        }
+        idx += length;
+        extCount++;
+    }
+    FreeDecodedCert(&cert);
+    return extCount;
+}
+
+/* Creates and returns pointer to a new X509_EXTENSION object in memory */
+WOLFSSL_X509_EXTENSION* wolfSSL_X509_EXTENSION_new(void)
+{
+    WOLFSSL_ENTER("wolfSSL_X509_EXTENSION_new");
+
+    WOLFSSL_X509_EXTENSION* newExt;
+    newExt = (WOLFSSL_X509_EXTENSION*)XMALLOC(sizeof(WOLFSSL_X509_EXTENSION),
+              NULL, DYNAMIC_TYPE_X509_EXT);
+    if (newExt == NULL)
+        return NULL;
+    XMEMSET(newExt, 0, sizeof(WOLFSSL_X509_EXTENSION));
+
+    return newExt;
+}
+
+void wolfSSL_X509_EXTENSION_free(WOLFSSL_X509_EXTENSION* x)
+{
+    WOLFSSL_ASN1_STRING asn1;
+    WOLFSSL_ENTER("wolfSSL_X509_EXTENSION_free");
+    if (x == NULL)
+        return;
+
+    if (x->obj != NULL)
+        wolfSSL_ASN1_OBJECT_free(x->obj);
+
+    asn1 = x->value;
+    if (asn1.length > 0 && asn1.data != NULL && asn1.isDynamic)
+        XFREE(asn1.data, NULL, DYNAMIC_TYPE_OPENSSL);
+
+    wolfSSL_sk_free(x->ext_sk);
+
+    XFREE(x, NULL, DYNAMIC_TYPE_X509_EXT);
+}
+
+/* Creates and returns a new WOLFSSL_X509_EXTENSION stack. */
+WOLFSSL_STACK* wolfSSL_sk_new_x509_ext(void)
+{
+    WOLFSSL_STACK* sk;
+    WOLFSSL_ENTER("wolfSSL_sk_new_x509_ext");
+
+    sk = wolfSSL_sk_new_null();
+    if (sk) {
+        sk->type = STACK_TYPE_X509_EXT;
+    }
+    return sk;
+}
+
+/* return 1 on success 0 on fail */
+int wolfSSL_sk_X509_EXTENSION_push(WOLFSSL_STACK* sk,WOLFSSL_X509_EXTENSION* ext)
+{
+    WOLFSSL_STACK* node;
+
+    WOLFSSL_ENTER("wolfSSL_sk_X509_EXTENSION_push");
+
+    if (sk == NULL || ext == NULL) {
+        return WOLFSSL_FAILURE;
+    }
+
+    /* no previous values in stack */
+    if (sk->data.ext == NULL) {
+        sk->data.ext = ext;
+        sk->num += 1;
+        return WOLFSSL_SUCCESS;
+    }
+
+    /* stack already has value(s) create a new node and add more */
+    node = (WOLFSSL_STACK*)XMALLOC(sizeof(WOLFSSL_STACK), NULL,
+                                                             DYNAMIC_TYPE_X509);
+    if (node == NULL) {
+        WOLFSSL_MSG("Memory error");
+        return WOLFSSL_FAILURE;
+    }
+    XMEMSET(node, 0, sizeof(WOLFSSL_STACK));
+
+    /* push new obj onto head of stack */
+    node->data.ext  = sk->data.ext;
+    node->next      = sk->next;
+    node->type      = sk->type;
+    sk->next        = node;
+    sk->data.ext    = ext;
+    sk->num        += 1;
+
+    return WOLFSSL_SUCCESS;
+}
+
+/* Free the structure for X509_EXTENSION stack
+ *
+ * sk  stack to free nodes in
+ */
+void wolfSSL_sk_X509_EXTENSION_free(WOLFSSL_STACK* sk)
+{
+    WOLFSSL_STACK* node;
+
+    WOLFSSL_ENTER("wolfSSL_sk_X509_EXTENSION_free");
+
+    if (sk == NULL) {
+        return;
+    }
+
+    /* parse through stack freeing each node */
+    node = sk->next;
+    while ((node != NULL) && (sk->num > 1)) {
+        WOLFSSL_STACK* tmp = node;
+        node = node->next;
+
+        wolfSSL_X509_EXTENSION_free(tmp->data.ext);
+        XFREE(tmp, NULL, DYNAMIC_TYPE_X509);
+        sk->num -= 1;
+    }
+
+    /* free head of stack */
+    if (sk->num == 1) {
+        wolfSSL_X509_EXTENSION_free(sk->data.ext);
+    }
+    XFREE(sk, NULL, DYNAMIC_TYPE_X509);
+}
+
+int wolfSSL_ASN1_BIT_STRING_set_bit(WOLFSSL_ASN1_BIT_STRING* str, int pos,
+    int val)
+{
+    int bytes_cnt, bit;
+    byte* temp;
+
+    if (!str || (val != 0 && val != 1) || pos < 0) {
+        return WOLFSSL_FAILURE;
+    }
+
+    bytes_cnt = pos/8;
+    bit = 1<<(7-(pos%8));
+
+    if (bytes_cnt+1 > str->length) {
+        if (!(temp = (byte*)XREALLOC(str->data, bytes_cnt+1, NULL,
+                DYNAMIC_TYPE_OPENSSL))) {
+            return WOLFSSL_FAILURE;
+        }
+        XMEMSET(temp+str->length, 0, bytes_cnt+1 - str->length);
+        str->data = temp;
+        str->length = bytes_cnt+1;
+    }
+
+    str->data[bytes_cnt] &= ~bit;
+    str->data[bytes_cnt] |= val ? bit : 0;
+
+    return WOLFSSL_SUCCESS;
+}
+
+/* Gets the X509_EXTENSION* ext based on it's location in WOLFSSL_X509* x509.
+ *
+ * x509   : The X509 structure to look for the extension.
+ * loc    : Location of the extension. If the extension is found at the given
+ * location, a new X509_EXTENSION structure is populated with extension-specific
+ * data based on the extension type.
+
+ * Returns NULL on error or pointer to X509_EXTENSION structure containing the
+ * extension. The returned X509_EXTENSION should not be free'd by caller.
+ * The returned X509_EXTENSION is pushed onto a stack inside the x509 argument.
+ * This is later free'd when x509 is free'd.
+ *
+ * NOTE: for unknown extension NIDs, a X509_EXTENSION is populated with the
+ * extension oid as the ASN1_OBJECT (QT compatibility)
+ */
+WOLFSSL_X509_EXTENSION* wolfSSL_X509_get_ext(const WOLFSSL_X509* x509, int loc)
+{
+    WOLFSSL_X509_EXTENSION* ext = NULL;
+    WOLFSSL_ENTER("wolfSSL_X509_get_ext");
+    if (x509 == NULL)
+        return NULL;
+
+   ext = wolfSSL_X509_set_ext((WOLFSSL_X509*) x509, loc);
+   return ext;
+}
+
+/* Pushes a new X509_EXTENSION* ext onto the stack inside WOLFSSL_X509* x509.
+ * This is currently a helper function for wolfSSL_X509_get_ext
+ * Caller does not free the returned WOLFSSL_X509_EXTENSION*
+ */
+WOLFSSL_X509_EXTENSION* wolfSSL_X509_set_ext(WOLFSSL_X509* x509, int loc)
+{
+    int extCount = 0, length = 0, outSz = 0, sz = 0, ret = 0;
+    int objSz = 0, isSet = 0;
+    const byte* rawCert;
+    const byte* input;
+    byte* oidBuf;
+    word32 oid, idx = 0, tmpIdx = 0;
+    WOLFSSL_X509_EXTENSION* ext = NULL;
+    WOLFSSL_ASN1_INTEGER* a;
+    WOLFSSL_STACK* sk;
+    DecodedCert cert;
+
+    WOLFSSL_ENTER("wolfSSL_X509_set_ext");
+
+    if(x509 == NULL){
+        WOLFSSL_MSG("\tNot passed a certificate");
+        return NULL;
+    }
+
+    if(loc <0 || (loc > wolfSSL_X509_get_ext_count(x509))){
+        WOLFSSL_MSG("\tBad location argument");
+        return NULL;
+    }
+
+    ext = wolfSSL_X509_EXTENSION_new();
+    if (ext == NULL) {
+        WOLFSSL_MSG("\tX509_EXTENSION_new() failed");
+        return NULL;
+    }
+
+    rawCert = wolfSSL_X509_get_der((WOLFSSL_X509*)x509, &outSz);
+    if (rawCert == NULL) {
+        WOLFSSL_MSG("\tX509_get_der() failed");
+        wolfSSL_X509_EXTENSION_free(ext);
+        return NULL;
+    }
+
+    InitDecodedCert( &cert, rawCert, (word32)outSz, 0);
+
+    if (ParseCert(&cert, CA_TYPE, NO_VERIFY, NULL) < 0) {
+        WOLFSSL_MSG("\tCertificate parsing failed");
+        wolfSSL_X509_EXTENSION_free(ext);
+        return NULL;
+    }
+
+    input = cert.extensions;
+    sz = cert.extensionsSz;
+
+    if (input == NULL || sz == 0) {
+        WOLFSSL_MSG("\tfail: should be an EXTENSIONS");
+        wolfSSL_X509_EXTENSION_free(ext);
+        FreeDecodedCert(&cert);
+        return NULL;
+    }
+
+    if (input[idx++] != ASN_EXTENSIONS) {
+        WOLFSSL_MSG("\tfail: should be an EXTENSIONS");
+        wolfSSL_X509_EXTENSION_free(ext);
+        FreeDecodedCert(&cert);
+        return NULL;
+    }
+
+    if (GetLength(input, &idx, &length, sz) < 0) {
+        WOLFSSL_MSG("\tfail: invalid length");
+        wolfSSL_X509_EXTENSION_free(ext);
+        FreeDecodedCert(&cert);
+        return NULL;
+    }
+
+    if (GetSequence(input, &idx, &length, sz) < 0) {
+        WOLFSSL_MSG("\tfail: should be a SEQUENCE (1)");
+        wolfSSL_X509_EXTENSION_free(ext);
+        FreeDecodedCert(&cert);
+        return NULL;
+    }
+
+    while (idx < (word32)sz) {
+        oid = 0;
+
+        if (GetSequence(input, &idx, &length, sz) < 0) {
+            WOLFSSL_MSG("\tfail: should be a SEQUENCE");
+            wolfSSL_X509_EXTENSION_free(ext);
+            FreeDecodedCert(&cert);
+            return NULL;
+        }
+
+        tmpIdx = idx;
+        ret = GetObjectId(input, &idx, &oid, oidCertExtType, sz);
+        if (ret < 0) {
+            WOLFSSL_MSG("\tfail: OBJECT ID");
+            wolfSSL_X509_EXTENSION_free(ext);
+            FreeDecodedCert(&cert);
+            return NULL;
+        }
+        idx = tmpIdx;
+
+        /* Continue while loop until extCount == loc or idx > sz */
+        if (extCount != loc) {
+            idx += length;
+            extCount++;
+            continue;
+        }
+        /* extCount == loc. Now get the extension. */
+        /* Check if extension has been set */
+        isSet = wolfSSL_X509_ext_isSet_by_NID((WOLFSSL_X509*)x509, oid);
+        ext->obj = wolfSSL_OBJ_nid2obj(oid);
+        if (ext->obj == NULL) {
+            WOLFSSL_MSG("\tfail: Invalid OBJECT");
+            wolfSSL_X509_EXTENSION_free(ext);
+            FreeDecodedCert(&cert);
+            return NULL;
+        }
+        ext->obj->nid = oid;
+
+        switch (oid) {
+            case BASIC_CA_OID:
+                if (!isSet)
+                    break;
+                /* Set pathlength */
+                a = wolfSSL_ASN1_INTEGER_new();
+                if (a == NULL) {
+                    wolfSSL_X509_EXTENSION_free(ext);
+                    FreeDecodedCert(&cert);
+                    return NULL;
+                }
+                a->length = x509->pathLength;
+
+                /* Save ASN1_INTEGER in x509 extension */
+                ext->obj->pathlen = a;
+
+                ext->obj->ca = x509->isCa;
+                ext->crit = x509->basicConstCrit;
+                break;
+
+            case AUTH_INFO_OID:
+                if (!isSet)
+                    break;
+
+                /* Create a stack to hold both the caIssuer and ocsp objects
+                    in X509_EXTENSION structure */
+                sk = (WOLF_STACK_OF(WOLFSSL_ASN1_OBJECT)*)XMALLOC(
+                            sizeof(WOLF_STACK_OF(WOLFSSL_ASN1_OBJECT)),
+                            NULL, DYNAMIC_TYPE_ASN1);
+                if (sk == NULL) {
+                    WOLFSSL_MSG("Failed to malloc stack");
+                    wolfSSL_X509_EXTENSION_free(ext);
+                    FreeDecodedCert(&cert);
+                    return NULL;
+                }
+                XMEMSET(sk, 0, sizeof(WOLF_STACK_OF(WOLFSSL_ASN1_OBJECT)));
+                sk->type = STACK_TYPE_OBJ;
+
+                /* Add CaIssuers object to stack */
+                if (x509->authInfoCaIssuer != NULL &&
+                    x509->authInfoCaIssuerSz > 0)
+                {
+                    WOLFSSL_ASN1_OBJECT* obj;
+                    obj = wolfSSL_ASN1_OBJECT_new();
+                    if (obj == NULL) {
+                        WOLFSSL_MSG("Error creating ASN1 object");
+                        wolfSSL_sk_ASN1_OBJECT_free(sk);
+                        wolfSSL_X509_EXTENSION_free(ext);
+                        FreeDecodedCert(&cert);
+                        return NULL;
+                    }
+                    obj->obj = (byte*)x509->authInfoCaIssuer;
+                    obj->objSz = x509->authInfoCaIssuerSz;
+                    obj->grp = oidCertAuthInfoType;
+                    obj->nid = AIA_CA_ISSUER_OID;
+
+                    ret = wolfSSL_sk_ASN1_OBJECT_push(sk, obj);
+                    if (ret != WOLFSSL_SUCCESS) {
+                        WOLFSSL_MSG("Error pushing ASN1 object onto stack");
+                        wolfSSL_ASN1_OBJECT_free(obj);
+                        wolfSSL_sk_ASN1_OBJECT_free(sk);
+                        wolfSSL_X509_EXTENSION_free(ext);
+                        FreeDecodedCert(&cert);
+                        return NULL;
+                    }
+                }
+
+                /* Add OCSP object to stack */
+                if (x509->authInfo != NULL &&
+                    x509->authInfoSz > 0)
+                {
+                    WOLFSSL_ASN1_OBJECT* obj;
+                    obj = wolfSSL_ASN1_OBJECT_new();
+                    if (obj == NULL) {
+                        WOLFSSL_MSG("Error creating ASN1 object");
+                        wolfSSL_sk_ASN1_OBJECT_free(sk);
+                        wolfSSL_X509_EXTENSION_free(ext);
+                        FreeDecodedCert(&cert);
+                        return NULL;
+                    }
+                    obj->obj = x509->authInfo;
+                    obj->objSz = x509->authInfoSz;
+                    obj->grp = oidCertAuthInfoType;
+                    obj->nid = AIA_OCSP_OID;
+
+                    ret = wolfSSL_sk_ASN1_OBJECT_push(sk, obj);
+                    if (ret != WOLFSSL_SUCCESS) {
+                        WOLFSSL_MSG("Error pushing ASN1 object onto stack");
+                        wolfSSL_ASN1_OBJECT_free(obj);
+                        wolfSSL_sk_ASN1_OBJECT_free(sk);
+                        wolfSSL_X509_EXTENSION_free(ext);
+                        FreeDecodedCert(&cert);
+                        return NULL;
+                    }
+                }
+                ext->ext_sk = sk;
+                ext->crit = x509->authInfoCrit;
+                break;
+
+            case AUTH_KEY_OID:
+                if (!isSet)
+                    break;
+
+                ret = wolfSSL_ASN1_STRING_set(&ext->value, x509->authKeyId,
+                                        x509->authKeyIdSz);
+                if (ret != WOLFSSL_SUCCESS) {
+                    WOLFSSL_MSG("ASN1_STRING_set() failed");
+                    wolfSSL_X509_EXTENSION_free(ext);
+                    FreeDecodedCert(&cert);
+                    return NULL;
+                }
+                ext->crit = x509->authKeyIdCrit;
+                break;
+
+            case SUBJ_KEY_OID:
+                if (!isSet)
+                    break;
+
+                ret = wolfSSL_ASN1_STRING_set(&ext->value, x509->subjKeyId,
+                                        x509->subjKeyIdSz);
+                if (ret != WOLFSSL_SUCCESS) {
+                    WOLFSSL_MSG("ASN1_STRING_set() failed");
+                    wolfSSL_X509_EXTENSION_free(ext);
+                    FreeDecodedCert(&cert);
+                    return NULL;
+                }
+                ext->crit = x509->subjKeyIdCrit;
+                break;
+
+            case CERT_POLICY_OID:
+                if (!isSet)
+                    break;
+                ext->crit = x509->certPolicyCrit;
+                break;
+
+            case KEY_USAGE_OID:
+                if (!isSet)
+                    break;
+
+                ret = wolfSSL_ASN1_STRING_set(&ext->value,
+                                  (byte*)&(x509->keyUsage), sizeof(word16));
+                if (ret != WOLFSSL_SUCCESS) {
+                    WOLFSSL_MSG("ASN1_STRING_set() failed");
+                    wolfSSL_X509_EXTENSION_free(ext);
+                    FreeDecodedCert(&cert);
+                    return NULL;
+                }
+                ext->crit = x509->keyUsageCrit;
+                break;
+
+            case EXT_KEY_USAGE_OID:
+                if (!isSet)
+                    break;
+                ext->crit = x509->keyUsageCrit;
+                break;
+
+            case CRL_DIST_OID:
+                if (!isSet)
+                    break;
+                ext->crit = x509->CRLdistCrit;
+                break;
+
+            case ALT_NAMES_OID:
+            {
+                WOLFSSL_GENERAL_NAME* gn = NULL;
+                DNS_entry* dns = NULL;
+                if (!isSet)
+                    break;
+
+                sk = (WOLF_STACK_OF(WOLFSSL_GENERAL_NAME)*)XMALLOC(
+                          sizeof(WOLF_STACK_OF(WOLFSSL_GENERAL_NAME)), NULL,
+                                                         DYNAMIC_TYPE_ASN1);
+                if (sk == NULL) {
+                    return NULL;
+                }
+                XMEMSET(sk, 0, sizeof(WOLF_STACK_OF(WOLFSSL_GENERAL_NAME)));
+                sk->type = STACK_TYPE_GEN_NAME;
+
+                if (x509->subjAltNameSet && x509->altNames != NULL) {
+                    /* alt names are DNS_entry structs */
+                    dns = x509->altNames;
+                    /* Currently only support GEN_DNS type */
+                    while (dns != NULL) {
+                        gn = wolfSSL_GENERAL_NAME_new();
+                        if (gn == NULL) {
+                            WOLFSSL_MSG("Error creating GENERAL_NAME");
+                            wolfSSL_sk_free(sk);
+                            return NULL;
+                        }
+
+                        gn->type = dns->type;
+                        gn->d.ia5->length = dns->len;
+                        if (wolfSSL_ASN1_STRING_set(gn->d.ia5, dns->name,
+                                    gn->d.ia5->length) != WOLFSSL_SUCCESS) {
+                            WOLFSSL_MSG("ASN1_STRING_set failed");
+                            wolfSSL_GENERAL_NAME_free(gn);
+                            wolfSSL_sk_free(sk);
+                            return NULL;
+                        }
+
+                        dns = dns->next;
+                        /* last dns in list add at end of function */
+                        if (dns != NULL) {
+                            if (wolfSSL_sk_GENERAL_NAME_push(sk, gn) !=
+                                                          WOLFSSL_SUCCESS) {
+                            WOLFSSL_MSG("Error pushing onto stack");
+                            wolfSSL_GENERAL_NAME_free(gn);
+                            wolfSSL_sk_free(sk);
+                            sk = NULL;
+                            }
+                        }
+                    }
+                    if (wolfSSL_sk_GENERAL_NAME_push(sk,gn) !=
+                                                          WOLFSSL_SUCCESS) {
+                        WOLFSSL_MSG("Error pushing onto stack");
+                        wolfSSL_GENERAL_NAME_free(gn);
+                        wolfSSL_sk_free(sk);
+                        sk = NULL;
+                    }
+                }
+                ext->ext_sk = sk;
+                ext->crit = x509->subjAltNameCrit;
+                break;
+            }
+
+            default:
+                WOLFSSL_MSG("Unknown extension type found, parsing OID");
+                /* If the extension type is not recognized/supported,
+                    set the ASN1_OBJECT in the extension with the
+                    parsed oid for access in later function calls */
+
+                /* Get OID from input */
+                if (GetASNObjectId(input, &idx, &length, sz) != 0) {
+                    WOLFSSL_MSG("Failed to Get ASN Object Id");
+                    wolfSSL_X509_EXTENSION_free(ext);
+                    FreeDecodedCert(&cert);
+                    return NULL;
+                }
+                oidBuf = (byte*)XMALLOC(length+1+MAX_LENGTH_SZ, NULL,
+                                    DYNAMIC_TYPE_TMP_BUFFER);
+                if (oidBuf == NULL) {
+                    WOLFSSL_MSG("Failed to malloc tmp buffer");
+                    wolfSSL_X509_EXTENSION_free(ext);
+                    FreeDecodedCert(&cert);
+                    return NULL;
+                }
+                oidBuf[0] = ASN_OBJECT_ID;
+                objSz++;
+                objSz += SetLength(length, oidBuf + 1);
+                objSz += length;
+
+                /* Set object size and reallocate space in object buffer */
+                ext->obj->objSz = objSz;
+                if(((ext->obj->dynamic & WOLFSSL_ASN1_DYNAMIC_DATA) != 0) ||
+                   (ext->obj->obj == NULL)) {
+                        ext->obj->obj =(byte*)XREALLOC((byte*)ext->obj->obj,
+                                             ext->obj->objSz,
+                                             NULL,DYNAMIC_TYPE_ASN1);
+                    if (ext->obj->obj == NULL) {
+                        wolfSSL_ASN1_OBJECT_free(ext->obj);
+                        wolfSSL_X509_EXTENSION_free(ext);
+                        FreeDecodedCert(&cert);
+                        return NULL;
+                    }
+                    ext->obj->dynamic |= WOLFSSL_ASN1_DYNAMIC_DATA;
+                } else {
+                    ext->obj->dynamic &= ~WOLFSSL_ASN1_DYNAMIC_DATA;
+                }
+                /* Get OID from input and copy to ASN1_OBJECT buffer */
+                XMEMCPY(oidBuf+2, input+idx, length);
+                XMEMCPY((byte*)ext->obj->obj, oidBuf, ext->obj->objSz);
+                XFREE(oidBuf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+                oidBuf = NULL;
+                ext->obj->grp = oidCertExtType;
+                ext->crit = 0;
+
+                /* Get extension data and copy as ASN1_STRING */
+                tmpIdx = idx + length;
+                if ((tmpIdx >= (word32)sz) || (input[tmpIdx++] != ASN_OCTET_STRING)) {
+                    WOLFSSL_MSG("Error decoding unknown extension data");
+                    wolfSSL_ASN1_OBJECT_free(ext->obj);
+                    wolfSSL_X509_EXTENSION_free(ext);
+                    FreeDecodedCert(&cert);
+                    return NULL;
+                }
+
+                if (GetLength(input, &tmpIdx, &length, sz) <= 0) {
+                    WOLFSSL_MSG("Error: Invalid Input Length.");
+                    wolfSSL_ASN1_OBJECT_free(ext->obj);
+                    wolfSSL_X509_EXTENSION_free(ext);
+                    FreeDecodedCert(&cert);
+                    return NULL;
+                }
+                ext->value.data = (char*)XMALLOC(length, NULL, DYNAMIC_TYPE_ASN1);
+                ext->value.isDynamic = 1;
+                if (ext->value.data == NULL) {
+                    WOLFSSL_MSG("Failed to malloc ASN1_STRING data");
+                    wolfSSL_X509_EXTENSION_free(ext);
+                    FreeDecodedCert(&cert);
+                    return NULL;
+                }
+                XMEMCPY(ext->value.data,input+tmpIdx,length);
+                ext->value.length = length;
+        } /* switch(oid) */
+
+        break; /* Got the Extension. Now exit while loop. */
+
+    } /* while(idx < sz) */
+
+    /* Store the new extension in a stack inside x509
+     * The extensions on the stack are free'd internally when FreeX509 is called
+     */
+    if (x509->ext_sk == NULL)
+        x509->ext_sk = wolfSSL_sk_new_x509_ext();
+    if (x509->ext_sk != NULL)
+        wolfSSL_sk_X509_EXTENSION_push(x509->ext_sk, ext);
+
+    FreeDecodedCert(&cert);
+    return ext;
+}
+
+/* Return 0 on success and 1 on failure. Copies ext data to bio, using indent
+ *  to pad the output. flag is ignored. */
+int wolfSSL_X509V3_EXT_print(WOLFSSL_BIO *out, WOLFSSL_X509_EXTENSION *ext,
+        unsigned long flag, int indent)
+{
+    ASN1_OBJECT* obj;
+    ASN1_STRING* str;
+    int nid;
+    const int sz = CTC_NAME_SIZE*2;
+    int rc = WOLFSSL_FAILURE;
+    char tmp[CTC_NAME_SIZE*2];
+    WOLFSSL_ENTER("wolfSSL_X509V3_EXT_print");
+
+    if ((out == NULL) || (ext == NULL)) {
+        WOLFSSL_MSG("NULL parameter error");
+        return rc;
+    }
+
+    obj = wolfSSL_X509_EXTENSION_get_object(ext);
+    if (obj == NULL) {
+        WOLFSSL_MSG("Error getting ASN1_OBJECT from X509_EXTENSION");
+        return rc;
+    }
+
+    str = wolfSSL_X509_EXTENSION_get_data(ext);
+    if (obj == NULL) {
+        WOLFSSL_MSG("Error getting ASN1_STRING from X509_EXTENSION");
+        return rc;
+    }
+
+    /* Print extension based on the type */
+    nid = wolfSSL_OBJ_obj2nid(obj);
+    switch (nid) {
+        case BASIC_CA_OID:
+        {
+            char isCa[] = "TRUE";
+            char notCa[] = "FALSE";
+            XSNPRINTF(tmp, sz, "%*sCA:%s", indent, "",
+                                                    obj->ca ? isCa : notCa);
+            break;
+        }
+        case ALT_NAMES_OID:
+        {
+            WOLFSSL_STACK* sk;
+            char* val;
+            int len;
+            tmp[0] = '\0'; /* Make sure tmp is null-terminated */
+
+            sk = ext->ext_sk;
+            while (sk != NULL) {
+                if (sk->type == STACK_TYPE_GEN_NAME && sk->data.gn) {
+                    /* str is GENERAL_NAME for subject alternative name ext */
+                    str = sk->data.gn->d.ia5;
+                    len = str->length + 2; /* + 2 for NULL char and "," */
+                    if (len > sz) {
+                        WOLFSSL_MSG("len greater than buffer size");
+                        return rc;
+                    }
+
+                    val = (char*)XMALLOC(len + indent, NULL,
+                                                       DYNAMIC_TYPE_TMP_BUFFER);
+                    if (val == NULL) {
+                        WOLFSSL_MSG("Memory error");
+                        return rc;
+                    }
+                    if (sk->next)
+                        XSNPRINTF(val, len, "%*s%s, ", indent, "", str->strData);
+                    else
+                        XSNPRINTF(val, len, "%*s%s", indent, "", str->strData);
+
+                    XSTRNCAT(tmp, val, len);
+                    XFREE(val, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+                }
+                sk = sk->next;
+            }
+            break;
+        }
+        case AUTH_KEY_OID:
+        case SUBJ_KEY_OID:
+        {
+            char* asn1str;
+            asn1str = wolfSSL_i2s_ASN1_STRING(NULL, str);
+            XSNPRINTF(tmp, sz, "%*s%s", indent, "", asn1str);
+            XFREE(asn1str, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+            break;
+        }
+        case AUTH_INFO_OID:
+        case CERT_POLICY_OID:
+        case CRL_DIST_OID:
+        case KEY_USAGE_OID:
+            WOLFSSL_MSG("X509V3_EXT_print not yet implemented for ext type");
+            break;
+
+        default:
+            XSNPRINTF(tmp, sz, "%*s%s", indent, "", str->strData);
+    }
+
+    if (wolfSSL_BIO_write(out, tmp, (int)XSTRLEN(tmp)) == (int)XSTRLEN(tmp)) {
+        rc = WOLFSSL_SUCCESS;
+    }
+    (void) flag;
+
+    return rc;
+}
+
+/* Returns crit flag in X509_EXTENSION object */
+int wolfSSL_X509_EXTENSION_get_critical(const WOLFSSL_X509_EXTENSION* ex)
+{
+    WOLFSSL_ENTER("wolfSSL_X509_EXTENSION_get_critical");
+    if (ex == NULL)
+        return BAD_FUNC_ARG;
+    return ex->crit;
+}
+
+/* Creates v3_ext_method for a given X509v3 extension
+ *
+ * ex   : The X509_EXTENSION used to create v3_ext_method. If the extension is
+ * not NULL, get the NID of the extension object and populate the
+ * extension type-specific X509V3_EXT_* function(s) in v3_ext_method.
+ *
+ * Returns NULL on error or pointer to the v3_ext_method populated with extension
+ * type-specific X509V3_EXT_* function(s).
+ *
+ * NOTE: NID_subject_key_identifier is currently the only extension implementing
+ * the X509V3_EXT_* functions, as it is the only type called directly by QT. The
+ * other extension types return a pointer to a v3_ext_method struct that contains
+ * only the NID.
+ */
+const WOLFSSL_v3_ext_method* wolfSSL_X509V3_EXT_get(WOLFSSL_X509_EXTENSION* ex)
+{
+    int nid;
+    WOLFSSL_v3_ext_method method;
+
+    WOLFSSL_ENTER("wolfSSL_X509V3_EXT_get");
+    if ((ex == NULL) || (ex->obj == NULL)) {
+        WOLFSSL_MSG("Passed an invalid X509_EXTENSION*");
+        return NULL;
+    }
+    /* Initialize all methods to NULL */
+    method.d2i = NULL;
+    method.i2v = NULL;
+    method.i2s = NULL;
+    method.i2r = NULL;
+
+    nid = ex->obj->nid;
+    if (nid <= 0) {
+        WOLFSSL_MSG("Failed to get nid from passed extension object");
+        return NULL;
+    }
+
+    switch (nid) {
+        case NID_basic_constraints:
+            break;
+        case NID_subject_key_identifier:
+            method.i2s = (X509V3_EXT_I2S)wolfSSL_i2s_ASN1_STRING;
+            break;
+        case NID_key_usage:
+            WOLFSSL_MSG("i2v function not yet implemented for Key Usage");
+            break;
+        case NID_authority_key_identifier:
+            WOLFSSL_MSG("i2v function not yet implemented for Auth Key Id");
+            break;
+        case NID_info_access:
+            WOLFSSL_MSG("i2v function not yet implemented for Info Access");
+            break;
+        case NID_ext_key_usage:
+            WOLFSSL_MSG("i2v function not yet implemented for Ext Key Usage");
+            break;
+        case NID_certificate_policies:
+            WOLFSSL_MSG("r2i function not yet implemented for Cert Policies");
+            break;
+        case NID_crl_distribution_points:
+            WOLFSSL_MSG("r2i function not yet implemented for CRL Dist Points");
+            break;
+        default:
+            /* If extension type is unknown, return NULL -- QT makes call to
+                X509_EXTENSION_get_data() if there is no v3_ext_method */
+            WOLFSSL_MSG("X509V3_EXT_get(): Unknown extension type found");
+            return NULL;
+    }
+
+    method.ext_nid = nid;
+    ex->ext_method = method;
+
+    return (const WOLFSSL_v3_ext_method*)&ex->ext_method;
+}
+
+/* Parses and returns an x509v3 extension internal structure.
+ *
+ * ext   : The X509_EXTENSION for parsing internal structure. If extension is
+ * not NULL, get the NID of the extension object and create a new
+ * extension-specific internal structure based on the extension type.
+ *
+ * Returns NULL on error or if NID is not found, otherwise returns a pointer to
+ * the extension type-specific X509_EXTENSION internal structure.
+ * Return is expected to be free'd by caller.
+ */
+void* wolfSSL_X509V3_EXT_d2i(WOLFSSL_X509_EXTENSION* ext)
+{
+    const WOLFSSL_v3_ext_method* method;
+    int ret;
+    WOLFSSL_ASN1_OBJECT* object;
+    WOLFSSL_BASIC_CONSTRAINTS* bc;
+    WOLFSSL_AUTHORITY_KEYID* akey;
+    WOLFSSL_ASN1_STRING* asn1String, *newString;
+    WOLFSSL_AUTHORITY_INFO_ACCESS* aia;
+    WOLFSSL_STACK* sk;
+
+    WOLFSSL_ENTER("wolfSSL_X509V3_EXT_d2i");
+
+    if(ext == NULL) {
+        WOLFSSL_MSG("Bad function Argument");
+        return NULL;
+    }
+
+    /* extract extension info */
+    method = wolfSSL_X509V3_EXT_get(ext);
+    if (method == NULL) {
+        WOLFSSL_MSG("wolfSSL_X509V3_EXT_get error");
+        return NULL;
+    }
+    object = wolfSSL_X509_EXTENSION_get_object(ext);
+    if (object == NULL) {
+        WOLFSSL_MSG("X509_EXTENSION_get_object failed");
+        return NULL;
+    }
+
+    /* Return pointer to proper internal structure based on NID */
+    switch (object->type) {
+        /* basicConstraints */
+        case (NID_basic_constraints):
+            WOLFSSL_MSG("basicConstraints");
+            /* Allocate new BASIC_CONSTRAINTS structure */
+            bc = (WOLFSSL_BASIC_CONSTRAINTS*)
+                  XMALLOC(sizeof(WOLFSSL_BASIC_CONSTRAINTS), NULL,
+                  DYNAMIC_TYPE_X509_EXT);
+            if (bc == NULL) {
+                WOLFSSL_MSG("Failed to malloc basic constraints");
+                return NULL;
+            }
+            /* Copy pathlen and CA into BASIC_CONSTRAINTS from object */
+            bc->ca = object->ca;
+            if (object->pathlen->length > 0) {
+                bc->pathlen = wolfSSL_ASN1_INTEGER_dup(object->pathlen);
+                if (bc->pathlen == NULL) {
+                    WOLFSSL_MSG("Failed to duplicate ASN1_INTEGER");
+                    XFREE(bc, NULL, DYNAMIC_TYPE_X509_EXT);
+                    return NULL;
+                }
+            }
+            else
+                bc->pathlen = NULL;
+            return bc;
+
+        /* subjectKeyIdentifier */
+        case (NID_subject_key_identifier):
+            WOLFSSL_MSG("subjectKeyIdentifier");
+            asn1String = wolfSSL_X509_EXTENSION_get_data(ext);
+            if (asn1String == NULL) {
+                WOLFSSL_MSG("X509_EXTENSION_get_data() failed");
+                return NULL;
+            }
+            newString = wolfSSL_ASN1_STRING_new();
+            if (newString == NULL) {
+                WOLFSSL_MSG("Failed to malloc ASN1_STRING");
+                return NULL;
+            }
+            ret = wolfSSL_ASN1_STRING_set(newString, asn1String->data,
+                                                            asn1String->length);
+            if (ret != WOLFSSL_SUCCESS) {
+                WOLFSSL_MSG("ASN1_STRING_set() failed");
+                wolfSSL_ASN1_STRING_free(newString);
+                return NULL;
+            };
+            newString->type = asn1String->type;
+            return newString;
+
+        /* authorityKeyIdentifier */
+        case (NID_authority_key_identifier):
+            WOLFSSL_MSG("AuthorityKeyIdentifier");
+
+            akey = (WOLFSSL_AUTHORITY_KEYID*)
+                    XMALLOC(sizeof(WOLFSSL_AUTHORITY_KEYID), NULL,
+                    DYNAMIC_TYPE_X509_EXT);
+            if (akey == NULL) {
+                WOLFSSL_MSG("Failed to malloc authority key id");
+                return NULL;
+            }
+
+            akey->keyid = wolfSSL_ASN1_STRING_new();
+            if (akey->keyid == NULL) {
+                WOLFSSL_MSG("ASN1_STRING_new() failed");
+                wolfSSL_AUTHORITY_KEYID_free(akey);
+                return NULL;
+            }
+
+            asn1String = wolfSSL_X509_EXTENSION_get_data(ext);
+            if (asn1String == NULL) {
+                WOLFSSL_MSG("X509_EXTENSION_get_data() failed");
+                wolfSSL_AUTHORITY_KEYID_free(akey);
+                return NULL;
+            }
+
+            ret = wolfSSL_ASN1_STRING_set(akey->keyid, asn1String->data,
+                                                            asn1String->length);
+            if (ret != WOLFSSL_SUCCESS) {
+                WOLFSSL_MSG("ASN1_STRING_set() failed");
+                wolfSSL_AUTHORITY_KEYID_free(akey);
+                return NULL;
+            };
+            akey->keyid->type   = asn1String->type;
+
+            /* For now, set issuer and serial to NULL. This may need to be
+                updated for future use */
+            akey->issuer = NULL;
+            akey->serial = NULL;
+            return akey;
+
+        /* keyUsage */
+        case (NID_key_usage):
+            WOLFSSL_MSG("keyUsage");
+            /* This may need to be updated for future use. The i2v method for
+                keyUsage is not currently set. For now, return the ASN1_STRING
+                representation of KeyUsage bit string */
+            asn1String = wolfSSL_X509_EXTENSION_get_data(ext);
+            if (asn1String == NULL) {
+                WOLFSSL_MSG("X509_EXTENSION_get_data() failed");
+                return NULL;
+            }
+            newString = wolfSSL_ASN1_STRING_new();
+            if (newString == NULL) {
+                WOLFSSL_MSG("Failed to malloc ASN1_STRING");
+                return NULL;
+            }
+            ret = wolfSSL_ASN1_STRING_set(newString, asn1String->data,
+                                                            asn1String->length);
+            if (ret != WOLFSSL_SUCCESS) {
+                WOLFSSL_MSG("ASN1_STRING_set() failed");
+                wolfSSL_ASN1_STRING_free(newString);
+                return NULL;
+            };
+            newString->type = asn1String->type;
+            return newString;
+
+        /* extKeyUsage */
+        case (NID_ext_key_usage):
+            WOLFSSL_MSG("extKeyUsage not supported yet");
+            return NULL;
+
+        /* certificatePolicies */
+        case (NID_certificate_policies):
+            WOLFSSL_MSG("certificatePolicies not supported yet");
+            return NULL;
+
+        /* cRLDistributionPoints */
+        case (NID_crl_distribution_points):
+            WOLFSSL_MSG("cRLDistributionPoints not supported yet");
+            return NULL;
+
+        /* authorityInfoAccess */
+        case (NID_info_access):
+            WOLFSSL_MSG("AuthorityInfoAccess");
+
+            sk = ext->ext_sk;
+            if (sk == NULL) {
+                WOLFSSL_MSG("ACCESS_DESCRIPTION stack NULL");
+                return NULL;
+            }
+
+            /* AUTHORITY_INFO_ACCESS is a stack of ACCESS_DESCRIPTION entries */
+            aia = wolfSSL_sk_new_null();
+            if (aia == NULL) {
+                WOLFSSL_MSG("Failed to malloc AUTHORITY_INFO_ACCESS");
+                return NULL;
+            }
+            aia->type = STACK_TYPE_ACCESS_DESCRIPTION;
+
+            while (sk) {
+                WOLFSSL_ACCESS_DESCRIPTION* ad;
+                WOLFSSL_ASN1_OBJECT* aiaEntry;
+
+                if (sk->type != STACK_TYPE_OBJ) {
+                    sk = sk->next;
+                    continue;
+                }
+
+                aiaEntry = sk->data.obj;
+
+                /* ACCESS_DESCRIPTION has two members, method and location.
+                Method: ASN1_OBJECT as either AIA_OCSP_OID or AIA_CA_ISSUER_OID
+                Location: GENERAL_NAME structure containing the URI. */
+
+                ad = (WOLFSSL_ACCESS_DESCRIPTION*)
+                        XMALLOC(sizeof(WOLFSSL_ACCESS_DESCRIPTION), NULL,
+                        DYNAMIC_TYPE_X509_EXT);
+                if (ad == NULL) {
+                    WOLFSSL_MSG("Failed to malloc ACCESS_DESCRIPTION");
+                    XFREE(aia, NULL, DYNAMIC_TYPE_X509_EXT);
+                    return NULL;
+                }
+                XMEMSET(ad, 0, sizeof(WOLFSSL_ACCESS_DESCRIPTION));
+
+                /* Create new ASN1_OBJECT from oid */
+                ad->method = wolfSSL_OBJ_nid2obj(aiaEntry->nid);
+                if (ad->method == NULL) {
+                    WOLFSSL_MSG("OBJ_nid2obj() failed");
+                    XFREE(aia, NULL, DYNAMIC_TYPE_X509_EXT);
+                    XFREE(ad, NULL, DYNAMIC_TYPE_X509_EXT);
+                    return NULL;
+                }
+
+                /* Allocate memory for GENERAL NAME */
+                ad->location = (WOLFSSL_GENERAL_NAME*)
+                                XMALLOC(sizeof(WOLFSSL_GENERAL_NAME), NULL,
+                                DYNAMIC_TYPE_OPENSSL);
+                if (ad->location == NULL) {
+                    WOLFSSL_MSG("Failed to malloc GENERAL_NAME");
+                    wolfSSL_ASN1_OBJECT_free(ad->method);
+                    XFREE(aia, NULL, DYNAMIC_TYPE_X509_EXT);
+                    XFREE(ad, NULL, DYNAMIC_TYPE_X509_EXT);
+                    return NULL;
+                }
+                XMEMSET(ad->location, 0, sizeof(WOLFSSL_GENERAL_NAME));
+                ad->location->type = GEN_URI;
+                ad->location->d.uniformResourceIdentifier =
+                                    wolfSSL_ASN1_STRING_new();
+                /* Set the URI in GENERAL_NAME */
+                ret = wolfSSL_ASN1_STRING_set(
+                                    ad->location->d.uniformResourceIdentifier,
+                                    aiaEntry->obj, aiaEntry->objSz);
+                if (ret != WOLFSSL_SUCCESS) {
+                    WOLFSSL_MSG("ASN1_STRING_set() failed");
+                    wolfSSL_ASN1_OBJECT_free(ad->method);
+                    XFREE(aia, NULL, DYNAMIC_TYPE_X509_EXT);
+                    XFREE(ad, NULL, DYNAMIC_TYPE_X509_EXT);
+                    return NULL;
+                }
+                /* Push to AUTHORITY_INFO_ACCESS stack */
+                ret = wolfSSL_sk_ACCESS_DESCRIPTION_push(aia, ad);
+                if (ret != WOLFSSL_SUCCESS) {
+                    WOLFSSL_MSG("Error pushing ASN1 AD onto stack");
+                    wolfSSL_sk_ACCESS_DESCRIPTION_pop_free(aia, NULL);
+                    wolfSSL_ASN1_OBJECT_free(ad->method);
+                    XFREE(aia, NULL, DYNAMIC_TYPE_X509_EXT);
+                    XFREE(ad, NULL, DYNAMIC_TYPE_X509_EXT);
+                    return NULL;
+                }
+
+                sk = sk->next;
+            }
+            return aia;
+
+        default:
+            WOLFSSL_MSG("Extension NID not in table, returning NULL");
+            break;
+    }
+    return NULL;
+}
+
+/* Looks for the extension matching the passed in nid
+ *
+ * x509 : certificate to get parse through for extension.
+ * nid : Extension OID to be found.
+ * lastPos : Start search from extension after lastPos.
+ *           Set to -1 to search from index 0.
+ * return >= 0 If successful the extension index is returned.
+ * return -1 If extension is not found or error is encountered.
+ */
+int wolfSSL_X509_get_ext_by_NID(const WOLFSSL_X509* x509, int nid, int lastPos)
+{
+    int extCount = 0, length = 0, outSz = 0, sz = 0, ret = 0;
+    int isSet = 0, found = 0, loc;
+    const byte* rawCert;
+    const byte* input;
+    word32 oid, idx = 0, tmpIdx = 0;
+    DecodedCert cert;
+
+    WOLFSSL_ENTER("wolfSSL_X509_get_ext_by_NID");
+
+    if(x509 == NULL){
+        WOLFSSL_MSG("\tNot passed a certificate");
+        return WOLFSSL_FATAL_ERROR;
+    }
+
+    if(lastPos < -1 || (lastPos > (wolfSSL_X509_get_ext_count(x509) - 1))){
+        WOLFSSL_MSG("\tBad location argument");
+        return WOLFSSL_FATAL_ERROR;
+    }
+
+    loc = lastPos + 1;
+
+    rawCert = wolfSSL_X509_get_der((WOLFSSL_X509*)x509, &outSz);
+    if (rawCert == NULL) {
+        WOLFSSL_MSG("\tX509_get_der() failed");
+        return WOLFSSL_FATAL_ERROR;
+    }
+
+    InitDecodedCert( &cert, rawCert, (word32)outSz, 0);
+
+    if (ParseCert(&cert, CA_TYPE, NO_VERIFY, NULL) < 0) {
+        WOLFSSL_MSG("\tCertificate parsing failed");
+        return WOLFSSL_FATAL_ERROR;
+    }
+
+    input = cert.extensions;
+    sz = cert.extensionsSz;
+
+    if (input == NULL || sz == 0) {
+        WOLFSSL_MSG("\tfail: should be an EXTENSIONS");
+        FreeDecodedCert(&cert);
+        return WOLFSSL_FATAL_ERROR;
+    }
+
+    if (input[idx++] != ASN_EXTENSIONS) {
+        WOLFSSL_MSG("\tfail: should be an EXTENSIONS");
+        FreeDecodedCert(&cert);
+        return WOLFSSL_FATAL_ERROR;
+    }
+
+    if (GetLength(input, &idx, &length, sz) < 0) {
+        WOLFSSL_MSG("\tfail: invalid length");
+        FreeDecodedCert(&cert);
+        return WOLFSSL_FATAL_ERROR;
+    }
+
+    if (GetSequence(input, &idx, &length, sz) < 0) {
+        WOLFSSL_MSG("\tfail: should be a SEQUENCE (1)");
+        FreeDecodedCert(&cert);
+        return WOLFSSL_FATAL_ERROR;
+    }
+
+    while (idx < (word32)sz) {
+        oid = 0;
+
+        if (GetSequence(input, &idx, &length, sz) < 0) {
+            WOLFSSL_MSG("\tfail: should be a SEQUENCE");
+            FreeDecodedCert(&cert);
+            return WOLFSSL_FATAL_ERROR;
+        }
+
+        tmpIdx = idx;
+        ret = GetObjectId(input, &idx, &oid, oidCertExtType, sz);
+        if (ret < 0) {
+            WOLFSSL_MSG("\tfail: OBJECT ID");
+            FreeDecodedCert(&cert);
+            return WOLFSSL_FATAL_ERROR;
+        }
+        idx = tmpIdx;
+
+        if (extCount >= loc) {
+            /* extCount >= loc. Now check if extension has been set */
+            isSet = wolfSSL_X509_ext_isSet_by_NID((WOLFSSL_X509*)x509, oid);
+
+            if (isSet && ((word32)nid == oid)) {
+                found = 1;
+                break;
+            }
+        }
+
+        idx += length;
+        extCount++;
+    } /* while(idx < sz) */
+
+    FreeDecodedCert(&cert);
+
+    return found ? extCount : WOLFSSL_FATAL_ERROR;
+}
+
+
+#endif /* OPENSSL_ALL */
+
+WOLFSSL_ASN1_BIT_STRING* wolfSSL_ASN1_BIT_STRING_new(void)
+{
+    WOLFSSL_ASN1_BIT_STRING* str;
+
+    str = (WOLFSSL_ASN1_BIT_STRING*)XMALLOC(sizeof(WOLFSSL_ASN1_BIT_STRING),
+                                                  NULL, DYNAMIC_TYPE_OPENSSL);
+    if (str) {
+        XMEMSET(str, 0, sizeof(WOLFSSL_ASN1_BIT_STRING));
+    }
+    return str;
+}
+
+void wolfSSL_ASN1_BIT_STRING_free(WOLFSSL_ASN1_BIT_STRING* str)
+{
+    if (str) {
+        if (str->data) {
+            XFREE(str->data, NULL, DYNAMIC_TYPE_OPENSSL);
+            str->data = NULL;
+        }
+        XFREE(str, NULL, DYNAMIC_TYPE_OPENSSL);
+    }
+}
+
+int wolfSSL_ASN1_BIT_STRING_get_bit(const WOLFSSL_ASN1_BIT_STRING* str, int i)
+{
+    if (!str || !str->data || str->length <= (i/8) || i < 0) {
+        return WOLFSSL_FAILURE;
+    }
+
+    return (str->data[i/8] & (1<<(7-(i%8)))) ? 1 : 0;
+}
+
+/* Looks for the extension matching the passed in nid
+ *
+ * c   : if not null then is set to status value -2 if multiple occurrences
+ *       of the extension are found, -1 if not found, 0 if found and not
+ *       critical, and 1 if found and critical.
+ * nid : Extension OID to be found.
+ * idx : if NULL return first extension found match, otherwise start search at
+ *       idx location and set idx to the location of extension returned.
+ * returns NULL or a pointer to an WOLFSSL_ASN1_BIT_STRING (for KEY_USAGE_OID)
+ * or WOLFSSL_STACK (for other)
+ * holding extension structure
+ *
+ * NOTE code for decoding extensions is in asn.c DecodeCertExtensions --
+ * use already decoded extension in this function to avoid decoding twice.
+ * Currently we do not make use of idx since getting pre decoded extensions.
+ */
+void* wolfSSL_X509_get_ext_d2i(const WOLFSSL_X509* x509, int nid, int* c,
+    int* idx)
+{
+    void* ret = NULL;
+    WOLFSSL_STACK* sk = NULL;
+    WOLFSSL_ASN1_OBJECT* obj = NULL;
+    WOLFSSL_GENERAL_NAME* gn = NULL;
+
+    WOLFSSL_ENTER("wolfSSL_X509_get_ext_d2i");
+
+    if (x509 == NULL) {
+        return NULL;
+    }
+
+    if (c != NULL) {
+        *c = -1; /* default to not found */
+    }
+
+    switch (nid) {
+        case BASIC_CA_OID:
+            if (x509->basicConstSet) {
+                obj = wolfSSL_ASN1_OBJECT_new();
+                if (obj == NULL) {
+                    WOLFSSL_MSG("Issue creating WOLFSSL_ASN1_OBJECT struct");
+                    return NULL;
+                }
+                if (c != NULL) {
+                    *c = x509->basicConstCrit;
+                }
+                obj->type = BASIC_CA_OID;
+                obj->grp  = oidCertExtType;
+                obj->nid  = nid;
+                obj->dynamic |= WOLFSSL_ASN1_DYNAMIC;
+            #if defined(OPENSSL_ALL) || defined(WOLFSSL_QT) || \
+                    defined(WOLFSSL_APACHE_HTTPD)
+                obj->ca = x509->isCa;
+            #endif
+            }
+            else {
+                WOLFSSL_MSG("No Basic Constraint set");
+            }
+            return obj;
+
+        case ALT_NAMES_OID:
+        {
+            DNS_entry* dns = NULL;
+            /* Malloc GENERAL_NAME stack */
+            sk = (WOLF_STACK_OF(WOLFSSL_GENERAL_NAME)*)XMALLOC(
+                        sizeof(WOLF_STACK_OF(WOLFSSL_GENERAL_NAME)), NULL,
+                                                         DYNAMIC_TYPE_ASN1);
+            if (sk == NULL) {
+                return NULL;
+            }
+            XMEMSET(sk, 0, sizeof(WOLF_STACK_OF(WOLFSSL_GENERAL_NAME)));
+            sk->type = STACK_TYPE_GEN_NAME;
+
+            if (x509->subjAltNameSet && x509->altNames != NULL) {
+                /* alt names are DNS_entry structs */
+                if (c != NULL) {
+                    if (x509->altNames->next != NULL) {
+                        *c = -2; /* more then one found */
+                    }
+                    else {
+                        *c = x509->subjAltNameCrit;
+                    }
+                }
+
+                dns = x509->altNames;
+                /* Currently only support GEN_DNS type */
+                while (dns != NULL) {
+                    gn = wolfSSL_GENERAL_NAME_new();
+                    if (gn == NULL) {
+                        WOLFSSL_MSG("Error creating GENERAL_NAME");
+                        wolfSSL_sk_free(sk);
+                        return NULL;
+                    }
+
+                    gn->type = dns->type;
+                    gn->d.ia5->length = dns->len;
+                    if (wolfSSL_ASN1_STRING_set(gn->d.ia5, dns->name,
+                                gn->d.ia5->length) != WOLFSSL_SUCCESS) {
+                        WOLFSSL_MSG("ASN1_STRING_set failed");
+                        wolfSSL_GENERAL_NAME_free(gn);
+                        wolfSSL_sk_free(sk);
+                        return NULL;
+                    }
+
+                    dns = dns->next;
+                    /* last dns in list add at end of function */
+                    if (dns != NULL) {
+                        if (wolfSSL_sk_GENERAL_NAME_push(sk, gn) !=
+                                                          WOLFSSL_SUCCESS) {
+                            WOLFSSL_MSG("Error pushing ASN1 object onto stack");
+                            wolfSSL_GENERAL_NAME_free(gn);
+                            wolfSSL_sk_free(sk);
+                            sk = NULL;
+                        }
+                    }
+                }
+            }
+            else {
+                WOLFSSL_MSG("No Alt Names set");
+            }
+
+            break;
+        }
+
+        case CRL_DIST_OID:
+            if (x509->CRLdistSet && x509->CRLInfo != NULL) {
+                if (c != NULL) {
+                    *c = x509->CRLdistCrit;
+                }
+                obj = wolfSSL_ASN1_OBJECT_new();
+                if (obj == NULL) {
+                    WOLFSSL_MSG("Issue creating WOLFSSL_ASN1_OBJECT struct");
+                    return NULL;
+                }
+                obj->type  = CRL_DIST_OID;
+                obj->grp   = oidCertExtType;
+                obj->obj   = x509->CRLInfo;
+                obj->objSz = x509->CRLInfoSz;
+                obj->dynamic |= WOLFSSL_ASN1_DYNAMIC;
+                obj->dynamic &= ~WOLFSSL_ASN1_DYNAMIC_DATA ;
+            }
+            else {
+                WOLFSSL_MSG("No CRL dist set");
+            }
+            break;
+
+        case AUTH_INFO_OID:
+            if (x509->authInfoSet && x509->authInfo != NULL) {
+                if (c != NULL) {
+                    *c = x509->authInfoCrit;
+                }
+                obj = wolfSSL_ASN1_OBJECT_new();
+                if (obj == NULL) {
+                    WOLFSSL_MSG("Issue creating WOLFSSL_ASN1_OBJECT struct");
+                    return NULL;
+                }
+                obj->type  = AUTH_INFO_OID;
+                obj->grp   = oidCertExtType;
+                obj->obj   = x509->authInfo;
+                obj->objSz = x509->authInfoSz;
+                obj->dynamic |= WOLFSSL_ASN1_DYNAMIC;
+                obj->dynamic &= ~WOLFSSL_ASN1_DYNAMIC_DATA;
+            }
+            else {
+                WOLFSSL_MSG("No Auth Info set");
+            }
+            break;
+
+        case AUTH_KEY_OID:
+            if (x509->authKeyIdSet) {
+                if (c != NULL) {
+                    *c = x509->authKeyIdCrit;
+                }
+                obj = wolfSSL_ASN1_OBJECT_new();
+                if (obj == NULL) {
+                    WOLFSSL_MSG("Issue creating WOLFSSL_ASN1_OBJECT struct");
+                    return NULL;
+                }
+                obj->type  = AUTH_KEY_OID;
+                obj->grp   = oidCertExtType;
+                obj->obj   = x509->authKeyId;
+                obj->objSz = x509->authKeyIdSz;
+                obj->dynamic |= WOLFSSL_ASN1_DYNAMIC;
+                obj->dynamic &= ~WOLFSSL_ASN1_DYNAMIC_DATA;
+            }
+            else {
+                WOLFSSL_MSG("No Auth Key set");
+            }
+            break;
+
+        case SUBJ_KEY_OID:
+            if (x509->subjKeyIdSet) {
+                if (c != NULL) {
+                    *c = x509->subjKeyIdCrit;
+                }
+                obj = wolfSSL_ASN1_OBJECT_new();
+                if (obj == NULL) {
+                    WOLFSSL_MSG("Issue creating WOLFSSL_ASN1_OBJECT struct");
+                    return NULL;
+                }
+                obj->type  = SUBJ_KEY_OID;
+                obj->grp   = oidCertExtType;
+                obj->obj   = x509->subjKeyId;
+                obj->objSz = x509->subjKeyIdSz;
+                obj->dynamic |= WOLFSSL_ASN1_DYNAMIC;
+                obj->dynamic &= ~WOLFSSL_ASN1_DYNAMIC_DATA;
+            }
+            else {
+                WOLFSSL_MSG("No Subject Key set");
+            }
+            break;
+
+        case CERT_POLICY_OID:
+        {
+        #ifdef WOLFSSL_CERT_EXT
+            int i;
+
+            if (x509->certPoliciesNb > 0) {
+                if (c != NULL) {
+                    if (x509->certPoliciesNb > 1) {
+                        *c = -2;
+                    }
+                    else {
+                        *c = 0;
+                    }
+                }
+
+                sk = wolfSSL_sk_new_asn1_obj();
+                if (sk == NULL) {
+                    return NULL;
+                }
+
+                for (i = 0; i < x509->certPoliciesNb - 1; i++) {
+                    obj = wolfSSL_ASN1_OBJECT_new();
+                    if (obj == NULL) {
+                        WOLFSSL_MSG("Issue creating WOLFSSL_ASN1_OBJECT struct");
+                        wolfSSL_sk_ASN1_OBJECT_free(sk);
+                        return NULL;
+                    }
+                    obj->type  = CERT_POLICY_OID;
+                    obj->grp   = oidCertExtType;
+                    obj->obj   = (byte*)(x509->certPolicies[i]);
+                    obj->objSz = MAX_CERTPOL_SZ;
+                    obj->dynamic |= WOLFSSL_ASN1_DYNAMIC;
+                    obj->dynamic &= ~WOLFSSL_ASN1_DYNAMIC_DATA;
+                    if (wolfSSL_sk_ASN1_OBJECT_push(sk, obj)
+                                                           != WOLFSSL_SUCCESS) {
+                        WOLFSSL_MSG("Error pushing ASN1 object onto stack");
+                        wolfSSL_ASN1_OBJECT_free(obj);
+                        wolfSSL_sk_ASN1_OBJECT_free(sk);
+                        sk = NULL;
+                    }
+                }
+                obj = wolfSSL_ASN1_OBJECT_new();
+                if (obj == NULL) {
+                    WOLFSSL_MSG("Issue creating WOLFSSL_ASN1_OBJECT struct");
+                    wolfSSL_sk_ASN1_OBJECT_free(sk);
+                    return NULL;
+                }
+                obj->type  = CERT_POLICY_OID;
+                obj->grp   = oidCertExtType;
+                obj->obj   = (byte*)(x509->certPolicies[i]);
+                obj->objSz = MAX_CERTPOL_SZ;
+                obj->dynamic |= WOLFSSL_ASN1_DYNAMIC;
+                obj->dynamic &= ~WOLFSSL_ASN1_DYNAMIC_DATA;
+            }
+            else {
+                WOLFSSL_MSG("No Cert Policy set");
+            }
+        #elif defined(WOLFSSL_SEP)
+            if (x509->certPolicySet) {
+                if (c != NULL) {
+                    *c = x509->certPolicyCrit;
+                }
+                obj = wolfSSL_ASN1_OBJECT_new();
+                if (obj == NULL) {
+                    WOLFSSL_MSG("Issue creating WOLFSSL_ASN1_OBJECT struct");
+                    return NULL;
+                }
+                obj->type  = CERT_POLICY_OID;
+                obj->grp   = oidCertExtType;
+                obj->dynamic |= WOLFSSL_ASN1_DYNAMIC;
+            }
+            else {
+                WOLFSSL_MSG("No Cert Policy set");
+            }
+        #else
+            WOLFSSL_MSG("wolfSSL not built with WOLFSSL_SEP or WOLFSSL_CERT_EXT");
+        #endif
+            break;
+        }
+        case KEY_USAGE_OID:
+        {
+            WOLFSSL_ASN1_BIT_STRING* bit_str = NULL;
+            if (x509->keyUsageSet) {
+                if (c != NULL) {
+                    *c = x509->keyUsageCrit;
+                }
+
+                bit_str = wolfSSL_ASN1_BIT_STRING_new();
+                if (bit_str == NULL) {
+                    WOLFSSL_MSG("Issue creating WOLFSSL_ASN1_BIT_STRING struct");
+                    return NULL;
+                }
+
+                bit_str->type = KEY_USAGE_OID;
+                bit_str->flags = 0;
+                bit_str->length = sizeof(word16);
+                bit_str->data = (byte*)XMALLOC(bit_str->length, NULL, DYNAMIC_TYPE_OPENSSL);
+                if (bit_str->data == NULL) {
+                    wolfSSL_ASN1_BIT_STRING_free(bit_str);
+                    return NULL;
+                }
+                XMEMCPY(bit_str->data, &x509->keyUsage, bit_str->length);
+            }
+            else {
+                WOLFSSL_MSG("No Key Usage set");
+            }
+            /* don't add stack of and return bit string directly */
+            return bit_str;
+        }
+        case INHIBIT_ANY_OID:
+            WOLFSSL_MSG("INHIBIT ANY extension not supported");
+            break;
+
+        case EXT_KEY_USAGE_OID:
+            if (x509->extKeyUsageSrc != NULL) {
+                if (c != NULL) {
+                    if (x509->extKeyUsageCount > 1) {
+                        *c = -2;
+                    }
+                    else {
+                        *c = x509->extKeyUsageCrit;
+                    }
+                }
+                obj = wolfSSL_ASN1_OBJECT_new();
+                if (obj == NULL) {
+                    WOLFSSL_MSG("Issue creating WOLFSSL_ASN1_OBJECT struct");
+                    return NULL;
+                }
+                obj->type  = EXT_KEY_USAGE_OID;
+                obj->grp   = oidCertExtType;
+                obj->obj   = x509->extKeyUsageSrc;
+                obj->objSz = x509->extKeyUsageSz;
+                obj->dynamic |= WOLFSSL_ASN1_DYNAMIC;
+                obj->dynamic &= ~WOLFSSL_ASN1_DYNAMIC_DATA;
+            }
+            else {
+                WOLFSSL_MSG("No Extended Key Usage set");
+            }
+            break;
+
+        case NAME_CONS_OID:
+            WOLFSSL_MSG("Name Constraint OID extension not supported");
+            break;
+
+        case PRIV_KEY_USAGE_PERIOD_OID:
+            WOLFSSL_MSG("Private Key Usage Period extension not supported");
+            break;
+
+        case SUBJECT_INFO_ACCESS:
+            WOLFSSL_MSG("Subject Info Access extension not supported");
+            break;
+
+        case POLICY_MAP_OID:
+            WOLFSSL_MSG("Policy Map extension not supported");
+            break;
+
+        case POLICY_CONST_OID:
+            WOLFSSL_MSG("Policy Constraint extension not supported");
+            break;
+
+        case ISSUE_ALT_NAMES_OID:
+            WOLFSSL_MSG("Issue Alt Names extension not supported");
+            break;
+
+        case TLS_FEATURE_OID:
+            WOLFSSL_MSG("TLS Feature extension not supported");
+            break;
+
+        default:
+            WOLFSSL_MSG("Unsupported/Unknown extension OID");
+    }
+
+    /* make sure stack of is allocated */
+    if ((obj || gn) && sk == NULL) {
+        sk = wolfSSL_sk_new_asn1_obj();
+        if (sk == NULL) {
+            goto err;
+        }
+    }
+    if (obj && wolfSSL_sk_ASN1_OBJECT_push(sk, obj) == WOLFSSL_SUCCESS) {
+        /* obj pushed successfully on stack */
+    }
+    else if (gn && wolfSSL_sk_GENERAL_NAME_push(sk, gn) == WOLFSSL_SUCCESS) {
+        /* gn pushed successfully on stack */
+    }
+    else {
+        /* Nothing to push or push failed */
+        WOLFSSL_MSG("Error pushing ASN1_OBJECT or GENERAL_NAME object onto stack "
+                    "or nothing to push.");
+        goto err;
+    }
+    ret = sk;
+
+    (void)idx;
+
+    return ret;
+
+err:
+    if (obj) {
+        wolfSSL_ASN1_OBJECT_free(obj);
+    }
+    if (gn) {
+        wolfSSL_GENERAL_NAME_free(gn);
+    }
+    if (sk) {
+        wolfSSL_sk_ASN1_OBJECT_free(sk);
+    }
+    return NULL;
+}
+
+
+int wolfSSL_X509_add_altname(WOLFSSL_X509* x509, const char* name, int type)
+{
+    DNS_entry* newAltName = NULL;
+    char* nameCopy = NULL;
+    word32 nameSz;
+
+    if (x509 == NULL)
+        return WOLFSSL_FAILURE;
+
+    if (name == NULL)
+        return WOLFSSL_SUCCESS;
+
+    nameSz = (word32)XSTRLEN(name);
+    if (nameSz == 0)
+        return WOLFSSL_SUCCESS;
+
+    newAltName = (DNS_entry*)XMALLOC(sizeof(DNS_entry),
+            x509->heap, DYNAMIC_TYPE_ALTNAME);
+    if (newAltName == NULL)
+        return WOLFSSL_FAILURE;
+
+    nameCopy = (char*)XMALLOC(nameSz + 1, x509->heap, DYNAMIC_TYPE_ALTNAME);
+    if (nameCopy == NULL) {
+        XFREE(newAltName, x509->heap, DYNAMIC_TYPE_ALTNAME);
+        return WOLFSSL_FAILURE;
+    }
+
+    XMEMCPY(nameCopy, name, nameSz + 1);
+
+    newAltName->next = x509->altNames;
+    newAltName->type = type;
+    newAltName->len = nameSz;
+    newAltName->name = nameCopy;
+    x509->altNames = newAltName;
+
+    return WOLFSSL_SUCCESS;
+}
+
+
+#ifndef NO_WOLFSSL_STUB
+int wolfSSL_X509_add_ext(WOLFSSL_X509 *x509, WOLFSSL_X509_EXTENSION *ext, int loc)
+{
+    WOLFSSL_STUB("wolfSSL_X509_add_ext");
+    (void)x509;
+    (void)ext;
+    (void)loc;
+    return WOLFSSL_FAILURE;
+}
+
+/* currently LHASH is not implemented (and not needed for Apache port) */
+WOLFSSL_X509_EXTENSION* wolfSSL_X509V3_EXT_conf_nid(
+        WOLF_LHASH_OF(CONF_VALUE)* conf, WOLFSSL_X509V3_CTX* ctx, int nid,
+        char* value)
+{
+    WOLFSSL_STUB("wolfSSL_X509V3_EXT_conf_nid");
+
+    if (conf != NULL) {
+        WOLFSSL_MSG("Handling LHASH not implemented yet");
+        return NULL;
+    }
+
+    (void)conf;
+    (void)ctx;
+    (void)nid;
+    (void)value;
+    return NULL;
+}
+
+void wolfSSL_X509V3_set_ctx_nodb(WOLFSSL_X509V3_CTX* ctx)
+{
+    WOLFSSL_STUB("wolfSSL_X509V3_set_ctx_nodb");
+    (void)ctx;
+}
+#endif /* !NO_WOLFSSL_STUB */
+
+/* Returns pointer to ASN1_OBJECT from an X509_EXTENSION object */
+WOLFSSL_ASN1_OBJECT* wolfSSL_X509_EXTENSION_get_object \
+    (WOLFSSL_X509_EXTENSION* ext)
+{
+    WOLFSSL_ENTER("wolfSSL_X509_EXTENSION_get_object");
+    if(ext == NULL)
+        return NULL;
+    return ext->obj;
+}
+
+/* Returns pointer to ASN1_STRING in X509_EXTENSION object */
+WOLFSSL_ASN1_STRING* wolfSSL_X509_EXTENSION_get_data(WOLFSSL_X509_EXTENSION* ext)
+{
+    WOLFSSL_ENTER("wolfSSL_X509_EXTENSION_get_data");
+    if (ext == NULL)
+        return NULL;
+    return &ext->value;
+}
+
+#if !defined(NO_PWDBASED)
+int wolfSSL_X509_digest(const WOLFSSL_X509* x509, const WOLFSSL_EVP_MD* digest,
+        unsigned char* buf, unsigned int* len)
+{
+    int ret;
+
+    WOLFSSL_ENTER("wolfSSL_X509_digest");
+
+    if (x509 == NULL || digest == NULL) {
+        WOLFSSL_MSG("Null argument found");
+        return WOLFSSL_FAILURE;
+    }
+
+    if (x509->derCert == NULL) {
+        WOLFSSL_MSG("No DER certificate stored in X509");
+        return WOLFSSL_FAILURE;
+    }
+
+    ret = wolfSSL_EVP_Digest(x509->derCert->buffer, x509->derCert->length, buf,
+                              len, digest, NULL);
+    WOLFSSL_LEAVE("wolfSSL_X509_digest", ret);
+    return ret;
+}
+#endif
+
+int wolfSSL_use_PrivateKey(WOLFSSL* ssl, WOLFSSL_EVP_PKEY* pkey)
+{
+    WOLFSSL_ENTER("wolfSSL_use_PrivateKey");
+    if (ssl == NULL || pkey == NULL ) {
+        return WOLFSSL_FAILURE;
+    }
+
+    return wolfSSL_use_PrivateKey_buffer(ssl, (unsigned char*)pkey->pkey.ptr,
+                                         pkey->pkey_sz, WOLFSSL_FILETYPE_ASN1);
+}
+
+
+int wolfSSL_use_PrivateKey_ASN1(int pri, WOLFSSL* ssl, const unsigned char* der,
+                                long derSz)
+{
+    WOLFSSL_ENTER("wolfSSL_use_PrivateKey_ASN1");
+    if (ssl == NULL || der == NULL ) {
+        return WOLFSSL_FAILURE;
+    }
+
+    (void)pri; /* type of private key */
+    return wolfSSL_use_PrivateKey_buffer(ssl, der, derSz, WOLFSSL_FILETYPE_ASN1);
+}
+/******************************************************************************
+* wolfSSL_CTX_use_PrivateKey_ASN1 - loads a private key buffer into the SSL ctx
+*
+* RETURNS:
+* returns WOLFSSL_SUCCESS on success, otherwise returns WOLFSSL_FAILURE
+*/
+
+int wolfSSL_CTX_use_PrivateKey_ASN1(int pri, WOLFSSL_CTX* ctx,
+                                            unsigned char* der, long derSz)
+{
+    WOLFSSL_ENTER("wolfSSL_CTX_use_PrivateKey_ASN1");
+    if (ctx == NULL || der == NULL ) {
+        return WOLFSSL_FAILURE;
+    }
+
+    (void)pri; /* type of private key */
+    return wolfSSL_CTX_use_PrivateKey_buffer(ctx, der, derSz, WOLFSSL_FILETYPE_ASN1);
+}
+
+
+#ifndef NO_RSA
+int wolfSSL_use_RSAPrivateKey_ASN1(WOLFSSL* ssl, unsigned char* der, long derSz)
+{
+    WOLFSSL_ENTER("wolfSSL_use_RSAPrivateKey_ASN1");
+    if (ssl == NULL || der == NULL ) {
+        return WOLFSSL_FAILURE;
+    }
+
+    return wolfSSL_use_PrivateKey_buffer(ssl, der, derSz, WOLFSSL_FILETYPE_ASN1);
+}
+#endif
+
+int wolfSSL_use_certificate(WOLFSSL* ssl, WOLFSSL_X509* x509)
+{
+    long idx;
+
+    WOLFSSL_ENTER("wolfSSL_use_certificate");
+    if (x509 != NULL && ssl != NULL && x509->derCert != NULL) {
+        if (ProcessBuffer(NULL, x509->derCert->buffer, x509->derCert->length,
+                          WOLFSSL_FILETYPE_ASN1, CERT_TYPE, ssl, &idx, 0,
+                          GET_VERIFY_SETTING_SSL(ssl)) == WOLFSSL_SUCCESS) {
+            return WOLFSSL_SUCCESS;
+        }
+    }
+
+    (void)idx;
+    return WOLFSSL_FAILURE;
+}
+
+#endif /* NO_CERTS */
+
+#endif /* OPENSSL_EXTRA */
+
+#ifndef NO_CERTS
+int wolfSSL_use_certificate_ASN1(WOLFSSL* ssl, const unsigned char* der,
+                                 int derSz)
+{
+    long idx;
+
+    WOLFSSL_ENTER("wolfSSL_use_certificate_ASN1");
+    if (der != NULL && ssl != NULL) {
+        if (ProcessBuffer(NULL, der, derSz, WOLFSSL_FILETYPE_ASN1, CERT_TYPE,
+                ssl, &idx, 0, GET_VERIFY_SETTING_SSL(ssl)) == WOLFSSL_SUCCESS) {
+            return WOLFSSL_SUCCESS;
+        }
+    }
+
+    (void)idx;
+    return WOLFSSL_FAILURE;
+}
+
+#ifndef NO_FILESYSTEM
+
+WOLFSSL_ABI
+int wolfSSL_use_certificate_file(WOLFSSL* ssl, const char* file, int format)
+{
+    WOLFSSL_ENTER("wolfSSL_use_certificate_file");
+
+    if (ssl == NULL) {
+        return BAD_FUNC_ARG;
+    }
+
+    if (ProcessFile(ssl->ctx, file, format, CERT_TYPE,
+                ssl, 0, NULL, GET_VERIFY_SETTING_SSL(ssl)) == WOLFSSL_SUCCESS) {
+        return WOLFSSL_SUCCESS;
+    }
+
+    return WOLFSSL_FAILURE;
+}
+
+
+WOLFSSL_ABI
+int wolfSSL_use_PrivateKey_file(WOLFSSL* ssl, const char* file, int format)
+{
+    WOLFSSL_ENTER("wolfSSL_use_PrivateKey_file");
+
+    if (ssl == NULL) {
+        return BAD_FUNC_ARG;
+    }
+
+    if (ProcessFile(ssl->ctx, file, format, PRIVATEKEY_TYPE,
+                ssl, 0, NULL, GET_VERIFY_SETTING_SSL(ssl)) == WOLFSSL_SUCCESS) {
+        return WOLFSSL_SUCCESS;
+    }
+
+    return WOLFSSL_FAILURE;
+}
+
+
+WOLFSSL_ABI
+int wolfSSL_use_certificate_chain_file(WOLFSSL* ssl, const char* file)
+{
+    /* process up to MAX_CHAIN_DEPTH plus subject cert */
+    WOLFSSL_ENTER("wolfSSL_use_certificate_chain_file");
+
+    if (ssl == NULL) {
+        return BAD_FUNC_ARG;
+    }
+
+    if (ProcessFile(ssl->ctx, file, WOLFSSL_FILETYPE_PEM, CERT_TYPE,
+               ssl, 1, NULL, GET_VERIFY_SETTING_SSL(ssl)) == WOLFSSL_SUCCESS) {
+        return WOLFSSL_SUCCESS;
+    }
+
+   return WOLFSSL_FAILURE;
+}
+
+int wolfSSL_use_certificate_chain_file_format(WOLFSSL* ssl, const char* file,
+                                              int format)
+{
+    /* process up to MAX_CHAIN_DEPTH plus subject cert */
+    WOLFSSL_ENTER("wolfSSL_use_certificate_chain_file_format");
+
+    if (ssl == NULL) {
+        return BAD_FUNC_ARG;
+    }
+
+    if (ProcessFile(ssl->ctx, file, format, CERT_TYPE, ssl, 1,
+                    NULL, GET_VERIFY_SETTING_SSL(ssl)) == WOLFSSL_SUCCESS) {
+        return WOLFSSL_SUCCESS;
+    }
+    return WOLFSSL_FAILURE;
+}
+
+#endif /* !NO_FILESYSTEM */
+#endif /* !NO_CERTS */
+
+#ifdef HAVE_ECC
+
+/* Set Temp CTX EC-DHE size in octets, should be 20 - 66 for 160 - 521 bit */
+int wolfSSL_CTX_SetTmpEC_DHE_Sz(WOLFSSL_CTX* ctx, word16 sz)
+{
+    if (ctx == NULL)
+        return BAD_FUNC_ARG;
+
+    if (sz == 0) {
+        /* applies only to ECDSA */
+        if (ctx->privateKeyType != ecc_dsa_sa_algo)
+            return WOLFSSL_SUCCESS;
+
+        if (ctx->privateKeySz == 0) {
+            WOLFSSL_MSG("Must set private key/cert first");
+            return BAD_FUNC_ARG;
+        }
+
+        sz = (word16)ctx->privateKeySz;
+    }
+
+    /* check size */
+    if (sz < ECC_MINSIZE || sz > ECC_MAXSIZE)
+        return BAD_FUNC_ARG;
+
+    ctx->eccTempKeySz = sz;
+
+    return WOLFSSL_SUCCESS;
+}
+
+
+/* Set Temp SSL EC-DHE size in octets, should be 20 - 66 for 160 - 521 bit */
+int wolfSSL_SetTmpEC_DHE_Sz(WOLFSSL* ssl, word16 sz)
+{
+    if (ssl == NULL || sz < ECC_MINSIZE || sz > ECC_MAXSIZE)
+        return BAD_FUNC_ARG;
+
+    ssl->eccTempKeySz = sz;
+
+    return WOLFSSL_SUCCESS;
+}
+
+#endif /* HAVE_ECC */
+
+
+#ifdef OPENSSL_EXTRA
+
+#ifndef NO_FILESYSTEM
+int wolfSSL_CTX_use_RSAPrivateKey_file(WOLFSSL_CTX* ctx,const char* file,
+                                   int format)
+{
+    WOLFSSL_ENTER("SSL_CTX_use_RSAPrivateKey_file");
+
+    return wolfSSL_CTX_use_PrivateKey_file(ctx, file, format);
+}
+
+
+int wolfSSL_use_RSAPrivateKey_file(WOLFSSL* ssl, const char* file, int format)
+{
+    WOLFSSL_ENTER("wolfSSL_use_RSAPrivateKey_file");
+
+    return wolfSSL_use_PrivateKey_file(ssl, file, format);
+}
+#endif /* NO_FILESYSTEM */
+
+
+/* Copies the master secret over to out buffer. If outSz is 0 returns the size
+ * of master secret.
+ *
+ * ses : a session from completed TLS/SSL handshake
+ * out : buffer to hold copy of master secret
+ * outSz : size of out buffer
+ * returns : number of bytes copied into out buffer on success
+ *           less then or equal to 0 is considered a failure case
+ */
+int wolfSSL_SESSION_get_master_key(const WOLFSSL_SESSION* ses,
+        unsigned char* out, int outSz)
+{
+    int size;
+
+    if (outSz == 0) {
+        return SECRET_LEN;
+    }
+
+    if (ses == NULL || out == NULL || outSz < 0) {
+        return 0;
+    }
+
+    if (outSz > SECRET_LEN) {
+        size = SECRET_LEN;
+    }
+    else {
+        size = outSz;
+    }
+
+    XMEMCPY(out, ses->masterSecret, size);
+    return size;
+}
+
+
+int wolfSSL_SESSION_get_master_key_length(const WOLFSSL_SESSION* ses)
+{
+    (void)ses;
+    return SECRET_LEN;
+}
+
+#endif /* OPENSSL_EXTRA */
+
+#ifndef NO_FILESYSTEM
+#ifdef HAVE_NTRU
+
+int wolfSSL_CTX_use_NTRUPrivateKey_file(WOLFSSL_CTX* ctx, const char* file)
+{
+    WOLFSSL_ENTER("wolfSSL_CTX_use_NTRUPrivateKey_file");
+
+    if (ctx == NULL)
+        return WOLFSSL_FAILURE;
+
+    if (ProcessFile(ctx, file, WOLFSSL_FILETYPE_RAW, PRIVATEKEY_TYPE, NULL, 0,
+                    NULL, GET_VERIFY_SETTING_CTX(ctx)) == WOLFSSL_SUCCESS) {
+        ctx->haveNTRU = 1;
+        return WOLFSSL_SUCCESS;
+    }
+
+    return WOLFSSL_FAILURE;
+}
+
+#endif /* HAVE_NTRU */
+
+
+#endif /* NO_FILESYSTEM */
+
+
+void wolfSSL_CTX_set_verify(WOLFSSL_CTX* ctx, int mode, VerifyCallback vc)
+{
+    WOLFSSL_ENTER("wolfSSL_CTX_set_verify");
+    if (ctx == NULL)
+        return;
+
+    if (mode & WOLFSSL_VERIFY_PEER) {
+        ctx->verifyPeer = 1;
+        ctx->verifyNone = 0;  /* in case previously set */
+    }
+
+    if (mode == WOLFSSL_VERIFY_NONE) {
+        ctx->verifyNone = 1;
+        ctx->verifyPeer = 0;  /* in case previously set */
+    }
+
+    if (mode & WOLFSSL_VERIFY_FAIL_IF_NO_PEER_CERT) {
+        ctx->failNoCert = 1;
+    }
+
+    if (mode & WOLFSSL_VERIFY_FAIL_EXCEPT_PSK) {
+        ctx->failNoCert    = 0; /* fail on all is set to fail on PSK */
+        ctx->failNoCertxPSK = 1;
+    }
+
+    ctx->verifyCallback = vc;
+}
+
+#ifdef OPENSSL_ALL
+void wolfSSL_CTX_set_cert_verify_callback(WOLFSSL_CTX* ctx,
+    CertVerifyCallback cb, void* arg)
+{
+    WOLFSSL_ENTER("SSL_CTX_set_cert_verify_callback");
+    if (ctx == NULL)
+        return;
+
+    ctx->verifyCertCb = cb;
+    ctx->verifyCertCbArg = arg;
+}
+#endif
+
+
+void wolfSSL_set_verify(WOLFSSL* ssl, int mode, VerifyCallback vc)
+{
+    WOLFSSL_ENTER("wolfSSL_set_verify");
+    if (ssl == NULL)
+        return;
+
+    if (mode & WOLFSSL_VERIFY_PEER) {
+        ssl->options.verifyPeer = 1;
+        ssl->options.verifyNone = 0;  /* in case previously set */
+    }
+
+    if (mode == WOLFSSL_VERIFY_NONE) {
+        ssl->options.verifyNone = 1;
+        ssl->options.verifyPeer = 0;  /* in case previously set */
+    }
+
+    if (mode & WOLFSSL_VERIFY_FAIL_IF_NO_PEER_CERT)
+        ssl->options.failNoCert = 1;
+
+    if (mode & WOLFSSL_VERIFY_FAIL_EXCEPT_PSK) {
+        ssl->options.failNoCert    = 0; /* fail on all is set to fail on PSK */
+        ssl->options.failNoCertxPSK = 1;
+    }
+
+    ssl->verifyCallback = vc;
+}
+
+void wolfSSL_set_verify_result(WOLFSSL *ssl, long v)
+{
+    WOLFSSL_ENTER("wolfSSL_set_verify_result");
+
+    if (ssl == NULL)
+        return;
+
+#ifdef OPENSSL_ALL
+    ssl->verifyCallbackResult = v;
+#else
+    (void)v;
+    WOLFSSL_STUB("wolfSSL_set_verify_result");
+#endif
+}
+
+/* store user ctx for verify callback */
+void wolfSSL_SetCertCbCtx(WOLFSSL* ssl, void* ctx)
+{
+    WOLFSSL_ENTER("wolfSSL_SetCertCbCtx");
+    if (ssl)
+        ssl->verifyCbCtx = ctx;
+}
+
+
+/* store context CA Cache addition callback */
+void wolfSSL_CTX_SetCACb(WOLFSSL_CTX* ctx, CallbackCACache cb)
+{
+    if (ctx && ctx->cm)
+        ctx->cm->caCacheCallback = cb;
+}
+
+
+#if defined(PERSIST_CERT_CACHE)
+
+#if !defined(NO_FILESYSTEM)
+
+/* Persist cert cache to file */
+int wolfSSL_CTX_save_cert_cache(WOLFSSL_CTX* ctx, const char* fname)
+{
+    WOLFSSL_ENTER("wolfSSL_CTX_save_cert_cache");
+
+    if (ctx == NULL || fname == NULL)
+        return BAD_FUNC_ARG;
+
+    return CM_SaveCertCache(ctx->cm, fname);
+}
+
+
+/* Persist cert cache from file */
+int wolfSSL_CTX_restore_cert_cache(WOLFSSL_CTX* ctx, const char* fname)
+{
+    WOLFSSL_ENTER("wolfSSL_CTX_restore_cert_cache");
+
+    if (ctx == NULL || fname == NULL)
+        return BAD_FUNC_ARG;
+
+    return CM_RestoreCertCache(ctx->cm, fname);
+}
+
+#endif /* NO_FILESYSTEM */
+
+/* Persist cert cache to memory */
+int wolfSSL_CTX_memsave_cert_cache(WOLFSSL_CTX* ctx, void* mem,
+                                   int sz, int* used)
+{
+    WOLFSSL_ENTER("wolfSSL_CTX_memsave_cert_cache");
+
+    if (ctx == NULL || mem == NULL || used == NULL || sz <= 0)
+        return BAD_FUNC_ARG;
+
+    return CM_MemSaveCertCache(ctx->cm, mem, sz, used);
+}
+
+
+/* Restore cert cache from memory */
+int wolfSSL_CTX_memrestore_cert_cache(WOLFSSL_CTX* ctx, const void* mem, int sz)
+{
+    WOLFSSL_ENTER("wolfSSL_CTX_memrestore_cert_cache");
+
+    if (ctx == NULL || mem == NULL || sz <= 0)
+        return BAD_FUNC_ARG;
+
+    return CM_MemRestoreCertCache(ctx->cm, mem, sz);
+}
+
+
+/* get how big the the cert cache save buffer needs to be */
+int wolfSSL_CTX_get_cert_cache_memsize(WOLFSSL_CTX* ctx)
+{
+    WOLFSSL_ENTER("wolfSSL_CTX_get_cert_cache_memsize");
+
+    if (ctx == NULL)
+        return BAD_FUNC_ARG;
+
+    return CM_GetCertCacheMemSize(ctx->cm);
+}
+
+#endif /* PERSIST_CERT_CACHE */
+#endif /* !NO_CERTS */
+
+
+#ifndef NO_SESSION_CACHE
+
+WOLFSSL_ABI
+WOLFSSL_SESSION* wolfSSL_get_session(WOLFSSL* ssl)
+{
+    WOLFSSL_ENTER("SSL_get_session");
+    if (ssl)
+        return GetSession(ssl, 0, 1);
+
+    return NULL;
+}
+
+
+WOLFSSL_ABI
+int wolfSSL_set_session(WOLFSSL* ssl, WOLFSSL_SESSION* session)
+{
+    WOLFSSL_ENTER("SSL_set_session");
+    if (session)
+        return SetSession(ssl, session);
+
+    return WOLFSSL_FAILURE;
+}
+
+
+#ifndef NO_CLIENT_CACHE
+
+/* Associate client session with serverID, find existing or store for saving
+   if newSession flag on, don't reuse existing session
+   WOLFSSL_SUCCESS on ok */
+int wolfSSL_SetServerID(WOLFSSL* ssl, const byte* id, int len, int newSession)
+{
+    WOLFSSL_SESSION* session = NULL;
+
+    WOLFSSL_ENTER("wolfSSL_SetServerID");
+
+    if (ssl == NULL || id == NULL || len <= 0)
+        return BAD_FUNC_ARG;
+
+    if (newSession == 0) {
+        session = GetSessionClient(ssl, id, len);
+        if (session) {
+            if (SetSession(ssl, session) != WOLFSSL_SUCCESS) {
+    #ifdef HAVE_EXT_CACHE
+                wolfSSL_SESSION_free(session);
+    #endif
+                WOLFSSL_MSG("SetSession failed");
+                session = NULL;
+            }
+        }
+    }
+
+    if (session == NULL) {
+        WOLFSSL_MSG("Valid ServerID not cached already");
+
+        ssl->session.idLen = (word16)min(SERVER_ID_LEN, (word32)len);
+        XMEMCPY(ssl->session.serverID, id, ssl->session.idLen);
+    }
+    #ifdef HAVE_EXT_CACHE
+    else
+        wolfSSL_SESSION_free(session);
+    #endif
+
+    return WOLFSSL_SUCCESS;
+}
+
+#endif /* NO_CLIENT_CACHE */
+
+#if defined(PERSIST_SESSION_CACHE)
+
+/* for persistence, if changes to layout need to increment and modify
+   save_session_cache() and restore_session_cache and memory versions too */
+#define WOLFSSL_CACHE_VERSION 2
+
+/* Session Cache Header information */
+typedef struct {
+    int version;     /* cache layout version id */
+    int rows;        /* session rows */
+    int columns;     /* session columns */
+    int sessionSz;   /* sizeof WOLFSSL_SESSION */
+} cache_header_t;
+
+/* current persistence layout is:
+
+   1) cache_header_t
+   2) SessionCache
+   3) ClientCache
+
+   update WOLFSSL_CACHE_VERSION if change layout for the following
+   PERSISTENT_SESSION_CACHE functions
+*/
+
+
+/* get how big the the session cache save buffer needs to be */
+int wolfSSL_get_session_cache_memsize(void)
+{
+    int sz  = (int)(sizeof(SessionCache) + sizeof(cache_header_t));
+
+    #ifndef NO_CLIENT_CACHE
+        sz += (int)(sizeof(ClientCache));
+    #endif
+
+    return sz;
+}
+
+
+/* Persist session cache to memory */
+int wolfSSL_memsave_session_cache(void* mem, int sz)
+{
+    int i;
+    cache_header_t cache_header;
+    SessionRow*    row  = (SessionRow*)((byte*)mem + sizeof(cache_header));
+#ifndef NO_CLIENT_CACHE
+    ClientRow*     clRow;
+#endif
+
+    WOLFSSL_ENTER("wolfSSL_memsave_session_cache");
+
+    if (sz < wolfSSL_get_session_cache_memsize()) {
+        WOLFSSL_MSG("Memory buffer too small");
+        return BUFFER_E;
+    }
+
+    cache_header.version   = WOLFSSL_CACHE_VERSION;
+    cache_header.rows      = SESSION_ROWS;
+    cache_header.columns   = SESSIONS_PER_ROW;
+    cache_header.sessionSz = (int)sizeof(WOLFSSL_SESSION);
+    XMEMCPY(mem, &cache_header, sizeof(cache_header));
+
+    if (wc_LockMutex(&session_mutex) != 0) {
+        WOLFSSL_MSG("Session cache mutex lock failed");
+        return BAD_MUTEX_E;
+    }
+
+    for (i = 0; i < cache_header.rows; ++i)
+        XMEMCPY(row++, SessionCache + i, sizeof(SessionRow));
+
+#ifndef NO_CLIENT_CACHE
+    clRow = (ClientRow*)row;
+    for (i = 0; i < cache_header.rows; ++i)
+        XMEMCPY(clRow++, ClientCache + i, sizeof(ClientRow));
+#endif
+
+    wc_UnLockMutex(&session_mutex);
+
+    WOLFSSL_LEAVE("wolfSSL_memsave_session_cache", WOLFSSL_SUCCESS);
+
+    return WOLFSSL_SUCCESS;
+}
+
+
+/* Restore the persistent session cache from memory */
+int wolfSSL_memrestore_session_cache(const void* mem, int sz)
+{
+    int    i;
+    cache_header_t cache_header;
+    SessionRow*    row  = (SessionRow*)((byte*)mem + sizeof(cache_header));
+#ifndef NO_CLIENT_CACHE
+    ClientRow*     clRow;
+#endif
+
+    WOLFSSL_ENTER("wolfSSL_memrestore_session_cache");
+
+    if (sz < wolfSSL_get_session_cache_memsize()) {
+        WOLFSSL_MSG("Memory buffer too small");
+        return BUFFER_E;
+    }
+
+    XMEMCPY(&cache_header, mem, sizeof(cache_header));
+    if (cache_header.version   != WOLFSSL_CACHE_VERSION ||
+        cache_header.rows      != SESSION_ROWS ||
+        cache_header.columns   != SESSIONS_PER_ROW ||
+        cache_header.sessionSz != (int)sizeof(WOLFSSL_SESSION)) {
+
+        WOLFSSL_MSG("Session cache header match failed");
+        return CACHE_MATCH_ERROR;
+    }
+
+    if (wc_LockMutex(&session_mutex) != 0) {
+        WOLFSSL_MSG("Session cache mutex lock failed");
+        return BAD_MUTEX_E;
+    }
+
+    for (i = 0; i < cache_header.rows; ++i)
+        XMEMCPY(SessionCache + i, row++, sizeof(SessionRow));
+
+#ifndef NO_CLIENT_CACHE
+    clRow = (ClientRow*)row;
+    for (i = 0; i < cache_header.rows; ++i)
+        XMEMCPY(ClientCache + i, clRow++, sizeof(ClientRow));
+#endif
+
+    wc_UnLockMutex(&session_mutex);
+
+    WOLFSSL_LEAVE("wolfSSL_memrestore_session_cache", WOLFSSL_SUCCESS);
+
+    return WOLFSSL_SUCCESS;
+}
+
+#if !defined(NO_FILESYSTEM)
+
+/* Persist session cache to file */
+/* doesn't use memsave because of additional memory use */
+int wolfSSL_save_session_cache(const char *fname)
+{
+    XFILE  file;
+    int    ret;
+    int    rc = WOLFSSL_SUCCESS;
+    int    i;
+    cache_header_t cache_header;
+
+    WOLFSSL_ENTER("wolfSSL_save_session_cache");
+
+    file = XFOPEN(fname, "w+b");
+    if (file == XBADFILE) {
+        WOLFSSL_MSG("Couldn't open session cache save file");
+        return WOLFSSL_BAD_FILE;
+    }
+    cache_header.version   = WOLFSSL_CACHE_VERSION;
+    cache_header.rows      = SESSION_ROWS;
+    cache_header.columns   = SESSIONS_PER_ROW;
+    cache_header.sessionSz = (int)sizeof(WOLFSSL_SESSION);
+
+    /* cache header */
+    ret = (int)XFWRITE(&cache_header, sizeof cache_header, 1, file);
+    if (ret != 1) {
+        WOLFSSL_MSG("Session cache header file write failed");
+        XFCLOSE(file);
+        return FWRITE_ERROR;
+    }
+
+    if (wc_LockMutex(&session_mutex) != 0) {
+        WOLFSSL_MSG("Session cache mutex lock failed");
+        XFCLOSE(file);
+        return BAD_MUTEX_E;
+    }
+
+    /* session cache */
+    for (i = 0; i < cache_header.rows; ++i) {
+        ret = (int)XFWRITE(SessionCache + i, sizeof(SessionRow), 1, file);
+        if (ret != 1) {
+            WOLFSSL_MSG("Session cache member file write failed");
+            rc = FWRITE_ERROR;
+            break;
+        }
+    }
+
+#ifndef NO_CLIENT_CACHE
+    /* client cache */
+    for (i = 0; i < cache_header.rows; ++i) {
+        ret = (int)XFWRITE(ClientCache + i, sizeof(ClientRow), 1, file);
+        if (ret != 1) {
+            WOLFSSL_MSG("Client cache member file write failed");
+            rc = FWRITE_ERROR;
+            break;
+        }
+    }
+#endif /* NO_CLIENT_CACHE */
+
+    wc_UnLockMutex(&session_mutex);
+
+    XFCLOSE(file);
+    WOLFSSL_LEAVE("wolfSSL_save_session_cache", rc);
+
+    return rc;
+}
+
+
+/* Restore the persistent session cache from file */
+/* doesn't use memstore because of additional memory use */
+int wolfSSL_restore_session_cache(const char *fname)
+{
+    XFILE  file;
+    int    rc = WOLFSSL_SUCCESS;
+    int    ret;
+    int    i;
+    cache_header_t cache_header;
+
+    WOLFSSL_ENTER("wolfSSL_restore_session_cache");
+
+    file = XFOPEN(fname, "rb");
+    if (file == XBADFILE) {
+        WOLFSSL_MSG("Couldn't open session cache save file");
+        return WOLFSSL_BAD_FILE;
+    }
+    /* cache header */
+    ret = (int)XFREAD(&cache_header, sizeof cache_header, 1, file);
+    if (ret != 1) {
+        WOLFSSL_MSG("Session cache header file read failed");
+        XFCLOSE(file);
+        return FREAD_ERROR;
+    }
+    if (cache_header.version   != WOLFSSL_CACHE_VERSION ||
+        cache_header.rows      != SESSION_ROWS ||
+        cache_header.columns   != SESSIONS_PER_ROW ||
+        cache_header.sessionSz != (int)sizeof(WOLFSSL_SESSION)) {
+
+        WOLFSSL_MSG("Session cache header match failed");
+        XFCLOSE(file);
+        return CACHE_MATCH_ERROR;
+    }
+
+    if (wc_LockMutex(&session_mutex) != 0) {
+        WOLFSSL_MSG("Session cache mutex lock failed");
+        XFCLOSE(file);
+        return BAD_MUTEX_E;
+    }
+
+    /* session cache */
+    for (i = 0; i < cache_header.rows; ++i) {
+        ret = (int)XFREAD(SessionCache + i, sizeof(SessionRow), 1, file);
+        if (ret != 1) {
+            WOLFSSL_MSG("Session cache member file read failed");
+            XMEMSET(SessionCache, 0, sizeof SessionCache);
+            rc = FREAD_ERROR;
+            break;
+        }
+    }
+
+#ifndef NO_CLIENT_CACHE
+    /* client cache */
+    for (i = 0; i < cache_header.rows; ++i) {
+        ret = (int)XFREAD(ClientCache + i, sizeof(ClientRow), 1, file);
+        if (ret != 1) {
+            WOLFSSL_MSG("Client cache member file read failed");
+            XMEMSET(ClientCache, 0, sizeof ClientCache);
+            rc = FREAD_ERROR;
+            break;
+        }
+    }
+
+#endif /* NO_CLIENT_CACHE */
+
+    wc_UnLockMutex(&session_mutex);
+
+    XFCLOSE(file);
+    WOLFSSL_LEAVE("wolfSSL_restore_session_cache", rc);
+
+    return rc;
+}
+
+#endif /* !NO_FILESYSTEM */
+#endif /* PERSIST_SESSION_CACHE */
+#endif /* NO_SESSION_CACHE */
+
+
+void wolfSSL_load_error_strings(void)   /* compatibility only */
+{}
+
+
+int wolfSSL_library_init(void)
+{
+    WOLFSSL_ENTER("SSL_library_init");
+    if (wolfSSL_Init() == WOLFSSL_SUCCESS)
+        return WOLFSSL_SUCCESS;
+    else
+        return WOLFSSL_FATAL_ERROR;
+}
+
+
+#ifdef HAVE_SECRET_CALLBACK
+
+int wolfSSL_set_session_secret_cb(WOLFSSL* ssl, SessionSecretCb cb, void* ctx)
+{
+    WOLFSSL_ENTER("wolfSSL_set_session_secret_cb");
+    if (ssl == NULL)
+        return WOLFSSL_FATAL_ERROR;
+
+    ssl->sessionSecretCb = cb;
+    ssl->sessionSecretCtx = ctx;
+    /* If using a pre-set key, assume session resumption. */
+    ssl->session.sessionIDSz = 0;
+    ssl->options.resuming = 1;
+
+    return WOLFSSL_SUCCESS;
+}
+
+#endif
+
+
+#ifndef NO_SESSION_CACHE
+
+/* on by default if built in but allow user to turn off */
+WOLFSSL_ABI
+long wolfSSL_CTX_set_session_cache_mode(WOLFSSL_CTX* ctx, long mode)
+{
+    WOLFSSL_ENTER("SSL_CTX_set_session_cache_mode");
+    if (mode == WOLFSSL_SESS_CACHE_OFF)
+        ctx->sessionCacheOff = 1;
+
+    if ((mode & WOLFSSL_SESS_CACHE_NO_AUTO_CLEAR) != 0)
+        ctx->sessionCacheFlushOff = 1;
+
+#ifdef HAVE_EXT_CACHE
+    if ((mode & WOLFSSL_SESS_CACHE_NO_INTERNAL_STORE) != 0)
+        ctx->internalCacheOff = 1;
+#endif
+
+    return WOLFSSL_SUCCESS;
+}
+
+#endif /* NO_SESSION_CACHE */
+
+
+#if !defined(NO_CERTS)
+#if defined(PERSIST_CERT_CACHE)
+
+
+#define WOLFSSL_CACHE_CERT_VERSION 1
+
+typedef struct {
+    int version;                 /* cache cert layout version id */
+    int rows;                    /* hash table rows, CA_TABLE_SIZE */
+    int columns[CA_TABLE_SIZE];  /* columns per row on list */
+    int signerSz;                /* sizeof Signer object */
+} CertCacheHeader;
+
+/* current cert persistence layout is:
+
+   1) CertCacheHeader
+   2) caTable
+
+   update WOLFSSL_CERT_CACHE_VERSION if change layout for the following
+   PERSIST_CERT_CACHE functions
+*/
+
+
+/* Return memory needed to persist this signer, have lock */
+static WC_INLINE int GetSignerMemory(Signer* signer)
+{
+    int sz = sizeof(signer->pubKeySize) + sizeof(signer->keyOID)
+           + sizeof(signer->nameLen)    + sizeof(signer->subjectNameHash);
+
+#if !defined(NO_SKID)
+        sz += (int)sizeof(signer->subjectKeyIdHash);
+#endif
+
+    /* add dynamic bytes needed */
+    sz += signer->pubKeySize;
+    sz += signer->nameLen;
+
+    return sz;
+}
+
+
+/* Return memory needed to persist this row, have lock */
+static WC_INLINE int GetCertCacheRowMemory(Signer* row)
+{
+    int sz = 0;
+
+    while (row) {
+        sz += GetSignerMemory(row);
+        row = row->next;
+    }
+
+    return sz;
+}
+
+
+/* get the size of persist cert cache, have lock */
+static WC_INLINE int GetCertCacheMemSize(WOLFSSL_CERT_MANAGER* cm)
+{
+    int sz;
+    int i;
+
+    sz = sizeof(CertCacheHeader);
+
+    for (i = 0; i < CA_TABLE_SIZE; i++)
+        sz += GetCertCacheRowMemory(cm->caTable[i]);
+
+    return sz;
+}
+
+
+/* Store cert cache header columns with number of items per list, have lock */
+static WC_INLINE void SetCertHeaderColumns(WOLFSSL_CERT_MANAGER* cm, int* columns)
+{
+    int     i;
+    Signer* row;
+
+    for (i = 0; i < CA_TABLE_SIZE; i++) {
+        int count = 0;
+        row = cm->caTable[i];
+
+        while (row) {
+            ++count;
+            row = row->next;
+        }
+        columns[i] = count;
+    }
+}
+
+
+/* Restore whole cert row from memory, have lock, return bytes consumed,
+   < 0 on error, have lock */
+static WC_INLINE int RestoreCertRow(WOLFSSL_CERT_MANAGER* cm, byte* current,
+                                 int row, int listSz, const byte* end)
+{
+    int idx = 0;
+
+    if (listSz < 0) {
+        WOLFSSL_MSG("Row header corrupted, negative value");
+        return PARSE_ERROR;
+    }
+
+    while (listSz) {
+        Signer* signer;
+        byte*   publicKey;
+        byte*   start = current + idx;  /* for end checks on this signer */
+        int     minSz = sizeof(signer->pubKeySize) + sizeof(signer->keyOID) +
+                      sizeof(signer->nameLen) + sizeof(signer->subjectNameHash);
+        #ifndef NO_SKID
+                minSz += (int)sizeof(signer->subjectKeyIdHash);
+        #endif
+
+        if (start + minSz > end) {
+            WOLFSSL_MSG("Would overread restore buffer");
+            return BUFFER_E;
+        }
+        signer = MakeSigner(cm->heap);
+        if (signer == NULL)
+            return MEMORY_E;
+
+        /* pubKeySize */
+        XMEMCPY(&signer->pubKeySize, current + idx, sizeof(signer->pubKeySize));
+        idx += (int)sizeof(signer->pubKeySize);
+
+        /* keyOID */
+        XMEMCPY(&signer->keyOID, current + idx, sizeof(signer->keyOID));
+        idx += (int)sizeof(signer->keyOID);
+
+        /* pulicKey */
+        if (start + minSz + signer->pubKeySize > end) {
+            WOLFSSL_MSG("Would overread restore buffer");
+            FreeSigner(signer, cm->heap);
+            return BUFFER_E;
+        }
+        publicKey = (byte*)XMALLOC(signer->pubKeySize, cm->heap,
+                                   DYNAMIC_TYPE_KEY);
+        if (publicKey == NULL) {
+            FreeSigner(signer, cm->heap);
+            return MEMORY_E;
+        }
+
+        XMEMCPY(publicKey, current + idx, signer->pubKeySize);
+        signer->publicKey = publicKey;
+        idx += signer->pubKeySize;
+
+        /* nameLen */
+        XMEMCPY(&signer->nameLen, current + idx, sizeof(signer->nameLen));
+        idx += (int)sizeof(signer->nameLen);
+
+        /* name */
+        if (start + minSz + signer->pubKeySize + signer->nameLen > end) {
+            WOLFSSL_MSG("Would overread restore buffer");
+            FreeSigner(signer, cm->heap);
+            return BUFFER_E;
+        }
+        signer->name = (char*)XMALLOC(signer->nameLen, cm->heap,
+                                      DYNAMIC_TYPE_SUBJECT_CN);
+        if (signer->name == NULL) {
+            FreeSigner(signer, cm->heap);
+            return MEMORY_E;
+        }
+
+        XMEMCPY(signer->name, current + idx, signer->nameLen);
+        idx += signer->nameLen;
+
+        /* subjectNameHash */
+        XMEMCPY(signer->subjectNameHash, current + idx, SIGNER_DIGEST_SIZE);
+        idx += SIGNER_DIGEST_SIZE;
+
+        #ifndef NO_SKID
+            /* subjectKeyIdHash */
+            XMEMCPY(signer->subjectKeyIdHash, current + idx,SIGNER_DIGEST_SIZE);
+            idx += SIGNER_DIGEST_SIZE;
+        #endif
+
+        signer->next = cm->caTable[row];
+        cm->caTable[row] = signer;
+
+        --listSz;
+    }
+
+    return idx;
+}
+
+
+/* Store whole cert row into memory, have lock, return bytes added */
+static WC_INLINE int StoreCertRow(WOLFSSL_CERT_MANAGER* cm, byte* current, int row)
+{
+    int     added  = 0;
+    Signer* list   = cm->caTable[row];
+
+    while (list) {
+        XMEMCPY(current + added, &list->pubKeySize, sizeof(list->pubKeySize));
+        added += (int)sizeof(list->pubKeySize);
+
+        XMEMCPY(current + added, &list->keyOID,     sizeof(list->keyOID));
+        added += (int)sizeof(list->keyOID);
+
+        XMEMCPY(current + added, list->publicKey, list->pubKeySize);
+        added += list->pubKeySize;
+
+        XMEMCPY(current + added, &list->nameLen, sizeof(list->nameLen));
+        added += (int)sizeof(list->nameLen);
+
+        XMEMCPY(current + added, list->name, list->nameLen);
+        added += list->nameLen;
+
+        XMEMCPY(current + added, list->subjectNameHash, SIGNER_DIGEST_SIZE);
+        added += SIGNER_DIGEST_SIZE;
+
+        #ifndef NO_SKID
+            XMEMCPY(current + added, list->subjectKeyIdHash,SIGNER_DIGEST_SIZE);
+            added += SIGNER_DIGEST_SIZE;
+        #endif
+
+        list = list->next;
+    }
+
+    return added;
+}
+
+
+/* Persist cert cache to memory, have lock */
+static WC_INLINE int DoMemSaveCertCache(WOLFSSL_CERT_MANAGER* cm,
+                                     void* mem, int sz)
+{
+    int realSz;
+    int ret = WOLFSSL_SUCCESS;
+    int i;
+
+    WOLFSSL_ENTER("DoMemSaveCertCache");
+
+    realSz = GetCertCacheMemSize(cm);
+    if (realSz > sz) {
+        WOLFSSL_MSG("Mem output buffer too small");
+        ret = BUFFER_E;
+    }
+    else {
+        byte*           current;
+        CertCacheHeader hdr;
+
+        hdr.version  = WOLFSSL_CACHE_CERT_VERSION;
+        hdr.rows     = CA_TABLE_SIZE;
+        SetCertHeaderColumns(cm, hdr.columns);
+        hdr.signerSz = (int)sizeof(Signer);
+
+        XMEMCPY(mem, &hdr, sizeof(CertCacheHeader));
+        current = (byte*)mem + sizeof(CertCacheHeader);
+
+        for (i = 0; i < CA_TABLE_SIZE; ++i)
+            current += StoreCertRow(cm, current, i);
+    }
+
+    return ret;
+}
+
+
+#if !defined(NO_FILESYSTEM)
+
+/* Persist cert cache to file */
+int CM_SaveCertCache(WOLFSSL_CERT_MANAGER* cm, const char* fname)
+{
+    XFILE file;
+    int   rc = WOLFSSL_SUCCESS;
+    int   memSz;
+    byte* mem;
+
+    WOLFSSL_ENTER("CM_SaveCertCache");
+
+    file = XFOPEN(fname, "w+b");
+    if (file == XBADFILE) {
+       WOLFSSL_MSG("Couldn't open cert cache save file");
+       return WOLFSSL_BAD_FILE;
+    }
+
+    if (wc_LockMutex(&cm->caLock) != 0) {
+        WOLFSSL_MSG("wc_LockMutex on caLock failed");
+        XFCLOSE(file);
+        return BAD_MUTEX_E;
+    }
+
+    memSz = GetCertCacheMemSize(cm);
+    mem   = (byte*)XMALLOC(memSz, cm->heap, DYNAMIC_TYPE_TMP_BUFFER);
+    if (mem == NULL) {
+        WOLFSSL_MSG("Alloc for tmp buffer failed");
+        rc = MEMORY_E;
+    } else {
+        rc = DoMemSaveCertCache(cm, mem, memSz);
+        if (rc == WOLFSSL_SUCCESS) {
+            int ret = (int)XFWRITE(mem, memSz, 1, file);
+            if (ret != 1) {
+                WOLFSSL_MSG("Cert cache file write failed");
+                rc = FWRITE_ERROR;
+            }
+        }
+        XFREE(mem, cm->heap, DYNAMIC_TYPE_TMP_BUFFER);
+    }
+
+    wc_UnLockMutex(&cm->caLock);
+    XFCLOSE(file);
+
+    return rc;
+}
+
+
+/* Restore cert cache from file */
+int CM_RestoreCertCache(WOLFSSL_CERT_MANAGER* cm, const char* fname)
+{
+    XFILE file;
+    int   rc = WOLFSSL_SUCCESS;
+    int   ret;
+    int   memSz;
+    byte* mem;
+
+    WOLFSSL_ENTER("CM_RestoreCertCache");
+
+    file = XFOPEN(fname, "rb");
+    if (file == XBADFILE) {
+       WOLFSSL_MSG("Couldn't open cert cache save file");
+       return WOLFSSL_BAD_FILE;
+    }
+
+    if(XFSEEK(file, 0, XSEEK_END) != 0) {
+        XFCLOSE(file);
+        return WOLFSSL_BAD_FILE;
+    }
+    memSz = (int)XFTELL(file);
+    XREWIND(file);
+
+    if (memSz > MAX_WOLFSSL_FILE_SIZE || memSz <= 0) {
+        WOLFSSL_MSG("CM_RestoreCertCache file size error");
+        XFCLOSE(file);
+        return WOLFSSL_BAD_FILE;
+    }
+
+    mem = (byte*)XMALLOC(memSz, cm->heap, DYNAMIC_TYPE_TMP_BUFFER);
+    if (mem == NULL) {
+        WOLFSSL_MSG("Alloc for tmp buffer failed");
+        XFCLOSE(file);
+        return MEMORY_E;
+    }
+
+    ret = (int)XFREAD(mem, memSz, 1, file);
+    if (ret != 1) {
+        WOLFSSL_MSG("Cert file read error");
+        rc = FREAD_ERROR;
+    } else {
+        rc = CM_MemRestoreCertCache(cm, mem, memSz);
+        if (rc != WOLFSSL_SUCCESS) {
+            WOLFSSL_MSG("Mem restore cert cache failed");
+        }
+    }
+
+    XFREE(mem, cm->heap, DYNAMIC_TYPE_TMP_BUFFER);
+    XFCLOSE(file);
+
+    return rc;
+}
+
+#endif /* NO_FILESYSTEM */
+
+
+/* Persist cert cache to memory */
+int CM_MemSaveCertCache(WOLFSSL_CERT_MANAGER* cm, void* mem, int sz, int* used)
+{
+    int ret = WOLFSSL_SUCCESS;
+
+    WOLFSSL_ENTER("CM_MemSaveCertCache");
+
+    if (wc_LockMutex(&cm->caLock) != 0) {
+        WOLFSSL_MSG("wc_LockMutex on caLock failed");
+        return BAD_MUTEX_E;
+    }
+
+    ret = DoMemSaveCertCache(cm, mem, sz);
+    if (ret == WOLFSSL_SUCCESS)
+        *used  = GetCertCacheMemSize(cm);
+
+    wc_UnLockMutex(&cm->caLock);
+
+    return ret;
+}
+
+
+/* Restore cert cache from memory */
+int CM_MemRestoreCertCache(WOLFSSL_CERT_MANAGER* cm, const void* mem, int sz)
+{
+    int ret = WOLFSSL_SUCCESS;
+    int i;
+    CertCacheHeader* hdr = (CertCacheHeader*)mem;
+    byte*            current = (byte*)mem + sizeof(CertCacheHeader);
+    byte*            end     = (byte*)mem + sz;  /* don't go over */
+
+    WOLFSSL_ENTER("CM_MemRestoreCertCache");
+
+    if (current > end) {
+        WOLFSSL_MSG("Cert Cache Memory buffer too small");
+        return BUFFER_E;
+    }
+
+    if (hdr->version  != WOLFSSL_CACHE_CERT_VERSION ||
+        hdr->rows     != CA_TABLE_SIZE ||
+        hdr->signerSz != (int)sizeof(Signer)) {
+
+        WOLFSSL_MSG("Cert Cache Memory header mismatch");
+        return CACHE_MATCH_ERROR;
+    }
+
+    if (wc_LockMutex(&cm->caLock) != 0) {
+        WOLFSSL_MSG("wc_LockMutex on caLock failed");
+        return BAD_MUTEX_E;
+    }
+
+    FreeSignerTable(cm->caTable, CA_TABLE_SIZE, cm->heap);
+
+    for (i = 0; i < CA_TABLE_SIZE; ++i) {
+        int added = RestoreCertRow(cm, current, i, hdr->columns[i], end);
+        if (added < 0) {
+            WOLFSSL_MSG("RestoreCertRow error");
+            ret = added;
+            break;
+        }
+        current += added;
+    }
+
+    wc_UnLockMutex(&cm->caLock);
+
+    return ret;
+}
+
+
+/* get how big the the cert cache save buffer needs to be */
+int CM_GetCertCacheMemSize(WOLFSSL_CERT_MANAGER* cm)
+{
+    int sz;
+
+    WOLFSSL_ENTER("CM_GetCertCacheMemSize");
+
+    if (wc_LockMutex(&cm->caLock) != 0) {
+        WOLFSSL_MSG("wc_LockMutex on caLock failed");
+        return BAD_MUTEX_E;
+    }
+
+    sz = GetCertCacheMemSize(cm);
+
+    wc_UnLockMutex(&cm->caLock);
+
+    return sz;
+}
+
+#endif /* PERSIST_CERT_CACHE */
+#endif /* NO_CERTS */
+
+#ifdef OPENSSL_EXTRA
+
+
+/* removes all cipher suites from the list that contain "toRemove"
+ * returns the new list size on success
+ */
+static int wolfSSL_remove_ciphers(char* list, int sz, const char* toRemove)
+{
+    int idx = 0;
+    char* next = (char*)list;
+    int totalSz = sz;
+
+    if (list == NULL) {
+        return 0;
+    }
+
+    do {
+        char*  current = next;
+        char   name[MAX_SUITE_NAME + 1];
+        word32 length;
+
+        next   = XSTRSTR(next, ":");
+        length = min(sizeof(name), !next ? (word32)XSTRLEN(current) /* last */
+                                         : (word32)(next - current));
+
+        XSTRNCPY(name, current, length);
+        name[(length == sizeof(name)) ? length - 1 : length] = 0;
+
+        if (XSTRSTR(name, toRemove)) {
+            XMEMMOVE(list + idx, list + idx + length, totalSz - (idx + length));
+            totalSz -= length;
+            list[totalSz] = '\0';
+            next = current;
+        }
+        else {
+            idx += length;
+        }
+    } while (next++); /* ++ needed to skip ':' */
+
+    return totalSz;
+}
+
+/* parse some bulk lists like !eNULL / !aNULL
+ *
+ * returns WOLFSSL_SUCCESS on success and sets the cipher suite list
+ */
+static int wolfSSL_parse_cipher_list(WOLFSSL_CTX* ctx, Suites* suites,
+        const char* list)
+{
+    int       ret          = 0;
+    const int suiteSz      = GetCipherNamesSize();
+    char*     next         = (char*)list;
+    const CipherSuiteInfo* names = GetCipherNames();
+    char*     localList    = NULL;
+    int sz = 0;
+
+    if (suites == NULL || list == NULL) {
+        WOLFSSL_MSG("NULL argument");
+        return WOLFSSL_FAILURE;
+    }
+
+    /* does list contain eNULL or aNULL? */
+    if (XSTRSTR(list, "aNULL") || XSTRSTR(list, "eNULL")) {
+        do {
+            char*  current = next;
+            char   name[MAX_SUITE_NAME + 1];
+            int    i;
+            word32 length;
+
+            next   = XSTRSTR(next, ":");
+            length = min(sizeof(name), !next ? (word32)XSTRLEN(current) /*last*/
+                                             : (word32)(next - current));
+
+            XSTRNCPY(name, current, length);
+            name[(length == sizeof(name)) ? length - 1 : length] = 0;
+
+            /* check for "not" case */
+            if (name[0] == '!' && suiteSz > 0) {
+                /* populate list with all suites if not already created */
+                if (localList == NULL) {
+                    for (i = 0; i < suiteSz; i++) {
+                        sz += (int)XSTRLEN(names[i].name) + 2;
+                    }
+                    localList = (char*)XMALLOC(sz, ctx->heap,
+                                                       DYNAMIC_TYPE_TMP_BUFFER);
+                    if (localList == NULL) {
+                        return WOLFSSL_FAILURE;
+                    }
+                    wolfSSL_get_ciphers(localList, sz);
+                    sz = (int)XSTRLEN(localList);
+                }
+
+                if (XSTRSTR(name, "eNULL")) {
+                    wolfSSL_remove_ciphers(localList, sz, "-NULL");
+                }
+            }
+        }
+        while (next++); /* ++ needed to skip ':' */
+
+        ret = SetCipherList(ctx, suites, localList);
+        XFREE(localList, ctx->heap, DYNAMIC_TYPE_TMP_BUFFER);
+        return (ret)? WOLFSSL_SUCCESS : WOLFSSL_FAILURE;
+    }
+    else {
+        return (SetCipherList(ctx, suites, list)) ? WOLFSSL_SUCCESS :
+            WOLFSSL_FAILURE;
+    }
+}
+
+#endif
+
+
+int wolfSSL_CTX_set_cipher_list(WOLFSSL_CTX* ctx, const char* list)
+{
+    WOLFSSL_ENTER("wolfSSL_CTX_set_cipher_list");
+
+    if (ctx == NULL)
+        return WOLFSSL_FAILURE;
+
+    /* alloc/init on demand only */
+    if (ctx->suites == NULL) {
+        ctx->suites = (Suites*)XMALLOC(sizeof(Suites), ctx->heap,
+                                       DYNAMIC_TYPE_SUITES);
+        if (ctx->suites == NULL) {
+            WOLFSSL_MSG("Memory alloc for Suites failed");
+            return WOLFSSL_FAILURE;
+        }
+        XMEMSET(ctx->suites, 0, sizeof(Suites));
+    }
+
+#ifdef OPENSSL_EXTRA
+    return wolfSSL_parse_cipher_list(ctx, ctx->suites, list);
+#else
+    return (SetCipherList(ctx, ctx->suites, list)) ? WOLFSSL_SUCCESS : WOLFSSL_FAILURE;
+#endif
+}
+
+
+int wolfSSL_set_cipher_list(WOLFSSL* ssl, const char* list)
+{
+    WOLFSSL_ENTER("wolfSSL_set_cipher_list");
+#ifdef SINGLE_THREADED
+    if (ssl->ctx->suites == ssl->suites) {
+        ssl->suites = (Suites*)XMALLOC(sizeof(Suites), ssl->heap,
+                                       DYNAMIC_TYPE_SUITES);
+        if (ssl->suites == NULL) {
+            WOLFSSL_MSG("Suites Memory error");
+            return MEMORY_E;
+        }
+        ssl->options.ownSuites = 1;
+    }
+#endif
+
+#ifdef OPENSSL_EXTRA
+    return wolfSSL_parse_cipher_list(ssl->ctx, ssl->suites, list);
+#else
+    return (SetCipherList(ssl->ctx, ssl->suites, list)) ? WOLFSSL_SUCCESS : WOLFSSL_FAILURE;
+#endif
+}
+
+
+int wolfSSL_dtls_get_using_nonblock(WOLFSSL* ssl)
+{
+    int useNb = 0;
+
+    if (ssl == NULL)
+        return WOLFSSL_FAILURE;
+
+    WOLFSSL_ENTER("wolfSSL_dtls_get_using_nonblock");
+    if (ssl->options.dtls) {
+#ifdef WOLFSSL_DTLS
+        useNb = ssl->options.dtlsUseNonblock;
+#endif
+    }
+    else {
+        WOLFSSL_MSG("wolfSSL_dtls_get_using_nonblock() is "
+                    "DEPRECATED for non-DTLS use.");
+    }
+    return useNb;
+}
+
+
+#ifndef WOLFSSL_LEANPSK
+
+void wolfSSL_dtls_set_using_nonblock(WOLFSSL* ssl, int nonblock)
+{
+    (void)nonblock;
+
+    WOLFSSL_ENTER("wolfSSL_dtls_set_using_nonblock");
+
+    if (ssl == NULL)
+        return;
+
+    if (ssl->options.dtls) {
+#ifdef WOLFSSL_DTLS
+        ssl->options.dtlsUseNonblock = (nonblock != 0);
+#endif
+    }
+    else {
+        WOLFSSL_MSG("wolfSSL_dtls_set_using_nonblock() is "
+                    "DEPRECATED for non-DTLS use.");
+    }
+}
+
+
+#ifdef WOLFSSL_DTLS
+
+int wolfSSL_dtls_get_current_timeout(WOLFSSL* ssl)
+{
+    int timeout = 0;
+    if (ssl)
+        timeout = ssl->dtls_timeout;
+
+    WOLFSSL_LEAVE("wolfSSL_dtls_get_current_timeout()", timeout);
+    return timeout;
+}
+
+int wolfSSL_DTLSv1_get_timeout(WOLFSSL* ssl, WOLFSSL_TIMEVAL* timeleft)
+{
+    if (ssl && timeleft) {
+        XMEMSET(timeleft, 0, sizeof(WOLFSSL_TIMEVAL));
+        timeleft->tv_sec = ssl->dtls_timeout;
+    }
+    return 0;
+}
+
+#ifndef NO_WOLFSSL_STUB
+int wolfSSL_DTLSv1_handle_timeout(WOLFSSL* ssl)
+{
+    WOLFSSL_STUB("SSL_DTLSv1_handle_timeout");
+    (void)ssl;
+    return 0;
+}
+#endif
+
+#ifndef NO_WOLFSSL_STUB
+void wolfSSL_DTLSv1_set_initial_timeout_duration(WOLFSSL* ssl, word32 duration_ms)
+{
+    WOLFSSL_STUB("SSL_DTLSv1_set_initial_timeout_duration");
+    (void)ssl;
+    (void)duration_ms;
+}
+#endif
+
+/* user may need to alter init dtls recv timeout, WOLFSSL_SUCCESS on ok */
+int wolfSSL_dtls_set_timeout_init(WOLFSSL* ssl, int timeout)
+{
+    if (ssl == NULL || timeout < 0)
+        return BAD_FUNC_ARG;
+
+    if (timeout > ssl->dtls_timeout_max) {
+        WOLFSSL_MSG("Can't set dtls timeout init greater than dtls timeout max");
+        return BAD_FUNC_ARG;
+    }
+
+    ssl->dtls_timeout_init = timeout;
+    ssl->dtls_timeout = timeout;
+
+    return WOLFSSL_SUCCESS;
+}
+
+
+/* user may need to alter max dtls recv timeout, WOLFSSL_SUCCESS on ok */
+int wolfSSL_dtls_set_timeout_max(WOLFSSL* ssl, int timeout)
+{
+    if (ssl == NULL || timeout < 0)
+        return BAD_FUNC_ARG;
+
+    if (timeout < ssl->dtls_timeout_init) {
+        WOLFSSL_MSG("Can't set dtls timeout max less than dtls timeout init");
+        return BAD_FUNC_ARG;
+    }
+
+    ssl->dtls_timeout_max = timeout;
+
+    return WOLFSSL_SUCCESS;
+}
+
+
+int wolfSSL_dtls_got_timeout(WOLFSSL* ssl)
+{
+    int result = WOLFSSL_SUCCESS;
+    WOLFSSL_ENTER("wolfSSL_dtls_got_timeout()");
+
+    if (ssl == NULL)
+        return WOLFSSL_FATAL_ERROR;
+
+    if (!ssl->options.handShakeDone &&
+        (DtlsMsgPoolTimeout(ssl) < 0 || DtlsMsgPoolSend(ssl, 0) < 0)) {
+
+        result = WOLFSSL_FATAL_ERROR;
+    }
+
+    WOLFSSL_LEAVE("wolfSSL_dtls_got_timeout()", result);
+    return result;
+}
+
+
+/* retransmit all the saves messages, WOLFSSL_SUCCESS on ok */
+int wolfSSL_dtls_retransmit(WOLFSSL* ssl)
+{
+    WOLFSSL_ENTER("wolfSSL_dtls_retransmit()");
+
+    if (ssl == NULL)
+        return WOLFSSL_FATAL_ERROR;
+
+    if (!ssl->options.handShakeDone) {
+        int result = DtlsMsgPoolSend(ssl, 0);
+        if (result < 0) {
+            ssl->error = result;
+            WOLFSSL_ERROR(result);
+            return WOLFSSL_FATAL_ERROR;
+        }
+    }
+
+    return 0;
+}
+
+#endif /* DTLS */
+#endif /* LEANPSK */
+
+
+#if defined(WOLFSSL_DTLS) && !defined(NO_WOLFSSL_SERVER)
+
+/* Not an SSL function, return 0 for success, error code otherwise */
+/* Prereq: ssl's RNG needs to be initialized. */
+int wolfSSL_DTLS_SetCookieSecret(WOLFSSL* ssl,
+                                 const byte* secret, word32 secretSz)
+{
+    int ret = 0;
+
+    WOLFSSL_ENTER("wolfSSL_DTLS_SetCookieSecret");
+
+    if (ssl == NULL) {
+        WOLFSSL_MSG("need a SSL object");
+        return BAD_FUNC_ARG;
+    }
+
+    if (secret != NULL && secretSz == 0) {
+        WOLFSSL_MSG("can't have a new secret without a size");
+        return BAD_FUNC_ARG;
+    }
+
+    /* If secretSz is 0, use the default size. */
+    if (secretSz == 0)
+        secretSz = COOKIE_SECRET_SZ;
+
+    if (secretSz != ssl->buffers.dtlsCookieSecret.length) {
+        byte* newSecret;
+
+        if (ssl->buffers.dtlsCookieSecret.buffer != NULL) {
+            ForceZero(ssl->buffers.dtlsCookieSecret.buffer,
+                      ssl->buffers.dtlsCookieSecret.length);
+            XFREE(ssl->buffers.dtlsCookieSecret.buffer,
+                  ssl->heap, DYNAMIC_TYPE_NONE);
+        }
+
+        newSecret = (byte*)XMALLOC(secretSz, ssl->heap,DYNAMIC_TYPE_COOKIE_PWD);
+        if (newSecret == NULL) {
+            ssl->buffers.dtlsCookieSecret.buffer = NULL;
+            ssl->buffers.dtlsCookieSecret.length = 0;
+            WOLFSSL_MSG("couldn't allocate new cookie secret");
+            return MEMORY_ERROR;
+        }
+        ssl->buffers.dtlsCookieSecret.buffer = newSecret;
+        ssl->buffers.dtlsCookieSecret.length = secretSz;
+    }
+
+    /* If the supplied secret is NULL, randomly generate a new secret. */
+    if (secret == NULL) {
+        ret = wc_RNG_GenerateBlock(ssl->rng,
+                             ssl->buffers.dtlsCookieSecret.buffer, secretSz);
+    }
+    else
+        XMEMCPY(ssl->buffers.dtlsCookieSecret.buffer, secret, secretSz);
+
+    WOLFSSL_LEAVE("wolfSSL_DTLS_SetCookieSecret", 0);
+    return ret;
+}
+
+#endif /* WOLFSSL_DTLS && !NO_WOLFSSL_SERVER */
+
+
+/* EITHER SIDE METHODS */
+#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_EITHER_SIDE)
+    WOLFSSL_METHOD* wolfSSLv23_method(void)
+    {
+        return wolfSSLv23_method_ex(NULL);
+    }
+    WOLFSSL_METHOD* wolfSSLv23_method_ex(void* heap)
+    {
+        WOLFSSL_METHOD* m = NULL;
+        WOLFSSL_ENTER("SSLv23_method");
+    #if !defined(NO_WOLFSSL_CLIENT)
+        m = wolfSSLv23_client_method_ex(heap);
+    #elif !defined(NO_WOLFSSL_SERVER)
+        m = wolfSSLv23_server_method_ex(heap);
+    #endif
+        if (m != NULL) {
+            m->side = WOLFSSL_NEITHER_END;
+        }
+
+        return m;
+    }
+
+    #ifdef WOLFSSL_ALLOW_SSLV3
+    WOLFSSL_METHOD* wolfSSLv3_method(void)
+    {
+        return wolfSSLv3_method_ex(NULL);
+    }
+    WOLFSSL_METHOD* wolfSSLv3_method_ex(void* heap)
+    {
+        WOLFSSL_METHOD* m = NULL;
+        WOLFSSL_ENTER("SSLv3_method");
+    #if !defined(NO_WOLFSSL_CLIENT)
+        m = wolfSSLv3_client_method_ex(heap);
+    #elif !defined(NO_WOLFSSL_SERVER)
+        m = wolfSSLv3_server_method_ex(heap);
+    #endif
+        if (m != NULL) {
+            m->side = WOLFSSL_NEITHER_END;
+        }
+
+        return m;
+    }
+    #endif
+#endif /* OPENSSL_EXTRA || WOLFSSL_EITHER_SIDE */
+
+/* client only parts */
+#ifndef NO_WOLFSSL_CLIENT
+
+    #ifdef OPENSSL_EXTRA
+    WOLFSSL_METHOD* wolfSSLv2_client_method(void)
+    {
+        WOLFSSL_STUB("wolfSSLv2_client_method");
+        return NULL;
+    }
+    #endif
+
+    #ifdef WOLFSSL_ALLOW_SSLV3
+    WOLFSSL_METHOD* wolfSSLv3_client_method(void)
+    {
+        return wolfSSLv3_client_method_ex(NULL);
+    }
+    WOLFSSL_METHOD* wolfSSLv3_client_method_ex(void* heap)
+    {
+        WOLFSSL_METHOD* method =
+                              (WOLFSSL_METHOD*) XMALLOC(sizeof(WOLFSSL_METHOD),
+                                                     heap, DYNAMIC_TYPE_METHOD);
+        (void)heap;
+        WOLFSSL_ENTER("SSLv3_client_method_ex");
+        if (method)
+            InitSSL_Method(method, MakeSSLv3());
+        return method;
+    }
+    #endif /* WOLFSSL_ALLOW_SSLV3 */
+
+
+    WOLFSSL_METHOD* wolfSSLv23_client_method(void)
+    {
+        return wolfSSLv23_client_method_ex(NULL);
+    }
+    WOLFSSL_METHOD* wolfSSLv23_client_method_ex(void* heap)
+    {
+        WOLFSSL_METHOD* method =
+                              (WOLFSSL_METHOD*) XMALLOC(sizeof(WOLFSSL_METHOD),
+                                                     heap, DYNAMIC_TYPE_METHOD);
+        (void)heap;
+        WOLFSSL_ENTER("SSLv23_client_method_ex");
+        if (method) {
+    #if !defined(NO_SHA256) || defined(WOLFSSL_SHA384) || defined(WOLFSSL_SHA512)
+        #if defined(WOLFSSL_TLS13)
+            InitSSL_Method(method, MakeTLSv1_3());
+        #elif !defined(WOLFSSL_NO_TLS12)
+            InitSSL_Method(method, MakeTLSv1_2());
+        #elif !defined(NO_OLD_TLS)
+            InitSSL_Method(method, MakeTLSv1_1());
+        #endif
+    #else
+        #ifndef NO_OLD_TLS
+            InitSSL_Method(method, MakeTLSv1_1());
+        #endif
+    #endif
+    #if !defined(NO_OLD_TLS) || defined(WOLFSSL_TLS13)
+            method->downgrade = 1;
+    #endif
+        }
+        return method;
+    }
+
+
+    #if defined(WOLFSSL_DTLS) || !defined(WOLFSSL_NO_TLS12) || !defined(NO_OLD_TLS) || \
+        defined(WOLFSSL_ALLOW_SSLV3)
+    /* If SCTP is not enabled returns the state of the dtls option.
+     * If SCTP is enabled returns dtls && !sctp. */
+    static WC_INLINE int IsDtlsNotSctpMode(WOLFSSL* ssl)
+    {
+        int result = ssl->options.dtls;
+
+        if (result) {
+        #ifdef WOLFSSL_SCTP
+            result = !ssl->options.dtlsSctp;
+        #endif
+        }
+
+        return result;
+    }
+    #endif /* WOLFSSL_DTLS || !WOLFSSL_NO_TLS12 || !NO_OLD_TLS */
+
+
+    /* please see note at top of README if you get an error from connect */
+    WOLFSSL_ABI
+    int wolfSSL_connect(WOLFSSL* ssl)
+    {
+    #if !(defined(WOLFSSL_NO_TLS12) && defined(NO_OLD_TLS) && defined(WOLFSSL_TLS13))
+        int neededState;
+    #endif
+
+        WOLFSSL_ENTER("SSL_connect()");
+
+        #ifdef HAVE_ERRNO_H
+            errno = 0;
+        #endif
+
+        if (ssl == NULL)
+            return BAD_FUNC_ARG;
+
+    #if defined(OPENSSL_EXTRA) || defined(WOLFSSL_EITHER_SIDE)
+        if (ssl->options.side == WOLFSSL_NEITHER_END) {
+            ssl->error = InitSSL_Side(ssl, WOLFSSL_CLIENT_END);
+            if (ssl->error != WOLFSSL_SUCCESS) {
+                WOLFSSL_ERROR(ssl->error);
+                return WOLFSSL_FATAL_ERROR;
+            }
+            ssl->error = 0; /* expected to be zero here */
+        }
+
+    #ifdef OPENSSL_EXTRA
+        if (ssl->CBIS != NULL) {
+            ssl->CBIS(ssl, SSL_ST_CONNECT, SSL_SUCCESS);
+            ssl->cbmode = SSL_CB_WRITE;
+        }
+    #endif
+    #endif /* OPENSSL_EXTRA || WOLFSSL_EITHER_SIDE */
+
+    #if defined(WOLFSSL_NO_TLS12) && defined(NO_OLD_TLS) && defined(WOLFSSL_TLS13)
+        return wolfSSL_connect_TLSv13(ssl);
+    #else
+        #ifdef WOLFSSL_TLS13
+        if (ssl->options.tls1_3)
+            return wolfSSL_connect_TLSv13(ssl);
+        #endif
+
+        if (ssl->options.side != WOLFSSL_CLIENT_END) {
+            WOLFSSL_ERROR(ssl->error = SIDE_ERROR);
+            return WOLFSSL_FATAL_ERROR;
+        }
+
+        #ifdef WOLFSSL_DTLS
+        if (ssl->version.major == DTLS_MAJOR) {
+            ssl->options.dtls   = 1;
+            ssl->options.tls    = 1;
+            ssl->options.tls1_1 = 1;
+        }
+        #endif
+
+        if (ssl->buffers.outputBuffer.length > 0
+        #ifdef WOLFSSL_ASYNC_CRYPT
+            /* do not send buffered or advance state if last error was an 
+                async pending operation */
+            && ssl->error != WC_PENDING_E
+        #endif
+        ) {
+            if ( (ssl->error = SendBuffered(ssl)) == 0) {
+                /* fragOffset is non-zero when sending fragments. On the last
+                 * fragment, fragOffset is zero again, and the state can be
+                 * advanced. */
+                if (ssl->fragOffset == 0) {
+                    ssl->options.connectState++;
+                    WOLFSSL_MSG("connect state: "
+                                "Advanced from last buffered fragment send");
+                }
+                else {
+                    WOLFSSL_MSG("connect state: "
+                                "Not advanced, more fragments to send");
+                }
+            }
+            else {
+                WOLFSSL_ERROR(ssl->error);
+                return WOLFSSL_FATAL_ERROR;
+            }
+        }
+
+        switch (ssl->options.connectState) {
+
+        case CONNECT_BEGIN :
+            /* always send client hello first */
+            if ( (ssl->error = SendClientHello(ssl)) != 0) {
+                WOLFSSL_ERROR(ssl->error);
+                return WOLFSSL_FATAL_ERROR;
+            }
+            ssl->options.connectState = CLIENT_HELLO_SENT;
+            WOLFSSL_MSG("connect state: CLIENT_HELLO_SENT");
+            FALL_THROUGH;
+
+        case CLIENT_HELLO_SENT :
+            neededState = ssl->options.resuming ? SERVER_FINISHED_COMPLETE :
+                                          SERVER_HELLODONE_COMPLETE;
+            #ifdef WOLFSSL_DTLS
+                /* In DTLS, when resuming, we can go straight to FINISHED,
+                 * or do a cookie exchange and then skip to FINISHED, assume
+                 * we need the cookie exchange first. */
+                if (IsDtlsNotSctpMode(ssl))
+                    neededState = SERVER_HELLOVERIFYREQUEST_COMPLETE;
+            #endif
+            /* get response */
+            while (ssl->options.serverState < neededState) {
+                #ifdef WOLFSSL_TLS13
+                    if (ssl->options.tls1_3)
+                        return wolfSSL_connect_TLSv13(ssl);
+                #endif
+                if ( (ssl->error = ProcessReply(ssl)) < 0) {
+                    WOLFSSL_ERROR(ssl->error);
+                    return WOLFSSL_FATAL_ERROR;
+                }
+                /* if resumption failed, reset needed state */
+                else if (neededState == SERVER_FINISHED_COMPLETE)
+                    if (!ssl->options.resuming) {
+                        if (!IsDtlsNotSctpMode(ssl))
+                            neededState = SERVER_HELLODONE_COMPLETE;
+                        else
+                            neededState = SERVER_HELLOVERIFYREQUEST_COMPLETE;
+                    }
+            }
+
+            ssl->options.connectState = HELLO_AGAIN;
+            WOLFSSL_MSG("connect state: HELLO_AGAIN");
+            FALL_THROUGH;
+
+        case HELLO_AGAIN :
+            if (ssl->options.certOnly)
+                return WOLFSSL_SUCCESS;
+
+        #ifdef WOLFSSL_TLS13
+            if (ssl->options.tls1_3)
+                return wolfSSL_connect_TLSv13(ssl);
+        #endif
+
+            #ifdef WOLFSSL_DTLS
+            if (ssl->options.serverState ==
+                    SERVER_HELLOVERIFYREQUEST_COMPLETE) {
+                if (IsDtlsNotSctpMode(ssl)) {
+                    /* re-init hashes, exclude first hello and verify request */
+                    if ((ssl->error = InitHandshakeHashes(ssl)) != 0) {
+                        WOLFSSL_ERROR(ssl->error);
+                        return WOLFSSL_FATAL_ERROR;
+                    }
+                    if ( (ssl->error = SendClientHello(ssl)) != 0) {
+                        WOLFSSL_ERROR(ssl->error);
+                        return WOLFSSL_FATAL_ERROR;
+                    }
+                }
+            }
+            #endif
+
+            ssl->options.connectState = HELLO_AGAIN_REPLY;
+            WOLFSSL_MSG("connect state: HELLO_AGAIN_REPLY");
+            FALL_THROUGH;
+
+        case HELLO_AGAIN_REPLY :
+            #ifdef WOLFSSL_DTLS
+                if (IsDtlsNotSctpMode(ssl)) {
+                    neededState = ssl->options.resuming ?
+                           SERVER_FINISHED_COMPLETE : SERVER_HELLODONE_COMPLETE;
+
+                    /* get response */
+                    while (ssl->options.serverState < neededState) {
+                        if ( (ssl->error = ProcessReply(ssl)) < 0) {
+                            WOLFSSL_ERROR(ssl->error);
+                            return WOLFSSL_FATAL_ERROR;
+                        }
+                        /* if resumption failed, reset needed state */
+                        if (neededState == SERVER_FINISHED_COMPLETE) {
+                            if (!ssl->options.resuming)
+                                neededState = SERVER_HELLODONE_COMPLETE;
+                        }
+                    }
+                }
+            #endif
+
+            ssl->options.connectState = FIRST_REPLY_DONE;
+            WOLFSSL_MSG("connect state: FIRST_REPLY_DONE");
+            FALL_THROUGH;
+
+        case FIRST_REPLY_DONE :
+            #if !defined(NO_CERTS) && !defined(WOLFSSL_NO_CLIENT_AUTH)
+                #ifdef WOLFSSL_TLS13
+                    if (ssl->options.tls1_3)
+                        return wolfSSL_connect_TLSv13(ssl);
+                #endif
+                if (ssl->options.sendVerify) {
+                    if ( (ssl->error = SendCertificate(ssl)) != 0) {
+                        WOLFSSL_ERROR(ssl->error);
+                        return WOLFSSL_FATAL_ERROR;
+                    }
+                    WOLFSSL_MSG("sent: certificate");
+                }
+
+            #endif
+            ssl->options.connectState = FIRST_REPLY_FIRST;
+            WOLFSSL_MSG("connect state: FIRST_REPLY_FIRST");
+            FALL_THROUGH;
+
+        case FIRST_REPLY_FIRST :
+        #ifdef WOLFSSL_TLS13
+            if (ssl->options.tls1_3)
+                return wolfSSL_connect_TLSv13(ssl);
+        #endif
+            if (!ssl->options.resuming) {
+                if ( (ssl->error = SendClientKeyExchange(ssl)) != 0) {
+                    WOLFSSL_ERROR(ssl->error);
+                    return WOLFSSL_FATAL_ERROR;
+                }
+                WOLFSSL_MSG("sent: client key exchange");
+            }
+
+            ssl->options.connectState = FIRST_REPLY_SECOND;
+            WOLFSSL_MSG("connect state: FIRST_REPLY_SECOND");
+            FALL_THROUGH;
+
+        case FIRST_REPLY_SECOND :
+            #if !defined(NO_CERTS) && !defined(WOLFSSL_NO_CLIENT_AUTH)
+                if (ssl->options.sendVerify) {
+                    if ( (ssl->error = SendCertificateVerify(ssl)) != 0) {
+                        WOLFSSL_ERROR(ssl->error);
+                        return WOLFSSL_FATAL_ERROR;
+                    }
+                    WOLFSSL_MSG("sent: certificate verify");
+                }
+            #endif /* !NO_CERTS && !WOLFSSL_NO_CLIENT_AUTH */
+            ssl->options.connectState = FIRST_REPLY_THIRD;
+            WOLFSSL_MSG("connect state: FIRST_REPLY_THIRD");
+            FALL_THROUGH;
+
+        case FIRST_REPLY_THIRD :
+            if ( (ssl->error = SendChangeCipher(ssl)) != 0) {
+                WOLFSSL_ERROR(ssl->error);
+                return WOLFSSL_FATAL_ERROR;
+            }
+            WOLFSSL_MSG("sent: change cipher spec");
+            ssl->options.connectState = FIRST_REPLY_FOURTH;
+            WOLFSSL_MSG("connect state: FIRST_REPLY_FOURTH");
+            FALL_THROUGH;
+
+        case FIRST_REPLY_FOURTH :
+            if ( (ssl->error = SendFinished(ssl)) != 0) {
+                WOLFSSL_ERROR(ssl->error);
+                return WOLFSSL_FATAL_ERROR;
+            }
+            WOLFSSL_MSG("sent: finished");
+            ssl->options.connectState = FINISHED_DONE;
+            WOLFSSL_MSG("connect state: FINISHED_DONE");
+            FALL_THROUGH;
+
+        case FINISHED_DONE :
+            /* get response */
+            while (ssl->options.serverState < SERVER_FINISHED_COMPLETE)
+                if ( (ssl->error = ProcessReply(ssl)) < 0) {
+                    WOLFSSL_ERROR(ssl->error);
+                    return WOLFSSL_FATAL_ERROR;
+                }
+
+            ssl->options.connectState = SECOND_REPLY_DONE;
+            WOLFSSL_MSG("connect state: SECOND_REPLY_DONE");
+            FALL_THROUGH;
+
+        case SECOND_REPLY_DONE:
+#ifndef NO_HANDSHAKE_DONE_CB
+            if (ssl->hsDoneCb) {
+                int cbret = ssl->hsDoneCb(ssl, ssl->hsDoneCtx);
+                if (cbret < 0) {
+                    ssl->error = cbret;
+                    WOLFSSL_MSG("HandShake Done Cb don't continue error");
+                    return WOLFSSL_FATAL_ERROR;
+                }
+            }
+#endif /* NO_HANDSHAKE_DONE_CB */
+
+            if (!ssl->options.dtls) {
+                if (!ssl->options.keepResources) {
+                    FreeHandshakeResources(ssl);
+                }
+            }
+#ifdef WOLFSSL_DTLS
+            else {
+                ssl->options.dtlsHsRetain = 1;
+            }
+#endif /* WOLFSSL_DTLS */
+
+            WOLFSSL_LEAVE("SSL_connect()", WOLFSSL_SUCCESS);
+            return WOLFSSL_SUCCESS;
+
+        default:
+            WOLFSSL_MSG("Unknown connect state ERROR");
+            return WOLFSSL_FATAL_ERROR; /* unknown connect state */
+        }
+    #endif /* !WOLFSSL_NO_TLS12 */
+    }
+
+#endif /* NO_WOLFSSL_CLIENT */
+
+
+/* server only parts */
+#ifndef NO_WOLFSSL_SERVER
+
+    #ifdef OPENSSL_EXTRA
+    WOLFSSL_METHOD* wolfSSLv2_server_method(void)
+    {
+        WOLFSSL_STUB("wolfSSLv2_server_method");
+        return 0;
+    }
+    #endif
+
+    #ifdef WOLFSSL_ALLOW_SSLV3
+    WOLFSSL_METHOD* wolfSSLv3_server_method(void)
+    {
+        return wolfSSLv3_server_method_ex(NULL);
+    }
+    WOLFSSL_METHOD* wolfSSLv3_server_method_ex(void* heap)
+    {
+        WOLFSSL_METHOD* method =
+                              (WOLFSSL_METHOD*) XMALLOC(sizeof(WOLFSSL_METHOD),
+                                                     heap, DYNAMIC_TYPE_METHOD);
+        (void)heap;
+        WOLFSSL_ENTER("SSLv3_server_method_ex");
+        if (method) {
+            InitSSL_Method(method, MakeSSLv3());
+            method->side = WOLFSSL_SERVER_END;
+        }
+        return method;
+    }
+    #endif /* WOLFSSL_ALLOW_SSLV3 */
+
+    WOLFSSL_METHOD* wolfSSLv23_server_method(void)
+    {
+        return wolfSSLv23_server_method_ex(NULL);
+    }
+
+    WOLFSSL_METHOD* wolfSSLv23_server_method_ex(void* heap)
+    {
+        WOLFSSL_METHOD* method =
+                              (WOLFSSL_METHOD*) XMALLOC(sizeof(WOLFSSL_METHOD),
+                                                     heap, DYNAMIC_TYPE_METHOD);
+        (void)heap;
+        WOLFSSL_ENTER("SSLv23_server_method_ex");
+        if (method) {
+    #if !defined(NO_SHA256) || defined(WOLFSSL_SHA384) || defined(WOLFSSL_SHA512)
+        #ifdef WOLFSSL_TLS13
+            InitSSL_Method(method, MakeTLSv1_3());
+        #elif !defined(WOLFSSL_NO_TLS12)
+            InitSSL_Method(method, MakeTLSv1_2());
+        #elif !defined(NO_OLD_TLS)
+            InitSSL_Method(method, MakeTLSv1_1());
+        #endif
+    #else
+        #ifndef NO_OLD_TLS
+            InitSSL_Method(method, MakeTLSv1_1());
+        #else
+            #error Must have SHA256, SHA384 or SHA512 enabled for TLS 1.2
+        #endif
+    #endif
+    #if !defined(NO_OLD_TLS) || defined(WOLFSSL_TLS13)
+            method->downgrade = 1;
+    #endif
+            method->side      = WOLFSSL_SERVER_END;
+        }
+        return method;
+    }
+
+
+    int wolfSSL_accept(WOLFSSL* ssl)
+    {
+#if !(defined(WOLFSSL_NO_TLS12) && defined(NO_OLD_TLS) && defined(WOLFSSL_TLS13))
+        word16 havePSK = 0;
+        word16 haveAnon = 0;
+        word16 haveMcast = 0;
+#endif
+
+        if (ssl == NULL)
+            return WOLFSSL_FATAL_ERROR;
+
+    #if defined(OPENSSL_EXTRA) || defined(WOLFSSL_EITHER_SIDE)
+        if (ssl->options.side == WOLFSSL_NEITHER_END) {
+            WOLFSSL_MSG("Setting WOLFSSL_SSL to be server side");
+            ssl->error = InitSSL_Side(ssl, WOLFSSL_SERVER_END);
+            if (ssl->error != WOLFSSL_SUCCESS) {
+                WOLFSSL_ERROR(ssl->error);
+                return WOLFSSL_FATAL_ERROR;
+            }
+            ssl->error = 0; /* expected to be zero here */
+        }
+    #endif /* OPENSSL_EXTRA || WOLFSSL_EITHER_SIDE */
+
+#if defined(WOLFSSL_NO_TLS12) && defined(NO_OLD_TLS) && defined(WOLFSSL_TLS13)
+        return wolfSSL_accept_TLSv13(ssl);
+#else
+    #ifdef WOLFSSL_TLS13
+        if (ssl->options.tls1_3)
+            return wolfSSL_accept_TLSv13(ssl);
+    #endif
+        WOLFSSL_ENTER("SSL_accept()");
+
+        #ifdef HAVE_ERRNO_H
+            errno = 0;
+        #endif
+
+        #ifndef NO_PSK
+            havePSK = ssl->options.havePSK;
+        #endif
+        (void)havePSK;
+
+        #ifdef HAVE_ANON
+            haveAnon = ssl->options.haveAnon;
+        #endif
+        (void)haveAnon;
+
+        #ifdef WOLFSSL_MULTICAST
+            haveMcast = ssl->options.haveMcast;
+        #endif
+        (void)haveMcast;
+
+        if (ssl->options.side != WOLFSSL_SERVER_END) {
+            WOLFSSL_ERROR(ssl->error = SIDE_ERROR);
+            return WOLFSSL_FATAL_ERROR;
+        }
+
+    #ifndef NO_CERTS
+        /* in case used set_accept_state after init */
+        /* allow no private key if using PK callbacks and CB is set */
+        if (!havePSK && !haveAnon && !haveMcast) {
+            if (!ssl->buffers.certificate ||
+                !ssl->buffers.certificate->buffer) {
+
+                WOLFSSL_MSG("accept error: server cert required");
+                WOLFSSL_ERROR(ssl->error = NO_PRIVATE_KEY);
+                return WOLFSSL_FATAL_ERROR;
+            }
+
+        #ifdef HAVE_PK_CALLBACKS
+            if (wolfSSL_CTX_IsPrivatePkSet(ssl->ctx)) {
+                WOLFSSL_MSG("Using PK for server private key");
+            }
+            else
+        #endif
+            if (!ssl->buffers.key || !ssl->buffers.key->buffer) {
+                WOLFSSL_MSG("accept error: server key required");
+                WOLFSSL_ERROR(ssl->error = NO_PRIVATE_KEY);
+                return WOLFSSL_FATAL_ERROR;
+            }
+        }
+    #endif
+
+    #ifdef WOLFSSL_DTLS
+        if (ssl->version.major == DTLS_MAJOR) {
+            ssl->options.dtls   = 1;
+            ssl->options.tls    = 1;
+            ssl->options.tls1_1 = 1;
+        }
+    #endif
+
+        if (ssl->buffers.outputBuffer.length > 0
+        #ifdef WOLFSSL_ASYNC_CRYPT
+            /* do not send buffered or advance state if last error was an 
+                async pending operation */
+            && ssl->error != WC_PENDING_E
+        #endif
+        ) {
+            if ( (ssl->error = SendBuffered(ssl)) == 0) {
+                /* fragOffset is non-zero when sending fragments. On the last
+                 * fragment, fragOffset is zero again, and the state can be
+                 * advanced. */
+                if (ssl->fragOffset == 0) {
+                    ssl->options.acceptState++;
+                    WOLFSSL_MSG("accept state: "
+                                "Advanced from last buffered fragment send");
+                }
+                else {
+                    WOLFSSL_MSG("accept state: "
+                                "Not advanced, more fragments to send");
+                }
+            }
+            else {
+                WOLFSSL_ERROR(ssl->error);
+                return WOLFSSL_FATAL_ERROR;
+            }
+        }
+
+        switch (ssl->options.acceptState) {
+
+        case ACCEPT_BEGIN :
+#ifdef HAVE_SECURE_RENEGOTIATION
+        case ACCEPT_BEGIN_RENEG:
+#endif
+            /* get response */
+            while (ssl->options.clientState < CLIENT_HELLO_COMPLETE)
+                if ( (ssl->error = ProcessReply(ssl)) < 0) {
+                    WOLFSSL_ERROR(ssl->error);
+                    return WOLFSSL_FATAL_ERROR;
+                }
+#ifdef WOLFSSL_TLS13
+            ssl->options.acceptState = ACCEPT_CLIENT_HELLO_DONE;
+            WOLFSSL_MSG("accept state ACCEPT_CLIENT_HELLO_DONE");
+            FALL_THROUGH;
+
+        case ACCEPT_CLIENT_HELLO_DONE :
+            if (ssl->options.tls1_3) {
+                return wolfSSL_accept_TLSv13(ssl);
+            }
+#endif
+            ssl->options.acceptState = ACCEPT_FIRST_REPLY_DONE;
+            WOLFSSL_MSG("accept state ACCEPT_FIRST_REPLY_DONE");
+            FALL_THROUGH;
+
+        case ACCEPT_FIRST_REPLY_DONE :
+            if ( (ssl->error = SendServerHello(ssl)) != 0) {
+                WOLFSSL_ERROR(ssl->error);
+                return WOLFSSL_FATAL_ERROR;
+            }
+            ssl->options.acceptState = SERVER_HELLO_SENT;
+            WOLFSSL_MSG("accept state SERVER_HELLO_SENT");
+            FALL_THROUGH;
+
+        case SERVER_HELLO_SENT :
+        #ifdef WOLFSSL_TLS13
+            if (ssl->options.tls1_3) {
+                return wolfSSL_accept_TLSv13(ssl);
+            }
+        #endif
+            #ifndef NO_CERTS
+                if (!ssl->options.resuming)
+                    if ( (ssl->error = SendCertificate(ssl)) != 0) {
+                        WOLFSSL_ERROR(ssl->error);
+                        return WOLFSSL_FATAL_ERROR;
+                    }
+            #endif
+            ssl->options.acceptState = CERT_SENT;
+            WOLFSSL_MSG("accept state CERT_SENT");
+            FALL_THROUGH;
+
+        case CERT_SENT :
+            #ifndef NO_CERTS
+            if (!ssl->options.resuming)
+                if ( (ssl->error = SendCertificateStatus(ssl)) != 0) {
+                    WOLFSSL_ERROR(ssl->error);
+                    return WOLFSSL_FATAL_ERROR;
+                }
+            #endif
+            ssl->options.acceptState = CERT_STATUS_SENT;
+            WOLFSSL_MSG("accept state CERT_STATUS_SENT");
+            FALL_THROUGH;
+
+        case CERT_STATUS_SENT :
+        #ifdef WOLFSSL_TLS13
+            if (ssl->options.tls1_3) {
+                return wolfSSL_accept_TLSv13(ssl);
+            }
+        #endif
+            if (!ssl->options.resuming)
+                if ( (ssl->error = SendServerKeyExchange(ssl)) != 0) {
+                    WOLFSSL_ERROR(ssl->error);
+                    return WOLFSSL_FATAL_ERROR;
+                }
+            ssl->options.acceptState = KEY_EXCHANGE_SENT;
+            WOLFSSL_MSG("accept state KEY_EXCHANGE_SENT");
+            FALL_THROUGH;
+
+        case KEY_EXCHANGE_SENT :
+            #ifndef NO_CERTS
+                if (!ssl->options.resuming) {
+                    if (ssl->options.verifyPeer) {
+                        if ( (ssl->error = SendCertificateRequest(ssl)) != 0) {
+                            WOLFSSL_ERROR(ssl->error);
+                            return WOLFSSL_FATAL_ERROR;
+                        }
+                    }
+                }
+            #endif
+            ssl->options.acceptState = CERT_REQ_SENT;
+            WOLFSSL_MSG("accept state CERT_REQ_SENT");
+            FALL_THROUGH;
+
+        case CERT_REQ_SENT :
+            if (!ssl->options.resuming)
+                if ( (ssl->error = SendServerHelloDone(ssl)) != 0) {
+                    WOLFSSL_ERROR(ssl->error);
+                    return WOLFSSL_FATAL_ERROR;
+                }
+            ssl->options.acceptState = SERVER_HELLO_DONE;
+            WOLFSSL_MSG("accept state SERVER_HELLO_DONE");
+            FALL_THROUGH;
+
+        case SERVER_HELLO_DONE :
+            if (!ssl->options.resuming) {
+                while (ssl->options.clientState < CLIENT_FINISHED_COMPLETE)
+                    if ( (ssl->error = ProcessReply(ssl)) < 0) {
+                        WOLFSSL_ERROR(ssl->error);
+                        return WOLFSSL_FATAL_ERROR;
+                    }
+            }
+            ssl->options.acceptState = ACCEPT_SECOND_REPLY_DONE;
+            WOLFSSL_MSG("accept state  ACCEPT_SECOND_REPLY_DONE");
+            FALL_THROUGH;
+
+        case ACCEPT_SECOND_REPLY_DONE :
+#ifdef HAVE_SESSION_TICKET
+            if (ssl->options.createTicket) {
+                if ( (ssl->error = SendTicket(ssl)) != 0) {
+                    WOLFSSL_ERROR(ssl->error);
+                    return WOLFSSL_FATAL_ERROR;
+                }
+            }
+#endif /* HAVE_SESSION_TICKET */
+            ssl->options.acceptState = TICKET_SENT;
+            WOLFSSL_MSG("accept state  TICKET_SENT");
+            FALL_THROUGH;
+
+        case TICKET_SENT:
+            if ( (ssl->error = SendChangeCipher(ssl)) != 0) {
+                WOLFSSL_ERROR(ssl->error);
+                return WOLFSSL_FATAL_ERROR;
+            }
+            ssl->options.acceptState = CHANGE_CIPHER_SENT;
+            WOLFSSL_MSG("accept state  CHANGE_CIPHER_SENT");
+            FALL_THROUGH;
+
+        case CHANGE_CIPHER_SENT :
+            if ( (ssl->error = SendFinished(ssl)) != 0) {
+                WOLFSSL_ERROR(ssl->error);
+                return WOLFSSL_FATAL_ERROR;
+            }
+
+            ssl->options.acceptState = ACCEPT_FINISHED_DONE;
+            WOLFSSL_MSG("accept state ACCEPT_FINISHED_DONE");
+            FALL_THROUGH;
+
+        case ACCEPT_FINISHED_DONE :
+            if (ssl->options.resuming)
+                while (ssl->options.clientState < CLIENT_FINISHED_COMPLETE)
+                    if ( (ssl->error = ProcessReply(ssl)) < 0) {
+                        WOLFSSL_ERROR(ssl->error);
+                        return WOLFSSL_FATAL_ERROR;
+                    }
+
+            ssl->options.acceptState = ACCEPT_THIRD_REPLY_DONE;
+            WOLFSSL_MSG("accept state ACCEPT_THIRD_REPLY_DONE");
+            FALL_THROUGH;
+
+        case ACCEPT_THIRD_REPLY_DONE :
+#ifndef NO_HANDSHAKE_DONE_CB
+            if (ssl->hsDoneCb) {
+                int cbret = ssl->hsDoneCb(ssl, ssl->hsDoneCtx);
+                if (cbret < 0) {
+                    ssl->error = cbret;
+                    WOLFSSL_MSG("HandShake Done Cb don't continue error");
+                    return WOLFSSL_FATAL_ERROR;
+                }
+            }
+#endif /* NO_HANDSHAKE_DONE_CB */
+
+            if (!ssl->options.dtls) {
+                if (!ssl->options.keepResources) {
+                    FreeHandshakeResources(ssl);
+                }
+            }
+#ifdef WOLFSSL_DTLS
+            else {
+                ssl->options.dtlsHsRetain = 1;
+            }
+#endif /* WOLFSSL_DTLS */
+
+#ifdef WOLFSSL_SESSION_EXPORT
+            if (ssl->dtls_export) {
+                if ((ssl->error = wolfSSL_send_session(ssl)) != 0) {
+                    WOLFSSL_MSG("Export DTLS session error");
+                    WOLFSSL_ERROR(ssl->error);
+                    return WOLFSSL_FATAL_ERROR;
+                }
+            }
+#endif
+
+            WOLFSSL_LEAVE("SSL_accept()", WOLFSSL_SUCCESS);
+            return WOLFSSL_SUCCESS;
+
+        default :
+            WOLFSSL_MSG("Unknown accept state ERROR");
+            return WOLFSSL_FATAL_ERROR;
+        }
+#endif /* !WOLFSSL_NO_TLS12 */
+    }
+
+#endif /* NO_WOLFSSL_SERVER */
+
+
+#ifndef NO_HANDSHAKE_DONE_CB
+
+int wolfSSL_SetHsDoneCb(WOLFSSL* ssl, HandShakeDoneCb cb, void* user_ctx)
+{
+    WOLFSSL_ENTER("wolfSSL_SetHsDoneCb");
+
+    if (ssl == NULL)
+        return BAD_FUNC_ARG;
+
+    ssl->hsDoneCb  = cb;
+    ssl->hsDoneCtx = user_ctx;
+
+
+    return WOLFSSL_SUCCESS;
+}
+
+#endif /* NO_HANDSHAKE_DONE_CB */
+
+WOLFSSL_ABI
+int wolfSSL_Cleanup(void)
+{
+    int ret = WOLFSSL_SUCCESS;
+    int release = 0;
+
+    WOLFSSL_ENTER("wolfSSL_Cleanup");
+
+    if (initRefCount == 0)
+        return ret;  /* possibly no init yet, but not failure either way */
+
+    if (wc_LockMutex(&count_mutex) != 0) {
+        WOLFSSL_MSG("Bad Lock Mutex count");
+        return BAD_MUTEX_E;
+    }
+
+    release = initRefCount-- == 1;
+    if (initRefCount < 0)
+        initRefCount = 0;
+
+    wc_UnLockMutex(&count_mutex);
+
+    if (!release)
+        return ret;
+
+#ifdef OPENSSL_EXTRA
+    if (bn_one) {
+        wolfSSL_BN_free(bn_one);
+        bn_one = NULL;
+    }
+#endif
+
+#ifndef NO_SESSION_CACHE
+    if (wc_FreeMutex(&session_mutex) != 0)
+        ret = BAD_MUTEX_E;
+#endif
+    if (wc_FreeMutex(&count_mutex) != 0)
+        ret = BAD_MUTEX_E;
+
+#ifdef OPENSSL_EXTRA
+    wolfSSL_RAND_Cleanup();
+#endif
+
+    if (wolfCrypt_Cleanup() != 0) {
+        WOLFSSL_MSG("Error with wolfCrypt_Cleanup call");
+        ret = WC_CLEANUP_E;
+    }
+
+    return ret;
+}
+
+
+#ifndef NO_SESSION_CACHE
+
+
+/* some session IDs aren't random after all, let's make them random */
+static WC_INLINE word32 HashSession(const byte* sessionID, word32 len, int* error)
+{
+    byte digest[WC_MAX_DIGEST_SIZE];
+
+#ifndef NO_MD5
+    *error =  wc_Md5Hash(sessionID, len, digest);
+#elif !defined(NO_SHA)
+    *error =  wc_ShaHash(sessionID, len, digest);
+#elif !defined(NO_SHA256)
+    *error =  wc_Sha256Hash(sessionID, len, digest);
+#else
+    #error "We need a digest to hash the session IDs"
+#endif
+
+    return *error == 0 ? MakeWordFromHash(digest) : 0; /* 0 on failure */
+}
+
+
+WOLFSSL_ABI
+void wolfSSL_flush_sessions(WOLFSSL_CTX* ctx, long tm)
+{
+    /* static table now, no flushing needed */
+    (void)ctx;
+    (void)tm;
+}
+
+
+/* set ssl session timeout in seconds */
+WOLFSSL_ABI
+int wolfSSL_set_timeout(WOLFSSL* ssl, unsigned int to)
+{
+    if (ssl == NULL)
+        return BAD_FUNC_ARG;
+
+    if (to == 0)
+        to = WOLFSSL_SESSION_TIMEOUT;
+    ssl->timeout = to;
+
+    return WOLFSSL_SUCCESS;
+}
+
+
+/* set ctx session timeout in seconds */
+WOLFSSL_ABI
+int wolfSSL_CTX_set_timeout(WOLFSSL_CTX* ctx, unsigned int to)
+{
+    if (ctx == NULL)
+        return BAD_FUNC_ARG;
+
+    if (to == 0)
+        to = WOLFSSL_SESSION_TIMEOUT;
+    ctx->timeout = to;
+
+    return WOLFSSL_SUCCESS;
+}
+
+
+#ifndef NO_CLIENT_CACHE
+
+/* Get Session from Client cache based on id/len, return NULL on failure */
+WOLFSSL_SESSION* GetSessionClient(WOLFSSL* ssl, const byte* id, int len)
+{
+    WOLFSSL_SESSION* ret = NULL;
+    word32          row;
+    int             idx;
+    int             count;
+    int             error = 0;
+
+    WOLFSSL_ENTER("GetSessionClient");
+
+    if (ssl->ctx->sessionCacheOff)
+        return NULL;
+
+    if (ssl->options.side == WOLFSSL_SERVER_END)
+        return NULL;
+
+    len = min(SERVER_ID_LEN, (word32)len);
+
+#ifdef HAVE_EXT_CACHE
+    if (ssl->ctx->get_sess_cb != NULL) {
+        int copy = 0;
+        ret = ssl->ctx->get_sess_cb(ssl, (byte*)id, len, &copy);
+        if (ret != NULL)
+            return ret;
+    }
+
+    if (ssl->ctx->internalCacheOff)
+        return NULL;
+#endif
+
+    row = HashSession(id, len, &error) % SESSION_ROWS;
+    if (error != 0) {
+        WOLFSSL_MSG("Hash session failed");
+        return NULL;
+    }
+
+    if (wc_LockMutex(&session_mutex) != 0) {
+        WOLFSSL_MSG("Lock session mutex failed");
+        return NULL;
+    }
+
+    /* start from most recently used */
+    count = min((word32)ClientCache[row].totalCount, SESSIONS_PER_ROW);
+    idx = ClientCache[row].nextIdx - 1;
+    if (idx < 0)
+        idx = SESSIONS_PER_ROW - 1; /* if back to front, the previous was end */
+
+    for (; count > 0; --count, idx = idx ? idx - 1 : SESSIONS_PER_ROW - 1) {
+        WOLFSSL_SESSION* current;
+        ClientSession   clSess;
+
+        if (idx >= SESSIONS_PER_ROW || idx < 0) { /* sanity check */
+            WOLFSSL_MSG("Bad idx");
+            break;
+        }
+
+        clSess = ClientCache[row].Clients[idx];
+
+        current = &SessionCache[clSess.serverRow].Sessions[clSess.serverIdx];
+        if (XMEMCMP(current->serverID, id, len) == 0) {
+            WOLFSSL_MSG("Found a serverid match for client");
+            if (LowResTimer() < (current->bornOn + current->timeout)) {
+                WOLFSSL_MSG("Session valid");
+                ret = current;
+                break;
+            } else {
+                WOLFSSL_MSG("Session timed out");  /* could have more for id */
+            }
+        } else {
+            WOLFSSL_MSG("ServerID not a match from client table");
+        }
+    }
+
+    wc_UnLockMutex(&session_mutex);
+
+    return ret;
+}
+
+#endif /* NO_CLIENT_CACHE */
+
+/* Restore the master secret and session information for certificates.
+ *
+ * ssl                  The SSL/TLS object.
+ * session              The cached session to restore.
+ * masterSecret         The master secret from the cached session.
+ * restoreSessionCerts  Restoring session certificates is required.
+ */
+static WC_INLINE void RestoreSession(WOLFSSL* ssl, WOLFSSL_SESSION* session,
+        byte* masterSecret, byte restoreSessionCerts)
+{
+    (void)ssl;
+    (void)restoreSessionCerts;
+
+    if (masterSecret)
+        XMEMCPY(masterSecret, session->masterSecret, SECRET_LEN);
+#ifdef SESSION_CERTS
+    /* If set, we should copy the session certs into the ssl object
+     * from the session we are returning so we can resume */
+    if (restoreSessionCerts) {
+        ssl->session.chain        = session->chain;
+        ssl->session.version      = session->version;
+    #ifdef NO_RESUME_SUITE_CHECK
+        ssl->session.cipherSuite0 = session->cipherSuite0;
+        ssl->session.cipherSuite  = session->cipherSuite;
+    #endif
+    }
+#endif /* SESSION_CERTS */
+#if !defined(NO_RESUME_SUITE_CHECK) || \
+                        (defined(WOLFSSL_TLS13) && defined(HAVE_SESSION_TICKET))
+    ssl->session.cipherSuite0 = session->cipherSuite0;
+    ssl->session.cipherSuite  = session->cipherSuite;
+#endif
+}
+
+WOLFSSL_SESSION* GetSession(WOLFSSL* ssl, byte* masterSecret,
+        byte restoreSessionCerts)
+{
+    WOLFSSL_SESSION* ret = 0;
+    const byte*  id = NULL;
+    word32       row;
+    int          idx;
+    int          count;
+    int          error = 0;
+
+    (void)       restoreSessionCerts;
+
+    if (ssl->options.sessionCacheOff)
+        return NULL;
+
+    if (ssl->options.haveSessionId == 0)
+        return NULL;
+
+#ifdef HAVE_SESSION_TICKET
+    if (ssl->options.side == WOLFSSL_SERVER_END && ssl->options.useTicket == 1)
+        return NULL;
+#endif
+
+    if (!ssl->options.tls1_3 && ssl->arrays != NULL)
+        id = ssl->arrays->sessionID;
+    else
+        id = ssl->session.sessionID;
+
+#ifdef HAVE_EXT_CACHE
+    if (ssl->ctx->get_sess_cb != NULL) {
+        int copy = 0;
+        /* Attempt to retrieve the session from the external cache. */
+        ret = ssl->ctx->get_sess_cb(ssl, (byte*)id, ID_LEN, &copy);
+        if (ret != NULL) {
+            RestoreSession(ssl, ret, masterSecret, restoreSessionCerts);
+            return ret;
+        }
+    }
+
+    if (ssl->ctx->internalCacheOff)
+        return NULL;
+#endif
+
+    row = HashSession(id, ID_LEN, &error) % SESSION_ROWS;
+    if (error != 0) {
+        WOLFSSL_MSG("Hash session failed");
+        return NULL;
+    }
+
+    if (wc_LockMutex(&session_mutex) != 0)
+        return 0;
+
+    /* start from most recently used */
+    count = min((word32)SessionCache[row].totalCount, SESSIONS_PER_ROW);
+    idx = SessionCache[row].nextIdx - 1;
+    if (idx < 0)
+        idx = SESSIONS_PER_ROW - 1; /* if back to front, the previous was end */
+
+    for (; count > 0; --count, idx = idx ? idx - 1 : SESSIONS_PER_ROW - 1) {
+        WOLFSSL_SESSION* current;
+
+        if (idx >= SESSIONS_PER_ROW || idx < 0) { /* sanity check */
+            WOLFSSL_MSG("Bad idx");
+            break;
+        }
+
+        current = &SessionCache[row].Sessions[idx];
+        if (XMEMCMP(current->sessionID, id, ID_LEN) == 0) {
+            WOLFSSL_MSG("Found a session match");
+            if (LowResTimer() < (current->bornOn + current->timeout)) {
+                WOLFSSL_MSG("Session valid");
+                ret = current;
+                RestoreSession(ssl, ret, masterSecret, restoreSessionCerts);
+            } else {
+                WOLFSSL_MSG("Session timed out");
+            }
+            break;  /* no more sessionIDs whether valid or not that match */
+        } else {
+            WOLFSSL_MSG("SessionID not a match at this idx");
+        }
+    }
+
+    wc_UnLockMutex(&session_mutex);
+
+    return ret;
+}
+
+
+static int GetDeepCopySession(WOLFSSL* ssl, WOLFSSL_SESSION* copyFrom)
+{
+    WOLFSSL_SESSION* copyInto = &ssl->session;
+    void* tmpBuff             = NULL;
+    int ticketLen             = 0;
+    int doDynamicCopy         = 0;
+    int ret                   = WOLFSSL_SUCCESS;
+
+    (void)ticketLen;
+    (void)doDynamicCopy;
+    (void)tmpBuff;
+
+    if (!ssl || !copyFrom)
+        return BAD_FUNC_ARG;
+
+#ifdef HAVE_SESSION_TICKET
+    /* Free old dynamic ticket if we had one to avoid leak */
+    if (copyInto->isDynamic) {
+        XFREE(copyInto->ticket, ssl->heap, DYNAMIC_TYPE_SESSION_TICK);
+        copyInto->ticket = copyInto->staticTicket;
+        copyInto->isDynamic = 0;
+    }
+#endif
+
+    if (wc_LockMutex(&session_mutex) != 0)
+        return BAD_MUTEX_E;
+
+#ifdef HAVE_SESSION_TICKET
+    /* Size of ticket to alloc if needed; Use later for alloc outside lock */
+    doDynamicCopy = copyFrom->isDynamic;
+    ticketLen = copyFrom->ticketLen;
+#endif
+
+    *copyInto = *copyFrom;
+
+    /* Default ticket to non dynamic. This will avoid crash if we fail below */
+#ifdef HAVE_SESSION_TICKET
+    copyInto->ticket = copyInto->staticTicket;
+    copyInto->isDynamic = 0;
+#endif
+
+#ifndef NO_RESUME_SUITE_CHECK
+    copyInto->cipherSuite0   = copyFrom->cipherSuite0;
+    copyInto->cipherSuite    = copyFrom->cipherSuite;
+#endif
+
+    if (wc_UnLockMutex(&session_mutex) != 0) {
+        return BAD_MUTEX_E;
+    }
+
+#ifdef HAVE_SESSION_TICKET
+#ifdef WOLFSSL_TLS13
+    if (wc_LockMutex(&session_mutex) != 0) {
+        XFREE(tmpBuff, ssl->heap, DYNAMIC_TYPE_SESSION_TICK);
+        return BAD_MUTEX_E;
+    }
+
+#ifdef NO_RESUME_SUITE_CHECK
+    copyInto->cipherSuite0   = copyFrom->cipherSuite0;
+    copyInto->cipherSuite    = copyFrom->cipherSuite;
+#endif
+    copyInto->namedGroup     = copyFrom->namedGroup;
+    copyInto->ticketSeen     = copyFrom->ticketSeen;
+    copyInto->ticketAdd      = copyFrom->ticketAdd;
+#ifndef WOLFSSL_TLS13_DRAFT_18
+    XMEMCPY(&copyInto->ticketNonce, &copyFrom->ticketNonce,
+                                                           sizeof(TicketNonce));
+#endif
+#ifdef WOLFSSL_EARLY_DATA
+    copyInto->maxEarlyDataSz = copyFrom->maxEarlyDataSz;
+#endif
+    XMEMCPY(copyInto->masterSecret, copyFrom->masterSecret, SECRET_LEN);
+
+    if (wc_UnLockMutex(&session_mutex) != 0) {
+        if (ret == WOLFSSL_SUCCESS)
+            ret = BAD_MUTEX_E;
+    }
+#endif
+    /* If doing dynamic copy, need to alloc outside lock, then inside a lock
+     * confirm the size still matches and memcpy */
+    if (doDynamicCopy) {
+        tmpBuff = (byte*)XMALLOC(ticketLen, ssl->heap,
+                                                     DYNAMIC_TYPE_SESSION_TICK);
+        if (!tmpBuff)
+            return MEMORY_ERROR;
+
+        if (wc_LockMutex(&session_mutex) != 0) {
+            XFREE(tmpBuff, ssl->heap, DYNAMIC_TYPE_SESSION_TICK);
+            return BAD_MUTEX_E;
+        }
+
+        if ((word16)ticketLen != copyFrom->ticketLen) {
+            /* Another thread modified the ssl-> session ticket during alloc.
+             * Treat as error, since ticket different than when copy requested */
+            ret = VAR_STATE_CHANGE_E;
+        }
+
+        if (ret == WOLFSSL_SUCCESS) {
+            copyInto->ticket = (byte*)tmpBuff;
+            copyInto->isDynamic = 1;
+            XMEMCPY(copyInto->ticket, copyFrom->ticket, ticketLen);
+        }
+    } else {
+        /* Need to ensure ticket pointer gets updated to own buffer
+         * and is not pointing to buff of session copied from */
+        copyInto->ticket = copyInto->staticTicket;
+    }
+
+    if (doDynamicCopy) {
+        if (wc_UnLockMutex(&session_mutex) != 0) {
+            if (ret == WOLFSSL_SUCCESS)
+                ret = BAD_MUTEX_E;
+        }
+    }
+
+    if (ret != WOLFSSL_SUCCESS) {
+        /* cleanup */
+        if (tmpBuff)
+            XFREE(tmpBuff, ssl->heap, DYNAMIC_TYPE_SESSION_TICK);
+        copyInto->ticket = copyInto->staticTicket;
+        copyInto->isDynamic = 0;
+    }
+#endif /* HAVE_SESSION_TICKET */
+    return ret;
+}
+
+
+int SetSession(WOLFSSL* ssl, WOLFSSL_SESSION* session)
+{
+    if (ssl->options.sessionCacheOff)
+        return WOLFSSL_FAILURE;
+
+#ifdef OPENSSL_EXTRA
+    /* check for application context id */
+    if (ssl->sessionCtxSz > 0) {
+        if (XMEMCMP(ssl->sessionCtx, session->sessionCtx, ssl->sessionCtxSz)) {
+            /* context id did not match! */
+            WOLFSSL_MSG("Session context did not match");
+            return SSL_FAILURE;
+        }
+    }
+#endif /* OPENSSL_EXTRA */
+
+    if (LowResTimer() < (session->bornOn + session->timeout)) {
+        int ret = GetDeepCopySession(ssl, session);
+        if (ret == WOLFSSL_SUCCESS) {
+            ssl->options.resuming = 1;
+
+#if defined(SESSION_CERTS) || (defined(WOLFSSL_TLS13) && \
+                               defined(HAVE_SESSION_TICKET))
+            ssl->version              = session->version;
+#endif
+#if defined(SESSION_CERTS) || !defined(NO_RESUME_SUITE_CHECK) || \
+                        (defined(WOLFSSL_TLS13) && defined(HAVE_SESSION_TICKET))
+            ssl->options.cipherSuite0 = session->cipherSuite0;
+            ssl->options.cipherSuite  = session->cipherSuite;
+#endif
+        }
+
+        return ret;
+    }
+    return WOLFSSL_FAILURE;  /* session timed out */
+}
+
+
+#ifdef WOLFSSL_SESSION_STATS
+static int get_locked_session_stats(word32* active, word32* total,
+                                    word32* peak);
+#endif
+
+int AddSession(WOLFSSL* ssl)
+{
+    word32 row = 0;
+    word32 idx = 0;
+    int    error = 0;
+#ifdef HAVE_SESSION_TICKET
+    byte*  tmpBuff = NULL;
+    int    ticLen  = 0;
+#endif
+    WOLFSSL_SESSION* session;
+    int i;
+    int overwrite = 0;
+
+    if (ssl->options.sessionCacheOff)
+        return 0;
+
+    if (ssl->options.haveSessionId == 0)
+        return 0;
+
+#ifdef HAVE_SESSION_TICKET
+    if (ssl->options.side == WOLFSSL_SERVER_END && ssl->options.useTicket == 1)
+        return 0;
+#endif
+
+#ifdef HAVE_SESSION_TICKET
+    ticLen = ssl->session.ticketLen;
+    /* Alloc Memory here so if Malloc fails can exit outside of lock */
+    if(ticLen > SESSION_TICKET_LEN) {
+        tmpBuff = (byte*)XMALLOC(ticLen, ssl->heap,
+                DYNAMIC_TYPE_SESSION_TICK);
+        if(!tmpBuff)
+            return MEMORY_E;
+    }
+#endif
+
+#ifdef HAVE_EXT_CACHE
+    if (ssl->options.internalCacheOff) {
+        /* Create a new session object to be stored. */
+        session = (WOLFSSL_SESSION*)XMALLOC(sizeof(WOLFSSL_SESSION), NULL,
+                                            DYNAMIC_TYPE_OPENSSL);
+        if (session == NULL) {
+#ifdef HAVE_SESSION_TICKET
+            XFREE(tmpBuff, ssl->heap, DYNAMIC_TYPE_SESSION_TICK);
+#endif
+            return MEMORY_E;
+        }
+        XMEMSET(session, 0, sizeof(WOLFSSL_SESSION));
+        session->isAlloced = 1;
+    }
+    else
+#endif
+    {
+        /* Use the session object in the cache for external cache if required.
+         */
+#if defined(WOLFSSL_TLS13) && defined(HAVE_SESSION_TICKET)
+        if (ssl->options.tls1_3) {
+            row = HashSession(ssl->session.sessionID, ID_LEN, &error) %
+                    SESSION_ROWS;
+        }
+        else
+#endif
+        {
+            row = HashSession(ssl->arrays->sessionID, ID_LEN, &error) %
+                    SESSION_ROWS;
+        }
+        if (error != 0) {
+            WOLFSSL_MSG("Hash session failed");
+#ifdef HAVE_SESSION_TICKET
+            XFREE(tmpBuff, ssl->heap, DYNAMIC_TYPE_SESSION_TICK);
+#endif
+            return error;
+        }
+
+        if (wc_LockMutex(&session_mutex) != 0) {
+#ifdef HAVE_SESSION_TICKET
+            XFREE(tmpBuff, ssl->heap, DYNAMIC_TYPE_SESSION_TICK);
+#endif
+            return BAD_MUTEX_E;
+        }
+
+        for (i=0; i<SESSIONS_PER_ROW; i++) {
+            if (ssl->options.tls1_3) {
+                if (XMEMCMP(ssl->session.sessionID, SessionCache[row].Sessions[i].sessionID, ID_LEN) == 0) {
+                    WOLFSSL_MSG("Session already exists. Overwriting.");
+                    overwrite = 1;
+                    idx = i;
+                    break;
+                }
+            }
+            else {
+                if (XMEMCMP(ssl->arrays->sessionID, SessionCache[row].Sessions[i].sessionID, ID_LEN) == 0) {
+                    WOLFSSL_MSG("Session already exists. Overwriting.");
+                    overwrite = 1;
+                    idx = i;
+                    break;
+                }
+            }
+        }
+
+        if (!overwrite) {
+            idx = SessionCache[row].nextIdx++;
+        }
+#ifdef SESSION_INDEX
+        ssl->sessionIndex = (row << SESSIDX_ROW_SHIFT) | idx;
+#endif
+        session = &SessionCache[row].Sessions[idx];
+    }
+
+    if (!ssl->options.tls1_3)
+        XMEMCPY(session->masterSecret, ssl->arrays->masterSecret, SECRET_LEN);
+    else
+        XMEMCPY(session->masterSecret, ssl->session.masterSecret, SECRET_LEN);
+    session->haveEMS = ssl->options.haveEMS;
+#if defined(WOLFSSL_TLS13) && defined(HAVE_SESSION_TICKET)
+    if (ssl->options.tls1_3) {
+        XMEMCPY(session->sessionID, ssl->session.sessionID, ID_LEN);
+        session->sessionIDSz = ID_LEN;
+    }
+    else
+#endif
+    {
+        XMEMCPY(session->sessionID, ssl->arrays->sessionID, ID_LEN);
+        session->sessionIDSz = ssl->arrays->sessionIDSz;
+    }
+
+#ifdef OPENSSL_EXTRA
+    /* If using compatibility layer then check for and copy over session context
+     * id. */
+    if (ssl->sessionCtxSz > 0 && ssl->sessionCtxSz < ID_LEN) {
+        XMEMCPY(session->sessionCtx, ssl->sessionCtx, ssl->sessionCtxSz);
+    }
+#endif
+
+    session->timeout = ssl->timeout;
+    session->bornOn  = LowResTimer();
+
+#ifdef HAVE_SESSION_TICKET
+    /* Check if another thread modified ticket since alloc */
+    if ((word16)ticLen != ssl->session.ticketLen) {
+        error = VAR_STATE_CHANGE_E;
+    }
+
+    if (error == 0) {
+        /* Cleanup cache row's old Dynamic buff if exists */
+        if(session->isDynamic) {
+            XFREE(session->ticket, ssl->heap, DYNAMIC_TYPE_SESSION_TICK);
+            session->ticket = NULL;
+        }
+
+        /* If too large to store in static buffer, use dyn buffer */
+        if (ticLen > SESSION_TICKET_LEN) {
+            session->ticket = tmpBuff;
+            session->isDynamic = 1;
+        } else {
+            session->ticket = session->staticTicket;
+            session->isDynamic = 0;
+        }
+
+        session->ticketLen = (word16)ticLen;
+        XMEMCPY(session->ticket, ssl->session.ticket, ticLen);
+    } else { /* cleanup, reset state */
+        session->ticket    = session->staticTicket;
+        session->isDynamic = 0;
+        session->ticketLen = 0;
+        if (tmpBuff) {
+            XFREE(tmpBuff, ssl->heap, DYNAMIC_TYPE_SESSION_TICK);
+            tmpBuff = NULL;
+        }
+    }
+#endif
+
+#ifdef SESSION_CERTS
+    if (error == 0) {
+        if (!overwrite || ssl->session.chain.count > 0) {
+            /*
+             * If we are overwriting and no certs present in ssl->session.chain
+             * then keep the old chain.
+             */
+            session->chain.count = ssl->session.chain.count;
+            XMEMCPY(session->chain.certs, ssl->session.chain.certs,
+                    sizeof(x509_buffer) * session->chain.count);
+        }
+    }
+#endif /* SESSION_CERTS */
+#if defined(SESSION_CERTS) || (defined(WOLFSSL_TLS13) && \
+                               defined(HAVE_SESSION_TICKET))
+    if (error == 0) {
+        session->version      = ssl->version;
+    }
+#endif /* SESSION_CERTS || (WOLFSSL_TLS13 & HAVE_SESSION_TICKET) */
+#if defined(SESSION_CERTS) || !defined(NO_RESUME_SUITE_CHECK) || \
+                        (defined(WOLFSSL_TLS13) && defined(HAVE_SESSION_TICKET))
+    if (error == 0) {
+        session->cipherSuite0 = ssl->options.cipherSuite0;
+        session->cipherSuite  = ssl->options.cipherSuite;
+    }
+#endif
+#if defined(WOLFSSL_TLS13)
+    if (error == 0) {
+        session->namedGroup     = ssl->session.namedGroup;
+    }
+#endif
+#if defined(WOLFSSL_TLS13) && defined(HAVE_SESSION_TICKET)
+    if (error == 0) {
+        session->ticketSeen     = ssl->session.ticketSeen;
+        session->ticketAdd      = ssl->session.ticketAdd;
+#ifndef WOLFSSL_TLS13_DRAFT_18
+        XMEMCPY(&session->ticketNonce, &ssl->session.ticketNonce,
+                                                           sizeof(TicketNonce));
+#endif
+    #ifdef WOLFSSL_EARLY_DATA
+        session->maxEarlyDataSz = ssl->session.maxEarlyDataSz;
+    #endif
+    }
+#endif /* WOLFSSL_TLS13 && HAVE_SESSION_TICKET */
+#ifdef HAVE_EXT_CACHE
+    if (!ssl->options.internalCacheOff)
+#endif
+    {
+        if (error == 0) {
+            SessionCache[row].totalCount++;
+            if (SessionCache[row].nextIdx == SESSIONS_PER_ROW)
+                SessionCache[row].nextIdx = 0;
+        }
+    }
+#ifndef NO_CLIENT_CACHE
+    if (error == 0) {
+        if (ssl->options.side == WOLFSSL_CLIENT_END && ssl->session.idLen) {
+            word32 clientRow, clientIdx;
+
+            WOLFSSL_MSG("Adding client cache entry");
+
+            session->idLen = ssl->session.idLen;
+            XMEMCPY(session->serverID, ssl->session.serverID,
+                    ssl->session.idLen);
+
+#ifdef HAVE_EXT_CACHE
+            if (!ssl->options.internalCacheOff)
+#endif
+            {
+                clientRow = HashSession(ssl->session.serverID,
+                        ssl->session.idLen, &error) % SESSION_ROWS;
+                if (error != 0) {
+                    WOLFSSL_MSG("Hash session failed");
+                } else {
+                    clientIdx = ClientCache[clientRow].nextIdx++;
+
+                    ClientCache[clientRow].Clients[clientIdx].serverRow =
+                                                                   (word16)row;
+                    ClientCache[clientRow].Clients[clientIdx].serverIdx =
+                                                                   (word16)idx;
+
+                    ClientCache[clientRow].totalCount++;
+                    if (ClientCache[clientRow].nextIdx == SESSIONS_PER_ROW)
+                        ClientCache[clientRow].nextIdx = 0;
+                }
+            }
+        }
+        else
+            session->idLen = 0;
+    }
+#endif /* NO_CLIENT_CACHE */
+
+#if defined(WOLFSSL_SESSION_STATS) && defined(WOLFSSL_PEAK_SESSIONS)
+#ifdef HAVE_EXT_CACHE
+    if (!ssl->options.internalCacheOff)
+#endif
+    {
+        if (error == 0) {
+            word32 active = 0;
+
+            error = get_locked_session_stats(&active, NULL, NULL);
+            if (error == WOLFSSL_SUCCESS) {
+                error = 0;  /* back to this function ok */
+
+                if (active > PeakSessions)
+                    PeakSessions = active;
+            }
+        }
+    }
+#endif /* defined(WOLFSSL_SESSION_STATS) && defined(WOLFSSL_PEAK_SESSIONS) */
+
+#ifdef HAVE_EXT_CACHE
+    if (!ssl->options.internalCacheOff)
+#endif
+    {
+        if (wc_UnLockMutex(&session_mutex) != 0)
+            return BAD_MUTEX_E;
+    }
+
+#ifdef HAVE_EXT_CACHE
+    if (error == 0 && ssl->ctx->new_sess_cb != NULL)
+        ssl->ctx->new_sess_cb(ssl, session);
+    if (ssl->options.internalCacheOff)
+        wolfSSL_SESSION_free(session);
+#endif
+
+    return error;
+}
+
+
+#ifdef SESSION_INDEX
+
+int wolfSSL_GetSessionIndex(WOLFSSL* ssl)
+{
+    WOLFSSL_ENTER("wolfSSL_GetSessionIndex");
+    WOLFSSL_LEAVE("wolfSSL_GetSessionIndex", ssl->sessionIndex);
+    return ssl->sessionIndex;
+}
+
+
+int wolfSSL_GetSessionAtIndex(int idx, WOLFSSL_SESSION* session)
+{
+    int row, col, result = WOLFSSL_FAILURE;
+
+    WOLFSSL_ENTER("wolfSSL_GetSessionAtIndex");
+
+    row = idx >> SESSIDX_ROW_SHIFT;
+    col = idx & SESSIDX_IDX_MASK;
+
+    if (wc_LockMutex(&session_mutex) != 0) {
+        return BAD_MUTEX_E;
+    }
+
+    if (row < SESSION_ROWS &&
+        col < (int)min(SessionCache[row].totalCount, SESSIONS_PER_ROW)) {
+        XMEMCPY(session,
+                 &SessionCache[row].Sessions[col], sizeof(WOLFSSL_SESSION));
+        result = WOLFSSL_SUCCESS;
+    }
+
+    if (wc_UnLockMutex(&session_mutex) != 0)
+        result = BAD_MUTEX_E;
+
+    WOLFSSL_LEAVE("wolfSSL_GetSessionAtIndex", result);
+    return result;
+}
+
+#endif /* SESSION_INDEX */
+
+#if defined(SESSION_CERTS)
+
+WOLFSSL_X509_CHAIN* wolfSSL_SESSION_get_peer_chain(WOLFSSL_SESSION* session)
+{
+    WOLFSSL_X509_CHAIN* chain = NULL;
+
+    WOLFSSL_ENTER("wolfSSL_SESSION_get_peer_chain");
+    if (session)
+        chain = &session->chain;
+
+    WOLFSSL_LEAVE("wolfSSL_SESSION_get_peer_chain", chain ? 1 : 0);
+    return chain;
+}
+
+
+#ifdef OPENSSL_EXTRA
+/* gets the peer certificate associated with the session passed in
+ * returns null on failure, the caller should not free the returned pointer */
+WOLFSSL_X509* wolfSSL_SESSION_get0_peer(WOLFSSL_SESSION* session)
+{
+    WOLFSSL_ENTER("wolfSSL_SESSION_get_peer_chain");
+    if (session) {
+        int count;
+
+        count = wolfSSL_get_chain_count(&session->chain);
+        if (count < 1 || count >= MAX_CHAIN_DEPTH) {
+            WOLFSSL_MSG("bad count found");
+            return NULL;
+        }
+
+        if (session->peer == NULL) {
+            session->peer = wolfSSL_get_chain_X509(&session->chain, 0);
+        }
+        return session->peer;
+    }
+    WOLFSSL_MSG("No session passed in");
+
+    return NULL;
+}
+#endif /* OPENSSL_EXTRA */
+#endif /* SESSION_INDEX && SESSION_CERTS */
+
+
+#ifdef WOLFSSL_SESSION_STATS
+
+/* requires session_mutex lock held, WOLFSSL_SUCCESS on ok */
+static int get_locked_session_stats(word32* active, word32* total, word32* peak)
+{
+    int result = WOLFSSL_SUCCESS;
+    int i;
+    int count;
+    int idx;
+    word32 now   = 0;
+    word32 seen  = 0;
+    word32 ticks = LowResTimer();
+
+    (void)peak;
+
+    WOLFSSL_ENTER("get_locked_session_stats");
+
+    for (i = 0; i < SESSION_ROWS; i++) {
+        seen += SessionCache[i].totalCount;
+
+        if (active == NULL)
+            continue;  /* no need to calculate what we can't set */
+
+        count = min((word32)SessionCache[i].totalCount, SESSIONS_PER_ROW);
+        idx   = SessionCache[i].nextIdx - 1;
+        if (idx < 0)
+            idx = SESSIONS_PER_ROW - 1; /* if back to front previous was end */
+
+        for (; count > 0; --count, idx = idx ? idx - 1 : SESSIONS_PER_ROW - 1) {
+            if (idx >= SESSIONS_PER_ROW || idx < 0) {  /* sanity check */
+                WOLFSSL_MSG("Bad idx");
+                break;
+            }
+
+            /* if not expired then good */
+            if (ticks < (SessionCache[i].Sessions[idx].bornOn +
+                         SessionCache[i].Sessions[idx].timeout) ) {
+                now++;
+            }
+        }
+    }
+
+    if (active)
+        *active = now;
+
+    if (total)
+        *total = seen;
+
+#ifdef WOLFSSL_PEAK_SESSIONS
+    if (peak)
+        *peak = PeakSessions;
+#endif
+
+    WOLFSSL_LEAVE("get_locked_session_stats", result);
+
+    return result;
+}
+
+
+/* return WOLFSSL_SUCCESS on ok */
+int wolfSSL_get_session_stats(word32* active, word32* total, word32* peak,
+                              word32* maxSessions)
+{
+    int result = WOLFSSL_SUCCESS;
+
+    WOLFSSL_ENTER("wolfSSL_get_session_stats");
+
+    if (maxSessions) {
+        *maxSessions = SESSIONS_PER_ROW * SESSION_ROWS;
+
+        if (active == NULL && total == NULL && peak == NULL)
+            return result;  /* we're done */
+    }
+
+    /* user must provide at least one query value */
+    if (active == NULL && total == NULL && peak == NULL)
+        return BAD_FUNC_ARG;
+
+    if (wc_LockMutex(&session_mutex) != 0) {
+        return BAD_MUTEX_E;
+    }
+
+    result = get_locked_session_stats(active, total, peak);
+
+    if (wc_UnLockMutex(&session_mutex) != 0)
+        result = BAD_MUTEX_E;
+
+    WOLFSSL_LEAVE("wolfSSL_get_session_stats", result);
+
+    return result;
+}
+
+#endif /* WOLFSSL_SESSION_STATS */
+
+
+    #ifdef PRINT_SESSION_STATS
+
+    /* WOLFSSL_SUCCESS on ok */
+    int wolfSSL_PrintSessionStats(void)
+    {
+        word32 totalSessionsSeen = 0;
+        word32 totalSessionsNow = 0;
+        word32 peak = 0;
+        word32 maxSessions = 0;
+        int    i;
+        int    ret;
+        double E;               /* expected freq */
+        double chiSquare = 0;
+
+        ret = wolfSSL_get_session_stats(&totalSessionsNow, &totalSessionsSeen,
+                                        &peak, &maxSessions);
+        if (ret != WOLFSSL_SUCCESS)
+            return ret;
+        printf("Total Sessions Seen = %d\n", totalSessionsSeen);
+        printf("Total Sessions Now  = %d\n", totalSessionsNow);
+#ifdef WOLFSSL_PEAK_SESSIONS
+        printf("Peak  Sessions      = %d\n", peak);
+#endif
+        printf("Max   Sessions      = %d\n", maxSessions);
+
+        E = (double)totalSessionsSeen / SESSION_ROWS;
+
+        for (i = 0; i < SESSION_ROWS; i++) {
+            double diff = SessionCache[i].totalCount - E;
+            diff *= diff;                /* square    */
+            diff /= E;                   /* normalize */
+
+            chiSquare += diff;
+        }
+        printf("  chi-square = %5.1f, d.f. = %d\n", chiSquare,
+                                                     SESSION_ROWS - 1);
+        #if (SESSION_ROWS == 11)
+            printf(" .05 p value =  18.3, chi-square should be less\n");
+        #elif (SESSION_ROWS == 211)
+            printf(".05 p value  = 244.8, chi-square should be less\n");
+        #elif (SESSION_ROWS == 5981)
+            printf(".05 p value  = 6161.0, chi-square should be less\n");
+        #elif (SESSION_ROWS == 3)
+            printf(".05 p value  =   6.0, chi-square should be less\n");
+        #elif (SESSION_ROWS == 2861)
+            printf(".05 p value  = 2985.5, chi-square should be less\n");
+        #endif
+        printf("\n");
+
+        return ret;
+    }
+
+    #endif /* SESSION_STATS */
+
+#else  /* NO_SESSION_CACHE */
+
+/* No session cache version */
+WOLFSSL_SESSION* GetSession(WOLFSSL* ssl, byte* masterSecret,
+        byte restoreSessionCerts)
+{
+    (void)ssl;
+    (void)masterSecret;
+    (void)restoreSessionCerts;
+
+    return NULL;
+}
+
+#endif /* NO_SESSION_CACHE */
+
+
+/* call before SSL_connect, if verifying will add name check to
+   date check and signature check */
+WOLFSSL_ABI
+int wolfSSL_check_domain_name(WOLFSSL* ssl, const char* dn)
+{
+    WOLFSSL_ENTER("wolfSSL_check_domain_name");
+
+    if (ssl == NULL || dn == NULL) {
+        WOLFSSL_MSG("Bad function argument: NULL");
+        return WOLFSSL_FAILURE;
+    }
+
+    if (ssl->buffers.domainName.buffer)
+        XFREE(ssl->buffers.domainName.buffer, ssl->heap, DYNAMIC_TYPE_DOMAIN);
+
+    ssl->buffers.domainName.length = (word32)XSTRLEN(dn);
+    ssl->buffers.domainName.buffer = (byte*)XMALLOC(
+            ssl->buffers.domainName.length + 1, ssl->heap, DYNAMIC_TYPE_DOMAIN);
+
+    if (ssl->buffers.domainName.buffer) {
+        unsigned char* domainName = ssl->buffers.domainName.buffer;
+        XMEMCPY(domainName, dn, ssl->buffers.domainName.length);
+        domainName[ssl->buffers.domainName.length] = '\0';
+        return WOLFSSL_SUCCESS;
+    }
+    else {
+        ssl->error = MEMORY_ERROR;
+        return WOLFSSL_FAILURE;
+    }
+}
+
+
+/* turn on wolfSSL zlib compression
+   returns WOLFSSL_SUCCESS for success, else error (not built in)
+*/
+int wolfSSL_set_compression(WOLFSSL* ssl)
+{
+    WOLFSSL_ENTER("wolfSSL_set_compression");
+    (void)ssl;
+#ifdef HAVE_LIBZ
+    ssl->options.usingCompression = 1;
+    return WOLFSSL_SUCCESS;
+#else
+    return NOT_COMPILED_IN;
+#endif
+}
+
+
+#ifndef USE_WINDOWS_API
+    #ifndef NO_WRITEV
+
+        /* simulate writev semantics, doesn't actually do block at a time though
+           because of SSL_write behavior and because front adds may be small */
+        int wolfSSL_writev(WOLFSSL* ssl, const struct iovec* iov, int iovcnt)
+        {
+        #ifdef WOLFSSL_SMALL_STACK
+            byte   staticBuffer[1]; /* force heap usage */
+        #else
+            byte   staticBuffer[FILE_BUFFER_SIZE];
+        #endif
+            byte* myBuffer  = staticBuffer;
+            int   dynamic   = 0;
+            int   sending   = 0;
+            int   idx       = 0;
+            int   i;
+            int   ret;
+
+            WOLFSSL_ENTER("wolfSSL_writev");
+
+            for (i = 0; i < iovcnt; i++)
+                sending += (int)iov[i].iov_len;
+
+            if (sending > (int)sizeof(staticBuffer)) {
+                myBuffer = (byte*)XMALLOC(sending, ssl->heap,
+                                                           DYNAMIC_TYPE_WRITEV);
+                if (!myBuffer)
+                    return MEMORY_ERROR;
+
+                dynamic = 1;
+            }
+
+            for (i = 0; i < iovcnt; i++) {
+                XMEMCPY(&myBuffer[idx], iov[i].iov_base, iov[i].iov_len);
+                idx += (int)iov[i].iov_len;
+            }
+
+            ret = wolfSSL_write(ssl, myBuffer, sending);
+
+            if (dynamic)
+                XFREE(myBuffer, ssl->heap, DYNAMIC_TYPE_WRITEV);
+
+            return ret;
+        }
+    #endif
+#endif
+
+
+#ifdef WOLFSSL_CALLBACKS
+
+    typedef struct itimerval Itimerval;
+
+    /* don't keep calling simple functions while setting up timer and signals
+       if no inlining these are the next best */
+
+    #define AddTimes(a, b, c)                       \
+        do {                                        \
+            c.tv_sec  = a.tv_sec  + b.tv_sec;       \
+            c.tv_usec = a.tv_usec + b.tv_usec;      \
+            if (c.tv_usec >=  1000000) {            \
+                c.tv_sec++;                         \
+                c.tv_usec -= 1000000;               \
+            }                                       \
+        } while (0)
+
+
+    #define SubtractTimes(a, b, c)                  \
+        do {                                        \
+            c.tv_sec  = a.tv_sec  - b.tv_sec;       \
+            c.tv_usec = a.tv_usec - b.tv_usec;      \
+            if (c.tv_usec < 0) {                    \
+                c.tv_sec--;                         \
+                c.tv_usec += 1000000;               \
+            }                                       \
+        } while (0)
+
+    #define CmpTimes(a, b, cmp)                     \
+        ((a.tv_sec  ==  b.tv_sec) ?                 \
+            (a.tv_usec cmp b.tv_usec) :             \
+            (a.tv_sec  cmp b.tv_sec))               \
+
+
+    /* do nothing handler */
+    static void myHandler(int signo)
+    {
+        (void)signo;
+        return;
+    }
+
+
+    static int wolfSSL_ex_wrapper(WOLFSSL* ssl, HandShakeCallBack hsCb,
+                                 TimeoutCallBack toCb, WOLFSSL_TIMEVAL timeout)
+    {
+        int       ret        = WOLFSSL_FATAL_ERROR;
+        int       oldTimerOn = 0;   /* was timer already on */
+        WOLFSSL_TIMEVAL startTime;
+        WOLFSSL_TIMEVAL endTime;
+        WOLFSSL_TIMEVAL totalTime;
+        Itimerval myTimeout;
+        Itimerval oldTimeout; /* if old timer adjust from total time to reset */
+        struct sigaction act, oact;
+
+        #define ERR_OUT(x) { ssl->hsInfoOn = 0; ssl->toInfoOn = 0; return x; }
+
+        if (hsCb) {
+            ssl->hsInfoOn = 1;
+            InitHandShakeInfo(&ssl->handShakeInfo, ssl);
+        }
+        if (toCb) {
+            ssl->toInfoOn = 1;
+            InitTimeoutInfo(&ssl->timeoutInfo);
+
+            if (gettimeofday(&startTime, 0) < 0)
+                ERR_OUT(GETTIME_ERROR);
+
+            /* use setitimer to simulate getitimer, init 0 myTimeout */
+            myTimeout.it_interval.tv_sec  = 0;
+            myTimeout.it_interval.tv_usec = 0;
+            myTimeout.it_value.tv_sec     = 0;
+            myTimeout.it_value.tv_usec    = 0;
+            if (setitimer(ITIMER_REAL, &myTimeout, &oldTimeout) < 0)
+                ERR_OUT(SETITIMER_ERROR);
+
+            if (oldTimeout.it_value.tv_sec || oldTimeout.it_value.tv_usec) {
+                oldTimerOn = 1;
+
+                /* is old timer going to expire before ours */
+                if (CmpTimes(oldTimeout.it_value, timeout, <)) {
+                    timeout.tv_sec  = oldTimeout.it_value.tv_sec;
+                    timeout.tv_usec = oldTimeout.it_value.tv_usec;
+                }
+            }
+            myTimeout.it_value.tv_sec  = timeout.tv_sec;
+            myTimeout.it_value.tv_usec = timeout.tv_usec;
+
+            /* set up signal handler, don't restart socket send/recv */
+            act.sa_handler = myHandler;
+            sigemptyset(&act.sa_mask);
+            act.sa_flags = 0;
+#ifdef SA_INTERRUPT
+            act.sa_flags |= SA_INTERRUPT;
+#endif
+            if (sigaction(SIGALRM, &act, &oact) < 0)
+                ERR_OUT(SIGACT_ERROR);
+
+            if (setitimer(ITIMER_REAL, &myTimeout, 0) < 0)
+                ERR_OUT(SETITIMER_ERROR);
+        }
+
+        /* do main work */
+#ifndef NO_WOLFSSL_CLIENT
+        if (ssl->options.side == WOLFSSL_CLIENT_END)
+            ret = wolfSSL_connect(ssl);
+#endif
+#ifndef NO_WOLFSSL_SERVER
+        if (ssl->options.side == WOLFSSL_SERVER_END)
+            ret = wolfSSL_accept(ssl);
+#endif
+
+        /* do callbacks */
+        if (toCb) {
+            if (oldTimerOn) {
+                gettimeofday(&endTime, 0);
+                SubtractTimes(endTime, startTime, totalTime);
+                /* adjust old timer for elapsed time */
+                if (CmpTimes(totalTime, oldTimeout.it_value, <))
+                    SubtractTimes(oldTimeout.it_value, totalTime,
+                                  oldTimeout.it_value);
+                else {
+                    /* reset value to interval, may be off */
+                    oldTimeout.it_value.tv_sec = oldTimeout.it_interval.tv_sec;
+                    oldTimeout.it_value.tv_usec =oldTimeout.it_interval.tv_usec;
+                }
+                /* keep iter the same whether there or not */
+            }
+            /* restore old handler */
+            if (sigaction(SIGALRM, &oact, 0) < 0)
+                ret = SIGACT_ERROR;    /* more pressing error, stomp */
+            else
+                /* use old settings which may turn off (expired or not there) */
+                if (setitimer(ITIMER_REAL, &oldTimeout, 0) < 0)
+                    ret = SETITIMER_ERROR;
+
+            /* if we had a timeout call callback */
+            if (ssl->timeoutInfo.timeoutName[0]) {
+                ssl->timeoutInfo.timeoutValue.tv_sec  = timeout.tv_sec;
+                ssl->timeoutInfo.timeoutValue.tv_usec = timeout.tv_usec;
+                (toCb)(&ssl->timeoutInfo);
+            }
+            /* clean up */
+            FreeTimeoutInfo(&ssl->timeoutInfo, ssl->heap);
+            ssl->toInfoOn = 0;
+        }
+        if (hsCb) {
+            FinishHandShakeInfo(&ssl->handShakeInfo);
+            (hsCb)(&ssl->handShakeInfo);
+            ssl->hsInfoOn = 0;
+        }
+        return ret;
+    }
+
+
+#ifndef NO_WOLFSSL_CLIENT
+
+    int wolfSSL_connect_ex(WOLFSSL* ssl, HandShakeCallBack hsCb,
+                          TimeoutCallBack toCb, WOLFSSL_TIMEVAL timeout)
+    {
+        WOLFSSL_ENTER("wolfSSL_connect_ex");
+        return wolfSSL_ex_wrapper(ssl, hsCb, toCb, timeout);
+    }
+
+#endif
+
+
+#ifndef NO_WOLFSSL_SERVER
+
+    int wolfSSL_accept_ex(WOLFSSL* ssl, HandShakeCallBack hsCb,
+                         TimeoutCallBack toCb, WOLFSSL_TIMEVAL timeout)
+    {
+        WOLFSSL_ENTER("wolfSSL_accept_ex");
+        return wolfSSL_ex_wrapper(ssl, hsCb, toCb, timeout);
+    }
+
+#endif
+
+#endif /* WOLFSSL_CALLBACKS */
+
+
+#ifndef NO_PSK
+
+    void wolfSSL_CTX_set_psk_client_callback(WOLFSSL_CTX* ctx,
+                                         wc_psk_client_callback cb)
+    {
+        WOLFSSL_ENTER("SSL_CTX_set_psk_client_callback");
+
+        if (ctx == NULL)
+            return;
+
+        ctx->havePSK = 1;
+        ctx->client_psk_cb = cb;
+    }
+
+
+    void wolfSSL_set_psk_client_callback(WOLFSSL* ssl,wc_psk_client_callback cb)
+    {
+        byte haveRSA = 1;
+        int  keySz   = 0;
+
+        WOLFSSL_ENTER("SSL_set_psk_client_callback");
+
+        if (ssl == NULL)
+            return;
+
+        ssl->options.havePSK = 1;
+        ssl->options.client_psk_cb = cb;
+
+        #ifdef NO_RSA
+            haveRSA = 0;
+        #endif
+        #ifndef NO_CERTS
+            keySz = ssl->buffers.keySz;
+        #endif
+        InitSuites(ssl->suites, ssl->version, keySz, haveRSA, TRUE,
+                   ssl->options.haveDH, ssl->options.haveNTRU,
+                   ssl->options.haveECDSAsig, ssl->options.haveECC,
+                   ssl->options.haveStaticECC, ssl->options.side);
+    }
+
+
+    void wolfSSL_CTX_set_psk_server_callback(WOLFSSL_CTX* ctx,
+                                         wc_psk_server_callback cb)
+    {
+        WOLFSSL_ENTER("SSL_CTX_set_psk_server_callback");
+        if (ctx == NULL)
+            return;
+        ctx->havePSK = 1;
+        ctx->server_psk_cb = cb;
+    }
+
+
+    void wolfSSL_set_psk_server_callback(WOLFSSL* ssl,wc_psk_server_callback cb)
+    {
+        byte haveRSA = 1;
+        int  keySz   = 0;
+
+        WOLFSSL_ENTER("SSL_set_psk_server_callback");
+        if (ssl == NULL)
+            return;
+
+        ssl->options.havePSK = 1;
+        ssl->options.server_psk_cb = cb;
+
+        #ifdef NO_RSA
+            haveRSA = 0;
+        #endif
+        #ifndef NO_CERTS
+            keySz = ssl->buffers.keySz;
+        #endif
+        InitSuites(ssl->suites, ssl->version, keySz, haveRSA, TRUE,
+                   ssl->options.haveDH, ssl->options.haveNTRU,
+                   ssl->options.haveECDSAsig, ssl->options.haveECC,
+                   ssl->options.haveStaticECC, ssl->options.side);
+    }
+
+
+    const char* wolfSSL_get_psk_identity_hint(const WOLFSSL* ssl)
+    {
+        WOLFSSL_ENTER("SSL_get_psk_identity_hint");
+
+        if (ssl == NULL || ssl->arrays == NULL)
+            return NULL;
+
+        return ssl->arrays->server_hint;
+    }
+
+
+    const char* wolfSSL_get_psk_identity(const WOLFSSL* ssl)
+    {
+        WOLFSSL_ENTER("SSL_get_psk_identity");
+
+        if (ssl == NULL || ssl->arrays == NULL)
+            return NULL;
+
+        return ssl->arrays->client_identity;
+    }
+
+
+    int wolfSSL_CTX_use_psk_identity_hint(WOLFSSL_CTX* ctx, const char* hint)
+    {
+        WOLFSSL_ENTER("SSL_CTX_use_psk_identity_hint");
+        if (hint == 0)
+            ctx->server_hint[0] = '\0';
+        else {
+            /* Qt does not call CTX_set_*_psk_callbacks where havePSK is set */
+            #ifdef WOLFSSL_QT
+            ctx->havePSK=1;
+            #endif
+            XSTRNCPY(ctx->server_hint, hint, MAX_PSK_ID_LEN);
+            ctx->server_hint[MAX_PSK_ID_LEN] = '\0'; /* null term */
+        }
+        return WOLFSSL_SUCCESS;
+    }
+
+
+    int wolfSSL_use_psk_identity_hint(WOLFSSL* ssl, const char* hint)
+    {
+        WOLFSSL_ENTER("SSL_use_psk_identity_hint");
+
+        if (ssl == NULL || ssl->arrays == NULL)
+            return WOLFSSL_FAILURE;
+
+        if (hint == 0)
+            ssl->arrays->server_hint[0] = 0;
+        else {
+            XSTRNCPY(ssl->arrays->server_hint, hint,
+                                            sizeof(ssl->arrays->server_hint)-1);
+            ssl->arrays->server_hint[sizeof(ssl->arrays->server_hint)-1] = '\0';
+        }
+        return WOLFSSL_SUCCESS;
+    }
+
+#endif /* NO_PSK */
+
+
+#ifdef HAVE_ANON
+
+    int wolfSSL_CTX_allow_anon_cipher(WOLFSSL_CTX* ctx)
+    {
+        WOLFSSL_ENTER("wolfSSL_CTX_allow_anon_cipher");
+
+        if (ctx == NULL)
+            return WOLFSSL_FAILURE;
+
+        ctx->haveAnon = 1;
+
+        return WOLFSSL_SUCCESS;
+    }
+
+#endif /* HAVE_ANON */
+
+
+#ifndef NO_CERTS
+/* used to be defined on NO_FILESYSTEM only, but are generally useful */
+
+    int wolfSSL_CTX_load_verify_buffer_ex(WOLFSSL_CTX* ctx,
+                                         const unsigned char* in,
+                                         long sz, int format, int userChain,
+                                         word32 flags)
+    {
+        int verify;
+
+        WOLFSSL_ENTER("wolfSSL_CTX_load_verify_buffer_ex");
+
+        verify = GET_VERIFY_SETTING_CTX(ctx);
+        if (flags & WOLFSSL_LOAD_FLAG_DATE_ERR_OKAY)
+            verify = VERIFY_SKIP_DATE;
+
+        if (format == WOLFSSL_FILETYPE_PEM)
+            return ProcessChainBuffer(ctx, in, sz, format, CA_TYPE, NULL,
+                                      verify);
+        else
+            return ProcessBuffer(ctx, in, sz, format, CA_TYPE, NULL, NULL,
+                                 userChain, verify);
+    }
+
+    /* wolfSSL extension allows DER files to be loaded from buffers as well */
+    int wolfSSL_CTX_load_verify_buffer(WOLFSSL_CTX* ctx,
+                                       const unsigned char* in,
+                                       long sz, int format)
+    {
+        return wolfSSL_CTX_load_verify_buffer_ex(ctx, in, sz, format, 0,
+            WOLFSSL_LOAD_VERIFY_DEFAULT_FLAGS);
+    }
+
+    int wolfSSL_CTX_load_verify_chain_buffer_format(WOLFSSL_CTX* ctx,
+                                       const unsigned char* in,
+                                       long sz, int format)
+    {
+        return wolfSSL_CTX_load_verify_buffer_ex(ctx, in, sz, format, 1,
+            WOLFSSL_LOAD_VERIFY_DEFAULT_FLAGS);
+    }
+
+
+#ifdef WOLFSSL_TRUST_PEER_CERT
+    int wolfSSL_CTX_trust_peer_buffer(WOLFSSL_CTX* ctx,
+                                       const unsigned char* in,
+                                       long sz, int format)
+    {
+        WOLFSSL_ENTER("wolfSSL_CTX_trust_peer_buffer");
+
+        /* sanity check on arguments */
+        if (sz < 0 || in == NULL || ctx == NULL) {
+            return BAD_FUNC_ARG;
+        }
+
+        if (format == WOLFSSL_FILETYPE_PEM)
+            return ProcessChainBuffer(ctx, in, sz, format, TRUSTED_PEER_TYPE,
+                                      NULL, GET_VERIFY_SETTING_CTX(ctx));
+        else
+            return ProcessBuffer(ctx, in, sz, format, TRUSTED_PEER_TYPE, NULL,
+                                 NULL, 0, GET_VERIFY_SETTING_CTX(ctx));
+    }
+#endif /* WOLFSSL_TRUST_PEER_CERT */
+
+
+    int wolfSSL_CTX_use_certificate_buffer(WOLFSSL_CTX* ctx,
+                                 const unsigned char* in, long sz, int format)
+    {
+        WOLFSSL_ENTER("wolfSSL_CTX_use_certificate_buffer");
+        return ProcessBuffer(ctx, in, sz, format, CERT_TYPE, NULL, NULL, 0,
+                             GET_VERIFY_SETTING_CTX(ctx));
+    }
+
+
+    int wolfSSL_CTX_use_PrivateKey_buffer(WOLFSSL_CTX* ctx,
+                                 const unsigned char* in, long sz, int format)
+    {
+        WOLFSSL_ENTER("wolfSSL_CTX_use_PrivateKey_buffer");
+        return ProcessBuffer(ctx, in, sz, format, PRIVATEKEY_TYPE, NULL, NULL,
+                             0, GET_VERIFY_SETTING_CTX(ctx));
+    }
+
+#ifdef HAVE_PKCS11
+    int wolfSSL_CTX_use_PrivateKey_id(WOLFSSL_CTX* ctx, const unsigned char* id,
+                                      long sz, int devId, long keySz)
+    {
+        int ret = WOLFSSL_FAILURE;
+
+        FreeDer(&ctx->privateKey);
+        if (AllocDer(&ctx->privateKey, (word32)sz, PRIVATEKEY_TYPE,
+                                                              ctx->heap) == 0) {
+            XMEMCPY(ctx->privateKey->buffer, id, sz);
+            ctx->privateKeyId = 1;
+            ctx->privateKeySz = (word32)keySz;
+            if (devId != INVALID_DEVID)
+                ctx->privateKeyDevId = devId;
+            else
+                ctx->privateKeyDevId = ctx->devId;
+
+            ret = WOLFSSL_SUCCESS;
+        }
+
+        return ret;
+    }
+#endif
+
+    int wolfSSL_CTX_use_certificate_chain_buffer_format(WOLFSSL_CTX* ctx,
+                                 const unsigned char* in, long sz, int format)
+    {
+        WOLFSSL_ENTER("wolfSSL_CTX_use_certificate_chain_buffer_format");
+        return ProcessBuffer(ctx, in, sz, format, CERT_TYPE, NULL, NULL, 1,
+                             GET_VERIFY_SETTING_CTX(ctx));
+    }
+
+    int wolfSSL_CTX_use_certificate_chain_buffer(WOLFSSL_CTX* ctx,
+                                 const unsigned char* in, long sz)
+    {
+        return wolfSSL_CTX_use_certificate_chain_buffer_format(ctx, in, sz,
+                                                            WOLFSSL_FILETYPE_PEM);
+    }
+
+
+#ifndef NO_DH
+
+    /* server wrapper for ctx or ssl Diffie-Hellman parameters */
+    static int wolfSSL_SetTmpDH_buffer_wrapper(WOLFSSL_CTX* ctx, WOLFSSL* ssl,
+                                               const unsigned char* buf,
+                                               long sz, int format)
+    {
+        DerBuffer* der = NULL;
+        int    ret      = 0;
+        word32 pSz = MAX_DH_SIZE;
+        word32 gSz = MAX_DH_SIZE;
+    #ifdef WOLFSSL_SMALL_STACK
+        byte*  p = NULL;
+        byte*  g = NULL;
+    #else
+        byte   p[MAX_DH_SIZE];
+        byte   g[MAX_DH_SIZE];
+    #endif
+
+        if (ctx == NULL || buf == NULL)
+            return BAD_FUNC_ARG;
+
+        ret = AllocDer(&der, 0, DH_PARAM_TYPE, ctx->heap);
+        if (ret != 0) {
+            return ret;
+        }
+        der->buffer = (byte*)buf;
+        der->length = (word32)sz;
+
+    #ifdef WOLFSSL_SMALL_STACK
+        p = (byte*)XMALLOC(pSz, NULL, DYNAMIC_TYPE_PUBLIC_KEY);
+        g = (byte*)XMALLOC(gSz, NULL, DYNAMIC_TYPE_PUBLIC_KEY);
+
+        if (p == NULL || g == NULL) {
+            XFREE(p, NULL, DYNAMIC_TYPE_PUBLIC_KEY);
+            XFREE(g, NULL, DYNAMIC_TYPE_PUBLIC_KEY);
+            return MEMORY_E;
+        }
+    #endif
+
+        if (format != WOLFSSL_FILETYPE_ASN1 && format != WOLFSSL_FILETYPE_PEM)
+            ret = WOLFSSL_BAD_FILETYPE;
+        else {
+            if (format == WOLFSSL_FILETYPE_PEM) {
+#ifdef WOLFSSL_PEM_TO_DER
+                FreeDer(&der);
+                ret = PemToDer(buf, sz, DH_PARAM_TYPE, &der, ctx->heap,
+                               NULL, NULL);
+    #ifdef WOLFSSL_WPAS
+        #ifndef NO_DSA
+                if (ret < 0) {
+                    ret = PemToDer(buf, sz, DSA_PARAM_TYPE, &der, ctx->heap,
+                               NULL, NULL);
+                }
+        #endif
+    #endif /* WOLFSSL_WPAS */
+#else
+                ret = NOT_COMPILED_IN;
+#endif /* WOLFSSL_PEM_TO_DER */
+            }
+
+            if (ret == 0) {
+                if (wc_DhParamsLoad(der->buffer, der->length, p, &pSz, g, &gSz) < 0)
+                    ret = WOLFSSL_BAD_FILETYPE;
+                else if (ssl)
+                    ret = wolfSSL_SetTmpDH(ssl, p, pSz, g, gSz);
+                else
+                    ret = wolfSSL_CTX_SetTmpDH(ctx, p, pSz, g, gSz);
+            }
+        }
+
+        FreeDer(&der);
+
+    #ifdef WOLFSSL_SMALL_STACK
+        XFREE(p, NULL, DYNAMIC_TYPE_PUBLIC_KEY);
+        XFREE(g, NULL, DYNAMIC_TYPE_PUBLIC_KEY);
+    #endif
+
+        return ret;
+    }
+
+
+    /* server Diffie-Hellman parameters, WOLFSSL_SUCCESS on ok */
+    int wolfSSL_SetTmpDH_buffer(WOLFSSL* ssl, const unsigned char* buf, long sz,
+                               int format)
+    {
+        if (ssl == NULL)
+            return BAD_FUNC_ARG;
+
+        return wolfSSL_SetTmpDH_buffer_wrapper(ssl->ctx, ssl, buf, sz, format);
+    }
+
+
+    /* server ctx Diffie-Hellman parameters, WOLFSSL_SUCCESS on ok */
+    int wolfSSL_CTX_SetTmpDH_buffer(WOLFSSL_CTX* ctx, const unsigned char* buf,
+                                   long sz, int format)
+    {
+        return wolfSSL_SetTmpDH_buffer_wrapper(ctx, NULL, buf, sz, format);
+    }
+
+#endif /* NO_DH */
+
+
+    int wolfSSL_use_certificate_buffer(WOLFSSL* ssl,
+                                 const unsigned char* in, long sz, int format)
+    {
+        WOLFSSL_ENTER("wolfSSL_use_certificate_buffer");
+        if (ssl == NULL)
+            return BAD_FUNC_ARG;
+
+        return ProcessBuffer(ssl->ctx, in, sz, format, CERT_TYPE, ssl, NULL, 0,
+                             GET_VERIFY_SETTING_SSL(ssl));
+    }
+
+
+    int wolfSSL_use_PrivateKey_buffer(WOLFSSL* ssl,
+                                 const unsigned char* in, long sz, int format)
+    {
+        WOLFSSL_ENTER("wolfSSL_use_PrivateKey_buffer");
+        if (ssl == NULL)
+            return BAD_FUNC_ARG;
+
+        return ProcessBuffer(ssl->ctx, in, sz, format, PRIVATEKEY_TYPE,
+                             ssl, NULL, 0, GET_VERIFY_SETTING_SSL(ssl));
+    }
+
+#ifdef HAVE_PKCS11
+    int wolfSSL_use_PrivateKey_id(WOLFSSL* ssl, const unsigned char* id,
+                                  long sz, int devId, long keySz)
+    {
+        int ret = WOLFSSL_FAILURE;
+
+        if (ssl->buffers.weOwnKey)
+            FreeDer(&ssl->buffers.key);
+        if (AllocDer(&ssl->buffers.key, (word32)sz, PRIVATEKEY_TYPE,
+                                                            ssl->heap) == 0) {
+            XMEMCPY(ssl->buffers.key->buffer, id, sz);
+            ssl->buffers.weOwnKey = 1;
+            ssl->buffers.keyId = 1;
+            ssl->buffers.keySz = (word32)keySz;
+            if (devId != INVALID_DEVID)
+                ssl->buffers.keyDevId = devId;
+            else
+                ssl->buffers.keyDevId = ssl->devId;
+
+            ret = WOLFSSL_SUCCESS;
+        }
+
+        return ret;
+    }
+#endif
+
+    int wolfSSL_use_certificate_chain_buffer_format(WOLFSSL* ssl,
+                                 const unsigned char* in, long sz, int format)
+    {
+        WOLFSSL_ENTER("wolfSSL_use_certificate_chain_buffer_format");
+        if (ssl == NULL)
+            return BAD_FUNC_ARG;
+
+        return ProcessBuffer(ssl->ctx, in, sz, format, CERT_TYPE,
+                             ssl, NULL, 1, GET_VERIFY_SETTING_SSL(ssl));
+    }
+
+    int wolfSSL_use_certificate_chain_buffer(WOLFSSL* ssl,
+                                 const unsigned char* in, long sz)
+    {
+        return wolfSSL_use_certificate_chain_buffer_format(ssl, in, sz,
+                                                            WOLFSSL_FILETYPE_PEM);
+    }
+
+
+    /* unload any certs or keys that SSL owns, leave CTX as is
+       WOLFSSL_SUCCESS on ok */
+    int wolfSSL_UnloadCertsKeys(WOLFSSL* ssl)
+    {
+        if (ssl == NULL) {
+            WOLFSSL_MSG("Null function arg");
+            return BAD_FUNC_ARG;
+        }
+
+        if (ssl->buffers.weOwnCert && !ssl->keepCert) {
+            WOLFSSL_MSG("Unloading cert");
+            FreeDer(&ssl->buffers.certificate);
+            #ifdef KEEP_OUR_CERT
+                FreeX509(ssl->ourCert);
+                if (ssl->ourCert) {
+                    XFREE(ssl->ourCert, ssl->heap, DYNAMIC_TYPE_X509);
+                    ssl->ourCert = NULL;
+                }
+            #endif
+            ssl->buffers.weOwnCert = 0;
+        }
+
+        if (ssl->buffers.weOwnCertChain) {
+            WOLFSSL_MSG("Unloading cert chain");
+            FreeDer(&ssl->buffers.certChain);
+            ssl->buffers.weOwnCertChain = 0;
+        }
+
+        if (ssl->buffers.weOwnKey) {
+            WOLFSSL_MSG("Unloading key");
+            FreeDer(&ssl->buffers.key);
+            ssl->buffers.weOwnKey = 0;
+        }
+
+        return WOLFSSL_SUCCESS;
+    }
+
+
+    int wolfSSL_CTX_UnloadCAs(WOLFSSL_CTX* ctx)
+    {
+        WOLFSSL_ENTER("wolfSSL_CTX_UnloadCAs");
+
+        if (ctx == NULL)
+            return BAD_FUNC_ARG;
+
+        return wolfSSL_CertManagerUnloadCAs(ctx->cm);
+    }
+
+
+#ifdef WOLFSSL_TRUST_PEER_CERT
+    int wolfSSL_CTX_Unload_trust_peers(WOLFSSL_CTX* ctx)
+    {
+        WOLFSSL_ENTER("wolfSSL_CTX_Unload_trust_peers");
+
+        if (ctx == NULL)
+            return BAD_FUNC_ARG;
+
+        return wolfSSL_CertManagerUnload_trust_peers(ctx->cm);
+    }
+#endif /* WOLFSSL_TRUST_PEER_CERT */
+/* old NO_FILESYSTEM end */
+#endif /* !NO_CERTS */
+
+
+#ifdef OPENSSL_EXTRA
+
+    int wolfSSL_add_all_algorithms(void)
+    {
+        WOLFSSL_ENTER("wolfSSL_add_all_algorithms");
+        if (wolfSSL_Init() == WOLFSSL_SUCCESS)
+            return WOLFSSL_SUCCESS;
+        else
+            return WOLFSSL_FATAL_ERROR;
+    }
+
+    int wolfSSL_OpenSSL_add_all_algorithms_noconf(void)
+    {
+        WOLFSSL_ENTER("wolfSSL_OpenSSL_add_all_algorithms_noconf");
+
+        if  (wolfSSL_add_all_algorithms() == WOLFSSL_FATAL_ERROR)
+            return WOLFSSL_FATAL_ERROR;
+
+        return  WOLFSSL_SUCCESS;
+    }
+
+    int wolfSSL_OpenSSL_add_all_algorithms_conf(void)
+    {
+        WOLFSSL_ENTER("wolfSSL_OpenSSL_add_all_algorithms_conf");
+        /* This function is currently the same as
+        wolfSSL_OpenSSL_add_all_algorithms_noconf since we do not employ
+        the use of a wolfssl.cnf type configuration file and is only used for
+        OpenSSL compatability. */
+
+        if (wolfSSL_add_all_algorithms() == WOLFSSL_FATAL_ERROR) {
+            return WOLFSSL_FATAL_ERROR;
+        }
+        return WOLFSSL_SUCCESS;
+    }
+
+   /* returns previous set cache size which stays constant */
+    long wolfSSL_CTX_sess_set_cache_size(WOLFSSL_CTX* ctx, long sz)
+    {
+        /* cache size fixed at compile time in wolfSSL */
+        (void)ctx;
+        (void)sz;
+        WOLFSSL_MSG("session cache is set at compile time");
+        #ifndef NO_SESSION_CACHE
+            return (long)(SESSIONS_PER_ROW * SESSION_ROWS);
+        #else
+            return 0;
+        #endif
+    }
+
+#endif
+
+#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_EXTRA)
+    void wolfSSL_CTX_set_quiet_shutdown(WOLFSSL_CTX* ctx, int mode)
+    {
+        WOLFSSL_ENTER("wolfSSL_CTX_set_quiet_shutdown");
+        if (mode)
+            ctx->quietShutdown = 1;
+    }
+
+
+    void wolfSSL_set_quiet_shutdown(WOLFSSL* ssl, int mode)
+    {
+        WOLFSSL_ENTER("wolfSSL_CTX_set_quiet_shutdown");
+        if (mode)
+            ssl->options.quietShutdown = 1;
+    }
+#endif
+
+#ifdef OPENSSL_EXTRA
+    void wolfSSL_set_bio(WOLFSSL* ssl, WOLFSSL_BIO* rd, WOLFSSL_BIO* wr)
+    {
+        WOLFSSL_ENTER("wolfSSL_set_bio");
+
+        if (ssl == NULL) {
+            WOLFSSL_MSG("Bad argument, ssl was NULL");
+            return;
+        }
+
+        /* if WOLFSSL_BIO is socket type then set WOLFSSL socket to use */
+        if (rd != NULL && rd->type == WOLFSSL_BIO_SOCKET) {
+            wolfSSL_set_rfd(ssl, rd->num);
+        }
+        if (wr != NULL && wr->type == WOLFSSL_BIO_SOCKET) {
+            wolfSSL_set_wfd(ssl, wr->num);
+        }
+
+        /* free any existing WOLFSSL_BIOs in use */
+        if (ssl->biord != NULL) {
+            if (ssl->biord != ssl->biowr) {
+                if (ssl->biowr != NULL) {
+                    wolfSSL_BIO_free(ssl->biowr);
+                    ssl->biowr = NULL;
+                }
+            }
+            wolfSSL_BIO_free(ssl->biord);
+            ssl->biord = NULL;
+        }
+
+
+        ssl->biord = rd;
+        ssl->biowr = wr;
+
+        /* set SSL to use BIO callbacks instead */
+        if (((ssl->cbioFlag & WOLFSSL_CBIO_RECV) == 0) &&
+            (rd != NULL && rd->type != WOLFSSL_BIO_SOCKET)) {
+            ssl->CBIORecv = BioReceive;
+        }
+        if (((ssl->cbioFlag & WOLFSSL_CBIO_SEND) == 0) &&
+            (wr != NULL && wr->type != WOLFSSL_BIO_SOCKET)) {
+            ssl->CBIOSend = BioSend;
+        }
+
+        /* User programs should always retry reading from these BIOs */
+        if (rd) {
+            /* User writes to rd */
+            BIO_set_retry_write(rd);
+        }
+        if (wr) {
+            /* User reads from wr */
+            BIO_set_retry_read(wr);
+        }
+    }
+#endif
+
+#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_EXTRA) || defined(HAVE_WEBSERVER)
+    void wolfSSL_CTX_set_client_CA_list(WOLFSSL_CTX* ctx,
+                                       WOLF_STACK_OF(WOLFSSL_X509_NAME)* names)
+    {
+        WOLFSSL_ENTER("wolfSSL_CTX_set_client_CA_list");
+    #if defined(OPENSSL_EXTRA) || defined(WOLFSSL_EXTRA)
+        if (ctx != NULL)
+            ctx->ca_names = names;
+    #else
+        (void)ctx;
+        (void)names;
+    #endif
+    }
+
+
+    /* returns the CA's set on server side or the CA's sent from server when
+     * on client side */
+#if defined(SESSION_CERTS) && defined(OPENSSL_ALL)
+    WOLF_STACK_OF(WOLFSSL_X509_NAME)* wolfSSL_get_client_CA_list(
+            const WOLFSSL* ssl)
+    {
+        WOLFSSL_ENTER("wolfSSL_get_client_CA_list");
+
+        if (ssl == NULL) {
+            WOLFSSL_MSG("Bad argument passed to wolfSSL_get_client_CA_list");
+            return NULL;
+        }
+
+        /* return list of CAs sent from the server */
+        if (ssl->options.side == WOLFSSL_CLIENT_END) {
+            WOLF_STACK_OF(WOLFSSL_X509)* sk;
+
+            sk = wolfSSL_get_peer_cert_chain(ssl);
+            if (sk != NULL) {
+                WOLF_STACK_OF(WOLFSSL_X509_NAME)* ret;
+                WOLFSSL_X509* x509;
+
+                ret = wolfSSL_sk_X509_NAME_new(NULL);
+                do {
+                    x509 = wolfSSL_sk_X509_pop(sk);
+                    if (x509 != NULL) {
+                        if (wolfSSL_X509_get_isCA(x509)) {
+                            if (wolfSSL_sk_X509_NAME_push(ret,
+                                    wolfSSL_X509_get_subject_name(x509)) != 0) {
+                                WOLFSSL_MSG("Error pushing X509 name to stack");
+                                /* continue on to try other certificates and
+                                 * do not fail out here */
+                            }
+                        }
+                        wolfSSL_X509_free(x509);
+                    }
+                } while (x509 != NULL);
+                wolfSSL_sk_X509_free(sk);
+                return ret;
+            }
+            return NULL;
+        }
+        else {
+            /* currently only can be set in the CTX */
+            return ssl->ctx->ca_names;
+        }
+    }
+#endif /* SESSION_CERTS */
+
+
+    #if defined(OPENSSL_ALL) || defined(OPENSSL_EXTRA) || \
+        defined(WOLFSSL_NGINX) || defined (WOLFSSL_HAPROXY)
+    /* registers client cert callback, called during handshake if server
+       requests client auth but user has not loaded client cert/key */
+    void wolfSSL_CTX_set_client_cert_cb(WOLFSSL_CTX *ctx, client_cert_cb cb)
+    {
+        WOLFSSL_ENTER("wolfSSL_CTX_set_client_cert_cb");
+
+        if (ctx != NULL) {
+            ctx->CBClientCert = cb;
+        }
+    }
+    #endif /* OPENSSL_ALL || OPENSSL_EXTRA || WOLFSSL_NGINX || WOLFSSL_HAPROXY */
+
+#endif /* OPENSSL_EXTRA || WOLFSSL_EXTRA || HAVE_WEBSERVER */
+
+#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_EXTRA)
+    WOLF_STACK_OF(WOLFSSL_X509_NAME)* wolfSSL_CTX_get_client_CA_list(
+            const WOLFSSL_CTX *s)
+    {
+        WOLFSSL_ENTER("wolfSSL_CTX_get_client_CA_list");
+
+        if (s == NULL)
+            return NULL;
+
+        return s->ca_names;
+    }
+#endif
+
+#if defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER)
+    #if !defined(NO_RSA) && !defined(NO_CERTS)
+    WOLF_STACK_OF(WOLFSSL_X509_NAME)* wolfSSL_load_client_CA_file(const char* fname)
+    {
+        /* The webserver build is using this to load a CA into the server
+         * for client authentication as an option. Have this return NULL in
+         * that case. If OPENSSL_EXTRA is enabled, go ahead and include
+         * the function. */
+    #ifdef OPENSSL_EXTRA
+        WOLFSSL_STACK *list = NULL;
+        WOLFSSL_STACK *node;
+        WOLFSSL_BIO* bio;
+        WOLFSSL_X509 *cert = NULL;
+        WOLFSSL_X509_NAME *subjectName = NULL;
+        unsigned long err;
+
+        WOLFSSL_ENTER("wolfSSL_load_client_CA_file");
+
+        bio = wolfSSL_BIO_new_file(fname, "r");
+        if (bio == NULL)
+            return NULL;
+
+        /* Read each certificate in the chain out of the file. */
+        while (wolfSSL_PEM_read_bio_X509(bio, &cert, NULL, NULL) != NULL) {
+            subjectName = wolfSSL_X509_get_subject_name(cert);
+            if (subjectName == NULL)
+                break;
+
+            node = wolfSSL_sk_new_node(NULL);
+            if (node == NULL)
+                break;
+            node->type = STACK_TYPE_X509_NAME;
+
+            /* Need a persistent copy of the subject name. */
+            node->data.name = wolfSSL_X509_NAME_dup(subjectName);
+            /*
+             * Original cert will be freed so make sure not to try to access
+             * it in the future.
+             */
+            node->data.name->x509 = NULL;
+
+            /* Put node on the front of the list. */
+            node->num  = (list == NULL) ? 1 : list->num + 1;
+            node->next = list;
+            list = node;
+
+            wolfSSL_X509_free(cert);
+            cert = NULL;
+        }
+
+        err = wolfSSL_ERR_peek_last_error();
+
+        if (ERR_GET_LIB(err) == ERR_LIB_PEM &&
+                ERR_GET_REASON(err) == PEM_R_NO_START_LINE) {
+            /*
+             * wolfSSL_PEM_read_bio_X509 pushes an ASN_NO_PEM_HEADER error
+             * to the error queue on file end. This should not be left
+             * for the caller to find so we clear the last error.
+             */
+            wc_RemoveErrorNode(-1);
+        }
+
+        wolfSSL_X509_free(cert);
+        wolfSSL_BIO_free(bio);
+        return list;
+    #else
+        (void)fname;
+        return NULL;
+    #endif
+    }
+    #endif
+#endif
+
+#ifdef OPENSSL_EXTRA
+    #if !defined(NO_RSA) && !defined(NO_CERTS)
+    int wolfSSL_CTX_add_client_CA(WOLFSSL_CTX* ctx, WOLFSSL_X509* x509)
+    {
+        WOLFSSL_STACK *node = NULL;
+        WOLFSSL_X509_NAME *subjectName = NULL;
+
+        WOLFSSL_ENTER("wolfSSL_CTX_add_client_CA");
+
+        if (ctx == NULL || x509 == NULL){
+            WOLFSSL_MSG("Bad argument");
+            return SSL_FAILURE;
+        }
+
+        subjectName = wolfSSL_X509_get_subject_name(x509);
+        if (subjectName == NULL){
+            WOLFSSL_MSG("invalid x509 data");
+            return SSL_FAILURE;
+        }
+
+        /* Alloc stack struct */
+        node = (WOLF_STACK_OF(WOLFSSL_X509_NAME)*)XMALLOC(
+                                           sizeof(WOLF_STACK_OF(WOLFSSL_X509_NAME)),
+                                           NULL, DYNAMIC_TYPE_OPENSSL);
+        if (node == NULL){
+            WOLFSSL_MSG("memory allocation error");
+            return SSL_FAILURE;
+        }
+        XMEMSET(node, 0, sizeof(WOLF_STACK_OF(WOLFSSL_X509_NAME)));
+
+        /* Alloc and copy WOLFSSL_X509_NAME */
+        node->data.name = (WOLFSSL_X509_NAME*)XMALLOC(
+                                              sizeof(WOLFSSL_X509_NAME),
+                                              NULL, DYNAMIC_TYPE_OPENSSL);
+        if (node->data.name == NULL) {
+            XFREE(node, NULL, DYNAMIC_TYPE_OPENSSL);
+            WOLFSSL_MSG("memory allocation error");
+            return SSL_FAILURE;
+        }
+        XMEMCPY(node->data.name, subjectName, sizeof(WOLFSSL_X509_NAME));
+        XMEMSET(subjectName, 0, sizeof(WOLFSSL_X509_NAME));
+
+        /* push new node onto head of stack */
+        node->num = (ctx->ca_names == NULL) ? 1 : ctx->ca_names->num + 1;
+        node->next = ctx->ca_names;
+        ctx->ca_names = node;
+        return SSL_SUCCESS;
+    }
+    #endif
+
+    #ifndef NO_WOLFSSL_STUB
+    int wolfSSL_CTX_set_default_verify_paths(WOLFSSL_CTX* ctx)
+    {
+        /* TODO:, not needed in goahead */
+        (void)ctx;
+        WOLFSSL_STUB("SSL_CTX_set_default_verify_paths");
+        return SSL_NOT_IMPLEMENTED;
+    }
+    #endif
+
+    #if defined(WOLFCRYPT_HAVE_SRP) && !defined(NO_SHA256) \
+        && !defined(WC_NO_RNG)
+    static const byte srp_N[] = {
+        0xEE, 0xAF, 0x0A, 0xB9, 0xAD, 0xB3, 0x8D, 0xD6, 0x9C, 0x33, 0xF8,
+        0x0A, 0xFA, 0x8F, 0xC5, 0xE8, 0x60, 0x72, 0x61, 0x87, 0x75, 0xFF,
+        0x3C, 0x0B, 0x9E, 0xA2, 0x31, 0x4C, 0x9C, 0x25, 0x65, 0x76, 0xD6,
+        0x74, 0xDF, 0x74, 0x96, 0xEA, 0x81, 0xD3, 0x38, 0x3B, 0x48, 0x13,
+        0xD6, 0x92, 0xC6, 0xE0, 0xE0, 0xD5, 0xD8, 0xE2, 0x50, 0xB9, 0x8B,
+        0xE4, 0x8E, 0x49, 0x5C, 0x1D, 0x60, 0x89, 0xDA, 0xD1, 0x5D, 0xC7,
+        0xD7, 0xB4, 0x61, 0x54, 0xD6, 0xB6, 0xCE, 0x8E, 0xF4, 0xAD, 0x69,
+        0xB1, 0x5D, 0x49, 0x82, 0x55, 0x9B, 0x29, 0x7B, 0xCF, 0x18, 0x85,
+        0xC5, 0x29, 0xF5, 0x66, 0x66, 0x0E, 0x57, 0xEC, 0x68, 0xED, 0xBC,
+        0x3C, 0x05, 0x72, 0x6C, 0xC0, 0x2F, 0xD4, 0xCB, 0xF4, 0x97, 0x6E,
+        0xAA, 0x9A, 0xFD, 0x51, 0x38, 0xFE, 0x83, 0x76, 0x43, 0x5B, 0x9F,
+        0xC6, 0x1D, 0x2F, 0xC0, 0xEB, 0x06, 0xE3
+    };
+    static const byte srp_g[] = {
+        0x02
+    };
+
+    int wolfSSL_CTX_set_srp_username(WOLFSSL_CTX* ctx, char* username)
+    {
+        int r = 0;
+        SrpSide srp_side = SRP_CLIENT_SIDE;
+        WC_RNG rng;
+        byte salt[SRP_SALT_SIZE];
+
+        WOLFSSL_ENTER("wolfSSL_CTX_set_srp_username");
+        if (ctx == NULL || ctx->srp == NULL || username==NULL)
+            return SSL_FAILURE;
+
+        if (ctx->method->side == WOLFSSL_SERVER_END){
+            srp_side = SRP_SERVER_SIDE;
+        } else if (ctx->method->side == WOLFSSL_CLIENT_END){
+            srp_side = SRP_CLIENT_SIDE;
+        } else {
+            WOLFSSL_MSG("Init CTX failed");
+            return SSL_FAILURE;
+        }
+
+        if (wc_SrpInit(ctx->srp, SRP_TYPE_SHA256, srp_side) < 0){
+            WOLFSSL_MSG("Init CTX failed");
+            XFREE(ctx->srp, ctx->heap, DYNAMIC_TYPE_SRP);
+            wolfSSL_CTX_free(ctx);
+            return SSL_FAILURE;
+        }
+        r = wc_SrpSetUsername(ctx->srp, (const byte*)username,
+                              (word32)XSTRLEN(username));
+        if (r < 0) {
+            WOLFSSL_MSG("fail to set srp username.");
+            return SSL_FAILURE;
+        }
+
+        /* if wolfSSL_CTX_set_srp_password has already been called, */
+        /* execute wc_SrpSetPassword here */
+        if (ctx->srp_password != NULL){
+            if (wc_InitRng(&rng) < 0){
+                WOLFSSL_MSG("wc_InitRng failed");
+                return SSL_FAILURE;
+            }
+            XMEMSET(salt, 0, sizeof(salt)/sizeof(salt[0]));
+            if (wc_RNG_GenerateBlock(&rng, salt,
+                                     sizeof(salt)/sizeof(salt[0])) <  0){
+                WOLFSSL_MSG("wc_RNG_GenerateBlock failed");
+                wc_FreeRng(&rng);
+                return SSL_FAILURE;
+            }
+            if (wc_SrpSetParams(ctx->srp, srp_N, sizeof(srp_N)/sizeof(srp_N[0]),
+                                srp_g, sizeof(srp_g)/sizeof(srp_g[0]),
+                                salt, sizeof(salt)/sizeof(salt[0])) < 0){
+                WOLFSSL_MSG("wc_SrpSetParam failed");
+                wc_FreeRng(&rng);
+                return SSL_FAILURE;
+            }
+            r = wc_SrpSetPassword(ctx->srp,
+                     (const byte*)ctx->srp_password,
+                     (word32)XSTRLEN((char *)ctx->srp_password));
+            if (r < 0) {
+                WOLFSSL_MSG("fail to set srp password.");
+                return SSL_FAILURE;
+            }
+            wc_FreeRng(&rng);
+            XFREE(ctx->srp_password, ctx->heap, DYNAMIC_TYPE_SRP);
+            ctx->srp_password = NULL;
+        }
+
+        return SSL_SUCCESS;
+    }
+
+    int wolfSSL_CTX_set_srp_password(WOLFSSL_CTX* ctx, char* password)
+    {
+        int r;
+        WC_RNG rng;
+        byte salt[SRP_SALT_SIZE];
+
+        WOLFSSL_ENTER("wolfSSL_CTX_set_srp_password");
+        if (ctx == NULL || ctx->srp == NULL || password == NULL)
+            return SSL_FAILURE;
+
+        if (ctx->srp->user != NULL){
+            if (wc_InitRng(&rng) < 0){
+                WOLFSSL_MSG("wc_InitRng failed");
+                return SSL_FAILURE;
+            }
+            XMEMSET(salt, 0, sizeof(salt)/sizeof(salt[0]));
+            if (wc_RNG_GenerateBlock(&rng, salt,
+                                     sizeof(salt)/sizeof(salt[0])) <  0){
+                WOLFSSL_MSG("wc_RNG_GenerateBlock failed");
+                wc_FreeRng(&rng);
+                return SSL_FAILURE;
+            }
+            if (wc_SrpSetParams(ctx->srp, srp_N, sizeof(srp_N)/sizeof(srp_N[0]),
+                                srp_g, sizeof(srp_g)/sizeof(srp_g[0]),
+                                salt, sizeof(salt)/sizeof(salt[0])) < 0){
+                WOLFSSL_MSG("wc_SrpSetParam failed");
+                wc_FreeRng(&rng);
+                return SSL_FAILURE;
+            }
+            r = wc_SrpSetPassword(ctx->srp, (const byte*)password,
+                                  (word32)XSTRLEN(password));
+            if (r < 0) {
+                WOLFSSL_MSG("wc_SrpSetPassword failed.");
+                wc_FreeRng(&rng);
+                return SSL_FAILURE;
+            }
+            if (ctx->srp_password != NULL){
+                XFREE(ctx->srp_password,NULL,
+                      DYNAMIC_TYPE_SRP);
+                ctx->srp_password = NULL;
+            }
+            wc_FreeRng(&rng);
+        } else {
+            /* save password for wolfSSL_set_srp_username */
+            if (ctx->srp_password != NULL)
+                XFREE(ctx->srp_password,ctx->heap, DYNAMIC_TYPE_SRP);
+
+            ctx->srp_password = (byte*)XMALLOC(XSTRLEN(password) + 1, ctx->heap,
+                                               DYNAMIC_TYPE_SRP);
+            if (ctx->srp_password == NULL){
+                WOLFSSL_MSG("memory allocation error");
+                return SSL_FAILURE;
+            }
+            XMEMCPY(ctx->srp_password, password, XSTRLEN(password) + 1);
+        }
+        return SSL_SUCCESS;
+    }
+    #endif /* WOLFCRYPT_HAVE_SRP && !NO_SHA256 && !WC_NO_RNG */
+
+    /* keyblock size in bytes or -1 */
+    int wolfSSL_get_keyblock_size(WOLFSSL* ssl)
+    {
+        if (ssl == NULL)
+            return WOLFSSL_FATAL_ERROR;
+
+        return 2 * (ssl->specs.key_size + ssl->specs.iv_size +
+                    ssl->specs.hash_size);
+    }
+
+
+    /* store keys returns WOLFSSL_SUCCESS or -1 on error */
+    int wolfSSL_get_keys(WOLFSSL* ssl, unsigned char** ms, unsigned int* msLen,
+                                     unsigned char** sr, unsigned int* srLen,
+                                     unsigned char** cr, unsigned int* crLen)
+    {
+        if (ssl == NULL || ssl->arrays == NULL)
+            return WOLFSSL_FATAL_ERROR;
+
+        *ms = ssl->arrays->masterSecret;
+        *sr = ssl->arrays->serverRandom;
+        *cr = ssl->arrays->clientRandom;
+
+        *msLen = SECRET_LEN;
+        *srLen = RAN_LEN;
+        *crLen = RAN_LEN;
+
+        return WOLFSSL_SUCCESS;
+    }
+
+#endif /* OPENSSL_EXTRA */
+
+#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_EXTRA)
+    void wolfSSL_set_accept_state(WOLFSSL* ssl)
+    {
+        WOLFSSL_ENTER("wolfSSL_set_accept_state");
+        if (ssl->options.side == WOLFSSL_CLIENT_END) {
+    #ifdef HAVE_ECC
+            ecc_key key;
+            word32 idx = 0;
+
+            if (ssl->options.haveStaticECC && ssl->buffers.key != NULL) {
+                if (wc_ecc_init(&key) >= 0) {
+                    if (wc_EccPrivateKeyDecode(ssl->buffers.key->buffer, &idx, &key,
+                                                   ssl->buffers.key->length) != 0) {
+                        ssl->options.haveECDSAsig = 0;
+                        ssl->options.haveECC = 0;
+                        ssl->options.haveStaticECC = 0;
+                    }
+                    wc_ecc_free(&key);
+                }
+            }
+    #endif
+
+    #ifndef NO_DH
+            if (!ssl->options.haveDH && ssl->ctx->haveDH) {
+                ssl->buffers.serverDH_P = ssl->ctx->serverDH_P;
+                ssl->buffers.serverDH_G = ssl->ctx->serverDH_G;
+                ssl->options.haveDH = 1;
+            }
+    #endif
+        }
+
+        if (InitSSL_Side(ssl, WOLFSSL_SERVER_END) != WOLFSSL_SUCCESS) {
+            WOLFSSL_MSG("Error initializing server side");
+        }
+    }
+
+#endif /* OPENSSL_EXTRA || WOLFSSL_EXTRA */
+
+    /* return true if connection established */
+    int wolfSSL_is_init_finished(WOLFSSL* ssl)
+    {
+        if (ssl == NULL)
+            return 0;
+
+        if (ssl->options.handShakeState == HANDSHAKE_DONE)
+            return 1;
+
+        return 0;
+    }
+
+#ifdef OPENSSL_EXTRA
+
+    void wolfSSL_CTX_set_tmp_rsa_callback(WOLFSSL_CTX* ctx,
+                                      WOLFSSL_RSA*(*f)(WOLFSSL*, int, int))
+    {
+        /* wolfSSL verifies all these internally */
+        (void)ctx;
+        (void)f;
+    }
+
+
+    void wolfSSL_set_shutdown(WOLFSSL* ssl, int opt)
+    {
+        WOLFSSL_ENTER("wolfSSL_set_shutdown");
+        if(ssl==NULL) {
+            WOLFSSL_MSG("Shutdown not set. ssl is null");
+            return;
+        }
+
+        ssl->options.sentNotify =  (opt&WOLFSSL_SENT_SHUTDOWN) > 0;
+        ssl->options.closeNotify = (opt&WOLFSSL_RECEIVED_SHUTDOWN) > 0;
+    }
+
+
+    long wolfSSL_CTX_get_options(WOLFSSL_CTX* ctx)
+    {
+        WOLFSSL_ENTER("wolfSSL_CTX_get_options");
+        WOLFSSL_MSG("wolfSSL options are set through API calls and macros");
+        if(ctx == NULL)
+            return BAD_FUNC_ARG;
+        return ctx->mask;
+    }
+
+#endif
+
+#if defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER)
+
+    static long wolf_set_options(long old_op, long op);
+    long wolfSSL_CTX_set_options(WOLFSSL_CTX* ctx, long opt)
+    {
+        WOLFSSL_ENTER("SSL_CTX_set_options");
+
+        if (ctx == NULL)
+            return BAD_FUNC_ARG;
+
+        ctx->mask = wolf_set_options(ctx->mask, opt);
+
+        return ctx->mask;
+    }
+
+#endif
+
+#ifdef OPENSSL_EXTRA
+
+    long wolfSSL_CTX_clear_options(WOLFSSL_CTX* ctx, long opt)
+    {
+        WOLFSSL_ENTER("SSL_CTX_clear_options");
+        if(ctx == NULL)
+            return BAD_FUNC_ARG;
+        ctx->mask &= ~opt;
+        return ctx->mask;
+    }
+
+    int wolfSSL_set_rfd(WOLFSSL* ssl, int rfd)
+    {
+        WOLFSSL_ENTER("SSL_set_rfd");
+        ssl->rfd = rfd;      /* not used directly to allow IO callbacks */
+
+        ssl->IOCB_ReadCtx  = &ssl->rfd;
+
+        return WOLFSSL_SUCCESS;
+    }
+
+
+    int wolfSSL_set_wfd(WOLFSSL* ssl, int wfd)
+    {
+        WOLFSSL_ENTER("SSL_set_wfd");
+        ssl->wfd = wfd;      /* not used directly to allow IO callbacks */
+
+        ssl->IOCB_WriteCtx  = &ssl->wfd;
+
+        return WOLFSSL_SUCCESS;
+    }
+
+#ifndef NO_CERTS
+
+    WOLFSSL_X509_STORE* wolfSSL_CTX_get_cert_store(WOLFSSL_CTX* ctx)
+    {
+        if (ctx == NULL) {
+            return NULL;
+        }
+
+        return &ctx->x509_store;
+    }
+
+    void wolfSSL_CTX_set_cert_store(WOLFSSL_CTX* ctx, WOLFSSL_X509_STORE* str)
+    {
+        if (ctx == NULL || str == NULL) {
+            return;
+        }
+
+        /* free cert manager if have one */
+        if (ctx->cm != NULL) {
+            wolfSSL_CertManagerFree(ctx->cm);
+        }
+        ctx->cm               = str->cm;
+
+        /* free existing store if it exists */
+        if (ctx->x509_store_pt != NULL) {
+            /* cert manager was free'd a little earlier in this function */
+            ctx->x509_store_pt->cm = NULL;
+        }
+        wolfSSL_X509_STORE_free(ctx->x509_store_pt);
+        ctx->x509_store.cache = str->cache;
+        ctx->x509_store_pt    = str; /* take ownership of store and free it
+                                        with CTX free */
+    }
+
+
+    WOLFSSL_X509* wolfSSL_X509_STORE_CTX_get_current_cert(
+                                                    WOLFSSL_X509_STORE_CTX* ctx)
+    {
+        WOLFSSL_ENTER("wolfSSL_X509_STORE_CTX_get_current_cert");
+        if (ctx)
+            return ctx->current_cert;
+        return NULL;
+    }
+
+
+    int wolfSSL_X509_STORE_CTX_get_error(WOLFSSL_X509_STORE_CTX* ctx)
+    {
+        WOLFSSL_ENTER("wolfSSL_X509_STORE_CTX_get_error");
+        if (ctx != NULL)
+            return ctx->error;
+        return 0;
+    }
+
+
+    int wolfSSL_X509_STORE_CTX_get_error_depth(WOLFSSL_X509_STORE_CTX* ctx)
+    {
+        WOLFSSL_ENTER("wolfSSL_X509_STORE_CTX_get_error_depth");
+        if(ctx)
+            return ctx->error_depth;
+        return WOLFSSL_FATAL_ERROR;
+    }
+
+    void wolfSSL_X509_STORE_CTX_set_verify_cb(WOLFSSL_X509_STORE_CTX *ctx,
+                                  WOLFSSL_X509_STORE_CTX_verify_cb verify_cb)
+    {
+        WOLFSSL_ENTER("wolfSSL_X509_STORE_CTX_set_verify_cb");
+        if(ctx == NULL)
+            return;
+        ctx->verify_cb = verify_cb;
+    }
+
+#if defined(WOLFSSL_QT) || defined(OPENSSL_ALL)
+    void wolfSSL_X509_STORE_set_verify_cb(WOLFSSL_X509_STORE *st,
+                                 WOLFSSL_X509_STORE_CTX_verify_cb verify_cb)
+    {
+        WOLFSSL_ENTER("WOLFSSL_X509_STORE_set_verify_cb");
+        if (st != NULL) {
+            st->verify_cb = verify_cb;
+        }
+    }
+#endif
+
+
+#endif /* !NO_CERTS */
+
+    WOLFSSL_BIO_METHOD* wolfSSL_BIO_f_md(void)
+    {
+        static WOLFSSL_BIO_METHOD meth;
+
+        WOLFSSL_ENTER("wolfSSL_BIO_f_md");
+        meth.type = WOLFSSL_BIO_MD;
+
+        return &meth;
+    }
+
+    /* return the context and initialize the BIO state */
+    int wolfSSL_BIO_get_md_ctx(WOLFSSL_BIO *bio, WOLFSSL_EVP_MD_CTX **mdcp)
+    {
+        int ret = WOLFSSL_FAILURE;
+
+        if ((bio != NULL) && (mdcp != NULL)) {
+            *mdcp = (WOLFSSL_EVP_MD_CTX*)bio->ptr;
+            ret = WOLFSSL_SUCCESS;
+        }
+
+        return ret;
+    }
+
+    WOLFSSL_BIO_METHOD* wolfSSL_BIO_f_buffer(void)
+    {
+        static WOLFSSL_BIO_METHOD meth;
+
+        WOLFSSL_ENTER("BIO_f_buffer");
+        meth.type = WOLFSSL_BIO_BUFFER;
+
+        return &meth;
+    }
+
+    #ifndef NO_WOLFSSL_STUB
+    long wolfSSL_BIO_set_write_buffer_size(WOLFSSL_BIO* bio, long size)
+    {
+        /* wolfSSL has internal buffer, compatibility only */
+        WOLFSSL_ENTER("BIO_set_write_buffer_size");
+        WOLFSSL_STUB("BIO_set_write_buffer_size");
+        (void)bio;
+        return size;
+    }
+    #endif
+
+    WOLFSSL_BIO_METHOD* wolfSSL_BIO_s_bio(void)
+    {
+        static WOLFSSL_BIO_METHOD bio_meth;
+
+        WOLFSSL_ENTER("wolfSSL_BIO_s_bio");
+        bio_meth.type = WOLFSSL_BIO_BIO;
+
+        return &bio_meth;
+    }
+
+
+#ifndef NO_FILESYSTEM
+    WOLFSSL_BIO_METHOD* wolfSSL_BIO_s_file(void)
+    {
+        static WOLFSSL_BIO_METHOD file_meth;
+
+        WOLFSSL_ENTER("wolfSSL_BIO_s_file");
+        file_meth.type = WOLFSSL_BIO_FILE;
+
+        return &file_meth;
+    }
+#endif
+
+
+    WOLFSSL_BIO_METHOD* wolfSSL_BIO_f_ssl(void)
+    {
+        static WOLFSSL_BIO_METHOD meth;
+
+        WOLFSSL_ENTER("wolfSSL_BIO_f_ssl");
+        meth.type = WOLFSSL_BIO_SSL;
+
+        return &meth;
+    }
+
+
+    WOLFSSL_BIO_METHOD *wolfSSL_BIO_s_socket(void)
+    {
+        static WOLFSSL_BIO_METHOD meth;
+
+        WOLFSSL_ENTER("wolfSSL_BIO_s_socket");
+        meth.type = WOLFSSL_BIO_SOCKET;
+
+        return &meth;
+    }
+
+
+    WOLFSSL_BIO* wolfSSL_BIO_new_socket(int sfd, int closeF)
+    {
+        WOLFSSL_BIO* bio = wolfSSL_BIO_new(wolfSSL_BIO_s_socket());
+
+        WOLFSSL_ENTER("BIO_new_socket");
+        if (bio) {
+            bio->type  = WOLFSSL_BIO_SOCKET;
+            bio->shutdown = (byte)closeF;
+            bio->num   = sfd;
+        }
+        return bio;
+    }
+
+
+    int wolfSSL_BIO_eof(WOLFSSL_BIO* b)
+    {
+        WOLFSSL_ENTER("BIO_eof");
+        if ((b != NULL) && (b->eof))
+            return 1;
+
+        return 0;
+    }
+
+
+    long wolfSSL_BIO_set_ssl(WOLFSSL_BIO* b, WOLFSSL* ssl, int closeF)
+    {
+        WOLFSSL_ENTER("wolfSSL_BIO_set_ssl");
+
+        if (b != NULL) {
+            b->ptr   = ssl;
+            b->shutdown = (byte)closeF;
+    /* add to ssl for bio free if SSL_free called before/instead of free_all? */
+        }
+
+        return 0;
+    }
+
+#ifndef NO_FILESYSTEM
+    long wolfSSL_BIO_set_fd(WOLFSSL_BIO* b, int fd, int closeF)
+    {
+        WOLFSSL_ENTER("wolfSSL_BIO_set_fd");
+
+        if (b != NULL) {
+            b->num = fd;
+            b->shutdown = (byte)closeF;
+        }
+
+        return WOLFSSL_SUCCESS;
+    }
+#endif
+
+    /* Sets the close flag */
+    int wolfSSL_BIO_set_close(WOLFSSL_BIO *b, long flag)
+    {
+        WOLFSSL_ENTER("wolfSSL_BIO_set_close");
+        if (b != NULL) {
+            b->shutdown = (byte)flag;
+        }
+
+        return WOLFSSL_SUCCESS;
+    }
+
+
+    WOLFSSL_BIO* wolfSSL_BIO_new(WOLFSSL_BIO_METHOD* method)
+    {
+        WOLFSSL_BIO* bio;
+
+        WOLFSSL_ENTER("wolfSSL_BIO_new");
+        if (method == NULL) {
+            WOLFSSL_MSG("Bad method pointer passed in");
+            return NULL;
+        }
+
+        bio = (WOLFSSL_BIO*) XMALLOC(sizeof(WOLFSSL_BIO), 0,
+                DYNAMIC_TYPE_OPENSSL);
+        if (bio) {
+            XMEMSET(bio, 0, sizeof(WOLFSSL_BIO));
+            bio->type = (byte)method->type;
+            bio->method = method;
+            bio->shutdown = BIO_CLOSE; /* default to close things */
+            bio->init = 1;
+            if (method->type != WOLFSSL_BIO_FILE &&
+                    method->type != WOLFSSL_BIO_SOCKET &&
+                    method->type != WOLFSSL_BIO_MD) {
+                bio->mem_buf =(WOLFSSL_BUF_MEM*)XMALLOC(sizeof(WOLFSSL_BUF_MEM),
+                                                       0, DYNAMIC_TYPE_OPENSSL);
+                if (bio->mem_buf == NULL) {
+                    WOLFSSL_MSG("Memory error");
+                    wolfSSL_BIO_free(bio);
+                    return NULL;
+                }
+                bio->mem_buf->data = (char*)bio->ptr;
+            }
+
+            if (method->type == WOLFSSL_BIO_MD) {
+                bio->ptr = wolfSSL_EVP_MD_CTX_new();
+                if (bio->ptr == NULL) {
+                    WOLFSSL_MSG("Memory error");
+                    wolfSSL_BIO_free(bio);
+                    return NULL;
+                }
+            }
+
+            /* check if is custom method */
+            if (method->createCb) {
+                method->createCb(bio);
+            }
+        }
+        return bio;
+    }
+
+    WOLFSSL_BIO* wolfSSL_BIO_new_mem_buf(const void* buf, int len)
+    {
+        WOLFSSL_BIO* bio = NULL;
+
+        if (buf == NULL || len < 0) {
+            return bio;
+        }
+
+        bio = wolfSSL_BIO_new(wolfSSL_BIO_s_mem());
+        if (bio == NULL) {
+            return bio;
+        }
+
+        bio->num = bio->wrSz = len;
+        bio->ptr = (byte*)XMALLOC(len, 0, DYNAMIC_TYPE_OPENSSL);
+        if (bio->ptr == NULL) {
+            wolfSSL_BIO_free(bio);
+            return NULL;
+        }
+        if (bio->mem_buf != NULL) {
+            bio->mem_buf->data = (char*)bio->ptr;
+            bio->mem_buf->length = bio->num;
+        }
+
+        XMEMCPY(bio->ptr, buf, len);
+
+        return bio;
+    }
+
+    /*
+     * Note : If the flag BIO_NOCLOSE is set then freeing memory buffers is up
+     *        to the application.
+     * Returns 1 on success, 0 on failure
+     */
+    int wolfSSL_BIO_free(WOLFSSL_BIO* bio)
+    {
+        int ret;
+
+        /* unchain?, doesn't matter in goahead since from free all */
+        WOLFSSL_ENTER("wolfSSL_BIO_free");
+        if (bio) {
+
+            if (bio->infoCb) {
+                /* info callback is called before free */
+                ret = (int)bio->infoCb(bio, WOLFSSL_BIO_CB_FREE, NULL, 0, 0, 1);
+                if (ret <= 0) {
+                    return ret;
+                }
+            }
+
+            /* call custom set free callback */
+            if (bio->method && bio->method->freeCb) {
+                bio->method->freeCb(bio);
+            }
+
+            /* remove from pair by setting the paired bios pair to NULL */
+            if (bio->pair != NULL) {
+                bio->pair->pair = NULL;
+            }
+
+            if (bio->shutdown) {
+                if (bio->type == WOLFSSL_BIO_SSL && bio->ptr)
+                    wolfSSL_free((WOLFSSL*)bio->ptr);
+            #ifdef CloseSocket
+                if (bio->type == WOLFSSL_BIO_SOCKET && bio->num)
+                    CloseSocket(bio->num);
+            #endif
+            }
+
+        #ifndef NO_FILESYSTEM
+            if (bio->type == WOLFSSL_BIO_FILE && bio->shutdown == BIO_CLOSE) {
+                if (bio->ptr) {
+                    XFCLOSE((XFILE)bio->ptr);
+                }
+            }
+        #endif
+
+            if (bio->shutdown != BIO_NOCLOSE) {
+                if (bio->type == WOLFSSL_BIO_MEMORY && bio->ptr != NULL) {
+                    if (bio->mem_buf != NULL) {
+                        if (bio->mem_buf->data != (char*)bio->ptr) {
+                            XFREE(bio->ptr, bio->heap, DYNAMIC_TYPE_OPENSSL);
+                            bio->ptr = NULL;
+                        }
+                    }
+                    else {
+                        XFREE(bio->ptr, bio->heap, DYNAMIC_TYPE_OPENSSL);
+                        bio->ptr = NULL;
+                    }
+                }
+                if (bio->mem_buf != NULL) {
+                    wolfSSL_BUF_MEM_free(bio->mem_buf);
+                    bio->mem_buf = NULL;
+                }
+            }
+
+            if (bio->type == WOLFSSL_BIO_MD) {
+                wolfSSL_EVP_MD_CTX_free((WOLFSSL_EVP_MD_CTX*)bio->ptr);
+            }
+
+            XFREE(bio, 0, DYNAMIC_TYPE_OPENSSL);
+        }
+        return 1;
+    }
+
+    /* like BIO_free, but no return value */
+    void wolfSSL_BIO_vfree(WOLFSSL_BIO* bio)
+    {
+        wolfSSL_BIO_free(bio);
+    }
+
+
+    int wolfSSL_BIO_free_all(WOLFSSL_BIO* bio)
+    {
+        WOLFSSL_ENTER("BIO_free_all");
+        while (bio) {
+            WOLFSSL_BIO* next = bio->next;
+            wolfSSL_BIO_free(bio);
+            bio = next;
+        }
+        return 0;
+    }
+
+
+    WOLFSSL_BIO* wolfSSL_BIO_push(WOLFSSL_BIO* top, WOLFSSL_BIO* append)
+    {
+        WOLFSSL_ENTER("BIO_push");
+        top->next    = append;
+        append->prev = top;
+
+        return top;
+    }
+#endif /* OPENSSL_EXTRA */
+
+#ifdef WOLFSSL_ENCRYPTED_KEYS
+
+    void wolfSSL_CTX_set_default_passwd_cb_userdata(WOLFSSL_CTX* ctx,
+                                                   void* userdata)
+    {
+        WOLFSSL_ENTER("SSL_CTX_set_default_passwd_cb_userdata");
+        if (ctx)
+            ctx->passwd_userdata = userdata;
+    }
+
+
+    void wolfSSL_CTX_set_default_passwd_cb(WOLFSSL_CTX* ctx,pem_password_cb* cb)
+    {
+        WOLFSSL_ENTER("SSL_CTX_set_default_passwd_cb");
+        if (ctx)
+            ctx->passwd_cb = cb;
+    }
+
+    pem_password_cb* wolfSSL_CTX_get_default_passwd_cb(WOLFSSL_CTX *ctx)
+    {
+        if (ctx == NULL || ctx->passwd_cb == NULL) {
+            return NULL;
+        }
+
+        return ctx->passwd_cb;
+    }
+
+
+    void* wolfSSL_CTX_get_default_passwd_cb_userdata(WOLFSSL_CTX *ctx)
+    {
+        if (ctx == NULL) {
+            return NULL;
+        }
+
+        return ctx->passwd_userdata;
+    }
+
+#endif /* WOLFSSL_ENCRYPTED_KEYS */
+
+
+#if defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER)
+    int wolfSSL_num_locks(void)
+    {
+        return 0;
+    }
+
+    void wolfSSL_set_locking_callback(void (*f)(int, int, const char*, int))
+    {
+        WOLFSSL_ENTER("wolfSSL_set_locking_callback");
+
+        if (wc_SetMutexCb(f) != 0) {
+            WOLFSSL_MSG("Error when setting mutex call back");
+        }
+    }
+
+
+    typedef unsigned long (idCb)(void);
+    static idCb* inner_idCb = NULL;
+
+    unsigned long wolfSSL_thread_id(void)
+    {
+        if (inner_idCb != NULL) {
+            return inner_idCb();
+        }
+        else {
+            return 0;
+        }
+    }
+
+
+    void wolfSSL_set_id_callback(unsigned long (*f)(void))
+    {
+        inner_idCb = f;
+    }
+
+    unsigned long wolfSSL_ERR_get_error(void)
+    {
+        WOLFSSL_ENTER("wolfSSL_ERR_get_error");
+
+#if defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY)
+        {
+            unsigned long ret = wolfSSL_ERR_peek_error_line_data(NULL, NULL,
+                                                                 NULL, NULL);
+            wc_RemoveErrorNode(-1);
+            return ret;
+        }
+#elif (defined(OPENSSL_EXTRA) || defined(DEBUG_WOLFSSL_VERBOSE))
+        {
+            int ret = wc_PullErrorNode(NULL, NULL, NULL);
+
+            if (ret < 0) {
+                if (ret == BAD_STATE_E) return 0; /* no errors in queue */
+                WOLFSSL_MSG("Error with pulling error node!");
+                WOLFSSL_LEAVE("wolfSSL_ERR_get_error", ret);
+                ret = 0 - ret; /* return absolute value of error */
+
+                /* panic and try to clear out nodes */
+                wc_ClearErrorNodes();
+            }
+
+            return (unsigned long)ret;
+        }
+#else
+        return (unsigned long)(0 - NOT_COMPILED_IN);
+#endif
+    }
+
+#if (defined(OPENSSL_EXTRA) || defined(DEBUG_WOLFSSL_VERBOSE))
+    /* print out and clear all errors */
+    void wolfSSL_ERR_print_errors(WOLFSSL_BIO* bio)
+    {
+        const char* file = NULL;
+        const char* reason = NULL;
+        int ret;
+        int line = 0;
+        char buf[WOLFSSL_MAX_ERROR_SZ * 2];
+
+        WOLFSSL_ENTER("wolfSSL_ERR_print_errors");
+
+        if (bio == NULL) {
+            WOLFSSL_MSG("BIO passed in was null");
+            return;
+        }
+
+        do {
+        ret = wc_PeekErrorNode(0, &file, &reason, &line);
+        if (ret >= 0) {
+            const char* r = wolfSSL_ERR_reason_error_string(0 - ret);
+            XSNPRINTF(buf, sizeof(buf), "error:%d:wolfSSL library:%s:%s:%d\n",
+                    ret, r, file, line);
+            wolfSSL_BIO_write(bio, buf, (int)XSTRLEN(buf));
+            wc_RemoveErrorNode(0);
+        }
+        } while (ret >= 0);
+    }
+#endif /* OPENSSL_EXTRA || DEBUG_WOLFSSL_VERBOSE */
+
+#endif /* OPENSSL_EXTRA || HAVE_WEBSERVER */
+
+#ifdef OPENSSL_EXTRA
+
+#if !defined(NO_WOLFSSL_SERVER)
+size_t wolfSSL_get_server_random(const WOLFSSL *ssl, unsigned char *out,
+                                                                   size_t outSz)
+{
+    size_t size;
+
+    /* return max size of buffer */
+    if (outSz == 0) {
+        return RAN_LEN;
+    }
+
+    if (ssl == NULL || out == NULL) {
+        return 0;
+    }
+
+    if (ssl->options.saveArrays == 0 || ssl->arrays == NULL) {
+        WOLFSSL_MSG("Arrays struct not saved after handshake");
+        return 0;
+    }
+
+    if (outSz > RAN_LEN) {
+        size = RAN_LEN;
+    }
+    else {
+        size = outSz;
+    }
+
+    XMEMCPY(out, ssl->arrays->serverRandom, size);
+    return size;
+}
+
+
+/* Used to get the peer ephemeral public key sent during the connection
+ * NOTE: currently wolfSSL_KeepHandshakeResources(WOLFSSL* ssl) must be called
+ *       before the ephemeral key is stored.
+ * return WOLFSSL_SUCCESS on success */
+int wolfSSL_get_server_tmp_key(const WOLFSSL* ssl, WOLFSSL_EVP_PKEY** pkey)
+{
+    WOLFSSL_EVP_PKEY* ret = NULL;
+
+    WOLFSSL_ENTER("wolfSSL_get_server_tmp_key");
+
+    if (ssl == NULL || pkey == NULL) {
+        WOLFSSL_MSG("Bad argument passed in");
+        return WOLFSSL_FAILURE;
+    }
+
+#ifdef HAVE_ECC
+    if (ssl->peerEccKey != NULL) {
+        unsigned char* der;
+        const unsigned char* pt;
+        unsigned int   derSz = 0;
+        int sz;
+
+        if (wc_ecc_export_x963(ssl->peerEccKey, NULL, &derSz) !=
+                LENGTH_ONLY_E) {
+            WOLFSSL_MSG("get ecc der size failed");
+            return WOLFSSL_FAILURE;
+        }
+
+        derSz += MAX_SEQ_SZ + (2 * MAX_ALGO_SZ) + MAX_SEQ_SZ + TRAILING_ZERO;
+        der = (unsigned char*)XMALLOC(derSz, ssl->heap, DYNAMIC_TYPE_KEY);
+        if (der == NULL) {
+            WOLFSSL_MSG("Memory error");
+            return WOLFSSL_FAILURE;
+        }
+
+        if ((sz = wc_EccPublicKeyToDer(ssl->peerEccKey, der, derSz, 1)) <= 0) {
+            WOLFSSL_MSG("get ecc der failed");
+            XFREE(der, ssl->heap, DYNAMIC_TYPE_KEY);
+            return WOLFSSL_FAILURE;
+        }
+        pt = der; /* in case pointer gets advanced */
+        ret = wolfSSL_d2i_PUBKEY(NULL, &pt, sz);
+        XFREE(der, ssl->heap, DYNAMIC_TYPE_KEY);
+    }
+#endif
+
+    *pkey = ret;
+    if (ret == NULL)
+        return WOLFSSL_FAILURE;
+    else
+        return WOLFSSL_SUCCESS;
+}
+
+#endif /* !NO_WOLFSSL_SERVER */
+
+int wolfSSL_CTX_set_min_proto_version(WOLFSSL_CTX* ctx, int version)
+{
+    WOLFSSL_ENTER("wolfSSL_CTX_set_min_proto_version");
+
+    if (ctx == NULL) {
+        return BAD_FUNC_ARG;
+    }
+
+    switch (version) {
+#if defined(WOLFSSL_ALLOW_SSLV3) && !defined(NO_OLD_TLS)
+        case SSL3_VERSION:
+            ctx->minDowngrade = SSLv3_MINOR;
+            break;
+#endif
+#ifndef NO_TLS
+    #ifndef NO_OLD_TLS
+        #ifdef WOLFSSL_ALLOW_TLSV10
+        case TLS1_VERSION:
+            ctx->minDowngrade = TLSv1_MINOR;
+            break;
+        #endif
+        case TLS1_1_VERSION:
+            ctx->minDowngrade = TLSv1_1_MINOR;
+            break;
+    #endif
+    #ifndef WOLFSSL_NO_TLS12
+        case TLS1_2_VERSION:
+            ctx->minDowngrade = TLSv1_2_MINOR;
+            break;
+    #endif
+    #ifdef WOLFSSL_TLS13
+        case TLS1_3_VERSION:
+            ctx->minDowngrade = TLSv1_3_MINOR;
+            break;
+    #endif
+#endif
+#ifdef WOLFSSL_DTLS
+    #ifndef NO_OLD_TLS
+        case DTLS1_VERSION:
+            ctx->minDowngrade = DTLS_MINOR;
+            break;
+    #endif
+        case DTLS1_2_VERSION:
+            ctx->minDowngrade = DTLSv1_2_MINOR;
+            break;
+#endif
+        default:
+            return BAD_FUNC_ARG;
+    }
+
+    return WOLFSSL_SUCCESS;
+}
+
+int wolfSSL_CTX_set_max_proto_version(WOLFSSL_CTX* ctx, int ver)
+{
+    WOLFSSL_ENTER("wolfSSL_CTX_set_max_proto_version");
+
+    /* supported only at compile-time only */
+    (void)ctx;
+    (void)ver;
+    return WOLFSSL_SUCCESS;
+}
+
+
+#if !defined(NO_WOLFSSL_CLIENT)
+/* Return the amount of random bytes copied over or error case.
+ * ssl : ssl struct after handshake
+ * out : buffer to hold random bytes
+ * outSz : either 0 (return max buffer sz) or size of out buffer
+ *
+ * NOTE: wolfSSL_KeepArrays(ssl) must be called to retain handshake information.
+ */
+size_t wolfSSL_get_client_random(const WOLFSSL* ssl, unsigned char* out,
+                                                                   size_t outSz)
+{
+    size_t size;
+
+    /* return max size of buffer */
+    if (outSz == 0) {
+        return RAN_LEN;
+    }
+
+    if (ssl == NULL || out == NULL) {
+        return 0;
+    }
+
+    if (ssl->options.saveArrays == 0 || ssl->arrays == NULL) {
+        WOLFSSL_MSG("Arrays struct not saved after handshake");
+        return 0;
+    }
+
+    if (outSz > RAN_LEN) {
+        size = RAN_LEN;
+    }
+    else {
+        size = outSz;
+    }
+
+    XMEMCPY(out, ssl->arrays->clientRandom, size);
+    return size;
+}
+#endif /* !NO_WOLFSSL_CLIENT */
+
+
+    unsigned long wolfSSLeay(void)
+    {
+        return SSLEAY_VERSION_NUMBER;
+    }
+
+    unsigned long wolfSSL_OpenSSL_version_num(void)
+    {
+        return OPENSSL_VERSION_NUMBER;
+    }
+
+    const char* wolfSSLeay_version(int type)
+    {
+        static const char* version = "SSLeay wolfSSL compatibility";
+        (void)type;
+        return version;
+    }
+
+
+#ifndef NO_MD5
+    int wolfSSL_MD5_Init(WOLFSSL_MD5_CTX* md5)
+    {
+        int ret;
+        typedef char md5_test[sizeof(MD5_CTX) >= sizeof(wc_Md5) ? 1 : -1];
+        (void)sizeof(md5_test);
+
+        WOLFSSL_ENTER("MD5_Init");
+        ret = wc_InitMd5((wc_Md5*)md5);
+
+        /* return 1 on success, 0 otherwise */
+        if (ret == 0)
+            return 1;
+
+        return 0;
+    }
+
+
+    int wolfSSL_MD5_Update(WOLFSSL_MD5_CTX* md5, const void* input,
+                           unsigned long sz)
+    {
+        int ret;
+
+        WOLFSSL_ENTER("wolfSSL_MD5_Update");
+        ret = wc_Md5Update((wc_Md5*)md5, (const byte*)input, (word32)sz);
+
+        /* return 1 on success, 0 otherwise */
+        if (ret == 0)
+            return 1;
+
+        return 0;
+    }
+
+
+    int wolfSSL_MD5_Final(byte* input, WOLFSSL_MD5_CTX* md5)
+    {
+        int ret;
+
+        WOLFSSL_ENTER("MD5_Final");
+        ret = wc_Md5Final((wc_Md5*)md5, input);
+
+        /* return 1 on success, 0 otherwise */
+        if (ret == 0)
+            return 1;
+
+        return 0;
+    }
+#endif /* !NO_MD5 */
+
+
+#ifndef NO_SHA
+    int wolfSSL_SHA_Init(WOLFSSL_SHA_CTX* sha)
+    {
+        int ret;
+
+        typedef char sha_test[sizeof(SHA_CTX) >= sizeof(wc_Sha) ? 1 : -1];
+        (void)sizeof(sha_test);
+
+        WOLFSSL_ENTER("SHA_Init");
+        ret = wc_InitSha((wc_Sha*)sha);
+
+        /* return 1 on success, 0 otherwise */
+        if (ret == 0)
+            return 1;
+
+        return 0;
+    }
+
+
+    int wolfSSL_SHA_Update(WOLFSSL_SHA_CTX* sha, const void* input,
+                           unsigned long sz)
+    {
+        int ret;
+
+        WOLFSSL_ENTER("SHA_Update");
+        ret = wc_ShaUpdate((wc_Sha*)sha, (const byte*)input, (word32)sz);
+
+        /* return 1 on success, 0 otherwise */
+        if (ret == 0)
+            return 1;
+
+        return 0;
+    }
+
+
+    int wolfSSL_SHA_Final(byte* input, WOLFSSL_SHA_CTX* sha)
+    {
+        int ret;
+
+        WOLFSSL_ENTER("SHA_Final");
+        ret = wc_ShaFinal((wc_Sha*)sha, input);
+
+        /* return 1 on success, 0 otherwise */
+        if (ret == 0)
+            return 1;
+
+        return 0;
+    }
+
+
+    int wolfSSL_SHA1_Init(WOLFSSL_SHA_CTX* sha)
+    {
+        WOLFSSL_ENTER("SHA1_Init");
+        return SHA_Init(sha);
+    }
+
+
+    int wolfSSL_SHA1_Update(WOLFSSL_SHA_CTX* sha, const void* input,
+                            unsigned long sz)
+    {
+        WOLFSSL_ENTER("SHA1_Update");
+        return SHA_Update(sha, input, sz);
+    }
+
+
+    int wolfSSL_SHA1_Final(byte* input, WOLFSSL_SHA_CTX* sha)
+    {
+        WOLFSSL_ENTER("SHA1_Final");
+        return SHA_Final(input, sha);
+    }
+#endif /* !NO_SHA */
+
+#ifdef WOLFSSL_SHA224
+
+    int wolfSSL_SHA224_Init(WOLFSSL_SHA224_CTX* sha)
+    {
+        int ret;
+
+        typedef char sha_test[sizeof(SHA224_CTX) >= sizeof(wc_Sha224) ? 1 : -1];
+        (void)sizeof(sha_test);
+
+        WOLFSSL_ENTER("SHA224_Init");
+        ret = wc_InitSha224((wc_Sha224*)sha);
+
+        /* return 1 on success, 0 otherwise */
+        if (ret == 0)
+            return 1;
+
+        return 0;
+    }
+
+
+    int wolfSSL_SHA224_Update(WOLFSSL_SHA224_CTX* sha, const void* input,
+                           unsigned long sz)
+    {
+        int ret;
+
+        WOLFSSL_ENTER("SHA224_Update");
+        ret = wc_Sha224Update((wc_Sha224*)sha, (const byte*)input, (word32)sz);
+
+        /* return 1 on success, 0 otherwise */
+        if (ret == 0)
+            return 1;
+
+        return 0;
+    }
+
+
+    int wolfSSL_SHA224_Final(byte* input, WOLFSSL_SHA224_CTX* sha)
+    {
+        int ret;
+
+        WOLFSSL_ENTER("SHA224_Final");
+        ret = wc_Sha224Final((wc_Sha224*)sha, input);
+
+        /* return 1 on success, 0 otherwise */
+        if (ret == 0)
+            return 1;
+
+        return 0;
+    }
+
+#endif /* WOLFSSL_SHA224 */
+
+
+    int wolfSSL_SHA256_Init(WOLFSSL_SHA256_CTX* sha256)
+    {
+        int ret;
+
+        typedef char sha_test[sizeof(SHA256_CTX) >= sizeof(wc_Sha256) ? 1 : -1];
+        (void)sizeof(sha_test);
+
+        WOLFSSL_ENTER("SHA256_Init");
+        ret = wc_InitSha256((wc_Sha256*)sha256);
+
+        /* return 1 on success, 0 otherwise */
+        if (ret == 0)
+            return 1;
+
+        return 0;
+    }
+
+
+    int wolfSSL_SHA256_Update(WOLFSSL_SHA256_CTX* sha, const void* input,
+                              unsigned long sz)
+    {
+        int ret;
+
+        WOLFSSL_ENTER("SHA256_Update");
+        ret = wc_Sha256Update((wc_Sha256*)sha, (const byte*)input, (word32)sz);
+
+        /* return 1 on success, 0 otherwise */
+        if (ret == 0)
+            return 1;
+
+        return 0;
+    }
+
+
+    int wolfSSL_SHA256_Final(byte* input, WOLFSSL_SHA256_CTX* sha)
+    {
+        int ret;
+
+        WOLFSSL_ENTER("SHA256_Final");
+        ret = wc_Sha256Final((wc_Sha256*)sha, input);
+
+        /* return 1 on success, 0 otherwise */
+        if (ret == 0)
+            return 1;
+
+        return 0;
+    }
+
+
+#ifdef WOLFSSL_SHA384
+
+    int wolfSSL_SHA384_Init(WOLFSSL_SHA384_CTX* sha)
+    {
+        int ret;
+
+        typedef char sha_test[sizeof(SHA384_CTX) >= sizeof(wc_Sha384) ? 1 : -1];
+        (void)sizeof(sha_test);
+
+        WOLFSSL_ENTER("SHA384_Init");
+        ret = wc_InitSha384((wc_Sha384*)sha);
+
+        /* return 1 on success, 0 otherwise */
+        if (ret == 0)
+            return 1;
+
+        return 0;
+    }
+
+
+    int wolfSSL_SHA384_Update(WOLFSSL_SHA384_CTX* sha, const void* input,
+                           unsigned long sz)
+    {
+        int ret;
+
+        WOLFSSL_ENTER("SHA384_Update");
+        ret = wc_Sha384Update((wc_Sha384*)sha, (const byte*)input, (word32)sz);
+
+        /* return 1 on success, 0 otherwise */
+        if (ret == 0)
+            return 1;
+
+        return 0;
+    }
+
+
+    int wolfSSL_SHA384_Final(byte* input, WOLFSSL_SHA384_CTX* sha)
+    {
+        int ret;
+
+        WOLFSSL_ENTER("SHA384_Final");
+        ret = wc_Sha384Final((wc_Sha384*)sha, input);
+
+        /* return 1 on success, 0 otherwise */
+        if (ret == 0)
+            return 1;
+
+        return 0;
+    }
+
+#endif /* WOLFSSL_SHA384 */
+
+
+#ifdef WOLFSSL_SHA512
+
+    int wolfSSL_SHA512_Init(WOLFSSL_SHA512_CTX* sha)
+    {
+        int ret;
+
+        typedef char sha_test[sizeof(SHA512_CTX) >= sizeof(wc_Sha512) ? 1 : -1];
+        (void)sizeof(sha_test);
+
+        WOLFSSL_ENTER("SHA512_Init");
+        ret = wc_InitSha512((wc_Sha512*)sha);
+
+        /* return 1 on success, 0 otherwise */
+        if (ret == 0)
+            return 1;
+
+        return 0;
+    }
+
+
+    int wolfSSL_SHA512_Update(WOLFSSL_SHA512_CTX* sha, const void* input,
+                           unsigned long sz)
+    {
+        int ret;
+
+        WOLFSSL_ENTER("SHA512_Update");
+        ret = wc_Sha512Update((wc_Sha512*)sha, (const byte*)input, (word32)sz);
+
+        /* return 1 on success, 0 otherwise */
+        if (ret == 0)
+            return 1;
+
+        return 0;
+    }
+
+
+    int wolfSSL_SHA512_Final(byte* input, WOLFSSL_SHA512_CTX* sha)
+    {
+        int ret;
+
+        WOLFSSL_ENTER("SHA512_Final");
+        ret = wc_Sha512Final((wc_Sha512*)sha, input);
+
+        /* return 1 on success, 0 otherwise */
+        if (ret == 0)
+            return 1;
+
+        return 0;
+    }
+
+#endif /* WOLFSSL_SHA512 */
+
+#ifdef WOLFSSL_SHA3
+#ifndef WOLFSSL_NOSHA3_224
+
+    int wolfSSL_SHA3_224_Init(WOLFSSL_SHA3_224_CTX* sha)
+    {
+        int ret;
+
+        typedef char sha_test[sizeof(SHA3_224_CTX) >= sizeof(wc_Sha3) ? 1 : -1];
+        (void)sizeof(sha_test);
+
+        WOLFSSL_ENTER("SHA3_224_Init");
+        ret = wc_InitSha3_224((wc_Sha3*)sha, NULL, 0);
+
+        /* return 1 on success, 0 otherwise */
+        if (ret == 0)
+            return 1;
+
+        return 0;
+    }
+
+
+    int wolfSSL_SHA3_224_Update(WOLFSSL_SHA3_224_CTX* sha, const void* input,
+                           unsigned long sz)
+    {
+        int ret;
+
+        WOLFSSL_ENTER("SHA3_224_Update");
+        ret = wc_Sha3_224_Update((wc_Sha3*)sha, (const byte*)input, (word32)sz);
+
+        /* return 1 on success, 0 otherwise */
+        if (ret == 0)
+            return 1;
+
+        return 0;
+    }
+
+
+    int wolfSSL_SHA3_224_Final(byte* input, WOLFSSL_SHA3_224_CTX* sha)
+    {
+        int ret;
+
+        WOLFSSL_ENTER("SHA3_224_Final");
+        ret = wc_Sha3_224_Final((wc_Sha3*)sha, input);
+
+        /* return 1 on success, 0 otherwise */
+        if (ret == 0)
+            return 1;
+
+        return 0;
+    }
+
+#endif /* WOLFSSL_NOSHA3_224 */
+
+
+#ifndef WOLFSSL_NOSHA3_256
+    int wolfSSL_SHA3_256_Init(WOLFSSL_SHA3_256_CTX* sha3_256)
+    {
+        int ret;
+
+        typedef char sha_test[sizeof(SHA3_256_CTX) >= sizeof(wc_Sha3) ? 1 : -1];
+        (void)sizeof(sha_test);
+
+        WOLFSSL_ENTER("SHA3_256_Init");
+        ret = wc_InitSha3_256((wc_Sha3*)sha3_256, NULL, 0);
+
+        /* return 1 on success, 0 otherwise */
+        if (ret == 0)
+            return 1;
+
+        return 0;
+    }
+
+
+    int wolfSSL_SHA3_256_Update(WOLFSSL_SHA3_256_CTX* sha, const void* input,
+                              unsigned long sz)
+    {
+        int ret;
+
+        WOLFSSL_ENTER("SHA3_256_Update");
+        ret = wc_Sha3_256_Update((wc_Sha3*)sha, (const byte*)input, (word32)sz);
+
+        /* return 1 on success, 0 otherwise */
+        if (ret == 0)
+            return 1;
+
+        return 0;
+    }
+
+
+    int wolfSSL_SHA3_256_Final(byte* input, WOLFSSL_SHA3_256_CTX* sha)
+    {
+        int ret;
+
+        WOLFSSL_ENTER("SHA3_256_Final");
+        ret = wc_Sha3_256_Final((wc_Sha3*)sha, input);
+
+        /* return 1 on success, 0 otherwise */
+        if (ret == 0)
+            return 1;
+
+        return 0;
+    }
+#endif /* WOLFSSL_NOSHA3_256 */
+
+
+    int wolfSSL_SHA3_384_Init(WOLFSSL_SHA3_384_CTX* sha)
+    {
+        int ret;
+
+        typedef char sha_test[sizeof(SHA3_384_CTX) >= sizeof(wc_Sha3) ? 1 : -1];
+        (void)sizeof(sha_test);
+
+        WOLFSSL_ENTER("SHA3_384_Init");
+        ret = wc_InitSha3_384((wc_Sha3*)sha, NULL, 0);
+
+        /* return 1 on success, 0 otherwise */
+        if (ret == 0)
+            return 1;
+
+        return 0;
+    }
+
+
+    int wolfSSL_SHA3_384_Update(WOLFSSL_SHA3_384_CTX* sha, const void* input,
+                           unsigned long sz)
+    {
+        int ret;
+
+        WOLFSSL_ENTER("SHA3_384_Update");
+        ret = wc_Sha3_384_Update((wc_Sha3*)sha, (const byte*)input, (word32)sz);
+
+        /* return 1 on success, 0 otherwise */
+        if (ret == 0)
+            return 1;
+
+        return 0;
+    }
+
+
+    int wolfSSL_SHA3_384_Final(byte* input, WOLFSSL_SHA3_384_CTX* sha)
+    {
+        int ret;
+
+        WOLFSSL_ENTER("SHA3_384_Final");
+        ret = wc_Sha3_384_Final((wc_Sha3*)sha, input);
+
+        /* return 1 on success, 0 otherwise */
+        if (ret == 0)
+            return 1;
+
+        return 0;
+    }
+
+
+
+#ifndef WOLFSSL_NOSHA3_512
+
+    int wolfSSL_SHA3_512_Init(WOLFSSL_SHA3_512_CTX* sha)
+    {
+        int ret;
+
+        typedef char sha_test[sizeof(SHA3_512_CTX) >= sizeof(wc_Sha3) ? 1 : -1];
+        (void)sizeof(sha_test);
+
+        WOLFSSL_ENTER("SHA3_512_Init");
+        ret = wc_InitSha3_512((wc_Sha3*)sha, NULL, 0);
+
+        /* return 1 on success, 0 otherwise */
+        if (ret == 0)
+            return 1;
+
+        return 0;
+    }
+
+
+    int wolfSSL_SHA3_512_Update(WOLFSSL_SHA3_512_CTX* sha, const void* input,
+                           unsigned long sz)
+    {
+        int ret;
+
+        WOLFSSL_ENTER("SHA3_512_Update");
+        ret = wc_Sha3_512_Update((wc_Sha3*)sha, (const byte*)input, (word32)sz);
+
+        /* return 1 on success, 0 otherwise */
+        if (ret == 0)
+            return 1;
+
+        return 0;
+    }
+
+
+    int wolfSSL_SHA3_512_Final(byte* input, WOLFSSL_SHA3_512_CTX* sha)
+    {
+        int ret;
+
+        WOLFSSL_ENTER("SHA3_512_Final");
+        ret = wc_Sha3_512_Final((wc_Sha3*)sha, input);
+
+        /* return 1 on success, 0 otherwise */
+        if (ret == 0)
+            return 1;
+
+        return 0;
+    }
+
+#endif /* WOLFSSL_NOSHA3_512 */
+#endif /* WOLFSSL_SHA3 */
+
+    /* store for external read of iv, WOLFSSL_SUCCESS on success */
+    int  wolfSSL_StoreExternalIV(WOLFSSL_EVP_CIPHER_CTX* ctx)
+    {
+        WOLFSSL_ENTER("wolfSSL_StoreExternalIV");
+
+        if (ctx == NULL) {
+            WOLFSSL_MSG("Bad function argument");
+            return WOLFSSL_FATAL_ERROR;
+        }
+
+        switch (ctx->cipherType) {
+
+#ifndef NO_AES
+#ifdef HAVE_AES_CBC
+            case AES_128_CBC_TYPE :
+            case AES_192_CBC_TYPE :
+            case AES_256_CBC_TYPE :
+                WOLFSSL_MSG("AES CBC");
+                XMEMCPY(ctx->iv, &ctx->cipher.aes.reg, AES_BLOCK_SIZE);
+                break;
+#endif
+#ifdef HAVE_AESGCM
+            case AES_128_GCM_TYPE :
+            case AES_192_GCM_TYPE :
+            case AES_256_GCM_TYPE :
+                WOLFSSL_MSG("AES GCM");
+                XMEMCPY(ctx->iv, &ctx->cipher.aes.reg, AES_BLOCK_SIZE);
+                break;
+#endif /* HAVE_AESGCM */
+#ifdef HAVE_AES_ECB
+            case AES_128_ECB_TYPE :
+            case AES_192_ECB_TYPE :
+            case AES_256_ECB_TYPE :
+                WOLFSSL_MSG("AES ECB");
+                break;
+#endif
+#ifdef WOLFSSL_AES_COUNTER
+            case AES_128_CTR_TYPE :
+            case AES_192_CTR_TYPE :
+            case AES_256_CTR_TYPE :
+                WOLFSSL_MSG("AES CTR");
+                XMEMCPY(ctx->iv, &ctx->cipher.aes.reg, AES_BLOCK_SIZE);
+                break;
+#endif /* WOLFSSL_AES_COUNTER */
+#ifdef WOLFSSL_AES_CFB
+#if !defined(HAVE_SELFTEST) && !defined(HAVE_FIPS)
+            case AES_128_CFB1_TYPE:
+            case AES_192_CFB1_TYPE:
+            case AES_256_CFB1_TYPE:
+                WOLFSSL_MSG("AES CFB1");
+                break;
+            case AES_128_CFB8_TYPE:
+            case AES_192_CFB8_TYPE:
+            case AES_256_CFB8_TYPE:
+                WOLFSSL_MSG("AES CFB8");
+                break;
+#endif /* !HAVE_SELFTEST && !HAVE_FIPS */
+            case AES_128_CFB128_TYPE:
+            case AES_192_CFB128_TYPE:
+            case AES_256_CFB128_TYPE:
+                WOLFSSL_MSG("AES CFB128");
+                break;
+#endif /* WOLFSSL_AES_CFB */
+#if defined(WOLFSSL_AES_OFB)
+            case AES_128_OFB_TYPE:
+            case AES_192_OFB_TYPE:
+            case AES_256_OFB_TYPE:
+                WOLFSSL_MSG("AES OFB");
+                break;
+#endif /* WOLFSSL_AES_OFB */
+#ifdef WOLFSSL_AES_XTS
+            case AES_128_XTS_TYPE:
+            case AES_256_XTS_TYPE:
+                WOLFSSL_MSG("AES XTS");
+                break;
+#endif /* WOLFSSL_AES_XTS */
+#endif /* NO_AES */
+
+#ifndef NO_DES3
+            case DES_CBC_TYPE :
+                WOLFSSL_MSG("DES CBC");
+                XMEMCPY(ctx->iv, &ctx->cipher.des.reg, DES_BLOCK_SIZE);
+                break;
+
+            case DES_EDE3_CBC_TYPE :
+                WOLFSSL_MSG("DES EDE3 CBC");
+                XMEMCPY(ctx->iv, &ctx->cipher.des3.reg, DES_BLOCK_SIZE);
+                break;
+#endif
+#ifdef WOLFSSL_DES_ECB
+            case DES_ECB_TYPE :
+                WOLFSSL_MSG("DES ECB");
+                break;
+            case DES_EDE3_ECB_TYPE :
+                WOLFSSL_MSG("DES3 ECB");
+                break;
+#endif
+
+#ifdef HAVE_IDEA
+            case IDEA_CBC_TYPE :
+                WOLFSSL_MSG("IDEA CBC");
+                XMEMCPY(ctx->iv, &ctx->cipher.idea.reg, IDEA_BLOCK_SIZE);
+                break;
+#endif
+            case ARC4_TYPE :
+                WOLFSSL_MSG("ARC4");
+                break;
+
+            case NULL_CIPHER_TYPE :
+                WOLFSSL_MSG("NULL");
+                break;
+
+            default: {
+                WOLFSSL_MSG("bad type");
+                return WOLFSSL_FATAL_ERROR;
+            }
+        }
+        return WOLFSSL_SUCCESS;
+    }
+
+    /* set internal IV from external, WOLFSSL_SUCCESS on success */
+    int  wolfSSL_SetInternalIV(WOLFSSL_EVP_CIPHER_CTX* ctx)
+    {
+
+        WOLFSSL_ENTER("wolfSSL_SetInternalIV");
+
+        if (ctx == NULL) {
+            WOLFSSL_MSG("Bad function argument");
+            return WOLFSSL_FATAL_ERROR;
+        }
+
+        switch (ctx->cipherType) {
+
+#ifndef NO_AES
+#ifdef HAVE_AES_CBC
+            case AES_128_CBC_TYPE :
+            case AES_192_CBC_TYPE :
+            case AES_256_CBC_TYPE :
+                WOLFSSL_MSG("AES CBC");
+                XMEMCPY(&ctx->cipher.aes.reg, ctx->iv, AES_BLOCK_SIZE);
+                break;
+#endif
+#ifdef HAVE_AESGCM
+            case AES_128_GCM_TYPE :
+            case AES_192_GCM_TYPE :
+            case AES_256_GCM_TYPE :
+                WOLFSSL_MSG("AES GCM");
+                XMEMCPY(&ctx->cipher.aes.reg, ctx->iv, AES_BLOCK_SIZE);
+                break;
+#endif
+#ifdef HAVE_AES_ECB
+            case AES_128_ECB_TYPE :
+            case AES_192_ECB_TYPE :
+            case AES_256_ECB_TYPE :
+                WOLFSSL_MSG("AES ECB");
+                break;
+#endif
+#ifdef WOLFSSL_AES_COUNTER
+            case AES_128_CTR_TYPE :
+            case AES_192_CTR_TYPE :
+            case AES_256_CTR_TYPE :
+                WOLFSSL_MSG("AES CTR");
+                XMEMCPY(&ctx->cipher.aes.reg, ctx->iv, AES_BLOCK_SIZE);
+                break;
+#endif
+
+#endif /* NO_AES */
+
+#ifndef NO_DES3
+            case DES_CBC_TYPE :
+                WOLFSSL_MSG("DES CBC");
+                XMEMCPY(&ctx->cipher.des.reg, ctx->iv, DES_BLOCK_SIZE);
+                break;
+
+            case DES_EDE3_CBC_TYPE :
+                WOLFSSL_MSG("DES EDE3 CBC");
+                XMEMCPY(&ctx->cipher.des3.reg, ctx->iv, DES_BLOCK_SIZE);
+                break;
+#endif
+#ifdef WOLFSSL_DES_ECB
+            case DES_ECB_TYPE :
+                WOLFSSL_MSG("DES ECB");
+                break;
+            case DES_EDE3_ECB_TYPE :
+                WOLFSSL_MSG("DES3 ECB");
+                break;
+#endif
+
+#ifdef HAVE_IDEA
+            case IDEA_CBC_TYPE :
+                WOLFSSL_MSG("IDEA CBC");
+                XMEMCPY(&ctx->cipher.idea.reg, ctx->iv, IDEA_BLOCK_SIZE);
+                break;
+#endif
+            case ARC4_TYPE :
+                WOLFSSL_MSG("ARC4");
+                break;
+
+            case NULL_CIPHER_TYPE :
+                WOLFSSL_MSG("NULL");
+                break;
+
+            default: {
+                WOLFSSL_MSG("bad type");
+                return WOLFSSL_FATAL_ERROR;
+            }
+        }
+        return WOLFSSL_SUCCESS;
+    }
+
+    unsigned char* wolfSSL_HMAC(const WOLFSSL_EVP_MD* evp_md, const void* key,
+                                int key_len, const unsigned char* d, int n,
+                                unsigned char* md, unsigned int* md_len)
+    {
+        int type;
+        int mdlen;
+        unsigned char* ret = NULL;
+#ifdef WOLFSSL_SMALL_STACK
+        Hmac* hmac = NULL;
+#else
+        Hmac  hmac[1];
+#endif
+        void* heap = NULL;
+
+        WOLFSSL_ENTER("wolfSSL_HMAC");
+        if (!md) {
+            WOLFSSL_MSG("Static buffer not supported, pass in md buffer");
+            return NULL;  /* no static buffer support */
+        }
+
+#ifndef NO_MD5
+        if (XSTRNCMP(evp_md, "MD5", 3) == 0) {
+            type = WC_MD5;
+            mdlen = WC_MD5_DIGEST_SIZE;
+        } else
+#endif
+#ifdef WOLFSSL_SHA224
+        if (XSTRNCMP(evp_md, "SHA224", 6) == 0) {
+            type = WC_SHA224;
+            mdlen = WC_SHA224_DIGEST_SIZE;
+        } else
+#endif
+#ifndef NO_SHA256
+        if (XSTRNCMP(evp_md, "SHA256", 6) == 0) {
+            type = WC_SHA256;
+            mdlen = WC_SHA256_DIGEST_SIZE;
+        } else
+#endif
+#ifdef WOLFSSL_SHA384
+        if (XSTRNCMP(evp_md, "SHA384", 6) == 0) {
+            type = WC_SHA384;
+            mdlen = WC_SHA384_DIGEST_SIZE;
+        } else
+#endif
+#ifdef WOLFSSL_SHA512
+        if (XSTRNCMP(evp_md, "SHA512", 6) == 0) {
+            type = WC_SHA512;
+            mdlen = WC_SHA512_DIGEST_SIZE;
+        } else
+#endif
+#ifdef WOLFSSL_SHA3
+    #ifndef WOLFSSL_NOSHA3_224
+        if (XSTRNCMP(evp_md, "SHA3_224", 8) == 0) {
+            type = WC_SHA3_224;
+            mdlen = WC_SHA3_224_DIGEST_SIZE;
+        } else
+    #endif
+    #ifndef WOLFSSL_NOSHA3_256
+        if (XSTRNCMP(evp_md, "SHA3_256", 8) == 0) {
+            type = WC_SHA3_256;
+            mdlen = WC_SHA3_256_DIGEST_SIZE;
+        } else
+    #endif
+        if (XSTRNCMP(evp_md, "SHA3_384", 8) == 0) {
+            type = WC_SHA3_384;
+            mdlen = WC_SHA3_384_DIGEST_SIZE;
+        } else
+    #ifndef WOLFSSL_NOSHA3_512
+        if (XSTRNCMP(evp_md, "SHA3_512", 8) == 0) {
+            type = WC_SHA3_512;
+            mdlen = WC_SHA3_512_DIGEST_SIZE;
+        } else
+    #endif
+#endif
+#ifndef NO_SHA
+        if (XSTRNCMP(evp_md, "SHA", 3) == 0) {
+            type = WC_SHA;
+            mdlen = WC_SHA_DIGEST_SIZE;
+        } else
+#endif
+        {
+            return NULL;
+        }
+
+    #ifdef WOLFSSL_SMALL_STACK
+        hmac = (Hmac*)XMALLOC(sizeof(Hmac), heap, DYNAMIC_TYPE_HMAC);
+        if (hmac == NULL)
+            return NULL;
+    #endif
+
+        if (wc_HmacInit(hmac, heap, INVALID_DEVID) == 0) {
+            if (wc_HmacSetKey(hmac, type, (const byte*)key, key_len) == 0) {
+                if (wc_HmacUpdate(hmac, d, n) == 0) {
+                    if (wc_HmacFinal(hmac, md) == 0) {
+                        if (md_len)
+                            *md_len = mdlen;
+                        ret = md;
+                    }
+                }
+            }
+            wc_HmacFree(hmac);
+        }
+
+    #ifdef WOLFSSL_SMALL_STACK
+        XFREE(hmac, heap, DYNAMIC_TYPE_HMAC);
+    #endif
+
+        (void)evp_md;
+        return ret;
+    }
+
+    void wolfSSL_ERR_clear_error(void)
+    {
+        WOLFSSL_ENTER("wolfSSL_ERR_clear_error");
+
+#if defined(DEBUG_WOLFSSL) || defined(WOLFSSL_NGINX) || \
+    defined(OPENSSL_EXTRA) || defined(DEBUG_WOLFSSL_VERBOSE)
+        wc_ClearErrorNodes();
+#endif
+    }
+
+
+    int wolfSSL_RAND_status(void)
+    {
+        return WOLFSSL_SUCCESS;  /* wolfCrypt provides enough seed internally */
+    }
+
+
+    #ifndef NO_WOLFSSL_STUB
+    void wolfSSL_RAND_add(const void* add, int len, double entropy)
+    {
+        (void)add;
+        (void)len;
+        (void)entropy;
+        WOLFSSL_STUB("RAND_add");
+        /* wolfSSL seeds/adds internally, use explicit RNG if you want
+           to take control */
+    }
+    #endif
+
+#ifndef NO_DES3
+    /* 0 on ok */
+    int wolfSSL_DES_key_sched(WOLFSSL_const_DES_cblock* key,
+                              WOLFSSL_DES_key_schedule* schedule)
+    {
+        WOLFSSL_ENTER("wolfSSL_DES_key_sched");
+
+        if (key == NULL || schedule == NULL) {
+            WOLFSSL_MSG("Null argument passed in");
+        }
+        else {
+            XMEMCPY(schedule, key, sizeof(WOLFSSL_const_DES_cblock));
+        }
+
+        return 0;
+    }
+
+
+    /* intended to behave similar to Kerberos mit_des_cbc_cksum
+     * return the last 4 bytes of cipher text */
+    WOLFSSL_DES_LONG wolfSSL_DES_cbc_cksum(const unsigned char* in,
+            WOLFSSL_DES_cblock* out, long length, WOLFSSL_DES_key_schedule* sc,
+            WOLFSSL_const_DES_cblock* iv)
+    {
+        WOLFSSL_DES_LONG ret;
+        unsigned char* tmp;
+        unsigned char* data   = (unsigned char*)in;
+        long           dataSz = length;
+        byte dynamicFlag = 0; /* when padding the buffer created needs free'd */
+
+        WOLFSSL_ENTER("wolfSSL_DES_cbc_cksum");
+
+        if (in == NULL || out == NULL || sc == NULL || iv == NULL) {
+            WOLFSSL_MSG("Bad argument passed in");
+            return 0;
+        }
+
+        /* if input length is not a multiple of DES_BLOCK_SIZE pad with 0s */
+        if (dataSz % DES_BLOCK_SIZE) {
+            dataSz += DES_BLOCK_SIZE - (dataSz % DES_BLOCK_SIZE);
+            data = (unsigned char*)XMALLOC(dataSz, NULL,
+                                           DYNAMIC_TYPE_TMP_BUFFER);
+            if (data == NULL) {
+                WOLFSSL_MSG("Issue creating temporary buffer");
+                return 0;
+            }
+            dynamicFlag = 1; /* set to free buffer at end */
+            XMEMCPY(data, in, length);
+            XMEMSET(data + length, 0, dataSz - length); /* padding */
+        }
+
+        tmp = (unsigned char*)XMALLOC(dataSz, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+        if (tmp == NULL) {
+            WOLFSSL_MSG("Issue creating temporary buffer");
+            if (dynamicFlag == 1) {
+                XFREE(data, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+            }
+            return 0;
+        }
+
+        wolfSSL_DES_cbc_encrypt(data, tmp, dataSz, sc,
+                (WOLFSSL_DES_cblock*)iv, 1);
+        XMEMCPY((unsigned char*)out, tmp + (dataSz - DES_BLOCK_SIZE),
+                DES_BLOCK_SIZE);
+
+        ret = (((*((unsigned char*)out + 4) & 0xFF) << 24)|
+               ((*((unsigned char*)out + 5) & 0xFF) << 16)|
+               ((*((unsigned char*)out + 6) & 0xFF) << 8) |
+               (*((unsigned char*)out + 7) & 0xFF));
+
+        XFREE(tmp, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+        if (dynamicFlag == 1) {
+            XFREE(data, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+        }
+
+        return ret;
+    }
+
+
+    void wolfSSL_DES_cbc_encrypt(const unsigned char* input,
+                                 unsigned char* output, long length,
+                                 WOLFSSL_DES_key_schedule* schedule,
+                                 WOLFSSL_DES_cblock* ivec, int enc)
+    {
+        Des myDes;
+        byte lastblock[DES_BLOCK_SIZE];
+        int  lb_sz;
+        long  blk;
+
+        WOLFSSL_ENTER("DES_cbc_encrypt");
+
+        /* OpenSSL compat, no ret */
+        wc_Des_SetKey(&myDes, (const byte*)schedule, (const byte*)ivec, !enc);
+        lb_sz = length%DES_BLOCK_SIZE;
+        blk   = length/DES_BLOCK_SIZE;
+
+        if (enc){
+            wc_Des_CbcEncrypt(&myDes, output, input, (word32)blk*DES_BLOCK_SIZE);
+            if(lb_sz){
+                XMEMSET(lastblock, 0, DES_BLOCK_SIZE);
+                XMEMCPY(lastblock, input+length-lb_sz, lb_sz);
+                wc_Des_CbcEncrypt(&myDes, output+blk*DES_BLOCK_SIZE,
+                    lastblock, (word32)DES_BLOCK_SIZE);
+            }
+        }
+        else {
+            wc_Des_CbcDecrypt(&myDes, output, input, (word32)blk*DES_BLOCK_SIZE);
+            if(lb_sz){
+                wc_Des_CbcDecrypt(&myDes, lastblock, input+length-lb_sz, (word32)DES_BLOCK_SIZE);
+                XMEMCPY(output+length-lb_sz, lastblock, lb_sz);
+            }
+        }
+    }
+
+
+    /* WOLFSSL_DES_key_schedule is a unsigned char array of size 8 */
+    void wolfSSL_DES_ede3_cbc_encrypt(const unsigned char* input,
+                                      unsigned char* output, long sz,
+                                      WOLFSSL_DES_key_schedule* ks1,
+                                      WOLFSSL_DES_key_schedule* ks2,
+                                      WOLFSSL_DES_key_schedule* ks3,
+                                      WOLFSSL_DES_cblock* ivec, int enc)
+    {
+        int ret;
+        Des3 des;
+        byte key[24];/* EDE uses 24 size key */
+        byte lastblock[DES_BLOCK_SIZE];
+        int  lb_sz;
+        long  blk;
+
+        WOLFSSL_ENTER("wolfSSL_DES_ede3_cbc_encrypt");
+
+        XMEMSET(key, 0, sizeof(key));
+        XMEMCPY(key, *ks1, DES_BLOCK_SIZE);
+        XMEMCPY(&key[DES_BLOCK_SIZE], *ks2, DES_BLOCK_SIZE);
+        XMEMCPY(&key[DES_BLOCK_SIZE * 2], *ks3, DES_BLOCK_SIZE);
+        lb_sz = sz%DES_BLOCK_SIZE;
+        blk   = sz/DES_BLOCK_SIZE;
+
+        /* OpenSSL compat, no ret */
+        (void)wc_Des3Init(&des, NULL, INVALID_DEVID);
+
+        if (enc) {
+            wc_Des3_SetKey(&des, key, (const byte*)ivec, DES_ENCRYPTION);
+            ret = wc_Des3_CbcEncrypt(&des, output, input, (word32)blk*DES_BLOCK_SIZE);
+        #if defined(WOLFSSL_ASYNC_CRYPT)
+            ret = wc_AsyncWait(ret, &des.asyncDev, WC_ASYNC_FLAG_NONE);
+        #endif
+            (void)ret; /* ignore return codes for processing */
+            if(lb_sz){
+                XMEMSET(lastblock, 0, DES_BLOCK_SIZE);
+                XMEMCPY(lastblock, input+sz-lb_sz, lb_sz);
+                ret = wc_Des3_CbcEncrypt(&des, output+blk*DES_BLOCK_SIZE,
+                    lastblock, (word32)DES_BLOCK_SIZE);
+            #if defined(WOLFSSL_ASYNC_CRYPT)
+                ret = wc_AsyncWait(ret, &des.asyncDev, WC_ASYNC_FLAG_NONE);
+            #endif
+                (void)ret; /* ignore return codes for processing */
+            }
+        }
+        else {
+            wc_Des3_SetKey(&des, key, (const byte*)ivec, DES_DECRYPTION);
+            ret = wc_Des3_CbcDecrypt(&des, output, input, (word32)blk*DES_BLOCK_SIZE);
+        #if defined(WOLFSSL_ASYNC_CRYPT)
+            ret = wc_AsyncWait(ret, &des.asyncDev, WC_ASYNC_FLAG_NONE);
+        #endif
+            (void)ret; /* ignore return codes for processing */
+            if(lb_sz){
+                ret = wc_Des3_CbcDecrypt(&des, lastblock, input+sz-lb_sz, (word32)DES_BLOCK_SIZE);
+            #if defined(WOLFSSL_ASYNC_CRYPT)
+                ret = wc_AsyncWait(ret, &des.asyncDev, WC_ASYNC_FLAG_NONE);
+            #endif
+                (void)ret; /* ignore return codes for processing */
+                XMEMCPY(output+sz-lb_sz, lastblock, lb_sz);
+            }
+        }
+        wc_Des3Free(&des);
+    }
+
+
+    /* correctly sets ivec for next call */
+    void wolfSSL_DES_ncbc_encrypt(const unsigned char* input,
+                     unsigned char* output, long length,
+                     WOLFSSL_DES_key_schedule* schedule, WOLFSSL_DES_cblock* ivec,
+                     int enc)
+    {
+        Des myDes;
+        byte lastblock[DES_BLOCK_SIZE];
+        int  lb_sz;
+        long idx = length;
+        long blk;
+
+        WOLFSSL_ENTER("DES_ncbc_encrypt");
+
+        /* OpenSSL compat, no ret */
+        wc_Des_SetKey(&myDes, (const byte*)schedule, (const byte*)ivec, !enc);
+        lb_sz = length%DES_BLOCK_SIZE;
+        blk   = length/DES_BLOCK_SIZE;
+        idx  -= sizeof(DES_cblock);
+        if (lb_sz) {
+            idx += DES_BLOCK_SIZE - lb_sz;
+        }
+        if (enc){
+            wc_Des_CbcEncrypt(&myDes, output, input,
+                    (word32)blk * DES_BLOCK_SIZE);
+            if (lb_sz){
+                XMEMSET(lastblock, 0, DES_BLOCK_SIZE);
+                XMEMCPY(lastblock, input+length-lb_sz, lb_sz);
+                wc_Des_CbcEncrypt(&myDes, output + blk * DES_BLOCK_SIZE,
+                    lastblock, (word32)DES_BLOCK_SIZE);
+            }
+            XMEMCPY(ivec, output + idx, sizeof(DES_cblock));
+        } else {
+            WOLFSSL_DES_cblock tmp;
+            XMEMCPY(tmp, input + idx, sizeof(DES_cblock));
+            wc_Des_CbcDecrypt(&myDes, output, input,
+                    (word32)blk * DES_BLOCK_SIZE);
+            if (lb_sz){
+                wc_Des_CbcDecrypt(&myDes, lastblock, input + length - lb_sz,
+                        (word32)DES_BLOCK_SIZE);
+                XMEMCPY(output+length-lb_sz, lastblock, lb_sz);
+            }
+            XMEMCPY(ivec, tmp, sizeof(WOLFSSL_DES_cblock));
+        }
+
+    }
+
+#endif /* NO_DES3 */
+
+    void wolfSSL_ERR_free_strings(void)
+    {
+        /* handled internally */
+    }
+
+    void wolfSSL_cleanup_all_ex_data(void)
+    {
+        /* nothing to do here */
+    }
+
+    int wolfSSL_clear(WOLFSSL* ssl)
+    {
+        if (ssl == NULL) {
+            return WOLFSSL_FAILURE;
+        }
+
+        ssl->options.isClosed = 0;
+        ssl->options.connReset = 0;
+        ssl->options.sentNotify = 0;
+        ssl->options.sendVerify = 0;
+        ssl->options.serverState = NULL_STATE;
+        ssl->options.clientState = NULL_STATE;
+        ssl->options.connectState = CONNECT_BEGIN;
+        ssl->options.acceptState  = ACCEPT_BEGIN;
+        ssl->options.handShakeState  = NULL_STATE;
+        ssl->options.handShakeDone = 0;
+        /* ssl->options.processReply = doProcessInit; */
+
+        ssl->keys.encryptionOn = 0;
+        XMEMSET(&ssl->msgsReceived, 0, sizeof(ssl->msgsReceived));
+
+        if (ssl->hsHashes != NULL) {
+#ifndef NO_OLD_TLS
+#ifndef NO_MD5
+            if (wc_InitMd5_ex(&ssl->hsHashes->hashMd5, ssl->heap,
+                    ssl->devId) != 0) {
+                return WOLFSSL_FAILURE;
+            }
+        #if defined(WOLFSSL_HASH_FLAGS) || defined(WOLF_CRYPTO_CB)
+            wc_Md5SetFlags(&ssl->hsHashes->hashMd5, WC_HASH_FLAG_WILLCOPY);
+        #endif
+#endif
+#ifndef NO_SHA
+            if (wc_InitSha_ex(&ssl->hsHashes->hashSha, ssl->heap,
+                    ssl->devId) != 0) {
+                return WOLFSSL_FAILURE;
+            }
+        #if defined(WOLFSSL_HASH_FLAGS) || defined(WOLF_CRYPTO_CB)
+            wc_ShaSetFlags(&ssl->hsHashes->hashSha, WC_HASH_FLAG_WILLCOPY);
+        #endif
+#endif
+#endif
+#ifndef NO_SHA256
+            if (wc_InitSha256_ex(&ssl->hsHashes->hashSha256, ssl->heap,
+                    ssl->devId) != 0) {
+                return WOLFSSL_FAILURE;
+            }
+        #if defined(WOLFSSL_HASH_FLAGS) || defined(WOLF_CRYPTO_CB)
+            wc_Sha256SetFlags(&ssl->hsHashes->hashSha256, WC_HASH_FLAG_WILLCOPY);
+        #endif
+#endif
+#ifdef WOLFSSL_SHA384
+            if (wc_InitSha384_ex(&ssl->hsHashes->hashSha384, ssl->heap,
+                    ssl->devId) != 0) {
+                return WOLFSSL_FAILURE;
+            }
+        #if defined(WOLFSSL_HASH_FLAGS) || defined(WOLF_CRYPTO_CB)
+            wc_Sha384SetFlags(&ssl->hsHashes->hashSha384, WC_HASH_FLAG_WILLCOPY);
+        #endif
+#endif
+#ifdef WOLFSSL_SHA512
+            if (wc_InitSha512_ex(&ssl->hsHashes->hashSha512, ssl->heap,
+                    ssl->devId) != 0) {
+                return WOLFSSL_FAILURE;
+            }
+        #if defined(WOLFSSL_HASH_FLAGS) || defined(WOLF_CRYPTO_CB)
+            wc_Sha512SetFlags(&ssl->hsHashes->hashSha512, WC_HASH_FLAG_WILLCOPY);
+        #endif
+#endif
+        }
+#ifdef SESSION_CERTS
+        ssl->session.chain.count = 0;
+#endif
+#ifdef KEEP_PEER_CERT
+        FreeX509(&ssl->peerCert);
+        InitX509(&ssl->peerCert, 0, ssl->heap);
+#endif
+
+        return WOLFSSL_SUCCESS;
+    }
+
+    long wolfSSL_SSL_SESSION_set_timeout(WOLFSSL_SESSION* ses, long t)
+    {
+        word32 tmptime;
+        if (!ses || t < 0)
+            return BAD_FUNC_ARG;
+
+        tmptime = t & 0xFFFFFFFF;
+
+        ses->timeout = tmptime;
+
+        return WOLFSSL_SUCCESS;
+    }
+
+#endif
+
+#if defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER)
+    long wolfSSL_CTX_set_mode(WOLFSSL_CTX* ctx, long mode)
+    {
+        /* WOLFSSL_MODE_ACCEPT_MOVING_WRITE_BUFFER is wolfSSL default mode */
+
+        WOLFSSL_ENTER("SSL_CTX_set_mode");
+        switch(mode) {
+            case SSL_MODE_ENABLE_PARTIAL_WRITE:
+                ctx->partialWrite = 1;
+                break;
+            #if defined(OPENSSL_ALL) || defined(WOLFSSL_QT)
+            case SSL_MODE_RELEASE_BUFFERS:
+                WOLFSSL_MSG("SSL_MODE_RELEASE_BUFFERS not implemented.");
+                break;
+            #endif
+            default:
+                WOLFSSL_MSG("Mode Not Implemented");
+        }
+
+        /* SSL_MODE_AUTO_RETRY
+         * Should not return -1 with renegotiation on read/write */
+
+        return mode;
+    }
+#endif
+
+#ifdef OPENSSL_EXTRA
+
+    #ifndef NO_WOLFSSL_STUB
+    long wolfSSL_SSL_get_mode(WOLFSSL* ssl)
+    {
+        /* TODO: */
+        (void)ssl;
+        WOLFSSL_STUB("SSL_get_mode");
+        return 0;
+    }
+    #endif
+
+    #ifndef NO_WOLFSSL_STUB
+    long wolfSSL_CTX_get_mode(WOLFSSL_CTX* ctx)
+    {
+        /* TODO: */
+        (void)ctx;
+        WOLFSSL_STUB("SSL_CTX_get_mode");
+        return 0;
+    }
+    #endif
+
+    #ifndef NO_WOLFSSL_STUB
+    void wolfSSL_CTX_set_default_read_ahead(WOLFSSL_CTX* ctx, int m)
+    {
+        /* TODO: maybe? */
+        (void)ctx;
+        (void)m;
+        WOLFSSL_STUB("SSL_CTX_set_default_read_ahead");
+    }
+    #endif
+
+
+    /* Storing app session context id, this value is inherited by WOLFSSL
+     * objects created from WOLFSSL_CTX. Any session that is imported with a
+     * different session context id will be rejected.
+     *
+     * ctx         structure to set context in
+     * sid_ctx     value of context to set
+     * sid_ctx_len length of sid_ctx buffer
+     *
+     * Returns SSL_SUCCESS in success case and SSL_FAILURE when failing
+     */
+    int wolfSSL_CTX_set_session_id_context(WOLFSSL_CTX* ctx,
+                                           const unsigned char* sid_ctx,
+                                           unsigned int sid_ctx_len)
+    {
+        WOLFSSL_ENTER("SSL_CTX_set_session_id_context");
+
+        /* No application specific context needed for wolfSSL */
+        if (sid_ctx_len > ID_LEN || ctx == NULL || sid_ctx == NULL) {
+            return SSL_FAILURE;
+        }
+        XMEMCPY(ctx->sessionCtx, sid_ctx, sid_ctx_len);
+        ctx->sessionCtxSz = (byte)sid_ctx_len;
+
+        return SSL_SUCCESS;
+    }
+
+
+
+    /* Storing app session context id. Any session that is imported with a
+     * different session context id will be rejected.
+     *
+     * ssl  structure to set context in
+     * id   value of context to set
+     * len  length of sid_ctx buffer
+     *
+     * Returns SSL_SUCCESS in success case and SSL_FAILURE when failing
+     */
+    int wolfSSL_set_session_id_context(WOLFSSL* ssl, const unsigned char* id,
+                                   unsigned int len)
+    {
+        WOLFSSL_ENTER("wolfSSL_set_session_id_context");
+
+        if (len > ID_LEN || ssl == NULL || id == NULL) {
+            return SSL_FAILURE;
+        }
+        XMEMCPY(ssl->sessionCtx, id, len);
+        ssl->sessionCtxSz = (byte)len;
+
+        return SSL_SUCCESS;
+    }
+
+
+    long wolfSSL_CTX_sess_get_cache_size(WOLFSSL_CTX* ctx)
+    {
+        (void)ctx;
+        #ifndef NO_SESSION_CACHE
+            return (long)(SESSIONS_PER_ROW * SESSION_ROWS);
+        #else
+            return 0;
+        #endif
+    }
+
+
+    /* returns the unsigned error value and increments the pointer into the
+     * error queue.
+     *
+     * file  pointer to file name
+     * line  gets set to line number of error when not NULL
+     */
+    unsigned long wolfSSL_ERR_get_error_line(const char** file, int* line)
+    {
+    #ifdef DEBUG_WOLFSSL
+        int ret = wc_PullErrorNode(file, NULL, line);
+        if (ret < 0) {
+            if (ret == BAD_STATE_E) return 0; /* no errors in queue */
+            WOLFSSL_MSG("Issue getting error node");
+            WOLFSSL_LEAVE("wolfSSL_ERR_get_error_line", ret);
+            ret = 0 - ret; /* return absolute value of error */
+
+            /* panic and try to clear out nodes */
+            wc_ClearErrorNodes();
+        }
+        return (unsigned long)ret;
+    #else
+        (void)file;
+        (void)line;
+
+        return 0;
+    #endif
+    }
+
+
+#if (defined(DEBUG_WOLFSSL) || defined(OPENSSL_EXTRA)) && \
+    (!defined(_WIN32) && !defined(NO_ERROR_QUEUE))
+    static const char WOLFSSL_SYS_ACCEPT_T[]  = "accept";
+    static const char WOLFSSL_SYS_BIND_T[]    = "bind";
+    static const char WOLFSSL_SYS_CONNECT_T[] = "connect";
+    static const char WOLFSSL_SYS_FOPEN_T[]   = "fopen";
+    static const char WOLFSSL_SYS_FREAD_T[]   = "fread";
+    static const char WOLFSSL_SYS_GETADDRINFO_T[] = "getaddrinfo";
+    static const char WOLFSSL_SYS_GETSOCKOPT_T[]  = "getsockopt";
+    static const char WOLFSSL_SYS_GETSOCKNAME_T[] = "getsockname";
+    static const char WOLFSSL_SYS_GETHOSTBYNAME_T[] = "gethostbyname";
+    static const char WOLFSSL_SYS_GETNAMEINFO_T[]   = "getnameinfo";
+    static const char WOLFSSL_SYS_GETSERVBYNAME_T[] = "getservbyname";
+    static const char WOLFSSL_SYS_IOCTLSOCKET_T[]   = "ioctlsocket";
+    static const char WOLFSSL_SYS_LISTEN_T[]        = "listen";
+    static const char WOLFSSL_SYS_OPENDIR_T[]       = "opendir";
+    static const char WOLFSSL_SYS_SETSOCKOPT_T[]    = "setsockopt";
+    static const char WOLFSSL_SYS_SOCKET_T[]        = "socket";
+
+    /* switch with int mapped to function name for compatibility */
+    static const char* wolfSSL_ERR_sys_func(int fun)
+    {
+        switch (fun) {
+            case WOLFSSL_SYS_ACCEPT:      return WOLFSSL_SYS_ACCEPT_T;
+            case WOLFSSL_SYS_BIND:        return WOLFSSL_SYS_BIND_T;
+            case WOLFSSL_SYS_CONNECT:     return WOLFSSL_SYS_CONNECT_T;
+            case WOLFSSL_SYS_FOPEN:       return WOLFSSL_SYS_FOPEN_T;
+            case WOLFSSL_SYS_FREAD:       return WOLFSSL_SYS_FREAD_T;
+            case WOLFSSL_SYS_GETADDRINFO: return WOLFSSL_SYS_GETADDRINFO_T;
+            case WOLFSSL_SYS_GETSOCKOPT:  return WOLFSSL_SYS_GETSOCKOPT_T;
+            case WOLFSSL_SYS_GETSOCKNAME: return WOLFSSL_SYS_GETSOCKNAME_T;
+            case WOLFSSL_SYS_GETHOSTBYNAME: return WOLFSSL_SYS_GETHOSTBYNAME_T;
+            case WOLFSSL_SYS_GETNAMEINFO: return WOLFSSL_SYS_GETNAMEINFO_T;
+            case WOLFSSL_SYS_GETSERVBYNAME: return WOLFSSL_SYS_GETSERVBYNAME_T;
+            case WOLFSSL_SYS_IOCTLSOCKET: return WOLFSSL_SYS_IOCTLSOCKET_T;
+            case WOLFSSL_SYS_LISTEN:      return WOLFSSL_SYS_LISTEN_T;
+            case WOLFSSL_SYS_OPENDIR:     return WOLFSSL_SYS_OPENDIR_T;
+            case WOLFSSL_SYS_SETSOCKOPT:  return WOLFSSL_SYS_SETSOCKOPT_T;
+            case WOLFSSL_SYS_SOCKET:      return WOLFSSL_SYS_SOCKET_T;
+            default:
+                return "NULL";
+        }
+    }
+#endif /* DEBUG_WOLFSSL */
+
+
+    /* @TODO when having an error queue this needs to push to the queue */
+    void wolfSSL_ERR_put_error(int lib, int fun, int err, const char* file,
+            int line)
+    {
+        WOLFSSL_ENTER("wolfSSL_ERR_put_error");
+
+        #if !defined(DEBUG_WOLFSSL) && !defined(OPENSSL_EXTRA)
+        (void)fun;
+        (void)err;
+        (void)file;
+        (void)line;
+        WOLFSSL_MSG("Not compiled in debug mode");
+        #elif defined(OPENSSL_EXTRA) && \
+                (defined(_WIN32) || defined(NO_ERROR_QUEUE))
+        (void)fun;
+        (void)file;
+        (void)line;
+        WOLFSSL_ERROR(err);
+        #else
+        WOLFSSL_ERROR_LINE(err, wolfSSL_ERR_sys_func(fun), (unsigned int)line,
+            file, NULL);
+        #endif
+        (void)lib;
+    }
+
+
+    /* Similar to wolfSSL_ERR_get_error_line but takes in a flags argument for
+     * more flexibility.
+     *
+     * file  output pointer to file where error happened
+     * line  output to line number of error
+     * data  output data. Is a string if ERR_TXT_STRING flag is used
+     * flags bit flag to adjust data output
+     *
+     * Returns the error value or 0 if no errors are in the queue
+     */
+    unsigned long wolfSSL_ERR_get_error_line_data(const char** file, int* line,
+                                                  const char** data, int *flags)
+    {
+        int ret;
+
+        WOLFSSL_STUB("wolfSSL_ERR_get_error_line_data");
+
+        if (flags != NULL) {
+            if ((*flags & ERR_TXT_STRING) == ERR_TXT_STRING) {
+                ret = wc_PullErrorNode(file, data, line);
+                if (ret < 0) {
+                    if (ret == BAD_STATE_E) return 0; /* no errors in queue */
+                    WOLFSSL_MSG("Error with pulling error node!");
+                    WOLFSSL_LEAVE("wolfSSL_ERR_get_error_line_data", ret);
+                    ret = 0 - ret; /* return absolute value of error */
+
+                    /* panic and try to clear out nodes */
+                    wc_ClearErrorNodes();
+                }
+
+                return (unsigned long)ret;
+            }
+        }
+
+        ret = wc_PullErrorNode(file, NULL, line);
+        if (ret < 0) {
+            if (ret == BAD_STATE_E) return 0; /* no errors in queue */
+            WOLFSSL_MSG("Error with pulling error node!");
+            WOLFSSL_LEAVE("wolfSSL_ERR_get_error_line_data", ret);
+            ret = 0 - ret; /* return absolute value of error */
+
+            /* panic and try to clear out nodes */
+            wc_ClearErrorNodes();
+        }
+
+        return (unsigned long)ret;
+    }
+
+#endif /* OPENSSL_EXTRA */
+
+
+#if (defined(KEEP_PEER_CERT) && defined(SESSION_CERTS)) || \
+                                   (defined(OPENSSL_ALL) && defined(HAVE_PKCS7))
+    /* Decode the X509 DER encoded certificate into a WOLFSSL_X509 object.
+     *
+     * x509  WOLFSSL_X509 object to decode into.
+     * in    X509 DER data.
+     * len   Length of the X509 DER data.
+     * returns the new certificate on success, otherwise NULL.
+     */
+    static int DecodeToX509(WOLFSSL_X509* x509, const byte* in, int len)
+    {
+        int          ret;
+    #ifdef WOLFSSL_SMALL_STACK
+        DecodedCert* cert;
+    #else
+        DecodedCert  cert[1];
+    #endif
+        if (x509 == NULL || in == NULL || len <= 0)
+            return BAD_FUNC_ARG;
+
+    #ifdef WOLFSSL_SMALL_STACK
+        cert = (DecodedCert*)XMALLOC(sizeof(DecodedCert), NULL,
+                                     DYNAMIC_TYPE_DCERT);
+        if (cert == NULL)
+            return MEMORY_E;
+    #endif
+
+        /* Create a DecodedCert object and copy fields into WOLFSSL_X509 object.
+         */
+        InitDecodedCert(cert, (byte*)in, len, NULL);
+        if ((ret = ParseCertRelative(cert, CERT_TYPE, 0, NULL)) == 0) {
+        /* Check if x509 was not previously initialized by wolfSSL_X509_new() */
+            if (x509->dynamicMemory != TRUE)
+                InitX509(x509, 0, NULL);
+            ret = CopyDecodedToX509(x509, cert);
+            FreeDecodedCert(cert);
+        }
+    #ifdef WOLFSSL_SMALL_STACK
+        XFREE(cert, NULL, DYNAMIC_TYPE_DCERT);
+    #endif
+
+        return ret;
+    }
+#endif /* (KEEP_PEER_CERT && SESSION_CERTS) || (OPENSSL_ALL && HAVE_PKCS7) */
+
+
+#ifdef KEEP_PEER_CERT
+    WOLFSSL_ABI
+    WOLFSSL_X509* wolfSSL_get_peer_certificate(WOLFSSL* ssl)
+    {
+        WOLFSSL_ENTER("SSL_get_peer_certificate");
+        if (ssl == NULL)
+            return NULL;
+
+        if (ssl->peerCert.issuer.sz)
+            return &ssl->peerCert;
+#ifdef SESSION_CERTS
+        else if (ssl->session.chain.count > 0) {
+            if (DecodeToX509(&ssl->peerCert, ssl->session.chain.certs[0].buffer,
+                    ssl->session.chain.certs[0].length) == 0) {
+                return &ssl->peerCert;
+            }
+        }
+#endif
+        return 0;
+    }
+
+#endif /* KEEP_PEER_CERT */
+
+#if defined(SESSION_CERTS)
+/*  Return stack of peer certs.
+ *      If Qt or OPENSSL_ALL is defined then return ssl->peerCertChain.
+ *      All other cases return &ssl->session.chain
+ * ssl->peerCertChain is type WOLFSSL_STACK*
+ * ssl->session.chain is type WOLFSSL_X509_CHAIN
+ * Caller does not need to free return. The stack is Free'd when WOLFSSL* ssl is.
+ */
+WOLF_STACK_OF(WOLFSSL_X509)* wolfSSL_get_peer_cert_chain(const WOLFSSL* ssl)
+{
+    WOLFSSL_STACK* sk;
+    WOLFSSL_ENTER("wolfSSL_get_peer_cert_chain");
+
+    if (ssl == NULL)
+        return NULL;
+
+    #if defined(WOLFSSL_QT) || defined(OPENSSL_ALL)
+        if (ssl->peerCertChain == NULL)
+            wolfSSL_set_peer_cert_chain((WOLFSSL*) ssl);
+        sk = ssl->peerCertChain;
+    #else
+        sk = (WOLF_STACK_OF(WOLFSSL_X509)* )&ssl->session.chain;
+    #endif
+
+    if (sk == NULL) {
+        WOLFSSL_MSG("Error: Null Peer Cert Chain");
+    }
+    return sk;
+}
+
+#if defined(WOLFSSL_QT) || defined(OPENSSL_ALL)
+/* Builds up and creates a stack of peer certificates for ssl->peerCertChain
+    based off of the ssl session chain. Returns stack of WOLFSSL_X509 certs or
+    NULL on failure */
+WOLF_STACK_OF(WOLFSSL_X509)* wolfSSL_set_peer_cert_chain(WOLFSSL* ssl)
+{
+    WOLFSSL_STACK* sk;
+    WOLFSSL_X509* x509;
+    int i = 0;
+    int ret;
+
+    WOLFSSL_ENTER("wolfSSL_set_peer_cert_chain");
+    if ((ssl == NULL) || (ssl->session.chain.count == 0))
+        return NULL;
+
+    sk = wolfSSL_sk_X509_new();
+    i = ssl->session.chain.count-1;
+    for (; i >= 0; i--) {
+        /* For servers, the peer certificate chain does not include the peer
+            certificate, so do not add it to the stack */
+        if (ssl->options.side == WOLFSSL_SERVER_END && i == 0)
+            continue;
+        x509 = wolfSSL_X509_new();
+        if (x509 == NULL) {
+            WOLFSSL_MSG("Error Creating X509");
+            return NULL;
+        }
+        ret = DecodeToX509(x509, ssl->session.chain.certs[i].buffer,
+                             ssl->session.chain.certs[i].length);
+
+        if (ret != 0 || wolfSSL_sk_X509_push(sk, x509) != WOLFSSL_SUCCESS) {
+            WOLFSSL_MSG("Error decoding cert");
+            wolfSSL_X509_free(x509);
+            wolfSSL_sk_X509_free(sk);
+            return NULL;
+        }
+    }
+
+    if (sk == NULL) {
+        WOLFSSL_MSG("Null session chain");
+    }
+    /* This is Free'd when ssl is Free'd */
+    ssl->peerCertChain = sk;
+    return sk;
+}
+#endif /* OPENSSL_ALL || WOLFSSL_QT */
+#endif /* SESSION_CERTS */
+
+#ifndef NO_CERTS
+#if defined(KEEP_PEER_CERT) || defined(SESSION_CERTS) || \
+    defined(OPENSSL_EXTRA)  || defined(OPENSSL_EXTRA_X509_SMALL)
+
+/* user externally called free X509, if dynamic go ahead with free, otherwise
+ * don't */
+static void ExternalFreeX509(WOLFSSL_X509* x509)
+{
+    int doFree = 0;
+
+    WOLFSSL_ENTER("ExternalFreeX509");
+    if (x509) {
+        if (x509->dynamicMemory) {
+        #if defined(OPENSSL_EXTRA) || defined(OPENSSL_ALL)
+            if (wc_LockMutex(&x509->refMutex) != 0) {
+                WOLFSSL_MSG("Couldn't lock x509 mutex");
+            }
+            /* only free if all references to it are done */
+            x509->refCount--;
+            if (x509->refCount == 0)
+                doFree = 1;
+            wc_UnLockMutex(&x509->refMutex);
+        #else
+            doFree = 1;
+        #endif /* OPENSSL_EXTRA */
+
+            if (doFree) {
+                FreeX509(x509);
+                XFREE(x509, x509->heap, DYNAMIC_TYPE_X509);
+            }
+        } else {
+            WOLFSSL_MSG("free called on non dynamic object, not freeing");
+        }
+    }
+}
+
+/* Frees an external WOLFSSL_X509 structure */
+WOLFSSL_ABI
+void wolfSSL_X509_free(WOLFSSL_X509* x509)
+{
+    WOLFSSL_ENTER("wolfSSL_FreeX509");
+    ExternalFreeX509(x509);
+}
+
+
+/* copy name into in buffer, at most sz bytes, if buffer is null will
+   malloc buffer, call responsible for freeing                     */
+WOLFSSL_ABI
+char* wolfSSL_X509_NAME_oneline(WOLFSSL_X509_NAME* name, char* in, int sz)
+{
+    int copySz;
+
+    if (name == NULL) {
+        WOLFSSL_MSG("WOLFSSL_X509_NAME pointer was NULL");
+        return NULL;
+    }
+
+    copySz = min(sz, name->sz);
+
+    WOLFSSL_ENTER("wolfSSL_X509_NAME_oneline");
+    if (!name->sz) return in;
+
+    if (!in) {
+    #ifdef WOLFSSL_STATIC_MEMORY
+        WOLFSSL_MSG("Using static memory -- please pass in a buffer");
+        return NULL;
+    #else
+        in = (char*)XMALLOC(name->sz, NULL, DYNAMIC_TYPE_OPENSSL);
+        if (!in ) return in;
+        copySz = name->sz;
+    #endif
+    }
+
+    if (copySz <= 0)
+        return in;
+
+    XMEMCPY(in, name->name, copySz - 1);
+    in[copySz - 1] = 0;
+
+    return in;
+}
+
+#if defined(OPENSSL_EXTRA) && defined(XSNPRINTF)
+/* Copies X509 subject name into a buffer, with comma-separated name entries
+ *   (matching OpenSSL v1.0.0 format)
+ * Example Output for Issuer:
+ *
+ * C=US, ST=Montana, L=Bozeman, O=Sawtooth, OU=Consulting,
+ *  CN=www.wolfssl.com, emailAddress=info@wolfssl.com
+ */
+char* wolfSSL_X509_get_name_oneline(WOLFSSL_X509_NAME* name, char* in, int sz)
+{
+    WOLFSSL_X509_NAME_ENTRY* entry;
+    int nameSz, strSz, count, i, idx = 0;
+    int totalSz = 0;
+    char *str;
+    char tmpBuf[256];
+    char buf[80];
+    const char* sn;
+    WOLFSSL_ENTER("wolfSSL_X509_get_name_oneline");
+
+    if (name == NULL) {
+        WOLFSSL_MSG("wolfSSL_X509_get_subject_name failed");
+        return NULL;
+    }
+    #ifdef WOLFSSL_STATIC_MEMORY
+    if (!in) {
+        WOLFSSL_MSG("Using static memory -- please pass in a buffer");
+        return NULL;
+    }
+    #endif
+
+    tmpBuf[0] = '\0'; /* Make sure tmpBuf is NULL terminated */
+    /* Loop through X509 name entries and copy new format to buffer */
+    count = wolfSSL_X509_NAME_entry_count(name);
+    for (i = 0; i < count; i++) {
+
+        /* Get name entry and size */
+        entry = wolfSSL_X509_NAME_get_entry(name, i);
+        if (entry == NULL) {
+            WOLFSSL_MSG("X509_NAME_get_entry failed");
+            return NULL;
+        }
+        nameSz = wolfSSL_X509_NAME_get_text_by_NID(name, entry->nid, buf,
+                                                                   sizeof(buf));
+        if (nameSz < 0) {
+            WOLFSSL_MSG("X509_NAME_get_text_by_NID failed");
+            return NULL;
+        }
+
+        /* Get short name */
+        sn = wolfSSL_OBJ_nid2sn(entry->nid);
+        if (sn == NULL) {
+            WOLFSSL_MSG("OBJ_nid2sn failed");
+            return NULL;
+        }
+
+        /* Copy sn and name text to buffer
+         * Add extra strSz for '=', ',', ' ' and '\0' characters in XSNPRINTF.
+         */
+        if (i != count - 1) {
+            strSz = (int)XSTRLEN(sn) + nameSz + 4;
+            totalSz+= strSz;
+            str = (char*)XMALLOC(strSz, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+            if (str == NULL) {
+                WOLFSSL_MSG("Memory error");
+                return NULL;
+            }
+            XSNPRINTF(str, strSz, "%s=%s, ", sn, buf);
+        }
+        else {
+            /* Copy last name entry
+            * Add extra strSz for '=' and '\0' characters in XSNPRINTF.
+            */
+            strSz = (int)XSTRLEN(sn) + nameSz + 2;
+            totalSz+= strSz;
+            str = (char*)XMALLOC(strSz, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+            if (str == NULL) {
+                WOLFSSL_MSG("Memory error");
+                return NULL;
+            }
+            XSNPRINTF(str, strSz, "%s=%s", sn, buf);
+        }
+        /* Copy string to tmpBuf */
+        XSTRNCAT(tmpBuf, str, strSz);
+        idx += strSz;
+        XFREE(str, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    }
+
+    /* Allocate space based on total string size if no buffer was provided */
+    if (!in) {
+        in = (char*)XMALLOC(totalSz+1, NULL, DYNAMIC_TYPE_OPENSSL);
+        if (in == NULL) {
+            WOLFSSL_MSG("Memory error");
+            return in;
+        }
+    }
+    else {
+        if (totalSz > sz) {
+            WOLFSSL_MSG("Memory error");
+            return NULL;
+        }
+    }
+
+    XMEMCPY(in, tmpBuf, totalSz);
+    in[totalSz] = '\0';
+
+    return in;
+}
+#endif
+
+
+/* Wraps wolfSSL_X509_d2i
+ *
+ * returns a WOLFSSL_X509 structure pointer on success and NULL on fail
+ */
+WOLFSSL_X509* wolfSSL_d2i_X509(WOLFSSL_X509** x509, const unsigned char** in,
+        int len)
+{
+    WOLFSSL_X509* newX509 = NULL;
+
+    newX509 = wolfSSL_X509_d2i(x509, *in, len);
+    if (newX509 != NULL) {
+        *in += newX509->derCert->length;
+    }
+    return newX509;
+}
+
+
+WOLFSSL_X509* wolfSSL_X509_d2i(WOLFSSL_X509** x509, const byte* in, int len)
+{
+    WOLFSSL_X509 *newX509 = NULL;
+
+    WOLFSSL_ENTER("wolfSSL_X509_d2i");
+
+    if (in != NULL && len != 0) {
+    #ifdef WOLFSSL_SMALL_STACK
+        DecodedCert* cert;
+    #else
+        DecodedCert  cert[1];
+    #endif
+
+    #ifdef WOLFSSL_SMALL_STACK
+        cert = (DecodedCert*)XMALLOC(sizeof(DecodedCert), NULL,
+                                     DYNAMIC_TYPE_DCERT);
+        if (cert == NULL)
+            return NULL;
+    #endif
+
+        InitDecodedCert(cert, (byte*)in, len, NULL);
+        if (ParseCertRelative(cert, CERT_TYPE, 0, NULL) == 0) {
+            newX509 = wolfSSL_X509_new();
+            if (newX509 != NULL) {
+                if (CopyDecodedToX509(newX509, cert) != 0) {
+                    wolfSSL_X509_free(newX509);
+                    newX509 = NULL;
+                }
+            }
+        }
+        FreeDecodedCert(cert);
+    #ifdef WOLFSSL_SMALL_STACK
+        XFREE(cert, NULL, DYNAMIC_TYPE_DCERT);
+    #endif
+    }
+
+    if (x509 != NULL)
+        *x509 = newX509;
+
+    return newX509;
+}
+#endif /* KEEP_PEER_CERT || SESSION_CERTS || OPENSSL_EXTRA ||
+          OPENSSL_EXTRA_X509_SMALL */
+
+
+
+#if defined(OPENSSL_ALL) || defined(KEEP_OUR_CERT) || defined(KEEP_PEER_CERT) || \
+    defined(SESSION_CERTS)
+    /* return the next, if any, altname from the peer cert */
+    WOLFSSL_ABI
+    char* wolfSSL_X509_get_next_altname(WOLFSSL_X509* cert)
+    {
+        char* ret = NULL;
+        WOLFSSL_ENTER("wolfSSL_X509_get_next_altname");
+
+        /* don't have any to work with */
+        if (cert == NULL || cert->altNames == NULL)
+            return NULL;
+
+        /* already went through them */
+        if (cert->altNamesNext == NULL)
+            return NULL;
+
+        ret = cert->altNamesNext->name;
+        cert->altNamesNext = cert->altNamesNext->next;
+
+        return ret;
+    }
+
+    int wolfSSL_X509_get_isCA(WOLFSSL_X509* x509)
+    {
+        int isCA = 0;
+
+        WOLFSSL_ENTER("wolfSSL_X509_get_isCA");
+
+        if (x509 != NULL)
+            isCA = x509->isCa;
+
+        WOLFSSL_LEAVE("wolfSSL_X509_get_isCA", isCA);
+
+        return isCA;
+    }
+
+    int wolfSSL_X509_get_signature(WOLFSSL_X509* x509,
+                                                 unsigned char* buf, int* bufSz)
+    {
+        WOLFSSL_ENTER("wolfSSL_X509_get_signature");
+        if (x509 == NULL || bufSz == NULL || (*bufSz < (int)x509->sig.length &&
+                    buf != NULL))
+            return WOLFSSL_FATAL_ERROR;
+
+        if (buf != NULL)
+            XMEMCPY(buf, x509->sig.buffer, x509->sig.length);
+        *bufSz = x509->sig.length;
+
+        return WOLFSSL_SUCCESS;
+    }
+
+
+    /* Getter function that copies over the DER public key buffer to "buf" and
+     * sets the size in bufSz. If "buf" is NULL then just bufSz is set to needed
+     * buffer size. "bufSz" passed in should initially be set by the user to be
+     * the size of "buf". This gets checked to make sure the buffer is large
+     * enough to hold the public key.
+     *
+     * Note: this is the X.509 form of key with "header" info.
+     * return WOLFSSL_SUCCESS on success
+     */
+    int wolfSSL_X509_get_pubkey_buffer(WOLFSSL_X509* x509,
+                                                unsigned char* buf, int* bufSz)
+    {
+    #ifdef WOLFSSL_SMALL_STACK
+        DecodedCert* cert;
+    #else
+        DecodedCert cert[1];
+    #endif
+        word32 idx;
+        const byte*  der;
+        int length = 0;
+        int    ret, derSz = 0;
+        int badDate = 0;
+        const byte* pubKeyX509 = NULL;
+        int   pubKeyX509Sz = 0;
+
+        WOLFSSL_ENTER("wolfSSL_X509_get_pubkey_buffer");
+        if (x509 == NULL || bufSz == NULL) {
+            WOLFSSL_LEAVE("wolfSSL_X509_get_pubkey_buffer", BAD_FUNC_ARG);
+            return WOLFSSL_FATAL_ERROR;
+        }
+
+
+    #ifdef WOLFSSL_SMALL_STACK
+        cert = (DecodedCert*)XMALLOC(sizeof(DecodedCert),
+                                       x509->heap, DYNAMIC_TYPE_TMP_BUFFER);
+        if (cert == NULL) {
+            WOLFSSL_LEAVE("wolfSSL_X509_get_pubkey_buffer", MEMORY_E);
+            return WOLFSSL_FATAL_ERROR;
+        }
+    #endif
+
+        der = wolfSSL_X509_get_der(x509, &derSz);
+        InitDecodedCert(cert, der, derSz, NULL);
+        ret = wc_GetPubX509(cert, 0, &badDate);
+        if (ret >= 0) {
+            idx = cert->srcIdx;
+            pubKeyX509 = cert->source + cert->srcIdx;
+            ret = GetSequence(cert->source, &cert->srcIdx, &length,
+                    cert->maxIdx);
+            pubKeyX509Sz = length + (cert->srcIdx - idx);
+        }
+
+        FreeDecodedCert(cert);
+    #ifdef WOLFSSL_SMALL_STACK
+        XFREE(cert, x509->heap, DYNAMIC_TYPE_TMP_BUFFER);
+    #endif
+
+        if (ret < 0) {
+            WOLFSSL_LEAVE("wolfSSL_X509_get_pubkey_buffer", ret);
+            return WOLFSSL_FATAL_ERROR;
+        }
+
+        if (buf != NULL) {
+            if (pubKeyX509Sz > *bufSz) {
+                WOLFSSL_LEAVE("wolfSSL_X509_get_pubkey_buffer", BUFFER_E);
+                return WOLFSSL_FATAL_ERROR;
+            }
+            XMEMCPY(buf, pubKeyX509, pubKeyX509Sz);
+        }
+        *bufSz = pubKeyX509Sz;
+
+        return WOLFSSL_SUCCESS;
+    }
+
+
+    /* Getter function for the public key OID value
+     * return public key OID stored in WOLFSSL_X509 structure */
+    int wolfSSL_X509_get_pubkey_type(WOLFSSL_X509* x509)
+    {
+        if (x509 == NULL)
+            return WOLFSSL_FAILURE;
+        return x509->pubKeyOID;
+    }
+
+    /* write X509 serial number in unsigned binary to buffer
+       buffer needs to be at least EXTERNAL_SERIAL_SIZE (32) for all cases
+       return WOLFSSL_SUCCESS on success */
+    int wolfSSL_X509_get_serial_number(WOLFSSL_X509* x509,
+                                       byte* in, int* inOutSz)
+    {
+        WOLFSSL_ENTER("wolfSSL_X509_get_serial_number");
+        if (x509 == NULL || in == NULL ||
+                                   inOutSz == NULL || *inOutSz < x509->serialSz)
+            return BAD_FUNC_ARG;
+
+        XMEMCPY(in, x509->serial, x509->serialSz);
+        *inOutSz = x509->serialSz;
+
+        return WOLFSSL_SUCCESS;
+    }
+
+    /* not an openssl compatibility function - getting for derCert */
+    const byte* wolfSSL_X509_get_der(WOLFSSL_X509* x509, int* outSz)
+    {
+        WOLFSSL_ENTER("wolfSSL_X509_get_der");
+
+        if (x509 == NULL || x509->derCert == NULL || outSz == NULL)
+            return NULL;
+
+        *outSz = (int)x509->derCert->length;
+        return x509->derCert->buffer;
+    }
+
+    /* used by JSSE (not a standard compatibility function) */
+    /* this is not thread safe */
+    WOLFSSL_ABI
+    const byte* wolfSSL_X509_notBefore(WOLFSSL_X509* x509)
+    {
+        static byte notBeforeData[CTC_DATE_SIZE]; /* temp buffer for date */
+        WOLFSSL_ENTER("wolfSSL_X509_notBefore");
+
+        if (x509 == NULL)
+            return NULL;
+
+        XMEMSET(notBeforeData, 0, sizeof(notBeforeData));
+        notBeforeData[0] = (byte)x509->notBefore.type;
+        notBeforeData[1] = (byte)x509->notBefore.length;
+        XMEMCPY(&notBeforeData[2], x509->notBefore.data, x509->notBefore.length);
+
+        return notBeforeData;
+    }
+    /* used by JSSE (not a standard compatibility function) */
+    /* this is not thread safe */
+    WOLFSSL_ABI
+    const byte* wolfSSL_X509_notAfter(WOLFSSL_X509* x509)
+    {
+        static byte notAfterData[CTC_DATE_SIZE]; /* temp buffer for date */
+        WOLFSSL_ENTER("wolfSSL_X509_notAfter");
+
+        if (x509 == NULL)
+            return NULL;
+
+        XMEMSET(notAfterData, 0, sizeof(notAfterData));
+        notAfterData[0] = (byte)x509->notAfter.type;
+        notAfterData[1] = (byte)x509->notAfter.length;
+        XMEMCPY(&notAfterData[2], x509->notAfter.data, x509->notAfter.length);
+
+        return notAfterData;
+    }
+
+    #if defined(WOLFSSL_QT) || defined(OPENSSL_ALL) && !defined(NO_WOLFSSL_STUB)
+    WOLFSSL_ASN1_TIME* wolfSSL_X509_gmtime_adj(WOLFSSL_ASN1_TIME *s, long adj)
+    {
+        (void) s;
+        (void) adj;
+        WOLFSSL_STUB("wolfSSL_X509_gmtime_adj");
+        return NULL;
+    }
+    #endif
+
+    /* get the buffer to be signed (tbs) from the WOLFSSL_X509 certificate
+     *
+     * outSz : gets set to the size of the buffer
+     * returns a pointer to the internal buffer at the location of TBS on
+     *         on success and NULL on failure.
+     */
+    const unsigned char* wolfSSL_X509_get_tbs(WOLFSSL_X509* x509, int* outSz)
+    {
+        int sz = 0, len;
+        unsigned int idx = 0, tmpIdx;
+        const unsigned char* der = NULL;
+        const unsigned char* tbs = NULL;
+
+        if (x509 == NULL || outSz == NULL) {
+            return NULL;
+        }
+
+        der = wolfSSL_X509_get_der(x509, &sz);
+        if (der == NULL) {
+            return NULL;
+        }
+
+        if (GetSequence(der, &idx, &len, sz) < 0) {
+            return NULL;
+        }
+        tbs = der + idx;
+        tmpIdx = idx;
+        if (GetSequence(der, &idx, &len, sz) < 0) {
+            return NULL;
+        }
+        *outSz = len + (idx - tmpIdx);
+        return tbs;
+    }
+
+    int wolfSSL_X509_version(WOLFSSL_X509* x509)
+    {
+        WOLFSSL_ENTER("wolfSSL_X509_version");
+
+        if (x509 == NULL)
+            return 0;
+
+        return x509->version;
+    }
+
+#ifdef WOLFSSL_SEP
+
+/* copy oid into in buffer, at most *inOutSz bytes, if buffer is null will
+   malloc buffer, call responsible for freeing. Actual size returned in
+   *inOutSz. Requires inOutSz be non-null */
+byte* wolfSSL_X509_get_device_type(WOLFSSL_X509* x509, byte* in, int *inOutSz)
+{
+    int copySz;
+
+    WOLFSSL_ENTER("wolfSSL_X509_get_dev_type");
+    if (inOutSz == NULL) return NULL;
+    if (!x509->deviceTypeSz) return in;
+
+    copySz = min(*inOutSz, x509->deviceTypeSz);
+
+    if (!in) {
+    #ifdef WOLFSSL_STATIC_MEMORY
+        WOLFSSL_MSG("Using static memory -- please pass in a buffer");
+        return NULL;
+    #else
+        in = (byte*)XMALLOC(x509->deviceTypeSz, 0, DYNAMIC_TYPE_OPENSSL);
+        if (!in) return in;
+        copySz = x509->deviceTypeSz;
+    #endif
+    }
+
+    XMEMCPY(in, x509->deviceType, copySz);
+    *inOutSz = copySz;
+
+    return in;
+}
+
+
+byte* wolfSSL_X509_get_hw_type(WOLFSSL_X509* x509, byte* in, int* inOutSz)
+{
+    int copySz;
+
+    WOLFSSL_ENTER("wolfSSL_X509_get_hw_type");
+    if (inOutSz == NULL) return NULL;
+    if (!x509->hwTypeSz) return in;
+
+    copySz = min(*inOutSz, x509->hwTypeSz);
+
+    if (!in) {
+    #ifdef WOLFSSL_STATIC_MEMORY
+        WOLFSSL_MSG("Using static memory -- please pass in a buffer");
+        return NULL;
+    #else
+        in = (byte*)XMALLOC(x509->hwTypeSz, 0, DYNAMIC_TYPE_OPENSSL);
+        if (!in) return in;
+        copySz = x509->hwTypeSz;
+    #endif
+    }
+
+    XMEMCPY(in, x509->hwType, copySz);
+    *inOutSz = copySz;
+
+    return in;
+}
+
+
+byte* wolfSSL_X509_get_hw_serial_number(WOLFSSL_X509* x509,byte* in,
+                                        int* inOutSz)
+{
+    int copySz;
+
+    WOLFSSL_ENTER("wolfSSL_X509_get_hw_serial_number");
+    if (inOutSz == NULL) return NULL;
+    if (!x509->hwTypeSz) return in;
+
+    copySz = min(*inOutSz, x509->hwSerialNumSz);
+
+    if (!in) {
+    #ifdef WOLFSSL_STATIC_MEMORY
+        WOLFSSL_MSG("Using static memory -- please pass in a buffer");
+        return NULL;
+    #else
+        in = (byte*)XMALLOC(x509->hwSerialNumSz, 0, DYNAMIC_TYPE_OPENSSL);
+        if (!in) return in;
+        copySz = x509->hwSerialNumSz;
+    #endif
+    }
+
+    XMEMCPY(in, x509->hwSerialNum, copySz);
+    *inOutSz = copySz;
+
+    return in;
+}
+
+#endif /* WOLFSSL_SEP */
+
+/* require OPENSSL_EXTRA since wolfSSL_X509_free is wrapped by OPENSSL_EXTRA */
+#if !defined(NO_CERTS) && defined(OPENSSL_EXTRA)
+
+WOLFSSL_ASN1_TIME* wolfSSL_X509_get_notBefore(const WOLFSSL_X509* x509)
+{
+    WOLFSSL_ENTER("wolfSSL_X509_get_notBefore");
+
+    if (x509 == NULL)
+        return NULL;
+
+    return (WOLFSSL_ASN1_TIME*)&x509->notBefore;
+}
+
+
+WOLFSSL_ASN1_TIME* wolfSSL_X509_get_notAfter(const WOLFSSL_X509* x509)
+{
+    WOLFSSL_ENTER("wolfSSL_X509_get_notAfter");
+
+    if (x509 == NULL)
+        return NULL;
+
+    return (WOLFSSL_ASN1_TIME*)&x509->notAfter;
+}
+
+
+/* return 1 on success 0 on fail */
+int wolfSSL_sk_X509_push(WOLF_STACK_OF(WOLFSSL_X509_NAME)* sk, WOLFSSL_X509* x509)
+{
+    WOLFSSL_STACK* node;
+    WOLFSSL_ENTER("wolfSSL_sk_X509_push");
+
+    if (sk == NULL || x509 == NULL) {
+        return WOLFSSL_FAILURE;
+    }
+
+    /* no previous values in stack */
+    if (sk->data.x509 == NULL) {
+        sk->data.x509 = x509;
+        sk->num += 1;
+        return WOLFSSL_SUCCESS;
+    }
+
+    /* stack already has value(s) create a new node and add more */
+    node = (WOLFSSL_STACK*)XMALLOC(sizeof(WOLFSSL_STACK), NULL,
+                                                             DYNAMIC_TYPE_X509);
+    if (node == NULL) {
+        WOLFSSL_MSG("Memory error");
+        return WOLFSSL_FAILURE;
+    }
+    XMEMSET(node, 0, sizeof(WOLFSSL_STACK));
+
+    /* push new x509 onto head of stack */
+    node->data.x509 = sk->data.x509;
+    node->next      = sk->next;
+    node->type      = sk->type;
+    sk->next        = node;
+    sk->data.x509   = x509;
+    sk->num        += 1;
+
+    return WOLFSSL_SUCCESS;
+}
+
+
+WOLFSSL_X509* wolfSSL_sk_X509_pop(WOLF_STACK_OF(WOLFSSL_X509_NAME)* sk) {
+    WOLFSSL_STACK* node;
+    WOLFSSL_X509*  x509;
+
+    if (sk == NULL) {
+        return NULL;
+    }
+
+    node = sk->next;
+    x509 = sk->data.x509;
+
+    if (node != NULL) { /* update sk and remove node from stack */
+        sk->data.x509 = node->data.x509;
+        sk->next = node->next;
+        XFREE(node, NULL, DYNAMIC_TYPE_X509);
+    }
+    else { /* last x509 in stack */
+        sk->data.x509 = NULL;
+    }
+
+    if (sk->num > 0) {
+        sk->num -= 1;
+    }
+
+    return x509;
+}
+
+/* Getter function for WOLFSSL_X509 pointer
+ *
+ * sk is the stack to retrieve pointer from
+ * i  is the index value in stack
+ *
+ * returns a pointer to a WOLFSSL_X509 structure on success and NULL on
+ *         fail
+ */
+WOLFSSL_X509* wolfSSL_sk_X509_value(STACK_OF(WOLFSSL_X509)* sk, int i)
+{
+    WOLFSSL_ENTER("wolfSSL_sk_X509_value");
+
+    for (; sk != NULL && i > 0; i--)
+        sk = sk->next;
+
+    if (i != 0 || sk == NULL)
+        return NULL;
+    return sk->data.x509;
+}
+
+WOLFSSL_X509* wolfSSL_sk_X509_shift(WOLF_STACK_OF(WOLFSSL_X509)* sk)
+{
+    return wolfSSL_sk_X509_pop(sk);
+}
+
+#ifndef NO_WOLFSSL_STUB
+void* wolfSSL_sk_X509_OBJECT_value(WOLF_STACK_OF(WOLFSSL_X509_OBJECT)* sk, int x)
+{
+    (void) sk;
+    (void) x;
+    return NULL;
+}
+#endif
+
+
+/* Free's all nodes in X509 stack. This is different then wolfSSL_sk_X509_free
+ * in that it allows for choosing the function to use when freeing an X509s.
+ *
+ * sk  stack to free nodes in
+ * f   X509 free function
+ */
+void wolfSSL_sk_X509_pop_free(STACK_OF(WOLFSSL_X509)* sk,
+    void (*f) (WOLFSSL_X509*))
+{
+    WOLFSSL_STACK* node;
+
+    WOLFSSL_ENTER("wolfSSL_sk_X509_pop_free");
+
+    if (sk == NULL) {
+        return;
+    }
+
+    /* parse through stack freeing each node */
+    node = sk->next;
+    while (node && sk->num > 1) {
+        WOLFSSL_STACK* tmp = node;
+        node = node->next;
+
+        if (f)
+            f(tmp->data.x509);
+        else
+            wolfSSL_X509_free(tmp->data.x509);
+        tmp->data.x509 = NULL;
+        XFREE(tmp, NULL, DYNAMIC_TYPE_X509);
+        sk->num -= 1;
+    }
+
+    /* free head of stack */
+    if (sk->num == 1) {
+        if (f)
+            f(sk->data.x509);
+        else
+            wolfSSL_X509_free(sk->data.x509);
+        sk->data.x509 = NULL;
+    }
+    XFREE(sk, NULL, DYNAMIC_TYPE_X509);
+}
+
+
+/* free structure for x509 stack */
+void wolfSSL_sk_X509_free(WOLF_STACK_OF(WOLFSSL_X509)* sk)
+{
+    wolfSSL_sk_X509_pop_free(sk, NULL);
+}
+
+#endif /* NO_CERTS && OPENSSL_EXTRA */
+
+#if defined(OPENSSL_ALL) || defined (WOLFSSL_QT)
+/* return 1 on success 0 on fail */
+int wolfSSL_sk_ACCESS_DESCRIPTION_push(WOLF_STACK_OF(ACCESS_DESCRIPTION)* sk,
+                                              WOLFSSL_ACCESS_DESCRIPTION* access)
+{
+    WOLFSSL_STACK* node;
+
+    WOLFSSL_ENTER("wolfSSL_sk_ACCESS_DESCRIPTION_push");
+
+    if (sk == NULL || access == NULL) {
+        return WOLFSSL_FAILURE;
+    }
+
+    /* no previous values in stack */
+    if (sk->data.access == NULL) {
+        sk->data.access = access;
+        sk->num += 1;
+        return WOLFSSL_SUCCESS;
+    }
+
+    /* stack already has value(s) create a new node and add more */
+    node = (WOLFSSL_STACK*)XMALLOC(sizeof(WOLFSSL_STACK), NULL,
+                                   DYNAMIC_TYPE_ASN1);
+    if (node == NULL) {
+        WOLFSSL_MSG("Memory error");
+        return WOLFSSL_FAILURE;
+    }
+    XMEMSET(node, 0, sizeof(WOLFSSL_STACK));
+
+    /* push new obj onto head of stack */
+    node->data.access  = sk->data.access;
+    node->next         = sk->next;
+    node->type         = sk->type;
+    sk->next           = node;
+    sk->data.access    = access;
+    sk->num            += 1;
+
+    return WOLFSSL_SUCCESS;
+}
+
+/* Frees all nodes in ACCESS_DESCRIPTION stack
+*
+* sk stack of nodes to free
+* f  free function to use, not called with wolfSSL
+*/
+void wolfSSL_sk_ACCESS_DESCRIPTION_pop_free(WOLFSSL_STACK* sk,
+    void (*f) (WOLFSSL_ACCESS_DESCRIPTION*))
+{
+   WOLFSSL_STACK* node;
+
+   WOLFSSL_ENTER("wolfSSL_sk_ACCESS_DESCRIPTION_pop_free");
+
+   if (sk == NULL) {
+       return;
+   }
+
+   /* parse through stack freeing each node */
+   node = sk->next;
+   while (node && sk->num > 1) {
+       WOLFSSL_STACK* tmp = node;
+       node = node->next;
+
+       if (f)
+           f(tmp->data.access);
+       else
+           wolfSSL_ACCESS_DESCRIPTION_free(tmp->data.access);
+       tmp->data.access = NULL;
+       XFREE(tmp, NULL, DYNAMIC_TYPE_ASN1);
+       sk->num -= 1;
+   }
+
+   /* free head of stack */
+   if (sk->num == 1) {
+        if (f)
+            f(sk->data.access);
+        else {
+            if(sk->data.access->method) {
+
+               wolfSSL_ASN1_OBJECT_free(sk->data.access->method);
+            }
+            if(sk->data.access->location) {
+               wolfSSL_GENERAL_NAME_free(sk->data.access->location);
+            }
+        }
+        sk->data.access = NULL;
+   }
+   XFREE(sk, NULL, DYNAMIC_TYPE_ASN1);
+}
+
+void wolfSSL_sk_ACCESS_DESCRIPTION_free(WOLFSSL_STACK* sk)
+{
+    wolfSSL_sk_ACCESS_DESCRIPTION_pop_free(sk, NULL);
+}
+
+void wolfSSL_ACCESS_DESCRIPTION_free(WOLFSSL_ACCESS_DESCRIPTION* access)
+{
+    WOLFSSL_ENTER("wolfSSL_ACCESS_DESCRIPTION_free");
+    if (access == NULL)
+        return;
+
+    if (access->method)
+        wolfSSL_ASN1_OBJECT_free(access->method);
+    if (access->location)
+        wolfSSL_GENERAL_NAME_free(access->location);
+
+    /* access = NULL, don't try to access or double free it */
+}
+#endif
+
+#ifdef OPENSSL_EXTRA
+
+/* create a generic wolfSSL stack node
+ * returns a new WOLFSSL_STACK structure on success */
+WOLFSSL_STACK* wolfSSL_sk_new_node(void* heap)
+{
+    WOLFSSL_STACK* sk;
+    WOLFSSL_ENTER("wolfSSL_sk_new_node");
+
+    sk = (WOLFSSL_STACK*)XMALLOC(sizeof(WOLFSSL_STACK), heap,
+                                                          DYNAMIC_TYPE_OPENSSL);
+    if (sk != NULL) {
+        XMEMSET(sk, 0, sizeof(*sk));
+        sk->heap = heap;
+    }
+
+    return sk;
+}
+
+/* free's node but does not free internal data such as in->data.x509 */
+void wolfSSL_sk_free_node(WOLFSSL_STACK* in)
+{
+    if (in != NULL) {
+        XFREE(in, in->heap, DYNAMIC_TYPE_OPENSSL);
+    }
+}
+
+/* pushes node "in" onto "stack" and returns pointer to the new stack on success
+ * also handles internal "num" for number of nodes on stack
+ * return WOLFSSL_SUCCESS on success
+ */
+int wolfSSL_sk_push_node(WOLFSSL_STACK** stack, WOLFSSL_STACK* in)
+{
+    if (stack == NULL || in == NULL) {
+        return WOLFSSL_FAILURE;
+    }
+
+    if (*stack == NULL) {
+        in->num = 1;
+        *stack = in;
+        return WOLFSSL_SUCCESS;
+    }
+
+    in->num  = (*stack)->num + 1;
+    in->next = *stack;
+    *stack   = in;
+    return WOLFSSL_SUCCESS;
+}
+
+/* return 1 on success 0 on fail */
+int wolfSSL_sk_push(WOLFSSL_STACK* sk, const void *data)
+{
+    int ret = WOLFSSL_FAILURE;
+    WOLFSSL_ENTER("wolfSSL_sk_push");
+
+    switch (sk->type) {
+    #if defined(OPENSSL_ALL) || defined(WOLFSSL_QT)
+        case STACK_TYPE_X509:
+            ret = wolfSSL_sk_X509_push(sk, (WOLFSSL_X509*) data);
+            break;
+        #ifndef NO_WOLFSSL_STUB
+        case STACK_TYPE_CIPHER:
+            ret = wolfSSL_sk_CIPHER_push(sk, (WOLFSSL_CIPHER*) data);
+            break;
+        #endif
+        case STACK_TYPE_GEN_NAME:
+            ret = wolfSSL_sk_ASN1_OBJECT_push(sk, (WOLFSSL_ASN1_OBJECT*) data);
+            break;
+        case STACK_TYPE_ACCESS_DESCRIPTION:
+            ret = wolfSSL_sk_ACCESS_DESCRIPTION_push(sk,
+                                            (WOLFSSL_ACCESS_DESCRIPTION*) data);
+            break;
+        case STACK_TYPE_NULL:
+            ret = wolfSSL_sk_GENERIC_push(sk, (void*) data);
+            break;
+        case STACK_TYPE_OBJ:
+            ret = wolfSSL_sk_ASN1_OBJECT_push(sk, (WOLFSSL_ASN1_OBJECT*) data);
+            break;
+    #endif
+        default:
+            ret = wolfSSL_sk_ASN1_OBJECT_push(sk, (WOLFSSL_ASN1_OBJECT*) data);
+            break;
+    }
+
+    return ret;
+}
+
+/* Creates and returns new GENERAL_NAME structure */
+WOLFSSL_GENERAL_NAME* wolfSSL_GENERAL_NAME_new(void)
+{
+    WOLFSSL_GENERAL_NAME* gn;
+    WOLFSSL_ENTER("GENERAL_NAME_new");
+
+    gn = (WOLFSSL_GENERAL_NAME*)XMALLOC(sizeof(WOLFSSL_GENERAL_NAME), NULL,
+                                                             DYNAMIC_TYPE_ASN1);
+    if (gn == NULL) {
+        return NULL;
+    }
+    XMEMSET(gn, 0, sizeof(WOLFSSL_GENERAL_NAME));
+
+    gn->d.ia5 = wolfSSL_ASN1_STRING_new();
+    if (gn->d.ia5 == NULL) {
+        WOLFSSL_MSG("Issue creating ASN1_STRING struct");
+        wolfSSL_GENERAL_NAME_free(gn);
+        return NULL;
+    }
+    return gn;
+}
+
+/* return 1 on success 0 on fail */
+int wolfSSL_sk_GENERAL_NAME_push(WOLF_STACK_OF(WOLFSSL_GENERAL_NAME)* sk,
+                                                      WOLFSSL_GENERAL_NAME* gn)
+{
+    WOLFSSL_STACK* node;
+    WOLFSSL_ENTER("wolfSSL_sk_GENERAL_NAME_push");
+
+    if (sk == NULL || gn == NULL) {
+        return WOLFSSL_FAILURE;
+    }
+
+    /* no previous values in stack */
+    if (sk->data.gn == NULL) {
+        sk->data.gn = gn;
+        sk->num += 1;
+
+        return WOLFSSL_SUCCESS;
+    }
+
+    /* stack already has value(s) create a new node and add more */
+    node = (WOLFSSL_STACK*)XMALLOC(sizeof(WOLFSSL_STACK), NULL,
+                                                             DYNAMIC_TYPE_ASN1);
+    if (node == NULL) {
+        WOLFSSL_MSG("Memory error");
+        return WOLFSSL_FAILURE;
+    }
+    XMEMSET(node, 0, sizeof(WOLFSSL_STACK));
+
+    /* push new obj onto head of stack */
+    node->data.gn = sk->data.gn;
+    node->next    = sk->next;
+    sk->next      = node;
+    sk->data.gn   = gn;
+    sk->num      += 1;
+
+    return WOLFSSL_SUCCESS;
+}
+
+/* Returns the general name at index i from the stack
+ *
+ * sk  stack to get general name from
+ * idx index to get
+ *
+ * return a pointer to the internal node of the stack
+ */
+WOLFSSL_GENERAL_NAME* wolfSSL_sk_GENERAL_NAME_value(WOLFSSL_STACK* sk, int idx)
+{
+    WOLFSSL_STACK* ret;
+
+    if (sk == NULL) {
+        return NULL;
+    }
+
+    ret = wolfSSL_sk_get_node(sk, idx);
+    if (ret != NULL) {
+        return ret->data.gn;
+    }
+    return NULL;
+}
+
+/* Gets the number of nodes in the stack
+ *
+ * sk  stack to get the number of nodes from
+ *
+ * returns the number of nodes, -1 if no nodes
+ */
+int wolfSSL_sk_GENERAL_NAME_num(WOLFSSL_STACK* sk)
+{
+    WOLFSSL_ENTER("wolfSSL_sk_GENERAL_NAME_num");
+
+    if (sk == NULL) {
+        return -1;
+    }
+
+    return (int)sk->num;
+}
+
+/* Frees all nodes in a GENERAL NAME stack
+ *
+ * sk stack of nodes to free
+ * f  free function to use, not called with wolfSSL
+ */
+void wolfSSL_sk_GENERAL_NAME_pop_free(WOLFSSL_STACK* sk,
+        void (*f) (WOLFSSL_GENERAL_NAME*))
+{
+    WOLFSSL_STACK* node;
+
+    WOLFSSL_ENTER("wolfSSL_sk_GENERAL_NAME_pop_free");
+
+    if (sk == NULL) {
+        return;
+    }
+
+    /* parse through stack freeing each node */
+    node = sk->next;
+    while (node && sk->num > 1) {
+        WOLFSSL_STACK* tmp = node;
+        node = node->next;
+
+        if (f)
+            f(tmp->data.gn);
+        else
+            wolfSSL_GENERAL_NAME_free(tmp->data.gn);
+        XFREE(tmp, NULL, DYNAMIC_TYPE_ASN1);
+        sk->num -= 1;
+    }
+
+    /* free head of stack */
+    if (sk->num == 1) {
+        if (f)
+            f(sk->data.gn);
+        else
+            wolfSSL_GENERAL_NAME_free(sk->data.gn);
+    }
+    XFREE(sk, NULL, DYNAMIC_TYPE_ASN1);
+}
+
+void wolfSSL_sk_GENERAL_NAME_free(WOLFSSL_STACK* sk)
+{
+    WOLFSSL_ENTER("sk_GENERAL_NAME_free");
+    wolfSSL_sk_GENERAL_NAME_pop_free(sk, NULL);
+}
+
+
+/* returns the number of nodes in stack on success and WOLFSSL_FATAL_ERROR
+ * on fail */
+int wolfSSL_sk_ACCESS_DESCRIPTION_num(WOLFSSL_STACK* sk)
+{
+    if (sk == NULL) {
+        return WOLFSSL_FATAL_ERROR;
+    }
+
+    return (int)sk->num;
+}
+
+#ifndef NO_WOLFSSL_STUB
+/* similar to call to sk_ACCESS_DESCRIPTION_pop_free */
+void wolfSSL_AUTHORITY_INFO_ACCESS_free(
+        WOLF_STACK_OF(WOLFSSL_ACCESS_DESCRIPTION)* sk)
+{
+    WOLFSSL_STUB("wolfSSL_AUTHORITY_INFO_ACCESS_free");
+    (void)sk;
+}
+#endif
+
+/* returns the node at index "idx", NULL if not found */
+WOLFSSL_STACK* wolfSSL_sk_get_node(WOLFSSL_STACK* sk, int idx)
+{
+    int i;
+    WOLFSSL_STACK* ret = NULL;
+    WOLFSSL_STACK* current;
+
+    current = sk;
+    for (i = 0; i <= idx && current != NULL; i++) {
+        if (i == idx) {
+            ret = current;
+            break;
+        }
+        current = current->next;
+    }
+    return ret;
+}
+
+/* returns NULL on fail and pointer to internal data on success */
+WOLFSSL_ACCESS_DESCRIPTION* wolfSSL_sk_ACCESS_DESCRIPTION_value(
+        WOLFSSL_STACK* sk, int idx)
+{
+    WOLFSSL_STACK* ret;
+
+    if (sk == NULL) {
+        return NULL;
+    }
+
+    ret = wolfSSL_sk_get_node(sk, idx);
+    if (ret != NULL) {
+        return ret->data.access;
+    }
+    return NULL;
+}
+
+/* Frees GENERAL_NAME objects.
+*/
+void wolfSSL_GENERAL_NAME_free(WOLFSSL_GENERAL_NAME* name)
+{
+    WOLFSSL_ENTER("wolfSSL_GENERAL_NAME_Free");
+    if(name != NULL) {
+        if (name->d.dNSName != NULL) {
+            wolfSSL_ASN1_STRING_free(name->d.dNSName);
+            name->d.dNSName = NULL;
+        }
+        if (name->d.uniformResourceIdentifier != NULL) {
+            wolfSSL_ASN1_STRING_free(name->d.uniformResourceIdentifier);
+            name->d.uniformResourceIdentifier = NULL;
+        }
+        if (name->d.iPAddress != NULL) {
+            wolfSSL_ASN1_STRING_free(name->d.iPAddress);
+            name->d.iPAddress = NULL;
+        }
+        if (name->d.registeredID != NULL) {
+            wolfSSL_ASN1_OBJECT_free(name->d.registeredID);
+            name->d.registeredID = NULL;
+        }
+        if (name->d.ia5 != NULL) {
+            wolfSSL_ASN1_STRING_free(name->d.ia5);
+            name->d.ia5 = NULL;
+        }
+        XFREE(name, NULL, DYNAMIC_TYPE_OPENSSL);
+    }
+}
+
+void wolfSSL_GENERAL_NAMES_free(WOLFSSL_GENERAL_NAMES *gens)
+{
+    WOLFSSL_STACK* node;
+
+    WOLFSSL_ENTER("wolfSSL_GENERAL_NAMES_free");
+
+    if (gens == NULL) {
+        return;
+    }
+
+    /* parse through stack freeing each node */
+    node = gens->next;
+    while (gens->num > 1) {
+        WOLFSSL_STACK* tmp = node;
+        node = node->next;
+
+        wolfSSL_ASN1_OBJECT_free(tmp->data.obj);
+        XFREE(tmp, NULL, DYNAMIC_TYPE_ASN1);
+        gens->num -= 1;
+    }
+
+    /* free head of stack */
+    if (gens->num == 1) {
+        wolfSSL_ASN1_OBJECT_free(gens->data.obj);
+    }
+    XFREE(gens, NULL, DYNAMIC_TYPE_ASN1);
+}
+
+#if defined(OPENSSL_ALL)
+WOLF_STACK_OF(WOLFSSL_X509_EXTENSION)* wolfSSL_sk_X509_EXTENSION_new_null(void)
+{
+    WOLFSSL_STACK* sk = wolfSSL_sk_new_node(NULL);
+    if (sk) {
+        sk->type = STACK_TYPE_X509_EXT;
+    }
+
+    return (WOLF_STACK_OF(WOLFSSL_X509_EXTENSION)*)sk;;
+}
+
+/* returns the number of nodes on the stack */
+int wolfSSL_sk_X509_EXTENSION_num(WOLF_STACK_OF(WOLFSSL_X509_EXTENSION)* sk)
+{
+    if (sk != NULL) {
+        return (int)sk->num;
+    }
+    return WOLFSSL_FATAL_ERROR;
+}
+
+
+/* returns null on failure and pointer to internal value on success */
+WOLFSSL_X509_EXTENSION* wolfSSL_sk_X509_EXTENSION_value(
+        WOLF_STACK_OF(WOLFSSL_X509_EXTENSION)* sk, int idx)
+{
+    WOLFSSL_STACK* ret;
+
+    if (sk == NULL) {
+        return NULL;
+    }
+
+    ret = wolfSSL_sk_get_node(sk, idx);
+    if (ret != NULL) {
+        return ret->data.ext;
+    }
+    return NULL;
+}
+
+/* frees all of the nodes and the values in stack */
+void wolfSSL_sk_X509_EXTENSION_pop_free(
+        WOLF_STACK_OF(WOLFSSL_X509_EXTENSION)* sk,
+        void (*f) (WOLFSSL_X509_EXTENSION*))
+{
+    WOLFSSL_STACK* current;
+
+    if (sk == NULL) {
+        return;
+    }
+
+    current = sk;
+    while (current != NULL) {
+        WOLFSSL_STACK* toFree = current;
+        current = current->next;
+
+        if (f)
+            f(toFree->data.ext);
+        wolfSSL_sk_free_node(toFree);
+    }
+}
+
+#if defined(HAVE_ECC)
+/* Copies ecc_key into new WOLFSSL_EC_KEY object
+ *
+ * src  : EC_KEY to duplicate. If EC_KEY is not null, create new EC_KEY and copy
+ * internal ecc_key from src to dup.
+ *
+ * Returns pointer to duplicate EC_KEY.
+ */
+WOLFSSL_EC_KEY *wolfSSL_EC_KEY_dup(const WOLFSSL_EC_KEY *src)
+{
+    WOLFSSL_EC_KEY *dup;
+    ecc_key *key, *srcKey;
+    int ret;
+
+    WOLFSSL_ENTER("wolfSSL_EC_KEY_dup");
+
+    if (src == NULL || src->internal == NULL || src->group == NULL || \
+       src->pub_key == NULL || src->priv_key == NULL) {
+
+        WOLFSSL_MSG("src NULL error");
+        return NULL;
+    }
+
+    dup = wolfSSL_EC_KEY_new();
+    if (dup == NULL) {
+        WOLFSSL_MSG("wolfSSL_EC_KEY_new error");
+        return NULL;
+    }
+
+    key = (ecc_key*)dup->internal;
+    if (key == NULL) {
+        WOLFSSL_MSG("ecc_key NULL error");
+        wolfSSL_EC_KEY_free(dup);
+        return NULL;
+    }
+    srcKey = (ecc_key*)src->internal;
+
+    /* ecc_key */
+    /* copy pubkey */
+    ret = wc_ecc_copy_point(&srcKey->pubkey, &key->pubkey);
+    if (ret != MP_OKAY) {
+        WOLFSSL_MSG("wc_ecc_copy_point error");
+        wolfSSL_EC_KEY_free(dup);
+        return NULL;
+    }
+
+    /* copy private key k */
+    ret = mp_copy(&srcKey->k, &key->k);
+    if (ret != MP_OKAY) {
+        WOLFSSL_MSG("mp_copy error");
+        wolfSSL_EC_KEY_free(dup);
+        return NULL;
+    }
+
+    /* copy domain parameters */
+    if (srcKey->dp) {
+        ret = wc_ecc_set_curve(key, 0, srcKey->dp->id);
+        if (ret != 0) {
+            WOLFSSL_MSG("wc_ecc_set_curve error");
+            return NULL;
+        }
+    }
+
+    key->type  = srcKey->type;
+    key->idx   = srcKey->idx;
+    key->state = srcKey->state;
+    key->flags = srcKey->flags;
+
+    /* Copy group */
+    if (dup->group == NULL) {
+        WOLFSSL_MSG("EC_GROUP_new_by_curve_name error");
+        wolfSSL_EC_KEY_free(dup);
+        return NULL;
+    }
+
+    dup->group->curve_idx = src->group->curve_idx;
+    dup->group->curve_nid = src->group->curve_nid;
+    dup->group->curve_oid = src->group->curve_oid;
+
+    /* Copy public key */
+    if (src->pub_key->internal == NULL || dup->pub_key->internal == NULL) {
+        WOLFSSL_MSG("NULL pub_key error");
+        wolfSSL_EC_KEY_free(dup);
+        return NULL;
+    }
+
+    /* Copy public key internal */
+    ret = wc_ecc_copy_point((ecc_point*)src->pub_key->internal, \
+                            (ecc_point*)dup->pub_key->internal);
+    if (ret != MP_OKAY) {
+        WOLFSSL_MSG("ecc_copy_point error");
+        wolfSSL_EC_KEY_free(dup);
+        return NULL;
+    }
+
+    /* Copy X, Y, Z */
+    dup->pub_key->X = wolfSSL_BN_dup(src->pub_key->X);
+    if (!dup->pub_key->X && src->pub_key->X) {
+        WOLFSSL_MSG("Error copying EC_POINT");
+        wolfSSL_EC_KEY_free(dup);
+        return NULL;
+    }
+    dup->pub_key->Y = wolfSSL_BN_dup(src->pub_key->Y);
+    if (!dup->pub_key->Y && src->pub_key->Y) {
+        WOLFSSL_MSG("Error copying EC_POINT");
+        wolfSSL_EC_KEY_free(dup);
+        return NULL;
+    }
+    dup->pub_key->Z = wolfSSL_BN_dup(src->pub_key->Z);
+    if (!dup->pub_key->Z && src->pub_key->Z) {
+        WOLFSSL_MSG("Error copying EC_POINT");
+        wolfSSL_EC_KEY_free(dup);
+        return NULL;
+    }
+
+    dup->pub_key->inSet = src->pub_key->inSet;
+    dup->pub_key->exSet = src->pub_key->exSet;
+
+    /* Copy private key */
+    if (src->priv_key->internal == NULL || dup->priv_key->internal == NULL) {
+        WOLFSSL_MSG("NULL priv_key error");
+        wolfSSL_EC_KEY_free(dup);
+        return NULL;
+    }
+
+    /* Free priv_key before call to dup function */
+    wolfSSL_BN_free(dup->priv_key);
+    dup->priv_key = wolfSSL_BN_dup(src->priv_key);
+    if (dup->priv_key == NULL) {
+        WOLFSSL_MSG("BN_dup error");
+        wolfSSL_EC_KEY_free(dup);
+        return NULL;
+    }
+
+    return dup;
+
+}
+#endif /* HAVE_ECC */
+
+#if !defined(NO_DH)
+int wolfSSL_DH_check(const WOLFSSL_DH *dh, int *codes)
+{
+    int isPrime = MP_NO, codeTmp = 0;
+    WC_RNG rng;
+
+    WOLFSSL_ENTER("wolfSSL_DH_check");
+    if (dh == NULL){
+        return WOLFSSL_FAILURE;
+    }
+
+    if (dh->g == NULL || dh->g->internal == NULL){
+        codeTmp = DH_NOT_SUITABLE_GENERATOR;
+    }
+
+    if (dh->p == NULL || dh->p->internal == NULL){
+        codeTmp = DH_CHECK_P_NOT_PRIME;
+    }
+    else
+    {
+        /* test if dh->p has prime */
+        if (wc_InitRng(&rng) == 0){
+            mp_prime_is_prime_ex((mp_int*)dh->p->internal,8,&isPrime,&rng);
+        }
+        else {
+            WOLFSSL_MSG("Error initializing rng\n");
+            return WOLFSSL_FAILURE;
+        }
+        wc_FreeRng(&rng);
+        if (isPrime != MP_YES){
+            codeTmp = DH_CHECK_P_NOT_PRIME;
+        }
+    }
+    /* User may choose to enter NULL for codes if they don't want to check it*/
+    if (codes != NULL){
+        *codes = codeTmp;
+    }
+
+    /* if codeTmp was set,some check was flagged invalid */
+    if (codeTmp){
+        return WOLFSSL_FAILURE;
+    }
+
+    return WOLFSSL_SUCCESS;
+}
+
+/* Converts DER encoded DH parameters to a WOLFSSL_DH structure.
+ *
+ * dh   : structure to copy DH parameters into.
+ * pp   : DER encoded DH parameters
+ * length   : length to copy
+ *
+ * Returns pointer to WOLFSSL_DH structure on success, or NULL on failure
+ */
+WOLFSSL_DH *wolfSSL_d2i_DHparams(WOLFSSL_DH **dh, const unsigned char **pp,
+                                                                    long length)
+{
+    WOLFSSL_DH *newDH = NULL;
+    int ret;
+    word32 idx = 0;
+
+    WOLFSSL_ENTER("wolfSSL_d2i_DHparams");
+
+    if (pp == NULL || length <= 0) {
+        WOLFSSL_MSG("bad argument");
+        return NULL;
+    }
+
+    if ((newDH = wolfSSL_DH_new()) == NULL) {
+        WOLFSSL_MSG("wolfSSL_DH_new() failed");
+        return NULL;
+    }
+
+    ret = wc_DhKeyDecode(*pp, &idx, (DhKey*)newDH->internal, (word32)length);
+    if (ret != 0) {
+        WOLFSSL_MSG("DhKeyDecode() failed");
+        wolfSSL_DH_free(newDH);
+        return NULL;
+    }
+    newDH->inSet = 1;
+
+    if (SetDhExternal(newDH) != WOLFSSL_SUCCESS) {
+        WOLFSSL_MSG("SetDhExternal failed");
+        wolfSSL_DH_free(newDH);
+        return NULL;
+    }
+
+    *pp += length;
+    if (dh != NULL){
+        *dh = newDH;
+    }
+
+    return newDH;
+}
+
+/* Converts internal WOLFSSL_DH structure to DER encoded DH.
+ *
+ * dh   : structure to copy DH parameters from.
+ * out  : DER buffer for DH parameters
+ *
+ * Returns size of DER on success and WOLFSSL_FAILURE if error
+ */
+int wolfSSL_i2d_DHparams(const WOLFSSL_DH *dh, unsigned char **out)
+{
+    word32 len;
+    int ret = 0;
+
+    WOLFSSL_ENTER("wolfSSL_i2d_DHparams");
+
+    if (dh == NULL) {
+        WOLFSSL_MSG("Bad parameters");
+        return WOLFSSL_FAILURE;
+    }
+
+    /* Get total length */
+    len = 2 + mp_leading_bit((mp_int*)dh->p->internal) +
+              mp_unsigned_bin_size((mp_int*)dh->p->internal) +
+          2 + mp_leading_bit((mp_int*)dh->g->internal) +
+              mp_unsigned_bin_size((mp_int*)dh->g->internal);
+
+    /* Two bytes required for length if ASN.1 SEQ data greater than 127 bytes
+     * and less than 256 bytes.
+     */
+    len = ((len > 127) ? 2 : 1) + len;
+
+    if (out != NULL && *out != NULL) {
+        ret = StoreDHparams(*out, &len, (mp_int*)dh->p->internal,
+                                        (mp_int*)dh->g->internal);
+        if (ret != MP_OKAY) {
+            WOLFSSL_MSG("StoreDHparams error");
+            len = 0;
+        }
+        else{
+            *out += len;
+        }
+    }
+    return (int)len;
+}
+#endif /* !NO_DH */
+
+#endif /* OPENSSL_ALL */
+
+#endif /* OPENSSL_EXTRA */
+
+#ifndef NO_FILESYSTEM
+
+#ifndef NO_STDIO_FILESYSTEM
+
+WOLFSSL_X509* wolfSSL_X509_d2i_fp(WOLFSSL_X509** x509, XFILE file)
+{
+    WOLFSSL_X509* newX509 = NULL;
+
+    WOLFSSL_ENTER("wolfSSL_X509_d2i_fp");
+
+    if (file != XBADFILE) {
+        byte* fileBuffer = NULL;
+        long sz = 0;
+
+        if (XFSEEK(file, 0, XSEEK_END) != 0)
+            return NULL;
+        sz = XFTELL(file);
+        XREWIND(file);
+
+        if (sz > MAX_WOLFSSL_FILE_SIZE || sz < 0) {
+            WOLFSSL_MSG("X509_d2i file size error");
+            return NULL;
+        }
+
+        fileBuffer = (byte*)XMALLOC(sz, NULL, DYNAMIC_TYPE_FILE);
+        if (fileBuffer != NULL) {
+            int ret = (int)XFREAD(fileBuffer, 1, sz, file);
+            if (ret == sz) {
+                newX509 = wolfSSL_X509_d2i(NULL, fileBuffer, (int)sz);
+            }
+            XFREE(fileBuffer, NULL, DYNAMIC_TYPE_FILE);
+        }
+    }
+
+    if (x509 != NULL)
+        *x509 = newX509;
+
+    return newX509;
+}
+
+#endif /* NO_STDIO_FILESYSTEM */
+
+WOLFSSL_ABI
+WOLFSSL_X509* wolfSSL_X509_load_certificate_file(const char* fname, int format)
+{
+#ifdef WOLFSSL_SMALL_STACK
+    byte  staticBuffer[1]; /* force heap usage */
+#else
+    byte  staticBuffer[FILE_BUFFER_SIZE];
+#endif
+    byte* fileBuffer = staticBuffer;
+    int   dynamic = 0;
+    int   ret;
+    long  sz = 0;
+    XFILE file;
+
+    WOLFSSL_X509* x509 = NULL;
+
+    /* Check the inputs */
+    if ((fname == NULL) ||
+        (format != WOLFSSL_FILETYPE_ASN1 && format != WOLFSSL_FILETYPE_PEM))
+        return NULL;
+
+    file = XFOPEN(fname, "rb");
+    if (file == XBADFILE)
+        return NULL;
+
+    if (XFSEEK(file, 0, XSEEK_END) != 0){
+        XFCLOSE(file);
+        return NULL;
+    }
+    sz = XFTELL(file);
+    XREWIND(file);
+
+    if (sz > MAX_WOLFSSL_FILE_SIZE || sz < 0) {
+        WOLFSSL_MSG("X509_load_certificate_file size error");
+        XFCLOSE(file);
+        return NULL;
+    }
+
+    if (sz > (long)sizeof(staticBuffer)) {
+        fileBuffer = (byte*)XMALLOC(sz, NULL, DYNAMIC_TYPE_FILE);
+        if (fileBuffer == NULL) {
+            XFCLOSE(file);
+            return NULL;
+        }
+        dynamic = 1;
+    }
+
+    ret = (int)XFREAD(fileBuffer, 1, sz, file);
+    if (ret != sz) {
+        XFCLOSE(file);
+        if (dynamic)
+            XFREE(fileBuffer, NULL, DYNAMIC_TYPE_FILE);
+        return NULL;
+    }
+
+    XFCLOSE(file);
+
+    x509 = wolfSSL_X509_load_certificate_buffer(fileBuffer, (int)sz, format);
+
+    if (dynamic)
+        XFREE(fileBuffer, NULL, DYNAMIC_TYPE_FILE);
+
+    return x509;
+}
+
+#endif /* NO_FILESYSTEM */
+
+
+WOLFSSL_X509* wolfSSL_X509_load_certificate_buffer(
+    const unsigned char* buf, int sz, int format)
+{
+    int ret;
+    WOLFSSL_X509* x509 = NULL;
+    DerBuffer* der = NULL;
+
+    WOLFSSL_ENTER("wolfSSL_X509_load_certificate_ex");
+
+    if (format == WOLFSSL_FILETYPE_PEM) {
+    #ifdef WOLFSSL_PEM_TO_DER
+        if (PemToDer(buf, sz, CERT_TYPE, &der, NULL, NULL, NULL) != 0) {
+            FreeDer(&der);
+        }
+    #else
+        ret = NOT_COMPILED_IN;
+    #endif
+    }
+    else {
+        ret = AllocDer(&der, (word32)sz, CERT_TYPE, NULL);
+        if (ret == 0) {
+            XMEMCPY(der->buffer, buf, sz);
+        }
+    }
+
+    /* At this point we want `der` to have the certificate in DER format */
+    /* ready to be decoded. */
+    if (der != NULL && der->buffer != NULL) {
+    #ifdef WOLFSSL_SMALL_STACK
+        DecodedCert* cert;
+    #else
+        DecodedCert  cert[1];
+    #endif
+
+    #ifdef WOLFSSL_SMALL_STACK
+        cert = (DecodedCert*)XMALLOC(sizeof(DecodedCert), NULL,
+                                     DYNAMIC_TYPE_DCERT);
+        if (cert != NULL)
+    #endif
+        {
+            InitDecodedCert(cert, der->buffer, der->length, NULL);
+            if (ParseCertRelative(cert, CERT_TYPE, 0, NULL) == 0) {
+                x509 = (WOLFSSL_X509*)XMALLOC(sizeof(WOLFSSL_X509), NULL,
+                                                             DYNAMIC_TYPE_X509);
+                if (x509 != NULL) {
+                    InitX509(x509, 1, NULL);
+                    if (CopyDecodedToX509(x509, cert) != 0) {
+                        wolfSSL_X509_free(x509);
+                        x509 = NULL;
+                    }
+                }
+            }
+
+            FreeDecodedCert(cert);
+        #ifdef WOLFSSL_SMALL_STACK
+            XFREE(cert, NULL, DYNAMIC_TYPE_DCERT);
+        #endif
+        }
+
+        FreeDer(&der);
+    }
+
+    return x509;
+}
+
+#endif /* KEEP_PEER_CERT || SESSION_CERTS */
+
+/* OPENSSL_EXTRA is needed for wolfSSL_X509_d21 function
+   KEEP_OUR_CERT is to insure ability for returning ssl certificate */
+#if (defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)) && \
+    defined(KEEP_OUR_CERT)
+WOLFSSL_X509* wolfSSL_get_certificate(WOLFSSL* ssl)
+{
+    if (ssl == NULL) {
+        return NULL;
+    }
+
+    if (ssl->buffers.weOwnCert) {
+        if (ssl->ourCert == NULL) {
+            if (ssl->buffers.certificate == NULL) {
+                WOLFSSL_MSG("Certificate buffer not set!");
+                return NULL;
+            }
+            #ifndef WOLFSSL_X509_STORE_CERTS
+            ssl->ourCert = wolfSSL_X509_d2i(NULL,
+                                              ssl->buffers.certificate->buffer,
+                                              ssl->buffers.certificate->length);
+            #endif
+        }
+        return ssl->ourCert;
+    }
+    else { /* if cert not owned get parent ctx cert or return null */
+        if (ssl->ctx) {
+            if (ssl->ctx->ourCert == NULL) {
+                if (ssl->ctx->certificate == NULL) {
+                    WOLFSSL_MSG("Ctx Certificate buffer not set!");
+                    return NULL;
+                }
+                #ifndef WOLFSSL_X509_STORE_CERTS
+                ssl->ctx->ourCert = wolfSSL_X509_d2i(NULL,
+                                               ssl->ctx->certificate->buffer,
+                                               ssl->ctx->certificate->length);
+                #endif
+                ssl->ctx->ownOurCert = 1;
+            }
+            return ssl->ctx->ourCert;
+        }
+    }
+
+    return NULL;
+}
+#endif /* OPENSSL_EXTRA && KEEP_OUR_CERT */
+#endif /* NO_CERTS */
+
+
+#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
+#ifndef NO_ASN
+void wolfSSL_ASN1_OBJECT_free(WOLFSSL_ASN1_OBJECT* obj)
+{
+    if (obj == NULL) {
+        return;
+    }
+    if ((obj->obj != NULL) && ((obj->dynamic & WOLFSSL_ASN1_DYNAMIC_DATA) != 0)) {
+        WOLFSSL_MSG("Freeing ASN1 data");
+        XFREE((void*)obj->obj, obj->heap, DYNAMIC_TYPE_ASN1);
+        obj->obj = NULL;
+    }
+    #if defined(WOLFSSL_QT) || defined(OPENSSL_ALL)
+    if (obj->pathlen != NULL) {
+        wolfSSL_ASN1_INTEGER_free(obj->pathlen);
+        obj->pathlen = NULL;
+    }
+    #endif
+    if ((obj->dynamic & WOLFSSL_ASN1_DYNAMIC) != 0) {
+        WOLFSSL_MSG("Freeing ASN1 OBJECT");
+        XFREE(obj, NULL, DYNAMIC_TYPE_ASN1);
+    }
+}
+#endif /* NO_ASN */
+#endif /* OPENSSL_EXTRA || OPENSSL_EXTRA_X509_SMALL */
+
+#ifdef OPENSSL_EXTRA
+#ifndef NO_ASN
+WOLFSSL_ASN1_OBJECT* wolfSSL_ASN1_OBJECT_new(void)
+{
+    WOLFSSL_ASN1_OBJECT* obj;
+
+    obj = (WOLFSSL_ASN1_OBJECT*)XMALLOC(sizeof(WOLFSSL_ASN1_OBJECT), NULL,
+                                        DYNAMIC_TYPE_ASN1);
+    if (obj == NULL) {
+        return NULL;
+    }
+
+    XMEMSET(obj, 0, sizeof(WOLFSSL_ASN1_OBJECT));
+    obj->d.ia5 = &(obj->d.ia5_internal);
+#if defined(WOLFSSL_QT) || defined(OPENSSL_ALL)
+    obj->d.iPAddress = &(obj->d.iPAddress_internal);
+#endif
+    obj->dynamic |= WOLFSSL_ASN1_DYNAMIC;
+    return obj;
+}
+
+/* Creates and returns a new WOLFSSL_CIPHER stack. */
+WOLFSSL_STACK* wolfSSL_sk_new_asn1_obj(void)
+{
+    WOLFSSL_STACK* sk;
+    WOLFSSL_ENTER("wolfSSL_sk_new_asn1_obj");
+
+    sk = wolfSSL_sk_new_null();
+    if (sk == NULL)
+        return NULL;
+    sk->type = STACK_TYPE_OBJ;
+
+    return sk;
+}
+
+/* return 1 on success 0 on fail */
+int wolfSSL_sk_ASN1_OBJECT_push(WOLF_STACK_OF(WOLFSSL_ASN1_OBJECT)* sk,
+                                              WOLFSSL_ASN1_OBJECT* obj)
+{
+    WOLFSSL_STACK* node;
+
+    WOLFSSL_ENTER("wolfSSL_sk_ASN1_OBJECT_push");
+
+    if (sk == NULL || obj == NULL) {
+        return WOLFSSL_FAILURE;
+    }
+
+    /* no previous values in stack */
+    if (sk->data.obj == NULL) {
+        sk->data.obj = obj;
+        sk->num += 1;
+        return WOLFSSL_SUCCESS;
+    }
+
+    /* stack already has value(s) create a new node and add more */
+    node = (WOLFSSL_STACK*)XMALLOC(sizeof(WOLFSSL_STACK), NULL,
+                                                             DYNAMIC_TYPE_ASN1);
+    if (node == NULL) {
+        WOLFSSL_MSG("Memory error");
+        return WOLFSSL_FAILURE;
+    }
+    XMEMSET(node, 0, sizeof(WOLFSSL_STACK));
+
+    /* push new obj onto head of stack */
+    node->data.obj  = sk->data.obj;
+    node->next      = sk->next;
+    node->type      = sk->type;
+    sk->next        = node;
+    sk->data.obj    = obj;
+    sk->num        += 1;
+
+    return WOLFSSL_SUCCESS;
+}
+
+
+WOLFSSL_ASN1_OBJECT* wolfSSL_sk_ASN1_OBJECT_pop(
+                                        WOLF_STACK_OF(WOLFSSL_ASN1_OBJECT)* sk)
+{
+    WOLFSSL_STACK* node;
+    WOLFSSL_ASN1_OBJECT* obj;
+
+    if (sk == NULL) {
+        return NULL;
+    }
+
+    node = sk->next;
+    obj = sk->data.obj;
+
+    if (node != NULL) { /* update sk and remove node from stack */
+        sk->data.obj = node->data.obj;
+        sk->next = node->next;
+        XFREE(node, NULL, DYNAMIC_TYPE_ASN1);
+    }
+    else { /* last obj in stack */
+        sk->data.obj = NULL;
+    }
+
+    if (sk->num > 0) {
+        sk->num -= 1;
+    }
+
+    return obj;
+}
+
+
+/* Free the structure for ASN1_OBJECT stack
+ *
+ * sk  stack to free nodes in
+ */
+void wolfSSL_sk_ASN1_OBJECT_free(WOLF_STACK_OF(WOLFSSL_ASN1_OBJECT)* sk)
+{
+    wolfSSL_sk_ASN1_OBJECT_pop_free(sk, NULL);
+}
+
+/* Free's all nodes in ASN1_OBJECT stack.
+ * This is different then wolfSSL_ASN1_OBJECT_free in that it allows for
+ * choosing the function to use when freeing an ASN1_OBJECT stack.
+ *
+ * sk  stack to free nodes in
+ * f   X509 free function
+ */
+void wolfSSL_sk_ASN1_OBJECT_pop_free(WOLF_STACK_OF(WOLFSSL_ASN1_OBJECT)* sk,
+                                     void (*f) (WOLFSSL_ASN1_OBJECT*))
+{
+    WOLFSSL_STACK* node;
+
+    WOLFSSL_ENTER("wolfSSL_sk_ASN1_OBJECT_pop_free");
+
+    if (sk == NULL) {
+        WOLFSSL_MSG("Parameter error");
+        return;
+    }
+
+    /* parse through stack freeing each node */
+    node = sk->next;
+    while (node && sk->num > 1) {
+        WOLFSSL_STACK* tmp = node;
+        node = node->next;
+
+        if (f)
+            f(tmp->data.obj);
+        else
+            wolfSSL_ASN1_OBJECT_free(tmp->data.obj);
+        tmp->data.obj = NULL;
+        XFREE(tmp, NULL, DYNAMIC_TYPE_ASN1);
+        sk->num -= 1;
+    }
+
+    /* free head of stack */
+    if (sk->num == 1) {
+        if (f)
+            f(sk->data.obj);
+        else
+            wolfSSL_ASN1_OBJECT_free(sk->data.obj);
+        sk->data.obj = NULL;
+    }
+    XFREE(sk, NULL, DYNAMIC_TYPE_ASN1);
+}
+
+int wolfSSL_ASN1_STRING_to_UTF8(unsigned char **out, WOLFSSL_ASN1_STRING *in)
+{
+    /*
+       ASN1_STRING_to_UTF8() converts the string in to UTF8 format,
+       the converted data is allocated in a buffer in *out.
+       The length of out is returned or a negative error code.
+       The buffer *out should be free using OPENSSL_free().
+       */
+    unsigned char* buf;
+    unsigned char* inPtr;
+    int inLen;
+
+    if (!out || !in) {
+        return -1;
+    }
+
+    inPtr = wolfSSL_ASN1_STRING_data(in);
+    inLen = wolfSSL_ASN1_STRING_length(in);
+    if (!inPtr || inLen < 0) {
+        return -1;
+    }
+    buf = (unsigned char*)XMALLOC(inLen + 1, NULL, DYNAMIC_TYPE_OPENSSL);
+    if (!buf) {
+        return -1;
+    }
+    XMEMCPY(buf, inPtr, inLen + 1);
+    *out = buf;
+    return inLen;
+}
+
+/* Returns string representation of ASN1_STRING */
+char* wolfSSL_i2s_ASN1_STRING(WOLFSSL_v3_ext_method *method,
+    const WOLFSSL_ASN1_STRING *s)
+{
+    int i;
+    int tmpSz = 100;
+    int valSz = 5;
+    char* tmp;
+    char val[5];
+    unsigned char* str;
+
+    WOLFSSL_ENTER("wolfSSL_i2s_ASN1_STRING");
+    (void)method;
+
+    if(s == NULL || s->data == NULL) {
+        WOLFSSL_MSG("Bad Function Argument");
+        return NULL;
+    }
+    str = (unsigned char*)XMALLOC(s->length, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    if (str == NULL) {
+        WOLFSSL_MSG("Memory Error");
+        return NULL;
+    }
+    XMEMCPY(str, (unsigned char*)s->data, s->length);
+
+    tmp = (char*)XMALLOC(tmpSz, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    if (tmp == NULL) {
+        WOLFSSL_MSG("Memory Error");
+        XFREE(str, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+        return NULL;
+    }
+    XMEMSET(tmp, 0, tmpSz);
+
+    for (i = 0; i < tmpSz && i < (s->length - 1); i++) {
+        XSNPRINTF(val, valSz - 1, "%02X:", str[i]);
+        XSTRNCAT(tmp, val, valSz);
+    }
+    XSNPRINTF(val, valSz - 1, "%02X", str[i]);
+    XSTRNCAT(tmp, val, valSz);
+    XFREE(str, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+
+    return tmp;
+}
+#endif /* NO_ASN */
+
+void wolfSSL_set_connect_state(WOLFSSL* ssl)
+{
+    WOLFSSL_ENTER("wolfSSL_set_connect_state");
+    if (ssl == NULL) {
+        WOLFSSL_MSG("WOLFSSL struct pointer passed in was null");
+        return;
+    }
+
+    #ifndef NO_DH
+    /* client creates its own DH parameters on handshake */
+    if (ssl->buffers.serverDH_P.buffer && ssl->buffers.weOwnDH) {
+        XFREE(ssl->buffers.serverDH_P.buffer, ssl->heap,
+            DYNAMIC_TYPE_PUBLIC_KEY);
+    }
+    ssl->buffers.serverDH_P.buffer = NULL;
+    if (ssl->buffers.serverDH_G.buffer && ssl->buffers.weOwnDH) {
+        XFREE(ssl->buffers.serverDH_G.buffer, ssl->heap,
+            DYNAMIC_TYPE_PUBLIC_KEY);
+    }
+    ssl->buffers.serverDH_G.buffer = NULL;
+    #endif
+
+    if (InitSSL_Side(ssl, WOLFSSL_CLIENT_END) != WOLFSSL_SUCCESS) {
+        WOLFSSL_MSG("Error initializing client side");
+    }
+}
+#endif /* OPENSSL_EXTRA */
+
+
+int wolfSSL_get_shutdown(const WOLFSSL* ssl)
+{
+    int isShutdown = 0;
+
+    WOLFSSL_ENTER("wolfSSL_get_shutdown");
+
+    if (ssl) {
+        /* in OpenSSL, WOLFSSL_SENT_SHUTDOWN = 1, when closeNotifySent   *
+         * WOLFSSL_RECEIVED_SHUTDOWN = 2, from close notify or fatal err */
+        isShutdown = ((ssl->options.closeNotify||ssl->options.connReset) << 1)
+                    | (ssl->options.sentNotify);
+    }
+    return isShutdown;
+}
+
+
+int wolfSSL_session_reused(WOLFSSL* ssl)
+{
+    int resuming = 0;
+    if (ssl)
+        resuming = ssl->options.resuming;
+    return resuming;
+}
+
+#if defined(OPENSSL_EXTRA) || defined(HAVE_EXT_CACHE)
+WOLFSSL_SESSION* wolfSSL_SESSION_dup(WOLFSSL_SESSION* session)
+{
+#ifdef HAVE_EXT_CACHE
+    WOLFSSL_SESSION* copy;
+
+    WOLFSSL_ENTER("wolfSSL_SESSION_dup");
+
+    if (session == NULL)
+        return NULL;
+#ifdef HAVE_SESSION_TICKET
+    if (session->isDynamic && !session->ticket) {
+        WOLFSSL_MSG("Session dynamic flag is set but ticket pointer is null");
+        return NULL;
+    }
+#endif
+
+    copy = (WOLFSSL_SESSION*)XMALLOC(sizeof(WOLFSSL_SESSION), NULL,
+            DYNAMIC_TYPE_OPENSSL);
+    if (copy != NULL) {
+        XMEMCPY(copy, session, sizeof(WOLFSSL_SESSION));
+        copy->isAlloced = 1;
+#ifdef HAVE_SESSION_TICKET
+        if (session->isDynamic) {
+            copy->ticket = (byte*)XMALLOC(session->ticketLen, NULL,
+                                                    DYNAMIC_TYPE_SESSION_TICK);
+            XMEMCPY(copy->ticket, session->ticket, session->ticketLen);
+        } else {
+            copy->ticket = copy->staticTicket;
+        }
+#endif
+#if defined(SESSION_CERTS) && defined(OPENSSL_EXTRA)
+        copy->peer = wolfSSL_X509_dup(session->peer);
+#endif
+    }
+    return copy;
+#else
+    WOLFSSL_MSG("wolfSSL_SESSION_dup was called "
+                "but HAVE_EXT_CACHE is not defined");
+    (void)session;
+    return NULL;
+#endif /* HAVE_EXT_CACHE */
+}
+
+void wolfSSL_SESSION_free(WOLFSSL_SESSION* session)
+{
+    if (session == NULL)
+        return;
+
+#if defined(SESSION_CERTS) && defined(OPENSSL_EXTRA)
+    if (session->peer) {
+        wolfSSL_X509_free(session->peer);
+    }
+#endif
+
+#ifdef HAVE_EXT_CACHE
+    if (session->isAlloced) {
+    #ifdef HAVE_SESSION_TICKET
+        if (session->isDynamic)
+            XFREE(session->ticket, NULL, DYNAMIC_TYPE_SESSION_TICK);
+    #endif
+        XFREE(session, NULL, DYNAMIC_TYPE_OPENSSL);
+    }
+#else
+    /* No need to free since cache is static */
+    (void)session;
+#endif
+}
+#endif
+
+
+/* helper function that takes in a protocol version struct and returns string */
+static const char* wolfSSL_internal_get_version(ProtocolVersion* version)
+{
+    WOLFSSL_ENTER("wolfSSL_get_version");
+
+    if (version == NULL) {
+        return "Bad arg";
+    }
+
+    if (version->major == SSLv3_MAJOR) {
+        switch (version->minor) {
+        #ifndef NO_OLD_TLS
+            #ifdef WOLFSSL_ALLOW_SSLV3
+            case SSLv3_MINOR :
+                return "SSLv3";
+            #endif
+            #ifdef WOLFSSL_ALLOW_TLSV10
+            case TLSv1_MINOR :
+                return "TLSv1";
+            #endif
+            case TLSv1_1_MINOR :
+                return "TLSv1.1";
+        #endif
+            case TLSv1_2_MINOR :
+                return "TLSv1.2";
+        #ifdef WOLFSSL_TLS13
+            case TLSv1_3_MINOR :
+            #ifdef WOLFSSL_TLS13_DRAFT
+                #ifdef WOLFSSL_TLS13_DRAFT_18
+                    return "TLSv1.3 (Draft 18)";
+                #elif defined(WOLFSSL_TLS13_DRAFT_22)
+                    return "TLSv1.3 (Draft 22)";
+                #elif defined(WOLFSSL_TLS13_DRAFT_23)
+                    return "TLSv1.3 (Draft 23)";
+                #elif defined(WOLFSSL_TLS13_DRAFT_26)
+                    return "TLSv1.3 (Draft 26)";
+                #else
+                    return "TLSv1.3 (Draft 28)";
+                #endif
+            #else
+                return "TLSv1.3";
+            #endif
+        #endif
+            default:
+                return "unknown";
+        }
+    }
+#ifdef WOLFSSL_DTLS
+    else if (version->major == DTLS_MAJOR) {
+        switch (version->minor) {
+            case DTLS_MINOR :
+                return "DTLS";
+            case DTLSv1_2_MINOR :
+                return "DTLSv1.2";
+            default:
+                return "unknown";
+        }
+    }
+#endif /* WOLFSSL_DTLS */
+    return "unknown";
+}
+
+
+const char* wolfSSL_get_version(WOLFSSL* ssl)
+{
+    if (ssl == NULL) {
+        WOLFSSL_MSG("Bad argument");
+        return "unknown";
+    }
+
+    return wolfSSL_internal_get_version(&ssl->version);
+}
+
+
+/* current library version */
+const char* wolfSSL_lib_version(void)
+{
+    return LIBWOLFSSL_VERSION_STRING;
+}
+
+
+/* current library version in hex */
+word32 wolfSSL_lib_version_hex(void)
+{
+    return LIBWOLFSSL_VERSION_HEX;
+}
+
+
+int wolfSSL_get_current_cipher_suite(WOLFSSL* ssl)
+{
+    WOLFSSL_ENTER("SSL_get_current_cipher_suite");
+    if (ssl)
+        return (ssl->options.cipherSuite0 << 8) | ssl->options.cipherSuite;
+    return 0;
+}
+
+WOLFSSL_CIPHER* wolfSSL_get_current_cipher(WOLFSSL* ssl)
+{
+    WOLFSSL_ENTER("SSL_get_current_cipher");
+    if (ssl) {
+        ssl->cipher.cipherSuite0 = ssl->options.cipherSuite0;
+        ssl->cipher.cipherSuite  = ssl->options.cipherSuite;
+        return &ssl->cipher;
+    }
+    else
+        return NULL;
+}
+
+
+const char* wolfSSL_CIPHER_get_name(const WOLFSSL_CIPHER* cipher)
+{
+    WOLFSSL_ENTER("wolfSSL_CIPHER_get_name");
+
+    if (cipher == NULL) {
+        return NULL;
+    }
+
+    #if !defined(WOLFSSL_CIPHER_INTERNALNAME) && !defined(NO_ERROR_STRINGS) && \
+        !defined(WOLFSSL_QT)
+        return GetCipherNameIana(cipher->cipherSuite0, cipher->cipherSuite);
+    #else
+        return wolfSSL_get_cipher_name_from_suite(cipher->cipherSuite0,
+                cipher->cipherSuite);
+    #endif
+}
+
+const char*  wolfSSL_CIPHER_get_version(const WOLFSSL_CIPHER* cipher)
+{
+    WOLFSSL_ENTER("SSL_CIPHER_get_version");
+
+    if (cipher == NULL || cipher->ssl == NULL) {
+        return NULL;
+    }
+
+    return wolfSSL_get_version(cipher->ssl);
+}
+
+const char* wolfSSL_SESSION_CIPHER_get_name(WOLFSSL_SESSION* session)
+{
+    if (session == NULL) {
+        return NULL;
+    }
+
+#if defined(SESSION_CERTS) || !defined(NO_RESUME_SUITE_CHECK) || \
+                        (defined(WOLFSSL_TLS13) && defined(HAVE_SESSION_TICKET))
+    #if !defined(WOLFSSL_CIPHER_INTERNALNAME) && !defined(NO_ERROR_STRINGS)
+        return GetCipherNameIana(session->cipherSuite0, session->cipherSuite);
+    #else
+        return GetCipherNameInternal(session->cipherSuite0, session->cipherSuite);
+    #endif
+#else
+    return NULL;
+#endif
+}
+
+const char* wolfSSL_get_cipher(WOLFSSL* ssl)
+{
+    WOLFSSL_ENTER("wolfSSL_get_cipher");
+    return wolfSSL_CIPHER_get_name(wolfSSL_get_current_cipher(ssl));
+}
+
+/* gets cipher name in the format DHE-RSA-... rather then TLS_DHE... */
+const char* wolfSSL_get_cipher_name(WOLFSSL* ssl)
+{
+    /* get access to cipher_name_idx in internal.c */
+    return wolfSSL_get_cipher_name_internal(ssl);
+}
+
+const char* wolfSSL_get_cipher_name_from_suite(const byte cipherSuite0,
+    const byte cipherSuite)
+{
+    return GetCipherNameInternal(cipherSuite0, cipherSuite);
+}
+
+const char* wolfSSL_get_cipher_name_iana_from_suite(const byte cipherSuite0,
+        const byte cipherSuite)
+{
+    return GetCipherNameIana(cipherSuite0, cipherSuite);
+}
+
+
+#if defined(WOLFSSL_QT) || defined(OPENSSL_ALL)
+/* Creates and returns a new WOLFSSL_CIPHER stack. */
+WOLFSSL_STACK* wolfSSL_sk_new_cipher(void)
+{
+    WOLFSSL_STACK* sk;
+    WOLFSSL_ENTER("wolfSSL_sk_new_cipher");
+
+    sk = wolfSSL_sk_new_null();
+    if (sk == NULL)
+        return NULL;
+    sk->type = STACK_TYPE_CIPHER;
+
+    return sk;
+}
+
+#ifndef NO_WOLFSSL_STUB
+/* Keep as stubs for now */
+/* return 1 on success 0 on fail */
+int wolfSSL_sk_CIPHER_push(WOLF_STACK_OF(WOLFSSL_CIPHER)* sk,
+                                                      WOLFSSL_CIPHER* cipher)
+{
+    WOLFSSL_STUB("wolfSSL_sk_CIPHER_push");
+    (void)sk;
+    (void)cipher;
+    return 0;
+}
+
+
+WOLFSSL_CIPHER* wolfSSL_sk_CIPHER_pop(WOLF_STACK_OF(WOLFSSL_CIPHER)* sk)
+{
+    WOLFSSL_STUB("wolfSSL_sk_CIPHER_pop");
+    (void)sk;
+    return NULL;
+}
+#endif /* NO_WOLFSSL_STUB */
+#endif /* WOLFSSL_QT || OPENSSL_ALL */
+
+word32 wolfSSL_CIPHER_get_id(const WOLFSSL_CIPHER* cipher)
+{
+    word16 cipher_id = 0;
+
+    WOLFSSL_ENTER("SSL_CIPHER_get_id");
+
+    if (cipher && cipher->ssl) {
+        cipher_id = (cipher->ssl->options.cipherSuite0 << 8) |
+                     cipher->ssl->options.cipherSuite;
+    }
+
+    return cipher_id;
+}
+
+const WOLFSSL_CIPHER* wolfSSL_get_cipher_by_value(word16 value)
+{
+    const WOLFSSL_CIPHER* cipher = NULL;
+    byte cipherSuite0, cipherSuite;
+    WOLFSSL_ENTER("SSL_get_cipher_by_value");
+
+    /* extract cipher id information */
+    cipherSuite =   (value       & 0xFF);
+    cipherSuite0 = ((value >> 8) & 0xFF);
+
+    /* TODO: lookup by cipherSuite0 / cipherSuite */
+    (void)cipherSuite0;
+    (void)cipherSuite;
+
+    return cipher;
+}
+
+
+#if defined(OPENSSL_ALL)
+/* Free the structure for WOLFSSL_CIPHER stack
+ *
+ * sk  stack to free nodes in
+ */
+void wolfSSL_sk_CIPHER_free(WOLF_STACK_OF(WOLFSSL_CIPHER)* sk)
+{
+    WOLFSSL_STACK* node;
+    WOLFSSL_STACK* tmp;
+    WOLFSSL_ENTER("wolfSSL_sk_CIPHER_free");
+
+    if (sk == NULL)
+        return;
+
+    /* parse through stack freeing each node */
+    node = sk->next;
+    while (node) {
+        tmp  = node;
+        node = node->next;
+        XFREE(tmp, NULL, DYNAMIC_TYPE_OPENSSL);
+    }
+
+    /* free head of stack */
+    XFREE(sk, NULL, DYNAMIC_TYPE_ASN1);
+}
+#endif
+
+#if defined(HAVE_ECC) || defined(HAVE_CURVE25519) || defined(HAVE_CURVE448) || \
+                                                                 !defined(NO_DH)
+#ifdef HAVE_FFDHE
+static const char* wolfssl_ffdhe_name(word16 group)
+{
+    const char* str = NULL;
+    switch (group) {
+        case WOLFSSL_FFDHE_2048:
+            str = "FFDHE_2048";
+            break;
+        case WOLFSSL_FFDHE_3072:
+            str = "FFDHE_3072";
+            break;
+        case WOLFSSL_FFDHE_4096:
+            str = "FFDHE_4096";
+            break;
+        case WOLFSSL_FFDHE_6144:
+            str = "FFDHE_6144";
+            break;
+        case WOLFSSL_FFDHE_8192:
+            str = "FFDHE_8192";
+            break;
+    }
+    return str;
+}
+#endif
+/* Return the name of the curve used for key exchange as a printable string.
+ *
+ * ssl  The SSL/TLS object.
+ * returns NULL if ECDH was not used, otherwise the name as a string.
+ */
+const char* wolfSSL_get_curve_name(WOLFSSL* ssl)
+{
+    const char* cName = NULL;
+
+    if (ssl == NULL)
+        return NULL;
+
+#ifdef HAVE_FFDHE
+    if (ssl->namedGroup != 0) {
+        cName = wolfssl_ffdhe_name(ssl->namedGroup);
+    }
+#endif
+
+#ifdef HAVE_CURVE25519
+    if (ssl->ecdhCurveOID == ECC_X25519_OID && cName == NULL) {
+        cName = "X25519";
+    }
+#endif
+
+#ifdef HAVE_CURVE448
+    if (ssl->ecdhCurveOID == ECC_X448_OID && cName == NULL) {
+        cName = "X448";
+    }
+#endif
+
+#ifdef HAVE_ECC
+    if (ssl->ecdhCurveOID != 0 && cName == NULL) {
+        cName = wc_ecc_get_name(wc_ecc_get_oid(ssl->ecdhCurveOID, NULL,
+                                NULL));
+    }
+#endif
+
+    return cName;
+}
+#endif
+
+
+#if defined(OPENSSL_EXTRA_X509_SMALL) || defined(KEEP_PEER_CERT) || \
+    defined(SESSION_CERTS)
+/* Smaller subset of X509 compatibility functions. Avoid increasing the size of
+ * this subset and its memory usage */
+
+#if !defined(NO_CERTS)
+/* returns a pointer to a new WOLFSSL_X509 structure on success and NULL on
+ * fail
+ */
+WOLFSSL_X509* wolfSSL_X509_new(void)
+{
+    WOLFSSL_X509* x509;
+
+    x509 = (WOLFSSL_X509*)XMALLOC(sizeof(WOLFSSL_X509), NULL,
+            DYNAMIC_TYPE_X509);
+    if (x509 != NULL) {
+        InitX509(x509, 1, NULL);
+    }
+
+    return x509;
+}
+
+WOLFSSL_ABI
+WOLFSSL_X509_NAME* wolfSSL_X509_get_subject_name(WOLFSSL_X509* cert)
+{
+    WOLFSSL_ENTER("wolfSSL_X509_get_subject_name");
+    if (cert && cert->subject.sz != 0)
+        return &cert->subject;
+    return NULL;
+}
+
+#if defined(OPENSSL_EXTRA) && !defined(NO_SHA)
+/******************************************************************************
+* wolfSSL_X509_subject_name_hash - compute the hash digest of the raw subject name
+*
+* RETURNS:
+* The beginning of the hash digest. Otherwise, returns zero.
+* Note:
+* Returns a different hash value from OpenSSL's X509_subject_name_hash() API
+* depending on the subject name.
+*/
+unsigned long wolfSSL_X509_subject_name_hash(const WOLFSSL_X509* x509)
+{
+    word32 ret = 0;
+    int retHash;
+    WOLFSSL_X509_NAME *subjectName = NULL;
+
+#ifdef WOLFSSL_PIC32MZ_HASH
+        byte digest[PIC32_DIGEST_SIZE];
+#else
+        byte digest[WC_SHA_DIGEST_SIZE];
+#endif
+
+    if (x509 == NULL){
+        return WOLFSSL_FAILURE;
+    }
+
+    subjectName = wolfSSL_X509_get_subject_name((WOLFSSL_X509*)x509);
+
+    if (subjectName != NULL){
+        retHash = wc_ShaHash((const byte*)subjectName->name,
+                             (word32)subjectName->sz, digest);
+
+        if(retHash != 0){
+            WOLFSSL_MSG("Hash of X509 subjectName has failed");
+            return WOLFSSL_FAILURE;
+        }
+        ret = MakeWordFromHash(digest);
+    }
+
+    return (unsigned long)ret;
+}
+#endif
+
+WOLFSSL_ABI
+WOLFSSL_X509_NAME* wolfSSL_X509_get_issuer_name(WOLFSSL_X509* cert)
+{
+    WOLFSSL_ENTER("X509_get_issuer_name");
+    if (cert && cert->issuer.sz != 0)
+        return &cert->issuer;
+    return NULL;
+}
+
+
+int wolfSSL_X509_get_signature_type(WOLFSSL_X509* x509)
+{
+    int type = 0;
+
+    WOLFSSL_ENTER("wolfSSL_X509_get_signature_type");
+
+    if (x509 != NULL)
+        type = x509->sigOID;
+
+    return type;
+}
+
+#if defined(OPENSSL_EXTRA_X509_SMALL)
+
+/* Used to get a string from the WOLFSSL_X509_NAME structure that
+ * corresponds with the NID value passed in.
+ *
+ * name structure to get string from
+ * nid  NID value to search for
+ * buf  [out] buffer to hold results. If NULL then the buffer size minus the
+ *      null char is returned.
+ * len  size of "buf" passed in
+ *
+ * returns the length of string found, not including the NULL terminator.
+ *         It's possible the function could return a negative value in the
+ *         case that len is less than or equal to 0. A negative value is
+ *         considered an error case.
+ */
+int wolfSSL_X509_NAME_get_text_by_NID(WOLFSSL_X509_NAME* name,
+                                      int nid, char* buf, int len)
+{
+    char *text = NULL;
+    int textSz = 0;
+
+    WOLFSSL_ENTER("wolfSSL_X509_NAME_get_text_by_NID");
+
+    switch (nid) {
+        case ASN_COMMON_NAME:
+            text = name->fullName.fullName + name->fullName.cnIdx;
+            textSz = name->fullName.cnLen;
+            break;
+        case ASN_SUR_NAME:
+            text = name->fullName.fullName + name->fullName.snIdx;
+            textSz = name->fullName.snLen;
+            break;
+        case ASN_SERIAL_NUMBER:
+            text = name->fullName.fullName + name->fullName.serialIdx;
+            textSz = name->fullName.serialLen;
+            break;
+        case ASN_COUNTRY_NAME:
+            text = name->fullName.fullName + name->fullName.cIdx;
+            textSz = name->fullName.cLen;
+            break;
+        case ASN_LOCALITY_NAME:
+            text = name->fullName.fullName + name->fullName.lIdx;
+            textSz = name->fullName.lLen;
+            break;
+        case ASN_STATE_NAME:
+            text = name->fullName.fullName + name->fullName.stIdx;
+            textSz = name->fullName.stLen;
+            break;
+        case ASN_ORG_NAME:
+            text = name->fullName.fullName + name->fullName.oIdx;
+            textSz = name->fullName.oLen;
+            break;
+        case ASN_ORGUNIT_NAME:
+            text = name->fullName.fullName + name->fullName.ouIdx;
+            textSz = name->fullName.ouLen;
+            break;
+        case ASN_DOMAIN_COMPONENT:
+            text = name->fullName.fullName + name->fullName.dcIdx[0];
+            textSz = name->fullName.dcLen[0];
+            break;
+        case NID_emailAddress:
+            text = name->fullName.fullName + name->fullName.emailIdx;
+            textSz = name->fullName.emailLen;
+            break;
+    #ifdef WOLFSSL_CERT_EXT
+        case ASN_BUS_CAT:
+            text = name->fullName.fullName + name->fullName.bcIdx;
+            textSz = name->fullName.bcLen;
+            break;
+    #endif
+        default:
+            WOLFSSL_MSG("Entry type not found");
+            return WOLFSSL_FATAL_ERROR;
+    }
+
+    /* if buf is NULL return size of buffer needed (minus null char) */
+    if (buf == NULL) {
+        return textSz;
+    }
+
+    if (buf != NULL && text != NULL) {
+        textSz = min(textSz + 1, len); /* + 1 to account for null char */
+        if (textSz > 0) {
+            XMEMCPY(buf, text, textSz - 1);
+            buf[textSz - 1] = '\0';
+        }
+    }
+
+    WOLFSSL_LEAVE("wolfSSL_X509_NAME_get_text_by_NID", textSz);
+    return (textSz - 1); /* do not include null character in size */
+}
+
+/* Creates a new WOLFSSL_EVP_PKEY structure that has the public key from x509
+ *
+ * returns a pointer to the created WOLFSSL_EVP_PKEY on success and NULL on fail
+ */
+WOLFSSL_EVP_PKEY* wolfSSL_X509_get_pubkey(WOLFSSL_X509* x509)
+{
+    WOLFSSL_EVP_PKEY* key = NULL;
+    WOLFSSL_ENTER("X509_get_pubkey");
+    if (x509 != NULL) {
+        key = wolfSSL_EVP_PKEY_new_ex(x509->heap);
+        if (key != NULL) {
+            if (x509->pubKeyOID == RSAk) {
+                key->type = EVP_PKEY_RSA;
+            }
+            else if (x509->pubKeyOID == DSAk) {
+                key->type = EVP_PKEY_DSA;
+            }
+            else {
+                key->type = EVP_PKEY_EC;
+            }
+            key->save_type = 0;
+            key->pkey.ptr = (char*)XMALLOC(
+                        x509->pubKey.length, x509->heap,
+                                                       DYNAMIC_TYPE_PUBLIC_KEY);
+            if (key->pkey.ptr == NULL) {
+                wolfSSL_EVP_PKEY_free(key);
+                return NULL;
+            }
+            XMEMCPY(key->pkey.ptr, x509->pubKey.buffer, x509->pubKey.length);
+            key->pkey_sz = x509->pubKey.length;
+
+            #ifdef HAVE_ECC
+                key->pkey_curve = (int)x509->pkCurveOID;
+            #endif /* HAVE_ECC */
+
+            /* decode RSA key */
+            #ifndef NO_RSA
+            if (key->type == EVP_PKEY_RSA) {
+                key->ownRsa = 1;
+                key->rsa = wolfSSL_RSA_new();
+                if (key->rsa == NULL) {
+                    wolfSSL_EVP_PKEY_free(key);
+                    return NULL;
+                }
+
+                if (wolfSSL_RSA_LoadDer_ex(key->rsa,
+                            (const unsigned char*)key->pkey.ptr, key->pkey_sz,
+                            WOLFSSL_RSA_LOAD_PUBLIC) != SSL_SUCCESS) {
+                    wolfSSL_EVP_PKEY_free(key);
+                    return NULL;
+                }
+            }
+            #endif /* NO_RSA */
+
+            /* decode ECC key */
+            #if defined(HAVE_ECC) && defined(OPENSSL_EXTRA)
+            if (key->type == EVP_PKEY_EC) {
+                word32 idx = 0;
+
+                key->ownEcc = 1;
+                key->ecc = wolfSSL_EC_KEY_new();
+                if (key->ecc == NULL || key->ecc->internal == NULL) {
+                    wolfSSL_EVP_PKEY_free(key);
+                    return NULL;
+                }
+
+                /* not using wolfSSL_EC_KEY_LoadDer because public key in x509
+                 * is in the format of x963 (no sequence at start of buffer) */
+                if (wc_EccPublicKeyDecode((const unsigned char*)key->pkey.ptr,
+                        &idx, (ecc_key*)key->ecc->internal, key->pkey_sz) < 0) {
+                    WOLFSSL_MSG("wc_EccPublicKeyDecode failed");
+                    wolfSSL_EVP_PKEY_free(key);
+                    return NULL;
+                }
+
+                if (SetECKeyExternal(key->ecc) != SSL_SUCCESS) {
+                    WOLFSSL_MSG("SetECKeyExternal failed");
+                    wolfSSL_EVP_PKEY_free(key);
+                    return NULL;
+                }
+
+                key->ecc->inSet = 1;
+            }
+            #endif /* HAVE_ECC */
+
+            #ifndef NO_DSA
+            if (key->type == EVP_PKEY_DSA) {
+                key->ownDsa = 1;
+                key->dsa = wolfSSL_DSA_new();
+                if (key->dsa == NULL) {
+                    wolfSSL_EVP_PKEY_free(key);
+                    return NULL;
+                }
+
+                if (wolfSSL_DSA_LoadDer_ex(key->dsa,
+                            (const unsigned char*)key->pkey.ptr, key->pkey_sz, \
+                            WOLFSSL_DSA_LOAD_PUBLIC) != SSL_SUCCESS) {
+                    wolfSSL_DSA_free(key->dsa);
+                    key->dsa = NULL;
+                    wolfSSL_EVP_PKEY_free(key);
+                    return NULL;
+                }
+            }
+            #endif /* NO_DSA */
+        }
+    }
+    return key;
+}
+#endif /* OPENSSL_EXTRA_X509_SMALL */
+#endif /* !NO_CERTS */
+
+/* End of smaller subset of X509 compatibility functions. Avoid increasing the
+ * size of this subset and its memory usage */
+#endif /* OPENSSL_EXTRA_X509_SMALL */
+
+#if defined(OPENSSL_ALL)
+/* Takes two WOLFSSL_X509* certificates and performs a Sha hash of each, if the
+   * has values are the same, then it will do an XMEMCMP to confirm they are
+   * identical. Returns a 0 when certificates match, returns a negative number
+   * when certificates are not a match.
+*/
+int wolfSSL_X509_cmp(const WOLFSSL_X509 *a, const WOLFSSL_X509 *b)
+{
+        const byte* derA;
+        const byte* derB;
+        int retHashA;
+        int retHashB;
+        int outSzA = 0;
+        int outSzB = 0;
+
+        #ifdef WOLFSSL_PIC32MZ_HASH
+            byte digestA[PIC32_DIGEST_SIZE];
+            byte digestB[PIC32_DIGEST_SIZE];
+        #else
+            byte digestA[WC_SHA_DIGEST_SIZE];
+            byte digestB[WC_SHA_DIGEST_SIZE];
+        #endif
+
+        if (a == NULL || b == NULL){
+            return BAD_FUNC_ARG;
+        }
+
+        derA = wolfSSL_X509_get_der((WOLFSSL_X509*)a, &outSzA);
+        if(derA == NULL){
+            WOLFSSL_MSG("wolfSSL_X509_get_der - certificate A has failed");
+            return WOLFSSL_FATAL_ERROR;
+        }
+        derB = wolfSSL_X509_get_der((WOLFSSL_X509*)b, &outSzB);
+        if(derB == NULL){
+            WOLFSSL_MSG("wolfSSL_X509_get_der - certificate B has failed");
+            return WOLFSSL_FATAL_ERROR;
+        }
+
+        retHashA = wc_ShaHash(derA, (word32)outSzA, digestA);
+        if(retHashA != 0){
+            WOLFSSL_MSG("Hash of certificate A has failed");
+            return WOLFSSL_FATAL_ERROR;
+        }
+        retHashB = wc_ShaHash(derB, (word32)outSzB, digestB);
+        if(retHashB != 0){
+            WOLFSSL_MSG("Hash of certificate B has failed");
+            return WOLFSSL_FATAL_ERROR;
+        }
+
+        if (outSzA == outSzB){
+            #ifdef WOLFSSL_PIC32MZ_HASH
+            if(XMEMCMP(digestA, digestB, PIC32_DIGEST_SIZE) != 0){
+                return WOLFSSL_FATAL_ERROR;
+            }
+            #else
+            if(XMEMCMP(digestA, digestB, WC_SHA_DIGEST_SIZE) != 0){
+                return WOLFSSL_FATAL_ERROR;
+            }
+            #endif
+            else{
+                WOLFSSL_LEAVE("wolfSSL_X509_cmp", 0);
+                return 0;
+            }
+        }
+        else{
+            WOLFSSL_LEAVE("wolfSSL_X509_cmp", WOLFSSL_FATAL_ERROR);
+            return WOLFSSL_FATAL_ERROR;
+        }
+    }
+#endif
+
+#if defined(OPENSSL_EXTRA)
+#if !defined(NO_CERTS)
+    int wolfSSL_X509_ext_isSet_by_NID(WOLFSSL_X509* x509, int nid)
+    {
+        int isSet = 0;
+
+        WOLFSSL_ENTER("wolfSSL_X509_ext_isSet_by_NID");
+
+        if (x509 != NULL) {
+            switch (nid) {
+                case BASIC_CA_OID: isSet = x509->basicConstSet; break;
+                case ALT_NAMES_OID: isSet = x509->subjAltNameSet; break;
+                case AUTH_KEY_OID: isSet = x509->authKeyIdSet; break;
+                case SUBJ_KEY_OID: isSet = x509->subjKeyIdSet; break;
+                case KEY_USAGE_OID: isSet = x509->keyUsageSet; break;
+                case CRL_DIST_OID: isSet = x509->CRLdistSet; break;
+                case EXT_KEY_USAGE_OID: isSet = ((x509->extKeyUsageSrc) ? 1 : 0);
+                    break;
+                case AUTH_INFO_OID: isSet = x509->authInfoSet; break;
+                #if defined(WOLFSSL_SEP) || defined(WOLFSSL_QT)
+                    case CERT_POLICY_OID: isSet = x509->certPolicySet; break;
+                #endif /* WOLFSSL_SEP || WOLFSSL_QT */
+                default:
+                    WOLFSSL_MSG("NID not in table");
+            }
+        }
+
+        WOLFSSL_LEAVE("wolfSSL_X509_ext_isSet_by_NID", isSet);
+
+        return isSet;
+    }
+
+
+    int wolfSSL_X509_ext_get_critical_by_NID(WOLFSSL_X509* x509, int nid)
+    {
+        int crit = 0;
+
+        WOLFSSL_ENTER("wolfSSL_X509_ext_get_critical_by_NID");
+
+        if (x509 != NULL) {
+            switch (nid) {
+                case BASIC_CA_OID: crit = x509->basicConstCrit; break;
+                case ALT_NAMES_OID: crit = x509->subjAltNameCrit; break;
+                case AUTH_KEY_OID: crit = x509->authKeyIdCrit; break;
+                case SUBJ_KEY_OID: crit = x509->subjKeyIdCrit; break;
+                case KEY_USAGE_OID: crit = x509->keyUsageCrit; break;
+                case CRL_DIST_OID: crit= x509->CRLdistCrit; break;
+                #if defined(WOLFSSL_SEP) || defined(WOLFSSL_QT)
+                    case CERT_POLICY_OID: crit = x509->certPolicyCrit; break;
+                #endif /* WOLFSSL_SEP || WOLFSSL_QT */
+            }
+        }
+
+        WOLFSSL_LEAVE("wolfSSL_X509_ext_get_critical_by_NID", crit);
+
+        return crit;
+    }
+
+
+    int wolfSSL_X509_get_isSet_pathLength(WOLFSSL_X509* x509)
+    {
+        int isSet = 0;
+
+        WOLFSSL_ENTER("wolfSSL_X509_get_isSet_pathLength");
+
+        if (x509 != NULL)
+            isSet = x509->basicConstPlSet;
+
+        WOLFSSL_LEAVE("wolfSSL_X509_get_isSet_pathLength", isSet);
+
+        return isSet;
+    }
+
+
+    word32 wolfSSL_X509_get_pathLength(WOLFSSL_X509* x509)
+    {
+        word32 pathLength = 0;
+
+        WOLFSSL_ENTER("wolfSSL_X509_get_pathLength");
+
+        if (x509 != NULL)
+            pathLength = x509->pathLength;
+
+        WOLFSSL_LEAVE("wolfSSL_X509_get_pathLength", pathLength);
+
+        return pathLength;
+    }
+
+
+    unsigned int wolfSSL_X509_get_keyUsage(WOLFSSL_X509* x509)
+    {
+        word16 usage = 0;
+
+        WOLFSSL_ENTER("wolfSSL_X509_get_keyUsage");
+
+        if (x509 != NULL)
+            usage = x509->keyUsage;
+
+        WOLFSSL_LEAVE("wolfSSL_X509_get_keyUsage", usage);
+
+        return usage;
+    }
+
+
+    byte* wolfSSL_X509_get_authorityKeyID(WOLFSSL_X509* x509,
+                                          byte* dst, int* dstLen)
+    {
+        byte *id = NULL;
+        int copySz = 0;
+
+        WOLFSSL_ENTER("wolfSSL_X509_get_authorityKeyID");
+
+        if (x509 != NULL) {
+            if (x509->authKeyIdSet) {
+                copySz = min(dstLen != NULL ? *dstLen : 0,
+                             (int)x509->authKeyIdSz);
+                id = x509->authKeyId;
+            }
+
+            if (dst != NULL && dstLen != NULL && id != NULL && copySz > 0) {
+                XMEMCPY(dst, id, copySz);
+                id = dst;
+                *dstLen = copySz;
+            }
+        }
+
+        WOLFSSL_LEAVE("wolfSSL_X509_get_authorityKeyID", copySz);
+
+        return id;
+    }
+
+
+    byte* wolfSSL_X509_get_subjectKeyID(WOLFSSL_X509* x509,
+                                        byte* dst, int* dstLen)
+    {
+        byte *id = NULL;
+        int copySz = 0;
+
+        WOLFSSL_ENTER("wolfSSL_X509_get_subjectKeyID");
+
+        if (x509 != NULL) {
+            if (x509->subjKeyIdSet) {
+                copySz = min(dstLen != NULL ? *dstLen : 0,
+                                                        (int)x509->subjKeyIdSz);
+                id = x509->subjKeyId;
+            }
+
+            if (dst != NULL && dstLen != NULL && id != NULL && copySz > 0) {
+                XMEMCPY(dst, id, copySz);
+                id = dst;
+                *dstLen = copySz;
+            }
+        }
+
+        WOLFSSL_LEAVE("wolfSSL_X509_get_subjectKeyID", copySz);
+
+        return id;
+    }
+
+
+    int wolfSSL_X509_NAME_entry_count(WOLFSSL_X509_NAME* name)
+    {
+        int count = 0;
+
+        WOLFSSL_ENTER("wolfSSL_X509_NAME_entry_count");
+
+        if (name != NULL)
+            count = name->fullName.locSz;
+
+        WOLFSSL_LEAVE("wolfSSL_X509_NAME_entry_count", count);
+        return count;
+    }
+
+
+
+    int wolfSSL_X509_NAME_get_index_by_NID(WOLFSSL_X509_NAME* name,
+                                          int nid, int pos)
+    {
+        int value = nid, i;
+
+        WOLFSSL_ENTER("wolfSSL_X509_NAME_get_index_by_NID");
+
+        if (name == NULL || pos >= DN_NAMES_MAX + DOMAIN_COMPONENT_MAX) {
+            return BAD_FUNC_ARG;
+        }
+
+        if (value == NID_emailAddress) {
+            value = ASN_EMAIL_NAME;
+        }
+
+        i = pos + 1; /* start search after index passed in */
+        if (i < 0) {
+            i = 0;
+        }
+
+        for (;i < name->fullName.locSz &&
+                i < DN_NAMES_MAX + DOMAIN_COMPONENT_MAX; i++) {
+            if (name->fullName.loc[i] == value) {
+                return i;
+            }
+        }
+        return WOLFSSL_FATAL_ERROR;
+    }
+
+
+    WOLFSSL_ASN1_STRING*  wolfSSL_X509_NAME_ENTRY_get_data(
+                                                    WOLFSSL_X509_NAME_ENTRY* in)
+    {
+        WOLFSSL_ENTER("wolfSSL_X509_NAME_ENTRY_get_data");
+        if (in == NULL)
+            return NULL;
+
+        return in->value;
+    }
+
+
+    /* Creates a new WOLFSSL_ASN1_STRING structure.
+     *
+     * returns a pointer to the new structure created on success or NULL if fail
+     */
+    WOLFSSL_ASN1_STRING* wolfSSL_ASN1_STRING_new(void)
+    {
+        WOLFSSL_ASN1_STRING* asn1;
+
+        WOLFSSL_ENTER("wolfSSL_ASN1_STRING_new");
+
+        asn1 = (WOLFSSL_ASN1_STRING*)XMALLOC(sizeof(WOLFSSL_ASN1_STRING), NULL,
+                DYNAMIC_TYPE_OPENSSL);
+        if (asn1 != NULL) {
+            XMEMSET(asn1, 0, sizeof(WOLFSSL_ASN1_STRING));
+        }
+
+        return asn1; /* no check for null because error case is returning null*/
+    }
+
+
+    /* used to free a WOLFSSL_ASN1_STRING structure */
+    void wolfSSL_ASN1_STRING_free(WOLFSSL_ASN1_STRING* asn1)
+    {
+        WOLFSSL_ENTER("wolfSSL_ASN1_STRING_free");
+
+        if (asn1 != NULL) {
+            if (asn1->length > 0 && asn1->data != NULL && asn1->isDynamic) {
+                XFREE(asn1->data, NULL, DYNAMIC_TYPE_OPENSSL);
+            }
+            XFREE(asn1, NULL, DYNAMIC_TYPE_OPENSSL);
+        }
+    }
+
+
+    /* Creates a new WOLFSSL_ASN1_STRING structure given the input type.
+     *
+     * type is the type of set when WOLFSSL_ASN1_STRING is created
+     *
+     * returns a pointer to the new structure created on success or NULL if fail
+     */
+    WOLFSSL_ASN1_STRING* wolfSSL_ASN1_STRING_type_new(int type)
+    {
+        WOLFSSL_ASN1_STRING* asn1;
+
+        WOLFSSL_ENTER("wolfSSL_ASN1_STRING_type_new");
+
+        asn1 = wolfSSL_ASN1_STRING_new();
+        if (asn1 == NULL) {
+            return NULL;
+        }
+        asn1->type = type;
+
+        return asn1;
+    }
+
+
+/******************************************************************************
+* wolfSSL_ASN1_STRING_type - returns the type of <asn1>
+*
+* RETURNS:
+* returns the type set for <asn1>. Otherwise, returns WOLFSSL_FAILURE.
+*/
+    int wolfSSL_ASN1_STRING_type(const WOLFSSL_ASN1_STRING* asn1)
+    {
+
+        WOLFSSL_ENTER("wolfSSL_ASN1_STRING_type");
+
+        if (asn1 == NULL) {
+            return WOLFSSL_FAILURE;
+        }
+
+        return asn1->type;
+    }
+
+    /* if dataSz is negative then use XSTRLEN to find length of data
+     * return WOLFSSL_SUCCESS on success and WOLFSSL_FAILURE on failure */
+    /* `data` can be NULL and only buffer will be allocated */
+    int wolfSSL_ASN1_STRING_set(WOLFSSL_ASN1_STRING* asn1, const void* data,
+            int dataSz)
+    {
+        int sz;
+
+        WOLFSSL_ENTER("wolfSSL_ASN1_STRING_set");
+
+        if (asn1 == NULL || (data == NULL && dataSz < 0)) {
+            return WOLFSSL_FAILURE;
+        }
+
+        if (dataSz < 0) {
+            sz = (int)XSTRLEN((const char*)data) + 1; /* +1 for null */
+        }
+        else {
+            sz = dataSz;
+        }
+
+        if (sz < 0) {
+            return WOLFSSL_FAILURE;
+        }
+
+        /* free any existing data before copying */
+        if (asn1->data != NULL && asn1->isDynamic) {
+            XFREE(asn1->data, NULL, DYNAMIC_TYPE_OPENSSL);
+            asn1->data = NULL;
+        }
+
+        if (sz > CTC_NAME_SIZE) {
+            /* create new data buffer and copy over */
+            asn1->data = (char*)XMALLOC(sz, NULL, DYNAMIC_TYPE_OPENSSL);
+            if (asn1->data == NULL) {
+                return WOLFSSL_FAILURE;
+            }
+            asn1->isDynamic = 1;
+        }
+        else {
+            XMEMSET(asn1->strData, 0, CTC_NAME_SIZE);
+            asn1->data = asn1->strData;
+            asn1->isDynamic = 0;
+        }
+        if (data != NULL) {
+            XMEMCPY(asn1->data, data, sz);
+            asn1->data[sz] = '\0';
+        }
+        asn1->length = sz;
+
+        return WOLFSSL_SUCCESS;
+    }
+
+
+    unsigned char* wolfSSL_ASN1_STRING_data(WOLFSSL_ASN1_STRING* asn)
+    {
+        WOLFSSL_ENTER("wolfSSL_ASN1_STRING_data");
+
+        if (asn) {
+            return (unsigned char*)asn->data;
+        }
+        else {
+            return NULL;
+        }
+    }
+
+
+    int wolfSSL_ASN1_STRING_length(WOLFSSL_ASN1_STRING* asn)
+    {
+        WOLFSSL_ENTER("wolfSSL_ASN1_STRING_length");
+
+        if (asn) {
+            return asn->length;
+        }
+        else {
+            return 0;
+        }
+    }
+
+#ifndef NO_WOLFSSL_STUB
+    WOLFSSL_ASN1_STRING* wolfSSL_d2i_DISPLAYTEXT(WOLFSSL_ASN1_STRING **asn,
+                                             const unsigned char **in, long len)
+    {
+        WOLFSSL_STUB("d2i_DISPLAYTEXT");
+        (void)asn;
+        (void)in;
+        (void)len;
+        return NULL;
+    }
+#endif
+
+#ifdef XSNPRINTF /* a snprintf function needs to be available */
+    /* Writes the human readable form of x509 to bio.
+     *
+     * bio  WOLFSSL_BIO to write to.
+     * x509 Certificate to write.
+     *
+     * returns WOLFSSL_SUCCESS on success and WOLFSSL_FAILURE on failure
+     */
+    int wolfSSL_X509_print_ex(WOLFSSL_BIO* bio, WOLFSSL_X509* x509,
+        unsigned long nmflags, unsigned long cflag)
+    {
+        WOLFSSL_ENTER("wolfSSL_X509_print_ex");
+
+    #ifndef NO_WOLFSSL_STUB
+        /* flags currently not supported */
+        (void)nmflags;
+        (void)cflag;
+    #endif
+
+        if (bio == NULL || x509 == NULL) {
+            return WOLFSSL_FAILURE;
+        }
+
+        if (wolfSSL_BIO_write(bio, "Certificate:\n",
+                      (int)XSTRLEN("Certificate:\n")) <= 0) {
+                return WOLFSSL_FAILURE;
+        }
+
+        if (wolfSSL_BIO_write(bio, "    Data:\n",
+                      (int)XSTRLEN("    Data:\n")) <= 0) {
+                return WOLFSSL_FAILURE;
+        }
+
+        /* print version of cert */
+        {
+            int version;
+            char tmp[20];
+
+            if ((version = wolfSSL_X509_version(x509)) < 0) {
+                WOLFSSL_MSG("Error getting X509 version");
+                return WOLFSSL_FAILURE;
+            }
+            if (wolfSSL_BIO_write(bio, "        Version:",
+                          (int)XSTRLEN("        Version:")) <= 0) {
+                return WOLFSSL_FAILURE;
+            }
+            XSNPRINTF(tmp, sizeof(tmp), " %d (0x%x)\n", version, (byte)version-1);
+            if (wolfSSL_BIO_write(bio, tmp, (int)XSTRLEN(tmp)) <= 0) {
+                return WOLFSSL_FAILURE;
+            }
+        }
+
+        /* print serial number out */
+        {
+            unsigned char serial[32];
+            int  sz = sizeof(serial);
+
+            XMEMSET(serial, 0, sz);
+            if (wolfSSL_X509_get_serial_number(x509, serial, &sz)
+                    != WOLFSSL_SUCCESS) {
+                WOLFSSL_MSG("Error getting x509 serial number");
+                return WOLFSSL_FAILURE;
+            }
+            if (wolfSSL_BIO_write(bio, "        Serial Number:",
+                          (int)XSTRLEN("        Serial Number:")) <= 0) {
+                return WOLFSSL_FAILURE;
+            }
+
+            /* if serial can fit into byte than print on the same line */
+            if (sz <= (int)sizeof(byte)) {
+                char tmp[17];
+                XSNPRINTF(tmp, sizeof(tmp), " %d (0x%x)\n", serial[0],serial[0]);
+                if (wolfSSL_BIO_write(bio, tmp, (int)XSTRLEN(tmp)) <= 0) {
+                    return WOLFSSL_FAILURE;
+                }
+            }
+            else {
+                int i;
+                char tmp[100];
+                int  tmpSz = 100;
+                char val[5];
+                int  valSz = 5;
+
+                /* serial is larger than int size so print off hex values */
+                if (wolfSSL_BIO_write(bio, "\n            ",
+                              (int)XSTRLEN("\n            ")) <= 0) {
+                    return WOLFSSL_FAILURE;
+                }
+                tmp[0] = '\0';
+                for (i = 0; i < sz - 1 && (3 * i) < tmpSz - valSz; i++) {
+                    XSNPRINTF(val, sizeof(val) - 1, "%02x:", serial[i]);
+                    val[3] = '\0'; /* make sure is null terminated */
+                    XSTRNCAT(tmp, val, valSz);
+                }
+                XSNPRINTF(val, sizeof(val) - 1, "%02x\n", serial[i]);
+                val[3] = '\0'; /* make sure is null terminated */
+                XSTRNCAT(tmp, val, valSz);
+                if (wolfSSL_BIO_write(bio, tmp, (int)XSTRLEN(tmp)) <= 0) {
+                    return WOLFSSL_FAILURE;
+                }
+            }
+        }
+
+        /* print signature algo */
+        {
+            int oid;
+            const char* sig;
+
+            if ((oid = wolfSSL_X509_get_signature_type(x509)) <= 0) {
+                WOLFSSL_MSG("Error getting x509 signature type");
+                return WOLFSSL_FAILURE;
+            }
+            if (wolfSSL_BIO_write(bio, "        Signature Algorithm: ",
+                          (int)XSTRLEN("        Signature Algorithm: ")) <= 0) {
+                return WOLFSSL_FAILURE;
+            }
+            sig = GetSigName(oid);
+            if (wolfSSL_BIO_write(bio, sig, (int)XSTRLEN(sig)) <= 0) {
+                return WOLFSSL_FAILURE;
+            }
+            if (wolfSSL_BIO_write(bio, "\n", (int)XSTRLEN("\n")) <= 0) {
+                return WOLFSSL_FAILURE;
+            }
+        }
+
+        /* print issuer */
+        {
+            char* issuer;
+        #ifdef WOLFSSL_SMALL_STACK
+            char* buff  = NULL;
+            int   issSz = 0;
+        #else
+            char buff[256];
+            int  issSz = 256;
+        #endif
+
+        #if defined(WOLFSSL_QT)
+            issuer = wolfSSL_X509_get_name_oneline(
+                               wolfSSL_X509_get_issuer_name(x509), buff, issSz);
+        #else
+            issuer = wolfSSL_X509_NAME_oneline(
+                               wolfSSL_X509_get_issuer_name(x509), buff, issSz);
+        #endif
+
+            if (wolfSSL_BIO_write(bio, "        Issuer: ",
+                          (int)XSTRLEN("        Issuer: ")) <= 0) {
+                #ifdef WOLFSSL_SMALL_STACK
+                XFREE(issuer, NULL, DYNAMIC_TYPE_OPENSSL);
+                #endif
+                return WOLFSSL_FAILURE;
+            }
+            if (issuer != NULL) {
+                if (wolfSSL_BIO_write(bio, issuer, (int)XSTRLEN(issuer)) <= 0) {
+                    #ifdef WOLFSSL_SMALL_STACK
+                    XFREE(issuer, NULL, DYNAMIC_TYPE_OPENSSL);
+                    #endif
+                    return WOLFSSL_FAILURE;
+                }
+            }
+            #ifdef WOLFSSL_SMALL_STACK
+            XFREE(issuer, NULL, DYNAMIC_TYPE_OPENSSL);
+            #endif
+            if (wolfSSL_BIO_write(bio, "\n", (int)XSTRLEN("\n")) <= 0) {
+                return WOLFSSL_FAILURE;
+            }
+        }
+
+    #ifndef NO_ASN_TIME
+        /* print validity */
+        {
+            char tmp[80];
+
+            if (wolfSSL_BIO_write(bio, "        Validity\n",
+                          (int)XSTRLEN("        Validity\n")) <= 0) {
+                return WOLFSSL_FAILURE;
+            }
+
+            if (wolfSSL_BIO_write(bio, "            Not Before: ",
+                          (int)XSTRLEN("            Not Before: ")) <= 0) {
+                return WOLFSSL_FAILURE;
+            }
+            if (x509->notBefore.length > 0) {
+                if (GetTimeString(x509->notBefore.data, ASN_UTC_TIME,
+                    tmp, sizeof(tmp)) != WOLFSSL_SUCCESS) {
+                    if (GetTimeString(x509->notBefore.data, ASN_GENERALIZED_TIME,
+                    tmp, sizeof(tmp)) != WOLFSSL_SUCCESS) {
+                        WOLFSSL_MSG("Error getting not before date");
+                        return WOLFSSL_FAILURE;
+                    }
+                }
+            }
+            else {
+                XSTRNCPY(tmp, "Not Set", sizeof(tmp)-1);
+            }
+            tmp[sizeof(tmp) - 1] = '\0'; /* make sure null terminated */
+            if (wolfSSL_BIO_write(bio, tmp, (int)XSTRLEN(tmp)) <= 0) {
+                return WOLFSSL_FAILURE;
+            }
+
+            if (wolfSSL_BIO_write(bio, "\n            Not After : ",
+                          (int)XSTRLEN("\n            Not After : ")) <= 0) {
+                return WOLFSSL_FAILURE;
+            }
+            if (x509->notAfter.length > 0) {
+                if (GetTimeString(x509->notAfter.data, ASN_UTC_TIME,
+                    tmp, sizeof(tmp)) != WOLFSSL_SUCCESS) {
+                    if (GetTimeString(x509->notAfter.data, ASN_GENERALIZED_TIME,
+                        tmp, sizeof(tmp)) != WOLFSSL_SUCCESS) {
+                        WOLFSSL_MSG("Error getting not after date");
+                        return WOLFSSL_FAILURE;
+                    }
+                }
+            }
+            else {
+                XSTRNCPY(tmp, "Not Set", sizeof(tmp)-1);
+            }
+            tmp[sizeof(tmp) - 1] = '\0'; /* make sure null terminated */
+            if (wolfSSL_BIO_write(bio, tmp, (int)XSTRLEN(tmp)) <= 0) {
+                return WOLFSSL_FAILURE;
+            }
+        }
+    #endif
+
+        /* print subject */
+        {
+            char* subject;
+        #ifdef WOLFSSL_SMALL_STACK
+            char* buff  = NULL;
+            int   subSz = 0;
+        #else
+            char buff[256];
+            int  subSz = 256;
+        #endif
+
+        #if defined(WOLFSSL_QT)
+            subject = wolfSSL_X509_get_name_oneline(
+                              wolfSSL_X509_get_subject_name(x509), buff, subSz);
+        #else
+            subject = wolfSSL_X509_NAME_oneline(
+                              wolfSSL_X509_get_subject_name(x509), buff, subSz);
+        #endif
+
+            if (wolfSSL_BIO_write(bio, "\n        Subject: ",
+                          (int)XSTRLEN("\n        Subject: ")) <= 0) {
+                #ifdef WOLFSSL_SMALL_STACK
+                XFREE(subject, NULL, DYNAMIC_TYPE_OPENSSL);
+                #endif
+                return WOLFSSL_FAILURE;
+            }
+            if (subject != NULL) {
+                if (wolfSSL_BIO_write(bio, subject, (int)XSTRLEN(subject)) <= 0) {
+                    #ifdef WOLFSSL_SMALL_STACK
+                    XFREE(subject, NULL, DYNAMIC_TYPE_OPENSSL);
+                    #endif
+                    return WOLFSSL_FAILURE;
+                }
+            }
+            #ifdef WOLFSSL_SMALL_STACK
+            XFREE(subject, NULL, DYNAMIC_TYPE_OPENSSL);
+            #endif
+        }
+
+        /* get and print public key */
+        if (wolfSSL_BIO_write(bio, "\n        Subject Public Key Info:\n",
+                      (int)XSTRLEN("\n        Subject Public Key Info:\n")) <= 0) {
+            return WOLFSSL_FAILURE;
+        }
+        {
+        #if (!defined(NO_RSA) && !defined(HAVE_USER_RSA)) || defined(HAVE_ECC)
+            char tmp[100];
+        #endif
+
+            switch (x509->pubKeyOID) {
+            #ifndef NO_RSA
+                case RSAk:
+                    if (wolfSSL_BIO_write(bio,
+                                "            Public Key Algorithm: rsaEncryption\n",
+                   (int)XSTRLEN("            Public Key Algorithm: rsaEncryption\n")) <= 0) {
+                        return WOLFSSL_FAILURE;
+                    }
+                #ifdef HAVE_USER_RSA
+                    if (wolfSSL_BIO_write(bio,
+                        "                Build without user RSA to print key\n",
+           (int)XSTRLEN("                Build without user RSA to print key\n"))
+                        <= 0) {
+                        return WOLFSSL_FAILURE;
+                    }
+                #else
+                    {
+                        RsaKey rsa;
+                        word32 idx = 0;
+                        int  sz;
+                        byte lbit = 0;
+                        int  rawLen;
+                        unsigned char* rawKey;
+
+                        if (wc_InitRsaKey(&rsa, NULL) != 0) {
+                            WOLFSSL_MSG("wc_InitRsaKey failure");
+                            return WOLFSSL_FAILURE;
+                        }
+                        if (wc_RsaPublicKeyDecode(x509->pubKey.buffer,
+                                &idx, &rsa, x509->pubKey.length) != 0) {
+                            WOLFSSL_MSG("Error decoding RSA key");
+                            wc_FreeRsaKey(&rsa);
+                            return WOLFSSL_FAILURE;
+                        }
+                        if ((sz = wc_RsaEncryptSize(&rsa)) < 0) {
+                            WOLFSSL_MSG("Error getting RSA key size");
+                            wc_FreeRsaKey(&rsa);
+                            return WOLFSSL_FAILURE;
+                        }
+                        XSNPRINTF(tmp, sizeof(tmp) - 1, "%s%s: (%d bit)\n%s\n",
+                                "                ", "Public-Key", 8 * sz,
+                                "                Modulus:");
+                        tmp[sizeof(tmp) - 1] = '\0';
+                        if (wolfSSL_BIO_write(bio, tmp,
+                                                      (int)XSTRLEN(tmp)) <= 0) {
+                            wc_FreeRsaKey(&rsa);
+                            return WOLFSSL_FAILURE;
+                        }
+
+                        /* print out modulus */
+                        XSNPRINTF(tmp, sizeof(tmp) - 1,"                    ");
+                        tmp[sizeof(tmp) - 1] = '\0';
+                        if (mp_leading_bit(&rsa.n)) {
+                            lbit = 1;
+                            XSTRNCAT(tmp, "00", 3);
+                        }
+
+                        rawLen = mp_unsigned_bin_size(&rsa.n);
+                        rawKey = (unsigned char*)XMALLOC(rawLen, NULL,
+                                DYNAMIC_TYPE_TMP_BUFFER);
+                        if (rawKey == NULL) {
+                            WOLFSSL_MSG("Memory error");
+                            wc_FreeRsaKey(&rsa);
+                            return WOLFSSL_FAILURE;
+                        }
+                        mp_to_unsigned_bin(&rsa.n, rawKey);
+                        for (idx = 0; idx < (word32)rawLen; idx++) {
+                            char val[5];
+                            int valSz = 5;
+
+                            if ((idx == 0) && !lbit) {
+                                XSNPRINTF(val, valSz - 1, "%02x", rawKey[idx]);
+                            }
+                            else if ((idx != 0) && (((idx + lbit) % 15) == 0)) {
+                                tmp[sizeof(tmp) - 1] = '\0';
+                                if (wolfSSL_BIO_write(bio, tmp,
+                                                      (int)XSTRLEN(tmp)) <= 0) {
+                                    XFREE(rawKey, NULL,
+                                        DYNAMIC_TYPE_TMP_BUFFER);
+                                    wc_FreeRsaKey(&rsa);
+                                    return WOLFSSL_FAILURE;
+                                }
+                                XSNPRINTF(tmp, sizeof(tmp) - 1,
+                                        ":\n                    ");
+                                XSNPRINTF(val, valSz - 1, "%02x", rawKey[idx]);
+                            }
+                            else {
+                                XSNPRINTF(val, valSz - 1, ":%02x", rawKey[idx]);
+                            }
+                            XSTRNCAT(tmp, val, valSz);
+                        }
+                        XFREE(rawKey, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+
+                        /* print out remaining modulus values */
+                        if ((idx > 0) && (((idx - 1 + lbit) % 15) != 0)) {
+                            tmp[sizeof(tmp) - 1] = '\0';
+                            if (wolfSSL_BIO_write(bio, tmp,
+                                                      (int)XSTRLEN(tmp)) <= 0) {
+                                return WOLFSSL_FAILURE;
+                            }
+                        }
+
+                        /* print out exponent values */
+                        rawLen = mp_unsigned_bin_size(&rsa.e);
+                        if (rawLen < 0) {
+                            WOLFSSL_MSG("Error getting exponent size");
+                            wc_FreeRsaKey(&rsa);
+                            return WOLFSSL_FAILURE;
+                        }
+
+                        if ((word32)rawLen < sizeof(word32)) {
+                            rawLen = sizeof(word32);
+                        }
+                        rawKey = (unsigned char*)XMALLOC(rawLen, NULL,
+                                DYNAMIC_TYPE_TMP_BUFFER);
+                        if (rawKey == NULL) {
+                            WOLFSSL_MSG("Memory error");
+                            wc_FreeRsaKey(&rsa);
+                            return WOLFSSL_FAILURE;
+                        }
+                        XMEMSET(rawKey, 0, rawLen);
+                        mp_to_unsigned_bin(&rsa.e, rawKey);
+                        if ((word32)rawLen <= sizeof(word32)) {
+                            idx = *(word32*)rawKey;
+                        #ifdef BIG_ENDIAN_ORDER
+                            idx = ByteReverseWord32(idx);
+                        #endif
+                        }
+                        XSNPRINTF(tmp, sizeof(tmp) - 1,
+                            "\n                Exponent: %d (0x%x)\n",idx, idx);
+                        if (wolfSSL_BIO_write(bio, tmp,
+                                                      (int)XSTRLEN(tmp)) <= 0) {
+                            XFREE(rawKey, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+                            wc_FreeRsaKey(&rsa);
+                            return WOLFSSL_FAILURE;
+                        }
+                        XFREE(rawKey, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+                        wc_FreeRsaKey(&rsa);
+                    }
+                #endif /* HAVE_USER_RSA */
+                    break;
+            #endif /* NO_RSA */
+
+            #ifdef HAVE_ECC
+                case ECDSAk:
+                    {
+                        word32 i;
+                        ecc_key ecc;
+
+                        if (wolfSSL_BIO_write(bio,
+                                "            Public Key Algorithm: EC\n",
+                   (int)XSTRLEN("            Public Key Algorithm: EC\n")) <= 0) {
+                        return WOLFSSL_FAILURE;
+                        }
+                        if (wc_ecc_init_ex(&ecc, x509->heap, INVALID_DEVID)
+                                != 0) {
+                            return WOLFSSL_FAILURE;
+                        }
+
+                        i = 0;
+                        if (wc_EccPublicKeyDecode(x509->pubKey.buffer, &i,
+                                              &ecc, x509->pubKey.length) != 0) {
+                            wc_ecc_free(&ecc);
+                            return WOLFSSL_FAILURE;
+                        }
+                        XSNPRINTF(tmp, sizeof(tmp) - 1, "%s%s: (%d bit)\n%s\n",
+                                "                 ", "Public-Key",
+                                8 * wc_ecc_size(&ecc),
+                                "                 pub:");
+                        tmp[sizeof(tmp) - 1] = '\0';
+                        if (wolfSSL_BIO_write(bio, tmp,
+                                                      (int)XSTRLEN(tmp)) <= 0) {
+                            wc_ecc_free(&ecc);
+                            return WOLFSSL_FAILURE;
+                        }
+                        XSNPRINTF(tmp, sizeof(tmp) - 1,"                     ");
+                        {
+                            word32 derSz;
+                            byte*  der;
+
+                            derSz = wc_ecc_size(&ecc) * WOLFSSL_BIT_SIZE;
+                            der = (byte*)XMALLOC(derSz, x509->heap,
+                                    DYNAMIC_TYPE_TMP_BUFFER);
+                            if (der == NULL) {
+                                wc_ecc_free(&ecc);
+                                return WOLFSSL_FAILURE;
+                            }
+
+                            if (wc_ecc_export_x963(&ecc, der, &derSz) != 0) {
+                                wc_ecc_free(&ecc);
+                                XFREE(der, x509->heap, DYNAMIC_TYPE_TMP_BUFFER);
+                                return WOLFSSL_FAILURE;
+                            }
+                            for (i = 0; i < derSz; i++) {
+                                char val[5];
+                                int valSz = 5;
+
+                                if (i == 0) {
+                                    XSNPRINTF(val, valSz - 1, "%02x", der[i]);
+                                }
+                                else if ((i % 15) == 0) {
+                                    tmp[sizeof(tmp) - 1] = '\0';
+                                    if (wolfSSL_BIO_write(bio, tmp,
+                                                (int)XSTRLEN(tmp)) <= 0) {
+                                        wc_ecc_free(&ecc);
+                                        XFREE(der, x509->heap,
+                                                DYNAMIC_TYPE_TMP_BUFFER);
+                                        return WOLFSSL_FAILURE;
+                                    }
+                                    XSNPRINTF(tmp, sizeof(tmp) - 1,
+                                        ":\n                     ");
+                                    XSNPRINTF(val, valSz - 1, "%02x", der[i]);
+                                }
+                                else {
+                                    XSNPRINTF(val, valSz - 1, ":%02x", der[i]);
+                                }
+                                XSTRNCAT(tmp, val, valSz);
+                            }
+
+                            /* print out remaining modulus values */
+                            if ((i > 0) && (((i - 1) % 15) != 0)) {
+                                tmp[sizeof(tmp) - 1] = '\0';
+                                if (wolfSSL_BIO_write(bio, tmp,
+                                                      (int)XSTRLEN(tmp)) <= 0) {
+                                    wc_ecc_free(&ecc);
+                                    XFREE(der, x509->heap,
+                                                DYNAMIC_TYPE_TMP_BUFFER);
+                                    return WOLFSSL_FAILURE;
+                                }
+                            }
+
+                            XFREE(der, x509->heap, DYNAMIC_TYPE_TMP_BUFFER);
+                        }
+                        XSNPRINTF(tmp, sizeof(tmp) - 1, "\n%s%s: %s\n",
+                                "                ", "ASN1 OID",
+                                ecc.dp->name);
+                        if (wolfSSL_BIO_write(bio, tmp,
+                                                      (int)XSTRLEN(tmp)) <= 0) {
+                            wc_ecc_free(&ecc);
+                            return WOLFSSL_FAILURE;
+                        }
+                        wc_ecc_free(&ecc);
+                    }
+                    break;
+            #endif /* HAVE_ECC */
+                default:
+                    WOLFSSL_MSG("Unknown key type");
+                    return WOLFSSL_FAILURE;
+            }
+        }
+
+        /* print out extensions */
+        if (wolfSSL_BIO_write(bio, "        X509v3 extensions:\n",
+                      (int)XSTRLEN("        X509v3 extensions:\n")) <= 0) {
+            return WOLFSSL_FAILURE;
+        }
+
+        /* print subject key id */
+        if (x509->subjKeyIdSet && x509->subjKeyId != NULL &&
+                x509->subjKeyIdSz > 0) {
+            char tmp[100];
+            word32 i;
+            char val[5];
+            int valSz = 5;
+
+
+            if (wolfSSL_BIO_write(bio,
+                        "            X509v3 Subject Key Identifier: \n",
+           (int)XSTRLEN("            X509v3 Subject Key Identifier: \n"))
+                 <= 0) {
+                return WOLFSSL_FAILURE;
+            }
+
+            XSNPRINTF(tmp, sizeof(tmp) - 1, "                ");
+            for (i = 0; i < sizeof(tmp) && i < (x509->subjKeyIdSz - 1); i++) {
+                XSNPRINTF(val, valSz - 1, "%02X:", x509->subjKeyId[i]);
+                XSTRNCAT(tmp, val, valSz);
+            }
+            XSNPRINTF(val, valSz - 1, "%02X\n", x509->subjKeyId[i]);
+            XSTRNCAT(tmp, val, valSz);
+            if (wolfSSL_BIO_write(bio, tmp, (int)XSTRLEN(tmp)) <= 0) {
+                return WOLFSSL_FAILURE;
+            }
+        }
+
+        /* printf out authority key id */
+        if (x509->authKeyIdSet && x509->authKeyId != NULL &&
+                x509->authKeyIdSz > 0) {
+            char tmp[100];
+            word32 i;
+            char val[5];
+            int valSz = 5;
+            int len = 0;
+
+            if (wolfSSL_BIO_write(bio,
+                        "            X509v3 Authority Key Identifier: \n",
+           (int)XSTRLEN("            X509v3 Authority Key Identifier: \n"))
+                 <= 0) {
+                return WOLFSSL_FAILURE;
+            }
+
+            XSNPRINTF(tmp, sizeof(tmp) - 1, "                keyid");
+            for (i = 0; i < x509->authKeyIdSz; i++) {
+                /* check if buffer is almost full */
+                if (XSTRLEN(tmp) >= sizeof(tmp) - valSz) {
+                    if (wolfSSL_BIO_write(bio, tmp, (int)XSTRLEN(tmp)) <= 0) {
+                        return WOLFSSL_FAILURE;
+                    }
+                    tmp[0] = '\0';
+                }
+                XSNPRINTF(val, valSz - 1, ":%02X", x509->authKeyId[i]);
+                XSTRNCAT(tmp, val, valSz);
+            }
+            len = (int)XSTRLEN("\n");
+            XSTRNCAT(tmp, "\n", len + 1);
+            if (wolfSSL_BIO_write(bio, tmp, (int)XSTRLEN(tmp)) <= 0) {
+                return WOLFSSL_FAILURE;
+            }
+        }
+
+        /* print basic constraint */
+        if (x509->basicConstSet) {
+            char tmp[100];
+
+            if (wolfSSL_BIO_write(bio,
+                        "\n            X509v3 Basic Constraints: \n",
+           (int)XSTRLEN("\n            X509v3 Basic Constraints: \n"))
+                 <= 0) {
+                return WOLFSSL_FAILURE;
+            }
+            XSNPRINTF(tmp, sizeof(tmp),
+                    "                CA:%s\n",
+                    (x509->isCa)? "TRUE": "FALSE");
+            if (wolfSSL_BIO_write(bio, tmp, (int)XSTRLEN(tmp)) <= 0) {
+                return WOLFSSL_FAILURE;
+            }
+        }
+
+        /* print out signature */
+        if (x509->sig.length > 0) {
+            unsigned char* sig;
+            int sigSz;
+            int i;
+            char tmp[100];
+            int sigOid = wolfSSL_X509_get_signature_type(x509);
+
+            if (wolfSSL_BIO_write(bio,
+                                "    Signature Algorithm: ",
+                   (int)XSTRLEN("    Signature Algorithm: ")) <= 0) {
+                return WOLFSSL_FAILURE;
+            }
+            XSNPRINTF(tmp, sizeof(tmp) - 1,"%s\n", GetSigName(sigOid));
+            tmp[sizeof(tmp) - 1] = '\0';
+            if (wolfSSL_BIO_write(bio, tmp, (int)XSTRLEN(tmp)) <= 0) {
+                return WOLFSSL_FAILURE;
+            }
+
+            sigSz = (int)x509->sig.length;
+            sig = (unsigned char*)XMALLOC(sigSz, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+            if (sig == NULL) {
+                return WOLFSSL_FAILURE;
+            }
+
+            if (wolfSSL_X509_get_signature(x509, sig, &sigSz) <= 0) {
+                XFREE(sig, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+                return WOLFSSL_FAILURE;
+            }
+            XSNPRINTF(tmp, sizeof(tmp) - 1,"        ");
+            tmp[sizeof(tmp) - 1] = '\0';
+            for (i = 0; i < sigSz; i++) {
+                char val[5];
+                int valSz = 5;
+
+                if (i == 0) {
+                    XSNPRINTF(val, valSz - 1, "%02x", sig[i]);
+                }
+                else if (((i % 18) == 0)) {
+                    tmp[sizeof(tmp) - 1] = '\0';
+                    if (wolfSSL_BIO_write(bio, tmp, (int)XSTRLEN(tmp))
+                            <= 0) {
+                        XFREE(sig, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+                        return WOLFSSL_FAILURE;
+                    }
+                    XSNPRINTF(tmp, sizeof(tmp) - 1,
+                            ":\n        ");
+                    XSNPRINTF(val, valSz - 1, "%02x", sig[i]);
+                }
+                else {
+                    XSNPRINTF(val, valSz - 1, ":%02x", sig[i]);
+                }
+                XSTRNCAT(tmp, val, valSz);
+            }
+            XFREE(sig, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+
+            /* print out remaining sig values */
+            if ((i > 0) && (((i - 1) % 18) != 0)) {
+                    tmp[sizeof(tmp) - 1] = '\0';
+                    if (wolfSSL_BIO_write(bio, tmp, (int)XSTRLEN(tmp))
+                            <= 0) {
+                        return WOLFSSL_FAILURE;
+                    }
+            }
+        }
+
+        /* done with print out */
+        if (wolfSSL_BIO_write(bio, "\n\0", (int)XSTRLEN("\n\0")) <= 0) {
+            return WOLFSSL_FAILURE;
+        }
+
+        return WOLFSSL_SUCCESS;
+    }
+    int wolfSSL_X509_print(WOLFSSL_BIO* bio, WOLFSSL_X509* x509)
+    {
+        return wolfSSL_X509_print_ex(bio, x509, 0, 0);
+    }
+
+#endif /* XSNPRINTF */
+
+#endif /* NO_CERTS */
+
+#if defined(OPENSSL_ALL) || defined(WOLFSSL_QT)
+/* Creates cipher->description based on cipher->offset
+ * cipher->offset is set in wolfSSL_get_ciphers_compat when it is added
+ * to a stack of ciphers.
+ * @param [in] cipher: A cipher from a stack of ciphers.
+ * return WOLFSSL_SUCCESS if cipher->description is set, else WOLFSSL_FAILURE
+ */
+int wolfSSL_sk_CIPHER_description(WOLFSSL_CIPHER* cipher)
+{
+    int ret = WOLFSSL_FAILURE;
+    int i,j,k;
+    int strLen;
+    unsigned long offset;
+    char* dp;
+    const char* name;
+    const char *keaStr, *authStr, *encStr, *macStr, *protocol;
+    char n[MAX_SEGMENTS][MAX_SEGMENT_SZ] = {{0}};
+    unsigned char len = MAX_DESCRIPTION_SZ-1;
+    const CipherSuiteInfo* cipher_names;
+    ProtocolVersion pv;
+    WOLFSSL_ENTER("wolfSSL_sk_CIPHER_description");
+
+    if (cipher == NULL)
+        return WOLFSSL_FAILURE;
+
+    dp = cipher->description;
+    if (dp == NULL)
+        return WOLFSSL_FAILURE;
+
+    cipher_names = GetCipherNames();
+
+    offset = cipher->offset;
+    pv.major = cipher_names[offset].major;
+    pv.minor = cipher_names[offset].minor;
+    protocol = wolfSSL_internal_get_version(&pv);
+
+    name = cipher_names[offset].name;
+
+    if (name == NULL)
+        return ret;
+
+    /* Segment cipher name into n[n0,n1,n2,n4]
+     * These are used later for comparisons to create:
+     * keaStr, authStr, encStr, macStr
+     *
+     * If cipher_name = ECDHE-ECDSA-AES256-SHA
+     * then n0 = "ECDHE", n1 = "ECDSA", n2 = "AES256", n3 = "SHA"
+     * and n = [n0,n1,n2,n3,0]
+     */
+    strLen = (int)XSTRLEN(name);
+
+    for (i = 0, j = 0, k = 0; i <= strLen; i++) {
+        if (k > MAX_SEGMENTS || j > MAX_SEGMENT_SZ)
+            break;
+
+        if (name[i] != '-' && name[i] != '\0') {
+            n[k][j] = name[i]; /* Fill kth segment string until '-' */
+            j++;
+        }
+        else {
+            n[k][j] = '\0';
+            j = 0;
+            k++;
+        }
+    }
+    /* keaStr */
+    keaStr = GetCipherKeaStr(n);
+    /* authStr */
+    authStr = GetCipherAuthStr(n);
+    /* encStr */
+    encStr = GetCipherEncStr(n);
+    if ((cipher->bits = SetCipherBits(encStr)) == WOLFSSL_FAILURE) {
+       WOLFSSL_MSG("Cipher Bits Not Set.");
+    }
+    /* macStr */
+    macStr = GetCipherMacStr(n);
+
+
+    /* Build up the string by copying onto the end. */
+    XSTRNCPY(dp, name, len);
+    dp[len-1] = '\0'; strLen = (int)XSTRLEN(dp);
+    len -= (int)strLen; dp += strLen;
+
+    XSTRNCPY(dp, " ", len);
+    dp[len-1] = '\0'; strLen = (int)XSTRLEN(dp);
+    len -= (int)strLen; dp += strLen;
+    XSTRNCPY(dp, protocol, len);
+    dp[len-1] = '\0'; strLen = (int)XSTRLEN(dp);
+    len -= (int)strLen; dp += strLen;
+
+    XSTRNCPY(dp, " Kx=", len);
+    dp[len-1] = '\0'; strLen = (int)XSTRLEN(dp);
+    len -= (int)strLen; dp += strLen;
+    XSTRNCPY(dp, keaStr, len);
+    dp[len-1] = '\0'; strLen = (int)XSTRLEN(dp);
+    len -= (int)strLen; dp += strLen;
+
+    XSTRNCPY(dp, " Au=", len);
+    dp[len-1] = '\0'; strLen = (int)XSTRLEN(dp);
+    len -= (int)strLen; dp += strLen;
+    XSTRNCPY(dp, authStr, len);
+    dp[len-1] = '\0'; strLen = (int)XSTRLEN(dp);
+    len -= (int)strLen; dp += strLen;
+
+    XSTRNCPY(dp, " Enc=", len);
+    dp[len-1] = '\0'; strLen = (int)XSTRLEN(dp);
+    len -= (int)strLen; dp += strLen;
+    XSTRNCPY(dp, encStr, len);
+    dp[len-1] = '\0'; strLen = (int)XSTRLEN(dp);
+    len -= (int)strLen; dp += strLen;
+
+    XSTRNCPY(dp, " Mac=", len);
+    dp[len-1] = '\0'; strLen = (int)XSTRLEN(dp);
+    len -= (int)strLen; dp += strLen;
+    XSTRNCPY(dp, macStr, len);
+    dp[len-1] = '\0';
+
+    return WOLFSSL_SUCCESS;
+}
+#endif
+
+char* wolfSSL_CIPHER_description(const WOLFSSL_CIPHER* cipher, char* in,
+                                 int len)
+{
+    char *ret = in;
+    const char *keaStr, *authStr, *encStr, *macStr;
+    size_t strLen;
+    WOLFSSL_ENTER("wolfSSL_CIPHER_description");
+
+    if (cipher == NULL || in == NULL)
+        return NULL;
+
+#if defined(WOLFSSL_QT) || defined(OPENSSL_ALL)
+    /* if cipher is in the stack from wolfSSL_get_ciphers_compat then
+     * Return the description based on cipher_names[cipher->offset]
+     */
+    if (cipher->in_stack == TRUE) {
+        wolfSSL_sk_CIPHER_description((WOLFSSL_CIPHER*)cipher);
+        XSTRNCPY(in,cipher->description,len);
+        return ret;
+    }
+#endif
+
+    /* Get the cipher description based on the SSL session cipher */
+    switch (cipher->ssl->specs.kea) {
+        case no_kea:
+            keaStr = "None";
+            break;
+#ifndef NO_RSA
+        case rsa_kea:
+            keaStr = "RSA";
+            break;
+#endif
+#ifndef NO_DH
+        case diffie_hellman_kea:
+            keaStr = "DHE";
+            break;
+#endif
+        case fortezza_kea:
+            keaStr = "FZ";
+            break;
+#ifndef NO_PSK
+        case psk_kea:
+            keaStr = "PSK";
+            break;
+    #ifndef NO_DH
+        case dhe_psk_kea:
+            keaStr = "DHEPSK";
+            break;
+    #endif
+    #ifdef HAVE_ECC
+        case ecdhe_psk_kea:
+            keaStr = "ECDHEPSK";
+            break;
+    #endif
+#endif
+#ifdef HAVE_NTRU
+        case ntru_kea:
+            keaStr = "NTRU";
+            break;
+#endif
+#ifdef HAVE_ECC
+        case ecc_diffie_hellman_kea:
+            keaStr = "ECDHE";
+            break;
+        case ecc_static_diffie_hellman_kea:
+            keaStr = "ECDH";
+            break;
+#endif
+        default:
+            keaStr = "unknown";
+            break;
+    }
+
+    switch (cipher->ssl->specs.sig_algo) {
+        case anonymous_sa_algo:
+            authStr = "None";
+            break;
+#ifndef NO_RSA
+        case rsa_sa_algo:
+            authStr = "RSA";
+            break;
+#endif
+#ifndef NO_DSA
+        case dsa_sa_algo:
+            authStr = "DSA";
+            break;
+#endif
+#ifdef HAVE_ECC
+        case ecc_dsa_sa_algo:
+            authStr = "ECDSA";
+            break;
+#endif
+        default:
+            authStr = "unknown";
+            break;
+    }
+
+    switch (cipher->ssl->specs.bulk_cipher_algorithm) {
+        case wolfssl_cipher_null:
+            encStr = "None";
+            break;
+#ifndef NO_RC4
+        case wolfssl_rc4:
+            encStr = "RC4(128)";
+            break;
+#endif
+#ifndef NO_DES3
+        case wolfssl_triple_des:
+            encStr = "3DES(168)";
+            break;
+#endif
+#ifdef HAVE_IDEA
+        case wolfssl_idea:
+            encStr = "IDEA(128)";
+            break;
+#endif
+#ifndef NO_AES
+        case wolfssl_aes:
+            if (cipher->ssl->specs.key_size == 128)
+                encStr = "AES(128)";
+            else if (cipher->ssl->specs.key_size == 256)
+                encStr = "AES(256)";
+            else
+                encStr = "AES(?)";
+            break;
+    #ifdef HAVE_AESGCM
+        case wolfssl_aes_gcm:
+            if (cipher->ssl->specs.key_size == 128)
+                encStr = "AESGCM(128)";
+            else if (cipher->ssl->specs.key_size == 256)
+                encStr = "AESGCM(256)";
+            else
+                encStr = "AESGCM(?)";
+            break;
+    #endif
+    #ifdef HAVE_AESCCM
+        case wolfssl_aes_ccm:
+            if (cipher->ssl->specs.key_size == 128)
+                encStr = "AESCCM(128)";
+            else if (cipher->ssl->specs.key_size == 256)
+                encStr = "AESCCM(256)";
+            else
+                encStr = "AESCCM(?)";
+            break;
+    #endif
+#endif
+#ifdef HAVE_CHACHA
+        case wolfssl_chacha:
+            encStr = "CHACHA20/POLY1305(256)";
+            break;
+#endif
+#ifdef HAVE_CAMELLIA
+        case wolfssl_camellia:
+            if (cipher->ssl->specs.key_size == 128)
+                encStr = "Camellia(128)";
+            else if (cipher->ssl->specs.key_size == 256)
+                encStr = "Camellia(256)";
+            else
+                encStr = "Camellia(?)";
+            break;
+#endif
+#if defined(HAVE_HC128) && !defined(NO_HC128)
+        case wolfssl_hc128:
+            encStr = "HC128(128)";
+            break;
+#endif
+#if defined(HAVE_RABBIT) && !defined(NO_RABBIT)
+        case wolfssl_rabbit:
+            encStr = "RABBIT(128)";
+            break;
+#endif
+        default:
+            encStr = "unknown";
+            break;
+    }
+
+    switch (cipher->ssl->specs.mac_algorithm) {
+        case no_mac:
+            macStr = "None";
+            break;
+#ifndef NO_MD5
+        case md5_mac:
+            macStr = "MD5";
+            break;
+#endif
+#ifndef NO_SHA
+        case sha_mac:
+            macStr = "SHA1";
+            break;
+#endif
+#ifdef HAVE_SHA224
+        case sha224_mac:
+            macStr = "SHA224";
+            break;
+#endif
+#ifndef NO_SHA256
+        case sha256_mac:
+            macStr = "SHA256";
+            break;
+#endif
+#ifdef HAVE_SHA384
+        case sha384_mac:
+            macStr = "SHA384";
+            break;
+#endif
+#ifdef HAVE_SHA512
+        case sha512_mac:
+            macStr = "SHA512";
+            break;
+#endif
+        default:
+            macStr = "unknown";
+            break;
+    }
+
+    /* Build up the string by copying onto the end. */
+    XSTRNCPY(in, wolfSSL_CIPHER_get_name(cipher), len);
+    in[len-1] = '\0'; strLen = XSTRLEN(in); len -= (int)strLen; in += strLen;
+
+    XSTRNCPY(in, " ", len);
+    in[len-1] = '\0'; strLen = XSTRLEN(in); len -= (int)strLen; in += strLen;
+    XSTRNCPY(in, wolfSSL_get_version(cipher->ssl), len);
+    in[len-1] = '\0'; strLen = XSTRLEN(in); len -= (int)strLen; in += strLen;
+
+    XSTRNCPY(in, " Kx=", len);
+    in[len-1] = '\0'; strLen = XSTRLEN(in); len -= (int)strLen; in += strLen;
+    XSTRNCPY(in, keaStr, len);
+    in[len-1] = '\0'; strLen = XSTRLEN(in); len -= (int)strLen; in += strLen;
+
+    XSTRNCPY(in, " Au=", len);
+    in[len-1] = '\0'; strLen = XSTRLEN(in); len -= (int)strLen; in += strLen;
+    XSTRNCPY(in, authStr, len);
+    in[len-1] = '\0'; strLen = XSTRLEN(in); len -= (int)strLen; in += strLen;
+
+    XSTRNCPY(in, " Enc=", len);
+    in[len-1] = '\0'; strLen = XSTRLEN(in); len -= (int)strLen; in += strLen;
+    XSTRNCPY(in, encStr, len);
+    in[len-1] = '\0'; strLen = XSTRLEN(in); len -= (int)strLen; in += strLen;
+
+    XSTRNCPY(in, " Mac=", len);
+    in[len-1] = '\0'; strLen = XSTRLEN(in); len -= (int)strLen; in += strLen;
+    XSTRNCPY(in, macStr, len);
+    in[len-1] = '\0';
+
+    return ret;
+}
+
+
+#ifndef NO_SESSION_CACHE
+
+WOLFSSL_SESSION* wolfSSL_get1_session(WOLFSSL* ssl)
+{
+    if (ssl == NULL) {
+        return NULL;
+    }
+
+    /* sessions are stored statically, no need for reference count */
+    return wolfSSL_get_session(ssl);
+}
+
+#endif /* NO_SESSION_CACHE */
+
+
+
+/* was do nothing */
+/*
+void OPENSSL_free(void* buf)
+{
+    (void)buf;
+}
+*/
+
+#ifndef NO_WOLFSSL_STUB
+int wolfSSL_OCSP_parse_url(char* url, char** host, char** port, char** path,
+                   int* ssl)
+{
+    (void)url;
+    (void)host;
+    (void)port;
+    (void)path;
+    (void)ssl;
+    WOLFSSL_STUB("OCSP_parse_url");
+    return 0;
+}
+#endif
+
+#ifndef NO_MD4
+
+void wolfSSL_MD4_Init(WOLFSSL_MD4_CTX* md4)
+{
+    /* make sure we have a big enough buffer */
+    typedef char ok[sizeof(md4->buffer) >= sizeof(Md4) ? 1 : -1];
+    (void) sizeof(ok);
+
+    WOLFSSL_ENTER("MD4_Init");
+    wc_InitMd4((Md4*)md4);
+}
+
+
+void wolfSSL_MD4_Update(WOLFSSL_MD4_CTX* md4, const void* data,
+                       unsigned long len)
+{
+    WOLFSSL_ENTER("MD4_Update");
+    wc_Md4Update((Md4*)md4, (const byte*)data, (word32)len);
+}
+
+
+void wolfSSL_MD4_Final(unsigned char* digest, WOLFSSL_MD4_CTX* md4)
+{
+    WOLFSSL_ENTER("MD4_Final");
+    wc_Md4Final((Md4*)md4, digest);
+}
+
+#endif /* NO_MD4 */
+
+
+/* Removes a WOLFSSL_BIO struct from the WOLFSSL_BIO linked list.
+ *
+ * bio is the WOLFSSL_BIO struct in the list and removed.
+ *
+ * The return WOLFSSL_BIO struct is the next WOLFSSL_BIO in the list or NULL if
+ * there is none.
+ */
+WOLFSSL_BIO* wolfSSL_BIO_pop(WOLFSSL_BIO* bio)
+{
+    if (bio == NULL) {
+        WOLFSSL_MSG("Bad argument passed in");
+        return NULL;
+    }
+
+    if (bio->prev != NULL) {
+        bio->prev->next = bio->next;
+    }
+
+    if (bio->next != NULL) {
+        bio->next->prev = bio->prev;
+    }
+
+    return bio->next;
+}
+
+
+
+WOLFSSL_BIO_METHOD* wolfSSL_BIO_s_mem(void)
+{
+    static WOLFSSL_BIO_METHOD meth;
+
+    WOLFSSL_ENTER("wolfSSL_BIO_s_mem");
+    meth.type = WOLFSSL_BIO_MEMORY;
+
+    return &meth;
+}
+
+
+WOLFSSL_BIO_METHOD* wolfSSL_BIO_f_base64(void)
+{
+    static WOLFSSL_BIO_METHOD meth;
+
+    WOLFSSL_ENTER("wolfSSL_BIO_f_base64");
+    meth.type = WOLFSSL_BIO_BASE64;
+
+    return &meth;
+}
+
+
+/* Set the flag for the bio.
+ *
+ * bio   the structure to set the flag in
+ * flags the flag to use
+ */
+void wolfSSL_BIO_set_flags(WOLFSSL_BIO* bio, int flags)
+{
+    WOLFSSL_ENTER("wolfSSL_BIO_set_flags");
+
+    if (bio != NULL) {
+        bio->flags |= flags;
+    }
+}
+
+void wolfSSL_BIO_clear_flags(WOLFSSL_BIO *bio, int flags)
+{
+    WOLFSSL_ENTER("wolfSSL_BIO_clear_flags");
+    if (bio != NULL) {
+        bio->flags &= ~flags;
+    }
+}
+
+/* Set ex_data for WOLFSSL_BIO
+ *
+ * bio  : BIO structure to set ex_data in
+ * idx  : Index of ex_data to set
+ * data : Data to set in ex_data
+ *
+ * Returns WOLFSSL_SUCCESS on success or WOLFSSL_FAILURE on failure
+ */
+int wolfSSL_BIO_set_ex_data(WOLFSSL_BIO *bio, int idx, void *data)
+{
+    WOLFSSL_ENTER("wolfSSL_BIO_set_ex_data");
+    #ifdef HAVE_EX_DATA
+    if (bio != NULL && idx < MAX_EX_DATA) {
+        return wolfSSL_CRYPTO_set_ex_data(&bio->ex_data, idx, data);
+    }
+    #else
+    (void)bio;
+    (void)idx;
+    (void)data;
+    #endif
+    return WOLFSSL_FAILURE;
+}
+
+/* Get ex_data in WOLFSSL_BIO at given index
+ *
+ * bio  : BIO structure to get ex_data from
+ * idx  : Index of ex_data to get data from
+ *
+ * Returns void pointer to ex_data on success or NULL on failure
+ */
+void *wolfSSL_BIO_get_ex_data(WOLFSSL_BIO *bio, int idx)
+{
+    WOLFSSL_ENTER("wolfSSL_BIO_get_ex_data");
+    #ifdef HAVE_EX_DATA
+    if (bio != NULL && idx < MAX_EX_DATA && idx >= 0) {
+        return wolfSSL_CRYPTO_get_ex_data(&bio->ex_data, idx);
+    }
+    #else
+    (void)bio;
+    (void)idx;
+    #endif
+    return NULL;
+}
+
+#ifndef NO_WOLFSSL_STUB
+void wolfSSL_RAND_screen(void)
+{
+    WOLFSSL_STUB("RAND_screen");
+}
+#endif
+
+
+
+int wolfSSL_RAND_load_file(const char* fname, long len)
+{
+    (void)fname;
+    /* wolfCrypt provides enough entropy internally or will report error */
+    if (len == -1)
+        return 1024;
+    else
+        return (int)len;
+}
+
+
+#ifndef NO_WOLFSSL_STUB
+WOLFSSL_COMP_METHOD* wolfSSL_COMP_zlib(void)
+{
+    WOLFSSL_STUB("COMP_zlib");
+    return 0;
+}
+#endif
+
+#ifndef NO_WOLFSSL_STUB
+WOLFSSL_COMP_METHOD* wolfSSL_COMP_rle(void)
+{
+    WOLFSSL_STUB("COMP_rle");
+    return 0;
+}
+#endif
+
+#ifndef NO_WOLFSSL_STUB
+int wolfSSL_COMP_add_compression_method(int method, void* data)
+{
+    (void)method;
+    (void)data;
+    WOLFSSL_STUB("COMP_add_compression_method");
+    return 0;
+}
+#endif
+
+#ifndef NO_WOLFSSL_STUB
+void wolfSSL_set_dynlock_create_callback(WOLFSSL_dynlock_value* (*f)(
+                                                          const char*, int))
+{
+    WOLFSSL_STUB("CRYPTO_set_dynlock_create_callback");
+    (void)f;
+}
+#endif
+
+#ifndef NO_WOLFSSL_STUB
+void wolfSSL_set_dynlock_lock_callback(
+             void (*f)(int, WOLFSSL_dynlock_value*, const char*, int))
+{
+    WOLFSSL_STUB("CRYPTO_set_set_dynlock_lock_callback");
+    (void)f;
+}
+#endif
+
+#ifndef NO_WOLFSSL_STUB
+void wolfSSL_set_dynlock_destroy_callback(
+                  void (*f)(WOLFSSL_dynlock_value*, const char*, int))
+{
+    WOLFSSL_STUB("CRYPTO_set_set_dynlock_destroy_callback");
+    (void)f;
+}
+#endif
+
+
+const char* wolfSSL_X509_verify_cert_error_string(long err)
+{
+    return wolfSSL_ERR_reason_error_string(err);
+}
+
+
+#ifndef NO_WOLFSSL_STUB
+int wolfSSL_X509_LOOKUP_add_dir(WOLFSSL_X509_LOOKUP* lookup, const char* dir,
+                               long len)
+{
+    (void)lookup;
+    (void)dir;
+    (void)len;
+    WOLFSSL_STUB("X509_LOOKUP_add_dir");
+    return 0;
+}
+#endif
+
+int wolfSSL_X509_LOOKUP_load_file(WOLFSSL_X509_LOOKUP* lookup,
+                                 const char* file, long type)
+{
+#if !defined(NO_FILESYSTEM) && \
+    (defined(WOLFSSL_PEM_TO_DER) || defined(WOLFSSL_DER_TO_PEM))
+    int           ret = WOLFSSL_FAILURE;
+    XFILE         fp;
+    long          sz;
+    byte*         pem = NULL;
+    byte*         curr = NULL;
+    byte*         prev = NULL;
+    WOLFSSL_X509* x509;
+    const char* header = NULL;
+    const char* footer = NULL;
+
+    if (type != X509_FILETYPE_PEM)
+        return BAD_FUNC_ARG;
+
+    fp = XFOPEN(file, "r");
+    if (fp == XBADFILE)
+        return BAD_FUNC_ARG;
+
+    if(XFSEEK(fp, 0, XSEEK_END) != 0) {
+        XFCLOSE(fp);
+        return WOLFSSL_BAD_FILE;
+    }
+    sz = XFTELL(fp);
+    XREWIND(fp);
+
+    if (sz > MAX_WOLFSSL_FILE_SIZE || sz <= 0) {
+        WOLFSSL_MSG("X509_LOOKUP_load_file size error");
+        goto end;
+    }
+
+    pem = (byte*)XMALLOC(sz, 0, DYNAMIC_TYPE_PEM);
+    if (pem == NULL) {
+        ret = MEMORY_ERROR;
+        goto end;
+    }
+
+    /* Read in file which may be CRLs or certificates. */
+    if (XFREAD(pem, (size_t)sz, 1, fp) != 1)
+        goto end;
+
+    prev = curr = pem;
+    do {
+        /* get PEM header and footer based on type */
+        if (wc_PemGetHeaderFooter(CRL_TYPE, &header, &footer) == 0 &&
+                XSTRNSTR((char*)curr, header, (unsigned int)sz) != NULL) {
+#ifdef HAVE_CRL
+            WOLFSSL_CERT_MANAGER* cm = lookup->store->cm;
+
+            if (cm->crl == NULL) {
+                if (wolfSSL_CertManagerEnableCRL(cm, 0) != WOLFSSL_SUCCESS) {
+                    WOLFSSL_MSG("Enable CRL failed");
+                    goto end;
+                }
+            }
+
+            ret = BufferLoadCRL(cm->crl, curr, sz, WOLFSSL_FILETYPE_PEM,
+                NO_VERIFY);
+            if (ret != WOLFSSL_SUCCESS)
+                goto end;
+#endif
+            curr = (byte*)XSTRNSTR((char*)curr, footer, (unsigned int)sz);
+        }
+        else if (wc_PemGetHeaderFooter(CERT_TYPE, &header, &footer) == 0 &&
+                XSTRNSTR((char*)curr, header, (unsigned int)sz) != NULL) {
+            x509 = wolfSSL_X509_load_certificate_buffer(curr, (int)sz,
+                                                        WOLFSSL_FILETYPE_PEM);
+            if (x509 == NULL)
+                 goto end;
+            ret = wolfSSL_X509_STORE_add_cert(lookup->store, x509);
+            wolfSSL_X509_free(x509);
+            if (ret != WOLFSSL_SUCCESS)
+                goto end;
+            curr = (byte*)XSTRNSTR((char*)curr, footer, (unsigned int)sz);
+        }
+        else
+            goto end;
+
+        if (curr == NULL)
+            goto end;
+
+        curr++;
+        sz -= (long)(curr - prev);
+        prev = curr;
+    }
+    while (ret == WOLFSSL_SUCCESS);
+
+end:
+    if (pem != NULL)
+        XFREE(pem, 0, DYNAMIC_TYPE_PEM);
+    XFCLOSE(fp);
+    return ret;
+#else
+    (void)lookup;
+    (void)file;
+    (void)type;
+    return WOLFSSL_FAILURE;
+#endif
+}
+
+WOLFSSL_X509_LOOKUP_METHOD* wolfSSL_X509_LOOKUP_hash_dir(void)
+{
+    /* Method implementation in functions. */
+    static WOLFSSL_X509_LOOKUP_METHOD meth = { 1 };
+    return &meth;
+}
+
+WOLFSSL_X509_LOOKUP_METHOD* wolfSSL_X509_LOOKUP_file(void)
+{
+    /* Method implementation in functions. */
+    static WOLFSSL_X509_LOOKUP_METHOD meth = { 0 };
+    return &meth;
+}
+
+
+WOLFSSL_X509_LOOKUP* wolfSSL_X509_STORE_add_lookup(WOLFSSL_X509_STORE* store,
+                                               WOLFSSL_X509_LOOKUP_METHOD* m)
+{
+    WOLFSSL_ENTER("SSL_X509_STORE_add_lookup");
+    if (store == NULL)
+        return NULL;
+
+    /* Method is a dummy value and is not needed. */
+    (void)m;
+    /* Make sure the lookup has a back reference to the store. */
+    store->lookup.store = store;
+    return &store->lookup;
+}
+
+
+#ifndef NO_CERTS
+/* Converts the X509 to DER format and outputs it into bio.
+ *
+ * bio  is the structure to hold output DER
+ * x509 certificate to create DER from
+ *
+ * returns WOLFSSL_SUCCESS on success
+ */
+int wolfSSL_i2d_X509_bio(WOLFSSL_BIO* bio, WOLFSSL_X509* x509)
+{
+    WOLFSSL_ENTER("wolfSSL_i2d_X509_bio");
+
+    if (bio == NULL || x509 == NULL) {
+        return WOLFSSL_FAILURE;
+    }
+
+    if (x509->derCert != NULL) {
+        word32 len = x509->derCert->length;
+        byte*  der = x509->derCert->buffer;
+
+        if (wolfSSL_BIO_write(bio, der, len) == (int)len) {
+            return SSL_SUCCESS;
+        }
+    }
+
+    return WOLFSSL_FAILURE;
+}
+
+
+/* Converts an internal structure to a DER buffer
+ *
+ * x509 structure to get DER buffer from
+ * out  buffer to hold result. If NULL then *out is NULL then a new buffer is
+ *      created.
+ *
+ * returns the size of the DER result on success
+ */
+int wolfSSL_i2d_X509(WOLFSSL_X509* x509, unsigned char** out)
+{
+    const unsigned char* der;
+    int derSz = 0;
+
+    WOLFSSL_ENTER("wolfSSL_i2d_X509");
+
+    if (x509 == NULL) {
+        WOLFSSL_LEAVE("wolfSSL_i2d_X509", BAD_FUNC_ARG);
+        return BAD_FUNC_ARG;
+    }
+
+    der = wolfSSL_X509_get_der(x509, &derSz);
+    if (der == NULL) {
+        WOLFSSL_LEAVE("wolfSSL_i2d_X509", MEMORY_E);
+        return MEMORY_E;
+    }
+
+    if (out != NULL && *out == NULL) {
+        *out = (unsigned char*)XMALLOC(derSz, NULL, DYNAMIC_TYPE_OPENSSL);
+        if (*out == NULL) {
+            WOLFSSL_LEAVE("wolfSSL_i2d_X509", MEMORY_E);
+            return MEMORY_E;
+        }
+    }
+
+    if (out != NULL)
+        XMEMCPY(*out, der, derSz);
+
+    WOLFSSL_LEAVE("wolfSSL_i2d_X509", derSz);
+    return derSz;
+}
+
+
+/* Converts the DER from bio and creates a WOLFSSL_X509 structure from it.
+ *
+ * bio  is the structure holding DER
+ * x509 certificate to create from DER. Can be NULL
+ *
+ * returns pointer to WOLFSSL_X509 structure on success and NULL on fail
+ */
+WOLFSSL_X509* wolfSSL_d2i_X509_bio(WOLFSSL_BIO* bio, WOLFSSL_X509** x509)
+{
+    WOLFSSL_X509* localX509 = NULL;
+    unsigned char* mem  = NULL;
+    int    ret;
+    word32 size;
+
+    WOLFSSL_ENTER("wolfSSL_d2i_X509_bio");
+
+    if (bio == NULL) {
+        WOLFSSL_MSG("Bad Function Argument bio is NULL");
+        return NULL;
+    }
+
+    ret = wolfSSL_BIO_get_mem_data(bio, &mem);
+    if (mem == NULL || ret <= 0) {
+        WOLFSSL_MSG("Failed to get data from bio struct");
+        return NULL;
+    }
+    size = ret;
+
+    localX509 = wolfSSL_X509_d2i(NULL, mem, size);
+    if (localX509 == NULL) {
+        return NULL;
+    }
+
+    if (x509 != NULL) {
+        *x509 = localX509;
+    }
+
+    return localX509;
+}
+
+
+#if !defined(NO_ASN) && !defined(NO_PWDBASED)
+WC_PKCS12* wolfSSL_d2i_PKCS12_bio(WOLFSSL_BIO* bio, WC_PKCS12** pkcs12)
+{
+    WC_PKCS12* localPkcs12    = NULL;
+    unsigned char* mem  = NULL;
+    int ret;
+    word32 size;
+
+    WOLFSSL_ENTER("wolfSSL_d2i_PKCS12_bio");
+
+    if (bio == NULL) {
+        WOLFSSL_MSG("Bad Function Argument bio is NULL");
+        return NULL;
+    }
+
+    localPkcs12 = wc_PKCS12_new();
+    if (localPkcs12 == NULL) {
+        WOLFSSL_MSG("Memory error");
+        return NULL;
+    }
+
+    if (pkcs12 != NULL) {
+        *pkcs12 = localPkcs12;
+    }
+
+    ret = wolfSSL_BIO_get_mem_data(bio, &mem);
+    if (mem == NULL || ret <= 0) {
+        WOLFSSL_MSG("Failed to get data from bio struct");
+        wc_PKCS12_free(localPkcs12);
+        if (pkcs12 != NULL) {
+            *pkcs12 = NULL;
+        }
+        return NULL;
+    }
+    size = ret;
+
+    ret = wc_d2i_PKCS12(mem, size, localPkcs12);
+    if (ret < 0) {
+        WOLFSSL_MSG("Failed to get PKCS12 sequence");
+        wc_PKCS12_free(localPkcs12);
+        if (pkcs12 != NULL) {
+            *pkcs12 = NULL;
+        }
+        return NULL;
+    }
+
+    return localPkcs12;
+}
+
+/* Converts the PKCS12 to DER format and outputs it into bio.
+ *
+ * bio is the structure to hold output DER
+ * pkcs12 structure to create DER from
+ *
+ * return 1 for success or 0 if an error occurs
+ */
+int wolfSSL_i2d_PKCS12_bio(WOLFSSL_BIO *bio, WC_PKCS12 *pkcs12)
+{
+    int ret = WOLFSSL_FAILURE;
+
+    WOLFSSL_ENTER("wolfSSL_i2d_PKCS12_bio");
+
+    if ((bio != NULL) && (pkcs12 != NULL)) {
+        word32 certSz = 0;
+        byte *certDer = NULL;
+
+        certSz = wc_i2d_PKCS12(pkcs12, &certDer, NULL);
+        if ((certSz > 0) && (certDer != NULL)) {
+            if (wolfSSL_BIO_write(bio, certDer, certSz) == (int)certSz) {
+                ret = SSL_SUCCESS;
+            }
+        }
+
+        if (certDer != NULL) {
+            XFREE(certDer, NULL, DYNAMIC_TYPE_PKCS);
+        }
+    }
+
+    return ret;
+}
+
+/* helper function to get raw pointer to DER buffer from WOLFSSL_EVP_PKEY */
+static int wolfSSL_EVP_PKEY_get_der(WOLFSSL_EVP_PKEY* key, unsigned char** der)
+{
+    if (!key)
+        return WOLFSSL_FAILURE;
+    if (der)
+        *der = (unsigned char*)key->pkey.ptr;
+    return key->pkey_sz;
+}
+
+/* Copies unencrypted DER key buffer into "der". If "der" is null then the size
+ * of buffer needed is returned
+ * NOTE: This also advances the "der" pointer to be at the end of buffer.
+ *
+ * Returns size of key buffer on success
+ */
+int wolfSSL_i2d_PrivateKey(WOLFSSL_EVP_PKEY* key, unsigned char** der)
+{
+    if (key == NULL) {
+        return WOLFSSL_FATAL_ERROR;
+    }
+
+    if (key->pkey_sz <= 0 || !key->pkey.ptr) {
+        return WOLFSSL_FATAL_ERROR;
+    }
+
+    if (der != NULL) {
+        /* since this function signature has no size value passed in it is
+         * assumed that the user has allocated a large enough buffer */
+        XMEMCPY(*der, key->pkey.ptr, key->pkey_sz);
+        *der += key->pkey_sz;
+    }
+    return key->pkey_sz;
+}
+
+/* Creates a new WC_PKCS12 structure
+ *
+ * pass  password to use
+ * name  friendlyName to use
+ * pkey  private key to go into PKCS12 bundle
+ * cert  certificate to go into PKCS12 bundle
+ * ca    extra certificates that can be added to bundle. Can be NULL
+ * keyNID  type of encryption to use on the key (-1 means no encryption)
+ * certNID type of encryption to use on the certificate
+ * itt     number of iterations with encryption
+ * macItt  number of iterations with mac creation
+ * keyType flag for signature and/or encryption key
+ *
+ * returns a pointer to a new WC_PKCS12 structure on success and NULL on fail
+ */
+WC_PKCS12* wolfSSL_PKCS12_create(char* pass, char* name,
+        WOLFSSL_EVP_PKEY* pkey, WOLFSSL_X509* cert,
+        WOLF_STACK_OF(WOLFSSL_X509)* ca,
+        int keyNID, int certNID, int itt, int macItt, int keyType)
+{
+    WC_PKCS12*      pkcs12;
+    WC_DerCertList* list = NULL;
+    word32 passSz;
+    byte* keyDer;
+    word32 keyDerSz;
+    byte* certDer;
+    int certDerSz;
+
+    int ret;
+
+    WOLFSSL_ENTER("wolfSSL_PKCS12_create()");
+
+    if (pass == NULL || pkey == NULL || cert == NULL) {
+        WOLFSSL_LEAVE("wolfSSL_PKCS12_create()", BAD_FUNC_ARG);
+        return NULL;
+    }
+    passSz = (word32)XSTRLEN(pass);
+
+    if ((ret = wolfSSL_EVP_PKEY_get_der(pkey, &keyDer)) < 0) {
+        WOLFSSL_LEAVE("wolfSSL_PKCS12_create", ret);
+        return NULL;
+    }
+    keyDerSz = ret;
+
+    certDer = (byte*)wolfSSL_X509_get_der(cert, &certDerSz);
+    if (certDer == NULL) {
+        return NULL;
+    }
+
+    if (ca != NULL) {
+        WC_DerCertList* cur;
+        unsigned long numCerts = ca->num;
+        byte* curDer;
+        int   curDerSz = 0;
+        WOLFSSL_STACK* sk = ca;
+
+        while (numCerts > 0 && sk != NULL) {
+            cur = (WC_DerCertList*)XMALLOC(sizeof(WC_DerCertList), NULL,
+                    DYNAMIC_TYPE_PKCS);
+            if (cur == NULL) {
+                wc_FreeCertList(list, NULL);
+                return NULL;
+            }
+
+            curDer = (byte*)wolfSSL_X509_get_der(sk->data.x509, &curDerSz);
+            if (curDer == NULL || curDerSz < 0) {
+                XFREE(cur, NULL, DYNAMIC_TYPE_PKCS);
+                wc_FreeCertList(list, NULL);
+                return NULL;
+            }
+
+            cur->buffer = (byte*)XMALLOC(curDerSz, NULL, DYNAMIC_TYPE_PKCS);
+            if (cur->buffer == NULL) {
+                XFREE(cur, NULL, DYNAMIC_TYPE_PKCS);
+                wc_FreeCertList(list, NULL);
+                return NULL;
+            }
+            XMEMCPY(cur->buffer, curDer, curDerSz);
+            cur->bufferSz = curDerSz;
+            cur->next = list;
+            list = cur;
+
+            sk = sk->next;
+            numCerts--;
+        }
+    }
+
+    pkcs12 = wc_PKCS12_create(pass, passSz, name, keyDer, keyDerSz,
+            certDer, certDerSz, list, keyNID, certNID, itt, macItt,
+            keyType, NULL);
+
+    if (ca != NULL) {
+        wc_FreeCertList(list, NULL);
+    }
+
+    return pkcs12;
+}
+
+
+/* return WOLFSSL_SUCCESS on success, WOLFSSL_FAILURE on failure */
+int wolfSSL_PKCS12_parse(WC_PKCS12* pkcs12, const char* psw,
+      WOLFSSL_EVP_PKEY** pkey, WOLFSSL_X509** cert, WOLF_STACK_OF(WOLFSSL_X509)** ca)
+{
+    DecodedCert DeCert;
+    void* heap = NULL;
+    int ret;
+    byte* certData = NULL;
+    word32 certDataSz;
+    byte* pk = NULL;
+    word32 pkSz;
+    WC_DerCertList* certList = NULL;
+
+    WOLFSSL_ENTER("wolfSSL_PKCS12_parse");
+
+    /* make sure we init return args */
+    if (pkey) *pkey = NULL;
+    if (cert) *cert = NULL;
+    if (ca)   *ca = NULL;
+
+    if (pkcs12 == NULL || psw == NULL || pkey == NULL || cert == NULL) {
+        WOLFSSL_MSG("Bad argument value");
+        return WOLFSSL_FAILURE;
+    }
+
+    heap  = wc_PKCS12_GetHeap(pkcs12);
+
+    if (ca == NULL) {
+        ret = wc_PKCS12_parse(pkcs12, psw, &pk, &pkSz, &certData, &certDataSz,
+            NULL);
+    }
+    else {
+        ret = wc_PKCS12_parse(pkcs12, psw, &pk, &pkSz, &certData, &certDataSz,
+            &certList);
+    }
+    if (ret < 0) {
+        WOLFSSL_LEAVE("wolfSSL_PKCS12_parse", ret);
+        return WOLFSSL_FAILURE;
+    }
+
+    /* Decode cert and place in X509 stack struct */
+    if (certList != NULL) {
+        WC_DerCertList* current = certList;
+
+        *ca = (WOLF_STACK_OF(WOLFSSL_X509)*)XMALLOC(sizeof(WOLF_STACK_OF(WOLFSSL_X509)),
+                                               heap, DYNAMIC_TYPE_X509);
+        if (*ca == NULL) {
+            if (pk != NULL) {
+                XFREE(pk, heap, DYNAMIC_TYPE_PUBLIC_KEY);
+            }
+            if (certData != NULL) {
+                XFREE(*cert, heap, DYNAMIC_TYPE_PKCS); *cert = NULL;
+            }
+            /* Free up WC_DerCertList and move on */
+            while (current != NULL) {
+                WC_DerCertList* next = current->next;
+
+                XFREE(current->buffer, heap, DYNAMIC_TYPE_PKCS);
+                XFREE(current, heap, DYNAMIC_TYPE_PKCS);
+                current = next;
+            }
+            return WOLFSSL_FAILURE;
+        }
+        XMEMSET(*ca, 0, sizeof(WOLF_STACK_OF(WOLFSSL_X509)));
+
+        /* add list of DER certs as X509's to stack */
+        while (current != NULL) {
+            WC_DerCertList*  toFree = current;
+            WOLFSSL_X509* x509;
+
+            x509 = (WOLFSSL_X509*)XMALLOC(sizeof(WOLFSSL_X509), heap,
+                                                             DYNAMIC_TYPE_X509);
+            InitX509(x509, 1, heap);
+            InitDecodedCert(&DeCert, current->buffer, current->bufferSz, heap);
+            if (ParseCertRelative(&DeCert, CERT_TYPE, NO_VERIFY, NULL) != 0) {
+                WOLFSSL_MSG("Issue with parsing certificate");
+                FreeDecodedCert(&DeCert);
+                wolfSSL_X509_free(x509);
+            }
+            else {
+                if ((ret = CopyDecodedToX509(x509, &DeCert)) != 0) {
+                    WOLFSSL_MSG("Failed to copy decoded cert");
+                    FreeDecodedCert(&DeCert);
+                    wolfSSL_X509_free(x509);
+                    wolfSSL_sk_X509_free(*ca); *ca = NULL;
+                    if (pk != NULL) {
+                        XFREE(pk, heap, DYNAMIC_TYPE_PUBLIC_KEY);
+                    }
+                    if (certData != NULL) {
+                        XFREE(certData, heap, DYNAMIC_TYPE_PKCS);
+                    }
+                    /* Free up WC_DerCertList */
+                    while (current != NULL) {
+                        WC_DerCertList* next = current->next;
+
+                        XFREE(current->buffer, heap, DYNAMIC_TYPE_PKCS);
+                        XFREE(current, heap, DYNAMIC_TYPE_PKCS);
+                        current = next;
+                    }
+                    return WOLFSSL_FAILURE;
+                }
+                FreeDecodedCert(&DeCert);
+
+                if (wolfSSL_sk_X509_push(*ca, x509) != 1) {
+                    WOLFSSL_MSG("Failed to push x509 onto stack");
+                    wolfSSL_X509_free(x509);
+                    wolfSSL_sk_X509_free(*ca); *ca = NULL;
+                    if (pk != NULL) {
+                        XFREE(pk, heap, DYNAMIC_TYPE_PUBLIC_KEY);
+                    }
+                    if (certData != NULL) {
+                        XFREE(certData, heap, DYNAMIC_TYPE_PKCS);
+                    }
+
+                    /* Free up WC_DerCertList */
+                    while (current != NULL) {
+                        WC_DerCertList* next = current->next;
+
+                        XFREE(current->buffer, heap, DYNAMIC_TYPE_PKCS);
+                        XFREE(current, heap, DYNAMIC_TYPE_PKCS);
+                        current = next;
+                    }
+                    return WOLFSSL_FAILURE;
+                }
+            }
+            current = current->next;
+            XFREE(toFree->buffer, heap, DYNAMIC_TYPE_PKCS);
+            XFREE(toFree, heap, DYNAMIC_TYPE_PKCS);
+        }
+    }
+
+
+    /* Decode cert and place in X509 struct */
+    if (certData != NULL) {
+        *cert = (WOLFSSL_X509*)XMALLOC(sizeof(WOLFSSL_X509), heap,
+                                                             DYNAMIC_TYPE_X509);
+        if (*cert == NULL) {
+            if (pk != NULL) {
+                XFREE(pk, heap, DYNAMIC_TYPE_PUBLIC_KEY);
+            }
+            if (ca != NULL) {
+                wolfSSL_sk_X509_free(*ca); *ca = NULL;
+            }
+            XFREE(certData, heap, DYNAMIC_TYPE_PKCS);
+            return WOLFSSL_FAILURE;
+        }
+        InitX509(*cert, 1, heap);
+        InitDecodedCert(&DeCert, certData, certDataSz, heap);
+        if (ParseCertRelative(&DeCert, CERT_TYPE, NO_VERIFY, NULL) != 0) {
+            WOLFSSL_MSG("Issue with parsing certificate");
+        }
+        if ((ret = CopyDecodedToX509(*cert, &DeCert)) != 0) {
+            WOLFSSL_MSG("Failed to copy decoded cert");
+            FreeDecodedCert(&DeCert);
+            if (pk != NULL) {
+                XFREE(pk, heap, DYNAMIC_TYPE_PUBLIC_KEY);
+            }
+            if (ca != NULL) {
+                wolfSSL_sk_X509_free(*ca); *ca = NULL;
+            }
+            wolfSSL_X509_free(*cert); *cert = NULL;
+            return WOLFSSL_FAILURE;
+        }
+        FreeDecodedCert(&DeCert);
+        XFREE(certData, heap, DYNAMIC_TYPE_PKCS);
+    }
+
+
+    /* get key type */
+    ret = BAD_STATE_E;
+    if (pk != NULL) { /* decode key if present */
+        *pkey = wolfSSL_EVP_PKEY_new_ex(heap);
+        if (*pkey == NULL) {
+            wolfSSL_X509_free(*cert); *cert = NULL;
+            if (ca != NULL) {
+                wolfSSL_sk_X509_free(*ca); *ca = NULL;
+            }
+            XFREE(pk, heap, DYNAMIC_TYPE_PUBLIC_KEY);
+            return WOLFSSL_FAILURE;
+        }
+        #ifndef NO_RSA
+        {
+            word32 keyIdx = 0;
+            RsaKey key;
+
+            if (wc_InitRsaKey(&key, heap) != 0) {
+                ret = BAD_STATE_E;
+            }
+            else {
+                if ((ret = wc_RsaPrivateKeyDecode(pk, &keyIdx, &key, pkSz))
+                                                                         == 0) {
+                    (*pkey)->type = EVP_PKEY_RSA;
+                    (*pkey)->rsa  = wolfSSL_RSA_new();
+                    (*pkey)->ownRsa = 1; /* we own RSA */
+                    if ((*pkey)->rsa == NULL) {
+                        WOLFSSL_MSG("issue creating EVP RSA key");
+                        wolfSSL_X509_free(*cert); *cert = NULL;
+                        if (ca != NULL) {
+                            wolfSSL_sk_X509_free(*ca); *ca = NULL;
+                        }
+                        wolfSSL_EVP_PKEY_free(*pkey); *pkey = NULL;
+                        XFREE(pk, heap, DYNAMIC_TYPE_PKCS);
+                        return WOLFSSL_FAILURE;
+                    }
+                    if ((ret = wolfSSL_RSA_LoadDer_ex((*pkey)->rsa, pk, pkSz,
+                                    WOLFSSL_RSA_LOAD_PRIVATE)) != SSL_SUCCESS) {
+                        WOLFSSL_MSG("issue loading RSA key");
+                        wolfSSL_X509_free(*cert); *cert = NULL;
+                        if (ca != NULL) {
+                            wolfSSL_sk_X509_free(*ca); *ca = NULL;
+                        }
+                        wolfSSL_EVP_PKEY_free(*pkey); *pkey = NULL;
+                        XFREE(pk, heap, DYNAMIC_TYPE_PKCS);
+                        return WOLFSSL_FAILURE;
+                    }
+
+                    WOLFSSL_MSG("Found PKCS12 RSA key");
+                    ret = 0; /* set in success state for upcoming ECC check */
+                }
+                wc_FreeRsaKey(&key);
+            }
+        }
+        #endif /* NO_RSA */
+
+        #ifdef HAVE_ECC
+        {
+            word32  keyIdx = 0;
+            ecc_key key;
+
+            if (ret != 0) { /* if is in fail state check if ECC key */
+                if (wc_ecc_init(&key) != 0) {
+                    wolfSSL_X509_free(*cert); *cert = NULL;
+                    if (ca != NULL) {
+                        wolfSSL_sk_X509_free(*ca); *ca = NULL;
+                    }
+                    wolfSSL_EVP_PKEY_free(*pkey); *pkey = NULL;
+                    XFREE(pk, heap, DYNAMIC_TYPE_PKCS);
+                    return WOLFSSL_FAILURE;
+                }
+
+                if ((ret = wc_EccPrivateKeyDecode(pk, &keyIdx, &key, pkSz))
+                                                                         != 0) {
+                    wolfSSL_X509_free(*cert); *cert = NULL;
+                    if (ca != NULL) {
+                        wolfSSL_sk_X509_free(*ca); *ca = NULL;
+                    }
+                    wolfSSL_EVP_PKEY_free(*pkey); *pkey = NULL;
+                    XFREE(pk, heap, DYNAMIC_TYPE_PKCS);
+                    WOLFSSL_MSG("Bad PKCS12 key format");
+                    return WOLFSSL_FAILURE;
+                }
+                (*pkey)->type = EVP_PKEY_EC;
+                (*pkey)->pkey_curve = key.dp->oidSum;
+                wc_ecc_free(&key);
+                WOLFSSL_MSG("Found PKCS12 ECC key");
+            }
+        }
+        #else
+        if (ret != 0) { /* if is in fail state and no ECC then fail */
+            wolfSSL_X509_free(*cert); *cert = NULL;
+            if (ca != NULL) {
+                wolfSSL_sk_X509_free(*ca); *ca = NULL;
+            }
+            wolfSSL_EVP_PKEY_free(*pkey); *pkey = NULL;
+            XFREE(pk, heap, DYNAMIC_TYPE_PKCS);
+            WOLFSSL_MSG("Bad PKCS12 key format");
+            return WOLFSSL_FAILURE;
+        }
+        #endif /* HAVE_ECC */
+
+        (*pkey)->save_type = 0;
+        (*pkey)->pkey_sz   = pkSz;
+        (*pkey)->pkey.ptr  = (char*)pk;
+    }
+
+    (void)ret;
+    (void)ca;
+
+    return WOLFSSL_SUCCESS;
+}
+#endif /* !defined(NO_ASN) && !defined(NO_PWDBASED) */
+
+
+/* no-op function. Was initially used for adding encryption algorithms available
+ * for PKCS12 */
+void wolfSSL_PKCS12_PBE_add(void)
+{
+    WOLFSSL_ENTER("wolfSSL_PKCS12_PBE_add");
+}
+
+
+
+WOLFSSL_STACK* wolfSSL_X509_STORE_CTX_get_chain(WOLFSSL_X509_STORE_CTX* ctx)
+{
+    WOLFSSL_ENTER("wolfSSL_X509_STORE_CTX_get_chain");
+
+    if (ctx == NULL) {
+        return NULL;
+    }
+
+#ifdef SESSION_CERTS
+    /* if chain is null but sesChain is available then populate stack */
+    if (ctx->chain == NULL && ctx->sesChain != NULL) {
+        int i;
+        WOLFSSL_X509_CHAIN* c = ctx->sesChain;
+        WOLFSSL_STACK*     sk = (WOLFSSL_STACK*)XMALLOC(sizeof(WOLFSSL_STACK),
+                                    NULL, DYNAMIC_TYPE_X509);
+
+        if (sk == NULL) {
+            return NULL;
+        }
+
+        XMEMSET(sk, 0, sizeof(WOLFSSL_STACK));
+        ctx->chain = sk;
+
+        for (i = 0; i < c->count && i < MAX_CHAIN_DEPTH; i++) {
+            WOLFSSL_X509* x509 = wolfSSL_get_chain_X509(c, i);
+
+            if (x509 == NULL) {
+                WOLFSSL_MSG("Unable to get x509 from chain");
+                wolfSSL_sk_X509_free(sk);
+                return NULL;
+            }
+
+            if (wolfSSL_sk_X509_push(sk, x509) != SSL_SUCCESS) {
+                WOLFSSL_MSG("Unable to load x509 into stack");
+                wolfSSL_sk_X509_free(sk);
+                wolfSSL_X509_free(x509);
+                return NULL;
+            }
+        }
+
+#if defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY) || defined(OPENSSL_EXTRA)
+        /* add CA used to verify top of chain to the list */
+        if (c->count > 0) {
+            WOLFSSL_X509* x509 = wolfSSL_get_chain_X509(c, c->count - 1);
+            if (x509 != NULL) {
+                WOLFSSL_X509* issuer = NULL;
+                if (wolfSSL_X509_STORE_CTX_get1_issuer(&issuer, ctx, x509)
+                        == WOLFSSL_SUCCESS) {
+                    /* check that the certificate being looked up is not self
+                     * signed and that a issuer was found */
+                    if (issuer != NULL && wolfSSL_X509_NAME_cmp(&x509->issuer,
+                                &x509->subject) != 0) {
+                        if (wolfSSL_sk_X509_push(sk, issuer) != SSL_SUCCESS) {
+                            WOLFSSL_MSG("Unable to load CA x509 into stack");
+                            wolfSSL_sk_X509_free(sk);
+                            wolfSSL_X509_free(issuer);
+                            return NULL;
+                        }
+                    }
+                    else {
+                        WOLFSSL_MSG("Certificate is self signed");
+                        if (issuer != NULL)
+                            wolfSSL_X509_free(issuer);
+                    }
+                }
+                else {
+                    WOLFSSL_MSG("Could not find CA for certificate");
+                }
+            }
+        }
+#endif
+
+    }
+#endif /* SESSION_CERTS */
+
+    return ctx->chain;
+}
+
+/* make shallow copy of the stack, data pointers are copied by reference */
+WOLFSSL_STACK* wolfSSL_sk_X509_dup(WOLFSSL_STACK* sk)
+{
+    unsigned long i;
+    WOLFSSL_STACK* dup = NULL;
+    WOLFSSL_STACK* node = NULL;
+    WOLFSSL_STACK *dIdx = NULL, *sIdx = sk;
+
+    if (sk == NULL) {
+        return NULL;
+    }
+
+    for (i = 0; i < sk->num; i++) {
+
+        node = (WOLFSSL_STACK*)XMALLOC(sizeof(WOLFSSL_STACK), NULL,
+                                         DYNAMIC_TYPE_X509);
+        if (node == NULL) {
+            if (i != 0) {
+                wolfSSL_sk_free(dup);
+            }
+            WOLFSSL_MSG("Memory error");
+            return NULL;
+        }
+        XMEMSET(node, 0, sizeof(WOLFSSL_STACK));
+
+        /* copy sk node to new node, data by reference */
+        node->data.x509 = sIdx->data.x509;
+        node->num = sIdx->num;
+
+        /* insert node into list, progress idx */
+        if (i == 0) {
+            dup = node;
+        } else {
+            dIdx->next = node;
+        }
+
+        dIdx = node;
+        sIdx = sIdx->next;
+    }
+
+    return dup;
+}
+
+
+/* like X509_STORE_CTX_get_chain(), but return a copy with data reference
+   counts increased */
+WOLFSSL_STACK* wolfSSL_X509_STORE_CTX_get1_chain(WOLFSSL_X509_STORE_CTX* ctx)
+{
+    unsigned long i;
+    WOLFSSL_STACK* ref;
+    WOLFSSL_STACK* dup;
+
+    if (ctx == NULL) {
+        return NULL;
+    }
+
+    /* get chain in ctx */
+    ref = wolfSSL_X509_STORE_CTX_get_chain(ctx);
+    if (ref == NULL) {
+        return ref;
+    }
+
+    /* create duplicate of ctx chain */
+    dup = wolfSSL_sk_X509_dup(ref);
+    if (dup == NULL) {
+        return NULL;
+    }
+
+    /* increase ref counts of inner data X509 */
+    ref = dup;
+    for (i = 0; i < dup->num && ref != NULL; i++) {
+        if (wc_LockMutex(&ref->data.x509->refMutex) != 0) {
+            WOLFSSL_MSG("Failed to lock x509 mutex");
+        }
+        ref->data.x509->refCount++;
+        wc_UnLockMutex(&ref->data.x509->refMutex);
+        ref = ref->next;
+    }
+
+    return dup;
+}
+
+
+int wolfSSL_X509_STORE_add_cert(WOLFSSL_X509_STORE* store, WOLFSSL_X509* x509)
+{
+    int result = WOLFSSL_FATAL_ERROR;
+
+    WOLFSSL_ENTER("wolfSSL_X509_STORE_add_cert");
+    if (store != NULL && store->cm != NULL && x509 != NULL
+                                                && x509->derCert != NULL) {
+        DerBuffer* derCert = NULL;
+
+        result = AllocDer(&derCert, x509->derCert->length,
+            x509->derCert->type, NULL);
+        if (result == 0) {
+            /* AddCA() frees the buffer. */
+            XMEMCPY(derCert->buffer,
+                            x509->derCert->buffer, x509->derCert->length);
+            result = AddCA(store->cm, &derCert, WOLFSSL_USER_CA, VERIFY);
+        }
+    }
+
+    WOLFSSL_LEAVE("wolfSSL_X509_STORE_add_cert", result);
+
+    if (result != WOLFSSL_SUCCESS) {
+        result = WOLFSSL_FATAL_ERROR;
+    }
+
+    return result;
+}
+
+WOLFSSL_X509_STORE* wolfSSL_X509_STORE_new(void)
+{
+    WOLFSSL_X509_STORE* store = NULL;
+    WOLFSSL_ENTER("SSL_X509_STORE_new");
+
+    if ((store = (WOLFSSL_X509_STORE*)XMALLOC(sizeof(WOLFSSL_X509_STORE), NULL,
+                                    DYNAMIC_TYPE_X509_STORE)) == NULL)
+        goto err_exit;
+
+    XMEMSET(store, 0, sizeof(WOLFSSL_X509_STORE));
+    store->isDynamic = 1;
+
+    if ((store->cm = wolfSSL_CertManagerNew()) == NULL)
+        goto err_exit;
+
+#ifdef HAVE_CRL
+    store->crl = NULL;
+    if ((store->crl = (WOLFSSL_X509_CRL *)XMALLOC(sizeof(WOLFSSL_X509_CRL),
+                                        NULL, DYNAMIC_TYPE_TMP_BUFFER)) == NULL)
+        goto err_exit;
+    if (InitCRL(store->crl, NULL) < 0)
+        goto err_exit;
+#endif
+
+#ifdef OPENSSL_EXTRA
+    if ((store->param = (WOLFSSL_X509_VERIFY_PARAM*)XMALLOC(
+                           sizeof(WOLFSSL_X509_VERIFY_PARAM),
+                           NULL,DYNAMIC_TYPE_OPENSSL)) == NULL)
+        goto err_exit;
+
+#endif
+
+    return store;
+
+err_exit:
+    if (store == NULL)
+        return NULL;
+
+    wolfSSL_X509_STORE_free(store);
+
+    return NULL;
+}
+
+
+void wolfSSL_X509_STORE_free(WOLFSSL_X509_STORE* store)
+{
+    if (store != NULL && store->isDynamic) {
+        if (store->cm != NULL)
+            wolfSSL_CertManagerFree(store->cm);
+#ifdef HAVE_CRL
+        if (store->crl != NULL)
+            wolfSSL_X509_CRL_free(store->crl);
+#endif
+#ifdef OPENSSL_EXTRA
+        if (store->param != NULL)
+            XFREE(store->param, NULL, DYNAMIC_TYPE_OPENSSL);
+#endif
+        XFREE(store, NULL, DYNAMIC_TYPE_X509_STORE);
+    }
+}
+
+
+int wolfSSL_X509_STORE_set_flags(WOLFSSL_X509_STORE* store, unsigned long flag)
+{
+    int ret = WOLFSSL_SUCCESS;
+
+    WOLFSSL_ENTER("wolfSSL_X509_STORE_set_flags");
+
+    if (store == NULL)
+        return WOLFSSL_FAILURE;
+
+    if ((flag & WOLFSSL_CRL_CHECKALL) || (flag & WOLFSSL_CRL_CHECK)) {
+        ret = wolfSSL_CertManagerEnableCRL(store->cm, (int)flag);
+    }
+
+    (void)store;
+    (void)flag;
+
+    return ret;
+}
+
+
+int wolfSSL_X509_STORE_set_default_paths(WOLFSSL_X509_STORE* store)
+{
+    (void)store;
+    return WOLFSSL_SUCCESS;
+}
+
+#ifndef NO_WOLFSSL_STUB
+int wolfSSL_X509_STORE_get_by_subject(WOLFSSL_X509_STORE_CTX* ctx, int idx,
+                            WOLFSSL_X509_NAME* name, WOLFSSL_X509_OBJECT* obj)
+{
+    (void)ctx;
+    (void)idx;
+    (void)name;
+    (void)obj;
+    WOLFSSL_STUB("X509_STORE_get_by_subject");
+    return 0;
+}
+#endif
+
+WOLFSSL_X509_STORE_CTX* wolfSSL_X509_STORE_CTX_new(void)
+{
+    WOLFSSL_X509_STORE_CTX* ctx;
+    WOLFSSL_ENTER("X509_STORE_CTX_new");
+
+    ctx = (WOLFSSL_X509_STORE_CTX*)XMALLOC(sizeof(WOLFSSL_X509_STORE_CTX), NULL,
+                                    DYNAMIC_TYPE_X509_CTX);
+    if (ctx != NULL) {
+        ctx->param = NULL;
+        wolfSSL_X509_STORE_CTX_init(ctx, NULL, NULL, NULL);
+    }
+
+    return ctx;
+}
+
+
+int wolfSSL_X509_STORE_CTX_init(WOLFSSL_X509_STORE_CTX* ctx,
+     WOLFSSL_X509_STORE* store, WOLFSSL_X509* x509, WOLF_STACK_OF(WOLFSSL_X509)* sk)
+{
+    WOLFSSL_X509* x509_cert;
+    int ret = 0;
+    (void)sk;
+    WOLFSSL_ENTER("wolfSSL_X509_STORE_CTX_init");
+
+    if (ctx != NULL) {
+        ctx->store = store;
+        #ifndef WOLFSSL_X509_STORE_CERTS
+        ctx->current_cert = x509;
+        #else
+        if(x509 != NULL){
+            ctx->current_cert = wolfSSL_X509_d2i(NULL, x509->derCert->buffer,x509->derCert->length);
+            if(ctx->current_cert == NULL)
+                return WOLFSSL_FATAL_ERROR;
+        } else
+            ctx->current_cert = NULL;
+        #endif
+
+        ctx->chain  = sk;
+        /* Add intermediate certificates from stack to store */
+        while (sk != NULL) {
+            x509_cert = sk->data.x509;
+            if (x509_cert != NULL && x509_cert->isCa) {
+                ret = wolfSSL_X509_STORE_add_cert(store, x509_cert);
+                if (ret < 0) {
+                    return WOLFSSL_FATAL_ERROR;
+                }
+            }
+            sk = sk->next;
+        }
+
+        ctx->sesChain = NULL;
+        ctx->domain = NULL;
+#if defined(HAVE_EX_DATA) || defined(FORTRESS)
+        XMEMSET(&ctx->ex_data, 0, sizeof(ctx->ex_data));
+#endif
+        ctx->userCtx = NULL;
+        ctx->error = 0;
+        ctx->error_depth = 0;
+        ctx->discardSessionCerts = 0;
+#ifdef OPENSSL_EXTRA
+        if (ctx->param == NULL) {
+            ctx->param = (WOLFSSL_X509_VERIFY_PARAM*)XMALLOC(
+                           sizeof(WOLFSSL_X509_VERIFY_PARAM),
+                           NULL,DYNAMIC_TYPE_OPENSSL);
+            if (ctx->param == NULL){
+                WOLFSSL_MSG("wolfSSL_X509_STORE_CTX_init failed");
+                return SSL_FATAL_ERROR;
+            }
+        }
+#endif
+        return SSL_SUCCESS;
+    }
+    return WOLFSSL_FATAL_ERROR;
+}
+
+
+void wolfSSL_X509_STORE_CTX_free(WOLFSSL_X509_STORE_CTX* ctx)
+{
+    WOLFSSL_ENTER("X509_STORE_CTX_free");
+    if (ctx != NULL) {
+    #if !defined(OPENSSL_ALL) && !defined(WOLFSSL_QT)
+        if (ctx->store != NULL)
+            wolfSSL_X509_STORE_free(ctx->store);
+        #ifndef WOLFSSL_KEEP_STORE_CERTS
+        if (ctx->current_cert != NULL)
+            wolfSSL_FreeX509(ctx->current_cert);
+        #endif
+    #endif /* !OPENSSL_ALL && !WOLFSSL_QT */
+#ifdef OPENSSL_EXTRA
+        if (ctx->param != NULL){
+            XFREE(ctx->param,NULL,DYNAMIC_TYPE_OPENSSL);
+        }
+#endif
+        XFREE(ctx, NULL, DYNAMIC_TYPE_X509_CTX);
+    }
+}
+
+
+void wolfSSL_X509_STORE_CTX_cleanup(WOLFSSL_X509_STORE_CTX* ctx)
+{
+    (void)ctx;
+    /* Do nothing */
+}
+
+#if defined(OPENSSL_ALL) || defined(WOLFSSL_QT)
+/* Returns corresponding X509 error from internal ASN error <e> */
+static int GetX509Error(int e)
+{
+    switch (e) {
+        case ASN_BEFORE_DATE_E:
+            return X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD;
+        case ASN_AFTER_DATE_E:
+            return X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD;
+        case ASN_NO_SIGNER_E:
+            return X509_V_ERR_INVALID_CA;
+        case ASN_SELF_SIGNED_E:
+            return X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT;
+        case ASN_PATHLEN_INV_E:
+        case ASN_PATHLEN_SIZE_E:
+            return X509_V_ERR_PATH_LENGTH_EXCEEDED;
+        case ASN_SIG_OID_E:
+        case ASN_SIG_CONFIRM_E:
+        case ASN_SIG_HASH_E:
+        case ASN_SIG_KEY_E:
+            return X509_V_ERR_CERT_SIGNATURE_FAILURE;
+        default:
+            WOLFSSL_MSG("Error not configured or implemented yet");
+            return e;
+    }
+}
+#endif
+
+/* Verifies certificate chain using WOLFSSL_X509_STORE_CTX
+ * returns 0 on success or < 0 on failure.
+ */
+int wolfSSL_X509_verify_cert(WOLFSSL_X509_STORE_CTX* ctx)
+{
+    int ret = 0;
+#if defined(OPENSSL_ALL) || defined(WOLFSSL_QT)
+    int depth = 0;
+    int error;
+    byte *afterDate, *beforeDate;
+#endif
+    WOLFSSL_ENTER("wolfSSL_X509_verify_cert");
+
+    if (ctx != NULL && ctx->store != NULL && ctx->store->cm != NULL
+         && ctx->current_cert != NULL && ctx->current_cert->derCert != NULL) {
+            ret = wolfSSL_CertManagerVerifyBuffer(ctx->store->cm,
+                    ctx->current_cert->derCert->buffer,
+                    ctx->current_cert->derCert->length,
+                    WOLFSSL_FILETYPE_ASN1);
+
+#if defined(OPENSSL_ALL) || defined(WOLFSSL_QT)
+        /* If there was an error, process it and add it to CTX */
+        if (ret < 0) {
+            /* Get corresponding X509 error */
+            error = GetX509Error(ret);
+            /* Set error depth */
+            if (ctx->chain)
+                depth = (int)ctx->chain->num;
+
+            wolfSSL_X509_STORE_CTX_set_error(ctx, error);
+            wolfSSL_X509_STORE_CTX_set_error_depth(ctx, depth);
+            ctx->store->verify_cb(0, ctx);
+        }
+
+        error = 0;
+        /* wolfSSL_CertManagerVerifyBuffer only returns ASN_AFTER_DATE_E or
+         ASN_BEFORE_DATE_E if there are no additional errors found in the
+         cert. Therefore, check if the cert is expired or not yet valid
+         in order to return the correct expected error. */
+        afterDate = ctx->current_cert->notAfter.data;
+        beforeDate = ctx->current_cert->notBefore.data;
+
+        if (ValidateDate(afterDate, ctx->current_cert->notAfter.type,
+                                                                   AFTER) < 1) {
+            error = X509_V_ERR_CERT_HAS_EXPIRED;
+        }
+        else if (ValidateDate(beforeDate, ctx->current_cert->notBefore.type,
+                                                                  BEFORE) < 1) {
+            error = X509_V_ERR_CERT_NOT_YET_VALID;
+        }
+
+        if (error != 0 ) {
+            wolfSSL_X509_STORE_CTX_set_error(ctx, error);
+            wolfSSL_X509_STORE_CTX_set_error_depth(ctx, depth);
+            if (ctx->store && ctx->store->verify_cb)
+                ctx->store->verify_cb(0, ctx);
+        }
+#endif /* OPENSSL_ALL || WOLFSSL_QT */
+        return ret;
+    }
+    return WOLFSSL_FATAL_ERROR;
+}
+
+
+/* Use the public key to verify the signature. Note: this only verifies
+ * the certificate signature.
+ * returns WOLFSSL_SUCCESS on successful signature verification */
+int wolfSSL_X509_verify(WOLFSSL_X509* x509, WOLFSSL_EVP_PKEY* pkey)
+{
+    int ret;
+    const byte* der;
+    int derSz = 0;
+    int type;
+
+    if (x509 == NULL || pkey == NULL) {
+        return WOLFSSL_FATAL_ERROR;
+    }
+
+    der = wolfSSL_X509_get_der(x509, &derSz);
+    if (der == NULL) {
+        WOLFSSL_MSG("Error getting WOLFSSL_X509 DER");
+        return WOLFSSL_FATAL_ERROR;
+    }
+
+    switch (pkey->type) {
+        case EVP_PKEY_RSA:
+            type = RSAk;
+            break;
+
+        case EVP_PKEY_EC:
+            type = ECDSAk;
+            break;
+
+        case EVP_PKEY_DSA:
+            type = DSAk;
+            break;
+
+        default:
+            WOLFSSL_MSG("Unknown pkey key type");
+            return WOLFSSL_FATAL_ERROR;
+    }
+
+    ret = CheckCertSignaturePubKey(der, derSz, x509->heap,
+            (unsigned char*)pkey->pkey.ptr, pkey->pkey_sz, type);
+    if (ret == 0) {
+        return WOLFSSL_SUCCESS;
+    }
+    return WOLFSSL_FAILURE;
+}
+#endif /* NO_CERTS */
+
+#if !defined(NO_FILESYSTEM)
+static void *wolfSSL_d2i_X509_fp_ex(XFILE file, void **x509, int type)
+{
+    void *newx509 = NULL;
+    byte *fileBuffer = NULL;
+    long sz = 0;
+
+    /* init variable */
+    if (x509)
+        *x509 = NULL;
+
+    /* argument check */
+    if (file == XBADFILE) {
+        return NULL;
+    }
+
+    /* determine file size */
+    if (XFSEEK(file, 0, XSEEK_END) != 0) {
+        return NULL;
+    }
+    sz = XFTELL(file);
+    XREWIND(file);
+
+    if (sz > MAX_WOLFSSL_FILE_SIZE || sz <= 0) {
+        WOLFSSL_MSG("d2i_X509_fp_ex file size error");
+        return NULL;
+    }
+
+    fileBuffer = (byte *)XMALLOC(sz, NULL, DYNAMIC_TYPE_FILE);
+    if (fileBuffer != NULL) {
+        if ((long)XFREAD(fileBuffer, 1, sz, file) != sz) {
+            WOLFSSL_MSG("File read failed");
+            goto err_exit;
+        }
+        if (type == CERT_TYPE) {
+            newx509 = (void *)wolfSSL_X509_d2i(NULL, fileBuffer, (int)sz);
+        }
+    #ifdef HAVE_CRL
+        else if (type == CRL_TYPE) {
+            newx509 = (void *)wolfSSL_d2i_X509_CRL(NULL, fileBuffer, (int)sz);
+        }
+    #endif
+    #if !defined(NO_ASN) && !defined(NO_PWDBASED)
+        else if (type == PKCS12_TYPE) {
+            if ((newx509 = wc_PKCS12_new()) == NULL) {
+                goto err_exit;
+            }
+            if (wc_d2i_PKCS12(fileBuffer, (int)sz, (WC_PKCS12*)newx509) < 0) {
+                goto err_exit;
+            }
+        }
+    #endif
+        else {
+            goto err_exit;
+        }
+        if (newx509 == NULL) {
+            WOLFSSL_MSG("X509 failed");
+            goto err_exit;
+        }
+    }
+
+    if (x509)
+        *x509 = newx509;
+
+    goto _exit;
+
+err_exit:
+#if !defined(NO_ASN) && !defined(NO_PWDBASED)
+    if ((newx509 != NULL) && (type == PKCS12_TYPE)) {
+        wc_PKCS12_free((WC_PKCS12*)newx509);
+        newx509 = NULL;
+    }
+#endif
+_exit:
+    if (fileBuffer != NULL)
+        XFREE(fileBuffer, NULL, DYNAMIC_TYPE_FILE);
+
+    return newx509;
+}
+
+WOLFSSL_X509_PKCS12 *wolfSSL_d2i_PKCS12_fp(XFILE fp, WOLFSSL_X509_PKCS12 **pkcs12)
+{
+    WOLFSSL_ENTER("wolfSSL_d2i_PKCS12_fp");
+    return (WOLFSSL_X509_PKCS12 *)wolfSSL_d2i_X509_fp_ex(fp, (void **)pkcs12, PKCS12_TYPE);
+}
+
+WOLFSSL_X509 *wolfSSL_d2i_X509_fp(XFILE fp, WOLFSSL_X509 **x509)
+{
+    WOLFSSL_ENTER("wolfSSL_d2i_X509_fp");
+    return (WOLFSSL_X509 *)wolfSSL_d2i_X509_fp_ex(fp, (void **)x509, CERT_TYPE);
+}
+#endif /* !NO_FILESYSTEM */
+
+
+#ifdef HAVE_CRL
+#ifndef NO_FILESYSTEM
+WOLFSSL_X509_CRL *wolfSSL_d2i_X509_CRL_fp(XFILE fp, WOLFSSL_X509_CRL **crl)
+{
+    WOLFSSL_ENTER("wolfSSL_d2i_X509_CRL_fp");
+    return (WOLFSSL_X509_CRL *)wolfSSL_d2i_X509_fp_ex(fp, (void **)crl, CRL_TYPE);
+}
+#endif /* !NO_FILESYSTEM */
+
+
+WOLFSSL_X509_CRL* wolfSSL_d2i_X509_CRL(WOLFSSL_X509_CRL** crl,
+        const unsigned char* in, int len)
+{
+    WOLFSSL_X509_CRL *newcrl = NULL;
+    int ret = WOLFSSL_SUCCESS;
+
+    WOLFSSL_ENTER("wolfSSL_d2i_X509_CRL");
+
+    if (in == NULL) {
+        WOLFSSL_MSG("Bad argument value");
+    } else {
+        newcrl = (WOLFSSL_X509_CRL*)XMALLOC(sizeof(WOLFSSL_X509_CRL), NULL,
+                DYNAMIC_TYPE_TMP_BUFFER);
+        if (newcrl == NULL){
+            WOLFSSL_MSG("New CRL allocation failed");
+        } else {
+            ret = InitCRL(newcrl, NULL);
+            if (ret < 0) {
+                WOLFSSL_MSG("Init tmp CRL failed");
+            } else {
+                ret = BufferLoadCRL(newcrl, in, len, WOLFSSL_FILETYPE_ASN1,
+                    NO_VERIFY);
+                if (ret != WOLFSSL_SUCCESS) {
+                    WOLFSSL_MSG("Buffer Load CRL failed");
+                } else {
+                    if (crl) {
+                        *crl = newcrl;
+                    }
+                }
+            }
+        }
+    }
+
+    if((ret != WOLFSSL_SUCCESS) && (newcrl != NULL)) {
+        wolfSSL_X509_CRL_free(newcrl);
+        newcrl = NULL;
+    }
+
+    return newcrl;
+}
+
+void wolfSSL_X509_CRL_free(WOLFSSL_X509_CRL *crl)
+{
+    WOLFSSL_ENTER("wolfSSL_X509_CRL_free");
+
+    FreeCRL(crl, 1);
+    return;
+}
+#endif /* HAVE_CRL */
+
+#ifndef NO_WOLFSSL_STUB
+WOLFSSL_ASN1_TIME* wolfSSL_X509_CRL_get_lastUpdate(WOLFSSL_X509_CRL* crl)
+{
+    (void)crl;
+    WOLFSSL_STUB("X509_CRL_get_lastUpdate");
+    return 0;
+}
+#endif
+#ifndef NO_WOLFSSL_STUB
+WOLFSSL_ASN1_TIME* wolfSSL_X509_CRL_get_nextUpdate(WOLFSSL_X509_CRL* crl)
+{
+    (void)crl;
+    WOLFSSL_STUB("X509_CRL_get_nextUpdate");
+    return 0;
+}
+#endif
+
+
+#ifndef NO_WOLFSSL_STUB
+int wolfSSL_X509_CRL_verify(WOLFSSL_X509_CRL* crl, WOLFSSL_EVP_PKEY* key)
+{
+    (void)crl;
+    (void)key;
+    WOLFSSL_STUB("X509_CRL_verify");
+    return 0;
+}
+#endif
+#endif /* OPENSSL_EXTRA */
+
+#ifdef OPENSSL_EXTRA
+
+/* Gets pointer to X509_STORE that was used to create context.
+ *
+ * Return valid pointer on success, NULL if ctx was NULL or not initialized
+ */
+WOLFSSL_X509_STORE* wolfSSL_X509_STORE_CTX_get0_store(
+        WOLFSSL_X509_STORE_CTX* ctx)
+{
+    WOLFSSL_ENTER("wolfSSL_X509_STORE_CTX_get0_store");
+
+    if (ctx == NULL)
+        return NULL;
+
+    return ctx->store;
+}
+
+WOLFSSL_X509* wolfSSL_X509_STORE_CTX_get0_cert(WOLFSSL_X509_STORE_CTX* ctx)
+{
+    if (ctx == NULL)
+        return NULL;
+
+    return ctx->current_cert;
+}
+
+void wolfSSL_X509_STORE_CTX_set_time(WOLFSSL_X509_STORE_CTX* ctx,
+                                    unsigned long flags,
+                                    time_t t)
+{
+    (void)flags;
+
+    if (ctx == NULL || ctx->param == NULL)
+        return;
+
+    ctx->param->check_time = t;
+    ctx->param->flags |= WOLFSSL_USE_CHECK_TIME;
+}
+
+#if defined(WOLFSSL_QT) || defined(OPENSSL_ALL)
+#ifndef NO_WOLFSSL_STUB
+int wolfSSL_X509_STORE_CTX_set_purpose(WOLFSSL_X509_STORE_CTX *ctx,
+                                       int purpose)
+{
+    (void)ctx;
+    (void)purpose;
+    WOLFSSL_STUB("wolfSSL_X509_STORE_CTX_set_purpose");
+    return 0;
+}
+#endif
+#endif /* WOLFSSL_QT || OPENSSL_ALL */
+
+#ifndef NO_WOLFSSL_STUB
+/* Returns default file name and path of config file. However
+   a wolfssl.cnf file is not currently supported */
+char* wolfSSL_CONF_get1_default_config_file(void)
+{
+    WOLFSSL_ENTER("wolfSSL_CONF_get1_default_config_file");
+    WOLFSSL_STUB("CONF_get1_default_config_file");
+    return NULL;
+}
+#endif
+/******************************************************************************
+* wolfSSL_X509_VERIFY_PARAM_set1_host - sets the DNS hostname to name
+* hostnames is cleared if name is NULL or empty.
+*
+* RETURNS:
+*
+*/
+int wolfSSL_X509_VERIFY_PARAM_set1_host(WOLFSSL_X509_VERIFY_PARAM* pParam,
+                                         const char* name,
+                                         unsigned int nameSz)
+{
+    unsigned int sz = 0;
+
+    if (pParam == NULL)
+        return WOLFSSL_FAILURE;
+
+    XMEMSET(pParam->hostName, 0, WOLFSSL_HOST_NAME_MAX);
+
+    if (name == NULL)
+        return WOLFSSL_SUCCESS;
+
+    sz = (unsigned int)XSTRLEN(name);
+
+    /* If name is NUL-terminated, namelen can be set to zero. */
+    if(nameSz == 0 || nameSz > sz)
+        nameSz = sz;
+
+    if (nameSz > 0 && name[nameSz - 1] == '\0')
+        nameSz--;
+
+    if (nameSz > WOLFSSL_HOST_NAME_MAX-1)
+        nameSz = WOLFSSL_HOST_NAME_MAX-1;
+
+    if (nameSz > 0)
+        XMEMCPY(pParam->hostName, name, nameSz);
+
+        pParam->hostName[nameSz] = '\0';
+
+    return WOLFSSL_SUCCESS;
+}
+/******************************************************************************
+* wolfSSL_get0_param - return a pointer to the SSL verification parameters
+*
+* RETURNS:
+* returns pointer to the SSL verification parameters on success,
+* otherwise returns NULL
+*/
+WOLFSSL_X509_VERIFY_PARAM* wolfSSL_get0_param(WOLFSSL* ssl)
+{
+    if (ssl == NULL) {
+        return NULL;
+    }
+    return ssl->param;
+}
+
+/* Set the host flag in the X509_VERIFY_PARAM structure */
+void wolfSSL_X509_VERIFY_PARAM_set_hostflags(WOLFSSL_X509_VERIFY_PARAM* param,
+                                             unsigned int flags)
+{
+    if (param != NULL) {
+        param->hostFlags = flags;
+    }
+}
+
+/* Sets the expected IP address to ipasc.
+ *
+ * param is a pointer to the X509_VERIFY_PARAM structure
+ * ipasc is a NULL-terminated string with N.N.N.N for IPv4 and
+ *       HH:HH ... HH:HH for IPv6. There is no validation performed on the
+ *       parameter, and it must be an exact match with the IP in the cert.
+ *
+ * return 1 for success and 0 for failure*/
+int wolfSSL_X509_VERIFY_PARAM_set1_ip_asc(WOLFSSL_X509_VERIFY_PARAM *param,
+        const char *ipasc)
+{
+    int ret = WOLFSSL_FAILURE;
+
+    if (param != NULL) {
+        if (ipasc == NULL) {
+            param->ipasc[0] = '\0';
+        }
+        else {
+            XSTRNCPY(param->ipasc, ipasc, WOLFSSL_MAX_IPSTR-1);
+            param->ipasc[WOLFSSL_MAX_IPSTR-1] = '\0';
+        }
+        ret = WOLFSSL_SUCCESS;
+    }
+
+    return ret;
+}
+
+#ifndef NO_WOLFSSL_STUB
+void wolfSSL_X509_OBJECT_free_contents(WOLFSSL_X509_OBJECT* obj)
+{
+    (void)obj;
+    WOLFSSL_STUB("X509_OBJECT_free_contents");
+}
+#endif
+
+#ifndef NO_ASN_TIME
+int wolfSSL_X509_cmp_current_time(const WOLFSSL_ASN1_TIME* asnTime)
+{
+    return wolfSSL_X509_cmp_time(asnTime, NULL);
+}
+
+/* return -1 if asnTime is earlier than or equal to cmpTime, and 1 otherwise
+ * return 0 on error
+ */
+int wolfSSL_X509_cmp_time(const WOLFSSL_ASN1_TIME* asnTime, time_t* cmpTime)
+{
+    int ret = WOLFSSL_FAILURE, i = 0;
+    time_t tmpTime, *pTime = &tmpTime;
+    byte data_ptr[MAX_TIME_STRING_SZ], inv = 0;
+    struct tm ts, *tmpTs, *ct;
+#if defined(NEED_TMP_TIME)
+    /* for use with gmtime_r */
+    struct tm tmpTimeStorage;
+
+    tmpTs = &tmpTimeStorage;
+#else
+    tmpTs = NULL;
+#endif
+    (void)tmpTs;
+
+    if (asnTime == NULL) {
+        return WOLFSSL_FAILURE;
+    }
+
+    if (cmpTime == NULL) {
+        /* Use current time */
+        *pTime = XTIME(0);
+    }
+    else {
+        pTime = cmpTime;
+    }
+
+    /* Convert ASN1_time to time_t */
+    XMEMSET(&ts, 0, sizeof(struct tm));
+
+    /* Check type */
+    if (asnTime->type == ASN_UTC_TIME) {
+        /* 2-digit year */
+        XMEMCPY(data_ptr, &asnTime->data[i], ASN_UTC_TIME_SIZE);
+        ts.tm_year = (data_ptr[i] - '0') * 10; i++;
+        ts.tm_year += data_ptr[i] - '0'; i++;
+        if (ts.tm_year < 70) {
+            ts.tm_year += 100;
+        }
+    }
+    else if (asnTime->type == ASN_GENERALIZED_TIME) {
+        /* 4-digit year */
+        XMEMCPY(data_ptr, &asnTime->data[i], ASN_GENERALIZED_TIME_SIZE);
+        ts.tm_year = (data_ptr[i] - '0') * 1000; i++;
+        ts.tm_year += (data_ptr[i] - '0') * 100; i++;
+        ts.tm_year += (data_ptr[i] - '0') * 10; i++;
+        ts.tm_year += data_ptr[i] - '0'; i++;
+        ts.tm_year -= 1900;
+    }
+    else {
+        /* Invalid type */
+        inv = 1;
+    }
+
+    if (inv != 1) {
+        ts.tm_mon = (data_ptr[i] - '0') * 10; i++;
+        ts.tm_mon += (data_ptr[i] - '0') - 1; i++; /* January is 0 not 1 */
+        ts.tm_mday = (data_ptr[i] - '0') * 10; i++;
+        ts.tm_mday += (data_ptr[i] - '0'); i++;
+        ts.tm_hour = (data_ptr[i] - '0') * 10; i++;
+        ts.tm_hour += (data_ptr[i] - '0'); i++;
+        ts.tm_min = (data_ptr[i] - '0') * 10; i++;
+        ts.tm_min += (data_ptr[i] - '0'); i++;
+        ts.tm_sec = (data_ptr[i] - '0') * 10; i++;
+        ts.tm_sec += (data_ptr[i] - '0');
+
+        /* Convert to time struct*/
+        ct = XGMTIME(pTime, tmpTs);
+
+        if (ct == NULL)
+            return GETTIME_ERROR;
+
+        /* DateGreaterThan returns 1 for >; 0 for <= */
+        ret = DateGreaterThan(&ts, ct) ? 1 : -1;
+    }
+
+    return ret;
+}
+#endif /* !NO_ASN_TIME */
+
+#if defined(OPENSSL_EXTRA) && !defined(NO_ASN_TIME) && !defined(USER_TIME) && \
+    !defined(TIME_OVERRIDES)
+WOLFSSL_ASN1_TIME *wolfSSL_X509_time_adj_ex(WOLFSSL_ASN1_TIME *asnTime,
+    int offset_day, long offset_sec, time_t *in_tm)
+{
+    /* get current time if in_tm is null */
+    time_t t = in_tm ? *in_tm : XTIME(0);
+    return wolfSSL_ASN1_TIME_adj(asnTime, t, offset_day, offset_sec);
+}
+
+WOLFSSL_ASN1_TIME *wolfSSL_X509_time_adj(WOLFSSL_ASN1_TIME *asnTime,
+    long offset_sec, time_t *in_tm)
+{
+    return wolfSSL_X509_time_adj_ex(asnTime, 0, offset_sec, in_tm);
+}
+#endif
+
+#ifndef NO_WOLFSSL_STUB
+int wolfSSL_sk_X509_REVOKED_num(WOLFSSL_X509_REVOKED* revoked)
+{
+    (void)revoked;
+    WOLFSSL_STUB("sk_X509_REVOKED_num");
+    return 0;
+}
+#endif
+
+#ifndef NO_WOLFSSL_STUB
+WOLFSSL_X509_REVOKED* wolfSSL_X509_CRL_get_REVOKED(WOLFSSL_X509_CRL* crl)
+{
+    (void)crl;
+    WOLFSSL_STUB("X509_CRL_get_REVOKED");
+    return 0;
+}
+#endif
+
+#ifndef NO_WOLFSSL_STUB
+WOLFSSL_X509_REVOKED* wolfSSL_sk_X509_REVOKED_value(
+                                    WOLFSSL_X509_REVOKED* revoked, int value)
+{
+    (void)revoked;
+    (void)value;
+    WOLFSSL_STUB("sk_X509_REVOKED_value");
+    return 0;
+}
+#endif
+
+/* Used to create a new WOLFSSL_ASN1_INTEGER structure.
+ * returns a pointer to new structure on success and NULL on failure
+ */
+WOLFSSL_ASN1_INTEGER* wolfSSL_ASN1_INTEGER_new(void)
+{
+    WOLFSSL_ASN1_INTEGER* a;
+
+    a = (WOLFSSL_ASN1_INTEGER*)XMALLOC(sizeof(WOLFSSL_ASN1_INTEGER), NULL,
+                                       DYNAMIC_TYPE_OPENSSL);
+    if (a == NULL) {
+        return NULL;
+    }
+
+    XMEMSET(a, 0, sizeof(WOLFSSL_ASN1_INTEGER));
+    a->data    = a->intData;
+    a->dataMax = WOLFSSL_ASN1_INTEGER_MAX;
+    a->length  = 0;
+    return a;
+}
+
+
+/* free's internal elements of WOLFSSL_ASN1_INTEGER and free's "in" itself */
+void wolfSSL_ASN1_INTEGER_free(WOLFSSL_ASN1_INTEGER* in)
+{
+    if (in != NULL) {
+        if (in->isDynamic) {
+            XFREE(in->data, NULL, DYNAMIC_TYPE_OPENSSL);
+        }
+        XFREE(in, NULL, DYNAMIC_TYPE_OPENSSL);
+    }
+}
+
+
+/* Duplicate all WOLFSSL_ASN1_INTEGER members from src to dup
+ *  src : WOLFSSL_ASN1_INTEGER to duplicate
+ *  Returns pointer to duplicate WOLFSSL_ASN1_INTEGER
+ */
+WOLFSSL_ASN1_INTEGER* wolfSSL_ASN1_INTEGER_dup(const WOLFSSL_ASN1_INTEGER* src)
+{
+    WOLFSSL_ASN1_INTEGER* dup;
+    WOLFSSL_ENTER("wolfSSL_ASN1_INTEGER_dup");
+    if (!src)
+        return NULL;
+
+    dup = wolfSSL_ASN1_INTEGER_new();
+
+    if (dup == NULL)
+        return NULL;
+
+    dup->negative  = src->negative;
+    dup->dataMax   = src->dataMax;
+    dup->isDynamic = src->isDynamic;
+#if defined(OPENSSL_ALL) || defined(WOLFSSL_QT)
+    dup->length    = src->length;
+#endif
+    XSTRNCPY((char*)dup->intData,(const char*)src->intData,WOLFSSL_ASN1_INTEGER_MAX);
+
+    if (dup->isDynamic && src->data && dup->dataMax) {
+        dup->data = (unsigned char*)
+            XMALLOC(src->dataMax,NULL,DYNAMIC_TYPE_OPENSSL);
+        if (dup->data == NULL) {
+            wolfSSL_ASN1_INTEGER_free(dup);
+            return NULL;
+        }
+        XMEMCPY(dup->data,src->data,dup->dataMax);
+    }
+    return dup;
+}
+
+
+/* sets the value of WOLFSSL_ASN1_INTEGER a to the long value v. */
+int wolfSSL_ASN1_INTEGER_set(WOLFSSL_ASN1_INTEGER *a, long v)
+{
+    int ret = WOLFSSL_SUCCESS; /* return 1 for success and 0 for failure */
+    int j;
+    unsigned int i = 0;
+    unsigned char tmp[sizeof(long)+1] = {0};
+
+    if (a != NULL) {
+        /* dynamically create data buffer, +2 for type and length */
+        a->data = (unsigned char*)XMALLOC((sizeof(long)+1) + 2, NULL,
+                DYNAMIC_TYPE_OPENSSL);
+        if (a->data == NULL) {
+            wolfSSL_ASN1_INTEGER_free(a);
+            ret = WOLFSSL_FAILURE;
+        }
+        else {
+            a->dataMax   = (int)(sizeof(long)+1) + 2;
+            a->isDynamic = 1;
+        }
+    }
+    else {
+        /* Invalid parameter */
+        ret = WOLFSSL_FAILURE;
+    }
+
+
+    if (ret != WOLFSSL_FAILURE) {
+        /* Set type */
+        a->data[i++] = ASN_INTEGER;
+
+        /* Check for negative */
+        if (v < 0) {
+            a->negative = 1;
+            v *= -1;
+        }
+
+        /* Create char buffer */
+        for (j = 0; j < (int)sizeof(long); j++) {
+            if (v == 0) {
+                break;
+            }
+            tmp[j] = (unsigned char)(v & 0xff);
+            v >>= 8;
+        }
+
+        /* Set length */
+        a->data[i++] = (unsigned char)((j == 0) ? ++j : j);
+        /* +2 for type and length */
+        a->length = j + 2;
+
+        /* Copy to data */
+        for (; j > 0; j--) {
+            a->data[i++] = tmp[j-1];
+        }
+    }
+
+    return ret;
+}
+
+
+WOLFSSL_ASN1_INTEGER* wolfSSL_X509_get_serialNumber(WOLFSSL_X509* x509)
+{
+    WOLFSSL_ASN1_INTEGER* a;
+    int i = 0;
+
+    WOLFSSL_ENTER("wolfSSL_X509_get_serialNumber");
+
+    a = wolfSSL_ASN1_INTEGER_new();
+    if (a == NULL)
+        return NULL;
+
+    /* Make sure there is space for the data, ASN.1 type and length. */
+    if (x509->serialSz > (WOLFSSL_ASN1_INTEGER_MAX - 2)) {
+        /* dynamically create data buffer, +2 for type and length */
+        a->data = (unsigned char*)XMALLOC(x509->serialSz + 2, NULL,
+                DYNAMIC_TYPE_OPENSSL);
+        if (a->data == NULL) {
+            wolfSSL_ASN1_INTEGER_free(a);
+            return NULL;
+        }
+        a->dataMax   = x509->serialSz + 2;
+        a->isDynamic = 1;
+    } else {
+        /* Use array instead of dynamic memory */
+        a->data    = a->intData;
+        a->dataMax = WOLFSSL_ASN1_INTEGER_MAX;
+    }
+
+    #ifdef WOLFSSL_QT
+        XMEMCPY(&a->data[i], x509->serial, x509->serialSz);
+        a->length = x509->serialSz;
+    #else
+        a->data[i++] = ASN_INTEGER;
+        i += SetLength(x509->serialSz, a->data + i);
+        XMEMCPY(&a->data[i], x509->serial, x509->serialSz);
+        a->length = x509->serialSz + 2;
+    #endif
+
+    x509->serialNumber = a;
+
+    return a;
+}
+
+#endif /* OPENSSL_EXTRA */
+
+#if defined(WOLFSSL_MYSQL_COMPATIBLE) || defined(WOLFSSL_NGINX) || \
+    defined(WOLFSSL_HAPROXY) || defined(OPENSSL_EXTRA) || defined(OPENSSL_ALL)
+#ifndef NO_ASN_TIME
+int wolfSSL_ASN1_TIME_print(WOLFSSL_BIO* bio, const WOLFSSL_ASN1_TIME* asnTime)
+{
+    char buf[MAX_TIME_STRING_SZ];
+    int  ret = WOLFSSL_SUCCESS;
+
+    WOLFSSL_ENTER("wolfSSL_ASN1_TIME_print");
+
+    if (bio == NULL || asnTime == NULL) {
+        WOLFSSL_MSG("NULL function argument");
+        return WOLFSSL_FAILURE;
+    }
+
+    if (wolfSSL_ASN1_TIME_to_string((WOLFSSL_ASN1_TIME*)asnTime, buf,
+                sizeof(buf)) == NULL) {
+        XMEMSET(buf, 0, MAX_TIME_STRING_SZ);
+        XMEMCPY(buf, "Bad time value", 14);
+        ret = WOLFSSL_FAILURE;
+    }
+
+    if (wolfSSL_BIO_write(bio, buf, (int)XSTRLEN(buf)) <= 0) {
+        WOLFSSL_MSG("Unable to write to bio");
+        return WOLFSSL_FAILURE;
+    }
+
+    return ret;
+}
+
+char* wolfSSL_ASN1_TIME_to_string(WOLFSSL_ASN1_TIME* t, char* buf, int len)
+{
+    WOLFSSL_ENTER("wolfSSL_ASN1_TIME_to_string");
+
+    if (t == NULL || buf == NULL || len < 5) {
+        WOLFSSL_MSG("Bad argument");
+        return NULL;
+    }
+
+    if (t->length > len) {
+        WOLFSSL_MSG("Length of date is longer then buffer");
+        return NULL;
+    }
+
+    if (!GetTimeString(t->data, t->type, buf, len)) {
+        return NULL;
+    }
+
+    return buf;
+}
+#endif /* !NO_ASN_TIME */
+#endif /* WOLFSSL_MYSQL_COMPATIBLE || WOLFSSL_NGINX || WOLFSSL_HAPROXY ||
+    OPENSSL_EXTRA*/
+
+
+#ifdef OPENSSL_EXTRA
+
+#ifndef NO_WOLFSSL_STUB
+int wolfSSL_ASN1_INTEGER_cmp(const WOLFSSL_ASN1_INTEGER* a,
+                            const WOLFSSL_ASN1_INTEGER* b)
+{
+    (void)a;
+    (void)b;
+    WOLFSSL_STUB("ASN1_INTEGER_cmp");
+    return 0;
+}
+#endif
+
+#ifndef NO_WOLFSSL_STUB
+long wolfSSL_ASN1_INTEGER_get(const WOLFSSL_ASN1_INTEGER* i)
+{
+    (void)i;
+    WOLFSSL_STUB("ASN1_INTEGER_get");
+    return 0;
+}
+#endif
+
+/* get X509_STORE_CTX ex_data, max idx is MAX_EX_DATA */
+void* wolfSSL_X509_STORE_CTX_get_ex_data(WOLFSSL_X509_STORE_CTX* ctx, int idx)
+{
+    WOLFSSL_ENTER("wolfSSL_X509_STORE_CTX_get_ex_data");
+    #if defined(HAVE_EX_DATA) || defined(FORTRESS)
+    if (ctx != NULL) {
+        return wolfSSL_CRYPTO_get_ex_data(&ctx->ex_data, idx);
+    }
+    #else
+    (void)ctx;
+    (void)idx;
+    #endif
+    return NULL;
+}
+
+
+/* set X509_STORE_CTX ex_data, max idx is MAX_EX_DATA. Return WOLFSSL_SUCCESS
+ * on success, WOLFSSL_FAILURE on error. */
+int wolfSSL_X509_STORE_CTX_set_ex_data(WOLFSSL_X509_STORE_CTX* ctx, int idx,
+                                       void *data)
+{
+    WOLFSSL_ENTER("wolfSSL_X509_STORE_CTX_set_ex_data");
+    #if defined(HAVE_EX_DATA) || defined(FORTRESS)
+    if (ctx != NULL)
+    {
+        return wolfSSL_CRYPTO_set_ex_data(&ctx->ex_data, idx, data);
+    }
+    #else
+    (void)ctx;
+    (void)idx;
+    (void)data;
+    #endif
+    return WOLFSSL_FAILURE;
+}
+
+#if defined(WOLFSSL_APACHE_HTTPD) || defined(OPENSSL_ALL)
+void wolfSSL_X509_STORE_CTX_set_depth(WOLFSSL_X509_STORE_CTX* ctx, int depth)
+{
+    WOLFSSL_ENTER("wolfSSL_X509_STORE_CTX_set_depth");
+    if (ctx)
+        ctx->depth = depth;
+}
+#endif
+
+
+WOLFSSL_X509* wolfSSL_X509_STORE_CTX_get0_current_issuer(
+        WOLFSSL_X509_STORE_CTX* ctx)
+{
+    int ret;
+    WOLFSSL_X509* issuer;
+
+    WOLFSSL_ENTER("wolfSSL_X509_STORE_CTX_get0_current_issuer");
+
+    if (ctx == NULL) {
+        return NULL;
+    }
+
+    ret = wolfSSL_X509_STORE_CTX_get1_issuer(&issuer, ctx, ctx->current_cert);
+    if (ret == WOLFSSL_SUCCESS) {
+        return issuer;
+    }
+
+    return NULL;
+}
+
+
+/* Gets an index to store SSL structure at.
+ *
+ * Returns positive index on success and negative values on failure
+ */
+int wolfSSL_get_ex_data_X509_STORE_CTX_idx(void)
+{
+    WOLFSSL_ENTER("wolfSSL_get_ex_data_X509_STORE_CTX_idx");
+
+    /* store SSL at index 0 */
+    return 0;
+}
+
+
+/* Set an error stat in the X509 STORE CTX
+ *
+ */
+void wolfSSL_X509_STORE_CTX_set_error(WOLFSSL_X509_STORE_CTX* ctx, int er)
+{
+    WOLFSSL_ENTER("wolfSSL_X509_STORE_CTX_set_error");
+
+    if (ctx != NULL) {
+        ctx->error = er;
+    }
+}
+
+/* Set the error depth in the X509 STORE CTX */
+void wolfSSL_X509_STORE_CTX_set_error_depth(WOLFSSL_X509_STORE_CTX* ctx,
+                                                                      int depth)
+{
+    WOLFSSL_ENTER("wolfSSL_X509_STORE_CTX_set_error_depth");
+
+    if (ctx != NULL) {
+        ctx->error_depth = depth;
+    }
+}
+
+/* Sets a function callback that will send information about the state of all
+ * WOLFSSL objects that have been created by the WOLFSSL_CTX structure passed
+ * in.
+ *
+ * ctx WOLFSSL_CTX structure to set callback function in
+ * f   callback function to use
+ */
+void wolfSSL_CTX_set_info_callback(WOLFSSL_CTX* ctx,
+       void (*f)(const WOLFSSL* ssl, int type, int val))
+{
+    WOLFSSL_ENTER("wolfSSL_CTX_set_info_callback");
+    if (ctx == NULL) {
+        WOLFSSL_MSG("Bad function argument");
+    }
+    else {
+        ctx->CBIS = f;
+    }
+}
+
+
+unsigned long wolfSSL_ERR_peek_error(void)
+{
+    WOLFSSL_ENTER("wolfSSL_ERR_peek_error");
+
+    return wolfSSL_ERR_peek_error_line_data(NULL, NULL, NULL, NULL);
+}
+
+int wolfSSL_ERR_GET_LIB(unsigned long err)
+{
+    switch (err) {
+    case PEM_R_NO_START_LINE:
+    case PEM_R_PROBLEMS_GETTING_PASSWORD:
+    case PEM_R_BAD_PASSWORD_READ:
+    case PEM_R_BAD_DECRYPT:
+        return ERR_LIB_PEM;
+    case EVP_R_BAD_DECRYPT:
+    case EVP_R_BN_DECODE_ERROR:
+    case EVP_R_DECODE_ERROR:
+    case EVP_R_PRIVATE_KEY_DECODE_ERROR:
+        return ERR_LIB_EVP;
+    default:
+        return 0;
+    }
+}
+
+/* This function is to find global error values that are the same through out
+ * all library version. With wolfSSL having only one set of error codes the
+ * return value is pretty straight forward. The only thing needed is all wolfSSL
+ * error values are typically negative.
+ *
+ * Returns the error reason
+ */
+int wolfSSL_ERR_GET_REASON(unsigned long err)
+{
+    int ret = (int)err;
+
+    WOLFSSL_ENTER("wolfSSL_ERR_GET_REASON");
+
+#if defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY)
+    /* Nginx looks for this error to know to stop parsing certificates. */
+    if (err == ((ERR_LIB_PEM << 24) | PEM_R_NO_START_LINE))
+        return PEM_R_NO_START_LINE;
+#endif
+
+    /* check if error value is in range of wolfSSL errors */
+    ret = 0 - ret; /* setting as negative value */
+    /* wolfCrypt range is less than MAX (-100)
+       wolfSSL range is MIN (-300) and lower */
+    if (ret < MAX_CODE_E && ret > MIN_CODE_E) {
+        return ret;
+    }
+    else {
+        WOLFSSL_MSG("Not in range of typical error values");
+        ret = (int)err;
+    }
+
+    return ret;
+}
+
+
+/* returns a string that describes the alert
+ *
+ * alertID the alert value to look up
+ */
+const char* wolfSSL_alert_type_string_long(int alertID)
+{
+    WOLFSSL_ENTER("wolfSSL_alert_type_string_long");
+
+    switch (alertID) {
+        case close_notify:
+            {
+                static const char close_notify_str[] =
+                    "close_notify";
+                return close_notify_str;
+            }
+
+        case unexpected_message:
+            {
+                static const char unexpected_message_str[] =
+                    "unexpected_message";
+                return unexpected_message_str;
+            }
+
+        case bad_record_mac:
+            {
+                static const char bad_record_mac_str[] =
+                    "bad_record_mac";
+                return bad_record_mac_str;
+            }
+
+        case record_overflow:
+            {
+                static const char record_overflow_str[] =
+                    "record_overflow";
+                return record_overflow_str;
+            }
+
+        case decompression_failure:
+            {
+                static const char decompression_failure_str[] =
+                    "decompression_failure";
+                return decompression_failure_str;
+            }
+
+        case handshake_failure:
+            {
+                static const char handshake_failure_str[] =
+                    "handshake_failure";
+                return handshake_failure_str;
+            }
+
+        case no_certificate:
+            {
+                static const char no_certificate_str[] =
+                    "no_certificate";
+                return no_certificate_str;
+            }
+
+        case bad_certificate:
+            {
+                static const char bad_certificate_str[] =
+                    "bad_certificate";
+                return bad_certificate_str;
+            }
+
+        case unsupported_certificate:
+            {
+                static const char unsupported_certificate_str[] =
+                    "unsupported_certificate";
+                return unsupported_certificate_str;
+            }
+
+        case certificate_revoked:
+            {
+                static const char certificate_revoked_str[] =
+                    "certificate_revoked";
+                return certificate_revoked_str;
+            }
+
+        case certificate_expired:
+            {
+                static const char certificate_expired_str[] =
+                    "certificate_expired";
+                return certificate_expired_str;
+            }
+
+        case certificate_unknown:
+            {
+                static const char certificate_unknown_str[] =
+                    "certificate_unknown";
+                return certificate_unknown_str;
+            }
+
+        case illegal_parameter:
+            {
+                static const char illegal_parameter_str[] =
+                    "illegal_parameter";
+                return illegal_parameter_str;
+            }
+
+        case unknown_ca:
+            {
+                static const char unknown_ca_str[] =
+                    "unknown_ca";
+                return unknown_ca_str;
+            }
+
+        case decode_error:
+            {
+                static const char decode_error_str[] =
+                    "decode_error";
+                return decode_error_str;
+            }
+
+        case decrypt_error:
+            {
+                static const char decrypt_error_str[] =
+                    "decrypt_error";
+                return decrypt_error_str;
+            }
+
+    #ifdef WOLFSSL_MYSQL_COMPATIBLE
+    /* catch name conflict for enum protocol with MYSQL build */
+        case wc_protocol_version:
+            {
+                static const char wc_protocol_version_str[] =
+                    "wc_protocol_version";
+                return wc_protocol_version_str;
+            }
+
+    #else
+        case protocol_version:
+            {
+                static const char protocol_version_str[] =
+                    "protocol_version";
+                return protocol_version_str;
+            }
+
+    #endif
+        case no_renegotiation:
+            {
+                static const char no_renegotiation_str[] =
+                    "no_renegotiation";
+                return no_renegotiation_str;
+            }
+
+        case unrecognized_name:
+            {
+                static const char unrecognized_name_str[] =
+                    "unrecognized_name";
+                return unrecognized_name_str;
+            }
+
+        case bad_certificate_status_response:
+            {
+                static const char bad_certificate_status_response_str[] =
+                    "bad_certificate_status_response";
+                return bad_certificate_status_response_str;
+            }
+
+        case no_application_protocol:
+            {
+                static const char no_application_protocol_str[] =
+                    "no_application_protocol";
+                return no_application_protocol_str;
+            }
+
+        default:
+            WOLFSSL_MSG("Unknown Alert");
+            return NULL;
+    }
+}
+
+
+const char* wolfSSL_alert_desc_string_long(int alertID)
+{
+    WOLFSSL_ENTER("wolfSSL_alert_desc_string_long");
+    return wolfSSL_alert_type_string_long(alertID);
+}
+
+
+/* Gets the current state of the WOLFSSL structure
+ *
+ * ssl WOLFSSL structure to get state of
+ *
+ * Returns a human readable string of the WOLFSSL structure state
+ */
+const char* wolfSSL_state_string_long(const WOLFSSL* ssl)
+{
+
+    static const char* OUTPUT_STR[14][6][3] = {
+        {
+            {"SSLv3 Initialization","SSLv3 Initialization","SSLv3 Initialization"},
+            {"TLSv1 Initialization","TLSv2 Initialization","TLSv2 Initialization"},
+            {"TLSv1_1 Initialization","TLSv1_1 Initialization","TLSv1_1 Initialization"},
+            {"TLSv1_2 Initialization","TLSv1_2 Initialization","TLSv1_2 Initialization"},
+            {"DTLSv1 Initialization","DTLSv1 Initialization","DTLSv1 Initialization"},
+            {"DTLSv1_2 Initialization","DTLSv1_2 Initialization","DTLSv1_2 Initialization"},
+        },
+        {
+            {"SSLv3 read Server Hello Verify Request",
+             "SSLv3 write Server Hello Verify Request",
+             "SSLv3 Server Hello Verify Request"},
+            {"TLSv1 read Server Hello Verify Request",
+             "TLSv1 write Server Hello Verify Request",
+             "TLSv1 Server Hello Verify Request"},
+            {"TLSv1_1 read Server Hello Verify Request",
+            "TLSv1_1 write Server Hello Verify Request",
+             "TLSv1_1 Server Hello Verify Request"},
+            {"TLSv1_2 read Server Hello Verify Request",
+            "TLSv1_2 write Server Hello Verify Request",
+             "TLSv1_2 Server Hello Verify Request"},
+            {"DTLSv1 read Server Hello Verify Request",
+             "DTLSv1 write Server Hello Verify Request",
+             "DTLSv1 Server Hello Verify Request"},
+            {"DTLSv1_2 read Server Hello Verify Request",
+             "DTLSv1_2 write Server Hello Verify Request",
+             "DTLSv1_2 Server Hello Verify Request"},
+        },
+        {
+            {"SSLv3 read Server Hello",
+             "SSLv3 write Server Hello",
+             "SSLv3 Server Hello"},
+            {"TLSv1 read Server Hello",
+             "TLSv1 write Server Hello",
+             "TLSv1 Server Hello"},
+            {"TLSv1_1 read Server Hello",
+            "TLSv1_1 write Server Hello",
+             "TLSv1_1 Server Hello"},
+            {"TLSv1_2 read Server Hello",
+            "TLSv1_2 write Server Hello",
+             "TLSv1_2 Server Hello"},
+            {"DTLSv1 read Server Hello",
+            "DTLSv1 write Server Hello",
+             "DTLSv1 Server Hello"},
+            {"DTLSv1_2 read Server Hello"
+             "DTLSv1_2 write Server Hello",
+             "DTLSv1_2 Server Hello",
+            },
+        },
+        {
+            {"SSLv3 read Server Session Ticket",
+             "SSLv3 write Server Session Ticket",
+             "SSLv3 Server Session Ticket"},
+            {"TLSv1 read Server Session Ticket",
+             "TLSv1 write Server Session Ticket",
+             "TLSv1 Server Session Ticket"},
+            {"TLSv1_1 read Server Session Ticket",
+             "TLSv1_1 write Server Session Ticket",
+             "TLSv1_1 Server Session Ticket"},
+            {"TLSv1_2 read Server Session Ticket",
+             "TLSv1_2 write Server Session Ticket",
+             "TLSv1_2 Server Session Ticket"},
+            {"DTLSv1 read Server Session Ticket",
+             "DTLSv1 write Server Session Ticket",
+             "DTLSv1 Server Session Ticket"},
+            {"DTLSv1_2 read Server Session Ticket",
+             "DTLSv1_2 write Server Session Ticket",
+             "DTLSv1_2 Server Session Ticket"},
+        },
+        {
+            {"SSLv3 read Server Cert",
+             "SSLv3 write Server Cert",
+             "SSLv3 Server Cert"},
+            {"TLSv1 read Server Cert",
+             "TLSv1 write Server Cert",
+             "TLSv1 Server Cert"},
+            {"TLSv1_1 read Server Cert",
+             "TLSv1_1 write Server Cert",
+             "TLSv1_1 Server Cert"},
+            {"TLSv1_2 read Server Cert",
+             "TLSv1_2 write Server Cert",
+             "TLSv1_2 Server Cert"},
+            {"DTLSv1 read Server Cert",
+             "DTLSv1 write Server Cert",
+             "DTLSv1 Server Cert"},
+            {"DTLSv1_2 read Server Cert",
+             "DTLSv1_2 write Server Cert",
+             "DTLSv1_2 Server Cert"},
+        },
+        {
+            {"SSLv3 read Server Key Exchange",
+             "SSLv3 write Server Key Exchange",
+             "SSLv3 Server Key Exchange"},
+            {"TLSv1 read Server Key Exchange",
+             "TLSv1 write Server Key Exchange",
+             "TLSv1 Server Key Exchange"},
+            {"TLSv1_1 read Server Key Exchange",
+             "TLSv1_1 write Server Key Exchange",
+             "TLSv1_1 Server Key Exchange"},
+            {"TLSv1_2 read Server Key Exchange",
+             "TLSv1_2 write Server Key Exchange",
+             "TLSv1_2 Server Key Exchange"},
+            {"DTLSv1 read Server Key Exchange",
+             "DTLSv1 write Server Key Exchange",
+             "DTLSv1 Server Key Exchange"},
+            {"DTLSv1_2 read Server Key Exchange",
+             "DTLSv1_2 write Server Key Exchange",
+             "DTLSv1_2 Server Key Exchange"},
+        },
+        {
+            {"SSLv3 read Server Hello Done",
+             "SSLv3 write Server Hello Done",
+             "SSLv3 Server Hello Done"},
+            {"TLSv1 read Server Hello Done",
+             "TLSv1 write Server Hello Done",
+             "TLSv1 Server Hello Done"},
+            {"TLSv1_1 read Server Hello Done",
+             "TLSv1_1 write Server Hello Done",
+             "TLSv1_1 Server Hello Done"},
+            {"TLSv1_2 read Server Hello Done",
+             "TLSv1_2 write Server Hello Done",
+             "TLSv1_2 Server Hello Done"},
+            {"DTLSv1 read Server Hello Done",
+             "DTLSv1 write Server Hello Done",
+             "DTLSv1 Server Hello Done"},
+            {"DTLSv1_2 read Server Hello Done",
+             "DTLSv1_2 write Server Hello Done",
+             "DTLSv1_2 Server Hello Done"},
+        },
+        {
+            {"SSLv3 read Server Change CipherSpec",
+             "SSLv3 write Server Change CipherSpec",
+             "SSLv3 Server Change CipherSpec"},
+            {"TLSv1 read Server Change CipherSpec",
+             "TLSv1 write Server Change CipherSpec",
+             "TLSv1 Server Change CipherSpec"},
+            {"TLSv1_1 read Server Change CipherSpec",
+             "TLSv1_1 write Server Change CipherSpec",
+             "TLSv1_1 Server Change CipherSpec"},
+            {"TLSv1_2 read Server Change CipherSpec",
+             "TLSv1_2 write Server Change CipherSpec",
+             "TLSv1_2 Server Change CipherSpec"},
+            {"DTLSv1 read Server Change CipherSpec",
+             "DTLSv1 write Server Change CipherSpec",
+             "DTLSv1 Server Change CipherSpec"},
+            {"DTLSv1_2 read Server Change CipherSpec",
+             "DTLSv1_2 write Server Change CipherSpec",
+             "DTLSv1_2 Server Change CipherSpec"},
+        },
+        {
+            {"SSLv3 read Server Finished",
+             "SSLv3 write Server Finished",
+             "SSLv3 Server Finished"},
+            {"TLSv1 read Server Finished",
+             "TLSv1 write Server Finished",
+             "TLSv1 Server Finished"},
+            {"TLSv1_1 read Server Finished",
+             "TLSv1_1 write Server Finished",
+             "TLSv1_1 Server Finished"},
+            {"TLSv1_2 read Server Finished",
+             "TLSv1_2 write Server Finished",
+             "TLSv1_2 Server Finished"},
+            {"DTLSv1 read Server Finished",
+             "DTLSv1 write Server Finished",
+             "DTLSv1 Server Finished"},
+            {"DTLSv1_2 read Server Finished",
+             "DTLSv1_2 write Server Finished",
+             "DTLSv1_2 Server Finished"},
+        },
+        {
+            {"SSLv3 read Client Hello",
+             "SSLv3 write Client Hello",
+             "SSLv3 Client Hello"},
+            {"TLSv1 read Client Hello",
+             "TLSv1 write Client Hello",
+             "TLSv1 Client Hello"},
+            {"TLSv1_1 read Client Hello",
+             "TLSv1_1 write Client Hello",
+             "TLSv1_1 Client Hello"},
+            {"TLSv1_2 read Client Hello",
+             "TLSv1_2 write Client Hello",
+             "TLSv1_2 Client Hello"},
+            {"DTLSv1 read Client Hello",
+             "DTLSv1 write Client Hello",
+             "DTLSv1 Client Hello"},
+            {"DTLSv1_2 read Client Hello",
+             "DTLSv1_2 write Client Hello",
+             "DTLSv1_2 Client Hello"},
+        },
+        {
+            {"SSLv3 read Client Key Exchange",
+             "SSLv3 write Client Key Exchange",
+             "SSLv3 Client Key Exchange"},
+            {"TLSv1 read Client Key Exchange",
+             "TLSv1 write Client Key Exchange",
+             "TLSv1 Client Key Exchange"},
+            {"TLSv1_1 read Client Key Exchange",
+             "TLSv1_1 write Client Key Exchange",
+             "TLSv1_1 Client Key Exchange"},
+            {"TLSv1_2 read Client Key Exchange",
+             "TLSv1_2 write Client Key Exchange",
+             "TLSv1_2 Client Key Exchange"},
+            {"DTLSv1 read Client Key Exchange",
+             "DTLSv1 write Client Key Exchange",
+             "DTLSv1 Client Key Exchange"},
+            {"DTLSv1_2 read Client Key Exchange",
+             "DTLSv1_2 write Client Key Exchange",
+             "DTLSv1_2 Client Key Exchange"},
+        },
+        {
+            {"SSLv3 read Client Change CipherSpec",
+             "SSLv3 write Client Change CipherSpec",
+             "SSLv3 Client Change CipherSpec"},
+            {"TLSv1 read Client Change CipherSpec",
+             "TLSv1 write Client Change CipherSpec",
+             "TLSv1 Client Change CipherSpec"},
+            {"TLSv1_1 read Client Change CipherSpec",
+             "TLSv1_1 write Client Change CipherSpec",
+             "TLSv1_1 Client Change CipherSpec"},
+            {"TLSv1_2 read Client Change CipherSpec",
+             "TLSv1_2 write Client Change CipherSpec",
+             "TLSv1_2 Client Change CipherSpec"},
+            {"DTLSv1 read Client Change CipherSpec",
+             "DTLSv1 write Client Change CipherSpec",
+             "DTLSv1 Client Change CipherSpec"},
+            {"DTLSv1_2 read Client Change CipherSpec",
+             "DTLSv1_2 write Client Change CipherSpec",
+             "DTLSv1_2 Client Change CipherSpec"},
+        },
+        {
+            {"SSLv3 read Client Finished",
+             "SSLv3 write Client Finished",
+             "SSLv3 Client Finished"},
+            {"TLSv1 read Client Finished",
+             "TLSv1 write Client Finished",
+             "TLSv1 Client Finished"},
+            {"TLSv1_1 read Client Finished",
+             "TLSv1_1 write Client Finished",
+             "TLSv1_1 Client Finished"},
+            {"TLSv1_2 read Client Finished",
+             "TLSv1_2 write Client Finished",
+             "TLSv1_2 Client Finished"},
+            {"DTLSv1 read Client Finished",
+             "DTLSv1 write Client Finished",
+             "DTLSv1 Client Finished"},
+            {"DTLSv1_2 read Client Finished",
+             "DTLSv1_2 write Client Finished",
+             "DTLSv1_2 Client Finished"},
+        },
+        {
+            {"SSLv3 Handshake Done",
+             "SSLv3 Handshake Done",
+             "SSLv3 Handshake Done"},
+            {"TLSv1 Handshake Done",
+             "TLSv1 Handshake Done",
+             "TLSv1 Handshake Done"},
+            {"TLSv1_1 Handshake Done",
+             "TLSv1_1 Handshake Done",
+             "TLSv1_1 Handshake Done"},
+            {"TLSv1_2 Handshake Done",
+             "TLSv1_2 Handshake Done",
+             "TLSv1_2 Handshake Done"},
+            {"DTLSv1 Handshake Done",
+             "DTLSv1 Handshake Done",
+             "DTLSv1 Handshake Done"},
+            {"DTLSv1_2 Handshake Done"
+             "DTLSv1_2 Handshake Done"
+             "DTLSv1_2 Handshake Done"}
+        }
+    };
+    enum ProtocolVer {
+        SSL_V3 = 0,
+        TLS_V1,
+        TLS_V1_1,
+        TLS_V1_2,
+        DTLS_V1,
+        DTLS_V1_2,
+        UNKNOWN = 100
+    };
+
+    enum IOMode {
+        SS_READ = 0,
+        SS_WRITE,
+        SS_NEITHER
+    };
+
+    enum SslState {
+        ss_null_state = 0,
+        ss_server_helloverify,
+        ss_server_hello,
+        ss_sessionticket,
+        ss_server_cert,
+        ss_server_keyexchange,
+        ss_server_hellodone,
+        ss_server_changecipherspec,
+        ss_server_finished,
+        ss_client_hello,
+        ss_client_keyexchange,
+        ss_client_changecipherspec,
+        ss_client_finished,
+        ss_handshake_done
+    };
+
+    int protocol = 0;
+    int cbmode = 0;
+    int state = 0;
+
+    WOLFSSL_ENTER("wolfSSL_state_string_long");
+    if (ssl == NULL) {
+        WOLFSSL_MSG("Null argument passed in");
+        return NULL;
+    }
+
+    /* Get state of callback */
+    if (ssl->cbmode == SSL_CB_MODE_WRITE){
+        cbmode =  SS_WRITE;
+    } else if (ssl->cbmode == SSL_CB_MODE_READ){
+        cbmode =  SS_READ;
+    } else {
+        cbmode =  SS_NEITHER;
+    }
+
+    /* Get protocol version */
+    switch (ssl->version.major){
+        case SSLv3_MAJOR:
+            switch (ssl->version.minor){
+                case TLSv1_MINOR:
+                    protocol = TLS_V1;
+                    break;
+                case TLSv1_1_MINOR:
+                    protocol = TLS_V1_1;
+                    break;
+                case TLSv1_2_MINOR:
+                    protocol = TLS_V1_2;
+                    break;
+                case SSLv3_MINOR:
+                    protocol = SSL_V3;
+                    break;
+                default:
+                    protocol = UNKNOWN;
+            }
+            break;
+        case DTLS_MAJOR:
+            switch (ssl->version.minor){
+        case DTLS_MINOR:
+            protocol = DTLS_V1;
+            break;
+        case DTLSv1_2_MINOR:
+            protocol = DTLS_V1_2;
+            break;
+        default:
+            protocol = UNKNOWN;
+    }
+    break;
+    default:
+        protocol = UNKNOWN;
+    }
+
+    /* accept process */
+    if (ssl->cbmode == SSL_CB_MODE_READ){
+        state = ssl->cbtype;
+        switch (state) {
+            case hello_verify_request:
+                state = ss_server_helloverify;
+                break;
+            case session_ticket:
+                state = ss_sessionticket;
+                break;
+            case server_hello:
+                state = ss_server_hello;
+                break;
+            case server_hello_done:
+                state = ss_server_hellodone;
+                break;
+            case certificate:
+                state = ss_server_cert;
+                break;
+            case server_key_exchange:
+                state = ss_server_keyexchange;
+                break;
+            case client_hello:
+                state = ss_client_hello;
+                break;
+            case client_key_exchange:
+                state = ss_client_keyexchange;
+                break;
+            case finished:
+                if (ssl->options.side == WOLFSSL_SERVER_END)
+                    state = ss_client_finished;
+                else if (ssl->options.side == WOLFSSL_CLIENT_END)
+                    state = ss_server_finished;
+                else {
+                    WOLFSSL_MSG("Unknown State");
+                    state = ss_null_state;
+                }
+                break;
+            default:
+                WOLFSSL_MSG("Unknown State");
+                state = ss_null_state;
+        }
+    } else {
+        /* Send process */
+        if (ssl->options.side == WOLFSSL_SERVER_END)
+            state = ssl->options.serverState;
+        else
+            state = ssl->options.clientState;
+
+        switch(state){
+            case SERVER_HELLOVERIFYREQUEST_COMPLETE:
+                state = ss_server_helloverify;
+                break;
+            case SERVER_HELLO_COMPLETE:
+                state = ss_server_hello;
+                break;
+            case SERVER_CERT_COMPLETE:
+                state = ss_server_cert;
+                break;
+            case SERVER_KEYEXCHANGE_COMPLETE:
+                state = ss_server_keyexchange;
+                break;
+            case SERVER_HELLODONE_COMPLETE:
+                state = ss_server_hellodone;
+                break;
+            case SERVER_CHANGECIPHERSPEC_COMPLETE:
+                state = ss_server_changecipherspec;
+                break;
+            case SERVER_FINISHED_COMPLETE:
+                state = ss_server_finished;
+                break;
+            case CLIENT_HELLO_COMPLETE:
+                state = ss_client_hello;
+                break;
+            case CLIENT_KEYEXCHANGE_COMPLETE:
+                state = ss_client_keyexchange;
+                break;
+            case CLIENT_CHANGECIPHERSPEC_COMPLETE:
+                state = ss_client_changecipherspec;
+                break;
+            case CLIENT_FINISHED_COMPLETE:
+                state = ss_client_finished;
+                break;
+            case HANDSHAKE_DONE:
+                state = ss_handshake_done;
+                break;
+            default:
+                WOLFSSL_MSG("Unknown State");
+                state = ss_null_state;
+        }
+    }
+
+    if (protocol == UNKNOWN)
+        return NULL;
+    else
+        return OUTPUT_STR[state][protocol][cbmode];
+}
+
+/*
+ * Sets default PEM callback password if null is passed into
+ * the callback parameter of a PEM_read_bio_* function.
+ *
+ * Returns callback phrase size on success or WOLFSSL_FAILURE otherwise.
+ */
+int wolfSSL_PEM_def_callback(char* name, int num, int w, void* key)
+{
+    int sz;
+    (void)w;
+    WOLFSSL_ENTER("wolfSSL_PEM_def_callback");
+
+    /* We assume that the user passes a default password as userdata */
+    if (key) {
+        sz = (int)XSTRLEN((const char*)key);
+        sz = (sz > num) ? num : sz;
+        XMEMCPY(name, key, sz);
+        return sz;
+    } else {
+        WOLFSSL_MSG("Error, default password cannot be created.");
+        return WOLFSSL_FAILURE;
+    }
+}
+
+#endif /* OPENSSL_EXTRA */
+
+#if defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER)
+static long wolf_set_options(long old_op, long op)
+{
+    /* if SSL_OP_ALL then turn all bug workarounds on */
+    if ((op & SSL_OP_ALL) == SSL_OP_ALL) {
+        WOLFSSL_MSG("\tSSL_OP_ALL");
+    }
+
+    /* by default cookie exchange is on with DTLS */
+    if ((op & SSL_OP_COOKIE_EXCHANGE) == SSL_OP_COOKIE_EXCHANGE) {
+        WOLFSSL_MSG("\tSSL_OP_COOKIE_EXCHANGE : on by default");
+    }
+
+    if ((op & WOLFSSL_OP_NO_SSLv2) == WOLFSSL_OP_NO_SSLv2) {
+        WOLFSSL_MSG("\tWOLFSSL_OP_NO_SSLv2 : wolfSSL does not support SSLv2");
+    }
+
+#ifdef SSL_OP_NO_TLSv1_3
+    if ((op & SSL_OP_NO_TLSv1_3) == SSL_OP_NO_TLSv1_3) {
+        WOLFSSL_MSG("\tSSL_OP_NO_TLSv1_3");
+    }
+#endif
+
+    if ((op & SSL_OP_NO_TLSv1_2) == SSL_OP_NO_TLSv1_2) {
+        WOLFSSL_MSG("\tSSL_OP_NO_TLSv1_2");
+    }
+
+    if ((op & SSL_OP_NO_TLSv1_1) == SSL_OP_NO_TLSv1_1) {
+        WOLFSSL_MSG("\tSSL_OP_NO_TLSv1_1");
+    }
+
+    if ((op & SSL_OP_NO_TLSv1) == SSL_OP_NO_TLSv1) {
+        WOLFSSL_MSG("\tSSL_OP_NO_TLSv1");
+    }
+
+    if ((op & SSL_OP_NO_SSLv3) == SSL_OP_NO_SSLv3) {
+        WOLFSSL_MSG("\tSSL_OP_NO_SSLv3");
+    }
+
+    if ((op & SSL_OP_CIPHER_SERVER_PREFERENCE) == SSL_OP_CIPHER_SERVER_PREFERENCE) {
+        WOLFSSL_MSG("\tSSL_OP_CIPHER_SERVER_PREFERENCE");
+    }
+
+    if ((op & SSL_OP_NO_COMPRESSION) == SSL_OP_NO_COMPRESSION) {
+    #ifdef HAVE_LIBZ
+        WOLFSSL_MSG("SSL_OP_NO_COMPRESSION");
+    #else
+        WOLFSSL_MSG("SSL_OP_NO_COMPRESSION: compression not compiled in");
+    #endif
+    }
+
+    return old_op | op;
+}
+#endif
+
+#ifdef OPENSSL_EXTRA
+long wolfSSL_set_options(WOLFSSL* ssl, long op)
+{
+    word16 haveRSA = 1;
+    word16 havePSK = 0;
+    int    keySz   = 0;
+
+    WOLFSSL_ENTER("wolfSSL_set_options");
+
+    if (ssl == NULL) {
+        return 0;
+    }
+
+    ssl->options.mask = wolf_set_options(ssl->options.mask, op);
+
+#ifdef SSL_OP_NO_TLSv1_3
+    if ((ssl->options.mask & SSL_OP_NO_TLSv1_3) == SSL_OP_NO_TLSv1_3) {
+        if (ssl->version.minor == TLSv1_3_MINOR)
+            ssl->version.minor = TLSv1_2_MINOR;
+    }
+#endif
+
+    if ((ssl->options.mask & SSL_OP_NO_TLSv1_2) == SSL_OP_NO_TLSv1_2) {
+        if (ssl->version.minor == TLSv1_2_MINOR)
+            ssl->version.minor = TLSv1_1_MINOR;
+    }
+
+    if ((ssl->options.mask & SSL_OP_NO_TLSv1_1) == SSL_OP_NO_TLSv1_1) {
+        if (ssl->version.minor == TLSv1_1_MINOR)
+            ssl->version.minor = TLSv1_MINOR;
+    }
+
+    if ((ssl->options.mask & SSL_OP_NO_TLSv1) == SSL_OP_NO_TLSv1) {
+        if (ssl->version.minor == TLSv1_MINOR)
+            ssl->version.minor = SSLv3_MINOR;
+    }
+
+    if ((ssl->options.mask & SSL_OP_NO_COMPRESSION) == SSL_OP_NO_COMPRESSION) {
+    #ifdef HAVE_LIBZ
+        ssl->options.usingCompression = 0;
+    #endif
+    }
+
+    /* in the case of a version change the cipher suites should be reset */
+#ifndef NO_PSK
+    havePSK = ssl->options.havePSK;
+#endif
+#ifdef NO_RSA
+    haveRSA = 0;
+#endif
+#ifndef NO_CERTS
+    keySz = ssl->buffers.keySz;
+#endif
+
+    InitSuites(ssl->suites, ssl->version, keySz, haveRSA, havePSK,
+                       ssl->options.haveDH, ssl->options.haveNTRU,
+                       ssl->options.haveECDSAsig, ssl->options.haveECC,
+                       ssl->options.haveStaticECC, ssl->options.side);
+
+    return ssl->options.mask;
+}
+
+
+long wolfSSL_get_options(const WOLFSSL* ssl)
+{
+    WOLFSSL_ENTER("wolfSSL_get_options");
+    if(ssl == NULL)
+        return WOLFSSL_FAILURE;
+    return ssl->options.mask;
+}
+
+long wolfSSL_clear_options(WOLFSSL* ssl, long opt)
+{
+    WOLFSSL_ENTER("SSL_clear_options");
+    if(ssl == NULL)
+        return WOLFSSL_FAILURE;
+    ssl->options.mask &= ~opt;
+    return ssl->options.mask;
+}
+
+
+#if defined(HAVE_SECURE_RENEGOTIATION) \
+        || defined(HAVE_SERVER_RENEGOTIATION_INFO)
+/* clears the counter for number of renegotiations done
+ * returns the current count before it is cleared */
+long wolfSSL_clear_num_renegotiations(WOLFSSL *s)
+{
+    long total;
+
+    WOLFSSL_ENTER("wolfSSL_clear_num_renegotiations");
+    if (s == NULL)
+        return 0;
+
+    total = s->secure_rene_count;
+    s->secure_rene_count = 0;
+    return total;
+}
+
+
+/* return the number of renegotiations since wolfSSL_new */
+long wolfSSL_total_renegotiations(WOLFSSL *s)
+{
+    WOLFSSL_ENTER("wolfSSL_total_renegotiations");
+    return wolfSSL_num_renegotiations(s);
+}
+
+
+/* return the number of renegotiations since wolfSSL_new */
+long wolfSSL_num_renegotiations(WOLFSSL* s)
+{
+    if (s == NULL) {
+        return 0;
+    }
+
+    return s->secure_rene_count;
+}
+#endif /* HAVE_SECURE_RENEGOTIATION || HAVE_SERVER_RENEGOTIATION_INFO */
+
+#ifndef NO_DH
+long wolfSSL_set_tmp_dh(WOLFSSL *ssl, WOLFSSL_DH *dh)
+{
+    int pSz, gSz;
+    byte *p, *g;
+    int ret = 0;
+
+    WOLFSSL_ENTER("wolfSSL_set_tmp_dh");
+
+    if (!ssl || !dh)
+        return BAD_FUNC_ARG;
+
+    /* Get needed size for p and g */
+    pSz = wolfSSL_BN_bn2bin(dh->p, NULL);
+    gSz = wolfSSL_BN_bn2bin(dh->g, NULL);
+
+    if (pSz <= 0 || gSz <= 0)
+        return WOLFSSL_FATAL_ERROR;
+
+    p = (byte*)XMALLOC(pSz, ssl->heap, DYNAMIC_TYPE_PUBLIC_KEY);
+    if (!p)
+        return MEMORY_E;
+
+    g = (byte*)XMALLOC(gSz, ssl->heap, DYNAMIC_TYPE_PUBLIC_KEY);
+    if (!g) {
+        XFREE(p, ssl->heap, DYNAMIC_TYPE_PUBLIC_KEY);
+        return MEMORY_E;
+    }
+
+    pSz = wolfSSL_BN_bn2bin(dh->p, p);
+    gSz = wolfSSL_BN_bn2bin(dh->g, g);
+
+    if (pSz >= 0 && gSz >= 0) /* Conversion successful */
+        ret = wolfSSL_SetTmpDH(ssl, p, pSz, g, gSz);
+
+    XFREE(p, ssl->heap, DYNAMIC_TYPE_PUBLIC_KEY);
+    XFREE(g, ssl->heap, DYNAMIC_TYPE_PUBLIC_KEY);
+
+    return pSz > 0 && gSz > 0 ? ret : WOLFSSL_FATAL_ERROR;
+}
+#endif /* !NO_DH */
+
+
+#ifdef HAVE_PK_CALLBACKS
+long wolfSSL_set_tlsext_debug_arg(WOLFSSL* ssl, void *arg)
+{
+    if (ssl == NULL) {
+        return WOLFSSL_FAILURE;
+    }
+
+    ssl->loggingCtx = arg;
+    return WOLFSSL_SUCCESS;
+}
+#endif /* HAVE_PK_CALLBACKS */
+
+#if defined(OPENSSL_ALL) || defined(WOLFSSL_HAPROXY)
+const unsigned char *SSL_SESSION_get0_id_context(const SSL_SESSION *sess, unsigned int *sid_ctx_length)
+{
+    const byte *c = wolfSSL_SESSION_get_id((SSL_SESSION *)sess, sid_ctx_length);
+    return c;
+}
+#endif
+
+/*** TBD ***/
+#ifndef NO_WOLFSSL_STUB
+WOLFSSL_API int wolfSSL_sk_SSL_COMP_zero(WOLFSSL_STACK* st)
+{
+    (void)st;
+    WOLFSSL_STUB("wolfSSL_sk_SSL_COMP_zero");
+    /* wolfSSL_set_options(ssl, SSL_OP_NO_COMPRESSION); */
+    return WOLFSSL_FAILURE;
+}
+#endif
+
+#ifdef HAVE_CERTIFICATE_STATUS_REQUEST
+long wolfSSL_set_tlsext_status_type(WOLFSSL *s, int type)
+{
+    WOLFSSL_ENTER("wolfSSL_set_tlsext_status_type");
+
+    if (s == NULL){
+        return BAD_FUNC_ARG;
+    }
+
+    if (type == TLSEXT_STATUSTYPE_ocsp){
+        int r = 0;
+        r = TLSX_UseCertificateStatusRequest(&s->extensions, type, 0, s,
+                                                             s->heap, s->devId);
+        return (long)r;
+    } else {
+        WOLFSSL_MSG(
+       "SSL_set_tlsext_status_type only supports TLSEXT_STATUSTYPE_ocsp type.");
+        return SSL_FAILURE;
+    }
+
+}
+#endif /* HAVE_CERTIFICATE_STATUS_REQUEST */
+
+#ifndef NO_WOLFSSL_STUB
+WOLFSSL_API long wolfSSL_get_tlsext_status_exts(WOLFSSL *s, void *arg)
+{
+    (void)s;
+    (void)arg;
+    WOLFSSL_STUB("wolfSSL_get_tlsext_status_exts");
+    return WOLFSSL_FAILURE;
+}
+#endif
+
+/*** TBD ***/
+#ifndef NO_WOLFSSL_STUB
+WOLFSSL_API long wolfSSL_set_tlsext_status_exts(WOLFSSL *s, void *arg)
+{
+    (void)s;
+    (void)arg;
+    WOLFSSL_STUB("wolfSSL_set_tlsext_status_exts");
+    return WOLFSSL_FAILURE;
+}
+#endif
+
+/*** TBD ***/
+#ifndef NO_WOLFSSL_STUB
+WOLFSSL_API long wolfSSL_get_tlsext_status_ids(WOLFSSL *s, void *arg)
+{
+    (void)s;
+    (void)arg;
+    WOLFSSL_STUB("wolfSSL_get_tlsext_status_ids");
+    return WOLFSSL_FAILURE;
+}
+#endif
+
+/*** TBD ***/
+#ifndef NO_WOLFSSL_STUB
+WOLFSSL_API long wolfSSL_set_tlsext_status_ids(WOLFSSL *s, void *arg)
+{
+    (void)s;
+    (void)arg;
+    WOLFSSL_STUB("wolfSSL_set_tlsext_status_ids");
+    return WOLFSSL_FAILURE;
+}
+#endif
+
+/*** TBD ***/
+#ifndef NO_WOLFSSL_STUB
+WOLFSSL_API int SSL_SESSION_set1_id(WOLFSSL_SESSION *s, const unsigned char *sid, unsigned int sid_len)
+{
+    (void)s;
+    (void)sid;
+    (void)sid_len;
+    WOLFSSL_STUB("SSL_SESSION_set1_id");
+    return WOLFSSL_FAILURE;
+}
+#endif
+
+#ifndef NO_WOLFSSL_STUB
+/*** TBD ***/
+WOLFSSL_API int SSL_SESSION_set1_id_context(WOLFSSL_SESSION *s, const unsigned char *sid_ctx, unsigned int sid_ctx_len)
+{
+    (void)s;
+    (void)sid_ctx;
+    (void)sid_ctx_len;
+    WOLFSSL_STUB("SSL_SESSION_set1_id_context");
+    return WOLFSSL_FAILURE;
+}
+#endif
+
+#if defined(OPENSSL_ALL) || defined(WOLFSSL_APACHE_HTTPD) \
+    || defined(WOLFSSL_HAPROXY) || defined(WOLFSSL_WPAS)
+WOLFSSL_X509_ALGOR* wolfSSL_X509_ALGOR_new(void)
+{
+    WOLFSSL_X509_ALGOR* ret;
+    ret = (WOLFSSL_X509_ALGOR*)XMALLOC(sizeof(WOLFSSL_X509_ALGOR), NULL,
+                                       DYNAMIC_TYPE_OPENSSL);
+    if (ret) {
+        XMEMSET(ret, 0, sizeof(WOLFSSL_X509_ALGOR));
+    }
+    return ret;
+}
+
+void wolfSSL_X509_ALGOR_free(WOLFSSL_X509_ALGOR *alg)
+{
+    if (alg) {
+        wolfSSL_ASN1_OBJECT_free(alg->algorithm);
+        wolfSSL_ASN1_TYPE_free(alg->parameter);
+        XFREE(alg, NULL, DYNAMIC_TYPE_OPENSSL);
+    }
+}
+
+/* Returns X509_ALGOR struct with signature algorithm */
+const WOLFSSL_X509_ALGOR* wolfSSL_X509_get0_tbs_sigalg(const WOLFSSL_X509 *x509)
+{
+    WOLFSSL_ENTER("X509_get0_tbs_sigalg");
+
+    if (x509 == NULL) {
+        WOLFSSL_MSG("x509 struct NULL error");
+        return NULL;
+    }
+
+    return &x509->algor;
+}
+
+/* Sets paobj pointer to X509_ALGOR signature algorithm */
+void wolfSSL_X509_ALGOR_get0(const WOLFSSL_ASN1_OBJECT **paobj, int *pptype,
+                            const void **ppval, const WOLFSSL_X509_ALGOR *algor)
+{
+    WOLFSSL_ENTER("X509_ALGOR_get0");
+
+    if (!algor) {
+        WOLFSSL_MSG("algor object is NULL");
+        return;
+    }
+
+    if (paobj)
+        *paobj = algor->algorithm;
+    if (ppval)
+        *ppval = algor->algorithm;
+    if (pptype) {
+        if (algor->parameter) {
+            *pptype = algor->parameter->type;
+        }
+        else {
+            /* Default to V_ASN1_OBJECT */
+            *pptype = V_ASN1_OBJECT;
+        }
+    }
+}
+
+/**
+ * Populate algor members.
+ *
+ * @param algor The object to be set
+ * @param aobj The value to be set in algor->algorithm
+ * @param ptype The type of algor->parameter
+ * @param pval The value of algor->parameter
+ * @return WOLFSSL_SUCCESS on success
+ *         WOLFSSL_FAILURE on missing parameters or bad malloc
+ */
+int wolfSSL_X509_ALGOR_set0(WOLFSSL_X509_ALGOR *algor, WOLFSSL_ASN1_OBJECT *aobj,
+                            int ptype, void *pval)
+{
+    if (!algor) {
+        return WOLFSSL_FAILURE;
+    }
+    if (aobj) {
+        algor->algorithm = aobj;
+    }
+    if (pval) {
+        if (!algor->parameter) {
+            algor->parameter = wolfSSL_ASN1_TYPE_new();
+            if (!algor->parameter) {
+                return WOLFSSL_FAILURE;
+            }
+        }
+        wolfSSL_ASN1_TYPE_set(algor->parameter, ptype, pval);
+    }
+    return WOLFSSL_SUCCESS;
+}
+
+/**
+ * Set `a` in a smart way.
+ *
+ * @param a Object to set
+ * @param type The type of object in value
+ * @param value Object to set
+ */
+void wolfSSL_ASN1_TYPE_set(WOLFSSL_ASN1_TYPE *a, int type, void *value)
+{
+    if (!a || !value) {
+        return;
+    }
+    switch (type) {
+        case V_ASN1_OBJECT:
+            a->value.object = value;
+            break;
+        case V_ASN1_UTCTIME:
+            a->value.utctime = value;
+            break;
+        case V_ASN1_GENERALIZEDTIME:
+            a->value.generalizedtime = value;
+            break;
+        default:
+            WOLFSSL_MSG("Unknown or unsupported ASN1_TYPE");
+            return;
+    }
+    a->type = type;
+}
+
+/**
+ * Allocate a new WOLFSSL_ASN1_TYPE object.
+ *
+ * @return New zero'ed WOLFSSL_ASN1_TYPE object
+ */
+WOLFSSL_ASN1_TYPE* wolfSSL_ASN1_TYPE_new(void)
+{
+    WOLFSSL_ASN1_TYPE* ret = (WOLFSSL_ASN1_TYPE*)XMALLOC(sizeof(WOLFSSL_ASN1_TYPE),
+                                                        NULL, DYNAMIC_TYPE_OPENSSL);
+    if (!ret)
+        return NULL;
+    XMEMSET(ret, 0, sizeof(WOLFSSL_ASN1_TYPE));
+    return ret;
+}
+
+/**
+ * Free WOLFSSL_ASN1_TYPE and all its members.
+ *
+ * @param at Object to free
+ */
+void wolfSSL_ASN1_TYPE_free(WOLFSSL_ASN1_TYPE* at)
+{
+    if (at) {
+        switch (at->type) {
+            case V_ASN1_OBJECT:
+                wolfSSL_ASN1_OBJECT_free(at->value.object);
+                break;
+            case V_ASN1_UTCTIME:
+                wolfSSL_ASN1_TIME_free(at->value.utctime);
+                break;
+            case V_ASN1_GENERALIZEDTIME:
+                wolfSSL_ASN1_TIME_free(at->value.generalizedtime);
+                break;
+            default:
+                WOLFSSL_MSG("Unknown or unsupported ASN1_TYPE");
+                break;
+        }
+        XFREE(at, NULL, DYNAMIC_TYPE_OPENSSL);
+    }
+}
+
+/**
+ * Allocate a new WOLFSSL_X509_PUBKEY object.
+ *
+ * @return New zero'ed WOLFSSL_X509_PUBKEY object
+ */
+WOLFSSL_X509_PUBKEY *wolfSSL_X509_PUBKEY_new(void)
+{
+    WOLFSSL_X509_PUBKEY *ret;
+    ret = (WOLFSSL_X509_PUBKEY*)XMALLOC(sizeof(WOLFSSL_X509_PUBKEY), NULL,
+                                        DYNAMIC_TYPE_OPENSSL);
+    if (!ret) {
+        return NULL;
+    }
+    XMEMSET(ret, 0, sizeof(WOLFSSL_X509_PUBKEY));
+    ret->algor = wolfSSL_X509_ALGOR_new();
+    if (!ret->algor) {
+        wolfSSL_X509_PUBKEY_free(ret);
+        return NULL;
+    }
+    return ret;
+}
+
+/**
+ * Free WOLFSSL_X509_PUBKEY and all its members.
+ *
+ * @param at Object to free
+ */
+void wolfSSL_X509_PUBKEY_free(WOLFSSL_X509_PUBKEY *x)
+{
+    if (x) {
+        if (x->algor) {
+            wolfSSL_X509_ALGOR_free(x->algor);
+        }
+        if (x->pkey) {
+            wolfSSL_EVP_PKEY_free(x->pkey);
+        }
+        XFREE(x, NULL, DYNAMIC_TYPE_OPENSSL);
+    }
+}
+
+/* Returns X509_PUBKEY structure containing X509_ALGOR and EVP_PKEY */
+WOLFSSL_X509_PUBKEY* wolfSSL_X509_get_X509_PUBKEY(const WOLFSSL_X509* x509)
+{
+    WOLFSSL_ENTER("X509_get_X509_PUBKEY");
+
+    if (x509 == NULL) {
+        WOLFSSL_MSG("x509 struct NULL error");
+        return NULL;
+    }
+
+    return (WOLFSSL_X509_PUBKEY*)&x509->key;
+}
+
+/* Sets ppkalg pointer to X509_PUBKEY algorithm. Returns WOLFSSL_SUCCESS on
+    success or WOLFSSL_FAILURE on error. */
+int wolfSSL_X509_PUBKEY_get0_param(WOLFSSL_ASN1_OBJECT **ppkalg,
+     const unsigned char **pk, int *ppklen, WOLFSSL_X509_ALGOR **pa,
+     WOLFSSL_X509_PUBKEY *pub)
+{
+    WOLFSSL_ENTER("X509_PUBKEY_get0_param");
+
+    if (!pub || !pub->pubKeyOID) {
+        WOLFSSL_MSG("X509_PUBKEY struct not populated");
+        return WOLFSSL_FAILURE;
+    }
+
+    if (!pub->algor) {
+        if (!(pub->algor = wolfSSL_X509_ALGOR_new())) {
+            return WOLFSSL_FAILURE;
+        }
+        pub->algor->algorithm = wolfSSL_OBJ_nid2obj(pub->pubKeyOID);
+        if (pub->algor->algorithm == NULL) {
+            WOLFSSL_MSG("Failed to create object from NID");
+            return WOLFSSL_FAILURE;
+        }
+    }
+
+    if (pa)
+        *pa = pub->algor;
+    if (ppkalg)
+        *ppkalg = pub->algor->algorithm;
+    if (pk)
+        wolfSSL_EVP_PKEY_get_der(pub->pkey, (unsigned char **)pk);
+    if (ppklen)
+        *ppklen = wolfSSL_EVP_PKEY_get_der(pub->pkey, NULL);
+
+    return WOLFSSL_SUCCESS;
+}
+
+/* Returns a pointer to the pkey when passed a key */
+WOLFSSL_EVP_PKEY* wolfSSL_X509_PUBKEY_get(WOLFSSL_X509_PUBKEY* key)
+{
+    WOLFSSL_ENTER("wolfSSL_X509_PUBKEY_get");
+    if(key == NULL || key->pkey == NULL){
+        WOLFSSL_LEAVE("wolfSSL_X509_PUBKEY_get", BAD_FUNC_ARG);
+        return NULL;
+    }
+    WOLFSSL_LEAVE("wolfSSL_X509_PUBKEY_get", WOLFSSL_SUCCESS);
+    return key->pkey;
+}
+
+int wolfSSL_X509_PUBKEY_set(WOLFSSL_X509_PUBKEY **x, WOLFSSL_EVP_PKEY *key)
+{
+    WOLFSSL_X509_PUBKEY *pk = NULL;
+
+    WOLFSSL_ENTER("wolfSSL_X509_PUBKEY_set");
+
+    if (!x || !key) {
+        return WOLFSSL_FAILURE;
+    }
+
+    if (!(pk = wolfSSL_X509_PUBKEY_new())) {
+        return WOLFSSL_FAILURE;
+    }
+
+    switch (key->type) {
+#ifndef NO_RSA
+    case EVP_PKEY_RSA:
+        pk->algor->algorithm= wolfSSL_OBJ_nid2obj(RSAk);
+        break;
+#endif
+#ifndef NO_DSA
+    case EVP_PKEY_DSA:
+        pk->algor->algorithm = wolfSSL_OBJ_nid2obj(DSAk);
+        break;
+#endif
+#ifdef HAVE_ECC
+    case EVP_PKEY_EC:
+        pk->algor->algorithm = wolfSSL_OBJ_nid2obj(ECDSAk);
+        break;
+#endif
+    default:
+        WOLFSSL_MSG("Unknown key type");
+        goto error;
+    }
+
+    if (!pk->algor->algorithm) {
+        WOLFSSL_MSG("Failed to create algorithm object");
+        goto error;
+    }
+
+    if (!wolfSSL_EVP_PKEY_up_ref(key)) {
+        WOLFSSL_MSG("Failed to up key reference");
+        goto error;
+    }
+    pk->pkey = key;
+
+    wolfSSL_X509_PUBKEY_free(*x);
+    *x = pk;
+    return WOLFSSL_SUCCESS;
+error:
+    if (pk) {
+        wolfSSL_X509_PUBKEY_free(pk);
+    }
+    return WOLFSSL_FAILURE;
+}
+
+#endif /* OPENSSL_ALL || WOLFSSL_APACHE_HTTPD || WOLFSSL_HAPROXY*/
+
+#ifndef NO_WOLFSSL_STUB
+/*** TBD ***/
+WOLFSSL_API WOLFSSL_EVP_PKEY *wolfSSL_get_privatekey(const WOLFSSL *ssl)
+{
+    (void)ssl;
+    WOLFSSL_STUB("SSL_get_privatekey");
+    return NULL;
+}
+#endif
+
+#ifndef NO_WOLFSSL_STUB
+/*** TBD ***/
+WOLFSSL_API int i2t_ASN1_OBJECT(char *buf, int buf_len, WOLFSSL_ASN1_OBJECT *a)
+{
+    (void)buf;
+    (void)buf_len;
+    (void)a;
+    WOLFSSL_STUB("i2t_ASN1_OBJECT");
+    return -1;
+}
+#endif
+
+/* Return number of bytes written to BIO on success. 0 on failure. */
+WOLFSSL_API int wolfSSL_i2a_ASN1_OBJECT(WOLFSSL_BIO *bp,
+                                        WOLFSSL_ASN1_OBJECT *a)
+{
+    int length = 0;
+    word32 idx = 0;
+    const char null_str[] = "NULL";
+
+    WOLFSSL_ENTER("wolfSSL_i2a_ASN1_OBJECT");
+
+    if (bp == NULL)
+        return WOLFSSL_FAILURE;
+
+    if (a == NULL) {
+        /* Write "NULL" */
+        if (wolfSSL_BIO_write(bp, null_str, (int)XSTRLEN(null_str)) ==
+                (int)XSTRLEN(null_str)) {
+            return (int)XSTRLEN(null_str);
+        }
+        else {
+            return WOLFSSL_FAILURE;
+        }
+    }
+
+
+    if ((a->obj == NULL) || (a->obj[idx++] != ASN_OBJECT_ID)) {
+        WOLFSSL_MSG("Bad ASN1 Object");
+        return WOLFSSL_FAILURE;
+    }
+
+    if (GetLength((const byte*)a->obj, &idx, &length,
+                   a->objSz) < 0 || length < 0) {
+        return WOLFSSL_FAILURE;
+    }
+
+    if (wolfSSL_BIO_write(bp, a->obj + idx, length) == (int)length) {
+        return length;
+    }
+
+    return WOLFSSL_FAILURE;
+}
+
+#if defined(OPENSSL_ALL) || defined(WOLFSSL_HAPROXY)
+#ifndef NO_WOLFSSL_STUB
+/*** TBD ***/
+WOLFSSL_API size_t SSL_get_finished(const WOLFSSL *s, void *buf, size_t count)
+{
+    (void)s;
+    (void)buf;
+    (void)count;
+    WOLFSSL_STUB("SSL_get_finished");
+    return WOLFSSL_FAILURE;
+}
+#endif
+
+#ifndef NO_WOLFSSL_STUB
+/*** TBD ***/
+WOLFSSL_API size_t SSL_get_peer_finished(const WOLFSSL *s, void *buf, size_t count)
+{
+    (void)s;
+    (void)buf;
+    (void)count;
+    WOLFSSL_STUB("SSL_get_peer_finished");
+    return WOLFSSL_FAILURE;
+}
+#endif
+#endif /* WOLFSSL_HAPROXY */
+
+#ifndef NO_WOLFSSL_STUB
+/*** TBD ***/
+WOLFSSL_API void SSL_CTX_set_tmp_dh_callback(WOLFSSL_CTX *ctx, WOLFSSL_DH *(*dh) (WOLFSSL *ssl, int is_export, int keylength))
+{
+    (void)ctx;
+    (void)dh;
+    WOLFSSL_STUB("SSL_CTX_set_tmp_dh_callback");
+}
+#endif
+
+#ifndef NO_WOLFSSL_STUB
+/*** TBD ***/
+WOLFSSL_API WOLF_STACK_OF(SSL_COMP) *SSL_COMP_get_compression_methods(void)
+{
+    WOLFSSL_STUB("SSL_COMP_get_compression_methods");
+    return NULL;
+}
+#endif
+
+
+int wolfSSL_sk_SSL_CIPHER_num(const WOLF_STACK_OF(WOLFSSL_CIPHER)* p)
+{
+    WOLFSSL_ENTER("wolfSSL_sk_SSL_CIPHER_num");
+    if (p == NULL) {
+        return WOLFSSL_FATAL_ERROR;
+    }
+    return (int)p->num;
+}
+
+#if !defined(NO_FILESYSTEM)
+#ifndef NO_WOLFSSL_STUB
+/*** TBD ***/
+WOLFSSL_API WOLFSSL_EVP_PKEY *wolfSSL_PEM_read_PrivateKey(XFILE fp, WOLFSSL_EVP_PKEY **x, pem_password_cb *cb, void *u)
+{
+    (void)fp;
+    (void)x;
+    (void)cb;
+    (void)u;
+    WOLFSSL_STUB("PEM_read_PrivateKey");
+    return NULL;
+}
+#endif
+#endif
+
+#if !defined(NO_FILESYSTEM) && !defined(NO_WOLFSSL_DIR)
+/* Loads certificate(s) files in pem format into X509_STORE struct from either
+ * a file or directory.
+ * Returns WOLFSSL_SUCCESS on success or WOLFSSL_FAILURE if an error occurs.
+ */
+WOLFSSL_API int wolfSSL_X509_STORE_load_locations(WOLFSSL_X509_STORE *str,
+                                              const char *file, const char *dir)
+{
+    WOLFSSL_CTX* ctx;
+    char *name = NULL;
+    int ret = WOLFSSL_SUCCESS;
+    int successes = 0;
+#ifdef WOLFSSL_SMALL_STACK
+    ReadDirCtx* readCtx = NULL;
+#else
+    ReadDirCtx  readCtx[1];
+#endif
+
+    WOLFSSL_ENTER("X509_STORE_load_locations");
+
+    if (str == NULL || str->cm == NULL || (file == NULL  && dir == NULL))
+        return WOLFSSL_FAILURE;
+
+    /* tmp ctx for setting our cert manager */
+    ctx = wolfSSL_CTX_new(cm_pick_method());
+    if (ctx == NULL)
+        return WOLFSSL_FAILURE;
+
+    wolfSSL_CertManagerFree(ctx->cm);
+    ctx->cm = str->cm;
+
+#ifdef HAVE_CRL
+    if (str->cm->crl == NULL) {
+        if (wolfSSL_CertManagerEnableCRL(str->cm, 0) != WOLFSSL_SUCCESS) {
+            WOLFSSL_MSG("Enable CRL failed");
+            wolfSSL_CTX_free(ctx);
+            return WOLFSSL_FAILURE;
+        }
+    }
+#endif
+
+    /* Load individual file */
+    if (file) {
+        /* Try to process file with type DETECT_CERT_TYPE to parse the
+           correct certificate header and footer type */
+        ret = ProcessFile(ctx, file, WOLFSSL_FILETYPE_PEM, DETECT_CERT_TYPE,
+                                                      NULL, 0, str->cm->crl, 0);
+        if (ret != WOLFSSL_SUCCESS) {
+            WOLFSSL_MSG("Failed to load file");
+            ret = WOLFSSL_FAILURE;
+        }
+    }
+
+    /* Load files in dir */
+    if (dir && ret == WOLFSSL_SUCCESS) {
+        #ifdef WOLFSSL_SMALL_STACK
+            readCtx = (ReadDirCtx*)XMALLOC(sizeof(ReadDirCtx), ctx->heap,
+                                                       DYNAMIC_TYPE_TMP_BUFFER);
+            if (readCtx == NULL) {
+                WOLFSSL_MSG("Memory error");
+                return WOLFSSL_FAILURE;
+            }
+        #endif
+
+        /* try to load each regular file in dir */
+        ret = wc_ReadDirFirst(readCtx, dir, &name);
+        while (ret == 0 && name) {
+            WOLFSSL_MSG(name);
+            /* Try to process file with type DETECT_CERT_TYPE to parse the
+               correct certificate header and footer type */
+            ret = ProcessFile(ctx, name, WOLFSSL_FILETYPE_PEM, DETECT_CERT_TYPE,
+                                                      NULL, 0, str->cm->crl, 0);
+            /* Not failing on load errors */
+            if (ret != WOLFSSL_SUCCESS)
+                WOLFSSL_MSG("Failed to load file in path, continuing");
+            else
+                successes++;
+
+            ret = wc_ReadDirNext(readCtx, dir, &name);
+        }
+        wc_ReadDirClose(readCtx);
+
+        /* Success if at least one file in dir was loaded */
+        if (successes > 0)
+            ret = WOLFSSL_SUCCESS;
+        else {
+            WOLFSSL_ERROR(ret);
+            ret = WOLFSSL_FAILURE;
+        }
+
+        #ifdef WOLFSSL_SMALL_STACK
+            XFREE(readCtx, ctx->heap, DYNAMIC_TYPE_DIRCTX);
+        #endif
+    }
+
+    ctx->cm = NULL;
+    wolfSSL_CTX_free(ctx);
+
+    return ret;
+}
+#endif /* !NO_FILESYSTEM && !NO_WOLFSSL_DIR */
+
+#ifndef NO_WOLFSSL_STUB
+/*** TBD ***/
+WOLFSSL_API WOLFSSL_CIPHER* wolfSSL_sk_SSL_CIPHER_value(void *ciphers, int idx)
+{
+    (void)ciphers;
+    (void)idx;
+    WOLFSSL_STUB("wolfSSL_sk_SSL_CIPHER_value");
+    return NULL;
+}
+#endif
+
+WOLFSSL_API void ERR_load_SSL_strings(void)
+{
+
+}
+
+#ifdef HAVE_OCSP
+WOLFSSL_API long wolfSSL_get_tlsext_status_ocsp_resp(WOLFSSL *s, unsigned char **resp)
+{
+    if (s == NULL || resp == NULL)
+        return 0;
+
+    *resp = s->ocspResp;
+    return s->ocspRespSz;
+}
+
+WOLFSSL_API long wolfSSL_set_tlsext_status_ocsp_resp(WOLFSSL *s, unsigned char *resp, int len)
+{
+    if (s == NULL)
+        return WOLFSSL_FAILURE;
+
+    s->ocspResp   = resp;
+    s->ocspRespSz = len;
+
+    return WOLFSSL_SUCCESS;
+}
+#endif /* HAVE_OCSP */
+
+#endif /* OPENSSL_EXTRA */
+
+#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
+long wolfSSL_get_verify_result(const WOLFSSL *ssl)
+{
+    if (ssl == NULL) {
+        return WOLFSSL_FAILURE;
+    }
+
+    return ssl->peerVerifyRet;
+}
+#endif
+
+#ifdef OPENSSL_EXTRA
+
+#ifndef NO_WOLFSSL_STUB
+/* shows the number of accepts attempted by CTX in it's lifetime */
+long wolfSSL_CTX_sess_accept(WOLFSSL_CTX* ctx)
+{
+    WOLFSSL_STUB("wolfSSL_CTX_sess_accept");
+    (void)ctx;
+    return 0;
+}
+#endif
+
+#ifndef NO_WOLFSSL_STUB
+/* shows the number of connects attempted CTX in it's lifetime */
+long wolfSSL_CTX_sess_connect(WOLFSSL_CTX* ctx)
+{
+    WOLFSSL_STUB("wolfSSL_CTX_sess_connect");
+    (void)ctx;
+    return 0;
+}
+#endif
+
+
+#ifndef NO_WOLFSSL_STUB
+/* shows the number of accepts completed by CTX in it's lifetime */
+long wolfSSL_CTX_sess_accept_good(WOLFSSL_CTX* ctx)
+{
+    WOLFSSL_STUB("wolfSSL_CTX_sess_accept_good");
+    (void)ctx;
+    return 0;
+}
+#endif
+
+
+#ifndef NO_WOLFSSL_STUB
+/* shows the number of connects completed by CTX in it's lifetime */
+long wolfSSL_CTX_sess_connect_good(WOLFSSL_CTX* ctx)
+{
+    WOLFSSL_STUB("wolfSSL_CTX_sess_connect_good");
+    (void)ctx;
+    return 0;
+}
+#endif
+
+
+#ifndef NO_WOLFSSL_STUB
+/* shows the number of renegotiation accepts attempted by CTX */
+long wolfSSL_CTX_sess_accept_renegotiate(WOLFSSL_CTX* ctx)
+{
+    WOLFSSL_STUB("wolfSSL_CTX_sess_accept_renegotiate");
+    (void)ctx;
+    return 0;
+}
+#endif
+
+
+#ifndef NO_WOLFSSL_STUB
+/* shows the number of renegotiation accepts attempted by CTX */
+long wolfSSL_CTX_sess_connect_renegotiate(WOLFSSL_CTX* ctx)
+{
+    WOLFSSL_STUB("wolfSSL_CTX_sess_connect_renegotiate");
+    (void)ctx;
+    return 0;
+}
+#endif
+
+
+#ifndef NO_WOLFSSL_STUB
+long wolfSSL_CTX_sess_hits(WOLFSSL_CTX* ctx)
+{
+    WOLFSSL_STUB("wolfSSL_CTX_sess_hits");
+    (void)ctx;
+    return 0;
+}
+#endif
+
+
+#ifndef NO_WOLFSSL_STUB
+long wolfSSL_CTX_sess_cb_hits(WOLFSSL_CTX* ctx)
+{
+    WOLFSSL_STUB("wolfSSL_CTX_sess_cb_hits");
+    (void)ctx;
+    return 0;
+}
+#endif
+
+
+#ifndef NO_WOLFSSL_STUB
+long wolfSSL_CTX_sess_cache_full(WOLFSSL_CTX* ctx)
+{
+    WOLFSSL_STUB("wolfSSL_CTX_sess_cache_full");
+    (void)ctx;
+    return 0;
+}
+#endif
+
+
+#ifndef NO_WOLFSSL_STUB
+long wolfSSL_CTX_sess_misses(WOLFSSL_CTX* ctx)
+{
+    WOLFSSL_STUB("wolfSSL_CTX_sess_misses");
+    (void)ctx;
+    return 0;
+}
+#endif
+
+
+#ifndef NO_WOLFSSL_STUB
+long wolfSSL_CTX_sess_timeouts(WOLFSSL_CTX* ctx)
+{
+    WOLFSSL_STUB("wolfSSL_CTX_sess_timeouts");
+    (void)ctx;
+    return 0;
+}
+#endif
+
+
+/* Return the total number of sessions */
+long wolfSSL_CTX_sess_number(WOLFSSL_CTX* ctx)
+{
+    word32 total = 0;
+
+    WOLFSSL_ENTER("wolfSSL_CTX_sess_number");
+    (void)ctx;
+
+#ifdef WOLFSSL_SESSION_STATS
+    if (wolfSSL_get_session_stats(NULL, &total, NULL, NULL) != SSL_SUCCESS) {
+        WOLFSSL_MSG("Error getting session stats");
+    }
+#else
+    WOLFSSL_MSG("Please use macro WOLFSSL_SESSION_STATS for session stats");
+#endif
+
+    return (long)total;
+}
+
+
+#ifndef NO_CERTS
+long wolfSSL_CTX_add_extra_chain_cert(WOLFSSL_CTX* ctx, WOLFSSL_X509* x509)
+{
+    byte* chain = NULL;
+    long  chainSz = 0;
+    int   derSz;
+    const byte* der;
+    int   ret;
+    int   idx = 0;
+    DerBuffer *derBuffer = NULL;
+
+    WOLFSSL_ENTER("wolfSSL_CTX_add_extra_chain_cert");
+
+    if (ctx == NULL || x509 == NULL) {
+        WOLFSSL_MSG("Bad Argument");
+        return WOLFSSL_FAILURE;
+    }
+
+    der = wolfSSL_X509_get_der(x509, &derSz);
+    if (der == NULL || derSz <= 0) {
+        WOLFSSL_MSG("Error getting X509 DER");
+        return WOLFSSL_FAILURE;
+    }
+
+    if (ctx->certificate == NULL) {
+        WOLFSSL_ENTER("wolfSSL_use_certificate_chain_buffer_format");
+
+        /* Process buffer makes first certificate the leaf. */
+        ret = ProcessBuffer(ctx, der, derSz, WOLFSSL_FILETYPE_ASN1, CERT_TYPE,
+                            NULL, NULL, 1, GET_VERIFY_SETTING_CTX(ctx));
+        if (ret != WOLFSSL_SUCCESS) {
+            WOLFSSL_LEAVE("wolfSSL_CTX_add_extra_chain_cert", ret);
+            return WOLFSSL_FAILURE;
+        }
+    }
+    else {
+        /* TODO: Do this elsewhere. */
+        ret = AllocDer(&derBuffer, derSz, CERT_TYPE, ctx->heap);
+        if (ret != 0) {
+            WOLFSSL_MSG("Memory Error");
+            return WOLFSSL_FAILURE;
+        }
+        XMEMCPY(derBuffer->buffer, der, derSz);
+        ret = AddCA(ctx->cm, &derBuffer, WOLFSSL_USER_CA,
+            GET_VERIFY_SETTING_CTX(ctx));
+        if (ret != WOLFSSL_SUCCESS) {
+            WOLFSSL_LEAVE("wolfSSL_CTX_add_extra_chain_cert", ret);
+            return WOLFSSL_FAILURE;
+        }
+
+        /* adding cert to existing chain */
+        if (ctx->certChain != NULL && ctx->certChain->length > 0) {
+            chainSz += ctx->certChain->length;
+        }
+        chainSz += OPAQUE24_LEN + derSz;
+
+        chain = (byte*)XMALLOC(chainSz, ctx->heap, DYNAMIC_TYPE_DER);
+        if (chain == NULL) {
+            WOLFSSL_MSG("Memory Error");
+            return WOLFSSL_FAILURE;
+        }
+
+        if (ctx->certChain != NULL && ctx->certChain->length > 0) {
+            XMEMCPY(chain, ctx->certChain->buffer, ctx->certChain->length);
+            idx = ctx->certChain->length;
+        }
+        c32to24(derSz, chain + idx);
+        idx += OPAQUE24_LEN,
+        XMEMCPY(chain + idx, der, derSz);
+        idx += derSz;
+#ifdef WOLFSSL_TLS13
+        ctx->certChainCnt++;
+#endif
+
+        FreeDer(&ctx->certChain);
+        ret = AllocDer(&ctx->certChain, idx, CERT_TYPE, ctx->heap);
+        if (ret == 0) {
+            XMEMCPY(ctx->certChain->buffer, chain, idx);
+        }
+    }
+
+    /* on success WOLFSSL_X509 memory is responsibility of ctx */
+    wolfSSL_X509_free(x509);
+    if (chain != NULL)
+        XFREE(chain, ctx->heap, DYNAMIC_TYPE_DER);
+
+    return WOLFSSL_SUCCESS;
+}
+
+
+long wolfSSL_CTX_set_tlsext_status_arg(WOLFSSL_CTX* ctx, void* arg)
+{
+    if (ctx == NULL || ctx->cm == NULL) {
+        return WOLFSSL_FAILURE;
+    }
+
+    ctx->cm->ocspIOCtx = arg;
+    return WOLFSSL_SUCCESS;
+}
+
+#endif /* NO_CERTS */
+
+
+/* Get the session cache mode for CTX
+ *
+ * ctx  WOLFSSL_CTX struct to get cache mode from
+ *
+ * Returns a bit mask that has the session cache mode */
+WOLFSSL_API long wolfSSL_CTX_get_session_cache_mode(WOLFSSL_CTX* ctx)
+{
+    long m = 0;
+
+    WOLFSSL_ENTER("SSL_CTX_set_session_cache_mode");
+
+    if (ctx == NULL) {
+        return m;
+    }
+
+    if (ctx->sessionCacheOff != 1) {
+        m |= SSL_SESS_CACHE_SERVER;
+    }
+
+    if (ctx->sessionCacheFlushOff == 1) {
+        m |= SSL_SESS_CACHE_NO_AUTO_CLEAR;
+    }
+
+#ifdef HAVE_EXT_CACHE
+    if (ctx->internalCacheOff == 1) {
+        m |= SSL_SESS_CACHE_NO_INTERNAL_STORE;
+    }
+#endif
+
+    return m;
+}
+
+
+int wolfSSL_CTX_get_read_ahead(WOLFSSL_CTX* ctx)
+{
+    if (ctx == NULL) {
+        return WOLFSSL_FAILURE;
+    }
+
+    return ctx->readAhead;
+}
+
+
+int wolfSSL_CTX_set_read_ahead(WOLFSSL_CTX* ctx, int v)
+{
+    if (ctx == NULL) {
+        return WOLFSSL_FAILURE;
+    }
+
+    ctx->readAhead = (byte)v;
+
+    return WOLFSSL_SUCCESS;
+}
+
+
+long wolfSSL_CTX_set_tlsext_opaque_prf_input_callback_arg(WOLFSSL_CTX* ctx,
+        void* arg)
+{
+    if (ctx == NULL) {
+        return WOLFSSL_FAILURE;
+    }
+
+    ctx->userPRFArg = arg;
+    return WOLFSSL_SUCCESS;
+}
+
+
+#ifndef NO_DES3
+/* 0 on success */
+int wolfSSL_DES_set_key(WOLFSSL_const_DES_cblock* myDes,
+                                               WOLFSSL_DES_key_schedule* key)
+{
+#ifdef WOLFSSL_CHECK_DESKEY
+    return wolfSSL_DES_set_key_checked(myDes, key);
+#else
+    wolfSSL_DES_set_key_unchecked(myDes, key);
+    return 0;
+#endif
+}
+
+
+
+/* return true in fail case (1) */
+static int DES_check(word32 mask, word32 mask2, unsigned char* key)
+{
+    word32 value[2];
+
+    /* sanity check on length made in wolfSSL_DES_set_key_checked */
+    value[0] = mask;
+    value[1] = mask2;
+    return (XMEMCMP(value, key, sizeof(value)) == 0)? 1: 0;
+}
+
+
+/* check that the key is odd parity and is not a weak key
+ * returns -1 if parity is wrong, -2 if weak/null key and 0 on success */
+int wolfSSL_DES_set_key_checked(WOLFSSL_const_DES_cblock* myDes,
+                                               WOLFSSL_DES_key_schedule* key)
+{
+    if (myDes == NULL || key == NULL) {
+        WOLFSSL_MSG("Bad argument passed to wolfSSL_DES_set_key_checked");
+        return -2;
+    }
+    else {
+        word32 sz = sizeof(WOLFSSL_DES_key_schedule);
+
+        /* sanity check before call to DES_check */
+        if (sz != (sizeof(word32) * 2)) {
+            WOLFSSL_MSG("Unexpected WOLFSSL_DES_key_schedule size");
+            return -2;
+        }
+
+        /* check odd parity */
+        if (wolfSSL_DES_check_key_parity(myDes) != 1) {
+            WOLFSSL_MSG("Odd parity test fail");
+            return -1;
+        }
+
+        if (wolfSSL_DES_is_weak_key(myDes) == 1) {
+            WOLFSSL_MSG("Weak key found");
+            return -2;
+        }
+
+        /* passed tests, now copy over key */
+        XMEMCPY(key, myDes, sizeof(WOLFSSL_const_DES_cblock));
+
+        return 0;
+    }
+}
+
+
+/* check is not weak. Weak key list from Nist "Recommendation for the Triple
+ * Data Encryption Algorithm (TDEA) Block Cipher"
+ *
+ * returns 1 if is weak 0 if not
+ */
+int wolfSSL_DES_is_weak_key(WOLFSSL_const_DES_cblock* key)
+{
+    word32 mask, mask2;
+
+    WOLFSSL_ENTER("wolfSSL_DES_is_weak_key");
+
+    if (key == NULL) {
+        WOLFSSL_MSG("NULL key passed in");
+        return 1;
+    }
+
+    mask = 0x01010101; mask2 = 0x01010101;
+    if (DES_check(mask, mask2, *key)) {
+        WOLFSSL_MSG("Weak key found");
+        return 1;
+    }
+
+    mask = 0xFEFEFEFE; mask2 = 0xFEFEFEFE;
+    if (DES_check(mask, mask2, *key)) {
+        WOLFSSL_MSG("Weak key found");
+        return 1;
+    }
+
+    mask = 0xE0E0E0E0; mask2 = 0xF1F1F1F1;
+    if (DES_check(mask, mask2, *key)) {
+        WOLFSSL_MSG("Weak key found");
+        return 1;
+    }
+
+    mask = 0x1F1F1F1F; mask2 = 0x0E0E0E0E;
+    if (DES_check(mask, mask2, *key)) {
+        WOLFSSL_MSG("Weak key found");
+        return 1;
+    }
+
+    /* semi-weak *key check (list from same Nist paper) */
+    mask  = 0x011F011F; mask2 = 0x010E010E;
+    if (DES_check(mask, mask2, *key) ||
+       DES_check(ByteReverseWord32(mask), ByteReverseWord32(mask2), *key)) {
+        WOLFSSL_MSG("Weak key found");
+        return 1;
+    }
+
+    mask  = 0x01E001E0; mask2 = 0x01F101F1;
+    if (DES_check(mask, mask2, *key) ||
+       DES_check(ByteReverseWord32(mask), ByteReverseWord32(mask2), *key)) {
+        WOLFSSL_MSG("Weak key found");
+        return 1;
+    }
+
+    mask  = 0x01FE01FE; mask2 = 0x01FE01FE;
+    if (DES_check(mask, mask2, *key) ||
+       DES_check(ByteReverseWord32(mask), ByteReverseWord32(mask2), *key)) {
+        WOLFSSL_MSG("Weak key found");
+        return 1;
+    }
+
+    mask  = 0x1FE01FE0; mask2 = 0x0EF10EF1;
+    if (DES_check(mask, mask2, *key) ||
+       DES_check(ByteReverseWord32(mask), ByteReverseWord32(mask2), *key)) {
+        WOLFSSL_MSG("Weak key found");
+        return 1;
+    }
+
+    mask  = 0x1FFE1FFE; mask2 = 0x0EFE0EFE;
+    if (DES_check(mask, mask2, *key) ||
+       DES_check(ByteReverseWord32(mask), ByteReverseWord32(mask2), *key)) {
+        WOLFSSL_MSG("Weak key found");
+        return 1;
+    }
+
+    return 0;
+}
+
+
+void wolfSSL_DES_set_key_unchecked(WOLFSSL_const_DES_cblock* myDes,
+                                               WOLFSSL_DES_key_schedule* key)
+{
+    if (myDes != NULL && key != NULL) {
+        XMEMCPY(key, myDes, sizeof(WOLFSSL_const_DES_cblock));
+    }
+}
+
+
+/* Sets the parity of the DES key for use */
+void wolfSSL_DES_set_odd_parity(WOLFSSL_DES_cblock* myDes)
+{
+    word32 i;
+    word32 sz = sizeof(WOLFSSL_DES_cblock);
+
+    WOLFSSL_ENTER("wolfSSL_DES_set_odd_parity");
+
+    for (i = 0; i < sz; i++) {
+        unsigned char c = (*myDes)[i];
+        if ((
+            ((c >> 1) & 0x01) ^
+            ((c >> 2) & 0x01) ^
+            ((c >> 3) & 0x01) ^
+            ((c >> 4) & 0x01) ^
+            ((c >> 5) & 0x01) ^
+            ((c >> 6) & 0x01) ^
+            ((c >> 7) & 0x01)) == (c & 0x01)) {
+            WOLFSSL_MSG("Flipping parity bit");
+            (*myDes)[i] = c ^ 0x01;
+        }
+    }
+}
+
+int wolfSSL_DES_check_key_parity(WOLFSSL_DES_cblock *myDes)
+{
+    word32 i;
+    word32 sz = sizeof(WOLFSSL_DES_cblock);
+
+    WOLFSSL_ENTER("wolfSSL_DES_check_key_parity");
+
+    for (i = 0; i < sz; i++) {
+        unsigned char c = (*myDes)[i];
+        if ((
+            ((c >> 1) & 0x01) ^
+            ((c >> 2) & 0x01) ^
+            ((c >> 3) & 0x01) ^
+            ((c >> 4) & 0x01) ^
+            ((c >> 5) & 0x01) ^
+            ((c >> 6) & 0x01) ^
+            ((c >> 7) & 0x01)) == (c & 0x01)) {
+            return 0;
+        }
+    }
+    return 1;
+}
+
+#ifdef WOLFSSL_DES_ECB
+/* Encrypt or decrypt input message desa with key and get output in desb.
+ * if enc is DES_ENCRYPT,input message is encrypted or
+ * if enc is DES_DECRYPT,input message is decrypted.
+ * */
+void wolfSSL_DES_ecb_encrypt(WOLFSSL_DES_cblock* desa,
+             WOLFSSL_DES_cblock* desb, WOLFSSL_DES_key_schedule* key, int enc)
+{
+    Des myDes;
+
+    WOLFSSL_ENTER("wolfSSL_DES_ecb_encrypt");
+
+    if (desa == NULL || key == NULL || desb == NULL ||
+        (enc != DES_ENCRYPT && enc != DES_DECRYPT)) {
+        WOLFSSL_MSG("Bad argument passed to wolfSSL_DES_ecb_encrypt");
+    } else {
+        if (wc_Des_SetKey(&myDes, (const byte*) key,
+                           (const byte*) NULL, !enc) != 0) {
+            WOLFSSL_MSG("wc_Des_SetKey return error.");
+            return;
+        }
+        if (enc){
+            if (wc_Des_EcbEncrypt(&myDes, (byte*) desb, (const byte*) desa,
+                        sizeof(WOLFSSL_DES_cblock)) != 0){
+                WOLFSSL_MSG("wc_Des_EcbEncrypt return error.");
+            }
+        } else {
+            if (wc_Des_EcbDecrypt(&myDes, (byte*) desb, (const byte*) desa,
+                        sizeof(WOLFSSL_DES_cblock)) != 0){
+                WOLFSSL_MSG("wc_Des_EcbDecrpyt return error.");
+            }
+        }
+    }
+}
+#endif
+#endif /* NO_DES3 */
+
+#ifndef NO_RC4
+/* Set the key state for Arc4 structure.
+ *
+ * key  Arc4 structure to use
+ * len  length of data buffer
+ * data initial state to set Arc4 structure
+ */
+void wolfSSL_RC4_set_key(WOLFSSL_RC4_KEY* key, int len,
+        const unsigned char* data)
+{
+    typedef char rc4_test[sizeof(WOLFSSL_RC4_KEY) >= sizeof(Arc4) ? 1 : -1];
+    (void)sizeof(rc4_test);
+
+    WOLFSSL_ENTER("wolfSSL_RC4_set_key");
+
+    if (key == NULL || len < 0) {
+        WOLFSSL_MSG("bad argument passed in");
+        return;
+    }
+
+    XMEMSET(key, 0, sizeof(WOLFSSL_RC4_KEY));
+    wc_Arc4SetKey((Arc4*)key, data, (word32)len);
+}
+
+
+/* Encrypt/decrypt with Arc4 structure.
+ *
+ * len length of buffer to encrypt/decrypt (in/out)
+ * in  buffer to encrypt/decrypt
+ * out results of encryption/decryption
+ */
+void wolfSSL_RC4(WOLFSSL_RC4_KEY* key, size_t len,
+        const unsigned char* in, unsigned char* out)
+{
+    WOLFSSL_ENTER("wolfSSL_RC4");
+
+    if (key == NULL || in == NULL || out == NULL) {
+        WOLFSSL_MSG("Bad argument passed in");
+        return;
+    }
+
+    wc_Arc4Process((Arc4*)key, out, in, (word32)len);
+}
+#endif /* NO_RC4 */
+
+#ifndef NO_AES
+
+#ifdef WOLFSSL_AES_DIRECT
+/* AES encrypt direct, it is expected to be blocks of AES_BLOCK_SIZE for input.
+ *
+ * input  Data to encrypt
+ * output Encrypted data after done
+ * key    AES key to use for encryption
+ */
+void wolfSSL_AES_encrypt(const unsigned char* input, unsigned char* output,
+        AES_KEY *key)
+{
+    WOLFSSL_ENTER("wolfSSL_AES_encrypt");
+
+    if (input == NULL || output == NULL || key == NULL) {
+        WOLFSSL_MSG("Null argument passed in");
+        return;
+    }
+
+    wc_AesEncryptDirect((Aes*)key, output, input);
+}
+
+
+/* AES decrypt direct, it is expected to be blocks of AES_BLOCK_SIZE for input.
+ *
+ * input  Data to decrypt
+ * output Decrypted data after done
+ * key    AES key to use for encryption
+ */
+void wolfSSL_AES_decrypt(const unsigned char* input, unsigned char* output,
+        AES_KEY *key)
+{
+    WOLFSSL_ENTER("wolfSSL_AES_decrypt");
+
+    if (input == NULL || output == NULL || key == NULL) {
+        WOLFSSL_MSG("Null argument passed in");
+        return;
+    }
+
+    wc_AesDecryptDirect((Aes*)key, output, input);
+}
+#endif /* WOLFSSL_AES_DIRECT */
+
+/* Setup of an AES key to use for encryption.
+ *
+ * key  key in bytes to use for encryption
+ * bits size of key in bits
+ * aes  AES structure to initialize
+ */
+int wolfSSL_AES_set_encrypt_key(const unsigned char *key, const int bits,
+        AES_KEY *aes)
+{
+    typedef char aes_test[sizeof(AES_KEY) >= sizeof(Aes) ? 1 : -1];
+    (void)sizeof(aes_test);
+
+    WOLFSSL_ENTER("wolfSSL_AES_set_encrypt_key");
+
+    if (key == NULL || aes == NULL) {
+        WOLFSSL_MSG("Null argument passed in");
+        return -1;
+    }
+
+    XMEMSET(aes, 0, sizeof(AES_KEY));
+    if (wc_AesSetKey((Aes*)aes, key, ((bits)/8), NULL, AES_ENCRYPTION) != 0) {
+        WOLFSSL_MSG("Error in setting AES key");
+        return -1;
+    }
+    return 0;
+}
+
+
+/* Setup of an AES key to use for decryption.
+ *
+ * key  key in bytes to use for decryption
+ * bits size of key in bits
+ * aes  AES structure to initialize
+ */
+int wolfSSL_AES_set_decrypt_key(const unsigned char *key, const int bits,
+        AES_KEY *aes)
+{
+    typedef char aes_test[sizeof(AES_KEY) >= sizeof(Aes) ? 1 : -1];
+    (void)sizeof(aes_test);
+
+    WOLFSSL_ENTER("wolfSSL_AES_set_decrypt_key");
+
+    if (key == NULL || aes == NULL) {
+        WOLFSSL_MSG("Null argument passed in");
+        return -1;
+    }
+
+    XMEMSET(aes, 0, sizeof(AES_KEY));
+    if (wc_AesSetKey((Aes*)aes, key, ((bits)/8), NULL, AES_DECRYPTION) != 0) {
+        WOLFSSL_MSG("Error in setting AES key");
+        return -1;
+    }
+    return 0;
+}
+
+
+#ifdef HAVE_AES_ECB
+/* Encrypt/decrypt a 16 byte block of data using the key passed in.
+ *
+ * in  buffer to encrypt/decrypt
+ * out buffer to hold result of encryption/decryption
+ * key AES structure to use with encryption/decryption
+ * enc AES_ENCRPT for encryption and AES_DECRYPT for decryption
+ */
+void wolfSSL_AES_ecb_encrypt(const unsigned char *in, unsigned char* out,
+                             AES_KEY *key, const int enc)
+{
+    Aes* aes;
+
+    WOLFSSL_ENTER("wolfSSL_AES_ecb_encrypt");
+
+    if (key == NULL || in == NULL || out == NULL) {
+        WOLFSSL_MSG("Error, Null argument passed in");
+        return;
+    }
+
+    aes = (Aes*)key;
+    if (enc == AES_ENCRYPT) {
+        if (wc_AesEcbEncrypt(aes, out, in, AES_BLOCK_SIZE) != 0) {
+            WOLFSSL_MSG("Error with AES CBC encrypt");
+        }
+    }
+    else {
+    #ifdef HAVE_AES_DECRYPT
+        if (wc_AesEcbDecrypt(aes, out, in, AES_BLOCK_SIZE) != 0) {
+            WOLFSSL_MSG("Error with AES CBC decrypt");
+        }
+    #else
+        WOLFSSL_MSG("AES decryption not compiled in");
+    #endif
+    }
+}
+#endif /* HAVE_AES_ECB */
+
+#ifdef HAVE_AES_CBC
+/* Encrypt data using key and iv passed in. iv gets updated to most recent iv
+ * state after encryption/decryption.
+ *
+ * in  buffer to encrypt/decrypt
+ * out buffer to hold result of encryption/decryption
+ * len length of input buffer
+ * key AES structure to use with encryption/decryption
+ * iv  iv to use with operation
+ * enc AES_ENCRPT for encryption and AES_DECRYPT for decryption
+ */
+void wolfSSL_AES_cbc_encrypt(const unsigned char *in, unsigned char* out,
+        size_t len, AES_KEY *key, unsigned char* iv, const int enc)
+{
+    Aes* aes;
+
+    WOLFSSL_ENTER("wolfSSL_AES_cbc_encrypt");
+
+    if (key == NULL || in == NULL || out == NULL || iv == NULL || len == 0) {
+        WOLFSSL_MSG("Error, Null argument passed in");
+        return;
+    }
+
+    aes = (Aes*)key;
+    if (wc_AesSetIV(aes, (const byte*)iv) != 0) {
+        WOLFSSL_MSG("Error with setting iv");
+        return;
+    }
+
+    if (enc == AES_ENCRYPT) {
+        if (wc_AesCbcEncrypt(aes, out, in, (word32)len) != 0) {
+            WOLFSSL_MSG("Error with AES CBC encrypt");
+        }
+    }
+    else {
+        if (wc_AesCbcDecrypt(aes, out, in, (word32)len) != 0) {
+            WOLFSSL_MSG("Error with AES CBC decrypt");
+        }
+    }
+
+    /* to be compatible copy iv to iv buffer after completing operation */
+    XMEMCPY(iv, (byte*)(aes->reg), AES_BLOCK_SIZE);
+}
+#endif /* HAVE_AES_CBC */
+
+
+/* Encrypt data using CFB mode with key and iv passed in. iv gets updated to
+ * most recent iv state after encryption/decryption.
+ *
+ * in  buffer to encrypt/decrypt
+ * out buffer to hold result of encryption/decryption
+ * len length of input buffer
+ * key AES structure to use with encryption/decryption
+ * iv  iv to use with operation
+ * num contains the amount of block used
+ * enc AES_ENCRPT for encryption and AES_DECRYPT for decryption
+ */
+void wolfSSL_AES_cfb128_encrypt(const unsigned char *in, unsigned char* out,
+        size_t len, AES_KEY *key, unsigned char* iv, int* num,
+        const int enc)
+{
+#ifndef WOLFSSL_AES_CFB
+    WOLFSSL_MSG("CFB mode not enabled please use macro WOLFSSL_AES_CFB");
+    (void)in;
+    (void)out;
+    (void)len;
+    (void)key;
+    (void)iv;
+    (void)num;
+    (void)enc;
+
+    return;
+#else
+    Aes* aes;
+
+    WOLFSSL_ENTER("wolfSSL_AES_cbc_encrypt");
+    if (key == NULL || in == NULL || out == NULL || iv == NULL) {
+        WOLFSSL_MSG("Error, Null argument passed in");
+        return;
+    }
+
+    aes = (Aes*)key;
+    if (wc_AesSetIV(aes, (const byte*)iv) != 0) {
+        WOLFSSL_MSG("Error with setting iv");
+        return;
+    }
+
+    if (enc == AES_ENCRYPT) {
+        if (wc_AesCfbEncrypt(aes, out, in, (word32)len) != 0) {
+            WOLFSSL_MSG("Error with AES CBC encrypt");
+        }
+    }
+    else {
+        if (wc_AesCfbDecrypt(aes, out, in, (word32)len) != 0) {
+            WOLFSSL_MSG("Error with AES CBC decrypt");
+        }
+    }
+
+    /* to be compatible copy iv to iv buffer after completing operation */
+    XMEMCPY(iv, (byte*)(aes->reg), AES_BLOCK_SIZE);
+
+    /* store number of left over bytes to num */
+    *num = (aes->left)? AES_BLOCK_SIZE - aes->left : 0;
+#endif /* WOLFSSL_AES_CFB */
+}
+#endif /* NO_AES */
+
+#ifndef NO_FILESYSTEM
+    #ifdef __clang__
+        #pragma clang diagnostic push
+        #pragma clang diagnostic ignored "-Wformat-nonliteral"
+    #endif
+#endif
+
+#if !defined(NO_FILESYSTEM) && defined (OPENSSL_EXTRA)
+/* returns amount printed on success, negative in fail case */
+int wolfSSL_BIO_vprintf(WOLFSSL_BIO* bio, const char* format, va_list args)
+{
+    int ret = -1;
+
+    if (bio == NULL)
+        return WOLFSSL_FATAL_ERROR;
+
+    switch (bio->type) {
+        case WOLFSSL_BIO_FILE:
+            if (bio->ptr == NULL) {
+                va_end(args);
+                return -1;
+            }
+            ret = vfprintf((XFILE)bio->ptr, format, args);
+            break;
+
+        case WOLFSSL_BIO_MEMORY:
+    #if defined(OPENSSL_EXTRA) && !defined(_WIN32)
+        case WOLFSSL_BIO_SSL:
+            {
+                int count;
+                char* pt = NULL;
+                va_list copy;
+
+                va_copy(copy, args);
+                count = vsnprintf(NULL, 0, format, args);
+                if (count >= 0)
+                {
+                    pt = (char*)XMALLOC(count + 1, bio->heap,
+                                        DYNAMIC_TYPE_TMP_BUFFER);
+                    if (pt != NULL)
+                    {
+                        count = vsnprintf(pt, count + 1, format, copy);
+                        if (count >= 0)
+                        {
+                            ret = wolfSSL_BIO_write(bio, pt, count);
+                        }
+                        XFREE(pt, bio->heap, DYNAMIC_TYPE_TMP_BUFFER);
+                    }
+                }
+                va_end(copy);
+            }
+            break;
+    #endif
+
+        default:
+            WOLFSSL_MSG("Unsupported WOLFSSL_BIO type for wolfSSL_BIO_printf");
+            break;
+    }
+
+    return ret;
+}
+
+/* returns amount printed on success, negative in fail case */
+int wolfSSL_BIO_printf(WOLFSSL_BIO* bio, const char* format, ...)
+{
+    int ret;
+    va_list args;
+    va_start(args, format);
+
+    ret = wolfSSL_BIO_vprintf(bio, format, args);
+
+    va_end(args);
+
+    return ret;
+}
+
+#endif /* !defined(NO_FILESYSTEM) && defined (OPENSSL_EXTRA) */
+
+#if !defined(NO_FILESYSTEM) && defined(__clang__)
+#pragma clang diagnostic pop
+#endif
+
+#undef  LINE_LEN
+#define LINE_LEN 16
+int wolfSSL_BIO_dump(WOLFSSL_BIO *bio, const char *buf, int length)
+{
+    int ret = 0;
+
+    if (bio == NULL)
+        return 0;
+
+#ifndef NO_FILESYSTEM
+    if (bio->type == WOLFSSL_BIO_FILE) {
+        int i;
+        char line[80];
+
+        if (!buf) {
+            return fputs("\tNULL", (XFILE)bio->ptr);
+        }
+
+        sprintf(line, "\t");
+        for (i = 0; i < LINE_LEN; i++) {
+            if (i < length)
+                sprintf(line + 1 + i * 3,"%02x ", buf[i]);
+            else
+                sprintf(line + 1 + i * 3, "   ");
+        }
+        sprintf(line + 1 + LINE_LEN * 3, "| ");
+        for (i = 0; i < LINE_LEN; i++) {
+            if (i < length) {
+                sprintf(line + 3 + LINE_LEN * 3 + i,
+                     "%c", 31 < buf[i] && buf[i] < 127 ? buf[i] : '.');
+            }
+        }
+        ret += fputs(line, (XFILE)bio->ptr);
+
+        if (length > LINE_LEN)
+            ret += wolfSSL_BIO_dump(bio, buf + LINE_LEN, length - LINE_LEN);
+    }
+#else
+    (void)buf;
+    (void)length;
+#endif
+
+    return ret;
+}
+
+#ifndef NO_ASN_TIME
+int wolfSSL_ASN1_UTCTIME_print(WOLFSSL_BIO* bio, const WOLFSSL_ASN1_UTCTIME* a)
+{
+    WOLFSSL_ENTER("ASN1_UTCTIME_print");
+    if (bio == NULL || a == NULL) {
+        return WOLFSSL_FAILURE;
+    }
+    if (a->type != ASN_UTC_TIME) {
+        WOLFSSL_MSG("Error, not UTC_TIME");
+        return WOLFSSL_FAILURE;
+    }
+
+    return wolfSSL_ASN1_TIME_print(bio, a);
+}
+
+/* Checks the ASN1 syntax of "a"
+ * returns WOLFSSL_SUCCESS (1)  if correct otherwise WOLFSSL_FAILURE (0) */
+int wolfSSL_ASN1_TIME_check(const WOLFSSL_ASN1_TIME* a)
+{
+    char buf[MAX_TIME_STRING_SZ];
+
+    WOLFSSL_ENTER("wolfSSL_ASN1_TIME_check");
+
+    /* if can parse the WOLFSSL_ASN1_TIME passed in then consider syntax good */
+    if (wolfSSL_ASN1_TIME_to_string((WOLFSSL_ASN1_TIME*)a, buf,
+                MAX_TIME_STRING_SZ) == NULL) {
+        return WOLFSSL_FAILURE;
+    }
+    return WOLFSSL_SUCCESS;
+}
+#endif /* !NO_ASN_TIME */
+
+#ifndef NO_WOLFSSL_STUB
+int wolfSSL_ASN1_TIME_diff(int *pday, int *psec,
+                   const WOLFSSL_ASN1_TIME *from, const WOLFSSL_ASN1_TIME *to)
+{
+    WOLFSSL_STUB("wolfSSL_ASN1_TIME_diff");
+    (void)pday;
+    (void)psec;
+    (void)from;
+    (void)to;
+    return 0;
+}
+
+WOLFSSL_API WOLFSSL_ASN1_TIME *wolfSSL_ASN1_TIME_set(WOLFSSL_ASN1_TIME *s, time_t t)
+{
+    WOLFSSL_STUB("wolfSSL_ASN1_TIME_set");
+    (void)s;
+    (void)t;
+    return s;
+}
+#endif /* !NO_WOLFSSL_STUB */
+
+/* Return the month as a string.
+ *
+ * n  The number of the month as a two characters (1 based).
+ * returns the month as a string.
+ */
+static WC_INLINE const char* MonthStr(const char* n)
+{
+    static const char monthStr[12][4] = {
+            "Jan", "Feb", "Mar", "Apr", "May", "Jun",
+            "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
+    return monthStr[(n[0] - '0') * 10 + (n[1] - '0') - 1];
+}
+
+int wolfSSL_ASN1_GENERALIZEDTIME_print(WOLFSSL_BIO* bio,
+    const WOLFSSL_ASN1_GENERALIZEDTIME* asnTime)
+{
+    const char* p;
+    WOLFSSL_ENTER("wolfSSL_ASN1_GENERALIZEDTIME_print");
+
+    if (bio == NULL || asnTime == NULL)
+        return BAD_FUNC_ARG;
+
+    if (asnTime->type != ASN_GENERALIZED_TIME) {
+        WOLFSSL_MSG("Error, not GENERALIZED_TIME");
+        return WOLFSSL_FAILURE;
+    }
+    p = (const char *)(asnTime->data);
+    /* GetTimeString not always available. */
+    wolfSSL_BIO_write(bio, MonthStr(p + 4), 3);
+    wolfSSL_BIO_write(bio, " ", 1);
+    /* Day */
+    wolfSSL_BIO_write(bio, p + 6, 2);
+    wolfSSL_BIO_write(bio, " ", 1);
+    /* Hour */
+    wolfSSL_BIO_write(bio, p + 8, 2);
+    wolfSSL_BIO_write(bio, ":", 1);
+    /* Min */
+    wolfSSL_BIO_write(bio, p + 10, 2);
+    wolfSSL_BIO_write(bio, ":", 1);
+    /* Secs */
+    wolfSSL_BIO_write(bio, p + 12, 2);
+    wolfSSL_BIO_write(bio, " ", 1);
+    wolfSSL_BIO_write(bio, p, 4);
+
+    return 0;
+}
+
+void wolfSSL_ASN1_GENERALIZEDTIME_free(WOLFSSL_ASN1_TIME* asn1Time)
+{
+    WOLFSSL_ENTER("wolfSSL_ASN1_GENERALIZEDTIME_free");
+    if (asn1Time == NULL)
+        return;
+    XMEMSET(asn1Time->data, 0, sizeof(asn1Time->data));
+}
+
+int wolfSSL_sk_num(WOLFSSL_STACK* sk)
+{
+    WOLFSSL_ENTER("wolfSSL_sk_num");
+    if (sk == NULL)
+        return 0;
+    return (int)sk->num;
+}
+
+void* wolfSSL_sk_value(WOLFSSL_STACK* sk, int i)
+{
+#if defined(OPENSSL_ALL) || defined(WOLFSSL_QT)
+    int offset = i;
+#endif
+    WOLFSSL_ENTER("wolfSSL_sk_value");
+
+    for (; sk != NULL && i > 0; i--)
+        sk = sk->next;
+    if (sk == NULL)
+        return NULL;
+
+    switch (sk->type) {
+        case STACK_TYPE_X509:
+            return (void*)sk->data.x509;
+        case STACK_TYPE_CIPHER:
+        #if defined(OPENSSL_ALL) || defined(WOLFSSL_QT)
+            sk->data.cipher.offset = offset;
+        #endif
+            return (void*)&sk->data.cipher;
+        case STACK_TYPE_GEN_NAME:
+            return (void*)sk->data.gn;
+        case STACK_TYPE_ACCESS_DESCRIPTION:
+            return (void*)sk->data.access;
+        case STACK_TYPE_OBJ:
+            return (void*)sk->data.obj;
+        case STACK_TYPE_X509_EXT:
+            return (void*)sk->data.ext;
+        case STACK_TYPE_CONF_VALUE:
+            return (void*)sk->data.conf->value;
+        case STACK_TYPE_NULL:
+        default:
+            return (void*)sk->data.generic;
+    }
+}
+
+/* Free the structure for ASN1_OBJECT stack */
+void wolfSSL_sk_free(WOLFSSL_STACK* sk)
+{
+    WOLFSSL_ENTER("wolfSSL_sk_free");
+
+    if (sk == NULL) {
+        WOLFSSL_MSG("Error, BAD_FUNC_ARG");
+        return;
+    }
+
+    switch (sk->type) {
+        case STACK_TYPE_X509:
+            wolfSSL_sk_X509_free(sk);
+            break;
+        #if defined(OPENSSL_ALL)
+        case STACK_TYPE_CIPHER:
+            wolfSSL_sk_CIPHER_free(sk);
+            break;
+        #endif
+        case STACK_TYPE_GEN_NAME:
+            wolfSSL_sk_GENERAL_NAME_free(sk);
+            break;
+        #if defined(OPENSSL_ALL) || defined (WOLFSSL_QT)
+        case STACK_TYPE_ACCESS_DESCRIPTION:
+            wolfSSL_sk_ACCESS_DESCRIPTION_free(sk);
+            break;
+        #endif
+        case STACK_TYPE_OBJ:
+            wolfSSL_sk_ASN1_OBJECT_free(sk);
+            break;
+        #ifdef OPENSSL_ALL
+        case STACK_TYPE_X509_INFO:
+            wolfSSL_sk_X509_INFO_free(sk);
+            break;
+        case STACK_TYPE_X509_NAME:
+            wolfSSL_sk_X509_NAME_free(sk);
+            break;
+        case STACK_TYPE_CONF_VALUE:
+            wolfSSL_sk_CONF_VALUE_free(sk);
+            break;
+        #endif
+        case STACK_TYPE_NULL:
+        default:
+            wolfSSL_sk_GENERIC_free(sk);
+    }
+}
+/* Frees each node in the stack and frees the stack.
+ * Does not free any internal members of the stack nodes.
+ */
+void wolfSSL_sk_GENERIC_pop_free(WOLFSSL_STACK* sk,
+    void (*f) (void*))
+{
+    WOLFSSL_STACK* node;
+    WOLFSSL_STACK* tmp;
+    WOLFSSL_ENTER("wolfSSL_sk_GENERIC_pop_free");
+
+    if (sk == NULL)
+        return;
+
+    /* parse through stack freeing each node */
+    node = sk->next;
+    while (node) {
+        tmp  = node;
+        node = node->next;
+        if (f)
+            f(tmp->data.generic);
+        tmp->data.generic = NULL;
+        XFREE(tmp, NULL, DYNAMIC_TYPE_OPENSSL);
+    }
+
+    /* free head of stack */
+    XFREE(sk, NULL, DYNAMIC_TYPE_ASN1);
+}
+
+/* return 1 on success 0 on fail */
+int wolfSSL_sk_GENERIC_push(WOLFSSL_STACK* sk, void* generic)
+{
+    WOLFSSL_STACK* node;
+
+    WOLFSSL_ENTER("wolfSSL_sk_GENERIC_push");
+
+    if (sk == NULL || generic == NULL) {
+        return WOLFSSL_FAILURE;
+    }
+
+    /* no previous values in stack */
+    if (sk->data.generic == NULL) {
+        sk->data.generic = generic;
+        sk->num += 1;
+        return WOLFSSL_SUCCESS;
+    }
+
+    /* stack already has value(s) create a new node and add more */
+    node = (WOLFSSL_STACK*)XMALLOC(sizeof(WOLFSSL_STACK),NULL,DYNAMIC_TYPE_SSL);
+    if (node == NULL) {
+        WOLFSSL_MSG("Memory error");
+        return WOLFSSL_FAILURE;
+    }
+    XMEMSET(node, 0, sizeof(WOLFSSL_STACK));
+
+    /* push new node onto head of stack */
+    node->type         = sk->type;
+    node->data.generic = sk->data.generic;
+    node->next         = sk->next;
+    sk->next           = node;
+    sk->data.generic   = generic;
+    sk->num           += 1;
+
+    return WOLFSSL_SUCCESS;
+}
+void wolfSSL_sk_GENERIC_free(WOLFSSL_STACK* sk)
+{
+    wolfSSL_sk_GENERIC_pop_free(sk, NULL);
+}
+
+
+/* Free all nodes in a stack */
+void wolfSSL_sk_pop_free(WOLF_STACK_OF(WOLFSSL_ASN1_OBJECT)* sk,
+                                                       wolfSSL_sk_freefunc func)
+{
+    WOLFSSL_ENTER("wolfSSL_sk_pop_free");
+
+    if (sk == NULL) {
+        WOLFSSL_MSG("Error, BAD_FUNC_ARG");
+        return;
+    }
+
+    switch(sk->type) {
+        #if defined(OPENSSL_ALL) || defined (WOLFSSL_QT)
+        case STACK_TYPE_ACCESS_DESCRIPTION:
+            wolfSSL_sk_ACCESS_DESCRIPTION_pop_free(sk,
+                                                wolfSSL_ACCESS_DESCRIPTION_free);
+            break;
+        #endif
+        case STACK_TYPE_X509:
+            wolfSSL_sk_X509_pop_free(sk,(void (*)(WOLFSSL_X509*))func);
+            break;
+        case STACK_TYPE_OBJ:
+            wolfSSL_sk_ASN1_OBJECT_pop_free(sk,
+                                          (void (*)(WOLFSSL_ASN1_OBJECT*))func);
+            break;
+        case STACK_TYPE_GEN_NAME:
+            wolfSSL_sk_GENERAL_NAME_pop_free(sk,
+                                         (void (*)(WOLFSSL_GENERAL_NAME*))func);
+            break;
+        #ifdef OPENSSL_ALL
+        case STACK_TYPE_X509_NAME:
+            wolfSSL_sk_X509_NAME_pop_free(sk,
+                                         (void (*)(WOLFSSL_X509_NAME*))func);
+            break;
+        case STACK_TYPE_X509_EXT:
+            wolfSSL_sk_X509_EXTENSION_pop_free(sk,
+                                       (void (*)(WOLFSSL_X509_EXTENSION*))func);
+            break;
+        #endif
+        #if defined(OPENSSL_ALL)
+        case STACK_TYPE_X509_INFO:
+            wolfSSL_sk_X509_INFO_pop_free(sk,
+                                            (void (*)(WOLFSSL_X509_INFO*))func);
+            break;
+        #endif
+        default:
+            wolfSSL_sk_GENERIC_pop_free(sk,
+                                          (void (*)(void*))func);
+            break;
+    }
+}
+
+#if defined(OPENSSL_ALL)
+/* Free the structure for WOLFSSL_CONF_VALUE stack
+ *
+ * sk  stack to free nodes in
+ */
+void wolfSSL_sk_CONF_VALUE_free(WOLF_STACK_OF(WOLFSSL_CONF_VALUE)* sk)
+{
+    WOLFSSL_STACK* node;
+    WOLFSSL_STACK* tmp;
+    WOLFSSL_ENTER("wolfSSL_sk_CONF_VALUE_free");
+
+    if (sk == NULL)
+        return;
+
+    /* parse through stack freeing each node */
+    node = sk->next;
+    while (node) {
+        tmp  = node;
+        node = node->next;
+        XFREE(tmp, NULL, DYNAMIC_TYPE_OPENSSL);
+    }
+
+    /* free head of stack */
+    XFREE(sk, NULL, DYNAMIC_TYPE_ASN1);
+}
+#endif
+
+/* Creates and returns a new null stack. */
+WOLFSSL_STACK* wolfSSL_sk_new_null(void)
+{
+    WOLFSSL_STACK* sk;
+    WOLFSSL_ENTER("wolfSSL_sk_new_null");
+
+    sk = (WOLFSSL_STACK*)XMALLOC(sizeof(WOLFSSL_STACK), NULL,
+                                 DYNAMIC_TYPE_OPENSSL);
+    if (sk == NULL) {
+        WOLFSSL_MSG("WOLFSSL_STACK memory error");
+        return NULL;
+    }
+
+    XMEMSET(sk, 0, sizeof(WOLFSSL_STACK));
+    sk->type = STACK_TYPE_NULL;
+
+    return sk;
+}
+
+/* frees the wolfSSL_BASIC_CONSTRAINTS object */
+void wolfSSL_BASIC_CONSTRAINTS_free(WOLFSSL_BASIC_CONSTRAINTS *bc)
+{
+    WOLFSSL_ENTER("wolfSSL_BASIC_CONSTRAINTS_free");
+    if (bc == NULL) {
+        WOLFSSL_MSG("Argument is NULL");
+        return;
+    }
+    if (bc->pathlen) {
+        wolfSSL_ASN1_INTEGER_free(bc->pathlen);
+    }
+    XFREE(bc, NULL, DYNAMIC_TYPE_OPENSSL);
+}
+
+/* frees the wolfSSL_AUTHORITY_KEYID object */
+void wolfSSL_AUTHORITY_KEYID_free(WOLFSSL_AUTHORITY_KEYID *id)
+{
+    WOLFSSL_ENTER("wolfSSL_AUTHORITY_KEYID_free");
+    if(id == NULL) {
+        WOLFSSL_MSG("Argument is NULL");
+        return;
+    }
+    if (id->keyid) {
+        wolfSSL_ASN1_STRING_free(id->keyid);
+    }
+    if (id->issuer) {
+        wolfSSL_ASN1_OBJECT_free(id->issuer);
+    }
+    if (id->serial) {
+        wolfSSL_ASN1_INTEGER_free(id->serial);
+    }
+    XFREE(id, NULL, DYNAMIC_TYPE_OPENSSL);
+}
+
+int wolfSSL_sk_SSL_COMP_num(WOLF_STACK_OF(WOLFSSL_COMP)* sk)
+{
+    if (sk == NULL)
+        return 0;
+    return (int)sk->num;
+}
+
+#endif /* OPENSSL_EXTRA */
+
+#if defined(OPENSSL_EXTRA) || defined(HAVE_EXT_CACHE)
+/* stunnel 4.28 needs
+ *
+ * Callback that is called if a session tries to resume but could not find
+ * the session to resume it.
+ */
+void wolfSSL_CTX_sess_set_get_cb(WOLFSSL_CTX* ctx,
+                    WOLFSSL_SESSION*(*f)(WOLFSSL*, unsigned char*, int, int*))
+{
+    if (ctx == NULL)
+        return;
+
+#ifdef HAVE_EXT_CACHE
+    ctx->get_sess_cb = f;
+#else
+    (void)f;
+#endif
+}
+
+void wolfSSL_CTX_sess_set_new_cb(WOLFSSL_CTX* ctx,
+                             int (*f)(WOLFSSL*, WOLFSSL_SESSION*))
+{
+    if (ctx == NULL)
+        return;
+
+#ifdef HAVE_EXT_CACHE
+    ctx->new_sess_cb = f;
+#else
+    (void)f;
+#endif
+}
+
+void wolfSSL_CTX_sess_set_remove_cb(WOLFSSL_CTX* ctx, void (*f)(WOLFSSL_CTX*,
+                                                        WOLFSSL_SESSION*))
+{
+    if (ctx == NULL)
+        return;
+
+#ifdef HAVE_EXT_CACHE
+    ctx->rem_sess_cb = f;
+#else
+    (void)f;
+#endif
+}
+#endif /* OPENSSL_EXTRA || HAVE_EXT_CACHE */
+
+#ifdef OPENSSL_EXTRA
+
+/*
+ *
+ * Note: It is expected that the importing and exporting function have been
+ *       built with the same settings. For example if session tickets was
+ *       enabled with the wolfSSL library exporting a session then it is
+ *       expected to be turned on with the wolfSSL library importing the session.
+ */
+int wolfSSL_i2d_SSL_SESSION(WOLFSSL_SESSION* sess, unsigned char** p)
+{
+    int size = 0;
+#ifdef HAVE_EXT_CACHE
+    int idx = 0;
+#ifdef SESSION_CERTS
+    int i;
+#endif
+    unsigned char *data;
+
+    if (sess == NULL) {
+        return BAD_FUNC_ARG;
+    }
+
+    /* bornOn | timeout | sessionID len | sessionID | masterSecret | haveEMS */
+    size += OPAQUE32_LEN + OPAQUE32_LEN + OPAQUE8_LEN + sess->sessionIDSz +
+            SECRET_LEN + OPAQUE8_LEN;
+#ifdef SESSION_CERTS
+    /* Peer chain */
+    size += OPAQUE8_LEN;
+    for (i = 0; i < sess->chain.count; i++)
+        size += OPAQUE16_LEN + sess->chain.certs[i].length;
+#endif
+#if defined(SESSION_CERTS) || (defined(WOLFSSL_TLS13) && \
+                               defined(HAVE_SESSION_TICKET))
+    /* Protocol version */
+    size += OPAQUE16_LEN;
+#endif
+#if defined(SESSION_CERTS) || !defined(NO_RESUME_SUITE_CHECK) || \
+                        (defined(WOLFSSL_TLS13) && defined(HAVE_SESSION_TICKET))
+    /* cipher suite */
+    size += OPAQUE16_LEN;
+#endif
+#ifndef NO_CLIENT_CACHE
+    /* ServerID len | ServerID */
+    size += OPAQUE16_LEN + sess->idLen;
+#endif
+#ifdef OPENSSL_EXTRA
+    /* session context ID len | session context ID */
+    size += OPAQUE8_LEN + sess->sessionCtxSz;
+#endif
+#ifdef WOLFSSL_TLS13
+    /* namedGroup */
+    size += OPAQUE16_LEN;
+#endif
+#if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
+#ifdef WOLFSSL_TLS13
+    /* ticketSeen | ticketAdd */
+    size += OPAQUE32_LEN + OPAQUE32_LEN;
+#ifndef WOLFSSL_TLS13_DRAFT_18
+    /* ticketNonce */
+    size += OPAQUE8_LEN + sess->ticketNonce.len;
+#endif
+#endif
+#ifdef WOLFSSL_EARLY_DATA
+    size += OPAQUE32_LEN;
+#endif
+#endif
+#ifdef HAVE_SESSION_TICKET
+    /* ticket len | ticket */
+    size += OPAQUE16_LEN + sess->ticketLen;
+#endif
+
+    if (p != NULL) {
+        if (*p == NULL)
+            *p = (unsigned char*)XMALLOC(size, NULL, DYNAMIC_TYPE_OPENSSL);
+        if (*p == NULL)
+            return 0;
+        data = *p;
+
+        c32toa(sess->bornOn, data + idx); idx += OPAQUE32_LEN;
+        c32toa(sess->timeout, data + idx); idx += OPAQUE32_LEN;
+        data[idx++] = sess->sessionIDSz;
+        XMEMCPY(data + idx, sess->sessionID, sess->sessionIDSz);
+        idx += sess->sessionIDSz;
+        XMEMCPY(data + idx, sess->masterSecret, SECRET_LEN); idx += SECRET_LEN;
+        data[idx++] = (byte)sess->haveEMS;
+#ifdef SESSION_CERTS
+        data[idx++] = (byte)sess->chain.count;
+        for (i = 0; i < sess->chain.count; i++) {
+            c16toa((word16)sess->chain.certs[i].length, data + idx);
+            idx += OPAQUE16_LEN;
+            XMEMCPY(data + idx, sess->chain.certs[i].buffer,
+                    sess->chain.certs[i].length);
+            idx += sess->chain.certs[i].length;
+        }
+#endif
+#if defined(SESSION_CERTS) || (defined(WOLFSSL_TLS13) && \
+                               defined(HAVE_SESSION_TICKET))
+        data[idx++] = sess->version.major;
+        data[idx++] = sess->version.minor;
+#endif
+#if defined(SESSION_CERTS) || !defined(NO_RESUME_SUITE_CHECK) || \
+                        (defined(WOLFSSL_TLS13) && defined(HAVE_SESSION_TICKET))
+        data[idx++] = sess->cipherSuite0;
+        data[idx++] = sess->cipherSuite;
+#endif
+#ifndef NO_CLIENT_CACHE
+        c16toa(sess->idLen, data + idx); idx += OPAQUE16_LEN;
+        XMEMCPY(data + idx, sess->serverID, sess->idLen);
+        idx += sess->idLen;
+#endif
+#ifdef OPENSSL_EXTRA
+        data[idx++] = sess->sessionCtxSz;
+        XMEMCPY(data + idx, sess->sessionCtx, sess->sessionCtxSz);
+        idx += sess->sessionCtxSz;
+#endif
+#ifdef WOLFSSL_TLS13
+        c16toa(sess->namedGroup, data + idx);
+        idx += OPAQUE16_LEN;
+#endif
+#if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
+#ifdef WOLFSSL_TLS13
+    c32toa(sess->ticketSeen, data + idx);
+    idx += OPAQUE32_LEN;
+    c32toa(sess->ticketAdd, data + idx);
+    idx += OPAQUE32_LEN;
+#ifndef WOLFSSL_TLS13_DRAFT_18
+    data[idx++] = sess->ticketNonce.len;
+    XMEMCPY(data + idx, sess->ticketNonce.data, sess->ticketNonce.len);
+    idx += sess->ticketNonce.len;
+#endif
+#endif
+#ifdef WOLFSSL_EARLY_DATA
+        c32toa(sess->maxEarlyDataSz, data + idx);
+        idx += OPAQUE32_LEN;
+#endif
+#endif
+#ifdef HAVE_SESSION_TICKET
+        c16toa(sess->ticketLen, data + idx); idx += OPAQUE16_LEN;
+        XMEMCPY(data + idx, sess->ticket, sess->ticketLen);
+        idx += sess->ticketLen;
+#endif
+    }
+#endif
+
+    (void)sess;
+    (void)p;
+#ifdef HAVE_EXT_CACHE
+    (void)idx;
+#endif
+
+    return size;
+}
+
+
+/* TODO: no function to free new session.
+ *
+ * Note: It is expected that the importing and exporting function have been
+ *       built with the same settings. For example if session tickets was
+ *       enabled with the wolfSSL library exporting a session then it is
+ *       expected to be turned on with the wolfSSL library importing the session.
+ */
+WOLFSSL_SESSION* wolfSSL_d2i_SSL_SESSION(WOLFSSL_SESSION** sess,
+                                const unsigned char** p, long i)
+{
+    WOLFSSL_SESSION* s = NULL;
+    int ret = 0;
+#if defined(HAVE_EXT_CACHE)
+    int idx;
+    byte* data;
+#ifdef SESSION_CERTS
+    int j;
+    word16 length;
+#endif
+#endif
+
+    (void)p;
+    (void)i;
+    (void)ret;
+
+    if (sess != NULL)
+        s = *sess;
+
+#ifdef HAVE_EXT_CACHE
+    if (p == NULL || *p == NULL)
+        return NULL;
+
+    if (s == NULL) {
+        s = (WOLFSSL_SESSION*)XMALLOC(sizeof(WOLFSSL_SESSION), NULL,
+                                      DYNAMIC_TYPE_OPENSSL);
+        if (s == NULL)
+            return NULL;
+        XMEMSET(s, 0, sizeof(WOLFSSL_SESSION));
+        s->isAlloced = 1;
+#ifdef HAVE_SESSION_TICKET
+        s->isDynamic = 0;
+#endif
+    }
+
+    idx = 0;
+    data = (byte*)*p;
+
+    /* bornOn | timeout | sessionID len */
+    if (i < OPAQUE32_LEN + OPAQUE32_LEN + OPAQUE8_LEN) {
+        ret = BUFFER_ERROR;
+        goto end;
+    }
+    ato32(data + idx, &s->bornOn); idx += OPAQUE32_LEN;
+    ato32(data + idx, &s->timeout); idx += OPAQUE32_LEN;
+    s->sessionIDSz = data[idx++];
+
+    /* sessionID | secret | haveEMS */
+    if (i - idx < s->sessionIDSz + SECRET_LEN + OPAQUE8_LEN) {
+        ret = BUFFER_ERROR;
+        goto end;
+    }
+    XMEMCPY(s->sessionID, data + idx, s->sessionIDSz);
+    idx  += s->sessionIDSz;
+    XMEMCPY(s->masterSecret, data + idx, SECRET_LEN); idx += SECRET_LEN;
+    s->haveEMS = data[idx++];
+
+#ifdef SESSION_CERTS
+    /* Certificate chain */
+    if (i - idx == 0) {
+        ret = BUFFER_ERROR;
+        goto end;
+    }
+    s->chain.count = data[idx++];
+    for (j = 0; j < s->chain.count; j++) {
+        if (i - idx < OPAQUE16_LEN) {
+            ret = BUFFER_ERROR;
+            goto end;
+        }
+        ato16(data + idx, &length); idx += OPAQUE16_LEN;
+        s->chain.certs[j].length = length;
+        if (i - idx < length) {
+            ret = BUFFER_ERROR;
+            goto end;
+        }
+        XMEMCPY(s->chain.certs[j].buffer, data + idx, length);
+        idx += length;
+    }
+#endif
+#if defined(SESSION_CERTS) || (defined(WOLFSSL_TLS13) && \
+                               defined(HAVE_SESSION_TICKET))
+    /* Protocol Version */
+    if (i - idx < OPAQUE16_LEN) {
+        ret = BUFFER_ERROR;
+        goto end;
+    }
+    s->version.major = data[idx++];
+    s->version.minor = data[idx++];
+#endif
+#if defined(SESSION_CERTS) || !defined(NO_RESUME_SUITE_CHECK) || \
+                        (defined(WOLFSSL_TLS13) && defined(HAVE_SESSION_TICKET))
+    /* Cipher suite */
+    if (i - idx < OPAQUE16_LEN) {
+        ret = BUFFER_ERROR;
+        goto end;
+    }
+    s->cipherSuite0 = data[idx++];
+    s->cipherSuite = data[idx++];
+#endif
+#ifndef NO_CLIENT_CACHE
+    /* ServerID len */
+    if (i - idx < OPAQUE16_LEN) {
+        ret = BUFFER_ERROR;
+        goto end;
+    }
+    ato16(data + idx, &s->idLen); idx += OPAQUE16_LEN;
+
+    /* ServerID */
+    if (i - idx < s->idLen) {
+        ret = BUFFER_ERROR;
+        goto end;
+    }
+    XMEMCPY(s->serverID, data + idx, s->idLen); idx += s->idLen;
+#endif
+#ifdef OPENSSL_EXTRA
+    /* byte for length of session context ID */
+    if (i - idx < OPAQUE8_LEN) {
+        ret = BUFFER_ERROR;
+        goto end;
+    }
+    s->sessionCtxSz = data[idx++];
+
+    /* app session context ID */
+    if (i - idx < s->sessionCtxSz) {
+        ret = BUFFER_ERROR;
+        goto end;
+    }
+    XMEMCPY(s->sessionCtx, data + idx, s->sessionCtxSz); idx += s->sessionCtxSz;
+#endif
+#ifdef WOLFSSL_TLS13
+    if (i - idx < OPAQUE16_LEN) {
+        ret = BUFFER_ERROR;
+        goto end;
+    }
+    ato16(data + idx, &s->namedGroup);
+    idx += OPAQUE16_LEN;
+#endif
+#if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
+#ifdef WOLFSSL_TLS13
+    if (i - idx < (OPAQUE32_LEN * 2)) {
+        ret = BUFFER_ERROR;
+        goto end;
+    }
+    ato32(data + idx, &s->ticketSeen);
+    idx += OPAQUE32_LEN;
+    ato32(data + idx, &s->ticketAdd);
+    idx += OPAQUE32_LEN;
+#ifndef WOLFSSL_TLS13_DRAFT_18
+    if (i - idx < OPAQUE8_LEN) {
+        ret = BUFFER_ERROR;
+        goto end;
+    }
+    s->ticketNonce.len = data[idx++];
+
+    if (i - idx < s->ticketNonce.len) {
+        ret = BUFFER_ERROR;
+        goto end;
+    }
+    XMEMCPY(s->ticketNonce.data, data + idx, s->ticketNonce.len);
+    idx += s->ticketNonce.len;
+#endif
+#endif
+#ifdef WOLFSSL_EARLY_DATA
+    if (i - idx < OPAQUE32_LEN) {
+        ret = BUFFER_ERROR;
+        goto end;
+    }
+    ato32(data + idx, &s->maxEarlyDataSz);
+    idx += OPAQUE32_LEN;
+#endif
+#endif
+#ifdef HAVE_SESSION_TICKET
+    /* ticket len */
+    if (i - idx < OPAQUE16_LEN) {
+        ret = BUFFER_ERROR;
+        goto end;
+    }
+    ato16(data + idx, &s->ticketLen); idx += OPAQUE16_LEN;
+
+    /* Dispose of ol dynamic ticket and ensure space for new ticket. */
+    if (s->isDynamic)
+        XFREE(s->ticket, NULL, DYNAMIC_TYPE_SESSION_TICK);
+    if (s->ticketLen <= SESSION_TICKET_LEN)
+        s->ticket = s->staticTicket;
+    else {
+        s->ticket = (byte*)XMALLOC(s->ticketLen, NULL,
+                                   DYNAMIC_TYPE_SESSION_TICK);
+        if (s->ticket == NULL) {
+            ret = MEMORY_ERROR;
+            goto end;
+        }
+        s->isDynamic = 1;
+    }
+
+    /* ticket */
+    if (i - idx < s->ticketLen) {
+        ret = BUFFER_ERROR;
+        goto end;
+    }
+    XMEMCPY(s->ticket, data + idx, s->ticketLen); idx += s->ticketLen;
+#endif
+    (void)idx;
+
+    if (sess != NULL)
+        *sess = s;
+
+    *p += idx;
+
+end:
+    if (ret != 0 && (sess == NULL || *sess != s))
+        wolfSSL_SESSION_free(s);
+#endif
+    return s;
+}
+
+
+long wolfSSL_SESSION_get_timeout(const WOLFSSL_SESSION* sess)
+{
+    long timeout = 0;
+    WOLFSSL_ENTER("wolfSSL_SESSION_get_timeout");
+    if (sess)
+        timeout = sess->timeout;
+    return timeout;
+}
+
+
+long wolfSSL_SESSION_get_time(const WOLFSSL_SESSION* sess)
+{
+    long bornOn = 0;
+    WOLFSSL_ENTER("wolfSSL_SESSION_get_time");
+    if (sess)
+        bornOn = sess->bornOn;
+    return bornOn;
+}
+
+
+#endif /* OPENSSL_EXTRA */
+
+
+#ifdef KEEP_PEER_CERT
+char*  wolfSSL_X509_get_subjectCN(WOLFSSL_X509* x509)
+{
+    if (x509 == NULL)
+        return NULL;
+
+    return x509->subjectCN;
+}
+#endif /* KEEP_PEER_CERT */
+
+#ifdef OPENSSL_EXTRA
+
+#if defined(FORTRESS) && !defined(NO_FILESYSTEM)
+int wolfSSL_cmp_peer_cert_to_file(WOLFSSL* ssl, const char *fname)
+{
+    int ret = WOLFSSL_FATAL_ERROR;
+
+    WOLFSSL_ENTER("wolfSSL_cmp_peer_cert_to_file");
+    if (ssl != NULL && fname != NULL)
+    {
+    #ifdef WOLFSSL_SMALL_STACK
+        byte           staticBuffer[1]; /* force heap usage */
+    #else
+        byte           staticBuffer[FILE_BUFFER_SIZE];
+    #endif
+        byte*          myBuffer  = staticBuffer;
+        int            dynamic   = 0;
+        XFILE          file;
+        long           sz        = 0;
+        WOLFSSL_CTX*   ctx       = ssl->ctx;
+        WOLFSSL_X509*  peer_cert = &ssl->peerCert;
+        DerBuffer*     fileDer = NULL;
+
+        file = XFOPEN(fname, "rb");
+        if (file == XBADFILE)
+            return WOLFSSL_BAD_FILE;
+
+        if (XFSEEK(file, 0, XSEEK_END) != 0) {
+            XFCLOSE(file);
+            return WOLFSSL_BAD_FILE;
+        }
+        sz = XFTELL(file);
+        XREWIND(file);
+
+        if (sz > MAX_WOLFSSL_FILE_SIZE || sz < 0) {
+            WOLFSSL_MSG("cmp_peer_cert_to_file size error");
+            XFCLOSE(file);
+            return WOLFSSL_BAD_FILE;
+        }
+
+        if (sz > (long)sizeof(staticBuffer)) {
+            WOLFSSL_MSG("Getting dynamic buffer");
+            myBuffer = (byte*)XMALLOC(sz, ctx->heap, DYNAMIC_TYPE_FILE);
+            dynamic = 1;
+        }
+
+        if ((myBuffer != NULL) &&
+            (sz > 0) &&
+            (XFREAD(myBuffer, 1, sz, file) == (size_t)sz) &&
+            (PemToDer(myBuffer, (long)sz, CERT_TYPE,
+                      &fileDer, ctx->heap, NULL, NULL) == 0) &&
+            (fileDer->length != 0) &&
+            (fileDer->length == peer_cert->derCert->length) &&
+            (XMEMCMP(peer_cert->derCert->buffer, fileDer->buffer,
+                                                fileDer->length) == 0))
+        {
+            ret = 0;
+        }
+
+        FreeDer(&fileDer);
+
+        if (dynamic)
+            XFREE(myBuffer, ctx->heap, DYNAMIC_TYPE_FILE);
+
+        XFCLOSE(file);
+    }
+
+    return ret;
+}
+#endif
+#endif /* OPENSSL_EXTRA */
+#endif /* !WOLFCRYPT_ONLY */
+#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
+const WOLFSSL_ObjectInfo wolfssl_object_info[] = {
+#ifndef NO_CERTS
+    /* oidCertExtType */
+    { NID_basic_constraints, BASIC_CA_OID, oidCertExtType, "basicConstraints",
+                                                "X509v3 Basic Constraints"},
+    { NID_subject_alt_name, ALT_NAMES_OID, oidCertExtType, "subjectAltName",
+                                         "X509v3 Subject Alternative Name"},
+    { CRL_DIST_OID, CRL_DIST_OID, oidCertExtType, "crlDistributionPoints",
+                                          "X509v3 CRL Distribution Points"},
+    { NID_info_access, AUTH_INFO_OID, oidCertExtType, "authorityInfoAccess",
+                                            "Authority Information Access"},
+    { NID_authority_key_identifier, AUTH_KEY_OID, oidCertExtType,
+               "authorityKeyIdentifier", "X509v3 Authority Key Identifier"},
+    { NID_subject_key_identifier, SUBJ_KEY_OID, oidCertExtType,
+                   "subjectKeyIdentifier", "X509v3 Subject Key Identifier"},
+    { NID_key_usage, KEY_USAGE_OID, oidCertExtType, "keyUsage",
+                                                        "X509v3 Key Usage"},
+    { NID_inhibit_any_policy, INHIBIT_ANY_OID, oidCertExtType,
+                           "inhibitAnyPolicy", "X509v3 Inhibit Any Policy"},
+    { NID_ext_key_usage, KEY_USAGE_OID, oidCertExtType,
+                           "extendedKeyUsage", "X509v3 Extended Key Usage"},
+    { NID_name_constraints, NAME_CONS_OID, oidCertExtType,
+                              "nameConstraints", "X509v3 Name Constraints"},
+    { NID_certificate_policies, CERT_POLICY_OID, oidCertExtType,
+                      "certificatePolicies", "X509v3 Certificate Policies"},
+
+    /* oidCertAuthInfoType */
+    { AIA_OCSP_OID, AIA_OCSP_OID, oidCertAuthInfoType, "authorityInfoAccess",
+                                            "Authority Information Access"},
+    { AIA_CA_ISSUER_OID, AIA_CA_ISSUER_OID, oidCertAuthInfoType,
+                                                 "caIssuers", "CA Issuers"},
+
+    /* oidCertPolicyType */
+    { NID_any_policy, CP_ANY_OID, oidCertPolicyType, "anyPolicy",
+                                                       "X509v3 Any Policy"},
+
+    /* oidCertAltNameType */
+    { NID_hw_name_oid, HW_NAME_OID, oidCertAltNameType, "Hardware name",""},
+
+    /* oidCertKeyUseType */
+    { NID_anyExtendedKeyUsage, EKU_ANY_OID, oidCertKeyUseType,
+                           "anyExtendedKeyUsage", "Any Extended Key Usage"},
+    { EKU_SERVER_AUTH_OID, EKU_SERVER_AUTH_OID, oidCertKeyUseType,
+                             "serverAuth", "TLS Web Server Authentication"},
+    { EKU_CLIENT_AUTH_OID, EKU_CLIENT_AUTH_OID, oidCertKeyUseType,
+                             "clientAuth", "TLS Web Client Authentication"},
+    { EKU_OCSP_SIGN_OID, EKU_OCSP_SIGN_OID, oidCertKeyUseType,
+                                             "OCSPSigning", "OCSP Signing"},
+
+    /* oidCertNameType */
+    { NID_commonName, NID_commonName, oidCertNameType, "CN", "commonName"},
+    { NID_surname, NID_surname, oidCertNameType, "SN", "surname"},
+    { NID_serialNumber, NID_serialNumber, oidCertNameType, "serialNumber",
+                                                            "serialNumber"},
+    { NID_countryName, NID_countryName, oidCertNameType, "C", "countryName"},
+    { NID_localityName, NID_localityName, oidCertNameType, "L", "localityName"},
+    { NID_stateOrProvinceName, NID_stateOrProvinceName, oidCertNameType, "ST",
+                                                        "stateOrProvinceName"},
+    { NID_organizationName, NID_organizationName, oidCertNameType, "O",
+                                                        "organizationName"},
+    { NID_organizationalUnitName, NID_organizationalUnitName, oidCertNameType,
+                                                "OU", "organizationalUnitName"},
+    { NID_emailAddress, NID_emailAddress, oidCertNameType, "emailAddress",
+                                                            "emailAddress"},
+    { NID_domainComponent, NID_domainComponent, oidCertNameType, "DC",
+                                                            "domainComponent"},
+    { NID_businessCategory, NID_businessCategory, oidCertNameType, "businessCategory",
+                                                            "businessCategory"},
+    { NID_jurisdictionCountryName, NID_jurisdictionCountryName, oidCertNameType, "jurisdictionC",
+                                                            "jurisdictionCountryName"},
+    { NID_jurisdictionStateOrProvinceName, NID_jurisdictionStateOrProvinceName,
+            oidCertNameType, "jurisdictionST", "jurisdictionStateOrProvinceName"},
+#endif
+#ifdef OPENSSL_EXTRA /* OPENSSL_EXTRA_X509_SMALL only needs the above */
+        /* oidHashType */
+    #ifdef WOLFSSL_MD2
+        { NID_md2, MD2h, oidHashType, "MD2", "md2"},
+    #endif
+    #ifdef WOLFSSL_MD5
+        { NID_md5, MD5h, oidHashType, "MD5", "md5"},
+    #endif
+    #ifndef NO_SHA
+        { NID_sha1, SHAh, oidHashType, "SHA1", "sha1"},
+    #endif
+    #ifdef WOLFSSL_SHA224
+        { NID_sha224, SHA224h, oidHashType, "SHA224", "sha224"},
+    #endif
+    #ifndef NO_SHA256
+        { NID_sha256, SHA256h, oidHashType, "SHA256", "sha256"},
+    #endif
+    #ifdef WOLFSSL_SHA384
+        { NID_sha384, SHA384h, oidHashType, "SHA384", "sha384"},
+    #endif
+    #ifdef WOLFSSL_SHA512
+        { NID_sha512, SHA512h, oidHashType, "SHA512", "sha512"},
+    #endif
+
+        /* oidSigType */
+    #ifndef NO_DSA
+        #ifndef NO_SHA
+        { CTC_SHAwDSA, CTC_SHAwDSA, oidSigType, "DSA-SHA1", "dsaWithSHA1"},
+        #endif
+    #endif /* NO_DSA */
+    #ifndef NO_RSA
+        #ifdef WOLFSSL_MD2
+        { CTC_MD2wRSA, CTC_MD2wRSA, oidSigType, "RSA-MD2",
+                                                        "md2WithRSAEncryption"},
+        #endif
+        #ifndef NO_MD5
+        { CTC_MD5wRSA, CTC_MD5wRSA, oidSigType, "RSA-MD5",
+                                                        "md5WithRSAEncryption"},
+        #endif
+        #ifndef NO_SHA
+        { CTC_SHAwRSA, CTC_SHAwRSA, oidSigType, "RSA-SHA1",
+                                                       "sha1WithRSAEncryption"},
+        #endif
+        #ifdef WOLFSSL_SHA224
+        { CTC_SHA224wRSA, CTC_SHA224wRSA, oidSigType, "RSA-SHA224",
+                                                     "sha224WithRSAEncryption"},
+        #endif
+        #ifndef NO_SHA256
+        { CTC_SHA256wRSA, CTC_SHA256wRSA, oidSigType, "RSA-SHA256",
+                                                     "sha256WithRSAEncryption"},
+        #endif
+        #ifdef WOLFSSL_SHA384
+        { CTC_SHA384wRSA, CTC_SHA384wRSA, oidSigType, "RSA-SHA384",
+                                                     "sha384WithRSAEncryption"},
+        #endif
+        #ifdef WOLFSSL_SHA512
+        { CTC_SHA512wRSA, CTC_SHA512wRSA, oidSigType, "RSA-SHA512",
+                                                     "sha512WithRSAEncryption"},
+        #endif
+    #endif /* NO_RSA */
+    #ifdef HAVE_ECC
+        #ifndef NO_SHA
+        { CTC_SHAwECDSA, CTC_SHAwECDSA, oidSigType, "ecdsa-with-SHA1", "shaWithECDSA"},
+        #endif
+        #ifdef WOLFSSL_SHA224
+        { CTC_SHA224wECDSA, CTC_SHA224wECDSA, oidSigType, "ecdsa-with-SHA224","sha224WithECDSA"},
+        #endif
+        #ifndef NO_SHA256
+        { CTC_SHA256wECDSA, CTC_SHA256wECDSA, oidSigType, "ecdsa-with-SHA256","sha256WithECDSA"},
+        #endif
+        #ifdef WOLFSSL_SHA384
+        { CTC_SHA384wECDSA, CTC_SHA384wECDSA, oidSigType, "ecdsa-with-SHA384","sha384WithECDSA"},
+        #endif
+        #ifdef WOLFSSL_SHA512
+        { CTC_SHA512wECDSA, CTC_SHA512wECDSA, oidSigType, "ecdsa-with-SHA512","sha512WithECDSA"},
+        #endif
+    #endif /* HAVE_ECC */
+
+        /* oidKeyType */
+    #ifndef NO_DSA
+        { DSAk, DSAk, oidKeyType, "DSA", "dsaEncryption"},
+        { NID_dsa, DSAk, oidKeyType, "DSA", "dsaEncryption"},
+    #endif /* NO_DSA */
+    #ifndef NO_RSA
+        { RSAk, RSAk, oidKeyType, "RSA", "rsaEncryption"},
+        { NID_rsaEncryption, RSAk, oidKeyType, "RSA", "rsaEncryption"},
+    #endif /* NO_RSA */
+    #ifdef HAVE_NTRU
+        { NTRUk, NTRUk, oidKeyType, "NTRU", "ntruEncryption"},
+    #endif /* HAVE_NTRU */
+    #ifdef HAVE_ECC
+        { ECDSAk, ECDSAk, oidKeyType, "ECDSA", "ecdsaEncryption"},
+        { NID_X9_62_id_ecPublicKey, ECDSAk, oidKeyType, "id-ecPublicKey",
+                                                        "id-ecPublicKey"},
+    #endif /* HAVE_ECC */
+    #ifndef NO_DH
+        { NID_dhKeyAgreement, DHk, oidKeyType, "dhKeyAgreement", "dhKeyAgreement"},
+    #endif
+
+        /* oidCurveType */
+    #ifdef HAVE_ECC
+        { NID_X9_62_prime192v1, ECC_SECP192R1_OID, oidCurveType, "prime192v1", "prime192v1"},
+        { NID_X9_62_prime192v2, ECC_PRIME192V2_OID, oidCurveType, "prime192v2", "prime192v2"},
+        { NID_X9_62_prime192v3, ECC_PRIME192V3_OID, oidCurveType, "prime192v3", "prime192v3"},
+
+        { NID_X9_62_prime239v1, ECC_PRIME239V1_OID, oidCurveType, "prime239v1", "prime239v1"},
+        { NID_X9_62_prime239v2, ECC_PRIME239V2_OID, oidCurveType, "prime239v2", "prime239v2"},
+        { NID_X9_62_prime239v3, ECC_PRIME239V3_OID, oidCurveType, "prime239v3", "prime239v3"},
+
+        { NID_X9_62_prime256v1, ECC_SECP256R1_OID, oidCurveType, "prime256v1", "prime256v1"},
+
+        { NID_secp112r1, ECC_SECP112R1_OID,  oidCurveType, "secp112r1", "secp112r1"},
+        { NID_secp112r2, ECC_SECP112R2_OID,  oidCurveType, "secp112r2", "secp112r2"},
+
+        { NID_secp128r1, ECC_SECP128R1_OID,  oidCurveType, "secp128r1", "secp128r1"},
+        { NID_secp128r2, ECC_SECP128R2_OID,  oidCurveType, "secp128r2", "secp128r2"},
+
+        { NID_secp160r1, ECC_SECP160R1_OID,  oidCurveType, "secp160r1", "secp160r1"},
+        { NID_secp160r2, ECC_SECP160R2_OID,  oidCurveType, "secp160r2", "secp160r2"},
+
+        { NID_secp224r1, ECC_SECP224R1_OID,  oidCurveType, "secp224r1", "secp224r1"},
+        { NID_secp384r1, ECC_SECP384R1_OID,  oidCurveType, "secp384r1", "secp384r1"},
+        { NID_secp521r1, ECC_SECP521R1_OID,  oidCurveType, "secp521r1", "secp521r1"},
+
+        { NID_secp160k1, ECC_SECP160K1_OID,  oidCurveType, "secp160k1", "secp160k1"},
+        { NID_secp192k1, ECC_SECP192K1_OID,  oidCurveType, "secp192k1", "secp192k1"},
+        { NID_secp224k1, ECC_SECP224K1_OID,  oidCurveType, "secp224k1", "secp224k1"},
+        { NID_secp256k1, ECC_SECP256K1_OID,  oidCurveType, "secp256k1", "secp256k1"},
+
+        { NID_brainpoolP160r1, ECC_BRAINPOOLP160R1_OID,  oidCurveType, "brainpoolP160r1", "brainpoolP160r1"},
+        { NID_brainpoolP192r1, ECC_BRAINPOOLP192R1_OID,  oidCurveType, "brainpoolP192r1", "brainpoolP192r1"},
+        { NID_brainpoolP224r1, ECC_BRAINPOOLP224R1_OID,  oidCurveType, "brainpoolP224r1", "brainpoolP224r1"},
+        { NID_brainpoolP256r1, ECC_BRAINPOOLP256R1_OID,  oidCurveType, "brainpoolP256r1", "brainpoolP256r1"},
+        { NID_brainpoolP320r1, ECC_BRAINPOOLP320R1_OID,  oidCurveType, "brainpoolP320r1", "brainpoolP320r1"},
+        { NID_brainpoolP384r1, ECC_BRAINPOOLP384R1_OID,  oidCurveType, "brainpoolP384r1", "brainpoolP384r1"},
+        { NID_brainpoolP512r1, ECC_BRAINPOOLP512R1_OID,  oidCurveType, "brainpoolP512r1", "brainpoolP512r1"},
+    #endif /* HAVE_ECC */
+
+        /* oidBlkType */
+    #ifdef WOLFSSL_AES_128
+        { AES128CBCb, AES128CBCb, oidBlkType, "AES-128-CBC", "aes-128-cbc"},
+    #endif
+    #ifdef WOLFSSL_AES_192
+        { AES192CBCb, AES192CBCb, oidBlkType, "AES-192-CBC", "aes-192-cbc"},
+    #endif
+    #ifdef WOLFSSL_AES_256
+        { AES256CBCb, AES256CBCb, oidBlkType, "AES-256-CBC", "aes-256-cbc"},
+    #endif
+    #ifndef NO_DES3
+        { NID_des, DESb, oidBlkType, "DES-CBC", "des-cbc"},
+        { NID_des3, DES3b, oidBlkType, "DES-EDE3-CBC", "des-ede3-cbc"},
+    #endif /* !NO_DES3 */
+
+        /* oidOcspType */
+    #ifdef HAVE_OCSP
+        { NID_id_pkix_OCSP_basic, OCSP_BASIC_OID, oidOcspType, "basicOCSPResponse",
+                                                         "Basic OCSP Response"},
+        { OCSP_NONCE_OID, OCSP_NONCE_OID, oidOcspType, "Nonce",
+                                                                  "OCSP Nonce"},
+    #endif /* HAVE_OCSP */
+
+    #ifndef NO_PWDBASED
+        /* oidKdfType */
+        { PBKDF2_OID, PBKDF2_OID, oidKdfType, "PBKDFv2", "PBKDF2"},
+
+        /* oidPBEType */
+        { PBE_SHA1_RC4_128, PBE_SHA1_RC4_128, oidPBEType,
+                                 "PBE-SHA1-RC4-128", "pbeWithSHA1And128BitRC4"},
+        { PBE_SHA1_DES, PBE_SHA1_DES, oidPBEType, "PBE-SHA1-DES",
+                                                       "pbeWithSHA1AndDES-CBC"},
+        { PBE_SHA1_DES3, PBE_SHA1_DES3, oidPBEType, "PBE-SHA1-3DES",
+                                            "pbeWithSHA1And3-KeyTripleDES-CBC"},
+    #endif
+
+        /* oidKeyWrapType */
+    #ifdef WOLFSSL_AES_128
+        { AES128_WRAP, AES128_WRAP, oidKeyWrapType, "AES-128 wrap", "aes128-wrap"},
+    #endif
+    #ifdef WOLFSSL_AES_192
+        { AES192_WRAP, AES192_WRAP, oidKeyWrapType, "AES-192 wrap", "aes192-wrap"},
+    #endif
+    #ifdef WOLFSSL_AES_256
+        { AES256_WRAP, AES256_WRAP, oidKeyWrapType, "AES-256 wrap", "aes256-wrap"},
+    #endif
+
+    #ifndef NO_PKCS7
+        #ifndef NO_DH
+        /* oidCmsKeyAgreeType */
+            #ifndef NO_SHA
+        { dhSinglePass_stdDH_sha1kdf_scheme, dhSinglePass_stdDH_sha1kdf_scheme,
+                oidCmsKeyAgreeType, "dhSinglePass-stdDH-sha1kdf-scheme", "dhSinglePass-stdDH-sha1kdf-scheme"},
+            #endif
+            #ifdef WOLFSSL_SHA224
+        { dhSinglePass_stdDH_sha224kdf_scheme,
+                dhSinglePass_stdDH_sha224kdf_scheme, oidCmsKeyAgreeType,
+                "dhSinglePass-stdDH-sha224kdf-scheme", "dhSinglePass-stdDH-sha224kdf-scheme"},
+            #endif
+            #ifndef NO_SHA256
+        { dhSinglePass_stdDH_sha256kdf_scheme,
+                        dhSinglePass_stdDH_sha256kdf_scheme, oidCmsKeyAgreeType,
+                        "dhSinglePass-stdDH-sha256kdf-scheme", "dhSinglePass-stdDH-sha256kdf-scheme"},
+            #endif
+            #ifdef WOLFSSL_SHA384
+        { dhSinglePass_stdDH_sha384kdf_scheme,
+                        dhSinglePass_stdDH_sha384kdf_scheme, oidCmsKeyAgreeType,
+                        "dhSinglePass-stdDH-sha384kdf-scheme", "dhSinglePass-stdDH-sha384kdf-scheme"},
+            #endif
+            #ifdef WOLFSSL_SHA512
+        { dhSinglePass_stdDH_sha512kdf_scheme,
+                        dhSinglePass_stdDH_sha512kdf_scheme, oidCmsKeyAgreeType,
+                        "dhSinglePass-stdDH-sha512kdf-scheme", "dhSinglePass-stdDH-sha512kdf-scheme"},
+            #endif
+        #endif
+    #endif
+    #if defined(WOLFSSL_APACHE_HTTPD)
+        /* "1.3.6.1.5.5.7.8.7" */
+        { NID_id_on_dnsSRV, NID_id_on_dnsSRV, oidCertNameType,
+            WOLFSSL_SN_DNS_SRV, WOLFSSL_LN_DNS_SRV },
+
+        /* "1.3.6.1.4.1.311.20.2.3" */
+        { NID_ms_upn, WOLFSSL_MS_UPN_SUM, oidCertExtType, WOLFSSL_SN_MS_UPN,
+            WOLFSSL_LN_MS_UPN },
+
+        /* "1.3.6.1.5.5.7.1.24" */
+        { NID_tlsfeature, WOLFSSL_TLS_FEATURE_SUM, oidTlsExtType,
+            WOLFSSL_SN_TLS_FEATURE, WOLFSSL_LN_TLS_FEATURE },
+    #endif
+#endif /* OPENSSL_EXTRA */
+};
+
+#define WOLFSSL_OBJECT_INFO_SZ \
+                (sizeof(wolfssl_object_info) / sizeof(*wolfssl_object_info))
+const size_t wolfssl_object_info_sz = WOLFSSL_OBJECT_INFO_SZ;
+#endif
+#if defined(OPENSSL_EXTRA) || \
+    (defined(OPENSSL_EXTRA_X509_SMALL) && !defined(NO_RSA))
+static WC_RNG globalRNG;
+static int initGlobalRNG = 0;
+#endif
+#if defined(OPENSSL_EXTRA) && \
+    !defined(NO_RSA) && !defined(HAVE_USER_RSA) && !defined(HAVE_FAST_RSA)
+WC_RNG* WOLFSSL_RSA_GetRNG(WOLFSSL_RSA *rsa, WC_RNG **tmpRNG, int *initTmpRng)
+{
+    WC_RNG* rng = NULL;
+
+    if (!rsa || !initTmpRng) {
+        return NULL;
+    }
+    *initTmpRng = 0;
+
+#if !defined(HAVE_FIPS) && !defined(HAVE_USER_RSA) && \
+    !defined(HAVE_FAST_RSA) && defined(WC_RSA_BLINDING)
+    rng = ((RsaKey*)rsa->internal)->rng;
+#endif
+    if (rng == NULL && tmpRNG) {
+        if (!*tmpRNG) {
+#ifdef WOLFSSL_SMALL_STACK
+            *tmpRNG = (WC_RNG*)XMALLOC(sizeof(WC_RNG), NULL, DYNAMIC_TYPE_TMP_BUFFER);
+            if (*tmpRNG == NULL)
+                return NULL;
+#else
+            WOLFSSL_MSG("*tmpRNG is null");
+            return NULL;
+#endif
+        }
+
+        if (wc_InitRng(*tmpRNG) == 0) {
+            rng = *tmpRNG;
+            *initTmpRng = 1;
+        }
+        else {
+            WOLFSSL_MSG("Bad RNG Init, trying global");
+            if (initGlobalRNG == 0)
+                WOLFSSL_MSG("Global RNG no Init");
+            else
+                rng = &globalRNG;
+#ifdef WOLFSSL_SMALL_STACK
+            if (*tmpRNG)
+                XFREE(*tmpRNG, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+            *tmpRNG = NULL;
+#endif
+        }
+    }
+    return rng;
+}
+#endif
+#ifndef WOLFCRYPT_ONLY
+
+#ifdef OPENSSL_EXTRA
+
+/* Not thread safe! Can be called multiple times.
+ * Checks if the global RNG has been created. If not then one is created.
+ *
+ * Returns SSL_SUCCESS when no error is encountered.
+ */
+static int wolfSSL_RAND_Init(void)
+{
+    if (initGlobalRNG == 0) {
+        if (wc_InitRng(&globalRNG) < 0) {
+            WOLFSSL_MSG("wolfSSL Init Global RNG failed");
+            return 0;
+        }
+        initGlobalRNG = 1;
+    }
+
+    return SSL_SUCCESS;
+}
+
+
+/* SSL_SUCCESS on ok */
+int wolfSSL_RAND_seed(const void* seed, int len)
+{
+
+    WOLFSSL_MSG("wolfSSL_RAND_seed");
+
+    (void)seed;
+    (void)len;
+
+    return wolfSSL_RAND_Init();
+}
+
+
+/* Returns the path for reading seed data from.
+ * Uses the env variable $RANDFILE first if set, if not then used $HOME/.rnd
+ *
+ * Note uses stdlib by default unless XGETENV macro is overwritten
+ *
+ * fname buffer to hold path
+ * len   length of fname buffer
+ *
+ * Returns a pointer to fname on success and NULL on failure
+ */
+const char* wolfSSL_RAND_file_name(char* fname, unsigned long len)
+{
+#ifndef NO_FILESYSTEM
+    char* rt;
+    char ap[] = "/.rnd";
+
+    WOLFSSL_ENTER("wolfSSL_RAND_file_name");
+
+    if (fname == NULL) {
+        return NULL;
+    }
+
+    XMEMSET(fname, 0, len);
+    /* if access to stdlib.h */
+    if ((rt = XGETENV("RANDFILE")) != NULL) {
+        if (len > XSTRLEN(rt)) {
+            XMEMCPY(fname, rt, XSTRLEN(rt));
+        }
+        else {
+            WOLFSSL_MSG("RANDFILE too large for buffer");
+            rt = NULL;
+        }
+    }
+
+    /* $RANDFILE was not set or is too large, check $HOME */
+    if (rt == NULL) {
+        WOLFSSL_MSG("Environment variable RANDFILE not set");
+        if ((rt = XGETENV("HOME")) == NULL) {
+            WOLFSSL_MSG("Environment variable HOME not set");
+            return NULL;
+        }
+
+        if (len > XSTRLEN(rt) +  XSTRLEN(ap)) {
+            fname[0] = '\0';
+            XSTRNCAT(fname, rt, len);
+            XSTRNCAT(fname, ap, len - XSTRLEN(rt));
+            return fname;
+        }
+        else {
+            WOLFSSL_MSG("HOME too large for buffer");
+            return NULL;
+        }
+    }
+
+    return fname;
+#else
+    /* no filesystem defined */
+    WOLFSSL_ENTER("wolfSSL_RAND_file_name");
+    WOLFSSL_MSG("No filesystem feature enabled, not compiled in");
+    (void)fname;
+    (void)len;
+    return NULL;
+#endif
+}
+
+
+/* Writes 1024 bytes from the RNG to the given file name.
+ *
+ * fname name of file to write to
+ *
+ * Returns the number of bytes written
+ */
+int wolfSSL_RAND_write_file(const char* fname)
+{
+    int bytes = 0;
+
+    WOLFSSL_ENTER("RAND_write_file");
+
+    if (fname == NULL) {
+        return SSL_FAILURE;
+    }
+
+#ifndef NO_FILESYSTEM
+    {
+    #ifndef WOLFSSL_SMALL_STACK
+        unsigned char buf[1024];
+    #else
+        unsigned char* buf = (unsigned char *)XMALLOC(1024, NULL,
+                                                       DYNAMIC_TYPE_TMP_BUFFER);
+        if (buf == NULL) {
+            WOLFSSL_MSG("malloc failed");
+            return SSL_FAILURE;
+        }
+    #endif
+        bytes = 1024; /* default size of buf */
+
+        if (initGlobalRNG == 0 && wolfSSL_RAND_Init() != SSL_SUCCESS) {
+            WOLFSSL_MSG("No RNG to use");
+        #ifdef WOLFSSL_SMALL_STACK
+            XFREE(buf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+        #endif
+            return 0;
+        }
+
+        if (wc_RNG_GenerateBlock(&globalRNG, buf, bytes) != 0) {
+            WOLFSSL_MSG("Error generating random buffer");
+            bytes = 0;
+        }
+        else {
+            XFILE f;
+
+            f = XFOPEN(fname, "wb");
+            if (f == XBADFILE) {
+                WOLFSSL_MSG("Error opening the file");
+                bytes = 0;
+            }
+            else {
+                XFWRITE(buf, 1, bytes, f);
+                XFCLOSE(f);
+            }
+        }
+        ForceZero(buf, bytes);
+    #ifdef WOLFSSL_SMALL_STACK
+        XFREE(buf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    #endif
+    }
+#endif
+
+    return bytes;
+}
+
+#ifndef FREERTOS_TCP
+
+/* These constant values are protocol values made by egd */
+#if defined(USE_WOLFSSL_IO) && !defined(USE_WINDOWS_API)
+    #define WOLFSSL_EGD_NBLOCK 0x01
+    #include <sys/un.h>
+#endif
+
+/* This collects entropy from the path nm and seeds the global PRNG with it.
+ * Makes a call to wolfSSL_RAND_Init which is not thread safe.
+ *
+ * nm is the file path to the egd server
+ *
+ * Returns the number of bytes read.
+ */
+int wolfSSL_RAND_egd(const char* nm)
+{
+#if defined(USE_WOLFSSL_IO) && !defined(USE_WINDOWS_API) && !defined(HAVE_FIPS) && \
+    defined(HAVE_HASHDRBG)
+    struct sockaddr_un rem;
+    int fd;
+    int ret = WOLFSSL_SUCCESS;
+    word32 bytes = 0;
+    word32 idx   = 0;
+#ifndef WOLFSSL_SMALL_STACK
+    unsigned char buf[256];
+#else
+    unsigned char* buf;
+    buf = (unsigned char*)XMALLOC(256, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    if (buf == NULL) {
+        WOLFSSL_MSG("Not enough memory");
+        return WOLFSSL_FATAL_ERROR;
+    }
+#endif
+
+    if (nm == NULL) {
+    #ifdef WOLFSSL_SMALL_STACK
+        XFREE(buf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    #endif
+        return WOLFSSL_FATAL_ERROR;
+    }
+
+    fd = socket(AF_UNIX, SOCK_STREAM, 0);
+    if (fd < 0) {
+        WOLFSSL_MSG("Error creating socket");
+    #ifdef WOLFSSL_SMALL_STACK
+        XFREE(buf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    #endif
+        return WOLFSSL_FATAL_ERROR;
+    }
+    if (ret == WOLFSSL_SUCCESS) {
+        rem.sun_family = AF_UNIX;
+        XSTRNCPY(rem.sun_path, nm, sizeof(rem.sun_path) - 1);
+        rem.sun_path[sizeof(rem.sun_path)-1] = '\0';
+    }
+
+    /* connect to egd server */
+    if (ret == WOLFSSL_SUCCESS) {
+        if (connect(fd, (struct sockaddr*)&rem, sizeof(struct sockaddr_un))
+                == -1) {
+            WOLFSSL_MSG("error connecting to egd server");
+            ret = WOLFSSL_FATAL_ERROR;
+        }
+    }
+
+    while (ret == WOLFSSL_SUCCESS && bytes < 255 && idx + 2 < 256) {
+        if (ret == WOLFSSL_SUCCESS) {
+            buf[idx]     = WOLFSSL_EGD_NBLOCK;
+            buf[idx + 1] = 255 - bytes; /* request 255 bytes from server */
+            ret = (int)write(fd, buf + idx, 2);
+            if (ret <= 0 || ret != 2) {
+                if (errno == EAGAIN) {
+                    ret = WOLFSSL_SUCCESS;
+                    continue;
+                }
+                WOLFSSL_MSG("error requesting entropy from egd server");
+                ret = WOLFSSL_FATAL_ERROR;
+                break;
+            }
+        }
+
+        /* attempting to read */
+        buf[idx] = 0;
+        ret = (int)read(fd, buf + idx, 256 - bytes);
+        if (ret == 0) {
+            WOLFSSL_MSG("error reading entropy from egd server");
+            ret = WOLFSSL_FATAL_ERROR;
+            break;
+        }
+        if (ret > 0 && buf[idx] > 0) {
+            bytes += buf[idx]; /* egd stores amount sent in first byte */
+            if (bytes + idx > 255 || buf[idx] > ret) {
+                WOLFSSL_MSG("Buffer error");
+                ret = WOLFSSL_FATAL_ERROR;
+                break;
+            }
+            XMEMMOVE(buf + idx, buf + idx + 1, buf[idx]);
+            idx = bytes;
+            ret = WOLFSSL_SUCCESS;
+            if (bytes >= 255) {
+                break;
+            }
+        }
+        else {
+            if (errno == EAGAIN || errno == EINTR) {
+                WOLFSSL_MSG("EGD would read");
+                ret = WOLFSSL_SUCCESS; /* try again */
+            }
+            else if (buf[idx] == 0) {
+                /* if egd returned 0 then there is no more entropy to be had.
+                   Do not try more reads. */
+                ret = WOLFSSL_SUCCESS;
+                break;
+            }
+            else {
+                WOLFSSL_MSG("Error with read");
+                ret = WOLFSSL_FATAL_ERROR;
+            }
+        }
+    }
+
+    if (bytes > 0 && ret == WOLFSSL_SUCCESS) {
+        wolfSSL_RAND_Init(); /* call to check global RNG is created */
+        if (wc_RNG_DRBG_Reseed(&globalRNG, (const byte*) buf, bytes)
+                != 0) {
+            WOLFSSL_MSG("Error with reseeding DRBG structure");
+            ret = WOLFSSL_FATAL_ERROR;
+        }
+        #ifdef SHOW_SECRETS
+        { /* print out entropy found */
+            word32 i;
+            printf("EGD Entropy = ");
+            for (i = 0; i < bytes; i++) {
+                printf("%02X", buf[i]);
+            }
+            printf("\n");
+        }
+        #endif
+    }
+
+    ForceZero(buf, bytes);
+    #ifdef WOLFSSL_SMALL_STACK
+    XFREE(buf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    #endif
+    close(fd);
+
+    if (ret == WOLFSSL_SUCCESS) {
+        return bytes;
+    }
+    else {
+        return ret;
+    }
+#else
+    WOLFSSL_MSG("Type of socket needed is not available");
+    WOLFSSL_MSG("\tor using mode where DRBG API is not available");
+    (void)nm;
+
+    return WOLFSSL_FATAL_ERROR;
+#endif /* USE_WOLFSSL_IO && !USE_WINDOWS_API && !HAVE_FIPS && HAVE_HASHDRBG */
+}
+
+#endif /* !FREERTOS_TCP */
+
+void wolfSSL_RAND_Cleanup(void)
+{
+    WOLFSSL_ENTER("wolfSSL_RAND_Cleanup()");
+
+    if (initGlobalRNG != 0) {
+        wc_FreeRng(&globalRNG);
+        initGlobalRNG = 0;
+    }
+}
+
+
+int wolfSSL_RAND_pseudo_bytes(unsigned char* buf, int num)
+{
+    return wolfSSL_RAND_bytes(buf, num);
+}
+
+
+/* SSL_SUCCESS on ok */
+int wolfSSL_RAND_bytes(unsigned char* buf, int num)
+{
+    int     ret = 0;
+    int     initTmpRng = 0;
+    WC_RNG* rng = NULL;
+#ifdef WOLFSSL_SMALL_STACK
+    WC_RNG* tmpRNG;
+#else
+    WC_RNG  tmpRNG[1];
+#endif
+
+    WOLFSSL_ENTER("wolfSSL_RAND_bytes");
+
+#ifdef WOLFSSL_SMALL_STACK
+    tmpRNG = (WC_RNG*)XMALLOC(sizeof(WC_RNG), NULL, DYNAMIC_TYPE_RNG);
+    if (tmpRNG == NULL)
+        return ret;
+#endif
+
+    if (initGlobalRNG)
+        rng = &globalRNG;
+    else if(wc_InitRng(tmpRNG) == 0) {
+        rng = tmpRNG;
+        initTmpRng = 1;
+    }
+    if (rng) {
+        if (wc_RNG_GenerateBlock(rng, buf, num) != 0)
+            WOLFSSL_MSG("Bad wc_RNG_GenerateBlock");
+        else
+            ret = WOLFSSL_SUCCESS;
+    }
+
+    if (initTmpRng)
+        wc_FreeRng(tmpRNG);
+
+#ifdef WOLFSSL_SMALL_STACK
+    XFREE(tmpRNG, NULL, DYNAMIC_TYPE_RNG);
+#endif
+
+    return ret;
+}
+
+
+int wolfSSL_RAND_poll(void)
+{
+    byte  entropy[16];
+    int  ret = 0;
+    word32 entropy_sz = 16;
+
+    WOLFSSL_ENTER("wolfSSL_RAND_poll");
+    if (initGlobalRNG == 0){
+        WOLFSSL_MSG("Global RNG no Init");
+        return  WOLFSSL_FAILURE;
+    }
+    ret = wc_GenerateSeed(&globalRNG.seed, entropy, entropy_sz);
+    if (ret != 0){
+        WOLFSSL_MSG("Bad wc_RNG_GenerateBlock");
+        ret = WOLFSSL_FAILURE;
+    }else
+        ret = WOLFSSL_SUCCESS;
+
+    return ret;
+}
+#endif /* OPENSSL_EXTRA */
+
+
+
+#ifdef OPENSSL_EXTRA
+
+WOLFSSL_ASN1_INTEGER* wolfSSL_BN_to_ASN1_INTEGER(const WOLFSSL_BIGNUM *bn, WOLFSSL_ASN1_INTEGER *ai)
+{
+    WOLFSSL_ASN1_INTEGER* a;
+    int len;
+    WOLFSSL_ENTER("wolfSSL_BN_to_ASN1_INTEGER");
+
+    if (ai == NULL) {
+        a = wolfSSL_ASN1_INTEGER_new();
+
+        if (a == NULL)
+            return NULL;
+
+        a->type = V_ASN1_INTEGER;
+    }
+    else {
+        a = ai;
+    }
+    if (a) {
+        if (wolfSSL_BN_is_negative(bn) && !wolfSSL_BN_is_zero(bn)) {
+            a->type |= V_ASN1_NEG_INTEGER;
+            a->negative = 1;
+        }
+
+        len = wolfSSL_BN_num_bytes(bn);
+        if (len == 0)
+            len = 1;
+
+        /* allocate buffer */
+        if (len > (int)sizeof(a->intData)) {
+            /* create new data buffer and copy over */
+            a->data = (byte*)XMALLOC(len, NULL, DYNAMIC_TYPE_OPENSSL);
+            if (a->data == NULL) {
+                if (a != ai)
+                    wolfSSL_ASN1_INTEGER_free(a);
+                return NULL;
+            }
+            a->isDynamic = 1;
+        }
+        else {
+            XMEMSET(a->intData, 0, sizeof(a->intData));
+            a->data = a->intData;
+        }
+        a->length = len;
+
+        /* populate data */
+        if (wolfSSL_BN_is_zero(bn)) {
+            a->data[0] = 0;
+        }
+        else {
+            len = wolfSSL_BN_bn2bin(bn, a->data);
+        }
+        a->length = len;
+    }
+
+    return a;
+}
+
+#ifdef OPENSSL_ALL
+void *wolfSSL_ASN1_item_new(const WOLFSSL_ASN1_ITEM *template)
+{
+    void *ret = NULL;
+    const WOLFSSL_ASN1_TEMPLATE *member = NULL;
+    size_t i;
+    WOLFSSL_ENTER("wolfSSL_ASN1_item_new");
+    if (!template) {
+        return NULL;
+    }
+    if (!(ret = XMALLOC(template->size, NULL, DYNAMIC_TYPE_OPENSSL))) {
+        return NULL;
+    }
+    XMEMSET(ret, 0, template->size);
+    for (member = template->members, i = 0; i < template->mcount;
+            member++, i++) {
+        switch (member->type) {
+            case WOLFSSL_X509_ALGOR_ASN1:
+            {
+                WOLFSSL_X509_ALGOR* algor = wolfSSL_X509_ALGOR_new();
+                if (!algor) {
+                    goto error;
+                }
+                *(WOLFSSL_X509_ALGOR**)(((byte*)ret) + member->offset) = algor;
+                break;
+            }
+            case WOLFSSL_ASN1_BIT_STRING_ASN1:
+            {
+                WOLFSSL_ASN1_BIT_STRING* bit_str = wolfSSL_ASN1_BIT_STRING_new();
+                if (!bit_str) {
+                    goto error;
+                }
+                *(WOLFSSL_ASN1_BIT_STRING**)(((byte*)ret) + member->offset) = bit_str;
+                break;
+            }
+            default:
+                WOLFSSL_MSG("Type not supported in wolfSSL_ASN1_item_new");
+                goto error;
+        }
+    }
+    return ret;
+error:
+    wolfSSL_ASN1_item_free(ret, template);
+    return NULL;
+}
+
+void wolfSSL_ASN1_item_free(void *val, const WOLFSSL_ASN1_ITEM *template)
+{
+    const WOLFSSL_ASN1_TEMPLATE *member = NULL;
+    size_t i;
+    WOLFSSL_ENTER("wolfSSL_ASN1_item_free");
+    if (val) {
+        for (member = template->members, i = 0; i < template->mcount;
+                member++, i++) {
+            switch (member->type) {
+                case WOLFSSL_X509_ALGOR_ASN1:
+                {
+                    WOLFSSL_X509_ALGOR* algor = *(WOLFSSL_X509_ALGOR**)
+                                                 (((byte*)val) + member->offset);
+                    if (algor) {
+                        wolfSSL_X509_ALGOR_free(algor);
+                    }
+                    break;
+                }
+                case WOLFSSL_ASN1_BIT_STRING_ASN1:
+                {
+                    WOLFSSL_ASN1_BIT_STRING* bit_str = *(WOLFSSL_ASN1_BIT_STRING**)
+                                                        (((byte*)val) + member->offset);
+                    if (bit_str) {
+                        wolfSSL_ASN1_BIT_STRING_free(bit_str);
+                    }
+                    break;
+                }
+                default:
+                    WOLFSSL_MSG("Type not supported in wolfSSL_ASN1_item_free");
+            }
+        }
+        XFREE(val, NULL, DYNAMIC_TYPE_OPENSSL);
+    }
+}
+
+#define bufLenOrNull(buf, len) (buf ? buf + len : NULL)
+
+static int i2dProcessMembers(const void *src, byte *buf,
+                          const WOLFSSL_ASN1_TEMPLATE *members, size_t mcount)
+{
+    const WOLFSSL_ASN1_TEMPLATE *member = NULL;
+    int len = 0, ret;
+    size_t i;
+    WOLFSSL_ENTER("processMembers");
+    for (member = members, i = 0; i < mcount; member++, i++) {
+        switch (member->type) {
+            case WOLFSSL_X509_ALGOR_ASN1:
+            {
+                word32 oid = 0;
+                word32 idx = 0;
+                const WOLFSSL_X509_ALGOR* algor = *(const WOLFSSL_X509_ALGOR**)
+                                                   (((byte*)src) + member->offset);
+                if (!algor->algorithm) {
+                    WOLFSSL_LEAVE("processMembers", WOLFSSL_FAILURE);
+                    return WOLFSSL_FAILURE;
+                }
+
+                if (GetObjectId(algor->algorithm->obj, &idx, &oid,
+                        algor->algorithm->grp, algor->algorithm->objSz) < 0) {
+                    WOLFSSL_MSG("Issue getting OID of object");
+                    return -1;
+                }
+
+                ret = SetAlgoID(oid, bufLenOrNull(buf, len),
+                                algor->algorithm->grp, 0);
+                if (!ret) {
+                    return WOLFSSL_FAILURE;
+                }
+                len += ret;
+                break;
+            }
+            case WOLFSSL_ASN1_BIT_STRING_ASN1:
+            {
+                const WOLFSSL_ASN1_BIT_STRING* bit_str;
+                bit_str = *(const WOLFSSL_ASN1_BIT_STRING**)
+                           (((byte*)src) + member->offset);
+                len += SetBitString(bit_str->length, 0, bufLenOrNull(buf, len));
+                if (buf && bit_str->data) {
+                    XMEMCPY(buf + len, bit_str->data, bit_str->length);
+                }
+                len += bit_str->length;
+                break;
+            }
+            default:
+                WOLFSSL_MSG("Type not support in processMembers");
+                WOLFSSL_LEAVE("processMembers", WOLFSSL_FAILURE);
+                return WOLFSSL_FAILURE;
+        }
+    }
+    WOLFSSL_LEAVE("processMembers", len);
+    return len;
+}
+
+int wolfSSL_ASN1_item_i2d(const void *src, byte **dest,
+                          const WOLFSSL_ASN1_ITEM *template)
+{
+    int len = 0;
+    byte *buf = NULL;
+
+    WOLFSSL_ENTER("wolfSSL_ASN1_item_i2d");
+
+    if (!src || !template) {
+        WOLFSSL_LEAVE("wolfSSL_ASN1_item_i2d", WOLFSSL_FAILURE);
+        return WOLFSSL_FAILURE;
+    }
+
+    if (dest && !*dest) {
+        len = wolfSSL_ASN1_item_i2d(src, NULL, template);
+        if (!len) {
+            goto error;
+        }
+        buf = (byte*)XMALLOC(len, NULL, DYNAMIC_TYPE_ASN1);
+        if (!buf) {
+            goto error;
+        }
+        len = 0;
+    }
+
+    switch (template->type) {
+        case ASN_SEQUENCE:
+        {
+            int seq_len = i2dProcessMembers(src, NULL, template->members,
+                                         template->mcount);
+            if (!seq_len) {
+                goto error;
+            }
+            len += SetSequence(seq_len, bufLenOrNull(buf, len));
+            if (buf &&
+                    i2dProcessMembers(src, bufLenOrNull(buf, len), template->members,
+                                   template->mcount) != seq_len) {
+                WOLFSSL_MSG("Inconsistent sequence length");
+                goto error;
+            }
+            len += seq_len;
+            break;
+        }
+        default:
+            WOLFSSL_MSG("Type not supported in wolfSSL_ASN1_item_i2d");
+            goto error;
+    }
+
+    if (dest && !*dest) {
+        *dest = buf;
+    }
+    else if (dest && *dest && buf) {
+        /* *dest length is not checked because the user is responsible
+         * for providing a long enough buffer */
+        XMEMCPY(*dest, buf, len);
+    }
+
+    WOLFSSL_LEAVE("wolfSSL_ASN1_item_i2d", len);
+    return len;
+error:
+    if (buf) {
+        XFREE(buf, NULL, DYNAMIC_TYPE_ASN1);
+    }
+    WOLFSSL_LEAVE("wolfSSL_ASN1_item_i2d", WOLFSSL_FAILURE);
+    return WOLFSSL_FAILURE;
+}
+#endif /* OPENSSL_ALL */
+
+#ifndef NO_DH
+
+static void InitwolfSSL_DH(WOLFSSL_DH* dh)
+{
+    if (dh) {
+        XMEMSET(dh, 0, sizeof(WOLFSSL_DH));
+    }
+}
+
+
+WOLFSSL_DH* wolfSSL_DH_new(void)
+{
+    WOLFSSL_DH* external;
+    DhKey*     key;
+
+    WOLFSSL_MSG("wolfSSL_DH_new");
+
+    key = (DhKey*) XMALLOC(sizeof(DhKey), NULL, DYNAMIC_TYPE_DH);
+    if (key == NULL) {
+        WOLFSSL_MSG("wolfSSL_DH_new malloc DhKey failure");
+        return NULL;
+    }
+
+    external = (WOLFSSL_DH*) XMALLOC(sizeof(WOLFSSL_DH), NULL,
+                                    DYNAMIC_TYPE_DH);
+    if (external == NULL) {
+        WOLFSSL_MSG("wolfSSL_DH_new malloc WOLFSSL_DH failure");
+        XFREE(key, NULL, DYNAMIC_TYPE_DH);
+        return NULL;
+    }
+
+    InitwolfSSL_DH(external);
+    if (wc_InitDhKey(key) != 0) {
+        WOLFSSL_MSG("wolfSSL_DH_new InitDhKey failure");
+        XFREE(key, NULL, DYNAMIC_TYPE_DH);
+        XFREE(external, NULL, DYNAMIC_TYPE_DH);
+        return NULL;
+    }
+    external->internal = key;
+
+    return external;
+}
+
+
+void wolfSSL_DH_free(WOLFSSL_DH* dh)
+{
+    WOLFSSL_MSG("wolfSSL_DH_free");
+
+    if (dh) {
+        if (dh->internal) {
+            wc_FreeDhKey((DhKey*)dh->internal);
+            XFREE(dh->internal, NULL, DYNAMIC_TYPE_DH);
+            dh->internal = NULL;
+        }
+        wolfSSL_BN_free(dh->priv_key);
+        wolfSSL_BN_free(dh->pub_key);
+        wolfSSL_BN_free(dh->g);
+        wolfSSL_BN_free(dh->p);
+        wolfSSL_BN_free(dh->q);
+        InitwolfSSL_DH(dh);  /* set back to NULLs for safety */
+
+        XFREE(dh, NULL, DYNAMIC_TYPE_DH);
+    }
+}
+
+int SetDhInternal(WOLFSSL_DH* dh)
+{
+    int            ret = WOLFSSL_FATAL_ERROR;
+    int            pSz = 1024;
+    int            gSz = 1024;
+#if defined(WOLFSSL_QT) || defined(OPENSSL_ALL)
+    int            privSz = 256; /* Up to 2048-bit */
+    int            pubSz  = 256;
+#endif
+#ifdef WOLFSSL_SMALL_STACK
+    unsigned char* p   = NULL;
+    unsigned char* g   = NULL;
+    #if defined(WOLFSSL_QT) || defined(OPENSSL_ALL)
+        unsigned char* priv_key = NULL;
+        unsigned char* pub_key = NULL;
+    #endif
+#else
+    unsigned char  p[1024];
+    unsigned char  g[1024];
+    #if defined(WOLFSSL_QT) || defined(OPENSSL_ALL)
+        unsigned char priv_key[256];
+        unsigned char pub_key[256];
+    #endif
+#endif
+
+    WOLFSSL_ENTER("SetDhInternal");
+
+    if (dh == NULL || dh->p == NULL || dh->g == NULL)
+        WOLFSSL_MSG("Bad function arguments");
+    else if (wolfSSL_BN_bn2bin(dh->p, NULL) > pSz)
+        WOLFSSL_MSG("Bad p internal size");
+    else if (wolfSSL_BN_bn2bin(dh->g, NULL) > gSz)
+        WOLFSSL_MSG("Bad g internal size");
+    #if defined(WOLFSSL_QT) || defined(OPENSSL_ALL)
+    else if (wolfSSL_BN_bn2bin(dh->priv_key, NULL) > privSz)
+        WOLFSSL_MSG("Bad private key internal size");
+    else if (wolfSSL_BN_bn2bin(dh->pub_key, NULL) > privSz)
+        WOLFSSL_MSG("Bad public key internal size");
+    #endif
+    else {
+    #ifdef WOLFSSL_SMALL_STACK
+        p = (unsigned char*)XMALLOC(pSz, NULL, DYNAMIC_TYPE_PUBLIC_KEY);
+        g = (unsigned char*)XMALLOC(gSz, NULL, DYNAMIC_TYPE_PUBLIC_KEY);
+
+    #if defined(WOLFSSL_QT) || defined(OPENSSL_ALL)
+        priv_key = (unsigned char*)XMALLOC(privSz,NULL,DYNAMIC_TYPE_PRIVATE_KEY);
+        pub_key  = (unsigned char*)XMALLOC(pubSz,NULL,DYNAMIC_TYPE_PUBLIC_KEY);
+    #endif
+
+        if (p == NULL || g == NULL) {
+            XFREE(p, NULL, DYNAMIC_TYPE_PUBLIC_KEY);
+            XFREE(g, NULL, DYNAMIC_TYPE_PUBLIC_KEY);
+            return ret;
+        }
+    #endif /* WOLFSSL_SMALL_STACK */
+
+    #if defined(WOLFSSL_QT) || defined(OPENSSL_ALL)
+        privSz = wolfSSL_BN_bn2bin(dh->priv_key, priv_key);
+        pubSz  = wolfSSL_BN_bn2bin(dh->pub_key,  pub_key);
+        if (privSz <= 0) {
+            WOLFSSL_MSG("No private key size.");
+        }
+        if (pubSz <= 0) {
+            WOLFSSL_MSG("No public key size.");
+        }
+        if (privSz > 0 || pubSz > 0) {
+            ret = wc_DhSetFullKeys((DhKey*)dh->internal,priv_key,privSz,
+                                    pub_key,pubSz);
+            if (ret == WOLFSSL_FAILURE) {
+                WOLFSSL_MSG("Failed setting private or public key.");
+            }
+        }
+    #endif /* WOLFSSL_QT || OPENSSL_ALL */
+
+        pSz = wolfSSL_BN_bn2bin(dh->p, p);
+        gSz = wolfSSL_BN_bn2bin(dh->g, g);
+
+        if (pSz <= 0 || gSz <= 0)
+            WOLFSSL_MSG("Bad BN2bin set");
+        else if (wc_DhSetKey((DhKey*)dh->internal, p, pSz, g, gSz) < 0)
+            WOLFSSL_MSG("Bad DH SetKey");
+        else {
+            dh->inSet = 1;
+            ret = WOLFSSL_SUCCESS;
+        }
+
+    #ifdef WOLFSSL_SMALL_STACK
+        XFREE(p, NULL, DYNAMIC_TYPE_PUBLIC_KEY);
+        XFREE(g, NULL, DYNAMIC_TYPE_PUBLIC_KEY);
+        #if defined(WOLFSSL_QT) || defined(OPENSSL_ALL)
+            XFREE(priv_key, NULL, DYNAMIC_TYPE_PRIVATE_KEY);
+            XFREE(pub_key,  NULL, DYNAMIC_TYPE_PUBLIC_KEY);
+        #endif
+    #endif
+    }
+
+
+    return ret;
+}
+
+#if !defined(NO_DH) && (defined(WOLFSSL_QT) || defined(OPENSSL_ALL) || defined(WOLFSSL_OPENSSH))
+/* Set the members of DhKey into WOLFSSL_DH
+ * DhKey was populated from wc_DhKeyDecode
+ */
+int SetDhExternal(WOLFSSL_DH *dh)
+{
+    DhKey *key;
+    WOLFSSL_MSG("Entering SetDhExternal");
+
+    if (dh == NULL || dh->internal == NULL) {
+        WOLFSSL_MSG("dh key NULL error");
+    }
+
+    key = (DhKey*)dh->internal;
+
+    if (SetIndividualExternal(&dh->p, &key->p) != WOLFSSL_SUCCESS) {
+        WOLFSSL_MSG("dh param p error");
+        return WOLFSSL_FATAL_ERROR;
+    }
+
+    if (SetIndividualExternal(&dh->g, &key->g) != WOLFSSL_SUCCESS) {
+        WOLFSSL_MSG("dh param g error");
+        return WOLFSSL_FATAL_ERROR;
+    }
+
+    if (SetIndividualExternal(&dh->priv_key, &key->priv) != WOLFSSL_SUCCESS) {
+        WOLFSSL_MSG("No DH Private Key");
+        return WOLFSSL_FATAL_ERROR;
+    }
+
+    if (SetIndividualExternal(&dh->pub_key, &key->pub) != WOLFSSL_SUCCESS) {
+        WOLFSSL_MSG("No DH Public Key");
+        return WOLFSSL_FATAL_ERROR;
+    }
+
+    dh->exSet = 1;
+
+    return WOLFSSL_SUCCESS;
+}
+#endif /* !NO_DH && (WOLFSSL_QT || OPENSSL_ALL) */
+
+/* return code compliant with OpenSSL :
+ *   DH prime size in bytes if success, 0 if error
+ */
+int wolfSSL_DH_size(WOLFSSL_DH* dh)
+{
+    WOLFSSL_MSG("wolfSSL_DH_size");
+
+    if (dh == NULL)
+        return WOLFSSL_FATAL_ERROR;
+
+    return wolfSSL_BN_num_bytes(dh->p);
+}
+
+/* This sets a big number with the 768-bit prime from RFC 2409.
+ *
+ * bn  if not NULL then the big number structure is used. If NULL then a new
+ *     big number structure is created.
+ *
+ * Returns a WOLFSSL_BIGNUM structure on success and NULL with failure.
+ */
+WOLFSSL_BIGNUM* wolfSSL_DH_768_prime(WOLFSSL_BIGNUM* bn)
+{
+    const char prm[] = {
+        "FFFFFFFFFFFFFFFFC90FDAA22168C234"
+        "C4C6628B80DC1CD129024E088A67CC74"
+        "020BBEA63B139B22514A08798E3404DD"
+        "EF9519B3CD3A431B302B0A6DF25F1437"
+        "4FE1356D6D51C245E485B576625E7EC6"
+        "F44C42E9A63A3620FFFFFFFFFFFFFFFF"
+    };
+
+    WOLFSSL_ENTER("wolfSSL_DH_768_prime");
+
+    if (wolfSSL_BN_hex2bn(&bn, prm) != SSL_SUCCESS) {
+        WOLFSSL_MSG("Error converting DH 768 prime to big number");
+        return NULL;
+    }
+
+    return bn;
+}
+
+/* This sets a big number with the 1024-bit prime from RFC 2409.
+ *
+ * bn  if not NULL then the big number structure is used. If NULL then a new
+ *     big number structure is created.
+ *
+ * Returns a WOLFSSL_BIGNUM structure on success and NULL with failure.
+ */
+WOLFSSL_BIGNUM* wolfSSL_DH_1024_prime(WOLFSSL_BIGNUM* bn)
+{
+    const char prm[] = {
+        "FFFFFFFFFFFFFFFFC90FDAA22168C234"
+        "C4C6628B80DC1CD129024E088A67CC74"
+        "020BBEA63B139B22514A08798E3404DD"
+        "EF9519B3CD3A431B302B0A6DF25F1437"
+        "4FE1356D6D51C245E485B576625E7EC6"
+        "F44C42E9A637ED6B0BFF5CB6F406B7ED"
+        "EE386BFB5A899FA5AE9F24117C4B1FE6"
+        "49286651ECE65381FFFFFFFFFFFFFFFF"
+    };
+
+    WOLFSSL_ENTER("wolfSSL_DH_1024_prime");
+
+    if (wolfSSL_BN_hex2bn(&bn, prm) != SSL_SUCCESS) {
+        WOLFSSL_MSG("Error converting DH 1024 prime to big number");
+        return NULL;
+    }
+
+    return bn;
+}
+
+/* This sets a big number with the 1536-bit prime from RFC 3526.
+ *
+ * bn  if not NULL then the big number structure is used. If NULL then a new
+ *     big number structure is created.
+ *
+ * Returns a WOLFSSL_BIGNUM structure on success and NULL with failure.
+ */
+WOLFSSL_BIGNUM* wolfSSL_DH_1536_prime(WOLFSSL_BIGNUM* bn)
+{
+    const char prm[] = {
+        "FFFFFFFFFFFFFFFFC90FDAA22168C234"
+        "C4C6628B80DC1CD129024E088A67CC74"
+        "020BBEA63B139B22514A08798E3404DD"
+        "EF9519B3CD3A431B302B0A6DF25F1437"
+        "4FE1356D6D51C245E485B576625E7EC6"
+        "F44C42E9A637ED6B0BFF5CB6F406B7ED"
+        "EE386BFB5A899FA5AE9F24117C4B1FE6"
+        "49286651ECE45B3DC2007CB8A163BF05"
+        "98DA48361C55D39A69163FA8FD24CF5F"
+        "83655D23DCA3AD961C62F356208552BB"
+        "9ED529077096966D670C354E4ABC9804"
+        "F1746C08CA237327FFFFFFFFFFFFFFFF"
+    };
+
+    WOLFSSL_ENTER("wolfSSL_DH_1536_prime");
+
+    if (wolfSSL_BN_hex2bn(&bn, prm) != SSL_SUCCESS) {
+        WOLFSSL_MSG("Error converting DH 1536 prime to big number");
+        return NULL;
+    }
+
+    return bn;
+}
+
+/* This sets a big number with the 2048-bit prime from RFC 3526.
+ *
+ * bn  if not NULL then the big number structure is used. If NULL then a new
+ *     big number structure is created.
+ *
+ * Returns a WOLFSSL_BIGNUM structure on success and NULL with failure.
+ */
+WOLFSSL_BIGNUM* wolfSSL_DH_2048_prime(WOLFSSL_BIGNUM* bn)
+{
+    const char prm[] = {
+        "FFFFFFFFFFFFFFFFC90FDAA22168C234"
+        "C4C6628B80DC1CD129024E088A67CC74"
+        "020BBEA63B139B22514A08798E3404DD"
+        "EF9519B3CD3A431B302B0A6DF25F1437"
+        "4FE1356D6D51C245E485B576625E7EC6"
+        "F44C42E9A637ED6B0BFF5CB6F406B7ED"
+        "EE386BFB5A899FA5AE9F24117C4B1FE6"
+        "49286651ECE45B3DC2007CB8A163BF05"
+        "98DA48361C55D39A69163FA8FD24CF5F"
+        "83655D23DCA3AD961C62F356208552BB"
+        "9ED529077096966D670C354E4ABC9804"
+        "F1746C08CA18217C32905E462E36CE3B"
+        "E39E772C180E86039B2783A2EC07A28F"
+        "B5C55DF06F4C52C9DE2BCBF695581718"
+        "3995497CEA956AE515D2261898FA0510"
+        "15728E5A8AACAA68FFFFFFFFFFFFFFFF"
+    };
+
+    WOLFSSL_ENTER("wolfSSL_DH_2048_prime");
+
+    if (wolfSSL_BN_hex2bn(&bn, prm) != SSL_SUCCESS) {
+        WOLFSSL_MSG("Error converting DH 2048 prime to big number");
+        return NULL;
+    }
+
+    return bn;
+}
+
+/* This sets a big number with the 3072-bit prime from RFC 3526.
+ *
+ * bn  if not NULL then the big number structure is used. If NULL then a new
+ *     big number structure is created.
+ *
+ * Returns a WOLFSSL_BIGNUM structure on success and NULL with failure.
+ */
+WOLFSSL_BIGNUM* wolfSSL_DH_3072_prime(WOLFSSL_BIGNUM* bn)
+{
+    const char prm[] = {
+        "FFFFFFFFFFFFFFFFC90FDAA22168C234"
+        "C4C6628B80DC1CD129024E088A67CC74"
+        "020BBEA63B139B22514A08798E3404DD"
+        "EF9519B3CD3A431B302B0A6DF25F1437"
+        "4FE1356D6D51C245E485B576625E7EC6"
+        "F44C42E9A637ED6B0BFF5CB6F406B7ED"
+        "EE386BFB5A899FA5AE9F24117C4B1FE6"
+        "49286651ECE45B3DC2007CB8A163BF05"
+        "98DA48361C55D39A69163FA8FD24CF5F"
+        "83655D23DCA3AD961C62F356208552BB"
+        "9ED529077096966D670C354E4ABC9804"
+        "F1746C08CA18217C32905E462E36CE3B"
+        "E39E772C180E86039B2783A2EC07A28F"
+        "B5C55DF06F4C52C9DE2BCBF695581718"
+        "3995497CEA956AE515D2261898FA0510"
+        "15728E5A8AAAC42DAD33170D04507A33"
+        "A85521ABDF1CBA64ECFB850458DBEF0A"
+        "8AEA71575D060C7DB3970F85A6E1E4C7"
+        "ABF5AE8CDB0933D71E8C94E04A25619D"
+        "CEE3D2261AD2EE6BF12FFA06D98A0864"
+        "D87602733EC86A64521F2B18177B200C"
+        "BBE117577A615D6C770988C0BAD946E2"
+        "08E24FA074E5AB3143DB5BFCE0FD108E"
+        "4B82D120A93AD2CAFFFFFFFFFFFFFFFF"
+    };
+
+    WOLFSSL_ENTER("wolfSSL_DH_3072_prime");
+
+    if (wolfSSL_BN_hex2bn(&bn, prm) != SSL_SUCCESS) {
+        WOLFSSL_MSG("Error converting DH 3072 prime to big number");
+        return NULL;
+    }
+
+    return bn;
+}
+
+/* This sets a big number with the 4096-bit prime from RFC 3526.
+ *
+ * bn  if not NULL then the big number structure is used. If NULL then a new
+ *     big number structure is created.
+ *
+ * Returns a WOLFSSL_BIGNUM structure on success and NULL with failure.
+ */
+WOLFSSL_BIGNUM* wolfSSL_DH_4096_prime(WOLFSSL_BIGNUM* bn)
+{
+    const char prm[] = {
+        "FFFFFFFFFFFFFFFFC90FDAA22168C234"
+        "C4C6628B80DC1CD129024E088A67CC74"
+        "020BBEA63B139B22514A08798E3404DD"
+        "EF9519B3CD3A431B302B0A6DF25F1437"
+        "4FE1356D6D51C245E485B576625E7EC6"
+        "F44C42E9A637ED6B0BFF5CB6F406B7ED"
+        "EE386BFB5A899FA5AE9F24117C4B1FE6"
+        "49286651ECE45B3DC2007CB8A163BF05"
+        "98DA48361C55D39A69163FA8FD24CF5F"
+        "83655D23DCA3AD961C62F356208552BB"
+        "9ED529077096966D670C354E4ABC9804"
+        "F1746C08CA18217C32905E462E36CE3B"
+        "E39E772C180E86039B2783A2EC07A28F"
+        "B5C55DF06F4C52C9DE2BCBF695581718"
+        "3995497CEA956AE515D2261898FA0510"
+        "15728E5A8AAAC42DAD33170D04507A33"
+        "A85521ABDF1CBA64ECFB850458DBEF0A"
+        "8AEA71575D060C7DB3970F85A6E1E4C7"
+        "ABF5AE8CDB0933D71E8C94E04A25619D"
+        "CEE3D2261AD2EE6BF12FFA06D98A0864"
+        "D87602733EC86A64521F2B18177B200C"
+        "BBE117577A615D6C770988C0BAD946E2"
+        "08E24FA074E5AB3143DB5BFCE0FD108E"
+        "4B82D120A92108011A723C12A787E6D7"
+        "88719A10BDBA5B2699C327186AF4E23C"
+        "1A946834B6150BDA2583E9CA2AD44CE8"
+        "DBBBC2DB04DE8EF92E8EFC141FBECAA6"
+        "287C59474E6BC05D99B2964FA090C3A2"
+        "233BA186515BE7ED1F612970CEE2D7AF"
+        "B81BDD762170481CD0069127D5B05AA9"
+        "93B4EA988D8FDDC186FFB7DC90A6C08F"
+        "4DF435C934063199FFFFFFFFFFFFFFFF"
+    };
+
+    WOLFSSL_ENTER("wolfSSL_DH_4096_prime");
+
+    if (wolfSSL_BN_hex2bn(&bn, prm) != SSL_SUCCESS) {
+        WOLFSSL_MSG("Error converting DH 4096 prime to big number");
+        return NULL;
+    }
+
+    return bn;
+}
+
+/* This sets a big number with the 6144-bit prime from RFC 3526.
+ *
+ * bn  if not NULL then the big number structure is used. If NULL then a new
+ *     big number structure is created.
+ *
+ * Returns a WOLFSSL_BIGNUM structure on success and NULL with failure.
+ */
+WOLFSSL_BIGNUM* wolfSSL_DH_6144_prime(WOLFSSL_BIGNUM* bn)
+{
+    const char prm[] = {
+        "FFFFFFFFFFFFFFFFC90FDAA22168C234"
+        "C4C6628B80DC1CD129024E088A67CC74"
+        "020BBEA63B139B22514A08798E3404DD"
+        "EF9519B3CD3A431B302B0A6DF25F1437"
+        "4FE1356D6D51C245E485B576625E7EC6"
+        "F44C42E9A637ED6B0BFF5CB6F406B7ED"
+        "EE386BFB5A899FA5AE9F24117C4B1FE6"
+        "49286651ECE45B3DC2007CB8A163BF05"
+        "98DA48361C55D39A69163FA8FD24CF5F"
+        "83655D23DCA3AD961C62F356208552BB"
+        "9ED529077096966D670C354E4ABC9804"
+        "F1746C08CA18217C32905E462E36CE3B"
+        "E39E772C180E86039B2783A2EC07A28F"
+        "B5C55DF06F4C52C9DE2BCBF695581718"
+        "3995497CEA956AE515D2261898FA0510"
+        "15728E5A8AAAC42DAD33170D04507A33"
+        "A85521ABDF1CBA64ECFB850458DBEF0A"
+        "8AEA71575D060C7DB3970F85A6E1E4C7"
+        "ABF5AE8CDB0933D71E8C94E04A25619D"
+        "CEE3D2261AD2EE6BF12FFA06D98A0864"
+        "D87602733EC86A64521F2B18177B200C"
+        "BBE117577A615D6C770988C0BAD946E2"
+        "08E24FA074E5AB3143DB5BFCE0FD108E"
+        "4B82D120A92108011A723C12A787E6D7"
+        "88719A10BDBA5B2699C327186AF4E23C"
+        "1A946834B6150BDA2583E9CA2AD44CE8"
+        "DBBBC2DB04DE8EF92E8EFC141FBECAA6"
+        "287C59474E6BC05D99B2964FA090C3A2"
+        "233BA186515BE7ED1F612970CEE2D7AF"
+        "B81BDD762170481CD0069127D5B05AA9"
+        "93B4EA988D8FDDC186FFB7DC90A6C08F"
+        "4DF435C93402849236C3FAB4D27C7026"
+        "C1D4DCB2602646DEC9751E763DBA37BD"
+        "F8FF9406AD9E530EE5DB382F413001AE"
+        "B06A53ED9027D831179727B0865A8918"
+        "DA3EDBEBCF9B14ED44CE6CBACED4BB1B"
+        "DB7F1447E6CC254B332051512BD7AF42"
+        "6FB8F401378CD2BF5983CA01C64B92EC"
+        "F032EA15D1721D03F482D7CE6E74FEF6"
+        "D55E702F46980C82B5A84031900B1C9E"
+        "59E7C97FBEC7E8F323A97A7E36CC88BE"
+        "0F1D45B7FF585AC54BD407B22B4154AA"
+        "CC8F6D7EBF48E1D814CC5ED20F8037E0"
+        "A79715EEF29BE32806A1D58BB7C5DA76"
+        "F550AA3D8A1FBFF0EB19CCB1A313D55C"
+        "DA56C9EC2EF29632387FE8D76E3C0468"
+        "043E8F663F4860EE12BF2D5B0B7474D6"
+        "E694F91E6DCC4024FFFFFFFFFFFFFFFF"
+    };
+
+    WOLFSSL_ENTER("wolfSSL_DH_6144_prime");
+
+    if (wolfSSL_BN_hex2bn(&bn, prm) != SSL_SUCCESS) {
+        WOLFSSL_MSG("Error converting DH 6144 prime to big number");
+        return NULL;
+    }
+
+    return bn;
+}
+
+
+/* This sets a big number with the 8192-bit prime from RFC 3526.
+ *
+ * bn  if not NULL then the big number structure is used. If NULL then a new
+ *     big number structure is created.
+ *
+ * Returns a WOLFSSL_BIGNUM structure on success and NULL with failure.
+ */
+WOLFSSL_BIGNUM* wolfSSL_DH_8192_prime(WOLFSSL_BIGNUM* bn)
+{
+    const char prm[] = {
+        "FFFFFFFFFFFFFFFFC90FDAA22168C234"
+        "C4C6628B80DC1CD129024E088A67CC74"
+        "020BBEA63B139B22514A08798E3404DD"
+        "EF9519B3CD3A431B302B0A6DF25F1437"
+        "4FE1356D6D51C245E485B576625E7EC6"
+        "F44C42E9A637ED6B0BFF5CB6F406B7ED"
+        "EE386BFB5A899FA5AE9F24117C4B1FE6"
+        "49286651ECE45B3DC2007CB8A163BF05"
+        "98DA48361C55D39A69163FA8FD24CF5F"
+        "83655D23DCA3AD961C62F356208552BB"
+        "9ED529077096966D670C354E4ABC9804"
+        "F1746C08CA18217C32905E462E36CE3B"
+        "E39E772C180E86039B2783A2EC07A28F"
+        "B5C55DF06F4C52C9DE2BCBF695581718"
+        "3995497CEA956AE515D2261898FA0510"
+        "15728E5A8AAAC42DAD33170D04507A33"
+        "A85521ABDF1CBA64ECFB850458DBEF0A"
+        "8AEA71575D060C7DB3970F85A6E1E4C7"
+        "ABF5AE8CDB0933D71E8C94E04A25619D"
+        "CEE3D2261AD2EE6BF12FFA06D98A0864"
+        "D87602733EC86A64521F2B18177B200C"
+        "BBE117577A615D6C770988C0BAD946E2"
+        "08E24FA074E5AB3143DB5BFCE0FD108E"
+        "4B82D120A92108011A723C12A787E6D7"
+        "88719A10BDBA5B2699C327186AF4E23C"
+        "1A946834B6150BDA2583E9CA2AD44CE8"
+        "DBBBC2DB04DE8EF92E8EFC141FBECAA6"
+        "287C59474E6BC05D99B2964FA090C3A2"
+        "233BA186515BE7ED1F612970CEE2D7AF"
+        "B81BDD762170481CD0069127D5B05AA9"
+        "93B4EA988D8FDDC186FFB7DC90A6C08F"
+        "4DF435C93402849236C3FAB4D27C7026"
+        "C1D4DCB2602646DEC9751E763DBA37BD"
+        "F8FF9406AD9E530EE5DB382F413001AE"
+        "B06A53ED9027D831179727B0865A8918"
+        "DA3EDBEBCF9B14ED44CE6CBACED4BB1B"
+        "DB7F1447E6CC254B332051512BD7AF42"
+        "6FB8F401378CD2BF5983CA01C64B92EC"
+        "F032EA15D1721D03F482D7CE6E74FEF6"
+        "D55E702F46980C82B5A84031900B1C9E"
+        "59E7C97FBEC7E8F323A97A7E36CC88BE"
+        "0F1D45B7FF585AC54BD407B22B4154AA"
+        "CC8F6D7EBF48E1D814CC5ED20F8037E0"
+        "A79715EEF29BE32806A1D58BB7C5DA76"
+        "F550AA3D8A1FBFF0EB19CCB1A313D55C"
+        "DA56C9EC2EF29632387FE8D76E3C0468"
+        "043E8F663F4860EE12BF2D5B0B7474D6"
+        "E694F91E6DBE115974A3926F12FEE5E4"
+        "38777CB6A932DF8CD8BEC4D073B931BA"
+        "3BC832B68D9DD300741FA7BF8AFC47ED"
+        "2576F6936BA424663AAB639C5AE4F568"
+        "3423B4742BF1C978238F16CBE39D652D"
+        "E3FDB8BEFC848AD922222E04A4037C07"
+        "13EB57A81A23F0C73473FC646CEA306B"
+        "4BCBC8862F8385DDFA9D4B7FA2C087E8"
+        "79683303ED5BDD3A062B3CF5B3A278A6"
+        "6D2A13F83F44F82DDF310EE074AB6A36"
+        "4597E899A0255DC164F31CC50846851D"
+        "F9AB48195DED7EA1B1D510BD7EE74D73"
+        "FAF36BC31ECFA268359046F4EB879F92"
+        "4009438B481C6CD7889A002ED5EE382B"
+        "C9190DA6FC026E479558E4475677E9AA"
+        "9E3050E2765694DFC81F56E880B96E71"
+        "60C980DD98EDD3DFFFFFFFFFFFFFFFFF"
+    };
+
+    WOLFSSL_ENTER("wolfSSL_DH_8192_prime");
+
+    if (wolfSSL_BN_hex2bn(&bn, prm) != SSL_SUCCESS) {
+        WOLFSSL_MSG("Error converting DH 8192 prime to big number");
+        return NULL;
+    }
+
+    return bn;
+}
+
+/* return code compliant with OpenSSL :
+ *   1 if success, 0 if error
+ */
+int wolfSSL_DH_generate_key(WOLFSSL_DH* dh)
+{
+    int            ret    = WOLFSSL_FAILURE;
+    word32         pubSz  = 0;
+    word32         privSz = 0;
+    int            initTmpRng = 0;
+    WC_RNG*        rng    = NULL;
+#ifdef WOLFSSL_SMALL_STACK
+    WC_RNG*        tmpRNG;
+#else
+    WC_RNG         tmpRNG[1];
+#endif
+    unsigned char* pub    = NULL;
+    unsigned char* priv   = NULL;
+
+    WOLFSSL_MSG("wolfSSL_DH_generate_key");
+
+#ifdef WOLFSSL_SMALL_STACK
+    tmpRNG = (WC_RNG*)XMALLOC(sizeof(WC_RNG), NULL, DYNAMIC_TYPE_RNG);
+    if (tmpRNG == NULL) {
+        XFREE(tmpRNG, NULL, DYNAMIC_TYPE_RNG);
+        return ret;
+    }
+#endif
+
+    if (dh == NULL || dh->p == NULL || dh->g == NULL)
+        WOLFSSL_MSG("Bad function arguments");
+    else if (dh->inSet == 0 && SetDhInternal(dh) != WOLFSSL_SUCCESS)
+            WOLFSSL_MSG("Bad DH set internal");
+    else if (wc_InitRng(tmpRNG) == 0) {
+        rng = tmpRNG;
+        initTmpRng = 1;
+    }
+    else {
+        WOLFSSL_MSG("Bad RNG Init, trying global");
+        if (initGlobalRNG == 0)
+            WOLFSSL_MSG("Global RNG no Init");
+        else
+            rng = &globalRNG;
+    }
+
+    if (rng) {
+        pubSz = wolfSSL_BN_num_bytes(dh->p);
+        if (dh->length) {
+            privSz = dh->length/8; /* to bytes */
+        } else {
+            privSz = pubSz;
+        }
+        pub   = (unsigned char*)XMALLOC(pubSz,  NULL, DYNAMIC_TYPE_PUBLIC_KEY);
+        priv  = (unsigned char*)XMALLOC(privSz, NULL, DYNAMIC_TYPE_PRIVATE_KEY);
+        if (pub == NULL || priv == NULL) {
+            WOLFSSL_MSG("Unable to malloc memory");
+        }
+        else if (wc_DhGenerateKeyPair((DhKey*)dh->internal, rng, priv, &privSz,
+                                                               pub, &pubSz) < 0)
+            WOLFSSL_MSG("Bad wc_DhGenerateKeyPair");
+        else {
+            if (dh->pub_key)
+                wolfSSL_BN_free(dh->pub_key);
+
+            dh->pub_key = wolfSSL_BN_new();
+            if (dh->pub_key == NULL) {
+                WOLFSSL_MSG("Bad DH new pub");
+            }
+            if (dh->priv_key)
+                wolfSSL_BN_free(dh->priv_key);
+
+            dh->priv_key = wolfSSL_BN_new();
+
+            if (dh->priv_key == NULL) {
+                WOLFSSL_MSG("Bad DH new priv");
+            }
+
+            if (dh->pub_key && dh->priv_key) {
+               if (wolfSSL_BN_bin2bn(pub, pubSz, dh->pub_key) == NULL)
+                   WOLFSSL_MSG("Bad DH bn2bin error pub");
+               else if (wolfSSL_BN_bin2bn(priv, privSz, dh->priv_key) == NULL)
+                   WOLFSSL_MSG("Bad DH bn2bin error priv");
+               else
+                   ret = WOLFSSL_SUCCESS;
+            }
+        }
+    }
+
+    if (initTmpRng)
+        wc_FreeRng(tmpRNG);
+
+#ifdef WOLFSSL_SMALL_STACK
+    XFREE(tmpRNG, NULL, DYNAMIC_TYPE_RNG);
+#endif
+    XFREE(pub,    NULL, DYNAMIC_TYPE_PUBLIC_KEY);
+    XFREE(priv,   NULL, DYNAMIC_TYPE_PRIVATE_KEY);
+
+    return ret;
+}
+
+
+/* return code compliant with OpenSSL :
+ *   size of shared secret if success, -1 if error
+ */
+int wolfSSL_DH_compute_key(unsigned char* key, WOLFSSL_BIGNUM* otherPub,
+                          WOLFSSL_DH* dh)
+{
+    int            ret    = WOLFSSL_FATAL_ERROR;
+    word32         keySz  = 0;
+    int            pubSz  = 1024;
+    int            privSz = 1024;
+#ifdef WOLFSSL_SMALL_STACK
+    unsigned char* pub;
+    unsigned char* priv   = NULL;
+#else
+    unsigned char  pub [1024];
+    unsigned char  priv[1024];
+#endif
+
+    WOLFSSL_MSG("wolfSSL_DH_compute_key");
+
+#ifdef WOLFSSL_SMALL_STACK
+    pub = (unsigned char*)XMALLOC(pubSz, NULL, DYNAMIC_TYPE_PUBLIC_KEY);
+    if (pub == NULL)
+        return ret;
+
+    priv = (unsigned char*)XMALLOC(privSz, NULL, DYNAMIC_TYPE_PRIVATE_KEY);
+    if (priv == NULL) {
+        XFREE(pub, NULL, DYNAMIC_TYPE_PUBLIC_KEY);
+        return ret;
+    }
+#endif
+
+    if (dh == NULL || dh->priv_key == NULL || otherPub == NULL)
+        WOLFSSL_MSG("Bad function arguments");
+    else if ((keySz = (word32)DH_size(dh)) == 0)
+        WOLFSSL_MSG("Bad DH_size");
+    else if (wolfSSL_BN_bn2bin(dh->priv_key, NULL) > (int)privSz)
+        WOLFSSL_MSG("Bad priv internal size");
+    else if (wolfSSL_BN_bn2bin(otherPub, NULL) > (int)pubSz)
+        WOLFSSL_MSG("Bad otherPub size");
+    else {
+        privSz = wolfSSL_BN_bn2bin(dh->priv_key, priv);
+        pubSz  = wolfSSL_BN_bn2bin(otherPub, pub);
+        if (dh->inSet == 0 && SetDhInternal(dh) != SSL_SUCCESS){
+                WOLFSSL_MSG("Bad DH set internal");
+        }
+        if (privSz <= 0 || pubSz <= 0)
+            WOLFSSL_MSG("Bad BN2bin set");
+        else if (wc_DhAgree((DhKey*)dh->internal, key, &keySz,
+                            priv, privSz, pub, pubSz) < 0)
+            WOLFSSL_MSG("wc_DhAgree failed");
+        else
+            ret = (int)keySz;
+    }
+
+#ifdef WOLFSSL_SMALL_STACK
+    XFREE(pub,  NULL, DYNAMIC_TYPE_PUBLIC_KEY);
+    XFREE(priv, NULL, DYNAMIC_TYPE_PRIVATE_KEY);
+#endif
+
+    return ret;
+}
+
+
+#if defined(OPENSSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER >= 0x10100000L
+/* ownership of p,q,and g get taken over by "dh" on success and should be free'd
+ * with a call to wolfSSL_DH_free -- not individually.
+ *
+ * returns WOLFSSL_SUCCESS on success
+ */
+int wolfSSL_DH_set0_pqg(WOLFSSL_DH *dh, WOLFSSL_BIGNUM *p,
+    WOLFSSL_BIGNUM *q, WOLFSSL_BIGNUM *g)
+{
+    int ret;
+    WOLFSSL_ENTER("wolfSSL_DH_set0_pqg");
+
+    /* q can be NULL */
+    if (dh == NULL || p == NULL || g == NULL) {
+        WOLFSSL_MSG("Bad function arguments");
+        return WOLFSSL_FAILURE;
+    }
+
+    /* free existing internal DH structure and recreate with new p / g */
+    if (dh->inSet) {
+        ret = wc_FreeDhKey((DhKey*)dh->internal);
+        if (ret != 0) {
+            WOLFSSL_MSG("Unable to free internal DH key");
+            return WOLFSSL_FAILURE;
+        }
+    }
+
+    wolfSSL_BN_free(dh->p);
+    wolfSSL_BN_free(dh->q);
+    wolfSSL_BN_free(dh->g);
+    wolfSSL_BN_free(dh->pub_key);
+    wolfSSL_BN_free(dh->priv_key);
+
+    dh->p = p;
+    dh->q = q;
+    dh->g = g;
+
+    ret = SetDhInternal(dh);
+    if (ret != WOLFSSL_SUCCESS) {
+        WOLFSSL_MSG("Unable to set internal DH key");
+        dh->p = NULL;
+        dh->q = NULL;
+        dh->g = NULL;
+        dh->inSet = 0;
+        return WOLFSSL_FAILURE;
+    }
+
+    return WOLFSSL_SUCCESS;
+}
+#endif /* v1.1.0 or later */
+
+#endif /* NO_DH */
+
+
+#ifndef NO_DSA
+static void InitwolfSSL_DSA(WOLFSSL_DSA* dsa)
+{
+    if (dsa) {
+        dsa->p        = NULL;
+        dsa->q        = NULL;
+        dsa->g        = NULL;
+        dsa->pub_key  = NULL;
+        dsa->priv_key = NULL;
+        dsa->internal = NULL;
+        dsa->inSet    = 0;
+        dsa->exSet    = 0;
+    }
+}
+
+
+WOLFSSL_DSA* wolfSSL_DSA_new(void)
+{
+    WOLFSSL_DSA* external;
+    DsaKey*     key;
+
+    WOLFSSL_MSG("wolfSSL_DSA_new");
+
+    key = (DsaKey*) XMALLOC(sizeof(DsaKey), NULL, DYNAMIC_TYPE_DSA);
+    if (key == NULL) {
+        WOLFSSL_MSG("wolfSSL_DSA_new malloc DsaKey failure");
+        return NULL;
+    }
+
+    external = (WOLFSSL_DSA*) XMALLOC(sizeof(WOLFSSL_DSA), NULL,
+                                    DYNAMIC_TYPE_DSA);
+    if (external == NULL) {
+        WOLFSSL_MSG("wolfSSL_DSA_new malloc WOLFSSL_DSA failure");
+        XFREE(key, NULL, DYNAMIC_TYPE_DSA);
+        return NULL;
+    }
+
+    InitwolfSSL_DSA(external);
+    if (wc_InitDsaKey(key) != 0) {
+        WOLFSSL_MSG("wolfSSL_DSA_new InitDsaKey failure");
+        XFREE(key, NULL, DYNAMIC_TYPE_DSA);
+        wolfSSL_DSA_free(external);
+        return NULL;
+    }
+    external->internal = key;
+
+    return external;
+}
+
+
+void wolfSSL_DSA_free(WOLFSSL_DSA* dsa)
+{
+    WOLFSSL_MSG("wolfSSL_DSA_free");
+
+    if (dsa) {
+        if (dsa->internal) {
+            FreeDsaKey((DsaKey*)dsa->internal);
+            XFREE(dsa->internal, NULL, DYNAMIC_TYPE_DSA);
+            dsa->internal = NULL;
+        }
+        wolfSSL_BN_free(dsa->priv_key);
+        wolfSSL_BN_free(dsa->pub_key);
+        wolfSSL_BN_free(dsa->g);
+        wolfSSL_BN_free(dsa->q);
+        wolfSSL_BN_free(dsa->p);
+        InitwolfSSL_DSA(dsa);  /* set back to NULLs for safety */
+
+        XFREE(dsa, NULL, DYNAMIC_TYPE_DSA);
+
+        /* dsa = NULL, don't try to access or double free it */
+    }
+}
+
+#endif /* NO_DSA */
+#endif /* OPENSSL_EXTRA */
+
+#ifdef OPENSSL_EXTRA
+
+#ifndef NO_DSA
+/* wolfSSL -> OpenSSL */
+int SetDsaExternal(WOLFSSL_DSA* dsa)
+{
+    DsaKey* key;
+    WOLFSSL_MSG("Entering SetDsaExternal");
+
+    if (dsa == NULL || dsa->internal == NULL) {
+        WOLFSSL_MSG("dsa key NULL error");
+        return WOLFSSL_FATAL_ERROR;
+    }
+
+    key = (DsaKey*)dsa->internal;
+
+    if (SetIndividualExternal(&dsa->p, &key->p) != WOLFSSL_SUCCESS) {
+        WOLFSSL_MSG("dsa p key error");
+        return WOLFSSL_FATAL_ERROR;
+    }
+
+    if (SetIndividualExternal(&dsa->q, &key->q) != WOLFSSL_SUCCESS) {
+        WOLFSSL_MSG("dsa q key error");
+        return WOLFSSL_FATAL_ERROR;
+    }
+
+    if (SetIndividualExternal(&dsa->g, &key->g) != WOLFSSL_SUCCESS) {
+        WOLFSSL_MSG("dsa g key error");
+        return WOLFSSL_FATAL_ERROR;
+    }
+
+    if (SetIndividualExternal(&dsa->pub_key, &key->y) != WOLFSSL_SUCCESS) {
+        WOLFSSL_MSG("dsa y key error");
+        return WOLFSSL_FATAL_ERROR;
+    }
+
+    if (SetIndividualExternal(&dsa->priv_key, &key->x) != WOLFSSL_SUCCESS) {
+        WOLFSSL_MSG("dsa x key error");
+        return WOLFSSL_FATAL_ERROR;
+    }
+
+    dsa->exSet = 1;
+
+    return WOLFSSL_SUCCESS;
+}
+
+/* Openssl -> WolfSSL */
+int SetDsaInternal(WOLFSSL_DSA* dsa)
+{
+    DsaKey* key;
+    WOLFSSL_MSG("Entering SetDsaInternal");
+
+    if (dsa == NULL || dsa->internal == NULL) {
+        WOLFSSL_MSG("dsa key NULL error");
+        return WOLFSSL_FATAL_ERROR;
+    }
+
+    key = (DsaKey*)dsa->internal;
+
+    if (dsa->p != NULL &&
+        SetIndividualInternal(dsa->p, &key->p) != WOLFSSL_SUCCESS) {
+        WOLFSSL_MSG("rsa p key error");
+        return WOLFSSL_FATAL_ERROR;
+    }
+
+    if (dsa->q != NULL &&
+        SetIndividualInternal(dsa->q, &key->q) != WOLFSSL_SUCCESS) {
+        WOLFSSL_MSG("rsa q key error");
+        return WOLFSSL_FATAL_ERROR;
+    }
+
+    if (dsa->g != NULL &&
+        SetIndividualInternal(dsa->g, &key->g) != WOLFSSL_SUCCESS) {
+        WOLFSSL_MSG("rsa g key error");
+        return WOLFSSL_FATAL_ERROR;
+    }
+
+    if (dsa->pub_key != NULL) {
+        if (SetIndividualInternal(dsa->pub_key, &key->y) != WOLFSSL_SUCCESS) {
+            WOLFSSL_MSG("rsa pub_key error");
+            return WOLFSSL_FATAL_ERROR;
+        }
+
+        /* public key */
+        key->type = DSA_PUBLIC;
+    }
+
+    if (dsa->priv_key != NULL) {
+        if (SetIndividualInternal(dsa->priv_key, &key->x) != WOLFSSL_SUCCESS) {
+            WOLFSSL_MSG("rsa priv_key error");
+            return WOLFSSL_FATAL_ERROR;
+        }
+
+        /* private key */
+        key->type = DSA_PRIVATE;
+    }
+
+    dsa->inSet = 1;
+
+    return WOLFSSL_SUCCESS;
+}
+#endif /* NO_DSA */
+#endif /* OPENSSL_EXTRA */
+
+
+#ifdef OPENSSL_EXTRA
+#if !defined(NO_RSA)
+/* Generates a RSA key of length len
+ *
+ * len  length of RSA key i.e. 2048
+ * e    e to use when generating RSA key
+ * f    callback function for generation details
+ * data user callback argument
+ *
+ * Note: Because of wc_MakeRsaKey an RSA key size generated can be slightly
+ *       rounded down. For example generating a key of size 2999 with e =
+ *       65537 will make a key of size 374 instead of 375.
+ * Returns a new RSA key on success and NULL on failure
+ */
+WOLFSSL_RSA* wolfSSL_RSA_generate_key(int len, unsigned long e,
+                                      void(*f)(int, int, void*), void* data)
+{
+    WOLFSSL_RSA*    rsa = NULL;
+    WOLFSSL_BIGNUM* bn  = NULL;
+
+    WOLFSSL_ENTER("wolfSSL_RSA_generate_key");
+
+    (void)f;
+    (void)data;
+
+    if (len < 0) {
+        WOLFSSL_MSG("Bad argument: length was less than 0");
+        return NULL;
+    }
+
+    bn = wolfSSL_BN_new();
+    if (bn == NULL) {
+        WOLFSSL_MSG("Error creating big number");
+        return NULL;
+    }
+
+    if (wolfSSL_BN_set_word(bn, (WOLFSSL_BN_ULONG)e) != SSL_SUCCESS) {
+        WOLFSSL_MSG("Error using e value");
+        wolfSSL_BN_free(bn);
+        return NULL;
+    }
+
+    rsa = wolfSSL_RSA_new();
+    if (rsa == NULL) {
+        WOLFSSL_MSG("memory error");
+    }
+    else {
+        if (wolfSSL_RSA_generate_key_ex(rsa, len, bn, NULL) != SSL_SUCCESS){
+            wolfSSL_RSA_free(rsa);
+            rsa = NULL;
+        }
+    }
+    wolfSSL_BN_free(bn);
+
+    return rsa;
+}
+
+
+/* return compliant with OpenSSL
+ *   1 if success, 0 if error
+ */
+int wolfSSL_RSA_generate_key_ex(WOLFSSL_RSA* rsa, int bits, WOLFSSL_BIGNUM* bn,
+                                void* cb)
+{
+    int ret = WOLFSSL_FAILURE;
+
+    (void)cb;
+    (void)bn;
+    (void)bits;
+
+    WOLFSSL_ENTER("wolfSSL_RSA_generate_key_ex");
+
+    if (rsa == NULL || rsa->internal == NULL) {
+        /* bit size checked during make key call */
+        WOLFSSL_MSG("bad arguments");
+        return WOLFSSL_FAILURE;
+    }
+
+#ifdef WOLFSSL_KEY_GEN
+    {
+    #ifdef WOLFSSL_SMALL_STACK
+        WC_RNG* rng;
+    #else
+        WC_RNG  rng[1];
+    #endif
+
+    #ifdef WOLFSSL_SMALL_STACK
+        rng = (WC_RNG*)XMALLOC(sizeof(WC_RNG), NULL, DYNAMIC_TYPE_RNG);
+        if (rng == NULL)
+            return WOLFSSL_FAILURE;
+    #endif
+
+        if (wc_InitRng(rng) < 0)
+            WOLFSSL_MSG("RNG init failed");
+        else if (wc_MakeRsaKey((RsaKey*)rsa->internal, bits,
+                    wolfSSL_BN_get_word(bn), rng) != MP_OKAY)
+            WOLFSSL_MSG("wc_MakeRsaKey failed");
+        else if (SetRsaExternal(rsa) != WOLFSSL_SUCCESS)
+            WOLFSSL_MSG("SetRsaExternal failed");
+        else {
+            rsa->inSet = 1;
+            ret = WOLFSSL_SUCCESS;
+        }
+
+        wc_FreeRng(rng);
+    #ifdef WOLFSSL_SMALL_STACK
+        XFREE(rng, NULL, DYNAMIC_TYPE_RNG);
+    #endif
+    }
+#else
+    WOLFSSL_MSG("No Key Gen built in");
+#endif
+    return ret;
+}
+#endif /* NO_RSA */
+
+#ifndef NO_DSA
+/* return code compliant with OpenSSL :
+ *   1 if success, 0 if error
+ */
+int wolfSSL_DSA_generate_key(WOLFSSL_DSA* dsa)
+{
+    int ret = WOLFSSL_FAILURE;
+
+    WOLFSSL_ENTER("wolfSSL_DSA_generate_key");
+
+    if (dsa == NULL || dsa->internal == NULL) {
+        WOLFSSL_MSG("Bad arguments");
+        return WOLFSSL_FAILURE;
+    }
+
+    if (dsa->inSet == 0) {
+        WOLFSSL_MSG("No DSA internal set, do it");
+
+        if (SetDsaInternal(dsa) != WOLFSSL_SUCCESS) {
+            WOLFSSL_MSG("SetDsaInternal failed");
+            return ret;
+        }
+    }
+
+#ifdef WOLFSSL_KEY_GEN
+    {
+        int initTmpRng = 0;
+        WC_RNG *rng = NULL;
+#ifdef WOLFSSL_SMALL_STACK
+        WC_RNG *tmpRNG;
+#else
+        WC_RNG tmpRNG[1];
+#endif
+
+#ifdef WOLFSSL_SMALL_STACK
+        tmpRNG = (WC_RNG*)XMALLOC(sizeof(WC_RNG), NULL, DYNAMIC_TYPE_RNG);
+        if (tmpRNG == NULL)
+            return WOLFSSL_FATAL_ERROR;
+#endif
+        if (wc_InitRng(tmpRNG) == 0) {
+            rng = tmpRNG;
+            initTmpRng = 1;
+        }
+        else {
+            WOLFSSL_MSG("Bad RNG Init, trying global");
+            if (initGlobalRNG == 0)
+                WOLFSSL_MSG("Global RNG no Init");
+            else
+                rng = &globalRNG;
+        }
+
+        if (rng) {
+            if (wc_MakeDsaKey(rng, (DsaKey*)dsa->internal) != MP_OKAY)
+                WOLFSSL_MSG("wc_MakeDsaKey failed");
+            else if (SetDsaExternal(dsa) != WOLFSSL_SUCCESS)
+                WOLFSSL_MSG("SetDsaExternal failed");
+            else
+                ret = WOLFSSL_SUCCESS;
+        }
+
+        if (initTmpRng)
+            wc_FreeRng(tmpRNG);
+
+#ifdef WOLFSSL_SMALL_STACK
+        XFREE(tmpRNG, NULL, DYNAMIC_TYPE_RNG);
+#endif
+    }
+#else /* WOLFSSL_KEY_GEN */
+    WOLFSSL_MSG("No Key Gen built in");
+#endif
+    return ret;
+}
+
+
+/* Returns a pointer to a new WOLFSSL_DSA structure on success and NULL on fail
+ */
+WOLFSSL_DSA* wolfSSL_DSA_generate_parameters(int bits, unsigned char* seed,
+        int seedLen, int* counterRet, unsigned long* hRet,
+        WOLFSSL_BN_CB cb, void* CBArg)
+{
+    WOLFSSL_DSA* dsa;
+
+    WOLFSSL_ENTER("wolfSSL_DSA_generate_parameters()");
+
+    (void)cb;
+    (void)CBArg;
+    dsa = wolfSSL_DSA_new();
+    if (dsa == NULL) {
+        return NULL;
+    }
+
+    if (wolfSSL_DSA_generate_parameters_ex(dsa, bits, seed, seedLen,
+                                  counterRet, hRet, NULL) != SSL_SUCCESS) {
+        wolfSSL_DSA_free(dsa);
+        return NULL;
+    }
+
+    return dsa;
+}
+
+
+/* return code compliant with OpenSSL :
+ *   1 if success, 0 if error
+ */
+int wolfSSL_DSA_generate_parameters_ex(WOLFSSL_DSA* dsa, int bits,
+                                       unsigned char* seed, int seedLen,
+                                       int* counterRet,
+                                       unsigned long* hRet, void* cb)
+{
+    int ret = WOLFSSL_FAILURE;
+
+    (void)bits;
+    (void)seed;
+    (void)seedLen;
+    (void)counterRet;
+    (void)hRet;
+    (void)cb;
+
+    WOLFSSL_ENTER("wolfSSL_DSA_generate_parameters_ex");
+
+    if (dsa == NULL || dsa->internal == NULL) {
+        WOLFSSL_MSG("Bad arguments");
+        return WOLFSSL_FAILURE;
+    }
+
+#ifdef WOLFSSL_KEY_GEN
+    {
+        int initTmpRng = 0;
+        WC_RNG *rng = NULL;
+#ifdef WOLFSSL_SMALL_STACK
+        WC_RNG *tmpRNG;
+#else
+        WC_RNG tmpRNG[1];
+#endif
+
+#ifdef WOLFSSL_SMALL_STACK
+        tmpRNG = (WC_RNG*)XMALLOC(sizeof(WC_RNG), NULL, DYNAMIC_TYPE_RNG);
+        if (tmpRNG == NULL)
+            return WOLFSSL_FATAL_ERROR;
+#endif
+        if (wc_InitRng(tmpRNG) == 0) {
+            rng = tmpRNG;
+            initTmpRng = 1;
+        }
+        else {
+            WOLFSSL_MSG("Bad RNG Init, trying global");
+            if (initGlobalRNG == 0)
+                WOLFSSL_MSG("Global RNG no Init");
+            else
+                rng = &globalRNG;
+        }
+
+        if (rng) {
+            if (wc_MakeDsaParameters(rng, bits,
+                                     (DsaKey*)dsa->internal) != MP_OKAY)
+                WOLFSSL_MSG("wc_MakeDsaParameters failed");
+            else if (SetDsaExternal(dsa) != WOLFSSL_SUCCESS)
+                WOLFSSL_MSG("SetDsaExternal failed");
+            else
+                ret = WOLFSSL_SUCCESS;
+        }
+
+        if (initTmpRng)
+            wc_FreeRng(tmpRNG);
+
+#ifdef WOLFSSL_SMALL_STACK
+        XFREE(tmpRNG, NULL, DYNAMIC_TYPE_RNG);
+#endif
+    }
+#else /* WOLFSSL_KEY_GEN */
+    WOLFSSL_MSG("No Key Gen built in");
+#endif
+
+    return ret;
+}
+
+WOLFSSL_DSA_SIG* wolfSSL_DSA_SIG_new(void)
+{
+    WOLFSSL_DSA_SIG* sig;
+    WOLFSSL_ENTER("wolfSSL_DSA_SIG_new");
+    sig = (WOLFSSL_DSA_SIG*)XMALLOC(sizeof(WOLFSSL_DSA_SIG), NULL, DYNAMIC_TYPE_OPENSSL);
+    if (sig)
+        XMEMSET(sig, 0, sizeof(WOLFSSL_DSA_SIG));
+    return sig;
+}
+
+void wolfSSL_DSA_SIG_free(WOLFSSL_DSA_SIG *sig)
+{
+    WOLFSSL_ENTER("wolfSSL_DSA_SIG_free");
+    if (sig) {
+        if (sig->r) {
+            wolfSSL_BN_free(sig->r);
+        }
+        if (sig->s) {
+            wolfSSL_BN_free(sig->s);
+        }
+        XFREE(sig, NULL, DYNAMIC_TYPE_OPENSSL);
+    }
+}
+
+/* return WOLFSSL_SUCCESS on success, < 0 otherwise */
+int wolfSSL_DSA_do_sign(const unsigned char* d, unsigned char* sigRet,
+                       WOLFSSL_DSA* dsa)
+{
+    int     ret = WOLFSSL_FATAL_ERROR;
+    int     initTmpRng = 0;
+    WC_RNG* rng = NULL;
+#ifdef WOLFSSL_SMALL_STACK
+    WC_RNG* tmpRNG = NULL;
+#else
+    WC_RNG  tmpRNG[1];
+#endif
+
+    WOLFSSL_ENTER("wolfSSL_DSA_do_sign");
+
+    if (d == NULL || sigRet == NULL || dsa == NULL) {
+        WOLFSSL_MSG("Bad function arguments");
+        return ret;
+    }
+
+    if (dsa->inSet == 0)
+    {
+        WOLFSSL_MSG("No DSA internal set, do it");
+
+        if (SetDsaInternal(dsa) != WOLFSSL_SUCCESS) {
+            WOLFSSL_MSG("SetDsaInternal failed");
+            return ret;
+        }
+    }
+
+#ifdef WOLFSSL_SMALL_STACK
+    tmpRNG = (WC_RNG*)XMALLOC(sizeof(WC_RNG), NULL, DYNAMIC_TYPE_RNG);
+    if (tmpRNG == NULL)
+        return WOLFSSL_FATAL_ERROR;
+#endif
+
+    if (wc_InitRng(tmpRNG) == 0) {
+        rng = tmpRNG;
+        initTmpRng = 1;
+    }
+    else {
+        WOLFSSL_MSG("Bad RNG Init, trying global");
+        if (initGlobalRNG == 0)
+            WOLFSSL_MSG("Global RNG no Init");
+        else
+            rng = &globalRNG;
+    }
+
+    if (rng) {
+        if (DsaSign(d, sigRet, (DsaKey*)dsa->internal, rng) < 0)
+            WOLFSSL_MSG("DsaSign failed");
+        else
+            ret = WOLFSSL_SUCCESS;
+    }
+
+    if (initTmpRng)
+        wc_FreeRng(tmpRNG);
+#ifdef WOLFSSL_SMALL_STACK
+    XFREE(tmpRNG, NULL, DYNAMIC_TYPE_RNG);
+#endif
+
+    return ret;
+}
+
+#if !defined(HAVE_SELFTEST) && !defined(HAVE_FIPS)
+WOLFSSL_DSA_SIG* wolfSSL_DSA_do_sign_ex(const unsigned char* digest,
+                                        int outLen, WOLFSSL_DSA* dsa)
+{
+    WOLFSSL_DSA_SIG* sig = NULL;
+    byte sigBin[DSA_SIG_SIZE];
+
+    WOLFSSL_ENTER("wolfSSL_DSA_do_sign_ex");
+
+    if (!digest || !dsa || outLen != WC_SHA_DIGEST_SIZE) {
+        WOLFSSL_MSG("Bad function arguments");
+        return NULL;
+    }
+
+    if (wolfSSL_DSA_do_sign(digest, sigBin, dsa) != WOLFSSL_SUCCESS) {
+        return NULL;
+    }
+
+    if (!(sig = wolfSSL_DSA_SIG_new())) {
+        goto error;
+    }
+
+    if (!(sig->r = wolfSSL_BN_bin2bn(sigBin, DSA_HALF_SIZE, NULL))) {
+        goto error;
+    }
+
+    if (!(sig->s = wolfSSL_BN_bin2bn(sigBin + DSA_HALF_SIZE, DSA_HALF_SIZE, NULL))) {
+        goto error;
+    }
+
+    return sig;
+error:
+    if (sig) {
+        wolfSSL_DSA_SIG_free(sig);
+    }
+    return NULL;
+}
+#endif /* !HAVE_SELFTEST && !HAVE_FIPS */
+
+int wolfSSL_DSA_do_verify(const unsigned char* d, unsigned char* sig,
+                        WOLFSSL_DSA* dsa, int *dsacheck)
+{
+    int    ret = WOLFSSL_FATAL_ERROR;
+
+    WOLFSSL_ENTER("wolfSSL_DSA_do_verify");
+
+    if (d == NULL || sig == NULL || dsa == NULL) {
+        WOLFSSL_MSG("Bad function arguments");
+        return WOLFSSL_FATAL_ERROR;
+    }
+    if (dsa->inSet == 0)
+    {
+        WOLFSSL_MSG("No DSA internal set, do it");
+
+        if (SetDsaInternal(dsa) != WOLFSSL_SUCCESS) {
+            WOLFSSL_MSG("SetDsaInternal failed");
+            return WOLFSSL_FATAL_ERROR;
+        }
+    }
+
+    ret = DsaVerify(d, sig, (DsaKey*)dsa->internal, dsacheck);
+    if (ret != 0 || *dsacheck != 1) {
+        WOLFSSL_MSG("DsaVerify failed");
+        return ret;
+    }
+
+    return WOLFSSL_SUCCESS;
+}
+
+#if !defined(HAVE_SELFTEST) && !defined(HAVE_FIPS)
+int wolfSSL_DSA_do_verify_ex(const unsigned char* digest, int digest_len,
+                             WOLFSSL_DSA_SIG* sig, WOLFSSL_DSA* dsa)
+{
+    int dsacheck, sz;
+    byte sigBin[DSA_SIG_SIZE];
+    byte* sigBinPtr = sigBin;
+
+    WOLFSSL_ENTER("wolfSSL_DSA_do_verify_ex");
+
+    if (!digest || !sig || !dsa || digest_len != WC_SHA_DIGEST_SIZE) {
+        WOLFSSL_MSG("Bad function arguments");
+        return WOLFSSL_FAILURE;
+    }
+
+    if (!sig->r || !sig->s) {
+        WOLFSSL_MSG("No signature found in DSA_SIG");
+        return WOLFSSL_FAILURE;
+    }
+
+    /* front pad with zeros */
+    if (!(sz = wolfSSL_BN_num_bytes(sig->r))) {
+        return WOLFSSL_FAILURE;
+    }
+    while (sz++ < DSA_HALF_SIZE) {
+        *sigBinPtr++ = 0;
+    }
+
+    if (wolfSSL_BN_bn2bin(sig->r, sigBinPtr) == WOLFSSL_FATAL_ERROR) {
+        return WOLFSSL_FAILURE;
+    }
+
+    /* Move to s */
+    sigBinPtr = sigBin + DSA_HALF_SIZE;
+
+    /* front pad with zeros */
+    if (!(sz = wolfSSL_BN_num_bytes(sig->s))) {
+        return WOLFSSL_FAILURE;
+    }
+    while (sz++ < DSA_HALF_SIZE) {
+        *sigBinPtr++ = 0;
+    }
+
+    if (wolfSSL_BN_bn2bin(sig->s, sigBinPtr) == WOLFSSL_FATAL_ERROR) {
+        return WOLFSSL_FAILURE;
+    }
+
+    if (wolfSSL_DSA_do_verify(digest, sigBin, dsa, &dsacheck) != WOLFSSL_SUCCESS ||
+            dsacheck != 1) {
+        return WOLFSSL_FAILURE;
+    }
+
+    return WOLFSSL_SUCCESS;
+}
+#endif /* !HAVE_SELFTEST && !HAVE_FIPS */
+#endif /* NO_DSA */
+
+
+#if !defined(NO_RSA) && !defined(HAVE_USER_RSA)
+
+#ifdef DEBUG_SIGN
+static void show(const char *title, const unsigned char *out, unsigned int outlen)
+{
+    const unsigned char *pt;
+    printf("%s[%d] = \n", title, (int)outlen);
+    outlen = outlen>100?100:outlen;
+    for (pt = out; pt < out + outlen;
+            printf("%c", ((*pt)&0x6f)>='A'?((*pt)&0x6f):'.'), pt++);
+    printf("\n");
+}
+#else
+#define show(a,b,c)
+#endif
+
+/* return SSL_SUCCESS on ok, 0 otherwise */
+int wolfSSL_RSA_sign(int type, const unsigned char* m,
+                           unsigned int mLen, unsigned char* sigRet,
+                           unsigned int* sigLen, WOLFSSL_RSA* rsa)
+{
+    return wolfSSL_RSA_sign_ex(type, m, mLen, sigRet, sigLen, rsa, 1);
+}
+
+int wolfSSL_RSA_sign_ex(int type, const unsigned char* m,
+                           unsigned int mLen, unsigned char* sigRet,
+                           unsigned int* sigLen, WOLFSSL_RSA* rsa, int flag)
+{
+    word32  outLen;
+    word32  signSz;
+    int     initTmpRng = 0;
+    WC_RNG* rng        = NULL;
+    int     ret        = 0;
+#ifdef WOLFSSL_SMALL_STACK
+    WC_RNG* tmpRNG     = NULL;
+    byte*   encodedSig = NULL;
+#else
+    WC_RNG  tmpRNG[1];
+    byte    encodedSig[MAX_ENCODED_SIG_SZ];
+#endif
+
+    WOLFSSL_ENTER("wolfSSL_RSA_sign");
+
+    if (m == NULL || sigRet == NULL || sigLen == NULL || rsa == NULL) {
+        WOLFSSL_MSG("Bad function arguments");
+        return 0;
+    }
+    show("Message to Sign", m, mLen);
+
+    switch (type) {
+    #ifdef WOLFSSL_MD2
+        case NID_md2:       type = MD2h;    break;
+    #endif
+    #ifndef NO_MD5
+        case NID_md5:       type = MD5h;    break;
+    #endif
+    #ifndef NO_SHA
+        case NID_sha1:      type = SHAh;    break;
+    #endif
+    #ifndef NO_SHA256
+        case NID_sha256:    type = SHA256h; break;
+    #endif
+    #ifdef WOLFSSL_SHA384
+        case NID_sha384:    type = SHA384h; break;
+    #endif
+    #ifdef WOLFSSL_SHA512
+        case NID_sha512:    type = SHA512h; break;
+    #endif
+    #ifndef WOLFSSL_NOSHA3_224
+        case NID_sha3_224:  type = SHA3_224h; break;
+    #endif
+    #ifndef WOLFSSL_NOSHA3_256
+        case NID_sha3_256:  type = SHA3_256h; break;
+    #endif
+    #ifndef WOLFSSL_NOSHA3_384
+        case NID_sha3_384:  type = SHA3_384h; break;
+    #endif
+    #ifndef WOLFSSL_NOSHA3_512
+        case NID_sha3_512:  type = SHA3_512h; break;
+    #endif
+        default:
+            WOLFSSL_MSG("This NID (md type) not configured or not implemented");
+            return 0;
+    }
+
+    if (rsa->inSet == 0)
+    {
+        WOLFSSL_MSG("No RSA internal set, do it");
+
+        if (SetRsaInternal(rsa) != WOLFSSL_SUCCESS) {
+            WOLFSSL_MSG("SetRsaInternal failed");
+            return 0;
+        }
+    }
+
+    outLen = (word32)wolfSSL_BN_num_bytes(rsa->n);
+
+#ifdef WOLFSSL_SMALL_STACK
+    tmpRNG = (WC_RNG*)XMALLOC(sizeof(WC_RNG), NULL, DYNAMIC_TYPE_RNG);
+    if (tmpRNG == NULL)
+        return 0;
+
+    encodedSig = (byte*)XMALLOC(MAX_ENCODED_SIG_SZ, NULL,
+                                                   DYNAMIC_TYPE_SIGNATURE);
+    if (encodedSig == NULL) {
+        XFREE(tmpRNG, NULL, DYNAMIC_TYPE_RNG);
+        return 0;
+    }
+#endif
+
+    if (outLen == 0)
+        WOLFSSL_MSG("Bad RSA size");
+    else if (wc_InitRng(tmpRNG) == 0) {
+        rng = tmpRNG;
+        initTmpRng = 1;
+    }
+    else {
+        WOLFSSL_MSG("Bad RNG Init, trying global");
+
+        if (initGlobalRNG == 0)
+            WOLFSSL_MSG("Global RNG no Init");
+        else
+            rng = &globalRNG;
+    }
+
+    if (rng) {
+
+        signSz = wc_EncodeSignature(encodedSig, m, mLen, type);
+        if (signSz == 0) {
+            WOLFSSL_MSG("Bad Encode Signature");
+        }
+        else {
+            show("Encoded Message", encodedSig, signSz);
+            if (flag != 0) {
+                ret = wc_RsaSSL_Sign(encodedSig, signSz, sigRet, outLen,
+                                (RsaKey*)rsa->internal, rng);
+                if (ret <= 0) {
+                    WOLFSSL_MSG("Bad Rsa Sign");
+                    ret = 0;
+                }
+                else {
+                    *sigLen = (unsigned int)ret;
+                    ret = SSL_SUCCESS;
+                    show("Signature", sigRet, *sigLen);
+                }
+            } else {
+                ret = SSL_SUCCESS;
+                XMEMCPY(sigRet, encodedSig, signSz);
+                *sigLen = signSz;
+            }
+        }
+
+    }
+
+    if (initTmpRng)
+        wc_FreeRng(tmpRNG);
+
+#ifdef WOLFSSL_SMALL_STACK
+    XFREE(tmpRNG,     NULL, DYNAMIC_TYPE_RNG);
+    XFREE(encodedSig, NULL, DYNAMIC_TYPE_SIGNATURE);
+#endif
+
+    if (ret == WOLFSSL_SUCCESS)
+        WOLFSSL_MSG("wolfSSL_RSA_sign success");
+    else {
+        WOLFSSL_MSG("wolfSSL_RSA_sign failed");
+    }
+    return ret;
+}
+
+
+/* returns WOLFSSL_SUCCESS on successful verify and WOLFSSL_FAILURE on fail */
+int wolfSSL_RSA_verify(int type, const unsigned char* m,
+                               unsigned int mLen, const unsigned char* sig,
+                               unsigned int sigLen, WOLFSSL_RSA* rsa)
+{
+    int     ret;
+    unsigned char *sigRet ;
+    unsigned char *sigDec ;
+    unsigned int   len;
+
+    WOLFSSL_ENTER("wolfSSL_RSA_verify");
+    if ((m == NULL) || (sig == NULL)) {
+        WOLFSSL_MSG("Bad function arguments");
+        return WOLFSSL_FAILURE;
+    }
+
+    sigRet = (unsigned char *)XMALLOC(sigLen, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    if (sigRet == NULL) {
+        WOLFSSL_MSG("Memory failure");
+        return WOLFSSL_FAILURE;
+    }
+    sigDec = (unsigned char *)XMALLOC(sigLen, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    if (sigDec == NULL) {
+        WOLFSSL_MSG("Memory failure");
+        XFREE(sigRet, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+        return WOLFSSL_FAILURE;
+    }
+    /* get non-encrypted signature to be compared with decrypted signature */
+    ret = wolfSSL_RSA_sign_ex(type, m, mLen, sigRet, &len, rsa, 0);
+    if (ret <= 0) {
+        WOLFSSL_MSG("Message Digest Error");
+        XFREE(sigRet, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+        XFREE(sigDec, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+        return WOLFSSL_FAILURE;
+    }
+    show("Encoded Message", sigRet, len);
+    /* decrypt signature */
+    ret = wc_RsaSSL_Verify(sig, sigLen, (unsigned char *)sigDec, sigLen,
+        (RsaKey*)rsa->internal);
+    if (ret <= 0) {
+        WOLFSSL_MSG("RSA Decrypt error");
+        XFREE(sigRet, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+        XFREE(sigDec, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+        return WOLFSSL_FAILURE;
+    }
+    show("Decrypted Signature", sigDec, ret);
+
+    if ((int)len == ret && XMEMCMP(sigRet, sigDec, ret) == 0) {
+        WOLFSSL_MSG("wolfSSL_RSA_verify success");
+        XFREE(sigRet, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+        XFREE(sigDec, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+        return WOLFSSL_SUCCESS;
+    }
+    else {
+        WOLFSSL_MSG("wolfSSL_RSA_verify failed");
+        XFREE(sigRet, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+        XFREE(sigDec, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+        return WOLFSSL_FAILURE;
+    }
+}
+
+void wolfSSL_RSA_get0_key(const WOLFSSL_RSA *r, const WOLFSSL_BIGNUM **n,
+    const WOLFSSL_BIGNUM **e, const WOLFSSL_BIGNUM **d)
+{
+    WOLFSSL_ENTER("wolfSSL_RSA_get0_key");
+
+    if (r != NULL) {
+        if (n != NULL)
+            *n = r->n;
+        if (e != NULL)
+            *e = r->e;
+        if (d != NULL)
+            *d = r->d;
+    } else {
+        if (n != NULL)
+            *n = NULL;
+        if (e != NULL)
+            *e = NULL;
+        if (d != NULL)
+            *d = NULL;
+    }
+}
+
+/* generate p-1 and q-1, WOLFSSL_SUCCESS on ok */
+int wolfSSL_RSA_GenAdd(WOLFSSL_RSA* rsa)
+{
+    int    err;
+    mp_int tmp;
+
+    WOLFSSL_MSG("wolfSSL_RsaGenAdd");
+
+    if (rsa == NULL || rsa->p == NULL || rsa->q == NULL || rsa->d == NULL ||
+                       rsa->dmp1 == NULL || rsa->dmq1 == NULL) {
+        WOLFSSL_MSG("rsa no init error");
+        return WOLFSSL_FATAL_ERROR;
+    }
+
+    if (mp_init(&tmp) != MP_OKAY) {
+        WOLFSSL_MSG("mp_init error");
+        return WOLFSSL_FATAL_ERROR;
+    }
+
+    err = mp_sub_d((mp_int*)rsa->p->internal, 1, &tmp);
+    if (err != MP_OKAY) {
+        WOLFSSL_MSG("mp_sub_d error");
+    }
+    else
+        err = mp_mod((mp_int*)rsa->d->internal, &tmp,
+                     (mp_int*)rsa->dmp1->internal);
+
+    if (err != MP_OKAY) {
+        WOLFSSL_MSG("mp_mod error");
+    }
+    else
+        err = mp_sub_d((mp_int*)rsa->q->internal, 1, &tmp);
+    if (err != MP_OKAY) {
+        WOLFSSL_MSG("mp_sub_d error");
+    }
+    else
+        err = mp_mod((mp_int*)rsa->d->internal, &tmp,
+                     (mp_int*)rsa->dmq1->internal);
+
+    mp_clear(&tmp);
+
+    if (err == MP_OKAY)
+        return WOLFSSL_SUCCESS;
+    else
+        return WOLFSSL_FATAL_ERROR;
+}
+#endif /* !NO_RSA && !HAVE_USER_RSA */
+
+WOLFSSL_HMAC_CTX* wolfSSL_HMAC_CTX_new(void)
+{
+    return (WOLFSSL_HMAC_CTX*)XMALLOC(sizeof(WOLFSSL_HMAC_CTX), NULL,
+        DYNAMIC_TYPE_OPENSSL);
+}
+
+int wolfSSL_HMAC_CTX_Init(WOLFSSL_HMAC_CTX* ctx)
+{
+    WOLFSSL_MSG("wolfSSL_HMAC_CTX_Init");
+
+    if (ctx != NULL) {
+        /* wc_HmacSetKey sets up ctx->hmac */
+        XMEMSET(ctx, 0, sizeof(WOLFSSL_HMAC_CTX));
+    }
+
+    return WOLFSSL_SUCCESS;
+}
+
+
+int wolfSSL_HMAC_Init_ex(WOLFSSL_HMAC_CTX* ctx, const void* key,
+                             int keylen, const EVP_MD* type, WOLFSSL_ENGINE* e)
+{
+    WOLFSSL_ENTER("wolfSSL_HMAC_Init_ex");
+
+    /* WOLFSSL_ENGINE not used, call wolfSSL_HMAC_Init */
+    (void)e;
+    return wolfSSL_HMAC_Init(ctx, key, keylen, type);
+}
+
+
+/* helper function for Deep copy of internal wolfSSL hmac structure
+ * returns WOLFSSL_SUCCESS on success */
+int wolfSSL_HmacCopy(Hmac* des, Hmac* src)
+{
+    void* heap;
+
+#ifndef HAVE_FIPS
+    heap = src->heap;
+#else
+    heap = NULL;
+#endif
+    if (wc_HmacInit(des, heap, 0) != 0) {
+        return WOLFSSL_FAILURE;
+    }
+
+    /* requires that hash structures have no dynamic parts to them */
+    switch (src->macType) {
+    #ifndef NO_MD5
+        case WC_MD5:
+            wc_Md5Copy(&src->hash.md5, &des->hash.md5);
+            break;
+    #endif /* !NO_MD5 */
+
+    #ifndef NO_SHA
+        case WC_SHA:
+            wc_ShaCopy(&src->hash.sha, &des->hash.sha);
+            break;
+    #endif /* !NO_SHA */
+
+    #ifdef WOLFSSL_SHA224
+        case WC_SHA224:
+            wc_Sha224Copy(&src->hash.sha224, &des->hash.sha224);
+            break;
+    #endif /* WOLFSSL_SHA224 */
+
+    #ifndef NO_SHA256
+        case WC_SHA256:
+            wc_Sha256Copy(&src->hash.sha256, &des->hash.sha256);
+            break;
+    #endif /* !NO_SHA256 */
+
+    #ifdef WOLFSSL_SHA384
+        case WC_SHA384:
+            wc_Sha384Copy(&src->hash.sha384, &des->hash.sha384);
+            break;
+    #endif /* WOLFSSL_SHA384 */
+    #ifdef WOLFSSL_SHA512
+        case WC_SHA512:
+            wc_Sha512Copy(&src->hash.sha512, &des->hash.sha512);
+            break;
+    #endif /* WOLFSSL_SHA512 */
+
+        default:
+            return WOLFSSL_FAILURE;
+    }
+
+    XMEMCPY((byte*)des->ipad, (byte*)src->ipad, WC_HMAC_BLOCK_SIZE);
+    XMEMCPY((byte*)des->opad, (byte*)src->opad, WC_HMAC_BLOCK_SIZE);
+    XMEMCPY((byte*)des->innerHash, (byte*)src->innerHash, WC_MAX_DIGEST_SIZE);
+#ifndef HAVE_FIPS
+    des->heap    = heap;
+#endif
+    des->macType = src->macType;
+    des->innerHashKeyed = src->innerHashKeyed;
+
+#ifdef WOLFSSL_ASYNC_CRYPT
+    XMEMCPY(&des->asyncDev, &src->asyncDev, sizeof(WC_ASYNC_DEV));
+    des->keyLen = src->keyLen;
+    #ifdef HAVE_CAVIUM
+        des->data = (byte*)XMALLOC(src->dataLen, des->heap,
+                DYNAMIC_TYPE_HMAC);
+        if (des->data == NULL) {
+            return BUFFER_E;
+        }
+        XMEMCPY(des->data, src->data, src->dataLen);
+        des->dataLen = src->dataLen;
+    #endif /* HAVE_CAVIUM */
+#endif /* WOLFSSL_ASYNC_CRYPT */
+        return WOLFSSL_SUCCESS;
+}
+
+
+/* Deep copy of information from src to des structure
+ *
+ * des destination to copy information to
+ * src structure to get information from
+ *
+ * Returns WOLFSSL_SUCCESS on success and WOLFSSL_FAILURE on error
+ */
+int wolfSSL_HMAC_CTX_copy(WOLFSSL_HMAC_CTX* des, WOLFSSL_HMAC_CTX* src)
+{
+    WOLFSSL_ENTER("wolfSSL_HMAC_CTX_copy");
+
+    if (des == NULL || src == NULL) {
+        return WOLFSSL_FAILURE;
+    }
+
+    des->type = src->type;
+    XMEMCPY((byte *)&des->save_ipad, (byte *)&src->hmac.ipad,
+                                        WC_HMAC_BLOCK_SIZE);
+    XMEMCPY((byte *)&des->save_opad, (byte *)&src->hmac.opad,
+                                        WC_HMAC_BLOCK_SIZE);
+
+    return wolfSSL_HmacCopy(&des->hmac, &src->hmac);
+}
+
+
+#if defined(HAVE_FIPS) && \
+    (!defined(HAVE_FIPS_VERSION) || (HAVE_FIPS_VERSION < 2))
+
+static int _HMAC_Init(Hmac* hmac, int type, void* heap)
+{
+    int ret = 0;
+
+    switch (type) {
+    #ifndef NO_MD5
+        case WC_MD5:
+            ret = wc_InitMd5(&hmac->hash.md5);
+            break;
+    #endif /* !NO_MD5 */
+
+    #ifndef NO_SHA
+        case WC_SHA:
+            ret = wc_InitSha(&hmac->hash.sha);
+            break;
+    #endif /* !NO_SHA */
+
+    #ifdef WOLFSSL_SHA224
+        case WC_SHA224:
+            ret = wc_InitSha224(&hmac->hash.sha224);
+            break;
+    #endif /* WOLFSSL_SHA224 */
+
+    #ifndef NO_SHA256
+        case WC_SHA256:
+            ret = wc_InitSha256(&hmac->hash.sha256);
+            break;
+    #endif /* !NO_SHA256 */
+
+    #ifdef WOLFSSL_SHA384
+        case WC_SHA384:
+            ret = wc_InitSha384(&hmac->hash.sha384);
+            break;
+    #endif /* WOLFSSL_SHA384 */
+    #ifdef WOLFSSL_SHA512
+        case WC_SHA512:
+            ret = wc_InitSha512(&hmac->hash.sha512);
+            break;
+    #endif /* WOLFSSL_SHA512 */
+
+    #ifdef WOLFSSL_SHA3
+        case WC_SHA3_224:
+            ret = wc_InitSha3_224(&hmac->hash.sha3, heap, INVALID_DEVID);
+            break;
+        case WC_SHA3_256:
+            ret = wc_InitSha3_256(&hmac->hash.sha3, heap, INVALID_DEVID);
+            break;
+        case WC_SHA3_384:
+            ret = wc_InitSha3_384(&hmac->hash.sha3, heap, INVALID_DEVID);
+            break;
+        case WC_SHA3_512:
+            ret = wc_InitSha3_512(&hmac->hash.sha3, heap, INVALID_DEVID);
+            break;
+    #endif
+
+        default:
+            ret = BAD_FUNC_ARG;
+            break;
+    }
+
+    (void)heap;
+
+    return ret;
+}
+
+#else
+    #define _HMAC_Init _InitHmac
+#endif
+
+
+int wolfSSL_HMAC_Init(WOLFSSL_HMAC_CTX* ctx, const void* key, int keylen,
+                  const EVP_MD* type)
+{
+    int hmac_error = 0;
+    void* heap = NULL;
+
+    WOLFSSL_MSG("wolfSSL_HMAC_Init");
+
+    if (ctx == NULL) {
+        WOLFSSL_MSG("no ctx on init");
+        return WOLFSSL_FAILURE;
+    }
+
+#ifndef HAVE_FIPS
+    heap = ctx->hmac.heap;
+#endif
+
+    if (type) {
+        WOLFSSL_MSG("init has type");
+
+#ifndef NO_MD5
+        if (XSTRNCMP(type, "MD5", 3) == 0) {
+            WOLFSSL_MSG("md5 hmac");
+            ctx->type = WC_MD5;
+        }
+        else
+#endif
+#ifdef WOLFSSL_SHA224
+        if (XSTRNCMP(type, "SHA224", 6) == 0) {
+            WOLFSSL_MSG("sha224 hmac");
+            ctx->type = WC_SHA224;
+        }
+        else
+#endif
+#ifndef NO_SHA256
+        if (XSTRNCMP(type, "SHA256", 6) == 0) {
+            WOLFSSL_MSG("sha256 hmac");
+            ctx->type = WC_SHA256;
+        }
+        else
+#endif
+#ifdef WOLFSSL_SHA384
+        if (XSTRNCMP(type, "SHA384", 6) == 0) {
+            WOLFSSL_MSG("sha384 hmac");
+            ctx->type = WC_SHA384;
+        }
+        else
+#endif
+#ifdef WOLFSSL_SHA512
+        if (XSTRNCMP(type, "SHA512", 6) == 0) {
+            WOLFSSL_MSG("sha512 hmac");
+            ctx->type = WC_SHA512;
+        }
+        else
+#endif
+
+#ifndef NO_SHA
+        /* has to be last since would pick or 256, 384, or 512 too */
+        if (XSTRNCMP(type, "SHA", 3) == 0) {
+            WOLFSSL_MSG("sha hmac");
+            ctx->type = WC_SHA;
+        }
+        else
+#endif
+        {
+            WOLFSSL_MSG("bad init type");
+            return WOLFSSL_FAILURE;
+        }
+    }
+
+    if (key && keylen) {
+        WOLFSSL_MSG("keying hmac");
+
+        if (wc_HmacInit(&ctx->hmac, NULL, INVALID_DEVID) == 0) {
+            hmac_error = wc_HmacSetKey(&ctx->hmac, ctx->type, (const byte*)key,
+                                       (word32)keylen);
+            if (hmac_error < 0){
+                wc_HmacFree(&ctx->hmac);
+                return WOLFSSL_FAILURE;
+            }
+            XMEMCPY((byte *)&ctx->save_ipad, (byte *)&ctx->hmac.ipad,
+                                        WC_HMAC_BLOCK_SIZE);
+            XMEMCPY((byte *)&ctx->save_opad, (byte *)&ctx->hmac.opad,
+                                        WC_HMAC_BLOCK_SIZE);
+        }
+        /* OpenSSL compat, no error */
+    } else if(ctx->type >= 0) { /* MD5 == 0 */
+        WOLFSSL_MSG("recover hmac");
+        wc_HmacFree(&ctx->hmac);
+        if (wc_HmacInit(&ctx->hmac, NULL, INVALID_DEVID) == 0) {
+            ctx->hmac.macType = (byte)ctx->type;
+            ctx->hmac.innerHashKeyed = 0;
+            XMEMCPY((byte *)&ctx->hmac.ipad, (byte *)&ctx->save_ipad,
+                                       WC_HMAC_BLOCK_SIZE);
+            XMEMCPY((byte *)&ctx->hmac.opad, (byte *)&ctx->save_opad,
+                                       WC_HMAC_BLOCK_SIZE);
+            if ((hmac_error = _HMAC_Init(&ctx->hmac, ctx->hmac.macType, heap))
+                    !=0) {
+               return hmac_error;
+            }
+        }
+    }
+
+    (void)hmac_error;
+
+    return WOLFSSL_SUCCESS;
+}
+
+
+int wolfSSL_HMAC_Update(WOLFSSL_HMAC_CTX* ctx, const unsigned char* data,
+                    int len)
+{
+    int hmac_error = 0;
+
+    WOLFSSL_MSG("wolfSSL_HMAC_Update");
+
+    if (ctx == NULL) {
+        WOLFSSL_MSG("no ctx");
+        return WOLFSSL_FAILURE;
+    }
+
+    if (data) {
+        WOLFSSL_MSG("updating hmac");
+        hmac_error = wc_HmacUpdate(&ctx->hmac, data, (word32)len);
+        if (hmac_error < 0){
+            WOLFSSL_MSG("hmac update error");
+            return WOLFSSL_FAILURE;
+        }
+    }
+
+    return WOLFSSL_SUCCESS;
+}
+
+
+int wolfSSL_HMAC_Final(WOLFSSL_HMAC_CTX* ctx, unsigned char* hash,
+                   unsigned int* len)
+{
+    int hmac_error;
+
+    WOLFSSL_MSG("wolfSSL_HMAC_Final");
+
+    /* "len" parameter is optional. */
+    if (ctx == NULL || hash == NULL) {
+        WOLFSSL_MSG("invalid parameter");
+        return WOLFSSL_FAILURE;
+    }
+
+    WOLFSSL_MSG("final hmac");
+    hmac_error = wc_HmacFinal(&ctx->hmac, hash);
+    if (hmac_error < 0){
+        WOLFSSL_MSG("final hmac error");
+        return WOLFSSL_FAILURE;
+    }
+
+    if (len) {
+        WOLFSSL_MSG("setting output len");
+        switch (ctx->type) {
+            #ifndef NO_MD5
+            case WC_MD5:
+                *len = WC_MD5_DIGEST_SIZE;
+                break;
+            #endif
+
+            #ifndef NO_SHA
+            case WC_SHA:
+                *len = WC_SHA_DIGEST_SIZE;
+                break;
+            #endif
+
+            #ifdef WOLFSSL_SHA224
+            case WC_SHA224:
+                *len = WC_SHA224_DIGEST_SIZE;
+                break;
+            #endif
+
+            #ifndef NO_SHA256
+            case WC_SHA256:
+                *len = WC_SHA256_DIGEST_SIZE;
+                break;
+            #endif
+
+            #ifdef WOLFSSL_SHA384
+            case WC_SHA384:
+                *len = WC_SHA384_DIGEST_SIZE;
+                break;
+            #endif
+
+            #ifdef WOLFSSL_SHA512
+            case WC_SHA512:
+                *len = WC_SHA512_DIGEST_SIZE;
+                break;
+            #endif
+
+            default:
+                WOLFSSL_MSG("bad hmac type");
+                return WOLFSSL_FAILURE;
+        }
+    }
+
+    return WOLFSSL_SUCCESS;
+}
+
+
+int wolfSSL_HMAC_cleanup(WOLFSSL_HMAC_CTX* ctx)
+{
+    WOLFSSL_MSG("wolfSSL_HMAC_cleanup");
+
+    if (ctx)
+        wc_HmacFree(&ctx->hmac);
+
+    return SSL_SUCCESS;
+}
+
+
+void wolfSSL_HMAC_CTX_free(WOLFSSL_HMAC_CTX* ctx)
+{
+    if (!ctx) {
+        return;
+    }
+    wolfSSL_HMAC_cleanup(ctx);
+    XFREE(ctx, NULL, DYNAMIC_TYPE_OPENSSL);
+}
+
+size_t wolfSSL_HMAC_size(const WOLFSSL_HMAC_CTX *ctx)
+{
+    if (!ctx) {
+        return 0;
+    }
+
+    return (size_t)wc_HashGetDigestSize((enum wc_HashType)ctx->hmac.macType);
+}
+
+#ifndef NO_DES3
+
+void wolfSSL_3des_iv(WOLFSSL_EVP_CIPHER_CTX* ctx, int doset,
+                            unsigned char* iv, int len)
+{
+    (void)len;
+
+    WOLFSSL_MSG("wolfSSL_3des_iv");
+
+    if (ctx == NULL || iv == NULL) {
+        WOLFSSL_MSG("Bad function argument");
+        return;
+    }
+
+    if (doset)
+        wc_Des3_SetIV(&ctx->cipher.des3, iv);  /* OpenSSL compat, no ret */
+    else
+        XMEMCPY(iv, &ctx->cipher.des3.reg, DES_BLOCK_SIZE);
+}
+
+#endif /* NO_DES3 */
+
+
+#ifndef NO_AES
+
+void wolfSSL_aes_ctr_iv(WOLFSSL_EVP_CIPHER_CTX* ctx, int doset,
+                      unsigned char* iv, int len)
+{
+    (void)len;
+
+    WOLFSSL_MSG("wolfSSL_aes_ctr_iv");
+
+    if (ctx == NULL || iv == NULL) {
+        WOLFSSL_MSG("Bad function argument");
+        return;
+    }
+
+    if (doset)
+       (void)wc_AesSetIV(&ctx->cipher.aes, iv);  /* OpenSSL compat, no ret */
+    else
+        XMEMCPY(iv, &ctx->cipher.aes.reg, AES_BLOCK_SIZE);
+}
+
+#endif /* NO_AES */
+
+
+/* Free the dynamically allocated data.
+ *
+ * p  Pointer to dynamically allocated memory.
+ */
+void wolfSSL_OPENSSL_free(void* p)
+{
+    WOLFSSL_MSG("wolfSSL_OPENSSL_free");
+
+    XFREE(p, NULL, DYNAMIC_TYPE_OPENSSL);
+}
+
+void *wolfSSL_OPENSSL_malloc(size_t a)
+{
+  return XMALLOC(a, NULL, DYNAMIC_TYPE_OPENSSL);
+}
+
+#if defined(WOLFSSL_KEY_GEN) && defined(WOLFSSL_PEM_TO_DER)
+
+static int EncryptDerKey(byte *der, int *derSz, const EVP_CIPHER* cipher,
+                         unsigned char* passwd, int passwdSz, byte **cipherInfo)
+{
+    int ret, paddingSz;
+    word32 idx, cipherInfoSz;
+#ifdef WOLFSSL_SMALL_STACK
+    EncryptedInfo* info = NULL;
+#else
+    EncryptedInfo  info[1];
+#endif
+
+    WOLFSSL_ENTER("EncryptDerKey");
+
+    if (der == NULL || derSz == NULL || cipher == NULL ||
+        passwd == NULL || cipherInfo == NULL)
+        return BAD_FUNC_ARG;
+
+#ifdef WOLFSSL_SMALL_STACK
+    info = (EncryptedInfo*)XMALLOC(sizeof(EncryptedInfo), NULL,
+                                   DYNAMIC_TYPE_ENCRYPTEDINFO);
+    if (info == NULL) {
+        WOLFSSL_MSG("malloc failed");
+        return WOLFSSL_FAILURE;
+    }
+#endif
+
+    XMEMSET(info, 0, sizeof(EncryptedInfo));
+
+    /* set the cipher name on info */
+    XSTRNCPY(info->name, cipher, NAME_SZ-1);
+    info->name[NAME_SZ-1] = '\0'; /* null term */
+
+    ret = wc_EncryptedInfoGet(info, info->name);
+    if (ret != 0) {
+        WOLFSSL_MSG("unsupported cipher");
+    #ifdef WOLFSSL_SMALL_STACK
+        XFREE(info, NULL, DYNAMIC_TYPE_ENCRYPTEDINFO);
+    #endif
+        return WOLFSSL_FAILURE;
+    }
+
+    /* Generate a random salt */
+    if (wolfSSL_RAND_bytes(info->iv, info->ivSz) != WOLFSSL_SUCCESS) {
+        WOLFSSL_MSG("generate iv failed");
+#ifdef WOLFSSL_SMALL_STACK
+        XFREE(info, NULL, DYNAMIC_TYPE_ENCRYPTEDINFO);
+#endif
+        return WOLFSSL_FAILURE;
+    }
+
+    /* add the padding before encryption */
+    paddingSz = ((*derSz)/info->ivSz + 1) * info->ivSz - (*derSz);
+    if (paddingSz == 0)
+        paddingSz = info->ivSz;
+    XMEMSET(der+(*derSz), (byte)paddingSz, paddingSz);
+    (*derSz) += paddingSz;
+
+    /* encrypt buffer */
+    if (wc_BufferKeyEncrypt(info, der, *derSz, passwd, passwdSz, WC_MD5) != 0) {
+        WOLFSSL_MSG("encrypt key failed");
+#ifdef WOLFSSL_SMALL_STACK
+        XFREE(info, NULL, DYNAMIC_TYPE_ENCRYPTEDINFO);
+#endif
+        return WOLFSSL_FAILURE;
+    }
+
+    /* create cipher info : 'cipher_name,Salt(hex)' */
+    cipherInfoSz = (word32)(2*info->ivSz + XSTRLEN(info->name) + 2);
+    *cipherInfo = (byte*)XMALLOC(cipherInfoSz, NULL,
+                                DYNAMIC_TYPE_STRING);
+    if (*cipherInfo == NULL) {
+        WOLFSSL_MSG("malloc failed");
+#ifdef WOLFSSL_SMALL_STACK
+        XFREE(info, NULL, DYNAMIC_TYPE_ENCRYPTEDINFO);
+#endif
+        return WOLFSSL_FAILURE;
+    }
+    XSTRNCPY((char*)*cipherInfo, info->name, cipherInfoSz);
+    XSTRNCAT((char*)*cipherInfo, ",", 2);
+
+    idx = (word32)XSTRLEN((char*)*cipherInfo);
+    cipherInfoSz -= idx;
+    ret = Base16_Encode(info->iv, info->ivSz, *cipherInfo+idx, &cipherInfoSz);
+
+#ifdef WOLFSSL_SMALL_STACK
+    XFREE(info, NULL, DYNAMIC_TYPE_ENCRYPTEDINFO);
+#endif
+    if (ret != 0) {
+        WOLFSSL_MSG("Base16_Encode failed");
+        XFREE(*cipherInfo, NULL, DYNAMIC_TYPE_STRING);
+        return WOLFSSL_FAILURE;
+    }
+
+    return WOLFSSL_SUCCESS;
+}
+#endif /* WOLFSSL_KEY_GEN || WOLFSSL_PEM_TO_DER */
+
+#if defined(WOLFSSL_KEY_GEN) && !defined(NO_RSA) && !defined(HAVE_USER_RSA)
+static int wolfSSL_RSA_To_Der(WOLFSSL_RSA* rsa, byte** outBuf, int publicKey)
+{
+    int derSz  = 0;
+    int ret;
+    byte* derBuf;
+
+    WOLFSSL_ENTER("wolfSSL_RSA_To_Der");
+
+    if (!rsa || (publicKey != 0 && publicKey != 1)) {
+        WOLFSSL_LEAVE("wolfSSL_RSA_To_Der", BAD_FUNC_ARG);
+        return BAD_FUNC_ARG;
+    }
+
+    if (rsa->inSet == 0) {
+        if ((ret = SetRsaInternal(rsa)) != WOLFSSL_SUCCESS) {
+            WOLFSSL_MSG("SetRsaInternal() Failed");
+            WOLFSSL_LEAVE("wolfSSL_RSA_To_Der", ret);
+            return ret;
+        }
+    }
+
+    if (publicKey) {
+        if ((derSz = wc_RsaPublicKeyDerSize((RsaKey *)rsa->internal, 1)) < 0) {
+            WOLFSSL_MSG("wc_RsaPublicKeyDerSize failed");
+            WOLFSSL_LEAVE("wolfSSL_RSA_To_Der", derSz);
+            return derSz;
+        }
+    }
+    else {
+        if ((derSz = wc_RsaKeyToDer((RsaKey*)rsa->internal, NULL, 0)) < 0) {
+            WOLFSSL_MSG("wc_RsaKeyToDer failed");
+            WOLFSSL_LEAVE("wolfSSL_RSA_To_Der", derSz);
+            return derSz;
+        }
+    }
+
+    if (outBuf) {
+        if (!(derBuf = (byte*)XMALLOC(derSz, NULL, DYNAMIC_TYPE_TMP_BUFFER))) {
+            WOLFSSL_MSG("malloc failed");
+            WOLFSSL_LEAVE("wolfSSL_RSA_To_Der", MEMORY_ERROR);
+            return MEMORY_ERROR;
+        }
+
+        /* Key to DER */
+        if (publicKey) {
+            derSz = wc_RsaKeyToPublicDer((RsaKey*)rsa->internal, derBuf, derSz);
+        }
+        else {
+            derSz = wc_RsaKeyToDer((RsaKey*)rsa->internal, derBuf, derSz);
+        }
+
+        if (derSz < 0) {
+            WOLFSSL_MSG("wc_RsaKeyToPublicDer failed");
+            XFREE(derBuf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+        }
+        else {
+            if (*outBuf) {
+                XMEMCPY(*outBuf, derBuf, derSz);
+                XFREE(derBuf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+            }
+            else {
+                *outBuf = derBuf;
+            }
+        }
+    }
+
+    WOLFSSL_LEAVE("wolfSSL_RSA_To_Der", derSz);
+    return derSz;
+}
+#endif
+
+#if defined(WOLFSSL_KEY_GEN) || defined(WOLFSSL_CERT_GEN)
+#if (defined(OPENSSL_EXTRA) || defined(OPENSSL_ALL)) && !defined(NO_RSA)
+
+/* Takes a WOLFSSL_RSA key and writes it out to a WOLFSSL_BIO
+ *
+ * bio    the WOLFSSL_BIO to write to
+ * key    the WOLFSSL_RSA key to write out
+ * cipher cipher used
+ * passwd password string if used
+ * len    length of password string
+ * cb     password callback to use
+ * arg    null terminated string for passphrase
+ */
+int wolfSSL_PEM_write_bio_RSAPrivateKey(WOLFSSL_BIO* bio, WOLFSSL_RSA* key,
+                                        const WOLFSSL_EVP_CIPHER* cipher,
+                                        unsigned char* passwd, int len,
+                                        pem_password_cb* cb, void* arg)
+{
+    int ret;
+    WOLFSSL_EVP_PKEY* pkey;
+
+    WOLFSSL_ENTER("wolfSSL_PEM_write_bio_RSAPrivateKey");
+
+    if (bio == NULL || key == NULL) {
+        WOLFSSL_MSG("Bad Function Arguments");
+        return WOLFSSL_FAILURE;
+    }
+
+    pkey = wolfSSL_EVP_PKEY_new_ex(bio->heap);
+    if (pkey == NULL) {
+        WOLFSSL_MSG("wolfSSL_EVP_PKEY_new_ex failed");
+        return WOLFSSL_FAILURE;
+    }
+
+    pkey->type   = EVP_PKEY_RSA;
+    pkey->rsa    = key;
+    pkey->ownRsa = 0;
+#if defined(WOLFSSL_KEY_GEN) && !defined(NO_RSA) && !defined(HAVE_USER_RSA)
+    /* similar to how wolfSSL_PEM_write_mem_RSAPrivateKey finds DER of key */
+    {
+        int derSz;
+        byte* derBuf = NULL;
+
+        if ((derSz = wolfSSL_RSA_To_Der(key, &derBuf, 0)) < 0) {
+            WOLFSSL_MSG("wolfSSL_RSA_To_Der failed");
+            return WOLFSSL_FAILURE;
+        }
+
+        pkey->pkey.ptr = (char*)XMALLOC(derSz, bio->heap,
+                DYNAMIC_TYPE_TMP_BUFFER);
+        if (pkey->pkey.ptr == NULL) {
+            WOLFSSL_MSG("key malloc failed");
+            XFREE(derBuf, bio->heap, DYNAMIC_TYPE_TMP_BUFFER);
+            wolfSSL_EVP_PKEY_free(pkey);
+            return WOLFSSL_FAILURE;
+        }
+        pkey->pkey_sz = derSz;
+        XMEMCPY(pkey->pkey.ptr, derBuf, derSz);
+        XFREE(derBuf, bio->heap, DYNAMIC_TYPE_TMP_BUFFER);
+    }
+#endif
+
+    ret = wolfSSL_PEM_write_bio_PrivateKey(bio, pkey, cipher, passwd, len,
+                                        cb, arg);
+
+    wolfSSL_EVP_PKEY_free(pkey);
+
+    return ret;
+}
+
+#if defined(WOLFSSL_KEY_GEN) && !defined(NO_RSA) && !defined(HAVE_USER_RSA)
+/* Takes an RSA public key and writes it out to a WOLFSSL_BIO
+ * Returns WOLFSSL_SUCCESS or WOLFSSL_FAILURE
+ */
+int wolfSSL_PEM_write_bio_RSA_PUBKEY(WOLFSSL_BIO* bio, WOLFSSL_RSA* rsa)
+{
+    int ret = 0, derSz = 0;
+    byte *derBuf = NULL;
+    WOLFSSL_EVP_PKEY* pkey = NULL;
+
+    WOLFSSL_ENTER("wolfSSL_PEM_write_bio_RSA_PUBKEY");
+
+    if (bio == NULL || rsa == NULL) {
+        WOLFSSL_MSG("Bad Function Arguments");
+        return WOLFSSL_FAILURE;
+    }
+
+    /* Initialize pkey structure */
+    pkey = wolfSSL_EVP_PKEY_new_ex(bio->heap);
+    if (pkey == NULL) {
+        WOLFSSL_MSG("wolfSSL_EVP_PKEY_new_ex failed");
+        return WOLFSSL_FAILURE;
+    }
+
+    pkey->type   = EVP_PKEY_RSA;
+    pkey->rsa    = rsa;
+    pkey->ownRsa = 0;
+
+    if ((derSz = wolfSSL_RSA_To_Der(rsa, &derBuf, 1)) < 0) {
+        WOLFSSL_MSG("wolfSSL_RSA_To_Der failed");
+        return WOLFSSL_FAILURE;
+    }
+
+    pkey->pkey.ptr = (char*)XMALLOC(derSz, bio->heap,
+            DYNAMIC_TYPE_TMP_BUFFER);
+    if (pkey->pkey.ptr == NULL) {
+        WOLFSSL_MSG("key malloc failed");
+        XFREE(derBuf, bio->heap, DYNAMIC_TYPE_TMP_BUFFER);
+        wolfSSL_EVP_PKEY_free(pkey);
+        return WOLFSSL_FAILURE;
+    }
+    pkey->pkey_sz = derSz;
+    XMEMCPY(pkey->pkey.ptr, derBuf, derSz);
+    XFREE(derBuf, bio->heap, DYNAMIC_TYPE_TMP_BUFFER);
+    ret = wolfSSL_PEM_write_bio_PUBKEY(bio, pkey);
+    wolfSSL_EVP_PKEY_free(pkey);
+
+    return ret;
+}
+#endif
+
+
+/* Reads an RSA public key from a WOLFSSL_BIO into a WOLFSSL_RSA
+ * Returns WOLFSSL_SUCCESS or WOLFSSL_FAILURE
+ */
+WOLFSSL_RSA *wolfSSL_PEM_read_bio_RSA_PUBKEY(WOLFSSL_BIO* bio,WOLFSSL_RSA** rsa,
+                                                pem_password_cb* cb, void *pass)
+{
+    WOLFSSL_EVP_PKEY* pkey;
+    WOLFSSL_RSA* local;
+
+    WOLFSSL_ENTER("wolfSSL_PEM_read_bio_RSA_PUBKEY");
+
+    pkey = wolfSSL_PEM_read_bio_PUBKEY(bio, NULL, cb, pass);
+    if (pkey == NULL) {
+        return NULL;
+    }
+
+    /* Since the WOLFSSL_RSA structure is being taken from WOLFSSL_EVP_PKEY the
+     * flag indicating that the WOLFSSL_RSA structure is owned should be FALSE
+     * to avoid having it free'd */
+    pkey->ownRsa = 0;
+    local = pkey->rsa;
+    if (rsa != NULL){
+        *rsa = local;
+    }
+
+    wolfSSL_EVP_PKEY_free(pkey);
+    return local;
+}
+
+#endif /* defined(OPENSSL_EXTRA) || defined(OPENSSL_ALL) && !defined(NO_RSA) */
+
+/* Takes a public key and writes it out to a WOLFSSL_BIO
+ * Returns WOLFSSL_SUCCESS or WOLFSSL_FAILURE
+ */
+int wolfSSL_PEM_write_bio_PUBKEY(WOLFSSL_BIO* bio, WOLFSSL_EVP_PKEY* key)
+{
+    byte* keyDer;
+    int pemSz;
+    int ret;
+    byte* tmp;
+
+    WOLFSSL_ENTER("wolfSSL_PEM_write_bio_PUBKEY");
+
+    if (bio == NULL || key == NULL) {
+        return WOLFSSL_FAILURE;
+    }
+
+    keyDer = (byte*)key->pkey.ptr;
+
+    pemSz = wc_DerToPem(keyDer, key->pkey_sz, NULL, 0, PUBLICKEY_TYPE);
+    if (pemSz < 0) {
+        WOLFSSL_LEAVE("wolfSSL_PEM_write_bio_PUBKEY", pemSz);
+        return WOLFSSL_FAILURE;
+    }
+    tmp = (byte*)XMALLOC(pemSz, bio->heap, DYNAMIC_TYPE_OPENSSL);
+    if (tmp == NULL) {
+        return MEMORY_E;
+    }
+
+    ret = wc_DerToPemEx(keyDer, key->pkey_sz, tmp, pemSz,
+                        NULL, PUBLICKEY_TYPE);
+    if (ret < 0) {
+        WOLFSSL_LEAVE("wolfSSL_PEM_write_bio_PUBKEY", ret);
+        XFREE(tmp, bio->heap, DYNAMIC_TYPE_OPENSSL);
+        return WOLFSSL_FAILURE;
+    }
+
+    ret = wolfSSL_BIO_write(bio, tmp, pemSz);
+    XFREE(tmp, bio->heap, DYNAMIC_TYPE_OPENSSL);
+    if (ret != pemSz) {
+        WOLFSSL_MSG("Unable to write full PEM to BIO");
+        return WOLFSSL_FAILURE;
+    }
+
+    return WOLFSSL_SUCCESS;
+}
+
+/* Takes a private key and writes it out to a WOLFSSL_BIO
+ * Returns WOLFSSL_SUCCESS or WOLFSSL_FAILURE
+ */
+int wolfSSL_PEM_write_bio_PrivateKey(WOLFSSL_BIO* bio, WOLFSSL_EVP_PKEY* key,
+                                        const WOLFSSL_EVP_CIPHER* cipher,
+                                        unsigned char* passwd, int len,
+                                        pem_password_cb* cb, void* arg)
+{
+    byte* keyDer;
+    int pemSz;
+    int type;
+    int ret;
+    byte* tmp;
+
+    (void)cipher;
+    (void)passwd;
+    (void)len;
+    (void)cb;
+    (void)arg;
+
+    WOLFSSL_ENTER("wolfSSL_PEM_write_bio_PrivateKey");
+
+    if (bio == NULL || key == NULL) {
+        WOLFSSL_MSG("Bad Function Arguments");
+        return WOLFSSL_FAILURE;
+    }
+
+    keyDer = (byte*)key->pkey.ptr;
+
+    switch (key->type) {
+#ifndef NO_RSA
+        case EVP_PKEY_RSA:
+            type = PRIVATEKEY_TYPE;
+            break;
+#endif
+
+#ifndef NO_DSA
+        case EVP_PKEY_DSA:
+            type = DSA_PRIVATEKEY_TYPE;
+            break;
+#endif
+
+#ifdef HAVE_ECC
+        case EVP_PKEY_EC:
+            type = ECC_PRIVATEKEY_TYPE;
+            break;
+#endif
+
+#if !defined(NO_DH) && (defined(WOLFSSL_QT) || defined(OPENSSL_ALL))
+        case EVP_PKEY_DH:
+            type = DH_PRIVATEKEY_TYPE;
+            break;
+#endif
+
+        default:
+            WOLFSSL_MSG("Unknown Key type!");
+            type = PRIVATEKEY_TYPE;
+    }
+
+    pemSz = wc_DerToPem(keyDer, key->pkey_sz, NULL, 0, type);
+    if (pemSz < 0) {
+        WOLFSSL_LEAVE("wolfSSL_PEM_write_bio_PrivateKey", pemSz);
+        return WOLFSSL_FAILURE;
+    }
+    tmp = (byte*)XMALLOC(pemSz, bio->heap, DYNAMIC_TYPE_OPENSSL);
+    if (tmp == NULL) {
+        return MEMORY_E;
+    }
+
+    ret = wc_DerToPemEx(keyDer, key->pkey_sz, tmp, pemSz,
+                                NULL, type);
+    if (ret < 0) {
+        WOLFSSL_LEAVE("wolfSSL_PEM_write_bio_PrivateKey", ret);
+        XFREE(tmp, bio->heap, DYNAMIC_TYPE_OPENSSL);
+        return WOLFSSL_FAILURE;
+    }
+
+    ret = wolfSSL_BIO_write(bio, tmp, pemSz);
+    XFREE(tmp, bio->heap, DYNAMIC_TYPE_OPENSSL);
+    if (ret != pemSz) {
+        WOLFSSL_MSG("Unable to write full PEM to BIO");
+        return WOLFSSL_FAILURE;
+    }
+
+    return WOLFSSL_SUCCESS;
+}
+#endif /* defined(WOLFSSL_KEY_GEN) || defined(WOLFSSL_CERT_GEN) */
+
+#if (defined(WOLFSSL_KEY_GEN) && !defined(NO_RSA) && !defined(HAVE_USER_RSA)) && \
+    (defined(WOLFSSL_PEM_TO_DER) || defined(WOLFSSL_DER_TO_PEM))
+
+/* return code compliant with OpenSSL :
+ *   1 if success, 0 if error
+ */
+int wolfSSL_PEM_write_mem_RSAPrivateKey(RSA* rsa, const EVP_CIPHER* cipher,
+                                        unsigned char* passwd, int passwdSz,
+                                        unsigned char **pem, int *plen)
+{
+    byte *derBuf = NULL, *tmp, *cipherInfo = NULL;
+    int  derSz = 0;
+    const int type = PRIVATEKEY_TYPE;
+    const char* header = NULL;
+    const char* footer = NULL;
+
+    WOLFSSL_ENTER("wolfSSL_PEM_write_mem_RSAPrivateKey");
+
+    if (pem == NULL || plen == NULL || rsa == NULL || rsa->internal == NULL) {
+        WOLFSSL_MSG("Bad function arguments");
+        return WOLFSSL_FAILURE;
+    }
+
+    if (wc_PemGetHeaderFooter(type, &header, &footer) != 0)
+        return WOLFSSL_FAILURE;
+
+    if (rsa->inSet == 0) {
+        WOLFSSL_MSG("No RSA internal set, do it");
+
+        if (SetRsaInternal(rsa) != WOLFSSL_SUCCESS) {
+            WOLFSSL_MSG("SetRsaInternal failed");
+            return WOLFSSL_FAILURE;
+        }
+    }
+
+    if ((derSz = wolfSSL_RSA_To_Der(rsa, &derBuf, 0)) < 0) {
+        WOLFSSL_MSG("wolfSSL_RSA_To_Der failed");
+        return WOLFSSL_FAILURE;
+    }
+
+    /* encrypt DER buffer if required */
+    if (passwd != NULL && passwdSz > 0 && cipher != NULL) {
+        int ret;
+
+        ret = EncryptDerKey(derBuf, &derSz, cipher,
+                            passwd, passwdSz, &cipherInfo);
+        if (ret != WOLFSSL_SUCCESS) {
+            WOLFSSL_MSG("EncryptDerKey failed");
+            XFREE(derBuf, NULL, DYNAMIC_TYPE_DER);
+            return ret;
+        }
+
+        /* tmp buffer with a max size */
+        *plen = (derSz * 2) + (int)XSTRLEN(header) + 1 +
+            (int)XSTRLEN(footer) + 1 + HEADER_ENCRYPTED_KEY_SIZE;
+    }
+    else {
+        /* tmp buffer with a max size */
+        *plen = (derSz * 2) + (int)XSTRLEN(header) + 1 +
+            (int)XSTRLEN(footer) + 1;
+    }
+
+    tmp = (byte*)XMALLOC(*plen, NULL, DYNAMIC_TYPE_PEM);
+    if (tmp == NULL) {
+        WOLFSSL_MSG("malloc failed");
+        XFREE(derBuf, NULL, DYNAMIC_TYPE_DER);
+        if (cipherInfo != NULL)
+            XFREE(cipherInfo, NULL, DYNAMIC_TYPE_STRING);
+        return WOLFSSL_FAILURE;
+    }
+
+    /* DER to PEM */
+    *plen = wc_DerToPemEx(derBuf, derSz, tmp, *plen, cipherInfo, type);
+    if (*plen <= 0) {
+        WOLFSSL_MSG("wc_DerToPemEx failed");
+        XFREE(derBuf, NULL, DYNAMIC_TYPE_DER);
+        XFREE(tmp, NULL, DYNAMIC_TYPE_PEM);
+        if (cipherInfo != NULL)
+            XFREE(cipherInfo, NULL, DYNAMIC_TYPE_STRING);
+        return WOLFSSL_FAILURE;
+    }
+    XFREE(derBuf, NULL, DYNAMIC_TYPE_DER);
+    if (cipherInfo != NULL)
+        XFREE(cipherInfo, NULL, DYNAMIC_TYPE_STRING);
+
+    *pem = (byte*)XMALLOC((*plen)+1, NULL, DYNAMIC_TYPE_KEY);
+    if (*pem == NULL) {
+        WOLFSSL_MSG("malloc failed");
+        XFREE(tmp, NULL, DYNAMIC_TYPE_PEM);
+        return WOLFSSL_FAILURE;
+    }
+    XMEMSET(*pem, 0, (*plen)+1);
+
+    if (XMEMCPY(*pem, tmp, *plen) == NULL) {
+        WOLFSSL_MSG("XMEMCPY failed");
+        XFREE(pem, NULL, DYNAMIC_TYPE_KEY);
+        XFREE(tmp, NULL, DYNAMIC_TYPE_PEM);
+        return WOLFSSL_FAILURE;
+    }
+    XFREE(tmp, NULL, DYNAMIC_TYPE_PEM);
+
+    return WOLFSSL_SUCCESS;
+}
+
+
+#ifndef NO_FILESYSTEM
+/* return code compliant with OpenSSL :
+ *   1 if success, 0 if error
+ */
+int wolfSSL_PEM_write_RSAPrivateKey(XFILE fp, WOLFSSL_RSA *rsa,
+                                    const EVP_CIPHER *enc,
+                                    unsigned char *kstr, int klen,
+                                    pem_password_cb *cb, void *u)
+{
+    byte *pem;
+    int  plen, ret;
+
+    (void)cb;
+    (void)u;
+
+    WOLFSSL_MSG("wolfSSL_PEM_write_RSAPrivateKey");
+
+    if (fp == XBADFILE || rsa == NULL || rsa->internal == NULL)
+    {
+        WOLFSSL_MSG("Bad function arguments");
+        return WOLFSSL_FAILURE;
+    }
+
+    ret = wolfSSL_PEM_write_mem_RSAPrivateKey(rsa, enc, kstr, klen, &pem, &plen);
+    if (ret != WOLFSSL_SUCCESS) {
+        WOLFSSL_MSG("wolfSSL_PEM_write_mem_RSAPrivateKey failed");
+        return WOLFSSL_FAILURE;
+    }
+
+    ret = (int)XFWRITE(pem, plen, 1, fp);
+    if (ret != 1) {
+        WOLFSSL_MSG("RSA private key file write failed");
+        return WOLFSSL_FAILURE;
+    }
+
+    XFREE(pem, NULL, DYNAMIC_TYPE_KEY);
+    return WOLFSSL_SUCCESS;
+}
+#endif /* NO_FILESYSTEM */
+#endif /* WOLFSSL_KEY_GEN && !NO_RSA && !HAVE_USER_RSA && WOLFSSL_PEM_TO_DER */
+
+
+#ifdef HAVE_ECC
+
+#ifdef ALT_ECC_SIZE
+static int SetIndividualInternalEcc(WOLFSSL_BIGNUM* bn, mp_int* mpi)
+{
+    WOLFSSL_MSG("Entering SetIndividualInternal");
+
+    if (bn == NULL || bn->internal == NULL) {
+        WOLFSSL_MSG("bn NULL error");
+        return WOLFSSL_FATAL_ERROR;
+    }
+
+    if (mpi == NULL) {
+        WOLFSSL_MSG("mpi NULL error");
+        return WOLFSSL_FATAL_ERROR;
+    }
+
+    if (mp_copy((mp_int*)bn->internal, mpi) != MP_OKAY) {
+        WOLFSSL_MSG("mp_copy error");
+        return WOLFSSL_FATAL_ERROR;
+    }
+
+    return WOLFSSL_SUCCESS;
+}
+#endif /* ALT_ECC_SIZE */
+
+/* EC_POINT Openssl -> WolfSSL */
+static int SetECPointInternal(WOLFSSL_EC_POINT *p)
+{
+    ecc_point* point;
+    WOLFSSL_ENTER("SetECPointInternal");
+
+    if (p == NULL || p->internal == NULL) {
+        WOLFSSL_MSG("ECPoint NULL error");
+        return WOLFSSL_FATAL_ERROR;
+    }
+
+    point = (ecc_point*)p->internal;
+
+#ifndef ALT_ECC_SIZE
+    if (p->X != NULL && SetIndividualInternal(p->X, point->x) != WOLFSSL_SUCCESS) {
+        WOLFSSL_MSG("ecc point X error");
+        return WOLFSSL_FATAL_ERROR;
+    }
+
+    if (p->Y != NULL && SetIndividualInternal(p->Y, point->y) != WOLFSSL_SUCCESS) {
+        WOLFSSL_MSG("ecc point Y error");
+        return WOLFSSL_FATAL_ERROR;
+    }
+
+    if (p->Z != NULL && SetIndividualInternal(p->Z, point->z) != WOLFSSL_SUCCESS) {
+        WOLFSSL_MSG("ecc point Z error");
+        return WOLFSSL_FATAL_ERROR;
+    }
+#else
+    if (p->X != NULL && SetIndividualInternalEcc(p->X, point->x) != WOLFSSL_SUCCESS) {
+        WOLFSSL_MSG("ecc point X error");
+        return WOLFSSL_FATAL_ERROR;
+    }
+
+    if (p->Y != NULL && SetIndividualInternalEcc(p->Y, point->y) != WOLFSSL_SUCCESS) {
+        WOLFSSL_MSG("ecc point Y error");
+        return WOLFSSL_FATAL_ERROR;
+    }
+
+    if (p->Z != NULL && SetIndividualInternalEcc(p->Z, point->z) != WOLFSSL_SUCCESS) {
+        WOLFSSL_MSG("ecc point Z error");
+        return WOLFSSL_FATAL_ERROR;
+    }
+#endif
+
+    p->inSet = 1;
+
+    return WOLFSSL_SUCCESS;
+}
+
+/* EC_POINT WolfSSL -> OpenSSL */
+static int SetECPointExternal(WOLFSSL_EC_POINT *p)
+{
+    ecc_point* point;
+
+    WOLFSSL_ENTER("SetECPointExternal");
+
+    if (p == NULL || p->internal == NULL) {
+        WOLFSSL_MSG("ECPoint NULL error");
+        return WOLFSSL_FATAL_ERROR;
+    }
+
+    point = (ecc_point*)p->internal;
+
+    if (SetIndividualExternal(&p->X, point->x) != WOLFSSL_SUCCESS) {
+        WOLFSSL_MSG("ecc point X error");
+        return WOLFSSL_FATAL_ERROR;
+    }
+
+    if (SetIndividualExternal(&p->Y, point->y) != WOLFSSL_SUCCESS) {
+        WOLFSSL_MSG("ecc point Y error");
+        return WOLFSSL_FATAL_ERROR;
+    }
+
+    if (SetIndividualExternal(&p->Z, point->z) != WOLFSSL_SUCCESS) {
+        WOLFSSL_MSG("ecc point Z error");
+        return WOLFSSL_FATAL_ERROR;
+    }
+
+    p->exSet = 1;
+
+    return WOLFSSL_SUCCESS;
+}
+
+
+/* EC_KEY wolfSSL -> OpenSSL */
+int SetECKeyExternal(WOLFSSL_EC_KEY* eckey)
+{
+    ecc_key* key;
+
+    WOLFSSL_ENTER("SetECKeyExternal");
+
+    if (eckey == NULL || eckey->internal == NULL) {
+        WOLFSSL_MSG("ec key NULL error");
+        return WOLFSSL_FATAL_ERROR;
+    }
+
+    key = (ecc_key*)eckey->internal;
+
+    /* set group (OID, nid and idx) */
+    eckey->group->curve_oid = ecc_sets[key->idx].oidSum;
+    eckey->group->curve_nid = ecc_sets[key->idx].id;
+    eckey->group->curve_idx = key->idx;
+
+    if (eckey->pub_key->internal != NULL) {
+        /* set the internal public key */
+        if (wc_ecc_copy_point(&key->pubkey,
+                             (ecc_point*)eckey->pub_key->internal) != MP_OKAY) {
+            WOLFSSL_MSG("SetECKeyExternal ecc_copy_point failed");
+            return WOLFSSL_FATAL_ERROR;
+        }
+
+        /* set the external pubkey (point) */
+        if (SetECPointExternal(eckey->pub_key) != WOLFSSL_SUCCESS) {
+            WOLFSSL_MSG("SetECKeyExternal SetECPointExternal failed");
+            return WOLFSSL_FATAL_ERROR;
+        }
+    }
+
+    /* set the external privkey */
+    if (key->type == ECC_PRIVATEKEY) {
+        if (SetIndividualExternal(&eckey->priv_key, &key->k) != WOLFSSL_SUCCESS) {
+            WOLFSSL_MSG("ec priv key error");
+            return WOLFSSL_FATAL_ERROR;
+        }
+    }
+
+    eckey->exSet = 1;
+
+    return WOLFSSL_SUCCESS;
+}
+
+/* EC_KEY Openssl -> WolfSSL */
+int SetECKeyInternal(WOLFSSL_EC_KEY* eckey)
+{
+    ecc_key* key;
+
+    WOLFSSL_ENTER("SetECKeyInternal");
+
+    if (eckey == NULL || eckey->internal == NULL || eckey->group == NULL) {
+        WOLFSSL_MSG("ec key NULL error");
+        return WOLFSSL_FATAL_ERROR;
+    }
+
+    key = (ecc_key*)eckey->internal;
+
+    /* validate group */
+    if ((eckey->group->curve_idx < 0) ||
+        (wc_ecc_is_valid_idx(eckey->group->curve_idx) == 0)) {
+        WOLFSSL_MSG("invalid curve idx");
+        return WOLFSSL_FATAL_ERROR;
+    }
+
+    /* set group (idx of curve and corresponding domain parameters) */
+    key->idx = eckey->group->curve_idx;
+    key->dp = &ecc_sets[key->idx];
+
+    /* set pubkey (point) */
+    if (eckey->pub_key != NULL) {
+        if (SetECPointInternal(eckey->pub_key) != WOLFSSL_SUCCESS) {
+            WOLFSSL_MSG("ec key pub error");
+            return WOLFSSL_FATAL_ERROR;
+        }
+
+        /* copy over the public point to key */
+        if (wc_ecc_copy_point((ecc_point*)eckey->pub_key->internal, &key->pubkey) != MP_OKAY) {
+            WOLFSSL_MSG("wc_ecc_copy_point error");
+            return WOLFSSL_FATAL_ERROR;
+        }
+
+        /* public key */
+        key->type = ECC_PUBLICKEY;
+    }
+
+    /* set privkey */
+    if (eckey->priv_key != NULL) {
+        if (SetIndividualInternal(eckey->priv_key, &key->k) != WOLFSSL_SUCCESS) {
+            WOLFSSL_MSG("ec key priv error");
+            return WOLFSSL_FATAL_ERROR;
+        }
+
+        /* private key */
+        key->type = ECC_PRIVATEKEY;
+    }
+
+    eckey->inSet = 1;
+
+    return WOLFSSL_SUCCESS;
+}
+
+WOLFSSL_EC_POINT *wolfSSL_EC_KEY_get0_public_key(const WOLFSSL_EC_KEY *key)
+{
+    WOLFSSL_ENTER("wolfSSL_EC_KEY_get0_public_key");
+
+    if (key == NULL) {
+        WOLFSSL_MSG("wolfSSL_EC_KEY_get0_public_key Bad arguments");
+        return NULL;
+    }
+
+    return key->pub_key;
+}
+
+const WOLFSSL_EC_GROUP *wolfSSL_EC_KEY_get0_group(const WOLFSSL_EC_KEY *key)
+{
+    WOLFSSL_ENTER("wolfSSL_EC_KEY_get0_group");
+
+    if (key == NULL) {
+        WOLFSSL_MSG("wolfSSL_EC_KEY_get0_group Bad arguments");
+        return NULL;
+    }
+
+    return key->group;
+}
+
+
+/* return code compliant with OpenSSL :
+ *   1 if success, 0 if error
+ */
+int wolfSSL_EC_KEY_set_private_key(WOLFSSL_EC_KEY *key,
+                                   const WOLFSSL_BIGNUM *priv_key)
+{
+    WOLFSSL_ENTER("wolfSSL_EC_KEY_set_private_key");
+
+    if (key == NULL || priv_key == NULL) {
+        WOLFSSL_MSG("Bad arguments");
+        return WOLFSSL_FAILURE;
+    }
+
+    /* free key if previously set */
+    if (key->priv_key != NULL)
+        wolfSSL_BN_free(key->priv_key);
+
+    key->priv_key = wolfSSL_BN_dup(priv_key);
+    if (key->priv_key == NULL) {
+        WOLFSSL_MSG("key ecc priv key NULL");
+        return WOLFSSL_FAILURE;
+    }
+
+    if (SetECKeyInternal(key) != WOLFSSL_SUCCESS) {
+        WOLFSSL_MSG("SetECKeyInternal failed");
+        wolfSSL_BN_free(key->priv_key);
+        return WOLFSSL_FAILURE;
+    }
+
+    return WOLFSSL_SUCCESS;
+}
+
+
+WOLFSSL_BIGNUM *wolfSSL_EC_KEY_get0_private_key(const WOLFSSL_EC_KEY *key)
+{
+    WOLFSSL_ENTER("wolfSSL_EC_KEY_get0_private_key");
+
+    if (key == NULL) {
+        WOLFSSL_MSG("wolfSSL_EC_KEY_get0_private_key Bad arguments");
+        return NULL;
+    }
+
+    if (wolfSSL_BN_is_zero(key->priv_key)) {
+        /* return NULL if not set */
+        return NULL;
+    }
+
+    return key->priv_key;
+}
+
+WOLFSSL_EC_KEY *wolfSSL_EC_KEY_new_by_curve_name(int nid)
+{
+    WOLFSSL_EC_KEY *key;
+    int x;
+    int eccEnum;
+
+    WOLFSSL_ENTER("wolfSSL_EC_KEY_new_by_curve_name");
+
+    /* If NID passed in is OpenSSL type, convert it to ecc_curve_id enum */
+    eccEnum = NIDToEccEnum(nid);
+    if (eccEnum == -1)
+        eccEnum = nid;
+
+    key = wolfSSL_EC_KEY_new();
+    if (key == NULL) {
+        WOLFSSL_MSG("wolfSSL_EC_KEY_new failure");
+        return NULL;
+    }
+
+    /* set the nid of the curve */
+    key->group->curve_nid = eccEnum;
+
+    /* search and set the corresponding internal curve idx */
+    for (x = 0; ecc_sets[x].size != 0; x++)
+        if (ecc_sets[x].id == key->group->curve_nid) {
+            key->group->curve_idx = x;
+            key->group->curve_oid = ecc_sets[x].oidSum;
+            break;
+        }
+
+    return key;
+}
+
+const char* wolfSSL_EC_curve_nid2nist(int nid)
+{
+    const WOLF_EC_NIST_NAME* nist_name;
+    for (nist_name = kNistCurves; nist_name->name != NULL; nist_name++) {
+        if (nist_name->nid == nid) {
+            return kNistCurves->name;
+        }
+    }
+    return NULL;
+}
+
+#ifdef WOLFSSL_TLS13
+static int populate_groups(int* groups, int max_count, char *list)
+{
+    char *end;
+    int len;
+    int count = 0;
+    const WOLF_EC_NIST_NAME* nist_name;
+
+    if (!groups || !list) {
+        return -1;
+    }
+
+    for (end = list; ; list = ++end) {
+        if (count > max_count) {
+            WOLFSSL_MSG("Too many curves in list");
+            return -1;
+        }
+        while (*end != ':' && *end != '\0') end++;
+        len = (int)(end - list); /* end points to char after end
+                                  * of curve name so no need for -1 */
+        if ((len < kNistCurves_MIN_NAME_LEN) ||
+                (len > kNistCurves_MAX_NAME_LEN)) {
+            WOLFSSL_MSG("Unrecognized curve name in list");
+            return -1;
+        }
+        for (nist_name = kNistCurves; nist_name->name != NULL; nist_name++) {
+            if (len == nist_name->name_len &&
+                    XSTRNCMP(list, nist_name->name, nist_name->name_len) == 0) {
+                break;
+            }
+        }
+        if (!nist_name->name) {
+            WOLFSSL_MSG("Unrecognized curve name in list");
+            return -1;
+        }
+        groups[count++] = nist_name->nid;
+        if (*end == '\0') break;
+    }
+
+    return count;
+}
+
+int wolfSSL_CTX_set1_groups_list(WOLFSSL_CTX *ctx, char *list)
+{
+    int groups[WOLFSSL_MAX_GROUP_COUNT];
+    int count;
+
+    if (!ctx || !list) {
+        return WOLFSSL_FAILURE;
+    }
+
+    if ((count = populate_groups(groups,
+            WOLFSSL_MAX_GROUP_COUNT, list)) == -1) {
+        return WOLFSSL_FAILURE;
+    }
+
+    return wolfSSL_CTX_set_groups(ctx, groups, count) == WOLFSSL_SUCCESS ?
+            WOLFSSL_SUCCESS : WOLFSSL_FAILURE;
+}
+
+int wolfSSL_set1_groups_list(WOLFSSL *ssl, char *list)
+{
+    int groups[WOLFSSL_MAX_GROUP_COUNT];
+    int count;
+
+    if (!ssl || !list) {
+        return WOLFSSL_FAILURE;
+    }
+
+    if ((count = populate_groups(groups,
+            WOLFSSL_MAX_GROUP_COUNT, list)) == -1) {
+        return WOLFSSL_FAILURE;
+    }
+
+    return wolfSSL_set_groups(ssl, groups, count) == WOLFSSL_SUCCESS ?
+            WOLFSSL_SUCCESS : WOLFSSL_FAILURE;
+}
+#endif /* WOLFSSL_TLS13 */
+
+static void InitwolfSSL_ECKey(WOLFSSL_EC_KEY* key)
+{
+    if (key) {
+        key->group    = NULL;
+        key->pub_key  = NULL;
+        key->priv_key = NULL;
+        key->internal = NULL;
+        key->inSet    = 0;
+        key->exSet    = 0;
+    }
+}
+
+WOLFSSL_EC_KEY *wolfSSL_EC_KEY_new(void)
+{
+    WOLFSSL_EC_KEY *external;
+    WOLFSSL_ENTER("wolfSSL_EC_KEY_new");
+
+    external = (WOLFSSL_EC_KEY*)XMALLOC(sizeof(WOLFSSL_EC_KEY), NULL,
+                                        DYNAMIC_TYPE_ECC);
+    if (external == NULL) {
+        WOLFSSL_MSG("wolfSSL_EC_KEY_new malloc WOLFSSL_EC_KEY failure");
+        return NULL;
+    }
+    XMEMSET(external, 0, sizeof(WOLFSSL_EC_KEY));
+
+    InitwolfSSL_ECKey(external);
+
+    external->internal = (ecc_key*)XMALLOC(sizeof(ecc_key), NULL,
+                                           DYNAMIC_TYPE_ECC);
+    if (external->internal == NULL) {
+        WOLFSSL_MSG("wolfSSL_EC_KEY_new malloc ecc key failure");
+        goto error;
+    }
+    XMEMSET(external->internal, 0, sizeof(ecc_key));
+
+    if (wc_ecc_init((ecc_key*)external->internal) != 0) {
+        WOLFSSL_MSG("wolfSSL_EC_KEY_new init ecc key failure");
+        goto error;
+    }
+
+    /* curve group */
+    external->group = wolfSSL_EC_GROUP_new_by_curve_name(ECC_CURVE_DEF);
+    if (external->group == NULL) {
+        WOLFSSL_MSG("wolfSSL_EC_KEY_new malloc WOLFSSL_EC_GROUP failure");
+        goto error;
+    }
+
+    /* public key */
+    external->pub_key = wolfSSL_EC_POINT_new(external->group);
+    if (external->pub_key == NULL) {
+        WOLFSSL_MSG("wolfSSL_EC_POINT_new failure");
+        goto error;
+    }
+
+    /* private key */
+    external->priv_key = wolfSSL_BN_new();
+    if (external->priv_key == NULL) {
+        WOLFSSL_MSG("wolfSSL_BN_new failure");
+        goto error;
+    }
+
+    return external;
+error:
+    wolfSSL_EC_KEY_free(external);
+    return NULL;
+}
+
+void wolfSSL_EC_KEY_free(WOLFSSL_EC_KEY *key)
+{
+    WOLFSSL_ENTER("wolfSSL_EC_KEY_free");
+
+    if (key != NULL) {
+        if (key->internal != NULL) {
+            wc_ecc_free((ecc_key*)key->internal);
+            XFREE(key->internal, NULL, DYNAMIC_TYPE_ECC);
+        }
+        wolfSSL_BN_free(key->priv_key);
+        wolfSSL_EC_POINT_free(key->pub_key);
+        wolfSSL_EC_GROUP_free(key->group);
+        InitwolfSSL_ECKey(key); /* set back to NULLs for safety */
+
+        XFREE(key, NULL, DYNAMIC_TYPE_ECC);
+        /* key = NULL, don't try to access or double free it */
+    }
+}
+
+#ifndef NO_WOLFSSL_STUB
+int wolfSSL_EC_KEY_set_group(WOLFSSL_EC_KEY *key, WOLFSSL_EC_GROUP *group)
+{
+    (void)key;
+    (void)group;
+
+    WOLFSSL_ENTER("wolfSSL_EC_KEY_set_group");
+    WOLFSSL_STUB("EC_KEY_set_group");
+
+    return -1;
+}
+#endif
+
+int wolfSSL_EC_KEY_generate_key(WOLFSSL_EC_KEY *key)
+{
+    int     initTmpRng = 0;
+    WC_RNG* rng = NULL;
+#ifdef WOLFSSL_SMALL_STACK
+    WC_RNG* tmpRNG = NULL;
+#else
+    WC_RNG  tmpRNG[1];
+#endif
+
+    WOLFSSL_ENTER("wolfSSL_EC_KEY_generate_key");
+
+    if (key == NULL || key->internal == NULL ||
+        key->group == NULL || key->group->curve_idx < 0) {
+        WOLFSSL_MSG("wolfSSL_EC_KEY_generate_key Bad arguments");
+        return 0;
+    }
+
+#ifdef WOLFSSL_SMALL_STACK
+    tmpRNG = (WC_RNG*)XMALLOC(sizeof(WC_RNG), NULL, DYNAMIC_TYPE_RNG);
+    if (tmpRNG == NULL)
+        return 0;
+#endif
+
+    if (wc_InitRng(tmpRNG) == 0) {
+        rng = tmpRNG;
+        initTmpRng = 1;
+    }
+    else {
+        WOLFSSL_MSG("Bad RNG Init, trying global");
+        if (initGlobalRNG == 0)
+            WOLFSSL_MSG("Global RNG no Init");
+        else
+            rng = &globalRNG;
+    }
+
+    if (rng == NULL) {
+        WOLFSSL_MSG("wolfSSL_EC_KEY_generate_key failed to set RNG");
+#ifdef WOLFSSL_SMALL_STACK
+        XFREE(tmpRNG, NULL, DYNAMIC_TYPE_RNG);
+#endif
+        return 0;
+    }
+
+    if (wc_ecc_make_key_ex(rng, 0, (ecc_key*)key->internal,
+                                        key->group->curve_nid) != MP_OKAY) {
+        WOLFSSL_MSG("wolfSSL_EC_KEY_generate_key wc_ecc_make_key failed");
+#ifdef WOLFSSL_SMALL_STACK
+        XFREE(tmpRNG, NULL, DYNAMIC_TYPE_RNG);
+#endif
+        return 0;
+    }
+
+    if (initTmpRng)
+        wc_FreeRng(tmpRNG);
+#ifdef WOLFSSL_SMALL_STACK
+    XFREE(tmpRNG, NULL, DYNAMIC_TYPE_RNG);
+#endif
+
+    if (SetECKeyExternal(key) != WOLFSSL_SUCCESS) {
+        WOLFSSL_MSG("wolfSSL_EC_KEY_generate_key SetECKeyExternal failed");
+        return 0;
+    }
+
+    return 1;
+}
+
+#ifndef NO_WOLFSSL_STUB
+void wolfSSL_EC_KEY_set_asn1_flag(WOLFSSL_EC_KEY *key, int asn1_flag)
+{
+    (void)key;
+    (void)asn1_flag;
+
+    WOLFSSL_ENTER("wolfSSL_EC_KEY_set_asn1_flag");
+    WOLFSSL_STUB("EC_KEY_set_asn1_flag");
+}
+#endif
+
+static int setupPoint(const WOLFSSL_EC_POINT *p) {
+    if (!p) {
+        return WOLFSSL_FAILURE;
+    }
+    if (p->inSet == 0) {
+        WOLFSSL_MSG("No ECPoint internal set, do it");
+
+        if (SetECPointInternal((WOLFSSL_EC_POINT *)p) != WOLFSSL_SUCCESS) {
+            WOLFSSL_MSG("SetECPointInternal SetECPointInternal failed");
+            return WOLFSSL_FAILURE;
+        }
+    }
+    return WOLFSSL_SUCCESS;
+}
+
+/* return code compliant with OpenSSL :
+ *   1 if success, 0 if error
+ */
+int wolfSSL_EC_KEY_set_public_key(WOLFSSL_EC_KEY *key,
+                                  const WOLFSSL_EC_POINT *pub)
+{
+    ecc_point *pub_p, *key_p;
+
+    WOLFSSL_ENTER("wolfSSL_EC_KEY_set_public_key");
+
+    if (key == NULL || key->internal == NULL ||
+        pub == NULL || pub->internal == NULL) {
+        WOLFSSL_MSG("wolfSSL_EC_GROUP_get_order Bad arguments");
+        return WOLFSSL_FAILURE;
+    }
+
+    if (key->inSet == 0) {
+        if (SetECKeyInternal(key) != WOLFSSL_SUCCESS) {
+            WOLFSSL_MSG("SetECKeyInternal failed");
+            return WOLFSSL_FAILURE;
+        }
+    }
+
+    if (setupPoint(pub) != WOLFSSL_SUCCESS) {
+        return WOLFSSL_FAILURE;
+    }
+
+    pub_p = (ecc_point*)pub->internal;
+    key_p = (ecc_point*)key->pub_key->internal;
+
+    /* create new point if required */
+    if (key_p == NULL)
+        key_p = wc_ecc_new_point();
+
+    if (key_p == NULL) {
+        WOLFSSL_MSG("key ecc point NULL");
+        return WOLFSSL_FAILURE;
+    }
+
+    if (wc_ecc_copy_point(pub_p, key_p) != MP_OKAY) {
+        WOLFSSL_MSG("ecc_copy_point failure");
+        return WOLFSSL_FAILURE;
+    }
+
+    if (SetECPointExternal(key->pub_key) != WOLFSSL_SUCCESS) {
+        WOLFSSL_MSG("SetECKeyInternal failed");
+        return WOLFSSL_FAILURE;
+    }
+
+    if (SetECKeyInternal(key) != WOLFSSL_SUCCESS) {
+        WOLFSSL_MSG("SetECKeyInternal failed");
+        return WOLFSSL_FAILURE;
+    }
+
+    wolfSSL_EC_POINT_dump("pub", pub);
+    wolfSSL_EC_POINT_dump("key->pub_key", key->pub_key);
+
+    return WOLFSSL_SUCCESS;
+}
+/* End EC_KEY */
+
+int wolfSSL_ECDSA_size(const WOLFSSL_EC_KEY *key)
+{
+    const EC_GROUP *group;
+    int bits, bytes;
+    word32 headerSz = 4;   /* 2*ASN_TAG + 2*LEN(ENUM) */
+
+    if (!key) {
+        return WOLFSSL_FAILURE;
+    }
+
+    if (!(group = wolfSSL_EC_KEY_get0_group(key))) {
+        return WOLFSSL_FAILURE;
+    }
+    if ((bits = wolfSSL_EC_GROUP_order_bits(group)) == 0) {
+        return WOLFSSL_FAILURE;
+    }
+    bytes = (bits + 7) / 8; /* bytes needed to hold bits */
+    return headerSz +
+            2 + /* possible leading zeroes in r and s */
+            bytes + bytes + /* r and s */
+            2;
+}
+
+int wolfSSL_ECDSA_sign(int type, const unsigned char *digest,
+                       int digestSz, unsigned char *sig,
+                       unsigned int *sigSz, WOLFSSL_EC_KEY *key)
+{
+    int ret = WOLFSSL_SUCCESS;
+    WC_RNG* rng = NULL;
+#ifdef WOLFSSL_SMALL_STACK
+    WC_RNG* tmpRNG = NULL;
+#else
+    WC_RNG  tmpRNG[1];
+#endif
+    int initTmpRng = 0;
+
+    WOLFSSL_ENTER("wolfSSL_ECDSA_sign");
+
+    if (!key) {
+        return WOLFSSL_FAILURE;
+    }
+
+#ifdef WOLFSSL_SMALL_STACK
+    tmpRNG = (WC_RNG*)XMALLOC(sizeof(WC_RNG), NULL, DYNAMIC_TYPE_RNG);
+    if (tmpRNG == NULL)
+        return WOLFSSL_FAILURE;
+#endif
+
+    if (wc_InitRng(tmpRNG) == 0) {
+        rng = tmpRNG;
+        initTmpRng = 1;
+    }
+    else {
+        WOLFSSL_MSG("Bad RNG Init, trying global");
+        if (initGlobalRNG == 0) {
+            WOLFSSL_MSG("Global RNG no Init");
+        }
+        else {
+            rng = &globalRNG;
+        }
+    }
+    if (rng) {
+        if (wc_ecc_sign_hash(digest, digestSz, sig, sigSz, rng, (ecc_key*)key->internal) != MP_OKAY) {
+            ret = WOLFSSL_FAILURE;
+        }
+        if (initTmpRng) {
+            wc_FreeRng(tmpRNG);
+        }
+    } else {
+        ret = WOLFSSL_FAILURE;
+    }
+
+#ifdef WOLFSSL_SMALL_STACK
+    if (tmpRNG)
+        XFREE(tmpRNG, NULL, DYNAMIC_TYPE_RNG);
+#endif
+
+    (void)type;
+    return ret;
+}
+
+#ifndef HAVE_SELFTEST
+/* ECC point compression types were not included in selftest ecc.h */
+
+char* wolfSSL_EC_POINT_point2hex(const WOLFSSL_EC_GROUP* group,
+                                 const WOLFSSL_EC_POINT* point, int form,
+                                 WOLFSSL_BN_CTX* ctx)
+{
+    static const char* hexDigit = "0123456789ABCDEF";
+    char* hex = NULL;
+    int id;
+    int i, sz, len;
+
+    (void)ctx;
+
+    if (group == NULL || point == NULL)
+        return NULL;
+
+    id = wc_ecc_get_curve_id(group->curve_idx);
+
+    if ((sz = wc_ecc_get_curve_size_from_id(id)) < 0)
+        return NULL;
+
+    len = sz + 1;
+    if (form == POINT_CONVERSION_UNCOMPRESSED)
+        len += sz;
+
+    hex = (char*)XMALLOC(2 * len + 1, NULL, DYNAMIC_TYPE_ECC);
+    if (hex == NULL)
+        return NULL;
+    XMEMSET(hex, 0, 2 * len + 1);
+
+    /* Put in x-ordinate after format byte. */
+    i = sz - mp_unsigned_bin_size((mp_int*)point->X->internal) + 1;
+    if (mp_to_unsigned_bin((mp_int*)point->X->internal, (byte*)(hex + i)) < 0) {
+        XFREE(hex,  NULL, DYNAMIC_TYPE_ECC);
+        return NULL;
+    }
+
+    if (form == POINT_CONVERSION_COMPRESSED) {
+        hex[0] = mp_isodd((mp_int*)point->Y->internal) ? ECC_POINT_COMP_ODD :
+                                                         ECC_POINT_COMP_EVEN;
+    }
+    else {
+        hex[0] = ECC_POINT_UNCOMP;
+        /* Put in y-ordinate after x-ordinate */
+        i = 1 + 2 * sz - mp_unsigned_bin_size((mp_int*)point->Y->internal);
+        if (mp_to_unsigned_bin((mp_int*)point->Y->internal,
+                                                        (byte*)(hex + i)) < 0) {
+            XFREE(hex,  NULL, DYNAMIC_TYPE_ECC);
+            return NULL;
+        }
+    }
+
+    for (i = len-1; i >= 0; i--) {
+        byte b = hex[i];
+        hex[i * 2 + 1] = hexDigit[b  & 0xf];
+        hex[i * 2    ] = hexDigit[b >>   4];
+    }
+
+    return hex;
+}
+
+#endif /* HAVE_SELFTEST */
+
+void wolfSSL_EC_POINT_dump(const char *msg, const WOLFSSL_EC_POINT *p)
+{
+#if defined(DEBUG_WOLFSSL)
+    char *num;
+
+    WOLFSSL_ENTER("wolfSSL_EC_POINT_dump");
+
+    if (!WOLFSSL_IS_DEBUG_ON() || wolfSSL_GetLoggingCb()) {
+        return;
+    }
+
+    if (p == NULL) {
+        printf("%s = NULL", msg);
+        return;
+    }
+
+    printf("%s:\n\tinSet=%d, exSet=%d\n", msg, p->inSet, p->exSet);
+    num = wolfSSL_BN_bn2hex(p->X);
+    printf("\tX = %s\n", num);
+    XFREE(num, NULL, DYNAMIC_TYPE_ECC);
+    num = wolfSSL_BN_bn2hex(p->Y);
+    printf("\tY = %s\n", num);
+    XFREE(num, NULL, DYNAMIC_TYPE_ECC);
+    num = wolfSSL_BN_bn2hex(p->Z);
+    printf("\tZ = %s\n", num);
+    XFREE(num, NULL, DYNAMIC_TYPE_ECC);
+#else
+    (void)msg;
+    (void)p;
+#endif
+}
+
+/* Start EC_GROUP */
+
+/* return code compliant with OpenSSL :
+ *   0 if equal, 1 if not and -1 in case of error
+ */
+int wolfSSL_EC_GROUP_cmp(const WOLFSSL_EC_GROUP *a, const WOLFSSL_EC_GROUP *b,
+                         WOLFSSL_BN_CTX *ctx)
+{
+    (void)ctx;
+
+    WOLFSSL_ENTER("wolfSSL_EC_GROUP_cmp");
+
+    if (a == NULL || b == NULL) {
+        WOLFSSL_MSG("wolfSSL_EC_GROUP_cmp Bad arguments");
+        return WOLFSSL_FATAL_ERROR;
+    }
+
+    /* ok */
+    if ((a->curve_idx == b->curve_idx) && (a->curve_nid == b->curve_nid))
+        return 0;
+
+    /* ko */
+    return 1;
+}
+
+#endif /* HAVE_ECC */
+#endif /* OPENSSL_EXTRA */
+
+#if defined(HAVE_ECC) && (defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL))
+const WOLFSSL_EC_METHOD* wolfSSL_EC_GROUP_method_of(
+                                                const WOLFSSL_EC_GROUP *group)
+{
+    return group;
+}
+
+int wolfSSL_EC_METHOD_get_field_type(const WOLFSSL_EC_METHOD *meth)
+{
+    if (meth) {
+        return NID_X9_62_prime_field;
+    }
+    return WOLFSSL_FAILURE;
+}
+
+void wolfSSL_EC_GROUP_free(WOLFSSL_EC_GROUP *group)
+{
+    WOLFSSL_ENTER("wolfSSL_EC_GROUP_free");
+
+    XFREE(group, NULL, DYNAMIC_TYPE_ECC);
+    /* group = NULL, don't try to access or double free it */
+}
+#endif
+
+#ifdef OPENSSL_EXTRA
+#ifdef HAVE_ECC
+#ifndef NO_WOLFSSL_STUB
+void wolfSSL_EC_GROUP_set_asn1_flag(WOLFSSL_EC_GROUP *group, int flag)
+{
+    (void)group;
+    (void)flag;
+
+    WOLFSSL_ENTER("wolfSSL_EC_GROUP_set_asn1_flag");
+    WOLFSSL_STUB("EC_GROUP_set_asn1_flag");
+}
+#endif
+
+WOLFSSL_EC_GROUP *wolfSSL_EC_GROUP_new_by_curve_name(int nid)
+{
+    WOLFSSL_EC_GROUP *g;
+    int x;
+    int eccEnum;
+
+    WOLFSSL_ENTER("wolfSSL_EC_GROUP_new_by_curve_name");
+
+    /* If NID passed in is OpenSSL type, convert it to ecc_curve_id enum */
+    eccEnum = NIDToEccEnum(nid);
+    if (eccEnum == -1)
+        eccEnum = nid;
+
+
+    /* curve group */
+    g = (WOLFSSL_EC_GROUP*) XMALLOC(sizeof(WOLFSSL_EC_GROUP), NULL,
+                                    DYNAMIC_TYPE_ECC);
+    if (g == NULL) {
+        WOLFSSL_MSG("wolfSSL_EC_GROUP_new_by_curve_name malloc failure");
+        return NULL;
+    }
+    XMEMSET(g, 0, sizeof(WOLFSSL_EC_GROUP));
+
+    /* set the nid of the curve */
+    g->curve_nid = eccEnum;
+
+    if (eccEnum > ECC_CURVE_DEF) {
+        /* search and set the corresponding internal curve idx */
+        for (x = 0; ecc_sets[x].size != 0; x++)
+            if (ecc_sets[x].id == g->curve_nid) {
+                g->curve_idx = x;
+                g->curve_oid = ecc_sets[x].oidSum;
+                break;
+            }
+    }
+
+    return g;
+}
+
+/* return code compliant with OpenSSL :
+ *   the curve nid if success, 0 if error
+ */
+int wolfSSL_EC_GROUP_get_curve_name(const WOLFSSL_EC_GROUP *group)
+{
+    int nid;
+    WOLFSSL_ENTER("wolfSSL_EC_GROUP_get_curve_name");
+
+    if (group == NULL) {
+        WOLFSSL_MSG("wolfSSL_EC_GROUP_get_curve_name Bad arguments");
+        return WOLFSSL_FAILURE;
+    }
+
+    /* If curve_nid is ECC Enum type, return corresponding OpenSSL nid */
+    if ((nid = EccEnumToNID(group->curve_nid)) != -1)
+        return nid;
+
+    return group->curve_nid;
+}
+
+/* return code compliant with OpenSSL :
+ *   the degree of the curve if success, 0 if error
+ */
+int wolfSSL_EC_GROUP_get_degree(const WOLFSSL_EC_GROUP *group)
+{
+    int nid;
+    int tmp;
+
+    WOLFSSL_ENTER("wolfSSL_EC_GROUP_get_degree");
+
+    if (group == NULL || group->curve_idx < 0) {
+        WOLFSSL_MSG("wolfSSL_EC_GROUP_get_degree Bad arguments");
+        return WOLFSSL_FAILURE;
+    }
+
+    /* If curve_nid passed in is an ecc_curve_id enum, convert it to the
+        corresponding OpenSSL NID */
+    tmp = EccEnumToNID(group->curve_nid);
+    if (tmp != -1){
+        nid = tmp;
+    }
+    else{
+        nid = group->curve_nid;
+    }
+
+    switch(nid) {
+        case NID_secp112r1:
+        case NID_secp112r2:
+            return 112;
+        case NID_secp128r1:
+        case NID_secp128r2:
+            return 128;
+        case NID_secp160k1:
+        case NID_secp160r1:
+        case NID_secp160r2:
+        case NID_brainpoolP160r1:
+            return 160;
+        case NID_secp192k1:
+        case NID_brainpoolP192r1:
+        case NID_X9_62_prime192v1:
+            return 192;
+        case NID_secp224k1:
+        case NID_secp224r1:
+        case NID_brainpoolP224r1:
+            return 224;
+        case NID_secp256k1:
+        case NID_brainpoolP256r1:
+        case NID_X9_62_prime256v1:
+            return 256;
+        case NID_brainpoolP320r1:
+            return 320;
+        case NID_secp384r1:
+        case NID_brainpoolP384r1:
+            return 384;
+        case NID_secp521r1:
+            return 521;
+        case NID_brainpoolP512r1:
+            return 512;
+        default:
+            return WOLFSSL_FAILURE;
+    }
+}
+
+/* Converts OpenSSL NID value of ECC curves to the associated enum values in
+   ecc_curve_id, used by ecc_sets[].*/
+int NIDToEccEnum(int n)
+{
+    WOLFSSL_ENTER("NIDToEccEnum()");
+
+    switch(n) {
+        case NID_X9_62_prime192v1:
+            return ECC_SECP192R1;
+        case NID_X9_62_prime192v2:
+            return ECC_PRIME192V2;
+        case NID_X9_62_prime192v3:
+            return ECC_PRIME192V3;
+        case NID_X9_62_prime239v1:
+            return ECC_PRIME239V1;
+        case NID_X9_62_prime239v2:
+            return ECC_PRIME239V2;
+        case NID_X9_62_prime239v3:
+            return ECC_PRIME239V3;
+        case NID_X9_62_prime256v1:
+            return ECC_SECP256R1;
+        case NID_secp112r1:
+            return ECC_SECP112R1;
+        case NID_secp112r2:
+            return ECC_SECP112R2;
+        case NID_secp128r1:
+            return ECC_SECP128R1;
+        case NID_secp128r2:
+            return ECC_SECP128R2;
+        case NID_secp160r1:
+            return ECC_SECP160R1;
+        case NID_secp160r2:
+            return ECC_SECP160R2;
+        case NID_secp224r1:
+            return ECC_SECP224R1;
+        case NID_secp384r1:
+            return ECC_SECP384R1;
+        case NID_secp521r1:
+            return ECC_SECP521R1;
+        case NID_secp160k1:
+            return ECC_SECP160K1;
+        case NID_secp192k1:
+            return ECC_SECP192K1;
+        case NID_secp224k1:
+            return ECC_SECP224K1;
+        case NID_secp256k1:
+            return ECC_SECP256K1;
+        case NID_brainpoolP160r1:
+            return ECC_BRAINPOOLP160R1;
+        case NID_brainpoolP192r1:
+            return ECC_BRAINPOOLP192R1;
+        case NID_brainpoolP224r1:
+            return ECC_BRAINPOOLP224R1;
+        case NID_brainpoolP256r1:
+            return ECC_BRAINPOOLP256R1;
+        case NID_brainpoolP320r1:
+            return ECC_BRAINPOOLP320R1;
+        case NID_brainpoolP384r1:
+            return ECC_BRAINPOOLP384R1;
+        case NID_brainpoolP512r1:
+            return ECC_BRAINPOOLP512R1;
+        default:
+            WOLFSSL_MSG("NID not found");
+            return -1;
+    }
+}
+
+/* return code compliant with OpenSSL :
+ *   1 if success, 0 if error
+ */
+int wolfSSL_EC_GROUP_get_order(const WOLFSSL_EC_GROUP *group,
+                               WOLFSSL_BIGNUM *order, WOLFSSL_BN_CTX *ctx)
+{
+    (void)ctx;
+
+    if (group == NULL || order == NULL || order->internal == NULL) {
+        WOLFSSL_MSG("wolfSSL_EC_GROUP_get_order NULL error");
+        return WOLFSSL_FAILURE;
+    }
+
+    if (mp_init((mp_int*)order->internal) != MP_OKAY) {
+        WOLFSSL_MSG("wolfSSL_EC_GROUP_get_order mp_init failure");
+        return WOLFSSL_FAILURE;
+    }
+
+    if (mp_read_radix((mp_int*)order->internal,
+                  ecc_sets[group->curve_idx].order, MP_RADIX_HEX) != MP_OKAY) {
+        WOLFSSL_MSG("wolfSSL_EC_GROUP_get_order mp_read order failure");
+        mp_clear((mp_int*)order->internal);
+        return WOLFSSL_FAILURE;
+    }
+
+    return WOLFSSL_SUCCESS;
+}
+
+int wolfSSL_EC_GROUP_order_bits(const WOLFSSL_EC_GROUP *group)
+{
+    int ret;
+    mp_int order;
+
+    if (group == NULL || group->curve_idx < 0) {
+        WOLFSSL_MSG("wolfSSL_EC_GROUP_order_bits NULL error");
+        return 0;
+    }
+
+    ret = mp_init(&order);
+    if (ret == 0) {
+        ret = mp_read_radix(&order, ecc_sets[group->curve_idx].order,
+            MP_RADIX_HEX);
+        if (ret == 0)
+            ret = mp_count_bits(&order);
+        mp_clear(&order);
+    }
+
+    return ret;
+}
+
+/* End EC_GROUP */
+
+/* Start EC_POINT */
+
+/* return code compliant with OpenSSL :
+ *   1 if success, 0 if error
+ */
+int wolfSSL_ECPoint_i2d(const WOLFSSL_EC_GROUP *group,
+                        const WOLFSSL_EC_POINT *p,
+                        unsigned char *out, unsigned int *len)
+{
+    int err;
+
+    WOLFSSL_ENTER("wolfSSL_ECPoint_i2d");
+
+    if (group == NULL || p == NULL || len == NULL) {
+        WOLFSSL_MSG("wolfSSL_ECPoint_i2d NULL error");
+        return WOLFSSL_FAILURE;
+    }
+
+    if (setupPoint(p) != WOLFSSL_SUCCESS) {
+        return WOLFSSL_FAILURE;
+    }
+
+    if (out != NULL) {
+        wolfSSL_EC_POINT_dump("i2d p", p);
+    }
+
+    err = wc_ecc_export_point_der(group->curve_idx, (ecc_point*)p->internal,
+                                  out, len);
+    if (err != MP_OKAY && !(out == NULL && err == LENGTH_ONLY_E)) {
+        WOLFSSL_MSG("wolfSSL_ECPoint_i2d wc_ecc_export_point_der failed");
+        return WOLFSSL_FAILURE;
+    }
+
+    return WOLFSSL_SUCCESS;
+}
+
+/* return code compliant with OpenSSL :
+ *   1 if success, 0 if error
+ */
+int wolfSSL_ECPoint_d2i(unsigned char *in, unsigned int len,
+                        const WOLFSSL_EC_GROUP *group, WOLFSSL_EC_POINT *p)
+{
+    WOLFSSL_ENTER("wolfSSL_ECPoint_d2i");
+
+    if (group == NULL || p == NULL || p->internal == NULL || in == NULL) {
+        WOLFSSL_MSG("wolfSSL_ECPoint_d2i NULL error");
+        return WOLFSSL_FAILURE;
+    }
+
+#ifndef HAVE_SELFTEST
+    if (wc_ecc_import_point_der_ex(in, len, group->curve_idx,
+                                   (ecc_point*)p->internal, 0) != MP_OKAY) {
+        WOLFSSL_MSG("wc_ecc_import_point_der_ex failed");
+        return WOLFSSL_FAILURE;
+    }
+#else
+    /* ECC_POINT_UNCOMP is not defined CAVP self test so use magic number */
+    if (in[0] == 0x04) {
+        if (wc_ecc_import_point_der(in, len, group->curve_idx,
+                                    (ecc_point*)p->internal) != MP_OKAY) {
+            WOLFSSL_MSG("wc_ecc_import_point_der failed");
+            return WOLFSSL_FAILURE;
+        }
+    }
+    else {
+        WOLFSSL_MSG("Only uncompressed points supported with HAVE_SELFTEST");
+        return WOLFSSL_FAILURE;
+    }
+#endif
+
+    /* Set new external point */
+    if (SetECPointExternal(p) != WOLFSSL_SUCCESS) {
+        WOLFSSL_MSG("SetECPointExternal failed");
+        return WOLFSSL_FAILURE;
+    }
+
+    wolfSSL_EC_POINT_dump("d2i p", p);
+
+    return WOLFSSL_SUCCESS;
+}
+
+size_t wolfSSL_EC_POINT_point2oct(const WOLFSSL_EC_GROUP *group,
+                                  const WOLFSSL_EC_POINT *p,
+                                  char form,
+                                  byte *buf, size_t len, WOLFSSL_BN_CTX *ctx)
+{
+    word32 min_len = (word32)len;
+#ifndef HAVE_SELFTEST
+    int compressed = form == POINT_CONVERSION_COMPRESSED ? 1 : 0;
+#endif /* !HAVE_SELFTEST */
+
+    WOLFSSL_ENTER("EC_POINT_point2oct");
+
+    if (!group || !p) {
+        return WOLFSSL_FAILURE;
+    }
+
+    if (setupPoint(p) != WOLFSSL_SUCCESS) {
+        return WOLFSSL_FAILURE;
+    }
+
+    if (wolfSSL_EC_POINT_is_at_infinity(group, p)) {
+        /* encodes to a single 0 octet */
+        if (buf != NULL) {
+            if (len < 1) {
+                ECerr(EC_F_EC_GFP_SIMPLE_POINT2OCT, EC_R_BUFFER_TOO_SMALL);
+                return WOLFSSL_FAILURE;
+            }
+            buf[0] = 0;
+        }
+        return 1;
+    }
+
+    if (form != POINT_CONVERSION_UNCOMPRESSED
+#ifndef HAVE_SELFTEST
+            && form != POINT_CONVERSION_COMPRESSED
+#endif /* !HAVE_SELFTEST */
+            ) {
+        WOLFSSL_MSG("Unsupported curve form");
+        return WOLFSSL_FAILURE;
+    }
+
+#ifndef HAVE_SELFTEST
+    if (wc_ecc_export_point_der_ex(group->curve_idx, (ecc_point*)p->internal,
+               buf, &min_len, compressed) != (buf ? MP_OKAY : LENGTH_ONLY_E)) {
+        return WOLFSSL_FAILURE;
+    }
+#else
+    if (wc_ecc_export_point_der(group->curve_idx, (ecc_point*)p->internal,
+                                buf, &min_len) != (buf ? MP_OKAY : LENGTH_ONLY_E)) {
+        return WOLFSSL_FAILURE;
+    }
+#endif /* !HAVE_SELFTEST */
+
+    (void)ctx;
+
+    return (size_t)min_len;
+}
+
+int wolfSSL_EC_POINT_oct2point(const WOLFSSL_EC_GROUP *group,
+                               WOLFSSL_EC_POINT *p, const unsigned char *buf,
+                               size_t len, WOLFSSL_BN_CTX *ctx)
+{
+    WOLFSSL_ENTER("wolfSSL_EC_POINT_oct2point");
+
+    if (!group || !p) {
+        return WOLFSSL_FAILURE;
+    }
+
+    (void)ctx;
+
+    return wolfSSL_ECPoint_d2i((unsigned char*)buf, (unsigned int)len, group, p);
+}
+
+int wolfSSL_i2o_ECPublicKey(const WOLFSSL_EC_KEY *in, unsigned char **out)
+{
+    size_t len;
+    unsigned char *tmp = NULL;
+    char form;
+    WOLFSSL_ENTER("wolfSSL_i2o_ECPublicKey");
+
+    if (!in) {
+        WOLFSSL_MSG("wolfSSL_i2o_ECPublicKey Bad arguments");
+        return WOLFSSL_FAILURE;
+    }
+
+    /* Default to compressed form if not set */
+    form = in->form == POINT_CONVERSION_UNCOMPRESSED ?
+            POINT_CONVERSION_UNCOMPRESSED:
+            POINT_CONVERSION_COMPRESSED;
+
+    len = wolfSSL_EC_POINT_point2oct(in->group, in->pub_key, form,
+                                     NULL, 0, NULL);
+
+    if (len != WOLFSSL_FAILURE && out) {
+        if (!*out) {
+            if (!(tmp = (unsigned char*)XMALLOC(len, NULL,
+                                                DYNAMIC_TYPE_OPENSSL))) {
+                WOLFSSL_MSG("malloc failed");
+                return WOLFSSL_FAILURE;
+            }
+            *out = tmp;
+        }
+
+        if (wolfSSL_EC_POINT_point2oct(in->group, in->pub_key, form, *out,
+                                       len, NULL) == WOLFSSL_FAILURE) {
+            if (tmp) {
+                XFREE(tmp, NULL, DYNAMIC_TYPE_OPENSSL);
+                *out = NULL;
+            }
+            return WOLFSSL_FAILURE;
+        }
+
+        if (!tmp) {
+            /* Move buffer forward if it was not alloced in this function */
+            *out += len;
+        }
+    }
+
+    return (int)len;
+}
+
+void wolfSSL_EC_KEY_set_conv_form(WOLFSSL_EC_KEY *eckey, char form)
+{
+    if (eckey && (form == POINT_CONVERSION_COMPRESSED ||
+                  form == POINT_CONVERSION_UNCOMPRESSED)) {
+        eckey->form = form;
+    }
+}
+
+
+/* wolfSSL_EC_POINT_point2bn should return "in" if not null */
+WOLFSSL_BIGNUM *wolfSSL_EC_POINT_point2bn(const WOLFSSL_EC_GROUP *group,
+                                          const WOLFSSL_EC_POINT *p,
+                                          char form,
+                                          WOLFSSL_BIGNUM *in, WOLFSSL_BN_CTX *ctx)
+{
+    size_t len;
+    byte *buf;
+    WOLFSSL_BIGNUM *ret = NULL;
+
+    WOLFSSL_ENTER("wolfSSL_EC_POINT_oct2point");
+
+    if (!group || !p) {
+        return NULL;
+    }
+
+    if ((len = wolfSSL_EC_POINT_point2oct(group, p, form,
+                                          NULL, 0, ctx)) == WOLFSSL_FAILURE) {
+        return NULL;
+    }
+
+    if (!(buf = (byte*)XMALLOC(len, NULL, DYNAMIC_TYPE_TMP_BUFFER))) {
+        WOLFSSL_MSG("malloc failed");
+        return NULL;
+    }
+
+    if (wolfSSL_EC_POINT_point2oct(group, p, form,
+                                   buf, len, ctx) == len) {
+        ret = wolfSSL_BN_bin2bn(buf, (int)len, in);
+    }
+
+    XFREE(buf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+
+    return ret;
+}
+
+WOLFSSL_EC_POINT *wolfSSL_EC_POINT_new(const WOLFSSL_EC_GROUP *group)
+{
+    WOLFSSL_EC_POINT *p;
+
+    WOLFSSL_ENTER("wolfSSL_EC_POINT_new");
+
+    if (group == NULL) {
+        WOLFSSL_MSG("wolfSSL_EC_POINT_new NULL error");
+        return NULL;
+    }
+
+    p = (WOLFSSL_EC_POINT *)XMALLOC(sizeof(WOLFSSL_EC_POINT), NULL,
+                                    DYNAMIC_TYPE_ECC);
+    if (p == NULL) {
+        WOLFSSL_MSG("wolfSSL_EC_POINT_new malloc ecc point failure");
+        return NULL;
+    }
+    XMEMSET(p, 0, sizeof(WOLFSSL_EC_POINT));
+
+    p->internal = wc_ecc_new_point();
+    if (p->internal == NULL) {
+        WOLFSSL_MSG("ecc_new_point failure");
+        XFREE(p, NULL, DYNAMIC_TYPE_ECC);
+        return NULL;
+    }
+
+    return p;
+}
+
+/* return code compliant with OpenSSL :
+ *   1 if success, 0 if error
+ */
+int wolfSSL_EC_POINT_get_affine_coordinates_GFp(const WOLFSSL_EC_GROUP *group,
+                                                const WOLFSSL_EC_POINT *point,
+                                                WOLFSSL_BIGNUM *x,
+                                                WOLFSSL_BIGNUM *y,
+                                                WOLFSSL_BN_CTX *ctx)
+{
+    mp_digit mp;
+    mp_int modulus;
+    (void)ctx;
+
+    WOLFSSL_ENTER("wolfSSL_EC_POINT_get_affine_coordinates_GFp");
+
+    if (group == NULL || point == NULL || point->internal == NULL ||
+        x == NULL || y == NULL || wolfSSL_EC_POINT_is_at_infinity(group, point)) {
+        WOLFSSL_MSG("wolfSSL_EC_POINT_get_affine_coordinates_GFp NULL error");
+        return WOLFSSL_FAILURE;
+    }
+
+    if (setupPoint(point) != WOLFSSL_SUCCESS) {
+        return WOLFSSL_FAILURE;
+    }
+
+    if (!wolfSSL_BN_is_one(point->Z)) {
+        if (mp_init(&modulus) != MP_OKAY) {
+            WOLFSSL_MSG("mp_init failed");
+            return WOLFSSL_FAILURE;
+        }
+        /* Map the Jacobian point back to affine space */
+        if (mp_read_radix(&modulus, ecc_sets[group->curve_idx].prime, MP_RADIX_HEX) != MP_OKAY) {
+            WOLFSSL_MSG("mp_read_radix failed");
+            mp_clear(&modulus);
+            return WOLFSSL_FAILURE;
+        }
+        if (mp_montgomery_setup(&modulus, &mp) != MP_OKAY) {
+            WOLFSSL_MSG("mp_montgomery_setup failed");
+            mp_clear(&modulus);
+            return WOLFSSL_FAILURE;
+        }
+        if (ecc_map((ecc_point*)point->internal, &modulus, mp) != MP_OKAY) {
+            WOLFSSL_MSG("ecc_map failed");
+            mp_clear(&modulus);
+            return WOLFSSL_FAILURE;
+        }
+        if (SetECPointExternal((WOLFSSL_EC_POINT *)point) != WOLFSSL_SUCCESS) {
+            WOLFSSL_MSG("SetECPointExternal failed");
+            mp_clear(&modulus);
+            return WOLFSSL_FAILURE;
+        }
+    }
+
+    BN_copy(x, point->X);
+    BN_copy(y, point->Y);
+    mp_clear(&modulus);
+
+    return WOLFSSL_SUCCESS;
+}
+
+int wolfSSL_EC_POINT_set_affine_coordinates_GFp(const WOLFSSL_EC_GROUP *group,
+                                                WOLFSSL_EC_POINT *point,
+                                                const WOLFSSL_BIGNUM *x,
+                                                const WOLFSSL_BIGNUM *y,
+                                                WOLFSSL_BN_CTX *ctx)
+{
+    (void)ctx;
+    WOLFSSL_ENTER("wolfSSL_EC_POINT_set_affine_coordinates_GFp");
+
+    if (group == NULL || point == NULL || point->internal == NULL ||
+        x == NULL || y == NULL) {
+        WOLFSSL_MSG("wolfSSL_EC_POINT_set_affine_coordinates_GFp NULL error");
+        return WOLFSSL_FAILURE;
+    }
+
+    if (!point->X) {
+        point->X = wolfSSL_BN_new();
+    }
+    if (!point->Y) {
+        point->Y = wolfSSL_BN_new();
+    }
+    if (!point->Z) {
+        point->Z = wolfSSL_BN_new();
+    }
+    if (!point->X || !point->Y || !point->Z) {
+        WOLFSSL_MSG("wolfSSL_BN_new failed");
+        return WOLFSSL_FAILURE;
+    }
+
+    BN_copy(point->X, x);
+    BN_copy(point->Y, y);
+    BN_copy(point->Z, wolfSSL_BN_value_one());
+
+    if (SetECPointInternal((WOLFSSL_EC_POINT *)point) != WOLFSSL_SUCCESS) {
+        WOLFSSL_MSG("SetECPointInternal failed");
+        return WOLFSSL_FAILURE;
+    }
+
+    return WOLFSSL_SUCCESS;
+}
+
+#if !defined(WOLFSSL_ATECC508A) && !defined(HAVE_SELFTEST)
+/* Calculate the value: generator * n + q * m
+ * return code compliant with OpenSSL :
+ *   1 if success, 0 if error
+ */
+int wolfSSL_EC_POINT_mul(const WOLFSSL_EC_GROUP *group, WOLFSSL_EC_POINT *r,
+                         const WOLFSSL_BIGNUM *n, const WOLFSSL_EC_POINT *q,
+                         const WOLFSSL_BIGNUM *m, WOLFSSL_BN_CTX *ctx)
+{
+    mp_int a, prime;
+    int ret = WOLFSSL_FAILURE;
+    ecc_point* result = NULL;
+    ecc_point* tmp = NULL;
+
+    (void)ctx;
+
+    WOLFSSL_ENTER("wolfSSL_EC_POINT_mul");
+
+    if (!group || !r) {
+        WOLFSSL_MSG("wolfSSL_EC_POINT_mul NULL error");
+        return WOLFSSL_FAILURE;
+    }
+
+    if (!(result = wc_ecc_new_point())) {
+        WOLFSSL_MSG("wolfSSL_EC_POINT_new error");
+        return WOLFSSL_FAILURE;
+    }
+
+    /* read the curve prime and a */
+    if (mp_init_multi(&prime, &a, NULL, NULL, NULL, NULL) != MP_OKAY) {
+        WOLFSSL_MSG("mp_init_multi error");
+        goto cleanup;
+    }
+
+    if (q && setupPoint(q) != WOLFSSL_SUCCESS) {
+        WOLFSSL_MSG("setupPoint error");
+        goto cleanup;
+    }
+
+    if (mp_read_radix(&prime, ecc_sets[group->curve_idx].prime, MP_RADIX_HEX)
+            != MP_OKAY) {
+        WOLFSSL_MSG("mp_read_radix prime error");
+        goto cleanup;
+    }
+
+    if (mp_read_radix(&a, ecc_sets[group->curve_idx].Af, MP_RADIX_HEX)
+            != MP_OKAY) {
+        WOLFSSL_MSG("mp_read_radix a error");
+        goto cleanup;
+    }
+
+    if (n) {
+        /* load generator */
+        if (wc_ecc_get_generator(result, group->curve_idx)
+                != MP_OKAY) {
+            WOLFSSL_MSG("wc_ecc_get_generator error");
+            goto cleanup;
+        }
+    }
+
+    if (n && q && m) {
+        /* r = generator * n + q * m */
+#ifdef ECC_SHAMIR
+        if (ecc_mul2add(result, (mp_int*)n->internal,
+                        (ecc_point*)q->internal, (mp_int*)m->internal,
+                        result, &a, &prime, NULL)
+                != MP_OKAY) {
+            WOLFSSL_MSG("ecc_mul2add error");
+            goto cleanup;
+        }
+#else
+        mp_digit mp = 0;
+        if (mp_montgomery_setup(&prime, &mp) != MP_OKAY) {
+            WOLFSSL_MSG("mp_montgomery_setup nqm error");
+            goto cleanup;
+        }
+        if (!(tmp = wc_ecc_new_point())) {
+            WOLFSSL_MSG("wolfSSL_EC_POINT_new nqm error");
+            goto cleanup;
+        }
+        /* r = generator * n */
+        if (wc_ecc_mulmod((mp_int*)n->internal, result, result, &a, &prime, 1)
+                != MP_OKAY) {
+            WOLFSSL_MSG("wc_ecc_mulmod nqm error");
+            goto cleanup;
+        }
+        /* tmp = q * m */
+        if (wc_ecc_mulmod((mp_int*)m->internal, (ecc_point*)q->internal,
+                tmp, &a, &prime, 1) != MP_OKAY) {
+            WOLFSSL_MSG("wc_ecc_mulmod nqm error");
+            goto cleanup;
+        }
+        /* result = result + tmp */
+        if (ecc_projective_add_point(tmp, result, result, &a, &prime, mp)
+                != MP_OKAY) {
+            WOLFSSL_MSG("wc_ecc_mulmod nqm error");
+            goto cleanup;
+        }
+        if (ecc_map(result, &prime, mp) != MP_OKAY) {
+            WOLFSSL_MSG("ecc_map nqm error");
+            goto cleanup;
+        }
+#endif
+    }
+    else if (n) {
+        /* r = generator * n */
+        if (wc_ecc_mulmod((mp_int*)n->internal, result, result, &a, &prime, 1)
+                != MP_OKAY) {
+            WOLFSSL_MSG("wc_ecc_mulmod gn error");
+            goto cleanup;
+        }
+    }
+    else if (q && m) {
+        /* r = q * m */
+        if (wc_ecc_mulmod((mp_int*)m->internal, (ecc_point*)q->internal,
+                           result, &a, &prime, 1) != MP_OKAY) {
+            WOLFSSL_MSG("wc_ecc_mulmod qm error");
+            goto cleanup;
+        }
+    }
+
+    /* copy to destination */
+    if (wc_ecc_copy_point(result, (ecc_point*)r->internal)) {
+        WOLFSSL_MSG("wc_ecc_copy_point error");
+        goto cleanup;
+    }
+    r->inSet = 1;
+    if (SetECPointExternal(r) != WOLFSSL_SUCCESS) {
+        WOLFSSL_MSG("SetECPointExternal error");
+        goto cleanup;
+    }
+
+    ret = WOLFSSL_SUCCESS;
+cleanup:
+    mp_clear(&a);
+    mp_clear(&prime);
+    wc_ecc_del_point(result);
+    wc_ecc_del_point(tmp);
+    return ret;
+}
+#endif /* !defined(WOLFSSL_ATECC508A) && defined(ECC_SHAMIR) &&
+        * !defined(HAVE_SELFTEST) */
+
+void wolfSSL_EC_POINT_clear_free(WOLFSSL_EC_POINT *p)
+{
+    WOLFSSL_ENTER("wolfSSL_EC_POINT_clear_free");
+
+    wolfSSL_EC_POINT_free(p);
+}
+
+/* return code compliant with OpenSSL :
+ *   0 if equal, 1 if not and -1 in case of error
+ */
+int wolfSSL_EC_POINT_cmp(const WOLFSSL_EC_GROUP *group,
+                         const WOLFSSL_EC_POINT *a, const WOLFSSL_EC_POINT *b,
+                         WOLFSSL_BN_CTX *ctx)
+{
+    int ret;
+
+    (void)ctx;
+
+    WOLFSSL_ENTER("wolfSSL_EC_POINT_cmp");
+
+    if (group == NULL || a == NULL || a->internal == NULL || b == NULL ||
+        b->internal == NULL) {
+        WOLFSSL_MSG("wolfSSL_EC_POINT_cmp Bad arguments");
+        return WOLFSSL_FATAL_ERROR;
+    }
+
+    ret = wc_ecc_cmp_point((ecc_point*)a->internal, (ecc_point*)b->internal);
+    if (ret == MP_EQ)
+        return 0;
+    else if (ret == MP_LT || ret == MP_GT)
+        return 1;
+
+    return WOLFSSL_FATAL_ERROR;
+}
+
+int wolfSSL_EC_POINT_copy(WOLFSSL_EC_POINT *dest, const WOLFSSL_EC_POINT *src)
+{
+    WOLFSSL_ENTER("wolfSSL_EC_POINT_copy");
+
+    if (!dest || !src) {
+        return WOLFSSL_FAILURE;
+    }
+
+    if (setupPoint(src) != WOLFSSL_SUCCESS) {
+        return WOLFSSL_FAILURE;
+    }
+
+    if (wc_ecc_copy_point((ecc_point*) dest->internal,
+                          (ecc_point*) src->internal) != MP_OKAY) {
+        return WOLFSSL_FAILURE;
+    }
+
+    dest->inSet = 1;
+
+    if (SetECPointExternal(dest) != WOLFSSL_SUCCESS) {
+        return WOLFSSL_FAILURE;
+    }
+
+    return WOLFSSL_SUCCESS;
+}
+#endif /* HAVE_ECC */
+#endif /* OPENSSL_EXTRA */
+
+#if defined(HAVE_ECC) && (defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL))
+void wolfSSL_EC_POINT_free(WOLFSSL_EC_POINT *p)
+{
+    WOLFSSL_ENTER("wolfSSL_EC_POINT_free");
+
+    if (p != NULL) {
+        if (p->internal != NULL) {
+            wc_ecc_del_point((ecc_point*)p->internal);
+            p->internal = NULL;
+        }
+
+        wolfSSL_BN_free(p->X);
+        wolfSSL_BN_free(p->Y);
+        wolfSSL_BN_free(p->Z);
+        p->X = NULL;
+        p->Y = NULL;
+        p->Z = NULL;
+        p->inSet = p->exSet = 0;
+
+        XFREE(p, NULL, DYNAMIC_TYPE_ECC);
+        /* p = NULL, don't try to access or double free it */
+    }
+}
+#endif
+
+#ifdef OPENSSL_EXTRA
+#ifdef HAVE_ECC
+/* return code compliant with OpenSSL :
+ *   1 if point at infinity, 0 else
+ */
+int wolfSSL_EC_POINT_is_at_infinity(const WOLFSSL_EC_GROUP *group,
+                                    const WOLFSSL_EC_POINT *point)
+{
+    int ret;
+
+    WOLFSSL_ENTER("wolfSSL_EC_POINT_is_at_infinity");
+
+    if (group == NULL || point == NULL || point->internal == NULL) {
+        WOLFSSL_MSG("wolfSSL_EC_POINT_is_at_infinity NULL error");
+        return WOLFSSL_FAILURE;
+    }
+
+    if (setupPoint(point) != WOLFSSL_SUCCESS) {
+        return WOLFSSL_FAILURE;
+    }
+
+    ret = wc_ecc_point_is_at_infinity((ecc_point*)point->internal);
+    if (ret < 0) {
+        WOLFSSL_MSG("ecc_point_is_at_infinity failure");
+        return WOLFSSL_FAILURE;
+    }
+
+    return ret;
+}
+
+/* End EC_POINT */
+
+size_t wolfSSL_EC_get_builtin_curves(WOLFSSL_EC_BUILTIN_CURVE *r, size_t nitems)
+{
+    size_t i, min_nitems;
+#ifdef HAVE_SELFTEST
+    size_t ecc_sets_count;
+    for (i = 0; ecc_sets[i].size != 0 && ecc_sets[i].name != NULL; i++);
+    ecc_sets_count = i;
+#endif
+
+    if (r == NULL || nitems == 0)
+        return ecc_sets_count;
+
+    min_nitems = nitems < ecc_sets_count ? nitems : ecc_sets_count;
+
+    for (i = 0; i < min_nitems; i++) {
+        r[i].nid = EccEnumToNID(ecc_sets[i].id);
+        r[i].comment = wolfSSL_OBJ_nid2sn(r[i].nid);
+    }
+
+    return ecc_sets_count;
+}
+
+/* Start ECDSA_SIG */
+void wolfSSL_ECDSA_SIG_free(WOLFSSL_ECDSA_SIG *sig)
+{
+    WOLFSSL_ENTER("wolfSSL_ECDSA_SIG_free");
+
+    if (sig) {
+        wolfSSL_BN_free(sig->r);
+        wolfSSL_BN_free(sig->s);
+
+        XFREE(sig, NULL, DYNAMIC_TYPE_ECC);
+    }
+}
+
+WOLFSSL_ECDSA_SIG *wolfSSL_ECDSA_SIG_new(void)
+{
+    WOLFSSL_ECDSA_SIG *sig;
+
+    WOLFSSL_ENTER("wolfSSL_ECDSA_SIG_new");
+
+    sig = (WOLFSSL_ECDSA_SIG*) XMALLOC(sizeof(WOLFSSL_ECDSA_SIG), NULL,
+                                       DYNAMIC_TYPE_ECC);
+    if (sig == NULL) {
+        WOLFSSL_MSG("wolfSSL_ECDSA_SIG_new malloc ECDSA signature failure");
+        return NULL;
+    }
+
+    sig->s = NULL;
+    sig->r = wolfSSL_BN_new();
+    if (sig->r == NULL) {
+        WOLFSSL_MSG("wolfSSL_ECDSA_SIG_new malloc ECDSA r failure");
+        wolfSSL_ECDSA_SIG_free(sig);
+        return NULL;
+    }
+
+    sig->s = wolfSSL_BN_new();
+    if (sig->s == NULL) {
+        WOLFSSL_MSG("wolfSSL_ECDSA_SIG_new malloc ECDSA s failure");
+        wolfSSL_ECDSA_SIG_free(sig);
+        return NULL;
+    }
+
+    return sig;
+}
+
+/* return signature structure on success, NULL otherwise */
+WOLFSSL_ECDSA_SIG *wolfSSL_ECDSA_do_sign(const unsigned char *d, int dlen,
+                                         WOLFSSL_EC_KEY *key)
+{
+    WOLFSSL_ECDSA_SIG *sig = NULL;
+    int     initTmpRng = 0;
+    WC_RNG* rng = NULL;
+#ifdef WOLFSSL_SMALL_STACK
+    WC_RNG* tmpRNG = NULL;
+#else
+    WC_RNG  tmpRNG[1];
+#endif
+
+    WOLFSSL_ENTER("wolfSSL_ECDSA_do_sign");
+
+    if (d == NULL || key == NULL || key->internal == NULL) {
+        WOLFSSL_MSG("wolfSSL_ECDSA_do_sign Bad arguments");
+        return NULL;
+    }
+
+    /* set internal key if not done */
+    if (key->inSet == 0)
+    {
+        WOLFSSL_MSG("wolfSSL_ECDSA_do_sign No EC key internal set, do it");
+
+        if (SetECKeyInternal(key) != WOLFSSL_SUCCESS) {
+            WOLFSSL_MSG("wolfSSL_ECDSA_do_sign SetECKeyInternal failed");
+            return NULL;
+        }
+    }
+
+#ifdef WOLFSSL_SMALL_STACK
+    tmpRNG = (WC_RNG*)XMALLOC(sizeof(WC_RNG), NULL, DYNAMIC_TYPE_RNG);
+    if (tmpRNG == NULL)
+        return NULL;
+#endif
+
+    if (wc_InitRng(tmpRNG) == 0) {
+        rng = tmpRNG;
+        initTmpRng = 1;
+    }
+    else {
+        WOLFSSL_MSG("wolfSSL_ECDSA_do_sign Bad RNG Init, trying global");
+        if (initGlobalRNG == 0)
+            WOLFSSL_MSG("wolfSSL_ECDSA_do_sign Global RNG no Init");
+        else
+            rng = &globalRNG;
+    }
+
+    if (rng) {
+        mp_int sig_r, sig_s;
+
+        if (mp_init_multi(&sig_r, &sig_s, NULL, NULL, NULL, NULL) == MP_OKAY) {
+            if (wc_ecc_sign_hash_ex(d, dlen, rng, (ecc_key*)key->internal,
+                                    &sig_r, &sig_s) != MP_OKAY) {
+                WOLFSSL_MSG("wc_ecc_sign_hash_ex failed");
+            }
+            else {
+                /* put signature blob in ECDSA structure */
+                sig = wolfSSL_ECDSA_SIG_new();
+                if (sig == NULL)
+                    WOLFSSL_MSG("wolfSSL_ECDSA_SIG_new failed");
+                else if (SetIndividualExternal(&(sig->r), &sig_r)!=WOLFSSL_SUCCESS){
+                    WOLFSSL_MSG("ecdsa r key error");
+                    wolfSSL_ECDSA_SIG_free(sig);
+                    sig = NULL;
+                }
+                else if (SetIndividualExternal(&(sig->s), &sig_s)!=WOLFSSL_SUCCESS){
+                    WOLFSSL_MSG("ecdsa s key error");
+                    wolfSSL_ECDSA_SIG_free(sig);
+                    sig = NULL;
+                }
+
+            }
+            mp_free(&sig_r);
+            mp_free(&sig_s);
+        }
+    }
+
+    if (initTmpRng)
+        wc_FreeRng(tmpRNG);
+#ifdef WOLFSSL_SMALL_STACK
+    XFREE(tmpRNG, NULL, DYNAMIC_TYPE_RNG);
+#endif
+
+    return sig;
+}
+
+/* return code compliant with OpenSSL :
+ *   1 for a valid signature, 0 for an invalid signature and -1 on error
+ */
+int wolfSSL_ECDSA_do_verify(const unsigned char *d, int dlen,
+                            const WOLFSSL_ECDSA_SIG *sig, WOLFSSL_EC_KEY *key)
+{
+    int check_sign = 0;
+
+    WOLFSSL_ENTER("wolfSSL_ECDSA_do_verify");
+
+    if (d == NULL || sig == NULL || key == NULL || key->internal == NULL) {
+        WOLFSSL_MSG("wolfSSL_ECDSA_do_verify Bad arguments");
+        return WOLFSSL_FATAL_ERROR;
+    }
+
+    /* set internal key if not done */
+    if (key->inSet == 0)
+    {
+        WOLFSSL_MSG("No EC key internal set, do it");
+
+        if (SetECKeyInternal(key) != WOLFSSL_SUCCESS) {
+            WOLFSSL_MSG("SetECKeyInternal failed");
+            return WOLFSSL_FATAL_ERROR;
+        }
+    }
+
+    if (wc_ecc_verify_hash_ex((mp_int*)sig->r->internal,
+                              (mp_int*)sig->s->internal, d, dlen, &check_sign,
+                              (ecc_key *)key->internal) != MP_OKAY) {
+        WOLFSSL_MSG("wc_ecc_verify_hash failed");
+        return WOLFSSL_FATAL_ERROR;
+    }
+    else if (check_sign == 0) {
+        WOLFSSL_MSG("wc_ecc_verify_hash incorrect signature detected");
+        return WOLFSSL_FAILURE;
+    }
+
+    return WOLFSSL_SUCCESS;
+}
+
+WOLFSSL_ECDSA_SIG *wolfSSL_d2i_ECDSA_SIG(WOLFSSL_ECDSA_SIG **sig,
+                                         const unsigned char **pp, long len)
+{
+    WOLFSSL_ECDSA_SIG *s = NULL;
+
+    if (pp == NULL)
+        return NULL;
+
+    if (sig != NULL)
+        s = *sig;
+    if (s == NULL) {
+        s = wolfSSL_ECDSA_SIG_new();
+        if (s == NULL)
+            return NULL;
+    }
+
+    /* DecodeECC_DSA_Sig calls mp_init, so free these */
+    mp_free((mp_int*)s->r->internal);
+    mp_free((mp_int*)s->s->internal);
+
+    if (DecodeECC_DSA_Sig(*pp, (word32)len, (mp_int*)s->r->internal,
+                                          (mp_int*)s->s->internal) != MP_OKAY) {
+        if (sig == NULL || *sig == NULL)
+            wolfSSL_ECDSA_SIG_free(s);
+        return NULL;
+    }
+
+    *pp += len;
+    if (sig != NULL)
+        *sig = s;
+    return s;
+}
+
+int wolfSSL_i2d_ECDSA_SIG(const WOLFSSL_ECDSA_SIG *sig, unsigned char **pp)
+{
+    word32 len;
+
+    if (sig == NULL)
+        return 0;
+
+    /* ASN.1: SEQ + INT + INT
+     *   ASN.1 Integer must be a positive value - prepend zero if number has
+     *   top bit set.
+     */
+    len = 2 + mp_leading_bit((mp_int*)sig->r->internal) +
+              mp_unsigned_bin_size((mp_int*)sig->r->internal) +
+          2 + mp_leading_bit((mp_int*)sig->s->internal) +
+              mp_unsigned_bin_size((mp_int*)sig->s->internal);
+    /* Two bytes required for length if ASN.1 SEQ data greater than 127 bytes
+     * and less than 256 bytes.
+     */
+    len = 1 + ((len > 127) ? 2 : 1) + len;
+    if (pp != NULL && *pp != NULL) {
+        if (StoreECC_DSA_Sig(*pp, &len, (mp_int*)sig->r->internal,
+                                        (mp_int*)sig->s->internal) != MP_OKAY) {
+            len = 0;
+        }
+        else
+            *pp += len;
+    }
+
+    return (int)len;
+}
+/* End ECDSA_SIG */
+
+/* Start ECDH */
+/* return code compliant with OpenSSL :
+ *   length of computed key if success, -1 if error
+ */
+int wolfSSL_ECDH_compute_key(void *out, size_t outlen,
+                             const WOLFSSL_EC_POINT *pub_key,
+                             WOLFSSL_EC_KEY *ecdh,
+                             void *(*KDF) (const void *in, size_t inlen,
+                                           void *out, size_t *outlen))
+{
+    word32 len;
+    (void)KDF;
+
+    (void)KDF;
+
+    WOLFSSL_ENTER("wolfSSL_ECDH_compute_key");
+
+    if (out == NULL || pub_key == NULL || pub_key->internal == NULL ||
+        ecdh == NULL || ecdh->internal == NULL) {
+        WOLFSSL_MSG("Bad function arguments");
+        return WOLFSSL_FATAL_ERROR;
+    }
+
+    /* set internal key if not done */
+    if (ecdh->inSet == 0)
+    {
+        WOLFSSL_MSG("No EC key internal set, do it");
+
+        if (SetECKeyInternal(ecdh) != WOLFSSL_SUCCESS) {
+            WOLFSSL_MSG("SetECKeyInternal failed");
+            return WOLFSSL_FATAL_ERROR;
+        }
+    }
+
+    len = (word32)outlen;
+
+    if (wc_ecc_shared_secret_ssh((ecc_key*)ecdh->internal,
+                                 (ecc_point*)pub_key->internal,
+                                 (byte *)out, &len) != MP_OKAY) {
+        WOLFSSL_MSG("wc_ecc_shared_secret failed");
+        return WOLFSSL_FATAL_ERROR;
+    }
+
+    return len;
+}
+/* End ECDH */
+
+#if !defined(NO_FILESYSTEM)
+/* return code compliant with OpenSSL :
+ *   1 if success, 0 if error
+ */
+#ifndef NO_WOLFSSL_STUB
+int wolfSSL_PEM_write_EC_PUBKEY(XFILE fp, WOLFSSL_EC_KEY *x)
+{
+    (void)fp;
+    (void)x;
+    WOLFSSL_STUB("PEM_write_EC_PUBKEY");
+    WOLFSSL_MSG("wolfSSL_PEM_write_EC_PUBKEY not implemented");
+
+    return WOLFSSL_FAILURE;
+}
+#endif
+
+/* Uses the same format of input as wolfSSL_PEM_read_bio_PrivateKey but expects
+ * the results to be an EC key.
+ *
+ * bio  structure to read EC private key from
+ * ec   if not null is then set to the result
+ * cb   password callback for reading PEM
+ * pass password string
+ *
+ * returns a pointer to a new WOLFSSL_EC_KEY struct on success and NULL on fail
+ */
+
+WOLFSSL_EC_KEY* wolfSSL_PEM_read_bio_EC_PUBKEY(WOLFSSL_BIO* bio,
+                                               WOLFSSL_EC_KEY** ec,
+                                               pem_password_cb* cb, void *pass)
+{
+    WOLFSSL_EVP_PKEY* pkey;
+    WOLFSSL_EC_KEY* local;
+
+    WOLFSSL_ENTER("wolfSSL_PEM_read_bio_EC_PUBKEY");
+
+    pkey = wolfSSL_PEM_read_bio_PUBKEY(bio, NULL, cb, pass);
+    if (pkey == NULL) {
+        return NULL;
+    }
+
+    /* Since the WOLFSSL_EC_KEY structure is being taken from WOLFSSL_EVP_PKEY the
+     * flag indicating that the WOLFSSL_EC_KEY structure is owned should be FALSE
+     * to avoid having it free'd */
+    pkey->ownEcc = 0;
+    local = pkey->ecc;
+    if (ec != NULL) {
+        *ec = local;
+    }
+
+    wolfSSL_EVP_PKEY_free(pkey);
+    return local;
+}
+
+/* Reads a private EC key from a WOLFSSL_BIO into a WOLFSSL_EC_KEY.
+ * Returns WOLFSSL_SUCCESS or WOLFSSL_FAILURE
+ */
+WOLFSSL_EC_KEY* wolfSSL_PEM_read_bio_ECPrivateKey(WOLFSSL_BIO* bio,
+                                                  WOLFSSL_EC_KEY** ec,
+                                                  pem_password_cb* cb,
+                                                  void *pass)
+{
+    WOLFSSL_EVP_PKEY* pkey;
+    WOLFSSL_EC_KEY* local;
+
+    WOLFSSL_ENTER("wolfSSL_PEM_read_bio_ECPrivateKey");
+
+    pkey = wolfSSL_PEM_read_bio_PrivateKey(bio, NULL, cb, pass);
+    if (pkey == NULL) {
+        return NULL;
+    }
+
+    /* Since the WOLFSSL_EC_KEY structure is being taken from WOLFSSL_EVP_PKEY the
+     * flag indicating that the WOLFSSL_EC_KEY structure is owned should be FALSE
+     * to avoid having it free'd */
+    pkey->ownEcc = 0;
+    local = pkey->ecc;
+    if (ec != NULL) {
+        *ec = local;
+    }
+
+    wolfSSL_EVP_PKEY_free(pkey);
+    return local;
+}
+#endif /* NO_FILESYSTEM */
+
+#if defined(WOLFSSL_KEY_GEN)
+/* Takes a public WOLFSSL_EC_KEY and writes it out to WOLFSSL_BIO
+ * Returns WOLFSSL_SUCCESS or WOLFSSL_FAILURE
+ */
+int wolfSSL_PEM_write_bio_EC_PUBKEY(WOLFSSL_BIO* bio, WOLFSSL_EC_KEY* ec)
+{
+    int ret = 0, der_max_len = 0, derSz = 0;
+    byte *derBuf;
+    WOLFSSL_EVP_PKEY* pkey;
+
+    WOLFSSL_ENTER("wolfSSL_PEM_write_bio_EC_PUBKEY");
+
+    if (bio == NULL || ec == NULL) {
+        WOLFSSL_MSG("Bad Function Arguments");
+        return WOLFSSL_FAILURE;
+    }
+
+    /* Initialize pkey structure */
+    pkey = wolfSSL_EVP_PKEY_new_ex(bio->heap);
+    if (pkey == NULL) {
+        WOLFSSL_MSG("wolfSSL_EVP_PKEY_new_ex failed");
+        return WOLFSSL_FAILURE;
+    }
+
+    /* Set pkey info */
+    pkey->ecc    = ec;
+    pkey->ownEcc = 0; /* pkey does not own ECC */
+    pkey->type = EVP_PKEY_EC;
+
+    /* 4 > size of pub, priv + ASN.1 additional information */
+    der_max_len = 4 * wc_ecc_size((ecc_key*)ec->internal) + AES_BLOCK_SIZE;
+
+    derBuf = (byte*)XMALLOC(der_max_len, bio->heap, DYNAMIC_TYPE_TMP_BUFFER);
+    if (derBuf == NULL) {
+        WOLFSSL_MSG("Malloc failed");
+        wolfSSL_EVP_PKEY_free(pkey);
+        return WOLFSSL_FAILURE;
+    }
+
+    /* convert key to der format */
+    derSz = wc_EccPublicKeyToDer((ecc_key*)ec->internal, derBuf, der_max_len, 1);
+    if (derSz < 0) {
+        WOLFSSL_MSG("wc_EccPublicKeyToDer failed");
+        XFREE(derBuf, NULL, DYNAMIC_TYPE_DER);
+        wolfSSL_EVP_PKEY_free(pkey);
+        return WOLFSSL_FAILURE;
+    }
+
+    pkey->pkey.ptr = (char*)XMALLOC(derSz, bio->heap, DYNAMIC_TYPE_TMP_BUFFER);
+    if (pkey->pkey.ptr == NULL) {
+        WOLFSSL_MSG("key malloc failed");
+        XFREE(derBuf, bio->heap, DYNAMIC_TYPE_TMP_BUFFER);
+        wolfSSL_EVP_PKEY_free(pkey);
+        return WOLFSSL_FAILURE;
+    }
+
+    /* add der info to the evp key */
+    pkey->pkey_sz = derSz;
+    XMEMCPY(pkey->pkey.ptr, derBuf, derSz);
+    XFREE(derBuf, bio->heap, DYNAMIC_TYPE_TMP_BUFFER);
+
+    if((ret = wolfSSL_PEM_write_bio_PUBKEY(bio, pkey)) != WOLFSSL_SUCCESS){
+        WOLFSSL_MSG("wolfSSL_PEM_write_bio_PUBKEY failed");
+    }
+    wolfSSL_EVP_PKEY_free(pkey);
+
+    return ret;
+}
+
+/* return code compliant with OpenSSL :
+ *   1 if success, 0 if error
+ */
+int wolfSSL_PEM_write_bio_ECPrivateKey(WOLFSSL_BIO* bio, WOLFSSL_EC_KEY* ec,
+                                       const EVP_CIPHER* cipher,
+                                       unsigned char* passwd, int len,
+                                       pem_password_cb* cb, void* arg)
+{
+    int ret = 0, der_max_len = 0, derSz = 0;
+    byte *derBuf;
+    WOLFSSL_EVP_PKEY* pkey;
+    WOLFSSL_ENTER("WOLFSSL_PEM_write_bio_ECPrivateKey");
+
+    if (bio == NULL || ec == NULL) {
+        WOLFSSL_MSG("Bad Function Arguments");
+        return WOLFSSL_FAILURE;
+    }
+
+    /* Initialize pkey structure */
+    pkey = wolfSSL_EVP_PKEY_new_ex(bio->heap);
+    if (pkey == NULL) {
+        WOLFSSL_MSG("wolfSSL_EVP_PKEY_new_ex failed");
+        return WOLFSSL_FAILURE;
+    }
+
+    /* Set pkey info */
+    pkey->ecc    = ec;
+    pkey->ownEcc = 0; /* pkey does not own ECC */
+    pkey->type = EVP_PKEY_EC;
+
+    /* 4 > size of pub, priv + ASN.1 additional informations
+     */
+    der_max_len = 4 * wc_ecc_size((ecc_key*)ec->internal) + AES_BLOCK_SIZE;
+
+    derBuf = (byte*)XMALLOC(der_max_len, bio->heap, DYNAMIC_TYPE_TMP_BUFFER);
+    if (derBuf == NULL) {
+        WOLFSSL_MSG("Malloc failed");
+        wolfSSL_EVP_PKEY_free(pkey);
+        return WOLFSSL_FAILURE;
+    }
+
+    /* convert key to der format */
+    derSz = wc_EccKeyToDer((ecc_key*)ec->internal, derBuf, der_max_len);
+    if (derSz < 0) {
+        WOLFSSL_MSG("wc_EccKeyToDer failed");
+        XFREE(derBuf, NULL, DYNAMIC_TYPE_DER);
+        wolfSSL_EVP_PKEY_free(pkey);
+        return WOLFSSL_FAILURE;
+    }
+
+    pkey->pkey.ptr = (char*)XMALLOC(derSz, bio->heap, DYNAMIC_TYPE_TMP_BUFFER);
+    if (pkey->pkey.ptr == NULL) {
+        WOLFSSL_MSG("key malloc failed");
+        XFREE(derBuf, bio->heap, DYNAMIC_TYPE_TMP_BUFFER);
+        wolfSSL_EVP_PKEY_free(pkey);
+        return WOLFSSL_FAILURE;
+    }
+
+    /* add der info to the evp key */
+    pkey->pkey_sz = derSz;
+    XMEMCPY(pkey->pkey.ptr, derBuf, derSz);
+    XFREE(derBuf, bio->heap, DYNAMIC_TYPE_TMP_BUFFER);
+
+    ret = wolfSSL_PEM_write_bio_PrivateKey(bio, pkey, cipher, passwd, len,
+                                        cb, arg);
+    wolfSSL_EVP_PKEY_free(pkey);
+
+    return ret;
+}
+
+/* return code compliant with OpenSSL :
+ *   1 if success, 0 if error
+ */
+int wolfSSL_PEM_write_mem_ECPrivateKey(WOLFSSL_EC_KEY* ecc,
+                                       const EVP_CIPHER* cipher,
+                                       unsigned char* passwd, int passwdSz,
+                                       unsigned char **pem, int *plen)
+{
+#if defined(WOLFSSL_PEM_TO_DER) || defined(WOLFSSL_DER_TO_PEM)
+    byte *derBuf, *tmp, *cipherInfo = NULL;
+    int  der_max_len = 0, derSz = 0;
+    const int type = ECC_PRIVATEKEY_TYPE;
+    const char* header = NULL;
+    const char* footer = NULL;
+
+    WOLFSSL_MSG("wolfSSL_PEM_write_mem_ECPrivateKey");
+
+    if (pem == NULL || plen == NULL || ecc == NULL || ecc->internal == NULL) {
+        WOLFSSL_MSG("Bad function arguments");
+        return WOLFSSL_FAILURE;
+    }
+
+    if (wc_PemGetHeaderFooter(type, &header, &footer) != 0)
+        return WOLFSSL_FAILURE;
+
+    if (ecc->inSet == 0) {
+        WOLFSSL_MSG("No ECC internal set, do it");
+
+        if (SetECKeyInternal(ecc) != WOLFSSL_SUCCESS) {
+            WOLFSSL_MSG("SetECKeyInternal failed");
+            return WOLFSSL_FAILURE;
+        }
+    }
+
+    /* 4 > size of pub, priv + ASN.1 additional information */
+    der_max_len = 4 * wc_ecc_size((ecc_key*)ecc->internal) + AES_BLOCK_SIZE;
+
+    derBuf = (byte*)XMALLOC(der_max_len, NULL, DYNAMIC_TYPE_DER);
+    if (derBuf == NULL) {
+        WOLFSSL_MSG("malloc failed");
+        return WOLFSSL_FAILURE;
+    }
+
+    /* Key to DER */
+    derSz = wc_EccKeyToDer((ecc_key*)ecc->internal, derBuf, der_max_len);
+    if (derSz < 0) {
+        WOLFSSL_MSG("wc_EccKeyToDer failed");
+        XFREE(derBuf, NULL, DYNAMIC_TYPE_DER);
+        return WOLFSSL_FAILURE;
+    }
+
+    /* encrypt DER buffer if required */
+    if (passwd != NULL && passwdSz > 0 && cipher != NULL) {
+        int ret;
+
+        ret = EncryptDerKey(derBuf, &derSz, cipher,
+                            passwd, passwdSz, &cipherInfo);
+        if (ret != WOLFSSL_SUCCESS) {
+            WOLFSSL_MSG("EncryptDerKey failed");
+            XFREE(derBuf, NULL, DYNAMIC_TYPE_DER);
+            return ret;
+        }
+
+        /* tmp buffer with a max size */
+        *plen = (derSz * 2) + (int)XSTRLEN(header) + 1 +
+            (int)XSTRLEN(footer) + 1 + HEADER_ENCRYPTED_KEY_SIZE;
+    }
+    else { /* tmp buffer with a max size */
+        *plen = (derSz * 2) + (int)XSTRLEN(header) + 1 +
+            (int)XSTRLEN(footer) + 1;
+    }
+
+    tmp = (byte*)XMALLOC(*plen, NULL, DYNAMIC_TYPE_PEM);
+    if (tmp == NULL) {
+        WOLFSSL_MSG("malloc failed");
+        XFREE(derBuf, NULL, DYNAMIC_TYPE_DER);
+        if (cipherInfo != NULL)
+            XFREE(cipherInfo, NULL, DYNAMIC_TYPE_STRING);
+        return WOLFSSL_FAILURE;
+    }
+
+    /* DER to PEM */
+    *plen = wc_DerToPemEx(derBuf, derSz, tmp, *plen, cipherInfo, type);
+    if (*plen <= 0) {
+        WOLFSSL_MSG("wc_DerToPemEx failed");
+        XFREE(derBuf, NULL, DYNAMIC_TYPE_DER);
+        XFREE(tmp, NULL, DYNAMIC_TYPE_PEM);
+        if (cipherInfo != NULL)
+            XFREE(cipherInfo, NULL, DYNAMIC_TYPE_STRING);
+        return WOLFSSL_FAILURE;
+    }
+    XFREE(derBuf, NULL, DYNAMIC_TYPE_DER);
+    if (cipherInfo != NULL)
+        XFREE(cipherInfo, NULL, DYNAMIC_TYPE_STRING);
+
+    *pem = (byte*)XMALLOC((*plen)+1, NULL, DYNAMIC_TYPE_KEY);
+    if (*pem == NULL) {
+        WOLFSSL_MSG("malloc failed");
+        XFREE(tmp, NULL, DYNAMIC_TYPE_PEM);
+        return WOLFSSL_FAILURE;
+    }
+    XMEMSET(*pem, 0, (*plen)+1);
+
+    if (XMEMCPY(*pem, tmp, *plen) == NULL) {
+        WOLFSSL_MSG("XMEMCPY failed");
+        XFREE(pem, NULL, DYNAMIC_TYPE_KEY);
+        XFREE(tmp, NULL, DYNAMIC_TYPE_PEM);
+        return WOLFSSL_FAILURE;
+    }
+    XFREE(tmp, NULL, DYNAMIC_TYPE_PEM);
+
+    return WOLFSSL_SUCCESS;
+#else
+    (void)ecc;
+    (void)cipher;
+    (void)passwd;
+    (void)passwdSz;
+    (void)pem;
+    (void)plen;
+    return WOLFSSL_FAILURE;
+#endif /* WOLFSSL_PEM_TO_DER || WOLFSSL_DER_TO_PEM */
+}
+
+#ifndef NO_FILESYSTEM
+/* return code compliant with OpenSSL :
+ *   1 if success, 0 if error
+ */
+int wolfSSL_PEM_write_ECPrivateKey(XFILE fp, WOLFSSL_EC_KEY *ecc,
+                                   const EVP_CIPHER *enc,
+                                   unsigned char *kstr, int klen,
+                                   pem_password_cb *cb, void *u)
+{
+    byte *pem;
+    int  plen, ret;
+
+    (void)cb;
+    (void)u;
+
+    WOLFSSL_MSG("wolfSSL_PEM_write_ECPrivateKey");
+
+    if (fp == XBADFILE || ecc == NULL || ecc->internal == NULL) {
+        WOLFSSL_MSG("Bad function arguments");
+        return WOLFSSL_FAILURE;
+    }
+
+    ret = wolfSSL_PEM_write_mem_ECPrivateKey(ecc, enc, kstr, klen, &pem, &plen);
+    if (ret != WOLFSSL_SUCCESS) {
+        WOLFSSL_MSG("wolfSSL_PEM_write_mem_ECPrivateKey failed");
+        return WOLFSSL_FAILURE;
+    }
+
+    ret = (int)XFWRITE(pem, plen, 1, fp);
+    if (ret != 1) {
+        WOLFSSL_MSG("ECC private key file write failed");
+        return WOLFSSL_FAILURE;
+    }
+
+    XFREE(pem, NULL, DYNAMIC_TYPE_KEY);
+    return WOLFSSL_SUCCESS;
+}
+
+#endif /* NO_FILESYSTEM */
+#endif /* defined(WOLFSSL_KEY_GEN) */
+
+#endif /* HAVE_ECC */
+
+
+#ifndef NO_DSA
+
+#if defined(WOLFSSL_KEY_GEN)
+
+/* Takes a DSA Privatekey and writes it out to a WOLFSSL_BIO
+ * Returns WOLFSSL_SUCCESS or WOLFSSL_FAILURE
+ */
+int wolfSSL_PEM_write_bio_DSAPrivateKey(WOLFSSL_BIO* bio, WOLFSSL_DSA* dsa,
+                                       const EVP_CIPHER* cipher,
+                                       unsigned char* passwd, int len,
+                                       pem_password_cb* cb, void* arg)
+{
+    int ret = 0, der_max_len = 0, derSz = 0;
+    byte *derBuf;
+    WOLFSSL_EVP_PKEY* pkey;
+
+    WOLFSSL_ENTER("wolfSSL_PEM_write_bio_DSAPrivateKey");
+
+    if (bio == NULL || dsa == NULL) {
+        WOLFSSL_MSG("Bad Function Arguments");
+        return WOLFSSL_FAILURE;
+    }
+
+    pkey = wolfSSL_EVP_PKEY_new_ex(bio->heap);
+    if (pkey == NULL) {
+        WOLFSSL_MSG("wolfSSL_EVP_PKEY_new_ex failed");
+        return WOLFSSL_FAILURE;
+    }
+
+    pkey->type   = EVP_PKEY_DSA;
+    pkey->dsa    = dsa;
+    pkey->ownDsa = 0;
+
+    /* 4 > size of pub, priv, p, q, g + ASN.1 additional information */
+    der_max_len = 4 * wolfSSL_BN_num_bytes(dsa->g) + AES_BLOCK_SIZE;
+
+    derBuf = (byte*)XMALLOC(der_max_len, bio->heap, DYNAMIC_TYPE_TMP_BUFFER);
+    if (derBuf == NULL) {
+        WOLFSSL_MSG("Malloc failed");
+        wolfSSL_EVP_PKEY_free(pkey);
+        return WOLFSSL_FAILURE;
+    }
+
+    /* convert key to der format */
+    derSz = wc_DsaKeyToDer((DsaKey*)dsa->internal, derBuf, der_max_len);
+    if (derSz < 0) {
+        WOLFSSL_MSG("wc_DsaKeyToDer failed");
+        XFREE(derBuf, NULL, DYNAMIC_TYPE_DER);
+        wolfSSL_EVP_PKEY_free(pkey);
+        return WOLFSSL_FAILURE;
+    }
+
+    pkey->pkey.ptr = (char*)XMALLOC(derSz, bio->heap, DYNAMIC_TYPE_TMP_BUFFER);
+    if (pkey->pkey.ptr == NULL) {
+        WOLFSSL_MSG("key malloc failed");
+        XFREE(derBuf, bio->heap, DYNAMIC_TYPE_TMP_BUFFER);
+        wolfSSL_EVP_PKEY_free(pkey);
+        return WOLFSSL_FAILURE;
+    }
+
+    /* add der info to the evp key */
+    pkey->pkey_sz = derSz;
+    XMEMCPY(pkey->pkey.ptr, derBuf, derSz);
+    XFREE(derBuf, bio->heap, DYNAMIC_TYPE_TMP_BUFFER);
+
+    ret = wolfSSL_PEM_write_bio_PrivateKey(bio, pkey, cipher, passwd, len,
+                                        cb, arg);
+    wolfSSL_EVP_PKEY_free(pkey);
+
+    return ret;
+}
+
+#ifndef HAVE_SELFTEST
+/* Takes a DSA public key and writes it out to a WOLFSSL_BIO
+ * Returns WOLFSSL_SUCCESS or WOLFSSL_FAILURE
+ */
+int wolfSSL_PEM_write_bio_DSA_PUBKEY(WOLFSSL_BIO* bio, WOLFSSL_DSA* dsa)
+{
+    int ret = 0, derMax = 0, derSz = 0;
+    byte *derBuf;
+    WOLFSSL_EVP_PKEY* pkey;
+
+    WOLFSSL_ENTER("wolfSSL_PEM_write_bio_DSA_PUBKEY");
+
+    if (bio == NULL || dsa == NULL) {
+        WOLFSSL_MSG("Bad function arguements");
+        return WOLFSSL_FAILURE;
+    }
+
+    pkey = wolfSSL_EVP_PKEY_new_ex(bio->heap);
+    if (pkey == NULL) {
+        WOLFSSL_MSG("wolfSSL_EVP_PKEY_new_ex failed");
+        return WOLFSSL_FAILURE;
+    }
+
+    pkey->type   = EVP_PKEY_DSA;
+    pkey->dsa    = dsa;
+    pkey->ownDsa = 0;
+
+    /* 4 > size of pub, priv, p, q, g + ASN.1 additional information */
+    derMax = 4 * wolfSSL_BN_num_bytes(dsa->g) + AES_BLOCK_SIZE;
+
+    derBuf = (byte*)XMALLOC(derMax, bio->heap, DYNAMIC_TYPE_DER);
+    if (derBuf == NULL) {
+        WOLFSSL_MSG("malloc failed");
+        wolfSSL_EVP_PKEY_free(pkey);
+        return WOLFSSL_FAILURE;
+    }
+
+    /* Key to DER */
+    derSz = wc_DsaKeyToPublicDer((DsaKey*)dsa->internal, derBuf, derMax);
+    if (derSz < 0) {
+        WOLFSSL_MSG("wc_DsaKeyToDer failed");
+        XFREE(derBuf, bio->heap, DYNAMIC_TYPE_DER);
+        wolfSSL_EVP_PKEY_free(pkey);
+        return WOLFSSL_FAILURE;
+    }
+
+    pkey->pkey.ptr = (char*)XMALLOC(derSz, bio->heap, DYNAMIC_TYPE_DER);
+
+    if (pkey->pkey.ptr == NULL) {
+        WOLFSSL_MSG("key malloc failed");
+        XFREE(derBuf, bio->heap, DYNAMIC_TYPE_DER);
+        wolfSSL_EVP_PKEY_free(pkey);
+        return WOLFSSL_FAILURE;
+    }
+    pkey->pkey_sz = derSz;
+    XMEMSET(pkey->pkey.ptr, 0, derSz);
+
+    if (XMEMCPY(pkey->pkey.ptr, derBuf, derSz) == NULL) {
+        WOLFSSL_MSG("XMEMCPY failed");
+        XFREE(derBuf, bio->heap, DYNAMIC_TYPE_DER);
+        XFREE(pkey->pkey.ptr, bio->heap, DYNAMIC_TYPE_DER);
+        wolfSSL_EVP_PKEY_free(pkey);
+        return WOLFSSL_FAILURE;
+    }
+    XFREE(derBuf, bio->heap, DYNAMIC_TYPE_DER);
+    ret = wolfSSL_PEM_write_bio_PUBKEY(bio, pkey);
+    wolfSSL_EVP_PKEY_free(pkey);
+    return ret;
+}
+#endif /* HAVE_SELFTEST */
+
+/* return code compliant with OpenSSL :
+ *   1 if success, 0 if error
+ */
+int wolfSSL_PEM_write_mem_DSAPrivateKey(WOLFSSL_DSA* dsa,
+                                        const EVP_CIPHER* cipher,
+                                        unsigned char* passwd, int passwdSz,
+                                        unsigned char **pem, int *plen)
+{
+#if defined(WOLFSSL_PEM_TO_DER) || defined(WOLFSSL_DER_TO_PEM)
+    byte *derBuf, *tmp, *cipherInfo = NULL;
+    int  der_max_len = 0, derSz = 0;
+    const int type = DSA_PRIVATEKEY_TYPE;
+    const char* header = NULL;
+    const char* footer = NULL;
+
+    WOLFSSL_MSG("wolfSSL_PEM_write_mem_DSAPrivateKey");
+
+    if (pem == NULL || plen == NULL || dsa == NULL || dsa->internal == NULL) {
+        WOLFSSL_MSG("Bad function arguments");
+        return WOLFSSL_FAILURE;
+    }
+
+    if (wc_PemGetHeaderFooter(type, &header, &footer) != 0)
+        return WOLFSSL_FAILURE;
+
+    if (dsa->inSet == 0) {
+        WOLFSSL_MSG("No DSA internal set, do it");
+
+        if (SetDsaInternal(dsa) != WOLFSSL_SUCCESS) {
+            WOLFSSL_MSG("SetDsaInternal failed");
+            return WOLFSSL_FAILURE;
+        }
+    }
+
+    /* 4 > size of pub, priv, p, q, g + ASN.1 additional information */
+    der_max_len = 4 * wolfSSL_BN_num_bytes(dsa->g) + AES_BLOCK_SIZE;
+
+    derBuf = (byte*)XMALLOC(der_max_len, NULL, DYNAMIC_TYPE_DER);
+    if (derBuf == NULL) {
+        WOLFSSL_MSG("malloc failed");
+        return WOLFSSL_FAILURE;
+    }
+
+    /* Key to DER */
+    derSz = wc_DsaKeyToDer((DsaKey*)dsa->internal, derBuf, der_max_len);
+    if (derSz < 0) {
+        WOLFSSL_MSG("wc_DsaKeyToDer failed");
+        XFREE(derBuf, NULL, DYNAMIC_TYPE_DER);
+        return WOLFSSL_FAILURE;
+    }
+
+    /* encrypt DER buffer if required */
+    if (passwd != NULL && passwdSz > 0 && cipher != NULL) {
+        int ret;
+
+        ret = EncryptDerKey(derBuf, &derSz, cipher,
+                            passwd, passwdSz, &cipherInfo);
+        if (ret != WOLFSSL_SUCCESS) {
+            WOLFSSL_MSG("EncryptDerKey failed");
+            XFREE(derBuf, NULL, DYNAMIC_TYPE_DER);
+            return ret;
+        }
+
+        /* tmp buffer with a max size */
+        *plen = (derSz * 2) + (int)XSTRLEN(header) + 1 +
+            (int)XSTRLEN(footer) + 1 + HEADER_ENCRYPTED_KEY_SIZE;
+    }
+    else { /* tmp buffer with a max size */
+        *plen = (derSz * 2) + (int)XSTRLEN(header) + 1 +
+            (int)XSTRLEN(footer) + 1;
+    }
+
+    tmp = (byte*)XMALLOC(*plen, NULL, DYNAMIC_TYPE_PEM);
+    if (tmp == NULL) {
+        WOLFSSL_MSG("malloc failed");
+        XFREE(derBuf, NULL, DYNAMIC_TYPE_DER);
+        if (cipherInfo != NULL)
+            XFREE(cipherInfo, NULL, DYNAMIC_TYPE_STRING);
+        return WOLFSSL_FAILURE;
+    }
+
+    /* DER to PEM */
+    *plen = wc_DerToPemEx(derBuf, derSz, tmp, *plen, cipherInfo, type);
+    if (*plen <= 0) {
+        WOLFSSL_MSG("wc_DerToPemEx failed");
+        XFREE(derBuf, NULL, DYNAMIC_TYPE_DER);
+        XFREE(tmp, NULL, DYNAMIC_TYPE_PEM);
+        if (cipherInfo != NULL)
+            XFREE(cipherInfo, NULL, DYNAMIC_TYPE_STRING);
+        return WOLFSSL_FAILURE;
+    }
+    XFREE(derBuf, NULL, DYNAMIC_TYPE_DER);
+    if (cipherInfo != NULL)
+        XFREE(cipherInfo, NULL, DYNAMIC_TYPE_STRING);
+
+    *pem = (byte*)XMALLOC((*plen)+1, NULL, DYNAMIC_TYPE_KEY);
+    if (*pem == NULL) {
+        WOLFSSL_MSG("malloc failed");
+        XFREE(tmp, NULL, DYNAMIC_TYPE_PEM);
+        return WOLFSSL_FAILURE;
+    }
+    XMEMSET(*pem, 0, (*plen)+1);
+
+    if (XMEMCPY(*pem, tmp, *plen) == NULL) {
+        WOLFSSL_MSG("XMEMCPY failed");
+        XFREE(pem, NULL, DYNAMIC_TYPE_KEY);
+        XFREE(tmp, NULL, DYNAMIC_TYPE_PEM);
+        return WOLFSSL_FAILURE;
+    }
+    XFREE(tmp, NULL, DYNAMIC_TYPE_PEM);
+
+    return WOLFSSL_SUCCESS;
+#else
+    (void)dsa;
+    (void)cipher;
+    (void)passwd;
+    (void)passwdSz;
+    (void)pem;
+    (void)plen;
+    return WOLFSSL_FAILURE;
+#endif /* WOLFSSL_PEM_TO_DER || WOLFSSL_DER_TO_PEM */
+}
+
+#ifndef NO_FILESYSTEM
+/* return code compliant with OpenSSL :
+ *   1 if success, 0 if error
+ */
+int wolfSSL_PEM_write_DSAPrivateKey(XFILE fp, WOLFSSL_DSA *dsa,
+                                    const EVP_CIPHER *enc,
+                                    unsigned char *kstr, int klen,
+                                    pem_password_cb *cb, void *u)
+{
+    byte *pem;
+    int  plen, ret;
+
+    (void)cb;
+    (void)u;
+
+    WOLFSSL_MSG("wolfSSL_PEM_write_DSAPrivateKey");
+
+    if (fp == XBADFILE || dsa == NULL || dsa->internal == NULL) {
+        WOLFSSL_MSG("Bad function arguments");
+        return WOLFSSL_FAILURE;
+    }
+
+    ret = wolfSSL_PEM_write_mem_DSAPrivateKey(dsa, enc, kstr, klen, &pem, &plen);
+    if (ret != WOLFSSL_SUCCESS) {
+        WOLFSSL_MSG("wolfSSL_PEM_write_mem_DSAPrivateKey failed");
+        return WOLFSSL_FAILURE;
+    }
+
+    ret = (int)XFWRITE(pem, plen, 1, fp);
+    if (ret != 1) {
+        WOLFSSL_MSG("DSA private key file write failed");
+        return WOLFSSL_FAILURE;
+    }
+
+    XFREE(pem, NULL, DYNAMIC_TYPE_KEY);
+    return WOLFSSL_SUCCESS;
+}
+
+#endif /* NO_FILESYSTEM */
+#endif /* defined(WOLFSSL_KEY_GEN) */
+
+#ifndef NO_FILESYSTEM
+/* return code compliant with OpenSSL :
+ *   1 if success, 0 if error
+ */
+#ifndef NO_WOLFSSL_STUB
+int wolfSSL_PEM_write_DSA_PUBKEY(XFILE fp, WOLFSSL_DSA *x)
+{
+    (void)fp;
+    (void)x;
+    WOLFSSL_STUB("PEM_write_DSA_PUBKEY");
+    WOLFSSL_MSG("wolfSSL_PEM_write_DSA_PUBKEY not implemented");
+
+    return WOLFSSL_FAILURE;
+}
+#endif
+#endif /* NO_FILESYSTEM */
+
+#endif /* #ifndef NO_DSA */
+
+static int pem_read_bio_key(WOLFSSL_BIO* bio, pem_password_cb* cb, void* pass,
+                            int keyType, int* eccFlag, DerBuffer** der)
+{
+#ifdef WOLFSSL_SMALL_STACK
+    EncryptedInfo* info = NULL;
+#else
+    EncryptedInfo info[1];
+#endif /* WOLFSSL_SMALL_STACK */
+    pem_password_cb* localCb = NULL;
+    char* mem = NULL;
+    int memSz = 0;
+    int ret;
+
+    if(cb) {
+        localCb = cb;
+    } else {
+        if(pass) {
+            localCb = wolfSSL_PEM_def_callback;
+        }
+    }
+
+    if ((ret = wolfSSL_BIO_pending(bio)) > 0) {
+        memSz = ret;
+        mem = (char*)XMALLOC(memSz, bio->heap, DYNAMIC_TYPE_OPENSSL);
+        if (mem == NULL) {
+            WOLFSSL_MSG("Memory error");
+            ret = MEMORY_E;
+        }
+        if (ret >= 0) {
+            if ((ret = wolfSSL_BIO_read(bio, mem, memSz)) <= 0) {
+                XFREE(mem, bio->heap, DYNAMIC_TYPE_OPENSSL);
+                mem = NULL;
+                ret = MEMORY_E;
+            }
+        }
+    }
+    else if (bio->type == WOLFSSL_BIO_FILE) {
+        int sz  = 100; /* read from file by 100 byte chunks */
+        int idx = 0;
+        char* tmp = (char*)XMALLOC(sz, bio->heap, DYNAMIC_TYPE_OPENSSL);
+        memSz = 0;
+        if (tmp == NULL) {
+            WOLFSSL_MSG("Memory error");
+            ret = MEMORY_E;
+        }
+
+        while (ret >= 0 && (sz = wolfSSL_BIO_read(bio, tmp, sz)) > 0) {
+            char* newMem;
+            if (memSz + sz < 0) {
+                /* sanity check */
+                break;
+            }
+            newMem = (char*)XREALLOC(mem, memSz + sz, bio->heap,
+                    DYNAMIC_TYPE_OPENSSL);
+            if (newMem == NULL) {
+                WOLFSSL_MSG("Memory error");
+                XFREE(mem, bio->heap, DYNAMIC_TYPE_OPENSSL);
+                mem = NULL;
+                XFREE(tmp, bio->heap, DYNAMIC_TYPE_OPENSSL);
+                tmp = NULL;
+                ret = MEMORY_E;
+                break;
+            }
+            mem = newMem;
+            XMEMCPY(mem + idx, tmp, sz);
+            memSz += sz;
+            idx   += sz;
+            sz = 100; /* read another 100 byte chunk from file */
+        }
+        XFREE(tmp, bio->heap, DYNAMIC_TYPE_OPENSSL);
+        tmp = NULL;
+        if (memSz <= 0) {
+            WOLFSSL_MSG("No data to read from bio");
+            if (mem != NULL) {
+                XFREE(mem, bio->heap, DYNAMIC_TYPE_OPENSSL);
+                mem = NULL;
+            }
+            ret = BUFFER_E;
+        }
+    }
+    else {
+        WOLFSSL_MSG("No data to read from bio");
+        ret = NOT_COMPILED_IN;
+    }
+
+#ifdef WOLFSSL_SMALL_STACK
+    if (ret >= 0) {
+        info = (EncryptedInfo*)XMALLOC(sizeof(EncryptedInfo), NULL,
+                                       DYNAMIC_TYPE_TMP_BUFFER);
+        if (info == NULL) {
+            WOLFSSL_MSG("Error getting memory for EncryptedInfo structure");
+            XFREE(mem, bio->heap, DYNAMIC_TYPE_OPENSSL);
+            mem = NULL;
+            ret = MEMORY_E;
+        }
+    }
+#endif
+
+    if (ret >= 0) {
+        XMEMSET(info, 0, sizeof(EncryptedInfo));
+        info->passwd_cb       = localCb;
+        info->passwd_userdata = pass;
+        ret = PemToDer((const unsigned char*)mem, memSz, keyType, der,
+            NULL, info, eccFlag);
+
+        if (ret < 0) {
+            WOLFSSL_MSG("Bad Pem To Der");
+        }
+        else {
+            /* write left over data back to bio */
+            if ((memSz - (int)info->consumed) > 0 &&
+                    bio->type != WOLFSSL_BIO_FILE) {
+                if (wolfSSL_BIO_write(bio, mem + (int)info->consumed,
+                                       memSz - (int)info->consumed) <= 0) {
+                    WOLFSSL_MSG("Unable to advance bio read pointer");
+                }
+            }
+        }
+    }
+
+#ifdef WOLFSSL_SMALL_STACK
+    XFREE(info, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+#endif
+    XFREE(mem, bio->heap, DYNAMIC_TYPE_OPENSSL);
+
+    return ret;
+}
+
+WOLFSSL_EVP_PKEY* wolfSSL_PEM_read_bio_PrivateKey(WOLFSSL_BIO* bio,
+                                                  WOLFSSL_EVP_PKEY** key,
+                                                  pem_password_cb* cb,
+                                                  void* pass)
+{
+    WOLFSSL_EVP_PKEY* pkey = NULL;
+    DerBuffer*         der = NULL;
+    int             keyFormat = 0;
+    int                 type = -1;
+
+    WOLFSSL_ENTER("wolfSSL_PEM_read_bio_PrivateKey");
+
+    if (bio == NULL)
+        return pkey;
+
+    if (pem_read_bio_key(bio, cb, pass, PRIVATEKEY_TYPE, &keyFormat,
+                                                                   &der) >= 0) {
+        const unsigned char* ptr = der->buffer;
+
+        if (keyFormat) {
+            /* keyFormat is Key_Sum enum */
+            if (keyFormat == RSAk)
+                type = EVP_PKEY_RSA;
+            else if (keyFormat == ECDSAk)
+                type =  EVP_PKEY_EC;
+            else if (keyFormat == DSAk)
+                type = EVP_PKEY_DSA;
+            else if (keyFormat == DHk)
+                type = EVP_PKEY_DH;
+        }
+        else {
+            /* Default to RSA if format is not set */
+            type = EVP_PKEY_RSA;
+        }
+
+        /* handle case where reuse is attempted */
+        if (key != NULL && *key != NULL)
+            pkey = *key;
+
+        wolfSSL_d2i_PrivateKey(type, &pkey, &ptr, der->length);
+        if (pkey == NULL) {
+            WOLFSSL_MSG("Error loading DER buffer into WOLFSSL_EVP_PKEY");
+        }
+    }
+
+    FreeDer(&der);
+
+    if (key != NULL && pkey != NULL)
+        *key = pkey;
+
+    WOLFSSL_LEAVE("wolfSSL_PEM_read_bio_PrivateKey", 0);
+
+    return pkey;
+}
+
+WOLFSSL_EVP_PKEY *wolfSSL_PEM_read_bio_PUBKEY(WOLFSSL_BIO* bio,
+                                              WOLFSSL_EVP_PKEY **key,
+                                              pem_password_cb *cb, void *pass)
+{
+    WOLFSSL_EVP_PKEY* pkey = NULL;
+    DerBuffer*        der = NULL;
+    int               keyFormat = 0;
+
+    WOLFSSL_ENTER("wolfSSL_PEM_read_bio_PUBKEY");
+
+    if (bio == NULL)
+        return pkey;
+
+    if (pem_read_bio_key(bio, cb, pass, PUBLICKEY_TYPE, &keyFormat, &der) >= 0) {
+        const unsigned char* ptr = der->buffer;
+
+        /* handle case where reuse is attempted */
+        if (key != NULL && *key != NULL)
+            pkey = *key;
+
+        wolfSSL_d2i_PUBKEY(&pkey, &ptr, der->length);
+        if (pkey == NULL) {
+            WOLFSSL_MSG("Error loading DER buffer into WOLFSSL_EVP_PKEY");
+        }
+    }
+
+    FreeDer(&der);
+
+    if (key != NULL && pkey != NULL)
+        *key = pkey;
+
+    WOLFSSL_LEAVE("wolfSSL_PEM_read_bio_PUBKEY", 0);
+
+    return pkey;
+}
+
+
+#if (defined(OPENSSL_EXTRA) || defined(OPENSSL_ALL)) && !defined(NO_RSA)
+/* Uses the same format of input as wolfSSL_PEM_read_bio_PrivateKey but expects
+ * the results to be an RSA key.
+ *
+ * bio  structure to read RSA private key from
+ * rsa  if not null is then set to the result
+ * cb   password callback for reading PEM
+ * pass password string
+ *
+ * returns a pointer to a new WOLFSSL_RSA structure on success and NULL on fail
+ */
+WOLFSSL_RSA* wolfSSL_PEM_read_bio_RSAPrivateKey(WOLFSSL_BIO* bio,
+        WOLFSSL_RSA** rsa, pem_password_cb* cb, void* pass)
+{
+    WOLFSSL_EVP_PKEY* pkey;
+    WOLFSSL_RSA* local;
+
+    WOLFSSL_ENTER("PEM_read_bio_RSAPrivateKey");
+
+    pkey = wolfSSL_PEM_read_bio_PrivateKey(bio, NULL, cb, pass);
+    if (pkey == NULL) {
+        return NULL;
+    }
+
+    /* Since the WOLFSSL_RSA structure is being taken from WOLFSSL_EVP_PEKY the
+     * flag indicating that the WOLFSSL_RSA structure is owned should be FALSE
+     * to avoid having it free'd */
+    pkey->ownRsa = 0;
+    local = pkey->rsa;
+    if (rsa != NULL) {
+        *rsa = local;
+    }
+
+    wolfSSL_EVP_PKEY_free(pkey);
+    return local;
+}
+#endif /* OPENSSL_EXTRA || OPENSSL_ALL || !NO_RSA */
+
+#if (defined(OPENSSL_EXTRA) || defined(OPENSSL_ALL)) && (!defined(NO_CERTS) && \
+       !defined(NO_FILESYSTEM) && !defined(NO_DSA) && defined(WOLFSSL_KEY_GEN))
+/* Uses the same format of input as wolfSSL_PEM_read_bio_PrivateKey but expects
+ * the results to be an DSA key.
+ *
+ * bio  structure to read DSA private key from
+ * dsa  if not null is then set to the result
+ * cb   password callback for reading PEM
+ * pass password string
+ *
+ * returns a pointer to a new WOLFSSL_DSA structure on success and NULL on fail
+ */
+WOLFSSL_DSA* wolfSSL_PEM_read_bio_DSAPrivateKey(WOLFSSL_BIO* bio,
+                                                WOLFSSL_DSA** dsa,
+                                                pem_password_cb* cb,void *pass)
+{
+    WOLFSSL_EVP_PKEY* pkey = NULL;
+    WOLFSSL_DSA* local;
+    WOLFSSL_ENTER("wolfSSL_PEM_read_bio_DSAPrivateKey");
+
+
+    pkey = wolfSSL_PEM_read_bio_PrivateKey(bio, NULL, cb, pass);
+    if (pkey == NULL) {
+        WOLFSSL_MSG("Error in PEM_read_bio_PrivateKey");
+         return NULL;
+     }
+     /* Since the WOLFSSL_DSA structure is being taken from WOLFSSL_EVP_PKEY the
+     * flag indicating that the WOLFSSL_DSA structure is owned should be FALSE
+     * to avoid having it free'd */
+    pkey->ownDsa = 0;
+    local = pkey->dsa;
+    if (dsa != NULL) {
+        *dsa = local;
+    }
+     wolfSSL_EVP_PKEY_free(pkey);
+    return local;
+}
+
+/* Reads an DSA public key from a WOLFSSL_BIO into a WOLFSSL_DSA.
+ * Returns WOLFSSL_SUCCESS or WOLFSSL_FAILURE
+ */
+WOLFSSL_DSA *wolfSSL_PEM_read_bio_DSA_PUBKEY(WOLFSSL_BIO* bio,WOLFSSL_DSA** dsa,
+                                                pem_password_cb* cb, void *pass)
+{
+    WOLFSSL_EVP_PKEY* pkey;
+    WOLFSSL_DSA* local;
+    WOLFSSL_ENTER("wolfSSL_PEM_read_bio_DSA_PUBKEY");
+
+    pkey = wolfSSL_PEM_read_bio_PUBKEY(bio, NULL, cb, pass);
+    if (pkey == NULL) {
+        WOLFSSL_MSG("wolfSSL_PEM_read_bio_PUBKEY failed");
+        return NULL;
+    }
+
+    /* Since the WOLFSSL_DSA structure is being taken from WOLFSSL_EVP_PKEY the
+     * flag indicating that the WOLFSSL_DSA structure is owned should be FALSE
+     * to avoid having it free'd */
+    pkey->ownDsa = 0;
+    local = pkey->dsa;
+    if (dsa != NULL) {
+        *dsa = local;
+    }
+
+    wolfSSL_EVP_PKEY_free(pkey);
+    return local;
+}
+#endif
+
+#ifdef HAVE_ECC
+/* returns a new WOLFSSL_EC_GROUP structure on success and NULL on fail */
+WOLFSSL_EC_GROUP* wolfSSL_PEM_read_bio_ECPKParameters(WOLFSSL_BIO* bio,
+        WOLFSSL_EC_GROUP** group, pem_password_cb* cb, void* pass)
+{
+    WOLFSSL_EVP_PKEY* pkey;
+    WOLFSSL_EC_GROUP* ret = NULL;
+
+    /* check on if bio is null is done in wolfSSL_PEM_read_bio_PrivateKey */
+    pkey = wolfSSL_PEM_read_bio_PrivateKey(bio, NULL, cb, pass);
+    if (pkey != NULL) {
+        if (pkey->type != EVP_PKEY_EC) {
+            WOLFSSL_MSG("Unexpected key type");
+        }
+        else {
+            ret = (WOLFSSL_EC_GROUP*)wolfSSL_EC_KEY_get0_group(pkey->ecc);
+
+            /* set ecc group to null so it is not free'd when pkey is free'd */
+            pkey->ecc->group = NULL;
+        }
+    }
+
+    (void)group;
+    wolfSSL_EVP_PKEY_free(pkey);
+    return ret;
+}
+#endif /* HAVE_ECC */
+
+#if !defined(NO_FILESYSTEM)
+WOLFSSL_EVP_PKEY *wolfSSL_PEM_read_PUBKEY(XFILE fp, EVP_PKEY **x,
+                                          pem_password_cb *cb, void *u)
+{
+    (void)fp;
+    (void)x;
+    (void)cb;
+    (void)u;
+
+    WOLFSSL_MSG("wolfSSL_PEM_read_PUBKEY not implemented");
+
+    return NULL;
+}
+#endif /* NO_FILESYSTEM */
+
+#ifndef NO_RSA
+
+#if defined(XSNPRINTF) && !defined(HAVE_FAST_RSA)
+/* snprintf() must be available */
+
+/******************************************************************************
+* wolfSSL_RSA_print - writes the human readable form of RSA to bio
+*
+* RETURNS:
+* returns WOLFSSL_SUCCESS on success, otherwise returns WOLFSSL_FAILURE
+*/
+int wolfSSL_RSA_print(WOLFSSL_BIO* bio, WOLFSSL_RSA* rsa, int offset)
+{
+    char tmp[100] = {0};
+    word32 idx = 0;
+    int  sz = 0;
+    byte lbit = 0;
+    int  rawLen = 0;
+    byte* rawKey = NULL;
+    RsaKey* iRsa = NULL;
+    int i = 0;
+    mp_int *rsaElem = NULL;
+    char rsaStr[][20] = { "Modulus:",
+                          "PublicExponent:",
+                          "PrivateExponent:",
+                          "Prime1:",
+                          "Prime2:",
+                          "Exponent1:",
+                          "Exponent2:",
+                          "Coefficient:"
+                        };
+
+    WOLFSSL_ENTER("wolfSSL_RSA_print");
+    (void)offset;
+
+    if (bio == NULL || rsa == NULL) {
+        return WOLFSSL_FATAL_ERROR;
+    }
+
+    if ((sz = wolfSSL_RSA_size(rsa)) < 0) {
+        WOLFSSL_MSG("Error getting RSA key size");
+        return WOLFSSL_FAILURE;
+    }
+    iRsa = (RsaKey*)rsa->internal;
+
+    XSNPRINTF(tmp, sizeof(tmp) - 1, "\n%s: (%d bit)",
+            "RSA Private-Key", 8 * sz);
+    tmp[sizeof(tmp) - 1] = '\0';
+    if (wolfSSL_BIO_write(bio, tmp, (int)XSTRLEN(tmp)) <= 0) {
+        return WOLFSSL_FAILURE;
+    }
+
+    for (i=0; i<RSA_INTS; i++) {
+        switch(i) {
+            case 0:
+                /* Print out modulus */
+                rsaElem = &iRsa->n;
+                break;
+            case 1:
+                rsaElem = &iRsa->e;
+                break;
+            case 2:
+                rsaElem = &iRsa->d;
+                break;
+            case 3:
+                rsaElem = &iRsa->p;
+                break;
+            case 4:
+                rsaElem = &iRsa->q;
+                break;
+            case 5:
+                rsaElem = &iRsa->dP;
+                break;
+            case 6:
+                rsaElem = &iRsa->dQ;
+                break;
+            case 7:
+                rsaElem = &iRsa->u;
+                break;
+            default:
+                WOLFSSL_MSG("Bad index value");
+        }
+
+        if (i == 1) {
+            /* Print out exponent values */
+            rawLen = mp_unsigned_bin_size(rsaElem);
+            if (rawLen < 0) {
+                WOLFSSL_MSG("Error getting exponent size");
+                return WOLFSSL_FAILURE;
+            }
+
+            if ((word32)rawLen < sizeof(word32)) {
+                rawLen = sizeof(word32);
+            }
+            rawKey = (byte*)XMALLOC(rawLen, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+            if (rawKey == NULL) {
+                WOLFSSL_MSG("Memory error");
+                return WOLFSSL_FAILURE;
+            }
+            XMEMSET(rawKey, 0, rawLen);
+            mp_to_unsigned_bin(rsaElem, rawKey);
+            if ((word32)rawLen <= sizeof(word32)) {
+                idx = *(word32*)rawKey;
+                #ifdef BIG_ENDIAN_ORDER
+                    idx = ByteReverseWord32(idx);
+                #endif
+            }
+            XSNPRINTF(tmp, sizeof(tmp) - 1, "\nExponent: %d (0x%x)", idx, idx);
+            if (wolfSSL_BIO_write(bio, tmp, (int)XSTRLEN(tmp)) <= 0) {
+                XFREE(rawKey, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+                return WOLFSSL_FAILURE;
+            }
+            XFREE(rawKey, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+        }
+        else {
+            XSNPRINTF(tmp, sizeof(tmp) - 1, "\n%s\n    ", rsaStr[i]);
+            tmp[sizeof(tmp) - 1] = '\0';
+            if (mp_leading_bit(rsaElem)) {
+                lbit = 1;
+                XSTRNCAT(tmp, "00", 3);
+            }
+
+            rawLen = mp_unsigned_bin_size(rsaElem);
+            rawKey = (byte*)XMALLOC(rawLen, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+            if (rawKey == NULL) {
+                WOLFSSL_MSG("Memory error");
+                return WOLFSSL_FAILURE;
+            }
+            mp_to_unsigned_bin(rsaElem, rawKey);
+            for (idx = 0; idx < (word32)rawLen; idx++) {
+                char val[5];
+                int  valSz = 5;
+
+                if ((idx == 0) && !lbit) {
+                    XSNPRINTF(val, valSz - 1, "%02x", rawKey[idx]);
+                }
+                else if ((idx != 0) && (((idx + lbit) % 15) == 0)) {
+                    tmp[sizeof(tmp) - 1] = '\0';
+                    if (wolfSSL_BIO_write(bio, tmp, (int)XSTRLEN(tmp)) <= 0) {
+                        XFREE(rawKey, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+                        return WOLFSSL_FAILURE;
+                    }
+                    XSNPRINTF(tmp, sizeof(tmp) - 1,
+                            ":\n    ");
+                    XSNPRINTF(val, valSz - 1, "%02x", rawKey[idx]);
+                }
+                else {
+                    XSNPRINTF(val, valSz - 1, ":%02x", rawKey[idx]);
+                }
+                XSTRNCAT(tmp, val, valSz);
+            }
+            XFREE(rawKey, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+
+            /* print out remaining values */
+            if ((idx > 0) && (((idx - 1 + lbit) % 15) != 0)) {
+                tmp[sizeof(tmp) - 1] = '\0';
+                if (wolfSSL_BIO_write(bio, tmp, (int)XSTRLEN(tmp)) <= 0) {
+                    return WOLFSSL_FAILURE;
+                }
+            }
+            lbit = 0;
+        }
+
+    }
+    /* done with print out */
+    if (wolfSSL_BIO_write(bio, "\n\0", (int)XSTRLEN("\n\0")) <= 0) {
+        return WOLFSSL_FAILURE;
+    }
+
+    return WOLFSSL_SUCCESS;
+}
+
+#endif /* XSNPRINTF */
+
+#if !defined(NO_FILESYSTEM)
+#ifndef NO_WOLFSSL_STUB
+WOLFSSL_RSA *wolfSSL_PEM_read_RSAPublicKey(XFILE fp, WOLFSSL_RSA **x,
+                                           pem_password_cb *cb, void *u)
+{
+    (void)fp;
+    (void)x;
+    (void)cb;
+    (void)u;
+    WOLFSSL_STUB("PEM_read_RSAPublicKey");
+    WOLFSSL_MSG("wolfSSL_PEM_read_RSAPublicKey not implemented");
+
+    return NULL;
+}
+#endif
+/* return code compliant with OpenSSL :
+ *   1 if success, 0 if error
+ */
+#ifndef NO_WOLFSSL_STUB
+int wolfSSL_PEM_write_RSAPublicKey(XFILE fp, WOLFSSL_RSA *x)
+{
+    (void)fp;
+    (void)x;
+    WOLFSSL_STUB("PEM_write_RSAPublicKey");
+    WOLFSSL_MSG("wolfSSL_PEM_write_RSAPublicKey not implemented");
+
+    return WOLFSSL_FAILURE;
+}
+#endif
+
+/* return code compliant with OpenSSL :
+ *   1 if success, 0 if error
+ */
+#ifndef NO_WOLFSSL_STUB
+int wolfSSL_PEM_write_RSA_PUBKEY(XFILE fp, WOLFSSL_RSA *x)
+{
+    (void)fp;
+    (void)x;
+    WOLFSSL_STUB("PEM_write_RSA_PUBKEY");
+    WOLFSSL_MSG("wolfSSL_PEM_write_RSA_PUBKEY not implemented");
+
+    return WOLFSSL_FAILURE;
+}
+#endif
+
+#endif /* NO_FILESYSTEM */
+
+WOLFSSL_RSA *wolfSSL_d2i_RSAPublicKey(WOLFSSL_RSA **r, const unsigned char **pp,
+    long len)
+{
+    WOLFSSL_RSA *rsa = NULL;
+
+    WOLFSSL_ENTER("d2i_RSAPublicKey");
+
+    if (pp == NULL) {
+        WOLFSSL_MSG("Bad argument");
+        return NULL;
+    }
+    if ((rsa = wolfSSL_RSA_new()) == NULL) {
+        WOLFSSL_MSG("RSA_new failed");
+        return NULL;
+    }
+
+    if (wolfSSL_RSA_LoadDer_ex(rsa, *pp, (int)len, WOLFSSL_RSA_LOAD_PUBLIC)
+                                                         != WOLFSSL_SUCCESS) {
+        WOLFSSL_MSG("RSA_LoadDer failed");
+        wolfSSL_RSA_free(rsa);
+        rsa = NULL;
+    }
+    if (r != NULL)
+        *r = rsa;
+
+    return rsa;
+}
+
+/* Converts an RSA private key from DER format to an RSA structure.
+Returns pointer to the RSA structure on success and NULL if error. */
+WOLFSSL_RSA *wolfSSL_d2i_RSAPrivateKey(WOLFSSL_RSA **r,
+                                       const unsigned char **derBuf, long derSz)
+{
+    WOLFSSL_RSA *rsa = NULL;
+
+    WOLFSSL_ENTER("wolfSSL_d2i_RSAPrivateKey");
+
+    /* check for bad functions arguments */
+    if (derBuf == NULL) {
+        WOLFSSL_MSG("Bad argument");
+        return NULL;
+    }
+    if ((rsa = wolfSSL_RSA_new()) == NULL) {
+        WOLFSSL_MSG("RSA_new failed");
+        return NULL;
+    }
+
+    if (wolfSSL_RSA_LoadDer_ex(rsa, *derBuf, (int)derSz,
+                                 WOLFSSL_RSA_LOAD_PRIVATE) != WOLFSSL_SUCCESS) {
+        WOLFSSL_MSG("RSA_LoadDer failed");
+        wolfSSL_RSA_free(rsa);
+        rsa = NULL;
+    }
+    if (r != NULL)
+        *r = rsa;
+
+    return rsa;
+}
+
+#if !defined(HAVE_FAST_RSA) && defined(WOLFSSL_KEY_GEN) && \
+    !defined(NO_RSA) && !defined(HAVE_USER_RSA)
+/* Converts an internal RSA structure to DER format.
+ * If "pp" is null then buffer size only is returned.
+ * If "*pp" is null then a created buffer is set in *pp and the caller is
+ *  responsible for free'ing it.
+ * Returns size of DER on success and WOLFSSL_FAILURE if error
+ */
+int wolfSSL_i2d_RSAPrivateKey(WOLFSSL_RSA *rsa, unsigned char **pp)
+{
+    int ret;
+
+    WOLFSSL_ENTER("wolfSSL_i2d_RSAPrivateKey");
+
+    /* check for bad functions arguments */
+    if (rsa == NULL) {
+        WOLFSSL_MSG("Bad Function Arguments");
+        return BAD_FUNC_ARG;
+    }
+
+    if ((ret = wolfSSL_RSA_To_Der(rsa, pp, 0)) < 0) {
+        WOLFSSL_MSG("wolfSSL_RSA_To_Der failed");
+        return WOLFSSL_FAILURE;
+    }
+
+    return ret; /* returns size of DER if successful */
+}
+
+
+int wolfSSL_i2d_RSAPublicKey(WOLFSSL_RSA *rsa, const unsigned char **pp)
+{
+    int ret;
+
+    /* check for bad functions arguments */
+    if (rsa == NULL) {
+        WOLFSSL_MSG("Bad Function Arguments");
+        return BAD_FUNC_ARG;
+    }
+
+    if ((ret = wolfSSL_RSA_To_Der(rsa, (byte**)pp, 1)) < 0) {
+        WOLFSSL_MSG("wolfSSL_RSA_To_Der failed");
+        return WOLFSSL_FAILURE;
+    }
+
+    return ret;
+}
+#endif /* !defined(HAVE_FAST_RSA) && defined(WOLFSSL_KEY_GEN) && \
+        * !defined(NO_RSA) && !defined(HAVE_USER_RSA) */
+
+#endif /* !NO_RSA */
+#endif /* OPENSSL_EXTRA */
+
+#if !defined(NO_RSA) && (defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL))
+/* return WOLFSSL_SUCCESS if success, WOLFSSL_FATAL_ERROR if error */
+int wolfSSL_RSA_LoadDer(WOLFSSL_RSA* rsa, const unsigned char* derBuf, int derSz)
+{
+  return wolfSSL_RSA_LoadDer_ex(rsa, derBuf, derSz, WOLFSSL_RSA_LOAD_PRIVATE);
+}
+
+
+int wolfSSL_RSA_LoadDer_ex(WOLFSSL_RSA* rsa, const unsigned char* derBuf,
+                                                     int derSz, int opt)
+{
+
+    word32 idx = 0;
+    int    ret;
+
+    WOLFSSL_ENTER("wolfSSL_RSA_LoadDer");
+
+    if (rsa == NULL || rsa->internal == NULL || derBuf == NULL || derSz <= 0) {
+        WOLFSSL_MSG("Bad function arguments");
+        return WOLFSSL_FATAL_ERROR;
+    }
+
+    if (opt == WOLFSSL_RSA_LOAD_PRIVATE) {
+        ret = wc_RsaPrivateKeyDecode(derBuf, &idx, (RsaKey*)rsa->internal, derSz);
+    }
+    else {
+        ret = wc_RsaPublicKeyDecode(derBuf, &idx, (RsaKey*)rsa->internal, derSz);
+    }
+
+    if (ret < 0) {
+        if (opt == WOLFSSL_RSA_LOAD_PRIVATE) {
+             WOLFSSL_MSG("RsaPrivateKeyDecode failed");
+        }
+        else {
+             WOLFSSL_MSG("RsaPublicKeyDecode failed");
+        }
+        return SSL_FATAL_ERROR;
+    }
+
+    if (SetRsaExternal(rsa) != WOLFSSL_SUCCESS) {
+        WOLFSSL_MSG("SetRsaExternal failed");
+        return WOLFSSL_FATAL_ERROR;
+    }
+
+    rsa->inSet = 1;
+
+    return WOLFSSL_SUCCESS;
+}
+
+#if defined(WC_RSA_PSS) && (defined(OPENSSL_ALL) || defined(WOLFSSL_ASIO) || \
+        defined(WOLFSSL_HAPROXY) || defined(WOLFSSL_NGINX))
+static int hash2mgf(enum wc_HashType hType)
+{
+    switch (hType) {
+#ifndef NO_SHA
+    case WC_HASH_TYPE_SHA:
+        return WC_MGF1SHA1;
+#endif
+#ifndef NO_SHA256
+#ifdef WOLFSSL_SHA224
+    case WC_HASH_TYPE_SHA224:
+        return WC_MGF1SHA224;
+#endif
+    case WC_HASH_TYPE_SHA256:
+        return WC_MGF1SHA256;
+#endif
+#ifdef WOLFSSL_SHA384
+    case WC_HASH_TYPE_SHA384:
+        return WC_MGF1SHA384;
+#endif
+#ifdef WOLFSSL_SHA512
+    case WC_HASH_TYPE_SHA512:
+        return WC_MGF1SHA512;
+#endif
+    case WC_HASH_TYPE_NONE:
+    case WC_HASH_TYPE_MD2:
+    case WC_HASH_TYPE_MD4:
+    case WC_HASH_TYPE_MD5:
+    case WC_HASH_TYPE_MD5_SHA:
+    case WC_HASH_TYPE_SHA3_224:
+    case WC_HASH_TYPE_SHA3_256:
+    case WC_HASH_TYPE_SHA3_384:
+    case WC_HASH_TYPE_SHA3_512:
+    case WC_HASH_TYPE_BLAKE2B:
+    case WC_HASH_TYPE_BLAKE2S:
+    default:
+        WOLFSSL_MSG("Unrecognized or unsupported hash function");
+        return WC_MGF1NONE;
+    }
+}
+
+/*
+ *                                +-----------+
+ *                                |     M     |
+ *                                +-----------+
+ *                                      |
+ *                                      V
+ *                                    Hash
+ *                                      |
+ *                                      V
+ *                        +--------+----------+----------+
+ *                   M' = |Padding1|  mHash   |   salt   |
+ *                        +--------+----------+----------+
+ *                                       |
+ *             +--------+----------+     V
+ *       DB =  |Padding2|maskedseed|   Hash
+ *             +--------+----------+     |
+ *                       |               |
+ *                       V               |    +--+
+ *                      xor <--- MGF <---|    |bc|
+ *                       |               |    +--+
+ *                       |               |      |
+ *                       V               V      V
+ *             +-------------------+----------+--+
+ *       EM =  |    maskedDB       |maskedseed|bc|
+ *             +-------------------+----------+--+
+ * Diagram taken from https://tools.ietf.org/html/rfc3447#section-9.1
+ */
+int wolfSSL_RSA_padding_add_PKCS1_PSS(WOLFSSL_RSA *rsa, unsigned char *EM,
+                                      const unsigned char *mHash,
+                                      const WOLFSSL_EVP_MD *hashAlg, int saltLen)
+{
+    int hashLen, emLen, mgf;
+    int ret = WOLFSSL_FAILURE;
+    int initTmpRng = 0;
+    WC_RNG *rng = NULL;
+#ifdef WOLFSSL_SMALL_STACK
+    WC_RNG* tmpRNG = NULL;
+#else
+    WC_RNG  _tmpRNG[1];
+    WC_RNG* tmpRNG = _tmpRNG;
+#endif
+    enum wc_HashType hashType;
+
+    WOLFSSL_ENTER("wolfSSL_RSA_padding_add_PKCS1_PSS");
+
+    if (!rsa || !EM || !mHash || !hashAlg) {
+        return WOLFSSL_FAILURE;
+    }
+
+    if (!(rng = WOLFSSL_RSA_GetRNG(rsa, (WC_RNG**)&tmpRNG, &initTmpRng))) {
+        WOLFSSL_MSG("WOLFSSL_RSA_GetRNG error");
+        goto cleanup;
+    }
+
+    if (!rsa->exSet && SetRsaExternal(rsa) != WOLFSSL_SUCCESS) {
+        WOLFSSL_MSG("SetRsaExternal error");
+        goto cleanup;
+    }
+
+    hashType = wolfSSL_EVP_md2macType(hashAlg);
+    if (hashType < WC_HASH_TYPE_NONE || hashType > WC_HASH_TYPE_MAX) {
+        WOLFSSL_MSG("wolfSSL_EVP_md2macType error");
+        goto cleanup;
+    }
+
+   if ((mgf = hash2mgf(hashType)) == WC_MGF1NONE) {
+       WOLFSSL_MSG("hash2mgf error");
+       goto cleanup;
+   }
+
+    if ((hashLen = wolfSSL_EVP_MD_size(hashAlg)) < 0) {
+        WOLFSSL_MSG("wolfSSL_EVP_MD_size error");
+        goto cleanup;
+    }
+
+    if ((emLen = wolfSSL_RSA_size(rsa)) <= 0) {
+        WOLFSSL_MSG("wolfSSL_RSA_size error");
+        goto cleanup;
+    }
+
+    switch (saltLen) {
+    /* Negative saltLen values are treated differently */
+        case RSA_PSS_SALTLEN_DIGEST:
+            saltLen = hashLen;
+            break;
+        case RSA_PSS_SALTLEN_MAX_SIGN:
+        case RSA_PSS_SALTLEN_MAX:
+            saltLen = emLen - hashLen - 2;
+            break;
+        default:
+            if (saltLen < 0) {
+                /* Not any currently implemented negative value */
+                WOLFSSL_MSG("invalid saltLen");
+                goto cleanup;
+            }
+    }
+
+    if (wc_RsaPad_ex(mHash, wolfSSL_EVP_MD_size(hashAlg), EM, emLen,
+                     RSA_BLOCK_TYPE_1, rng, WC_RSA_PSS_PAD,
+                     wolfSSL_EVP_md2macType(hashAlg), mgf, NULL, 0, saltLen,
+                     wolfSSL_BN_num_bits(rsa->n), NULL) != MP_OKAY) {
+        WOLFSSL_MSG("wc_RsaPad_ex error");
+        goto cleanup;
+    }
+
+    ret = WOLFSSL_SUCCESS;
+cleanup:
+    if (initTmpRng)
+        wc_FreeRng(tmpRNG);
+#ifdef WOLFSSL_SMALL_STACK
+    if (tmpRNG)
+        XFREE(tmpRNG, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+#endif
+
+    return ret;
+}
+
+/*
+ * Refer to wolfSSL_RSA_padding_add_PKCS1_PSS
+ * for an explanation of the parameters.
+ */
+int wolfSSL_RSA_verify_PKCS1_PSS(WOLFSSL_RSA *rsa, const unsigned char *mHash,
+                                 const WOLFSSL_EVP_MD *hashAlg,
+                                 const unsigned char *EM, int saltLen)
+{
+    int hashLen, mgf, emLen, mPrimeLen;
+    enum wc_HashType hashType;
+    byte *mPrime = NULL;
+    byte *buf = NULL;
+
+    WOLFSSL_ENTER("wolfSSL_RSA_verify_PKCS1_PSS");
+
+    if (!rsa || !mHash || !hashAlg || !EM) {
+        return WOLFSSL_FAILURE;
+    }
+
+    if ((hashLen = wolfSSL_EVP_MD_size(hashAlg)) < 0) {
+        return WOLFSSL_FAILURE;
+    }
+
+    if ((emLen = wolfSSL_RSA_size(rsa)) <= 0) {
+        WOLFSSL_MSG("wolfSSL_RSA_size error");
+        return WOLFSSL_FAILURE;
+    }
+
+    switch (saltLen) {
+    /* Negative saltLen values are treated differently */
+        case RSA_PSS_SALTLEN_DIGEST:
+            saltLen = hashLen;
+            break;
+        case RSA_PSS_SALTLEN_MAX_SIGN:
+        case RSA_PSS_SALTLEN_MAX:
+            saltLen = emLen - hashLen - 2;
+            break;
+        default:
+            if (saltLen < 0) {
+                /* Not any currently implemented negative value */
+                WOLFSSL_MSG("invalid saltLen");
+                return WOLFSSL_FAILURE;
+            }
+    }
+
+    if (!rsa->exSet && SetRsaExternal(rsa) != WOLFSSL_SUCCESS) {
+        return WOLFSSL_FAILURE;
+    }
+
+    hashType = wolfSSL_EVP_md2macType(hashAlg);
+    if (hashType < WC_HASH_TYPE_NONE || hashType > WC_HASH_TYPE_MAX) {
+        WOLFSSL_MSG("wolfSSL_EVP_md2macType error");
+        return WOLFSSL_FAILURE;
+    }
+
+    if ((mgf = hash2mgf(hashType)) == WC_MGF1NONE) {
+        WOLFSSL_MSG("hash2mgf error");
+        return WOLFSSL_FAILURE;
+    }
+
+    if ((hashLen = wolfSSL_EVP_MD_size(hashAlg)) < 0) {
+        WOLFSSL_MSG("wolfSSL_EVP_MD_size error");
+        return WOLFSSL_FAILURE;
+    }
+
+    if (!(buf = (byte*)XMALLOC(emLen, NULL, DYNAMIC_TYPE_TMP_BUFFER))) {
+        WOLFSSL_MSG("malloc error");
+        return WOLFSSL_FAILURE;
+    }
+    XMEMCPY(buf, EM, emLen);
+
+    /* Remove and verify the PSS padding */
+    if ((mPrimeLen = wc_RsaUnPad_ex(buf, emLen, &mPrime,
+                                    RSA_BLOCK_TYPE_1, WC_RSA_PSS_PAD, hashType,
+                                    mgf, NULL, 0, saltLen,
+                                    wolfSSL_BN_num_bits(rsa->n), NULL)) < 0) {
+        WOLFSSL_MSG("wc_RsaPad_ex error");
+        XFREE(buf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+        return WOLFSSL_FAILURE;
+    }
+
+    /* Verify the hash is correct */
+    if (wc_RsaPSS_CheckPadding_ex(mHash, hashLen, mPrime, mPrimeLen, hashType,
+                                  saltLen, wolfSSL_BN_num_bits(rsa->n))
+                                  != MP_OKAY) {
+        WOLFSSL_MSG("wc_RsaPSS_CheckPadding_ex error");
+        XFREE(buf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+        return WOLFSSL_FAILURE;
+    }
+    XFREE(buf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    return WOLFSSL_SUCCESS;
+}
+#endif
+
+#if defined(OPENSSL_EXTRA)
+WOLFSSL_RSA_METHOD *wolfSSL_RSA_meth_new(const char *name, int flags)
+{
+    int name_len;
+    WOLFSSL_RSA_METHOD* meth;
+
+    if (name == NULL) {
+        return NULL;
+    }
+
+    meth = (WOLFSSL_RSA_METHOD*)XMALLOC(sizeof(WOLFSSL_RSA_METHOD), NULL,
+        DYNAMIC_TYPE_OPENSSL);
+    name_len = (int)XSTRLEN(name);
+    if (!meth) {
+        return NULL;
+    }
+    meth->flags = flags;
+    meth->name = (char*)XMALLOC(name_len+1, NULL, DYNAMIC_TYPE_OPENSSL);
+    if (!meth->name) {
+        XFREE(meth, NULL, DYNAMIC_TYPE_OPENSSL);
+        return NULL;
+    }
+    XMEMCPY(meth->name, name, name_len+1);
+
+    return meth;
+}
+
+void wolfSSL_RSA_meth_free(WOLFSSL_RSA_METHOD *meth)
+{
+    if (meth) {
+        XFREE(meth->name, NULL, DYNAMIC_TYPE_OPENSSL);
+        XFREE(meth, NULL, DYNAMIC_TYPE_OPENSSL);
+    }
+}
+
+#ifndef NO_WOLFSSL_STUB
+int wolfSSL_RSA_meth_set(WOLFSSL_RSA_METHOD *rsa, void* p)
+{
+    (void)rsa;
+    (void)p;
+    WOLFSSL_STUB("RSA_METHOD is not implemented.");
+    return 1;
+}
+#endif
+
+int wolfSSL_RSA_set_method(WOLFSSL_RSA *rsa, WOLFSSL_RSA_METHOD *meth)
+{
+    if (rsa)
+        rsa->meth = meth;
+    return 1;
+}
+
+const WOLFSSL_RSA_METHOD* wolfSSL_RSA_get_method(const WOLFSSL_RSA *rsa)
+{
+    if (!rsa) {
+        return NULL;
+    }
+    return rsa->meth;
+}
+
+const WOLFSSL_RSA_METHOD* wolfSSL_RSA_get_default_method(void)
+{
+    return wolfSSL_RSA_meth_new("wolfSSL RSA", 0);
+}
+
+int wolfSSL_RSA_flags(const WOLFSSL_RSA *r)
+{
+    if (r && r->meth) {
+        return r->meth->flags;
+    } else {
+        return 0;
+    }
+}
+
+void wolfSSL_RSA_set_flags(WOLFSSL_RSA *r, int flags)
+{
+    if (r && r->meth) {
+        r->meth->flags = flags;
+    }
+}
+
+#if defined(WOLFSSL_KEY_GEN) && !defined(NO_RSA) && !defined(HAVE_USER_RSA)
+WOLFSSL_RSA* wolfSSL_RSAPublicKey_dup(WOLFSSL_RSA *rsa)
+{
+    int derSz = 0;
+    byte *derBuf = NULL;
+    WOLFSSL_RSA* local;
+
+    WOLFSSL_ENTER("wolfSSL_RSAPublicKey_dup");
+
+    if (!rsa) {
+        return NULL;
+    }
+
+    local = wolfSSL_RSA_new();
+    if (local == NULL) {
+        WOLFSSL_MSG("Error creating a new WOLFSSL_RSA structure");
+        return NULL;
+    }
+
+    if ((derSz = wolfSSL_RSA_To_Der(rsa, &derBuf, 1)) < 0) {
+        WOLFSSL_MSG("wolfSSL_RSA_To_Der failed");
+        return NULL;
+    }
+
+    if (wolfSSL_RSA_LoadDer_ex(local,
+                derBuf, derSz,
+                WOLFSSL_RSA_LOAD_PUBLIC) != SSL_SUCCESS) {
+        wolfSSL_RSA_free(local);
+        local = NULL;
+    }
+    XFREE(derBuf, NULL, DYNAMIC_TYPE_ASN1);
+    return local;
+}
+#endif
+
+void* wolfSSL_RSA_get_ex_data(const WOLFSSL_RSA *rsa, int idx)
+{
+    WOLFSSL_ENTER("wolfSSL_RSA_get_ex_data");
+#ifdef HAVE_EX_DATA
+    if (rsa) {
+        return wolfSSL_CRYPTO_get_ex_data(&rsa->ex_data, idx);
+    }
+#else
+    (void)rsa;
+    (void)idx;
+#endif
+    return NULL;
+}
+
+int wolfSSL_RSA_set_ex_data(WOLFSSL_RSA *rsa, int idx, void *data)
+{
+    WOLFSSL_ENTER("wolfSSL_RSA_set_ex_data");
+    #ifdef HAVE_EX_DATA
+    if (rsa) {
+        return wolfSSL_CRYPTO_set_ex_data(&rsa->ex_data, idx, data);
+    }
+    #else
+    (void)rsa;
+    (void)idx;
+    (void)data;
+    #endif
+    return WOLFSSL_FAILURE;
+}
+
+int wolfSSL_RSA_set0_key(WOLFSSL_RSA *r, WOLFSSL_BIGNUM *n, WOLFSSL_BIGNUM *e,
+                         WOLFSSL_BIGNUM *d)
+{
+    /* If the fields n and e in r are NULL, the corresponding input
+     * parameters MUST be non-NULL for n and e.  d may be
+     * left NULL (in case only the public key is used).
+     */
+    if ((!r->n && !n) || (!r->e && !e))
+        return 0;
+
+    if (n) {
+        wolfSSL_BN_free(r->n);
+        r->n = n;
+    }
+    if (e) {
+        wolfSSL_BN_free(r->e);
+        r->e = e;
+    }
+    if (d) {
+        wolfSSL_BN_clear_free(r->d);
+        r->d = d;
+    }
+
+    return 1;
+}
+#endif /* OPENSSL_EXTRA */
+#endif /* NO_RSA */
+
+#ifdef OPENSSL_EXTRA
+#ifndef NO_DSA
+/* return WOLFSSL_SUCCESS if success, WOLFSSL_FATAL_ERROR if error */
+int wolfSSL_DSA_LoadDer(WOLFSSL_DSA* dsa, const unsigned char* derBuf, int derSz)
+{
+    word32 idx = 0;
+    int    ret;
+
+    WOLFSSL_ENTER("wolfSSL_DSA_LoadDer");
+
+    if (dsa == NULL || dsa->internal == NULL || derBuf == NULL || derSz <= 0) {
+        WOLFSSL_MSG("Bad function arguments");
+        return WOLFSSL_FATAL_ERROR;
+    }
+
+    ret = DsaPrivateKeyDecode(derBuf, &idx, (DsaKey*)dsa->internal, derSz);
+    if (ret < 0) {
+        WOLFSSL_MSG("DsaPrivateKeyDecode failed");
+        return WOLFSSL_FATAL_ERROR;
+    }
+
+    if (SetDsaExternal(dsa) != WOLFSSL_SUCCESS) {
+        WOLFSSL_MSG("SetDsaExternal failed");
+        return WOLFSSL_FATAL_ERROR;
+    }
+
+    dsa->inSet = 1;
+
+    return WOLFSSL_SUCCESS;
+}
+
+/* Loads DSA key from DER buffer. opt = DSA_LOAD_PRIVATE or DSA_LOAD_PUBLIC.
+    returns 1 on success, or 0 on failure.  */
+int wolfSSL_DSA_LoadDer_ex(WOLFSSL_DSA* dsa, const unsigned char* derBuf,
+                                                            int derSz, int opt)
+{
+    word32 idx = 0;
+    int    ret;
+
+    WOLFSSL_ENTER("wolfSSL_DSA_LoadDer");
+
+    if (dsa == NULL || dsa->internal == NULL || derBuf == NULL || derSz <= 0) {
+        WOLFSSL_MSG("Bad function arguments");
+        return WOLFSSL_FATAL_ERROR;
+    }
+
+    if (opt == WOLFSSL_DSA_LOAD_PRIVATE) {
+        ret = DsaPrivateKeyDecode(derBuf, &idx, (DsaKey*)dsa->internal, derSz);
+    }
+    else {
+        ret = DsaPublicKeyDecode(derBuf, &idx, (DsaKey*)dsa->internal, derSz);
+    }
+
+    if (ret < 0 && opt == WOLFSSL_DSA_LOAD_PRIVATE) {
+        WOLFSSL_MSG("DsaPrivateKeyDecode failed");
+        return WOLFSSL_FATAL_ERROR;
+    }
+    else if (ret < 0 && opt == WOLFSSL_DSA_LOAD_PUBLIC) {
+        WOLFSSL_MSG("DsaPublicKeyDecode failed");
+        return WOLFSSL_FATAL_ERROR;
+    }
+
+    if (SetDsaExternal(dsa) != WOLFSSL_SUCCESS) {
+        WOLFSSL_MSG("SetDsaExternal failed");
+        return WOLFSSL_FATAL_ERROR;
+    }
+
+    dsa->inSet = 1;
+
+    return WOLFSSL_SUCCESS;
+}
+#endif /* !NO_DSA */
+
+#ifdef HAVE_ECC
+/* return WOLFSSL_SUCCESS if success, WOLFSSL_FATAL_ERROR if error */
+int wolfSSL_EC_KEY_LoadDer(WOLFSSL_EC_KEY* key, const unsigned char* derBuf,
+                           int derSz)
+{
+    return wolfSSL_EC_KEY_LoadDer_ex(key, derBuf, derSz,
+                                     WOLFSSL_EC_KEY_LOAD_PRIVATE);
+}
+
+int wolfSSL_EC_KEY_LoadDer_ex(WOLFSSL_EC_KEY* key, const unsigned char* derBuf,
+                              int derSz, int opt)
+{
+    word32 idx = 0;
+    int    ret;
+
+    WOLFSSL_ENTER("wolfSSL_EC_KEY_LoadDer");
+
+    if (key == NULL || key->internal == NULL || derBuf == NULL || derSz <= 0) {
+        WOLFSSL_MSG("Bad function arguments");
+        return WOLFSSL_FATAL_ERROR;
+    }
+
+    if (opt == WOLFSSL_EC_KEY_LOAD_PRIVATE) {
+        ret = wc_EccPrivateKeyDecode(derBuf, &idx, (ecc_key*)key->internal,
+                                     derSz);
+    }
+    else {
+        ret = wc_EccPublicKeyDecode(derBuf, &idx, (ecc_key*)key->internal,
+                                    derSz);
+    }
+    if (ret < 0) {
+        if (opt == WOLFSSL_EC_KEY_LOAD_PRIVATE) {
+            WOLFSSL_MSG("wc_EccPrivateKeyDecode failed");
+        }
+        else {
+            WOLFSSL_MSG("wc_EccPublicKeyDecode failed");
+        }
+        return WOLFSSL_FATAL_ERROR;
+    }
+
+    if (SetECKeyExternal(key) != WOLFSSL_SUCCESS) {
+        WOLFSSL_MSG("SetECKeyExternal failed");
+        return WOLFSSL_FATAL_ERROR;
+    }
+
+    key->inSet = 1;
+
+    return WOLFSSL_SUCCESS;
+}
+#endif /* HAVE_ECC */
+
+#if !defined(NO_DH) && (defined(WOLFSSL_QT) || defined(OPENSSL_ALL) || defined(WOLFSSL_OPENSSH))
+/* return WOLFSSL_SUCCESS if success, WOLFSSL_FATAL_ERROR if error */
+int wolfSSL_DH_LoadDer(WOLFSSL_DH* dh, const unsigned char* derBuf, int derSz)
+{
+    word32 idx = 0;
+    int    ret;
+
+    if (dh == NULL || dh->internal == NULL || derBuf == NULL || derSz <= 0) {
+        WOLFSSL_MSG("Bad function arguments");
+        return WOLFSSL_FATAL_ERROR;
+    }
+
+    ret = wc_DhKeyDecode(derBuf, &idx, (DhKey*)dh->internal, (word32)derSz);
+    if (ret < 0) {
+        WOLFSSL_MSG("wc_DhKeyDecode failed");
+        return WOLFSSL_FATAL_ERROR;
+    }
+
+    if (SetDhExternal(dh) != WOLFSSL_SUCCESS) {
+        WOLFSSL_MSG("SetDhExternal failed");
+        return WOLFSSL_FATAL_ERROR;
+    }
+
+    return WOLFSSL_SUCCESS;
+}
+#endif /* ! NO_DH && WOLFSSL_QT || OPENSSL_ALL */
+
+#endif /* OPENSSL_EXTRA */
+
+
+#if defined(OPENSSL_EXTRA) || defined(OPENSSL_ALL)
+
+/* increments ref count of WOLFSSL_RSA. Return 1 on success, 0 on error */
+int wolfSSL_RSA_up_ref(WOLFSSL_RSA* rsa)
+{
+    if (rsa) {
+        if (wc_LockMutex(&rsa->refMutex) != 0) {
+            WOLFSSL_MSG("Failed to lock x509 mutex");
+        }
+        rsa->refCount++;
+        wc_UnLockMutex(&rsa->refMutex);
+
+        return 1;
+    }
+
+    return 0;
+}
+
+/* increments ref count of WOLFSSL_X509. Return 1 on success, 0 on error */
+int wolfSSL_X509_up_ref(WOLFSSL_X509* x509)
+{
+    if (x509) {
+        if (wc_LockMutex(&x509->refMutex) != 0) {
+            WOLFSSL_MSG("Failed to lock x509 mutex");
+        }
+        x509->refCount++;
+        wc_UnLockMutex(&x509->refMutex);
+
+        return 1;
+    }
+
+    return 0;
+}
+
+#endif /* OPENSSL_EXTRA || OPENSSL_ALL */
+
+
+#ifdef WOLFSSL_ALT_CERT_CHAINS
+int wolfSSL_is_peer_alt_cert_chain(const WOLFSSL* ssl)
+{
+    int isUsing = 0;
+    if (ssl)
+        isUsing = ssl->options.usingAltCertChain;
+    return isUsing;
+}
+#endif /* WOLFSSL_ALT_CERT_CHAINS */
+
+
+#ifdef SESSION_CERTS
+
+#ifdef WOLFSSL_ALT_CERT_CHAINS
+/* Get peer's alternate certificate chain */
+WOLFSSL_X509_CHAIN* wolfSSL_get_peer_alt_chain(WOLFSSL* ssl)
+{
+    WOLFSSL_ENTER("wolfSSL_get_peer_alt_chain");
+    if (ssl)
+        return &ssl->session.altChain;
+
+    return 0;
+}
+#endif /* WOLFSSL_ALT_CERT_CHAINS */
+
+
+/* Get peer's certificate chain */
+WOLFSSL_X509_CHAIN* wolfSSL_get_peer_chain(WOLFSSL* ssl)
+{
+    WOLFSSL_ENTER("wolfSSL_get_peer_chain");
+    if (ssl)
+        return &ssl->session.chain;
+
+    return 0;
+}
+
+
+/* Get peer's certificate chain total count */
+int wolfSSL_get_chain_count(WOLFSSL_X509_CHAIN* chain)
+{
+    WOLFSSL_ENTER("wolfSSL_get_chain_count");
+    if (chain)
+        return chain->count;
+
+    return 0;
+}
+
+
+/* Get peer's ASN.1 DER certificate at index (idx) length in bytes */
+int wolfSSL_get_chain_length(WOLFSSL_X509_CHAIN* chain, int idx)
+{
+    WOLFSSL_ENTER("wolfSSL_get_chain_length");
+    if (chain)
+        return chain->certs[idx].length;
+
+    return 0;
+}
+
+
+/* Get peer's ASN.1 DER certificate at index (idx) */
+byte* wolfSSL_get_chain_cert(WOLFSSL_X509_CHAIN* chain, int idx)
+{
+    WOLFSSL_ENTER("wolfSSL_get_chain_cert");
+    if (chain)
+        return chain->certs[idx].buffer;
+
+    return 0;
+}
+
+
+/* Get peer's wolfSSL X509 certificate at index (idx) */
+WOLFSSL_X509* wolfSSL_get_chain_X509(WOLFSSL_X509_CHAIN* chain, int idx)
+{
+    int          ret;
+    WOLFSSL_X509* x509 = NULL;
+#ifdef WOLFSSL_SMALL_STACK
+    DecodedCert* cert = NULL;
+#else
+    DecodedCert  cert[1];
+#endif
+
+    WOLFSSL_ENTER("wolfSSL_get_chain_X509");
+    if (chain != NULL) {
+    #ifdef WOLFSSL_SMALL_STACK
+        cert = (DecodedCert*)XMALLOC(sizeof(DecodedCert), NULL,
+                                                       DYNAMIC_TYPE_DCERT);
+        if (cert != NULL)
+    #endif
+        {
+            InitDecodedCert(cert, chain->certs[idx].buffer,
+                                  chain->certs[idx].length, NULL);
+
+            if ((ret = ParseCertRelative(cert, CERT_TYPE, 0, NULL)) != 0) {
+                WOLFSSL_MSG("Failed to parse cert");
+            }
+            else {
+                x509 = (WOLFSSL_X509*)XMALLOC(sizeof(WOLFSSL_X509), NULL,
+                                                             DYNAMIC_TYPE_X509);
+                if (x509 == NULL) {
+                    WOLFSSL_MSG("Failed alloc X509");
+                }
+                else {
+                    InitX509(x509, 1, NULL);
+
+                    if ((ret = CopyDecodedToX509(x509, cert)) != 0) {
+                        WOLFSSL_MSG("Failed to copy decoded");
+                        wolfSSL_X509_free(x509);
+                        x509 = NULL;
+                    }
+                }
+            }
+
+            FreeDecodedCert(cert);
+        #ifdef WOLFSSL_SMALL_STACK
+            XFREE(cert, NULL, DYNAMIC_TYPE_DCERT);
+        #endif
+        }
+    }
+    (void)ret;
+
+    return x509;
+}
+
+
+/* Get peer's PEM certificate at index (idx), output to buffer if inLen big
+   enough else return error (-1). If buffer is NULL only calculate
+   outLen. Output length is in *outLen WOLFSSL_SUCCESS on ok */
+int  wolfSSL_get_chain_cert_pem(WOLFSSL_X509_CHAIN* chain, int idx,
+                               unsigned char* buf, int inLen, int* outLen)
+{
+#if defined(WOLFSSL_PEM_TO_DER) || defined(WOLFSSL_DER_TO_PEM)
+    const char* header = NULL;
+    const char* footer = NULL;
+    int headerLen;
+    int footerLen;
+    int i;
+    int err;
+    word32 szNeeded = 0;
+
+    WOLFSSL_ENTER("wolfSSL_get_chain_cert_pem");
+    if (!chain || !outLen || idx < 0 || idx >= wolfSSL_get_chain_count(chain))
+        return BAD_FUNC_ARG;
+
+    err = wc_PemGetHeaderFooter(CERT_TYPE, &header, &footer);
+    if (err != 0)
+        return err;
+
+    headerLen = (int)XSTRLEN(header);
+    footerLen = (int)XSTRLEN(footer);
+
+    /* Null output buffer return size needed in outLen */
+    if(!buf) {
+        if(Base64_Encode(chain->certs[idx].buffer, chain->certs[idx].length,
+                    NULL, &szNeeded) != LENGTH_ONLY_E)
+            return WOLFSSL_FAILURE;
+        *outLen = szNeeded + headerLen + footerLen;
+        return LENGTH_ONLY_E;
+    }
+
+    /* don't even try if inLen too short */
+    if (inLen < headerLen + footerLen + chain->certs[idx].length)
+        return BAD_FUNC_ARG;
+
+    /* header */
+    if (XMEMCPY(buf, header, headerLen) == NULL)
+        return WOLFSSL_FATAL_ERROR;
+
+    i = headerLen;
+
+    /* body */
+    *outLen = inLen;  /* input to Base64_Encode */
+    if ( (err = Base64_Encode(chain->certs[idx].buffer,
+                       chain->certs[idx].length, buf + i, (word32*)outLen)) < 0)
+        return err;
+    i += *outLen;
+
+    /* footer */
+    if ( (i + footerLen) > inLen)
+        return BAD_FUNC_ARG;
+    if (XMEMCPY(buf + i, footer, footerLen) == NULL)
+        return WOLFSSL_FATAL_ERROR;
+    *outLen += headerLen + footerLen;
+
+    return WOLFSSL_SUCCESS;
+#else
+    (void)chain;
+    (void)idx;
+    (void)buf;
+    (void)inLen;
+    (void)outLen;
+    return WOLFSSL_FAILURE;
+#endif /* WOLFSSL_PEM_TO_DER || WOLFSSL_DER_TO_PEM */
+}
+
+
+/* get session ID */
+WOLFSSL_ABI
+const byte* wolfSSL_get_sessionID(const WOLFSSL_SESSION* session)
+{
+    WOLFSSL_ENTER("wolfSSL_get_sessionID");
+    if (session)
+        return session->sessionID;
+
+    return NULL;
+}
+
+
+#endif /* SESSION_CERTS */
+
+#ifdef HAVE_FUZZER
+void wolfSSL_SetFuzzerCb(WOLFSSL* ssl, CallbackFuzzer cbf, void* fCtx)
+{
+    if (ssl) {
+        ssl->fuzzerCb  = cbf;
+        ssl->fuzzerCtx = fCtx;
+    }
+}
+#endif
+
+#ifndef NO_CERTS
+#ifdef  HAVE_PK_CALLBACKS
+
+#ifdef HAVE_ECC
+void  wolfSSL_CTX_SetEccKeyGenCb(WOLFSSL_CTX* ctx, CallbackEccKeyGen cb)
+{
+    if (ctx)
+        ctx->EccKeyGenCb = cb;
+}
+void  wolfSSL_SetEccKeyGenCtx(WOLFSSL* ssl, void *ctx)
+{
+    if (ssl)
+        ssl->EccKeyGenCtx = ctx;
+}
+void* wolfSSL_GetEccKeyGenCtx(WOLFSSL* ssl)
+{
+    if (ssl)
+        return ssl->EccKeyGenCtx;
+
+    return NULL;
+}
+
+WOLFSSL_ABI
+void  wolfSSL_CTX_SetEccSignCb(WOLFSSL_CTX* ctx, CallbackEccSign cb)
+{
+    if (ctx)
+        ctx->EccSignCb = cb;
+}
+void  wolfSSL_SetEccSignCtx(WOLFSSL* ssl, void *ctx)
+{
+    if (ssl)
+        ssl->EccSignCtx = ctx;
+}
+void* wolfSSL_GetEccSignCtx(WOLFSSL* ssl)
+{
+    if (ssl)
+        return ssl->EccSignCtx;
+
+    return NULL;
+}
+
+void  wolfSSL_CTX_SetEccVerifyCb(WOLFSSL_CTX* ctx, CallbackEccVerify cb)
+{
+    if (ctx)
+        ctx->EccVerifyCb = cb;
+}
+void  wolfSSL_SetEccVerifyCtx(WOLFSSL* ssl, void *ctx)
+{
+    if (ssl)
+        ssl->EccVerifyCtx = ctx;
+}
+void* wolfSSL_GetEccVerifyCtx(WOLFSSL* ssl)
+{
+    if (ssl)
+        return ssl->EccVerifyCtx;
+
+    return NULL;
+}
+
+void wolfSSL_CTX_SetEccSharedSecretCb(WOLFSSL_CTX* ctx, CallbackEccSharedSecret cb)
+{
+    if (ctx)
+        ctx->EccSharedSecretCb = cb;
+}
+void  wolfSSL_SetEccSharedSecretCtx(WOLFSSL* ssl, void *ctx)
+{
+    if (ssl)
+        ssl->EccSharedSecretCtx = ctx;
+}
+void* wolfSSL_GetEccSharedSecretCtx(WOLFSSL* ssl)
+{
+    if (ssl)
+        return ssl->EccSharedSecretCtx;
+
+    return NULL;
+}
+#endif /* HAVE_ECC */
+
+#ifdef HAVE_ED25519
+void  wolfSSL_CTX_SetEd25519SignCb(WOLFSSL_CTX* ctx, CallbackEd25519Sign cb)
+{
+    if (ctx)
+        ctx->Ed25519SignCb = cb;
+}
+void  wolfSSL_SetEd25519SignCtx(WOLFSSL* ssl, void *ctx)
+{
+    if (ssl)
+        ssl->Ed25519SignCtx = ctx;
+}
+void* wolfSSL_GetEd25519SignCtx(WOLFSSL* ssl)
+{
+    if (ssl)
+        return ssl->Ed25519SignCtx;
+
+    return NULL;
+}
+
+void  wolfSSL_CTX_SetEd25519VerifyCb(WOLFSSL_CTX* ctx, CallbackEd25519Verify cb)
+{
+    if (ctx)
+        ctx->Ed25519VerifyCb = cb;
+}
+void  wolfSSL_SetEd25519VerifyCtx(WOLFSSL* ssl, void *ctx)
+{
+    if (ssl)
+        ssl->Ed25519VerifyCtx = ctx;
+}
+void* wolfSSL_GetEd25519VerifyCtx(WOLFSSL* ssl)
+{
+    if (ssl)
+        return ssl->Ed25519VerifyCtx;
+
+    return NULL;
+}
+#endif /* HAVE_ED25519 */
+
+#ifdef HAVE_CURVE25519
+void wolfSSL_CTX_SetX25519KeyGenCb(WOLFSSL_CTX* ctx,
+        CallbackX25519KeyGen cb)
+{
+    if (ctx)
+        ctx->X25519KeyGenCb = cb;
+}
+void  wolfSSL_SetX25519KeyGenCtx(WOLFSSL* ssl, void *ctx)
+{
+    if (ssl)
+        ssl->X25519KeyGenCtx = ctx;
+}
+void* wolfSSL_GetX25519KeyGenCtx(WOLFSSL* ssl)
+{
+    if (ssl)
+        return ssl->X25519KeyGenCtx;
+
+    return NULL;
+}
+
+void wolfSSL_CTX_SetX25519SharedSecretCb(WOLFSSL_CTX* ctx,
+        CallbackX25519SharedSecret cb)
+{
+    if (ctx)
+        ctx->X25519SharedSecretCb = cb;
+}
+void  wolfSSL_SetX25519SharedSecretCtx(WOLFSSL* ssl, void *ctx)
+{
+    if (ssl)
+        ssl->X25519SharedSecretCtx = ctx;
+}
+void* wolfSSL_GetX25519SharedSecretCtx(WOLFSSL* ssl)
+{
+    if (ssl)
+        return ssl->X25519SharedSecretCtx;
+
+    return NULL;
+}
+#endif /* HAVE_CURVE25519 */
+
+#ifdef HAVE_ED448
+void  wolfSSL_CTX_SetEd448SignCb(WOLFSSL_CTX* ctx, CallbackEd448Sign cb)
+{
+    if (ctx)
+        ctx->Ed448SignCb = cb;
+}
+void  wolfSSL_SetEd448SignCtx(WOLFSSL* ssl, void *ctx)
+{
+    if (ssl)
+        ssl->Ed448SignCtx = ctx;
+}
+void* wolfSSL_GetEd448SignCtx(WOLFSSL* ssl)
+{
+    if (ssl)
+        return ssl->Ed448SignCtx;
+
+    return NULL;
+}
+
+void  wolfSSL_CTX_SetEd448VerifyCb(WOLFSSL_CTX* ctx, CallbackEd448Verify cb)
+{
+    if (ctx)
+        ctx->Ed448VerifyCb = cb;
+}
+void  wolfSSL_SetEd448VerifyCtx(WOLFSSL* ssl, void *ctx)
+{
+    if (ssl)
+        ssl->Ed448VerifyCtx = ctx;
+}
+void* wolfSSL_GetEd448VerifyCtx(WOLFSSL* ssl)
+{
+    if (ssl)
+        return ssl->Ed448VerifyCtx;
+
+    return NULL;
+}
+#endif /* HAVE_ED448 */
+
+#ifdef HAVE_CURVE448
+void wolfSSL_CTX_SetX448KeyGenCb(WOLFSSL_CTX* ctx,
+        CallbackX448KeyGen cb)
+{
+    if (ctx)
+        ctx->X448KeyGenCb = cb;
+}
+void  wolfSSL_SetX448KeyGenCtx(WOLFSSL* ssl, void *ctx)
+{
+    if (ssl)
+        ssl->X448KeyGenCtx = ctx;
+}
+void* wolfSSL_GetX448KeyGenCtx(WOLFSSL* ssl)
+{
+    if (ssl)
+        return ssl->X448KeyGenCtx;
+
+    return NULL;
+}
+
+void wolfSSL_CTX_SetX448SharedSecretCb(WOLFSSL_CTX* ctx,
+        CallbackX448SharedSecret cb)
+{
+    if (ctx)
+        ctx->X448SharedSecretCb = cb;
+}
+void  wolfSSL_SetX448SharedSecretCtx(WOLFSSL* ssl, void *ctx)
+{
+    if (ssl)
+        ssl->X448SharedSecretCtx = ctx;
+}
+void* wolfSSL_GetX448SharedSecretCtx(WOLFSSL* ssl)
+{
+    if (ssl)
+        return ssl->X448SharedSecretCtx;
+
+    return NULL;
+}
+#endif /* HAVE_CURVE448 */
+
+#ifndef NO_RSA
+void  wolfSSL_CTX_SetRsaSignCb(WOLFSSL_CTX* ctx, CallbackRsaSign cb)
+{
+    if (ctx)
+        ctx->RsaSignCb = cb;
+}
+void  wolfSSL_CTX_SetRsaSignCheckCb(WOLFSSL_CTX* ctx, CallbackRsaVerify cb)
+{
+    if (ctx)
+        ctx->RsaSignCheckCb = cb;
+}
+void  wolfSSL_SetRsaSignCtx(WOLFSSL* ssl, void *ctx)
+{
+    if (ssl)
+        ssl->RsaSignCtx = ctx;
+}
+void* wolfSSL_GetRsaSignCtx(WOLFSSL* ssl)
+{
+    if (ssl)
+        return ssl->RsaSignCtx;
+
+    return NULL;
+}
+
+
+void  wolfSSL_CTX_SetRsaVerifyCb(WOLFSSL_CTX* ctx, CallbackRsaVerify cb)
+{
+    if (ctx)
+        ctx->RsaVerifyCb = cb;
+}
+void  wolfSSL_SetRsaVerifyCtx(WOLFSSL* ssl, void *ctx)
+{
+    if (ssl)
+        ssl->RsaVerifyCtx = ctx;
+}
+void* wolfSSL_GetRsaVerifyCtx(WOLFSSL* ssl)
+{
+    if (ssl)
+        return ssl->RsaVerifyCtx;
+
+    return NULL;
+}
+
+#ifdef WC_RSA_PSS
+void  wolfSSL_CTX_SetRsaPssSignCb(WOLFSSL_CTX* ctx, CallbackRsaPssSign cb)
+{
+    if (ctx)
+        ctx->RsaPssSignCb = cb;
+}
+void  wolfSSL_CTX_SetRsaPssSignCheckCb(WOLFSSL_CTX* ctx, CallbackRsaPssVerify cb)
+{
+    if (ctx)
+        ctx->RsaPssSignCheckCb = cb;
+}
+void  wolfSSL_SetRsaPssSignCtx(WOLFSSL* ssl, void *ctx)
+{
+    if (ssl)
+        ssl->RsaPssSignCtx = ctx;
+}
+void* wolfSSL_GetRsaPssSignCtx(WOLFSSL* ssl)
+{
+    if (ssl)
+        return ssl->RsaPssSignCtx;
+
+    return NULL;
+}
+
+void  wolfSSL_CTX_SetRsaPssVerifyCb(WOLFSSL_CTX* ctx, CallbackRsaPssVerify cb)
+{
+    if (ctx)
+        ctx->RsaPssVerifyCb = cb;
+}
+void  wolfSSL_SetRsaPssVerifyCtx(WOLFSSL* ssl, void *ctx)
+{
+    if (ssl)
+        ssl->RsaPssVerifyCtx = ctx;
+}
+void* wolfSSL_GetRsaPssVerifyCtx(WOLFSSL* ssl)
+{
+    if (ssl)
+        return ssl->RsaPssVerifyCtx;
+
+    return NULL;
+}
+#endif /* WC_RSA_PSS */
+
+void  wolfSSL_CTX_SetRsaEncCb(WOLFSSL_CTX* ctx, CallbackRsaEnc cb)
+{
+    if (ctx)
+        ctx->RsaEncCb = cb;
+}
+void  wolfSSL_SetRsaEncCtx(WOLFSSL* ssl, void *ctx)
+{
+    if (ssl)
+        ssl->RsaEncCtx = ctx;
+}
+void* wolfSSL_GetRsaEncCtx(WOLFSSL* ssl)
+{
+    if (ssl)
+        return ssl->RsaEncCtx;
+
+    return NULL;
+}
+
+void  wolfSSL_CTX_SetRsaDecCb(WOLFSSL_CTX* ctx, CallbackRsaDec cb)
+{
+    if (ctx)
+        ctx->RsaDecCb = cb;
+}
+void  wolfSSL_SetRsaDecCtx(WOLFSSL* ssl, void *ctx)
+{
+    if (ssl)
+        ssl->RsaDecCtx = ctx;
+}
+void* wolfSSL_GetRsaDecCtx(WOLFSSL* ssl)
+{
+    if (ssl)
+        return ssl->RsaDecCtx;
+
+    return NULL;
+}
+#endif /* NO_RSA */
+
+#endif /* HAVE_PK_CALLBACKS */
+#endif /* NO_CERTS */
+
+#if defined(HAVE_PK_CALLBACKS) && !defined(NO_DH)
+void wolfSSL_CTX_SetDhAgreeCb(WOLFSSL_CTX* ctx, CallbackDhAgree cb)
+{
+    if (ctx)
+        ctx->DhAgreeCb = cb;
+}
+void wolfSSL_SetDhAgreeCtx(WOLFSSL* ssl, void *ctx)
+{
+    if (ssl)
+        ssl->DhAgreeCtx = ctx;
+}
+void* wolfSSL_GetDhAgreeCtx(WOLFSSL* ssl)
+{
+    if (ssl)
+        return ssl->DhAgreeCtx;
+
+    return NULL;
+}
+#endif /* HAVE_PK_CALLBACKS && !NO_DH */
+
+
+#ifdef WOLFSSL_HAVE_WOLFSCEP
+    /* Used by autoconf to see if wolfSCEP is available */
+    void wolfSSL_wolfSCEP(void) {}
+#endif
+
+
+#ifdef WOLFSSL_HAVE_CERT_SERVICE
+    /* Used by autoconf to see if cert service is available */
+    void wolfSSL_cert_service(void) {}
+#endif
+
+#ifdef OPENSSL_EXTRA
+    #ifndef NO_CERTS
+    void wolfSSL_X509_NAME_free(WOLFSSL_X509_NAME *name)
+    {
+        WOLFSSL_ENTER("wolfSSL_X509_NAME_free");
+        FreeX509Name(name, NULL);
+        XFREE(name, NULL, DYNAMIC_TYPE_X509);
+    }
+
+
+    /* Malloc's a new WOLFSSL_X509_NAME structure
+     *
+     * returns NULL on failure, otherwise returns a new structure.
+     */
+    WOLFSSL_X509_NAME* wolfSSL_X509_NAME_new(void)
+    {
+        WOLFSSL_X509_NAME* name;
+
+        WOLFSSL_ENTER("wolfSSL_X509_NAME_new");
+
+        name = (WOLFSSL_X509_NAME*)XMALLOC(sizeof(WOLFSSL_X509_NAME), NULL,
+                DYNAMIC_TYPE_X509);
+        if (name != NULL) {
+            InitX509Name(name, 1);
+        }
+        return name;
+    }
+
+    /* Creates a duplicate of a WOLFSSL_X509_NAME structure.
+       Returns a new WOLFSSL_X509_NAME structure or NULL on failure */
+    WOLFSSL_X509_NAME* wolfSSL_X509_NAME_dup(WOLFSSL_X509_NAME *name)
+    {
+        WOLFSSL_X509_NAME* dup = NULL;
+
+        WOLFSSL_ENTER("wolfSSL_X509_NAME_dup");
+
+        if (name == NULL) {
+            WOLFSSL_MSG("NULL parameter");
+            return NULL;
+        }
+
+        if (!(dup = wolfSSL_X509_NAME_new())) {
+            return NULL;
+        }
+
+        /* copy contents */
+        XMEMCPY(dup, name, sizeof(WOLFSSL_X509_NAME));
+        InitX509Name(dup, 1);
+        dup->sz = name->sz;
+
+        /* handle dynamic portions */
+        if (name->dynamicName) {
+            if (!(dup->name = (char*)XMALLOC(name->sz, 0,
+                                             DYNAMIC_TYPE_OPENSSL))) {
+                goto err;
+            }
+        }
+        XMEMCPY(dup->name, name->name, name->sz);
+    #if (defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)) && \
+        !defined(NO_ASN)
+        if (!(dup->fullName.fullName = (char*)XMALLOC(name->fullName.fullNameLen,
+                                                   0, DYNAMIC_TYPE_OPENSSL))) {
+            goto err;
+        }
+        XMEMCPY(dup->fullName.fullName, name->fullName.fullName,
+            name->fullName.fullNameLen);
+    #endif
+
+        return dup;
+
+    err:
+        if (dup) {
+            if (dup->dynamicName && dup->name) {
+                XFREE(dup->name, 0, DYNAMIC_TYPE_OPENSSL);
+                dup->name = NULL;
+            }
+        #if (defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)) && \
+            !defined(NO_ASN)
+            if (dup->fullName.fullName &&
+                dup->fullName.fullName != name->fullName.fullName) {
+                XFREE(dup->fullName.fullName, 0, DYNAMIC_TYPE_OPENSSL);
+                dup->fullName.fullName = NULL;
+            }
+        #endif
+            wolfSSL_X509_NAME_free(dup);
+        }
+        return NULL;
+    }
+
+#if defined(WOLFSSL_CERT_GEN)
+    /* helper function for CopyX509NameToCertName()
+     *
+     * returns WOLFSSL_SUCCESS on success
+     */
+    static int CopyX509NameEntry(char* out, int mx, char* in, int inLen)
+    {
+        if (inLen > mx) {
+            WOLFSSL_MSG("Name too long");
+            XMEMCPY(out, in, mx);
+        }
+        else {
+            XMEMCPY(out, in, inLen);
+            out[inLen] = '\0';
+        }
+
+        /* make sure is null terminated */
+        out[mx-1] = '\0';
+
+        return WOLFSSL_SUCCESS;
+    }
+
+
+    /* Helper function to copy cert name from a WOLFSSL_X509_NAME structure to
+     * a CertName structure.
+     *
+     * returns WOLFSSL_SUCCESS on success and a negative error value on failure
+     */
+    static int CopyX509NameToCertName(WOLFSSL_X509_NAME* n, CertName* cName)
+    {
+        DecodedName* dn = NULL;
+
+        if (n == NULL || cName == NULL) {
+            return BAD_FUNC_ARG;
+        }
+
+        dn = &(n->fullName);
+
+        /* initialize cert name */
+        cName->country[0] = '\0';
+        cName->countryEnc = CTC_PRINTABLE;
+        cName->state[0] = '\0';
+        cName->stateEnc = CTC_UTF8;
+        cName->locality[0] = '\0';
+        cName->localityEnc = CTC_UTF8;
+        cName->sur[0] = '\0';
+        cName->surEnc = CTC_UTF8;
+        cName->org[0] = '\0';
+        cName->orgEnc = CTC_UTF8;
+        cName->unit[0] = '\0';
+        cName->unitEnc = CTC_UTF8;
+        cName->commonName[0] = '\0';
+        cName->commonNameEnc = CTC_UTF8;
+        cName->serialDev[0] = '\0';
+        cName->serialDevEnc = CTC_PRINTABLE;
+    #ifdef WOLFSSL_CERT_EXT
+        cName->busCat[0] = '\0';
+        cName->busCatEnc = CTC_UTF8;
+        cName->joiC[0] = '\0';
+        cName->joiCEnc = CTC_PRINTABLE;
+        cName->joiSt[0] = '\0';
+        cName->joiStEnc = CTC_PRINTABLE;
+    #endif
+        cName->email[0] = '\0';
+
+
+        /* ASN_COUNTRY_NAME */
+        WOLFSSL_MSG("Copy Country Name");
+        if (CopyX509NameEntry(cName->country, CTC_NAME_SIZE, dn->fullName + dn->cIdx,
+                    dn->cLen) != SSL_SUCCESS) {
+            return BUFFER_E;
+        }
+
+        /* ASN_ORGUNIT_NAME */
+        WOLFSSL_MSG("Copy Org Unit Name");
+        if (CopyX509NameEntry(cName->unit, CTC_NAME_SIZE, dn->fullName + dn->ouIdx,
+                    dn->ouLen) != SSL_SUCCESS) {
+            return BUFFER_E;
+        }
+
+        /* ASN_ORG_NAME */
+        WOLFSSL_MSG("Copy Org Name");
+        if (CopyX509NameEntry(cName->org, CTC_NAME_SIZE, dn->fullName + dn->oIdx,
+                    dn->oLen) != SSL_SUCCESS) {
+            return BUFFER_E;
+        }
+
+        /* ASN_STATE_NAME */
+        WOLFSSL_MSG("Copy State Name");
+        if (CopyX509NameEntry(cName->state, CTC_NAME_SIZE, dn->fullName + dn->stIdx,
+                    dn->stLen) != SSL_SUCCESS) {
+            return BUFFER_E;
+        }
+
+        /* ASN_LOCALITY_NAME */
+        WOLFSSL_MSG("Copy Locality Name");
+        if (CopyX509NameEntry(cName->locality, CTC_NAME_SIZE,
+                    dn->fullName + dn->lIdx, dn->lLen)
+                    != SSL_SUCCESS) {
+            return BUFFER_E;
+        }
+
+        /* ASN_SUR_NAME */
+        WOLFSSL_MSG("Copy Sur Name");
+        if (CopyX509NameEntry(cName->sur, CTC_NAME_SIZE, dn->fullName + dn->snIdx,
+                    dn->snLen) != SSL_SUCCESS) {
+            return BUFFER_E;
+        }
+
+        /* ASN_COMMON_NAME */
+        WOLFSSL_MSG("Copy Common Name");
+        if (CopyX509NameEntry(cName->commonName, CTC_NAME_SIZE,
+                    dn->fullName + dn->cnIdx, dn->cnLen)
+                    != SSL_SUCCESS) {
+            return BUFFER_E;
+        }
+
+        /* ASN_SERIAL_NUMBER */
+        WOLFSSL_MSG("Copy Serial Number of Device");
+        if (CopyX509NameEntry(cName->serialDev, CTC_NAME_SIZE,
+                    dn->fullName + dn->serialIdx, dn->serialLen)
+                    != SSL_SUCCESS) {
+            return BUFFER_E;
+        }
+
+    #ifdef WOLFSSL_CERT_EXT
+        /* ASN_BUS_CAT */
+        WOLFSSL_MSG("Copy Business Category");
+        if (CopyX509NameEntry(cName->busCat, CTC_NAME_SIZE,
+                    dn->fullName + dn->bcIdx, dn->bcLen)
+                    != SSL_SUCCESS) {
+            return BUFFER_E;
+        }
+
+        /* JoI Country */
+        WOLFSSL_MSG("Copy Jurisdiction of Incorporation Country");
+        if (CopyX509NameEntry(cName->joiC, CTC_NAME_SIZE,
+                    dn->fullName + dn->jcIdx, dn->jcLen)
+                    != SSL_SUCCESS) {
+            return BUFFER_E;
+        }
+
+        /* JoI State */
+        WOLFSSL_MSG("Copy Jurisdiction of Incorporation State");
+        if (CopyX509NameEntry(cName->joiSt, CTC_NAME_SIZE,
+                    dn->fullName + dn->jsIdx, dn->jsLen)
+                    != SSL_SUCCESS) {
+            return BUFFER_E;
+        }
+    #endif
+
+        WOLFSSL_MSG("Copy Email");
+        if (CopyX509NameEntry(cName->email, CTC_NAME_SIZE,
+                    dn->fullName + dn->emailIdx, dn->emailLen)
+                    != SSL_SUCCESS) {
+            return BUFFER_E;
+        }
+
+        return WOLFSSL_SUCCESS;
+    }
+
+#ifdef WOLFSSL_CERT_REQ
+    static int ReqCertFromX509(Cert* cert, WOLFSSL_X509* req)
+    {
+        int ret;
+
+        if (wc_InitCert(cert) != 0)
+            return WOLFSSL_FAILURE;
+
+        ret = CopyX509NameToCertName(&req->subject, &cert->subject);
+        if (ret == WOLFSSL_SUCCESS) {
+            cert->version = req->version;
+            cert->isCA = req->isCa;
+#ifdef WOLFSSL_CERT_EXT
+            if (req->subjKeyIdSz != 0) {
+                XMEMCPY(cert->skid, req->subjKeyId, req->subjKeyIdSz);
+                cert->skidSz = req->subjKeyIdSz;
+            }
+            if (req->keyUsageSet)
+                cert->keyUsage = req->keyUsage;
+            /* Extended Key Usage not supported. */
+#endif
+        }
+
+        return ret;
+    }
+#endif
+
+    /* convert a WOLFSSL_X509 to a Cert structure for writing out */
+    static int CertFromX509(Cert* cert, WOLFSSL_X509* x509)
+    {
+        int ret;
+        #ifdef WOLFSSL_CERT_EXT
+        int i;
+        #endif
+
+        WOLFSSL_ENTER("wolfSSL_X509_to_Cert()");
+
+        if (x509 == NULL || cert == NULL) {
+            return BAD_FUNC_ARG;
+        }
+
+        wc_InitCert(cert);
+
+        cert->version = (int)wolfSSL_X509_get_version(x509);
+
+    #ifdef WOLFSSL_ALT_NAMES
+        if (x509->notBefore.length > 0) {
+            if ((x509->notBefore.length + 2) < CTC_DATE_SIZE) {
+                cert->beforeDate[0] = x509->notBefore.type;
+                cert->beforeDate[1] = x509->notBefore.length;
+                XMEMCPY(&cert->beforeDate[2], x509->notBefore.data,
+                        x509->notBefore.length);
+                cert->beforeDateSz = x509->notBefore.length + 2;
+            }
+            else {
+                WOLFSSL_MSG("Not before date too large");
+                return WOLFSSL_FAILURE;
+            }
+        }
+        else {
+            cert->beforeDateSz = 0;
+        }
+        if (x509->notAfter.length > 0) {
+            if ((x509->notAfter.length + 2) < CTC_DATE_SIZE) {
+                cert->afterDate[0] = x509->notAfter.type;
+                cert->afterDate[1] = x509->notAfter.length;
+                XMEMCPY(&cert->afterDate[2], x509->notAfter.data,
+                        x509->notAfter.length);
+                cert->afterDateSz = x509->notAfter.length + 2;
+            }
+            else {
+                WOLFSSL_MSG("Not after date too large");
+                return WOLFSSL_FAILURE;
+            }
+        }
+        else {
+            cert->afterDateSz = 0;
+        }
+
+        cert->altNamesSz = FlattenAltNames(cert->altNames,
+                sizeof(cert->altNames), x509->altNames);
+
+    #endif /* WOLFSSL_ALT_NAMES */
+
+        cert->sigType = wolfSSL_X509_get_signature_type(x509);
+        cert->keyType = x509->pubKeyOID;
+        cert->isCA    = wolfSSL_X509_get_isCA(x509);
+
+    #ifdef WOLFSSL_CERT_EXT
+        if (x509->subjKeyIdSz < CTC_MAX_SKID_SIZE) {
+            XMEMCPY(cert->skid, x509->subjKeyId, x509->subjKeyIdSz);
+            cert->skidSz = (int)x509->subjKeyIdSz;
+        }
+        else {
+            WOLFSSL_MSG("Subject Key ID too large");
+            return WOLFSSL_FAILURE;
+        }
+
+        if (x509->authKeyIdSz < CTC_MAX_AKID_SIZE) {
+            XMEMCPY(cert->akid, x509->authKeyId, x509->authKeyIdSz);
+            cert->akidSz = (int)x509->authKeyIdSz;
+        }
+        else {
+            WOLFSSL_MSG("Auth Key ID too large");
+            return WOLFSSL_FAILURE;
+        }
+
+        for (i = 0; i < x509->certPoliciesNb; i++) {
+            /* copy the smaller of MAX macros, by default they are currently equal*/
+            if ((int)CTC_MAX_CERTPOL_SZ <= (int)MAX_CERTPOL_SZ) {
+                XMEMCPY(cert->certPolicies[i], x509->certPolicies[i],
+                        CTC_MAX_CERTPOL_SZ);
+            }
+            else {
+                XMEMCPY(cert->certPolicies[i], x509->certPolicies[i],
+                        MAX_CERTPOL_SZ);
+            }
+        }
+        cert->certPoliciesNb = (word16)x509->certPoliciesNb;
+
+        cert->keyUsage = x509->keyUsage;
+    #endif /* WOLFSSL_CERT_EXT */
+
+    #ifdef WOLFSSL_CERT_REQ
+        /* copy over challenge password for REQ certs */
+        XMEMCPY(cert->challengePw, x509->challengePw, CTC_NAME_SIZE);
+    #endif
+
+        if (x509->serialSz <= CTC_SERIAL_SIZE) {
+            XMEMCPY(cert->serial, x509->serial, x509->serialSz);
+        }
+        else {
+            WOLFSSL_MSG("Serial size error");
+            return WOLFSSL_FAILURE;
+        }
+
+        /* copy over Name structures */
+        if (x509->issuerSet)
+            cert->selfSigned = 0;
+        if ((ret = CopyX509NameToCertName(&(x509->issuer), &(cert->issuer)))
+            != WOLFSSL_SUCCESS) {
+            WOLFSSL_MSG("Error copying over issuer names");
+            WOLFSSL_LEAVE("wolfSSL_X509_to_Cert()", ret);
+            return WOLFSSL_FAILURE;
+        }
+        if ((ret = CopyX509NameToCertName(&(x509->subject), &(cert->subject)))
+            != WOLFSSL_SUCCESS) {
+            WOLFSSL_MSG("Error copying over subject names");
+            WOLFSSL_LEAVE("wolfSSL_X509_to_Cert()", ret);
+            return WOLFSSL_FAILURE;
+        }
+
+        cert->heap = x509->heap;
+
+        return WOLFSSL_SUCCESS;
+    }
+
+
+    /* returns the sig type to use on success i.e CTC_SHAwRSA and WOLFSSL_FALURE
+     * on fail case */
+    static int wolfSSL_sigTypeFromPKEY(WOLFSSL_EVP_MD* md,
+            WOLFSSL_EVP_PKEY* pkey)
+    {
+        int hashType;
+        int sigType = WOLFSSL_FAILURE;
+
+        /* Convert key type and hash algorithm to a signature algorithm */
+        if (wolfSSL_EVP_get_hashinfo(md, &hashType, NULL) == WOLFSSL_FAILURE)
+            return WOLFSSL_FAILURE;
+
+
+        if (pkey->type == EVP_PKEY_RSA) {
+            switch (hashType) {
+                case WC_HASH_TYPE_SHA:
+                    sigType = CTC_SHAwRSA;
+                    break;
+                case WC_HASH_TYPE_SHA224:
+                    sigType = CTC_SHA224wRSA;
+                    break;
+                case WC_HASH_TYPE_SHA256:
+                    sigType = CTC_SHA256wRSA;
+                    break;
+                case WC_HASH_TYPE_SHA384:
+                    sigType = CTC_SHA384wRSA;
+                    break;
+                case WC_HASH_TYPE_SHA512:
+                    sigType = CTC_SHA512wRSA;
+                    break;
+                default:
+                    return WOLFSSL_FAILURE;
+            }
+        }
+        else if (pkey->type == EVP_PKEY_EC) {
+            switch (hashType) {
+                case WC_HASH_TYPE_SHA:
+                    sigType = CTC_SHAwECDSA;
+                    break;
+                case WC_HASH_TYPE_SHA224:
+                    sigType = CTC_SHA224wECDSA;
+                    break;
+                case WC_HASH_TYPE_SHA256:
+                    sigType = CTC_SHA256wECDSA;
+                    break;
+                case WC_HASH_TYPE_SHA384:
+                    sigType = CTC_SHA384wECDSA;
+                    break;
+                case WC_HASH_TYPE_SHA512:
+                    sigType = CTC_SHA512wECDSA;
+                    break;
+                default:
+                    return WOLFSSL_FAILURE;
+            }
+        }
+        else
+            return WOLFSSL_FAILURE;
+        return sigType;
+    }
+
+
+    /* generates DER buffer from WOLFSSL_X509
+     * If req == 1 then creates a request DER buffer
+     *
+     * updates derSz with certificate body size on success
+     * return WOLFSSL_SUCCESS on success
+     */
+    static int wolfSSL_X509_make_der(WOLFSSL_X509* x509, int req,
+            unsigned char* der, int* derSz)
+    {
+        int ret;
+        Cert cert;
+        void* key = NULL;
+        int type = -1;
+    #ifndef NO_RSA
+        RsaKey rsa;
+    #endif
+    #ifdef HAVE_ECC
+        ecc_key ecc;
+    #endif
+        WC_RNG rng;
+        word32 idx = 0;
+
+        if (x509 == NULL || der == NULL || derSz == NULL)
+            return BAD_FUNC_ARG;
+
+    #ifndef WOLFSSL_CERT_REQ
+        if (req) {
+            WOLFSSL_MSG("WOLFSSL_CERT_REQ needed for certificate request");
+            return WOLFSSL_FAILURE;
+        }
+    #endif
+
+    #ifdef WOLFSSL_CERT_REQ
+        if (req) {
+            if (ReqCertFromX509(&cert, x509) != WOLFSSL_SUCCESS)
+                return WOLFSSL_FAILURE;
+        }
+        else
+    #endif
+        {
+            /* Create a Cert that has the certificate fields. */
+            if (CertFromX509(&cert, x509) != WOLFSSL_SUCCESS)
+                return WOLFSSL_FAILURE;
+        }
+
+        /* Create a public key object from requests public key. */
+    #ifndef NO_RSA
+        if (x509->pubKeyOID == RSAk) {
+            type = RSA_TYPE;
+            ret = wc_InitRsaKey(&rsa, x509->heap);
+            if (ret != 0)
+                return ret;
+            ret = wc_RsaPublicKeyDecode(x509->pubKey.buffer, &idx, &rsa,
+                                                           x509->pubKey.length);
+            if (ret != 0) {
+                wc_FreeRsaKey(&rsa);
+                return ret;
+            }
+            key = (void*)&rsa;
+        }
+    #endif
+    #ifdef HAVE_ECC
+        if (x509->pubKeyOID == ECDSAk) {
+            type = ECC_TYPE;
+            ret = wc_ecc_init(&ecc);
+            if (ret != 0)
+                return ret;
+            ret = wc_EccPublicKeyDecode(x509->pubKey.buffer, &idx, &ecc,
+                                                           x509->pubKey.length);
+            if (ret != 0) {
+                wc_ecc_free(&ecc);
+                return ret;
+            }
+            key = (void*)&ecc;
+        }
+    #endif
+        if (key == NULL)
+            return WOLFSSL_FAILURE;
+
+        /* Make the body of the certificate request. */
+    #ifdef WOLFSSL_CERT_REQ
+        if (req) {
+            ret = wc_MakeCertReq_ex(&cert, der, *derSz, type, key);
+        }
+        else
+    #endif
+        {
+            ret = wc_InitRng(&rng);
+            if (ret != 0)
+                return WOLFSSL_FAILURE;
+
+            ret = wc_MakeCert_ex(&cert, der, *derSz, type, key, &rng);
+            wc_FreeRng(&rng);
+        }
+        if (ret < 0) {
+            return ret;
+        }
+
+        /* Dispose of the public key object. */
+    #ifndef NO_RSA
+        if (x509->pubKeyOID == RSAk)
+            wc_FreeRsaKey(&rsa);
+    #endif
+    #ifdef HAVE_ECC
+        if (x509->pubKeyOID == ECDSAk)
+            wc_ecc_free(&ecc);
+    #endif
+        *derSz = ret;
+
+        return WOLFSSL_SUCCESS;
+    }
+
+
+    /* signs a der buffer for the WOLFSSL_X509 structure using the PKEY and MD
+     * hash passed in
+     *
+     * WARNING: this free's and replaces the existing DER buffer in the
+     *          WOLFSSL_X509 with the newly signed buffer.
+     * returns size of signed buffer on success and negative values on fail
+     */
+    static int wolfSSL_X509_resign_cert(WOLFSSL_X509* x509, int req,
+            unsigned char* der, int derSz, int certBodySz, WOLFSSL_EVP_MD* md,
+            WOLFSSL_EVP_PKEY* pkey)
+    {
+        int ret;
+        void* key = NULL;
+        int type = -1;
+        int sigType;
+        WC_RNG rng;
+
+        sigType = wolfSSL_sigTypeFromPKEY(md, pkey);
+        if (sigType == WOLFSSL_FAILURE)
+            return WOLFSSL_FATAL_ERROR;
+
+
+        /* Get the private key object and type from pkey. */
+    #ifndef NO_RSA
+        if (pkey->type == EVP_PKEY_RSA) {
+            type = RSA_TYPE;
+            key = pkey->rsa->internal;
+        }
+    #endif
+    #ifdef HAVE_ECC
+        if (pkey->type == EVP_PKEY_EC) {
+            type = ECC_TYPE;
+            key = pkey->ecc->internal;
+        }
+    #endif
+
+        /* Sign the certificate request body. */
+        ret = wc_InitRng(&rng);
+        if (ret != 0)
+            return ret;
+        ret = wc_SignCert_ex(certBodySz, sigType, der, derSz, type, key, &rng);
+        wc_FreeRng(&rng);
+        if (ret < 0)
+            return ret;
+
+        /* Put in the new certificate encoding into the x509 object. */
+        FreeDer(&x509->derCert);
+        type = CERT_TYPE;
+    #ifdef WOLFSSL_REQ_CERT
+        if (req) {
+            type = CERTREQ_TYPE;
+        }
+    #endif
+
+        if (AllocDer(&x509->derCert, ret, type, NULL) != 0)
+            return WOLFSSL_FATAL_ERROR;
+        XMEMCPY(x509->derCert->buffer, der, ret);
+        x509->derCert->length = ret;
+
+        (void)req;
+        return ret;
+    }
+
+
+    /* returns the size of signature on success */
+    int wolfSSL_X509_sign(WOLFSSL_X509* x509, WOLFSSL_EVP_PKEY* pkey,
+            const WOLFSSL_EVP_MD* md)
+    {
+        int  ret;
+        byte der[4096]; /* @TODO dynamic set based on expected cert size */
+        int  derSz = sizeof(der);
+
+        WOLFSSL_ENTER("wolfSSL_X509_sign");
+
+        if (x509 == NULL || pkey == NULL || md == NULL)
+            return WOLFSSL_FAILURE;
+
+        x509->sigOID = wolfSSL_sigTypeFromPKEY((WOLFSSL_EVP_MD*)md, pkey);
+        if ((ret = wolfSSL_X509_make_der(x509, 0, der, &derSz)) !=
+                WOLFSSL_SUCCESS) {
+            WOLFSSL_MSG("Unable to make DER for X509");
+            WOLFSSL_LEAVE("wolfSSL_X509_sign", ret);
+            return WOLFSSL_FAILURE;
+        }
+
+        ret = wolfSSL_X509_resign_cert(x509, 0, der, sizeof(der), derSz,
+                (WOLFSSL_EVP_MD*)md, pkey);
+        if (ret <= 0) {
+            WOLFSSL_LEAVE("wolfSSL_X509_sign", ret);
+            return WOLFSSL_FAILURE;
+        }
+
+        return ret;
+    }
+
+
+    /* Converts the x509 name structure into DER format.
+     *
+     * out  pointer to either a pre setup buffer or a pointer to null for
+     *      creating a dynamic buffer. In the case that a pre-existing buffer is
+     *      used out will be incremented the size of the DER buffer on success.
+     *
+     * returns the size of the buffer on success, or negative value with failure
+     */
+    int wolfSSL_i2d_X509_NAME(WOLFSSL_X509_NAME* name, unsigned char** out)
+    {
+        CertName cName;
+        unsigned char buf[256]; /* ASN_MAX_NAME */
+        int sz;
+        WOLFSSL_ENTER("wolfSSL_i2d_X509_NAME");
+
+        if (out == NULL || name == NULL) {
+            return BAD_FUNC_ARG;
+        }
+        XMEMSET(&cName, 0, sizeof(CertName));
+
+        if (CopyX509NameToCertName(name, &cName) != SSL_SUCCESS) {
+            WOLFSSL_MSG("Error converting x509 name to internal CertName");
+            return SSL_FATAL_ERROR;
+        }
+
+        sz = SetName(buf, sizeof(buf), &cName);
+        if (sz < 0) {
+            return sz;
+        }
+
+        /* using buffer passed in */
+        if (*out != NULL) {
+            XMEMCPY(*out, buf, sz);
+            *out += sz;
+        }
+        else {
+            *out = (unsigned char*)XMALLOC(sz, NULL, DYNAMIC_TYPE_OPENSSL);
+            if (*out == NULL) {
+                return MEMORY_E;
+            }
+            XMEMCPY(*out, buf, sz);
+        }
+
+        return sz;
+    }
+#endif /* WOLFSSL_CERT_GEN */
+
+
+    /* Compares the two X509 names. If the size of x is larger then y then a
+     * positive value is returned if x is smaller a negative value is returned.
+     * In the case that the sizes are equal a the value of strcmp between the
+     * two names is returned.
+     *
+     * x First name for comparison
+     * y Second name to compare with x
+     */
+    int wolfSSL_X509_NAME_cmp(const WOLFSSL_X509_NAME* x,
+            const WOLFSSL_X509_NAME* y)
+    {
+        const char* _x;
+        const char* _y;
+        WOLFSSL_ENTER("wolfSSL_X509_NAME_cmp");
+
+        if (x == NULL || y == NULL) {
+            WOLFSSL_MSG("Bad argument passed in");
+            return -2;
+        }
+
+        if (x == y) {
+            return 0; /* match */
+        }
+
+        if (x->sz != y->sz) {
+            return x->sz - y->sz;
+        }
+
+        /*
+         * If the name member is not set or is immediately null terminated then
+         * compare the staticName member
+         */
+        _x = (x->name && *x->name) ? x->name : x->staticName;
+        _y = (y->name && *y->name) ? y->name : y->staticName;
+
+        return XSTRNCMP(_x, _y, x->sz); /* y sz is the same */
+    }
+
+
+    WOLFSSL_X509 *wolfSSL_PEM_read_bio_X509(WOLFSSL_BIO *bp, WOLFSSL_X509 **x,
+                                                 pem_password_cb *cb, void *u)
+    {
+        WOLFSSL_X509* x509 = NULL;
+#if defined(WOLFSSL_PEM_TO_DER) || defined(WOLFSSL_DER_TO_PEM)
+        unsigned char* pem = NULL;
+        int pemSz;
+        long  i = 0, l;
+        const char* footer = NULL;
+
+        WOLFSSL_ENTER("wolfSSL_PEM_read_bio_X509");
+
+        if (bp == NULL) {
+            WOLFSSL_LEAVE("wolfSSL_PEM_read_bio_X509", BAD_FUNC_ARG);
+            return NULL;
+        }
+
+        if ((l = wolfSSL_BIO_get_len(bp)) <= 0) {
+    #if defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX)
+            /* No certificate in buffer */
+            WOLFSSL_ERROR(ASN_NO_PEM_HEADER);
+    #endif
+            return NULL;
+        }
+
+        pem = (unsigned char*)XMALLOC(l, 0, DYNAMIC_TYPE_PEM);
+        if (pem == NULL)
+            return NULL;
+
+        i = 0;
+        if (wc_PemGetHeaderFooter(CERT_TYPE, NULL, &footer) != 0) {
+            XFREE(pem, 0, DYNAMIC_TYPE_PEM);
+            return NULL;
+        }
+
+        /* TODO: Inefficient
+         * reading in one byte at a time until see "END CERTIFICATE"
+         */
+        while ((l = wolfSSL_BIO_read(bp, (char *)&pem[i], 1)) == 1) {
+            i++;
+            if (i > 26 && XMEMCMP((char *)&pem[i-26], footer, 25) == 0) {
+                if (pem[i-1] == '\r') {
+                    /* found \r , Windows line ending is \r\n so try to read one
+                     * more byte for \n, ignoring return value */
+                    (void)wolfSSL_BIO_read(bp, (char *)&pem[i++], 1);
+                }
+                break;
+            }
+        }
+    #if defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX)
+        if (l == 0)
+            WOLFSSL_ERROR(ASN_NO_PEM_HEADER);
+    #endif
+        pemSz = (int)i;
+        x509 = wolfSSL_X509_load_certificate_buffer(pem, pemSz,
+                                                              WOLFSSL_FILETYPE_PEM);
+
+        if (x != NULL) {
+            *x = x509;
+        }
+
+        XFREE(pem, NULL, DYNAMIC_TYPE_PEM);
+
+#endif /* WOLFSSL_PEM_TO_DER || WOLFSSL_DER_TO_PEM */
+        (void)bp;
+        (void)x;
+        (void)cb;
+        (void)u;
+
+        return x509;
+    }
+
+    WOLFSSL_X509_CRL *wolfSSL_PEM_read_bio_X509_CRL(WOLFSSL_BIO *bp,
+            WOLFSSL_X509_CRL **x, pem_password_cb *cb, void *u)
+    {
+#if defined(WOLFSSL_PEM_TO_DER) && defined(HAVE_CRL)
+        unsigned char* pem = NULL;
+        int pemSz;
+        int derSz;
+        DerBuffer* der = NULL;
+        WOLFSSL_X509_CRL* crl = NULL;
+
+        if ((pemSz = wolfSSL_BIO_get_len(bp)) <= 0) {
+            goto err;
+        }
+
+        pem = (unsigned char*)XMALLOC(pemSz, 0, DYNAMIC_TYPE_PEM);
+        if (pem == NULL) {
+            goto err;
+        }
+
+        if (wolfSSL_BIO_read(bp, pem, pemSz) != pemSz) {
+            goto err;
+        }
+
+        if((PemToDer(pem, pemSz, CRL_TYPE, &der, NULL, NULL, NULL)) < 0) {
+            goto err;
+        }
+        derSz = der->length;
+        if((crl = wolfSSL_d2i_X509_CRL(x, der->buffer, derSz)) == NULL) {
+            goto err;
+        }
+
+err:
+        if(pem != NULL) {
+            XFREE(pem, 0, DYNAMIC_TYPE_PEM);
+        }
+        if(der != NULL) {
+            FreeDer(&der);
+        }
+
+        (void)cb;
+        (void)u;
+
+        return crl;
+#else
+        (void)bp;
+        (void)x;
+        (void)cb;
+        (void)u;
+
+        return NULL;
+#endif
+    }
+
+#if !defined(NO_FILESYSTEM)
+    static void* wolfSSL_PEM_read_X509_ex(XFILE fp, void **x,
+        pem_password_cb *cb, void *u, int type)
+    {
+        unsigned char* pem = NULL;
+        int pemSz;
+        long i = 0, l;
+        void *newx509;
+        int derSz;
+        DerBuffer* der = NULL;
+
+        WOLFSSL_ENTER("wolfSSL_PEM_read_X509");
+
+        if (fp == XBADFILE) {
+            WOLFSSL_LEAVE("wolfSSL_PEM_read_X509", BAD_FUNC_ARG);
+            return NULL;
+        }
+        /* Read cert from file */
+        i = XFTELL(fp);
+        if (i < 0) {
+            WOLFSSL_LEAVE("wolfSSL_PEM_read_X509", BAD_FUNC_ARG);
+            return NULL;
+        }
+
+        if (XFSEEK(fp, 0, XSEEK_END) != 0)
+            return NULL;
+        l = XFTELL(fp);
+        if (l < 0)
+            return NULL;
+        if (XFSEEK(fp, i, SEEK_SET) != 0)
+            return NULL;
+        pemSz = (int)(l - i);
+
+        /* check calculated length */
+        if (pemSz > MAX_WOLFSSL_FILE_SIZE || pemSz < 0) {
+            WOLFSSL_MSG("PEM_read_X509_ex file size error");
+            return NULL;
+        }
+
+        /* allocate pem buffer */
+        pem = (unsigned char*)XMALLOC(pemSz, NULL, DYNAMIC_TYPE_PEM);
+        if (pem == NULL)
+            return NULL;
+
+        if ((int)XFREAD((char *)pem, 1, pemSz, fp) != pemSz)
+            goto err_exit;
+
+        switch (type) {
+            case CERT_TYPE:
+                newx509 = (void *)wolfSSL_X509_load_certificate_buffer(pem,
+                    pemSz, WOLFSSL_FILETYPE_PEM);
+                break;
+
+        #ifdef HAVE_CRL
+            case CRL_TYPE:
+                if ((PemToDer(pem, pemSz, CRL_TYPE, &der, NULL, NULL, NULL)) < 0)
+                    goto err_exit;
+                derSz = der->length;
+                newx509 = (void*)wolfSSL_d2i_X509_CRL((WOLFSSL_X509_CRL **)x,
+                    (const unsigned char *)der->buffer, derSz);
+                if (newx509 == NULL)
+                    goto err_exit;
+                FreeDer(&der);
+                break;
+        #endif
+
+            default:
+                goto err_exit;
+        }
+        if (x != NULL) {
+            *x = newx509;
+        }
+        XFREE(pem, NULL, DYNAMIC_TYPE_PEM);
+        return newx509;
+
+    err_exit:
+        if (pem != NULL)
+            XFREE(pem, NULL, DYNAMIC_TYPE_PEM);
+        if (der != NULL)
+            FreeDer(&der);
+
+        /* unused */
+        (void)cb;
+        (void)u;
+	    (void)derSz;
+
+        return NULL;
+    }
+
+    WOLFSSL_API WOLFSSL_X509* wolfSSL_PEM_read_X509(XFILE fp, WOLFSSL_X509 **x,
+                                                    pem_password_cb *cb, void *u)
+    {
+        return (WOLFSSL_X509* )wolfSSL_PEM_read_X509_ex(fp, (void **)x, cb, u, CERT_TYPE);
+    }
+
+#if defined(HAVE_CRL)
+    WOLFSSL_API WOLFSSL_X509_CRL* wolfSSL_PEM_read_X509_CRL(XFILE fp, WOLFSSL_X509_CRL **crl,
+                                                    pem_password_cb *cb, void *u)
+    {
+        return (WOLFSSL_X509_CRL* )wolfSSL_PEM_read_X509_ex(fp, (void **)crl, cb, u, CRL_TYPE);
+    }
+#endif
+
+    int wolfSSL_PEM_write_X509(XFILE fp, WOLFSSL_X509* x)
+    {
+        int ret;
+        WOLFSSL_BIO* bio;
+
+        if (x == NULL)
+            return 0;
+
+        bio = wolfSSL_BIO_new(wolfSSL_BIO_s_file());
+        if (bio == NULL)
+            return 0;
+
+        if (wolfSSL_BIO_set_fp(bio, fp, BIO_NOCLOSE) != WOLFSSL_SUCCESS) {
+            wolfSSL_BIO_free(bio);
+            bio = NULL;
+        }
+
+        ret = wolfSSL_PEM_write_bio_X509(bio, x);
+
+        if (bio != NULL)
+            wolfSSL_BIO_free(bio);
+
+        return ret;
+    }
+#endif /* !NO_FILESYSTEM */
+
+    #define PEM_BEGIN              "-----BEGIN "
+    #define PEM_BEGIN_SZ           11
+    #define PEM_END                "-----END "
+    #define PEM_END_SZ             9
+    #define PEM_HDR_FIN            "-----"
+    #define PEM_HDR_FIN_SZ         5
+    #define PEM_HDR_FIN_EOL_NEWLINE   "-----\n"
+    #define PEM_HDR_FIN_EOL_NULL_TERM "-----\0"
+    #define PEM_HDR_FIN_EOL_SZ     6
+
+    int wolfSSL_PEM_read_bio(WOLFSSL_BIO* bio, char **name, char **header,
+                             unsigned char **data, long *len)
+    {
+        int ret = WOLFSSL_SUCCESS;
+        char pem[256];
+        int pemLen;
+        char* p;
+        char* nameStr = NULL;
+        int nameLen = 0;
+        char* headerStr = NULL;
+        int headerLen;
+        int headerFound = 0;
+        unsigned char* der = NULL;
+        word32 derLen = 0;
+
+        if (bio == NULL || name == NULL || header == NULL || data == NULL ||
+                                                                  len == NULL) {
+            return WOLFSSL_FAILURE;
+        }
+
+        /* Find header line. */
+        pem[sizeof(pem) - 1] = '\0';
+        while ((pemLen = wolfSSL_BIO_gets(bio, pem, sizeof(pem) - 1)) > 0) {
+            if (XSTRNCMP(pem, PEM_BEGIN, PEM_BEGIN_SZ) == 0)
+                break;
+        }
+        if (pemLen <= 0)
+            ret = WOLFSSL_FAILURE;
+        /* Have a header line. */
+        if (ret == WOLFSSL_SUCCESS) {
+            while (pem[pemLen - 1] == '\r' || pem[pemLen - 1] == '\n')
+                pemLen--;
+            pem[pemLen] = '\0';
+            if (XSTRNCMP(pem + pemLen - PEM_HDR_FIN_SZ, PEM_HDR_FIN,
+                                                         PEM_HDR_FIN_SZ) != 0) {
+                ret = WOLFSSL_FAILURE;
+            }
+        }
+
+        /* Get out name. */
+        if (ret == WOLFSSL_SUCCESS) {
+            nameLen = pemLen - PEM_BEGIN_SZ - PEM_HDR_FIN_SZ;
+            nameStr = (char*)XMALLOC(nameLen + 1, NULL,
+                                                       DYNAMIC_TYPE_TMP_BUFFER);
+            if (nameStr == NULL)
+                ret = WOLFSSL_FAILURE;
+        }
+        if (ret == WOLFSSL_SUCCESS) {
+            XSTRNCPY(nameStr, pem + PEM_BEGIN_SZ, nameLen);
+            nameStr[nameLen] = '\0';
+
+            /* Get header of PEM - encryption header. */
+            headerLen = 0;
+            while ((pemLen = wolfSSL_BIO_gets(bio, pem, sizeof(pem) - 1)) > 0) {
+                while (pemLen > 0 && (pem[pemLen - 1] == '\r' ||
+                                                     pem[pemLen - 1] == '\n')) {
+                    pemLen--;
+                }
+                pem[pemLen++] = '\n';
+                pem[pemLen] = '\0';
+
+                /* Header separator is a blank line. */
+                if (pem[0] == '\n') {
+                    headerFound = 1;
+                    break;
+                }
+
+                /* Didn't find a blank line - no header. */
+                if (XSTRNCMP(pem, PEM_END, PEM_END_SZ) == 0) {
+                    der = (unsigned char*)headerStr;
+                    derLen = headerLen;
+                    /* Empty header - empty string. */
+                    headerStr = (char*)XMALLOC(1, NULL,
+                                                       DYNAMIC_TYPE_TMP_BUFFER);
+                    if (headerStr == NULL)
+                        ret = WOLFSSL_FAILURE;
+                    else
+                        headerStr[0] = '\0';
+                    break;
+                }
+
+                p = (char*)XREALLOC(headerStr, headerLen + pemLen + 1, NULL,
+                                                       DYNAMIC_TYPE_TMP_BUFFER);
+                if (p == NULL) {
+                    ret = WOLFSSL_FAILURE;
+                    break;
+                }
+
+                headerStr = p;
+                XMEMCPY(headerStr + headerLen, pem, pemLen + 1);
+                headerLen += pemLen;
+            }
+            if (pemLen <= 0)
+                ret = WOLFSSL_FAILURE;
+        }
+
+        /* Get body of PEM - if there was a header */
+        if (ret == WOLFSSL_SUCCESS && headerFound) {
+            derLen = 0;
+            while ((pemLen = wolfSSL_BIO_gets(bio, pem, sizeof(pem) - 1)) > 0) {
+                while (pemLen > 0 && (pem[pemLen - 1] == '\r' ||
+                                                     pem[pemLen - 1] == '\n')) {
+                    pemLen--;
+                }
+                pem[pemLen++] = '\n';
+                pem[pemLen] = '\0';
+
+                if (XSTRNCMP(pem, PEM_END, PEM_END_SZ) == 0)
+                    break;
+
+                p = (char*)XREALLOC(der, derLen + pemLen + 1, NULL,
+                                                       DYNAMIC_TYPE_TMP_BUFFER);
+                if (p == NULL) {
+                    ret = WOLFSSL_FAILURE;
+                    break;
+                }
+
+                der = (unsigned char*)p;
+                XMEMCPY(der + derLen, pem, pemLen + 1);
+                derLen += pemLen;
+            }
+            if (pemLen <= 0)
+                ret = WOLFSSL_FAILURE;
+        }
+
+        /* Check trailer. */
+        if (ret == WOLFSSL_SUCCESS) {
+            if (XSTRNCMP(pem + PEM_END_SZ, nameStr, nameLen) != 0)
+                ret = WOLFSSL_FAILURE;
+        }
+        if (ret == WOLFSSL_SUCCESS) {
+            if (XSTRNCMP(pem + PEM_END_SZ + nameLen,
+                    PEM_HDR_FIN_EOL_NEWLINE,
+                    PEM_HDR_FIN_EOL_SZ) != 0 &&
+                XSTRNCMP(pem + PEM_END_SZ + nameLen,
+                        PEM_HDR_FIN_EOL_NULL_TERM,
+                        PEM_HDR_FIN_EOL_SZ) != 0) {
+                ret = WOLFSSL_FAILURE;
+            }
+        }
+
+        /* Base64 decode body. */
+        if (ret == WOLFSSL_SUCCESS) {
+            if (Base64_Decode(der, derLen, der, &derLen) != 0)
+                ret = WOLFSSL_FAILURE;
+        }
+
+        if (ret == WOLFSSL_SUCCESS) {
+            *name = nameStr;
+            *header = headerStr;
+            *data = der;
+            *len = derLen;
+            nameStr = NULL;
+            headerStr = NULL;
+            der = NULL;
+        }
+
+        if (nameStr != NULL)
+            XFREE(nameStr, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+        if (headerStr != NULL)
+            XFREE(headerStr, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+        if (der != NULL)
+            XFREE(der, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+
+        return ret;
+    }
+
+    int wolfSSL_PEM_write_bio(WOLFSSL_BIO* bio, const char *name,
+                              const char *header, const unsigned char *data,
+                              long len)
+    {
+        int err = 0;
+        int outSz = 0;
+        int nameLen;
+        int headerLen;
+        byte* pem = NULL;
+        word32 pemLen;
+        word32 derLen = (word32)len;
+
+        if (bio == NULL || name == NULL || header == NULL || data == NULL)
+            return 0;
+
+        nameLen = (int)XSTRLEN(name);
+        headerLen = (int)XSTRLEN(header);
+
+        pemLen = (derLen + 2) / 3 * 4;
+        pemLen += (pemLen + 63) / 64;
+
+        pem = (byte*)XMALLOC(pemLen, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+        err = pem == NULL;
+        if (!err)
+            err = Base64_Encode(data, derLen, pem, &pemLen) != 0;
+
+        if (!err) {
+            err = wolfSSL_BIO_write(bio, PEM_BEGIN, PEM_BEGIN_SZ) !=
+                                                              (int)PEM_BEGIN_SZ;
+        }
+        if (!err)
+            err = wolfSSL_BIO_write(bio, name, nameLen) != nameLen;
+        if (!err) {
+            err = wolfSSL_BIO_write(bio, PEM_HDR_FIN_EOL_NEWLINE,
+                    PEM_HDR_FIN_EOL_SZ) != (int)PEM_HDR_FIN_EOL_SZ;
+        }
+        if (!err && headerLen > 0) {
+            err = wolfSSL_BIO_write(bio, header, headerLen) != headerLen;
+            /* Blank line after a header and before body. */
+            if (!err)
+                err = wolfSSL_BIO_write(bio, "\n", 1) != 1;
+            headerLen++;
+        }
+        if (!err)
+            err = wolfSSL_BIO_write(bio, pem, pemLen) != (int)pemLen;
+        if (!err)
+            err = wolfSSL_BIO_write(bio, PEM_END, PEM_END_SZ) !=
+                                                                (int)PEM_END_SZ;
+        if (!err)
+            err = wolfSSL_BIO_write(bio, name, nameLen) != nameLen;
+        if (!err) {
+            err = wolfSSL_BIO_write(bio, PEM_HDR_FIN_EOL_NEWLINE,
+                    PEM_HDR_FIN_EOL_SZ) != (int)PEM_HDR_FIN_EOL_SZ;
+        }
+
+        if (!err) {
+            outSz = PEM_BEGIN_SZ + nameLen + PEM_HDR_FIN_EOL_SZ + headerLen +
+                             pemLen + PEM_END_SZ + nameLen + PEM_HDR_FIN_EOL_SZ;
+        }
+
+        if (pem != NULL)
+            XFREE(pem, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+
+        return outSz;
+    }
+
+#if !defined(NO_FILESYSTEM)
+    int wolfSSL_PEM_read(XFILE fp, char **name, char **header,
+                         unsigned char **data, long *len)
+    {
+        int ret;
+        WOLFSSL_BIO* bio;
+
+        if (name == NULL || header == NULL || data == NULL || len == NULL)
+            return WOLFSSL_FAILURE;
+
+        bio = wolfSSL_BIO_new(wolfSSL_BIO_s_file());
+        if (bio == NULL)
+            return 0;
+
+        if (wolfSSL_BIO_set_fp(bio, fp, BIO_NOCLOSE) != WOLFSSL_SUCCESS) {
+            wolfSSL_BIO_free(bio);
+            bio = NULL;
+        }
+
+        ret = wolfSSL_PEM_read_bio(bio, name, header, data, len);
+
+        if (bio != NULL)
+            wolfSSL_BIO_free(bio);
+
+        return ret;
+    }
+
+    int wolfSSL_PEM_write(XFILE fp, const char *name, const char *header,
+                          const unsigned char *data, long len)
+    {
+        int ret;
+        WOLFSSL_BIO* bio;
+
+        if (name == NULL || header == NULL || data == NULL)
+            return 0;
+
+        bio = wolfSSL_BIO_new(wolfSSL_BIO_s_file());
+        if (bio == NULL)
+            return 0;
+
+        if (wolfSSL_BIO_set_fp(bio, fp, BIO_NOCLOSE) != WOLFSSL_SUCCESS) {
+            wolfSSL_BIO_free(bio);
+            bio = NULL;
+        }
+
+        ret = wolfSSL_PEM_write_bio(bio, name, header, data, len);
+
+        if (bio != NULL)
+            wolfSSL_BIO_free(bio);
+
+        return ret;
+    }
+#endif
+
+    int wolfSSL_PEM_get_EVP_CIPHER_INFO(char* header, EncryptedInfo* cipher)
+    {
+        if (header == NULL || cipher == NULL)
+            return WOLFSSL_FAILURE;
+
+        XMEMSET(cipher, 0, sizeof(*cipher));
+
+        if (wc_EncryptedInfoParse(cipher, &header, XSTRLEN(header)) != 0)
+            return WOLFSSL_FAILURE;
+
+        return WOLFSSL_SUCCESS;
+    }
+
+    int wolfSSL_PEM_do_header(EncryptedInfo* cipher, unsigned char* data,
+                              long* len, pem_password_cb* callback, void* ctx)
+    {
+        int ret = WOLFSSL_SUCCESS;
+        char password[NAME_SZ];
+        int passwordSz;
+
+        if (cipher == NULL || data == NULL || len == NULL || callback == NULL)
+            return WOLFSSL_FAILURE;
+
+        passwordSz = callback(password, sizeof(password), PEM_PASS_READ, ctx);
+        if (passwordSz < 0)
+            ret = WOLFSSL_FAILURE;
+
+        if (ret == WOLFSSL_SUCCESS) {
+            if (wc_BufferKeyDecrypt(cipher, data, (word32)*len, (byte*)password,
+                                                     passwordSz, WC_MD5) != 0) {
+                ret = WOLFSSL_FAILURE;
+            }
+        }
+
+        if (passwordSz > 0)
+            XMEMSET(password, 0, passwordSz);
+
+        return ret;
+    }
+
+    /*
+     * bp : bio to read X509 from
+     * x  : x509 to write to
+     * cb : password call back for reading PEM
+     * u  : password
+     * _AUX is for working with a trusted X509 certificate
+     */
+    WOLFSSL_X509 *wolfSSL_PEM_read_bio_X509_AUX(WOLFSSL_BIO *bp,
+                               WOLFSSL_X509 **x, pem_password_cb *cb, void *u) {
+        WOLFSSL_ENTER("wolfSSL_PEM_read_bio_X509");
+
+        /* AUX info is; trusted/rejected uses, friendly name, private key id,
+         * and potentially a stack of "other" info. wolfSSL does not store
+         * friendly name or private key id yet in WOLFSSL_X509 for human
+         * readability and does not support extra trusted/rejected uses for
+         * root CA. */
+        return wolfSSL_PEM_read_bio_X509(bp, x, cb, u);
+    }
+
+
+#ifdef OPENSSL_ALL
+    /* create and return a new WOLFSSL_X509_PKEY structure or NULL on failure */
+    static WOLFSSL_X509_PKEY* wolfSSL_X509_PKEY_new(void* heap)
+    {
+        WOLFSSL_X509_PKEY* ret;
+
+        ret = (WOLFSSL_X509_PKEY*)XMALLOC(sizeof(WOLFSSL_X509_PKEY), heap,
+            DYNAMIC_TYPE_KEY);
+        if (ret != NULL) {
+            XMEMSET(ret, 0, sizeof(WOLFSSL_X509_PKEY));
+            ret->heap = heap;
+        }
+        return ret;
+    }
+
+
+    /* sets the values of X509_PKEY based on certificate passed in
+     * return WOLFSSL_SUCCESS on success */
+    static int wolfSSL_X509_PKEY_set(WOLFSSL_X509_PKEY* xPkey,
+            WOLFSSL_X509* x509)
+    {
+        if (xPkey == NULL || x509 == NULL) {
+            return BAD_FUNC_ARG;
+        }
+        wolfSSL_EVP_PKEY_free(xPkey->dec_pkey);
+        xPkey->dec_pkey = wolfSSL_X509_get_pubkey(x509);
+        if (xPkey->dec_pkey == NULL) {
+            return WOLFSSL_FAILURE;
+        }
+        return WOLFSSL_SUCCESS;
+    }
+
+
+    /* free up all memory used by "xPkey" passed in */
+    static void wolfSSL_X509_PKEY_free(WOLFSSL_X509_PKEY* xPkey)
+    {
+        if (xPkey != NULL) {
+            wolfSSL_EVP_PKEY_free(xPkey->dec_pkey);
+        }
+        XFREE(xPkey, xPkey->heap, DYNAMIC_TYPE_KEY);
+    }
+
+
+    /* Takes control of x509 on success
+     * helper function to break out code needed to set WOLFSSL_X509_INFO up
+     * free's "info" passed in if is not defaults
+     *
+     * returns WOLFSSL_SUCCESS on success
+     */
+    static int wolfSSL_X509_INFO_set(WOLFSSL_X509_INFO* info,
+            WOLFSSL_X509* x509)
+    {
+        if (info == NULL || x509 == NULL) {
+            return BAD_FUNC_ARG;
+        }
+
+        /* check is fresh "info" passed in, if not free it */
+        if (info->x509 != NULL || info->x_pkey != NULL) {
+            WOLFSSL_X509_INFO* tmp;
+
+            tmp = wolfSSL_X509_INFO_new();
+            if (tmp == NULL) {
+                WOLFSSL_MSG("Unable to create new structure");
+                return MEMORY_E;
+            }
+            wolfSSL_X509_INFO_free(info);
+            info = tmp;
+        }
+
+        info->x509 = x509;
+
+        //@TODO info->num
+        //@TODO info->enc_cipher
+        //@TODO info->enc_len
+        //@TODO info->enc_data
+        //@TODO info->crl
+
+        info->x_pkey = wolfSSL_X509_PKEY_new(x509->heap);
+        return wolfSSL_X509_PKEY_set(info->x_pkey, x509);
+    }
+
+
+    /*
+     * bio WOLFSSL_BIO to read certificates from
+     * sk  possible stack to push more X509_INFO structs to. Can be NULL
+     * cb  callback password for encrypted PEM certificates
+     * u   user input such as password
+     *
+     * returns stack on success and NULL or default stack passed in on fail
+     */
+    WOLF_STACK_OF(WOLFSSL_X509_INFO)* wolfSSL_PEM_X509_INFO_read_bio(
+        WOLFSSL_BIO* bio, WOLF_STACK_OF(WOLFSSL_X509_INFO)* sk,
+        pem_password_cb* cb, void* u)
+    {
+        WOLF_STACK_OF(WOLFSSL_X509_INFO)* localSk;
+        WOLFSSL_X509* x509 = NULL;
+        int ret = WOLFSSL_SUCCESS;
+
+        WOLFSSL_ENTER("wolfSSL_PEM_X509_INFO_read_bio");
+
+        /* attempt to used passed in stack or create a new one */
+        if (sk != NULL) {
+            localSk = sk;
+        }
+        else {
+            localSk = wolfSSL_sk_X509_INFO_new_null();
+        }
+        if (localSk == NULL) {
+            WOLFSSL_LEAVE("wolfSSL_PEM_X509_INFO_read_bio", MEMORY_E);
+            return NULL;
+        }
+
+        /* parse through BIO and push new info's found onto stack */
+        do {
+            x509 = wolfSSL_PEM_read_bio_X509(bio, NULL, cb, u);
+            if (x509 != NULL) {
+                WOLFSSL_X509_INFO* current;
+
+                current = wolfSSL_X509_INFO_new();
+                if (current == NULL) {
+                    WOLFSSL_LEAVE("wolfSSL_PEM_X509_INFO_read_bio", MEMORY_E);
+                    return NULL;
+                }
+                ret = wolfSSL_X509_INFO_set(current, x509);
+                if (ret  != WOLFSSL_SUCCESS) {
+                    wolfSSL_X509_free(x509);
+                }
+                else {
+                    wolfSSL_sk_X509_INFO_push(localSk, current);
+                }
+            }
+        } while (x509 != NULL && ret == WOLFSSL_SUCCESS);
+        WOLFSSL_LEAVE("wolfSSL_PEM_X509_INFO_read_bio", ret);
+        return localSk;
+    }
+#endif /* OPENSSL_ALL */
+
+    void wolfSSL_X509_NAME_ENTRY_free(WOLFSSL_X509_NAME_ENTRY* ne)
+    {
+        WOLFSSL_ENTER("wolfSSL_X509_NAME_ENTRY_free");
+        if (ne != NULL) {
+            if (ne->value != NULL && ne->value != &(ne->data)) {
+                wolfSSL_ASN1_STRING_free(ne->value);
+            }
+            XFREE(ne, NULL, DYNAMIC_TYPE_NAME_ENTRY);
+        }
+    }
+
+
+    WOLFSSL_X509_NAME_ENTRY* wolfSSL_X509_NAME_ENTRY_new(void)
+    {
+        WOLFSSL_X509_NAME_ENTRY* ne;
+
+        ne = (WOLFSSL_X509_NAME_ENTRY*)XMALLOC(sizeof(WOLFSSL_X509_NAME_ENTRY),
+                NULL, DYNAMIC_TYPE_NAME_ENTRY);
+        if (ne != NULL) {
+            XMEMSET(ne, 0, sizeof(WOLFSSL_X509_NAME_ENTRY));
+            ne->value = &(ne->data);
+        }
+
+        return ne;
+    }
+
+
+    /* Create a new WOLFSSL_X509_NAME_ENTRY structure based on the text passed
+     * in. Returns NULL on failure */
+    WOLFSSL_X509_NAME_ENTRY* wolfSSL_X509_NAME_ENTRY_create_by_txt(
+            WOLFSSL_X509_NAME_ENTRY **neIn, const char *txt, int type,
+            const unsigned char *data, int dataSz)
+    {
+        int nid = -1;
+        WOLFSSL_X509_NAME_ENTRY* ne = NULL;
+
+        WOLFSSL_ENTER("wolfSSL_X509_NAME_ENTRY_create_by_txt()");
+
+        if (txt == NULL) {
+            return NULL;
+        }
+
+        if (neIn != NULL) {
+            ne = *neIn;
+        }
+
+        nid = wolfSSL_OBJ_txt2nid(txt);
+        if (nid == NID_undef) {
+            WOLFSSL_MSG("Unable to find text");
+            ne = NULL;
+        }
+        else {
+            if (ne == NULL) {
+                ne = wolfSSL_X509_NAME_ENTRY_new();
+                if (ne == NULL) {
+                    return NULL;
+                }
+            }
+            ne->nid = nid;
+            ne->value = wolfSSL_ASN1_STRING_type_new(type);
+            if (ne->value != NULL) {
+                wolfSSL_ASN1_STRING_set(ne->value, (const void*)data, dataSz);
+                ne->set = 1;
+            }
+        }
+
+        return ne;
+    }
+
+
+    WOLFSSL_X509_NAME_ENTRY* wolfSSL_X509_NAME_ENTRY_create_by_NID(
+            WOLFSSL_X509_NAME_ENTRY** out, int nid, int type,
+            const unsigned char* data, int dataSz)
+    {
+        WOLFSSL_X509_NAME_ENTRY* ne;
+
+        WOLFSSL_ENTER("wolfSSL_X509_NAME_ENTRY_create_by_NID()");
+
+        ne = wolfSSL_X509_NAME_ENTRY_new();
+        if (ne == NULL) {
+            return NULL;
+        }
+
+        ne->nid = nid;
+        ne->value = wolfSSL_ASN1_STRING_type_new(type);
+        wolfSSL_ASN1_STRING_set(ne->value, (const void*)data, dataSz);
+        ne->set = 1;
+
+        if (out != NULL) {
+            *out = ne;
+        }
+
+        return ne;
+    }
+
+    static int RebuildFullNameAdd(DecodedName* dName, char* data)
+    {
+        int totalLen = 0;
+        int i;
+        char* fullName;
+        int idx;
+
+        if (dName->cnLen != 0)
+            totalLen += dName->cnLen + 4;
+        if (dName->snLen != 0)
+            totalLen += dName->snLen + 4;
+        if (dName->cLen != 0)
+            totalLen += dName->cLen + 3;
+        if (dName->lLen != 0)
+            totalLen += dName->lLen + 3;
+        if (dName->stLen != 0)
+            totalLen += dName->stLen + 4;
+        if (dName->oLen != 0)
+            totalLen += dName->oLen + 3;
+        if (dName->ouLen != 0)
+            totalLen += dName->ouLen + 4;
+        if (dName->emailLen != 0)
+            totalLen += dName->emailLen + 14;
+        if (dName->uidLen != 0)
+            totalLen += dName->uidLen + 5;
+        if (dName->serialLen != 0)
+            totalLen += dName->serialLen + 14;
+        if (dName->dcNum != 0) {
+            for (i = 0; i < dName->dcNum; i++)
+                totalLen += dName->dcLen[i] + 4;
+        }
+
+        fullName = (char*)XMALLOC(totalLen + 1, NULL, DYNAMIC_TYPE_X509);
+        if (fullName == NULL)
+            return MEMORY_E;
+
+        idx = 0;
+        dName->entryCount = 0;
+        if (dName->cnLen != 0) {
+            dName->entryCount++;
+            XMEMCPY(fullName + idx, WOLFSSL_COMMON_NAME, 4);
+            idx += 4;
+            if (dName->cnIdx == -1)
+                XMEMCPY(fullName + idx, data, dName->cnLen);
+            else {
+                XMEMCPY(fullName + idx, dName->fullName + dName->cnIdx,
+                                                                  dName->cnLen);
+            }
+            dName->cnIdx = idx;
+            idx += dName->cnLen;
+        }
+        if (dName->snLen != 0) {
+            dName->entryCount++;
+            XMEMCPY(fullName + idx, WOLFSSL_SUR_NAME, 4);
+            idx += 4;
+            if (dName->snIdx == -1)
+                XMEMCPY(fullName + idx, data, dName->snLen);
+            else {
+                XMEMCPY(fullName + idx, dName->fullName + dName->snIdx,
+                                                                  dName->snLen);
+            }
+            dName->snIdx = idx;
+            idx += dName->snLen;
+        }
+        if (dName->cLen != 0) {
+            dName->entryCount++;
+            XMEMCPY(fullName + idx, WOLFSSL_COUNTRY_NAME, 3);
+            idx += 3;
+            if (dName->cIdx == -1)
+                XMEMCPY(fullName + idx, data, dName->cLen);
+            else {
+                XMEMCPY(fullName + idx, dName->fullName + dName->cIdx,
+                                                                   dName->cLen);
+            }
+            dName->cIdx = idx;
+            idx += dName->cLen;
+        }
+        if (dName->lLen != 0) {
+            dName->entryCount++;
+            XMEMCPY(fullName + idx, WOLFSSL_LOCALITY_NAME, 3);
+            idx += 3;
+            if (dName->lIdx == -1)
+                XMEMCPY(fullName + idx, data, dName->lLen);
+            else {
+                XMEMCPY(fullName + idx, dName->fullName + dName->lIdx,
+                                                                   dName->lLen);
+            }
+            dName->lIdx = idx;
+            idx += dName->lLen;
+        }
+        if (dName->stLen != 0) {
+            dName->entryCount++;
+            XMEMCPY(fullName + idx, WOLFSSL_STATE_NAME, 4);
+            idx += 4;
+            if (dName->stIdx == -1)
+                XMEMCPY(fullName + idx, data, dName->stLen);
+            else {
+                XMEMCPY(fullName + idx, dName->fullName + dName->stIdx,
+                                                                  dName->stLen);
+            }
+            dName->stIdx = idx;
+            idx += dName->stLen;
+        }
+        if (dName->oLen != 0) {
+            dName->entryCount++;
+            XMEMCPY(fullName + idx, WOLFSSL_ORG_NAME, 3);
+            idx += 3;
+            if (dName->oIdx == -1)
+                XMEMCPY(fullName + idx, data, dName->oLen);
+            else {
+                XMEMCPY(fullName + idx, dName->fullName + dName->oIdx,
+                                                                   dName->oLen);
+            }
+            dName->oIdx = idx;
+            idx += dName->oLen;
+        }
+        if (dName->ouLen != 0) {
+            dName->entryCount++;
+            XMEMCPY(fullName + idx, WOLFSSL_ORGUNIT_NAME, 4);
+            idx += 4;
+            if (dName->ouIdx == -1)
+                XMEMCPY(fullName + idx, data, dName->ouLen);
+            else {
+                XMEMCPY(fullName + idx, dName->fullName + dName->ouIdx,
+                                                                  dName->ouLen);
+            }
+            dName->ouIdx = idx;
+            idx += dName->ouLen;
+        }
+        if (dName->emailLen != 0) {
+            dName->entryCount++;
+            XMEMCPY(fullName + idx, "/emailAddress=", 14);
+            idx += 14;
+            if (dName->emailIdx == -1)
+                XMEMCPY(fullName + idx, data, dName->emailLen);
+            else {
+                XMEMCPY(fullName + idx, dName->fullName + dName->emailIdx,
+                                                               dName->emailLen);
+            }
+            dName->emailIdx = idx;
+            idx += dName->emailLen;
+        }
+        if (dName->dcNum != 0) {
+            for (i = 0; i < dName->dcNum; i++) {
+                dName->entryCount++;
+                XMEMCPY(fullName + idx, WOLFSSL_DOMAIN_COMPONENT, 4);
+                idx += 4;
+                XMEMCPY(fullName + idx, dName->fullName + dName->dcIdx[i],
+                                                               dName->dcLen[i]);
+                dName->dcIdx[i] = idx;
+                idx += dName->dcLen[i];
+            }
+        }
+        if (dName->uidLen != 0) {
+            dName->entryCount++;
+            XMEMCPY(fullName + idx, "/UID=", 5);
+            idx += 5;
+            if (dName->uidIdx == -1)
+                XMEMCPY(fullName + idx, data, dName->uidLen);
+            else {
+                XMEMCPY(fullName + idx, dName->fullName + dName->uidIdx,
+                                                                 dName->uidLen);
+            }
+            dName->uidIdx = idx;
+            idx += dName->uidLen;
+        }
+        if (dName->serialLen != 0) {
+            dName->entryCount++;
+            XMEMCPY(fullName + idx, WOLFSSL_SERIAL_NUMBER, 14);
+            idx += 14;
+            if (dName->serialIdx == -1)
+                XMEMCPY(fullName + idx, data, dName->serialLen);
+            else {
+                XMEMCPY(fullName + idx, dName->fullName + dName->serialIdx,
+                                                              dName->serialLen);
+            }
+            dName->serialIdx = idx;
+            idx += dName->serialLen;
+        }
+
+        if (dName->fullName != NULL)
+            XFREE(dName->fullName, NULL, DYNAMIC_TYPE_X509);
+        dName->fullName = fullName;
+        dName->fullNameLen = idx + 1;
+
+        return 0;
+    }
+
+    /* Copies entry into name. With it being copied freeing entry becomes the
+     * callers responsibility.
+     * returns 1 for success and 0 for error */
+    int wolfSSL_X509_NAME_add_entry(WOLFSSL_X509_NAME* name,
+            WOLFSSL_X509_NAME_ENTRY* entry, int idx, int set)
+    {
+        int i;
+        int fullName = 1;
+
+        WOLFSSL_ENTER("wolfSSL_X509_NAME_add_entry()");
+
+        switch (entry->nid) {
+            case ASN_COMMON_NAME:
+                name->fullName.cnIdx = -1;
+                name->fullName.cnLen = entry->value->length;
+                name->fullName.cnNid = entry->nid;
+                break;
+            case ASN_SUR_NAME:
+                name->fullName.snIdx = -1;
+                name->fullName.snLen = entry->value->length;
+                name->fullName.snNid = entry->nid;
+                break;
+            case ASN_SERIAL_NUMBER:
+                name->fullName.serialIdx = -1;
+                name->fullName.serialLen = entry->value->length;
+                name->fullName.serialNid = entry->nid;
+                break;
+            case ASN_COUNTRY_NAME:
+                name->fullName.cIdx = -1;
+                name->fullName.cLen = entry->value->length;
+                name->fullName.cNid = entry->nid;
+                break;
+            case ASN_LOCALITY_NAME:
+                name->fullName.lIdx = -1;
+                name->fullName.lLen = entry->value->length;
+                name->fullName.lNid = entry->nid;
+                break;
+            case ASN_STATE_NAME:
+                name->fullName.stIdx = -1;
+                name->fullName.stLen = entry->value->length;
+                name->fullName.stNid = entry->nid;
+                break;
+            case ASN_ORG_NAME:
+                name->fullName.oIdx = -1;
+                name->fullName.oLen = entry->value->length;
+                name->fullName.oNid = entry->nid;
+                break;
+            case ASN_ORGUNIT_NAME:
+                name->fullName.ouIdx = -1;
+                name->fullName.ouLen = entry->value->length;
+                name->fullName.ouNid = entry->nid;
+                break;
+            case NID_emailAddress:
+                name->fullName.emailIdx = -1;
+                name->fullName.emailLen = entry->value->length;
+                name->fullName.emailNid = entry->nid;
+                break;
+            case ASN_USER_ID:
+                name->fullName.uidIdx = -1;
+                name->fullName.uidLen = entry->value->length;
+                name->fullName.uidNid = entry->nid;
+                break;
+            case ASN_DOMAIN_COMPONENT:
+                name->fullName.dcIdx[0] = -1;
+                name->fullName.dcLen[0] = entry->value->length;
+                break;
+            default:
+                fullName = 0;
+                break;
+        }
+
+        if (fullName) {
+            int nid = entry->nid;
+
+            if (nid == NID_emailAddress) {
+                nid = (int)ASN_EMAIL_NAME;
+            }
+
+            if (idx >= DN_NAMES_MAX + DOMAIN_COMPONENT_MAX) {
+                return WOLFSSL_FAILURE;
+            }
+
+            if (idx >= 0) {
+                name->fullName.loc[idx] = nid;
+                if (idx == name->fullName.locSz) {
+                    name->fullName.locSz += 1;
+                }
+            }
+
+            /* place at end */
+            if (idx < 0 && name->fullName.locSz + 1
+                    < DN_NAMES_MAX + DOMAIN_COMPONENT_MAX) {
+                name->fullName.loc[name->fullName.locSz] = nid;
+                name->fullName.locSz += 1;
+            }
+
+            if (RebuildFullNameAdd(&name->fullName, entry->value->data) != 0)
+                return WOLFSSL_FAILURE;
+        }
+        else {
+            for (i = 0; i < MAX_NAME_ENTRIES; i++) {
+                if (name->extra[i].set != 1) { /* not set so overwritten */
+                    WOLFSSL_X509_NAME_ENTRY* current = &(name->extra[i]);
+                    WOLFSSL_ASN1_STRING*     str;
+
+                    WOLFSSL_MSG("Found place for name entry");
+
+                    XMEMCPY(current, entry, sizeof(WOLFSSL_X509_NAME_ENTRY));
+                    str = entry->value;
+                    XMEMCPY(&(current->data), str, sizeof(WOLFSSL_ASN1_STRING));
+                    current->value = &(current->data);
+                    current->data.data = (char*)XMALLOC(str->length,
+                           name->x509->heap, DYNAMIC_TYPE_OPENSSL);
+
+                    if (current->data.data == NULL) {
+                        return SSL_FAILURE;
+                    }
+                    XMEMCPY(current->data.data, str->data, str->length);
+
+                    /* make sure is null terminated */
+                    current->data.data[str->length - 1] = '\0';
+
+                    current->set = 1; /* make sure now listed as set */
+                    break;
+                }
+            }
+
+            if (i == MAX_NAME_ENTRIES) {
+                WOLFSSL_MSG("No spot found for name entry");
+                return SSL_FAILURE;
+            }
+        }
+
+        (void)idx;
+        (void)set;
+        return SSL_SUCCESS;
+    }
+
+    int wolfSSL_X509_NAME_add_entry_by_txt(WOLFSSL_X509_NAME *name,
+                                           const char *field, int type,
+                                           const unsigned char *bytes, int len,
+                                           int loc, int set)
+    {
+        int ret = WOLFSSL_FAILURE;
+        int nid;
+        WOLFSSL_X509_NAME_ENTRY* entry;
+
+        (void)type;
+        WOLFSSL_ENTER("wolfSSL_X509_NAME_add_entry_by_txt");
+
+        if (name == NULL || field == NULL)
+            return WOLFSSL_FAILURE;
+
+        if ((nid = wolfSSL_OBJ_txt2nid(field)) == NID_undef)
+            return WOLFSSL_FAILURE;
+
+        entry = wolfSSL_X509_NAME_ENTRY_create_by_NID(NULL,
+                  nid, type, (unsigned char*)bytes, len);
+        if (entry == NULL)
+            return WOLFSSL_FAILURE;
+
+        ret = wolfSSL_X509_NAME_add_entry(name, entry, loc, set);
+        wolfSSL_X509_NAME_ENTRY_free(entry);
+
+        return ret;
+    }
+
+    int wolfSSL_X509_NAME_add_entry_by_NID(WOLFSSL_X509_NAME *name, int nid,
+                                           int type, const unsigned char *bytes,
+                                           int len, int loc, int set)
+    {
+        int ret;
+        WOLFSSL_X509_NAME_ENTRY* entry;
+        entry = wolfSSL_X509_NAME_ENTRY_create_by_NID(NULL, nid, type, bytes, len);
+        if (entry == NULL)
+            return WOLFSSL_FAILURE;
+        ret = wolfSSL_X509_NAME_add_entry(name, entry, loc, set);
+        wolfSSL_X509_NAME_ENTRY_free(entry);
+        return ret;
+    }
+    #endif /* !NO_CERTS */
+
+
+    /* NID variables are dependent on compatibility header files currently
+     *
+     * returns a pointer to a new WOLFSSL_ASN1_OBJECT struct on success and NULL
+     *         on fail
+     */
+
+    WOLFSSL_ASN1_OBJECT* wolfSSL_OBJ_nid2obj(int id)
+    {
+        return wolfSSL_OBJ_nid2obj_ex(id, NULL);
+    }
+
+
+    WOLFSSL_LOCAL WOLFSSL_ASN1_OBJECT* wolfSSL_OBJ_nid2obj_ex(int id,
+                                                WOLFSSL_ASN1_OBJECT* arg_obj)
+    {
+        word32 oidSz = 0;
+        const byte* oid;
+        word32 type = 0;
+        WOLFSSL_ASN1_OBJECT* obj = arg_obj;
+        byte objBuf[MAX_OID_SZ + MAX_LENGTH_SZ + 1]; /* +1 for object tag */
+        word32 objSz = 0;
+        const char* sName = NULL;
+        int i;
+
+        WOLFSSL_ENTER("wolfSSL_OBJ_nid2obj()");
+
+        for (i = 0; i < (int)WOLFSSL_OBJECT_INFO_SZ; i++) {
+            if (wolfssl_object_info[i].nid == id) {
+                id = wolfssl_object_info[i].id;
+                sName = wolfssl_object_info[i].sName;
+                type = wolfssl_object_info[i].type;
+                break;
+            }
+        }
+        if (i == (int)WOLFSSL_OBJECT_INFO_SZ) {
+            WOLFSSL_MSG("NID not in table");
+        #ifdef WOLFSSL_QT
+            sName = NULL;
+            type = id;
+        #else
+            return NULL;
+        #endif
+        }
+
+    #ifdef HAVE_ECC
+         if (type == 0 && wc_ecc_get_oid(id, &oid, &oidSz) > 0) {
+             type = oidCurveType;
+         }
+    #endif /* HAVE_ECC */
+
+        if (sName != NULL) {
+            if (XSTRLEN(sName) > WOLFSSL_MAX_SNAME - 1) {
+                WOLFSSL_MSG("Attempted short name is too large");
+                return NULL;
+            }
+        }
+
+        oid = OidFromId(id, type, &oidSz);
+
+        /* set object ID to buffer */
+        if (obj == NULL){
+            obj = wolfSSL_ASN1_OBJECT_new();
+            if (obj == NULL) {
+                WOLFSSL_MSG("Issue creating WOLFSSL_ASN1_OBJECT struct");
+                return NULL;
+            }
+            obj->dynamic |= WOLFSSL_ASN1_DYNAMIC;
+        } else {
+            obj->dynamic &= ~WOLFSSL_ASN1_DYNAMIC;
+        }
+        obj->type    = id;
+        obj->grp     = type;
+
+        obj->sName[0] = '\0';
+        if (sName != NULL) {
+            XMEMCPY(obj->sName, (char*)sName, XSTRLEN((char*)sName));
+        }
+
+        objBuf[0] = ASN_OBJECT_ID; objSz++;
+        objSz += SetLength(oidSz, objBuf + 1);
+        XMEMCPY(objBuf + objSz, oid, oidSz);
+        objSz     += oidSz;
+        obj->objSz = objSz;
+        if(((obj->dynamic & WOLFSSL_ASN1_DYNAMIC_DATA) != 0) ||
+                                                           (obj->obj == NULL)) {
+            obj->obj = (byte*)XREALLOC((byte*)obj->obj, obj->objSz, NULL,
+                                                             DYNAMIC_TYPE_ASN1);
+            if (obj->obj == NULL) {
+                wolfSSL_ASN1_OBJECT_free(obj);
+                return NULL;
+            }
+            obj->dynamic |= WOLFSSL_ASN1_DYNAMIC_DATA ;
+        } else {
+            obj->dynamic &= ~WOLFSSL_ASN1_DYNAMIC_DATA ;
+        }
+        XMEMCPY((byte*)obj->obj, objBuf, obj->objSz);
+
+        (void)type;
+
+        return obj;
+    }
+
+    static const char* oid_translate_num_to_str(const char* oid)
+    {
+        const struct oid_dict {
+            const char* num;
+            const char* desc;
+        } oid_dict[] = {
+            { "2.5.29.37.0",       "Any Extended Key Usage" },
+            { "1.3.6.1.5.5.7.3.1", "TLS Web Server Authentication" },
+            { "1.3.6.1.5.5.7.3.2", "TLS Web Client Authentication" },
+            { "1.3.6.1.5.5.7.3.3", "Code Signing" },
+            { "1.3.6.1.5.5.7.3.4", "E-mail Protection" },
+            { "1.3.6.1.5.5.7.3.8", "Time Stamping" },
+            { "1.3.6.1.5.5.7.3.9", "OCSP Signing" },
+            { NULL, NULL }
+        };
+        const struct oid_dict* idx;
+
+        for (idx = oid_dict; idx->num != NULL; idx++) {
+            if (!XSTRNCMP(oid, idx->num, XSTRLEN(idx->num))) {
+                return idx->desc;
+            }
+        }
+        return NULL;
+    }
+
+    /* if no_name is one than use numerical form otherwise can be short name.
+     *
+     * returns the buffer size on success
+     */
+    int wolfSSL_OBJ_obj2txt(char *buf, int bufLen, WOLFSSL_ASN1_OBJECT *a, int no_name)
+    {
+        int bufSz;
+        const char* desc;
+
+        WOLFSSL_ENTER("wolfSSL_OBJ_obj2txt()");
+
+        if (buf == NULL || bufLen <= 1 || a == NULL) {
+            WOLFSSL_MSG("Bad input argument");
+            return WOLFSSL_FAILURE;
+        }
+
+        if (no_name == 1) {
+            int    length;
+            word32 idx = 0;
+            byte   tag;
+
+            if (GetASNTag(a->obj, &idx, &tag, a->objSz) != 0) {
+                return WOLFSSL_FAILURE;
+            }
+
+            if (tag != ASN_OBJECT_ID) {
+                WOLFSSL_MSG("Bad ASN1 Object");
+                return WOLFSSL_FAILURE;
+            }
+
+            if (GetLength((const byte*)a->obj, &idx, &length,
+                           a->objSz) < 0 || length < 0) {
+                return ASN_PARSE_E;
+            }
+
+            if (bufLen < MAX_OID_STRING_SZ) {
+                bufSz = bufLen - 1;
+            }
+            else {
+                bufSz = MAX_OID_STRING_SZ;
+            }
+
+            if ((bufSz = DecodePolicyOID(buf, (word32)bufSz, a->obj + idx,
+                        (word32)length)) <= 0) {
+                WOLFSSL_MSG("Error decoding OID");
+                return WOLFSSL_FAILURE;
+            }
+
+        }
+        else { /* return short name */
+            if (XSTRLEN(a->sName) + 1 < (word32)bufLen - 1) {
+                bufSz = (int)XSTRLEN(a->sName);
+            }
+            else {
+                bufSz = bufLen - 1;
+            }
+            if (bufSz) {
+                XMEMCPY(buf, a->sName, bufSz);
+            }
+            else if (wolfSSL_OBJ_obj2txt(buf, bufLen, a, 1)) {
+                if ((desc = oid_translate_num_to_str(buf))) {
+                    bufSz = (int)XSTRLEN(desc);
+                    XMEMCPY(buf, desc, min(bufSz, bufLen));
+                }
+            }
+            else if (a->type == GEN_DNS || a->type == GEN_EMAIL || a->type == GEN_URI) {
+                bufSz = (int)XSTRLEN((const char*)a->obj);
+                XMEMCPY(buf, a->obj, min(bufSz, bufLen));
+            }
+        }
+
+        buf[bufSz] = '\0';
+        #ifdef WOLFSSL_QT
+            /* For unknown extension types, QT expects the short name to be the
+                text representation of the oid */
+            if (XSTRLEN(a->sName) == 0) {
+                XMEMCPY(a->sName, buf, bufSz);
+            }
+        #endif
+        return bufSz;
+    }
+#endif /* OPENSSL_EXTRA */
+
+#if defined(OPENSSL_EXTRA) && !defined(NO_ASN)
+    /* DN_Tags to strings */
+    static const struct DN_Tag_Strings {
+        enum DN_Tags tag;
+        const char* str;
+    } dn_tag_strings[] = {
+           { ASN_COMMON_NAME,      "CN" },
+           { ASN_SUR_NAME,         "SN" },
+           { ASN_SERIAL_NUMBER,    "serialNumber" },
+           { ASN_COUNTRY_NAME,     "C" },
+           { ASN_LOCALITY_NAME,    "L" },
+           { ASN_STATE_NAME,       "ST" },
+           { ASN_ORG_NAME,         "O"},
+           { ASN_ORGUNIT_NAME,     "OU"},
+           { ASN_BUS_CAT,          "businessCategory"},
+           { ASN_EMAIL_NAME,       "emailAddress"},
+           { ASN_USER_ID,          "UID"},
+           { ASN_DOMAIN_COMPONENT, "DC"},
+           { ASN_DN_NULL,          NULL }
+    };
+
+    int wolfSSL_X509_NAME_get_index_by_OBJ(WOLFSSL_X509_NAME *name,
+                                           const WOLFSSL_ASN1_OBJECT *obj,
+                                           int idx) {
+        const struct DN_Tag_Strings* dn;
+        enum DN_Tags tag = ASN_DN_NULL;
+
+        if (!name || idx >= name->fullName.locSz ||
+                !obj || !obj->obj) {
+            return -1;
+        }
+
+        if (idx < 0) {
+            idx = 0;
+        }
+        for (dn = dn_tag_strings; dn->str != NULL; dn++) {
+            /* Find the DN_Tags number for the name */
+            if (XSTRNCMP((const char*) obj->sName, dn->str, obj->objSz - 1) == 0) {
+                tag = dn->tag;
+                break;
+            }
+        }
+        if (!tag) {
+            /* Unable to identify desired name */
+            return -1;
+        }
+        for (idx++; idx < name->fullName.locSz; idx++) {
+            /* Find index of desired name */
+            if ((enum DN_Tags)name->fullName.loc[idx] == tag) {
+                return idx;
+            }
+        }
+        return -1;
+    }
+#endif
+
+#if defined(OPENSSL_EXTRA) || defined(HAVE_LIGHTY) || \
+    defined(WOLFSSL_MYSQL_COMPATIBLE) || defined(HAVE_STUNNEL) || \
+    defined(WOLFSSL_NGINX) || defined(HAVE_POCO_LIB) || \
+    defined(WOLFSSL_HAPROXY)
+
+#ifndef NO_SHA
+    /* One shot SHA1 hash of message.
+     *
+     * d  message to hash
+     * n  size of d buffer
+     * md buffer to hold digest. Should be SHA_DIGEST_SIZE.
+     *
+     * Note: if md is null then a static buffer of SHA_DIGEST_SIZE is used.
+     *       When the static buffer is used this function is not thread safe.
+     *
+     * Returns a pointer to the message digest on success and NULL on failure.
+     */
+    unsigned char *wolfSSL_SHA1(const unsigned char *d, size_t n,
+            unsigned char *md)
+    {
+        static byte dig[WC_SHA_DIGEST_SIZE];
+        wc_Sha sha;
+
+        WOLFSSL_ENTER("wolfSSL_SHA1");
+
+        if (wc_InitSha_ex(&sha, NULL, 0) != 0) {
+            WOLFSSL_MSG("SHA1 Init failed");
+            return NULL;
+        }
+
+        if (wc_ShaUpdate(&sha, (const byte*)d, (word32)n) != 0) {
+            WOLFSSL_MSG("SHA1 Update failed");
+            return NULL;
+        }
+
+        if (wc_ShaFinal(&sha, dig) != 0) {
+            WOLFSSL_MSG("SHA1 Final failed");
+            return NULL;
+        }
+
+        wc_ShaFree(&sha);
+
+        if (md != NULL) {
+            XMEMCPY(md, dig, WC_SHA_DIGEST_SIZE);
+            return md;
+        }
+        else {
+            return (unsigned char*)dig;
+        }
+    }
+#endif /* ! NO_SHA */
+
+#ifndef NO_SHA256
+    /* One shot SHA256 hash of message.
+     *
+     * d  message to hash
+     * n  size of d buffer
+     * md buffer to hold digest. Should be WC_SHA256_DIGEST_SIZE.
+     *
+     * Note: if md is null then a static buffer of WC_SHA256_DIGEST_SIZE is used.
+     *       When the static buffer is used this function is not thread safe.
+     *
+     * Returns a pointer to the message digest on success and NULL on failure.
+     */
+    unsigned char *wolfSSL_SHA256(const unsigned char *d, size_t n,
+            unsigned char *md)
+    {
+        static byte dig[WC_SHA256_DIGEST_SIZE];
+        wc_Sha256 sha;
+
+        WOLFSSL_ENTER("wolfSSL_SHA256");
+
+        if (wc_InitSha256_ex(&sha, NULL, 0) != 0) {
+            WOLFSSL_MSG("SHA256 Init failed");
+            return NULL;
+        }
+
+        if (wc_Sha256Update(&sha, (const byte*)d, (word32)n) != 0) {
+            WOLFSSL_MSG("SHA256 Update failed");
+            return NULL;
+        }
+
+        if (wc_Sha256Final(&sha, dig) != 0) {
+            WOLFSSL_MSG("SHA256 Final failed");
+            return NULL;
+        }
+
+        wc_Sha256Free(&sha);
+
+        if (md != NULL) {
+            XMEMCPY(md, dig, WC_SHA256_DIGEST_SIZE);
+            return md;
+        }
+        else {
+            return (unsigned char*)dig;
+        }
+    }
+#endif /* ! NO_SHA256 */
+
+#ifdef WOLFSSL_SHA384
+     /* One shot SHA384 hash of message.
+      *
+      * d  message to hash
+      * n  size of d buffer
+      * md buffer to hold digest. Should be WC_SHA256_DIGEST_SIZE.
+      *
+      * Note: if md is null then a static buffer of WC_SHA256_DIGEST_SIZE is used.
+      *       When the static buffer is used this function is not thread safe.
+      *
+      * Returns a pointer to the message digest on success and NULL on failure.
+      */
+     unsigned char *wolfSSL_SHA384(const unsigned char *d, size_t n,
+             unsigned char *md)
+     {
+         static byte dig[WC_SHA384_DIGEST_SIZE];
+         wc_Sha384 sha;
+
+         WOLFSSL_ENTER("wolfSSL_SHA384");
+
+         if (wc_InitSha384_ex(&sha, NULL, 0) != 0) {
+             WOLFSSL_MSG("SHA384 Init failed");
+             return NULL;
+         }
+
+         if (wc_Sha384Update(&sha, (const byte*)d, (word32)n) != 0) {
+             WOLFSSL_MSG("SHA384 Update failed");
+             return NULL;
+         }
+
+         if (wc_Sha384Final(&sha, dig) != 0) {
+             WOLFSSL_MSG("SHA384 Final failed");
+             return NULL;
+         }
+
+         wc_Sha384Free(&sha);
+
+         if (md != NULL) {
+             XMEMCPY(md, dig, WC_SHA384_DIGEST_SIZE);
+             return md;
+         }
+         else {
+             return (unsigned char*)dig;
+         }
+     }
+#endif /* WOLFSSL_SHA384  */
+
+
+#if defined(WOLFSSL_SHA512)
+     /* One shot SHA512 hash of message.
+      *
+      * d  message to hash
+      * n  size of d buffer
+      * md buffer to hold digest. Should be WC_SHA256_DIGEST_SIZE.
+      *
+      * Note: if md is null then a static buffer of WC_SHA256_DIGEST_SIZE is used.
+      *       When the static buffer is used this function is not thread safe.
+      *
+      * Returns a pointer to the message digest on success and NULL on failure.
+      */
+     unsigned char *wolfSSL_SHA512(const unsigned char *d, size_t n,
+             unsigned char *md)
+     {
+         static byte dig[WC_SHA512_DIGEST_SIZE];
+         wc_Sha512 sha;
+
+         WOLFSSL_ENTER("wolfSSL_SHA512");
+
+         if (wc_InitSha512_ex(&sha, NULL, 0) != 0) {
+             WOLFSSL_MSG("SHA512 Init failed");
+             return NULL;
+         }
+
+         if (wc_Sha512Update(&sha, (const byte*)d, (word32)n) != 0) {
+             WOLFSSL_MSG("SHA512 Update failed");
+             return NULL;
+         }
+
+         if (wc_Sha512Final(&sha, dig) != 0) {
+             WOLFSSL_MSG("SHA512 Final failed");
+             return NULL;
+         }
+
+         wc_Sha512Free(&sha);
+
+         if (md != NULL) {
+             XMEMCPY(md, dig, WC_SHA512_DIGEST_SIZE);
+             return md;
+         }
+         else {
+             return (unsigned char*)dig;
+         }
+     }
+#endif /* defined(WOLFSSL_SHA512)  */
+#endif /* OPENSSL_EXTRA */
+
+#ifndef WOLFCRYPT_ONLY
+#if defined(OPENSSL_EXTRA) || defined(HAVE_LIGHTY) || \
+    defined(WOLFSSL_MYSQL_COMPATIBLE) || defined(HAVE_STUNNEL) || \
+    defined(WOLFSSL_NGINX) || defined(HAVE_POCO_LIB) || \
+    defined(WOLFSSL_HAPROXY)
+
+    char wolfSSL_CTX_use_certificate(WOLFSSL_CTX *ctx, WOLFSSL_X509 *x)
+    {
+        int ret;
+
+        WOLFSSL_ENTER("wolfSSL_CTX_use_certificate");
+
+        FreeDer(&ctx->certificate); /* Make sure previous is free'd */
+        ret = AllocDer(&ctx->certificate, x->derCert->length, CERT_TYPE,
+                       ctx->heap);
+        if (ret != 0)
+            return 0;
+
+        XMEMCPY(ctx->certificate->buffer, x->derCert->buffer,
+                x->derCert->length);
+#ifdef KEEP_OUR_CERT
+        if (ctx->ourCert != NULL && ctx->ownOurCert) {
+            FreeX509(ctx->ourCert);
+            XFREE(ctx->ourCert, ctx->heap, DYNAMIC_TYPE_X509);
+        }
+        #ifndef WOLFSSL_X509_STORE_CERTS
+        ctx->ourCert = x;
+        #else
+        ctx->ourCert = wolfSSL_X509_d2i(NULL, x->derCert->buffer,x->derCert->length);
+        if(ctx->ourCert == NULL){
+            return 0;
+        }
+        #endif
+
+        ctx->ownOurCert = 0;
+#endif
+
+        /* Update the available options with public keys. */
+        switch (x->pubKeyOID) {
+            case RSAk:
+                ctx->haveRSA = 1;
+                break;
+        #ifdef HAVE_ED25519
+            case ED25519k:
+        #endif
+        #ifdef HAVE_ED448
+            case ED448k:
+        #endif
+            case ECDSAk:
+                ctx->haveECC = 1;
+        #if defined(HAVE_ECC) || defined(HAVE_ED25519) || defined(HAVE_ED448)
+                ctx->pkCurveOID = x->pkCurveOID;
+        #endif
+                break;
+        }
+
+        return WOLFSSL_SUCCESS;
+    }
+
+    int wolfSSL_CTX_add1_chain_cert(WOLFSSL_CTX* ctx, WOLFSSL_X509* x509)
+    {
+        int ret;
+        if (ctx == NULL || x509 == NULL || x509->derCert == NULL) {
+            return WOLFSSL_FAILURE;
+        }
+
+        ret = wolfSSL_CTX_load_verify_buffer(ctx, x509->derCert->buffer,
+            x509->derCert->length, WOLFSSL_FILETYPE_ASN1);
+
+        return (ret == 0) ? WOLFSSL_SUCCESS : WOLFSSL_FAILURE;
+    }
+
+    int wolfSSL_BIO_read_filename(WOLFSSL_BIO *b, const char *name) {
+    #ifndef NO_FILESYSTEM
+        XFILE fp;
+
+        WOLFSSL_ENTER("wolfSSL_BIO_new_file");
+
+        if ((wolfSSL_BIO_get_fp(b, &fp) == WOLFSSL_SUCCESS) && (fp != XBADFILE))
+        {
+            XFCLOSE(fp);
+        }
+
+        fp = XFOPEN(name, "r");
+        if (fp == XBADFILE)
+            return WOLFSSL_BAD_FILE;
+
+        if (wolfSSL_BIO_set_fp(b, fp, BIO_CLOSE) != WOLFSSL_SUCCESS) {
+            XFCLOSE(fp);
+            return WOLFSSL_BAD_FILE;
+        }
+
+        /* file is closed when bio is free'd */
+        return WOLFSSL_SUCCESS;
+    #else
+        (void)name;
+        (void)b;
+        return WOLFSSL_NOT_IMPLEMENTED;
+    #endif
+    }
+
+    /* Return the corresponding short name for the nid <n>.
+     * or NULL if short name can't be found.
+     */
+    const char * wolfSSL_OBJ_nid2sn(int n) {
+        const WOLFSSL_ObjectInfo *obj_info = wolfssl_object_info;
+        size_t i;
+        WOLFSSL_ENTER("wolfSSL_OBJ_nid2sn");
+        for (i = 0; i < WOLFSSL_OBJECT_INFO_SZ; i++, obj_info++) {
+            if (obj_info->nid == n) {
+                return obj_info->sName;
+            }
+        }
+        WOLFSSL_MSG("SN not found");
+        return NULL;
+    }
+
+#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
+    int wolfSSL_OBJ_sn2nid(const char *sn) {
+        WOLFSSL_ENTER("wolfSSL_OBJ_sn2nid");
+        if (sn == NULL)
+            return NID_undef;
+        return wc_OBJ_sn2nid(sn);
+    }
+#endif
+
+
+    /* Gets the NID value that corresponds with the ASN1 object.
+     *
+     * o ASN1 object to get NID of
+     *
+     * Return NID on success and a negative value on failure
+     */
+    int wolfSSL_OBJ_obj2nid(const WOLFSSL_ASN1_OBJECT *o)
+    {
+        word32 oid = 0;
+        word32 idx = 0;
+
+        WOLFSSL_ENTER("wolfSSL_OBJ_obj2nid");
+
+        if (o == NULL) {
+            return -1;
+        }
+
+        #ifdef WOLFSSL_QT
+        if (o->grp == oidCertExtType) {
+            /* If nid is an unknown extension, return NID_undef */
+            if (wolfSSL_OBJ_nid2sn(o->nid) == NULL)
+                return NID_undef;
+        }
+        #endif
+
+        if (o->nid > 0)
+            return o->nid;
+        if (GetObjectId(o->obj, &idx, &oid, o->grp, o->objSz) < 0) {
+            WOLFSSL_MSG("Issue getting OID of object");
+            return -1;
+        }
+
+        return oid2nid(oid, o->grp);
+    }
+
+    /* Returns the long name that corresponds with an ASN1_OBJECT nid value.
+     *  n : NID value of ASN1_OBJECT to search */
+    const char* wolfSSL_OBJ_nid2ln(int n)
+    {
+        const WOLFSSL_ObjectInfo *obj_info = wolfssl_object_info;
+        size_t i;
+        WOLFSSL_ENTER("wolfSSL_OBJ_nid2ln");
+        for (i = 0; i < WOLFSSL_OBJECT_INFO_SZ; i++, obj_info++) {
+            if (obj_info->nid == n) {
+                return obj_info->lName;
+            }
+        }
+        WOLFSSL_MSG("NID not found in table");
+        return NULL;
+    }
+
+    /* Return the corresponding NID for the long name <ln>
+     * or NID_undef if NID can't be found.
+     */
+    int wolfSSL_OBJ_ln2nid(const char *ln)
+    {
+        const WOLFSSL_ObjectInfo *obj_info = wolfssl_object_info;
+        size_t i, lnlen;
+        WOLFSSL_ENTER("wolfSSL_OBJ_ln2nid");
+        if (ln && (lnlen = XSTRLEN(ln)) > 0) {
+            /* Accept input like "/commonName=" */
+            if (ln[0] == '/') {
+                ln++;
+                lnlen--;
+            }
+            if (lnlen) {
+                if (ln[lnlen-1] == '=') {
+                    lnlen--;
+                }
+                for (i = 0; i < WOLFSSL_OBJECT_INFO_SZ; i++, obj_info++) {
+                    if (lnlen == XSTRLEN(obj_info->lName) &&
+                            XSTRNCMP(ln, obj_info->lName, lnlen) == 0) {
+                        return obj_info->nid;
+                    }
+                }
+            }
+        }
+        return NID_undef;
+    }
+
+    /* compares two objects, return 0 if equal */
+    int wolfSSL_OBJ_cmp(const WOLFSSL_ASN1_OBJECT* a,
+                        const WOLFSSL_ASN1_OBJECT* b)
+    {
+        WOLFSSL_ENTER("wolfSSL_OBJ_cmp");
+
+        if (a != NULL && b != NULL &&
+            a->obj != NULL && b->obj != NULL &&
+            a->objSz == b->objSz) {
+            return XMEMCMP(a->obj, b->obj, a->objSz);
+        }
+
+        return WOLFSSL_FATAL_ERROR;
+    }
+
+    /* Gets the NID value that is related to the OID string passed in. Example
+     * string would be "2.5.29.14" for subject key ID.
+     *
+     * returns NID value on success and NID_undef on error
+     */
+    int wolfSSL_OBJ_txt2nid(const char* s)
+    {
+        unsigned int i;
+    #ifdef WOLFSSL_CERT_EXT
+        int ret;
+        unsigned int sum = 0;
+        unsigned int outSz = MAX_OID_SZ;
+        unsigned char out[MAX_OID_SZ];
+    #endif
+
+        WOLFSSL_ENTER("OBJ_txt2nid");
+
+        if (s == NULL) {
+            return NID_undef;
+        }
+
+    #ifdef WOLFSSL_CERT_EXT
+        ret = EncodePolicyOID(out, &outSz, s, NULL);
+        if (ret == 0) {
+            /* sum OID */
+            for (i = 0; i < outSz; i++) {
+                sum += out[i];
+            }
+        }
+    #endif /* WOLFSSL_CERT_EXT */
+
+        /* get the group that the OID's sum is in
+         * @TODO possible conflict with multiples */
+        for (i = 0; i < WOLFSSL_OBJECT_INFO_SZ; i++) {
+            int len;
+        #ifdef WOLFSSL_CERT_EXT
+            if (ret == 0) {
+                if (wolfssl_object_info[i].id == (int)sum) {
+                    return wolfssl_object_info[i].nid;
+                }
+            }
+        #endif
+
+            /* try as a short name */
+            len = (int)XSTRLEN(s);
+            if (XSTRNCMP(wolfssl_object_info[i].sName, s, len) == 0) {
+                return wolfssl_object_info[i].nid;
+            }
+
+            /* try as a long name */
+            if (XSTRNCMP(wolfssl_object_info[i].lName, s, len) == 0) {
+                return wolfssl_object_info[i].nid;
+            }
+        }
+
+        return NID_undef;
+    }
+
+    /* Creates new ASN1_OBJECT from short name, long name, or text
+     * representation of oid. If no_name is 0, then short name, long name, and
+     * numerical value of oid are interpreted. If no_name is 1, then only the
+     * numerical value of the oid is interpreted.
+     *
+     * Returns pointer to ASN1_OBJECT on success, or NULL on error.
+     */
+#if defined(WOLFSSL_CERT_EXT) && defined(WOLFSSL_CERT_GEN)
+    WOLFSSL_ASN1_OBJECT* wolfSSL_OBJ_txt2obj(const char* s, int no_name)
+    {
+        int len, i, ret;
+        int nid = NID_undef;
+        unsigned int outSz = MAX_OID_SZ;
+        unsigned char out[MAX_OID_SZ];
+        unsigned int sum = 0;
+
+        WOLFSSL_ENTER("wolfSSL_OBJ_txt2obj");
+
+        if (s == NULL)
+            return NULL;
+
+        /* If s is numerical value, try to sum oid */
+        ret = EncodePolicyOID(out, &outSz, s, NULL);
+        if (ret == 0) {
+            for (i = 0; i < (int)outSz; i++) {
+                sum += out[i];
+            }
+        }
+
+        len = (int)XSTRLEN(s);
+
+        /* TODO: update short names in wolfssl_object_info and check OID sums
+           are correct */
+        for (i = 0; i < (int)WOLFSSL_OBJECT_INFO_SZ; i++) {
+            /* Short name, long name, and numerical value are interpreted */
+            if (no_name == 0 && ((XSTRNCMP(s, wolfssl_object_info[i].sName, len) == 0) ||
+                                 (XSTRNCMP(s, wolfssl_object_info[i].lName, len) == 0) ||
+                                 (wolfssl_object_info[i].id == (int)sum)))
+                    nid = wolfssl_object_info[i].nid;
+            /* Only numerical value is interpreted */
+            else if (no_name == 1 && wolfssl_object_info[i].id == (int)sum)
+                    nid = wolfssl_object_info[i].nid;
+        }
+
+        if (nid != NID_undef)
+            return wolfSSL_OBJ_nid2obj(nid);
+
+        return NULL;
+    }
+#endif
+
+    /* compatibility function. Its intended use is to remove OID's from an
+     * internal table that have been added with OBJ_create. wolfSSL manages its
+     * own internal OID values and does not currently support OBJ_create. */
+    void wolfSSL_OBJ_cleanup(void)
+    {
+        WOLFSSL_ENTER("wolfSSL_OBJ_cleanup()");
+    }
+
+    #ifndef NO_WOLFSSL_STUB
+    int wolfSSL_OBJ_create(const char *oid, const char *sn, const char *ln)
+    {
+        (void)oid;
+        (void)sn;
+        (void)ln;
+        WOLFSSL_STUB("wolfSSL_OBJ_create");
+        return WOLFSSL_FAILURE;
+    }
+    #endif
+
+    void wolfSSL_set_verify_depth(WOLFSSL *ssl, int depth)
+    {
+    #if !defined(OPENSSL_EXTRA) && !defined(NO_WOLFSSL_STUB)
+        (void)ssl;
+        (void)depth;
+        WOLFSSL_STUB("wolfSSL_set_verify_depth");
+    #else
+        WOLFSSL_ENTER("wolfSSL_set_verify_depth");
+        ssl->options.verifyDepth = (byte)depth;
+    #endif
+    }
+
+
+    WOLFSSL_ASN1_OBJECT * wolfSSL_X509_NAME_ENTRY_get_object(WOLFSSL_X509_NAME_ENTRY *ne) {
+        WOLFSSL_ENTER("wolfSSL_X509_NAME_ENTRY_get_object");
+        if (ne == NULL) return NULL;
+        if (wolfSSL_OBJ_nid2obj_ex(ne->nid, &ne->object) != NULL) {
+            ne->object.nid = ne->nid;
+            return &ne->object;
+        }
+        return NULL;
+    }
+
+
+    /* looks up the DN given the location "loc". "loc" is the number indicating
+     * the order that the DN was parsed as, 0 is first DN parsed.
+     *
+     * returns the setup WOLFSSL_X509_NAME pointer on success and NULL on fail
+     */
+    static WOLFSSL_X509_NAME* wolfSSL_nameByLoc(WOLFSSL_X509_NAME *name, int loc)
+    {
+        char* pt = NULL;
+        int sz = 0;
+
+        switch (name->fullName.loc[loc])
+        {
+        case ASN_COMMON_NAME:
+            sz = name->fullName.cnLen;
+            pt = &name->fullName.fullName[name->fullName.cnIdx];
+            name->cnEntry.nid           = name->fullName.cnNid;
+            break;
+        case ASN_COUNTRY_NAME:
+            sz = name->fullName.cLen;
+            pt = &name->fullName.fullName[name->fullName.cIdx];
+            name->cnEntry.nid           = name->fullName.cNid;
+            break;
+        case ASN_LOCALITY_NAME:
+            sz = name->fullName.lLen;
+            pt = &name->fullName.fullName[name->fullName.lIdx];
+            name->cnEntry.nid           = name->fullName.lNid;
+            break;
+        case ASN_STATE_NAME:
+            sz = name->fullName.stLen;
+            pt = &name->fullName.fullName[name->fullName.stIdx];
+            name->cnEntry.nid           = name->fullName.stNid;
+            break;
+        case ASN_ORG_NAME:
+            sz = name->fullName.oLen;
+            pt = &name->fullName.fullName[name->fullName.oIdx];
+            name->cnEntry.nid           = name->fullName.oNid;
+            break;
+        case ASN_ORGUNIT_NAME:
+            sz = name->fullName.ouLen;
+            pt = &name->fullName.fullName[name->fullName.ouIdx];
+            name->cnEntry.nid           = name->fullName.ouNid;
+            break;
+        case ASN_EMAIL_NAME:
+            sz = name->fullName.emailLen;
+            pt = &name->fullName.fullName[name->fullName.emailIdx];
+            name->cnEntry.nid           = name->fullName.emailNid;
+            break;
+        case ASN_SUR_NAME:
+            sz = name->fullName.snLen;
+            pt = &name->fullName.fullName[name->fullName.snIdx];
+            name->cnEntry.nid           = name->fullName.snNid;
+            break;
+        case ASN_USER_ID:
+            sz = name->fullName.uidLen;
+            pt = &name->fullName.fullName[name->fullName.uidIdx];
+            name->cnEntry.nid           = name->fullName.uidNid;
+            break;
+        case ASN_SERIAL_NUMBER:
+            sz = name->fullName.serialLen;
+            pt = &name->fullName.fullName[name->fullName.serialIdx];
+            name->cnEntry.nid           = name->fullName.serialNid;
+            break;
+#ifdef WOLFSSL_CERT_EXT
+        case ASN_BUS_CAT:
+            sz = name->fullName.bcLen;
+            pt = &name->fullName.fullName[name->fullName.bcIdx];
+            break;
+#endif
+
+        case ASN_DOMAIN_COMPONENT:
+            /* get index of DC i.e. first or second or ... case */
+            {
+                int idx = 0, i;
+                for (i = 0; i < loc; i++) {
+                    if (name->fullName.loc[i] == ASN_DOMAIN_COMPONENT) {
+                        idx++;
+                    }
+                }
+
+                /* check that index is not larger than max buffer size or larger
+                 * than the number of domain components parsed */
+                if (idx >= DOMAIN_COMPONENT_MAX || idx > name->fullName.dcNum) {
+                    WOLFSSL_MSG("Index was larger then domain buffer");
+                    return NULL;
+                }
+                pt = &name->fullName.fullName[name->fullName.dcIdx[idx]],
+                sz = name->fullName.dcLen[idx];
+                name->cnEntry.nid         = ASN_DOMAIN_COMPONENT;
+                name->cnEntry.data.type   = CTC_UTF8;
+            }
+            break;
+
+        default:
+            return NULL;
+        }
+
+        /* -1 to leave room for trailing terminator 0 */
+        if (sz == 0 || sz >= CTC_NAME_SIZE - 1)
+            return NULL;
+        if (wolfSSL_ASN1_STRING_set(name->cnEntry.value, pt, sz) !=
+                WOLFSSL_SUCCESS) {
+            WOLFSSL_MSG("Error setting local ASN1 string data");
+            return NULL;
+        }
+        name->cnEntry.value->type   = CTC_UTF8;
+        name->cnEntry.set           = 1;
+        return name;
+    }
+
+
+    WOLFSSL_X509_NAME_ENTRY *wolfSSL_X509_NAME_get_entry(
+                                             WOLFSSL_X509_NAME *name, int loc)
+    {
+        WOLFSSL_ENTER("wolfSSL_X509_NAME_get_entry");
+
+        if (name == NULL) {
+            return NULL;
+        }
+
+        if (loc < 0) {
+            WOLFSSL_MSG("Bad argument");
+            return NULL;
+        }
+
+        if (loc <= DN_NAMES_MAX + name->fullName.dcNum) {
+            if (wolfSSL_nameByLoc(name, loc) != NULL)
+                return &name->cnEntry;
+        }
+        /* DC component */
+        if (name->fullName.dcMode) {
+            if (name->fullName.fullName != NULL){
+                if (loc == name->fullName.dcNum){
+                    name->cnEntry.data.data
+                        = &name->fullName.fullName[name->fullName.cIdx];
+                    name->cnEntry.data.length = name->fullName.cLen;
+                    name->cnEntry.nid         = ASN_COUNTRY_NAME;
+                } else {
+                    name->cnEntry.data.data
+                        = &name->fullName.fullName[name->fullName.dcIdx[loc]];
+                    name->cnEntry.data.length = name->fullName.dcLen[loc];
+                    name->cnEntry.nid         = ASN_DOMAIN_COMPONENT;
+                }
+            }
+            name->cnEntry.data.type = CTC_UTF8;
+        /* common name index case */
+        } else if (loc == name->fullName.cnIdx && name->x509 != NULL) {
+            /* get CN shortcut from x509 since it has null terminator */
+            name->cnEntry.data.data   = name->x509->subjectCN;
+            name->cnEntry.data.length = name->fullName.cnLen;
+            name->cnEntry.data.type   = CTC_UTF8;
+            name->cnEntry.nid         = ASN_COMMON_NAME;
+            name->cnEntry.set         = 1;
+        } else {
+            WOLFSSL_MSG("loc passed in is not in range of parsed DN's");
+            return NULL;
+        }
+        return &name->cnEntry;
+    }
+
+    #ifndef NO_WOLFSSL_STUB
+    int wolfSSL_X509_check_private_key(WOLFSSL_X509 *x509, WOLFSSL_EVP_PKEY *key)
+    {
+        (void) x509;
+        (void) key;
+        WOLFSSL_ENTER("wolfSSL_X509_check_private_key");
+        WOLFSSL_STUB("X509_check_private_key");
+
+        return WOLFSSL_SUCCESS;
+    }
+
+    WOLF_STACK_OF(WOLFSSL_X509_NAME) *wolfSSL_dup_CA_list(
+        WOLF_STACK_OF(WOLFSSL_X509_NAME) *sk)
+    {
+        (void) sk;
+        WOLFSSL_ENTER("wolfSSL_dup_CA_list");
+        WOLFSSL_STUB("SSL_dup_CA_list");
+
+        return NULL;
+    }
+
+    #endif
+
+#endif /* OPENSSL_ALL || HAVE_LIGHTY || WOLFSSL_MYSQL_COMPATIBLE ||
+    HAVE_STUNNEL || WOLFSSL_NGINX || HAVE_POCO_LIB || WOLFSSL_HAPROXY */
+#endif /* OPENSSL_EXTRA */
+
+#ifndef WOLFCRYPT_ONLY
+
+#ifdef OPENSSL_EXTRA
+
+/* wolfSSL uses negative values for error states. This function returns an
+ * unsigned type so the value returned is the absolute value of the error.
+ */
+unsigned long wolfSSL_ERR_peek_last_error_line(const char **file, int *line)
+{
+    WOLFSSL_ENTER("wolfSSL_ERR_peek_last_error");
+
+    (void)line;
+    (void)file;
+#if defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX) || defined(DEBUG_WOLFSSL) || \
+    defined(WOLFSSL_HAPROXY)
+    {
+        int ret;
+
+        if ((ret = wc_PeekErrorNode(-1, file, NULL, line)) < 0) {
+            WOLFSSL_MSG("Issue peeking at error node in queue");
+            return 0;
+        }
+    #if defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX)
+        if (ret == -ASN_NO_PEM_HEADER)
+            return (ERR_LIB_PEM << 24) | PEM_R_NO_START_LINE;
+    #endif
+        return (unsigned long)ret;
+    }
+#else
+    return (unsigned long)(0 - NOT_COMPILED_IN);
+#endif
+}
+
+
+#ifndef NO_CERTS
+int wolfSSL_CTX_use_PrivateKey(WOLFSSL_CTX *ctx, WOLFSSL_EVP_PKEY *pkey)
+{
+    WOLFSSL_ENTER("wolfSSL_CTX_use_PrivateKey");
+
+    if (ctx == NULL || pkey == NULL) {
+        return WOLFSSL_FAILURE;
+    }
+
+    if (pkey->pkey.ptr != NULL) {
+        /* ptr for WOLFSSL_EVP_PKEY struct is expected to be DER format */
+        return wolfSSL_CTX_use_PrivateKey_buffer(ctx,
+                                       (const unsigned char*)pkey->pkey.ptr,
+                                       pkey->pkey_sz, SSL_FILETYPE_ASN1);
+    }
+
+    WOLFSSL_MSG("wolfSSL private key not set");
+    return BAD_FUNC_ARG;
+}
+#endif /* !NO_CERTS */
+
+
+#if defined(HAVE_EX_DATA) || defined(FORTRESS)
+void* wolfSSL_CTX_get_ex_data(const WOLFSSL_CTX* ctx, int idx)
+{
+    WOLFSSL_ENTER("wolfSSL_CTX_get_ex_data");
+    #ifdef HAVE_EX_DATA
+    if(ctx != NULL) {
+        return wolfSSL_CRYPTO_get_ex_data(&ctx->ex_data, idx);
+    }
+    #else
+    (void)ctx;
+    (void)idx;
+    #endif
+    return NULL;
+}
+
+int wolfSSL_CTX_get_ex_new_index(long idx, void* arg, void* a, void* b,
+                                void* c)
+{
+    static int ctx_idx = 0;
+
+    WOLFSSL_ENTER("wolfSSL_CTX_get_ex_new_index");
+    (void)idx;
+    (void)arg;
+    (void)a;
+    (void)b;
+    (void)c;
+
+    return ctx_idx++;
+}
+
+/* Return the index that can be used for the WOLFSSL structure to store
+ * application data.
+ *
+ */
+int wolfSSL_get_ex_new_index(long argValue, void* arg,
+        WOLFSSL_CRYPTO_EX_new* cb1, WOLFSSL_CRYPTO_EX_dup* cb2,
+        WOLFSSL_CRYPTO_EX_free* cb3)
+{
+    static int ssl_idx = 0;
+
+    WOLFSSL_ENTER("wolfSSL_get_ex_new_index");
+
+    (void)argValue;
+    (void)arg;
+    (void)cb1;
+    (void)cb2;
+    (void)cb3;
+
+    return ssl_idx++;
+}
+
+
+int wolfSSL_CTX_set_ex_data(WOLFSSL_CTX* ctx, int idx, void* data)
+{
+    WOLFSSL_ENTER("wolfSSL_CTX_set_ex_data");
+    #ifdef HAVE_EX_DATA
+    if (ctx != NULL)
+    {
+        return wolfSSL_CRYPTO_set_ex_data(&ctx->ex_data, idx, data);
+    }
+    #else
+    (void)ctx;
+    (void)idx;
+    (void)data;
+    #endif
+    return WOLFSSL_FAILURE;
+}
+#endif
+
+
+/* Returns char* to app data stored in ex[0].
+ *
+ * ssl WOLFSSL structure to get app data from
+ */
+void* wolfSSL_get_app_data(const WOLFSSL *ssl)
+{
+    /* checkout exdata stuff... */
+    WOLFSSL_ENTER("wolfSSL_get_app_data");
+
+    return wolfSSL_get_ex_data(ssl, 0);
+}
+
+
+/* Set ex array 0 to have app data
+ *
+ * ssl WOLFSSL struct to set app data in
+ * arg data to be stored
+ *
+ * Returns SSL_SUCCESS on success and SSL_FAILURE on failure
+ */
+int wolfSSL_set_app_data(WOLFSSL *ssl, void* arg) {
+    WOLFSSL_ENTER("wolfSSL_set_app_data");
+
+    return wolfSSL_set_ex_data(ssl, 0, arg);
+}
+
+
+int wolfSSL_set_ex_data(WOLFSSL* ssl, int idx, void* data)
+{
+    WOLFSSL_ENTER("wolfSSL_set_ex_data");
+#if defined(HAVE_EX_DATA) || defined(FORTRESS)
+    if (ssl != NULL)
+    {
+        return wolfSSL_CRYPTO_set_ex_data(&ssl->ex_data, idx, data);
+    }
+#else
+    WOLFSSL_MSG("HAVE_EX_DATA macro is not defined");
+    (void)ssl;
+    (void)idx;
+    (void)data;
+#endif
+    return WOLFSSL_FAILURE;
+}
+
+
+
+void* wolfSSL_get_ex_data(const WOLFSSL* ssl, int idx)
+{
+    WOLFSSL_ENTER("wolfSSL_get_ex_data");
+#if defined(HAVE_EX_DATA) || defined(FORTRESS)
+    if (ssl != NULL) {
+        return wolfSSL_CRYPTO_get_ex_data(&ssl->ex_data, idx);
+    }
+#else
+    WOLFSSL_MSG("HAVE_EX_DATA macro is not defined");
+    (void)ssl;
+    (void)idx;
+#endif
+    return 0;
+}
+
+#ifndef NO_DSA
+WOLFSSL_DSA *wolfSSL_PEM_read_bio_DSAparams(WOLFSSL_BIO *bp, WOLFSSL_DSA **x,
+        pem_password_cb *cb, void *u)
+{
+    WOLFSSL_DSA* dsa;
+    DsaKey* key;
+    int    length;
+    unsigned char*  buf;
+    word32 bufSz;
+    int ret;
+    word32 idx = 0;
+    DerBuffer* pDer;
+
+    WOLFSSL_ENTER("wolfSSL_PEM_read_bio_DSAparams");
+
+    ret = wolfSSL_BIO_get_mem_data(bp, &buf);
+    if (ret <= 0) {
+        WOLFSSL_LEAVE("wolfSSL_PEM_read_bio_DSAparams", ret);
+        return NULL;
+    }
+
+    bufSz = (word32)ret;
+
+    if (cb != NULL || u != NULL) {
+        /*
+         * cb is for a call back when encountering encrypted PEM files
+         * if cb == NULL and u != NULL then u = null terminated password string
+         */
+        WOLFSSL_MSG("Not yet supporting call back or password for encrypted PEM");
+    }
+
+    if ((ret = PemToDer(buf, (long)bufSz, DSA_PARAM_TYPE, &pDer, NULL, NULL,
+                    NULL)) < 0 ) {
+        WOLFSSL_MSG("Issue converting from PEM to DER");
+        return NULL;
+    }
+
+    if ((ret = GetSequence(pDer->buffer, &idx, &length, pDer->length)) < 0) {
+        WOLFSSL_LEAVE("wolfSSL_PEM_read_bio_DSAparams", ret);
+        FreeDer(&pDer);
+        return NULL;
+    }
+
+    dsa = wolfSSL_DSA_new();
+    if (dsa == NULL) {
+        FreeDer(&pDer);
+        WOLFSSL_MSG("Error creating DSA struct");
+        return NULL;
+    }
+
+    key = (DsaKey*)dsa->internal;
+    if (key == NULL) {
+        FreeDer(&pDer);
+        wolfSSL_DSA_free(dsa);
+        WOLFSSL_MSG("Error finding DSA key struct");
+        return NULL;
+    }
+
+    if (GetInt(&key->p,  pDer->buffer, &idx, pDer->length) < 0 ||
+        GetInt(&key->q,  pDer->buffer, &idx, pDer->length) < 0 ||
+        GetInt(&key->g,  pDer->buffer, &idx, pDer->length) < 0 ) {
+        WOLFSSL_MSG("dsa key error");
+        FreeDer(&pDer);
+        wolfSSL_DSA_free(dsa);
+        return NULL;
+    }
+
+    if (SetIndividualExternal(&dsa->p, &key->p) != WOLFSSL_SUCCESS) {
+        WOLFSSL_MSG("dsa p key error");
+        FreeDer(&pDer);
+        wolfSSL_DSA_free(dsa);
+        return NULL;
+    }
+
+    if (SetIndividualExternal(&dsa->q, &key->q) != WOLFSSL_SUCCESS) {
+        WOLFSSL_MSG("dsa q key error");
+        FreeDer(&pDer);
+        wolfSSL_DSA_free(dsa);
+        return NULL;
+    }
+
+    if (SetIndividualExternal(&dsa->g, &key->g) != WOLFSSL_SUCCESS) {
+        WOLFSSL_MSG("dsa g key error");
+        FreeDer(&pDer);
+        wolfSSL_DSA_free(dsa);
+        return NULL;
+    }
+
+    if (x != NULL) {
+        *x = dsa;
+    }
+
+    FreeDer(&pDer);
+    return dsa;
+}
+#endif /* NO_DSA */
+#endif /* OPENSSL_EXTRA */
+#endif /* WOLFCRYPT_ONLY */
+
+#if defined(OPENSSL_EXTRA)
+
+/* Begin functions for openssl/buffer.h */
+WOLFSSL_BUF_MEM* wolfSSL_BUF_MEM_new(void)
+{
+    WOLFSSL_BUF_MEM* buf;
+    buf = (WOLFSSL_BUF_MEM*)XMALLOC(sizeof(WOLFSSL_BUF_MEM), NULL,
+                                                        DYNAMIC_TYPE_OPENSSL);
+    if (buf) {
+        XMEMSET(buf, 0, sizeof(WOLFSSL_BUF_MEM));
+    }
+    return buf;
+}
+
+
+/* returns length of buffer on success */
+int wolfSSL_BUF_MEM_grow(WOLFSSL_BUF_MEM* buf, size_t len)
+{
+    int len_int = (int)len;
+    int mx;
+
+    /* verify provided arguments */
+    if (buf == NULL || len_int < 0) {
+        return 0; /* BAD_FUNC_ARG; */
+    }
+
+    /* check to see if fits in existing length */
+    if (buf->length > len) {
+        buf->length = len;
+        return len_int;
+    }
+
+    /* check to see if fits in max buffer */
+    if (buf->max >= len) {
+        if (buf->data != NULL) {
+            XMEMSET(&buf->data[buf->length], 0, len - buf->length);
+        }
+        buf->length = len;
+        return len_int;
+    }
+
+    /* expand size, to handle growth */
+    mx = (len_int + 3) / 3 * 4;
+
+    /* use realloc */
+    buf->data = (char*)XREALLOC(buf->data, mx, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    if (buf->data == NULL) {
+        return 0; /* ERR_R_MALLOC_FAILURE; */
+    }
+
+    buf->max = mx;
+    XMEMSET(&buf->data[buf->length], 0, len - buf->length);
+    buf->length = len;
+
+    return len_int;
+}
+
+void wolfSSL_BUF_MEM_free(WOLFSSL_BUF_MEM* buf)
+{
+    if (buf) {
+        if (buf->data) {
+            XFREE(buf->data, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+            buf->data = NULL;
+        }
+        buf->max = 0;
+        buf->length = 0;
+        XFREE(buf, NULL, DYNAMIC_TYPE_OPENSSL);
+    }
+}
+/* End Functions for openssl/buffer.h */
+
+#endif /* OPENSSL_EXTRA */
+
+
+#if defined(HAVE_LIGHTY) || defined(HAVE_STUNNEL) \
+    || defined(WOLFSSL_MYSQL_COMPATIBLE) || defined(OPENSSL_EXTRA)
+
+WOLFSSL_BIO *wolfSSL_BIO_new_file(const char *filename, const char *mode)
+{
+#ifndef NO_FILESYSTEM
+    WOLFSSL_BIO* bio;
+    XFILE fp;
+
+    WOLFSSL_ENTER("wolfSSL_BIO_new_file");
+
+    fp = XFOPEN(filename, mode);
+    if (fp == XBADFILE)
+        return NULL;
+
+    bio = wolfSSL_BIO_new(wolfSSL_BIO_s_file());
+    if (bio == NULL) {
+        XFCLOSE(fp);
+        return bio;
+    }
+
+    if (wolfSSL_BIO_set_fp(bio, fp, BIO_CLOSE) != WOLFSSL_SUCCESS) {
+        XFCLOSE(fp);
+        wolfSSL_BIO_free(bio);
+        bio = NULL;
+    }
+
+    /* file is closed when BIO is free'd */
+    return bio;
+#else
+    (void)filename;
+    (void)mode;
+    return NULL;
+#endif /* NO_FILESYSTEM */
+}
+
+#ifndef NO_FILESYSTEM
+WOLFSSL_BIO* wolfSSL_BIO_new_fp(XFILE fp, int close_flag)
+{
+    WOLFSSL_BIO* bio;
+
+    WOLFSSL_ENTER("wolfSSL_BIO_new_fp");
+
+    bio = wolfSSL_BIO_new(wolfSSL_BIO_s_file());
+    if (bio == NULL) {
+        return bio;
+    }
+
+    if (wolfSSL_BIO_set_fp(bio, fp, close_flag) != WOLFSSL_SUCCESS) {
+        wolfSSL_BIO_free(bio);
+        bio = NULL;
+    }
+
+    /* file is closed when BIO is free'd or by user depending on flag */
+    return bio;
+}
+#endif
+
+
+#ifndef NO_DH
+WOLFSSL_DH *wolfSSL_PEM_read_bio_DHparams(WOLFSSL_BIO *bio, WOLFSSL_DH **x,
+        pem_password_cb *cb, void *u)
+{
+#ifndef NO_FILESYSTEM
+    WOLFSSL_DH* localDh = NULL;
+    unsigned char* mem  = NULL;
+    word32 size;
+    long   sz;
+    int    ret;
+    DerBuffer *der = NULL;
+    byte*  p = NULL;
+    byte*  g = NULL;
+    word32 pSz = MAX_DH_SIZE;
+    word32 gSz = MAX_DH_SIZE;
+    int    memAlloced = 0;
+
+    WOLFSSL_ENTER("wolfSSL_PEM_read_bio_DHparams");
+    (void)cb;
+    (void)u;
+
+    if (bio == NULL) {
+        WOLFSSL_MSG("Bad Function Argument bio is NULL");
+        return NULL;
+    }
+
+    if (bio->type == WOLFSSL_BIO_MEMORY) {
+        /* Use the buffer directly. */
+        ret = wolfSSL_BIO_get_mem_data(bio, &mem);
+        if (mem == NULL || ret <= 0) {
+            WOLFSSL_MSG("Failed to get data from bio struct");
+            goto end;
+        }
+        size = ret;
+    }
+    else if (bio->type == WOLFSSL_BIO_FILE) {
+        /* Read whole file into a new buffer. */
+        if (XFSEEK((XFILE)bio->ptr, 0, SEEK_END) != 0)
+            goto end;
+        sz = XFTELL((XFILE)bio->ptr);
+        if (XFSEEK((XFILE)bio->ptr, 0, SEEK_SET) != 0)
+            goto end;
+        if (sz > MAX_WOLFSSL_FILE_SIZE || sz <= 0L) {
+            WOLFSSL_MSG("PEM_read_bio_DHparams file size error");
+            goto end;
+        }
+        mem = (unsigned char*)XMALLOC(sz, NULL, DYNAMIC_TYPE_PEM);
+        if (mem == NULL)
+            goto end;
+        memAlloced = 1;
+
+        if (wolfSSL_BIO_read(bio, (char *)mem, (int)sz) <= 0)
+            goto end;
+        size = (word32)sz;
+    }
+    else {
+        WOLFSSL_MSG("BIO type not supported for reading DH parameters");
+        goto end;
+    }
+
+    ret = PemToDer(mem, size, DH_PARAM_TYPE, &der, NULL, NULL, NULL);
+    if (ret != 0)
+        goto end;
+
+    /* Use the object passed in, otherwise allocate a new object */
+    if (x != NULL)
+        localDh = *x;
+    if (localDh == NULL) {
+        localDh = wolfSSL_DH_new();
+        if (localDh == NULL)
+            goto end;
+    }
+
+    /* Load data in manually */
+    p = (byte*)XMALLOC(pSz, NULL, DYNAMIC_TYPE_PUBLIC_KEY);
+    g = (byte*)XMALLOC(gSz, NULL, DYNAMIC_TYPE_PUBLIC_KEY);
+    if (p == NULL || g == NULL)
+        goto end;
+
+    /* Extract the p and g as data from the DER encoded DH parameters. */
+    ret = wc_DhParamsLoad(der->buffer, der->length, p, &pSz, g, &gSz);
+    if (ret != 0) {
+        if (x != NULL && localDh != *x)
+            XFREE(localDh, NULL, DYNAMIC_TYPE_OPENSSL);
+        localDh = NULL;
+        goto end;
+    }
+
+    if (x != NULL)
+        *x = localDh;
+
+    /* Put p and g in as big numbers. */
+    if (localDh->p != NULL) {
+        wolfSSL_BN_free(localDh->p);
+        localDh->p = NULL;
+    }
+    if (localDh->g != NULL) {
+        wolfSSL_BN_free(localDh->g);
+        localDh->g = NULL;
+    }
+    localDh->p = wolfSSL_BN_bin2bn(p, pSz, NULL);
+    localDh->g = wolfSSL_BN_bin2bn(g, gSz, NULL);
+    if (localDh->p == NULL || localDh->g == NULL) {
+        if (x != NULL && localDh != *x)
+            wolfSSL_DH_free(localDh);
+        localDh = NULL;
+    }
+
+    if (localDh != NULL && localDh->inSet == 0) {
+        if (SetDhInternal(localDh) != WOLFSSL_SUCCESS) {
+            WOLFSSL_MSG("Unable to set internal DH structure");
+            wolfSSL_DH_free(localDh);
+            localDh = NULL;
+        }
+    }
+
+end:
+    if (memAlloced) XFREE(mem, NULL, DYNAMIC_TYPE_PEM);
+    if (der != NULL) FreeDer(&der);
+    XFREE(p, NULL, DYNAMIC_TYPE_PUBLIC_KEY);
+    XFREE(g, NULL, DYNAMIC_TYPE_PUBLIC_KEY);
+    return localDh;
+#else
+    (void)bio;
+    (void)x;
+    (void)cb;
+    (void)u;
+    return NULL;
+#endif
+}
+
+#ifndef NO_FILESYSTEM
+#if defined(WOLFSSL_QT) || defined(OPENSSL_ALL) || defined(WOLFSSL_OPENSSH)
+/* Convert DH key parameters to DER format, write to output (outSz)
+ * If output is NULL then max expected size is set to outSz and LENGTH_ONLY_E is
+ * returned.
+ *
+ * Note : static function due to redefinition complications with DhKey and FIPS
+ * version 2 build.
+ *
+ * return bytes written on success */
+int wc_DhParamsToDer(DhKey* key, byte* out, word32* outSz)
+{
+    word32 sz = 0, idx = 0;
+    int pSz = 0, gSz = 0, ret;
+    byte scratch[MAX_LENGTH_SZ];
+
+    if (key == NULL || outSz == NULL) {
+        return BAD_FUNC_ARG;
+    }
+
+    pSz = mp_unsigned_bin_size(&key->p);
+    if (pSz < 0) {
+        return pSz;
+    }
+    if (mp_leading_bit(&key->p)) {
+        pSz++;
+    }
+
+    gSz = mp_unsigned_bin_size(&key->g);
+    if (gSz < 0) {
+        return gSz;
+    }
+    if (mp_leading_bit(&key->g)) {
+        gSz++;
+    }
+
+    sz  = ASN_TAG_SZ; /* Integer */
+    sz += SetLength(pSz, scratch);
+    sz += ASN_TAG_SZ; /* Integer */
+    sz += SetLength(gSz, scratch);
+    sz += gSz + pSz;
+
+    if (out == NULL) {
+        byte seqScratch[MAX_SEQ_SZ];
+
+        *outSz = sz + SetSequence(sz, seqScratch);
+        return LENGTH_ONLY_E;
+    }
+
+    if (*outSz < MAX_SEQ_SZ || *outSz < sz) {
+        return BUFFER_E;
+    }
+
+    idx += SetSequence(sz, out);
+    if (*outSz < idx + sz) {
+        return BUFFER_E;
+    }
+
+    out[idx++] = ASN_INTEGER;
+    idx += SetLength(pSz, out + idx);
+    if (mp_leading_bit(&key->p)) {
+        out[idx++] = 0x00;
+        pSz -= 1; /* subtract 1 from size to account for leading 0 */
+    }
+    ret = mp_to_unsigned_bin(&key->p, out + idx);
+    if (ret != MP_OKAY) {
+        return BUFFER_E;
+    }
+    idx += pSz;
+
+    out[idx++] = ASN_INTEGER;
+    idx += SetLength(gSz, out + idx);
+    if (mp_leading_bit(&key->g)) {
+        out[idx++] = 0x00;
+        gSz -= 1; /* subtract 1 from size to account for leading 0 */
+    }
+    ret = mp_to_unsigned_bin(&key->g, out + idx);
+    if (ret != MP_OKAY) {
+        return BUFFER_E;
+    }
+    idx += gSz;
+    return idx;
+}
+
+int wc_DhPubKeyToDer(DhKey*  key, byte* out, word32* outSz)
+{
+    word32 sz = 0;
+    word32 paramSz = 0;
+    int ret;
+    int pubSz = 0;
+    int idx = 0;
+    byte scratch[MAX_ALGO_SZ];
+
+    /* Get size of entire key */
+
+    /*  SEQUENCE               <--| SetAlgoId
+     *      OBJECT IDENTIFIER  <--|
+     *      SEQUENCE     <--
+     *          INTEGER    | wc_DhParamsToDer
+     *          INTEGER  <--
+     */
+    ret = wc_DhParamsToDer(key, NULL, &paramSz);
+    if (ret != LENGTH_ONLY_E)
+        return ASN_PARSE_E;
+    sz += paramSz;
+    sz += SetAlgoID(DHk, scratch, oidKeyType, paramSz);
+
+    /*  BIT STRING
+     *      INTEGER
+     */
+    pubSz = mp_unsigned_bin_size(&key->pub);
+    if (pubSz < 0)
+        return pubSz;
+
+    if (mp_leading_bit(&key->pub))
+        pubSz++;
+
+    sz += ASN_TAG_SZ; /* Integer */
+    sz += SetLength(pubSz, scratch);
+    sz += pubSz;
+
+    sz += SetBitString(pubSz, 0, scratch);
+
+    if (out == NULL) {
+        /* Uppermost SEQUENCE */
+        *outSz = sz + SetSequence(sz, scratch);
+        return LENGTH_ONLY_E;
+    }
+    /* end get size of entire key */
+
+    /* Check for indexing errors */
+    if (*outSz < MAX_SEQ_SZ || *outSz < sz) {
+        return BUFFER_E;
+    }
+
+    /* Build Up Entire Key */
+
+    idx += SetSequence(sz, out);
+
+    idx += SetAlgoID(DHk, out+idx, oidKeyType, paramSz);
+    ret = wc_DhParamsToDer(key, out+idx, &paramSz);
+    if (ret < 0)
+        return ret;
+    idx += ret;
+
+    /* BIT STRING
+     *   INTEGER
+     */
+    idx += SetBitString(pubSz, 0, out+idx);
+
+    out[idx++] = ASN_INTEGER;
+    idx += SetLength(pubSz, out + idx);
+    if (mp_leading_bit(&key->pub)) {
+        out[idx++] = 0x00;
+        pubSz -= 1; /* subtract 1 from size to account for leading 0 */
+    }
+    ret = mp_to_unsigned_bin(&key->pub, out + idx);
+    if (ret != MP_OKAY) {
+        return BUFFER_E;
+    }
+    idx += pubSz;
+
+    return idx;
+}
+
+int wc_DhPrivKeyToDer(DhKey* key, byte* out, word32* outSz)
+{
+    word32 sz = 0;
+    word32 paramSz = 0;
+    int ret;
+    int privSz = 0;
+    int idx = 0;
+    byte scratch[MAX_ALGO_SZ];
+
+    /* Get size of entire key */
+
+    /*  INTEGER 0 */
+    sz += ASN_TAG_SZ; /* Integer */
+    sz += SetLength(1, scratch);
+    sz += 1;
+
+    /*  SEQUENCE               <--| SetAlgoId
+     *      OBJECT IDENTIFIER  <--|
+     *      SEQUENCE       <--
+     *          INTEGER       | wc_DhParamsToDer
+     *          INTEGER     <--
+     */
+    ret = wc_DhParamsToDer(key, NULL, &paramSz);
+    if (ret != LENGTH_ONLY_E)
+        return ASN_PARSE_E;
+    sz += paramSz;
+    sz += SetAlgoID(DHk, scratch, oidKeyType, paramSz);
+
+    /*  OCTET STRING
+     *      INTEGER
+     */
+    privSz = mp_unsigned_bin_size(&key->priv);
+    if (privSz < 0)
+        return privSz;
+    else if (privSz > 256) /* Key is larger than 2048 */
+        return ASN_VERSION_E;
+
+    if (mp_leading_bit(&key->priv))
+        privSz++;
+
+    sz += ASN_TAG_SZ; /* Integer */
+    sz += SetLength(privSz, scratch);
+    sz += privSz;
+
+    sz += SetOctetString(privSz + ASN_OCTET_STRING, scratch);
+
+    if (out == NULL) {
+        /* Uppermost SEQUENCE */
+        *outSz = sz + SetSequence(sz, scratch);
+        return LENGTH_ONLY_E;
+    }
+    /* end get size of entire key */
+
+    /* Check for indexing errors */
+    if (*outSz < MAX_SEQ_SZ || *outSz < sz) {
+        return BUFFER_E;
+    }
+
+    /* Build Up Entire Key */
+
+    idx += SetSequence(sz, out);
+
+    /* INTEGER 0 */
+    out[idx++] = ASN_INTEGER;
+    idx += SetLength(1, out+idx);
+    out[idx++] = 0;
+
+    idx += SetAlgoID(DHk, out+idx, oidKeyType, paramSz);
+    ret = wc_DhParamsToDer(key, out+idx, &paramSz);
+    if (ret < 0)
+        return ret;
+    idx += ret;
+
+    /* OCTET STRING
+     *   INTEGER
+     */
+    if (privSz == 256) {
+        idx += SetOctetString(privSz + ASN_OCTET_STRING, out+idx);
+    } else if (privSz == 128) {
+        idx += SetOctetString(privSz + ASN_OCTET_STRING-1, out+idx);
+    } else if (privSz == 64) {
+        idx += SetOctetString(privSz + ASN_OCTET_STRING-2, out+idx);
+    } else {
+        WOLFSSL_MSG("Unsupported key size");
+        return ASN_VERSION_E;
+    }
+
+    out[idx++] = ASN_INTEGER;
+    idx += SetLength(privSz, out + idx);
+    if (mp_leading_bit(&key->priv)) {
+        out[idx++] = 0x00;
+        privSz -= 1; /* subtract 1 from size to account for leading 0 */
+    }
+    ret = mp_to_unsigned_bin(&key->priv, out + idx);
+    if (ret != MP_OKAY) {
+        return BUFFER_E;
+    }
+    idx += privSz;
+
+    return idx;
+}
+
+/* Writes the DH parameters in PEM format from "dh" out to the file pointer
+ * passed in.
+ *
+ * returns WOLFSSL_SUCCESS on success
+ */
+int wolfSSL_PEM_write_DHparams(XFILE fp, WOLFSSL_DH* dh)
+{
+    int ret;
+    word32 derSz = 0, pemSz = 0;
+    byte *der, *pem;
+    DhKey* key;
+
+    WOLFSSL_ENTER("wolfSSL_PEM_write_DHparams");
+
+    if (dh == NULL) {
+        WOLFSSL_LEAVE("wolfSSL_PEM_write_DHparams", BAD_FUNC_ARG);
+        return WOLFSSL_FAILURE;
+    }
+
+    if (dh->inSet == 0) {
+        if (SetDhInternal(dh) != WOLFSSL_SUCCESS) {
+            WOLFSSL_MSG("Unable to set internal DH structure");
+            return WOLFSSL_FAILURE;
+        }
+    }
+    key = (DhKey*)dh->internal;
+    ret = wc_DhParamsToDer(key, NULL, &derSz);
+    if (ret != LENGTH_ONLY_E) {
+        WOLFSSL_MSG("Failed to get size of DH params");
+        WOLFSSL_LEAVE("wolfSSL_PEM_write_DHparams", ret);
+        return WOLFSSL_FAILURE;
+    }
+
+    der = (byte*)XMALLOC(derSz, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
+    if (der == NULL) {
+        WOLFSSL_LEAVE("wolfSSL_PEM_write_DHparams", MEMORY_E);
+        return WOLFSSL_FAILURE;
+    }
+    ret = wc_DhParamsToDer(key, der, &derSz);
+    if (ret <= 0) {
+        WOLFSSL_MSG("Failed to export DH params");
+        WOLFSSL_LEAVE("wolfSSL_PEM_write_DHparams", ret);
+        XFREE(der, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
+        return WOLFSSL_FAILURE;
+    }
+
+    /* convert to PEM */
+    ret = wc_DerToPem(der, derSz, NULL, 0, DH_PARAM_TYPE);
+    if (ret < 0) {
+        WOLFSSL_MSG("Failed to convert DH params to PEM");
+        WOLFSSL_LEAVE("wolfSSL_PEM_write_DHparams", ret);
+        XFREE(der, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
+        return ret;
+    }
+    pemSz = (word32)ret;
+
+    pem = (byte*)XMALLOC(pemSz, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
+    if (pem == NULL) {
+        WOLFSSL_LEAVE("wolfSSL_PEM_write_DHparams", MEMORY_E);
+        XFREE(der, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
+        return ret;
+    }
+    ret = wc_DerToPem(der, derSz, pem, pemSz, DH_PARAM_TYPE);
+    XFREE(der, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
+    if (ret < 0) {
+        WOLFSSL_MSG("Failed to convert DH params to PEM");
+        WOLFSSL_LEAVE("wolfSSL_PEM_write_DHparams", ret);
+        XFREE(pem, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
+        return ret;
+    }
+
+    ret = (int)XFWRITE(pem, 1, pemSz, fp);
+    XFREE(pem, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
+    if (ret <= 0) {
+        WOLFSSL_MSG("Failed to write to file");
+        WOLFSSL_LEAVE("wolfSSL_PEM_write_DHparams", ret);
+        return WOLFSSL_FAILURE;
+    }
+
+    WOLFSSL_LEAVE("wolfSSL_PEM_write_DHparams", WOLFSSL_SUCCESS);
+    return WOLFSSL_SUCCESS;
+}
+#endif /* WOLFSSL_QT || OPENSSL_ALL */
+#endif /* !NO_FILESYSTEM */
+#endif /* !NO_DH */
+
+#ifdef WOLFSSL_CERT_GEN
+
+#ifdef WOLFSSL_CERT_REQ
+/* writes the x509 from x to the WOLFSSL_BIO bp
+ *
+ * returns WOLFSSL_SUCCESS on success and WOLFSSL_FAILURE on fail
+ */
+int wolfSSL_PEM_write_bio_X509_REQ(WOLFSSL_BIO *bp, WOLFSSL_X509 *x)
+{
+    byte* pem;
+    int   pemSz = 0;
+    const unsigned char* der;
+    int derSz;
+    int ret;
+
+    WOLFSSL_ENTER("wolfSSL_PEM_write_bio_X509_REQ()");
+
+    if (x == NULL || bp == NULL) {
+        return WOLFSSL_FAILURE;
+    }
+
+    der = wolfSSL_X509_get_der(x, &derSz);
+    if (der == NULL) {
+        return WOLFSSL_FAILURE;
+    }
+
+    /* get PEM size */
+    pemSz = wc_DerToPemEx(der, derSz, NULL, 0, NULL, CERTREQ_TYPE);
+    if (pemSz < 0) {
+        return WOLFSSL_FAILURE;
+    }
+
+    /* create PEM buffer and convert from DER */
+    pem = (byte*)XMALLOC(pemSz, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    if (pem == NULL) {
+        return WOLFSSL_FAILURE;
+    }
+    if (wc_DerToPemEx(der, derSz, pem, pemSz, NULL, CERTREQ_TYPE) < 0) {
+        XFREE(pem, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+        return WOLFSSL_FAILURE;
+    }
+
+    /* write the PEM to BIO */
+    ret = wolfSSL_BIO_write(bp, pem, pemSz);
+    XFREE(pem, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+
+    if (ret <= 0) return WOLFSSL_FAILURE;
+    return WOLFSSL_SUCCESS;
+}
+#endif /* WOLFSSL_CERT_REQ */
+
+
+/* writes the x509 from x to the WOLFSSL_BIO bp
+ *
+ * returns WOLFSSL_SUCCESS on success and WOLFSSL_FAILURE on fail
+ */
+int wolfSSL_PEM_write_bio_X509_AUX(WOLFSSL_BIO *bp, WOLFSSL_X509 *x)
+{
+    byte* pem;
+    int   pemSz = 0;
+    const unsigned char* der;
+    int derSz;
+    int ret;
+
+    WOLFSSL_ENTER("wolfSSL_PEM_write_bio_X509_AUX()");
+
+    if (bp == NULL || x == NULL) {
+        WOLFSSL_MSG("NULL argument passed in");
+        return WOLFSSL_FAILURE;
+    }
+
+    der = wolfSSL_X509_get_der(x, &derSz);
+    if (der == NULL) {
+        return WOLFSSL_FAILURE;
+    }
+
+    /* get PEM size */
+    pemSz = wc_DerToPemEx(der, derSz, NULL, 0, NULL, CERT_TYPE);
+    if (pemSz < 0) {
+        return WOLFSSL_FAILURE;
+    }
+
+    /* create PEM buffer and convert from DER */
+    pem = (byte*)XMALLOC(pemSz, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    if (pem == NULL) {
+        return WOLFSSL_FAILURE;
+    }
+    if (wc_DerToPemEx(der, derSz, pem, pemSz, NULL, CERT_TYPE) < 0) {
+        XFREE(pem, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+        return WOLFSSL_FAILURE;
+    }
+
+    /* write the PEM to BIO */
+    ret = wolfSSL_BIO_write(bp, pem, pemSz);
+    XFREE(pem, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+
+    if (ret <= 0) return WOLFSSL_FAILURE;
+    return WOLFSSL_SUCCESS;
+}
+#endif /* WOLFSSL_CERT_GEN */
+
+int wolfSSL_PEM_write_bio_X509(WOLFSSL_BIO *bio, WOLFSSL_X509 *cert)
+{
+    byte* pem;
+    int   pemSz = 0;
+    const unsigned char* der;
+    int derSz;
+    int ret;
+
+    WOLFSSL_ENTER("wolfSSL_PEM_write_bio_X509_AUX()");
+
+    if (bio == NULL || cert == NULL) {
+        WOLFSSL_MSG("NULL argument passed in");
+        return WOLFSSL_FAILURE;
+    }
+
+    der = wolfSSL_X509_get_der(cert, &derSz);
+    if (der == NULL) {
+        return WOLFSSL_FAILURE;
+    }
+
+    /* get PEM size */
+    pemSz = wc_DerToPemEx(der, derSz, NULL, 0, NULL, CERT_TYPE);
+    if (pemSz < 0) {
+        return WOLFSSL_FAILURE;
+    }
+
+    /* create PEM buffer and convert from DER */
+    pem = (byte*)XMALLOC(pemSz, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    if (pem == NULL) {
+        return WOLFSSL_FAILURE;
+    }
+    if (wc_DerToPemEx(der, derSz, pem, pemSz, NULL, CERT_TYPE) < 0) {
+        XFREE(pem, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+        return WOLFSSL_FAILURE;
+    }
+
+    /* write the PEM to BIO */
+    ret = wolfSSL_BIO_write(bio, pem, pemSz);
+    XFREE(pem, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+
+    if (ret <= 0) return WOLFSSL_FAILURE;
+    return WOLFSSL_SUCCESS;
+}
+
+
+#if defined(OPENSSL_EXTRA) && !defined(NO_DH)
+/* Initialize ctx->dh with dh's params. Return WOLFSSL_SUCCESS on ok */
+long wolfSSL_CTX_set_tmp_dh(WOLFSSL_CTX* ctx, WOLFSSL_DH* dh)
+{
+    int pSz, gSz;
+    byte *p, *g;
+    int ret=0;
+
+    WOLFSSL_ENTER("wolfSSL_CTX_set_tmp_dh");
+
+    if(!ctx || !dh)
+        return BAD_FUNC_ARG;
+
+    /* Get needed size for p and g */
+    pSz = wolfSSL_BN_bn2bin(dh->p, NULL);
+    gSz = wolfSSL_BN_bn2bin(dh->g, NULL);
+
+    if(pSz <= 0 || gSz <= 0)
+        return WOLFSSL_FATAL_ERROR;
+
+    p = (byte*)XMALLOC(pSz, ctx->heap, DYNAMIC_TYPE_PUBLIC_KEY);
+    if(!p)
+        return MEMORY_E;
+
+    g = (byte*)XMALLOC(gSz, ctx->heap, DYNAMIC_TYPE_PUBLIC_KEY);
+    if(!g) {
+        XFREE(p, ctx->heap, DYNAMIC_TYPE_PUBLIC_KEY);
+        return MEMORY_E;
+    }
+
+    pSz = wolfSSL_BN_bn2bin(dh->p, p);
+    gSz = wolfSSL_BN_bn2bin(dh->g, g);
+
+    if(pSz >= 0 && gSz >= 0) /* Conversion successful */
+        ret = wolfSSL_CTX_SetTmpDH(ctx, p, pSz, g, gSz);
+
+    XFREE(p, ctx->heap, DYNAMIC_TYPE_PUBLIC_KEY);
+    XFREE(g, ctx->heap, DYNAMIC_TYPE_PUBLIC_KEY);
+
+    return pSz > 0 && gSz > 0 ? ret : WOLFSSL_FATAL_ERROR;
+}
+#endif /* OPENSSL_EXTRA && !NO_DH */
+
+
+/* returns the enum value associated with handshake state
+ *
+ * ssl the WOLFSSL structure to get state of
+ */
+int wolfSSL_get_state(const WOLFSSL* ssl)
+{
+    WOLFSSL_ENTER("wolfSSL_get_state");
+
+    if (ssl == NULL) {
+        WOLFSSL_MSG("Null argument passed in");
+        return SSL_FAILURE;
+    }
+
+    return ssl->options.handShakeState;
+}
+#endif /* HAVE_LIGHTY || HAVE_STUNNEL || WOLFSSL_MYSQL_COMPATIBLE */
+
+#if defined(OPENSSL_ALL) || defined(WOLFSSL_ASIO) || defined(WOLFSSL_HAPROXY) \
+    || defined(WOLFSSL_NGINX) || defined(WOLFSSL_QT)
+
+long wolfSSL_ctrl(WOLFSSL* ssl, int cmd, long opt, void* pt)
+{
+    WOLFSSL_ENTER("wolfSSL_ctrl");
+    if (ssl == NULL)
+        return BAD_FUNC_ARG;
+
+    switch (cmd) {
+        #if defined(WOLFSSL_NGINX) || defined(WOLFSSL_QT) || defined(OPENSSL_ALL)
+        case SSL_CTRL_SET_TLSEXT_HOSTNAME:
+            WOLFSSL_MSG("Entering Case: SSL_CTRL_SET_TLSEXT_HOSTNAME.");
+        #ifdef HAVE_SNI
+            if (pt == NULL) {
+                WOLFSSL_MSG("Passed in NULL Host Name.");
+                break;
+            }
+            return wolfSSL_set_tlsext_host_name(ssl, (const char*) pt);
+        #else
+            WOLFSSL_MSG("SNI not enabled.");
+            break;
+        #endif /* HAVE_SNI */
+        #endif /* WOLFSSL_NGINX || WOLFSSL_QT || OPENSSL_ALL */
+        default:
+            WOLFSSL_MSG("Case not implemented.");
+    }
+    (void)opt;
+    (void)pt;
+    return WOLFSSL_FAILURE;
+}
+
+long wolfSSL_CTX_ctrl(WOLFSSL_CTX* ctx, int cmd, long opt, void* pt)
+{
+#if defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER)
+    long ctrl_opt;
+#endif
+    long ret = WOLFSSL_SUCCESS;
+
+    WOLFSSL_ENTER("wolfSSL_CTX_ctrl");
+    if (ctx == NULL)
+        return WOLFSSL_FAILURE;
+
+    switch (cmd) {
+    case SSL_CTRL_CHAIN:
+#ifdef SESSION_CERTS
+    {
+        /*
+         * We don't care about opt here because a copy of the certificate is
+         * stored anyway so increasing the reference counter is not necessary.
+         * Just check to make sure that it is set to one of the correct values.
+         */
+        WOLF_STACK_OF(WOLFSSL_X509)* sk = (WOLF_STACK_OF(WOLFSSL_X509)*) pt;
+        WOLFSSL_X509* x509;
+        int i;
+        if (opt != 0 && opt != 1) {
+            ret = WOLFSSL_FAILURE;
+            break;
+        }
+        /* Clear certificate chain */
+        FreeDer(&ctx->certChain);
+        if (sk) {
+            for (i = 0; i < wolfSSL_sk_X509_num(sk); i++) {
+                x509 = wolfSSL_sk_X509_value(sk, i);
+                /* Prevent wolfSSL_CTX_add_extra_chain_cert from freeing cert */
+                if (wolfSSL_X509_up_ref(x509) != 1) {
+                    WOLFSSL_MSG("Error increasing reference count");
+                    continue;
+                }
+                if (wolfSSL_CTX_add_extra_chain_cert(ctx, x509) !=
+                        WOLFSSL_SUCCESS) {
+                    WOLFSSL_MSG("Error adding certificate to context");
+                    /* Decrease reference count on failure */
+                    wolfSSL_X509_free(x509);
+                }
+            }
+        }
+        /* Free previous chain */
+        wolfSSL_sk_X509_free(ctx->x509Chain);
+        ctx->x509Chain = sk;
+        if (sk) {
+            for (i = 0; i < wolfSSL_sk_X509_num(sk); i++) {
+                x509 = wolfSSL_sk_X509_value(sk, i);
+                /* On successful setting of new chain up all refs */
+                if (wolfSSL_X509_up_ref(x509) != 1) {
+                    WOLFSSL_MSG("Error increasing reference count");
+                    continue;
+                }
+            }
+        }
+    }
+#else
+        WOLFSSL_MSG("Session certificates not compiled in");
+        ret = WOLFSSL_FAILURE;
+#endif
+        break;
+
+#if defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER)
+    case SSL_CTRL_OPTIONS:
+        WOLFSSL_MSG("Entering Case: SSL_CTRL_OPTIONS.");
+        ctrl_opt = wolfSSL_CTX_set_options(ctx, opt);
+
+        #ifdef WOLFSSL_QT
+        /* Set whether to use client or server cipher preference */
+        if ((ctrl_opt & SSL_OP_CIPHER_SERVER_PREFERENCE)
+                     == SSL_OP_CIPHER_SERVER_PREFERENCE) {
+            WOLFSSL_MSG("Using Server's Cipher Preference.");
+            ctx->useClientOrder = FALSE;
+        } else {
+            WOLFSSL_MSG("Using Client's Cipher Preference.");
+            ctx->useClientOrder = TRUE;
+        }
+        #endif /* WOLFSSL_QT */
+
+        return ctrl_opt;
+#endif /* OPENSSL_EXTRA || HAVE_WEBSERVER */
+    case SSL_CTRL_EXTRA_CHAIN_CERT:
+        WOLFSSL_MSG("Entering Case: SSL_CTRL_EXTRA_CHAIN_CERT.");
+        if (pt == NULL) {
+            WOLFSSL_MSG("Passed in x509 pointer NULL.");
+            ret = WOLFSSL_FAILURE;
+            break;
+        }
+        return wolfSSL_CTX_add_extra_chain_cert(ctx, (WOLFSSL_X509*)pt);
+
+#ifndef NO_DH
+    case SSL_CTRL_SET_TMP_DH:
+        WOLFSSL_MSG("Entering Case: SSL_CTRL_SET_TMP_DH.");
+        if (pt == NULL) {
+            WOLFSSL_MSG("Passed in DH pointer NULL.");
+            ret = WOLFSSL_FAILURE;
+            break;
+        }
+        return wolfSSL_CTX_set_tmp_dh(ctx, (WOLFSSL_DH*)pt);
+#endif
+
+#ifdef HAVE_ECC
+    case SSL_CTRL_SET_TMP_ECDH:
+        WOLFSSL_MSG("Entering Case: SSL_CTRL_SET_TMP_ECDH.");
+        if (pt == NULL) {
+            WOLFSSL_MSG("Passed in ECDH pointer NULL.");
+            ret = WOLFSSL_FAILURE;
+            break;
+        }
+        return wolfSSL_SSL_CTX_set_tmp_ecdh(ctx, (WOLFSSL_EC_KEY*)pt);
+#endif
+    case SSL_CTRL_MODE:
+        wolfSSL_CTX_set_mode(ctx,opt);
+        break;
+
+    default:
+        WOLFSSL_MSG("CTX_ctrl cmd not implemented");
+        ret = WOLFSSL_FAILURE;
+        break;
+    }
+
+    (void)ctx;
+    (void)cmd;
+    (void)opt;
+    (void)pt;
+    WOLFSSL_LEAVE("wolfSSL_CTX_ctrl", (int)ret);
+    return ret;
+}
+
+#ifndef WOLFSSL_NO_STUB
+long wolfSSL_CTX_callback_ctrl(WOLFSSL_CTX* ctx, int cmd, void (*fp)(void))
+{
+    (void) ctx;
+    (void) cmd;
+    (void) fp;
+    WOLFSSL_STUB("wolfSSL_CTX_callback_ctrl");
+    return WOLFSSL_FAILURE;
+
+}
+#endif /* WOLFSSL_NO_STUB */
+
+#ifndef NO_WOLFSSL_STUB
+long wolfSSL_CTX_clear_extra_chain_certs(WOLFSSL_CTX* ctx)
+{
+    return wolfSSL_CTX_ctrl(ctx, SSL_CTRL_CLEAR_EXTRA_CHAIN_CERTS, 0l, NULL);
+}
+#endif
+
+/* Returns the verifyCallback from the ssl structure if successful.
+Returns NULL otherwise. */
+VerifyCallback wolfSSL_get_verify_callback(WOLFSSL* ssl)
+{
+    WOLFSSL_ENTER("wolfSSL_get_verify_callback()");
+    if (ssl) {
+        return ssl->verifyCallback;
+    }
+    return NULL;
+}
+
+/* Creates a new bio pair.
+Returns WOLFSSL_SUCCESS if no error, WOLFSSL_FAILURE otherwise.*/
+int wolfSSL_BIO_new_bio_pair(WOLFSSL_BIO **bio1_p, size_t writebuf1,
+                                         WOLFSSL_BIO **bio2_p, size_t writebuf2)
+{
+    WOLFSSL_BIO *bio1 = NULL, *bio2 = NULL;
+    int ret = 1;
+
+    WOLFSSL_ENTER("wolfSSL_BIO_new_bio_pair()");
+
+    if (bio1_p == NULL || bio2_p == NULL) {
+        WOLFSSL_MSG("Bad Function Argument");
+        return BAD_FUNC_ARG;
+    }
+
+    /* set up the new bio structures and write buf sizes */
+    if ((bio1 = wolfSSL_BIO_new(wolfSSL_BIO_s_bio())) == NULL) {
+        WOLFSSL_MSG("Bio allocation failed");
+        ret = WOLFSSL_FAILURE;
+    }
+    if (ret) {
+        if ((bio2 = wolfSSL_BIO_new(wolfSSL_BIO_s_bio())) == NULL) {
+            WOLFSSL_MSG("Bio allocation failed");
+            ret = WOLFSSL_FAILURE;
+        }
+    }
+    if (ret && writebuf1) {
+        if (!(ret = wolfSSL_BIO_set_write_buf_size(bio1, writebuf1))) {
+            WOLFSSL_MSG("wolfSSL_BIO_set_write_buf() failure");
+        }
+    }
+    if (ret && writebuf2) {
+        if (!(ret = wolfSSL_BIO_set_write_buf_size(bio2, writebuf2))) {
+            WOLFSSL_MSG("wolfSSL_BIO_set_write_buf() failure");
+        }
+    }
+
+    if (ret) {
+        if ((ret = wolfSSL_BIO_make_bio_pair(bio1, bio2))) {
+            *bio1_p = bio1;
+            *bio2_p = bio2;
+        }
+    }
+    if (!ret) {
+        wolfSSL_BIO_free(bio1);
+        bio1 = NULL;
+        wolfSSL_BIO_free(bio2);
+        bio2 = NULL;
+    }
+    return ret;
+}
+
+
+#if !defined(HAVE_FAST_RSA) && defined(WOLFSSL_KEY_GEN) && \
+    !defined(NO_RSA) && !defined(HAVE_USER_RSA)
+/* Converts an rsa key from a bio buffer into an internal rsa structure.
+Returns a pointer to the new WOLFSSL_RSA structure. */
+WOLFSSL_RSA* wolfSSL_d2i_RSAPrivateKey_bio(WOLFSSL_BIO *bio, WOLFSSL_RSA **out)
+{
+    const unsigned char* bioMem = NULL;
+    int bioMemSz = 0;
+    WOLFSSL_RSA* key = NULL;
+    unsigned char maxKeyBuf[4096];
+    unsigned char* bufPtr = NULL;
+    unsigned char* extraBioMem = NULL;
+    int extraBioMemSz = 0;
+    int derLength = 0;
+    int j = 0, i = 0;
+
+    WOLFSSL_ENTER("wolfSSL_d2i_RSAPrivateKey_bio()");
+
+    if (bio == NULL) {
+        WOLFSSL_MSG("Bad Function Argument");
+        return NULL;
+    }
+    (void)out;
+
+    bioMemSz = wolfSSL_BIO_pending(bio);
+    if (bioMemSz <= 0) {
+        WOLFSSL_MSG("wolfSSL_BIO_pending() failure");
+        return NULL;
+    }
+
+    bioMem = (unsigned char*)XMALLOC(bioMemSz, bio->heap, DYNAMIC_TYPE_TMP_BUFFER);
+    if (bioMem == NULL) {
+        WOLFSSL_MSG("Malloc failure");
+        return NULL;
+    }
+
+    bufPtr = maxKeyBuf;
+    if (wolfSSL_BIO_read(bio, (unsigned char*)bioMem, (int)bioMemSz) == bioMemSz) {
+        const byte* bioMemPt = bioMem; /* leave bioMem pointer unaltered */
+        if ((key = wolfSSL_d2i_RSAPrivateKey(NULL, &bioMemPt, bioMemSz)) == NULL) {
+            XFREE((unsigned char*)bioMem, bio->heap, DYNAMIC_TYPE_TMP_BUFFER);
+            return NULL;
+        }
+
+        /* This function is used to get the total length of the rsa key. */
+        derLength = wolfSSL_i2d_RSAPrivateKey(key, &bufPtr);
+
+        /* Write extra data back into bio object if necessary. */
+        extraBioMemSz = (bioMemSz - derLength);
+        if (extraBioMemSz > 0) {
+            extraBioMem = (unsigned char *)XMALLOC(extraBioMemSz, NULL,
+                                                       DYNAMIC_TYPE_TMP_BUFFER);
+            if (extraBioMem == NULL) {
+                WOLFSSL_MSG("Malloc failure");
+                XFREE((unsigned char*)extraBioMem, bio->heap,
+                                                       DYNAMIC_TYPE_TMP_BUFFER);
+                XFREE((unsigned char*)bioMem, bio->heap,
+                                                       DYNAMIC_TYPE_TMP_BUFFER);
+                return NULL;
+            }
+
+            for (i = derLength; i < bioMemSz; i++) {
+                *(extraBioMem + j) = *(bioMem + i);
+                j++;
+            }
+
+            wolfSSL_BIO_write(bio, extraBioMem, extraBioMemSz);
+            if (wolfSSL_BIO_pending(bio) <= 0) {
+                WOLFSSL_MSG("Failed to write memory to bio");
+                XFREE((unsigned char*)extraBioMem, bio->heap,
+                                                       DYNAMIC_TYPE_TMP_BUFFER);
+                XFREE((unsigned char*)bioMem, bio->heap,
+                                                       DYNAMIC_TYPE_TMP_BUFFER);
+                return NULL;
+            }
+            XFREE((unsigned char*)extraBioMem, bio->heap,
+                                                       DYNAMIC_TYPE_TMP_BUFFER);
+        }
+
+        if (out != NULL && key != NULL) {
+            *out = key;
+        }
+    }
+    XFREE((unsigned char*)bioMem, bio->heap, DYNAMIC_TYPE_TMP_BUFFER);
+    return key;
+}
+#endif
+
+
+/* Adds the ASN1 certificate to the user ctx.
+Returns WOLFSSL_SUCCESS if no error, returns WOLFSSL_FAILURE otherwise.*/
+int wolfSSL_CTX_use_certificate_ASN1(WOLFSSL_CTX *ctx, int derSz,
+                                                       const unsigned char *der)
+{
+    WOLFSSL_ENTER("wolfSSL_CTX_use_certificate_ASN1()");
+    if (der != NULL && ctx != NULL) {
+        if (wolfSSL_CTX_use_certificate_buffer(ctx, der, derSz,
+                                      WOLFSSL_FILETYPE_ASN1) == WOLFSSL_SUCCESS) {
+            return WOLFSSL_SUCCESS;
+        }
+
+    }
+    return WOLFSSL_FAILURE;
+}
+
+
+#if !defined(HAVE_FAST_RSA) && defined(WOLFSSL_KEY_GEN) && \
+    !defined(NO_RSA) && !defined(HAVE_USER_RSA)
+/* Adds the rsa private key to the user ctx.
+Returns WOLFSSL_SUCCESS if no error, returns WOLFSSL_FAILURE otherwise.*/
+int wolfSSL_CTX_use_RSAPrivateKey(WOLFSSL_CTX* ctx, WOLFSSL_RSA* rsa)
+{
+    int ret;
+    int derSize;
+    unsigned char maxDerBuf[4096];
+    unsigned char* key = NULL;
+
+    WOLFSSL_ENTER("wolfSSL_CTX_use_RSAPrivateKey()");
+
+    if (ctx == NULL || rsa == NULL) {
+        WOLFSSL_MSG("one or more inputs were NULL");
+        return BAD_FUNC_ARG;
+    }
+    key = maxDerBuf;
+    /* convert RSA struct to der encoded buffer and get the size */
+    if ((derSize = wolfSSL_i2d_RSAPrivateKey(rsa, &key)) <= 0) {
+        WOLFSSL_MSG("wolfSSL_i2d_RSAPrivateKey() failure");
+        return WOLFSSL_FAILURE;
+    }
+    ret = wolfSSL_CTX_use_PrivateKey_buffer(ctx, (const unsigned char*)maxDerBuf,
+                                                    derSize, SSL_FILETYPE_ASN1);
+    if (ret != WOLFSSL_SUCCESS) {
+        WOLFSSL_MSG("wolfSSL_CTX_USE_PrivateKey_buffer() failure");
+        return WOLFSSL_FAILURE;
+    }
+    return ret;
+}
+#endif /* NO_RSA && !HAVE_FAST_RSA */
+
+
+/* Converts EVP_PKEY data from a bio buffer to a WOLFSSL_EVP_PKEY structure.
+Returns pointer to private EVP_PKEY struct upon success, NULL if there
+is a failure.*/
+WOLFSSL_EVP_PKEY* wolfSSL_d2i_PrivateKey_bio(WOLFSSL_BIO* bio,
+                                                         WOLFSSL_EVP_PKEY** out)
+{
+    unsigned char* mem = NULL;
+    int memSz = 0;
+    WOLFSSL_EVP_PKEY* key = NULL;
+    int i = 0, j = 0;
+    unsigned char* extraBioMem = NULL;
+    int extraBioMemSz = 0;
+    int derLength = 0;
+
+    WOLFSSL_ENTER("wolfSSL_d2i_PrivateKey_bio()");
+
+    if (bio == NULL) {
+        return NULL;
+    }
+    (void)out;
+
+    memSz = wolfSSL_BIO_pending(bio);
+    if (memSz <= 0) {
+        WOLFSSL_MSG("wolfSSL_BIO_pending() failure");
+        return NULL;
+    }
+
+    mem = (unsigned char*)XMALLOC(memSz, bio->heap, DYNAMIC_TYPE_TMP_BUFFER);
+    if (mem == NULL) {
+        WOLFSSL_MSG("Malloc failure");
+        return NULL;
+    }
+
+    if (wolfSSL_BIO_read(bio, (unsigned char*)mem, memSz) == memSz) {
+        /* Determines key type and returns the new private EVP_PKEY object */
+        if ((key = wolfSSL_d2i_PrivateKey_EVP(NULL, &mem, (long)memSz)) == NULL) {
+            WOLFSSL_MSG("wolfSSL_d2i_PrivateKey_EVP() failure");
+            XFREE(mem, bio->heap, DYNAMIC_TYPE_TMP_BUFFER);
+            return NULL;
+        }
+
+        /* Write extra data back into bio object if necessary. */
+        derLength = key->pkey_sz;
+        extraBioMemSz = (memSz - derLength);
+        if (extraBioMemSz > 0) {
+            extraBioMem = (unsigned char *)XMALLOC(extraBioMemSz, NULL,
+                                                       DYNAMIC_TYPE_TMP_BUFFER);
+            if (extraBioMem == NULL) {
+                WOLFSSL_MSG("Malloc failure");
+                XFREE((unsigned char*)extraBioMem, bio->heap,
+                                                       DYNAMIC_TYPE_TMP_BUFFER);
+                XFREE(mem, bio->heap, DYNAMIC_TYPE_TMP_BUFFER);
+                return NULL;
+            }
+
+            for (i = derLength; i < memSz; i++) {
+                *(extraBioMem + j) = *(mem + i);
+                j++;
+            }
+
+            wolfSSL_BIO_write(bio, extraBioMem, extraBioMemSz);
+            if (wolfSSL_BIO_pending(bio) <= 0) {
+                WOLFSSL_MSG("Failed to write memory to bio");
+                XFREE((unsigned char*)extraBioMem, bio->heap,
+                                                       DYNAMIC_TYPE_TMP_BUFFER);
+                XFREE(mem, bio->heap, DYNAMIC_TYPE_TMP_BUFFER);
+                return NULL;
+            }
+            XFREE((unsigned char*)extraBioMem, bio->heap,
+                                                       DYNAMIC_TYPE_TMP_BUFFER);
+        }
+
+        if (out != NULL) {
+            *out = key;
+        }
+    }
+    XFREE(mem, bio->heap, DYNAMIC_TYPE_TMP_BUFFER);
+    return key;
+}
+
+
+/* Converts a DER encoded private key to a WOLFSSL_EVP_PKEY structure.
+ * returns a pointer to a new WOLFSSL_EVP_PKEY structure on success and NULL
+ * on fail */
+WOLFSSL_EVP_PKEY* wolfSSL_d2i_PrivateKey_EVP(WOLFSSL_EVP_PKEY** out,
+                                                  unsigned char** in, long inSz)
+{
+    WOLFSSL_EVP_PKEY* pkey = NULL;
+    const unsigned char* mem;
+    long memSz = inSz;
+
+    WOLFSSL_ENTER("wolfSSL_d2i_PrivateKey_EVP()");
+
+    if (in == NULL || *in == NULL || inSz < 0) {
+        WOLFSSL_MSG("Bad argument");
+        return NULL;
+    }
+    mem = *in;
+
+    #if !defined(NO_RSA)
+    {
+        RsaKey rsa;
+        word32 keyIdx = 0;
+
+        /* test if RSA key */
+        if (wc_InitRsaKey(&rsa, NULL) == 0 &&
+            wc_RsaPrivateKeyDecode(mem, &keyIdx, &rsa, (word32)memSz) == 0) {
+            wc_FreeRsaKey(&rsa);
+            pkey = wolfSSL_EVP_PKEY_new();
+            if (pkey != NULL) {
+                pkey->pkey_sz = keyIdx;
+                pkey->pkey.ptr = (char*)XMALLOC(memSz, NULL,
+                        DYNAMIC_TYPE_PRIVATE_KEY);
+                if (pkey->pkey.ptr == NULL) {
+                    wolfSSL_EVP_PKEY_free(pkey);
+                    return NULL;
+                }
+                XMEMCPY(pkey->pkey.ptr, mem, keyIdx);
+                pkey->type = EVP_PKEY_RSA;
+                if (out != NULL) {
+                    *out = pkey;
+                }
+
+                pkey->ownRsa = 1;
+                pkey->rsa = wolfSSL_RSA_new();
+                if (pkey->rsa == NULL) {
+                    wolfSSL_EVP_PKEY_free(pkey);
+                    return NULL;
+                }
+
+                if (wolfSSL_RSA_LoadDer_ex(pkey->rsa,
+                            (const unsigned char*)pkey->pkey.ptr,
+                            pkey->pkey_sz, WOLFSSL_RSA_LOAD_PRIVATE) != 1) {
+                    wolfSSL_EVP_PKEY_free(pkey);
+                    return NULL;
+                }
+
+                return pkey;
+            }
+        }
+        wc_FreeRsaKey(&rsa);
+    }
+    #endif /* NO_RSA */
+
+    #ifdef HAVE_ECC
+    {
+        word32  keyIdx = 0;
+        ecc_key ecc;
+
+        /* test if ecc key */
+        if (wc_ecc_init(&ecc) == 0 &&
+            wc_EccPrivateKeyDecode(mem, &keyIdx, &ecc, (word32)memSz) == 0) {
+            wc_ecc_free(&ecc);
+            pkey = wolfSSL_EVP_PKEY_new();
+            if (pkey != NULL) {
+                pkey->pkey_sz = keyIdx;
+                pkey->pkey.ptr = (char*)XMALLOC(keyIdx, NULL,
+                        DYNAMIC_TYPE_PRIVATE_KEY);
+                if (pkey->pkey.ptr == NULL) {
+                    wolfSSL_EVP_PKEY_free(pkey);
+                    return NULL;
+                }
+                XMEMCPY(pkey->pkey.ptr, mem, keyIdx);
+                pkey->type = EVP_PKEY_EC;
+                if (out != NULL) {
+                    *out = pkey;
+                }
+                return pkey;
+            }
+        }
+        wc_ecc_free(&ecc);
+    }
+    #endif /* HAVE_ECC */
+    return pkey;
+}
+#endif /* OPENSSL_ALL || WOLFSSL_ASIO || WOLFSSL_HAPROXY || WOLFSSL_QT */
+
+
+/* stunnel compatibility functions*/
+#if defined(OPENSSL_ALL) || (defined(OPENSSL_EXTRA) && (defined(HAVE_STUNNEL) || \
+                             defined(WOLFSSL_NGINX) || defined(HAVE_LIGHTY) || \
+                             defined(WOLFSSL_HAPROXY) || defined(WOLFSSL_OPENSSH)))
+void wolfSSL_ERR_remove_thread_state(void* pid)
+{
+    (void) pid;
+    return;
+}
+
+#ifndef NO_FILESYSTEM
+/***TBD ***/
+void wolfSSL_print_all_errors_fp(XFILE fp)
+{
+    (void)fp;
+}
+#endif
+
+int wolfSSL_SESSION_set_ex_data(WOLFSSL_SESSION* session, int idx, void* data)
+{
+    WOLFSSL_ENTER("wolfSSL_SESSION_set_ex_data");
+#ifdef HAVE_EX_DATA
+    if(session != NULL) {
+        return wolfSSL_CRYPTO_set_ex_data(&session->ex_data, idx, data);
+    }
+#else
+    (void)session;
+    (void)idx;
+    (void)data;
+#endif
+    return WOLFSSL_FAILURE;
+}
+
+
+int wolfSSL_SESSION_get_ex_new_index(long idx, void* data, void* cb1,
+       void* cb2, CRYPTO_free_func* cb3)
+{
+    WOLFSSL_ENTER("wolfSSL_SESSION_get_ex_new_index");
+    (void)idx;
+    (void)cb1;
+    (void)cb2;
+    (void)cb3;
+    if (XSTRNCMP((const char*)data, "redirect index", 14) == 0) {
+        return 0;
+    }
+    else if (XSTRNCMP((const char*)data, "addr index", 10) == 0) {
+        return 1;
+    }
+    return WOLFSSL_FAILURE;
+}
+
+
+void* wolfSSL_SESSION_get_ex_data(const WOLFSSL_SESSION* session, int idx)
+{
+    WOLFSSL_ENTER("wolfSSL_SESSION_get_ex_data");
+#ifdef HAVE_EX_DATA
+    if (session != NULL) {
+        return wolfSSL_CRYPTO_get_ex_data(&session->ex_data, idx);
+    }
+#else
+    (void)session;
+    (void)idx;
+#endif
+    return NULL;
+}
+
+#ifndef NO_WOLFSSL_STUB
+int wolfSSL_CRYPTO_set_mem_ex_functions(void *(*m) (size_t, const char *, int),
+                                void *(*r) (void *, size_t, const char *,
+                                            int), void (*f) (void *))
+{
+    (void) m;
+    (void) r;
+    (void) f;
+    WOLFSSL_ENTER("wolfSSL_CRYPTO_set_mem_ex_functions");
+    WOLFSSL_STUB("CRYPTO_set_mem_ex_functions");
+
+    return WOLFSSL_FAILURE;
+}
+#endif
+
+
+void wolfSSL_CRYPTO_cleanup_all_ex_data(void){
+    WOLFSSL_ENTER("CRYPTO_cleanup_all_ex_data");
+}
+
+
+#ifndef NO_WOLFSSL_STUB
+WOLFSSL_DH *wolfSSL_DH_generate_parameters(int prime_len, int generator,
+                           void (*callback) (int, int, void *), void *cb_arg)
+{
+    (void)prime_len;
+    (void)generator;
+    (void)callback;
+    (void)cb_arg;
+    WOLFSSL_ENTER("wolfSSL_DH_generate_parameters");
+    WOLFSSL_STUB("DH_generate_parameters");
+
+    return NULL;
+}
+#endif
+
+#ifndef NO_WOLFSSL_STUB
+int wolfSSL_DH_generate_parameters_ex(WOLFSSL_DH* dh, int prime_len, int generator,
+                           void (*callback) (int, int, void *))
+{
+    (void)prime_len;
+    (void)generator;
+    (void)callback;
+    (void)dh;
+    WOLFSSL_ENTER("wolfSSL_DH_generate_parameters_ex");
+    WOLFSSL_STUB("DH_generate_parameters_ex");
+
+    return -1;
+}
+#endif
+
+void wolfSSL_ERR_load_crypto_strings(void)
+{
+    WOLFSSL_ENTER("wolfSSL_ERR_load_crypto_strings");
+    /* Do nothing */
+    return;
+}
+
+#ifndef NO_WOLFSSL_STUB
+int wolfSSL_FIPS_mode(void)
+{
+    WOLFSSL_ENTER("wolfSSL_FIPS_mode");
+    WOLFSSL_STUB("FIPS_mode");
+
+    return WOLFSSL_FAILURE;
+}
+#endif
+
+#ifndef NO_WOLFSSL_STUB
+int wolfSSL_FIPS_mode_set(int r)
+{
+    (void)r;
+    WOLFSSL_ENTER("wolfSSL_FIPS_mode_set");
+    WOLFSSL_STUB("FIPS_mode_set");
+
+    return WOLFSSL_FAILURE;
+}
+#endif
+
+#ifndef NO_WOLFSSL_STUB
+int wolfSSL_RAND_set_rand_method(const void *meth)
+{
+    (void) meth;
+    WOLFSSL_ENTER("wolfSSL_RAND_set_rand_method");
+    WOLFSSL_STUB("RAND_set_rand_method");
+
+    /* if implemented RAND_bytes and RAND_pseudo_bytes need updated
+     * those two functions will call the respective functions from meth */
+    return SSL_FAILURE;
+}
+#endif
+
+int wolfSSL_CIPHER_get_bits(const WOLFSSL_CIPHER *c, int *alg_bits)
+{
+    int ret = WOLFSSL_FAILURE;
+    WOLFSSL_ENTER("wolfSSL_CIPHER_get_bits");
+
+    #if defined(WOLFSSL_QT) || defined(OPENSSL_ALL)
+    (void)alg_bits;
+    if (c!= NULL)
+        ret = c->bits;
+    #else
+    if (c != NULL && c->ssl != NULL) {
+        ret = 8 * c->ssl->specs.key_size;
+        if (alg_bits != NULL) {
+            *alg_bits = ret;
+        }
+    }
+    #endif
+    return ret;
+}
+
+#if defined(OPENSSL_ALL)
+WOLFSSL_X509_INFO* wolfSSL_X509_INFO_new(void)
+{
+    WOLFSSL_X509_INFO* info;
+    info = (WOLFSSL_X509_INFO*)XMALLOC(sizeof(WOLFSSL_X509_INFO), NULL,
+        DYNAMIC_TYPE_X509);
+    if (info) {
+        XMEMSET(info, 0, sizeof(*info));
+    }
+    return info;
+}
+
+void wolfSSL_X509_INFO_free(WOLFSSL_X509_INFO* info)
+{
+    if (info == NULL)
+        return;
+
+    if (info->x509) {
+        wolfSSL_X509_free(info->x509);
+        info->x509 = NULL;
+    }
+#ifdef HAVE_CRL
+    if (info->crl) {
+        wolfSSL_X509_CRL_free(info->crl);
+        info->crl = NULL;
+    }
+#endif
+    wolfSSL_X509_PKEY_free(info->x_pkey);
+    info->x_pkey = NULL;
+
+    XFREE(info, NULL, DYNAMIC_TYPE_X509);
+}
+#endif
+
+WOLFSSL_STACK* wolfSSL_sk_X509_INFO_new_null(void)
+{
+    WOLFSSL_STACK* sk = wolfSSL_sk_new_node(NULL);
+    if (sk) {
+        sk->type = STACK_TYPE_X509_INFO;
+    }
+    return sk;
+}
+
+
+/* returns value less than 0 on fail to match
+ * On a successful match the priority level found is returned
+ */
+int wolfSSL_sk_SSL_CIPHER_find(
+        WOLF_STACK_OF(WOLFSSL_CIPHER)* sk, const WOLFSSL_CIPHER* toFind)
+{
+    WOLFSSL_STACK* next;
+    int i, sz;
+
+    if (sk == NULL || toFind == NULL) {
+        return WOLFSSL_FATAL_ERROR;
+    }
+
+    sz   = wolfSSL_sk_SSL_CIPHER_num(sk);
+    next = sk;
+    for (i = 0; i < sz && next != NULL; i++) {
+        if (next->data.cipher.cipherSuite0 == toFind->cipherSuite0 &&
+                next->data.cipher.cipherSuite == toFind->cipherSuite) {
+            return sz - i; /* reverse because stack pushed highest on first */
+        }
+        next = next->next;
+    }
+    return WOLFSSL_FATAL_ERROR;
+}
+
+
+/* copies over data of "in" to "out" */
+static void wolfSSL_CIPHER_copy(WOLFSSL_CIPHER* in, WOLFSSL_CIPHER* out)
+{
+    if (in == NULL || out == NULL)
+        return;
+
+    out->cipherSuite  = in->cipherSuite;
+    out->cipherSuite0 = in->cipherSuite0;
+}
+
+
+/* create duplicate of stack and return the new stack
+ * returns null on failure */
+WOLF_STACK_OF(WOLFSSL_CIPHER)* wolfSSL_sk_SSL_CIPHER_dup(
+        WOLF_STACK_OF(WOLFSSL_CIPHER)* in)
+{
+    WOLFSSL_STACK* current;
+    WOLF_STACK_OF(WOLFSSL_CIPHER)* ret = NULL;
+    int i, sz;
+
+    sz = wolfSSL_sk_SSL_CIPHER_num(in);
+    current = in;
+    for (i = 0; i < sz && current != NULL; i++) {
+        WOLFSSL_STACK* add = wolfSSL_sk_new_node(in->heap);
+        if (add != NULL) {
+            add->type = STACK_TYPE_CIPHER;
+            wolfSSL_CIPHER_copy(&(current->data.cipher), &(add->data.cipher));
+            add->num = i+1;
+            add->next = ret;
+            ret = add;
+            current = current->next;
+        }
+    }
+    return ret;
+}
+
+/* nothing to do yet */
+static void wolfSSL_CIPHER_free(WOLFSSL_CIPHER* in)
+{
+    (void)in;
+}
+
+
+/* free's all nodes in the stack and there data */
+void wolfSSL_sk_SSL_CIPHER_free(WOLF_STACK_OF(WOLFSSL_CIPHER)* sk)
+{
+    WOLFSSL_STACK* current = sk;
+
+    while (current != NULL) {
+        WOLFSSL_STACK* toFree = current;
+        current = current->next;
+
+        wolfSSL_CIPHER_free(&(toFree->data.cipher));
+        wolfSSL_sk_free_node(toFree);
+    }
+}
+
+
+int wolfSSL_sk_X509_INFO_num(const WOLF_STACK_OF(WOLFSSL_X509_INFO) *sk)
+{
+    WOLFSSL_ENTER("wolfSSL_sk_X509_INFO_num");
+
+    if (sk == NULL)
+        return -1;
+    return (int)sk->num;
+}
+
+WOLFSSL_X509_INFO* wolfSSL_sk_X509_INFO_value(const WOLF_STACK_OF(WOLFSSL_X509_INFO) *sk, int i)
+{
+    WOLFSSL_ENTER("wolfSSL_sk_X509_INFO_value");
+
+    for (; sk != NULL && i > 0; i--)
+        sk = sk->next;
+
+    if (i != 0 || sk == NULL)
+        return NULL;
+    return sk->data.info;
+}
+
+WOLFSSL_X509_INFO* wolfSSL_sk_X509_INFO_pop(WOLF_STACK_OF(WOLFSSL_X509_INFO)* sk)
+{
+    WOLFSSL_STACK* node;
+    WOLFSSL_X509_INFO* info;
+
+    if (sk == NULL) {
+        return NULL;
+    }
+
+    node = sk->next;
+    info = sk->data.info;
+
+    if (node != NULL) { /* update sk and remove node from stack */
+        sk->data.info = node->data.info;
+        sk->next = node->next;
+        XFREE(node, NULL, DYNAMIC_TYPE_OPENSSL);
+    }
+    else { /* last x509 in stack */
+        sk->data.info = NULL;
+    }
+
+    if (sk->num > 0) {
+        sk->num -= 1;
+    }
+
+    return info;
+}
+
+#if defined(OPENSSL_ALL)
+void wolfSSL_sk_X509_INFO_pop_free(WOLF_STACK_OF(WOLFSSL_X509_INFO)* sk,
+    void (*f) (WOLFSSL_X509_INFO*))
+{
+    WOLFSSL_STACK* node;
+
+    WOLFSSL_ENTER("wolfSSL_sk_X509_INFO_pop_free");
+
+    if (sk == NULL) {
+        return;
+    }
+
+    /* parse through stack freeing each node */
+    node = sk->next;
+    while (node && sk->num > 1) {
+        WOLFSSL_STACK* tmp = node;
+        node = node->next;
+
+        if (f)
+            f(tmp->data.info);
+        else
+            wolfSSL_X509_INFO_free(tmp->data.info);
+        tmp->data.info = NULL;
+        XFREE(tmp, NULL, DYNAMIC_TYPE_OPENSSL);
+        sk->num -= 1;
+    }
+
+    /* free head of stack */
+    if (sk->num == 1) {
+        if (f)
+            f(sk->data.info);
+        else
+            wolfSSL_X509_INFO_free(sk->data.info);
+        sk->data.info = NULL;
+    }
+    XFREE(sk, NULL, DYNAMIC_TYPE_OPENSSL);
+}
+
+void wolfSSL_sk_X509_INFO_free(WOLF_STACK_OF(WOLFSSL_X509_INFO) *sk)
+{
+    wolfSSL_sk_X509_INFO_pop_free(sk, NULL);
+}
+
+
+/* Adds the WOLFSSL_X509_INFO to the stack "sk". "sk" takes control of "in" and
+ * tries to free it when the stack is free'd.
+ *
+ * return 1 on success 0 on fail
+ */
+int wolfSSL_sk_X509_INFO_push(WOLF_STACK_OF(WOLFSSL_X509_INFO)* sk,
+                                                      WOLFSSL_X509_INFO* in)
+{
+    WOLFSSL_STACK* node;
+
+    if (sk == NULL || in == NULL) {
+        return WOLFSSL_FAILURE;
+    }
+
+    /* no previous values in stack */
+    if (sk->data.info == NULL) {
+        sk->data.info = in;
+        sk->num += 1;
+        return WOLFSSL_SUCCESS;
+    }
+
+    /* stack already has value(s) create a new node and add more */
+    node = (WOLFSSL_STACK*)XMALLOC(sizeof(WOLFSSL_STACK), NULL,
+            DYNAMIC_TYPE_X509);
+    if (node == NULL) {
+        WOLFSSL_MSG("Memory error");
+        return WOLFSSL_FAILURE;
+    }
+    XMEMSET(node, 0, sizeof(WOLFSSL_STACK));
+
+    /* push new obj onto head of stack */
+    node->data.info = sk->data.info;
+    node->next      = sk->next;
+    node->type      = sk->type;
+    sk->next        = node;
+    sk->data.info   = in;
+    sk->num        += 1;
+
+    return WOLFSSL_SUCCESS;
+}
+
+
+WOLF_STACK_OF(WOLFSSL_X509_NAME)* wolfSSL_sk_X509_NAME_new(wolf_sk_compare_cb cb)
+{
+    WOLFSSL_STACK* sk;
+
+    WOLFSSL_ENTER("wolfSSL_sk_X509_NAME_new");
+
+    sk = wolfSSL_sk_new_node(NULL);
+    if (sk != NULL) {
+        sk->type = STACK_TYPE_X509_NAME;
+        sk->comp = cb;
+    }
+
+    return sk;
+}
+
+int wolfSSL_sk_X509_NAME_push(WOLF_STACK_OF(WOLFSSL_X509_NAME)* sk,
+    WOLFSSL_X509_NAME* name)
+{
+    WOLFSSL_STACK* node;
+
+    WOLFSSL_ENTER("wolfSSL_sk_X509_NAME_push");
+
+    if (sk == NULL || name == NULL) {
+        return BAD_FUNC_ARG;
+    }
+
+    /* no previous values in stack */
+    if (sk->data.name == NULL) {
+        sk->data.name = name;
+        sk->num += 1;
+        return 0;
+    }
+
+    /* stack already has value(s) create a new node and add more */
+    node = (WOLFSSL_STACK*)XMALLOC(sizeof(WOLFSSL_STACK), NULL,
+        DYNAMIC_TYPE_OPENSSL);
+    if (node == NULL) {
+        WOLFSSL_MSG("Memory error");
+        return MEMORY_E;
+    }
+    XMEMSET(node, 0, sizeof(WOLFSSL_STACK));
+
+    /* push new obj onto head of stack */
+    node->data.name = sk->data.name;
+    node->next      = sk->next;
+    sk->type        = STACK_TYPE_X509_NAME;
+    sk->next        = node;
+    sk->data.name   = name;
+    sk->num        += 1;
+
+    return 0;
+}
+
+/* return index of found, or negative to indicate not found */
+int wolfSSL_sk_X509_NAME_find(const WOLF_STACK_OF(WOLFSSL_X509_NAME) *sk,
+    WOLFSSL_X509_NAME *name)
+{
+    int i;
+
+    WOLFSSL_ENTER("wolfSSL_sk_X509_NAME_find");
+
+    if (sk == NULL)
+        return BAD_FUNC_ARG;
+
+    for (i = 0; sk; i++, sk = sk->next) {
+        if (wolfSSL_X509_NAME_cmp(sk->data.name, name) == 0) {
+            return i;
+        }
+    }
+    return -1;
+}
+
+int wolfSSL_sk_X509_OBJECT_num(const WOLF_STACK_OF(WOLFSSL_X509_OBJECT) *s)
+{
+    WOLFSSL_ENTER("wolfSSL_sk_X509_OBJECT_num");
+    if (s) {
+        return (int)s->num;
+    } else {
+        return 0;
+    }
+}
+
+
+int wolfSSL_sk_X509_NAME_set_cmp_func(WOLF_STACK_OF(WOLFSSL_X509_NAME)* sk,
+    wolf_sk_compare_cb cb)
+{
+    WOLFSSL_ENTER("wolfSSL_sk_X509_NAME_set_cmp_func");
+
+    if (sk == NULL)
+        return BAD_FUNC_ARG;
+
+    sk->comp = cb;
+    return 0;
+}
+#endif /* OPENSSL_ALL */
+
+int wolfSSL_sk_X509_NAME_num(const WOLF_STACK_OF(WOLFSSL_X509_NAME) *sk)
+{
+    WOLFSSL_ENTER("wolfSSL_sk_X509_NAME_num");
+
+    if (sk == NULL)
+        return BAD_FUNC_ARG;
+
+    return (int)sk->num;
+}
+
+/* Getter function for WOLFSSL_X509_NAME pointer
+ *
+ * sk is the stack to retrieve pointer from
+ * i  is the index value in stack
+ *
+ * returns a pointer to a WOLFSSL_X509_NAME structure on success and NULL on
+ *         fail
+ */
+WOLFSSL_X509_NAME* wolfSSL_sk_X509_NAME_value(const STACK_OF(WOLFSSL_X509_NAME)* sk,
+    int i)
+{
+    WOLFSSL_ENTER("wolfSSL_sk_X509_NAME_value");
+
+    for (; sk != NULL && i > 0; i--) {
+        sk = sk->next;
+    }
+
+    if (i != 0 || sk == NULL)
+        return NULL;
+
+    return sk->data.name;
+}
+
+WOLFSSL_X509_NAME* wolfSSL_sk_X509_NAME_pop(WOLF_STACK_OF(WOLFSSL_X509_NAME)* sk)
+{
+    WOLFSSL_STACK* node;
+    WOLFSSL_X509_NAME* name;
+
+    if (sk == NULL) {
+        return NULL;
+    }
+
+    node = sk->next;
+    name = sk->data.name;
+
+    if (node != NULL) { /* update sk and remove node from stack */
+        sk->data.name = node->data.name;
+        sk->next = node->next;
+        XFREE(node, NULL, DYNAMIC_TYPE_OPENSSL);
+    }
+    else { /* last x509 in stack */
+        sk->data.name = NULL;
+    }
+
+    if (sk->num > 0) {
+        sk->num -= 1;
+    }
+
+    return name;
+}
+
+void wolfSSL_sk_X509_NAME_pop_free(WOLF_STACK_OF(WOLFSSL_X509_NAME)* sk,
+    void (*f) (WOLFSSL_X509_NAME*))
+{
+    WOLFSSL_STACK* node;
+    WOLFSSL_ENTER("wolfSSL_sk_X509_NAME_pop_free");
+
+    if (sk == NULL)
+        return;
+
+    node = sk->next;
+    while (node && sk->num > 1) {
+        WOLFSSL_STACK* tmp = node;
+        node = node->next;
+        if (f)
+            f(tmp->data.name);
+        else
+            wolfSSL_X509_NAME_free(tmp->data.name);
+        tmp->data.name = NULL;
+        XFREE(tmp, NULL, DYNAMIC_TYPE_OPENSSL);
+        sk->num -= 1;
+    }
+
+    /* free head of stack */
+    if (sk->num == 1) {
+        if (f)
+            f(sk->data.name);
+        else
+            wolfSSL_X509_NAME_free(sk->data.name);
+        sk->data.name = NULL;
+    }
+
+    XFREE(sk, sk->heap, DYNAMIC_TYPE_OPENSSL);
+}
+
+/* Free only the sk structure, NOT X509_NAME members */
+void wolfSSL_sk_X509_NAME_free(WOLF_STACK_OF(WOLFSSL_X509_NAME)* sk)
+{
+    WOLFSSL_STACK* node;
+    WOLFSSL_ENTER("wolfSSL_sk_X509_NAME_free");
+
+    if (sk == NULL)
+        return;
+
+    node = sk->next;
+    while (sk->num > 1) {
+        WOLFSSL_STACK* tmp = node;
+        node = node->next;
+        XFREE(tmp, NULL, DYNAMIC_TYPE_OPENSSL);
+        sk->num -= 1;
+    }
+
+    XFREE(sk, sk->heap, DYNAMIC_TYPE_OPENSSL);
+}
+
+#if defined(WOLFSSL_APACHE_HTTPD) || defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX)
+/* Helper function for X509_NAME_print_ex. Sets *buf to string for domain
+   name attribute based on NID. Returns size of buf */
+static int get_dn_attr_by_nid(int n, const char** buf)
+{
+    int len = 0;
+    const char *str;
+
+    switch(n)
+    {
+        case NID_commonName :
+            str = "CN";
+            len = 2;
+            break;
+        case NID_countryName:
+            str = "C";
+            len = 1;
+            break;
+        case NID_localityName:
+            str = "L";
+            len = 1;
+            break;
+        case NID_stateOrProvinceName:
+            str = "ST";
+            len = 2;
+            break;
+        case NID_organizationName:
+            str = "O";
+            len = 1;
+            break;
+        case NID_organizationalUnitName:
+            str = "OU";
+            len = 2;
+            break;
+        case NID_emailAddress:
+            str = "emailAddress";
+            len = 12;
+            break;
+        default:
+            WOLFSSL_MSG("Attribute type not found");
+            str = NULL;
+
+    }
+    if (buf != NULL)
+        *buf = str;
+    return len;
+}
+#endif
+
+/*
+ * The BIO output of  wolfSSL_X509_NAME_print_ex does NOT include the null terminator
+ */
+int wolfSSL_X509_NAME_print_ex(WOLFSSL_BIO* bio, WOLFSSL_X509_NAME* name,
+                int indent, unsigned long flags)
+{
+#if defined(WOLFSSL_APACHE_HTTPD) || defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX)
+    int count = 0, len = 0, totalSz = 0, tmpSz = 0;
+    char tmp[ASN_NAME_MAX];
+    char fullName[ASN_NAME_MAX];
+    const char *buf = NULL;
+    WOLFSSL_X509_NAME_ENTRY* ne;
+    WOLFSSL_ASN1_STRING* str;
+#endif
+    int i;
+    (void)flags;
+    WOLFSSL_ENTER("wolfSSL_X509_NAME_print_ex");
+
+    for (i = 0; i < indent; i++) {
+        if (wolfSSL_BIO_write(bio, " ", 1) != 1)
+            return WOLFSSL_FAILURE;
+    }
+
+#if defined(WOLFSSL_APACHE_HTTPD) || defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX)
+    /* If XN_FLAG_DN_REV is present, print X509_NAME in reverse order */
+    if (flags == (XN_FLAG_RFC2253 & ~XN_FLAG_DN_REV)) {
+        fullName[0] = '\0';
+        count = wolfSSL_X509_NAME_entry_count(name);
+        for (i = 0; i < count; i++) {
+            ne = wolfSSL_X509_NAME_get_entry(name, count - i - 1);
+            if (ne == NULL)
+                return WOLFSSL_FAILURE;
+
+            str = wolfSSL_X509_NAME_ENTRY_get_data(ne);
+            if (str == NULL)
+                return WOLFSSL_FAILURE;
+
+            len = get_dn_attr_by_nid(ne->nid, &buf);
+            if (len == 0 || buf == NULL)
+                return WOLFSSL_FAILURE;
+
+            tmpSz = str->length + len + 2; /* + 2 for '=' and comma */
+            if (tmpSz > ASN_NAME_MAX) {
+                WOLFSSL_MSG("Size greater than ASN_NAME_MAX");
+                return WOLFSSL_FAILURE;
+            }
+
+            if (i < count - 1) {
+                /* tmpSz+1 for last null char */
+                XSNPRINTF(tmp, tmpSz+1, "%s=%s,", buf, str->data);
+                XSTRNCAT(fullName, tmp, tmpSz);
+            }
+            else {
+                XSNPRINTF(tmp, tmpSz, "%s=%s", buf, str->data);
+                XSTRNCAT(fullName, tmp, tmpSz-1);
+                tmpSz--; /* Don't include null char in tmpSz */
+            }
+            totalSz += tmpSz;
+        }
+        if (wolfSSL_BIO_write(bio, fullName, totalSz) != totalSz)
+            return WOLFSSL_FAILURE;
+        return WOLFSSL_SUCCESS;
+    }
+#else
+    if (flags == XN_FLAG_RFC2253) {
+        if (wolfSSL_BIO_write(bio, name->name + 1, name->sz - 2)
+                                                                != name->sz - 2)
+            return WOLFSSL_FAILURE;
+    }
+#endif /* WOLFSSL_APACHE_HTTPD || OPENSSL_ALL || WOLFSSL_NGINX */
+    else if (wolfSSL_BIO_write(bio, name->name, name->sz - 1) != name->sz - 1)
+        return WOLFSSL_FAILURE;
+
+    return WOLFSSL_SUCCESS;
+}
+
+#ifndef NO_WOLFSSL_STUB
+WOLFSSL_ASN1_BIT_STRING* wolfSSL_X509_get0_pubkey_bitstr(const WOLFSSL_X509* x)
+{
+    (void)x;
+    WOLFSSL_ENTER("wolfSSL_X509_get0_pubkey_bitstr");
+    WOLFSSL_STUB("X509_get0_pubkey_bitstr");
+
+    return NULL;
+}
+#endif
+
+#ifndef NO_WOLFSSL_STUB
+int wolfSSL_CTX_add_session(WOLFSSL_CTX* ctx, WOLFSSL_SESSION* session)
+{
+    (void)ctx;
+    (void)session;
+    WOLFSSL_ENTER("wolfSSL_CTX_add_session");
+    WOLFSSL_STUB("SSL_CTX_add_session");
+
+    return WOLFSSL_SUCCESS;
+}
+#endif
+
+
+int wolfSSL_version(WOLFSSL* ssl)
+{
+    WOLFSSL_ENTER("wolfSSL_version");
+    if (ssl->version.major == SSLv3_MAJOR) {
+        switch (ssl->version.minor) {
+            case SSLv3_MINOR :
+                return SSL3_VERSION;
+            case TLSv1_MINOR :
+                return TLS1_VERSION;
+            case TLSv1_1_MINOR :
+                return TLS1_1_VERSION;
+            case TLSv1_2_MINOR :
+                return TLS1_2_VERSION;
+            case TLSv1_3_MINOR :
+                return TLS1_3_VERSION;
+            default:
+                return WOLFSSL_FAILURE;
+        }
+    }
+    else if (ssl->version.major == DTLS_MAJOR) {
+        switch (ssl->version.minor) {
+            case DTLS_MINOR :
+                return DTLS1_VERSION;
+            case DTLSv1_2_MINOR :
+                return DTLS1_2_VERSION;
+            default:
+                return WOLFSSL_FAILURE;
+        }
+    }
+    return WOLFSSL_FAILURE;
+}
+
+
+int wolfSSL_X509_NAME_get_sz(WOLFSSL_X509_NAME* name)
+{
+    WOLFSSL_ENTER("wolfSSL_X509_NAME_get_sz");
+    if(!name)
+        return -1;
+    return name->sz;
+}
+
+#ifdef HAVE_SNI
+int wolfSSL_set_tlsext_host_name(WOLFSSL* ssl, const char* host_name)
+{
+    int ret;
+    WOLFSSL_ENTER("wolfSSL_set_tlsext_host_name");
+    ret = wolfSSL_UseSNI(ssl, WOLFSSL_SNI_HOST_NAME,
+            host_name, (word16)XSTRLEN(host_name));
+    WOLFSSL_LEAVE("wolfSSL_set_tlsext_host_name", ret);
+    return ret;
+}
+
+
+#ifndef NO_WOLFSSL_SERVER
+const char * wolfSSL_get_servername(WOLFSSL* ssl, byte type)
+{
+    void * serverName = NULL;
+    if (ssl == NULL)
+        return NULL;
+    TLSX_SNI_GetRequest(ssl->extensions, type, &serverName);
+    return (const char *)serverName;
+}
+#endif /* NO_WOLFSSL_SERVER */
+#endif /* HAVE_SNI */
+
+WOLFSSL_CTX* wolfSSL_set_SSL_CTX(WOLFSSL* ssl, WOLFSSL_CTX* ctx)
+{
+    if (ssl && ctx && SetSSL_CTX(ssl, ctx, 0) == WOLFSSL_SUCCESS)
+        return ssl->ctx;
+    return NULL;
+}
+
+
+VerifyCallback wolfSSL_CTX_get_verify_callback(WOLFSSL_CTX* ctx)
+{
+    WOLFSSL_ENTER("wolfSSL_CTX_get_verify_callback");
+    if(ctx)
+        return ctx->verifyCallback;
+    return NULL;
+}
+
+
+void wolfSSL_CTX_set_servername_callback(WOLFSSL_CTX* ctx, CallbackSniRecv cb)
+{
+    WOLFSSL_ENTER("wolfSSL_CTX_set_servername_callback");
+    if (ctx)
+        ctx->sniRecvCb = cb;
+}
+
+int wolfSSL_CTX_set_tlsext_servername_callback(WOLFSSL_CTX* ctx,
+                                               CallbackSniRecv cb)
+{
+    WOLFSSL_ENTER("wolfSSL_CTX_set_tlsext_servername_callback");
+    if (ctx) {
+        ctx->sniRecvCb = cb;
+        return WOLFSSL_SUCCESS;
+    }
+    return WOLFSSL_FAILURE;
+}
+
+int wolfSSL_CTX_set_servername_arg(WOLFSSL_CTX* ctx, void* arg)
+{
+    WOLFSSL_ENTER("wolfSSL_CTX_set_servername_arg");
+    if (ctx) {
+        ctx->sniRecvCbArg = arg;
+        return WOLFSSL_SUCCESS;
+    }
+    return WOLFSSL_FAILURE;
+}
+
+void wolfSSL_ERR_load_BIO_strings(void) {
+    WOLFSSL_ENTER("ERR_load_BIO_strings");
+    /* do nothing */
+}
+
+#ifndef NO_WOLFSSL_STUB
+void wolfSSL_THREADID_set_callback(void(*threadid_func)(void*))
+{
+    WOLFSSL_ENTER("wolfSSL_THREADID_set_callback");
+    WOLFSSL_STUB("CRYPTO_THREADID_set_callback");
+    (void)threadid_func;
+    return;
+}
+#endif
+
+#ifndef NO_WOLFSSL_STUB
+void wolfSSL_THREADID_set_numeric(void* id, unsigned long val)
+{
+    WOLFSSL_ENTER("wolfSSL_THREADID_set_numeric");
+    WOLFSSL_STUB("CRYPTO_THREADID_set_numeric");
+    (void)id;
+    (void)val;
+    return;
+}
+#endif
+
+
+#ifndef NO_WOLFSSL_STUB
+WOLF_STACK_OF(WOLFSSL_X509)* wolfSSL_X509_STORE_get1_certs(
+    WOLFSSL_X509_STORE_CTX* ctx, WOLFSSL_X509_NAME* name)
+{
+    WOLFSSL_ENTER("wolfSSL_X509_STORE_get1_certs");
+    WOLFSSL_STUB("X509_STORE_get1_certs");
+    (void)ctx;
+    (void)name;
+    return NULL;
+}
+
+WOLF_STACK_OF(WOLFSSL_X509_OBJECT)* wolfSSL_X509_STORE_get0_objects(
+    WOLFSSL_X509_STORE* store)
+{
+    WOLFSSL_ENTER("wolfSSL_X509_STORE_get0_objects");
+    WOLFSSL_STUB("wolfSSL_X509_STORE_get0_objects");
+    (void)store;
+    return NULL;
+}
+
+WOLFSSL_X509_OBJECT* wolfSSL_sk_X509_OBJECT_delete(
+    WOLF_STACK_OF(WOLFSSL_X509_OBJECT)* sk, int i)
+{
+    WOLFSSL_ENTER("wolfSSL_sk_X509_OBJECT_delete");
+    WOLFSSL_STUB("wolfSSL_sk_X509_OBJECT_delete");
+    (void)sk;
+    (void)i;
+    return NULL;
+}
+
+void wolfSSL_X509_OBJECT_free(WOLFSSL_X509_OBJECT *a)
+{
+    WOLFSSL_ENTER("wolfSSL_X509_OBJECT_free");
+    WOLFSSL_STUB("wolfSSL_X509_OBJECT_free");
+    (void)a;
+}
+
+#endif
+
+
+#endif /* OPENSSL_ALL || (OPENSSL_EXTRA && (HAVE_STUNNEL || WOLFSSL_NGINX || HAVE_LIGHTY)) */
+
+
+#if defined(OPENSSL_EXTRA)
+
+int wolfSSL_sk_X509_num(const WOLF_STACK_OF(WOLFSSL_X509) *s)
+{
+    WOLFSSL_ENTER("wolfSSL_sk_X509_num");
+
+    if (s == NULL)
+        return -1;
+    return (int)s->num;
+}
+
+unsigned long wolfSSL_ERR_peek_last_error(void)
+{
+    WOLFSSL_ENTER("wolfSSL_ERR_peek_last_error");
+
+#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_NGINX)
+    {
+        int ret;
+
+        if ((ret = wc_PeekErrorNode(-1, NULL, NULL, NULL)) < 0) {
+            WOLFSSL_MSG("Issue peeking at error node in queue");
+            return 0;
+        }
+        if (ret == -ASN_NO_PEM_HEADER)
+            return (ERR_LIB_PEM << 24) | PEM_R_NO_START_LINE;
+        return (unsigned long)ret;
+    }
+#else
+    return (unsigned long)(0 - NOT_COMPILED_IN);
+#endif
+}
+
+#endif /* OPENSSL_EXTRA */
+
+WOLFSSL_CTX* wolfSSL_get_SSL_CTX(WOLFSSL* ssl)
+{
+    WOLFSSL_ENTER("wolfSSL_get_SSL_CTX");
+    return ssl->ctx;
+}
+
+#if defined(OPENSSL_ALL) || \
+    defined(OPENSSL_EXTRA) || defined(HAVE_STUNNEL) || \
+    defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY)
+
+const byte* wolfSSL_SESSION_get_id(WOLFSSL_SESSION* sess, unsigned int* idLen)
+{
+    WOLFSSL_ENTER("wolfSSL_SESSION_get_id");
+    if(!sess || !idLen) {
+        WOLFSSL_MSG("Bad func args. Please provide idLen");
+        return NULL;
+    }
+    *idLen = sess->sessionIDSz;
+    return sess->sessionID;
+}
+
+#if (defined(HAVE_SESSION_TICKET) || defined(SESSION_CERTS)) && \
+    !defined(NO_FILESYSTEM)
+
+#if defined(SESSION_CERTS) || \
+   (defined(WOLFSSL_TLS13) && defined(HAVE_SESSION_TICKET))
+/* returns a pointer to the protocol used by the session */
+static const char* wolfSSL_SESSION_get_protocol(const WOLFSSL_SESSION* in)
+{
+    return wolfSSL_internal_get_version((ProtocolVersion*)&in->version);
+}
+#endif
+
+/* returns true (non 0) if the session has EMS (extended master secret) */
+static int wolfSSL_SESSION_haveEMS(const WOLFSSL_SESSION* in)
+{
+    if (in == NULL)
+        return 0;
+    return in->haveEMS;
+}
+
+#if defined(HAVE_SESSION_TICKET)
+/* prints out the ticket to bio passed in
+ * return WOLFSSL_SUCCESS on success
+ */
+static int wolfSSL_SESSION_print_ticket(WOLFSSL_BIO* bio,
+        const WOLFSSL_SESSION* in, const char* tab)
+{
+    unsigned short i, j, z, sz;
+    short tag = 0;
+    byte* pt;
+
+
+    if (in == NULL || bio == NULL) {
+        return BAD_FUNC_ARG;
+    }
+
+    sz = in->ticketLen;
+    pt = in->ticket;
+
+    if (wolfSSL_BIO_printf(bio, "%s\n", (sz == 0)? " NONE": "") <= 0)
+        return WOLFSSL_FAILURE;
+
+    for (i = 0; i < sz;) {
+        char asc[16];
+
+        if (sz - i < 16) {
+            if (wolfSSL_BIO_printf(bio, "%s%04X -", tab, tag + (sz - i)) <= 0)
+                return WOLFSSL_FAILURE;
+        }
+        else {
+            if (wolfSSL_BIO_printf(bio, "%s%04X -", tab, tag) <= 0)
+                return WOLFSSL_FAILURE;
+        }
+        for (j = 0; i < sz && j < 8; j++,i++) {
+            asc[j] =  ((pt[i])&0x6f)>='A'?((pt[i])&0x6f):'.';
+            if (wolfSSL_BIO_printf(bio, " %02X", pt[i]) <= 0)
+                return WOLFSSL_FAILURE;
+        }
+
+        if (i < sz) {
+            asc[j] =  ((pt[i])&0x6f)>='A'?((pt[i])&0x6f):'.';
+            if (wolfSSL_BIO_printf(bio, "-%02X", pt[i]) <= 0)
+                return WOLFSSL_FAILURE;
+            j++;
+            i++;
+        }
+
+        for (; i < sz && j < 16; j++,i++) {
+            asc[j] =  ((pt[i])&0x6f)>='A'?((pt[i])&0x6f):'.';
+            if (wolfSSL_BIO_printf(bio, " %02X", pt[i]) <= 0)
+                return WOLFSSL_FAILURE;
+        }
+
+        /* pad out spacing */
+        for (z = j; z < 17; z++) {
+            if (wolfSSL_BIO_printf(bio, "   ") <= 0)
+                return WOLFSSL_FAILURE;
+        }
+
+        for (z = 0; z < j; z++) {
+            if (wolfSSL_BIO_printf(bio, "%c", asc[z]) <= 0)
+                return WOLFSSL_FAILURE;
+        }
+        if (wolfSSL_BIO_printf(bio, "\n") <= 0)
+            return WOLFSSL_FAILURE;
+
+        tag += 16;
+    }
+    return WOLFSSL_SUCCESS;
+}
+#endif /* HAVE_SESSION_TICKET */
+
+
+/* prints out the session information in human readable form
+ * return WOLFSSL_SUCCESS on success
+ */
+int wolfSSL_SESSION_print(WOLFSSL_BIO *bp, const WOLFSSL_SESSION *x)
+{
+    const unsigned char* pt;
+    unsigned char buf[SECRET_LEN];
+    unsigned int sz = 0, i;
+    int ret;
+    WOLFSSL_SESSION* session = (WOLFSSL_SESSION*)x;
+
+    if (session == NULL) {
+        WOLFSSL_MSG("Bad NULL argument");
+        return WOLFSSL_FAILURE;
+    }
+
+    if (wolfSSL_BIO_printf(bp, "%s\n", "SSL-Session:") <= 0)
+        return WOLFSSL_FAILURE;
+
+#if defined(SESSION_CERTS) || (defined(WOLFSSL_TLS13) && \
+                               defined(HAVE_SESSION_TICKET))
+    if (wolfSSL_BIO_printf(bp, "    Protocol  : %s\n",
+            wolfSSL_SESSION_get_protocol(session)) <= 0)
+        return WOLFSSL_FAILURE;
+#endif
+
+    if (wolfSSL_BIO_printf(bp, "    Cipher    : %s\n",
+            wolfSSL_SESSION_CIPHER_get_name(session)) <= 0)
+        return WOLFSSL_FAILURE;
+
+    pt = wolfSSL_SESSION_get_id(session, &sz);
+    if (wolfSSL_BIO_printf(bp, "    Session-ID: ") <= 0)
+        return WOLFSSL_FAILURE;
+
+    for (i = 0; i < sz; i++) {
+        if (wolfSSL_BIO_printf(bp, "%02X", pt[i]) <= 0)
+            return WOLFSSL_FAILURE;
+    }
+    if (wolfSSL_BIO_printf(bp, "\n") <= 0)
+        return WOLFSSL_FAILURE;
+
+    if (wolfSSL_BIO_printf(bp, "    Session-ID-ctx: \n") <= 0)
+        return WOLFSSL_FAILURE;
+
+    ret = wolfSSL_SESSION_get_master_key(x, buf, sizeof(buf));
+    if (wolfSSL_BIO_printf(bp, "    Master-Key: ") <= 0)
+        return WOLFSSL_FAILURE;
+
+    if (ret > 0) {
+        sz = (unsigned int)ret;
+        for (i = 0; i < sz; i++) {
+            if (wolfSSL_BIO_printf(bp, "%02X", buf[i]) <= 0)
+                return WOLFSSL_FAILURE;
+        }
+    }
+    if (wolfSSL_BIO_printf(bp, "\n") <= 0)
+        return WOLFSSL_FAILURE;
+
+    /* @TODO PSK identity hint and SRP */
+
+    if (wolfSSL_BIO_printf(bp, "    TLS session ticket:") <= 0)
+        return WOLFSSL_FAILURE;
+
+#ifdef HAVE_SESSION_TICKET
+    if (wolfSSL_SESSION_print_ticket(bp, x, "    ") != WOLFSSL_SUCCESS)
+        return WOLFSSL_FAILURE;
+#endif
+
+    if (wolfSSL_BIO_printf(bp, "    Start Time: %ld\n",
+                wolfSSL_SESSION_get_time(x)) <= 0)
+        return WOLFSSL_FAILURE;
+
+    if (wolfSSL_BIO_printf(bp, "    Timeout   : %ld (sec)\n",
+            wolfSSL_SESSION_get_timeout(x)) <= 0)
+        return WOLFSSL_FAILURE;
+
+    /* @TODO verify return code print */
+
+    if (wolfSSL_BIO_printf(bp, "    Extended master secret: %s\n",
+            (wolfSSL_SESSION_haveEMS(session) == 0)? "no" : "yes") <= 0)
+        return WOLFSSL_FAILURE;
+
+    return WOLFSSL_SUCCESS;
+}
+#endif /* (HAVE_SESSION_TICKET || SESSION_CERTS) && !NO_FILESYSTEM */
+
+#endif /* OPENSSL_ALL || OPENSSL_EXTRA || HAVE_STUNNEL || WOLFSSL_NGINX || WOLFSSL_HAPROXY */
+
+#if defined(OPENSSL_ALL) || (defined(OPENSSL_EXTRA) && defined(HAVE_STUNNEL)) \
+    || defined(WOLFSSL_MYSQL_COMPATIBLE) || defined(WOLFSSL_NGINX)
+
+int wolfSSL_CTX_get_verify_mode(WOLFSSL_CTX* ctx)
+{
+    int mode = 0;
+    WOLFSSL_ENTER("wolfSSL_CTX_get_verify_mode");
+
+    if(!ctx)
+        return WOLFSSL_FATAL_ERROR;
+
+    if (ctx->verifyPeer)
+        mode |= WOLFSSL_VERIFY_PEER;
+    else if (ctx->verifyNone)
+        mode |= WOLFSSL_VERIFY_NONE;
+
+    if (ctx->failNoCert)
+        mode |= WOLFSSL_VERIFY_FAIL_IF_NO_PEER_CERT;
+
+    if (ctx->failNoCertxPSK)
+        mode |= WOLFSSL_VERIFY_FAIL_EXCEPT_PSK;
+
+    WOLFSSL_LEAVE("wolfSSL_CTX_get_verify_mode", mode);
+    return mode;
+}
+
+#endif
+#if defined(OPENSSL_EXTRA) && defined(HAVE_CURVE25519)
+/* return 1 if success, 0 if error
+ * output keys are little endian format
+ */
+int wolfSSL_EC25519_generate_key(unsigned char *priv, unsigned int *privSz,
+                                 unsigned char *pub, unsigned int *pubSz)
+{
+#ifndef WOLFSSL_KEY_GEN
+    WOLFSSL_MSG("No Key Gen built in");
+    (void) priv;
+    (void) privSz;
+    (void) pub;
+    (void) pubSz;
+    return WOLFSSL_FAILURE;
+#else /* WOLFSSL_KEY_GEN */
+    int ret = WOLFSSL_FAILURE;
+    int initTmpRng = 0;
+    WC_RNG *rng = NULL;
+#ifdef WOLFSSL_SMALL_STACK
+    WC_RNG *tmpRNG = NULL;
+#else
+    WC_RNG tmpRNG[1];
+#endif
+
+    WOLFSSL_ENTER("wolfSSL_EC25519_generate_key");
+
+    if (priv == NULL || privSz == NULL || *privSz < CURVE25519_KEYSIZE ||
+        pub == NULL || pubSz == NULL || *pubSz < CURVE25519_KEYSIZE) {
+        WOLFSSL_MSG("Bad arguments");
+        return WOLFSSL_FAILURE;
+    }
+
+#ifdef WOLFSSL_SMALL_STACK
+    tmpRNG = (WC_RNG*)XMALLOC(sizeof(WC_RNG), NULL, DYNAMIC_TYPE_RNG);
+    if (tmpRNG == NULL)
+        return WOLFSSL_FAILURE;
+#endif
+    if (wc_InitRng(tmpRNG) == 0) {
+        rng = tmpRNG;
+        initTmpRng = 1;
+    }
+    else {
+        WOLFSSL_MSG("Bad RNG Init, trying global");
+        if (initGlobalRNG == 0)
+            WOLFSSL_MSG("Global RNG no Init");
+        else
+            rng = &globalRNG;
+    }
+
+    if (rng) {
+        curve25519_key key;
+
+        if (wc_curve25519_init(&key) != MP_OKAY)
+            WOLFSSL_MSG("wc_curve25519_init failed");
+        else if (wc_curve25519_make_key(rng, CURVE25519_KEYSIZE, &key)!=MP_OKAY)
+            WOLFSSL_MSG("wc_curve25519_make_key failed");
+        /* export key pair */
+        else if (wc_curve25519_export_key_raw_ex(&key, priv, privSz, pub,
+                                                 pubSz, EC25519_LITTLE_ENDIAN)
+                 != MP_OKAY)
+            WOLFSSL_MSG("wc_curve25519_export_key_raw_ex failed");
+        else
+            ret = WOLFSSL_SUCCESS;
+
+        wc_curve25519_free(&key);
+    }
+
+    if (initTmpRng)
+        wc_FreeRng(tmpRNG);
+
+#ifdef WOLFSSL_SMALL_STACK
+    XFREE(tmpRNG, NULL, DYNAMIC_TYPE_RNG);
+#endif
+
+    return ret;
+#endif /* WOLFSSL_KEY_GEN */
+}
+
+/* return 1 if success, 0 if error
+ * input and output keys are little endian format
+ */
+int wolfSSL_EC25519_shared_key(unsigned char *shared, unsigned int *sharedSz,
+                               const unsigned char *priv, unsigned int privSz,
+                               const unsigned char *pub, unsigned int pubSz)
+{
+#ifndef WOLFSSL_KEY_GEN
+    WOLFSSL_MSG("No Key Gen built in");
+    (void) shared;
+    (void) sharedSz;
+    (void) priv;
+    (void) privSz;
+    (void) pub;
+    (void) pubSz;
+    return WOLFSSL_FAILURE;
+#else /* WOLFSSL_KEY_GEN */
+    int ret = WOLFSSL_FAILURE;
+    curve25519_key privkey, pubkey;
+
+    WOLFSSL_ENTER("wolfSSL_EC25519_shared_key");
+
+    if (shared == NULL || sharedSz == NULL || *sharedSz < CURVE25519_KEYSIZE ||
+        priv == NULL || privSz < CURVE25519_KEYSIZE ||
+        pub == NULL || pubSz < CURVE25519_KEYSIZE) {
+        WOLFSSL_MSG("Bad arguments");
+        return WOLFSSL_FAILURE;
+    }
+
+    /* import private key */
+    if (wc_curve25519_init(&privkey) != MP_OKAY) {
+        WOLFSSL_MSG("wc_curve25519_init privkey failed");
+        return ret;
+    }
+    if (wc_curve25519_import_private_ex(priv, privSz, &privkey,
+                                        EC25519_LITTLE_ENDIAN) != MP_OKAY) {
+        WOLFSSL_MSG("wc_curve25519_import_private_ex failed");
+        wc_curve25519_free(&privkey);
+        return ret;
+    }
+
+    /* import public key */
+    if (wc_curve25519_init(&pubkey) != MP_OKAY) {
+        WOLFSSL_MSG("wc_curve25519_init pubkey failed");
+        wc_curve25519_free(&privkey);
+        return ret;
+    }
+    if (wc_curve25519_import_public_ex(pub, pubSz, &pubkey,
+                                       EC25519_LITTLE_ENDIAN) != MP_OKAY) {
+        WOLFSSL_MSG("wc_curve25519_import_public_ex failed");
+        wc_curve25519_free(&privkey);
+        wc_curve25519_free(&pubkey);
+        return ret;
+    }
+
+    if (wc_curve25519_shared_secret_ex(&privkey, &pubkey,
+                                       shared, sharedSz,
+                                       EC25519_LITTLE_ENDIAN) != MP_OKAY)
+        WOLFSSL_MSG("wc_curve25519_shared_secret_ex failed");
+    else
+        ret = WOLFSSL_SUCCESS;
+
+    wc_curve25519_free(&privkey);
+    wc_curve25519_free(&pubkey);
+
+    return ret;
+#endif /* WOLFSSL_KEY_GEN */
+}
+#endif /* OPENSSL_EXTRA && HAVE_CURVE25519 */
+
+#if defined(OPENSSL_EXTRA) && defined(HAVE_ED25519)
+/* return 1 if success, 0 if error
+ * output keys are little endian format
+ */
+int wolfSSL_ED25519_generate_key(unsigned char *priv, unsigned int *privSz,
+                                 unsigned char *pub, unsigned int *pubSz)
+{
+#ifndef WOLFSSL_KEY_GEN
+    WOLFSSL_MSG("No Key Gen built in");
+    (void) priv;
+    (void) privSz;
+    (void) pub;
+    (void) pubSz;
+    return WOLFSSL_FAILURE;
+#else /* WOLFSSL_KEY_GEN */
+    int ret = WOLFSSL_FAILURE;
+    int initTmpRng = 0;
+    WC_RNG *rng = NULL;
+#ifdef WOLFSSL_SMALL_STACK
+    WC_RNG *tmpRNG = NULL;
+#else
+    WC_RNG tmpRNG[1];
+#endif
+
+    WOLFSSL_ENTER("wolfSSL_ED25519_generate_key");
+
+    if (priv == NULL || privSz == NULL || *privSz < ED25519_PRV_KEY_SIZE ||
+        pub == NULL || pubSz == NULL || *pubSz < ED25519_PUB_KEY_SIZE) {
+        WOLFSSL_MSG("Bad arguments");
+        return WOLFSSL_FAILURE;
+    }
+
+#ifdef WOLFSSL_SMALL_STACK
+    tmpRNG = (WC_RNG*)XMALLOC(sizeof(WC_RNG), NULL, DYNAMIC_TYPE_RNG);
+    if (tmpRNG == NULL)
+        return WOLFSSL_FATAL_ERROR;
+#endif
+    if (wc_InitRng(tmpRNG) == 0) {
+        rng = tmpRNG;
+        initTmpRng = 1;
+    }
+    else {
+        WOLFSSL_MSG("Bad RNG Init, trying global");
+        if (initGlobalRNG == 0)
+            WOLFSSL_MSG("Global RNG no Init");
+        else
+            rng = &globalRNG;
+    }
+
+    if (rng) {
+        ed25519_key key;
+
+        if (wc_ed25519_init(&key) != MP_OKAY)
+            WOLFSSL_MSG("wc_ed25519_init failed");
+        else if (wc_ed25519_make_key(rng, ED25519_KEY_SIZE, &key)!=MP_OKAY)
+            WOLFSSL_MSG("wc_ed25519_make_key failed");
+        /* export private key */
+        else if (wc_ed25519_export_key(&key, priv, privSz, pub, pubSz)!=MP_OKAY)
+            WOLFSSL_MSG("wc_ed25519_export_key failed");
+        else
+            ret = WOLFSSL_SUCCESS;
+
+        wc_ed25519_free(&key);
+    }
+
+    if (initTmpRng)
+        wc_FreeRng(tmpRNG);
+
+#ifdef WOLFSSL_SMALL_STACK
+    XFREE(tmpRNG, NULL, DYNAMIC_TYPE_RNG);
+#endif
+
+    return ret;
+#endif /* WOLFSSL_KEY_GEN */
+}
+
+/* return 1 if success, 0 if error
+ * input and output keys are little endian format
+ * priv is a buffer containing private and public part of key
+ */
+int wolfSSL_ED25519_sign(const unsigned char *msg, unsigned int msgSz,
+                         const unsigned char *priv, unsigned int privSz,
+                         unsigned char *sig, unsigned int *sigSz)
+{
+#ifndef WOLFSSL_KEY_GEN
+    WOLFSSL_MSG("No Key Gen built in");
+    (void) msg;
+    (void) msgSz;
+    (void) priv;
+    (void) privSz;
+    (void) sig;
+    (void) sigSz;
+    return WOLFSSL_FAILURE;
+#else /* WOLFSSL_KEY_GEN */
+    ed25519_key key;
+    int ret = WOLFSSL_FAILURE;
+
+    WOLFSSL_ENTER("wolfSSL_ED25519_sign");
+
+    if (priv == NULL || privSz != ED25519_PRV_KEY_SIZE ||
+        msg == NULL || sig == NULL || *sigSz < ED25519_SIG_SIZE) {
+        WOLFSSL_MSG("Bad arguments");
+        return WOLFSSL_FAILURE;
+    }
+
+    /* import key */
+    if (wc_ed25519_init(&key) != MP_OKAY) {
+        WOLFSSL_MSG("wc_curve25519_init failed");
+        return ret;
+    }
+    if (wc_ed25519_import_private_key(priv, privSz/2,
+                                      priv+(privSz/2), ED25519_PUB_KEY_SIZE,
+                                      &key) != MP_OKAY){
+        WOLFSSL_MSG("wc_ed25519_import_private failed");
+        wc_ed25519_free(&key);
+        return ret;
+    }
+
+    if (wc_ed25519_sign_msg(msg, msgSz, sig, sigSz, &key) != MP_OKAY)
+        WOLFSSL_MSG("wc_curve25519_shared_secret_ex failed");
+    else
+        ret = WOLFSSL_SUCCESS;
+
+    wc_ed25519_free(&key);
+
+    return ret;
+#endif /* WOLFSSL_KEY_GEN */
+}
+
+/* return 1 if success, 0 if error
+ * input and output keys are little endian format
+ * pub is a buffer containing public part of key
+ */
+int wolfSSL_ED25519_verify(const unsigned char *msg, unsigned int msgSz,
+                           const unsigned char *pub, unsigned int pubSz,
+                           const unsigned char *sig, unsigned int sigSz)
+{
+#ifndef WOLFSSL_KEY_GEN
+    WOLFSSL_MSG("No Key Gen built in");
+    (void) msg;
+    (void) msgSz;
+    (void) pub;
+    (void) pubSz;
+    (void) sig;
+    (void) sigSz;
+    return WOLFSSL_FAILURE;
+#else /* WOLFSSL_KEY_GEN */
+    ed25519_key key;
+    int ret = WOLFSSL_FAILURE, check = 0;
+
+    WOLFSSL_ENTER("wolfSSL_ED25519_verify");
+
+    if (pub == NULL || pubSz != ED25519_PUB_KEY_SIZE ||
+        msg == NULL || sig == NULL || sigSz != ED25519_SIG_SIZE) {
+        WOLFSSL_MSG("Bad arguments");
+        return WOLFSSL_FAILURE;
+    }
+
+    /* import key */
+    if (wc_ed25519_init(&key) != MP_OKAY) {
+        WOLFSSL_MSG("wc_curve25519_init failed");
+        return ret;
+    }
+    if (wc_ed25519_import_public(pub, pubSz, &key) != MP_OKAY){
+        WOLFSSL_MSG("wc_ed25519_import_public failed");
+        wc_ed25519_free(&key);
+        return ret;
+    }
+
+    if ((ret = wc_ed25519_verify_msg((byte*)sig, sigSz, msg, msgSz,
+                                     &check, &key)) != MP_OKAY) {
+        WOLFSSL_MSG("wc_ed25519_verify_msg failed");
+    }
+    else if (!check)
+        WOLFSSL_MSG("wc_ed25519_verify_msg failed (signature invalid)");
+    else
+        ret = WOLFSSL_SUCCESS;
+
+    wc_ed25519_free(&key);
+
+    return ret;
+#endif /* WOLFSSL_KEY_GEN */
+}
+
+#endif /* OPENSSL_EXTRA && HAVE_ED25519 */
+
+#if defined(OPENSSL_EXTRA) && defined(HAVE_CURVE448)
+/* return 1 if success, 0 if error
+ * output keys are little endian format
+ */
+int wolfSSL_EC448_generate_key(unsigned char *priv, unsigned int *privSz,
+                               unsigned char *pub, unsigned int *pubSz)
+{
+#ifndef WOLFSSL_KEY_GEN
+    WOLFSSL_MSG("No Key Gen built in");
+    (void) priv;
+    (void) privSz;
+    (void) pub;
+    (void) pubSz;
+    return WOLFSSL_FAILURE;
+#else /* WOLFSSL_KEY_GEN */
+    int ret = WOLFSSL_FAILURE;
+    int initTmpRng = 0;
+    WC_RNG *rng = NULL;
+#ifdef WOLFSSL_SMALL_STACK
+    WC_RNG *tmpRNG = NULL;
+#else
+    WC_RNG tmpRNG[1];
+#endif
+
+    WOLFSSL_ENTER("wolfSSL_EC448_generate_key");
+
+    if (priv == NULL || privSz == NULL || *privSz < CURVE448_KEY_SIZE ||
+        pub == NULL || pubSz == NULL || *pubSz < CURVE448_KEY_SIZE) {
+        WOLFSSL_MSG("Bad arguments");
+        return WOLFSSL_FAILURE;
+    }
+
+#ifdef WOLFSSL_SMALL_STACK
+    tmpRNG = (WC_RNG*)XMALLOC(sizeof(WC_RNG), NULL, DYNAMIC_TYPE_RNG);
+    if (tmpRNG == NULL)
+        return WOLFSSL_FAILURE;
+#endif
+    if (wc_InitRng(tmpRNG) == 0) {
+        rng = tmpRNG;
+        initTmpRng = 1;
+    }
+    else {
+        WOLFSSL_MSG("Bad RNG Init, trying global");
+        if (initGlobalRNG == 0)
+            WOLFSSL_MSG("Global RNG no Init");
+        else
+            rng = &globalRNG;
+    }
+
+    if (rng) {
+        curve448_key key;
+
+        if (wc_curve448_init(&key) != MP_OKAY)
+            WOLFSSL_MSG("wc_curve448_init failed");
+        else if (wc_curve448_make_key(rng, CURVE448_KEY_SIZE, &key)!=MP_OKAY)
+            WOLFSSL_MSG("wc_curve448_make_key failed");
+        /* export key pair */
+        else if (wc_curve448_export_key_raw_ex(&key, priv, privSz, pub, pubSz,
+                                               EC448_LITTLE_ENDIAN)
+                 != MP_OKAY)
+            WOLFSSL_MSG("wc_curve448_export_key_raw_ex failed");
+        else
+            ret = WOLFSSL_SUCCESS;
+
+        wc_curve448_free(&key);
+    }
+
+    if (initTmpRng)
+        wc_FreeRng(tmpRNG);
+
+#ifdef WOLFSSL_SMALL_STACK
+    XFREE(tmpRNG, NULL, DYNAMIC_TYPE_RNG);
+#endif
+
+    return ret;
+#endif /* WOLFSSL_KEY_GEN */
+}
+
+/* return 1 if success, 0 if error
+ * input and output keys are little endian format
+ */
+int wolfSSL_EC448_shared_key(unsigned char *shared, unsigned int *sharedSz,
+                             const unsigned char *priv, unsigned int privSz,
+                             const unsigned char *pub, unsigned int pubSz)
+{
+#ifndef WOLFSSL_KEY_GEN
+    WOLFSSL_MSG("No Key Gen built in");
+    (void) shared;
+    (void) sharedSz;
+    (void) priv;
+    (void) privSz;
+    (void) pub;
+    (void) pubSz;
+    return WOLFSSL_FAILURE;
+#else /* WOLFSSL_KEY_GEN */
+    int ret = WOLFSSL_FAILURE;
+    curve448_key privkey, pubkey;
+
+    WOLFSSL_ENTER("wolfSSL_EC448_shared_key");
+
+    if (shared == NULL || sharedSz == NULL || *sharedSz < CURVE448_KEY_SIZE ||
+            priv == NULL || privSz < CURVE448_KEY_SIZE ||
+            pub == NULL || pubSz < CURVE448_KEY_SIZE) {
+        WOLFSSL_MSG("Bad arguments");
+        return WOLFSSL_FAILURE;
+    }
+
+    /* import private key */
+    if (wc_curve448_init(&privkey) != MP_OKAY) {
+        WOLFSSL_MSG("wc_curve448_init privkey failed");
+        return ret;
+    }
+    if (wc_curve448_import_private_ex(priv, privSz, &privkey,
+                                      EC448_LITTLE_ENDIAN) != MP_OKAY) {
+        WOLFSSL_MSG("wc_curve448_import_private_ex failed");
+        wc_curve448_free(&privkey);
+        return ret;
+    }
+
+    /* import public key */
+    if (wc_curve448_init(&pubkey) != MP_OKAY) {
+        WOLFSSL_MSG("wc_curve448_init pubkey failed");
+        wc_curve448_free(&privkey);
+        return ret;
+    }
+    if (wc_curve448_import_public_ex(pub, pubSz, &pubkey,
+                                     EC448_LITTLE_ENDIAN) != MP_OKAY) {
+        WOLFSSL_MSG("wc_curve448_import_public_ex failed");
+        wc_curve448_free(&privkey);
+        wc_curve448_free(&pubkey);
+        return ret;
+    }
+
+    if (wc_curve448_shared_secret_ex(&privkey, &pubkey, shared, sharedSz,
+                                     EC448_LITTLE_ENDIAN) != MP_OKAY)
+        WOLFSSL_MSG("wc_curve448_shared_secret_ex failed");
+    else
+        ret = WOLFSSL_SUCCESS;
+
+    wc_curve448_free(&privkey);
+    wc_curve448_free(&pubkey);
+
+    return ret;
+#endif /* WOLFSSL_KEY_GEN */
+}
+#endif /* OPENSSL_EXTRA && HAVE_CURVE448 */
+
+#if defined(OPENSSL_EXTRA) && defined(HAVE_ED448)
+/* return 1 if success, 0 if error
+ * output keys are little endian format
+ */
+int wolfSSL_ED448_generate_key(unsigned char *priv, unsigned int *privSz,
+                               unsigned char *pub, unsigned int *pubSz)
+{
+#ifndef WOLFSSL_KEY_GEN
+    WOLFSSL_MSG("No Key Gen built in");
+    (void) priv;
+    (void) privSz;
+    (void) pub;
+    (void) pubSz;
+    return WOLFSSL_FAILURE;
+#else /* WOLFSSL_KEY_GEN */
+    int ret = WOLFSSL_FAILURE;
+    int initTmpRng = 0;
+    WC_RNG *rng = NULL;
+#ifdef WOLFSSL_SMALL_STACK
+    WC_RNG *tmpRNG = NULL;
+#else
+    WC_RNG tmpRNG[1];
+#endif
+
+    WOLFSSL_ENTER("wolfSSL_ED448_generate_key");
+
+    if (priv == NULL || privSz == NULL || *privSz < ED448_PRV_KEY_SIZE ||
+            pub == NULL || pubSz == NULL || *pubSz < ED448_PUB_KEY_SIZE) {
+        WOLFSSL_MSG("Bad arguments");
+        return WOLFSSL_FAILURE;
+    }
+
+#ifdef WOLFSSL_SMALL_STACK
+    tmpRNG = (WC_RNG*)XMALLOC(sizeof(WC_RNG), NULL, DYNAMIC_TYPE_RNG);
+    if (tmpRNG == NULL)
+        return WOLFSSL_FATAL_ERROR;
+#endif
+    if (wc_InitRng(tmpRNG) == 0) {
+        rng = tmpRNG;
+        initTmpRng = 1;
+    }
+    else {
+        WOLFSSL_MSG("Bad RNG Init, trying global");
+        if (initGlobalRNG == 0)
+            WOLFSSL_MSG("Global RNG no Init");
+        else
+            rng = &globalRNG;
+    }
+
+    if (rng) {
+        ed448_key key;
+
+        if (wc_ed448_init(&key) != MP_OKAY)
+            WOLFSSL_MSG("wc_ed448_init failed");
+        else if (wc_ed448_make_key(rng, ED448_KEY_SIZE, &key) != MP_OKAY)
+            WOLFSSL_MSG("wc_ed448_make_key failed");
+        /* export private key */
+        else if (wc_ed448_export_key(&key, priv, privSz, pub, pubSz) != MP_OKAY)
+            WOLFSSL_MSG("wc_ed448_export_key failed");
+        else
+            ret = WOLFSSL_SUCCESS;
+
+        wc_ed448_free(&key);
+    }
+
+    if (initTmpRng)
+        wc_FreeRng(tmpRNG);
+
+#ifdef WOLFSSL_SMALL_STACK
+    XFREE(tmpRNG, NULL, DYNAMIC_TYPE_RNG);
+#endif
+
+    return ret;
+#endif /* WOLFSSL_KEY_GEN */
+}
+
+/* return 1 if success, 0 if error
+ * input and output keys are little endian format
+ * priv is a buffer containing private and public part of key
+ */
+int wolfSSL_ED448_sign(const unsigned char *msg, unsigned int msgSz,
+                       const unsigned char *priv, unsigned int privSz,
+                       unsigned char *sig, unsigned int *sigSz)
+{
+#ifndef WOLFSSL_KEY_GEN
+    WOLFSSL_MSG("No Key Gen built in");
+    (void) msg;
+    (void) msgSz;
+    (void) priv;
+    (void) privSz;
+    (void) sig;
+    (void) sigSz;
+    return WOLFSSL_FAILURE;
+#else /* WOLFSSL_KEY_GEN */
+    ed448_key key;
+    int ret = WOLFSSL_FAILURE;
+
+    WOLFSSL_ENTER("wolfSSL_ED448_sign");
+
+    if (priv == NULL || privSz != ED448_PRV_KEY_SIZE || msg == NULL ||
+            sig == NULL || *sigSz < ED448_SIG_SIZE) {
+        WOLFSSL_MSG("Bad arguments");
+        return WOLFSSL_FAILURE;
+    }
+
+    /* import key */
+    if (wc_ed448_init(&key) != MP_OKAY) {
+        WOLFSSL_MSG("wc_curve448_init failed");
+        return ret;
+    }
+    if (wc_ed448_import_private_key(priv, privSz/2, priv+(privSz/2),
+                                    ED448_PUB_KEY_SIZE, &key) != MP_OKAY){
+        WOLFSSL_MSG("wc_ed448_import_private failed");
+        wc_ed448_free(&key);
+        return ret;
+    }
+
+    if (wc_ed448_sign_msg(msg, msgSz, sig, sigSz, &key) != MP_OKAY)
+        WOLFSSL_MSG("wc_curve448_shared_secret_ex failed");
+    else
+        ret = WOLFSSL_SUCCESS;
+
+    wc_ed448_free(&key);
+
+    return ret;
+#endif /* WOLFSSL_KEY_GEN */
+}
+
+/* return 1 if success, 0 if error
+ * input and output keys are little endian format
+ * pub is a buffer containing public part of key
+ */
+int wolfSSL_ED448_verify(const unsigned char *msg, unsigned int msgSz,
+                         const unsigned char *pub, unsigned int pubSz,
+                         const unsigned char *sig, unsigned int sigSz)
+{
+#ifndef WOLFSSL_KEY_GEN
+    WOLFSSL_MSG("No Key Gen built in");
+    (void) msg;
+    (void) msgSz;
+    (void) pub;
+    (void) pubSz;
+    (void) sig;
+    (void) sigSz;
+    return WOLFSSL_FAILURE;
+#else /* WOLFSSL_KEY_GEN */
+    ed448_key key;
+    int ret = WOLFSSL_FAILURE, check = 0;
+
+    WOLFSSL_ENTER("wolfSSL_ED448_verify");
+
+    if (pub == NULL || pubSz != ED448_PUB_KEY_SIZE || msg == NULL ||
+            sig == NULL || sigSz != ED448_SIG_SIZE) {
+        WOLFSSL_MSG("Bad arguments");
+        return WOLFSSL_FAILURE;
+    }
+
+    /* import key */
+    if (wc_ed448_init(&key) != MP_OKAY) {
+        WOLFSSL_MSG("wc_curve448_init failed");
+        return ret;
+    }
+    if (wc_ed448_import_public(pub, pubSz, &key) != MP_OKAY){
+        WOLFSSL_MSG("wc_ed448_import_public failed");
+        wc_ed448_free(&key);
+        return ret;
+    }
+
+    if ((ret = wc_ed448_verify_msg((byte*)sig, sigSz, msg, msgSz, &check,
+                                   &key)) != MP_OKAY) {
+        WOLFSSL_MSG("wc_ed448_verify_msg failed");
+    }
+    else if (!check)
+        WOLFSSL_MSG("wc_ed448_verify_msg failed (signature invalid)");
+    else
+        ret = WOLFSSL_SUCCESS;
+
+    wc_ed448_free(&key);
+
+    return ret;
+#endif /* WOLFSSL_KEY_GEN */
+}
+
+#endif /* OPENSSL_EXTRA && HAVE_ED448 */
+
+#ifdef WOLFSSL_JNI
+
+int wolfSSL_set_jobject(WOLFSSL* ssl, void* objPtr)
+{
+    WOLFSSL_ENTER("wolfSSL_set_jobject");
+    if (ssl != NULL)
+    {
+        ssl->jObjectRef = objPtr;
+        return WOLFSSL_SUCCESS;
+    }
+    return WOLFSSL_FAILURE;
+}
+
+void* wolfSSL_get_jobject(WOLFSSL* ssl)
+{
+    WOLFSSL_ENTER("wolfSSL_get_jobject");
+    if (ssl != NULL)
+        return ssl->jObjectRef;
+    return NULL;
+}
+
+#endif /* WOLFSSL_JNI */
+
+
+#ifdef WOLFSSL_ASYNC_CRYPT
+int wolfSSL_CTX_AsyncPoll(WOLFSSL_CTX* ctx, WOLF_EVENT** events, int maxEvents,
+    WOLF_EVENT_FLAG flags, int* eventCount)
+{
+    if (ctx == NULL) {
+        return BAD_FUNC_ARG;
+    }
+
+    return wolfAsync_EventQueuePoll(&ctx->event_queue, NULL,
+                                        events, maxEvents, flags, eventCount);
+}
+
+int wolfSSL_AsyncPoll(WOLFSSL* ssl, WOLF_EVENT_FLAG flags)
+{
+    int ret, eventCount = 0;
+    WOLF_EVENT* events[1];
+
+    if (ssl == NULL) {
+        return BAD_FUNC_ARG;
+    }
+
+    ret = wolfAsync_EventQueuePoll(&ssl->ctx->event_queue, ssl,
+        events, sizeof(events)/sizeof(*events), flags, &eventCount);
+    if (ret == 0) {
+        ret = eventCount;
+    }
+
+    return ret;
+}
+#endif /* WOLFSSL_ASYNC_CRYPT */
+
+#ifdef OPENSSL_EXTRA
+unsigned long wolfSSL_ERR_peek_error_line_data(const char **file, int *line,
+                                               const char **data, int *flags)
+{
+    WOLFSSL_ENTER("wolfSSL_ERR_peek_error_line_data");
+
+    (void)line;
+    (void)file;
+
+    /* No data or flags stored - error display only in Nginx. */
+    if (data != NULL) {
+        *data = "";
+    }
+    if (flags != NULL) {
+        *flags = 0;
+    }
+
+#if defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX) || \
+    defined(WOLFSSL_OPENSSH) || defined(WOLFSSL_HAPROXY) || \
+    defined(WOLFSSL_MYSQL_COMPATIBLE)
+    {
+        int ret = 0;
+
+        while (1) {
+            if ((ret = wc_PeekErrorNode(-1, file, NULL, line)) < 0) {
+                WOLFSSL_MSG("Issue peeking at error node in queue");
+                return 0;
+            }
+            /* OpenSSL uses positive error codes */
+            if (ret < 0) {
+                ret = -ret;
+            }
+
+            if (ret == -ASN_NO_PEM_HEADER)
+                return (ERR_LIB_PEM << 24) | PEM_R_NO_START_LINE;
+            if (ret != WANT_READ && ret != WANT_WRITE &&
+                    ret != ZERO_RETURN && ret != WOLFSSL_ERROR_ZERO_RETURN &&
+                    ret != SOCKET_PEER_CLOSED_E && ret != SOCKET_ERROR_E)
+                break;
+
+            wc_RemoveErrorNode(-1);
+        }
+
+        return (unsigned long)ret;
+    }
+#else
+    return (unsigned long)(0 - NOT_COMPILED_IN);
+#endif
+}
+#endif
+
+#if defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY)
+
+/* returns a pointer to internal cipher suite list. Should not be free'd by
+ * caller.
+ */
+WOLF_STACK_OF(WOLFSSL_CIPHER) *wolfSSL_get_ciphers_compat(const WOLFSSL *ssl)
+{
+    WOLF_STACK_OF(WOLFSSL_CIPHER)* ret = NULL;
+    Suites* suites;
+
+    WOLFSSL_ENTER("wolfSSL_get_ciphers_compat");
+    if (ssl == NULL || (ssl->suites == NULL && ssl->ctx->suites == NULL)) {
+        return NULL;
+    }
+
+    if (ssl->suites != NULL) {
+        suites = ssl->suites;
+    }
+    else {
+        suites = ssl->ctx->suites;
+    }
+
+    /* check if stack needs populated */
+    if (suites->stack == NULL) {
+        int i;
+        for (i = 0; i < suites->suiteSz; i+=2) {
+            WOLFSSL_STACK* add = wolfSSL_sk_new_node(ssl->heap);
+            if (add != NULL) {
+                add->type = STACK_TYPE_CIPHER;
+                add->data.cipher.cipherSuite0 = suites->suites[i];
+                add->data.cipher.cipherSuite  = suites->suites[i+1];
+                #if defined(WOLFSSL_QT) || defined(OPENSSL_ALL)
+                /* in_stack is checked in wolfSSL_CIPHER_description */
+                add->data.cipher.in_stack = 1;
+                #endif
+
+                add->next = ret;
+                if (ret != NULL) {
+                    add->num = ret->num + 1;
+                }
+                else {
+                    add->num = 1;
+                }
+                ret = add;
+            }
+        }
+        suites->stack = ret;
+    }
+    return suites->stack;
+}
+
+#ifndef NO_WOLFSSL_STUB
+void wolfSSL_OPENSSL_config(char *config_name)
+{
+    (void)config_name;
+    WOLFSSL_STUB("OPENSSL_config");
+}
+#endif /* !NO_WOLFSSL_STUB */
+#endif /* OPENSSL_ALL || WOLFSSL_NGINX || WOLFSSL_HAPROXY */
+
+#if defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY) \
+    || defined(OPENSSL_EXTRA) || defined(HAVE_LIGHTY)
+int wolfSSL_X509_get_ex_new_index(int idx, void *arg, void *a, void *b, void *c)
+{
+    static int x509_idx = 0;
+
+    WOLFSSL_ENTER("wolfSSL_X509_get_ex_new_index");
+    (void)idx;
+    (void)arg;
+    (void)a;
+    (void)b;
+    (void)c;
+
+    return x509_idx++;
+}
+
+#if defined(HAVE_EX_DATA) || defined(FORTRESS)
+void* wolfSSL_CRYPTO_get_ex_data(const WOLFSSL_CRYPTO_EX_DATA* ex_data, int idx)
+{
+    WOLFSSL_ENTER("wolfSSL_CTX_get_ex_data");
+#ifdef MAX_EX_DATA
+    if(ex_data && idx < MAX_EX_DATA && idx >= 0) {
+        return ex_data->ex_data[idx];
+    }
+#else
+    (void)ex_data;
+    (void)idx;
+#endif
+    return NULL;
+}
+
+int wolfSSL_CRYPTO_set_ex_data(WOLFSSL_CRYPTO_EX_DATA* ex_data, int idx, void *data)
+{
+    WOLFSSL_ENTER("wolfSSL_CRYPTO_set_ex_data");
+#ifdef MAX_EX_DATA
+    if (ex_data && idx < MAX_EX_DATA && idx >= 0) {
+        ex_data->ex_data[idx] = data;
+        return WOLFSSL_SUCCESS;
+    }
+#else
+    (void)ex_data;
+    (void)idx;
+    (void)data;
+#endif
+    return WOLFSSL_FAILURE;
+}
+#endif /* defined(HAVE_EX_DATA) || defined(FORTRESS) */
+
+void *wolfSSL_X509_get_ex_data(X509 *x509, int idx)
+{
+    WOLFSSL_ENTER("wolfSSL_X509_get_ex_data");
+    #ifdef HAVE_EX_DATA
+    if (x509 != NULL) {
+        return wolfSSL_CRYPTO_get_ex_data(&x509->ex_data, idx);
+    }
+    #else
+    (void)x509;
+    (void)idx;
+    #endif
+    return NULL;
+}
+
+int wolfSSL_X509_set_ex_data(X509 *x509, int idx, void *data)
+{
+    WOLFSSL_ENTER("wolfSSL_X509_set_ex_data");
+    #ifdef HAVE_EX_DATA
+    if (x509 != NULL)
+    {
+        return wolfSSL_CRYPTO_set_ex_data(&x509->ex_data, idx, data);
+    }
+    #else
+    (void)x509;
+    (void)idx;
+    (void)data;
+    #endif
+    return WOLFSSL_FAILURE;
+}
+
+int wolfSSL_X509_NAME_digest(const WOLFSSL_X509_NAME *name,
+        const WOLFSSL_EVP_MD *type, unsigned char *md, unsigned int *len)
+{
+    WOLFSSL_ENTER("wolfSSL_X509_NAME_digest");
+
+    if (name == NULL || type == NULL)
+        return WOLFSSL_FAILURE;
+
+#if !defined(NO_FILESYSTEM) && !defined(NO_PWDBASED)
+    return wolfSSL_EVP_Digest((unsigned char*)name->fullName.fullName,
+                              name->fullName.fullNameLen, md, len, type, NULL);
+#else
+    (void)md;
+    (void)len;
+    return NOT_COMPILED_IN;
+#endif
+}
+
+long wolfSSL_SSL_CTX_get_timeout(const WOLFSSL_CTX *ctx)
+{
+    WOLFSSL_ENTER("wolfSSL_SSL_CTX_get_timeout");
+
+    if (ctx == NULL)
+        return 0;
+
+    return ctx->timeout;
+}
+
+
+/* returns the time in seconds of the current timeout */
+long wolfSSL_get_timeout(WOLFSSL* ssl)
+{
+    WOLFSSL_ENTER("wolfSSL_get_timeout");
+
+    if (ssl == NULL)
+        return 0;
+    return ssl->timeout;
+}
+
+#ifdef HAVE_ECC
+int wolfSSL_SSL_CTX_set_tmp_ecdh(WOLFSSL_CTX *ctx, WOLFSSL_EC_KEY *ecdh)
+{
+    WOLFSSL_ENTER("wolfSSL_SSL_CTX_set_tmp_ecdh");
+
+    if (ctx == NULL || ecdh == NULL)
+        return BAD_FUNC_ARG;
+
+    ctx->ecdhCurveOID = ecdh->group->curve_oid;
+
+    return WOLFSSL_SUCCESS;
+}
+#endif
+
+/* Assumes that the session passed in is from the cache. */
+int wolfSSL_SSL_CTX_remove_session(WOLFSSL_CTX *ctx, WOLFSSL_SESSION *s)
+{
+    WOLFSSL_ENTER("wolfSSL_SSL_CTX_remove_session");
+
+    if (ctx == NULL || s == NULL)
+        return BAD_FUNC_ARG;
+
+#ifdef HAVE_EXT_CACHE
+    if (!ctx->internalCacheOff)
+#endif
+    {
+        /* Don't remove session just timeout session. */
+        s->timeout = 0;
+    }
+
+#ifdef HAVE_EXT_CACHE
+    if (ctx->rem_sess_cb != NULL)
+        ctx->rem_sess_cb(ctx, s);
+#endif
+
+    return 0;
+}
+
+BIO *wolfSSL_SSL_get_rbio(const WOLFSSL *s)
+{
+    WOLFSSL_ENTER("wolfSSL_SSL_get_rbio");
+    /* Nginx sets the buffer size if the read BIO is different to write BIO.
+     * The setting buffer size doesn't do anything so return NULL for both.
+     */
+    if (s == NULL)
+        return NULL;
+
+    return s->biord;
+}
+BIO *wolfSSL_SSL_get_wbio(const WOLFSSL *s)
+{
+    WOLFSSL_ENTER("wolfSSL_SSL_get_wbio");
+    (void)s;
+    /* Nginx sets the buffer size if the read BIO is different to write BIO.
+     * The setting buffer size doesn't do anything so return NULL for both.
+     */
+    if (s == NULL)
+        return NULL;
+
+    return s->biowr;
+}
+
+int wolfSSL_SSL_do_handshake(WOLFSSL *s)
+{
+    WOLFSSL_ENTER("wolfSSL_SSL_do_handshake");
+
+    if (s == NULL)
+        return WOLFSSL_FAILURE;
+
+    if (s->options.side == WOLFSSL_CLIENT_END) {
+    #ifndef NO_WOLFSSL_CLIENT
+        return wolfSSL_connect(s);
+    #else
+        WOLFSSL_MSG("Client not compiled in");
+        return WOLFSSL_FAILURE;
+    #endif
+    }
+
+#ifndef NO_WOLFSSL_SERVER
+    return wolfSSL_accept(s);
+#else
+    WOLFSSL_MSG("Server not compiled in");
+    return WOLFSSL_FAILURE;
+#endif
+}
+
+int wolfSSL_SSL_in_init(WOLFSSL *ssl)
+{
+    WOLFSSL_ENTER("SSL_in_init");
+
+    if (ssl == NULL)
+        return WOLFSSL_FAILURE;
+
+    if (ssl->options.side == WOLFSSL_CLIENT_END) {
+        return ssl->options.connectState < SECOND_REPLY_DONE;
+    }
+    return ssl->options.acceptState < ACCEPT_THIRD_REPLY_DONE;
+}
+
+int wolfSSL_SSL_in_connect_init(WOLFSSL* ssl)
+{
+    WOLFSSL_ENTER("SSL_connect_init");
+
+    if (ssl == NULL)
+        return WOLFSSL_FAILURE;
+
+    if (ssl->options.side == WOLFSSL_CLIENT_END) {
+        return ssl->options.connectState > CONNECT_BEGIN &&
+            ssl->options.connectState < SECOND_REPLY_DONE;
+    }
+
+    return ssl->options.acceptState > ACCEPT_BEGIN &&
+        ssl->options.acceptState < ACCEPT_THIRD_REPLY_DONE;
+}
+
+#ifndef NO_SESSION_CACHE
+
+WOLFSSL_SESSION *wolfSSL_SSL_get0_session(const WOLFSSL *ssl)
+{
+    WOLFSSL_SESSION *session;
+
+    WOLFSSL_ENTER("wolfSSL_SSL_get0_session");
+
+    if (ssl == NULL) {
+        return NULL;
+    }
+
+    session = wolfSSL_get_session((WOLFSSL*)ssl);
+
+#ifdef HAVE_EXT_CACHE
+    ((WOLFSSL*)ssl)->extSession = session;
+#endif
+
+    return session;
+}
+
+#endif /* NO_SESSION_CACHE */
+
+int wolfSSL_X509_check_host(X509 *x, const char *chk, size_t chklen,
+                    unsigned int flags, char **peername)
+{
+    int         ret;
+    DecodedCert dCert;
+
+    WOLFSSL_ENTER("wolfSSL_X509_check_host");
+
+    /* flags and peername not needed for Nginx. */
+    (void)flags;
+    (void)peername;
+
+    if (flags == WOLFSSL_NO_WILDCARDS) {
+        WOLFSSL_MSG("X509_CHECK_FLAG_NO_WILDCARDS not yet implemented");
+        return WOLFSSL_FAILURE;
+    }
+
+    InitDecodedCert(&dCert, x->derCert->buffer, x->derCert->length, NULL);
+    ret = ParseCertRelative(&dCert, CERT_TYPE, 0, NULL);
+    if (ret != 0) {
+        FreeDecodedCert(&dCert);
+        return WOLFSSL_FAILURE;
+    }
+
+    ret = CheckHostName(&dCert, (char *)chk, chklen);
+    FreeDecodedCert(&dCert);
+    if (ret != 0)
+        return WOLFSSL_FAILURE;
+    return WOLFSSL_SUCCESS;
+}
+
+int wolfSSL_i2a_ASN1_INTEGER(BIO *bp, const WOLFSSL_ASN1_INTEGER *a)
+{
+    static char num[16] = { '0', '1', '2', '3', '4', '5', '6', '7',
+                            '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
+    int    i;
+    word32 j;
+    word32 len = 0;
+
+    WOLFSSL_ENTER("wolfSSL_i2a_ASN1_INTEGER");
+
+    if (bp == NULL || a == NULL)
+        return WOLFSSL_FAILURE;
+
+    /* Skip ASN.1 INTEGER (type) byte. */
+    i = 1;
+    /* When indefinite length, can't determine length with data available. */
+    if (a->data[i] == 0x80)
+        return 0;
+    /* One length byte if less than 0x80. */
+    if (a->data[i] < 0x80)
+        len = a->data[i++];
+    /* Multiple length byte if greater than 0x80. */
+    else if (a->data[i] > 0x80) {
+        switch (a->data[i++] - 0x80) {
+            case 4:
+                len |= a->data[i++] << 24;
+                FALL_THROUGH;
+            case 3:
+                len |= a->data[i++] << 16;
+                FALL_THROUGH;
+            case 2:
+                len |= a->data[i++] <<  8;
+                FALL_THROUGH;
+            case 1:
+                len |= a->data[i++];
+                break;
+            default:
+                /* Not supporting greater than 4 bytes of length. */
+                return 0;
+        }
+    }
+
+    /* Zero length integer is the value zero. */
+    if (len == 0) {
+        wolfSSL_BIO_write(bp, "00", 2);
+        return 2;
+    }
+
+    /* Don't do negative - just write out every byte. */
+    for (j = 0; j < len; i++,j++) {
+        wolfSSL_BIO_write(bp, &num[a->data[i] >> 4], 1);
+        wolfSSL_BIO_write(bp, &num[a->data[i] & 0xf], 1);
+    }
+
+    /* Two nibbles written for each byte. */
+    return len * 2;
+}
+
+
+#if defined(HAVE_SESSION_TICKET) && !defined(NO_WOLFSSL_SERVER)
+/* Expected return values from implementations of OpenSSL ticket key callback.
+ */
+#define TICKET_KEY_CB_RET_FAILURE    -1
+#define TICKET_KEY_CB_RET_NOT_FOUND   0
+#define TICKET_KEY_CB_RET_OK          1
+#define TICKET_KEY_CB_RET_RENEW       2
+
+/* The ticket key callback as used in OpenSSL is stored here. */
+static int (*ticketKeyCb)(WOLFSSL *ssl, unsigned char *name, unsigned char *iv,
+    WOLFSSL_EVP_CIPHER_CTX *ectx, WOLFSSL_HMAC_CTX *hctx, int enc) = NULL;
+
+/* Implementation of session ticket encryption/decryption using OpenSSL
+ * callback to initialize the cipher and HMAC.
+ *
+ * ssl           The SSL/TLS object.
+ * keyName       The key name - used to identify the key to be used.
+ * iv            The IV to use.
+ * mac           The MAC of the encrypted data.
+ * enc           Encrypt ticket.
+ * encTicket     The ticket data.
+ * encTicketLen  The length of the ticket data.
+ * encLen        The encrypted/decrypted ticket length - output length.
+ * ctx           Ignored. Application specific data.
+ * returns WOLFSSL_TICKET_RET_OK to indicate success,
+ *         WOLFSSL_TICKET_RET_CREATE if a new ticket is required and
+ *         WOLFSSL_TICKET_RET_FATAL on error.
+ */
+static int wolfSSL_TicketKeyCb(WOLFSSL* ssl,
+                                  unsigned char keyName[WOLFSSL_TICKET_NAME_SZ],
+                                  unsigned char iv[WOLFSSL_TICKET_IV_SZ],
+                                  unsigned char mac[WOLFSSL_TICKET_MAC_SZ],
+                                  int enc, unsigned char* encTicket,
+                                  int encTicketLen, int* encLen, void* ctx)
+{
+    byte                    digest[WC_MAX_DIGEST_SIZE];
+    WOLFSSL_EVP_CIPHER_CTX  evpCtx;
+    WOLFSSL_HMAC_CTX        hmacCtx;
+    unsigned int            mdSz = 0;
+    int                     len = 0;
+    int                     ret = WOLFSSL_TICKET_RET_FATAL;
+    int                     res;
+
+    (void)ctx;
+
+    if (ticketKeyCb == NULL)
+        return WOLFSSL_TICKET_RET_FATAL;
+
+    wolfSSL_EVP_CIPHER_CTX_init(&evpCtx);
+    /* Initialize the cipher and HMAC. */
+    res = ticketKeyCb(ssl, keyName, iv, &evpCtx, &hmacCtx, enc);
+    if (res != TICKET_KEY_CB_RET_OK && res != TICKET_KEY_CB_RET_RENEW)
+        return WOLFSSL_TICKET_RET_FATAL;
+
+    if (enc)
+    {
+        /* Encrypt in place. */
+        if (!wolfSSL_EVP_CipherUpdate(&evpCtx, encTicket, &len,
+                                      encTicket, encTicketLen))
+            goto end;
+        encTicketLen = len;
+        if (!wolfSSL_EVP_EncryptFinal(&evpCtx, &encTicket[encTicketLen], &len))
+            goto end;
+        /* Total length of encrypted data. */
+        encTicketLen += len;
+        *encLen = encTicketLen;
+
+        /* HMAC the encrypted data into the parameter 'mac'. */
+        if (!wolfSSL_HMAC_Update(&hmacCtx, encTicket, encTicketLen))
+            goto end;
+#ifdef WOLFSSL_SHA512
+        /* Check for SHA512, which would overrun the mac buffer */
+        if (hmacCtx.hmac.macType == WC_SHA512)
+            goto end;
+#endif
+        if (!wolfSSL_HMAC_Final(&hmacCtx, mac, &mdSz))
+            goto end;
+    }
+    else
+    {
+        /* HMAC the encrypted data and compare it to the passed in data. */
+        if (!wolfSSL_HMAC_Update(&hmacCtx, encTicket, encTicketLen))
+            goto end;
+        if (!wolfSSL_HMAC_Final(&hmacCtx, digest, &mdSz))
+            goto end;
+        if (XMEMCMP(mac, digest, mdSz) != 0)
+            goto end;
+
+        /* Decrypt the ticket data in place. */
+        if (!wolfSSL_EVP_CipherUpdate(&evpCtx, encTicket, &len,
+                                      encTicket, encTicketLen))
+            goto end;
+        encTicketLen = len;
+        if (!wolfSSL_EVP_DecryptFinal(&evpCtx, &encTicket[encTicketLen], &len))
+            goto end;
+        /* Total length of decrypted data. */
+        *encLen = encTicketLen + len;
+    }
+
+    ret = (res == TICKET_KEY_CB_RET_RENEW) ? WOLFSSL_TICKET_RET_CREATE :
+                                             WOLFSSL_TICKET_RET_OK;
+end:
+    return ret;
+}
+
+/* Set the callback to use when encrypting/decrypting tickets.
+ *
+ * ctx  The SSL/TLS context object.
+ * cb   The OpenSSL session ticket callback.
+ * returns WOLFSSL_SUCCESS to indicate success.
+ */
+int wolfSSL_CTX_set_tlsext_ticket_key_cb(WOLFSSL_CTX *ctx, int (*cb)(
+    WOLFSSL *ssl, unsigned char *name, unsigned char *iv,
+    WOLFSSL_EVP_CIPHER_CTX *ectx, WOLFSSL_HMAC_CTX *hctx, int enc))
+{
+    /* Store callback in a global. */
+    ticketKeyCb = cb;
+    /* Set the ticket encryption callback to be a wrapper around OpenSSL
+     * callback.
+     */
+    ctx->ticketEncCb = wolfSSL_TicketKeyCb;
+
+    return WOLFSSL_SUCCESS;
+}
+#endif /* HAVE_SESSION_TICKET */
+
+#endif /* OPENSSL_ALL || WOLFSSL_NGINX || WOLFSSL_HAPROXY ||
+    OPENSSL_EXTRA || HAVE_LIGHTY */
+
+#if defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY)
+#ifdef HAVE_OCSP
+/* Not an OpenSSL API. */
+int wolfSSL_get_ocsp_response(WOLFSSL* ssl, byte** response)
+{
+    *response = ssl->ocspResp;
+    return ssl->ocspRespSz;
+}
+
+/* Not an OpenSSL API. */
+char* wolfSSL_get_ocsp_url(WOLFSSL* ssl)
+{
+    return ssl->url;
+}
+
+/* Not an OpenSSL API. */
+int wolfSSL_set_ocsp_url(WOLFSSL* ssl, char* url)
+{
+    if (ssl == NULL)
+        return WOLFSSL_FAILURE;
+
+    ssl->url = url;
+    return WOLFSSL_SUCCESS;
+}
+#endif /* OCSP */
+#endif /* OPENSSL_ALL / WOLFSSL_NGINX  / WOLFSSL_HAPROXY */
+
+#if defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY) || \
+    defined(OPENSSL_EXTRA) || defined(OPENSSL_ALL)
+int wolfSSL_CTX_get_extra_chain_certs(WOLFSSL_CTX* ctx, WOLF_STACK_OF(X509)** chain)
+{
+    word32         idx;
+    word32         length;
+    WOLFSSL_STACK* node;
+    WOLFSSL_STACK* last = NULL;
+
+    if (ctx == NULL || chain == NULL) {
+        chain = NULL;
+        return WOLFSSL_FAILURE;
+    }
+    if (ctx->x509Chain != NULL) {
+        *chain = ctx->x509Chain;
+        return WOLFSSL_SUCCESS;
+    }
+
+    /* If there are no chains then success! */
+    *chain = NULL;
+    if (ctx->certChain == NULL || ctx->certChain->length == 0) {
+        return WOLFSSL_SUCCESS;
+    }
+
+    /* Create a new stack of WOLFSSL_X509 object from chain buffer. */
+    for (idx = 0; idx < ctx->certChain->length; ) {
+        node = (WOLFSSL_STACK*)XMALLOC(sizeof(WOLFSSL_STACK), NULL,
+                                       DYNAMIC_TYPE_OPENSSL);
+        if (node == NULL)
+            return WOLFSSL_FAILURE;
+        node->next = NULL;
+
+        /* 3 byte length | X509 DER data */
+        ato24(ctx->certChain->buffer + idx, &length);
+        idx += 3;
+
+        /* Create a new X509 from DER encoded data. */
+        node->data.x509 = wolfSSL_X509_d2i(NULL, ctx->certChain->buffer + idx,
+            length);
+        if (node->data.x509 == NULL) {
+            XFREE(node, NULL, DYNAMIC_TYPE_OPENSSL);
+            /* Return as much of the chain as we created. */
+            ctx->x509Chain = *chain;
+            return WOLFSSL_FAILURE;
+        }
+        idx += length;
+
+        /* Add object to the end of the stack. */
+        if (last == NULL) {
+            node->num = 1;
+            *chain = node;
+        }
+        else {
+            (*chain)->num++;
+            last->next = node;
+        }
+
+        last = node;
+    }
+
+    ctx->x509Chain = *chain;
+
+    return WOLFSSL_SUCCESS;
+}
+
+int wolfSSL_CTX_set_tlsext_status_cb(WOLFSSL_CTX* ctx,
+    int(*cb)(WOLFSSL*, void*))
+{
+    if (ctx == NULL || ctx->cm == NULL)
+        return WOLFSSL_FAILURE;
+
+#if !defined(NO_WOLFSSL_SERVER) && (defined(HAVE_CERTIFICATE_STATUS_REQUEST) \
+                               ||  defined(HAVE_CERTIFICATE_STATUS_REQUEST_V2))
+    /* Ensure stapling is on for callback to be used. */
+    wolfSSL_CTX_EnableOCSPStapling(ctx);
+
+    if (ctx->cm->ocsp_stapling == NULL)
+        return WOLFSSL_FAILURE;
+
+    ctx->cm->ocsp_stapling->statusCb = cb;
+#else
+    (void)cb;
+#endif
+
+    return WOLFSSL_SUCCESS;
+}
+
+int wolfSSL_X509_STORE_CTX_get1_issuer(WOLFSSL_X509 **issuer,
+    WOLFSSL_X509_STORE_CTX *ctx, WOLFSSL_X509 *x)
+{
+    WOLFSSL_STACK* node;
+    Signer* ca = NULL;
+#ifdef WOLFSSL_SMALL_STACK
+    DecodedCert* cert = NULL;
+#else
+    DecodedCert  cert[1];
+#endif
+
+    if (issuer == NULL || ctx == NULL || x == NULL)
+        return WOLFSSL_FATAL_ERROR;
+
+    if (ctx->chain != NULL) {
+        for (node = ctx->chain; node != NULL; node = node->next) {
+            if (wolfSSL_X509_check_issued(node->data.x509, x) == X509_V_OK) {
+                *issuer = x;
+                return WOLFSSL_SUCCESS;
+            }
+        }
+    }
+
+
+#ifdef WOLFSSL_SMALL_STACK
+    cert = (DecodedCert*)XMALLOC(sizeof(DecodedCert), NULL, DYNAMIC_TYPE_DCERT);
+    if (cert == NULL)
+        return WOLFSSL_FAILURE;
+#endif
+
+    /* Use existing CA retrieval APIs that use DecodedCert. */
+    InitDecodedCert(cert, x->derCert->buffer, x->derCert->length, NULL);
+    if (ParseCertRelative(cert, CERT_TYPE, 0, NULL) == 0) {
+    #ifndef NO_SKID
+        if (cert->extAuthKeyIdSet)
+            ca = GetCA(ctx->store->cm, cert->extAuthKeyId);
+        if (ca == NULL)
+            ca = GetCAByName(ctx->store->cm, cert->issuerHash);
+    #else /* NO_SKID */
+        ca = GetCA(ctx->store->cm, cert->issuerHash);
+    #endif /* NO SKID */
+    }
+    FreeDecodedCert(cert);
+#ifdef WOLFSSL_SMALL_STACK
+    XFREE(cert, NULL, DYNAMIC_TYPE_DCERT);
+#endif
+
+    if (ca == NULL)
+        return WOLFSSL_FAILURE;
+
+#ifdef WOLFSSL_SIGNER_DER_CERT
+    /* populate issuer with Signer DER */
+    *issuer = wolfSSL_X509_d2i(issuer, ca->derCert->buffer,
+                               ca->derCert->length);
+    if (*issuer == NULL)
+        return WOLFSSL_FAILURE;
+#else
+    /* Create an empty certificate as CA doesn't have a certificate. */
+    *issuer = (WOLFSSL_X509 *)XMALLOC(sizeof(WOLFSSL_X509), 0,
+        DYNAMIC_TYPE_OPENSSL);
+    if (*issuer == NULL)
+        return WOLFSSL_FAILURE;
+
+    InitX509((*issuer), 1, NULL);
+#endif
+
+    /* Result is ignored when passed to wolfSSL_OCSP_cert_to_id(). */
+
+    return WOLFSSL_SUCCESS;
+}
+
+void wolfSSL_X509_email_free(WOLF_STACK_OF(WOLFSSL_STRING) *sk)
+{
+    WOLFSSL_STACK *curr;
+
+    while (sk != NULL) {
+        curr = sk;
+        sk = sk->next;
+
+        XFREE(curr, NULL, DYNAMIC_TYPE_OPENSSL);
+    }
+}
+
+WOLF_STACK_OF(WOLFSSL_STRING) *wolfSSL_X509_get1_ocsp(WOLFSSL_X509 *x)
+{
+    WOLFSSL_STACK* list = NULL;
+    char*          url;
+
+    if (x->authInfoSz == 0)
+        return NULL;
+
+    list = (WOLFSSL_STACK*)XMALLOC(sizeof(WOLFSSL_STACK) + x->authInfoSz + 1,
+                                   NULL, DYNAMIC_TYPE_OPENSSL);
+    if (list == NULL)
+        return NULL;
+
+    url = (char*)list;
+    url += sizeof(WOLFSSL_STACK);
+    XMEMCPY(url, x->authInfo, x->authInfoSz);
+    url[x->authInfoSz] = '\0';
+
+    list->data.string = url;
+    list->next = NULL;
+
+    return list;
+}
+
+int wolfSSL_X509_check_issued(WOLFSSL_X509 *issuer, WOLFSSL_X509 *subject)
+{
+    WOLFSSL_X509_NAME *issuerName = wolfSSL_X509_get_issuer_name(subject);
+    WOLFSSL_X509_NAME *subjectName = wolfSSL_X509_get_subject_name(issuer);
+
+    if (issuerName == NULL || subjectName == NULL)
+        return X509_V_ERR_SUBJECT_ISSUER_MISMATCH;
+
+    /* Literal matching of encoded names and key ids. */
+    if (issuerName->sz != subjectName->sz ||
+           XMEMCMP(issuerName->name, subjectName->name, subjectName->sz) != 0) {
+        return X509_V_ERR_SUBJECT_ISSUER_MISMATCH;
+    }
+
+    if (subject->authKeyId != NULL && issuer->subjKeyId != NULL) {
+        if (subject->authKeyIdSz != issuer->subjKeyIdSz ||
+                XMEMCMP(subject->authKeyId, issuer->subjKeyId,
+                        issuer->subjKeyIdSz) != 0) {
+            return X509_V_ERR_SUBJECT_ISSUER_MISMATCH;
+        }
+    }
+
+    return X509_V_OK;
+}
+
+WOLFSSL_X509* wolfSSL_X509_dup(WOLFSSL_X509 *x)
+{
+    return wolfSSL_X509_d2i(NULL, x->derCert->buffer, x->derCert->length);
+}
+
+char* wolfSSL_sk_WOLFSSL_STRING_value(WOLF_STACK_OF(WOLFSSL_STRING)* strings,
+    int idx)
+{
+    for (; idx > 0 && strings != NULL; idx--)
+        strings = strings->next;
+    if (strings == NULL)
+        return NULL;
+    return strings->data.string;
+}
+#endif /* WOLFSSL_NGINX || WOLFSSL_HAPROXY || OPENSSL_EXTRA || OPENSSL_ALL */
+
+#if defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY)
+#ifdef HAVE_ALPN
+void wolfSSL_get0_alpn_selected(const WOLFSSL *ssl, const unsigned char **data,
+                                unsigned int *len)
+{
+    word16 nameLen;
+
+    if (ssl != NULL && data != NULL && len != NULL) {
+        TLSX_ALPN_GetRequest(ssl->extensions, (void **)data, &nameLen);
+        *len = nameLen;
+    }
+}
+
+int wolfSSL_select_next_proto(unsigned char **out, unsigned char *outLen,
+                              const unsigned char *in, unsigned int inLen,
+                              const unsigned char *clientNames,
+                              unsigned int clientLen)
+{
+    unsigned int i, j;
+    byte lenIn, lenClient;
+
+    if (out == NULL || outLen == NULL || in == NULL || clientNames == NULL)
+        return OPENSSL_NPN_UNSUPPORTED;
+
+    for (i = 0; i < inLen; i += lenIn) {
+        lenIn = in[i++];
+        for (j = 0; j < clientLen; j += lenClient) {
+            lenClient = clientNames[j++];
+
+            if (lenIn != lenClient)
+                continue;
+
+            if (XMEMCMP(in + i, clientNames + j, lenIn) == 0) {
+                *out = (unsigned char *)(in + i);
+                *outLen = lenIn;
+                return OPENSSL_NPN_NEGOTIATED;
+            }
+        }
+    }
+
+    *out = (unsigned char *)clientNames + 1;
+    *outLen = clientNames[0];
+    return OPENSSL_NPN_NO_OVERLAP;
+}
+
+void wolfSSL_CTX_set_alpn_select_cb(WOLFSSL_CTX *ctx,
+                                    int (*cb) (WOLFSSL *ssl,
+                                               const unsigned char **out,
+                                               unsigned char *outlen,
+                                               const unsigned char *in,
+                                               unsigned int inlen,
+                                               void *arg), void *arg)
+{
+    if (ctx != NULL) {
+        ctx->alpnSelect = cb;
+        ctx->alpnSelectArg = arg;
+    }
+}
+
+void wolfSSL_CTX_set_next_protos_advertised_cb(WOLFSSL_CTX *s,
+                                           int (*cb) (WOLFSSL *ssl,
+                                                      const unsigned char
+                                                      **out,
+                                                      unsigned int *outlen,
+                                                      void *arg), void *arg)
+{
+    (void)s;
+    (void)cb;
+    (void)arg;
+    WOLFSSL_STUB("wolfSSL_CTX_set_next_protos_advertised_cb");
+}
+
+void wolfSSL_CTX_set_next_proto_select_cb(WOLFSSL_CTX *s,
+                                      int (*cb) (WOLFSSL *ssl,
+                                                 unsigned char **out,
+                                                 unsigned char *outlen,
+                                                 const unsigned char *in,
+                                                 unsigned int inlen,
+                                                 void *arg), void *arg)
+{
+    (void)s;
+    (void)cb;
+    (void)arg;
+    WOLFSSL_STUB("wolfSSL_CTX_set_next_proto_select_cb");
+}
+
+void wolfSSL_get0_next_proto_negotiated(const WOLFSSL *s, const unsigned char **data,
+                                    unsigned *len)
+{
+    (void)s;
+    (void)data;
+    (void)len;
+    WOLFSSL_STUB("wolfSSL_get0_next_proto_negotiated");
+}
+#endif /* HAVE_ALPN */
+
+#endif /* WOLFSSL_NGINX  / WOLFSSL_HAPROXY */
+
+#if defined(OPENSSL_EXTRA) && defined(HAVE_ECC)
+int wolfSSL_CTX_set1_curves_list(WOLFSSL_CTX* ctx, const char* names)
+{
+    int idx, start = 0, len;
+    word16 curve;
+    char name[MAX_CURVE_NAME_SZ];
+
+    /* Disable all curves so that only the ones the user wants are enabled. */
+    ctx->disabledCurves = 0xFFFFFFFFUL;
+    for (idx = 1; names[idx-1] != '\0'; idx++) {
+        if (names[idx] != ':' && names[idx] != '\0')
+            continue;
+
+        len = idx - 1 - start;
+        if (len > MAX_CURVE_NAME_SZ - 1)
+            return WOLFSSL_FAILURE;
+
+        XMEMCPY(name, names + start, len);
+        name[len] = 0;
+
+        if ((XSTRNCMP(name, "prime256v1", len) == 0) ||
+                                      (XSTRNCMP(name, "secp256r1", len) == 0) ||
+                                      (XSTRNCMP(name, "P-256", len) == 0)) {
+            curve = WOLFSSL_ECC_SECP256R1;
+        }
+        else if ((XSTRNCMP(name, "secp384r1", len) == 0) ||
+                                          (XSTRNCMP(name, "P-384", len) == 0)) {
+            curve = WOLFSSL_ECC_SECP384R1;
+        }
+        else if ((XSTRNCMP(name, "secp521r1", len) == 0) ||
+                                          (XSTRNCMP(name, "P-521", len) == 0)) {
+            curve = WOLFSSL_ECC_SECP521R1;
+        }
+        else if (XSTRNCMP(name, "X25519", len) == 0) {
+            curve = WOLFSSL_ECC_X25519;
+        }
+        else if (XSTRNCMP(name, "X448", len) == 0) {
+            curve = WOLFSSL_ECC_X448;
+        }
+        else {
+        #if !defined(HAVE_FIPS) && !defined(HAVE_SELFTEST)
+            int   ret;
+            const ecc_set_type *eccSet;
+
+            ret = wc_ecc_get_curve_idx_from_name(name);
+            if (ret < 0) {
+                WOLFSSL_MSG("Could not find name in set");
+                return WOLFSSL_FAILURE;
+            }
+
+            eccSet = wc_ecc_get_curve_params(ret);
+            if (eccSet == NULL) {
+                WOLFSSL_MSG("NULL set returned");
+                return WOLFSSL_FAILURE;
+            }
+
+            curve = GetCurveByOID(eccSet->oidSum);
+        #else
+            WOLFSSL_MSG("API not present to search farther using name");
+            return WOLFSSL_FAILURE;
+        #endif
+        }
+
+        if (curve > (sizeof(word32) * WOLFSSL_BIT_SIZE)) {
+            /* shift left more than size of ctx->disabledCurves causes static
+             * analysis report */
+            WOLFSSL_MSG("curve value is too large for upcoming shift");
+            return WOLFSSL_FAILURE;
+        }
+
+    #if defined(HAVE_SUPPORTED_CURVES) && !defined(NO_WOLFSSL_CLIENT)
+        /* set the supported curve so client TLS extension contains only the
+         * desired curves */
+        if (wolfSSL_CTX_UseSupportedCurve(ctx, curve) != WOLFSSL_SUCCESS) {
+            WOLFSSL_MSG("Unable to set supported curve");
+            return WOLFSSL_FAILURE;
+        }
+    #endif
+
+        /* Switch the bit to off and therefore is enabled. */
+        ctx->disabledCurves &= ~(1U << curve);
+        start = idx + 1;
+    }
+
+    return WOLFSSL_SUCCESS;
+}
+
+int wolfSSL_set1_curves_list(WOLFSSL* ssl, const char* names)
+{
+    if (ssl == NULL) {
+        return WOLFSSL_FAILURE;
+    }
+    return wolfSSL_CTX_set1_curves_list(ssl->ctx, names);
+}
+#endif /* OPENSSL_EXTRA && HAVE_ECC */
+
+#ifdef OPENSSL_EXTRA
+#ifndef NO_WOLFSSL_STUB
+int wolfSSL_CTX_set_msg_callback(WOLFSSL_CTX *ctx, SSL_Msg_Cb cb)
+{
+    WOLFSSL_STUB("SSL_CTX_set_msg_callback");
+    (void)ctx;
+    (void)cb;
+    return WOLFSSL_FAILURE;
+}
+#endif
+
+
+/* Sets a callback for when sending and receiving protocol messages.
+ *
+ * ssl WOLFSSL structure to set callback in
+ * cb  callback to use
+ *
+ * return SSL_SUCCESS on success and SSL_FAILURE with error case
+ */
+int wolfSSL_set_msg_callback(WOLFSSL *ssl, SSL_Msg_Cb cb)
+{
+    WOLFSSL_ENTER("wolfSSL_set_msg_callback");
+
+    if (ssl == NULL) {
+        return SSL_FAILURE;
+    }
+
+    if (cb != NULL) {
+        ssl->toInfoOn = 1;
+    }
+
+    ssl->protoMsgCb = cb;
+    return SSL_SUCCESS;
+}
+#ifndef NO_WOLFSSL_STUB
+int wolfSSL_CTX_set_msg_callback_arg(WOLFSSL_CTX *ctx, void* arg)
+{
+    WOLFSSL_STUB("SSL_CTX_set_msg_callback_arg");
+    (void)ctx;
+    (void)arg;
+    return WOLFSSL_FAILURE;
+}
+#endif
+
+int wolfSSL_set_msg_callback_arg(WOLFSSL *ssl, void* arg)
+{
+    WOLFSSL_ENTER("wolfSSL_set_msg_callback_arg");
+    if (ssl == NULL)
+        return WOLFSSL_FAILURE;
+
+    ssl->protoMsgCtx = arg;
+    return WOLFSSL_SUCCESS;
+}
+
+void *wolfSSL_OPENSSL_memdup(const void *data, size_t siz, const char* file, int line)
+{
+    void *ret;
+    (void)file;
+    (void)line;
+
+    if (data == NULL || siz >= INT_MAX)
+        return NULL;
+
+    ret = OPENSSL_malloc(siz);
+    if (ret == NULL) {
+        return NULL;
+    }
+    return XMEMCPY(ret, data, siz);
+}
+
+int wolfSSL_CTX_set_alpn_protos(WOLFSSL_CTX *ctx, const unsigned char *p,
+                            unsigned int p_len)
+{
+    WOLFSSL_ENTER("wolfSSL_CTX_set_alpn_protos");
+    if(ctx == NULL)
+        return BAD_FUNC_ARG;
+    if((void *)ctx->alpn_cli_protos != NULL)
+        wolfSSL_OPENSSL_free((void *)ctx->alpn_cli_protos);
+    ctx->alpn_cli_protos =
+        (const unsigned char *)wolfSSL_OPENSSL_memdup(p, p_len, NULL, 0);
+    if (ctx->alpn_cli_protos == NULL) {
+        return SSL_FAILURE;
+    }
+    ctx->alpn_cli_protos_len = p_len;
+
+    return SSL_SUCCESS;
+}
+
+
+#ifdef HAVE_ALPN
+/* Sets the ALPN extension protos
+ *
+ * example format is
+ * unsigned char p[] = {
+ *      8, 'h', 't', 't', 'p', '/', '1', '.', '1'
+ * };
+ *
+ * returns WOLFSSL_SUCCESS on success */
+int wolfSSL_set_alpn_protos(WOLFSSL* ssl,
+        const unsigned char* p, unsigned int p_len)
+{
+    WOLFSSL_BIO* bio;
+    char* pt;
+
+    unsigned int sz;
+    unsigned int idx = 0;
+    int alpn_opt = WOLFSSL_ALPN_CONTINUE_ON_MISMATCH;
+    WOLFSSL_ENTER("wolfSSL_set_alpn_protos");
+
+    if (ssl == NULL || p_len <= 1) {
+        return WOLFSSL_FAILURE;
+    }
+
+    bio = wolfSSL_BIO_new(wolfSSL_BIO_s_mem());
+    if (bio == NULL) {
+        return WOLFSSL_FAILURE;
+    }
+
+    /* convert into comma separated list */
+    while (idx < p_len - 1) {
+        unsigned int i;
+
+        sz = p[idx++];
+        if (idx + sz > p_len) {
+            WOLFSSL_MSG("Bad list format");
+            wolfSSL_BIO_free(bio);
+            return WOLFSSL_FAILURE;
+        }
+        if (sz > 0) {
+            for (i = 0; i < sz; i++) {
+                wolfSSL_BIO_write(bio, &p[idx++], 1);
+            }
+            if (idx < p_len - 1)
+                wolfSSL_BIO_write(bio, ",", 1);
+        }
+    }
+    wolfSSL_BIO_write(bio, "\0", 1);
+
+    /* clears out all current ALPN extensions set */
+    TLSX_Remove(&ssl->extensions, TLSX_APPLICATION_LAYER_PROTOCOL, ssl->heap);
+
+    if ((sz = wolfSSL_BIO_get_mem_data(bio, &pt)) > 0) {
+        wolfSSL_UseALPN(ssl, pt, sz, alpn_opt);
+    }
+    wolfSSL_BIO_free(bio);
+    return WOLFSSL_SUCCESS;
+}
+#endif /* HAVE_ALPN */
+#endif
+
+#endif /* WOLFCRYPT_ONLY */
+
+#if defined(OPENSSL_EXTRA)
+
+#define WOLFSSL_BIO_INCLUDED
+#include "src/bio.c"
+
+int oid2nid(word32 oid, int grp)
+{
+    /* get OID type */
+    switch (grp) {
+        /* oidHashType */
+        case oidHashType:
+            switch (oid) {
+            #ifdef WOLFSSL_MD2
+                case MD2h:
+                    return NID_md2;
+            #endif
+            #ifndef NO_MD5
+                case MD5h:
+                    return NID_md5;
+            #endif
+            #ifndef NO_SHA
+                case SHAh:
+                    return NID_sha1;
+            #endif
+                case SHA224h:
+                    return NID_sha224;
+            #ifndef NO_SHA256
+                case SHA256h:
+                    return NID_sha256;
+            #endif
+            #ifdef WOLFSSL_SHA384
+                case SHA384h:
+                    return NID_sha384;
+            #endif
+            #ifdef WOLFSSL_SHA512
+                case SHA512h:
+                    return NID_sha512;
+            #endif
+            }
+            break;
+
+        /*  oidSigType */
+        case oidSigType:
+            switch (oid) {
+            #ifndef NO_DSA
+                case CTC_SHAwDSA:
+                    return CTC_SHAwDSA;
+            #endif /* NO_DSA */
+            #ifndef NO_RSA
+                case CTC_MD2wRSA:
+                    return CTC_MD2wRSA;
+                case CTC_MD5wRSA:
+                    return CTC_MD5wRSA;
+                case CTC_SHAwRSA:
+                    return CTC_SHAwRSA;
+                case CTC_SHA224wRSA:
+                    return CTC_SHA224wRSA;
+                case CTC_SHA256wRSA:
+                    return CTC_SHA256wRSA;
+                case CTC_SHA384wRSA:
+                    return CTC_SHA384wRSA;
+                case CTC_SHA512wRSA:
+                    return CTC_SHA512wRSA;
+            #endif /* NO_RSA */
+            #ifdef HAVE_ECC
+                case CTC_SHAwECDSA:
+                    return CTC_SHAwECDSA;
+                case CTC_SHA224wECDSA:
+                    return CTC_SHA224wECDSA;
+                case CTC_SHA256wECDSA:
+                    return CTC_SHA256wECDSA;
+                case CTC_SHA384wECDSA:
+                    return CTC_SHA384wECDSA;
+                case CTC_SHA512wECDSA:
+                    return CTC_SHA512wECDSA;
+            #endif /* HAVE_ECC */
+            }
+            break;
+
+        /* oidKeyType */
+        case oidKeyType:
+            switch (oid) {
+            #ifndef NO_DSA
+                case DSAk:
+                    return DSAk;
+            #endif /* NO_DSA */
+            #ifndef NO_RSA
+                case RSAk:
+                    return RSAk;
+            #endif /* NO_RSA */
+            #ifdef HAVE_NTRU
+                case NTRUk:
+                    return NTRUk;
+            #endif /* HAVE_NTRU */
+            #ifdef HAVE_ECC
+                case ECDSAk:
+                    return ECDSAk;
+            #endif /* HAVE_ECC */
+            }
+            break;
+
+
+    #ifdef HAVE_ECC
+        case oidCurveType:
+            switch (oid) {
+            case ECC_SECP192R1_OID:
+                return NID_X9_62_prime192v1;
+            case ECC_PRIME192V2_OID:
+                return NID_X9_62_prime192v2;
+            case ECC_PRIME192V3_OID:
+                return NID_X9_62_prime192v3;
+            case ECC_PRIME239V1_OID:
+                return NID_X9_62_prime239v1;
+            case ECC_PRIME239V2_OID:
+                return NID_X9_62_prime239v2;
+            case ECC_PRIME239V3_OID:
+                return NID_X9_62_prime239v3;
+            case ECC_SECP256R1_OID:
+                return NID_X9_62_prime256v1;
+            case ECC_SECP112R1_OID:
+                return NID_secp112r1;
+            case ECC_SECP112R2_OID:
+                return NID_secp112r2;
+            case ECC_SECP128R1_OID:
+                return NID_secp128r1;
+            case ECC_SECP128R2_OID:
+                return NID_secp128r2;
+            case ECC_SECP160R1_OID:
+                return NID_secp160r1;
+            case ECC_SECP160R2_OID:
+                return NID_secp160r2;
+            case ECC_SECP224R1_OID:
+                return NID_secp224r1;
+            case ECC_SECP384R1_OID:
+                return NID_secp384r1;
+            case ECC_SECP521R1_OID:
+                return NID_secp521r1;
+            case ECC_SECP160K1_OID:
+                return NID_secp160k1;
+            case ECC_SECP192K1_OID:
+                return NID_secp192k1;
+            case ECC_SECP224K1_OID:
+                return NID_secp224k1;
+            case ECC_SECP256K1_OID:
+                return NID_secp256k1;
+            case ECC_BRAINPOOLP160R1_OID:
+                return NID_brainpoolP160r1;
+            case ECC_BRAINPOOLP192R1_OID:
+                return NID_brainpoolP192r1;
+            case ECC_BRAINPOOLP224R1_OID:
+                return NID_brainpoolP224r1;
+            case ECC_BRAINPOOLP256R1_OID:
+                return NID_brainpoolP256r1;
+            case ECC_BRAINPOOLP320R1_OID:
+                return NID_brainpoolP320r1;
+            case ECC_BRAINPOOLP384R1_OID:
+                return NID_brainpoolP384r1;
+            case ECC_BRAINPOOLP512R1_OID:
+                return NID_brainpoolP512r1;
+            }
+            break;
+    #endif /* HAVE_ECC */
+
+        /* oidBlkType */
+        case oidBlkType:
+            switch (oid) {
+            #ifdef WOLFSSL_AES_128
+                case AES128CBCb:
+                    return AES128CBCb;
+            #endif
+            #ifdef WOLFSSL_AES_192
+                case AES192CBCb:
+                    return AES192CBCb;
+            #endif
+            #ifdef WOLFSSL_AES_256
+                case AES256CBCb:
+                    return AES256CBCb;
+            #endif
+            #ifndef NO_DES3
+                case DESb:
+                    return NID_des;
+                case DES3b:
+                    return NID_des3;
+            #endif
+            }
+            break;
+
+    #ifdef HAVE_OCSP
+        case oidOcspType:
+            switch (oid) {
+                case OCSP_BASIC_OID:
+                    return NID_id_pkix_OCSP_basic;
+                case OCSP_NONCE_OID:
+                    return OCSP_NONCE_OID;
+            }
+            break;
+    #endif /* HAVE_OCSP */
+
+        /* oidCertExtType */
+        case oidCertExtType:
+            switch (oid) {
+                case BASIC_CA_OID:
+                    return BASIC_CA_OID;
+                case ALT_NAMES_OID:
+                    return ALT_NAMES_OID;
+                case CRL_DIST_OID:
+                    return CRL_DIST_OID;
+                case AUTH_INFO_OID:
+                    return AUTH_INFO_OID;
+                case AUTH_KEY_OID:
+                    return AUTH_KEY_OID;
+                case SUBJ_KEY_OID:
+                    return SUBJ_KEY_OID;
+                case INHIBIT_ANY_OID:
+                    return INHIBIT_ANY_OID;
+                case KEY_USAGE_OID:
+                    return NID_key_usage;
+                case NAME_CONS_OID:
+                    return NID_name_constraints;
+                case CERT_POLICY_OID:
+                    return NID_certificate_policies;
+            }
+            break;
+
+        /* oidCertAuthInfoType */
+        case oidCertAuthInfoType:
+            switch (oid) {
+                case AIA_OCSP_OID:
+                    return AIA_OCSP_OID;
+                case AIA_CA_ISSUER_OID:
+                    return AIA_CA_ISSUER_OID;
+            }
+            break;
+
+        /* oidCertPolicyType */
+        case oidCertPolicyType:
+            switch (oid) {
+                case CP_ANY_OID:
+                    return NID_any_policy;
+            }
+            break;
+
+        /* oidCertAltNameType */
+        case oidCertAltNameType:
+            switch (oid) {
+                case HW_NAME_OID:
+                    return NID_hw_name_oid;
+            }
+            break;
+
+        /* oidCertKeyUseType */
+        case oidCertKeyUseType:
+            switch (oid) {
+                case EKU_ANY_OID:
+                    return NID_anyExtendedKeyUsage;
+                case EKU_SERVER_AUTH_OID:
+                    return EKU_SERVER_AUTH_OID;
+                case EKU_CLIENT_AUTH_OID:
+                    return EKU_CLIENT_AUTH_OID;
+                case EKU_OCSP_SIGN_OID:
+                    return EKU_OCSP_SIGN_OID;
+            }
+            break;
+
+        /* oidKdfType */
+        case oidKdfType:
+            switch (oid) {
+                case PBKDF2_OID:
+                    return PBKDF2_OID;
+            }
+            break;
+
+        /* oidPBEType */
+        case oidPBEType:
+            switch (oid) {
+                case PBE_SHA1_RC4_128:
+                    return PBE_SHA1_RC4_128;
+                case PBE_SHA1_DES:
+                    return PBE_SHA1_DES;
+                case PBE_SHA1_DES3:
+                    return PBE_SHA1_DES3;
+            }
+            break;
+
+        /* oidKeyWrapType */
+        case oidKeyWrapType:
+            switch (oid) {
+            #ifdef WOLFSSL_AES_128
+                case AES128_WRAP:
+                    return AES128_WRAP;
+            #endif
+            #ifdef WOLFSSL_AES_192
+                case AES192_WRAP:
+                    return AES192_WRAP;
+            #endif
+            #ifdef WOLFSSL_AES_256
+                case AES256_WRAP:
+                    return AES256_WRAP;
+            #endif
+            }
+            break;
+
+        /* oidCmsKeyAgreeType */
+        case oidCmsKeyAgreeType:
+            switch (oid) {
+                #ifndef NO_SHA
+                case dhSinglePass_stdDH_sha1kdf_scheme:
+                    return dhSinglePass_stdDH_sha1kdf_scheme;
+                #endif
+                #ifdef WOLFSSL_SHA224
+                case dhSinglePass_stdDH_sha224kdf_scheme:
+                    return dhSinglePass_stdDH_sha224kdf_scheme;
+                #endif
+                #ifndef NO_SHA256
+                case dhSinglePass_stdDH_sha256kdf_scheme:
+                    return dhSinglePass_stdDH_sha256kdf_scheme;
+                #endif
+                #ifdef WOLFSSL_SHA384
+                case dhSinglePass_stdDH_sha384kdf_scheme:
+                    return dhSinglePass_stdDH_sha384kdf_scheme;
+                #endif
+                #ifdef WOLFSSL_SHA512
+                case dhSinglePass_stdDH_sha512kdf_scheme:
+                    return dhSinglePass_stdDH_sha512kdf_scheme;
+                #endif
+            }
+            break;
+
+        default:
+            WOLFSSL_MSG("NID not in table");
+            return -1;
+    }
+
+    return -1;
+}
+
+
+/* when calling SetIndividualInternal, mpi should be cleared by caller if no
+ * longer used. ie mp_free(mpi). This is to free data when fastmath is
+ * disabled since a copy of mpi is made by this function and placed into bn.
+ */
+int SetIndividualInternal(WOLFSSL_BIGNUM* bn, mp_int* mpi)
+{
+    WOLFSSL_MSG("Entering SetIndividualInternal");
+
+    if (bn == NULL || bn->internal == NULL) {
+        WOLFSSL_MSG("bn NULL error");
+        return WOLFSSL_FATAL_ERROR;
+    }
+
+    if (mpi == NULL || (mp_init(mpi) != MP_OKAY)) {
+        WOLFSSL_MSG("mpi NULL error");
+        return WOLFSSL_FATAL_ERROR;
+    }
+
+    if (mp_copy((mp_int*)bn->internal, mpi) != MP_OKAY) {
+        WOLFSSL_MSG("mp_copy error");
+        return WOLFSSL_FATAL_ERROR;
+    }
+
+    return WOLFSSL_SUCCESS;
+}
+
+
+#ifndef NO_ASN
+WOLFSSL_BIGNUM *wolfSSL_ASN1_INTEGER_to_BN(const WOLFSSL_ASN1_INTEGER *ai,
+                                       WOLFSSL_BIGNUM *bn)
+{
+    mp_int mpi;
+    word32 idx = 0;
+    int ret;
+
+    WOLFSSL_ENTER("wolfSSL_ASN1_INTEGER_to_BN");
+
+    if (ai == NULL) {
+        return NULL;
+    }
+
+    ret = GetInt(&mpi, ai->data, &idx, ai->dataMax);
+    if (ret != 0) {
+    #ifdef WOLFSSL_QT
+        mp_init(&mpi); /* must init mpi */
+        /* Serial number in QT starts at index 0 of data */
+        if (mp_read_unsigned_bin(&mpi, (byte*)ai->data, ai->length) != 0) {
+                mp_clear(&mpi);
+                return NULL;
+            }
+    #else
+        /* expecting ASN1 format for INTEGER */
+        WOLFSSL_LEAVE("wolfSSL_ASN1_INTEGER_to_BN", ret);
+        return NULL;
+    #endif
+    }
+
+    /* mp_clear needs called because mpi is copied and causes memory leak with
+     * --disable-fastmath */
+    ret = SetIndividualExternal(&bn, &mpi);
+    mp_clear(&mpi);
+
+    if (ret != WOLFSSL_SUCCESS) {
+        return NULL;
+    }
+    return bn;
+}
+#endif /* !NO_ASN */
+
+#if !defined(NO_DSA) && !defined(NO_DH)
+WOLFSSL_DH *wolfSSL_DSA_dup_DH(const WOLFSSL_DSA *dsa)
+{
+    WOLFSSL_DH* dh;
+    DhKey*      key;
+
+    WOLFSSL_ENTER("wolfSSL_DSA_dup_DH");
+
+    if (dsa == NULL) {
+        return NULL;
+    }
+
+    dh = wolfSSL_DH_new();
+    if (dh == NULL) {
+        return NULL;
+    }
+    key = (DhKey*)dh->internal;
+
+    if (dsa->p != NULL &&
+        SetIndividualInternal(((WOLFSSL_DSA*)dsa)->p, &key->p) != WOLFSSL_SUCCESS) {
+        WOLFSSL_MSG("rsa p key error");
+        wolfSSL_DH_free(dh);
+        return NULL;
+    }
+    if (dsa->g != NULL &&
+        SetIndividualInternal(((WOLFSSL_DSA*)dsa)->g, &key->g) != WOLFSSL_SUCCESS) {
+        WOLFSSL_MSG("rsa g key error");
+        wolfSSL_DH_free(dh);
+        return NULL;
+    }
+
+    if (SetIndividualExternal(&dh->p, &key->p) != WOLFSSL_SUCCESS) {
+        WOLFSSL_MSG("dsa p key error");
+        wolfSSL_DH_free(dh);
+        return NULL;
+    }
+    if (SetIndividualExternal(&dh->g, &key->g) != WOLFSSL_SUCCESS) {
+        WOLFSSL_MSG("dsa g key error");
+        wolfSSL_DH_free(dh);
+        return NULL;
+    }
+
+    return dh;
+}
+#endif /* !NO_DSA && !NO_DH */
+
+
+#ifndef NO_RSA
+#if !defined(HAVE_USER_RSA) && !defined(HAVE_FAST_RSA)
+/* Openssl -> WolfSSL */
+int SetRsaInternal(WOLFSSL_RSA* rsa)
+{
+    RsaKey* key;
+    WOLFSSL_MSG("Entering SetRsaInternal");
+
+    if (rsa == NULL || rsa->internal == NULL) {
+        WOLFSSL_MSG("rsa key NULL error");
+        return WOLFSSL_FATAL_ERROR;
+    }
+
+    key = (RsaKey*)rsa->internal;
+
+    if (SetIndividualInternal(rsa->n, &key->n) != WOLFSSL_SUCCESS) {
+        WOLFSSL_MSG("rsa n key error");
+        return WOLFSSL_FATAL_ERROR;
+    }
+
+    if (SetIndividualInternal(rsa->e, &key->e) != WOLFSSL_SUCCESS) {
+        WOLFSSL_MSG("rsa e key error");
+        return WOLFSSL_FATAL_ERROR;
+    }
+
+    /* public key */
+    key->type = RSA_PUBLIC;
+
+    if (rsa->d != NULL) {
+        if (SetIndividualInternal(rsa->d, &key->d) != WOLFSSL_SUCCESS) {
+            WOLFSSL_MSG("rsa d key error");
+            return WOLFSSL_FATAL_ERROR;
+        }
+
+        /* private key */
+        key->type = RSA_PRIVATE;
+    }
+
+    if (rsa->p != NULL &&
+        SetIndividualInternal(rsa->p, &key->p) != WOLFSSL_SUCCESS) {
+        WOLFSSL_MSG("rsa p key error");
+        return WOLFSSL_FATAL_ERROR;
+    }
+
+    if (rsa->q != NULL &&
+        SetIndividualInternal(rsa->q, &key->q) != WOLFSSL_SUCCESS) {
+        WOLFSSL_MSG("rsa q key error");
+        return WOLFSSL_FATAL_ERROR;
+    }
+
+#ifndef RSA_LOW_MEM
+    if (rsa->dmp1 != NULL &&
+        SetIndividualInternal(rsa->dmp1, &key->dP) != WOLFSSL_SUCCESS) {
+        WOLFSSL_MSG("rsa dP key error");
+        return WOLFSSL_FATAL_ERROR;
+    }
+
+    if (rsa->dmq1 != NULL &&
+        SetIndividualInternal(rsa->dmq1, &key->dQ) != WOLFSSL_SUCCESS) {
+        WOLFSSL_MSG("rsa dQ key error");
+        return WOLFSSL_FATAL_ERROR;
+    }
+
+    if (rsa->iqmp != NULL &&
+        SetIndividualInternal(rsa->iqmp, &key->u) != WOLFSSL_SUCCESS) {
+        WOLFSSL_MSG("rsa u key error");
+        return WOLFSSL_FATAL_ERROR;
+    }
+#endif /* !RSA_LOW_MEM */
+
+    rsa->inSet = 1;
+
+    return WOLFSSL_SUCCESS;
+}
+
+
+/* SSL_SUCCESS on ok */
+#ifndef NO_WOLFSSL_STUB
+int wolfSSL_RSA_blinding_on(WOLFSSL_RSA* rsa, WOLFSSL_BN_CTX* bn)
+{
+    (void)rsa;
+    (void)bn;
+    WOLFSSL_STUB("RSA_blinding_on");
+    WOLFSSL_MSG("wolfSSL_RSA_blinding_on");
+
+    return WOLFSSL_SUCCESS;  /* on by default */
+}
+#endif
+
+/* return compliant with OpenSSL
+ *   size of encrypted data if success , -1 if error
+ */
+int wolfSSL_RSA_public_encrypt(int len, const unsigned char* fr,
+                            unsigned char* to, WOLFSSL_RSA* rsa, int padding)
+{
+    int initTmpRng = 0;
+    WC_RNG *rng = NULL;
+    int outLen;
+    int ret = 0;
+#ifdef WOLFSSL_SMALL_STACK
+    WC_RNG* tmpRNG = NULL;
+#else
+    WC_RNG  _tmpRNG[1];
+    WC_RNG* tmpRNG = _tmpRNG;
+#endif
+#if !defined(HAVE_FIPS) && !defined(HAVE_USER_RSA) && !defined(HAVE_FAST_RSA)
+    int  mgf = WC_MGF1NONE;
+    enum wc_HashType hash = WC_HASH_TYPE_NONE;
+#endif
+
+    WOLFSSL_MSG("wolfSSL_RSA_public_encrypt");
+
+    /* Check and remap the padding to internal values, if needed. */
+#if !defined(HAVE_FIPS) && !defined(HAVE_USER_RSA) && !defined(HAVE_FAST_RSA)
+    if (padding == RSA_PKCS1_PADDING)
+        padding = WC_RSA_PKCSV15_PAD;
+    else if (padding == RSA_PKCS1_OAEP_PADDING) {
+        padding = WC_RSA_OAEP_PAD;
+        hash = WC_HASH_TYPE_SHA;
+        mgf = WC_MGF1SHA1;
+    }
+    else if (padding == RSA_PKCS1_PSS_PADDING) {
+        padding = WC_RSA_PSS_PAD;
+        hash = WC_HASH_TYPE_SHA256;
+        mgf  = WC_MGF1SHA256;
+    }
+    else if (padding == RSA_NO_PADDING) {
+        padding = WC_RSA_NO_PAD;
+    }
+#else
+    if (padding == RSA_PKCS1_PADDING)
+      ;
+#endif
+    else {
+        WOLFSSL_MSG("wolfSSL_RSA_public_encrypt unsupported padding");
+        return 0;
+    }
+
+    if (rsa->inSet == 0)
+    {
+        if (SetRsaInternal(rsa) != SSL_SUCCESS) {
+            WOLFSSL_MSG("SetRsaInternal failed");
+            return 0;
+        }
+    }
+
+    outLen = wolfSSL_RSA_size(rsa);
+
+    rng = WOLFSSL_RSA_GetRNG(rsa, (WC_RNG**)&tmpRNG, &initTmpRng);
+
+    if (outLen == 0) {
+        WOLFSSL_MSG("Bad RSA size");
+    }
+
+    if (rng) {
+#if !defined(HAVE_FIPS) && !defined(HAVE_USER_RSA) && !defined(HAVE_FAST_RSA)
+        ret = wc_RsaPublicEncrypt_ex(fr, len, to, outLen,
+                             (RsaKey*)rsa->internal, rng, padding,
+                             hash, mgf, NULL, 0);
+#else
+        ret = wc_RsaPublicEncrypt(fr, len, to, outLen,
+                             (RsaKey*)rsa->internal, rng);
+#endif
+        if (ret <= 0) {
+            WOLFSSL_MSG("Bad Rsa Encrypt");
+        }
+        if (len <= 0) {
+            WOLFSSL_MSG("Bad Rsa Encrypt");
+        }
+    }
+
+    if (initTmpRng)
+        wc_FreeRng(tmpRNG);
+#ifdef WOLFSSL_SMALL_STACK
+    if (tmpRNG)
+        XFREE(tmpRNG, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+#endif
+
+    if (ret >= 0)
+        WOLFSSL_MSG("wolfSSL_RSA_public_encrypt success");
+    else {
+        WOLFSSL_MSG("wolfSSL_RSA_public_encrypt failed");
+        ret = WOLFSSL_FATAL_ERROR; /* return -1 on error case */
+    }
+    return ret;
+}
+
+
+
+
+/* return compliant with OpenSSL
+ *   size of plain recovered data if success , -1 if error
+ */
+int wolfSSL_RSA_private_decrypt(int len, const unsigned char* fr,
+                            unsigned char* to, WOLFSSL_RSA* rsa, int padding)
+{
+    int outLen;
+    int ret = 0;
+  #if !defined(HAVE_FIPS) && !defined(HAVE_USER_RSA) && !defined(HAVE_FAST_RSA)
+    int mgf = WC_MGF1NONE;
+    enum wc_HashType hash = WC_HASH_TYPE_NONE;
+  #endif
+
+    WOLFSSL_MSG("wolfSSL_RSA_private_decrypt");
+
+#if !defined(HAVE_FIPS) && !defined(HAVE_USER_RSA) && !defined(HAVE_FAST_RSA)
+    if (padding == RSA_PKCS1_PADDING)
+        padding = WC_RSA_PKCSV15_PAD;
+    else if (padding == RSA_PKCS1_OAEP_PADDING) {
+        padding = WC_RSA_OAEP_PAD;
+        hash = WC_HASH_TYPE_SHA;
+        mgf = WC_MGF1SHA1;
+    }
+    else if (padding == RSA_PKCS1_PSS_PADDING) {
+        padding = WC_RSA_PSS_PAD;
+        hash = WC_HASH_TYPE_SHA256;
+        mgf  = WC_MGF1SHA256;
+    }
+    else if (padding == RSA_NO_PADDING) {
+        padding = WC_RSA_NO_PAD;
+    }
+#else
+    if (padding == RSA_PKCS1_PADDING)
+        ;
+#endif
+    else {
+        WOLFSSL_MSG("wolfSSL_RSA_private_decrypt unsupported padding");
+        return 0;
+    }
+
+    if (rsa->inSet == 0)
+    {
+        if (SetRsaInternal(rsa) != SSL_SUCCESS) {
+            WOLFSSL_MSG("SetRsaInternal failed");
+            return 0;
+        }
+    }
+
+    outLen = wolfSSL_RSA_size(rsa);
+    if (outLen == 0) {
+        WOLFSSL_MSG("Bad RSA size");
+    }
+
+    /* size of 'to' buffer must be size of RSA key */
+#if !defined(HAVE_FIPS) && !defined(HAVE_USER_RSA) && !defined(HAVE_FAST_RSA)
+    ret = wc_RsaPrivateDecrypt_ex(fr, len, to, outLen,
+                            (RsaKey*)rsa->internal, padding,
+                            hash, mgf, NULL, 0);
+#else
+    ret = wc_RsaPrivateDecrypt(fr, len, to, outLen,
+                            (RsaKey*)rsa->internal);
+#endif
+
+    if (len <= 0) {
+        WOLFSSL_MSG("Bad Rsa Decrypt");
+    }
+
+    if (ret > 0)
+        WOLFSSL_MSG("wolfSSL_RSA_private_decrypt success");
+    else {
+        WOLFSSL_MSG("wolfSSL_RSA_private_decrypt failed");
+        ret = WOLFSSL_FATAL_ERROR;
+    }
+    return ret;
+}
+
+#if !defined(_WIN32) && !defined(HAVE_FIPS) && !defined(HAVE_SELFTEST)
+int wolfSSL_RSA_public_decrypt(int flen, const unsigned char* from,
+                          unsigned char* to, WOLFSSL_RSA* rsa, int padding)
+{
+    int tlen = 0;
+    int pad_type;
+
+    WOLFSSL_ENTER("wolfSSL_RSA_public_decrypt");
+
+    if (rsa == NULL || rsa->internal == NULL || from == NULL) {
+        WOLFSSL_MSG("Bad function arguments");
+        return WOLFSSL_FAILURE;
+    }
+
+    switch (padding) {
+    case RSA_PKCS1_PADDING:
+        pad_type = WC_RSA_PKCSV15_PAD;
+        break;
+    case RSA_PKCS1_OAEP_PADDING:
+        pad_type = WC_RSA_OAEP_PAD;
+        break;
+    case RSA_PKCS1_PSS_PADDING:
+        pad_type = WC_RSA_PSS_PAD;
+        break;
+    case RSA_NO_PADDING:
+        pad_type = WC_RSA_NO_PAD;
+        break;
+    default:
+        WOLFSSL_MSG("wolfSSL_RSA_public_decrypt unsupported padding");
+        return WOLFSSL_FAILURE;
+    }
+
+    if (rsa->inSet == 0)
+    {
+        WOLFSSL_MSG("No RSA internal set, do it");
+
+        if (SetRsaInternal(rsa) != WOLFSSL_SUCCESS) {
+            WOLFSSL_MSG("SetRsaInternal failed");
+            return WOLFSSL_FAILURE;
+        }
+    }
+
+    /* size of 'to' buffer must be size of RSA key */
+    tlen = wc_RsaSSL_Verify_ex(from, flen, to, wolfSSL_RSA_size(rsa),
+                               (RsaKey*)rsa->internal, pad_type);
+    if (tlen <= 0)
+        WOLFSSL_MSG("wolfSSL_RSA_public_decrypt failed");
+    else {
+        WOLFSSL_MSG("wolfSSL_RSA_public_decrypt success");
+    }
+    return tlen;
+}
+#endif /* !defined(_WIN32) && !defined(HAVE_FIPS) && !defined(HAVE_SELFTEST) */
+
+/* RSA private encrypt calls wc_RsaSSL_Sign. Similar function set up as RSA
+ * public decrypt.
+ *
+ * len  Length of input buffer
+ * in   Input buffer to sign
+ * out  Output buffer (expected to be greater than or equal to RSA key size)
+ * rsa     Key to use for encryption
+ * padding Type of RSA padding to use.
+ */
+int wolfSSL_RSA_private_encrypt(int len, unsigned char* in,
+                            unsigned char* out, WOLFSSL_RSA* rsa, int padding)
+{
+    int sz = 0;
+    WC_RNG* rng = NULL;
+#if !defined(WC_RSA_BLINDING) || defined(HAVE_USER_RSA)
+    WC_RNG rng_lcl;
+#endif
+    RsaKey* key;
+
+    WOLFSSL_MSG("wolfSSL_RSA_private_encrypt");
+
+    if (len < 0 || rsa == NULL || rsa->internal == NULL || in == NULL) {
+        WOLFSSL_MSG("Bad function arguments");
+        return 0;
+    }
+
+    if (padding != RSA_PKCS1_PADDING && padding != RSA_PKCS1_PSS_PADDING) {
+        WOLFSSL_MSG("wolfSSL_RSA_private_encrypt unsupported padding");
+        return 0;
+    }
+
+    if (rsa->inSet == 0)
+    {
+        WOLFSSL_MSG("Setting internal RSA structure");
+
+        if (SetRsaInternal(rsa) != SSL_SUCCESS) {
+            WOLFSSL_MSG("SetRsaInternal failed");
+            return 0;
+        }
+    }
+
+    key = (RsaKey*)rsa->internal;
+#if defined(WC_RSA_BLINDING) && !defined(HAVE_USER_RSA)
+    rng = key->rng;
+#else
+    rng = &rng_lcl;
+    #ifndef HAVE_FIPS
+    if (wc_InitRng_ex(rng, key->heap, INVALID_DEVID) != 0)
+    #else
+    if (wc_InitRng(rng) != 0)
+    #endif
+    {
+        WOLFSSL_MSG("Error with random number");
+        return SSL_FATAL_ERROR;
+    }
+#endif
+
+    /* size of output buffer must be size of RSA key */
+    sz = wc_RsaSSL_Sign(in, (word32)len, out, wolfSSL_RSA_size(rsa), key, rng);
+    #if !defined(WC_RSA_BLINDING) || defined(HAVE_USER_RSA)
+    if (wc_FreeRng(rng) != 0) {
+        WOLFSSL_MSG("Error freeing random number generator");
+        return SSL_FATAL_ERROR;
+    }
+    #endif
+    if (sz <= 0) {
+        WOLFSSL_LEAVE("wolfSSL_RSA_private_encrypt", sz);
+        return 0;
+    }
+
+    return sz;
+}
+#endif /* HAVE_USER_RSA */
+#endif
+
+
+/* frees all nodes in the current threads error queue
+ *
+ * id  thread id. ERR_remove_state is depreciated and id is ignored. The
+ *     current threads queue will be free'd.
+ */
+void wolfSSL_ERR_remove_state(unsigned long id)
+{
+    WOLFSSL_ENTER("wolfSSL_ERR_remove_state");
+    (void)id;
+    if (wc_ERR_remove_state() != 0) {
+        WOLFSSL_MSG("Error with removing the state");
+    }
+}
+
+
+WOLFSSL_BN_CTX* wolfSSL_BN_CTX_new(void)
+{
+    static int ctx;  /* wolfcrypt doesn't now need ctx */
+
+    WOLFSSL_MSG("wolfSSL_BN_CTX_new");
+    return (WOLFSSL_BN_CTX*)&ctx;
+
+}
+
+void wolfSSL_BN_CTX_init(WOLFSSL_BN_CTX* ctx)
+{
+    (void)ctx;
+    WOLFSSL_MSG("wolfSSL_BN_CTX_init");
+}
+
+
+void wolfSSL_BN_CTX_free(WOLFSSL_BN_CTX* ctx)
+{
+    (void)ctx;
+    WOLFSSL_MSG("wolfSSL_BN_CTX_free");
+    /* do free since static ctx that does nothing */
+}
+
+/* WOLFSSL_SUCCESS on ok */
+int wolfSSL_BN_sub(WOLFSSL_BIGNUM* r, const WOLFSSL_BIGNUM* a,
+                  const WOLFSSL_BIGNUM* b)
+{
+    WOLFSSL_MSG("wolfSSL_BN_sub");
+
+    if (r == NULL || a == NULL || b == NULL)
+        return 0;
+
+    if (mp_sub((mp_int*)a->internal,(mp_int*)b->internal,
+               (mp_int*)r->internal) == MP_OKAY)
+        return WOLFSSL_SUCCESS;
+
+    WOLFSSL_MSG("wolfSSL_BN_sub mp_sub failed");
+    return 0;
+}
+
+/* WOLFSSL_SUCCESS on ok */
+int wolfSSL_BN_mod(WOLFSSL_BIGNUM* r, const WOLFSSL_BIGNUM* a,
+                  const WOLFSSL_BIGNUM* b, const WOLFSSL_BN_CTX* c)
+{
+    (void)c;
+    WOLFSSL_MSG("wolfSSL_BN_mod");
+
+    if (r == NULL || a == NULL || b == NULL)
+        return 0;
+
+    if (mp_mod((mp_int*)a->internal,(mp_int*)b->internal,
+               (mp_int*)r->internal) == MP_OKAY)
+        return WOLFSSL_SUCCESS;
+
+    WOLFSSL_MSG("wolfSSL_BN_mod mp_mod failed");
+    return 0;
+}
+
+
+/* r = (a^p) % m */
+int wolfSSL_BN_mod_exp(WOLFSSL_BIGNUM *r, const WOLFSSL_BIGNUM *a,
+      const WOLFSSL_BIGNUM *p, const WOLFSSL_BIGNUM *m, WOLFSSL_BN_CTX *ctx)
+{
+    int ret;
+
+    WOLFSSL_ENTER("wolfSSL_BN_mod_exp");
+
+    (void) ctx;
+    if (r == NULL || a == NULL || p == NULL || m == NULL) {
+        WOLFSSL_MSG("Bad Argument");
+        return WOLFSSL_FAILURE;
+    }
+
+    if ((ret = mp_exptmod((mp_int*)a->internal,(mp_int*)p->internal,
+               (mp_int*)m->internal, (mp_int*)r->internal)) == MP_OKAY) {
+        return WOLFSSL_SUCCESS;
+    }
+
+    WOLFSSL_LEAVE("wolfSSL_BN_mod_exp", ret);
+    (void)ret;
+
+    return WOLFSSL_FAILURE;
+}
+
+/* r = (a * p) % m */
+int wolfSSL_BN_mod_mul(WOLFSSL_BIGNUM *r, const WOLFSSL_BIGNUM *a,
+        const WOLFSSL_BIGNUM *p, const WOLFSSL_BIGNUM *m, WOLFSSL_BN_CTX *ctx)
+{
+    int ret;
+
+    WOLFSSL_ENTER("wolfSSL_BN_mod_mul");
+
+    (void) ctx;
+    if (r == NULL || a == NULL || p == NULL || m == NULL) {
+        WOLFSSL_MSG("Bad Argument");
+        return SSL_FAILURE;
+    }
+
+    if ((ret = mp_mulmod((mp_int*)a->internal,(mp_int*)p->internal,
+               (mp_int*)m->internal, (mp_int*)r->internal)) == MP_OKAY) {
+        return SSL_SUCCESS;
+    }
+
+    WOLFSSL_LEAVE("wolfSSL_BN_mod_mul", ret);
+    (void)ret;
+
+    return SSL_FAILURE;
+}
+
+#ifdef OPENSSL_EXTRA
+const WOLFSSL_BIGNUM* wolfSSL_BN_value_one(void)
+{
+    WOLFSSL_MSG("wolfSSL_BN_value_one");
+
+    if (bn_one == NULL) {
+        bn_one = wolfSSL_BN_new();
+        if (bn_one) {
+            if (mp_set_int((mp_int*)bn_one->internal, 1) != MP_OKAY) {
+                /* handle error by freeing BN and returning NULL */
+                wolfSSL_BN_free(bn_one);
+                bn_one = NULL;
+            }
+        }
+    }
+
+    return bn_one;
+}
+#endif
+
+/* return compliant with OpenSSL
+ *   size of BIGNUM in bytes, 0 if error */
+int wolfSSL_BN_num_bytes(const WOLFSSL_BIGNUM* bn)
+{
+    WOLFSSL_ENTER("wolfSSL_BN_num_bytes");
+
+    if (bn == NULL || bn->internal == NULL)
+        return WOLFSSL_FAILURE;
+
+    return mp_unsigned_bin_size((mp_int*)bn->internal);
+}
+
+/* return compliant with OpenSSL
+ *   size of BIGNUM in bits, 0 if error */
+int wolfSSL_BN_num_bits(const WOLFSSL_BIGNUM* bn)
+{
+    WOLFSSL_ENTER("wolfSSL_BN_num_bits");
+
+    if (bn == NULL || bn->internal == NULL)
+        return WOLFSSL_FAILURE;
+
+    return mp_count_bits((mp_int*)bn->internal);
+}
+
+int wolfSSL_BN_is_negative(const WOLFSSL_BIGNUM* bn)
+{
+    if (bn == NULL)
+        return WOLFSSL_FAILURE;
+
+    return mp_isneg((mp_int*)bn->internal);
+}
+
+/* return compliant with OpenSSL
+ *   1 if BIGNUM is zero, 0 else */
+int wolfSSL_BN_is_zero(const WOLFSSL_BIGNUM* bn)
+{
+    WOLFSSL_MSG("wolfSSL_BN_is_zero");
+
+    if (bn == NULL || bn->internal == NULL)
+        return WOLFSSL_FAILURE;
+
+    if (mp_iszero((mp_int*)bn->internal) == MP_YES)
+        return WOLFSSL_SUCCESS;
+
+    return WOLFSSL_FAILURE;
+}
+
+/* return compliant with OpenSSL
+ *   1 if BIGNUM is one, 0 else */
+int wolfSSL_BN_is_one(const WOLFSSL_BIGNUM* bn)
+{
+    WOLFSSL_MSG("wolfSSL_BN_is_one");
+
+    if (bn == NULL || bn->internal == NULL)
+        return WOLFSSL_FAILURE;
+
+    if (mp_cmp_d((mp_int*)bn->internal, 1) == MP_EQ)
+        return WOLFSSL_SUCCESS;
+
+    return WOLFSSL_FAILURE;
+}
+
+/* return compliant with OpenSSL
+ *   1 if BIGNUM is odd, 0 else */
+int wolfSSL_BN_is_odd(const WOLFSSL_BIGNUM* bn)
+{
+    WOLFSSL_MSG("wolfSSL_BN_is_odd");
+
+    if (bn == NULL || bn->internal == NULL)
+        return WOLFSSL_FAILURE;
+
+    if (mp_isodd((mp_int*)bn->internal) == MP_YES)
+        return WOLFSSL_SUCCESS;
+
+    return WOLFSSL_FAILURE;
+}
+
+/* return compliant with OpenSSL
+ *   1 if BIGNUM is word, 0 else */
+int wolfSSL_BN_is_word(const WOLFSSL_BIGNUM* bn, WOLFSSL_BN_ULONG w)
+{
+    WOLFSSL_ENTER("wolfSSL_BN_is_word");
+
+    if (bn == NULL || bn->internal == NULL) {
+        WOLFSSL_MSG("bn NULL error");
+        return WOLFSSL_FAILURE;
+    }
+
+    if (mp_isword((mp_int*)bn->internal, w) == MP_YES) {
+         return WOLFSSL_SUCCESS;
+    }
+
+    return WOLFSSL_FAILURE;
+}
+
+/* return compliant with OpenSSL
+ *   -1 if a < b, 0 if a == b and 1 if a > b
+ */
+int wolfSSL_BN_cmp(const WOLFSSL_BIGNUM* a, const WOLFSSL_BIGNUM* b)
+{
+    int ret;
+
+    WOLFSSL_MSG("wolfSSL_BN_cmp");
+
+    if (a == NULL || a->internal == NULL || b == NULL || b->internal == NULL)
+        return WOLFSSL_FATAL_ERROR;
+
+    ret = mp_cmp((mp_int*)a->internal, (mp_int*)b->internal);
+
+    return (ret == MP_EQ ? 0 : (ret == MP_GT ? 1 : -1));
+}
+
+/* return compliant with OpenSSL
+ *   length of BIGNUM in bytes, -1 if error */
+int wolfSSL_BN_bn2bin(const WOLFSSL_BIGNUM* bn, unsigned char* r)
+{
+    WOLFSSL_MSG("wolfSSL_BN_bn2bin");
+
+    if (bn == NULL || bn->internal == NULL) {
+        WOLFSSL_MSG("NULL bn error");
+        return WOLFSSL_FATAL_ERROR;
+    }
+
+    if (r == NULL)
+        return mp_unsigned_bin_size((mp_int*)bn->internal);
+
+    if (mp_to_unsigned_bin((mp_int*)bn->internal, r) != MP_OKAY) {
+        WOLFSSL_MSG("mp_to_unsigned_bin error");
+        return WOLFSSL_FATAL_ERROR;
+    }
+
+    return mp_unsigned_bin_size((mp_int*)bn->internal);
+}
+
+
+WOLFSSL_BIGNUM* wolfSSL_BN_bin2bn(const unsigned char* str, int len,
+                            WOLFSSL_BIGNUM* ret)
+{
+    int weOwn = 0;
+
+    WOLFSSL_MSG("wolfSSL_BN_bin2bn");
+
+    /* if ret is null create a BN */
+    if (ret == NULL) {
+        ret = wolfSSL_BN_new();
+        weOwn = 1;
+        if (ret == NULL)
+            return NULL;
+    }
+
+    /* check ret and ret->internal then read in value */
+    if (ret && ret->internal) {
+        if (mp_read_unsigned_bin((mp_int*)ret->internal, str, len) != 0) {
+            WOLFSSL_MSG("mp_read_unsigned_bin failure");
+            if (weOwn)
+                wolfSSL_BN_free(ret);
+            return NULL;
+        }
+    } else {
+        return NULL;
+    }
+
+    return ret;
+}
+
+/* return compliant with OpenSSL
+ *   1 if success, 0 if error */
+#ifndef NO_WOLFSSL_STUB
+int wolfSSL_mask_bits(WOLFSSL_BIGNUM* bn, int n)
+{
+    (void)bn;
+    (void)n;
+    WOLFSSL_ENTER("wolfSSL_BN_mask_bits");
+    WOLFSSL_STUB("BN_mask_bits");
+    return SSL_FAILURE;
+}
+#endif
+
+
+/* WOLFSSL_SUCCESS on ok */
+int wolfSSL_BN_rand(WOLFSSL_BIGNUM* bn, int bits, int top, int bottom)
+{
+    int           ret    = 0;
+    int           len    = bits / 8;
+    int           initTmpRng = 0;
+    WC_RNG*       rng    = NULL;
+#ifdef WOLFSSL_SMALL_STACK
+    WC_RNG*       tmpRNG = NULL;
+    byte*         buff   = NULL;
+#else
+    WC_RNG        tmpRNG[1];
+    byte          buff[1024];
+#endif
+
+    (void)top;
+    (void)bottom;
+    WOLFSSL_MSG("wolfSSL_BN_rand");
+
+    if (bits % 8)
+        len++;
+
+#ifdef WOLFSSL_SMALL_STACK
+    buff   = (byte*)XMALLOC(1024,        NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    tmpRNG = (WC_RNG*) XMALLOC(sizeof(WC_RNG), NULL, DYNAMIC_TYPE_RNG);
+    if (buff == NULL || tmpRNG == NULL) {
+        XFREE(buff,   NULL, DYNAMIC_TYPE_TMP_BUFFER);
+        XFREE(tmpRNG, NULL, DYNAMIC_TYPE_RNG);
+        return ret;
+    }
+#endif
+
+    if (bn == NULL || bn->internal == NULL)
+        WOLFSSL_MSG("Bad function arguments");
+    else if (wc_InitRng(tmpRNG) == 0) {
+        rng = tmpRNG;
+        initTmpRng = 1;
+    }
+    else if (initGlobalRNG)
+        rng = &globalRNG;
+
+    if (rng) {
+        if (wc_RNG_GenerateBlock(rng, buff, len) != 0)
+            WOLFSSL_MSG("Bad wc_RNG_GenerateBlock");
+        else {
+            buff[0]     |= 0x80 | 0x40;
+            buff[len-1] |= 0x01;
+
+            if (mp_read_unsigned_bin((mp_int*)bn->internal,buff,len) != MP_OKAY)
+                WOLFSSL_MSG("mp read bin failed");
+            else
+                ret = WOLFSSL_SUCCESS;
+        }
+    }
+
+    if (initTmpRng)
+        wc_FreeRng(tmpRNG);
+
+#ifdef WOLFSSL_SMALL_STACK
+    XFREE(buff,   NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    XFREE(tmpRNG, NULL, DYNAMIC_TYPE_RNG);
+#endif
+
+    return ret;
+}
+
+
+/* WOLFSSL_SUCCESS on ok
+ * code is same as wolfSSL_BN_rand except for how top and bottom is handled.
+ * top -1 then leave most sig bit alone
+ * top 0 then most sig is set to 1
+ * top is 1 then first two most sig bits are 1
+ *
+ * bottom is hot then odd number */
+int wolfSSL_BN_pseudo_rand(WOLFSSL_BIGNUM* bn, int bits, int top, int bottom)
+{
+    int           ret    = 0;
+    int           len    = bits / 8;
+    int           initTmpRng = 0;
+    WC_RNG*       rng    = NULL;
+#ifdef WOLFSSL_SMALL_STACK
+    WC_RNG*       tmpRNG = NULL;
+    byte*         buff   = NULL;
+#else
+    WC_RNG        tmpRNG[1];
+    byte          buff[1024];
+#endif
+
+    WOLFSSL_MSG("wolfSSL_BN_rand");
+
+    if (bits % 8)
+        len++;
+
+#ifdef WOLFSSL_SMALL_STACK
+    buff   = (byte*)XMALLOC(1024,        NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    tmpRNG = (WC_RNG*) XMALLOC(sizeof(WC_RNG), NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    if (buff == NULL || tmpRNG == NULL) {
+        XFREE(buff,   NULL, DYNAMIC_TYPE_TMP_BUFFER);
+        XFREE(tmpRNG, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+        return ret;
+    }
+#endif
+
+    if (bn == NULL || bn->internal == NULL)
+        WOLFSSL_MSG("Bad function arguments");
+    else if (wc_InitRng(tmpRNG) == 0) {
+        rng = tmpRNG;
+        initTmpRng = 1;
+    }
+    else if (initGlobalRNG)
+        rng = &globalRNG;
+
+    if (rng) {
+        if (wc_RNG_GenerateBlock(rng, buff, len) != 0)
+            WOLFSSL_MSG("Bad wc_RNG_GenerateBlock");
+        else {
+            switch (top) {
+                case -1:
+                    break;
+
+                case 0:
+                    buff[0] |= 0x80;
+                    break;
+
+                case 1:
+                    buff[0] |= 0x80 | 0x40;
+                    break;
+            }
+
+            if (bottom == 1) {
+                buff[len-1] |= 0x01;
+            }
+
+            if (mp_read_unsigned_bin((mp_int*)bn->internal,buff,len) != MP_OKAY)
+                WOLFSSL_MSG("mp read bin failed");
+            else
+                ret = WOLFSSL_SUCCESS;
+        }
+    }
+
+    if (initTmpRng)
+        wc_FreeRng(tmpRNG);
+
+#ifdef WOLFSSL_SMALL_STACK
+    XFREE(buff,   NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    XFREE(tmpRNG, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+#endif
+
+    return ret;
+}
+
+/* return code compliant with OpenSSL :
+ *   1 if bit set, 0 else
+ */
+int wolfSSL_BN_is_bit_set(const WOLFSSL_BIGNUM* bn, int n)
+{
+    if (bn == NULL || bn->internal == NULL) {
+        WOLFSSL_MSG("bn NULL error");
+        return WOLFSSL_FAILURE;
+    }
+
+    return mp_is_bit_set((mp_int*)bn->internal, (mp_digit)n);
+}
+
+/* return code compliant with OpenSSL :
+ *   1 if success, 0 else
+ */
+int wolfSSL_BN_set_bit(WOLFSSL_BIGNUM* bn, int n)
+{
+    if (bn == NULL || bn->internal == NULL) {
+        WOLFSSL_MSG("bn NULL error");
+        return WOLFSSL_FAILURE;
+    }
+
+    if (mp_set_bit((mp_int*)bn->internal, n) != MP_OKAY) {
+        WOLFSSL_MSG("mp_set_bit error");
+        return WOLFSSL_FAILURE;
+    }
+
+    return WOLFSSL_SUCCESS;
+}
+
+
+int wolfSSL_BN_clear_bit(WOLFSSL_BIGNUM* bn, int n)
+{
+    int ret = WOLFSSL_FAILURE;
+#ifndef WOLFSSL_SMALL_STACK
+    mp_int tmp[1];
+#else
+    mp_int* tmp = NULL;
+#endif
+
+    if (bn == NULL || bn->internal == NULL) {
+        WOLFSSL_MSG("bn NULL error");
+        goto cleanup;
+    }
+    if (mp_is_bit_set((mp_int*)bn->internal, n)) {
+#ifdef WOLFSSL_SMALL_STACK
+       tmp = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_BIGINT);
+       if (tmp == NULL) {
+           goto cleanup;
+       }
+#endif
+        if (mp_init(tmp) != MP_OKAY) {
+            goto cleanup;
+        }
+        if (mp_set_bit(tmp, n) != MP_OKAY) {
+            goto cleanup;
+        }
+        if (mp_sub((mp_int*)bn->internal, tmp, (mp_int*)bn->internal) != MP_OKAY) {
+            goto cleanup;
+        }
+    }
+
+    ret = WOLFSSL_SUCCESS;
+cleanup:
+    mp_clear(tmp);
+#ifdef WOLFSSL_SMALL_STACK
+    if (tmp)
+        XFREE(tmp, NULL, DYNAMIC_TYPE_BIGINT);
+#endif
+    return ret;
+}
+
+
+/* WOLFSSL_SUCCESS on ok */
+/* Note on use: this function expects str to be an even length. It is
+ * converting pairs of bytes into 8-bit values. As an example, the RSA
+ * public exponent is commonly 0x010001. To get it to convert, you need
+ * to pass in the string "010001", it will fail if you use "10001". This
+ * is an affect of how Base16_Decode() works.
+ */
+int wolfSSL_BN_hex2bn(WOLFSSL_BIGNUM** bn, const char* str)
+{
+    int     ret     = 0;
+    word32  decSz   = 1024;
+#ifdef WOLFSSL_SMALL_STACK
+    byte*   decoded;
+#else
+    byte    decoded[1024];
+#endif
+    int     weOwn = 0;
+    int     strLen;
+
+    WOLFSSL_MSG("wolfSSL_BN_hex2bn");
+
+#ifdef WOLFSSL_SMALL_STACK
+    decoded = (byte*)XMALLOC(decSz, NULL, DYNAMIC_TYPE_DER);
+    if (decoded == NULL)
+        return ret;
+#endif
+
+    if (str == NULL || str[0] == '\0') {
+        WOLFSSL_MSG("Bad function argument");
+        ret = WOLFSSL_FAILURE;
+    } else {
+        strLen = (int)XSTRLEN(str);
+        /* ignore trailing new lines */
+        while (str[strLen-1] == '\n' && strLen > 0) strLen--;
+
+        if (Base16_Decode((byte*)str, strLen, decoded, &decSz) < 0)
+            WOLFSSL_MSG("Bad Base16_Decode error");
+        else if (bn == NULL)
+            ret = decSz;
+        else {
+            if (*bn == NULL) {
+                *bn = wolfSSL_BN_new();
+                if (*bn != NULL) {
+                    weOwn = 1;
+                }
+            }
+
+            if (*bn == NULL)
+                WOLFSSL_MSG("BN new failed");
+            else if (wolfSSL_BN_bin2bn(decoded, decSz, *bn) == NULL) {
+                WOLFSSL_MSG("Bad bin2bn error");
+                if (weOwn == 1) {
+                    wolfSSL_BN_free(*bn); /* Free new BN */
+                }
+            }
+            else
+                ret = WOLFSSL_SUCCESS;
+        }
+    }
+
+#ifdef WOLFSSL_SMALL_STACK
+    XFREE(decoded, NULL, DYNAMIC_TYPE_DER);
+#endif
+
+    return ret;
+}
+
+
+WOLFSSL_BIGNUM* wolfSSL_BN_dup(const WOLFSSL_BIGNUM* bn)
+{
+    WOLFSSL_BIGNUM* ret;
+
+    WOLFSSL_MSG("wolfSSL_BN_dup");
+
+    if (bn == NULL || bn->internal == NULL) {
+        WOLFSSL_MSG("bn NULL error");
+        return NULL;
+    }
+
+    ret = wolfSSL_BN_new();
+    if (ret == NULL) {
+        WOLFSSL_MSG("bn new error");
+        return NULL;
+    }
+
+    if (mp_copy((mp_int*)bn->internal, (mp_int*)ret->internal) != MP_OKAY) {
+        WOLFSSL_MSG("mp_copy error");
+        wolfSSL_BN_free(ret);
+        return NULL;
+    }
+
+    ret->neg = bn->neg;
+
+    return ret;
+}
+
+
+WOLFSSL_BIGNUM* wolfSSL_BN_copy(WOLFSSL_BIGNUM* r, const WOLFSSL_BIGNUM* bn)
+{
+    WOLFSSL_MSG("wolfSSL_BN_copy");
+
+    if (r == NULL || bn == NULL) {
+        WOLFSSL_MSG("r or bn NULL error");
+        return NULL;
+    }
+
+    if (mp_copy((mp_int*)bn->internal, (mp_int*)r->internal) != MP_OKAY) {
+        WOLFSSL_MSG("mp_copy error");
+        return NULL;
+    }
+
+    r->neg = bn->neg;
+
+    return r;
+}
+
+/* return code compliant with OpenSSL :
+ *   1 if success, 0 else
+ */
+int wolfSSL_BN_set_word(WOLFSSL_BIGNUM* bn, WOLFSSL_BN_ULONG w)
+{
+    WOLFSSL_MSG("wolfSSL_BN_set_word");
+
+    if (bn == NULL) {
+        WOLFSSL_MSG("bn NULL error");
+        return WOLFSSL_FAILURE;
+    }
+
+    if (mp_set_int((mp_int*)bn->internal, w) != MP_OKAY) {
+        WOLFSSL_MSG("mp_init_set_int error");
+        return WOLFSSL_FAILURE;
+    }
+
+    return WOLFSSL_SUCCESS;
+}
+
+
+/* Returns the big number as an unsigned long if possible.
+ *
+ * bn  big number structure to get value from
+ *
+ * Returns value or 0xFFFFFFFFL if bigger than unsigned long.
+ */
+unsigned long wolfSSL_BN_get_word(const WOLFSSL_BIGNUM* bn)
+{
+    mp_int* mp;
+
+    WOLFSSL_MSG("wolfSSL_BN_get_word");
+
+    if (bn == NULL) {
+        WOLFSSL_MSG("Invalid argument");
+        return 0;
+    }
+
+    if (wolfSSL_BN_num_bytes(bn) > (int)sizeof(unsigned long)) {
+        WOLFSSL_MSG("bignum is larger than unsigned long");
+        return 0xFFFFFFFFL;
+    }
+    mp = (mp_int*)bn->internal;
+
+    return (unsigned long)(mp->dp[0]);
+}
+
+/* return code compliant with OpenSSL :
+ *   number length in decimal if success, 0 if error
+ */
+#ifndef NO_WOLFSSL_STUB
+int wolfSSL_BN_dec2bn(WOLFSSL_BIGNUM** bn, const char* str)
+{
+    (void)bn;
+    (void)str;
+
+    WOLFSSL_MSG("wolfSSL_BN_dec2bn");
+    WOLFSSL_STUB("BN_dec2bn");
+    return SSL_FAILURE;
+}
+#endif
+
+#if defined(WOLFSSL_KEY_GEN) || defined(HAVE_COMP_KEY)
+char *wolfSSL_BN_bn2dec(const WOLFSSL_BIGNUM *bn)
+{
+    int len = 0;
+    char *buf;
+
+    WOLFSSL_MSG("wolfSSL_BN_bn2dec");
+
+    if (bn == NULL || bn->internal == NULL) {
+        WOLFSSL_MSG("bn NULL error");
+        return NULL;
+    }
+
+    if (mp_radix_size((mp_int*)bn->internal, MP_RADIX_DEC, &len) != MP_OKAY) {
+        WOLFSSL_MSG("mp_radix_size failure");
+        return NULL;
+    }
+
+    buf = (char*) XMALLOC(len, NULL, DYNAMIC_TYPE_OPENSSL);
+    if (buf == NULL) {
+        WOLFSSL_MSG("BN_bn2dec malloc buffer failure");
+        return NULL;
+    }
+
+    if (mp_todecimal((mp_int*)bn->internal, buf) != MP_OKAY) {
+        XFREE(buf, NULL, DYNAMIC_TYPE_ECC);
+        return NULL;
+    }
+
+    return buf;
+}
+#else
+char* wolfSSL_BN_bn2dec(const WOLFSSL_BIGNUM* bn)
+{
+    (void)bn;
+
+    WOLFSSL_MSG("wolfSSL_BN_bn2dec");
+
+    return NULL;
+}
+#endif /* defined(WOLFSSL_KEY_GEN) || defined(HAVE_COMP_KEY) */
+
+/* return code compliant with OpenSSL :
+ *   1 if success, 0 else
+ */
+int wolfSSL_BN_lshift(WOLFSSL_BIGNUM *r, const WOLFSSL_BIGNUM *bn, int n)
+{
+    WOLFSSL_MSG("wolfSSL_BN_lshift");
+
+    if (r == NULL || r->internal == NULL || bn == NULL || bn->internal == NULL){
+        WOLFSSL_MSG("bn NULL error");
+        return WOLFSSL_FAILURE;
+    }
+
+    if (mp_mul_2d((mp_int*)bn->internal, n, (mp_int*)r->internal) != MP_OKAY) {
+        WOLFSSL_MSG("mp_mul_2d error");
+        return WOLFSSL_FAILURE;
+    }
+
+    return WOLFSSL_SUCCESS;
+}
+
+/* return code compliant with OpenSSL :
+ *   1 if success, 0 else
+ */
+int wolfSSL_BN_rshift(WOLFSSL_BIGNUM *r, const WOLFSSL_BIGNUM *bn, int n)
+{
+    WOLFSSL_MSG("wolfSSL_BN_rshift");
+
+    if (r == NULL || r->internal == NULL || bn == NULL || bn->internal == NULL){
+        WOLFSSL_MSG("bn NULL error");
+        return WOLFSSL_FAILURE;
+    }
+
+    if (mp_div_2d((mp_int*)bn->internal, n,
+                  (mp_int*)r->internal, NULL) != MP_OKAY) {
+        WOLFSSL_MSG("mp_mul_2d error");
+        return WOLFSSL_FAILURE;
+    }
+
+    return WOLFSSL_SUCCESS;
+}
+
+/* return code compliant with OpenSSL :
+ *   1 if success, 0 else
+ */
+int wolfSSL_BN_add_word(WOLFSSL_BIGNUM *bn, WOLFSSL_BN_ULONG w)
+{
+    WOLFSSL_MSG("wolfSSL_BN_add_word");
+
+    if (bn == NULL || bn->internal == NULL) {
+        WOLFSSL_MSG("bn NULL error");
+        return WOLFSSL_FAILURE;
+    }
+
+    if (mp_add_d((mp_int*)bn->internal, w, (mp_int*)bn->internal) != MP_OKAY) {
+        WOLFSSL_MSG("mp_add_d error");
+        return WOLFSSL_FAILURE;
+    }
+
+    return WOLFSSL_SUCCESS;
+}
+
+/* return code compliant with OpenSSL :
+ *   1 if success, 0 else
+ */
+int wolfSSL_BN_add(WOLFSSL_BIGNUM *r, WOLFSSL_BIGNUM *a, WOLFSSL_BIGNUM *b)
+{
+    WOLFSSL_MSG("wolfSSL_BN_add");
+
+    if (r == NULL || r->internal == NULL || a == NULL || a->internal == NULL ||
+        b == NULL || b->internal == NULL) {
+        WOLFSSL_MSG("bn NULL error");
+        return WOLFSSL_FAILURE;
+    }
+
+    if (mp_add((mp_int*)a->internal, (mp_int*)b->internal,
+               (mp_int*)r->internal) != MP_OKAY) {
+        WOLFSSL_MSG("mp_add_d error");
+        return WOLFSSL_FAILURE;
+    }
+
+    return WOLFSSL_SUCCESS;
+}
+
+/* r = a + b (mod m) */
+int wolfSSL_BN_mod_add(WOLFSSL_BIGNUM *r, const WOLFSSL_BIGNUM *a,
+                       const WOLFSSL_BIGNUM *b, const WOLFSSL_BIGNUM *m,
+                       WOLFSSL_BN_CTX *ctx)
+{
+    (void)ctx;
+    WOLFSSL_MSG("wolfSSL_BN_add");
+
+    if (r == NULL || r->internal == NULL ||
+            a == NULL || a->internal == NULL ||
+            b == NULL || b->internal == NULL ||
+            m == NULL || m->internal == NULL) {
+        WOLFSSL_MSG("bn NULL error");
+        return WOLFSSL_FAILURE;
+    }
+
+    if (mp_addmod((mp_int*)a->internal, (mp_int*)b->internal,
+                  (mp_int*)m->internal, (mp_int*)r->internal) != MP_OKAY) {
+        WOLFSSL_MSG("mp_add_d error");
+        return WOLFSSL_FAILURE;
+    }
+
+    return WOLFSSL_SUCCESS;
+}
+
+#ifdef WOLFSSL_KEY_GEN
+
+/* return code compliant with OpenSSL :
+ *   1 if prime, 0 if not, -1 if error
+ */
+int wolfSSL_BN_is_prime_ex(const WOLFSSL_BIGNUM *bn, int nbchecks,
+                           WOLFSSL_BN_CTX *ctx, WOLFSSL_BN_GENCB *cb)
+{
+    WC_RNG*        rng    = NULL;
+#ifdef WOLFSSL_SMALL_STACK
+    WC_RNG*        tmpRNG = NULL;
+#else
+    WC_RNG         tmpRNG[1];
+#endif
+    int            initTmpRng = 0;
+    int            res = MP_NO;
+
+    (void)ctx;
+    (void)cb;
+
+    WOLFSSL_MSG("wolfSSL_BN_is_prime_ex");
+
+    if (bn == NULL || bn->internal == NULL) {
+        WOLFSSL_MSG("bn NULL error");
+        return WOLFSSL_FATAL_ERROR;
+    }
+
+#ifdef WOLFSSL_SMALL_STACK
+    tmpRNG = (WC_RNG*)XMALLOC(sizeof(WC_RNG), NULL, DYNAMIC_TYPE_RNG);
+    if (tmpRNG == NULL)
+        return WOLFSSL_FAILURE;
+#endif
+    if (wc_InitRng(tmpRNG) == 0) {
+        rng = tmpRNG;
+        initTmpRng = 1;
+    }
+    else {
+        WOLFSSL_MSG("Bad RNG Init, trying global");
+        if (initGlobalRNG == 0) {
+            WOLFSSL_MSG("Global RNG no Init");
+        }
+        else
+            rng = &globalRNG;
+    }
+
+    if (rng) {
+        if (mp_prime_is_prime_ex((mp_int*)bn->internal,
+                                 nbchecks, &res, rng) != MP_OKAY) {
+            WOLFSSL_MSG("mp_prime_is_prime_ex error");
+            res = MP_NO;
+        }
+    }
+
+    if (initTmpRng)
+        wc_FreeRng(tmpRNG);
+#ifdef WOLFSSL_SMALL_STACK
+    XFREE(tmpRNG, NULL, DYNAMIC_TYPE_RNG);
+#endif
+
+    if (res != MP_YES) {
+        WOLFSSL_MSG("mp_prime_is_prime_ex not prime");
+        return WOLFSSL_FAILURE;
+    }
+
+    return WOLFSSL_SUCCESS;
+}
+
+/* return code compliant with OpenSSL :
+ *   (bn mod w) if success, -1 if error
+ */
+WOLFSSL_BN_ULONG wolfSSL_BN_mod_word(const WOLFSSL_BIGNUM *bn,
+                                     WOLFSSL_BN_ULONG w)
+{
+    WOLFSSL_BN_ULONG ret = 0;
+
+    WOLFSSL_MSG("wolfSSL_BN_mod_word");
+
+    if (bn == NULL || bn->internal == NULL) {
+        WOLFSSL_MSG("bn NULL error");
+        return (WOLFSSL_BN_ULONG)WOLFSSL_FATAL_ERROR;
+    }
+
+    if (mp_mod_d((mp_int*)bn->internal, w, &ret) != MP_OKAY) {
+        WOLFSSL_MSG("mp_add_d error");
+        return (WOLFSSL_BN_ULONG)WOLFSSL_FATAL_ERROR;
+    }
+
+    return ret;
+}
+#endif /* #ifdef WOLFSSL_KEY_GEN */
+
+char *wolfSSL_BN_bn2hex(const WOLFSSL_BIGNUM *bn)
+{
+    int len = 0;
+    char *buf;
+
+    WOLFSSL_ENTER("wolfSSL_BN_bn2hex");
+
+    if (bn == NULL || bn->internal == NULL) {
+        WOLFSSL_MSG("bn NULL error");
+        return NULL;
+    }
+
+    if (mp_radix_size((mp_int*)bn->internal, MP_RADIX_HEX, &len) != MP_OKAY) {
+        WOLFSSL_MSG("mp_radix_size failure");
+        return NULL;
+    }
+    len += 1; /* add one for null terminator */
+
+    buf = (char*)XMALLOC(len, NULL, DYNAMIC_TYPE_OPENSSL);
+    if (buf == NULL) {
+        WOLFSSL_MSG("BN_bn2hex malloc buffer failure");
+        return NULL;
+    }
+
+    if (mp_tohex((mp_int*)bn->internal, buf) != MP_OKAY) {
+        XFREE(buf, NULL, DYNAMIC_TYPE_OPENSSL);
+        return NULL;
+    }
+
+    return buf;
+}
+
+#ifndef NO_FILESYSTEM
+/* return code compliant with OpenSSL :
+ *   1 if success, 0 if error
+ */
+int wolfSSL_BN_print_fp(XFILE fp, const WOLFSSL_BIGNUM *bn)
+{
+    char *buf;
+
+    WOLFSSL_ENTER("wolfSSL_BN_print_fp");
+
+    if (fp == XBADFILE || bn == NULL || bn->internal == NULL) {
+        WOLFSSL_MSG("bn NULL error");
+        return WOLFSSL_FAILURE;
+    }
+
+    buf = wolfSSL_BN_bn2hex(bn);
+    if (buf == NULL) {
+        WOLFSSL_MSG("wolfSSL_BN_bn2hex failure");
+        return WOLFSSL_FAILURE;
+    }
+
+    fprintf(fp, "%s", buf);
+    XFREE(buf, NULL, DYNAMIC_TYPE_OPENSSL);
+
+    return WOLFSSL_SUCCESS;
+}
+#endif /* !NO_FILESYSTEM */
+
+
+WOLFSSL_BIGNUM *wolfSSL_BN_CTX_get(WOLFSSL_BN_CTX *ctx)
+{
+    /* ctx is not used, return new Bignum */
+    (void)ctx;
+
+    WOLFSSL_ENTER("wolfSSL_BN_CTX_get");
+
+    return wolfSSL_BN_new();
+}
+
+#ifndef NO_WOLFSSL_STUB
+void wolfSSL_BN_CTX_start(WOLFSSL_BN_CTX *ctx)
+{
+    (void)ctx;
+
+    WOLFSSL_ENTER("wolfSSL_BN_CTX_start");
+    WOLFSSL_STUB("BN_CTX_start");
+    WOLFSSL_MSG("wolfSSL_BN_CTX_start TBD");
+}
+#endif
+
+
+WOLFSSL_BIGNUM *wolfSSL_BN_mod_inverse(WOLFSSL_BIGNUM *r,
+                                       WOLFSSL_BIGNUM *a,
+                                       const WOLFSSL_BIGNUM *n,
+                                       WOLFSSL_BN_CTX *ctx)
+{
+    int dynamic = 0;
+
+    /* ctx is not used */
+    (void)ctx;
+
+    WOLFSSL_ENTER("wolfSSL_BN_mod_inverse");
+
+    /* check parameter */
+    if (r == NULL) {
+        r = wolfSSL_BN_new();
+        if (r == NULL){
+            WOLFSSL_MSG("WolfSSL_BN_new() failed");
+            return NULL;
+        }
+        dynamic = 1;
+    }
+
+    if (a == NULL) {
+        WOLFSSL_MSG("a NULL error");
+        if (dynamic == 1) {
+            wolfSSL_BN_free(r);
+        }
+        return NULL;
+    }
+
+    if (n == NULL) {
+        WOLFSSL_MSG("n NULL error");
+        if (dynamic == 1) {
+            wolfSSL_BN_free(r);
+        }
+        return NULL;
+    }
+
+    /* Compute inverse of a modulo n and return r */
+    if (mp_invmod((mp_int *)a->internal,(mp_int *)n->internal,
+                  (mp_int*)r->internal) == MP_VAL){
+        WOLFSSL_MSG("mp_invmod() error");
+        if (dynamic == 1) {
+            wolfSSL_BN_free(r);
+        }
+        return NULL;
+    }
+
+    return  r;
+}
+#endif  /* OPENSSL_EXTRA */
+#if (defined(WOLFSSL_QT) || defined(OPENSSL_ALL)) && !defined(NO_ASN)
+static int unprintable_char(char c)
+{
+    const unsigned char last_unprintable = 31;
+    const unsigned char LF = 10;
+    const unsigned char CR = 13;
+
+    if (c <= last_unprintable && c != LF && c != CR) {
+        return 1;
+    }
+    return 0;
+}
+
+int wolfSSL_ASN1_STRING_print(WOLFSSL_BIO *out, WOLFSSL_ASN1_STRING *str)
+{
+    int i;
+
+    WOLFSSL_ENTER("wolfSSL_ASN1_STRING_print");
+    if (out == NULL || str == NULL)
+           return WOLFSSL_FAILURE;
+
+    for (i=0; i < str->length; i++) {
+        if (unprintable_char(str->data[i])) {
+            str->data[i] = '.';
+        }
+    }
+
+    if (wolfSSL_BIO_write(out, str->data, str->length) != str->length){
+        return WOLFSSL_FAILURE;
+    }
+
+    return str->length;
+}
+#endif /* (WOLFSSL_QT || OPENSSL_ALL) && !NO_ASN */
+
+#if defined(OPENSSL_EXTRA)
+int wolfSSL_X509_check_ca(WOLFSSL_X509 *x509)
+{
+    WOLFSSL_ENTER("X509_check_ca");
+
+    if (x509 == NULL)
+        return WOLFSSL_FAILURE;
+    if (x509->isCa)
+        return 1;
+    if (x509->extKeyUsageCrit)
+        return 4;
+
+    return 0;
+}
+
+
+const char *wolfSSL_ASN1_tag2str(int tag)
+{
+    static const char *const tag_label[31] = {
+        "EOC", "BOOLEAN", "INTEGER", "BIT STRING", "OCTET STRING", "NULL",
+        "OBJECT", "OBJECT DESCRIPTOR", "EXTERNAL", "REAL", "ENUMERATED",
+        "<ASN1 11>", "UTF8STRING", "<ASN1 13>", "<ASN1 14>", "<ASN1 15>",
+        "SEQUENCE", "SET", "NUMERICSTRING", "PRINTABLESTRING", "T61STRING",
+        "VIDEOTEXTSTRING", "IA5STRING", "UTCTIME", "GENERALIZEDTIME",
+        "GRAPHICSTRING", "VISIBLESTRING", "GENERALSTRING", "UNIVERSALSTRING",
+        "<ASN1 29>", "BMPSTRING"
+    };
+
+    if ((tag == V_ASN1_NEG_INTEGER) || (tag == V_ASN1_NEG_ENUMERATED))
+        tag &= ~0x100;
+    if (tag < 0 || tag > 30)
+        return "(unknown)";
+    return tag_label[tag];
+}
+
+static int check_esc_char(char c, char *esc)
+{
+    char *ptr;
+
+    ptr = esc;
+    while(*ptr != 0){
+        if (c == *ptr)
+            return 1;
+        ptr++;
+    }
+    return 0;
+}
+
+int wolfSSL_ASN1_STRING_print_ex(WOLFSSL_BIO *out, WOLFSSL_ASN1_STRING *str,
+                                 unsigned long flags)
+{
+    size_t str_len = 0, type_len = 0;
+    unsigned char *typebuf = NULL;
+    const char *hash="#";
+
+    WOLFSSL_ENTER("wolfSSL_ASN1_STRING_PRINT_ex");
+    if (out == NULL || str == NULL)
+        return WOLFSSL_FAILURE;
+
+    /* add ASN1 type tag */
+    if (flags & ASN1_STRFLGS_SHOW_TYPE){
+        const char *tag = wolfSSL_ASN1_tag2str(str->type);
+        /* colon len + tag len + null*/
+        type_len = XSTRLEN(tag) + 2;
+        typebuf = (unsigned char *)XMALLOC(type_len , NULL, DYNAMIC_TYPE_TMP_BUFFER);
+        if (typebuf == NULL){
+            WOLFSSL_MSG("memory alloc failed.");
+            return WOLFSSL_FAILURE;
+        }
+        XMEMSET(typebuf, 0, type_len);
+        XSNPRINTF((char*)typebuf, (size_t)type_len , "%s:", tag);
+        type_len--;
+    }
+
+    /* dump hex */
+    if (flags & ASN1_STRFLGS_DUMP_ALL){
+        static const char hex_char[] = { '0', '1', '2', '3', '4', '5', '6',
+                                         '7','8', '9', 'A', 'B', 'C', 'D',
+                                         'E', 'F' };
+        char hex_tmp[4];
+        char *str_ptr, *str_end;
+
+        if (type_len > 0){
+            if (wolfSSL_BIO_write(out, typebuf, (int)type_len) != (int)type_len){
+                XFREE(typebuf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+                return WOLFSSL_FAILURE;
+            }
+            str_len += type_len;
+        }
+        if (wolfSSL_BIO_write(out, hash, 1) != 1){
+            goto err_exit;
+        }
+        str_len++;
+        if (flags & ASN1_STRFLGS_DUMP_DER){
+            hex_tmp[0] = hex_char[str->type >> 4];
+            hex_tmp[1] = hex_char[str->type & 0xf];
+            hex_tmp[2] = hex_char[str->length >> 4];
+            hex_tmp[3] = hex_char[str->length & 0xf];
+            if (wolfSSL_BIO_write(out, hex_tmp, 4) != 4){
+                goto err_exit;
+            }
+            str_len += 4;
+            XMEMSET(hex_tmp, 0, 4);
+        }
+
+        str_ptr = str->data;
+        str_end = str->data + str->length;
+        while (str_ptr < str_end){
+            hex_tmp[0] = hex_char[*str_ptr >> 4];
+            hex_tmp[1] = hex_char[*str_ptr & 0xf];
+            if (wolfSSL_BIO_write(out, hex_tmp, 2) != 2){
+                goto err_exit;
+            }
+            str_ptr++;
+            str_len += 2;
+        }
+        if (type_len > 0)
+            XFREE(typebuf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+
+        return (int)str_len;
+    }
+
+    if (type_len > 0){
+        if (wolfSSL_BIO_write(out, typebuf, (int)type_len) != (int)type_len){
+            XFREE(typebuf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+            return WOLFSSL_FAILURE;
+        }
+        str_len += type_len;
+    }
+
+    if (flags & ASN1_STRFLGS_ESC_2253){
+        char esc_ch[] = "+;<>\\";
+        char* esc_ptr;
+
+        esc_ptr = str->data;
+        while (*esc_ptr != 0){
+            if (check_esc_char(*esc_ptr, esc_ch)){
+                if (wolfSSL_BIO_write(out,"\\", 1) != 1)
+                    goto err_exit;
+                str_len++;
+            }
+            if (wolfSSL_BIO_write(out, esc_ptr, 1) != 1)
+                goto err_exit;
+            str_len++;
+            esc_ptr++;
+        }
+        if (type_len > 0)
+            XFREE(typebuf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+        return (int)str_len;
+    }
+
+    if (wolfSSL_BIO_write(out, str->data, str->length) != str->length){
+        goto err_exit;
+    }
+    str_len += str->length;
+    if (type_len > 0)
+        XFREE(typebuf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+
+    return (int)str_len;
+
+err_exit:
+    if (type_len > 0)
+        XFREE(typebuf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    return WOLFSSL_FAILURE;
+}
+
+#if !defined(NO_ASN_TIME) && !defined(USER_TIME) && !defined(TIME_OVERRIDES)
+WOLFSSL_ASN1_TIME* wolfSSL_ASN1_TIME_new(void)
+{
+    WOLFSSL_ASN1_TIME* ret = (WOLFSSL_ASN1_TIME*)
+            XMALLOC(sizeof(WOLFSSL_ASN1_TIME), NULL, DYNAMIC_TYPE_OPENSSL);
+    if (!ret)
+        return NULL;
+    XMEMSET(ret, 0, sizeof(WOLFSSL_ASN1_TIME));
+    return ret;
+}
+
+void wolfSSL_ASN1_TIME_free(WOLFSSL_ASN1_TIME* t)
+{
+    if (t) {
+        XFREE(t, NULL, DYNAMIC_TYPE_OPENSSL);
+    }
+}
+
+WOLFSSL_ASN1_TIME* wolfSSL_ASN1_TIME_adj(WOLFSSL_ASN1_TIME *s, time_t t,
+                                    int offset_day, long offset_sec)
+{
+    const time_t sec_per_day = 24*60*60;
+    struct tm* ts = NULL;
+    struct tm* tmpTime;
+    time_t t_adj = 0;
+    time_t offset_day_sec = 0;
+#if defined(NEED_TMP_TIME)
+    struct tm tmpTimeStorage;
+
+    tmpTime = &tmpTimeStorage;
+#else
+    tmpTime = NULL;
+#endif
+    (void)tmpTime;
+
+    WOLFSSL_ENTER("wolfSSL_ASN1_TIME_adj");
+
+    if (s == NULL){
+        s = wolfSSL_ASN1_TIME_new();
+        if (s == NULL){
+            return NULL;
+        }
+    }
+
+    /* compute GMT time with offset */
+    offset_day_sec = offset_day * sec_per_day;
+    t_adj          = t + offset_day_sec + offset_sec;
+    ts             = (struct tm *)XGMTIME(&t_adj, tmpTime);
+    if (ts == NULL){
+        WOLFSSL_MSG("failed to get time data.");
+        XFREE(s, NULL, DYNAMIC_TYPE_OPENSSL);
+        return NULL;
+    }
+
+    /* create ASN1 time notation */
+    /* UTC Time */
+    if (ts->tm_year >= 50 && ts->tm_year < 150){
+        char utc_str[ASN_UTC_TIME_SIZE];
+        int utc_year = 0,utc_mon,utc_day,utc_hour,utc_min,utc_sec;
+
+        s->type = V_ASN1_UTCTIME;
+        s->length = ASN_UTC_TIME_SIZE;
+
+        if (ts->tm_year >= 50 && ts->tm_year < 100){
+            utc_year = ts->tm_year;
+        } else if (ts->tm_year >= 100 && ts->tm_year < 150){
+            utc_year = ts->tm_year - 100;
+        }
+        utc_mon  = ts->tm_mon + 1;
+        utc_day  = ts->tm_mday;
+        utc_hour = ts->tm_hour;
+        utc_min  = ts->tm_min;
+        utc_sec  = ts->tm_sec;
+        XSNPRINTF((char *)utc_str, sizeof(utc_str),
+                  "%02d%02d%02d%02d%02d%02dZ",
+                  utc_year, utc_mon, utc_day, utc_hour, utc_min, utc_sec);
+        XMEMCPY(s->data, (byte *)utc_str, s->length);
+    /* GeneralizedTime */
+    } else {
+        char gt_str[ASN_GENERALIZED_TIME_MAX];
+        int gt_year,gt_mon,gt_day,gt_hour,gt_min,gt_sec;
+
+        s->type = V_ASN1_GENERALIZEDTIME;
+        s->length = ASN_GENERALIZED_TIME_SIZE;
+
+        gt_year = ts->tm_year + 1900;
+        gt_mon  = ts->tm_mon + 1;
+        gt_day  = ts->tm_mday;
+        gt_hour = ts->tm_hour;
+        gt_min  = ts->tm_min;
+        gt_sec  = ts->tm_sec;
+        XSNPRINTF((char *)gt_str, sizeof(gt_str),
+                  "%4d%02d%02d%02d%02d%02dZ",
+                  gt_year, gt_mon, gt_day, gt_hour, gt_min,gt_sec);
+        XMEMCPY(s->data, (byte *)gt_str, s->length);
+    }
+
+    return s;
+}
+#endif /* !NO_ASN_TIME && !USER_TIME && !TIME_OVERRIDES */
+
+#ifndef NO_ASN_TIME
+/* not a compatibility function - length getter for opaque type */
+int wolfSSL_ASN1_TIME_get_length(WOLFSSL_ASN1_TIME *t)
+{
+    WOLFSSL_ENTER("wolfSSL_ASN1_TIME_get_length");
+    if (t == NULL)
+        return WOLFSSL_FAILURE;
+    return t->length;
+}
+/* not a compatibility function - data getter for opaque type */
+unsigned char* wolfSSL_ASN1_TIME_get_data(WOLFSSL_ASN1_TIME *t)
+{
+    WOLFSSL_ENTER("wolfSSL_ASN1_TIME_get_data");
+    if (t == NULL)
+        return NULL;
+    return t->data;
+}
+
+WOLFSSL_ASN1_TIME* wolfSSL_ASN1_TIME_to_generalizedtime(WOLFSSL_ASN1_TIME *t,
+                                                        WOLFSSL_ASN1_TIME **out)
+{
+    int time_type = 0;
+    WOLFSSL_ASN1_TIME *ret = NULL;
+
+    WOLFSSL_ENTER("wolfSSL_ASN1_TIME_to_generalizedtime");
+    if (t == NULL) {
+        WOLFSSL_MSG("Invalid ASN_TIME value");
+    } else {
+        time_type = t->type;
+        if (time_type != ASN_UTC_TIME && time_type != ASN_GENERALIZED_TIME){
+            WOLFSSL_MSG("Invalid ASN_TIME type.");
+        } else {
+            if (out == NULL || *out == NULL) {
+                ret = wolfSSL_ASN1_TIME_new();
+                if (ret == NULL){
+                    WOLFSSL_MSG("memory alloc failed.");
+                }
+            } else {
+                ret = *out;
+            }
+        }
+    }
+
+    if (ret != NULL) {
+        if (time_type == ASN_GENERALIZED_TIME){
+            XMEMCPY(ret->data, t->data, ASN_GENERALIZED_TIME_SIZE);
+        } else { /* ASN_UTC_TIME */
+            /* convert UTC to generalized time */
+            ret->type = ASN_GENERALIZED_TIME;
+            ret->length = ASN_GENERALIZED_TIME_SIZE;
+            if (t->data[0] >= '5') {
+                ret->data[0] = '1'; ret->data[1] = '9';
+            } else {
+                ret->data[0] = '2'; ret->data[1] = '0';
+            }
+            XMEMCPY(&ret->data[2], t->data, ASN_UTC_TIME_SIZE);
+        }
+    }
+
+    return ret;
+}
+#endif /* !NO_ASN_TIME */
+
+#ifndef NO_ASN
+int wolfSSL_i2c_ASN1_INTEGER(WOLFSSL_ASN1_INTEGER *a, unsigned char **pp)
+{
+    unsigned char *pptr = NULL;
+    char pad = 0 ;
+    unsigned char pad_val = 0;
+    int ret_size = 0;
+    unsigned char data1 = 0;
+    unsigned char neg = 0;
+    int i = 0;
+
+    WOLFSSL_ENTER("wolfSSL_i2c_ASN1_INTEGER");
+    if (a == NULL)
+        return WOLFSSL_FAILURE;
+
+    ret_size = a->intData[1];
+    if (ret_size == 0)
+        ret_size = 1;
+    else{
+        ret_size = (int)a->intData[1];
+        neg = a->negative;
+        data1 = a->intData[2];
+        if (ret_size == 1 && data1 == 0)
+            neg = 0;
+        /* 0x80 or greater positive number in first byte */
+        if (!neg && (data1 > 127)){
+            pad = 1;
+            pad_val = 0;
+        } else if (neg){
+            /* negative number */
+            if (data1 > 128){
+                pad = 1;
+                pad_val = 0xff;
+            } else if (data1 == 128){
+                for (i = 3; i < a->intData[1] + 2; i++){
+                    if (a->intData[i]){
+                        pad = 1;
+                        pad_val = 0xff;
+                        break;
+                    }
+                }
+            }
+        }
+        ret_size += (int)pad;
+    }
+    if (pp == NULL)
+        return ret_size;
+
+    pptr = *pp;
+    if (pad)
+        *(pptr++) = pad_val;
+    if (a->intData[1] == 0)
+        *(pptr++) = 0;
+    else if (!neg){
+        /* positive number */
+        for (i=0; i < a->intData[1]; i++){
+            *pptr = a->intData[i+2];
+            pptr++;
+        }
+    } else {
+        /* negative number */
+        int str_len = 0;
+
+        /* 0 padding from end of buffer */
+        str_len = (int)a->intData[1];
+        pptr += a->intData[1] - 1;
+        while (!a->intData[str_len + 2] && str_len > 1){
+            *(pptr--) = 0;
+            str_len--;
+        }
+        /* 2's complement next octet */
+        *(pptr--) = ((a->intData[str_len + 1]) ^ 0xff) + 1;
+        str_len--;
+        /* Complement any octets left */
+        while (str_len > 0){
+            *(pptr--) = a->intData[str_len + 1] ^ 0xff;
+            str_len--;
+        }
+    }
+    *pp += ret_size;
+    return ret_size;
+}
+#endif /* !NO_ASN */
+
+
+#ifndef NO_CERTS
+int wolfSSL_X509_CA_num(WOLFSSL_X509_STORE* store)
+{
+    int i = 0;
+    int cnt_ret = 0;
+    Signer **table;
+
+    WOLFSSL_ENTER("wolfSSL_X509_CA_num");
+    if (store == NULL || store->cm == NULL){
+        WOLFSSL_MSG("invalid parameter");
+        return WOLFSSL_FAILURE;
+    }
+
+    table = store->cm->caTable;
+    if (table){
+        if (wc_LockMutex(&store->cm->caLock) == 0){
+            for (i = 0; i < CA_TABLE_SIZE; i++) {
+                Signer* signer = table[i];
+                while (signer) {
+                    Signer* next = signer->next;
+                    cnt_ret++;
+                    signer = next;
+                }
+            }
+            wc_UnLockMutex(&store->cm->caLock);
+        }
+    }
+
+    return cnt_ret;
+}
+#endif /* !NO_CERTS */
+
+long wolfSSL_X509_get_version(const WOLFSSL_X509 *x509)
+{
+    int version = 0;
+
+    WOLFSSL_ENTER("wolfSSL_X509_get_version");
+
+    if (x509 == NULL){
+        WOLFSSL_MSG("invalid parameter");
+        return 0L;
+    }
+    version = x509->version;
+    if (version != 0)
+        return (long)version - 1L;
+
+    return 0L;
+}
+
+
+int wolfSSL_X509_get_signature_nid(const WOLFSSL_X509 *x)
+{
+    if (x == NULL)
+        return 0;
+
+    return oid2nid(x->sigOID, oidSigType);
+}
+#endif  /* OPENSSL_EXTRA */
+
+#if defined(OPENSSL_EXTRA) && !defined(NO_RSA)
+/* return compliant with OpenSSL
+ *   RSA modulus size in bytes, -1 if error
+ */
+int wolfSSL_RSA_size(const WOLFSSL_RSA* rsa)
+{
+    WOLFSSL_ENTER("wolfSSL_RSA_size");
+
+    if (rsa == NULL)
+        return WOLFSSL_FATAL_ERROR;
+    if (rsa->inSet == 0)
+    {
+        if (SetRsaInternal((WOLFSSL_RSA*)rsa) != SSL_SUCCESS) {
+            WOLFSSL_MSG("SetRsaInternal failed");
+            return 0;
+        }
+    }
+    return wc_RsaEncryptSize((RsaKey*)rsa->internal);
+}
+#endif
+
+#if !defined(HAVE_USER_RSA) && !defined(HAVE_FAST_RSA) && \
+    !defined(NO_RSA) && (defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL))
+/* WolfSSL -> OpenSSL */
+int SetRsaExternal(WOLFSSL_RSA* rsa)
+{
+    RsaKey* key;
+    WOLFSSL_MSG("Entering SetRsaExternal");
+
+    if (rsa == NULL || rsa->internal == NULL) {
+        WOLFSSL_MSG("rsa key NULL error");
+        return WOLFSSL_FATAL_ERROR;
+    }
+
+    key = (RsaKey*)rsa->internal;
+
+    if (SetIndividualExternal(&rsa->n, &key->n) != WOLFSSL_SUCCESS) {
+        WOLFSSL_MSG("rsa n key error");
+        return WOLFSSL_FATAL_ERROR;
+    }
+
+    if (SetIndividualExternal(&rsa->e, &key->e) != WOLFSSL_SUCCESS) {
+        WOLFSSL_MSG("rsa e key error");
+        return WOLFSSL_FATAL_ERROR;
+    }
+
+    if (key->type == RSA_PRIVATE) {
+        if (SetIndividualExternal(&rsa->d, &key->d) != WOLFSSL_SUCCESS) {
+            WOLFSSL_MSG("rsa d key error");
+            return WOLFSSL_FATAL_ERROR;
+        }
+
+        if (SetIndividualExternal(&rsa->p, &key->p) != WOLFSSL_SUCCESS) {
+            WOLFSSL_MSG("rsa p key error");
+            return WOLFSSL_FATAL_ERROR;
+        }
+
+        if (SetIndividualExternal(&rsa->q, &key->q) != WOLFSSL_SUCCESS) {
+            WOLFSSL_MSG("rsa q key error");
+            return WOLFSSL_FATAL_ERROR;
+        }
+
+    #ifndef RSA_LOW_MEM
+        if (SetIndividualExternal(&rsa->dmp1, &key->dP) != WOLFSSL_SUCCESS) {
+            WOLFSSL_MSG("rsa dP key error");
+            return WOLFSSL_FATAL_ERROR;
+        }
+
+        if (SetIndividualExternal(&rsa->dmq1, &key->dQ) != WOLFSSL_SUCCESS) {
+            WOLFSSL_MSG("rsa dQ key error");
+            return WOLFSSL_FATAL_ERROR;
+        }
+
+        if (SetIndividualExternal(&rsa->iqmp, &key->u) != WOLFSSL_SUCCESS) {
+            WOLFSSL_MSG("rsa u key error");
+            return WOLFSSL_FATAL_ERROR;
+        }
+    #endif /* !RSA_LOW_MEM */
+    }
+    rsa->exSet = 1;
+
+    return WOLFSSL_SUCCESS;
+}
+#endif
+#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
+/* when calling SetIndividualExternal, mpi should be cleared by caller if no
+ * longer used. ie mp_free(mpi). This is to free data when fastmath is
+ * disabled since a copy of mpi is made by this function and placed into bn.
+ */
+int SetIndividualExternal(WOLFSSL_BIGNUM** bn, mp_int* mpi)
+{
+    byte dynamic = 0;
+
+    WOLFSSL_MSG("Entering SetIndividualExternal");
+
+    if (mpi == NULL || bn == NULL) {
+        WOLFSSL_MSG("mpi NULL error");
+        return WOLFSSL_FATAL_ERROR;
+    }
+
+    if (*bn == NULL) {
+        *bn = wolfSSL_BN_new();
+        if (*bn == NULL) {
+            WOLFSSL_MSG("SetIndividualExternal alloc failed");
+            return WOLFSSL_FATAL_ERROR;
+        }
+        dynamic = 1;
+    }
+
+    if (mp_copy(mpi, (mp_int*)((*bn)->internal)) != MP_OKAY) {
+        WOLFSSL_MSG("mp_copy error");
+        if (dynamic == 1) {
+            wolfSSL_BN_free(*bn);
+        }
+        return WOLFSSL_FATAL_ERROR;
+    }
+
+    return WOLFSSL_SUCCESS;
+}
+
+
+static void InitwolfSSL_BigNum(WOLFSSL_BIGNUM* bn)
+{
+    if (bn) {
+        XMEMSET(bn, 0, sizeof(WOLFSSL_BIGNUM));
+        bn->neg      = 0;
+        bn->internal = NULL;
+    }
+}
+
+
+WOLFSSL_BIGNUM* wolfSSL_BN_new(void)
+{
+    WOLFSSL_BIGNUM* external;
+    mp_int*        mpi;
+
+    WOLFSSL_MSG("wolfSSL_BN_new");
+
+#if !defined(USE_FAST_MATH) || defined(HAVE_WOLF_BIGINT)
+    mpi = (mp_int*) XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_BIGINT);
+    if (mpi == NULL) {
+        WOLFSSL_MSG("wolfSSL_BN_new malloc mpi failure");
+        return NULL;
+    }
+#endif
+
+    external = (WOLFSSL_BIGNUM*) XMALLOC(sizeof(WOLFSSL_BIGNUM), NULL,
+                                        DYNAMIC_TYPE_BIGINT);
+    if (external == NULL) {
+        WOLFSSL_MSG("wolfSSL_BN_new malloc WOLFSSL_BIGNUM failure");
+#if !defined(USE_FAST_MATH) || defined(HAVE_WOLF_BIGINT)
+        XFREE(mpi, NULL, DYNAMIC_TYPE_BIGINT);
+#endif
+        return NULL;
+    }
+
+#if defined(USE_FAST_MATH) && !defined(HAVE_WOLF_BIGINT)
+    mpi = &external->fp;
+#endif
+
+    InitwolfSSL_BigNum(external);
+    if (mp_init(mpi) != MP_OKAY) {
+        wolfSSL_BN_free(external);
+        return NULL;
+    }
+    external->internal = mpi;
+
+    return external;
+}
+
+
+#if defined(USE_FAST_MATH) && !defined(HAVE_WOLF_BIGINT)
+/* This function works without BN_free only with TFM */
+void wolfSSL_BN_init(WOLFSSL_BIGNUM* bn)
+{
+    if(bn == NULL)return;
+    WOLFSSL_MSG("wolfSSL_BN_init");
+    InitwolfSSL_BigNum(bn);
+    if (mp_init(&bn->fp) != MP_OKAY)
+        return;
+    bn->internal = (void *)&bn->fp;
+}
+#endif
+
+void wolfSSL_BN_free(WOLFSSL_BIGNUM* bn)
+{
+    WOLFSSL_MSG("wolfSSL_BN_free");
+    if (bn) {
+        if (bn->internal) {
+            mp_int* bni = (mp_int*)bn->internal;
+            mp_free(bni);
+#if !defined(USE_FAST_MATH) || defined(HAVE_WOLF_BIGINT)
+            XFREE(bn->internal, NULL, DYNAMIC_TYPE_BIGINT);
+#endif
+            bn->internal = NULL;
+        }
+        XFREE(bn, NULL, DYNAMIC_TYPE_BIGINT);
+        /* bn = NULL, don't try to access or double free it */
+    }
+}
+
+void wolfSSL_BN_clear_free(WOLFSSL_BIGNUM* bn)
+{
+    WOLFSSL_MSG("wolfSSL_BN_clear_free");
+    if (bn) {
+        if (bn->internal) {
+            mp_int* bni = (mp_int*)bn->internal;
+            mp_forcezero(bni);
+        }
+        wolfSSL_BN_free(bn);
+    }
+}
+
+void wolfSSL_BN_clear(WOLFSSL_BIGNUM* bn)
+{
+    WOLFSSL_MSG("wolfSSL_BN_clear");
+    if (bn && bn->internal) {
+        mp_forcezero((mp_int*)bn->internal);
+    }
+}
+#endif /* OPENSSL_EXTRA || OPENSSL_EXTRA_X509_SMALL */
+
+#if !defined(NO_RSA) && (defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL))
+static void InitwolfSSL_Rsa(WOLFSSL_RSA* rsa)
+{
+    if (rsa) {
+        XMEMSET(rsa, 0, sizeof(WOLFSSL_RSA));
+    }
+}
+
+
+void wolfSSL_RSA_free(WOLFSSL_RSA* rsa)
+{
+    WOLFSSL_ENTER("wolfSSL_RSA_free");
+
+    if (rsa) {
+#if defined(OPENSSL_EXTRA) || defined(OPENSSL_ALL)
+        int doFree = 0;
+        if (wc_LockMutex(&rsa->refMutex) != 0) {
+            WOLFSSL_MSG("Couldn't lock rsa mutex");
+        }
+
+        /* only free if all references to it are done */
+        rsa->refCount--;
+        if (rsa->refCount == 0) {
+            doFree = 1;
+        }
+        wc_UnLockMutex(&rsa->refMutex);
+
+        if (!doFree) {
+            return;
+        }
+
+        wc_FreeMutex(&rsa->refMutex);
+#endif
+
+        if (rsa->internal) {
+#if !defined(HAVE_FIPS) && !defined(HAVE_USER_RSA) && \
+    !defined(HAVE_FAST_RSA) && defined(WC_RSA_BLINDING)
+            WC_RNG* rng;
+
+            /* check if RNG is owned before freeing it */
+            if (rsa->ownRng) {
+                rng = ((RsaKey*)rsa->internal)->rng;
+                if (rng != NULL && rng != &globalRNG) {
+                    wc_FreeRng(rng);
+                    XFREE(rng, NULL, DYNAMIC_TYPE_RNG);
+                }
+            }
+#endif /* WC_RSA_BLINDING */
+            wc_FreeRsaKey((RsaKey*)rsa->internal);
+            XFREE(rsa->internal, NULL, DYNAMIC_TYPE_RSA);
+            rsa->internal = NULL;
+        }
+        wolfSSL_BN_free(rsa->iqmp);
+        wolfSSL_BN_free(rsa->dmq1);
+        wolfSSL_BN_free(rsa->dmp1);
+        wolfSSL_BN_free(rsa->q);
+        wolfSSL_BN_free(rsa->p);
+        wolfSSL_BN_free(rsa->d);
+        wolfSSL_BN_free(rsa->e);
+        wolfSSL_BN_free(rsa->n);
+
+    #ifdef WC_RSA_BLINDING
+        if (rsa->rng && wc_FreeRng(rsa->rng) != 0) {
+            WOLFSSL_MSG("Issue freeing rng");
+        }
+        XFREE(rsa->rng, NULL, DYNAMIC_TYPE_RNG);
+    #endif
+
+#if defined(OPENSSL_EXTRA) && !defined(WOLFCRYPT_ONLY)
+        if (rsa->meth) {
+            wolfSSL_RSA_meth_free(rsa->meth);
+        }
+#endif
+
+        InitwolfSSL_Rsa(rsa);  /* set back to NULLs for safety */
+
+        XFREE(rsa, NULL, DYNAMIC_TYPE_RSA);
+
+        /* rsa = NULL, don't try to access or double free it */
+    }
+}
+
+WOLFSSL_RSA* wolfSSL_RSA_new(void)
+{
+    WOLFSSL_RSA* external;
+    RsaKey*     key;
+
+    WOLFSSL_ENTER("wolfSSL_RSA_new");
+
+    key = (RsaKey*) XMALLOC(sizeof(RsaKey), NULL, DYNAMIC_TYPE_RSA);
+    if (key == NULL) {
+        WOLFSSL_MSG("wolfSSL_RSA_new malloc RsaKey failure");
+        return NULL;
+    }
+
+    external = (WOLFSSL_RSA*) XMALLOC(sizeof(WOLFSSL_RSA), NULL,
+                                     DYNAMIC_TYPE_RSA);
+    if (external == NULL) {
+        WOLFSSL_MSG("wolfSSL_RSA_new malloc WOLFSSL_RSA failure");
+        XFREE(key, NULL, DYNAMIC_TYPE_RSA);
+        return NULL;
+    }
+
+    InitwolfSSL_Rsa(external);
+    if (wc_InitRsaKey(key, NULL) != 0) {
+        WOLFSSL_MSG("InitRsaKey WOLFSSL_RSA failure");
+        XFREE(external, NULL, DYNAMIC_TYPE_RSA);
+        XFREE(key, NULL, DYNAMIC_TYPE_RSA);
+        return NULL;
+    }
+
+#if !defined(HAVE_FIPS) && !defined(HAVE_USER_RSA) && \
+    !defined(HAVE_FAST_RSA) && defined(WC_RSA_BLINDING)
+    {
+        WC_RNG* rng;
+
+        rng = (WC_RNG*) XMALLOC(sizeof(WC_RNG), NULL, DYNAMIC_TYPE_RNG);
+        if (rng != NULL && wc_InitRng(rng) != 0) {
+            WOLFSSL_MSG("InitRng failure, attempting to use global RNG");
+            XFREE(rng, NULL, DYNAMIC_TYPE_RNG);
+            rng = NULL;
+        }
+
+        external->ownRng = 1;
+        if (rng == NULL && initGlobalRNG) {
+            external->ownRng = 0;
+            rng = &globalRNG;
+        }
+
+        if (rng == NULL) {
+            WOLFSSL_MSG("wolfSSL_RSA_new no WC_RNG for blinding");
+            XFREE(external, NULL, DYNAMIC_TYPE_RSA);
+            XFREE(key, NULL, DYNAMIC_TYPE_RSA);
+            return NULL;
+        }
+
+        wc_RsaSetRNG(key, rng);
+    }
+#else
+    XMEMSET(key, 0, sizeof(RsaKey));
+#endif /* WC_RSA_BLINDING */
+
+    external->internal = key;
+    external->inSet = 0;
+#if defined(OPENSSL_EXTRA) || defined(OPENSSL_ALL)
+    external->refCount = 1;
+    wc_InitMutex(&external->refMutex);
+#endif
+    return external;
+}
+#endif /* !NO_RSA && (OPENSSL_EXTRA || OPENSSL_EXTRA_X509_SMALL) */
+
+#if defined(OPENSSL_ALL) && defined(HAVE_PKCS7)
+PKCS7* wolfSSL_PKCS7_new(void)
+{
+    WOLFSSL_PKCS7* pkcs7;
+    int ret = 0;
+
+    pkcs7 = (WOLFSSL_PKCS7*)XMALLOC(sizeof(*pkcs7), NULL, DYNAMIC_TYPE_PKCS7);
+    if (pkcs7 != NULL) {
+        XMEMSET(pkcs7, 0, sizeof(*pkcs7));
+        ret = wc_PKCS7_Init(&pkcs7->pkcs7, NULL, INVALID_DEVID);
+    }
+
+    if (ret != 0 && pkcs7 != NULL)
+        XFREE(pkcs7, NULL, DYNAMIC_TYPE_PKCS7);
+
+    return (PKCS7*)pkcs7;
+}
+/******************************************************************************
+* wolfSSL_PKCS7_SIGNED_new - allocates PKCS7 and initialize it for a signed data
+*
+* RETURNS:
+* returns pointer to the PKCS7 structure on success, otherwise returns NULL
+*/
+PKCS7_SIGNED* wolfSSL_PKCS7_SIGNED_new(void)
+{
+    byte signedData[]= { 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x07, 0x02};
+    PKCS7* pkcs7 = NULL;
+
+    if ((pkcs7 = wolfSSL_PKCS7_new()) == NULL)
+        return NULL;
+    pkcs7->contentOID = SIGNED_DATA;
+    if ((wc_PKCS7_SetContentType(pkcs7, signedData, sizeof(signedData))) < 0) {
+        if (pkcs7) {
+            wolfSSL_PKCS7_free(pkcs7);
+            return NULL;
+        }
+    }
+    return pkcs7;
+}
+
+void wolfSSL_PKCS7_free(PKCS7* pkcs7)
+{
+    WOLFSSL_PKCS7* p7 = (WOLFSSL_PKCS7*)pkcs7;
+
+    if (p7 != NULL) {
+        if (p7->data != NULL)
+            XFREE(p7->data, NULL, DYNAMIC_TYPE_PKCS7);
+        wc_PKCS7_Free(&p7->pkcs7);
+        XFREE(p7, NULL, DYNAMIC_TYPE_PKCS7);
+    }
+}
+void wolfSSL_PKCS7_SIGNED_free(PKCS7_SIGNED* p7)
+{
+    wolfSSL_PKCS7_free(p7);
+    return;
+}
+PKCS7* wolfSSL_d2i_PKCS7(PKCS7** p7, const unsigned char** in, int len)
+{
+    WOLFSSL_PKCS7* pkcs7 = NULL;
+    word32 idx = 0;
+
+    if (in == NULL)
+        return NULL;
+
+    if ((pkcs7 = (WOLFSSL_PKCS7*)wolfSSL_PKCS7_new()) == NULL)
+        return NULL;
+
+    if (GetSequence(*in, &idx, &pkcs7->len, len) < 0) {
+        wolfSSL_PKCS7_free((PKCS7*)pkcs7);
+        return NULL;
+    }
+    pkcs7->len += idx;
+
+    pkcs7->data = (byte*)XMALLOC(pkcs7->len, NULL, DYNAMIC_TYPE_PKCS7);
+    if (pkcs7->data == NULL) {
+        wolfSSL_PKCS7_free((PKCS7*)pkcs7);
+        return NULL;
+    }
+    XMEMCPY(pkcs7->data, *in, pkcs7->len);
+    *in += pkcs7->len;
+
+    if (p7 != NULL)
+        *p7 = (PKCS7*)pkcs7;
+    return (PKCS7*)pkcs7;
+}
+
+PKCS7* wolfSSL_d2i_PKCS7_bio(WOLFSSL_BIO* bio, PKCS7** p7)
+{
+    WOLFSSL_PKCS7* pkcs7;
+
+    if (bio == NULL)
+        return NULL;
+
+    if ((pkcs7 = (WOLFSSL_PKCS7*)wolfSSL_PKCS7_new()) == NULL)
+        return NULL;
+
+    pkcs7->len = wolfSSL_BIO_pending(bio);
+    pkcs7->data = (byte*)XMALLOC(pkcs7->len, NULL, DYNAMIC_TYPE_PKCS7);
+    if (pkcs7->data == NULL) {
+        wolfSSL_PKCS7_free((PKCS7*)pkcs7);
+        return NULL;
+    }
+
+    if (wolfSSL_BIO_read(bio, pkcs7->data, pkcs7->len) != pkcs7->len) {
+        wolfSSL_PKCS7_free((PKCS7*)pkcs7);
+        return NULL;
+    }
+
+    if (p7 != NULL)
+        *p7 = (PKCS7*)pkcs7;
+    return (PKCS7*)pkcs7;
+}
+
+int wolfSSL_PKCS7_verify(PKCS7* pkcs7, WOLFSSL_STACK* certs,
+                         WOLFSSL_X509_STORE* store, WOLFSSL_BIO* in,
+                         WOLFSSL_BIO* out, int flags)
+{
+    int ret = 0;
+    unsigned char* mem = NULL;
+    int memSz = 0;
+    WOLFSSL_PKCS7* p7 = (WOLFSSL_PKCS7*)pkcs7;
+
+    if (pkcs7 == NULL)
+        return WOLFSSL_FAILURE;
+
+    if (in != NULL) {
+        if ((memSz = wolfSSL_BIO_get_mem_data(in, &mem)) < 0)
+            return WOLFSSL_FAILURE;
+
+        p7->pkcs7.content = mem;
+        p7->pkcs7.contentSz = memSz;
+    }
+
+    /* certs is the list of certificates to find the cert with issuer/serial. */
+    (void)certs;
+    /* store is the certificate store to use to verify signer certificate
+     * associated with the signers.
+     */
+    (void)store;
+
+    ret = wc_PKCS7_VerifySignedData_ex(&p7->pkcs7, NULL, 0, p7->data, p7->len,
+                                                                       NULL, 0);
+    if (ret != 0)
+        return WOLFSSL_FAILURE;
+
+    if ((flags & PKCS7_NOVERIFY) != PKCS7_NOVERIFY) {
+        /* All signer certificates are verified. */
+        return WOLFSSL_FAILURE;
+    }
+
+    if (out != NULL)
+       wolfSSL_BIO_write(out, p7->pkcs7.content, p7->pkcs7.contentSz);
+
+    return WOLFSSL_SUCCESS;
+}
+
+WOLFSSL_STACK* wolfSSL_PKCS7_get0_signers(PKCS7* pkcs7, WOLFSSL_STACK* certs,
+                                          int flags)
+{
+    WOLFSSL_STACK* signers = NULL;
+    WOLFSSL_PKCS7* p7 = (WOLFSSL_PKCS7*)pkcs7;
+
+    if (p7 == NULL)
+        return NULL;
+    /* Only PKCS#7 messages with a single cert that is the verifying certificate
+     * is supported.
+     */
+    if ((flags | PKCS7_NOINTERN) == PKCS7_NOINTERN)
+        return NULL;
+
+    signers = (WOLFSSL_STACK*)XMALLOC(sizeof(WOLFSSL_STACK), NULL,
+                                                             DYNAMIC_TYPE_X509);
+    if (signers == NULL)
+        return NULL;
+
+    signers->num = 1;
+    signers->data.x509 = (WOLFSSL_X509*)XMALLOC(sizeof(WOLFSSL_X509), NULL,
+                                                             DYNAMIC_TYPE_X509);
+    if (signers->data.x509 == NULL) {
+        XFREE(signers, NULL, DYNAMIC_TYPE_X509);
+        return NULL;
+    }
+
+    if (DecodeToX509(signers->data.x509, p7->pkcs7.singleCert,
+                                                 p7->pkcs7.singleCertSz) != 0) {
+        XFREE(signers->data.x509, NULL, DYNAMIC_TYPE_X509);
+        XFREE(signers, NULL, DYNAMIC_TYPE_X509);
+        return NULL;
+    }
+
+    (void)certs;
+
+    return signers;
+}
+
+/******************************************************************************
+* wolfSSL_PEM_write_bio_PKCS7 - writes the PKCS7 data to BIO
+*
+* RETURNS:
+* returns WOLFSSL_SUCCESS on success, otherwise returns WOLFSSL_FAILURE
+*/
+
+int wolfSSL_PEM_write_bio_PKCS7(WOLFSSL_BIO* bio, PKCS7* p7)
+{
+#ifdef WOLFSSL_SMALL_STACK
+    byte* outputHead;
+    byte* outputFoot;
+#else
+    byte outputHead[2048];
+    byte outputFoot[2048];
+#endif
+    word32 outputHeadSz = 2048;
+    word32 outputFootSz = 2048;
+    word32 outputSz = 0;
+    byte*  output = NULL;
+    byte*  pem = NULL;
+    int    pemSz = -1;
+    enum wc_HashType hashType;
+    byte hashBuf[WC_MAX_DIGEST_SIZE];
+    word32 hashSz = -1;
+
+    WOLFSSL_ENTER("wolfSSL_PEM_write_bio_PKCS7()");
+
+    if (bio == NULL || p7 == NULL)
+        return WOLFSSL_FAILURE;
+
+#ifdef WOLFSSL_SMALL_STACK
+    outputHead = (byte*)XMALLOC(outputHeadSz, bio->heap, DYNAMIC_TYPE_TMP_BUFFER);
+    if (outputHead == NULL)
+        return MEMORY_E;
+
+    outputFoot = (byte*)XMALLOC(outputFootSz, bio->heap, DYNAMIC_TYPE_TMP_BUFFER);
+    if (outputFoot == NULL)
+        goto error;
+
+#endif
+
+    XMEMSET(hashBuf, 0, WC_MAX_DIGEST_SIZE);
+    XMEMSET(outputHead, 0, outputHeadSz);
+    XMEMSET(outputFoot, 0, outputFootSz);
+
+    hashType = wc_OidGetHash(p7->hashOID);
+    hashSz = wc_HashGetDigestSize(hashType);
+    if (hashSz > WC_MAX_DIGEST_SIZE)
+        return WOLFSSL_FAILURE;
+
+    /* only SIGNED_DATA is supported */
+    switch (p7->contentOID) {
+        case SIGNED_DATA:
+            break;
+        default:
+            WOLFSSL_MSG("Unknown PKCS#7 Type");
+            return WOLFSSL_FAILURE;
+    };
+
+    if ((wc_PKCS7_EncodeSignedData_ex(p7, hashBuf, hashSz,
+        outputHead, &outputHeadSz, outputFoot, &outputFootSz)) != 0)
+        return WOLFSSL_FAILURE;
+
+    outputSz = outputHeadSz + p7->contentSz + outputFootSz;
+    output = (byte*)XMALLOC(outputSz, bio->heap, DYNAMIC_TYPE_TMP_BUFFER);
+
+    if (!output)
+         return WOLFSSL_FAILURE;
+
+    XMEMSET(output, 0, outputSz);
+    outputSz = 0;
+    XMEMCPY(&output[outputSz], outputHead, outputHeadSz);
+    outputSz += outputHeadSz;
+    XMEMCPY(&output[outputSz], p7->content, p7->contentSz);
+    outputSz += p7->contentSz;
+    XMEMCPY(&output[outputSz], outputFoot, outputFootSz);
+    outputSz += outputFootSz;
+
+    /* get PEM size */
+    pemSz = wc_DerToPemEx(output, outputSz, NULL, 0, NULL, CERT_TYPE);
+    if (pemSz < 0)
+        goto error;
+
+    pemSz++; /* for '\0'*/
+
+    /* create PEM buffer and convert from DER to PEM*/
+    if ((pem = (byte*)XMALLOC(pemSz, bio->heap, DYNAMIC_TYPE_TMP_BUFFER)) == NULL)
+        goto error;
+
+    XMEMSET(pem, 0, pemSz);
+
+    if (wc_DerToPemEx(output, outputSz, pem, pemSz, NULL, CERT_TYPE) < 0) {
+        goto error;
+    }
+    if ((wolfSSL_BIO_write(bio, pem, pemSz) == pemSz)) {
+        XFREE(output, bio->heap, DYNAMIC_TYPE_TMP_BUFFER);
+        XFREE(pem, bio->heap, DYNAMIC_TYPE_TMP_BUFFER);
+#ifdef WOLFSSL_SMALL_STACK
+        XFREE(outputHead, bio->heap, DYNAMIC_TYPE_TMP_BUFFER);
+        XFREE(outputFoot, bio->heap, DYNAMIC_TYPE_TMP_BUFFER);
+#endif
+        return WOLFSSL_SUCCESS;
+    }
+
+error:
+#ifdef WOLFSSL_SMALL_STACK
+    if (outputHead) {
+        XFREE(outputHead, bio->heap, DYNAMIC_TYPE_TMP_BUFFER);
+    }
+    if (outputFoot) {
+        XFREE(outputFoot, bio->heap, DYNAMIC_TYPE_TMP_BUFFER);
+    }
+#endif
+    if (output) {
+        XFREE(output, bio->heap, DYNAMIC_TYPE_TMP_BUFFER);
+    }
+    if (pem) {
+        XFREE(pem, bio->heap, DYNAMIC_TYPE_TMP_BUFFER);
+    }
+    return WOLFSSL_FAILURE;
+}
+#endif /* OPENSSL_ALL && HAVE_PKCS7 */
+
+#if defined(OPENSSL_EXTRA)
+WOLFSSL_STACK* wolfSSL_sk_X509_new(void)
+{
+    WOLFSSL_STACK* s = (WOLFSSL_STACK*)XMALLOC(sizeof(WOLFSSL_STACK), NULL,
+                                                             DYNAMIC_TYPE_X509);
+    if (s != NULL) {
+        XMEMSET(s, 0, sizeof(*s));
+        s->type = STACK_TYPE_X509;
+    }
+
+    return s;
+}
+#endif
+
+#ifdef OPENSSL_ALL
+int wolfSSL_PEM_write_bio_PKCS8PrivateKey(WOLFSSL_BIO* bio,
+                                          WOLFSSL_EVP_PKEY* pkey,
+                                          const WOLFSSL_EVP_CIPHER* enc,
+                                          char* passwd, int passwdSz,
+                                          pem_password_cb* cb, void* ctx)
+{
+    int ret = 0;
+    char password[NAME_SZ];
+    byte* key = NULL;
+    word32 keySz;
+    byte* pem = NULL;
+    int pemSz;
+    int type = PKCS8_PRIVATEKEY_TYPE;
+    int algId;
+    const byte* curveOid;
+    word32 oidSz;
+    int encAlgId;
+
+    if (bio == NULL || pkey == NULL)
+        return -1;
+
+    keySz = pkey->pkey_sz + 128;
+    key = (byte*)XMALLOC(keySz, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    if (key == NULL)
+        ret = MEMORY_E;
+
+    if (ret == 0 && enc != NULL && passwd == NULL) {
+        passwdSz = cb(password, sizeof(password), 1, ctx);
+        if (passwdSz < 0)
+            ret = WOLFSSL_FAILURE;
+        passwd = password;
+    }
+
+    if (ret == 0 && enc != NULL) {
+        WC_RNG rng;
+        ret = wc_InitRng(&rng);
+        if (ret == 0) {
+        #ifndef NO_DES3
+            if (enc == EVP_DES_CBC)
+                encAlgId = DESb;
+            else if (enc == EVP_DES_EDE3_CBC)
+                encAlgId = DES3b;
+            else
+        #endif
+        #if !defined(NO_AES) && defined(HAVE_AES_CBC)
+            #ifdef WOLFSSL_AES_256
+            if (enc == EVP_AES_256_CBC)
+                encAlgId = AES256CBCb;
+            else
+            #endif
+        #endif
+                ret = -1;
+            if (ret == 0) {
+                ret = TraditionalEnc((byte*)pkey->pkey.ptr, pkey->pkey_sz, key,
+                                       &keySz, passwd, passwdSz, PKCS5, PBES2,
+                                       encAlgId, NULL, 0, WC_PKCS12_ITT_DEFAULT,
+                                       &rng, NULL);
+                if (ret > 0) {
+                    keySz = ret;
+                    ret = 0;
+                }
+            }
+            wc_FreeRng(&rng);
+        }
+        type = PKCS8_ENC_PRIVATEKEY_TYPE;
+    }
+    if (ret == 0 && enc == NULL) {
+        type = PKCS8_PRIVATEKEY_TYPE;
+        if (pkey->type == EVP_PKEY_EC) {
+            algId = ECDSAk;
+            ret = wc_ecc_get_oid(pkey->ecc->group->curve_oid, &curveOid,
+                                                                        &oidSz);
+        }
+        else {
+            algId = RSAk;
+            curveOid = NULL;
+            oidSz = 0;
+        }
+
+        if (ret >= 0) {
+            ret = wc_CreatePKCS8Key(key, &keySz, (byte*)pkey->pkey.ptr,
+                                         pkey->pkey_sz, algId, curveOid, oidSz);
+            keySz = ret;
+        }
+    }
+
+    if (password == passwd)
+        XMEMSET(password, 0, passwdSz);
+
+    if (ret >= 0) {
+        pemSz = 2 * keySz + 2 * 64;
+        pem = (byte*)XMALLOC(pemSz, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+        if (pem == NULL)
+            ret = MEMORY_E;
+    }
+
+    if (ret >= 0)
+        ret = wc_DerToPemEx(key, keySz, pem, pemSz, NULL, type);
+
+    if (key != NULL)
+        XFREE(key, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+
+    if (ret >= 0) {
+        if (wolfSSL_BIO_write(bio, pem, ret) != ret)
+            ret = -1;
+    }
+
+    if (pem != NULL)
+        XFREE(pem, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+
+    return ret < 0 ? 0 : ret;
+
+}
+
+static int bio_get_data(WOLFSSL_BIO* bio, byte** data)
+{
+    int ret = 0;
+    byte* mem = NULL;
+#ifndef NO_FILESYSTEM
+    long memSz;
+    XFILE file;
+    long curr;
+#endif
+
+    if ((ret = wolfSSL_BIO_pending(bio)) > 0) {
+    }
+#ifndef NO_FILESYSTEM
+    else if (bio->type == WOLFSSL_BIO_FILE) {
+        if (wolfSSL_BIO_get_fp(bio, &file) != WOLFSSL_SUCCESS)
+            ret = BAD_FUNC_ARG;
+        if (ret == 0) {
+            curr = XFTELL(file);
+            if (curr < 0) {
+                ret = WOLFSSL_BAD_FILE;
+            }
+            if (XFSEEK(file, 0, XSEEK_END) != 0)
+                ret = WOLFSSL_BAD_FILE;
+        }
+        if (ret == 0) {
+            memSz = XFTELL(file);
+            if (memSz > MAX_WOLFSSL_FILE_SIZE || memSz < 0) {
+                ret = WOLFSSL_BAD_FILE;
+            }
+        }
+        if (ret == 0) {
+            memSz -= curr;
+            ret = (int)memSz;
+            if (XFSEEK(file, curr, SEEK_SET) != 0)
+                ret = WOLFSSL_BAD_FILE;
+        }
+    }
+#endif
+
+    if (ret > 0) {
+        mem = (byte*)XMALLOC(ret, bio->heap, DYNAMIC_TYPE_OPENSSL);
+        if (mem == NULL) {
+            WOLFSSL_MSG("Memory error");
+            ret = MEMORY_E;
+        }
+        if (ret >= 0) {
+            if ((ret = wolfSSL_BIO_read(bio, mem, ret)) <= 0) {
+                XFREE(mem, bio->heap, DYNAMIC_TYPE_OPENSSL);
+                ret = MEMORY_E;
+                mem = NULL;
+            }
+        }
+    }
+
+    *data = mem;
+
+    return ret;
+}
+
+#ifndef NO_WOLFSSL_STUB
+void wolfSSL_BIO_set_init(WOLFSSL_BIO* bio, int init)
+{
+    WOLFSSL_STUB("wolfSSL_BIO_set_init");
+    (void)bio;
+    (void)init;
+}
+
+void wolfSSL_BIO_set_shutdown(WOLFSSL_BIO* bio, int shut)
+{
+    WOLFSSL_STUB("wolfSSL_BIO_set_shutdown");
+    (void)bio;
+    (void)shut;
+
+}
+int wolfSSL_BIO_get_shutdown(WOLFSSL_BIO* bio)
+{
+    WOLFSSL_STUB("wolfSSL_BIO_get_shutdown");
+    (void)bio;
+    return 0;
+}
+#endif /* NO_WOLFSSL_STUB */
+
+void wolfSSL_BIO_clear_retry_flags(WOLFSSL_BIO* bio)
+{
+    WOLFSSL_ENTER("wolfSSL_BIO_clear_retry_flags");
+
+    if (bio)
+        bio->flags &= ~(WOLFSSL_BIO_FLAG_READ|WOLFSSL_BIO_FLAG_RETRY);
+}
+
+int wolfSSL_BIO_should_retry(WOLFSSL_BIO *bio)
+{
+    int ret = 0;
+    if (bio != NULL) {
+        ret = (int)(bio->flags & WOLFSSL_BIO_FLAG_RETRY);
+    }
+
+    return ret;
+}
+
+/* DER data is PKCS#8 encrypted. */
+WOLFSSL_EVP_PKEY* wolfSSL_d2i_PKCS8PrivateKey_bio(WOLFSSL_BIO* bio,
+                                                  WOLFSSL_EVP_PKEY** pkey,
+                                                  pem_password_cb* cb,
+                                                  void* ctx)
+{
+    int ret;
+    byte* der;
+    int len;
+    byte* p;
+    char password[NAME_SZ];
+    int passwordSz;
+    word32 algId;
+    WOLFSSL_EVP_PKEY* key;
+
+    if ((len = bio_get_data(bio, &der)) < 0)
+        return NULL;
+
+    if (cb != NULL) {
+        passwordSz = cb(password, sizeof(password), PEM_PASS_READ, ctx);
+        if (passwordSz < 0) {
+            XFREE(der, bio->heap, DYNAMIC_TYPE_OPENSSL);
+            return NULL;
+        }
+
+        ret = ToTraditionalEnc(der, len, password, passwordSz, &algId);
+        if (ret < 0) {
+            XFREE(der, bio->heap, DYNAMIC_TYPE_OPENSSL);
+            return NULL;
+        }
+
+        XMEMSET(password, 0, passwordSz);
+    }
+
+    p = der;
+    key = wolfSSL_d2i_PrivateKey_EVP(pkey, &p, len);
+    XFREE(der, bio->heap, DYNAMIC_TYPE_OPENSSL);
+    return key;
+}
+
+/* Detect which type of key it is before decoding. */
+WOLFSSL_EVP_PKEY* wolfSSL_d2i_AutoPrivateKey(WOLFSSL_EVP_PKEY** pkey,
+                                             const unsigned char** pp,
+                                             long length)
+{
+    int ret;
+    WOLFSSL_EVP_PKEY* key = NULL;
+    const byte* der = *pp;
+    word32 idx = 0;
+    int len = 0;
+    word32 end = 0;
+    int cnt = 0;
+    int type;
+    word32 algId;
+    word32 keyLen = (word32)length;
+
+    /* Take off PKCS#8 wrapper if found. */
+    if ((len = ToTraditionalInline_ex(der, &idx, keyLen, &algId)) >= 0) {
+        der += idx;
+        keyLen = len;
+    }
+    idx = 0;
+    len = 0;
+
+    /* Use the number of elements in the outer sequence to determine key type.
+     */
+    ret = GetSequence(der, &idx, &len, keyLen);
+    if (ret >= 0) {
+        end = idx + len;
+        while (ret >= 0 && idx < end) {
+            /* Skip type */
+            idx++;
+            /* Get length and skip over - keeping count */
+            len = 0;
+            ret = GetLength(der, &idx, &len, keyLen);
+            if (ret >= 0) {
+                if (idx + len > end)
+                    ret = ASN_PARSE_E;
+                else {
+                    idx += len;
+                    cnt++;
+                }
+            }
+        }
+    }
+
+    if (ret >= 0) {
+        /* ECC includes version, private[, curve][, public key] */
+        if (cnt >= 2 && cnt <= 4)
+            type = EVP_PKEY_EC;
+        else
+            type = EVP_PKEY_RSA;
+
+        key = wolfSSL_d2i_PrivateKey(type, pkey, &der, keyLen);
+        *pp = der;
+    }
+
+    return key;
+}
+#endif
+
+#if defined(OPENSSL_EXTRA) && !defined(NO_CERTS) && \
+    defined(WOLFSSL_CERT_GEN) && defined(WOLFSSL_CERT_REQ)
+int wolfSSL_X509_set_subject_name(WOLFSSL_X509 *cert, WOLFSSL_X509_NAME *name)
+{
+    int i;
+    WOLFSSL_X509_NAME_ENTRY* ne;
+
+    WOLFSSL_ENTER("X509_set_subject_name");
+    if (cert == NULL || name == NULL)
+        return WOLFSSL_FAILURE;
+
+    FreeX509Name(&cert->subject, cert->heap);
+    InitX509Name(&cert->subject, 0);
+    if (name->dynamicName) {
+        cert->subject.name = (char*)XMALLOC(name->sz, cert->heap,
+                                                       DYNAMIC_TYPE_SUBJECT_CN);
+        if (cert->subject.name == NULL)
+            return WOLFSSL_FAILURE;
+    }
+    XMEMCPY(cert->subject.name, name->name, name->sz);
+    cert->subject.sz = name->sz;
+
+    for (i = 0; i < 10; i++) {
+        ne = wolfSSL_X509_NAME_get_entry(name, i);
+        if (ne != NULL)
+            wolfSSL_X509_NAME_add_entry(&cert->subject, ne, i, 1);
+    }
+    cert->subject.x509 = cert;
+    cert->subject.name = cert->subject.fullName.fullName;
+    cert->subject.sz = cert->subject.fullName.fullNameLen;
+
+    return WOLFSSL_SUCCESS;
+}
+
+int wolfSSL_X509_set_issuer_name(WOLFSSL_X509 *cert, WOLFSSL_X509_NAME *name)
+{
+    int i;
+    WOLFSSL_X509_NAME_ENTRY* ne;
+
+    WOLFSSL_ENTER("X509_set_issuer_name");
+    if (cert == NULL || name == NULL)
+        return WOLFSSL_FAILURE;
+
+    FreeX509Name(&cert->issuer, cert->heap);
+    InitX509Name(&cert->issuer, 0);
+    if (name->dynamicName) {
+        cert->issuer.name = (char*)XMALLOC(name->sz, cert->heap,
+                                                       DYNAMIC_TYPE_SUBJECT_CN);
+        if (cert->issuer.name == NULL)
+            return WOLFSSL_FAILURE;
+    }
+    XMEMCPY(cert->issuer.name, name->name, name->sz);
+    cert->issuer.sz = name->sz;
+
+    for (i = 0; i < 10; i++) {
+        ne = wolfSSL_X509_NAME_get_entry(name, i);
+        if (ne != NULL)
+            wolfSSL_X509_NAME_add_entry(&cert->issuer, ne, i, 1);
+    }
+    cert->issuer.x509 = cert;
+    cert->issuer.name = cert->issuer.fullName.fullName;
+    cert->issuer.sz = cert->issuer.fullName.fullNameLen;
+    cert->issuerSet = 1;
+
+    return WOLFSSL_SUCCESS;
+}
+
+int wolfSSL_X509_set_notAfter(WOLFSSL_X509* x509, const WOLFSSL_ASN1_TIME* t)
+{
+    if (x509 == NULL || t == NULL) {
+        return WOLFSSL_FAILURE;
+    }
+
+    XMEMCPY(&x509->notAfter, t, sizeof(WOLFSSL_ASN1_TIME));
+
+    return WOLFSSL_SUCCESS;
+}
+
+int wolfSSL_X509_set_notBefore(WOLFSSL_X509* x509, const WOLFSSL_ASN1_TIME* t)
+{
+    if (x509 == NULL || t == NULL) {
+        return WOLFSSL_FAILURE;
+    }
+
+    XMEMCPY(&x509->notBefore, t, sizeof(WOLFSSL_ASN1_TIME));
+
+    return WOLFSSL_SUCCESS;
+}
+
+int wolfSSL_X509_set_serialNumber(WOLFSSL_X509* x509, WOLFSSL_ASN1_INTEGER* s)
+{
+    WOLFSSL_ENTER("wolfSSL_X509_set_serialNumber");
+    if (!x509 || !s || s->dataMax >= EXTERNAL_SERIAL_SIZE)
+        return WOLFSSL_FAILURE;
+
+    if (s->isDynamic)
+        XSTRNCPY((char*)x509->serial,(char*)s->data,s->dataMax);
+    else
+        XSTRNCPY((char*)x509->serial,(char*)s->intData,s->dataMax);
+
+    x509->serial[s->dataMax] = 0;
+    x509->serialSz = s->dataMax;
+
+    return WOLFSSL_SUCCESS;
+}
+
+
+int wolfSSL_X509_set_pubkey(WOLFSSL_X509 *cert, WOLFSSL_EVP_PKEY *pkey)
+{
+    byte* p;
+    WOLFSSL_ENTER("wolfSSL_X509_set_pubkey");
+
+    if (cert == NULL || pkey == NULL)
+        return WOLFSSL_FAILURE;
+
+    if (pkey->type == EVP_PKEY_RSA)
+        cert->pubKeyOID = RSAk;
+    else if (pkey->type == EVP_PKEY_EC)
+        cert->pubKeyOID = ECDSAk;
+    else
+        return WOLFSSL_FAILURE;
+
+    p = (byte*)XMALLOC(pkey->pkey_sz, cert->heap, DYNAMIC_TYPE_PUBLIC_KEY);
+    if (p == NULL)
+        return WOLFSSL_FAILURE;
+
+    if (cert->pubKey.buffer != NULL)
+        XFREE(cert->pubKey.buffer, cert->heap, DYNAMIC_TYPE_PUBLIC_KEY);
+    cert->pubKey.buffer = p;
+    XMEMCPY(cert->pubKey.buffer, pkey->pkey.ptr, pkey->pkey_sz);
+    cert->pubKey.length = pkey->pkey_sz;
+
+    return WOLFSSL_SUCCESS;
+}
+
+int wolfSSL_X509_set_version(WOLFSSL_X509* x509, long v)
+{
+    WOLFSSL_ENTER("wolfSSL_X509_set_version");
+    if ((x509 == NULL) || (v < 0) || (v > INT_MAX)) {
+        return WOLFSSL_FAILURE;
+    }
+    x509->version = (int) v + 1;
+
+    return WOLFSSL_SUCCESS;
+}
+
+#endif /* OPENSSL_EXTRA && !NO_CERTS && WOLFSSL_CERT_GEN && WOLFSSL_CERT_REQ */
+
+#if defined(OPENSSL_EXTRA) && !defined(NO_CERTS) && \
+    defined(WOLFSSL_CERT_GEN) && defined(WOLFSSL_CERT_REQ)
+
+void wolfSSL_X509V3_set_ctx(WOLFSSL_X509V3_CTX* ctx, WOLFSSL_X509* issuer,
+        WOLFSSL_X509* subject, WOLFSSL_X509* req, WOLFSSL_X509_CRL* crl,
+        int flag)
+{
+    int ret = WOLFSSL_SUCCESS;
+    WOLFSSL_ENTER("wolfSSL_X509V3_set_ctx");
+    if (!ctx || !ctx->x509)
+        return;
+
+    /* Set parameters in ctx as long as ret == WOLFSSL_SUCCESS */
+    if (issuer)
+        ret = wolfSSL_X509_set_issuer_name(ctx->x509,&issuer->issuer);
+
+    if (subject && ret == WOLFSSL_SUCCESS)
+        ret = wolfSSL_X509_set_subject_name(ctx->x509,&subject->subject);
+
+    if (req && ret == WOLFSSL_SUCCESS) {
+        WOLFSSL_MSG("req not implemented.");
+    }
+
+    if (crl && ret == WOLFSSL_SUCCESS) {
+        WOLFSSL_MSG("crl not implemented.");
+    }
+
+    if (flag && ret == WOLFSSL_SUCCESS) {
+        WOLFSSL_MSG("flag not implemented.");
+    }
+
+    if (!ret) {
+        WOLFSSL_MSG("Error setting WOLFSSL_X509V3_CTX parameters.");
+    }
+}
+
+int wolfSSL_i2d_X509_REQ(WOLFSSL_X509* req, unsigned char** out)
+{
+    const unsigned char* der;
+    int derSz = 0;
+    WOLFSSL_ENTER("wolfSSL_i2d_X509_REQ");
+
+    if (req == NULL || out == NULL) {
+        return BAD_FUNC_ARG;
+    }
+
+    der = wolfSSL_X509_get_der(req, &derSz);
+    if (der == NULL) {
+        return MEMORY_E;
+    }
+
+    if (*out == NULL) {
+        *out = (unsigned char*)XMALLOC(derSz, NULL, DYNAMIC_TYPE_OPENSSL);
+        if (*out == NULL) {
+            return MEMORY_E;
+        }
+    }
+
+    XMEMCPY(*out, der, derSz);
+
+    return derSz;
+}
+
+WOLFSSL_X509* wolfSSL_X509_REQ_new(void)
+{
+    return wolfSSL_X509_new();
+}
+
+void wolfSSL_X509_REQ_free(WOLFSSL_X509* req)
+{
+    wolfSSL_X509_free(req);
+}
+
+int wolfSSL_X509_REQ_sign(WOLFSSL_X509 *req, WOLFSSL_EVP_PKEY *pkey,
+                          const WOLFSSL_EVP_MD *md)
+{
+    byte der[2048];
+    int derSz = sizeof(der);
+
+    if (req == NULL || pkey == NULL || md == NULL)
+        return WOLFSSL_FAILURE;
+
+    /* Create a Cert that has the certificate request fields. */
+    req->sigOID = wolfSSL_sigTypeFromPKEY((WOLFSSL_EVP_MD*)md, pkey);
+    if (wolfSSL_X509_make_der(req, 1, der, &derSz) != WOLFSSL_SUCCESS) {
+        return WOLFSSL_FAILURE;
+    }
+
+    if (wolfSSL_X509_resign_cert(req, 1, der, sizeof(der), derSz,
+            (WOLFSSL_EVP_MD*)md, pkey) <= 0) {
+        return WOLFSSL_FAILURE;
+    }
+    return WOLFSSL_SUCCESS;
+}
+
+
+#ifndef NO_WOLFSSL_STUB
+int wolfSSL_X509_REQ_add_extensions(WOLFSSL_X509* req,
+        WOLF_STACK_OF(WOLFSSL_X509_EXTENSION)* ext)
+{
+    (void)req;
+    (void)ext;
+    return WOLFSSL_FATAL_ERROR;
+}
+#endif
+
+int wolfSSL_X509_REQ_set_subject_name(WOLFSSL_X509 *req,
+                                      WOLFSSL_X509_NAME *name)
+{
+    return wolfSSL_X509_set_subject_name(req, name);
+}
+
+int wolfSSL_X509_REQ_set_pubkey(WOLFSSL_X509 *req, WOLFSSL_EVP_PKEY *pkey)
+{
+    return wolfSSL_X509_set_pubkey(req, pkey);
+}
+#endif /* OPENSSL_EXTRA && !NO_CERTS && WOLFSSL_CERT_GEN && WOLFSSL_CERT_REQ */
+
+
Index: azure_iot_hub_f767zi/trunk/wolfssl-4.4.0/src/tls.c
===================================================================
--- azure_iot_hub_f767zi/trunk/wolfssl-4.4.0/src/tls.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/wolfssl-4.4.0/src/tls.c	(revision 457)
@@ -0,0 +1,11755 @@
+/* tls.c
+ *
+ * Copyright (C) 2006-2020 wolfSSL Inc.
+ *
+ * This file is part of wolfSSL.
+ *
+ * wolfSSL is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * wolfSSL is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
+ */
+
+
+
+#ifdef HAVE_CONFIG_H
+    #include <config.h>
+#endif
+
+#include <wolfssl/wolfcrypt/settings.h>
+
+#ifndef WOLFCRYPT_ONLY
+
+#include <wolfssl/ssl.h>
+#include <wolfssl/internal.h>
+#include <wolfssl/error-ssl.h>
+#include <wolfssl/wolfcrypt/hmac.h>
+#ifdef NO_INLINE
+    #include <wolfssl/wolfcrypt/misc.h>
+#else
+    #define WOLFSSL_MISC_INCLUDED
+    #include <wolfcrypt/src/misc.c>
+#endif
+
+#ifdef HAVE_CURVE25519
+    #include <wolfssl/wolfcrypt/curve25519.h>
+#endif
+#ifdef HAVE_CURVE448
+    #include <wolfssl/wolfcrypt/curve448.h>
+#endif
+#ifdef HAVE_NTRU
+    #include "libntruencrypt/ntru_crypto.h"
+    #include <wolfssl/wolfcrypt/random.h>
+#endif
+
+#ifdef HAVE_QSH
+    static int TLSX_AddQSHKey(QSHKey** list, QSHKey* key);
+    static byte* TLSX_QSHKeyFind_Pub(QSHKey* qsh, word16* pubLen, word16 name);
+#if defined(HAVE_NTRU)
+    static int TLSX_CreateNtruKey(WOLFSSL* ssl, int type);
+#endif
+#endif /* HAVE_QSH */
+
+#if (!defined(NO_WOLFSSL_SERVER) && defined(WOLFSSL_TLS13) && \
+        !defined(WOLFSSL_NO_SERVER_GROUPS_EXT)) || \
+    (defined(WOLFSSL_TLS13) && defined(HAVE_SUPPORTED_CURVES))
+static int TLSX_KeyShare_IsSupported(int namedGroup);
+#endif
+
+#if ((!defined(NO_WOLFSSL_SERVER) && defined(WOLFSSL_TLS13) && \
+        !defined(WOLFSSL_NO_SERVER_GROUPS_EXT)) || \
+    (defined(WOLFSSL_TLS13) && !defined(HAVE_ECC) && !defined(HAVE_CURVE25519) \
+        && !defined(HAVE_CURVE448) && defined(HAVE_SUPPORTED_CURVES)) || \
+    ((defined(HAVE_ECC) || defined(HAVE_CURVE25519) || \
+        defined(HAVE_CURVE448)) && defined(HAVE_SUPPORTED_CURVES))) && \
+     defined(HAVE_TLS_EXTENSIONS)
+static int TLSX_PopulateSupportedGroups(WOLFSSL* ssl, TLSX** extensions);
+#endif
+
+
+#ifndef NO_TLS
+
+/* Digest enable checks */
+#ifdef NO_OLD_TLS /* TLS 1.2 only */
+    #if defined(NO_SHA256) && !defined(WOLFSSL_SHA384) && \
+            !defined(WOLFSSL_SHA512)
+        #error Must have SHA256, SHA384 or SHA512 enabled for TLS 1.2
+    #endif
+#else  /* TLS 1.1 or older */
+    #if defined(NO_MD5) && defined(NO_SHA)
+        #error Must have SHA1 and MD5 enabled for old TLS
+    #endif
+#endif
+
+#ifdef WOLFSSL_TLS13
+    #if !defined(NO_DH) && \
+        !defined(HAVE_FFDHE_2048) && !defined(HAVE_FFDHE_3072) && \
+        !defined(HAVE_FFDHE_4096) && !defined(HAVE_FFDHE_6144) && \
+        !defined(HAVE_FFDHE_8192)
+        #error Please configure your TLS 1.3 DH key size using either: HAVE_FFDHE_2048, HAVE_FFDHE_3072, HAVE_FFDHE_4096, HAVE_FFDHE_6144 or HAVE_FFDHE_8192
+    #endif
+    #if !defined(NO_RSA) && !defined(WC_RSA_PSS)
+        #error The build option WC_RSA_PSS is required for TLS 1.3 with RSA
+    #endif
+    #ifndef HAVE_TLS_EXTENSIONS
+        #ifndef _MSC_VER
+            #error "The build option HAVE_TLS_EXTENSIONS is required for TLS 1.3"
+        #else
+            #pragma message("Error: The build option HAVE_TLS_EXTENSIONS is required for TLS 1.3")
+        #endif
+    #endif
+#endif
+
+/* Warn if secrets logging is enabled */
+#if defined(SHOW_SECRETS) || defined(WOLFSSL_SSLKEYLOGFILE)
+    #ifndef _MSC_VER
+        #warning The SHOW_SECRETS and WOLFSSL_SSLKEYLOGFILE options should only be used for debugging and never in a production environment
+    #else
+        #pragma message("Warning: The SHOW_SECRETS and WOLFSSL_SSLKEYLOGFILE options should only be used for debugging and never in a production environment")
+    #endif
+#endif
+
+/* Optional Pre-Master-Secret logging for Wireshark */
+#if !defined(NO_FILESYSTEM) && defined(WOLFSSL_SSLKEYLOGFILE)
+#ifndef WOLFSSL_SSLKEYLOGFILE_OUTPUT
+    #define WOLFSSL_SSLKEYLOGFILE_OUTPUT "sslkeylog.log"
+#endif
+#endif
+
+#ifndef WOLFSSL_NO_TLS12
+
+#ifdef WOLFSSL_SHA384
+    #define HSHASH_SZ WC_SHA384_DIGEST_SIZE
+#else
+    #define HSHASH_SZ FINISHED_SZ
+#endif
+
+#ifdef WOLFSSL_RENESAS_TSIP_TLS
+    int tsip_useable(const WOLFSSL *ssl);
+    int tsip_generateMasterSecret(const byte *pre,
+                                const byte *cr,const byte *sr,
+                                byte *ms/* out */);
+    int tsip_generateSeesionKey(WOLFSSL *ssl);
+    int tsip_generateVerifyData(const byte *ms, const byte *side,
+                                const byte *handshake_hash,
+                                byte *hashes /* out */);
+#endif
+
+int BuildTlsHandshakeHash(WOLFSSL* ssl, byte* hash, word32* hashLen)
+{
+    int ret = 0;
+    word32 hashSz = FINISHED_SZ;
+
+    if (ssl == NULL || hash == NULL || hashLen == NULL || *hashLen < HSHASH_SZ)
+        return BAD_FUNC_ARG;
+
+    /* for constant timing perform these even if error */
+#ifndef NO_OLD_TLS
+    ret |= wc_Md5GetHash(&ssl->hsHashes->hashMd5, hash);
+    ret |= wc_ShaGetHash(&ssl->hsHashes->hashSha, &hash[WC_MD5_DIGEST_SIZE]);
+#endif
+
+    if (IsAtLeastTLSv1_2(ssl)) {
+#ifndef NO_SHA256
+        if (ssl->specs.mac_algorithm <= sha256_mac ||
+            ssl->specs.mac_algorithm == blake2b_mac) {
+            ret |= wc_Sha256GetHash(&ssl->hsHashes->hashSha256, hash);
+            hashSz = WC_SHA256_DIGEST_SIZE;
+        }
+#endif
+#ifdef WOLFSSL_SHA384
+        if (ssl->specs.mac_algorithm == sha384_mac) {
+            ret |= wc_Sha384GetHash(&ssl->hsHashes->hashSha384, hash);
+            hashSz = WC_SHA384_DIGEST_SIZE;
+        }
+#endif
+    }
+
+    *hashLen = hashSz;
+
+    if (ret != 0)
+        ret = BUILD_MSG_ERROR;
+
+    return ret;
+}
+
+
+int BuildTlsFinished(WOLFSSL* ssl, Hashes* hashes, const byte* sender)
+{
+    int ret;
+    const byte* side;
+    word32 hashSz = HSHASH_SZ;
+#if defined(WOLFSSL_ASYNC_CRYPT) && !defined(WC_ASYNC_NO_HASH)
+    DECLARE_VAR(handshake_hash, byte, HSHASH_SZ, ssl->heap);
+    if (handshake_hash == NULL)
+        return MEMORY_E;
+#else
+    byte handshake_hash[HSHASH_SZ];
+#endif
+
+    ret = BuildTlsHandshakeHash(ssl, handshake_hash, &hashSz);
+    if (ret == 0) {
+        if (XSTRNCMP((const char*)sender, (const char*)client, SIZEOF_SENDER) == 0)
+            side = tls_client;
+        else
+            side = tls_server;
+
+#ifdef WOLFSSL_HAVE_PRF
+#if defined(WOLFSSL_RENESAS_TSIP_TLS) && \
+    !defined(NO_WOLFSSL_RENESAS_TSIP_TLS_SESSION)
+        if (tsip_useable(ssl)) {
+            ret = tsip_generateVerifyData(ssl->arrays->tsip_masterSecret,
+                            side, handshake_hash, (byte*)hashes /* out */);
+        } else
+#endif
+        ret = wc_PRF_TLS((byte*)hashes, TLS_FINISHED_SZ, ssl->arrays->masterSecret,
+                   SECRET_LEN, side, FINISHED_LABEL_SZ, handshake_hash, hashSz,
+                   IsAtLeastTLSv1_2(ssl), ssl->specs.mac_algorithm,
+                   ssl->heap, ssl->devId);
+#else
+        /* Pseudo random function must be enabled in the configuration. */
+        ret = PRF_MISSING;
+        WOLFSSL_MSG("Pseudo-random function is not enabled");
+
+        (void)side;
+        (void)hashes;
+#endif
+    }
+
+#if defined(WOLFSSL_ASYNC_CRYPT) && !defined(WC_ASYNC_NO_HASH)
+    FREE_VAR(handshake_hash, ssl->heap);
+#endif
+
+    return ret;
+}
+
+#endif /* !WOLFSSL_NO_TLS12 */
+
+#ifndef NO_OLD_TLS
+
+#ifdef WOLFSSL_ALLOW_TLSV10
+ProtocolVersion MakeTLSv1(void)
+{
+    ProtocolVersion pv;
+    pv.major = SSLv3_MAJOR;
+    pv.minor = TLSv1_MINOR;
+
+    return pv;
+}
+#endif /* WOLFSSL_ALLOW_TLSV10 */
+
+
+ProtocolVersion MakeTLSv1_1(void)
+{
+    ProtocolVersion pv;
+    pv.major = SSLv3_MAJOR;
+    pv.minor = TLSv1_1_MINOR;
+
+    return pv;
+}
+
+#endif /* !NO_OLD_TLS */
+
+
+#ifndef WOLFSSL_NO_TLS12
+
+ProtocolVersion MakeTLSv1_2(void)
+{
+    ProtocolVersion pv;
+    pv.major = SSLv3_MAJOR;
+    pv.minor = TLSv1_2_MINOR;
+
+    return pv;
+}
+
+#endif /* !WOLFSSL_NO_TLS12 */
+
+#ifdef WOLFSSL_TLS13
+/* The TLS v1.3 protocol version.
+ *
+ * returns the protocol version data for TLS v1.3.
+ */
+ProtocolVersion MakeTLSv1_3(void)
+{
+    ProtocolVersion pv;
+    pv.major = SSLv3_MAJOR;
+    pv.minor = TLSv1_3_MINOR;
+
+    return pv;
+}
+#endif
+
+#ifndef WOLFSSL_NO_TLS12
+
+#ifdef HAVE_EXTENDED_MASTER
+static const byte ext_master_label[EXT_MASTER_LABEL_SZ + 1] =
+                                                      "extended master secret";
+#endif
+static const byte master_label[MASTER_LABEL_SZ + 1] = "master secret";
+static const byte key_label   [KEY_LABEL_SZ + 1]    = "key expansion";
+
+static int _DeriveTlsKeys(byte* key_dig, word32 key_dig_len,
+                         const byte* ms, word32 msLen,
+                         const byte* sr, const byte* cr,
+                         int tls1_2, int hash_type,
+                         void* heap, int devId)
+{
+    int ret;
+#if defined(WOLFSSL_ASYNC_CRYPT) && !defined(WC_ASYNC_NO_HASH)
+    DECLARE_VAR(seed, byte, SEED_LEN, heap);
+    if (seed == NULL)
+        return MEMORY_E;
+#else
+    byte seed[SEED_LEN];
+#endif
+
+    XMEMCPY(seed,           sr, RAN_LEN);
+    XMEMCPY(seed + RAN_LEN, cr, RAN_LEN);
+
+#ifdef WOLFSSL_HAVE_PRF
+    ret = wc_PRF_TLS(key_dig, key_dig_len, ms, msLen, key_label, KEY_LABEL_SZ,
+               seed, SEED_LEN, tls1_2, hash_type, heap, devId);
+#else
+    /* Pseudo random function must be enabled in the configuration. */
+    ret = PRF_MISSING;
+    WOLFSSL_MSG("Pseudo-random function is not enabled");
+
+    (void)key_dig;
+    (void)key_dig_len;
+    (void)ms;
+    (void)msLen;
+    (void)tls1_2;
+    (void)hash_type;
+    (void)heap;
+    (void)devId;
+    (void)key_label;
+    (void)master_label;
+#ifdef HAVE_EXTENDED_MASTER
+    (void)ext_master_label;
+#endif
+#endif
+
+#if defined(WOLFSSL_ASYNC_CRYPT) && !defined(WC_ASYNC_NO_HASH)
+    FREE_VAR(seed, heap);
+#endif
+
+    return ret;
+}
+
+/* External facing wrapper so user can call as well, 0 on success */
+int wolfSSL_DeriveTlsKeys(byte* key_dig, word32 key_dig_len,
+                         const byte* ms, word32 msLen,
+                         const byte* sr, const byte* cr,
+                         int tls1_2, int hash_type)
+{
+    return _DeriveTlsKeys(key_dig, key_dig_len, ms, msLen, sr, cr, tls1_2,
+        hash_type, NULL, INVALID_DEVID);
+}
+
+
+int DeriveTlsKeys(WOLFSSL* ssl)
+{
+    int   ret;
+    int   key_dig_len = 2 * ssl->specs.hash_size +
+                        2 * ssl->specs.key_size  +
+                        2 * ssl->specs.iv_size;
+#ifdef WOLFSSL_SMALL_STACK
+    byte* key_dig;
+#else
+    byte  key_dig[MAX_PRF_DIG];
+#endif
+
+#ifdef WOLFSSL_SMALL_STACK
+    key_dig = (byte*)XMALLOC(MAX_PRF_DIG, ssl->heap, DYNAMIC_TYPE_DIGEST);
+    if (key_dig == NULL) {
+        return MEMORY_E;
+    }
+#endif
+#if defined(WOLFSSL_RENESAS_TSIP_TLS) && \
+    !defined(NO_WOLFSSL_RENESAS_TSIP_TLS_SESSION)
+    if (tsip_useable(ssl))
+        ret = tsip_generateSeesionKey(ssl);
+    else {
+#endif
+    ret = _DeriveTlsKeys(key_dig, key_dig_len,
+                         ssl->arrays->masterSecret, SECRET_LEN,
+                         ssl->arrays->serverRandom, ssl->arrays->clientRandom,
+                         IsAtLeastTLSv1_2(ssl), ssl->specs.mac_algorithm,
+                         ssl->heap, ssl->devId);
+    if (ret == 0)
+        ret = StoreKeys(ssl, key_dig, PROVISION_CLIENT_SERVER);
+#if defined(WOLFSSL_RENESAS_TSIP_TLS) && \
+    !defined(NO_WOLFSSL_RENESAS_TSIP_TLS_SESSION)
+    }
+#endif
+
+#ifdef WOLFSSL_SMALL_STACK
+    XFREE(key_dig, ssl->heap, DYNAMIC_TYPE_DIGEST);
+#endif
+
+    return ret;
+}
+
+static int _MakeTlsMasterSecret(byte* ms, word32 msLen,
+                               const byte* pms, word32 pmsLen,
+                               const byte* cr, const byte* sr,
+                               int tls1_2, int hash_type,
+                               void* heap, int devId)
+{
+    int ret;
+#if defined(WOLFSSL_ASYNC_CRYPT) && !defined(WC_ASYNC_NO_HASH)
+    DECLARE_VAR(seed, byte, SEED_LEN, heap);
+    if (seed == NULL)
+        return MEMORY_E;
+#else
+    byte seed[SEED_LEN];
+#endif
+
+    XMEMCPY(seed,           cr, RAN_LEN);
+    XMEMCPY(seed + RAN_LEN, sr, RAN_LEN);
+
+#ifdef WOLFSSL_HAVE_PRF
+    ret = wc_PRF_TLS(ms, msLen, pms, pmsLen, master_label, MASTER_LABEL_SZ,
+               seed, SEED_LEN, tls1_2, hash_type, heap, devId);
+#else
+    /* Pseudo random function must be enabled in the configuration. */
+    ret = PRF_MISSING;
+    WOLFSSL_MSG("Pseudo-random function is not enabled");
+
+    (void)ms;
+    (void)msLen;
+    (void)pms;
+    (void)pmsLen;
+    (void)tls1_2;
+    (void)hash_type;
+    (void)heap;
+    (void)devId;
+#endif
+
+#if defined(WOLFSSL_ASYNC_CRYPT) && !defined(WC_ASYNC_NO_HASH)
+    FREE_VAR(seed, heap);
+#endif
+
+    return ret;
+}
+
+/* External facing wrapper so user can call as well, 0 on success */
+int wolfSSL_MakeTlsMasterSecret(byte* ms, word32 msLen,
+                               const byte* pms, word32 pmsLen,
+                               const byte* cr, const byte* sr,
+                               int tls1_2, int hash_type)
+{
+    return _MakeTlsMasterSecret(ms, msLen, pms, pmsLen, cr, sr, tls1_2,
+        hash_type, NULL, INVALID_DEVID);
+}
+
+
+#ifdef HAVE_EXTENDED_MASTER
+
+static int _MakeTlsExtendedMasterSecret(byte* ms, word32 msLen,
+                                        const byte* pms, word32 pmsLen,
+                                        const byte* sHash, word32 sHashLen,
+                                        int tls1_2, int hash_type,
+                                        void* heap, int devId)
+{
+    int ret;
+
+#ifdef WOLFSSL_HAVE_PRF
+    ret = wc_PRF_TLS(ms, msLen, pms, pmsLen, ext_master_label, EXT_MASTER_LABEL_SZ,
+               sHash, sHashLen, tls1_2, hash_type, heap, devId);
+#else
+    /* Pseudo random function must be enabled in the configuration. */
+    ret = PRF_MISSING;
+    WOLFSSL_MSG("Pseudo-random function is not enabled");
+
+    (void)ms;
+    (void)msLen;
+    (void)pms;
+    (void)pmsLen;
+    (void)sHash;
+    (void)sHashLen;
+    (void)tls1_2;
+    (void)hash_type;
+    (void)heap;
+    (void)devId;
+#endif
+    return ret;
+}
+
+/* External facing wrapper so user can call as well, 0 on success */
+int wolfSSL_MakeTlsExtendedMasterSecret(byte* ms, word32 msLen,
+                                        const byte* pms, word32 pmsLen,
+                                        const byte* sHash, word32 sHashLen,
+                                        int tls1_2, int hash_type)
+{
+    return _MakeTlsExtendedMasterSecret(ms, msLen, pms, pmsLen, sHash, sHashLen,
+        tls1_2, hash_type, NULL, INVALID_DEVID);
+}
+
+#endif /* HAVE_EXTENDED_MASTER */
+
+
+int MakeTlsMasterSecret(WOLFSSL* ssl)
+{
+    int ret;
+
+#ifdef HAVE_EXTENDED_MASTER
+    if (ssl->options.haveEMS) {
+        word32 hashSz = HSHASH_SZ;
+    #ifdef WOLFSSL_SMALL_STACK
+        byte* handshake_hash = (byte*)XMALLOC(HSHASH_SZ, ssl->heap,
+                                              DYNAMIC_TYPE_DIGEST);
+        if (handshake_hash == NULL)
+            return MEMORY_E;
+    #else
+        byte handshake_hash[HSHASH_SZ];
+    #endif
+
+        ret = BuildTlsHandshakeHash(ssl, handshake_hash, &hashSz);
+        if (ret == 0) {
+            ret = _MakeTlsExtendedMasterSecret(
+                ssl->arrays->masterSecret, SECRET_LEN,
+                ssl->arrays->preMasterSecret, ssl->arrays->preMasterSz,
+                handshake_hash, hashSz,
+                IsAtLeastTLSv1_2(ssl), ssl->specs.mac_algorithm,
+                ssl->heap, ssl->devId);
+        }
+
+    #ifdef WOLFSSL_SMALL_STACK
+        XFREE(handshake_hash, ssl->heap, DYNAMIC_TYPE_DIGEST);
+    #endif
+    }
+    else
+#endif /* HAVE_EXTENDED_MASTER */
+    {
+#if defined(WOLFSSL_RENESAS_TSIP_TLS) && \
+    !defined(NO_WOLFSSL_RENESAS_TSIP_TLS_SESSION)
+        if (tsip_useable(ssl)) {
+            ret = tsip_generateMasterSecret(
+                            &ssl->arrays->preMasterSecret[VERSION_SZ],
+                            ssl->arrays->clientRandom,
+                            ssl->arrays->serverRandom,
+                            ssl->arrays->tsip_masterSecret);
+        } else
+#endif
+        ret = _MakeTlsMasterSecret(ssl->arrays->masterSecret, SECRET_LEN,
+              ssl->arrays->preMasterSecret, ssl->arrays->preMasterSz,
+              ssl->arrays->clientRandom, ssl->arrays->serverRandom,
+              IsAtLeastTLSv1_2(ssl), ssl->specs.mac_algorithm,
+              ssl->heap, ssl->devId);
+    }
+    if (ret == 0) {
+    #ifdef SHOW_SECRETS
+        /* Wireshark Pre-Master-Secret Format:
+         *  CLIENT_RANDOM <clientrandom> <mastersecret>
+         */
+        const char* CLIENT_RANDOM_LABEL = "CLIENT_RANDOM";
+        int i, pmsPos = 0;
+        char pmsBuf[13 + 1 + 64 + 1 + 96 + 1 + 1];
+
+        XSNPRINTF(&pmsBuf[pmsPos], sizeof(pmsBuf) - pmsPos, "%s ",
+            CLIENT_RANDOM_LABEL);
+        pmsPos += XSTRLEN(CLIENT_RANDOM_LABEL) + 1;
+        for (i = 0; i < RAN_LEN; i++) {
+            XSNPRINTF(&pmsBuf[pmsPos], sizeof(pmsBuf) - pmsPos, "%02x",
+                ssl->arrays->clientRandom[i]);
+            pmsPos += 2;
+        }
+        XSNPRINTF(&pmsBuf[pmsPos], sizeof(pmsBuf) - pmsPos, " ");
+        pmsPos += 1;
+        for (i = 0; i < SECRET_LEN; i++) {
+            XSNPRINTF(&pmsBuf[pmsPos], sizeof(pmsBuf) - pmsPos, "%02x",
+                ssl->arrays->masterSecret[i]);
+            pmsPos += 2;
+        }
+        XSNPRINTF(&pmsBuf[pmsPos], sizeof(pmsBuf) - pmsPos, "\n");
+        pmsPos += 1;
+
+        /* print master secret */
+        puts(pmsBuf);
+
+        #if !defined(NO_FILESYSTEM) && defined(WOLFSSL_SSLKEYLOGFILE)
+        {
+            FILE* f = XFOPEN(WOLFSSL_SSLKEYLOGFILE_OUTPUT, "a");
+            if (f != XBADFILE) {
+                XFWRITE(pmsBuf, 1, pmsPos, f);
+                XFCLOSE(f);
+            }
+        }
+        #endif
+    #endif /* SHOW_SECRETS */
+
+        ret = DeriveTlsKeys(ssl);
+    }
+
+    return ret;
+}
+
+
+/* Used by EAP-TLS and EAP-TTLS to derive keying material from
+ * the master_secret. */
+int wolfSSL_make_eap_keys(WOLFSSL* ssl, void* msk, unsigned int len,
+                                                              const char* label)
+{
+    int   ret;
+#ifdef WOLFSSL_SMALL_STACK
+    byte* seed;
+#else
+    byte  seed[SEED_LEN];
+#endif
+
+#ifdef WOLFSSL_SMALL_STACK
+    seed = (byte*)XMALLOC(SEED_LEN, ssl->heap, DYNAMIC_TYPE_SEED);
+    if (seed == NULL)
+        return MEMORY_E;
+#endif
+
+    /*
+     * As per RFC-5281, the order of the client and server randoms is reversed
+     * from that used by the TLS protocol to derive keys.
+     */
+    XMEMCPY(seed,           ssl->arrays->clientRandom, RAN_LEN);
+    XMEMCPY(seed + RAN_LEN, ssl->arrays->serverRandom, RAN_LEN);
+
+#ifdef WOLFSSL_HAVE_PRF
+    ret = wc_PRF_TLS((byte*)msk, len, ssl->arrays->masterSecret, SECRET_LEN,
+              (const byte *)label, (word32)XSTRLEN(label), seed, SEED_LEN,
+              IsAtLeastTLSv1_2(ssl), ssl->specs.mac_algorithm,
+              ssl->heap, ssl->devId);
+#else
+    /* Pseudo random function must be enabled in the configuration. */
+    ret = PRF_MISSING;
+    WOLFSSL_MSG("Pseudo-random function is not enabled");
+
+    (void)msk;
+    (void)len;
+    (void)label;
+#endif
+
+#ifdef WOLFSSL_SMALL_STACK
+    XFREE(seed, ssl->heap, DYNAMIC_TYPE_SEED);
+#endif
+
+    return ret;
+}
+
+
+static WC_INLINE void GetSEQIncrement(WOLFSSL* ssl, int verify, word32 seq[2])
+{
+    if (verify) {
+        seq[0] = ssl->keys.peer_sequence_number_hi;
+        seq[1] = ssl->keys.peer_sequence_number_lo++;
+        if (seq[1] > ssl->keys.peer_sequence_number_lo) {
+            /* handle rollover */
+            ssl->keys.peer_sequence_number_hi++;
+        }
+    }
+    else {
+        seq[0] = ssl->keys.sequence_number_hi;
+        seq[1] = ssl->keys.sequence_number_lo++;
+        if (seq[1] > ssl->keys.sequence_number_lo) {
+            /* handle rollover */
+            ssl->keys.sequence_number_hi++;
+        }
+    }
+}
+
+
+#ifdef WOLFSSL_DTLS
+static WC_INLINE void DtlsGetSEQ(WOLFSSL* ssl, int order, word32 seq[2])
+{
+    if (order == PREV_ORDER) {
+        /* Previous epoch case */
+        seq[0] = (((word32)ssl->keys.dtls_epoch - 1) << 16) |
+                 (ssl->keys.dtls_prev_sequence_number_hi & 0xFFFF);
+        seq[1] = ssl->keys.dtls_prev_sequence_number_lo;
+    }
+    else if (order == PEER_ORDER) {
+        seq[0] = ((word32)ssl->keys.curEpoch << 16) |
+                 (ssl->keys.curSeq_hi & 0xFFFF);
+        seq[1] = ssl->keys.curSeq_lo; /* explicit from peer */
+    }
+    else {
+        seq[0] = ((word32)ssl->keys.dtls_epoch << 16) |
+                 (ssl->keys.dtls_sequence_number_hi & 0xFFFF);
+        seq[1] = ssl->keys.dtls_sequence_number_lo;
+    }
+}
+#endif /* WOLFSSL_DTLS */
+
+
+static WC_INLINE void WriteSEQ(WOLFSSL* ssl, int verifyOrder, byte* out)
+{
+    word32 seq[2] = {0, 0};
+
+    if (!ssl->options.dtls) {
+        GetSEQIncrement(ssl, verifyOrder, seq);
+    }
+    else {
+#ifdef WOLFSSL_DTLS
+        DtlsGetSEQ(ssl, verifyOrder, seq);
+#endif
+    }
+
+    c32toa(seq[0], out);
+    c32toa(seq[1], out + OPAQUE32_LEN);
+}
+
+
+/*** end copy ***/
+
+
+/* return HMAC digest type in wolfSSL format */
+int wolfSSL_GetHmacType(WOLFSSL* ssl)
+{
+    if (ssl == NULL)
+        return BAD_FUNC_ARG;
+
+    switch (ssl->specs.mac_algorithm) {
+        #ifndef NO_MD5
+        case md5_mac:
+        {
+            return WC_MD5;
+        }
+        #endif
+        #ifndef NO_SHA256
+        case sha256_mac:
+        {
+            return WC_SHA256;
+        }
+        #endif
+        #ifdef WOLFSSL_SHA384
+        case sha384_mac:
+        {
+            return WC_SHA384;
+        }
+
+        #endif
+        #ifndef NO_SHA
+        case sha_mac:
+        {
+            return WC_SHA;
+        }
+        #endif
+        #ifdef HAVE_BLAKE2
+        case blake2b_mac:
+        {
+            return BLAKE2B_ID;
+        }
+        #endif
+        default:
+        {
+            return WOLFSSL_FATAL_ERROR;
+        }
+    }
+}
+
+
+int wolfSSL_SetTlsHmacInner(WOLFSSL* ssl, byte* inner, word32 sz, int content,
+                           int verify)
+{
+    if (ssl == NULL || inner == NULL)
+        return BAD_FUNC_ARG;
+
+    XMEMSET(inner, 0, WOLFSSL_TLS_HMAC_INNER_SZ);
+
+    WriteSEQ(ssl, verify, inner);
+    inner[SEQ_SZ] = (byte)content;
+    inner[SEQ_SZ + ENUM_LEN]            = ssl->version.major;
+    inner[SEQ_SZ + ENUM_LEN + ENUM_LEN] = ssl->version.minor;
+    c16toa((word16)sz, inner + SEQ_SZ + ENUM_LEN + VERSION_SZ);
+
+    return 0;
+}
+
+
+#ifndef WOLFSSL_AEAD_ONLY
+#if !defined(WOLFSSL_NO_HASH_RAW) && !defined(HAVE_FIPS) && \
+    !defined(HAVE_SELFTEST)
+
+/* Update the hash in the HMAC.
+ *
+ * hmac  HMAC object.
+ * data  Data to be hashed.
+ * sz    Size of data to hash.
+ * returns 0 on success, otherwise failure.
+ */
+static int Hmac_HashUpdate(Hmac* hmac, const byte* data, word32 sz)
+{
+    int ret = BAD_FUNC_ARG;
+
+    switch (hmac->macType) {
+    #ifndef NO_SHA
+        case WC_SHA:
+            ret = wc_ShaUpdate(&hmac->hash.sha, data, sz);
+            break;
+    #endif /* !NO_SHA */
+
+    #ifndef NO_SHA256
+        case WC_SHA256:
+            ret = wc_Sha256Update(&hmac->hash.sha256, data, sz);
+            break;
+    #endif /* !NO_SHA256 */
+
+    #ifdef WOLFSSL_SHA384
+        case WC_SHA384:
+            ret = wc_Sha384Update(&hmac->hash.sha384, data, sz);
+            break;
+    #endif /* WOLFSSL_SHA384 */
+
+    #ifdef WOLFSSL_SHA512
+        case WC_SHA512:
+            ret = wc_Sha512Update(&hmac->hash.sha512, data, sz);
+            break;
+    #endif /* WOLFSSL_SHA512 */
+    }
+
+    return ret;
+}
+
+/* Finalize the hash but don't put the EOC, padding or length in.
+ *
+ * hmac  HMAC object.
+ * hash  Hash result.
+ * returns 0 on success, otherwise failure.
+ */
+static int Hmac_HashFinalRaw(Hmac* hmac, unsigned char* hash)
+{
+    int ret = BAD_FUNC_ARG;
+
+    switch (hmac->macType) {
+    #ifndef NO_SHA
+        case WC_SHA:
+            ret = wc_ShaFinalRaw(&hmac->hash.sha, hash);
+            break;
+    #endif /* !NO_SHA */
+
+    #ifndef NO_SHA256
+        case WC_SHA256:
+            ret = wc_Sha256FinalRaw(&hmac->hash.sha256, hash);
+            break;
+    #endif /* !NO_SHA256 */
+
+    #ifdef WOLFSSL_SHA384
+        case WC_SHA384:
+            ret = wc_Sha384FinalRaw(&hmac->hash.sha384, hash);
+            break;
+    #endif /* WOLFSSL_SHA384 */
+
+    #ifdef WOLFSSL_SHA512
+        case WC_SHA512:
+            ret = wc_Sha512FinalRaw(&hmac->hash.sha512, hash);
+            break;
+    #endif /* WOLFSSL_SHA512 */
+    }
+
+    return ret;
+}
+
+/* Finalize the HMAC by performing outer hash.
+ *
+ * hmac  HMAC object.
+ * mac   MAC result.
+ * returns 0 on success, otherwise failure.
+ */
+static int Hmac_OuterHash(Hmac* hmac, unsigned char* mac)
+{
+    int ret = BAD_FUNC_ARG;
+    wc_HashAlg hash;
+    enum wc_HashType hashType = (enum wc_HashType)hmac->macType;
+    int digestSz = wc_HashGetDigestSize(hashType);
+    int blockSz = wc_HashGetBlockSize(hashType);
+
+    if ((digestSz >= 0) && (blockSz >= 0)) {
+        ret = wc_HashInit(&hash, hashType);
+    }
+    if (ret == 0) {
+        ret = wc_HashUpdate(&hash, hashType, (byte*)hmac->opad,
+            blockSz);
+        if (ret == 0)
+            ret = wc_HashUpdate(&hash, hashType, (byte*)hmac->innerHash,
+                digestSz);
+        if (ret == 0)
+            ret = wc_HashFinal(&hash, hashType, mac);
+        wc_HashFree(&hash, hashType);
+    }
+
+    return ret;
+}
+
+/* Calculate the HMAC of the header + message data.
+ * Constant time implementation using wc_Sha*FinalRaw().
+ *
+ * hmac    HMAC object.
+ * digest  MAC result.
+ * in      Message data.
+ * sz      Size of the message data.
+ * header  Constructed record header with length of handshake data.
+ * returns 0 on success, otherwise failure.
+ */
+static int Hmac_UpdateFinal_CT(Hmac* hmac, byte* digest, const byte* in,
+                               word32 sz, byte* header)
+{
+    byte lenBytes[8];
+    int  i, j, k;
+    int  blockBits, blockMask;
+    int  lastBlockLen, macLen, extraLen, eocIndex;
+    int  blocks, safeBlocks, lenBlock, eocBlock;
+    int  maxLen;
+    int  blockSz, padSz;
+    int  ret;
+    word32 realLen;
+    byte extraBlock;
+
+    switch (hmac->macType) {
+    #ifndef NO_SHA
+        case WC_SHA:
+            blockSz = WC_SHA_BLOCK_SIZE;
+            blockBits = 6;
+            macLen = WC_SHA_DIGEST_SIZE;
+            padSz = WC_SHA_BLOCK_SIZE - WC_SHA_PAD_SIZE + 1;
+            break;
+    #endif /* !NO_SHA */
+
+    #ifndef NO_SHA256
+        case WC_SHA256:
+            blockSz = WC_SHA256_BLOCK_SIZE;
+            blockBits = 6;
+            macLen = WC_SHA256_DIGEST_SIZE;
+            padSz = WC_SHA256_BLOCK_SIZE - WC_SHA256_PAD_SIZE + 1;
+            break;
+    #endif /* !NO_SHA256 */
+
+    #ifdef WOLFSSL_SHA384
+        case WC_SHA384:
+            blockSz = WC_SHA384_BLOCK_SIZE;
+            blockBits = 7;
+            macLen = WC_SHA384_DIGEST_SIZE;
+            padSz = WC_SHA384_BLOCK_SIZE - WC_SHA384_PAD_SIZE + 1;
+            break;
+    #endif /* WOLFSSL_SHA384 */
+
+    #ifdef WOLFSSL_SHA512
+        case WC_SHA512:
+            blockSz = WC_SHA512_BLOCK_SIZE;
+            blockBits = 7;
+            macLen = WC_SHA512_DIGEST_SIZE;
+            padSz = WC_SHA512_BLOCK_SIZE - WC_SHA512_PAD_SIZE + 1;
+            break;
+    #endif /* WOLFSSL_SHA512 */
+
+        default:
+            return BAD_FUNC_ARG;
+    }
+    blockMask = blockSz - 1;
+
+    /* Size of data to HMAC if padding length byte is zero. */
+    maxLen = WOLFSSL_TLS_HMAC_INNER_SZ + sz - 1 - macLen;
+    /* Complete data (including padding) has block for EOC and/or length. */
+    extraBlock = ctSetLTE((maxLen + padSz) & blockMask, padSz);
+    /* Total number of blocks for data including padding. */
+    blocks = ((maxLen + blockSz - 1) >> blockBits) + extraBlock;
+    /* Up to last 6 blocks can be hashed safely. */
+    safeBlocks = blocks - 6;
+
+    /* Length of message data. */
+    realLen = maxLen - in[sz - 1];
+    /* Number of message bytes in last block. */
+    lastBlockLen = realLen & blockMask;
+    /* Number of padding bytes in last block. */
+    extraLen = ((blockSz * 2 - padSz - lastBlockLen) & blockMask) + 1;
+    /* Number of blocks to create for hash. */
+    lenBlock = (realLen + extraLen) >> blockBits;
+    /* Block containing EOC byte. */
+    eocBlock = realLen >> blockBits;
+    /* Index of EOC byte in block. */
+    eocIndex = realLen & blockMask;
+
+    /* Add length of hmac's ipad to total length. */
+    realLen += blockSz;
+    /* Length as bits - 8 bytes bigendian. */
+    c32toa(realLen >> ((sizeof(word32) * 8) - 3), lenBytes);
+    c32toa(realLen << 3, lenBytes + sizeof(word32));
+
+    ret = Hmac_HashUpdate(hmac, (unsigned char*)hmac->ipad, blockSz);
+    if (ret != 0)
+        return ret;
+
+    XMEMSET(hmac->innerHash, 0, macLen);
+
+    if (safeBlocks > 0) {
+        ret = Hmac_HashUpdate(hmac, header, WOLFSSL_TLS_HMAC_INNER_SZ);
+        if (ret != 0)
+            return ret;
+        ret = Hmac_HashUpdate(hmac, in, safeBlocks * blockSz -
+                                                     WOLFSSL_TLS_HMAC_INNER_SZ);
+        if (ret != 0)
+            return ret;
+    }
+    else
+        safeBlocks = 0;
+
+    XMEMSET(digest, 0, macLen);
+    k = safeBlocks * blockSz;
+    for (i = safeBlocks; i < blocks; i++) {
+        unsigned char hashBlock[WC_MAX_BLOCK_SIZE];
+        unsigned char isEocBlock = ctMaskEq(i, eocBlock);
+        unsigned char isOutBlock = ctMaskEq(i, lenBlock);
+
+        for (j = 0; j < blockSz; j++, k++) {
+            unsigned char atEoc = ctMaskEq(j, eocIndex) & isEocBlock;
+            unsigned char pastEoc = ctMaskGT(j, eocIndex) & isEocBlock;
+            unsigned char b = 0;
+
+            if (k < WOLFSSL_TLS_HMAC_INNER_SZ)
+                b = header[k];
+            else if (k < maxLen)
+                b = in[k - WOLFSSL_TLS_HMAC_INNER_SZ];
+
+            b = ctMaskSel(atEoc, 0x80, b);
+            b &= (unsigned char)~(word32)pastEoc;
+            b &= ((unsigned char)~(word32)isOutBlock) | isEocBlock;
+
+            if (j >= blockSz - 8) {
+                b = ctMaskSel(isOutBlock, lenBytes[j - (blockSz - 8)], b);
+            }
+
+            hashBlock[j] = b;
+        }
+
+        ret = Hmac_HashUpdate(hmac, hashBlock, blockSz);
+        if (ret != 0)
+            return ret;
+        ret = Hmac_HashFinalRaw(hmac, hashBlock);
+        if (ret != 0)
+            return ret;
+        for (j = 0; j < macLen; j++)
+            ((unsigned char*)hmac->innerHash)[j] |= hashBlock[j] & isOutBlock;
+    }
+
+    ret = Hmac_OuterHash(hmac, digest);
+
+    return ret;
+}
+
+#endif
+
+#if defined(WOLFSSL_NO_HASH_RAW) || defined(HAVE_FIPS) || \
+    defined(HAVE_SELFTEST) || defined(HAVE_BLAKE2)
+
+/* Calculate the HMAC of the header + message data.
+ * Constant time implementation using normal hashing operations.
+ * Update-Final need to be constant time.
+ *
+ * hmac    HMAC object.
+ * digest  MAC result.
+ * in      Message data.
+ * sz      Size of the message data.
+ * header  Constructed record header with length of handshake data.
+ * returns 0 on success, otherwise failure.
+ */
+static int Hmac_UpdateFinal(Hmac* hmac, byte* digest, const byte* in,
+                            word32 sz, byte* header)
+{
+    byte       dummy[WC_MAX_BLOCK_SIZE] = {0};
+    int        ret;
+    word32     msgSz, blockSz, macSz, padSz, maxSz, realSz;
+    word32     currSz, offset = 0;
+    int        msgBlocks, blocks, blockBits;
+    int        i;
+
+    switch (hmac->macType) {
+    #ifndef NO_SHA
+        case WC_SHA:
+            blockSz = WC_SHA_BLOCK_SIZE;
+            blockBits = 6;
+            macSz = WC_SHA_DIGEST_SIZE;
+            padSz = WC_SHA_BLOCK_SIZE - WC_SHA_PAD_SIZE + 1;
+            break;
+    #endif /* !NO_SHA */
+
+    #ifndef NO_SHA256
+        case WC_SHA256:
+            blockSz = WC_SHA256_BLOCK_SIZE;
+            blockBits = 6;
+            macSz = WC_SHA256_DIGEST_SIZE;
+            padSz = WC_SHA256_BLOCK_SIZE - WC_SHA256_PAD_SIZE + 1;
+            break;
+    #endif /* !NO_SHA256 */
+
+    #ifdef WOLFSSL_SHA384
+        case WC_SHA384:
+            blockSz = WC_SHA384_BLOCK_SIZE;
+            blockBits = 7;
+            macSz = WC_SHA384_DIGEST_SIZE;
+            padSz = WC_SHA384_BLOCK_SIZE - WC_SHA384_PAD_SIZE + 1;
+            break;
+    #endif /* WOLFSSL_SHA384 */
+
+    #ifdef WOLFSSL_SHA512
+        case WC_SHA512:
+            blockSz = WC_SHA512_BLOCK_SIZE;
+            blockBits = 7;
+            macSz = WC_SHA512_DIGEST_SIZE;
+            padSz = WC_SHA512_BLOCK_SIZE - WC_SHA512_PAD_SIZE + 1;
+            break;
+    #endif /* WOLFSSL_SHA512 */
+
+    #ifdef HAVE_BLAKE2
+        case WC_HASH_TYPE_BLAKE2B:
+            blockSz = BLAKE2B_BLOCKBYTES;
+            blockBits = 7;
+            macSz = BLAKE2B_256;
+            padSz = 0;
+            break;
+    #endif /* HAVE_BLAK2 */
+
+        default:
+            return BAD_FUNC_ARG;
+    }
+
+    msgSz = sz - (1 + in[sz - 1] + macSz);
+    /* Make negative result 0 */
+    msgSz &= ~(0 - (msgSz >> 31));
+    realSz = WOLFSSL_TLS_HMAC_INNER_SZ + msgSz;
+    maxSz = WOLFSSL_TLS_HMAC_INNER_SZ + (sz - 1) - macSz;
+
+    /* Calculate #blocks processed in HMAC for max and real data. */
+    blocks      = maxSz >> blockBits;
+    blocks     += ((maxSz + padSz) % blockSz) < padSz;
+    msgBlocks   = realSz >> blockBits;
+    /* #Extra blocks to process. */
+    blocks -= msgBlocks + (((realSz + padSz) % blockSz) < padSz);
+    /* Calculate whole blocks. */
+    msgBlocks--;
+
+    ret = wc_HmacUpdate(hmac, header, WOLFSSL_TLS_HMAC_INNER_SZ);
+    if (ret == 0) {
+        /* Fill the rest of the block with any available data. */
+        currSz = ctMaskLT(msgSz, blockSz) & msgSz;
+        currSz |= ctMaskGTE(msgSz, blockSz) & blockSz;
+        currSz -= WOLFSSL_TLS_HMAC_INNER_SZ;
+        currSz &= ~(0 - (currSz >> 31));
+        ret = wc_HmacUpdate(hmac, in, currSz);
+        offset = currSz;
+    }
+    if (ret == 0) {
+        /* Do the hash operations on a block basis. */
+        for (i = 0; i < msgBlocks; i++, offset += blockSz) {
+            ret = wc_HmacUpdate(hmac, in + offset, blockSz);
+            if (ret != 0)
+                break;
+        }
+    }
+    if (ret == 0)
+        ret = wc_HmacUpdate(hmac, in + offset, msgSz - offset);
+    if (ret == 0)
+        ret = wc_HmacFinal(hmac, digest);
+    if (ret == 0) {
+        /* Do the dummy hash operations. Do at least one. */
+        for (i = 0; i < blocks + 1; i++) {
+            ret = wc_HmacUpdate(hmac, dummy, blockSz);
+            if (ret != 0)
+                break;
+        }
+    }
+
+    return ret;
+}
+
+#endif
+
+int TLS_hmac(WOLFSSL* ssl, byte* digest, const byte* in, word32 sz, int padSz,
+             int content, int verify)
+{
+    Hmac   hmac;
+    byte   myInner[WOLFSSL_TLS_HMAC_INNER_SZ];
+    int    ret = 0;
+#ifdef HAVE_TRUNCATED_HMAC
+    word32 hashSz = ssl->truncated_hmac ? (byte)TRUNCATED_HMAC_SZ
+                                        : ssl->specs.hash_size;
+#else
+    word32 hashSz = ssl->specs.hash_size;
+#endif
+
+    if (ssl == NULL)
+        return BAD_FUNC_ARG;
+
+#ifdef HAVE_FUZZER
+    /* Fuzz "in" buffer with sz to be used in HMAC algorithm */
+    if (ssl->fuzzerCb) {
+        if (verify && padSz >= 0) {
+            ssl->fuzzerCb(ssl, in, sz + hashSz + padSz + 1, FUZZ_HMAC,
+                          ssl->fuzzerCtx);
+        }
+        else {
+            ssl->fuzzerCb(ssl, in, sz, FUZZ_HMAC, ssl->fuzzerCtx);
+        }
+    }
+#endif
+
+    wolfSSL_SetTlsHmacInner(ssl, myInner, sz, content, verify);
+#if defined(WOLFSSL_RENESAS_TSIP_TLS) && \
+    !defined(NO_WOLFSSL_RENESAS_TSIP_TLS_SESSION)
+    if (tsip_useable(ssl)) {
+        if (ssl->specs.hash_size == WC_SHA_DIGEST_SIZE)
+            ret = tsip_Sha1Hmac(ssl, myInner, WOLFSSL_TLS_HMAC_INNER_SZ,
+                                                        in, sz, digest, verify);
+        else if (ssl->specs.hash_size == WC_SHA256_DIGEST_SIZE)
+            ret = tsip_Sha256Hmac(ssl, myInner, WOLFSSL_TLS_HMAC_INNER_SZ,
+                                                        in, sz, digest, verify);
+        else
+            ret = TSIP_MAC_DIGSZ_E;
+
+        return ret;
+    }
+#endif
+    ret = wc_HmacInit(&hmac, ssl->heap, ssl->devId);
+    if (ret != 0)
+        return ret;
+
+    ret = wc_HmacSetKey(&hmac, wolfSSL_GetHmacType(ssl),
+                                              wolfSSL_GetMacSecret(ssl, verify),
+                                              ssl->specs.hash_size);
+    if (ret == 0) {
+        /* Constant time verification required. */
+        if (verify && padSz >= 0) {
+#if !defined(WOLFSSL_NO_HASH_RAW) && !defined(HAVE_FIPS) && \
+    !defined(HAVE_SELFTEST)
+    #ifdef HAVE_BLAKE2
+            if (wolfSSL_GetHmacType(ssl) == WC_HASH_TYPE_BLAKE2B) {
+                ret = Hmac_UpdateFinal(&hmac, digest, in,
+                                              sz + hashSz + padSz + 1, myInner);
+            }
+            else
+    #endif
+            {
+                ret = Hmac_UpdateFinal_CT(&hmac, digest, in,
+                                              sz + hashSz + padSz + 1, myInner);
+            }
+#else
+            ret = Hmac_UpdateFinal(&hmac, digest, in, sz + hashSz + padSz + 1,
+                                                                       myInner);
+#endif
+        }
+        else {
+            ret = wc_HmacUpdate(&hmac, myInner, sizeof(myInner));
+            if (ret == 0)
+                ret = wc_HmacUpdate(&hmac, in, sz);                /* content */
+            if (ret == 0)
+                ret = wc_HmacFinal(&hmac, digest);
+        }
+    }
+
+    wc_HmacFree(&hmac);
+
+    return ret;
+}
+#endif /* WOLFSSL_AEAD_ONLY */
+
+#endif /* !WOLFSSL_NO_TLS12 */
+
+#ifdef HAVE_TLS_EXTENSIONS
+
+/**
+ * The TLSX semaphore is used to calculate the size of the extensions to be sent
+ * from one peer to another.
+ */
+
+/** Supports up to 64 flags. Increase as needed. */
+#define SEMAPHORE_SIZE 8
+
+/**
+ * Converts the extension type (id) to an index in the semaphore.
+ *
+ * Official reference for TLS extension types:
+ *   http://www.iana.org/assignments/tls-extensiontype-values/tls-extensiontype-values.xml
+ *
+ * Motivation:
+ *   Previously, we used the extension type itself as the index of that
+ *   extension in the semaphore as the extension types were declared
+ *   sequentially, but maintain a semaphore as big as the number of available
+ *   extensions is no longer an option since the release of renegotiation_info.
+ *
+ * How to update:
+ *   Assign extension types that extrapolate the number of available semaphores
+ *   to the first available index going backwards in the semaphore array.
+ *   When adding a new extension type that don't extrapolate the number of
+ *   available semaphores, check for a possible collision with with a
+ *   'remapped' extension type.
+ */
+static WC_INLINE word16 TLSX_ToSemaphore(word16 type)
+{
+    switch (type) {
+
+        case TLSX_RENEGOTIATION_INFO: /* 0xFF01 */
+            return 63;
+
+        default:
+            if (type > 62) {
+                /* This message SHOULD only happens during the adding of
+                   new TLS extensions in which its IANA number overflows
+                   the current semaphore's range, or if its number already
+                   is assigned to be used by another extension.
+                   Use this check value for the new extension and decrement
+                   the check value by one. */
+                WOLFSSL_MSG("### TLSX semaphore collision or overflow detected!");
+            }
+    }
+
+    return type;
+}
+
+/** Checks if a specific light (tls extension) is not set in the semaphore. */
+#define IS_OFF(semaphore, light) \
+    (!(((semaphore)[(light) / 8] &  (byte) (0x01 << ((light) % 8)))))
+
+/** Turn on a specific light (tls extension) in the semaphore. */
+/* the semaphore marks the extensions already written to the message */
+#define TURN_ON(semaphore, light) \
+    ((semaphore)[(light) / 8] |= (byte) (0x01 << ((light) % 8)))
+
+/** Turn off a specific light (tls extension) in the semaphore. */
+#define TURN_OFF(semaphore, light) \
+    ((semaphore)[(light) / 8] &= (byte) ~(0x01 << ((light) % 8)))
+
+/** Creates a new extension. */
+static TLSX* TLSX_New(TLSX_Type type, void* data, void* heap)
+{
+    TLSX* extension = (TLSX*)XMALLOC(sizeof(TLSX), heap, DYNAMIC_TYPE_TLSX);
+
+    (void)heap;
+
+    if (extension) {
+        extension->type = type;
+        extension->data = data;
+        extension->resp = 0;
+        extension->next = NULL;
+    }
+
+    return extension;
+}
+
+/**
+ * Creates a new extension and pushes it to the provided list.
+ * Checks for duplicate extensions, keeps the newest.
+ */
+static int TLSX_Push(TLSX** list, TLSX_Type type, void* data, void* heap)
+{
+    TLSX* extension = TLSX_New(type, data, heap);
+
+    if (extension == NULL)
+        return MEMORY_E;
+
+    /* pushes the new extension on the list. */
+    extension->next = *list;
+    *list = extension;
+
+    /* remove duplicate extensions, there should be only one of each type. */
+    do {
+        if (extension->next && extension->next->type == type) {
+            TLSX *next = extension->next;
+
+            extension->next = next->next;
+            next->next = NULL;
+
+            TLSX_FreeAll(next, heap);
+
+            /* there is no way to occur more than
+             * two extensions of the same type.
+             */
+            break;
+        }
+    } while ((extension = extension->next));
+
+    return 0;
+}
+
+#ifndef NO_WOLFSSL_CLIENT
+
+int TLSX_CheckUnsupportedExtension(WOLFSSL* ssl, TLSX_Type type);
+
+int TLSX_CheckUnsupportedExtension(WOLFSSL* ssl, TLSX_Type type)
+{
+    TLSX *extension = TLSX_Find(ssl->extensions, type);
+
+    if (!extension)
+        extension = TLSX_Find(ssl->ctx->extensions, type);
+
+    return extension == NULL;
+}
+
+int TLSX_HandleUnsupportedExtension(WOLFSSL* ssl);
+
+int TLSX_HandleUnsupportedExtension(WOLFSSL* ssl)
+{
+    SendAlert(ssl, alert_fatal, unsupported_extension);
+    return UNSUPPORTED_EXTENSION;
+}
+
+#else
+
+#define TLSX_CheckUnsupportedExtension(ssl, type) 0
+#define TLSX_HandleUnsupportedExtension(ssl) 0
+
+#endif
+
+/** Mark an extension to be sent back to the client. */
+void TLSX_SetResponse(WOLFSSL* ssl, TLSX_Type type);
+
+void TLSX_SetResponse(WOLFSSL* ssl, TLSX_Type type)
+{
+    TLSX *extension = TLSX_Find(ssl->extensions, type);
+
+    if (extension)
+        extension->resp = 1;
+}
+
+/******************************************************************************/
+/* Application-Layer Protocol Negotiation                                     */
+/******************************************************************************/
+
+#ifdef HAVE_ALPN
+/** Creates a new ALPN object, providing protocol name to use. */
+static ALPN* TLSX_ALPN_New(char *protocol_name, word16 protocol_nameSz,
+                                                                     void* heap)
+{
+    ALPN *alpn;
+
+    WOLFSSL_ENTER("TLSX_ALPN_New");
+
+    if (protocol_name == NULL ||
+        protocol_nameSz > WOLFSSL_MAX_ALPN_PROTO_NAME_LEN) {
+        WOLFSSL_MSG("Invalid arguments");
+        return NULL;
+    }
+
+    alpn = (ALPN*)XMALLOC(sizeof(ALPN), heap, DYNAMIC_TYPE_TLSX);
+    if (alpn == NULL) {
+        WOLFSSL_MSG("Memory failure");
+        return NULL;
+    }
+
+    alpn->next = NULL;
+    alpn->negotiated = 0;
+    alpn->options = 0;
+
+    alpn->protocol_name = (char*)XMALLOC(protocol_nameSz + 1,
+                                         heap, DYNAMIC_TYPE_TLSX);
+    if (alpn->protocol_name == NULL) {
+        WOLFSSL_MSG("Memory failure");
+        XFREE(alpn, heap, DYNAMIC_TYPE_TLSX);
+        return NULL;
+    }
+
+    XMEMCPY(alpn->protocol_name, protocol_name, protocol_nameSz);
+    alpn->protocol_name[protocol_nameSz] = 0;
+
+    (void)heap;
+
+    return alpn;
+}
+
+/** Releases an ALPN object. */
+static void TLSX_ALPN_Free(ALPN *alpn, void* heap)
+{
+    (void)heap;
+
+    if (alpn == NULL)
+        return;
+
+    XFREE(alpn->protocol_name, heap, DYNAMIC_TYPE_TLSX);
+    XFREE(alpn, heap, DYNAMIC_TYPE_TLSX);
+}
+
+/** Releases all ALPN objects in the provided list. */
+static void TLSX_ALPN_FreeAll(ALPN *list, void* heap)
+{
+    ALPN* alpn;
+
+    while ((alpn = list)) {
+        list = alpn->next;
+        TLSX_ALPN_Free(alpn, heap);
+    }
+}
+
+/** Tells the buffered size of the ALPN objects in a list. */
+static word16 TLSX_ALPN_GetSize(ALPN *list)
+{
+    ALPN* alpn;
+    word16 length = OPAQUE16_LEN; /* list length */
+
+    while ((alpn = list)) {
+        list = alpn->next;
+
+        length++; /* protocol name length is on one byte */
+        length += (word16)XSTRLEN(alpn->protocol_name);
+    }
+
+    return length;
+}
+
+/** Writes the ALPN objects of a list in a buffer. */
+static word16 TLSX_ALPN_Write(ALPN *list, byte *output)
+{
+    ALPN* alpn;
+    word16 length = 0;
+    word16 offset = OPAQUE16_LEN; /* list length offset */
+
+    while ((alpn = list)) {
+        list = alpn->next;
+
+        length = (word16)XSTRLEN(alpn->protocol_name);
+
+        /* protocol name length */
+        output[offset++] = (byte)length;
+
+        /* protocol name value */
+        XMEMCPY(output + offset, alpn->protocol_name, length);
+
+        offset += length;
+    }
+
+    /* writing list length */
+    c16toa(offset - OPAQUE16_LEN, output);
+
+    return offset;
+}
+
+/** Finds a protocol name in the provided ALPN list */
+static ALPN* TLSX_ALPN_Find(ALPN *list, char *protocol_name, word16 size)
+{
+    ALPN *alpn;
+
+    if (list == NULL || protocol_name == NULL)
+        return NULL;
+
+    alpn = list;
+    while (alpn != NULL && (
+           (word16)XSTRLEN(alpn->protocol_name) != size ||
+           XSTRNCMP(alpn->protocol_name, protocol_name, size)))
+        alpn = alpn->next;
+
+    return alpn;
+}
+
+/** Set the ALPN matching client and server requirements */
+static int TLSX_SetALPN(TLSX** extensions, const void* data, word16 size,
+                                                                     void* heap)
+{
+    ALPN *alpn;
+    int  ret;
+
+    if (extensions == NULL || data == NULL)
+        return BAD_FUNC_ARG;
+
+    alpn = TLSX_ALPN_New((char *)data, size, heap);
+    if (alpn == NULL) {
+        WOLFSSL_MSG("Memory failure");
+        return MEMORY_E;
+    }
+
+    alpn->negotiated = 1;
+
+    ret = TLSX_Push(extensions, TLSX_APPLICATION_LAYER_PROTOCOL, (void*)alpn,
+                                                                          heap);
+    if (ret != 0) {
+        TLSX_ALPN_Free(alpn, heap);
+        return ret;
+    }
+
+    return WOLFSSL_SUCCESS;
+}
+
+/** Parses a buffer of ALPN extensions and set the first one matching
+ * client and server requirements */
+static int TLSX_ALPN_ParseAndSet(WOLFSSL *ssl, byte *input, word16 length,
+                                 byte isRequest)
+{
+    word16  size = 0, offset = 0, idx = 0;
+    int     r = BUFFER_ERROR;
+    byte    match = 0;
+    TLSX    *extension;
+    ALPN    *alpn = NULL, *list;
+
+    if (OPAQUE16_LEN > length)
+        return BUFFER_ERROR;
+
+    ato16(input, &size);
+    offset += OPAQUE16_LEN;
+
+    if (size == 0)
+        return BUFFER_ERROR;
+
+    extension = TLSX_Find(ssl->extensions, TLSX_APPLICATION_LAYER_PROTOCOL);
+    if (extension == NULL)
+        extension = TLSX_Find(ssl->ctx->extensions,
+                                               TLSX_APPLICATION_LAYER_PROTOCOL);
+
+#if defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY)
+    if (ssl->alpnSelect != NULL) {
+        const byte* out;
+        unsigned char outLen;
+
+        if (ssl->alpnSelect(ssl, &out, &outLen, input + offset, size,
+                            ssl->alpnSelectArg) == 0) {
+            WOLFSSL_MSG("ALPN protocol match");
+            if (TLSX_UseALPN(&ssl->extensions, (char*)out, outLen, 0, ssl->heap)
+                                                           == WOLFSSL_SUCCESS) {
+                if (extension == NULL) {
+                    extension = TLSX_Find(ssl->extensions,
+                                          TLSX_APPLICATION_LAYER_PROTOCOL);
+                }
+            }
+        }
+    }
+#endif
+
+    if (extension == NULL || extension->data == NULL) {
+        return isRequest ? 0
+                         : TLSX_HandleUnsupportedExtension(ssl);
+    }
+
+    /* validating alpn list length */
+    if (length != OPAQUE16_LEN + size)
+        return BUFFER_ERROR;
+
+    list = (ALPN*)extension->data;
+
+    /* keep the list sent by client */
+    if (isRequest) {
+        if (ssl->alpn_client_list != NULL)
+            XFREE(ssl->alpn_client_list, ssl->heap, DYNAMIC_TYPE_ALPN);
+
+        ssl->alpn_client_list = (char *)XMALLOC(size, ssl->heap,
+                                                DYNAMIC_TYPE_ALPN);
+        if (ssl->alpn_client_list == NULL)
+            return MEMORY_ERROR;
+    }
+
+    for (size = 0; offset < length; offset += size) {
+
+        size = input[offset++];
+        if (offset + size > length || size == 0)
+            return BUFFER_ERROR;
+
+        if (isRequest) {
+            XMEMCPY(ssl->alpn_client_list+idx, (char*)input + offset, size);
+            idx += size;
+            ssl->alpn_client_list[idx++] = ',';
+        }
+
+        if (!match) {
+            alpn = TLSX_ALPN_Find(list, (char*)input + offset, size);
+            if (alpn != NULL) {
+                WOLFSSL_MSG("ALPN protocol match");
+                match = 1;
+
+                /* skip reading other values if not required */
+                if (!isRequest)
+                    break;
+            }
+        }
+    }
+
+    if (isRequest)
+        ssl->alpn_client_list[idx-1] = 0;
+
+    if (!match) {
+        WOLFSSL_MSG("No ALPN protocol match");
+
+        /* do nothing if no protocol match between client and server and option
+         is set to continue (like OpenSSL) */
+        if (list->options & WOLFSSL_ALPN_CONTINUE_ON_MISMATCH) {
+            WOLFSSL_MSG("Continue on mismatch");
+            return 0;
+        }
+
+        SendAlert(ssl, alert_fatal, no_application_protocol);
+        return UNKNOWN_ALPN_PROTOCOL_NAME_E;
+    }
+
+    /* set the matching negotiated protocol */
+    r = TLSX_SetALPN(&ssl->extensions,
+                     alpn->protocol_name,
+                     (word16)XSTRLEN(alpn->protocol_name),
+                     ssl->heap);
+    if (r != WOLFSSL_SUCCESS) {
+        WOLFSSL_MSG("TLSX_UseALPN failed");
+        return BUFFER_ERROR;
+    }
+
+    /* reply to ALPN extension sent from client */
+    if (isRequest) {
+#ifndef NO_WOLFSSL_SERVER
+        TLSX_SetResponse(ssl, TLSX_APPLICATION_LAYER_PROTOCOL);
+#endif
+    }
+
+    return 0;
+}
+
+/** Add a protocol name to the list of accepted usable ones */
+int TLSX_UseALPN(TLSX** extensions, const void* data, word16 size, byte options,
+                                                                     void* heap)
+{
+    ALPN *alpn;
+    TLSX *extension;
+    int  ret;
+
+    if (extensions == NULL || data == NULL)
+        return BAD_FUNC_ARG;
+
+    alpn = TLSX_ALPN_New((char *)data, size, heap);
+    if (alpn == NULL) {
+        WOLFSSL_MSG("Memory failure");
+        return MEMORY_E;
+    }
+
+    /* Set Options of ALPN */
+    alpn->options = options;
+
+    extension = TLSX_Find(*extensions, TLSX_APPLICATION_LAYER_PROTOCOL);
+    if (extension == NULL) {
+        ret = TLSX_Push(extensions, TLSX_APPLICATION_LAYER_PROTOCOL,
+                                                             (void*)alpn, heap);
+        if (ret != 0) {
+            TLSX_ALPN_Free(alpn, heap);
+            return ret;
+        }
+    }
+    else {
+        /* push new ALPN object to extension data. */
+        alpn->next = (ALPN*)extension->data;
+        extension->data = (void*)alpn;
+    }
+
+    return WOLFSSL_SUCCESS;
+}
+
+/** Get the protocol name set by the server */
+int TLSX_ALPN_GetRequest(TLSX* extensions, void** data, word16 *dataSz)
+{
+    TLSX *extension;
+    ALPN *alpn;
+
+    if (extensions == NULL || data == NULL || dataSz == NULL)
+        return BAD_FUNC_ARG;
+
+    extension = TLSX_Find(extensions, TLSX_APPLICATION_LAYER_PROTOCOL);
+    if (extension == NULL) {
+        WOLFSSL_MSG("TLS extension not found");
+        return WOLFSSL_ALPN_NOT_FOUND;
+    }
+
+    alpn = (ALPN *)extension->data;
+    if (alpn == NULL) {
+        WOLFSSL_MSG("ALPN extension not found");
+        *data = NULL;
+        *dataSz = 0;
+        return WOLFSSL_FATAL_ERROR;
+    }
+
+    if (alpn->negotiated != 1) {
+
+        /* consider as an error */
+        if (alpn->options & WOLFSSL_ALPN_FAILED_ON_MISMATCH) {
+            WOLFSSL_MSG("No protocol match with peer -> Failed");
+            return WOLFSSL_FATAL_ERROR;
+        }
+
+        /* continue without negotiated protocol */
+        WOLFSSL_MSG("No protocol match with peer -> Continue");
+        return WOLFSSL_ALPN_NOT_FOUND;
+    }
+
+    if (alpn->next != NULL) {
+        WOLFSSL_MSG("Only one protocol name must be accepted");
+        return WOLFSSL_FATAL_ERROR;
+    }
+
+    *data = alpn->protocol_name;
+    *dataSz = (word16)XSTRLEN((char*)*data);
+
+    return WOLFSSL_SUCCESS;
+}
+
+#define ALPN_FREE_ALL     TLSX_ALPN_FreeAll
+#define ALPN_GET_SIZE     TLSX_ALPN_GetSize
+#define ALPN_WRITE        TLSX_ALPN_Write
+#define ALPN_PARSE        TLSX_ALPN_ParseAndSet
+
+#else /* HAVE_ALPN */
+
+#define ALPN_FREE_ALL(list, heap)
+#define ALPN_GET_SIZE(list)     0
+#define ALPN_WRITE(a, b)        0
+#define ALPN_PARSE(a, b, c, d)  0
+
+#endif /* HAVE_ALPN */
+
+/******************************************************************************/
+/* Server Name Indication                                                     */
+/******************************************************************************/
+
+#ifdef HAVE_SNI
+
+/** Creates a new SNI object. */
+static SNI* TLSX_SNI_New(byte type, const void* data, word16 size, void* heap)
+{
+    SNI* sni = (SNI*)XMALLOC(sizeof(SNI), heap, DYNAMIC_TYPE_TLSX);
+
+    (void)heap;
+
+    if (sni) {
+        sni->type = type;
+        sni->next = NULL;
+
+    #ifndef NO_WOLFSSL_SERVER
+        sni->options = 0;
+        sni->status  = WOLFSSL_SNI_NO_MATCH;
+    #endif
+
+        switch (sni->type) {
+            case WOLFSSL_SNI_HOST_NAME:
+                sni->data.host_name = (char*)XMALLOC(size + 1, heap,
+                                                     DYNAMIC_TYPE_TLSX);
+                if (sni->data.host_name) {
+                    XSTRNCPY(sni->data.host_name, (const char*)data, size);
+                    sni->data.host_name[size] = '\0';
+                } else {
+                    XFREE(sni, heap, DYNAMIC_TYPE_TLSX);
+                    sni = NULL;
+                }
+            break;
+
+            default: /* invalid type */
+                XFREE(sni, heap, DYNAMIC_TYPE_TLSX);
+                sni = NULL;
+        }
+    }
+
+    return sni;
+}
+
+/** Releases a SNI object. */
+static void TLSX_SNI_Free(SNI* sni, void* heap)
+{
+    if (sni) {
+        switch (sni->type) {
+            case WOLFSSL_SNI_HOST_NAME:
+                XFREE(sni->data.host_name, heap, DYNAMIC_TYPE_TLSX);
+            break;
+        }
+
+        XFREE(sni, heap, DYNAMIC_TYPE_TLSX);
+    }
+    (void)heap;
+}
+
+/** Releases all SNI objects in the provided list. */
+static void TLSX_SNI_FreeAll(SNI* list, void* heap)
+{
+    SNI* sni;
+
+    while ((sni = list)) {
+        list = sni->next;
+        TLSX_SNI_Free(sni, heap);
+    }
+}
+
+/** Tells the buffered size of the SNI objects in a list. */
+static word16 TLSX_SNI_GetSize(SNI* list)
+{
+    SNI* sni;
+    word16 length = OPAQUE16_LEN; /* list length */
+
+    while ((sni = list)) {
+        list = sni->next;
+
+        length += ENUM_LEN + OPAQUE16_LEN; /* sni type + sni length */
+
+        switch (sni->type) {
+            case WOLFSSL_SNI_HOST_NAME:
+                length += (word16)XSTRLEN((char*)sni->data.host_name);
+            break;
+        }
+    }
+
+    return length;
+}
+
+/** Writes the SNI objects of a list in a buffer. */
+static word16 TLSX_SNI_Write(SNI* list, byte* output)
+{
+    SNI* sni;
+    word16 length = 0;
+    word16 offset = OPAQUE16_LEN; /* list length offset */
+
+    while ((sni = list)) {
+        list = sni->next;
+
+        output[offset++] = sni->type; /* sni type */
+
+        switch (sni->type) {
+            case WOLFSSL_SNI_HOST_NAME:
+                length = (word16)XSTRLEN((char*)sni->data.host_name);
+
+                c16toa(length, output + offset); /* sni length */
+                offset += OPAQUE16_LEN;
+
+                XMEMCPY(output + offset, sni->data.host_name, length);
+
+                offset += length;
+            break;
+        }
+    }
+
+    c16toa(offset - OPAQUE16_LEN, output); /* writing list length */
+
+    return offset;
+}
+
+/** Finds a SNI object in the provided list. */
+static SNI* TLSX_SNI_Find(SNI *list, byte type)
+{
+    SNI* sni = list;
+
+    while (sni && sni->type != type)
+        sni = sni->next;
+
+    return sni;
+}
+
+/** Sets the status of a SNI object. */
+static void TLSX_SNI_SetStatus(TLSX* extensions, byte type, byte status)
+{
+    TLSX* extension = TLSX_Find(extensions, TLSX_SERVER_NAME);
+    SNI* sni = TLSX_SNI_Find(extension ? (SNI*)extension->data : NULL, type);
+
+    if (sni)
+        sni->status = status;
+}
+
+/** Gets the status of a SNI object. */
+byte TLSX_SNI_Status(TLSX* extensions, byte type)
+{
+    TLSX* extension = TLSX_Find(extensions, TLSX_SERVER_NAME);
+    SNI* sni = TLSX_SNI_Find(extension ? (SNI*)extension->data : NULL, type);
+
+    if (sni)
+        return sni->status;
+
+    return 0;
+}
+
+/** Parses a buffer of SNI extensions. */
+static int TLSX_SNI_Parse(WOLFSSL* ssl, byte* input, word16 length,
+                                                                 byte isRequest)
+{
+#ifndef NO_WOLFSSL_SERVER
+    word16 size = 0;
+    word16 offset = 0;
+    int cacheOnly = 0;
+    SNI *sni = NULL;
+    byte type;
+    int matchStat;
+    byte matched;
+#endif
+
+    TLSX *extension = TLSX_Find(ssl->extensions, TLSX_SERVER_NAME);
+
+    if (!extension)
+        extension = TLSX_Find(ssl->ctx->extensions, TLSX_SERVER_NAME);
+
+    if (!isRequest) {
+        #ifndef NO_WOLFSSL_CLIENT
+            if (!extension || !extension->data)
+                return TLSX_HandleUnsupportedExtension(ssl);
+
+            if (length > 0)
+                return BUFFER_ERROR; /* SNI response MUST be empty. */
+
+            /* This call enables wolfSSL_SNI_GetRequest() to be called in the
+             * client side to fetch the used SNI. It will only work if the SNI
+             * was set at the SSL object level. Right now we only support one
+             * name type, WOLFSSL_SNI_HOST_NAME, but in the future, the
+             * inclusion of other name types will turn this method inaccurate,
+             * as the extension response doesn't contains information of which
+             * name was accepted.
+             */
+            TLSX_SNI_SetStatus(ssl->extensions, WOLFSSL_SNI_HOST_NAME,
+                                                        WOLFSSL_SNI_REAL_MATCH);
+
+            return 0;
+        #endif
+    }
+
+#ifndef NO_WOLFSSL_SERVER
+    if (!extension || !extension->data) {
+        #if defined(WOLFSSL_ALWAYS_KEEP_SNI) && !defined(NO_WOLFSSL_SERVER)
+            /* This will keep SNI even though TLSX_UseSNI has not been called.
+            * Enable it so that the received sni is available to functions
+            * that use a custom callback when SNI is received.
+            */
+
+            cacheOnly = 1;
+            WOLFSSL_MSG("Forcing SSL object to store SNI parameter");
+        #else
+            /* Skipping, SNI not enabled at server side. */
+            return 0;
+        #endif
+    }
+
+    if (OPAQUE16_LEN > length)
+        return BUFFER_ERROR;
+
+    ato16(input, &size);
+    offset += OPAQUE16_LEN;
+
+    /* validating sni list length */
+    if (length != OPAQUE16_LEN + size || size == 0)
+        return BUFFER_ERROR;
+
+    /* SNI was badly specified and only one type is now recognized and allowed.
+     * Only one SNI value per type (RFC6066), so, no loop. */
+    type = input[offset++];
+    if (type != WOLFSSL_SNI_HOST_NAME)
+        return BUFFER_ERROR;
+
+    if (offset + OPAQUE16_LEN > length)
+        return BUFFER_ERROR;
+    ato16(input + offset, &size);
+    offset += OPAQUE16_LEN;
+
+    if (offset + size != length || size == 0)
+        return BUFFER_ERROR;
+
+    if (!cacheOnly && !(sni = TLSX_SNI_Find((SNI*)extension->data, type)))
+        return 0; /* not using this type of SNI. */
+
+#ifdef WOLFSSL_TLS13
+    /* Don't process the second ClientHello SNI extension if there
+     * was problems with the first.
+     */
+    if (!cacheOnly && sni->status != 0)
+        return 0;
+#endif
+    matched = cacheOnly || (XSTRLEN(sni->data.host_name) == size &&
+         XSTRNCMP(sni->data.host_name, (const char*)input + offset, size) == 0);
+
+    if (matched || sni->options & WOLFSSL_SNI_ANSWER_ON_MISMATCH) {
+        int r = TLSX_UseSNI(&ssl->extensions, type, input + offset, size,
+                                                                     ssl->heap);
+        if (r != WOLFSSL_SUCCESS)
+            return r; /* throws error. */
+
+        if (cacheOnly) {
+            WOLFSSL_MSG("Forcing storage of SNI, Fake match");
+            matchStat = WOLFSSL_SNI_FORCE_KEEP;
+        }
+        else if (matched) {
+            WOLFSSL_MSG("SNI did match!");
+            matchStat = WOLFSSL_SNI_REAL_MATCH;
+        }
+        else {
+            WOLFSSL_MSG("fake SNI match from ANSWER_ON_MISMATCH");
+            matchStat = WOLFSSL_SNI_FAKE_MATCH;
+        }
+
+        TLSX_SNI_SetStatus(ssl->extensions, type, (byte)matchStat);
+
+        if(!cacheOnly)
+            TLSX_SetResponse(ssl, TLSX_SERVER_NAME);
+    }
+    else if (!(sni->options & WOLFSSL_SNI_CONTINUE_ON_MISMATCH)) {
+        SendAlert(ssl, alert_fatal, unrecognized_name);
+
+        return UNKNOWN_SNI_HOST_NAME_E;
+    }
+#else
+    (void)input;
+#endif
+
+    return 0;
+}
+
+static int TLSX_SNI_VerifyParse(WOLFSSL* ssl,  byte isRequest)
+{
+    (void)ssl;
+
+    if (isRequest) {
+    #ifndef NO_WOLFSSL_SERVER
+        TLSX* ctx_ext = TLSX_Find(ssl->ctx->extensions, TLSX_SERVER_NAME);
+        TLSX* ssl_ext = TLSX_Find(ssl->extensions,      TLSX_SERVER_NAME);
+        SNI* ctx_sni = ctx_ext ? (SNI*)ctx_ext->data : NULL;
+        SNI* ssl_sni = ssl_ext ? (SNI*)ssl_ext->data : NULL;
+        SNI* sni = NULL;
+
+        for (; ctx_sni; ctx_sni = ctx_sni->next) {
+            if (ctx_sni->options & WOLFSSL_SNI_ABORT_ON_ABSENCE) {
+                sni = TLSX_SNI_Find(ssl_sni, ctx_sni->type);
+
+                if (sni) {
+                    if (sni->status != WOLFSSL_SNI_NO_MATCH)
+                        continue;
+
+                    /* if ssl level overrides ctx level, it is ok. */
+                    if ((sni->options & WOLFSSL_SNI_ABORT_ON_ABSENCE) == 0)
+                        continue;
+                }
+
+                SendAlert(ssl, alert_fatal, handshake_failure);
+                return SNI_ABSENT_ERROR;
+            }
+        }
+
+        for (; ssl_sni; ssl_sni = ssl_sni->next) {
+            if (ssl_sni->options & WOLFSSL_SNI_ABORT_ON_ABSENCE) {
+                if (ssl_sni->status != WOLFSSL_SNI_NO_MATCH)
+                    continue;
+
+                SendAlert(ssl, alert_fatal, handshake_failure);
+                return SNI_ABSENT_ERROR;
+            }
+        }
+    #endif /* NO_WOLFSSL_SERVER */
+    }
+
+    return 0;
+}
+
+int TLSX_UseSNI(TLSX** extensions, byte type, const void* data, word16 size,
+                                                                     void* heap)
+{
+    TLSX* extension;
+    SNI* sni = NULL;
+
+    if (extensions == NULL || data == NULL)
+        return BAD_FUNC_ARG;
+
+    if ((sni = TLSX_SNI_New(type, data, size, heap)) == NULL)
+        return MEMORY_E;
+
+    extension = TLSX_Find(*extensions, TLSX_SERVER_NAME);
+    if (!extension) {
+        int ret = TLSX_Push(extensions, TLSX_SERVER_NAME, (void*)sni, heap);
+
+        if (ret != 0) {
+            TLSX_SNI_Free(sni, heap);
+            return ret;
+        }
+    }
+    else {
+        /* push new SNI object to extension data. */
+        sni->next = (SNI*)extension->data;
+        extension->data = (void*)sni;
+
+        /* remove duplicate SNI, there should be only one of each type. */
+        do {
+            if (sni->next && sni->next->type == type) {
+                SNI* next = sni->next;
+
+                sni->next = next->next;
+                TLSX_SNI_Free(next, heap);
+
+                /* there is no way to occur more than
+                 * two SNIs of the same type.
+                 */
+                break;
+            }
+        } while ((sni = sni->next));
+    }
+
+    return WOLFSSL_SUCCESS;
+}
+
+#ifndef NO_WOLFSSL_SERVER
+
+/** Tells the SNI requested by the client. */
+word16 TLSX_SNI_GetRequest(TLSX* extensions, byte type, void** data)
+{
+    TLSX* extension = TLSX_Find(extensions, TLSX_SERVER_NAME);
+    SNI* sni = TLSX_SNI_Find(extension ? (SNI*)extension->data : NULL, type);
+
+    if (sni && sni->status != WOLFSSL_SNI_NO_MATCH) {
+        switch (sni->type) {
+            case WOLFSSL_SNI_HOST_NAME:
+                if (data) {
+                    *data = sni->data.host_name;
+                    return (word16)XSTRLEN((char*)*data);
+                }
+        }
+    }
+
+    return 0;
+}
+
+/** Sets the options for a SNI object. */
+void TLSX_SNI_SetOptions(TLSX* extensions, byte type, byte options)
+{
+    TLSX* extension = TLSX_Find(extensions, TLSX_SERVER_NAME);
+    SNI* sni = TLSX_SNI_Find(extension ? (SNI*)extension->data : NULL, type);
+
+    if (sni)
+        sni->options = options;
+}
+
+/** Retrieves a SNI request from a client hello buffer. */
+int TLSX_SNI_GetFromBuffer(const byte* clientHello, word32 helloSz,
+                           byte type, byte* sni, word32* inOutSz)
+{
+    word32 offset = 0;
+    word32 len32 = 0;
+    word16 len16 = 0;
+
+    if (helloSz < RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ + CLIENT_HELLO_FIRST)
+        return INCOMPLETE_DATA;
+
+    /* TLS record header */
+    if ((enum ContentType) clientHello[offset++] != handshake) {
+
+        /* checking for SSLv2.0 client hello according to: */
+        /* http://tools.ietf.org/html/rfc4346#appendix-E.1 */
+        if ((enum HandShakeType) clientHello[++offset] == client_hello) {
+            offset += ENUM_LEN + VERSION_SZ; /* skip version */
+
+            ato16(clientHello + offset, &len16);
+            offset += OPAQUE16_LEN;
+
+            if (len16 % 3) /* cipher_spec_length must be multiple of 3 */
+                return BUFFER_ERROR;
+
+            ato16(clientHello + offset, &len16);
+            /* Returning SNI_UNSUPPORTED do not increment offset here */
+
+            if (len16 != 0) /* session_id_length must be 0 */
+                return BUFFER_ERROR;
+
+            return SNI_UNSUPPORTED;
+        }
+
+        return BUFFER_ERROR;
+    }
+
+    if (clientHello[offset++] != SSLv3_MAJOR)
+        return BUFFER_ERROR;
+
+    if (clientHello[offset++] < TLSv1_MINOR)
+        return SNI_UNSUPPORTED;
+
+    ato16(clientHello + offset, &len16);
+    offset += OPAQUE16_LEN;
+
+    if (offset + len16 > helloSz)
+        return INCOMPLETE_DATA;
+
+    /* Handshake header */
+    if ((enum HandShakeType) clientHello[offset] != client_hello)
+        return BUFFER_ERROR;
+
+    c24to32(clientHello + offset + 1, &len32);
+    offset += HANDSHAKE_HEADER_SZ;
+
+    if (offset + len32 > helloSz)
+        return BUFFER_ERROR;
+
+    /* client hello */
+    offset += VERSION_SZ + RAN_LEN; /* version, random */
+
+    if (helloSz < offset + clientHello[offset])
+        return BUFFER_ERROR;
+
+    offset += ENUM_LEN + clientHello[offset]; /* skip session id */
+
+    /* cypher suites */
+    if (helloSz < offset + OPAQUE16_LEN)
+        return BUFFER_ERROR;
+
+    ato16(clientHello + offset, &len16);
+    offset += OPAQUE16_LEN;
+
+    if (helloSz < offset + len16)
+        return BUFFER_ERROR;
+
+    offset += len16; /* skip cypher suites */
+
+    /* compression methods */
+    if (helloSz < offset + 1)
+        return BUFFER_ERROR;
+
+    if (helloSz < offset + clientHello[offset])
+        return BUFFER_ERROR;
+
+    offset += ENUM_LEN + clientHello[offset]; /* skip compression methods */
+
+    /* extensions */
+    if (helloSz < offset + OPAQUE16_LEN)
+        return 0; /* no extensions in client hello. */
+
+    ato16(clientHello + offset, &len16);
+    offset += OPAQUE16_LEN;
+
+    if (helloSz < offset + len16)
+        return BUFFER_ERROR;
+
+    while (len16 >= OPAQUE16_LEN + OPAQUE16_LEN) {
+        word16 extType;
+        word16 extLen;
+
+        ato16(clientHello + offset, &extType);
+        offset += OPAQUE16_LEN;
+
+        ato16(clientHello + offset, &extLen);
+        offset += OPAQUE16_LEN;
+
+        if (helloSz < offset + extLen)
+            return BUFFER_ERROR;
+
+        if (extType != TLSX_SERVER_NAME) {
+            offset += extLen; /* skip extension */
+        } else {
+            word16 listLen;
+
+            ato16(clientHello + offset, &listLen);
+            offset += OPAQUE16_LEN;
+
+            if (helloSz < offset + listLen)
+                return BUFFER_ERROR;
+
+            while (listLen > ENUM_LEN + OPAQUE16_LEN) {
+                byte   sniType = clientHello[offset++];
+                word16 sniLen;
+
+                ato16(clientHello + offset, &sniLen);
+                offset += OPAQUE16_LEN;
+
+                if (helloSz < offset + sniLen)
+                    return BUFFER_ERROR;
+
+                if (sniType != type) {
+                    offset  += sniLen;
+                    listLen -= min(ENUM_LEN + OPAQUE16_LEN + sniLen, listLen);
+                    continue;
+                }
+
+                *inOutSz = min(sniLen, *inOutSz);
+                XMEMCPY(sni, clientHello + offset, *inOutSz);
+
+                return WOLFSSL_SUCCESS;
+            }
+        }
+
+        len16 -= min(2 * OPAQUE16_LEN + extLen, len16);
+    }
+
+    return len16 ? BUFFER_ERROR : 0;
+}
+
+#endif
+
+#define SNI_FREE_ALL     TLSX_SNI_FreeAll
+#define SNI_GET_SIZE     TLSX_SNI_GetSize
+#define SNI_WRITE        TLSX_SNI_Write
+#define SNI_PARSE        TLSX_SNI_Parse
+#define SNI_VERIFY_PARSE TLSX_SNI_VerifyParse
+
+#else
+
+#define SNI_FREE_ALL(list, heap)
+#define SNI_GET_SIZE(list)     0
+#define SNI_WRITE(a, b)        0
+#define SNI_PARSE(a, b, c, d)  0
+#define SNI_VERIFY_PARSE(a, b) 0
+
+#endif /* HAVE_SNI */
+
+/******************************************************************************/
+/* Trusted CA Key Indication                                                  */
+/******************************************************************************/
+
+#ifdef HAVE_TRUSTED_CA
+
+/** Creates a new TCA object. */
+static TCA* TLSX_TCA_New(byte type, const byte* id, word16 idSz, void* heap)
+{
+    TCA* tca = (TCA*)XMALLOC(sizeof(TCA), heap, DYNAMIC_TYPE_TLSX);
+
+    if (tca) {
+        XMEMSET(tca, 0, sizeof(TCA));
+        tca->type = type;
+
+        switch (type) {
+            case WOLFSSL_TRUSTED_CA_PRE_AGREED:
+                break;
+
+            #ifndef NO_SHA
+            case WOLFSSL_TRUSTED_CA_KEY_SHA1:
+            case WOLFSSL_TRUSTED_CA_CERT_SHA1:
+                if (idSz == WC_SHA_DIGEST_SIZE &&
+                        (tca->id =
+                            (byte*)XMALLOC(idSz, heap, DYNAMIC_TYPE_TLSX))) {
+                    XMEMCPY(tca->id, id, idSz);
+                    tca->idSz = idSz;
+                }
+                else {
+                    XFREE(tca, heap, DYNAMIC_TYPE_TLSX);
+                    tca = NULL;
+                }
+                break;
+            #endif
+
+            case WOLFSSL_TRUSTED_CA_X509_NAME:
+                if (idSz > 0 &&
+                        (tca->id =
+                            (byte*)XMALLOC(idSz, heap, DYNAMIC_TYPE_TLSX))) {
+                    XMEMCPY(tca->id, id, idSz);
+                    tca->idSz = idSz;
+                }
+                else {
+                    XFREE(tca, heap, DYNAMIC_TYPE_TLSX);
+                    tca = NULL;
+                }
+                break;
+
+            default: /* invalid type */
+                XFREE(tca, heap, DYNAMIC_TYPE_TLSX);
+                tca = NULL;
+        }
+    }
+
+    (void)heap;
+
+    return tca;
+}
+
+/** Releases a TCA object. */
+static void TLSX_TCA_Free(TCA* tca, void* heap)
+{
+    (void)heap;
+
+    if (tca) {
+        if (tca->id)
+            XFREE(tca->id, heap, DYNAMIC_TYPE_TLSX);
+        XFREE(tca, heap, DYNAMIC_TYPE_TLSX);
+    }
+}
+
+/** Releases all TCA objects in the provided list. */
+static void TLSX_TCA_FreeAll(TCA* list, void* heap)
+{
+    TCA* tca;
+
+    while ((tca = list)) {
+        list = tca->next;
+        TLSX_TCA_Free(tca, heap);
+    }
+}
+
+/** Tells the buffered size of the TCA objects in a list. */
+static word16 TLSX_TCA_GetSize(TCA* list)
+{
+    TCA* tca;
+    word16 length = OPAQUE16_LEN; /* list length */
+
+    while ((tca = list)) {
+        list = tca->next;
+
+        length += ENUM_LEN; /* tca type */
+
+        switch (tca->type) {
+            case WOLFSSL_TRUSTED_CA_PRE_AGREED:
+                break;
+            case WOLFSSL_TRUSTED_CA_KEY_SHA1:
+            case WOLFSSL_TRUSTED_CA_CERT_SHA1:
+                length += tca->idSz;
+                break;
+            case WOLFSSL_TRUSTED_CA_X509_NAME:
+                length += OPAQUE16_LEN + tca->idSz;
+                break;
+        }
+    }
+
+    return length;
+}
+
+/** Writes the TCA objects of a list in a buffer. */
+static word16 TLSX_TCA_Write(TCA* list, byte* output)
+{
+    TCA* tca;
+    word16 offset = OPAQUE16_LEN; /* list length offset */
+
+    while ((tca = list)) {
+        list = tca->next;
+
+        output[offset++] = tca->type; /* tca type */
+
+        switch (tca->type) {
+            case WOLFSSL_TRUSTED_CA_PRE_AGREED:
+                break;
+            #ifndef NO_SHA
+            case WOLFSSL_TRUSTED_CA_KEY_SHA1:
+            case WOLFSSL_TRUSTED_CA_CERT_SHA1:
+                if (tca->id != NULL) {
+                    XMEMCPY(output + offset, tca->id, tca->idSz);
+                    offset += tca->idSz;
+                }
+                else {
+                    /* ID missing. Set to an empty string. */
+                    c16toa(0, output + offset);
+                    offset += OPAQUE16_LEN;
+                }
+                break;
+            #endif
+            case WOLFSSL_TRUSTED_CA_X509_NAME:
+                if (tca->id != NULL) {
+                    c16toa(tca->idSz, output + offset); /* tca length */
+                    offset += OPAQUE16_LEN;
+                    XMEMCPY(output + offset, tca->id, tca->idSz);
+                    offset += tca->idSz;
+                }
+                else {
+                    /* ID missing. Set to an empty string. */
+                    c16toa(0, output + offset);
+                    offset += OPAQUE16_LEN;
+                }
+                break;
+            default:
+                /* ID unknown. Set to an empty string. */
+                c16toa(0, output + offset);
+                offset += OPAQUE16_LEN;
+        }
+    }
+
+    c16toa(offset - OPAQUE16_LEN, output); /* writing list length */
+
+    return offset;
+}
+
+#ifndef NO_WOLFSSL_SERVER
+static TCA* TLSX_TCA_Find(TCA *list, byte type, const byte* id, word16 idSz)
+{
+    TCA* tca = list;
+
+    while (tca && tca->type != type && type != WOLFSSL_TRUSTED_CA_PRE_AGREED &&
+           idSz != tca->idSz && !XMEMCMP(id, tca->id, idSz))
+        tca = tca->next;
+
+    return tca;
+}
+#endif /* NO_WOLFSSL_SERVER */
+
+/** Parses a buffer of TCA extensions. */
+static int TLSX_TCA_Parse(WOLFSSL* ssl, const byte* input, word16 length,
+                          byte isRequest)
+{
+#ifndef NO_WOLFSSL_SERVER
+    word16 size = 0;
+    word16 offset = 0;
+#endif
+
+    TLSX *extension = TLSX_Find(ssl->extensions, TLSX_TRUSTED_CA_KEYS);
+
+    if (!extension)
+        extension = TLSX_Find(ssl->ctx->extensions, TLSX_TRUSTED_CA_KEYS);
+
+    if (!isRequest) {
+        #ifndef NO_WOLFSSL_CLIENT
+            if (!extension || !extension->data)
+                return TLSX_HandleUnsupportedExtension(ssl);
+
+            if (length > 0)
+                return BUFFER_ERROR; /* TCA response MUST be empty. */
+
+            /* Set the flag that we're good for keys */
+            TLSX_SetResponse(ssl, TLSX_TRUSTED_CA_KEYS);
+
+            return 0;
+        #endif
+    }
+
+#ifndef NO_WOLFSSL_SERVER
+    if (!extension || !extension->data) {
+        /* Skipping, TCA not enabled at server side. */
+        return 0;
+    }
+
+    if (OPAQUE16_LEN > length)
+        return BUFFER_ERROR;
+
+    ato16(input, &size);
+    offset += OPAQUE16_LEN;
+
+    /* validating tca list length */
+    if (length != OPAQUE16_LEN + size)
+        return BUFFER_ERROR;
+
+    for (size = 0; offset < length; offset += size) {
+        TCA *tca = NULL;
+        byte type;
+        const byte* id = NULL;
+        word16 idSz = 0;
+
+        if (offset + ENUM_LEN > length)
+            return BUFFER_ERROR;
+
+        type = input[offset++];
+
+        switch (type) {
+            case WOLFSSL_TRUSTED_CA_PRE_AGREED:
+                break;
+            #ifndef NO_SHA
+            case WOLFSSL_TRUSTED_CA_KEY_SHA1:
+            case WOLFSSL_TRUSTED_CA_CERT_SHA1:
+                if (offset + WC_SHA_DIGEST_SIZE > length)
+                    return BUFFER_ERROR;
+                idSz = WC_SHA_DIGEST_SIZE;
+                id = input + offset;
+                offset += idSz;
+                break;
+            #endif
+            case WOLFSSL_TRUSTED_CA_X509_NAME:
+                if (offset + OPAQUE16_LEN > length)
+                    return BUFFER_ERROR;
+                ato16(input + offset, &idSz);
+                offset += OPAQUE16_LEN;
+                if ((offset > length) || (idSz > length - offset))
+                    return BUFFER_ERROR;
+                id = input + offset;
+                offset += idSz;
+                break;
+            default:
+                return TCA_INVALID_ID_TYPE;
+        }
+
+        /* Find the type/ID in the TCA list. */
+        tca = TLSX_TCA_Find((TCA*)extension->data, type, id, idSz);
+        if (tca != NULL) {
+            /* Found it. Set the response flag and break out of the loop. */
+            TLSX_SetResponse(ssl, TLSX_TRUSTED_CA_KEYS);
+            break;
+        }
+    }
+#else
+    (void)input;
+#endif
+
+    return 0;
+}
+
+/* Checks to see if the server sent a response for the TCA. */
+static int TLSX_TCA_VerifyParse(WOLFSSL* ssl, byte isRequest)
+{
+    (void)ssl;
+
+    if (!isRequest) {
+    #ifndef NO_WOLFSSL_CLIENT
+        TLSX* extension = TLSX_Find(ssl->extensions, TLSX_TRUSTED_CA_KEYS);
+
+        if (extension && !extension->resp) {
+            SendAlert(ssl, alert_fatal, handshake_failure);
+            return TCA_ABSENT_ERROR;
+        }
+    #endif /* NO_WOLFSSL_CLIENT */
+    }
+
+    return 0;
+}
+
+int TLSX_UseTrustedCA(TLSX** extensions, byte type,
+                    const byte* id, word16 idSz, void* heap)
+{
+    TLSX* extension;
+    TCA* tca = NULL;
+
+    if (extensions == NULL)
+        return BAD_FUNC_ARG;
+
+    if ((tca = TLSX_TCA_New(type, id, idSz, heap)) == NULL)
+        return MEMORY_E;
+
+    extension = TLSX_Find(*extensions, TLSX_TRUSTED_CA_KEYS);
+    if (!extension) {
+        int ret = TLSX_Push(extensions, TLSX_TRUSTED_CA_KEYS, (void*)tca, heap);
+
+        if (ret != 0) {
+            TLSX_TCA_Free(tca, heap);
+            return ret;
+        }
+    }
+    else {
+        /* push new TCA object to extension data. */
+        tca->next = (TCA*)extension->data;
+        extension->data = (void*)tca;
+    }
+
+    return WOLFSSL_SUCCESS;
+}
+
+#define TCA_FREE_ALL     TLSX_TCA_FreeAll
+#define TCA_GET_SIZE     TLSX_TCA_GetSize
+#define TCA_WRITE        TLSX_TCA_Write
+#define TCA_PARSE        TLSX_TCA_Parse
+#define TCA_VERIFY_PARSE TLSX_TCA_VerifyParse
+
+#else /* HAVE_TRUSTED_CA */
+
+#define TCA_FREE_ALL(list, heap)
+#define TCA_GET_SIZE(list)     0
+#define TCA_WRITE(a, b)        0
+#define TCA_PARSE(a, b, c, d)  0
+#define TCA_VERIFY_PARSE(a, b) 0
+
+#endif /* HAVE_TRUSTED_CA */
+
+/******************************************************************************/
+/* Max Fragment Length Negotiation                                            */
+/******************************************************************************/
+
+#ifdef HAVE_MAX_FRAGMENT
+
+static word16 TLSX_MFL_Write(byte* data, byte* output)
+{
+    output[0] = data[0];
+
+    return ENUM_LEN;
+}
+
+static int TLSX_MFL_Parse(WOLFSSL* ssl, byte* input, word16 length,
+                                                                 byte isRequest)
+{
+    if (length != ENUM_LEN)
+        return BUFFER_ERROR;
+
+#ifdef WOLFSSL_OLD_UNSUPPORTED_EXTENSION
+    (void) isRequest;
+#else
+    if (!isRequest)
+        if (TLSX_CheckUnsupportedExtension(ssl, TLSX_MAX_FRAGMENT_LENGTH))
+            return TLSX_HandleUnsupportedExtension(ssl);
+#endif
+
+    switch (*input) {
+        case WOLFSSL_MFL_2_8 : ssl->max_fragment =  256; break;
+        case WOLFSSL_MFL_2_9 : ssl->max_fragment =  512; break;
+        case WOLFSSL_MFL_2_10: ssl->max_fragment = 1024; break;
+        case WOLFSSL_MFL_2_11: ssl->max_fragment = 2048; break;
+        case WOLFSSL_MFL_2_12: ssl->max_fragment = 4096; break;
+        case WOLFSSL_MFL_2_13: ssl->max_fragment = 8192; break;
+
+        default:
+            SendAlert(ssl, alert_fatal, illegal_parameter);
+
+            return UNKNOWN_MAX_FRAG_LEN_E;
+    }
+
+#ifndef NO_WOLFSSL_SERVER
+    if (isRequest) {
+        int ret = TLSX_UseMaxFragment(&ssl->extensions, *input, ssl->heap);
+
+        if (ret != WOLFSSL_SUCCESS)
+            return ret; /* throw error */
+
+        TLSX_SetResponse(ssl, TLSX_MAX_FRAGMENT_LENGTH);
+    }
+#endif
+
+    return 0;
+}
+
+int TLSX_UseMaxFragment(TLSX** extensions, byte mfl, void* heap)
+{
+    byte* data = NULL;
+    int ret = 0;
+
+    if (extensions == NULL || mfl < WOLFSSL_MFL_MIN || mfl > WOLFSSL_MFL_MAX)
+        return BAD_FUNC_ARG;
+
+    data = (byte*)XMALLOC(ENUM_LEN, heap, DYNAMIC_TYPE_TLSX);
+    if (data == NULL)
+        return MEMORY_E;
+
+    data[0] = mfl;
+
+    ret = TLSX_Push(extensions, TLSX_MAX_FRAGMENT_LENGTH, data, heap);
+    if (ret != 0) {
+        XFREE(data, heap, DYNAMIC_TYPE_TLSX);
+        return ret;
+    }
+
+    return WOLFSSL_SUCCESS;
+}
+
+
+#define MFL_FREE_ALL(data, heap) XFREE(data, (heap), DYNAMIC_TYPE_TLSX)
+#define MFL_GET_SIZE(data) ENUM_LEN
+#define MFL_WRITE          TLSX_MFL_Write
+#define MFL_PARSE          TLSX_MFL_Parse
+
+#else
+
+#define MFL_FREE_ALL(a, b)
+#define MFL_GET_SIZE(a)       0
+#define MFL_WRITE(a, b)       0
+#define MFL_PARSE(a, b, c, d) 0
+
+#endif /* HAVE_MAX_FRAGMENT */
+
+/******************************************************************************/
+/* Truncated HMAC                                                             */
+/******************************************************************************/
+
+#ifdef HAVE_TRUNCATED_HMAC
+
+static int TLSX_THM_Parse(WOLFSSL* ssl, byte* input, word16 length,
+                                                                 byte isRequest)
+{
+    if (length != 0 || input == NULL)
+        return BUFFER_ERROR;
+
+    if (!isRequest) {
+    #ifndef WOLFSSL_OLD_UNSUPPORTED_EXTENSION
+        if (TLSX_CheckUnsupportedExtension(ssl, TLSX_TRUNCATED_HMAC))
+            return TLSX_HandleUnsupportedExtension(ssl);
+    #endif
+    }
+    else {
+        #ifndef NO_WOLFSSL_SERVER
+            int ret = TLSX_UseTruncatedHMAC(&ssl->extensions, ssl->heap);
+
+            if (ret != WOLFSSL_SUCCESS)
+                return ret; /* throw error */
+
+            TLSX_SetResponse(ssl, TLSX_TRUNCATED_HMAC);
+        #endif
+    }
+
+    ssl->truncated_hmac = 1;
+
+    return 0;
+}
+
+int TLSX_UseTruncatedHMAC(TLSX** extensions, void* heap)
+{
+    int ret = 0;
+
+    if (extensions == NULL)
+        return BAD_FUNC_ARG;
+
+    ret = TLSX_Push(extensions, TLSX_TRUNCATED_HMAC, NULL, heap);
+    if (ret != 0)
+        return ret;
+
+    return WOLFSSL_SUCCESS;
+}
+
+#define THM_PARSE TLSX_THM_Parse
+
+#else
+
+#define THM_PARSE(a, b, c, d) 0
+
+#endif /* HAVE_TRUNCATED_HMAC */
+
+/******************************************************************************/
+/* Certificate Status Request                                                 */
+/******************************************************************************/
+
+#ifdef HAVE_CERTIFICATE_STATUS_REQUEST
+
+static void TLSX_CSR_Free(CertificateStatusRequest* csr, void* heap)
+{
+    switch (csr->status_type) {
+        case WOLFSSL_CSR_OCSP:
+            FreeOcspRequest(&csr->request.ocsp);
+        break;
+    }
+
+    XFREE(csr, heap, DYNAMIC_TYPE_TLSX);
+    (void)heap;
+}
+
+static word16 TLSX_CSR_GetSize(CertificateStatusRequest* csr, byte isRequest)
+{
+    word16 size = 0;
+
+    /* shut up compiler warnings */
+    (void) csr; (void) isRequest;
+
+#ifndef NO_WOLFSSL_CLIENT
+    if (isRequest) {
+        switch (csr->status_type) {
+            case WOLFSSL_CSR_OCSP:
+                size += ENUM_LEN + 2 * OPAQUE16_LEN;
+
+                if (csr->request.ocsp.nonceSz)
+                    size += OCSP_NONCE_EXT_SZ;
+            break;
+        }
+    }
+#endif
+#if defined(WOLFSSL_TLS13) && !defined(NO_WOLFSSL_SERVER)
+    if (!isRequest && csr->ssl->options.tls1_3)
+        return OPAQUE8_LEN + OPAQUE24_LEN + csr->response.length;
+#endif
+
+    return size;
+}
+
+static word16 TLSX_CSR_Write(CertificateStatusRequest* csr, byte* output,
+                                                                 byte isRequest)
+{
+    /* shut up compiler warnings */
+    (void) csr; (void) output; (void) isRequest;
+
+#ifndef NO_WOLFSSL_CLIENT
+    if (isRequest) {
+        word16 offset = 0;
+        word16 length = 0;
+
+        /* type */
+        output[offset++] = csr->status_type;
+
+        switch (csr->status_type) {
+            case WOLFSSL_CSR_OCSP:
+                /* responder id list */
+                c16toa(0, output + offset);
+                offset += OPAQUE16_LEN;
+
+                /* request extensions */
+                if (csr->request.ocsp.nonceSz)
+                    length = (word16)EncodeOcspRequestExtensions(
+                                                 &csr->request.ocsp,
+                                                 output + offset + OPAQUE16_LEN,
+                                                 OCSP_NONCE_EXT_SZ);
+
+                c16toa(length, output + offset);
+                offset += OPAQUE16_LEN + length;
+
+            break;
+        }
+
+        return offset;
+    }
+#endif
+#if defined(WOLFSSL_TLS13) && !defined(NO_WOLFSSL_SERVER)
+    if (!isRequest && csr->ssl->options.tls1_3) {
+        word16 offset = 0;
+        output[offset++] = csr->status_type;
+        c32to24(csr->response.length, output + offset);
+        offset += OPAQUE24_LEN;
+        XMEMCPY(output + offset, csr->response.buffer, csr->response.length);
+        offset += csr->response.length;
+        return offset;
+    }
+#endif
+
+    return 0;
+}
+
+static int TLSX_CSR_Parse(WOLFSSL* ssl, byte* input, word16 length,
+                                                                 byte isRequest)
+{
+    int ret;
+
+    /* shut up compiler warnings */
+    (void) ssl; (void) input;
+
+    if (!isRequest) {
+#ifndef NO_WOLFSSL_CLIENT
+        TLSX* extension = TLSX_Find(ssl->extensions, TLSX_STATUS_REQUEST);
+        CertificateStatusRequest* csr = extension ?
+                              (CertificateStatusRequest*)extension->data : NULL;
+
+        if (!csr) {
+            /* look at context level */
+            extension = TLSX_Find(ssl->ctx->extensions, TLSX_STATUS_REQUEST);
+            csr = extension ? (CertificateStatusRequest*)extension->data : NULL;
+
+            if (!csr) /* unexpected extension */
+                return TLSX_HandleUnsupportedExtension(ssl);
+
+            /* enable extension at ssl level */
+            ret = TLSX_UseCertificateStatusRequest(&ssl->extensions,
+                                     csr->status_type, csr->options, ssl,
+                                     ssl->heap, ssl->devId);
+            if (ret != WOLFSSL_SUCCESS)
+                return ret;
+
+            switch (csr->status_type) {
+                case WOLFSSL_CSR_OCSP:
+                    /* propagate nonce */
+                    if (csr->request.ocsp.nonceSz) {
+                        OcspRequest* request =
+                             (OcspRequest*)TLSX_CSR_GetRequest(ssl->extensions);
+
+                        if (request) {
+                            XMEMCPY(request->nonce, csr->request.ocsp.nonce,
+                                                    csr->request.ocsp.nonceSz);
+                            request->nonceSz = csr->request.ocsp.nonceSz;
+                        }
+                    }
+                break;
+            }
+        }
+
+        ssl->status_request = 1;
+
+    #ifdef WOLFSSL_TLS13
+        if (ssl->options.tls1_3) {
+            word32       resp_length;
+            word32       offset = 0;
+
+            /* Get the new extension potentially created above. */
+            extension = TLSX_Find(ssl->extensions, TLSX_STATUS_REQUEST);
+            csr = extension ? (CertificateStatusRequest*)extension->data : NULL;
+            if (csr == NULL)
+                return MEMORY_ERROR;
+
+            ret = 0;
+            if (OPAQUE8_LEN + OPAQUE24_LEN > length)
+                ret = BUFFER_ERROR;
+            if (ret == 0 && input[offset++] != WOLFSSL_CSR_OCSP)
+                ret = BAD_CERTIFICATE_STATUS_ERROR;
+            if (ret == 0) {
+                c24to32(input + offset, &resp_length);
+                offset += OPAQUE24_LEN;
+                if (offset + resp_length != length)
+                    ret = BUFFER_ERROR;
+            }
+        #if !defined(NO_WOLFSSL_SERVER)
+            if (ret == 0) {
+                csr->response.buffer = input + offset;
+                csr->response.length = resp_length;
+            }
+        #endif
+
+            return ret;
+        }
+        else
+    #endif
+        {
+            /* extension_data MUST be empty. */
+            return length ? BUFFER_ERROR : 0;
+        }
+#endif
+    }
+    else {
+#ifndef NO_WOLFSSL_SERVER
+        byte   status_type;
+        word16 offset = 0;
+        word16 size = 0;
+
+        if (length == 0)
+            return 0;
+        if (length < ENUM_LEN)
+            return BUFFER_ERROR;
+
+        status_type = input[offset++];
+
+        switch (status_type) {
+            case WOLFSSL_CSR_OCSP: {
+
+                /* skip responder_id_list */
+                if (length - offset < OPAQUE16_LEN)
+                    return BUFFER_ERROR;
+
+                ato16(input + offset, &size);
+                offset += OPAQUE16_LEN + size;
+
+                /* skip request_extensions */
+                if (length - offset < OPAQUE16_LEN)
+                    return BUFFER_ERROR;
+
+                ato16(input + offset, &size);
+                offset += OPAQUE16_LEN + size;
+
+                if (offset > length)
+                    return BUFFER_ERROR;
+
+                /* is able to send OCSP response? */
+                if (ssl->ctx->cm == NULL || !ssl->ctx->cm->ocspStaplingEnabled)
+                    return 0;
+            }
+            break;
+
+            /* unknown status type */
+            default:
+                return 0;
+        }
+
+        /* if using status_request and already sending it, skip this one */
+        #ifdef HAVE_CERTIFICATE_STATUS_REQUEST_V2
+        if (ssl->status_request_v2)
+            return 0;
+        #endif
+
+        /* accept the first good status_type and return */
+        ret = TLSX_UseCertificateStatusRequest(&ssl->extensions, status_type,
+                                                 0, ssl, ssl->heap, ssl->devId);
+        if (ret != WOLFSSL_SUCCESS)
+            return ret; /* throw error */
+
+    #if defined(WOLFSSL_TLS13) && !defined(NO_WOLFSSL_SERVER)
+        if (ssl->options.tls1_3) {
+            OcspRequest* request;
+            TLSX* extension = TLSX_Find(ssl->extensions, TLSX_STATUS_REQUEST);
+            CertificateStatusRequest* csr = extension ?
+                (CertificateStatusRequest*)extension->data : NULL;
+            if (csr == NULL)
+                return MEMORY_ERROR;
+
+            request = &csr->request.ocsp;
+            ret = CreateOcspResponse(ssl, &request, &csr->response);
+            if (ret != 0)
+                return ret;
+            if (csr->response.buffer)
+                TLSX_SetResponse(ssl, TLSX_STATUS_REQUEST);
+        }
+        else
+    #endif
+            TLSX_SetResponse(ssl, TLSX_STATUS_REQUEST);
+        ssl->status_request = status_type;
+#endif
+    }
+
+    return 0;
+}
+
+int TLSX_CSR_InitRequest(TLSX* extensions, DecodedCert* cert, void* heap)
+{
+    TLSX* extension = TLSX_Find(extensions, TLSX_STATUS_REQUEST);
+    CertificateStatusRequest* csr = extension ?
+        (CertificateStatusRequest*)extension->data : NULL;
+    int ret = 0;
+
+    if (csr) {
+        switch (csr->status_type) {
+            case WOLFSSL_CSR_OCSP: {
+                byte nonce[MAX_OCSP_NONCE_SZ];
+                int  nonceSz = csr->request.ocsp.nonceSz;
+
+                /* preserve nonce */
+                XMEMCPY(nonce, csr->request.ocsp.nonce, nonceSz);
+
+                if ((ret = InitOcspRequest(&csr->request.ocsp, cert, 0, heap))
+                                                                           != 0)
+                    return ret;
+
+                /* restore nonce */
+                XMEMCPY(csr->request.ocsp.nonce, nonce, nonceSz);
+                csr->request.ocsp.nonceSz = nonceSz;
+            }
+            break;
+        }
+    }
+
+    return ret;
+}
+
+void* TLSX_CSR_GetRequest(TLSX* extensions)
+{
+    TLSX* extension = TLSX_Find(extensions, TLSX_STATUS_REQUEST);
+    CertificateStatusRequest* csr = extension ?
+                              (CertificateStatusRequest*)extension->data : NULL;
+
+    if (csr) {
+        switch (csr->status_type) {
+            case WOLFSSL_CSR_OCSP:
+                return &csr->request.ocsp;
+            break;
+        }
+    }
+
+    return NULL;
+}
+
+int TLSX_CSR_ForceRequest(WOLFSSL* ssl)
+{
+    TLSX* extension = TLSX_Find(ssl->extensions, TLSX_STATUS_REQUEST);
+    CertificateStatusRequest* csr = extension ?
+                              (CertificateStatusRequest*)extension->data : NULL;
+
+    if (csr) {
+        switch (csr->status_type) {
+            case WOLFSSL_CSR_OCSP:
+                if (ssl->ctx->cm->ocspEnabled) {
+                    csr->request.ocsp.ssl = ssl;
+                    return CheckOcspRequest(ssl->ctx->cm->ocsp,
+                                                      &csr->request.ocsp, NULL);
+                }
+                else
+                    return OCSP_LOOKUP_FAIL;
+        }
+    }
+
+    return 0;
+}
+
+int TLSX_UseCertificateStatusRequest(TLSX** extensions, byte status_type,
+                                         byte options, WOLFSSL* ssl, void* heap,
+                                                                      int devId)
+{
+    CertificateStatusRequest* csr = NULL;
+    int ret = 0;
+
+    if (!extensions || status_type != WOLFSSL_CSR_OCSP)
+        return BAD_FUNC_ARG;
+
+    csr = (CertificateStatusRequest*)
+             XMALLOC(sizeof(CertificateStatusRequest), heap, DYNAMIC_TYPE_TLSX);
+    if (!csr)
+        return MEMORY_E;
+
+    ForceZero(csr, sizeof(CertificateStatusRequest));
+
+    csr->status_type = status_type;
+    csr->options     = options;
+    csr->ssl         = ssl;
+
+    switch (csr->status_type) {
+        case WOLFSSL_CSR_OCSP:
+            if (options & WOLFSSL_CSR_OCSP_USE_NONCE) {
+                WC_RNG rng;
+
+            #ifndef HAVE_FIPS
+                ret = wc_InitRng_ex(&rng, heap, devId);
+            #else
+                ret = wc_InitRng(&rng);
+                (void)devId;
+            #endif
+                if (ret == 0) {
+                    if (wc_RNG_GenerateBlock(&rng, csr->request.ocsp.nonce,
+                                                        MAX_OCSP_NONCE_SZ) == 0)
+                        csr->request.ocsp.nonceSz = MAX_OCSP_NONCE_SZ;
+
+                    wc_FreeRng(&rng);
+                }
+            }
+        break;
+    }
+
+    if ((ret = TLSX_Push(extensions, TLSX_STATUS_REQUEST, csr, heap)) != 0) {
+        XFREE(csr, heap, DYNAMIC_TYPE_TLSX);
+        return ret;
+    }
+
+    return WOLFSSL_SUCCESS;
+}
+
+#define CSR_FREE_ALL TLSX_CSR_Free
+#define CSR_GET_SIZE TLSX_CSR_GetSize
+#define CSR_WRITE    TLSX_CSR_Write
+#define CSR_PARSE    TLSX_CSR_Parse
+
+#else
+
+#define CSR_FREE_ALL(data, heap)
+#define CSR_GET_SIZE(a, b)    0
+#define CSR_WRITE(a, b, c)    0
+#define CSR_PARSE(a, b, c, d) 0
+
+#endif /* HAVE_CERTIFICATE_STATUS_REQUEST */
+
+/******************************************************************************/
+/* Certificate Status Request v2                                              */
+/******************************************************************************/
+
+#ifdef HAVE_CERTIFICATE_STATUS_REQUEST_V2
+
+static void TLSX_CSR2_FreeAll(CertificateStatusRequestItemV2* csr2, void* heap)
+{
+    CertificateStatusRequestItemV2* next;
+
+    for (; csr2; csr2 = next) {
+        next = csr2->next;
+
+        switch (csr2->status_type) {
+            case WOLFSSL_CSR2_OCSP:
+            case WOLFSSL_CSR2_OCSP_MULTI:
+                while(csr2->requests--)
+                    FreeOcspRequest(&csr2->request.ocsp[csr2->requests]);
+            break;
+        }
+
+        XFREE(csr2, heap, DYNAMIC_TYPE_TLSX);
+    }
+    (void)heap;
+}
+
+static word16 TLSX_CSR2_GetSize(CertificateStatusRequestItemV2* csr2,
+                                                                 byte isRequest)
+{
+    word16 size = 0;
+
+    /* shut up compiler warnings */
+    (void) csr2; (void) isRequest;
+
+#ifndef NO_WOLFSSL_CLIENT
+    if (isRequest) {
+        CertificateStatusRequestItemV2* next;
+
+        for (size = OPAQUE16_LEN; csr2; csr2 = next) {
+            next = csr2->next;
+
+            switch (csr2->status_type) {
+                case WOLFSSL_CSR2_OCSP:
+                case WOLFSSL_CSR2_OCSP_MULTI:
+                    size += ENUM_LEN + 3 * OPAQUE16_LEN;
+
+                    if (csr2->request.ocsp[0].nonceSz)
+                        size += OCSP_NONCE_EXT_SZ;
+                break;
+            }
+        }
+    }
+#endif
+
+    return size;
+}
+
+static word16 TLSX_CSR2_Write(CertificateStatusRequestItemV2* csr2,
+                                                   byte* output, byte isRequest)
+{
+    /* shut up compiler warnings */
+    (void) csr2; (void) output; (void) isRequest;
+
+#ifndef NO_WOLFSSL_CLIENT
+    if (isRequest) {
+        word16 offset;
+        word16 length;
+
+        for (offset = OPAQUE16_LEN; csr2 != NULL; csr2 = csr2->next) {
+            /* status_type */
+            output[offset++] = csr2->status_type;
+
+            /* request */
+            switch (csr2->status_type) {
+                case WOLFSSL_CSR2_OCSP:
+                case WOLFSSL_CSR2_OCSP_MULTI:
+                    /* request_length */
+                    length = 2 * OPAQUE16_LEN;
+
+                    if (csr2->request.ocsp[0].nonceSz)
+                        length += OCSP_NONCE_EXT_SZ;
+
+                    c16toa(length, output + offset);
+                    offset += OPAQUE16_LEN;
+
+                    /* responder id list */
+                    c16toa(0, output + offset);
+                    offset += OPAQUE16_LEN;
+
+                    /* request extensions */
+                    length = 0;
+
+                    if (csr2->request.ocsp[0].nonceSz)
+                        length = (word16)EncodeOcspRequestExtensions(
+                                                 &csr2->request.ocsp[0],
+                                                 output + offset + OPAQUE16_LEN,
+                                                 OCSP_NONCE_EXT_SZ);
+
+                    c16toa(length, output + offset);
+                    offset += OPAQUE16_LEN + length;
+                break;
+            }
+        }
+
+        /* list size */
+        c16toa(offset - OPAQUE16_LEN, output);
+
+        return offset;
+    }
+#endif
+
+    return 0;
+}
+
+static int TLSX_CSR2_Parse(WOLFSSL* ssl, byte* input, word16 length,
+                                                                 byte isRequest)
+{
+    int ret;
+
+    /* shut up compiler warnings */
+    (void) ssl; (void) input;
+
+    if (!isRequest) {
+#ifndef NO_WOLFSSL_CLIENT
+        TLSX* extension = TLSX_Find(ssl->extensions, TLSX_STATUS_REQUEST_V2);
+        CertificateStatusRequestItemV2* csr2 = extension ?
+                        (CertificateStatusRequestItemV2*)extension->data : NULL;
+
+        if (!csr2) {
+            /* look at context level */
+            extension = TLSX_Find(ssl->ctx->extensions, TLSX_STATUS_REQUEST_V2);
+            csr2 = extension ?
+                        (CertificateStatusRequestItemV2*)extension->data : NULL;
+
+            if (!csr2) /* unexpected extension */
+                return TLSX_HandleUnsupportedExtension(ssl);
+
+            /* enable extension at ssl level */
+            for (; csr2; csr2 = csr2->next) {
+                ret = TLSX_UseCertificateStatusRequestV2(&ssl->extensions,
+                                    csr2->status_type, csr2->options, ssl->heap,
+                                                                    ssl->devId);
+                if (ret != WOLFSSL_SUCCESS)
+                    return ret;
+
+                switch (csr2->status_type) {
+                    case WOLFSSL_CSR2_OCSP:
+                        /* followed by */
+                    case WOLFSSL_CSR2_OCSP_MULTI:
+                        /* propagate nonce */
+                        if (csr2->request.ocsp[0].nonceSz) {
+                            OcspRequest* request =
+                             (OcspRequest*)TLSX_CSR2_GetRequest(ssl->extensions,
+                                                          csr2->status_type, 0);
+
+                            if (request) {
+                                XMEMCPY(request->nonce,
+                                        csr2->request.ocsp[0].nonce,
+                                        csr2->request.ocsp[0].nonceSz);
+
+                                request->nonceSz =
+                                                  csr2->request.ocsp[0].nonceSz;
+                            }
+                        }
+                    break;
+                }
+            }
+        }
+
+        ssl->status_request_v2 = 1;
+
+        return length ? BUFFER_ERROR : 0; /* extension_data MUST be empty. */
+#endif
+    }
+    else {
+#ifndef NO_WOLFSSL_SERVER
+        byte   status_type;
+        word16 request_length;
+        word16 offset = 0;
+        word16 size = 0;
+
+        /* list size */
+        if (offset + OPAQUE16_LEN >= length) {
+            return BUFFER_E;
+        }
+
+        ato16(input + offset, &request_length);
+        offset += OPAQUE16_LEN;
+
+        if (length - OPAQUE16_LEN != request_length)
+            return BUFFER_ERROR;
+
+        while (length > offset) {
+            if (length - offset < ENUM_LEN + OPAQUE16_LEN)
+                return BUFFER_ERROR;
+
+            status_type = input[offset++];
+
+            ato16(input + offset, &request_length);
+            offset += OPAQUE16_LEN;
+
+            if (length - offset < request_length)
+                return BUFFER_ERROR;
+
+            switch (status_type) {
+                case WOLFSSL_CSR2_OCSP:
+                case WOLFSSL_CSR2_OCSP_MULTI:
+                    /* skip responder_id_list */
+                    if (length - offset < OPAQUE16_LEN)
+                        return BUFFER_ERROR;
+
+                    ato16(input + offset, &size);
+                    if (length - offset < size)
+                        return BUFFER_ERROR;
+
+                    offset += OPAQUE16_LEN + size;
+                    /* skip request_extensions */
+                    if (length - offset < OPAQUE16_LEN)
+                        return BUFFER_ERROR;
+
+                    ato16(input + offset, &size);
+                    if (length - offset < size)
+                        return BUFFER_ERROR;
+
+                    offset += OPAQUE16_LEN + size;
+                    if (offset > length)
+                        return BUFFER_ERROR;
+
+                    /* is able to send OCSP response? */
+                    if (ssl->ctx->cm == NULL
+                    || !ssl->ctx->cm->ocspStaplingEnabled)
+                        continue;
+                break;
+
+                default:
+                    /* unknown status type, skipping! */
+                    offset += request_length;
+                    continue;
+            }
+
+            /* if using status_request and already sending it, skip this one */
+            #ifdef HAVE_CERTIFICATE_STATUS_REQUEST
+            if (ssl->status_request)
+                return 0;
+            #endif
+
+            /* accept the first good status_type and return */
+            ret = TLSX_UseCertificateStatusRequestV2(&ssl->extensions,
+                                         status_type, 0, ssl->heap, ssl->devId);
+            if (ret != WOLFSSL_SUCCESS)
+                return ret; /* throw error */
+
+            TLSX_SetResponse(ssl, TLSX_STATUS_REQUEST_V2);
+            ssl->status_request_v2 = status_type;
+
+            return 0;
+        }
+#endif
+    }
+
+    return 0;
+}
+
+int TLSX_CSR2_InitRequests(TLSX* extensions, DecodedCert* cert, byte isPeer,
+                                                                     void* heap)
+{
+    TLSX* extension = TLSX_Find(extensions, TLSX_STATUS_REQUEST_V2);
+    CertificateStatusRequestItemV2* csr2 = extension ?
+        (CertificateStatusRequestItemV2*)extension->data : NULL;
+    int ret = 0;
+
+    for (; csr2; csr2 = csr2->next) {
+        switch (csr2->status_type) {
+            case WOLFSSL_CSR2_OCSP:
+                if (!isPeer || csr2->requests != 0)
+                    break;
+
+                FALL_THROUGH; /* followed by */
+
+            case WOLFSSL_CSR2_OCSP_MULTI: {
+                if (csr2->requests < 1 + MAX_CHAIN_DEPTH) {
+                    byte nonce[MAX_OCSP_NONCE_SZ];
+                    int  nonceSz = csr2->request.ocsp[0].nonceSz;
+
+                    /* preserve nonce, replicating nonce of ocsp[0] */
+                    XMEMCPY(nonce, csr2->request.ocsp[0].nonce, nonceSz);
+
+                    if ((ret = InitOcspRequest(
+                                      &csr2->request.ocsp[csr2->requests], cert,
+                                                                 0, heap)) != 0)
+                        return ret;
+
+                    /* restore nonce */
+                    XMEMCPY(csr2->request.ocsp[csr2->requests].nonce,
+                                                                nonce, nonceSz);
+                    csr2->request.ocsp[csr2->requests].nonceSz = nonceSz;
+                    csr2->requests++;
+                }
+            }
+            break;
+        }
+    }
+
+    (void)cert;
+    return ret;
+}
+
+void* TLSX_CSR2_GetRequest(TLSX* extensions, byte status_type, byte idx)
+{
+    TLSX* extension = TLSX_Find(extensions, TLSX_STATUS_REQUEST_V2);
+    CertificateStatusRequestItemV2* csr2 = extension ?
+                        (CertificateStatusRequestItemV2*)extension->data : NULL;
+
+    for (; csr2; csr2 = csr2->next) {
+        if (csr2->status_type == status_type) {
+            switch (csr2->status_type) {
+                case WOLFSSL_CSR2_OCSP:
+                    /* followed by */
+
+                case WOLFSSL_CSR2_OCSP_MULTI:
+                    /* requests are initialized in the reverse order */
+                    return idx < csr2->requests
+                         ? &csr2->request.ocsp[csr2->requests - idx - 1]
+                         : NULL;
+                break;
+            }
+        }
+    }
+
+    return NULL;
+}
+
+int TLSX_CSR2_ForceRequest(WOLFSSL* ssl)
+{
+    TLSX* extension = TLSX_Find(ssl->extensions, TLSX_STATUS_REQUEST_V2);
+    CertificateStatusRequestItemV2* csr2 = extension ?
+                        (CertificateStatusRequestItemV2*)extension->data : NULL;
+
+    /* forces only the first one */
+    if (csr2) {
+        switch (csr2->status_type) {
+            case WOLFSSL_CSR2_OCSP:
+                /* followed by */
+
+            case WOLFSSL_CSR2_OCSP_MULTI:
+                if (ssl->ctx->cm->ocspEnabled) {
+                    csr2->request.ocsp[0].ssl = ssl;
+                    return CheckOcspRequest(ssl->ctx->cm->ocsp,
+                                                  &csr2->request.ocsp[0], NULL);
+                }
+                else
+                    return OCSP_LOOKUP_FAIL;
+        }
+    }
+
+    return 0;
+}
+
+int TLSX_UseCertificateStatusRequestV2(TLSX** extensions, byte status_type,
+                                           byte options, void* heap, int devId)
+{
+    TLSX* extension = NULL;
+    CertificateStatusRequestItemV2* csr2 = NULL;
+    int ret = 0;
+
+    if (!extensions)
+        return BAD_FUNC_ARG;
+
+    if (status_type != WOLFSSL_CSR2_OCSP
+    &&  status_type != WOLFSSL_CSR2_OCSP_MULTI)
+        return BAD_FUNC_ARG;
+
+    csr2 = (CertificateStatusRequestItemV2*)
+       XMALLOC(sizeof(CertificateStatusRequestItemV2), heap, DYNAMIC_TYPE_TLSX);
+    if (!csr2)
+        return MEMORY_E;
+
+    ForceZero(csr2, sizeof(CertificateStatusRequestItemV2));
+
+    csr2->status_type = status_type;
+    csr2->options     = options;
+    csr2->next        = NULL;
+
+    switch (csr2->status_type) {
+        case WOLFSSL_CSR2_OCSP:
+        case WOLFSSL_CSR2_OCSP_MULTI:
+            if (options & WOLFSSL_CSR2_OCSP_USE_NONCE) {
+                WC_RNG rng;
+
+            #ifndef HAVE_FIPS
+                ret = wc_InitRng_ex(&rng, heap, devId);
+            #else
+                ret = wc_InitRng(&rng);
+                (void)devId;
+            #endif
+                if (ret == 0) {
+                    if (wc_RNG_GenerateBlock(&rng, csr2->request.ocsp[0].nonce,
+                                                        MAX_OCSP_NONCE_SZ) == 0)
+                        csr2->request.ocsp[0].nonceSz = MAX_OCSP_NONCE_SZ;
+
+                    wc_FreeRng(&rng);
+                }
+            }
+        break;
+    }
+
+    /* append new item */
+    if ((extension = TLSX_Find(*extensions, TLSX_STATUS_REQUEST_V2))) {
+        CertificateStatusRequestItemV2* last =
+                               (CertificateStatusRequestItemV2*)extension->data;
+
+        for (; last->next; last = last->next);
+
+        last->next = csr2;
+    }
+    else if ((ret = TLSX_Push(extensions, TLSX_STATUS_REQUEST_V2, csr2,heap))) {
+        XFREE(csr2, heap, DYNAMIC_TYPE_TLSX);
+        return ret;
+    }
+
+    return WOLFSSL_SUCCESS;
+}
+
+#define CSR2_FREE_ALL TLSX_CSR2_FreeAll
+#define CSR2_GET_SIZE TLSX_CSR2_GetSize
+#define CSR2_WRITE    TLSX_CSR2_Write
+#define CSR2_PARSE    TLSX_CSR2_Parse
+
+#else
+
+#define CSR2_FREE_ALL(data, heap)
+#define CSR2_GET_SIZE(a, b)    0
+#define CSR2_WRITE(a, b, c)    0
+#define CSR2_PARSE(a, b, c, d) 0
+
+#endif /* HAVE_CERTIFICATE_STATUS_REQUEST_V2 */
+
+/******************************************************************************/
+/* Supported Elliptic Curves                                                  */
+/******************************************************************************/
+
+#ifdef HAVE_SUPPORTED_CURVES
+
+#if !defined(HAVE_ECC) && !defined(HAVE_CURVE25519) && !defined(HAVE_CURVE448) \
+                       && !defined(HAVE_FFDHE)
+#error Elliptic Curves Extension requires Elliptic Curve Cryptography. \
+       Use --enable-ecc in the configure script or define HAVE_ECC. \
+       Alternatively use FFDHE for DH ciperhsuites.
+#endif
+
+static int TLSX_SupportedCurve_New(SupportedCurve** curve, word16 name,
+                                                                     void* heap)
+{
+    if (curve == NULL)
+        return BAD_FUNC_ARG;
+
+    (void)heap;
+
+    *curve = (SupportedCurve*)XMALLOC(sizeof(SupportedCurve), heap,
+                                                             DYNAMIC_TYPE_TLSX);
+    if (*curve == NULL)
+        return MEMORY_E;
+
+    (*curve)->name = name;
+    (*curve)->next = NULL;
+
+    return 0;
+}
+
+static int TLSX_PointFormat_New(PointFormat** point, byte format, void* heap)
+{
+    if (point == NULL)
+        return BAD_FUNC_ARG;
+
+    (void)heap;
+
+    *point = (PointFormat*)XMALLOC(sizeof(PointFormat), heap,
+                                                             DYNAMIC_TYPE_TLSX);
+    if (*point == NULL)
+        return MEMORY_E;
+
+    (*point)->format = format;
+    (*point)->next = NULL;
+
+    return 0;
+}
+
+static void TLSX_SupportedCurve_FreeAll(SupportedCurve* list, void* heap)
+{
+    SupportedCurve* curve;
+
+    while ((curve = list)) {
+        list = curve->next;
+        XFREE(curve, heap, DYNAMIC_TYPE_TLSX);
+    }
+    (void)heap;
+}
+
+static void TLSX_PointFormat_FreeAll(PointFormat* list, void* heap)
+{
+    PointFormat* point;
+
+    while ((point = list)) {
+        list = point->next;
+        XFREE(point, heap, DYNAMIC_TYPE_TLSX);
+    }
+    (void)heap;
+}
+
+static int TLSX_SupportedCurve_Append(SupportedCurve* list, word16 name,
+                                                                     void* heap)
+{
+    int ret = BAD_FUNC_ARG;
+
+    while (list) {
+        if (list->name == name) {
+            ret = 0; /* curve already in use */
+            break;
+        }
+
+        if (list->next == NULL) {
+            ret = TLSX_SupportedCurve_New(&list->next, name, heap);
+            break;
+        }
+
+        list = list->next;
+    }
+
+    return ret;
+}
+
+static int TLSX_PointFormat_Append(PointFormat* list, byte format, void* heap)
+{
+    int ret = BAD_FUNC_ARG;
+
+    while (list) {
+        if (list->format == format) {
+            ret = 0; /* format already in use */
+            break;
+        }
+
+        if (list->next == NULL) {
+            ret = TLSX_PointFormat_New(&list->next, format, heap);
+            break;
+        }
+
+        list = list->next;
+    }
+
+    return ret;
+}
+
+#if defined(WOLFSSL_TLS13) || !defined(NO_WOLFSSL_CLIENT)
+
+static void TLSX_SupportedCurve_ValidateRequest(WOLFSSL* ssl, byte* semaphore)
+{
+    word16 i;
+
+    for (i = 0; i < ssl->suites->suiteSz; i+= 2) {
+        if (ssl->suites->suites[i] == TLS13_BYTE)
+            return;
+        if (ssl->suites->suites[i] == ECC_BYTE ||
+                ssl->suites->suites[i] == CHACHA_BYTE) {
+        #if defined(HAVE_ECC) || defined(HAVE_CURVE25519) || \
+                                                          defined(HAVE_CURVE448)
+            return;
+        #endif
+        }
+        else {
+        #ifdef HAVE_FFDHE
+            return;
+        #endif
+        }
+    }
+
+    /* turns semaphore on to avoid sending this extension. */
+    TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_SUPPORTED_GROUPS));
+}
+
+static void TLSX_PointFormat_ValidateRequest(WOLFSSL* ssl, byte* semaphore)
+{
+    word16 i;
+
+    for (i = 0; i < ssl->suites->suiteSz; i+= 2) {
+        if (ssl->suites->suites[i] == TLS13_BYTE)
+            return;
+        if (ssl->suites->suites[i] == ECC_BYTE ||
+                ssl->suites->suites[i] == CHACHA_BYTE) {
+        #if defined(HAVE_ECC) || defined(HAVE_CURVE25519) || \
+                                                          defined(HAVE_CURVE448)
+            return;
+        #endif
+        }
+        else {
+        #ifdef HAVE_FFDHE
+            return;
+        #endif
+        }
+    }
+
+    /* turns semaphore on to avoid sending this extension. */
+    TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_EC_POINT_FORMATS));
+}
+
+#endif
+
+#ifndef NO_WOLFSSL_SERVER
+
+static void TLSX_PointFormat_ValidateResponse(WOLFSSL* ssl, byte* semaphore)
+{
+#if defined(HAVE_FFDHE) || defined(HAVE_ECC) || defined(HAVE_CURVE25519) || \
+                                                          defined(HAVE_CURVE448)
+    (void)semaphore;
+#endif
+
+    if (ssl->options.cipherSuite0 == TLS13_BYTE)
+        return;
+    if (ssl->options.cipherSuite0 == ECC_BYTE ||
+        ssl->options.cipherSuite0 == CHACHA_BYTE) {
+#if defined(HAVE_ECC) || defined(HAVE_CURVE25519) || defined(HAVE_CURVE448)
+        return;
+#endif
+    }
+    else {
+#ifdef HAVE_FFDHE
+        return;
+#endif
+    }
+
+#if !defined(HAVE_FFDHE) || (!defined(HAVE_ECC) && !defined(HAVE_CURVE25519) \
+                                                     && !defined(HAVE_CURVE448))
+    /* turns semaphore on to avoid sending this extension. */
+    TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_EC_POINT_FORMATS));
+#endif
+}
+
+#endif
+#ifndef NO_WOLFSSL_CLIENT
+
+static word16 TLSX_SupportedCurve_GetSize(SupportedCurve* list)
+{
+    SupportedCurve* curve;
+    word16 length = OPAQUE16_LEN; /* list length */
+
+    while ((curve = list)) {
+        list = curve->next;
+        length += OPAQUE16_LEN; /* curve length */
+    }
+
+    return length;
+}
+
+#endif
+
+static word16 TLSX_PointFormat_GetSize(PointFormat* list)
+{
+    PointFormat* point;
+    word16 length = ENUM_LEN; /* list length */
+
+    while ((point = list)) {
+        list = point->next;
+        length += ENUM_LEN; /* format length */
+    }
+
+    return length;
+}
+
+#ifndef NO_WOLFSSL_CLIENT
+
+static word16 TLSX_SupportedCurve_Write(SupportedCurve* list, byte* output)
+{
+    word16 offset = OPAQUE16_LEN;
+
+    while (list) {
+        c16toa(list->name, output + offset);
+        offset += OPAQUE16_LEN;
+        list = list->next;
+    }
+
+    c16toa(offset - OPAQUE16_LEN, output); /* writing list length */
+
+    return offset;
+}
+
+#endif
+
+static word16 TLSX_PointFormat_Write(PointFormat* list, byte* output)
+{
+    word16 offset = ENUM_LEN;
+
+    while (list) {
+        output[offset++] = list->format;
+        list = list->next;
+    }
+
+    output[0] = (byte)(offset - ENUM_LEN);
+
+    return offset;
+}
+
+#if !defined(NO_WOLFSSL_SERVER) || (defined(WOLFSSL_TLS13) && \
+                                         !defined(WOLFSSL_NO_SERVER_GROUPS_EXT))
+
+static int TLSX_SupportedCurve_Parse(WOLFSSL* ssl, byte* input, word16 length,
+                                                                 byte isRequest)
+{
+    word16 offset;
+    word16 name;
+    int ret;
+
+    if(!isRequest && !IsAtLeastTLSv1_3(ssl->version)) {
+#ifdef WOLFSSL_ALLOW_SERVER_SC_EXT
+        return 0;
+#else
+        return BUFFER_ERROR; /* servers doesn't send this extension. */
+#endif
+    }
+
+    if (OPAQUE16_LEN > length || length % OPAQUE16_LEN)
+        return BUFFER_ERROR;
+
+    ato16(input, &offset);
+
+    /* validating curve list length */
+    if (length != OPAQUE16_LEN + offset)
+        return BUFFER_ERROR;
+
+    offset = OPAQUE16_LEN;
+    if (offset == length)
+        return 0;
+
+#if defined(WOLFSSL_TLS13) && !defined(WOLFSSL_NO_SERVER_GROUPS_EXT)
+    if (!isRequest) {
+        TLSX* extension;
+        SupportedCurve* curve;
+
+        extension = TLSX_Find(ssl->extensions, TLSX_SUPPORTED_GROUPS);
+        if (extension != NULL) {
+            /* Replace client list with server list of supported groups. */
+            curve = (SupportedCurve*)extension->data;
+            extension->data = NULL;
+            TLSX_SupportedCurve_FreeAll(curve, ssl->heap);
+
+            ato16(input + offset, &name);
+            offset += OPAQUE16_LEN;
+
+            ret = TLSX_SupportedCurve_New(&curve, name, ssl->heap);
+            if (ret != 0)
+                return ret; /* throw error */
+            extension->data = (void*)curve;
+        }
+    }
+#endif
+
+    for (; offset < length; offset += OPAQUE16_LEN) {
+        ato16(input + offset, &name);
+
+        ret = TLSX_UseSupportedCurve(&ssl->extensions, name, ssl->heap);
+        if (ret != WOLFSSL_SUCCESS)
+            return ret; /* throw error */
+    }
+
+    return 0;
+}
+
+#endif
+
+#if !defined(NO_WOLFSSL_SERVER)
+
+#if defined(WOLFSSL_TLS13) && !defined(WOLFSSL_NO_SERVER_GROUPS_EXT)
+
+/* Checks the priority of the groups on the server and set the supported groups
+ * response if there is a group not advertised by the client that is preferred.
+ *
+ * ssl  SSL/TLS object.
+ * returns 0 on success, otherwise an error.
+ */
+int TLSX_SupportedCurve_CheckPriority(WOLFSSL* ssl)
+{
+    int ret;
+    TLSX* extension;
+    TLSX* priority = NULL;
+    TLSX* ext = NULL;
+    word16 name;
+    SupportedCurve* curve;
+
+    extension = TLSX_Find(ssl->extensions, TLSX_SUPPORTED_GROUPS);
+    /* May be doing PSK with no key exchange. */
+    if (extension == NULL)
+        return 0;
+
+    if ((ret = TLSX_PopulateSupportedGroups(ssl, &priority)) != WOLFSSL_SUCCESS)
+        return ret;
+
+    ext = TLSX_Find(priority, TLSX_SUPPORTED_GROUPS);
+    curve = (SupportedCurve*)ext->data;
+    name = curve->name;
+
+    curve = (SupportedCurve*)extension->data;
+    while (curve != NULL) {
+        if (curve->name == name)
+            break;
+        curve = curve->next;
+    }
+
+    if (curve == NULL) {
+        /* Couldn't find the preferred group in client list. */
+        extension->resp = 1;
+
+        /* Send server list back and free client list. */
+        curve = (SupportedCurve*)extension->data;
+        extension->data = ext->data;
+        ext->data = curve;
+    }
+
+    TLSX_FreeAll(priority, ssl->heap);
+
+    return 0;
+}
+
+#endif
+
+#if defined(HAVE_FFDHE) && !defined(WOLFSSL_NO_TLS12)
+/* Set the highest priority common FFDHE group on the server as compared to
+ * client extensions.
+ *
+ * ssl    SSL/TLS object.
+ * returns 0 on success, otherwise an error.
+ */
+int TLSX_SupportedFFDHE_Set(WOLFSSL* ssl)
+{
+    int ret = 0;
+    TLSX* extension;
+    TLSX* priority = NULL;
+    TLSX* ext = NULL;
+    SupportedCurve* serverGroup;
+    SupportedCurve* clientGroup;
+    SupportedCurve* group;
+    const DhParams* params = NULL;
+    int found = 0;
+
+    extension = TLSX_Find(ssl->extensions, TLSX_SUPPORTED_GROUPS);
+    /* May be doing PSK with no key exchange. */
+    if (extension == NULL)
+        return 0;
+    clientGroup = (SupportedCurve*)extension->data;
+    for (group = clientGroup; group != NULL; group = group->next) {
+        if (group->name >= MIN_FFHDE_GROUP && group->name <= MAX_FFHDE_GROUP) {
+            found = 1;
+            break;
+        }
+    }
+    if (!found)
+        return 0;
+
+    if (ssl->buffers.serverDH_P.buffer && ssl->buffers.weOwnDH) {
+        XFREE(ssl->buffers.serverDH_P.buffer, ssl->heap,
+                                                       DYNAMIC_TYPE_PUBLIC_KEY);
+    }
+    if (ssl->buffers.serverDH_G.buffer && ssl->buffers.weOwnDH) {
+        XFREE(ssl->buffers.serverDH_G.buffer, ssl->heap,
+                                                       DYNAMIC_TYPE_PUBLIC_KEY);
+    }
+    ssl->buffers.serverDH_P.buffer = NULL;
+    ssl->buffers.serverDH_G.buffer = NULL;
+    ssl->buffers.weOwnDH = 0;
+    ssl->options.haveDH = 0;
+
+
+    if ((ret = TLSX_PopulateSupportedGroups(ssl, &priority)) != WOLFSSL_SUCCESS)
+        return ret;
+    ret = 0;
+
+    ext = TLSX_Find(priority, TLSX_SUPPORTED_GROUPS);
+    serverGroup = (SupportedCurve*)ext->data;
+
+    for (; serverGroup != NULL; serverGroup = serverGroup->next) {
+        if ((serverGroup->name & NAMED_DH_MASK) != NAMED_DH_MASK)
+            continue;
+
+        for (group = clientGroup; group != NULL; group = group->next) {
+            if (serverGroup->name != group->name)
+                continue;
+
+            switch (serverGroup->name) {
+            #ifdef HAVE_FFDHE_2048
+                case WOLFSSL_FFDHE_2048:
+                    params = wc_Dh_ffdhe2048_Get();
+                    break;
+            #endif
+            #ifdef HAVE_FFDHE_3072
+                case WOLFSSL_FFDHE_3072:
+                    params = wc_Dh_ffdhe3072_Get();
+                    break;
+            #endif
+            #ifdef HAVE_FFDHE_4096
+                case WOLFSSL_FFDHE_4096:
+                    params = wc_Dh_ffdhe4096_Get();
+                    break;
+            #endif
+            #ifdef HAVE_FFDHE_6144
+                case WOLFSSL_FFDHE_6144:
+                    params = wc_Dh_ffdhe6144_Get();
+                    break;
+            #endif
+            #ifdef HAVE_FFDHE_8192
+                case WOLFSSL_FFDHE_8192:
+                    params = wc_Dh_ffdhe8192_Get();
+                    break;
+            #endif
+            }
+            if (params == NULL)
+                return BAD_FUNC_ARG;
+            if (params->p_len >= ssl->options.minDhKeySz &&
+                                     params->p_len <= ssl->options.maxDhKeySz) {
+                break;
+            }
+        }
+
+        if (group != NULL && serverGroup->name == group->name)
+            break;
+    }
+
+    if (serverGroup) {
+        ssl->buffers.serverDH_P.buffer = (unsigned char *)params->p;
+        ssl->buffers.serverDH_P.length = params->p_len;
+        ssl->buffers.serverDH_G.buffer = (unsigned char *)params->g;
+        ssl->buffers.serverDH_G.length = params->g_len;
+        ssl->namedGroup = serverGroup->name;
+    #if !defined(WOLFSSL_OLD_PRIME_CHECK) && \
+        !defined(HAVE_FIPS) && !defined(HAVE_SELFTEST)
+        ssl->options.dhDoKeyTest = 0;
+    #endif
+        ssl->options.haveDH = 1;
+    }
+
+    TLSX_FreeAll(priority, ssl->heap);
+
+    return ret;
+}
+#endif /* HAVE_FFDHE && !WOLFSSL_NO_TLS12 */
+
+#endif /* !NO_WOLFSSL_SERVER */
+
+#if defined(WOLFSSL_TLS13) && !defined(WOLFSSL_NO_SERVER_GROUPS_EXT)
+/* Return the preferred group.
+ *
+ * ssl             SSL/TLS object.
+ * checkSupported  Whether to check for the first supported group.
+ * returns BAD_FUNC_ARG if no group found, otherwise the group.
+ */
+int TLSX_SupportedCurve_Preferred(WOLFSSL* ssl, int checkSupported)
+{
+    TLSX* extension;
+    SupportedCurve* curve;
+
+    extension = TLSX_Find(ssl->extensions, TLSX_SUPPORTED_GROUPS);
+    if (extension == NULL)
+        return BAD_FUNC_ARG;
+
+    curve = (SupportedCurve*)extension->data;
+    while (curve != NULL) {
+        if (!checkSupported || TLSX_KeyShare_IsSupported(curve->name))
+            return curve->name;
+        curve = curve->next;
+    }
+
+    return BAD_FUNC_ARG;
+}
+
+#endif
+
+#ifndef NO_WOLFSSL_SERVER
+
+static int TLSX_PointFormat_Parse(WOLFSSL* ssl, byte* input, word16 length,
+                                                                 byte isRequest)
+{
+    int ret;
+
+    /* validating formats list length */
+    if (ENUM_LEN > length || length != (word16)ENUM_LEN + input[0])
+        return BUFFER_ERROR;
+
+    if (isRequest) {
+        /* adding uncompressed point format to response */
+        ret = TLSX_UsePointFormat(&ssl->extensions, WOLFSSL_EC_PF_UNCOMPRESSED,
+                                                                     ssl->heap);
+        if (ret != WOLFSSL_SUCCESS)
+            return ret; /* throw error */
+
+        TLSX_SetResponse(ssl, TLSX_EC_POINT_FORMATS);
+    }
+
+    return 0;
+}
+
+#if defined(HAVE_ECC) || defined(HAVE_CURVE25519) || defined(HAVE_CURVE448)
+int TLSX_ValidateSupportedCurves(WOLFSSL* ssl, byte first, byte second) {
+    TLSX*           extension = NULL;
+    SupportedCurve* curve     = NULL;
+    word32          oid       = 0;
+    word32          pkOid     = 0;
+    word32          defOid    = 0;
+    word32          defSz     = 80; /* Maximum known curve size is 66. */
+    word32          nextOid   = 0;
+    word32          nextSz    = 80; /* Maximum known curve size is 66. */
+    word32          currOid   = ssl->ecdhCurveOID;
+    int             ephmSuite = 0;
+    word16          octets    = 0; /* according to 'ecc_set_type ecc_sets[];' */
+    int             sig       = 0; /* validate signature */
+    int             key       = 0; /* validate key       */
+
+    (void)oid;
+
+    if (first == ECC_BYTE || first == CHACHA_BYTE)
+        extension = TLSX_Find(ssl->extensions, TLSX_SUPPORTED_GROUPS);
+    if (!extension)
+        return 1; /* no suite restriction */
+
+    for (curve = (SupportedCurve*)extension->data;
+         curve && !(sig && key);
+         curve = curve->next) {
+
+    #ifdef OPENSSL_EXTRA
+        /* skip if name is not in supported ECC range */
+        if (curve->name > WOLFSSL_ECC_X448)
+            continue;
+        /* skip if curve is disabled by user */
+        if (ssl->ctx->disabledCurves & (1 << curve->name))
+            continue;
+    #endif
+
+        /* find supported curve */
+        switch (curve->name) {
+#ifdef HAVE_ECC
+    #if defined(HAVE_ECC160) || defined(HAVE_ALL_CURVES)
+        #ifndef NO_ECC_SECP
+            case WOLFSSL_ECC_SECP160R1:
+                pkOid = oid = ECC_SECP160R1_OID;
+                octets = 20;
+                break;
+        #endif /* !NO_ECC_SECP */
+        #ifdef HAVE_ECC_SECPR2
+            case WOLFSSL_ECC_SECP160R2:
+                pkOid = oid = ECC_SECP160R2_OID;
+                octets = 20;
+                break;
+        #endif /* HAVE_ECC_SECPR2 */
+        #ifdef HAVE_ECC_KOBLITZ
+            case WOLFSSL_ECC_SECP160K1:
+                pkOid = oid = ECC_SECP160K1_OID;
+                octets = 20;
+                break;
+        #endif /* HAVE_ECC_KOBLITZ */
+    #endif
+    #if defined(HAVE_ECC192) || defined(HAVE_ALL_CURVES)
+        #ifndef NO_ECC_SECP
+            case WOLFSSL_ECC_SECP192R1:
+                pkOid = oid = ECC_SECP192R1_OID;
+                octets = 24;
+                break;
+        #endif /* !NO_ECC_SECP */
+        #ifdef HAVE_ECC_KOBLITZ
+            case WOLFSSL_ECC_SECP192K1:
+                pkOid = oid = ECC_SECP192K1_OID;
+                octets = 24;
+                break;
+        #endif /* HAVE_ECC_KOBLITZ */
+    #endif
+    #if defined(HAVE_ECC224) || defined(HAVE_ALL_CURVES)
+        #ifndef NO_ECC_SECP
+            case WOLFSSL_ECC_SECP224R1:
+                pkOid = oid = ECC_SECP224R1_OID;
+                octets = 28;
+                break;
+        #endif /* !NO_ECC_SECP */
+        #ifdef HAVE_ECC_KOBLITZ
+            case WOLFSSL_ECC_SECP224K1:
+                pkOid = oid = ECC_SECP224K1_OID;
+                octets = 28;
+                break;
+        #endif /* HAVE_ECC_KOBLITZ */
+    #endif
+    #if !defined(NO_ECC256) || defined(HAVE_ALL_CURVES)
+        #ifndef NO_ECC_SECP
+            case WOLFSSL_ECC_SECP256R1:
+                pkOid = oid = ECC_SECP256R1_OID;
+                octets = 32;
+                break;
+        #endif /* !NO_ECC_SECP */
+    #endif /* !NO_ECC256 || HAVE_ALL_CURVES */
+#endif
+        #ifdef HAVE_CURVE25519
+            case WOLFSSL_ECC_X25519:
+                oid = ECC_X25519_OID;
+            #ifdef HAVE_ED25519
+                pkOid = ECC_ED25519_OID;
+            #else
+                pkOid = ECC_X25519_OID;
+            #endif
+                octets = 32;
+                break;
+        #endif /* HAVE_CURVE25519 */
+#ifdef HAVE_ECC
+    #if !defined(NO_ECC256) || defined(HAVE_ALL_CURVES)
+        #ifdef HAVE_ECC_KOBLITZ
+            case WOLFSSL_ECC_SECP256K1:
+                pkOid = oid = ECC_SECP256K1_OID;
+                octets = 32;
+                break;
+        #endif /* HAVE_ECC_KOBLITZ */
+        #ifdef HAVE_ECC_BRAINPOOL
+            case WOLFSSL_ECC_BRAINPOOLP256R1:
+                pkOid = oid = ECC_BRAINPOOLP256R1_OID;
+                octets = 32;
+                break;
+        #endif /* HAVE_ECC_BRAINPOOL */
+    #endif
+#endif
+        #ifdef HAVE_CURVE448
+            case WOLFSSL_ECC_X448:
+                oid = ECC_X448_OID;
+            #ifdef HAVE_ED448
+                pkOid = ECC_ED448_OID;
+            #else
+                pkOid = ECC_X448_OID;
+            #endif
+                octets = 57;
+                break;
+        #endif /* HAVE_CURVE448 */
+#ifdef HAVE_ECC
+    #if defined(HAVE_ECC384) || defined(HAVE_ALL_CURVES)
+        #ifndef NO_ECC_SECP
+            case WOLFSSL_ECC_SECP384R1:
+                pkOid = oid = ECC_SECP384R1_OID;
+                octets = 48;
+                break;
+        #endif /* !NO_ECC_SECP */
+        #ifdef HAVE_ECC_BRAINPOOL
+            case WOLFSSL_ECC_BRAINPOOLP384R1:
+                pkOid = oid = ECC_BRAINPOOLP384R1_OID;
+                octets = 48;
+                break;
+        #endif /* HAVE_ECC_BRAINPOOL */
+    #endif
+    #if defined(HAVE_ECC512) || defined(HAVE_ALL_CURVES)
+        #ifdef HAVE_ECC_BRAINPOOL
+            case WOLFSSL_ECC_BRAINPOOLP512R1:
+                pkOid = oid = ECC_BRAINPOOLP512R1_OID;
+                octets = 64;
+                break;
+        #endif /* HAVE_ECC_BRAINPOOL */
+    #endif
+    #if defined(HAVE_ECC521) || defined(HAVE_ALL_CURVES)
+        #ifndef NO_ECC_SECP
+            case WOLFSSL_ECC_SECP521R1:
+                pkOid = oid = ECC_SECP521R1_OID;
+                octets = 66;
+                break;
+        #endif /* !NO_ECC_SECP */
+    #endif
+#endif
+            default: continue; /* unsupported curve */
+        }
+
+    #ifdef HAVE_ECC
+        /* Set default Oid */
+        if (defOid == 0 && ssl->eccTempKeySz <= octets && defSz > octets) {
+            defOid = oid;
+            defSz = octets;
+        }
+
+        /* The eccTempKeySz is the preferred ephemeral key size */
+        if (currOid == 0 && ssl->eccTempKeySz == octets)
+            currOid = oid;
+        if ((nextOid == 0 || nextSz > octets) && ssl->eccTempKeySz <= octets) {
+            nextOid = oid;
+            nextSz  = octets;
+        }
+    #else
+        if (defOid == 0 && defSz > octets) {
+            defOid = oid;
+            defSz = octets;
+        }
+
+        if (currOid == 0)
+            currOid = oid;
+        if (nextOid == 0 || nextSz > octets) {
+            nextOid = oid;
+            nextSz  = octets;
+        }
+    #endif
+
+        if (first == ECC_BYTE) {
+            switch (second) {
+                /* ECDHE_ECDSA */
+                case TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA:
+                case TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA:
+                case TLS_ECDHE_ECDSA_WITH_RC4_128_SHA:
+                case TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA:
+                case TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256:
+                case TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384:
+                case TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256:
+                case TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384:
+                case TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8:
+                case TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8:
+                    sig |= ssl->pkCurveOID == pkOid;
+                    key |= ssl->ecdhCurveOID == oid;
+                    ephmSuite = 1;
+                break;
+
+#ifdef WOLFSSL_STATIC_DH
+                /* ECDH_ECDSA */
+                case TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA:
+                case TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA:
+                case TLS_ECDH_ECDSA_WITH_RC4_128_SHA:
+                case TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA:
+                case TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256:
+                case TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384:
+                case TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256:
+                case TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384:
+                    if (oid == ECC_X25519_OID && defOid == oid) {
+                        defOid = 0;
+                        defSz = 80;
+                    }
+                    if (oid == ECC_X448_OID && defOid == oid) {
+                        defOid = 0;
+                        defSz = 80;
+                    }
+                    sig |= ssl->pkCurveOID == pkOid;
+                    key |= ssl->pkCurveOID == oid;
+                break;
+#endif /* WOLFSSL_STATIC_DH */
+#ifndef NO_RSA
+                /* ECDHE_RSA */
+                case TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA:
+                case TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA:
+                case TLS_ECDHE_RSA_WITH_RC4_128_SHA:
+                case TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA:
+                case TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256:
+                case TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384:
+                case TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256:
+                case TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384:
+                    sig = 1;
+                    key |= ssl->ecdhCurveOID == oid;
+                    ephmSuite = 1;
+                break;
+
+#ifdef WOLFSSL_STATIC_DH
+                /* ECDH_RSA */
+                case TLS_ECDH_RSA_WITH_AES_256_CBC_SHA:
+                case TLS_ECDH_RSA_WITH_AES_128_CBC_SHA:
+                case TLS_ECDH_RSA_WITH_RC4_128_SHA:
+                case TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA:
+                case TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256:
+                case TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384:
+                case TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256:
+                case TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384:
+                    if (oid == ECC_X25519_OID && defOid == oid) {
+                        defOid = 0;
+                        defSz = 80;
+                    }
+                    if (oid == ECC_X448_OID && defOid == oid) {
+                        defOid = 0;
+                        defSz = 80;
+                    }
+                    sig = 1;
+                    key |= ssl->pkCurveOID == pkOid;
+                break;
+#endif /* WOLFSSL_STATIC_DH */
+#endif
+                default:
+                    if (oid == ECC_X25519_OID && defOid == oid) {
+                        defOid = 0;
+                        defSz = 80;
+                    }
+                    if (oid == ECC_X448_OID && defOid == oid) {
+                        defOid = 0;
+                        defSz = 80;
+                    }
+                    if (oid != ECC_X25519_OID && oid != ECC_X448_OID) {
+                        sig = 1;
+                    }
+                    key = 1;
+                break;
+            }
+        }
+
+        /* ChaCha20-Poly1305 ECC cipher suites */
+        if (first == CHACHA_BYTE) {
+            switch (second) {
+                /* ECDHE_ECDSA */
+                case TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 :
+                case TLS_ECDHE_ECDSA_WITH_CHACHA20_OLD_POLY1305_SHA256 :
+                    sig |= ssl->pkCurveOID == pkOid;
+                    key |= ssl->ecdhCurveOID == oid;
+                    ephmSuite = 1;
+                break;
+#ifndef NO_RSA
+                /* ECDHE_RSA */
+                case TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 :
+                case TLS_ECDHE_RSA_WITH_CHACHA20_OLD_POLY1305_SHA256 :
+                    sig = 1;
+                    key |= ssl->ecdhCurveOID == oid;
+                    ephmSuite = 1;
+                break;
+#endif
+                default:
+                    sig = 1;
+                    key = 1;
+                break;
+            }
+        }
+    }
+
+    /* Choose the default if it is at the required strength. */
+#ifdef HAVE_ECC
+    if (ssl->ecdhCurveOID == 0 && defSz == ssl->eccTempKeySz)
+#else
+    if (ssl->ecdhCurveOID == 0)
+#endif
+    {
+        key = 1;
+        ssl->ecdhCurveOID = defOid;
+    }
+    /* Choose any curve at the required strength. */
+    if (ssl->ecdhCurveOID == 0) {
+        key = 1;
+        ssl->ecdhCurveOID = currOid;
+    }
+    /* Choose the default if it is at the next highest strength. */
+    if (ssl->ecdhCurveOID == 0 && defSz == nextSz)
+        ssl->ecdhCurveOID = defOid;
+    /* Choose any curve at the next highest strength. */
+    if (ssl->ecdhCurveOID == 0)
+        ssl->ecdhCurveOID = nextOid;
+    /* No curve and ephemeral ECC suite requires a matching curve. */
+    if (ssl->ecdhCurveOID == 0 && ephmSuite)
+        key = 0;
+
+    return sig && key;
+}
+#endif
+
+#endif /* NO_WOLFSSL_SERVER */
+
+int TLSX_UseSupportedCurve(TLSX** extensions, word16 name, void* heap)
+{
+    TLSX* extension = NULL;
+    SupportedCurve* curve = NULL;
+    int ret;
+
+    if (extensions == NULL)
+        return BAD_FUNC_ARG;
+
+    extension = TLSX_Find(*extensions, TLSX_SUPPORTED_GROUPS);
+
+    if (!extension) {
+        ret = TLSX_SupportedCurve_New(&curve, name, heap);
+        if (ret != 0)
+            return ret;
+
+        ret = TLSX_Push(extensions, TLSX_SUPPORTED_GROUPS, curve, heap);
+        if (ret != 0) {
+            XFREE(curve, heap, DYNAMIC_TYPE_TLSX);
+            return ret;
+        }
+    }
+    else {
+        ret = TLSX_SupportedCurve_Append((SupportedCurve*)extension->data, name,
+                                                                          heap);
+        if (ret != 0)
+            return ret;
+    }
+
+    return WOLFSSL_SUCCESS;
+}
+
+int TLSX_UsePointFormat(TLSX** extensions, byte format, void* heap)
+{
+    TLSX* extension = NULL;
+    PointFormat* point = NULL;
+    int ret = 0;
+
+    if (extensions == NULL)
+        return BAD_FUNC_ARG;
+
+    extension = TLSX_Find(*extensions, TLSX_EC_POINT_FORMATS);
+
+    if (!extension) {
+        ret = TLSX_PointFormat_New(&point, format, heap);
+        if (ret != 0)
+            return ret;
+
+        ret = TLSX_Push(extensions, TLSX_EC_POINT_FORMATS, point, heap);
+        if (ret != 0) {
+            XFREE(point, heap, DYNAMIC_TYPE_TLSX);
+            return ret;
+        }
+    }
+    else {
+        ret = TLSX_PointFormat_Append((PointFormat*)extension->data, format,
+                                                                          heap);
+        if (ret != 0)
+            return ret;
+    }
+
+    return WOLFSSL_SUCCESS;
+}
+
+#define EC_FREE_ALL         TLSX_SupportedCurve_FreeAll
+#define EC_VALIDATE_REQUEST TLSX_SupportedCurve_ValidateRequest
+
+#ifndef NO_WOLFSSL_CLIENT
+#define EC_GET_SIZE TLSX_SupportedCurve_GetSize
+#define EC_WRITE    TLSX_SupportedCurve_Write
+#else
+#define EC_GET_SIZE(list)         0
+#define EC_WRITE(a, b)            0
+#endif
+
+#if !defined(NO_WOLFSSL_SERVER) || (defined(WOLFSSL_TLS13) && \
+                                         !defined(WOLFSSL_NO_SERVER_GROUPS_EXT))
+#define EC_PARSE TLSX_SupportedCurve_Parse
+#else
+#define EC_PARSE(a, b, c, d)      0
+#endif
+
+#define PF_FREE_ALL          TLSX_PointFormat_FreeAll
+#define PF_VALIDATE_REQUEST  TLSX_PointFormat_ValidateRequest
+#define PF_VALIDATE_RESPONSE TLSX_PointFormat_ValidateResponse
+
+#define PF_GET_SIZE TLSX_PointFormat_GetSize
+#define PF_WRITE    TLSX_PointFormat_Write
+
+#ifndef NO_WOLFSSL_SERVER
+#define PF_PARSE TLSX_PointFormat_Parse
+#else
+#define PF_PARSE(a, b, c, d)      0
+#endif
+
+#else
+
+#define EC_FREE_ALL(list, heap)
+#define EC_GET_SIZE(list)         0
+#define EC_WRITE(a, b)            0
+#define EC_PARSE(a, b, c, d)      0
+#define EC_VALIDATE_REQUEST(a, b)
+
+#define PF_FREE_ALL(list, heap)
+#define PF_GET_SIZE(list)         0
+#define PF_WRITE(a, b)            0
+#define PF_PARSE(a, b, c, d)      0
+#define PF_VALIDATE_REQUEST(a, b)
+#define PF_VALIDATE_RESPONSE(a, b)
+
+#endif /* HAVE_SUPPORTED_CURVES */
+
+/******************************************************************************/
+/* Renegotiation Indication                                                   */
+/******************************************************************************/
+
+#if defined(HAVE_SECURE_RENEGOTIATION) \
+ || defined(HAVE_SERVER_RENEGOTIATION_INFO)
+
+static byte TLSX_SecureRenegotiation_GetSize(SecureRenegotiation* data,
+                                                                  int isRequest)
+{
+    byte length = OPAQUE8_LEN; /* empty info length */
+
+    /* data will be NULL for HAVE_SERVER_RENEGOTIATION_INFO only */
+    if (data && data->enabled && data->verifySet) {
+        /* client sends client_verify_data only */
+        length += TLS_FINISHED_SZ;
+
+        /* server also sends server_verify_data */
+        if (!isRequest)
+            length += TLS_FINISHED_SZ;
+    }
+
+    return length;
+}
+
+static word16 TLSX_SecureRenegotiation_Write(SecureRenegotiation* data,
+                                                    byte* output, int isRequest)
+{
+    word16 offset = OPAQUE8_LEN; /* RenegotiationInfo length */
+    if (data && data->enabled && data->verifySet) {
+        /* client sends client_verify_data only */
+        XMEMCPY(output + offset, data->client_verify_data, TLS_FINISHED_SZ);
+        offset += TLS_FINISHED_SZ;
+
+        /* server also sends server_verify_data */
+        if (!isRequest) {
+            XMEMCPY(output + offset, data->server_verify_data, TLS_FINISHED_SZ);
+            offset += TLS_FINISHED_SZ;
+        }
+    }
+
+    output[0] = (byte)(offset - 1);  /* info length - self */
+
+    return offset;
+}
+
+static int TLSX_SecureRenegotiation_Parse(WOLFSSL* ssl, byte* input,
+                                                  word16 length, byte isRequest)
+{
+    int ret = SECURE_RENEGOTIATION_E;
+
+    if (length >= OPAQUE8_LEN) {
+        if (isRequest) {
+        #ifndef NO_WOLFSSL_SERVER
+            if (ssl->secure_renegotiation == NULL) {
+                ret = wolfSSL_UseSecureRenegotiation(ssl);
+                if (ret == WOLFSSL_SUCCESS)
+                    ret = 0;
+            }
+            if (ret != 0 && ret != SECURE_RENEGOTIATION_E) {
+            }
+            else if (!ssl->secure_renegotiation->enabled) {
+                if (*input == 0) {
+                    input++; /* get past size */
+
+                    ssl->secure_renegotiation->enabled = 1;
+                    TLSX_SetResponse(ssl, TLSX_RENEGOTIATION_INFO);
+                    ret = 0;
+                }
+                else {
+                    /* already in error state */
+                    WOLFSSL_MSG("SCR client verify data present");
+                }
+            }
+            else if (*input == TLS_FINISHED_SZ) {
+                if (length < TLS_FINISHED_SZ + 1) {
+                    WOLFSSL_MSG("SCR malformed buffer");
+                    ret = BUFFER_E;
+                }
+                else {
+                    input++; /* get past size */
+
+                    /* validate client verify data */
+                    if (XMEMCMP(input,
+                            ssl->secure_renegotiation->client_verify_data,
+                            TLS_FINISHED_SZ) == 0) {
+                        WOLFSSL_MSG("SCR client verify data match");
+                        TLSX_SetResponse(ssl, TLSX_RENEGOTIATION_INFO);
+                        ret = 0;  /* verified */
+                    } else {
+                        /* already in error state */
+                        WOLFSSL_MSG("SCR client verify data Failure");
+                    }
+                }
+            }
+        #endif
+        }
+        else {
+        #ifndef NO_WOLFSSL_CLIENT
+            if (!ssl->secure_renegotiation->enabled) {
+                if (*input == 0) {
+                    ssl->secure_renegotiation->enabled = 1;
+                    ret = 0;
+                }
+            }
+            else if (*input == 2 * TLS_FINISHED_SZ &&
+                     length == 2 * TLS_FINISHED_SZ + OPAQUE8_LEN) {
+                input++;  /* get past size */
+
+                /* validate client and server verify data */
+                if (XMEMCMP(input,
+                            ssl->secure_renegotiation->client_verify_data,
+                            TLS_FINISHED_SZ) == 0 &&
+                    XMEMCMP(input + TLS_FINISHED_SZ,
+                            ssl->secure_renegotiation->server_verify_data,
+                            TLS_FINISHED_SZ) == 0) {
+                    WOLFSSL_MSG("SCR client and server verify data match");
+                    ret = 0;  /* verified */
+                } else {
+                    /* already in error state */
+                    WOLFSSL_MSG("SCR client and server verify data Failure");
+                }
+            }
+        #endif
+        }
+    }
+
+    if (ret != 0) {
+        SendAlert(ssl, alert_fatal, handshake_failure);
+    }
+
+    return ret;
+}
+
+int TLSX_UseSecureRenegotiation(TLSX** extensions, void* heap)
+{
+    int ret = 0;
+    SecureRenegotiation* data;
+
+    data = (SecureRenegotiation*)XMALLOC(sizeof(SecureRenegotiation), heap,
+                                                             DYNAMIC_TYPE_TLSX);
+    if (data == NULL)
+        return MEMORY_E;
+
+    XMEMSET(data, 0, sizeof(SecureRenegotiation));
+
+    ret = TLSX_Push(extensions, TLSX_RENEGOTIATION_INFO, data, heap);
+    if (ret != 0) {
+        XFREE(data, heap, DYNAMIC_TYPE_TLSX);
+        return ret;
+    }
+
+    return WOLFSSL_SUCCESS;
+}
+
+#ifdef HAVE_SERVER_RENEGOTIATION_INFO
+
+int TLSX_AddEmptyRenegotiationInfo(TLSX** extensions, void* heap)
+{
+    int ret;
+
+    /* send empty renegotiation_info extension */
+    TLSX* ext = TLSX_Find(*extensions, TLSX_RENEGOTIATION_INFO);
+    if (ext == NULL) {
+        ret = TLSX_UseSecureRenegotiation(extensions, heap);
+        if (ret != WOLFSSL_SUCCESS)
+            return ret;
+
+        ext = TLSX_Find(*extensions, TLSX_RENEGOTIATION_INFO);
+    }
+    if (ext)
+        ext->resp = 1;
+
+    return WOLFSSL_SUCCESS;
+}
+
+#endif /* HAVE_SERVER_RENEGOTIATION_INFO */
+
+
+#define SCR_FREE_ALL(data, heap) XFREE(data, (heap), DYNAMIC_TYPE_TLSX)
+#define SCR_GET_SIZE       TLSX_SecureRenegotiation_GetSize
+#define SCR_WRITE          TLSX_SecureRenegotiation_Write
+#define SCR_PARSE          TLSX_SecureRenegotiation_Parse
+
+#else
+
+#define SCR_FREE_ALL(a, heap)
+#define SCR_GET_SIZE(a, b)    0
+#define SCR_WRITE(a, b, c)    0
+#define SCR_PARSE(a, b, c, d) 0
+
+#endif /* HAVE_SECURE_RENEGOTIATION */
+
+/******************************************************************************/
+/* Session Tickets                                                            */
+/******************************************************************************/
+
+#ifdef HAVE_SESSION_TICKET
+
+#if defined(WOLFSSL_TLS13) || !defined(NO_WOLFSSL_CLIENT)
+static void TLSX_SessionTicket_ValidateRequest(WOLFSSL* ssl)
+{
+    TLSX*          extension = TLSX_Find(ssl->extensions, TLSX_SESSION_TICKET);
+    SessionTicket* ticket    = extension ?
+                                         (SessionTicket*)extension->data : NULL;
+
+    if (ticket) {
+        /* TODO validate ticket timeout here! */
+        if (ticket->lifetime == 0xfffffff) {
+            /* send empty ticket on timeout */
+            TLSX_UseSessionTicket(&ssl->extensions, NULL, ssl->heap);
+        }
+    }
+}
+#endif /* WLFSSL_TLS13 || !NO_WOLFSSL_CLIENT */
+
+
+static word16 TLSX_SessionTicket_GetSize(SessionTicket* ticket, int isRequest)
+{
+    (void)isRequest;
+    return ticket ? ticket->size : 0;
+}
+
+static word16 TLSX_SessionTicket_Write(SessionTicket* ticket, byte* output,
+                                                                  int isRequest)
+{
+    word16 offset = 0; /* empty ticket */
+
+    if (isRequest && ticket) {
+        XMEMCPY(output + offset, ticket->data, ticket->size);
+        offset += ticket->size;
+    }
+
+    return offset;
+}
+
+
+static int TLSX_SessionTicket_Parse(WOLFSSL* ssl, byte* input, word16 length,
+                                                                 byte isRequest)
+{
+    int ret = 0;
+
+    (void) input; /* avoid unused parameter if NO_WOLFSSL_SERVER defined */
+
+    if (!isRequest) {
+        if (TLSX_CheckUnsupportedExtension(ssl, TLSX_SESSION_TICKET))
+            return TLSX_HandleUnsupportedExtension(ssl);
+
+        if (length != 0)
+            return BUFFER_ERROR;
+
+#ifndef NO_WOLFSSL_CLIENT
+        ssl->expect_session_ticket = 1;
+#endif
+    }
+#ifndef NO_WOLFSSL_SERVER
+    else {
+        /* server side */
+        if (ssl->ctx->ticketEncCb == NULL) {
+            WOLFSSL_MSG("Client sent session ticket, server has no callback");
+            return 0;
+        }
+
+        if (length == 0) {
+            /* blank ticket */
+            ret = TLSX_UseSessionTicket(&ssl->extensions, NULL, ssl->heap);
+            if (ret == WOLFSSL_SUCCESS) {
+                ret = 0;
+                TLSX_SetResponse(ssl, TLSX_SESSION_TICKET);  /* send blank ticket */
+                ssl->options.createTicket = 1;  /* will send ticket msg */
+                ssl->options.useTicket    = 1;
+                ssl->options.resuming     = 0;  /* no standard resumption */
+                ssl->arrays->sessionIDSz  = 0;  /* no echo on blank ticket */
+            }
+        } else {
+            /* got actual ticket from client */
+            ret = DoClientTicket(ssl, input, length);
+            if (ret == WOLFSSL_TICKET_RET_OK) {    /* use ticket to resume */
+                WOLFSSL_MSG("Using existing client ticket");
+                ssl->options.useTicket = 1;
+                ssl->options.resuming  = 1;
+            } else if (ret == WOLFSSL_TICKET_RET_CREATE) {
+                WOLFSSL_MSG("Using existing client ticket, creating new one");
+                ret = TLSX_UseSessionTicket(&ssl->extensions, NULL, ssl->heap);
+                if (ret == WOLFSSL_SUCCESS) {
+                    ret = 0;
+                    TLSX_SetResponse(ssl, TLSX_SESSION_TICKET);
+                                                    /* send blank ticket */
+                    ssl->options.createTicket = 1;  /* will send ticket msg */
+                    ssl->options.useTicket    = 1;
+                    ssl->options.resuming     = 1;
+                }
+            } else if (ret == WOLFSSL_TICKET_RET_REJECT) {
+                WOLFSSL_MSG("Process client ticket rejected, not using");
+                ssl->options.rejectTicket = 1;
+                ret = 0;  /* not fatal */
+            } else if (ret == WOLFSSL_TICKET_RET_FATAL || ret < 0) {
+                WOLFSSL_MSG("Process client ticket fatal error, not using");
+            }
+        }
+    }
+#endif /* NO_WOLFSSL_SERVER */
+
+    return ret;
+}
+
+WOLFSSL_LOCAL SessionTicket* TLSX_SessionTicket_Create(word32 lifetime,
+                                            byte* data, word16 size, void* heap)
+{
+    SessionTicket* ticket = (SessionTicket*)XMALLOC(sizeof(SessionTicket),
+                                                       heap, DYNAMIC_TYPE_TLSX);
+    if (ticket) {
+        ticket->data = (byte*)XMALLOC(size, heap, DYNAMIC_TYPE_TLSX);
+        if (ticket->data == NULL) {
+            XFREE(ticket, heap, DYNAMIC_TYPE_TLSX);
+            return NULL;
+        }
+
+        XMEMCPY(ticket->data, data, size);
+        ticket->size     = size;
+        ticket->lifetime = lifetime;
+    }
+
+    (void)heap;
+
+    return ticket;
+}
+WOLFSSL_LOCAL void TLSX_SessionTicket_Free(SessionTicket* ticket, void* heap)
+{
+    if (ticket) {
+        XFREE(ticket->data, heap, DYNAMIC_TYPE_TLSX);
+        XFREE(ticket,       heap, DYNAMIC_TYPE_TLSX);
+    }
+
+    (void)heap;
+}
+
+int TLSX_UseSessionTicket(TLSX** extensions, SessionTicket* ticket, void* heap)
+{
+    int ret = 0;
+
+    if (extensions == NULL)
+        return BAD_FUNC_ARG;
+
+    /* If the ticket is NULL, the client will request a new ticket from the
+       server. Otherwise, the client will use it in the next client hello. */
+    if ((ret = TLSX_Push(extensions, TLSX_SESSION_TICKET, (void*)ticket, heap))
+                                                                           != 0)
+        return ret;
+
+    return WOLFSSL_SUCCESS;
+}
+
+#define WOLF_STK_VALIDATE_REQUEST TLSX_SessionTicket_ValidateRequest
+#define WOLF_STK_GET_SIZE         TLSX_SessionTicket_GetSize
+#define WOLF_STK_WRITE            TLSX_SessionTicket_Write
+#define WOLF_STK_PARSE            TLSX_SessionTicket_Parse
+#define WOLF_STK_FREE(stk, heap)  TLSX_SessionTicket_Free((SessionTicket*)stk,(heap))
+
+#else
+
+#define WOLF_STK_FREE(a, b)
+#define WOLF_STK_VALIDATE_REQUEST(a)
+#define WOLF_STK_GET_SIZE(a, b)      0
+#define WOLF_STK_WRITE(a, b, c)      0
+#define WOLF_STK_PARSE(a, b, c, d)   0
+
+#endif /* HAVE_SESSION_TICKET */
+
+/******************************************************************************/
+/* Quantum-Safe-Hybrid                                                        */
+/******************************************************************************/
+
+#ifdef HAVE_QSH
+#if defined(HAVE_NTRU)
+static WC_RNG* gRng;
+static wolfSSL_Mutex* gRngMutex;
+#endif
+
+static void TLSX_QSH_FreeAll(QSHScheme* list, void* heap)
+{
+    QSHScheme* current;
+
+    while ((current = list)) {
+        list = current->next;
+        XFREE(current, heap, DYNAMIC_TYPE_TLSX);
+    }
+
+    (void)heap;
+}
+
+static int TLSX_QSH_Append(QSHScheme** list, word16 name, byte* pub,
+                                                                  word16 pubLen)
+{
+    QSHScheme* temp;
+
+    if (list == NULL)
+        return BAD_FUNC_ARG;
+
+    if ((temp = (QSHScheme*)XMALLOC(sizeof(QSHScheme), NULL,
+                                                    DYNAMIC_TYPE_TLSX)) == NULL)
+        return MEMORY_E;
+
+    temp->name  = name;
+    temp->PK    = pub;
+    temp->PKLen = pubLen;
+    temp->next  = *list;
+
+    *list = temp;
+
+    return 0;
+}
+
+
+/* request for server's public key : 02 indicates 0-2 requested */
+static byte TLSX_QSH_SerPKReq(byte* output, byte isRequest)
+{
+    if (isRequest) {
+        /* only request one public key from the server */
+        output[0] = 0x01;
+
+        return OPAQUE8_LEN;
+    }
+    else {
+        return 0;
+    }
+}
+
+#ifndef NO_WOLFSSL_CLIENT
+
+/* check for TLS_QSH suite */
+static void TLSX_QSH_ValidateRequest(WOLFSSL* ssl, byte* semaphore)
+{
+    int i;
+
+    for (i = 0; i < ssl->suites->suiteSz; i+= 2)
+        if (ssl->suites->suites[i] == QSH_BYTE)
+            return;
+
+    /* No QSH suite found */
+    TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_QUANTUM_SAFE_HYBRID));
+}
+
+
+/* return the size of the QSH hello extension
+   list      the list of QSHScheme structs containing id and key
+   isRequest if 1 then is being sent to the server
+ */
+word16 TLSX_QSH_GetSize(QSHScheme* list, byte isRequest)
+{
+    QSHScheme* temp = list;
+    word16 length = 0;
+
+    /* account for size of scheme list and public key list */
+    if (isRequest)
+        length = OPAQUE16_LEN;
+    length += OPAQUE24_LEN;
+
+    /* for each non null element in list add size */
+    while ((temp)) {
+        /* add public key info Scheme | Key Length | Key */
+        length += OPAQUE16_LEN;
+        length += OPAQUE16_LEN;
+        length += temp->PKLen;
+
+        /* if client add name size for scheme list
+           advance to next QSHScheme struct in list */
+        if (isRequest)
+            length += OPAQUE16_LEN;
+        temp = temp->next;
+    }
+
+    /* add length for request server public keys */
+    if (isRequest)
+        length += OPAQUE8_LEN;
+
+    return length;
+}
+
+
+/* write out a list of QSHScheme IDs */
+static word16 TLSX_QSH_Write(QSHScheme* list, byte* output)
+{
+    QSHScheme* current = list;
+    word16 length      = 0;
+
+    length += OPAQUE16_LEN;
+
+    while (current) {
+        c16toa(current->name, output + length);
+        length += OPAQUE16_LEN;
+        current = (QSHScheme*)current->next;
+    }
+
+    c16toa(length - OPAQUE16_LEN, output); /* writing list length */
+
+    return length;
+}
+
+
+/* write public key list in extension */
+static word16 TLSX_QSHPK_WriteR(QSHScheme* format, byte* output)
+{
+    word32 offset = 0;
+    word16 public_len = 0;
+
+    if (!format)
+        return offset;
+
+    /* write scheme ID */
+    c16toa(format->name, output + offset);
+    offset += OPAQUE16_LEN;
+
+    /* write public key matching scheme */
+    public_len = format->PKLen;
+    c16toa(public_len, output + offset);
+    offset += OPAQUE16_LEN;
+    if (format->PK) {
+        XMEMCPY(output+offset, format->PK, public_len);
+    }
+
+    return public_len + offset;
+}
+
+word16 TLSX_QSHPK_Write(QSHScheme* list, byte* output)
+{
+    QSHScheme* current = list;
+    word32 length = 0;
+    word24 toWire;
+
+    length += OPAQUE24_LEN;
+
+    while (current) {
+        length += TLSX_QSHPK_WriteR(current, output + length);
+        current = (QSHScheme*)current->next;
+    }
+    /* length of public keys sent */
+    c32to24(length - OPAQUE24_LEN, toWire);
+    output[0] = toWire[0];
+    output[1] = toWire[1];
+    output[2] = toWire[2];
+
+    return length;
+}
+
+#endif /* NO_WOLFSSL_CLIENT */
+#ifndef NO_WOLFSSL_SERVER
+
+static void TLSX_QSHAgreement(TLSX** extensions, void* heap)
+{
+    TLSX* extension = TLSX_Find(*extensions, TLSX_QUANTUM_SAFE_HYBRID);
+    QSHScheme* format = NULL;
+    QSHScheme* del    = NULL;
+    QSHScheme* prev   = NULL;
+
+    if (extension == NULL)
+        return;
+
+    format = (QSHScheme*)extension->data;
+    while (format) {
+        if (format->PKLen == 0) {
+            /* case of head */
+            if (format == extension->data) {
+                extension->data = format->next;
+            }
+            if (prev)
+                prev->next = format->next;
+            del = format;
+            format = format->next;
+            XFREE(del, heap, DYNAMIC_TYPE_TMP_BUFFER);
+            del = NULL;
+        } else {
+            prev   = format;
+            format = format->next;
+        }
+    }
+
+    (void)heap;
+}
+
+
+/* Parse in hello extension
+   input     the byte stream to process
+   length    length of total extension found
+   isRequest set to 1 if being sent to the server
+ */
+static int TLSX_QSH_Parse(WOLFSSL* ssl, byte* input, word16 length,
+                                                                 byte isRequest)
+{
+    byte   numKeys    = 0;
+    word16 offset     = 0;
+    word16 schemSz    = 0;
+    word16 offset_len = 0;
+    word32 offset_pk  = 0;
+    word16 name  = 0;
+    word16 PKLen = 0;
+    byte*  PK = NULL;
+    int r;
+
+
+    if (OPAQUE16_LEN > length)
+        return BUFFER_ERROR;
+
+    if (isRequest) {
+        ato16(input, &schemSz);
+
+        /* list of public keys available for QSH schemes */
+        offset_len = schemSz + OPAQUE16_LEN;
+    }
+
+    offset_pk = ((input[offset_len] << 16)   & 0xFF00000) |
+                (((input[offset_len + 1]) << 8) & 0xFF00) |
+                (input[offset_len + 2] & 0xFF);
+    offset_len += OPAQUE24_LEN;
+
+    /* check buffer size */
+    if (offset_pk > length)
+        return BUFFER_ERROR;
+
+    /* set maximum number of keys the client will accept */
+    if (!isRequest)
+        numKeys = (ssl->maxRequest < 1)? 1 : ssl->maxRequest;
+
+    /* hello extension read list of scheme ids */
+    if (isRequest) {
+
+        /* read in request for public keys */
+        ssl->minRequest = (input[length -1] >> 4) & 0xFF;
+        ssl->maxRequest = input[length -1] & 0x0F;
+
+        /* choose the min between min requested by client and 1 */
+        numKeys = (ssl->minRequest > 1) ? ssl->minRequest : 1;
+
+        if (ssl->minRequest > ssl->maxRequest)
+            return BAD_FUNC_ARG;
+
+        offset  += OPAQUE16_LEN;
+        schemSz += offset;
+
+        /* check buffer size */
+        if (schemSz > length)
+            return BUFFER_ERROR;
+
+        while ((offset < schemSz) && numKeys) {
+            /* Scheme ID list */
+            ato16(input + offset, &name);
+            offset += OPAQUE16_LEN;
+
+            /* validate we have scheme id */
+            if (ssl->user_set_QSHSchemes &&
+                    !TLSX_ValidateQSHScheme(&ssl->extensions, name)) {
+                continue;
+            }
+
+            /* server create keys on demand */
+            if ((r = TLSX_CreateNtruKey(ssl, name)) != 0) {
+                WOLFSSL_MSG("Error creating ntru keys");
+                return r;
+            }
+
+            /* peer sent an agreed upon scheme */
+            r = TLSX_UseQSHScheme(&ssl->extensions, name, NULL, 0, ssl->heap);
+
+            if (r != WOLFSSL_SUCCESS) return r; /* throw error */
+
+            numKeys--;
+        }
+
+        /* choose the min between min requested by client and 1 */
+        numKeys = (ssl->minRequest > 1) ? ssl->minRequest : 1;
+    }
+
+    /* QSHPK struct */
+    offset_pk += offset_len;
+    while ((offset_len < offset_pk) && numKeys) {
+        QSHKey * temp;
+
+        if ((temp = (QSHKey*)XMALLOC(sizeof(QSHKey), ssl->heap,
+                                                    DYNAMIC_TYPE_TLSX)) == NULL)
+            return MEMORY_E;
+
+        /* initialize */
+        temp->next = NULL;
+        temp->pub.buffer = NULL;
+        temp->pub.length = 0;
+        temp->pri.buffer = NULL;
+        temp->pri.length = 0;
+
+        /* scheme id */
+        ato16(input + offset_len, &(temp->name));
+        offset_len += OPAQUE16_LEN;
+
+        /* public key length */
+        ato16(input + offset_len, &PKLen);
+        temp->pub.length = PKLen;
+        offset_len += OPAQUE16_LEN;
+
+
+        if (isRequest) {
+            /* validate we have scheme id */
+            if (ssl->user_set_QSHSchemes &&
+                    (!TLSX_ValidateQSHScheme(&ssl->extensions, temp->name))) {
+                offset_len += PKLen;
+                XFREE(temp, ssl->heap, DYNAMIC_TYPE_TLSX);
+                continue;
+            }
+        }
+
+        /* read in public key */
+        if (PKLen > 0) {
+            temp->pub.buffer = (byte*)XMALLOC(temp->pub.length,
+                                            ssl->heap, DYNAMIC_TYPE_PUBLIC_KEY);
+            XMEMCPY(temp->pub.buffer, input + offset_len, temp->pub.length);
+            offset_len += PKLen;
+        }
+        else {
+            PK = NULL;
+        }
+
+        /* use own key when adding to extensions list for sending reply */
+        PKLen = 0;
+        PK = TLSX_QSHKeyFind_Pub(ssl->QSH_Key, &PKLen, temp->name);
+        r  = TLSX_UseQSHScheme(&ssl->extensions, temp->name, PK, PKLen,
+                                                                     ssl->heap);
+
+        /* store peers key */
+        ssl->peerQSHKeyPresent = 1;
+        if (TLSX_AddQSHKey(&ssl->peerQSHKey, temp) != 0)
+            return MEMORY_E;
+
+        if (temp->pub.length == 0) {
+            XFREE(temp, ssl->heap, DYNAMIC_TYPE_TLSX);
+        }
+
+        if (r != WOLFSSL_SUCCESS) {return r;} /* throw error */
+
+        numKeys--;
+    }
+
+    /* reply to a QSH extension sent from client */
+    if (isRequest) {
+        TLSX_SetResponse(ssl, TLSX_QUANTUM_SAFE_HYBRID);
+        /* only use schemes we have key generated for -- free the rest */
+        TLSX_QSHAgreement(&ssl->extensions, ssl->heap);
+    }
+
+    return 0;
+}
+
+
+/* Used for parsing in QSHCipher structs on Key Exchange */
+int TLSX_QSHCipher_Parse(WOLFSSL* ssl, const byte* input, word16 length,
+                                                                  byte isServer)
+{
+    QSHKey* key;
+    word16 Max_Secret_Len = 48;
+    word16 offset     = 0;
+    word16 offset_len = 0;
+    word32 offset_pk  = 0;
+    word16 name       = 0;
+    word16 secretLen  = 0;
+    byte*  secret     = NULL;
+    word16 buffLen    = 0;
+    byte buff[145]; /* size enough for 3 secrets */
+    buffer* buf;
+
+    /* pointer to location where secret should be stored */
+    if (isServer) {
+        buf = ssl->QSH_secret->CliSi;
+    }
+    else {
+        buf = ssl->QSH_secret->SerSi;
+    }
+
+    offset_pk = ((input[offset_len] << 16)    & 0xFF0000) |
+                (((input[offset_len + 1]) << 8) & 0xFF00) |
+                (input[offset_len + 2] & 0xFF);
+    offset_len += OPAQUE24_LEN;
+
+    /* validating extension list length -- check if trying to read over edge
+       of buffer */
+    if (length < (offset_pk + OPAQUE24_LEN)) {
+        return BUFFER_ERROR;
+    }
+
+    /* QSHCipherList struct */
+    offset_pk += offset_len;
+    while (offset_len < offset_pk) {
+
+        /* scheme id */
+        ato16(input + offset_len, &name);
+        offset_len += OPAQUE16_LEN;
+
+        /* public key length */
+        ato16(input + offset_len, &secretLen);
+        offset_len += OPAQUE16_LEN;
+
+        /* read in public key */
+        if (secretLen > 0) {
+            secret = (byte*)(input + offset_len);
+            offset_len += secretLen;
+        }
+        else {
+            secret = NULL;
+        }
+
+        /* no secret sent */
+        if (secret == NULL)
+            continue;
+
+        /* find corresponding key */
+        key = ssl->QSH_Key;
+        while (key) {
+            if (key->name == name)
+                break;
+            else
+                key = (QSHKey*)key->next;
+        }
+
+        /* if we do not have the key than there was a big issue negotiation */
+        if (key == NULL) {
+            WOLFSSL_MSG("key was null for decryption!!!\n");
+            return MEMORY_E;
+        }
+
+        /* Decrypt sent secret */
+        buffLen = Max_Secret_Len;
+        QSH_Decrypt(key, secret, secretLen, buff + offset, &buffLen);
+        offset += buffLen;
+    }
+
+    /* allocate memory for buffer */
+    buf->length = offset;
+    buf->buffer = (byte*)XMALLOC(offset, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER);
+    if (buf->buffer == NULL)
+        return MEMORY_E;
+
+    /* store secrets */
+    XMEMCPY(buf->buffer, buff, offset);
+    ForceZero(buff, offset);
+
+    return offset_len;
+}
+
+
+/* return 1 on success */
+int TLSX_ValidateQSHScheme(TLSX** extensions, word16 theirs) {
+    TLSX* extension = TLSX_Find(*extensions, TLSX_QUANTUM_SAFE_HYBRID);
+    QSHScheme* format    = NULL;
+
+    /* if no extension is sent then do not use QSH */
+    if (!extension) {
+        WOLFSSL_MSG("No QSH Extension");
+        return 0;
+    }
+
+    for (format = (QSHScheme*)extension->data; format; format = format->next) {
+        if (format->name == theirs) {
+            WOLFSSL_MSG("Found Matching QSH Scheme");
+            return 1; /* have QSH */
+        }
+    }
+
+    return 0;
+}
+#endif /* NO_WOLFSSL_SERVER */
+
+/* test if the QSH Scheme is implemented
+   return 1 if yes 0 if no */
+static int TLSX_HaveQSHScheme(word16 name)
+{
+    switch(name) {
+        #ifdef HAVE_NTRU
+            case WOLFSSL_NTRU_EESS439:
+            case WOLFSSL_NTRU_EESS593:
+            case WOLFSSL_NTRU_EESS743:
+                    return 1;
+        #endif
+            case WOLFSSL_LWE_XXX:
+            case WOLFSSL_HFE_XXX:
+                    return 0; /* not supported yet */
+
+        default:
+            return 0;
+    }
+}
+
+
+/* Add a QSHScheme struct to list of usable ones */
+int TLSX_UseQSHScheme(TLSX** extensions, word16 name, byte* pKey, word16 pkeySz,
+                                                                     void* heap)
+{
+    TLSX*      extension = NULL;
+    QSHScheme* format    = NULL;
+    int        ret       = 0;
+
+    /* sanity check */
+    if (extensions == NULL || (pKey == NULL && pkeySz != 0))
+        return BAD_FUNC_ARG;
+
+    extension = TLSX_Find(*extensions, TLSX_QUANTUM_SAFE_HYBRID);
+
+    /* if scheme is implemented than add */
+    if (TLSX_HaveQSHScheme(name)) {
+        if ((ret = TLSX_QSH_Append(&format, name, pKey, pkeySz)) != 0)
+            return ret;
+
+        extension = TLSX_Find(*extensions, TLSX_QUANTUM_SAFE_HYBRID);
+        if (!extension) {
+            if ((ret = TLSX_Push(extensions, TLSX_QUANTUM_SAFE_HYBRID, format,
+                                                                  heap)) != 0) {
+                XFREE(format, 0, DYNAMIC_TYPE_TLSX);
+                return ret;
+            }
+        }
+        else {
+            /* push new QSH object to extension data. */
+            format->next = (QSHScheme*)extension->data;
+            extension->data = (void*)format;
+
+            /* look for another format of the same name to remove (replacement) */
+            do {
+                if (format->next && (format->next->name == name)) {
+                    QSHScheme* next = format->next;
+
+                    format->next = next->next;
+                    XFREE(next, 0, DYNAMIC_TYPE_TLSX);
+
+                    break;
+                }
+            } while ((format = format->next));
+        }
+    }
+    return WOLFSSL_SUCCESS;
+}
+
+#define QSH_FREE_ALL         TLSX_QSH_FreeAll
+#define QSH_VALIDATE_REQUEST TLSX_QSH_ValidateRequest
+
+#ifndef NO_WOLFSSL_CLIENT
+#define QSH_GET_SIZE TLSX_QSH_GetSize
+#define QSH_WRITE    TLSX_QSH_Write
+#else
+#define QSH_GET_SIZE(list, a)      0
+#define QSH_WRITE(a, b)            0
+#endif
+
+#ifndef NO_WOLFSSL_SERVER
+#define QSH_PARSE TLSX_QSH_Parse
+#else
+#define QSH_PARSE(a, b, c, d)      0
+#endif
+
+#define QSHPK_WRITE TLSX_QSHPK_Write
+#define QSH_SERREQ TLSX_QSH_SerPKReq
+#else
+
+#define QSH_FREE_ALL(list, heap)
+#define QSH_GET_SIZE(list, a)      0
+#define QSH_WRITE(a, b)            0
+#define QSH_PARSE(a, b, c, d)      0
+#define QSHPK_WRITE(a, b)          0
+#define QSH_SERREQ(a, b)           0
+#define QSH_VALIDATE_REQUEST(a, b)
+
+#endif /* HAVE_QSH */
+
+#if defined(HAVE_ENCRYPT_THEN_MAC) && !defined(WOLFSSL_AEAD_ONLY)
+/******************************************************************************/
+/* Encrypt-then-MAC                                                           */
+/******************************************************************************/
+
+#ifndef WOLFSSL_NO_TLS12
+static int TLSX_EncryptThenMac_Use(WOLFSSL* ssl);
+
+/**
+ * Get the size of the Encrypt-Then-MAC extension.
+ *
+ * msgType  Type of message to put extension into.
+ * pSz      Size of extension data.
+ * return SANITY_MSG_E when the message is not allowed to have extension and
+ *        0 otherwise.
+ */
+static int TLSX_EncryptThenMac_GetSize(byte msgType, word16* pSz)
+{
+    (void)pSz;
+
+    if (msgType != client_hello && msgType != server_hello) {
+        return SANITY_MSG_E;
+    }
+
+    /* Empty extension */
+
+    return 0;
+}
+
+/**
+ * Write the Encrypt-Then-MAC extension.
+ *
+ * data     Unused
+ * output   Extension data buffer. Unused.
+ * msgType  Type of message to put extension into.
+ * pSz      Size of extension data.
+ * return SANITY_MSG_E when the message is not allowed to have extension and
+ *        0 otherwise.
+ */
+static int TLSX_EncryptThenMac_Write(void* data, byte* output, byte msgType,
+                                     word16* pSz)
+{
+    (void)data;
+    (void)output;
+    (void)pSz;
+
+    if (msgType != client_hello && msgType != server_hello) {
+        return SANITY_MSG_E;
+    }
+
+    /* Empty extension */
+
+    return 0;
+}
+
+/**
+ * Parse the Encrypt-Then-MAC extension.
+ *
+ * ssl      SSL object
+ * input    Extension data buffer.
+ * length   Length of this extension's data.
+ * msgType  Type of message to extension appeared in.
+ * return SANITY_MSG_E when the message is not allowed to have extension,
+ *        BUFFER_ERROR when the extension's data is invalid,
+ *        MEMORY_E when unable to allocate memory and
+ *        0 otherwise.
+ */
+static int TLSX_EncryptThenMac_Parse(WOLFSSL* ssl, byte* input, word16 length,
+                                     byte msgType)
+{
+    int ret;
+
+    (void)input;
+
+    if (msgType != client_hello && msgType != server_hello) {
+        return SANITY_MSG_E;
+    }
+
+    /* Empty extension */
+    if (length != 0)
+        return BUFFER_ERROR;
+
+    if (msgType == client_hello) {
+        /* Check the user hasn't disallowed use of Encrypt-Then-Mac. */
+        if (!ssl->options.disallowEncThenMac) {
+            ssl->options.encThenMac = 1;
+            /* Set the extension reply. */
+            ret = TLSX_EncryptThenMac_Use(ssl);
+            if (ret != 0)
+                return ret;
+            TLSX_SetResponse(ssl, TLSX_ENCRYPT_THEN_MAC);
+        }
+        return 0;
+    }
+
+    /* Server Hello */
+    if (ssl->options.disallowEncThenMac)
+        return SANITY_MSG_E;
+
+    ssl->options.encThenMac = 1;
+    return 0;
+
+}
+
+/**
+ * Add the Encrypt-Then-MAC extension to list.
+ *
+ * ssl      SSL object
+ * return MEMORY_E when unable to allocate memory and 0 otherwise.
+ */
+static int TLSX_EncryptThenMac_Use(WOLFSSL* ssl)
+{
+    int   ret = 0;
+    TLSX* extension;
+
+    /* Find the Encrypt-Then-Mac extension if it exists. */
+    extension = TLSX_Find(ssl->extensions, TLSX_ENCRYPT_THEN_MAC);
+    if (extension == NULL) {
+        /* Push new Encrypt-Then-Mac extension. */
+        ret = TLSX_Push(&ssl->extensions, TLSX_ENCRYPT_THEN_MAC, NULL,
+            ssl->heap);
+        if (ret != 0)
+            return ret;
+    }
+
+    return 0;
+}
+
+#define ETM_GET_SIZE  TLSX_EncryptThenMac_GetSize
+#define ETM_WRITE     TLSX_EncryptThenMac_Write
+#define ETM_PARSE     TLSX_EncryptThenMac_Parse
+
+#else
+
+#define ETM_GET_SIZE(a, b)    0
+#define ETM_WRITE(a, b, c, d) 0
+#define ETM_PARSE(a, b, c, d) 0
+
+#endif /* !WOLFSSL_NO_TLS12 */
+
+#endif /* HAVE_ENCRYPT_THEN_MAC && !WOLFSSL_AEAD_ONLY */
+
+/******************************************************************************/
+/* Supported Versions                                                         */
+/******************************************************************************/
+
+#ifdef WOLFSSL_TLS13
+/* Return the size of the SupportedVersions extension's data.
+ *
+ * data       The SSL/TLS object.
+ * msgType The type of the message this extension is being written into.
+ * returns the length of data that will be in the extension.
+ */
+static int TLSX_SupportedVersions_GetSize(void* data, byte msgType, word16* pSz)
+{
+    WOLFSSL* ssl = (WOLFSSL*)data;
+
+    if (msgType == client_hello) {
+        /* TLS v1.2 and TLS v1.3  */
+        int cnt = 0;
+
+        #if defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER)
+            if ((ssl->options.mask & SSL_OP_NO_TLSv1_3) == 0)
+        #endif
+                cnt++;
+
+        if (ssl->options.downgrade) {
+#ifndef WOLFSSL_NO_TLS12
+        #if defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER)
+            if ((ssl->options.mask & SSL_OP_NO_TLSv1_2) == 0)
+        #endif
+                cnt++;
+#endif
+
+#ifndef NO_OLD_TLS
+        #if defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER)
+            if ((ssl->options.mask & SSL_OP_NO_TLSv1_1) == 0)
+        #endif
+                cnt++;
+    #ifdef WOLFSSL_ALLOW_TLSV10
+        #if defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER)
+            if ((ssl->options.mask & SSL_OP_NO_TLSv1) == 0)
+        #endif
+                cnt++;
+    #endif
+#endif
+        }
+
+        *pSz += (word16)(OPAQUE8_LEN + cnt * OPAQUE16_LEN);
+    }
+#ifndef WOLFSSL_TLS13_DRAFT_18
+    else if (msgType == server_hello || msgType == hello_retry_request)
+        *pSz += OPAQUE16_LEN;
+#endif
+    else
+        return SANITY_MSG_E;
+
+    return 0;
+}
+
+/* Writes the SupportedVersions extension into the buffer.
+ *
+ * data    The SSL/TLS object.
+ * output  The buffer to write the extension into.
+ * msgType The type of the message this extension is being written into.
+ * returns the length of data that was written.
+ */
+static int TLSX_SupportedVersions_Write(void* data, byte* output,
+                                        byte msgType, word16* pSz)
+{
+    WOLFSSL* ssl = (WOLFSSL*)data;
+    byte major;
+    byte* cnt;
+
+    if (msgType == client_hello) {
+        major = ssl->ctx->method->version.major;
+
+
+        cnt = output++;
+        *cnt = 0;
+        #if defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER)
+            if ((ssl->options.mask & SSL_OP_NO_TLSv1_3) == 0)
+        #endif
+            {
+                *cnt += OPAQUE16_LEN;
+#ifdef WOLFSSL_TLS13_DRAFT
+                /* The TLS draft major number. */
+                *(output++) = TLS_DRAFT_MAJOR;
+                /* Version of draft supported. */
+                *(output++) = TLS_DRAFT_MINOR;
+#else
+                *(output++) = major;
+                *(output++) = (byte)TLSv1_3_MINOR;
+#endif
+            }
+        if (ssl->options.downgrade) {
+#ifndef WOLFSSL_NO_TLS12
+        #if defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER)
+            if ((ssl->options.mask & SSL_OP_NO_TLSv1_2) == 0)
+        #endif
+            {
+                *cnt += OPAQUE16_LEN;
+                *(output++) = major;
+                *(output++) = (byte)TLSv1_2_MINOR;
+            }
+#endif
+
+#ifndef NO_OLD_TLS
+        #if defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER)
+            if ((ssl->options.mask & SSL_OP_NO_TLSv1_1) == 0)
+        #endif
+            {
+                *cnt += OPAQUE16_LEN;
+                *(output++) = major;
+                *(output++) = (byte)TLSv1_1_MINOR;
+            }
+    #ifdef WOLFSSL_ALLOW_TLSV10
+        #if defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER)
+            if ((ssl->options.mask & SSL_OP_NO_TLSv1) == 0)
+        #endif
+            {
+                *cnt += OPAQUE16_LEN;
+                *(output++) = major;
+                *(output++) = (byte)TLSv1_MINOR;
+            }
+    #endif
+#endif
+        }
+
+        *pSz += (word16)(OPAQUE8_LEN + *cnt);
+    }
+#ifndef WOLFSSL_TLS13_DRAFT_18
+    else if (msgType == server_hello || msgType == hello_retry_request) {
+    #ifdef WOLFSSL_TLS13_DRAFT
+        if (ssl->version.major == SSLv3_MAJOR &&
+                                          ssl->version.minor == TLSv1_3_MINOR) {
+            output[0] = TLS_DRAFT_MAJOR;
+            output[1] = TLS_DRAFT_MINOR;
+        }
+        else
+    #endif
+        {
+            output[0] = ssl->version.major;
+            output[1] = ssl->version.minor;
+        }
+
+        *pSz += OPAQUE16_LEN;
+    }
+#endif
+    else
+        return SANITY_MSG_E;
+
+    return 0;
+}
+
+/* Parse the SupportedVersions extension.
+ *
+ * ssl     The SSL/TLS object.
+ * input   The buffer with the extension data.
+ * length  The length of the extension data.
+ * msgType The type of the message this extension is being parsed from.
+ * returns 0 on success, otherwise failure.
+ */
+static int TLSX_SupportedVersions_Parse(WOLFSSL* ssl, byte* input,
+                                        word16 length, byte msgType)
+{
+    ProtocolVersion pv = ssl->ctx->method->version;
+    int i;
+    int len;
+    byte major, minor;
+    int newMinor = 0;
+    int set = 0;
+
+    if (msgType == client_hello) {
+        /* Must contain a length and at least one version. */
+        if (length < OPAQUE8_LEN + OPAQUE16_LEN || (length & 1) != 1)
+            return BUFFER_ERROR;
+
+        len = *input;
+
+        /* Protocol version array must fill rest of data. */
+        if (length != (word16)OPAQUE8_LEN + len)
+            return BUFFER_ERROR;
+
+        input++;
+
+        /* Find first match. */
+        for (i = 0; i < len; i += OPAQUE16_LEN) {
+            major = input[i];
+            minor = input[i + OPAQUE8_LEN];
+
+#ifdef WOLFSSL_TLS13_DRAFT
+            if (major == TLS_DRAFT_MAJOR && minor == TLS_DRAFT_MINOR) {
+                major = SSLv3_MAJOR;
+                minor = TLSv1_3_MINOR;
+            }
+#else
+            if (major == TLS_DRAFT_MAJOR)
+                continue;
+#endif
+
+            if (major != pv.major)
+                continue;
+
+            /* No upgrade allowed. */
+            if (minor > ssl->version.minor)
+                    continue;
+            /* Check downgrade. */
+            if (minor < ssl->version.minor) {
+                if (!ssl->options.downgrade)
+                    continue;
+
+                if (minor < ssl->options.minDowngrade)
+                    continue;
+
+                if (newMinor == 0 && minor > ssl->options.oldMinor) {
+                    /* Downgrade the version. */
+                    ssl->version.minor = minor;
+                }
+            }
+
+            if (minor >= TLSv1_3_MINOR) {
+                if (!ssl->options.tls1_3) {
+                    ssl->options.tls1_3 = 1;
+                    TLSX_Push(&ssl->extensions, TLSX_SUPPORTED_VERSIONS, ssl,
+                              ssl->heap);
+#ifndef WOLFSSL_TLS13_DRAFT_18
+                    TLSX_SetResponse(ssl, TLSX_SUPPORTED_VERSIONS);
+#endif
+                }
+                if (minor > newMinor) {
+                    ssl->version.minor = minor;
+                    newMinor = minor;
+                }
+            }
+            else if (minor > ssl->options.oldMinor)
+                ssl->options.oldMinor = minor;
+
+            set = 1;
+        }
+        if (!set) {
+ #ifdef WOLFSSL_MYSQL_COMPATIBLE
+            SendAlert(ssl, alert_fatal, wc_protocol_version);
+ #else
+            SendAlert(ssl, alert_fatal, protocol_version);
+ #endif
+            return VERSION_ERROR;
+        }
+    }
+#ifndef WOLFSSL_TLS13_DRAFT_18
+    else if (msgType == server_hello || msgType == hello_retry_request) {
+        /* Must contain one version. */
+        if (length != OPAQUE16_LEN)
+            return BUFFER_ERROR;
+
+        major = input[0];
+        minor = input[OPAQUE8_LEN];
+
+    #ifdef WOLFSSL_TLS13_DRAFT
+        if (major == TLS_DRAFT_MAJOR && minor == TLS_DRAFT_MINOR) {
+            major = SSLv3_MAJOR;
+            minor = TLSv1_3_MINOR;
+        }
+    #endif
+
+        if (major != pv.major)
+            return VERSION_ERROR;
+
+        /* Can't downgrade with this extension below TLS v1.3. */
+        if (minor < TLSv1_3_MINOR)
+            return VERSION_ERROR;
+
+        /* Version is TLS v1.2 to handle downgrading from TLS v1.3+. */
+        if (ssl->options.downgrade && ssl->version.minor == TLSv1_2_MINOR) {
+            /* Set minor version back to TLS v1.3+ */
+            ssl->version.minor = ssl->ctx->method->version.minor;
+        }
+
+        /* No upgrade allowed. */
+        if (ssl->version.minor < minor)
+            return VERSION_ERROR;
+
+        /* Check downgrade. */
+        if (ssl->version.minor > minor) {
+            if (!ssl->options.downgrade)
+                return VERSION_ERROR;
+
+            if (minor < ssl->options.minDowngrade)
+                return VERSION_ERROR;
+
+            /* Downgrade the version. */
+            ssl->version.minor = minor;
+        }
+    }
+#endif
+    else
+        return SANITY_MSG_E;
+
+    return 0;
+}
+
+/* Sets a new SupportedVersions extension into the extension list.
+ *
+ * extensions  The list of extensions.
+ * data        The extensions specific data.
+ * heap        The heap used for allocation.
+ * returns 0 on success, otherwise failure.
+ */
+static int TLSX_SetSupportedVersions(TLSX** extensions, const void* data,
+                                     void* heap)
+{
+    if (extensions == NULL || data == NULL)
+        return BAD_FUNC_ARG;
+
+    return TLSX_Push(extensions, TLSX_SUPPORTED_VERSIONS, (void *)data, heap);
+}
+
+#define SV_GET_SIZE  TLSX_SupportedVersions_GetSize
+#define SV_WRITE     TLSX_SupportedVersions_Write
+#define SV_PARSE     TLSX_SupportedVersions_Parse
+
+#else
+
+#define SV_GET_SIZE(a, b, c) 0
+#define SV_WRITE(a, b, c, d) 0
+#define SV_PARSE(a, b, c, d) 0
+
+#endif /* WOLFSSL_TLS13 */
+
+#if defined(WOLFSSL_TLS13)
+
+/******************************************************************************/
+/* Cookie                                                                     */
+/******************************************************************************/
+
+/* Free the cookie data.
+ *
+ * cookie  Cookie data.
+ * heap    The heap used for allocation.
+ */
+static void TLSX_Cookie_FreeAll(Cookie* cookie, void* heap)
+{
+    (void)heap;
+
+    if (cookie != NULL)
+        XFREE(cookie, heap, DYNAMIC_TYPE_TLSX);
+}
+
+/* Get the size of the encoded Cookie extension.
+ * In messages: ClientHello and HelloRetryRequest.
+ *
+ * cookie   The cookie to write.
+ * msgType  The type of the message this extension is being written into.
+ * returns the number of bytes of the encoded Cookie extension.
+ */
+static int TLSX_Cookie_GetSize(Cookie* cookie, byte msgType, word16* pSz)
+{
+    if (msgType == client_hello || msgType == hello_retry_request)
+        *pSz += OPAQUE16_LEN + cookie->len;
+    else
+        return SANITY_MSG_E;
+    return 0;
+}
+
+/* Writes the Cookie extension into the output buffer.
+ * Assumes that the the output buffer is big enough to hold data.
+ * In messages: ClientHello and HelloRetryRequest.
+ *
+ * cookie   The cookie to write.
+ * output   The buffer to write into.
+ * msgType  The type of the message this extension is being written into.
+ * returns the number of bytes written into the buffer.
+ */
+static int TLSX_Cookie_Write(Cookie* cookie, byte* output, byte msgType,
+                             word16* pSz)
+{
+    if (msgType == client_hello || msgType == hello_retry_request) {
+        c16toa(cookie->len, output);
+        output += OPAQUE16_LEN;
+        XMEMCPY(output, &cookie->data, cookie->len);
+        *pSz += OPAQUE16_LEN + cookie->len;
+    }
+    else
+        return SANITY_MSG_E;
+    return 0;
+}
+
+/* Parse the Cookie extension.
+ * In messages: ClientHello and HelloRetryRequest.
+ *
+ * ssl      The SSL/TLS object.
+ * input    The extension data.
+ * length   The length of the extension data.
+ * msgType  The type of the message this extension is being parsed from.
+ * returns 0 on success and other values indicate failure.
+ */
+static int TLSX_Cookie_Parse(WOLFSSL* ssl, byte* input, word16 length,
+                                 byte msgType)
+{
+    word16  len;
+    word16  idx = 0;
+    TLSX*   extension;
+    Cookie* cookie;
+
+    if (msgType != client_hello && msgType != hello_retry_request)
+        return SANITY_MSG_E;
+
+    /* Message contains length and Cookie which must be at least one byte
+     * in length.
+     */
+    if (length < OPAQUE16_LEN + 1)
+        return BUFFER_E;
+    ato16(input + idx, &len);
+    idx += OPAQUE16_LEN;
+    if (length - idx != len)
+        return BUFFER_E;
+
+    if (msgType == hello_retry_request)
+        return TLSX_Cookie_Use(ssl, input + idx, len, NULL, 0, 0);
+
+    /* client_hello */
+    extension = TLSX_Find(ssl->extensions, TLSX_COOKIE);
+    if (extension == NULL)
+        return HRR_COOKIE_ERROR;
+
+    cookie = (Cookie*)extension->data;
+    if (cookie->len != len || XMEMCMP(&cookie->data, input + idx, len) != 0)
+        return HRR_COOKIE_ERROR;
+
+    /* Request seen. */
+    extension->resp = 0;
+
+    return 0;
+}
+
+/* Use the data to create a new Cookie object in the extensions.
+ *
+ * ssl    SSL/TLS object.
+ * data   Cookie data.
+ * len    Length of cookie data in bytes.
+ * mac    MAC data.
+ * macSz  Length of MAC data in bytes.
+ * resp   Indicates the extension will go into a response (HelloRetryRequest).
+ * returns 0 on success and other values indicate failure.
+ */
+int TLSX_Cookie_Use(WOLFSSL* ssl, byte* data, word16 len, byte* mac,
+                    byte macSz, int resp)
+{
+    int     ret = 0;
+    TLSX*   extension;
+    Cookie* cookie;
+
+    /* Find the cookie extension if it exists. */
+    extension = TLSX_Find(ssl->extensions, TLSX_COOKIE);
+    if (extension == NULL) {
+        /* Push new cookie extension. */
+        ret = TLSX_Push(&ssl->extensions, TLSX_COOKIE, NULL, ssl->heap);
+        if (ret != 0)
+            return ret;
+
+        extension = TLSX_Find(ssl->extensions, TLSX_COOKIE);
+        if (extension == NULL)
+            return MEMORY_E;
+    }
+
+    /* The Cookie structure has one byte for cookie data already. */
+    cookie = (Cookie*)XMALLOC(sizeof(Cookie) + len + macSz - 1, ssl->heap,
+                              DYNAMIC_TYPE_TLSX);
+    if (cookie == NULL)
+        return MEMORY_E;
+
+    cookie->len = len + macSz;
+    XMEMCPY(&cookie->data, data, len);
+    if (mac != NULL)
+        XMEMCPY(&cookie->data + len, mac, macSz);
+
+    extension->data = (void*)cookie;
+    extension->resp = (byte)resp;
+
+    return 0;
+}
+
+#define CKE_FREE_ALL  TLSX_Cookie_FreeAll
+#define CKE_GET_SIZE  TLSX_Cookie_GetSize
+#define CKE_WRITE     TLSX_Cookie_Write
+#define CKE_PARSE     TLSX_Cookie_Parse
+
+#else
+
+#define CKE_FREE_ALL(a, b)    0
+#define CKE_GET_SIZE(a, b, c) 0
+#define CKE_WRITE(a, b, c, d) 0
+#define CKE_PARSE(a, b, c, d) 0
+
+#endif
+#if !defined(WOLFSSL_NO_SIGALG)
+/******************************************************************************/
+/* Signature Algorithms                                                       */
+/******************************************************************************/
+
+/* Return the size of the SignatureAlgorithms extension's data.
+ *
+ * data  Unused
+ * returns the length of data that will be in the extension.
+ */
+
+static word16 TLSX_SignatureAlgorithms_GetSize(void* data)
+{
+    WOLFSSL* ssl = (WOLFSSL*)data;
+
+    return OPAQUE16_LEN + ssl->suites->hashSigAlgoSz;
+}
+
+/* Creates a bit string of supported hash algorithms with RSA PSS.
+ * The bit string is used when determining which signature algorithm to use
+ * when creating the CertificateVerify message.
+ * Note: Valid data has an even length as each signature algorithm is two bytes.
+ *
+ * ssl     The SSL/TLS object.
+ * input   The buffer with the list of supported signature algorithms.
+ * length  The length of the list in bytes.
+ * returns 0 on success, BUFFER_ERROR when the length is not even.
+ */
+static int TLSX_SignatureAlgorithms_MapPss(WOLFSSL *ssl, byte* input,
+                                                                  word16 length)
+{
+    word16 i;
+
+    if ((length & 1) == 1)
+        return BUFFER_ERROR;
+
+    ssl->pssAlgo = 0;
+    for (i = 0; i < length; i += 2) {
+        if (input[i] == rsa_pss_sa_algo && input[i + 1] <= sha512_mac)
+            ssl->pssAlgo |= 1 << input[i + 1];
+    #ifdef WOLFSSL_TLS13
+        if (input[i] == rsa_pss_sa_algo && input[i + 1] >= pss_sha256 &&
+                                                   input[i + 1] <= pss_sha512) {
+            ssl->pssAlgo |= 1 << input[i + 1];
+        }
+    #endif
+    }
+
+    return 0;
+}
+
+/* Writes the SignatureAlgorithms extension into the buffer.
+ *
+ * data    Unused
+ * output  The buffer to write the extension into.
+ * returns the length of data that was written.
+ */
+static word16 TLSX_SignatureAlgorithms_Write(void* data, byte* output)
+{
+    WOLFSSL* ssl = (WOLFSSL*)data;
+
+    c16toa(ssl->suites->hashSigAlgoSz, output);
+    XMEMCPY(output + OPAQUE16_LEN, ssl->suites->hashSigAlgo,
+            ssl->suites->hashSigAlgoSz);
+
+    TLSX_SignatureAlgorithms_MapPss(ssl, output + OPAQUE16_LEN,
+                                    ssl->suites->hashSigAlgoSz);
+
+    return OPAQUE16_LEN + ssl->suites->hashSigAlgoSz;
+}
+
+/* Parse the SignatureAlgorithms extension.
+ *
+ * ssl     The SSL/TLS object.
+ * input   The buffer with the extension data.
+ * length  The length of the extension data.
+ * returns 0 on success, otherwise failure.
+ */
+static int TLSX_SignatureAlgorithms_Parse(WOLFSSL *ssl, byte* input,
+                                  word16 length, byte isRequest, Suites* suites)
+{
+    word16 len;
+
+    if (!isRequest)
+        return BUFFER_ERROR;
+
+    /* Must contain a length and at least algorithm. */
+    if (length < OPAQUE16_LEN + OPAQUE16_LEN || (length & 1) != 0)
+        return BUFFER_ERROR;
+
+    ato16(input, &len);
+    input += OPAQUE16_LEN;
+
+    /* Algorithm array must fill rest of data. */
+    if (length != OPAQUE16_LEN + len)
+        return BUFFER_ERROR;
+
+    /* truncate hashSigAlgo list if too long */
+    suites->hashSigAlgoSz = len;
+    if (suites->hashSigAlgoSz > WOLFSSL_MAX_SIGALGO) {
+        WOLFSSL_MSG("TLSX SigAlgo list exceeds max, truncating");
+        suites->hashSigAlgoSz = WOLFSSL_MAX_SIGALGO;
+    }
+    XMEMCPY(suites->hashSigAlgo, input, suites->hashSigAlgoSz);
+
+    return TLSX_SignatureAlgorithms_MapPss(ssl, input, len);
+}
+
+/* Sets a new SignatureAlgorithms extension into the extension list.
+ *
+ * extensions  The list of extensions.
+ * data        The extensions specific data.
+ * heap        The heap used for allocation.
+ * returns 0 on success, otherwise failure.
+ */
+static int TLSX_SetSignatureAlgorithms(TLSX** extensions, const void* data,
+                                       void* heap)
+{
+    if (extensions == NULL)
+        return BAD_FUNC_ARG;
+
+    return TLSX_Push(extensions, TLSX_SIGNATURE_ALGORITHMS, (void *)data, heap);
+}
+
+#define SA_GET_SIZE  TLSX_SignatureAlgorithms_GetSize
+#define SA_WRITE     TLSX_SignatureAlgorithms_Write
+#define SA_PARSE     TLSX_SignatureAlgorithms_Parse
+#endif
+/******************************************************************************/
+/* Signature Algorithms Certificate                                           */
+/******************************************************************************/
+
+#ifdef WOLFSSL_TLS13
+#if !defined(WOLFSSL_TLS13_DRAFT_18) && !defined(WOLFSSL_TLS13_DRAFT_22)
+/* Return the size of the SignatureAlgorithms extension's data.
+ *
+ * data  Unused
+ * returns the length of data that will be in the extension.
+ */
+static word16 TLSX_SignatureAlgorithmsCert_GetSize(void* data)
+{
+    WOLFSSL* ssl = (WOLFSSL*)data;
+
+    return OPAQUE16_LEN + ssl->certHashSigAlgoSz;
+}
+
+/* Writes the SignatureAlgorithmsCert extension into the buffer.
+ *
+ * data    Unused
+ * output  The buffer to write the extension into.
+ * returns the length of data that was written.
+ */
+static word16 TLSX_SignatureAlgorithmsCert_Write(void* data, byte* output)
+{
+    WOLFSSL* ssl = (WOLFSSL*)data;
+
+    c16toa(ssl->certHashSigAlgoSz, output);
+    XMEMCPY(output + OPAQUE16_LEN, ssl->certHashSigAlgo,
+            ssl->certHashSigAlgoSz);
+
+    return OPAQUE16_LEN + ssl->certHashSigAlgoSz;
+}
+
+/* Parse the SignatureAlgorithmsCert extension.
+ *
+ * ssl     The SSL/TLS object.
+ * input   The buffer with the extension data.
+ * length  The length of the extension data.
+ * returns 0 on success, otherwise failure.
+ */
+static int TLSX_SignatureAlgorithmsCert_Parse(WOLFSSL *ssl, byte* input,
+                                              word16 length, byte isRequest)
+{
+    word16 len;
+
+    if (!isRequest)
+        return BUFFER_ERROR;
+
+    /* Must contain a length and at least algorithm. */
+    if (length < OPAQUE16_LEN + OPAQUE16_LEN || (length & 1) != 0)
+        return BUFFER_ERROR;
+
+    ato16(input, &len);
+    input += OPAQUE16_LEN;
+
+    /* Algorithm array must fill rest of data. */
+    if (length != OPAQUE16_LEN + len)
+        return BUFFER_ERROR;
+
+    /* truncate hashSigAlgo list if too long */
+    ssl->certHashSigAlgoSz = len;
+    if (ssl->certHashSigAlgoSz > WOLFSSL_MAX_SIGALGO) {
+        WOLFSSL_MSG("TLSX SigAlgo list exceeds max, truncating");
+        ssl->certHashSigAlgoSz = WOLFSSL_MAX_SIGALGO;
+    }
+    XMEMCPY(ssl->certHashSigAlgo, input, ssl->certHashSigAlgoSz);
+
+    return 0;
+}
+
+/* Sets a new SignatureAlgorithmsCert extension into the extension list.
+ *
+ * extensions  The list of extensions.
+ * data        The extensions specific data.
+ * heap        The heap used for allocation.
+ * returns 0 on success, otherwise failure.
+ */
+static int TLSX_SetSignatureAlgorithmsCert(TLSX** extensions, const void* data,
+                                                                     void* heap)
+{
+    if (extensions == NULL)
+        return BAD_FUNC_ARG;
+
+    return TLSX_Push(extensions, TLSX_SIGNATURE_ALGORITHMS_CERT, (void *)data,
+                                                                          heap);
+}
+
+#define SAC_GET_SIZE  TLSX_SignatureAlgorithmsCert_GetSize
+#define SAC_WRITE     TLSX_SignatureAlgorithmsCert_Write
+#define SAC_PARSE     TLSX_SignatureAlgorithmsCert_Parse
+#endif /* !WOLFSSL_TLS13_DRAFT_18 && !WOLFSSL_TLS13_DRAFT_22 */
+#endif /* WOLFSSL_TLS13 */
+
+
+/******************************************************************************/
+/* Key Share                                                                  */
+/******************************************************************************/
+
+#ifdef WOLFSSL_TLS13
+/* Create a key share entry using named Diffie-Hellman parameters group.
+ * Generates a key pair.
+ *
+ * ssl   The SSL/TLS object.
+ * kse   The key share entry object.
+ * returns 0 on success, otherwise failure.
+ */
+static int TLSX_KeyShare_GenDhKey(WOLFSSL *ssl, KeyShareEntry* kse)
+{
+    int             ret;
+#ifndef NO_DH
+    byte*           keyData;
+    void*           key = NULL;
+    word32          keySz;
+    word32          dataSz;
+    const DhParams* params;
+#ifdef WOLFSSL_SMALL_STACK
+    DhKey*          dhKey = NULL;
+#else
+    DhKey           dhKey[1];
+#endif
+
+    /* TODO: [TLS13] The key size should come from wolfcrypt. */
+    /* Pick the parameters from the named group. */
+    switch (kse->group) {
+    #ifdef HAVE_FFDHE_2048
+        case WOLFSSL_FFDHE_2048:
+            params = wc_Dh_ffdhe2048_Get();
+            keySz = 29;
+            break;
+    #endif
+    #ifdef HAVE_FFDHE_3072
+        case WOLFSSL_FFDHE_3072:
+            params = wc_Dh_ffdhe3072_Get();
+            keySz = 34;
+            break;
+    #endif
+    #ifdef HAVE_FFDHE_4096
+        case WOLFSSL_FFDHE_4096:
+            params = wc_Dh_ffdhe4096_Get();
+            keySz = 39;
+            break;
+    #endif
+    #ifdef HAVE_FFDHE_6144
+        case WOLFSSL_FFDHE_6144:
+            params = wc_Dh_ffdhe6144_Get();
+            keySz = 46;
+            break;
+    #endif
+    #ifdef HAVE_FFDHE_8192
+        case WOLFSSL_FFDHE_8192:
+            params = wc_Dh_ffdhe8192_Get();
+            keySz = 52;
+            break;
+    #endif
+        default:
+            return BAD_FUNC_ARG;
+    }
+
+#ifdef WOLFSSL_SMALL_STACK
+    dhKey = (DhKey*)XMALLOC(sizeof(DhKey), ssl->heap, DYNAMIC_TYPE_DH);
+    if (dhKey == NULL)
+        return MEMORY_E;
+#endif
+
+    ret = wc_InitDhKey_ex(dhKey, ssl->heap, ssl->devId);
+    if (ret != 0) {
+    #ifdef WOLFSSL_SMALL_STACK
+        XFREE(dhKey, ssl->heap, DYNAMIC_TYPE_DH);
+    #endif
+        return ret;
+    }
+
+    /* Allocate space for the public key. */
+    dataSz = params->p_len;
+    keyData = (byte*)XMALLOC(dataSz, ssl->heap, DYNAMIC_TYPE_PUBLIC_KEY);
+    if (keyData == NULL) {
+        ret = MEMORY_E;
+        goto end;
+    }
+    /* Allocate space for the private key. */
+    key = (byte*)XMALLOC(keySz, ssl->heap, DYNAMIC_TYPE_PRIVATE_KEY);
+    if (key == NULL) {
+        ret = MEMORY_E;
+        goto end;
+    }
+
+    /* Set key */
+    ret = wc_DhSetKey(dhKey,
+        (byte*)params->p, params->p_len,
+        (byte*)params->g, params->g_len);
+    if (ret != 0)
+        goto end;
+
+    /* Generate a new key pair. */
+    ret = wc_DhGenerateKeyPair(dhKey, ssl->rng, (byte*)key, &keySz, keyData,
+                               &dataSz);
+#ifdef WOLFSSL_ASYNC_CRYPT
+    /* TODO: Make this function non-blocking */
+    if (ret == WC_PENDING_E) {
+        ret = wc_AsyncWait(ret, &dhKey->asyncDev, WC_ASYNC_FLAG_NONE);
+    }
+#endif
+    if (ret != 0)
+        goto end;
+
+    if (params->p_len != dataSz) {
+        /* Pad the front of the key data with zeros. */
+        XMEMMOVE(keyData + params->p_len - dataSz, keyData, dataSz);
+        XMEMSET(keyData, 0, params->p_len - dataSz);
+    }
+
+    kse->pubKey = keyData;
+    kse->pubKeyLen = params->p_len;
+    kse->key = key;
+    kse->keyLen = keySz;
+
+#ifdef WOLFSSL_DEBUG_TLS
+    WOLFSSL_MSG("Public DH Key");
+    WOLFSSL_BUFFER(keyData, params->p_len);
+#endif
+
+end:
+
+    wc_FreeDhKey(dhKey);
+#ifdef WOLFSSL_SMALL_STACK
+    XFREE(dhKey, ssl->heap, DYNAMIC_TYPE_DH);
+#endif
+
+    if (ret != 0) {
+        /* Data owned by key share entry otherwise. */
+        if (keyData != NULL)
+            XFREE(keyData, ssl->heap, DYNAMIC_TYPE_PUBLIC_KEY);
+        if (key != NULL)
+            XFREE(key, ssl->heap, DYNAMIC_TYPE_PRIVATE_KEY);
+    }
+#else
+    (void)ssl;
+    (void)kse;
+
+    ret = NOT_COMPILED_IN;
+#endif
+
+    return ret;
+}
+
+/* Create a key share entry using X25519 parameters group.
+ * Generates a key pair.
+ *
+ * ssl   The SSL/TLS object.
+ * kse   The key share entry object.
+ * returns 0 on success, otherwise failure.
+ */
+static int TLSX_KeyShare_GenX25519Key(WOLFSSL *ssl, KeyShareEntry* kse)
+{
+    int             ret;
+#ifdef HAVE_CURVE25519
+    byte*           keyData = NULL;
+    word32          dataSize = CURVE25519_KEYSIZE;
+    curve25519_key* key;
+
+    /* Allocate an ECC key to hold private key. */
+    key = (curve25519_key*)XMALLOC(sizeof(curve25519_key), ssl->heap,
+                                                      DYNAMIC_TYPE_PRIVATE_KEY);
+    if (key == NULL) {
+        WOLFSSL_MSG("EccTempKey Memory error");
+        return MEMORY_E;
+    }
+
+    /* Make an ECC key. */
+    ret = wc_curve25519_init(key);
+    if (ret != 0)
+        goto end;
+    ret = wc_curve25519_make_key(ssl->rng, CURVE25519_KEYSIZE, key);
+    if (ret != 0)
+        goto end;
+
+    /* Allocate space for the public key. */
+    keyData = (byte*)XMALLOC(CURVE25519_KEYSIZE, ssl->heap,
+                                                       DYNAMIC_TYPE_PUBLIC_KEY);
+    if (keyData == NULL) {
+        WOLFSSL_MSG("Key data Memory error");
+        ret = MEMORY_E;
+        goto end;
+    }
+
+    /* Export public key. */
+    if (wc_curve25519_export_public_ex(key, keyData, &dataSize,
+                                                  EC25519_LITTLE_ENDIAN) != 0) {
+        ret = ECC_EXPORT_ERROR;
+        goto end;
+    }
+
+    kse->pubKey = keyData;
+    kse->pubKeyLen = CURVE25519_KEYSIZE;
+    kse->key = key;
+
+#ifdef WOLFSSL_DEBUG_TLS
+    WOLFSSL_MSG("Public Curve25519 Key");
+    WOLFSSL_BUFFER(keyData, dataSize);
+#endif
+
+end:
+    if (ret != 0) {
+        /* Data owned by key share entry otherwise. */
+        if (keyData != NULL)
+            XFREE(keyData, ssl->heap, DYNAMIC_TYPE_PUBLIC_KEY);
+        wc_curve25519_free(key);
+        XFREE(key, ssl->heap, DYNAMIC_TYPE_PRIVATE_KEY);
+    }
+#else
+    (void)ssl;
+    (void)kse;
+
+    ret = NOT_COMPILED_IN;
+#endif /* HAVE_CURVE25519 */
+
+    return ret;
+}
+
+/* Create a key share entry using X448 parameters group.
+ * Generates a key pair.
+ *
+ * ssl   The SSL/TLS object.
+ * kse   The key share entry object.
+ * returns 0 on success, otherwise failure.
+ */
+static int TLSX_KeyShare_GenX448Key(WOLFSSL *ssl, KeyShareEntry* kse)
+{
+    int             ret;
+#ifdef HAVE_CURVE448
+    byte*           keyData = NULL;
+    word32          dataSize = CURVE448_KEY_SIZE;
+    curve448_key*   key;
+
+    /* Allocate an ECC key to hold private key. */
+    key = (curve448_key*)XMALLOC(sizeof(curve448_key), ssl->heap,
+                                                      DYNAMIC_TYPE_PRIVATE_KEY);
+    if (key == NULL) {
+        WOLFSSL_MSG("EccTempKey Memory error");
+        return MEMORY_E;
+    }
+
+    /* Make an ECC key. */
+    ret = wc_curve448_init(key);
+    if (ret != 0)
+        goto end;
+    ret = wc_curve448_make_key(ssl->rng, CURVE448_KEY_SIZE, key);
+    if (ret != 0)
+        goto end;
+
+    /* Allocate space for the public key. */
+    keyData = (byte*)XMALLOC(CURVE448_KEY_SIZE, ssl->heap,
+                                                       DYNAMIC_TYPE_PUBLIC_KEY);
+    if (keyData == NULL) {
+        WOLFSSL_MSG("Key data Memory error");
+        ret = MEMORY_E;
+        goto end;
+    }
+
+    /* Export public key. */
+    if (wc_curve448_export_public_ex(key, keyData, &dataSize,
+                                                    EC448_LITTLE_ENDIAN) != 0) {
+        ret = ECC_EXPORT_ERROR;
+        goto end;
+    }
+
+    kse->pubKey = keyData;
+    kse->pubKeyLen = CURVE448_KEY_SIZE;
+    kse->key = key;
+
+#ifdef WOLFSSL_DEBUG_TLS
+    WOLFSSL_MSG("Public Curve448 Key");
+    WOLFSSL_BUFFER(keyData, dataSize);
+#endif
+
+end:
+    if (ret != 0) {
+        /* Data owned by key share entry otherwise. */
+        if (keyData != NULL)
+            XFREE(keyData, ssl->heap, DYNAMIC_TYPE_PUBLIC_KEY);
+        wc_curve448_free(key);
+        XFREE(key, ssl->heap, DYNAMIC_TYPE_PRIVATE_KEY);
+    }
+#else
+    (void)ssl;
+    (void)kse;
+
+    ret = NOT_COMPILED_IN;
+#endif /* HAVE_CURVE448 */
+
+    return ret;
+}
+
+/* Create a key share entry using named elliptic curve parameters group.
+ * Generates a key pair.
+ *
+ * ssl   The SSL/TLS object.
+ * kse   The key share entry object.
+ * returns 0 on success, otherwise failure.
+ */
+static int TLSX_KeyShare_GenEccKey(WOLFSSL *ssl, KeyShareEntry* kse)
+{
+    int      ret;
+#ifdef HAVE_ECC
+    byte*    keyData = NULL;
+    word32   dataSize;
+    byte*    keyPtr = NULL;
+    word32   keySize;
+    ecc_key* eccKey;
+    word16   curveId;
+
+    /* TODO: [TLS13] The key sizes should come from wolfcrypt. */
+    /* Translate named group to a curve id. */
+    switch (kse->group) {
+    #if !defined(NO_ECC256)  || defined(HAVE_ALL_CURVES)
+        #ifndef NO_ECC_SECP
+        case WOLFSSL_ECC_SECP256R1:
+            curveId = ECC_SECP256R1;
+            keySize = 32;
+            dataSize = keySize * 2 + 1;
+            break;
+        #endif /* !NO_ECC_SECP */
+    #endif
+    #if defined(HAVE_ECC384) || defined(HAVE_ALL_CURVES)
+        #ifndef NO_ECC_SECP
+        case WOLFSSL_ECC_SECP384R1:
+            curveId = ECC_SECP384R1;
+            keySize = 48;
+            dataSize = keySize * 2 + 1;
+            break;
+        #endif /* !NO_ECC_SECP */
+    #endif
+    #if defined(HAVE_ECC521) || defined(HAVE_ALL_CURVES)
+        #ifndef NO_ECC_SECP
+        case WOLFSSL_ECC_SECP521R1:
+            curveId = ECC_SECP521R1;
+            keySize = 66;
+            dataSize = keySize * 2 + 1;
+            break;
+        #endif /* !NO_ECC_SECP */
+    #endif
+    #ifdef HAVE_X448
+        case WOLFSSL_ECC_X448:
+            curveId = ECC_X448;
+            dataSize = keySize = 56;
+            break;
+    #endif
+        default:
+            return BAD_FUNC_ARG;
+    }
+
+    /* Allocate an ECC key to hold private key. */
+    keyPtr = (byte*)XMALLOC(sizeof(ecc_key), ssl->heap,
+                                                      DYNAMIC_TYPE_PRIVATE_KEY);
+    if (keyPtr == NULL) {
+        WOLFSSL_MSG("EccTempKey Memory error");
+        return MEMORY_E;
+    }
+    eccKey = (ecc_key*)keyPtr;
+
+    /* Make an ECC key. */
+    ret = wc_ecc_init_ex(eccKey, ssl->heap, ssl->devId);
+    if (ret != 0)
+        goto end;
+    ret = wc_ecc_make_key_ex(ssl->rng, keySize, eccKey, curveId);
+#ifdef WOLFSSL_ASYNC_CRYPT
+    /* TODO: Make this function non-blocking */
+    if (ret == WC_PENDING_E) {
+        ret = wc_AsyncWait(ret, &eccKey->asyncDev, WC_ASYNC_FLAG_NONE);
+    }
+#endif
+    if (ret != 0)
+        goto end;
+
+    /* Allocate space for the public key. */
+    keyData = (byte*)XMALLOC(dataSize, ssl->heap, DYNAMIC_TYPE_PUBLIC_KEY);
+    if (keyData == NULL) {
+        WOLFSSL_MSG("Key data Memory error");
+        ret = MEMORY_E;
+        goto end;
+    }
+
+    /* Export public key. */
+    if (wc_ecc_export_x963(eccKey, keyData, &dataSize) != 0) {
+        ret = ECC_EXPORT_ERROR;
+        goto end;
+    }
+
+    kse->pubKey = keyData;
+    kse->pubKeyLen = dataSize;
+    kse->key = keyPtr;
+
+#ifdef WOLFSSL_DEBUG_TLS
+    WOLFSSL_MSG("Public ECC Key");
+    WOLFSSL_BUFFER(keyData, dataSize);
+#endif
+
+end:
+    if (ret != 0) {
+        /* Data owned by key share entry otherwise. */
+        if (keyPtr != NULL)
+            XFREE(keyPtr, ssl->heap, DYNAMIC_TYPE_PRIVATE_KEY);
+        if (keyData != NULL)
+            XFREE(keyData, ssl->heap, DYNAMIC_TYPE_PUBLIC_KEY);
+    }
+#else
+    (void)ssl;
+    (void)kse;
+
+    ret = NOT_COMPILED_IN;
+#endif /* HAVE_ECC */
+
+    return ret;
+}
+
+/* Generate a secret/key using the key share entry.
+ *
+ * ssl  The SSL/TLS object.
+ * kse  The key share entry holding peer data.
+ */
+static int TLSX_KeyShare_GenKey(WOLFSSL *ssl, KeyShareEntry *kse)
+{
+    /* Named FFHE groups have a bit set to identify them. */
+    if ((kse->group & NAMED_DH_MASK) == NAMED_DH_MASK)
+        return TLSX_KeyShare_GenDhKey(ssl, kse);
+    if (kse->group == WOLFSSL_ECC_X25519)
+        return TLSX_KeyShare_GenX25519Key(ssl, kse);
+    if (kse->group == WOLFSSL_ECC_X448)
+        return TLSX_KeyShare_GenX448Key(ssl, kse);
+    return TLSX_KeyShare_GenEccKey(ssl, kse);
+}
+
+/* Free the key share dynamic data.
+ *
+ * list  The linked list of key share entry objects.
+ * heap  The heap used for allocation.
+ */
+static void TLSX_KeyShare_FreeAll(KeyShareEntry* list, void* heap)
+{
+    KeyShareEntry* current;
+
+    while ((current = list) != NULL) {
+        list = current->next;
+        if ((current->group & NAMED_DH_MASK) == 0) {
+            if (current->group == WOLFSSL_ECC_X25519) {
+#ifdef HAVE_CURVE25519
+                wc_curve25519_free((curve25519_key*)current->key);
+#endif
+            }
+            else if (current->group == WOLFSSL_ECC_X448) {
+#ifdef HAVE_CURVE448
+                wc_curve448_free((curve448_key*)current->key);
+#endif
+            }
+            else {
+#ifdef HAVE_ECC
+                wc_ecc_free((ecc_key*)(current->key));
+#endif
+            }
+        }
+        if (current->key != NULL)
+            XFREE(current->key, heap, DYNAMIC_TYPE_PRIVATE_KEY);
+        XFREE(current->pubKey, heap, DYNAMIC_TYPE_PUBLIC_KEY);
+        XFREE(current->ke, heap, DYNAMIC_TYPE_PUBLIC_KEY);
+        XFREE(current, heap, DYNAMIC_TYPE_TLSX);
+    }
+
+    (void)heap;
+}
+
+/* Get the size of the encoded key share extension.
+ *
+ * list     The linked list of key share extensions.
+ * msgType  The type of the message this extension is being written into.
+ * returns the number of bytes of the encoded key share extension.
+ */
+static word16 TLSX_KeyShare_GetSize(KeyShareEntry* list, byte msgType)
+{
+    word16         len = 0;
+    byte           isRequest = (msgType == client_hello);
+    KeyShareEntry* current;
+
+    /* The named group the server wants to use. */
+    if (msgType == hello_retry_request)
+        return OPAQUE16_LEN;
+
+    /* List of key exchange groups. */
+    if (isRequest)
+        len += OPAQUE16_LEN;
+    while ((current = list) != NULL) {
+        list = current->next;
+
+        if (!isRequest && current->key == NULL)
+            continue;
+
+        len += KE_GROUP_LEN + OPAQUE16_LEN + current->pubKeyLen;
+    }
+
+    return len;
+}
+
+/* Writes the key share extension into the output buffer.
+ * Assumes that the the output buffer is big enough to hold data.
+ *
+ * list     The linked list of key share entries.
+ * output   The buffer to write into.
+ * msgType  The type of the message this extension is being written into.
+ * returns the number of bytes written into the buffer.
+ */
+static word16 TLSX_KeyShare_Write(KeyShareEntry* list, byte* output,
+                                  byte msgType)
+{
+    word16         i = 0;
+    byte           isRequest = (msgType == client_hello);
+    KeyShareEntry* current;
+
+    if (msgType == hello_retry_request) {
+        c16toa(list->group, output);
+        return OPAQUE16_LEN;
+    }
+
+    /* ClientHello has a list but ServerHello is only the chosen. */
+    if (isRequest)
+        i += OPAQUE16_LEN;
+
+    /* Write out all in the list. */
+    while ((current = list) != NULL) {
+        list = current->next;
+
+        if (!isRequest && current->key == NULL)
+            continue;
+
+        c16toa(current->group, &output[i]);
+        i += KE_GROUP_LEN;
+        c16toa((word16)(current->pubKeyLen), &output[i]);
+        i += OPAQUE16_LEN;
+        XMEMCPY(&output[i], current->pubKey, current->pubKeyLen);
+        i += (word16)current->pubKeyLen;
+    }
+    /* Write the length of the list if required. */
+    if (isRequest)
+        c16toa(i - OPAQUE16_LEN, output);
+
+    return i;
+}
+
+/* Process the DH key share extension on the client side.
+ *
+ * ssl            The SSL/TLS object.
+ * keyShareEntry  The key share entry object to use to calculate shared secret.
+ * returns 0 on success and other values indicate failure.
+ */
+static int TLSX_KeyShare_ProcessDh(WOLFSSL* ssl, KeyShareEntry* keyShareEntry)
+{
+#ifndef NO_DH
+    int             ret;
+    const DhParams* params;
+#ifdef WOLFSSL_SMALL_STACK
+    DhKey*          dhKey = NULL;
+#else
+    DhKey           dhKey[1];
+#endif
+
+    switch (keyShareEntry->group) {
+    #ifdef HAVE_FFDHE_2048
+        case WOLFSSL_FFDHE_2048:
+            params = wc_Dh_ffdhe2048_Get();
+            break;
+    #endif
+    #ifdef HAVE_FFDHE_3072
+        case WOLFSSL_FFDHE_3072:
+            params = wc_Dh_ffdhe3072_Get();
+            break;
+    #endif
+    #ifdef HAVE_FFDHE_4096
+        case WOLFSSL_FFDHE_4096:
+            params = wc_Dh_ffdhe4096_Get();
+            break;
+    #endif
+    #ifdef HAVE_FFDHE_6144
+        case WOLFSSL_FFDHE_6144:
+            params = wc_Dh_ffdhe6144_Get();
+            break;
+    #endif
+    #ifdef HAVE_FFDHE_8192
+        case WOLFSSL_FFDHE_8192:
+            params = wc_Dh_ffdhe8192_Get();
+            break;
+    #endif
+        default:
+            return PEER_KEY_ERROR;
+    }
+
+#ifdef WOLFSSL_DEBUG_TLS
+    WOLFSSL_MSG("Peer DH Key");
+    WOLFSSL_BUFFER(keyShareEntry->ke, keyShareEntry->keLen);
+#endif
+
+#ifdef WOLFSSL_SMALL_STACK
+    dhKey = (DhKey*)XMALLOC(sizeof(DhKey), ssl->heap, DYNAMIC_TYPE_DH);
+    if (dhKey == NULL)
+        return MEMORY_E;
+#endif
+
+    ret = wc_InitDhKey_ex(dhKey, ssl->heap, ssl->devId);
+    if (ret != 0) {
+    #ifdef WOLFSSL_SMALL_STACK
+        XFREE(dhKey, ssl->heap, DYNAMIC_TYPE_DH);
+    #endif
+        return ret;
+    }
+
+    /* Set key */
+    ret = wc_DhSetKey(dhKey, (byte*)params->p, params->p_len, (byte*)params->g,
+                                                                 params->g_len);
+    if (ret != 0) {
+        wc_FreeDhKey(dhKey);
+    #ifdef WOLFSSL_SMALL_STACK
+        XFREE(dhKey, ssl->heap, DYNAMIC_TYPE_DH);
+    #endif
+        return ret;
+    }
+
+    ret = wc_DhCheckPubKey(dhKey, keyShareEntry->ke, keyShareEntry->keLen);
+    if (ret != 0) {
+        wc_FreeDhKey(dhKey);
+    #ifdef WOLFSSL_SMALL_STACK
+        XFREE(dhKey, ssl->heap, DYNAMIC_TYPE_DH);
+    #endif
+        return PEER_KEY_ERROR;
+    }
+
+    /* Derive secret from private key and peer's public key. */
+    ret = wc_DhAgree(dhKey,
+        ssl->arrays->preMasterSecret, &ssl->arrays->preMasterSz,
+        (const byte*)keyShareEntry->key, keyShareEntry->keyLen,
+        keyShareEntry->ke, keyShareEntry->keLen);
+#ifdef WOLFSSL_ASYNC_CRYPT
+    /* TODO: Make this function non-blocking */
+    if (ret == WC_PENDING_E) {
+        ret = wc_AsyncWait(ret, &dhKey->asyncDev, WC_ASYNC_FLAG_NONE);
+    }
+#endif
+    /* RFC 8446 Section 7.4.1:
+     *     ... left-padded with zeros up to the size of the prime. ...
+     */
+    if (params->p_len > ssl->arrays->preMasterSz) {
+        word32 diff = params->p_len - ssl->arrays->preMasterSz;
+        XMEMMOVE(ssl->arrays->preMasterSecret + diff,
+                        ssl->arrays->preMasterSecret, ssl->arrays->preMasterSz);
+        XMEMSET(ssl->arrays->preMasterSecret, 0, diff);
+        ssl->arrays->preMasterSz = params->p_len;
+    }
+
+    ssl->options.dhKeySz = params->p_len;
+
+    wc_FreeDhKey(dhKey);
+#ifdef WOLFSSL_SMALL_STACK
+    XFREE(dhKey, ssl->heap, DYNAMIC_TYPE_DH);
+#endif
+    if (keyShareEntry->key != NULL) {
+        XFREE(keyShareEntry->key, ssl->heap, DYNAMIC_TYPE_PRIVATE_KEY);
+        keyShareEntry->key = NULL;
+    }
+    XFREE(keyShareEntry->pubKey, ssl->heap, DYNAMIC_TYPE_PUBLIC_KEY);
+    keyShareEntry->pubKey = NULL;
+    XFREE(keyShareEntry->ke, ssl->heap, DYNAMIC_TYPE_PUBLIC_KEY);
+    keyShareEntry->ke = NULL;
+
+    return ret;
+#else
+    (void)ssl;
+    (void)keyShareEntry;
+    return PEER_KEY_ERROR;
+#endif
+}
+
+/* Process the X25519 key share extension on the client side.
+ *
+ * ssl            The SSL/TLS object.
+ * keyShareEntry  The key share entry object to use to calculate shared secret.
+ * returns 0 on success and other values indicate failure.
+ */
+static int TLSX_KeyShare_ProcessX25519(WOLFSSL* ssl,
+                                       KeyShareEntry* keyShareEntry)
+{
+    int ret;
+
+#ifdef HAVE_CURVE25519
+    curve25519_key* key = (curve25519_key*)keyShareEntry->key;
+    curve25519_key* peerX25519Key;
+
+#ifdef HAVE_ECC
+    if (ssl->peerEccKey != NULL) {
+        wc_ecc_free(ssl->peerEccKey);
+        ssl->peerEccKey = NULL;
+    }
+#endif
+
+    peerX25519Key = (curve25519_key*)XMALLOC(sizeof(curve25519_key), ssl->heap,
+                                                             DYNAMIC_TYPE_TLSX);
+    if (peerX25519Key == NULL) {
+        WOLFSSL_MSG("PeerEccKey Memory error");
+        return MEMORY_ERROR;
+    }
+    ret = wc_curve25519_init(peerX25519Key);
+    if (ret != 0) {
+        XFREE(peerX25519Key, ssl->heap, DYNAMIC_TYPE_TLSX);
+        return ret;
+    }
+#ifdef WOLFSSL_DEBUG_TLS
+    WOLFSSL_MSG("Peer Curve25519 Key");
+    WOLFSSL_BUFFER(keyShareEntry->ke, keyShareEntry->keLen);
+#endif
+
+    if (wc_curve25519_check_public(keyShareEntry->ke, keyShareEntry->keLen,
+                                                  EC25519_LITTLE_ENDIAN) != 0) {
+        ret = ECC_PEERKEY_ERROR;
+    }
+
+    if (ret == 0) {
+        if (wc_curve25519_import_public_ex(keyShareEntry->ke,
+                                            keyShareEntry->keLen, peerX25519Key,
+                                            EC25519_LITTLE_ENDIAN) != 0) {
+            ret = ECC_PEERKEY_ERROR;
+        }
+    }
+
+    if (ret == 0) {
+        ssl->ecdhCurveOID = ECC_X25519_OID;
+
+        ret = wc_curve25519_shared_secret_ex(key, peerX25519Key,
+                                                   ssl->arrays->preMasterSecret,
+                                                   &ssl->arrays->preMasterSz,
+                                                   EC25519_LITTLE_ENDIAN);
+    }
+
+    wc_curve25519_free(peerX25519Key);
+    XFREE(peerX25519Key, ssl->heap, DYNAMIC_TYPE_TLSX);
+    wc_curve25519_free((curve25519_key*)keyShareEntry->key);
+    if (keyShareEntry->key != NULL) {
+        XFREE(keyShareEntry->key, ssl->heap, DYNAMIC_TYPE_PRIVATE_KEY);
+        keyShareEntry->key = NULL;
+    }
+#else
+    (void)ssl;
+    (void)keyShareEntry;
+
+    ret = PEER_KEY_ERROR;
+#endif /* HAVE_CURVE25519 */
+
+    return ret;
+}
+
+/* Process the X448 key share extension on the client side.
+ *
+ * ssl            The SSL/TLS object.
+ * keyShareEntry  The key share entry object to use to calculate shared secret.
+ * returns 0 on success and other values indicate failure.
+ */
+static int TLSX_KeyShare_ProcessX448(WOLFSSL* ssl, KeyShareEntry* keyShareEntry)
+{
+    int ret;
+
+#ifdef HAVE_CURVE448
+    curve448_key* key = (curve448_key*)keyShareEntry->key;
+    curve448_key* peerX448Key;
+
+#ifdef HAVE_ECC
+    if (ssl->peerEccKey != NULL) {
+        wc_ecc_free(ssl->peerEccKey);
+        ssl->peerEccKey = NULL;
+    }
+#endif
+
+    peerX448Key = (curve448_key*)XMALLOC(sizeof(curve448_key), ssl->heap,
+                                                             DYNAMIC_TYPE_TLSX);
+    if (peerX448Key == NULL) {
+        WOLFSSL_MSG("PeerEccKey Memory error");
+        return MEMORY_ERROR;
+    }
+    ret = wc_curve448_init(peerX448Key);
+    if (ret != 0) {
+        XFREE(peerX448Key, ssl->heap, DYNAMIC_TYPE_TLSX);
+        return ret;
+    }
+#ifdef WOLFSSL_DEBUG_TLS
+    WOLFSSL_MSG("Peer Curve448 Key");
+    WOLFSSL_BUFFER(keyShareEntry->ke, keyShareEntry->keLen);
+#endif
+
+    if (wc_curve448_check_public(keyShareEntry->ke, keyShareEntry->keLen,
+                                                    EC448_LITTLE_ENDIAN) != 0) {
+        ret = ECC_PEERKEY_ERROR;
+    }
+
+    if (ret == 0) {
+        if (wc_curve448_import_public_ex(keyShareEntry->ke,
+                                              keyShareEntry->keLen, peerX448Key,
+                                              EC448_LITTLE_ENDIAN) != 0) {
+            ret = ECC_PEERKEY_ERROR;
+        }
+    }
+
+    if (ret == 0) {
+        ssl->ecdhCurveOID = ECC_X448_OID;
+
+        ret = wc_curve448_shared_secret_ex(key, peerX448Key,
+                                                   ssl->arrays->preMasterSecret,
+                                                   &ssl->arrays->preMasterSz,
+                                                   EC448_LITTLE_ENDIAN);
+    }
+
+    wc_curve448_free(peerX448Key);
+    XFREE(peerX448Key, ssl->heap, DYNAMIC_TYPE_TLSX);
+    wc_curve448_free((curve448_key*)keyShareEntry->key);
+    if (keyShareEntry->key != NULL) {
+        XFREE(keyShareEntry->key, ssl->heap, DYNAMIC_TYPE_PRIVATE_KEY);
+        keyShareEntry->key = NULL;
+    }
+#else
+    (void)ssl;
+    (void)keyShareEntry;
+
+    ret = PEER_KEY_ERROR;
+#endif /* HAVE_CURVE448 */
+
+    return ret;
+}
+
+/* Process the ECC key share extension on the client side.
+ *
+ * ssl            The SSL/TLS object.
+ * keyShareEntry  The key share entry object to use to calculate shared secret.
+ * returns 0 on success and other values indicate failure.
+ */
+static int TLSX_KeyShare_ProcessEcc(WOLFSSL* ssl, KeyShareEntry* keyShareEntry)
+{
+    int ret;
+
+#ifdef HAVE_ECC
+    int curveId;
+    ecc_key* keyShareKey = (ecc_key*)keyShareEntry->key;
+
+    if (ssl->peerEccKey != NULL)
+        wc_ecc_free(ssl->peerEccKey);
+
+    ssl->peerEccKey = (ecc_key*)XMALLOC(sizeof(ecc_key), ssl->heap,
+                                        DYNAMIC_TYPE_ECC);
+    if (ssl->peerEccKey == NULL) {
+        WOLFSSL_MSG("PeerEccKey Memory error");
+        return MEMORY_ERROR;
+    }
+    ret = wc_ecc_init_ex(ssl->peerEccKey, ssl->heap, ssl->devId);
+    if (ret != 0)
+        return ret;
+
+    /* find supported curve */
+    switch (keyShareEntry->group) {
+    #if !defined(NO_ECC256)  || defined(HAVE_ALL_CURVES)
+        #ifndef NO_ECC_SECP
+        case WOLFSSL_ECC_SECP256R1:
+            curveId = ECC_SECP256R1;
+            break;
+        #endif /* !NO_ECC_SECP */
+    #endif
+    #if defined(HAVE_ECC384) || defined(HAVE_ALL_CURVES)
+        #ifndef NO_ECC_SECP
+        case WOLFSSL_ECC_SECP384R1:
+            curveId = ECC_SECP384R1;
+            break;
+        #endif /* !NO_ECC_SECP */
+    #endif
+    #if defined(HAVE_ECC521) || defined(HAVE_ALL_CURVES)
+        #ifndef NO_ECC_SECP
+        case WOLFSSL_ECC_SECP521R1:
+            curveId = ECC_SECP521R1;
+            break;
+        #endif /* !NO_ECC_SECP */
+    #endif
+    #ifdef HAVE_X448
+        case WOLFSSL_ECC_X448:
+            curveId = ECC_X448;
+            break;
+    #endif
+        default:
+            /* unsupported curve */
+            return ECC_PEERKEY_ERROR;
+    }
+
+#ifdef WOLFSSL_DEBUG_TLS
+    WOLFSSL_MSG("Peer ECC Key");
+    WOLFSSL_BUFFER(keyShareEntry->ke, keyShareEntry->keLen);
+#endif
+
+    /* Point is validated by import function. */
+    if (wc_ecc_import_x963_ex(keyShareEntry->ke, keyShareEntry->keLen,
+                              ssl->peerEccKey, curveId) != 0) {
+        return ECC_PEERKEY_ERROR;
+    }
+    ssl->ecdhCurveOID = ssl->peerEccKey->dp->oidSum;
+
+    do {
+    #if defined(WOLFSSL_ASYNC_CRYPT)
+        ret = wc_AsyncWait(ret, &keyShareKey->asyncDev, WC_ASYNC_FLAG_CALL_AGAIN);
+    #endif
+        if (ret >= 0)
+            ret = wc_ecc_shared_secret(keyShareKey, ssl->peerEccKey,
+                ssl->arrays->preMasterSecret, &ssl->arrays->preMasterSz);
+    } while (ret == WC_PENDING_E);
+
+#if 0
+    /* TODO: Switch to support async here and use: */
+    ret = EccSharedSecret(ssl, keyShareEntry->key, ssl->peerEccKey,
+        keyShareEntry->ke, &keyShareEntry->keLen,
+        ssl->arrays->preMasterSecret, &ssl->arrays->preMasterSz,
+        ssl->options.side
+    );
+#endif
+
+    wc_ecc_free(ssl->peerEccKey);
+    XFREE(ssl->peerEccKey, ssl->heap, DYNAMIC_TYPE_ECC);
+    ssl->peerEccKey = NULL;
+    wc_ecc_free((ecc_key*)(keyShareEntry->key));
+    if (keyShareEntry->key != NULL) {
+        XFREE(keyShareEntry->key, ssl->heap, DYNAMIC_TYPE_PRIVATE_KEY);
+        keyShareEntry->key = NULL;
+    }
+
+#else
+    (void)ssl;
+    (void)keyShareEntry;
+
+    ret = PEER_KEY_ERROR;
+#endif /* HAVE_ECC */
+
+    return ret;
+}
+
+/* Process the key share extension on the client side.
+ *
+ * ssl            The SSL/TLS object.
+ * keyShareEntry  The key share entry object to use to calculate shared secret.
+ * returns 0 on success and other values indicate failure.
+ */
+static int TLSX_KeyShare_Process(WOLFSSL* ssl, KeyShareEntry* keyShareEntry)
+{
+    int ret;
+
+#if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
+    ssl->session.namedGroup = (byte)keyShareEntry->group;
+#endif
+    /* Use Key Share Data from server. */
+    if (keyShareEntry->group & NAMED_DH_MASK)
+        ret = TLSX_KeyShare_ProcessDh(ssl, keyShareEntry);
+    else if (keyShareEntry->group == WOLFSSL_ECC_X25519)
+        ret = TLSX_KeyShare_ProcessX25519(ssl, keyShareEntry);
+    else if (keyShareEntry->group == WOLFSSL_ECC_X448)
+        ret = TLSX_KeyShare_ProcessX448(ssl, keyShareEntry);
+    else
+        ret = TLSX_KeyShare_ProcessEcc(ssl, keyShareEntry);
+
+#ifdef WOLFSSL_DEBUG_TLS
+    WOLFSSL_MSG("KE Secret");
+    WOLFSSL_BUFFER(ssl->arrays->preMasterSecret, ssl->arrays->preMasterSz);
+#endif
+
+    return ret;
+}
+
+/* Parse an entry of the KeyShare extension.
+ *
+ * ssl     The SSL/TLS object.
+ * input   The extension data.
+ * length  The length of the extension data.
+ * kse     The new key share entry object.
+ * returns a positive number to indicate amount of data parsed and a negative
+ * number on error.
+ */
+static int TLSX_KeyShareEntry_Parse(WOLFSSL* ssl, byte* input, word16 length,
+                                    KeyShareEntry **kse)
+{
+    int    ret;
+    word16 group;
+    word16 keLen;
+    int    offset = 0;
+    byte*  ke;
+
+    if (length < OPAQUE16_LEN + OPAQUE16_LEN)
+        return BUFFER_ERROR;
+    /* Named group */
+    ato16(&input[offset], &group);
+    offset += OPAQUE16_LEN;
+    /* Key exchange data - public key. */
+    ato16(&input[offset], &keLen);
+    offset += OPAQUE16_LEN;
+    if (keLen == 0)
+        return INVALID_PARAMETER;
+    if (keLen > length - offset)
+        return BUFFER_ERROR;
+
+    /* Store a copy in the key share object. */
+    ke = (byte*)XMALLOC(keLen, ssl->heap, DYNAMIC_TYPE_PUBLIC_KEY);
+    if (ke == NULL)
+        return MEMORY_E;
+    XMEMCPY(ke, &input[offset], keLen);
+
+    /* Populate a key share object in the extension. */
+    ret = TLSX_KeyShare_Use(ssl, group, keLen, ke, kse);
+    if (ret != 0) {
+        XFREE(ke, ssl->heap, DYNAMIC_TYPE_PUBLIC_KEY);
+        return ret;
+    }
+
+    /* Total length of the parsed data. */
+    return offset + keLen;
+}
+
+/* Searches the groups sent for the specified named group.
+ *
+ * ssl    SSL/TLS object.
+ * name   Group name to match.
+ * returns 1 when the extension has the group name and 0 otherwise.
+ */
+static int TLSX_KeyShare_Find(WOLFSSL* ssl, word16 group)
+{
+    TLSX*          extension;
+    KeyShareEntry* list;
+
+    extension = TLSX_Find(ssl->extensions, TLSX_KEY_SHARE);
+    if (extension == NULL) {
+        extension = TLSX_Find(ssl->ctx->extensions, TLSX_KEY_SHARE);
+        if (extension == NULL)
+            return 0;
+    }
+
+    list = (KeyShareEntry*)extension->data;
+    while (list != NULL) {
+        if (list->group == group)
+            return 1;
+        list = list->next;
+    }
+
+    return 0;
+}
+
+
+/* Searches the supported groups extension for the specified named group.
+ *
+ * ssl   The SSL/TLS object.
+ * name  The group name to match.
+ * returns 1 when the extension has the group name and 0 otherwise.
+ */
+static int TLSX_SupportedGroups_Find(WOLFSSL* ssl, word16 name)
+{
+#ifdef HAVE_SUPPORTED_CURVES
+    TLSX*          extension;
+    SupportedCurve* curve = NULL;
+
+    if ((extension = TLSX_Find(ssl->extensions,
+                                              TLSX_SUPPORTED_GROUPS)) == NULL) {
+        if ((extension = TLSX_Find(ssl->ctx->extensions,
+                                              TLSX_SUPPORTED_GROUPS)) == NULL) {
+            return 0;
+        }
+    }
+
+    for (curve = (SupportedCurve*)extension->data; curve; curve = curve->next) {
+        if (curve->name == name)
+            return 1;
+    }
+#endif
+
+    (void)ssl;
+    (void)name;
+
+    return 0;
+}
+
+
+/* Parse the KeyShare extension.
+ * Different formats in different messages.
+ *
+ * ssl      The SSL/TLS object.
+ * input    The extension data.
+ * length   The length of the extension data.
+ * msgType  The type of the message this extension is being parsed from.
+ * returns 0 on success and other values indicate failure.
+ */
+static int TLSX_KeyShare_Parse(WOLFSSL* ssl, byte* input, word16 length,
+                               byte msgType)
+{
+    int ret;
+    KeyShareEntry *keyShareEntry = NULL;
+    word16 group;
+
+    if (msgType == client_hello) {
+        int    offset = 0;
+        word16 len;
+        TLSX*  extension;
+
+        /* Add a KeyShare extension if it doesn't exist. */
+        extension = TLSX_Find(ssl->extensions, TLSX_KEY_SHARE);
+        if (extension == NULL) {
+            /* Push new KeyShare extension. */
+            ret = TLSX_Push(&ssl->extensions, TLSX_KEY_SHARE, NULL, ssl->heap);
+            if (ret != 0)
+                return ret;
+        }
+
+        if (length < OPAQUE16_LEN)
+            return BUFFER_ERROR;
+
+        /* ClientHello contains zero or more key share entries. */
+        ato16(input, &len);
+        if (len != length - OPAQUE16_LEN)
+            return BUFFER_ERROR;
+        offset += OPAQUE16_LEN;
+
+        while (offset < (int)length) {
+            ret = TLSX_KeyShareEntry_Parse(ssl, &input[offset], length - offset,
+                                                                &keyShareEntry);
+            if (ret < 0)
+                return ret;
+
+            offset += ret;
+        }
+
+        ret = 0;
+    }
+    else if (msgType == server_hello) {
+        int len;
+
+        if (length < OPAQUE16_LEN)
+            return BUFFER_ERROR;
+
+        /* The data is the named group the server wants to use. */
+        ato16(input, &group);
+
+        /* Check the selected group was supported by ClientHello extensions. */
+        if (!TLSX_SupportedGroups_Find(ssl, group))
+            return BAD_KEY_SHARE_DATA;
+
+        /* Check if the group was sent. */
+        if (!TLSX_KeyShare_Find(ssl, group))
+            return BAD_KEY_SHARE_DATA;
+
+        /* ServerHello contains one key share entry. */
+        len = TLSX_KeyShareEntry_Parse(ssl, input, length, &keyShareEntry);
+        if (len != (int)length)
+            return BUFFER_ERROR;
+
+        /* Not in list sent if there isn't a private key. */
+        if (keyShareEntry == NULL || keyShareEntry->key == NULL)
+            return BAD_KEY_SHARE_DATA;
+
+        /* Process the entry to calculate the secret. */
+        ret = TLSX_KeyShare_Process(ssl, keyShareEntry);
+        if (ret == 0)
+            ssl->session.namedGroup = ssl->namedGroup = group;
+    }
+    else if (msgType == hello_retry_request) {
+        if (length != OPAQUE16_LEN)
+            return BUFFER_ERROR;
+
+        /* The data is the named group the server wants to use. */
+        ato16(input, &group);
+
+        /* Check the selected group was supported by ClientHello extensions. */
+        if (!TLSX_SupportedGroups_Find(ssl, group))
+            return BAD_KEY_SHARE_DATA;
+
+        /* Check if the group was sent. */
+        if (TLSX_KeyShare_Find(ssl, group))
+            return BAD_KEY_SHARE_DATA;
+
+        /* Clear out unusable key shares. */
+        ret = TLSX_KeyShare_Empty(ssl);
+        if (ret != 0)
+            return ret;
+
+        /* Try to use the server's group. */
+        ret = TLSX_KeyShare_Use(ssl, group, 0, NULL, NULL);
+    }
+    else {
+        /* Not a message type that is allowed to have this extension. */
+        return SANITY_MSG_E;
+    }
+
+    return ret;
+}
+
+/* Create a new key share entry and put it into the list.
+ *
+ * list           The linked list of key share entries.
+ * group          The named group.
+ * heap           The memory to allocate with.
+ * keyShareEntry  The new key share entry object.
+ * returns 0 on success and other values indicate failure.
+ */
+static int TLSX_KeyShare_New(KeyShareEntry** list, int group, void *heap,
+                             KeyShareEntry** keyShareEntry)
+{
+    KeyShareEntry* kse;
+    KeyShareEntry** next;
+
+    kse = (KeyShareEntry*)XMALLOC(sizeof(KeyShareEntry), heap,
+                                  DYNAMIC_TYPE_TLSX);
+    if (kse == NULL)
+        return MEMORY_E;
+
+    XMEMSET(kse, 0, sizeof(*kse));
+    kse->group = (word16)group;
+
+    /* Add it to the back and maintain the links. */
+    while (*list != NULL) {
+        /* Assign to temporary to work around compiler bug found by customer. */
+        next = &((*list)->next);
+        list = next;
+    }
+    *list = kse;
+    *keyShareEntry = kse;
+
+    (void)heap;
+
+    return 0;
+}
+
+/* Use the data to create a new key share object in the extensions.
+ *
+ * ssl    The SSL/TLS object.
+ * group  The named group.
+ * len    The length of the public key data.
+ * data   The public key data.
+ * kse    The new key share entry object.
+ * returns 0 on success and other values indicate failure.
+ */
+int TLSX_KeyShare_Use(WOLFSSL* ssl, word16 group, word16 len, byte* data,
+                      KeyShareEntry **kse)
+{
+    int            ret = 0;
+    TLSX*          extension;
+    KeyShareEntry* keyShareEntry = NULL;
+
+    /* Find the KeyShare extension if it exists. */
+    extension = TLSX_Find(ssl->extensions, TLSX_KEY_SHARE);
+    if (extension == NULL) {
+        /* Push new KeyShare extension. */
+        ret = TLSX_Push(&ssl->extensions, TLSX_KEY_SHARE, NULL, ssl->heap);
+        if (ret != 0)
+            return ret;
+
+        extension = TLSX_Find(ssl->extensions, TLSX_KEY_SHARE);
+        if (extension == NULL)
+            return MEMORY_E;
+    }
+    extension->resp = 0;
+
+    /* Try to find the key share entry with this group. */
+    keyShareEntry = (KeyShareEntry*)extension->data;
+    while (keyShareEntry != NULL) {
+        if (keyShareEntry->group == group)
+            break;
+        keyShareEntry = keyShareEntry->next;
+    }
+
+    /* Create a new key share entry if not found. */
+    if (keyShareEntry == NULL) {
+        ret = TLSX_KeyShare_New((KeyShareEntry**)&extension->data, group,
+                                ssl->heap, &keyShareEntry);
+        if (ret != 0)
+            return ret;
+    }
+
+    if (data != NULL) {
+        if (keyShareEntry->ke != NULL) {
+            XFREE(keyShareEntry->ke, ssl->heap, DYNAMIC_TYPE_PUBLIC_KEY);
+        }
+        keyShareEntry->ke = data;
+        keyShareEntry->keLen = len;
+    }
+    else {
+        /* Generate a key pair. */
+        ret = TLSX_KeyShare_GenKey(ssl, keyShareEntry);
+        if (ret != 0)
+            return ret;
+    }
+
+    if (kse != NULL)
+        *kse = keyShareEntry;
+
+    return 0;
+}
+
+/* Set an empty Key Share extension.
+ *
+ * ssl  The SSL/TLS object.
+ * returns 0 on success and other values indicate failure.
+ */
+int TLSX_KeyShare_Empty(WOLFSSL* ssl)
+{
+    int   ret = 0;
+    TLSX* extension;
+
+    /* Find the KeyShare extension if it exists. */
+    extension = TLSX_Find(ssl->extensions, TLSX_KEY_SHARE);
+    if (extension == NULL) {
+        /* Push new KeyShare extension. */
+        ret = TLSX_Push(&ssl->extensions, TLSX_KEY_SHARE, NULL, ssl->heap);
+    }
+    else if (extension->data != NULL) {
+        TLSX_KeyShare_FreeAll((KeyShareEntry*)extension->data, ssl->heap);
+        extension->data = NULL;
+    }
+
+    return ret;
+}
+
+/* Returns whether this group is supported.
+ *
+ * namedGroup  The named group to check.
+ * returns 1 when supported or 0 otherwise.
+ */
+static int TLSX_KeyShare_IsSupported(int namedGroup)
+{
+    switch (namedGroup) {
+    #ifdef HAVE_FFDHE_2048
+        case WOLFSSL_FFDHE_2048:
+            break;
+    #endif
+    #ifdef HAVE_FFDHE_3072
+        case WOLFSSL_FFDHE_3072:
+            break;
+    #endif
+    #ifdef HAVE_FFDHE_4096
+        case WOLFSSL_FFDHE_4096:
+            break;
+    #endif
+    #ifdef HAVE_FFDHE_6144
+        case WOLFSSL_FFDHE_6144:
+            break;
+    #endif
+    #ifdef HAVE_FFDHE_8192
+        case WOLFSSL_FFDHE_8192:
+            break;
+    #endif
+    #if !defined(NO_ECC256)  || defined(HAVE_ALL_CURVES)
+        #ifndef NO_ECC_SECP
+        case WOLFSSL_ECC_SECP256R1:
+            break;
+        #endif /* !NO_ECC_SECP */
+    #endif
+    #ifdef HAVE_CURVE25519
+        case WOLFSSL_ECC_X25519:
+            break;
+    #endif
+    #ifdef HAVE_CURVE448
+        case WOLFSSL_ECC_X448:
+            break;
+    #endif
+    #if defined(HAVE_ECC384) || defined(HAVE_ALL_CURVES)
+        #ifndef NO_ECC_SECP
+        case WOLFSSL_ECC_SECP384R1:
+            break;
+        #endif /* !NO_ECC_SECP */
+    #endif
+    #if defined(HAVE_ECC521) || defined(HAVE_ALL_CURVES)
+        #ifndef NO_ECC_SECP
+        case WOLFSSL_ECC_SECP521R1:
+            break;
+        #endif /* !NO_ECC_SECP */
+    #endif
+        default:
+            return 0;
+    }
+
+    return 1;
+}
+
+/* Examines the application specified group ranking and returns the rank of the
+ * group.
+ * If no group ranking set then all groups are rank 0 (highest).
+ *
+ * ssl    The SSL/TLS object.
+ * group  The group to check ranking for.
+ * returns ranking from 0 to MAX_GROUP_COUNT-1 or -1 when group not in list.
+ */
+static int TLSX_KeyShare_GroupRank(WOLFSSL* ssl, int group)
+{
+    byte i;
+
+    if (ssl->numGroups == 0) {
+#if defined(HAVE_ECC) && defined(HAVE_SUPPORTED_CURVES)
+    #if !defined(NO_ECC256)  || defined(HAVE_ALL_CURVES)
+        #ifndef NO_ECC_SECP
+            ssl->group[ssl->numGroups++] = WOLFSSL_ECC_SECP256R1;
+        #endif
+    #endif
+#endif
+    #ifndef HAVE_FIPS
+        #if defined(HAVE_CURVE25519)
+            ssl->group[ssl->numGroups++] = WOLFSSL_ECC_X25519;
+        #endif
+    #endif
+    #ifndef HAVE_FIPS
+        #if defined(HAVE_CURVE448)
+            ssl->group[ssl->numGroups++] = WOLFSSL_ECC_X448;
+        #endif
+    #endif
+#if defined(HAVE_ECC) && defined(HAVE_SUPPORTED_CURVES)
+    #if defined(HAVE_ECC384) || defined(HAVE_ALL_CURVES)
+        #ifndef NO_ECC_SECP
+            ssl->group[ssl->numGroups++] = WOLFSSL_ECC_SECP384R1;
+        #endif
+    #endif
+    #if defined(HAVE_ECC521) || defined(HAVE_ALL_CURVES)
+        #ifndef NO_ECC_SECP
+            ssl->group[ssl->numGroups++] = WOLFSSL_ECC_SECP521R1;
+        #endif
+    #endif
+#endif
+            /* Add FFDHE supported groups. */
+        #ifdef HAVE_FFDHE_2048
+            ssl->group[ssl->numGroups++] = WOLFSSL_FFDHE_2048;
+        #endif
+        #ifdef HAVE_FFDHE_3072
+            ssl->group[ssl->numGroups++] = WOLFSSL_FFDHE_3072;
+        #endif
+        #ifdef HAVE_FFDHE_4096
+            ssl->group[ssl->numGroups++] = WOLFSSL_FFDHE_4096;
+        #endif
+        #ifdef HAVE_FFDHE_6144
+            ssl->group[ssl->numGroups++] = WOLFSSL_FFDHE_6144;
+        #endif
+        #ifdef HAVE_FFDHE_8192
+            ssl->group[ssl->numGroups++] = WOLFSSL_FFDHE_8192;
+        #endif
+    }
+
+    for (i = 0; i < ssl->numGroups; i++)
+        if (ssl->group[i] == (word16)group)
+            return i;
+
+    return -1;
+}
+
+/* Set a key share that is supported by the client into extensions.
+ *
+ * ssl  The SSL/TLS object.
+ * returns BAD_KEY_SHARE_DATA if no supported group has a key share,
+ * 0 if a supported group has a key share and other values indicate an error.
+ */
+static int TLSX_KeyShare_SetSupported(WOLFSSL* ssl)
+{
+    int             ret;
+#ifdef HAVE_SUPPORTED_CURVES
+    TLSX*           extension;
+    SupportedCurve* curve = NULL;
+    SupportedCurve* preferredCurve = NULL;
+    int             preferredRank = WOLFSSL_MAX_GROUP_COUNT;
+    int             rank;
+
+    extension = TLSX_Find(ssl->extensions, TLSX_SUPPORTED_GROUPS);
+    if (extension != NULL)
+        curve = (SupportedCurve*)extension->data;
+    /* Use server's preference order. */
+    for (; curve != NULL; curve = curve->next) {
+        if (!TLSX_KeyShare_IsSupported(curve->name))
+            continue;
+
+        rank = TLSX_KeyShare_GroupRank(ssl, curve->name);
+        if (rank == -1)
+            continue;
+        if (rank < preferredRank) {
+            preferredCurve = curve;
+            preferredRank = rank;
+        }
+    }
+    curve = preferredCurve;
+
+    if (curve == NULL)
+        return BAD_KEY_SHARE_DATA;
+
+    /* Delete the old key share data list. */
+    extension = TLSX_Find(ssl->extensions, TLSX_KEY_SHARE);
+    if (extension != NULL) {
+        TLSX_KeyShare_FreeAll((KeyShareEntry*)extension->data, ssl->heap);
+        extension->data = NULL;
+    }
+
+    /* Add in the chosen group. */
+    ret = TLSX_KeyShare_Use(ssl, curve->name, 0, NULL, NULL);
+    if (ret != 0)
+        return ret;
+
+    /* Set extension to be in response. */
+    extension = TLSX_Find(ssl->extensions, TLSX_KEY_SHARE);
+    extension->resp = 1;
+#else
+
+    (void)ssl;
+    ret = NOT_COMPILED_IN;
+#endif
+
+    return ret;
+}
+
+/* Ensure there is a key pair that can be used for key exchange.
+ *
+ * ssl  The SSL/TLS object.
+ * returns 0 on success and other values indicate failure.
+ */
+int TLSX_KeyShare_Establish(WOLFSSL *ssl)
+{
+    int            ret;
+    TLSX*          extension;
+    KeyShareEntry* clientKSE = NULL;
+    KeyShareEntry* serverKSE;
+    KeyShareEntry* list = NULL;
+    KeyShareEntry* preferredKSE = NULL;
+    int preferredRank = WOLFSSL_MAX_GROUP_COUNT;
+    int rank;
+
+    /* Find the KeyShare extension if it exists. */
+    extension = TLSX_Find(ssl->extensions, TLSX_KEY_SHARE);
+    if (extension != NULL)
+        list = (KeyShareEntry*)extension->data;
+
+    if (extension && extension->resp == 1)
+        return 0;
+
+    /* Use server's preference order. */
+    for (clientKSE = list; clientKSE != NULL; clientKSE = clientKSE->next) {
+        if (clientKSE->ke == NULL)
+            continue;
+
+        /* Check consistency now - extensions in any order. */
+        if (!TLSX_SupportedGroups_Find(ssl, clientKSE->group))
+            return BAD_KEY_SHARE_DATA;
+
+    #ifdef OPENSSL_EXTRA
+        if ((clientKSE->group & NAMED_DH_MASK) == 0) {
+            /* Check if server supports group. */
+            if (ssl->ctx->disabledCurves & (1 << clientKSE->group))
+                continue;
+        }
+    #endif
+        if (!TLSX_KeyShare_IsSupported(clientKSE->group))
+            continue;
+
+        rank = TLSX_KeyShare_GroupRank(ssl, clientKSE->group);
+        if (rank == -1)
+            continue;
+        if (rank < preferredRank) {
+            preferredKSE = clientKSE;
+            preferredRank = rank;
+        }
+    }
+    clientKSE = preferredKSE;
+
+    /* No supported group found - send HelloRetryRequest. */
+    if (clientKSE == NULL) {
+        ret = TLSX_KeyShare_SetSupported(ssl);
+        /* Return KEY_SHARE_ERROR to indicate HelloRetryRequest required. */
+        if (ret == 0)
+            return KEY_SHARE_ERROR;
+        return ret;
+    }
+
+    list = NULL;
+    /* Generate a new key pair. */
+    ret = TLSX_KeyShare_New(&list, clientKSE->group, ssl->heap, &serverKSE);
+    if (ret != 0)
+        return ret;
+
+    if (clientKSE->key == NULL) {
+        ret = TLSX_KeyShare_GenKey(ssl, serverKSE);
+        if (ret != 0)
+            return ret;
+    }
+    else {
+        serverKSE->key = clientKSE->key;
+        serverKSE->keyLen = clientKSE->keyLen;
+        serverKSE->pubKey = clientKSE->pubKey;
+        serverKSE->pubKeyLen = clientKSE->pubKeyLen;
+        clientKSE->key = NULL;
+        clientKSE->pubKey = NULL;
+    }
+    serverKSE->ke = clientKSE->ke;
+    serverKSE->keLen = clientKSE->keLen;
+    clientKSE->ke = NULL;
+    clientKSE->keLen = 0;
+
+    TLSX_KeyShare_FreeAll((KeyShareEntry*)extension->data, ssl->heap);
+    extension->data = (void *)serverKSE;
+
+    extension->resp = 1;
+
+    return 0;
+}
+
+/* Derive the shared secret of the key exchange.
+ *
+ * ssl  The SSL/TLS object.
+ * returns 0 on success and other values indicate failure.
+ */
+int TLSX_KeyShare_DeriveSecret(WOLFSSL *ssl)
+{
+    int            ret;
+    TLSX*          extension;
+    KeyShareEntry* list = NULL;
+
+    /* Find the KeyShare extension if it exists. */
+    extension = TLSX_Find(ssl->extensions, TLSX_KEY_SHARE);
+    if (extension != NULL)
+        list = (KeyShareEntry*)extension->data;
+
+    if (list == NULL)
+        return KEY_SHARE_ERROR;
+
+    /* Calculate secret. */
+    ret = TLSX_KeyShare_Process(ssl, list);
+    if (ret != 0)
+        return ret;
+
+    return ret;
+}
+
+#define KS_FREE_ALL  TLSX_KeyShare_FreeAll
+#define KS_GET_SIZE  TLSX_KeyShare_GetSize
+#define KS_WRITE     TLSX_KeyShare_Write
+#define KS_PARSE     TLSX_KeyShare_Parse
+
+#else
+
+#define KS_FREE_ALL(a, b)
+#define KS_GET_SIZE(a, b)    0
+#define KS_WRITE(a, b, c)    0
+#define KS_PARSE(a, b, c, d) 0
+
+#endif /* WOLFSSL_TLS13 */
+
+/******************************************************************************/
+/* Pre-Shared Key                                                             */
+/******************************************************************************/
+
+#if defined(WOLFSSL_TLS13) && (defined(HAVE_SESSION_TICKET) || !defined(NO_PSK))
+/* Free the pre-shared key dynamic data.
+ *
+ * list  The linked list of key share entry objects.
+ * heap  The heap used for allocation.
+ */
+static void TLSX_PreSharedKey_FreeAll(PreSharedKey* list, void* heap)
+{
+    PreSharedKey* current;
+
+    while ((current = list) != NULL) {
+        list = current->next;
+        XFREE(current->identity, heap, DYNAMIC_TYPE_TLSX);
+        XFREE(current, heap, DYNAMIC_TYPE_TLSX);
+    }
+
+    (void)heap;
+}
+
+/* Get the size of the encoded pre shared key extension.
+ *
+ * list     The linked list of pre-shared key extensions.
+ * msgType  The type of the message this extension is being written into.
+ * returns the number of bytes of the encoded pre-shared key extension or
+ * SANITY_MSG_E to indicate invalid message type.
+ */
+static int TLSX_PreSharedKey_GetSize(PreSharedKey* list, byte msgType,
+                                     word16* pSz)
+{
+    if (msgType == client_hello) {
+        /* Length of identities + Length of binders. */
+        word16 len = OPAQUE16_LEN + OPAQUE16_LEN;
+        while (list != NULL) {
+            /* Each entry has: identity, ticket age and binder. */
+            len += OPAQUE16_LEN + list->identityLen + OPAQUE32_LEN +
+                   OPAQUE8_LEN + list->binderLen;
+            list = list->next;
+        }
+        *pSz += len;
+        return 0;
+    }
+
+    if (msgType == server_hello) {
+        *pSz += OPAQUE16_LEN;
+        return 0;
+    }
+
+    return SANITY_MSG_E;
+}
+
+/* The number of bytes to be written for the binders.
+ *
+ * list     The linked list of pre-shared key extensions.
+ * msgType  The type of the message this extension is being written into.
+ * returns the number of bytes of the encoded pre-shared key extension or
+ * SANITY_MSG_E to indicate invalid message type.
+ */
+int TLSX_PreSharedKey_GetSizeBinders(PreSharedKey* list, byte msgType,
+                                     word16* pSz)
+{
+    word16 len;
+
+    if (msgType != client_hello)
+        return SANITY_MSG_E;
+
+    /* Length of all binders. */
+    len = OPAQUE16_LEN;
+    while (list != NULL) {
+        len += OPAQUE8_LEN + list->binderLen;
+        list = list->next;
+    }
+
+    *pSz = len;
+    return 0;
+}
+
+/* Writes the pre-shared key extension into the output buffer - binders only.
+ * Assumes that the the output buffer is big enough to hold data.
+ *
+ * list     The linked list of key share entries.
+ * output   The buffer to write into.
+ * msgType  The type of the message this extension is being written into.
+ * returns the number of bytes written into the buffer.
+ */
+int TLSX_PreSharedKey_WriteBinders(PreSharedKey* list, byte* output,
+                                   byte msgType, word16* pSz)
+{
+    PreSharedKey* current = list;
+    word16 idx = 0;
+    word16 lenIdx;
+    word16 len;
+
+    if (msgType != client_hello)
+        return SANITY_MSG_E;
+
+    /* Skip length of all binders. */
+    lenIdx = idx;
+    idx += OPAQUE16_LEN;
+    while (current != NULL) {
+        /* Binder data length. */
+        output[idx++] = current->binderLen;
+        /* Binder data. */
+        XMEMCPY(output + idx, current->binder, current->binderLen);
+        idx += current->binderLen;
+
+        current = current->next;
+    }
+    /* Length of the binders. */
+    len = idx - lenIdx - OPAQUE16_LEN;
+    c16toa(len, output + lenIdx);
+
+    *pSz = idx;
+    return 0;
+}
+
+
+/* Writes the pre-shared key extension into the output buffer.
+ * Assumes that the the output buffer is big enough to hold data.
+ *
+ * list     The linked list of key share entries.
+ * output   The buffer to write into.
+ * msgType  The type of the message this extension is being written into.
+ * returns the number of bytes written into the buffer.
+ */
+static int TLSX_PreSharedKey_Write(PreSharedKey* list, byte* output,
+                                   byte msgType, word16* pSz)
+{
+    if (msgType == client_hello) {
+        PreSharedKey* current = list;
+        word16 idx = 0;
+        word16 lenIdx;
+        word16 len;
+        int ret;
+
+        /* Write identites only. Binders after HMACing over this. */
+        lenIdx = idx;
+        idx += OPAQUE16_LEN;
+        while (current != NULL) {
+            /* Identity length */
+            c16toa(current->identityLen, output + idx);
+            idx += OPAQUE16_LEN;
+            /* Identity data */
+            XMEMCPY(output + idx, current->identity, current->identityLen);
+            idx += current->identityLen;
+
+            /* Obfuscated ticket age. */
+            c32toa(current->ticketAge, output + idx);
+            idx += OPAQUE32_LEN;
+
+            current = current->next;
+        }
+        /* Length of the identites. */
+        len = idx - lenIdx - OPAQUE16_LEN;
+        c16toa(len, output + lenIdx);
+
+        /* Don't include binders here.
+         * The binders are based on the hash of all the ClientHello data up to
+         * and include the identities written above.
+         */
+        ret = TLSX_PreSharedKey_GetSizeBinders(list, msgType, &len);
+        if (ret < 0)
+            return ret;
+        *pSz += idx + len;
+    }
+    else if (msgType == server_hello) {
+        word16 i;
+
+        /* Find the index of the chosen identity. */
+        for (i=0; list != NULL && !list->chosen; i++)
+            list = list->next;
+        if (list == NULL)
+            return BUILD_MSG_ERROR;
+
+        /* The index of the identity chosen by the server from the list supplied
+         * by the client.
+         */
+        c16toa(i, output);
+        *pSz += OPAQUE16_LEN;
+    }
+    else
+        return SANITY_MSG_E;
+
+    return 0;
+}
+
+/* Parse the pre-shared key extension.
+ * Different formats in different messages.
+ *
+ * ssl      The SSL/TLS object.
+ * input    The extension data.
+ * length   The length of the extension data.
+ * msgType  The type of the message this extension is being parsed from.
+ * returns 0 on success and other values indicate failure.
+ */
+static int TLSX_PreSharedKey_Parse(WOLFSSL* ssl, byte* input, word16 length,
+                                   byte msgType)
+{
+    TLSX*         extension;
+    PreSharedKey* list;
+
+    if (msgType == client_hello) {
+        int    ret;
+        word16 len;
+        word16 idx = 0;
+
+        TLSX_Remove(&ssl->extensions, TLSX_PRE_SHARED_KEY, ssl->heap);
+
+        /* Length of identities and of binders. */
+        if (length - idx < OPAQUE16_LEN + OPAQUE16_LEN)
+            return BUFFER_E;
+
+        /* Length of identities. */
+        ato16(input + idx, &len);
+        idx += OPAQUE16_LEN;
+        if (len < MIN_PSK_ID_LEN || length - idx < len)
+            return BUFFER_E;
+
+        /* Create a pre-shared key object for each identity. */
+        while (len > 0) {
+            byte*  identity;
+            word16 identityLen;
+            word32 age;
+
+            if (len < OPAQUE16_LEN)
+                return BUFFER_E;
+
+            /* Length of identity. */
+            ato16(input + idx, &identityLen);
+            idx += OPAQUE16_LEN;
+            if (len < OPAQUE16_LEN + identityLen + OPAQUE32_LEN ||
+                    identityLen > MAX_PSK_ID_LEN)
+                return BUFFER_E;
+            /* Cache identity pointer. */
+            identity = input + idx;
+            idx += identityLen;
+            /* Ticket age. */
+            ato32(input + idx, &age);
+            idx += OPAQUE32_LEN;
+
+            ret = TLSX_PreSharedKey_Use(ssl, identity, identityLen, age, no_mac,
+                                        0, 0, 1, NULL);
+            if (ret != 0)
+                return ret;
+
+            /* Done with this identity. */
+            len -= OPAQUE16_LEN + identityLen + OPAQUE32_LEN;
+        }
+
+        /* Find the list of identities sent to server. */
+        extension = TLSX_Find(ssl->extensions, TLSX_PRE_SHARED_KEY);
+        if (extension == NULL)
+            return PSK_KEY_ERROR;
+        list = (PreSharedKey*)extension->data;
+
+        /* Length of binders. */
+        if (idx + OPAQUE16_LEN > length)
+            return BUFFER_E;
+        ato16(input + idx, &len);
+        idx += OPAQUE16_LEN;
+        if (len < MIN_PSK_BINDERS_LEN || length - idx < len)
+            return BUFFER_E;
+
+        /* Set binder for each identity. */
+        while (list != NULL && len > 0) {
+            /* Length of binder */
+            list->binderLen = input[idx++];
+            if (list->binderLen < WC_SHA256_DIGEST_SIZE ||
+                    list->binderLen > WC_MAX_DIGEST_SIZE)
+                return BUFFER_E;
+            if (len < OPAQUE8_LEN + list->binderLen)
+                return BUFFER_E;
+
+            /* Copy binder into static buffer. */
+            XMEMCPY(list->binder, input + idx, list->binderLen);
+            idx += list->binderLen;
+
+            /* Done with binder entry. */
+            len -= OPAQUE8_LEN + list->binderLen;
+
+            /* Next identity. */
+            list = list->next;
+        }
+        if (list != NULL || len != 0)
+            return BUFFER_E;
+
+        return 0;
+    }
+
+    if (msgType == server_hello) {
+        word16 idx;
+
+        /* Index of identity chosen by server. */
+        if (length != OPAQUE16_LEN)
+            return BUFFER_E;
+        ato16(input, &idx);
+
+    #ifdef WOLFSSL_EARLY_DATA
+        ssl->options.pskIdIndex = idx + 1;
+    #endif
+
+        /* Find the list of identities sent to server. */
+        extension = TLSX_Find(ssl->extensions, TLSX_PRE_SHARED_KEY);
+        if (extension == NULL)
+            return PSK_KEY_ERROR;
+        list = (PreSharedKey*)extension->data;
+
+        /* Mark the identity as chosen. */
+        for (; list != NULL && idx > 0; idx--)
+            list = list->next;
+        if (list == NULL)
+            return PSK_KEY_ERROR;
+        list->chosen = 1;
+
+    #ifdef HAVE_SESSION_TICKET
+        if (list->resumption) {
+           /* Check that the session's details are the same as the server's. */
+           if (ssl->options.cipherSuite0  != ssl->session.cipherSuite0       ||
+               ssl->options.cipherSuite   != ssl->session.cipherSuite        ||
+               ssl->session.version.major != ssl->ctx->method->version.major ||
+               ssl->session.version.minor != ssl->ctx->method->version.minor) {
+               return PSK_KEY_ERROR;
+           }
+        }
+    #endif
+
+        return 0;
+    }
+
+    return SANITY_MSG_E;
+}
+
+/* Create a new pre-shared key and put it into the list.
+ *
+ * list          The linked list of pre-shared key.
+ * identity      The identity.
+ * len           The length of the identity data.
+ * heap          The memory to allocate with.
+ * preSharedKey  The new pre-shared key object.
+ * returns 0 on success and other values indicate failure.
+ */
+static int TLSX_PreSharedKey_New(PreSharedKey** list, byte* identity,
+                                 word16 len, void *heap,
+                                 PreSharedKey** preSharedKey)
+{
+    PreSharedKey* psk;
+    PreSharedKey** next;
+
+    psk = (PreSharedKey*)XMALLOC(sizeof(PreSharedKey), heap, DYNAMIC_TYPE_TLSX);
+    if (psk == NULL)
+        return MEMORY_E;
+    XMEMSET(psk, 0, sizeof(*psk));
+
+    /* Make a copy of the identity data. */
+    psk->identity = (byte*)XMALLOC(len, heap, DYNAMIC_TYPE_TLSX);
+    if (psk->identity == NULL) {
+        XFREE(psk, heap, DYNAMIC_TYPE_TLSX);
+        return MEMORY_E;
+    }
+    XMEMCPY(psk->identity, identity, len);
+    psk->identityLen = len;
+
+    /* Add it to the end and maintain the links. */
+    while (*list != NULL) {
+        /* Assign to temporary to work around compiler bug found by customer. */
+        next = &((*list)->next);
+        list = next;
+    }
+    *list = psk;
+    *preSharedKey = psk;
+
+    (void)heap;
+
+    return 0;
+}
+
+static WC_INLINE byte GetHmacLength(int hmac)
+{
+    switch (hmac) {
+    #ifndef NO_SHA256
+        case sha256_mac:
+            return WC_SHA256_DIGEST_SIZE;
+    #endif
+    #ifdef WOLFSSL_SHA384
+        case sha384_mac:
+            return WC_SHA384_DIGEST_SIZE;
+    #endif
+    #ifdef WOLFSSL_SHA512
+        case sha512_mac:
+            return WC_SHA512_DIGEST_SIZE;
+    #endif
+    }
+    return 0;
+}
+
+/* Use the data to create a new pre-shared key object in the extensions.
+ *
+ * ssl           The SSL/TLS object.
+ * identity      The identity.
+ * len           The length of the identity data.
+ * age           The age of the identity.
+ * hmac          The HMAC algorithm.
+ * ciphersuite0  The first byte of the ciphersuite to use.
+ * ciphersuite   The second byte of the ciphersuite to use.
+ * resumption    The PSK is for resumption of a session.
+ * preSharedKey  The new pre-shared key object.
+ * returns 0 on success and other values indicate failure.
+ */
+int TLSX_PreSharedKey_Use(WOLFSSL* ssl, byte* identity, word16 len, word32 age,
+                          byte hmac, byte cipherSuite0,
+                          byte cipherSuite, byte resumption,
+                          PreSharedKey **preSharedKey)
+{
+    int           ret = 0;
+    TLSX*         extension;
+    PreSharedKey* psk = NULL;
+
+    /* Find the pre-shared key extension if it exists. */
+    extension = TLSX_Find(ssl->extensions, TLSX_PRE_SHARED_KEY);
+    if (extension == NULL) {
+        /* Push new pre-shared key extension. */
+        ret = TLSX_Push(&ssl->extensions, TLSX_PRE_SHARED_KEY, NULL, ssl->heap);
+        if (ret != 0)
+            return ret;
+
+        extension = TLSX_Find(ssl->extensions, TLSX_PRE_SHARED_KEY);
+        if (extension == NULL)
+            return MEMORY_E;
+    }
+
+    /* Try to find the pre-shared key with this identity. */
+    psk = (PreSharedKey*)extension->data;
+    while (psk != NULL) {
+        if ((psk->identityLen == len) &&
+               (XMEMCMP(psk->identity, identity, len) == 0)) {
+            break;
+        }
+        psk = psk->next;
+    }
+
+    /* Create a new pre-shared key object if not found. */
+    if (psk == NULL) {
+        ret = TLSX_PreSharedKey_New((PreSharedKey**)&extension->data, identity,
+                                    len, ssl->heap, &psk);
+        if (ret != 0)
+            return ret;
+    }
+
+    /* Update/set age and HMAC algorithm. */
+    psk->ticketAge    = age;
+    psk->hmac         = hmac;
+    psk->cipherSuite0 = cipherSuite0;
+    psk->cipherSuite  = cipherSuite;
+    psk->resumption   = resumption;
+    psk->binderLen    = GetHmacLength(psk->hmac);
+
+    if (preSharedKey != NULL)
+        *preSharedKey = psk;
+
+    return 0;
+}
+
+#define PSK_FREE_ALL  TLSX_PreSharedKey_FreeAll
+#define PSK_GET_SIZE  TLSX_PreSharedKey_GetSize
+#define PSK_WRITE     TLSX_PreSharedKey_Write
+#define PSK_PARSE     TLSX_PreSharedKey_Parse
+
+#else
+
+#define PSK_FREE_ALL(a, b)
+#define PSK_GET_SIZE(a, b, c) 0
+#define PSK_WRITE(a, b, c, d) 0
+#define PSK_PARSE(a, b, c, d) 0
+
+#endif
+
+/******************************************************************************/
+/* PSK Key Exchange Modes                                                     */
+/******************************************************************************/
+
+#if defined(WOLFSSL_TLS13) && (defined(HAVE_SESSION_TICKET) || !defined(NO_PSK))
+/* Get the size of the encoded PSK KE modes extension.
+ * Only in ClientHello.
+ *
+ * modes    The PSK KE mode bit string.
+ * msgType  The type of the message this extension is being written into.
+ * returns the number of bytes of the encoded PSK KE mode extension.
+ */
+static int TLSX_PskKeModes_GetSize(byte modes, byte msgType, word16* pSz)
+{
+    if (msgType == client_hello) {
+        /* Format: Len | Modes* */
+        word16 len = OPAQUE8_LEN;
+        /* Check whether each possible mode is to be written. */
+        if (modes & (1 << PSK_KE))
+            len += OPAQUE8_LEN;
+        if (modes & (1 << PSK_DHE_KE))
+            len += OPAQUE8_LEN;
+        *pSz += len;
+        return 0;
+    }
+
+    return SANITY_MSG_E;
+}
+
+/* Writes the PSK KE modes extension into the output buffer.
+ * Assumes that the the output buffer is big enough to hold data.
+ * Only in ClientHello.
+ *
+ * modes    The PSK KE mode bit string.
+ * output   The buffer to write into.
+ * msgType  The type of the message this extension is being written into.
+ * returns the number of bytes written into the buffer.
+ */
+static int TLSX_PskKeModes_Write(byte modes, byte* output, byte msgType,
+                                 word16* pSz)
+{
+    if (msgType == client_hello) {
+        /* Format: Len | Modes* */
+        int idx = OPAQUE8_LEN;
+
+        /* Write out each possible mode. */
+        if (modes & (1 << PSK_KE))
+            output[idx++] = PSK_KE;
+        if (modes & (1 << PSK_DHE_KE))
+            output[idx++] = PSK_DHE_KE;
+        /* Write out length of mode list. */
+        output[0] = idx - OPAQUE8_LEN;
+
+        *pSz += idx;
+        return 0;
+    }
+
+    return SANITY_MSG_E;
+}
+
+/* Parse the PSK KE modes extension.
+ * Only in ClientHello.
+ *
+ * ssl      The SSL/TLS object.
+ * input    The extension data.
+ * length   The length of the extension data.
+ * msgType  The type of the message this extension is being parsed from.
+ * returns 0 on success and other values indicate failure.
+ */
+static int TLSX_PskKeModes_Parse(WOLFSSL* ssl, byte* input, word16 length,
+                                 byte msgType)
+{
+    int    ret;
+
+    if (msgType == client_hello) {
+        /* Format: Len | Modes* */
+        int   idx = 0;
+        word16 len;
+        byte  modes = 0;
+
+        /* Ensure length byte exists. */
+        if (length < OPAQUE8_LEN)
+            return BUFFER_E;
+
+        /* Get length of mode list and ensure that is the only data. */
+        len = input[0];
+        if (length - OPAQUE8_LEN != len)
+            return BUFFER_E;
+
+        idx = OPAQUE8_LEN;
+        /* Set a bit for each recognized modes. */
+        while (len > 0) {
+            /* Ignore unrecognized modes.  */
+            if (input[idx] <= PSK_DHE_KE)
+               modes |= 1 << input[idx];
+            idx++;
+            len--;
+        }
+
+        ret = TLSX_PskKeModes_Use(ssl, modes);
+        if (ret != 0)
+            return ret;
+
+        return 0;
+    }
+
+    return SANITY_MSG_E;
+}
+
+/* Use the data to create a new PSK Key Exchange Modes object in the extensions.
+ *
+ * ssl    The SSL/TLS object.
+ * modes  The PSK key exchange modes.
+ * returns 0 on success and other values indicate failure.
+ */
+int TLSX_PskKeModes_Use(WOLFSSL* ssl, byte modes)
+{
+    int           ret = 0;
+    TLSX*         extension;
+
+    /* Find the PSK key exchange modes extension if it exists. */
+    extension = TLSX_Find(ssl->extensions, TLSX_PSK_KEY_EXCHANGE_MODES);
+    if (extension == NULL) {
+        /* Push new PSK key exchange modes extension. */
+        ret = TLSX_Push(&ssl->extensions, TLSX_PSK_KEY_EXCHANGE_MODES, NULL,
+            ssl->heap);
+        if (ret != 0)
+            return ret;
+
+        extension = TLSX_Find(ssl->extensions, TLSX_PSK_KEY_EXCHANGE_MODES);
+        if (extension == NULL)
+            return MEMORY_E;
+    }
+
+    extension->val = modes;
+
+    return 0;
+}
+
+#define PKM_GET_SIZE  TLSX_PskKeModes_GetSize
+#define PKM_WRITE     TLSX_PskKeModes_Write
+#define PKM_PARSE     TLSX_PskKeModes_Parse
+
+#else
+
+#define PKM_GET_SIZE(a, b, c) 0
+#define PKM_WRITE(a, b, c, d) 0
+#define PKM_PARSE(a, b, c, d) 0
+
+#endif
+
+/******************************************************************************/
+/* Post-Handshake Authentication                                              */
+/******************************************************************************/
+
+#if defined(WOLFSSL_TLS13) && defined(WOLFSSL_POST_HANDSHAKE_AUTH)
+/* Get the size of the encoded Post-Handshake Authentication extension.
+ * Only in ClientHello.
+ *
+ * msgType  The type of the message this extension is being written into.
+ * returns the number of bytes of the encoded Post-Handshake Authentication
+ * extension.
+ */
+static int TLSX_PostHandAuth_GetSize(byte msgType, word16* pSz)
+{
+    if (msgType == client_hello) {
+        *pSz += 0;
+        return 0;
+    }
+
+    return SANITY_MSG_E;
+}
+
+/* Writes the Post-Handshake Authentication extension into the output buffer.
+ * Assumes that the the output buffer is big enough to hold data.
+ * Only in ClientHello.
+ *
+ * output   The buffer to write into.
+ * msgType  The type of the message this extension is being written into.
+ * returns the number of bytes written into the buffer.
+ */
+static int TLSX_PostHandAuth_Write(byte* output, byte msgType, word16* pSz)
+{
+    (void)output;
+
+    if (msgType == client_hello) {
+        *pSz += 0;
+        return 0;
+    }
+
+    return SANITY_MSG_E;
+}
+
+/* Parse the Post-Handshake Authentication extension.
+ * Only in ClientHello.
+ *
+ * ssl      The SSL/TLS object.
+ * input    The extension data.
+ * length   The length of the extension data.
+ * msgType  The type of the message this extension is being parsed from.
+ * returns 0 on success and other values indicate failure.
+ */
+static int TLSX_PostHandAuth_Parse(WOLFSSL* ssl, byte* input, word16 length,
+                                 byte msgType)
+{
+    (void)input;
+
+    if (msgType == client_hello) {
+        /* Ensure extension is empty. */
+        if (length != 0)
+            return BUFFER_E;
+
+        ssl->options.postHandshakeAuth = 1;
+        return 0;
+    }
+
+    return SANITY_MSG_E;
+}
+
+/* Create a new Post-handshake authentication object in the extensions.
+ *
+ * ssl    The SSL/TLS object.
+ * returns 0 on success and other values indicate failure.
+ */
+static int TLSX_PostHandAuth_Use(WOLFSSL* ssl)
+{
+    int   ret = 0;
+    TLSX* extension;
+
+    /* Find the PSK key exchange modes extension if it exists. */
+    extension = TLSX_Find(ssl->extensions, TLSX_POST_HANDSHAKE_AUTH);
+    if (extension == NULL) {
+        /* Push new Post-handshake Authentication extension. */
+        ret = TLSX_Push(&ssl->extensions, TLSX_POST_HANDSHAKE_AUTH, NULL,
+            ssl->heap);
+        if (ret != 0)
+            return ret;
+    }
+
+    return 0;
+}
+
+#define PHA_GET_SIZE  TLSX_PostHandAuth_GetSize
+#define PHA_WRITE     TLSX_PostHandAuth_Write
+#define PHA_PARSE     TLSX_PostHandAuth_Parse
+
+#else
+
+#define PHA_GET_SIZE(a, b)    0
+#define PHA_WRITE(a, b, c)    0
+#define PHA_PARSE(a, b, c, d) 0
+
+#endif
+
+/******************************************************************************/
+/* Early Data Indication                                                      */
+/******************************************************************************/
+
+#ifdef WOLFSSL_EARLY_DATA
+/* Get the size of the encoded Early Data Indication extension.
+ * In messages: ClientHello, EncryptedExtensions and NewSessionTicket.
+ *
+ * msgType  The type of the message this extension is being written into.
+ * returns the number of bytes of the encoded Early Data Indication extension.
+ */
+static int TLSX_EarlyData_GetSize(byte msgType, word16* pSz)
+{
+    int ret = 0;
+
+    if (msgType == client_hello || msgType == encrypted_extensions)
+        *pSz += 0;
+    else if (msgType == session_ticket)
+        *pSz += OPAQUE32_LEN;
+    else
+        ret = SANITY_MSG_E;
+
+    return ret;
+}
+
+/* Writes the Early Data Indicator extension into the output buffer.
+ * Assumes that the the output buffer is big enough to hold data.
+ * In messages: ClientHello, EncryptedExtensions and NewSessionTicket.
+ *
+ * max      The maximum early data size.
+ * output   The buffer to write into.
+ * msgType  The type of the message this extension is being written into.
+ * returns the number of bytes written into the buffer.
+ */
+static int TLSX_EarlyData_Write(word32 max, byte* output, byte msgType,
+                                word16* pSz)
+{
+    if (msgType == client_hello || msgType == encrypted_extensions)
+        return 0;
+    else if (msgType == session_ticket) {
+        c32toa(max, output);
+        *pSz += OPAQUE32_LEN;
+        return 0;
+    }
+
+    return SANITY_MSG_E;
+}
+
+/* Parse the Early Data Indicator extension.
+ * In messages: ClientHello, EncryptedExtensions and NewSessionTicket.
+ *
+ * ssl      The SSL/TLS object.
+ * input    The extension data.
+ * length   The length of the extension data.
+ * msgType  The type of the message this extension is being parsed from.
+ * returns 0 on success and other values indicate failure.
+ */
+static int TLSX_EarlyData_Parse(WOLFSSL* ssl, byte* input, word16 length,
+                                 byte msgType)
+{
+    if (msgType == client_hello) {
+        if (length != 0)
+            return BUFFER_E;
+
+        if (ssl->earlyData == expecting_early_data)
+            return TLSX_EarlyData_Use(ssl, 0);
+        ssl->earlyData = early_data_ext;
+        return 0;
+    }
+    if (msgType == encrypted_extensions) {
+        if (length != 0)
+            return BUFFER_E;
+
+        /* Ensure the index of PSK identity chosen by server is 0.
+         * Index is plus one to handle 'not set' value of 0.
+         */
+        if (ssl->options.pskIdIndex != 1)
+            return PSK_KEY_ERROR;
+
+        return TLSX_EarlyData_Use(ssl, 1);
+    }
+    if (msgType == session_ticket) {
+        word32 maxSz;
+
+        if (length != OPAQUE32_LEN)
+            return BUFFER_E;
+        ato32(input, &maxSz);
+
+        ssl->session.maxEarlyDataSz = maxSz;
+        return 0;
+    }
+
+    return SANITY_MSG_E;
+}
+
+/* Use the data to create a new Early Data object in the extensions.
+ *
+ * ssl  The SSL/TLS object.
+ * max  The maximum early data size.
+ * returns 0 on success and other values indicate failure.
+ */
+int TLSX_EarlyData_Use(WOLFSSL* ssl, word32 max)
+{
+    int   ret = 0;
+    TLSX* extension;
+
+    /* Find the early data extension if it exists. */
+    extension = TLSX_Find(ssl->extensions, TLSX_EARLY_DATA);
+    if (extension == NULL) {
+        /* Push new early data extension. */
+        ret = TLSX_Push(&ssl->extensions, TLSX_EARLY_DATA, NULL, ssl->heap);
+        if (ret != 0)
+            return ret;
+
+        extension = TLSX_Find(ssl->extensions, TLSX_EARLY_DATA);
+        if (extension == NULL)
+            return MEMORY_E;
+    }
+
+    extension->resp = 1;
+    extension->val  = max;
+
+    return 0;
+}
+
+#define EDI_GET_SIZE  TLSX_EarlyData_GetSize
+#define EDI_WRITE     TLSX_EarlyData_Write
+#define EDI_PARSE     TLSX_EarlyData_Parse
+
+#else
+
+#define EDI_GET_SIZE(a, b)    0
+#define EDI_WRITE(a, b, c, d) 0
+#define EDI_PARSE(a, b, c, d) 0
+
+#endif
+
+/******************************************************************************/
+/* TLS Extensions Framework                                                   */
+/******************************************************************************/
+
+/** Finds an extension in the provided list. */
+TLSX* TLSX_Find(TLSX* list, TLSX_Type type)
+{
+    TLSX* extension = list;
+
+    while (extension && extension->type != type)
+        extension = extension->next;
+
+    return extension;
+}
+
+/** Remove an extension. */
+void TLSX_Remove(TLSX** list, TLSX_Type type, void* heap)
+{
+    TLSX* extension = *list;
+    TLSX** next = list;
+
+    while (extension && extension->type != type) {
+        next = &extension->next;
+        extension = extension->next;
+    }
+
+    if (extension) {
+        *next = extension->next;
+        extension->next = NULL;
+        TLSX_FreeAll(extension, heap);
+    }
+}
+
+/** Releases all extensions in the provided list. */
+void TLSX_FreeAll(TLSX* list, void* heap)
+{
+    TLSX* extension;
+
+    while ((extension = list)) {
+        list = extension->next;
+
+        switch (extension->type) {
+
+            case TLSX_SERVER_NAME:
+                SNI_FREE_ALL((SNI*)extension->data, heap);
+                break;
+
+            case TLSX_TRUSTED_CA_KEYS:
+                TCA_FREE_ALL((TCA*)extension->data, heap);
+                break;
+
+            case TLSX_MAX_FRAGMENT_LENGTH:
+                MFL_FREE_ALL(extension->data, heap);
+                break;
+
+            case TLSX_TRUNCATED_HMAC:
+                /* Nothing to do. */
+                break;
+
+            case TLSX_SUPPORTED_GROUPS:
+                EC_FREE_ALL((SupportedCurve*)extension->data, heap);
+                break;
+
+            case TLSX_EC_POINT_FORMATS:
+                PF_FREE_ALL((PointFormat*)extension->data, heap);
+                break;
+
+            case TLSX_STATUS_REQUEST:
+                CSR_FREE_ALL((CertificateStatusRequest*)extension->data, heap);
+                break;
+
+            case TLSX_STATUS_REQUEST_V2:
+                CSR2_FREE_ALL((CertificateStatusRequestItemV2*)extension->data,
+                        heap);
+                break;
+
+            case TLSX_RENEGOTIATION_INFO:
+                SCR_FREE_ALL(extension->data, heap);
+                break;
+
+            case TLSX_SESSION_TICKET:
+                WOLF_STK_FREE(extension->data, heap);
+                break;
+
+            case TLSX_QUANTUM_SAFE_HYBRID:
+                QSH_FREE_ALL((QSHScheme*)extension->data, heap);
+                break;
+
+            case TLSX_APPLICATION_LAYER_PROTOCOL:
+                ALPN_FREE_ALL((ALPN*)extension->data, heap);
+                break;
+#if !defined(WOLFSSL_NO_SIGALG)
+            case TLSX_SIGNATURE_ALGORITHMS:
+                break;
+#endif
+#if defined(HAVE_ENCRYPT_THEN_MAC) && !defined(WOLFSSL_AEAD_ONLY)
+            case TLSX_ENCRYPT_THEN_MAC:
+                break;
+#endif
+#ifdef WOLFSSL_TLS13
+            case TLSX_SUPPORTED_VERSIONS:
+                break;
+
+            case TLSX_COOKIE:
+                CKE_FREE_ALL((Cookie*)extension->data, heap);
+                break;
+
+    #if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
+            case TLSX_PRE_SHARED_KEY:
+                PSK_FREE_ALL((PreSharedKey*)extension->data, heap);
+                break;
+
+            case TLSX_PSK_KEY_EXCHANGE_MODES:
+                break;
+    #endif
+
+    #ifdef WOLFSSL_EARLY_DATA
+            case TLSX_EARLY_DATA:
+                break;
+    #endif
+
+    #ifdef WOLFSSL_POST_HANDSHAKE_AUTH
+            case TLSX_POST_HANDSHAKE_AUTH:
+                break;
+    #endif
+
+    #if !defined(WOLFSSL_TLS13_DRAFT_18) && !defined(WOLFSSL_TLS13_DRAFT_22)
+            case TLSX_SIGNATURE_ALGORITHMS_CERT:
+                break;
+    #endif
+
+            case TLSX_KEY_SHARE:
+                KS_FREE_ALL((KeyShareEntry*)extension->data, heap);
+                break;
+#endif
+        }
+
+        XFREE(extension, heap, DYNAMIC_TYPE_TLSX);
+    }
+
+    (void)heap;
+}
+
+/** Checks if the tls extensions are supported based on the protocol version. */
+int TLSX_SupportExtensions(WOLFSSL* ssl) {
+    return ssl && (IsTLS(ssl) || ssl->version.major == DTLS_MAJOR);
+}
+
+/** Tells the buffered size of the extensions in a list. */
+static int TLSX_GetSize(TLSX* list, byte* semaphore, byte msgType,
+                        word16* pLength)
+{
+    int    ret = 0;
+    TLSX*  extension;
+    word16 length = 0;
+    byte   isRequest = (msgType == client_hello ||
+                        msgType == certificate_request);
+
+    while ((extension = list)) {
+        list = extension->next;
+
+        /* only extensions marked as response are sent back to the client. */
+        if (!isRequest && !extension->resp)
+            continue; /* skip! */
+
+        /* ssl level extensions are expected to override ctx level ones. */
+        if (!IS_OFF(semaphore, TLSX_ToSemaphore(extension->type)))
+            continue; /* skip! */
+
+        /* extension type + extension data length. */
+        length += HELLO_EXT_TYPE_SZ + OPAQUE16_LEN;
+
+
+        switch (extension->type) {
+
+            case TLSX_SERVER_NAME:
+                /* SNI only sends the name on the request. */
+                if (isRequest)
+                    length += SNI_GET_SIZE((SNI*)extension->data);
+                break;
+
+            case TLSX_TRUSTED_CA_KEYS:
+                /* TCA only sends the list on the request. */
+                if (isRequest)
+                    length += TCA_GET_SIZE((TCA*)extension->data);
+                break;
+
+            case TLSX_MAX_FRAGMENT_LENGTH:
+                length += MFL_GET_SIZE(extension->data);
+                break;
+
+            case TLSX_TRUNCATED_HMAC:
+                /* always empty. */
+                break;
+
+            case TLSX_SUPPORTED_GROUPS:
+                length += EC_GET_SIZE((SupportedCurve*)extension->data);
+                break;
+
+            case TLSX_EC_POINT_FORMATS:
+                length += PF_GET_SIZE((PointFormat*)extension->data);
+                break;
+
+            case TLSX_STATUS_REQUEST:
+                length += CSR_GET_SIZE(
+                         (CertificateStatusRequest*)extension->data, isRequest);
+                break;
+
+            case TLSX_STATUS_REQUEST_V2:
+                length += CSR2_GET_SIZE(
+                        (CertificateStatusRequestItemV2*)extension->data,
+                        isRequest);
+                break;
+
+            case TLSX_RENEGOTIATION_INFO:
+                length += SCR_GET_SIZE((SecureRenegotiation*)extension->data,
+                        isRequest);
+                break;
+
+            case TLSX_SESSION_TICKET:
+                length += WOLF_STK_GET_SIZE((SessionTicket*)extension->data,
+                        isRequest);
+                break;
+
+            case TLSX_QUANTUM_SAFE_HYBRID:
+                length += QSH_GET_SIZE((QSHScheme*)extension->data, isRequest);
+                break;
+
+            case TLSX_APPLICATION_LAYER_PROTOCOL:
+                length += ALPN_GET_SIZE((ALPN*)extension->data);
+                break;
+#if !defined(WOLFSSL_NO_SIGALG)
+            case TLSX_SIGNATURE_ALGORITHMS:
+                length += SA_GET_SIZE(extension->data);
+                break;
+#endif
+#if defined(HAVE_ENCRYPT_THEN_MAC) && !defined(WOLFSSL_AEAD_ONLY)
+            case TLSX_ENCRYPT_THEN_MAC:
+                ret = ETM_GET_SIZE(msgType, &length);
+                break;
+#endif /* HAVE_ENCRYPT_THEN_MAC */
+#ifdef WOLFSSL_TLS13
+            case TLSX_SUPPORTED_VERSIONS:
+                ret = SV_GET_SIZE(extension->data, msgType, &length);
+                break;
+
+            case TLSX_COOKIE:
+                ret = CKE_GET_SIZE((Cookie*)extension->data, msgType, &length);
+                break;
+
+    #if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
+            case TLSX_PRE_SHARED_KEY:
+                ret = PSK_GET_SIZE((PreSharedKey*)extension->data, msgType,
+                                                                       &length);
+                break;
+
+            case TLSX_PSK_KEY_EXCHANGE_MODES:
+                ret = PKM_GET_SIZE(extension->val, msgType, &length);
+                break;
+    #endif
+
+    #ifdef WOLFSSL_EARLY_DATA
+            case TLSX_EARLY_DATA:
+                ret = EDI_GET_SIZE(msgType, &length);
+                break;
+    #endif
+
+    #ifdef WOLFSSL_POST_HANDSHAKE_AUTH
+            case TLSX_POST_HANDSHAKE_AUTH:
+                ret = PHA_GET_SIZE(msgType, &length);
+                break;
+    #endif
+
+    #if !defined(WOLFSSL_TLS13_DRAFT_18) && !defined(WOLFSSL_TLS13_DRAFT_22)
+            case TLSX_SIGNATURE_ALGORITHMS_CERT:
+                length += SAC_GET_SIZE(extension->data);
+                break;
+    #endif
+
+            case TLSX_KEY_SHARE:
+                length += KS_GET_SIZE((KeyShareEntry*)extension->data, msgType);
+                break;
+#endif
+        }
+
+        /* marks the extension as processed so ctx level */
+        /* extensions don't overlap with ssl level ones. */
+        TURN_ON(semaphore, TLSX_ToSemaphore(extension->type));
+    }
+
+    *pLength += length;
+
+    return ret;
+}
+
+/** Writes the extensions of a list in a buffer. */
+static int TLSX_Write(TLSX* list, byte* output, byte* semaphore,
+                         byte msgType, word16* pOffset)
+{
+    int    ret = 0;
+    TLSX*  extension;
+    word16 offset = 0;
+    word16 length_offset = 0;
+    byte   isRequest = (msgType == client_hello ||
+                        msgType == certificate_request);
+
+    while ((extension = list)) {
+        list = extension->next;
+
+        /* only extensions marked as response are written in a response. */
+        if (!isRequest && !extension->resp)
+            continue; /* skip! */
+
+        /* ssl level extensions are expected to override ctx level ones. */
+        if (!IS_OFF(semaphore, TLSX_ToSemaphore(extension->type)))
+            continue; /* skip! */
+
+        /* writes extension type. */
+        c16toa(extension->type, output + offset);
+        offset += HELLO_EXT_TYPE_SZ + OPAQUE16_LEN;
+        length_offset = offset;
+
+        /* extension data should be written internally. */
+        switch (extension->type) {
+            case TLSX_SERVER_NAME:
+                if (isRequest) {
+                    WOLFSSL_MSG("SNI extension to write");
+                    offset += SNI_WRITE((SNI*)extension->data, output + offset);
+                }
+                break;
+
+            case TLSX_TRUSTED_CA_KEYS:
+                WOLFSSL_MSG("Trusted CA Indication extension to write");
+                if (isRequest) {
+                    offset += TCA_WRITE((TCA*)extension->data, output + offset);
+                }
+                break;
+
+            case TLSX_MAX_FRAGMENT_LENGTH:
+                WOLFSSL_MSG("Max Fragment Length extension to write");
+                offset += MFL_WRITE((byte*)extension->data, output + offset);
+                break;
+
+            case TLSX_TRUNCATED_HMAC:
+                WOLFSSL_MSG("Truncated HMAC extension to write");
+                /* always empty. */
+                break;
+
+            case TLSX_SUPPORTED_GROUPS:
+                WOLFSSL_MSG("Supported Groups extension to write");
+                offset += EC_WRITE((SupportedCurve*)extension->data,
+                                    output + offset);
+                break;
+
+            case TLSX_EC_POINT_FORMATS:
+                WOLFSSL_MSG("Point Formats extension to write");
+                offset += PF_WRITE((PointFormat*)extension->data,
+                                    output + offset);
+                break;
+
+            case TLSX_STATUS_REQUEST:
+                WOLFSSL_MSG("Certificate Status Request extension to write");
+                offset += CSR_WRITE((CertificateStatusRequest*)extension->data,
+                        output + offset, isRequest);
+                break;
+
+            case TLSX_STATUS_REQUEST_V2:
+                WOLFSSL_MSG("Certificate Status Request v2 extension to write");
+                offset += CSR2_WRITE(
+                        (CertificateStatusRequestItemV2*)extension->data,
+                        output + offset, isRequest);
+                break;
+
+            case TLSX_RENEGOTIATION_INFO:
+                WOLFSSL_MSG("Secure Renegotiation extension to write");
+                offset += SCR_WRITE((SecureRenegotiation*)extension->data,
+                        output + offset, isRequest);
+                break;
+
+            case TLSX_SESSION_TICKET:
+                WOLFSSL_MSG("Session Ticket extension to write");
+                offset += WOLF_STK_WRITE((SessionTicket*)extension->data,
+                        output + offset, isRequest);
+                break;
+
+            case TLSX_QUANTUM_SAFE_HYBRID:
+                WOLFSSL_MSG("Quantum-Safe-Hybrid extension to write");
+                if (isRequest) {
+                    offset += QSH_WRITE((QSHScheme*)extension->data, output + offset);
+                }
+                offset += QSHPK_WRITE((QSHScheme*)extension->data, output + offset);
+                offset += QSH_SERREQ(output + offset, isRequest);
+                break;
+
+            case TLSX_APPLICATION_LAYER_PROTOCOL:
+                WOLFSSL_MSG("ALPN extension to write");
+                offset += ALPN_WRITE((ALPN*)extension->data, output + offset);
+                break;
+#if !defined(WOLFSSL_NO_SIGALG)
+            case TLSX_SIGNATURE_ALGORITHMS:
+                WOLFSSL_MSG("Signature Algorithms extension to write");
+                offset += SA_WRITE(extension->data, output + offset);
+                break;
+#endif
+#if defined(HAVE_ENCRYPT_THEN_MAC) && !defined(WOLFSSL_AEAD_ONLY)
+            case TLSX_ENCRYPT_THEN_MAC:
+                WOLFSSL_MSG("Encrypt-Then-Mac extension to write");
+                ret = ETM_WRITE(extension->data, output, msgType, &offset);
+                break;
+#endif /* HAVE_ENCRYPT_THEN_MAC */
+#ifdef WOLFSSL_TLS13
+            case TLSX_SUPPORTED_VERSIONS:
+                WOLFSSL_MSG("Supported Versions extension to write");
+                ret = SV_WRITE(extension->data, output + offset, msgType, &offset);
+                break;
+
+            case TLSX_COOKIE:
+                WOLFSSL_MSG("Cookie extension to write");
+                ret = CKE_WRITE((Cookie*)extension->data, output + offset,
+                                msgType, &offset);
+                break;
+
+    #if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
+            case TLSX_PRE_SHARED_KEY:
+                WOLFSSL_MSG("Pre-Shared Key extension to write");
+                ret = PSK_WRITE((PreSharedKey*)extension->data, output + offset,
+                                                              msgType, &offset);
+                break;
+
+            case TLSX_PSK_KEY_EXCHANGE_MODES:
+                WOLFSSL_MSG("PSK Key Exchange Modes extension to write");
+                ret = PKM_WRITE(extension->val, output + offset, msgType,
+                                                                       &offset);
+                break;
+    #endif
+
+    #ifdef WOLFSSL_EARLY_DATA
+            case TLSX_EARLY_DATA:
+                WOLFSSL_MSG("Early Data extension to write");
+                ret = EDI_WRITE(extension->val, output + offset, msgType,
+                                                                       &offset);
+                break;
+    #endif
+
+    #ifdef WOLFSSL_POST_HANDSHAKE_AUTH
+            case TLSX_POST_HANDSHAKE_AUTH:
+                WOLFSSL_MSG("Post-Handshake Authentication extension to write");
+                ret = PHA_WRITE(output + offset, msgType, &offset);
+                break;
+    #endif
+
+    #if !defined(WOLFSSL_TLS13_DRAFT_18) && !defined(WOLFSSL_TLS13_DRAFT_22)
+            case TLSX_SIGNATURE_ALGORITHMS_CERT:
+                WOLFSSL_MSG("Signature Algorithms extension to write");
+                offset += SAC_WRITE(extension->data, output + offset);
+                break;
+    #endif
+
+            case TLSX_KEY_SHARE:
+                WOLFSSL_MSG("Key Share extension to write");
+                offset += KS_WRITE((KeyShareEntry*)extension->data,
+                                                      output + offset, msgType);
+                break;
+#endif
+        }
+
+        /* writes extension data length. */
+        c16toa(offset - length_offset, output + length_offset - OPAQUE16_LEN);
+
+        /* marks the extension as processed so ctx level */
+        /* extensions don't overlap with ssl level ones. */
+        TURN_ON(semaphore, TLSX_ToSemaphore(extension->type));
+    }
+
+    *pOffset += offset;
+
+    return ret;
+}
+
+
+#if defined(HAVE_NTRU) && defined(HAVE_QSH)
+
+static word32 GetEntropy(unsigned char* out, word32 num_bytes)
+{
+    int ret = 0;
+
+    if (gRng == NULL) {
+        if ((gRng = (WC_RNG*)XMALLOC(sizeof(WC_RNG), NULL,
+                                                    DYNAMIC_TYPE_TLSX)) == NULL)
+            return DRBG_OUT_OF_MEMORY;
+        wc_InitRng(gRng);
+    }
+
+    if (gRngMutex == NULL) {
+        if ((gRngMutex = (wolfSSL_Mutex*)XMALLOC(sizeof(wolfSSL_Mutex), NULL,
+                                                    DYNAMIC_TYPE_TLSX)) == NULL)
+            return DRBG_OUT_OF_MEMORY;
+        wc_InitMutex(gRngMutex);
+    }
+
+    ret |= wc_LockMutex(gRngMutex);
+    ret |= wc_RNG_GenerateBlock(gRng, out, num_bytes);
+    ret |= wc_UnLockMutex(gRngMutex);
+
+    if (ret != 0)
+        return DRBG_ENTROPY_FAIL;
+
+    return DRBG_OK;
+}
+#endif
+
+
+#ifdef HAVE_QSH
+static int TLSX_CreateQSHKey(WOLFSSL* ssl, int type)
+{
+    int ret = -1;
+
+    (void)ssl;
+
+    switch (type) {
+#ifdef HAVE_NTRU
+        case WOLFSSL_NTRU_EESS439:
+        case WOLFSSL_NTRU_EESS593:
+        case WOLFSSL_NTRU_EESS743:
+            ret = TLSX_CreateNtruKey(ssl, type);
+            break;
+#endif
+        default:
+            WOLFSSL_MSG("Unknown type for creating NTRU key");
+            break;
+    }
+
+    return ret;
+}
+
+
+static int TLSX_AddQSHKey(QSHKey** list, QSHKey* key)
+{
+    QSHKey* current;
+
+    if (key == NULL)
+        return BAD_FUNC_ARG;
+
+    /* if no public key stored in key then do not add */
+    if (key->pub.length == 0 || key->pub.buffer == NULL)
+        return 0;
+
+    /* first element to be added to the list */
+    current = *list;
+    if (current == NULL) {
+        *list = key;
+        return 0;
+    }
+
+    while (current->next) {
+        /* can only have one of the key in the list */
+        if (current->name == key->name)
+            return -1;
+        current = (QSHKey*)current->next;
+    }
+
+    current->next = (struct QSHKey*)key;
+
+    return 0;
+}
+
+
+#if defined(HAVE_NTRU)
+int TLSX_CreateNtruKey(WOLFSSL* ssl, int type)
+{
+    int ret = -1;
+    int ntruType;
+
+    /* variable declarations for NTRU*/
+    QSHKey* temp = NULL;
+    byte   public_key[1027];
+    word16 public_key_len = sizeof(public_key);
+    byte   private_key[1120];
+    word16 private_key_len = sizeof(private_key);
+    DRBG_HANDLE drbg;
+
+    if (ssl == NULL)
+        return BAD_FUNC_ARG;
+
+    switch (type) {
+        case WOLFSSL_NTRU_EESS439:
+            ntruType = NTRU_EES439EP1;
+            break;
+        case WOLFSSL_NTRU_EESS593:
+            ntruType = NTRU_EES593EP1;
+            break;
+        case WOLFSSL_NTRU_EESS743:
+            ntruType = NTRU_EES743EP1;
+            break;
+        default:
+            WOLFSSL_MSG("Unknown type for creating NTRU key");
+            return -1;
+    }
+    ret = ntru_crypto_drbg_external_instantiate(GetEntropy, &drbg);
+    if (ret != DRBG_OK) {
+        WOLFSSL_MSG("NTRU drbg instantiate failed\n");
+        return ret;
+    }
+
+    if ((ret = ntru_crypto_ntru_encrypt_keygen(drbg, ntruType,
+                     &public_key_len, NULL, &private_key_len, NULL)) != NTRU_OK)
+        return ret;
+
+    if ((ret = ntru_crypto_ntru_encrypt_keygen(drbg, ntruType,
+        &public_key_len, public_key, &private_key_len, private_key)) != NTRU_OK)
+        return ret;
+
+    ret = ntru_crypto_drbg_uninstantiate(drbg);
+    if (ret != NTRU_OK) {
+        WOLFSSL_MSG("NTRU drbg uninstantiate failed\n");
+        return ret;
+    }
+
+    if ((temp = (QSHKey*)XMALLOC(sizeof(QSHKey), ssl->heap,
+                                                    DYNAMIC_TYPE_TLSX)) == NULL)
+        return MEMORY_E;
+    temp->name = type;
+    temp->pub.length = public_key_len;
+    temp->pub.buffer = (byte*)XMALLOC(public_key_len, ssl->heap,
+                                DYNAMIC_TYPE_PUBLIC_KEY);
+    XMEMCPY(temp->pub.buffer, public_key, public_key_len);
+    temp->pri.length = private_key_len;
+    temp->pri.buffer = (byte*)XMALLOC(private_key_len, ssl->heap,
+                                DYNAMIC_TYPE_ARRAYS);
+    XMEMCPY(temp->pri.buffer, private_key, private_key_len);
+    temp->next = NULL;
+
+    TLSX_AddQSHKey(&ssl->QSH_Key, temp);
+
+    (void)ssl;
+    (void)type;
+
+    return ret;
+}
+#endif
+
+
+/*
+    Used to find a public key from the list of keys
+    pubLen length of array
+    name   input the name of the scheme looking for ie WOLFSSL_NTRU_ESSXXX
+
+    returns a pointer to public key byte* or NULL if not found
+ */
+static byte* TLSX_QSHKeyFind_Pub(QSHKey* qsh, word16* pubLen, word16 name)
+{
+    QSHKey* current = qsh;
+
+    if (qsh == NULL || pubLen == NULL)
+        return NULL;
+
+    *pubLen = 0;
+
+    while(current) {
+        if (current->name == name) {
+            *pubLen = current->pub.length;
+            return current->pub.buffer;
+        }
+        current = (QSHKey*)current->next;
+    }
+
+    return NULL;
+}
+#endif /* HAVE_QSH */
+
+#if (!defined(NO_WOLFSSL_SERVER) && defined(WOLFSSL_TLS13) && \
+        !defined(WOLFSSL_NO_SERVER_GROUPS_EXT)) || \
+    (defined(WOLFSSL_TLS13) && !defined(HAVE_ECC) && !defined(HAVE_CURVE25519) \
+        && !defined(HAVE_CURVE448) && defined(HAVE_SUPPORTED_CURVES)) || \
+    ((defined(HAVE_ECC) || defined(HAVE_CURVE25519) || \
+        defined(HAVE_CURVE448)) && defined(HAVE_SUPPORTED_CURVES))
+
+/* Populates the default supported groups / curves */
+static int TLSX_PopulateSupportedGroups(WOLFSSL* ssl, TLSX** extensions)
+{
+    int ret = WOLFSSL_SUCCESS;
+#ifdef WOLFSSL_TLS13
+    int i;
+
+#if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
+    if (ssl->options.resuming && ssl->session.namedGroup != 0) {
+        return TLSX_UseSupportedCurve(extensions, ssl->session.namedGroup,
+                                                                     ssl->heap);
+    }
+#endif
+
+    if (ssl->numGroups != 0) {
+        for (i = 0; i < ssl->numGroups; i++) {
+            ret = TLSX_UseSupportedCurve(extensions, ssl->group[i], ssl->heap);
+            if (ret != WOLFSSL_SUCCESS)
+                return ret;
+        }
+        return WOLFSSL_SUCCESS;
+    }
+#endif /* WOLFSSL_TLS13 */
+
+#if defined(HAVE_ECC) && defined(HAVE_SUPPORTED_CURVES)
+        /* list in order by strength, since not all servers choose by strength */
+        #if defined(HAVE_ECC521) || defined(HAVE_ALL_CURVES)
+            #ifndef NO_ECC_SECP
+                ret = TLSX_UseSupportedCurve(extensions,
+                                              WOLFSSL_ECC_SECP521R1, ssl->heap);
+                if (ret != WOLFSSL_SUCCESS) return ret;
+            #endif
+        #endif
+        #if defined(HAVE_ECC512) || defined(HAVE_ALL_CURVES)
+            #ifdef HAVE_ECC_BRAINPOOL
+                ret = TLSX_UseSupportedCurve(extensions,
+                                        WOLFSSL_ECC_BRAINPOOLP512R1, ssl->heap);
+                if (ret != WOLFSSL_SUCCESS) return ret;
+            #endif
+        #endif
+        #if defined(HAVE_ECC384) || defined(HAVE_ALL_CURVES)
+            #ifndef NO_ECC_SECP
+                ret = TLSX_UseSupportedCurve(extensions,
+                                              WOLFSSL_ECC_SECP384R1, ssl->heap);
+                if (ret != WOLFSSL_SUCCESS) return ret;
+            #endif
+            #ifdef HAVE_ECC_BRAINPOOL
+                ret = TLSX_UseSupportedCurve(extensions,
+                                        WOLFSSL_ECC_BRAINPOOLP384R1, ssl->heap);
+                if (ret != WOLFSSL_SUCCESS) return ret;
+            #endif
+        #endif
+#endif /* HAVE_ECC && HAVE_SUPPORTED_CURVES */
+
+        #ifndef HAVE_FIPS
+            #if defined(HAVE_CURVE448)
+                ret = TLSX_UseSupportedCurve(extensions,
+                                                   WOLFSSL_ECC_X448, ssl->heap);
+                if (ret != WOLFSSL_SUCCESS) return ret;
+            #endif
+        #endif /* HAVE_FIPS */
+
+#if defined(HAVE_ECC) && defined(HAVE_SUPPORTED_CURVES)
+        #if !defined(NO_ECC256)  || defined(HAVE_ALL_CURVES)
+            #ifndef NO_ECC_SECP
+                ret = TLSX_UseSupportedCurve(extensions,
+                                              WOLFSSL_ECC_SECP256R1, ssl->heap);
+                if (ret != WOLFSSL_SUCCESS) return ret;
+            #endif
+            #ifdef HAVE_ECC_KOBLITZ
+                ret = TLSX_UseSupportedCurve(extensions,
+                                              WOLFSSL_ECC_SECP256K1, ssl->heap);
+                if (ret != WOLFSSL_SUCCESS) return ret;
+            #endif
+            #ifdef HAVE_ECC_BRAINPOOL
+                ret = TLSX_UseSupportedCurve(extensions,
+                                        WOLFSSL_ECC_BRAINPOOLP256R1, ssl->heap);
+                if (ret != WOLFSSL_SUCCESS) return ret;
+            #endif
+        #endif
+#endif /* HAVE_ECC && HAVE_SUPPORTED_CURVES */
+
+        #ifndef HAVE_FIPS
+            #if defined(HAVE_CURVE25519)
+                ret = TLSX_UseSupportedCurve(extensions,
+                                                 WOLFSSL_ECC_X25519, ssl->heap);
+                if (ret != WOLFSSL_SUCCESS) return ret;
+            #endif
+        #endif /* HAVE_FIPS */
+
+#if defined(HAVE_ECC) && defined(HAVE_SUPPORTED_CURVES)
+        #if defined(HAVE_ECC224) || defined(HAVE_ALL_CURVES)
+            #ifndef NO_ECC_SECP
+                ret = TLSX_UseSupportedCurve(extensions,
+                                              WOLFSSL_ECC_SECP224R1, ssl->heap);
+                if (ret != WOLFSSL_SUCCESS) return ret;
+            #endif
+            #ifdef HAVE_ECC_KOBLITZ
+                ret = TLSX_UseSupportedCurve(extensions,
+                                              WOLFSSL_ECC_SECP224K1, ssl->heap);
+                if (ret != WOLFSSL_SUCCESS) return ret;
+            #endif
+        #endif
+
+    #ifndef HAVE_FIPS
+        #if defined(HAVE_ECC192) || defined(HAVE_ALL_CURVES)
+            #ifndef NO_ECC_SECP
+                ret = TLSX_UseSupportedCurve(extensions,
+                                              WOLFSSL_ECC_SECP192R1, ssl->heap);
+                if (ret != WOLFSSL_SUCCESS) return ret;
+            #endif
+            #ifdef HAVE_ECC_KOBLITZ
+                ret = TLSX_UseSupportedCurve(extensions,
+                                              WOLFSSL_ECC_SECP192K1, ssl->heap);
+                if (ret != WOLFSSL_SUCCESS) return ret;
+            #endif
+        #endif
+        #if defined(HAVE_ECC160) || defined(HAVE_ALL_CURVES)
+            #ifndef NO_ECC_SECP
+                ret = TLSX_UseSupportedCurve(extensions,
+                                              WOLFSSL_ECC_SECP160R1, ssl->heap);
+                if (ret != WOLFSSL_SUCCESS) return ret;
+            #endif
+            #ifdef HAVE_ECC_SECPR2
+                ret = TLSX_UseSupportedCurve(extensions,
+                                              WOLFSSL_ECC_SECP160R2, ssl->heap);
+                if (ret != WOLFSSL_SUCCESS) return ret;
+            #endif
+            #ifdef HAVE_ECC_KOBLITZ
+                ret = TLSX_UseSupportedCurve(extensions,
+                                              WOLFSSL_ECC_SECP160K1, ssl->heap);
+                if (ret != WOLFSSL_SUCCESS) return ret;
+            #endif
+        #endif
+    #endif /* HAVE_FIPS */
+#endif /* HAVE_ECC && HAVE_SUPPORTED_CURVES */
+
+                /* Add FFDHE supported groups. */
+        #ifdef HAVE_FFDHE_8192
+            if (8192/8 >= ssl->options.minDhKeySz &&
+                                            8192/8 <= ssl->options.maxDhKeySz) {
+                ret = TLSX_UseSupportedCurve(extensions,
+                                             WOLFSSL_FFDHE_8192, ssl->heap);
+                if (ret != WOLFSSL_SUCCESS)
+                    return ret;
+            }
+        #endif
+        #ifdef HAVE_FFDHE_6144
+            if (6144/8 >= ssl->options.minDhKeySz &&
+                                            6144/8 <= ssl->options.maxDhKeySz) {
+                ret = TLSX_UseSupportedCurve(extensions,
+                                             WOLFSSL_FFDHE_6144, ssl->heap);
+                if (ret != WOLFSSL_SUCCESS)
+                    return ret;
+            }
+        #endif
+        #ifdef HAVE_FFDHE_4096
+            if (4096/8 >= ssl->options.minDhKeySz &&
+                                            4096/8 <= ssl->options.maxDhKeySz) {
+                ret = TLSX_UseSupportedCurve(extensions,
+                                             WOLFSSL_FFDHE_4096, ssl->heap);
+                if (ret != WOLFSSL_SUCCESS)
+                    return ret;
+            }
+        #endif
+        #ifdef HAVE_FFDHE_3072
+            if (3072/8 >= ssl->options.minDhKeySz &&
+                                            3072/8 <= ssl->options.maxDhKeySz) {
+                ret = TLSX_UseSupportedCurve(extensions,
+                                             WOLFSSL_FFDHE_3072, ssl->heap);
+                if (ret != WOLFSSL_SUCCESS)
+                    return ret;
+            }
+        #endif
+        #ifdef HAVE_FFDHE_2048
+            if (2048/8 >= ssl->options.minDhKeySz &&
+                                            2048/8 <= ssl->options.maxDhKeySz) {
+                ret = TLSX_UseSupportedCurve(extensions,
+                                             WOLFSSL_FFDHE_2048, ssl->heap);
+                if (ret != WOLFSSL_SUCCESS)
+                    return ret;
+            }
+        #endif
+
+    (void)ssl;
+    (void)extensions;
+
+    return ret;
+}
+
+#endif
+
+int TLSX_PopulateExtensions(WOLFSSL* ssl, byte isServer)
+{
+    int ret = 0;
+    byte* public_key      = NULL;
+    word16 public_key_len = 0;
+#if defined(WOLFSSL_TLS13) && (defined(HAVE_SESSION_TICKET) || !defined(NO_PSK))
+    int usingPSK = 0;
+#endif
+#ifdef HAVE_QSH
+    TLSX* extension;
+    QSHScheme* qsh;
+    QSHScheme* next;
+
+    /* add supported QSHSchemes */
+    WOLFSSL_MSG("Adding supported QSH Schemes");
+#endif
+
+    /* server will add extension depending on what is parsed from client */
+    if (!isServer) {
+#ifdef HAVE_QSH
+        /* test if user has set a specific scheme already */
+        if (!ssl->user_set_QSHSchemes) {
+            if (ssl->sendQSHKeys && ssl->QSH_Key == NULL) {
+                if ((ret = TLSX_CreateQSHKey(ssl, WOLFSSL_NTRU_EESS743)) != 0) {
+                    WOLFSSL_MSG("Error creating ntru keys");
+                    return ret;
+                }
+                if ((ret = TLSX_CreateQSHKey(ssl, WOLFSSL_NTRU_EESS593)) != 0) {
+                    WOLFSSL_MSG("Error creating ntru keys");
+                    return ret;
+                }
+                if ((ret = TLSX_CreateQSHKey(ssl, WOLFSSL_NTRU_EESS439)) != 0) {
+                    WOLFSSL_MSG("Error creating ntru keys");
+                    return ret;
+                }
+
+            /* add NTRU 256 */
+            public_key = TLSX_QSHKeyFind_Pub(ssl->QSH_Key,
+                    &public_key_len, WOLFSSL_NTRU_EESS743);
+            }
+            if (TLSX_UseQSHScheme(&ssl->extensions, WOLFSSL_NTRU_EESS743,
+                                  public_key, public_key_len, ssl->heap)
+                                  != WOLFSSL_SUCCESS)
+                ret = -1;
+
+            /* add NTRU 196 */
+            if (ssl->sendQSHKeys) {
+                public_key = TLSX_QSHKeyFind_Pub(ssl->QSH_Key,
+                    &public_key_len, WOLFSSL_NTRU_EESS593);
+            }
+            if (TLSX_UseQSHScheme(&ssl->extensions, WOLFSSL_NTRU_EESS593,
+                                  public_key, public_key_len, ssl->heap)
+                                  != WOLFSSL_SUCCESS)
+                ret = -1;
+
+            /* add NTRU 128 */
+            if (ssl->sendQSHKeys) {
+                public_key = TLSX_QSHKeyFind_Pub(ssl->QSH_Key,
+                    &public_key_len, WOLFSSL_NTRU_EESS439);
+            }
+            if (TLSX_UseQSHScheme(&ssl->extensions, WOLFSSL_NTRU_EESS439,
+                                  public_key, public_key_len, ssl->heap)
+                                  != WOLFSSL_SUCCESS)
+                ret = -1;
+        }
+        else if (ssl->sendQSHKeys && ssl->QSH_Key == NULL) {
+            /* for each scheme make a client key */
+            extension = TLSX_Find(ssl->extensions, TLSX_QUANTUM_SAFE_HYBRID);
+            if (extension) {
+                qsh = (QSHScheme*)extension->data;
+
+                while (qsh) {
+                    if ((ret = TLSX_CreateQSHKey(ssl, qsh->name)) != 0)
+                        return ret;
+
+                    /* get next now because qsh could be freed */
+                    next = qsh->next;
+
+                    /* find the public key created and add to extension*/
+                    public_key = TLSX_QSHKeyFind_Pub(ssl->QSH_Key,
+                             &public_key_len, qsh->name);
+                    if (TLSX_UseQSHScheme(&ssl->extensions, qsh->name,
+                                          public_key, public_key_len,
+                                          ssl->heap) != WOLFSSL_SUCCESS)
+                        ret = -1;
+                    qsh = next;
+                }
+            }
+        }
+#endif
+
+#if defined(HAVE_ENCRYPT_THEN_MAC) && !defined(WOLFSSL_AEAD_ONLY)
+        if (!ssl->options.disallowEncThenMac) {
+            ret = TLSX_EncryptThenMac_Use(ssl);
+            if (ret != 0)
+                return ret;
+        }
+#endif
+
+#if (defined(HAVE_ECC) || defined(HAVE_CURVE25519) || \
+                       defined(HAVE_CURVE448)) && defined(HAVE_SUPPORTED_CURVES)
+        if (!ssl->options.userCurves && !ssl->ctx->userCurves) {
+            if (TLSX_Find(ssl->ctx->extensions,
+                                               TLSX_SUPPORTED_GROUPS) == NULL) {
+                ret = TLSX_PopulateSupportedGroups(ssl, &ssl->extensions);
+                if (ret != WOLFSSL_SUCCESS)
+                    return ret;
+            }
+        }
+        if ((!IsAtLeastTLSv1_3(ssl->version) || ssl->options.downgrade) &&
+               TLSX_Find(ssl->ctx->extensions, TLSX_EC_POINT_FORMATS) == NULL &&
+               TLSX_Find(ssl->extensions, TLSX_EC_POINT_FORMATS) == NULL) {
+             ret = TLSX_UsePointFormat(&ssl->extensions,
+                                         WOLFSSL_EC_PF_UNCOMPRESSED, ssl->heap);
+             if (ret != WOLFSSL_SUCCESS)
+                 return ret;
+        }
+#endif /* (HAVE_ECC || CURVE25519 || CURVE448) && HAVE_SUPPORTED_CURVES */
+    } /* is not server */
+
+#if !defined(WOLFSSL_NO_SIGALG)
+    WOLFSSL_MSG("Adding signature algorithms extension");
+    if ((ret = TLSX_SetSignatureAlgorithms(&ssl->extensions, ssl, ssl->heap))
+                                                                         != 0) {
+            return ret;
+    }
+#else
+    ret = 0;
+#endif
+    #ifdef WOLFSSL_TLS13
+        if (!isServer && IsAtLeastTLSv1_3(ssl->version)) {
+            /* Add mandatory TLS v1.3 extension: supported version */
+            WOLFSSL_MSG("Adding supported versions extension");
+            if ((ret = TLSX_SetSupportedVersions(&ssl->extensions, ssl,
+                                                             ssl->heap)) != 0) {
+                return ret;
+            }
+
+    #if !defined(HAVE_ECC) && !defined(HAVE_CURVE25519) && \
+                       !defined(HAVE_CURVE448) && defined(HAVE_SUPPORTED_CURVES)
+        if (TLSX_Find(ssl->ctx->extensions, TLSX_SUPPORTED_GROUPS) == NULL) {
+            /* Put in DH groups for TLS 1.3 only. */
+            ret = TLSX_PopulateSupportedGroups(ssl, &ssl->extensions);
+            if (ret != WOLFSSL_SUCCESS)
+                return ret;
+            ret = 0;
+        }
+    #endif /* (HAVE_ECC || CURVE25519 || CURVE448) && HAVE_SUPPORTED_CURVES */
+
+        #if !defined(WOLFSSL_TLS13_DRAFT_18) && !defined(WOLFSSL_TLS13_DRAFT_22)
+            if (ssl->certHashSigAlgoSz > 0) {
+                WOLFSSL_MSG("Adding signature algorithms cert extension");
+                if ((ret = TLSX_SetSignatureAlgorithmsCert(&ssl->extensions,
+                                                        ssl, ssl->heap)) != 0) {
+                    return ret;
+                }
+            }
+        #endif /* !WOLFSSL_TLS13_DRAFT_18 && !WOLFSSL_TLS13_DRAFT_22 */
+
+            if (TLSX_Find(ssl->extensions, TLSX_KEY_SHARE) == NULL) {
+                word16 namedGroup;
+
+        #if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
+                if (ssl->options.resuming && ssl->session.namedGroup != 0)
+                    namedGroup = ssl->session.namedGroup;
+                else
+        #endif
+                {
+        #if defined(HAVE_ECC) && (!defined(NO_ECC256) || \
+                              defined(HAVE_ALL_CURVES)) && !defined(NO_ECC_SECP)
+                    namedGroup = WOLFSSL_ECC_SECP256R1;
+        #elif defined(HAVE_CURVE25519)
+                    namedGroup = WOLFSSL_ECC_X25519;
+        #elif defined(HAVE_CURVE448)
+                    namedGroup = WOLFSSL_ECC_X448;
+        #elif defined(HAVE_ECC) && (!defined(NO_ECC384) || \
+                              defined(HAVE_ALL_CURVES)) && !defined(NO_ECC_SECP)
+                    namedGroup = WOLFSSL_ECC_SECP384R1;
+        #elif defined(HAVE_ECC) && (!defined(NO_ECC521) || \
+                              defined(HAVE_ALL_CURVES)) && !defined(NO_ECC_SECP)
+                    namedGroup = WOLFSSL_ECC_SECP521R1;
+        #elif defined(HAVE_FFDHE_2048)
+                    namedGroup = WOLFSSL_FFDHE_2048;
+        #elif defined(HAVE_FFDHE_3072)
+                    namedGroup = WOLFSSL_FFDHE_3072;
+        #elif defined(HAVE_FFDHE_4096)
+                    namedGroup = WOLFSSL_FFDHE_4096;
+        #elif defined(HAVE_FFDHE_6144)
+                    namedGroup = WOLFSSL_FFDHE_6144;
+        #elif defined(HAVE_FFDHE_8192)
+                    namedGroup = WOLFSSL_FFDHE_8192;
+        #else
+                    return KEY_SHARE_ERROR;
+        #endif
+                }
+                ret = TLSX_KeyShare_Use(ssl, namedGroup, 0, NULL, NULL);
+                if (ret != 0)
+                    return ret;
+            }
+
+        #if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
+            TLSX_Remove(&ssl->extensions, TLSX_PRE_SHARED_KEY, ssl->heap);
+        #endif
+        #if defined(HAVE_SESSION_TICKET)
+            if (ssl->options.resuming && ssl->session.ticketLen > 0) {
+                WOLFSSL_SESSION* sess = &ssl->session;
+                word32           milli;
+
+                if (sess->ticketLen > MAX_PSK_ID_LEN) {
+                    WOLFSSL_MSG("Session ticket length for PSK ext is too large");
+                    return BUFFER_ERROR;
+                }
+
+                /* Determine the MAC algorithm for the cipher suite used. */
+                ssl->options.cipherSuite0 = sess->cipherSuite0;
+                ssl->options.cipherSuite  = sess->cipherSuite;
+                ret = SetCipherSpecs(ssl);
+                if (ret != 0)
+                    return ret;
+                milli = TimeNowInMilliseconds() - sess->ticketSeen +
+                        sess->ticketAdd;
+                /* Pre-shared key is mandatory extension for resumption. */
+                ret = TLSX_PreSharedKey_Use(ssl, sess->ticket, sess->ticketLen,
+                                            milli, ssl->specs.mac_algorithm,
+                                            ssl->options.cipherSuite0,
+                                            ssl->options.cipherSuite, 1,
+                                            NULL);
+                if (ret != 0)
+                    return ret;
+
+                usingPSK = 1;
+            }
+        #endif
+        #ifndef NO_PSK
+            if (ssl->options.client_psk_cb != NULL ||
+                                     ssl->options.client_psk_tls13_cb != NULL) {
+                /* Default ciphersuite. */
+                byte cipherSuite0 = TLS13_BYTE;
+                byte cipherSuite = WOLFSSL_DEF_PSK_CIPHER;
+                const char* cipherName = NULL;
+
+                if (ssl->options.client_psk_tls13_cb != NULL) {
+                    ssl->arrays->psk_keySz = ssl->options.client_psk_tls13_cb(
+                        ssl, ssl->arrays->server_hint,
+                        ssl->arrays->client_identity, MAX_PSK_ID_LEN,
+                        ssl->arrays->psk_key, MAX_PSK_KEY_LEN, &cipherName);
+                    if (GetCipherSuiteFromName(cipherName, &cipherSuite0,
+                                                           &cipherSuite) != 0) {
+                        return PSK_KEY_ERROR;
+                    }
+                }
+                else {
+                    ssl->arrays->psk_keySz = ssl->options.client_psk_cb(ssl,
+                        ssl->arrays->server_hint, ssl->arrays->client_identity,
+                        MAX_PSK_ID_LEN, ssl->arrays->psk_key, MAX_PSK_KEY_LEN);
+                }
+                if (ssl->arrays->psk_keySz == 0 ||
+                                     ssl->arrays->psk_keySz > MAX_PSK_KEY_LEN) {
+                    return PSK_KEY_ERROR;
+                }
+                ssl->arrays->client_identity[MAX_PSK_ID_LEN] = '\0';
+                /* TODO: Callback should be able to change ciphersuite. */
+                ssl->options.cipherSuite0 = cipherSuite0;
+                ssl->options.cipherSuite  = cipherSuite;
+                ret = SetCipherSpecs(ssl);
+                if (ret != 0)
+                    return ret;
+
+                ret = TLSX_PreSharedKey_Use(ssl,
+                                  (byte*)ssl->arrays->client_identity,
+                                  (word16)XSTRLEN(ssl->arrays->client_identity),
+                                  0, ssl->specs.mac_algorithm,
+                                  cipherSuite0, cipherSuite, 0,
+                                  NULL);
+                if (ret != 0)
+                    return ret;
+
+                usingPSK = 1;
+            }
+        #endif
+        #if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
+            if (usingPSK) {
+                byte modes;
+
+                /* Pre-shared key modes: mandatory extension for resumption. */
+                modes = 1 << PSK_KE;
+            #if !defined(NO_DH) || defined(HAVE_ECC) || \
+                              defined(HAVE_CURVE25519) || defined(HAVE_CURVE448)
+                if (!ssl->options.noPskDheKe)
+                    modes |= 1 << PSK_DHE_KE;
+            #endif
+                ret = TLSX_PskKeModes_Use(ssl, modes);
+                if (ret != 0)
+                    return ret;
+            }
+        #endif
+        #if defined(WOLFSSL_POST_HANDSHAKE_AUTH)
+            if (!isServer && ssl->options.postHandshakeAuth) {
+                ret = TLSX_PostHandAuth_Use(ssl);
+                if (ret != 0)
+                    return ret;
+            }
+        #endif
+        }
+
+    #endif
+
+    (void)isServer;
+    (void)public_key;
+    (void)public_key_len;
+    (void)ssl;
+
+    return ret;
+}
+
+
+#if defined(WOLFSSL_TLS13) || !defined(NO_WOLFSSL_CLIENT)
+
+/** Tells the buffered size of extensions to be sent into the client hello. */
+int TLSX_GetRequestSize(WOLFSSL* ssl, byte msgType, word16* pLength)
+{
+    int ret = 0;
+    word16 length = 0;
+    byte semaphore[SEMAPHORE_SIZE] = {0};
+
+    if (!TLSX_SupportExtensions(ssl))
+        return 0;
+    if (msgType == client_hello) {
+        EC_VALIDATE_REQUEST(ssl, semaphore);
+        PF_VALIDATE_REQUEST(ssl, semaphore);
+        QSH_VALIDATE_REQUEST(ssl, semaphore);
+        WOLF_STK_VALIDATE_REQUEST(ssl);
+#if !defined(WOLFSSL_NO_SIGALG)
+        if (ssl->suites->hashSigAlgoSz == 0)
+            TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_SIGNATURE_ALGORITHMS));
+#endif
+#if defined(WOLFSSL_TLS13)
+        if (!IsAtLeastTLSv1_2(ssl))
+            TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_SUPPORTED_VERSIONS));
+        if (!IsAtLeastTLSv1_3(ssl->version)) {
+            TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_KEY_SHARE));
+    #if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
+            TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_PRE_SHARED_KEY));
+            TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_PSK_KEY_EXCHANGE_MODES));
+    #endif
+    #ifdef WOLFSSL_EARLY_DATA
+            TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_EARLY_DATA));
+    #endif
+            TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_COOKIE));
+    #ifdef WOLFSSL_POST_HANDSHAKE_AUTH
+            TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_POST_HANDSHAKE_AUTH));
+    #endif
+        }
+#endif
+    #if defined(HAVE_CERTIFICATE_STATUS_REQUEST) \
+     || defined(HAVE_CERTIFICATE_STATUS_REQUEST_V2)
+        if (!ssl->ctx->cm->ocspStaplingEnabled) {
+            /* mark already sent, so it won't send it */
+            TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_STATUS_REQUEST));
+            TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_STATUS_REQUEST_V2));
+        }
+    #endif
+    }
+
+#ifdef WOLFSSL_TLS13
+    #ifndef NO_CERTS
+    else if (msgType == certificate_request) {
+        XMEMSET(semaphore, 0xff, SEMAPHORE_SIZE);
+#if !defined(WOLFSSL_NO_SIGALG)
+        TURN_OFF(semaphore, TLSX_ToSemaphore(TLSX_SIGNATURE_ALGORITHMS));
+#endif
+        /* TODO: TLSX_SIGNED_CERTIFICATE_TIMESTAMP,
+         *       TLSX_CERTIFICATE_AUTHORITIES, OID_FILTERS
+         *       TLSX_STATUS_REQUEST
+         */
+    }
+    #endif
+#endif
+    if (ssl->extensions) {
+        ret = TLSX_GetSize(ssl->extensions, semaphore, msgType, &length);
+        if (ret != 0)
+            return ret;
+    }
+    if (ssl->ctx && ssl->ctx->extensions) {
+        ret = TLSX_GetSize(ssl->ctx->extensions, semaphore, msgType, &length);
+        if (ret != 0)
+            return ret;
+    }
+
+#ifdef HAVE_EXTENDED_MASTER
+    if (msgType == client_hello && ssl->options.haveEMS &&
+                  (!IsAtLeastTLSv1_3(ssl->version) || ssl->options.downgrade)) {
+        length += HELLO_EXT_SZ;
+    }
+#endif
+
+    if (length)
+        length += OPAQUE16_LEN; /* for total length storage. */
+
+    *pLength += length;
+
+    return ret;
+}
+
+/** Writes the extensions to be sent into the client hello. */
+int TLSX_WriteRequest(WOLFSSL* ssl, byte* output, byte msgType, word16* pOffset)
+{
+    int ret = 0;
+    word16 offset = 0;
+    byte semaphore[SEMAPHORE_SIZE] = {0};
+
+    if (!TLSX_SupportExtensions(ssl) || output == NULL)
+        return 0;
+
+    offset += OPAQUE16_LEN; /* extensions length */
+
+    if (msgType == client_hello) {
+        EC_VALIDATE_REQUEST(ssl, semaphore);
+        PF_VALIDATE_REQUEST(ssl, semaphore);
+        WOLF_STK_VALIDATE_REQUEST(ssl);
+        QSH_VALIDATE_REQUEST(ssl, semaphore);
+#if !defined(WOLFSSL_NO_SIGALG)
+        if (ssl->suites->hashSigAlgoSz == 0)
+            TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_SIGNATURE_ALGORITHMS));
+#endif
+#ifdef WOLFSSL_TLS13
+        if (!IsAtLeastTLSv1_2(ssl))
+            TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_SUPPORTED_VERSIONS));
+        if (!IsAtLeastTLSv1_3(ssl->version)) {
+            TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_KEY_SHARE));
+    #if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
+            TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_PSK_KEY_EXCHANGE_MODES));
+    #endif
+    #ifdef WOLFSSL_EARLY_DATA
+            TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_EARLY_DATA));
+    #endif
+            TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_COOKIE));
+    #ifdef WOLFSSL_POST_HANDSHAKE_AUTH
+            TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_POST_HANDSHAKE_AUTH));
+    #endif
+        }
+    #if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
+        /* Must write Pre-shared Key extension at the end in TLS v1.3.
+         * Must not write out Pre-shared Key extension in earlier versions of
+         * protocol.
+         */
+        TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_PRE_SHARED_KEY));
+    #endif
+#endif
+    #if defined(HAVE_CERTIFICATE_STATUS_REQUEST) \
+     || defined(HAVE_CERTIFICATE_STATUS_REQUEST_V2)
+         /* mark already sent, so it won't send it */
+        if (!ssl->ctx->cm->ocspStaplingEnabled) {
+            TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_STATUS_REQUEST));
+            TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_STATUS_REQUEST_V2));
+        }
+    #endif
+    }
+#ifdef WOLFSSL_TLS13
+    #ifndef NO_CERTS
+    else if (msgType == certificate_request) {
+        XMEMSET(semaphore, 0xff, SEMAPHORE_SIZE);
+#if !defined(WOLFSSL_NO_SIGALG)
+        TURN_OFF(semaphore, TLSX_ToSemaphore(TLSX_SIGNATURE_ALGORITHMS));
+#endif
+        /* TODO: TLSX_SIGNED_CERTIFICATE_TIMESTAMP,
+         *       TLSX_CERTIFICATE_AUTHORITIES, TLSX_OID_FILTERS
+         *       TLSX_STATUS_REQUEST
+         */
+    }
+    #endif
+#endif
+    if (ssl->extensions) {
+        ret = TLSX_Write(ssl->extensions, output + offset, semaphore,
+                         msgType, &offset);
+        if (ret != 0)
+            return ret;
+    }
+    if (ssl->ctx && ssl->ctx->extensions) {
+        ret = TLSX_Write(ssl->ctx->extensions, output + offset, semaphore,
+                         msgType, &offset);
+        if (ret != 0)
+            return ret;
+    }
+
+#ifdef HAVE_EXTENDED_MASTER
+    if (msgType == client_hello && ssl->options.haveEMS &&
+                  (!IsAtLeastTLSv1_3(ssl->version) || ssl->options.downgrade)) {
+        WOLFSSL_MSG("EMS extension to write");
+        c16toa(HELLO_EXT_EXTMS, output + offset);
+        offset += HELLO_EXT_TYPE_SZ;
+        c16toa(0, output + offset);
+        offset += HELLO_EXT_SZ_SZ;
+    }
+#endif
+
+#ifdef WOLFSSL_TLS13
+    #if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
+    if (msgType == client_hello && IsAtLeastTLSv1_3(ssl->version)) {
+        /* Write out what we can of Pre-shared key extension.  */
+        TURN_OFF(semaphore, TLSX_ToSemaphore(TLSX_PRE_SHARED_KEY));
+        ret = TLSX_Write(ssl->extensions, output + offset, semaphore,
+                         client_hello, &offset);
+        if (ret != 0)
+            return ret;
+    }
+    #endif
+#endif
+
+    if (offset > OPAQUE16_LEN || msgType != client_hello)
+        c16toa(offset - OPAQUE16_LEN, output); /* extensions length */
+
+     *pOffset += offset;
+
+    return ret;
+}
+
+#endif /* WOLFSSL_TLS13 || !NO_WOLFSSL_CLIENT */
+
+#if defined(WOLFSSL_TLS13) || !defined(NO_WOLFSSL_SERVER)
+
+/** Tells the buffered size of extensions to be sent into the server hello. */
+int TLSX_GetResponseSize(WOLFSSL* ssl, byte msgType, word16* pLength)
+{
+    int ret = 0;
+    word16 length = 0;
+    byte semaphore[SEMAPHORE_SIZE] = {0};
+
+    switch (msgType) {
+#ifndef NO_WOLFSSL_SERVER
+        case server_hello:
+            PF_VALIDATE_RESPONSE(ssl, semaphore);
+    #ifdef WOLFSSL_TLS13
+                if (IsAtLeastTLSv1_3(ssl->version)) {
+                    XMEMSET(semaphore, 0xff, SEMAPHORE_SIZE);
+        #ifndef WOLFSSL_TLS13_DRAFT_18
+                    TURN_OFF(semaphore,
+                                     TLSX_ToSemaphore(TLSX_SUPPORTED_VERSIONS));
+        #endif
+                    if (!ssl->options.noPskDheKe)
+                        TURN_OFF(semaphore, TLSX_ToSemaphore(TLSX_KEY_SHARE));
+        #if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
+                    TURN_OFF(semaphore, TLSX_ToSemaphore(TLSX_PRE_SHARED_KEY));
+        #endif
+                }
+                else {
+                    TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_KEY_SHARE));
+        #if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
+                    TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_PRE_SHARED_KEY));
+        #endif
+                }
+    #endif
+            break;
+
+    #ifdef WOLFSSL_TLS13
+        case hello_retry_request:
+            XMEMSET(semaphore, 0xff, SEMAPHORE_SIZE);
+        #ifndef WOLFSSL_TLS13_DRAFT_18
+                TURN_OFF(semaphore, TLSX_ToSemaphore(TLSX_SUPPORTED_VERSIONS));
+        #endif
+            if (!ssl->options.noPskDheKe)
+                TURN_OFF(semaphore, TLSX_ToSemaphore(TLSX_KEY_SHARE));
+            TURN_OFF(semaphore, TLSX_ToSemaphore(TLSX_COOKIE));
+            break;
+    #endif
+
+    #ifdef WOLFSSL_TLS13
+        case encrypted_extensions:
+            TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_EC_POINT_FORMATS));
+            TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_SUPPORTED_VERSIONS));
+            TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_SESSION_TICKET));
+            TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_KEY_SHARE));
+        #if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
+            TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_PRE_SHARED_KEY));
+        #endif
+        #ifdef HAVE_CERTIFICATE_STATUS_REQUEST
+            TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_STATUS_REQUEST));
+        #endif
+        #if defined(HAVE_SECURE_RENEGOTIATION)
+            TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_RENEGOTIATION_INFO));
+        #endif
+            break;
+
+        #ifdef WOLFSSL_EARLY_DATA
+        case session_ticket:
+            if (ssl->options.tls1_3) {
+                XMEMSET(semaphore, 0xff, SEMAPHORE_SIZE);
+                TURN_OFF(semaphore, TLSX_ToSemaphore(TLSX_EARLY_DATA));
+            }
+            break;
+        #endif
+    #endif
+#endif
+
+#ifdef WOLFSSL_TLS13
+    #ifndef NO_CERTS
+        case certificate:
+            XMEMSET(semaphore, 0xff, SEMAPHORE_SIZE);
+            TURN_OFF(semaphore, TLSX_ToSemaphore(TLSX_STATUS_REQUEST));
+            /* TODO: TLSX_SIGNED_CERTIFICATE_TIMESTAMP,
+             *       TLSX_SERVER_CERTIFICATE_TYPE
+             */
+            break;
+    #endif
+#endif
+    }
+
+    #ifdef HAVE_QSH
+        /* change response if not using TLS_QSH */
+        if (!ssl->options.haveQSH) {
+            TLSX* ext = TLSX_Find(ssl->extensions, TLSX_QUANTUM_SAFE_HYBRID);
+            if (ext)
+                ext->resp = 0;
+        }
+    #endif
+
+#ifdef HAVE_EXTENDED_MASTER
+    if (ssl->options.haveEMS && msgType == server_hello &&
+                                              !IsAtLeastTLSv1_3(ssl->version)) {
+        length += HELLO_EXT_SZ;
+    }
+#endif
+
+    if (TLSX_SupportExtensions(ssl)) {
+        ret = TLSX_GetSize(ssl->extensions, semaphore, msgType, &length);
+        if (ret != 0)
+            return ret;
+    }
+
+    /* All the response data is set at the ssl object only, so no ctx here. */
+
+    if (length || msgType != server_hello)
+        length += OPAQUE16_LEN; /* for total length storage. */
+
+    *pLength += length;
+
+    return ret;
+}
+
+/** Writes the server hello extensions into a buffer. */
+int TLSX_WriteResponse(WOLFSSL *ssl, byte* output, byte msgType, word16* pOffset)
+{
+    int ret = 0;
+    word16 offset = 0;
+
+    if (TLSX_SupportExtensions(ssl) && output) {
+        byte semaphore[SEMAPHORE_SIZE] = {0};
+
+        switch (msgType) {
+#ifndef NO_WOLFSSL_SERVER
+            case server_hello:
+                PF_VALIDATE_RESPONSE(ssl, semaphore);
+    #ifdef WOLFSSL_TLS13
+                if (IsAtLeastTLSv1_3(ssl->version)) {
+                    XMEMSET(semaphore, 0xff, SEMAPHORE_SIZE);
+        #ifndef WOLFSSL_TLS13_DRAFT_18
+                    TURN_OFF(semaphore,
+                                     TLSX_ToSemaphore(TLSX_SUPPORTED_VERSIONS));
+        #endif
+                    if (!ssl->options.noPskDheKe)
+                        TURN_OFF(semaphore, TLSX_ToSemaphore(TLSX_KEY_SHARE));
+        #if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
+                    TURN_OFF(semaphore, TLSX_ToSemaphore(TLSX_PRE_SHARED_KEY));
+        #endif
+                }
+                else {
+                    TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_KEY_SHARE));
+        #if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
+                    TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_PRE_SHARED_KEY));
+        #endif
+                }
+    #endif
+                break;
+
+    #ifdef WOLFSSL_TLS13
+            case hello_retry_request:
+                XMEMSET(semaphore, 0xff, SEMAPHORE_SIZE);
+        #ifndef WOLFSSL_TLS13_DRAFT_18
+                TURN_OFF(semaphore, TLSX_ToSemaphore(TLSX_SUPPORTED_VERSIONS));
+        #endif
+                if (!ssl->options.noPskDheKe)
+                    TURN_OFF(semaphore, TLSX_ToSemaphore(TLSX_KEY_SHARE));
+                /* Cookie is written below as last extension. */
+                break;
+    #endif
+
+    #ifdef WOLFSSL_TLS13
+            case encrypted_extensions:
+                TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_EC_POINT_FORMATS));
+                TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_SUPPORTED_VERSIONS));
+                TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_SESSION_TICKET));
+                TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_KEY_SHARE));
+        #if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
+                TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_PRE_SHARED_KEY));
+        #endif
+        #ifdef HAVE_CERTIFICATE_STATUS_REQUEST
+                TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_STATUS_REQUEST));
+        #endif
+        #if defined(HAVE_SECURE_RENEGOTIATION)
+            TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_RENEGOTIATION_INFO));
+        #endif
+                break;
+
+        #ifdef WOLFSSL_EARLY_DATA
+            case session_ticket:
+                if (ssl->options.tls1_3) {
+                    XMEMSET(semaphore, 0xff, SEMAPHORE_SIZE);
+                    TURN_OFF(semaphore, TLSX_ToSemaphore(TLSX_EARLY_DATA));
+                }
+                break;
+        #endif
+    #endif
+#endif
+
+    #ifdef WOLFSSL_TLS13
+        #ifndef NO_CERTS
+            case certificate:
+                XMEMSET(semaphore, 0xff, SEMAPHORE_SIZE);
+                TURN_OFF(semaphore, TLSX_ToSemaphore(TLSX_STATUS_REQUEST));
+                /* TODO: TLSX_SIGNED_CERTIFICATE_TIMESTAMP,
+                 *       TLSX_SERVER_CERTIFICATE_TYPE
+                 */
+                break;
+        #endif
+    #endif
+        }
+
+        offset += OPAQUE16_LEN; /* extensions length */
+
+        ret = TLSX_Write(ssl->extensions, output + offset, semaphore,
+                         msgType, &offset);
+        if (ret != 0)
+            return ret;
+
+#ifdef WOLFSSL_TLS13
+        if (msgType == hello_retry_request) {
+            XMEMSET(semaphore, 0xff, SEMAPHORE_SIZE);
+            TURN_OFF(semaphore, TLSX_ToSemaphore(TLSX_COOKIE));
+            ret = TLSX_Write(ssl->extensions, output + offset, semaphore,
+                             msgType, &offset);
+            if (ret != 0)
+                return ret;
+        }
+#endif
+
+#ifdef HAVE_EXTENDED_MASTER
+        if (ssl->options.haveEMS && msgType == server_hello &&
+                                              !IsAtLeastTLSv1_3(ssl->version)) {
+            WOLFSSL_MSG("EMS extension to write");
+            c16toa(HELLO_EXT_EXTMS, output + offset);
+            offset += HELLO_EXT_TYPE_SZ;
+            c16toa(0, output + offset);
+            offset += HELLO_EXT_SZ_SZ;
+        }
+#endif
+
+        if (offset > OPAQUE16_LEN || msgType != server_hello)
+            c16toa(offset - OPAQUE16_LEN, output); /* extensions length */
+    }
+
+    if (pOffset)
+        *pOffset += offset;
+
+    return ret;
+}
+
+#endif /* WOLFSSL_TLS13 || !NO_WOLFSSL_SERVER */
+
+#ifdef WOLFSSL_TLS13
+int TLSX_ParseVersion(WOLFSSL* ssl, byte* input, word16 length, byte msgType,
+                      int* found)
+{
+    int ret = 0;
+    int offset = 0;
+
+    *found = 0;
+    while (offset < (int)length) {
+        word16 type;
+        word16 size;
+
+        if (offset + (2 * OPAQUE16_LEN) > length) {
+            ret = BUFFER_ERROR;
+            break;
+        }
+
+        ato16(input + offset, &type);
+        offset += HELLO_EXT_TYPE_SZ;
+
+        ato16(input + offset, &size);
+        offset += OPAQUE16_LEN;
+
+        if (offset + size > length) {
+            ret = BUFFER_ERROR;
+            break;
+        }
+
+        if (type == TLSX_SUPPORTED_VERSIONS) {
+            *found = 1;
+
+            WOLFSSL_MSG("Supported Versions extension received");
+
+            ret = SV_PARSE(ssl, input + offset, size, msgType);
+            break;
+        }
+
+        offset += size;
+    }
+
+    return ret;
+}
+#endif
+
+/** Parses a buffer of TLS extensions. */
+int TLSX_Parse(WOLFSSL* ssl, byte* input, word16 length, byte msgType,
+                                                                 Suites *suites)
+{
+    int ret = 0;
+    word16 offset = 0;
+    byte isRequest = (msgType == client_hello ||
+                      msgType == certificate_request);
+
+#ifdef HAVE_EXTENDED_MASTER
+    byte pendingEMS = 0;
+#endif
+#if defined(WOLFSSL_TLS13) && (defined(HAVE_SESSION_TICKET) || !defined(NO_PSK))
+    int pskDone = 0;
+#endif
+
+    if (!ssl || !input || (isRequest && !suites))
+        return BAD_FUNC_ARG;
+
+    while (ret == 0 && offset < length) {
+        word16 type;
+        word16 size;
+
+#if defined(WOLFSSL_TLS13) && (defined(HAVE_SESSION_TICKET) || !defined(NO_PSK))
+        if (msgType == client_hello && pskDone)
+            return PSK_KEY_ERROR;
+#endif
+
+        if (length - offset < HELLO_EXT_TYPE_SZ + OPAQUE16_LEN)
+            return BUFFER_ERROR;
+
+        ato16(input + offset, &type);
+        offset += HELLO_EXT_TYPE_SZ;
+
+        ato16(input + offset, &size);
+        offset += OPAQUE16_LEN;
+
+        if (offset + size > length)
+            return BUFFER_ERROR;
+
+        switch (type) {
+            case TLSX_SERVER_NAME:
+                WOLFSSL_MSG("SNI extension received");
+            #ifdef WOLFSSL_DEBUG_TLS
+                WOLFSSL_BUFFER(input + offset, size);
+            #endif
+
+#ifdef WOLFSSL_TLS13
+                if (IsAtLeastTLSv1_3(ssl->version) &&
+                        msgType != client_hello &&
+                        msgType != server_hello &&
+                        msgType != encrypted_extensions) {
+                    return EXT_NOT_ALLOWED;
+                }
+                else if (!IsAtLeastTLSv1_3(ssl->version) &&
+                         msgType == encrypted_extensions) {
+                    return EXT_NOT_ALLOWED;
+                }
+#endif
+                ret = SNI_PARSE(ssl, input + offset, size, isRequest);
+                break;
+
+            case TLSX_TRUSTED_CA_KEYS:
+                WOLFSSL_MSG("Trusted CA extension received");
+            #ifdef WOLFSSL_DEBUG_TLS
+                WOLFSSL_BUFFER(input + offset, size);
+            #endif
+
+#ifdef WOLFSSL_TLS13
+                if (IsAtLeastTLSv1_3(ssl->version) &&
+                        msgType != client_hello &&
+                        msgType != encrypted_extensions) {
+                    return EXT_NOT_ALLOWED;
+                }
+#endif
+                ret = TCA_PARSE(ssl, input + offset, size, isRequest);
+                break;
+
+            case TLSX_MAX_FRAGMENT_LENGTH:
+                WOLFSSL_MSG("Max Fragment Length extension received");
+            #ifdef WOLFSSL_DEBUG_TLS
+                WOLFSSL_BUFFER(input + offset, size);
+            #endif
+
+#ifdef WOLFSSL_TLS13
+                if (IsAtLeastTLSv1_3(ssl->version) &&
+                        msgType != client_hello &&
+                        msgType != encrypted_extensions) {
+                    return EXT_NOT_ALLOWED;
+                }
+                else if (!IsAtLeastTLSv1_3(ssl->version) &&
+                         msgType == encrypted_extensions) {
+                    return EXT_NOT_ALLOWED;
+                }
+#endif
+                ret = MFL_PARSE(ssl, input + offset, size, isRequest);
+                break;
+
+            case TLSX_TRUNCATED_HMAC:
+                WOLFSSL_MSG("Truncated HMAC extension received");
+            #ifdef WOLFSSL_DEBUG_TLS
+                WOLFSSL_BUFFER(input + offset, size);
+            #endif
+
+#ifdef WOLFSSL_TLS13
+                if (IsAtLeastTLSv1_3(ssl->version))
+                    break;
+#endif
+                ret = THM_PARSE(ssl, input + offset, size, isRequest);
+                break;
+
+            case TLSX_SUPPORTED_GROUPS:
+                WOLFSSL_MSG("Supported Groups extension received");
+            #ifdef WOLFSSL_DEBUG_TLS
+                WOLFSSL_BUFFER(input + offset, size);
+            #endif
+
+#ifdef WOLFSSL_TLS13
+                if (IsAtLeastTLSv1_3(ssl->version) &&
+                        msgType != client_hello &&
+                        msgType != server_hello &&
+                        msgType != encrypted_extensions) {
+                    return EXT_NOT_ALLOWED;
+                }
+                else if (!IsAtLeastTLSv1_3(ssl->version) &&
+                         msgType == encrypted_extensions) {
+                    return EXT_NOT_ALLOWED;
+                }
+#endif
+                ret = EC_PARSE(ssl, input + offset, size, isRequest);
+                break;
+
+            case TLSX_EC_POINT_FORMATS:
+                WOLFSSL_MSG("Point Formats extension received");
+            #ifdef WOLFSSL_DEBUG_TLS
+                WOLFSSL_BUFFER(input + offset, size);
+            #endif
+
+#ifdef WOLFSSL_TLS13
+                if (IsAtLeastTLSv1_3(ssl->version))
+                    break;
+#endif
+                ret = PF_PARSE(ssl, input + offset, size, isRequest);
+                break;
+
+            case TLSX_STATUS_REQUEST:
+                WOLFSSL_MSG("Certificate Status Request extension received");
+            #ifdef WOLFSSL_DEBUG_TLS
+                WOLFSSL_BUFFER(input + offset, size);
+            #endif
+
+ #ifdef WOLFSSL_TLS13
+                if (IsAtLeastTLSv1_3(ssl->version) &&
+                        msgType != client_hello &&
+                        msgType != certificate_request &&
+                        msgType != certificate) {
+                     break;
+                }
+ #endif
+                ret = CSR_PARSE(ssl, input + offset, size, isRequest);
+                break;
+
+            case TLSX_STATUS_REQUEST_V2:
+                WOLFSSL_MSG("Certificate Status Request v2 extension received");
+            #ifdef WOLFSSL_DEBUG_TLS
+                WOLFSSL_BUFFER(input + offset, size);
+            #endif
+
+#ifdef WOLFSSL_TLS13
+                if (IsAtLeastTLSv1_3(ssl->version) &&
+                        msgType != client_hello &&
+                        msgType != certificate_request &&
+                        msgType != certificate) {
+                    return EXT_NOT_ALLOWED;
+                }
+#endif
+                ret = CSR2_PARSE(ssl, input + offset, size, isRequest);
+                break;
+
+#ifdef HAVE_EXTENDED_MASTER
+            case HELLO_EXT_EXTMS:
+                WOLFSSL_MSG("Extended Master Secret extension received");
+            #ifdef WOLFSSL_DEBUG_TLS
+                WOLFSSL_BUFFER(input + offset, size);
+            #endif
+
+#ifdef WOLFSSL_TLS13
+                if (IsAtLeastTLSv1_3(ssl->version))
+                    break;
+#endif
+                if (size != 0)
+                    return BUFFER_ERROR;
+
+#ifndef NO_WOLFSSL_SERVER
+                if (isRequest)
+                    ssl->options.haveEMS = 1;
+#endif
+                pendingEMS = 1;
+                break;
+#endif
+
+            case TLSX_RENEGOTIATION_INFO:
+                WOLFSSL_MSG("Secure Renegotiation extension received");
+            #ifdef WOLFSSL_DEBUG_TLS
+                WOLFSSL_BUFFER(input + offset, size);
+            #endif
+
+#ifdef WOLFSSL_TLS13
+                if (IsAtLeastTLSv1_3(ssl->version))
+                    break;
+#endif
+                ret = SCR_PARSE(ssl, input + offset, size, isRequest);
+                break;
+
+            case TLSX_SESSION_TICKET:
+                WOLFSSL_MSG("Session Ticket extension received");
+            #ifdef WOLFSSL_DEBUG_TLS
+                WOLFSSL_BUFFER(input + offset, size);
+            #endif
+
+#ifdef WOLFSSL_TLS13
+                if (IsAtLeastTLSv1_3(ssl->version) &&
+                        msgType != client_hello) {
+                    return EXT_NOT_ALLOWED;
+                }
+#endif
+                ret = WOLF_STK_PARSE(ssl, input + offset, size, isRequest);
+                break;
+
+            case TLSX_QUANTUM_SAFE_HYBRID:
+                WOLFSSL_MSG("Quantum-Safe-Hybrid extension received");
+            #ifdef WOLFSSL_DEBUG_TLS
+                WOLFSSL_BUFFER(input + offset, size);
+            #endif
+
+#ifdef WOLFSSL_TLS13
+                if (IsAtLeastTLSv1_3(ssl->version))
+                    break;
+#endif
+                ret = QSH_PARSE(ssl, input + offset, size, isRequest);
+                break;
+
+            case TLSX_APPLICATION_LAYER_PROTOCOL:
+                WOLFSSL_MSG("ALPN extension received");
+
+            #ifdef WOLFSSL_DEBUG_TLS
+                WOLFSSL_BUFFER(input + offset, size);
+            #endif
+
+#ifdef WOLFSSL_TLS13
+                if (IsAtLeastTLSv1_3(ssl->version) &&
+                        msgType != client_hello &&
+                        msgType != server_hello &&
+                        msgType != encrypted_extensions) {
+                    return EXT_NOT_ALLOWED;
+                }
+                else if (!IsAtLeastTLSv1_3(ssl->version) &&
+                         msgType == encrypted_extensions) {
+                    return EXT_NOT_ALLOWED;
+                }
+#endif
+                ret = ALPN_PARSE(ssl, input + offset, size, isRequest);
+                break;
+#if !defined(WOLFSSL_NO_SIGALG)
+            case TLSX_SIGNATURE_ALGORITHMS:
+                WOLFSSL_MSG("Signature Algorithms extension received");
+            #ifdef WOLFSSL_DEBUG_TLS
+                WOLFSSL_BUFFER(input + offset, size);
+            #endif
+
+                if (!IsAtLeastTLSv1_2(ssl))
+                    break;
+#ifdef WOLFSSL_TLS13
+                if (IsAtLeastTLSv1_3(ssl->version) &&
+                        msgType != client_hello &&
+                        msgType != certificate_request) {
+                    return EXT_NOT_ALLOWED;
+                }
+#endif
+                ret = SA_PARSE(ssl, input + offset, size, isRequest, suites);
+                break;
+#endif
+
+#if defined(HAVE_ENCRYPT_THEN_MAC) && !defined(WOLFSSL_AEAD_ONLY)
+            case TLSX_ENCRYPT_THEN_MAC:
+                WOLFSSL_MSG("Encrypt-Then-Mac extension received");
+
+                /* Ignore for TLS 1.3+ */
+                if (IsAtLeastTLSv1_3(ssl->version))
+                    break;
+
+                ret = ETM_PARSE(ssl, input + offset, size, msgType);
+                break;
+#endif /* HAVE_ENCRYPT_THEN_MAC */
+
+#ifdef WOLFSSL_TLS13
+            case TLSX_SUPPORTED_VERSIONS:
+                WOLFSSL_MSG("Skipping Supported Versions - already processed");
+            #ifdef WOLFSSL_DEBUG_TLS
+                WOLFSSL_BUFFER(input + offset, size);
+            #endif
+
+                break;
+
+            case TLSX_COOKIE:
+                WOLFSSL_MSG("Cookie extension received");
+            #ifdef WOLFSSL_DEBUG_TLS
+                WOLFSSL_BUFFER(input + offset, size);
+            #endif
+
+                if (!IsAtLeastTLSv1_3(ssl->version))
+                    break;
+
+                if (msgType != client_hello &&
+                        msgType != hello_retry_request) {
+                    return EXT_NOT_ALLOWED;
+                }
+
+                ret = CKE_PARSE(ssl, input + offset, size, msgType);
+                break;
+
+    #if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
+            case TLSX_PRE_SHARED_KEY:
+                WOLFSSL_MSG("Pre-Shared Key extension received");
+            #ifdef WOLFSSL_DEBUG_TLS
+                WOLFSSL_BUFFER(input + offset, size);
+            #endif
+
+                if (!IsAtLeastTLSv1_3(ssl->version))
+                    break;
+
+                if (msgType != client_hello && msgType != server_hello)
+                    return EXT_NOT_ALLOWED;
+
+                ret = PSK_PARSE(ssl, input + offset, size, msgType);
+                pskDone = 1;
+                break;
+
+            case TLSX_PSK_KEY_EXCHANGE_MODES:
+                WOLFSSL_MSG("PSK Key Exchange Modes extension received");
+            #ifdef WOLFSSL_DEBUG_TLS
+                WOLFSSL_BUFFER(input + offset, size);
+            #endif
+
+                if (!IsAtLeastTLSv1_3(ssl->version))
+                    break;
+
+                if (msgType != client_hello)
+                    return EXT_NOT_ALLOWED;
+
+                ret = PKM_PARSE(ssl, input + offset, size, msgType);
+                break;
+    #endif
+
+    #ifdef WOLFSSL_EARLY_DATA
+            case TLSX_EARLY_DATA:
+                WOLFSSL_MSG("Early Data extension received");
+            #ifdef WOLFSSL_DEBUG_TLS
+                WOLFSSL_BUFFER(input + offset, size);
+            #endif
+
+                if (!IsAtLeastTLSv1_3(ssl->version))
+                    break;
+
+                if (msgType != client_hello && msgType != session_ticket &&
+                        msgType != encrypted_extensions) {
+                    return EXT_NOT_ALLOWED;
+                }
+                if (!IsAtLeastTLSv1_3(ssl->version) &&
+                        (msgType == session_ticket ||
+                         msgType == encrypted_extensions)) {
+                    return EXT_NOT_ALLOWED;
+                }
+                ret = EDI_PARSE(ssl, input + offset, size, msgType);
+                break;
+    #endif
+
+    #ifdef WOLFSSL_POST_HANDSHAKE_AUTH
+            case TLSX_POST_HANDSHAKE_AUTH:
+                WOLFSSL_MSG("Post Handshake Authentication extension received");
+            #ifdef WOLFSSL_DEBUG_TLS
+                WOLFSSL_BUFFER(input + offset, size);
+            #endif
+
+                if (!IsAtLeastTLSv1_3(ssl->version))
+                    break;
+
+                if (msgType != client_hello)
+                    return EXT_NOT_ALLOWED;
+
+                ret = PHA_PARSE(ssl, input + offset, size, msgType);
+                break;
+    #endif
+
+    #if !defined(WOLFSSL_TLS13_DRAFT_18) && !defined(WOLFSSL_TLS13_DRAFT_22)
+            case TLSX_SIGNATURE_ALGORITHMS_CERT:
+                WOLFSSL_MSG("Signature Algorithms extension received");
+            #ifdef WOLFSSL_DEBUG_TLS
+                WOLFSSL_BUFFER(input + offset, size);
+            #endif
+
+                if (!IsAtLeastTLSv1_3(ssl->version))
+                    break;
+
+                if (msgType != client_hello &&
+                        msgType != certificate_request) {
+                    return EXT_NOT_ALLOWED;
+                }
+                if (!IsAtLeastTLSv1_3(ssl->version) &&
+                        msgType == certificate_request) {
+                    return EXT_NOT_ALLOWED;
+                }
+
+                ret = SAC_PARSE(ssl, input + offset, size, isRequest);
+                break;
+    #endif
+
+            case TLSX_KEY_SHARE:
+                WOLFSSL_MSG("Key Share extension received");
+            #ifdef WOLFSSL_DEBUG_TLS
+                WOLFSSL_BUFFER(input + offset, size);
+            #endif
+
+                if (!IsAtLeastTLSv1_3(ssl->version))
+                    break;
+
+                if (msgType != client_hello && msgType != server_hello &&
+                        msgType != hello_retry_request) {
+                    return EXT_NOT_ALLOWED;
+                }
+                ret = KS_PARSE(ssl, input + offset, size, msgType);
+                break;
+#endif
+            default:
+                WOLFSSL_MSG("Unknown TLS extension type");
+        }
+
+        /* offset should be updated here! */
+        offset += size;
+    }
+
+#ifdef HAVE_EXTENDED_MASTER
+    if (!isRequest && ssl->options.haveEMS && !pendingEMS)
+        ssl->options.haveEMS = 0;
+#endif
+
+    if (ret == 0)
+        ret = SNI_VERIFY_PARSE(ssl, isRequest);
+    if (ret == 0)
+        ret = TCA_VERIFY_PARSE(ssl, isRequest);
+
+    return ret;
+}
+
+/* undefining semaphore macros */
+#undef IS_OFF
+#undef TURN_ON
+#undef SEMAPHORE_SIZE
+
+#endif /* HAVE_TLS_EXTENSIONS */
+
+#ifndef NO_WOLFSSL_CLIENT
+
+    WOLFSSL_METHOD* wolfTLS_client_method(void)
+    {
+        return wolfTLS_client_method_ex(NULL);
+    }
+    WOLFSSL_METHOD* wolfTLS_client_method_ex(void* heap)
+    {
+        WOLFSSL_METHOD* method =
+                              (WOLFSSL_METHOD*) XMALLOC(sizeof(WOLFSSL_METHOD),
+                                                     heap, DYNAMIC_TYPE_METHOD);
+        (void)heap;
+        WOLFSSL_ENTER("TLS_client_method_ex");
+        if (method) {
+        #if defined(WOLFSSL_TLS13)
+            InitSSL_Method(method, MakeTLSv1_3());
+        #elif !defined(WOLFSSL_NO_TLS12)
+            InitSSL_Method(method, MakeTLSv1_2());
+        #elif !defined(NO_OLD_TLS)
+            InitSSL_Method(method, MakeTLSv1_1());
+        #elif defined(WOLFSSL_ALLOW_TLSV10)
+            InitSSL_Method(method, MakeTLSv1());
+        #else
+            #error No TLS version enabled!
+        #endif
+
+            method->downgrade = 1;
+            method->side      = WOLFSSL_CLIENT_END;
+        }
+        return method;
+    }
+
+#ifndef NO_OLD_TLS
+    #ifdef WOLFSSL_ALLOW_TLSV10
+    WOLFSSL_METHOD* wolfTLSv1_client_method(void)
+    {
+        return wolfTLSv1_client_method_ex(NULL);
+    }
+    WOLFSSL_METHOD* wolfTLSv1_client_method_ex(void* heap)
+    {
+        WOLFSSL_METHOD* method =
+                             (WOLFSSL_METHOD*) XMALLOC(sizeof(WOLFSSL_METHOD),
+                                                     heap, DYNAMIC_TYPE_METHOD);
+        (void)heap;
+        WOLFSSL_ENTER("TLSv1_client_method_ex");
+        if (method)
+            InitSSL_Method(method, MakeTLSv1());
+        return method;
+    }
+    #endif /* WOLFSSL_ALLOW_TLSV10 */
+
+    WOLFSSL_METHOD* wolfTLSv1_1_client_method(void)
+    {
+        return wolfTLSv1_1_client_method_ex(NULL);
+    }
+    WOLFSSL_METHOD* wolfTLSv1_1_client_method_ex(void* heap)
+    {
+        WOLFSSL_METHOD* method =
+                              (WOLFSSL_METHOD*) XMALLOC(sizeof(WOLFSSL_METHOD),
+                                                     heap, DYNAMIC_TYPE_METHOD);
+        (void)heap;
+        WOLFSSL_ENTER("TLSv1_1_client_method_ex");
+        if (method)
+            InitSSL_Method(method, MakeTLSv1_1());
+        return method;
+    }
+#endif /* !NO_OLD_TLS */
+
+#ifndef WOLFSSL_NO_TLS12
+    WOLFSSL_ABI
+    WOLFSSL_METHOD* wolfTLSv1_2_client_method(void)
+    {
+        return wolfTLSv1_2_client_method_ex(NULL);
+    }
+    WOLFSSL_METHOD* wolfTLSv1_2_client_method_ex(void* heap)
+    {
+        WOLFSSL_METHOD* method =
+                              (WOLFSSL_METHOD*) XMALLOC(sizeof(WOLFSSL_METHOD),
+                                                     heap, DYNAMIC_TYPE_METHOD);
+        (void)heap;
+        WOLFSSL_ENTER("TLSv1_2_client_method_ex");
+        if (method)
+            InitSSL_Method(method, MakeTLSv1_2());
+        return method;
+    }
+#endif /* WOLFSSL_NO_TLS12 */
+
+#ifdef WOLFSSL_TLS13
+    /* The TLS v1.3 client method data.
+     *
+     * returns the method data for a TLS v1.3 client.
+     */
+    WOLFSSL_ABI
+    WOLFSSL_METHOD* wolfTLSv1_3_client_method(void)
+    {
+        return wolfTLSv1_3_client_method_ex(NULL);
+    }
+
+    /* The TLS v1.3 client method data.
+     *
+     * heap  The heap used for allocation.
+     * returns the method data for a TLS v1.3 client.
+     */
+    WOLFSSL_METHOD* wolfTLSv1_3_client_method_ex(void* heap)
+    {
+        WOLFSSL_METHOD* method = (WOLFSSL_METHOD*)
+                                 XMALLOC(sizeof(WOLFSSL_METHOD), heap,
+                                         DYNAMIC_TYPE_METHOD);
+        (void)heap;
+        WOLFSSL_ENTER("TLSv1_3_client_method_ex");
+        if (method)
+            InitSSL_Method(method, MakeTLSv1_3());
+        return method;
+    }
+#endif /* WOLFSSL_TLS13 */
+
+#ifdef WOLFSSL_DTLS
+
+    WOLFSSL_METHOD* wolfDTLS_client_method(void)
+    {
+        return wolfDTLS_client_method_ex(NULL);
+    }
+    WOLFSSL_METHOD* wolfDTLS_client_method_ex(void* heap)
+    {
+        WOLFSSL_METHOD* method =
+                              (WOLFSSL_METHOD*) XMALLOC(sizeof(WOLFSSL_METHOD),
+                                                     heap, DYNAMIC_TYPE_METHOD);
+        (void)heap;
+        WOLFSSL_ENTER("DTLS_client_method_ex");
+        if (method) {
+        #if !defined(WOLFSSL_NO_TLS12)
+            InitSSL_Method(method, MakeDTLSv1_2());
+        #elif !defined(NO_OLD_TLS)
+            InitSSL_Method(method, MakeDTLSv1());
+        #else
+            #error No DTLS version enabled!
+        #endif
+
+            method->downgrade = 1;
+            method->side      = WOLFSSL_CLIENT_END;
+        }
+        return method;
+    }
+
+    #ifndef NO_OLD_TLS
+    WOLFSSL_METHOD* wolfDTLSv1_client_method(void)
+    {
+        return wolfDTLSv1_client_method_ex(NULL);
+    }
+    WOLFSSL_METHOD* wolfDTLSv1_client_method_ex(void* heap)
+    {
+        WOLFSSL_METHOD* method =
+                          (WOLFSSL_METHOD*) XMALLOC(sizeof(WOLFSSL_METHOD),
+                                                 heap, DYNAMIC_TYPE_METHOD);
+        (void)heap;
+        WOLFSSL_ENTER("DTLSv1_client_method_ex");
+        if (method)
+            InitSSL_Method(method, MakeDTLSv1());
+        return method;
+    }
+    #endif  /* NO_OLD_TLS */
+
+    #ifndef WOLFSSL_NO_TLS12
+    WOLFSSL_METHOD* wolfDTLSv1_2_client_method(void)
+    {
+        return wolfDTLSv1_2_client_method_ex(NULL);
+    }
+    WOLFSSL_METHOD* wolfDTLSv1_2_client_method_ex(void* heap)
+    {
+        WOLFSSL_METHOD* method =
+                          (WOLFSSL_METHOD*) XMALLOC(sizeof(WOLFSSL_METHOD),
+                                                 heap, DYNAMIC_TYPE_METHOD);
+        (void)heap;
+        WOLFSSL_ENTER("DTLSv1_2_client_method_ex");
+        if (method)
+            InitSSL_Method(method, MakeDTLSv1_2());
+        (void)heap;
+        return method;
+    }
+    #endif /* !WOLFSSL_NO_TLS12 */
+#endif /* WOLFSSL_DTLS */
+
+#endif /* NO_WOLFSSL_CLIENT */
+
+
+/* EITHER SIDE METHODS */
+#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_EITHER_SIDE)
+    #ifndef NO_OLD_TLS
+    #ifdef WOLFSSL_ALLOW_TLSV10
+    /* Gets a WOLFSL_METHOD type that is not set as client or server
+     *
+     * Returns a pointer to a WOLFSSL_METHOD struct
+     */
+    WOLFSSL_METHOD* wolfTLSv1_method(void)
+    {
+        return wolfTLSv1_method_ex(NULL);
+    }
+    WOLFSSL_METHOD* wolfTLSv1_method_ex(void* heap)
+    {
+        WOLFSSL_METHOD* m;
+        WOLFSSL_ENTER("TLSv1_method");
+    #ifndef NO_WOLFSSL_CLIENT
+        m = wolfTLSv1_client_method_ex(heap);
+    #else
+        m = wolfTLSv1_server_method_ex(heap);
+    #endif
+        if (m != NULL) {
+            m->side = WOLFSSL_NEITHER_END;
+        }
+
+        return m;
+    }
+    #endif /* WOLFSSL_ALLOW_TLSV10 */
+
+    /* Gets a WOLFSL_METHOD type that is not set as client or server
+     *
+     * Returns a pointer to a WOLFSSL_METHOD struct
+     */
+    WOLFSSL_METHOD* wolfTLSv1_1_method(void)
+    {
+        return wolfTLSv1_1_method_ex(NULL);
+    }
+    WOLFSSL_METHOD* wolfTLSv1_1_method_ex(void* heap)
+    {
+        WOLFSSL_METHOD* m;
+        WOLFSSL_ENTER("TLSv1_1_method");
+    #ifndef NO_WOLFSSL_CLIENT
+        m = wolfTLSv1_1_client_method_ex(heap);
+    #else
+        m = wolfTLSv1_1_server_method_ex(heap);
+    #endif
+        if (m != NULL) {
+            m->side = WOLFSSL_NEITHER_END;
+        }
+        return m;
+    }
+    #endif /* !NO_OLD_TLS */
+
+    #ifndef WOLFSSL_NO_TLS12
+    /* Gets a WOLFSL_METHOD type that is not set as client or server
+     *
+     * Returns a pointer to a WOLFSSL_METHOD struct
+     */
+    WOLFSSL_METHOD* wolfTLSv1_2_method(void)
+    {
+        return wolfTLSv1_2_method_ex(NULL);
+    }
+    WOLFSSL_METHOD* wolfTLSv1_2_method_ex(void* heap)
+    {
+        WOLFSSL_METHOD* m;
+        WOLFSSL_ENTER("TLSv1_2_method");
+    #ifndef NO_WOLFSSL_CLIENT
+        m = wolfTLSv1_2_client_method_ex(heap);
+    #else
+        m = wolfTLSv1_2_server_method_ex(heap);
+    #endif
+        if (m != NULL) {
+            m->side = WOLFSSL_NEITHER_END;
+        }
+        return m;
+    }
+    #endif /* !WOLFSSL_NO_TLS12 */
+
+    #ifdef WOLFSSL_TLS13
+    /* Gets a WOLFSL_METHOD type that is not set as client or server
+     *
+     * Returns a pointer to a WOLFSSL_METHOD struct
+     */
+    WOLFSSL_METHOD* wolfTLSv1_3_method(void)
+    {
+        return wolfTLSv1_3_method_ex(NULL);
+    }
+    WOLFSSL_METHOD* wolfTLSv1_3_method_ex(void* heap)
+    {
+        WOLFSSL_METHOD* m;
+        WOLFSSL_ENTER("TLSv1_3_method");
+    #ifndef NO_WOLFSSL_CLIENT
+        m = wolfTLSv1_3_client_method_ex(heap);
+    #else
+        m = wolfTLSv1_3_server_method_ex(heap);
+    #endif
+        if (m != NULL) {
+            m->side = WOLFSSL_NEITHER_END;
+        }
+        return m;
+    }
+    #endif /* WOLFSSL_TLS13 */
+
+#ifdef WOLFSSL_DTLS
+    WOLFSSL_METHOD* wolfDTLS_method(void)
+    {
+        return wolfDTLS_method_ex(NULL);
+    }
+    WOLFSSL_METHOD* wolfDTLS_method_ex(void* heap)
+    {
+        WOLFSSL_METHOD* m;
+        WOLFSSL_ENTER("DTLS_method_ex");
+    #ifndef NO_WOLFSSL_CLIENT
+        m = wolfDTLS_client_method_ex(heap);
+    #else
+        m = wolfDTLS_server_method_ex(heap);
+    #endif
+        if (m != NULL) {
+            m->side = WOLFSSL_NEITHER_END;
+        }
+        return m;
+    }
+
+    #ifndef NO_OLD_TLS
+    WOLFSSL_METHOD* wolfDTLSv1_method(void)
+    {
+        return wolfDTLSv1_method_ex(NULL);
+    }
+    WOLFSSL_METHOD* wolfDTLSv1_method_ex(void* heap)
+    {
+        WOLFSSL_METHOD* m;
+        WOLFSSL_ENTER("DTLSv1_method_ex");
+    #ifndef NO_WOLFSSL_CLIENT
+        m = wolfDTLSv1_client_method_ex(heap);
+    #else
+        m = wolfDTLSv1_server_method_ex(heap);
+    #endif
+        if (m != NULL) {
+            m->side = WOLFSSL_NEITHER_END;
+        }
+        return m;
+    }
+    #endif /* !NO_OLD_TLS */
+    #ifndef WOLFSSL_NO_TLS12
+    WOLFSSL_METHOD* wolfDTLSv1_2_method(void)
+    {
+        return wolfDTLSv1_2_method_ex(NULL);
+    }
+    WOLFSSL_METHOD* wolfDTLSv1_2_method_ex(void* heap)
+    {
+        WOLFSSL_METHOD* m;
+        WOLFSSL_ENTER("DTLSv1_2_method");
+    #ifndef NO_WOLFSSL_CLIENT
+        m = wolfDTLSv1_2_client_method_ex(heap);
+    #else
+        m = wolfDTLSv1_2_server_method_ex(heap);
+    #endif
+        if (m != NULL) {
+            m->side = WOLFSSL_NEITHER_END;
+        }
+        return m;
+    }
+    #endif /* !WOLFSSL_NO_TLS12 */
+#endif /* WOLFSSL_DTLS */
+#endif /* OPENSSL_EXTRA || WOLFSSL_EITHER_SIDE */
+
+
+#ifndef NO_WOLFSSL_SERVER
+
+    WOLFSSL_METHOD* wolfTLS_server_method(void)
+    {
+        return wolfTLS_server_method_ex(NULL);
+    }
+
+    WOLFSSL_METHOD* wolfTLS_server_method_ex(void* heap)
+    {
+        WOLFSSL_METHOD* method =
+                              (WOLFSSL_METHOD*) XMALLOC(sizeof(WOLFSSL_METHOD),
+                                                     heap, DYNAMIC_TYPE_METHOD);
+        (void)heap;
+        WOLFSSL_ENTER("TLS_server_method_ex");
+        if (method) {
+        #if defined(WOLFSSL_TLS13)
+            InitSSL_Method(method, MakeTLSv1_3());
+        #elif !defined(WOLFSSL_NO_TLS12)
+            InitSSL_Method(method, MakeTLSv1_2());
+        #elif !defined(NO_OLD_TLS)
+            InitSSL_Method(method, MakeTLSv1_1());
+        #elif defined(WOLFSSL_ALLOW_TLSV10)
+            InitSSL_Method(method, MakeTLSv1());
+        #else
+            #error No TLS version enabled!
+        #endif
+
+            method->downgrade = 1;
+            method->side      = WOLFSSL_SERVER_END;
+        }
+        return method;
+    }
+
+#ifndef NO_OLD_TLS
+    #ifdef WOLFSSL_ALLOW_TLSV10
+    WOLFSSL_METHOD* wolfTLSv1_server_method(void)
+    {
+        return wolfTLSv1_server_method_ex(NULL);
+    }
+    WOLFSSL_METHOD* wolfTLSv1_server_method_ex(void* heap)
+    {
+        WOLFSSL_METHOD* method =
+                              (WOLFSSL_METHOD*) XMALLOC(sizeof(WOLFSSL_METHOD),
+                                                     heap, DYNAMIC_TYPE_METHOD);
+        (void)heap;
+        WOLFSSL_ENTER("TLSv1_server_method_ex");
+        if (method) {
+            InitSSL_Method(method, MakeTLSv1());
+            method->side = WOLFSSL_SERVER_END;
+        }
+        return method;
+    }
+    #endif /* WOLFSSL_ALLOW_TLSV10 */
+
+    WOLFSSL_METHOD* wolfTLSv1_1_server_method(void)
+    {
+        return wolfTLSv1_1_server_method_ex(NULL);
+    }
+    WOLFSSL_METHOD* wolfTLSv1_1_server_method_ex(void* heap)
+    {
+        WOLFSSL_METHOD* method =
+                              (WOLFSSL_METHOD*) XMALLOC(sizeof(WOLFSSL_METHOD),
+                                                     heap, DYNAMIC_TYPE_METHOD);
+        (void)heap;
+        WOLFSSL_ENTER("TLSv1_1_server_method_ex");
+        if (method) {
+            InitSSL_Method(method, MakeTLSv1_1());
+            method->side = WOLFSSL_SERVER_END;
+        }
+        return method;
+    }
+#endif /* !NO_OLD_TLS */
+
+
+#ifndef WOLFSSL_NO_TLS12
+    WOLFSSL_METHOD* wolfTLSv1_2_server_method(void)
+    {
+        return wolfTLSv1_2_server_method_ex(NULL);
+    }
+    WOLFSSL_METHOD* wolfTLSv1_2_server_method_ex(void* heap)
+    {
+        WOLFSSL_METHOD* method =
+                              (WOLFSSL_METHOD*) XMALLOC(sizeof(WOLFSSL_METHOD),
+                                                     heap, DYNAMIC_TYPE_METHOD);
+        (void)heap;
+        WOLFSSL_ENTER("TLSv1_2_server_method_ex");
+        if (method) {
+            InitSSL_Method(method, MakeTLSv1_2());
+            method->side = WOLFSSL_SERVER_END;
+        }
+        return method;
+    }
+#endif /* !WOLFSSL_NO_TLS12 */
+
+#ifdef WOLFSSL_TLS13
+    /* The TLS v1.3 server method data.
+     *
+     * returns the method data for a TLS v1.3 server.
+     */
+    WOLFSSL_METHOD* wolfTLSv1_3_server_method(void)
+    {
+        return wolfTLSv1_3_server_method_ex(NULL);
+    }
+
+    /* The TLS v1.3 server method data.
+     *
+     * heap  The heap used for allocation.
+     * returns the method data for a TLS v1.3 server.
+     */
+    WOLFSSL_METHOD* wolfTLSv1_3_server_method_ex(void* heap)
+    {
+        WOLFSSL_METHOD* method =
+                              (WOLFSSL_METHOD*) XMALLOC(sizeof(WOLFSSL_METHOD),
+                                                     heap, DYNAMIC_TYPE_METHOD);
+        (void)heap;
+        WOLFSSL_ENTER("TLSv1_3_server_method_ex");
+        if (method) {
+            InitSSL_Method(method, MakeTLSv1_3());
+            method->side = WOLFSSL_SERVER_END;
+        }
+        return method;
+    }
+#endif /* WOLFSSL_TLS13 */
+
+#ifdef WOLFSSL_DTLS
+    WOLFSSL_METHOD* wolfDTLS_server_method(void)
+    {
+        return wolfDTLS_server_method_ex(NULL);
+    }
+    WOLFSSL_METHOD* wolfDTLS_server_method_ex(void* heap)
+    {
+        WOLFSSL_METHOD* method =
+                              (WOLFSSL_METHOD*) XMALLOC(sizeof(WOLFSSL_METHOD),
+                                                     heap, DYNAMIC_TYPE_METHOD);
+        (void)heap;
+        WOLFSSL_ENTER("DTLS_server_method_ex");
+        if (method) {
+        #if !defined(WOLFSSL_NO_TLS12)
+            InitSSL_Method(method, MakeDTLSv1_2());
+        #elif !defined(NO_OLD_TLS)
+            InitSSL_Method(method, MakeDTLSv1());
+        #else
+            #error No DTLS version enabled!
+        #endif
+
+            method->downgrade = 1;
+            method->side      = WOLFSSL_SERVER_END;
+        }
+        return method;
+    }
+
+    #ifndef NO_OLD_TLS
+    WOLFSSL_METHOD* wolfDTLSv1_server_method(void)
+    {
+        return wolfDTLSv1_server_method_ex(NULL);
+    }
+    WOLFSSL_METHOD* wolfDTLSv1_server_method_ex(void* heap)
+    {
+        WOLFSSL_METHOD* method =
+                          (WOLFSSL_METHOD*) XMALLOC(sizeof(WOLFSSL_METHOD),
+                                                 heap, DYNAMIC_TYPE_METHOD);
+        (void)heap;
+        WOLFSSL_ENTER("DTLSv1_server_method_ex");
+        if (method) {
+            InitSSL_Method(method, MakeDTLSv1());
+            method->side = WOLFSSL_SERVER_END;
+        }
+        return method;
+    }
+    #endif /* !NO_OLD_TLS */
+
+    #ifndef WOLFSSL_NO_TLS12
+    WOLFSSL_METHOD* wolfDTLSv1_2_server_method(void)
+    {
+        return wolfDTLSv1_2_server_method_ex(NULL);
+    }
+    WOLFSSL_METHOD* wolfDTLSv1_2_server_method_ex(void* heap)
+    {
+        WOLFSSL_METHOD* method =
+                          (WOLFSSL_METHOD*) XMALLOC(sizeof(WOLFSSL_METHOD),
+                                                 heap, DYNAMIC_TYPE_METHOD);
+        WOLFSSL_ENTER("DTLSv1_2_server_method_ex");
+        (void)heap;
+        if (method) {
+            InitSSL_Method(method, MakeDTLSv1_2());
+            method->side = WOLFSSL_SERVER_END;
+        }
+        (void)heap;
+        return method;
+    }
+    #endif /* !WOLFSSL_NO_TLS12 */
+#endif /* WOLFSSL_DTLS */
+
+#endif /* NO_WOLFSSL_SERVER */
+
+#endif /* NO_TLS */
+#endif /* WOLFCRYPT_ONLY */
Index: azure_iot_hub_f767zi/trunk/wolfssl-4.4.0/src/tls13.c
===================================================================
--- azure_iot_hub_f767zi/trunk/wolfssl-4.4.0/src/tls13.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/wolfssl-4.4.0/src/tls13.c	(revision 457)
@@ -0,0 +1,9048 @@
+/* tls13.c
+ *
+ * Copyright (C) 2006-2020 wolfSSL Inc.
+ *
+ * This file is part of wolfSSL.
+ *
+ * wolfSSL is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * wolfSSL is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
+ */
+
+
+/*
+ * BUILD_GCM
+ *    Enables AES-GCM ciphersuites.
+ * HAVE_AESCCM
+ *    Enables AES-CCM ciphersuites.
+ * HAVE_SESSION_TICKET
+ *    Enables session tickets - required for TLS 1.3 resumption.
+ * NO_PSK
+ *    Do not enable Pre-Shared Keys.
+ * TLS13_SUPPORTS_EXPORTERS
+ *    Guard to compile out any code for exporter keys.
+ *    Feature not supported yet.
+ * WOLFSSL_ASYNC_CRYPT
+ *    Enables the use of asynchronous cryptographic operations.
+ *    This is available for ciphers and certificates.
+ * HAVE_CHACHA && HAVE_POLY1305
+ *    Enables use of CHACHA20-POLY1305 ciphersuites.
+ * WOLFSSL_DEBUG_TLS
+ *    Writes out details of TLS 1.3 protocol including handshake message buffers
+ *    and key generation input and output.
+ * WOLFSSL_EARLY_DATA
+ *    Allow 0-RTT Handshake using Early Data extensions and handshake message
+ * WOLFSSL_EARLY_DATA_GROUP
+ *    Group EarlyData message with ClientHello when sending
+ * WOLFSSL_NO_SERVER_GROUPS_EXT
+ *    Do not send the server's groups in an extension when the server's top
+ *    preference is not in client's list.
+ * WOLFSSL_POST_HANDSHAKE_AUTH
+ *    Allow TLS v1.3 code to perform post-handshake authentication of the
+ *    client.
+ * WOLFSSL_SEND_HRR_COOKIE
+ *    Send a cookie in hello_retry_request message to enable stateless tracking
+ *    of ClientHello replies.
+ * WOLFSSL_TLS13
+ *    Enable TLS 1.3 protocol implementation.
+ * WOLFSSL_TLS13_DRAFT_18
+ *    Conform with Draft 18 of the TLS v1.3 specification.
+ * WOLFSSL_TLS13_DRAFT_22
+ *    Conform with Draft 22 of the TLS v1.3 specification.
+ * WOLFSSL_TLS13_DRAFT_23
+ *    Conform with Draft 23 of the TLS v1.3 specification.
+ * WOLFSSL_TLS13_MIDDLEBOX_COMPAT
+ *    Enable middlebox compatibility in the TLS 1.3 handshake.
+ *    This includes sending ChangeCipherSpec before encrypted messages and
+ *    including a session id.
+ * WOLFSSL_TLS13_SHA512
+ *    Allow generation of SHA-512 digests in handshake - no ciphersuite
+ *    requires SHA-512 at this time.
+ * WOLFSSL_TLS13_TICKET_BEFORE_FINISHED
+ *    Allow a NewSessionTicket message to be sent by server before Client's
+ *    Finished message.
+ *    See TLS v1.3 specification, Section 4.6.1, Paragraph 4 (Note).
+ */
+
+#ifdef HAVE_CONFIG_H
+    #include <config.h>
+#endif
+
+#include <wolfssl/wolfcrypt/settings.h>
+
+#ifdef WOLFSSL_TLS13
+#ifdef HAVE_SESSION_TICKET
+    #include <wolfssl/wolfcrypt/wc_port.h>
+#endif
+
+#ifndef WOLFCRYPT_ONLY
+
+#ifdef HAVE_ERRNO_H
+    #include <errno.h>
+#endif
+
+#include <wolfssl/internal.h>
+#include <wolfssl/error-ssl.h>
+#include <wolfssl/wolfcrypt/asn.h>
+#include <wolfssl/wolfcrypt/dh.h>
+#ifdef NO_INLINE
+    #include <wolfssl/wolfcrypt/misc.h>
+#else
+    #define WOLFSSL_MISC_INCLUDED
+    #include <wolfcrypt/src/misc.c>
+#endif
+
+#ifdef HAVE_NTRU
+    #include "libntruencrypt/ntru_crypto.h"
+#endif
+
+#ifdef __sun
+    #include <sys/filio.h>
+#endif
+
+#ifndef TRUE
+    #define TRUE  1
+#endif
+#ifndef FALSE
+    #define FALSE 0
+#endif
+
+#ifndef HAVE_HKDF
+    #error The build option HAVE_HKDF is required for TLS 1.3
+#endif
+
+#ifndef HAVE_TLS_EXTENSIONS
+    #ifndef _MSC_VER
+        #error "The build option HAVE_TLS_EXTENSIONS is required for TLS 1.3"
+    #else
+        #pragma message("error: The build option HAVE_TLS_EXTENSIONS is required for TLS 1.3")
+    #endif
+#endif
+
+
+/* Set ret to error value and jump to label.
+ *
+ * err     The error value to set.
+ * eLabel  The label to jump to.
+ */
+#define ERROR_OUT(err, eLabel) { ret = (err); goto eLabel; }
+
+
+/* Extract data using HMAC, salt and input.
+ * RFC 5869 - HMAC-based Extract-and-Expand Key Derivation Function (HKDF)
+ *
+ * prk      The generated pseudorandom key.
+ * salt     The salt.
+ * saltLen  The length of the salt.
+ * ikm      The input keying material.
+ * ikmLen   The length of the input keying material.
+ * mac      The type of digest to use.
+ * returns 0 on success, otherwise failure.
+ */
+static int Tls13_HKDF_Extract(byte* prk, const byte* salt, int saltLen,
+                             byte* ikm, int ikmLen, int mac)
+{
+    int ret;
+    int hash = 0;
+    int len = 0;
+
+    switch (mac) {
+        #ifndef NO_SHA256
+        case sha256_mac:
+            hash = WC_SHA256;
+            len = WC_SHA256_DIGEST_SIZE;
+            break;
+        #endif
+
+        #ifdef WOLFSSL_SHA384
+        case sha384_mac:
+            hash = WC_SHA384;
+            len = WC_SHA384_DIGEST_SIZE;
+            break;
+        #endif
+
+        #ifdef WOLFSSL_TLS13_SHA512
+        case sha512_mac:
+            hash = WC_SHA512;
+            len = WC_SHA512_DIGEST_SIZE;
+            break;
+        #endif
+    }
+
+    /* When length is 0 then use zeroed data of digest length. */
+    if (ikmLen == 0) {
+        ikmLen = len;
+        XMEMSET(ikm, 0, len);
+    }
+
+#ifdef WOLFSSL_DEBUG_TLS
+    WOLFSSL_MSG("  Salt");
+    WOLFSSL_BUFFER(salt, saltLen);
+    WOLFSSL_MSG("  IKM");
+    WOLFSSL_BUFFER(ikm, ikmLen);
+#endif
+
+    ret = wc_HKDF_Extract(hash, salt, saltLen, ikm, ikmLen, prk);
+
+#ifdef WOLFSSL_DEBUG_TLS
+    WOLFSSL_MSG("  PRK");
+    WOLFSSL_BUFFER(prk, len);
+#endif
+
+    return ret;
+}
+
+/* Expand data using HMAC, salt and label and info.
+ * TLS v1.3 defines this function.
+ *
+ * okm          The generated pseudorandom key - output key material.
+ * okmLen       The length of generated pseudorandom key - output key material.
+ * prk          The salt - pseudo-random key.
+ * prkLen       The length of the salt - pseudo-random key.
+ * protocol     The TLS protocol label.
+ * protocolLen  The length of the TLS protocol label.
+ * info         The information to expand.
+ * infoLen      The length of the information.
+ * digest       The type of digest to use.
+ * returns 0 on success, otherwise failure.
+ */
+static int HKDF_Expand_Label(byte* okm, word32 okmLen,
+                             const byte* prk, word32 prkLen,
+                             const byte* protocol, word32 protocolLen,
+                             const byte* label, word32 labelLen,
+                             const byte* info, word32 infoLen,
+                             int digest)
+{
+    int    ret = 0;
+    int    idx = 0;
+    byte   data[MAX_HKDF_LABEL_SZ];
+
+    /* Output length. */
+    data[idx++] = (byte)(okmLen >> 8);
+    data[idx++] = (byte)okmLen;
+    /* Length of protocol | label. */
+    data[idx++] = (byte)(protocolLen + labelLen);
+    /* Protocol */
+    XMEMCPY(&data[idx], protocol, protocolLen);
+    idx += protocolLen;
+    /* Label */
+    XMEMCPY(&data[idx], label, labelLen);
+    idx += labelLen;
+    /* Length of hash of messages */
+    data[idx++] = (byte)infoLen;
+    /* Hash of messages */
+    XMEMCPY(&data[idx], info, infoLen);
+    idx += infoLen;
+
+#ifdef WOLFSSL_DEBUG_TLS
+    WOLFSSL_MSG("  PRK");
+    WOLFSSL_BUFFER(prk, prkLen);
+    WOLFSSL_MSG("  Info");
+    WOLFSSL_BUFFER(data, idx);
+#endif
+
+    ret = wc_HKDF_Expand(digest, prk, prkLen, data, idx, okm, okmLen);
+
+#ifdef WOLFSSL_DEBUG_TLS
+    WOLFSSL_MSG("  OKM");
+    WOLFSSL_BUFFER(okm, okmLen);
+#endif
+
+    ForceZero(data, idx);
+
+    return ret;
+}
+
+#ifdef WOLFSSL_TLS13_DRAFT_18
+/* Size of the TLS v1.3 label use when deriving keys. */
+#define TLS13_PROTOCOL_LABEL_SZ    9
+/* The protocol label for TLS v1.3. */
+static const byte tls13ProtocolLabel[TLS13_PROTOCOL_LABEL_SZ + 1] = "TLS 1.3, ";
+#else
+/* Size of the TLS v1.3 label use when deriving keys. */
+#define TLS13_PROTOCOL_LABEL_SZ    6
+/* The protocol label for TLS v1.3. */
+static const byte tls13ProtocolLabel[TLS13_PROTOCOL_LABEL_SZ + 1] = "tls13 ";
+#endif
+
+#if !defined(WOLFSSL_TLS13_DRAFT_18) || defined(HAVE_SESSION_TICKET) || \
+                                        !defined(NO_PSK)
+/* Derive a key from a message.
+ *
+ * ssl        The SSL/TLS object.
+ * output     The buffer to hold the derived key.
+ * outputLen  The length of the derived key.
+ * secret     The secret used to derive the key (HMAC secret).
+ * label      The label used to distinguish the context.
+ * labelLen   The length of the label.
+ * msg        The message data to derive key from.
+ * msgLen     The length of the message data to derive key from.
+ * hashAlgo   The hash algorithm to use in the HMAC.
+ * returns 0 on success, otherwise failure.
+ */
+static int DeriveKeyMsg(WOLFSSL* ssl, byte* output, int outputLen,
+                        const byte* secret, const byte* label, word32 labelLen,
+                        byte* msg, int msgLen, int hashAlgo)
+{
+    byte        hash[WC_MAX_DIGEST_SIZE];
+    Digest      digest;
+    word32      hashSz = 0;
+    const byte* protocol;
+    word32      protocolLen;
+    int         digestAlg = -1;
+    int         ret = BAD_FUNC_ARG;
+
+    switch (hashAlgo) {
+#ifndef NO_WOLFSSL_SHA256
+        case sha256_mac:
+            ret = wc_InitSha256_ex(&digest.sha256, ssl->heap, INVALID_DEVID);
+            if (ret == 0) {
+                    ret = wc_Sha256Update(&digest.sha256, msg, msgLen);
+                if (ret == 0)
+                    ret = wc_Sha256Final(&digest.sha256, hash);
+                wc_Sha256Free(&digest.sha256);
+            }
+            hashSz = WC_SHA256_DIGEST_SIZE;
+            digestAlg = WC_SHA256;
+            break;
+#endif
+#ifdef WOLFSSL_SHA384
+        case sha384_mac:
+            ret = wc_InitSha384_ex(&digest.sha384, ssl->heap, INVALID_DEVID);
+            if (ret == 0) {
+                ret = wc_Sha384Update(&digest.sha384, msg, msgLen);
+                if (ret == 0)
+                    ret = wc_Sha384Final(&digest.sha384, hash);
+                wc_Sha384Free(&digest.sha384);
+            }
+            hashSz = WC_SHA384_DIGEST_SIZE;
+            digestAlg = WC_SHA384;
+            break;
+#endif
+#ifdef WOLFSSL_TLS13_SHA512
+        case sha512_mac:
+            ret = wc_InitSha512_ex(&digest.sha512, ssl->heap, INVALID_DEVID);
+            if (ret == 0) {
+                ret = wc_Sha512Update(&digest.sha512, msg, msgLen);
+                if (ret == 0)
+                    ret = wc_Sha512Final(&digest.sha512, hash);
+                wc_Sha512Free(&digest.sha512);
+            }
+            hashSz = WC_SHA512_DIGEST_SIZE;
+            digestAlg = WC_SHA512;
+            break;
+#endif
+        default:
+            digestAlg = -1;
+            break;
+    }
+
+    if (digestAlg < 0)
+        return HASH_TYPE_E;
+
+    if (ret != 0)
+        return ret;
+
+    switch (ssl->version.minor) {
+        case TLSv1_3_MINOR:
+            protocol = tls13ProtocolLabel;
+            protocolLen = TLS13_PROTOCOL_LABEL_SZ;
+            break;
+
+        default:
+            return VERSION_ERROR;
+    }
+    if (outputLen == -1)
+        outputLen = hashSz;
+
+    return HKDF_Expand_Label(output, outputLen, secret, hashSz,
+                             protocol, protocolLen, label, labelLen,
+                             hash, hashSz, digestAlg);
+}
+#endif
+
+/* Derive a key.
+ *
+ * ssl          The SSL/TLS object.
+ * output       The buffer to hold the derived key.
+ * outputLen    The length of the derived key.
+ * secret       The secret used to derive the key (HMAC secret).
+ * label        The label used to distinguish the context.
+ * labelLen     The length of the label.
+ * hashAlgo     The hash algorithm to use in the HMAC.
+ * includeMsgs  Whether to include a hash of the handshake messages so far.
+ * returns 0 on success, otherwise failure.
+ */
+static int DeriveKey(WOLFSSL* ssl, byte* output, int outputLen,
+                     const byte* secret, const byte* label, word32 labelLen,
+                     int hashAlgo, int includeMsgs)
+{
+    int         ret = 0;
+    byte        hash[WC_MAX_DIGEST_SIZE];
+    word32      hashSz = 0;
+    word32      hashOutSz = 0;
+    const byte* protocol;
+    word32      protocolLen;
+    int         digestAlg = 0;
+
+    switch (hashAlgo) {
+        #ifndef NO_SHA256
+            case sha256_mac:
+                hashSz    = WC_SHA256_DIGEST_SIZE;
+                digestAlg = WC_SHA256;
+                if (includeMsgs)
+                    ret = wc_Sha256GetHash(&ssl->hsHashes->hashSha256, hash);
+            break;
+        #endif
+
+        #ifdef WOLFSSL_SHA384
+            case sha384_mac:
+                hashSz    = WC_SHA384_DIGEST_SIZE;
+                digestAlg = WC_SHA384;
+                if (includeMsgs)
+                    ret = wc_Sha384GetHash(&ssl->hsHashes->hashSha384, hash);
+            break;
+        #endif
+
+        #ifdef WOLFSSL_TLS13_SHA512
+            case sha512_mac:
+                hashSz    = WC_SHA512_DIGEST_SIZE;
+                digestAlg = WC_SHA512;
+                if (includeMsgs)
+                    ret = wc_Sha512GetHash(&ssl->hsHashes->hashSha512, hash);
+            break;
+        #endif
+    }
+    if (ret != 0)
+        return ret;
+
+    /* Only one protocol version defined at this time. */
+    protocol = tls13ProtocolLabel;
+    protocolLen = TLS13_PROTOCOL_LABEL_SZ;
+
+    if (outputLen == -1)
+        outputLen = hashSz;
+    if (includeMsgs)
+        hashOutSz = hashSz;
+
+    return HKDF_Expand_Label(output, outputLen, secret, hashSz,
+                             protocol, protocolLen, label, labelLen,
+                             hash, hashOutSz, digestAlg);
+}
+
+#ifndef NO_PSK
+#ifdef WOLFSSL_TLS13_DRAFT_18
+/* The length of the binder key label. */
+#define BINDER_KEY_LABEL_SZ         23
+/* The binder key label. */
+static const byte binderKeyLabel[BINDER_KEY_LABEL_SZ + 1] =
+    "external psk binder key";
+#else
+/* The length of the binder key label. */
+#define BINDER_KEY_LABEL_SZ         10
+/* The binder key label. */
+static const byte binderKeyLabel[BINDER_KEY_LABEL_SZ + 1] =
+    "ext binder";
+#endif
+/* Derive the binder key.
+ *
+ * ssl  The SSL/TLS object.
+ * key  The derived key.
+ * returns 0 on success, otherwise failure.
+ */
+static int DeriveBinderKey(WOLFSSL* ssl, byte* key)
+{
+    WOLFSSL_MSG("Derive Binder Key");
+    return DeriveKeyMsg(ssl, key, -1, ssl->arrays->secret,
+                        binderKeyLabel, BINDER_KEY_LABEL_SZ,
+                        NULL, 0, ssl->specs.mac_algorithm);
+}
+#endif /* !NO_PSK */
+
+#ifdef HAVE_SESSION_TICKET
+#ifdef WOLFSSL_TLS13_DRAFT_18
+/* The length of the binder key resume label. */
+#define BINDER_KEY_RESUME_LABEL_SZ  25
+/* The binder key resume label. */
+static const byte binderKeyResumeLabel[BINDER_KEY_RESUME_LABEL_SZ + 1] =
+    "resumption psk binder key";
+#else
+/* The length of the binder key resume label. */
+#define BINDER_KEY_RESUME_LABEL_SZ  10
+/* The binder key resume label. */
+static const byte binderKeyResumeLabel[BINDER_KEY_RESUME_LABEL_SZ + 1] =
+    "res binder";
+#endif
+/* Derive the binder resumption key.
+ *
+ * ssl  The SSL/TLS object.
+ * key  The derived key.
+ * returns 0 on success, otherwise failure.
+ */
+static int DeriveBinderKeyResume(WOLFSSL* ssl, byte* key)
+{
+    WOLFSSL_MSG("Derive Binder Key - Resumption");
+    return DeriveKeyMsg(ssl, key, -1, ssl->arrays->secret,
+                        binderKeyResumeLabel, BINDER_KEY_RESUME_LABEL_SZ,
+                        NULL, 0, ssl->specs.mac_algorithm);
+}
+#endif /* HAVE_SESSION_TICKET */
+
+#ifdef WOLFSSL_EARLY_DATA
+#ifdef WOLFSSL_TLS13_DRAFT_18
+/* The length of the early traffic label. */
+#define EARLY_TRAFFIC_LABEL_SZ      27
+/* The early traffic label. */
+static const byte earlyTrafficLabel[EARLY_TRAFFIC_LABEL_SZ + 1] =
+    "client early traffic secret";
+#else
+/* The length of the early traffic label. */
+#define EARLY_TRAFFIC_LABEL_SZ      11
+/* The early traffic label. */
+static const byte earlyTrafficLabel[EARLY_TRAFFIC_LABEL_SZ + 1] =
+    "c e traffic";
+#endif
+/* Derive the early traffic key.
+ *
+ * ssl  The SSL/TLS object.
+ * key  The derived key.
+ * returns 0 on success, otherwise failure.
+ */
+static int DeriveEarlyTrafficSecret(WOLFSSL* ssl, byte* key)
+{
+    int ret;
+    WOLFSSL_MSG("Derive Early Traffic Secret");
+    ret = DeriveKey(ssl, key, -1, ssl->arrays->secret,
+                    earlyTrafficLabel, EARLY_TRAFFIC_LABEL_SZ,
+                    ssl->specs.mac_algorithm, 1);
+#ifdef HAVE_SECRET_CALLBACK
+    if (ret == 0 && ssl->tls13SecretCb != NULL) {
+        ret = ssl->tls13SecretCb(ssl, CLIENT_EARLY_TRAFFIC_SECRET, key,
+                                 ssl->specs.hash_size, ssl->tls13SecretCtx);
+        if (ret != 0) {
+            return TLS13_SECRET_CB_E;
+        }
+    }
+#endif /* HAVE_SECRET_CALLBACK */
+    return ret;
+}
+
+#ifdef TLS13_SUPPORTS_EXPORTERS
+#ifdef WOLFSSL_TLS13_DRAFT_18
+/* The length of the early exporter label. */
+#define EARLY_EXPORTER_LABEL_SZ     28
+/* The early exporter label. */
+static const byte earlyExporterLabel[EARLY_EXPORTER_LABEL_SZ + 1] =
+    "early exporter master secret";
+#else
+/* The length of the early exporter label. */
+#define EARLY_EXPORTER_LABEL_SZ     12
+/* The early exporter label. */
+static const byte earlyExporterLabel[EARLY_EXPORTER_LABEL_SZ + 1] =
+    "e exp master";
+#endif
+/* Derive the early exporter key.
+ *
+ * ssl  The SSL/TLS object.
+ * key  The derived key.
+ * returns 0 on success, otherwise failure.
+ */
+static int DeriveEarlyExporterSecret(WOLFSSL* ssl, byte* key)
+{
+    int ret;
+    WOLFSSL_MSG("Derive Early Exporter Secret");
+    ret = DeriveKey(ssl, key, -1, ssl->arrays->secret,
+                    earlyExporterLabel, EARLY_EXPORTER_LABEL_SZ,
+                    ssl->specs.mac_algorithm, 1);
+#ifdef HAVE_SECRET_CALLBACK
+    if (ret == 0 && ssl->tls13SecretCb != NULL) {
+        ret = ssl->tls13SecretCb(ssl, EARLY_EXPORTER_SECRET, key
+                                 ssl->specs.hash_size, ssl->tls13SecretCtx);
+        if (ret != 0) {
+            return TLS13_SECRET_CB_E;
+        }
+    }
+#endif /* HAVE_SECRET_CALLBACK */
+    return ret;
+}
+#endif
+#endif
+
+#ifdef WOLFSSL_TLS13_DRAFT_18
+/* The length of the client handshake label. */
+#define CLIENT_HANDSHAKE_LABEL_SZ   31
+/* The client handshake label. */
+static const byte clientHandshakeLabel[CLIENT_HANDSHAKE_LABEL_SZ + 1] =
+    "client handshake traffic secret";
+#else
+/* The length of the client handshake label. */
+#define CLIENT_HANDSHAKE_LABEL_SZ   12
+/* The client handshake label. */
+static const byte clientHandshakeLabel[CLIENT_HANDSHAKE_LABEL_SZ + 1] =
+    "c hs traffic";
+#endif
+/* Derive the client handshake key.
+ *
+ * ssl  The SSL/TLS object.
+ * key  The derived key.
+ * returns 0 on success, otherwise failure.
+ */
+static int DeriveClientHandshakeSecret(WOLFSSL* ssl, byte* key)
+{
+    int ret;
+    WOLFSSL_MSG("Derive Client Handshake Secret");
+    ret = DeriveKey(ssl, key, -1, ssl->arrays->preMasterSecret,
+                    clientHandshakeLabel, CLIENT_HANDSHAKE_LABEL_SZ,
+                    ssl->specs.mac_algorithm, 1);
+#ifdef HAVE_SECRET_CALLBACK
+    if (ret == 0 && ssl->tls13SecretCb != NULL) {
+        ret = ssl->tls13SecretCb(ssl, CLIENT_HANDSHAKE_TRAFFIC_SECRET, key,
+                                 ssl->specs.hash_size, ssl->tls13SecretCtx);
+        if (ret != 0) {
+            return TLS13_SECRET_CB_E;
+        }
+    }
+#endif /* HAVE_SECRET_CALLBACK */
+    return ret;
+}
+
+#ifdef WOLFSSL_TLS13_DRAFT_18
+/* The length of the server handshake label. */
+#define SERVER_HANDSHAKE_LABEL_SZ   31
+/* The server handshake label. */
+static const byte serverHandshakeLabel[SERVER_HANDSHAKE_LABEL_SZ + 1] =
+    "server handshake traffic secret";
+#else
+/* The length of the server handshake label. */
+#define SERVER_HANDSHAKE_LABEL_SZ   12
+/* The server handshake label. */
+static const byte serverHandshakeLabel[SERVER_HANDSHAKE_LABEL_SZ + 1] =
+    "s hs traffic";
+#endif
+/* Derive the server handshake key.
+ *
+ * ssl  The SSL/TLS object.
+ * key  The derived key.
+ * returns 0 on success, otherwise failure.
+ */
+static int DeriveServerHandshakeSecret(WOLFSSL* ssl, byte* key)
+{
+    int ret;
+    WOLFSSL_MSG("Derive Server Handshake Secret");
+    ret = DeriveKey(ssl, key, -1, ssl->arrays->preMasterSecret,
+                    serverHandshakeLabel, SERVER_HANDSHAKE_LABEL_SZ,
+                    ssl->specs.mac_algorithm, 1);
+#ifdef HAVE_SECRET_CALLBACK
+    if (ret == 0 && ssl->tls13SecretCb != NULL) {
+        ret = ssl->tls13SecretCb(ssl, SERVER_HANDSHAKE_TRAFFIC_SECRET, key,
+                                 ssl->specs.hash_size, ssl->tls13SecretCtx);
+        if (ret != 0) {
+            return TLS13_SECRET_CB_E;
+        }
+    }
+#endif /* HAVE_SECRET_CALLBACK */
+    return ret;
+}
+
+#ifdef WOLFSSL_TLS13_DRAFT_18
+/* The length of the client application traffic label. */
+#define CLIENT_APP_LABEL_SZ         33
+/* The client application traffic label. */
+static const byte clientAppLabel[CLIENT_APP_LABEL_SZ + 1] =
+    "client application traffic secret";
+#else
+/* The length of the client application traffic label. */
+#define CLIENT_APP_LABEL_SZ         12
+/* The client application traffic label. */
+static const byte clientAppLabel[CLIENT_APP_LABEL_SZ + 1] =
+    "c ap traffic";
+#endif
+/* Derive the client application traffic key.
+ *
+ * ssl  The SSL/TLS object.
+ * key  The derived key.
+ * returns 0 on success, otherwise failure.
+ */
+static int DeriveClientTrafficSecret(WOLFSSL* ssl, byte* key)
+{
+    int ret;
+    WOLFSSL_MSG("Derive Client Traffic Secret");
+    ret = DeriveKey(ssl, key, -1, ssl->arrays->masterSecret,
+                    clientAppLabel, CLIENT_APP_LABEL_SZ,
+                    ssl->specs.mac_algorithm, 1);
+#ifdef HAVE_SECRET_CALLBACK
+    if (ret == 0 && ssl->tls13SecretCb != NULL) {
+        ret = ssl->tls13SecretCb(ssl, CLIENT_TRAFFIC_SECRET, key,
+                                 ssl->specs.hash_size, ssl->tls13SecretCtx);
+        if (ret != 0) {
+            return TLS13_SECRET_CB_E;
+        }
+    }
+#endif /* HAVE_SECRET_CALLBACK */
+    return ret;
+}
+
+#ifdef WOLFSSL_TLS13_DRAFT_18
+/* The length of the server application traffic label. */
+#define SERVER_APP_LABEL_SZ         33
+/* The  server application traffic label. */
+static const byte serverAppLabel[SERVER_APP_LABEL_SZ + 1] =
+    "server application traffic secret";
+#else
+/* The length of the server application traffic label. */
+#define SERVER_APP_LABEL_SZ         12
+/* The  server application traffic label. */
+static const byte serverAppLabel[SERVER_APP_LABEL_SZ + 1] =
+    "s ap traffic";
+#endif
+/* Derive the server application traffic key.
+ *
+ * ssl  The SSL/TLS object.
+ * key  The derived key.
+ * returns 0 on success, otherwise failure.
+ */
+static int DeriveServerTrafficSecret(WOLFSSL* ssl, byte* key)
+{
+    int ret;
+    WOLFSSL_MSG("Derive Server Traffic Secret");
+    ret = DeriveKey(ssl, key, -1, ssl->arrays->masterSecret,
+                    serverAppLabel, SERVER_APP_LABEL_SZ,
+                    ssl->specs.mac_algorithm, 1);
+#ifdef HAVE_SECRET_CALLBACK
+    if (ret == 0 && ssl->tls13SecretCb != NULL) {
+        ret = ssl->tls13SecretCb(ssl, SERVER_TRAFFIC_SECRET, key,
+                                 ssl->specs.hash_size, ssl->tls13SecretCtx);
+        if (ret != 0) {
+            return TLS13_SECRET_CB_E;
+        }
+    }
+#endif /* HAVE_SECRET_CALLBACK */
+    return ret;
+}
+
+#ifdef TLS13_SUPPORTS_EXPORTERS
+#ifdef WOLFSSL_TLS13_DRAFT_18
+/* The length of the exporter master secret label. */
+#define EXPORTER_MASTER_LABEL_SZ    22
+/* The exporter master secret label. */
+static const byte exporterMasterLabel[EXPORTER_MASTER_LABEL_SZ + 1] =
+    "exporter master secret";
+#else
+/* The length of the exporter master secret label. */
+#define EXPORTER_MASTER_LABEL_SZ    10
+/* The exporter master secret label. */
+static const byte exporterMasterLabel[EXPORTER_MASTER_LABEL_SZ + 1] =
+    "exp master";
+#endif
+/* Derive the exporter secret.
+ *
+ * ssl  The SSL/TLS object.
+ * key  The derived key.
+ * returns 0 on success, otherwise failure.
+ */
+static int DeriveExporterSecret(WOLFSSL* ssl, byte* key)
+{
+    int ret;
+    WOLFSSL_MSG("Derive Exporter Secret");
+    ret = DeriveKey(ssl, key, -1, ssl->arrays->masterSecret,
+                    exporterMasterLabel, EXPORTER_MASTER_LABEL_SZ,
+                    ssl->specs.mac_algorithm, 1);
+#ifdef HAVE_SECRET_CALLBACK
+    if (ret == 0 && ssl->tls13SecretCb != NULL) {
+        ret = ssl->tls13SecretCb(ssl, EXPORTER_SECRET, key,
+                                 ssl->specs.hash_size, ssl->tls13SecretCtx);
+        if (ret != 0) {
+            return TLS13_SECRET_CB_E;
+        }
+    }
+#endif /* HAVE_SECRET_CALLBACK */
+    return ret;
+}
+#endif
+
+#if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
+#ifdef WOLFSSL_TLS13_DRAFT_18
+/* The length of the resumption master secret label. */
+#define RESUME_MASTER_LABEL_SZ      24
+/* The resumption master secret label. */
+static const byte resumeMasterLabel[RESUME_MASTER_LABEL_SZ + 1] =
+    "resumption master secret";
+#else
+/* The length of the resumption master secret label. */
+#define RESUME_MASTER_LABEL_SZ      10
+/* The resumption master secret label. */
+static const byte resumeMasterLabel[RESUME_MASTER_LABEL_SZ + 1] =
+    "res master";
+#endif
+/* Derive the resumption secret.
+ *
+ * ssl  The SSL/TLS object.
+ * key  The derived key.
+ * returns 0 on success, otherwise failure.
+ */
+static int DeriveResumptionSecret(WOLFSSL* ssl, byte* key)
+{
+    WOLFSSL_MSG("Derive Resumption Secret");
+    return DeriveKey(ssl, key, -1, ssl->arrays->masterSecret,
+                     resumeMasterLabel, RESUME_MASTER_LABEL_SZ,
+                     ssl->specs.mac_algorithm, 1);
+}
+#endif
+
+/* Length of the finished label. */
+#define FINISHED_LABEL_SZ           8
+/* Finished label for generating finished key. */
+static const byte finishedLabel[FINISHED_LABEL_SZ+1] = "finished";
+/* Derive the finished secret.
+ *
+ * ssl     The SSL/TLS object.
+ * key     The key to use with the HMAC.
+ * secret  The derived secret.
+ * returns 0 on success, otherwise failure.
+ */
+static int DeriveFinishedSecret(WOLFSSL* ssl, byte* key, byte* secret)
+{
+    WOLFSSL_MSG("Derive Finished Secret");
+    return DeriveKey(ssl, secret, -1, key, finishedLabel, FINISHED_LABEL_SZ,
+                     ssl->specs.mac_algorithm, 0);
+}
+
+#ifdef WOLFSSL_TLS13_DRAFT_18
+/* The length of the application traffic label. */
+#define APP_TRAFFIC_LABEL_SZ        26
+/* The application traffic label. */
+static const byte appTrafficLabel[APP_TRAFFIC_LABEL_SZ + 1] =
+    "application traffic secret";
+#else
+/* The length of the application traffic label. */
+#define APP_TRAFFIC_LABEL_SZ        11
+/* The application traffic label. */
+static const byte appTrafficLabel[APP_TRAFFIC_LABEL_SZ + 1] =
+    "traffic upd";
+#endif
+/* Update the traffic secret.
+ *
+ * ssl     The SSL/TLS object.
+ * secret  The previous secret and derived secret.
+ * returns 0 on success, otherwise failure.
+ */
+static int DeriveTrafficSecret(WOLFSSL* ssl, byte* secret)
+{
+    WOLFSSL_MSG("Derive New Application Traffic Secret");
+    return DeriveKey(ssl, secret, -1, secret,
+                     appTrafficLabel, APP_TRAFFIC_LABEL_SZ,
+                     ssl->specs.mac_algorithm, 0);
+}
+
+/* Derive the early secret using HKDF Extract.
+ *
+ * ssl  The SSL/TLS object.
+ */
+static int DeriveEarlySecret(WOLFSSL* ssl)
+{
+    WOLFSSL_MSG("Derive Early Secret");
+#if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
+    return Tls13_HKDF_Extract(ssl->arrays->secret, NULL, 0,
+            ssl->arrays->psk_key, ssl->arrays->psk_keySz,
+            ssl->specs.mac_algorithm);
+#else
+    return Tls13_HKDF_Extract(ssl->arrays->secret, NULL, 0,
+            ssl->arrays->masterSecret, 0, ssl->specs.mac_algorithm);
+#endif
+}
+
+#ifndef WOLFSSL_TLS13_DRAFT_18
+/* The length of the derived label. */
+#define DERIVED_LABEL_SZ        7
+/* The derived label. */
+static const byte derivedLabel[DERIVED_LABEL_SZ + 1] =
+    "derived";
+#endif
+/* Derive the handshake secret using HKDF Extract.
+ *
+ * ssl  The SSL/TLS object.
+ */
+static int DeriveHandshakeSecret(WOLFSSL* ssl)
+{
+#ifdef WOLFSSL_TLS13_DRAFT_18
+    WOLFSSL_MSG("Derive Handshake Secret");
+    return Tls13_HKDF_Extract(ssl->arrays->preMasterSecret,
+            ssl->arrays->secret, ssl->specs.hash_size,
+            ssl->arrays->preMasterSecret, ssl->arrays->preMasterSz,
+            ssl->specs.mac_algorithm);
+#else
+    byte key[WC_MAX_DIGEST_SIZE];
+    int ret;
+
+    WOLFSSL_MSG("Derive Handshake Secret");
+
+    ret = DeriveKeyMsg(ssl, key, -1, ssl->arrays->secret,
+                        derivedLabel, DERIVED_LABEL_SZ,
+                        NULL, 0, ssl->specs.mac_algorithm);
+    if (ret != 0)
+        return ret;
+
+    return Tls13_HKDF_Extract(ssl->arrays->preMasterSecret,
+            key, ssl->specs.hash_size,
+            ssl->arrays->preMasterSecret, ssl->arrays->preMasterSz,
+            ssl->specs.mac_algorithm);
+#endif
+}
+
+/* Derive the master secret using HKDF Extract.
+ *
+ * ssl  The SSL/TLS object.
+ */
+static int DeriveMasterSecret(WOLFSSL* ssl)
+{
+#ifdef WOLFSSL_TLS13_DRAFT_18
+    WOLFSSL_MSG("Derive Master Secret");
+    return Tls13_HKDF_Extract(ssl->arrays->masterSecret,
+            ssl->arrays->preMasterSecret, ssl->specs.hash_size,
+            ssl->arrays->masterSecret, 0, ssl->specs.mac_algorithm);
+#else
+    byte key[WC_MAX_DIGEST_SIZE];
+    int ret;
+
+    WOLFSSL_MSG("Derive Master Secret");
+
+    ret = DeriveKeyMsg(ssl, key, -1, ssl->arrays->preMasterSecret,
+                        derivedLabel, DERIVED_LABEL_SZ,
+                        NULL, 0, ssl->specs.mac_algorithm);
+    if (ret != 0)
+        return ret;
+
+    return Tls13_HKDF_Extract(ssl->arrays->masterSecret,
+            key, ssl->specs.hash_size,
+            ssl->arrays->masterSecret, 0, ssl->specs.mac_algorithm);
+#endif
+}
+
+#ifndef WOLFSSL_TLS13_DRAFT_18
+#if defined(HAVE_SESSION_TICKET)
+/* Length of the resumption label. */
+#define RESUMPTION_LABEL_SZ         10
+/* Resumption label for generating PSK associated with the ticket. */
+static const byte resumptionLabel[RESUMPTION_LABEL_SZ+1] = "resumption";
+/* Derive the PSK associated with the ticket.
+ *
+ * ssl       The SSL/TLS object.
+ * nonce     The nonce to derive with.
+ * nonceLen  The length of the nonce to derive with.
+ * secret    The derived secret.
+ * returns 0 on success, otherwise failure.
+ */
+static int DeriveResumptionPSK(WOLFSSL* ssl, byte* nonce, byte nonceLen,
+                               byte* secret)
+{
+    int         digestAlg;
+    /* Only one protocol version defined at this time. */
+    const byte* protocol    = tls13ProtocolLabel;
+    word32      protocolLen = TLS13_PROTOCOL_LABEL_SZ;
+
+    WOLFSSL_MSG("Derive Resumption PSK");
+
+    switch (ssl->specs.mac_algorithm) {
+        #ifndef NO_SHA256
+        case sha256_mac:
+            digestAlg = WC_SHA256;
+            break;
+        #endif
+
+        #ifdef WOLFSSL_SHA384
+        case sha384_mac:
+            digestAlg = WC_SHA384;
+            break;
+        #endif
+
+        #ifdef WOLFSSL_TLS13_SHA512
+        case sha512_mac:
+            digestAlg = WC_SHA512;
+            break;
+        #endif
+
+        default:
+            return BAD_FUNC_ARG;
+    }
+
+    return HKDF_Expand_Label(secret, ssl->specs.hash_size,
+                             ssl->session.masterSecret, ssl->specs.hash_size,
+                             protocol, protocolLen, resumptionLabel,
+                             RESUMPTION_LABEL_SZ, nonce, nonceLen, digestAlg);
+}
+#endif /* HAVE_SESSION_TICKET */
+#endif /* WOLFSSL_TLS13_DRAFT_18 */
+
+
+/* Calculate the HMAC of message data to this point.
+ *
+ * ssl   The SSL/TLS object.
+ * key   The HMAC key.
+ * hash  The hash result - verify data.
+ * returns length of verify data generated.
+ */
+static int BuildTls13HandshakeHmac(WOLFSSL* ssl, byte* key, byte* hash,
+    word32* pHashSz)
+{
+    Hmac verifyHmac;
+    int  hashType = WC_SHA256;
+    int  hashSz = WC_SHA256_DIGEST_SIZE;
+    int  ret = BAD_FUNC_ARG;
+
+    /* Get the hash of the previous handshake messages. */
+    switch (ssl->specs.mac_algorithm) {
+    #ifndef NO_SHA256
+        case sha256_mac:
+            hashType = WC_SHA256;
+            hashSz = WC_SHA256_DIGEST_SIZE;
+            ret = wc_Sha256GetHash(&ssl->hsHashes->hashSha256, hash);
+            break;
+    #endif /* !NO_SHA256 */
+    #ifdef WOLFSSL_SHA384
+        case sha384_mac:
+            hashType = WC_SHA384;
+            hashSz = WC_SHA384_DIGEST_SIZE;
+            ret = wc_Sha384GetHash(&ssl->hsHashes->hashSha384, hash);
+            break;
+    #endif /* WOLFSSL_SHA384 */
+    #ifdef WOLFSSL_TLS13_SHA512
+        case sha512_mac:
+            hashType = WC_SHA512;
+            hashSz = WC_SHA512_DIGEST_SIZE;
+            ret = wc_Sha512GetHash(&ssl->hsHashes->hashSha512, hash);
+            break;
+    #endif /* WOLFSSL_TLS13_SHA512 */
+    }
+    if (ret != 0)
+        return ret;
+
+    /* Calculate the verify data. */
+    ret = wc_HmacInit(&verifyHmac, ssl->heap, ssl->devId);
+    if (ret == 0) {
+        ret = wc_HmacSetKey(&verifyHmac, hashType, key, ssl->specs.hash_size);
+        if (ret == 0)
+            ret = wc_HmacUpdate(&verifyHmac, hash, hashSz);
+        if (ret == 0)
+            ret = wc_HmacFinal(&verifyHmac, hash);
+        wc_HmacFree(&verifyHmac);
+    }
+
+    if (pHashSz)
+        *pHashSz = hashSz;
+
+    return ret;
+}
+
+/* The length of the label to use when deriving keys. */
+#define WRITE_KEY_LABEL_SZ     3
+/* The length of the label to use when deriving IVs. */
+#define WRITE_IV_LABEL_SZ      2
+/* The label to use when deriving keys. */
+static const byte writeKeyLabel[WRITE_KEY_LABEL_SZ+1] = "key";
+/* The label to use when deriving IVs. */
+static const byte writeIVLabel[WRITE_IV_LABEL_SZ+1]   = "iv";
+
+/* Derive the keys and IVs for TLS v1.3.
+ *
+ * ssl      The SSL/TLS object.
+ * sercret  early_data_key when deriving the key and IV for encrypting early
+ *          data application data and end_of_early_data messages.
+ *          handshake_key when deriving keys and IVs for encrypting handshake
+ *          messages.
+ *          traffic_key when deriving first keys and IVs for encrypting
+ *          traffic messages.
+ *          update_traffic_key when deriving next keys and IVs for encrypting
+ *          traffic messages.
+ * side     ENCRYPT_SIDE_ONLY when only encryption secret needs to be derived.
+ *          DECRYPT_SIDE_ONLY when only decryption secret needs to be derived.
+ *          ENCRYPT_AND_DECRYPT_SIDE when both secret needs to be derived.
+ * store    1 indicates to derive the keys and IVs from derived secret and
+ *          store ready for provisioning.
+ * returns 0 on success, otherwise failure.
+ */
+static int DeriveTls13Keys(WOLFSSL* ssl, int secret, int side, int store)
+{
+    int   ret = BAD_FUNC_ARG; /* Assume failure */
+    int   i = 0;
+#ifdef WOLFSSL_SMALL_STACK
+    byte* key_dig;
+#else
+    byte  key_dig[MAX_PRF_DIG];
+#endif
+    int   provision;
+
+#ifdef WOLFSSL_SMALL_STACK
+    key_dig = (byte*)XMALLOC(MAX_PRF_DIG, ssl->heap, DYNAMIC_TYPE_DIGEST);
+    if (key_dig == NULL)
+        return MEMORY_E;
+#endif
+
+    if (side == ENCRYPT_AND_DECRYPT_SIDE) {
+        provision = PROVISION_CLIENT_SERVER;
+    }
+    else {
+        provision = ((ssl->options.side != WOLFSSL_CLIENT_END) ^
+                     (side == ENCRYPT_SIDE_ONLY)) ? PROVISION_CLIENT :
+                                                    PROVISION_SERVER;
+    }
+
+    /* Derive the appropriate secret to use in the HKDF. */
+    switch (secret) {
+#ifdef WOLFSSL_EARLY_DATA
+        case early_data_key:
+            ret = DeriveEarlyTrafficSecret(ssl, ssl->clientSecret);
+            if (ret != 0)
+                goto end;
+            break;
+#endif
+
+        case handshake_key:
+            if (provision & PROVISION_CLIENT) {
+                ret = DeriveClientHandshakeSecret(ssl,
+                                                  ssl->clientSecret);
+                if (ret != 0)
+                    goto end;
+            }
+            if (provision & PROVISION_SERVER) {
+                ret = DeriveServerHandshakeSecret(ssl,
+                                                  ssl->serverSecret);
+                if (ret != 0)
+                    goto end;
+            }
+            break;
+
+        case traffic_key:
+            if (provision & PROVISION_CLIENT) {
+                ret = DeriveClientTrafficSecret(ssl, ssl->clientSecret);
+                if (ret != 0)
+                    goto end;
+            }
+            if (provision & PROVISION_SERVER) {
+                ret = DeriveServerTrafficSecret(ssl, ssl->serverSecret);
+                if (ret != 0)
+                    goto end;
+            }
+            break;
+
+        case update_traffic_key:
+            if (provision & PROVISION_CLIENT) {
+                ret = DeriveTrafficSecret(ssl, ssl->clientSecret);
+                if (ret != 0)
+                    goto end;
+            }
+            if (provision & PROVISION_SERVER) {
+                ret = DeriveTrafficSecret(ssl, ssl->serverSecret);
+                if (ret != 0)
+                    goto end;
+            }
+            break;
+    }
+
+    if (!store)
+        goto end;
+
+    /* Key data = client key | server key | client IV | server IV */
+
+    if (provision & PROVISION_CLIENT) {
+        /* Derive the client key.  */
+        WOLFSSL_MSG("Derive Client Key");
+        ret = DeriveKey(ssl, &key_dig[i], ssl->specs.key_size,
+                        ssl->clientSecret, writeKeyLabel,
+                        WRITE_KEY_LABEL_SZ, ssl->specs.mac_algorithm, 0);
+        if (ret != 0)
+            goto end;
+        i += ssl->specs.key_size;
+    }
+
+    if (provision & PROVISION_SERVER) {
+        /* Derive the server key.  */
+        WOLFSSL_MSG("Derive Server Key");
+        ret = DeriveKey(ssl, &key_dig[i], ssl->specs.key_size,
+                        ssl->serverSecret, writeKeyLabel,
+                        WRITE_KEY_LABEL_SZ, ssl->specs.mac_algorithm, 0);
+        if (ret != 0)
+            goto end;
+        i += ssl->specs.key_size;
+    }
+
+    if (provision & PROVISION_CLIENT) {
+        /* Derive the client IV.  */
+        WOLFSSL_MSG("Derive Client IV");
+        ret = DeriveKey(ssl, &key_dig[i], ssl->specs.iv_size,
+                        ssl->clientSecret, writeIVLabel,
+                        WRITE_IV_LABEL_SZ, ssl->specs.mac_algorithm, 0);
+        if (ret != 0)
+            goto end;
+        i += ssl->specs.iv_size;
+    }
+
+    if (provision & PROVISION_SERVER) {
+        /* Derive the server IV.  */
+        WOLFSSL_MSG("Derive Server IV");
+        ret = DeriveKey(ssl, &key_dig[i], ssl->specs.iv_size,
+                        ssl->serverSecret, writeIVLabel,
+                        WRITE_IV_LABEL_SZ, ssl->specs.mac_algorithm, 0);
+        if (ret != 0)
+            goto end;
+    }
+
+    /* Store keys and IVs but don't activate them. */
+    ret = StoreKeys(ssl, key_dig, provision);
+
+end:
+#ifdef WOLFSSL_SMALL_STACK
+    XFREE(key_dig, ssl->heap, DYNAMIC_TYPE_DIGEST);
+#endif
+
+    return ret;
+}
+
+#ifdef HAVE_SESSION_TICKET
+#if defined(USER_TICKS)
+#if 0
+    word32 TimeNowInMilliseconds(void)
+    {
+        /*
+        write your own clock tick function if don't want gettimeofday()
+        needs millisecond accuracy but doesn't have to correlated to EPOCH
+        */
+    }
+#endif
+
+#elif defined(TIME_OVERRIDES)
+    #ifndef HAVE_TIME_T_TYPE
+        typedef long time_t;
+    #endif
+    extern time_t XTIME(time_t * timer);
+
+    /* The time in milliseconds.
+     * Used for tickets to represent difference between when first seen and when
+     * sending.
+     *
+     * returns the time in milliseconds as a 32-bit value.
+     */
+    word32 TimeNowInMilliseconds(void)
+    {
+        return (word32) XTIME(0) * 1000;
+    }
+
+#elif defined(XTIME_MS)
+    word32 TimeNowInMilliseconds(void)
+    {
+        return (word32)XTIME_MS(0);
+    }
+
+#elif defined(USE_WINDOWS_API)
+    /* The time in milliseconds.
+     * Used for tickets to represent difference between when first seen and when
+     * sending.
+     *
+     * returns the time in milliseconds as a 32-bit value.
+     */
+    word32 TimeNowInMilliseconds(void)
+    {
+        static int           init = 0;
+        static LARGE_INTEGER freq;
+        LARGE_INTEGER        count;
+
+        if (!init) {
+            QueryPerformanceFrequency(&freq);
+            init = 1;
+        }
+
+        QueryPerformanceCounter(&count);
+
+        return (word32)(count.QuadPart / (freq.QuadPart / 1000));
+    }
+
+#elif defined(HAVE_RTP_SYS)
+    #include "rtptime.h"
+
+    /* The time in milliseconds.
+     * Used for tickets to represent difference between when first seen and when
+     * sending.
+     *
+     * returns the time in milliseconds as a 32-bit value.
+     */
+    word32 TimeNowInMilliseconds(void)
+    {
+        return (word32)rtp_get_system_sec() * 1000;
+    }
+#elif defined(WOLFSSL_DEOS)
+    word32 TimeNowInMilliseconds(void)
+    {
+        const uint32_t systemTickTimeInHz = 1000000 / systemTickInMicroseconds();
+        uint32_t *systemTickPtr = systemTickPointer();
+
+        return (word32) (*systemTickPtr/systemTickTimeInHz) * 1000;
+    }
+#elif defined(MICRIUM)
+    /* The time in milliseconds.
+     * Used for tickets to represent difference between when first seen and when
+     * sending.
+     *
+     * returns the time in milliseconds as a 32-bit value.
+     */
+    word32 TimeNowInMilliseconds(void)
+    {
+        OS_TICK ticks = 0;
+        OS_ERR  err;
+
+        ticks = OSTimeGet(&err);
+
+        return (word32) (ticks / OSCfg_TickRate_Hz) * 1000;
+    }
+#elif defined(MICROCHIP_TCPIP_V5)
+    /* The time in milliseconds.
+     * Used for tickets to represent difference between when first seen and when
+     * sending.
+     *
+     * returns the time in milliseconds as a 32-bit value.
+     */
+    word32 TimeNowInMilliseconds(void)
+    {
+        return (word32) (TickGet() / (TICKS_PER_SECOND / 1000));
+    }
+#elif defined(MICROCHIP_TCPIP)
+    #if defined(MICROCHIP_MPLAB_HARMONY)
+        #include <system/tmr/sys_tmr.h>
+
+    /* The time in milliseconds.
+     * Used for tickets to represent difference between when first seen and when
+     * sending.
+     *
+     * returns the time in milliseconds as a 32-bit value.
+     */
+    word32 TimeNowInMilliseconds(void)
+    {
+        return (word32)(SYS_TMR_TickCountGet() /
+                        (SYS_TMR_TickCounterFrequencyGet() / 1000));
+    }
+    #else
+    /* The time in milliseconds.
+     * Used for tickets to represent difference between when first seen and when
+     * sending.
+     *
+     * returns the time in milliseconds as a 32-bit value.
+     */
+    word32 TimeNowInMilliseconds(void)
+    {
+        return (word32)(SYS_TICK_Get() / (SYS_TICK_TicksPerSecondGet() / 1000));
+    }
+
+    #endif
+
+#elif defined(FREESCALE_MQX) || defined(FREESCALE_KSDK_MQX)
+    /* The time in milliseconds.
+     * Used for tickets to represent difference between when first seen and when
+     * sending.
+     *
+     * returns the time in milliseconds as a 32-bit value.
+     */
+    word32 TimeNowInMilliseconds(void)
+    {
+        TIME_STRUCT mqxTime;
+
+        _time_get_elapsed(&mqxTime);
+
+        return (word32) mqxTime.SECONDS * 1000;
+    }
+#elif defined(FREESCALE_FREE_RTOS) || defined(FREESCALE_KSDK_FREERTOS)
+    #include "include/task.h"
+
+    /* The time in milliseconds.
+     * Used for tickets to represent difference between when first seen and when
+     * sending.
+     *
+     * returns the time in milliseconds as a 32-bit value.
+     */
+    word32 TimeNowInMilliseconds(void)
+    {
+        return (unsigned int)(((float)xTaskGetTickCount()) /
+                              (configTICK_RATE_HZ / 1000));
+    }
+#elif defined(FREESCALE_KSDK_BM)
+    #include "lwip/sys.h" /* lwIP */
+
+    /* The time in milliseconds.
+     * Used for tickets to represent difference between when first seen and when
+     * sending.
+     *
+     * returns the time in milliseconds as a 32-bit value.
+     */
+    word32 TimeNowInMilliseconds(void)
+    {
+        return sys_now();
+    }
+#elif defined(WOLFSSL_TIRTOS)
+    /* The time in milliseconds.
+     * Used for tickets to represent difference between when first seen and when
+     * sending.
+     *
+     * returns the time in milliseconds as a 32-bit value.
+     */
+    word32 TimeNowInMilliseconds(void)
+    {
+        return (word32) Seconds_get() * 1000;
+    }
+#elif defined(WOLFSSL_UTASKER)
+    /* The time in milliseconds.
+     * Used for tickets to represent difference between when first seen and when
+     * sending.
+     *
+     * returns the time in milliseconds as a 32-bit value.
+     */
+    word32 TimeNowInMilliseconds(void)
+    {
+        return (word32)(uTaskerSystemTick / (TICK_RESOLUTION / 1000));
+    }
+#else
+    /* The time in milliseconds.
+     * Used for tickets to represent difference between when first seen and when
+     * sending.
+     *
+     * returns the time in milliseconds as a 32-bit value.
+     */
+    word32 TimeNowInMilliseconds(void)
+    {
+        struct timeval now;
+
+        if (gettimeofday(&now, 0) < 0)
+            return GETTIME_ERROR;
+        /* Convert to milliseconds number. */
+        return (word32)(now.tv_sec * 1000 + now.tv_usec / 1000);
+    }
+#endif
+#endif /* HAVE_SESSION_TICKET || !NO_PSK */
+
+
+#if !defined(NO_WOLFSSL_SERVER) && (defined(HAVE_SESSION_TICKET) || \
+                                    !defined(NO_PSK))
+/* Add input to all handshake hashes.
+ *
+ * ssl    The SSL/TLS object.
+ * input  The data to hash.
+ * sz     The size of the data to hash.
+ * returns 0 on success, otherwise failure.
+ */
+static int HashInputRaw(WOLFSSL* ssl, const byte* input, int sz)
+{
+    int ret = BAD_FUNC_ARG;
+
+#ifndef NO_SHA256
+    ret = wc_Sha256Update(&ssl->hsHashes->hashSha256, input, sz);
+    if (ret != 0)
+        return ret;
+#endif
+#ifdef WOLFSSL_SHA384
+    ret = wc_Sha384Update(&ssl->hsHashes->hashSha384, input, sz);
+    if (ret != 0)
+        return ret;
+#endif
+#ifdef WOLFSSL_TLS13_SHA512
+    ret = wc_Sha512Update(&ssl->hsHashes->hashSha512, input, sz);
+    if (ret != 0)
+        return ret;
+#endif
+
+    return ret;
+}
+#endif
+
+/* Extract the handshake header information.
+ *
+ * ssl       The SSL/TLS object.
+ * input     The buffer holding the message data.
+ * inOutIdx  On entry, the index into the buffer of the handshake data.
+ *           On exit, the start of the handshake data.
+ * type      Type of handshake message.
+ * size      The length of the handshake message data.
+ * totalSz   The total size of data in the buffer.
+ * returns BUFFER_E if there is not enough input data and 0 on success.
+ */
+static int GetHandshakeHeader(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
+                              byte* type, word32* size, word32 totalSz)
+{
+    const byte* ptr = input + *inOutIdx;
+    (void)ssl;
+
+    *inOutIdx += HANDSHAKE_HEADER_SZ;
+    if (*inOutIdx > totalSz)
+        return BUFFER_E;
+
+    *type = ptr[0];
+    c24to32(&ptr[1], size);
+
+    return 0;
+}
+
+/* Add record layer header to message.
+ *
+ * output  The buffer to write the record layer header into.
+ * length  The length of the record data.
+ * type    The type of record message.
+ * ssl     The SSL/TLS object.
+ */
+static void AddTls13RecordHeader(byte* output, word32 length, byte type,
+                                 WOLFSSL* ssl)
+{
+    RecordLayerHeader* rl;
+
+    rl = (RecordLayerHeader*)output;
+    rl->type    = type;
+    rl->pvMajor = ssl->version.major;
+#ifdef WOLFSSL_TLS13_DRAFT_18
+    rl->pvMinor = TLSv1_MINOR;
+#else
+    /* NOTE: May be TLSv1_MINOR when sending first ClientHello. */
+    rl->pvMinor = TLSv1_2_MINOR;
+#endif
+    c16toa((word16)length, rl->length);
+}
+
+/* Add handshake header to message.
+ *
+ * output      The buffer to write the handshake header into.
+ * length      The length of the handshake data.
+ * fragOffset  The offset of the fragment data. (DTLS)
+ * fragLength  The length of the fragment data. (DTLS)
+ * type        The type of handshake message.
+ * ssl         The SSL/TLS object. (DTLS)
+ */
+static void AddTls13HandShakeHeader(byte* output, word32 length,
+                                    word32 fragOffset, word32 fragLength,
+                                    byte type, WOLFSSL* ssl)
+{
+    HandShakeHeader* hs;
+    (void)fragOffset;
+    (void)fragLength;
+    (void)ssl;
+
+    /* handshake header */
+    hs = (HandShakeHeader*)output;
+    hs->type = type;
+    c32to24(length, hs->length);
+}
+
+
+/* Add both record layer and handshake header to message.
+ *
+ * output      The buffer to write the headers into.
+ * length      The length of the handshake data.
+ * type        The type of record layer message.
+ * ssl         The SSL/TLS object. (DTLS)
+ */
+static void AddTls13Headers(byte* output, word32 length, byte type,
+                            WOLFSSL* ssl)
+{
+    word32 lengthAdj = HANDSHAKE_HEADER_SZ;
+    word32 outputAdj = RECORD_HEADER_SZ;
+
+    AddTls13RecordHeader(output, length + lengthAdj, handshake, ssl);
+    AddTls13HandShakeHeader(output + outputAdj, length, 0, length, type, ssl);
+}
+
+
+#ifndef NO_CERTS
+/* Add both record layer and fragment handshake header to message.
+ *
+ * output      The buffer to write the headers into.
+ * fragOffset  The offset of the fragment data. (DTLS)
+ * fragLength  The length of the fragment data. (DTLS)
+ * length      The length of the handshake data.
+ * type        The type of record layer message.
+ * ssl         The SSL/TLS object. (DTLS)
+ */
+static void AddTls13FragHeaders(byte* output, word32 fragSz, word32 fragOffset,
+                                word32 length, byte type, WOLFSSL* ssl)
+{
+    word32 lengthAdj = HANDSHAKE_HEADER_SZ;
+    word32 outputAdj = RECORD_HEADER_SZ;
+    (void)fragSz;
+
+    AddTls13RecordHeader(output, fragSz + lengthAdj, handshake, ssl);
+    AddTls13HandShakeHeader(output + outputAdj, length, fragOffset, fragSz,
+                            type, ssl);
+}
+#endif /* NO_CERTS */
+
+/* Write the sequence number into the buffer.
+ * No DTLS v1.3 support.
+ *
+ * ssl          The SSL/TLS object.
+ * verifyOrder  Which set of sequence numbers to use.
+ * out          The buffer to write into.
+ */
+static WC_INLINE void WriteSEQ(WOLFSSL* ssl, int verifyOrder, byte* out)
+{
+    word32 seq[2] = {0, 0};
+
+    if (verifyOrder) {
+        seq[0] = ssl->keys.peer_sequence_number_hi;
+        seq[1] = ssl->keys.peer_sequence_number_lo++;
+        /* handle rollover */
+        if (seq[1] > ssl->keys.peer_sequence_number_lo)
+            ssl->keys.peer_sequence_number_hi++;
+    }
+    else {
+        seq[0] = ssl->keys.sequence_number_hi;
+        seq[1] = ssl->keys.sequence_number_lo++;
+        /* handle rollover */
+        if (seq[1] > ssl->keys.sequence_number_lo)
+            ssl->keys.sequence_number_hi++;
+    }
+
+    c32toa(seq[0], out);
+    c32toa(seq[1], out + OPAQUE32_LEN);
+}
+
+/* Build the nonce for TLS v1.3 encryption and decryption.
+ *
+ * ssl    The SSL/TLS object.
+ * nonce  The nonce data to use when encrypting or decrypting.
+ * iv     The derived IV.
+ * order  The side on which the message is to be or was sent.
+ */
+static WC_INLINE void BuildTls13Nonce(WOLFSSL* ssl, byte* nonce, const byte* iv,
+                                   int order)
+{
+    int  i;
+
+    /* The nonce is the IV with the sequence XORed into the last bytes. */
+    WriteSEQ(ssl, order, nonce + AEAD_NONCE_SZ - SEQ_SZ);
+    for (i = 0; i < AEAD_NONCE_SZ - SEQ_SZ; i++)
+        nonce[i] = iv[i];
+    for (; i < AEAD_NONCE_SZ; i++)
+        nonce[i] ^= iv[i];
+}
+
+#if defined(HAVE_CHACHA) && defined(HAVE_POLY1305)
+/* Encrypt with ChaCha20 and create authenication tag with Poly1305.
+ *
+ * ssl     The SSL/TLS object.
+ * output  The buffer to write encrypted data and authentication tag into.
+ *         May be the same pointer as input.
+ * input   The data to encrypt.
+ * sz      The number of bytes to encrypt.
+ * nonce   The nonce to use with ChaCha20.
+ * aad     The additional authentication data.
+ * aadSz   The size of the addition authentication data.
+ * tag     The authentication tag buffer.
+ * returns 0 on success, otherwise failure.
+ */
+static int ChaCha20Poly1305_Encrypt(WOLFSSL* ssl, byte* output,
+                                    const byte* input, word16 sz, byte* nonce,
+                                    const byte* aad, word16 aadSz, byte* tag)
+{
+    int    ret    = 0;
+    byte   poly[CHACHA20_256_KEY_SIZE];
+
+    /* Poly1305 key is 256 bits of zero encrypted with ChaCha20. */
+    XMEMSET(poly, 0, sizeof(poly));
+
+    /* Set the nonce for ChaCha and get Poly1305 key. */
+    ret = wc_Chacha_SetIV(ssl->encrypt.chacha, nonce, 0);
+    if (ret != 0)
+        return ret;
+    /* Create Poly1305 key using ChaCha20 keystream. */
+    ret = wc_Chacha_Process(ssl->encrypt.chacha, poly, poly, sizeof(poly));
+    if (ret != 0)
+        return ret;
+    ret = wc_Chacha_SetIV(ssl->encrypt.chacha, nonce, 1);
+    if (ret != 0)
+        return ret;
+    /* Encrypt the plain text. */
+    ret = wc_Chacha_Process(ssl->encrypt.chacha, output, input, sz);
+    if (ret != 0) {
+        ForceZero(poly, sizeof(poly));
+        return ret;
+    }
+
+    /* Set key for Poly1305. */
+    ret = wc_Poly1305SetKey(ssl->auth.poly1305, poly, sizeof(poly));
+    ForceZero(poly, sizeof(poly)); /* done with poly1305 key, clear it */
+    if (ret != 0)
+        return ret;
+    /* Add authentication code of encrypted data to end. */
+    ret = wc_Poly1305_MAC(ssl->auth.poly1305, (byte*)aad, aadSz, output, sz,
+                          tag, POLY1305_AUTH_SZ);
+
+    return ret;
+}
+#endif
+
+#ifdef HAVE_NULL_CIPHER
+/* Create authenication tag and copy data over input.
+ *
+ * ssl     The SSL/TLS object.
+ * output  The buffer to copy data into.
+ *         May be the same pointer as input.
+ * input   The data.
+ * sz      The number of bytes of data.
+ * nonce   The nonce to use with authentication.
+ * aad     The additional authentication data.
+ * aadSz   The size of the addition authentication data.
+ * tag     The authentication tag buffer.
+ * returns 0 on success, otherwise failure.
+ */
+static int Tls13IntegrityOnly_Encrypt(WOLFSSL* ssl, byte* output,
+                                      const byte* input, word16 sz,
+                                      const byte* nonce,
+                                      const byte* aad, word16 aadSz, byte* tag)
+{
+    int ret;
+
+    /* HMAC: nonce | aad | input  */
+    ret = wc_HmacUpdate(ssl->encrypt.hmac, nonce, HMAC_NONCE_SZ);
+    if (ret == 0)
+        ret = wc_HmacUpdate(ssl->encrypt.hmac, aad, aadSz);
+    if (ret == 0)
+        ret = wc_HmacUpdate(ssl->encrypt.hmac, input, sz);
+    if (ret == 0)
+        ret = wc_HmacFinal(ssl->encrypt.hmac, tag);
+    /* Copy the input to output if not the same buffer */
+    if (ret == 0 && output != input)
+        XMEMCPY(output, input, sz);
+
+    return ret;
+}
+#endif
+
+/* Encrypt data for TLS v1.3.
+ *
+ * ssl     The SSL/TLS object.
+ * output  The buffer to write encrypted data and authentication tag into.
+ *         May be the same pointer as input.
+ * input   The record header and data to encrypt.
+ * sz      The number of bytes to encrypt.
+ * aad     The additional authentication data.
+ * aadSz   The size of the addition authentication data.
+ * asyncOkay If non-zero can return WC_PENDING_E, otherwise blocks on crypto
+ * returns 0 on success, otherwise failure.
+ */
+static int EncryptTls13(WOLFSSL* ssl, byte* output, const byte* input,
+                        word16 sz, const byte* aad, word16 aadSz, int asyncOkay)
+{
+    int    ret    = 0;
+    word16 dataSz = sz - ssl->specs.aead_mac_size;
+    word16 macSz  = ssl->specs.aead_mac_size;
+    word32 nonceSz = 0;
+#ifdef WOLFSSL_ASYNC_CRYPT
+    WC_ASYNC_DEV* asyncDev = NULL;
+    word32 event_flags = WC_ASYNC_FLAG_CALL_AGAIN;
+#endif
+
+    WOLFSSL_ENTER("EncryptTls13");
+
+    (void)output;
+    (void)input;
+    (void)sz;
+    (void)dataSz;
+    (void)macSz;
+    (void)asyncOkay;
+    (void)nonceSz;
+
+#ifdef WOLFSSL_ASYNC_CRYPT
+    if (ssl->error == WC_PENDING_E) {
+        ssl->error = 0; /* clear async */
+    }
+#endif
+
+    switch (ssl->encrypt.state) {
+        case CIPHER_STATE_BEGIN:
+        {
+        #ifdef WOLFSSL_DEBUG_TLS
+            WOLFSSL_MSG("Data to encrypt");
+            WOLFSSL_BUFFER(input, dataSz);
+#if !defined(WOLFSSL_TLS13_DRAFT_18) && !defined(WOLFSSL_TLS13_DRAFT_22) && \
+                                        !defined(WOLFSSL_TLS13_DRAFT_23)
+            WOLFSSL_MSG("Additional Authentication Data");
+            WOLFSSL_BUFFER(aad, aadSz);
+#endif
+        #endif
+
+        #ifdef CIPHER_NONCE
+            if (ssl->encrypt.nonce == NULL)
+                ssl->encrypt.nonce = (byte*)XMALLOC(AEAD_NONCE_SZ,
+                                            ssl->heap, DYNAMIC_TYPE_AES_BUFFER);
+            if (ssl->encrypt.nonce == NULL)
+                return MEMORY_E;
+
+            BuildTls13Nonce(ssl, ssl->encrypt.nonce, ssl->keys.aead_enc_imp_IV,
+                            CUR_ORDER);
+        #endif
+
+            /* Advance state and proceed */
+            ssl->encrypt.state = CIPHER_STATE_DO;
+        }
+        FALL_THROUGH;
+
+        case CIPHER_STATE_DO:
+        {
+            switch (ssl->specs.bulk_cipher_algorithm) {
+            #ifdef BUILD_AESGCM
+                case wolfssl_aes_gcm:
+                #ifdef WOLFSSL_ASYNC_CRYPT
+                    /* initialize event */
+                    asyncDev = &ssl->encrypt.aes->asyncDev;
+                    ret = wolfSSL_AsyncInit(ssl, asyncDev, event_flags);
+                    if (ret != 0)
+                        break;
+                #endif
+
+                    nonceSz = AESGCM_NONCE_SZ;
+                #if ((defined(HAVE_FIPS) || defined(HAVE_SELFTEST)) && \
+                    (!defined(HAVE_FIPS_VERSION) || (HAVE_FIPS_VERSION < 2)))
+                    ret = wc_AesGcmEncrypt(ssl->encrypt.aes, output, input,
+                        dataSz, ssl->encrypt.nonce, nonceSz,
+                        output + dataSz, macSz, aad, aadSz);
+                #else
+                    ret = wc_AesGcmSetExtIV(ssl->encrypt.aes,
+                            ssl->encrypt.nonce, nonceSz);
+                    if (ret == 0) {
+                        ret = wc_AesGcmEncrypt_ex(ssl->encrypt.aes, output,
+                                input, dataSz, ssl->encrypt.nonce, nonceSz,
+                                output + dataSz, macSz, aad, aadSz);
+                    }
+                #endif
+                    break;
+            #endif
+
+            #ifdef HAVE_AESCCM
+                case wolfssl_aes_ccm:
+                #ifdef WOLFSSL_ASYNC_CRYPT
+                    /* initialize event */
+                    asyncDev = &ssl->encrypt.aes->asyncDev;
+                    ret = wolfSSL_AsyncInit(ssl, asyncDev, event_flags);
+                    if (ret != 0)
+                        break;
+                #endif
+
+                    nonceSz = AESCCM_NONCE_SZ;
+                #if ((defined(HAVE_FIPS) || defined(HAVE_SELFTEST)) && \
+                    (!defined(HAVE_FIPS_VERSION) || (HAVE_FIPS_VERSION < 2)))
+                    ret = wc_AesCcmEncrypt(ssl->encrypt.aes, output, input,
+                        dataSz, ssl->encrypt.nonce, nonceSz,
+                        output + dataSz, macSz, aad, aadSz);
+                #else
+                    ret = wc_AesCcmSetNonce(ssl->encrypt.aes,
+                            ssl->encrypt.nonce, nonceSz);
+                    if (ret == 0) {
+                        ret = wc_AesCcmEncrypt_ex(ssl->encrypt.aes, output,
+                                input, dataSz, ssl->encrypt.nonce, nonceSz,
+                                output + dataSz, macSz, aad, aadSz);
+                    }
+                #endif
+                    break;
+            #endif
+
+            #if defined(HAVE_CHACHA) && defined(HAVE_POLY1305)
+                case wolfssl_chacha:
+                    ret = ChaCha20Poly1305_Encrypt(ssl, output, input, dataSz,
+                        ssl->encrypt.nonce, aad, aadSz, output + dataSz);
+                    break;
+            #endif
+
+            #ifdef HAVE_NULL_CIPHER
+                case wolfssl_cipher_null:
+                    ret = Tls13IntegrityOnly_Encrypt(ssl, output, input, dataSz,
+                        ssl->encrypt.nonce, aad, aadSz, output + dataSz);
+                    break;
+            #endif
+
+                default:
+                    WOLFSSL_MSG("wolfSSL Encrypt programming error");
+                    return ENCRYPT_ERROR;
+            }
+
+            /* Advance state */
+            ssl->encrypt.state = CIPHER_STATE_END;
+
+        #ifdef WOLFSSL_ASYNC_CRYPT
+            if (ret == WC_PENDING_E) {
+                /* if async is not okay, then block */
+                if (!asyncOkay) {
+                    ret = wc_AsyncWait(ret, asyncDev, event_flags);
+                }
+                else {
+                    /* If pending, then leave and return will resume below */
+                    return wolfSSL_AsyncPush(ssl, asyncDev);
+                }
+            }
+        #endif
+        }
+        FALL_THROUGH;
+
+        case CIPHER_STATE_END:
+        {
+        #ifdef WOLFSSL_DEBUG_TLS
+            #ifdef CIPHER_NONCE
+                WOLFSSL_MSG("Nonce");
+                WOLFSSL_BUFFER(ssl->encrypt.nonce, ssl->specs.iv_size);
+            #endif
+                WOLFSSL_MSG("Encrypted data");
+                WOLFSSL_BUFFER(output, dataSz);
+                WOLFSSL_MSG("Authentication Tag");
+                WOLFSSL_BUFFER(output + dataSz, macSz);
+        #endif
+
+        #ifdef CIPHER_NONCE
+            ForceZero(ssl->encrypt.nonce, AEAD_NONCE_SZ);
+        #endif
+
+            break;
+        }
+    }
+
+    /* Reset state */
+    ssl->encrypt.state = CIPHER_STATE_BEGIN;
+
+    return ret;
+}
+
+#if defined(HAVE_CHACHA) && defined(HAVE_POLY1305)
+/* Decrypt with ChaCha20 and check authenication tag with Poly1305.
+ *
+ * ssl     The SSL/TLS object.
+ * output  The buffer to write decrypted data into.
+ *         May be the same pointer as input.
+ * input   The data to decrypt.
+ * sz      The number of bytes to decrypt.
+ * nonce   The nonce to use with ChaCha20.
+ * aad     The additional authentication data.
+ * aadSz   The size of the addition authentication data.
+ * tagIn   The authentication tag data from packet.
+ * returns 0 on success, otherwise failure.
+ */
+static int ChaCha20Poly1305_Decrypt(WOLFSSL* ssl, byte* output,
+                                    const byte* input, word16 sz, byte* nonce,
+                                    const byte* aad, word16 aadSz,
+                                    const byte* tagIn)
+{
+    int ret;
+    byte tag[POLY1305_AUTH_SZ];
+    byte poly[CHACHA20_256_KEY_SIZE]; /* generated key for mac */
+
+    /* Poly1305 key is 256 bits of zero encrypted with ChaCha20. */
+    XMEMSET(poly, 0, sizeof(poly));
+
+    /* Set nonce and get Poly1305 key. */
+    ret = wc_Chacha_SetIV(ssl->decrypt.chacha, nonce, 0);
+    if (ret != 0)
+        return ret;
+    /* Use ChaCha20 keystream to get Poly1305 key for tag. */
+    ret = wc_Chacha_Process(ssl->decrypt.chacha, poly, poly, sizeof(poly));
+    if (ret != 0)
+        return ret;
+    ret = wc_Chacha_SetIV(ssl->decrypt.chacha, nonce, 1);
+    if (ret != 0)
+        return ret;
+
+    /* Set key for Poly1305. */
+    ret = wc_Poly1305SetKey(ssl->auth.poly1305, poly, sizeof(poly));
+    ForceZero(poly, sizeof(poly)); /* done with poly1305 key, clear it */
+    if (ret != 0)
+        return ret;
+    /* Generate authentication tag for encrypted data. */
+    if ((ret = wc_Poly1305_MAC(ssl->auth.poly1305, (byte*)aad, aadSz,
+                                    (byte*)input, sz, tag, sizeof(tag))) != 0) {
+        return ret;
+    }
+
+    /* Check tag sent along with packet. */
+    if (ConstantCompare(tagIn, tag, POLY1305_AUTH_SZ) != 0) {
+        WOLFSSL_MSG("MAC did not match");
+        return VERIFY_MAC_ERROR;
+    }
+
+    /* If the tag was good decrypt message. */
+    ret = wc_Chacha_Process(ssl->decrypt.chacha, output, input, sz);
+
+    return ret;
+}
+#endif
+
+#ifdef HAVE_NULL_CIPHER
+/* Check HMAC tag and copy over input.
+ *
+ * ssl     The SSL/TLS object.
+ * output  The buffer to copy data into.
+ *         May be the same pointer as input.
+ * input   The data.
+ * sz      The number of bytes of data.
+ * nonce   The nonce to use with authentication.
+ * aad     The additional authentication data.
+ * aadSz   The size of the addition authentication data.
+ * tagIn   The authentication tag data from packet.
+ * returns 0 on success, otherwise failure.
+ */
+static int Tls13IntegrityOnly_Decrypt(WOLFSSL* ssl, byte* output,
+                                      const byte* input, word16 sz,
+                                      const byte* nonce,
+                                      const byte* aad, word16 aadSz,
+                                      const byte* tagIn)
+{
+    int ret;
+    byte hmac[WC_MAX_DIGEST_SIZE];
+
+    /* HMAC: nonce | aad | input  */
+    ret = wc_HmacUpdate(ssl->decrypt.hmac, nonce, HMAC_NONCE_SZ);
+    if (ret == 0)
+        ret = wc_HmacUpdate(ssl->decrypt.hmac, aad, aadSz);
+    if (ret == 0)
+        ret = wc_HmacUpdate(ssl->decrypt.hmac, input, sz);
+    if (ret == 0)
+        ret = wc_HmacFinal(ssl->decrypt.hmac, hmac);
+    /* Check authentication tag matches */
+    if (ret == 0 && ConstantCompare(tagIn, hmac, ssl->specs.hash_size) != 0)
+        ret = DECRYPT_ERROR;
+    /* Copy the input to output if not the same buffer */
+    if (ret == 0 && output != input)
+        XMEMCPY(output, input, sz);
+
+    return ret;
+}
+#endif
+
+/* Decrypt data for TLS v1.3.
+ *
+ * ssl     The SSL/TLS object.
+ * output  The buffer to write decrypted data into.
+ *         May be the same pointer as input.
+ * input   The data to decrypt and authentication tag.
+ * sz      The length of the encrypted data plus authentication tag.
+ * aad     The additional authentication data.
+ * aadSz   The size of the addition authentication data.
+ * returns 0 on success, otherwise failure.
+ */
+int DecryptTls13(WOLFSSL* ssl, byte* output, const byte* input, word16 sz,
+                 const byte* aad, word16 aadSz)
+{
+    int    ret    = 0;
+    word16 dataSz = sz - ssl->specs.aead_mac_size;
+    word16 macSz  = ssl->specs.aead_mac_size;
+    word32 nonceSz = 0;
+
+    WOLFSSL_ENTER("DecryptTls13");
+
+#ifdef WOLFSSL_ASYNC_CRYPT
+    ret = wolfSSL_AsyncPop(ssl, &ssl->decrypt.state);
+    if (ret != WC_NOT_PENDING_E) {
+        /* check for still pending */
+        if (ret == WC_PENDING_E)
+            return ret;
+
+        ssl->error = 0; /* clear async */
+
+        /* let failures through so CIPHER_STATE_END logic is run */
+    }
+    else
+#endif
+    {
+        /* Reset state */
+        ret = 0;
+        ssl->decrypt.state = CIPHER_STATE_BEGIN;
+    }
+
+    (void)output;
+    (void)input;
+    (void)sz;
+    (void)dataSz;
+    (void)macSz;
+    (void)nonceSz;
+
+    switch (ssl->decrypt.state) {
+        case CIPHER_STATE_BEGIN:
+        {
+        #ifdef WOLFSSL_DEBUG_TLS
+            WOLFSSL_MSG("Data to decrypt");
+            WOLFSSL_BUFFER(input, dataSz);
+#if !defined(WOLFSSL_TLS13_DRAFT_18) && !defined(WOLFSSL_TLS13_DRAFT_22) && \
+                                        !defined(WOLFSSL_TLS13_DRAFT_23)
+            WOLFSSL_MSG("Additional Authentication Data");
+            WOLFSSL_BUFFER(aad, aadSz);
+#endif
+            WOLFSSL_MSG("Authentication tag");
+            WOLFSSL_BUFFER(input + dataSz, macSz);
+        #endif
+
+        #ifdef CIPHER_NONCE
+            if (ssl->decrypt.nonce == NULL)
+                ssl->decrypt.nonce = (byte*)XMALLOC(AEAD_NONCE_SZ,
+                                            ssl->heap, DYNAMIC_TYPE_AES_BUFFER);
+            if (ssl->decrypt.nonce == NULL)
+                return MEMORY_E;
+
+            BuildTls13Nonce(ssl, ssl->decrypt.nonce, ssl->keys.aead_dec_imp_IV,
+                            PEER_ORDER);
+        #endif
+
+            /* Advance state and proceed */
+            ssl->decrypt.state = CIPHER_STATE_DO;
+        }
+        FALL_THROUGH;
+
+        case CIPHER_STATE_DO:
+        {
+            switch (ssl->specs.bulk_cipher_algorithm) {
+            #ifdef BUILD_AESGCM
+                case wolfssl_aes_gcm:
+                #ifdef WOLFSSL_ASYNC_CRYPT
+                    /* initialize event */
+                    ret = wolfSSL_AsyncInit(ssl, &ssl->decrypt.aes->asyncDev,
+                        WC_ASYNC_FLAG_CALL_AGAIN);
+                    if (ret != 0)
+                        break;
+                #endif
+
+                    nonceSz = AESGCM_NONCE_SZ;
+                    ret = wc_AesGcmDecrypt(ssl->decrypt.aes, output, input,
+                        dataSz, ssl->decrypt.nonce, nonceSz,
+                        input + dataSz, macSz, aad, aadSz);
+                #ifdef WOLFSSL_ASYNC_CRYPT
+                    if (ret == WC_PENDING_E) {
+                        ret = wolfSSL_AsyncPush(ssl,
+                                                   &ssl->decrypt.aes->asyncDev);
+                    }
+                #endif
+                    break;
+            #endif
+
+            #ifdef HAVE_AESCCM
+                case wolfssl_aes_ccm:
+                #ifdef WOLFSSL_ASYNC_CRYPT
+                    /* initialize event */
+                    ret = wolfSSL_AsyncInit(ssl, &ssl->decrypt.aes->asyncDev,
+                        WC_ASYNC_FLAG_CALL_AGAIN);
+                    if (ret != 0)
+                        break;
+                #endif
+
+                    nonceSz = AESCCM_NONCE_SZ;
+                    ret = wc_AesCcmDecrypt(ssl->decrypt.aes, output, input,
+                        dataSz, ssl->decrypt.nonce, nonceSz,
+                        input + dataSz, macSz, aad, aadSz);
+                #ifdef WOLFSSL_ASYNC_CRYPT
+                    if (ret == WC_PENDING_E) {
+                        ret = wolfSSL_AsyncPush(ssl,
+                                                   &ssl->decrypt.aes->asyncDev);
+                    }
+                #endif
+                    break;
+            #endif
+
+            #if defined(HAVE_CHACHA) && defined(HAVE_POLY1305)
+                case wolfssl_chacha:
+                    ret = ChaCha20Poly1305_Decrypt(ssl, output, input, dataSz,
+                        ssl->decrypt.nonce, aad, aadSz, input + dataSz);
+                    break;
+            #endif
+
+            #ifdef HAVE_NULL_CIPHER
+                case wolfssl_cipher_null:
+                    ret = Tls13IntegrityOnly_Decrypt(ssl, output, input, dataSz,
+                        ssl->decrypt.nonce, aad, aadSz, input + dataSz);
+                    break;
+            #endif
+                default:
+                    WOLFSSL_MSG("wolfSSL Decrypt programming error");
+                    return DECRYPT_ERROR;
+            }
+
+            /* Advance state */
+            ssl->decrypt.state = CIPHER_STATE_END;
+
+        #ifdef WOLFSSL_ASYNC_CRYPT
+            /* If pending, leave now */
+            if (ret == WC_PENDING_E) {
+                return ret;
+            }
+        #endif
+        }
+        FALL_THROUGH;
+
+        case CIPHER_STATE_END:
+        {
+        #ifdef WOLFSSL_DEBUG_TLS
+            #ifdef CIPHER_NONCE
+                WOLFSSL_MSG("Nonce");
+                WOLFSSL_BUFFER(ssl->decrypt.nonce, ssl->specs.iv_size);
+            #endif
+                WOLFSSL_MSG("Decrypted data");
+                WOLFSSL_BUFFER(output, dataSz);
+        #endif
+
+        #ifdef CIPHER_NONCE
+            ForceZero(ssl->decrypt.nonce, AEAD_NONCE_SZ);
+        #endif
+
+            break;
+        }
+    }
+
+#ifndef WOLFSSL_EARLY_DATA
+    if (ret < 0) {
+        SendAlert(ssl, alert_fatal, bad_record_mac);
+        ret = VERIFY_MAC_ERROR;
+    }
+#endif
+
+    return ret;
+}
+
+/* Persistable BuildTls13Message arguments */
+typedef struct BuildMsg13Args {
+    word32 sz;
+    word32 idx;
+    word32 headerSz;
+    word16 size;
+} BuildMsg13Args;
+
+static void FreeBuildMsg13Args(WOLFSSL* ssl, void* pArgs)
+{
+    BuildMsg13Args* args = (BuildMsg13Args*)pArgs;
+
+    (void)ssl;
+    (void)args;
+
+    /* no allocations in BuildTls13Message */
+}
+
+/* Build SSL Message, encrypted.
+ * TLS v1.3 encryption is AEAD only.
+ *
+ * ssl         The SSL/TLS object.
+ * output      The buffer to write record message to.
+ * outSz       Size of the buffer being written into.
+ * input       The record data to encrypt (excluding record header).
+ * inSz        The size of the record data.
+ * type        The recorder header content type.
+ * hashOutput  Whether to hash the unencrypted record data.
+ * sizeOnly    Only want the size of the record message.
+ * asyncOkay   If non-zero can return WC_PENDING_E, otherwise blocks on crypto
+ * returns the size of the encrypted record message or negative value on error.
+ */
+int BuildTls13Message(WOLFSSL* ssl, byte* output, int outSz, const byte* input,
+                int inSz, int type, int hashOutput, int sizeOnly, int asyncOkay)
+{
+    int ret = 0;
+    BuildMsg13Args* args;
+    BuildMsg13Args  lcl_args;
+#ifdef WOLFSSL_ASYNC_CRYPT
+    args = (BuildMsg13Args*)ssl->async.args;
+    typedef char args_test[sizeof(ssl->async.args) >= sizeof(*args) ? 1 : -1];
+    (void)sizeof(args_test);
+#endif
+
+    WOLFSSL_ENTER("BuildTls13Message");
+
+    ret = WC_NOT_PENDING_E;
+#ifdef WOLFSSL_ASYNC_CRYPT
+    if (asyncOkay) {
+        ret = wolfSSL_AsyncPop(ssl, &ssl->options.buildMsgState);
+        if (ret != WC_NOT_PENDING_E) {
+            /* Check for error */
+            if (ret < 0)
+                goto exit_buildmsg;
+        }
+    }
+    else
+#endif
+    {
+        args = &lcl_args;
+    }
+
+    /* Reset state */
+    if (ret == WC_NOT_PENDING_E) {
+        ret = 0;
+        ssl->options.buildMsgState = BUILD_MSG_BEGIN;
+        XMEMSET(args, 0, sizeof(BuildMsg13Args));
+
+        args->sz = RECORD_HEADER_SZ + inSz;
+        args->idx  = RECORD_HEADER_SZ;
+        args->headerSz = RECORD_HEADER_SZ;
+    #ifdef WOLFSSL_ASYNC_CRYPT
+        ssl->async.freeArgs = FreeBuildMsg13Args;
+    #endif
+    }
+
+    switch (ssl->options.buildMsgState) {
+        case BUILD_MSG_BEGIN:
+        {
+           /* catch mistaken sizeOnly parameter */
+            if (sizeOnly) {
+                if (output || input) {
+                    WOLFSSL_MSG("BuildTls13Message with sizeOnly "
+                                "doesn't need input or output");
+                    return BAD_FUNC_ARG;
+                }
+            }
+            else if (output == NULL || input == NULL) {
+                return BAD_FUNC_ARG;
+            }
+
+            /* Record layer content type at the end of record data. */
+            args->sz++;
+            /* Authentication data at the end. */
+            args->sz += ssl->specs.aead_mac_size;
+
+            if (sizeOnly)
+                return args->sz;
+
+            if (args->sz > (word32)outSz) {
+                WOLFSSL_MSG("Oops, want to write past output buffer size");
+                return BUFFER_E;
+            }
+
+            /* Record data length. */
+            args->size = (word16)(args->sz - args->headerSz);
+            /* Write/update the record header with the new size.
+             * Always have the content type as application data for encrypted
+             * messages in TLS v1.3.
+             */
+            AddTls13RecordHeader(output, args->size, application_data, ssl);
+
+            /* TLS v1.3 can do in place encryption. */
+            if (input != output + args->idx)
+                XMEMCPY(output + args->idx, input, inSz);
+            args->idx += inSz;
+
+            ssl->options.buildMsgState = BUILD_MSG_HASH;
+        }
+        FALL_THROUGH;
+
+        case BUILD_MSG_HASH:
+        {
+            if (hashOutput) {
+                ret = HashOutput(ssl, output, args->headerSz + inSz, 0);
+                if (ret != 0)
+                    goto exit_buildmsg;
+            }
+
+            /* The real record content type goes at the end of the data. */
+            output[args->idx++] = (byte)type;
+
+            ssl->options.buildMsgState = BUILD_MSG_ENCRYPT;
+        }
+        FALL_THROUGH;
+
+        case BUILD_MSG_ENCRYPT:
+        {
+        #ifdef ATOMIC_USER
+            if (ssl->ctx->MacEncryptCb) {
+                /* User Record Layer Callback handling */
+                byte* mac = output + args->idx;
+                output += args->headerSz;
+
+                ret = ssl->ctx->MacEncryptCb(ssl, mac, output, inSz, type, 0,
+                        output, output, args->size, ssl->MacEncryptCtx);
+            }
+            else
+        #endif
+            {
+#if defined(WOLFSSL_TLS13_DRAFT_18) || defined(WOLFSSL_TLS13_DRAFT_22) || \
+                                       defined(WOLFSSL_TLS13_DRAFT_23)
+                output += args->headerSz;
+                ret = EncryptTls13(ssl, output, output, args->size, NULL, 0,
+                                                                     asyncOkay);
+#else
+                const byte* aad = output;
+                output += args->headerSz;
+                ret = EncryptTls13(ssl, output, output, args->size, aad,
+                                   RECORD_HEADER_SZ, asyncOkay);
+#endif
+            }
+            break;
+        }
+    }
+
+exit_buildmsg:
+
+    WOLFSSL_LEAVE("BuildTls13Message", ret);
+
+#ifdef WOLFSSL_ASYNC_CRYPT
+    if (ret == WC_PENDING_E) {
+        return ret;
+    }
+#endif
+
+    /* make sure build message state is reset */
+    ssl->options.buildMsgState = BUILD_MSG_BEGIN;
+
+    /* return sz on success */
+    if (ret == 0)
+        ret = args->sz;
+
+    /* Final cleanup */
+    FreeBuildMsg13Args(ssl, args);
+#ifdef WOLFSSL_ASYNC_CRYPT
+    ssl->async.freeArgs = NULL;
+#endif
+
+    return ret;
+}
+
+#if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
+/* Find the cipher suite in the suites set in the SSL.
+ *
+ * ssl    SSL/TLS object.
+ * suite  Cipher suite to look for.
+ * returns 1 when suite is found in SSL/TLS object's list and 0 otherwise.
+ */
+static int FindSuiteSSL(WOLFSSL* ssl, byte* suite)
+{
+    word16 i;
+
+    for (i = 0; i < ssl->suites->suiteSz; i += 2) {
+        if (ssl->suites->suites[i+0] == suite[0] &&
+            ssl->suites->suites[i+1] == suite[1]) {
+            return 1;
+        }
+    }
+
+    return 0;
+}
+#endif
+
+#ifndef WOLFSSL_TLS13_DRAFT_18
+#if defined(WOLFSSL_SEND_HRR_COOKIE) && !defined(NO_WOLFSSL_SERVER)
+/* Create Cookie extension using the hash of the first ClientHello.
+ *
+ * ssl     SSL/TLS object.
+ * hash    The hash data.
+ * hashSz  The size of the hash data in bytes.
+ * returns 0 on success, otherwise failure.
+ */
+static int CreateCookie(WOLFSSL* ssl, byte* hash, byte hashSz)
+{
+    int  ret;
+    byte mac[WC_MAX_DIGEST_SIZE] = {0};
+    Hmac cookieHmac;
+    byte cookieType = 0;
+    byte macSz = 0;
+
+#if !defined(NO_SHA) && defined(NO_SHA256)
+    cookieType = SHA;
+    macSz = WC_SHA_DIGEST_SIZE;
+#endif /* NO_SHA */
+#ifndef NO_SHA256
+    cookieType = WC_SHA256;
+    macSz = WC_SHA256_DIGEST_SIZE;
+#endif /* NO_SHA256 */
+    XMEMSET(&cookieHmac, 0, sizeof(Hmac));
+
+    ret = wc_HmacSetKey(&cookieHmac, cookieType,
+                        ssl->buffers.tls13CookieSecret.buffer,
+                        ssl->buffers.tls13CookieSecret.length);
+    if (ret != 0)
+        return ret;
+    if ((ret = wc_HmacUpdate(&cookieHmac, hash, hashSz)) != 0)
+        return ret;
+    if ((ret = wc_HmacFinal(&cookieHmac, mac)) != 0)
+        return ret;
+
+    /* The cookie data is the hash and the integrity check. */
+    return TLSX_Cookie_Use(ssl, hash, hashSz, mac, macSz, 1);
+}
+#endif
+
+/* Restart the handshake hash with a hash of the previous messages.
+ *
+ * ssl The SSL/TLS object.
+ * returns 0 on success, otherwise failure.
+ */
+static int RestartHandshakeHash(WOLFSSL* ssl)
+{
+    int    ret;
+    Hashes hashes;
+    byte   header[HANDSHAKE_HEADER_SZ] = {0};
+    byte*  hash = NULL;
+    byte   hashSz = 0;
+
+    ret = BuildCertHashes(ssl, &hashes);
+    if (ret != 0)
+        return ret;
+    switch (ssl->specs.mac_algorithm) {
+    #ifndef NO_SHA256
+        case sha256_mac:
+            hash = hashes.sha256;
+            break;
+    #endif
+    #ifdef WOLFSSL_SHA384
+        case sha384_mac:
+            hash = hashes.sha384;
+            break;
+    #endif
+    #ifdef WOLFSSL_TLS13_SHA512
+        case sha512_mac:
+            hash = hashes.sha512;
+            break;
+    #endif
+    }
+    hashSz = ssl->specs.hash_size;
+
+    /* check hash */
+    if (hash == NULL && hashSz > 0)
+        return BAD_FUNC_ARG;
+
+    AddTls13HandShakeHeader(header, hashSz, 0, 0, message_hash, ssl);
+
+    WOLFSSL_MSG("Restart Hash");
+    WOLFSSL_BUFFER(hash, hashSz);
+
+#if defined(WOLFSSL_SEND_HRR_COOKIE) && !defined(NO_WOLFSSL_SERVER)
+    if (ssl->options.sendCookie) {
+        byte   cookie[OPAQUE8_LEN + WC_MAX_DIGEST_SIZE + OPAQUE16_LEN * 2];
+        TLSX*  ext;
+        word32 idx = 0;
+
+        /* Cookie Data = Hash Len | Hash | CS | KeyShare Group */
+        cookie[idx++] = hashSz;
+        if (hash)
+            XMEMCPY(cookie + idx, hash, hashSz);
+        idx += hashSz;
+        cookie[idx++] = ssl->options.cipherSuite0;
+        cookie[idx++] = ssl->options.cipherSuite;
+        if ((ext = TLSX_Find(ssl->extensions, TLSX_KEY_SHARE)) != NULL) {
+            KeyShareEntry* kse = (KeyShareEntry*)ext->data;
+            c16toa(kse->group, cookie + idx);
+            idx += OPAQUE16_LEN;
+        }
+        return CreateCookie(ssl, cookie, idx);
+    }
+#endif
+
+    ret = InitHandshakeHashes(ssl);
+    if (ret != 0)
+        return ret;
+    ret = HashOutputRaw(ssl, header, sizeof(header));
+    if (ret != 0)
+        return ret;
+    return HashOutputRaw(ssl, hash, hashSz);
+}
+
+/* The value in the random field of a ServerHello to indicate
+ * HelloRetryRequest.
+ */
+static byte helloRetryRequestRandom[] = {
+    0xCF, 0x21, 0xAD, 0x74, 0xE5, 0x9A, 0x61, 0x11,
+    0xBE, 0x1D, 0x8C, 0x02, 0x1E, 0x65, 0xB8, 0x91,
+    0xC2, 0xA2, 0x11, 0x16, 0x7A, 0xBB, 0x8C, 0x5E,
+    0x07, 0x9E, 0x09, 0xE2, 0xC8, 0xA8, 0x33, 0x9C
+};
+#endif /* WOLFSSL_TLS13_DRAFT_18 */
+
+#ifndef NO_WOLFSSL_CLIENT
+#if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
+/* Setup pre-shared key based on the details in the extension data.
+ *
+ * ssl  SSL/TLS object.
+ * psk  Pre-shared key extension data.
+ * returns 0 on success, PSK_KEY_ERROR when the client PSK callback fails and
+ * other negative value on failure.
+ */
+static int SetupPskKey(WOLFSSL* ssl, PreSharedKey* psk)
+{
+    int ret;
+    byte suite[2];
+
+    if (psk == NULL)
+        return BAD_FUNC_ARG;
+
+    suite[0] = psk->cipherSuite0;
+    suite[1] = psk->cipherSuite;
+    if (!FindSuiteSSL(ssl, suite))
+        return PSK_KEY_ERROR;
+
+    ssl->options.cipherSuite0 = psk->cipherSuite0;
+    ssl->options.cipherSuite  = psk->cipherSuite;
+    if ((ret = SetCipherSpecs(ssl)) != 0)
+        return ret;
+
+#ifdef HAVE_SESSION_TICKET
+    if (psk->resumption) {
+    #ifdef WOLFSSL_EARLY_DATA
+        if (ssl->session.maxEarlyDataSz == 0)
+            ssl->earlyData = no_early_data;
+    #endif
+        /* Resumption PSK is master secret. */
+        ssl->arrays->psk_keySz = ssl->specs.hash_size;
+#ifdef WOLFSSL_TLS13_DRAFT_18
+        XMEMCPY(ssl->arrays->psk_key, ssl->session.masterSecret,
+                ssl->arrays->psk_keySz);
+#else
+        if ((ret = DeriveResumptionPSK(ssl, ssl->session.ticketNonce.data,
+                    ssl->session.ticketNonce.len, ssl->arrays->psk_key)) != 0) {
+            return ret;
+        }
+#endif
+    }
+#endif
+#ifndef NO_PSK
+    if (!psk->resumption) {
+    #ifndef WOLFSSL_PSK_ONE_ID
+        const char* cipherName = NULL;
+        byte cipherSuite0 = TLS13_BYTE, cipherSuite = WOLFSSL_DEF_PSK_CIPHER;
+
+        /* Get the pre-shared key. */
+        if (ssl->options.client_psk_tls13_cb != NULL) {
+            ssl->arrays->psk_keySz = ssl->options.client_psk_tls13_cb(ssl,
+                    (char *)psk->identity, ssl->arrays->client_identity,
+                    MAX_PSK_ID_LEN, ssl->arrays->psk_key, MAX_PSK_KEY_LEN,
+                    &cipherName);
+            if (GetCipherSuiteFromName(cipherName, &cipherSuite0,
+                                                           &cipherSuite) != 0) {
+                return PSK_KEY_ERROR;
+            }
+        }
+        else {
+            ssl->arrays->psk_keySz = ssl->options.client_psk_cb(ssl,
+                    (char *)psk->identity, ssl->arrays->client_identity,
+                    MAX_PSK_ID_LEN, ssl->arrays->psk_key, MAX_PSK_KEY_LEN);
+        }
+        if (ssl->arrays->psk_keySz == 0 ||
+                                     ssl->arrays->psk_keySz > MAX_PSK_KEY_LEN) {
+            return PSK_KEY_ERROR;
+        }
+
+        if (psk->cipherSuite0 != cipherSuite0 ||
+                                              psk->cipherSuite != cipherSuite) {
+            return PSK_KEY_ERROR;
+        }
+    #else
+        /* PSK information loaded during setting of default TLS extensions. */
+    #endif
+    }
+#endif
+
+    if (ssl->options.noPskDheKe)
+        ssl->arrays->preMasterSz = 0;
+
+    /* Derive the early secret using the PSK. */
+    return DeriveEarlySecret(ssl);
+}
+
+/* Derive and write the binders into the ClientHello in space left when
+ * writing the Pre-Shared Key extension.
+ *
+ * ssl     The SSL/TLS object.
+ * output  The buffer containing the ClientHello.
+ * idx     The index at the end of the completed ClientHello.
+ * returns 0 on success and otherwise failure.
+ */
+static int WritePSKBinders(WOLFSSL* ssl, byte* output, word32 idx)
+{
+    int           ret;
+    TLSX*         ext;
+    PreSharedKey* current;
+    byte          binderKey[WC_MAX_DIGEST_SIZE];
+    word16        len;
+
+    WOLFSSL_ENTER("WritePSKBinders");
+
+    ext = TLSX_Find(ssl->extensions, TLSX_PRE_SHARED_KEY);
+    if (ext == NULL)
+        return SANITY_MSG_E;
+
+    /* Get the size of the binders to determine where to write binders. */
+    ret = TLSX_PreSharedKey_GetSizeBinders((PreSharedKey*)ext->data,
+                                                            client_hello, &len);
+    if (ret < 0)
+        return ret;
+    idx -= len;
+
+    /* Hash truncated ClientHello - up to binders. */
+    ret = HashOutput(ssl, output, idx, 0);
+    if (ret != 0)
+        return ret;
+
+    current = (PreSharedKey*)ext->data;
+    /* Calculate the binder for each identity based on previous handshake data.
+     */
+    while (current != NULL) {
+        if ((ret = SetupPskKey(ssl, current)) != 0)
+            return ret;
+
+    #ifdef HAVE_SESSION_TICKET
+        if (current->resumption)
+            ret = DeriveBinderKeyResume(ssl, binderKey);
+    #endif
+    #ifndef NO_PSK
+        if (!current->resumption)
+            ret = DeriveBinderKey(ssl, binderKey);
+    #endif
+        if (ret != 0)
+            return ret;
+
+        /* Derive the Finished message secret. */
+        ret = DeriveFinishedSecret(ssl, binderKey,
+                                             ssl->keys.client_write_MAC_secret);
+        if (ret != 0)
+            return ret;
+
+        /* Build the HMAC of the handshake message data = binder. */
+        ret = BuildTls13HandshakeHmac(ssl, ssl->keys.client_write_MAC_secret,
+            current->binder, &current->binderLen);
+        if (ret != 0)
+            return ret;
+
+        current = current->next;
+    }
+
+    /* Data entered into extension, now write to message. */
+    ret = TLSX_PreSharedKey_WriteBinders((PreSharedKey*)ext->data, output + idx,
+                                                            client_hello, &len);
+    if (ret < 0)
+        return ret;
+
+    /* Hash binders to complete the hash of the ClientHello. */
+    ret = HashOutputRaw(ssl, output + idx, len);
+    if (ret < 0)
+        return ret;
+
+    #ifdef WOLFSSL_EARLY_DATA
+    if (ssl->earlyData != no_early_data) {
+        if ((ret = SetupPskKey(ssl, (PreSharedKey*)ext->data)) != 0)
+            return ret;
+
+        /* Derive early data encryption key. */
+        ret = DeriveTls13Keys(ssl, early_data_key, ENCRYPT_SIDE_ONLY, 1);
+        if (ret != 0)
+            return ret;
+        if ((ret = SetKeysSide(ssl, ENCRYPT_SIDE_ONLY)) != 0)
+            return ret;
+    }
+    #endif
+
+    WOLFSSL_LEAVE("WritePSKBinders", ret);
+
+    return ret;
+}
+#endif
+
+/* handle generation of TLS 1.3 client_hello (1) */
+/* Send a ClientHello message to the server.
+ * Include the information required to start a handshake with servers using
+ * protocol versions less than TLS v1.3.
+ * Only a client will send this message.
+ *
+ * ssl  The SSL/TLS object.
+ * returns 0 on success and otherwise failure.
+ */
+int SendTls13ClientHello(WOLFSSL* ssl)
+{
+    byte*  output;
+    word16 length;
+    word32 idx = RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ;
+    int    sendSz;
+    int    ret;
+
+    WOLFSSL_START(WC_FUNC_CLIENT_HELLO_SEND);
+    WOLFSSL_ENTER("SendTls13ClientHello");
+
+#ifdef HAVE_SESSION_TICKET
+    if (ssl->options.resuming &&
+            (ssl->session.version.major != ssl->version.major ||
+             ssl->session.version.minor != ssl->version.minor)) {
+    #ifndef WOLFSSL_NO_TLS12
+        if (ssl->session.version.major == ssl->version.major &&
+            ssl->session.version.minor < ssl->version.minor) {
+            /* Cannot resume with a different protocol version. */
+            ssl->options.resuming = 0;
+            ssl->version.major = ssl->session.version.major;
+            ssl->version.minor = ssl->session.version.minor;
+            return SendClientHello(ssl);
+        }
+        else
+    #endif
+            return VERSION_ERROR;
+    }
+#endif
+
+    if (ssl->suites == NULL) {
+        WOLFSSL_MSG("Bad suites pointer in SendTls13ClientHello");
+        return SUITES_ERROR;
+    }
+
+    /* Version | Random | Session Id | Cipher Suites | Compression */
+    length = VERSION_SZ + RAN_LEN + ENUM_LEN + ssl->suites->suiteSz +
+             SUITE_LEN + COMP_LEN + ENUM_LEN;
+#ifndef WOLFSSL_TLS13_DRAFT_18
+    #if defined(WOLFSSL_TLS13_MIDDLEBOX_COMPAT)
+    length += ID_LEN;
+    #else
+    if (ssl->session.sessionIDSz > 0)
+        length += ssl->session.sessionIDSz;
+    #endif
+#endif
+
+    /* Auto populate extensions supported unless user defined. */
+    if ((ret = TLSX_PopulateExtensions(ssl, 0)) != 0)
+        return ret;
+#ifdef WOLFSSL_EARLY_DATA
+    #ifndef NO_PSK
+        if (!ssl->options.resuming &&
+                                     ssl->options.client_psk_tls13_cb == NULL &&
+                                     ssl->options.client_psk_cb == NULL)
+    #else
+        if (!ssl->options.resuming)
+    #endif
+            ssl->earlyData = no_early_data;
+    if (ssl->options.serverState == SERVER_HELLO_RETRY_REQUEST_COMPLETE)
+        ssl->earlyData = no_early_data;
+    if (ssl->earlyData == no_early_data)
+        TLSX_Remove(&ssl->extensions, TLSX_EARLY_DATA, ssl->heap);
+    if (ssl->earlyData != no_early_data &&
+                                       (ret = TLSX_EarlyData_Use(ssl, 0)) < 0) {
+        return ret;
+    }
+#endif
+    /* Include length of TLS extensions. */
+    ret = TLSX_GetRequestSize(ssl, client_hello, &length);
+    if (ret != 0)
+        return ret;
+
+    /* Total message size. */
+    sendSz = length + HANDSHAKE_HEADER_SZ + RECORD_HEADER_SZ;
+
+    /* Check buffers are big enough and grow if needed. */
+    if ((ret = CheckAvailableSize(ssl, sendSz)) != 0)
+        return ret;
+
+    /* Get position in output buffer to write new message to. */
+    output = ssl->buffers.outputBuffer.buffer +
+             ssl->buffers.outputBuffer.length;
+
+    /* Put the record and handshake headers on. */
+    AddTls13Headers(output, length, client_hello, ssl);
+
+    /* Protocol version - negotiation now in extension: supported_versions. */
+    output[idx++] = SSLv3_MAJOR;
+    output[idx++] = TLSv1_2_MINOR;
+    /* Keep for downgrade. */
+    ssl->chVersion = ssl->version;
+
+    /* Client Random */
+    if (ssl->options.connectState == CONNECT_BEGIN) {
+        ret = wc_RNG_GenerateBlock(ssl->rng, output + idx, RAN_LEN);
+        if (ret != 0)
+            return ret;
+
+        /* Store random for possible second ClientHello. */
+        XMEMCPY(ssl->arrays->clientRandom, output + idx, RAN_LEN);
+    }
+    else
+        XMEMCPY(output + idx, ssl->arrays->clientRandom, RAN_LEN);
+    idx += RAN_LEN;
+
+#ifdef WOLFSSL_TLS13_DRAFT_18
+    /* TLS v1.3 does not use session id - 0 length. */
+    output[idx++] = 0;
+#else
+    if (ssl->session.sessionIDSz > 0) {
+        /* Session resumption for old versions of protocol. */
+        output[idx++] = ID_LEN;
+        XMEMCPY(output + idx, ssl->session.sessionID, ssl->session.sessionIDSz);
+        idx += ID_LEN;
+    }
+    else {
+    #ifdef WOLFSSL_TLS13_MIDDLEBOX_COMPAT
+        output[idx++] = ID_LEN;
+        XMEMCPY(output + idx, ssl->arrays->clientRandom, ID_LEN);
+        idx += ID_LEN;
+    #else
+        /* TLS v1.3 does not use session id - 0 length. */
+        output[idx++] = 0;
+    #endif /* WOLFSSL_TLS13_MIDDLEBOX_COMPAT */
+    }
+#endif /* WOLFSSL_TLS13_DRAFT_18 */
+
+    /* Cipher suites */
+    c16toa(ssl->suites->suiteSz, output + idx);
+    idx += OPAQUE16_LEN;
+    XMEMCPY(output + idx, &ssl->suites->suites, ssl->suites->suiteSz);
+    idx += ssl->suites->suiteSz;
+
+    /* Compression not supported in TLS v1.3. */
+    output[idx++] = COMP_LEN;
+    output[idx++] = NO_COMPRESSION;
+
+    /* Write out extensions for a request. */
+    length = 0;
+    ret = TLSX_WriteRequest(ssl, output + idx, client_hello, &length);
+    if (ret != 0)
+        return ret;
+    idx += length;
+
+#if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
+    /* Resumption has a specific set of extensions and binder is calculated
+     * for each identity.
+     */
+    if (TLSX_Find(ssl->extensions, TLSX_PRE_SHARED_KEY))
+        ret = WritePSKBinders(ssl, output, idx);
+    else
+#endif
+        ret = HashOutput(ssl, output, idx, 0);
+    if (ret != 0)
+        return ret;
+
+    ssl->options.clientState = CLIENT_HELLO_COMPLETE;
+
+#ifdef WOLFSSL_CALLBACKS
+    if (ssl->hsInfoOn) AddPacketName(ssl, "ClientHello");
+    if (ssl->toInfoOn) {
+        AddPacketInfo(ssl, "ClientHello", handshake, output, sendSz,
+                      WRITE_PROTO, ssl->heap);
+    }
+#endif
+
+    ssl->buffers.outputBuffer.length += sendSz;
+
+#ifdef WOLFSSL_EARLY_DATA_GROUP
+    if (ssl->earlyData == no_early_data)
+#endif
+        ret = SendBuffered(ssl);
+
+
+    WOLFSSL_LEAVE("SendTls13ClientHello", ret);
+    WOLFSSL_END(WC_FUNC_CLIENT_HELLO_SEND);
+
+    return ret;
+}
+
+#ifdef WOLFSSL_TLS13_DRAFT_18
+/* handle rocessing of TLS 1.3 hello_retry_request (6) */
+/* Parse and handle a HelloRetryRequest message.
+ * Only a client will receive this message.
+ *
+ * ssl       The SSL/TLS object.
+ * input     The message buffer.
+ * inOutIdx  On entry, the index into the message buffer of
+ *           HelloRetryRequest.
+ *           On exit, the index of byte after the HelloRetryRequest message.
+ * totalSz   The length of the current handshake message.
+ * returns 0 on success and otherwise failure.
+ */
+static int DoTls13HelloRetryRequest(WOLFSSL* ssl, const byte* input,
+                                    word32* inOutIdx, word32 totalSz)
+{
+    int             ret;
+    word32          begin = *inOutIdx;
+    word32          i = begin;
+    word16          totalExtSz;
+    ProtocolVersion pv;
+
+    WOLFSSL_ENTER("DoTls13HelloRetryRequest");
+
+#ifdef WOLFSSL_CALLBACKS
+    if (ssl->hsInfoOn) AddPacketName(ssl, "HelloRetryRequest");
+    if (ssl->toInfoOn) AddLateName("HelloRetryRequest", &ssl->timeoutInfo);
+#endif
+
+    /* Version info and length field of extension data. */
+    if (totalSz < i - begin + OPAQUE16_LEN + OPAQUE16_LEN + OPAQUE16_LEN)
+        return BUFFER_ERROR;
+
+    /* Protocol version. */
+    XMEMCPY(&pv, input + i, OPAQUE16_LEN);
+    i += OPAQUE16_LEN;
+    ret = CheckVersion(ssl, pv);
+    if (ret != 0)
+        return ret;
+
+    /* Length of extension data. */
+    ato16(&input[i], &totalExtSz);
+    i += OPAQUE16_LEN;
+    if (totalExtSz == 0) {
+        WOLFSSL_MSG("HelloRetryRequest must contain extensions");
+        return MISSING_HANDSHAKE_DATA;
+    }
+
+    /* Extension data. */
+    if (i - begin + totalExtSz > totalSz)
+        return BUFFER_ERROR;
+    if ((ret = TLSX_Parse(ssl, (byte *)(input + i), totalExtSz,
+                          hello_retry_request, NULL)) != 0)
+        return ret;
+    /* The KeyShare extension parsing fails when not valid. */
+
+    /* Move index to byte after message. */
+    *inOutIdx = i + totalExtSz;
+
+    ssl->options.tls1_3 = 1;
+    ssl->options.serverState = SERVER_HELLO_RETRY_REQUEST_COMPLETE;
+
+    WOLFSSL_LEAVE("DoTls13HelloRetryRequest", ret);
+
+    return ret;
+}
+#endif
+
+
+/* handle processing of TLS 1.3 server_hello (2) and hello_retry_request (6) */
+/* Handle the ServerHello message from the server.
+ * Only a client will receive this message.
+ *
+ * ssl       The SSL/TLS object.
+ * input     The message buffer.
+ * inOutIdx  On entry, the index into the message buffer of ServerHello.
+ *           On exit, the index of byte after the ServerHello message.
+ * helloSz   The length of the current handshake message.
+ * returns 0 on success and otherwise failure.
+ */
+int DoTls13ServerHello(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
+                       word32 helloSz, byte* extMsgType)
+{
+    ProtocolVersion pv;
+    word32          i = *inOutIdx;
+    word32          begin = i;
+    int             ret;
+#ifndef WOLFSSL_TLS13_DRAFT_18
+    byte            sessIdSz;
+    const byte*     sessId;
+    byte            b;
+    int             foundVersion;
+#endif
+    word16          totalExtSz;
+#if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
+    TLSX*           ext;
+    PreSharedKey*   psk = NULL;
+#endif
+
+    WOLFSSL_START(WC_FUNC_SERVER_HELLO_DO);
+    WOLFSSL_ENTER("DoTls13ServerHello");
+
+#ifdef WOLFSSL_CALLBACKS
+    if (ssl->hsInfoOn) AddPacketName(ssl, "ServerHello");
+    if (ssl->toInfoOn) AddLateName("ServerHello", &ssl->timeoutInfo);
+#endif
+
+    /* Protocol version length check. */
+    if (OPAQUE16_LEN > helloSz)
+        return BUFFER_ERROR;
+
+    /* Protocol version */
+    XMEMCPY(&pv, input + i, OPAQUE16_LEN);
+    i += OPAQUE16_LEN;
+#ifdef WOLFSSL_TLS13_DRAFT_18
+    ret = CheckVersion(ssl, pv);
+    if (ret != 0)
+        return ret;
+    if (!IsAtLeastTLSv1_3(pv) && pv.major != TLS_DRAFT_MAJOR) {
+#ifndef WOLFSSL_NO_TLS12
+        if (ssl->options.downgrade) {
+            ssl->version = pv;
+            return DoServerHello(ssl, input, inOutIdx, helloSz);
+        }
+#endif
+
+        WOLFSSL_MSG("Client using higher version, fatal error");
+        return VERSION_ERROR;
+    }
+#else
+#ifndef WOLFSSL_NO_TLS12
+    if (pv.major == ssl->version.major  && pv.minor < TLSv1_2_MINOR &&
+                                                       ssl->options.downgrade) {
+        /* Force client hello version 1.2 to work for static RSA. */
+        ssl->chVersion.minor = TLSv1_2_MINOR;
+        ssl->version.minor = TLSv1_2_MINOR;
+        return DoServerHello(ssl, input, inOutIdx, helloSz);
+    }
+#endif
+    if (pv.major != ssl->version.major || pv.minor != TLSv1_2_MINOR)
+        return VERSION_ERROR;
+#endif
+
+#ifdef WOLFSSL_TLS13_DRAFT_18
+    /* Random length check */
+    if ((i - begin) + RAN_LEN > helloSz)
+        return BUFFER_ERROR;
+#else
+    /* Random and session id length check */
+    if ((i - begin) + RAN_LEN + ENUM_LEN > helloSz)
+        return BUFFER_ERROR;
+
+    if (XMEMCMP(input + i, helloRetryRequestRandom, RAN_LEN) == 0)
+        *extMsgType = hello_retry_request;
+#endif
+
+    /* Server random - keep for debugging. */
+    XMEMCPY(ssl->arrays->serverRandom, input + i, RAN_LEN);
+    i += RAN_LEN;
+
+#ifndef WOLFSSL_TLS13_DRAFT_18
+    /* Session id */
+    sessIdSz = input[i++];
+    if ((i - begin) + sessIdSz > helloSz)
+        return BUFFER_ERROR;
+    sessId = input + i;
+    i += sessIdSz;
+#endif /* WOLFSSL_TLS13_DRAFT_18 */
+    ssl->options.haveSessionId = 1;
+
+#ifdef WOLFSSL_TLS13_DRAFT_18
+    /* Ciphersuite check */
+    if ((i - begin) + OPAQUE16_LEN + OPAQUE16_LEN > helloSz)
+        return BUFFER_ERROR;
+#else
+    /* Ciphersuite and compression check */
+    if ((i - begin) + OPAQUE16_LEN + OPAQUE8_LEN > helloSz)
+        return BUFFER_ERROR;
+#endif
+
+    /* Set the cipher suite from the message. */
+    ssl->options.cipherSuite0 = input[i++];
+    ssl->options.cipherSuite  = input[i++];
+
+#ifndef WOLFSSL_TLS13_DRAFT_18
+    /* Compression */
+    b = input[i++];
+    if (b != 0) {
+        WOLFSSL_MSG("Must be no compression types in list");
+        return INVALID_PARAMETER;
+    }
+#endif
+
+#ifndef WOLFSSL_TLS13_DRAFT_18
+    if ((i - begin) + OPAQUE16_LEN > helloSz) {
+        if (!ssl->options.downgrade)
+            return BUFFER_ERROR;
+#ifndef WOLFSSL_NO_TLS12
+        ssl->version.minor = TLSv1_2_MINOR;
+#endif
+        ssl->options.haveEMS = 0;
+    }
+    if ((i - begin) < helloSz)
+#endif
+    {
+        /* Get extension length and length check. */
+        if ((i - begin) + OPAQUE16_LEN > helloSz)
+            return BUFFER_ERROR;
+        ato16(&input[i], &totalExtSz);
+        i += OPAQUE16_LEN;
+        if ((i - begin) + totalExtSz > helloSz)
+            return BUFFER_ERROR;
+
+#ifndef WOLFSSL_TLS13_DRAFT_18
+        /* Need to negotiate version first. */
+        if ((ret = TLSX_ParseVersion(ssl, (byte*)input + i, totalExtSz,
+                                                 *extMsgType, &foundVersion))) {
+            return ret;
+        }
+        if (!foundVersion) {
+            if (!ssl->options.downgrade) {
+                WOLFSSL_MSG("Server trying to downgrade to version less than "
+                            "TLS v1.3");
+                return VERSION_ERROR;
+            }
+
+            if (pv.minor < ssl->options.minDowngrade)
+                return VERSION_ERROR;
+            ssl->version.minor = pv.minor;
+        }
+#endif
+
+        /* Parse and handle extensions. */
+        ret = TLSX_Parse(ssl, (byte *) input + i, totalExtSz, *extMsgType,
+                                                                          NULL);
+        if (ret != 0)
+            return ret;
+
+        i += totalExtSz;
+    }
+    *inOutIdx = i;
+
+    ssl->options.serverState = SERVER_HELLO_COMPLETE;
+
+#ifdef HAVE_SECRET_CALLBACK
+    if (ssl->sessionSecretCb != NULL) {
+        int secretSz = SECRET_LEN;
+        ret = ssl->sessionSecretCb(ssl, ssl->session.masterSecret,
+                                   &secretSz, ssl->sessionSecretCtx);
+        if (ret != 0 || secretSz != SECRET_LEN) {
+            return SESSION_SECRET_CB_E;
+        }
+    }
+#endif /* HAVE_SECRET_CALLBACK */
+
+#ifndef WOLFSSL_TLS13_DRAFT_18
+    /* Version only negotiated in extensions for TLS v1.3.
+     * Only now do we know how to deal with session id.
+     */
+    if (!IsAtLeastTLSv1_3(ssl->version)) {
+#ifndef WOLFSSL_NO_TLS12
+        ssl->arrays->sessionIDSz = sessIdSz;
+
+        if (ssl->arrays->sessionIDSz > ID_LEN) {
+            WOLFSSL_MSG("Invalid session ID size");
+            ssl->arrays->sessionIDSz = 0;
+            return BUFFER_ERROR;
+        }
+        else if (ssl->arrays->sessionIDSz) {
+            XMEMCPY(ssl->arrays->sessionID, sessId, ssl->arrays->sessionIDSz);
+            ssl->options.haveSessionId = 1;
+        }
+
+        /* Force client hello version 1.2 to work for static RSA. */
+        ssl->chVersion.minor = TLSv1_2_MINOR;
+        /* Complete TLS v1.2 processing of ServerHello. */
+        ret = CompleteServerHello(ssl);
+#else
+        WOLFSSL_MSG("Client using higher version, fatal error");
+        ret = VERSION_ERROR;
+#endif
+
+        WOLFSSL_LEAVE("DoTls13ServerHello", ret);
+
+        return ret;
+    }
+
+    #ifdef WOLFSSL_TLS13_MIDDLEBOX_COMPAT
+    if (sessIdSz == 0)
+        return INVALID_PARAMETER;
+    if (ssl->session.sessionIDSz != 0) {
+        if (ssl->session.sessionIDSz != sessIdSz ||
+                   XMEMCMP(ssl->session.sessionID, sessId, sessIdSz) != 0) {
+            return INVALID_PARAMETER;
+        }
+    }
+    else if (XMEMCMP(ssl->arrays->clientRandom, sessId, sessIdSz) != 0)
+        return INVALID_PARAMETER;
+    #else
+    if (sessIdSz != ssl->session.sessionIDSz || (sessIdSz > 0 &&
+                  XMEMCMP(ssl->session.sessionID, sessId, sessIdSz) != 0)) {
+        WOLFSSL_MSG("Server sent different session id");
+        return INVALID_PARAMETER;
+    }
+    #endif /* WOLFSSL_TLS13_MIDDLEBOX_COMPAT */
+#endif
+
+    ret = SetCipherSpecs(ssl);
+    if (ret != 0)
+        return ret;
+#ifdef HAVE_NULL_CIPHER
+    if (ssl->options.cipherSuite0 == ECC_BYTE &&
+                              (ssl->options.cipherSuite == TLS_SHA256_SHA256 ||
+                               ssl->options.cipherSuite == TLS_SHA384_SHA384)) {
+        ;
+    }
+    else
+#endif
+    /* Check that the negotiated ciphersuite matches protocol version. */
+    if (ssl->options.cipherSuite0 != TLS13_BYTE) {
+        WOLFSSL_MSG("Server sent non-TLS13 cipher suite in TLS 1.3 packet");
+        return INVALID_PARAMETER;
+    }
+
+#if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
+#ifndef WOLFSSL_TLS13_DRAFT_18
+    if (*extMsgType == server_hello)
+#endif
+    {
+        ext = TLSX_Find(ssl->extensions, TLSX_PRE_SHARED_KEY);
+        if (ext != NULL)
+            psk = (PreSharedKey*)ext->data;
+        while (psk != NULL && !psk->chosen)
+            psk = psk->next;
+        if (psk == NULL) {
+            ssl->options.resuming = 0;
+            ssl->arrays->psk_keySz = 0;
+            XMEMSET(ssl->arrays->psk_key, 0, MAX_PSK_KEY_LEN);
+        }
+        else if ((ret = SetupPskKey(ssl, psk)) != 0)
+            return ret;
+    }
+#endif
+
+#ifdef WOLFSSL_TLS13_DRAFT_18
+    ssl->keys.encryptionOn = 1;
+#else
+    if (*extMsgType == server_hello) {
+        ssl->keys.encryptionOn = 1;
+        ssl->options.serverState = SERVER_HELLO_COMPLETE;
+    }
+    else {
+        ssl->options.tls1_3 = 1;
+        ssl->options.serverState = SERVER_HELLO_RETRY_REQUEST_COMPLETE;
+
+        ret = RestartHandshakeHash(ssl);
+    }
+#endif
+
+    WOLFSSL_LEAVE("DoTls13ServerHello", ret);
+    WOLFSSL_END(WC_FUNC_SERVER_HELLO_DO);
+
+    return ret;
+}
+
+/* handle processing TLS 1.3 encrypted_extensions (8) */
+/* Parse and handle an EncryptedExtensions message.
+ * Only a client will receive this message.
+ *
+ * ssl       The SSL/TLS object.
+ * input     The message buffer.
+ * inOutIdx  On entry, the index into the message buffer of
+ *           EncryptedExtensions.
+ *           On exit, the index of byte after the EncryptedExtensions
+ *           message.
+ * totalSz   The length of the current handshake message.
+ * returns 0 on success and otherwise failure.
+ */
+static int DoTls13EncryptedExtensions(WOLFSSL* ssl, const byte* input,
+                                      word32* inOutIdx, word32 totalSz)
+{
+    int    ret;
+    word32 begin = *inOutIdx;
+    word32 i = begin;
+    word16 totalExtSz;
+
+    WOLFSSL_START(WC_FUNC_ENCRYPTED_EXTENSIONS_DO);
+    WOLFSSL_ENTER("DoTls13EncryptedExtensions");
+
+#ifdef WOLFSSL_CALLBACKS
+    if (ssl->hsInfoOn) AddPacketName(ssl, "EncryptedExtensions");
+    if (ssl->toInfoOn) AddLateName("EncryptedExtensions", &ssl->timeoutInfo);
+#endif
+
+    /* Length field of extension data. */
+    if (totalSz < i - begin + OPAQUE16_LEN)
+        return BUFFER_ERROR;
+    ato16(&input[i], &totalExtSz);
+    i += OPAQUE16_LEN;
+
+    /* Extension data. */
+    if (i - begin + totalExtSz > totalSz)
+        return BUFFER_ERROR;
+    if ((ret = TLSX_Parse(ssl, (byte *)(input + i), totalExtSz,
+                          encrypted_extensions, NULL)))
+        return ret;
+
+    /* Move index to byte after message. */
+    *inOutIdx = i + totalExtSz;
+
+    /* Always encrypted. */
+    *inOutIdx += ssl->keys.padSz;
+
+#ifdef WOLFSSL_EARLY_DATA
+    if (ssl->earlyData != no_early_data) {
+        TLSX* ext = TLSX_Find(ssl->extensions, TLSX_EARLY_DATA);
+        if (ext == NULL || !ext->val)
+            ssl->earlyData = no_early_data;
+    }
+#endif
+
+#ifdef WOLFSSL_EARLY_DATA
+    if (ssl->earlyData == no_early_data) {
+        ret = SetKeysSide(ssl, ENCRYPT_SIDE_ONLY);
+        if (ret != 0)
+            return ret;
+    }
+#endif
+
+    ssl->options.serverState = SERVER_ENCRYPTED_EXTENSIONS_COMPLETE;
+
+    WOLFSSL_LEAVE("DoTls13EncryptedExtensions", ret);
+    WOLFSSL_END(WC_FUNC_ENCRYPTED_EXTENSIONS_DO);
+
+    return ret;
+}
+
+/* handle processing TLS v1.3 certificate_request (13) */
+/* Handle a TLS v1.3 CertificateRequest message.
+ * This message is always encrypted.
+ * Only a client will receive this message.
+ *
+ * ssl       The SSL/TLS object.
+ * input     The message buffer.
+ * inOutIdx  On entry, the index into the message buffer of CertificateRequest.
+ *           On exit, the index of byte after the CertificateRequest message.
+ * size      The length of the current handshake message.
+ * returns 0 on success and otherwise failure.
+ */
+static int DoTls13CertificateRequest(WOLFSSL* ssl, const byte* input,
+                                     word32* inOutIdx, word32 size)
+{
+    word16      len;
+    word32      begin = *inOutIdx;
+    int         ret = 0;
+#ifndef WOLFSSL_TLS13_DRAFT_18
+    Suites      peerSuites;
+#endif
+#ifdef WOLFSSL_POST_HANDSHAKE_AUTH
+    CertReqCtx* certReqCtx;
+#endif
+
+    WOLFSSL_START(WC_FUNC_CERTIFICATE_REQUEST_DO);
+    WOLFSSL_ENTER("DoTls13CertificateRequest");
+
+#ifndef WOLFSSL_TLS13_DRAFT_18
+    XMEMSET(&peerSuites, 0, sizeof(Suites));
+#endif
+#ifdef WOLFSSL_CALLBACKS
+    if (ssl->hsInfoOn) AddPacketName(ssl, "CertificateRequest");
+    if (ssl->toInfoOn) AddLateName("CertificateRequest", &ssl->timeoutInfo);
+#endif
+
+    if ((*inOutIdx - begin) + OPAQUE8_LEN > size)
+        return BUFFER_ERROR;
+
+    /* Length of the request context. */
+    len = input[(*inOutIdx)++];
+    if ((*inOutIdx - begin) + len > size)
+        return BUFFER_ERROR;
+    if (ssl->options.connectState < FINISHED_DONE && len > 0)
+        return BUFFER_ERROR;
+
+#ifdef WOLFSSL_POST_HANDSHAKE_AUTH
+    /* CertReqCtx has one byte at end for context value.
+     * Increase size to handle other implementations sending more than one byte.
+     * That is, allocate extra space, over one byte, to hold the context value.
+     */
+    certReqCtx = (CertReqCtx*)XMALLOC(sizeof(CertReqCtx) + len - 1, ssl->heap,
+                                                       DYNAMIC_TYPE_TMP_BUFFER);
+    if (certReqCtx == NULL)
+        return MEMORY_E;
+    certReqCtx->next = ssl->certReqCtx;
+    certReqCtx->len = len;
+    XMEMCPY(&certReqCtx->ctx, input + *inOutIdx, len);
+    ssl->certReqCtx = certReqCtx;
+#endif
+    *inOutIdx += len;
+
+#ifdef WOLFSSL_TLS13_DRAFT_18
+    /* Signature and hash algorithms. */
+    if ((*inOutIdx - begin) + OPAQUE16_LEN > size)
+        return BUFFER_ERROR;
+    ato16(input + *inOutIdx, &len);
+    *inOutIdx += OPAQUE16_LEN;
+    if ((*inOutIdx - begin) + len > size)
+        return BUFFER_ERROR;
+    if (PickHashSigAlgo(ssl, input + *inOutIdx, len) != 0 &&
+                 ssl->buffers.certificate && ssl->buffers.certificate->buffer &&
+                 ssl->buffers.key && ssl->buffers.key->buffer) {
+        return INVALID_PARAMETER;
+    }
+    *inOutIdx += len;
+
+    /* Length of certificate authority data. */
+    if ((*inOutIdx - begin) + OPAQUE16_LEN > size)
+        return BUFFER_ERROR;
+    ato16(input + *inOutIdx, &len);
+    *inOutIdx += OPAQUE16_LEN;
+    if ((*inOutIdx - begin) + len > size)
+        return BUFFER_ERROR;
+
+    /* Certificate authorities. */
+    while (len) {
+        word16 dnSz;
+
+        if ((*inOutIdx - begin) + OPAQUE16_LEN > size)
+            return BUFFER_ERROR;
+
+        ato16(input + *inOutIdx, &dnSz);
+        *inOutIdx += OPAQUE16_LEN;
+
+        if ((*inOutIdx - begin) + dnSz > size)
+            return BUFFER_ERROR;
+
+        *inOutIdx += dnSz;
+        len -= OPAQUE16_LEN + dnSz;
+    }
+
+    /* Certificate extensions */
+    if ((*inOutIdx - begin) + OPAQUE16_LEN > size)
+        return BUFFER_ERROR;
+    ato16(input + *inOutIdx, &len);
+    *inOutIdx += OPAQUE16_LEN;
+    if ((*inOutIdx - begin) + len > size)
+        return BUFFER_ERROR;
+    *inOutIdx += len;
+#else
+    /* TODO: Add support for more extensions:
+     *   signed_certificate_timestamp, certificate_authorities, oid_filters.
+     */
+    /* Certificate extensions */
+    if ((*inOutIdx - begin) + OPAQUE16_LEN > size)
+        return BUFFER_ERROR;
+    ato16(input + *inOutIdx, &len);
+    *inOutIdx += OPAQUE16_LEN;
+    if ((*inOutIdx - begin) + len > size)
+        return BUFFER_ERROR;
+    if (len == 0)
+        return INVALID_PARAMETER;
+    if ((ret = TLSX_Parse(ssl, (byte *)(input + *inOutIdx), len,
+                                           certificate_request, &peerSuites))) {
+        return ret;
+    }
+    *inOutIdx += len;
+#endif
+
+    if (ssl->buffers.certificate && ssl->buffers.certificate->buffer &&
+        ((ssl->buffers.key && ssl->buffers.key->buffer)
+        #ifdef HAVE_PK_CALLBACKS
+            || wolfSSL_CTX_IsPrivatePkSet(ssl->ctx)
+        #endif
+    )) {
+#ifndef WOLFSSL_TLS13_DRAFT_18
+        if (PickHashSigAlgo(ssl, peerSuites.hashSigAlgo,
+                                               peerSuites.hashSigAlgoSz) != 0) {
+            return INVALID_PARAMETER;
+        }
+#endif
+        ssl->options.sendVerify = SEND_CERT;
+    }
+    else {
+        ssl->options.sendVerify = SEND_BLANK_CERT;
+    }
+
+    /* This message is always encrypted so add encryption padding. */
+    *inOutIdx += ssl->keys.padSz;
+
+    WOLFSSL_LEAVE("DoTls13CertificateRequest", ret);
+    WOLFSSL_END(WC_FUNC_CERTIFICATE_REQUEST_DO);
+
+    return ret;
+}
+
+#endif /* !NO_WOLFSSL_CLIENT */
+
+#ifndef NO_WOLFSSL_SERVER
+#if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
+/* Refine list of supported cipher suites to those common to server and client.
+ *
+ * ssl         SSL/TLS object.
+ * peerSuites  The peer's advertised list of supported cipher suites.
+ */
+static void RefineSuites(WOLFSSL* ssl, Suites* peerSuites)
+{
+    byte suites[WOLFSSL_MAX_SUITE_SZ];
+    int suiteSz = 0;
+    word16 i, j;
+
+    XMEMSET(suites, 0, WOLFSSL_MAX_SUITE_SZ);
+
+    for (i = 0; i < ssl->suites->suiteSz; i += 2) {
+        for (j = 0; j < peerSuites->suiteSz; j += 2) {
+            if (ssl->suites->suites[i+0] == peerSuites->suites[j+0] &&
+                ssl->suites->suites[i+1] == peerSuites->suites[j+1]) {
+                suites[suiteSz++] = peerSuites->suites[j+0];
+                suites[suiteSz++] = peerSuites->suites[j+1];
+            }
+        }
+    }
+
+    ssl->suites->suiteSz = suiteSz;
+    XMEMCPY(ssl->suites->suites, &suites, sizeof(suites));
+}
+
+/* Handle any Pre-Shared Key (PSK) extension.
+ * Must do this in ClientHello as it requires a hash of the truncated message.
+ * Don't know size of binders until Pre-Shared Key extension has been parsed.
+ *
+ * ssl       The SSL/TLS object.
+ * input     The ClientHello message.
+ * helloSz   The size of the ClientHello message (including binders if present).
+ * usingPSK  Indicates handshake is using Pre-Shared Keys.
+ * returns 0 on success and otherwise failure.
+ */
+static int DoPreSharedKeys(WOLFSSL* ssl, const byte* input, word32 helloSz,
+                           int* usingPSK)
+{
+    int           ret;
+    TLSX*         ext;
+    word16        bindersLen;
+    PreSharedKey* current;
+    byte          binderKey[WC_MAX_DIGEST_SIZE];
+    byte          binder[WC_MAX_DIGEST_SIZE];
+    word32        binderLen;
+    word16        modes;
+    byte          suite[2];
+#ifdef WOLFSSL_EARLY_DATA
+    int           pskCnt = 0;
+    TLSX*         extEarlyData;
+#endif
+#ifndef NO_PSK
+    const char*   cipherName = NULL;
+    byte          cipherSuite0 = TLS13_BYTE;
+    byte          cipherSuite  = WOLFSSL_DEF_PSK_CIPHER;
+#endif
+
+    WOLFSSL_ENTER("DoPreSharedKeys");
+
+    ext = TLSX_Find(ssl->extensions, TLSX_PRE_SHARED_KEY);
+    if (ext == NULL) {
+        /* Hash data up to binders for deriving binders in PSK extension. */
+        ret = HashInput(ssl, input,  helloSz);
+        return ret;
+    }
+
+    /* Extensions pushed on stack/list and PSK must be last. */
+    if (ssl->extensions != ext)
+        return PSK_KEY_ERROR;
+
+    /* Assume we are going to resume with a pre-shared key. */
+    ssl->options.resuming = 1;
+
+    /* Find the pre-shared key extension and calculate hash of truncated
+     * ClientHello for binders.
+     */
+    ret = TLSX_PreSharedKey_GetSizeBinders((PreSharedKey*)ext->data,
+                                                     client_hello, &bindersLen);
+    if (ret < 0)
+        return ret;
+
+    /* Hash data up to binders for deriving binders in PSK extension. */
+    ret = HashInput(ssl, input,  helloSz - bindersLen);
+    if (ret != 0)
+        return ret;
+
+    /* Look through all client's pre-shared keys for a match. */
+    current = (PreSharedKey*)ext->data;
+    while (current != NULL) {
+    #ifdef WOLFSSL_EARLY_DATA
+        pskCnt++;
+    #endif
+
+    #ifndef NO_PSK
+        if (current->identityLen > MAX_PSK_ID_LEN) {
+            return BUFFER_ERROR;
+        }
+        XMEMCPY(ssl->arrays->client_identity, current->identity,
+                current->identityLen);
+        ssl->arrays->client_identity[current->identityLen] = '\0';
+    #endif
+
+    #ifdef HAVE_SESSION_TICKET
+        /* Decode the identity. */
+        if ((ret = DoClientTicket(ssl, current->identity, current->identityLen))
+                                                     == WOLFSSL_TICKET_RET_OK) {
+            word32 now;
+            int    diff;
+
+            now = TimeNowInMilliseconds();
+            if (now == (word32)GETTIME_ERROR)
+                return now;
+            diff = now - ssl->session.ticketSeen;
+            diff -= current->ticketAge - ssl->session.ticketAdd;
+            /* Check session and ticket age timeout.
+             * Allow +/- 1000 milliseconds on ticket age.
+             */
+            if (diff > (int)ssl->timeout * 1000 || diff < -1000 ||
+                                     diff - MAX_TICKET_AGE_SECS * 1000 > 1000) {
+                /* Invalid difference, fallback to full handshake. */
+                ssl->options.resuming = 0;
+                break;
+            }
+
+            /* Check whether resumption is possible based on suites in SSL and
+             * ciphersuite in ticket.
+             */
+            suite[0] = ssl->session.cipherSuite0;
+            suite[1] = ssl->session.cipherSuite;
+            if (!FindSuiteSSL(ssl, suite)) {
+                current = current->next;
+                continue;
+            }
+
+        #ifdef WOLFSSL_EARLY_DATA
+            ssl->options.maxEarlyDataSz = ssl->session.maxEarlyDataSz;
+        #endif
+            /* Use the same cipher suite as before and set up for use. */
+            ssl->options.cipherSuite0   = ssl->session.cipherSuite0;
+            ssl->options.cipherSuite    = ssl->session.cipherSuite;
+            ret = SetCipherSpecs(ssl);
+            if (ret != 0)
+                return ret;
+
+            /* Resumption PSK is resumption master secret. */
+            ssl->arrays->psk_keySz = ssl->specs.hash_size;
+        #ifdef WOLFSSL_TLS13_DRAFT_18
+            XMEMCPY(ssl->arrays->psk_key, ssl->session.masterSecret,
+                    ssl->arrays->psk_keySz);
+        #else
+            if ((ret = DeriveResumptionPSK(ssl, ssl->session.ticketNonce.data,
+                    ssl->session.ticketNonce.len, ssl->arrays->psk_key)) != 0) {
+                return ret;
+            }
+        #endif
+
+            /* Derive the early secret using the PSK. */
+            ret = DeriveEarlySecret(ssl);
+            if (ret != 0)
+                return ret;
+            /* Derive the binder key to use to with HMAC. */
+            ret = DeriveBinderKeyResume(ssl, binderKey);
+            if (ret != 0)
+                return ret;
+        }
+        else
+    #endif
+    #ifndef NO_PSK
+        if ((ssl->options.server_psk_tls13_cb != NULL &&
+             (ssl->arrays->psk_keySz = ssl->options.server_psk_tls13_cb(ssl,
+                             ssl->arrays->client_identity, ssl->arrays->psk_key,
+                             MAX_PSK_KEY_LEN, &cipherName)) != 0 &&
+             GetCipherSuiteFromName(cipherName, &cipherSuite0,
+                                                          &cipherSuite) == 0) ||
+            (ssl->options.server_psk_cb != NULL &&
+             (ssl->arrays->psk_keySz = ssl->options.server_psk_cb(ssl,
+                             ssl->arrays->client_identity, ssl->arrays->psk_key,
+                             MAX_PSK_KEY_LEN)) != 0)) {
+            if (ssl->arrays->psk_keySz > MAX_PSK_KEY_LEN)
+                return PSK_KEY_ERROR;
+
+            /* Check whether PSK ciphersuite is in SSL. */
+            suite[0] = cipherSuite0;
+            suite[1] = cipherSuite;
+            if (!FindSuiteSSL(ssl, suite)) {
+                current = current->next;
+                continue;
+            }
+
+            /* Default to ciphersuite if cb doesn't specify. */
+            ssl->options.resuming = 0;
+
+            /* PSK age is always zero. */
+            if (current->ticketAge != ssl->session.ticketAdd)
+                return PSK_KEY_ERROR;
+
+            /* Set PSK ciphersuite into SSL. */
+            ssl->options.cipherSuite0 = cipherSuite0;
+            ssl->options.cipherSuite  = cipherSuite;
+            ret = SetCipherSpecs(ssl);
+            if (ret != 0)
+                return ret;
+
+            /* Derive the early secret using the PSK. */
+            ret = DeriveEarlySecret(ssl);
+            if (ret != 0)
+                return ret;
+            /* Derive the binder key to use to with HMAC. */
+            ret = DeriveBinderKey(ssl, binderKey);
+            if (ret != 0)
+                return ret;
+        }
+        else
+    #endif
+        {
+            current = current->next;
+            continue;
+        }
+
+        ssl->options.sendVerify = 0;
+
+        /* Derive the Finished message secret. */
+        ret = DeriveFinishedSecret(ssl, binderKey,
+                                             ssl->keys.client_write_MAC_secret);
+        if (ret != 0)
+            return ret;
+
+        /* Derive the binder and compare with the one in the extension. */
+        ret = BuildTls13HandshakeHmac(ssl,
+                         ssl->keys.client_write_MAC_secret, binder, &binderLen);
+        if (ret != 0)
+            return ret;
+        if (binderLen != current->binderLen ||
+                             XMEMCMP(binder, current->binder, binderLen) != 0) {
+            return BAD_BINDER;
+        }
+
+        /* This PSK works, no need to try any more. */
+        current->chosen = 1;
+        ext->resp = 1;
+        break;
+    }
+
+    /* Hash the rest of the ClientHello. */
+    ret = HashInputRaw(ssl, input + helloSz - bindersLen, bindersLen);
+    if (ret != 0)
+        return ret;
+
+    if (current == NULL) {
+#ifdef WOLFSSL_PSK_ID_PROTECTION
+    #ifndef NO_CERTS
+        if (ssl->buffers.certChainCnt != 0)
+            return 0;
+    #endif
+        return BAD_BINDER;
+#else
+        return 0;
+#endif
+    }
+
+#ifdef WOLFSSL_EARLY_DATA
+    extEarlyData = TLSX_Find(ssl->extensions, TLSX_EARLY_DATA);
+    if (extEarlyData != NULL) {
+        if (ssl->earlyData != no_early_data && current == ext->data) {
+            extEarlyData->resp = 1;
+
+            /* Derive early data decryption key. */
+            ret = DeriveTls13Keys(ssl, early_data_key, DECRYPT_SIDE_ONLY, 1);
+            if (ret != 0)
+                return ret;
+            if ((ret = SetKeysSide(ssl, DECRYPT_SIDE_ONLY)) != 0)
+                return ret;
+
+            ssl->earlyData = process_early_data;
+        }
+        else
+            extEarlyData->resp = 0;
+    }
+#endif
+
+    /* Get the PSK key exchange modes the client wants to negotiate. */
+    ext = TLSX_Find(ssl->extensions, TLSX_PSK_KEY_EXCHANGE_MODES);
+    if (ext == NULL)
+        return MISSING_HANDSHAKE_DATA;
+    modes = ext->val;
+
+    ext = TLSX_Find(ssl->extensions, TLSX_KEY_SHARE);
+    /* Use (EC)DHE for forward-security if possible. */
+    if ((modes & (1 << PSK_DHE_KE)) != 0 && !ssl->options.noPskDheKe &&
+                                                                  ext != NULL) {
+        /* Only use named group used in last session. */
+        ssl->namedGroup = ssl->session.namedGroup;
+
+        /* Pick key share and Generate a new key if not present. */
+        ret = TLSX_KeyShare_Establish(ssl);
+        if (ret == KEY_SHARE_ERROR) {
+            ssl->options.serverState = SERVER_HELLO_RETRY_REQUEST_COMPLETE;
+            ret = 0;
+        }
+        else if (ret < 0)
+            return ret;
+
+        /* Send new public key to client. */
+        ext->resp = 1;
+    }
+    else {
+        if ((modes & (1 << PSK_KE)) == 0)
+            return PSK_KEY_ERROR;
+        ssl->options.noPskDheKe = 1;
+        ssl->arrays->preMasterSz = 0;
+    }
+
+    *usingPSK = 1;
+
+    WOLFSSL_LEAVE("DoPreSharedKeys", ret);
+
+    return ret;
+}
+#endif
+
+#if !defined(WOLFSSL_TLS13_DRAFT_18) && defined(WOLFSSL_SEND_HRR_COOKIE)
+/* Check that the Cookie data's integrity.
+ *
+ * ssl       SSL/TLS object.
+ * cookie    The cookie data - hash and MAC.
+ * cookieSz  The length of the cookie data in bytes.
+ * returns Length of the hash on success, otherwise failure.
+ */
+static int CheckCookie(WOLFSSL* ssl, byte* cookie, byte cookieSz)
+{
+    int  ret;
+    byte mac[WC_MAX_DIGEST_SIZE] = {0};
+    Hmac cookieHmac;
+    byte cookieType = 0;
+    byte macSz = 0;
+
+#if !defined(NO_SHA) && defined(NO_SHA256)
+    cookieType = SHA;
+    macSz = WC_SHA_DIGEST_SIZE;
+#endif /* NO_SHA */
+#ifndef NO_SHA256
+    cookieType = WC_SHA256;
+    macSz = WC_SHA256_DIGEST_SIZE;
+#endif /* NO_SHA256 */
+
+    if (cookieSz < ssl->specs.hash_size + macSz)
+        return HRR_COOKIE_ERROR;
+    cookieSz -= macSz;
+    XMEMSET(&cookieHmac, 0, sizeof(Hmac));
+
+    ret = wc_HmacSetKey(&cookieHmac, cookieType,
+                        ssl->buffers.tls13CookieSecret.buffer,
+                        ssl->buffers.tls13CookieSecret.length);
+    if (ret != 0)
+        return ret;
+    if ((ret = wc_HmacUpdate(&cookieHmac, cookie, cookieSz)) != 0)
+        return ret;
+    if ((ret = wc_HmacFinal(&cookieHmac, mac)) != 0)
+        return ret;
+
+    if (ConstantCompare(cookie + cookieSz, mac, macSz) != 0)
+        return HRR_COOKIE_ERROR;
+    return cookieSz;
+}
+
+/* Length of the KeyShare Extension */
+#define HRR_KEY_SHARE_SZ   (OPAQUE16_LEN + OPAQUE16_LEN + OPAQUE16_LEN)
+/* Length of the Supported Vresions Extension */
+#define HRR_VERSIONS_SZ    (OPAQUE16_LEN + OPAQUE16_LEN + OPAQUE16_LEN)
+/* Length of the Cookie Extension excluding cookie data */
+#define HRR_COOKIE_HDR_SZ  (OPAQUE16_LEN + OPAQUE16_LEN + OPAQUE16_LEN)
+#ifdef WOLFSSL_TLS13_DRAFT_18
+/* PV | CipherSuite | Ext Len */
+#define HRR_BODY_SZ        (OPAQUE16_LEN + OPAQUE16_LEN + OPAQUE16_LEN)
+/* HH | PV | CipherSuite | Ext Len | Key Share | Cookie */
+#define MAX_HRR_SZ   (HANDSHAKE_HEADER_SZ   + \
+                        HRR_BODY_SZ         + \
+                          HRR_KEY_SHARE_SZ  + \
+                          HRR_COOKIE_HDR_SZ)
+#else
+/* PV | Random | Session Id | CipherSuite | Compression | Ext Len */
+#define HRR_BODY_SZ        (VERSION_SZ + RAN_LEN + ENUM_LEN + ID_LEN + \
+                            SUITE_LEN + COMP_LEN + OPAQUE16_LEN)
+/* HH | PV | CipherSuite | Ext Len | Key Share | Supported Version | Cookie */
+#define MAX_HRR_SZ   (HANDSHAKE_HEADER_SZ   + \
+                        HRR_BODY_SZ         + \
+                          HRR_KEY_SHARE_SZ  + \
+                          HRR_VERSIONS_SZ   + \
+                          HRR_COOKIE_HDR_SZ)
+#endif
+
+/* Restart the handshake hash from the cookie value.
+ *
+ * ssl     SSL/TLS object.
+ * cookie  Cookie data from client.
+ * returns 0 on success, otherwise failure.
+ */
+static int RestartHandshakeHashWithCookie(WOLFSSL* ssl, Cookie* cookie)
+{
+    byte   header[HANDSHAKE_HEADER_SZ] = {0};
+    byte   hrr[MAX_HRR_SZ] = {0};
+    int    hrrIdx;
+    word32 idx;
+    byte   hashSz;
+    byte*  cookieData;
+    byte   cookieDataSz;
+    word16 length;
+    int    keyShareExt = 0;
+    int    ret;
+
+    cookieDataSz = ret = CheckCookie(ssl, &cookie->data, cookie->len);
+    if (ret < 0)
+        return ret;
+    hashSz = cookie->data;
+    cookieData = &cookie->data;
+    idx = OPAQUE8_LEN;
+
+    /* Restart handshake hash with synthetic message hash. */
+    AddTls13HandShakeHeader(header, hashSz, 0, 0, message_hash, ssl);
+    if ((ret = InitHandshakeHashes(ssl)) != 0)
+        return ret;
+    if ((ret = HashOutputRaw(ssl, header, sizeof(header))) != 0)
+        return ret;
+    if ((ret = HashOutputRaw(ssl, cookieData + idx, hashSz)) != 0)
+        return ret;
+
+    /* Reconstruct the HelloRetryMessage for handshake hash. */
+#ifdef WOLFSSL_TLS13_DRAFT_18
+    length = HRR_BODY_SZ + HRR_COOKIE_HDR_SZ + cookie->len;
+#else
+    length = HRR_BODY_SZ - ID_LEN + ssl->session.sessionIDSz +
+             HRR_COOKIE_HDR_SZ + cookie->len;
+    length += HRR_VERSIONS_SZ;
+#endif
+    if (cookieDataSz > hashSz + OPAQUE16_LEN) {
+        keyShareExt = 1;
+        length += HRR_KEY_SHARE_SZ;
+    }
+#ifdef WOLFSSL_TLS13_DRAFT_18
+    AddTls13HandShakeHeader(hrr, length, 0, 0, hello_retry_request, ssl);
+
+    idx += hashSz;
+    hrrIdx = HANDSHAKE_HEADER_SZ;
+    /* The negotiated protocol version. */
+    hrr[hrrIdx++] = TLS_DRAFT_MAJOR;
+    hrr[hrrIdx++] = TLS_DRAFT_MINOR;
+    /* Cipher Suite */
+    hrr[hrrIdx++] = cookieData[idx++];
+    hrr[hrrIdx++] = cookieData[idx++];
+
+    /* Extensions' length */
+    length -= HRR_BODY_SZ;
+    c16toa(length, hrr + hrrIdx);
+    hrrIdx += 2;
+#else
+    AddTls13HandShakeHeader(hrr, length, 0, 0, server_hello, ssl);
+
+    idx += hashSz;
+    hrrIdx = HANDSHAKE_HEADER_SZ;
+
+    /* The negotiated protocol version. */
+    hrr[hrrIdx++] = ssl->version.major;
+    hrr[hrrIdx++] = TLSv1_2_MINOR;
+
+    /* HelloRetryRequest message has fixed value for random. */
+    XMEMCPY(hrr + hrrIdx, helloRetryRequestRandom, RAN_LEN);
+    hrrIdx += RAN_LEN;
+
+    hrr[hrrIdx++] = ssl->session.sessionIDSz;
+    if (ssl->session.sessionIDSz > 0) {
+        XMEMCPY(hrr + hrrIdx, ssl->session.sessionID, ssl->session.sessionIDSz);
+        hrrIdx += ssl->session.sessionIDSz;
+    }
+
+    /* Cipher Suite */
+    hrr[hrrIdx++] = cookieData[idx++];
+    hrr[hrrIdx++] = cookieData[idx++];
+
+    /* Compression not supported in TLS v1.3. */
+    hrr[hrrIdx++] = 0;
+
+    /* Extensions' length */
+    length -= HRR_BODY_SZ - ID_LEN + ssl->session.sessionIDSz;
+    c16toa(length, hrr + hrrIdx);
+    hrrIdx += 2;
+
+#endif
+    /* Optional KeyShare Extension */
+    if (keyShareExt) {
+        c16toa(TLSX_KEY_SHARE, hrr + hrrIdx);
+        hrrIdx += 2;
+        c16toa(OPAQUE16_LEN, hrr + hrrIdx);
+        hrrIdx += 2;
+        hrr[hrrIdx++] = cookieData[idx++];
+        hrr[hrrIdx++] = cookieData[idx++];
+    }
+#ifndef WOLFSSL_TLS13_DRAFT_18
+    c16toa(TLSX_SUPPORTED_VERSIONS, hrr + hrrIdx);
+    hrrIdx += 2;
+    c16toa(OPAQUE16_LEN, hrr + hrrIdx);
+    hrrIdx += 2;
+    #ifdef WOLFSSL_TLS13_DRAFT
+        hrr[hrrIdx++] = TLS_DRAFT_MAJOR;
+        hrr[hrrIdx++] = TLS_DRAFT_MINOR;
+    #else
+        hrr[hrrIdx++] = ssl->version.major;
+        hrr[hrrIdx++] = ssl->version.minor;
+    #endif
+#endif
+    /* Mandatory Cookie Extension */
+    c16toa(TLSX_COOKIE, hrr + hrrIdx);
+    hrrIdx += 2;
+    c16toa(cookie->len + OPAQUE16_LEN, hrr + hrrIdx);
+    hrrIdx += 2;
+    c16toa(cookie->len, hrr + hrrIdx);
+    hrrIdx += 2;
+
+#ifdef WOLFSSL_DEBUG_TLS
+    WOLFSSL_MSG("Reconstucted HelloRetryRequest");
+    WOLFSSL_BUFFER(hrr, hrrIdx);
+    WOLFSSL_MSG("Cookie");
+    WOLFSSL_BUFFER(cookieData, cookie->len);
+#endif
+
+    if ((ret = HashOutputRaw(ssl, hrr, hrrIdx)) != 0)
+        return ret;
+    return HashOutputRaw(ssl, cookieData, cookie->len);
+}
+#endif
+
+/* Do SupportedVersion extension for TLS v1.3+ otherwise it is not.
+ *
+ * ssl       The SSL/TLS object.
+ * input     The message buffer.
+ * i         The index into the message buffer of ClientHello.
+ * helloSz   The length of the current handshake message.
+ * returns 0 on success and otherwise failure.
+ */
+static int DoTls13SupportedVersions(WOLFSSL* ssl, const byte* input, word32 i,
+                                    word32 helloSz, int* wantDowngrade)
+{
+    int    ret;
+    byte   b;
+    word16 suiteSz;
+    word16 totalExtSz;
+    int    foundVersion = 0;
+
+    /* Client random */
+    i += RAN_LEN;
+    /* Session id - not used in TLS v1.3 */
+    b = input[i++];
+    if (i + b > helloSz) {
+        return BUFFER_ERROR;
+    }
+    i += b;
+    /* Cipher suites */
+    if (i + OPAQUE16_LEN > helloSz)
+        return BUFFER_ERROR;
+    ato16(input + i, &suiteSz);
+    i += OPAQUE16_LEN;
+    if (i + suiteSz + 1 > helloSz)
+        return BUFFER_ERROR;
+    i += suiteSz;
+    /* Compression */
+    b = input[i++];
+    if (i + b > helloSz)
+        return BUFFER_ERROR;
+    i += b;
+
+    /* TLS 1.3 must have extensions */
+    if (i < helloSz) {
+        if (i + OPAQUE16_LEN > helloSz)
+            return BUFFER_ERROR;
+        ato16(&input[i], &totalExtSz);
+        i += OPAQUE16_LEN;
+        if (totalExtSz != helloSz - i)
+            return BUFFER_ERROR;
+
+        /* Need to negotiate version first. */
+        if ((ret = TLSX_ParseVersion(ssl, (byte*)input + i, totalExtSz,
+                                                client_hello, &foundVersion))) {
+            return ret;
+        }
+    }
+    *wantDowngrade = !foundVersion || !IsAtLeastTLSv1_3(ssl->version);
+
+    return 0;
+}
+
+/* Handle a ClientHello handshake message.
+ * If the protocol version in the message is not TLS v1.3 or higher, use
+ * DoClientHello()
+ * Only a server will receive this message.
+ *
+ * ssl       The SSL/TLS object.
+ * input     The message buffer.
+ * inOutIdx  On entry, the index into the message buffer of ClientHello.
+ *           On exit, the index of byte after the ClientHello message and
+ *           padding.
+ * helloSz   The length of the current handshake message.
+ * returns 0 on success and otherwise failure.
+ */
+int DoTls13ClientHello(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
+                       word32 helloSz)
+{
+    int             ret = VERSION_ERROR;
+    byte            b = 0;
+    ProtocolVersion pv;
+    Suites          clSuites;
+    word32          i = *inOutIdx;
+    word32          begin = i;
+    word16          totalExtSz = 0;
+    int             usingPSK = 0;
+    byte            sessIdSz = 0;
+    int             wantDowngrade = 0;
+
+    WOLFSSL_START(WC_FUNC_CLIENT_HELLO_DO);
+    WOLFSSL_ENTER("DoTls13ClientHello");
+
+    XMEMSET(&pv, 0, sizeof(ProtocolVersion));
+    XMEMSET(&clSuites, 0, sizeof(Suites));
+
+#ifdef WOLFSSL_CALLBACKS
+    if (ssl->hsInfoOn) AddPacketName(ssl, "ClientHello");
+    if (ssl->toInfoOn) AddLateName("ClientHello", &ssl->timeoutInfo);
+#endif
+
+    /* protocol version, random and session id length check */
+    if ((i - begin) + OPAQUE16_LEN + RAN_LEN + OPAQUE8_LEN > helloSz)
+        return BUFFER_ERROR;
+
+    /* Protocol version */
+    XMEMCPY(&pv, input + i, OPAQUE16_LEN);
+    ssl->chVersion = pv;   /* store */
+    i += OPAQUE16_LEN;
+    if (pv.major < SSLv3_MAJOR) {
+        WOLFSSL_MSG("Legacy version field contains unsupported value");
+ #ifdef WOLFSSL_MYSQL_COMPATIBLE
+        SendAlert(ssl, alert_fatal, wc_protocol_version);
+ #else
+        SendAlert(ssl, alert_fatal, protocol_version);
+ #endif
+        return INVALID_PARAMETER;
+    }
+    /* Legacy protocol version cannot negotiate TLS 1.3 or higher. */
+    if (pv.major > SSLv3_MAJOR || (pv.major == SSLv3_MAJOR &&
+                                                   pv.minor >= TLSv1_3_MINOR)) {
+        pv.major = SSLv3_MAJOR;
+        pv.minor = TLSv1_2_MINOR;
+        wantDowngrade = 1;
+        ssl->version.minor = pv.minor;
+    }
+    /* Legacy version must be [ SSLv3_MAJOR, TLSv1_2_MINOR ] for TLS v1.3 */
+    else if (pv.major == SSLv3_MAJOR && pv.minor < TLSv1_2_MINOR) {
+        wantDowngrade = 1;
+        ssl->version.minor = pv.minor;
+    }
+    else {
+        ret = DoTls13SupportedVersions(ssl, input + begin, i - begin, helloSz,
+                                                                &wantDowngrade);
+        if (ret < 0)
+            return ret;
+    }
+    if (wantDowngrade) {
+#ifndef WOLFSSL_NO_TLS12
+        if (!ssl->options.downgrade) {
+            WOLFSSL_MSG("Client trying to connect with lesser version than "
+                        "TLS v1.3");
+            return VERSION_ERROR;
+        }
+
+        if (pv.minor < ssl->options.minDowngrade)
+            return VERSION_ERROR;
+
+        if ((ret = HashInput(ssl, input + begin, helloSz)) != 0)
+            return ret;
+        return DoClientHello(ssl, input, inOutIdx, helloSz);
+#else
+        WOLFSSL_MSG("Client trying to connect with lesser version than "
+                    "TLS v1.3");
+        return VERSION_ERROR;
+#endif
+    }
+
+    /* Client random */
+    XMEMCPY(ssl->arrays->clientRandom, input + i, RAN_LEN);
+    i += RAN_LEN;
+
+#ifdef WOLFSSL_DEBUG_TLS
+    WOLFSSL_MSG("client random");
+    WOLFSSL_BUFFER(ssl->arrays->clientRandom, RAN_LEN);
+#endif
+
+#ifdef WOLFSSL_TLS13_DRAFT_18
+    /* Session id - empty in TLS v1.3 */
+    sessIdSz = input[i++];
+    if (sessIdSz > 0 && !ssl->options.downgrade) {
+        WOLFSSL_MSG("Client sent session id - not supported");
+        return BUFFER_ERROR;
+    }
+#else
+    sessIdSz = input[i++];
+    if (sessIdSz != ID_LEN && sessIdSz != 0)
+        return INVALID_PARAMETER;
+#endif
+
+    if (sessIdSz + i > helloSz) {
+        return BUFFER_ERROR;
+    }
+
+    ssl->session.sessionIDSz = sessIdSz;
+    if (sessIdSz == ID_LEN) {
+        XMEMCPY(ssl->session.sessionID, input + i, sessIdSz);
+        i += ID_LEN;
+    }
+
+    /* Cipher suites */
+    if ((i - begin) + OPAQUE16_LEN > helloSz)
+        return BUFFER_ERROR;
+    ato16(&input[i], &clSuites.suiteSz);
+    i += OPAQUE16_LEN;
+    /* suites and compression length check */
+    if ((i - begin) + clSuites.suiteSz + OPAQUE8_LEN > helloSz)
+        return BUFFER_ERROR;
+    if (clSuites.suiteSz > WOLFSSL_MAX_SUITE_SZ)
+        return BUFFER_ERROR;
+    XMEMCPY(clSuites.suites, input + i, clSuites.suiteSz);
+    i += clSuites.suiteSz;
+    clSuites.hashSigAlgoSz = 0;
+
+#ifdef HAVE_SERVER_RENEGOTIATION_INFO
+    ret = FindSuite(&clSuites, 0, TLS_EMPTY_RENEGOTIATION_INFO_SCSV);
+    if (ret == SUITES_ERROR)
+        return BUFFER_ERROR;
+    if (ret >= 0) {
+        TLSX* extension;
+
+        /* check for TLS_EMPTY_RENEGOTIATION_INFO_SCSV suite */
+        ret = TLSX_AddEmptyRenegotiationInfo(&ssl->extensions, ssl->heap);
+        if (ret != WOLFSSL_SUCCESS)
+            return ret;
+
+        extension = TLSX_Find(ssl->extensions, TLSX_RENEGOTIATION_INFO);
+        if (extension) {
+            ssl->secure_renegotiation = (SecureRenegotiation*)extension->data;
+            ssl->secure_renegotiation->enabled = 1;
+        }
+    }
+#endif /* HAVE_SERVER_RENEGOTIATION_INFO */
+
+    /* Compression */
+    b = input[i++];
+    if ((i - begin) + b > helloSz)
+        return BUFFER_ERROR;
+    if (b != COMP_LEN) {
+        WOLFSSL_MSG("Must be one compression type in list");
+        return INVALID_PARAMETER;
+    }
+    b = input[i++];
+    if (b != NO_COMPRESSION) {
+        WOLFSSL_MSG("Must be no compression type in list");
+        return INVALID_PARAMETER;
+    }
+
+    /* Extensions */
+    if ((i - begin) == helloSz)
+        return BUFFER_ERROR;
+    if ((i - begin) + OPAQUE16_LEN > helloSz)
+        return BUFFER_ERROR;
+
+    ato16(&input[i], &totalExtSz);
+    i += OPAQUE16_LEN;
+    if ((i - begin) + totalExtSz > helloSz)
+        return BUFFER_ERROR;
+
+    /* Auto populate extensions supported unless user defined. */
+    if ((ret = TLSX_PopulateExtensions(ssl, 1)) != 0)
+        return ret;
+
+    /* Parse extensions */
+    if ((ret = TLSX_Parse(ssl, (byte*)input + i, totalExtSz, client_hello,
+                                                                  &clSuites))) {
+        return ret;
+    }
+
+#if defined(OPENSSL_ALL) || defined(HAVE_STUNNEL) || defined(WOLFSSL_NGINX) || \
+                                                        defined(WOLFSSL_HAPROXY)
+        if ((ret = SNI_Callback(ssl)) != 0)
+            return ret;
+        ssl->options.side = WOLFSSL_SERVER_END;
+#endif /* OPENSSL_ALL || HAVE_STUNNEL || WOLFSSL_NGINX || WOLFSSL_HAPROXY */
+
+    i += totalExtSz;
+    *inOutIdx = i;
+
+    ssl->options.sendVerify = SEND_CERT;
+
+    ssl->options.clientState = CLIENT_HELLO_COMPLETE;
+    ssl->options.haveSessionId = 1;
+
+#if !defined(WOLFSSL_TLS13_DRAFT_18) && defined(WOLFSSL_SEND_HRR_COOKIE)
+    if (ssl->options.sendCookie &&
+              ssl->options.serverState == SERVER_HELLO_RETRY_REQUEST_COMPLETE) {
+        TLSX* ext;
+
+        if ((ext = TLSX_Find(ssl->extensions, TLSX_COOKIE)) == NULL)
+            return HRR_COOKIE_ERROR;
+        /* Ensure the cookie came from client and isn't the one in the
+         * response - HelloRetryRequest.
+         */
+        if (ext->resp == 1)
+            return HRR_COOKIE_ERROR;
+        ret = RestartHandshakeHashWithCookie(ssl, (Cookie*)ext->data);
+        if (ret != 0)
+            return ret;
+    }
+#endif
+
+#if (defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)) && \
+     defined(HAVE_TLS_EXTENSIONS)
+    if (TLSX_Find(ssl->extensions, TLSX_PRE_SHARED_KEY) != NULL) {
+        /* Refine list for PSK processing. */
+        RefineSuites(ssl, &clSuites);
+
+        /* Process the Pre-Shared Key extension if present. */
+        ret = DoPreSharedKeys(ssl, input + begin, helloSz, &usingPSK);
+        if (ret != 0)
+            return ret;
+    }
+    else
+#endif
+    {
+#ifdef WOLFSSL_EARLY_DATA
+        ssl->earlyData = no_early_data;
+#endif
+        if ((ret = HashInput(ssl, input + begin, helloSz)) != 0)
+            return ret;
+
+    }
+
+    if (!usingPSK) {
+        if (TLSX_Find(ssl->extensions, TLSX_KEY_SHARE) == NULL) {
+            WOLFSSL_MSG("Client did not send a KeyShare extension");
+            SendAlert(ssl, alert_fatal, missing_extension);
+            return INCOMPLETE_DATA;
+        }
+        if (TLSX_Find(ssl->extensions, TLSX_SIGNATURE_ALGORITHMS) == NULL) {
+            WOLFSSL_MSG("Client did not send a SignatureAlgorithms extension");
+            SendAlert(ssl, alert_fatal, missing_extension);
+            return INCOMPLETE_DATA;
+        }
+
+        if ((ret = MatchSuite(ssl, &clSuites)) < 0) {
+            WOLFSSL_MSG("Unsupported cipher suite, ClientHello");
+            SendAlert(ssl, alert_fatal, handshake_failure);
+            return ret;
+        }
+
+#ifdef HAVE_NULL_CIPHER
+        if (ssl->options.cipherSuite0 == ECC_BYTE &&
+                              (ssl->options.cipherSuite == TLS_SHA256_SHA256 ||
+                               ssl->options.cipherSuite == TLS_SHA384_SHA384)) {
+            ;
+        }
+        else
+#endif
+        /* Check that the negotiated ciphersuite matches protocol version. */
+        if (ssl->options.cipherSuite0 != TLS13_BYTE) {
+            WOLFSSL_MSG("Negotiated ciphersuite from lesser version than "
+                        "TLS v1.3");
+            SendAlert(ssl, alert_fatal, handshake_failure);
+            return VERSION_ERROR;
+        }
+
+#ifdef HAVE_SESSION_TICKET
+        if (ssl->options.resuming) {
+            ssl->options.resuming = 0;
+            XMEMSET(ssl->arrays->psk_key, 0, ssl->specs.hash_size);
+        }
+#endif
+
+        /* Derive early secret for handshake secret. */
+        if ((ret = DeriveEarlySecret(ssl)) != 0)
+            return ret;
+    }
+
+    WOLFSSL_LEAVE("DoTls13ClientHello", ret);
+    WOLFSSL_END(WC_FUNC_CLIENT_HELLO_DO);
+
+    return ret;
+}
+
+#ifdef WOLFSSL_TLS13_DRAFT_18
+/* handle generation of TLS 1.3 hello_retry_request (6) */
+/* Send the HelloRetryRequest message to indicate the negotiated protocol
+ * version and security parameters the server is willing to use.
+ * Only a server will send this message.
+ *
+ * ssl  The SSL/TLS object.
+ * returns 0 on success, otherwise failure.
+ */
+int SendTls13HelloRetryRequest(WOLFSSL* ssl)
+{
+    int    ret;
+    byte*  output;
+    word32 length;
+    word16 len;
+    word32 idx = RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ;
+    int    sendSz;
+
+    WOLFSSL_ENTER("SendTls13HelloRetryRequest");
+
+    /* Get the length of the extensions that will be written. */
+    len = 0;
+    ret = TLSX_GetResponseSize(ssl, hello_retry_request, &len);
+    /* There must be extensions sent to indicate what client needs to do. */
+    if (ret != 0)
+        return MISSING_HANDSHAKE_DATA;
+
+    /* Protocol version + Extensions */
+    length = OPAQUE16_LEN + len;
+    sendSz = idx + length;
+
+    /* Check buffers are big enough and grow if needed. */
+    if ((ret = CheckAvailableSize(ssl, sendSz)) != 0)
+        return ret;
+
+    /* Get position in output buffer to write new message to. */
+    output = ssl->buffers.outputBuffer.buffer +
+             ssl->buffers.outputBuffer.length;
+    /* Add record and handshake headers. */
+    AddTls13Headers(output, length, hello_retry_request, ssl);
+
+    /* The negotiated protocol version. */
+    output[idx++] = TLS_DRAFT_MAJOR;
+    output[idx++] = TLS_DRAFT_MINOR;
+
+    /* Add TLS extensions. */
+    ret = TLSX_WriteResponse(ssl, output + idx, hello_retry_request, NULL);
+    if (ret != 0)
+        return ret;
+    idx += len;
+
+#ifdef WOLFSSL_CALLBACKS
+    if (ssl->hsInfoOn)
+        AddPacketName(ssl, "HelloRetryRequest");
+    if (ssl->toInfoOn) {
+        AddPacketInfo(ssl, "HelloRetryRequest", handshake, output, sendSz,
+                      WRITE_PROTO, ssl->heap);
+    }
+#endif
+    if ((ret = HashOutput(ssl, output, idx, 0)) != 0)
+        return ret;
+
+    ssl->buffers.outputBuffer.length += sendSz;
+
+    if (!ssl->options.groupMessages)
+        ret = SendBuffered(ssl);
+
+    WOLFSSL_LEAVE("SendTls13HelloRetryRequest", ret);
+
+    return ret;
+}
+#endif /* WOLFSSL_TLS13_DRAFT_18 */
+
+/* Send TLS v1.3 ServerHello message to client.
+ * Only a server will send this message.
+ *
+ * ssl  The SSL/TLS object.
+ * returns 0 on success, otherwise failure.
+ */
+#ifdef WOLFSSL_TLS13_DRAFT_18
+static
+#endif
+/* handle generation of TLS 1.3 server_hello (2) */
+int SendTls13ServerHello(WOLFSSL* ssl, byte extMsgType)
+{
+    int    ret;
+    byte*  output;
+    word16 length;
+    word32 idx = RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ;
+    int    sendSz;
+
+    WOLFSSL_START(WC_FUNC_SERVER_HELLO_SEND);
+    WOLFSSL_ENTER("SendTls13ServerHello");
+
+#ifndef WOLFSSL_TLS13_DRAFT_18
+    if (extMsgType == hello_retry_request) {
+        WOLFSSL_MSG("wolfSSL Doing HelloRetryRequest");
+        if ((ret = RestartHandshakeHash(ssl)) < 0)
+            return ret;
+    }
+#endif
+
+#ifdef WOLFSSL_TLS13_DRAFT_18
+    /* Protocol version, server random, cipher suite and extensions. */
+    length = VERSION_SZ + RAN_LEN + SUITE_LEN;
+    ret = TLSX_GetResponseSize(ssl, server_hello, &length);
+    if (ret != 0)
+        return ret;
+#else
+    /* Protocol version, server random, session id, cipher suite, compression
+     * and extensions.
+     */
+    length = VERSION_SZ + RAN_LEN + ENUM_LEN + ssl->session.sessionIDSz +
+             SUITE_LEN + COMP_LEN;
+    ret = TLSX_GetResponseSize(ssl, extMsgType, &length);
+    if (ret != 0)
+        return ret;
+#endif
+    sendSz = idx + length;
+
+    /* Check buffers are big enough and grow if needed. */
+    if ((ret = CheckAvailableSize(ssl, sendSz)) != 0)
+        return ret;
+
+    /* Get position in output buffer to write new message to. */
+    output = ssl->buffers.outputBuffer.buffer +
+             ssl->buffers.outputBuffer.length;
+
+    /* Put the record and handshake headers on. */
+    AddTls13Headers(output, length, server_hello, ssl);
+
+#ifdef WOLFSSL_TLS13_DRAFT_18
+    /* The negotiated protocol version. */
+    output[idx++] = TLS_DRAFT_MAJOR;
+    output[idx++] = TLS_DRAFT_MINOR;
+#else
+    /* The protocol version must be TLS v1.2 for middleboxes. */
+    output[idx++] = ssl->version.major;
+    output[idx++] = TLSv1_2_MINOR;
+#endif
+
+    if (extMsgType == server_hello) {
+        /* Generate server random. */
+        if ((ret = wc_RNG_GenerateBlock(ssl->rng, output + idx, RAN_LEN)) != 0)
+            return ret;
+    }
+#ifndef WOLFSSL_TLS13_DRAFT_18
+    else {
+        /* HelloRetryRequest message has fixed value for random. */
+        XMEMCPY(output + idx, helloRetryRequestRandom, RAN_LEN);
+    }
+#endif
+    /* Store in SSL for debugging. */
+    XMEMCPY(ssl->arrays->serverRandom, output + idx, RAN_LEN);
+    idx += RAN_LEN;
+
+#ifdef WOLFSSL_DEBUG_TLS
+    WOLFSSL_MSG("Server random");
+    WOLFSSL_BUFFER(ssl->arrays->serverRandom, RAN_LEN);
+#endif
+
+#ifndef WOLFSSL_TLS13_DRAFT_18
+    output[idx++] = ssl->session.sessionIDSz;
+    if (ssl->session.sessionIDSz > 0) {
+        XMEMCPY(output + idx, ssl->session.sessionID, ssl->session.sessionIDSz);
+        idx += ssl->session.sessionIDSz;
+    }
+#endif
+
+    /* Chosen cipher suite */
+    output[idx++] = ssl->options.cipherSuite0;
+    output[idx++] = ssl->options.cipherSuite;
+
+#ifndef WOLFSSL_TLS13_DRAFT_18
+    /* Compression not supported in TLS v1.3. */
+    output[idx++] = 0;
+#endif
+
+    /* Extensions */
+    ret = TLSX_WriteResponse(ssl, output + idx, extMsgType, NULL);
+    if (ret != 0)
+        return ret;
+
+    ssl->buffers.outputBuffer.length += sendSz;
+
+    if ((ret = HashOutput(ssl, output, sendSz, 0)) != 0)
+        return ret;
+
+    #ifdef WOLFSSL_CALLBACKS
+    if (ssl->hsInfoOn)
+        AddPacketName(ssl, "ServerHello");
+    if (ssl->toInfoOn) {
+        AddPacketInfo(ssl, "ServerHello", handshake, output, sendSz,
+                      WRITE_PROTO, ssl->heap);
+    }
+    #endif
+
+#ifdef WOLFSSL_TLS13_DRAFT_18
+    ssl->options.serverState = SERVER_HELLO_COMPLETE;
+#else
+    if (extMsgType == server_hello)
+        ssl->options.serverState = SERVER_HELLO_COMPLETE;
+#endif
+
+#ifdef WOLFSSL_TLS13_DRAFT_18
+    if (!ssl->options.groupMessages)
+#else
+    if (!ssl->options.groupMessages || extMsgType != server_hello)
+#endif
+        ret = SendBuffered(ssl);
+
+    WOLFSSL_LEAVE("SendTls13ServerHello", ret);
+    WOLFSSL_END(WC_FUNC_SERVER_HELLO_SEND);
+
+    return ret;
+}
+
+/* handle generation of TLS 1.3 encrypted_extensions (8) */
+/* Send the rest of the extensions encrypted under the handshake key.
+ * This message is always encrypted in TLS v1.3.
+ * Only a server will send this message.
+ *
+ * ssl  The SSL/TLS object.
+ * returns 0 on success, otherwise failure.
+ */
+static int SendTls13EncryptedExtensions(WOLFSSL* ssl)
+{
+    int    ret;
+    byte*  output;
+    word16 length = 0;
+    word32 idx = RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ;
+    int    sendSz;
+
+    WOLFSSL_START(WC_FUNC_ENCRYPTED_EXTENSIONS_SEND);
+    WOLFSSL_ENTER("SendTls13EncryptedExtensions");
+
+    ssl->keys.encryptionOn = 1;
+
+#ifndef WOLFSSL_NO_SERVER_GROUPS_EXT
+    if ((ret = TLSX_SupportedCurve_CheckPriority(ssl)) != 0)
+        return ret;
+#endif
+
+    /* Derive the handshake secret now that we are at first message to be
+     * encrypted under the keys.
+     */
+    if ((ret = DeriveHandshakeSecret(ssl)) != 0)
+        return ret;
+    if ((ret = DeriveTls13Keys(ssl, handshake_key,
+                               ENCRYPT_AND_DECRYPT_SIDE, 1)) != 0)
+        return ret;
+
+    /* Setup encrypt/decrypt keys for following messages. */
+#ifdef WOLFSSL_EARLY_DATA
+    if ((ret = SetKeysSide(ssl, ENCRYPT_SIDE_ONLY)) != 0)
+        return ret;
+    if (ssl->earlyData != process_early_data) {
+        if ((ret = SetKeysSide(ssl, DECRYPT_SIDE_ONLY)) != 0)
+            return ret;
+    }
+#else
+    if ((ret = SetKeysSide(ssl, ENCRYPT_AND_DECRYPT_SIDE)) != 0)
+        return ret;
+#endif
+
+    ret = TLSX_GetResponseSize(ssl, encrypted_extensions, &length);
+    if (ret != 0)
+        return ret;
+
+    sendSz = idx + length;
+    /* Encryption always on. */
+    sendSz += MAX_MSG_EXTRA;
+
+    /* Check buffers are big enough and grow if needed. */
+    ret = CheckAvailableSize(ssl, sendSz);
+    if (ret != 0)
+        return ret;
+
+    /* Get position in output buffer to write new message to. */
+    output = ssl->buffers.outputBuffer.buffer +
+             ssl->buffers.outputBuffer.length;
+
+    /* Put the record and handshake headers on. */
+    AddTls13Headers(output, length, encrypted_extensions, ssl);
+
+    ret = TLSX_WriteResponse(ssl, output + idx, encrypted_extensions, NULL);
+    if (ret != 0)
+        return ret;
+    idx += length;
+
+#ifdef WOLFSSL_CALLBACKS
+    if (ssl->hsInfoOn)
+        AddPacketName(ssl, "EncryptedExtensions");
+    if (ssl->toInfoOn) {
+        AddPacketInfo(ssl, "EncryptedExtensions", handshake, output,
+                      sendSz, WRITE_PROTO, ssl->heap);
+    }
+#endif
+
+    /* This handshake message is always encrypted. */
+    sendSz = BuildTls13Message(ssl, output, sendSz, output + RECORD_HEADER_SZ,
+                               idx - RECORD_HEADER_SZ, handshake, 1, 0, 0);
+    if (sendSz < 0)
+        return sendSz;
+
+    ssl->buffers.outputBuffer.length += sendSz;
+
+    ssl->options.serverState = SERVER_ENCRYPTED_EXTENSIONS_COMPLETE;
+
+    if (!ssl->options.groupMessages)
+        ret = SendBuffered(ssl);
+
+    WOLFSSL_LEAVE("SendTls13EncryptedExtensions", ret);
+    WOLFSSL_END(WC_FUNC_ENCRYPTED_EXTENSIONS_SEND);
+
+    return ret;
+}
+
+#ifndef NO_CERTS
+/* handle generation TLS v1.3 certificate_request (13) */
+/* Send the TLS v1.3 CertificateRequest message.
+ * This message is always encrypted in TLS v1.3.
+ * Only a server will send this message.
+ *
+ * ssl        SSL/TLS object.
+ * reqCtx     Request context.
+ * reqCtxLen  Length of context. 0 when sending as part of handshake.
+ * returns 0 on success, otherwise failure.
+ */
+static int SendTls13CertificateRequest(WOLFSSL* ssl, byte* reqCtx,
+                                       int reqCtxLen)
+{
+    byte*   output;
+    int    ret;
+    int    sendSz;
+    word32 i;
+    word16 reqSz;
+#ifndef WOLFSSL_TLS13_DRAFT_18
+    TLSX*  ext;
+#endif
+
+    WOLFSSL_START(WC_FUNC_CERTIFICATE_REQUEST_SEND);
+    WOLFSSL_ENTER("SendTls13CertificateRequest");
+
+    if (ssl->options.side == WOLFSSL_SERVER_END)
+        InitSuitesHashSigAlgo(ssl->suites, 1, 1, 0, 1, ssl->buffers.keySz);
+
+#ifdef WOLFSSL_TLS13_DRAFT_18
+    i = RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ;
+    reqSz = OPAQUE8_LEN + reqCtxLen + REQ_HEADER_SZ + REQ_HEADER_SZ;
+    reqSz += LENGTH_SZ + ssl->suites->hashSigAlgoSz;
+
+    sendSz = RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ + reqSz;
+    /* Always encrypted and make room for padding. */
+    sendSz += MAX_MSG_EXTRA;
+
+    /* Check buffers are big enough and grow if needed. */
+    if ((ret = CheckAvailableSize(ssl, sendSz)) != 0)
+        return ret;
+
+    /* Get position in output buffer to write new message to. */
+    output = ssl->buffers.outputBuffer.buffer +
+             ssl->buffers.outputBuffer.length;
+
+    /* Put the record and handshake headers on. */
+    AddTls13Headers(output, reqSz, certificate_request, ssl);
+
+    /* Certificate request context. */
+    output[i++] = reqCtxLen;
+    if (reqCtxLen != 0) {
+        XMEMCPY(output + i, reqCtx, reqCtxLen);
+        i += reqCtxLen;
+    }
+
+    /* supported hash/sig */
+    c16toa(ssl->suites->hashSigAlgoSz, &output[i]);
+    i += LENGTH_SZ;
+
+    XMEMCPY(&output[i], ssl->suites->hashSigAlgo, ssl->suites->hashSigAlgoSz);
+    i += ssl->suites->hashSigAlgoSz;
+
+    /* Certificate authorities not supported yet - empty buffer. */
+    c16toa(0, &output[i]);
+    i += REQ_HEADER_SZ;
+
+    /* Certificate extensions. */
+    c16toa(0, &output[i]);  /* auth's */
+    i += REQ_HEADER_SZ;
+#else
+    ext = TLSX_Find(ssl->extensions, TLSX_SIGNATURE_ALGORITHMS);
+    if (ext == NULL)
+        return EXT_MISSING;
+    ext->resp = 0;
+
+    i = RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ;
+    reqSz = (word16)(OPAQUE8_LEN + reqCtxLen);
+    ret = TLSX_GetRequestSize(ssl, certificate_request, &reqSz);
+    if (ret != 0)
+        return ret;
+
+    sendSz = i + reqSz;
+    /* Always encrypted and make room for padding. */
+    sendSz += MAX_MSG_EXTRA;
+
+    /* Check buffers are big enough and grow if needed. */
+    if ((ret = CheckAvailableSize(ssl, sendSz)) != 0)
+        return ret;
+
+    /* Get position in output buffer to write new message to. */
+    output = ssl->buffers.outputBuffer.buffer +
+             ssl->buffers.outputBuffer.length;
+
+    /* Put the record and handshake headers on. */
+    AddTls13Headers(output, reqSz, certificate_request, ssl);
+
+    /* Certificate request context. */
+    output[i++] = (byte)reqCtxLen;
+    if (reqCtxLen != 0) {
+        XMEMCPY(output + i, reqCtx, reqCtxLen);
+        i += reqCtxLen;
+    }
+
+    /* Certificate extensions. */
+    reqSz = 0;
+    ret = TLSX_WriteRequest(ssl, output + i, certificate_request, &reqSz);
+    if (ret != 0)
+        return ret;
+    i += reqSz;
+#endif
+
+    /* Always encrypted. */
+    sendSz = BuildTls13Message(ssl, output, sendSz, output + RECORD_HEADER_SZ,
+                               i - RECORD_HEADER_SZ, handshake, 1, 0, 0);
+    if (sendSz < 0)
+        return sendSz;
+
+    #ifdef WOLFSSL_CALLBACKS
+        if (ssl->hsInfoOn)
+            AddPacketName(ssl, "CertificateRequest");
+        if (ssl->toInfoOn) {
+            AddPacketInfo(ssl, "CertificateRequest", handshake, output,
+                          sendSz, WRITE_PROTO, ssl->heap);
+        }
+    #endif
+
+    ssl->buffers.outputBuffer.length += sendSz;
+    if (!ssl->options.groupMessages)
+        ret = SendBuffered(ssl);
+
+    WOLFSSL_LEAVE("SendTls13CertificateRequest", ret);
+    WOLFSSL_END(WC_FUNC_CERTIFICATE_REQUEST_SEND);
+
+    return ret;
+}
+#endif /* NO_CERTS */
+#endif /* NO_WOLFSSL_SERVER */
+
+#ifndef NO_CERTS
+#if !defined(NO_RSA) || defined(HAVE_ECC) || defined(HAVE_ED25519) || \
+                                                             defined(HAVE_ED448)
+/* Encode the signature algorithm into buffer.
+ *
+ * hashalgo  The hash algorithm.
+ * hsType   The signature type.
+ * output    The buffer to encode into.
+ */
+static WC_INLINE void EncodeSigAlg(byte hashAlgo, byte hsType, byte* output)
+{
+    switch (hsType) {
+#ifdef HAVE_ECC
+        case ecc_dsa_sa_algo:
+            output[0] = hashAlgo;
+            output[1] = ecc_dsa_sa_algo;
+            break;
+#endif
+#ifdef HAVE_ED25519
+        /* ED25519: 0x0807 */
+        case ed25519_sa_algo:
+            output[0] = ED25519_SA_MAJOR;
+            output[1] = ED25519_SA_MINOR;
+            (void)hashAlgo;
+            break;
+#endif
+#ifdef HAVE_ED448
+        /* ED448: 0x0808 */
+        case ed448_sa_algo:
+            output[0] = ED448_SA_MAJOR;
+            output[1] = ED448_SA_MINOR;
+            (void)hashAlgo;
+            break;
+#endif
+#ifndef NO_RSA
+        /* PSS signatures: 0x080[4-6] */
+        case rsa_pss_sa_algo:
+            output[0] = rsa_pss_sa_algo;
+            output[1] = hashAlgo;
+            break;
+#endif
+    }
+}
+
+/* Decode the signature algorithm.
+ *
+ * input     The encoded signature algorithm.
+ * hashalgo  The hash algorithm.
+ * hsType    The signature type.
+ * returns INVALID_PARAMETER if not recognized and 0 otherwise.
+ */
+static WC_INLINE int DecodeTls13SigAlg(byte* input, byte* hashAlgo,
+                                       byte* hsType)
+{
+    int ret = 0;
+
+    switch (input[0]) {
+        case NEW_SA_MAJOR:
+            /* PSS signatures: 0x080[4-6] */
+            if (input[1] >= sha256_mac && input[1] <= sha512_mac) {
+                *hsType   = input[0];
+                *hashAlgo = input[1];
+            }
+    #ifdef HAVE_ED25519
+            /* ED25519: 0x0807 */
+            else if (input[1] == ED25519_SA_MINOR) {
+                *hsType = ed25519_sa_algo;
+                /* Hash performed as part of sign/verify operation. */
+                *hashAlgo = sha512_mac;
+            }
+    #endif
+    #ifdef HAVE_ED448
+            /* ED448: 0x0808 */
+            else if (input[1] == ED448_SA_MINOR) {
+                *hsType = ed448_sa_algo;
+                /* Hash performed as part of sign/verify operation. */
+                *hashAlgo = sha512_mac;
+            }
+    #endif
+            else
+                ret = INVALID_PARAMETER;
+            break;
+        default:
+            *hashAlgo = input[0];
+            *hsType   = input[1];
+            break;
+    }
+
+    return ret;
+}
+
+/* Get the hash of the messages so far.
+ *
+ * ssl   The SSL/TLS object.
+ * hash  The buffer to write the hash to.
+ * returns the length of the hash.
+ */
+static WC_INLINE int GetMsgHash(WOLFSSL* ssl, byte* hash)
+{
+    int ret = 0;
+    switch (ssl->specs.mac_algorithm) {
+    #ifndef NO_SHA256
+        case sha256_mac:
+            ret = wc_Sha256GetHash(&ssl->hsHashes->hashSha256, hash);
+            if (ret == 0)
+                ret = WC_SHA256_DIGEST_SIZE;
+            break;
+    #endif /* !NO_SHA256 */
+    #ifdef WOLFSSL_SHA384
+        case sha384_mac:
+            ret = wc_Sha384GetHash(&ssl->hsHashes->hashSha384, hash);
+            if (ret == 0)
+                ret = WC_SHA384_DIGEST_SIZE;
+            break;
+    #endif /* WOLFSSL_SHA384 */
+    #ifdef WOLFSSL_TLS13_SHA512
+        case sha512_mac:
+            ret = wc_Sha512GetHash(&ssl->hsHashes->hashSha512, hash);
+            if (ret == 0)
+                ret = WC_SHA512_DIGEST_SIZE;
+            break;
+    #endif /* WOLFSSL_TLS13_SHA512 */
+    }
+    return ret;
+}
+
+/* The length of the certificate verification label - client and server. */
+#define CERT_VFY_LABEL_SZ    34
+/* The server certificate verification label. */
+static const byte serverCertVfyLabel[CERT_VFY_LABEL_SZ] =
+    "TLS 1.3, server CertificateVerify";
+/* The client certificate verification label. */
+static const byte clientCertVfyLabel[CERT_VFY_LABEL_SZ] =
+    "TLS 1.3, client CertificateVerify";
+
+/* The number of prefix bytes for signature data. */
+#define SIGNING_DATA_PREFIX_SZ     64
+/* The prefix byte in the signature data. */
+#define SIGNING_DATA_PREFIX_BYTE   0x20
+/* Maximum length of the signature data. */
+#define MAX_SIG_DATA_SZ            (SIGNING_DATA_PREFIX_SZ + \
+                                    CERT_VFY_LABEL_SZ      + \
+                                    WC_MAX_DIGEST_SIZE)
+
+/* Create the signature data for TLS v1.3 certificate verification.
+ *
+ * ssl        The SSL/TLS object.
+ * sigData    The signature data.
+ * sigDataSz  The length of the signature data.
+ * check      Indicates this is a check not create.
+ */
+static int CreateSigData(WOLFSSL* ssl, byte* sigData, word16* sigDataSz,
+                          int check)
+{
+    word16 idx;
+    int side = ssl->options.side;
+    int ret;
+
+    /* Signature Data = Prefix | Label | Handshake Hash */
+    XMEMSET(sigData, SIGNING_DATA_PREFIX_BYTE, SIGNING_DATA_PREFIX_SZ);
+    idx = SIGNING_DATA_PREFIX_SZ;
+
+    if ((side == WOLFSSL_SERVER_END && check) ||
+        (side == WOLFSSL_CLIENT_END && !check)) {
+        XMEMCPY(&sigData[idx], clientCertVfyLabel, CERT_VFY_LABEL_SZ);
+    }
+    if ((side == WOLFSSL_CLIENT_END && check) ||
+        (side == WOLFSSL_SERVER_END && !check)) {
+        XMEMCPY(&sigData[idx], serverCertVfyLabel, CERT_VFY_LABEL_SZ);
+    }
+    idx += CERT_VFY_LABEL_SZ;
+
+    ret = GetMsgHash(ssl, &sigData[idx]);
+    if (ret < 0)
+        return ret;
+
+    *sigDataSz = (word16)(idx + ret);
+    ret = 0;
+
+    return ret;
+}
+
+#ifndef NO_RSA
+/* Encode the PKCS #1.5 RSA signature.
+ *
+ * sig        The buffer to place the encoded signature into.
+ * sigData    The data to be signed.
+ * sigDataSz  The size of the data to be signed.
+ * hashAlgo   The hash algorithm to use when signing.
+ * returns the length of the encoded signature or negative on error.
+ */
+static int CreateRSAEncodedSig(byte* sig, byte* sigData, int sigDataSz,
+                               int sigAlgo, int hashAlgo)
+{
+    Digest digest;
+    int    hashSz = 0;
+    int    ret = BAD_FUNC_ARG;
+    byte*  hash;
+
+    (void)sigAlgo;
+
+    hash = sig;
+
+    /* Digest the signature data. */
+    switch (hashAlgo) {
+#ifndef NO_WOLFSSL_SHA256
+        case sha256_mac:
+            ret = wc_InitSha256(&digest.sha256);
+            if (ret == 0) {
+                ret = wc_Sha256Update(&digest.sha256, sigData, sigDataSz);
+                if (ret == 0)
+                    ret = wc_Sha256Final(&digest.sha256, hash);
+                wc_Sha256Free(&digest.sha256);
+            }
+            hashSz = WC_SHA256_DIGEST_SIZE;
+            break;
+#endif
+#ifdef WOLFSSL_SHA384
+        case sha384_mac:
+            ret = wc_InitSha384(&digest.sha384);
+            if (ret == 0) {
+                ret = wc_Sha384Update(&digest.sha384, sigData, sigDataSz);
+                if (ret == 0)
+                    ret = wc_Sha384Final(&digest.sha384, hash);
+                wc_Sha384Free(&digest.sha384);
+            }
+            hashSz = WC_SHA384_DIGEST_SIZE;
+            break;
+#endif
+#ifdef WOLFSSL_SHA512
+        case sha512_mac:
+            ret = wc_InitSha512(&digest.sha512);
+            if (ret == 0) {
+                ret = wc_Sha512Update(&digest.sha512, sigData, sigDataSz);
+                if (ret == 0)
+                    ret = wc_Sha512Final(&digest.sha512, hash);
+                wc_Sha512Free(&digest.sha512);
+            }
+            hashSz = WC_SHA512_DIGEST_SIZE;
+            break;
+#endif
+    }
+
+    if (ret != 0)
+        return ret;
+
+    return hashSz;
+}
+#endif /* !NO_RSA */
+
+#ifdef HAVE_ECC
+/* Encode the ECC signature.
+ *
+ * sigData    The data to be signed.
+ * sigDataSz  The size of the data to be signed.
+ * hashAlgo   The hash algorithm to use when signing.
+ * returns the length of the encoded signature or negative on error.
+ */
+static int CreateECCEncodedSig(byte* sigData, int sigDataSz, int hashAlgo)
+{
+    Digest digest;
+    int    hashSz = 0;
+    int    ret = BAD_FUNC_ARG;
+
+    /* Digest the signature data. */
+    switch (hashAlgo) {
+#ifndef NO_WOLFSSL_SHA256
+        case sha256_mac:
+            ret = wc_InitSha256(&digest.sha256);
+            if (ret == 0) {
+                ret = wc_Sha256Update(&digest.sha256, sigData, sigDataSz);
+                if (ret == 0)
+                    ret = wc_Sha256Final(&digest.sha256, sigData);
+                wc_Sha256Free(&digest.sha256);
+            }
+            hashSz = WC_SHA256_DIGEST_SIZE;
+            break;
+#endif
+#ifdef WOLFSSL_SHA384
+        case sha384_mac:
+            ret = wc_InitSha384(&digest.sha384);
+            if (ret == 0) {
+                ret = wc_Sha384Update(&digest.sha384, sigData, sigDataSz);
+                if (ret == 0)
+                    ret = wc_Sha384Final(&digest.sha384, sigData);
+                wc_Sha384Free(&digest.sha384);
+            }
+            hashSz = WC_SHA384_DIGEST_SIZE;
+            break;
+#endif
+#ifdef WOLFSSL_SHA512
+        case sha512_mac:
+            ret = wc_InitSha512(&digest.sha512);
+            if (ret == 0) {
+                ret = wc_Sha512Update(&digest.sha512, sigData, sigDataSz);
+                if (ret == 0)
+                    ret = wc_Sha512Final(&digest.sha512, sigData);
+                wc_Sha512Free(&digest.sha512);
+            }
+            hashSz = WC_SHA512_DIGEST_SIZE;
+            break;
+#endif
+    }
+
+    if (ret != 0)
+        return ret;
+
+    return hashSz;
+}
+#endif /* HAVE_ECC */
+
+#ifndef NO_RSA
+/* Check that the decrypted signature matches the encoded signature
+ * based on the digest of the signature data.
+ *
+ * ssl       The SSL/TLS object.
+ * sigAlgo   The signature algorithm used to generate signature.
+ * hashAlgo  The hash algorithm used to generate signature.
+ * decSig    The decrypted signature.
+ * decSigSz  The size of the decrypted signature.
+ * returns 0 on success, otherwise failure.
+ */
+static int CheckRSASignature(WOLFSSL* ssl, int sigAlgo, int hashAlgo,
+                             byte* decSig, word32 decSigSz)
+{
+    int    ret = 0;
+    byte   sigData[MAX_SIG_DATA_SZ];
+    word16 sigDataSz;
+    word32 sigSz;
+
+    ret = CreateSigData(ssl, sigData, &sigDataSz, 1);
+    if (ret != 0)
+        return ret;
+
+    if (sigAlgo == rsa_pss_sa_algo) {
+        enum wc_HashType hashType = WC_HASH_TYPE_NONE;
+
+        ret = ConvertHashPss(hashAlgo, &hashType, NULL);
+        if (ret < 0)
+            return ret;
+
+        /* PSS signature can be done in-place */
+        ret = CreateRSAEncodedSig(sigData, sigData, sigDataSz,
+                                  sigAlgo, hashAlgo);
+        if (ret < 0)
+            return ret;
+        sigSz = ret;
+
+        ret = wc_RsaPSS_CheckPadding(sigData, sigSz, decSig, decSigSz,
+                                     hashType);
+    }
+
+    return ret;
+}
+#endif /* !NO_RSA */
+#endif /* !NO_RSA || HAVE_ECC */
+
+/* Get the next certificate from the list for writing into the TLS v1.3
+ * Certificate message.
+ *
+ * data    The certificate list.
+ * length  The length of the certificate data in the list.
+ * idx     The index of the next certificate.
+ * returns the length of the certificate data. 0 indicates no more certificates
+ * in the list.
+ */
+static word32 NextCert(byte* data, word32 length, word32* idx)
+{
+    word32 len;
+
+    /* Is index at end of list. */
+    if (*idx == length)
+        return 0;
+
+    /* Length of the current ASN.1 encoded certificate. */
+    c24to32(data + *idx, &len);
+    /* Include the length field. */
+    len += 3;
+
+    /* Move index to next certificate and return the current certificate's
+     * length.
+     */
+    *idx += len;
+    return len;
+}
+
+/* Add certificate data and empty extension to output up to the fragment size.
+ *
+ * ssl     SSL/TLS object.
+ * cert    The certificate data to write out.
+ * len     The length of the certificate data.
+ * extSz   Length of the extension data with the certificate.
+ * idx     The start of the certificate data to write out.
+ * fragSz  The maximum size of this fragment.
+ * output  The buffer to write to.
+ * returns the number of bytes written.
+ */
+static word32 AddCertExt(WOLFSSL* ssl, byte* cert, word32 len, word16 extSz,
+                         word32 idx, word32 fragSz, byte* output)
+{
+    word32 i = 0;
+    word32 copySz = min(len - idx, fragSz);
+
+    if (idx < len) {
+        XMEMCPY(output, cert + idx, copySz);
+        i = copySz;
+        if (copySz == fragSz)
+            return i;
+    }
+    copySz = len + extSz - idx - i;
+
+    if (extSz == OPAQUE16_LEN) {
+        if (copySz <= fragSz) {
+            /* Empty extension */
+            output[i++] = 0;
+            output[i++] = 0;
+        }
+    }
+    else {
+        byte* certExts = ssl->buffers.certExts->buffer + idx + i - len;
+        /* Put out as much of the extensions' data as will fit in fragment. */
+        if (copySz > fragSz - i)
+            copySz = fragSz - i;
+        XMEMCPY(output + i, certExts, copySz);
+        i += copySz;
+    }
+
+    return i;
+}
+
+/* handle generation TLS v1.3 certificate (11) */
+/* Send the certificate for this end and any CAs that help with validation.
+ * This message is always encrypted in TLS v1.3.
+ *
+ * ssl  The SSL/TLS object.
+ * returns 0 on success, otherwise failure.
+ */
+static int SendTls13Certificate(WOLFSSL* ssl)
+{
+    int    ret = 0;
+    word32 certSz, certChainSz, headerSz, listSz, payloadSz;
+    word16 extSz = 0;
+    word32 length, maxFragment;
+    word32 len = 0;
+    word32 idx = 0;
+    word32 offset = OPAQUE16_LEN;
+    byte*  p = NULL;
+    byte   certReqCtxLen = 0;
+    byte*  certReqCtx = NULL;
+
+    WOLFSSL_START(WC_FUNC_CERTIFICATE_SEND);
+    WOLFSSL_ENTER("SendTls13Certificate");
+
+#ifdef WOLFSSL_POST_HANDSHAKE_AUTH
+    if (ssl->options.side == WOLFSSL_CLIENT_END && ssl->certReqCtx != NULL) {
+        certReqCtxLen = ssl->certReqCtx->len;
+        certReqCtx = &ssl->certReqCtx->ctx;
+    }
+#endif
+
+    if (ssl->options.sendVerify == SEND_BLANK_CERT) {
+        certSz = 0;
+        certChainSz = 0;
+        headerSz = OPAQUE8_LEN + certReqCtxLen + CERT_HEADER_SZ;
+        length = headerSz;
+        listSz = 0;
+    }
+    else {
+        if (!ssl->buffers.certificate) {
+            WOLFSSL_MSG("Send Cert missing certificate buffer");
+            return BUFFER_ERROR;
+        }
+        /* Certificate Data */
+        certSz = ssl->buffers.certificate->length;
+        /* Cert Req Ctx Len | Cert Req Ctx | Cert List Len | Cert Data Len */
+        headerSz = OPAQUE8_LEN + certReqCtxLen + CERT_HEADER_SZ +
+                   CERT_HEADER_SZ;
+
+        ret = TLSX_GetResponseSize(ssl, certificate, &extSz);
+        if (ret < 0)
+            return ret;
+
+        /* Create extensions' data if none already present. */
+        if (extSz > OPAQUE16_LEN && ssl->buffers.certExts == NULL) {
+            ret = AllocDer(&ssl->buffers.certExts, extSz, CERT_TYPE, ssl->heap);
+            if (ret < 0)
+                return ret;
+
+            extSz = 0;
+            ret = TLSX_WriteResponse(ssl, ssl->buffers.certExts->buffer,
+                                                           certificate, &extSz);
+            if (ret < 0)
+                return ret;
+        }
+
+        /* Length of message data with one certificate and extensions. */
+        length = headerSz + certSz + extSz;
+        /* Length of list data with one certificate and extensions. */
+        listSz = CERT_HEADER_SZ + certSz + extSz;
+
+        /* Send rest of chain if sending cert (chain has leading size/s). */
+        if (certSz > 0 && ssl->buffers.certChainCnt > 0) {
+            p = ssl->buffers.certChain->buffer;
+            /* Chain length including extensions. */
+            certChainSz = ssl->buffers.certChain->length +
+                          OPAQUE16_LEN * ssl->buffers.certChainCnt;
+            length += certChainSz;
+            listSz += certChainSz;
+        }
+        else
+            certChainSz = 0;
+    }
+
+    payloadSz = length;
+
+    if (ssl->fragOffset != 0)
+        length -= (ssl->fragOffset + headerSz);
+
+    maxFragment = wolfSSL_GetMaxRecordSize(ssl, MAX_RECORD_SIZE);
+
+    while (length > 0 && ret == 0) {
+        byte*  output = NULL;
+        word32 fragSz = 0;
+        word32 i = RECORD_HEADER_SZ;
+        int    sendSz = RECORD_HEADER_SZ;
+
+        if (ssl->fragOffset == 0)  {
+            if (headerSz + certSz + extSz + certChainSz <=
+                                            maxFragment - HANDSHAKE_HEADER_SZ) {
+                fragSz = headerSz + certSz + extSz + certChainSz;
+            }
+            else
+                fragSz = maxFragment - HANDSHAKE_HEADER_SZ;
+
+            sendSz += fragSz + HANDSHAKE_HEADER_SZ;
+            i += HANDSHAKE_HEADER_SZ;
+        }
+        else {
+            fragSz = min(length, maxFragment);
+            sendSz += fragSz;
+        }
+
+        sendSz += MAX_MSG_EXTRA;
+
+        /* Check buffers are big enough and grow if needed. */
+        if ((ret = CheckAvailableSize(ssl, sendSz)) != 0)
+            return ret;
+
+        /* Get position in output buffer to write new message to. */
+        output = ssl->buffers.outputBuffer.buffer +
+                 ssl->buffers.outputBuffer.length;
+
+        if (ssl->fragOffset == 0) {
+            AddTls13FragHeaders(output, fragSz, 0, payloadSz, certificate, ssl);
+
+            /* Request context. */
+            output[i++] = certReqCtxLen;
+            if (certReqCtxLen > 0) {
+                XMEMCPY(output + i, certReqCtx, certReqCtxLen);
+                i += certReqCtxLen;
+            }
+            length -= OPAQUE8_LEN + certReqCtxLen;
+            fragSz -= OPAQUE8_LEN + certReqCtxLen;
+            /* Certificate list length. */
+            c32to24(listSz, output + i);
+            i += CERT_HEADER_SZ;
+            length -= CERT_HEADER_SZ;
+            fragSz -= CERT_HEADER_SZ;
+            /* Leaf certificate data length. */
+            if (certSz > 0) {
+                c32to24(certSz, output + i);
+                i += CERT_HEADER_SZ;
+                length -= CERT_HEADER_SZ;
+                fragSz -= CERT_HEADER_SZ;
+            }
+        }
+        else
+            AddTls13RecordHeader(output, fragSz, handshake, ssl);
+
+        if (certSz > 0 && ssl->fragOffset < certSz + extSz) {
+            /* Put in the leaf certificate with extensions. */
+            word32 copySz = AddCertExt(ssl, ssl->buffers.certificate->buffer,
+                            certSz, extSz, ssl->fragOffset, fragSz, output + i);
+            i += copySz;
+            ssl->fragOffset += copySz;
+            length -= copySz;
+            fragSz -= copySz;
+            if (ssl->fragOffset == certSz + extSz)
+                FreeDer(&ssl->buffers.certExts);
+        }
+        if (certChainSz > 0 && fragSz > 0) {
+            /* Put in the CA certificates with empty extensions. */
+            while (fragSz > 0) {
+                word32 l;
+
+                if (offset == len + OPAQUE16_LEN) {
+                    /* Find next CA certificate to write out. */
+                    offset = 0;
+                    /* Point to the start of current cert in chain buffer. */
+                    p = ssl->buffers.certChain->buffer + idx;
+                    len = NextCert(ssl->buffers.certChain->buffer,
+                                   ssl->buffers.certChain->length, &idx);
+                    if (len == 0)
+                        break;
+                }
+
+                /* Write out certificate and empty extension. */
+                l = AddCertExt(ssl, p, len, OPAQUE16_LEN, offset, fragSz,
+                                                                    output + i);
+                i += l;
+                ssl->fragOffset += l;
+                length -= l;
+                fragSz -= l;
+                offset += l;
+            }
+        }
+
+        if ((int)i - RECORD_HEADER_SZ < 0) {
+            WOLFSSL_MSG("Send Cert bad inputSz");
+            return BUFFER_E;
+        }
+
+        /* This message is always encrypted. */
+        sendSz = BuildTls13Message(ssl, output, sendSz,
+                                   output + RECORD_HEADER_SZ,
+                                   i - RECORD_HEADER_SZ, handshake, 1, 0, 0);
+        if (sendSz < 0)
+            return sendSz;
+
+        #ifdef WOLFSSL_CALLBACKS
+            if (ssl->hsInfoOn)
+                AddPacketName(ssl, "Certificate");
+            if (ssl->toInfoOn) {
+                AddPacketInfo(ssl, "Certificate", handshake, output,
+                        sendSz, WRITE_PROTO, ssl->heap);
+            }
+        #endif
+
+        ssl->buffers.outputBuffer.length += sendSz;
+        if (!ssl->options.groupMessages)
+            ret = SendBuffered(ssl);
+    }
+
+    if (ret != WANT_WRITE) {
+        /* Clean up the fragment offset. */
+        ssl->fragOffset = 0;
+        if (ssl->options.side == WOLFSSL_SERVER_END)
+            ssl->options.serverState = SERVER_CERT_COMPLETE;
+    }
+
+#ifdef WOLFSSL_POST_HANDSHAKE_AUTH
+    if (ssl->options.side == WOLFSSL_CLIENT_END && ssl->certReqCtx != NULL) {
+        CertReqCtx* ctx = ssl->certReqCtx;
+        ssl->certReqCtx = ssl->certReqCtx->next;
+        XFREE(ctx, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER);
+    }
+#endif
+
+    WOLFSSL_LEAVE("SendTls13Certificate", ret);
+    WOLFSSL_END(WC_FUNC_CERTIFICATE_SEND);
+
+    return ret;
+}
+
+typedef struct Scv13Args {
+    byte*  output; /* not allocated */
+    byte*  verify; /* not allocated */
+    word32 idx;
+    word32 sigLen;
+    int    sendSz;
+    word16 length;
+
+    byte   sigAlgo;
+    byte*  sigData;
+    word16 sigDataSz;
+} Scv13Args;
+
+static void FreeScv13Args(WOLFSSL* ssl, void* pArgs)
+{
+    Scv13Args* args = (Scv13Args*)pArgs;
+
+    (void)ssl;
+
+    if (args->sigData) {
+        XFREE(args->sigData, ssl->heap, DYNAMIC_TYPE_SIGNATURE);
+        args->sigData = NULL;
+    }
+}
+
+/* handle generation TLS v1.3 certificate_verify (15) */
+/* Send the TLS v1.3 CertificateVerify message.
+ * A hash of all the message so far is used.
+ * The signed data is:
+ *     0x20 * 64 | context string | 0x00 | hash of messages
+ * This message is always encrypted in TLS v1.3.
+ *
+ * ssl  The SSL/TLS object.
+ * returns 0 on success, otherwise failure.
+ */
+static int SendTls13CertificateVerify(WOLFSSL* ssl)
+{
+    int ret = 0;
+    buffer* sig = &ssl->buffers.sig;
+#ifdef WOLFSSL_ASYNC_CRYPT
+    Scv13Args* args = (Scv13Args*)ssl->async.args;
+    typedef char args_test[sizeof(ssl->async.args) >= sizeof(*args) ? 1 : -1];
+    (void)sizeof(args_test);
+#else
+    Scv13Args  args[1];
+#endif
+
+    WOLFSSL_START(WC_FUNC_CERTIFICATE_VERIFY_SEND);
+    WOLFSSL_ENTER("SendTls13CertificateVerify");
+
+#ifdef WOLFSSL_ASYNC_CRYPT
+    ret = wolfSSL_AsyncPop(ssl, &ssl->options.asyncState);
+    if (ret != WC_NOT_PENDING_E) {
+        /* Check for error */
+        if (ret < 0)
+            goto exit_scv;
+    }
+    else
+#endif
+    {
+        /* Reset state */
+        ret = 0;
+        ssl->options.asyncState = TLS_ASYNC_BEGIN;
+        XMEMSET(args, 0, sizeof(Scv13Args));
+    #ifdef WOLFSSL_ASYNC_CRYPT
+        ssl->async.freeArgs = FreeScv13Args;
+    #endif
+    }
+
+    switch(ssl->options.asyncState)
+    {
+        case TLS_ASYNC_BEGIN:
+        {
+            if (ssl->options.sendVerify == SEND_BLANK_CERT) {
+                return 0;  /* sent blank cert, can't verify */
+            }
+
+            args->sendSz = MAX_CERT_VERIFY_SZ + MAX_MSG_EXTRA;
+            /* Always encrypted.  */
+            args->sendSz += MAX_MSG_EXTRA;
+
+            /* check for available size */
+            if ((ret = CheckAvailableSize(ssl, args->sendSz)) != 0) {
+                goto exit_scv;
+            }
+
+            /* get output buffer */
+            args->output = ssl->buffers.outputBuffer.buffer +
+                           ssl->buffers.outputBuffer.length;
+
+            /* Advance state and proceed */
+            ssl->options.asyncState = TLS_ASYNC_BUILD;
+        } /* case TLS_ASYNC_BEGIN */
+        FALL_THROUGH;
+
+        case TLS_ASYNC_BUILD:
+        {
+            /* idx is used to track verify pointer offset to output */
+            args->idx = RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ;
+            args->verify =
+                          &args->output[RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ];
+
+            if (ssl->buffers.key == NULL) {
+            #ifdef HAVE_PK_CALLBACKS
+                if (wolfSSL_CTX_IsPrivatePkSet(ssl->ctx))
+                    args->length = GetPrivateKeySigSize(ssl);
+                else
+            #endif
+                    ERROR_OUT(NO_PRIVATE_KEY, exit_scv);
+            }
+            else {
+                ret = DecodePrivateKey(ssl, &args->length);
+                if (ret != 0)
+                    goto exit_scv;
+            }
+
+            if (args->length <= 0) {
+                ERROR_OUT(NO_PRIVATE_KEY, exit_scv);
+            }
+
+            /* Add signature algorithm. */
+            if (ssl->hsType == DYNAMIC_TYPE_RSA)
+                args->sigAlgo = rsa_pss_sa_algo;
+            else if (ssl->hsType == DYNAMIC_TYPE_ECC)
+                args->sigAlgo = ecc_dsa_sa_algo;
+        #ifdef HAVE_ED25519
+            else if (ssl->hsType == DYNAMIC_TYPE_ED25519)
+                args->sigAlgo = ed25519_sa_algo;
+        #endif
+        #ifdef HAVE_ED448
+            else if (ssl->hsType == DYNAMIC_TYPE_ED448)
+                args->sigAlgo = ed448_sa_algo;
+        #endif
+            EncodeSigAlg(ssl->suites->hashAlgo, args->sigAlgo, args->verify);
+
+            if (ssl->hsType == DYNAMIC_TYPE_RSA) {
+                int sigLen = MAX_SIG_DATA_SZ;
+                if (args->length > MAX_SIG_DATA_SZ)
+                    sigLen = args->length;
+                args->sigData = (byte*)XMALLOC(sigLen, ssl->heap,
+                                                        DYNAMIC_TYPE_SIGNATURE);
+            }
+            else {
+                args->sigData = (byte*)XMALLOC(MAX_SIG_DATA_SZ, ssl->heap,
+                                                        DYNAMIC_TYPE_SIGNATURE);
+            }
+            if (args->sigData == NULL) {
+                ERROR_OUT(MEMORY_E, exit_scv);
+            }
+
+            /* Create the data to be signed. */
+            ret = CreateSigData(ssl, args->sigData, &args->sigDataSz, 0);
+            if (ret != 0)
+                goto exit_scv;
+
+        #ifndef NO_RSA
+            if (ssl->hsType == DYNAMIC_TYPE_RSA) {
+                /* build encoded signature buffer */
+                sig->length = WC_MAX_DIGEST_SIZE;
+                sig->buffer = (byte*)XMALLOC(sig->length, ssl->heap,
+                                                        DYNAMIC_TYPE_SIGNATURE);
+                if (sig->buffer == NULL) {
+                    ERROR_OUT(MEMORY_E, exit_scv);
+                }
+
+                ret = CreateRSAEncodedSig(sig->buffer, args->sigData,
+                    args->sigDataSz, args->sigAlgo, ssl->suites->hashAlgo);
+                if (ret < 0)
+                    goto exit_scv;
+                sig->length = ret;
+                ret = 0;
+
+                /* Maximum size of RSA Signature. */
+                args->sigLen = args->length;
+            }
+        #endif /* !NO_RSA */
+        #ifdef HAVE_ECC
+            if (ssl->hsType == DYNAMIC_TYPE_ECC) {
+                sig->length = args->sendSz - args->idx - HASH_SIG_SIZE -
+                              VERIFY_HEADER;
+                ret = CreateECCEncodedSig(args->sigData,
+                    args->sigDataSz, ssl->suites->hashAlgo);
+                if (ret < 0)
+                    goto exit_scv;
+                args->sigDataSz = (word16)ret;
+                ret = 0;
+            }
+        #endif /* HAVE_ECC */
+        #ifdef HAVE_ED25519
+            if (ssl->hsType == DYNAMIC_TYPE_ED25519) {
+                ret = Ed25519CheckPubKey(ssl);
+                if (ret < 0) {
+                    ERROR_OUT(ret, exit_scv);
+                }
+                sig->length = ED25519_SIG_SIZE;
+            }
+        #endif /* HAVE_ED25519 */
+        #ifdef HAVE_ED448
+            if (ssl->hsType == DYNAMIC_TYPE_ED448) {
+                ret = Ed448CheckPubKey(ssl);
+                if (ret < 0) {
+                    ERROR_OUT(ret, exit_scv);
+                }
+                sig->length = ED448_SIG_SIZE;
+            }
+        #endif /* HAVE_ED448 */
+
+            /* Advance state and proceed */
+            ssl->options.asyncState = TLS_ASYNC_DO;
+        } /* case TLS_ASYNC_BUILD */
+        FALL_THROUGH;
+
+        case TLS_ASYNC_DO:
+        {
+        #ifdef HAVE_ECC
+           if (ssl->hsType == DYNAMIC_TYPE_ECC) {
+
+                ret = EccSign(ssl, args->sigData, args->sigDataSz,
+                    args->verify + HASH_SIG_SIZE + VERIFY_HEADER,
+                    (word32*)&sig->length, (ecc_key*)ssl->hsKey,
+            #ifdef HAVE_PK_CALLBACKS
+                    ssl->buffers.key
+            #else
+                    NULL
+            #endif
+                );
+                args->length = (word16)sig->length;
+            }
+        #endif /* HAVE_ECC */
+        #ifdef HAVE_ED25519
+            if (ssl->hsType == DYNAMIC_TYPE_ED25519) {
+                ret = Ed25519Sign(ssl, args->sigData, args->sigDataSz,
+                    args->verify + HASH_SIG_SIZE + VERIFY_HEADER,
+                    (word32*)&sig->length, (ed25519_key*)ssl->hsKey,
+            #ifdef HAVE_PK_CALLBACKS
+                    ssl->buffers.key
+            #else
+                    NULL
+            #endif
+                );
+                args->length = (word16)sig->length;
+            }
+        #endif
+        #ifdef HAVE_ED448
+            if (ssl->hsType == DYNAMIC_TYPE_ED448) {
+                ret = Ed448Sign(ssl, args->sigData, args->sigDataSz,
+                    args->verify + HASH_SIG_SIZE + VERIFY_HEADER,
+                    (word32*)&sig->length, (ed448_key*)ssl->hsKey,
+            #ifdef HAVE_PK_CALLBACKS
+                    ssl->buffers.key
+            #else
+                    NULL
+            #endif
+                );
+                args->length = (word16)sig->length;
+            }
+        #endif
+        #ifndef NO_RSA
+            if (ssl->hsType == DYNAMIC_TYPE_RSA) {
+                ret = RsaSign(ssl, sig->buffer, (word32)sig->length,
+                    args->verify + HASH_SIG_SIZE + VERIFY_HEADER, &args->sigLen,
+                    args->sigAlgo, ssl->suites->hashAlgo,
+                    (RsaKey*)ssl->hsKey,
+                    ssl->buffers.key
+                );
+                if (ret == 0) {
+                    args->length = (word16)args->sigLen;
+
+                    XMEMCPY(args->sigData,
+                        args->verify + HASH_SIG_SIZE + VERIFY_HEADER,
+                        args->sigLen);
+                }
+            }
+        #endif /* !NO_RSA */
+
+            /* Check for error */
+            if (ret != 0) {
+                goto exit_scv;
+            }
+
+            /* Add signature length. */
+            c16toa(args->length, args->verify + HASH_SIG_SIZE);
+
+            /* Advance state and proceed */
+            ssl->options.asyncState = TLS_ASYNC_VERIFY;
+        } /* case TLS_ASYNC_DO */
+        FALL_THROUGH;
+
+        case TLS_ASYNC_VERIFY:
+        {
+        #ifndef NO_RSA
+            if (ssl->hsType == DYNAMIC_TYPE_RSA) {
+                /* check for signature faults */
+                ret = VerifyRsaSign(ssl, args->sigData, args->sigLen,
+                    sig->buffer, (word32)sig->length, args->sigAlgo,
+                    ssl->suites->hashAlgo, (RsaKey*)ssl->hsKey,
+                    ssl->buffers.key
+                );
+            }
+        #endif /* !NO_RSA */
+
+            /* Check for error */
+            if (ret != 0) {
+                goto exit_scv;
+            }
+
+            /* Advance state and proceed */
+            ssl->options.asyncState = TLS_ASYNC_FINALIZE;
+        } /* case TLS_ASYNC_VERIFY */
+        FALL_THROUGH;
+
+        case TLS_ASYNC_FINALIZE:
+        {
+            /* Put the record and handshake headers on. */
+            AddTls13Headers(args->output, args->length + HASH_SIG_SIZE +
+                            VERIFY_HEADER, certificate_verify, ssl);
+
+            args->sendSz = RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ +
+                                   args->length + HASH_SIG_SIZE + VERIFY_HEADER;
+
+            /* Advance state and proceed */
+            ssl->options.asyncState = TLS_ASYNC_END;
+        } /* case TLS_ASYNC_FINALIZE */
+        FALL_THROUGH;
+
+        case TLS_ASYNC_END:
+        {
+            /* This message is always encrypted. */
+            ret = BuildTls13Message(ssl, args->output,
+                                    MAX_CERT_VERIFY_SZ + MAX_MSG_EXTRA,
+                                    args->output + RECORD_HEADER_SZ,
+                                    args->sendSz - RECORD_HEADER_SZ, handshake,
+                                    1, 0, 0);
+
+            if (ret < 0) {
+                goto exit_scv;
+            }
+            else {
+                args->sendSz = ret;
+                ret = 0;
+            }
+
+        #ifdef WOLFSSL_CALLBACKS
+            if (ssl->hsInfoOn)
+                AddPacketName(ssl, "CertificateVerify");
+            if (ssl->toInfoOn) {
+                AddPacketInfo(ssl, "CertificateVerify", handshake,
+                            args->output, args->sendSz, WRITE_PROTO, ssl->heap);
+            }
+        #endif
+
+            ssl->buffers.outputBuffer.length += args->sendSz;
+
+            if (!ssl->options.groupMessages)
+                ret = SendBuffered(ssl);
+            break;
+        }
+        default:
+            ret = INPUT_CASE_ERROR;
+    } /* switch(ssl->options.asyncState) */
+
+exit_scv:
+
+    WOLFSSL_LEAVE("SendTls13CertificateVerify", ret);
+    WOLFSSL_END(WC_FUNC_CERTIFICATE_VERIFY_SEND);
+
+#ifdef WOLFSSL_ASYNC_CRYPT
+    /* Handle async operation */
+    if (ret == WC_PENDING_E) {
+        return ret;
+    }
+#endif /* WOLFSSL_ASYNC_CRYPT */
+
+    /* Final cleanup */
+    FreeScv13Args(ssl, args);
+    FreeKeyExchange(ssl);
+
+    return ret;
+}
+
+/* handle processing TLS v1.3 certificate (11) */
+/* Parse and handle a TLS v1.3 Certificate message.
+ *
+ * ssl       The SSL/TLS object.
+ * input     The message buffer.
+ * inOutIdx  On entry, the index into the message buffer of Certificate.
+ *           On exit, the index of byte after the Certificate message.
+ * totalSz   The length of the current handshake message.
+ * returns 0 on success and otherwise failure.
+ */
+static int DoTls13Certificate(WOLFSSL* ssl, byte* input, word32* inOutIdx,
+                              word32 totalSz)
+{
+    int ret;
+
+    WOLFSSL_START(WC_FUNC_CERTIFICATE_DO);
+    WOLFSSL_ENTER("DoTls13Certificate");
+
+    ret = ProcessPeerCerts(ssl, input, inOutIdx, totalSz);
+    if (ret == 0) {
+#if !defined(NO_WOLFSSL_CLIENT)
+        if (ssl->options.side == WOLFSSL_CLIENT_END)
+            ssl->options.serverState = SERVER_CERT_COMPLETE;
+#endif
+#if !defined(NO_WOLFSSL_SERVER) && defined(WOLFSSL_POST_HANDSHAKE_AUTH)
+        if (ssl->options.side == WOLFSSL_SERVER_END &&
+                                ssl->options.handShakeState == HANDSHAKE_DONE) {
+            /* reset handshake states */
+            ssl->options.serverState = SERVER_FINISHED_COMPLETE;
+            ssl->options.acceptState  = TICKET_SENT;
+            ssl->options.handShakeState = SERVER_FINISHED_COMPLETE;
+        }
+#endif
+    }
+
+    WOLFSSL_LEAVE("DoTls13Certificate", ret);
+    WOLFSSL_END(WC_FUNC_CERTIFICATE_DO);
+
+    return ret;
+}
+
+#if !defined(NO_RSA) || defined(HAVE_ECC) || defined(HAVE_ED25519) || \
+                                                             defined(HAVE_ED448)
+
+typedef struct Dcv13Args {
+    byte*  output; /* not allocated */
+    word32 sendSz;
+    word16 sz;
+    word32 sigSz;
+    word32 idx;
+    word32 begin;
+    byte   hashAlgo;
+    byte   sigAlgo;
+
+    byte*  sigData;
+    word16 sigDataSz;
+} Dcv13Args;
+
+static void FreeDcv13Args(WOLFSSL* ssl, void* pArgs)
+{
+    Dcv13Args* args = (Dcv13Args*)pArgs;
+
+    if (args->sigData != NULL) {
+        XFREE(args->sigData, ssl->heap, DYNAMIC_TYPE_SIGNATURE);
+        args->sigData = NULL;
+    }
+
+    (void)ssl;
+}
+
+/* handle processing TLS v1.3 certificate_verify (15) */
+/* Parse and handle a TLS v1.3 CertificateVerify message.
+ *
+ * ssl       The SSL/TLS object.
+ * input     The message buffer.
+ * inOutIdx  On entry, the index into the message buffer of
+ *           CertificateVerify.
+ *           On exit, the index of byte after the CertificateVerify message.
+ * totalSz   The length of the current handshake message.
+ * returns 0 on success and otherwise failure.
+ */
+static int DoTls13CertificateVerify(WOLFSSL* ssl, byte* input,
+                                    word32* inOutIdx, word32 totalSz)
+{
+    int         ret = 0;
+    buffer*     sig = &ssl->buffers.sig;
+#ifdef WOLFSSL_ASYNC_CRYPT
+    Dcv13Args* args = (Dcv13Args*)ssl->async.args;
+    typedef char args_test[sizeof(ssl->async.args) >= sizeof(*args) ? 1 : -1];
+    (void)sizeof(args_test);
+#else
+    Dcv13Args  args[1];
+#endif
+
+    WOLFSSL_START(WC_FUNC_CERTIFICATE_VERIFY_DO);
+    WOLFSSL_ENTER("DoTls13CertificateVerify");
+
+#ifdef WOLFSSL_ASYNC_CRYPT
+    ret = wolfSSL_AsyncPop(ssl, &ssl->options.asyncState);
+    if (ret != WC_NOT_PENDING_E) {
+        /* Check for error */
+        if (ret < 0)
+            goto exit_dcv;
+    }
+    else
+#endif
+    {
+        /* Reset state */
+        ret = 0;
+        ssl->options.asyncState = TLS_ASYNC_BEGIN;
+        XMEMSET(args, 0, sizeof(Dcv13Args));
+        args->hashAlgo = sha_mac;
+        args->sigAlgo = anonymous_sa_algo;
+        args->idx = *inOutIdx;
+        args->begin = *inOutIdx;
+    #ifdef WOLFSSL_ASYNC_CRYPT
+        ssl->async.freeArgs = FreeDcv13Args;
+    #endif
+    }
+
+    switch(ssl->options.asyncState)
+    {
+        case TLS_ASYNC_BEGIN:
+        {
+        #ifdef WOLFSSL_CALLBACKS
+            if (ssl->hsInfoOn) AddPacketName(ssl, "CertificateVerify");
+            if (ssl->toInfoOn) AddLateName("CertificateVerify",
+                                           &ssl->timeoutInfo);
+        #endif
+
+            /* Advance state and proceed */
+            ssl->options.asyncState = TLS_ASYNC_BUILD;
+        } /* case TLS_ASYNC_BEGIN */
+        FALL_THROUGH;
+
+        case TLS_ASYNC_BUILD:
+        {
+            /* Signature algorithm. */
+            if ((args->idx - args->begin) + ENUM_LEN + ENUM_LEN > totalSz) {
+                ERROR_OUT(BUFFER_ERROR, exit_dcv);
+            }
+            ret = DecodeTls13SigAlg(input + args->idx, &args->hashAlgo,
+                                                                &args->sigAlgo);
+            if (ret < 0)
+                goto exit_dcv;
+            args->idx += OPAQUE16_LEN;
+
+            /* Signature length. */
+            if ((args->idx - args->begin) + OPAQUE16_LEN > totalSz) {
+                ERROR_OUT(BUFFER_ERROR, exit_dcv);
+            }
+            ato16(input + args->idx, &args->sz);
+            args->idx += OPAQUE16_LEN;
+
+            /* Signature data. */
+            if ((args->idx - args->begin) + args->sz > totalSz ||
+                                                       args->sz > ENCRYPT_LEN) {
+                ERROR_OUT(BUFFER_ERROR, exit_dcv);
+            }
+
+            /* Check for public key of required type. */
+        #ifdef HAVE_ED25519
+            if (args->sigAlgo == ed25519_sa_algo &&
+                                                  !ssl->peerEd25519KeyPresent) {
+                WOLFSSL_MSG("Oops, peer sent ED25519 key but not in verify");
+            }
+        #endif
+        #ifdef HAVE_ED448
+            if (args->sigAlgo == ed448_sa_algo && !ssl->peerEd448KeyPresent) {
+                WOLFSSL_MSG("Oops, peer sent ED448 key but not in verify");
+            }
+        #endif
+        #ifdef HAVE_ECC
+            if (args->sigAlgo == ecc_dsa_sa_algo &&
+                                                   !ssl->peerEccDsaKeyPresent) {
+                WOLFSSL_MSG("Oops, peer sent ECC key but not in verify");
+            }
+        #endif
+        #ifndef NO_RSA
+            if (args->sigAlgo == rsa_sa_algo) {
+                WOLFSSL_MSG("Oops, peer sent PKCS#1.5 signature");
+                ERROR_OUT(INVALID_PARAMETER, exit_dcv);
+            }
+            if (args->sigAlgo == rsa_pss_sa_algo &&
+                         (ssl->peerRsaKey == NULL || !ssl->peerRsaKeyPresent)) {
+                WOLFSSL_MSG("Oops, peer sent RSA key but not in verify");
+            }
+        #endif
+
+            sig->buffer = (byte*)XMALLOC(args->sz, ssl->heap,
+                                         DYNAMIC_TYPE_SIGNATURE);
+            if (sig->buffer == NULL) {
+                ERROR_OUT(MEMORY_E, exit_dcv);
+            }
+            sig->length = args->sz;
+            XMEMCPY(sig->buffer, input + args->idx, args->sz);
+
+        #ifdef HAVE_ECC
+            if (ssl->peerEccDsaKeyPresent) {
+                WOLFSSL_MSG("Doing ECC peer cert verify");
+
+                args->sigData = (byte*)XMALLOC(MAX_SIG_DATA_SZ, ssl->heap,
+                                                        DYNAMIC_TYPE_SIGNATURE);
+                if (args->sigData == NULL) {
+                    ERROR_OUT(MEMORY_E, exit_dcv);
+                }
+
+                ret = CreateSigData(ssl, args->sigData, &args->sigDataSz, 1);
+                if (ret != 0)
+                    goto exit_dcv;
+                ret = CreateECCEncodedSig(args->sigData,
+                    args->sigDataSz, args->hashAlgo);
+                if (ret < 0)
+                    goto exit_dcv;
+                args->sigDataSz = (word16)ret;
+                ret = 0;
+            }
+        #endif
+        #ifdef HAVE_ED25519
+            if (ssl->peerEd25519KeyPresent) {
+                WOLFSSL_MSG("Doing ED25519 peer cert verify");
+
+                args->sigData = (byte*)XMALLOC(MAX_SIG_DATA_SZ, ssl->heap,
+                                                        DYNAMIC_TYPE_SIGNATURE);
+                if (args->sigData == NULL) {
+                    ERROR_OUT(MEMORY_E, exit_dcv);
+                }
+
+                CreateSigData(ssl, args->sigData, &args->sigDataSz, 1);
+                ret = 0;
+            }
+        #endif
+        #ifdef HAVE_ED448
+            if (ssl->peerEd448KeyPresent) {
+                WOLFSSL_MSG("Doing ED448 peer cert verify");
+
+                args->sigData = (byte*)XMALLOC(MAX_SIG_DATA_SZ, ssl->heap,
+                                                        DYNAMIC_TYPE_SIGNATURE);
+                if (args->sigData == NULL) {
+                    ERROR_OUT(MEMORY_E, exit_dcv);
+                }
+
+                CreateSigData(ssl, args->sigData, &args->sigDataSz, 1);
+                ret = 0;
+            }
+       #endif
+
+            /* Advance state and proceed */
+            ssl->options.asyncState = TLS_ASYNC_DO;
+        } /* case TLS_ASYNC_BUILD */
+        FALL_THROUGH;
+
+        case TLS_ASYNC_DO:
+        {
+        #ifndef NO_RSA
+            if (ssl->peerRsaKey != NULL && ssl->peerRsaKeyPresent != 0) {
+                WOLFSSL_MSG("Doing RSA peer cert verify");
+
+                ret = RsaVerify(ssl, sig->buffer, (word32)sig->length, &args->output,
+                    args->sigAlgo, args->hashAlgo, ssl->peerRsaKey,
+                #ifdef HAVE_PK_CALLBACKS
+                    &ssl->buffers.peerRsaKey
+                #else
+                    NULL
+                #endif
+                );
+                if (ret >= 0) {
+                    args->sendSz = ret;
+                    ret = 0;
+                }
+            }
+        #endif /* !NO_RSA */
+        #ifdef HAVE_ECC
+            if (ssl->peerEccDsaKeyPresent) {
+                WOLFSSL_MSG("Doing ECC peer cert verify");
+
+                ret = EccVerify(ssl, input + args->idx, args->sz,
+                    args->sigData, args->sigDataSz,
+                    ssl->peerEccDsaKey,
+                #ifdef HAVE_PK_CALLBACKS
+                    &ssl->buffers.peerEccDsaKey
+                #else
+                    NULL
+                #endif
+                );
+
+                if (ret >= 0) {
+                    FreeKey(ssl, DYNAMIC_TYPE_ECC, (void**)&ssl->peerEccDsaKey);
+                    ssl->peerEccDsaKeyPresent = 0;
+                }
+            }
+        #endif /* HAVE_ECC */
+        #ifdef HAVE_ED25519
+            if (ssl->peerEd25519KeyPresent) {
+                WOLFSSL_MSG("Doing ED25519 peer cert verify");
+
+                ret = Ed25519Verify(ssl, input + args->idx, args->sz,
+                    args->sigData, args->sigDataSz,
+                    ssl->peerEd25519Key,
+                #ifdef HAVE_PK_CALLBACKS
+                    &ssl->buffers.peerEd25519Key
+                #else
+                    NULL
+                #endif
+                );
+
+                if (ret >= 0) {
+                    FreeKey(ssl, DYNAMIC_TYPE_ED25519,
+                                                  (void**)&ssl->peerEd25519Key);
+                    ssl->peerEd25519KeyPresent = 0;
+                }
+            }
+        #endif
+        #ifdef HAVE_ED448
+            if (ssl->peerEd448KeyPresent) {
+                WOLFSSL_MSG("Doing ED448 peer cert verify");
+
+                ret = Ed448Verify(ssl, input + args->idx, args->sz,
+                    args->sigData, args->sigDataSz,
+                    ssl->peerEd448Key,
+                #ifdef HAVE_PK_CALLBACKS
+                    &ssl->buffers.peerEd448Key
+                #else
+                    NULL
+                #endif
+                );
+
+                if (ret >= 0) {
+                    FreeKey(ssl, DYNAMIC_TYPE_ED448,
+                                                    (void**)&ssl->peerEd448Key);
+                    ssl->peerEd448KeyPresent = 0;
+                }
+            }
+        #endif
+
+            /* Check for error */
+            if (ret != 0) {
+                goto exit_dcv;
+            }
+
+            /* Advance state and proceed */
+            ssl->options.asyncState = TLS_ASYNC_VERIFY;
+        } /* case TLS_ASYNC_DO */
+        FALL_THROUGH;
+
+        case TLS_ASYNC_VERIFY:
+        {
+        #ifndef NO_RSA
+            if (ssl->peerRsaKey != NULL && ssl->peerRsaKeyPresent != 0) {
+                ret = CheckRSASignature(ssl, args->sigAlgo, args->hashAlgo,
+                                        args->output, args->sendSz);
+                if (ret != 0)
+                    goto exit_dcv;
+
+                FreeKey(ssl, DYNAMIC_TYPE_RSA, (void**)&ssl->peerRsaKey);
+                ssl->peerRsaKeyPresent = 0;
+            }
+        #endif /* !NO_RSA */
+
+            /* Advance state and proceed */
+            ssl->options.asyncState = TLS_ASYNC_FINALIZE;
+        } /* case TLS_ASYNC_VERIFY */
+        FALL_THROUGH;
+
+        case TLS_ASYNC_FINALIZE:
+        {
+            ssl->options.havePeerVerify = 1;
+
+            /* Set final index */
+            args->idx += args->sz;
+            *inOutIdx = args->idx;
+
+            /* Encryption is always on: add padding */
+            *inOutIdx += ssl->keys.padSz;
+
+            /* Advance state and proceed */
+            ssl->options.asyncState = TLS_ASYNC_END;
+        } /* case TLS_ASYNC_FINALIZE */
+
+        case TLS_ASYNC_END:
+        {
+            break;
+        }
+        default:
+            ret = INPUT_CASE_ERROR;
+    } /* switch(ssl->options.asyncState) */
+
+exit_dcv:
+
+    WOLFSSL_LEAVE("DoTls13CertificateVerify", ret);
+    WOLFSSL_END(WC_FUNC_CERTIFICATE_VERIFY_DO);
+
+#ifdef WOLFSSL_ASYNC_CRYPT
+    /* Handle async operation */
+    if (ret == WC_PENDING_E) {
+        /* Mark message as not received so it can process again */
+        ssl->msgsReceived.got_certificate_verify = 0;
+
+        return ret;
+    }
+    else
+#endif /* WOLFSSL_ASYNC_CRYPT */
+    if (ret != 0 && ret != INVALID_PARAMETER)
+        SendAlert(ssl, alert_fatal, decrypt_error);
+
+    /* Final cleanup */
+    FreeDcv13Args(ssl, args);
+    FreeKeyExchange(ssl);
+
+    return ret;
+}
+#endif /* !NO_RSA || HAVE_ECC */
+
+/* Parse and handle a TLS v1.3 Finished message.
+ *
+ * ssl       The SSL/TLS object.
+ * input     The message buffer.
+ * inOutIdx  On entry, the index into the message buffer of Finished.
+ *           On exit, the index of byte after the Finished message and padding.
+ * size      Length of message data.
+ * totalSz   Length of remaining data in the message buffer.
+ * sniff     Indicates whether we are sniffing packets.
+ * returns 0 on success and otherwise failure.
+ */
+static int DoTls13Finished(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
+                           word32 size, word32 totalSz, int sniff)
+{
+    int    ret;
+    word32 finishedSz = 0;
+    byte*  secret;
+    byte   mac[WC_MAX_DIGEST_SIZE];
+
+    WOLFSSL_START(WC_FUNC_FINISHED_DO);
+    WOLFSSL_ENTER("DoTls13Finished");
+
+    /* check against totalSz */
+    if (*inOutIdx + size + ssl->keys.padSz > totalSz)
+        return BUFFER_E;
+
+    if (ssl->options.handShakeDone) {
+        ret = DeriveFinishedSecret(ssl, ssl->clientSecret,
+                                   ssl->keys.client_write_MAC_secret);
+        if (ret != 0)
+            return ret;
+
+        secret = ssl->keys.client_write_MAC_secret;
+    }
+    else if (ssl->options.side == WOLFSSL_CLIENT_END) {
+        /* All the handshake messages have been received to calculate
+         * client and server finished keys.
+         */
+        ret = DeriveFinishedSecret(ssl, ssl->clientSecret,
+                                   ssl->keys.client_write_MAC_secret);
+        if (ret != 0)
+            return ret;
+
+        ret = DeriveFinishedSecret(ssl, ssl->serverSecret,
+                                   ssl->keys.server_write_MAC_secret);
+        if (ret != 0)
+            return ret;
+
+        secret = ssl->keys.server_write_MAC_secret;
+    }
+    else
+        secret = ssl->keys.client_write_MAC_secret;
+
+    ret = BuildTls13HandshakeHmac(ssl, secret, mac, &finishedSz);
+    if (ret != 0)
+        return ret;
+    if (size != finishedSz)
+        return BUFFER_ERROR;
+
+    #ifdef WOLFSSL_CALLBACKS
+        if (ssl->hsInfoOn) AddPacketName(ssl, "Finished");
+        if (ssl->toInfoOn) AddLateName("Finished", &ssl->timeoutInfo);
+    #endif
+
+    if (sniff == NO_SNIFF) {
+        /* Actually check verify data. */
+        if (XMEMCMP(input + *inOutIdx, mac, size) != 0){
+            WOLFSSL_MSG("Verify finished error on hashes");
+            SendAlert(ssl, alert_fatal, decrypt_error);
+            return VERIFY_FINISHED_ERROR;
+        }
+    }
+
+    /* Force input exhaustion at ProcessReply by consuming padSz. */
+    *inOutIdx += size + ssl->keys.padSz;
+
+    if (ssl->options.side == WOLFSSL_SERVER_END &&
+                                                  !ssl->options.handShakeDone) {
+#ifdef WOLFSSL_EARLY_DATA
+        if (ssl->earlyData != no_early_data) {
+            if ((ret = DeriveTls13Keys(ssl, no_key, DECRYPT_SIDE_ONLY, 1)) != 0)
+                return ret;
+        }
+#endif
+        /* Setup keys for application data messages from client. */
+        if ((ret = SetKeysSide(ssl, DECRYPT_SIDE_ONLY)) != 0)
+            return ret;
+    }
+
+#ifndef NO_WOLFSSL_CLIENT
+    if (ssl->options.side == WOLFSSL_CLIENT_END)
+        ssl->options.serverState = SERVER_FINISHED_COMPLETE;
+#endif
+#ifndef NO_WOLFSSL_SERVER
+    if (ssl->options.side == WOLFSSL_SERVER_END) {
+        ssl->options.clientState = CLIENT_FINISHED_COMPLETE;
+        ssl->options.handShakeState = HANDSHAKE_DONE;
+        ssl->options.handShakeDone  = 1;
+    }
+#endif
+
+    WOLFSSL_LEAVE("DoTls13Finished", 0);
+    WOLFSSL_END(WC_FUNC_FINISHED_DO);
+
+    return 0;
+}
+#endif /* NO_CERTS */
+
+/* Send the TLS v1.3 Finished message.
+ *
+ * ssl  The SSL/TLS object.
+ * returns 0 on success, otherwise failure.
+ */
+static int SendTls13Finished(WOLFSSL* ssl)
+{
+    int   sendSz;
+    int   finishedSz = ssl->specs.hash_size;
+    byte* input;
+    byte* output;
+    int   ret;
+    int   headerSz = HANDSHAKE_HEADER_SZ;
+    int   outputSz;
+    byte* secret;
+
+    WOLFSSL_START(WC_FUNC_FINISHED_SEND);
+    WOLFSSL_ENTER("SendTls13Finished");
+
+    outputSz = WC_MAX_DIGEST_SIZE + DTLS_HANDSHAKE_HEADER_SZ + MAX_MSG_EXTRA;
+    /* Check buffers are big enough and grow if needed. */
+    if ((ret = CheckAvailableSize(ssl, outputSz)) != 0)
+        return ret;
+
+    /* get output buffer */
+    output = ssl->buffers.outputBuffer.buffer +
+             ssl->buffers.outputBuffer.length;
+    input = output + RECORD_HEADER_SZ;
+
+    AddTls13HandShakeHeader(input, finishedSz, 0, finishedSz, finished, ssl);
+
+    /* make finished hashes */
+    if (ssl->options.handShakeDone) {
+        ret = DeriveFinishedSecret(ssl, ssl->clientSecret,
+                                   ssl->keys.client_write_MAC_secret);
+        if (ret != 0)
+            return ret;
+
+        secret = ssl->keys.client_write_MAC_secret;
+    }
+    else if (ssl->options.side == WOLFSSL_CLIENT_END)
+        secret = ssl->keys.client_write_MAC_secret;
+    else {
+        /* All the handshake messages have been done to calculate client and
+         * server finished keys.
+         */
+        ret = DeriveFinishedSecret(ssl, ssl->clientSecret,
+                                   ssl->keys.client_write_MAC_secret);
+        if (ret != 0)
+            return ret;
+
+        ret = DeriveFinishedSecret(ssl, ssl->serverSecret,
+                                   ssl->keys.server_write_MAC_secret);
+        if (ret != 0)
+            return ret;
+
+        secret = ssl->keys.server_write_MAC_secret;
+    }
+    ret = BuildTls13HandshakeHmac(ssl, secret, &input[headerSz], NULL);
+    if (ret != 0)
+        return ret;
+
+    /* This message is always encrypted. */
+    sendSz = BuildTls13Message(ssl, output, outputSz, input,
+                               headerSz + finishedSz, handshake, 1, 0, 0);
+    if (sendSz < 0)
+        return BUILD_MSG_ERROR;
+
+#ifndef NO_SESSION_CACHE
+    if (!ssl->options.resuming && (ssl->options.side == WOLFSSL_SERVER_END ||
+            (ssl->options.side == WOLFSSL_SERVER_END && ssl->arrays != NULL))) {
+        AddSession(ssl);    /* just try */
+    }
+#endif
+
+    #ifdef WOLFSSL_CALLBACKS
+        if (ssl->hsInfoOn) AddPacketName(ssl, "Finished");
+        if (ssl->toInfoOn) {
+            AddPacketInfo(ssl, "Finished", handshake, output, sendSz,
+                          WRITE_PROTO, ssl->heap);
+        }
+    #endif
+
+    ssl->buffers.outputBuffer.length += sendSz;
+
+    if (ssl->options.side == WOLFSSL_SERVER_END) {
+        /* Can send application data now. */
+        if ((ret = DeriveMasterSecret(ssl)) != 0)
+            return ret;
+#ifdef WOLFSSL_EARLY_DATA
+        if ((ret = DeriveTls13Keys(ssl, traffic_key, ENCRYPT_SIDE_ONLY, 1))
+                                                                         != 0) {
+            return ret;
+        }
+        if ((ret = DeriveTls13Keys(ssl, traffic_key, DECRYPT_SIDE_ONLY,
+                                       ssl->earlyData == no_early_data)) != 0) {
+            return ret;
+        }
+#else
+        if ((ret = DeriveTls13Keys(ssl, traffic_key, ENCRYPT_AND_DECRYPT_SIDE,
+                                                                     1)) != 0) {
+            return ret;
+        }
+#endif
+        if ((ret = SetKeysSide(ssl, ENCRYPT_SIDE_ONLY)) != 0)
+            return ret;
+    }
+
+    if (ssl->options.side == WOLFSSL_CLIENT_END &&
+                                                  !ssl->options.handShakeDone) {
+#ifdef WOLFSSL_EARLY_DATA
+        if (ssl->earlyData != no_early_data) {
+            if ((ret = DeriveTls13Keys(ssl, no_key, ENCRYPT_AND_DECRYPT_SIDE,
+                                                                     1)) != 0) {
+                    return ret;
+            }
+        }
+#endif
+        /* Setup keys for application data messages. */
+        if ((ret = SetKeysSide(ssl, ENCRYPT_AND_DECRYPT_SIDE)) != 0)
+            return ret;
+
+#if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
+        ret = DeriveResumptionSecret(ssl, ssl->session.masterSecret);
+        if (ret != 0)
+            return ret;
+#endif
+    }
+
+#ifndef NO_WOLFSSL_CLIENT
+    if (ssl->options.side == WOLFSSL_CLIENT_END) {
+        ssl->options.clientState = CLIENT_FINISHED_COMPLETE;
+        ssl->options.handShakeState = HANDSHAKE_DONE;
+        ssl->options.handShakeDone  = 1;
+    }
+#endif
+#ifndef NO_WOLFSSL_SERVER
+    if (ssl->options.side == WOLFSSL_SERVER_END) {
+        ssl->options.serverState = SERVER_FINISHED_COMPLETE;
+    }
+#endif
+
+    if ((ret = SendBuffered(ssl)) != 0)
+        return ret;
+
+    WOLFSSL_LEAVE("SendTls13Finished", ret);
+    WOLFSSL_END(WC_FUNC_FINISHED_SEND);
+
+    return ret;
+}
+
+/* handle generation TLS v1.3 key_update (24) */
+/* Send the TLS v1.3 KeyUpdate message.
+ *
+ * ssl  The SSL/TLS object.
+ * returns 0 on success, otherwise failure.
+ */
+static int SendTls13KeyUpdate(WOLFSSL* ssl)
+{
+    int    sendSz;
+    byte*  input;
+    byte*  output;
+    int    ret;
+    int    headerSz = HANDSHAKE_HEADER_SZ;
+    int    outputSz;
+    word32 i = RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ;
+
+    WOLFSSL_START(WC_FUNC_KEY_UPDATE_SEND);
+    WOLFSSL_ENTER("SendTls13KeyUpdate");
+
+    outputSz = OPAQUE8_LEN + MAX_MSG_EXTRA;
+    /* Check buffers are big enough and grow if needed. */
+    if ((ret = CheckAvailableSize(ssl, outputSz)) != 0)
+        return ret;
+
+    /* get output buffer */
+    output = ssl->buffers.outputBuffer.buffer +
+             ssl->buffers.outputBuffer.length;
+    input = output + RECORD_HEADER_SZ;
+
+    AddTls13Headers(output, OPAQUE8_LEN, key_update, ssl);
+
+    /* If:
+     *   1. I haven't sent a KeyUpdate requesting a response and
+     *   2. This isn't responding to peer KeyUpdate requiring a response then,
+     * I want a response.
+     */
+    ssl->keys.updateResponseReq = output[i++] =
+         !ssl->keys.updateResponseReq && !ssl->keys.keyUpdateRespond;
+    /* Sent response, no longer need to respond. */
+    ssl->keys.keyUpdateRespond = 0;
+
+    /* This message is always encrypted. */
+    sendSz = BuildTls13Message(ssl, output, outputSz, input,
+                               headerSz + OPAQUE8_LEN, handshake, 0, 0, 0);
+    if (sendSz < 0)
+        return BUILD_MSG_ERROR;
+
+    #ifdef WOLFSSL_CALLBACKS
+        if (ssl->hsInfoOn) AddPacketName(ssl, "KeyUpdate");
+        if (ssl->toInfoOn) {
+            AddPacketInfo(ssl, "KeyUpdate", handshake, output, sendSz,
+                          WRITE_PROTO, ssl->heap);
+        }
+    #endif
+
+    ssl->buffers.outputBuffer.length += sendSz;
+
+    ret = SendBuffered(ssl);
+    if (ret != 0 && ret != WANT_WRITE)
+        return ret;
+
+    /* Future traffic uses new encryption keys. */
+    if ((ret = DeriveTls13Keys(ssl, update_traffic_key, ENCRYPT_SIDE_ONLY, 1))
+                                                                           != 0)
+        return ret;
+    if ((ret = SetKeysSide(ssl, ENCRYPT_SIDE_ONLY)) != 0)
+        return ret;
+
+    WOLFSSL_LEAVE("SendTls13KeyUpdate", ret);
+    WOLFSSL_END(WC_FUNC_KEY_UPDATE_SEND);
+
+    return ret;
+}
+
+/* handle processing TLS v1.3 key_update (24) */
+/* Parse and handle a TLS v1.3 KeyUpdate message.
+ *
+ * ssl       The SSL/TLS object.
+ * input     The message buffer.
+ * inOutIdx  On entry, the index into the message buffer of Finished.
+ *           On exit, the index of byte after the Finished message and padding.
+ * totalSz   The length of the current handshake message.
+ * returns 0 on success and otherwise failure.
+ */
+static int DoTls13KeyUpdate(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
+                            word32 totalSz)
+{
+    int    ret;
+    word32 i = *inOutIdx;
+
+    WOLFSSL_START(WC_FUNC_KEY_UPDATE_DO);
+    WOLFSSL_ENTER("DoTls13KeyUpdate");
+
+    /* check against totalSz */
+    if (OPAQUE8_LEN != totalSz)
+        return BUFFER_E;
+
+    switch (input[i]) {
+        case update_not_requested:
+            /* This message in response to any outstanding request. */
+            ssl->keys.keyUpdateRespond = 0;
+            ssl->keys.updateResponseReq = 0;
+            break;
+        case update_requested:
+            /* New key update requiring a response. */
+            ssl->keys.keyUpdateRespond = 1;
+            break;
+        default:
+            return INVALID_PARAMETER;
+    }
+
+    /* Move index to byte after message. */
+    *inOutIdx += totalSz;
+    /* Always encrypted. */
+    *inOutIdx += ssl->keys.padSz;
+
+    /* Future traffic uses new decryption keys. */
+    if ((ret = DeriveTls13Keys(ssl, update_traffic_key, DECRYPT_SIDE_ONLY, 1))
+                                                                         != 0) {
+        return ret;
+    }
+    if ((ret = SetKeysSide(ssl, DECRYPT_SIDE_ONLY)) != 0)
+        return ret;
+
+    if (ssl->keys.keyUpdateRespond)
+        return SendTls13KeyUpdate(ssl);
+
+    WOLFSSL_LEAVE("DoTls13KeyUpdate", ret);
+    WOLFSSL_END(WC_FUNC_KEY_UPDATE_DO);
+
+    return 0;
+}
+
+#ifdef WOLFSSL_EARLY_DATA
+#ifndef NO_WOLFSSL_CLIENT
+/* Send the TLS v1.3 EndOfEarlyData message to indicate that there will be no
+ * more early application data.
+ * The encryption key now changes to the pre-calculated handshake key.
+ *
+ * ssl  The SSL/TLS object.
+ * returns 0 on success and otherwise failure.
+ */
+static int SendTls13EndOfEarlyData(WOLFSSL* ssl)
+{
+    byte*  output;
+    int    ret;
+    int    sendSz;
+    word32 length;
+    word32 idx = RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ;
+
+    WOLFSSL_START(WC_FUNC_END_OF_EARLY_DATA_SEND);
+    WOLFSSL_ENTER("SendTls13EndOfEarlyData");
+
+    length = 0;
+    sendSz = idx + length + MAX_MSG_EXTRA;
+
+    /* Check buffers are big enough and grow if needed. */
+    if ((ret = CheckAvailableSize(ssl, sendSz)) != 0)
+        return ret;
+
+    /* Get position in output buffer to write new message to. */
+    output = ssl->buffers.outputBuffer.buffer +
+             ssl->buffers.outputBuffer.length;
+
+    /* Put the record and handshake headers on. */
+    AddTls13Headers(output, length, end_of_early_data, ssl);
+
+    /* This message is always encrypted. */
+    sendSz = BuildTls13Message(ssl, output, sendSz, output + RECORD_HEADER_SZ,
+                               idx - RECORD_HEADER_SZ, handshake, 1, 0, 0);
+    if (sendSz < 0)
+        return sendSz;
+
+    ssl->buffers.outputBuffer.length += sendSz;
+
+    if ((ret = SetKeysSide(ssl, ENCRYPT_SIDE_ONLY)) != 0)
+        return ret;
+
+    if (!ssl->options.groupMessages)
+        ret = SendBuffered(ssl);
+
+    WOLFSSL_LEAVE("SendTls13EndOfEarlyData", ret);
+    WOLFSSL_END(WC_FUNC_END_OF_EARLY_DATA_SEND);
+
+    return ret;
+}
+#endif /* !NO_WOLFSSL_CLIENT */
+
+#ifndef NO_WOLFSSL_SERVER
+/* handle processing of TLS 1.3 end_of_early_data (5) */
+/* Parse the TLS v1.3 EndOfEarlyData message that indicates that there will be
+ * no more early application data.
+ * The decryption key now changes to the pre-calculated handshake key.
+ *
+ * ssl  The SSL/TLS object.
+ * returns 0 on success and otherwise failure.
+ */
+static int DoTls13EndOfEarlyData(WOLFSSL* ssl, const byte* input,
+                                 word32* inOutIdx, word32 size)
+{
+    int    ret;
+    word32 begin = *inOutIdx;
+
+    (void)input;
+
+    WOLFSSL_START(WC_FUNC_END_OF_EARLY_DATA_DO);
+    WOLFSSL_ENTER("DoTls13EndOfEarlyData");
+
+    if ((*inOutIdx - begin) != size)
+        return BUFFER_ERROR;
+
+    if (ssl->earlyData == no_early_data) {
+        WOLFSSL_MSG("EndOfEarlyData received unexpectedly");
+        SendAlert(ssl, alert_fatal, unexpected_message);
+        return OUT_OF_ORDER_E;
+    }
+
+    ssl->earlyData = done_early_data;
+
+    /* Always encrypted. */
+    *inOutIdx += ssl->keys.padSz;
+
+    ret = SetKeysSide(ssl, DECRYPT_SIDE_ONLY);
+
+    WOLFSSL_LEAVE("DoTls13EndOfEarlyData", ret);
+    WOLFSSL_END(WC_FUNC_END_OF_EARLY_DATA_DO);
+
+    return ret;
+}
+#endif /* !NO_WOLFSSL_SERVER */
+#endif /* WOLFSSL_EARLY_DATA */
+
+#ifndef NO_WOLFSSL_CLIENT
+/* Handle a New Session Ticket handshake message.
+ * Message contains the information required to perform resumption.
+ *
+ * ssl       The SSL/TLS object.
+ * input     The message buffer.
+ * inOutIdx  On entry, the index into the message buffer of Finished.
+ *           On exit, the index of byte after the Finished message and padding.
+ * size      The length of the current handshake message.
+ * returns 0 on success, otherwise failure.
+ */
+static int DoTls13NewSessionTicket(WOLFSSL* ssl, const byte* input,
+                                   word32* inOutIdx, word32 size)
+{
+#ifdef HAVE_SESSION_TICKET
+    int    ret;
+    word32 begin = *inOutIdx;
+    word32 lifetime;
+    word32 ageAdd;
+    word16 length;
+    word32 now;
+#ifndef WOLFSSL_TLS13_DRAFT_18
+    const byte*  nonce;
+    byte         nonceLength;
+#endif
+
+    WOLFSSL_START(WC_FUNC_NEW_SESSION_TICKET_DO);
+    WOLFSSL_ENTER("DoTls13NewSessionTicket");
+
+    /* Lifetime hint. */
+    if ((*inOutIdx - begin) + SESSION_HINT_SZ > size)
+        return BUFFER_ERROR;
+    ato32(input + *inOutIdx, &lifetime);
+    *inOutIdx += SESSION_HINT_SZ;
+    if (lifetime > MAX_LIFETIME)
+        return SERVER_HINT_ERROR;
+
+    /* Age add. */
+    if ((*inOutIdx - begin) + SESSION_ADD_SZ > size)
+        return BUFFER_ERROR;
+    ato32(input + *inOutIdx, &ageAdd);
+    *inOutIdx += SESSION_ADD_SZ;
+
+#ifndef WOLFSSL_TLS13_DRAFT_18
+    /* Ticket nonce. */
+    if ((*inOutIdx - begin) + 1 > size)
+        return BUFFER_ERROR;
+    nonceLength = input[*inOutIdx];
+    if (nonceLength > MAX_TICKET_NONCE_SZ) {
+        WOLFSSL_MSG("Nonce length not supported");
+        return INVALID_PARAMETER;
+    }
+    *inOutIdx += 1;
+    if ((*inOutIdx - begin) + nonceLength > size)
+        return BUFFER_ERROR;
+    nonce = input + *inOutIdx;
+    *inOutIdx += nonceLength;
+#endif
+
+    /* Ticket length. */
+    if ((*inOutIdx - begin) + LENGTH_SZ > size)
+        return BUFFER_ERROR;
+    ato16(input + *inOutIdx, &length);
+    *inOutIdx += LENGTH_SZ;
+    if ((*inOutIdx - begin) + length > size)
+        return BUFFER_ERROR;
+
+    if ((ret = SetTicket(ssl, input + *inOutIdx, length)) != 0)
+        return ret;
+    *inOutIdx += length;
+
+    now = TimeNowInMilliseconds();
+    if (now == (word32)GETTIME_ERROR)
+        return now;
+    /* Copy in ticket data (server identity). */
+    ssl->timeout                = lifetime;
+    ssl->session.timeout        = lifetime;
+    ssl->session.cipherSuite0   = ssl->options.cipherSuite0;
+    ssl->session.cipherSuite    = ssl->options.cipherSuite;
+    ssl->session.ticketSeen     = now;
+    ssl->session.ticketAdd      = ageAdd;
+    #ifdef WOLFSSL_EARLY_DATA
+    ssl->session.maxEarlyDataSz = ssl->options.maxEarlyDataSz;
+    #endif
+#ifndef WOLFSSL_TLS13_DRAFT_18
+    ssl->session.ticketNonce.len = nonceLength;
+    if (nonceLength > 0)
+        XMEMCPY(&ssl->session.ticketNonce.data, nonce, nonceLength);
+#endif
+    ssl->session.namedGroup     = ssl->namedGroup;
+
+    if ((*inOutIdx - begin) + EXTS_SZ > size)
+        return BUFFER_ERROR;
+    ato16(input + *inOutIdx, &length);
+    *inOutIdx += EXTS_SZ;
+    if ((*inOutIdx - begin) + length != size)
+        return BUFFER_ERROR;
+    #ifdef WOLFSSL_EARLY_DATA
+    ret = TLSX_Parse(ssl, (byte *)input + (*inOutIdx), length, session_ticket,
+                     NULL);
+    if (ret != 0)
+        return ret;
+    #endif
+    *inOutIdx += length;
+
+    #ifndef NO_SESSION_CACHE
+    AddSession(ssl);
+    #endif
+
+    /* Always encrypted. */
+    *inOutIdx += ssl->keys.padSz;
+
+    ssl->expect_session_ticket = 0;
+#else
+    (void)ssl;
+    (void)input;
+
+    WOLFSSL_ENTER("DoTls13NewSessionTicket");
+
+    *inOutIdx += size + ssl->keys.padSz;
+#endif /* HAVE_SESSION_TICKET */
+
+    WOLFSSL_LEAVE("DoTls13NewSessionTicket", 0);
+    WOLFSSL_END(WC_FUNC_NEW_SESSION_TICKET_DO);
+
+    return 0;
+}
+#endif /* NO_WOLFSSL_CLIENT */
+
+#ifndef NO_WOLFSSL_SERVER
+    #ifdef HAVE_SESSION_TICKET
+
+#ifdef WOLFSSL_TLS13_TICKET_BEFORE_FINISHED
+/* Offset of the MAC size in the finished message. */
+#define FINISHED_MSG_SIZE_OFFSET    3
+
+/* Calculate the resumption secret which includes the unseen client finished
+ * message.
+ *
+ * ssl  The SSL/TLS object.
+ * returns 0 on success, otherwise failure.
+ */
+static int ExpectedResumptionSecret(WOLFSSL* ssl)
+{
+    int         ret;
+    word32      finishedSz = 0;
+    byte        mac[WC_MAX_DIGEST_SIZE];
+    Digest      digest;
+    static byte header[] = { 0x14, 0x00, 0x00, 0x00 };
+
+    /* Copy the running hash so we can restore it after. */
+    switch (ssl->specs.mac_algorithm) {
+    #ifndef NO_SHA256
+        case sha256_mac:
+            ret = wc_Sha256Copy(&ssl->hsHashes->hashSha256, &digest.sha256);
+            if (ret != 0)
+                return ret;
+            break;
+    #endif
+    #ifdef WOLFSSL_SHA384
+        case sha384_mac:
+            ret = wc_Sha384Copy(&ssl->hsHashes->hashSha384, &digest.sha384);
+            if (ret != 0)
+                return ret;
+            break;
+    #endif
+    #ifdef WOLFSSL_TLS13_SHA512
+        case sha512_mac:
+            ret = wc_Sha512Copy(&ssl->hsHashes->hashSha512, &digest.sha512);
+            if (ret != 0)
+                return ret;
+            break;
+    #endif
+    }
+
+    /* Generate the Client's Finished message and hash it. */
+    ret = BuildTls13HandshakeHmac(ssl, ssl->keys.client_write_MAC_secret, mac,
+                                  &finishedSz);
+    if (ret != 0)
+        return ret;
+    header[FINISHED_MSG_SIZE_OFFSET] = finishedSz;
+#ifdef WOLFSSL_EARLY_DATA
+    if (ssl->earlyData != no_early_data) {
+        static byte endOfEarlyData[] = { 0x05, 0x00, 0x00, 0x00 };
+        ret = HashInputRaw(ssl, endOfEarlyData, sizeof(endOfEarlyData));
+        if (ret != 0)
+            return ret;
+    }
+#endif
+    if ((ret = HashInputRaw(ssl, header, sizeof(header))) != 0)
+        return ret;
+    if ((ret = HashInputRaw(ssl, mac, finishedSz)) != 0)
+        return ret;
+
+    if ((ret = DeriveResumptionSecret(ssl, ssl->session.masterSecret)) != 0)
+        return ret;
+
+    /* Restore the hash inline with currently seen messages. */
+    switch (ssl->specs.mac_algorithm) {
+    #ifndef NO_SHA256
+        case sha256_mac:
+            ret = wc_Sha256Copy(&digest.sha256, &ssl->hsHashes->hashSha256);
+            if (ret != 0)
+                return ret;
+            break;
+    #endif
+    #ifdef WOLFSSL_SHA384
+        case sha384_mac:
+            ret = wc_Sha384Copy(&digest.sha384, &ssl->hsHashes->hashSha384);
+            if (ret != 0)
+                return ret;
+            break;
+    #endif
+    #ifdef WOLFSSL_TLS13_SHA512
+        case sha512_mac:
+            ret = wc_Sha512Copy(&digest.sha512, &ssl->hsHashes->hashSha384);
+            if (ret != 0)
+                return ret;
+            break;
+    #endif
+    }
+
+    return ret;
+}
+#endif
+
+/* Send New Session Ticket handshake message.
+ * Message contains the information required to perform resumption.
+ *
+ * ssl  The SSL/TLS object.
+ * returns 0 on success, otherwise failure.
+ */
+static int SendTls13NewSessionTicket(WOLFSSL* ssl)
+{
+    byte*  output;
+    int    ret;
+    int    sendSz;
+    word16 extSz;
+    word32 length;
+    word32 idx = RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ;
+
+    WOLFSSL_START(WC_FUNC_NEW_SESSION_TICKET_SEND);
+    WOLFSSL_ENTER("SendTls13NewSessionTicket");
+
+#ifdef WOLFSSL_TLS13_TICKET_BEFORE_FINISHED
+    if (!ssl->msgsReceived.got_finished) {
+        if ((ret = ExpectedResumptionSecret(ssl)) != 0)
+            return ret;
+    }
+#endif
+
+#ifndef WOLFSSL_TLS13_DRAFT_18
+    /* Start ticket nonce at 0 and go up to 255. */
+    if (ssl->session.ticketNonce.len == 0) {
+        ssl->session.ticketNonce.len = DEF_TICKET_NONCE_SZ;
+        ssl->session.ticketNonce.data[0] = 0;
+    }
+    else
+        ssl->session.ticketNonce.data[0]++;
+#endif
+
+    if (!ssl->options.noTicketTls13) {
+        if ((ret = CreateTicket(ssl)) != 0)
+            return ret;
+    }
+
+#ifdef WOLFSSL_EARLY_DATA
+    ssl->session.maxEarlyDataSz = ssl->options.maxEarlyDataSz;
+    if (ssl->session.maxEarlyDataSz > 0)
+        TLSX_EarlyData_Use(ssl, ssl->session.maxEarlyDataSz);
+    extSz = 0;
+    ret = TLSX_GetResponseSize(ssl, session_ticket, &extSz);
+    if (ret != 0)
+        return ret;
+#else
+    extSz = EXTS_SZ;
+#endif
+
+    /* Lifetime | Age Add | Ticket | Extensions */
+    length = SESSION_HINT_SZ + SESSION_ADD_SZ + LENGTH_SZ +
+             ssl->session.ticketLen + extSz;
+#ifndef WOLFSSL_TLS13_DRAFT_18
+    /* Nonce */
+    length += TICKET_NONCE_LEN_SZ + DEF_TICKET_NONCE_SZ;
+#endif
+    sendSz = idx + length + MAX_MSG_EXTRA;
+
+    /* Check buffers are big enough and grow if needed. */
+    if ((ret = CheckAvailableSize(ssl, sendSz)) != 0)
+        return ret;
+
+    /* Get position in output buffer to write new message to. */
+    output = ssl->buffers.outputBuffer.buffer +
+             ssl->buffers.outputBuffer.length;
+
+    /* Put the record and handshake headers on. */
+    AddTls13Headers(output, length, session_ticket, ssl);
+
+    /* Lifetime hint */
+    c32toa(ssl->ctx->ticketHint, output + idx);
+    idx += SESSION_HINT_SZ;
+    /* Age add - obfuscator */
+    c32toa(ssl->session.ticketAdd, output + idx);
+    idx += SESSION_ADD_SZ;
+
+#ifndef WOLFSSL_TLS13_DRAFT_18
+    output[idx++] = ssl->session.ticketNonce.len;
+    output[idx++] = ssl->session.ticketNonce.data[0];
+#endif
+
+    /* length */
+    c16toa(ssl->session.ticketLen, output + idx);
+    idx += LENGTH_SZ;
+    /* ticket */
+    XMEMCPY(output + idx, ssl->session.ticket, ssl->session.ticketLen);
+    idx += ssl->session.ticketLen;
+
+#ifdef WOLFSSL_EARLY_DATA
+    extSz = 0;
+    ret = TLSX_WriteResponse(ssl, output + idx, session_ticket, &extSz);
+    if (ret != 0)
+        return ret;
+    idx += extSz;
+#else
+    /* No extension support - empty extensions. */
+    c16toa(0, output + idx);
+    idx += EXTS_SZ;
+#endif
+
+    ssl->options.haveSessionId = 1;
+
+#ifndef NO_SESSION_CACHE
+    AddSession(ssl);
+#endif
+
+    /* This message is always encrypted. */
+    sendSz = BuildTls13Message(ssl, output, sendSz, output + RECORD_HEADER_SZ,
+                               idx - RECORD_HEADER_SZ, handshake, 0, 0, 0);
+    if (sendSz < 0)
+        return sendSz;
+
+    ssl->buffers.outputBuffer.length += sendSz;
+
+    if (!ssl->options.groupMessages)
+        ret = SendBuffered(ssl);
+
+    WOLFSSL_LEAVE("SendTls13NewSessionTicket", 0);
+    WOLFSSL_END(WC_FUNC_NEW_SESSION_TICKET_SEND);
+
+    return ret;
+}
+    #endif /* HAVE_SESSION_TICKET */
+#endif /* NO_WOLFSSL_SERVER */
+
+/* Make sure no duplicates, no fast forward, or other problems
+ *
+ * ssl   The SSL/TLS object.
+ * type  Type of handshake message received.
+ * returns 0 on success, otherwise failure.
+ */
+static int SanityCheckTls13MsgReceived(WOLFSSL* ssl, byte type)
+{
+    /* verify not a duplicate, mark received, check state */
+    switch (type) {
+
+#ifndef NO_WOLFSSL_SERVER
+        case client_hello:
+        #ifndef NO_WOLFSSL_CLIENT
+            if (ssl->options.side == WOLFSSL_CLIENT_END) {
+                WOLFSSL_MSG("ClientHello received by client");
+                return OUT_OF_ORDER_E;
+            }
+        #endif
+            if (ssl->options.clientState >= CLIENT_HELLO_COMPLETE) {
+                WOLFSSL_MSG("ClientHello received out of order");
+                return OUT_OF_ORDER_E;
+            }
+            if (ssl->msgsReceived.got_client_hello == 2) {
+                WOLFSSL_MSG("Too many ClientHello received");
+                return DUPLICATE_MSG_E;
+            }
+            ssl->msgsReceived.got_client_hello++;
+
+            break;
+#endif
+
+#ifndef NO_WOLFSSL_CLIENT
+        case server_hello:
+        #ifndef NO_WOLFSSL_SERVER
+            if (ssl->options.side == WOLFSSL_SERVER_END) {
+                WOLFSSL_MSG("ServerHello received by server");
+                return OUT_OF_ORDER_E;
+            }
+        #endif
+        #ifdef WOLFSSL_TLS13_DRAFT_18
+            if (ssl->msgsReceived.got_server_hello) {
+                WOLFSSL_MSG("Duplicate ServerHello received");
+                return DUPLICATE_MSG_E;
+            }
+            ssl->msgsReceived.got_server_hello = 1;
+        #else
+            if (ssl->msgsReceived.got_server_hello == 2) {
+                WOLFSSL_MSG("Duplicate ServerHello received");
+                return DUPLICATE_MSG_E;
+            }
+            ssl->msgsReceived.got_server_hello++;
+        #endif
+
+            break;
+#endif
+
+#ifndef NO_WOLFSSL_CLIENT
+        case session_ticket:
+        #ifndef NO_WOLFSSL_SERVER
+            if (ssl->options.side == WOLFSSL_SERVER_END) {
+                WOLFSSL_MSG("NewSessionTicket received by server");
+                return OUT_OF_ORDER_E;
+            }
+        #endif
+            if (ssl->options.clientState < CLIENT_FINISHED_COMPLETE) {
+                WOLFSSL_MSG("NewSessionTicket received out of order");
+                return OUT_OF_ORDER_E;
+            }
+            ssl->msgsReceived.got_session_ticket = 1;
+
+            break;
+#endif
+
+#ifndef NO_WOLFSSL_SERVER
+    #ifdef WOLFSSL_EARLY_DATA
+        case end_of_early_data:
+        #ifndef NO_WOLFSSL_CLIENT
+            if (ssl->options.side == WOLFSSL_CLIENT_END) {
+                WOLFSSL_MSG("EndOfEarlyData received by client");
+                return OUT_OF_ORDER_E;
+            }
+        #endif
+            if (ssl->options.serverState < SERVER_FINISHED_COMPLETE) {
+                WOLFSSL_MSG("EndOfEarlyData received out of order");
+                return OUT_OF_ORDER_E;
+            }
+            if (ssl->options.clientState >= CLIENT_FINISHED_COMPLETE) {
+                WOLFSSL_MSG("EndOfEarlyData received out of order");
+                return OUT_OF_ORDER_E;
+            }
+            if (ssl->msgsReceived.got_end_of_early_data == 1) {
+                WOLFSSL_MSG("Too many EndOfEarlyData received");
+                return DUPLICATE_MSG_E;
+            }
+            ssl->msgsReceived.got_end_of_early_data++;
+
+            break;
+    #endif
+#endif
+
+#ifdef WOLFSSL_TLS13_DRAFT_18
+    #ifndef NO_WOLFSSL_CLIENT
+        case hello_retry_request:
+        #ifndef NO_WOLFSSL_SERVER
+            if (ssl->options.side == WOLFSSL_SERVER_END) {
+                WOLFSSL_MSG("HelloRetryRequest received by server");
+                return OUT_OF_ORDER_E;
+            }
+        #endif
+            if (ssl->options.clientState > CLIENT_FINISHED_COMPLETE) {
+                WOLFSSL_MSG("HelloRetryRequest received out of order");
+                return OUT_OF_ORDER_E;
+            }
+            if (ssl->msgsReceived.got_hello_retry_request) {
+                WOLFSSL_MSG("Duplicate HelloRetryRequest received");
+                return DUPLICATE_MSG_E;
+            }
+            ssl->msgsReceived.got_hello_retry_request = 1;
+
+            break;
+    #endif
+#endif
+
+#ifndef NO_WOLFSSL_CLIENT
+        case encrypted_extensions:
+        #ifndef NO_WOLFSSL_SERVER
+            if (ssl->options.side == WOLFSSL_SERVER_END) {
+                WOLFSSL_MSG("EncryptedExtensions received by server");
+                return OUT_OF_ORDER_E;
+            }
+        #endif
+            if (ssl->options.serverState != SERVER_HELLO_COMPLETE) {
+                WOLFSSL_MSG("EncryptedExtensions received out of order");
+                return OUT_OF_ORDER_E;
+            }
+            if (ssl->msgsReceived.got_encrypted_extensions) {
+                WOLFSSL_MSG("Duplicate EncryptedExtensions received");
+                return DUPLICATE_MSG_E;
+            }
+            ssl->msgsReceived.got_encrypted_extensions = 1;
+
+            break;
+#endif
+
+        case certificate:
+    #ifndef NO_WOLFSSL_CLIENT
+            if (ssl->options.side == WOLFSSL_CLIENT_END &&
+                ssl->options.serverState !=
+                                         SERVER_ENCRYPTED_EXTENSIONS_COMPLETE) {
+                WOLFSSL_MSG("Certificate received out of order - Client");
+                return OUT_OF_ORDER_E;
+            }
+        #if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
+            /* Server's authenticating with PSK must not send this. */
+            if (ssl->options.side == WOLFSSL_CLIENT_END &&
+                             ssl->options.serverState == SERVER_CERT_COMPLETE &&
+                             ssl->arrays->psk_keySz != 0) {
+                WOLFSSL_MSG("Certificate received while using PSK");
+                return SANITY_MSG_E;
+            }
+        #endif
+    #endif
+    #ifndef NO_WOLFSSL_SERVER
+            if (ssl->options.side == WOLFSSL_SERVER_END &&
+                ssl->options.serverState < SERVER_FINISHED_COMPLETE) {
+                WOLFSSL_MSG("Certificate received out of order - Server");
+                return OUT_OF_ORDER_E;
+            }
+    #endif
+            if (ssl->msgsReceived.got_certificate) {
+                WOLFSSL_MSG("Duplicate Certificate received");
+                return DUPLICATE_MSG_E;
+            }
+            ssl->msgsReceived.got_certificate = 1;
+
+            break;
+
+#ifndef NO_WOLFSSL_CLIENT
+        case certificate_request:
+        #ifndef NO_WOLFSSL_SERVER
+            if (ssl->options.side == WOLFSSL_SERVER_END) {
+                WOLFSSL_MSG("CertificateRequest received by server");
+                return OUT_OF_ORDER_E;
+            }
+        #endif
+        #ifndef WOLFSSL_POST_HANDSHAKE_AUTH
+            if (ssl->options.serverState !=
+                                         SERVER_ENCRYPTED_EXTENSIONS_COMPLETE) {
+                WOLFSSL_MSG("CertificateRequest received out of order");
+                return OUT_OF_ORDER_E;
+            }
+        #else
+            if (ssl->options.serverState !=
+                                         SERVER_ENCRYPTED_EXTENSIONS_COMPLETE &&
+                       (ssl->options.serverState != SERVER_FINISHED_COMPLETE ||
+                        ssl->options.clientState != CLIENT_FINISHED_COMPLETE)) {
+                WOLFSSL_MSG("CertificateRequest received out of order");
+                return OUT_OF_ORDER_E;
+            }
+        #endif
+        #if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
+            /* Server's authenticating with PSK must not send this. */
+            if (ssl->options.serverState ==
+                                         SERVER_ENCRYPTED_EXTENSIONS_COMPLETE &&
+                                                  ssl->arrays->psk_keySz != 0) {
+                WOLFSSL_MSG("CertificateRequset received while using PSK");
+                return SANITY_MSG_E;
+            }
+        #endif
+        #ifndef WOLFSSL_POST_HANDSHAKE_AUTH
+            if (ssl->msgsReceived.got_certificate_request) {
+                WOLFSSL_MSG("Duplicate CertificateRequest received");
+                return DUPLICATE_MSG_E;
+            }
+        #endif
+            ssl->msgsReceived.got_certificate_request = 1;
+
+            break;
+#endif
+
+        case certificate_verify:
+    #ifndef NO_WOLFSSL_CLIENT
+            if (ssl->options.side == WOLFSSL_CLIENT_END) {
+                if (ssl->options.serverState != SERVER_CERT_COMPLETE) {
+                    WOLFSSL_MSG("No Cert before CertVerify");
+                    return OUT_OF_ORDER_E;
+                }
+            #if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
+                /* Server's authenticating with PSK must not send this. */
+                if (ssl->options.serverState == SERVER_CERT_COMPLETE &&
+                                                  ssl->arrays->psk_keySz != 0) {
+                    WOLFSSL_MSG("CertificateVerify received while using PSK");
+                    return SANITY_MSG_E;
+                }
+            #endif
+            }
+    #endif
+    #ifndef NO_WOLFSSL_SERVER
+            if (ssl->options.side == WOLFSSL_SERVER_END) {
+                if (ssl->options.serverState < SERVER_FINISHED_COMPLETE) {
+                    WOLFSSL_MSG("CertificateVerify received out of order");
+                    return OUT_OF_ORDER_E;
+                }
+                if (ssl->options.clientState < CLIENT_HELLO_COMPLETE) {
+                    WOLFSSL_MSG("CertificateVerify before ClientHello done");
+                    return OUT_OF_ORDER_E;
+                }
+                if (!ssl->msgsReceived.got_certificate) {
+                    WOLFSSL_MSG("No Cert before CertificateVerify");
+                    return OUT_OF_ORDER_E;
+                }
+            }
+    #endif
+            if (ssl->msgsReceived.got_certificate_verify) {
+                WOLFSSL_MSG("Duplicate CertificateVerify received");
+                return DUPLICATE_MSG_E;
+            }
+            ssl->msgsReceived.got_certificate_verify = 1;
+
+            break;
+
+        case finished:
+        #ifndef NO_WOLFSSL_CLIENT
+            if (ssl->options.side == WOLFSSL_CLIENT_END) {
+                if (ssl->options.clientState < CLIENT_HELLO_COMPLETE) {
+                    WOLFSSL_MSG("Finished received out of order");
+                    return OUT_OF_ORDER_E;
+                }
+                if (ssl->options.serverState <
+                                         SERVER_ENCRYPTED_EXTENSIONS_COMPLETE) {
+                    WOLFSSL_MSG("Finished received out of order");
+                    return OUT_OF_ORDER_E;
+                }
+            }
+        #endif
+        #ifndef NO_WOLFSSL_SERVER
+            if (ssl->options.side == WOLFSSL_SERVER_END) {
+                if (ssl->options.serverState < SERVER_FINISHED_COMPLETE) {
+                    WOLFSSL_MSG("Finished received out of order");
+                    return OUT_OF_ORDER_E;
+                }
+                if (ssl->options.clientState < CLIENT_HELLO_COMPLETE) {
+                    WOLFSSL_MSG("Finished received out of order");
+                    return OUT_OF_ORDER_E;
+                }
+            #ifdef WOLFSSL_EARLY_DATA
+                if (ssl->earlyData == process_early_data) {
+                    return OUT_OF_ORDER_E;
+                }
+            #endif
+            }
+        #endif
+            if (ssl->msgsReceived.got_finished) {
+                WOLFSSL_MSG("Duplicate Finished received");
+                return DUPLICATE_MSG_E;
+            }
+            ssl->msgsReceived.got_finished = 1;
+
+            break;
+
+        case key_update:
+            if (!ssl->msgsReceived.got_finished) {
+                WOLFSSL_MSG("No KeyUpdate before Finished");
+                return OUT_OF_ORDER_E;
+            }
+            break;
+
+        default:
+            WOLFSSL_MSG("Unknown message type");
+            return SANITY_MSG_E;
+    }
+
+    return 0;
+}
+
+/* Handle a type of handshake message that has been received.
+ *
+ * ssl       The SSL/TLS object.
+ * input     The message buffer.
+ * inOutIdx  On entry, the index into the buffer of the current message.
+ *           On exit, the index into the buffer of the next message.
+ * size      The length of the current handshake message.
+ * totalSz   Length of remaining data in the message buffer.
+ * returns 0 on success and otherwise failure.
+ */
+int DoTls13HandShakeMsgType(WOLFSSL* ssl, byte* input, word32* inOutIdx,
+                            byte type, word32 size, word32 totalSz)
+{
+    int ret = 0;
+    word32 inIdx = *inOutIdx;
+
+    (void)totalSz;
+
+    WOLFSSL_ENTER("DoTls13HandShakeMsgType");
+
+    /* make sure we can read the message */
+    if (*inOutIdx + size > totalSz)
+        return INCOMPLETE_DATA;
+
+    /* sanity check msg received */
+    if ((ret = SanityCheckTls13MsgReceived(ssl, type)) != 0) {
+        WOLFSSL_MSG("Sanity Check on handshake message type received failed");
+        SendAlert(ssl, alert_fatal, unexpected_message);
+        return ret;
+    }
+
+#ifdef WOLFSSL_CALLBACKS
+    /* add name later, add on record and handshake header part back on */
+    if (ssl->toInfoOn) {
+        int add = RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ;
+        AddPacketInfo(ssl, 0, handshake, input + *inOutIdx - add,
+                      size + add, READ_PROTO, ssl->heap);
+        AddLateRecordHeader(&ssl->curRL, &ssl->timeoutInfo);
+    }
+#endif
+
+    if (ssl->options.handShakeState == HANDSHAKE_DONE &&
+            type != session_ticket && type != certificate_request &&
+            type != certificate && type != key_update) {
+        WOLFSSL_MSG("HandShake message after handshake complete");
+        SendAlert(ssl, alert_fatal, unexpected_message);
+        return OUT_OF_ORDER_E;
+    }
+
+    if (ssl->options.side == WOLFSSL_CLIENT_END &&
+               ssl->options.serverState == NULL_STATE &&
+               type != server_hello && type != hello_retry_request) {
+        WOLFSSL_MSG("First server message not server hello");
+        SendAlert(ssl, alert_fatal, unexpected_message);
+        return OUT_OF_ORDER_E;
+    }
+
+    if (ssl->options.side == WOLFSSL_SERVER_END &&
+               ssl->options.clientState == NULL_STATE && type != client_hello) {
+        WOLFSSL_MSG("First client message not client hello");
+        SendAlert(ssl, alert_fatal, unexpected_message);
+        return OUT_OF_ORDER_E;
+    }
+
+    /* above checks handshake state */
+    switch (type) {
+#ifndef NO_WOLFSSL_CLIENT
+    /* Messages only received by client. */
+    #ifdef WOLFSSL_TLS13_DRAFT_18
+    case hello_retry_request:
+        WOLFSSL_MSG("processing hello retry request");
+        ret = DoTls13HelloRetryRequest(ssl, input, inOutIdx, size);
+        break;
+    #endif
+
+    case server_hello:
+        WOLFSSL_MSG("processing server hello");
+        ret = DoTls13ServerHello(ssl, input, inOutIdx, size, &type);
+    #if !defined(WOLFSSL_NO_CLIENT_AUTH) && \
+               ((defined(HAVE_ED25519) && !defined(NO_ED25519_CLIENT_AUTH)) || \
+                (defined(HAVE_ED448) && !defined(NO_ED448_CLIENT_AUTH)))
+        if (ssl->options.resuming || !IsAtLeastTLSv1_2(ssl) ||
+                                               IsAtLeastTLSv1_3(ssl->version)) {
+            ssl->options.cacheMessages = 0;
+            if (ssl->hsHashes->messages != NULL) {
+                XFREE(ssl->hsHashes->messages, ssl->heap, DYNAMIC_TYPE_HASHES);
+                ssl->hsHashes->messages = NULL;
+            }
+        }
+    #endif
+        break;
+
+    case encrypted_extensions:
+        WOLFSSL_MSG("processing encrypted extensions");
+        ret = DoTls13EncryptedExtensions(ssl, input, inOutIdx, size);
+        break;
+
+    #ifndef NO_CERTS
+    case certificate_request:
+        WOLFSSL_MSG("processing certificate request");
+        ret = DoTls13CertificateRequest(ssl, input, inOutIdx, size);
+        break;
+    #endif
+
+    case session_ticket:
+        WOLFSSL_MSG("processing new session ticket");
+        ret = DoTls13NewSessionTicket(ssl, input, inOutIdx, size);
+        break;
+#endif /* !NO_WOLFSSL_CLIENT */
+
+#ifndef NO_WOLFSSL_SERVER
+    /* Messages only received by server. */
+    case client_hello:
+        WOLFSSL_MSG("processing client hello");
+        ret = DoTls13ClientHello(ssl, input, inOutIdx, size);
+        break;
+
+    #ifdef WOLFSSL_EARLY_DATA
+    case end_of_early_data:
+        WOLFSSL_MSG("processing end of early data");
+        ret = DoTls13EndOfEarlyData(ssl, input, inOutIdx, size);
+        break;
+    #endif
+#endif /* !NO_WOLFSSL_SERVER */
+
+    /* Messages received by both client and server. */
+#ifndef NO_CERTS
+    case certificate:
+        WOLFSSL_MSG("processing certificate");
+        ret = DoTls13Certificate(ssl, input, inOutIdx, size);
+        break;
+#endif
+
+#if !defined(NO_RSA) || defined(HAVE_ECC) || defined(HAVE_ED25519) || \
+                                                             defined(HAVE_ED448)
+    case certificate_verify:
+        WOLFSSL_MSG("processing certificate verify");
+        ret = DoTls13CertificateVerify(ssl, input, inOutIdx, size);
+        break;
+#endif /* !NO_RSA || HAVE_ECC */
+
+    case finished:
+        WOLFSSL_MSG("processing finished");
+        ret = DoTls13Finished(ssl, input, inOutIdx, size, totalSz, NO_SNIFF);
+        break;
+
+    case key_update:
+        WOLFSSL_MSG("processing finished");
+        ret = DoTls13KeyUpdate(ssl, input, inOutIdx, size);
+        break;
+
+    default:
+        WOLFSSL_MSG("Unknown handshake message type");
+        ret = UNKNOWN_HANDSHAKE_TYPE;
+        break;
+    }
+
+    /* reset error */
+    if (ret == 0 && ssl->error == WC_PENDING_E)
+        ssl->error = 0;
+
+    if (ret == 0 && type != client_hello && type != session_ticket &&
+                                                           type != key_update) {
+        ret = HashInput(ssl, input + inIdx, size);
+    }
+    if (ret == 0 && ssl->buffers.inputBuffer.dynamicFlag) {
+        ShrinkInputBuffer(ssl, NO_FORCED_FREE);
+    }
+
+    if (ret == BUFFER_ERROR || ret == MISSING_HANDSHAKE_DATA)
+        SendAlert(ssl, alert_fatal, decode_error);
+    else if (ret == EXT_NOT_ALLOWED || ret == PEER_KEY_ERROR ||
+                        ret == ECC_PEERKEY_ERROR || ret == BAD_KEY_SHARE_DATA ||
+                        ret == PSK_KEY_ERROR || ret == INVALID_PARAMETER) {
+        SendAlert(ssl, alert_fatal, illegal_parameter);
+    }
+
+    if (ret == 0 && ssl->options.tls1_3) {
+        /* Need to hash input message before deriving secrets. */
+    #ifndef NO_WOLFSSL_CLIENT
+        if (ssl->options.side == WOLFSSL_CLIENT_END) {
+            if (type == server_hello) {
+                if ((ret = DeriveEarlySecret(ssl)) != 0)
+                    return ret;
+                if ((ret = DeriveHandshakeSecret(ssl)) != 0)
+                    return ret;
+
+                if ((ret = DeriveTls13Keys(ssl, handshake_key,
+                                           ENCRYPT_AND_DECRYPT_SIDE, 1)) != 0) {
+                    return ret;
+                }
+        #ifdef WOLFSSL_EARLY_DATA
+                if ((ret = SetKeysSide(ssl, DECRYPT_SIDE_ONLY)) != 0)
+                    return ret;
+        #else
+                if ((ret = SetKeysSide(ssl, ENCRYPT_AND_DECRYPT_SIDE)) != 0)
+                    return ret;
+        #endif
+            }
+
+            if (type == finished) {
+                if ((ret = DeriveMasterSecret(ssl)) != 0)
+                    return ret;
+        #ifdef WOLFSSL_EARLY_DATA
+                if ((ret = DeriveTls13Keys(ssl, traffic_key,
+                                       ENCRYPT_AND_DECRYPT_SIDE,
+                                       ssl->earlyData == no_early_data)) != 0) {
+                    return ret;
+                }
+        #else
+                if ((ret = DeriveTls13Keys(ssl, traffic_key,
+                                           ENCRYPT_AND_DECRYPT_SIDE, 1)) != 0) {
+                    return ret;
+                }
+        #endif
+            }
+        #ifdef WOLFSSL_POST_HANDSHAKE_AUTH
+            if (type == certificate_request &&
+                                ssl->options.handShakeState == HANDSHAKE_DONE) {
+                /* reset handshake states */
+                ssl->options.clientState = CLIENT_HELLO_COMPLETE;
+                ssl->options.connectState  = FIRST_REPLY_DONE;
+                ssl->options.handShakeState = CLIENT_HELLO_COMPLETE;
+
+                if (wolfSSL_connect_TLSv13(ssl) != SSL_SUCCESS)
+                    ret = POST_HAND_AUTH_ERROR;
+            }
+        #endif
+        }
+    #endif /* NO_WOLFSSL_CLIENT */
+
+#ifndef NO_WOLFSSL_SERVER
+    #if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
+        if (ssl->options.side == WOLFSSL_SERVER_END && type == finished) {
+            ret = DeriveResumptionSecret(ssl, ssl->session.masterSecret);
+            if (ret != 0)
+                return ret;
+        }
+    #endif
+#endif /* NO_WOLFSSL_SERVER */
+    }
+
+#ifdef WOLFSSL_ASYNC_CRYPT
+    /* if async, offset index so this msg will be processed again */
+    if (ret == WC_PENDING_E && *inOutIdx > 0) {
+        *inOutIdx -= HANDSHAKE_HEADER_SZ;
+    }
+#endif
+
+    WOLFSSL_LEAVE("DoTls13HandShakeMsgType()", ret);
+    return ret;
+}
+
+
+/* Handle a handshake message that has been received.
+ *
+ * ssl       The SSL/TLS object.
+ * input     The message buffer.
+ * inOutIdx  On entry, the index into the buffer of the current message.
+ *           On exit, the index into the buffer of the next message.
+ * totalSz   Length of remaining data in the message buffer.
+ * returns 0 on success and otherwise failure.
+ */
+int DoTls13HandShakeMsg(WOLFSSL* ssl, byte* input, word32* inOutIdx,
+                        word32 totalSz)
+{
+    int    ret = 0;
+    word32 inputLength;
+
+    WOLFSSL_ENTER("DoTls13HandShakeMsg()");
+
+    if (ssl->arrays == NULL) {
+        byte   type;
+        word32 size;
+
+        if (GetHandshakeHeader(ssl, input, inOutIdx, &type, &size,
+                                                                totalSz) != 0) {
+            SendAlert(ssl, alert_fatal, unexpected_message);
+            return PARSE_ERROR;
+        }
+
+        return DoTls13HandShakeMsgType(ssl, input, inOutIdx, type, size,
+                                       totalSz);
+    }
+
+    inputLength = ssl->buffers.inputBuffer.length - *inOutIdx - ssl->keys.padSz;
+
+    /* If there is a pending fragmented handshake message,
+     * pending message size will be non-zero. */
+    if (ssl->arrays->pendingMsgSz == 0) {
+        byte   type;
+        word32 size;
+
+        if (GetHandshakeHeader(ssl,input, inOutIdx, &type, &size, totalSz) != 0)
+            return PARSE_ERROR;
+
+        /* Cap the maximum size of a handshake message to something reasonable.
+         * By default is the maximum size of a certificate message assuming
+         * nine 2048-bit RSA certificates in the chain. */
+        if (size > MAX_HANDSHAKE_SZ) {
+            WOLFSSL_MSG("Handshake message too large");
+            return HANDSHAKE_SIZE_ERROR;
+        }
+
+        /* size is the size of the certificate message payload */
+        if (inputLength - HANDSHAKE_HEADER_SZ < size) {
+            ssl->arrays->pendingMsgType = type;
+            ssl->arrays->pendingMsgSz = size + HANDSHAKE_HEADER_SZ;
+            ssl->arrays->pendingMsg = (byte*)XMALLOC(size + HANDSHAKE_HEADER_SZ,
+                                                     ssl->heap,
+                                                     DYNAMIC_TYPE_ARRAYS);
+            if (ssl->arrays->pendingMsg == NULL)
+                return MEMORY_E;
+            XMEMCPY(ssl->arrays->pendingMsg,
+                    input + *inOutIdx - HANDSHAKE_HEADER_SZ,
+                    inputLength);
+            ssl->arrays->pendingMsgOffset = inputLength;
+            *inOutIdx += inputLength + ssl->keys.padSz - HANDSHAKE_HEADER_SZ;
+            return 0;
+        }
+
+        ret = DoTls13HandShakeMsgType(ssl, input, inOutIdx, type, size,
+                                      totalSz);
+    }
+    else {
+        if (inputLength + ssl->arrays->pendingMsgOffset >
+                                                    ssl->arrays->pendingMsgSz) {
+            inputLength = ssl->arrays->pendingMsgSz -
+                                                  ssl->arrays->pendingMsgOffset;
+        }
+        XMEMCPY(ssl->arrays->pendingMsg + ssl->arrays->pendingMsgOffset,
+                input + *inOutIdx, inputLength);
+        ssl->arrays->pendingMsgOffset += inputLength;
+        *inOutIdx += inputLength + ssl->keys.padSz;
+
+        if (ssl->arrays->pendingMsgOffset == ssl->arrays->pendingMsgSz)
+        {
+            word32 idx = 0;
+            ret = DoTls13HandShakeMsgType(ssl,
+                                ssl->arrays->pendingMsg + HANDSHAKE_HEADER_SZ,
+                                &idx, ssl->arrays->pendingMsgType,
+                                ssl->arrays->pendingMsgSz - HANDSHAKE_HEADER_SZ,
+                                ssl->arrays->pendingMsgSz);
+        #ifdef WOLFSSL_ASYNC_CRYPT
+            if (ret == WC_PENDING_E) {
+                /* setup to process fragment again */
+                ssl->arrays->pendingMsgOffset -= inputLength;
+                *inOutIdx -= inputLength + ssl->keys.padSz;
+            }
+            else
+        #endif
+            {
+                XFREE(ssl->arrays->pendingMsg, ssl->heap, DYNAMIC_TYPE_ARRAYS);
+                ssl->arrays->pendingMsg = NULL;
+                ssl->arrays->pendingMsgSz = 0;
+            }
+        }
+    }
+
+    WOLFSSL_LEAVE("DoTls13HandShakeMsg()", ret);
+    return ret;
+}
+
+#ifndef NO_WOLFSSL_CLIENT
+
+/* The client connecting to the server.
+ * The protocol version is expecting to be TLS v1.3.
+ * If the server downgrades, and older versions of the protocol are compiled
+ * in, the client will fallback to wolfSSL_connect().
+ * Please see note at top of README if you get an error from connect.
+ *
+ * ssl  The SSL/TLS object.
+ * returns WOLFSSL_SUCCESS on successful handshake, WOLFSSL_FATAL_ERROR when
+ * unrecoverable error occurs and 0 otherwise.
+ * For more error information use wolfSSL_get_error().
+ */
+int wolfSSL_connect_TLSv13(WOLFSSL* ssl)
+{
+    WOLFSSL_ENTER("wolfSSL_connect_TLSv13()");
+
+    #ifdef HAVE_ERRNO_H
+    errno = 0;
+    #endif
+
+    if (ssl->options.side != WOLFSSL_CLIENT_END) {
+        WOLFSSL_ERROR(ssl->error = SIDE_ERROR);
+        return WOLFSSL_FATAL_ERROR;
+    }
+
+    if (ssl->buffers.outputBuffer.length > 0
+    #ifdef WOLFSSL_ASYNC_CRYPT
+        /* do not send buffered or advance state if last error was an 
+            async pending operation */
+        && ssl->error != WC_PENDING_E
+    #endif
+    ) {
+        if ((ssl->error = SendBuffered(ssl)) == 0) {
+            /* fragOffset is non-zero when sending fragments. On the last
+             * fragment, fragOffset is zero again, and the state can be
+             * advanced. */
+            if (ssl->fragOffset == 0) {
+                ssl->options.connectState++;
+                WOLFSSL_MSG("connect state: "
+                            "Advanced from last buffered fragment send");
+            }
+            else {
+                WOLFSSL_MSG("connect state: "
+                            "Not advanced, more fragments to send");
+            }
+        }
+        else {
+            WOLFSSL_ERROR(ssl->error);
+            return WOLFSSL_FATAL_ERROR;
+        }
+    }
+
+    switch (ssl->options.connectState) {
+
+        case CONNECT_BEGIN:
+            /* Always send client hello first. */
+            if ((ssl->error = SendTls13ClientHello(ssl)) != 0) {
+                WOLFSSL_ERROR(ssl->error);
+                return WOLFSSL_FATAL_ERROR;
+            }
+
+            ssl->options.connectState = CLIENT_HELLO_SENT;
+            WOLFSSL_MSG("connect state: CLIENT_HELLO_SENT");
+    #ifdef WOLFSSL_EARLY_DATA
+            if (ssl->earlyData != no_early_data) {
+        #if !defined(WOLFSSL_TLS13_DRAFT_18) && \
+                                         defined(WOLFSSL_TLS13_MIDDLEBOX_COMPAT)
+                if ((ssl->error = SendChangeCipher(ssl)) != 0) {
+                    WOLFSSL_ERROR(ssl->error);
+                    return WOLFSSL_FATAL_ERROR;
+                }
+                ssl->options.sentChangeCipher = 1;
+        #endif
+                ssl->options.handShakeState = CLIENT_HELLO_COMPLETE;
+                return WOLFSSL_SUCCESS;
+            }
+    #endif
+            FALL_THROUGH;
+
+        case CLIENT_HELLO_SENT:
+            /* Get the response/s from the server. */
+            while (ssl->options.serverState <
+                                          SERVER_HELLO_RETRY_REQUEST_COMPLETE) {
+                if ((ssl->error = ProcessReply(ssl)) < 0) {
+                    WOLFSSL_ERROR(ssl->error);
+                    return WOLFSSL_FATAL_ERROR;
+                }
+            }
+
+            ssl->options.connectState = HELLO_AGAIN;
+            WOLFSSL_MSG("connect state: HELLO_AGAIN");
+            FALL_THROUGH;
+
+        case HELLO_AGAIN:
+            if (ssl->options.certOnly)
+                return WOLFSSL_SUCCESS;
+
+            if (!ssl->options.tls1_3) {
+    #ifndef WOLFSSL_NO_TLS12
+                if (ssl->options.downgrade)
+                    return wolfSSL_connect(ssl);
+    #endif
+
+                WOLFSSL_MSG("Client using higher version, fatal error");
+                return VERSION_ERROR;
+            }
+
+            if (ssl->options.serverState ==
+                                          SERVER_HELLO_RETRY_REQUEST_COMPLETE) {
+        #if !defined(WOLFSSL_TLS13_DRAFT_18) && \
+                                         defined(WOLFSSL_TLS13_MIDDLEBOX_COMPAT)
+                if (!ssl->options.sentChangeCipher) {
+                    if ((ssl->error = SendChangeCipher(ssl)) != 0) {
+                        WOLFSSL_ERROR(ssl->error);
+                        return WOLFSSL_FATAL_ERROR;
+                    }
+                    ssl->options.sentChangeCipher = 1;
+                }
+        #endif
+                /* Try again with different security parameters. */
+                if ((ssl->error = SendTls13ClientHello(ssl)) != 0) {
+                    WOLFSSL_ERROR(ssl->error);
+                    return WOLFSSL_FATAL_ERROR;
+                }
+            }
+
+            ssl->options.connectState = HELLO_AGAIN_REPLY;
+            WOLFSSL_MSG("connect state: HELLO_AGAIN_REPLY");
+            FALL_THROUGH;
+
+        case HELLO_AGAIN_REPLY:
+            /* Get the response/s from the server. */
+            while (ssl->options.serverState < SERVER_FINISHED_COMPLETE) {
+                if ((ssl->error = ProcessReply(ssl)) < 0) {
+                    WOLFSSL_ERROR(ssl->error);
+                    return WOLFSSL_FATAL_ERROR;
+                }
+            }
+
+            ssl->options.connectState = FIRST_REPLY_DONE;
+            WOLFSSL_MSG("connect state: FIRST_REPLY_DONE");
+            FALL_THROUGH;
+
+        case FIRST_REPLY_DONE:
+        #ifdef WOLFSSL_EARLY_DATA
+            if (ssl->earlyData != no_early_data) {
+                if ((ssl->error = SendTls13EndOfEarlyData(ssl)) != 0) {
+                    WOLFSSL_ERROR(ssl->error);
+                    return WOLFSSL_FATAL_ERROR;
+                }
+                WOLFSSL_MSG("sent: end_of_early_data");
+            }
+        #endif
+
+            ssl->options.connectState = FIRST_REPLY_FIRST;
+            WOLFSSL_MSG("connect state: FIRST_REPLY_FIRST");
+            FALL_THROUGH;
+
+        case FIRST_REPLY_FIRST:
+        #if !defined(WOLFSSL_TLS13_DRAFT_18) && \
+                                         defined(WOLFSSL_TLS13_MIDDLEBOX_COMPAT)
+            if (!ssl->options.sentChangeCipher) {
+                if ((ssl->error = SendChangeCipher(ssl)) != 0) {
+                    WOLFSSL_ERROR(ssl->error);
+                    return WOLFSSL_FATAL_ERROR;
+                }
+                ssl->options.sentChangeCipher = 1;
+            }
+        #endif
+
+            ssl->options.connectState = FIRST_REPLY_SECOND;
+            WOLFSSL_MSG("connect state: FIRST_REPLY_SECOND");
+            FALL_THROUGH;
+
+        case FIRST_REPLY_SECOND:
+        #ifndef NO_CERTS
+            if (!ssl->options.resuming && ssl->options.sendVerify) {
+                ssl->error = SendTls13Certificate(ssl);
+                if (ssl->error != 0) {
+                    WOLFSSL_ERROR(ssl->error);
+                    return WOLFSSL_FATAL_ERROR;
+                }
+                WOLFSSL_MSG("sent: certificate");
+            }
+        #endif
+
+            ssl->options.connectState = FIRST_REPLY_THIRD;
+            WOLFSSL_MSG("connect state: FIRST_REPLY_THIRD");
+            FALL_THROUGH;
+
+        case FIRST_REPLY_THIRD:
+        #ifndef NO_CERTS
+            if (!ssl->options.resuming && ssl->options.sendVerify) {
+                ssl->error = SendTls13CertificateVerify(ssl);
+                if (ssl->error != 0) {
+                    WOLFSSL_ERROR(ssl->error);
+                    return WOLFSSL_FATAL_ERROR;
+                }
+                WOLFSSL_MSG("sent: certificate verify");
+            }
+        #endif
+
+            ssl->options.connectState = FIRST_REPLY_FOURTH;
+            WOLFSSL_MSG("connect state: FIRST_REPLY_FOURTH");
+            FALL_THROUGH;
+
+        case FIRST_REPLY_FOURTH:
+            if ((ssl->error = SendTls13Finished(ssl)) != 0) {
+                WOLFSSL_ERROR(ssl->error);
+                return WOLFSSL_FATAL_ERROR;
+            }
+            WOLFSSL_MSG("sent: finished");
+
+            ssl->options.connectState = FINISHED_DONE;
+            WOLFSSL_MSG("connect state: FINISHED_DONE");
+            FALL_THROUGH;
+
+        case FINISHED_DONE:
+        #ifndef NO_HANDSHAKE_DONE_CB
+            if (ssl->hsDoneCb != NULL) {
+                int cbret = ssl->hsDoneCb(ssl, ssl->hsDoneCtx);
+                if (cbret < 0) {
+                    ssl->error = cbret;
+                    WOLFSSL_MSG("HandShake Done Cb don't continue error");
+                    return WOLFSSL_FATAL_ERROR;
+                }
+            }
+        #endif /* NO_HANDSHAKE_DONE_CB */
+
+            if (!ssl->options.keepResources) {
+                FreeHandshakeResources(ssl);
+            }
+
+            WOLFSSL_LEAVE("wolfSSL_connect_TLSv13()", WOLFSSL_SUCCESS);
+            return WOLFSSL_SUCCESS;
+
+        default:
+            WOLFSSL_MSG("Unknown connect state ERROR");
+            return WOLFSSL_FATAL_ERROR; /* unknown connect state */
+    }
+}
+#endif
+
+#if defined(WOLFSSL_SEND_HRR_COOKIE)
+/* Send a cookie with the HelloRetryRequest to avoid storing state.
+ *
+ * ssl       SSL/TLS object.
+ * secret    Secret to use when generating integrity check for cookie.
+ *           A value of NULL indicates to generate a new random secret.
+ * secretSz  Size of secret data in bytes.
+ *           Use a value of 0 to indicate use of default size.
+ * returns BAD_FUNC_ARG when ssl is NULL or not using TLS v1.3, SIDE_ERROR when
+ * called on a client; WOLFSSL_SUCCESS on success and otherwise failure.
+ */
+int wolfSSL_send_hrr_cookie(WOLFSSL* ssl, const unsigned char* secret,
+                            unsigned int secretSz)
+{
+    int ret;
+
+    if (ssl == NULL || !IsAtLeastTLSv1_3(ssl->version))
+        return BAD_FUNC_ARG;
+ #ifndef NO_WOLFSSL_SERVER
+    if (ssl->options.side == WOLFSSL_CLIENT_END)
+        return SIDE_ERROR;
+
+    if (secretSz == 0) {
+    #if !defined(NO_SHA) && defined(NO_SHA256)
+        secretSz = WC_SHA_DIGEST_SIZE;
+    #endif /* NO_SHA */
+    #ifndef NO_SHA256
+        secretSz = WC_SHA256_DIGEST_SIZE;
+    #endif /* NO_SHA256 */
+    }
+
+    if (secretSz != ssl->buffers.tls13CookieSecret.length) {
+        byte* newSecret;
+
+        if (ssl->buffers.tls13CookieSecret.buffer != NULL) {
+            ForceZero(ssl->buffers.tls13CookieSecret.buffer,
+                      ssl->buffers.tls13CookieSecret.length);
+            XFREE(ssl->buffers.tls13CookieSecret.buffer,
+                  ssl->heap, DYNAMIC_TYPE_COOKIE_PWD);
+        }
+
+        newSecret = (byte*)XMALLOC(secretSz, ssl->heap,
+                                   DYNAMIC_TYPE_COOKIE_PWD);
+        if (newSecret == NULL) {
+            ssl->buffers.tls13CookieSecret.buffer = NULL;
+            ssl->buffers.tls13CookieSecret.length = 0;
+            WOLFSSL_MSG("couldn't allocate new cookie secret");
+            return MEMORY_ERROR;
+        }
+        ssl->buffers.tls13CookieSecret.buffer = newSecret;
+        ssl->buffers.tls13CookieSecret.length = secretSz;
+    }
+
+    /* If the supplied secret is NULL, randomly generate a new secret. */
+    if (secret == NULL) {
+        ret = wc_RNG_GenerateBlock(ssl->rng,
+                               ssl->buffers.tls13CookieSecret.buffer, secretSz);
+        if (ret < 0)
+            return ret;
+    }
+    else
+        XMEMCPY(ssl->buffers.tls13CookieSecret.buffer, secret, secretSz);
+
+    ssl->options.sendCookie = 1;
+
+    ret = WOLFSSL_SUCCESS;
+#else
+    (void)secret;
+    (void)secretSz;
+
+    ret = SIDE_ERROR;
+#endif
+
+    return ret;
+}
+#endif
+
+/* Create a key share entry from group.
+ * Generates a key pair.
+ *
+ * ssl    The SSL/TLS object.
+ * group  The named group.
+ * returns 0 on success, otherwise failure.
+ */
+int wolfSSL_UseKeyShare(WOLFSSL* ssl, word16 group)
+{
+    int ret;
+
+    if (ssl == NULL)
+        return BAD_FUNC_ARG;
+
+    ret = TLSX_KeyShare_Use(ssl, group, 0, NULL, NULL);
+    if (ret != 0)
+        return ret;
+
+    return WOLFSSL_SUCCESS;
+}
+
+/* Send no key share entries - use HelloRetryRequest to negotiate shared group.
+ *
+ * ssl    The SSL/TLS object.
+ * returns 0 on success, otherwise failure.
+ */
+int wolfSSL_NoKeyShares(WOLFSSL* ssl)
+{
+    int ret;
+
+    if (ssl == NULL)
+        return BAD_FUNC_ARG;
+    if (ssl->options.side == WOLFSSL_SERVER_END)
+        return SIDE_ERROR;
+
+    ret = TLSX_KeyShare_Empty(ssl);
+    if (ret != 0)
+        return ret;
+
+    return WOLFSSL_SUCCESS;
+}
+
+/* Do not send a ticket after TLS v1.3 handshake for resumption.
+ *
+ * ctx  The SSL/TLS CTX object.
+ * returns BAD_FUNC_ARG when ctx is NULL and 0 on success.
+ */
+int wolfSSL_CTX_no_ticket_TLSv13(WOLFSSL_CTX* ctx)
+{
+    if (ctx == NULL || !IsAtLeastTLSv1_3(ctx->method->version))
+        return BAD_FUNC_ARG;
+    if (ctx->method->side == WOLFSSL_CLIENT_END)
+        return SIDE_ERROR;
+
+#ifdef HAVE_SESSION_TICKET
+    ctx->noTicketTls13 = 1;
+#endif
+
+    return 0;
+}
+
+/* Do not send a ticket after TLS v1.3 handshake for resumption.
+ *
+ * ssl  The SSL/TLS object.
+ * returns BAD_FUNC_ARG when ssl is NULL, not using TLS v1.3, or called on
+ * a client and 0 on success.
+ */
+int wolfSSL_no_ticket_TLSv13(WOLFSSL* ssl)
+{
+    if (ssl == NULL || !IsAtLeastTLSv1_3(ssl->version))
+        return BAD_FUNC_ARG;
+    if (ssl->options.side == WOLFSSL_CLIENT_END)
+        return SIDE_ERROR;
+
+#ifdef HAVE_SESSION_TICKET
+    ssl->options.noTicketTls13 = 1;
+#endif
+
+    return 0;
+}
+
+/* Disallow (EC)DHE key exchange when using pre-shared keys.
+ *
+ * ctx  The SSL/TLS CTX object.
+ * returns BAD_FUNC_ARG when ctx is NULL and 0 on success.
+ */
+int wolfSSL_CTX_no_dhe_psk(WOLFSSL_CTX* ctx)
+{
+    if (ctx == NULL || !IsAtLeastTLSv1_3(ctx->method->version))
+        return BAD_FUNC_ARG;
+
+    ctx->noPskDheKe = 1;
+
+    return 0;
+}
+
+/* Disallow (EC)DHE key exchange when using pre-shared keys.
+ *
+ * ssl  The SSL/TLS object.
+ * returns BAD_FUNC_ARG when ssl is NULL, or not using TLS v1.3 and 0 on
+ * success.
+ */
+int wolfSSL_no_dhe_psk(WOLFSSL* ssl)
+{
+    if (ssl == NULL || !IsAtLeastTLSv1_3(ssl->version))
+        return BAD_FUNC_ARG;
+
+    ssl->options.noPskDheKe = 1;
+
+    return 0;
+}
+
+/* Update the keys for encryption and decryption.
+ * If using non-blocking I/O and WOLFSSL_ERROR_WANT_WRITE is returned then
+ * calling wolfSSL_write() will have the message sent when ready.
+ *
+ * ssl  The SSL/TLS object.
+ * returns BAD_FUNC_ARG when ssl is NULL, or not using TLS v1.3,
+ * WOLFSSL_ERROR_WANT_WRITE when non-blocking I/O is not ready to write,
+ * WOLFSSL_SUCCESS on success and otherwise failure.
+ */
+int wolfSSL_update_keys(WOLFSSL* ssl)
+{
+    int ret;
+
+    if (ssl == NULL || !IsAtLeastTLSv1_3(ssl->version))
+        return BAD_FUNC_ARG;
+
+    ret = SendTls13KeyUpdate(ssl);
+    if (ret == WANT_WRITE)
+        ret = WOLFSSL_ERROR_WANT_WRITE;
+    else if (ret == 0)
+        ret = WOLFSSL_SUCCESS;
+    return ret;
+}
+
+#if !defined(NO_CERTS) && defined(WOLFSSL_POST_HANDSHAKE_AUTH)
+/* Allow post-handshake authentication in TLS v1.3 connections.
+ *
+ * ctx  The SSL/TLS CTX object.
+ * returns BAD_FUNC_ARG when ctx is NULL, SIDE_ERROR when not a client and
+ * 0 on success.
+ */
+int wolfSSL_CTX_allow_post_handshake_auth(WOLFSSL_CTX* ctx)
+{
+    if (ctx == NULL || !IsAtLeastTLSv1_3(ctx->method->version))
+        return BAD_FUNC_ARG;
+    if (ctx->method->side == WOLFSSL_SERVER_END)
+        return SIDE_ERROR;
+
+    ctx->postHandshakeAuth = 1;
+
+    return 0;
+}
+
+/* Allow post-handshake authentication in TLS v1.3 connection.
+ *
+ * ssl  The SSL/TLS object.
+ * returns BAD_FUNC_ARG when ssl is NULL, or not using TLS v1.3,
+ * SIDE_ERROR when not a client and 0 on success.
+ */
+int wolfSSL_allow_post_handshake_auth(WOLFSSL* ssl)
+{
+    if (ssl == NULL || !IsAtLeastTLSv1_3(ssl->version))
+        return BAD_FUNC_ARG;
+    if (ssl->options.side == WOLFSSL_SERVER_END)
+        return SIDE_ERROR;
+
+    ssl->options.postHandshakeAuth = 1;
+
+    return 0;
+}
+
+/* Request a certificate of the client.
+ * Can be called any time after handshake completion.
+ * A maximum of 256 requests can be sent on a connection.
+ *
+ * ssl  SSL/TLS object.
+ */
+int wolfSSL_request_certificate(WOLFSSL* ssl)
+{
+    int         ret;
+#ifndef NO_WOLFSSL_SERVER
+    CertReqCtx* certReqCtx;
+#endif
+
+    if (ssl == NULL || !IsAtLeastTLSv1_3(ssl->version))
+        return BAD_FUNC_ARG;
+#ifndef NO_WOLFSSL_SERVER
+    if (ssl->options.side == WOLFSSL_CLIENT_END)
+        return SIDE_ERROR;
+    if (ssl->options.handShakeState != HANDSHAKE_DONE)
+        return NOT_READY_ERROR;
+    if (!ssl->options.postHandshakeAuth)
+        return POST_HAND_AUTH_ERROR;
+
+    certReqCtx = (CertReqCtx*)XMALLOC(sizeof(CertReqCtx), ssl->heap,
+                                                       DYNAMIC_TYPE_TMP_BUFFER);
+    if (certReqCtx == NULL)
+        return MEMORY_E;
+    XMEMSET(certReqCtx, 0, sizeof(CertReqCtx));
+    certReqCtx->next = ssl->certReqCtx;
+    certReqCtx->len = 1;
+    if (certReqCtx->next != NULL)
+        certReqCtx->ctx = certReqCtx->next->ctx + 1;
+    ssl->certReqCtx = certReqCtx;
+
+    ssl->msgsReceived.got_certificate = 0;
+    ssl->msgsReceived.got_certificate_verify = 0;
+    ssl->msgsReceived.got_finished = 0;
+
+    ret = SendTls13CertificateRequest(ssl, &certReqCtx->ctx, certReqCtx->len);
+    if (ret == WANT_WRITE)
+        ret = WOLFSSL_ERROR_WANT_WRITE;
+    else if (ret == 0)
+        ret = WOLFSSL_SUCCESS;
+#else
+    ret = SIDE_ERROR;
+#endif
+
+    return ret;
+}
+#endif /* !NO_CERTS && WOLFSSL_POST_HANDSHAKE_AUTH */
+
+#if !defined(WOLFSSL_NO_SERVER_GROUPS_EXT)
+/* Get the preferred key exchange group.
+ *
+ * ssl  The SSL/TLS object.
+ * returns BAD_FUNC_ARG when ssl is NULL or not using TLS v1.3,
+ * SIDE_ERROR when not a client, NOT_READY_ERROR when handshake not complete
+ * and group number on success.
+ */
+int wolfSSL_preferred_group(WOLFSSL* ssl)
+{
+    if (ssl == NULL || !IsAtLeastTLSv1_3(ssl->version))
+        return BAD_FUNC_ARG;
+#ifndef NO_WOLFSSL_CLIENT
+    if (ssl->options.side == WOLFSSL_SERVER_END)
+        return SIDE_ERROR;
+    if (ssl->options.handShakeState != HANDSHAKE_DONE)
+        return NOT_READY_ERROR;
+
+    /* Return supported groups only. */
+    return TLSX_SupportedCurve_Preferred(ssl, 1);
+#else
+    return SIDE_ERROR;
+#endif
+}
+#endif
+
+/* Sets the key exchange groups in rank order on a context.
+ *
+ * ctx     SSL/TLS context object.
+ * groups  Array of groups.
+ * count   Number of groups in array.
+ * returns BAD_FUNC_ARG when ctx or groups is NULL, not using TLS v1.3 or
+ * count is greater than WOLFSSL_MAX_GROUP_COUNT and WOLFSSL_SUCCESS on success.
+ */
+int wolfSSL_CTX_set_groups(WOLFSSL_CTX* ctx, int* groups, int count)
+{
+    int i;
+
+    if (ctx == NULL || groups == NULL || count > WOLFSSL_MAX_GROUP_COUNT)
+        return BAD_FUNC_ARG;
+    if (!IsAtLeastTLSv1_3(ctx->method->version))
+        return BAD_FUNC_ARG;
+
+    for (i = 0; i < count; i++)
+        ctx->group[i] = (word16)groups[i];
+    ctx->numGroups = (byte)count;
+
+    return WOLFSSL_SUCCESS;
+}
+
+/* Sets the key exchange groups in rank order.
+ *
+ * ssl     SSL/TLS object.
+ * groups  Array of groups.
+ * count   Number of groups in array.
+ * returns BAD_FUNC_ARG when ssl or groups is NULL, not using TLS v1.3 or
+ * count is greater than WOLFSSL_MAX_GROUP_COUNT and WOLFSSL_SUCCESS on success.
+ */
+int wolfSSL_set_groups(WOLFSSL* ssl, int* groups, int count)
+{
+    int i;
+
+    if (ssl == NULL || groups == NULL || count > WOLFSSL_MAX_GROUP_COUNT)
+        return BAD_FUNC_ARG;
+    if (!IsAtLeastTLSv1_3(ssl->version))
+        return BAD_FUNC_ARG;
+
+    for (i = 0; i < count; i++)
+        ssl->group[i] = (word16)groups[i];
+    ssl->numGroups = (byte)count;
+
+    return WOLFSSL_SUCCESS;
+}
+
+#ifndef NO_PSK
+void wolfSSL_CTX_set_psk_client_tls13_callback(WOLFSSL_CTX* ctx,
+                                               wc_psk_client_tls13_callback cb)
+{
+    WOLFSSL_ENTER("SSL_CTX_set_psk_client_tls13_callback");
+
+    if (ctx == NULL)
+        return;
+
+    ctx->havePSK = 1;
+    ctx->client_psk_tls13_cb = cb;
+}
+
+
+void wolfSSL_set_psk_client_tls13_callback(WOLFSSL* ssl,
+                                           wc_psk_client_tls13_callback cb)
+{
+    byte haveRSA = 1;
+    int  keySz   = 0;
+
+    WOLFSSL_ENTER("SSL_set_psk_client_tls13_callback");
+
+    if (ssl == NULL)
+        return;
+
+    ssl->options.havePSK = 1;
+    ssl->options.client_psk_tls13_cb = cb;
+
+    #ifdef NO_RSA
+        haveRSA = 0;
+    #endif
+    #ifndef NO_CERTS
+        keySz = ssl->buffers.keySz;
+    #endif
+    InitSuites(ssl->suites, ssl->version, keySz, haveRSA, TRUE,
+               ssl->options.haveDH, ssl->options.haveNTRU,
+               ssl->options.haveECDSAsig, ssl->options.haveECC,
+               ssl->options.haveStaticECC, ssl->options.side);
+}
+
+
+void wolfSSL_CTX_set_psk_server_tls13_callback(WOLFSSL_CTX* ctx,
+                                               wc_psk_server_tls13_callback cb)
+{
+    WOLFSSL_ENTER("SSL_CTX_set_psk_server_tls13_callback");
+    if (ctx == NULL)
+        return;
+    ctx->havePSK = 1;
+    ctx->server_psk_tls13_cb = cb;
+}
+
+
+void wolfSSL_set_psk_server_tls13_callback(WOLFSSL* ssl,
+                                           wc_psk_server_tls13_callback cb)
+{
+    byte haveRSA = 1;
+    int  keySz   = 0;
+
+    WOLFSSL_ENTER("SSL_set_psk_server_tls13_callback");
+    if (ssl == NULL)
+        return;
+
+    ssl->options.havePSK = 1;
+    ssl->options.server_psk_tls13_cb = cb;
+
+    #ifdef NO_RSA
+        haveRSA = 0;
+    #endif
+    #ifndef NO_CERTS
+        keySz = ssl->buffers.keySz;
+    #endif
+    InitSuites(ssl->suites, ssl->version, keySz, haveRSA, TRUE,
+               ssl->options.haveDH, ssl->options.haveNTRU,
+               ssl->options.haveECDSAsig, ssl->options.haveECC,
+               ssl->options.haveStaticECC, ssl->options.side);
+}
+#endif
+
+
+#ifndef NO_WOLFSSL_SERVER
+/* The server accepting a connection from a client.
+ * The protocol version is expecting to be TLS v1.3.
+ * If the client downgrades, and older versions of the protocol are compiled
+ * in, the server will fallback to wolfSSL_accept().
+ * Please see note at top of README if you get an error from accept.
+ *
+ * ssl  The SSL/TLS object.
+ * returns WOLFSSL_SUCCESS on successful handshake, WOLFSSL_FATAL_ERROR when
+ * unrecoverable error occurs and 0 otherwise.
+ * For more error information use wolfSSL_get_error().
+ */
+int wolfSSL_accept_TLSv13(WOLFSSL* ssl)
+{
+    word16 havePSK = 0;
+    WOLFSSL_ENTER("SSL_accept_TLSv13()");
+
+#ifdef HAVE_ERRNO_H
+    errno = 0;
+#endif
+
+#if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
+    havePSK = ssl->options.havePSK;
+#endif
+    (void)havePSK;
+
+    if (ssl->options.side != WOLFSSL_SERVER_END) {
+        WOLFSSL_ERROR(ssl->error = SIDE_ERROR);
+        return WOLFSSL_FATAL_ERROR;
+    }
+
+#ifndef NO_CERTS
+    /* allow no private key if using PK callbacks and CB is set */
+    if (!havePSK) {
+        if (!ssl->buffers.certificate ||
+            !ssl->buffers.certificate->buffer) {
+
+            WOLFSSL_MSG("accept error: server cert required");
+            WOLFSSL_ERROR(ssl->error = NO_PRIVATE_KEY);
+            return WOLFSSL_FATAL_ERROR;
+        }
+
+    #ifdef HAVE_PK_CALLBACKS
+        if (wolfSSL_CTX_IsPrivatePkSet(ssl->ctx)) {
+            WOLFSSL_MSG("Using PK for server private key");
+        }
+        else
+    #endif
+        if (!ssl->buffers.key || !ssl->buffers.key->buffer) {
+            WOLFSSL_MSG("accept error: server key required");
+            WOLFSSL_ERROR(ssl->error = NO_PRIVATE_KEY);
+            return WOLFSSL_FATAL_ERROR;
+        }
+    }
+#endif
+
+    if (ssl->buffers.outputBuffer.length > 0
+    #ifdef WOLFSSL_ASYNC_CRYPT
+        /* do not send buffered or advance state if last error was an 
+            async pending operation */
+        && ssl->error != WC_PENDING_E
+    #endif
+    ) {
+        if ((ssl->error = SendBuffered(ssl)) == 0) {
+            /* fragOffset is non-zero when sending fragments. On the last
+             * fragment, fragOffset is zero again, and the state can be
+             * advanced. */
+            if (ssl->fragOffset == 0) {
+                ssl->options.acceptState++;
+                WOLFSSL_MSG("accept state: "
+                            "Advanced from last buffered fragment send");
+            }
+            else {
+                WOLFSSL_MSG("accept state: "
+                            "Not advanced, more fragments to send");
+            }
+        }
+        else {
+            WOLFSSL_ERROR(ssl->error);
+            return WOLFSSL_FATAL_ERROR;
+        }
+    }
+
+    switch (ssl->options.acceptState) {
+
+#ifdef HAVE_SECURE_RENEGOTIATION
+        case TLS13_ACCEPT_BEGIN_RENEG:
+#endif
+        case TLS13_ACCEPT_BEGIN :
+            /* get client_hello */
+            while (ssl->options.clientState < CLIENT_HELLO_COMPLETE) {
+                if ((ssl->error = ProcessReply(ssl)) < 0) {
+                    WOLFSSL_ERROR(ssl->error);
+                    return WOLFSSL_FATAL_ERROR;
+                }
+            }
+
+            ssl->options.acceptState = TLS13_ACCEPT_CLIENT_HELLO_DONE;
+            WOLFSSL_MSG("accept state ACCEPT_CLIENT_HELLO_DONE");
+            if (!IsAtLeastTLSv1_3(ssl->version))
+                return wolfSSL_accept(ssl);
+            FALL_THROUGH;
+
+        case TLS13_ACCEPT_CLIENT_HELLO_DONE :
+#ifdef WOLFSSL_TLS13_DRAFT_18
+            if (ssl->options.serverState ==
+                                          SERVER_HELLO_RETRY_REQUEST_COMPLETE) {
+                if ((ssl->error = SendTls13HelloRetryRequest(ssl)) != 0) {
+                    WOLFSSL_ERROR(ssl->error);
+                    return WOLFSSL_FATAL_ERROR;
+                }
+            }
+
+            ssl->options.acceptState = TLS13_ACCEPT_FIRST_REPLY_DONE;
+            WOLFSSL_MSG("accept state ACCEPT_FIRST_REPLY_DONE");
+            FALL_THROUGH;
+
+        case TLS13_ACCEPT_HELLO_RETRY_REQUEST_DONE :
+#else
+            if (ssl->options.serverState ==
+                                          SERVER_HELLO_RETRY_REQUEST_COMPLETE) {
+                if ((ssl->error = SendTls13ServerHello(ssl,
+                                                   hello_retry_request)) != 0) {
+                    WOLFSSL_ERROR(ssl->error);
+                    return WOLFSSL_FATAL_ERROR;
+                }
+            }
+
+            ssl->options.acceptState = TLS13_ACCEPT_HELLO_RETRY_REQUEST_DONE;
+            WOLFSSL_MSG("accept state ACCEPT_HELLO_RETRY_REQUEST_DONE");
+            FALL_THROUGH;
+
+        case TLS13_ACCEPT_HELLO_RETRY_REQUEST_DONE :
+    #ifdef WOLFSSL_TLS13_MIDDLEBOX_COMPAT
+            if (ssl->options.serverState ==
+                                          SERVER_HELLO_RETRY_REQUEST_COMPLETE) {
+                if ((ssl->error = SendChangeCipher(ssl)) != 0) {
+                    WOLFSSL_ERROR(ssl->error);
+                    return WOLFSSL_FATAL_ERROR;
+                }
+                ssl->options.sentChangeCipher = 1;
+                ssl->options.serverState = SERVER_HELLO_RETRY_REQUEST_COMPLETE;
+            }
+    #endif
+            ssl->options.acceptState = TLS13_ACCEPT_FIRST_REPLY_DONE;
+            WOLFSSL_MSG("accept state ACCEPT_FIRST_REPLY_DONE");
+            FALL_THROUGH;
+#endif
+
+        case TLS13_ACCEPT_FIRST_REPLY_DONE :
+            if (ssl->options.serverState ==
+                                          SERVER_HELLO_RETRY_REQUEST_COMPLETE) {
+                ssl->options.clientState = CLIENT_HELLO_RETRY;
+                while (ssl->options.clientState < CLIENT_HELLO_COMPLETE) {
+                    if ((ssl->error = ProcessReply(ssl)) < 0) {
+                        WOLFSSL_ERROR(ssl->error);
+                        return WOLFSSL_FATAL_ERROR;
+                    }
+                }
+            }
+
+            ssl->options.acceptState = TLS13_ACCEPT_SECOND_REPLY_DONE;
+            WOLFSSL_MSG("accept state ACCEPT_SECOND_REPLY_DONE");
+            FALL_THROUGH;
+
+        case TLS13_ACCEPT_SECOND_REPLY_DONE :
+            if ((ssl->error = SendTls13ServerHello(ssl, server_hello)) != 0) {
+                WOLFSSL_ERROR(ssl->error);
+                return WOLFSSL_FATAL_ERROR;
+            }
+            ssl->options.acceptState = TLS13_SERVER_HELLO_SENT;
+            WOLFSSL_MSG("accept state SERVER_HELLO_SENT");
+            FALL_THROUGH;
+
+        case TLS13_SERVER_HELLO_SENT :
+    #if !defined(WOLFSSL_TLS13_DRAFT_18) && \
+                                         defined(WOLFSSL_TLS13_MIDDLEBOX_COMPAT)
+            if (!ssl->options.sentChangeCipher) {
+                if ((ssl->error = SendChangeCipher(ssl)) != 0) {
+                    WOLFSSL_ERROR(ssl->error);
+                    return WOLFSSL_FATAL_ERROR;
+                }
+                ssl->options.sentChangeCipher = 1;
+            }
+    #endif
+
+            ssl->options.acceptState = TLS13_ACCEPT_THIRD_REPLY_DONE;
+            WOLFSSL_MSG("accept state ACCEPT_THIRD_REPLY_DONE");
+            FALL_THROUGH;
+
+        case TLS13_ACCEPT_THIRD_REPLY_DONE :
+            if (!ssl->options.noPskDheKe) {
+                ssl->error = TLSX_KeyShare_DeriveSecret(ssl);
+                if (ssl->error != 0)
+                    return WOLFSSL_FATAL_ERROR;
+            }
+
+            if ((ssl->error = SendTls13EncryptedExtensions(ssl)) != 0) {
+                WOLFSSL_ERROR(ssl->error);
+                return WOLFSSL_FATAL_ERROR;
+            }
+            ssl->options.acceptState = TLS13_SERVER_EXTENSIONS_SENT;
+            WOLFSSL_MSG("accept state SERVER_EXTENSIONS_SENT");
+            FALL_THROUGH;
+
+        case TLS13_SERVER_EXTENSIONS_SENT :
+#ifndef NO_CERTS
+            if (!ssl->options.resuming) {
+                if (ssl->options.verifyPeer) {
+                    ssl->error = SendTls13CertificateRequest(ssl, NULL, 0);
+                    if (ssl->error != 0) {
+                        WOLFSSL_ERROR(ssl->error);
+                        return WOLFSSL_FATAL_ERROR;
+                    }
+                }
+            }
+#endif
+            ssl->options.acceptState = TLS13_CERT_REQ_SENT;
+            WOLFSSL_MSG("accept state CERT_REQ_SENT");
+            FALL_THROUGH;
+
+        case TLS13_CERT_REQ_SENT :
+#ifndef NO_CERTS
+            if (!ssl->options.resuming && ssl->options.sendVerify) {
+                if ((ssl->error = SendTls13Certificate(ssl)) != 0) {
+                    WOLFSSL_ERROR(ssl->error);
+                    return WOLFSSL_FATAL_ERROR;
+                }
+            }
+#endif
+            ssl->options.acceptState = TLS13_CERT_SENT;
+            WOLFSSL_MSG("accept state CERT_SENT");
+            FALL_THROUGH;
+
+        case TLS13_CERT_SENT :
+#ifndef NO_CERTS
+            if (!ssl->options.resuming && ssl->options.sendVerify) {
+                if ((ssl->error = SendTls13CertificateVerify(ssl)) != 0) {
+                    WOLFSSL_ERROR(ssl->error);
+                    return WOLFSSL_FATAL_ERROR;
+                }
+            }
+#endif
+            ssl->options.acceptState = TLS13_CERT_VERIFY_SENT;
+            WOLFSSL_MSG("accept state CERT_VERIFY_SENT");
+            FALL_THROUGH;
+
+        case TLS13_CERT_VERIFY_SENT :
+            if ((ssl->error = SendTls13Finished(ssl)) != 0) {
+                WOLFSSL_ERROR(ssl->error);
+                return WOLFSSL_FATAL_ERROR;
+            }
+
+            ssl->options.acceptState = TLS13_ACCEPT_FINISHED_SENT;
+            WOLFSSL_MSG("accept state ACCEPT_FINISHED_SENT");
+#ifdef WOLFSSL_EARLY_DATA
+            if (ssl->earlyData != no_early_data) {
+                ssl->options.handShakeState = SERVER_FINISHED_COMPLETE;
+                return WOLFSSL_SUCCESS;
+            }
+#endif
+            FALL_THROUGH;
+
+        case TLS13_ACCEPT_FINISHED_SENT :
+#ifdef HAVE_SESSION_TICKET
+    #ifdef WOLFSSL_TLS13_TICKET_BEFORE_FINISHED
+            if (!ssl->options.verifyPeer && !ssl->options.noTicketTls13 &&
+                                                ssl->ctx->ticketEncCb != NULL) {
+                if ((ssl->error = SendTls13NewSessionTicket(ssl)) != 0) {
+                    WOLFSSL_ERROR(ssl->error);
+                    return WOLFSSL_FATAL_ERROR;
+                }
+            }
+    #endif
+#endif /* HAVE_SESSION_TICKET */
+            ssl->options.acceptState = TLS13_PRE_TICKET_SENT;
+            WOLFSSL_MSG("accept state  TICKET_SENT");
+            FALL_THROUGH;
+
+        case TLS13_PRE_TICKET_SENT :
+            while (ssl->options.clientState < CLIENT_FINISHED_COMPLETE)
+                if ( (ssl->error = ProcessReply(ssl)) < 0) {
+                    WOLFSSL_ERROR(ssl->error);
+                    return WOLFSSL_FATAL_ERROR;
+                }
+
+            ssl->options.acceptState = TLS13_ACCEPT_FINISHED_DONE;
+            WOLFSSL_MSG("accept state ACCEPT_FINISHED_DONE");
+            FALL_THROUGH;
+
+        case TLS13_ACCEPT_FINISHED_DONE :
+#ifdef HAVE_SESSION_TICKET
+    #ifdef WOLFSSL_TLS13_TICKET_BEFORE_FINISHED
+            if (!ssl->options.verifyPeer) {
+            }
+            else
+    #endif
+            if (!ssl->options.noTicketTls13 && ssl->ctx->ticketEncCb != NULL) {
+                if ((ssl->error = SendTls13NewSessionTicket(ssl)) != 0) {
+                    WOLFSSL_ERROR(ssl->error);
+                    return WOLFSSL_FATAL_ERROR;
+                }
+            }
+#endif /* HAVE_SESSION_TICKET */
+            ssl->options.acceptState = TLS13_TICKET_SENT;
+            WOLFSSL_MSG("accept state TICKET_SENT");
+            FALL_THROUGH;
+
+        case TLS13_TICKET_SENT :
+#ifndef NO_HANDSHAKE_DONE_CB
+            if (ssl->hsDoneCb) {
+                int cbret = ssl->hsDoneCb(ssl, ssl->hsDoneCtx);
+                if (cbret < 0) {
+                    ssl->error = cbret;
+                    WOLFSSL_MSG("HandShake Done Cb don't continue error");
+                    return WOLFSSL_FATAL_ERROR;
+                }
+            }
+#endif /* NO_HANDSHAKE_DONE_CB */
+
+            if (!ssl->options.keepResources) {
+                FreeHandshakeResources(ssl);
+            }
+
+            WOLFSSL_LEAVE("SSL_accept()", WOLFSSL_SUCCESS);
+            return WOLFSSL_SUCCESS;
+
+        default :
+            WOLFSSL_MSG("Unknown accept state ERROR");
+            return WOLFSSL_FATAL_ERROR;
+    }
+}
+#endif
+
+#ifdef WOLFSSL_EARLY_DATA
+/* Sets the maximum amount of early data that can be seen by server when using
+ * session tickets for resumption.
+ * A value of zero indicates no early data is to be sent by client using session
+ * tickets.
+ *
+ * ctx  The SSL/TLS CTX object.
+ * sz   Maximum size of the early data.
+ * returns BAD_FUNC_ARG when ctx is NULL, SIDE_ERROR when not a server and
+ * 0 on success.
+ */
+int wolfSSL_CTX_set_max_early_data(WOLFSSL_CTX* ctx, unsigned int sz)
+{
+    if (ctx == NULL || !IsAtLeastTLSv1_3(ctx->method->version))
+        return BAD_FUNC_ARG;
+    if (ctx->method->side == WOLFSSL_CLIENT_END)
+        return SIDE_ERROR;
+
+    ctx->maxEarlyDataSz = sz;
+
+    return 0;
+}
+
+/* Sets the maximum amount of early data that can be seen by server when using
+ * session tickets for resumption.
+ * A value of zero indicates no early data is to be sent by client using session
+ * tickets.
+ *
+ * ssl  The SSL/TLS object.
+ * sz   Maximum size of the early data.
+ * returns BAD_FUNC_ARG when ssl is NULL, or not using TLS v1.3,
+ * SIDE_ERROR when not a server and 0 on success.
+ */
+int wolfSSL_set_max_early_data(WOLFSSL* ssl, unsigned int sz)
+{
+    if (ssl == NULL || !IsAtLeastTLSv1_3(ssl->version))
+        return BAD_FUNC_ARG;
+    if (ssl->options.side == WOLFSSL_CLIENT_END)
+        return SIDE_ERROR;
+
+    ssl->options.maxEarlyDataSz = sz;
+
+    return 0;
+}
+
+/* Write early data to the server.
+ *
+ * ssl    The SSL/TLS object.
+ * data   Early data to write
+ * sz     The size of the eary data in bytes.
+ * outSz  The number of early data bytes written.
+ * returns BAD_FUNC_ARG when: ssl, data or outSz is NULL; sz is negative;
+ * or not using TLS v1.3. SIDE ERROR when not a server. Otherwise the number of
+ * early data bytes written.
+ */
+int wolfSSL_write_early_data(WOLFSSL* ssl, const void* data, int sz, int* outSz)
+{
+    int ret = 0;
+
+    WOLFSSL_ENTER("SSL_write_early_data()");
+
+    if (ssl == NULL || data == NULL || sz < 0 || outSz == NULL)
+        return BAD_FUNC_ARG;
+    if (!IsAtLeastTLSv1_3(ssl->version))
+        return BAD_FUNC_ARG;
+
+#ifndef NO_WOLFSSL_CLIENT
+    if (ssl->options.side == WOLFSSL_SERVER_END)
+        return SIDE_ERROR;
+
+    if (ssl->options.handShakeState == NULL_STATE) {
+        ssl->earlyData = expecting_early_data;
+        ret = wolfSSL_connect_TLSv13(ssl);
+        if (ret != WOLFSSL_SUCCESS)
+            return WOLFSSL_FATAL_ERROR;
+    }
+    if (ssl->options.handShakeState == CLIENT_HELLO_COMPLETE) {
+        ret = SendData(ssl, data, sz);
+        if (ret > 0)
+            *outSz = ret;
+    }
+#else
+    return SIDE_ERROR;
+#endif
+
+    WOLFSSL_LEAVE("SSL_write_early_data()", ret);
+
+    if (ret < 0)
+        ret = WOLFSSL_FATAL_ERROR;
+    return ret;
+}
+
+/* Read the any early data from the client.
+ *
+ * ssl    The SSL/TLS object.
+ * data   Buffer to put the early data into.
+ * sz     The size of the buffer in bytes.
+ * outSz  The number of early data bytes read.
+ * returns BAD_FUNC_ARG when: ssl, data or outSz is NULL; sz is negative;
+ * or not using TLS v1.3. SIDE ERROR when not a server. Otherwise the number of
+ * early data bytes read.
+ */
+int wolfSSL_read_early_data(WOLFSSL* ssl, void* data, int sz, int* outSz)
+{
+    int ret = 0;
+
+    WOLFSSL_ENTER("wolfSSL_read_early_data()");
+
+
+    if (ssl == NULL || data == NULL || sz < 0 || outSz == NULL)
+        return BAD_FUNC_ARG;
+    if (!IsAtLeastTLSv1_3(ssl->version))
+        return BAD_FUNC_ARG;
+
+#ifndef NO_WOLFSSL_SERVER
+    if (ssl->options.side == WOLFSSL_CLIENT_END)
+        return SIDE_ERROR;
+
+    if (ssl->options.handShakeState == NULL_STATE) {
+        ssl->earlyData = expecting_early_data;
+        ret = wolfSSL_accept_TLSv13(ssl);
+        if (ret <= 0)
+            return WOLFSSL_FATAL_ERROR;
+    }
+    if (ssl->options.handShakeState == SERVER_FINISHED_COMPLETE) {
+        ret = ReceiveData(ssl, (byte*)data, sz, FALSE);
+        if (ret > 0)
+            *outSz = ret;
+        if (ssl->error == ZERO_RETURN)
+            ssl->error = WOLFSSL_ERROR_NONE;
+    }
+    else
+        ret = 0;
+#else
+    return SIDE_ERROR;
+#endif
+
+    WOLFSSL_LEAVE("wolfSSL_read_early_data()", ret);
+
+    if (ret < 0)
+        ret = WOLFSSL_FATAL_ERROR;
+    return ret;
+}
+#endif
+
+#ifdef HAVE_SECRET_CALLBACK
+int wolfSSL_set_tls13_secret_cb(WOLFSSL* ssl, Tls13SecretCb cb, void* ctx)
+{
+    WOLFSSL_ENTER("wolfSSL_set_tls13_secret_cb");
+    if (ssl == NULL)
+        return WOLFSSL_FATAL_ERROR;
+
+    ssl->tls13SecretCb = cb;
+    ssl->tls13SecretCtx = ctx;
+
+    return WOLFSSL_SUCCESS;
+}
+#endif
+
+#undef ERROR_OUT
+
+#endif /* !WOLFCRYPT_ONLY */
+
+#endif /* WOLFSSL_TLS13 */
Index: azure_iot_hub_f767zi/trunk/wolfssl-4.4.0/src/wolfio.c
===================================================================
--- azure_iot_hub_f767zi/trunk/wolfssl-4.4.0/src/wolfio.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/wolfssl-4.4.0/src/wolfio.c	(revision 457)
@@ -0,0 +1,2375 @@
+/* wolfio.c
+ *
+ * Copyright (C) 2006-2020 wolfSSL Inc.
+ *
+ * This file is part of wolfSSL.
+ *
+ * wolfSSL is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * wolfSSL is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
+ */
+
+
+
+#ifdef HAVE_CONFIG_H
+    #include <config.h>
+#endif
+
+#include <wolfssl/wolfcrypt/settings.h>
+
+#ifndef WOLFCRYPT_ONLY
+
+#ifdef _WIN32_WCE
+    /* On WinCE winsock2.h must be included before windows.h for socket stuff */
+    #include <winsock2.h>
+#endif
+
+#include <wolfssl/internal.h>
+#include <wolfssl/error-ssl.h>
+#include <wolfssl/wolfio.h>
+
+#if defined(HAVE_HTTP_CLIENT)
+    #include <stdlib.h>   /* strtol() */
+#endif
+
+/*
+Possible IO enable options:
+ * WOLFSSL_USER_IO:     Disables default Embed* callbacks and     default: off
+                        allows user to define their own using
+                        wolfSSL_CTX_SetIORecv and wolfSSL_CTX_SetIOSend
+ * USE_WOLFSSL_IO:      Enables the wolfSSL IO functions          default: off
+ * HAVE_HTTP_CLIENT:    Enables HTTP client API's                 default: off
+                                     (unless HAVE_OCSP or HAVE_CRL_IO defined)
+ * HAVE_IO_TIMEOUT:     Enables support for connect timeout       default: off
+ */
+
+
+/* if user writes own I/O callbacks they can define WOLFSSL_USER_IO to remove
+   automatic setting of default I/O functions EmbedSend() and EmbedReceive()
+   but they'll still need SetCallback xxx() at end of file
+*/
+
+#if defined(USE_WOLFSSL_IO) || defined(HAVE_HTTP_CLIENT)
+
+/* Translates return codes returned from
+ * send() and recv() if need be.
+ */
+static WC_INLINE int TranslateReturnCode(int old, int sd)
+{
+    (void)sd;
+
+#if defined(FREESCALE_MQX) || defined(FREESCALE_KSDK_MQX)
+    if (old == 0) {
+        errno = SOCKET_EWOULDBLOCK;
+        return -1;  /* convert to BSD style wouldblock as error */
+    }
+
+    if (old < 0) {
+        errno = RTCS_geterror(sd);
+        if (errno == RTCSERR_TCP_CONN_CLOSING)
+            return 0;   /* convert to BSD style closing */
+        if (errno == RTCSERR_TCP_CONN_RLSD)
+            errno = SOCKET_ECONNRESET;
+        if (errno == RTCSERR_TCP_TIMED_OUT)
+            errno = SOCKET_EAGAIN;
+    }
+#endif
+
+    return old;
+}
+
+static WC_INLINE int wolfSSL_LastError(void)
+{
+#ifdef USE_WINDOWS_API
+    return WSAGetLastError();
+#elif defined(EBSNET)
+    return xn_getlasterror();
+#else
+    return errno;
+#endif
+}
+
+#endif /* USE_WOLFSSL_IO || HAVE_HTTP_CLIENT */
+
+
+#ifdef OPENSSL_EXTRA
+/* Use the WOLFSSL read BIO for receiving data. This is set by the function
+ * wolfSSL_set_bio and can also be set by wolfSSL_CTX_SetIORecv.
+ *
+ * ssl  WOLFSSL struct passed in that has this function set as the receive
+ *      callback.
+ * buf  buffer to fill with data read
+ * sz   size of buf buffer
+ * ctx  a user set context
+ *
+ * returns the amount of data read or want read. See WOLFSSL_CBIO_ERR_* values.
+ */
+int BioReceive(WOLFSSL* ssl, char* buf, int sz, void* ctx)
+{
+    int recvd = WOLFSSL_CBIO_ERR_GENERAL;
+
+    WOLFSSL_ENTER("BioReceive");
+
+    if (ssl->biord == NULL) {
+        WOLFSSL_MSG("WOLFSSL biord not set");
+        return WOLFSSL_CBIO_ERR_GENERAL;
+    }
+
+    if (ssl->biord->method && ssl->biord->method->readCb) {
+        WOLFSSL_MSG("Calling custom biord");
+        recvd = ssl->biord->method->readCb(ssl->biord, buf, sz);
+        if (recvd < 0 && recvd != WOLFSSL_CBIO_ERR_WANT_READ)
+            return WOLFSSL_CBIO_ERR_GENERAL;
+        return recvd;
+    }
+
+    switch (ssl->biord->type) {
+        case WOLFSSL_BIO_MEMORY:
+        case WOLFSSL_BIO_BIO:
+            if (wolfSSL_BIO_ctrl_pending(ssl->biord) == 0) {
+                WOLFSSL_MSG("BIO want read");
+               return WOLFSSL_CBIO_ERR_WANT_READ;
+            }
+            recvd = wolfSSL_BIO_read(ssl->biord, buf, sz);
+            if (recvd <= 0) {
+                WOLFSSL_MSG("BIO general error");
+                return WOLFSSL_CBIO_ERR_GENERAL;
+            }
+            break;
+
+       default:
+            WOLFSSL_MSG("This BIO type is unknown / unsupported");
+            return WOLFSSL_CBIO_ERR_GENERAL;
+    }
+
+    (void)ctx;
+    return recvd;
+}
+
+
+/* Use the WOLFSSL write BIO for sending data. This is set by the function
+ * wolfSSL_set_bio and can also be set by wolfSSL_CTX_SetIOSend.
+ *
+ * ssl  WOLFSSL struct passed in that has this function set as the send callback.
+ * buf  buffer with data to write out
+ * sz   size of buf buffer
+ * ctx  a user set context
+ *
+ * returns the amount of data sent or want send. See WOLFSSL_CBIO_ERR_* values.
+ */
+int BioSend(WOLFSSL* ssl, char *buf, int sz, void *ctx)
+{
+    int sent = WOLFSSL_CBIO_ERR_GENERAL;
+
+    WOLFSSL_ENTER("BioSend");
+
+    if (ssl->biowr == NULL) {
+        WOLFSSL_MSG("WOLFSSL biowr not set");
+        return WOLFSSL_CBIO_ERR_GENERAL;
+    }
+
+    if (ssl->biowr->method && ssl->biowr->method->writeCb) {
+        WOLFSSL_MSG("Calling custom biowr");
+        sent = ssl->biowr->method->writeCb(ssl->biowr, buf, sz);
+        if (sent < 0) {
+            return WOLFSSL_CBIO_ERR_GENERAL;
+        }
+        return sent;
+    }
+
+    switch (ssl->biowr->type) {
+        case WOLFSSL_BIO_MEMORY:
+        case WOLFSSL_BIO_BIO:
+            sent = wolfSSL_BIO_write(ssl->biowr, buf, sz);
+            if (sent < 0) {
+                return WOLFSSL_CBIO_ERR_GENERAL;
+            }
+            break;
+
+        default:
+            WOLFSSL_MSG("This BIO type is unknown / unsupported");
+            return WOLFSSL_CBIO_ERR_GENERAL;
+    }
+    (void)ctx;
+
+    return sent;
+}
+#endif
+
+
+#ifdef USE_WOLFSSL_IO
+
+/* The receive embedded callback
+ *  return : nb bytes read, or error
+ */
+int EmbedReceive(WOLFSSL *ssl, char *buf, int sz, void *ctx)
+{
+    int sd = *(int*)ctx;
+    int recvd;
+
+    recvd = wolfIO_Recv(sd, buf, sz, ssl->rflags);
+    if (recvd < 0) {
+        int err = wolfSSL_LastError();
+        WOLFSSL_MSG("Embed Receive error");
+
+        if (err == SOCKET_EWOULDBLOCK || err == SOCKET_EAGAIN) {
+            WOLFSSL_MSG("\tWould block");
+            return WOLFSSL_CBIO_ERR_WANT_READ;
+        }
+        else if (err == SOCKET_ECONNRESET) {
+            WOLFSSL_MSG("\tConnection reset");
+            return WOLFSSL_CBIO_ERR_CONN_RST;
+        }
+        else if (err == SOCKET_EINTR) {
+            WOLFSSL_MSG("\tSocket interrupted");
+            return WOLFSSL_CBIO_ERR_ISR;
+        }
+        else if (err == SOCKET_ECONNABORTED) {
+            WOLFSSL_MSG("\tConnection aborted");
+            return WOLFSSL_CBIO_ERR_CONN_CLOSE;
+        }
+        else {
+            WOLFSSL_MSG("\tGeneral error");
+            return WOLFSSL_CBIO_ERR_GENERAL;
+        }
+    }
+    else if (recvd == 0) {
+        WOLFSSL_MSG("Embed receive connection closed");
+        return WOLFSSL_CBIO_ERR_CONN_CLOSE;
+    }
+
+    return recvd;
+}
+
+/* The send embedded callback
+ *  return : nb bytes sent, or error
+ */
+int EmbedSend(WOLFSSL* ssl, char *buf, int sz, void *ctx)
+{
+    int sd = *(int*)ctx;
+    int sent;
+
+#ifdef WOLFSSL_MAX_SEND_SZ
+    if (sz > WOLFSSL_MAX_SEND_SZ)
+        sz = WOLFSSL_MAX_SEND_SZ;
+#endif
+
+    sent = wolfIO_Send(sd, buf, sz, ssl->wflags);
+    if (sent < 0) {
+        int err = wolfSSL_LastError();
+        WOLFSSL_MSG("Embed Send error");
+
+        if (err == SOCKET_EWOULDBLOCK || err == SOCKET_EAGAIN) {
+            WOLFSSL_MSG("\tWould Block");
+            return WOLFSSL_CBIO_ERR_WANT_WRITE;
+        }
+        else if (err == SOCKET_ECONNRESET) {
+            WOLFSSL_MSG("\tConnection reset");
+            return WOLFSSL_CBIO_ERR_CONN_RST;
+        }
+        else if (err == SOCKET_EINTR) {
+            WOLFSSL_MSG("\tSocket interrupted");
+            return WOLFSSL_CBIO_ERR_ISR;
+        }
+        else if (err == SOCKET_EPIPE) {
+            WOLFSSL_MSG("\tSocket EPIPE");
+            return WOLFSSL_CBIO_ERR_CONN_CLOSE;
+        }
+        else {
+            WOLFSSL_MSG("\tGeneral error");
+            return WOLFSSL_CBIO_ERR_GENERAL;
+        }
+    }
+
+    return sent;
+}
+
+
+#ifdef WOLFSSL_DTLS
+
+#include <wolfssl/wolfcrypt/sha.h>
+
+#define SENDTO_FUNCTION sendto
+#define RECVFROM_FUNCTION recvfrom
+
+
+/* The receive embedded callback
+ *  return : nb bytes read, or error
+ */
+int EmbedReceiveFrom(WOLFSSL *ssl, char *buf, int sz, void *ctx)
+{
+    WOLFSSL_DTLS_CTX* dtlsCtx = (WOLFSSL_DTLS_CTX*)ctx;
+    int recvd;
+    int err;
+    int sd = dtlsCtx->rfd;
+    int dtls_timeout = wolfSSL_dtls_get_current_timeout(ssl);
+    SOCKADDR_S peer;
+    XSOCKLENT peerSz = sizeof(peer);
+
+    WOLFSSL_ENTER("EmbedReceiveFrom()");
+
+    if (ssl->options.handShakeDone)
+        dtls_timeout = 0;
+
+    if (!wolfSSL_get_using_nonblock(ssl)) {
+        #ifdef USE_WINDOWS_API
+            DWORD timeout = dtls_timeout * 1000;
+        #else
+            struct timeval timeout;
+            XMEMSET(&timeout, 0, sizeof(timeout));
+            timeout.tv_sec = dtls_timeout;
+        #endif
+        if (setsockopt(sd, SOL_SOCKET, SO_RCVTIMEO, (char*)&timeout,
+                       sizeof(timeout)) != 0) {
+                WOLFSSL_MSG("setsockopt rcvtimeo failed");
+        }
+    }
+
+    recvd = (int)RECVFROM_FUNCTION(sd, buf, sz, ssl->rflags,
+                                  (SOCKADDR*)&peer, &peerSz);
+
+    recvd = TranslateReturnCode(recvd, sd);
+
+    if (recvd < 0) {
+        err = wolfSSL_LastError();
+        WOLFSSL_MSG("Embed Receive From error");
+
+        if (err == SOCKET_EWOULDBLOCK || err == SOCKET_EAGAIN) {
+            if (wolfSSL_dtls_get_using_nonblock(ssl)) {
+                WOLFSSL_MSG("\tWould block");
+                return WOLFSSL_CBIO_ERR_WANT_READ;
+            }
+            else {
+                WOLFSSL_MSG("\tSocket timeout");
+                return WOLFSSL_CBIO_ERR_TIMEOUT;
+            }
+        }
+        else if (err == SOCKET_ECONNRESET) {
+            WOLFSSL_MSG("\tConnection reset");
+            return WOLFSSL_CBIO_ERR_CONN_RST;
+        }
+        else if (err == SOCKET_EINTR) {
+            WOLFSSL_MSG("\tSocket interrupted");
+            return WOLFSSL_CBIO_ERR_ISR;
+        }
+        else if (err == SOCKET_ECONNREFUSED) {
+            WOLFSSL_MSG("\tConnection refused");
+            return WOLFSSL_CBIO_ERR_WANT_READ;
+        }
+        else {
+            WOLFSSL_MSG("\tGeneral error");
+            return WOLFSSL_CBIO_ERR_GENERAL;
+        }
+    }
+    else {
+        if (dtlsCtx->peer.sz > 0
+                && peerSz != (XSOCKLENT)dtlsCtx->peer.sz
+                && XMEMCMP(&peer, dtlsCtx->peer.sa, peerSz) != 0) {
+            WOLFSSL_MSG("    Ignored packet from invalid peer");
+            return WOLFSSL_CBIO_ERR_WANT_READ;
+        }
+    }
+
+    return recvd;
+}
+
+
+/* The send embedded callback
+ *  return : nb bytes sent, or error
+ */
+int EmbedSendTo(WOLFSSL* ssl, char *buf, int sz, void *ctx)
+{
+    WOLFSSL_DTLS_CTX* dtlsCtx = (WOLFSSL_DTLS_CTX*)ctx;
+    int sd = dtlsCtx->wfd;
+    int sent;
+    int err;
+
+    WOLFSSL_ENTER("EmbedSendTo()");
+
+    sent = (int)SENDTO_FUNCTION(sd, buf, sz, ssl->wflags,
+                                (const SOCKADDR*)dtlsCtx->peer.sa,
+                                dtlsCtx->peer.sz);
+
+    sent = TranslateReturnCode(sent, sd);
+
+    if (sent < 0) {
+        err = wolfSSL_LastError();
+        WOLFSSL_MSG("Embed Send To error");
+
+        if (err == SOCKET_EWOULDBLOCK || err == SOCKET_EAGAIN) {
+            WOLFSSL_MSG("\tWould Block");
+            return WOLFSSL_CBIO_ERR_WANT_WRITE;
+        }
+        else if (err == SOCKET_ECONNRESET) {
+            WOLFSSL_MSG("\tConnection reset");
+            return WOLFSSL_CBIO_ERR_CONN_RST;
+        }
+        else if (err == SOCKET_EINTR) {
+            WOLFSSL_MSG("\tSocket interrupted");
+            return WOLFSSL_CBIO_ERR_ISR;
+        }
+        else if (err == SOCKET_EPIPE) {
+            WOLFSSL_MSG("\tSocket EPIPE");
+            return WOLFSSL_CBIO_ERR_CONN_CLOSE;
+        }
+        else {
+            WOLFSSL_MSG("\tGeneral error");
+            return WOLFSSL_CBIO_ERR_GENERAL;
+        }
+    }
+
+    return sent;
+}
+
+
+#ifdef WOLFSSL_MULTICAST
+
+/* The alternate receive embedded callback for Multicast
+ *  return : nb bytes read, or error
+ */
+int EmbedReceiveFromMcast(WOLFSSL *ssl, char *buf, int sz, void *ctx)
+{
+    WOLFSSL_DTLS_CTX* dtlsCtx = (WOLFSSL_DTLS_CTX*)ctx;
+    int recvd;
+    int err;
+    int sd = dtlsCtx->rfd;
+
+    WOLFSSL_ENTER("EmbedReceiveFromMcast()");
+
+    recvd = (int)RECVFROM_FUNCTION(sd, buf, sz, ssl->rflags, NULL, NULL);
+
+    recvd = TranslateReturnCode(recvd, sd);
+
+    if (recvd < 0) {
+        err = wolfSSL_LastError();
+        WOLFSSL_MSG("Embed Receive From error");
+
+        if (err == SOCKET_EWOULDBLOCK || err == SOCKET_EAGAIN) {
+            if (wolfSSL_dtls_get_using_nonblock(ssl)) {
+                WOLFSSL_MSG("\tWould block");
+                return WOLFSSL_CBIO_ERR_WANT_READ;
+            }
+            else {
+                WOLFSSL_MSG("\tSocket timeout");
+                return WOLFSSL_CBIO_ERR_TIMEOUT;
+            }
+        }
+        else if (err == SOCKET_ECONNRESET) {
+            WOLFSSL_MSG("\tConnection reset");
+            return WOLFSSL_CBIO_ERR_CONN_RST;
+        }
+        else if (err == SOCKET_EINTR) {
+            WOLFSSL_MSG("\tSocket interrupted");
+            return WOLFSSL_CBIO_ERR_ISR;
+        }
+        else if (err == SOCKET_ECONNREFUSED) {
+            WOLFSSL_MSG("\tConnection refused");
+            return WOLFSSL_CBIO_ERR_WANT_READ;
+        }
+        else {
+            WOLFSSL_MSG("\tGeneral error");
+            return WOLFSSL_CBIO_ERR_GENERAL;
+        }
+    }
+
+    return recvd;
+}
+#endif /* WOLFSSL_MULTICAST */
+
+
+/* The DTLS Generate Cookie callback
+ *  return : number of bytes copied into buf, or error
+ */
+int EmbedGenerateCookie(WOLFSSL* ssl, byte *buf, int sz, void *ctx)
+{
+    int sd = ssl->wfd;
+    SOCKADDR_S peer;
+    XSOCKLENT peerSz = sizeof(peer);
+    byte digest[WC_SHA256_DIGEST_SIZE];
+    int  ret = 0;
+
+    (void)ctx;
+
+    XMEMSET(&peer, 0, sizeof(peer));
+    if (getpeername(sd, (SOCKADDR*)&peer, &peerSz) != 0) {
+        WOLFSSL_MSG("getpeername failed in EmbedGenerateCookie");
+        return GEN_COOKIE_E;
+    }
+
+    ret = wc_Sha256Hash((byte*)&peer, peerSz, digest);
+    if (ret != 0)
+        return ret;
+
+    if (sz > WC_SHA256_DIGEST_SIZE)
+        sz = WC_SHA256_DIGEST_SIZE;
+    XMEMCPY(buf, digest, sz);
+
+    return sz;
+}
+
+#ifdef WOLFSSL_SESSION_EXPORT
+
+    /* get the peer information in human readable form (ip, port, family)
+     * default function assumes BSD sockets
+     * can be overridden with wolfSSL_CTX_SetIOGetPeer
+     */
+    int EmbedGetPeer(WOLFSSL* ssl, char* ip, int* ipSz,
+                                                 unsigned short* port, int* fam)
+    {
+        SOCKADDR_S peer;
+        word32     peerSz;
+        int        ret;
+
+        if (ssl == NULL || ip == NULL || ipSz == NULL ||
+                                                  port == NULL || fam == NULL) {
+            return BAD_FUNC_ARG;
+        }
+
+        /* get peer information stored in ssl struct */
+        peerSz = sizeof(SOCKADDR_S);
+        if ((ret = wolfSSL_dtls_get_peer(ssl, (void*)&peer, &peerSz))
+                                                               != WOLFSSL_SUCCESS) {
+            return ret;
+        }
+
+        /* extract family, ip, and port */
+        *fam = ((SOCKADDR_S*)&peer)->ss_family;
+        switch (*fam) {
+            case WOLFSSL_IP4:
+                if (XINET_NTOP(*fam, &(((SOCKADDR_IN*)&peer)->sin_addr),
+                                                           ip, *ipSz) == NULL) {
+                    WOLFSSL_MSG("XINET_NTOP error");
+                    return SOCKET_ERROR_E;
+                }
+                *port = XNTOHS(((SOCKADDR_IN*)&peer)->sin_port);
+                break;
+
+            case WOLFSSL_IP6:
+            #ifdef WOLFSSL_IPV6
+                if (XINET_NTOP(*fam, &(((SOCKADDR_IN6*)&peer)->sin6_addr),
+                                                           ip, *ipSz) == NULL) {
+                    WOLFSSL_MSG("XINET_NTOP error");
+                    return SOCKET_ERROR_E;
+                }
+                *port = XNTOHS(((SOCKADDR_IN6*)&peer)->sin6_port);
+            #endif /* WOLFSSL_IPV6 */
+                break;
+
+            default:
+                WOLFSSL_MSG("Unknown family type");
+                return SOCKET_ERROR_E;
+        }
+        ip[*ipSz - 1] = '\0'; /* make sure has terminator */
+        *ipSz = (word16)XSTRLEN(ip);
+
+        return WOLFSSL_SUCCESS;
+    }
+
+    /* set the peer information in human readable form (ip, port, family)
+     * default function assumes BSD sockets
+     * can be overridden with wolfSSL_CTX_SetIOSetPeer
+     */
+    int EmbedSetPeer(WOLFSSL* ssl, char* ip, int ipSz,
+                                                   unsigned short port, int fam)
+    {
+        int    ret;
+        SOCKADDR_S addr;
+
+        /* sanity checks on arguments */
+        if (ssl == NULL || ip == NULL || ipSz < 0 || ipSz > DTLS_EXPORT_IP) {
+            return BAD_FUNC_ARG;
+        }
+
+        addr.ss_family = fam;
+        switch (addr.ss_family) {
+            case WOLFSSL_IP4:
+                if (XINET_PTON(addr.ss_family, ip,
+                                     &(((SOCKADDR_IN*)&addr)->sin_addr)) <= 0) {
+                    WOLFSSL_MSG("XINET_PTON error");
+                    return SOCKET_ERROR_E;
+                }
+                ((SOCKADDR_IN*)&addr)->sin_port = XHTONS(port);
+
+                /* peer sa is free'd in SSL_ResourceFree */
+                if ((ret = wolfSSL_dtls_set_peer(ssl, (SOCKADDR_IN*)&addr,
+                                          sizeof(SOCKADDR_IN)))!= WOLFSSL_SUCCESS) {
+                    WOLFSSL_MSG("Import DTLS peer info error");
+                    return ret;
+                }
+                break;
+
+            case WOLFSSL_IP6:
+            #ifdef WOLFSSL_IPV6
+                if (XINET_PTON(addr.ss_family, ip,
+                                   &(((SOCKADDR_IN6*)&addr)->sin6_addr)) <= 0) {
+                    WOLFSSL_MSG("XINET_PTON error");
+                    return SOCKET_ERROR_E;
+                }
+                ((SOCKADDR_IN6*)&addr)->sin6_port = XHTONS(port);
+
+                /* peer sa is free'd in SSL_ResourceFree */
+                if ((ret = wolfSSL_dtls_set_peer(ssl, (SOCKADDR_IN6*)&addr,
+                                         sizeof(SOCKADDR_IN6)))!= WOLFSSL_SUCCESS) {
+                    WOLFSSL_MSG("Import DTLS peer info error");
+                    return ret;
+                }
+            #endif /* WOLFSSL_IPV6 */
+                break;
+
+            default:
+                WOLFSSL_MSG("Unknown address family");
+                return BUFFER_E;
+        }
+
+        return WOLFSSL_SUCCESS;
+    }
+#endif /* WOLFSSL_SESSION_EXPORT */
+#endif /* WOLFSSL_DTLS */
+
+
+int wolfIO_Recv(SOCKET_T sd, char *buf, int sz, int rdFlags)
+{
+    int recvd;
+
+    recvd = (int)RECV_FUNCTION(sd, buf, sz, rdFlags);
+    recvd = TranslateReturnCode(recvd, sd);
+
+    return recvd;
+}
+
+int wolfIO_Send(SOCKET_T sd, char *buf, int sz, int wrFlags)
+{
+    int sent;
+
+    sent = (int)SEND_FUNCTION(sd, buf, sz, wrFlags);
+    sent = TranslateReturnCode(sent, sd);
+
+    return sent;
+}
+
+#endif /* USE_WOLFSSL_IO */
+
+
+#ifdef HAVE_HTTP_CLIENT
+
+#ifndef HAVE_IO_TIMEOUT
+    #define io_timeout_sec 0
+#else
+
+    #ifndef DEFAULT_TIMEOUT_SEC
+        #define DEFAULT_TIMEOUT_SEC 0 /* no timeout */
+    #endif
+
+    static int io_timeout_sec = DEFAULT_TIMEOUT_SEC;
+
+    void wolfIO_SetTimeout(int to_sec)
+    {
+        io_timeout_sec = to_sec;
+    }
+
+    int wolfIO_SetBlockingMode(SOCKET_T sockfd, int non_blocking)
+    {
+        int ret = 0;
+
+    #ifdef USE_WINDOWS_API
+        unsigned long blocking = non_blocking;
+        ret = ioctlsocket(sockfd, FIONBIO, &blocking);
+        if (ret == SOCKET_ERROR)
+            ret = -1;
+    #else
+        ret = fcntl(sockfd, F_GETFL, 0);
+        if (ret >= 0) {
+            if (non_blocking)
+                ret |= O_NONBLOCK;
+            else
+                ret &= ~O_NONBLOCK;
+            ret = fcntl(sockfd, F_SETFL, ret);
+        }
+    #endif
+        if (ret < 0) {
+            WOLFSSL_MSG("wolfIO_SetBlockingMode failed");
+        }
+
+        return ret;
+    }
+
+    int wolfIO_Select(SOCKET_T sockfd, int to_sec)
+    {
+        fd_set rfds, wfds;
+        int nfds = 0;
+        struct timeval timeout = { (to_sec > 0) ? to_sec : 0, 0};
+        int ret;
+
+    #ifndef USE_WINDOWS_API
+        nfds = (int)sockfd + 1;
+    #endif
+
+        FD_ZERO(&rfds);
+        FD_SET(sockfd, &rfds);
+        wfds = rfds;
+
+        ret = select(nfds, &rfds, &wfds, NULL, &timeout);
+        if (ret == 0) {
+        #ifdef DEBUG_HTTP
+            printf("Timeout: %d\n", ret);
+        #endif
+            return HTTP_TIMEOUT;
+        }
+        else if (ret > 0) {
+            if (FD_ISSET(sockfd, &wfds)) {
+                if (!FD_ISSET(sockfd, &rfds)) {
+                    return 0;
+                }
+            }
+        }
+        return SOCKET_ERROR_E;
+    }
+#endif /* HAVE_IO_TIMEOUT */
+
+static int wolfIO_Word16ToString(char* d, word16 number)
+{
+    int i = 0;
+    word16 order = 10000;
+    word16 digit;
+
+    if (d == NULL)
+        return i;
+
+    if (number == 0)
+        d[i++] = '0';
+    else {
+        while (order) {
+            digit = number / order;
+            if (i > 0 || digit != 0)
+                d[i++] = (char)digit + '0';
+            if (digit != 0)
+                number %= digit * order;
+
+            order = (order > 1) ? order / 10 : 0;
+        }
+    }
+    d[i] = 0; /* null terminate */
+
+    return i;
+}
+
+int wolfIO_TcpConnect(SOCKET_T* sockfd, const char* ip, word16 port, int to_sec)
+{
+#ifdef HAVE_SOCKADDR
+    int ret = 0;
+    SOCKADDR_S addr;
+    int sockaddr_len = sizeof(SOCKADDR_IN);
+    /* use gethostbyname for c99 */
+#if defined(HAVE_GETADDRINFO) && !defined(WOLF_C99)
+    ADDRINFO hints;
+    ADDRINFO* answer = NULL;
+    char strPort[6];
+#else
+    HOSTENT* entry;
+    SOCKADDR_IN *sin;
+#endif
+
+    XMEMSET(&addr, 0, sizeof(addr));
+
+#ifdef WOLFIO_DEBUG
+    printf("TCP Connect: %s:%d\n", ip, port);
+#endif
+
+    /* use gethostbyname for c99 */
+#if defined(HAVE_GETADDRINFO) && !defined(WOLF_C99)
+    XMEMSET(&hints, 0, sizeof(hints));
+    hints.ai_family = AF_UNSPEC;
+    hints.ai_socktype = SOCK_STREAM;
+    hints.ai_protocol = IPPROTO_TCP;
+
+    if (wolfIO_Word16ToString(strPort, port) == 0) {
+        WOLFSSL_MSG("invalid port number for responder");
+        return -1;
+    }
+
+    if (getaddrinfo(ip, strPort, &hints, &answer) < 0 || answer == NULL) {
+        WOLFSSL_MSG("no addr info for responder");
+        return -1;
+    }
+
+    sockaddr_len = answer->ai_addrlen;
+    XMEMCPY(&addr, answer->ai_addr, sockaddr_len);
+    freeaddrinfo(answer);
+#else
+    entry = gethostbyname(ip);
+    sin = (SOCKADDR_IN *)&addr;
+
+    if (entry) {
+        sin->sin_family = AF_INET;
+        sin->sin_port = XHTONS(port);
+        XMEMCPY(&sin->sin_addr.s_addr, entry->h_addr_list[0], entry->h_length);
+    }
+    else {
+        WOLFSSL_MSG("no addr info for responder");
+        return -1;
+    }
+#endif
+
+    *sockfd = (SOCKET_T)socket(addr.ss_family, SOCK_STREAM, 0);
+
+#ifdef USE_WINDOWS_API
+    if (*sockfd == INVALID_SOCKET) {
+        WOLFSSL_MSG("bad socket fd, out of fds?");
+        return -1;
+    }
+#else
+     if (*sockfd < 0) {
+         WOLFSSL_MSG("bad socket fd, out of fds?");
+         return -1;
+     }
+#endif
+
+#ifdef HAVE_IO_TIMEOUT
+    /* if timeout value provided then set socket non-blocking */
+    if (to_sec > 0) {
+        wolfIO_SetBlockingMode(*sockfd, 1);
+    }
+#else
+    (void)to_sec;
+#endif
+
+    ret = connect(*sockfd, (SOCKADDR *)&addr, sockaddr_len);
+#ifdef HAVE_IO_TIMEOUT
+    if (ret != 0) {
+        if ((errno == EINPROGRESS) && (to_sec > 0)) {
+            /* wait for connect to complete */
+            ret = wolfIO_Select(*sockfd, to_sec);
+
+            /* restore blocking mode */
+            wolfIO_SetBlockingMode(*sockfd, 0);
+        }
+    }
+#endif
+    if (ret != 0) {
+        WOLFSSL_MSG("Responder tcp connect failed");
+        return -1;
+    }
+    return ret;
+#else
+    (void)sockfd;
+    (void)ip;
+    (void)port;
+    (void)to_sec;
+    return -1;
+#endif /* HAVE_SOCKADDR */
+}
+
+#ifndef HTTP_SCRATCH_BUFFER_SIZE
+    #define HTTP_SCRATCH_BUFFER_SIZE 512
+#endif
+#ifndef MAX_URL_ITEM_SIZE
+    #define MAX_URL_ITEM_SIZE   80
+#endif
+
+int wolfIO_DecodeUrl(const char* url, int urlSz, char* outName, char* outPath,
+    word16* outPort)
+{
+    int result = -1;
+
+    if (url == NULL || urlSz == 0) {
+        if (outName)
+            *outName = 0;
+        if (outPath)
+            *outPath = 0;
+        if (outPort)
+            *outPort = 0;
+    }
+    else {
+        int i, cur;
+
+        /* need to break the url down into scheme, address, and port */
+        /*     "http://example.com:8080/" */
+        /*     "http://[::1]:443/"        */
+        if (XSTRNCMP(url, "http://", 7) == 0) {
+            cur = 7;
+        } else cur = 0;
+
+        i = 0;
+        if (url[cur] == '[') {
+            cur++;
+            /* copy until ']' */
+            while (i < MAX_URL_ITEM_SIZE-1 && cur < urlSz && url[cur] != 0 &&
+                    url[cur] != ']') {
+                if (outName)
+                    outName[i] = url[cur];
+                i++; cur++;
+            }
+            cur++; /* skip ']' */
+        }
+        else {
+            while (i < MAX_URL_ITEM_SIZE-1 && cur < urlSz && url[cur] != 0 &&
+                    url[cur] != ':' && url[cur] != '/') {
+                if (outName)
+                    outName[i] = url[cur];
+                i++; cur++;
+            }
+        }
+        if (outName)
+            outName[i] = 0;
+        /* Need to pick out the path after the domain name */
+
+        if (cur < urlSz && url[cur] == ':') {
+            char port[6];
+            int j;
+            word32 bigPort = 0;
+            i = 0;
+            cur++;
+            while (i < 6 && cur < urlSz && url[cur] != 0 && url[cur] != '/') {
+                port[i] = url[cur];
+                i++; cur++;
+            }
+
+            for (j = 0; j < i; j++) {
+                if (port[j] < '0' || port[j] > '9') return -1;
+                bigPort = (bigPort * 10) + (port[j] - '0');
+            }
+            if (outPort)
+                *outPort = (word16)bigPort;
+        }
+        else if (outPort)
+            *outPort = 80;
+
+
+        if (cur < urlSz && url[cur] == '/') {
+            i = 0;
+            while (i < MAX_URL_ITEM_SIZE-1 && cur < urlSz && url[cur] != 0) {
+                if (outPath)
+                    outPath[i] = url[cur];
+                i++; cur++;
+            }
+            if (outPath)
+                outPath[i] = 0;
+        }
+        else if (outPath) {
+            outPath[0] = '/';
+            outPath[1] = 0;
+        }
+
+        result = 0;
+    }
+
+    return result;
+}
+
+static int wolfIO_HttpProcessResponseBuf(int sfd, byte **recvBuf,
+    int* recvBufSz, int chunkSz, char* start, int len, int dynType, void* heap)
+{
+    byte* newRecvBuf = NULL;
+    int newRecvSz = *recvBufSz + chunkSz;
+    int pos = 0;
+
+    WOLFSSL_MSG("Processing HTTP response");
+#ifdef WOLFIO_DEBUG
+    printf("HTTP Chunk %d->%d\n", *recvBufSz, chunkSz);
+#endif
+
+    (void)heap;
+    (void)dynType;
+
+    if (chunkSz < 0 || len < 0) {
+        WOLFSSL_MSG("wolfIO_HttpProcessResponseBuf invalid chunk or length size");
+        return MEMORY_E;
+    }
+
+    if (newRecvSz <= 0) {
+        WOLFSSL_MSG("wolfIO_HttpProcessResponseBuf new receive size overflow");
+        return MEMORY_E;
+    }
+
+    newRecvBuf = (byte*)XMALLOC(newRecvSz, heap, dynType);
+    if (newRecvBuf == NULL) {
+        WOLFSSL_MSG("wolfIO_HttpProcessResponseBuf malloc failed");
+        return MEMORY_E;
+    }
+
+    /* if buffer already exists, then we are growing it */
+    if (*recvBuf) {
+        XMEMCPY(&newRecvBuf[pos], *recvBuf, *recvBufSz);
+        XFREE(*recvBuf, heap, dynType);
+        pos += *recvBufSz;
+        *recvBuf = NULL;
+    }
+
+    /* copy the remainder of the httpBuf into the respBuf */
+    if (len != 0) {
+        if (pos + len <= newRecvSz) {
+            XMEMCPY(&newRecvBuf[pos], start, len);
+            pos += len;
+        }
+        else {
+            WOLFSSL_MSG("wolfIO_HttpProcessResponseBuf bad size");
+            XFREE(newRecvBuf, heap, dynType);
+            return -1;
+        }
+    }
+
+    /* receive the remainder of chunk */
+    while (len < chunkSz) {
+        int rxSz = wolfIO_Recv(sfd, (char*)&newRecvBuf[pos], chunkSz-len, 0);
+        if (rxSz > 0) {
+            len += rxSz;
+            pos += rxSz;
+        }
+        else {
+            WOLFSSL_MSG("wolfIO_HttpProcessResponseBuf recv failed");
+            XFREE(newRecvBuf, heap, dynType);
+            return -1;
+        }
+    }
+
+    *recvBuf = newRecvBuf;
+    *recvBufSz = newRecvSz;
+
+    return 0;
+}
+
+int wolfIO_HttpProcessResponse(int sfd, const char** appStrList,
+    byte** respBuf, byte* httpBuf, int httpBufSz, int dynType, void* heap)
+{
+    int result = 0;
+    int len = 0;
+    char *start, *end;
+    int respBufSz = 0;
+    int isChunked = 0, chunkSz = 0;
+    enum phr_state { phr_init, phr_http_start, phr_have_length, phr_have_type,
+                     phr_wait_end, phr_get_chunk_len, phr_get_chunk_data,
+                     phr_http_end
+    } state = phr_init;
+
+    *respBuf = NULL;
+    start = end = NULL;
+    do {
+        if (state == phr_get_chunk_data) {
+            /* get chunk of data */
+            result = wolfIO_HttpProcessResponseBuf(sfd, respBuf, &respBufSz,
+                chunkSz, start, len, dynType, heap);
+
+            state = (result != 0) ? phr_http_end : phr_get_chunk_len;
+            end = NULL;
+            len = 0;
+        }
+
+        /* read data if no \r\n or first time */
+        if (end == NULL) {
+            result = wolfIO_Recv(sfd, (char*)httpBuf+len, httpBufSz-len-1, 0);
+            if (result > 0) {
+                len += result;
+                start = (char*)httpBuf;
+                start[len] = 0;
+            }
+            else {
+                WOLFSSL_MSG("wolfIO_HttpProcessResponse recv http from peer failed");
+                return -1;
+            }
+        }
+        end = XSTRSTR(start, "\r\n"); /* locate end */
+
+        /* handle incomplete rx */
+        if (end == NULL) {
+            if (len != 0)
+                XMEMMOVE(httpBuf, start, len);
+            start = end = NULL;
+        }
+        /* when start is "\r\n" */
+        else if (end == start) {
+            /* if waiting for end or need chunk len */
+            if (state == phr_wait_end || state == phr_get_chunk_len) {
+                state = (isChunked) ? phr_get_chunk_len : phr_http_end;
+                len -= 2; start += 2; /* skip \r\n */
+             }
+             else {
+                WOLFSSL_MSG("wolfIO_HttpProcessResponse header ended early");
+                return -1;
+             }
+        }
+        else {
+            *end = 0; /* null terminate */
+            len -= (int)(end - start) + 2;
+                /* adjust len to remove the first line including the /r/n */
+
+        #ifdef WOLFIO_DEBUG
+            printf("HTTP Resp: %s\n", start);
+        #endif
+
+            switch (state) {
+                case phr_init:
+                    if (XSTRLEN(start) < 15) { /* 15 is the length of the two
+                                          constant strings we're about to
+                                          compare against. */
+                        WOLFSSL_MSG("wolfIO_HttpProcessResponse HTTP header too short.");
+                        return -1;
+                    }
+                    if (XSTRNCASECMP(start, "HTTP/1", 6) == 0) {
+                        start += 9;
+                        if (XSTRNCASECMP(start, "200 OK", 6) != 0) {
+                            WOLFSSL_MSG("wolfIO_HttpProcessResponse not OK");
+                            return -1;
+                        }
+                        state = phr_http_start;
+                    }
+                    break;
+                case phr_http_start:
+                case phr_have_length:
+                case phr_have_type:
+                    if (XSTRLEN(start) < 13) { /* 13 is the shortest of the following
+                                          next lines we're checking for. */
+                        WOLFSSL_MSG("wolfIO_HttpProcessResponse content type is too short.");
+                        return -1;
+                    }
+
+                    if (XSTRNCASECMP(start, "Content-Type:", 13) == 0) {
+                        int i;
+
+                        start += 13;
+                        while (*start == ' ') start++;
+
+                        /* try and match against appStrList */
+                        i = 0;
+                        while (appStrList[i] != NULL) {
+                            if (XSTRNCASECMP(start, appStrList[i],
+                                                XSTRLEN(appStrList[i])) == 0) {
+                                break;
+                            }
+                            i++;
+                        }
+                        if (appStrList[i] == NULL) {
+                            WOLFSSL_MSG("wolfIO_HttpProcessResponse appstr mismatch");
+                            return -1;
+                        }
+                        state = (state == phr_http_start) ? phr_have_type : phr_wait_end;
+                    }
+                    else if (XSTRNCASECMP(start, "Content-Length:", 15) == 0) {
+                        start += 15;
+                        while (*start == ' ') start++;
+                        chunkSz = XATOI(start);
+                        state = (state == phr_http_start) ? phr_have_length : phr_wait_end;
+                    }
+                    else if (XSTRNCASECMP(start, "Transfer-Encoding:", 18) == 0) {
+                        start += 18;
+                        while (*start == ' ') start++;
+                        if (XSTRNCASECMP(start, "chunked", 7) == 0) {
+                            isChunked = 1;
+                            state = (state == phr_http_start) ? phr_have_length : phr_wait_end;
+                        }
+                    }
+                    break;
+                case phr_get_chunk_len:
+                    chunkSz = (int)strtol(start, NULL, 16); /* hex format */
+                    state = (chunkSz == 0) ? phr_http_end : phr_get_chunk_data;
+                    break;
+                case phr_get_chunk_data:
+                    /* processing for chunk data done above, since \r\n isn't required */
+                case phr_wait_end:
+                case phr_http_end:
+                    /* do nothing */
+                    break;
+            } /* switch (state) */
+
+            /* skip to end plus \r\n */
+            start = end + 2;
+        }
+    } while (state != phr_http_end);
+
+    if (!isChunked) {
+        result = wolfIO_HttpProcessResponseBuf(sfd, respBuf, &respBufSz, chunkSz,
+                                                    start, len, dynType, heap);
+    }
+
+    if (result >= 0) {
+        result = respBufSz;
+    }
+    else {
+        WOLFSSL_ERROR(result);
+    }
+
+    return result;
+}
+int wolfIO_HttpBuildRequest(const char *reqType, const char *domainName,
+                               const char *path, int pathLen, int reqSz, const char *contentType,
+                               byte *buf, int bufSize)
+{
+    return wolfIO_HttpBuildRequest_ex(reqType, domainName, path, pathLen, reqSz, contentType, "", buf, bufSize);
+}
+
+    int wolfIO_HttpBuildRequest_ex(const char *reqType, const char *domainName,
+                                const char *path, int pathLen, int reqSz, const char *contentType,
+                                const char *exHdrs, byte *buf, int bufSize)
+    {
+    word32 reqTypeLen, domainNameLen, reqSzStrLen, contentTypeLen, exHdrsLen, maxLen;
+    char reqSzStr[6];
+    char* req = (char*)buf;
+    const char* blankStr = " ";
+    const char* http11Str = " HTTP/1.1";
+    const char* hostStr = "\r\nHost: ";
+    const char* contentLenStr = "\r\nContent-Length: ";
+    const char* contentTypeStr = "\r\nContent-Type: ";
+    const char* singleCrLfStr = "\r\n";
+    const char* doubleCrLfStr = "\r\n\r\n";
+    word32 blankStrLen, http11StrLen, hostStrLen, contentLenStrLen,
+        contentTypeStrLen, singleCrLfStrLen, doubleCrLfStrLen;
+
+    reqTypeLen = (word32)XSTRLEN(reqType);
+    domainNameLen = (word32)XSTRLEN(domainName);
+    reqSzStrLen = wolfIO_Word16ToString(reqSzStr, (word16)reqSz);
+    contentTypeLen = (word32)XSTRLEN(contentType);
+
+    blankStrLen = (word32)XSTRLEN(blankStr);
+    http11StrLen = (word32)XSTRLEN(http11Str);
+    hostStrLen = (word32)XSTRLEN(hostStr);
+    contentLenStrLen = (word32)XSTRLEN(contentLenStr);
+    contentTypeStrLen = (word32)XSTRLEN(contentTypeStr);
+
+    if(exHdrs){
+        singleCrLfStrLen = (word32)XSTRLEN(singleCrLfStr);
+        exHdrsLen = (word32)XSTRLEN(exHdrs);
+    } else {
+        singleCrLfStrLen = 0;
+        exHdrsLen = 0;
+    }
+
+    doubleCrLfStrLen = (word32)XSTRLEN(doubleCrLfStr);
+
+    /* determine max length and check it */
+    maxLen =
+        reqTypeLen +
+        blankStrLen +
+        pathLen +
+        http11StrLen +
+        hostStrLen +
+        domainNameLen +
+        contentLenStrLen +
+        reqSzStrLen +
+        contentTypeStrLen +
+        contentTypeLen +
+        singleCrLfStrLen +
+        exHdrsLen +
+        doubleCrLfStrLen +
+        1 /* null term */;
+    if (maxLen > (word32)bufSize)
+        return 0;
+
+    XSTRNCPY((char*)buf, reqType, bufSize);
+    buf += reqTypeLen; bufSize -= reqTypeLen;
+    XSTRNCPY((char*)buf, blankStr, bufSize);
+    buf += blankStrLen; bufSize -= blankStrLen;
+    XSTRNCPY((char*)buf, path, bufSize);
+    buf += pathLen; bufSize -= pathLen;
+    XSTRNCPY((char*)buf, http11Str, bufSize);
+    buf += http11StrLen; bufSize -= http11StrLen;
+    if (domainNameLen > 0) {
+        XSTRNCPY((char*)buf, hostStr, bufSize);
+        buf += hostStrLen; bufSize -= hostStrLen;
+        XSTRNCPY((char*)buf, domainName, bufSize);
+        buf += domainNameLen; bufSize -= domainNameLen;
+    }
+    if (reqSz > 0 && reqSzStrLen > 0) {
+        XSTRNCPY((char*)buf, contentLenStr, bufSize);
+        buf += contentLenStrLen; bufSize -= contentLenStrLen;
+        XSTRNCPY((char*)buf, reqSzStr, bufSize);
+        buf += reqSzStrLen; bufSize -= reqSzStrLen;
+    }
+    if (contentTypeLen > 0) {
+        XSTRNCPY((char*)buf, contentTypeStr, bufSize);
+        buf += contentTypeStrLen; bufSize -= contentTypeStrLen;
+        XSTRNCPY((char*)buf, contentType, bufSize);
+        buf += contentTypeLen; bufSize -= contentTypeLen;
+    }
+    if (exHdrsLen > 0)
+    {
+        XSTRNCPY((char *)buf, singleCrLfStr, bufSize);
+        buf += singleCrLfStrLen;
+        bufSize -= singleCrLfStrLen;
+        XSTRNCPY((char *)buf, exHdrs, bufSize);
+        buf += exHdrsLen;
+        bufSize -= exHdrsLen;
+    }
+    XSTRNCPY((char*)buf, doubleCrLfStr, bufSize);
+    buf += doubleCrLfStrLen;
+
+#ifdef WOLFIO_DEBUG
+    printf("HTTP %s: %s", reqType, req);
+#endif
+
+    /* calculate actual length based on original and new pointer */
+    return (int)((char*)buf - req);
+}
+
+
+#ifdef HAVE_OCSP
+
+int wolfIO_HttpBuildRequestOcsp(const char* domainName, const char* path,
+                                    int ocspReqSz, byte* buf, int bufSize)
+{
+    const char *cacheCtl = "Cache-Control: no-cache";
+    return wolfIO_HttpBuildRequest_ex("POST", domainName, path, (int)XSTRLEN(path),
+        ocspReqSz, "application/ocsp-request", cacheCtl, buf, bufSize);
+}
+
+/* return: >0 OCSP Response Size
+ *         -1 error */
+int wolfIO_HttpProcessResponseOcsp(int sfd, byte** respBuf,
+                                       byte* httpBuf, int httpBufSz, void* heap)
+{
+    const char* appStrList[] = {
+        "application/ocsp-response",
+        NULL
+    };
+
+    return wolfIO_HttpProcessResponse(sfd, appStrList,
+        respBuf, httpBuf, httpBufSz, DYNAMIC_TYPE_OCSP, heap);
+}
+
+/* in default wolfSSL callback ctx is the heap pointer */
+int EmbedOcspLookup(void* ctx, const char* url, int urlSz,
+                        byte* ocspReqBuf, int ocspReqSz, byte** ocspRespBuf)
+{
+    SOCKET_T sfd = 0;
+    word16   port;
+    int      ret = -1;
+#ifdef WOLFSSL_SMALL_STACK
+    char*    path;
+    char*    domainName;
+#else
+    char     path[MAX_URL_ITEM_SIZE];
+    char     domainName[MAX_URL_ITEM_SIZE];
+#endif
+
+#ifdef WOLFSSL_SMALL_STACK
+    path = (char*)XMALLOC(MAX_URL_ITEM_SIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    if (path == NULL)
+        return MEMORY_E;
+
+    domainName = (char*)XMALLOC(MAX_URL_ITEM_SIZE, NULL,
+            DYNAMIC_TYPE_TMP_BUFFER);
+    if (domainName == NULL) {
+        XFREE(path, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+        return MEMORY_E;
+    }
+#endif
+
+    if (ocspReqBuf == NULL || ocspReqSz == 0) {
+        WOLFSSL_MSG("OCSP request is required for lookup");
+    }
+    else if (ocspRespBuf == NULL) {
+        WOLFSSL_MSG("Cannot save OCSP response");
+    }
+    else if (wolfIO_DecodeUrl(url, urlSz, domainName, path, &port) < 0) {
+        WOLFSSL_MSG("Unable to decode OCSP URL");
+    }
+    else {
+        /* Note, the library uses the EmbedOcspRespFree() callback to
+         * free this buffer. */
+        int   httpBufSz = HTTP_SCRATCH_BUFFER_SIZE;
+        byte* httpBuf   = (byte*)XMALLOC(httpBufSz, ctx, DYNAMIC_TYPE_OCSP);
+
+        if (httpBuf == NULL) {
+            WOLFSSL_MSG("Unable to create OCSP response buffer");
+        }
+        else {
+            httpBufSz = wolfIO_HttpBuildRequestOcsp(domainName, path, ocspReqSz,
+                                                            httpBuf, httpBufSz);
+
+            ret = wolfIO_TcpConnect(&sfd, domainName, port, io_timeout_sec);
+            if ((ret != 0) || ((int)sfd < 0)) {
+                WOLFSSL_MSG("OCSP Responder connection failed");
+            }
+            else if (wolfIO_Send(sfd, (char*)httpBuf, httpBufSz, 0) !=
+                                                                    httpBufSz) {
+                WOLFSSL_MSG("OCSP http request failed");
+            }
+            else if (wolfIO_Send(sfd, (char*)ocspReqBuf, ocspReqSz, 0) !=
+                                                                    ocspReqSz) {
+                WOLFSSL_MSG("OCSP ocsp request failed");
+            }
+            else {
+                ret = wolfIO_HttpProcessResponseOcsp(sfd, ocspRespBuf, httpBuf,
+                                                 HTTP_SCRATCH_BUFFER_SIZE, ctx);
+            }
+
+            CloseSocket(sfd);
+            XFREE(httpBuf, ctx, DYNAMIC_TYPE_OCSP);
+        }
+    }
+
+#ifdef WOLFSSL_SMALL_STACK
+    XFREE(path,       NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    XFREE(domainName, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+#endif
+
+    return ret;
+}
+
+/* in default callback ctx is heap hint */
+void EmbedOcspRespFree(void* ctx, byte *resp)
+{
+    if (resp)
+        XFREE(resp, ctx, DYNAMIC_TYPE_OCSP);
+
+    (void)ctx;
+}
+#endif /* HAVE_OCSP */
+
+
+#if defined(HAVE_CRL) && defined(HAVE_CRL_IO)
+
+int wolfIO_HttpBuildRequestCrl(const char* url, int urlSz,
+    const char* domainName, byte* buf, int bufSize)
+{
+    const char *cacheCtl = "Cache-Control: no-cache";
+    return wolfIO_HttpBuildRequest_ex("GET", domainName, url, urlSz, 0, "",
+                                   cacheCtl, buf, bufSize);
+}
+
+int wolfIO_HttpProcessResponseCrl(WOLFSSL_CRL* crl, int sfd, byte* httpBuf,
+    int httpBufSz)
+{
+    int result;
+    byte *respBuf = NULL;
+
+    const char* appStrList[] = {
+        "application/pkix-crl",
+        "application/x-pkcs7-crl",
+        NULL
+    };
+
+    result = wolfIO_HttpProcessResponse(sfd, appStrList,
+        &respBuf, httpBuf, httpBufSz, DYNAMIC_TYPE_CRL, crl->heap);
+    if (result >= 0) {
+        result = BufferLoadCRL(crl, respBuf, result, WOLFSSL_FILETYPE_ASN1, 0);
+    }
+    XFREE(respBuf, crl->heap, DYNAMIC_TYPE_CRL);
+
+    return result;
+}
+
+int EmbedCrlLookup(WOLFSSL_CRL* crl, const char* url, int urlSz)
+{
+    SOCKET_T sfd = 0;
+    word16   port;
+    int      ret = -1;
+#ifdef WOLFSSL_SMALL_STACK
+    char*    domainName;
+#else
+    char     domainName[MAX_URL_ITEM_SIZE];
+#endif
+
+#ifdef WOLFSSL_SMALL_STACK
+    domainName = (char*)XMALLOC(MAX_URL_ITEM_SIZE, crl->heap,
+                                                       DYNAMIC_TYPE_TMP_BUFFER);
+    if (domainName == NULL) {
+        return MEMORY_E;
+    }
+#endif
+
+    if (wolfIO_DecodeUrl(url, urlSz, domainName, NULL, &port) < 0) {
+        WOLFSSL_MSG("Unable to decode CRL URL");
+    }
+    else {
+        int   httpBufSz = HTTP_SCRATCH_BUFFER_SIZE;
+        byte* httpBuf   = (byte*)XMALLOC(httpBufSz, crl->heap,
+                                                              DYNAMIC_TYPE_CRL);
+        if (httpBuf == NULL) {
+            WOLFSSL_MSG("Unable to create CRL response buffer");
+        }
+        else {
+            httpBufSz = wolfIO_HttpBuildRequestCrl(url, urlSz, domainName,
+                httpBuf, httpBufSz);
+
+            ret = wolfIO_TcpConnect(&sfd, domainName, port, io_timeout_sec);
+            if ((ret != 0) || (sfd < 0)) {
+                WOLFSSL_MSG("CRL connection failed");
+            }
+            else if (wolfIO_Send(sfd, (char*)httpBuf, httpBufSz, 0)
+                                                                 != httpBufSz) {
+                WOLFSSL_MSG("CRL http get failed");
+            }
+            else {
+                ret = wolfIO_HttpProcessResponseCrl(crl, sfd, httpBuf,
+                                                      HTTP_SCRATCH_BUFFER_SIZE);
+            }
+
+            CloseSocket(sfd);
+            XFREE(httpBuf, crl->heap, DYNAMIC_TYPE_CRL);
+        }
+    }
+
+#ifdef WOLFSSL_SMALL_STACK
+    XFREE(domainName, crl->heap, DYNAMIC_TYPE_TMP_BUFFER);
+#endif
+
+    return ret;
+}
+#endif /* HAVE_CRL && HAVE_CRL_IO */
+
+#endif /* HAVE_HTTP_CLIENT */
+
+
+
+void wolfSSL_CTX_SetIORecv(WOLFSSL_CTX *ctx, CallbackIORecv CBIORecv)
+{
+    if (ctx) {
+        ctx->CBIORecv = CBIORecv;
+    #ifdef OPENSSL_EXTRA
+        ctx->cbioFlag |= WOLFSSL_CBIO_RECV;
+    #endif
+    }
+}
+
+
+void wolfSSL_CTX_SetIOSend(WOLFSSL_CTX *ctx, CallbackIOSend CBIOSend)
+{
+    if (ctx) {
+        ctx->CBIOSend = CBIOSend;
+    #ifdef OPENSSL_EXTRA
+        ctx->cbioFlag |= WOLFSSL_CBIO_SEND;
+    #endif
+    }
+}
+
+
+/* sets the IO callback to use for receives at WOLFSSL level */
+void wolfSSL_SSLSetIORecv(WOLFSSL *ssl, CallbackIORecv CBIORecv)
+{
+    if (ssl) {
+        ssl->CBIORecv = CBIORecv;
+    #ifdef OPENSSL_EXTRA
+        ssl->cbioFlag |= WOLFSSL_CBIO_RECV;
+    #endif
+    }
+}
+
+
+/* sets the IO callback to use for sends at WOLFSSL level */
+void wolfSSL_SSLSetIOSend(WOLFSSL *ssl, CallbackIOSend CBIOSend)
+{
+    if (ssl) {
+        ssl->CBIOSend = CBIOSend;
+    #ifdef OPENSSL_EXTRA
+        ssl->cbioFlag |= WOLFSSL_CBIO_SEND;
+    #endif
+    }
+}
+
+
+void wolfSSL_SetIOReadCtx(WOLFSSL* ssl, void *rctx)
+{
+    if (ssl)
+        ssl->IOCB_ReadCtx = rctx;
+}
+
+
+void wolfSSL_SetIOWriteCtx(WOLFSSL* ssl, void *wctx)
+{
+    if (ssl)
+        ssl->IOCB_WriteCtx = wctx;
+}
+
+
+void* wolfSSL_GetIOReadCtx(WOLFSSL* ssl)
+{
+    if (ssl)
+        return ssl->IOCB_ReadCtx;
+
+    return NULL;
+}
+
+
+void* wolfSSL_GetIOWriteCtx(WOLFSSL* ssl)
+{
+    if (ssl)
+        return ssl->IOCB_WriteCtx;
+
+    return NULL;
+}
+
+
+void wolfSSL_SetIOReadFlags(WOLFSSL* ssl, int flags)
+{
+    if (ssl)
+        ssl->rflags = flags;
+}
+
+
+void wolfSSL_SetIOWriteFlags(WOLFSSL* ssl, int flags)
+{
+    if (ssl)
+        ssl->wflags = flags;
+}
+
+
+#ifdef WOLFSSL_DTLS
+
+void wolfSSL_CTX_SetGenCookie(WOLFSSL_CTX* ctx, CallbackGenCookie cb)
+{
+    if (ctx)
+        ctx->CBIOCookie = cb;
+}
+
+
+void wolfSSL_SetCookieCtx(WOLFSSL* ssl, void *ctx)
+{
+    if (ssl)
+        ssl->IOCB_CookieCtx = ctx;
+}
+
+
+void* wolfSSL_GetCookieCtx(WOLFSSL* ssl)
+{
+    if (ssl)
+        return ssl->IOCB_CookieCtx;
+
+    return NULL;
+}
+
+#ifdef WOLFSSL_SESSION_EXPORT
+
+void wolfSSL_CTX_SetIOGetPeer(WOLFSSL_CTX* ctx, CallbackGetPeer cb)
+{
+    if (ctx)
+        ctx->CBGetPeer = cb;
+}
+
+
+void wolfSSL_CTX_SetIOSetPeer(WOLFSSL_CTX* ctx, CallbackSetPeer cb)
+{
+    if (ctx)
+        ctx->CBSetPeer = cb;
+}
+
+#endif /* WOLFSSL_SESSION_EXPORT */
+#endif /* WOLFSSL_DTLS */
+
+
+#ifdef HAVE_NETX
+
+/* The NetX receive callback
+ *  return :  bytes read, or error
+ */
+int NetX_Receive(WOLFSSL *ssl, char *buf, int sz, void *ctx)
+{
+    NetX_Ctx* nxCtx = (NetX_Ctx*)ctx;
+    ULONG left;
+    ULONG total;
+    ULONG copied = 0;
+    UINT  status;
+
+    (void)ssl;
+
+    if (nxCtx == NULL || nxCtx->nxSocket == NULL) {
+        WOLFSSL_MSG("NetX Recv NULL parameters");
+        return WOLFSSL_CBIO_ERR_GENERAL;
+    }
+
+    if (nxCtx->nxPacket == NULL) {
+        status = nx_tcp_socket_receive(nxCtx->nxSocket, &nxCtx->nxPacket,
+                                       nxCtx->nxWait);
+        if (status != NX_SUCCESS) {
+            WOLFSSL_MSG("NetX Recv receive error");
+            return WOLFSSL_CBIO_ERR_GENERAL;
+        }
+    }
+
+    if (nxCtx->nxPacket) {
+        status = nx_packet_length_get(nxCtx->nxPacket, &total);
+        if (status != NX_SUCCESS) {
+            WOLFSSL_MSG("NetX Recv length get error");
+            return WOLFSSL_CBIO_ERR_GENERAL;
+        }
+
+        left = total - nxCtx->nxOffset;
+        status = nx_packet_data_extract_offset(nxCtx->nxPacket, nxCtx->nxOffset,
+                                               buf, sz, &copied);
+        if (status != NX_SUCCESS) {
+            WOLFSSL_MSG("NetX Recv data extract offset error");
+            return WOLFSSL_CBIO_ERR_GENERAL;
+        }
+
+        nxCtx->nxOffset += copied;
+
+        if (copied == left) {
+            WOLFSSL_MSG("NetX Recv Drained packet");
+            nx_packet_release(nxCtx->nxPacket);
+            nxCtx->nxPacket = NULL;
+            nxCtx->nxOffset = 0;
+        }
+    }
+
+    return copied;
+}
+
+
+/* The NetX send callback
+ *  return : bytes sent, or error
+ */
+int NetX_Send(WOLFSSL* ssl, char *buf, int sz, void *ctx)
+{
+    NetX_Ctx*       nxCtx = (NetX_Ctx*)ctx;
+    NX_PACKET*      packet;
+    NX_PACKET_POOL* pool;   /* shorthand */
+    UINT            status;
+
+    (void)ssl;
+
+    if (nxCtx == NULL || nxCtx->nxSocket == NULL) {
+        WOLFSSL_MSG("NetX Send NULL parameters");
+        return WOLFSSL_CBIO_ERR_GENERAL;
+    }
+
+    pool = nxCtx->nxSocket->nx_tcp_socket_ip_ptr->nx_ip_default_packet_pool;
+    status = nx_packet_allocate(pool, &packet, NX_TCP_PACKET,
+                                nxCtx->nxWait);
+    if (status != NX_SUCCESS) {
+        WOLFSSL_MSG("NetX Send packet alloc error");
+        return WOLFSSL_CBIO_ERR_GENERAL;
+    }
+
+    status = nx_packet_data_append(packet, buf, sz, pool, nxCtx->nxWait);
+    if (status != NX_SUCCESS) {
+        nx_packet_release(packet);
+        WOLFSSL_MSG("NetX Send data append error");
+        return WOLFSSL_CBIO_ERR_GENERAL;
+    }
+
+    status = nx_tcp_socket_send(nxCtx->nxSocket, packet, nxCtx->nxWait);
+    if (status != NX_SUCCESS) {
+        nx_packet_release(packet);
+        WOLFSSL_MSG("NetX Send socket send error");
+        return WOLFSSL_CBIO_ERR_GENERAL;
+    }
+
+    return sz;
+}
+
+
+/* like set_fd, but for default NetX context */
+void wolfSSL_SetIO_NetX(WOLFSSL* ssl, NX_TCP_SOCKET* nxSocket, ULONG waitOption)
+{
+    if (ssl) {
+        ssl->nxCtx.nxSocket = nxSocket;
+        ssl->nxCtx.nxWait   = waitOption;
+    }
+}
+
+#endif /* HAVE_NETX */
+
+
+#ifdef MICRIUM
+
+/* Micrium uTCP/IP port, using the NetSock API
+ * TCP and UDP are currently supported with the callbacks below.
+ *
+ * WOLFSSL_SESSION_EXPORT is not yet supported, would need EmbedGetPeer()
+ * and EmbedSetPeer() callbacks implemented.
+ *
+ * HAVE_CRL is not yet supported, would need an EmbedCrlLookup()
+ * callback implemented.
+ *
+ * HAVE_OCSP is not yet supported, would need an EmbedOCSPLookup()
+ * callback implemented.
+ */
+
+/* The Micrium uTCP/IP send callback
+ * return : bytes sent, or error
+ */
+int MicriumSend(WOLFSSL* ssl, char* buf, int sz, void* ctx)
+{
+    NET_SOCK_ID sd = *(int*)ctx;
+    NET_SOCK_RTN_CODE ret;
+    NET_ERR err;
+
+    ret = NetSock_TxData(sd, buf, sz, ssl->wflags, &err);
+    if (ret < 0) {
+        WOLFSSL_MSG("Embed Send error");
+
+        if (err == NET_ERR_TX) {
+            WOLFSSL_MSG("\tWould block");
+            return WOLFSSL_CBIO_ERR_WANT_WRITE;
+
+        } else {
+            WOLFSSL_MSG("\tGeneral error");
+            return WOLFSSL_CBIO_ERR_GENERAL;
+        }
+    }
+
+    return ret;
+}
+
+/* The Micrium uTCP/IP receive callback
+ *  return : nb bytes read, or error
+ */
+int MicriumReceive(WOLFSSL *ssl, char *buf, int sz, void *ctx)
+{
+    NET_SOCK_ID sd = *(int*)ctx;
+    NET_SOCK_RTN_CODE ret;
+    NET_ERR err;
+
+#ifdef WOLFSSL_DTLS
+    {
+        int dtls_timeout = wolfSSL_dtls_get_current_timeout(ssl);
+        if (wolfSSL_dtls(ssl)
+                     && !wolfSSL_dtls_get_using_nonblock(ssl)
+                     && dtls_timeout != 0) {
+            /* needs timeout in milliseconds */
+            NetSock_CfgTimeoutRxQ_Set(sd, dtls_timeout * 1000, &err);
+            if (err != NET_SOCK_ERR_NONE) {
+                WOLFSSL_MSG("NetSock_CfgTimeoutRxQ_Set failed");
+            }
+        }
+    }
+#endif
+
+    ret = NetSock_RxData(sd, buf, sz, ssl->rflags, &err);
+    if (ret < 0) {
+        WOLFSSL_MSG("Embed Receive error");
+
+        if (err == NET_ERR_RX || err == NET_SOCK_ERR_RX_Q_EMPTY ||
+            err == NET_ERR_FAULT_LOCK_ACQUIRE) {
+            if (!wolfSSL_dtls(ssl) || wolfSSL_dtls_get_using_nonblock(ssl)) {
+                WOLFSSL_MSG("\tWould block");
+                return WOLFSSL_CBIO_ERR_WANT_READ;
+            }
+            else {
+                WOLFSSL_MSG("\tSocket timeout");
+                return WOLFSSL_CBIO_ERR_TIMEOUT;
+            }
+
+        } else if (err == NET_SOCK_ERR_CLOSED) {
+            WOLFSSL_MSG("Embed receive connection closed");
+            return WOLFSSL_CBIO_ERR_CONN_CLOSE;
+
+        } else {
+            WOLFSSL_MSG("\tGeneral error");
+            return WOLFSSL_CBIO_ERR_GENERAL;
+        }
+    }
+
+    return ret;
+}
+
+/* The Micrium uTCP/IP receivefrom callback
+ *  return : nb bytes read, or error
+ */
+int MicriumReceiveFrom(WOLFSSL *ssl, char *buf, int sz, void *ctx)
+{
+    WOLFSSL_DTLS_CTX* dtlsCtx = (WOLFSSL_DTLS_CTX*)ctx;
+    NET_SOCK_ID       sd = dtlsCtx->rfd;
+    NET_SOCK_ADDR     peer;
+    NET_SOCK_ADDR_LEN peerSz = sizeof(peer);
+    NET_SOCK_RTN_CODE ret;
+    NET_ERR err;
+    int dtls_timeout = wolfSSL_dtls_get_current_timeout(ssl);
+
+    WOLFSSL_ENTER("MicriumReceiveFrom()");
+
+    if (ssl->options.handShakeDone)
+        dtls_timeout = 0;
+
+    if (!wolfSSL_dtls_get_using_nonblock(ssl)) {
+        /* needs timeout in milliseconds */
+        NetSock_CfgTimeoutRxQ_Set(sd, dtls_timeout * 1000, &err);
+        if (err != NET_SOCK_ERR_NONE) {
+            WOLFSSL_MSG("NetSock_CfgTimeoutRxQ_Set failed");
+        }
+    }
+
+    ret = NetSock_RxDataFrom(sd, buf, sz, ssl->rflags, &peer, &peerSz,
+                             0, 0, 0, &err);
+    if (ret < 0) {
+        WOLFSSL_MSG("Embed Receive From error");
+
+        if (err == NET_ERR_RX || err == NET_SOCK_ERR_RX_Q_EMPTY ||
+            err == NET_ERR_FAULT_LOCK_ACQUIRE) {
+            if (wolfSSL_dtls_get_using_nonblock(ssl)) {
+                WOLFSSL_MSG("\tWould block");
+                return WOLFSSL_CBIO_ERR_WANT_READ;
+            }
+            else {
+                WOLFSSL_MSG("\tSocket timeout");
+                return WOLFSSL_CBIO_ERR_TIMEOUT;
+            }
+        } else {
+            WOLFSSL_MSG("\tGeneral error");
+            return WOLFSSL_CBIO_ERR_GENERAL;
+        }
+    }
+    else {
+        if (dtlsCtx->peer.sz > 0
+                && peerSz != (NET_SOCK_ADDR_LEN)dtlsCtx->peer.sz
+                && XMEMCMP(&peer, dtlsCtx->peer.sa, peerSz) != 0) {
+            WOLFSSL_MSG("\tIgnored packet from invalid peer");
+            return WOLFSSL_CBIO_ERR_WANT_READ;
+        }
+    }
+
+    return ret;
+}
+
+/* The Micrium uTCP/IP sendto callback
+ *  return : nb bytes sent, or error
+ */
+int MicriumSendTo(WOLFSSL* ssl, char *buf, int sz, void *ctx)
+{
+    WOLFSSL_DTLS_CTX* dtlsCtx = (WOLFSSL_DTLS_CTX*)ctx;
+    NET_SOCK_ID sd = dtlsCtx->wfd;
+    NET_SOCK_RTN_CODE ret;
+    NET_ERR err;
+
+    WOLFSSL_ENTER("MicriumSendTo()");
+
+    ret = NetSock_TxDataTo(sd, buf, sz, ssl->wflags,
+                           (NET_SOCK_ADDR*)dtlsCtx->peer.sa,
+                           (NET_SOCK_ADDR_LEN)dtlsCtx->peer.sz,
+                           &err);
+    if (err < 0) {
+        WOLFSSL_MSG("Embed Send To error");
+
+        if (err == NET_ERR_TX) {
+            WOLFSSL_MSG("\tWould block");
+            return WOLFSSL_CBIO_ERR_WANT_WRITE;
+
+        } else {
+            WOLFSSL_MSG("\tGeneral error");
+            return WOLFSSL_CBIO_ERR_GENERAL;
+        }
+    }
+
+    return ret;
+}
+
+/* Micrium DTLS Generate Cookie callback
+ *  return : number of bytes copied into buf, or error
+ */
+int MicriumGenerateCookie(WOLFSSL* ssl, byte *buf, int sz, void *ctx)
+{
+    NET_SOCK_ADDR peer;
+    NET_SOCK_ADDR_LEN peerSz = sizeof(peer);
+    byte digest[WC_SHA_DIGEST_SIZE];
+    int  ret = 0;
+
+    (void)ctx;
+
+    XMEMSET(&peer, 0, sizeof(peer));
+    if (wolfSSL_dtls_get_peer(ssl, (void*)&peer,
+                              (unsigned int*)&peerSz) != WOLFSSL_SUCCESS) {
+        WOLFSSL_MSG("getpeername failed in MicriumGenerateCookie");
+        return GEN_COOKIE_E;
+    }
+
+    ret = wc_ShaHash((byte*)&peer, peerSz, digest);
+    if (ret != 0)
+        return ret;
+
+    if (sz > WC_SHA_DIGEST_SIZE)
+        sz = WC_SHA_DIGEST_SIZE;
+    XMEMCPY(buf, digest, sz);
+
+    return sz;
+}
+
+#endif /* MICRIUM */
+
+#if defined(WOLFSSL_APACHE_MYNEWT) && !defined(WOLFSSL_LWIP)
+
+#include <os/os_error.h>
+#include <os/os_mbuf.h>
+#include <os/os_mempool.h>
+
+#define MB_NAME "wolfssl_mb"
+
+typedef struct Mynewt_Ctx {
+        struct mn_socket *mnSocket;          /* send/recv socket handler */
+        struct mn_sockaddr_in mnSockAddrIn;  /* socket address */
+        struct os_mbuf *mnPacket;            /* incoming packet handle
+                                                for short reads */
+        int reading;                         /* reading flag */
+
+        /* private */
+        void *mnMemBuffer;                   /* memory buffer for mempool */
+        struct os_mempool mnMempool;         /* mempool */
+        struct os_mbuf_pool mnMbufpool;      /* mbuf pool */
+} Mynewt_Ctx;
+
+void mynewt_ctx_clear(void *ctx) {
+    Mynewt_Ctx *mynewt_ctx = (Mynewt_Ctx*)ctx;
+    if(!mynewt_ctx) return;
+
+    if(mynewt_ctx->mnPacket) {
+        os_mbuf_free_chain(mynewt_ctx->mnPacket);
+        mynewt_ctx->mnPacket = NULL;
+    }
+    os_mempool_clear(&mynewt_ctx->mnMempool);
+    XFREE(mynewt_ctx->mnMemBuffer, 0, 0);
+    XFREE(mynewt_ctx, 0, 0);
+}
+
+/* return Mynewt_Ctx instance */
+void* mynewt_ctx_new() {
+    int rc = 0;
+    Mynewt_Ctx *mynewt_ctx;
+    int mem_buf_count = MYNEWT_VAL(WOLFSSL_MNSOCK_MEM_BUF_COUNT);
+    int mem_buf_size = MYNEWT_VAL(WOLFSSL_MNSOCK_MEM_BUF_SIZE);
+    int mempool_bytes = OS_MEMPOOL_BYTES(mem_buf_count, mem_buf_size);
+
+    mynewt_ctx = (Mynewt_Ctx *)XMALLOC(sizeof(struct Mynewt_Ctx),
+                                       NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    if(!mynewt_ctx) return NULL;
+
+    XMEMSET(mynewt_ctx, 0, sizeof(Mynewt_Ctx));
+    mynewt_ctx->mnMemBuffer = XMALLOC(mempool_bytes, 0, 0);
+    if(!mynewt_ctx->mnMemBuffer) {
+        mynewt_ctx_clear((void*)mynewt_ctx);
+        return NULL;
+    }
+
+    rc = os_mempool_init(&mynewt_ctx->mnMempool,
+                         mem_buf_count, mem_buf_size,
+                         mynewt_ctx->mnMemBuffer, MB_NAME);
+    if(rc != 0) {
+        mynewt_ctx_clear((void*)mynewt_ctx);
+        return NULL;
+    }
+    rc = os_mbuf_pool_init(&mynewt_ctx->mnMbufpool, &mynewt_ctx->mnMempool,
+                           mem_buf_count, mem_buf_size);
+    if(rc != 0) {
+        mynewt_ctx_clear((void*)mynewt_ctx);
+        return NULL;
+    }
+
+    return mynewt_ctx;
+}
+
+static void mynewt_sock_writable(void *arg, int err);
+static void mynewt_sock_readable(void *arg, int err);
+static const union mn_socket_cb mynewt_sock_cbs = {
+    .socket.writable = mynewt_sock_writable,
+    .socket.readable = mynewt_sock_readable,
+};
+static void mynewt_sock_writable(void *arg, int err)
+{
+    /* do nothing */
+}
+static void mynewt_sock_readable(void *arg, int err)
+{
+    Mynewt_Ctx *mynewt_ctx = (Mynewt_Ctx *)arg;
+    if (err && mynewt_ctx->reading) {
+        mynewt_ctx->reading = 0;
+    }
+}
+
+/* The Mynewt receive callback
+ *  return :  bytes read, or error
+ */
+int Mynewt_Receive(WOLFSSL *ssl, char *buf, int sz, void *ctx)
+{
+    Mynewt_Ctx *mynewt_ctx = (Mynewt_Ctx*)ctx;
+    int rc = 0;
+    struct mn_sockaddr_in from;
+    struct os_mbuf *m;
+    int read_sz = 0;
+    uint16_t total;
+
+    if (mynewt_ctx == NULL || mynewt_ctx->mnSocket == NULL) {
+        WOLFSSL_MSG("Mynewt Recv NULL parameters");
+        return WOLFSSL_CBIO_ERR_GENERAL;
+    }
+
+    if(mynewt_ctx->mnPacket == NULL) {
+        mynewt_ctx->mnPacket = os_mbuf_get_pkthdr(&mynewt_ctx->mnMbufpool, 0);
+        if(mynewt_ctx->mnPacket == NULL) {
+            return MEMORY_E;
+        }
+
+        mynewt_ctx->reading = 1;
+        while(mynewt_ctx->reading && rc == 0) {
+            rc = mn_recvfrom(mynewt_ctx->mnSocket, &m, (struct mn_sockaddr *) &from);
+            if(rc == MN_ECONNABORTED) {
+                rc = 0;
+                mynewt_ctx->reading = 0;
+                break;
+            }
+            if (!(rc == 0 || rc == MN_EAGAIN)) {
+                WOLFSSL_MSG("Mynewt Recv receive error");
+                mynewt_ctx->reading = 0;
+                break;
+            }
+            if(rc == 0) {
+                int len = OS_MBUF_PKTLEN(m);
+                if(len == 0) {
+                    break;
+                }
+                rc = os_mbuf_appendfrom(mynewt_ctx->mnPacket, m, 0, len);
+                if(rc != 0) {
+                    WOLFSSL_MSG("Mynewt Recv os_mbuf_appendfrom error");
+                    break;
+                }
+                os_mbuf_free_chain(m);
+                m = NULL;
+            } else if(rc == MN_EAGAIN) {
+                /* continue to until reading all of packet data. */
+                rc = 0;
+                break;
+            }
+        }
+        if(rc != 0) {
+            mynewt_ctx->reading = 0;
+            os_mbuf_free_chain(mynewt_ctx->mnPacket);
+            mynewt_ctx->mnPacket = NULL;
+            return rc;
+        }
+    }
+
+    if(mynewt_ctx->mnPacket) {
+        total = OS_MBUF_PKTLEN(mynewt_ctx->mnPacket);
+        read_sz = (total >= sz)? sz : total;
+
+        os_mbuf_copydata(mynewt_ctx->mnPacket, 0, read_sz, (void*)buf);
+        os_mbuf_adj(mynewt_ctx->mnPacket, read_sz);
+
+        if (read_sz == total) {
+            WOLFSSL_MSG("Mynewt Recv Drained packet");
+            os_mbuf_free_chain(mynewt_ctx->mnPacket);
+            mynewt_ctx->mnPacket = NULL;
+        }
+    }
+
+    return read_sz;
+}
+
+/* The Mynewt send callback
+ *  return : bytes sent, or error
+ */
+int Mynewt_Send(WOLFSSL* ssl, char *buf, int sz, void *ctx)
+{
+    Mynewt_Ctx *mynewt_ctx = (Mynewt_Ctx*)ctx;
+    int rc = 0;
+    struct os_mbuf *m;
+    int write_sz = 0;
+    m = os_msys_get_pkthdr(sz, 0);
+    if (!m) {
+        WOLFSSL_MSG("Mynewt Send os_msys_get_pkthdr error");
+        return WOLFSSL_CBIO_ERR_GENERAL;
+    }
+    rc = os_mbuf_copyinto(m, 0, buf, sz);
+    if (rc != 0) {
+        WOLFSSL_MSG("Mynewt Send os_mbuf_copyinto error");
+        os_mbuf_free_chain(m);
+        return rc;
+    }
+    rc = mn_sendto(mynewt_ctx->mnSocket, m, (struct mn_sockaddr *)&mynewt_ctx->mnSockAddrIn);
+    if(rc != 0) {
+        WOLFSSL_MSG("Mynewt Send mn_sendto error");
+        os_mbuf_free_chain(m);
+        return rc;
+    }
+    write_sz = sz;
+    return write_sz;
+}
+
+/* like set_fd, but for default NetX context */
+void wolfSSL_SetIO_Mynewt(WOLFSSL* ssl, struct mn_socket* mnSocket, struct mn_sockaddr_in* mnSockAddrIn)
+{
+    if (ssl && ssl->mnCtx) {
+        Mynewt_Ctx *mynewt_ctx = (Mynewt_Ctx *)ssl->mnCtx;
+        mynewt_ctx->mnSocket = mnSocket;
+        memcpy(&mynewt_ctx->mnSockAddrIn, mnSockAddrIn, sizeof(struct mn_sockaddr_in));
+        mn_socket_set_cbs(mynewt_ctx->mnSocket, mnSocket, &mynewt_sock_cbs);
+    }
+}
+
+#endif /* defined(WOLFSSL_APACHE_MYNEWT) && !defined(WOLFSSL_LWIP) */
+
+#ifdef WOLFSSL_UIP
+#include <uip.h>
+#include <stdio.h>
+
+/* uIP TCP/IP port, using the native tcp/udp socket api.
+ * TCP and UDP are currently supported with the callbacks below.
+ *
+ */
+/* The uIP tcp send callback
+ * return : bytes sent, or error
+ */
+int uIPSend(WOLFSSL* ssl, char* buf, int sz, void* _ctx)
+{
+    uip_wolfssl_ctx *ctx = (struct uip_wolfssl_ctx *)_ctx;
+    int ret;
+    unsigned int max_sendlen;
+    int total_written = 0;
+    (void)ssl;
+    do {
+        unsigned int bytes_left = sz - total_written;
+        max_sendlen = tcp_socket_max_sendlen(&ctx->conn.tcp);
+        if (bytes_left > max_sendlen) {
+            printf("Send limited by buffer\r\n");
+            bytes_left = max_sendlen;
+        }
+        if (bytes_left == 0) {
+            printf("Buffer full!\r\n");
+            break;
+        }
+        ret = tcp_socket_send(&ctx->conn.tcp, (unsigned char *)buf + total_written, bytes_left);
+        if (ret <= 0)
+            break;
+        total_written += ret;
+    } while(total_written < sz);
+    if (total_written == 0)
+        return WOLFSSL_CBIO_ERR_WANT_WRITE;
+    return total_written;
+}
+
+int uIPSendTo(WOLFSSL* ssl, char* buf, int sz, void* _ctx)
+{
+    uip_wolfssl_ctx *ctx = (struct uip_wolfssl_ctx *)_ctx;
+    int ret = 0;
+    (void)ssl;
+    ret = udp_socket_sendto(&ctx->conn.udp, (unsigned char *)buf, sz, &ctx->peer_addr, ctx->peer_port );
+    if (ret == 0)
+        return WOLFSSL_CBIO_ERR_WANT_WRITE;
+    return ret;
+}
+
+/* The uIP uTCP/IP receive callback
+ *  return : nb bytes read, or error
+ */
+int uIPReceive(WOLFSSL *ssl, char *buf, int sz, void *_ctx)
+{
+    uip_wolfssl_ctx *ctx = (uip_wolfssl_ctx *)_ctx;
+    if (!ctx || !ctx->ssl_rx_databuf)
+        return -1;
+    (void)ssl;
+    if (ctx->ssl_rb_len > 0) {
+        if (sz > ctx->ssl_rb_len - ctx->ssl_rb_off)
+            sz = ctx->ssl_rb_len - ctx->ssl_rb_off;
+        XMEMCPY(buf, ctx->ssl_rx_databuf + ctx->ssl_rb_off, sz);
+        ctx->ssl_rb_off += sz;
+        if (ctx->ssl_rb_off >= ctx->ssl_rb_len) {
+            ctx->ssl_rb_len = 0;
+            ctx->ssl_rb_off = 0;
+        }
+        return sz;
+    } else {
+        return WOLFSSL_CBIO_ERR_WANT_READ;
+    }
+}
+
+/* uIP DTLS Generate Cookie callback
+ *  return : number of bytes copied into buf, or error
+ */
+int uIPGenerateCookie(WOLFSSL* ssl, byte *buf, int sz, void *_ctx)
+{
+    uip_wolfssl_ctx *ctx = (uip_wolfssl_ctx *)_ctx;
+    byte token[32];
+    byte digest[WC_SHA_DIGEST_SIZE];
+    int  ret = 0;
+    XMEMSET(token, 0, sizeof(token));
+    XMEMCPY(token, &ctx->peer_addr, sizeof(uip_ipaddr_t));
+    XMEMCPY(token + sizeof(uip_ipaddr_t), &ctx->peer_port, sizeof(word16));
+    ret = wc_ShaHash(token, sizeof(uip_ipaddr_t) + sizeof(word16), digest);
+    if (ret != 0)
+        return ret;
+    if (sz > WC_SHA_DIGEST_SIZE)
+        sz = WC_SHA_DIGEST_SIZE;
+    XMEMCPY(buf, digest, sz);
+    return sz;
+}
+
+#endif /* WOLFSSL_UIP */
+
+#ifdef WOLFSSL_GNRC
+
+#include <net/sock.h>
+#include <net/sock/tcp.h>
+#include <stdio.h>
+
+/* GNRC TCP/IP port, using the native tcp/udp socket api.
+ * TCP and UDP are currently supported with the callbacks below.
+ *
+ */
+/* The GNRC tcp send callback
+ * return : bytes sent, or error
+ */
+
+int GNRC_SendTo(WOLFSSL* ssl, char* buf, int sz, void* _ctx)
+{
+    sock_tls_t *ctx = (sock_tls_t *)_ctx;
+    int ret = 0;
+    (void)ssl;
+    if (!ctx)
+        return WOLFSSL_CBIO_ERR_GENERAL;
+    ret = sock_udp_send(&ctx->conn.udp, (unsigned char *)buf, sz, &ctx->peer_addr);
+    if (ret == 0)
+        return WOLFSSL_CBIO_ERR_WANT_WRITE;
+    return ret;
+}
+
+/* The GNRC TCP/IP receive callback
+ *  return : nb bytes read, or error
+ */
+int GNRC_ReceiveFrom(WOLFSSL *ssl, char *buf, int sz, void *_ctx)
+{
+    sock_udp_ep_t ep;
+    int ret;
+    uint32_t timeout = wolfSSL_dtls_get_current_timeout(ssl) * 1000000;
+    sock_tls_t *ctx = (sock_tls_t *)_ctx;
+    if (!ctx)
+        return WOLFSSL_CBIO_ERR_GENERAL;
+    (void)ssl;
+    if (wolfSSL_get_using_nonblock(ctx->ssl)) {
+        timeout = 0;
+    }
+    ret = sock_udp_recv(&ctx->conn.udp, buf, sz, timeout, &ep);
+    if (ret > 0) {
+        if (ctx->peer_addr.port == 0)
+            XMEMCPY(&ctx->peer_addr, &ep, sizeof(sock_udp_ep_t));
+    }
+    if (ret == -ETIMEDOUT) {
+        return WOLFSSL_CBIO_ERR_WANT_READ;
+    }
+    return ret;
+}
+
+/* GNRC DTLS Generate Cookie callback
+ *  return : number of bytes copied into buf, or error
+ */
+#define GNRC_MAX_TOKEN_SIZE (32)
+int GNRC_GenerateCookie(WOLFSSL* ssl, byte *buf, int sz, void *_ctx)
+{
+    sock_tls_t *ctx = (sock_tls_t *)_ctx;
+    if (!ctx)
+        return WOLFSSL_CBIO_ERR_GENERAL;
+    byte token[GNRC_MAX_TOKEN_SIZE];
+    byte digest[WC_SHA_DIGEST_SIZE];
+    int  ret = 0;
+    size_t token_size = sizeof(sock_udp_ep_t);
+    (void)ssl;
+    if (token_size > GNRC_MAX_TOKEN_SIZE)
+        token_size = GNRC_MAX_TOKEN_SIZE;
+    XMEMSET(token, 0, GNRC_MAX_TOKEN_SIZE);
+    XMEMCPY(token, &ctx->peer_addr, token_size);
+    ret = wc_ShaHash(token, token_size, digest);
+    if (ret != 0)
+        return ret;
+    if (sz > WC_SHA_DIGEST_SIZE)
+        sz = WC_SHA_DIGEST_SIZE;
+    XMEMCPY(buf, digest, sz);
+    return sz;
+}
+
+#endif /* WOLFSSL_GNRC */
+
+#endif /* WOLFCRYPT_ONLY */
Index: azure_iot_hub_f767zi/trunk/wolfssl-4.4.0/user_settings.h
===================================================================
--- azure_iot_hub_f767zi/trunk/wolfssl-4.4.0/user_settings.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/wolfssl-4.4.0/user_settings.h	(revision 457)
@@ -0,0 +1,55 @@
+//#define DEBUG_WOLFSSL
+
+#define WOLFSSL_LWIP
+#define NO_WOLFSSL_DIR
+#define NO_WRITEV
+
+#ifndef HAVE_LIBZ
+#define HAVE_LIBZ
+#endif
+#define HAVE_ECC
+#define HAVE_AESGCM
+//#define HAVE_FIPS
+#define HAVE_TLS_EXTENSIONS
+#define HAVE_SNI
+#define HAVE_SUPPORTED_CURVES
+
+#define ECC_TIMING_RESISTANT
+#define TFM_TIMING_RESISTANT
+
+#define WOLFSSL_RIPEMD
+#define WOLFSSL_SHA512
+#define WOLFSSL_SHA384
+#define WOLFSSL_SMALL_STACK
+// curlÅgpµÄ¢é
+#define WOLFSSL_ALLOW_TLSV10
+
+#define WOLFSSL_CERT_EXT
+
+#define WC_RSA_BLINDING
+
+#define SINGLE_THREADED
+
+#define CUSTOM_RAND_GENERATE_SEED custom_rand_generate_seed
+
+#define WOLFSSL_USER_FILESYSTEM
+#include <stdio.h>
+#include <fcntl.h>
+
+#define XFILE      FILE*
+#define XFOPEN     fopen
+#define XFSEEK     fseek
+#define XFTELL     ftell
+#define XREWIND    rewind
+#define XFREAD     fread
+#define XFWRITE    fwrite
+#define XFCLOSE    fclose
+#define XSEEK_END  SEEK_END
+#define XBADFILE   NULL
+#define XFGETS     fgets
+
+struct WOLFSSL;
+int EmbedReceive(struct WOLFSSL *ssl, char *buf, int sz, void *_ctx);
+int EmbedSend(struct WOLFSSL* ssl, char* buf, int sz, void* _ctx);
+
+/* WOLFSSL_USER_FILESYSTEM */
Index: azure_iot_hub_f767zi/trunk/wolfssl-4.4.0/wolfcrypt/src/aes.c
===================================================================
--- azure_iot_hub_f767zi/trunk/wolfssl-4.4.0/wolfcrypt/src/aes.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/wolfssl-4.4.0/wolfcrypt/src/aes.c	(revision 457)
@@ -0,0 +1,8704 @@
+/* aes.c
+ *
+ * Copyright (C) 2006-2020 wolfSSL Inc.
+ *
+ * This file is part of wolfSSL.
+ *
+ * wolfSSL is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * wolfSSL is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
+ */
+
+
+#ifdef HAVE_CONFIG_H
+    #include <config.h>
+#endif
+
+#include <wolfssl/wolfcrypt/settings.h>
+#include <wolfssl/wolfcrypt/error-crypt.h>
+
+#if !defined(NO_AES)
+
+/* Tip: Locate the software cipher modes by searching for "Software AES" */
+
+#if defined(HAVE_FIPS) && \
+    defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION >= 2)
+
+    /* set NO_WRAPPERS before headers, use direct internal f()s not wrappers */
+    #define FIPS_NO_WRAPPERS
+
+    #ifdef USE_WINDOWS_API
+        #pragma code_seg(".fipsA$g")
+        #pragma const_seg(".fipsB$g")
+    #endif
+#endif
+
+#include <wolfssl/wolfcrypt/aes.h>
+#include <wolfssl/wolfcrypt/cpuid.h>
+
+#ifdef WOLF_CRYPTO_CB
+    #include <wolfssl/wolfcrypt/cryptocb.h>
+#endif
+
+
+/* fips wrapper calls, user can call direct */
+#if defined(HAVE_FIPS) && \
+    (!defined(HAVE_FIPS_VERSION) || (HAVE_FIPS_VERSION < 2))
+
+    int wc_AesSetKey(Aes* aes, const byte* key, word32 len, const byte* iv,
+                              int dir)
+    {
+        if (aes == NULL ||  !( (len == 16) || (len == 24) || (len == 32)) ) {
+            return BAD_FUNC_ARG;
+        }
+
+        return AesSetKey_fips(aes, key, len, iv, dir);
+    }
+    int wc_AesSetIV(Aes* aes, const byte* iv)
+    {
+        if (aes == NULL) {
+            return BAD_FUNC_ARG;
+        }
+
+        return AesSetIV_fips(aes, iv);
+    }
+    #ifdef HAVE_AES_CBC
+        int wc_AesCbcEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
+        {
+            if (aes == NULL || out == NULL || in == NULL) {
+                return BAD_FUNC_ARG;
+            }
+
+            return AesCbcEncrypt_fips(aes, out, in, sz);
+        }
+        #ifdef HAVE_AES_DECRYPT
+            int wc_AesCbcDecrypt(Aes* aes, byte* out, const byte* in, word32 sz)
+            {
+                if (aes == NULL || out == NULL || in == NULL
+                                            || sz % AES_BLOCK_SIZE != 0) {
+                    return BAD_FUNC_ARG;
+                }
+
+                return AesCbcDecrypt_fips(aes, out, in, sz);
+            }
+        #endif /* HAVE_AES_DECRYPT */
+    #endif /* HAVE_AES_CBC */
+
+    /* AES-CTR */
+    #ifdef WOLFSSL_AES_COUNTER
+        int wc_AesCtrEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
+        {
+            if (aes == NULL || out == NULL || in == NULL) {
+                return BAD_FUNC_ARG;
+            }
+
+            return AesCtrEncrypt(aes, out, in, sz);
+        }
+    #endif
+
+    /* AES-DIRECT */
+    #if defined(WOLFSSL_AES_DIRECT)
+        void wc_AesEncryptDirect(Aes* aes, byte* out, const byte* in)
+        {
+            AesEncryptDirect(aes, out, in);
+        }
+
+        #ifdef HAVE_AES_DECRYPT
+            void wc_AesDecryptDirect(Aes* aes, byte* out, const byte* in)
+            {
+                AesDecryptDirect(aes, out, in);
+            }
+        #endif /* HAVE_AES_DECRYPT */
+
+        int wc_AesSetKeyDirect(Aes* aes, const byte* key, word32 len,
+                                        const byte* iv, int dir)
+        {
+            return AesSetKeyDirect(aes, key, len, iv, dir);
+        }
+    #endif /* WOLFSSL_AES_DIRECT */
+
+    /* AES-GCM */
+    #ifdef HAVE_AESGCM
+        int wc_AesGcmSetKey(Aes* aes, const byte* key, word32 len)
+        {
+            if (aes == NULL || !( (len == 16) || (len == 24) || (len == 32)) ) {
+                return BAD_FUNC_ARG;
+            }
+
+            return AesGcmSetKey_fips(aes, key, len);
+        }
+        int wc_AesGcmEncrypt(Aes* aes, byte* out, const byte* in, word32 sz,
+                                      const byte* iv, word32 ivSz,
+                                      byte* authTag, word32 authTagSz,
+                                      const byte* authIn, word32 authInSz)
+        {
+            if (aes == NULL || authTagSz > AES_BLOCK_SIZE ||
+                        authTagSz < WOLFSSL_MIN_AUTH_TAG_SZ ||
+                        ivSz == 0 || ivSz > AES_BLOCK_SIZE) {
+                return BAD_FUNC_ARG;
+            }
+
+            return AesGcmEncrypt_fips(aes, out, in, sz, iv, ivSz, authTag,
+                authTagSz, authIn, authInSz);
+        }
+
+        #ifdef HAVE_AES_DECRYPT
+            int wc_AesGcmDecrypt(Aes* aes, byte* out, const byte* in, word32 sz,
+                                          const byte* iv, word32 ivSz,
+                                          const byte* authTag, word32 authTagSz,
+                                          const byte* authIn, word32 authInSz)
+            {
+                if (aes == NULL || out == NULL || in == NULL || iv == NULL
+                        || authTag == NULL || authTagSz > AES_BLOCK_SIZE ||
+                        ivSz == 0 || ivSz > AES_BLOCK_SIZE) {
+                    return BAD_FUNC_ARG;
+                }
+
+                return AesGcmDecrypt_fips(aes, out, in, sz, iv, ivSz, authTag,
+                    authTagSz, authIn, authInSz);
+            }
+        #endif /* HAVE_AES_DECRYPT */
+
+        int wc_GmacSetKey(Gmac* gmac, const byte* key, word32 len)
+        {
+            if (gmac == NULL || key == NULL || !((len == 16) ||
+                                (len == 24) || (len == 32)) ) {
+                return BAD_FUNC_ARG;
+            }
+
+            return GmacSetKey(gmac, key, len);
+        }
+        int wc_GmacUpdate(Gmac* gmac, const byte* iv, word32 ivSz,
+                                      const byte* authIn, word32 authInSz,
+                                      byte* authTag, word32 authTagSz)
+        {
+            if (gmac == NULL || authTagSz > AES_BLOCK_SIZE ||
+                               authTagSz < WOLFSSL_MIN_AUTH_TAG_SZ) {
+                return BAD_FUNC_ARG;
+            }
+
+            return GmacUpdate(gmac, iv, ivSz, authIn, authInSz,
+                              authTag, authTagSz);
+        }
+    #endif /* HAVE_AESGCM */
+
+    /* AES-CCM */
+    #if defined(HAVE_AESCCM) && \
+        defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION >= 2)
+        int wc_AesCcmSetKey(Aes* aes, const byte* key, word32 keySz)
+        {
+            return AesCcmSetKey(aes, key, keySz);
+        }
+        int wc_AesCcmEncrypt(Aes* aes, byte* out, const byte* in, word32 inSz,
+                                      const byte* nonce, word32 nonceSz,
+                                      byte* authTag, word32 authTagSz,
+                                      const byte* authIn, word32 authInSz)
+        {
+            /* sanity check on arguments */
+            if (aes == NULL || out == NULL || in == NULL || nonce == NULL
+                    || authTag == NULL || nonceSz < 7 || nonceSz > 13)
+                return BAD_FUNC_ARG;
+
+            AesCcmEncrypt(aes, out, in, inSz, nonce, nonceSz, authTag,
+                authTagSz, authIn, authInSz);
+            return 0;
+        }
+
+        #ifdef HAVE_AES_DECRYPT
+            int  wc_AesCcmDecrypt(Aes* aes, byte* out,
+                const byte* in, word32 inSz,
+                const byte* nonce, word32 nonceSz,
+                const byte* authTag, word32 authTagSz,
+                const byte* authIn, word32 authInSz)
+            {
+
+                if (aes == NULL || out == NULL || in == NULL || nonce == NULL
+                    || authTag == NULL || nonceSz < 7 || nonceSz > 13) {
+                        return BAD_FUNC_ARG;
+                }
+
+                return AesCcmDecrypt(aes, out, in, inSz, nonce, nonceSz,
+                    authTag, authTagSz, authIn, authInSz);
+            }
+        #endif /* HAVE_AES_DECRYPT */
+    #endif /* HAVE_AESCCM && HAVE_FIPS_VERSION 2 */
+
+    int wc_AesInit(Aes* aes, void* h, int i)
+    {
+        if (aes == NULL)
+            return BAD_FUNC_ARG;
+
+        (void)h;
+        (void)i;
+
+        /* FIPS doesn't support:
+            return AesInit(aes, h, i); */
+        return 0;
+    }
+    void wc_AesFree(Aes* aes)
+    {
+        (void)aes;
+        /* FIPS doesn't support:
+            AesFree(aes); */
+    }
+
+#else /* else build without fips, or for FIPS v2 */
+
+
+#if defined(WOLFSSL_TI_CRYPT)
+    #include <wolfcrypt/src/port/ti/ti-aes.c>
+#else
+
+#include <wolfssl/wolfcrypt/logging.h>
+
+#ifdef NO_INLINE
+    #include <wolfssl/wolfcrypt/misc.h>
+#else
+    #define WOLFSSL_MISC_INCLUDED
+    #include <wolfcrypt/src/misc.c>
+#endif
+
+#if !defined(WOLFSSL_ARMASM)
+
+#ifdef WOLFSSL_IMX6_CAAM_BLOB
+    /* case of possibly not using hardware acceleration for AES but using key
+       blobs */
+    #include <wolfssl/wolfcrypt/port/caam/wolfcaam.h>
+#endif
+
+#ifdef DEBUG_AESNI
+    #include <stdio.h>
+#endif
+
+#ifdef _MSC_VER
+    /* 4127 warning constant while(1)  */
+    #pragma warning(disable: 4127)
+#endif
+
+
+/* Define AES implementation includes and functions */
+#if defined(STM32_CRYPTO)
+     /* STM32F2/F4/F7/L4 hardware AES support for ECB, CBC, CTR and GCM modes */
+
+#if defined(WOLFSSL_AES_DIRECT) || defined(HAVE_AESGCM) || defined(HAVE_AESCCM)
+
+    static int wc_AesEncrypt(Aes* aes, const byte* inBlock, byte* outBlock)
+    {
+        int ret = 0;
+    #ifdef WOLFSSL_STM32_CUBEMX
+        CRYP_HandleTypeDef hcryp;
+    #else
+        CRYP_InitTypeDef cryptInit;
+        CRYP_KeyInitTypeDef keyInit;
+    #endif
+
+    #ifdef WOLFSSL_STM32_CUBEMX
+        ret = wc_Stm32_Aes_Init(aes, &hcryp);
+        if (ret != 0)
+            return ret;
+
+    #ifdef STM32_CRYPTO_AES_ONLY
+        hcryp.Init.OperatingMode = CRYP_ALGOMODE_ENCRYPT;
+        hcryp.Init.ChainingMode  = CRYP_CHAINMODE_AES_ECB;
+        hcryp.Init.KeyWriteFlag  = CRYP_KEY_WRITE_ENABLE;
+    #elif defined(STM32_HAL_V2)
+        hcryp.Init.Algorithm  = CRYP_AES_ECB;
+    #endif
+        HAL_CRYP_Init(&hcryp);
+
+    #ifdef STM32_CRYPTO_AES_ONLY
+        ret = HAL_CRYPEx_AES(&hcryp, (uint8_t*)inBlock, AES_BLOCK_SIZE,
+            outBlock, STM32_HAL_TIMEOUT);
+    #elif defined(STM32_HAL_V2)
+        ret = HAL_CRYP_Encrypt(&hcryp, (uint32_t*)inBlock, AES_BLOCK_SIZE,
+            (uint32_t*)outBlock, STM32_HAL_TIMEOUT);
+    #else
+        ret = HAL_CRYP_AESECB_Encrypt(&hcryp, (uint8_t*)inBlock, AES_BLOCK_SIZE,
+            outBlock, STM32_HAL_TIMEOUT);
+    #endif
+        if (ret != HAL_OK) {
+            ret = WC_TIMEOUT_E;
+        }
+        HAL_CRYP_DeInit(&hcryp);
+
+    #else /* STD_PERI_LIB */
+        ret = wc_Stm32_Aes_Init(aes, &cryptInit, &keyInit);
+        if (ret != 0)
+            return ret;
+
+        /* reset registers to their default values */
+        CRYP_DeInit();
+
+        /* setup key */
+        CRYP_KeyInit(&keyInit);
+
+        /* set direction and mode */
+        cryptInit.CRYP_AlgoDir  = CRYP_AlgoDir_Encrypt;
+        cryptInit.CRYP_AlgoMode = CRYP_AlgoMode_AES_ECB;
+        CRYP_Init(&cryptInit);
+
+        /* enable crypto processor */
+        CRYP_Cmd(ENABLE);
+
+        /* flush IN/OUT FIFOs */
+        CRYP_FIFOFlush();
+
+        CRYP_DataIn(*(uint32_t*)&inBlock[0]);
+        CRYP_DataIn(*(uint32_t*)&inBlock[4]);
+        CRYP_DataIn(*(uint32_t*)&inBlock[8]);
+        CRYP_DataIn(*(uint32_t*)&inBlock[12]);
+
+        /* wait until the complete message has been processed */
+        while (CRYP_GetFlagStatus(CRYP_FLAG_BUSY) != RESET) {}
+
+        *(uint32_t*)&outBlock[0]  = CRYP_DataOut();
+        *(uint32_t*)&outBlock[4]  = CRYP_DataOut();
+        *(uint32_t*)&outBlock[8]  = CRYP_DataOut();
+        *(uint32_t*)&outBlock[12] = CRYP_DataOut();
+
+        /* disable crypto processor */
+        CRYP_Cmd(DISABLE);
+    #endif /* WOLFSSL_STM32_CUBEMX */
+
+        return ret;
+    }
+#endif /* WOLFSSL_AES_DIRECT || HAVE_AESGCM || HAVE_AESCCM */
+
+#ifdef HAVE_AES_DECRYPT
+    #if defined(WOLFSSL_AES_DIRECT) || defined(HAVE_AESCCM)
+    static int wc_AesDecrypt(Aes* aes, const byte* inBlock, byte* outBlock)
+    {
+        int ret = 0;
+    #ifdef WOLFSSL_STM32_CUBEMX
+        CRYP_HandleTypeDef hcryp;
+    #else
+        CRYP_InitTypeDef cryptInit;
+        CRYP_KeyInitTypeDef keyInit;
+    #endif
+
+    #ifdef WOLFSSL_STM32_CUBEMX
+        ret = wc_Stm32_Aes_Init(aes, &hcryp);
+        if (ret != 0)
+            return ret;
+
+    #ifdef STM32_CRYPTO_AES_ONLY
+        hcryp.Init.OperatingMode = CRYP_ALGOMODE_DECRYPT;
+        hcryp.Init.ChainingMode  = CRYP_CHAINMODE_AES_ECB;
+        hcryp.Init.KeyWriteFlag  = CRYP_KEY_WRITE_ENABLE;
+    #elif defined(STM32_HAL_V2)
+        hcryp.Init.Algorithm  = CRYP_AES_ECB;
+    #endif
+        HAL_CRYP_Init(&hcryp);
+
+    #ifdef STM32_CRYPTO_AES_ONLY
+        ret = HAL_CRYPEx_AES(&hcryp, (uint8_t*)inBlock, AES_BLOCK_SIZE,
+            outBlock, STM32_HAL_TIMEOUT);
+    #elif defined(STM32_HAL_V2)
+        ret = HAL_CRYP_Decrypt(&hcryp, (uint32_t*)inBlock, AES_BLOCK_SIZE,
+            (uint32_t*)outBlock, STM32_HAL_TIMEOUT);
+    #else
+        ret = HAL_CRYP_AESECB_Decrypt(&hcryp, (uint8_t*)inBlock, AES_BLOCK_SIZE,
+            outBlock, STM32_HAL_TIMEOUT);
+    #endif
+        if (ret != HAL_OK) {
+            ret = WC_TIMEOUT_E;
+        }
+        HAL_CRYP_DeInit(&hcryp);
+
+    #else /* STD_PERI_LIB */
+        ret = wc_Stm32_Aes_Init(aes, &cryptInit, &keyInit);
+        if (ret != 0)
+            return ret;
+
+        /* reset registers to their default values */
+        CRYP_DeInit();
+
+        /* set direction and key */
+        CRYP_KeyInit(&keyInit);
+        cryptInit.CRYP_AlgoDir  = CRYP_AlgoDir_Decrypt;
+        cryptInit.CRYP_AlgoMode = CRYP_AlgoMode_AES_Key;
+        CRYP_Init(&cryptInit);
+
+        /* enable crypto processor */
+        CRYP_Cmd(ENABLE);
+
+        /* wait until decrypt key has been initialized */
+        while (CRYP_GetFlagStatus(CRYP_FLAG_BUSY) != RESET) {}
+
+        /* set direction and mode */
+        cryptInit.CRYP_AlgoDir  = CRYP_AlgoDir_Decrypt;
+        cryptInit.CRYP_AlgoMode = CRYP_AlgoMode_AES_ECB;
+        CRYP_Init(&cryptInit);
+
+        /* enable crypto processor */
+        CRYP_Cmd(ENABLE);
+
+        /* flush IN/OUT FIFOs */
+        CRYP_FIFOFlush();
+
+        CRYP_DataIn(*(uint32_t*)&inBlock[0]);
+        CRYP_DataIn(*(uint32_t*)&inBlock[4]);
+        CRYP_DataIn(*(uint32_t*)&inBlock[8]);
+        CRYP_DataIn(*(uint32_t*)&inBlock[12]);
+
+        /* wait until the complete message has been processed */
+        while (CRYP_GetFlagStatus(CRYP_FLAG_BUSY) != RESET) {}
+
+        *(uint32_t*)&outBlock[0]  = CRYP_DataOut();
+        *(uint32_t*)&outBlock[4]  = CRYP_DataOut();
+        *(uint32_t*)&outBlock[8]  = CRYP_DataOut();
+        *(uint32_t*)&outBlock[12] = CRYP_DataOut();
+
+        /* disable crypto processor */
+        CRYP_Cmd(DISABLE);
+    #endif /* WOLFSSL_STM32_CUBEMX */
+
+        return ret;
+    }
+    #endif /* WOLFSSL_AES_DIRECT || HAVE_AESCCM */
+#endif /* HAVE_AES_DECRYPT */
+
+#elif defined(HAVE_COLDFIRE_SEC)
+    /* Freescale Coldfire SEC support for CBC mode.
+     * NOTE: no support for AES-CTR/GCM/CCM/Direct */
+    #include <wolfssl/wolfcrypt/types.h>
+    #include "sec.h"
+    #include "mcf5475_sec.h"
+    #include "mcf5475_siu.h"
+#elif defined(FREESCALE_LTC)
+    #include "fsl_ltc.h"
+    #if defined(FREESCALE_LTC_AES_GCM)
+        #undef NEED_AES_TABLES
+        #undef GCM_TABLE
+    #else
+        /* if LTC doesn't have GCM, use software with LTC AES ECB mode */
+        static int wc_AesEncrypt(Aes* aes, const byte* inBlock, byte* outBlock)
+        {
+            wc_AesEncryptDirect(aes, outBlock, inBlock);
+            return 0;
+        }
+        static int wc_AesDecrypt(Aes* aes, const byte* inBlock, byte* outBlock)
+        {
+            wc_AesDecryptDirect(aes, outBlock, inBlock);
+            return 0;
+        }
+    #endif
+#elif defined(FREESCALE_MMCAU)
+    /* Freescale mmCAU hardware AES support for Direct, CBC, CCM, GCM modes
+     * through the CAU/mmCAU library. Documentation located in
+     * ColdFire/ColdFire+ CAU and Kinetis mmCAU Software Library User
+     * Guide (See note in README). */
+    #ifdef FREESCALE_MMCAU_CLASSIC
+        /* MMCAU 1.4 library used with non-KSDK / classic MQX builds */
+        #include "cau_api.h"
+    #else
+        #include "fsl_mmcau.h"
+    #endif
+
+    static int wc_AesEncrypt(Aes* aes, const byte* inBlock, byte* outBlock)
+    {
+        int ret;
+
+    #ifdef FREESCALE_MMCAU_CLASSIC
+        if ((wolfssl_word)outBlock % WOLFSSL_MMCAU_ALIGNMENT) {
+            WOLFSSL_MSG("Bad cau_aes_encrypt alignment");
+            return BAD_ALIGN_E;
+        }
+    #endif
+
+        ret = wolfSSL_CryptHwMutexLock();
+        if(ret == 0) {
+        #ifdef FREESCALE_MMCAU_CLASSIC
+            cau_aes_encrypt(inBlock, (byte*)aes->key, aes->rounds, outBlock);
+        #else
+            MMCAU_AES_EncryptEcb(inBlock, (byte*)aes->key, aes->rounds,
+                                 outBlock);
+        #endif
+            wolfSSL_CryptHwMutexUnLock();
+        }
+        return ret;
+    }
+    #ifdef HAVE_AES_DECRYPT
+    static int wc_AesDecrypt(Aes* aes, const byte* inBlock, byte* outBlock)
+    {
+        int ret;
+
+    #ifdef FREESCALE_MMCAU_CLASSIC
+        if ((wolfssl_word)outBlock % WOLFSSL_MMCAU_ALIGNMENT) {
+            WOLFSSL_MSG("Bad cau_aes_decrypt alignment");
+            return BAD_ALIGN_E;
+        }
+    #endif
+
+        ret = wolfSSL_CryptHwMutexLock();
+        if(ret == 0) {
+        #ifdef FREESCALE_MMCAU_CLASSIC
+            cau_aes_decrypt(inBlock, (byte*)aes->key, aes->rounds, outBlock);
+        #else
+            MMCAU_AES_DecryptEcb(inBlock, (byte*)aes->key, aes->rounds,
+                                 outBlock);
+        #endif
+            wolfSSL_CryptHwMutexUnLock();
+        }
+        return ret;
+    }
+    #endif /* HAVE_AES_DECRYPT */
+
+#elif defined(WOLFSSL_PIC32MZ_CRYPT)
+
+    #include <wolfssl/wolfcrypt/port/pic32/pic32mz-crypt.h>
+
+    #if defined(HAVE_AESGCM) || defined(WOLFSSL_AES_DIRECT)
+    static int wc_AesEncrypt(Aes* aes, const byte* inBlock, byte* outBlock)
+    {
+        return wc_Pic32AesCrypt(aes->key, aes->keylen, NULL, 0,
+            outBlock, inBlock, AES_BLOCK_SIZE,
+            PIC32_ENCRYPTION, PIC32_ALGO_AES, PIC32_CRYPTOALGO_RECB);
+    }
+    #endif
+
+    #if defined(HAVE_AES_DECRYPT) && defined(WOLFSSL_AES_DIRECT)
+    static int wc_AesDecrypt(Aes* aes, const byte* inBlock, byte* outBlock)
+    {
+        return wc_Pic32AesCrypt(aes->key, aes->keylen, NULL, 0,
+            outBlock, inBlock, AES_BLOCK_SIZE,
+            PIC32_DECRYPTION, PIC32_ALGO_AES, PIC32_CRYPTOALGO_RECB);
+    }
+    #endif
+
+#elif defined(WOLFSSL_NRF51_AES)
+    /* Use built-in AES hardware - AES 128 ECB Encrypt Only */
+    #include "wolfssl/wolfcrypt/port/nrf51.h"
+
+    static int wc_AesEncrypt(Aes* aes, const byte* inBlock, byte* outBlock)
+    {
+        return nrf51_aes_encrypt(inBlock, (byte*)aes->key, aes->rounds, outBlock);
+    }
+
+    #ifdef HAVE_AES_DECRYPT
+        #error nRF51 AES Hardware does not support decrypt
+    #endif /* HAVE_AES_DECRYPT */
+
+#elif defined(WOLFSSL_ESP32WROOM32_CRYPT) && \
+    !defined(NO_WOLFSSL_ESP32WROOM32_CRYPT_AES)
+
+    #include "wolfssl/wolfcrypt/port/Espressif/esp32-crypt.h"
+
+    #if defined(HAVE_AESGCM) || defined(WOLFSSL_AES_DIRECT)
+    static int wc_AesEncrypt(Aes* aes, const byte* inBlock, byte* outBlock)
+    {
+        return wc_esp32AesEncrypt(aes, inBlock, outBlock);
+    }
+    #endif
+
+    #if defined(HAVE_AES_DECRYPT) && defined(WOLFSSL_AES_DIRECT)
+    static int wc_AesDecrypt(Aes* aes, const byte* inBlock, byte* outBlock)
+    {
+       return wc_esp32AesDecrypt(aes, inBlock, outBlock);
+    }
+    #endif
+
+#elif defined(WOLFSSL_AESNI)
+
+    #define NEED_AES_TABLES
+
+    /* Each platform needs to query info type 1 from cpuid to see if aesni is
+     * supported. Also, let's setup a macro for proper linkage w/o ABI conflicts
+     */
+
+    #ifndef AESNI_ALIGN
+        #define AESNI_ALIGN 16
+    #endif
+
+    #ifdef _MSC_VER
+        #define XASM_LINK(f)
+    #elif defined(__APPLE__)
+        #define XASM_LINK(f) asm("_" f)
+    #else
+        #define XASM_LINK(f) asm(f)
+    #endif /* _MSC_VER */
+
+    static int checkAESNI = 0;
+    static int haveAESNI  = 0;
+    static word32 intel_flags = 0;
+
+    static int Check_CPU_support_AES(void)
+    {
+        intel_flags = cpuid_get_flags();
+
+        return IS_INTEL_AESNI(intel_flags) != 0;
+    }
+
+
+    /* tell C compiler these are asm functions in case any mix up of ABI underscore
+       prefix between clang/gcc/llvm etc */
+    #ifdef HAVE_AES_CBC
+        void AES_CBC_encrypt(const unsigned char* in, unsigned char* out,
+                             unsigned char* ivec, unsigned long length,
+                             const unsigned char* KS, int nr)
+                             XASM_LINK("AES_CBC_encrypt");
+
+        #ifdef HAVE_AES_DECRYPT
+            #if defined(WOLFSSL_AESNI_BY4)
+                void AES_CBC_decrypt_by4(const unsigned char* in, unsigned char* out,
+                                         unsigned char* ivec, unsigned long length,
+                                         const unsigned char* KS, int nr)
+                                         XASM_LINK("AES_CBC_decrypt_by4");
+            #elif defined(WOLFSSL_AESNI_BY6)
+                void AES_CBC_decrypt_by6(const unsigned char* in, unsigned char* out,
+                                         unsigned char* ivec, unsigned long length,
+                                         const unsigned char* KS, int nr)
+                                         XASM_LINK("AES_CBC_decrypt_by6");
+            #else /* WOLFSSL_AESNI_BYx */
+                void AES_CBC_decrypt_by8(const unsigned char* in, unsigned char* out,
+                                         unsigned char* ivec, unsigned long length,
+                                         const unsigned char* KS, int nr)
+                                         XASM_LINK("AES_CBC_decrypt_by8");
+            #endif /* WOLFSSL_AESNI_BYx */
+        #endif /* HAVE_AES_DECRYPT */
+    #endif /* HAVE_AES_CBC */
+
+    void AES_ECB_encrypt(const unsigned char* in, unsigned char* out,
+                         unsigned long length, const unsigned char* KS, int nr)
+                         XASM_LINK("AES_ECB_encrypt");
+
+    #ifdef HAVE_AES_DECRYPT
+        void AES_ECB_decrypt(const unsigned char* in, unsigned char* out,
+                             unsigned long length, const unsigned char* KS, int nr)
+                             XASM_LINK("AES_ECB_decrypt");
+    #endif
+
+    void AES_128_Key_Expansion(const unsigned char* userkey,
+                               unsigned char* key_schedule)
+                               XASM_LINK("AES_128_Key_Expansion");
+
+    void AES_192_Key_Expansion(const unsigned char* userkey,
+                               unsigned char* key_schedule)
+                               XASM_LINK("AES_192_Key_Expansion");
+
+    void AES_256_Key_Expansion(const unsigned char* userkey,
+                               unsigned char* key_schedule)
+                               XASM_LINK("AES_256_Key_Expansion");
+
+
+    static int AES_set_encrypt_key(const unsigned char *userKey, const int bits,
+                                   Aes* aes)
+    {
+        int ret;
+
+        if (!userKey || !aes)
+            return BAD_FUNC_ARG;
+
+        switch (bits) {
+            case 128:
+               AES_128_Key_Expansion (userKey,(byte*)aes->key); aes->rounds = 10;
+               return 0;
+            case 192:
+               AES_192_Key_Expansion (userKey,(byte*)aes->key); aes->rounds = 12;
+               return 0;
+            case 256:
+               AES_256_Key_Expansion (userKey,(byte*)aes->key); aes->rounds = 14;
+               return 0;
+            default:
+                ret = BAD_FUNC_ARG;
+        }
+
+        return ret;
+    }
+
+    #ifdef HAVE_AES_DECRYPT
+        static int AES_set_decrypt_key(const unsigned char* userKey,
+                                                    const int bits, Aes* aes)
+        {
+            int nr;
+            Aes temp_key;
+            __m128i *Key_Schedule = (__m128i*)aes->key;
+            __m128i *Temp_Key_Schedule = (__m128i*)temp_key.key;
+
+            if (!userKey || !aes)
+                return BAD_FUNC_ARG;
+
+            if (AES_set_encrypt_key(userKey,bits,&temp_key) == BAD_FUNC_ARG)
+                return BAD_FUNC_ARG;
+
+            nr = temp_key.rounds;
+            aes->rounds = nr;
+
+            Key_Schedule[nr] = Temp_Key_Schedule[0];
+            Key_Schedule[nr-1] = _mm_aesimc_si128(Temp_Key_Schedule[1]);
+            Key_Schedule[nr-2] = _mm_aesimc_si128(Temp_Key_Schedule[2]);
+            Key_Schedule[nr-3] = _mm_aesimc_si128(Temp_Key_Schedule[3]);
+            Key_Schedule[nr-4] = _mm_aesimc_si128(Temp_Key_Schedule[4]);
+            Key_Schedule[nr-5] = _mm_aesimc_si128(Temp_Key_Schedule[5]);
+            Key_Schedule[nr-6] = _mm_aesimc_si128(Temp_Key_Schedule[6]);
+            Key_Schedule[nr-7] = _mm_aesimc_si128(Temp_Key_Schedule[7]);
+            Key_Schedule[nr-8] = _mm_aesimc_si128(Temp_Key_Schedule[8]);
+            Key_Schedule[nr-9] = _mm_aesimc_si128(Temp_Key_Schedule[9]);
+
+            if (nr>10) {
+                Key_Schedule[nr-10] = _mm_aesimc_si128(Temp_Key_Schedule[10]);
+                Key_Schedule[nr-11] = _mm_aesimc_si128(Temp_Key_Schedule[11]);
+            }
+
+            if (nr>12) {
+                Key_Schedule[nr-12] = _mm_aesimc_si128(Temp_Key_Schedule[12]);
+                Key_Schedule[nr-13] = _mm_aesimc_si128(Temp_Key_Schedule[13]);
+            }
+
+            Key_Schedule[0] = Temp_Key_Schedule[nr];
+
+            return 0;
+        }
+    #endif /* HAVE_AES_DECRYPT */
+
+#elif (defined(WOLFSSL_IMX6_CAAM) && !defined(NO_IMX6_CAAM_AES)) || \
+      ((defined(WOLFSSL_AFALG) || defined(WOLFSSL_DEVCRYPTO_AES)) && \
+        defined(HAVE_AESCCM))
+        static int wc_AesEncrypt(Aes* aes, const byte* inBlock, byte* outBlock)
+        {
+            wc_AesEncryptDirect(aes, outBlock, inBlock);
+            return 0;
+        }
+
+#elif defined(WOLFSSL_AFALG)
+#elif defined(WOLFSSL_DEVCRYPTO_AES)
+
+#elif defined(WOLFSSL_SCE) && !defined(WOLFSSL_SCE_NO_AES)
+    #include "hal_data.h"
+
+    #ifndef WOLFSSL_SCE_AES256_HANDLE
+        #define WOLFSSL_SCE_AES256_HANDLE g_sce_aes_256
+    #endif
+
+    #ifndef WOLFSSL_SCE_AES192_HANDLE
+        #define WOLFSSL_SCE_AES192_HANDLE g_sce_aes_192
+    #endif
+
+    #ifndef WOLFSSL_SCE_AES128_HANDLE
+        #define WOLFSSL_SCE_AES128_HANDLE g_sce_aes_128
+    #endif
+
+    static int AES_ECB_encrypt(Aes* aes, const byte* inBlock, byte* outBlock,
+            int sz)
+    {
+        uint32_t ret;
+
+        if (WOLFSSL_SCE_GSCE_HANDLE.p_cfg->endian_flag ==
+                CRYPTO_WORD_ENDIAN_BIG) {
+            ByteReverseWords((word32*)inBlock, (word32*)inBlock, sz);
+        }
+
+        switch (aes->keylen) {
+        #ifdef WOLFSSL_AES_128
+            case AES_128_KEY_SIZE:
+                ret = WOLFSSL_SCE_AES128_HANDLE.p_api->encrypt(
+                        WOLFSSL_SCE_AES128_HANDLE.p_ctrl, aes->key,
+                        NULL, (sz / sizeof(word32)), (word32*)inBlock,
+                        (word32*)outBlock);
+                break;
+        #endif
+        #ifdef WOLFSSL_AES_192
+            case AES_192_KEY_SIZE:
+                ret = WOLFSSL_SCE_AES192_HANDLE.p_api->encrypt(
+                        WOLFSSL_SCE_AES192_HANDLE.p_ctrl, aes->key,
+                        NULL, (sz / sizeof(word32)), (word32*)inBlock,
+                        (word32*)outBlock);
+                break;
+        #endif
+        #ifdef WOLFSSL_AES_256
+            case AES_256_KEY_SIZE:
+                ret = WOLFSSL_SCE_AES256_HANDLE.p_api->encrypt(
+                        WOLFSSL_SCE_AES256_HANDLE.p_ctrl, aes->key,
+                        NULL, (sz / sizeof(word32)), (word32*)inBlock,
+                        (word32*)outBlock);
+                break;
+        #endif
+            default:
+                WOLFSSL_MSG("Unknown key size");
+                return BAD_FUNC_ARG;
+        }
+
+        if (ret != SSP_SUCCESS) {
+           /* revert input */
+            ByteReverseWords((word32*)inBlock, (word32*)inBlock, sz);
+            return WC_HW_E;
+        }
+
+        if (WOLFSSL_SCE_GSCE_HANDLE.p_cfg->endian_flag ==
+                CRYPTO_WORD_ENDIAN_BIG) {
+            ByteReverseWords((word32*)outBlock, (word32*)outBlock, sz);
+            if (inBlock != outBlock) {
+                /* revert input */
+                ByteReverseWords((word32*)inBlock, (word32*)inBlock, sz);
+            }
+        }
+        return 0;
+    }
+
+    #if defined(HAVE_AES_DECRYPT)
+    static int AES_ECB_decrypt(Aes* aes, const byte* inBlock, byte* outBlock,
+            int sz)
+    {
+        uint32_t ret;
+
+        if (WOLFSSL_SCE_GSCE_HANDLE.p_cfg->endian_flag ==
+                CRYPTO_WORD_ENDIAN_BIG) {
+            ByteReverseWords((word32*)inBlock, (word32*)inBlock, sz);
+        }
+
+        switch (aes->keylen) {
+        #ifdef WOLFSSL_AES_128
+            case AES_128_KEY_SIZE:
+                ret = WOLFSSL_SCE_AES128_HANDLE.p_api->decrypt(
+                        WOLFSSL_SCE_AES128_HANDLE.p_ctrl, aes->key, aes->reg,
+                        (sz / sizeof(word32)), (word32*)inBlock,
+                        (word32*)outBlock);
+                break;
+        #endif
+        #ifdef WOLFSSL_AES_192
+            case AES_192_KEY_SIZE:
+                ret = WOLFSSL_SCE_AES192_HANDLE.p_api->decrypt(
+                        WOLFSSL_SCE_AES192_HANDLE.p_ctrl, aes->key, aes->reg,
+                        (sz / sizeof(word32)), (word32*)inBlock,
+                        (word32*)outBlock);
+                break;
+        #endif
+        #ifdef WOLFSSL_AES_256
+            case AES_256_KEY_SIZE:
+                ret = WOLFSSL_SCE_AES256_HANDLE.p_api->decrypt(
+                        WOLFSSL_SCE_AES256_HANDLE.p_ctrl, aes->key, aes->reg,
+                        (sz / sizeof(word32)), (word32*)inBlock,
+                        (word32*)outBlock);
+                break;
+        #endif
+            default:
+                WOLFSSL_MSG("Unknown key size");
+                return BAD_FUNC_ARG;
+        }
+        if (ret != SSP_SUCCESS) {
+            return WC_HW_E;
+        }
+
+        if (WOLFSSL_SCE_GSCE_HANDLE.p_cfg->endian_flag ==
+                CRYPTO_WORD_ENDIAN_BIG) {
+            ByteReverseWords((word32*)outBlock, (word32*)outBlock, sz);
+            if (inBlock != outBlock) {
+                /* revert input */
+                ByteReverseWords((word32*)inBlock, (word32*)inBlock, sz);
+            }
+        }
+
+        return 0;
+    }
+
+    #endif
+
+    #if defined(HAVE_AESGCM) || defined(WOLFSSL_AES_DIRECT)
+    static int wc_AesEncrypt(Aes* aes, const byte* inBlock, byte* outBlock)
+    {
+        return AES_ECB_encrypt(aes, inBlock, outBlock, AES_BLOCK_SIZE);
+    }
+    #endif
+
+    #if defined(HAVE_AES_DECRYPT) && defined(WOLFSSL_AES_DIRECT)
+    static int wc_AesDecrypt(Aes* aes, const byte* inBlock, byte* outBlock)
+    {
+        return AES_ECB_decrypt(aes, inBlock, outBlock, AES_BLOCK_SIZE);
+    }
+    #endif
+#else
+
+    /* using wolfCrypt software implementation */
+    #define NEED_AES_TABLES
+#endif
+
+
+
+#ifdef NEED_AES_TABLES
+
+static const word32 rcon[] = {
+    0x01000000, 0x02000000, 0x04000000, 0x08000000,
+    0x10000000, 0x20000000, 0x40000000, 0x80000000,
+    0x1B000000, 0x36000000,
+    /* for 128-bit blocks, Rijndael never uses more than 10 rcon values */
+};
+
+#ifndef WOLFSSL_AES_SMALL_TABLES
+static const word32 Te[4][256] = {
+{
+    0xc66363a5U, 0xf87c7c84U, 0xee777799U, 0xf67b7b8dU,
+    0xfff2f20dU, 0xd66b6bbdU, 0xde6f6fb1U, 0x91c5c554U,
+    0x60303050U, 0x02010103U, 0xce6767a9U, 0x562b2b7dU,
+    0xe7fefe19U, 0xb5d7d762U, 0x4dababe6U, 0xec76769aU,
+    0x8fcaca45U, 0x1f82829dU, 0x89c9c940U, 0xfa7d7d87U,
+    0xeffafa15U, 0xb25959ebU, 0x8e4747c9U, 0xfbf0f00bU,
+    0x41adadecU, 0xb3d4d467U, 0x5fa2a2fdU, 0x45afafeaU,
+    0x239c9cbfU, 0x53a4a4f7U, 0xe4727296U, 0x9bc0c05bU,
+    0x75b7b7c2U, 0xe1fdfd1cU, 0x3d9393aeU, 0x4c26266aU,
+    0x6c36365aU, 0x7e3f3f41U, 0xf5f7f702U, 0x83cccc4fU,
+    0x6834345cU, 0x51a5a5f4U, 0xd1e5e534U, 0xf9f1f108U,
+    0xe2717193U, 0xabd8d873U, 0x62313153U, 0x2a15153fU,
+    0x0804040cU, 0x95c7c752U, 0x46232365U, 0x9dc3c35eU,
+    0x30181828U, 0x379696a1U, 0x0a05050fU, 0x2f9a9ab5U,
+    0x0e070709U, 0x24121236U, 0x1b80809bU, 0xdfe2e23dU,
+    0xcdebeb26U, 0x4e272769U, 0x7fb2b2cdU, 0xea75759fU,
+    0x1209091bU, 0x1d83839eU, 0x582c2c74U, 0x341a1a2eU,
+    0x361b1b2dU, 0xdc6e6eb2U, 0xb45a5aeeU, 0x5ba0a0fbU,
+    0xa45252f6U, 0x763b3b4dU, 0xb7d6d661U, 0x7db3b3ceU,
+    0x5229297bU, 0xdde3e33eU, 0x5e2f2f71U, 0x13848497U,
+    0xa65353f5U, 0xb9d1d168U, 0x00000000U, 0xc1eded2cU,
+    0x40202060U, 0xe3fcfc1fU, 0x79b1b1c8U, 0xb65b5bedU,
+    0xd46a6abeU, 0x8dcbcb46U, 0x67bebed9U, 0x7239394bU,
+    0x944a4adeU, 0x984c4cd4U, 0xb05858e8U, 0x85cfcf4aU,
+    0xbbd0d06bU, 0xc5efef2aU, 0x4faaaae5U, 0xedfbfb16U,
+    0x864343c5U, 0x9a4d4dd7U, 0x66333355U, 0x11858594U,
+    0x8a4545cfU, 0xe9f9f910U, 0x04020206U, 0xfe7f7f81U,
+    0xa05050f0U, 0x783c3c44U, 0x259f9fbaU, 0x4ba8a8e3U,
+    0xa25151f3U, 0x5da3a3feU, 0x804040c0U, 0x058f8f8aU,
+    0x3f9292adU, 0x219d9dbcU, 0x70383848U, 0xf1f5f504U,
+    0x63bcbcdfU, 0x77b6b6c1U, 0xafdada75U, 0x42212163U,
+    0x20101030U, 0xe5ffff1aU, 0xfdf3f30eU, 0xbfd2d26dU,
+    0x81cdcd4cU, 0x180c0c14U, 0x26131335U, 0xc3ecec2fU,
+    0xbe5f5fe1U, 0x359797a2U, 0x884444ccU, 0x2e171739U,
+    0x93c4c457U, 0x55a7a7f2U, 0xfc7e7e82U, 0x7a3d3d47U,
+    0xc86464acU, 0xba5d5de7U, 0x3219192bU, 0xe6737395U,
+    0xc06060a0U, 0x19818198U, 0x9e4f4fd1U, 0xa3dcdc7fU,
+    0x44222266U, 0x542a2a7eU, 0x3b9090abU, 0x0b888883U,
+    0x8c4646caU, 0xc7eeee29U, 0x6bb8b8d3U, 0x2814143cU,
+    0xa7dede79U, 0xbc5e5ee2U, 0x160b0b1dU, 0xaddbdb76U,
+    0xdbe0e03bU, 0x64323256U, 0x743a3a4eU, 0x140a0a1eU,
+    0x924949dbU, 0x0c06060aU, 0x4824246cU, 0xb85c5ce4U,
+    0x9fc2c25dU, 0xbdd3d36eU, 0x43acacefU, 0xc46262a6U,
+    0x399191a8U, 0x319595a4U, 0xd3e4e437U, 0xf279798bU,
+    0xd5e7e732U, 0x8bc8c843U, 0x6e373759U, 0xda6d6db7U,
+    0x018d8d8cU, 0xb1d5d564U, 0x9c4e4ed2U, 0x49a9a9e0U,
+    0xd86c6cb4U, 0xac5656faU, 0xf3f4f407U, 0xcfeaea25U,
+    0xca6565afU, 0xf47a7a8eU, 0x47aeaee9U, 0x10080818U,
+    0x6fbabad5U, 0xf0787888U, 0x4a25256fU, 0x5c2e2e72U,
+    0x381c1c24U, 0x57a6a6f1U, 0x73b4b4c7U, 0x97c6c651U,
+    0xcbe8e823U, 0xa1dddd7cU, 0xe874749cU, 0x3e1f1f21U,
+    0x964b4bddU, 0x61bdbddcU, 0x0d8b8b86U, 0x0f8a8a85U,
+    0xe0707090U, 0x7c3e3e42U, 0x71b5b5c4U, 0xcc6666aaU,
+    0x904848d8U, 0x06030305U, 0xf7f6f601U, 0x1c0e0e12U,
+    0xc26161a3U, 0x6a35355fU, 0xae5757f9U, 0x69b9b9d0U,
+    0x17868691U, 0x99c1c158U, 0x3a1d1d27U, 0x279e9eb9U,
+    0xd9e1e138U, 0xebf8f813U, 0x2b9898b3U, 0x22111133U,
+    0xd26969bbU, 0xa9d9d970U, 0x078e8e89U, 0x339494a7U,
+    0x2d9b9bb6U, 0x3c1e1e22U, 0x15878792U, 0xc9e9e920U,
+    0x87cece49U, 0xaa5555ffU, 0x50282878U, 0xa5dfdf7aU,
+    0x038c8c8fU, 0x59a1a1f8U, 0x09898980U, 0x1a0d0d17U,
+    0x65bfbfdaU, 0xd7e6e631U, 0x844242c6U, 0xd06868b8U,
+    0x824141c3U, 0x299999b0U, 0x5a2d2d77U, 0x1e0f0f11U,
+    0x7bb0b0cbU, 0xa85454fcU, 0x6dbbbbd6U, 0x2c16163aU,
+},
+{
+    0xa5c66363U, 0x84f87c7cU, 0x99ee7777U, 0x8df67b7bU,
+    0x0dfff2f2U, 0xbdd66b6bU, 0xb1de6f6fU, 0x5491c5c5U,
+    0x50603030U, 0x03020101U, 0xa9ce6767U, 0x7d562b2bU,
+    0x19e7fefeU, 0x62b5d7d7U, 0xe64dababU, 0x9aec7676U,
+    0x458fcacaU, 0x9d1f8282U, 0x4089c9c9U, 0x87fa7d7dU,
+    0x15effafaU, 0xebb25959U, 0xc98e4747U, 0x0bfbf0f0U,
+    0xec41adadU, 0x67b3d4d4U, 0xfd5fa2a2U, 0xea45afafU,
+    0xbf239c9cU, 0xf753a4a4U, 0x96e47272U, 0x5b9bc0c0U,
+    0xc275b7b7U, 0x1ce1fdfdU, 0xae3d9393U, 0x6a4c2626U,
+    0x5a6c3636U, 0x417e3f3fU, 0x02f5f7f7U, 0x4f83ccccU,
+    0x5c683434U, 0xf451a5a5U, 0x34d1e5e5U, 0x08f9f1f1U,
+    0x93e27171U, 0x73abd8d8U, 0x53623131U, 0x3f2a1515U,
+    0x0c080404U, 0x5295c7c7U, 0x65462323U, 0x5e9dc3c3U,
+    0x28301818U, 0xa1379696U, 0x0f0a0505U, 0xb52f9a9aU,
+    0x090e0707U, 0x36241212U, 0x9b1b8080U, 0x3ddfe2e2U,
+    0x26cdebebU, 0x694e2727U, 0xcd7fb2b2U, 0x9fea7575U,
+    0x1b120909U, 0x9e1d8383U, 0x74582c2cU, 0x2e341a1aU,
+    0x2d361b1bU, 0xb2dc6e6eU, 0xeeb45a5aU, 0xfb5ba0a0U,
+    0xf6a45252U, 0x4d763b3bU, 0x61b7d6d6U, 0xce7db3b3U,
+    0x7b522929U, 0x3edde3e3U, 0x715e2f2fU, 0x97138484U,
+    0xf5a65353U, 0x68b9d1d1U, 0x00000000U, 0x2cc1ededU,
+    0x60402020U, 0x1fe3fcfcU, 0xc879b1b1U, 0xedb65b5bU,
+    0xbed46a6aU, 0x468dcbcbU, 0xd967bebeU, 0x4b723939U,
+    0xde944a4aU, 0xd4984c4cU, 0xe8b05858U, 0x4a85cfcfU,
+    0x6bbbd0d0U, 0x2ac5efefU, 0xe54faaaaU, 0x16edfbfbU,
+    0xc5864343U, 0xd79a4d4dU, 0x55663333U, 0x94118585U,
+    0xcf8a4545U, 0x10e9f9f9U, 0x06040202U, 0x81fe7f7fU,
+    0xf0a05050U, 0x44783c3cU, 0xba259f9fU, 0xe34ba8a8U,
+    0xf3a25151U, 0xfe5da3a3U, 0xc0804040U, 0x8a058f8fU,
+    0xad3f9292U, 0xbc219d9dU, 0x48703838U, 0x04f1f5f5U,
+    0xdf63bcbcU, 0xc177b6b6U, 0x75afdadaU, 0x63422121U,
+    0x30201010U, 0x1ae5ffffU, 0x0efdf3f3U, 0x6dbfd2d2U,
+    0x4c81cdcdU, 0x14180c0cU, 0x35261313U, 0x2fc3ececU,
+    0xe1be5f5fU, 0xa2359797U, 0xcc884444U, 0x392e1717U,
+    0x5793c4c4U, 0xf255a7a7U, 0x82fc7e7eU, 0x477a3d3dU,
+    0xacc86464U, 0xe7ba5d5dU, 0x2b321919U, 0x95e67373U,
+    0xa0c06060U, 0x98198181U, 0xd19e4f4fU, 0x7fa3dcdcU,
+    0x66442222U, 0x7e542a2aU, 0xab3b9090U, 0x830b8888U,
+    0xca8c4646U, 0x29c7eeeeU, 0xd36bb8b8U, 0x3c281414U,
+    0x79a7dedeU, 0xe2bc5e5eU, 0x1d160b0bU, 0x76addbdbU,
+    0x3bdbe0e0U, 0x56643232U, 0x4e743a3aU, 0x1e140a0aU,
+    0xdb924949U, 0x0a0c0606U, 0x6c482424U, 0xe4b85c5cU,
+    0x5d9fc2c2U, 0x6ebdd3d3U, 0xef43acacU, 0xa6c46262U,
+    0xa8399191U, 0xa4319595U, 0x37d3e4e4U, 0x8bf27979U,
+    0x32d5e7e7U, 0x438bc8c8U, 0x596e3737U, 0xb7da6d6dU,
+    0x8c018d8dU, 0x64b1d5d5U, 0xd29c4e4eU, 0xe049a9a9U,
+    0xb4d86c6cU, 0xfaac5656U, 0x07f3f4f4U, 0x25cfeaeaU,
+    0xafca6565U, 0x8ef47a7aU, 0xe947aeaeU, 0x18100808U,
+    0xd56fbabaU, 0x88f07878U, 0x6f4a2525U, 0x725c2e2eU,
+    0x24381c1cU, 0xf157a6a6U, 0xc773b4b4U, 0x5197c6c6U,
+    0x23cbe8e8U, 0x7ca1ddddU, 0x9ce87474U, 0x213e1f1fU,
+    0xdd964b4bU, 0xdc61bdbdU, 0x860d8b8bU, 0x850f8a8aU,
+    0x90e07070U, 0x427c3e3eU, 0xc471b5b5U, 0xaacc6666U,
+    0xd8904848U, 0x05060303U, 0x01f7f6f6U, 0x121c0e0eU,
+    0xa3c26161U, 0x5f6a3535U, 0xf9ae5757U, 0xd069b9b9U,
+    0x91178686U, 0x5899c1c1U, 0x273a1d1dU, 0xb9279e9eU,
+    0x38d9e1e1U, 0x13ebf8f8U, 0xb32b9898U, 0x33221111U,
+    0xbbd26969U, 0x70a9d9d9U, 0x89078e8eU, 0xa7339494U,
+    0xb62d9b9bU, 0x223c1e1eU, 0x92158787U, 0x20c9e9e9U,
+    0x4987ceceU, 0xffaa5555U, 0x78502828U, 0x7aa5dfdfU,
+    0x8f038c8cU, 0xf859a1a1U, 0x80098989U, 0x171a0d0dU,
+    0xda65bfbfU, 0x31d7e6e6U, 0xc6844242U, 0xb8d06868U,
+    0xc3824141U, 0xb0299999U, 0x775a2d2dU, 0x111e0f0fU,
+    0xcb7bb0b0U, 0xfca85454U, 0xd66dbbbbU, 0x3a2c1616U,
+},
+{
+    0x63a5c663U, 0x7c84f87cU, 0x7799ee77U, 0x7b8df67bU,
+    0xf20dfff2U, 0x6bbdd66bU, 0x6fb1de6fU, 0xc55491c5U,
+    0x30506030U, 0x01030201U, 0x67a9ce67U, 0x2b7d562bU,
+    0xfe19e7feU, 0xd762b5d7U, 0xabe64dabU, 0x769aec76U,
+    0xca458fcaU, 0x829d1f82U, 0xc94089c9U, 0x7d87fa7dU,
+    0xfa15effaU, 0x59ebb259U, 0x47c98e47U, 0xf00bfbf0U,
+    0xadec41adU, 0xd467b3d4U, 0xa2fd5fa2U, 0xafea45afU,
+    0x9cbf239cU, 0xa4f753a4U, 0x7296e472U, 0xc05b9bc0U,
+    0xb7c275b7U, 0xfd1ce1fdU, 0x93ae3d93U, 0x266a4c26U,
+    0x365a6c36U, 0x3f417e3fU, 0xf702f5f7U, 0xcc4f83ccU,
+    0x345c6834U, 0xa5f451a5U, 0xe534d1e5U, 0xf108f9f1U,
+    0x7193e271U, 0xd873abd8U, 0x31536231U, 0x153f2a15U,
+    0x040c0804U, 0xc75295c7U, 0x23654623U, 0xc35e9dc3U,
+    0x18283018U, 0x96a13796U, 0x050f0a05U, 0x9ab52f9aU,
+    0x07090e07U, 0x12362412U, 0x809b1b80U, 0xe23ddfe2U,
+    0xeb26cdebU, 0x27694e27U, 0xb2cd7fb2U, 0x759fea75U,
+    0x091b1209U, 0x839e1d83U, 0x2c74582cU, 0x1a2e341aU,
+    0x1b2d361bU, 0x6eb2dc6eU, 0x5aeeb45aU, 0xa0fb5ba0U,
+    0x52f6a452U, 0x3b4d763bU, 0xd661b7d6U, 0xb3ce7db3U,
+    0x297b5229U, 0xe33edde3U, 0x2f715e2fU, 0x84971384U,
+    0x53f5a653U, 0xd168b9d1U, 0x00000000U, 0xed2cc1edU,
+    0x20604020U, 0xfc1fe3fcU, 0xb1c879b1U, 0x5bedb65bU,
+    0x6abed46aU, 0xcb468dcbU, 0xbed967beU, 0x394b7239U,
+    0x4ade944aU, 0x4cd4984cU, 0x58e8b058U, 0xcf4a85cfU,
+    0xd06bbbd0U, 0xef2ac5efU, 0xaae54faaU, 0xfb16edfbU,
+    0x43c58643U, 0x4dd79a4dU, 0x33556633U, 0x85941185U,
+    0x45cf8a45U, 0xf910e9f9U, 0x02060402U, 0x7f81fe7fU,
+    0x50f0a050U, 0x3c44783cU, 0x9fba259fU, 0xa8e34ba8U,
+    0x51f3a251U, 0xa3fe5da3U, 0x40c08040U, 0x8f8a058fU,
+    0x92ad3f92U, 0x9dbc219dU, 0x38487038U, 0xf504f1f5U,
+    0xbcdf63bcU, 0xb6c177b6U, 0xda75afdaU, 0x21634221U,
+    0x10302010U, 0xff1ae5ffU, 0xf30efdf3U, 0xd26dbfd2U,
+    0xcd4c81cdU, 0x0c14180cU, 0x13352613U, 0xec2fc3ecU,
+    0x5fe1be5fU, 0x97a23597U, 0x44cc8844U, 0x17392e17U,
+    0xc45793c4U, 0xa7f255a7U, 0x7e82fc7eU, 0x3d477a3dU,
+    0x64acc864U, 0x5de7ba5dU, 0x192b3219U, 0x7395e673U,
+    0x60a0c060U, 0x81981981U, 0x4fd19e4fU, 0xdc7fa3dcU,
+    0x22664422U, 0x2a7e542aU, 0x90ab3b90U, 0x88830b88U,
+    0x46ca8c46U, 0xee29c7eeU, 0xb8d36bb8U, 0x143c2814U,
+    0xde79a7deU, 0x5ee2bc5eU, 0x0b1d160bU, 0xdb76addbU,
+    0xe03bdbe0U, 0x32566432U, 0x3a4e743aU, 0x0a1e140aU,
+    0x49db9249U, 0x060a0c06U, 0x246c4824U, 0x5ce4b85cU,
+    0xc25d9fc2U, 0xd36ebdd3U, 0xacef43acU, 0x62a6c462U,
+    0x91a83991U, 0x95a43195U, 0xe437d3e4U, 0x798bf279U,
+    0xe732d5e7U, 0xc8438bc8U, 0x37596e37U, 0x6db7da6dU,
+    0x8d8c018dU, 0xd564b1d5U, 0x4ed29c4eU, 0xa9e049a9U,
+    0x6cb4d86cU, 0x56faac56U, 0xf407f3f4U, 0xea25cfeaU,
+    0x65afca65U, 0x7a8ef47aU, 0xaee947aeU, 0x08181008U,
+    0xbad56fbaU, 0x7888f078U, 0x256f4a25U, 0x2e725c2eU,
+    0x1c24381cU, 0xa6f157a6U, 0xb4c773b4U, 0xc65197c6U,
+    0xe823cbe8U, 0xdd7ca1ddU, 0x749ce874U, 0x1f213e1fU,
+    0x4bdd964bU, 0xbddc61bdU, 0x8b860d8bU, 0x8a850f8aU,
+    0x7090e070U, 0x3e427c3eU, 0xb5c471b5U, 0x66aacc66U,
+    0x48d89048U, 0x03050603U, 0xf601f7f6U, 0x0e121c0eU,
+    0x61a3c261U, 0x355f6a35U, 0x57f9ae57U, 0xb9d069b9U,
+    0x86911786U, 0xc15899c1U, 0x1d273a1dU, 0x9eb9279eU,
+    0xe138d9e1U, 0xf813ebf8U, 0x98b32b98U, 0x11332211U,
+    0x69bbd269U, 0xd970a9d9U, 0x8e89078eU, 0x94a73394U,
+    0x9bb62d9bU, 0x1e223c1eU, 0x87921587U, 0xe920c9e9U,
+    0xce4987ceU, 0x55ffaa55U, 0x28785028U, 0xdf7aa5dfU,
+    0x8c8f038cU, 0xa1f859a1U, 0x89800989U, 0x0d171a0dU,
+    0xbfda65bfU, 0xe631d7e6U, 0x42c68442U, 0x68b8d068U,
+    0x41c38241U, 0x99b02999U, 0x2d775a2dU, 0x0f111e0fU,
+    0xb0cb7bb0U, 0x54fca854U, 0xbbd66dbbU, 0x163a2c16U,
+},
+{
+    0x6363a5c6U, 0x7c7c84f8U, 0x777799eeU, 0x7b7b8df6U,
+    0xf2f20dffU, 0x6b6bbdd6U, 0x6f6fb1deU, 0xc5c55491U,
+    0x30305060U, 0x01010302U, 0x6767a9ceU, 0x2b2b7d56U,
+    0xfefe19e7U, 0xd7d762b5U, 0xababe64dU, 0x76769aecU,
+    0xcaca458fU, 0x82829d1fU, 0xc9c94089U, 0x7d7d87faU,
+    0xfafa15efU, 0x5959ebb2U, 0x4747c98eU, 0xf0f00bfbU,
+    0xadadec41U, 0xd4d467b3U, 0xa2a2fd5fU, 0xafafea45U,
+    0x9c9cbf23U, 0xa4a4f753U, 0x727296e4U, 0xc0c05b9bU,
+    0xb7b7c275U, 0xfdfd1ce1U, 0x9393ae3dU, 0x26266a4cU,
+    0x36365a6cU, 0x3f3f417eU, 0xf7f702f5U, 0xcccc4f83U,
+    0x34345c68U, 0xa5a5f451U, 0xe5e534d1U, 0xf1f108f9U,
+    0x717193e2U, 0xd8d873abU, 0x31315362U, 0x15153f2aU,
+    0x04040c08U, 0xc7c75295U, 0x23236546U, 0xc3c35e9dU,
+    0x18182830U, 0x9696a137U, 0x05050f0aU, 0x9a9ab52fU,
+    0x0707090eU, 0x12123624U, 0x80809b1bU, 0xe2e23ddfU,
+    0xebeb26cdU, 0x2727694eU, 0xb2b2cd7fU, 0x75759feaU,
+    0x09091b12U, 0x83839e1dU, 0x2c2c7458U, 0x1a1a2e34U,
+    0x1b1b2d36U, 0x6e6eb2dcU, 0x5a5aeeb4U, 0xa0a0fb5bU,
+    0x5252f6a4U, 0x3b3b4d76U, 0xd6d661b7U, 0xb3b3ce7dU,
+    0x29297b52U, 0xe3e33eddU, 0x2f2f715eU, 0x84849713U,
+    0x5353f5a6U, 0xd1d168b9U, 0x00000000U, 0xeded2cc1U,
+    0x20206040U, 0xfcfc1fe3U, 0xb1b1c879U, 0x5b5bedb6U,
+    0x6a6abed4U, 0xcbcb468dU, 0xbebed967U, 0x39394b72U,
+    0x4a4ade94U, 0x4c4cd498U, 0x5858e8b0U, 0xcfcf4a85U,
+    0xd0d06bbbU, 0xefef2ac5U, 0xaaaae54fU, 0xfbfb16edU,
+    0x4343c586U, 0x4d4dd79aU, 0x33335566U, 0x85859411U,
+    0x4545cf8aU, 0xf9f910e9U, 0x02020604U, 0x7f7f81feU,
+    0x5050f0a0U, 0x3c3c4478U, 0x9f9fba25U, 0xa8a8e34bU,
+    0x5151f3a2U, 0xa3a3fe5dU, 0x4040c080U, 0x8f8f8a05U,
+    0x9292ad3fU, 0x9d9dbc21U, 0x38384870U, 0xf5f504f1U,
+    0xbcbcdf63U, 0xb6b6c177U, 0xdada75afU, 0x21216342U,
+    0x10103020U, 0xffff1ae5U, 0xf3f30efdU, 0xd2d26dbfU,
+    0xcdcd4c81U, 0x0c0c1418U, 0x13133526U, 0xecec2fc3U,
+    0x5f5fe1beU, 0x9797a235U, 0x4444cc88U, 0x1717392eU,
+    0xc4c45793U, 0xa7a7f255U, 0x7e7e82fcU, 0x3d3d477aU,
+    0x6464acc8U, 0x5d5de7baU, 0x19192b32U, 0x737395e6U,
+    0x6060a0c0U, 0x81819819U, 0x4f4fd19eU, 0xdcdc7fa3U,
+    0x22226644U, 0x2a2a7e54U, 0x9090ab3bU, 0x8888830bU,
+    0x4646ca8cU, 0xeeee29c7U, 0xb8b8d36bU, 0x14143c28U,
+    0xdede79a7U, 0x5e5ee2bcU, 0x0b0b1d16U, 0xdbdb76adU,
+    0xe0e03bdbU, 0x32325664U, 0x3a3a4e74U, 0x0a0a1e14U,
+    0x4949db92U, 0x06060a0cU, 0x24246c48U, 0x5c5ce4b8U,
+    0xc2c25d9fU, 0xd3d36ebdU, 0xacacef43U, 0x6262a6c4U,
+    0x9191a839U, 0x9595a431U, 0xe4e437d3U, 0x79798bf2U,
+    0xe7e732d5U, 0xc8c8438bU, 0x3737596eU, 0x6d6db7daU,
+    0x8d8d8c01U, 0xd5d564b1U, 0x4e4ed29cU, 0xa9a9e049U,
+    0x6c6cb4d8U, 0x5656faacU, 0xf4f407f3U, 0xeaea25cfU,
+    0x6565afcaU, 0x7a7a8ef4U, 0xaeaee947U, 0x08081810U,
+    0xbabad56fU, 0x787888f0U, 0x25256f4aU, 0x2e2e725cU,
+    0x1c1c2438U, 0xa6a6f157U, 0xb4b4c773U, 0xc6c65197U,
+    0xe8e823cbU, 0xdddd7ca1U, 0x74749ce8U, 0x1f1f213eU,
+    0x4b4bdd96U, 0xbdbddc61U, 0x8b8b860dU, 0x8a8a850fU,
+    0x707090e0U, 0x3e3e427cU, 0xb5b5c471U, 0x6666aaccU,
+    0x4848d890U, 0x03030506U, 0xf6f601f7U, 0x0e0e121cU,
+    0x6161a3c2U, 0x35355f6aU, 0x5757f9aeU, 0xb9b9d069U,
+    0x86869117U, 0xc1c15899U, 0x1d1d273aU, 0x9e9eb927U,
+    0xe1e138d9U, 0xf8f813ebU, 0x9898b32bU, 0x11113322U,
+    0x6969bbd2U, 0xd9d970a9U, 0x8e8e8907U, 0x9494a733U,
+    0x9b9bb62dU, 0x1e1e223cU, 0x87879215U, 0xe9e920c9U,
+    0xcece4987U, 0x5555ffaaU, 0x28287850U, 0xdfdf7aa5U,
+    0x8c8c8f03U, 0xa1a1f859U, 0x89898009U, 0x0d0d171aU,
+    0xbfbfda65U, 0xe6e631d7U, 0x4242c684U, 0x6868b8d0U,
+    0x4141c382U, 0x9999b029U, 0x2d2d775aU, 0x0f0f111eU,
+    0xb0b0cb7bU, 0x5454fca8U, 0xbbbbd66dU, 0x16163a2cU,
+}
+};
+
+#ifdef HAVE_AES_DECRYPT
+static const word32 Td[4][256] = {
+{
+    0x51f4a750U, 0x7e416553U, 0x1a17a4c3U, 0x3a275e96U,
+    0x3bab6bcbU, 0x1f9d45f1U, 0xacfa58abU, 0x4be30393U,
+    0x2030fa55U, 0xad766df6U, 0x88cc7691U, 0xf5024c25U,
+    0x4fe5d7fcU, 0xc52acbd7U, 0x26354480U, 0xb562a38fU,
+    0xdeb15a49U, 0x25ba1b67U, 0x45ea0e98U, 0x5dfec0e1U,
+    0xc32f7502U, 0x814cf012U, 0x8d4697a3U, 0x6bd3f9c6U,
+    0x038f5fe7U, 0x15929c95U, 0xbf6d7aebU, 0x955259daU,
+    0xd4be832dU, 0x587421d3U, 0x49e06929U, 0x8ec9c844U,
+    0x75c2896aU, 0xf48e7978U, 0x99583e6bU, 0x27b971ddU,
+    0xbee14fb6U, 0xf088ad17U, 0xc920ac66U, 0x7dce3ab4U,
+    0x63df4a18U, 0xe51a3182U, 0x97513360U, 0x62537f45U,
+    0xb16477e0U, 0xbb6bae84U, 0xfe81a01cU, 0xf9082b94U,
+    0x70486858U, 0x8f45fd19U, 0x94de6c87U, 0x527bf8b7U,
+    0xab73d323U, 0x724b02e2U, 0xe31f8f57U, 0x6655ab2aU,
+    0xb2eb2807U, 0x2fb5c203U, 0x86c57b9aU, 0xd33708a5U,
+    0x302887f2U, 0x23bfa5b2U, 0x02036abaU, 0xed16825cU,
+    0x8acf1c2bU, 0xa779b492U, 0xf307f2f0U, 0x4e69e2a1U,
+    0x65daf4cdU, 0x0605bed5U, 0xd134621fU, 0xc4a6fe8aU,
+    0x342e539dU, 0xa2f355a0U, 0x058ae132U, 0xa4f6eb75U,
+    0x0b83ec39U, 0x4060efaaU, 0x5e719f06U, 0xbd6e1051U,
+    0x3e218af9U, 0x96dd063dU, 0xdd3e05aeU, 0x4de6bd46U,
+    0x91548db5U, 0x71c45d05U, 0x0406d46fU, 0x605015ffU,
+    0x1998fb24U, 0xd6bde997U, 0x894043ccU, 0x67d99e77U,
+    0xb0e842bdU, 0x07898b88U, 0xe7195b38U, 0x79c8eedbU,
+    0xa17c0a47U, 0x7c420fe9U, 0xf8841ec9U, 0x00000000U,
+    0x09808683U, 0x322bed48U, 0x1e1170acU, 0x6c5a724eU,
+    0xfd0efffbU, 0x0f853856U, 0x3daed51eU, 0x362d3927U,
+    0x0a0fd964U, 0x685ca621U, 0x9b5b54d1U, 0x24362e3aU,
+    0x0c0a67b1U, 0x9357e70fU, 0xb4ee96d2U, 0x1b9b919eU,
+    0x80c0c54fU, 0x61dc20a2U, 0x5a774b69U, 0x1c121a16U,
+    0xe293ba0aU, 0xc0a02ae5U, 0x3c22e043U, 0x121b171dU,
+    0x0e090d0bU, 0xf28bc7adU, 0x2db6a8b9U, 0x141ea9c8U,
+    0x57f11985U, 0xaf75074cU, 0xee99ddbbU, 0xa37f60fdU,
+    0xf701269fU, 0x5c72f5bcU, 0x44663bc5U, 0x5bfb7e34U,
+    0x8b432976U, 0xcb23c6dcU, 0xb6edfc68U, 0xb8e4f163U,
+    0xd731dccaU, 0x42638510U, 0x13972240U, 0x84c61120U,
+    0x854a247dU, 0xd2bb3df8U, 0xaef93211U, 0xc729a16dU,
+    0x1d9e2f4bU, 0xdcb230f3U, 0x0d8652ecU, 0x77c1e3d0U,
+    0x2bb3166cU, 0xa970b999U, 0x119448faU, 0x47e96422U,
+    0xa8fc8cc4U, 0xa0f03f1aU, 0x567d2cd8U, 0x223390efU,
+    0x87494ec7U, 0xd938d1c1U, 0x8ccaa2feU, 0x98d40b36U,
+    0xa6f581cfU, 0xa57ade28U, 0xdab78e26U, 0x3fadbfa4U,
+    0x2c3a9de4U, 0x5078920dU, 0x6a5fcc9bU, 0x547e4662U,
+    0xf68d13c2U, 0x90d8b8e8U, 0x2e39f75eU, 0x82c3aff5U,
+    0x9f5d80beU, 0x69d0937cU, 0x6fd52da9U, 0xcf2512b3U,
+    0xc8ac993bU, 0x10187da7U, 0xe89c636eU, 0xdb3bbb7bU,
+    0xcd267809U, 0x6e5918f4U, 0xec9ab701U, 0x834f9aa8U,
+    0xe6956e65U, 0xaaffe67eU, 0x21bccf08U, 0xef15e8e6U,
+    0xbae79bd9U, 0x4a6f36ceU, 0xea9f09d4U, 0x29b07cd6U,
+    0x31a4b2afU, 0x2a3f2331U, 0xc6a59430U, 0x35a266c0U,
+    0x744ebc37U, 0xfc82caa6U, 0xe090d0b0U, 0x33a7d815U,
+    0xf104984aU, 0x41ecdaf7U, 0x7fcd500eU, 0x1791f62fU,
+    0x764dd68dU, 0x43efb04dU, 0xccaa4d54U, 0xe49604dfU,
+    0x9ed1b5e3U, 0x4c6a881bU, 0xc12c1fb8U, 0x4665517fU,
+    0x9d5eea04U, 0x018c355dU, 0xfa877473U, 0xfb0b412eU,
+    0xb3671d5aU, 0x92dbd252U, 0xe9105633U, 0x6dd64713U,
+    0x9ad7618cU, 0x37a10c7aU, 0x59f8148eU, 0xeb133c89U,
+    0xcea927eeU, 0xb761c935U, 0xe11ce5edU, 0x7a47b13cU,
+    0x9cd2df59U, 0x55f2733fU, 0x1814ce79U, 0x73c737bfU,
+    0x53f7cdeaU, 0x5ffdaa5bU, 0xdf3d6f14U, 0x7844db86U,
+    0xcaaff381U, 0xb968c43eU, 0x3824342cU, 0xc2a3405fU,
+    0x161dc372U, 0xbce2250cU, 0x283c498bU, 0xff0d9541U,
+    0x39a80171U, 0x080cb3deU, 0xd8b4e49cU, 0x6456c190U,
+    0x7bcb8461U, 0xd532b670U, 0x486c5c74U, 0xd0b85742U,
+},
+{
+    0x5051f4a7U, 0x537e4165U, 0xc31a17a4U, 0x963a275eU,
+    0xcb3bab6bU, 0xf11f9d45U, 0xabacfa58U, 0x934be303U,
+    0x552030faU, 0xf6ad766dU, 0x9188cc76U, 0x25f5024cU,
+    0xfc4fe5d7U, 0xd7c52acbU, 0x80263544U, 0x8fb562a3U,
+    0x49deb15aU, 0x6725ba1bU, 0x9845ea0eU, 0xe15dfec0U,
+    0x02c32f75U, 0x12814cf0U, 0xa38d4697U, 0xc66bd3f9U,
+    0xe7038f5fU, 0x9515929cU, 0xebbf6d7aU, 0xda955259U,
+    0x2dd4be83U, 0xd3587421U, 0x2949e069U, 0x448ec9c8U,
+    0x6a75c289U, 0x78f48e79U, 0x6b99583eU, 0xdd27b971U,
+    0xb6bee14fU, 0x17f088adU, 0x66c920acU, 0xb47dce3aU,
+    0x1863df4aU, 0x82e51a31U, 0x60975133U, 0x4562537fU,
+    0xe0b16477U, 0x84bb6baeU, 0x1cfe81a0U, 0x94f9082bU,
+    0x58704868U, 0x198f45fdU, 0x8794de6cU, 0xb7527bf8U,
+    0x23ab73d3U, 0xe2724b02U, 0x57e31f8fU, 0x2a6655abU,
+    0x07b2eb28U, 0x032fb5c2U, 0x9a86c57bU, 0xa5d33708U,
+    0xf2302887U, 0xb223bfa5U, 0xba02036aU, 0x5ced1682U,
+    0x2b8acf1cU, 0x92a779b4U, 0xf0f307f2U, 0xa14e69e2U,
+    0xcd65daf4U, 0xd50605beU, 0x1fd13462U, 0x8ac4a6feU,
+    0x9d342e53U, 0xa0a2f355U, 0x32058ae1U, 0x75a4f6ebU,
+    0x390b83ecU, 0xaa4060efU, 0x065e719fU, 0x51bd6e10U,
+    0xf93e218aU, 0x3d96dd06U, 0xaedd3e05U, 0x464de6bdU,
+    0xb591548dU, 0x0571c45dU, 0x6f0406d4U, 0xff605015U,
+    0x241998fbU, 0x97d6bde9U, 0xcc894043U, 0x7767d99eU,
+    0xbdb0e842U, 0x8807898bU, 0x38e7195bU, 0xdb79c8eeU,
+    0x47a17c0aU, 0xe97c420fU, 0xc9f8841eU, 0x00000000U,
+    0x83098086U, 0x48322bedU, 0xac1e1170U, 0x4e6c5a72U,
+    0xfbfd0effU, 0x560f8538U, 0x1e3daed5U, 0x27362d39U,
+    0x640a0fd9U, 0x21685ca6U, 0xd19b5b54U, 0x3a24362eU,
+    0xb10c0a67U, 0x0f9357e7U, 0xd2b4ee96U, 0x9e1b9b91U,
+    0x4f80c0c5U, 0xa261dc20U, 0x695a774bU, 0x161c121aU,
+    0x0ae293baU, 0xe5c0a02aU, 0x433c22e0U, 0x1d121b17U,
+    0x0b0e090dU, 0xadf28bc7U, 0xb92db6a8U, 0xc8141ea9U,
+    0x8557f119U, 0x4caf7507U, 0xbbee99ddU, 0xfda37f60U,
+    0x9ff70126U, 0xbc5c72f5U, 0xc544663bU, 0x345bfb7eU,
+    0x768b4329U, 0xdccb23c6U, 0x68b6edfcU, 0x63b8e4f1U,
+    0xcad731dcU, 0x10426385U, 0x40139722U, 0x2084c611U,
+    0x7d854a24U, 0xf8d2bb3dU, 0x11aef932U, 0x6dc729a1U,
+    0x4b1d9e2fU, 0xf3dcb230U, 0xec0d8652U, 0xd077c1e3U,
+    0x6c2bb316U, 0x99a970b9U, 0xfa119448U, 0x2247e964U,
+    0xc4a8fc8cU, 0x1aa0f03fU, 0xd8567d2cU, 0xef223390U,
+    0xc787494eU, 0xc1d938d1U, 0xfe8ccaa2U, 0x3698d40bU,
+    0xcfa6f581U, 0x28a57adeU, 0x26dab78eU, 0xa43fadbfU,
+    0xe42c3a9dU, 0x0d507892U, 0x9b6a5fccU, 0x62547e46U,
+    0xc2f68d13U, 0xe890d8b8U, 0x5e2e39f7U, 0xf582c3afU,
+    0xbe9f5d80U, 0x7c69d093U, 0xa96fd52dU, 0xb3cf2512U,
+    0x3bc8ac99U, 0xa710187dU, 0x6ee89c63U, 0x7bdb3bbbU,
+    0x09cd2678U, 0xf46e5918U, 0x01ec9ab7U, 0xa8834f9aU,
+    0x65e6956eU, 0x7eaaffe6U, 0x0821bccfU, 0xe6ef15e8U,
+    0xd9bae79bU, 0xce4a6f36U, 0xd4ea9f09U, 0xd629b07cU,
+    0xaf31a4b2U, 0x312a3f23U, 0x30c6a594U, 0xc035a266U,
+    0x37744ebcU, 0xa6fc82caU, 0xb0e090d0U, 0x1533a7d8U,
+    0x4af10498U, 0xf741ecdaU, 0x0e7fcd50U, 0x2f1791f6U,
+    0x8d764dd6U, 0x4d43efb0U, 0x54ccaa4dU, 0xdfe49604U,
+    0xe39ed1b5U, 0x1b4c6a88U, 0xb8c12c1fU, 0x7f466551U,
+    0x049d5eeaU, 0x5d018c35U, 0x73fa8774U, 0x2efb0b41U,
+    0x5ab3671dU, 0x5292dbd2U, 0x33e91056U, 0x136dd647U,
+    0x8c9ad761U, 0x7a37a10cU, 0x8e59f814U, 0x89eb133cU,
+    0xeecea927U, 0x35b761c9U, 0xede11ce5U, 0x3c7a47b1U,
+    0x599cd2dfU, 0x3f55f273U, 0x791814ceU, 0xbf73c737U,
+    0xea53f7cdU, 0x5b5ffdaaU, 0x14df3d6fU, 0x867844dbU,
+    0x81caaff3U, 0x3eb968c4U, 0x2c382434U, 0x5fc2a340U,
+    0x72161dc3U, 0x0cbce225U, 0x8b283c49U, 0x41ff0d95U,
+    0x7139a801U, 0xde080cb3U, 0x9cd8b4e4U, 0x906456c1U,
+    0x617bcb84U, 0x70d532b6U, 0x74486c5cU, 0x42d0b857U,
+},
+{
+    0xa75051f4U, 0x65537e41U, 0xa4c31a17U, 0x5e963a27U,
+    0x6bcb3babU, 0x45f11f9dU, 0x58abacfaU, 0x03934be3U,
+    0xfa552030U, 0x6df6ad76U, 0x769188ccU, 0x4c25f502U,
+    0xd7fc4fe5U, 0xcbd7c52aU, 0x44802635U, 0xa38fb562U,
+    0x5a49deb1U, 0x1b6725baU, 0x0e9845eaU, 0xc0e15dfeU,
+    0x7502c32fU, 0xf012814cU, 0x97a38d46U, 0xf9c66bd3U,
+    0x5fe7038fU, 0x9c951592U, 0x7aebbf6dU, 0x59da9552U,
+    0x832dd4beU, 0x21d35874U, 0x692949e0U, 0xc8448ec9U,
+    0x896a75c2U, 0x7978f48eU, 0x3e6b9958U, 0x71dd27b9U,
+    0x4fb6bee1U, 0xad17f088U, 0xac66c920U, 0x3ab47dceU,
+    0x4a1863dfU, 0x3182e51aU, 0x33609751U, 0x7f456253U,
+    0x77e0b164U, 0xae84bb6bU, 0xa01cfe81U, 0x2b94f908U,
+    0x68587048U, 0xfd198f45U, 0x6c8794deU, 0xf8b7527bU,
+    0xd323ab73U, 0x02e2724bU, 0x8f57e31fU, 0xab2a6655U,
+    0x2807b2ebU, 0xc2032fb5U, 0x7b9a86c5U, 0x08a5d337U,
+    0x87f23028U, 0xa5b223bfU, 0x6aba0203U, 0x825ced16U,
+    0x1c2b8acfU, 0xb492a779U, 0xf2f0f307U, 0xe2a14e69U,
+    0xf4cd65daU, 0xbed50605U, 0x621fd134U, 0xfe8ac4a6U,
+    0x539d342eU, 0x55a0a2f3U, 0xe132058aU, 0xeb75a4f6U,
+    0xec390b83U, 0xefaa4060U, 0x9f065e71U, 0x1051bd6eU,
+
+    0x8af93e21U, 0x063d96ddU, 0x05aedd3eU, 0xbd464de6U,
+    0x8db59154U, 0x5d0571c4U, 0xd46f0406U, 0x15ff6050U,
+    0xfb241998U, 0xe997d6bdU, 0x43cc8940U, 0x9e7767d9U,
+    0x42bdb0e8U, 0x8b880789U, 0x5b38e719U, 0xeedb79c8U,
+    0x0a47a17cU, 0x0fe97c42U, 0x1ec9f884U, 0x00000000U,
+    0x86830980U, 0xed48322bU, 0x70ac1e11U, 0x724e6c5aU,
+    0xfffbfd0eU, 0x38560f85U, 0xd51e3daeU, 0x3927362dU,
+    0xd9640a0fU, 0xa621685cU, 0x54d19b5bU, 0x2e3a2436U,
+    0x67b10c0aU, 0xe70f9357U, 0x96d2b4eeU, 0x919e1b9bU,
+    0xc54f80c0U, 0x20a261dcU, 0x4b695a77U, 0x1a161c12U,
+    0xba0ae293U, 0x2ae5c0a0U, 0xe0433c22U, 0x171d121bU,
+    0x0d0b0e09U, 0xc7adf28bU, 0xa8b92db6U, 0xa9c8141eU,
+    0x198557f1U, 0x074caf75U, 0xddbbee99U, 0x60fda37fU,
+    0x269ff701U, 0xf5bc5c72U, 0x3bc54466U, 0x7e345bfbU,
+    0x29768b43U, 0xc6dccb23U, 0xfc68b6edU, 0xf163b8e4U,
+    0xdccad731U, 0x85104263U, 0x22401397U, 0x112084c6U,
+    0x247d854aU, 0x3df8d2bbU, 0x3211aef9U, 0xa16dc729U,
+    0x2f4b1d9eU, 0x30f3dcb2U, 0x52ec0d86U, 0xe3d077c1U,
+    0x166c2bb3U, 0xb999a970U, 0x48fa1194U, 0x642247e9U,
+    0x8cc4a8fcU, 0x3f1aa0f0U, 0x2cd8567dU, 0x90ef2233U,
+    0x4ec78749U, 0xd1c1d938U, 0xa2fe8ccaU, 0x0b3698d4U,
+    0x81cfa6f5U, 0xde28a57aU, 0x8e26dab7U, 0xbfa43fadU,
+    0x9de42c3aU, 0x920d5078U, 0xcc9b6a5fU, 0x4662547eU,
+    0x13c2f68dU, 0xb8e890d8U, 0xf75e2e39U, 0xaff582c3U,
+    0x80be9f5dU, 0x937c69d0U, 0x2da96fd5U, 0x12b3cf25U,
+    0x993bc8acU, 0x7da71018U, 0x636ee89cU, 0xbb7bdb3bU,
+    0x7809cd26U, 0x18f46e59U, 0xb701ec9aU, 0x9aa8834fU,
+    0x6e65e695U, 0xe67eaaffU, 0xcf0821bcU, 0xe8e6ef15U,
+    0x9bd9bae7U, 0x36ce4a6fU, 0x09d4ea9fU, 0x7cd629b0U,
+    0xb2af31a4U, 0x23312a3fU, 0x9430c6a5U, 0x66c035a2U,
+    0xbc37744eU, 0xcaa6fc82U, 0xd0b0e090U, 0xd81533a7U,
+    0x984af104U, 0xdaf741ecU, 0x500e7fcdU, 0xf62f1791U,
+    0xd68d764dU, 0xb04d43efU, 0x4d54ccaaU, 0x04dfe496U,
+    0xb5e39ed1U, 0x881b4c6aU, 0x1fb8c12cU, 0x517f4665U,
+    0xea049d5eU, 0x355d018cU, 0x7473fa87U, 0x412efb0bU,
+    0x1d5ab367U, 0xd25292dbU, 0x5633e910U, 0x47136dd6U,
+    0x618c9ad7U, 0x0c7a37a1U, 0x148e59f8U, 0x3c89eb13U,
+    0x27eecea9U, 0xc935b761U, 0xe5ede11cU, 0xb13c7a47U,
+    0xdf599cd2U, 0x733f55f2U, 0xce791814U, 0x37bf73c7U,
+    0xcdea53f7U, 0xaa5b5ffdU, 0x6f14df3dU, 0xdb867844U,
+    0xf381caafU, 0xc43eb968U, 0x342c3824U, 0x405fc2a3U,
+    0xc372161dU, 0x250cbce2U, 0x498b283cU, 0x9541ff0dU,
+    0x017139a8U, 0xb3de080cU, 0xe49cd8b4U, 0xc1906456U,
+    0x84617bcbU, 0xb670d532U, 0x5c74486cU, 0x5742d0b8U,
+},
+{
+    0xf4a75051U, 0x4165537eU, 0x17a4c31aU, 0x275e963aU,
+    0xab6bcb3bU, 0x9d45f11fU, 0xfa58abacU, 0xe303934bU,
+    0x30fa5520U, 0x766df6adU, 0xcc769188U, 0x024c25f5U,
+    0xe5d7fc4fU, 0x2acbd7c5U, 0x35448026U, 0x62a38fb5U,
+    0xb15a49deU, 0xba1b6725U, 0xea0e9845U, 0xfec0e15dU,
+    0x2f7502c3U, 0x4cf01281U, 0x4697a38dU, 0xd3f9c66bU,
+    0x8f5fe703U, 0x929c9515U, 0x6d7aebbfU, 0x5259da95U,
+    0xbe832dd4U, 0x7421d358U, 0xe0692949U, 0xc9c8448eU,
+    0xc2896a75U, 0x8e7978f4U, 0x583e6b99U, 0xb971dd27U,
+    0xe14fb6beU, 0x88ad17f0U, 0x20ac66c9U, 0xce3ab47dU,
+    0xdf4a1863U, 0x1a3182e5U, 0x51336097U, 0x537f4562U,
+    0x6477e0b1U, 0x6bae84bbU, 0x81a01cfeU, 0x082b94f9U,
+    0x48685870U, 0x45fd198fU, 0xde6c8794U, 0x7bf8b752U,
+    0x73d323abU, 0x4b02e272U, 0x1f8f57e3U, 0x55ab2a66U,
+    0xeb2807b2U, 0xb5c2032fU, 0xc57b9a86U, 0x3708a5d3U,
+    0x2887f230U, 0xbfa5b223U, 0x036aba02U, 0x16825cedU,
+    0xcf1c2b8aU, 0x79b492a7U, 0x07f2f0f3U, 0x69e2a14eU,
+    0xdaf4cd65U, 0x05bed506U, 0x34621fd1U, 0xa6fe8ac4U,
+    0x2e539d34U, 0xf355a0a2U, 0x8ae13205U, 0xf6eb75a4U,
+    0x83ec390bU, 0x60efaa40U, 0x719f065eU, 0x6e1051bdU,
+    0x218af93eU, 0xdd063d96U, 0x3e05aeddU, 0xe6bd464dU,
+    0x548db591U, 0xc45d0571U, 0x06d46f04U, 0x5015ff60U,
+    0x98fb2419U, 0xbde997d6U, 0x4043cc89U, 0xd99e7767U,
+    0xe842bdb0U, 0x898b8807U, 0x195b38e7U, 0xc8eedb79U,
+    0x7c0a47a1U, 0x420fe97cU, 0x841ec9f8U, 0x00000000U,
+    0x80868309U, 0x2bed4832U, 0x1170ac1eU, 0x5a724e6cU,
+    0x0efffbfdU, 0x8538560fU, 0xaed51e3dU, 0x2d392736U,
+    0x0fd9640aU, 0x5ca62168U, 0x5b54d19bU, 0x362e3a24U,
+    0x0a67b10cU, 0x57e70f93U, 0xee96d2b4U, 0x9b919e1bU,
+    0xc0c54f80U, 0xdc20a261U, 0x774b695aU, 0x121a161cU,
+    0x93ba0ae2U, 0xa02ae5c0U, 0x22e0433cU, 0x1b171d12U,
+    0x090d0b0eU, 0x8bc7adf2U, 0xb6a8b92dU, 0x1ea9c814U,
+    0xf1198557U, 0x75074cafU, 0x99ddbbeeU, 0x7f60fda3U,
+    0x01269ff7U, 0x72f5bc5cU, 0x663bc544U, 0xfb7e345bU,
+    0x4329768bU, 0x23c6dccbU, 0xedfc68b6U, 0xe4f163b8U,
+    0x31dccad7U, 0x63851042U, 0x97224013U, 0xc6112084U,
+    0x4a247d85U, 0xbb3df8d2U, 0xf93211aeU, 0x29a16dc7U,
+    0x9e2f4b1dU, 0xb230f3dcU, 0x8652ec0dU, 0xc1e3d077U,
+    0xb3166c2bU, 0x70b999a9U, 0x9448fa11U, 0xe9642247U,
+    0xfc8cc4a8U, 0xf03f1aa0U, 0x7d2cd856U, 0x3390ef22U,
+    0x494ec787U, 0x38d1c1d9U, 0xcaa2fe8cU, 0xd40b3698U,
+    0xf581cfa6U, 0x7ade28a5U, 0xb78e26daU, 0xadbfa43fU,
+    0x3a9de42cU, 0x78920d50U, 0x5fcc9b6aU, 0x7e466254U,
+    0x8d13c2f6U, 0xd8b8e890U, 0x39f75e2eU, 0xc3aff582U,
+    0x5d80be9fU, 0xd0937c69U, 0xd52da96fU, 0x2512b3cfU,
+    0xac993bc8U, 0x187da710U, 0x9c636ee8U, 0x3bbb7bdbU,
+    0x267809cdU, 0x5918f46eU, 0x9ab701ecU, 0x4f9aa883U,
+    0x956e65e6U, 0xffe67eaaU, 0xbccf0821U, 0x15e8e6efU,
+    0xe79bd9baU, 0x6f36ce4aU, 0x9f09d4eaU, 0xb07cd629U,
+    0xa4b2af31U, 0x3f23312aU, 0xa59430c6U, 0xa266c035U,
+    0x4ebc3774U, 0x82caa6fcU, 0x90d0b0e0U, 0xa7d81533U,
+    0x04984af1U, 0xecdaf741U, 0xcd500e7fU, 0x91f62f17U,
+    0x4dd68d76U, 0xefb04d43U, 0xaa4d54ccU, 0x9604dfe4U,
+    0xd1b5e39eU, 0x6a881b4cU, 0x2c1fb8c1U, 0x65517f46U,
+    0x5eea049dU, 0x8c355d01U, 0x877473faU, 0x0b412efbU,
+    0x671d5ab3U, 0xdbd25292U, 0x105633e9U, 0xd647136dU,
+    0xd7618c9aU, 0xa10c7a37U, 0xf8148e59U, 0x133c89ebU,
+    0xa927eeceU, 0x61c935b7U, 0x1ce5ede1U, 0x47b13c7aU,
+    0xd2df599cU, 0xf2733f55U, 0x14ce7918U, 0xc737bf73U,
+    0xf7cdea53U, 0xfdaa5b5fU, 0x3d6f14dfU, 0x44db8678U,
+    0xaff381caU, 0x68c43eb9U, 0x24342c38U, 0xa3405fc2U,
+    0x1dc37216U, 0xe2250cbcU, 0x3c498b28U, 0x0d9541ffU,
+    0xa8017139U, 0x0cb3de08U, 0xb4e49cd8U, 0x56c19064U,
+    0xcb84617bU, 0x32b670d5U, 0x6c5c7448U, 0xb85742d0U,
+}
+};
+#endif /* HAVE_AES_DECRYPT */
+#endif
+
+#ifdef HAVE_AES_DECRYPT
+#if (defined(HAVE_AES_CBC) && !defined(WOLFSSL_DEVCRYPTO_CBC)) \
+			|| defined(WOLFSSL_AES_DIRECT)
+static const byte Td4[256] =
+{
+    0x52U, 0x09U, 0x6aU, 0xd5U, 0x30U, 0x36U, 0xa5U, 0x38U,
+    0xbfU, 0x40U, 0xa3U, 0x9eU, 0x81U, 0xf3U, 0xd7U, 0xfbU,
+    0x7cU, 0xe3U, 0x39U, 0x82U, 0x9bU, 0x2fU, 0xffU, 0x87U,
+    0x34U, 0x8eU, 0x43U, 0x44U, 0xc4U, 0xdeU, 0xe9U, 0xcbU,
+    0x54U, 0x7bU, 0x94U, 0x32U, 0xa6U, 0xc2U, 0x23U, 0x3dU,
+    0xeeU, 0x4cU, 0x95U, 0x0bU, 0x42U, 0xfaU, 0xc3U, 0x4eU,
+    0x08U, 0x2eU, 0xa1U, 0x66U, 0x28U, 0xd9U, 0x24U, 0xb2U,
+    0x76U, 0x5bU, 0xa2U, 0x49U, 0x6dU, 0x8bU, 0xd1U, 0x25U,
+    0x72U, 0xf8U, 0xf6U, 0x64U, 0x86U, 0x68U, 0x98U, 0x16U,
+    0xd4U, 0xa4U, 0x5cU, 0xccU, 0x5dU, 0x65U, 0xb6U, 0x92U,
+    0x6cU, 0x70U, 0x48U, 0x50U, 0xfdU, 0xedU, 0xb9U, 0xdaU,
+    0x5eU, 0x15U, 0x46U, 0x57U, 0xa7U, 0x8dU, 0x9dU, 0x84U,
+    0x90U, 0xd8U, 0xabU, 0x00U, 0x8cU, 0xbcU, 0xd3U, 0x0aU,
+    0xf7U, 0xe4U, 0x58U, 0x05U, 0xb8U, 0xb3U, 0x45U, 0x06U,
+    0xd0U, 0x2cU, 0x1eU, 0x8fU, 0xcaU, 0x3fU, 0x0fU, 0x02U,
+    0xc1U, 0xafU, 0xbdU, 0x03U, 0x01U, 0x13U, 0x8aU, 0x6bU,
+    0x3aU, 0x91U, 0x11U, 0x41U, 0x4fU, 0x67U, 0xdcU, 0xeaU,
+    0x97U, 0xf2U, 0xcfU, 0xceU, 0xf0U, 0xb4U, 0xe6U, 0x73U,
+    0x96U, 0xacU, 0x74U, 0x22U, 0xe7U, 0xadU, 0x35U, 0x85U,
+    0xe2U, 0xf9U, 0x37U, 0xe8U, 0x1cU, 0x75U, 0xdfU, 0x6eU,
+    0x47U, 0xf1U, 0x1aU, 0x71U, 0x1dU, 0x29U, 0xc5U, 0x89U,
+    0x6fU, 0xb7U, 0x62U, 0x0eU, 0xaaU, 0x18U, 0xbeU, 0x1bU,
+    0xfcU, 0x56U, 0x3eU, 0x4bU, 0xc6U, 0xd2U, 0x79U, 0x20U,
+    0x9aU, 0xdbU, 0xc0U, 0xfeU, 0x78U, 0xcdU, 0x5aU, 0xf4U,
+    0x1fU, 0xddU, 0xa8U, 0x33U, 0x88U, 0x07U, 0xc7U, 0x31U,
+    0xb1U, 0x12U, 0x10U, 0x59U, 0x27U, 0x80U, 0xecU, 0x5fU,
+    0x60U, 0x51U, 0x7fU, 0xa9U, 0x19U, 0xb5U, 0x4aU, 0x0dU,
+    0x2dU, 0xe5U, 0x7aU, 0x9fU, 0x93U, 0xc9U, 0x9cU, 0xefU,
+    0xa0U, 0xe0U, 0x3bU, 0x4dU, 0xaeU, 0x2aU, 0xf5U, 0xb0U,
+    0xc8U, 0xebU, 0xbbU, 0x3cU, 0x83U, 0x53U, 0x99U, 0x61U,
+    0x17U, 0x2bU, 0x04U, 0x7eU, 0xbaU, 0x77U, 0xd6U, 0x26U,
+    0xe1U, 0x69U, 0x14U, 0x63U, 0x55U, 0x21U, 0x0cU, 0x7dU,
+};
+#endif /* HAVE_AES_CBC || WOLFSSL_AES_DIRECT */
+#endif /* HAVE_AES_DECRYPT */
+
+#define GETBYTE(x, y) (word32)((byte)((x) >> (8 * (y))))
+
+#ifdef WOLFSSL_AES_SMALL_TABLES
+static const byte Tsbox[256] = {
+    0x63U, 0x7cU, 0x77U, 0x7bU, 0xf2U, 0x6bU, 0x6fU, 0xc5U,
+    0x30U, 0x01U, 0x67U, 0x2bU, 0xfeU, 0xd7U, 0xabU, 0x76U,
+    0xcaU, 0x82U, 0xc9U, 0x7dU, 0xfaU, 0x59U, 0x47U, 0xf0U,
+    0xadU, 0xd4U, 0xa2U, 0xafU, 0x9cU, 0xa4U, 0x72U, 0xc0U,
+    0xb7U, 0xfdU, 0x93U, 0x26U, 0x36U, 0x3fU, 0xf7U, 0xccU,
+    0x34U, 0xa5U, 0xe5U, 0xf1U, 0x71U, 0xd8U, 0x31U, 0x15U,
+    0x04U, 0xc7U, 0x23U, 0xc3U, 0x18U, 0x96U, 0x05U, 0x9aU,
+    0x07U, 0x12U, 0x80U, 0xe2U, 0xebU, 0x27U, 0xb2U, 0x75U,
+    0x09U, 0x83U, 0x2cU, 0x1aU, 0x1bU, 0x6eU, 0x5aU, 0xa0U,
+    0x52U, 0x3bU, 0xd6U, 0xb3U, 0x29U, 0xe3U, 0x2fU, 0x84U,
+    0x53U, 0xd1U, 0x00U, 0xedU, 0x20U, 0xfcU, 0xb1U, 0x5bU,
+    0x6aU, 0xcbU, 0xbeU, 0x39U, 0x4aU, 0x4cU, 0x58U, 0xcfU,
+    0xd0U, 0xefU, 0xaaU, 0xfbU, 0x43U, 0x4dU, 0x33U, 0x85U,
+    0x45U, 0xf9U, 0x02U, 0x7fU, 0x50U, 0x3cU, 0x9fU, 0xa8U,
+    0x51U, 0xa3U, 0x40U, 0x8fU, 0x92U, 0x9dU, 0x38U, 0xf5U,
+    0xbcU, 0xb6U, 0xdaU, 0x21U, 0x10U, 0xffU, 0xf3U, 0xd2U,
+    0xcdU, 0x0cU, 0x13U, 0xecU, 0x5fU, 0x97U, 0x44U, 0x17U,
+    0xc4U, 0xa7U, 0x7eU, 0x3dU, 0x64U, 0x5dU, 0x19U, 0x73U,
+    0x60U, 0x81U, 0x4fU, 0xdcU, 0x22U, 0x2aU, 0x90U, 0x88U,
+    0x46U, 0xeeU, 0xb8U, 0x14U, 0xdeU, 0x5eU, 0x0bU, 0xdbU,
+    0xe0U, 0x32U, 0x3aU, 0x0aU, 0x49U, 0x06U, 0x24U, 0x5cU,
+    0xc2U, 0xd3U, 0xacU, 0x62U, 0x91U, 0x95U, 0xe4U, 0x79U,
+    0xe7U, 0xc8U, 0x37U, 0x6dU, 0x8dU, 0xd5U, 0x4eU, 0xa9U,
+    0x6cU, 0x56U, 0xf4U, 0xeaU, 0x65U, 0x7aU, 0xaeU, 0x08U,
+    0xbaU, 0x78U, 0x25U, 0x2eU, 0x1cU, 0xa6U, 0xb4U, 0xc6U,
+    0xe8U, 0xddU, 0x74U, 0x1fU, 0x4bU, 0xbdU, 0x8bU, 0x8aU,
+    0x70U, 0x3eU, 0xb5U, 0x66U, 0x48U, 0x03U, 0xf6U, 0x0eU,
+    0x61U, 0x35U, 0x57U, 0xb9U, 0x86U, 0xc1U, 0x1dU, 0x9eU,
+    0xe1U, 0xf8U, 0x98U, 0x11U, 0x69U, 0xd9U, 0x8eU, 0x94U,
+    0x9bU, 0x1eU, 0x87U, 0xe9U, 0xceU, 0x55U, 0x28U, 0xdfU,
+    0x8cU, 0xa1U, 0x89U, 0x0dU, 0xbfU, 0xe6U, 0x42U, 0x68U,
+    0x41U, 0x99U, 0x2dU, 0x0fU, 0xb0U, 0x54U, 0xbbU, 0x16U
+};
+
+#define AES_XTIME(x)    ((byte)((byte)((x) << 1) ^ ((0 - ((x) >> 7)) & 0x1b)))
+
+static word32 col_mul(word32 t, int i2, int i3, int ia, int ib)
+{
+    byte t3 = GETBYTE(t, i3);
+    byte tm = AES_XTIME(GETBYTE(t, i2) ^ t3);
+
+    return GETBYTE(t, ia) ^ GETBYTE(t, ib) ^ t3 ^ tm;
+}
+
+static word32 inv_col_mul(word32 t, int i9, int ib, int id, int ie)
+{
+    byte t9 = GETBYTE(t, i9);
+    byte tb = GETBYTE(t, ib);
+    byte td = GETBYTE(t, id);
+    byte te = GETBYTE(t, ie);
+    byte t0 = t9 ^ tb ^ td;
+    return t0 ^ AES_XTIME(AES_XTIME(AES_XTIME(t0 ^ te) ^ td ^ te) ^ tb ^ te);
+}
+#endif
+
+#if defined(HAVE_AES_CBC) || defined(WOLFSSL_AES_DIRECT) || defined(HAVE_AESGCM)
+
+#ifndef WC_CACHE_LINE_SZ
+    #if defined(__x86_64__) || defined(_M_X64) || \
+       (defined(__ILP32__) && (__ILP32__ >= 1))
+        #define WC_CACHE_LINE_SZ 64
+    #else
+        /* default cache line size */
+        #define WC_CACHE_LINE_SZ 32
+    #endif
+#endif
+
+
+#ifndef WOLFSSL_AES_SMALL_TABLES
+/* load 4 Te Tables into cache by cache line stride */
+static WC_INLINE word32 PreFetchTe(void)
+{
+    word32 x = 0;
+    int i,j;
+
+    for (i = 0; i < 4; i++) {
+        /* 256 elements, each one is 4 bytes */
+        for (j = 0; j < 256; j += WC_CACHE_LINE_SZ/4) {
+            x &= Te[i][j];
+        }
+    }
+    return x;
+}
+#else
+/* load sbox into cache by cache line stride */
+static WC_INLINE word32 PreFetchSBox(void)
+{
+    word32 x = 0;
+    int i;
+
+    for (i = 0; i < 256; i += WC_CACHE_LINE_SZ/4) {
+        x &= Tsbox[i];
+    }
+    return x;
+}
+#endif
+
+/* Software AES - ECB Encrypt */
+static void wc_AesEncrypt(Aes* aes, const byte* inBlock, byte* outBlock)
+{
+    word32 s0, s1, s2, s3;
+    word32 t0, t1, t2, t3;
+    word32 r = aes->rounds >> 1;
+    const word32* rk = aes->key;
+
+    if (r > 7 || r == 0) {
+        WOLFSSL_MSG("AesEncrypt encountered improper key, set it up");
+        return;  /* stop instead of seg-faulting, set up your keys! */
+    }
+
+#ifdef WOLFSSL_AESNI
+    if (haveAESNI && aes->use_aesni) {
+        #ifdef DEBUG_AESNI
+            printf("about to aes encrypt\n");
+            printf("in  = %p\n", inBlock);
+            printf("out = %p\n", outBlock);
+            printf("aes->key = %p\n", aes->key);
+            printf("aes->rounds = %d\n", aes->rounds);
+            printf("sz = %d\n", AES_BLOCK_SIZE);
+        #endif
+
+        /* check alignment, decrypt doesn't need alignment */
+        if ((wolfssl_word)inBlock % AESNI_ALIGN) {
+        #ifndef NO_WOLFSSL_ALLOC_ALIGN
+            byte* tmp = (byte*)XMALLOC(AES_BLOCK_SIZE + AESNI_ALIGN, aes->heap,
+                                                      DYNAMIC_TYPE_TMP_BUFFER);
+            byte* tmp_align;
+            if (tmp == NULL) return;
+
+            tmp_align = tmp + (AESNI_ALIGN - ((size_t)tmp % AESNI_ALIGN));
+
+            XMEMCPY(tmp_align, inBlock, AES_BLOCK_SIZE);
+            AES_ECB_encrypt(tmp_align, tmp_align, AES_BLOCK_SIZE,
+                    (byte*)aes->key, aes->rounds);
+            XMEMCPY(outBlock, tmp_align, AES_BLOCK_SIZE);
+            XFREE(tmp, aes->heap, DYNAMIC_TYPE_TMP_BUFFER);
+            return;
+        #else
+            WOLFSSL_MSG("AES-ECB encrypt with bad alignment");
+            return;
+        #endif
+        }
+
+        AES_ECB_encrypt(inBlock, outBlock, AES_BLOCK_SIZE, (byte*)aes->key,
+                        aes->rounds);
+
+        return;
+    }
+    else {
+        #ifdef DEBUG_AESNI
+            printf("Skipping AES-NI\n");
+        #endif
+    }
+#endif
+#if defined(WOLFSSL_SCE) && !defined(WOLFSSL_SCE_NO_AES)
+    AES_ECB_encrypt(aes, inBlock, outBlock, AES_BLOCK_SIZE);
+    return;
+#endif
+
+    /*
+     * map byte array block to cipher state
+     * and add initial round key:
+     */
+    XMEMCPY(&s0, inBlock,                  sizeof(s0));
+    XMEMCPY(&s1, inBlock + sizeof(s0),     sizeof(s1));
+    XMEMCPY(&s2, inBlock + 2 * sizeof(s0), sizeof(s2));
+    XMEMCPY(&s3, inBlock + 3 * sizeof(s0), sizeof(s3));
+
+#ifdef LITTLE_ENDIAN_ORDER
+    s0 = ByteReverseWord32(s0);
+    s1 = ByteReverseWord32(s1);
+    s2 = ByteReverseWord32(s2);
+    s3 = ByteReverseWord32(s3);
+#endif
+
+    /* AddRoundKey */
+    s0 ^= rk[0];
+    s1 ^= rk[1];
+    s2 ^= rk[2];
+    s3 ^= rk[3];
+
+#ifndef WOLFSSL_AES_SMALL_TABLES
+    s0 |= PreFetchTe();
+
+    /*
+     * Nr - 1 full rounds:
+     */
+
+    for (;;) {
+        t0 =
+            Te[0][GETBYTE(s0, 3)] ^
+            Te[1][GETBYTE(s1, 2)] ^
+            Te[2][GETBYTE(s2, 1)] ^
+            Te[3][GETBYTE(s3, 0)] ^
+            rk[4];
+        t1 =
+            Te[0][GETBYTE(s1, 3)] ^
+            Te[1][GETBYTE(s2, 2)] ^
+            Te[2][GETBYTE(s3, 1)] ^
+            Te[3][GETBYTE(s0, 0)] ^
+            rk[5];
+        t2 =
+            Te[0][GETBYTE(s2, 3)] ^
+            Te[1][GETBYTE(s3, 2)] ^
+            Te[2][GETBYTE(s0, 1)] ^
+            Te[3][GETBYTE(s1, 0)] ^
+            rk[6];
+        t3 =
+            Te[0][GETBYTE(s3, 3)] ^
+            Te[1][GETBYTE(s0, 2)] ^
+            Te[2][GETBYTE(s1, 1)] ^
+            Te[3][GETBYTE(s2, 0)] ^
+            rk[7];
+
+        rk += 8;
+        if (--r == 0) {
+            break;
+        }
+
+        s0 =
+            Te[0][GETBYTE(t0, 3)] ^
+            Te[1][GETBYTE(t1, 2)] ^
+            Te[2][GETBYTE(t2, 1)] ^
+            Te[3][GETBYTE(t3, 0)] ^
+            rk[0];
+        s1 =
+            Te[0][GETBYTE(t1, 3)] ^
+            Te[1][GETBYTE(t2, 2)] ^
+            Te[2][GETBYTE(t3, 1)] ^
+            Te[3][GETBYTE(t0, 0)] ^
+            rk[1];
+        s2 =
+            Te[0][GETBYTE(t2, 3)] ^
+            Te[1][GETBYTE(t3, 2)] ^
+            Te[2][GETBYTE(t0, 1)] ^
+            Te[3][GETBYTE(t1, 0)] ^
+            rk[2];
+        s3 =
+            Te[0][GETBYTE(t3, 3)] ^
+            Te[1][GETBYTE(t0, 2)] ^
+            Te[2][GETBYTE(t1, 1)] ^
+            Te[3][GETBYTE(t2, 0)] ^
+            rk[3];
+    }
+
+    /*
+     * apply last round and
+     * map cipher state to byte array block:
+     */
+
+    s0 =
+        (Te[2][GETBYTE(t0, 3)] & 0xff000000) ^
+        (Te[3][GETBYTE(t1, 2)] & 0x00ff0000) ^
+        (Te[0][GETBYTE(t2, 1)] & 0x0000ff00) ^
+        (Te[1][GETBYTE(t3, 0)] & 0x000000ff) ^
+        rk[0];
+    s1 =
+        (Te[2][GETBYTE(t1, 3)] & 0xff000000) ^
+        (Te[3][GETBYTE(t2, 2)] & 0x00ff0000) ^
+        (Te[0][GETBYTE(t3, 1)] & 0x0000ff00) ^
+        (Te[1][GETBYTE(t0, 0)] & 0x000000ff) ^
+        rk[1];
+    s2 =
+        (Te[2][GETBYTE(t2, 3)] & 0xff000000) ^
+        (Te[3][GETBYTE(t3, 2)] & 0x00ff0000) ^
+        (Te[0][GETBYTE(t0, 1)] & 0x0000ff00) ^
+        (Te[1][GETBYTE(t1, 0)] & 0x000000ff) ^
+        rk[2];
+    s3 =
+        (Te[2][GETBYTE(t3, 3)] & 0xff000000) ^
+        (Te[3][GETBYTE(t0, 2)] & 0x00ff0000) ^
+        (Te[0][GETBYTE(t1, 1)] & 0x0000ff00) ^
+        (Te[1][GETBYTE(t2, 0)] & 0x000000ff) ^
+        rk[3];
+#else
+    s0 |= PreFetchSBox();
+
+    r *= 2;
+    /* Two rounds at a time */
+    for (rk += 4; r > 1; r--, rk += 4) {
+        t0 =
+            ((word32)Tsbox[GETBYTE(s0, 3)] << 24) ^
+            ((word32)Tsbox[GETBYTE(s1, 2)] << 16) ^
+            ((word32)Tsbox[GETBYTE(s2, 1)] <<  8) ^
+            ((word32)Tsbox[GETBYTE(s3, 0)]);
+        t1 =
+            ((word32)Tsbox[GETBYTE(s1, 3)] << 24) ^
+            ((word32)Tsbox[GETBYTE(s2, 2)] << 16) ^
+            ((word32)Tsbox[GETBYTE(s3, 1)] <<  8) ^
+            ((word32)Tsbox[GETBYTE(s0, 0)]);
+        t2 =
+            ((word32)Tsbox[GETBYTE(s2, 3)] << 24) ^
+            ((word32)Tsbox[GETBYTE(s3, 2)] << 16) ^
+            ((word32)Tsbox[GETBYTE(s0, 1)] <<  8) ^
+            ((word32)Tsbox[GETBYTE(s1, 0)]);
+        t3 =
+            ((word32)Tsbox[GETBYTE(s3, 3)] << 24) ^
+            ((word32)Tsbox[GETBYTE(s0, 2)] << 16) ^
+            ((word32)Tsbox[GETBYTE(s1, 1)] <<  8) ^
+            ((word32)Tsbox[GETBYTE(s2, 0)]);
+
+        s0 =
+            (col_mul(t0, 3, 2, 0, 1) << 24) ^
+            (col_mul(t0, 2, 1, 0, 3) << 16) ^
+            (col_mul(t0, 1, 0, 2, 3) <<  8) ^
+            (col_mul(t0, 0, 3, 2, 1)      ) ^
+            rk[0];
+        s1 =
+            (col_mul(t1, 3, 2, 0, 1) << 24) ^
+            (col_mul(t1, 2, 1, 0, 3) << 16) ^
+            (col_mul(t1, 1, 0, 2, 3) <<  8) ^
+            (col_mul(t1, 0, 3, 2, 1)      ) ^
+            rk[1];
+        s2 =
+            (col_mul(t2, 3, 2, 0, 1) << 24) ^
+            (col_mul(t2, 2, 1, 0, 3) << 16) ^
+            (col_mul(t2, 1, 0, 2, 3) <<  8) ^
+            (col_mul(t2, 0, 3, 2, 1)      ) ^
+            rk[2];
+        s3 =
+            (col_mul(t3, 3, 2, 0, 1) << 24) ^
+            (col_mul(t3, 2, 1, 0, 3) << 16) ^
+            (col_mul(t3, 1, 0, 2, 3) <<  8) ^
+            (col_mul(t3, 0, 3, 2, 1)      ) ^
+            rk[3];
+    }
+
+    t0 =
+        ((word32)Tsbox[GETBYTE(s0, 3)] << 24) ^
+        ((word32)Tsbox[GETBYTE(s1, 2)] << 16) ^
+        ((word32)Tsbox[GETBYTE(s2, 1)] <<  8) ^
+        ((word32)Tsbox[GETBYTE(s3, 0)]);
+    t1 =
+        ((word32)Tsbox[GETBYTE(s1, 3)] << 24) ^
+        ((word32)Tsbox[GETBYTE(s2, 2)] << 16) ^
+        ((word32)Tsbox[GETBYTE(s3, 1)] <<  8) ^
+        ((word32)Tsbox[GETBYTE(s0, 0)]);
+    t2 =
+        ((word32)Tsbox[GETBYTE(s2, 3)] << 24) ^
+        ((word32)Tsbox[GETBYTE(s3, 2)] << 16) ^
+        ((word32)Tsbox[GETBYTE(s0, 1)] <<  8) ^
+        ((word32)Tsbox[GETBYTE(s1, 0)]);
+    t3 =
+        ((word32)Tsbox[GETBYTE(s3, 3)] << 24) ^
+        ((word32)Tsbox[GETBYTE(s0, 2)] << 16) ^
+        ((word32)Tsbox[GETBYTE(s1, 1)] <<  8) ^
+        ((word32)Tsbox[GETBYTE(s2, 0)]);
+    s0 = t0 ^ rk[0];
+    s1 = t1 ^ rk[1];
+    s2 = t2 ^ rk[2];
+    s3 = t3 ^ rk[3];
+#endif
+
+    /* write out */
+#ifdef LITTLE_ENDIAN_ORDER
+    s0 = ByteReverseWord32(s0);
+    s1 = ByteReverseWord32(s1);
+    s2 = ByteReverseWord32(s2);
+    s3 = ByteReverseWord32(s3);
+#endif
+
+    XMEMCPY(outBlock,                  &s0, sizeof(s0));
+    XMEMCPY(outBlock + sizeof(s0),     &s1, sizeof(s1));
+    XMEMCPY(outBlock + 2 * sizeof(s0), &s2, sizeof(s2));
+    XMEMCPY(outBlock + 3 * sizeof(s0), &s3, sizeof(s3));
+
+}
+#endif /* HAVE_AES_CBC || WOLFSSL_AES_DIRECT || HAVE_AESGCM */
+
+#if defined(HAVE_AES_DECRYPT)
+#if (defined(HAVE_AES_CBC) && !defined(WOLFSSL_DEVCRYPTO_CBC)) || \
+     defined(WOLFSSL_AES_DIRECT)
+
+#ifndef WOLFSSL_AES_SMALL_TABLES
+/* load 4 Td Tables into cache by cache line stride */
+static WC_INLINE word32 PreFetchTd(void)
+{
+    word32 x = 0;
+    int i,j;
+
+    for (i = 0; i < 4; i++) {
+        /* 256 elements, each one is 4 bytes */
+        for (j = 0; j < 256; j += WC_CACHE_LINE_SZ/4) {
+            x &= Td[i][j];
+        }
+    }
+    return x;
+}
+#endif
+
+/* load Td Table4 into cache by cache line stride */
+static WC_INLINE word32 PreFetchTd4(void)
+{
+    word32 x = 0;
+    int i;
+
+    for (i = 0; i < 256; i += WC_CACHE_LINE_SZ) {
+        x &= (word32)Td4[i];
+    }
+    return x;
+}
+
+/* Software AES - ECB Decrypt */
+static void wc_AesDecrypt(Aes* aes, const byte* inBlock, byte* outBlock)
+{
+    word32 s0, s1, s2, s3;
+    word32 t0, t1, t2, t3;
+    word32 r = aes->rounds >> 1;
+
+    const word32* rk = aes->key;
+    if (r > 7 || r == 0) {
+        WOLFSSL_MSG("AesDecrypt encountered improper key, set it up");
+        return;  /* stop instead of seg-faulting, set up your keys! */
+    }
+#ifdef WOLFSSL_AESNI
+    if (haveAESNI && aes->use_aesni) {
+        #ifdef DEBUG_AESNI
+            printf("about to aes decrypt\n");
+            printf("in  = %p\n", inBlock);
+            printf("out = %p\n", outBlock);
+            printf("aes->key = %p\n", aes->key);
+            printf("aes->rounds = %d\n", aes->rounds);
+            printf("sz = %d\n", AES_BLOCK_SIZE);
+        #endif
+
+        /* if input and output same will overwrite input iv */
+        if ((const byte*)aes->tmp != inBlock)
+            XMEMCPY(aes->tmp, inBlock, AES_BLOCK_SIZE);
+        AES_ECB_decrypt(inBlock, outBlock, AES_BLOCK_SIZE, (byte*)aes->key,
+                        aes->rounds);
+        return;
+    }
+    else {
+        #ifdef DEBUG_AESNI
+            printf("Skipping AES-NI\n");
+        #endif
+    }
+#endif /* WOLFSSL_AESNI */
+#if defined(WOLFSSL_SCE) && !defined(WOLFSSL_SCE_NO_AES)
+    return AES_ECB_decrypt(aes, inBlock, outBlock, AES_BLOCK_SIZE);
+#endif
+
+    /*
+     * map byte array block to cipher state
+     * and add initial round key:
+     */
+    XMEMCPY(&s0, inBlock,                  sizeof(s0));
+    XMEMCPY(&s1, inBlock + sizeof(s0),     sizeof(s1));
+    XMEMCPY(&s2, inBlock + 2 * sizeof(s0), sizeof(s2));
+    XMEMCPY(&s3, inBlock + 3 * sizeof(s0), sizeof(s3));
+
+#ifdef LITTLE_ENDIAN_ORDER
+    s0 = ByteReverseWord32(s0);
+    s1 = ByteReverseWord32(s1);
+    s2 = ByteReverseWord32(s2);
+    s3 = ByteReverseWord32(s3);
+#endif
+
+    s0 ^= rk[0];
+    s1 ^= rk[1];
+    s2 ^= rk[2];
+    s3 ^= rk[3];
+
+#ifndef WOLFSSL_AES_SMALL_TABLES
+    s0 |= PreFetchTd();
+
+    /*
+     * Nr - 1 full rounds:
+     */
+
+    for (;;) {
+        t0 =
+            Td[0][GETBYTE(s0, 3)] ^
+            Td[1][GETBYTE(s3, 2)] ^
+            Td[2][GETBYTE(s2, 1)] ^
+            Td[3][GETBYTE(s1, 0)] ^
+            rk[4];
+        t1 =
+            Td[0][GETBYTE(s1, 3)] ^
+            Td[1][GETBYTE(s0, 2)] ^
+            Td[2][GETBYTE(s3, 1)] ^
+            Td[3][GETBYTE(s2, 0)] ^
+            rk[5];
+        t2 =
+            Td[0][GETBYTE(s2, 3)] ^
+            Td[1][GETBYTE(s1, 2)] ^
+            Td[2][GETBYTE(s0, 1)] ^
+            Td[3][GETBYTE(s3, 0)] ^
+            rk[6];
+        t3 =
+            Td[0][GETBYTE(s3, 3)] ^
+            Td[1][GETBYTE(s2, 2)] ^
+            Td[2][GETBYTE(s1, 1)] ^
+            Td[3][GETBYTE(s0, 0)] ^
+            rk[7];
+
+        rk += 8;
+        if (--r == 0) {
+            break;
+        }
+
+        s0 =
+            Td[0][GETBYTE(t0, 3)] ^
+            Td[1][GETBYTE(t3, 2)] ^
+            Td[2][GETBYTE(t2, 1)] ^
+            Td[3][GETBYTE(t1, 0)] ^
+            rk[0];
+        s1 =
+            Td[0][GETBYTE(t1, 3)] ^
+            Td[1][GETBYTE(t0, 2)] ^
+            Td[2][GETBYTE(t3, 1)] ^
+            Td[3][GETBYTE(t2, 0)] ^
+            rk[1];
+        s2 =
+            Td[0][GETBYTE(t2, 3)] ^
+            Td[1][GETBYTE(t1, 2)] ^
+            Td[2][GETBYTE(t0, 1)] ^
+            Td[3][GETBYTE(t3, 0)] ^
+            rk[2];
+        s3 =
+            Td[0][GETBYTE(t3, 3)] ^
+            Td[1][GETBYTE(t2, 2)] ^
+            Td[2][GETBYTE(t1, 1)] ^
+            Td[3][GETBYTE(t0, 0)] ^
+            rk[3];
+    }
+    /*
+     * apply last round and
+     * map cipher state to byte array block:
+     */
+
+    t0 |= PreFetchTd4();
+
+    s0 =
+        ((word32)Td4[GETBYTE(t0, 3)] << 24) ^
+        ((word32)Td4[GETBYTE(t3, 2)] << 16) ^
+        ((word32)Td4[GETBYTE(t2, 1)] <<  8) ^
+        ((word32)Td4[GETBYTE(t1, 0)]) ^
+        rk[0];
+    s1 =
+        ((word32)Td4[GETBYTE(t1, 3)] << 24) ^
+        ((word32)Td4[GETBYTE(t0, 2)] << 16) ^
+        ((word32)Td4[GETBYTE(t3, 1)] <<  8) ^
+        ((word32)Td4[GETBYTE(t2, 0)]) ^
+        rk[1];
+    s2 =
+        ((word32)Td4[GETBYTE(t2, 3)] << 24) ^
+        ((word32)Td4[GETBYTE(t1, 2)] << 16) ^
+        ((word32)Td4[GETBYTE(t0, 1)] <<  8) ^
+        ((word32)Td4[GETBYTE(t3, 0)]) ^
+        rk[2];
+    s3 =
+        ((word32)Td4[GETBYTE(t3, 3)] << 24) ^
+        ((word32)Td4[GETBYTE(t2, 2)] << 16) ^
+        ((word32)Td4[GETBYTE(t1, 1)] <<  8) ^
+        ((word32)Td4[GETBYTE(t0, 0)]) ^
+        rk[3];
+#else
+    s0 |= PreFetchTd4();
+
+    r *= 2;
+    for (rk += 4; r > 1; r--, rk += 4) {
+        t0 =
+            ((word32)Td4[GETBYTE(s0, 3)] << 24) ^
+            ((word32)Td4[GETBYTE(s3, 2)] << 16) ^
+            ((word32)Td4[GETBYTE(s2, 1)] <<  8) ^
+            ((word32)Td4[GETBYTE(s1, 0)]) ^
+            rk[0];
+        t1 =
+            ((word32)Td4[GETBYTE(s1, 3)] << 24) ^
+            ((word32)Td4[GETBYTE(s0, 2)] << 16) ^
+            ((word32)Td4[GETBYTE(s3, 1)] <<  8) ^
+            ((word32)Td4[GETBYTE(s2, 0)]) ^
+            rk[1];
+        t2 =
+            ((word32)Td4[GETBYTE(s2, 3)] << 24) ^
+            ((word32)Td4[GETBYTE(s1, 2)] << 16) ^
+            ((word32)Td4[GETBYTE(s0, 1)] <<  8) ^
+            ((word32)Td4[GETBYTE(s3, 0)]) ^
+            rk[2];
+        t3 =
+            ((word32)Td4[GETBYTE(s3, 3)] << 24) ^
+            ((word32)Td4[GETBYTE(s2, 2)] << 16) ^
+            ((word32)Td4[GETBYTE(s1, 1)] <<  8) ^
+            ((word32)Td4[GETBYTE(s0, 0)]) ^
+            rk[3];
+
+        s0 =
+            (inv_col_mul(t0, 0, 2, 1, 3) << 24) ^
+            (inv_col_mul(t0, 3, 1, 0, 2) << 16) ^
+            (inv_col_mul(t0, 2, 0, 3, 1) <<  8) ^
+            (inv_col_mul(t0, 1, 3, 2, 0)      );
+        s1 =
+            (inv_col_mul(t1, 0, 2, 1, 3) << 24) ^
+            (inv_col_mul(t1, 3, 1, 0, 2) << 16) ^
+            (inv_col_mul(t1, 2, 0, 3, 1) <<  8) ^
+            (inv_col_mul(t1, 1, 3, 2, 0)      );
+        s2 =
+            (inv_col_mul(t2, 0, 2, 1, 3) << 24) ^
+            (inv_col_mul(t2, 3, 1, 0, 2) << 16) ^
+            (inv_col_mul(t2, 2, 0, 3, 1) <<  8) ^
+            (inv_col_mul(t2, 1, 3, 2, 0)      );
+        s3 =
+            (inv_col_mul(t3, 0, 2, 1, 3) << 24) ^
+            (inv_col_mul(t3, 3, 1, 0, 2) << 16) ^
+            (inv_col_mul(t3, 2, 0, 3, 1) <<  8) ^
+            (inv_col_mul(t3, 1, 3, 2, 0)      );
+    }
+
+    t0 =
+        ((word32)Td4[GETBYTE(s0, 3)] << 24) ^
+        ((word32)Td4[GETBYTE(s3, 2)] << 16) ^
+        ((word32)Td4[GETBYTE(s2, 1)] <<  8) ^
+        ((word32)Td4[GETBYTE(s1, 0)]);
+    t1 =
+        ((word32)Td4[GETBYTE(s1, 3)] << 24) ^
+        ((word32)Td4[GETBYTE(s0, 2)] << 16) ^
+        ((word32)Td4[GETBYTE(s3, 1)] <<  8) ^
+        ((word32)Td4[GETBYTE(s2, 0)]);
+    t2 =
+        ((word32)Td4[GETBYTE(s2, 3)] << 24) ^
+        ((word32)Td4[GETBYTE(s1, 2)] << 16) ^
+        ((word32)Td4[GETBYTE(s0, 1)] <<  8) ^
+        ((word32)Td4[GETBYTE(s3, 0)]);
+    t3 =
+        ((word32)Td4[GETBYTE(s3, 3)] << 24) ^
+        ((word32)Td4[GETBYTE(s2, 2)] << 16) ^
+        ((word32)Td4[GETBYTE(s1, 1)] <<  8) ^
+        ((word32)Td4[GETBYTE(s0, 0)]);
+    s0 = t0 ^ rk[0];
+    s1 = t1 ^ rk[1];
+    s2 = t2 ^ rk[2];
+    s3 = t3 ^ rk[3];
+#endif
+
+    /* write out */
+#ifdef LITTLE_ENDIAN_ORDER
+    s0 = ByteReverseWord32(s0);
+    s1 = ByteReverseWord32(s1);
+    s2 = ByteReverseWord32(s2);
+    s3 = ByteReverseWord32(s3);
+#endif
+
+    XMEMCPY(outBlock,                  &s0, sizeof(s0));
+    XMEMCPY(outBlock + sizeof(s0),     &s1, sizeof(s1));
+    XMEMCPY(outBlock + 2 * sizeof(s0), &s2, sizeof(s2));
+    XMEMCPY(outBlock + 3 * sizeof(s0), &s3, sizeof(s3));
+}
+#endif /* HAVE_AES_CBC || WOLFSSL_AES_DIRECT */
+#endif /* HAVE_AES_DECRYPT */
+
+#endif /* NEED_AES_TABLES */
+
+
+
+/* wc_AesSetKey */
+#if defined(STM32_CRYPTO)
+
+    int wc_AesSetKey(Aes* aes, const byte* userKey, word32 keylen,
+            const byte* iv, int dir)
+    {
+        word32 *rk;
+
+        (void)dir;
+
+        if (aes == NULL || (keylen != 16 &&
+        #ifdef WOLFSSL_AES_192
+            keylen != 24 &&
+        #endif
+            keylen != 32)) {
+            return BAD_FUNC_ARG;
+        }
+
+        rk = aes->key;
+        aes->keylen = keylen;
+        aes->rounds = keylen/4 + 6;
+        XMEMCPY(rk, userKey, keylen);
+    #if !defined(WOLFSSL_STM32_CUBEMX) || defined(STM32_HAL_V2)
+        ByteReverseWords(rk, rk, keylen);
+    #endif
+    #if defined(WOLFSSL_AES_CFB) || defined(WOLFSSL_AES_COUNTER) || \
+        defined(WOLFSSL_AES_OFB)
+        aes->left = 0;
+    #endif
+
+        return wc_AesSetIV(aes, iv);
+    }
+    #if defined(WOLFSSL_AES_DIRECT)
+        int wc_AesSetKeyDirect(Aes* aes, const byte* userKey, word32 keylen,
+                            const byte* iv, int dir)
+        {
+            return wc_AesSetKey(aes, userKey, keylen, iv, dir);
+        }
+    #endif
+
+#elif defined(HAVE_COLDFIRE_SEC)
+    #if defined (HAVE_THREADX)
+        #include "memory_pools.h"
+        extern TX_BYTE_POOL mp_ncached;  /* Non Cached memory pool */
+    #endif
+
+    #define AES_BUFFER_SIZE (AES_BLOCK_SIZE * 64)
+    static unsigned char *AESBuffIn = NULL;
+    static unsigned char *AESBuffOut = NULL;
+    static byte *secReg;
+    static byte *secKey;
+    static volatile SECdescriptorType *secDesc;
+
+    static wolfSSL_Mutex Mutex_AesSEC;
+
+    #define SEC_DESC_AES_CBC_ENCRYPT 0x60300010
+    #define SEC_DESC_AES_CBC_DECRYPT 0x60200010
+
+    extern volatile unsigned char __MBAR[];
+
+    int wc_AesSetKey(Aes* aes, const byte* userKey, word32 keylen,
+        const byte* iv, int dir)
+    {
+        if (AESBuffIn == NULL) {
+        #if defined (HAVE_THREADX)
+            int s1, s2, s3, s4, s5;
+            s5 = tx_byte_allocate(&mp_ncached,(void *)&secDesc,
+                                  sizeof(SECdescriptorType), TX_NO_WAIT);
+            s1 = tx_byte_allocate(&mp_ncached, (void *)&AESBuffIn,
+                                  AES_BUFFER_SIZE, TX_NO_WAIT);
+            s2 = tx_byte_allocate(&mp_ncached, (void *)&AESBuffOut,
+                                  AES_BUFFER_SIZE, TX_NO_WAIT);
+            s3 = tx_byte_allocate(&mp_ncached, (void *)&secKey,
+                                  AES_BLOCK_SIZE*2, TX_NO_WAIT);
+            s4 = tx_byte_allocate(&mp_ncached, (void *)&secReg,
+                                  AES_BLOCK_SIZE, TX_NO_WAIT);
+
+            if (s1 || s2 || s3 || s4 || s5)
+                return BAD_FUNC_ARG;
+        #else
+            #warning "Allocate non-Cache buffers"
+        #endif
+
+            wc_InitMutex(&Mutex_AesSEC);
+        }
+
+        if (!((keylen == 16) || (keylen == 24) || (keylen == 32)))
+            return BAD_FUNC_ARG;
+
+        if (aes == NULL)
+            return BAD_FUNC_ARG;
+
+        aes->keylen = keylen;
+        aes->rounds = keylen/4 + 6;
+        XMEMCPY(aes->key, userKey, keylen);
+
+        if (iv)
+            XMEMCPY(aes->reg, iv, AES_BLOCK_SIZE);
+
+    #if defined(WOLFSSL_AES_CFB) || defined(WOLFSSL_AES_COUNTER) || \
+        defined(WOLFSSL_AES_OFB)
+        aes->left = 0;
+    #endif
+
+        return 0;
+    }
+#elif defined(FREESCALE_LTC)
+    int wc_AesSetKey(Aes* aes, const byte* userKey, word32 keylen, const byte* iv,
+                  int dir)
+    {
+        if (aes == NULL || !((keylen == 16) || (keylen == 24) || (keylen == 32)))
+            return BAD_FUNC_ARG;
+
+        aes->rounds = keylen/4 + 6;
+        XMEMCPY(aes->key, userKey, keylen);
+
+    #if defined(WOLFSSL_AES_CFB) || defined(WOLFSSL_AES_COUNTER) || \
+        defined(WOLFSSL_AES_OFB)
+        aes->left = 0;
+    #endif
+
+        return wc_AesSetIV(aes, iv);
+    }
+
+    int wc_AesSetKeyDirect(Aes* aes, const byte* userKey, word32 keylen,
+                        const byte* iv, int dir)
+    {
+        return wc_AesSetKey(aes, userKey, keylen, iv, dir);
+    }
+#elif defined(FREESCALE_MMCAU)
+    int wc_AesSetKey(Aes* aes, const byte* userKey, word32 keylen,
+        const byte* iv, int dir)
+    {
+        int ret;
+        byte* rk;
+        byte* tmpKey = (byte*)userKey;
+        int tmpKeyDynamic = 0;
+        word32 alignOffset = 0;
+
+        (void)dir;
+
+        if (!((keylen == 16) || (keylen == 24) || (keylen == 32)))
+            return BAD_FUNC_ARG;
+        if (aes == NULL)
+            return BAD_FUNC_ARG;
+
+        rk = (byte*)aes->key;
+        if (rk == NULL)
+            return BAD_FUNC_ARG;
+
+    #if defined(WOLFSSL_AES_CFB) || defined(WOLFSSL_AES_COUNTER) || \
+        defined(WOLFSSL_AES_OFB)
+        aes->left = 0;
+    #endif
+
+        aes->rounds = keylen/4 + 6;
+
+    #ifdef FREESCALE_MMCAU_CLASSIC
+        if ((wolfssl_word)userKey % WOLFSSL_MMCAU_ALIGNMENT) {
+        #ifndef NO_WOLFSSL_ALLOC_ALIGN
+            byte* tmp = (byte*)XMALLOC(keylen + WOLFSSL_MMCAU_ALIGNMENT,
+                                       aes->heap, DYNAMIC_TYPE_TMP_BUFFER);
+            if (tmp == NULL) {
+                return MEMORY_E;
+            }
+            alignOffset = WOLFSSL_MMCAU_ALIGNMENT -
+                          ((wolfssl_word)tmp % WOLFSSL_MMCAU_ALIGNMENT);
+            tmpKey = tmp + alignOffset;
+            XMEMCPY(tmpKey, userKey, keylen);
+            tmpKeyDynamic = 1;
+        #else
+            WOLFSSL_MSG("Bad cau_aes_set_key alignment");
+            return BAD_ALIGN_E;
+        #endif
+        }
+    #endif
+
+        ret = wolfSSL_CryptHwMutexLock();
+        if(ret == 0) {
+        #ifdef FREESCALE_MMCAU_CLASSIC
+            cau_aes_set_key(tmpKey, keylen*8, rk);
+        #else
+            MMCAU_AES_SetKey(tmpKey, keylen, rk);
+        #endif
+            wolfSSL_CryptHwMutexUnLock();
+
+            ret = wc_AesSetIV(aes, iv);
+        }
+
+        if (tmpKeyDynamic == 1) {
+            XFREE(tmpKey - alignOffset, aes->heap, DYNAMIC_TYPE_TMP_BUFFER);
+        }
+
+        return ret;
+    }
+
+    int wc_AesSetKeyDirect(Aes* aes, const byte* userKey, word32 keylen,
+                        const byte* iv, int dir)
+    {
+        return wc_AesSetKey(aes, userKey, keylen, iv, dir);
+    }
+
+#elif defined(WOLFSSL_NRF51_AES)
+    int wc_AesSetKey(Aes* aes, const byte* userKey, word32 keylen,
+        const byte* iv, int dir)
+    {
+        int ret;
+
+        (void)dir;
+        (void)iv;
+
+        if (aes == NULL || keylen != 16)
+            return BAD_FUNC_ARG;
+
+        aes->keylen = keylen;
+        aes->rounds = keylen/4 + 6;
+        ret = nrf51_aes_set_key(userKey);
+
+    #if defined(WOLFSSL_AES_CFB) || defined(WOLFSSL_AES_COUNTER) || \
+        defined(WOLFSSL_AES_OFB)
+        aes->left = 0;
+    #endif
+
+        return ret;
+    }
+
+    int wc_AesSetKeyDirect(Aes* aes, const byte* userKey, word32 keylen,
+                        const byte* iv, int dir)
+    {
+        return wc_AesSetKey(aes, userKey, keylen, iv, dir);
+    }
+#elif defined(WOLFSSL_ESP32WROOM32_CRYPT) && \
+    !defined(NO_WOLFSSL_ESP32WROOM32_CRYPT_AES)
+
+    int wc_AesSetKey(Aes* aes, const byte* userKey, word32 keylen,
+        const byte* iv, int dir)
+    {
+        (void)dir;
+        (void)iv;
+
+        if (aes == NULL || (keylen != 16 && keylen != 24 && keylen != 32)) {
+            return BAD_FUNC_ARG;
+        }
+
+        aes->keylen = keylen;
+        aes->rounds = keylen/4 + 6;
+
+        XMEMCPY(aes->key, userKey, keylen);
+        #if defined(WOLFSSL_AES_COUNTER)
+            aes->left = 0;
+        #endif
+        return wc_AesSetIV(aes, iv);
+    }
+
+    int wc_AesSetKeyDirect(Aes* aes, const byte* userKey, word32 keylen,
+                        const byte* iv, int dir)
+    {
+        return wc_AesSetKey(aes, userKey, keylen, iv, dir);
+    }
+#elif defined(WOLFSSL_CRYPTOCELL) && defined(WOLFSSL_CRYPTOCELL_AES)
+
+    int wc_AesSetKey(Aes* aes, const byte* userKey, word32 keylen, const byte* iv,
+                    int dir)
+    {
+        SaSiError_t ret = SASI_OK;
+        SaSiAesIv_t iv_aes;
+
+        if (aes == NULL ||
+           (keylen != AES_128_KEY_SIZE &&
+            keylen != AES_192_KEY_SIZE &&
+            keylen != AES_256_KEY_SIZE)) {
+            return BAD_FUNC_ARG;
+        }
+    #if defined(AES_MAX_KEY_SIZE)
+        if (keylen > (AES_MAX_KEY_SIZE/8)) {
+            return BAD_FUNC_ARG;
+        }
+    #endif
+        if (dir != AES_ENCRYPTION &&
+            dir != AES_DECRYPTION) {
+            return BAD_FUNC_ARG;
+        }
+
+        if (dir == AES_ENCRYPTION) {
+            aes->ctx.mode = SASI_AES_ENCRYPT;
+            SaSi_AesInit(&aes->ctx.user_ctx,
+                         SASI_AES_ENCRYPT,
+                         SASI_AES_MODE_CBC,
+                         SASI_AES_PADDING_NONE);
+        }
+        else {
+            aes->ctx.mode = SASI_AES_DECRYPT;
+            SaSi_AesInit(&aes->ctx.user_ctx,
+                         SASI_AES_DECRYPT,
+                         SASI_AES_MODE_CBC,
+                         SASI_AES_PADDING_NONE);
+        }
+
+        aes->keylen = keylen;
+        aes->rounds = keylen/4 + 6;
+        XMEMCPY(aes->key, userKey, keylen);
+
+        aes->ctx.key.pKey = (uint8_t*)aes->key;
+        aes->ctx.key.keySize= keylen;
+
+        ret = SaSi_AesSetKey(&aes->ctx.user_ctx,
+                             SASI_AES_USER_KEY,
+                             &aes->ctx.key,
+                             sizeof(aes->ctx.key));
+        if (ret != SASI_OK) {
+            return BAD_FUNC_ARG;
+        }
+
+        ret = wc_AesSetIV(aes, iv);
+
+        if (iv)
+            XMEMCPY(iv_aes, iv, AES_BLOCK_SIZE);
+        else
+            XMEMSET(iv_aes,  0, AES_BLOCK_SIZE);
+
+
+        ret = SaSi_AesSetIv(&aes->ctx.user_ctx, iv_aes);
+        if (ret != SASI_OK) {
+            return ret;
+        }
+       return ret;
+    }
+    #if defined(WOLFSSL_AES_DIRECT)
+        int wc_AesSetKeyDirect(Aes* aes, const byte* userKey, word32 keylen,
+                            const byte* iv, int dir)
+        {
+            return wc_AesSetKey(aes, userKey, keylen, iv, dir);
+        }
+    #endif
+
+#elif defined(WOLFSSL_IMX6_CAAM) && !defined(NO_IMX6_CAAM_AES)
+      /* implemented in wolfcrypt/src/port/caam/caam_aes.c */
+
+#elif defined(WOLFSSL_AFALG)
+    /* implemented in wolfcrypt/src/port/af_alg/afalg_aes.c */
+
+#elif defined(WOLFSSL_DEVCRYPTO_AES)
+    /* implemented in wolfcrypt/src/port/devcrypto/devcrypto_aes.c */
+
+#else
+
+    /* Software AES - SetKey */
+    static int wc_AesSetKeyLocal(Aes* aes, const byte* userKey, word32 keylen,
+                const byte* iv, int dir)
+    {
+        word32 *rk = aes->key;
+    #ifdef NEED_AES_TABLES
+        word32 temp;
+        unsigned int i = 0;
+    #endif
+
+        #ifdef WOLFSSL_AESNI
+            aes->use_aesni = 0;
+        #endif /* WOLFSSL_AESNI */
+        #if defined(WOLFSSL_AES_CFB) || defined(WOLFSSL_AES_COUNTER) || \
+            defined(WOLFSSL_AES_OFB)
+            aes->left = 0;
+        #endif
+
+        aes->keylen = keylen;
+        aes->rounds = (keylen/4) + 6;
+
+        XMEMCPY(rk, userKey, keylen);
+    #if defined(LITTLE_ENDIAN_ORDER) && !defined(WOLFSSL_PIC32MZ_CRYPT) && \
+        (!defined(WOLFSSL_ESP32WROOM32_CRYPT) || \
+          defined(NO_WOLFSSL_ESP32WROOM32_CRYPT_AES))
+        ByteReverseWords(rk, rk, keylen);
+    #endif
+
+#ifdef NEED_AES_TABLES
+        switch (keylen) {
+    #if defined(AES_MAX_KEY_SIZE) && AES_MAX_KEY_SIZE >= 128 && \
+            defined(WOLFSSL_AES_128)
+        case 16:
+            while (1)
+            {
+                temp  = rk[3];
+                rk[4] = rk[0] ^
+            #ifndef WOLFSSL_AES_SMALL_TABLES
+                    (Te[2][GETBYTE(temp, 2)] & 0xff000000) ^
+                    (Te[3][GETBYTE(temp, 1)] & 0x00ff0000) ^
+                    (Te[0][GETBYTE(temp, 0)] & 0x0000ff00) ^
+                    (Te[1][GETBYTE(temp, 3)] & 0x000000ff) ^
+            #else
+                    ((word32)Tsbox[GETBYTE(temp, 2)] << 24) ^
+                    ((word32)Tsbox[GETBYTE(temp, 1)] << 16) ^
+                    ((word32)Tsbox[GETBYTE(temp, 0)] <<  8) ^
+                    ((word32)Tsbox[GETBYTE(temp, 3)]) ^
+            #endif
+                    rcon[i];
+                rk[5] = rk[1] ^ rk[4];
+                rk[6] = rk[2] ^ rk[5];
+                rk[7] = rk[3] ^ rk[6];
+                if (++i == 10)
+                    break;
+                rk += 4;
+            }
+            break;
+    #endif /* 128 */
+
+    #if defined(AES_MAX_KEY_SIZE) && AES_MAX_KEY_SIZE >= 192 && \
+            defined(WOLFSSL_AES_192)
+        case 24:
+            /* for (;;) here triggers a bug in VC60 SP4 w/ Pro Pack */
+            while (1)
+            {
+                temp = rk[ 5];
+                rk[ 6] = rk[ 0] ^
+            #ifndef WOLFSSL_AES_SMALL_TABLES
+                    (Te[2][GETBYTE(temp, 2)] & 0xff000000) ^
+                    (Te[3][GETBYTE(temp, 1)] & 0x00ff0000) ^
+                    (Te[0][GETBYTE(temp, 0)] & 0x0000ff00) ^
+                    (Te[1][GETBYTE(temp, 3)] & 0x000000ff) ^
+            #else
+                    ((word32)Tsbox[GETBYTE(temp, 2)] << 24) ^
+                    ((word32)Tsbox[GETBYTE(temp, 1)] << 16) ^
+                    ((word32)Tsbox[GETBYTE(temp, 0)] <<  8) ^
+                    ((word32)Tsbox[GETBYTE(temp, 3)]) ^
+            #endif
+                    rcon[i];
+                rk[ 7] = rk[ 1] ^ rk[ 6];
+                rk[ 8] = rk[ 2] ^ rk[ 7];
+                rk[ 9] = rk[ 3] ^ rk[ 8];
+                if (++i == 8)
+                    break;
+                rk[10] = rk[ 4] ^ rk[ 9];
+                rk[11] = rk[ 5] ^ rk[10];
+                rk += 6;
+            }
+            break;
+    #endif /* 192 */
+
+    #if defined(AES_MAX_KEY_SIZE) && AES_MAX_KEY_SIZE >= 256 && \
+            defined(WOLFSSL_AES_256)
+        case 32:
+            while (1)
+            {
+                temp = rk[ 7];
+                rk[ 8] = rk[ 0] ^
+            #ifndef WOLFSSL_AES_SMALL_TABLES
+                    (Te[2][GETBYTE(temp, 2)] & 0xff000000) ^
+                    (Te[3][GETBYTE(temp, 1)] & 0x00ff0000) ^
+                    (Te[0][GETBYTE(temp, 0)] & 0x0000ff00) ^
+                    (Te[1][GETBYTE(temp, 3)] & 0x000000ff) ^
+            #else
+                    ((word32)Tsbox[GETBYTE(temp, 2)] << 24) ^
+                    ((word32)Tsbox[GETBYTE(temp, 1)] << 16) ^
+                    ((word32)Tsbox[GETBYTE(temp, 0)] <<  8) ^
+                    ((word32)Tsbox[GETBYTE(temp, 3)]) ^
+            #endif
+                    rcon[i];
+                rk[ 9] = rk[ 1] ^ rk[ 8];
+                rk[10] = rk[ 2] ^ rk[ 9];
+                rk[11] = rk[ 3] ^ rk[10];
+                if (++i == 7)
+                    break;
+                temp = rk[11];
+                rk[12] = rk[ 4] ^
+            #ifndef WOLFSSL_AES_SMALL_TABLES
+                    (Te[2][GETBYTE(temp, 3)] & 0xff000000) ^
+                    (Te[3][GETBYTE(temp, 2)] & 0x00ff0000) ^
+                    (Te[0][GETBYTE(temp, 1)] & 0x0000ff00) ^
+                    (Te[1][GETBYTE(temp, 0)] & 0x000000ff);
+            #else
+                    ((word32)Tsbox[GETBYTE(temp, 3)] << 24) ^
+                    ((word32)Tsbox[GETBYTE(temp, 2)] << 16) ^
+                    ((word32)Tsbox[GETBYTE(temp, 1)] <<  8) ^
+                    ((word32)Tsbox[GETBYTE(temp, 0)]);
+            #endif
+                rk[13] = rk[ 5] ^ rk[12];
+                rk[14] = rk[ 6] ^ rk[13];
+                rk[15] = rk[ 7] ^ rk[14];
+
+                rk += 8;
+            }
+            break;
+    #endif /* 256 */
+
+        default:
+            return BAD_FUNC_ARG;
+        } /* switch */
+
+    #if defined(HAVE_AES_DECRYPT)
+        if (dir == AES_DECRYPTION) {
+            unsigned int j;
+            rk = aes->key;
+
+            /* invert the order of the round keys: */
+            for (i = 0, j = 4* aes->rounds; i < j; i += 4, j -= 4) {
+                temp = rk[i    ]; rk[i    ] = rk[j    ]; rk[j    ] = temp;
+                temp = rk[i + 1]; rk[i + 1] = rk[j + 1]; rk[j + 1] = temp;
+                temp = rk[i + 2]; rk[i + 2] = rk[j + 2]; rk[j + 2] = temp;
+                temp = rk[i + 3]; rk[i + 3] = rk[j + 3]; rk[j + 3] = temp;
+            }
+        #if !defined(WOLFSSL_AES_SMALL_TABLES)
+            /* apply the inverse MixColumn transform to all round keys but the
+               first and the last: */
+            for (i = 1; i < aes->rounds; i++) {
+                rk += 4;
+                rk[0] =
+                    Td[0][Te[1][GETBYTE(rk[0], 3)] & 0xff] ^
+                    Td[1][Te[1][GETBYTE(rk[0], 2)] & 0xff] ^
+                    Td[2][Te[1][GETBYTE(rk[0], 1)] & 0xff] ^
+                    Td[3][Te[1][GETBYTE(rk[0], 0)] & 0xff];
+                rk[1] =
+                    Td[0][Te[1][GETBYTE(rk[1], 3)] & 0xff] ^
+                    Td[1][Te[1][GETBYTE(rk[1], 2)] & 0xff] ^
+                    Td[2][Te[1][GETBYTE(rk[1], 1)] & 0xff] ^
+                    Td[3][Te[1][GETBYTE(rk[1], 0)] & 0xff];
+                rk[2] =
+                    Td[0][Te[1][GETBYTE(rk[2], 3)] & 0xff] ^
+                    Td[1][Te[1][GETBYTE(rk[2], 2)] & 0xff] ^
+                    Td[2][Te[1][GETBYTE(rk[2], 1)] & 0xff] ^
+                    Td[3][Te[1][GETBYTE(rk[2], 0)] & 0xff];
+                rk[3] =
+                    Td[0][Te[1][GETBYTE(rk[3], 3)] & 0xff] ^
+                    Td[1][Te[1][GETBYTE(rk[3], 2)] & 0xff] ^
+                    Td[2][Te[1][GETBYTE(rk[3], 1)] & 0xff] ^
+                    Td[3][Te[1][GETBYTE(rk[3], 0)] & 0xff];
+            }
+        #endif
+        }
+    #else
+        (void)dir;
+    #endif /* HAVE_AES_DECRYPT */
+        (void)temp;
+#endif /* NEED_AES_TABLES */
+
+#if defined(WOLFSSL_SCE) && !defined(WOLFSSL_SCE_NO_AES)
+        XMEMCPY((byte*)aes->key, userKey, keylen);
+        if (WOLFSSL_SCE_GSCE_HANDLE.p_cfg->endian_flag == CRYPTO_WORD_ENDIAN_BIG) {
+            ByteReverseWords(aes->key, aes->key, 32);
+        }
+#endif
+
+        return wc_AesSetIV(aes, iv);
+    }
+
+    int wc_AesSetKey(Aes* aes, const byte* userKey, word32 keylen,
+        const byte* iv, int dir)
+    {
+        int ret;
+    #if defined(AES_MAX_KEY_SIZE)
+        const word32 max_key_len = (AES_MAX_KEY_SIZE / 8);
+    #endif
+
+    #ifdef WOLFSSL_IMX6_CAAM_BLOB
+        byte   local[32];
+        word32 localSz = 32;
+
+        if (keylen == (16 + WC_CAAM_BLOB_SZ) ||
+                keylen == (24 + WC_CAAM_BLOB_SZ) ||
+                keylen == (32 + WC_CAAM_BLOB_SZ)) {
+            if (wc_caamOpenBlob((byte*)userKey, keylen, local, &localSz) != 0) {
+                return BAD_FUNC_ARG;
+            }
+
+            /* set local values */
+            userKey = local;
+            keylen = localSz;
+        }
+    #endif
+        if (aes == NULL ||
+                !((keylen == 16) || (keylen == 24) || (keylen == 32))) {
+            return BAD_FUNC_ARG;
+        }
+
+    #if defined(AES_MAX_KEY_SIZE)
+        /* Check key length */
+        if (keylen > max_key_len) {
+            return BAD_FUNC_ARG;
+        }
+    #endif
+        aes->keylen = keylen;
+        aes->rounds = keylen/4 + 6;
+
+    #if defined(WOLF_CRYPTO_CB) || (defined(WOLFSSL_DEVCRYPTO) && \
+        (defined(WOLFSSL_DEVCRYPTO_AES) || defined(WOLFSSL_DEVCRYPTO_CBC))) || \
+        (defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_AES))
+        #ifdef WOLF_CRYPTO_CB
+        if (aes->devId != INVALID_DEVID)
+        #endif
+        {
+            XMEMCPY(aes->devKey, userKey, keylen);
+        }
+    #endif
+
+    #ifdef WOLFSSL_AESNI
+        if (checkAESNI == 0) {
+            haveAESNI  = Check_CPU_support_AES();
+            checkAESNI = 1;
+        }
+        if (haveAESNI) {
+            #if defined(WOLFSSL_AES_COUNTER) || defined(WOLFSSL_AES_CFB) || \
+                defined(WOLFSSL_AES_OFB)
+                aes->left = 0;
+            #endif /* WOLFSSL_AES_COUNTER */
+            aes->use_aesni = 1;
+            if (iv)
+                XMEMCPY(aes->reg, iv, AES_BLOCK_SIZE);
+            else
+                XMEMSET(aes->reg, 0, AES_BLOCK_SIZE);
+            if (dir == AES_ENCRYPTION)
+                return AES_set_encrypt_key(userKey, keylen * 8, aes);
+        #ifdef HAVE_AES_DECRYPT
+            else
+                return AES_set_decrypt_key(userKey, keylen * 8, aes);
+        #endif
+        }
+    #endif /* WOLFSSL_AESNI */
+
+        ret = wc_AesSetKeyLocal(aes, userKey, keylen, iv, dir);
+
+    #if defined(WOLFSSL_DEVCRYPTO) && \
+        (defined(WOLFSSL_DEVCRYPTO_AES) || defined(WOLFSSL_DEVCRYPTO_CBC))
+        aes->ctx.cfd = -1;
+    #endif
+    #ifdef WOLFSSL_IMX6_CAAM_BLOB
+        ForceZero(local, sizeof(local));
+    #endif
+        return ret;
+    }
+
+    #if defined(WOLFSSL_AES_DIRECT) || defined(WOLFSSL_AES_COUNTER)
+        /* AES-CTR and AES-DIRECT need to use this for key setup, no aesni yet */
+        int wc_AesSetKeyDirect(Aes* aes, const byte* userKey, word32 keylen,
+                            const byte* iv, int dir)
+        {
+            int ret;
+
+        #ifdef WOLFSSL_IMX6_CAAM_BLOB
+            byte   local[32];
+            word32 localSz = 32;
+
+            if (keylen == (16 + WC_CAAM_BLOB_SZ) ||
+             keylen == (24 + WC_CAAM_BLOB_SZ) ||
+             keylen == (32 + WC_CAAM_BLOB_SZ)) {
+                if (wc_caamOpenBlob((byte*)userKey, keylen, local, &localSz)
+                        != 0) {
+                    return BAD_FUNC_ARG;
+                }
+
+                /* set local values */
+                userKey = local;
+                keylen = localSz;
+            }
+        #endif
+            ret = wc_AesSetKeyLocal(aes, userKey, keylen, iv, dir);
+
+        #ifdef WOLFSSL_IMX6_CAAM_BLOB
+            ForceZero(local, sizeof(local));
+        #endif
+
+            return ret;
+        }
+    #endif /* WOLFSSL_AES_DIRECT || WOLFSSL_AES_COUNTER */
+#endif /* wc_AesSetKey block */
+
+
+/* wc_AesSetIV is shared between software and hardware */
+int wc_AesSetIV(Aes* aes, const byte* iv)
+{
+    if (aes == NULL)
+        return BAD_FUNC_ARG;
+
+    if (iv)
+        XMEMCPY(aes->reg, iv, AES_BLOCK_SIZE);
+    else
+        XMEMSET(aes->reg,  0, AES_BLOCK_SIZE);
+
+    return 0;
+}
+
+/* AES-DIRECT */
+#if defined(WOLFSSL_AES_DIRECT)
+    #if defined(HAVE_COLDFIRE_SEC)
+        #error "Coldfire SEC doesn't yet support AES direct"
+
+    #elif defined(FREESCALE_LTC)
+        /* Allow direct access to one block encrypt */
+        void wc_AesEncryptDirect(Aes* aes, byte* out, const byte* in)
+        {
+            byte *key;
+            uint32_t keySize;
+
+            key = (byte*)aes->key;
+            wc_AesGetKeySize(aes, &keySize);
+
+            LTC_AES_EncryptEcb(LTC_BASE, in, out, AES_BLOCK_SIZE,
+                key, keySize);
+        }
+
+        /* Allow direct access to one block decrypt */
+        void wc_AesDecryptDirect(Aes* aes, byte* out, const byte* in)
+        {
+            byte *key;
+            uint32_t keySize;
+
+            key = (byte*)aes->key;
+            wc_AesGetKeySize(aes, &keySize);
+
+            LTC_AES_DecryptEcb(LTC_BASE, in, out, AES_BLOCK_SIZE,
+                key, keySize, kLTC_EncryptKey);
+        }
+
+    #elif defined(WOLFSSL_IMX6_CAAM) && !defined(NO_IMX6_CAAM_AES)
+        /* implemented in wolfcrypt/src/port/caam/caam_aes.c */
+
+    #elif defined(WOLFSSL_AFALG)
+        /* implemented in wolfcrypt/src/port/af_alg/afalg_aes.c */
+
+    #elif defined(WOLFSSL_DEVCRYPTO_AES)
+        /* implemented in wolfcrypt/src/port/devcrypt/devcrypto_aes.c */
+
+    #elif defined(STM32_CRYPTO)
+        /* Allow direct access to one block encrypt */
+        void wc_AesEncryptDirect(Aes* aes, byte* out, const byte* in)
+        {
+            if (wolfSSL_CryptHwMutexLock() == 0) {
+                wc_AesEncrypt(aes, in, out);
+                wolfSSL_CryptHwMutexUnLock();
+            }
+        }
+        #ifdef HAVE_AES_DECRYPT
+        /* Allow direct access to one block decrypt */
+        void wc_AesDecryptDirect(Aes* aes, byte* out, const byte* in)
+        {
+            if (wolfSSL_CryptHwMutexLock() == 0) {
+                wc_AesDecrypt(aes, in, out);
+                wolfSSL_CryptHwMutexUnLock();
+            }
+        }
+        #endif /* HAVE_AES_DECRYPT */
+
+    #elif defined(WOLFSSL_ESP32WROOM32_CRYPT) && \
+        !defined(NO_WOLFSSL_ESP32WROOM32_CRYPT_AES)
+        
+        /* Allow direct access to one block encrypt */
+        void wc_AesEncryptDirect(Aes* aes, byte* out, const byte* in)
+        {
+            wc_AesEncrypt(aes, in, out);
+        }
+        #ifdef HAVE_AES_DECRYPT
+        /* Allow direct access to one block decrypt */
+        void wc_AesDecryptDirect(Aes* aes, byte* out, const byte* in)
+        {
+            wc_AesDecrypt(aes, in, out);
+        }
+        #endif /* HAVE_AES_DECRYPT */
+    #else
+        /* Allow direct access to one block encrypt */
+        void wc_AesEncryptDirect(Aes* aes, byte* out, const byte* in)
+        {
+            wc_AesEncrypt(aes, in, out);
+        }
+        #ifdef HAVE_AES_DECRYPT
+        /* Allow direct access to one block decrypt */
+        void wc_AesDecryptDirect(Aes* aes, byte* out, const byte* in)
+        {
+            wc_AesDecrypt(aes, in, out);
+        }
+        #endif /* HAVE_AES_DECRYPT */
+    #endif /* AES direct block */
+#endif /* WOLFSSL_AES_DIRECT */
+
+
+/* AES-CBC */
+#ifdef HAVE_AES_CBC
+#if defined(STM32_CRYPTO)
+
+#ifdef WOLFSSL_STM32_CUBEMX
+    int wc_AesCbcEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
+    {
+        int ret = 0;
+        word32 blocks = (sz / AES_BLOCK_SIZE);
+        CRYP_HandleTypeDef hcryp;
+
+        ret = wc_Stm32_Aes_Init(aes, &hcryp);
+        if (ret != 0)
+            return ret;
+
+        ret = wolfSSL_CryptHwMutexLock();
+        if (ret != 0) {
+            return ret;
+        }
+
+    #ifdef STM32_CRYPTO_AES_ONLY
+        hcryp.Init.OperatingMode = CRYP_ALGOMODE_ENCRYPT;
+        hcryp.Init.ChainingMode  = CRYP_CHAINMODE_AES_CBC;
+        hcryp.Init.KeyWriteFlag  = CRYP_KEY_WRITE_ENABLE;
+    #elif defined(STM32_HAL_V2)
+        hcryp.Init.Algorithm  = CRYP_AES_CBC;
+        ByteReverseWords(aes->reg, aes->reg, AES_BLOCK_SIZE);
+    #endif
+        hcryp.Init.pInitVect = (STM_CRYPT_TYPE*)aes->reg;
+        HAL_CRYP_Init(&hcryp);
+
+        while (blocks--) {
+        #ifdef STM32_CRYPTO_AES_ONLY
+            ret = HAL_CRYPEx_AES(&hcryp, (uint8_t*)in, AES_BLOCK_SIZE,
+                out, STM32_HAL_TIMEOUT);
+        #elif defined(STM32_HAL_V2)
+            ret = HAL_CRYP_Encrypt(&hcryp, (uint32_t*)in, AES_BLOCK_SIZE,
+                (uint32_t*)out, STM32_HAL_TIMEOUT);
+        #else
+            ret = HAL_CRYP_AESCBC_Encrypt(&hcryp, (uint8_t*)in, AES_BLOCK_SIZE,
+                out, STM32_HAL_TIMEOUT);
+        #endif
+            if (ret != HAL_OK) {
+                ret = WC_TIMEOUT_E;
+                break;
+            }
+
+            /* store iv for next call */
+            XMEMCPY(aes->reg, out + sz - AES_BLOCK_SIZE, AES_BLOCK_SIZE);
+
+            sz  -= AES_BLOCK_SIZE;
+            in  += AES_BLOCK_SIZE;
+            out += AES_BLOCK_SIZE;
+        }
+
+        HAL_CRYP_DeInit(&hcryp);
+
+        wolfSSL_CryptHwMutexUnLock();
+
+        return ret;
+    }
+    #ifdef HAVE_AES_DECRYPT
+    int wc_AesCbcDecrypt(Aes* aes, byte* out, const byte* in, word32 sz)
+    {
+        int ret = 0;
+        word32 blocks = (sz / AES_BLOCK_SIZE);
+        CRYP_HandleTypeDef hcryp;
+
+        ret = wc_Stm32_Aes_Init(aes, &hcryp);
+        if (ret != 0)
+            return ret;
+
+        ret = wolfSSL_CryptHwMutexLock();
+        if (ret != 0) {
+            return ret;
+        }
+
+        /* if input and output same will overwrite input iv */
+        XMEMCPY(aes->tmp, in + sz - AES_BLOCK_SIZE, AES_BLOCK_SIZE);
+
+    #ifdef STM32_CRYPTO_AES_ONLY
+        hcryp.Init.OperatingMode = CRYP_ALGOMODE_KEYDERIVATION_DECRYPT;
+        hcryp.Init.ChainingMode  = CRYP_CHAINMODE_AES_CBC;
+        hcryp.Init.KeyWriteFlag  = CRYP_KEY_WRITE_ENABLE;
+    #elif defined(STM32_HAL_V2)
+        hcryp.Init.Algorithm  = CRYP_AES_CBC;
+        ByteReverseWords(aes->reg, aes->reg, AES_BLOCK_SIZE);
+    #endif
+
+        hcryp.Init.pInitVect = (STM_CRYPT_TYPE*)aes->reg;
+        HAL_CRYP_Init(&hcryp);
+
+        while (blocks--) {
+        #ifdef STM32_CRYPTO_AES_ONLY
+            ret = HAL_CRYPEx_AES(&hcryp, (uint8_t*)in, AES_BLOCK_SIZE,
+                out, STM32_HAL_TIMEOUT);
+        #elif defined(STM32_HAL_V2)
+            ret = HAL_CRYP_Decrypt(&hcryp, (uint32_t*)in, AES_BLOCK_SIZE,
+                (uint32_t*)out, STM32_HAL_TIMEOUT);
+        #else
+            ret = HAL_CRYP_AESCBC_Decrypt(&hcryp, (uint8_t*)in, AES_BLOCK_SIZE,
+                out, STM32_HAL_TIMEOUT);
+        #endif
+            if (ret != HAL_OK) {
+                ret = WC_TIMEOUT_E;
+                break;
+            }
+
+            /* store iv for next call */
+            XMEMCPY(aes->reg, aes->tmp, AES_BLOCK_SIZE);
+
+            in  += AES_BLOCK_SIZE;
+            out += AES_BLOCK_SIZE;
+        }
+
+        HAL_CRYP_DeInit(&hcryp);
+        wolfSSL_CryptHwMutexUnLock();
+
+        return ret;
+    }
+    #endif /* HAVE_AES_DECRYPT */
+
+#else /* STD_PERI_LIB */
+    int wc_AesCbcEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
+    {
+        int ret;
+        word32 *iv;
+        word32 blocks = (sz / AES_BLOCK_SIZE);
+        CRYP_InitTypeDef cryptInit;
+        CRYP_KeyInitTypeDef keyInit;
+        CRYP_IVInitTypeDef ivInit;
+
+        ret = wc_Stm32_Aes_Init(aes, &cryptInit, &keyInit);
+        if (ret != 0)
+            return ret;
+
+        ret = wolfSSL_CryptHwMutexLock();
+        if (ret != 0) {
+            return ret;
+        }
+
+        /* reset registers to their default values */
+        CRYP_DeInit();
+
+        /* set key */
+        CRYP_KeyInit(&keyInit);
+
+        /* set iv */
+        iv = aes->reg;
+        CRYP_IVStructInit(&ivInit);
+        ByteReverseWords(iv, iv, AES_BLOCK_SIZE);
+        ivInit.CRYP_IV0Left  = iv[0];
+        ivInit.CRYP_IV0Right = iv[1];
+        ivInit.CRYP_IV1Left  = iv[2];
+        ivInit.CRYP_IV1Right = iv[3];
+        CRYP_IVInit(&ivInit);
+
+        /* set direction and mode */
+        cryptInit.CRYP_AlgoDir  = CRYP_AlgoDir_Encrypt;
+        cryptInit.CRYP_AlgoMode = CRYP_AlgoMode_AES_CBC;
+        CRYP_Init(&cryptInit);
+
+        /* enable crypto processor */
+        CRYP_Cmd(ENABLE);
+
+        while (blocks--) {
+            /* flush IN/OUT FIFOs */
+            CRYP_FIFOFlush();
+
+            CRYP_DataIn(*(uint32_t*)&in[0]);
+            CRYP_DataIn(*(uint32_t*)&in[4]);
+            CRYP_DataIn(*(uint32_t*)&in[8]);
+            CRYP_DataIn(*(uint32_t*)&in[12]);
+
+            /* wait until the complete message has been processed */
+            while (CRYP_GetFlagStatus(CRYP_FLAG_BUSY) != RESET) {}
+
+            *(uint32_t*)&out[0]  = CRYP_DataOut();
+            *(uint32_t*)&out[4]  = CRYP_DataOut();
+            *(uint32_t*)&out[8]  = CRYP_DataOut();
+            *(uint32_t*)&out[12] = CRYP_DataOut();
+
+            /* store iv for next call */
+            XMEMCPY(aes->reg, out + sz - AES_BLOCK_SIZE, AES_BLOCK_SIZE);
+
+            sz  -= AES_BLOCK_SIZE;
+            in  += AES_BLOCK_SIZE;
+            out += AES_BLOCK_SIZE;
+        }
+
+        /* disable crypto processor */
+        CRYP_Cmd(DISABLE);
+        wolfSSL_CryptHwMutexUnLock();
+
+        return ret;
+    }
+
+    #ifdef HAVE_AES_DECRYPT
+    int wc_AesCbcDecrypt(Aes* aes, byte* out, const byte* in, word32 sz)
+    {
+        int ret;
+        word32 *iv;
+        word32 blocks = (sz / AES_BLOCK_SIZE);
+        CRYP_InitTypeDef cryptInit;
+        CRYP_KeyInitTypeDef keyInit;
+        CRYP_IVInitTypeDef ivInit;
+
+        ret = wc_Stm32_Aes_Init(aes, &cryptInit, &keyInit);
+        if (ret != 0)
+            return ret;
+
+        ret = wolfSSL_CryptHwMutexLock();
+        if (ret != 0) {
+            return ret;
+        }
+
+        /* if input and output same will overwrite input iv */
+        XMEMCPY(aes->tmp, in + sz - AES_BLOCK_SIZE, AES_BLOCK_SIZE);
+
+        /* reset registers to their default values */
+        CRYP_DeInit();
+
+        /* set direction and key */
+        CRYP_KeyInit(&keyInit);
+        cryptInit.CRYP_AlgoDir  = CRYP_AlgoDir_Decrypt;
+        cryptInit.CRYP_AlgoMode = CRYP_AlgoMode_AES_Key;
+        CRYP_Init(&cryptInit);
+
+        /* enable crypto processor */
+        CRYP_Cmd(ENABLE);
+
+        /* wait until key has been prepared */
+        while (CRYP_GetFlagStatus(CRYP_FLAG_BUSY) != RESET) {}
+
+        /* set direction and mode */
+        cryptInit.CRYP_AlgoDir  = CRYP_AlgoDir_Decrypt;
+        cryptInit.CRYP_AlgoMode = CRYP_AlgoMode_AES_CBC;
+        CRYP_Init(&cryptInit);
+
+        /* set iv */
+        iv = aes->reg;
+        CRYP_IVStructInit(&ivInit);
+        ByteReverseWords(iv, iv, AES_BLOCK_SIZE);
+        ivInit.CRYP_IV0Left  = iv[0];
+        ivInit.CRYP_IV0Right = iv[1];
+        ivInit.CRYP_IV1Left  = iv[2];
+        ivInit.CRYP_IV1Right = iv[3];
+        CRYP_IVInit(&ivInit);
+
+        /* enable crypto processor */
+        CRYP_Cmd(ENABLE);
+
+        while (blocks--) {
+            /* flush IN/OUT FIFOs */
+            CRYP_FIFOFlush();
+
+            CRYP_DataIn(*(uint32_t*)&in[0]);
+            CRYP_DataIn(*(uint32_t*)&in[4]);
+            CRYP_DataIn(*(uint32_t*)&in[8]);
+            CRYP_DataIn(*(uint32_t*)&in[12]);
+
+            /* wait until the complete message has been processed */
+            while (CRYP_GetFlagStatus(CRYP_FLAG_BUSY) != RESET) {}
+
+            *(uint32_t*)&out[0]  = CRYP_DataOut();
+            *(uint32_t*)&out[4]  = CRYP_DataOut();
+            *(uint32_t*)&out[8]  = CRYP_DataOut();
+            *(uint32_t*)&out[12] = CRYP_DataOut();
+
+            /* store iv for next call */
+            XMEMCPY(aes->reg, aes->tmp, AES_BLOCK_SIZE);
+
+            in  += AES_BLOCK_SIZE;
+            out += AES_BLOCK_SIZE;
+        }
+
+        /* disable crypto processor */
+        CRYP_Cmd(DISABLE);
+        wolfSSL_CryptHwMutexUnLock();
+
+        return ret;
+    }
+    #endif /* HAVE_AES_DECRYPT */
+#endif /* WOLFSSL_STM32_CUBEMX */
+
+#elif defined(HAVE_COLDFIRE_SEC)
+    static int wc_AesCbcCrypt(Aes* aes, byte* po, const byte* pi, word32 sz,
+        word32 descHeader)
+    {
+        #ifdef DEBUG_WOLFSSL
+            int i; int stat1, stat2; int ret;
+        #endif
+
+        int size;
+        volatile int v;
+
+        if ((pi == NULL) || (po == NULL))
+            return BAD_FUNC_ARG;    /*wrong pointer*/
+
+        wc_LockMutex(&Mutex_AesSEC);
+
+        /* Set descriptor for SEC */
+        secDesc->length1 = 0x0;
+        secDesc->pointer1 = NULL;
+
+        secDesc->length2 = AES_BLOCK_SIZE;
+        secDesc->pointer2 = (byte *)secReg; /* Initial Vector */
+
+        switch(aes->rounds) {
+            case 10: secDesc->length3 = 16; break;
+            case 12: secDesc->length3 = 24; break;
+            case 14: secDesc->length3 = 32; break;
+        }
+        XMEMCPY(secKey, aes->key, secDesc->length3);
+
+        secDesc->pointer3 = (byte *)secKey;
+        secDesc->pointer4 = AESBuffIn;
+        secDesc->pointer5 = AESBuffOut;
+        secDesc->length6 = 0x0;
+        secDesc->pointer6 = NULL;
+        secDesc->length7 = 0x0;
+        secDesc->pointer7 = NULL;
+        secDesc->nextDescriptorPtr = NULL;
+
+        while (sz) {
+            secDesc->header = descHeader;
+            XMEMCPY(secReg, aes->reg, AES_BLOCK_SIZE);
+            if ((sz % AES_BUFFER_SIZE) == sz) {
+                size = sz;
+                sz = 0;
+            } else {
+                size = AES_BUFFER_SIZE;
+                sz -= AES_BUFFER_SIZE;
+            }
+            secDesc->length4 = size;
+            secDesc->length5 = size;
+
+            XMEMCPY(AESBuffIn, pi, size);
+            if(descHeader == SEC_DESC_AES_CBC_DECRYPT) {
+                XMEMCPY((void*)aes->tmp, (void*)&(pi[size-AES_BLOCK_SIZE]),
+                        AES_BLOCK_SIZE);
+            }
+
+            /* Point SEC to the location of the descriptor */
+            MCF_SEC_FR0 = (uint32)secDesc;
+            /* Initialize SEC and wait for encryption to complete */
+            MCF_SEC_CCCR0 = 0x0000001a;
+            /* poll SISR to determine when channel is complete */
+            v=0;
+
+            while ((secDesc->header>> 24) != 0xff) v++;
+
+            #ifdef DEBUG_WOLFSSL
+                ret = MCF_SEC_SISRH;
+                stat1 = MCF_SEC_AESSR;
+                stat2 = MCF_SEC_AESISR;
+                if (ret & 0xe0000000) {
+                    db_printf("Aes_Cbc(i=%d):ISRH=%08x, AESSR=%08x, "
+                              "AESISR=%08x\n", i, ret, stat1, stat2);
+                }
+            #endif
+
+            XMEMCPY(po, AESBuffOut, size);
+
+            if (descHeader == SEC_DESC_AES_CBC_ENCRYPT) {
+                XMEMCPY((void*)aes->reg, (void*)&(po[size-AES_BLOCK_SIZE]),
+                        AES_BLOCK_SIZE);
+            } else {
+                XMEMCPY((void*)aes->reg, (void*)aes->tmp, AES_BLOCK_SIZE);
+            }
+
+            pi += size;
+            po += size;
+        }
+
+        wc_UnLockMutex(&Mutex_AesSEC);
+        return 0;
+    }
+
+    int wc_AesCbcEncrypt(Aes* aes, byte* po, const byte* pi, word32 sz)
+    {
+        return (wc_AesCbcCrypt(aes, po, pi, sz, SEC_DESC_AES_CBC_ENCRYPT));
+    }
+
+    #ifdef HAVE_AES_DECRYPT
+    int wc_AesCbcDecrypt(Aes* aes, byte* po, const byte* pi, word32 sz)
+    {
+        return (wc_AesCbcCrypt(aes, po, pi, sz, SEC_DESC_AES_CBC_DECRYPT));
+    }
+    #endif /* HAVE_AES_DECRYPT */
+
+#elif defined(FREESCALE_LTC)
+    int wc_AesCbcEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
+    {
+        uint32_t keySize;
+        status_t status;
+        byte *iv, *enc_key;
+        word32 blocks = (sz / AES_BLOCK_SIZE);
+
+        iv      = (byte*)aes->reg;
+        enc_key = (byte*)aes->key;
+
+        status = wc_AesGetKeySize(aes, &keySize);
+        if (status != 0) {
+            return status;
+        }
+
+        status = LTC_AES_EncryptCbc(LTC_BASE, in, out, blocks * AES_BLOCK_SIZE,
+            iv, enc_key, keySize);
+
+        /* store iv for next call */
+        if (status == kStatus_Success) {
+            XMEMCPY(iv, out + sz - AES_BLOCK_SIZE, AES_BLOCK_SIZE);
+        }
+
+        return (status == kStatus_Success) ? 0 : -1;
+    }
+
+    #ifdef HAVE_AES_DECRYPT
+    int wc_AesCbcDecrypt(Aes* aes, byte* out, const byte* in, word32 sz)
+    {
+        uint32_t keySize;
+        status_t status;
+        byte* iv, *dec_key;
+        word32 blocks = (sz / AES_BLOCK_SIZE);
+        byte temp_block[AES_BLOCK_SIZE];
+
+        iv      = (byte*)aes->reg;
+        dec_key = (byte*)aes->key;
+
+        status = wc_AesGetKeySize(aes, &keySize);
+        if (status != 0) {
+            return status;
+        }
+
+        /* get IV for next call */
+        XMEMCPY(temp_block, in + sz - AES_BLOCK_SIZE, AES_BLOCK_SIZE);
+
+        status = LTC_AES_DecryptCbc(LTC_BASE, in, out, blocks * AES_BLOCK_SIZE,
+            iv, dec_key, keySize, kLTC_EncryptKey);
+
+        /* store IV for next call */
+        if (status == kStatus_Success) {
+            XMEMCPY(iv, temp_block, AES_BLOCK_SIZE);
+        }
+
+        return (status == kStatus_Success) ? 0 : -1;
+    }
+    #endif /* HAVE_AES_DECRYPT */
+
+#elif defined(FREESCALE_MMCAU)
+    int wc_AesCbcEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
+    {
+        int i;
+        int offset = 0;
+        word32 blocks = (sz / AES_BLOCK_SIZE);
+        byte *iv;
+        byte temp_block[AES_BLOCK_SIZE];
+
+        iv      = (byte*)aes->reg;
+
+        while (blocks--) {
+            XMEMCPY(temp_block, in + offset, AES_BLOCK_SIZE);
+
+            /* XOR block with IV for CBC */
+            for (i = 0; i < AES_BLOCK_SIZE; i++)
+                temp_block[i] ^= iv[i];
+
+            wc_AesEncrypt(aes, temp_block, out + offset);
+
+            offset += AES_BLOCK_SIZE;
+
+            /* store IV for next block */
+            XMEMCPY(iv, out + offset - AES_BLOCK_SIZE, AES_BLOCK_SIZE);
+        }
+
+        return 0;
+    }
+    #ifdef HAVE_AES_DECRYPT
+    int wc_AesCbcDecrypt(Aes* aes, byte* out, const byte* in, word32 sz)
+    {
+        int i;
+        int offset = 0;
+        word32 blocks = (sz / AES_BLOCK_SIZE);
+        byte* iv;
+        byte temp_block[AES_BLOCK_SIZE];
+
+        iv      = (byte*)aes->reg;
+
+        while (blocks--) {
+            XMEMCPY(temp_block, in + offset, AES_BLOCK_SIZE);
+
+            wc_AesDecrypt(aes, in + offset, out + offset);
+
+            /* XOR block with IV for CBC */
+            for (i = 0; i < AES_BLOCK_SIZE; i++)
+                (out + offset)[i] ^= iv[i];
+
+            /* store IV for next block */
+            XMEMCPY(iv, temp_block, AES_BLOCK_SIZE);
+
+            offset += AES_BLOCK_SIZE;
+        }
+
+        return 0;
+    }
+    #endif /* HAVE_AES_DECRYPT */
+
+#elif defined(WOLFSSL_PIC32MZ_CRYPT)
+
+    int wc_AesCbcEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
+    {
+        int ret;
+
+        /* hardware fails on input that is not a multiple of AES block size */
+        if (sz % AES_BLOCK_SIZE != 0) {
+            return BAD_FUNC_ARG;
+        }
+
+        ret = wc_Pic32AesCrypt(
+            aes->key, aes->keylen, aes->reg, AES_BLOCK_SIZE,
+            out, in, sz, PIC32_ENCRYPTION,
+            PIC32_ALGO_AES, PIC32_CRYPTOALGO_RCBC);
+
+        /* store iv for next call */
+        if (ret == 0) {
+            XMEMCPY(aes->reg, out + sz - AES_BLOCK_SIZE, AES_BLOCK_SIZE);
+        }
+
+        return ret;
+    }
+    #ifdef HAVE_AES_DECRYPT
+    int wc_AesCbcDecrypt(Aes* aes, byte* out, const byte* in, word32 sz)
+    {
+        int ret;
+        byte scratch[AES_BLOCK_SIZE];
+
+        /* hardware fails on input that is not a multiple of AES block size */
+        if (sz % AES_BLOCK_SIZE != 0) {
+            return BAD_FUNC_ARG;
+        }
+        XMEMCPY(scratch, in + sz - AES_BLOCK_SIZE, AES_BLOCK_SIZE);
+
+        ret = wc_Pic32AesCrypt(
+            aes->key, aes->keylen, aes->reg, AES_BLOCK_SIZE,
+            out, in, sz, PIC32_DECRYPTION,
+            PIC32_ALGO_AES, PIC32_CRYPTOALGO_RCBC);
+
+        /* store iv for next call */
+        if (ret == 0) {
+            XMEMCPY((byte*)aes->reg, scratch, AES_BLOCK_SIZE);
+        }
+
+        return ret;
+    }
+    #endif /* HAVE_AES_DECRYPT */
+#elif defined(WOLFSSL_ESP32WROOM32_CRYPT) && \
+    !defined(NO_WOLFSSL_ESP32WROOM32_CRYPT_AES)
+
+    int wc_AesCbcEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
+    {
+        return wc_esp32AesCbcEncrypt(aes, out, in, sz);
+    }
+    int wc_AesCbcDecrypt(Aes* aes, byte* out, const byte* in, word32 sz)
+    {
+        return wc_esp32AesCbcDecrypt(aes, out, in, sz);
+    }
+#elif defined(WOLFSSL_CRYPTOCELL) && defined(WOLFSSL_CRYPTOCELL_AES)
+    int wc_AesCbcEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
+    {
+        return SaSi_AesBlock(&aes->ctx.user_ctx, (uint8_t* )in, sz, out);
+    }
+    int wc_AesCbcDecrypt(Aes* aes, byte* out, const byte* in, word32 sz)
+    {
+        return SaSi_AesBlock(&aes->ctx.user_ctx, (uint8_t* )in, sz, out);
+    }
+#elif defined(WOLFSSL_IMX6_CAAM) && !defined(NO_IMX6_CAAM_AES)
+      /* implemented in wolfcrypt/src/port/caam/caam_aes.c */
+
+#elif defined(WOLFSSL_AFALG)
+    /* implemented in wolfcrypt/src/port/af_alg/afalg_aes.c */
+
+#elif defined(WOLFSSL_DEVCRYPTO_CBC)
+    /* implemented in wolfcrypt/src/port/devcrypt/devcrypto_aes.c */
+
+#else
+
+    /* Software AES - CBC Encrypt */
+    int wc_AesCbcEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
+    {
+        word32 blocks = (sz / AES_BLOCK_SIZE);
+
+        if (aes == NULL || out == NULL || in == NULL) {
+            return BAD_FUNC_ARG;
+        }
+
+    #ifdef WOLF_CRYPTO_CB
+        if (aes->devId != INVALID_DEVID) {
+            int ret = wc_CryptoCb_AesCbcEncrypt(aes, out, in, sz);
+            if (ret != CRYPTOCB_UNAVAILABLE)
+                return ret;
+            /* fall-through when unavailable */
+        }
+    #endif
+    #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_AES)
+        /* if async and byte count above threshold */
+        if (aes->asyncDev.marker == WOLFSSL_ASYNC_MARKER_AES &&
+                                                sz >= WC_ASYNC_THRESH_AES_CBC) {
+        #if defined(HAVE_CAVIUM)
+            return NitroxAesCbcEncrypt(aes, out, in, sz);
+        #elif defined(HAVE_INTEL_QA)
+            return IntelQaSymAesCbcEncrypt(&aes->asyncDev, out, in, sz,
+                (const byte*)aes->devKey, aes->keylen,
+                (byte*)aes->reg, AES_BLOCK_SIZE);
+        #else /* WOLFSSL_ASYNC_CRYPT_TEST */
+            if (wc_AsyncTestInit(&aes->asyncDev, ASYNC_TEST_AES_CBC_ENCRYPT)) {
+                WC_ASYNC_TEST* testDev = &aes->asyncDev.test;
+                testDev->aes.aes = aes;
+                testDev->aes.out = out;
+                testDev->aes.in = in;
+                testDev->aes.sz = sz;
+                return WC_PENDING_E;
+            }
+        #endif
+        }
+    #endif /* WOLFSSL_ASYNC_CRYPT */
+
+    #ifdef WOLFSSL_AESNI
+        if (haveAESNI) {
+            #ifdef DEBUG_AESNI
+                printf("about to aes cbc encrypt\n");
+                printf("in  = %p\n", in);
+                printf("out = %p\n", out);
+                printf("aes->key = %p\n", aes->key);
+                printf("aes->reg = %p\n", aes->reg);
+                printf("aes->rounds = %d\n", aes->rounds);
+                printf("sz = %d\n", sz);
+            #endif
+
+            /* check alignment, decrypt doesn't need alignment */
+            if ((wolfssl_word)in % AESNI_ALIGN) {
+            #ifndef NO_WOLFSSL_ALLOC_ALIGN
+                byte* tmp = (byte*)XMALLOC(sz + AES_BLOCK_SIZE + AESNI_ALIGN,
+                                            aes->heap, DYNAMIC_TYPE_TMP_BUFFER);
+                byte* tmp_align;
+                if (tmp == NULL) return MEMORY_E;
+
+                tmp_align = tmp + (AESNI_ALIGN - ((size_t)tmp % AESNI_ALIGN));
+                XMEMCPY(tmp_align, in, sz);
+                AES_CBC_encrypt(tmp_align, tmp_align, (byte*)aes->reg, sz,
+                                                  (byte*)aes->key, aes->rounds);
+                /* store iv for next call */
+                XMEMCPY(aes->reg, tmp_align + sz - AES_BLOCK_SIZE, AES_BLOCK_SIZE);
+
+                XMEMCPY(out, tmp_align, sz);
+                XFREE(tmp, aes->heap, DYNAMIC_TYPE_TMP_BUFFER);
+                return 0;
+            #else
+                WOLFSSL_MSG("AES-CBC encrypt with bad alignment");
+                return BAD_ALIGN_E;
+            #endif
+            }
+
+            AES_CBC_encrypt(in, out, (byte*)aes->reg, sz, (byte*)aes->key,
+                            aes->rounds);
+            /* store iv for next call */
+            XMEMCPY(aes->reg, out + sz - AES_BLOCK_SIZE, AES_BLOCK_SIZE);
+
+            return 0;
+        }
+    #endif
+
+        while (blocks--) {
+            xorbuf((byte*)aes->reg, in, AES_BLOCK_SIZE);
+            wc_AesEncrypt(aes, (byte*)aes->reg, (byte*)aes->reg);
+            XMEMCPY(out, aes->reg, AES_BLOCK_SIZE);
+
+            out += AES_BLOCK_SIZE;
+            in  += AES_BLOCK_SIZE;
+        }
+
+        return 0;
+    }
+
+    #ifdef HAVE_AES_DECRYPT
+    /* Software AES - CBC Decrypt */
+    int wc_AesCbcDecrypt(Aes* aes, byte* out, const byte* in, word32 sz)
+    {
+        word32 blocks;
+
+        if (aes == NULL || out == NULL || in == NULL
+                                       || sz % AES_BLOCK_SIZE != 0) {
+            return BAD_FUNC_ARG;
+        }
+
+    #ifdef WOLF_CRYPTO_CB
+        if (aes->devId != INVALID_DEVID) {
+            int ret = wc_CryptoCb_AesCbcDecrypt(aes, out, in, sz);
+            if (ret != CRYPTOCB_UNAVAILABLE)
+                return ret;
+            /* fall-through when unavailable */
+        }
+    #endif
+    #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_AES)
+        /* if async and byte count above threshold */
+        if (aes->asyncDev.marker == WOLFSSL_ASYNC_MARKER_AES &&
+                                                sz >= WC_ASYNC_THRESH_AES_CBC) {
+        #if defined(HAVE_CAVIUM)
+            return NitroxAesCbcDecrypt(aes, out, in, sz);
+        #elif defined(HAVE_INTEL_QA)
+            return IntelQaSymAesCbcDecrypt(&aes->asyncDev, out, in, sz,
+                (const byte*)aes->devKey, aes->keylen,
+                (byte*)aes->reg, AES_BLOCK_SIZE);
+        #else /* WOLFSSL_ASYNC_CRYPT_TEST */
+            if (wc_AsyncTestInit(&aes->asyncDev, ASYNC_TEST_AES_CBC_DECRYPT)) {
+                WC_ASYNC_TEST* testDev = &aes->asyncDev.test;
+                testDev->aes.aes = aes;
+                testDev->aes.out = out;
+                testDev->aes.in = in;
+                testDev->aes.sz = sz;
+                return WC_PENDING_E;
+            }
+        #endif
+        }
+    #endif
+
+    #ifdef WOLFSSL_AESNI
+        if (haveAESNI) {
+            #ifdef DEBUG_AESNI
+                printf("about to aes cbc decrypt\n");
+                printf("in  = %p\n", in);
+                printf("out = %p\n", out);
+                printf("aes->key = %p\n", aes->key);
+                printf("aes->reg = %p\n", aes->reg);
+                printf("aes->rounds = %d\n", aes->rounds);
+                printf("sz = %d\n", sz);
+            #endif
+
+            /* if input and output same will overwrite input iv */
+            XMEMCPY(aes->tmp, in + sz - AES_BLOCK_SIZE, AES_BLOCK_SIZE);
+            #if defined(WOLFSSL_AESNI_BY4)
+            AES_CBC_decrypt_by4(in, out, (byte*)aes->reg, sz, (byte*)aes->key,
+                            aes->rounds);
+            #elif defined(WOLFSSL_AESNI_BY6)
+            AES_CBC_decrypt_by6(in, out, (byte*)aes->reg, sz, (byte*)aes->key,
+                            aes->rounds);
+            #else /* WOLFSSL_AESNI_BYx */
+            AES_CBC_decrypt_by8(in, out, (byte*)aes->reg, sz, (byte*)aes->key,
+                            aes->rounds);
+            #endif /* WOLFSSL_AESNI_BYx */
+            /* store iv for next call */
+            XMEMCPY(aes->reg, aes->tmp, AES_BLOCK_SIZE);
+            return 0;
+        }
+    #endif
+
+        blocks = sz / AES_BLOCK_SIZE;
+        while (blocks--) {
+            XMEMCPY(aes->tmp, in, AES_BLOCK_SIZE);
+            wc_AesDecrypt(aes, (byte*)aes->tmp, out);
+            xorbuf(out, (byte*)aes->reg, AES_BLOCK_SIZE);
+            /* store iv for next call */
+            XMEMCPY(aes->reg, aes->tmp, AES_BLOCK_SIZE);
+
+            out += AES_BLOCK_SIZE;
+            in  += AES_BLOCK_SIZE;
+        }
+
+        return 0;
+    }
+    #endif
+
+#endif /* AES-CBC block */
+#endif /* HAVE_AES_CBC */
+
+/* AES-CTR */
+#if defined(WOLFSSL_AES_COUNTER)
+
+    #ifdef STM32_CRYPTO
+        #define NEED_AES_CTR_SOFT
+        #define XTRANSFORM_AESCTRBLOCK wc_AesCtrEncryptBlock
+
+        int wc_AesCtrEncryptBlock(Aes* aes, byte* out, const byte* in)
+        {
+            int ret = 0;
+        #ifdef WOLFSSL_STM32_CUBEMX
+            CRYP_HandleTypeDef hcryp;
+            #ifdef STM32_HAL_V2
+            word32 iv[AES_BLOCK_SIZE/sizeof(word32)];
+            #endif
+        #else
+            word32 *iv;
+            CRYP_InitTypeDef cryptInit;
+            CRYP_KeyInitTypeDef keyInit;
+            CRYP_IVInitTypeDef ivInit;
+        #endif
+
+            ret = wolfSSL_CryptHwMutexLock();
+            if (ret != 0) {
+                return ret;
+            }
+
+        #ifdef WOLFSSL_STM32_CUBEMX
+            ret = wc_Stm32_Aes_Init(aes, &hcryp);
+            if (ret != 0) {
+                wolfSSL_CryptHwMutexUnLock();
+                return ret;
+            }
+
+        #ifdef STM32_CRYPTO_AES_ONLY
+            hcryp.Init.OperatingMode = CRYP_ALGOMODE_ENCRYPT;
+            hcryp.Init.ChainingMode  = CRYP_CHAINMODE_AES_CTR;
+            hcryp.Init.KeyWriteFlag  = CRYP_KEY_WRITE_ENABLE;
+            hcryp.Init.pInitVect = (STM_CRYPT_TYPE*)aes->reg;
+        #elif defined(STM32_HAL_V2)
+            hcryp.Init.Algorithm  = CRYP_AES_CTR;
+            ByteReverseWords(iv, aes->reg, AES_BLOCK_SIZE);
+            hcryp.Init.pInitVect = (STM_CRYPT_TYPE*)iv;
+        #else
+            hcryp.Init.pInitVect = (STM_CRYPT_TYPE*)aes->reg;
+        #endif
+            HAL_CRYP_Init(&hcryp);
+
+        #ifdef STM32_CRYPTO_AES_ONLY
+            ret = HAL_CRYPEx_AES(&hcryp, (byte*)in, AES_BLOCK_SIZE,
+                out, STM32_HAL_TIMEOUT);
+        #elif defined(STM32_HAL_V2)
+            ret = HAL_CRYP_Encrypt(&hcryp, (uint32_t*)in, AES_BLOCK_SIZE,
+                (uint32_t*)out, STM32_HAL_TIMEOUT);
+        #else
+            ret = HAL_CRYP_AESCTR_Encrypt(&hcryp, (byte*)in, AES_BLOCK_SIZE,
+                out, STM32_HAL_TIMEOUT);
+        #endif
+            if (ret != HAL_OK) {
+                ret = WC_TIMEOUT_E;
+            }
+            HAL_CRYP_DeInit(&hcryp);
+
+        #else /* STD_PERI_LIB */
+            ret = wc_Stm32_Aes_Init(aes, &cryptInit, &keyInit);
+            if (ret != 0) {
+                wolfSSL_CryptHwMutexUnLock();
+                return ret;
+            }
+
+            /* reset registers to their default values */
+            CRYP_DeInit();
+
+            /* set key */
+            CRYP_KeyInit(&keyInit);
+
+            /* set iv */
+            iv = aes->reg;
+            CRYP_IVStructInit(&ivInit);
+            ivInit.CRYP_IV0Left  = ByteReverseWord32(iv[0]);
+            ivInit.CRYP_IV0Right = ByteReverseWord32(iv[1]);
+            ivInit.CRYP_IV1Left  = ByteReverseWord32(iv[2]);
+            ivInit.CRYP_IV1Right = ByteReverseWord32(iv[3]);
+            CRYP_IVInit(&ivInit);
+
+            /* set direction and mode */
+            cryptInit.CRYP_AlgoDir  = CRYP_AlgoDir_Encrypt;
+            cryptInit.CRYP_AlgoMode = CRYP_AlgoMode_AES_CTR;
+            CRYP_Init(&cryptInit);
+
+            /* enable crypto processor */
+            CRYP_Cmd(ENABLE);
+
+            /* flush IN/OUT FIFOs */
+            CRYP_FIFOFlush();
+
+            CRYP_DataIn(*(uint32_t*)&in[0]);
+            CRYP_DataIn(*(uint32_t*)&in[4]);
+            CRYP_DataIn(*(uint32_t*)&in[8]);
+            CRYP_DataIn(*(uint32_t*)&in[12]);
+
+            /* wait until the complete message has been processed */
+            while (CRYP_GetFlagStatus(CRYP_FLAG_BUSY) != RESET) {}
+
+            *(uint32_t*)&out[0]  = CRYP_DataOut();
+            *(uint32_t*)&out[4]  = CRYP_DataOut();
+            *(uint32_t*)&out[8]  = CRYP_DataOut();
+            *(uint32_t*)&out[12] = CRYP_DataOut();
+
+            /* disable crypto processor */
+            CRYP_Cmd(DISABLE);
+
+        #endif /* WOLFSSL_STM32_CUBEMX */
+
+            wolfSSL_CryptHwMutexUnLock();
+            return ret;
+        }
+
+
+    #elif defined(WOLFSSL_PIC32MZ_CRYPT)
+
+        #define NEED_AES_CTR_SOFT
+        #define XTRANSFORM_AESCTRBLOCK wc_AesCtrEncryptBlock
+
+        int wc_AesCtrEncryptBlock(Aes* aes, byte* out, const byte* in)
+        {
+            word32 tmpIv[AES_BLOCK_SIZE / sizeof(word32)];
+            XMEMCPY(tmpIv, aes->reg, AES_BLOCK_SIZE);
+            return wc_Pic32AesCrypt(
+                aes->key, aes->keylen, tmpIv, AES_BLOCK_SIZE,
+                out, in, AES_BLOCK_SIZE,
+                PIC32_ENCRYPTION, PIC32_ALGO_AES, PIC32_CRYPTOALGO_RCTR);
+        }
+
+    #elif defined(HAVE_COLDFIRE_SEC)
+        #error "Coldfire SEC doesn't currently support AES-CTR mode"
+
+    #elif defined(FREESCALE_LTC)
+        int wc_AesCtrEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
+        {
+            uint32_t keySize;
+            byte *iv, *enc_key;
+            byte* tmp;
+
+            if (aes == NULL || out == NULL || in == NULL) {
+                return BAD_FUNC_ARG;
+            }
+
+            /* consume any unused bytes left in aes->tmp */
+            tmp = (byte*)aes->tmp + AES_BLOCK_SIZE - aes->left;
+            while (aes->left && sz) {
+                *(out++) = *(in++) ^ *(tmp++);
+                aes->left--;
+                sz--;
+            }
+
+            if (sz) {
+                iv      = (byte*)aes->reg;
+                enc_key = (byte*)aes->key;
+
+                wc_AesGetKeySize(aes, &keySize);
+
+                LTC_AES_CryptCtr(LTC_BASE, in, out, sz,
+                    iv, enc_key, keySize, (byte*)aes->tmp,
+                    (uint32_t*)&aes->left);
+            }
+
+            return 0;
+        }
+
+    #elif defined(WOLFSSL_IMX6_CAAM) && !defined(NO_IMX6_CAAM_AES)
+        /* implemented in wolfcrypt/src/port/caam/caam_aes.c */
+
+    #elif defined(WOLFSSL_AFALG)
+        /* implemented in wolfcrypt/src/port/af_alg/afalg_aes.c */
+
+    #elif defined(WOLFSSL_DEVCRYPTO_AES)
+        /* implemented in wolfcrypt/src/port/devcrypt/devcrypto_aes.c */
+   
+    #elif defined(WOLFSSL_ESP32WROOM32_CRYPT) && \
+        !defined(NO_WOLFSSL_ESP32WROOM32_CRYPT_AES)
+        /* esp32 doesn't support CRT mode by hw.     */
+        /* use aes ecnryption plus sw implementation */
+        #define NEED_AES_CTR_SOFT
+
+    #else
+
+        /* Use software based AES counter */
+        #define NEED_AES_CTR_SOFT
+    #endif
+
+    #ifdef NEED_AES_CTR_SOFT
+        /* Increment AES counter */
+        static WC_INLINE void IncrementAesCounter(byte* inOutCtr)
+        {
+            /* in network byte order so start at end and work back */
+            int i;
+            for (i = AES_BLOCK_SIZE - 1; i >= 0; i--) {
+                if (++inOutCtr[i])  /* we're done unless we overflow */
+                    return;
+            }
+        }
+
+        /* Software AES - CTR Encrypt */
+        int wc_AesCtrEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
+        {
+            byte* tmp;
+            byte scratch[AES_BLOCK_SIZE];
+
+            if (aes == NULL || out == NULL || in == NULL) {
+                return BAD_FUNC_ARG;
+            }
+
+            /* consume any unused bytes left in aes->tmp */
+            tmp = (byte*)aes->tmp + AES_BLOCK_SIZE - aes->left;
+            while (aes->left && sz) {
+               *(out++) = *(in++) ^ *(tmp++);
+               aes->left--;
+               sz--;
+            }
+
+            /* do as many block size ops as possible */
+            while (sz >= AES_BLOCK_SIZE) {
+            #ifdef XTRANSFORM_AESCTRBLOCK
+                XTRANSFORM_AESCTRBLOCK(aes, out, in);
+            #else
+                wc_AesEncrypt(aes, (byte*)aes->reg, scratch);
+                xorbuf(scratch, in, AES_BLOCK_SIZE);
+                XMEMCPY(out, scratch, AES_BLOCK_SIZE);
+            #endif
+                IncrementAesCounter((byte*)aes->reg);
+
+                out += AES_BLOCK_SIZE;
+                in  += AES_BLOCK_SIZE;
+                sz  -= AES_BLOCK_SIZE;
+                aes->left = 0;
+            }
+            ForceZero(scratch, AES_BLOCK_SIZE);
+
+            /* handle non block size remaining and store unused byte count in left */
+            if (sz) {
+                wc_AesEncrypt(aes, (byte*)aes->reg, (byte*)aes->tmp);
+                IncrementAesCounter((byte*)aes->reg);
+
+                aes->left = AES_BLOCK_SIZE;
+                tmp = (byte*)aes->tmp;
+
+                while (sz--) {
+                    *(out++) = *(in++) ^ *(tmp++);
+                    aes->left--;
+                }
+            }
+
+            return 0;
+        }
+
+    #endif /* NEED_AES_CTR_SOFT */
+
+#endif /* WOLFSSL_AES_COUNTER */
+#endif /* !WOLFSSL_ARMASM */
+
+
+/*
+ * The IV for AES GCM and CCM, stored in struct Aes's member reg, is comprised
+ * of two parts in order:
+ *   1. The fixed field which may be 0 or 4 bytes long. In TLS, this is set
+ *      to the implicit IV.
+ *   2. The explicit IV is generated by wolfCrypt. It needs to be managed
+ *      by wolfCrypt to ensure the IV is unique for each call to encrypt.
+ * The IV may be a 96-bit random value, or the 32-bit fixed value and a
+ * 64-bit set of 0 or random data. The final 32-bits of reg is used as a
+ * block counter during the encryption.
+ */
+
+#if (defined(HAVE_AESGCM) && !defined(WC_NO_RNG)) || defined(HAVE_AESCCM)
+static WC_INLINE void IncCtr(byte* ctr, word32 ctrSz)
+{
+    int i;
+    for (i = ctrSz-1; i >= 0; i--) {
+        if (++ctr[i])
+            break;
+    }
+}
+#endif /* HAVE_AESGCM || HAVE_AESCCM */
+
+
+#ifdef HAVE_AESGCM
+
+#if defined(HAVE_COLDFIRE_SEC)
+    #error "Coldfire SEC doesn't currently support AES-GCM mode"
+
+#elif defined(WOLFSSL_NRF51_AES)
+    #error "nRF51 doesn't currently support AES-GCM mode"
+
+#endif
+
+#ifdef WOLFSSL_ARMASM
+    /* implementation is located in wolfcrypt/src/port/arm/armv8-aes.c */
+
+#elif defined(WOLFSSL_AFALG)
+    /* implemented in wolfcrypt/src/port/afalg/afalg_aes.c */
+
+#elif defined(WOLFSSL_DEVCRYPTO_AES)
+    /* implemented in wolfcrypt/src/port/devcrypt/devcrypto_aes.c */
+
+#else /* software + AESNI implementation */
+
+#if !defined(FREESCALE_LTC_AES_GCM)
+static WC_INLINE void IncrementGcmCounter(byte* inOutCtr)
+{
+    int i;
+
+    /* in network byte order so start at end and work back */
+    for (i = AES_BLOCK_SIZE - 1; i >= AES_BLOCK_SIZE - CTR_SZ; i--) {
+        if (++inOutCtr[i])  /* we're done unless we overflow */
+            return;
+    }
+}
+#ifdef STM32_CRYPTO_AES_GCM
+static WC_INLINE void DecrementGcmCounter(byte* inOutCtr)
+{
+    int i;
+
+    /* in network byte order so start at end and work back */
+    for (i = AES_BLOCK_SIZE - 1; i >= AES_BLOCK_SIZE - CTR_SZ; i--) {
+        if (--inOutCtr[i] != 0xFF)  /* we're done unless we underflow */
+            return;
+    }
+}
+#endif /* STM32_CRYPTO_AES_GCM */
+#endif /* !FREESCALE_LTC_AES_GCM */
+
+#if defined(GCM_SMALL) || defined(GCM_TABLE)
+
+static WC_INLINE void FlattenSzInBits(byte* buf, word32 sz)
+{
+    /* Multiply the sz by 8 */
+    word32 szHi = (sz >> (8*sizeof(sz) - 3));
+    sz <<= 3;
+
+    /* copy over the words of the sz into the destination buffer */
+    buf[0] = (szHi >> 24) & 0xff;
+    buf[1] = (szHi >> 16) & 0xff;
+    buf[2] = (szHi >>  8) & 0xff;
+    buf[3] = szHi & 0xff;
+    buf[4] = (sz >> 24) & 0xff;
+    buf[5] = (sz >> 16) & 0xff;
+    buf[6] = (sz >>  8) & 0xff;
+    buf[7] = sz & 0xff;
+}
+
+
+static WC_INLINE void RIGHTSHIFTX(byte* x)
+{
+    int i;
+    int carryOut = 0;
+    int carryIn = 0;
+    int borrow = x[15] & 0x01;
+
+    for (i = 0; i < AES_BLOCK_SIZE; i++) {
+        carryOut = x[i] & 0x01;
+        x[i] = (x[i] >> 1) | (carryIn ? 0x80 : 0);
+        carryIn = carryOut;
+    }
+    if (borrow) x[0] ^= 0xE1;
+}
+
+#endif /* defined(GCM_SMALL) || defined(GCM_TABLE) */
+
+
+#ifdef GCM_TABLE
+
+static void GenerateM0(Aes* aes)
+{
+    int i, j;
+    byte (*m)[AES_BLOCK_SIZE] = aes->M0;
+
+    XMEMCPY(m[128], aes->H, AES_BLOCK_SIZE);
+
+    for (i = 64; i > 0; i /= 2) {
+        XMEMCPY(m[i], m[i*2], AES_BLOCK_SIZE);
+        RIGHTSHIFTX(m[i]);
+    }
+
+    for (i = 2; i < 256; i *= 2) {
+        for (j = 1; j < i; j++) {
+            XMEMCPY(m[i+j], m[i], AES_BLOCK_SIZE);
+            xorbuf(m[i+j], m[j], AES_BLOCK_SIZE);
+        }
+    }
+
+    XMEMSET(m[0], 0, AES_BLOCK_SIZE);
+}
+
+#endif /* GCM_TABLE */
+
+/* Software AES - GCM SetKey */
+int wc_AesGcmSetKey(Aes* aes, const byte* key, word32 len)
+{
+    int  ret;
+    byte iv[AES_BLOCK_SIZE];
+
+    #ifdef WOLFSSL_IMX6_CAAM_BLOB
+        byte   local[32];
+        word32 localSz = 32;
+
+        if (len == (16 + WC_CAAM_BLOB_SZ) ||
+          len == (24 + WC_CAAM_BLOB_SZ) ||
+          len == (32 + WC_CAAM_BLOB_SZ)) {
+            if (wc_caamOpenBlob((byte*)key, len, local, &localSz) != 0) {
+                 return BAD_FUNC_ARG;
+            }
+
+            /* set local values */
+            key = local;
+            len = localSz;
+        }
+    #endif
+
+    if (!((len == 16) || (len == 24) || (len == 32)))
+        return BAD_FUNC_ARG;
+
+#ifdef OPENSSL_EXTRA
+    if (aes != NULL) {
+        XMEMSET(aes->aadH, 0, sizeof(aes->aadH));
+        aes->aadLen = 0;
+    }
+#endif
+    XMEMSET(iv, 0, AES_BLOCK_SIZE);
+    ret = wc_AesSetKey(aes, key, len, iv, AES_ENCRYPTION);
+
+    #ifdef WOLFSSL_AESNI
+        /* AES-NI code generates its own H value. */
+        if (haveAESNI)
+            return ret;
+    #endif /* WOLFSSL_AESNI */
+
+#if !defined(FREESCALE_LTC_AES_GCM)
+    if (ret == 0) {
+        wc_AesEncrypt(aes, iv, aes->H);
+    #ifdef GCM_TABLE
+        GenerateM0(aes);
+    #endif /* GCM_TABLE */
+    }
+#endif /* FREESCALE_LTC_AES_GCM */
+
+#if defined(WOLFSSL_XILINX_CRYPT)
+    wc_AesGcmSetKey_ex(aes, key, len, XSECURE_CSU_AES_KEY_SRC_KUP);
+#elif defined(WOLFSSL_AFALG_XILINX_AES)
+    wc_AesGcmSetKey_ex(aes, key, len, 0);
+#endif
+
+#ifdef WOLF_CRYPTO_CB
+    if (aes->devId != INVALID_DEVID) {
+        XMEMCPY(aes->devKey, key, len);
+    }
+#endif
+
+#ifdef WOLFSSL_IMX6_CAAM_BLOB
+    ForceZero(local, sizeof(local));
+#endif
+
+    return ret;
+}
+
+
+#ifdef WOLFSSL_AESNI
+
+#if defined(USE_INTEL_SPEEDUP)
+    #define HAVE_INTEL_AVX1
+    #define HAVE_INTEL_AVX2
+#endif /* USE_INTEL_SPEEDUP */
+
+#ifndef _MSC_VER
+
+void AES_GCM_encrypt(const unsigned char *in, unsigned char *out,
+                     const unsigned char* addt, const unsigned char* ivec,
+                     unsigned char *tag, unsigned int nbytes,
+                     unsigned int abytes, unsigned int ibytes,
+                     unsigned int tbytes, const unsigned char* key, int nr)
+                     XASM_LINK("AES_GCM_encrypt");
+#ifdef HAVE_INTEL_AVX1
+void AES_GCM_encrypt_avx1(const unsigned char *in, unsigned char *out,
+                          const unsigned char* addt, const unsigned char* ivec,
+                          unsigned char *tag, unsigned int nbytes,
+                          unsigned int abytes, unsigned int ibytes,
+                          unsigned int tbytes, const unsigned char* key,
+                          int nr)
+                          XASM_LINK("AES_GCM_encrypt_avx1");
+#ifdef HAVE_INTEL_AVX2
+void AES_GCM_encrypt_avx2(const unsigned char *in, unsigned char *out,
+                          const unsigned char* addt, const unsigned char* ivec,
+                          unsigned char *tag, unsigned int nbytes,
+                          unsigned int abytes, unsigned int ibytes,
+                          unsigned int tbytes, const unsigned char* key,
+                          int nr)
+                          XASM_LINK("AES_GCM_encrypt_avx2");
+#endif /* HAVE_INTEL_AVX2 */
+#endif /* HAVE_INTEL_AVX1 */
+
+#ifdef HAVE_AES_DECRYPT
+void AES_GCM_decrypt(const unsigned char *in, unsigned char *out,
+                     const unsigned char* addt, const unsigned char* ivec,
+                     const unsigned char *tag, int nbytes, int abytes,
+                     int ibytes, int tbytes, const unsigned char* key, int nr,
+                     int* res)
+                     XASM_LINK("AES_GCM_decrypt");
+#ifdef HAVE_INTEL_AVX1
+void AES_GCM_decrypt_avx1(const unsigned char *in, unsigned char *out,
+                          const unsigned char* addt, const unsigned char* ivec,
+                          const unsigned char *tag, int nbytes, int abytes,
+                          int ibytes, int tbytes, const unsigned char* key,
+                          int nr, int* res)
+                          XASM_LINK("AES_GCM_decrypt_avx1");
+#ifdef HAVE_INTEL_AVX2
+void AES_GCM_decrypt_avx2(const unsigned char *in, unsigned char *out,
+                          const unsigned char* addt, const unsigned char* ivec,
+                          const unsigned char *tag, int nbytes, int abytes,
+                          int ibytes, int tbytes, const unsigned char* key,
+                          int nr, int* res)
+                          XASM_LINK("AES_GCM_decrypt_avx2");
+#endif /* HAVE_INTEL_AVX2 */
+#endif /* HAVE_INTEL_AVX1 */
+#endif /* HAVE_AES_DECRYPT */
+
+#else /* _MSC_VER */
+
+#define S(w,z) ((char)((unsigned long long)(w) >> (8*(7-(z))) & 0xFF))
+#define M128_INIT(x,y) { S((x),7), S((x),6), S((x),5), S((x),4), \
+                         S((x),3), S((x),2), S((x),1), S((x),0), \
+                         S((y),7), S((y),6), S((y),5), S((y),4), \
+                         S((y),3), S((y),2), S((y),1), S((y),0) }
+
+static const __m128i MOD2_128 =
+        M128_INIT(0x1, (long long int)0xc200000000000000UL);
+
+
+/* See Intel® Carry-Less Multiplication Instruction
+ * and its Usage for Computing the GCM Mode White Paper
+ * by Shay Gueron, Intel Mobility Group, Israel Development Center;
+ * and Michael E. Kounavis, Intel Labs, Circuits and Systems Research */
+
+
+/* Figure 9. AES-GCM – Encrypt With Single Block Ghash at a Time */
+
+static const __m128i ONE   = M128_INIT(0x0, 0x1);
+#ifndef AES_GCM_AESNI_NO_UNROLL
+static const __m128i TWO   = M128_INIT(0x0, 0x2);
+static const __m128i THREE = M128_INIT(0x0, 0x3);
+static const __m128i FOUR  = M128_INIT(0x0, 0x4);
+static const __m128i FIVE  = M128_INIT(0x0, 0x5);
+static const __m128i SIX   = M128_INIT(0x0, 0x6);
+static const __m128i SEVEN = M128_INIT(0x0, 0x7);
+static const __m128i EIGHT = M128_INIT(0x0, 0x8);
+#endif
+static const __m128i BSWAP_EPI64 =
+        M128_INIT(0x0001020304050607, 0x08090a0b0c0d0e0f);
+static const __m128i BSWAP_MASK =
+        M128_INIT(0x08090a0b0c0d0e0f, 0x0001020304050607);
+
+
+/* The following are for MSC based builds which do not allow
+ * inline assembly. Intrinsic functions are used instead. */
+
+#define aes_gcm_calc_iv_12(KEY, ivec, nr, H, Y, T)         \
+do                                                         \
+{                                                          \
+    word32 iv12[4];                                        \
+    iv12[0] = *(word32*)&ivec[0];                          \
+    iv12[1] = *(word32*)&ivec[4];                          \
+    iv12[2] = *(word32*)&ivec[8];                          \
+    iv12[3] = 0x01000000;                                  \
+    Y = _mm_loadu_si128((__m128i*)iv12);                   \
+                                                           \
+    /* (Compute E[ZERO, KS] and E[Y0, KS] together */      \
+    tmp1 = _mm_load_si128(&KEY[0]);                        \
+    tmp2 = _mm_xor_si128(Y, KEY[0]);                       \
+    tmp1 = _mm_aesenc_si128(tmp1, KEY[1]);                 \
+    tmp2 = _mm_aesenc_si128(tmp2, KEY[1]);                 \
+    tmp1 = _mm_aesenc_si128(tmp1, KEY[2]);                 \
+    tmp2 = _mm_aesenc_si128(tmp2, KEY[2]);                 \
+    tmp1 = _mm_aesenc_si128(tmp1, KEY[3]);                 \
+    tmp2 = _mm_aesenc_si128(tmp2, KEY[3]);                 \
+    tmp1 = _mm_aesenc_si128(tmp1, KEY[4]);                 \
+    tmp2 = _mm_aesenc_si128(tmp2, KEY[4]);                 \
+    tmp1 = _mm_aesenc_si128(tmp1, KEY[5]);                 \
+    tmp2 = _mm_aesenc_si128(tmp2, KEY[5]);                 \
+    tmp1 = _mm_aesenc_si128(tmp1, KEY[6]);                 \
+    tmp2 = _mm_aesenc_si128(tmp2, KEY[6]);                 \
+    tmp1 = _mm_aesenc_si128(tmp1, KEY[7]);                 \
+    tmp2 = _mm_aesenc_si128(tmp2, KEY[7]);                 \
+    tmp1 = _mm_aesenc_si128(tmp1, KEY[8]);                 \
+    tmp2 = _mm_aesenc_si128(tmp2, KEY[8]);                 \
+    tmp1 = _mm_aesenc_si128(tmp1, KEY[9]);                 \
+    tmp2 = _mm_aesenc_si128(tmp2, KEY[9]);                 \
+    lastKey = KEY[10];                                     \
+    if (nr > 10) {                                         \
+        tmp1 = _mm_aesenc_si128(tmp1, lastKey);            \
+        tmp2 = _mm_aesenc_si128(tmp2, lastKey);            \
+        tmp1 = _mm_aesenc_si128(tmp1, KEY[11]);            \
+        tmp2 = _mm_aesenc_si128(tmp2, KEY[11]);            \
+        lastKey = KEY[12];                                 \
+        if (nr > 12) {                                     \
+            tmp1 = _mm_aesenc_si128(tmp1, lastKey);        \
+            tmp2 = _mm_aesenc_si128(tmp2, lastKey);        \
+            tmp1 = _mm_aesenc_si128(tmp1, KEY[13]);        \
+            tmp2 = _mm_aesenc_si128(tmp2, KEY[13]);        \
+            lastKey = KEY[14];                             \
+        }                                                  \
+    }                                                      \
+    H = _mm_aesenclast_si128(tmp1, lastKey);               \
+    T = _mm_aesenclast_si128(tmp2, lastKey);               \
+    H = _mm_shuffle_epi8(H, BSWAP_MASK);                   \
+}                                                          \
+while (0)
+
+#define aes_gcm_calc_iv(KEY, ivec, ibytes, nr, H, Y, T)         \
+do                                                              \
+{                                                               \
+    if (ibytes % 16) {                                          \
+        i = ibytes / 16;                                        \
+        for (j=0; j < (int)(ibytes%16); j++)                    \
+            ((unsigned char*)&last_block)[j] = ivec[i*16+j];    \
+    }                                                           \
+    tmp1 = _mm_load_si128(&KEY[0]);                             \
+    tmp1 = _mm_aesenc_si128(tmp1, KEY[1]);                      \
+    tmp1 = _mm_aesenc_si128(tmp1, KEY[2]);                      \
+    tmp1 = _mm_aesenc_si128(tmp1, KEY[3]);                      \
+    tmp1 = _mm_aesenc_si128(tmp1, KEY[4]);                      \
+    tmp1 = _mm_aesenc_si128(tmp1, KEY[5]);                      \
+    tmp1 = _mm_aesenc_si128(tmp1, KEY[6]);                      \
+    tmp1 = _mm_aesenc_si128(tmp1, KEY[7]);                      \
+    tmp1 = _mm_aesenc_si128(tmp1, KEY[8]);                      \
+    tmp1 = _mm_aesenc_si128(tmp1, KEY[9]);                      \
+    lastKey = KEY[10];                                          \
+    if (nr > 10) {                                              \
+        tmp1 = _mm_aesenc_si128(tmp1, lastKey);                 \
+        tmp1 = _mm_aesenc_si128(tmp1, KEY[11]);                 \
+        lastKey = KEY[12];                                      \
+        if (nr > 12) {                                          \
+            tmp1 = _mm_aesenc_si128(tmp1, lastKey);             \
+            tmp1 = _mm_aesenc_si128(tmp1, KEY[13]);             \
+            lastKey = KEY[14];                                  \
+        }                                                       \
+    }                                                           \
+    H = _mm_aesenclast_si128(tmp1, lastKey);                    \
+    H = _mm_shuffle_epi8(H, BSWAP_MASK);                        \
+    Y = _mm_setzero_si128();                                    \
+    for (i=0; i < (int)(ibytes/16); i++) {                      \
+        tmp1 = _mm_loadu_si128(&((__m128i*)ivec)[i]);           \
+        tmp1 = _mm_shuffle_epi8(tmp1, BSWAP_MASK);              \
+        Y = _mm_xor_si128(Y, tmp1);                             \
+        Y = gfmul_sw(Y, H);                                     \
+    }                                                           \
+    if (ibytes % 16) {                                          \
+        tmp1 = last_block;                                      \
+        tmp1 = _mm_shuffle_epi8(tmp1, BSWAP_MASK);              \
+        Y = _mm_xor_si128(Y, tmp1);                             \
+        Y = gfmul_sw(Y, H);                                     \
+    }                                                           \
+    tmp1 = _mm_insert_epi64(tmp1, ibytes*8, 0);                 \
+    tmp1 = _mm_insert_epi64(tmp1, 0, 1);                        \
+    Y = _mm_xor_si128(Y, tmp1);                                 \
+    Y = gfmul_sw(Y, H);                                         \
+    Y = _mm_shuffle_epi8(Y, BSWAP_MASK); /* Compute E(K, Y0) */ \
+    tmp1 = _mm_xor_si128(Y, KEY[0]);                            \
+    tmp1 = _mm_aesenc_si128(tmp1, KEY[1]);                      \
+    tmp1 = _mm_aesenc_si128(tmp1, KEY[2]);                      \
+    tmp1 = _mm_aesenc_si128(tmp1, KEY[3]);                      \
+    tmp1 = _mm_aesenc_si128(tmp1, KEY[4]);                      \
+    tmp1 = _mm_aesenc_si128(tmp1, KEY[5]);                      \
+    tmp1 = _mm_aesenc_si128(tmp1, KEY[6]);                      \
+    tmp1 = _mm_aesenc_si128(tmp1, KEY[7]);                      \
+    tmp1 = _mm_aesenc_si128(tmp1, KEY[8]);                      \
+    tmp1 = _mm_aesenc_si128(tmp1, KEY[9]);                      \
+    lastKey = KEY[10];                                          \
+    if (nr > 10) {                                              \
+        tmp1 = _mm_aesenc_si128(tmp1, lastKey);                 \
+        tmp1 = _mm_aesenc_si128(tmp1, KEY[11]);                 \
+        lastKey = KEY[12];                                      \
+        if (nr > 12) {                                          \
+            tmp1 = _mm_aesenc_si128(tmp1, lastKey);             \
+            tmp1 = _mm_aesenc_si128(tmp1, KEY[13]);             \
+            lastKey = KEY[14];                                  \
+        }                                                       \
+    }                                                           \
+    T = _mm_aesenclast_si128(tmp1, lastKey);                    \
+}                                                               \
+while (0)
+
+#define AES_ENC_8(j)                       \
+    tmp1 = _mm_aesenc_si128(tmp1, KEY[j]); \
+    tmp2 = _mm_aesenc_si128(tmp2, KEY[j]); \
+    tmp3 = _mm_aesenc_si128(tmp3, KEY[j]); \
+    tmp4 = _mm_aesenc_si128(tmp4, KEY[j]); \
+    tmp5 = _mm_aesenc_si128(tmp5, KEY[j]); \
+    tmp6 = _mm_aesenc_si128(tmp6, KEY[j]); \
+    tmp7 = _mm_aesenc_si128(tmp7, KEY[j]); \
+    tmp8 = _mm_aesenc_si128(tmp8, KEY[j]);
+
+#define AES_ENC_LAST_8()                                                  \
+    tmp1 =_mm_aesenclast_si128(tmp1, lastKey);                            \
+    tmp2 =_mm_aesenclast_si128(tmp2, lastKey);                            \
+    tmp1 = _mm_xor_si128(tmp1, _mm_loadu_si128(&((__m128i*)in)[i*8+0]));  \
+    tmp2 = _mm_xor_si128(tmp2, _mm_loadu_si128(&((__m128i*)in)[i*8+1]));  \
+    _mm_storeu_si128(&((__m128i*)out)[i*8+0], tmp1);                      \
+    _mm_storeu_si128(&((__m128i*)out)[i*8+1], tmp2);                      \
+    tmp3 =_mm_aesenclast_si128(tmp3, lastKey);                            \
+    tmp4 =_mm_aesenclast_si128(tmp4, lastKey);                            \
+    tmp3 = _mm_xor_si128(tmp3, _mm_loadu_si128(&((__m128i*)in)[i*8+2]));  \
+    tmp4 = _mm_xor_si128(tmp4, _mm_loadu_si128(&((__m128i*)in)[i*8+3]));  \
+    _mm_storeu_si128(&((__m128i*)out)[i*8+2], tmp3);                      \
+    _mm_storeu_si128(&((__m128i*)out)[i*8+3], tmp4);                      \
+    tmp5 =_mm_aesenclast_si128(tmp5, lastKey);                            \
+    tmp6 =_mm_aesenclast_si128(tmp6, lastKey);                            \
+    tmp5 = _mm_xor_si128(tmp5, _mm_loadu_si128(&((__m128i*)in)[i*8+4]));  \
+    tmp6 = _mm_xor_si128(tmp6, _mm_loadu_si128(&((__m128i*)in)[i*8+5]));  \
+    _mm_storeu_si128(&((__m128i*)out)[i*8+4], tmp5);                      \
+    _mm_storeu_si128(&((__m128i*)out)[i*8+5], tmp6);                      \
+    tmp7 =_mm_aesenclast_si128(tmp7, lastKey);                            \
+    tmp8 =_mm_aesenclast_si128(tmp8, lastKey);                            \
+    tmp7 = _mm_xor_si128(tmp7, _mm_loadu_si128(&((__m128i*)in)[i*8+6]));  \
+    tmp8 = _mm_xor_si128(tmp8, _mm_loadu_si128(&((__m128i*)in)[i*8+7]));  \
+    _mm_storeu_si128(&((__m128i*)out)[i*8+6], tmp7);                      \
+    _mm_storeu_si128(&((__m128i*)out)[i*8+7], tmp8);
+
+
+static __m128i gfmul_sw(__m128i a, __m128i b)
+{
+    __m128i r, t1, t2, t3, t4, t5, t6, t7;
+    t2 = _mm_shuffle_epi32(b, 78);
+    t3 = _mm_shuffle_epi32(a, 78);
+    t2 = _mm_xor_si128(t2, b);
+    t3 = _mm_xor_si128(t3, a);
+    t4 = _mm_clmulepi64_si128(b, a, 0x11);
+    t1 = _mm_clmulepi64_si128(b, a, 0x00);
+    t2 = _mm_clmulepi64_si128(t2, t3, 0x00);
+    t2 = _mm_xor_si128(t2, t1);
+    t2 = _mm_xor_si128(t2, t4);
+    t3 = _mm_slli_si128(t2, 8);
+    t2 = _mm_srli_si128(t2, 8);
+    t1 = _mm_xor_si128(t1, t3);
+    t4 = _mm_xor_si128(t4, t2);
+
+    t5 = _mm_srli_epi32(t1, 31);
+    t6 = _mm_srli_epi32(t4, 31);
+    t1 = _mm_slli_epi32(t1, 1);
+    t4 = _mm_slli_epi32(t4, 1);
+    t7 = _mm_srli_si128(t5, 12);
+    t5 = _mm_slli_si128(t5, 4);
+    t6 = _mm_slli_si128(t6, 4);
+    t4 = _mm_or_si128(t4, t7);
+    t1 = _mm_or_si128(t1, t5);
+    t4 = _mm_or_si128(t4, t6);
+
+    t5 = _mm_slli_epi32(t1, 31);
+    t6 = _mm_slli_epi32(t1, 30);
+    t7 = _mm_slli_epi32(t1, 25);
+    t5 = _mm_xor_si128(t5, t6);
+    t5 = _mm_xor_si128(t5, t7);
+
+    t6 = _mm_srli_si128(t5, 4);
+    t5 = _mm_slli_si128(t5, 12);
+    t1 = _mm_xor_si128(t1, t5);
+    t7 = _mm_srli_epi32(t1, 1);
+    t3 = _mm_srli_epi32(t1, 2);
+    t2 = _mm_srli_epi32(t1, 7);
+
+    t7 = _mm_xor_si128(t7, t3);
+    t7 = _mm_xor_si128(t7, t2);
+    t7 = _mm_xor_si128(t7, t6);
+    t7 = _mm_xor_si128(t7, t1);
+    r = _mm_xor_si128(t4, t7);
+
+    return r;
+}
+
+static void gfmul_only(__m128i a, __m128i b, __m128i* r0, __m128i* r1)
+{
+    __m128i t1, t2, t3, t4;
+
+    /* 128 x 128 Carryless Multiply */
+    t2 = _mm_shuffle_epi32(b, 78);
+    t3 = _mm_shuffle_epi32(a, 78);
+    t2 = _mm_xor_si128(t2, b);
+    t3 = _mm_xor_si128(t3, a);
+    t4 = _mm_clmulepi64_si128(b, a, 0x11);
+    t1 = _mm_clmulepi64_si128(b, a, 0x00);
+    t2 = _mm_clmulepi64_si128(t2, t3, 0x00);
+    t2 = _mm_xor_si128(t2, t1);
+    t2 = _mm_xor_si128(t2, t4);
+    t3 = _mm_slli_si128(t2, 8);
+    t2 = _mm_srli_si128(t2, 8);
+    t1 = _mm_xor_si128(t1, t3);
+    t4 = _mm_xor_si128(t4, t2);
+    *r0 = _mm_xor_si128(t1, *r0);
+    *r1 = _mm_xor_si128(t4, *r1);
+}
+
+static __m128i gfmul_shl1(__m128i a)
+{
+    __m128i t1 = a, t2;
+    t2 = _mm_srli_epi64(t1, 63);
+    t1 = _mm_slli_epi64(t1, 1);
+    t2 = _mm_slli_si128(t2, 8);
+    t1 = _mm_or_si128(t1, t2);
+    /* if (a[1] >> 63) t1 = _mm_xor_si128(t1, MOD2_128); */
+    a = _mm_shuffle_epi32(a, 0xff);
+    a = _mm_srai_epi32(a, 31);
+    a = _mm_and_si128(a, MOD2_128);
+    t1 = _mm_xor_si128(t1, a);
+    return t1;
+}
+
+static __m128i ghash_red(__m128i r0, __m128i r1)
+{
+    __m128i t2, t3;
+    __m128i t5, t6, t7;
+
+    t5 = _mm_slli_epi32(r0, 31);
+    t6 = _mm_slli_epi32(r0, 30);
+    t7 = _mm_slli_epi32(r0, 25);
+    t5 = _mm_xor_si128(t5, t6);
+    t5 = _mm_xor_si128(t5, t7);
+
+    t6 = _mm_srli_si128(t5, 4);
+    t5 = _mm_slli_si128(t5, 12);
+    r0 = _mm_xor_si128(r0, t5);
+    t7 = _mm_srli_epi32(r0, 1);
+    t3 = _mm_srli_epi32(r0, 2);
+    t2 = _mm_srli_epi32(r0, 7);
+
+    t7 = _mm_xor_si128(t7, t3);
+    t7 = _mm_xor_si128(t7, t2);
+    t7 = _mm_xor_si128(t7, t6);
+    t7 = _mm_xor_si128(t7, r0);
+    return _mm_xor_si128(r1, t7);
+}
+
+static __m128i gfmul_shifted(__m128i a, __m128i b)
+{
+    __m128i t0 = _mm_setzero_si128(), t1 = _mm_setzero_si128();
+    gfmul_only(a, b, &t0, &t1);
+    return ghash_red(t0, t1);
+}
+
+#ifndef AES_GCM_AESNI_NO_UNROLL
+static __m128i gfmul8(__m128i a1, __m128i a2, __m128i a3, __m128i a4,
+                      __m128i a5, __m128i a6, __m128i a7, __m128i a8,
+                      __m128i b1, __m128i b2, __m128i b3, __m128i b4,
+                      __m128i b5, __m128i b6, __m128i b7, __m128i b8)
+{
+    __m128i t0 = _mm_setzero_si128(), t1 = _mm_setzero_si128();
+    gfmul_only(a1, b8, &t0, &t1);
+    gfmul_only(a2, b7, &t0, &t1);
+    gfmul_only(a3, b6, &t0, &t1);
+    gfmul_only(a4, b5, &t0, &t1);
+    gfmul_only(a5, b4, &t0, &t1);
+    gfmul_only(a6, b3, &t0, &t1);
+    gfmul_only(a7, b2, &t0, &t1);
+    gfmul_only(a8, b1, &t0, &t1);
+    return ghash_red(t0, t1);
+}
+#endif
+
+
+static void AES_GCM_encrypt(const unsigned char *in,
+                              unsigned char *out,
+                              const unsigned char* addt,
+                              const unsigned char* ivec,
+                              unsigned char *tag, unsigned int nbytes,
+                              unsigned int abytes, unsigned int ibytes,
+                              unsigned int tbytes,
+                              const unsigned char* key, int nr)
+{
+    int i, j ,k;
+    __m128i ctr1;
+    __m128i H, Y, T;
+    __m128i X = _mm_setzero_si128();
+    __m128i *KEY = (__m128i*)key, lastKey;
+    __m128i last_block = _mm_setzero_si128();
+    __m128i tmp1, tmp2;
+#ifndef AES_GCM_AESNI_NO_UNROLL
+    __m128i HT[8];
+    __m128i r0, r1;
+    __m128i XV;
+    __m128i tmp3, tmp4, tmp5, tmp6, tmp7, tmp8;
+#endif
+
+    if (ibytes == GCM_NONCE_MID_SZ)
+        aes_gcm_calc_iv_12(KEY, ivec, nr, H, Y, T);
+    else
+        aes_gcm_calc_iv(KEY, ivec, ibytes, nr, H, Y, T);
+
+    for (i=0; i < (int)(abytes/16); i++) {
+        tmp1 = _mm_loadu_si128(&((__m128i*)addt)[i]);
+        tmp1 = _mm_shuffle_epi8(tmp1, BSWAP_MASK);
+        X = _mm_xor_si128(X, tmp1);
+        X = gfmul_sw(X, H);
+    }
+    if (abytes%16) {
+        last_block = _mm_setzero_si128();
+        for (j=0; j < (int)(abytes%16); j++)
+            ((unsigned char*)&last_block)[j] = addt[i*16+j];
+        tmp1 = last_block;
+        tmp1 = _mm_shuffle_epi8(tmp1, BSWAP_MASK);
+        X = _mm_xor_si128(X, tmp1);
+        X = gfmul_sw(X, H);
+    }
+    tmp1 = _mm_shuffle_epi8(Y, BSWAP_EPI64);
+    ctr1 = _mm_add_epi32(tmp1, ONE);
+    H = gfmul_shl1(H);
+
+#ifndef AES_GCM_AESNI_NO_UNROLL
+    i = 0;
+    if (nbytes >= 16*8) {
+        HT[0] = H;
+        HT[1] = gfmul_shifted(H, H);
+        HT[2] = gfmul_shifted(H, HT[1]);
+        HT[3] = gfmul_shifted(HT[1], HT[1]);
+        HT[4] = gfmul_shifted(HT[1], HT[2]);
+        HT[5] = gfmul_shifted(HT[2], HT[2]);
+        HT[6] = gfmul_shifted(HT[2], HT[3]);
+        HT[7] = gfmul_shifted(HT[3], HT[3]);
+
+        tmp1 = _mm_shuffle_epi8(ctr1, BSWAP_EPI64);
+        tmp2 = _mm_add_epi32(ctr1, ONE);
+        tmp2 = _mm_shuffle_epi8(tmp2, BSWAP_EPI64);
+        tmp3 = _mm_add_epi32(ctr1, TWO);
+        tmp3 = _mm_shuffle_epi8(tmp3, BSWAP_EPI64);
+        tmp4 = _mm_add_epi32(ctr1, THREE);
+        tmp4 = _mm_shuffle_epi8(tmp4, BSWAP_EPI64);
+        tmp5 = _mm_add_epi32(ctr1, FOUR);
+        tmp5 = _mm_shuffle_epi8(tmp5, BSWAP_EPI64);
+        tmp6 = _mm_add_epi32(ctr1, FIVE);
+        tmp6 = _mm_shuffle_epi8(tmp6, BSWAP_EPI64);
+        tmp7 = _mm_add_epi32(ctr1, SIX);
+        tmp7 = _mm_shuffle_epi8(tmp7, BSWAP_EPI64);
+        tmp8 = _mm_add_epi32(ctr1, SEVEN);
+        tmp8 = _mm_shuffle_epi8(tmp8, BSWAP_EPI64);
+        ctr1 = _mm_add_epi32(ctr1, EIGHT);
+        tmp1 =_mm_xor_si128(tmp1, KEY[0]);
+        tmp2 =_mm_xor_si128(tmp2, KEY[0]);
+        tmp3 =_mm_xor_si128(tmp3, KEY[0]);
+        tmp4 =_mm_xor_si128(tmp4, KEY[0]);
+        tmp5 =_mm_xor_si128(tmp5, KEY[0]);
+        tmp6 =_mm_xor_si128(tmp6, KEY[0]);
+        tmp7 =_mm_xor_si128(tmp7, KEY[0]);
+        tmp8 =_mm_xor_si128(tmp8, KEY[0]);
+        AES_ENC_8(1);
+        AES_ENC_8(2);
+        AES_ENC_8(3);
+        AES_ENC_8(4);
+        AES_ENC_8(5);
+        AES_ENC_8(6);
+        AES_ENC_8(7);
+        AES_ENC_8(8);
+        AES_ENC_8(9);
+        lastKey = KEY[10];
+        if (nr > 10) {
+            AES_ENC_8(10);
+            AES_ENC_8(11);
+            lastKey = KEY[12];
+            if (nr > 12) {
+                AES_ENC_8(12);
+                AES_ENC_8(13);
+                lastKey = KEY[14];
+            }
+        }
+        AES_ENC_LAST_8();
+
+        for (i=1; i < (int)(nbytes/16/8); i++) {
+                r0 = _mm_setzero_si128();
+                r1 = _mm_setzero_si128();
+            tmp1 = _mm_shuffle_epi8(ctr1, BSWAP_EPI64);
+            tmp2 = _mm_add_epi32(ctr1, ONE);
+            tmp2 = _mm_shuffle_epi8(tmp2, BSWAP_EPI64);
+            tmp3 = _mm_add_epi32(ctr1, TWO);
+            tmp3 = _mm_shuffle_epi8(tmp3, BSWAP_EPI64);
+            tmp4 = _mm_add_epi32(ctr1, THREE);
+            tmp4 = _mm_shuffle_epi8(tmp4, BSWAP_EPI64);
+            tmp5 = _mm_add_epi32(ctr1, FOUR);
+            tmp5 = _mm_shuffle_epi8(tmp5, BSWAP_EPI64);
+            tmp6 = _mm_add_epi32(ctr1, FIVE);
+            tmp6 = _mm_shuffle_epi8(tmp6, BSWAP_EPI64);
+            tmp7 = _mm_add_epi32(ctr1, SIX);
+            tmp7 = _mm_shuffle_epi8(tmp7, BSWAP_EPI64);
+            tmp8 = _mm_add_epi32(ctr1, SEVEN);
+            tmp8 = _mm_shuffle_epi8(tmp8, BSWAP_EPI64);
+            ctr1 = _mm_add_epi32(ctr1, EIGHT);
+            tmp1 =_mm_xor_si128(tmp1, KEY[0]);
+            tmp2 =_mm_xor_si128(tmp2, KEY[0]);
+            tmp3 =_mm_xor_si128(tmp3, KEY[0]);
+            tmp4 =_mm_xor_si128(tmp4, KEY[0]);
+            tmp5 =_mm_xor_si128(tmp5, KEY[0]);
+            tmp6 =_mm_xor_si128(tmp6, KEY[0]);
+            tmp7 =_mm_xor_si128(tmp7, KEY[0]);
+            tmp8 =_mm_xor_si128(tmp8, KEY[0]);
+                /* 128 x 128 Carryless Multiply */
+                XV = _mm_loadu_si128(&((__m128i*)out)[(i-1)*8+0]);
+                XV = _mm_shuffle_epi8(XV, BSWAP_MASK);
+                XV = _mm_xor_si128(XV, X);
+                gfmul_only(XV, HT[7], &r0, &r1);
+            tmp1 = _mm_aesenc_si128(tmp1, KEY[1]);
+            tmp2 = _mm_aesenc_si128(tmp2, KEY[1]);
+            tmp3 = _mm_aesenc_si128(tmp3, KEY[1]);
+            tmp4 = _mm_aesenc_si128(tmp4, KEY[1]);
+            tmp5 = _mm_aesenc_si128(tmp5, KEY[1]);
+            tmp6 = _mm_aesenc_si128(tmp6, KEY[1]);
+            tmp7 = _mm_aesenc_si128(tmp7, KEY[1]);
+            tmp8 = _mm_aesenc_si128(tmp8, KEY[1]);
+                /* 128 x 128 Carryless Multiply */
+                XV = _mm_loadu_si128(&((__m128i*)out)[(i-1)*8+1]);
+                XV = _mm_shuffle_epi8(XV, BSWAP_MASK);
+                gfmul_only(XV, HT[6], &r0, &r1);
+            tmp1 = _mm_aesenc_si128(tmp1, KEY[2]);
+            tmp2 = _mm_aesenc_si128(tmp2, KEY[2]);
+            tmp3 = _mm_aesenc_si128(tmp3, KEY[2]);
+            tmp4 = _mm_aesenc_si128(tmp4, KEY[2]);
+            tmp5 = _mm_aesenc_si128(tmp5, KEY[2]);
+            tmp6 = _mm_aesenc_si128(tmp6, KEY[2]);
+            tmp7 = _mm_aesenc_si128(tmp7, KEY[2]);
+            tmp8 = _mm_aesenc_si128(tmp8, KEY[2]);
+                /* 128 x 128 Carryless Multiply */
+                XV = _mm_loadu_si128(&((__m128i*)out)[(i-1)*8+2]);
+                XV = _mm_shuffle_epi8(XV, BSWAP_MASK);
+                gfmul_only(XV, HT[5], &r0, &r1);
+            tmp1 = _mm_aesenc_si128(tmp1, KEY[3]);
+            tmp2 = _mm_aesenc_si128(tmp2, KEY[3]);
+            tmp3 = _mm_aesenc_si128(tmp3, KEY[3]);
+            tmp4 = _mm_aesenc_si128(tmp4, KEY[3]);
+            tmp5 = _mm_aesenc_si128(tmp5, KEY[3]);
+            tmp6 = _mm_aesenc_si128(tmp6, KEY[3]);
+            tmp7 = _mm_aesenc_si128(tmp7, KEY[3]);
+            tmp8 = _mm_aesenc_si128(tmp8, KEY[3]);
+                /* 128 x 128 Carryless Multiply */
+                XV = _mm_loadu_si128(&((__m128i*)out)[(i-1)*8+3]);
+                XV = _mm_shuffle_epi8(XV, BSWAP_MASK);
+                gfmul_only(XV, HT[4], &r0, &r1);
+            tmp1 = _mm_aesenc_si128(tmp1, KEY[4]);
+            tmp2 = _mm_aesenc_si128(tmp2, KEY[4]);
+            tmp3 = _mm_aesenc_si128(tmp3, KEY[4]);
+            tmp4 = _mm_aesenc_si128(tmp4, KEY[4]);
+            tmp5 = _mm_aesenc_si128(tmp5, KEY[4]);
+            tmp6 = _mm_aesenc_si128(tmp6, KEY[4]);
+            tmp7 = _mm_aesenc_si128(tmp7, KEY[4]);
+            tmp8 = _mm_aesenc_si128(tmp8, KEY[4]);
+                /* 128 x 128 Carryless Multiply */
+                XV = _mm_loadu_si128(&((__m128i*)out)[(i-1)*8+4]);
+                XV = _mm_shuffle_epi8(XV, BSWAP_MASK);
+                gfmul_only(XV, HT[3], &r0, &r1);
+            tmp1 = _mm_aesenc_si128(tmp1, KEY[5]);
+            tmp2 = _mm_aesenc_si128(tmp2, KEY[5]);
+            tmp3 = _mm_aesenc_si128(tmp3, KEY[5]);
+            tmp4 = _mm_aesenc_si128(tmp4, KEY[5]);
+            tmp5 = _mm_aesenc_si128(tmp5, KEY[5]);
+            tmp6 = _mm_aesenc_si128(tmp6, KEY[5]);
+            tmp7 = _mm_aesenc_si128(tmp7, KEY[5]);
+            tmp8 = _mm_aesenc_si128(tmp8, KEY[5]);
+                /* 128 x 128 Carryless Multiply */
+                XV = _mm_loadu_si128(&((__m128i*)out)[(i-1)*8+5]);
+                XV = _mm_shuffle_epi8(XV, BSWAP_MASK);
+                gfmul_only(XV, HT[2], &r0, &r1);
+            tmp1 = _mm_aesenc_si128(tmp1, KEY[6]);
+            tmp2 = _mm_aesenc_si128(tmp2, KEY[6]);
+            tmp3 = _mm_aesenc_si128(tmp3, KEY[6]);
+            tmp4 = _mm_aesenc_si128(tmp4, KEY[6]);
+            tmp5 = _mm_aesenc_si128(tmp5, KEY[6]);
+            tmp6 = _mm_aesenc_si128(tmp6, KEY[6]);
+            tmp7 = _mm_aesenc_si128(tmp7, KEY[6]);
+            tmp8 = _mm_aesenc_si128(tmp8, KEY[6]);
+                /* 128 x 128 Carryless Multiply */
+                XV = _mm_loadu_si128(&((__m128i*)out)[(i-1)*8+6]);
+                XV = _mm_shuffle_epi8(XV, BSWAP_MASK);
+                gfmul_only(XV, HT[1], &r0, &r1);
+            tmp1 = _mm_aesenc_si128(tmp1, KEY[7]);
+            tmp2 = _mm_aesenc_si128(tmp2, KEY[7]);
+            tmp3 = _mm_aesenc_si128(tmp3, KEY[7]);
+            tmp4 = _mm_aesenc_si128(tmp4, KEY[7]);
+            tmp5 = _mm_aesenc_si128(tmp5, KEY[7]);
+            tmp6 = _mm_aesenc_si128(tmp6, KEY[7]);
+            tmp7 = _mm_aesenc_si128(tmp7, KEY[7]);
+            tmp8 = _mm_aesenc_si128(tmp8, KEY[7]);
+                /* 128 x 128 Carryless Multiply */
+                XV = _mm_loadu_si128(&((__m128i*)out)[(i-1)*8+7]);
+                XV = _mm_shuffle_epi8(XV, BSWAP_MASK);
+                gfmul_only(XV, HT[0], &r0, &r1);
+            tmp1 = _mm_aesenc_si128(tmp1, KEY[8]);
+            tmp2 = _mm_aesenc_si128(tmp2, KEY[8]);
+            tmp3 = _mm_aesenc_si128(tmp3, KEY[8]);
+            tmp4 = _mm_aesenc_si128(tmp4, KEY[8]);
+            tmp5 = _mm_aesenc_si128(tmp5, KEY[8]);
+            tmp6 = _mm_aesenc_si128(tmp6, KEY[8]);
+            tmp7 = _mm_aesenc_si128(tmp7, KEY[8]);
+            tmp8 = _mm_aesenc_si128(tmp8, KEY[8]);
+                /* Reduction */
+                X = ghash_red(r0, r1);
+            tmp1 = _mm_aesenc_si128(tmp1, KEY[9]);
+            tmp2 = _mm_aesenc_si128(tmp2, KEY[9]);
+            tmp3 = _mm_aesenc_si128(tmp3, KEY[9]);
+            tmp4 = _mm_aesenc_si128(tmp4, KEY[9]);
+            tmp5 = _mm_aesenc_si128(tmp5, KEY[9]);
+            tmp6 = _mm_aesenc_si128(tmp6, KEY[9]);
+            tmp7 = _mm_aesenc_si128(tmp7, KEY[9]);
+            tmp8 = _mm_aesenc_si128(tmp8, KEY[9]);
+            lastKey = KEY[10];
+            if (nr > 10) {
+                tmp1 = _mm_aesenc_si128(tmp1, KEY[10]);
+                tmp2 = _mm_aesenc_si128(tmp2, KEY[10]);
+                tmp3 = _mm_aesenc_si128(tmp3, KEY[10]);
+                tmp4 = _mm_aesenc_si128(tmp4, KEY[10]);
+                tmp5 = _mm_aesenc_si128(tmp5, KEY[10]);
+                tmp6 = _mm_aesenc_si128(tmp6, KEY[10]);
+                tmp7 = _mm_aesenc_si128(tmp7, KEY[10]);
+                tmp8 = _mm_aesenc_si128(tmp8, KEY[10]);
+                tmp1 = _mm_aesenc_si128(tmp1, KEY[11]);
+                tmp2 = _mm_aesenc_si128(tmp2, KEY[11]);
+                tmp3 = _mm_aesenc_si128(tmp3, KEY[11]);
+                tmp4 = _mm_aesenc_si128(tmp4, KEY[11]);
+                tmp5 = _mm_aesenc_si128(tmp5, KEY[11]);
+                tmp6 = _mm_aesenc_si128(tmp6, KEY[11]);
+                tmp7 = _mm_aesenc_si128(tmp7, KEY[11]);
+                tmp8 = _mm_aesenc_si128(tmp8, KEY[11]);
+                lastKey = KEY[12];
+                if (nr > 12) {
+                    tmp1 = _mm_aesenc_si128(tmp1, KEY[12]);
+                    tmp2 = _mm_aesenc_si128(tmp2, KEY[12]);
+                    tmp3 = _mm_aesenc_si128(tmp3, KEY[12]);
+                    tmp4 = _mm_aesenc_si128(tmp4, KEY[12]);
+                    tmp5 = _mm_aesenc_si128(tmp5, KEY[12]);
+                    tmp6 = _mm_aesenc_si128(tmp6, KEY[12]);
+                    tmp7 = _mm_aesenc_si128(tmp7, KEY[12]);
+                    tmp8 = _mm_aesenc_si128(tmp8, KEY[12]);
+                    tmp1 = _mm_aesenc_si128(tmp1, KEY[13]);
+                    tmp2 = _mm_aesenc_si128(tmp2, KEY[13]);
+                    tmp3 = _mm_aesenc_si128(tmp3, KEY[13]);
+                    tmp4 = _mm_aesenc_si128(tmp4, KEY[13]);
+                    tmp5 = _mm_aesenc_si128(tmp5, KEY[13]);
+                    tmp6 = _mm_aesenc_si128(tmp6, KEY[13]);
+                    tmp7 = _mm_aesenc_si128(tmp7, KEY[13]);
+                    tmp8 = _mm_aesenc_si128(tmp8, KEY[13]);
+                    lastKey = KEY[14];
+                }
+            }
+            AES_ENC_LAST_8();
+        }
+
+        tmp1 = _mm_shuffle_epi8(tmp1, BSWAP_MASK);
+        tmp2 = _mm_shuffle_epi8(tmp2, BSWAP_MASK);
+        tmp3 = _mm_shuffle_epi8(tmp3, BSWAP_MASK);
+        tmp4 = _mm_shuffle_epi8(tmp4, BSWAP_MASK);
+        tmp5 = _mm_shuffle_epi8(tmp5, BSWAP_MASK);
+        tmp6 = _mm_shuffle_epi8(tmp6, BSWAP_MASK);
+        tmp7 = _mm_shuffle_epi8(tmp7, BSWAP_MASK);
+        tmp8 = _mm_shuffle_epi8(tmp8, BSWAP_MASK);
+        tmp1 = _mm_xor_si128(X, tmp1);
+        X = gfmul8(tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8,
+                   HT[0], HT[1], HT[2], HT[3], HT[4], HT[5], HT[6], HT[7]);
+    }
+    for (k = i*8; k < (int)(nbytes/16); k++) {
+        tmp1 = _mm_shuffle_epi8(ctr1, BSWAP_EPI64);
+        ctr1 = _mm_add_epi32(ctr1, ONE);
+        tmp1 = _mm_xor_si128(tmp1, KEY[0]);
+        tmp1 = _mm_aesenc_si128(tmp1, KEY[1]);
+        tmp1 = _mm_aesenc_si128(tmp1, KEY[2]);
+        tmp1 = _mm_aesenc_si128(tmp1, KEY[3]);
+        tmp1 = _mm_aesenc_si128(tmp1, KEY[4]);
+        tmp1 = _mm_aesenc_si128(tmp1, KEY[5]);
+        tmp1 = _mm_aesenc_si128(tmp1, KEY[6]);
+        tmp1 = _mm_aesenc_si128(tmp1, KEY[7]);
+        tmp1 = _mm_aesenc_si128(tmp1, KEY[8]);
+        tmp1 = _mm_aesenc_si128(tmp1, KEY[9]);
+        lastKey = KEY[10];
+        if (nr > 10) {
+            tmp1 = _mm_aesenc_si128(tmp1, lastKey);
+            tmp1 = _mm_aesenc_si128(tmp1, KEY[11]);
+            lastKey = KEY[12];
+            if (nr > 12) {
+                tmp1 = _mm_aesenc_si128(tmp1, lastKey);
+                tmp1 = _mm_aesenc_si128(tmp1, KEY[13]);
+                lastKey = KEY[14];
+            }
+        }
+        tmp1 = _mm_aesenclast_si128(tmp1, lastKey);
+        tmp1 = _mm_xor_si128(tmp1, _mm_loadu_si128(&((__m128i*)in)[k]));
+        _mm_storeu_si128(&((__m128i*)out)[k], tmp1);
+        tmp1 = _mm_shuffle_epi8(tmp1, BSWAP_MASK);
+        X =_mm_xor_si128(X, tmp1);
+        X = gfmul_shifted(X, H);
+    }
+#else /* AES_GCM_AESNI_NO_UNROLL */
+    for (k = 0; k < (int)(nbytes/16) && k < 1; k++) {
+        tmp1 = _mm_shuffle_epi8(ctr1, BSWAP_EPI64);
+        ctr1 = _mm_add_epi32(ctr1, ONE);
+        tmp1 = _mm_xor_si128(tmp1, KEY[0]);
+        tmp1 = _mm_aesenc_si128(tmp1, KEY[1]);
+        tmp1 = _mm_aesenc_si128(tmp1, KEY[2]);
+        tmp1 = _mm_aesenc_si128(tmp1, KEY[3]);
+        tmp1 = _mm_aesenc_si128(tmp1, KEY[4]);
+        tmp1 = _mm_aesenc_si128(tmp1, KEY[5]);
+        tmp1 = _mm_aesenc_si128(tmp1, KEY[6]);
+        tmp1 = _mm_aesenc_si128(tmp1, KEY[7]);
+        tmp1 = _mm_aesenc_si128(tmp1, KEY[8]);
+        tmp1 = _mm_aesenc_si128(tmp1, KEY[9]);
+        lastKey = KEY[10];
+        if (nr > 10) {
+            tmp1 = _mm_aesenc_si128(tmp1, lastKey);
+            tmp1 = _mm_aesenc_si128(tmp1, KEY[11]);
+            lastKey = KEY[12];
+            if (nr > 12) {
+                tmp1 = _mm_aesenc_si128(tmp1, lastKey);
+                tmp1 = _mm_aesenc_si128(tmp1, KEY[13]);
+                lastKey = KEY[14];
+            }
+        }
+        tmp1 = _mm_aesenclast_si128(tmp1, lastKey);
+        tmp1 = _mm_xor_si128(tmp1, _mm_loadu_si128(&((__m128i*)in)[k]));
+        _mm_storeu_si128(&((__m128i*)out)[k], tmp1);
+        tmp1 = _mm_shuffle_epi8(tmp1, BSWAP_MASK);
+        X =_mm_xor_si128(X, tmp1);
+    }
+    for (; k < (int)(nbytes/16); k++) {
+        tmp1 = _mm_shuffle_epi8(ctr1, BSWAP_EPI64);
+        ctr1 = _mm_add_epi32(ctr1, ONE);
+        tmp1 = _mm_xor_si128(tmp1, KEY[0]);
+        tmp1 = _mm_aesenc_si128(tmp1, KEY[1]);
+        tmp1 = _mm_aesenc_si128(tmp1, KEY[2]);
+        tmp1 = _mm_aesenc_si128(tmp1, KEY[3]);
+        tmp1 = _mm_aesenc_si128(tmp1, KEY[4]);
+        tmp1 = _mm_aesenc_si128(tmp1, KEY[5]);
+        tmp1 = _mm_aesenc_si128(tmp1, KEY[6]);
+        tmp1 = _mm_aesenc_si128(tmp1, KEY[7]);
+        tmp1 = _mm_aesenc_si128(tmp1, KEY[8]);
+        tmp1 = _mm_aesenc_si128(tmp1, KEY[9]);
+        X = gfmul_shifted(X, H);
+        lastKey = KEY[10];
+        if (nr > 10) {
+            tmp1 = _mm_aesenc_si128(tmp1, lastKey);
+            tmp1 = _mm_aesenc_si128(tmp1, KEY[11]);
+            lastKey = KEY[12];
+            if (nr > 12) {
+                tmp1 = _mm_aesenc_si128(tmp1, lastKey);
+                tmp1 = _mm_aesenc_si128(tmp1, KEY[13]);
+                lastKey = KEY[14];
+            }
+        }
+        tmp1 = _mm_aesenclast_si128(tmp1, lastKey);
+        tmp1 = _mm_xor_si128(tmp1, _mm_loadu_si128(&((__m128i*)in)[k]));
+        _mm_storeu_si128(&((__m128i*)out)[k], tmp1);
+        tmp1 = _mm_shuffle_epi8(tmp1, BSWAP_MASK);
+        X =_mm_xor_si128(X, tmp1);
+    }
+    if (k > 0) {
+        X = gfmul_shifted(X, H);
+    }
+#endif /* AES_GCM_AESNI_NO_UNROLL */
+
+    /* If one partial block remains */
+    if (nbytes % 16) {
+        tmp1 = _mm_shuffle_epi8(ctr1, BSWAP_EPI64);
+        tmp1 = _mm_xor_si128(tmp1, KEY[0]);
+        tmp1 = _mm_aesenc_si128(tmp1, KEY[1]);
+        tmp1 = _mm_aesenc_si128(tmp1, KEY[2]);
+        tmp1 = _mm_aesenc_si128(tmp1, KEY[3]);
+        tmp1 = _mm_aesenc_si128(tmp1, KEY[4]);
+        tmp1 = _mm_aesenc_si128(tmp1, KEY[5]);
+        tmp1 = _mm_aesenc_si128(tmp1, KEY[6]);
+        tmp1 = _mm_aesenc_si128(tmp1, KEY[7]);
+        tmp1 = _mm_aesenc_si128(tmp1, KEY[8]);
+        tmp1 = _mm_aesenc_si128(tmp1, KEY[9]);
+        lastKey = KEY[10];
+        if (nr > 10) {
+            tmp1 = _mm_aesenc_si128(tmp1, lastKey);
+            tmp1 = _mm_aesenc_si128(tmp1, KEY[11]);
+            lastKey = KEY[12];
+            if (nr > 12) {
+                tmp1 = _mm_aesenc_si128(tmp1, lastKey);
+                tmp1 = _mm_aesenc_si128(tmp1, KEY[13]);
+                lastKey = KEY[14];
+            }
+        }
+        tmp1 = _mm_aesenclast_si128(tmp1, lastKey);
+        last_block = tmp1;
+        for (j=0; j < (int)(nbytes%16); j++)
+            ((unsigned char*)&last_block)[j] = in[k*16+j];
+        tmp1 = _mm_xor_si128(tmp1, last_block);
+        last_block = tmp1;
+        for (j=0; j < (int)(nbytes%16); j++)
+            out[k*16+j] = ((unsigned char*)&last_block)[j];
+        tmp1 = last_block;
+        tmp1 = _mm_shuffle_epi8(tmp1, BSWAP_MASK);
+        X =_mm_xor_si128(X, tmp1);
+        X = gfmul_shifted(X, H);
+    }
+    tmp1 = _mm_insert_epi64(tmp1, nbytes*8, 0);
+    tmp1 = _mm_insert_epi64(tmp1, abytes*8, 1);
+    X = _mm_xor_si128(X, tmp1);
+    X = gfmul_shifted(X, H);
+    X = _mm_shuffle_epi8(X, BSWAP_MASK);
+    T = _mm_xor_si128(X, T);
+    /*_mm_storeu_si128((__m128i*)tag, T);*/
+    XMEMCPY(tag, &T, tbytes);
+}
+
+#ifdef HAVE_AES_DECRYPT
+
+static void AES_GCM_decrypt(const unsigned char *in,
+                           unsigned char *out,
+                           const unsigned char* addt,
+                           const unsigned char* ivec,
+                           const unsigned char *tag, int nbytes, int abytes,
+                           int ibytes, word32 tbytes, const unsigned char* key,
+                           int nr, int* res)
+{
+    int i, j ,k;
+    __m128i H, Y, T;
+    __m128i *KEY = (__m128i*)key, lastKey;
+    __m128i ctr1;
+    __m128i last_block = _mm_setzero_si128();
+    __m128i X = _mm_setzero_si128();
+    __m128i tmp1, tmp2, XV;
+#ifndef AES_GCM_AESNI_NO_UNROLL
+    __m128i HT[8];
+    __m128i r0, r1;
+    __m128i tmp3, tmp4, tmp5, tmp6, tmp7, tmp8;
+#endif /* AES_GCM_AESNI_NO_UNROLL */
+
+    if (ibytes == GCM_NONCE_MID_SZ)
+        aes_gcm_calc_iv_12(KEY, ivec, nr, H, Y, T);
+    else
+        aes_gcm_calc_iv(KEY, ivec, ibytes, nr, H, Y, T);
+
+    for (i=0; i<abytes/16; i++) {
+        tmp1 = _mm_loadu_si128(&((__m128i*)addt)[i]);
+        tmp1 = _mm_shuffle_epi8(tmp1, BSWAP_MASK);
+        X = _mm_xor_si128(X, tmp1);
+        X = gfmul_sw(X, H);
+    }
+    if (abytes%16) {
+        last_block = _mm_setzero_si128();
+        for (j=0; j<abytes%16; j++)
+            ((unsigned char*)&last_block)[j] = addt[i*16+j];
+        tmp1 = last_block;
+        tmp1 = _mm_shuffle_epi8(tmp1, BSWAP_MASK);
+        X = _mm_xor_si128(X, tmp1);
+        X = gfmul_sw(X, H);
+    }
+
+    tmp1 = _mm_shuffle_epi8(Y, BSWAP_EPI64);
+    ctr1 = _mm_add_epi32(tmp1, ONE);
+    H = gfmul_shl1(H);
+    i = 0;
+
+#ifndef AES_GCM_AESNI_NO_UNROLL
+
+    if (0 < nbytes/16/8) {
+        HT[0] = H;
+        HT[1] = gfmul_shifted(H, H);
+        HT[2] = gfmul_shifted(H, HT[1]);
+        HT[3] = gfmul_shifted(HT[1], HT[1]);
+        HT[4] = gfmul_shifted(HT[1], HT[2]);
+        HT[5] = gfmul_shifted(HT[2], HT[2]);
+        HT[6] = gfmul_shifted(HT[2], HT[3]);
+        HT[7] = gfmul_shifted(HT[3], HT[3]);
+
+        for (; i < nbytes/16/8; i++) {
+                r0 = _mm_setzero_si128();
+                r1 = _mm_setzero_si128();
+
+            tmp1 = _mm_shuffle_epi8(ctr1, BSWAP_EPI64);
+            tmp2 = _mm_add_epi32(ctr1, ONE);
+            tmp2 = _mm_shuffle_epi8(tmp2, BSWAP_EPI64);
+            tmp3 = _mm_add_epi32(ctr1, TWO);
+            tmp3 = _mm_shuffle_epi8(tmp3, BSWAP_EPI64);
+            tmp4 = _mm_add_epi32(ctr1, THREE);
+            tmp4 = _mm_shuffle_epi8(tmp4, BSWAP_EPI64);
+            tmp5 = _mm_add_epi32(ctr1, FOUR);
+            tmp5 = _mm_shuffle_epi8(tmp5, BSWAP_EPI64);
+            tmp6 = _mm_add_epi32(ctr1, FIVE);
+            tmp6 = _mm_shuffle_epi8(tmp6, BSWAP_EPI64);
+            tmp7 = _mm_add_epi32(ctr1, SIX);
+            tmp7 = _mm_shuffle_epi8(tmp7, BSWAP_EPI64);
+            tmp8 = _mm_add_epi32(ctr1, SEVEN);
+            tmp8 = _mm_shuffle_epi8(tmp8, BSWAP_EPI64);
+            ctr1 = _mm_add_epi32(ctr1, EIGHT);
+            tmp1 =_mm_xor_si128(tmp1, KEY[0]);
+            tmp2 =_mm_xor_si128(tmp2, KEY[0]);
+            tmp3 =_mm_xor_si128(tmp3, KEY[0]);
+            tmp4 =_mm_xor_si128(tmp4, KEY[0]);
+            tmp5 =_mm_xor_si128(tmp5, KEY[0]);
+            tmp6 =_mm_xor_si128(tmp6, KEY[0]);
+            tmp7 =_mm_xor_si128(tmp7, KEY[0]);
+            tmp8 =_mm_xor_si128(tmp8, KEY[0]);
+                /* 128 x 128 Carryless Multiply */
+                XV = _mm_loadu_si128(&((__m128i*)in)[i*8+0]);
+                XV = _mm_shuffle_epi8(XV, BSWAP_MASK);
+                XV = _mm_xor_si128(XV, X);
+                gfmul_only(XV, HT[7], &r0, &r1);
+            tmp1 = _mm_aesenc_si128(tmp1, KEY[1]);
+            tmp2 = _mm_aesenc_si128(tmp2, KEY[1]);
+            tmp3 = _mm_aesenc_si128(tmp3, KEY[1]);
+            tmp4 = _mm_aesenc_si128(tmp4, KEY[1]);
+            tmp5 = _mm_aesenc_si128(tmp5, KEY[1]);
+            tmp6 = _mm_aesenc_si128(tmp6, KEY[1]);
+            tmp7 = _mm_aesenc_si128(tmp7, KEY[1]);
+            tmp8 = _mm_aesenc_si128(tmp8, KEY[1]);
+                /* 128 x 128 Carryless Multiply */
+                XV = _mm_loadu_si128(&((__m128i*)in)[i*8+1]);
+                XV = _mm_shuffle_epi8(XV, BSWAP_MASK);
+                gfmul_only(XV, HT[6], &r0, &r1);
+            tmp1 = _mm_aesenc_si128(tmp1, KEY[2]);
+            tmp2 = _mm_aesenc_si128(tmp2, KEY[2]);
+            tmp3 = _mm_aesenc_si128(tmp3, KEY[2]);
+            tmp4 = _mm_aesenc_si128(tmp4, KEY[2]);
+            tmp5 = _mm_aesenc_si128(tmp5, KEY[2]);
+            tmp6 = _mm_aesenc_si128(tmp6, KEY[2]);
+            tmp7 = _mm_aesenc_si128(tmp7, KEY[2]);
+            tmp8 = _mm_aesenc_si128(tmp8, KEY[2]);
+                /* 128 x 128 Carryless Multiply */
+                XV = _mm_loadu_si128(&((__m128i*)in)[i*8+2]);
+                XV = _mm_shuffle_epi8(XV, BSWAP_MASK);
+                gfmul_only(XV, HT[5], &r0, &r1);
+            tmp1 = _mm_aesenc_si128(tmp1, KEY[3]);
+            tmp2 = _mm_aesenc_si128(tmp2, KEY[3]);
+            tmp3 = _mm_aesenc_si128(tmp3, KEY[3]);
+            tmp4 = _mm_aesenc_si128(tmp4, KEY[3]);
+            tmp5 = _mm_aesenc_si128(tmp5, KEY[3]);
+            tmp6 = _mm_aesenc_si128(tmp6, KEY[3]);
+            tmp7 = _mm_aesenc_si128(tmp7, KEY[3]);
+            tmp8 = _mm_aesenc_si128(tmp8, KEY[3]);
+                /* 128 x 128 Carryless Multiply */
+                XV = _mm_loadu_si128(&((__m128i*)in)[i*8+3]);
+                XV = _mm_shuffle_epi8(XV, BSWAP_MASK);
+                gfmul_only(XV, HT[4], &r0, &r1);
+            tmp1 = _mm_aesenc_si128(tmp1, KEY[4]);
+            tmp2 = _mm_aesenc_si128(tmp2, KEY[4]);
+            tmp3 = _mm_aesenc_si128(tmp3, KEY[4]);
+            tmp4 = _mm_aesenc_si128(tmp4, KEY[4]);
+            tmp5 = _mm_aesenc_si128(tmp5, KEY[4]);
+            tmp6 = _mm_aesenc_si128(tmp6, KEY[4]);
+            tmp7 = _mm_aesenc_si128(tmp7, KEY[4]);
+            tmp8 = _mm_aesenc_si128(tmp8, KEY[4]);
+                /* 128 x 128 Carryless Multiply */
+                XV = _mm_loadu_si128(&((__m128i*)in)[i*8+4]);
+                XV = _mm_shuffle_epi8(XV, BSWAP_MASK);
+                gfmul_only(XV, HT[3], &r0, &r1);
+            tmp1 = _mm_aesenc_si128(tmp1, KEY[5]);
+            tmp2 = _mm_aesenc_si128(tmp2, KEY[5]);
+            tmp3 = _mm_aesenc_si128(tmp3, KEY[5]);
+            tmp4 = _mm_aesenc_si128(tmp4, KEY[5]);
+            tmp5 = _mm_aesenc_si128(tmp5, KEY[5]);
+            tmp6 = _mm_aesenc_si128(tmp6, KEY[5]);
+            tmp7 = _mm_aesenc_si128(tmp7, KEY[5]);
+            tmp8 = _mm_aesenc_si128(tmp8, KEY[5]);
+                /* 128 x 128 Carryless Multiply */
+                XV = _mm_loadu_si128(&((__m128i*)in)[i*8+5]);
+                XV = _mm_shuffle_epi8(XV, BSWAP_MASK);
+                gfmul_only(XV, HT[2], &r0, &r1);
+            tmp1 = _mm_aesenc_si128(tmp1, KEY[6]);
+            tmp2 = _mm_aesenc_si128(tmp2, KEY[6]);
+            tmp3 = _mm_aesenc_si128(tmp3, KEY[6]);
+            tmp4 = _mm_aesenc_si128(tmp4, KEY[6]);
+            tmp5 = _mm_aesenc_si128(tmp5, KEY[6]);
+            tmp6 = _mm_aesenc_si128(tmp6, KEY[6]);
+            tmp7 = _mm_aesenc_si128(tmp7, KEY[6]);
+            tmp8 = _mm_aesenc_si128(tmp8, KEY[6]);
+                /* 128 x 128 Carryless Multiply */
+                XV = _mm_loadu_si128(&((__m128i*)in)[i*8+6]);
+                XV = _mm_shuffle_epi8(XV, BSWAP_MASK);
+                gfmul_only(XV, HT[1], &r0, &r1);
+            tmp1 = _mm_aesenc_si128(tmp1, KEY[7]);
+            tmp2 = _mm_aesenc_si128(tmp2, KEY[7]);
+            tmp3 = _mm_aesenc_si128(tmp3, KEY[7]);
+            tmp4 = _mm_aesenc_si128(tmp4, KEY[7]);
+            tmp5 = _mm_aesenc_si128(tmp5, KEY[7]);
+            tmp6 = _mm_aesenc_si128(tmp6, KEY[7]);
+            tmp7 = _mm_aesenc_si128(tmp7, KEY[7]);
+            tmp8 = _mm_aesenc_si128(tmp8, KEY[7]);
+                /* 128 x 128 Carryless Multiply */
+                XV = _mm_loadu_si128(&((__m128i*)in)[i*8+7]);
+                XV = _mm_shuffle_epi8(XV, BSWAP_MASK);
+                gfmul_only(XV, HT[0], &r0, &r1);
+            tmp1 = _mm_aesenc_si128(tmp1, KEY[8]);
+            tmp2 = _mm_aesenc_si128(tmp2, KEY[8]);
+            tmp3 = _mm_aesenc_si128(tmp3, KEY[8]);
+            tmp4 = _mm_aesenc_si128(tmp4, KEY[8]);
+            tmp5 = _mm_aesenc_si128(tmp5, KEY[8]);
+            tmp6 = _mm_aesenc_si128(tmp6, KEY[8]);
+            tmp7 = _mm_aesenc_si128(tmp7, KEY[8]);
+            tmp8 = _mm_aesenc_si128(tmp8, KEY[8]);
+                /* Reduction */
+                X = ghash_red(r0, r1);
+            tmp1 = _mm_aesenc_si128(tmp1, KEY[9]);
+            tmp2 = _mm_aesenc_si128(tmp2, KEY[9]);
+            tmp3 = _mm_aesenc_si128(tmp3, KEY[9]);
+            tmp4 = _mm_aesenc_si128(tmp4, KEY[9]);
+            tmp5 = _mm_aesenc_si128(tmp5, KEY[9]);
+            tmp6 = _mm_aesenc_si128(tmp6, KEY[9]);
+            tmp7 = _mm_aesenc_si128(tmp7, KEY[9]);
+            tmp8 = _mm_aesenc_si128(tmp8, KEY[9]);
+            lastKey = KEY[10];
+            if (nr > 10) {
+                tmp1 = _mm_aesenc_si128(tmp1, KEY[10]);
+                tmp2 = _mm_aesenc_si128(tmp2, KEY[10]);
+                tmp3 = _mm_aesenc_si128(tmp3, KEY[10]);
+                tmp4 = _mm_aesenc_si128(tmp4, KEY[10]);
+                tmp5 = _mm_aesenc_si128(tmp5, KEY[10]);
+                tmp6 = _mm_aesenc_si128(tmp6, KEY[10]);
+                tmp7 = _mm_aesenc_si128(tmp7, KEY[10]);
+                tmp8 = _mm_aesenc_si128(tmp8, KEY[10]);
+                tmp1 = _mm_aesenc_si128(tmp1, KEY[11]);
+                tmp2 = _mm_aesenc_si128(tmp2, KEY[11]);
+                tmp3 = _mm_aesenc_si128(tmp3, KEY[11]);
+                tmp4 = _mm_aesenc_si128(tmp4, KEY[11]);
+                tmp5 = _mm_aesenc_si128(tmp5, KEY[11]);
+                tmp6 = _mm_aesenc_si128(tmp6, KEY[11]);
+                tmp7 = _mm_aesenc_si128(tmp7, KEY[11]);
+                tmp8 = _mm_aesenc_si128(tmp8, KEY[11]);
+                lastKey = KEY[12];
+                if (nr > 12) {
+                    tmp1 = _mm_aesenc_si128(tmp1, KEY[12]);
+                    tmp2 = _mm_aesenc_si128(tmp2, KEY[12]);
+                    tmp3 = _mm_aesenc_si128(tmp3, KEY[12]);
+                    tmp4 = _mm_aesenc_si128(tmp4, KEY[12]);
+                    tmp5 = _mm_aesenc_si128(tmp5, KEY[12]);
+                    tmp6 = _mm_aesenc_si128(tmp6, KEY[12]);
+                    tmp7 = _mm_aesenc_si128(tmp7, KEY[12]);
+                    tmp8 = _mm_aesenc_si128(tmp8, KEY[12]);
+                    tmp1 = _mm_aesenc_si128(tmp1, KEY[13]);
+                    tmp2 = _mm_aesenc_si128(tmp2, KEY[13]);
+                    tmp3 = _mm_aesenc_si128(tmp3, KEY[13]);
+                    tmp4 = _mm_aesenc_si128(tmp4, KEY[13]);
+                    tmp5 = _mm_aesenc_si128(tmp5, KEY[13]);
+                    tmp6 = _mm_aesenc_si128(tmp6, KEY[13]);
+                    tmp7 = _mm_aesenc_si128(tmp7, KEY[13]);
+                    tmp8 = _mm_aesenc_si128(tmp8, KEY[13]);
+                    lastKey = KEY[14];
+                }
+            }
+            AES_ENC_LAST_8();
+        }
+    }
+
+#endif /* AES_GCM_AESNI_NO_UNROLL */
+
+    for (k = i*8; k < nbytes/16; k++) {
+        tmp1 = _mm_shuffle_epi8(ctr1, BSWAP_EPI64);
+        ctr1 = _mm_add_epi32(ctr1, ONE);
+        tmp1 = _mm_xor_si128(tmp1, KEY[0]);
+        tmp1 = _mm_aesenc_si128(tmp1, KEY[1]);
+        tmp1 = _mm_aesenc_si128(tmp1, KEY[2]);
+        tmp1 = _mm_aesenc_si128(tmp1, KEY[3]);
+        tmp1 = _mm_aesenc_si128(tmp1, KEY[4]);
+        tmp1 = _mm_aesenc_si128(tmp1, KEY[5]);
+        tmp1 = _mm_aesenc_si128(tmp1, KEY[6]);
+        tmp1 = _mm_aesenc_si128(tmp1, KEY[7]);
+        tmp1 = _mm_aesenc_si128(tmp1, KEY[8]);
+        tmp1 = _mm_aesenc_si128(tmp1, KEY[9]);
+        /* 128 x 128 Carryless Multiply */
+        XV = _mm_loadu_si128(&((__m128i*)in)[k]);
+        XV = _mm_shuffle_epi8(XV, BSWAP_MASK);
+        XV = _mm_xor_si128(XV, X);
+        X = gfmul_shifted(XV, H);
+        lastKey = KEY[10];
+        if (nr > 10) {
+            tmp1 = _mm_aesenc_si128(tmp1, lastKey);
+            tmp1 = _mm_aesenc_si128(tmp1, KEY[11]);
+            lastKey = KEY[12];
+            if (nr > 12) {
+                tmp1 = _mm_aesenc_si128(tmp1, lastKey);
+                tmp1 = _mm_aesenc_si128(tmp1, KEY[13]);
+                lastKey = KEY[14];
+            }
+        }
+        tmp1 = _mm_aesenclast_si128(tmp1, lastKey);
+        tmp2 = _mm_loadu_si128(&((__m128i*)in)[k]);
+        tmp1 = _mm_xor_si128(tmp1, tmp2);
+        _mm_storeu_si128(&((__m128i*)out)[k], tmp1);
+    }
+
+    /* If one partial block remains */
+    if (nbytes % 16) {
+        tmp1 = _mm_shuffle_epi8(ctr1, BSWAP_EPI64);
+        tmp1 = _mm_xor_si128(tmp1, KEY[0]);
+        tmp1 = _mm_aesenc_si128(tmp1, KEY[1]);
+        tmp1 = _mm_aesenc_si128(tmp1, KEY[2]);
+        tmp1 = _mm_aesenc_si128(tmp1, KEY[3]);
+        tmp1 = _mm_aesenc_si128(tmp1, KEY[4]);
+        tmp1 = _mm_aesenc_si128(tmp1, KEY[5]);
+        tmp1 = _mm_aesenc_si128(tmp1, KEY[6]);
+        tmp1 = _mm_aesenc_si128(tmp1, KEY[7]);
+        tmp1 = _mm_aesenc_si128(tmp1, KEY[8]);
+        tmp1 = _mm_aesenc_si128(tmp1, KEY[9]);
+        lastKey = KEY[10];
+        if (nr > 10) {
+            tmp1 = _mm_aesenc_si128(tmp1, lastKey);
+            tmp1 = _mm_aesenc_si128(tmp1, KEY[11]);
+            lastKey = KEY[12];
+            if (nr > 12) {
+                tmp1 = _mm_aesenc_si128(tmp1, lastKey);
+                tmp1 = _mm_aesenc_si128(tmp1, KEY[13]);
+                lastKey = KEY[14];
+            }
+        }
+        tmp1 = _mm_aesenclast_si128(tmp1, lastKey);
+        last_block = _mm_setzero_si128();
+        for (j=0; j < nbytes%16; j++)
+            ((unsigned char*)&last_block)[j] = in[k*16+j];
+        XV = last_block;
+        tmp1 = _mm_xor_si128(tmp1, last_block);
+        last_block = tmp1;
+        for (j=0; j < nbytes%16; j++)
+            out[k*16+j] = ((unsigned char*)&last_block)[j];
+        XV = _mm_shuffle_epi8(XV, BSWAP_MASK);
+        XV = _mm_xor_si128(XV, X);
+        X = gfmul_shifted(XV, H);
+    }
+
+    tmp1 = _mm_insert_epi64(tmp1, nbytes*8, 0);
+    tmp1 = _mm_insert_epi64(tmp1, abytes*8, 1);
+    /* 128 x 128 Carryless Multiply */
+    X = _mm_xor_si128(X, tmp1);
+    X = gfmul_shifted(X, H);
+    X = _mm_shuffle_epi8(X, BSWAP_MASK);
+    T = _mm_xor_si128(X, T);
+
+/*    if (0xffff !=
+           _mm_movemask_epi8(_mm_cmpeq_epi8(T, _mm_loadu_si128((__m128i*)tag)))) */
+    if (XMEMCMP(tag, &T, tbytes) != 0)
+        *res = 0; /* in case the authentication failed */
+    else
+        *res = 1; /* when successful returns 1 */
+}
+
+#endif /* HAVE_AES_DECRYPT */
+#endif /* _MSC_VER */
+#endif /* WOLFSSL_AESNI */
+
+
+#if defined(GCM_SMALL)
+static void GMULT(byte* X, byte* Y)
+{
+    byte Z[AES_BLOCK_SIZE];
+    byte V[AES_BLOCK_SIZE];
+    int i, j;
+
+    XMEMSET(Z, 0, AES_BLOCK_SIZE);
+    XMEMCPY(V, X, AES_BLOCK_SIZE);
+    for (i = 0; i < AES_BLOCK_SIZE; i++)
+    {
+        byte y = Y[i];
+        for (j = 0; j < 8; j++)
+        {
+            if (y & 0x80) {
+                xorbuf(Z, V, AES_BLOCK_SIZE);
+            }
+
+            RIGHTSHIFTX(V);
+            y = y << 1;
+        }
+    }
+    XMEMCPY(X, Z, AES_BLOCK_SIZE);
+}
+
+
+void GHASH(Aes* aes, const byte* a, word32 aSz, const byte* c,
+    word32 cSz, byte* s, word32 sSz)
+{
+    byte x[AES_BLOCK_SIZE];
+    byte scratch[AES_BLOCK_SIZE];
+    word32 blocks, partial;
+    byte* h = aes->H;
+
+    XMEMSET(x, 0, AES_BLOCK_SIZE);
+
+    /* Hash in A, the Additional Authentication Data */
+    if (aSz != 0 && a != NULL) {
+        blocks = aSz / AES_BLOCK_SIZE;
+        partial = aSz % AES_BLOCK_SIZE;
+        while (blocks--) {
+            xorbuf(x, a, AES_BLOCK_SIZE);
+            GMULT(x, h);
+            a += AES_BLOCK_SIZE;
+        }
+        if (partial != 0) {
+            XMEMSET(scratch, 0, AES_BLOCK_SIZE);
+            XMEMCPY(scratch, a, partial);
+            xorbuf(x, scratch, AES_BLOCK_SIZE);
+            GMULT(x, h);
+        }
+    }
+
+    /* Hash in C, the Ciphertext */
+    if (cSz != 0 && c != NULL) {
+        blocks = cSz / AES_BLOCK_SIZE;
+        partial = cSz % AES_BLOCK_SIZE;
+        while (blocks--) {
+            xorbuf(x, c, AES_BLOCK_SIZE);
+            GMULT(x, h);
+            c += AES_BLOCK_SIZE;
+        }
+        if (partial != 0) {
+            XMEMSET(scratch, 0, AES_BLOCK_SIZE);
+            XMEMCPY(scratch, c, partial);
+            xorbuf(x, scratch, AES_BLOCK_SIZE);
+            GMULT(x, h);
+        }
+    }
+
+    /* Hash in the lengths of A and C in bits */
+    FlattenSzInBits(&scratch[0], aSz);
+    FlattenSzInBits(&scratch[8], cSz);
+    xorbuf(x, scratch, AES_BLOCK_SIZE);
+    GMULT(x, h);
+
+    /* Copy the result into s. */
+    XMEMCPY(s, x, sSz);
+}
+
+/* end GCM_SMALL */
+#elif defined(GCM_TABLE)
+
+static const byte R[256][2] = {
+    {0x00, 0x00}, {0x01, 0xc2}, {0x03, 0x84}, {0x02, 0x46},
+    {0x07, 0x08}, {0x06, 0xca}, {0x04, 0x8c}, {0x05, 0x4e},
+    {0x0e, 0x10}, {0x0f, 0xd2}, {0x0d, 0x94}, {0x0c, 0x56},
+    {0x09, 0x18}, {0x08, 0xda}, {0x0a, 0x9c}, {0x0b, 0x5e},
+    {0x1c, 0x20}, {0x1d, 0xe2}, {0x1f, 0xa4}, {0x1e, 0x66},
+    {0x1b, 0x28}, {0x1a, 0xea}, {0x18, 0xac}, {0x19, 0x6e},
+    {0x12, 0x30}, {0x13, 0xf2}, {0x11, 0xb4}, {0x10, 0x76},
+    {0x15, 0x38}, {0x14, 0xfa}, {0x16, 0xbc}, {0x17, 0x7e},
+    {0x38, 0x40}, {0x39, 0x82}, {0x3b, 0xc4}, {0x3a, 0x06},
+    {0x3f, 0x48}, {0x3e, 0x8a}, {0x3c, 0xcc}, {0x3d, 0x0e},
+    {0x36, 0x50}, {0x37, 0x92}, {0x35, 0xd4}, {0x34, 0x16},
+    {0x31, 0x58}, {0x30, 0x9a}, {0x32, 0xdc}, {0x33, 0x1e},
+    {0x24, 0x60}, {0x25, 0xa2}, {0x27, 0xe4}, {0x26, 0x26},
+    {0x23, 0x68}, {0x22, 0xaa}, {0x20, 0xec}, {0x21, 0x2e},
+    {0x2a, 0x70}, {0x2b, 0xb2}, {0x29, 0xf4}, {0x28, 0x36},
+    {0x2d, 0x78}, {0x2c, 0xba}, {0x2e, 0xfc}, {0x2f, 0x3e},
+    {0x70, 0x80}, {0x71, 0x42}, {0x73, 0x04}, {0x72, 0xc6},
+    {0x77, 0x88}, {0x76, 0x4a}, {0x74, 0x0c}, {0x75, 0xce},
+    {0x7e, 0x90}, {0x7f, 0x52}, {0x7d, 0x14}, {0x7c, 0xd6},
+    {0x79, 0x98}, {0x78, 0x5a}, {0x7a, 0x1c}, {0x7b, 0xde},
+    {0x6c, 0xa0}, {0x6d, 0x62}, {0x6f, 0x24}, {0x6e, 0xe6},
+    {0x6b, 0xa8}, {0x6a, 0x6a}, {0x68, 0x2c}, {0x69, 0xee},
+    {0x62, 0xb0}, {0x63, 0x72}, {0x61, 0x34}, {0x60, 0xf6},
+    {0x65, 0xb8}, {0x64, 0x7a}, {0x66, 0x3c}, {0x67, 0xfe},
+    {0x48, 0xc0}, {0x49, 0x02}, {0x4b, 0x44}, {0x4a, 0x86},
+    {0x4f, 0xc8}, {0x4e, 0x0a}, {0x4c, 0x4c}, {0x4d, 0x8e},
+    {0x46, 0xd0}, {0x47, 0x12}, {0x45, 0x54}, {0x44, 0x96},
+    {0x41, 0xd8}, {0x40, 0x1a}, {0x42, 0x5c}, {0x43, 0x9e},
+    {0x54, 0xe0}, {0x55, 0x22}, {0x57, 0x64}, {0x56, 0xa6},
+    {0x53, 0xe8}, {0x52, 0x2a}, {0x50, 0x6c}, {0x51, 0xae},
+    {0x5a, 0xf0}, {0x5b, 0x32}, {0x59, 0x74}, {0x58, 0xb6},
+    {0x5d, 0xf8}, {0x5c, 0x3a}, {0x5e, 0x7c}, {0x5f, 0xbe},
+    {0xe1, 0x00}, {0xe0, 0xc2}, {0xe2, 0x84}, {0xe3, 0x46},
+    {0xe6, 0x08}, {0xe7, 0xca}, {0xe5, 0x8c}, {0xe4, 0x4e},
+    {0xef, 0x10}, {0xee, 0xd2}, {0xec, 0x94}, {0xed, 0x56},
+    {0xe8, 0x18}, {0xe9, 0xda}, {0xeb, 0x9c}, {0xea, 0x5e},
+    {0xfd, 0x20}, {0xfc, 0xe2}, {0xfe, 0xa4}, {0xff, 0x66},
+    {0xfa, 0x28}, {0xfb, 0xea}, {0xf9, 0xac}, {0xf8, 0x6e},
+    {0xf3, 0x30}, {0xf2, 0xf2}, {0xf0, 0xb4}, {0xf1, 0x76},
+    {0xf4, 0x38}, {0xf5, 0xfa}, {0xf7, 0xbc}, {0xf6, 0x7e},
+    {0xd9, 0x40}, {0xd8, 0x82}, {0xda, 0xc4}, {0xdb, 0x06},
+    {0xde, 0x48}, {0xdf, 0x8a}, {0xdd, 0xcc}, {0xdc, 0x0e},
+    {0xd7, 0x50}, {0xd6, 0x92}, {0xd4, 0xd4}, {0xd5, 0x16},
+    {0xd0, 0x58}, {0xd1, 0x9a}, {0xd3, 0xdc}, {0xd2, 0x1e},
+    {0xc5, 0x60}, {0xc4, 0xa2}, {0xc6, 0xe4}, {0xc7, 0x26},
+    {0xc2, 0x68}, {0xc3, 0xaa}, {0xc1, 0xec}, {0xc0, 0x2e},
+    {0xcb, 0x70}, {0xca, 0xb2}, {0xc8, 0xf4}, {0xc9, 0x36},
+    {0xcc, 0x78}, {0xcd, 0xba}, {0xcf, 0xfc}, {0xce, 0x3e},
+    {0x91, 0x80}, {0x90, 0x42}, {0x92, 0x04}, {0x93, 0xc6},
+    {0x96, 0x88}, {0x97, 0x4a}, {0x95, 0x0c}, {0x94, 0xce},
+    {0x9f, 0x90}, {0x9e, 0x52}, {0x9c, 0x14}, {0x9d, 0xd6},
+    {0x98, 0x98}, {0x99, 0x5a}, {0x9b, 0x1c}, {0x9a, 0xde},
+    {0x8d, 0xa0}, {0x8c, 0x62}, {0x8e, 0x24}, {0x8f, 0xe6},
+    {0x8a, 0xa8}, {0x8b, 0x6a}, {0x89, 0x2c}, {0x88, 0xee},
+    {0x83, 0xb0}, {0x82, 0x72}, {0x80, 0x34}, {0x81, 0xf6},
+    {0x84, 0xb8}, {0x85, 0x7a}, {0x87, 0x3c}, {0x86, 0xfe},
+    {0xa9, 0xc0}, {0xa8, 0x02}, {0xaa, 0x44}, {0xab, 0x86},
+    {0xae, 0xc8}, {0xaf, 0x0a}, {0xad, 0x4c}, {0xac, 0x8e},
+    {0xa7, 0xd0}, {0xa6, 0x12}, {0xa4, 0x54}, {0xa5, 0x96},
+    {0xa0, 0xd8}, {0xa1, 0x1a}, {0xa3, 0x5c}, {0xa2, 0x9e},
+    {0xb5, 0xe0}, {0xb4, 0x22}, {0xb6, 0x64}, {0xb7, 0xa6},
+    {0xb2, 0xe8}, {0xb3, 0x2a}, {0xb1, 0x6c}, {0xb0, 0xae},
+    {0xbb, 0xf0}, {0xba, 0x32}, {0xb8, 0x74}, {0xb9, 0xb6},
+    {0xbc, 0xf8}, {0xbd, 0x3a}, {0xbf, 0x7c}, {0xbe, 0xbe} };
+
+
+static void GMULT(byte *x, byte m[256][AES_BLOCK_SIZE])
+{
+    int i, j;
+    byte Z[AES_BLOCK_SIZE];
+    byte a;
+
+    XMEMSET(Z, 0, sizeof(Z));
+
+    for (i = 15; i > 0; i--) {
+        xorbuf(Z, m[x[i]], AES_BLOCK_SIZE);
+        a = Z[15];
+
+        for (j = 15; j > 0; j--) {
+            Z[j] = Z[j-1];
+        }
+
+        Z[0] = R[a][0];
+        Z[1] ^= R[a][1];
+    }
+    xorbuf(Z, m[x[0]], AES_BLOCK_SIZE);
+
+    XMEMCPY(x, Z, AES_BLOCK_SIZE);
+}
+
+
+void GHASH(Aes* aes, const byte* a, word32 aSz, const byte* c,
+    word32 cSz, byte* s, word32 sSz)
+{
+    byte x[AES_BLOCK_SIZE];
+    byte scratch[AES_BLOCK_SIZE];
+    word32 blocks, partial;
+
+    XMEMSET(x, 0, AES_BLOCK_SIZE);
+
+    /* Hash in A, the Additional Authentication Data */
+    if (aSz != 0 && a != NULL) {
+        blocks = aSz / AES_BLOCK_SIZE;
+        partial = aSz % AES_BLOCK_SIZE;
+        while (blocks--) {
+            xorbuf(x, a, AES_BLOCK_SIZE);
+            GMULT(x, aes->M0);
+            a += AES_BLOCK_SIZE;
+        }
+        if (partial != 0) {
+            XMEMSET(scratch, 0, AES_BLOCK_SIZE);
+            XMEMCPY(scratch, a, partial);
+            xorbuf(x, scratch, AES_BLOCK_SIZE);
+            GMULT(x, aes->M0);
+        }
+    }
+
+    /* Hash in C, the Ciphertext */
+    if (cSz != 0 && c != NULL) {
+        blocks = cSz / AES_BLOCK_SIZE;
+        partial = cSz % AES_BLOCK_SIZE;
+        while (blocks--) {
+            xorbuf(x, c, AES_BLOCK_SIZE);
+            GMULT(x, aes->M0);
+            c += AES_BLOCK_SIZE;
+        }
+        if (partial != 0) {
+            XMEMSET(scratch, 0, AES_BLOCK_SIZE);
+            XMEMCPY(scratch, c, partial);
+            xorbuf(x, scratch, AES_BLOCK_SIZE);
+            GMULT(x, aes->M0);
+        }
+    }
+
+    /* Hash in the lengths of A and C in bits */
+    FlattenSzInBits(&scratch[0], aSz);
+    FlattenSzInBits(&scratch[8], cSz);
+    xorbuf(x, scratch, AES_BLOCK_SIZE);
+    GMULT(x, aes->M0);
+
+    /* Copy the result into s. */
+    XMEMCPY(s, x, sSz);
+}
+
+/* end GCM_TABLE */
+#elif defined(WORD64_AVAILABLE) && !defined(GCM_WORD32)
+
+#if !defined(FREESCALE_LTC_AES_GCM)
+static void GMULT(word64* X, word64* Y)
+{
+    word64 Z[2] = {0,0};
+    word64 V[2];
+    int i, j;
+    V[0] = X[0];  V[1] = X[1];
+
+    for (i = 0; i < 2; i++)
+    {
+        word64 y = Y[i];
+        for (j = 0; j < 64; j++)
+        {
+            if (y & 0x8000000000000000ULL) {
+                Z[0] ^= V[0];
+                Z[1] ^= V[1];
+            }
+
+            if (V[1] & 0x0000000000000001) {
+                V[1] >>= 1;
+                V[1] |= ((V[0] & 0x0000000000000001) ?
+                    0x8000000000000000ULL : 0);
+                V[0] >>= 1;
+                V[0] ^= 0xE100000000000000ULL;
+            }
+            else {
+                V[1] >>= 1;
+                V[1] |= ((V[0] & 0x0000000000000001) ?
+                    0x8000000000000000ULL : 0);
+                V[0] >>= 1;
+            }
+            y <<= 1;
+        }
+    }
+    X[0] = Z[0];
+    X[1] = Z[1];
+}
+
+
+void GHASH(Aes* aes, const byte* a, word32 aSz, const byte* c,
+    word32 cSz, byte* s, word32 sSz)
+{
+    word64 x[2] = {0,0};
+    word32 blocks, partial;
+    word64 bigH[2];
+
+    XMEMCPY(bigH, aes->H, AES_BLOCK_SIZE);
+    #ifdef LITTLE_ENDIAN_ORDER
+        ByteReverseWords64(bigH, bigH, AES_BLOCK_SIZE);
+    #endif
+
+    /* Hash in A, the Additional Authentication Data */
+    if (aSz != 0 && a != NULL) {
+        word64 bigA[2];
+        blocks = aSz / AES_BLOCK_SIZE;
+        partial = aSz % AES_BLOCK_SIZE;
+        while (blocks--) {
+            XMEMCPY(bigA, a, AES_BLOCK_SIZE);
+            #ifdef LITTLE_ENDIAN_ORDER
+                ByteReverseWords64(bigA, bigA, AES_BLOCK_SIZE);
+            #endif
+            x[0] ^= bigA[0];
+            x[1] ^= bigA[1];
+            GMULT(x, bigH);
+            a += AES_BLOCK_SIZE;
+        }
+        if (partial != 0) {
+            XMEMSET(bigA, 0, AES_BLOCK_SIZE);
+            XMEMCPY(bigA, a, partial);
+            #ifdef LITTLE_ENDIAN_ORDER
+                ByteReverseWords64(bigA, bigA, AES_BLOCK_SIZE);
+            #endif
+            x[0] ^= bigA[0];
+            x[1] ^= bigA[1];
+            GMULT(x, bigH);
+        }
+#ifdef OPENSSL_EXTRA
+        /* store AAD partial tag for next call */
+        aes->aadH[0] = (word32)((x[0] & 0xFFFFFFFF00000000) >> 32);
+        aes->aadH[1] = (word32)(x[0] & 0xFFFFFFFF);
+        aes->aadH[2] = (word32)((x[1] & 0xFFFFFFFF00000000) >> 32);
+        aes->aadH[3] = (word32)(x[1] & 0xFFFFFFFF);
+#endif
+    }
+
+    /* Hash in C, the Ciphertext */
+    if (cSz != 0 && c != NULL) {
+        word64 bigC[2];
+        blocks = cSz / AES_BLOCK_SIZE;
+        partial = cSz % AES_BLOCK_SIZE;
+#ifdef OPENSSL_EXTRA
+        /* Start from last AAD partial tag */
+        if(aes->aadLen) {
+            x[0] = ((word64)aes->aadH[0]) << 32 | aes->aadH[1];
+            x[1] = ((word64)aes->aadH[2]) << 32 | aes->aadH[3];
+         }
+#endif
+        while (blocks--) {
+            XMEMCPY(bigC, c, AES_BLOCK_SIZE);
+            #ifdef LITTLE_ENDIAN_ORDER
+                ByteReverseWords64(bigC, bigC, AES_BLOCK_SIZE);
+            #endif
+            x[0] ^= bigC[0];
+            x[1] ^= bigC[1];
+            GMULT(x, bigH);
+            c += AES_BLOCK_SIZE;
+        }
+        if (partial != 0) {
+            XMEMSET(bigC, 0, AES_BLOCK_SIZE);
+            XMEMCPY(bigC, c, partial);
+            #ifdef LITTLE_ENDIAN_ORDER
+                ByteReverseWords64(bigC, bigC, AES_BLOCK_SIZE);
+            #endif
+            x[0] ^= bigC[0];
+            x[1] ^= bigC[1];
+            GMULT(x, bigH);
+        }
+    }
+
+    /* Hash in the lengths in bits of A and C */
+    {
+        word64 len[2];
+        len[0] = aSz; len[1] = cSz;
+#ifdef OPENSSL_EXTRA
+        if (aes->aadLen)
+            len[0] = (word64)aes->aadLen;
+#endif
+        /* Lengths are in bytes. Convert to bits. */
+        len[0] *= 8;
+        len[1] *= 8;
+
+        x[0] ^= len[0];
+        x[1] ^= len[1];
+        GMULT(x, bigH);
+    }
+    #ifdef LITTLE_ENDIAN_ORDER
+        ByteReverseWords64(x, x, AES_BLOCK_SIZE);
+    #endif
+    XMEMCPY(s, x, sSz);
+}
+#endif /* !FREESCALE_LTC_AES_GCM */
+
+/* end defined(WORD64_AVAILABLE) && !defined(GCM_WORD32) */
+#else /* GCM_WORD32 */
+
+static void GMULT(word32* X, word32* Y)
+{
+    word32 Z[4] = {0,0,0,0};
+    word32 V[4];
+    int i, j;
+
+    V[0] = X[0];  V[1] = X[1]; V[2] =  X[2]; V[3] =  X[3];
+
+    for (i = 0; i < 4; i++)
+    {
+        word32 y = Y[i];
+        for (j = 0; j < 32; j++)
+        {
+            if (y & 0x80000000) {
+                Z[0] ^= V[0];
+                Z[1] ^= V[1];
+                Z[2] ^= V[2];
+                Z[3] ^= V[3];
+            }
+
+            if (V[3] & 0x00000001) {
+                V[3] >>= 1;
+                V[3] |= ((V[2] & 0x00000001) ? 0x80000000 : 0);
+                V[2] >>= 1;
+                V[2] |= ((V[1] & 0x00000001) ? 0x80000000 : 0);
+                V[1] >>= 1;
+                V[1] |= ((V[0] & 0x00000001) ? 0x80000000 : 0);
+                V[0] >>= 1;
+                V[0] ^= 0xE1000000;
+            } else {
+                V[3] >>= 1;
+                V[3] |= ((V[2] & 0x00000001) ? 0x80000000 : 0);
+                V[2] >>= 1;
+                V[2] |= ((V[1] & 0x00000001) ? 0x80000000 : 0);
+                V[1] >>= 1;
+                V[1] |= ((V[0] & 0x00000001) ? 0x80000000 : 0);
+                V[0] >>= 1;
+            }
+            y <<= 1;
+        }
+    }
+    X[0] = Z[0];
+    X[1] = Z[1];
+    X[2] = Z[2];
+    X[3] = Z[3];
+}
+
+
+void GHASH(Aes* aes, const byte* a, word32 aSz, const byte* c,
+    word32 cSz, byte* s, word32 sSz)
+{
+    word32 x[4] = {0,0,0,0};
+    word32 blocks, partial;
+    word32 bigH[4];
+
+    XMEMCPY(bigH, aes->H, AES_BLOCK_SIZE);
+    #ifdef LITTLE_ENDIAN_ORDER
+        ByteReverseWords(bigH, bigH, AES_BLOCK_SIZE);
+    #endif
+
+    /* Hash in A, the Additional Authentication Data */
+    if (aSz != 0 && a != NULL) {
+        word32 bigA[4];
+        blocks = aSz / AES_BLOCK_SIZE;
+        partial = aSz % AES_BLOCK_SIZE;
+        while (blocks--) {
+            XMEMCPY(bigA, a, AES_BLOCK_SIZE);
+            #ifdef LITTLE_ENDIAN_ORDER
+                ByteReverseWords(bigA, bigA, AES_BLOCK_SIZE);
+            #endif
+            x[0] ^= bigA[0];
+            x[1] ^= bigA[1];
+            x[2] ^= bigA[2];
+            x[3] ^= bigA[3];
+            GMULT(x, bigH);
+            a += AES_BLOCK_SIZE;
+        }
+        if (partial != 0) {
+            XMEMSET(bigA, 0, AES_BLOCK_SIZE);
+            XMEMCPY(bigA, a, partial);
+            #ifdef LITTLE_ENDIAN_ORDER
+                ByteReverseWords(bigA, bigA, AES_BLOCK_SIZE);
+            #endif
+            x[0] ^= bigA[0];
+            x[1] ^= bigA[1];
+            x[2] ^= bigA[2];
+            x[3] ^= bigA[3];
+            GMULT(x, bigH);
+        }
+    }
+
+    /* Hash in C, the Ciphertext */
+    if (cSz != 0 && c != NULL) {
+        word32 bigC[4];
+        blocks = cSz / AES_BLOCK_SIZE;
+        partial = cSz % AES_BLOCK_SIZE;
+        while (blocks--) {
+            XMEMCPY(bigC, c, AES_BLOCK_SIZE);
+            #ifdef LITTLE_ENDIAN_ORDER
+                ByteReverseWords(bigC, bigC, AES_BLOCK_SIZE);
+            #endif
+            x[0] ^= bigC[0];
+            x[1] ^= bigC[1];
+            x[2] ^= bigC[2];
+            x[3] ^= bigC[3];
+            GMULT(x, bigH);
+            c += AES_BLOCK_SIZE;
+        }
+        if (partial != 0) {
+            XMEMSET(bigC, 0, AES_BLOCK_SIZE);
+            XMEMCPY(bigC, c, partial);
+            #ifdef LITTLE_ENDIAN_ORDER
+                ByteReverseWords(bigC, bigC, AES_BLOCK_SIZE);
+            #endif
+            x[0] ^= bigC[0];
+            x[1] ^= bigC[1];
+            x[2] ^= bigC[2];
+            x[3] ^= bigC[3];
+            GMULT(x, bigH);
+        }
+    }
+
+    /* Hash in the lengths in bits of A and C */
+    {
+        word32 len[4];
+
+        /* Lengths are in bytes. Convert to bits. */
+        len[0] = (aSz >> (8*sizeof(aSz) - 3));
+        len[1] = aSz << 3;
+        len[2] = (cSz >> (8*sizeof(cSz) - 3));
+        len[3] = cSz << 3;
+
+        x[0] ^= len[0];
+        x[1] ^= len[1];
+        x[2] ^= len[2];
+        x[3] ^= len[3];
+        GMULT(x, bigH);
+    }
+    #ifdef LITTLE_ENDIAN_ORDER
+        ByteReverseWords(x, x, AES_BLOCK_SIZE);
+    #endif
+    XMEMCPY(s, x, sSz);
+}
+
+#endif /* end GCM_WORD32 */
+
+
+#if !defined(WOLFSSL_XILINX_CRYPT) && !defined(WOLFSSL_AFALG_XILINX_AES)
+#ifdef FREESCALE_LTC_AES_GCM
+int wc_AesGcmEncrypt(Aes* aes, byte* out, const byte* in, word32 sz,
+                   const byte* iv, word32 ivSz,
+                   byte* authTag, word32 authTagSz,
+                   const byte* authIn, word32 authInSz)
+{
+    status_t status;
+    word32 keySize;
+
+    /* argument checks */
+    if (aes == NULL || authTagSz > AES_BLOCK_SIZE || ivSz == 0) {
+        return BAD_FUNC_ARG;
+    }
+
+    if (authTagSz < WOLFSSL_MIN_AUTH_TAG_SZ) {
+        WOLFSSL_MSG("GcmEncrypt authTagSz too small error");
+        return BAD_FUNC_ARG;
+    }
+
+    status = wc_AesGetKeySize(aes, &keySize);
+    if (status)
+        return status;
+
+    status = LTC_AES_EncryptTagGcm(LTC_BASE, in, out, sz, iv, ivSz,
+        authIn, authInSz, (byte*)aes->key, keySize, authTag, authTagSz);
+
+    return (status == kStatus_Success) ? 0 : AES_GCM_AUTH_E;
+}
+
+#else
+
+#ifdef STM32_CRYPTO_AES_GCM
+
+/* this function supports inline encrypt */
+static int wc_AesGcmEncrypt_STM32(Aes* aes, byte* out, const byte* in, word32 sz,
+                                  const byte* iv, word32 ivSz,
+                                  byte* authTag, word32 authTagSz,
+                                  const byte* authIn, word32 authInSz)
+{
+    int ret;
+#ifdef WOLFSSL_STM32_CUBEMX
+    CRYP_HandleTypeDef hcryp;
+#else
+    word32 keyCopy[AES_256_KEY_SIZE/sizeof(word32)];
+#endif
+    word32 keySize;
+    int status = HAL_OK;
+    word32 blocks = sz / AES_BLOCK_SIZE;
+    word32 partial = sz % AES_BLOCK_SIZE;
+    byte tag[AES_BLOCK_SIZE];
+    byte partialBlock[AES_BLOCK_SIZE];
+    byte ctr[AES_BLOCK_SIZE];
+    byte* authInPadded = NULL;
+    int authPadSz;
+
+    ret = wc_AesGetKeySize(aes, &keySize);
+    if (ret != 0)
+        return ret;
+
+#ifdef WOLFSSL_STM32_CUBEMX
+    ret = wc_Stm32_Aes_Init(aes, &hcryp);
+    if (ret != 0)
+        return ret;
+#endif
+
+    ret = wolfSSL_CryptHwMutexLock();
+    if (ret != 0) {
+        return ret;
+    }
+
+    XMEMSET(ctr, 0, AES_BLOCK_SIZE);
+    if (ivSz == GCM_NONCE_MID_SZ) {
+        XMEMCPY(ctr, iv, ivSz);
+        ctr[AES_BLOCK_SIZE - 1] = 1;
+    }
+    else {
+        GHASH(aes, NULL, 0, iv, ivSz, ctr, AES_BLOCK_SIZE);
+    }
+    /* Hardware requires counter + 1 */
+    IncrementGcmCounter(ctr);
+
+    if (authInSz == 0 || (authInSz % AES_BLOCK_SIZE) != 0) {
+        /* Need to pad the AAD to a full block with zeros. */
+        authPadSz = ((authInSz / AES_BLOCK_SIZE) + 1) * AES_BLOCK_SIZE;
+        authInPadded = (byte*)XMALLOC(authPadSz, aes->heap,
+            DYNAMIC_TYPE_TMP_BUFFER);
+        if (authInPadded == NULL) {
+            wolfSSL_CryptHwMutexUnLock();
+            return MEMORY_E;
+        }
+        XMEMSET(authInPadded, 0, authPadSz);
+        XMEMCPY(authInPadded, authIn, authInSz);
+    } else {
+        authPadSz = authInSz;
+        authInPadded = (byte*)authIn;
+    }
+
+#ifdef WOLFSSL_STM32_CUBEMX
+    hcryp.Init.pInitVect = (STM_CRYPT_TYPE*)ctr;
+    hcryp.Init.Header = (STM_CRYPT_TYPE*)authInPadded;
+    hcryp.Init.HeaderSize = authInSz;
+
+#ifdef STM32_CRYPTO_AES_ONLY
+    /* Set the CRYP parameters */
+    hcryp.Init.ChainingMode  = CRYP_CHAINMODE_AES_GCM_GMAC;
+    hcryp.Init.OperatingMode = CRYP_ALGOMODE_ENCRYPT;
+    hcryp.Init.GCMCMACPhase  = CRYP_INIT_PHASE;
+    HAL_CRYP_Init(&hcryp);
+
+    /* GCM init phase */
+    status = HAL_CRYPEx_AES_Auth(&hcryp, NULL, 0, NULL, STM32_HAL_TIMEOUT);
+    if (status == HAL_OK) {
+        /* GCM header phase */
+        hcryp.Init.GCMCMACPhase  = CRYP_HEADER_PHASE;
+        status = HAL_CRYPEx_AES_Auth(&hcryp, NULL, 0, NULL, STM32_HAL_TIMEOUT);
+    }
+    if (status == HAL_OK) {
+        /* GCM payload phase - blocks */
+        hcryp.Init.GCMCMACPhase  = CRYP_PAYLOAD_PHASE;
+        if (blocks) {
+            status = HAL_CRYPEx_AES_Auth(&hcryp, (byte*)in,
+                (blocks * AES_BLOCK_SIZE), out, STM32_HAL_TIMEOUT);
+        }
+    }
+    if (status == HAL_OK && (partial != 0 || blocks == 0)) {
+        /* GCM payload phase - partial remainder */
+        XMEMSET(partialBlock, 0, sizeof(partialBlock));
+        XMEMCPY(partialBlock, in + (blocks * AES_BLOCK_SIZE), partial);
+        status = HAL_CRYPEx_AES_Auth(&hcryp, partialBlock, partial,
+            partialBlock, STM32_HAL_TIMEOUT);
+        XMEMCPY(out + (blocks * AES_BLOCK_SIZE), partialBlock, partial);
+    }
+    if (status == HAL_OK) {
+        /* GCM final phase */
+        hcryp.Init.GCMCMACPhase  = CRYP_FINAL_PHASE;
+        status = HAL_CRYPEx_AES_Auth(&hcryp, NULL, sz, tag, STM32_HAL_TIMEOUT);
+    }
+#elif defined(STM32_HAL_V2)
+    hcryp.Init.Algorithm  = CRYP_AES_GCM;
+    ByteReverseWords((word32*)partialBlock, (word32*)ctr, AES_BLOCK_SIZE);
+    hcryp.Init.pInitVect = (STM_CRYPT_TYPE*)partialBlock;
+    HAL_CRYP_Init(&hcryp);
+
+    /* GCM payload phase - can handle partial blocks */
+    status = HAL_CRYP_Encrypt(&hcryp, (uint32_t*)in,
+        (blocks * AES_BLOCK_SIZE) + partial, (uint32_t*)out, STM32_HAL_TIMEOUT);
+    if (status == HAL_OK) {
+        /* Compute the authTag */
+        status = HAL_CRYPEx_AESGCM_GenerateAuthTAG(&hcryp, (uint32_t*)tag,
+            STM32_HAL_TIMEOUT);
+    }
+#else
+    HAL_CRYP_Init(&hcryp);
+    if (blocks) {
+        /* GCM payload phase - blocks */
+        status = HAL_CRYPEx_AESGCM_Encrypt(&hcryp, (byte*)in,
+            (blocks * AES_BLOCK_SIZE), out, STM32_HAL_TIMEOUT);
+    }
+    if (status == HAL_OK && (partial != 0 || blocks == 0)) {
+        /* GCM payload phase - partial remainder */
+        XMEMSET(partialBlock, 0, sizeof(partialBlock));
+        XMEMCPY(partialBlock, in + (blocks * AES_BLOCK_SIZE), partial);
+        status = HAL_CRYPEx_AESGCM_Encrypt(&hcryp, partialBlock, partial,
+            partialBlock, STM32_HAL_TIMEOUT);
+        XMEMCPY(out + (blocks * AES_BLOCK_SIZE), partialBlock, partial);
+    }
+    if (status == HAL_OK) {
+        /* Compute the authTag */
+        status = HAL_CRYPEx_AESGCM_Finish(&hcryp, sz, tag, STM32_HAL_TIMEOUT);
+    }
+#endif
+
+    if (status != HAL_OK)
+        ret = AES_GCM_AUTH_E;
+    HAL_CRYP_DeInit(&hcryp);
+
+#else /* STD_PERI_LIB */
+    ByteReverseWords(keyCopy, (word32*)aes->key, keySize);
+    status = CRYP_AES_GCM(MODE_ENCRYPT, (uint8_t*)ctr,
+                         (uint8_t*)keyCopy,      keySize * 8,
+                         (uint8_t*)in,           sz,
+                         (uint8_t*)authInPadded, authInSz,
+                         (uint8_t*)out,          tag);
+    if (status != SUCCESS)
+        ret = AES_GCM_AUTH_E;
+#endif /* WOLFSSL_STM32_CUBEMX */
+
+    if (ret == 0) {
+        /* return authTag */
+        if (authTag) {
+            /* STM32 GCM won't compute Auth correctly for partial or
+                when IV != 12, so use software here */
+            if (sz == 0 || partial != 0 || ivSz != GCM_NONCE_MID_SZ) {
+                DecrementGcmCounter(ctr); /* hardware requires +1, so subtract it */
+                GHASH(aes, authIn, authInSz, out, sz, authTag, authTagSz);
+                wc_AesEncrypt(aes, ctr, tag);
+                xorbuf(authTag, tag, authTagSz);
+            }
+            else {
+                XMEMCPY(authTag, tag, authTagSz);
+            }
+        }
+    }
+
+    /* Free memory if not a multiple of AES_BLOCK_SZ */
+    if (authInPadded != authIn) {
+        XFREE(authInPadded, aes->heap, DYNAMIC_TYPE_TMP_BUFFER);
+    }
+
+    wolfSSL_CryptHwMutexUnLock();
+
+    return ret;
+}
+
+#endif /* STM32_CRYPTO_AES_GCM */
+
+#ifdef WOLFSSL_AESNI
+int AES_GCM_encrypt_C(Aes* aes, byte* out, const byte* in, word32 sz,
+                      const byte* iv, word32 ivSz,
+                      byte* authTag, word32 authTagSz,
+                      const byte* authIn, word32 authInSz);
+#else
+static
+#endif
+int AES_GCM_encrypt_C(Aes* aes, byte* out, const byte* in, word32 sz,
+                      const byte* iv, word32 ivSz,
+                      byte* authTag, word32 authTagSz,
+                      const byte* authIn, word32 authInSz)
+{
+    int ret = 0;
+    word32 blocks = sz / AES_BLOCK_SIZE;
+    word32 partial = sz % AES_BLOCK_SIZE;
+    const byte* p = in;
+    byte* c = out;
+    byte counter[AES_BLOCK_SIZE];
+    byte initialCounter[AES_BLOCK_SIZE];
+    byte *ctr;
+    byte scratch[AES_BLOCK_SIZE];
+#ifdef OPENSSL_EXTRA
+    word32 aadTemp;
+#endif
+    ctr = counter;
+    XMEMSET(initialCounter, 0, AES_BLOCK_SIZE);
+    XMEMSET(scratch, 0, AES_BLOCK_SIZE);
+    if (ivSz == GCM_NONCE_MID_SZ) {
+        XMEMCPY(initialCounter, iv, ivSz);
+        initialCounter[AES_BLOCK_SIZE - 1] = 1;
+    }
+    else {
+#ifdef OPENSSL_EXTRA
+        aadTemp = aes->aadLen;
+        aes->aadLen = 0;
+#endif
+        GHASH(aes, NULL, 0, iv, ivSz, initialCounter, AES_BLOCK_SIZE);
+#ifdef OPENSSL_EXTRA
+        aes->aadLen = aadTemp;
+#endif
+    }
+    XMEMCPY(ctr, initialCounter, AES_BLOCK_SIZE);
+
+#ifdef WOLFSSL_PIC32MZ_CRYPT
+    if (blocks) {
+        /* use initial IV for HW, but don't use it below */
+        XMEMCPY(aes->reg, ctr, AES_BLOCK_SIZE);
+
+        ret = wc_Pic32AesCrypt(
+            aes->key, aes->keylen, aes->reg, AES_BLOCK_SIZE,
+            out, in, (blocks * AES_BLOCK_SIZE),
+            PIC32_ENCRYPTION, PIC32_ALGO_AES, PIC32_CRYPTOALGO_AES_GCM);
+        if (ret != 0)
+            return ret;
+    }
+    /* process remainder using partial handling */
+#endif
+
+#if defined(HAVE_AES_ECB) && !defined(WOLFSSL_PIC32MZ_CRYPT)
+    /* some hardware acceleration can gain performance from doing AES encryption
+     * of the whole buffer at once */
+    if (c != p && blocks > 0) { /* can not handle inline encryption */
+        while (blocks--) {
+            IncrementGcmCounter(ctr);
+            XMEMCPY(c, ctr, AES_BLOCK_SIZE);
+            c += AES_BLOCK_SIZE;
+        }
+
+        /* reset number of blocks and then do encryption */
+        blocks = sz / AES_BLOCK_SIZE;
+        wc_AesEcbEncrypt(aes, out, out, AES_BLOCK_SIZE * blocks);
+        xorbuf(out, p, AES_BLOCK_SIZE * blocks);
+        p += AES_BLOCK_SIZE * blocks;
+    }
+    else
+#endif /* HAVE_AES_ECB && !WOLFSSL_PIC32MZ_CRYPT */
+
+    while (blocks--) {
+        IncrementGcmCounter(ctr);
+    #if !defined(WOLFSSL_PIC32MZ_CRYPT)
+        wc_AesEncrypt(aes, ctr, scratch);
+        xorbuf(scratch, p, AES_BLOCK_SIZE);
+        XMEMCPY(c, scratch, AES_BLOCK_SIZE);
+    #endif
+        p += AES_BLOCK_SIZE;
+        c += AES_BLOCK_SIZE;
+    }
+
+    if (partial != 0) {
+        IncrementGcmCounter(ctr);
+        wc_AesEncrypt(aes, ctr, scratch);
+        xorbuf(scratch, p, partial);
+        XMEMCPY(c, scratch, partial);
+    }
+    if (authTag) {
+        GHASH(aes, authIn, authInSz, out, sz, authTag, authTagSz);
+        wc_AesEncrypt(aes, initialCounter, scratch);
+        xorbuf(authTag, scratch, authTagSz);
+#ifdef OPENSSL_EXTRA
+        if (!in && !sz)
+            /* store AAD size for next call */
+            aes->aadLen = authInSz;
+#endif
+    }
+
+    return ret;
+}
+
+/* Software AES - GCM Encrypt */
+int wc_AesGcmEncrypt(Aes* aes, byte* out, const byte* in, word32 sz,
+                   const byte* iv, word32 ivSz,
+                   byte* authTag, word32 authTagSz,
+                   const byte* authIn, word32 authInSz)
+{
+    /* argument checks */
+    if (aes == NULL || authTagSz > AES_BLOCK_SIZE || ivSz == 0) {
+        return BAD_FUNC_ARG;
+    }
+
+    if (authTagSz < WOLFSSL_MIN_AUTH_TAG_SZ) {
+        WOLFSSL_MSG("GcmEncrypt authTagSz too small error");
+        return BAD_FUNC_ARG;
+    }
+
+#ifdef WOLF_CRYPTO_CB
+    if (aes->devId != INVALID_DEVID) {
+        int ret = wc_CryptoCb_AesGcmEncrypt(aes, out, in, sz, iv, ivSz,
+            authTag, authTagSz, authIn, authInSz);
+        if (ret != CRYPTOCB_UNAVAILABLE)
+            return ret;
+        /* fall-through when unavailable */
+    }
+#endif
+
+#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_AES)
+    /* if async and byte count above threshold */
+    /* only 12-byte IV is supported in HW */
+    if (aes->asyncDev.marker == WOLFSSL_ASYNC_MARKER_AES &&
+                    sz >= WC_ASYNC_THRESH_AES_GCM && ivSz == GCM_NONCE_MID_SZ) {
+    #if defined(HAVE_CAVIUM)
+        #ifdef HAVE_CAVIUM_V
+        if (authInSz == 20) { /* Nitrox V GCM is only working with 20 byte AAD */
+            return NitroxAesGcmEncrypt(aes, out, in, sz,
+                (const byte*)aes->devKey, aes->keylen, iv, ivSz,
+                authTag, authTagSz, authIn, authInSz);
+        }
+        #endif
+    #elif defined(HAVE_INTEL_QA)
+        return IntelQaSymAesGcmEncrypt(&aes->asyncDev, out, in, sz,
+            (const byte*)aes->devKey, aes->keylen, iv, ivSz,
+            authTag, authTagSz, authIn, authInSz);
+    #else /* WOLFSSL_ASYNC_CRYPT_TEST */
+        if (wc_AsyncTestInit(&aes->asyncDev, ASYNC_TEST_AES_GCM_ENCRYPT)) {
+            WC_ASYNC_TEST* testDev = &aes->asyncDev.test;
+            testDev->aes.aes = aes;
+            testDev->aes.out = out;
+            testDev->aes.in = in;
+            testDev->aes.sz = sz;
+            testDev->aes.iv = iv;
+            testDev->aes.ivSz = ivSz;
+            testDev->aes.authTag = authTag;
+            testDev->aes.authTagSz = authTagSz;
+            testDev->aes.authIn = authIn;
+            testDev->aes.authInSz = authInSz;
+            return WC_PENDING_E;
+        }
+    #endif
+    }
+#endif /* WOLFSSL_ASYNC_CRYPT */
+
+#ifdef STM32_CRYPTO_AES_GCM
+    /* The STM standard peripheral library API's doesn't support partial blocks */
+    #ifdef STD_PERI_LIB
+    if (partial == 0)
+    #endif
+    {
+        return wc_AesGcmEncrypt_STM32(
+            aes, out, in, sz, iv, ivSz,
+            authTag, authTagSz, authIn, authInSz);
+    }
+#endif /* STM32_CRYPTO_AES_GCM */
+
+#ifdef WOLFSSL_AESNI
+    #ifdef HAVE_INTEL_AVX2
+    if (IS_INTEL_AVX2(intel_flags)) {
+        AES_GCM_encrypt_avx2(in, out, authIn, iv, authTag, sz, authInSz, ivSz,
+                                 authTagSz, (const byte*)aes->key, aes->rounds);
+        return 0;
+    }
+    else
+    #endif
+    #ifdef HAVE_INTEL_AVX1
+    if (IS_INTEL_AVX1(intel_flags)) {
+        AES_GCM_encrypt_avx1(in, out, authIn, iv, authTag, sz, authInSz, ivSz,
+                                 authTagSz, (const byte*)aes->key, aes->rounds);
+        return 0;
+    }
+    else
+    #endif
+    if (haveAESNI) {
+        AES_GCM_encrypt(in, out, authIn, iv, authTag, sz, authInSz, ivSz,
+                                 authTagSz, (const byte*)aes->key, aes->rounds);
+        return 0;
+    }
+    else
+#endif
+    {
+        return AES_GCM_encrypt_C(aes, out, in, sz, iv, ivSz, authTag, authTagSz,
+                                                              authIn, authInSz);
+    }
+}
+#endif
+
+
+
+/* AES GCM Decrypt */
+#if defined(HAVE_AES_DECRYPT) || defined(HAVE_AESGCM_DECRYPT)
+#ifdef FREESCALE_LTC_AES_GCM
+int  wc_AesGcmDecrypt(Aes* aes, byte* out, const byte* in, word32 sz,
+                   const byte* iv, word32 ivSz,
+                   const byte* authTag, word32 authTagSz,
+                   const byte* authIn, word32 authInSz)
+{
+    int ret;
+    word32 keySize;
+    status_t status;
+
+    /* argument checks */
+    /* If the sz is non-zero, both in and out must be set. If sz is 0,
+     * in and out are don't cares, as this is is the GMAC case. */
+    if (aes == NULL || iv == NULL || (sz != 0 && (in == NULL || out == NULL)) ||
+        authTag == NULL || authTagSz > AES_BLOCK_SIZE || authTagSz == 0 ||
+        ivSz == 0) {
+
+        return BAD_FUNC_ARG;
+    }
+
+    ret = wc_AesGetKeySize(aes, &keySize);
+    if (ret != 0) {
+        return ret;
+    }
+
+    status = LTC_AES_DecryptTagGcm(LTC_BASE, in, out, sz, iv, ivSz,
+        authIn, authInSz, (byte*)aes->key, keySize, authTag, authTagSz);
+
+    return (status == kStatus_Success) ? 0 : AES_GCM_AUTH_E;
+}
+
+#else
+
+#ifdef STM32_CRYPTO_AES_GCM
+/* this function supports inline decrypt */
+static int wc_AesGcmDecrypt_STM32(Aes* aes, byte* out,
+                                  const byte* in, word32 sz,
+                                  const byte* iv, word32 ivSz,
+                                  const byte* authTag, word32 authTagSz,
+                                  const byte* authIn, word32 authInSz)
+{
+    int ret;
+#ifdef WOLFSSL_STM32_CUBEMX
+    CRYP_HandleTypeDef hcryp;
+#else
+    word32 keyCopy[AES_256_KEY_SIZE/sizeof(word32)];
+#endif
+    word32 keySize;
+    int status = HAL_OK;
+    word32 blocks = sz / AES_BLOCK_SIZE;
+    word32 partial = sz % AES_BLOCK_SIZE;
+    byte tag[AES_BLOCK_SIZE];
+    byte partialBlock[AES_BLOCK_SIZE];
+    byte ctr[AES_BLOCK_SIZE];
+    byte* authInPadded = NULL;
+    int authPadSz;
+
+    ret = wc_AesGetKeySize(aes, &keySize);
+    if (ret != 0)
+        return ret;
+
+#ifdef WOLFSSL_STM32_CUBEMX
+    ret = wc_Stm32_Aes_Init(aes, &hcryp);
+    if (ret != 0)
+        return ret;
+#endif
+
+    ret = wolfSSL_CryptHwMutexLock();
+    if (ret != 0) {
+        return ret;
+    }
+
+    XMEMSET(ctr, 0, AES_BLOCK_SIZE);
+    if (ivSz == GCM_NONCE_MID_SZ) {
+        XMEMCPY(ctr, iv, ivSz);
+        ctr[AES_BLOCK_SIZE - 1] = 1;
+    }
+    else {
+        GHASH(aes, NULL, 0, iv, ivSz, ctr, AES_BLOCK_SIZE);
+    }
+    /* Hardware requires counter + 1 */
+    IncrementGcmCounter(ctr);
+
+    if (authInSz == 0 || (authInSz % AES_BLOCK_SIZE) != 0) {
+        /* Need to pad the AAD to a full block with zeros. */
+        authPadSz = ((authInSz / AES_BLOCK_SIZE) + 1) * AES_BLOCK_SIZE;
+        authInPadded = (byte*)XMALLOC(authPadSz, aes->heap,
+            DYNAMIC_TYPE_TMP_BUFFER);
+        if (authInPadded == NULL) {
+            wolfSSL_CryptHwMutexUnLock();
+            return MEMORY_E;
+        }
+        XMEMSET(authInPadded, 0, authPadSz);
+        XMEMCPY(authInPadded, authIn, authInSz);
+    } else {
+        authPadSz = authInSz;
+        authInPadded = (byte*)authIn;
+    }
+
+#ifdef WOLFSSL_STM32_CUBEMX
+    hcryp.Init.pInitVect = (STM_CRYPT_TYPE*)ctr;
+    hcryp.Init.Header = (STM_CRYPT_TYPE*)authInPadded;
+    hcryp.Init.HeaderSize = authInSz;
+
+#ifdef STM32_CRYPTO_AES_ONLY
+    /* Set the CRYP parameters */
+    hcryp.Init.ChainingMode  = CRYP_CHAINMODE_AES_GCM_GMAC;
+    hcryp.Init.OperatingMode = CRYP_ALGOMODE_DECRYPT;
+    hcryp.Init.GCMCMACPhase  = CRYP_INIT_PHASE;
+    HAL_CRYP_Init(&hcryp);
+
+    /* GCM init phase */
+    status = HAL_CRYPEx_AES_Auth(&hcryp, NULL, 0, NULL, STM32_HAL_TIMEOUT);
+    if (status == HAL_OK) {
+        /* GCM header phase */
+        hcryp.Init.GCMCMACPhase = CRYP_HEADER_PHASE;
+        status = HAL_CRYPEx_AES_Auth(&hcryp, NULL, 0, NULL, STM32_HAL_TIMEOUT);
+    }
+    if (status == HAL_OK) {
+        /* GCM payload phase - blocks */
+        hcryp.Init.GCMCMACPhase  = CRYP_PAYLOAD_PHASE;
+        if (blocks) {
+            status = HAL_CRYPEx_AES_Auth(&hcryp, (byte*)in,
+                (blocks * AES_BLOCK_SIZE), out, STM32_HAL_TIMEOUT);
+        }
+    }
+    if (status == HAL_OK && (partial != 0 || blocks == 0)) {
+        /* GCM payload phase - partial remainder */
+        XMEMSET(partialBlock, 0, sizeof(partialBlock));
+        XMEMCPY(partialBlock, in + (blocks * AES_BLOCK_SIZE), partial);
+        status = HAL_CRYPEx_AES_Auth(&hcryp, partialBlock, partial,
+            partialBlock, STM32_HAL_TIMEOUT);
+        XMEMCPY(out + (blocks * AES_BLOCK_SIZE), partialBlock, partial);
+    }
+    if (status == HAL_OK) {
+        /* GCM final phase */
+        hcryp.Init.GCMCMACPhase = CRYP_FINAL_PHASE;
+        status = HAL_CRYPEx_AES_Auth(&hcryp, NULL, sz, tag, STM32_HAL_TIMEOUT);
+    }
+#elif defined(STM32_HAL_V2)
+    hcryp.Init.Algorithm = CRYP_AES_GCM;
+    ByteReverseWords((word32*)partialBlock, (word32*)ctr, AES_BLOCK_SIZE);
+    hcryp.Init.pInitVect = (STM_CRYPT_TYPE*)partialBlock;
+    HAL_CRYP_Init(&hcryp);
+
+    /* GCM payload phase - can handle partial blocks */
+    status = HAL_CRYP_Decrypt(&hcryp, (uint32_t*)in,
+        (blocks * AES_BLOCK_SIZE) + partial, (uint32_t*)out, STM32_HAL_TIMEOUT);
+    if (status == HAL_OK) {
+        /* Compute the authTag */
+        status = HAL_CRYPEx_AESGCM_GenerateAuthTAG(&hcryp, (uint32_t*)tag,
+            STM32_HAL_TIMEOUT);
+    }
+#else
+    HAL_CRYP_Init(&hcryp);
+    if (blocks) {
+        /* GCM payload phase - blocks */
+        status = HAL_CRYPEx_AESGCM_Decrypt(&hcryp, (byte*)in,
+            (blocks * AES_BLOCK_SIZE), out, STM32_HAL_TIMEOUT);
+    }
+    if (status == HAL_OK && (partial != 0 || blocks == 0)) {
+        /* GCM payload phase - partial remainder */
+        XMEMSET(partialBlock, 0, sizeof(partialBlock));
+        XMEMCPY(partialBlock, in + (blocks * AES_BLOCK_SIZE), partial);
+        status = HAL_CRYPEx_AESGCM_Decrypt(&hcryp, partialBlock, partial,
+            partialBlock, STM32_HAL_TIMEOUT);
+        XMEMCPY(out + (blocks * AES_BLOCK_SIZE), partialBlock, partial);
+    }
+    if (status == HAL_OK) {
+        /* Compute the authTag */
+        status = HAL_CRYPEx_AESGCM_Finish(&hcryp, sz, tag, STM32_HAL_TIMEOUT);
+    }
+#endif
+
+    if (status != HAL_OK)
+        ret = AES_GCM_AUTH_E;
+
+    HAL_CRYP_DeInit(&hcryp);
+
+#else /* STD_PERI_LIB */
+    ByteReverseWords(keyCopy, (word32*)aes->key, aes->keylen);
+
+    /* Input size and auth size need to be the actual sizes, even though
+     * they are not block aligned, because this length (in bits) is used
+     * in the final GHASH. */
+    status = CRYP_AES_GCM(MODE_DECRYPT, (uint8_t*)ctr,
+                         (uint8_t*)keyCopy,      keySize * 8,
+                         (uint8_t*)in,           sz,
+                         (uint8_t*)authInPadded, authInSz,
+                         (uint8_t*)out,          tag);
+    if (status != SUCCESS)
+        ret = AES_GCM_AUTH_E;
+#endif /* WOLFSSL_STM32_CUBEMX */
+
+    /* STM32 GCM hardware only supports IV of 12 bytes, so use software for auth */
+    if (sz == 0 || ivSz != GCM_NONCE_MID_SZ) {
+        DecrementGcmCounter(ctr); /* hardware requires +1, so subtract it */
+        GHASH(aes, authIn, authInSz, in, sz, tag, sizeof(tag));
+        wc_AesEncrypt(aes, ctr, partialBlock);
+        xorbuf(tag, partialBlock, sizeof(tag));
+    }
+
+    if (ConstantCompare(authTag, tag, authTagSz) != 0) {
+        ret = AES_GCM_AUTH_E;
+    }
+
+    /* Free memory if not a multiple of AES_BLOCK_SZ */
+    if (authInPadded != authIn) {
+        XFREE(authInPadded, aes->heap, DYNAMIC_TYPE_TMP_BUFFER);
+    }
+
+    wolfSSL_CryptHwMutexUnLock();
+
+    return ret;
+}
+
+#endif /* STM32_CRYPTO_AES_GCM */
+
+#ifdef WOLFSSL_AESNI
+int AES_GCM_decrypt_C(Aes* aes, byte* out, const byte* in, word32 sz,
+                      const byte* iv, word32 ivSz,
+                      const byte* authTag, word32 authTagSz,
+                      const byte* authIn, word32 authInSz);
+#else
+static
+#endif
+int AES_GCM_decrypt_C(Aes* aes, byte* out, const byte* in, word32 sz,
+                      const byte* iv, word32 ivSz,
+                      const byte* authTag, word32 authTagSz,
+                      const byte* authIn, word32 authInSz)
+{
+    int ret = 0;
+    word32 blocks = sz / AES_BLOCK_SIZE;
+    word32 partial = sz % AES_BLOCK_SIZE;
+    const byte* c = in;
+    byte* p = out;
+    byte counter[AES_BLOCK_SIZE];
+    byte initialCounter[AES_BLOCK_SIZE];
+    byte *ctr;
+    byte scratch[AES_BLOCK_SIZE];
+    byte Tprime[AES_BLOCK_SIZE];
+    byte EKY0[AES_BLOCK_SIZE];
+#ifdef OPENSSL_EXTRA
+    word32 aadTemp;
+#endif
+    ctr = counter;
+    XMEMSET(initialCounter, 0, AES_BLOCK_SIZE);
+    if (ivSz == GCM_NONCE_MID_SZ) {
+        XMEMCPY(initialCounter, iv, ivSz);
+        initialCounter[AES_BLOCK_SIZE - 1] = 1;
+    }
+    else {
+#ifdef OPENSSL_EXTRA
+        aadTemp = aes->aadLen;
+        aes->aadLen = 0;
+#endif
+        GHASH(aes, NULL, 0, iv, ivSz, initialCounter, AES_BLOCK_SIZE);
+#ifdef OPENSSL_EXTRA
+        aes->aadLen = aadTemp;
+#endif
+    }
+    XMEMCPY(ctr, initialCounter, AES_BLOCK_SIZE);
+
+    /* Calc the authTag again using the received auth data and the cipher text */
+    GHASH(aes, authIn, authInSz, in, sz, Tprime, sizeof(Tprime));
+    wc_AesEncrypt(aes, ctr, EKY0);
+    xorbuf(Tprime, EKY0, sizeof(Tprime));
+
+#ifdef OPENSSL_EXTRA
+    if (!out) {
+        /* authenticated, non-confidential data */
+        /* store AAD size for next call */
+        aes->aadLen = authInSz;
+    }
+#endif
+    if (ConstantCompare(authTag, Tprime, authTagSz) != 0) {
+        return AES_GCM_AUTH_E;
+    }
+
+#if defined(WOLFSSL_PIC32MZ_CRYPT)
+    if (blocks) {
+        /* use initial IV for HW, but don't use it below */
+        XMEMCPY(aes->reg, ctr, AES_BLOCK_SIZE);
+
+        ret = wc_Pic32AesCrypt(
+            aes->key, aes->keylen, aes->reg, AES_BLOCK_SIZE,
+            out, in, (blocks * AES_BLOCK_SIZE),
+            PIC32_DECRYPTION, PIC32_ALGO_AES, PIC32_CRYPTOALGO_AES_GCM);
+        if (ret != 0)
+            return ret;
+    }
+    /* process remainder using partial handling */
+#endif
+
+#if defined(HAVE_AES_ECB) && !defined(WOLFSSL_PIC32MZ_CRYPT)
+    /* some hardware acceleration can gain performance from doing AES encryption
+     * of the whole buffer at once */
+    if (c != p && blocks > 0) { /* can not handle inline decryption */
+        while (blocks--) {
+            IncrementGcmCounter(ctr);
+            XMEMCPY(p, ctr, AES_BLOCK_SIZE);
+            p += AES_BLOCK_SIZE;
+        }
+
+        /* reset number of blocks and then do encryption */
+        blocks = sz / AES_BLOCK_SIZE;
+
+        wc_AesEcbEncrypt(aes, out, out, AES_BLOCK_SIZE * blocks);
+        xorbuf(out, c, AES_BLOCK_SIZE * blocks);
+        c += AES_BLOCK_SIZE * blocks;
+    }
+    else
+#endif /* HAVE_AES_ECB && !PIC32MZ */
+    while (blocks--) {
+        IncrementGcmCounter(ctr);
+    #if !defined(WOLFSSL_PIC32MZ_CRYPT)
+        wc_AesEncrypt(aes, ctr, scratch);
+        xorbuf(scratch, c, AES_BLOCK_SIZE);
+        XMEMCPY(p, scratch, AES_BLOCK_SIZE);
+    #endif
+        p += AES_BLOCK_SIZE;
+        c += AES_BLOCK_SIZE;
+    }
+
+    if (partial != 0) {
+        IncrementGcmCounter(ctr);
+        wc_AesEncrypt(aes, ctr, scratch);
+        xorbuf(scratch, c, partial);
+        XMEMCPY(p, scratch, partial);
+    }
+
+    return ret;
+}
+
+/* Software AES - GCM Decrypt */
+int wc_AesGcmDecrypt(Aes* aes, byte* out, const byte* in, word32 sz,
+                     const byte* iv, word32 ivSz,
+                     const byte* authTag, word32 authTagSz,
+                     const byte* authIn, word32 authInSz)
+{
+#ifdef WOLFSSL_AESNI
+    int res = AES_GCM_AUTH_E;
+#endif
+
+    /* argument checks */
+    /* If the sz is non-zero, both in and out must be set. If sz is 0,
+     * in and out are don't cares, as this is is the GMAC case. */
+    if (aes == NULL || iv == NULL || (sz != 0 && (in == NULL || out == NULL)) ||
+        authTag == NULL || authTagSz > AES_BLOCK_SIZE || authTagSz == 0 ||
+        ivSz == 0) {
+
+        return BAD_FUNC_ARG;
+    }
+
+#ifdef WOLF_CRYPTO_CB
+    if (aes->devId != INVALID_DEVID) {
+        int ret = wc_CryptoCb_AesGcmDecrypt(aes, out, in, sz, iv, ivSz,
+            authTag, authTagSz, authIn, authInSz);
+        if (ret != CRYPTOCB_UNAVAILABLE)
+            return ret;
+        /* fall-through when unavailable */
+    }
+#endif
+
+#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_AES)
+    /* if async and byte count above threshold */
+    /* only 12-byte IV is supported in HW */
+    if (aes->asyncDev.marker == WOLFSSL_ASYNC_MARKER_AES &&
+                    sz >= WC_ASYNC_THRESH_AES_GCM && ivSz == GCM_NONCE_MID_SZ) {
+    #if defined(HAVE_CAVIUM)
+        #ifdef HAVE_CAVIUM_V
+        if (authInSz == 20) { /* Nitrox V GCM is only working with 20 byte AAD */
+            return NitroxAesGcmDecrypt(aes, out, in, sz,
+                (const byte*)aes->devKey, aes->keylen, iv, ivSz,
+                authTag, authTagSz, authIn, authInSz);
+        }
+        #endif
+    #elif defined(HAVE_INTEL_QA)
+        return IntelQaSymAesGcmDecrypt(&aes->asyncDev, out, in, sz,
+            (const byte*)aes->devKey, aes->keylen, iv, ivSz,
+            authTag, authTagSz, authIn, authInSz);
+    #else /* WOLFSSL_ASYNC_CRYPT_TEST */
+        if (wc_AsyncTestInit(&aes->asyncDev, ASYNC_TEST_AES_GCM_DECRYPT)) {
+            WC_ASYNC_TEST* testDev = &aes->asyncDev.test;
+            testDev->aes.aes = aes;
+            testDev->aes.out = out;
+            testDev->aes.in = in;
+            testDev->aes.sz = sz;
+            testDev->aes.iv = iv;
+            testDev->aes.ivSz = ivSz;
+            testDev->aes.authTag = (byte*)authTag;
+            testDev->aes.authTagSz = authTagSz;
+            testDev->aes.authIn = authIn;
+            testDev->aes.authInSz = authInSz;
+            return WC_PENDING_E;
+        }
+    #endif
+    }
+#endif /* WOLFSSL_ASYNC_CRYPT */
+
+#ifdef STM32_CRYPTO_AES_GCM
+    /* The STM standard peripheral library API's doesn't support partial blocks */
+    #ifdef STD_PERI_LIB
+    if (partial == 0)
+    #endif
+    {
+        return wc_AesGcmDecrypt_STM32(
+            aes, out, in, sz, iv, ivSz,
+            authTag, authTagSz, authIn, authInSz);
+    }
+#endif /* STM32_CRYPTO_AES_GCM */
+
+#ifdef WOLFSSL_AESNI
+    #ifdef HAVE_INTEL_AVX2
+    if (IS_INTEL_AVX2(intel_flags)) {
+        AES_GCM_decrypt_avx2(in, out, authIn, iv, authTag, sz, authInSz, ivSz,
+                                 authTagSz, (byte*)aes->key, aes->rounds, &res);
+        if (res == 0)
+            return AES_GCM_AUTH_E;
+        return 0;
+    }
+    else
+    #endif
+    #ifdef HAVE_INTEL_AVX1
+    if (IS_INTEL_AVX1(intel_flags)) {
+        AES_GCM_decrypt_avx1(in, out, authIn, iv, authTag, sz, authInSz, ivSz,
+                                 authTagSz, (byte*)aes->key, aes->rounds, &res);
+        if (res == 0)
+            return AES_GCM_AUTH_E;
+        return 0;
+    }
+    else
+    #endif
+    if (haveAESNI) {
+        AES_GCM_decrypt(in, out, authIn, iv, authTag, sz, authInSz, ivSz,
+                                 authTagSz, (byte*)aes->key, aes->rounds, &res);
+        if (res == 0)
+            return AES_GCM_AUTH_E;
+        return 0;
+    }
+    else
+#endif
+    {
+        return AES_GCM_decrypt_C(aes, out, in, sz, iv, ivSz, authTag, authTagSz,
+                                                              authIn, authInSz);
+    }
+}
+#endif
+#endif /* HAVE_AES_DECRYPT || HAVE_AESGCM_DECRYPT */
+#endif /* WOLFSSL_XILINX_CRYPT */
+#endif /* end of block for AESGCM implementation selection */
+
+
+/* Common to all, abstract functions that build off of lower level AESGCM
+ * functions */
+#ifndef WC_NO_RNG
+
+int wc_AesGcmSetExtIV(Aes* aes, const byte* iv, word32 ivSz)
+{
+    int ret = 0;
+
+    if (aes == NULL || iv == NULL ||
+        (ivSz != GCM_NONCE_MIN_SZ && ivSz != GCM_NONCE_MID_SZ &&
+         ivSz != GCM_NONCE_MAX_SZ)) {
+
+        ret = BAD_FUNC_ARG;
+    }
+
+    if (ret == 0) {
+        XMEMCPY((byte*)aes->reg, iv, ivSz);
+
+        /* If the IV is 96, allow for a 2^64 invocation counter.
+         * For any other size for the nonce, limit the invocation
+         * counter to 32-bits. (SP 800-38D 8.3) */
+        aes->invokeCtr[0] = 0;
+        aes->invokeCtr[1] = (ivSz == GCM_NONCE_MID_SZ) ? 0 : 0xFFFFFFFF;
+        aes->nonceSz = ivSz;
+    }
+
+    return ret;
+}
+
+
+int wc_AesGcmSetIV(Aes* aes, word32 ivSz,
+                   const byte* ivFixed, word32 ivFixedSz,
+                   WC_RNG* rng)
+{
+    int ret = 0;
+
+    if (aes == NULL || rng == NULL ||
+        (ivSz != GCM_NONCE_MIN_SZ && ivSz != GCM_NONCE_MID_SZ &&
+         ivSz != GCM_NONCE_MAX_SZ) ||
+        (ivFixed == NULL && ivFixedSz != 0) ||
+        (ivFixed != NULL && ivFixedSz != AES_IV_FIXED_SZ)) {
+
+        ret = BAD_FUNC_ARG;
+    }
+
+    if (ret == 0) {
+        byte* iv = (byte*)aes->reg;
+
+        if (ivFixedSz)
+            XMEMCPY(iv, ivFixed, ivFixedSz);
+
+        ret = wc_RNG_GenerateBlock(rng, iv + ivFixedSz, ivSz - ivFixedSz);
+    }
+
+    if (ret == 0) {
+        /* If the IV is 96, allow for a 2^64 invocation counter.
+         * For any other size for the nonce, limit the invocation
+         * counter to 32-bits. (SP 800-38D 8.3) */
+        aes->invokeCtr[0] = 0;
+        aes->invokeCtr[1] = (ivSz == GCM_NONCE_MID_SZ) ? 0 : 0xFFFFFFFF;
+        aes->nonceSz = ivSz;
+    }
+
+    return ret;
+}
+
+
+int wc_AesGcmEncrypt_ex(Aes* aes, byte* out, const byte* in, word32 sz,
+                        byte* ivOut, word32 ivOutSz,
+                        byte* authTag, word32 authTagSz,
+                        const byte* authIn, word32 authInSz)
+{
+    int ret = 0;
+
+    if (aes == NULL || (sz != 0 && (in == NULL || out == NULL)) ||
+        ivOut == NULL || ivOutSz != aes->nonceSz ||
+        (authIn == NULL && authInSz != 0)) {
+
+        ret = BAD_FUNC_ARG;
+    }
+
+    if (ret == 0) {
+        aes->invokeCtr[0]++;
+        if (aes->invokeCtr[0] == 0) {
+            aes->invokeCtr[1]++;
+            if (aes->invokeCtr[1] == 0)
+                ret = AES_GCM_OVERFLOW_E;
+        }
+    }
+
+    if (ret == 0) {
+        XMEMCPY(ivOut, aes->reg, ivOutSz);
+        ret = wc_AesGcmEncrypt(aes, out, in, sz,
+                               (byte*)aes->reg, ivOutSz,
+                               authTag, authTagSz,
+                               authIn, authInSz);
+        if (ret == 0)
+            IncCtr((byte*)aes->reg, ivOutSz);
+    }
+
+    return ret;
+}
+
+int wc_Gmac(const byte* key, word32 keySz, byte* iv, word32 ivSz,
+            const byte* authIn, word32 authInSz,
+            byte* authTag, word32 authTagSz, WC_RNG* rng)
+{
+    Aes aes;
+    int ret;
+
+    if (key == NULL || iv == NULL || (authIn == NULL && authInSz != 0) ||
+        authTag == NULL || authTagSz == 0 || rng == NULL) {
+
+        return BAD_FUNC_ARG;
+    }
+
+    ret = wc_AesInit(&aes, NULL, INVALID_DEVID);
+    if (ret == 0) {
+        ret = wc_AesGcmSetKey(&aes, key, keySz);
+        if (ret == 0)
+            ret = wc_AesGcmSetIV(&aes, ivSz, NULL, 0, rng);
+        if (ret == 0)
+            ret = wc_AesGcmEncrypt_ex(&aes, NULL, NULL, 0, iv, ivSz,
+                                  authTag, authTagSz, authIn, authInSz);
+        wc_AesFree(&aes);
+    }
+    ForceZero(&aes, sizeof(aes));
+
+    return ret;
+}
+
+int wc_GmacVerify(const byte* key, word32 keySz,
+                  const byte* iv, word32 ivSz,
+                  const byte* authIn, word32 authInSz,
+                  const byte* authTag, word32 authTagSz)
+{
+    int ret;
+#ifndef NO_AES_DECRYPT
+    Aes aes;
+
+    if (key == NULL || iv == NULL || (authIn == NULL && authInSz != 0) ||
+        authTag == NULL || authTagSz == 0 || authTagSz > AES_BLOCK_SIZE) {
+
+        return BAD_FUNC_ARG;
+    }
+
+    ret = wc_AesInit(&aes, NULL, INVALID_DEVID);
+    if (ret == 0) {
+        ret = wc_AesGcmSetKey(&aes, key, keySz);
+        if (ret == 0)
+            ret = wc_AesGcmDecrypt(&aes, NULL, NULL, 0, iv, ivSz,
+                                  authTag, authTagSz, authIn, authInSz);
+        wc_AesFree(&aes);
+    }
+    ForceZero(&aes, sizeof(aes));
+#else
+    (void)key;
+    (void)keySz;
+    (void)iv;
+    (void)ivSz;
+    (void)authIn;
+    (void)authInSz;
+    (void)authTag;
+    (void)authTagSz;
+    ret = NOT_COMPILED_IN;
+#endif
+    return ret;
+}
+
+#endif /* WC_NO_RNG */
+
+
+WOLFSSL_API int wc_GmacSetKey(Gmac* gmac, const byte* key, word32 len)
+{
+    if (gmac == NULL || key == NULL) {
+        return BAD_FUNC_ARG;
+    }
+    return wc_AesGcmSetKey(&gmac->aes, key, len);
+}
+
+
+WOLFSSL_API int wc_GmacUpdate(Gmac* gmac, const byte* iv, word32 ivSz,
+                              const byte* authIn, word32 authInSz,
+                              byte* authTag, word32 authTagSz)
+{
+    return wc_AesGcmEncrypt(&gmac->aes, NULL, NULL, 0, iv, ivSz,
+                                         authTag, authTagSz, authIn, authInSz);
+}
+
+#endif /* HAVE_AESGCM */
+
+
+#ifdef HAVE_AESCCM
+
+int wc_AesCcmSetKey(Aes* aes, const byte* key, word32 keySz)
+{
+    if (!((keySz == 16) || (keySz == 24) || (keySz == 32)))
+        return BAD_FUNC_ARG;
+
+    return wc_AesSetKey(aes, key, keySz, NULL, AES_ENCRYPTION);
+}
+
+#ifdef WOLFSSL_ARMASM
+    /* implementation located in wolfcrypt/src/port/arm/armv8-aes.c */
+
+#elif defined(HAVE_COLDFIRE_SEC)
+    #error "Coldfire SEC doesn't currently support AES-CCM mode"
+
+#elif defined(WOLFSSL_IMX6_CAAM) && !defined(NO_IMX6_CAAM_AES)
+    /* implemented in wolfcrypt/src/port/caam_aes.c */
+
+#elif defined(FREESCALE_LTC)
+
+/* return 0 on success */
+int wc_AesCcmEncrypt(Aes* aes, byte* out, const byte* in, word32 inSz,
+                   const byte* nonce, word32 nonceSz,
+                   byte* authTag, word32 authTagSz,
+                   const byte* authIn, word32 authInSz)
+{
+    byte *key;
+    uint32_t keySize;
+    status_t status;
+
+    /* sanity check on arguments */
+    if (aes == NULL || out == NULL || in == NULL || nonce == NULL
+            || authTag == NULL || nonceSz < 7 || nonceSz > 13)
+        return BAD_FUNC_ARG;
+
+    key = (byte*)aes->key;
+
+    status = wc_AesGetKeySize(aes, &keySize);
+    if (status != 0) {
+        return status;
+    }
+
+    status = LTC_AES_EncryptTagCcm(LTC_BASE, in, out, inSz,
+        nonce, nonceSz, authIn, authInSz, key, keySize, authTag, authTagSz);
+
+    return (kStatus_Success == status) ? 0 : BAD_FUNC_ARG;
+}
+
+#ifdef HAVE_AES_DECRYPT
+int  wc_AesCcmDecrypt(Aes* aes, byte* out, const byte* in, word32 inSz,
+                   const byte* nonce, word32 nonceSz,
+                   const byte* authTag, word32 authTagSz,
+                   const byte* authIn, word32 authInSz)
+{
+    byte *key;
+    uint32_t keySize;
+    status_t status;
+
+    /* sanity check on arguments */
+    if (aes == NULL || out == NULL || in == NULL || nonce == NULL
+            || authTag == NULL || nonceSz < 7 || nonceSz > 13)
+        return BAD_FUNC_ARG;
+
+    key = (byte*)aes->key;
+
+    status = wc_AesGetKeySize(aes, &keySize);
+    if (status != 0) {
+        return status;
+    }
+
+    status = LTC_AES_DecryptTagCcm(LTC_BASE, in, out, inSz,
+        nonce, nonceSz, authIn, authInSz, key, keySize, authTag, authTagSz);
+
+    if (status == kStatus_Success) {
+        return 0;
+    }
+    else {
+        XMEMSET(out, 0, inSz);
+        return AES_CCM_AUTH_E;
+    }
+}
+#endif /* HAVE_AES_DECRYPT */
+
+#else
+
+/* Software CCM */
+static void roll_x(Aes* aes, const byte* in, word32 inSz, byte* out)
+{
+    /* process the bulk of the data */
+    while (inSz >= AES_BLOCK_SIZE) {
+        xorbuf(out, in, AES_BLOCK_SIZE);
+        in += AES_BLOCK_SIZE;
+        inSz -= AES_BLOCK_SIZE;
+
+        wc_AesEncrypt(aes, out, out);
+    }
+
+    /* process remainder of the data */
+    if (inSz > 0) {
+        xorbuf(out, in, inSz);
+        wc_AesEncrypt(aes, out, out);
+    }
+}
+
+static void roll_auth(Aes* aes, const byte* in, word32 inSz, byte* out)
+{
+    word32 authLenSz;
+    word32 remainder;
+
+    /* encode the length in */
+    if (inSz <= 0xFEFF) {
+        authLenSz = 2;
+        out[0] ^= ((inSz & 0xFF00) >> 8);
+        out[1] ^=  (inSz & 0x00FF);
+    }
+    else if (inSz <= 0xFFFFFFFF) {
+        authLenSz = 6;
+        out[0] ^= 0xFF; out[1] ^= 0xFE;
+        out[2] ^= ((inSz & 0xFF000000) >> 24);
+        out[3] ^= ((inSz & 0x00FF0000) >> 16);
+        out[4] ^= ((inSz & 0x0000FF00) >>  8);
+        out[5] ^=  (inSz & 0x000000FF);
+    }
+    /* Note, the protocol handles auth data up to 2^64, but we are
+     * using 32-bit sizes right now, so the bigger data isn't handled
+     * else if (inSz <= 0xFFFFFFFFFFFFFFFF) {} */
+    else
+        return;
+
+    /* start fill out the rest of the first block */
+    remainder = AES_BLOCK_SIZE - authLenSz;
+    if (inSz >= remainder) {
+        /* plenty of bulk data to fill the remainder of this block */
+        xorbuf(out + authLenSz, in, remainder);
+        inSz -= remainder;
+        in += remainder;
+    }
+    else {
+        /* not enough bulk data, copy what is available, and pad zero */
+        xorbuf(out + authLenSz, in, inSz);
+        inSz = 0;
+    }
+    wc_AesEncrypt(aes, out, out);
+
+    if (inSz > 0)
+        roll_x(aes, in, inSz, out);
+}
+
+
+static WC_INLINE void AesCcmCtrInc(byte* B, word32 lenSz)
+{
+    word32 i;
+
+    for (i = 0; i < lenSz; i++) {
+        if (++B[AES_BLOCK_SIZE - 1 - i] != 0) return;
+    }
+}
+
+#ifdef WOLFSSL_AESNI
+static WC_INLINE void AesCcmCtrIncSet4(byte* B, word32 lenSz)
+{
+    word32 i;
+
+    /* B+1 = B */
+    XMEMCPY(B + AES_BLOCK_SIZE * 1, B, AES_BLOCK_SIZE);
+    /* B+2,B+3 = B,B+1 */
+    XMEMCPY(B + AES_BLOCK_SIZE * 2, B, AES_BLOCK_SIZE * 2);
+
+    for (i = 0; i < lenSz; i++) {
+        if (++B[AES_BLOCK_SIZE * 1 - 1 - i] != 0) break;
+    }
+    B[AES_BLOCK_SIZE * 2 - 1] += 2;
+    if (B[AES_BLOCK_SIZE * 2 - 1] < 2) {
+        for (i = 1; i < lenSz; i++) {
+            if (++B[AES_BLOCK_SIZE * 2 - 1 - i] != 0) break;
+        }
+    }
+    B[AES_BLOCK_SIZE * 3 - 1] += 3;
+    if (B[AES_BLOCK_SIZE * 3 - 1] < 3) {
+        for (i = 1; i < lenSz; i++) {
+            if (++B[AES_BLOCK_SIZE * 3 - 1 - i] != 0) break;
+        }
+    }
+}
+
+static WC_INLINE void AesCcmCtrInc4(byte* B, word32 lenSz)
+{
+    word32 i;
+
+    B[AES_BLOCK_SIZE - 1] += 4;
+    if (B[AES_BLOCK_SIZE - 1] < 4) {
+        for (i = 1; i < lenSz; i++) {
+            if (++B[AES_BLOCK_SIZE - 1 - i] != 0) break;
+        }
+    }
+}
+#endif
+
+/* Software AES - CCM Encrypt */
+/* return 0 on success */
+int wc_AesCcmEncrypt(Aes* aes, byte* out, const byte* in, word32 inSz,
+                   const byte* nonce, word32 nonceSz,
+                   byte* authTag, word32 authTagSz,
+                   const byte* authIn, word32 authInSz)
+{
+#ifndef WOLFSSL_AESNI
+    byte A[AES_BLOCK_SIZE];
+    byte B[AES_BLOCK_SIZE];
+#else
+    ALIGN128 byte A[AES_BLOCK_SIZE * 4];
+    ALIGN128 byte B[AES_BLOCK_SIZE * 4];
+#endif
+    byte lenSz;
+    word32 i;
+    byte mask = 0xFF;
+    const word32 wordSz = (word32)sizeof(word32);
+
+    /* sanity check on arguments */
+    if (aes == NULL || out == NULL || in == NULL || nonce == NULL
+            || authTag == NULL || nonceSz < 7 || nonceSz > 13 ||
+            authTagSz > AES_BLOCK_SIZE)
+        return BAD_FUNC_ARG;
+
+    XMEMSET(A, 0, sizeof(A));
+    XMEMCPY(B+1, nonce, nonceSz);
+    lenSz = AES_BLOCK_SIZE - 1 - (byte)nonceSz;
+    B[0] = (authInSz > 0 ? 64 : 0)
+         + (8 * (((byte)authTagSz - 2) / 2))
+         + (lenSz - 1);
+    for (i = 0; i < lenSz; i++) {
+        if (mask && i >= wordSz)
+            mask = 0x00;
+        B[AES_BLOCK_SIZE - 1 - i] = (inSz >> ((8 * i) & mask)) & mask;
+    }
+
+    wc_AesEncrypt(aes, B, A);
+
+    if (authInSz > 0)
+        roll_auth(aes, authIn, authInSz, A);
+    if (inSz > 0)
+        roll_x(aes, in, inSz, A);
+    XMEMCPY(authTag, A, authTagSz);
+
+    B[0] = lenSz - 1;
+    for (i = 0; i < lenSz; i++)
+        B[AES_BLOCK_SIZE - 1 - i] = 0;
+    wc_AesEncrypt(aes, B, A);
+    xorbuf(authTag, A, authTagSz);
+
+    B[15] = 1;
+#ifdef WOLFSSL_AESNI
+    if (haveAESNI && aes->use_aesni) {
+        while (inSz >= AES_BLOCK_SIZE * 4) {
+            AesCcmCtrIncSet4(B, lenSz);
+
+            AES_ECB_encrypt(B, A, AES_BLOCK_SIZE * 4, (byte*)aes->key,
+                            aes->rounds);
+            xorbuf(A, in, AES_BLOCK_SIZE * 4);
+            XMEMCPY(out, A, AES_BLOCK_SIZE * 4);
+
+            inSz -= AES_BLOCK_SIZE * 4;
+            in += AES_BLOCK_SIZE * 4;
+            out += AES_BLOCK_SIZE * 4;
+
+            if (inSz < AES_BLOCK_SIZE * 4) {
+                AesCcmCtrInc4(B, lenSz);
+            }
+        }
+    }
+#endif
+    while (inSz >= AES_BLOCK_SIZE) {
+        wc_AesEncrypt(aes, B, A);
+        xorbuf(A, in, AES_BLOCK_SIZE);
+        XMEMCPY(out, A, AES_BLOCK_SIZE);
+
+        AesCcmCtrInc(B, lenSz);
+        inSz -= AES_BLOCK_SIZE;
+        in += AES_BLOCK_SIZE;
+        out += AES_BLOCK_SIZE;
+    }
+    if (inSz > 0) {
+        wc_AesEncrypt(aes, B, A);
+        xorbuf(A, in, inSz);
+        XMEMCPY(out, A, inSz);
+    }
+
+    ForceZero(A, AES_BLOCK_SIZE);
+    ForceZero(B, AES_BLOCK_SIZE);
+
+    return 0;
+}
+
+#ifdef HAVE_AES_DECRYPT
+/* Software AES - CCM Decrypt */
+int  wc_AesCcmDecrypt(Aes* aes, byte* out, const byte* in, word32 inSz,
+                   const byte* nonce, word32 nonceSz,
+                   const byte* authTag, word32 authTagSz,
+                   const byte* authIn, word32 authInSz)
+{
+#ifndef WOLFSSL_AESNI
+    byte A[AES_BLOCK_SIZE];
+    byte B[AES_BLOCK_SIZE];
+#else
+    ALIGN128 byte B[AES_BLOCK_SIZE * 4];
+    ALIGN128 byte A[AES_BLOCK_SIZE * 4];
+#endif
+    byte* o;
+    byte lenSz;
+    word32 i, oSz;
+    int result = 0;
+    byte mask = 0xFF;
+    const word32 wordSz = (word32)sizeof(word32);
+
+    /* sanity check on arguments */
+    if (aes == NULL || out == NULL || in == NULL || nonce == NULL
+            || authTag == NULL || nonceSz < 7 || nonceSz > 13 ||
+            authTagSz > AES_BLOCK_SIZE)
+        return BAD_FUNC_ARG;
+
+    o = out;
+    oSz = inSz;
+    XMEMCPY(B+1, nonce, nonceSz);
+    lenSz = AES_BLOCK_SIZE - 1 - (byte)nonceSz;
+
+    B[0] = lenSz - 1;
+    for (i = 0; i < lenSz; i++)
+        B[AES_BLOCK_SIZE - 1 - i] = 0;
+    B[15] = 1;
+
+#ifdef WOLFSSL_AESNI
+    if (haveAESNI && aes->use_aesni) {
+        while (oSz >= AES_BLOCK_SIZE * 4) {
+            AesCcmCtrIncSet4(B, lenSz);
+
+            AES_ECB_encrypt(B, A, AES_BLOCK_SIZE * 4, (byte*)aes->key,
+                            aes->rounds);
+            xorbuf(A, in, AES_BLOCK_SIZE * 4);
+            XMEMCPY(o, A, AES_BLOCK_SIZE * 4);
+
+            oSz -= AES_BLOCK_SIZE * 4;
+            in += AES_BLOCK_SIZE * 4;
+            o += AES_BLOCK_SIZE * 4;
+
+            if (oSz < AES_BLOCK_SIZE * 4) {
+                AesCcmCtrInc4(B, lenSz);
+            }
+        }
+    }
+#endif
+    while (oSz >= AES_BLOCK_SIZE) {
+        wc_AesEncrypt(aes, B, A);
+        xorbuf(A, in, AES_BLOCK_SIZE);
+        XMEMCPY(o, A, AES_BLOCK_SIZE);
+
+        AesCcmCtrInc(B, lenSz);
+        oSz -= AES_BLOCK_SIZE;
+        in += AES_BLOCK_SIZE;
+        o += AES_BLOCK_SIZE;
+    }
+    if (inSz > 0) {
+        wc_AesEncrypt(aes, B, A);
+        xorbuf(A, in, oSz);
+        XMEMCPY(o, A, oSz);
+    }
+
+    for (i = 0; i < lenSz; i++)
+        B[AES_BLOCK_SIZE - 1 - i] = 0;
+    wc_AesEncrypt(aes, B, A);
+
+    o = out;
+    oSz = inSz;
+
+    B[0] = (authInSz > 0 ? 64 : 0)
+         + (8 * (((byte)authTagSz - 2) / 2))
+         + (lenSz - 1);
+    for (i = 0; i < lenSz; i++) {
+        if (mask && i >= wordSz)
+            mask = 0x00;
+        B[AES_BLOCK_SIZE - 1 - i] = (inSz >> ((8 * i) & mask)) & mask;
+    }
+
+    wc_AesEncrypt(aes, B, A);
+
+    if (authInSz > 0)
+        roll_auth(aes, authIn, authInSz, A);
+    if (inSz > 0)
+        roll_x(aes, o, oSz, A);
+
+    B[0] = lenSz - 1;
+    for (i = 0; i < lenSz; i++)
+        B[AES_BLOCK_SIZE - 1 - i] = 0;
+    wc_AesEncrypt(aes, B, B);
+    xorbuf(A, B, authTagSz);
+
+    if (ConstantCompare(A, authTag, authTagSz) != 0) {
+        /* If the authTag check fails, don't keep the decrypted data.
+         * Unfortunately, you need the decrypted data to calculate the
+         * check value. */
+        XMEMSET(out, 0, inSz);
+        result = AES_CCM_AUTH_E;
+    }
+
+    ForceZero(A, AES_BLOCK_SIZE);
+    ForceZero(B, AES_BLOCK_SIZE);
+    o = NULL;
+
+    return result;
+}
+
+#endif /* HAVE_AES_DECRYPT */
+#endif /* software CCM */
+
+/* abstract functions that call lower level AESCCM functions */
+#ifndef WC_NO_RNG
+
+int wc_AesCcmSetNonce(Aes* aes, const byte* nonce, word32 nonceSz)
+{
+    int ret = 0;
+
+    if (aes == NULL || nonce == NULL ||
+        nonceSz < CCM_NONCE_MIN_SZ || nonceSz > CCM_NONCE_MAX_SZ) {
+
+        ret = BAD_FUNC_ARG;
+    }
+
+    if (ret == 0) {
+        XMEMCPY(aes->reg, nonce, nonceSz);
+        aes->nonceSz = nonceSz;
+
+        /* Invocation counter should be 2^61 */
+        aes->invokeCtr[0] = 0;
+        aes->invokeCtr[1] = 0xE0000000;
+    }
+
+    return ret;
+}
+
+
+int wc_AesCcmEncrypt_ex(Aes* aes, byte* out, const byte* in, word32 sz,
+                        byte* ivOut, word32 ivOutSz,
+                        byte* authTag, word32 authTagSz,
+                        const byte* authIn, word32 authInSz)
+{
+    int ret = 0;
+
+    if (aes == NULL || out == NULL ||
+        (in == NULL && sz != 0) ||
+        ivOut == NULL ||
+        (authIn == NULL && authInSz != 0) ||
+        (ivOutSz != aes->nonceSz)) {
+
+        ret = BAD_FUNC_ARG;
+    }
+
+    if (ret == 0) {
+        aes->invokeCtr[0]++;
+        if (aes->invokeCtr[0] == 0) {
+            aes->invokeCtr[1]++;
+            if (aes->invokeCtr[1] == 0)
+                ret = AES_CCM_OVERFLOW_E;
+        }
+    }
+
+    if (ret == 0) {
+        ret = wc_AesCcmEncrypt(aes, out, in, sz,
+                               (byte*)aes->reg, aes->nonceSz,
+                               authTag, authTagSz,
+                               authIn, authInSz);
+        if (ret == 0) {
+            XMEMCPY(ivOut, aes->reg, aes->nonceSz);
+            IncCtr((byte*)aes->reg, aes->nonceSz);
+        }
+    }
+
+    return ret;
+}
+
+#endif /* WC_NO_RNG */
+
+#endif /* HAVE_AESCCM */
+
+
+/* Initialize Aes for use with async hardware */
+int wc_AesInit(Aes* aes, void* heap, int devId)
+{
+    int ret = 0;
+
+    if (aes == NULL)
+        return BAD_FUNC_ARG;
+
+    aes->heap = heap;
+
+#ifdef WOLF_CRYPTO_CB
+    aes->devId = devId;
+    aes->devCtx = NULL;
+#else
+    (void)devId;
+#endif
+#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_AES)
+    ret = wolfAsync_DevCtxInit(&aes->asyncDev, WOLFSSL_ASYNC_MARKER_AES,
+                                                        aes->heap, devId);
+#endif /* WOLFSSL_ASYNC_CRYPT */
+
+#ifdef WOLFSSL_AFALG
+    aes->alFd = -1;
+    aes->rdFd = -1;
+#endif
+#if defined(WOLFSSL_DEVCRYPTO) && \
+   (defined(WOLFSSL_DEVCRYPTO_AES) || defined(WOLFSSL_DEVCRYPTO_CBC))
+    aes->ctx.cfd = -1;
+#endif
+#if defined(WOLFSSL_CRYPTOCELL) && defined(WOLFSSL_CRYPTOCELL_AES)
+    XMEMSET(&aes->ctx, 0, sizeof(aes->ctx));
+#endif
+#ifdef HAVE_AESGCM
+#ifdef OPENSSL_EXTRA
+    XMEMSET(aes->aadH, 0, sizeof(aes->aadH));
+    aes->aadLen = 0;
+#endif
+#endif
+    return ret;
+}
+
+#ifdef HAVE_PKCS11
+int  wc_AesInit_Id(Aes* aes, unsigned char* id, int len, void* heap, int devId)
+{
+    int ret = 0;
+
+    if (aes == NULL)
+        ret = BAD_FUNC_ARG;
+    if (ret == 0 && (len < 0 || len > AES_MAX_ID_LEN))
+        ret = BUFFER_E;
+
+    if (ret == 0)
+        ret  = wc_AesInit(aes, heap, devId);
+    if (ret == 0) {
+        XMEMCPY(aes->id, id, len);
+        aes->idLen = len;
+    }
+
+    return ret;
+}
+#endif
+
+/* Free Aes from use with async hardware */
+void wc_AesFree(Aes* aes)
+{
+    if (aes == NULL)
+        return;
+
+#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_AES)
+    wolfAsync_DevCtxFree(&aes->asyncDev, WOLFSSL_ASYNC_MARKER_AES);
+#endif /* WOLFSSL_ASYNC_CRYPT */
+#if defined(WOLFSSL_AFALG) || defined(WOLFSSL_AFALG_XILINX_AES)
+    if (aes->rdFd > 0) { /* negative is error case */
+        close(aes->rdFd);
+    }
+    if (aes->alFd > 0) {
+        close(aes->alFd);
+    }
+#endif /* WOLFSSL_AFALG */
+#if defined(WOLFSSL_DEVCRYPTO) && \
+    (defined(WOLFSSL_DEVCRYPTO_AES) || defined(WOLFSSL_DEVCRYPTO_CBC))
+    wc_DevCryptoFree(&aes->ctx);
+#endif
+#if defined(WOLF_CRYPTO_CB) || (defined(WOLFSSL_DEVCRYPTO) && \
+    (defined(WOLFSSL_DEVCRYPTO_AES) || defined(WOLFSSL_DEVCRYPTO_CBC))) || \
+    (defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_AES))
+    ForceZero((byte*)aes->devKey, AES_MAX_KEY_SIZE/WOLFSSL_BIT_SIZE);
+#endif
+}
+
+
+int wc_AesGetKeySize(Aes* aes, word32* keySize)
+{
+    int ret = 0;
+
+    if (aes == NULL || keySize == NULL) {
+        return BAD_FUNC_ARG;
+    }
+#if defined(WOLFSSL_CRYPTOCELL) && defined(WOLFSSL_CRYPTOCELL_AES)
+    *keySize = aes->ctx.key.keySize;
+    return ret;
+#endif
+    switch (aes->rounds) {
+#ifdef WOLFSSL_AES_128
+    case 10:
+        *keySize = 16;
+        break;
+#endif
+#ifdef WOLFSSL_AES_192
+    case 12:
+        *keySize = 24;
+        break;
+#endif
+#ifdef WOLFSSL_AES_256
+    case 14:
+        *keySize = 32;
+        break;
+#endif
+    default:
+        *keySize = 0;
+        ret = BAD_FUNC_ARG;
+    }
+
+    return ret;
+}
+
+#endif /* !WOLFSSL_TI_CRYPT */
+
+#ifdef HAVE_AES_ECB
+#if defined(WOLFSSL_IMX6_CAAM) && !defined(NO_IMX6_CAAM_AES)
+    /* implemented in wolfcrypt/src/port/caam/caam_aes.c */
+
+#elif defined(WOLFSSL_AFALG)
+    /* implemented in wolfcrypt/src/port/af_alg/afalg_aes.c */
+
+#elif defined(WOLFSSL_DEVCRYPTO_AES)
+    /* implemented in wolfcrypt/src/port/devcrypt/devcrypto_aes.c */
+
+#elif defined(WOLFSSL_SCE) && !defined(WOLFSSL_SCE_NO_AES)
+
+/* Software AES - ECB */
+int wc_AesEcbEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
+{
+    if ((in == NULL) || (out == NULL) || (aes == NULL))
+        return BAD_FUNC_ARG;
+
+        return AES_ECB_encrypt(aes, in, out, sz);
+}
+
+
+int wc_AesEcbDecrypt(Aes* aes, byte* out, const byte* in, word32 sz)
+{
+    if ((in == NULL) || (out == NULL) || (aes == NULL))
+        return BAD_FUNC_ARG;
+
+        return AES_ECB_decrypt(aes, in, out, sz);
+}
+
+#else
+
+/* Software AES - ECB */
+int wc_AesEcbEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
+{
+    word32 blocks = sz / AES_BLOCK_SIZE;
+
+    if ((in == NULL) || (out == NULL) || (aes == NULL))
+      return BAD_FUNC_ARG;
+    while (blocks>0) {
+      wc_AesEncryptDirect(aes, out, in);
+      out += AES_BLOCK_SIZE;
+      in  += AES_BLOCK_SIZE;
+      sz  -= AES_BLOCK_SIZE;
+      blocks--;
+    }
+    return 0;
+}
+
+
+int wc_AesEcbDecrypt(Aes* aes, byte* out, const byte* in, word32 sz)
+{
+    word32 blocks = sz / AES_BLOCK_SIZE;
+
+    if ((in == NULL) || (out == NULL) || (aes == NULL))
+      return BAD_FUNC_ARG;
+    while (blocks>0) {
+      wc_AesDecryptDirect(aes, out, in);
+      out += AES_BLOCK_SIZE;
+      in  += AES_BLOCK_SIZE;
+      sz  -= AES_BLOCK_SIZE;
+      blocks--;
+    }
+    return 0;
+}
+#endif
+#endif /* HAVE_AES_ECB */
+
+#if defined(WOLFSSL_AES_CFB) || defined(WOLFSSL_AES_OFB)
+/* Feedback AES mode
+ *
+ * aes structure holding key to use for encryption
+ * out buffer to hold result of encryption (must be at least as large as input
+ *     buffer)
+ * in  buffer to encrypt
+ * sz  size of input buffer
+ * mode flag to specify AES mode
+ *
+ * returns 0 on success and negative error values on failure
+ */
+/* Software AES - CFB Encrypt */
+static int wc_AesFeedbackEncrypt(Aes* aes, byte* out, const byte* in,
+        word32 sz, byte mode)
+{
+    byte*  tmp = NULL;
+#ifdef WOLFSSL_AES_CFB
+    byte*  reg = NULL;
+#endif
+
+    if (aes == NULL || out == NULL || in == NULL) {
+        return BAD_FUNC_ARG;
+    }
+
+#ifdef WOLFSSL_AES_CFB
+    if (aes->left && sz) {
+        reg = (byte*)aes->reg + AES_BLOCK_SIZE - aes->left;
+    }
+#endif
+
+    /* consume any unused bytes left in aes->tmp */
+    tmp = (byte*)aes->tmp + AES_BLOCK_SIZE - aes->left;
+    while (aes->left && sz) {
+        *(out) = *(in++) ^ *(tmp++);
+    #ifdef WOLFSSL_AES_CFB
+        if (mode == AES_CFB_MODE) {
+            *(reg++) = *out;
+        }
+    #endif
+        out++;
+        aes->left--;
+        sz--;
+    }
+
+    while (sz >= AES_BLOCK_SIZE) {
+        /* Using aes->tmp here for inline case i.e. in=out */
+        wc_AesEncryptDirect(aes, (byte*)aes->tmp, (byte*)aes->reg);
+    #ifdef WOLFSSL_AES_OFB
+        if (mode == AES_OFB_MODE) {
+            XMEMCPY(aes->reg, aes->tmp, AES_BLOCK_SIZE);
+        }
+    #endif
+        xorbuf((byte*)aes->tmp, in, AES_BLOCK_SIZE);
+    #ifdef WOLFSSL_AES_CFB
+        if (mode == AES_CFB_MODE) {
+            XMEMCPY(aes->reg, aes->tmp, AES_BLOCK_SIZE);
+        }
+    #endif
+        XMEMCPY(out, aes->tmp, AES_BLOCK_SIZE);
+        out += AES_BLOCK_SIZE;
+        in  += AES_BLOCK_SIZE;
+        sz  -= AES_BLOCK_SIZE;
+        aes->left = 0;
+    }
+
+    /* encrypt left over data */
+    if (sz) {
+        wc_AesEncryptDirect(aes, (byte*)aes->tmp, (byte*)aes->reg);
+        aes->left = AES_BLOCK_SIZE;
+        tmp = (byte*)aes->tmp;
+    #ifdef WOLFSSL_AES_OFB
+        if (mode == AES_OFB_MODE) {
+            XMEMCPY(aes->reg, aes->tmp, AES_BLOCK_SIZE);
+        }
+    #endif
+    #ifdef WOLFSSL_AES_CFB
+        reg = (byte*)aes->reg;
+    #endif
+
+        while (sz--) {
+            *(out) = *(in++) ^ *(tmp++);
+        #ifdef WOLFSSL_AES_CFB
+            if (mode == AES_CFB_MODE) {
+                *(reg++) = *out;
+            }
+        #endif
+            out++;
+            aes->left--;
+        }
+    }
+
+    return 0;
+}
+
+
+#ifdef HAVE_AES_DECRYPT
+/* CFB 128
+ *
+ * aes structure holding key to use for decryption
+ * out buffer to hold result of decryption (must be at least as large as input
+ *     buffer)
+ * in  buffer to decrypt
+ * sz  size of input buffer
+ *
+ * returns 0 on success and negative error values on failure
+ */
+/* Software AES - CFB Decrypt */
+static int wc_AesFeedbackDecrypt(Aes* aes, byte* out, const byte* in, word32 sz,
+        byte mode)
+{
+    byte*  tmp;
+
+    if (aes == NULL || out == NULL || in == NULL) {
+        return BAD_FUNC_ARG;
+    }
+
+    #ifdef WOLFSSL_AES_CFB
+    /* check if more input needs copied over to aes->reg */
+    if (aes->left && sz && mode == AES_CFB_MODE) {
+        int size = min(aes->left, sz);
+        XMEMCPY((byte*)aes->reg + AES_BLOCK_SIZE - aes->left, in, size);
+    }
+    #endif
+
+    /* consume any unused bytes left in aes->tmp */
+    tmp = (byte*)aes->tmp + AES_BLOCK_SIZE - aes->left;
+    while (aes->left && sz) {
+        *(out++) = *(in++) ^ *(tmp++);
+        aes->left--;
+        sz--;
+    }
+
+    while (sz > AES_BLOCK_SIZE) {
+        /* Using aes->tmp here for inline case i.e. in=out */
+        wc_AesEncryptDirect(aes, (byte*)aes->tmp, (byte*)aes->reg);
+    #ifdef WOLFSSL_AES_OFB
+        if (mode == AES_OFB_MODE) {
+            XMEMCPY((byte*)aes->reg, (byte*)aes->tmp, AES_BLOCK_SIZE);
+        }
+    #endif
+        xorbuf((byte*)aes->tmp, in, AES_BLOCK_SIZE);
+    #ifdef WOLFSSL_AES_CFB
+        if (mode == AES_CFB_MODE) {
+            XMEMCPY(aes->reg, in, AES_BLOCK_SIZE);
+        }
+    #endif
+        XMEMCPY(out, (byte*)aes->tmp, AES_BLOCK_SIZE);
+        out += AES_BLOCK_SIZE;
+        in  += AES_BLOCK_SIZE;
+        sz  -= AES_BLOCK_SIZE;
+        aes->left = 0;
+    }
+
+    /* decrypt left over data */
+    if (sz) {
+        wc_AesEncryptDirect(aes, (byte*)aes->tmp, (byte*)aes->reg);
+    #ifdef WOLFSSL_AES_CFB
+        if (mode == AES_CFB_MODE) {
+            XMEMCPY(aes->reg, in, sz);
+        }
+    #endif
+    #ifdef WOLFSSL_AES_OFB
+        if (mode == AES_OFB_MODE) {
+            XMEMCPY(aes->reg, aes->tmp, AES_BLOCK_SIZE);
+        }
+    #endif
+
+        aes->left = AES_BLOCK_SIZE;
+        tmp = (byte*)aes->tmp;
+
+        while (sz--) {
+            *(out++) = *(in++) ^ *(tmp++);
+            aes->left--;
+        }
+    }
+
+    return 0;
+}
+#endif /* HAVE_AES_DECRYPT */
+#endif /* WOLFSSL_AES_CFB */
+
+#ifdef WOLFSSL_AES_CFB
+/* CFB 128
+ *
+ * aes structure holding key to use for encryption
+ * out buffer to hold result of encryption (must be at least as large as input
+ *     buffer)
+ * in  buffer to encrypt
+ * sz  size of input buffer
+ *
+ * returns 0 on success and negative error values on failure
+ */
+/* Software AES - CFB Encrypt */
+int wc_AesCfbEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
+{
+    return wc_AesFeedbackEncrypt(aes, out, in, sz, AES_CFB_MODE);
+}
+
+
+#ifdef HAVE_AES_DECRYPT
+/* CFB 128
+ *
+ * aes structure holding key to use for decryption
+ * out buffer to hold result of decryption (must be at least as large as input
+ *     buffer)
+ * in  buffer to decrypt
+ * sz  size of input buffer
+ *
+ * returns 0 on success and negative error values on failure
+ */
+/* Software AES - CFB Decrypt */
+int wc_AesCfbDecrypt(Aes* aes, byte* out, const byte* in, word32 sz)
+{
+    return wc_AesFeedbackDecrypt(aes, out, in, sz, AES_CFB_MODE);
+}
+#endif /* HAVE_AES_DECRYPT */
+
+
+/* shift the whole AES_BLOCK_SIZE array left by 8 or 1 bits */
+static void shiftLeftArray(byte* ary, byte shift)
+{
+    int i;
+
+    if (shift == WOLFSSL_BIT_SIZE) {
+        /* shifting over by 8 bits */
+        for (i = 0; i < AES_BLOCK_SIZE - 1; i++) {
+            ary[i] = ary[i+1];
+        }
+        ary[i] = 0;
+    }
+    else {
+        byte carry = 0;
+
+        /* shifting over by 7 or less bits */
+        for (i = 0; i < AES_BLOCK_SIZE - 1; i++) {
+            carry = ary[i+1] & (0XFF << (WOLFSSL_BIT_SIZE - shift));
+            carry >>= (WOLFSSL_BIT_SIZE - shift);
+            ary[i] = (ary[i] << shift) + carry;
+        }
+        ary[i] = ary[i] << shift;
+    }
+}
+
+
+/* returns 0 on success and negative values on failure */
+static int wc_AesFeedbackCFB8(Aes* aes, byte* out, const byte* in,
+        word32 sz, byte dir)
+{
+    byte *pt;
+
+    if (aes == NULL || out == NULL || in == NULL) {
+        return BAD_FUNC_ARG;
+    }
+
+    if (sz == 0) {
+        return 0;
+    }
+
+    while (sz > 0) {
+        wc_AesEncryptDirect(aes, (byte*)aes->tmp, (byte*)aes->reg);
+        if (dir == AES_DECRYPTION) {
+            pt = (byte*)aes->reg;
+
+            /* LSB + CAT */
+            shiftLeftArray(pt, WOLFSSL_BIT_SIZE);
+            pt[AES_BLOCK_SIZE - 1] = in[0];
+        }
+
+        /* MSB + XOR */
+        out[0] = aes->tmp[0] ^ in[0];
+        if (dir == AES_ENCRYPTION) {
+            pt = (byte*)aes->reg;
+
+            /* LSB + CAT */
+            shiftLeftArray(pt, WOLFSSL_BIT_SIZE);
+            pt[AES_BLOCK_SIZE - 1] = out[0];
+        }
+
+        out += 1;
+        in  += 1;
+        sz  -= 1;
+    }
+
+    return 0;
+}
+
+
+/* returns 0 on success and negative values on failure */
+static int wc_AesFeedbackCFB1(Aes* aes, byte* out, const byte* in,
+        word32 sz, byte dir)
+{
+    byte tmp;
+    byte cur = 0; /* hold current work in order to handle inline in=out */
+    byte* pt;
+    int bit = 7;
+
+    if (aes == NULL || out == NULL || in == NULL) {
+        return BAD_FUNC_ARG;
+    }
+
+    if (sz == 0) {
+        return 0;
+    }
+
+    while (sz > 0) {
+        wc_AesEncryptDirect(aes, (byte*)aes->tmp, (byte*)aes->reg);
+        if (dir == AES_DECRYPTION) {
+            pt = (byte*)aes->reg;
+
+            /* LSB + CAT */
+            tmp = (0X01 << bit) & in[0];
+            tmp = tmp >> bit;
+            tmp &= 0x01;
+            shiftLeftArray((byte*)aes->reg, 1);
+            pt[AES_BLOCK_SIZE - 1] |= tmp;
+        }
+
+        /* MSB  + XOR */
+        tmp = (0X01 << bit) & in[0];
+        pt = (byte*)aes->tmp;
+        tmp = (pt[0] >> 7) ^ (tmp >> bit);
+        tmp &= 0x01;
+        cur |= (tmp << bit);
+
+
+        if (dir == AES_ENCRYPTION) {
+            pt = (byte*)aes->reg;
+
+            /* LSB + CAT */
+            shiftLeftArray((byte*)aes->reg, 1);
+            pt[AES_BLOCK_SIZE - 1] |= tmp;
+        }
+
+        bit--;
+        if (bit < 0) {
+            out[0] = cur;
+            out += 1;
+            in  += 1;
+            sz  -= 1;
+            bit = 7;
+            cur = 0;
+        }
+        else {
+            sz -= 1;
+        }
+    }
+
+    if (bit > 0 && bit < 7) {
+        out[0] = cur;
+    }
+
+    return 0;
+}
+
+
+/* CFB 1
+ *
+ * aes structure holding key to use for encryption
+ * out buffer to hold result of encryption (must be at least as large as input
+ *     buffer)
+ * in  buffer to encrypt (packed to left, i.e. 101 is 0x90)
+ * sz  size of input buffer in bits (0x1 would be size of 1 and 0xFF size of 8)
+ *
+ * returns 0 on success and negative values on failure
+ */
+int wc_AesCfb1Encrypt(Aes* aes, byte* out, const byte* in, word32 sz)
+{
+    return wc_AesFeedbackCFB1(aes, out, in, sz, AES_ENCRYPTION);
+}
+
+
+/* CFB 8
+ *
+ * aes structure holding key to use for encryption
+ * out buffer to hold result of encryption (must be at least as large as input
+ *     buffer)
+ * in  buffer to encrypt
+ * sz  size of input buffer
+ *
+ * returns 0 on success and negative values on failure
+ */
+int wc_AesCfb8Encrypt(Aes* aes, byte* out, const byte* in, word32 sz)
+{
+    return wc_AesFeedbackCFB8(aes, out, in, sz, AES_ENCRYPTION);
+}
+#ifdef HAVE_AES_DECRYPT
+
+/* CFB 1
+ *
+ * aes structure holding key to use for encryption
+ * out buffer to hold result of encryption (must be at least as large as input
+ *     buffer)
+ * in  buffer to encrypt
+ * sz  size of input buffer in bits (0x1 would be size of 1 and 0xFF size of 8)
+ *
+ * returns 0 on success and negative values on failure
+ */
+int wc_AesCfb1Decrypt(Aes* aes, byte* out, const byte* in, word32 sz)
+{
+    return wc_AesFeedbackCFB1(aes, out, in, sz, AES_DECRYPTION);
+}
+
+
+/* CFB 8
+ *
+ * aes structure holding key to use for encryption
+ * out buffer to hold result of encryption (must be at least as large as input
+ *     buffer)
+ * in  buffer to encrypt
+ * sz  size of input buffer
+ *
+ * returns 0 on success and negative values on failure
+ */
+int wc_AesCfb8Decrypt(Aes* aes, byte* out, const byte* in, word32 sz)
+{
+    return wc_AesFeedbackCFB8(aes, out, in, sz, AES_DECRYPTION);
+}
+#endif /* HAVE_AES_DECRYPT */
+#endif /* WOLFSSL_AES_CFB */
+
+#ifdef WOLFSSL_AES_OFB
+/* OFB
+ *
+ * aes structure holding key to use for encryption
+ * out buffer to hold result of encryption (must be at least as large as input
+ *     buffer)
+ * in  buffer to encrypt
+ * sz  size of input buffer
+ *
+ * returns 0 on success and negative error values on failure
+ */
+/* Software AES - CFB Encrypt */
+int wc_AesOfbEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
+{
+    return wc_AesFeedbackEncrypt(aes, out, in, sz, AES_OFB_MODE);
+}
+
+
+#ifdef HAVE_AES_DECRYPT
+/* OFB
+ *
+ * aes structure holding key to use for decryption
+ * out buffer to hold result of decryption (must be at least as large as input
+ *     buffer)
+ * in  buffer to decrypt
+ * sz  size of input buffer
+ *
+ * returns 0 on success and negative error values on failure
+ */
+/* Software AES - OFB Decrypt */
+int wc_AesOfbDecrypt(Aes* aes, byte* out, const byte* in, word32 sz)
+{
+    return wc_AesFeedbackDecrypt(aes, out, in, sz, AES_OFB_MODE);
+}
+#endif /* HAVE_AES_DECRYPT */
+#endif /* WOLFSSL_AES_OFB */
+
+
+#ifdef HAVE_AES_KEYWRAP
+
+/* Initialize key wrap counter with value */
+static WC_INLINE void InitKeyWrapCounter(byte* inOutCtr, word32 value)
+{
+    int i;
+    word32 bytes;
+
+    bytes = sizeof(word32);
+    for (i = 0; i < (int)sizeof(word32); i++) {
+        inOutCtr[i+sizeof(word32)] = (value >> ((bytes - 1) * 8)) & 0xFF;
+        bytes--;
+    }
+}
+
+/* Increment key wrap counter */
+static WC_INLINE void IncrementKeyWrapCounter(byte* inOutCtr)
+{
+    int i;
+
+    /* in network byte order so start at end and work back */
+    for (i = KEYWRAP_BLOCK_SIZE - 1; i >= 0; i--) {
+        if (++inOutCtr[i])  /* we're done unless we overflow */
+            return;
+    }
+}
+
+/* Decrement key wrap counter */
+static WC_INLINE void DecrementKeyWrapCounter(byte* inOutCtr)
+{
+    int i;
+
+    for (i = KEYWRAP_BLOCK_SIZE - 1; i >= 0; i--) {
+        if (--inOutCtr[i] != 0xFF)  /* we're done unless we underflow */
+            return;
+    }
+}
+
+/* perform AES key wrap (RFC3394), return out sz on success, negative on err */
+int wc_AesKeyWrap(const byte* key, word32 keySz, const byte* in, word32 inSz,
+                  byte* out, word32 outSz, const byte* iv)
+{
+    Aes aes;
+    byte* r;
+    word32 i;
+    int ret, j;
+
+    byte t[KEYWRAP_BLOCK_SIZE];
+    byte tmp[AES_BLOCK_SIZE];
+
+    /* n must be at least 2, output size is n + 8 bytes */
+    if (key == NULL || in  == NULL || inSz < 2 ||
+        out == NULL || outSz < (inSz + KEYWRAP_BLOCK_SIZE))
+        return BAD_FUNC_ARG;
+
+    /* input must be multiple of 64-bits */
+    if (inSz % KEYWRAP_BLOCK_SIZE != 0)
+        return BAD_FUNC_ARG;
+
+    /* user IV is optional */
+    if (iv == NULL) {
+        XMEMSET(tmp, 0xA6, KEYWRAP_BLOCK_SIZE);
+    } else {
+        XMEMCPY(tmp, iv, KEYWRAP_BLOCK_SIZE);
+    }
+
+    r = out + 8;
+    XMEMCPY(r, in, inSz);
+    XMEMSET(t, 0, sizeof(t));
+
+    ret = wc_AesInit(&aes, NULL, INVALID_DEVID);
+    if (ret != 0)
+        return ret;
+
+    ret = wc_AesSetKey(&aes, key, keySz, NULL, AES_ENCRYPTION);
+    if (ret != 0)
+        return ret;
+
+    for (j = 0; j <= 5; j++) {
+        for (i = 1; i <= inSz / KEYWRAP_BLOCK_SIZE; i++) {
+
+            /* load R[i] */
+            XMEMCPY(tmp + KEYWRAP_BLOCK_SIZE, r, KEYWRAP_BLOCK_SIZE);
+
+            wc_AesEncryptDirect(&aes, tmp, tmp);
+
+            /* calculate new A */
+            IncrementKeyWrapCounter(t);
+            xorbuf(tmp, t, KEYWRAP_BLOCK_SIZE);
+
+            /* save R[i] */
+            XMEMCPY(r, tmp + KEYWRAP_BLOCK_SIZE, KEYWRAP_BLOCK_SIZE);
+            r += KEYWRAP_BLOCK_SIZE;
+        }
+        r = out + KEYWRAP_BLOCK_SIZE;
+    }
+
+    /* C[0] = A */
+    XMEMCPY(out, tmp, KEYWRAP_BLOCK_SIZE);
+
+    wc_AesFree(&aes);
+
+    return inSz + KEYWRAP_BLOCK_SIZE;
+}
+
+int wc_AesKeyUnWrap(const byte* key, word32 keySz, const byte* in, word32 inSz,
+                    byte* out, word32 outSz, const byte* iv)
+{
+    Aes aes;
+    byte* r;
+    word32 i, n;
+    int ret, j;
+
+    byte t[KEYWRAP_BLOCK_SIZE];
+    byte tmp[AES_BLOCK_SIZE];
+
+    const byte* expIv;
+    const byte defaultIV[] = {
+        0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6
+    };
+
+    (void)iv;
+
+    if (key == NULL || in == NULL || inSz < 3 ||
+        out == NULL || outSz < (inSz - KEYWRAP_BLOCK_SIZE))
+        return BAD_FUNC_ARG;
+
+    /* input must be multiple of 64-bits */
+    if (inSz % KEYWRAP_BLOCK_SIZE != 0)
+        return BAD_FUNC_ARG;
+
+    /* user IV optional */
+    if (iv != NULL) {
+        expIv = iv;
+    } else {
+        expIv = defaultIV;
+    }
+
+    /* A = C[0], R[i] = C[i] */
+    XMEMCPY(tmp, in, KEYWRAP_BLOCK_SIZE);
+    XMEMCPY(out, in + KEYWRAP_BLOCK_SIZE, inSz - KEYWRAP_BLOCK_SIZE);
+    XMEMSET(t, 0, sizeof(t));
+
+    ret = wc_AesInit(&aes, NULL, INVALID_DEVID);
+    if (ret != 0)
+        return ret;
+
+    ret = wc_AesSetKey(&aes, key, keySz, NULL, AES_DECRYPTION);
+    if (ret != 0)
+        return ret;
+
+    /* initialize counter to 6n */
+    n = (inSz - 1) / KEYWRAP_BLOCK_SIZE;
+    InitKeyWrapCounter(t, 6 * n);
+
+    for (j = 5; j >= 0; j--) {
+        for (i = n; i >= 1; i--) {
+
+            /* calculate A */
+            xorbuf(tmp, t, KEYWRAP_BLOCK_SIZE);
+            DecrementKeyWrapCounter(t);
+
+            /* load R[i], starting at end of R */
+            r = out + ((i - 1) * KEYWRAP_BLOCK_SIZE);
+            XMEMCPY(tmp + KEYWRAP_BLOCK_SIZE, r, KEYWRAP_BLOCK_SIZE);
+            wc_AesDecryptDirect(&aes, tmp, tmp);
+
+            /* save R[i] */
+            XMEMCPY(r, tmp + KEYWRAP_BLOCK_SIZE, KEYWRAP_BLOCK_SIZE);
+        }
+    }
+
+    wc_AesFree(&aes);
+
+    /* verify IV */
+    if (XMEMCMP(tmp, expIv, KEYWRAP_BLOCK_SIZE) != 0)
+        return BAD_KEYWRAP_IV_E;
+
+    return inSz - KEYWRAP_BLOCK_SIZE;
+}
+
+#endif /* HAVE_AES_KEYWRAP */
+
+#ifdef WOLFSSL_AES_XTS
+
+/* Galios Field to use */
+#define GF_XTS 0x87
+
+/* This is to help with setting keys to correct encrypt or decrypt type.
+ *
+ * tweak AES key for tweak in XTS
+ * aes   AES key for encrypt/decrypt process
+ * key   buffer holding aes key | tweak key
+ * len   length of key buffer in bytes. Should be twice that of key size. i.e.
+ *       32 for a 16 byte key.
+ * dir   direction, either AES_ENCRYPTION or AES_DECRYPTION
+ * heap  heap hint to use for memory. Can be NULL
+ * devId id to use with async crypto. Can be 0
+ *
+ * Note: is up to user to call wc_AesFree on tweak and aes key when done.
+ *
+ * return 0 on success
+ */
+int wc_AesXtsSetKey(XtsAes* aes, const byte* key, word32 len, int dir,
+        void* heap, int devId)
+{
+    word32 keySz;
+    int    ret = 0;
+
+    if (aes == NULL || key == NULL) {
+        return BAD_FUNC_ARG;
+    }
+
+    if ((ret = wc_AesInit(&aes->tweak, heap, devId)) != 0) {
+        return ret;
+    }
+    if ((ret = wc_AesInit(&aes->aes, heap, devId)) != 0) {
+        return ret;
+    }
+
+    keySz = len/2;
+    if (keySz != 16 && keySz != 32) {
+        WOLFSSL_MSG("Unsupported key size");
+        return WC_KEY_SIZE_E;
+    }
+
+    if ((ret = wc_AesSetKey(&aes->aes, key, keySz, NULL, dir)) == 0) {
+        ret = wc_AesSetKey(&aes->tweak, key + keySz, keySz, NULL,
+                AES_ENCRYPTION);
+        if (ret != 0) {
+            wc_AesFree(&aes->aes);
+        }
+    }
+
+    return ret;
+}
+
+
+/* This is used to free up resources used by Aes structs
+ *
+ * aes AES keys to free
+ *
+ * return 0 on success
+ */
+int wc_AesXtsFree(XtsAes* aes)
+{
+    if (aes != NULL) {
+        wc_AesFree(&aes->aes);
+        wc_AesFree(&aes->tweak);
+    }
+
+    return 0;
+}
+
+
+/* Same process as wc_AesXtsEncrypt but uses a word64 type as the tweak value
+ * instead of a byte array. This just converts the word64 to a byte array and
+ * calls wc_AesXtsEncrypt.
+ *
+ * aes    AES keys to use for block encrypt/decrypt
+ * out    output buffer to hold cipher text
+ * in     input plain text buffer to encrypt
+ * sz     size of both out and in buffers
+ * sector value to use for tweak
+ *
+ * returns 0 on success
+ */
+int wc_AesXtsEncryptSector(XtsAes* aes, byte* out, const byte* in,
+        word32 sz, word64 sector)
+{
+    byte* pt;
+    byte  i[AES_BLOCK_SIZE];
+
+    XMEMSET(i, 0, AES_BLOCK_SIZE);
+#ifdef BIG_ENDIAN_ORDER
+    sector = ByteReverseWord64(sector);
+#endif
+    pt = (byte*)&sector;
+    XMEMCPY(i, pt, sizeof(word64));
+
+    return wc_AesXtsEncrypt(aes, out, in, sz, (const byte*)i, AES_BLOCK_SIZE);
+}
+
+
+/* Same process as wc_AesXtsDecrypt but uses a word64 type as the tweak value
+ * instead of a byte array. This just converts the word64 to a byte array.
+ *
+ * aes    AES keys to use for block encrypt/decrypt
+ * out    output buffer to hold plain text
+ * in     input cipher text buffer to encrypt
+ * sz     size of both out and in buffers
+ * sector value to use for tweak
+ *
+ * returns 0 on success
+ */
+int wc_AesXtsDecryptSector(XtsAes* aes, byte* out, const byte* in, word32 sz,
+        word64 sector)
+{
+    byte* pt;
+    byte  i[AES_BLOCK_SIZE];
+
+    XMEMSET(i, 0, AES_BLOCK_SIZE);
+#ifdef BIG_ENDIAN_ORDER
+    sector = ByteReverseWord64(sector);
+#endif
+    pt = (byte*)&sector;
+    XMEMCPY(i, pt, sizeof(word64));
+
+    return wc_AesXtsDecrypt(aes, out, in, sz, (const byte*)i, AES_BLOCK_SIZE);
+}
+
+#ifdef HAVE_AES_ECB
+/* helper function for encrypting / decrypting full buffer at once */
+static int _AesXtsHelper(Aes* aes, byte* out, const byte* in, word32 sz, int dir)
+{
+    word32 outSz   = sz;
+    word32 totalSz = (sz / AES_BLOCK_SIZE) * AES_BLOCK_SIZE; /* total bytes */
+    byte*  pt      = out;
+
+    outSz -= AES_BLOCK_SIZE;
+
+    while (outSz > 0) {
+        word32 j;
+        byte carry = 0;
+
+        /* multiply by shift left and propagate carry */
+        for (j = 0; j < AES_BLOCK_SIZE && outSz > 0; j++, outSz--) {
+            byte tmpC;
+
+            tmpC   = (pt[j] >> 7) & 0x01;
+            pt[j+AES_BLOCK_SIZE] = ((pt[j] << 1) + carry) & 0xFF;
+            carry  = tmpC;
+        }
+        if (carry) {
+            pt[AES_BLOCK_SIZE] ^= GF_XTS;
+        }
+
+        pt += AES_BLOCK_SIZE;
+    }
+
+    xorbuf(out, in, totalSz);
+    if (dir == AES_ENCRYPTION) {
+        return wc_AesEcbEncrypt(aes, out, out, totalSz);
+    }
+    else {
+        return wc_AesEcbDecrypt(aes, out, out, totalSz);
+    }
+}
+#endif /* HAVE_AES_ECB */
+
+
+/* AES with XTS mode. (XTS) XEX encryption with Tweak and cipher text Stealing.
+ *
+ * xaes  AES keys to use for block encrypt/decrypt
+ * out   output buffer to hold cipher text
+ * in    input plain text buffer to encrypt
+ * sz    size of both out and in buffers
+ * i     value to use for tweak
+ * iSz   size of i buffer, should always be AES_BLOCK_SIZE but having this input
+ *       adds a sanity check on how the user calls the function.
+ *
+ * returns 0 on success
+ */
+/* Software AES - XTS Encrypt  */
+int wc_AesXtsEncrypt(XtsAes* xaes, byte* out, const byte* in, word32 sz,
+        const byte* i, word32 iSz)
+{
+    int ret = 0;
+    word32 blocks = (sz / AES_BLOCK_SIZE);
+    Aes *aes, *tweak;
+
+    if (xaes == NULL || out == NULL || in == NULL) {
+        return BAD_FUNC_ARG;
+    }
+
+    aes   = &xaes->aes;
+    tweak = &xaes->tweak;
+
+    if (iSz < AES_BLOCK_SIZE) {
+        return BAD_FUNC_ARG;
+    }
+
+    if (blocks > 0) {
+        byte tmp[AES_BLOCK_SIZE];
+
+        XMEMSET(tmp, 0, AES_BLOCK_SIZE); /* set to 0's in case of improper AES
+                                          * key setup passed to encrypt direct*/
+
+        wc_AesEncryptDirect(tweak, tmp, i);
+
+    #ifdef HAVE_AES_ECB
+        /* encrypt all of buffer at once when possible */
+        if (in != out) { /* can not handle inline */
+            XMEMCPY(out, tmp, AES_BLOCK_SIZE);
+            if ((ret = _AesXtsHelper(aes, out, in, sz, AES_ENCRYPTION)) != 0) {
+                return ret;
+            }
+        }
+    #endif
+
+        while (blocks > 0) {
+            word32 j;
+            byte carry = 0;
+            byte buf[AES_BLOCK_SIZE];
+
+    #ifdef HAVE_AES_ECB
+            if (in == out) { /* check for if inline */
+    #endif
+            XMEMCPY(buf, in, AES_BLOCK_SIZE);
+            xorbuf(buf, tmp, AES_BLOCK_SIZE);
+            wc_AesEncryptDirect(aes, out, buf);
+    #ifdef HAVE_AES_ECB
+            }
+    #endif
+            xorbuf(out, tmp, AES_BLOCK_SIZE);
+
+            /* multiply by shift left and propagate carry */
+            for (j = 0; j < AES_BLOCK_SIZE; j++) {
+                byte tmpC;
+
+                tmpC   = (tmp[j] >> 7) & 0x01;
+                tmp[j] = ((tmp[j] << 1) + carry) & 0xFF;
+                carry  = tmpC;
+            }
+            if (carry) {
+                tmp[0] ^= GF_XTS;
+            }
+
+            in  += AES_BLOCK_SIZE;
+            out += AES_BLOCK_SIZE;
+            sz  -= AES_BLOCK_SIZE;
+            blocks--;
+        }
+
+        /* stealing operation of XTS to handle left overs */
+        if (sz > 0) {
+            byte buf[AES_BLOCK_SIZE];
+
+            XMEMCPY(buf, out - AES_BLOCK_SIZE, AES_BLOCK_SIZE);
+            if (sz >= AES_BLOCK_SIZE) { /* extra sanity check before copy */
+                return BUFFER_E;
+            }
+            XMEMCPY(out, buf, sz);
+            XMEMCPY(buf, in, sz);
+
+            xorbuf(buf, tmp, AES_BLOCK_SIZE);
+            wc_AesEncryptDirect(aes, out - AES_BLOCK_SIZE, buf);
+            xorbuf(out - AES_BLOCK_SIZE, tmp, AES_BLOCK_SIZE);
+        }
+    }
+    else {
+        WOLFSSL_MSG("Plain text input too small for encryption");
+        return BAD_FUNC_ARG;
+    }
+
+    return ret;
+}
+
+
+/* Same process as encryption but Aes key is AES_DECRYPTION type.
+ *
+ * xaes  AES keys to use for block encrypt/decrypt
+ * out   output buffer to hold plain text
+ * in    input cipher text buffer to decrypt
+ * sz    size of both out and in buffers
+ * i     value to use for tweak
+ * iSz   size of i buffer, should always be AES_BLOCK_SIZE but having this input
+ *       adds a sanity check on how the user calls the function.
+ *
+ * returns 0 on success
+ */
+/* Software AES - XTS Decrypt */
+int wc_AesXtsDecrypt(XtsAes* xaes, byte* out, const byte* in, word32 sz,
+        const byte* i, word32 iSz)
+{
+    int ret = 0;
+    word32 blocks = (sz / AES_BLOCK_SIZE);
+    Aes *aes, *tweak;
+
+    if (xaes == NULL || out == NULL || in == NULL) {
+        return BAD_FUNC_ARG;
+    }
+
+    aes   = &xaes->aes;
+    tweak = &xaes->tweak;
+
+    if (iSz < AES_BLOCK_SIZE) {
+        return BAD_FUNC_ARG;
+    }
+
+    if (blocks > 0) {
+        word32 j;
+        byte carry = 0;
+        byte tmp[AES_BLOCK_SIZE];
+        byte stl = (sz % AES_BLOCK_SIZE);
+
+        XMEMSET(tmp, 0, AES_BLOCK_SIZE); /* set to 0's in case of improper AES
+                                          * key setup passed to decrypt direct*/
+
+        wc_AesEncryptDirect(tweak, tmp, i);
+
+        /* if Stealing then break out of loop one block early to handle special
+         * case */
+        if (stl > 0) {
+            blocks--;
+        }
+
+    #ifdef HAVE_AES_ECB
+        /* decrypt all of buffer at once when possible */
+        if (in != out) { /* can not handle inline */
+            XMEMCPY(out, tmp, AES_BLOCK_SIZE);
+            if ((ret = _AesXtsHelper(aes, out, in, sz, AES_DECRYPTION)) != 0) {
+                return ret;
+            }
+        }
+    #endif
+
+        while (blocks > 0) {
+            byte buf[AES_BLOCK_SIZE];
+
+    #ifdef HAVE_AES_ECB
+            if (in == out) { /* check for if inline */
+    #endif
+            XMEMCPY(buf, in, AES_BLOCK_SIZE);
+            xorbuf(buf, tmp, AES_BLOCK_SIZE);
+            wc_AesDecryptDirect(aes, out, buf);
+    #ifdef HAVE_AES_ECB
+            }
+    #endif
+            xorbuf(out, tmp, AES_BLOCK_SIZE);
+
+            /* multiply by shift left and propagate carry */
+            for (j = 0; j < AES_BLOCK_SIZE; j++) {
+                byte tmpC;
+
+                tmpC   = (tmp[j] >> 7) & 0x01;
+                tmp[j] = ((tmp[j] << 1) + carry) & 0xFF;
+                carry  = tmpC;
+            }
+            if (carry) {
+                tmp[0] ^= GF_XTS;
+            }
+            carry = 0;
+
+            in  += AES_BLOCK_SIZE;
+            out += AES_BLOCK_SIZE;
+            sz  -= AES_BLOCK_SIZE;
+            blocks--;
+        }
+
+        /* stealing operation of XTS to handle left overs */
+        if (sz > 0) {
+            byte buf[AES_BLOCK_SIZE];
+            byte tmp2[AES_BLOCK_SIZE];
+
+            /* multiply by shift left and propagate carry */
+            for (j = 0; j < AES_BLOCK_SIZE; j++) {
+                byte tmpC;
+
+                tmpC   = (tmp[j] >> 7) & 0x01;
+                tmp2[j] = ((tmp[j] << 1) + carry) & 0xFF;
+                carry  = tmpC;
+            }
+            if (carry) {
+                tmp2[0] ^= GF_XTS;
+            }
+
+            XMEMCPY(buf, in, AES_BLOCK_SIZE);
+            xorbuf(buf, tmp2, AES_BLOCK_SIZE);
+            wc_AesDecryptDirect(aes, out, buf);
+            xorbuf(out, tmp2, AES_BLOCK_SIZE);
+
+            /* tmp2 holds partial | last */
+            XMEMCPY(tmp2, out, AES_BLOCK_SIZE);
+            in  += AES_BLOCK_SIZE;
+            out += AES_BLOCK_SIZE;
+            sz  -= AES_BLOCK_SIZE;
+
+            /* Make buffer with end of cipher text | last */
+            XMEMCPY(buf, tmp2, AES_BLOCK_SIZE);
+            if (sz >= AES_BLOCK_SIZE) { /* extra sanity check before copy */
+                return BUFFER_E;
+            }
+            XMEMCPY(buf, in,   sz);
+            XMEMCPY(out, tmp2, sz);
+
+            xorbuf(buf, tmp, AES_BLOCK_SIZE);
+            wc_AesDecryptDirect(aes, tmp2, buf);
+            xorbuf(tmp2, tmp, AES_BLOCK_SIZE);
+            XMEMCPY(out - AES_BLOCK_SIZE, tmp2, AES_BLOCK_SIZE);
+        }
+    }
+    else {
+        WOLFSSL_MSG("Plain text input too small for encryption");
+        return BAD_FUNC_ARG;
+    }
+
+    return ret;
+}
+
+#endif /* WOLFSSL_AES_XTS */
+
+#endif /* HAVE_FIPS */
+#endif /* !NO_AES */
Index: azure_iot_hub_f767zi/trunk/wolfssl-4.4.0/wolfcrypt/src/arc4.c
===================================================================
--- azure_iot_hub_f767zi/trunk/wolfssl-4.4.0/wolfcrypt/src/arc4.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/wolfssl-4.4.0/wolfcrypt/src/arc4.c	(revision 457)
@@ -0,0 +1,149 @@
+/* arc4.c
+ *
+ * Copyright (C) 2006-2020 wolfSSL Inc.
+ *
+ * This file is part of wolfSSL.
+ *
+ * wolfSSL is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * wolfSSL is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
+ */
+
+
+#ifdef HAVE_CONFIG_H
+    #include <config.h>
+#endif
+
+#include <wolfssl/wolfcrypt/settings.h>
+
+#ifndef NO_RC4
+
+#include <wolfssl/wolfcrypt/error-crypt.h>
+#include <wolfssl/wolfcrypt/arc4.h>
+
+
+int wc_Arc4SetKey(Arc4* arc4, const byte* key, word32 length)
+{
+    int ret = 0;
+    word32 i;
+    word32 keyIndex = 0, stateIndex = 0;
+
+    if (arc4 == NULL || key == NULL || length == 0) {
+        return BAD_FUNC_ARG;
+    }
+
+#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ARC4) && \
+        defined(HAVE_CAVIUM) && !defined(HAVE_CAVIUM_V)
+    if (arc4->asyncDev.marker == WOLFSSL_ASYNC_MARKER_ARC4) {
+        return NitroxArc4SetKey(arc4, key, length);
+    }
+#endif
+
+    arc4->x = 1;
+    arc4->y = 0;
+
+    for (i = 0; i < ARC4_STATE_SIZE; i++)
+        arc4->state[i] = (byte)i;
+
+    for (i = 0; i < ARC4_STATE_SIZE; i++) {
+        word32 a = arc4->state[i];
+        stateIndex += key[keyIndex] + a;
+        stateIndex &= 0xFF;
+        arc4->state[i] = arc4->state[stateIndex];
+        arc4->state[stateIndex] = (byte)a;
+
+        if (++keyIndex >= length)
+            keyIndex = 0;
+    }
+
+    return ret;
+}
+
+
+static WC_INLINE byte MakeByte(word32* x, word32* y, byte* s)
+{
+    word32 a = s[*x], b;
+    *y = (*y+a) & 0xff;
+
+    b = s[*y];
+    s[*x] = (byte)b;
+    s[*y] = (byte)a;
+    *x = (*x+1) & 0xff;
+
+    return s[(a+b) & 0xff];
+}
+
+
+int wc_Arc4Process(Arc4* arc4, byte* out, const byte* in, word32 length)
+{
+    int ret = 0;
+    word32 x;
+    word32 y;
+
+    if (arc4 == NULL || out == NULL || in == NULL) {
+        return BAD_FUNC_ARG;
+    }
+
+#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ARC4) && \
+        defined(HAVE_CAVIUM) && !defined(HAVE_CAVIUM_V)
+    if (arc4->asyncDev.marker == WOLFSSL_ASYNC_MARKER_ARC4) {
+        return NitroxArc4Process(arc4, out, in, length);
+    }
+#endif
+
+    x = arc4->x;
+    y = arc4->y;
+
+    while(length--)
+        *out++ = *in++ ^ MakeByte(&x, &y, arc4->state);
+
+    arc4->x = (byte)x;
+    arc4->y = (byte)y;
+
+    return ret;
+}
+
+/* Initialize Arc4 for use with async device */
+int wc_Arc4Init(Arc4* arc4, void* heap, int devId)
+{
+    int ret = 0;
+
+    if (arc4 == NULL)
+        return BAD_FUNC_ARG;
+
+    arc4->heap = heap;
+
+#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ARC4)
+    ret = wolfAsync_DevCtxInit(&arc4->asyncDev, WOLFSSL_ASYNC_MARKER_ARC4,
+        arc4->heap, devId);
+#else
+    (void)devId;
+#endif /* WOLFSSL_ASYNC_CRYPT */
+
+    return ret;
+}
+
+
+/* Free Arc4 from use with async device */
+void wc_Arc4Free(Arc4* arc4)
+{
+    if (arc4 == NULL)
+        return;
+
+#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ARC4)
+    wolfAsync_DevCtxFree(&arc4->asyncDev, WOLFSSL_ASYNC_MARKER_ARC4);
+#endif /* WOLFSSL_ASYNC_CRYPT */
+}
+
+#endif /* NO_RC4 */
+
Index: azure_iot_hub_f767zi/trunk/wolfssl-4.4.0/wolfcrypt/src/asn.c
===================================================================
--- azure_iot_hub_f767zi/trunk/wolfssl-4.4.0/wolfcrypt/src/asn.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/wolfssl-4.4.0/wolfcrypt/src/asn.c	(revision 457)
@@ -0,0 +1,17525 @@
+/* asn.c
+ *
+ * Copyright (C) 2006-2020 wolfSSL Inc.
+ *
+ * This file is part of wolfSSL.
+ *
+ * wolfSSL is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * wolfSSL is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
+ */
+
+
+#ifdef HAVE_CONFIG_H
+    #include <config.h>
+#endif
+
+#include <wolfssl/wolfcrypt/settings.h>
+
+/*
+ASN Options:
+ * NO_ASN_TIME: Disables time parts of the ASN code for systems without an RTC
+    or wishing to save space.
+ * IGNORE_NAME_CONSTRAINTS: Skip ASN name checks.
+ * ASN_DUMP_OID: Allows dump of OID information for debugging.
+ * RSA_DECODE_EXTRA: Decodes extra information in RSA public key.
+ * WOLFSSL_CERT_GEN: Cert generation. Saves extra certificate info in GetName.
+ * WOLFSSL_NO_ASN_STRICT: Disable strict RFC compliance checks to
+    restore 3.13.0 behavior.
+ * WOLFSSL_NO_OCSP_OPTIONAL_CERTS: Skip optional OCSP certs (responder issuer
+    must still be trusted)
+ * WOLFSSL_NO_TRUSTED_CERTS_VERIFY: Workaround for situation where entire cert
+    chain is not loaded. This only matches on subject and public key and
+    does not perform a PKI validation, so it is not a secure solution.
+    Only enabled for OCSP.
+ * WOLFSSL_NO_OCSP_ISSUER_CHECK: Can be defined for backwards compatibility to
+    disable checking of OCSP subject hash with issuer hash.
+ * WOLFSSL_SMALL_CERT_VERIFY: Verify the certificate signature without using
+    DecodedCert. Doubles up on some code but allows smaller dynamic memory
+    usage.
+ * WOLFSSL_NO_OCSP_DATE_CHECK: Disable date checks for OCSP responses. This
+    may be required when the system's real-time clock is not very accurate.
+    It is recommended to enforce the nonce check instead if possible.
+ * WOLFSSL_FORCE_OCSP_NONCE_CHECK: Require nonces to be available in OCSP
+    responses. The nonces are optional and may not be supported by all
+    responders. If it can be ensured that the used responder sends nonces this
+    option may improve security.
+*/
+
+#ifndef NO_ASN
+
+#include <wolfssl/wolfcrypt/asn.h>
+#include <wolfssl/wolfcrypt/coding.h>
+#include <wolfssl/wolfcrypt/md2.h>
+#include <wolfssl/wolfcrypt/hmac.h>
+#include <wolfssl/wolfcrypt/error-crypt.h>
+#include <wolfssl/wolfcrypt/pwdbased.h>
+#include <wolfssl/wolfcrypt/des3.h>
+#include <wolfssl/wolfcrypt/aes.h>
+#include <wolfssl/wolfcrypt/wc_encrypt.h>
+#include <wolfssl/wolfcrypt/logging.h>
+
+#include <wolfssl/wolfcrypt/random.h>
+#include <wolfssl/wolfcrypt/hash.h>
+#ifdef NO_INLINE
+    #include <wolfssl/wolfcrypt/misc.h>
+#else
+    #define WOLFSSL_MISC_INCLUDED
+    #include <wolfcrypt/src/misc.c>
+#endif
+
+#ifndef NO_RC4
+    #include <wolfssl/wolfcrypt/arc4.h>
+#endif
+
+#ifdef HAVE_NTRU
+    #include "libntruencrypt/ntru_crypto.h"
+#endif
+
+#if defined(WOLFSSL_SHA512) || defined(WOLFSSL_SHA384)
+    #include <wolfssl/wolfcrypt/sha512.h>
+#endif
+
+#ifndef NO_SHA256
+    #include <wolfssl/wolfcrypt/sha256.h>
+#endif
+
+#ifdef HAVE_ECC
+    #include <wolfssl/wolfcrypt/ecc.h>
+#endif
+
+#ifdef HAVE_ED25519
+    #include <wolfssl/wolfcrypt/ed25519.h>
+#endif
+
+#ifdef HAVE_ED448
+    #include <wolfssl/wolfcrypt/ed448.h>
+#endif
+
+#ifndef NO_RSA
+    #include <wolfssl/wolfcrypt/rsa.h>
+#if defined(WOLFSSL_XILINX_CRYPT) || defined(WOLFSSL_CRYPTOCELL)
+extern int wc_InitRsaHw(RsaKey* key);
+#endif
+#endif
+
+#ifdef WOLF_CRYPTO_CB
+    #include <wolfssl/wolfcrypt/cryptocb.h>
+#endif
+
+#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
+    #include <wolfssl/openssl/objects.h>
+#endif
+
+#ifdef _MSC_VER
+    /* 4996 warning to use MS extensions e.g., strcpy_s instead of XSTRNCPY */
+    #pragma warning(disable: 4996)
+#endif
+
+#define ERROR_OUT(err, eLabel) { ret = (err); goto eLabel; }
+
+#if defined(HAVE_SELFTEST) || ( !defined(NO_SKID) && \
+                                ( !defined(HAVE_FIPS) || \
+                                  !defined(HAVE_FIPS_VERSION) ))
+    #ifndef WOLFSSL_AES_KEY_SIZE_ENUM
+    #define WOLFSSL_AES_KEY_SIZE_ENUM
+    enum Asn_Misc {
+        AES_IV_SIZE         = 16,
+        AES_128_KEY_SIZE    = 16,
+        AES_192_KEY_SIZE    = 24,
+        AES_256_KEY_SIZE    = 32
+    };
+    #endif
+#endif
+#ifdef WOLFSSL_RENESAS_TSIP_TLS
+void tsip_inform_key_position(const word32 key_n_start,
+                const word32 key_n_len, const word32 key_e_start,
+                const word32 key_e_len);
+int tsip_tls_CertVerify(const byte *cert, word32 certSz,
+                        const byte *signature, word32 sigSz,
+                        word32 key_n_start, word32 key_n_len,
+                        word32 key_e_start, word32 key_e_len,
+                        byte *tsip_encRsaKeyIdx);
+#endif
+int GetLength(const byte* input, word32* inOutIdx, int* len,
+                           word32 maxIdx)
+{
+    return GetLength_ex(input, inOutIdx, len, maxIdx, 1);
+}
+
+
+/* give option to check length value found against index. 1 to check 0 to not */
+int GetLength_ex(const byte* input, word32* inOutIdx, int* len,
+                           word32 maxIdx, int check)
+{
+    int     length = 0;
+    word32  idx = *inOutIdx;
+    byte    b;
+
+    *len = 0;    /* default length */
+
+    if ((idx + 1) > maxIdx) {   /* for first read */
+        WOLFSSL_MSG("GetLength bad index on input");
+        return BUFFER_E;
+    }
+
+    b = input[idx++];
+    if (b >= ASN_LONG_LENGTH) {
+        word32 bytes = b & 0x7F;
+
+        if ((idx + bytes) > maxIdx) {   /* for reading bytes */
+            WOLFSSL_MSG("GetLength bad long length");
+            return BUFFER_E;
+        }
+
+        if (bytes > sizeof(length)) {
+            return ASN_PARSE_E;
+        }
+        while (bytes--) {
+            b = input[idx++];
+            length = (length << 8) | b;
+        }
+        if (length < 0) {
+            return ASN_PARSE_E;
+        }
+    }
+    else
+        length = b;
+
+    if (check && (idx + length) > maxIdx) {   /* for user of length */
+        WOLFSSL_MSG("GetLength value exceeds buffer length");
+        return BUFFER_E;
+    }
+
+    *inOutIdx = idx;
+    if (length > 0)
+        *len = length;
+
+    return length;
+}
+
+
+/* input : buffer to read from
+ * inOutIdx : index to start reading from, gets advanced by 1 if successful
+ * maxIdx : maximum index value
+ * tag : ASN tag value found
+ *
+ * returns 0 on success
+ */
+int GetASNTag(const byte* input, word32* inOutIdx, byte* tag, word32 maxIdx)
+{
+    word32 idx;
+
+    if (tag == NULL || inOutIdx == NULL || input == NULL) {
+        return BAD_FUNC_ARG;
+    }
+
+    idx = *inOutIdx;
+    if (idx + ASN_TAG_SZ > maxIdx) {
+        WOLFSSL_MSG("Buffer too small for ASN tag");
+        return BUFFER_E;
+    }
+
+    *tag = input[idx];
+    *inOutIdx = idx + ASN_TAG_SZ;
+    return 0;
+}
+
+
+static int GetASNHeader_ex(const byte* input, byte tag, word32* inOutIdx, int* len,
+                        word32 maxIdx, int check)
+{
+    word32 idx = *inOutIdx;
+    byte   tagFound;
+    int    length;
+
+    if (GetASNTag(input, &idx, &tagFound, maxIdx) != 0)
+        return ASN_PARSE_E;
+
+    if (tagFound != tag)
+        return ASN_PARSE_E;
+
+    if (GetLength_ex(input, &idx, &length, maxIdx, check) < 0)
+        return ASN_PARSE_E;
+
+    *len      = length;
+    *inOutIdx = idx;
+    return length;
+}
+
+
+/* Get the DER/BER encoding of an ASN.1 header.
+ *
+ * input     Buffer holding DER/BER encoded data.
+ * tag       ASN.1 tag value expected in header.
+ * inOutIdx  Current index into buffer to parse.
+ * len       The number of bytes in the ASN.1 data.
+ * maxIdx    Length of data in buffer.
+ * returns BUFFER_E when there is not enough data to parse.
+ *         ASN_PARSE_E when the expected tag is not found or length is invalid.
+ *         Otherwise, the number of bytes in the ASN.1 data.
+ */
+static int GetASNHeader(const byte* input, byte tag, word32* inOutIdx, int* len,
+                        word32 maxIdx)
+{
+    return GetASNHeader_ex(input, tag, inOutIdx, len, maxIdx, 1);
+}
+
+static int GetHeader(const byte* input, byte* tag, word32* inOutIdx, int* len,
+                     word32 maxIdx, int check)
+{
+    word32 idx = *inOutIdx;
+    int    length;
+
+    if ((idx + 1) > maxIdx)
+        return BUFFER_E;
+
+    *tag = input[idx++];
+
+    if (GetLength_ex(input, &idx, &length, maxIdx, check) < 0)
+        return ASN_PARSE_E;
+
+    *len      = length;
+    *inOutIdx = idx;
+    return length;
+}
+
+int GetSequence(const byte* input, word32* inOutIdx, int* len,
+                           word32 maxIdx)
+{
+    return GetASNHeader(input, ASN_SEQUENCE | ASN_CONSTRUCTED, inOutIdx, len,
+                        maxIdx);
+}
+
+
+int GetSequence_ex(const byte* input, word32* inOutIdx, int* len,
+                           word32 maxIdx, int check)
+{
+    return GetASNHeader_ex(input, ASN_SEQUENCE | ASN_CONSTRUCTED, inOutIdx, len,
+                        maxIdx, check);
+}
+
+
+int GetSet(const byte* input, word32* inOutIdx, int* len,
+                        word32 maxIdx)
+{
+    return GetASNHeader(input, ASN_SET | ASN_CONSTRUCTED, inOutIdx, len,
+                        maxIdx);
+}
+
+
+int GetSet_ex(const byte* input, word32* inOutIdx, int* len,
+                        word32 maxIdx, int check)
+{
+    return GetASNHeader_ex(input, ASN_SET | ASN_CONSTRUCTED, inOutIdx, len,
+                        maxIdx, check);
+}
+
+/* Get the DER/BER encoded ASN.1 NULL element.
+ * Ensure that the all fields are as expected and move index past the element.
+ *
+ * input     Buffer holding DER/BER encoded data.
+ * inOutIdx  Current index into buffer to parse.
+ * maxIdx    Length of data in buffer.
+ * returns BUFFER_E when there is not enough data to parse.
+ *         ASN_TAG_NULL_E when the NULL tag is not found.
+ *         ASN_EXPECT_0_E when the length is not zero.
+ *         Otherwise, 0 to indicate success.
+ */
+static int GetASNNull(const byte* input, word32* inOutIdx, word32 maxIdx)
+{
+    word32 idx = *inOutIdx;
+    byte   b;
+
+    if ((idx + 2) > maxIdx)
+        return BUFFER_E;
+
+    b = input[idx++];
+    if (b != ASN_TAG_NULL)
+        return ASN_TAG_NULL_E;
+
+    if (input[idx++] != 0)
+        return ASN_EXPECT_0_E;
+
+    *inOutIdx = idx;
+    return 0;
+}
+
+/* Set the DER/BER encoding of the ASN.1 NULL element.
+ *
+ * output  Buffer to write into.
+ * returns the number of bytes added to the buffer.
+ */
+static int SetASNNull(byte* output)
+{
+    output[0] = ASN_TAG_NULL;
+    output[1] = 0;
+
+    return 2;
+}
+
+/* Get the DER/BER encoding of an ASN.1 BOOLEAN.
+ *
+ * input     Buffer holding DER/BER encoded data.
+ * inOutIdx  Current index into buffer to parse.
+ * maxIdx    Length of data in buffer.
+ * returns BUFFER_E when there is not enough data to parse.
+ *         ASN_PARSE_E when the BOOLEAN tag is not found or length is not 1.
+ *         Otherwise, 0 to indicate the value was false and 1 to indicate true.
+ */
+static int GetBoolean(const byte* input, word32* inOutIdx, word32 maxIdx)
+{
+    word32 idx = *inOutIdx;
+    byte   b;
+
+    if ((idx + 3) > maxIdx)
+        return BUFFER_E;
+
+    b = input[idx++];
+    if (b != ASN_BOOLEAN)
+        return ASN_PARSE_E;
+
+    if (input[idx++] != 1)
+        return ASN_PARSE_E;
+
+    b = input[idx++] != 0;
+
+    *inOutIdx = idx;
+    return b;
+}
+
+#ifdef ASN1_SET_BOOLEAN
+/* Set the DER/BER encoding of the ASN.1 NULL element.
+ * Note: Function not required as yet.
+ *
+ * val     Boolean value to encode.
+ * output  Buffer to write into.
+ * returns the number of bytes added to the buffer.
+ */
+static int SetBoolean(int val, byte* output)
+{
+    output[0] = ASN_BOOLEAN;
+    output[1] = 1;
+    output[2] = val ? -1 : 0;
+
+    return 3;
+}
+#endif
+
+/* Get the DER/BER encoding of an ASN.1 OCTET_STRING header.
+ *
+ * input     Buffer holding DER/BER encoded data.
+ * inOutIdx  Current index into buffer to parse.
+ * len       The number of bytes in the ASN.1 data.
+ * maxIdx    Length of data in buffer.
+ * returns BUFFER_E when there is not enough data to parse.
+ *         ASN_PARSE_E when the OCTET_STRING tag is not found or length is
+ *         invalid.
+ *         Otherwise, the number of bytes in the ASN.1 data.
+ */
+int GetOctetString(const byte* input, word32* inOutIdx, int* len,
+                          word32 maxIdx)
+{
+    return GetASNHeader(input, ASN_OCTET_STRING, inOutIdx, len, maxIdx);
+}
+
+/* Get the DER/BER encoding of an ASN.1 INTEGER header.
+ * Removes the leading zero byte when found.
+ *
+ * input     Buffer holding DER/BER encoded data.
+ * inOutIdx  Current index into buffer to parse.
+ * len       The number of bytes in the ASN.1 data (excluding any leading zero).
+ * maxIdx    Length of data in buffer.
+ * returns BUFFER_E when there is not enough data to parse.
+ *         ASN_PARSE_E when the INTEGER tag is not found, length is invalid,
+ *         or invalid use of or missing leading zero.
+ *         Otherwise, 0 to indicate success.
+ */
+static int GetASNInt(const byte* input, word32* inOutIdx, int* len,
+                     word32 maxIdx)
+{
+    int    ret;
+
+    ret = GetASNHeader(input, ASN_INTEGER, inOutIdx, len, maxIdx);
+    if (ret < 0)
+        return ret;
+
+    if (*len > 0) {
+        /* remove leading zero, unless there is only one 0x00 byte */
+        if ((input[*inOutIdx] == 0x00) && (*len > 1)) {
+            (*inOutIdx)++;
+            (*len)--;
+
+            if (*len > 0 && (input[*inOutIdx] & 0x80) == 0)
+                return ASN_PARSE_E;
+        }
+    }
+
+    return 0;
+}
+
+/* Get the DER/BER encoding of an ASN.1 INTEGER that has a value of no more than
+ * 7 bits.
+ *
+ * input     Buffer holding DER/BER encoded data.
+ * inOutIdx  Current index into buffer to parse.
+ * maxIdx    Length of data in buffer.
+ * returns BUFFER_E when there is not enough data to parse.
+ *         ASN_PARSE_E when the INTEGER tag is not found or length is invalid.
+ *         Otherwise, the 7-bit value.
+ */
+static int GetInteger7Bit(const byte* input, word32* inOutIdx, word32 maxIdx)
+{
+    word32 idx = *inOutIdx;
+    byte   b;
+
+    if ((idx + 3) > maxIdx)
+        return BUFFER_E;
+
+    if (GetASNTag(input, &idx, &b, maxIdx) != 0)
+        return ASN_PARSE_E;
+    if (b != ASN_INTEGER)
+        return ASN_PARSE_E;
+    if (input[idx++] != 1)
+        return ASN_PARSE_E;
+    b = input[idx++];
+
+    *inOutIdx = idx;
+    return b;
+}
+
+
+#if !defined(NO_DSA) && !defined(NO_SHA)
+static const char sigSha1wDsaName[] = "SHAwDSA";
+#endif /* NO_DSA */
+#ifndef NO_RSA
+#ifdef WOLFSSL_MD2
+    static const char  sigMd2wRsaName[] = "md2WithRSAEncryption";
+#endif
+#ifndef NO_MD5
+    static const char  sigMd5wRsaName[] = "md5WithRSAEncryption";
+#endif
+#ifndef NO_SHA
+    static const char  sigSha1wRsaName[] = "sha1WithRSAEncryption";
+#endif
+#ifdef WOLFSSL_SHA224
+    static const char sigSha224wRsaName[] = "sha224WithRSAEncryption";
+#endif
+#ifndef NO_SHA256
+    static const char sigSha256wRsaName[] = "sha256WithRSAEncryption";
+#endif
+#ifdef WOLFSSL_SHA384
+    static const char sigSha384wRsaName[] = "sha384WithRSAEncryption";
+#endif
+#ifdef WOLFSSL_SHA512
+    static const char sigSha512wRsaName[] = "sha512WithRSAEncryption";
+#endif
+#endif /* NO_RSA */
+#ifdef HAVE_ECC
+#ifndef NO_SHA
+    static const char sigSha1wEcdsaName[] = "SHAwECDSA";
+#endif
+#ifdef WOLFSSL_SHA224
+    static const char sigSha224wEcdsaName[] = "SHA224wECDSA";
+#endif
+#ifndef NO_SHA256
+    static const char sigSha256wEcdsaName[] = "SHA256wECDSA";
+#endif
+#ifdef WOLFSSL_SHA384
+    static const char sigSha384wEcdsaName[] = "SHA384wECDSA";
+#endif
+#ifdef WOLFSSL_SHA512
+    static const char sigSha512wEcdsaName[] = "SHA512wECDSA";
+#endif
+#endif /* HAVE_ECC */
+static const char sigUnknownName[] = "Unknown";
+
+
+/* Get the human readable string for a signature type
+ *
+ * oid  Oid value for signature
+ */
+const char* GetSigName(int oid) {
+    switch (oid) {
+    #if !defined(NO_DSA) && !defined(NO_SHA)
+        case CTC_SHAwDSA:
+            return sigSha1wDsaName;
+    #endif /* NO_DSA && NO_SHA */
+    #ifndef NO_RSA
+        #ifdef WOLFSSL_MD2
+        case CTC_MD2wRSA:
+            return sigMd2wRsaName;
+        #endif
+        #ifndef NO_MD5
+        case CTC_MD5wRSA:
+            return sigMd5wRsaName;
+        #endif
+        #ifndef NO_SHA
+        case CTC_SHAwRSA:
+            return sigSha1wRsaName;
+        #endif
+        #ifdef WOLFSSL_SHA224
+        case CTC_SHA224wRSA:
+            return sigSha224wRsaName;
+        #endif
+        #ifndef NO_SHA256
+        case CTC_SHA256wRSA:
+            return sigSha256wRsaName;
+        #endif
+        #ifdef WOLFSSL_SHA384
+        case CTC_SHA384wRSA:
+            return sigSha384wRsaName;
+        #endif
+        #ifdef WOLFSSL_SHA512
+        case CTC_SHA512wRSA:
+            return sigSha512wRsaName;
+        #endif
+    #endif /* NO_RSA */
+    #ifdef HAVE_ECC
+        #ifndef NO_SHA
+        case CTC_SHAwECDSA:
+            return sigSha1wEcdsaName;
+        #endif
+        #ifdef WOLFSSL_SHA224
+        case CTC_SHA224wECDSA:
+            return sigSha224wEcdsaName;
+        #endif
+        #ifndef NO_SHA256
+        case CTC_SHA256wECDSA:
+            return sigSha256wEcdsaName;
+        #endif
+        #ifdef WOLFSSL_SHA384
+        case CTC_SHA384wECDSA:
+            return sigSha384wEcdsaName;
+        #endif
+        #ifdef WOLFSSL_SHA512
+        case CTC_SHA512wECDSA:
+            return sigSha512wEcdsaName;
+        #endif
+    #endif /* HAVE_ECC */
+        default:
+            return sigUnknownName;
+    }
+}
+
+
+#if !defined(NO_DSA) || defined(HAVE_ECC) || !defined(NO_CERTS) || \
+   (!defined(NO_RSA) && \
+        (defined(WOLFSSL_CERT_GEN) || \
+        ((defined(WOLFSSL_KEY_GEN) || defined(OPENSSL_EXTRA)) && !defined(HAVE_USER_RSA))))
+/* Set the DER/BER encoding of the ASN.1 INTEGER header.
+ *
+ * len        Length of data to encode.
+ * firstByte  First byte of data, most significant byte of integer, to encode.
+ * output     Buffer to write into.
+ * returns the number of bytes added to the buffer.
+ */
+static int SetASNInt(int len, byte firstByte, byte* output)
+{
+    word32 idx = 0;
+
+    if (output)
+        output[idx] = ASN_INTEGER;
+    idx++;
+    if (firstByte & 0x80)
+        len++;
+    idx += SetLength(len, output ? output + idx : NULL);
+    if (firstByte & 0x80) {
+        if (output)
+            output[idx] = 0x00;
+        idx++;
+    }
+
+    return idx;
+}
+#endif
+
+#if !defined(NO_DSA) || defined(HAVE_ECC) || (defined(WOLFSSL_CERT_GEN) && \
+    !defined(NO_RSA)) || ((defined(WOLFSSL_KEY_GEN) || \
+    defined(OPENSSL_EXTRA)) && !defined(NO_RSA) && !defined(HAVE_USER_RSA))
+/* Set the DER/BER encoding of the ASN.1 INTEGER element with an mp_int.
+ * The number is assumed to be positive.
+ *
+ * n       Multi-precision integer to encode.
+ * maxSz   Maximum size of the encoded integer.
+ *         A negative value indicates no check of length requested.
+ * output  Buffer to write into.
+ * returns BUFFER_E when the data is too long for the buffer.
+ *         MP_TO_E when encoding the integer fails.
+ *         Otherwise, the number of bytes added to the buffer.
+ */
+static int SetASNIntMP(mp_int* n, int maxSz, byte* output)
+{
+    int idx = 0;
+    int leadingBit;
+    int length;
+    int err;
+
+    leadingBit = mp_leading_bit(n);
+    length = mp_unsigned_bin_size(n);
+    idx = SetASNInt(length, leadingBit ? 0x80 : 0x00, output);
+    if (maxSz >= 0 && (idx + length) > maxSz)
+        return BUFFER_E;
+
+    if (output) {
+        err = mp_to_unsigned_bin(n, output + idx);
+        if (err != MP_OKAY)
+            return MP_TO_E;
+    }
+    idx += length;
+
+    return idx;
+}
+#endif
+
+#if !defined(NO_RSA) && defined(HAVE_USER_RSA) && \
+    (defined(WOLFSSL_CERT_GEN) || defined(OPENSSL_EXTRA))
+/* Set the DER/BER encoding of the ASN.1 INTEGER element with an mp_int from
+ * an RSA key.
+ * The number is assumed to be positive.
+ *
+ * n       Multi-precision integer to encode.
+ * output  Buffer to write into.
+ * returns BUFFER_E when the data is too long for the buffer.
+ *         MP_TO_E when encoding the integer fails.
+ *         Otherwise, the number of bytes added to the buffer.
+ */
+static int SetASNIntRSA(void* n, byte* output)
+{
+    int idx = 0;
+    int leadingBit;
+    int length;
+    int err;
+
+    leadingBit = wc_Rsa_leading_bit(n);
+    length = wc_Rsa_unsigned_bin_size(n);
+    idx = SetASNInt(length, leadingBit ? 0x80 : 0x00, output);
+    if ((idx + length) > MAX_RSA_INT_SZ)
+        return BUFFER_E;
+
+    if (output) {
+        err = wc_Rsa_to_unsigned_bin(n, output + idx, length);
+        if (err != MP_OKAY)
+            return MP_TO_E;
+    }
+    idx += length;
+
+    return idx;
+}
+#endif /* !NO_RSA && HAVE_USER_RSA && WOLFSSL_CERT_GEN */
+
+/* Windows header clash for WinCE using GetVersion */
+int GetMyVersion(const byte* input, word32* inOutIdx,
+                               int* version, word32 maxIdx)
+{
+    word32 idx = *inOutIdx;
+    byte   tag;
+
+    if ((idx + MIN_VERSION_SZ) > maxIdx)
+        return ASN_PARSE_E;
+
+    if (GetASNTag(input, &idx, &tag, maxIdx) != 0)
+        return ASN_PARSE_E;
+
+    if (tag != ASN_INTEGER)
+        return ASN_PARSE_E;
+
+    if (input[idx++] != 0x01)
+        return ASN_VERSION_E;
+
+    *version  = input[idx++];
+    *inOutIdx = idx;
+
+    return *version;
+}
+
+
+#ifndef NO_PWDBASED
+/* Get small count integer, 32 bits or less */
+int GetShortInt(const byte* input, word32* inOutIdx, int* number, word32 maxIdx)
+{
+    word32 idx = *inOutIdx;
+    word32 len;
+    byte   tag;
+
+    *number = 0;
+
+    /* check for type and length bytes */
+    if ((idx + 2) > maxIdx)
+        return BUFFER_E;
+
+    if (GetASNTag(input, &idx, &tag, maxIdx) != 0)
+        return ASN_PARSE_E;
+
+    if (tag != ASN_INTEGER)
+        return ASN_PARSE_E;
+
+    len = input[idx++];
+    if (len > 4)
+        return ASN_PARSE_E;
+
+    if (len + idx > maxIdx)
+        return ASN_PARSE_E;
+
+    while (len--) {
+        *number  = *number << 8 | input[idx++];
+    }
+
+    *inOutIdx = idx;
+
+    return *number;
+}
+
+
+/* Set small integer, 32 bits or less. DER encoding with no leading 0s
+ * returns total amount written including ASN tag and length byte on success */
+int SetShortInt(byte* input, word32* inOutIdx, word32 number, word32 maxIdx)
+{
+    word32 idx = *inOutIdx;
+    word32 len = 0;
+    int    i;
+    byte ar[MAX_LENGTH_SZ];
+
+    /* check for room for type and length bytes */
+    if ((idx + 2) > maxIdx)
+        return BUFFER_E;
+
+    input[idx++] = ASN_INTEGER;
+    idx++; /* place holder for length byte */
+    if (MAX_LENGTH_SZ + idx > maxIdx)
+        return ASN_PARSE_E;
+
+    /* find first non zero byte */
+    XMEMSET(ar, 0, MAX_LENGTH_SZ);
+    c32toa(number, ar);
+    for (i = 0; i < MAX_LENGTH_SZ; i++) {
+        if (ar[i] != 0) {
+            break;
+        }
+    }
+
+    /* handle case of 0 */
+    if (i == MAX_LENGTH_SZ) {
+        input[idx++] = 0; len++;
+    }
+
+    for (; i < MAX_LENGTH_SZ && idx < maxIdx; i++) {
+        input[idx++] = ar[i]; len++;
+    }
+
+    /* jump back to beginning of input buffer using unaltered inOutIdx value
+     * and set number of bytes for integer, then update the index value */
+    input[*inOutIdx + 1] = (byte)len;
+    *inOutIdx = idx;
+
+    return len + 2; /* size of integer bytes plus ASN TAG and length byte */
+}
+#endif /* !NO_PWDBASED */
+
+/* May not have one, not an error */
+static int GetExplicitVersion(const byte* input, word32* inOutIdx, int* version,
+                              word32 maxIdx)
+{
+    word32 idx = *inOutIdx;
+    byte tag;
+
+    WOLFSSL_ENTER("GetExplicitVersion");
+
+    if (GetASNTag(input, &idx, &tag, maxIdx) != 0)
+        return ASN_PARSE_E;
+
+    if (tag == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED)) {
+        *inOutIdx = ++idx;  /* skip header */
+        return GetMyVersion(input, inOutIdx, version, maxIdx);
+    }
+
+    /* go back as is */
+    *version = 0;
+
+    return 0;
+}
+
+int GetInt(mp_int* mpi, const byte* input, word32* inOutIdx, word32 maxIdx)
+{
+    word32 idx = *inOutIdx;
+    int    ret;
+    int    length;
+
+    ret = GetASNInt(input, &idx, &length, maxIdx);
+    if (ret != 0)
+        return ret;
+
+    if (mp_init(mpi) != MP_OKAY)
+        return MP_INIT_E;
+
+    if (mp_read_unsigned_bin(mpi, (byte*)input + idx, length) != 0) {
+        mp_clear(mpi);
+        return ASN_GETINT_E;
+    }
+
+#ifdef HAVE_WOLF_BIGINT
+    if (wc_bigint_from_unsigned_bin(&mpi->raw, input + idx, length) != 0) {
+        mp_clear(mpi);
+        return ASN_GETINT_E;
+    }
+#endif /* HAVE_WOLF_BIGINT */
+
+    *inOutIdx = idx + length;
+
+    return 0;
+}
+
+#if (!defined(WOLFSSL_KEY_GEN) && !defined(OPENSSL_EXTRA) && defined(RSA_LOW_MEM)) \
+    || defined(WOLFSSL_RSA_PUBLIC_ONLY) || (!defined(NO_DSA) && defined(WOLFSSL_QT))
+#if !defined(NO_RSA) && !defined(HAVE_USER_RSA)
+static int SkipInt(const byte* input, word32* inOutIdx, word32 maxIdx)
+{
+    word32 idx = *inOutIdx;
+    int    ret;
+    int    length;
+
+    ret = GetASNInt(input, &idx, &length, maxIdx);
+    if (ret != 0)
+        return ret;
+
+    *inOutIdx = idx + length;
+
+    return 0;
+}
+#endif
+#endif
+
+static int CheckBitString(const byte* input, word32* inOutIdx, int* len,
+                          word32 maxIdx, int zeroBits, byte* unusedBits)
+{
+    word32 idx = *inOutIdx;
+    int    length;
+    byte   b;
+
+    if (GetASNTag(input, &idx, &b, maxIdx) != 0) {
+        return ASN_BITSTR_E;
+    }
+
+    if (b != ASN_BIT_STRING) {
+        return ASN_BITSTR_E;
+    }
+
+    if (GetLength(input, &idx, &length, maxIdx) < 0)
+        return ASN_PARSE_E;
+
+    /* extra sanity check that length is greater than 0 */
+    if (length <= 0) {
+        WOLFSSL_MSG("Error length was 0 in CheckBitString");
+        return BUFFER_E;
+    }
+
+    if (idx + 1 > maxIdx) {
+        WOLFSSL_MSG("Attempted buffer read larger than input buffer");
+        return BUFFER_E;
+    }
+
+    b = input[idx];
+    if (zeroBits && b != 0x00)
+        return ASN_EXPECT_0_E;
+    if (b >= 0x08)
+        return ASN_PARSE_E;
+    if (b != 0) {
+        if ((byte)(input[idx + length - 1] << (8 - b)) != 0)
+            return ASN_PARSE_E;
+    }
+    idx++;
+    length--; /* length has been checked for greater than 0 */
+
+    *inOutIdx = idx;
+    if (len != NULL)
+        *len = length;
+    if (unusedBits != NULL)
+        *unusedBits = b;
+
+    return 0;
+}
+
+/* RSA (with CertGen or KeyGen) OR ECC OR ED25519 OR ED448 (with CertGen or
+ * KeyGen) */
+#if (!defined(NO_RSA) && !defined(HAVE_USER_RSA) && \
+        (defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_KEY_GEN) || defined(OPENSSL_EXTRA))) || \
+    (defined(HAVE_ECC) && defined(HAVE_ECC_KEY_EXPORT)) || \
+    ((defined(HAVE_ED25519) || defined(HAVE_ED448)) && \
+        (defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_KEY_GEN) || defined(OPENSSL_EXTRA)))
+
+/* Set the DER/BER encoding of the ASN.1 BIT_STRING header.
+ *
+ * len         Length of data to encode.
+ * unusedBits  The number of unused bits in the last byte of data.
+ *             That is, the number of least significant zero bits before a one.
+ *             The last byte is the most-significant non-zero byte of a number.
+ * output      Buffer to write into.
+ * returns the number of bytes added to the buffer.
+ */
+word32 SetBitString(word32 len, byte unusedBits, byte* output)
+{
+    word32 idx = 0;
+
+    if (output)
+        output[idx] = ASN_BIT_STRING;
+    idx++;
+
+    idx += SetLength(len + 1, output ? output + idx : NULL);
+    if (output)
+        output[idx] = unusedBits;
+    idx++;
+
+    return idx;
+}
+#endif /* !NO_RSA || HAVE_ECC || HAVE_ED25519 || HAVE_ED448 */
+
+#ifdef ASN_BER_TO_DER
+/* Pull informtation from the ASN.1 BER encoded item header */
+static int GetBerHeader(const byte* data, word32* idx, word32 maxIdx,
+                        byte* pTag, word32* pLen, int* indef)
+{
+    int len = 0;
+    byte tag;
+    word32 i = *idx;
+
+    *indef = 0;
+
+    /* Check there is enough data for a minimal header */
+    if (i + 2 > maxIdx) {
+        return ASN_PARSE_E;
+    }
+
+    /* Retrieve tag */
+    tag = data[i++];
+
+    /* Indefinite length handled specially */
+    if (data[i] == 0x80) {
+        /* Check valid tag for indefinite */
+        if (((tag & 0xc0) == 0) && ((tag & ASN_CONSTRUCTED) == 0x00)) {
+            return ASN_PARSE_E;
+        }
+        i++;
+        *indef = 1;
+    }
+    else if (GetLength(data, &i, &len, maxIdx) < 0) {
+        return ASN_PARSE_E;
+    }
+
+    /* Return tag, length and index after BER item header */
+    *pTag = tag;
+    *pLen = len;
+    *idx = i;
+    return 0;
+}
+
+#ifndef INDEF_ITEMS_MAX
+#define INDEF_ITEMS_MAX       20
+#endif
+
+/* Indef length item data */
+typedef struct Indef {
+    word32 start;
+    int depth;
+    int headerLen;
+    word32 len;
+} Indef;
+
+/* Indef length items */
+typedef struct IndefItems
+{
+    Indef len[INDEF_ITEMS_MAX];
+    int cnt;
+    int idx;
+    int depth;
+} IndefItems;
+
+
+/* Get header length of current item */
+static int IndefItems_HeaderLen(IndefItems* items)
+{
+    return items->len[items->idx].headerLen;
+}
+
+/* Get data length of current item */
+static word32 IndefItems_Len(IndefItems* items)
+{
+    return items->len[items->idx].len;
+}
+
+/* Add a indefinite length item */
+static int IndefItems_AddItem(IndefItems* items, word32 start)
+{
+    int ret = 0;
+    int i;
+
+    if (items->cnt == INDEF_ITEMS_MAX) {
+        ret = MEMORY_E;
+    }
+    else {
+        i = items->cnt++;
+        items->len[i].start = start;
+        items->len[i].depth = items->depth++;
+        items->len[i].headerLen = 1;
+        items->len[i].len = 0;
+        items->idx = i;
+    }
+
+    return ret;
+}
+
+/* Increase data length of current item */
+static void IndefItems_AddData(IndefItems* items, word32 length)
+{
+    items->len[items->idx].len += length;
+}
+
+/* Update header length of current item to reflect data length */
+static void IndefItems_UpdateHeaderLen(IndefItems* items)
+{
+    items->len[items->idx].headerLen +=
+                                    SetLength(items->len[items->idx].len, NULL);
+}
+
+/* Go to indefinite parent of current item */
+static void IndefItems_Up(IndefItems* items)
+{
+    int i;
+    int depth = items->len[items->idx].depth - 1;
+
+    for (i = items->cnt - 1; i >= 0; i--) {
+        if (items->len[i].depth == depth) {
+            break;
+        }
+    }
+    items->idx = i;
+    items->depth = depth + 1;
+}
+
+/* Calculate final length by adding length of indefinite child items */
+static void IndefItems_CalcLength(IndefItems* items)
+{
+    int i;
+    int idx = items->idx;
+
+    for (i = idx + 1; i < items->cnt; i++) {
+        if (items->len[i].depth == items->depth) {
+            items->len[idx].len += items->len[i].headerLen;
+            items->len[idx].len += items->len[i].len;
+        }
+    }
+    items->len[idx].headerLen += SetLength(items->len[idx].len, NULL);
+}
+
+/* Add more data to indefinite length item */
+static void IndefItems_MoreData(IndefItems* items, word32 length)
+{
+    if (items->cnt > 0 && items->idx >= 0) {
+        items->len[items->idx].len += length;
+    }
+}
+
+/* Convert a BER encoding with indefinite length items to DER.
+ *
+ * ber    BER encoded data.
+ * berSz  Length of BER encoded data.
+ * der    Buffer to hold DER encoded version of data.
+ *        NULL indicates only the length is required.
+ * derSz  The size of the buffer to hold the DER encoded data.
+ *        Will be set if der is NULL, otherwise the value is checked as der is
+ *        filled.
+ * returns ASN_PARSE_E if the BER data is invalid and BAD_FUNC_ARG if ber or
+ * derSz are NULL.
+ */
+int wc_BerToDer(const byte* ber, word32 berSz, byte* der, word32* derSz)
+{
+    int ret = 0;
+    word32 i, j;
+#ifdef WOLFSSL_SMALL_STACK
+    IndefItems* indefItems = NULL;
+#else
+    IndefItems indefItems[1];
+#endif
+    byte tag, basic;
+    word32 length;
+    int indef;
+
+    if (ber == NULL || derSz == NULL)
+        return BAD_FUNC_ARG;
+
+#ifdef WOLFSSL_SMALL_STACK
+    indefItems = XMALLOC(sizeof(IndefItems), NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    if (indefItems == NULL) {
+        ret = MEMORY_E;
+        goto end;
+    }
+#endif
+
+    XMEMSET(indefItems, 0, sizeof(*indefItems));
+
+    /* Calculate indefinite item lengths */
+    for (i = 0; i < berSz; ) {
+        word32 start = i;
+
+        /* Get next BER item */
+        ret = GetBerHeader(ber, &i, berSz, &tag, &length, &indef);
+        if (ret != 0) {
+            goto end;
+        }
+
+        if (indef) {
+            /* Indefinite item - add to list */
+            ret = IndefItems_AddItem(indefItems, i);
+            if (ret != 0) {
+                goto end;
+            }
+
+            if ((tag & 0xC0) == 0 &&
+                tag != (ASN_SEQUENCE | ASN_CONSTRUCTED) &&
+                tag != (ASN_SET      | ASN_CONSTRUCTED)) {
+                /* Constructed basic type - get repeating tag */
+                basic = tag & (~ASN_CONSTRUCTED);
+
+                /* Add up lengths of each item below */
+                for (; i < berSz; ) {
+                    /* Get next BER_item */
+                    ret = GetBerHeader(ber, &i, berSz, &tag, &length, &indef);
+                    if (ret != 0) {
+                        goto end;
+                    }
+
+                    /* End of content closes item */
+                    if (tag == ASN_EOC) {
+                        /* Must be zero length */
+                        if (length != 0) {
+                            ret = ASN_PARSE_E;
+                            goto end;
+                        }
+                        break;
+                    }
+
+                    /* Must not be indefinite and tag must match parent */
+                    if (indef || tag != basic) {
+                        ret = ASN_PARSE_E;
+                        goto end;
+                    }
+
+                    /* Add to length */
+                    IndefItems_AddData(indefItems, length);
+                    /* Skip data */
+                    i += length;
+                }
+
+                /* Ensure we got an EOC and not end of data */
+                if (tag != ASN_EOC) {
+                    ret = ASN_PARSE_E;
+                    goto end;
+                }
+
+                /* Set the header length to include the length field */
+                IndefItems_UpdateHeaderLen(indefItems);
+                /* Go to indefinte parent item */
+                IndefItems_Up(indefItems);
+            }
+        }
+        else if (tag == ASN_EOC) {
+            /* End-of-content must be 0 length */
+            if (length != 0) {
+                ret = ASN_PARSE_E;
+                goto end;
+            }
+            /* Check there is an item to close - missing EOC */
+            if (indefItems->depth == 0) {
+                ret = ASN_PARSE_E;
+                goto end;
+            }
+
+            /* Finish calculation of data length for indefinite item */
+            IndefItems_CalcLength(indefItems);
+            /* Go to indefinte parent item */
+            IndefItems_Up(indefItems);
+        }
+        else {
+            /* Known length item to add in - make sure enough data for it */
+            if (i + length > berSz) {
+                ret = ASN_PARSE_E;
+                goto end;
+            }
+
+            /* Include all data - can't have indefinite inside definite */
+            i += length;
+            /* Add entire item to current indefinite item */
+            IndefItems_MoreData(indefItems, i - start);
+        }
+    }
+    /* Check we had a EOC for each indefinite item */
+    if (indefItems->depth != 0) {
+        ret = ASN_PARSE_E;
+        goto end;
+    }
+
+    /* Write out DER */
+
+    j = 0;
+    /* Reset index */
+    indefItems->idx = 0;
+    for (i = 0; i < berSz; ) {
+        word32 start = i;
+
+        /* Get item - checked above */
+        (void)GetBerHeader(ber, &i, berSz, &tag, &length, &indef);
+        if (indef) {
+            if (der != NULL) {
+                /* Check enough space for header */
+                if (j + IndefItems_HeaderLen(indefItems) > *derSz) {
+                    ret = BUFFER_E;
+                    goto end;
+                }
+
+                if ((tag & 0xC0) == 0 &&
+                    tag != (ASN_SEQUENCE | ASN_CONSTRUCTED) &&
+                    tag != (ASN_SET      | ASN_CONSTRUCTED)) {
+                    /* Remove constructed tag for basic types */
+                    tag &= ~ASN_CONSTRUCTED;
+                }
+                /* Add tag and length */
+                der[j] = tag;
+                (void)SetLength(IndefItems_Len(indefItems), der + j + 1);
+            }
+            /* Add header length of indefinite item */
+            j += IndefItems_HeaderLen(indefItems);
+
+            if ((tag & 0xC0) == 0 &&
+                tag != (ASN_SEQUENCE | ASN_CONSTRUCTED) &&
+                tag != (ASN_SET      | ASN_CONSTRUCTED)) {
+                /* For basic type - get each child item and add data */
+                for (; i < berSz; ) {
+                    (void)GetBerHeader(ber, &i, berSz, &tag, &length, &indef);
+                    if (tag == ASN_EOC) {
+                        break;
+                    }
+                    if (der != NULL) {
+                        if (j + length > *derSz) {
+                            ret = BUFFER_E;
+                            goto end;
+                        }
+                        XMEMCPY(der + j, ber + i, length);
+                    }
+                    j += length;
+                    i += length;
+                }
+            }
+
+            /* Move to next indef item in list */
+            indefItems->idx++;
+        }
+        else if (tag == ASN_EOC) {
+            /* End-Of-Content is not written out in DER */
+        }
+        else {
+            /* Write out definite length item as is. */
+            i += length;
+            if (der != NULL) {
+                /* Ensure space for item */
+                if (j + i - start > *derSz) {
+                    ret = BUFFER_E;
+                    goto end;
+                }
+                /* Copy item as is */
+                XMEMCPY(der + j, ber + start, i - start);
+            }
+            j += i - start;
+        }
+    }
+
+    /* Return the length of the DER encoded ASN.1 */
+    *derSz = j;
+    if (der == NULL) {
+        ret = LENGTH_ONLY_E;
+    }
+end:
+#ifdef WOLFSSL_SMALL_STACK
+    if (indefItems != NULL) {
+        XFREE(indefItems, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    }
+#endif
+    return ret;
+}
+#endif
+
+#if defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_KEY_GEN)
+
+#if (!defined(NO_RSA) && !defined(HAVE_USER_RSA)) || \
+    defined(HAVE_ECC) || defined(HAVE_ED25519) || defined(HAVE_ED448)
+
+#ifdef WOLFSSL_CERT_EXT
+/* Set the DER/BER encoding of the ASN.1 BIT_STRING with a 16-bit value.
+ *
+ * val         16-bit value to encode.
+ * output      Buffer to write into.
+ * returns the number of bytes added to the buffer.
+ */
+static word32 SetBitString16Bit(word16 val, byte* output)
+{
+    word32 idx;
+    int    len;
+    byte   lastByte;
+    byte   unusedBits = 0;
+
+    if ((val >> 8) != 0) {
+        len = 2;
+        lastByte = (byte)(val >> 8);
+    }
+    else {
+        len = 1;
+        lastByte = (byte)val;
+    }
+
+    while (((lastByte >> unusedBits) & 0x01) == 0x00)
+        unusedBits++;
+
+    idx = SetBitString(len, unusedBits, output);
+    output[idx++] = (byte)val;
+    if (len > 1)
+        output[idx++] = (byte)(val >> 8);
+
+    return idx;
+}
+#endif /* WOLFSSL_CERT_EXT */
+#endif /* !NO_RSA || HAVE_ECC || HAVE_ED25519 || defined(HAVE_ED448) */
+#endif /* WOLFSSL_CERT_GEN || WOLFSSL_KEY_GEN */
+
+
+
+/* hashType */
+#ifdef WOLFSSL_MD2
+    static const byte hashMd2hOid[] = {42, 134, 72, 134, 247, 13, 2, 2};
+#endif
+#ifndef NO_MD5
+    static const byte hashMd5hOid[] = {42, 134, 72, 134, 247, 13, 2, 5};
+#endif
+#ifndef NO_SHA
+    static const byte hashSha1hOid[] = {43, 14, 3, 2, 26};
+#endif
+#ifdef WOLFSSL_SHA224
+    static const byte hashSha224hOid[] = {96, 134, 72, 1, 101, 3, 4, 2, 4};
+#endif
+#ifndef NO_SHA256
+    static const byte hashSha256hOid[] = {96, 134, 72, 1, 101, 3, 4, 2, 1};
+#endif
+#ifdef WOLFSSL_SHA384
+    static const byte hashSha384hOid[] = {96, 134, 72, 1, 101, 3, 4, 2, 2};
+#endif
+#ifdef WOLFSSL_SHA512
+    static const byte hashSha512hOid[] = {96, 134, 72, 1, 101, 3, 4, 2, 3};
+#endif
+
+/* hmacType */
+#ifndef NO_HMAC
+    #ifdef WOLFSSL_SHA224
+    static const byte hmacSha224Oid[] = {42, 134, 72, 134, 247, 13, 2, 8};
+    #endif
+    #ifndef NO_SHA256
+    static const byte hmacSha256Oid[] = {42, 134, 72, 134, 247, 13, 2, 9};
+    #endif
+    #ifdef WOLFSSL_SHA384
+    static const byte hmacSha384Oid[] = {42, 134, 72, 134, 247, 13, 2, 10};
+    #endif
+    #ifdef WOLFSSL_SHA512
+    static const byte hmacSha512Oid[] = {42, 134, 72, 134, 247, 13, 2, 11};
+    #endif
+#endif
+
+/* sigType */
+#if !defined(NO_DSA) && !defined(NO_SHA)
+    static const byte sigSha1wDsaOid[] = {42, 134, 72, 206, 56, 4, 3};
+#endif /* NO_DSA */
+#ifndef NO_RSA
+    #ifdef WOLFSSL_MD2
+    static const byte sigMd2wRsaOid[] = {42, 134, 72, 134, 247, 13, 1, 1, 2};
+    #endif
+    #ifndef NO_MD5
+    static const byte sigMd5wRsaOid[] = {42, 134, 72, 134, 247, 13, 1, 1, 4};
+    #endif
+    #ifndef NO_SHA
+    static const byte sigSha1wRsaOid[] = {42, 134, 72, 134, 247, 13, 1, 1, 5};
+    #endif
+    #ifdef WOLFSSL_SHA224
+    static const byte sigSha224wRsaOid[] = {42, 134, 72, 134, 247, 13, 1, 1,14};
+    #endif
+    #ifndef NO_SHA256
+    static const byte sigSha256wRsaOid[] = {42, 134, 72, 134, 247, 13, 1, 1,11};
+    #endif
+    #ifdef WOLFSSL_SHA384
+    static const byte sigSha384wRsaOid[] = {42, 134, 72, 134, 247, 13, 1, 1,12};
+    #endif
+    #ifdef WOLFSSL_SHA512
+    static const byte sigSha512wRsaOid[] = {42, 134, 72, 134, 247, 13, 1, 1,13};
+    #endif
+#endif /* NO_RSA */
+#ifdef HAVE_ECC
+    #ifndef NO_SHA
+    static const byte sigSha1wEcdsaOid[] = {42, 134, 72, 206, 61, 4, 1};
+    #endif
+    #ifdef WOLFSSL_SHA224
+    static const byte sigSha224wEcdsaOid[] = {42, 134, 72, 206, 61, 4, 3, 1};
+    #endif
+    #ifndef NO_SHA256
+    static const byte sigSha256wEcdsaOid[] = {42, 134, 72, 206, 61, 4, 3, 2};
+    #endif
+    #ifdef WOLFSSL_SHA384
+    static const byte sigSha384wEcdsaOid[] = {42, 134, 72, 206, 61, 4, 3, 3};
+    #endif
+    #ifdef WOLFSSL_SHA512
+    static const byte sigSha512wEcdsaOid[] = {42, 134, 72, 206, 61, 4, 3, 4};
+    #endif
+#endif /* HAVE_ECC */
+#ifdef HAVE_ED25519
+    static const byte sigEd25519Oid[] = {43, 101, 112};
+#endif /* HAVE_ED25519 */
+#ifdef HAVE_ED448
+    static const byte sigEd448Oid[] = {43, 101, 113};
+#endif /* HAVE_ED448 */
+
+/* keyType */
+#ifndef NO_DSA
+    static const byte keyDsaOid[] = {42, 134, 72, 206, 56, 4, 1};
+#endif /* NO_DSA */
+#ifndef NO_RSA
+    static const byte keyRsaOid[] = {42, 134, 72, 134, 247, 13, 1, 1, 1};
+#endif /* NO_RSA */
+#ifdef HAVE_NTRU
+    static const byte keyNtruOid[] = {43, 6, 1, 4, 1, 193, 22, 1, 1, 1, 1};
+#endif /* HAVE_NTRU */
+#ifdef HAVE_ECC
+    static const byte keyEcdsaOid[] = {42, 134, 72, 206, 61, 2, 1};
+#endif /* HAVE_ECC */
+#ifdef HAVE_ED25519
+    static const byte keyEd25519Oid[] = {43, 101, 112};
+#endif /* HAVE_ED25519 */
+#ifdef HAVE_ED448
+    static const byte keyEd448Oid[] = {43, 101, 113};
+#endif /* HAVE_ED448 */
+#if !defined(NO_DH) && (defined(WOLFSSL_QT) || defined(OPENSSL_ALL))
+    static const byte keyDhOid[] = {42, 134, 72, 134, 247, 13, 1, 3, 1};
+#endif /* ! NO_DH ... */
+
+/* curveType */
+#ifdef HAVE_ECC
+    /* See "ecc_sets" table in ecc.c */
+#endif /* HAVE_ECC */
+
+#ifdef HAVE_AES_CBC
+/* blkType */
+    #ifdef WOLFSSL_AES_128
+    static const byte blkAes128CbcOid[] = {96, 134, 72, 1, 101, 3, 4, 1, 2};
+    #endif
+    #ifdef WOLFSSL_AES_192
+    static const byte blkAes192CbcOid[] = {96, 134, 72, 1, 101, 3, 4, 1, 22};
+    #endif
+    #ifdef WOLFSSL_AES_256
+    static const byte blkAes256CbcOid[] = {96, 134, 72, 1, 101, 3, 4, 1, 42};
+    #endif
+#endif /* HAVE_AES_CBC */
+#ifdef HAVE_AESGCM
+    #ifdef WOLFSSL_AES_128
+    static const byte blkAes128GcmOid[] = {96, 134, 72, 1, 101, 3, 4, 1, 6};
+    #endif
+    #ifdef WOLFSSL_AES_192
+    static const byte blkAes192GcmOid[] = {96, 134, 72, 1, 101, 3, 4, 1, 26};
+    #endif
+    #ifdef WOLFSSL_AES_256
+    static const byte blkAes256GcmOid[] = {96, 134, 72, 1, 101, 3, 4, 1, 46};
+    #endif
+#endif /* HAVE_AESGCM */
+#ifdef HAVE_AESCCM
+    #ifdef WOLFSSL_AES_128
+    static const byte blkAes128CcmOid[] = {96, 134, 72, 1, 101, 3, 4, 1, 7};
+    #endif
+    #ifdef WOLFSSL_AES_192
+    static const byte blkAes192CcmOid[] = {96, 134, 72, 1, 101, 3, 4, 1, 27};
+    #endif
+    #ifdef WOLFSSL_AES_256
+    static const byte blkAes256CcmOid[] = {96, 134, 72, 1, 101, 3, 4, 1, 47};
+    #endif
+#endif /* HAVE_AESCCM */
+
+#ifndef NO_DES3
+    static const byte blkDesCbcOid[]  = {43, 14, 3, 2, 7};
+    static const byte blkDes3CbcOid[] = {42, 134, 72, 134, 247, 13, 3, 7};
+#endif
+
+/* keyWrapType */
+#ifdef WOLFSSL_AES_128
+    static const byte wrapAes128Oid[] = {96, 134, 72, 1, 101, 3, 4, 1, 5};
+#endif
+#ifdef WOLFSSL_AES_192
+    static const byte wrapAes192Oid[] = {96, 134, 72, 1, 101, 3, 4, 1, 25};
+#endif
+#ifdef WOLFSSL_AES_256
+    static const byte wrapAes256Oid[] = {96, 134, 72, 1, 101, 3, 4, 1, 45};
+#endif
+#ifdef HAVE_PKCS7
+/* From RFC 3211 */
+static const byte wrapPwriKekOid[] = {42, 134, 72, 134, 247, 13, 1, 9, 16, 3,9};
+#endif
+
+/* cmsKeyAgreeType */
+#ifndef NO_SHA
+    static const byte dhSinglePass_stdDH_sha1kdf_Oid[]   =
+                                          {43, 129, 5, 16, 134, 72, 63, 0, 2};
+#endif
+#ifdef WOLFSSL_SHA224
+    static const byte dhSinglePass_stdDH_sha224kdf_Oid[] = {43, 129, 4, 1, 11, 0};
+#endif
+#ifndef NO_SHA256
+    static const byte dhSinglePass_stdDH_sha256kdf_Oid[] = {43, 129, 4, 1, 11, 1};
+#endif
+#ifdef WOLFSSL_SHA384
+    static const byte dhSinglePass_stdDH_sha384kdf_Oid[] = {43, 129, 4, 1, 11, 2};
+#endif
+#ifdef WOLFSSL_SHA512
+    static const byte dhSinglePass_stdDH_sha512kdf_Oid[] = {43, 129, 4, 1, 11, 3};
+#endif
+
+/* ocspType */
+#ifdef HAVE_OCSP
+    static const byte ocspBasicOid[] = {43, 6, 1, 5, 5, 7, 48, 1, 1};
+    static const byte ocspNonceOid[] = {43, 6, 1, 5, 5, 7, 48, 1, 2};
+#endif /* HAVE_OCSP */
+
+/* certExtType */
+static const byte extBasicCaOid[] = {85, 29, 19};
+static const byte extAltNamesOid[] = {85, 29, 17};
+static const byte extCrlDistOid[] = {85, 29, 31};
+static const byte extAuthInfoOid[] = {43, 6, 1, 5, 5, 7, 1, 1};
+static const byte extAuthKeyOid[] = {85, 29, 35};
+static const byte extSubjKeyOid[] = {85, 29, 14};
+static const byte extCertPolicyOid[] = {85, 29, 32};
+static const byte extKeyUsageOid[] = {85, 29, 15};
+static const byte extInhibitAnyOid[] = {85, 29, 54};
+static const byte extExtKeyUsageOid[] = {85, 29, 37};
+#ifndef IGNORE_NAME_CONSTRAINTS
+    static const byte extNameConsOid[] = {85, 29, 30};
+#endif
+
+/* certAuthInfoType */
+#ifdef HAVE_OCSP
+    static const byte extAuthInfoOcspOid[] = {43, 6, 1, 5, 5, 7, 48, 1};
+#endif
+static const byte extAuthInfoCaIssuerOid[] = {43, 6, 1, 5, 5, 7, 48, 2};
+
+/* certPolicyType */
+static const byte extCertPolicyAnyOid[] = {85, 29, 32, 0};
+
+/* certKeyUseType */
+static const byte extAltNamesHwNameOid[] = {43, 6, 1, 5, 5, 7, 8, 4};
+
+/* certKeyUseType */
+static const byte extExtKeyUsageAnyOid[] = {85, 29, 37, 0};
+static const byte extExtKeyUsageServerAuthOid[]   = {43, 6, 1, 5, 5, 7, 3, 1};
+static const byte extExtKeyUsageClientAuthOid[]   = {43, 6, 1, 5, 5, 7, 3, 2};
+static const byte extExtKeyUsageCodeSigningOid[]  = {43, 6, 1, 5, 5, 7, 3, 3};
+static const byte extExtKeyUsageEmailProtectOid[] = {43, 6, 1, 5, 5, 7, 3, 4};
+static const byte extExtKeyUsageTimestampOid[]    = {43, 6, 1, 5, 5, 7, 3, 8};
+static const byte extExtKeyUsageOcspSignOid[]     = {43, 6, 1, 5, 5, 7, 3, 9};
+
+/* kdfType */
+static const byte pbkdf2Oid[] = {42, 134, 72, 134, 247, 13, 1, 5, 12};
+
+/* PKCS5 */
+#if !defined(NO_DES3) && !defined(NO_SHA)
+static const byte pbeSha1Des[] = {42, 134, 72, 134, 247, 13, 1, 5, 10};
+#endif
+static const byte pbes2[] = {42, 134, 72, 134, 247, 13, 1, 5, 13};
+
+/* PKCS12 */
+#if !defined(NO_RC4) && !defined(NO_SHA)
+static const byte pbeSha1RC4128[] = {42, 134, 72, 134, 247, 13, 1, 12, 1, 1};
+#endif
+#if !defined(NO_DES3) && !defined(NO_SHA)
+static const byte pbeSha1Des3[] = {42, 134, 72, 134, 247, 13, 1, 12, 1, 3};
+#endif
+
+#ifdef HAVE_LIBZ
+/* zlib compression */
+static const byte zlibCompress[] = {42, 134, 72, 134, 247, 13, 1, 9, 16, 3, 8};
+#endif
+#ifdef WOLFSSL_APACHE_HTTPD
+/* tlsExtType */
+static const byte tlsFeatureOid[] = {43, 6, 1, 5, 5, 7, 1, 24};
+/* certNameType */
+static const byte dnsSRVOid[] = {43, 6, 1, 5, 5, 7, 8, 7};
+#endif
+
+
+/* returns a pointer to the OID string on success and NULL on fail */
+const byte* OidFromId(word32 id, word32 type, word32* oidSz)
+{
+    const byte* oid = NULL;
+
+    *oidSz = 0;
+
+    switch (type) {
+
+        case oidHashType:
+            switch (id) {
+            #ifdef WOLFSSL_MD2
+                case MD2h:
+                    oid = hashMd2hOid;
+                    *oidSz = sizeof(hashMd2hOid);
+                    break;
+            #endif
+            #ifndef NO_MD5
+                case MD5h:
+                    oid = hashMd5hOid;
+                    *oidSz = sizeof(hashMd5hOid);
+                    break;
+            #endif
+            #ifndef NO_SHA
+                case SHAh:
+                    oid = hashSha1hOid;
+                    *oidSz = sizeof(hashSha1hOid);
+                    break;
+            #endif
+            #ifdef WOLFSSL_SHA224
+                case SHA224h:
+                    oid = hashSha224hOid;
+                    *oidSz = sizeof(hashSha224hOid);
+                    break;
+            #endif
+            #ifndef NO_SHA256
+                case SHA256h:
+                    oid = hashSha256hOid;
+                    *oidSz = sizeof(hashSha256hOid);
+                    break;
+            #endif
+            #ifdef WOLFSSL_SHA384
+                case SHA384h:
+                    oid = hashSha384hOid;
+                    *oidSz = sizeof(hashSha384hOid);
+                    break;
+            #endif
+            #ifdef WOLFSSL_SHA512
+                case SHA512h:
+                    oid = hashSha512hOid;
+                    *oidSz = sizeof(hashSha512hOid);
+                    break;
+            #endif
+            }
+            break;
+
+        case oidSigType:
+            switch (id) {
+                #if !defined(NO_DSA) && !defined(NO_SHA)
+                case CTC_SHAwDSA:
+                    oid = sigSha1wDsaOid;
+                    *oidSz = sizeof(sigSha1wDsaOid);
+                    break;
+                #endif /* NO_DSA */
+                #ifndef NO_RSA
+                #ifdef WOLFSSL_MD2
+                case CTC_MD2wRSA:
+                    oid = sigMd2wRsaOid;
+                    *oidSz = sizeof(sigMd2wRsaOid);
+                    break;
+                #endif
+                #ifndef NO_MD5
+                case CTC_MD5wRSA:
+                    oid = sigMd5wRsaOid;
+                    *oidSz = sizeof(sigMd5wRsaOid);
+                    break;
+                #endif
+                #ifndef NO_SHA
+                case CTC_SHAwRSA:
+                    oid = sigSha1wRsaOid;
+                    *oidSz = sizeof(sigSha1wRsaOid);
+                    break;
+                #endif
+                #ifdef WOLFSSL_SHA224
+                case CTC_SHA224wRSA:
+                    oid = sigSha224wRsaOid;
+                    *oidSz = sizeof(sigSha224wRsaOid);
+                    break;
+                #endif
+                #ifndef NO_SHA256
+                case CTC_SHA256wRSA:
+                    oid = sigSha256wRsaOid;
+                    *oidSz = sizeof(sigSha256wRsaOid);
+                    break;
+                #endif
+                #ifdef WOLFSSL_SHA384
+                case CTC_SHA384wRSA:
+                    oid = sigSha384wRsaOid;
+                    *oidSz = sizeof(sigSha384wRsaOid);
+                    break;
+                #endif
+                #ifdef WOLFSSL_SHA512
+                case CTC_SHA512wRSA:
+                    oid = sigSha512wRsaOid;
+                    *oidSz = sizeof(sigSha512wRsaOid);
+                    break;
+                #endif /* WOLFSSL_SHA512 */
+                #endif /* NO_RSA */
+                #ifdef HAVE_ECC
+                #ifndef NO_SHA
+                case CTC_SHAwECDSA:
+                    oid = sigSha1wEcdsaOid;
+                    *oidSz = sizeof(sigSha1wEcdsaOid);
+                    break;
+                #endif
+                #ifdef WOLFSSL_SHA224
+                case CTC_SHA224wECDSA:
+                    oid = sigSha224wEcdsaOid;
+                    *oidSz = sizeof(sigSha224wEcdsaOid);
+                    break;
+                #endif
+                #ifndef NO_SHA256
+                case CTC_SHA256wECDSA:
+                    oid = sigSha256wEcdsaOid;
+                    *oidSz = sizeof(sigSha256wEcdsaOid);
+                    break;
+                #endif
+                #ifdef WOLFSSL_SHA384
+                case CTC_SHA384wECDSA:
+                    oid = sigSha384wEcdsaOid;
+                    *oidSz = sizeof(sigSha384wEcdsaOid);
+                    break;
+                #endif
+                #ifdef WOLFSSL_SHA512
+                case CTC_SHA512wECDSA:
+                    oid = sigSha512wEcdsaOid;
+                    *oidSz = sizeof(sigSha512wEcdsaOid);
+                    break;
+                #endif
+                #endif /* HAVE_ECC */
+                #ifdef HAVE_ED25519
+                case CTC_ED25519:
+                    oid = sigEd25519Oid;
+                    *oidSz = sizeof(sigEd25519Oid);
+                    break;
+                #endif
+                #ifdef HAVE_ED448
+                case CTC_ED448:
+                    oid = sigEd448Oid;
+                    *oidSz = sizeof(sigEd448Oid);
+                    break;
+                #endif
+                default:
+                    break;
+            }
+            break;
+
+        case oidKeyType:
+            switch (id) {
+                #ifndef NO_DSA
+                case DSAk:
+                    oid = keyDsaOid;
+                    *oidSz = sizeof(keyDsaOid);
+                    break;
+                #endif /* NO_DSA */
+                #ifndef NO_RSA
+                case RSAk:
+                    oid = keyRsaOid;
+                    *oidSz = sizeof(keyRsaOid);
+                    break;
+                #endif /* NO_RSA */
+                #ifdef HAVE_NTRU
+                case NTRUk:
+                    oid = keyNtruOid;
+                    *oidSz = sizeof(keyNtruOid);
+                    break;
+                #endif /* HAVE_NTRU */
+                #ifdef HAVE_ECC
+                case ECDSAk:
+                    oid = keyEcdsaOid;
+                    *oidSz = sizeof(keyEcdsaOid);
+                    break;
+                #endif /* HAVE_ECC */
+                #ifdef HAVE_ED25519
+                case ED25519k:
+                    oid = keyEd25519Oid;
+                    *oidSz = sizeof(keyEd25519Oid);
+                    break;
+                #endif /* HAVE_ED25519 */
+                #ifdef HAVE_ED448
+                case ED448k:
+                    oid = keyEd448Oid;
+                    *oidSz = sizeof(keyEd448Oid);
+                    break;
+                #endif /* HAVE_ED448 */
+                #if !defined(NO_DH) && (defined(WOLFSSL_QT) || defined(OPENSSL_ALL))
+                case DHk:
+                    oid = keyDhOid;
+                    *oidSz = sizeof(keyDhOid);
+                    break;
+                #endif /* ! NO_DH && (WOLFSSL_QT || OPENSSL_ALL */
+                default:
+                    break;
+            }
+            break;
+
+        #ifdef HAVE_ECC
+        case oidCurveType:
+            if (wc_ecc_get_oid(id, &oid, oidSz) < 0) {
+                WOLFSSL_MSG("ECC OID not found");
+            }
+            break;
+        #endif /* HAVE_ECC */
+
+        case oidBlkType:
+            switch (id) {
+    #ifdef HAVE_AES_CBC
+        #ifdef WOLFSSL_AES_128
+                case AES128CBCb:
+                    oid = blkAes128CbcOid;
+                    *oidSz = sizeof(blkAes128CbcOid);
+                    break;
+        #endif
+        #ifdef WOLFSSL_AES_192
+                case AES192CBCb:
+                    oid = blkAes192CbcOid;
+                    *oidSz = sizeof(blkAes192CbcOid);
+                    break;
+        #endif
+        #ifdef WOLFSSL_AES_256
+                case AES256CBCb:
+                    oid = blkAes256CbcOid;
+                    *oidSz = sizeof(blkAes256CbcOid);
+                    break;
+        #endif
+    #endif /* HAVE_AES_CBC */
+    #ifdef HAVE_AESGCM
+        #ifdef WOLFSSL_AES_128
+                case AES128GCMb:
+                    oid = blkAes128GcmOid;
+                    *oidSz = sizeof(blkAes128GcmOid);
+                    break;
+        #endif
+        #ifdef WOLFSSL_AES_192
+                case AES192GCMb:
+                    oid = blkAes192GcmOid;
+                    *oidSz = sizeof(blkAes192GcmOid);
+                    break;
+        #endif
+        #ifdef WOLFSSL_AES_256
+                case AES256GCMb:
+                    oid = blkAes256GcmOid;
+                    *oidSz = sizeof(blkAes256GcmOid);
+                    break;
+        #endif
+    #endif /* HAVE_AESGCM */
+    #ifdef HAVE_AESCCM
+        #ifdef WOLFSSL_AES_128
+                case AES128CCMb:
+                    oid = blkAes128CcmOid;
+                    *oidSz = sizeof(blkAes128CcmOid);
+                    break;
+        #endif
+        #ifdef WOLFSSL_AES_192
+                case AES192CCMb:
+                    oid = blkAes192CcmOid;
+                    *oidSz = sizeof(blkAes192CcmOid);
+                    break;
+        #endif
+        #ifdef WOLFSSL_AES_256
+                case AES256CCMb:
+                    oid = blkAes256CcmOid;
+                    *oidSz = sizeof(blkAes256CcmOid);
+                    break;
+        #endif
+    #endif /* HAVE_AESCCM */
+    #ifndef NO_DES3
+                case DESb:
+                    oid = blkDesCbcOid;
+                    *oidSz = sizeof(blkDesCbcOid);
+                    break;
+                case DES3b:
+                    oid = blkDes3CbcOid;
+                    *oidSz = sizeof(blkDes3CbcOid);
+                    break;
+    #endif /* !NO_DES3 */
+            }
+            break;
+
+        #ifdef HAVE_OCSP
+        case oidOcspType:
+            switch (id) {
+                case OCSP_BASIC_OID:
+                    oid = ocspBasicOid;
+                    *oidSz = sizeof(ocspBasicOid);
+                    break;
+                case OCSP_NONCE_OID:
+                    oid = ocspNonceOid;
+                    *oidSz = sizeof(ocspNonceOid);
+                    break;
+            }
+            break;
+        #endif /* HAVE_OCSP */
+
+        case oidCertExtType:
+            switch (id) {
+                case BASIC_CA_OID:
+                    oid = extBasicCaOid;
+                    *oidSz = sizeof(extBasicCaOid);
+                    break;
+                case ALT_NAMES_OID:
+                    oid = extAltNamesOid;
+                    *oidSz = sizeof(extAltNamesOid);
+                    break;
+                case CRL_DIST_OID:
+                    oid = extCrlDistOid;
+                    *oidSz = sizeof(extCrlDistOid);
+                    break;
+                case AUTH_INFO_OID:
+                    oid = extAuthInfoOid;
+                    *oidSz = sizeof(extAuthInfoOid);
+                    break;
+                case AUTH_KEY_OID:
+                    oid = extAuthKeyOid;
+                    *oidSz = sizeof(extAuthKeyOid);
+                    break;
+                case SUBJ_KEY_OID:
+                    oid = extSubjKeyOid;
+                    *oidSz = sizeof(extSubjKeyOid);
+                    break;
+                case CERT_POLICY_OID:
+                    oid = extCertPolicyOid;
+                    *oidSz = sizeof(extCertPolicyOid);
+                    break;
+                case KEY_USAGE_OID:
+                    oid = extKeyUsageOid;
+                    *oidSz = sizeof(extKeyUsageOid);
+                    break;
+                case INHIBIT_ANY_OID:
+                    oid = extInhibitAnyOid;
+                    *oidSz = sizeof(extInhibitAnyOid);
+                    break;
+                case EXT_KEY_USAGE_OID:
+                    oid = extExtKeyUsageOid;
+                    *oidSz = sizeof(extExtKeyUsageOid);
+                    break;
+            #ifndef IGNORE_NAME_CONSTRAINTS
+                case NAME_CONS_OID:
+                    oid = extNameConsOid;
+                    *oidSz = sizeof(extNameConsOid);
+                    break;
+            #endif
+            }
+            break;
+
+        case oidCrlExtType:
+            #ifdef HAVE_CRL
+            switch (id) {
+                case AUTH_KEY_OID:
+                    oid = extAuthKeyOid;
+                    *oidSz = sizeof(extAuthKeyOid);
+                    break;
+            }
+            #endif
+            break;
+
+        case oidCertAuthInfoType:
+            switch (id) {
+            #ifdef HAVE_OCSP
+                case AIA_OCSP_OID:
+                    oid = extAuthInfoOcspOid;
+                    *oidSz = sizeof(extAuthInfoOcspOid);
+                    break;
+            #endif
+                case AIA_CA_ISSUER_OID:
+                    oid = extAuthInfoCaIssuerOid;
+                    *oidSz = sizeof(extAuthInfoCaIssuerOid);
+                    break;
+            }
+            break;
+
+        case oidCertPolicyType:
+            switch (id) {
+                case CP_ANY_OID:
+                    oid = extCertPolicyAnyOid;
+                    *oidSz = sizeof(extCertPolicyAnyOid);
+                    break;
+            }
+            break;
+
+        case oidCertAltNameType:
+            switch (id) {
+                case HW_NAME_OID:
+                    oid = extAltNamesHwNameOid;
+                    *oidSz = sizeof(extAltNamesHwNameOid);
+                    break;
+            }
+            break;
+
+        case oidCertKeyUseType:
+            switch (id) {
+                case EKU_ANY_OID:
+                    oid = extExtKeyUsageAnyOid;
+                    *oidSz = sizeof(extExtKeyUsageAnyOid);
+                    break;
+                case EKU_SERVER_AUTH_OID:
+                    oid = extExtKeyUsageServerAuthOid;
+                    *oidSz = sizeof(extExtKeyUsageServerAuthOid);
+                    break;
+                case EKU_CLIENT_AUTH_OID:
+                    oid = extExtKeyUsageClientAuthOid;
+                    *oidSz = sizeof(extExtKeyUsageClientAuthOid);
+                    break;
+                case EKU_CODESIGNING_OID:
+                    oid = extExtKeyUsageCodeSigningOid;
+                    *oidSz = sizeof(extExtKeyUsageCodeSigningOid);
+                    break;
+                case EKU_EMAILPROTECT_OID:
+                    oid = extExtKeyUsageEmailProtectOid;
+                    *oidSz = sizeof(extExtKeyUsageEmailProtectOid);
+                    break;
+                case EKU_TIMESTAMP_OID:
+                    oid = extExtKeyUsageTimestampOid;
+                    *oidSz = sizeof(extExtKeyUsageTimestampOid);
+                    break;
+                case EKU_OCSP_SIGN_OID:
+                    oid = extExtKeyUsageOcspSignOid;
+                    *oidSz = sizeof(extExtKeyUsageOcspSignOid);
+                    break;
+            }
+            break;
+
+        case oidKdfType:
+            switch (id) {
+                case PBKDF2_OID:
+                    oid = pbkdf2Oid;
+                    *oidSz = sizeof(pbkdf2Oid);
+                    break;
+            }
+            break;
+
+        case oidPBEType:
+            switch (id) {
+        #if !defined(NO_SHA) && !defined(NO_RC4)
+                case PBE_SHA1_RC4_128:
+                    oid = pbeSha1RC4128;
+                    *oidSz = sizeof(pbeSha1RC4128);
+                    break;
+        #endif
+        #if !defined(NO_SHA) && !defined(NO_DES3)
+                case PBE_SHA1_DES:
+                    oid = pbeSha1Des;
+                    *oidSz = sizeof(pbeSha1Des);
+                    break;
+
+        #endif
+        #if !defined(NO_SHA) && !defined(NO_DES3)
+                case PBE_SHA1_DES3:
+                    oid = pbeSha1Des3;
+                    *oidSz = sizeof(pbeSha1Des3);
+                    break;
+        #endif
+                case PBES2:
+                    oid = pbes2;
+                    *oidSz = sizeof(pbes2);
+                    break;
+            }
+            break;
+
+        case oidKeyWrapType:
+            switch (id) {
+            #ifdef WOLFSSL_AES_128
+                case AES128_WRAP:
+                    oid = wrapAes128Oid;
+                    *oidSz = sizeof(wrapAes128Oid);
+                    break;
+            #endif
+            #ifdef WOLFSSL_AES_192
+                case AES192_WRAP:
+                    oid = wrapAes192Oid;
+                    *oidSz = sizeof(wrapAes192Oid);
+                    break;
+            #endif
+            #ifdef WOLFSSL_AES_256
+                case AES256_WRAP:
+                    oid = wrapAes256Oid;
+                    *oidSz = sizeof(wrapAes256Oid);
+                    break;
+            #endif
+            #ifdef HAVE_PKCS7
+                case PWRI_KEK_WRAP:
+                    oid = wrapPwriKekOid;
+                    *oidSz = sizeof(wrapPwriKekOid);
+                    break;
+            #endif
+            }
+            break;
+
+        case oidCmsKeyAgreeType:
+            switch (id) {
+            #ifndef NO_SHA
+                case dhSinglePass_stdDH_sha1kdf_scheme:
+                    oid = dhSinglePass_stdDH_sha1kdf_Oid;
+                    *oidSz = sizeof(dhSinglePass_stdDH_sha1kdf_Oid);
+                    break;
+            #endif
+            #ifdef WOLFSSL_SHA224
+                case dhSinglePass_stdDH_sha224kdf_scheme:
+                    oid = dhSinglePass_stdDH_sha224kdf_Oid;
+                    *oidSz = sizeof(dhSinglePass_stdDH_sha224kdf_Oid);
+                    break;
+            #endif
+            #ifndef NO_SHA256
+                case dhSinglePass_stdDH_sha256kdf_scheme:
+                    oid = dhSinglePass_stdDH_sha256kdf_Oid;
+                    *oidSz = sizeof(dhSinglePass_stdDH_sha256kdf_Oid);
+                    break;
+            #endif
+            #ifdef WOLFSSL_SHA384
+                case dhSinglePass_stdDH_sha384kdf_scheme:
+                    oid = dhSinglePass_stdDH_sha384kdf_Oid;
+                    *oidSz = sizeof(dhSinglePass_stdDH_sha384kdf_Oid);
+                    break;
+            #endif
+            #ifdef WOLFSSL_SHA512
+                case dhSinglePass_stdDH_sha512kdf_scheme:
+                    oid = dhSinglePass_stdDH_sha512kdf_Oid;
+                    *oidSz = sizeof(dhSinglePass_stdDH_sha512kdf_Oid);
+                    break;
+            #endif
+            }
+            break;
+
+#ifndef NO_HMAC
+        case oidHmacType:
+            switch (id) {
+        #ifdef WOLFSSL_SHA224
+                case HMAC_SHA224_OID:
+                    oid = hmacSha224Oid;
+                    *oidSz = sizeof(hmacSha224Oid);
+                    break;
+        #endif
+        #ifndef NO_SHA256
+                case HMAC_SHA256_OID:
+                    oid = hmacSha256Oid;
+                    *oidSz = sizeof(hmacSha256Oid);
+                    break;
+        #endif
+        #ifdef WOLFSSL_SHA384
+                case HMAC_SHA384_OID:
+                    oid = hmacSha384Oid;
+                    *oidSz = sizeof(hmacSha384Oid);
+                    break;
+        #endif
+        #ifdef WOLFSSL_SHA512
+                case HMAC_SHA512_OID:
+                    oid = hmacSha512Oid;
+                    *oidSz = sizeof(hmacSha512Oid);
+                    break;
+        #endif
+            }
+            break;
+#endif /* !NO_HMAC */
+
+#ifdef HAVE_LIBZ
+        case oidCompressType:
+            switch (id) {
+                case ZLIBc:
+                    oid = zlibCompress;
+                    *oidSz = sizeof(zlibCompress);
+                    break;
+            }
+            break;
+#endif /* HAVE_LIBZ */
+#ifdef WOLFSSL_APACHE_HTTPD
+        case oidCertNameType:
+            switch (id) {
+                 case NID_id_on_dnsSRV:
+                    oid = dnsSRVOid;
+                    *oidSz = sizeof(dnsSRVOid);
+                    break;
+            }
+            break;
+        case oidTlsExtType:
+            switch (id) {
+                case TLS_FEATURE_OID:
+                    oid = tlsFeatureOid;
+                    *oidSz = sizeof(tlsFeatureOid);
+                    break;
+            }
+            break;
+#endif /* WOLFSSL_APACHE_HTTPD */
+        case oidIgnoreType:
+        default:
+            break;
+    }
+
+    return oid;
+}
+
+#ifdef HAVE_OID_ENCODING
+int EncodeObjectId(const word16* in, word32 inSz, byte* out, word32* outSz)
+{
+    int i, x, len;
+    word32 d, t;
+
+    /* check args */
+    if (in == NULL || outSz == NULL) {
+        return BAD_FUNC_ARG;
+    }
+
+    /* compute length of encoded OID */
+    d = (in[0] * 40) + in[1];
+    len = 0;
+    for (i = 1; i < (int)inSz; i++) {
+        x = 0;
+        t = d;
+        while (t) {
+            x++;
+            t >>= 1;
+        }
+        len += (x / 7) + ((x % 7) ? 1 : 0) + (d == 0 ? 1 : 0);
+
+        if (i < (int)inSz - 1) {
+            d = in[i + 1];
+        }
+    }
+
+    if (out) {
+        /* verify length */
+        if ((int)*outSz < len) {
+            return BUFFER_E; /* buffer provided is not large enough */
+        }
+
+        /* calc first byte */
+        d = (in[0] * 40) + in[1];
+
+        /* encode bytes */
+        x = 0;
+        for (i = 1; i < (int)inSz; i++) {
+            if (d) {
+                int y = x, z;
+                byte mask = 0;
+                while (d) {
+                    out[x++] = (byte)((d & 0x7F) | mask);
+                    d     >>= 7;
+                    mask  |= 0x80;  /* upper bit is set on all but the last byte */
+                }
+                /* now swap bytes y...x-1 */
+                z = x - 1;
+                while (y < z) {
+                    mask = out[y];
+                    out[y] = out[z];
+                    out[z] = mask;
+                    ++y;
+                    --z;
+                }
+            }
+            else {
+              out[x++] = 0x00; /* zero value */
+            }
+
+            /* next word */
+            if (i < (int)inSz - 1) {
+                d = in[i + 1];
+            }
+        }
+    }
+
+    /* return length */
+    *outSz = len;
+
+    return 0;
+}
+#endif /* HAVE_OID_ENCODING */
+
+#ifdef HAVE_OID_DECODING
+int DecodeObjectId(const byte* in, word32 inSz, word16* out, word32* outSz)
+{
+    int x = 0, y = 0;
+    word32 t = 0;
+
+    /* check args */
+    if (in == NULL || outSz == NULL) {
+        return BAD_FUNC_ARG;
+    }
+
+    /* decode bytes */
+    while (inSz--) {
+        t = (t << 7) | (in[x] & 0x7F);
+        if (!(in[x] & 0x80)) {
+            if (y >= (int)*outSz) {
+                return BUFFER_E;
+            }
+            if (y == 0) {
+                out[0] = (t / 40);
+                out[1] = (t % 40);
+                y = 2;
+            }
+            else {
+                out[y++] = t;
+            }
+            t = 0; /* reset tmp */
+        }
+        x++;
+    }
+
+    /* return length */
+    *outSz = y;
+
+    return 0;
+}
+#endif /* HAVE_OID_DECODING */
+
+/* Get the DER/BER encoding of an ASN.1 OBJECT_ID header.
+ *
+ * input     Buffer holding DER/BER encoded data.
+ * inOutIdx  Current index into buffer to parse.
+ * len       The number of bytes in the ASN.1 data.
+ * maxIdx    Length of data in buffer.
+ * returns BUFFER_E when there is not enough data to parse.
+ *         ASN_OBJECt_ID_E when the OBJECT_ID tag is not found.
+ *         ASN_PARSE_E when length is invalid.
+ *         Otherwise, 0 to indicate success.
+ */
+int GetASNObjectId(const byte* input, word32* inOutIdx, int* len,
+                          word32 maxIdx)
+{
+    word32 idx = *inOutIdx;
+    int    length;
+    byte   tag;
+
+    if ((idx + 1) > maxIdx)
+        return BUFFER_E;
+
+    if (GetASNTag(input, &idx, &tag, maxIdx) != 0)
+        return ASN_PARSE_E;
+
+    if (tag != ASN_OBJECT_ID)
+        return ASN_OBJECT_ID_E;
+
+    if (GetLength(input, &idx, &length, maxIdx) < 0)
+        return ASN_PARSE_E;
+
+    *len = length;
+    *inOutIdx = idx;
+    return 0;
+}
+
+/* Set the DER/BER encoding of the ASN.1 OBJECT_ID header.
+ *
+ * len         Length of the OBJECT_ID data.
+ * output      Buffer to write into.
+ * returns the number of bytes added to the buffer.
+ */
+int SetObjectId(int len, byte* output)
+{
+    int idx = 0;
+
+    output[idx++] = ASN_OBJECT_ID;
+    idx += SetLength(len, output + idx);
+
+    return idx;
+}
+
+int GetObjectId(const byte* input, word32* inOutIdx, word32* oid,
+                                  word32 oidType, word32 maxIdx)
+{
+    int    ret = 0, length;
+    word32 idx = *inOutIdx;
+#ifndef NO_VERIFY_OID
+    word32 actualOidSz = 0;
+    const byte* actualOid;
+#endif /* NO_VERIFY_OID */
+
+    (void)oidType;
+    WOLFSSL_ENTER("GetObjectId()");
+    *oid = 0;
+
+    ret = GetASNObjectId(input, &idx, &length, maxIdx);
+    if (ret != 0)
+        return ret;
+
+#ifndef NO_VERIFY_OID
+    actualOid = &input[idx];
+    if (length > 0)
+        actualOidSz = (word32)length;
+#endif /* NO_VERIFY_OID */
+
+    while (length--) {
+        /* odd HC08 compiler behavior here when input[idx++] */
+        *oid += (word32)input[idx];
+        idx++;
+    }
+    /* just sum it up for now */
+
+    *inOutIdx = idx;
+
+#ifndef NO_VERIFY_OID
+    {
+        const byte* checkOid = NULL;
+        word32 checkOidSz;
+    #ifdef ASN_DUMP_OID
+        word32 i;
+    #endif
+
+        if (oidType != oidIgnoreType) {
+            checkOid = OidFromId(*oid, oidType, &checkOidSz);
+
+        #ifdef ASN_DUMP_OID
+            /* support for dumping OID information */
+            printf("OID (Type %d, Sz %d, Sum %d): ", oidType, actualOidSz, *oid);
+            for (i=0; i<actualOidSz; i++) {
+                printf("%d, ", actualOid[i]);
+            }
+            printf("\n");
+            #ifdef HAVE_OID_DECODING
+            {
+                word16 decOid[16];
+                word32 decOidSz = sizeof(decOid);
+                ret = DecodeObjectId(actualOid, actualOidSz, decOid, &decOidSz);
+                if (ret == 0) {
+                    printf("  Decoded (Sz %d): ", decOidSz);
+                    for (i=0; i<decOidSz; i++) {
+                        printf("%d.", decOid[i]);
+                    }
+                    printf("\n");
+                }
+                else {
+                    printf("DecodeObjectId failed: %d\n", ret);
+                }
+            }
+            #endif /* HAVE_OID_DECODING */
+        #endif /* ASN_DUMP_OID */
+
+            if (checkOid != NULL &&
+                (checkOidSz != actualOidSz ||
+                    XMEMCMP(actualOid, checkOid, checkOidSz) != 0)) {
+                WOLFSSL_MSG("OID Check Failed");
+                return ASN_UNKNOWN_OID_E;
+            }
+        }
+    }
+#endif /* NO_VERIFY_OID */
+
+    return ret;
+}
+
+static int SkipObjectId(const byte* input, word32* inOutIdx, word32 maxIdx)
+{
+    word32 idx = *inOutIdx;
+    int    length;
+    int ret;
+
+    ret = GetASNObjectId(input, &idx, &length, maxIdx);
+    if (ret != 0)
+        return ret;
+
+    idx += length;
+    *inOutIdx = idx;
+
+    return 0;
+}
+
+int GetAlgoId(const byte* input, word32* inOutIdx, word32* oid,
+                     word32 oidType, word32 maxIdx)
+{
+    int    length;
+    word32 idx = *inOutIdx;
+    int    ret;
+    *oid = 0;
+
+    WOLFSSL_ENTER("GetAlgoId");
+
+    if (GetSequence(input, &idx, &length, maxIdx) < 0)
+        return ASN_PARSE_E;
+
+    if (GetObjectId(input, &idx, oid, oidType, maxIdx) < 0)
+        return ASN_OBJECT_ID_E;
+
+    /* could have NULL tag and 0 terminator, but may not */
+    if (idx < maxIdx) {
+        word32 localIdx = idx; /*use localIdx to not advance when checking tag*/
+        byte   tag;
+
+        if (GetASNTag(input, &localIdx, &tag, maxIdx) == 0) {
+            if (tag == ASN_TAG_NULL) {
+                ret = GetASNNull(input, &idx, maxIdx);
+                if (ret != 0)
+                    return ret;
+            }
+        }
+    }
+
+    *inOutIdx = idx;
+
+    return 0;
+}
+
+#ifndef NO_RSA
+
+#ifndef HAVE_USER_RSA
+int wc_RsaPrivateKeyDecode(const byte* input, word32* inOutIdx, RsaKey* key,
+                        word32 inSz)
+{
+    int version, length;
+
+    if (inOutIdx == NULL) {
+        return BAD_FUNC_ARG;
+    }
+    if (GetSequence(input, inOutIdx, &length, inSz) < 0)
+        return ASN_PARSE_E;
+
+    if (GetMyVersion(input, inOutIdx, &version, inSz) < 0)
+        return ASN_PARSE_E;
+
+    key->type = RSA_PRIVATE;
+
+    if (GetInt(&key->n,  input, inOutIdx, inSz) < 0 ||
+        GetInt(&key->e,  input, inOutIdx, inSz) < 0 ||
+#ifndef WOLFSSL_RSA_PUBLIC_ONLY
+        GetInt(&key->d,  input, inOutIdx, inSz) < 0 ||
+        GetInt(&key->p,  input, inOutIdx, inSz) < 0 ||
+        GetInt(&key->q,  input, inOutIdx, inSz) < 0)
+#else
+        SkipInt(input, inOutIdx, inSz) < 0 ||
+        SkipInt(input, inOutIdx, inSz) < 0 ||
+        SkipInt(input, inOutIdx, inSz) < 0 )
+
+#endif
+            return ASN_RSA_KEY_E;
+#if (defined(WOLFSSL_KEY_GEN) || defined(OPENSSL_EXTRA) || !defined(RSA_LOW_MEM)) \
+    && !defined(WOLFSSL_RSA_PUBLIC_ONLY)
+    if (GetInt(&key->dP, input, inOutIdx, inSz) < 0 ||
+        GetInt(&key->dQ, input, inOutIdx, inSz) < 0 ||
+        GetInt(&key->u,  input, inOutIdx, inSz) < 0 )  return ASN_RSA_KEY_E;
+#else
+    if (SkipInt(input, inOutIdx, inSz) < 0 ||
+        SkipInt(input, inOutIdx, inSz) < 0 ||
+        SkipInt(input, inOutIdx, inSz) < 0 )  return ASN_RSA_KEY_E;
+#endif
+
+#if defined(WOLFSSL_XILINX_CRYPT) || defined(WOLFSSL_CRYPTOCELL)
+    if (wc_InitRsaHw(key) != 0) {
+        return BAD_STATE_E;
+    }
+#endif
+
+    return 0;
+}
+#endif /* HAVE_USER_RSA */
+#endif /* NO_RSA */
+
+#if defined(HAVE_PKCS8) || defined(HAVE_PKCS12)
+
+/* Remove PKCS8 header, place inOutIdx at beginning of traditional,
+ * return traditional length on success, negative on error */
+int ToTraditionalInline_ex(const byte* input, word32* inOutIdx, word32 sz,
+                           word32* algId)
+{
+    word32 idx;
+    int    version, length;
+    int    ret;
+    byte   tag;
+
+    if (input == NULL || inOutIdx == NULL)
+        return BAD_FUNC_ARG;
+
+    idx = *inOutIdx;
+
+    if (GetSequence(input, &idx, &length, sz) < 0)
+        return ASN_PARSE_E;
+
+    if (GetMyVersion(input, &idx, &version, sz) < 0)
+        return ASN_PARSE_E;
+
+    if (GetAlgoId(input, &idx, algId, oidKeyType, sz) < 0)
+        return ASN_PARSE_E;
+
+    if (GetASNTag(input, &idx, &tag, sz) < 0)
+        return ASN_PARSE_E;
+    idx = idx - 1; /* reset idx after finding tag */
+
+    if (tag == ASN_OBJECT_ID) {
+        if (SkipObjectId(input, &idx, sz) < 0)
+            return ASN_PARSE_E;
+    }
+
+    ret = GetOctetString(input, &idx, &length, sz);
+    if (ret < 0) {
+        if (ret == BUFFER_E)
+            return ASN_PARSE_E;
+        /* Some private keys don't expect an octet string */
+        WOLFSSL_MSG("Couldn't find Octet string");
+    }
+
+    *inOutIdx = idx;
+
+    return length;
+}
+
+int ToTraditionalInline(const byte* input, word32* inOutIdx, word32 sz)
+{
+    word32 oid;
+
+    return ToTraditionalInline_ex(input, inOutIdx, sz, &oid);
+}
+
+/* Remove PKCS8 header, move beginning of traditional to beginning of input */
+int ToTraditional_ex(byte* input, word32 sz, word32* algId)
+{
+    word32 inOutIdx = 0;
+    int    length;
+
+    if (input == NULL)
+        return BAD_FUNC_ARG;
+
+    length = ToTraditionalInline_ex(input, &inOutIdx, sz, algId);
+    if (length < 0)
+        return length;
+
+    XMEMMOVE(input, input + inOutIdx, length);
+
+    return length;
+}
+
+int ToTraditional(byte* input, word32 sz)
+{
+    word32 oid;
+
+    return ToTraditional_ex(input, sz, &oid);
+}
+
+#endif /* HAVE_PKCS8 || HAVE_PKCS12 */
+
+#ifdef HAVE_PKCS8
+
+/* find beginning of traditional key inside PKCS#8 unencrypted buffer
+ * return traditional length on success, with inOutIdx at beginning of
+ * traditional
+ * return negative on failure/error */
+int wc_GetPkcs8TraditionalOffset(byte* input, word32* inOutIdx, word32 sz)
+{
+    int length;
+    word32 algId;
+
+    if (input == NULL || inOutIdx == NULL || (*inOutIdx > sz))
+        return BAD_FUNC_ARG;
+
+    length = ToTraditionalInline_ex(input, inOutIdx, sz, &algId);
+
+    return length;
+}
+
+
+/* PKCS#8 from RFC 5208
+ * This function takes in a DER key and converts it to PKCS#8 format. Used
+ * in creating PKCS#12 shrouded key bags.
+ * Reverse of ToTraditional
+ *
+ * PrivateKeyInfo ::= SEQUENCE {
+ *  version Version,
+ *  privateKeyAlgorithm PrivateKeyAlgorithmIdentifier,
+ *  privateKey          PrivateKey,
+ *  attributes          optional
+ *  }
+ *  Version ::= INTEGER
+ *  PrivateKeyAlgorithmIdentifier ::= AlgorithmIdentifier
+ *  PrivateKey ::= OCTET STRING
+ *
+ * out      buffer to place result in
+ * outSz    size of out buffer
+ * key      buffer with DER key
+ * keySz    size of key buffer
+ * algoID   algorithm ID i.e. RSAk
+ * curveOID ECC curve oid if used. Should be NULL for RSA keys.
+ * oidSz    size of curve oid. Is set to 0 if curveOID is NULL.
+ *
+ * Returns the size of PKCS#8 placed into out. In error cases returns negative
+ * values.
+ */
+int wc_CreatePKCS8Key(byte* out, word32* outSz, byte* key, word32 keySz,
+        int algoID, const byte* curveOID, word32 oidSz)
+{
+        word32 keyIdx = 0;
+        word32 tmpSz  = 0;
+        word32 sz;
+
+
+        /* If out is NULL then return the max size needed
+         * + 2 for ASN_OBJECT_ID and ASN_OCTET_STRING tags */
+        if (out == NULL && outSz != NULL) {
+            *outSz = keySz + MAX_SEQ_SZ + MAX_VERSION_SZ + MAX_ALGO_SZ
+                     + MAX_LENGTH_SZ + MAX_LENGTH_SZ + 2;
+
+            if (curveOID != NULL)
+                *outSz += oidSz + MAX_LENGTH_SZ + 1;
+
+            WOLFSSL_MSG("Checking size of PKCS8");
+
+            return LENGTH_ONLY_E;
+        }
+
+        WOLFSSL_ENTER("wc_CreatePKCS8Key()");
+
+        if (key == NULL || out == NULL || outSz == NULL) {
+            return BAD_FUNC_ARG;
+        }
+
+        /* check the buffer has enough room for largest possible size */
+        if (curveOID != NULL) {
+            if (*outSz < (keySz + MAX_SEQ_SZ + MAX_VERSION_SZ + MAX_ALGO_SZ
+                   + MAX_LENGTH_SZ + MAX_LENGTH_SZ + 3 + oidSz + MAX_LENGTH_SZ))
+                return BUFFER_E;
+        }
+        else {
+            oidSz = 0; /* with no curveOID oid size must be 0 */
+            if (*outSz < (keySz + MAX_SEQ_SZ + MAX_VERSION_SZ + MAX_ALGO_SZ
+                      + MAX_LENGTH_SZ + MAX_LENGTH_SZ + 2))
+                return BUFFER_E;
+        }
+
+        /* PrivateKeyInfo ::= SEQUENCE */
+        keyIdx += MAX_SEQ_SZ; /* save room for sequence */
+
+        /*  version Version
+         *  no header information just INTEGER */
+        sz = SetMyVersion(PKCS8v0, out + keyIdx, 0);
+        tmpSz += sz; keyIdx += sz;
+
+        /*  privateKeyAlgorithm PrivateKeyAlgorithmIdentifier */
+        sz = 0; /* set sz to 0 and get privateKey oid buffer size needed */
+        if (curveOID != NULL && oidSz > 0) {
+            byte buf[MAX_LENGTH_SZ];
+            sz = SetLength(oidSz, buf);
+            sz += 1; /* plus one for ASN object id */
+        }
+        sz = SetAlgoID(algoID, out + keyIdx, oidKeyType, oidSz + sz);
+        tmpSz += sz; keyIdx += sz;
+
+        /*  privateKey          PrivateKey *
+         * pkcs8 ecc uses slightly different format. Places curve oid in
+         * buffer */
+        if (curveOID != NULL && oidSz > 0) {
+            sz = SetObjectId(oidSz, out + keyIdx);
+            keyIdx += sz; tmpSz += sz;
+            XMEMCPY(out + keyIdx, curveOID, oidSz);
+            keyIdx += oidSz; tmpSz += oidSz;
+        }
+
+        sz = SetOctetString(keySz, out + keyIdx);
+        keyIdx += sz; tmpSz += sz;
+        XMEMCPY(out + keyIdx, key, keySz);
+        tmpSz += keySz;
+
+        /*  attributes          optional
+         * No attributes currently added */
+
+        /* rewind and add sequence */
+        sz = SetSequence(tmpSz, out);
+        XMEMMOVE(out + sz, out + MAX_SEQ_SZ, tmpSz);
+
+        return tmpSz + sz;
+}
+
+#endif /* HAVE_PKCS8 */
+
+#if defined(HAVE_PKCS12) || !defined(NO_CHECK_PRIVATE_KEY)
+/* check that the private key is a pair for the public key in certificate
+ * return 1 (true) on match
+ * return 0 or negative value on failure/error
+ *
+ * key   : buffer holding DER format key
+ * keySz : size of key buffer
+ * der   : a initialized and parsed DecodedCert holding a certificate */
+int wc_CheckPrivateKey(byte* key, word32 keySz, DecodedCert* der)
+{
+    int ret;
+    (void)keySz;
+
+    if (key == NULL || der == NULL) {
+        return BAD_FUNC_ARG;
+    }
+
+    #if !defined(NO_RSA) && !defined(NO_ASN_CRYPT)
+    /* test if RSA key */
+    if (der->keyOID == RSAk) {
+    #ifdef WOLFSSL_SMALL_STACK
+        RsaKey* a;
+        RsaKey* b = NULL;
+    #else
+        RsaKey a[1], b[1];
+    #endif
+        word32 keyIdx = 0;
+
+    #ifdef WOLFSSL_SMALL_STACK
+        a = (RsaKey*)XMALLOC(sizeof(RsaKey), NULL, DYNAMIC_TYPE_RSA);
+        if (a == NULL)
+            return MEMORY_E;
+        b = (RsaKey*)XMALLOC(sizeof(RsaKey), NULL, DYNAMIC_TYPE_RSA);
+        if (b == NULL) {
+            XFREE(a, NULL, DYNAMIC_TYPE_RSA);
+            return MEMORY_E;
+        }
+    #endif
+
+        if ((ret = wc_InitRsaKey(a, NULL)) < 0) {
+    #ifdef WOLFSSL_SMALL_STACK
+            XFREE(b, NULL, DYNAMIC_TYPE_RSA);
+            XFREE(a, NULL, DYNAMIC_TYPE_RSA);
+    #endif
+            return ret;
+        }
+        if ((ret = wc_InitRsaKey(b, NULL)) < 0) {
+            wc_FreeRsaKey(a);
+    #ifdef WOLFSSL_SMALL_STACK
+            XFREE(b, NULL, DYNAMIC_TYPE_RSA);
+            XFREE(a, NULL, DYNAMIC_TYPE_RSA);
+    #endif
+            return ret;
+        }
+        if ((ret = wc_RsaPrivateKeyDecode(key, &keyIdx, a, keySz)) == 0) {
+            WOLFSSL_MSG("Checking RSA key pair");
+            keyIdx = 0; /* reset to 0 for parsing public key */
+
+            if ((ret = wc_RsaPublicKeyDecode(der->publicKey, &keyIdx, b,
+                                                       der->pubKeySize)) == 0) {
+                /* limit for user RSA crypto because of RsaKey
+                 * dereference. */
+            #if defined(HAVE_USER_RSA)
+                WOLFSSL_MSG("Cannot verify RSA pair with user RSA");
+                ret = 1; /* return first RSA cert as match */
+            #else
+                /* both keys extracted successfully now check n and e
+                 * values are the same. This is dereferencing RsaKey */
+                if (mp_cmp(&(a->n), &(b->n)) != MP_EQ ||
+                    mp_cmp(&(a->e), &(b->e)) != MP_EQ) {
+                    ret = MP_CMP_E;
+                }
+                else
+                    ret = 1;
+            #endif
+            }
+        }
+        wc_FreeRsaKey(b);
+        wc_FreeRsaKey(a);
+    #ifdef WOLFSSL_SMALL_STACK
+        XFREE(b, NULL, DYNAMIC_TYPE_RSA);
+        XFREE(a, NULL, DYNAMIC_TYPE_RSA);
+    #endif
+    }
+    else
+    #endif /* !NO_RSA && !NO_ASN_CRYPT */
+
+    #if defined(HAVE_ECC) && defined(HAVE_ECC_KEY_EXPORT) && !defined(NO_ASN_CRYPT)
+    if (der->keyOID == ECDSAk) {
+    #ifdef WOLFSSL_SMALL_STACK
+        ecc_key* key_pair;
+        byte*    privDer;
+    #else
+        ecc_key  key_pair[1];
+        byte     privDer[MAX_ECC_BYTES];
+    #endif
+        word32   privSz = MAX_ECC_BYTES;
+        word32   keyIdx = 0;
+
+    #ifdef WOLFSSL_SMALL_STACK
+        key_pair = (ecc_key*)XMALLOC(sizeof(ecc_key), NULL, DYNAMIC_TYPE_ECC);
+        if (key_pair == NULL)
+            return MEMORY_E;
+        privDer = (byte*)XMALLOC(MAX_ECC_BYTES, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+        if (privDer == NULL) {
+            XFREE(key_pair, NULL, DYNAMIC_TYPE_ECC);
+            return MEMORY_E;
+        }
+    #endif
+
+        if ((ret = wc_ecc_init(key_pair)) < 0) {
+    #ifdef WOLFSSL_SMALL_STACK
+            XFREE(privDer, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+            XFREE(key_pair, NULL, DYNAMIC_TYPE_ECC);
+    #endif
+            return ret;
+        }
+
+        if ((ret = wc_EccPrivateKeyDecode(key, &keyIdx, key_pair,
+                                                                 keySz)) == 0) {
+            WOLFSSL_MSG("Checking ECC key pair");
+
+            if ((ret = wc_ecc_export_private_only(key_pair, privDer, &privSz))
+                                                                         == 0) {
+                wc_ecc_free(key_pair);
+                ret = wc_ecc_init(key_pair);
+                if (ret == 0) {
+                    ret = wc_ecc_import_private_key((const byte*)privDer,
+                                            privSz, (const byte*)der->publicKey,
+                                            der->pubKeySize, key_pair);
+                }
+
+                /* public and private extracted successfully now check if is
+                 * a pair and also do sanity checks on key. wc_ecc_check_key
+                 * checks that private * base generator equals pubkey */
+                if (ret == 0) {
+                    if ((ret = wc_ecc_check_key(key_pair)) == 0) {
+                        ret = 1;
+                    }
+                }
+                ForceZero(privDer, privSz);
+            }
+        }
+        wc_ecc_free(key_pair);
+    #ifdef WOLFSSL_SMALL_STACK
+        XFREE(privDer, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+        XFREE(key_pair, NULL, DYNAMIC_TYPE_ECC);
+    #endif
+    }
+    else
+    #endif /* HAVE_ECC && HAVE_ECC_KEY_EXPORT && !NO_ASN_CRYPT */
+
+    #if defined(HAVE_ED25519) && !defined(NO_ASN_CRYPT)
+    if (der->keyOID == ED25519k) {
+    #ifdef WOLFSSL_SMALL_STACK
+        ed25519_key* key_pair;
+    #else
+        ed25519_key  key_pair[1];
+    #endif
+        word32       keyIdx = 0;
+
+    #ifdef WOLFSSL_SMALL_STACK
+        key_pair = (ed25519_key*)XMALLOC(sizeof(ed25519_key), NULL,
+                                                          DYNAMIC_TYPE_ED25519);
+        if (key_pair == NULL)
+            return MEMORY_E;
+    #endif
+
+        if ((ret = wc_ed25519_init(key_pair)) < 0) {
+    #ifdef WOLFSSL_SMALL_STACK
+            XFREE(key_pair, NULL, DYNAMIC_TYPE_ED25519);
+    #endif
+            return ret;
+        }
+        if ((ret = wc_Ed25519PrivateKeyDecode(key, &keyIdx, key_pair,
+                                                                 keySz)) == 0) {
+            WOLFSSL_MSG("Checking ED25519 key pair");
+            keyIdx = 0;
+            if ((ret = wc_ed25519_import_public(der->publicKey, der->pubKeySize,
+                                                              key_pair)) == 0) {
+                /* public and private extracted successfully no check if is
+                 * a pair and also do sanity checks on key. wc_ecc_check_key
+                 * checks that private * base generator equals pubkey */
+                if ((ret = wc_ed25519_check_key(key_pair)) == 0)
+                    ret = 1;
+            }
+        }
+        wc_ed25519_free(key_pair);
+    #ifdef WOLFSSL_SMALL_STACK
+        XFREE(key_pair, NULL, DYNAMIC_TYPE_ED25519);
+    #endif
+    }
+    else
+    #endif /* HAVE_ED25519 && !NO_ASN_CRYPT */
+
+    #if defined(HAVE_ED448) && !defined(NO_ASN_CRYPT)
+    if (der->keyOID == ED448k) {
+    #ifdef WOLFSSL_SMALL_STACK
+        ed448_key* key_pair = NULL;
+    #else
+        ed448_key  key_pair[1];
+    #endif
+        word32     keyIdx = 0;
+
+    #ifdef WOLFSSL_SMALL_STACK
+        key_pair = (ed448_key*)XMALLOC(sizeof(ed448_key), NULL,
+                                                            DYNAMIC_TYPE_ED448);
+        if (key_pair == NULL)
+            return MEMORY_E;
+    #endif
+
+        if ((ret = wc_ed448_init(key_pair)) < 0) {
+    #ifdef WOLFSSL_SMALL_STACK
+            XFREE(key_pair, NULL, DYNAMIC_TYPE_ED448);
+    #endif
+            return ret;
+        }
+        if ((ret = wc_Ed448PrivateKeyDecode(key, &keyIdx, key_pair,
+                                                                 keySz)) == 0) {
+            WOLFSSL_MSG("Checking ED448 key pair");
+            keyIdx = 0;
+            if ((ret = wc_ed448_import_public(der->publicKey, der->pubKeySize,
+                                                              key_pair)) == 0) {
+                /* public and private extracted successfully no check if is
+                 * a pair and also do sanity checks on key. wc_ecc_check_key
+                 * checks that private * base generator equals pubkey */
+                if ((ret = wc_ed448_check_key(key_pair)) == 0)
+                    ret = 1;
+            }
+        }
+        wc_ed448_free(key_pair);
+    #ifdef WOLFSSL_SMALL_STACK
+        XFREE(key_pair, NULL, DYNAMIC_TYPE_ED448);
+    #endif
+    }
+    else
+    #endif /* HAVE_ED448 && !NO_ASN_CRYPT */
+    {
+        ret = 0;
+    }
+
+    (void)keySz;
+
+    return ret;
+}
+
+#endif /* HAVE_PKCS12 || !NO_CHECK_PRIVATE_KEY */
+
+#ifndef NO_PWDBASED
+
+#if defined(HAVE_PKCS8) || defined(HAVE_PKCS12)
+/* Check To see if PKCS version algo is supported, set id if it is return 0
+   < 0 on error */
+static int CheckAlgo(int first, int second, int* id, int* version, int* blockSz)
+{
+    *id      = ALGO_ID_E;
+    *version = PKCS5;   /* default */
+    if (blockSz) *blockSz = 8; /* default */
+
+    if (first == 1) {
+        switch (second) {
+#if !defined(NO_SHA)
+    #ifndef NO_RC4
+        case PBE_SHA1_RC4_128:
+            *id = PBE_SHA1_RC4_128;
+            *version = PKCS12v1;
+            return 0;
+    #endif
+    #ifndef NO_DES3
+        case PBE_SHA1_DES3:
+            *id = PBE_SHA1_DES3;
+            *version = PKCS12v1;
+            if (blockSz) *blockSz = DES_BLOCK_SIZE;
+            return 0;
+        case PBE_SHA1_DES:
+            *id = PBE_SHA1_DES;
+            *version = PKCS12v1;
+            if (blockSz) *blockSz = DES_BLOCK_SIZE;
+            return 0;
+    #endif
+#endif /* !NO_SHA */
+        default:
+            return ALGO_ID_E;
+        }
+    }
+
+    if (first != PKCS5)
+        return ASN_INPUT_E;  /* VERSION ERROR */
+
+    if (second == PBES2) {
+        *version = PKCS5v2;
+        return 0;
+    }
+
+    switch (second) {
+#ifndef NO_DES3
+    #ifndef NO_MD5
+    case 3:                   /* see RFC 2898 for ids */
+        *id = PBE_MD5_DES;
+        if (blockSz) *blockSz = DES_BLOCK_SIZE;
+        return 0;
+    #endif
+    #ifndef NO_SHA
+    case 10:
+        *id = PBE_SHA1_DES;
+        if (blockSz) *blockSz = DES_BLOCK_SIZE;
+        return 0;
+    #endif
+#endif /* !NO_DES3 */
+    default:
+        return ALGO_ID_E;
+
+    }
+}
+
+/* Check To see if PKCS v2 algo is supported, set id if it is return 0
+   < 0 on error */
+static int CheckAlgoV2(int oid, int* id, int* blockSz)
+{
+    if (blockSz) *blockSz = 8; /* default */
+    (void)id; /* not used if AES and DES3 disabled */
+    switch (oid) {
+#if !defined(NO_DES3) && !defined(NO_SHA)
+    case DESb:
+        *id = PBE_SHA1_DES;
+        if (blockSz) *blockSz = DES_BLOCK_SIZE;
+        return 0;
+    case DES3b:
+        *id = PBE_SHA1_DES3;
+        if (blockSz) *blockSz = DES_BLOCK_SIZE;
+        return 0;
+#endif
+#ifdef WOLFSSL_AES_256
+    case AES256CBCb:
+        *id = PBE_AES256_CBC;
+        if (blockSz) *blockSz = AES_BLOCK_SIZE;
+        return 0;
+#endif
+#ifdef WOLFSSL_AES_128
+    case AES128CBCb:
+        *id = PBE_AES128_CBC;
+        if (blockSz) *blockSz = AES_BLOCK_SIZE;
+        return 0;
+#endif
+    default:
+        WOLFSSL_MSG("No PKCS v2 algo found");
+        return ALGO_ID_E;
+
+    }
+}
+
+#endif /* HAVE_PKCS8 || HAVE_PKCS12 */
+
+#ifdef HAVE_PKCS8
+
+int wc_GetKeyOID(byte* key, word32 keySz, const byte** curveOID, word32* oidSz,
+        int* algoID, void* heap)
+{
+    word32 tmpIdx = 0;
+
+    if (key == NULL || algoID == NULL)
+        return BAD_FUNC_ARG;
+
+    *algoID = 0;
+
+    #if !defined(NO_RSA) && !defined(NO_ASN_CRYPT)
+    {
+        RsaKey rsa;
+
+        wc_InitRsaKey(&rsa, heap);
+        if (wc_RsaPrivateKeyDecode(key, &tmpIdx, &rsa, keySz) == 0) {
+            *algoID = RSAk;
+        }
+        else {
+            WOLFSSL_MSG("Not RSA DER key");
+        }
+        wc_FreeRsaKey(&rsa);
+    }
+    #endif /* !NO_RSA && !NO_ASN_CRYPT */
+    #if defined(HAVE_ECC) && !defined(NO_ASN_CRYPT)
+    if (*algoID == 0) {
+        ecc_key ecc;
+
+        tmpIdx = 0;
+        wc_ecc_init_ex(&ecc, heap, INVALID_DEVID);
+        if (wc_EccPrivateKeyDecode(key, &tmpIdx, &ecc, keySz) == 0) {
+            *algoID = ECDSAk;
+
+            /* now find oid */
+            if (wc_ecc_get_oid(ecc.dp->oidSum, curveOID, oidSz) < 0) {
+                WOLFSSL_MSG("Error getting ECC curve OID");
+                wc_ecc_free(&ecc);
+                return BAD_FUNC_ARG;
+            }
+        }
+        else {
+            WOLFSSL_MSG("Not ECC DER key either");
+        }
+        wc_ecc_free(&ecc);
+    }
+#endif /* HAVE_ECC && !NO_ASN_CRYPT */
+#if defined(HAVE_ED25519) && !defined(NO_ASN_CRYPT)
+    if (*algoID != RSAk && *algoID != ECDSAk) {
+        ed25519_key ed25519;
+
+        tmpIdx = 0;
+        if (wc_ed25519_init(&ed25519) == 0) {
+            if (wc_Ed25519PrivateKeyDecode(key, &tmpIdx, &ed25519, keySz)
+                                                                         == 0) {
+                *algoID = ED25519k;
+            }
+            else {
+                WOLFSSL_MSG("Not ED25519 DER key");
+            }
+            wc_ed25519_free(&ed25519);
+        }
+        else {
+            WOLFSSL_MSG("GetKeyOID wc_ed25519_init failed");
+        }
+    }
+#endif /* HAVE_ED25519 && !NO_ASN_CRYPT */
+#if defined(HAVE_ED448) && !defined(NO_ASN_CRYPT)
+    if (*algoID != RSAk && *algoID != ECDSAk && *algoID != ED25519k) {
+        ed448_key ed448;
+
+        tmpIdx = 0;
+        if (wc_ed448_init(&ed448) == 0) {
+            if (wc_Ed448PrivateKeyDecode(key, &tmpIdx, &ed448, keySz) == 0) {
+                *algoID = ED448k;
+            }
+            else {
+                WOLFSSL_MSG("Not ED448 DER key");
+            }
+            wc_ed448_free(&ed448);
+        }
+        else {
+            WOLFSSL_MSG("GetKeyOID wc_ed448_init failed");
+        }
+    }
+#endif /* HAVE_ED448 && !NO_ASN_CRYPT */
+
+    /* if flag is not set then is neither RSA or ECC key that could be
+     * found */
+    if (*algoID == 0) {
+        WOLFSSL_MSG("Bad key DER or compile options");
+        return BAD_FUNC_ARG;
+    }
+
+    (void)tmpIdx;
+    (void)curveOID;
+    (void)oidSz;
+    (void)keySz;
+    (void)heap;
+
+    return 1;
+}
+
+#endif /* HAVE_PKCS8 */
+
+#if defined(HAVE_PKCS8) || defined(HAVE_PKCS12)
+
+#define PKCS8_MIN_BLOCK_SIZE 8
+static int Pkcs8Pad(byte* buf, int sz, int blockSz)
+{
+    int i, padSz;
+
+    /* calculate pad size */
+    padSz = blockSz - (sz & (blockSz - 1));
+
+    /* pad with padSz value */
+    if (buf) {
+        for (i = 0; i < padSz; i++) {
+            buf[sz+i] = (byte)(padSz & 0xFF);
+        }
+    }
+
+    /* return adjusted length */
+    return sz + padSz;
+}
+
+#endif /* HAVE_PKCS8 || HAVE_PKCS12 */
+
+#ifdef HAVE_PKCS8
+
+/*
+ * Used when creating PKCS12 shrouded key bags
+ * vPKCS is the version of PKCS to use
+ * vAlgo is the algorithm version to use
+ *
+ * if salt is NULL a random number is generated
+ *
+ * returns the size of encrypted data on success
+ */
+int UnTraditionalEnc(byte* key, word32 keySz, byte* out, word32* outSz,
+        const char* password, int passwordSz, int vPKCS, int vAlgo,
+        byte* salt, word32 saltSz, int itt, WC_RNG* rng, void* heap)
+{
+    int algoID = 0;
+    byte*  tmp;
+    word32 tmpSz = 0;
+    word32 sz;
+    word32 seqSz;
+    word32 inOutIdx = 0;
+    word32 totalSz = 0;
+    int    version, id;
+    int    ret;
+    int    blockSz = 0;
+
+    const byte* curveOID = NULL;
+    word32 oidSz   = 0;
+
+#ifdef WOLFSSL_SMALL_STACK
+    byte*  saltTmp = NULL;
+    byte*  cbcIv   = NULL;
+#else
+    byte   saltTmp[MAX_IV_SIZE];
+    byte   cbcIv[MAX_IV_SIZE];
+#endif
+
+    WOLFSSL_ENTER("UnTraditionalEnc()");
+
+    if (saltSz > MAX_SALT_SIZE)
+        return ASN_PARSE_E;
+
+
+    inOutIdx += MAX_SEQ_SZ; /* leave room for size of finished shroud */
+    if (CheckAlgo(vPKCS, vAlgo, &id, &version, &blockSz) < 0) {
+        WOLFSSL_MSG("Bad/Unsupported algorithm ID");
+        return ASN_INPUT_E;  /* Algo ID error */
+    }
+
+    if (out != NULL) {
+        if (*outSz < inOutIdx + MAX_ALGO_SZ + MAX_SALT_SIZE + MAX_SEQ_SZ + 1 +
+                MAX_LENGTH_SZ + MAX_SHORT_SZ + 1)
+                return BUFFER_E;
+
+        if (version == PKCS5v2) {
+            WOLFSSL_MSG("PKCS5v2 Not supported yet\n");
+            return ASN_VERSION_E;
+        }
+
+        if (salt == NULL || saltSz == 0) {
+            saltSz = 8;
+        #ifdef WOLFSSL_SMALL_STACK
+            saltTmp = (byte*)XMALLOC(saltSz, heap, DYNAMIC_TYPE_TMP_BUFFER);
+            if (saltTmp == NULL)
+                return MEMORY_E;
+        #endif
+            salt = saltTmp;
+
+            if ((ret = wc_RNG_GenerateBlock(rng, saltTmp, saltSz)) != 0) {
+                WOLFSSL_MSG("Error generating random salt");
+            #ifdef WOLFSSL_SMALL_STACK
+                if (saltTmp != NULL)
+                    XFREE(saltTmp, heap, DYNAMIC_TYPE_TMP_BUFFER);
+            #endif
+                return ret;
+            }
+        }
+
+
+        /* leave room for a sequence (contains salt and iterations int) */
+        inOutIdx += MAX_SEQ_SZ; sz = 0;
+        inOutIdx += MAX_ALGO_SZ;
+
+        /* place salt in buffer */
+        out[inOutIdx++] = ASN_OCTET_STRING; sz++;
+        tmpSz = SetLength(saltSz, out + inOutIdx);
+        inOutIdx += tmpSz; sz += tmpSz;
+        XMEMCPY(out + inOutIdx, salt, saltSz);
+        inOutIdx += saltSz; sz += saltSz;
+
+        /* place iteration count in buffer */
+        ret = SetShortInt(out, &inOutIdx, itt, *outSz);
+        if (ret < 0) {
+            return ret;
+        }
+        sz += (word32)ret;
+
+        /* wind back index and set sequence then clean up buffer */
+        inOutIdx -= (sz + MAX_SEQ_SZ);
+        tmpSz = SetSequence(sz, out + inOutIdx);
+        XMEMMOVE(out + inOutIdx + tmpSz, out + inOutIdx + MAX_SEQ_SZ, sz);
+        totalSz += tmpSz + sz; sz += tmpSz;
+
+        /* add in algo ID */
+        inOutIdx -= MAX_ALGO_SZ;
+        tmpSz =  SetAlgoID(id, out + inOutIdx, oidPBEType, sz);
+        XMEMMOVE(out + inOutIdx + tmpSz, out + inOutIdx + MAX_ALGO_SZ, sz);
+        totalSz += tmpSz; inOutIdx += tmpSz + sz;
+
+        /* octet string containing encrypted key */
+        out[inOutIdx++] = ASN_OCTET_STRING; totalSz++;
+    }
+
+    /* check key type and get OID if ECC */
+    if ((ret = wc_GetKeyOID(key, keySz, &curveOID, &oidSz, &algoID, heap))< 0) {
+        WOLFSSL_MSG("Error getting key OID");
+        return ret;
+    }
+
+    /* PKCS#8 wrapping around key */
+    if (wc_CreatePKCS8Key(NULL, &tmpSz, key, keySz, algoID, curveOID, oidSz)
+            != LENGTH_ONLY_E) {
+    #ifdef WOLFSSL_SMALL_STACK
+        if (saltTmp != NULL)
+            XFREE(saltTmp, heap, DYNAMIC_TYPE_TMP_BUFFER);
+    #endif
+        return MEMORY_E;
+    }
+
+    /* check if should return max size */
+    if (out == NULL) {
+        /* account for salt size */
+        if (salt == NULL || saltSz == 0) {
+            tmpSz += MAX_SALT_SIZE;
+        }
+        else {
+            tmpSz += saltSz;
+        }
+
+        /* plus 3 for tags */
+        *outSz = tmpSz + MAX_ALGO_SZ + MAX_LENGTH_SZ +MAX_LENGTH_SZ + MAX_SEQ_SZ
+            + MAX_LENGTH_SZ + MAX_SEQ_SZ + 3;
+        return LENGTH_ONLY_E;
+    }
+
+    /* reserve buffer for crypto and make sure it supports full blocks */
+    tmp = (byte*)XMALLOC(tmpSz + (blockSz-1), heap, DYNAMIC_TYPE_TMP_BUFFER);
+    if (tmp == NULL) {
+    #ifdef WOLFSSL_SMALL_STACK
+        if (saltTmp != NULL)
+            XFREE(saltTmp, heap, DYNAMIC_TYPE_TMP_BUFFER);
+    #endif
+        return MEMORY_E;
+    }
+
+    if ((ret = wc_CreatePKCS8Key(tmp, &tmpSz, key, keySz, algoID, curveOID,
+                    oidSz)) < 0) {
+        XFREE(tmp, heap, DYNAMIC_TYPE_TMP_BUFFER);
+        WOLFSSL_MSG("Error wrapping key with PKCS#8");
+    #ifdef WOLFSSL_SMALL_STACK
+        if (saltTmp != NULL)
+            XFREE(saltTmp, heap, DYNAMIC_TYPE_TMP_BUFFER);
+    #endif
+        return ret;
+    }
+    tmpSz = ret;
+
+    /* adjust size to pad */
+    tmpSz = Pkcs8Pad(tmp, tmpSz, blockSz);
+
+#ifdef WOLFSSL_SMALL_STACK
+    cbcIv = (byte*)XMALLOC(MAX_IV_SIZE, heap, DYNAMIC_TYPE_TMP_BUFFER);
+    if (cbcIv == NULL) {
+        if (saltTmp != NULL)
+            XFREE(saltTmp, heap, DYNAMIC_TYPE_TMP_BUFFER);
+        XFREE(salt, heap, DYNAMIC_TYPE_TMP_BUFFER);
+        return MEMORY_E;
+    }
+#endif
+
+    /* encrypt PKCS#8 wrapped key */
+    if ((ret = wc_CryptKey(password, passwordSz, salt, saltSz, itt, id,
+               tmp, tmpSz, version, cbcIv, 1, 0)) < 0) {
+        XFREE(tmp, heap, DYNAMIC_TYPE_TMP_BUFFER);
+        WOLFSSL_MSG("Error encrypting key");
+    #ifdef WOLFSSL_SMALL_STACK
+        if (saltTmp != NULL)
+            XFREE(saltTmp, heap, DYNAMIC_TYPE_TMP_BUFFER);
+        if (cbcIv != NULL)
+            XFREE(cbcIv, heap, DYNAMIC_TYPE_TMP_BUFFER);
+    #endif
+        return ret;  /* encryption failure */
+    }
+    totalSz += tmpSz;
+
+#ifdef WOLFSSL_SMALL_STACK
+    if (saltTmp != NULL)
+        XFREE(saltTmp, heap, DYNAMIC_TYPE_TMP_BUFFER);
+    if (cbcIv != NULL)
+        XFREE(cbcIv, heap, DYNAMIC_TYPE_TMP_BUFFER);
+#endif
+
+    if (*outSz < inOutIdx + tmpSz + MAX_LENGTH_SZ) {
+        XFREE(tmp, heap, DYNAMIC_TYPE_TMP_BUFFER);
+        return BUFFER_E;
+    }
+
+    /* set length of key and copy over encrypted key */
+    seqSz = SetLength(tmpSz, out + inOutIdx);
+    inOutIdx += seqSz; totalSz += seqSz;
+    XMEMCPY(out + inOutIdx, tmp, tmpSz);
+    XFREE(tmp, heap, DYNAMIC_TYPE_TMP_BUFFER);
+
+    /* set total size at beginning */
+    sz = SetSequence(totalSz, out);
+    XMEMMOVE(out + sz, out + MAX_SEQ_SZ, totalSz);
+
+    (void)rng;
+
+    return totalSz + sz;
+}
+
+static int GetAlgoV2(int encAlgId, const byte** oid, int *len, int* id,
+                     int *blkSz)
+{
+    int ret = 0;
+
+    switch (encAlgId) {
+#if !defined(NO_DES3) && !defined(NO_SHA)
+    case DESb:
+        *len = sizeof(blkDesCbcOid);
+        *oid = blkDesCbcOid;
+        *id = PBE_SHA1_DES;
+        *blkSz = 8;
+        break;
+    case DES3b:
+        *len = sizeof(blkDes3CbcOid);
+        *oid = blkDes3CbcOid;
+        *id = PBE_SHA1_DES3;
+        *blkSz = 8;
+        break;
+#endif
+#if defined(WOLFSSL_AES_256) && defined(HAVE_AES_CBC)
+    case AES256CBCb:
+        *len = sizeof(blkAes256CbcOid);
+        *oid = blkAes256CbcOid;
+        *id = PBE_AES256_CBC;
+        *blkSz = 16;
+        break;
+#endif
+    default:
+        (void)len;
+        (void)oid;
+        (void)id;
+        (void)blkSz;
+        ret = ALGO_ID_E;
+    }
+
+    return ret;
+}
+
+/* Converts Encrypted PKCS#8 to 'traditional' (i.e. PKCS#8 removed from
+ * decrypted key.)
+ */
+int TraditionalEnc(byte* key, word32 keySz, byte* out, word32* outSz,
+        const char* password, int passwordSz, int vPKCS, int vAlgo,
+        int encAlgId, byte* salt, word32 saltSz, int itt, WC_RNG* rng,
+        void* heap)
+{
+    int ret = 0;
+    int version, blockSz, id;
+    word32 idx = 0, encIdx;
+#ifdef WOLFSSL_SMALL_STACK
+    byte* saltTmp = NULL;
+#else
+    byte saltTmp[MAX_SALT_SIZE];
+#endif
+    byte cbcIv[MAX_IV_SIZE];
+    byte *pkcs8Key = NULL;
+    word32 pkcs8KeySz = 0, padSz = 0;
+    int algId = 0;
+    const byte* curveOid = NULL;
+    word32 curveOidSz = 0;
+    const byte* pbeOid = NULL;
+    word32 pbeOidSz = 0;
+    const byte* encOid = NULL;
+    int encOidSz = 0;
+    word32 pbeLen = 0, kdfLen = 0, encLen = 0;
+    word32 innerLen = 0, outerLen;
+
+    ret = CheckAlgo(vPKCS, vAlgo, &id, &version, &blockSz);
+    /* create random salt if one not provided */
+    if (ret == 0 && (salt == NULL || saltSz == 0)) {
+        saltSz = 8;
+    #ifdef WOLFSSL_SMALL_STACK
+        saltTmp = (byte*)XMALLOC(saltSz, heap, DYNAMIC_TYPE_TMP_BUFFER);
+        if (saltTmp == NULL)
+            return MEMORY_E;
+    #endif
+        salt = saltTmp;
+
+        if ((ret = wc_RNG_GenerateBlock(rng, saltTmp, saltSz)) != 0) {
+            WOLFSSL_MSG("Error generating random salt");
+        #ifdef WOLFSSL_SMALL_STACK
+            XFREE(saltTmp, heap, DYNAMIC_TYPE_TMP_BUFFER);
+        #endif
+            return ret;
+        }
+    }
+
+    if (ret == 0) {
+        /* check key type and get OID if ECC */
+        ret = wc_GetKeyOID(key, keySz, &curveOid, &curveOidSz, &algId, heap);
+        if (ret == 1)
+            ret = 0;
+    }
+    if (ret == 0) {
+        ret = wc_CreatePKCS8Key(NULL, &pkcs8KeySz, key, keySz, algId, curveOid,
+                                                                    curveOidSz);
+        if (ret == LENGTH_ONLY_E)
+            ret = 0;
+    }
+    if (ret == 0) {
+        pkcs8Key = (byte*)XMALLOC(pkcs8KeySz, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+        if (pkcs8Key == NULL)
+            ret = MEMORY_E;
+    }
+    if (ret == 0) {
+        ret = wc_CreatePKCS8Key(pkcs8Key, &pkcs8KeySz, key, keySz, algId,
+                                                          curveOid, curveOidSz);
+        if (ret >= 0) {
+            pkcs8KeySz = ret;
+            ret = 0;
+        }
+    }
+
+    if (ret == 0 && version == PKCS5v2)
+        ret = GetAlgoV2(encAlgId, &encOid, &encOidSz, &id, &blockSz);
+
+    if (ret == 0) {
+        padSz = (blockSz - (pkcs8KeySz & (blockSz - 1))) & (blockSz - 1);
+        /* inner = OCT salt INT itt */
+        innerLen = 2 + saltSz + 2 + (itt < 256 ? 1 : 2);
+
+        if (version != PKCS5v2) {
+            pbeOid = OidFromId(id, oidPBEType, &pbeOidSz);
+            /* pbe = OBJ pbse1 SEQ [ inner ] */
+            pbeLen = 2 + pbeOidSz + 2 + innerLen;
+        }
+        else {
+            pbeOid = pbes2;
+            pbeOidSz = sizeof(pbes2);
+            /* kdf = OBJ pbkdf2 [ SEQ innerLen ] */
+            kdfLen = 2 + sizeof(pbkdf2Oid) + 2 + innerLen;
+            /* enc = OBJ enc_alg OCT iv */
+            encLen = 2 + encOidSz + 2 + blockSz;
+            /* pbe = OBJ pbse2 SEQ [ SEQ [ kdf ] SEQ [ enc ] ] */
+            pbeLen = 2 + sizeof(pbes2) + 2 + 2 + kdfLen + 2 + encLen;
+
+            ret = wc_RNG_GenerateBlock(rng, cbcIv, blockSz);
+        }
+    }
+    if (ret == 0) {
+        /* outer = SEQ [ pbe ] OCT encrypted_PKCS#8_key */
+        outerLen = 2 + pbeLen;
+        outerLen += SetOctetString(pkcs8KeySz + padSz, out);
+        outerLen += pkcs8KeySz + padSz;
+
+        idx += SetSequence(outerLen, out + idx);
+
+        encIdx = idx + outerLen - pkcs8KeySz - padSz;
+        /* Put Encrypted content in place. */
+        XMEMCPY(out + encIdx, pkcs8Key, pkcs8KeySz);
+        if (padSz > 0) {
+            XMEMSET(out + encIdx + pkcs8KeySz, padSz, padSz);
+            pkcs8KeySz += padSz;
+        }
+        ret = wc_CryptKey(password, passwordSz, salt, saltSz, itt, id,
+                                out + encIdx, pkcs8KeySz, version, cbcIv, 1, 0);
+    }
+    if (ret == 0) {
+        if (version != PKCS5v2) {
+            /* PBE algorithm */
+            idx += SetSequence(pbeLen, out + idx);
+            idx += SetObjectId(pbeOidSz, out + idx);
+            XMEMCPY(out + idx, pbeOid, pbeOidSz);
+            idx += pbeOidSz;
+        }
+        else {
+            /* PBES2 algorithm identifier */
+            idx += SetSequence(pbeLen, out + idx);
+            idx += SetObjectId(pbeOidSz, out + idx);
+            XMEMCPY(out + idx, pbeOid, pbeOidSz);
+            idx += pbeOidSz;
+            /* PBES2 Parameters: SEQ [ kdf ] SEQ [ enc ] */
+            idx += SetSequence(2 + kdfLen + 2 + encLen, out + idx);
+            /* KDF Algorithm Identifier */
+            idx += SetSequence(kdfLen, out + idx);
+            idx += SetObjectId(sizeof(pbkdf2Oid), out + idx);
+            XMEMCPY(out + idx, pbkdf2Oid, sizeof(pbkdf2Oid));
+            idx += sizeof(pbkdf2Oid);
+        }
+        idx += SetSequence(innerLen, out + idx);
+        idx += SetOctetString(saltSz, out + idx);
+        XMEMCPY(out + idx, salt, saltSz); idx += saltSz;
+        ret = SetShortInt(out, &idx, itt, *outSz);
+        if (ret > 0)
+            ret = 0;
+    }
+    if (ret == 0) {
+        if (version == PKCS5v2) {
+            /* Encryption Algorithm Identifier */
+            idx += SetSequence(encLen, out + idx);
+            idx += SetObjectId(encOidSz, out + idx);
+            XMEMCPY(out + idx, encOid, encOidSz);
+            idx += encOidSz;
+            /* Encryption Algorithm Parameter: CBC IV */
+            idx += SetOctetString(blockSz, out + idx);
+            XMEMCPY(out + idx, cbcIv, blockSz);
+            idx += blockSz;
+        }
+        idx += SetOctetString(pkcs8KeySz, out + idx);
+        /* Default PRF - no need to write out OID */
+        idx += pkcs8KeySz;
+
+        ret = idx;
+    }
+
+    if (pkcs8Key != NULL) {
+        ForceZero(pkcs8Key, pkcs8KeySz);
+        XFREE(pkcs8Key, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    }
+#ifdef WOLFSSL_SMALL_STACK
+    if (saltTmp != NULL) {
+        XFREE(saltTmp, heap, DYNAMIC_TYPE_TMP_BUFFER);
+    }
+#endif
+
+    (void)rng;
+
+    return ret;
+}
+
+#endif /* HAVE_PKCS8 */
+
+#if defined(HAVE_PKCS8) || defined(HAVE_PKCS12)
+/* decrypt PKCS
+ *
+ * NOTE: input buffer is overwritten with decrypted data!
+ *
+ * input[in/out] data to decrypt and results are written to
+ * sz            size of input buffer
+ * password      password if used. Can be NULL for no password
+ * passwordSz    size of password buffer
+ *
+ * returns the total size of decrypted content on success.
+ */
+int DecryptContent(byte* input, word32 sz, const char* password, int passwordSz)
+{
+    word32 inOutIdx = 0, seqEnd, oid, shaOid = 0;
+    int    ret = 0, first, second, length = 0, version, saltSz, id;
+    int    iterations = 0, keySz = 0;
+#ifdef WOLFSSL_SMALL_STACK
+    byte*  salt = NULL;
+    byte*  cbcIv = NULL;
+#else
+    byte   salt[MAX_SALT_SIZE];
+    byte   cbcIv[MAX_IV_SIZE];
+#endif
+    byte   tag;
+
+    if (passwordSz < 0) {
+        WOLFSSL_MSG("Bad password size");
+        return BAD_FUNC_ARG;
+    }
+
+    if (GetAlgoId(input, &inOutIdx, &oid, oidIgnoreType, sz) < 0) {
+        ERROR_OUT(ASN_PARSE_E, exit_dc);
+    }
+
+    first  = input[inOutIdx - 2];   /* PKCS version always 2nd to last byte */
+    second = input[inOutIdx - 1];   /* version.algo, algo id last byte */
+
+    if (CheckAlgo(first, second, &id, &version, NULL) < 0) {
+        ERROR_OUT(ASN_INPUT_E, exit_dc); /* Algo ID error */
+    }
+
+    if (version == PKCS5v2) {
+        if (GetSequence(input, &inOutIdx, &length, sz) < 0) {
+            ERROR_OUT(ASN_PARSE_E, exit_dc);
+        }
+
+        if (GetAlgoId(input, &inOutIdx, &oid, oidKdfType, sz) < 0) {
+            ERROR_OUT(ASN_PARSE_E, exit_dc);
+        }
+
+        if (oid != PBKDF2_OID) {
+            ERROR_OUT(ASN_PARSE_E, exit_dc);
+        }
+    }
+
+    if (GetSequence(input, &inOutIdx, &length, sz) <= 0) {
+        ERROR_OUT(ASN_PARSE_E, exit_dc);
+    }
+    /* Find the end of this SEQUENCE so we can check for the OPTIONAL and
+     * DEFAULT items. */
+    seqEnd = inOutIdx + length;
+
+    ret = GetOctetString(input, &inOutIdx, &saltSz, sz);
+    if (ret < 0)
+        goto exit_dc;
+
+    if (saltSz > MAX_SALT_SIZE) {
+        ERROR_OUT(ASN_PARSE_E, exit_dc);
+    }
+
+#ifdef WOLFSSL_SMALL_STACK
+    salt = (byte*)XMALLOC(MAX_SALT_SIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    if (salt == NULL) {
+        ERROR_OUT(MEMORY_E, exit_dc);
+    }
+#endif
+
+    XMEMCPY(salt, &input[inOutIdx], saltSz);
+    inOutIdx += saltSz;
+
+    if (GetShortInt(input, &inOutIdx, &iterations, sz) < 0) {
+        ERROR_OUT(ASN_PARSE_E, exit_dc);
+    }
+
+    /* OPTIONAL key length */
+    if (seqEnd > inOutIdx) {
+        word32 localIdx = inOutIdx;
+
+        if (GetASNTag(input, &localIdx, &tag, sz) < 0) {
+            ERROR_OUT(ASN_PARSE_E, exit_dc);
+        }
+
+        if (tag == ASN_INTEGER &&
+                GetShortInt(input, &inOutIdx, &keySz, sz) < 0) {
+            ERROR_OUT(ASN_PARSE_E, exit_dc);
+        }
+    }
+
+    /* DEFAULT HMAC is SHA-1 */
+    if (seqEnd > inOutIdx) {
+        if (GetAlgoId(input, &inOutIdx, &oid, oidHmacType, sz) < 0) {
+            ERROR_OUT(ASN_PARSE_E, exit_dc);
+        }
+
+        shaOid = oid;
+    }
+
+#ifdef WOLFSSL_SMALL_STACK
+    cbcIv = (byte*)XMALLOC(MAX_IV_SIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    if (cbcIv == NULL) {
+        ERROR_OUT(MEMORY_E, exit_dc);
+    }
+#endif
+
+    if (version == PKCS5v2) {
+        /* get encryption algo */
+        if (GetAlgoId(input, &inOutIdx, &oid, oidBlkType, sz) < 0) {
+            ERROR_OUT(ASN_PARSE_E, exit_dc);
+        }
+
+        if (CheckAlgoV2(oid, &id, NULL) < 0) {
+            ERROR_OUT(ASN_PARSE_E, exit_dc); /* PKCS v2 algo id error */
+        }
+
+        if (shaOid == 0)
+            shaOid = oid;
+
+        ret = GetOctetString(input, &inOutIdx, &length, sz);
+        if (ret < 0)
+            goto exit_dc;
+
+        if (length > MAX_IV_SIZE) {
+            ERROR_OUT(ASN_PARSE_E, exit_dc);
+        }
+
+        XMEMCPY(cbcIv, &input[inOutIdx], length);
+        inOutIdx += length;
+    }
+
+    if (GetASNTag(input, &inOutIdx, &tag, sz) < 0) {
+        ERROR_OUT(ASN_PARSE_E, exit_dc);
+    }
+
+    if (tag != (ASN_CONTEXT_SPECIFIC | 0) && tag != ASN_OCTET_STRING) {
+        ERROR_OUT(ASN_PARSE_E, exit_dc);
+    }
+
+    if (GetLength(input, &inOutIdx, &length, sz) < 0) {
+        ERROR_OUT(ASN_PARSE_E, exit_dc);
+    }
+
+    ret = wc_CryptKey(password, passwordSz, salt, saltSz, iterations, id,
+                   input + inOutIdx, length, version, cbcIv, 0, shaOid);
+
+exit_dc:
+#ifdef WOLFSSL_SMALL_STACK
+    XFREE(salt,  NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    XFREE(cbcIv, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+#endif
+
+    if (ret == 0) {
+        XMEMMOVE(input, input + inOutIdx, length);
+        ret = length;
+    }
+
+    return ret;
+}
+
+
+/* Remove Encrypted PKCS8 header, move beginning of traditional to beginning
+   of input */
+int ToTraditionalEnc(byte* input, word32 sz,const char* password,
+                     int passwordSz, word32* algId)
+{
+    int ret, length;
+    word32 inOutIdx = 0;
+
+    if (GetSequence(input, &inOutIdx, &length, sz) < 0) {
+        ret = ASN_PARSE_E;
+    }
+    else {
+        ret = DecryptContent(input + inOutIdx, sz - inOutIdx, password,
+                passwordSz);
+        if (ret > 0) {
+            XMEMMOVE(input, input + inOutIdx, ret);
+            ret = ToTraditional_ex(input, ret, algId);
+        }
+    }
+
+    return ret;
+}
+
+#endif /* HAVE_PKCS8 || HAVE_PKCS12 */
+
+#ifdef HAVE_PKCS12
+
+/* encrypt PKCS 12 content
+ *
+ * NOTE: if out is NULL then outSz is set with the total buffer size needed and
+ *       the error value LENGTH_ONLY_E is returned.
+ *
+ * input      data to encrypt
+ * inputSz    size of input buffer
+ * out        buffer to hold the result
+ * outSz      size of out buffer
+ * password   password if used. Can be NULL for no password
+ * passwordSz size of password buffer
+ * vPKCS      version of PKCS i.e. PKCS5v2
+ * vAlgo      algorithm version
+ * salt       buffer holding salt if used. If NULL then a random salt is created
+ * saltSz     size of salt buffer if it is not NULL
+ * itt        number of iterations used
+ * rng        random number generator to use
+ * heap       possible heap hint for mallocs/frees
+ *
+ * returns the total size of encrypted content on success.
+ *
+ * data returned is :
+ * [ seq - obj [ seq -salt,itt]] , construct with encrypted data
+ */
+int EncryptContent(byte* input, word32 inputSz, byte* out, word32* outSz,
+        const char* password, int passwordSz, int vPKCS, int vAlgo,
+        byte* salt, word32 saltSz, int itt, WC_RNG* rng, void* heap)
+{
+    word32 sz;
+    word32 inOutIdx = 0;
+    word32 tmpIdx   = 0;
+    word32 totalSz  = 0;
+    word32 seqSz;
+    word32 innerSz;
+    int    ret;
+    int    version, id, blockSz = 0;
+#ifdef WOLFSSL_SMALL_STACK
+    byte*  saltTmp = NULL;
+    byte*  cbcIv   = NULL;
+#else
+    byte   saltTmp[MAX_SALT_SIZE];
+    byte   cbcIv[MAX_IV_SIZE];
+#endif
+    byte   seq[MAX_SEQ_SZ];
+    byte   shr[MAX_SHORT_SZ];
+    word32 maxShr = MAX_SHORT_SZ;
+    word32 algoSz;
+    const  byte* algoName;
+
+    (void)heap;
+
+    WOLFSSL_ENTER("EncryptContent()");
+
+    if (CheckAlgo(vPKCS, vAlgo, &id, &version, &blockSz) < 0)
+        return ASN_INPUT_E;  /* Algo ID error */
+
+    if (version == PKCS5v2) {
+        WOLFSSL_MSG("PKCS#5 version 2 not supported yet");
+        return BAD_FUNC_ARG;
+    }
+
+    if (saltSz > MAX_SALT_SIZE)
+        return ASN_PARSE_E;
+
+    if (outSz == NULL) {
+        return BAD_FUNC_ARG;
+    }
+
+    /* calculate size */
+    /* size of constructed string at end */
+    sz = Pkcs8Pad(NULL, inputSz, blockSz);
+    totalSz  = ASN_TAG_SZ;
+    totalSz += SetLength(sz, seq);
+    totalSz += sz;
+
+    /* size of sequence holding object id and sub sequence of salt and itt */
+    algoName = OidFromId(id, oidPBEType, &algoSz);
+    if (algoName == NULL) {
+        WOLFSSL_MSG("Unknown Algorithm");
+        return 0;
+    }
+    innerSz = SetObjectId(algoSz, seq);
+    innerSz += algoSz;
+
+    /* get subsequence of salt and itt */
+    if (salt == NULL || saltSz == 0) {
+        sz = 8;
+    }
+    else {
+        sz = saltSz;
+    }
+    seqSz  = SetOctetString(sz, seq);
+    seqSz += sz;
+
+    tmpIdx = 0;
+    seqSz += SetShortInt(shr, &tmpIdx, itt, maxShr);
+    innerSz += seqSz + SetSequence(seqSz, seq);
+    totalSz += innerSz + SetSequence(innerSz, seq);
+
+    if (out == NULL) {
+        *outSz = totalSz;
+        return LENGTH_ONLY_E;
+    }
+
+    inOutIdx = 0;
+    if (totalSz > *outSz)
+        return BUFFER_E;
+
+    inOutIdx += SetSequence(innerSz, out + inOutIdx);
+    inOutIdx += SetObjectId(algoSz, out + inOutIdx);
+    XMEMCPY(out + inOutIdx, algoName, algoSz);
+    inOutIdx += algoSz;
+    inOutIdx += SetSequence(seqSz, out + inOutIdx);
+
+    /* create random salt if one not provided */
+    if (salt == NULL || saltSz == 0) {
+        saltSz = 8;
+    #ifdef WOLFSSL_SMALL_STACK
+        saltTmp = (byte*)XMALLOC(saltSz, heap, DYNAMIC_TYPE_TMP_BUFFER);
+        if (saltTmp == NULL)
+            return MEMORY_E;
+    #endif
+        salt = saltTmp;
+
+        if ((ret = wc_RNG_GenerateBlock(rng, saltTmp, saltSz)) != 0) {
+            WOLFSSL_MSG("Error generating random salt");
+        #ifdef WOLFSSL_SMALL_STACK
+            XFREE(saltTmp, heap, DYNAMIC_TYPE_TMP_BUFFER);
+        #endif
+            return ret;
+        }
+    }
+    inOutIdx += SetOctetString(saltSz, out + inOutIdx);
+    if (saltSz + inOutIdx > *outSz) {
+    #ifdef WOLFSSL_SMALL_STACK
+        XFREE(saltTmp, heap, DYNAMIC_TYPE_TMP_BUFFER);
+    #endif
+        return BUFFER_E;
+    }
+    XMEMCPY(out + inOutIdx, salt, saltSz);
+    inOutIdx += saltSz;
+
+    /* place iteration setting in buffer */
+    ret = SetShortInt(out, &inOutIdx, itt, *outSz);
+    if (ret < 0) {
+    #ifdef WOLFSSL_SMALL_STACK
+        XFREE(saltTmp, heap, DYNAMIC_TYPE_TMP_BUFFER);
+    #endif
+        return ret;
+    }
+
+    if (inOutIdx + 1 > *outSz) {
+    #ifdef WOLFSSL_SMALL_STACK
+        XFREE(saltTmp, heap, DYNAMIC_TYPE_TMP_BUFFER);
+    #endif
+        return BUFFER_E;
+    }
+    out[inOutIdx++] = ASN_CONTEXT_SPECIFIC | 0;
+
+    /* get pad size and verify buffer room */
+    sz = Pkcs8Pad(NULL, inputSz, blockSz);
+    if (sz + inOutIdx > *outSz) {
+    #ifdef WOLFSSL_SMALL_STACK
+        XFREE(saltTmp, heap, DYNAMIC_TYPE_TMP_BUFFER);
+    #endif
+        return BUFFER_E;
+    }
+    inOutIdx += SetLength(sz, out + inOutIdx);
+
+    /* copy input to output buffer and pad end */
+    XMEMCPY(out + inOutIdx, input, inputSz);
+    sz = Pkcs8Pad(out + inOutIdx, inputSz, blockSz);
+#ifdef WOLFSSL_SMALL_STACK
+    cbcIv = (byte*)XMALLOC(MAX_IV_SIZE, heap, DYNAMIC_TYPE_TMP_BUFFER);
+    if (cbcIv == NULL) {
+        XFREE(saltTmp, heap, DYNAMIC_TYPE_TMP_BUFFER);
+        return MEMORY_E;
+    }
+#endif
+
+    /* encrypt */
+    if ((ret = wc_CryptKey(password, passwordSz, salt, saltSz, itt, id,
+                   out + inOutIdx, sz, version, cbcIv, 1, 0)) < 0) {
+
+    #ifdef WOLFSSL_SMALL_STACK
+        XFREE(cbcIv,   heap, DYNAMIC_TYPE_TMP_BUFFER);
+        XFREE(saltTmp, heap, DYNAMIC_TYPE_TMP_BUFFER);
+    #endif
+        return ret;  /* encrypt failure */
+    }
+
+#ifdef WOLFSSL_SMALL_STACK
+    XFREE(cbcIv,   heap, DYNAMIC_TYPE_TMP_BUFFER);
+    XFREE(saltTmp, heap, DYNAMIC_TYPE_TMP_BUFFER);
+#endif
+
+    (void)rng;
+
+    return inOutIdx + sz;
+}
+
+
+#endif /* HAVE_PKCS12 */
+#endif /* NO_PWDBASED */
+
+#ifndef NO_RSA
+
+#ifndef HAVE_USER_RSA
+#ifdef WOLFSSL_RENESAS_TSIP
+/* This function is to retrieve key position information in a cert.*
+ * The information will be used to call TSIP TLS-linked API for    *
+ * certificate verification.                                       */
+static int RsaPublicKeyDecodeRawIndex(const byte* input, word32* inOutIdx,
+                                      word32 inSz, word32* key_n,
+                                      word32* key_n_len, word32* key_e,
+                                      word32* key_e_len)
+{
+
+    int ret = 0;
+    int length = 0;
+#if defined(OPENSSL_EXTRA) || defined(RSA_DECODE_EXTRA)
+    byte b;
+#endif
+
+    if (input == NULL || inOutIdx == NULL)
+        return BAD_FUNC_ARG;
+
+    if (GetSequence(input, inOutIdx, &length, inSz) < 0)
+        return ASN_PARSE_E;
+
+#if defined(OPENSSL_EXTRA) || defined(RSA_DECODE_EXTRA)
+    if ((*inOutIdx + 1) > inSz)
+        return BUFFER_E;
+
+    b = input[*inOutIdx];
+    if (b != ASN_INTEGER) {
+        /* not from decoded cert, will have algo id, skip past */
+        if (GetSequence(input, inOutIdx, &length, inSz) < 0)
+            return ASN_PARSE_E;
+
+        if (SkipObjectId(input, inOutIdx, inSz) < 0)
+            return ASN_PARSE_E;
+
+        /* Option NULL ASN.1 tag */
+        if (*inOutIdx  >= inSz) {
+            return BUFFER_E;
+        }
+        if (input[*inOutIdx] == ASN_TAG_NULL) {
+            ret = GetASNNull(input, inOutIdx, inSz);
+            if (ret != 0)
+                return ret;
+        }
+
+        /* should have bit tag length and seq next */
+        ret = CheckBitString(input, inOutIdx, NULL, inSz, 1, NULL);
+        if (ret != 0)
+            return ret;
+
+        if (GetSequence(input, inOutIdx, &length, inSz) < 0)
+            return ASN_PARSE_E;
+    }
+#endif /* OPENSSL_EXTRA */
+
+    /* Get modulus */
+    ret = GetASNInt(input, inOutIdx, &length, inSz);
+    *key_n += *inOutIdx;
+    if (ret < 0) {
+        return ASN_RSA_KEY_E;
+    }
+    if (key_n_len)
+        *key_n_len = length;
+    *inOutIdx += length;
+
+    /* Get exponent */
+    ret = GetASNInt(input, inOutIdx, &length, inSz);
+    *key_e += *inOutIdx;
+    if (ret < 0) {
+        return ASN_RSA_KEY_E;
+    }
+    if (key_e_len)
+        *key_e_len = length;
+
+    return ret;
+}
+#endif /* WOLFSSL_RENESAS_TSIP */
+
+int wc_RsaPublicKeyDecode_ex(const byte* input, word32* inOutIdx, word32 inSz,
+    const byte** n, word32* nSz, const byte** e, word32* eSz)
+{
+    int ret = 0;
+    int length = 0;
+#if defined(OPENSSL_EXTRA) || defined(RSA_DECODE_EXTRA)
+    word32 localIdx;
+    byte   tag;
+#endif
+
+    if (input == NULL || inOutIdx == NULL)
+        return BAD_FUNC_ARG;
+
+    if (GetSequence(input, inOutIdx, &length, inSz) < 0)
+        return ASN_PARSE_E;
+
+#if defined(OPENSSL_EXTRA) || defined(RSA_DECODE_EXTRA)
+    localIdx = *inOutIdx;
+    if (GetASNTag(input, &localIdx, &tag, inSz) < 0)
+        return BUFFER_E;
+
+    if (tag != ASN_INTEGER) {
+        /* not from decoded cert, will have algo id, skip past */
+        if (GetSequence(input, inOutIdx, &length, inSz) < 0)
+            return ASN_PARSE_E;
+
+        if (SkipObjectId(input, inOutIdx, inSz) < 0)
+            return ASN_PARSE_E;
+
+        /* Option NULL ASN.1 tag */
+        if (*inOutIdx  >= inSz) {
+            return BUFFER_E;
+        }
+
+        localIdx = *inOutIdx;
+        if (GetASNTag(input, &localIdx, &tag, inSz) < 0)
+            return ASN_PARSE_E;
+
+        if (tag == ASN_TAG_NULL) {
+            ret = GetASNNull(input, inOutIdx, inSz);
+            if (ret != 0)
+                return ret;
+        }
+
+        /* should have bit tag length and seq next */
+        ret = CheckBitString(input, inOutIdx, NULL, inSz, 1, NULL);
+        if (ret != 0)
+            return ret;
+
+        if (GetSequence(input, inOutIdx, &length, inSz) < 0)
+            return ASN_PARSE_E;
+    }
+#endif /* OPENSSL_EXTRA */
+
+    /* Get modulus */
+    ret = GetASNInt(input, inOutIdx, &length, inSz);
+    if (ret < 0) {
+        return ASN_RSA_KEY_E;
+    }
+    if (nSz)
+        *nSz = length;
+    if (n)
+        *n = &input[*inOutIdx];
+    *inOutIdx += length;
+
+    /* Get exponent */
+    ret = GetASNInt(input, inOutIdx, &length, inSz);
+    if (ret < 0) {
+        return ASN_RSA_KEY_E;
+    }
+    if (eSz)
+        *eSz = length;
+    if (e)
+        *e = &input[*inOutIdx];
+    *inOutIdx += length;
+
+    return ret;
+}
+
+int wc_RsaPublicKeyDecode(const byte* input, word32* inOutIdx, RsaKey* key,
+                       word32 inSz)
+{
+    int ret;
+    const byte *n = NULL, *e = NULL;
+    word32 nSz = 0, eSz = 0;
+
+    if (key == NULL)
+        return BAD_FUNC_ARG;
+
+    ret = wc_RsaPublicKeyDecode_ex(input, inOutIdx, inSz, &n, &nSz, &e, &eSz);
+    if (ret == 0) {
+        ret = wc_RsaPublicKeyDecodeRaw(n, nSz, e, eSz, key);
+    }
+
+    return ret;
+}
+
+/* import RSA public key elements (n, e) into RsaKey structure (key) */
+int wc_RsaPublicKeyDecodeRaw(const byte* n, word32 nSz, const byte* e,
+                             word32 eSz, RsaKey* key)
+{
+    if (n == NULL || e == NULL || key == NULL)
+        return BAD_FUNC_ARG;
+
+    key->type = RSA_PUBLIC;
+
+    if (mp_init(&key->n) != MP_OKAY)
+        return MP_INIT_E;
+
+    if (mp_read_unsigned_bin(&key->n, n, nSz) != 0) {
+        mp_clear(&key->n);
+        return ASN_GETINT_E;
+    }
+#ifdef HAVE_WOLF_BIGINT
+    if ((int)nSz > 0 && wc_bigint_from_unsigned_bin(&key->n.raw, n, nSz) != 0) {
+        mp_clear(&key->n);
+        return ASN_GETINT_E;
+    }
+#endif /* HAVE_WOLF_BIGINT */
+
+    if (mp_init(&key->e) != MP_OKAY) {
+        mp_clear(&key->n);
+        return MP_INIT_E;
+    }
+
+    if (mp_read_unsigned_bin(&key->e, e, eSz) != 0) {
+        mp_clear(&key->n);
+        mp_clear(&key->e);
+        return ASN_GETINT_E;
+    }
+#ifdef HAVE_WOLF_BIGINT
+    if ((int)eSz > 0 && wc_bigint_from_unsigned_bin(&key->e.raw, e, eSz) != 0) {
+        mp_clear(&key->n);
+        mp_clear(&key->e);
+        return ASN_GETINT_E;
+    }
+#endif /* HAVE_WOLF_BIGINT */
+
+#ifdef WOLFSSL_XILINX_CRYPT
+    if (wc_InitRsaHw(key) != 0) {
+        return BAD_STATE_E;
+    }
+#endif
+
+    return 0;
+}
+#endif /* HAVE_USER_RSA */
+#endif /* !NO_RSA */
+
+#ifndef NO_DH
+
+int wc_DhKeyDecode(const byte* input, word32* inOutIdx, DhKey* key, word32 inSz)
+{
+    int ret = 0;
+    int length;
+    #if defined(WOLFSSL_QT) || defined(OPENSSL_ALL)
+    word32 oid = 0, temp = 0;
+    #endif
+
+    WOLFSSL_ENTER("wc_DhKeyDecode");
+
+    if (inOutIdx == NULL)
+        return BAD_FUNC_ARG;
+
+    if (GetSequence(input, inOutIdx, &length, inSz) < 0)
+        return ASN_PARSE_E;
+
+    #if defined(WOLFSSL_QT) || defined(OPENSSL_ALL)
+    temp = *inOutIdx;
+    #endif
+
+    /* Assume input started after 1.2.840.113549.1.3.1 dhKeyAgreement */
+    if (GetInt(&key->p,  input, inOutIdx, inSz) < 0 ||
+        GetInt(&key->g,  input, inOutIdx, inSz) < 0) {
+        ret = ASN_DH_KEY_E;
+    }
+
+    #if defined(WOLFSSL_QT) || defined(OPENSSL_ALL)
+    /* If ASN_DH_KEY_E: Check if input started at beginning of key */
+    if (ret == ASN_DH_KEY_E) {
+        /* rewind back to after the first sequence */
+        *inOutIdx = temp;
+        if (GetSequence(input, inOutIdx, &length, inSz) < 0)
+            return ASN_PARSE_E;
+
+        /* Check for dhKeyAgreement */
+        ret = GetObjectId(input, inOutIdx, &oid, oidKeyType, inSz);
+        if (oid != DHk || ret < 0)
+            return ASN_DH_KEY_E;
+
+        if (GetSequence(input, inOutIdx, &length, inSz) < 0)
+            return ASN_PARSE_E;
+
+        if (GetInt(&key->p,  input, inOutIdx, inSz) < 0 ||
+            GetInt(&key->g,  input, inOutIdx, inSz) < 0) {
+            return ASN_DH_KEY_E;
+        }
+    }
+
+    temp = *inOutIdx;
+    ret = (CheckBitString(input, inOutIdx, &length, inSz, 0, NULL) == 0);
+    if (ret > 0) {
+        /* Found Bit String */
+        if (GetInt(&key->pub, input, inOutIdx, inSz) == 0) {
+            WOLFSSL_MSG("Found Public Key");
+            ret = 0;
+        }
+    } else {
+        *inOutIdx = temp;
+        ret = (GetOctetString(input, inOutIdx, &length, inSz) >= 0);
+        if (ret > 0) {
+            /* Found Octet String */
+            if (GetInt(&key->priv, input, inOutIdx, inSz) == 0) {
+                WOLFSSL_MSG("Found Private Key");
+                ret = 0;
+            }
+        } else {
+            /* Don't use length from failed CheckBitString/GetOctetString */
+            *inOutIdx = temp;
+            ret = 0;
+        }
+    }
+    #endif /* WOLFSSL_QT || OPENSSL_ALL */
+
+    WOLFSSL_MSG("wc_DhKeyDecode Success");
+
+    return ret;
+}
+
+
+int wc_DhParamsLoad(const byte* input, word32 inSz, byte* p, word32* pInOutSz,
+                 byte* g, word32* gInOutSz)
+{
+    word32 idx = 0;
+    int    ret;
+    int    length;
+
+    if (GetSequence(input, &idx, &length, inSz) <= 0)
+        return ASN_PARSE_E;
+
+    ret = GetASNInt(input, &idx, &length, inSz);
+    if (ret != 0)
+        return ret;
+
+    if (length <= (int)*pInOutSz) {
+        XMEMCPY(p, &input[idx], length);
+        *pInOutSz = length;
+    }
+    else {
+        return BUFFER_E;
+    }
+    idx += length;
+
+    ret = GetASNInt(input, &idx, &length, inSz);
+    if (ret != 0)
+        return ret;
+
+    if (length <= (int)*gInOutSz) {
+        XMEMCPY(g, &input[idx], length);
+        *gInOutSz = length;
+    }
+    else {
+        return BUFFER_E;
+    }
+
+    return 0;
+}
+#endif /* NO_DH */
+
+
+#ifndef NO_DSA
+
+int DsaPublicKeyDecode(const byte* input, word32* inOutIdx, DsaKey* key,
+                        word32 inSz)
+{
+    int    length;
+    int    ret = 0;
+    word32 oid;
+
+    if (input == NULL || inOutIdx == NULL || key == NULL)
+        return BAD_FUNC_ARG;
+
+    if (GetSequence(input, inOutIdx, &length, inSz) < 0)
+        return ASN_PARSE_E;
+
+    if (GetInt(&key->p,  input, inOutIdx, inSz) < 0 ||
+        GetInt(&key->q,  input, inOutIdx, inSz) < 0 ||
+        GetInt(&key->g,  input, inOutIdx, inSz) < 0 ||
+        GetInt(&key->y,  input, inOutIdx, inSz) < 0 )
+        ret = ASN_DH_KEY_E;
+
+    if (ret != 0) {
+        if (GetSequence(input, inOutIdx, &length, inSz) < 0)
+            return ASN_PARSE_E;
+
+        ret = GetObjectId(input, inOutIdx, &oid, oidIgnoreType, inSz);
+        if (ret != 0)
+            return ret;
+
+        if (GetSequence(input, inOutIdx, &length, inSz) < 0)
+            return ASN_PARSE_E;
+
+        if (GetInt(&key->p,  input, inOutIdx, inSz) < 0 ||
+            GetInt(&key->q,  input, inOutIdx, inSz) < 0 ||
+            GetInt(&key->g,  input, inOutIdx, inSz) < 0)
+            return ASN_DH_KEY_E;
+
+        if (CheckBitString(input, inOutIdx, &length, inSz, 0, NULL) < 0)
+            return ASN_PARSE_E;
+
+        if (GetInt(&key->y,  input, inOutIdx, inSz) < 0 )
+            return ASN_DH_KEY_E;
+
+        ret = 0;
+    }
+
+    key->type = DSA_PUBLIC;
+    return ret;
+}
+
+
+int DsaPrivateKeyDecode(const byte* input, word32* inOutIdx, DsaKey* key,
+                        word32 inSz)
+{
+    int    length, version, ret = 0, temp = 0;
+
+    /* Sanity checks on input */
+    if (input == NULL || inOutIdx == NULL || key == NULL) {
+        return BAD_FUNC_ARG;
+    }
+
+    if (GetSequence(input, inOutIdx, &length, inSz) < 0)
+        return ASN_PARSE_E;
+
+    temp = (int)*inOutIdx;
+
+    /* Default case expects a certificate with OctetString but no version ID */
+    ret = GetInt(&key->p, input, inOutIdx, inSz);
+    if (ret < 0) {
+        mp_clear(&key->p);
+        ret = ASN_PARSE_E;
+    }
+    else {
+        ret = GetInt(&key->q, input, inOutIdx, inSz);
+        if (ret < 0) {
+            mp_clear(&key->p);
+            mp_clear(&key->q);
+            ret = ASN_PARSE_E;
+        }
+        else {
+            ret = GetInt(&key->g, input, inOutIdx, inSz);
+            if (ret < 0) {
+                mp_clear(&key->p);
+                mp_clear(&key->q);
+                mp_clear(&key->g);
+                ret = ASN_PARSE_E;
+            }
+            else {
+                ret = GetOctetString(input, inOutIdx, &length, inSz);
+                if (ret < 0) {
+                    mp_clear(&key->p);
+                    mp_clear(&key->q);
+                    mp_clear(&key->g);
+                    ret = ASN_PARSE_E;
+                }
+                else {
+                    ret = GetInt(&key->y, input, inOutIdx, inSz);
+                    if (ret < 0) {
+                        mp_clear(&key->p);
+                        mp_clear(&key->q);
+                        mp_clear(&key->g);
+                        mp_clear(&key->y);
+                        ret = ASN_PARSE_E;
+                    }
+                }
+            }
+        }
+    }
+    /* An alternate pass if default certificate fails parsing */
+    if (ret == ASN_PARSE_E) {
+        *inOutIdx = temp;
+        if (GetMyVersion(input, inOutIdx, &version, inSz) < 0)
+            return ASN_PARSE_E;
+
+        if (GetInt(&key->p,  input, inOutIdx, inSz) < 0 ||
+            GetInt(&key->q,  input, inOutIdx, inSz) < 0 ||
+            GetInt(&key->g,  input, inOutIdx, inSz) < 0 ||
+            GetInt(&key->y,  input, inOutIdx, inSz) < 0 ||
+            GetInt(&key->x,  input, inOutIdx, inSz) < 0 )
+            return ASN_DH_KEY_E;
+    }
+
+    key->type = DSA_PRIVATE;
+    return 0;
+}
+
+static mp_int* GetDsaInt(DsaKey* key, int idx)
+{
+    if (idx == 0)
+        return &key->p;
+    if (idx == 1)
+        return &key->q;
+    if (idx == 2)
+        return &key->g;
+    if (idx == 3)
+        return &key->y;
+    if (idx == 4)
+        return &key->x;
+
+    return NULL;
+}
+
+/* Release Tmp DSA resources */
+static WC_INLINE void FreeTmpDsas(byte** tmps, void* heap)
+{
+    int i;
+
+    for (i = 0; i < DSA_INTS; i++)
+        XFREE(tmps[i], heap, DYNAMIC_TYPE_DSA);
+
+    (void)heap;
+}
+
+#if !defined(HAVE_SELFTEST) && defined(WOLFSSL_KEY_GEN)
+/* Write a public DSA key to output */
+int wc_SetDsaPublicKey(byte* output, DsaKey* key,
+                           int outLen, int with_header)
+{
+    /* p, g, q = DSA params, y = public exponent */
+#ifdef WOLFSSL_SMALL_STACK
+    byte* p = NULL;
+    byte* g = NULL;
+    byte* q = NULL;
+    byte* y = NULL;
+#else
+    byte p[MAX_DSA_INT_SZ];
+    byte g[MAX_DSA_INT_SZ];
+    byte q[MAX_DSA_INT_SZ];
+    byte y[MAX_DSA_INT_SZ];
+#endif
+    byte innerSeq[MAX_SEQ_SZ];
+    byte outerSeq[MAX_SEQ_SZ];
+    byte bitString[1 + MAX_LENGTH_SZ + 1];
+    int  idx, pSz, gSz, qSz, ySz, innerSeqSz, outerSeqSz, bitStringSz = 0;
+
+    WOLFSSL_ENTER("wc_SetDsaPublicKey");
+
+    if (output == NULL || key == NULL || outLen < MAX_SEQ_SZ) {
+        return BAD_FUNC_ARG;
+    }
+
+    /* p */
+#ifdef WOLFSSL_SMALL_STACK
+    p = (byte*)XMALLOC(MAX_DSA_INT_SZ, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
+    if (p == NULL)
+        return MEMORY_E;
+#endif
+    if ((pSz = SetASNIntMP(&key->p, MAX_DSA_INT_SZ, p)) < 0) {
+        WOLFSSL_MSG("SetASNIntMP Error with p");
+#ifdef WOLFSSL_SMALL_STACK
+        XFREE(p, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
+#endif
+        return pSz;
+    }
+
+    /* q */
+#ifdef WOLFSSL_SMALL_STACK
+    q = (byte*)XMALLOC(MAX_DSA_INT_SZ, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
+    if (q == NULL)
+        return MEMORY_E;
+#endif
+    if ((qSz = SetASNIntMP(&key->q, MAX_DSA_INT_SZ, q)) < 0) {
+        WOLFSSL_MSG("SetASNIntMP Error with q");
+#ifdef WOLFSSL_SMALL_STACK
+        XFREE(p, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
+        XFREE(q, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
+#endif
+        return qSz;
+    }
+
+    /* g */
+#ifdef WOLFSSL_SMALL_STACK
+    g = (byte*)XMALLOC(MAX_DSA_INT_SZ, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
+    if (g == NULL)
+        return MEMORY_E;
+#endif
+    if ((gSz = SetASNIntMP(&key->g, MAX_DSA_INT_SZ, g)) < 0) {
+        WOLFSSL_MSG("SetASNIntMP Error with g");
+#ifdef WOLFSSL_SMALL_STACK
+        XFREE(p, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
+        XFREE(q, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
+        XFREE(g, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
+#endif
+        return gSz;
+    }
+
+    /* y */
+#ifdef WOLFSSL_SMALL_STACK
+    y = (byte*)XMALLOC(MAX_DSA_INT_SZ, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
+    if (y == NULL)
+        return MEMORY_E;
+#endif
+    if ((ySz = SetASNIntMP(&key->y, MAX_DSA_INT_SZ, y)) < 0) {
+        WOLFSSL_MSG("SetASNIntMP Error with y");
+#ifdef WOLFSSL_SMALL_STACK
+        XFREE(p, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
+        XFREE(q, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
+        XFREE(g, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
+        XFREE(y, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
+#endif
+        return ySz;
+    }
+
+    innerSeqSz  = SetSequence(pSz + qSz + gSz, innerSeq);
+
+    /* check output size */
+    if ((innerSeqSz + pSz + qSz + gSz) > outLen) {
+#ifdef WOLFSSL_SMALL_STACK
+        XFREE(p,    key->heap, DYNAMIC_TYPE_TMP_BUFFER);
+        XFREE(q,    key->heap, DYNAMIC_TYPE_TMP_BUFFER);
+        XFREE(g,    key->heap, DYNAMIC_TYPE_TMP_BUFFER);
+        XFREE(y,    key->heap, DYNAMIC_TYPE_TMP_BUFFER);
+#endif
+        WOLFSSL_MSG("Error, output size smaller than outlen");
+        return BUFFER_E;
+    }
+
+    if (with_header) {
+        int algoSz;
+#ifdef WOLFSSL_SMALL_STACK
+        byte* algo = NULL;
+
+        algo = (byte*)XMALLOC(MAX_ALGO_SZ, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
+        if (algo == NULL) {
+            XFREE(p,    key->heap, DYNAMIC_TYPE_TMP_BUFFER);
+            XFREE(q,    key->heap, DYNAMIC_TYPE_TMP_BUFFER);
+            XFREE(g,    key->heap, DYNAMIC_TYPE_TMP_BUFFER);
+            XFREE(y,    key->heap, DYNAMIC_TYPE_TMP_BUFFER);
+            return MEMORY_E;
+        }
+#else
+        byte algo[MAX_ALGO_SZ];
+#endif
+        algoSz = SetAlgoID(DSAk, algo, oidKeyType, 0);
+        bitStringSz  = SetBitString(ySz, 0, bitString);
+        outerSeqSz = SetSequence(algoSz + innerSeqSz + pSz + qSz + gSz,
+                                                                      outerSeq);
+
+        idx = SetSequence(algoSz + innerSeqSz + pSz + qSz + gSz + bitStringSz +
+                                                      ySz + outerSeqSz, output);
+
+        /* check output size */
+        if ((idx + algoSz + bitStringSz + innerSeqSz + pSz + qSz + gSz + ySz) >
+                                                                       outLen) {
+            #ifdef WOLFSSL_SMALL_STACK
+                XFREE(p,    key->heap, DYNAMIC_TYPE_TMP_BUFFER);
+                XFREE(q,    key->heap, DYNAMIC_TYPE_TMP_BUFFER);
+                XFREE(g,    key->heap, DYNAMIC_TYPE_TMP_BUFFER);
+                XFREE(y,    key->heap, DYNAMIC_TYPE_TMP_BUFFER);
+                XFREE(algo, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
+            #endif
+            WOLFSSL_MSG("Error, output size smaller than outlen");
+            return BUFFER_E;
+        }
+
+        /* outerSeq */
+        XMEMCPY(output + idx, outerSeq, outerSeqSz);
+        idx += outerSeqSz;
+        /* algo */
+        XMEMCPY(output + idx, algo, algoSz);
+        idx += algoSz;
+#ifdef WOLFSSL_SMALL_STACK
+        XFREE(algo, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
+#endif
+    } else {
+        idx = 0;
+    }
+
+    /* innerSeq */
+    XMEMCPY(output + idx, innerSeq, innerSeqSz);
+    idx += innerSeqSz;
+    /* p */
+    XMEMCPY(output + idx, p, pSz);
+    idx += pSz;
+    /* q */
+    XMEMCPY(output + idx, q, qSz);
+    idx += qSz;
+    /* g */
+    XMEMCPY(output + idx, g, gSz);
+    idx += gSz;
+    /* bit string */
+    XMEMCPY(output + idx, bitString, bitStringSz);
+    idx += bitStringSz;
+    /* y */
+    XMEMCPY(output + idx, y, ySz);
+    idx += ySz;
+
+#ifdef WOLFSSL_SMALL_STACK
+    XFREE(p,    key->heap, DYNAMIC_TYPE_TMP_BUFFER);
+    XFREE(q,    key->heap, DYNAMIC_TYPE_TMP_BUFFER);
+    XFREE(g,    key->heap, DYNAMIC_TYPE_TMP_BUFFER);
+    XFREE(y,    key->heap, DYNAMIC_TYPE_TMP_BUFFER);
+#endif
+    return idx;
+}
+
+/* Convert DSA Public key to DER format, write to output (inLen), return bytes
+   written */
+int wc_DsaKeyToPublicDer(DsaKey* key, byte* output, word32 inLen)
+{
+    return wc_SetDsaPublicKey(output, key, inLen, 1);
+}
+#endif /* !HAVE_SELFTEST && WOLFSSL_KEY_GEN */
+
+/* Convert private DsaKey key to DER format, write to output (inLen),
+   return bytes written */
+int wc_DsaKeyToDer(DsaKey* key, byte* output, word32 inLen)
+{
+    word32 seqSz, verSz, rawLen, intTotalLen = 0;
+    word32 sizes[DSA_INTS];
+    int    i, j, outLen, ret = 0, mpSz;
+
+    byte  seq[MAX_SEQ_SZ];
+    byte  ver[MAX_VERSION_SZ];
+    byte* tmps[DSA_INTS];
+
+    if (!key || !output)
+        return BAD_FUNC_ARG;
+
+    if (key->type != DSA_PRIVATE)
+        return BAD_FUNC_ARG;
+
+    for (i = 0; i < DSA_INTS; i++)
+        tmps[i] = NULL;
+
+    /* write all big ints from key to DER tmps */
+    for (i = 0; i < DSA_INTS; i++) {
+        mp_int* keyInt = GetDsaInt(key, i);
+
+        rawLen = mp_unsigned_bin_size(keyInt) + 1;
+        tmps[i] = (byte*)XMALLOC(rawLen + MAX_SEQ_SZ, key->heap,
+                                                              DYNAMIC_TYPE_DSA);
+        if (tmps[i] == NULL) {
+            ret = MEMORY_E;
+            break;
+        }
+
+        mpSz = SetASNIntMP(keyInt, -1, tmps[i]);
+        if (mpSz < 0) {
+            ret = mpSz;
+            break;
+        }
+        intTotalLen += (sizes[i] = mpSz);
+    }
+
+    if (ret != 0) {
+        FreeTmpDsas(tmps, key->heap);
+        return ret;
+    }
+
+    /* make headers */
+    verSz = SetMyVersion(0, ver, FALSE);
+    seqSz = SetSequence(verSz + intTotalLen, seq);
+
+    outLen = seqSz + verSz + intTotalLen;
+    if (outLen > (int)inLen) {
+        FreeTmpDsas(tmps, key->heap);
+        return BAD_FUNC_ARG;
+    }
+
+    /* write to output */
+    XMEMCPY(output, seq, seqSz);
+    j = seqSz;
+    XMEMCPY(output + j, ver, verSz);
+    j += verSz;
+
+    for (i = 0; i < DSA_INTS; i++) {
+        XMEMCPY(output + j, tmps[i], sizes[i]);
+        j += sizes[i];
+    }
+    FreeTmpDsas(tmps, key->heap);
+
+    return outLen;
+}
+
+#endif /* NO_DSA */
+
+void InitDecodedCert(DecodedCert* cert,
+                     const byte* source, word32 inSz, void* heap)
+{
+    if (cert != NULL) {
+        XMEMSET(cert, 0, sizeof(DecodedCert));
+
+        cert->subjectCNEnc    = CTC_UTF8;
+        cert->issuer[0]       = '\0';
+        cert->subject[0]      = '\0';
+        cert->source          = source;  /* don't own */
+        cert->maxIdx          = inSz;    /* can't go over this index */
+        cert->heap            = heap;
+        cert->maxPathLen      = WOLFSSL_MAX_PATH_LEN;
+    #ifdef WOLFSSL_CERT_GEN
+        cert->subjectSNEnc    = CTC_UTF8;
+        cert->subjectCEnc     = CTC_PRINTABLE;
+        cert->subjectLEnc     = CTC_UTF8;
+        cert->subjectSTEnc    = CTC_UTF8;
+        cert->subjectOEnc     = CTC_UTF8;
+        cert->subjectOUEnc    = CTC_UTF8;
+    #endif /* WOLFSSL_CERT_GEN */
+
+    #ifndef NO_CERTS
+        InitSignatureCtx(&cert->sigCtx, heap, INVALID_DEVID);
+    #endif
+    }
+}
+
+
+void FreeAltNames(DNS_entry* altNames, void* heap)
+{
+    (void)heap;
+
+    while (altNames) {
+        DNS_entry* tmp = altNames->next;
+
+        XFREE(altNames->name, heap, DYNAMIC_TYPE_ALTNAME);
+        XFREE(altNames,       heap, DYNAMIC_TYPE_ALTNAME);
+        altNames = tmp;
+    }
+}
+
+#ifndef IGNORE_NAME_CONSTRAINTS
+
+void FreeNameSubtrees(Base_entry* names, void* heap)
+{
+    (void)heap;
+
+    while (names) {
+        Base_entry* tmp = names->next;
+
+        XFREE(names->name, heap, DYNAMIC_TYPE_ALTNAME);
+        XFREE(names,       heap, DYNAMIC_TYPE_ALTNAME);
+        names = tmp;
+    }
+}
+
+#endif /* IGNORE_NAME_CONSTRAINTS */
+
+void FreeDecodedCert(DecodedCert* cert)
+{
+    if (cert == NULL)
+        return;
+    if (cert->subjectCNStored == 1)
+        XFREE(cert->subjectCN, cert->heap, DYNAMIC_TYPE_SUBJECT_CN);
+    if (cert->pubKeyStored == 1)
+        XFREE((void*)cert->publicKey, cert->heap, DYNAMIC_TYPE_PUBLIC_KEY);
+    if (cert->weOwnAltNames && cert->altNames)
+        FreeAltNames(cert->altNames, cert->heap);
+#ifndef IGNORE_NAME_CONSTRAINTS
+    if (cert->altEmailNames)
+        FreeAltNames(cert->altEmailNames, cert->heap);
+    if (cert->permittedNames)
+        FreeNameSubtrees(cert->permittedNames, cert->heap);
+    if (cert->excludedNames)
+        FreeNameSubtrees(cert->excludedNames, cert->heap);
+#endif /* IGNORE_NAME_CONSTRAINTS */
+#ifdef WOLFSSL_SEP
+    XFREE(cert->deviceType, cert->heap, DYNAMIC_TYPE_X509_EXT);
+    XFREE(cert->hwType, cert->heap, DYNAMIC_TYPE_X509_EXT);
+    XFREE(cert->hwSerialNum, cert->heap, DYNAMIC_TYPE_X509_EXT);
+#endif /* WOLFSSL_SEP */
+#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
+    if (cert->issuerName.fullName != NULL)
+        XFREE(cert->issuerName.fullName, cert->heap, DYNAMIC_TYPE_X509);
+    if (cert->subjectName.fullName != NULL)
+        XFREE(cert->subjectName.fullName, cert->heap, DYNAMIC_TYPE_X509);
+#endif /* OPENSSL_EXTRA */
+#ifdef WOLFSSL_RENESAS_TSIP_TLS
+    if (cert->tsip_encRsaKeyIdx != NULL)
+        XFREE(cert->tsip_encRsaKeyIdx, cert->heap, DYNAMIC_TYPE_RSA);
+#endif
+#ifndef NO_CERTS
+    FreeSignatureCtx(&cert->sigCtx);
+#endif
+}
+
+static int GetCertHeader(DecodedCert* cert)
+{
+    int ret = 0, len;
+
+    if (GetSequence(cert->source, &cert->srcIdx, &len, cert->maxIdx) < 0)
+        return ASN_PARSE_E;
+
+    /* Reset the max index for the size indicated in the outer wrapper. */
+    cert->maxIdx = len + cert->srcIdx;
+    cert->certBegin = cert->srcIdx;
+
+    if (GetSequence(cert->source, &cert->srcIdx, &len, cert->maxIdx) < 0)
+        return ASN_PARSE_E;
+
+    cert->sigIndex = len + cert->srcIdx;
+    if (cert->sigIndex > cert->maxIdx)
+        return ASN_PARSE_E;
+
+    if (GetExplicitVersion(cert->source, &cert->srcIdx, &cert->version,
+                                                            cert->sigIndex) < 0)
+        return ASN_PARSE_E;
+
+    if (GetSerialNumber(cert->source, &cert->srcIdx, cert->serial,
+                                           &cert->serialSz, cert->sigIndex) < 0)
+        return ASN_PARSE_E;
+
+    return ret;
+}
+
+#if !defined(NO_RSA)
+/* Store Rsa Key, may save later, Dsa could use in future */
+static int StoreRsaKey(DecodedCert* cert, word32 bitStringEnd)
+{
+    int    length;
+    word32 recvd = cert->srcIdx;
+
+    if (GetSequence(cert->source, &cert->srcIdx, &length, bitStringEnd) < 0)
+        return ASN_PARSE_E;
+
+    recvd = cert->srcIdx - recvd;
+    length += recvd;
+
+    while (recvd--)
+       cert->srcIdx--;
+#if defined(WOLFSSL_RENESAS_TSIP)
+    cert->sigCtx.pubkey_n_start = cert->sigCtx.pubkey_e_start = cert->srcIdx;
+#endif
+    cert->pubKeySize = length;
+    cert->publicKey = cert->source + cert->srcIdx;
+    cert->srcIdx += length;
+
+    return 0;
+}
+#endif /* !NO_RSA */
+
+#ifdef HAVE_ECC
+
+    /* return 0 on success if the ECC curve oid sum is supported */
+    static int CheckCurve(word32 oid)
+    {
+        int ret = 0;
+        word32 oidSz = 0;
+
+        ret = wc_ecc_get_oid(oid, NULL, &oidSz);
+        if (ret < 0 || oidSz == 0) {
+            WOLFSSL_MSG("CheckCurve not found");
+            ret = ALGO_ID_E;
+        }
+
+        return ret;
+    }
+
+#endif /* HAVE_ECC */
+
+static int GetKey(DecodedCert* cert)
+{
+    int length;
+#if !defined(NO_DSA) && defined(WOLFSSL_QT)
+    int tmpLen;
+#endif
+#if defined(HAVE_ECC) || defined(HAVE_NTRU)
+    int tmpIdx = cert->srcIdx;
+#endif
+
+    if (GetSequence(cert->source, &cert->srcIdx, &length, cert->maxIdx) < 0)
+        return ASN_PARSE_E;
+
+#if !defined(NO_DSA) && defined(WOLFSSL_QT)
+    tmpLen = length + 4;
+#endif
+
+    if (GetAlgoId(cert->source, &cert->srcIdx,
+                  &cert->keyOID, oidKeyType, cert->maxIdx) < 0)
+        return ASN_PARSE_E;
+
+    switch (cert->keyOID) {
+   #ifndef NO_RSA
+        case RSAk:
+        {
+            int ret;
+
+            ret = CheckBitString(cert->source, &cert->srcIdx, &length,
+                                 cert->maxIdx, 1, NULL);
+            if (ret != 0)
+                return ret;
+
+            #ifdef HAVE_OCSP
+                ret = CalcHashId(cert->source + cert->srcIdx, length,
+                        cert->subjectKeyHash);
+                if (ret != 0)
+                    return ret;
+            #endif
+
+            return StoreRsaKey(cert, cert->srcIdx + length);
+        }
+
+    #endif /* NO_RSA */
+    #ifdef HAVE_NTRU
+        case NTRUk:
+        {
+            const byte* key = &cert->source[tmpIdx];
+            byte*       next = (byte*)key;
+            word16      keyLen;
+            word32      rc;
+            word32      remaining = cert->maxIdx - cert->srcIdx;
+            byte*       publicKey;
+#ifdef WOLFSSL_SMALL_STACK
+            byte*       keyBlob = NULL;
+#else
+            byte        keyBlob[MAX_NTRU_KEY_SZ];
+#endif
+            rc = ntru_crypto_ntru_encrypt_subjectPublicKeyInfo2PublicKey(key,
+                                &keyLen, NULL, &next, &remaining);
+            if (rc != NTRU_OK)
+                return ASN_NTRU_KEY_E;
+            if (keyLen > MAX_NTRU_KEY_SZ)
+                return ASN_NTRU_KEY_E;
+
+#ifdef WOLFSSL_SMALL_STACK
+            keyBlob = (byte*)XMALLOC(MAX_NTRU_KEY_SZ, cert->heap,
+                                     DYNAMIC_TYPE_TMP_BUFFER);
+            if (keyBlob == NULL)
+                return MEMORY_E;
+#endif
+
+            rc = ntru_crypto_ntru_encrypt_subjectPublicKeyInfo2PublicKey(key,
+                                &keyLen, keyBlob, &next, &remaining);
+            if (rc != NTRU_OK) {
+#ifdef WOLFSSL_SMALL_STACK
+                XFREE(keyBlob, cert->heap, DYNAMIC_TYPE_TMP_BUFFER);
+#endif
+                return ASN_NTRU_KEY_E;
+            }
+
+            if ( (next - key) < 0) {
+#ifdef WOLFSSL_SMALL_STACK
+                XFREE(keyBlob, cert->heap, DYNAMIC_TYPE_TMP_BUFFER);
+#endif
+                return ASN_NTRU_KEY_E;
+            }
+
+            cert->srcIdx = tmpIdx + (int)(next - key);
+
+            publicKey = (byte*)XMALLOC(keyLen, cert->heap,
+                                       DYNAMIC_TYPE_PUBLIC_KEY);
+            if (publicKey == NULL) {
+#ifdef WOLFSSL_SMALL_STACK
+                XFREE(keyBlob, cert->heap, DYNAMIC_TYPE_TMP_BUFFER);
+#endif
+                return MEMORY_E;
+            }
+            XMEMCPY(publicKey, keyBlob, keyLen);
+            cert->publicKey = publicKey;
+            cert->pubKeyStored = 1;
+            cert->pubKeySize   = keyLen;
+
+#ifdef WOLFSSL_SMALL_STACK
+            XFREE(keyBlob, cert->heap, DYNAMIC_TYPE_TMP_BUFFER);
+#endif
+
+            return 0;
+        }
+    #endif /* HAVE_NTRU */
+    #ifdef HAVE_ECC
+        case ECDSAk:
+        {
+            int ret;
+            byte seq[5];
+            int pubLen = length + 1 + SetLength(length, seq);
+            word32 localIdx;
+            byte* publicKey;
+            byte  tag;
+
+            localIdx = cert->srcIdx;
+            if (GetASNTag(cert->source, &localIdx, &tag, cert->maxIdx) < 0)
+                return ASN_PARSE_E;
+
+            if (tag != (ASN_SEQUENCE | ASN_CONSTRUCTED)) {
+                if (GetObjectId(cert->source, &cert->srcIdx,
+                            &cert->pkCurveOID, oidCurveType, cert->maxIdx) < 0)
+                    return ASN_PARSE_E;
+
+                if (CheckCurve(cert->pkCurveOID) < 0)
+                    return ECC_CURVE_OID_E;
+
+                /* key header */
+                ret = CheckBitString(cert->source, &cert->srcIdx, &length,
+                                                         cert->maxIdx, 1, NULL);
+                if (ret != 0)
+                    return ret;
+            #ifdef HAVE_OCSP
+                ret = CalcHashId(cert->source + cert->srcIdx, length,
+                        cert->subjectKeyHash);
+                if (ret != 0)
+                    return ret;
+            #endif
+            }
+
+            publicKey = (byte*)XMALLOC(pubLen, cert->heap,
+                                       DYNAMIC_TYPE_PUBLIC_KEY);
+            if (publicKey == NULL)
+                return MEMORY_E;
+            XMEMCPY(publicKey, &cert->source[tmpIdx], pubLen);
+            cert->publicKey = publicKey;
+            cert->pubKeyStored = 1;
+            cert->pubKeySize   = pubLen;
+
+            cert->srcIdx = tmpIdx + pubLen;
+
+            return 0;
+        }
+    #endif /* HAVE_ECC */
+    #ifdef HAVE_ED25519
+        case ED25519k:
+        {
+            byte* publicKey;
+            int ret;
+
+            cert->pkCurveOID = ED25519k;
+
+            ret = CheckBitString(cert->source, &cert->srcIdx, &length,
+                                 cert->maxIdx, 1, NULL);
+            if (ret != 0)
+                return ret;
+
+            #ifdef HAVE_OCSP
+                ret = CalcHashId(cert->source + cert->srcIdx, length,
+                        cert->subjectKeyHash);
+                if (ret != 0)
+                    return ret;
+            #endif
+
+            publicKey = (byte*) XMALLOC(length, cert->heap,
+                                        DYNAMIC_TYPE_PUBLIC_KEY);
+            if (publicKey == NULL)
+                return MEMORY_E;
+            XMEMCPY(publicKey, &cert->source[cert->srcIdx], length);
+            cert->publicKey = publicKey;
+            cert->pubKeyStored = 1;
+            cert->pubKeySize   = length;
+
+            cert->srcIdx += length;
+
+            return 0;
+        }
+    #endif /* HAVE_ED25519 */
+    #ifdef HAVE_ED448
+        case ED448k:
+        {
+            byte* publicKey;
+            int ret;
+
+            cert->pkCurveOID = ED448k;
+
+            ret = CheckBitString(cert->source, &cert->srcIdx, &length,
+                                 cert->maxIdx, 1, NULL);
+            if (ret != 0)
+                return ret;
+
+            #ifdef HAVE_OCSP
+                ret = CalcHashId(cert->source + cert->srcIdx, length,
+                                 cert->subjectKeyHash);
+                if (ret != 0)
+                    return ret;
+            #endif
+
+            publicKey = (byte*) XMALLOC(length, cert->heap,
+                                        DYNAMIC_TYPE_PUBLIC_KEY);
+            if (publicKey == NULL)
+                return MEMORY_E;
+            XMEMCPY(publicKey, &cert->source[cert->srcIdx], length);
+            cert->publicKey = publicKey;
+            cert->pubKeyStored = 1;
+            cert->pubKeySize   = length;
+
+            cert->srcIdx += length;
+
+            return 0;
+        }
+    #endif /* HAVE_ED448 */
+    #if !defined(NO_DSA) && defined(WOLFSSL_QT)
+        case DSAk:
+        {
+            int ret;
+            ret = GetSequence(cert->source, &cert->srcIdx, &length,
+                           cert->maxIdx);
+            if (ret < 0)
+                return ret;
+
+            ret = SkipInt(cert->source, &cert->srcIdx, cert->maxIdx);
+            if (ret != 0)
+                return ret;
+            ret = SkipInt(cert->source, &cert->srcIdx, cert->maxIdx);
+            if (ret != 0)
+                return ret;
+            ret = SkipInt(cert->source, &cert->srcIdx, cert->maxIdx);
+            if (ret != 0)
+                return ret;
+
+            ret = CheckBitString(cert->source, &cert->srcIdx, &length,
+                                                         cert->maxIdx, 1, NULL);
+            if (ret != 0)
+                return ret;
+
+            ret = GetASNInt(cert->source, &cert->srcIdx, &length, cert->maxIdx);
+            if (ret !=0)
+                return ASN_PARSE_E;
+
+            cert->publicKey = cert->source + tmpIdx;
+            cert->pubKeySize = tmpLen;
+            cert->srcIdx += length;
+            return 0;
+        }
+    #endif /* NO_DSA && QT */
+        default:
+            return ASN_UNKNOWN_OID_E;
+    }
+}
+
+#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
+#if defined(HAVE_ECC)
+/* Converts ECC curve enum values in ecc_curve_id to the associated OpenSSL NID
+    value */
+WOLFSSL_API int EccEnumToNID(int n)
+{
+    WOLFSSL_ENTER("EccEnumToNID()");
+
+    switch(n) {
+        case ECC_SECP192R1:
+            return NID_X9_62_prime192v1;
+        case ECC_PRIME192V2:
+            return NID_X9_62_prime192v2;
+        case ECC_PRIME192V3:
+            return NID_X9_62_prime192v3;
+        case ECC_PRIME239V1:
+            return NID_X9_62_prime239v1;
+        case ECC_PRIME239V2:
+            return NID_X9_62_prime239v2;
+        case ECC_PRIME239V3:
+            return NID_X9_62_prime239v3;
+        case ECC_SECP256R1:
+            return NID_X9_62_prime256v1;
+        case ECC_SECP112R1:
+            return NID_secp112r1;
+        case ECC_SECP112R2:
+            return NID_secp112r2;
+        case ECC_SECP128R1:
+            return NID_secp128r1;
+        case ECC_SECP128R2:
+            return NID_secp128r2;
+        case ECC_SECP160R1:
+            return NID_secp160r1;
+        case ECC_SECP160R2:
+            return NID_secp160r2;
+        case ECC_SECP224R1:
+            return NID_secp224r1;
+        case ECC_SECP384R1:
+            return NID_secp384r1;
+        case ECC_SECP521R1:
+            return NID_secp521r1;
+        case ECC_SECP160K1:
+            return NID_secp160k1;
+        case ECC_SECP192K1:
+            return NID_secp192k1;
+        case ECC_SECP224K1:
+            return NID_secp224k1;
+        case ECC_SECP256K1:
+            return NID_secp256k1;
+        case ECC_BRAINPOOLP160R1:
+            return NID_brainpoolP160r1;
+        case ECC_BRAINPOOLP192R1:
+            return NID_brainpoolP192r1;
+        case ECC_BRAINPOOLP224R1:
+            return NID_brainpoolP224r1;
+        case ECC_BRAINPOOLP256R1:
+            return NID_brainpoolP256r1;
+        case ECC_BRAINPOOLP320R1:
+            return NID_brainpoolP320r1;
+        case ECC_BRAINPOOLP384R1:
+            return NID_brainpoolP384r1;
+        case ECC_BRAINPOOLP512R1:
+            return NID_brainpoolP512r1;
+        default:
+            WOLFSSL_MSG("NID not found");
+            return -1;
+    }
+}
+#endif /* HAVE_ECC */
+#endif /* OPENSSL_EXTRA || OPENSSL_EXTRA_X509_SMALL */
+
+#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
+int wc_OBJ_sn2nid(const char *sn)
+{
+    const struct {
+        const char *sn;
+        int  nid;
+    } sn2nid[] = {
+        {WOLFSSL_COMMON_NAME, NID_commonName},
+        {WOLFSSL_COUNTRY_NAME, NID_countryName},
+        {WOLFSSL_LOCALITY_NAME, NID_localityName},
+        {WOLFSSL_STATE_NAME, NID_stateOrProvinceName},
+        {WOLFSSL_ORG_NAME, NID_organizationName},
+        {WOLFSSL_ORGUNIT_NAME, NID_organizationalUnitName},
+        {WOLFSSL_EMAIL_ADDR, NID_emailAddress},
+        {NULL, -1}};
+
+    int i;
+    #ifdef HAVE_ECC
+    int eccEnum;
+    #endif
+    WOLFSSL_ENTER("OBJ_sn2nid");
+    for(i=0; sn2nid[i].sn != NULL; i++) {
+        if(XSTRNCMP(sn, sn2nid[i].sn, XSTRLEN(sn2nid[i].sn)) == 0) {
+            return sn2nid[i].nid;
+        }
+    }
+    #ifdef HAVE_ECC
+    /* Nginx uses this OpenSSL string. */
+    if (XSTRNCMP(sn, "prime256v1", 10) == 0)
+        sn = "SECP256R1";
+    if (XSTRNCMP(sn, "secp384r1", 10) == 0)
+        sn = "SECP384R1";
+    /* find based on name and return NID */
+    for (i = 0; ecc_sets[i].size != 0 && ecc_sets[i].name != NULL; i++) {
+        if (XSTRNCMP(sn, ecc_sets[i].name, ECC_MAXNAME) == 0) {
+            eccEnum = ecc_sets[i].id;
+            /* Convert enum value in ecc_curve_id to OpenSSL NID */
+            return EccEnumToNID(eccEnum);
+        }
+    }
+    #endif
+
+    return NID_undef;
+}
+#endif
+
+/* Routine for calculating hashId */
+int CalcHashId(const byte* data, word32 len, byte* hash)
+{
+    int ret;
+
+#ifdef WOLF_CRYPTO_CB
+    /* try to use a registered crypto callback */
+    ret = wc_CryptoCb_Sha256Hash(NULL, data, len, hash);
+    if (ret != CRYPTOCB_UNAVAILABLE)
+        return ret;
+    /* fall-through when unavailable */
+#endif
+
+#if defined(NO_SHA) && !defined(NO_SHA256)
+    ret = wc_Sha256Hash(data, len, hash);
+#elif !defined(NO_SHA)
+    ret = wc_ShaHash(data, len, hash);
+#else
+    ret = NOT_COMPILED_IN;
+#endif
+
+    return ret;
+}
+
+/* process NAME, either issuer or subject */
+static int GetName(DecodedCert* cert, int nameType, int maxIdx)
+{
+    int    length;  /* length of all distinguished names */
+    int    dummy;
+    int    ret;
+    char*  full;
+    byte*  hash;
+    word32 idx, localIdx = 0;
+    byte   tag;
+    #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
+        DecodedName* dName =
+                  (nameType == ISSUER) ? &cert->issuerName : &cert->subjectName;
+        int dcnum = 0;
+        #ifdef OPENSSL_EXTRA
+        int count = 0;
+        #endif
+    #endif /* OPENSSL_EXTRA */
+
+    WOLFSSL_MSG("Getting Cert Name");
+
+    if (nameType == ISSUER) {
+        full = cert->issuer;
+        hash = cert->issuerHash;
+    }
+    else {
+        full = cert->subject;
+        hash = cert->subjectHash;
+    }
+
+    if (cert->srcIdx >= (word32)maxIdx) {
+        return BUFFER_E;
+    }
+
+    localIdx = cert->srcIdx;
+    if (GetASNTag(cert->source, &localIdx, &tag, maxIdx) < 0) {
+        return ASN_PARSE_E;
+    }
+
+    if (tag == ASN_OBJECT_ID) {
+        WOLFSSL_MSG("Trying optional prefix...");
+
+        if (SkipObjectId(cert->source, &cert->srcIdx, maxIdx) < 0)
+            return ASN_PARSE_E;
+        WOLFSSL_MSG("Got optional prefix");
+    }
+
+    /* For OCSP, RFC2560 section 4.1.1 states the issuer hash should be
+     * calculated over the entire DER encoding of the Name field, including
+     * the tag and length. */
+    idx = cert->srcIdx;
+    if (GetSequence(cert->source, &cert->srcIdx, &length, maxIdx) < 0)
+        return ASN_PARSE_E;
+
+    ret = CalcHashId(&cert->source[idx], length + cert->srcIdx - idx, hash);
+    if (ret != 0)
+        return ret;
+
+    length += cert->srcIdx;
+    idx = 0;
+
+#if defined(HAVE_PKCS7) || defined(WOLFSSL_CERT_EXT)
+    /* store pointer to raw issuer */
+    if (nameType == ISSUER) {
+        cert->issuerRaw = &cert->source[cert->srcIdx];
+        cert->issuerRawLen = length - cert->srcIdx;
+    }
+#endif
+#ifndef IGNORE_NAME_CONSTRAINTS
+    if (nameType == SUBJECT) {
+        cert->subjectRaw = &cert->source[cert->srcIdx];
+        cert->subjectRawLen = length - cert->srcIdx;
+    }
+#endif
+
+    while (cert->srcIdx < (word32)length) {
+        byte        b       = 0;
+        byte        joint[3];
+        byte        tooBig  = FALSE;
+        int         oidSz;
+        const char* copy    = NULL;
+        int         copyLen = 0;
+        int         strLen  = 0;
+        byte        id      = 0;
+
+        if (GetSet(cert->source, &cert->srcIdx, &dummy, maxIdx) < 0) {
+            WOLFSSL_MSG("Cert name lacks set header, trying sequence");
+        }
+
+        if (GetSequence(cert->source, &cert->srcIdx, &dummy, maxIdx) <= 0)
+            return ASN_PARSE_E;
+
+        ret = GetASNObjectId(cert->source, &cert->srcIdx, &oidSz, maxIdx);
+        if (ret != 0)
+            return ret;
+
+        /* make sure there is room for joint */
+        if ((cert->srcIdx + sizeof(joint)) > (word32)maxIdx)
+            return ASN_PARSE_E;
+
+        XMEMCPY(joint, &cert->source[cert->srcIdx], sizeof(joint));
+
+        /* v1 name types */
+        if (joint[0] == 0x55 && joint[1] == 0x04) {
+            cert->srcIdx += 3;
+            id = joint[2];
+            if (GetHeader(cert->source, &b, &cert->srcIdx, &strLen,
+                          maxIdx, 1) < 0) {
+                return ASN_PARSE_E;
+            }
+
+            if (id == ASN_COMMON_NAME) {
+                if (nameType == SUBJECT) {
+                    cert->subjectCN = (char *)&cert->source[cert->srcIdx];
+                    cert->subjectCNLen = strLen;
+                    cert->subjectCNEnc = b;
+                }
+
+                copy = WOLFSSL_COMMON_NAME;
+                copyLen = sizeof(WOLFSSL_COMMON_NAME) - 1;
+                #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
+                    dName->cnIdx = cert->srcIdx;
+                    dName->cnLen = strLen;
+                #endif /* OPENSSL_EXTRA */
+            }
+            else if (id == ASN_SUR_NAME) {
+                copy = WOLFSSL_SUR_NAME;
+                copyLen = sizeof(WOLFSSL_SUR_NAME) - 1;
+                #ifdef WOLFSSL_CERT_GEN
+                    if (nameType == SUBJECT) {
+                        cert->subjectSN = (char*)&cert->source[cert->srcIdx];
+                        cert->subjectSNLen = strLen;
+                        cert->subjectSNEnc = b;
+                    }
+                #endif /* WOLFSSL_CERT_GEN */
+                #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
+                    dName->snIdx = cert->srcIdx;
+                    dName->snLen = strLen;
+                #endif /* OPENSSL_EXTRA */
+            }
+            else if (id == ASN_COUNTRY_NAME) {
+                copy = WOLFSSL_COUNTRY_NAME;
+                copyLen = sizeof(WOLFSSL_COUNTRY_NAME) - 1;
+                #ifdef WOLFSSL_CERT_GEN
+                    if (nameType == SUBJECT) {
+                        cert->subjectC = (char*)&cert->source[cert->srcIdx];
+                        cert->subjectCLen = strLen;
+                        cert->subjectCEnc = b;
+                    }
+                #endif /* WOLFSSL_CERT_GEN */
+                #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
+                    dName->cIdx = cert->srcIdx;
+                    dName->cLen = strLen;
+                #endif /* OPENSSL_EXTRA */
+            }
+            else if (id == ASN_LOCALITY_NAME) {
+                copy = WOLFSSL_LOCALITY_NAME;
+                copyLen = sizeof(WOLFSSL_LOCALITY_NAME) - 1;
+                #ifdef WOLFSSL_CERT_GEN
+                    if (nameType == SUBJECT) {
+                        cert->subjectL = (char*)&cert->source[cert->srcIdx];
+                        cert->subjectLLen = strLen;
+                        cert->subjectLEnc = b;
+                    }
+                #endif /* WOLFSSL_CERT_GEN */
+                #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
+                    dName->lIdx = cert->srcIdx;
+                    dName->lLen = strLen;
+                #endif /* OPENSSL_EXTRA */
+            }
+            else if (id == ASN_STATE_NAME) {
+                copy = WOLFSSL_STATE_NAME;
+                copyLen = sizeof(WOLFSSL_STATE_NAME) - 1;
+                #ifdef WOLFSSL_CERT_GEN
+                    if (nameType == SUBJECT) {
+                        cert->subjectST = (char*)&cert->source[cert->srcIdx];
+                        cert->subjectSTLen = strLen;
+                        cert->subjectSTEnc = b;
+                    }
+                #endif /* WOLFSSL_CERT_GEN */
+                #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
+                    dName->stIdx = cert->srcIdx;
+                    dName->stLen = strLen;
+                #endif /* OPENSSL_EXTRA */
+            }
+            else if (id == ASN_ORG_NAME) {
+                copy = WOLFSSL_ORG_NAME;
+                copyLen = sizeof(WOLFSSL_ORG_NAME) - 1;
+                #ifdef WOLFSSL_CERT_GEN
+                    if (nameType == SUBJECT) {
+                        cert->subjectO = (char*)&cert->source[cert->srcIdx];
+                        cert->subjectOLen = strLen;
+                        cert->subjectOEnc = b;
+                    }
+                #endif /* WOLFSSL_CERT_GEN */
+                #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
+                    dName->oIdx = cert->srcIdx;
+                    dName->oLen = strLen;
+                #endif /* OPENSSL_EXTRA */
+            }
+            else if (id == ASN_ORGUNIT_NAME) {
+                copy = WOLFSSL_ORGUNIT_NAME;
+                copyLen = sizeof(WOLFSSL_ORGUNIT_NAME) - 1;
+                #ifdef WOLFSSL_CERT_GEN
+                    if (nameType == SUBJECT) {
+                        cert->subjectOU = (char*)&cert->source[cert->srcIdx];
+                        cert->subjectOULen = strLen;
+                        cert->subjectOUEnc = b;
+                    }
+                #endif /* WOLFSSL_CERT_GEN */
+                #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
+                    dName->ouIdx = cert->srcIdx;
+                    dName->ouLen = strLen;
+                #endif /* OPENSSL_EXTRA */
+            }
+            else if (id == ASN_SERIAL_NUMBER) {
+                copy = WOLFSSL_SERIAL_NUMBER;
+                copyLen = sizeof(WOLFSSL_SERIAL_NUMBER) - 1;
+                #ifdef WOLFSSL_CERT_GEN
+                    if (nameType == SUBJECT) {
+                        cert->subjectSND = (char*)&cert->source[cert->srcIdx];
+                        cert->subjectSNDLen = strLen;
+                        cert->subjectSNDEnc = b;
+                    }
+                #endif /* WOLFSSL_CERT_GEN */
+                #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
+                    dName->snIdx = cert->srcIdx;
+                    dName->snLen = strLen;
+                #endif /* OPENSSL_EXTRA */
+            }
+        #ifdef WOLFSSL_CERT_EXT
+            else if (id == ASN_BUS_CAT) {
+                copy = WOLFSSL_BUS_CAT;
+                copyLen = sizeof(WOLFSSL_BUS_CAT) - 1;
+            #ifdef WOLFSSL_CERT_GEN
+                if (nameType == SUBJECT) {
+                    cert->subjectBC = (char*)&cert->source[cert->srcIdx];
+                    cert->subjectBCLen = strLen;
+                    cert->subjectBCEnc = b;
+                }
+            #endif /* WOLFSSL_CERT_GEN */
+            #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
+                dName->bcIdx = cert->srcIdx;
+                dName->bcLen = strLen;
+            #endif /* OPENSSL_EXTRA */
+            }
+        #endif /* WOLFSSL_CERT_EXT */
+        }
+    #ifdef WOLFSSL_CERT_EXT
+        else if ((cert->srcIdx + ASN_JOI_PREFIX_SZ + 2 <= (word32)maxIdx) &&
+                 (0 == XMEMCMP(&cert->source[cert->srcIdx], ASN_JOI_PREFIX,
+                               ASN_JOI_PREFIX_SZ)) &&
+                 ((cert->source[cert->srcIdx+ASN_JOI_PREFIX_SZ] == ASN_JOI_C) ||
+                  (cert->source[cert->srcIdx+ASN_JOI_PREFIX_SZ] == ASN_JOI_ST)))
+        {
+            cert->srcIdx += ASN_JOI_PREFIX_SZ;
+            id = cert->source[cert->srcIdx++];
+            b = cert->source[cert->srcIdx++]; /* encoding */
+
+            if (GetLength(cert->source, &cert->srcIdx, &strLen,
+                          maxIdx) < 0)
+                return ASN_PARSE_E;
+
+            /* Check for jurisdiction of incorporation country name */
+            if (id == ASN_JOI_C) {
+                copy = WOLFSSL_JOI_C;
+                copyLen = sizeof(WOLFSSL_JOI_C) - 1;
+                #ifdef WOLFSSL_CERT_GEN
+                    if (nameType == SUBJECT) {
+                        cert->subjectJC = (char*)&cert->source[cert->srcIdx];
+                        cert->subjectJCLen = strLen;
+                        cert->subjectJCEnc = b;
+                    }
+                #endif /* WOLFSSL_CERT_GEN */
+                #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
+                    dName->jcIdx = cert->srcIdx;
+                    dName->jcLen = strLen;
+                #endif /* OPENSSL_EXTRA */
+            }
+
+            /* Check for jurisdiction of incorporation state name */
+            else if (id == ASN_JOI_ST) {
+                copy = WOLFSSL_JOI_ST;
+                copyLen = sizeof(WOLFSSL_JOI_ST) - 1;
+                #ifdef WOLFSSL_CERT_GEN
+                    if (nameType == SUBJECT) {
+                        cert->subjectJS = (char*)&cert->source[cert->srcIdx];
+                        cert->subjectJSLen = strLen;
+                        cert->subjectJSEnc = b;
+                    }
+                #endif /* WOLFSSL_CERT_GEN */
+                #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
+                    dName->jsIdx = cert->srcIdx;
+                    dName->jsLen = strLen;
+                #endif /* OPENSSL_EXTRA */
+            }
+
+            if ((strLen + copyLen) > (int)(ASN_NAME_MAX - idx)) {
+                WOLFSSL_MSG("ASN Name too big, skipping");
+                tooBig = TRUE;
+            }
+        }
+    #endif /* WOLFSSL_CERT_EXT */
+        else {
+            /* skip */
+            byte email = FALSE;
+            byte pilot = FALSE;
+
+            if (joint[0] == 0x2a && joint[1] == 0x86) {  /* email id hdr */
+                id = ASN_EMAIL_NAME;
+                email = TRUE;
+            }
+
+            if (joint[0] == 0x9  && joint[1] == 0x92) { /* uid id hdr */
+                /* last value of OID is the type of pilot attribute */
+                id    = cert->source[cert->srcIdx + oidSz - 1];
+                pilot = TRUE;
+            }
+
+            cert->srcIdx += oidSz + 1;
+
+            if (GetLength(cert->source, &cert->srcIdx, &strLen, maxIdx) < 0)
+                return ASN_PARSE_E;
+
+            if (strLen > (int)(ASN_NAME_MAX - idx)) {
+                WOLFSSL_MSG("ASN name too big, skipping");
+                tooBig = TRUE;
+            }
+
+            if (email) {
+                copyLen = sizeof(WOLFSSL_EMAIL_ADDR) - 1;
+                if ((copyLen + strLen) > (int)(ASN_NAME_MAX - idx)) {
+                    WOLFSSL_MSG("ASN name too big, skipping");
+                    tooBig = TRUE;
+                }
+                else {
+                    copy = WOLFSSL_EMAIL_ADDR;
+                }
+
+                #ifdef WOLFSSL_CERT_GEN
+                    if (nameType == SUBJECT) {
+                        cert->subjectEmail = (char*)&cert->source[cert->srcIdx];
+                        cert->subjectEmailLen = strLen;
+                    }
+                #endif /* WOLFSSL_CERT_GEN */
+                #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
+                    dName->emailIdx = cert->srcIdx;
+                    dName->emailLen = strLen;
+                #endif /* OPENSSL_EXTRA */
+                #ifndef IGNORE_NAME_CONSTRAINTS
+                    {
+                        DNS_entry* emailName;
+
+                        emailName = (DNS_entry*)XMALLOC(sizeof(DNS_entry),
+                                              cert->heap, DYNAMIC_TYPE_ALTNAME);
+                        if (emailName == NULL) {
+                            WOLFSSL_MSG("\tOut of Memory");
+                            return MEMORY_E;
+                        }
+                        emailName->type = 0;
+                        emailName->name = (char*)XMALLOC(strLen + 1,
+                                              cert->heap, DYNAMIC_TYPE_ALTNAME);
+                        if (emailName->name == NULL) {
+                            WOLFSSL_MSG("\tOut of Memory");
+                            XFREE(emailName, cert->heap, DYNAMIC_TYPE_ALTNAME);
+                            return MEMORY_E;
+                        }
+                        emailName->len = strLen;
+                        XMEMCPY(emailName->name, &cert->source[cert->srcIdx],
+                                                                        strLen);
+                        emailName->name[strLen] = '\0';
+
+                        emailName->next = cert->altEmailNames;
+                        cert->altEmailNames = emailName;
+                    }
+                #endif /* IGNORE_NAME_CONSTRAINTS */
+            }
+
+            if (pilot) {
+                switch (id) {
+                    case ASN_USER_ID:
+                        copy = WOLFSSL_USER_ID;
+                        copyLen = sizeof(WOLFSSL_USER_ID) - 1;
+                    #if defined(OPENSSL_EXTRA) || \
+                        defined(OPENSSL_EXTRA_X509_SMALL)
+                        dName->uidIdx = cert->srcIdx;
+                        dName->uidLen = strLen;
+                    #endif /* OPENSSL_EXTRA */
+                        break;
+
+                    case ASN_DOMAIN_COMPONENT:
+                        copy = WOLFSSL_DOMAIN_COMPONENT;
+                        copyLen = sizeof(WOLFSSL_DOMAIN_COMPONENT) - 1;
+                    #if defined(OPENSSL_EXTRA) || \
+                        defined(OPENSSL_EXTRA_X509_SMALL)
+                        dName->dcIdx[dcnum] = cert->srcIdx;
+                        dName->dcLen[dcnum] = strLen;
+                        dName->dcNum = dcnum + 1;
+                        dcnum++;
+                    #endif /* OPENSSL_EXTRA */
+                        break;
+
+                    default:
+                        WOLFSSL_MSG("Unknown pilot attribute type");
+                        return ASN_PARSE_E;
+                }
+            }
+        }
+        if ((copyLen + strLen) > (int)(ASN_NAME_MAX - idx))
+        {
+            WOLFSSL_MSG("ASN Name too big, skipping");
+            tooBig = TRUE;
+        }
+        if ((copy != NULL) && !tooBig) {
+            XMEMCPY(&full[idx], copy, copyLen);
+            idx += copyLen;
+            XMEMCPY(&full[idx], &cert->source[cert->srcIdx], strLen);
+            idx += strLen;
+
+        #ifdef OPENSSL_EXTRA
+            if (count < DOMAIN_COMPONENT_MAX) {
+                /* store order that DN was parsed */
+                dName->loc[count++] = id;
+            }
+        #endif
+        }
+        cert->srcIdx += strLen;
+    }
+    full[idx++] = 0;
+#if defined(OPENSSL_EXTRA)
+    /* store order that DN was parsed */
+    dName->locSz = count;
+#endif
+
+    #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
+    {
+        int totalLen = 0;
+        int i = 0;
+
+        if (dName->cnLen != 0)
+            totalLen += dName->cnLen + 4;
+        if (dName->snLen != 0)
+            totalLen += dName->snLen + 4;
+        if (dName->cLen != 0)
+            totalLen += dName->cLen + 3;
+        if (dName->lLen != 0)
+            totalLen += dName->lLen + 3;
+        if (dName->stLen != 0)
+            totalLen += dName->stLen + 4;
+        if (dName->oLen != 0)
+            totalLen += dName->oLen + 3;
+        if (dName->ouLen != 0)
+            totalLen += dName->ouLen + 4;
+        if (dName->emailLen != 0)
+            totalLen += dName->emailLen + 14;
+        if (dName->uidLen != 0)
+            totalLen += dName->uidLen + 5;
+        if (dName->serialLen != 0)
+            totalLen += dName->serialLen + 14;
+        if (dName->dcNum != 0){
+            for (i = 0;i < dName->dcNum;i++)
+                totalLen += dName->dcLen[i] + 4;
+        }
+
+        dName->fullName = (char*)XMALLOC(totalLen + 1, cert->heap,
+                                                             DYNAMIC_TYPE_X509);
+        if (dName->fullName != NULL) {
+            idx = 0;
+
+            if (dName->cnLen != 0) {
+                dName->entryCount++;
+                XMEMCPY(&dName->fullName[idx], WOLFSSL_COMMON_NAME, 4);
+                dName->cnNid = wc_OBJ_sn2nid((const char *)WOLFSSL_COMMON_NAME);
+                idx += 4;
+                XMEMCPY(&dName->fullName[idx],
+                                     &cert->source[dName->cnIdx], dName->cnLen);
+                dName->cnIdx = idx;
+                idx += dName->cnLen;
+            }
+            if (dName->snLen != 0) {
+                dName->entryCount++;
+                XMEMCPY(&dName->fullName[idx], WOLFSSL_SUR_NAME, 4);
+                dName->snNid = wc_OBJ_sn2nid((const char *)WOLFSSL_SUR_NAME);
+                idx += 4;
+                XMEMCPY(&dName->fullName[idx],
+                                     &cert->source[dName->snIdx], dName->snLen);
+                dName->snIdx = idx;
+                idx += dName->snLen;
+            }
+            if (dName->cLen != 0) {
+                dName->entryCount++;
+                XMEMCPY(&dName->fullName[idx], WOLFSSL_COUNTRY_NAME, 3);
+                dName->cNid = wc_OBJ_sn2nid((const char *)WOLFSSL_COUNTRY_NAME);
+                idx += 3;
+                XMEMCPY(&dName->fullName[idx],
+                                       &cert->source[dName->cIdx], dName->cLen);
+                dName->cIdx = idx;
+                idx += dName->cLen;
+            }
+            if (dName->lLen != 0) {
+                dName->entryCount++;
+                XMEMCPY(&dName->fullName[idx], WOLFSSL_LOCALITY_NAME, 3);
+                dName->lNid = wc_OBJ_sn2nid((const char *)WOLFSSL_LOCALITY_NAME);
+                idx += 3;
+                XMEMCPY(&dName->fullName[idx],
+                                       &cert->source[dName->lIdx], dName->lLen);
+                dName->lIdx = idx;
+                idx += dName->lLen;
+            }
+            if (dName->stLen != 0) {
+                dName->entryCount++;
+                XMEMCPY(&dName->fullName[idx], WOLFSSL_STATE_NAME, 4);
+                dName->stNid = wc_OBJ_sn2nid((const char *)WOLFSSL_STATE_NAME);
+                idx += 4;
+                XMEMCPY(&dName->fullName[idx],
+                                     &cert->source[dName->stIdx], dName->stLen);
+                dName->stIdx = idx;
+                idx += dName->stLen;
+            }
+            if (dName->oLen != 0) {
+                dName->entryCount++;
+                XMEMCPY(&dName->fullName[idx], WOLFSSL_ORG_NAME, 3);
+                dName->oNid = wc_OBJ_sn2nid((const char *)WOLFSSL_ORG_NAME);
+                idx += 3;
+                XMEMCPY(&dName->fullName[idx],
+                                       &cert->source[dName->oIdx], dName->oLen);
+                dName->oIdx = idx;
+                idx += dName->oLen;
+            }
+            if (dName->ouLen != 0) {
+                dName->entryCount++;
+                XMEMCPY(&dName->fullName[idx], WOLFSSL_ORGUNIT_NAME, 4);
+                dName->ouNid = wc_OBJ_sn2nid((const char *)WOLFSSL_ORGUNIT_NAME);
+                idx += 4;
+                XMEMCPY(&dName->fullName[idx],
+                                     &cert->source[dName->ouIdx], dName->ouLen);
+                dName->ouIdx = idx;
+                idx += dName->ouLen;
+            }
+            if (dName->emailLen != 0) {
+                dName->entryCount++;
+                XMEMCPY(&dName->fullName[idx], "/emailAddress=", 14);
+                dName->emailNid = wc_OBJ_sn2nid((const char *)"/emailAddress=");
+                idx += 14;
+                XMEMCPY(&dName->fullName[idx],
+                               &cert->source[dName->emailIdx], dName->emailLen);
+                dName->emailIdx = idx;
+                idx += dName->emailLen;
+            }
+            for (i = 0;i < dName->dcNum;i++){
+                if (dName->dcLen[i] != 0) {
+                    dName->entryCount++;
+                    XMEMCPY(&dName->fullName[idx], WOLFSSL_DOMAIN_COMPONENT, 4);
+                    idx += 4;
+                    XMEMCPY(&dName->fullName[idx],
+                                    &cert->source[dName->dcIdx[i]], dName->dcLen[i]);
+                    dName->dcIdx[i] = idx;
+                    idx += dName->dcLen[i];
+                }
+            }
+            if (dName->uidLen != 0) {
+                dName->entryCount++;
+                XMEMCPY(&dName->fullName[idx], "/UID=", 5);
+                dName->uidNid = wc_OBJ_sn2nid((const char *)"/UID=");
+                idx += 5;
+                XMEMCPY(&dName->fullName[idx],
+                                   &cert->source[dName->uidIdx], dName->uidLen);
+                dName->uidIdx = idx;
+                idx += dName->uidLen;
+            }
+            if (dName->serialLen != 0) {
+                dName->entryCount++;
+                XMEMCPY(&dName->fullName[idx], WOLFSSL_SERIAL_NUMBER, 14);
+                dName->serialNid = wc_OBJ_sn2nid((const char *)WOLFSSL_SERIAL_NUMBER);
+                idx += 14;
+                XMEMCPY(&dName->fullName[idx],
+                             &cert->source[dName->serialIdx], dName->serialLen);
+                dName->serialIdx = idx;
+                idx += dName->serialLen;
+            }
+            dName->fullName[idx] = '\0';
+            dName->fullNameLen = totalLen;
+        }
+    }
+    #endif /* OPENSSL_EXTRA */
+
+    return 0;
+}
+
+
+#ifndef NO_ASN_TIME
+
+/* two byte date/time, add to value */
+static WC_INLINE int GetTime(int* value, const byte* date, int* idx)
+{
+    int i = *idx;
+
+    if (date[i] < 0x30 || date[i] > 0x39 || date[i+1] < 0x30 ||
+                                                             date[i+1] > 0x39) {
+        return ASN_PARSE_E;
+    }
+
+    *value += btoi(date[i++]) * 10;
+    *value += btoi(date[i++]);
+
+    *idx = i;
+
+    return 0;
+}
+
+int ExtractDate(const unsigned char* date, unsigned char format,
+                                                  struct tm* certTime, int* idx)
+{
+    XMEMSET(certTime, 0, sizeof(struct tm));
+
+    if (format == ASN_UTC_TIME) {
+        if (btoi(date[*idx]) >= 5)
+            certTime->tm_year = 1900;
+        else
+            certTime->tm_year = 2000;
+    }
+    else  { /* format == GENERALIZED_TIME */
+        if (GetTime(&certTime->tm_year, date, idx) != 0) return 0;
+        certTime->tm_year *= 100;
+    }
+
+    /* adjust tm_year, tm_mon */
+    if (GetTime(&certTime->tm_year, date, idx) != 0) return 0;
+    certTime->tm_year -= 1900;
+    if (GetTime(&certTime->tm_mon , date, idx) != 0) return 0;
+    certTime->tm_mon  -= 1;
+    if (GetTime(&certTime->tm_mday, date, idx) != 0) return 0;
+    if (GetTime(&certTime->tm_hour, date, idx) != 0) return 0;
+    if (GetTime(&certTime->tm_min , date, idx) != 0) return 0;
+    if (GetTime(&certTime->tm_sec , date, idx) != 0) return 0;
+
+    return 1;
+}
+
+
+#if defined(OPENSSL_ALL) || defined(WOLFSSL_MYSQL_COMPATIBLE) || \
+    defined(OPENSSL_EXTRA) || defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY)
+int GetTimeString(byte* date, int format, char* buf, int len)
+{
+    struct tm t;
+    int idx = 0;
+
+    if (!ExtractDate(date, (unsigned char)format, &t, &idx)) {
+        return 0;
+    }
+
+    if (date[idx] != 'Z') {
+        WOLFSSL_MSG("UTCtime, not Zulu") ;
+        return 0;
+    }
+
+    /* place month in buffer */
+    buf[0] = '\0';
+    switch(t.tm_mon) {
+        case 0:  XSTRNCAT(buf, "Jan ", 5); break;
+        case 1:  XSTRNCAT(buf, "Feb ", 5); break;
+        case 2:  XSTRNCAT(buf, "Mar ", 5); break;
+        case 3:  XSTRNCAT(buf, "Apr ", 5); break;
+        case 4:  XSTRNCAT(buf, "May ", 5); break;
+        case 5:  XSTRNCAT(buf, "Jun ", 5); break;
+        case 6:  XSTRNCAT(buf, "Jul ", 5); break;
+        case 7:  XSTRNCAT(buf, "Aug ", 5); break;
+        case 8:  XSTRNCAT(buf, "Sep ", 5); break;
+        case 9:  XSTRNCAT(buf, "Oct ", 5); break;
+        case 10: XSTRNCAT(buf, "Nov ", 5); break;
+        case 11: XSTRNCAT(buf, "Dec ", 5); break;
+        default:
+            return 0;
+
+    }
+    idx = 4; /* use idx now for char buffer */
+
+    XSNPRINTF(buf + idx, len - idx, "%2d %02d:%02d:%02d %d GMT",
+              t.tm_mday, t.tm_hour, t.tm_min, t.tm_sec, t.tm_year + 1900);
+
+    return 1;
+}
+#endif /* OPENSSL_ALL || WOLFSSL_MYSQL_COMPATIBLE || WOLFSSL_NGINX || WOLFSSL_HAPROXY */
+
+
+#if !defined(NO_ASN_TIME) && defined(HAVE_PKCS7)
+
+/* Set current time string, either UTC or GeneralizedTime.
+ * (void*) tm should be a pointer to time_t, output is placed in buf.
+ *
+ * Return time string length placed in buf on success, negative on error */
+int GetAsnTimeString(void* currTime, byte* buf, word32 len)
+{
+    struct tm* ts      = NULL;
+    struct tm* tmpTime = NULL;
+#if defined(NEED_TMP_TIME)
+    struct tm tmpTimeStorage;
+    tmpTime = &tmpTimeStorage;
+#else
+    (void)tmpTime;
+#endif
+    byte* data_ptr  = buf;
+    word32 data_len = 0;
+    int year, mon, day, hour, mini, sec;
+
+    WOLFSSL_ENTER("SetAsnTimeString");
+
+    if (buf == NULL || len == 0)
+        return BAD_FUNC_ARG;
+
+    ts = (struct tm *)XGMTIME((time_t*)currTime, tmpTime);
+    if (ts == NULL){
+        WOLFSSL_MSG("failed to get time data.");
+        return ASN_TIME_E;
+    }
+
+    /* Note ASN_UTC_TIME_SIZE and ASN_GENERALIZED_TIME_SIZE include space for
+     * the null terminator. ASN encoded values leave off the terminator. */
+
+    if (ts->tm_year >= 50 && ts->tm_year < 150) {
+        /* UTC Time */
+        char utc_str[ASN_UTC_TIME_SIZE];
+        data_len = ASN_UTC_TIME_SIZE - 1 + 2;
+
+        if (len < data_len)
+            return BUFFER_E;
+
+        if (ts->tm_year >= 50 && ts->tm_year < 100) {
+            year = ts->tm_year;
+        } else if (ts->tm_year >= 100 && ts->tm_year < 150) {
+            year = ts->tm_year - 100;
+        }
+        else {
+            WOLFSSL_MSG("unsupported year range");
+            return BAD_FUNC_ARG;
+        }
+        mon  = ts->tm_mon + 1;
+        day  = ts->tm_mday;
+        hour = ts->tm_hour;
+        mini = ts->tm_min;
+        sec  = ts->tm_sec;
+        XSNPRINTF((char *)utc_str, ASN_UTC_TIME_SIZE,
+                  "%02d%02d%02d%02d%02d%02dZ", year, mon, day, hour, mini, sec);
+        *data_ptr = (byte) ASN_UTC_TIME; data_ptr++;
+        /* -1 below excludes null terminator */
+        *data_ptr = (byte) ASN_UTC_TIME_SIZE - 1; data_ptr++;
+        XMEMCPY(data_ptr,(byte *)utc_str, ASN_UTC_TIME_SIZE - 1);
+
+    } else {
+        /* GeneralizedTime */
+        char gt_str[ASN_GENERALIZED_TIME_SIZE];
+        data_len = ASN_GENERALIZED_TIME_SIZE - 1 + 2;
+
+        if (len < data_len)
+            return BUFFER_E;
+
+        year = ts->tm_year + 1900;
+        mon  = ts->tm_mon + 1;
+        day  = ts->tm_mday;
+        hour = ts->tm_hour;
+        mini = ts->tm_min;
+        sec  = ts->tm_sec;
+        XSNPRINTF((char *)gt_str, ASN_GENERALIZED_TIME_SIZE,
+                  "%4d%02d%02d%02d%02d%02dZ", year, mon, day, hour, mini, sec);
+        *data_ptr = (byte) ASN_GENERALIZED_TIME; data_ptr++;
+        /* -1 below excludes null terminator */
+        *data_ptr = (byte) ASN_GENERALIZED_TIME_SIZE - 1; data_ptr++;
+        XMEMCPY(data_ptr,(byte *)gt_str, ASN_GENERALIZED_TIME_SIZE - 1);
+    }
+
+    return data_len;
+}
+
+#endif /* !NO_ASN_TIME && HAVE_PKCS7 */
+
+
+#if defined(USE_WOLF_VALIDDATE)
+
+/* to the second */
+int DateGreaterThan(const struct tm* a, const struct tm* b)
+{
+    if (a->tm_year > b->tm_year)
+        return 1;
+
+    if (a->tm_year == b->tm_year && a->tm_mon > b->tm_mon)
+        return 1;
+
+    if (a->tm_year == b->tm_year && a->tm_mon == b->tm_mon &&
+           a->tm_mday > b->tm_mday)
+        return 1;
+
+    if (a->tm_year == b->tm_year && a->tm_mon == b->tm_mon &&
+        a->tm_mday == b->tm_mday && a->tm_hour > b->tm_hour)
+        return 1;
+
+    if (a->tm_year == b->tm_year && a->tm_mon == b->tm_mon &&
+        a->tm_mday == b->tm_mday && a->tm_hour == b->tm_hour &&
+        a->tm_min > b->tm_min)
+        return 1;
+
+    if (a->tm_year == b->tm_year && a->tm_mon == b->tm_mon &&
+        a->tm_mday == b->tm_mday && a->tm_hour == b->tm_hour &&
+        a->tm_min  == b->tm_min  && a->tm_sec > b->tm_sec)
+        return 1;
+
+    return 0; /* false */
+}
+
+
+static WC_INLINE int DateLessThan(const struct tm* a, const struct tm* b)
+{
+    return DateGreaterThan(b,a);
+}
+
+/* like atoi but only use first byte */
+/* Make sure before and after dates are valid */
+int ValidateDate(const byte* date, byte format, int dateType)
+{
+    time_t ltime;
+    struct tm  certTime;
+    struct tm* localTime;
+    struct tm* tmpTime;
+    int    i = 0;
+    int    timeDiff = 0 ;
+    int    diffHH = 0 ; int diffMM = 0 ;
+    int    diffSign = 0 ;
+
+#if defined(NEED_TMP_TIME)
+    struct tm tmpTimeStorage;
+    tmpTime = &tmpTimeStorage;
+#else
+    tmpTime = NULL;
+#endif
+    (void)tmpTime;
+
+    ltime = XTIME(0);
+
+#ifdef WOLFSSL_BEFORE_DATE_CLOCK_SKEW
+    if (dateType == BEFORE) {
+        WOLFSSL_MSG("Skewing local time for before date check");
+        ltime += WOLFSSL_BEFORE_DATE_CLOCK_SKEW;
+    }
+#endif
+
+#ifdef WOLFSSL_AFTER_DATE_CLOCK_SKEW
+    if (dateType == AFTER) {
+        WOLFSSL_MSG("Skewing local time for after date check");
+        ltime -= WOLFSSL_AFTER_DATE_CLOCK_SKEW;
+    }
+#endif
+
+    if (!ExtractDate(date, format, &certTime, &i)) {
+        WOLFSSL_MSG("Error extracting the date");
+        return 0;
+    }
+
+    if ((date[i] == '+') || (date[i] == '-')) {
+        WOLFSSL_MSG("Using time differential, not Zulu") ;
+        diffSign = date[i++] == '+' ? 1 : -1 ;
+        if (GetTime(&diffHH, date, &i) != 0)
+            return 0;
+        if (GetTime(&diffMM, date, &i) != 0)
+            return 0;
+        timeDiff = diffSign * (diffHH*60 + diffMM) * 60 ;
+    } else if (date[i] != 'Z') {
+        WOLFSSL_MSG("UTCtime, neither Zulu or time differential") ;
+        return 0;
+    }
+
+    ltime -= (time_t)timeDiff ;
+    localTime = XGMTIME(&ltime, tmpTime);
+
+    if (localTime == NULL) {
+        WOLFSSL_MSG("XGMTIME failed");
+        return 0;
+    }
+
+    if (dateType == BEFORE) {
+        if (DateLessThan(localTime, &certTime)) {
+            WOLFSSL_MSG("Date BEFORE check failed");
+            return 0;
+        }
+    }
+    else {  /* dateType == AFTER */
+        if (DateGreaterThan(localTime, &certTime)) {
+            WOLFSSL_MSG("Date AFTER check failed");
+            return 0;
+        }
+    }
+
+    return 1;
+}
+#endif /* USE_WOLF_VALIDDATE */
+
+int wc_GetTime(void* timePtr, word32 timeSize)
+{
+    time_t* ltime = (time_t*)timePtr;
+
+    if (timePtr == NULL) {
+        return BAD_FUNC_ARG;
+    }
+
+    if ((word32)sizeof(time_t) > timeSize) {
+        return BUFFER_E;
+    }
+
+    *ltime = XTIME(0);
+
+    return 0;
+}
+
+#endif /* !NO_ASN_TIME */
+
+
+/* Get date buffer, format and length. Returns 0=success or error */
+static int GetDateInfo(const byte* source, word32* idx, const byte** pDate,
+                        byte* pFormat, int* pLength, word32 maxIdx)
+{
+    int length;
+    byte format;
+
+    if (source == NULL || idx == NULL)
+        return BAD_FUNC_ARG;
+
+    /* get ASN format header */
+    if (*idx+1 > maxIdx)
+        return BUFFER_E;
+    format = source[*idx];
+    *idx += 1;
+    if (format != ASN_UTC_TIME && format != ASN_GENERALIZED_TIME)
+        return ASN_TIME_E;
+
+    /* get length */
+    if (GetLength(source, idx, &length, maxIdx) < 0)
+        return ASN_PARSE_E;
+    if (length > MAX_DATE_SIZE || length < MIN_DATE_SIZE)
+        return ASN_DATE_SZ_E;
+
+    /* return format, date and length */
+    if (pFormat)
+        *pFormat = format;
+    if (pDate)
+        *pDate = &source[*idx];
+    if (pLength)
+        *pLength = length;
+
+    *idx += length;
+
+    return 0;
+}
+
+static int GetDate(DecodedCert* cert, int dateType, int verify, int maxIdx)
+{
+    int    ret, length;
+    const byte *datePtr = NULL;
+    byte   date[MAX_DATE_SIZE];
+    byte   format;
+    word32 startIdx = 0;
+
+    if (dateType == BEFORE)
+        cert->beforeDate = &cert->source[cert->srcIdx];
+    else
+        cert->afterDate = &cert->source[cert->srcIdx];
+    startIdx = cert->srcIdx;
+
+    ret = GetDateInfo(cert->source, &cert->srcIdx, &datePtr, &format,
+                      &length, maxIdx);
+    if (ret < 0)
+        return ret;
+
+    XMEMSET(date, 0, MAX_DATE_SIZE);
+    XMEMCPY(date, datePtr, length);
+
+    if (dateType == BEFORE)
+        cert->beforeDateLen = cert->srcIdx - startIdx;
+    else
+        cert->afterDateLen  = cert->srcIdx - startIdx;
+
+#ifndef NO_ASN_TIME
+    if (verify != NO_VERIFY && verify != VERIFY_SKIP_DATE &&
+            !XVALIDATE_DATE(date, format, dateType)) {
+        if (dateType == BEFORE)
+            return ASN_BEFORE_DATE_E;
+        else
+            return ASN_AFTER_DATE_E;
+    }
+#else
+    (void)verify;
+#endif
+
+    return 0;
+}
+
+static int GetValidity(DecodedCert* cert, int verify, int maxIdx)
+{
+    int length;
+    int badDate = 0;
+
+    if (GetSequence(cert->source, &cert->srcIdx, &length, maxIdx) < 0)
+        return ASN_PARSE_E;
+
+    maxIdx = cert->srcIdx + length;
+
+    if (GetDate(cert, BEFORE, verify, maxIdx) < 0)
+        badDate = ASN_BEFORE_DATE_E; /* continue parsing */
+
+    if (GetDate(cert, AFTER, verify, maxIdx) < 0)
+        return ASN_AFTER_DATE_E;
+
+    if (badDate != 0)
+        return badDate;
+
+    return 0;
+}
+
+
+int wc_GetDateInfo(const byte* certDate, int certDateSz, const byte** date,
+    byte* format, int* length)
+{
+    int ret;
+    word32 idx = 0;
+
+    ret = GetDateInfo(certDate, &idx, date, format, length, certDateSz);
+    if (ret < 0)
+        return ret;
+
+    return 0;
+}
+
+#ifndef NO_ASN_TIME
+int wc_GetDateAsCalendarTime(const byte* date, int length, byte format,
+    struct tm* timearg)
+{
+    int idx = 0;
+    (void)length;
+    if (!ExtractDate(date, format, timearg, &idx))
+        return ASN_TIME_E;
+    return 0;
+}
+
+#if defined(WOLFSSL_CERT_GEN) && defined(WOLFSSL_ALT_NAMES)
+int wc_GetCertDates(Cert* cert, struct tm* before, struct tm* after)
+{
+    int ret = 0;
+    const byte* date;
+    byte format;
+    int length;
+
+    if (cert == NULL)
+        return BAD_FUNC_ARG;
+
+    if (before && cert->beforeDateSz > 0) {
+        ret = wc_GetDateInfo(cert->beforeDate, cert->beforeDateSz, &date,
+                             &format, &length);
+        if (ret == 0)
+            ret = wc_GetDateAsCalendarTime(date, length, format, before);
+    }
+    if (after && cert->afterDateSz > 0) {
+        ret = wc_GetDateInfo(cert->afterDate, cert->afterDateSz, &date,
+                             &format, &length);
+        if (ret == 0)
+            ret = wc_GetDateAsCalendarTime(date, length, format, after);
+    }
+
+    return ret;
+}
+#endif /* WOLFSSL_CERT_GEN && WOLFSSL_ALT_NAMES */
+#endif /* !NO_ASN_TIME */
+
+/* parses certificate up to point of X.509 public key
+ *
+ * if cert date is invalid then badDate gets set to error value, otherwise is 0
+ *
+ * returns a negative value on fail case
+ */
+int wc_GetPubX509(DecodedCert* cert, int verify, int* badDate)
+{
+    int ret;
+
+    if (cert == NULL || badDate == NULL)
+        return BAD_FUNC_ARG;
+
+    *badDate = 0;
+    if ( (ret = GetCertHeader(cert)) < 0)
+        return ret;
+
+    WOLFSSL_MSG("Got Cert Header");
+
+    /* Using the sigIndex as the upper bound because that's where the
+     * actual certificate data ends. */
+    if ( (ret = GetAlgoId(cert->source, &cert->srcIdx, &cert->signatureOID,
+                          oidSigType, cert->sigIndex)) < 0)
+        return ret;
+
+    WOLFSSL_MSG("Got Algo ID");
+
+    if ( (ret = GetName(cert, ISSUER, cert->sigIndex)) < 0)
+        return ret;
+
+    if ( (ret = GetValidity(cert, verify, cert->sigIndex)) < 0)
+        *badDate = ret;
+
+    if ( (ret = GetName(cert, SUBJECT, cert->sigIndex)) < 0)
+        return ret;
+
+    WOLFSSL_MSG("Got Subject Name");
+    return ret;
+}
+
+int DecodeToKey(DecodedCert* cert, int verify)
+{
+    int badDate = 0;
+    int ret;
+
+    if ( (ret = wc_GetPubX509(cert, verify, &badDate)) < 0)
+        return ret;
+
+    /* Determine if self signed */
+    cert->selfSigned = XMEMCMP(cert->issuerHash,
+                               cert->subjectHash,
+                               KEYID_SIZE) == 0 ? 1 : 0;
+
+    if ( (ret = GetKey(cert)) < 0)
+        return ret;
+
+    WOLFSSL_MSG("Got Key");
+
+    if (badDate != 0)
+        return badDate;
+
+    return ret;
+}
+
+static int GetSignature(DecodedCert* cert)
+{
+    int length;
+    int ret;
+    ret = CheckBitString(cert->source, &cert->srcIdx, &length, cert->maxIdx, 1,
+                         NULL);
+    if (ret != 0)
+        return ret;
+
+    cert->sigLength = length;
+    cert->signature = &cert->source[cert->srcIdx];
+    cert->srcIdx += cert->sigLength;
+
+    return 0;
+}
+
+static word32 SetOctetString8Bit(word32 len, byte* output)
+{
+    output[0] = ASN_OCTET_STRING;
+    output[1] = (byte)len;
+    return 2;
+}
+
+static word32 SetDigest(const byte* digest, word32 digSz, byte* output)
+{
+    word32 idx = SetOctetString8Bit(digSz, output);
+    XMEMCPY(&output[idx], digest, digSz);
+
+    return idx + digSz;
+}
+
+
+static word32 BytePrecision(word32 value)
+{
+    word32 i;
+    for (i = sizeof(value); i; --i)
+        if (value >> ((i - 1) * WOLFSSL_BIT_SIZE))
+            break;
+
+    return i;
+}
+
+
+word32 SetLength(word32 length, byte* output)
+{
+    word32 i = 0, j;
+
+    if (length < ASN_LONG_LENGTH) {
+        if (output)
+            output[i] = (byte)length;
+        i++;
+    }
+    else {
+        if (output)
+            output[i] = (byte)(BytePrecision(length) | ASN_LONG_LENGTH);
+        i++;
+
+        for (j = BytePrecision(length); j; --j) {
+            if (output)
+                output[i] = (byte)(length >> ((j - 1) * WOLFSSL_BIT_SIZE));
+            i++;
+        }
+    }
+
+    return i;
+}
+
+word32 SetSequence(word32 len, byte* output)
+{
+    if (output)
+        output[0] = ASN_SEQUENCE | ASN_CONSTRUCTED;
+    return SetLength(len, output ? output + 1 : NULL) + 1;
+}
+
+word32 SetOctetString(word32 len, byte* output)
+{
+    output[0] = ASN_OCTET_STRING;
+    return SetLength(len, output + 1) + 1;
+}
+
+/* Write a set header to output */
+word32 SetSet(word32 len, byte* output)
+{
+    output[0] = ASN_SET | ASN_CONSTRUCTED;
+    return SetLength(len, output + 1) + 1;
+}
+
+word32 SetImplicit(byte tag, byte number, word32 len, byte* output)
+{
+
+    output[0] = ((tag == ASN_SEQUENCE || tag == ASN_SET) ? ASN_CONSTRUCTED : 0)
+                    | ASN_CONTEXT_SPECIFIC | number;
+    return SetLength(len, output + 1) + 1;
+}
+
+word32 SetExplicit(byte number, word32 len, byte* output)
+{
+    output[0] = ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | number;
+    return SetLength(len, output + 1) + 1;
+}
+
+
+#if defined(HAVE_ECC) && defined(HAVE_ECC_KEY_EXPORT)
+
+static int SetCurve(ecc_key* key, byte* output)
+{
+#ifdef HAVE_OID_ENCODING
+    int ret;
+#endif
+    int idx = 0;
+    word32 oidSz = 0;
+
+    /* validate key */
+    if (key == NULL || key->dp == NULL) {
+        return BAD_FUNC_ARG;
+    }
+
+#ifdef HAVE_OID_ENCODING
+    ret = EncodeObjectId(key->dp->oid, key->dp->oidSz, NULL, &oidSz);
+    if (ret != 0) {
+        return ret;
+    }
+#else
+    oidSz = key->dp->oidSz;
+#endif
+
+    idx += SetObjectId(oidSz, output);
+
+#ifdef HAVE_OID_ENCODING
+    ret = EncodeObjectId(key->dp->oid, key->dp->oidSz, output+idx, &oidSz);
+    if (ret != 0) {
+        return ret;
+    }
+#else
+    XMEMCPY(output+idx, key->dp->oid, oidSz);
+#endif
+    idx += oidSz;
+
+    return idx;
+}
+
+#endif /* HAVE_ECC && HAVE_ECC_KEY_EXPORT */
+
+
+#ifdef HAVE_ECC
+static WC_INLINE int IsSigAlgoECDSA(int algoOID)
+{
+    /* ECDSA sigAlgo must not have ASN1 NULL parameters */
+    if (algoOID == CTC_SHAwECDSA || algoOID == CTC_SHA256wECDSA ||
+        algoOID == CTC_SHA384wECDSA || algoOID == CTC_SHA512wECDSA) {
+        return 1;
+    }
+
+    return 0;
+}
+#endif
+
+word32 SetAlgoID(int algoOID, byte* output, int type, int curveSz)
+{
+    word32 tagSz, idSz, seqSz, algoSz = 0;
+    const  byte* algoName = 0;
+    byte   ID_Length[1 + MAX_LENGTH_SZ];
+    byte   seqArray[MAX_SEQ_SZ + 1];  /* add object_id to end */
+    int    length = 0;
+
+    tagSz = (type == oidHashType ||
+             (type == oidSigType
+        #ifdef HAVE_ECC
+              && !IsSigAlgoECDSA(algoOID)
+        #endif
+        #ifdef HAVE_ED25519
+              && algoOID != ED25519k
+        #endif
+        #ifdef HAVE_ED448
+              && algoOID != ED448k
+        #endif
+              ) ||
+             (type == oidKeyType && algoOID == RSAk)) ? 2 : 0;
+
+    algoName = OidFromId(algoOID, type, &algoSz);
+
+    if (algoName == NULL) {
+        WOLFSSL_MSG("Unknown Algorithm");
+        return 0;
+    }
+
+    idSz  = SetObjectId(algoSz, ID_Length);
+    seqSz = SetSequence(idSz + algoSz + tagSz + curveSz, seqArray);
+
+    /* Copy only algo to output for DSA keys */
+    if (algoOID == DSAk && output) {
+        XMEMCPY(output, ID_Length, idSz);
+        XMEMCPY(output + idSz, algoName, algoSz);
+        if (tagSz == 2)
+            SetASNNull(&output[seqSz + idSz + algoSz]);
+    }
+    else if (output) {
+        XMEMCPY(output, seqArray, seqSz);
+        XMEMCPY(output + seqSz, ID_Length, idSz);
+        XMEMCPY(output + seqSz + idSz, algoName, algoSz);
+        if (tagSz == 2)
+            SetASNNull(&output[seqSz + idSz + algoSz]);
+    }
+
+    if (algoOID == DSAk)
+        length = idSz + algoSz + tagSz;
+    else
+        length = seqSz + idSz + algoSz + tagSz;
+
+    return length;
+}
+
+
+word32 wc_EncodeSignature(byte* out, const byte* digest, word32 digSz,
+                          int hashOID)
+{
+    byte digArray[MAX_ENCODED_DIG_SZ];
+    byte algoArray[MAX_ALGO_SZ];
+    byte seqArray[MAX_SEQ_SZ];
+    word32 encDigSz, algoSz, seqSz;
+
+    encDigSz = SetDigest(digest, digSz, digArray);
+    algoSz   = SetAlgoID(hashOID, algoArray, oidHashType, 0);
+    seqSz    = SetSequence(encDigSz + algoSz, seqArray);
+
+    XMEMCPY(out, seqArray, seqSz);
+    XMEMCPY(out + seqSz, algoArray, algoSz);
+    XMEMCPY(out + seqSz + algoSz, digArray, encDigSz);
+
+    return encDigSz + algoSz + seqSz;
+}
+
+
+#ifndef NO_CERTS
+
+int wc_GetCTC_HashOID(int type)
+{
+    int ret;
+    enum wc_HashType hType;
+
+    hType = wc_HashTypeConvert(type);
+    ret = wc_HashGetOID(hType);
+    if (ret < 0)
+        ret = 0; /* backwards compatibility */
+
+    return ret;
+}
+
+void InitSignatureCtx(SignatureCtx* sigCtx, void* heap, int devId)
+{
+    if (sigCtx) {
+        XMEMSET(sigCtx, 0, sizeof(SignatureCtx));
+        sigCtx->devId = devId;
+        sigCtx->heap = heap;
+    }
+}
+
+void FreeSignatureCtx(SignatureCtx* sigCtx)
+{
+    if (sigCtx == NULL)
+        return;
+
+    if (sigCtx->digest) {
+        XFREE(sigCtx->digest, sigCtx->heap, DYNAMIC_TYPE_DIGEST);
+        sigCtx->digest = NULL;
+    }
+#ifndef NO_RSA
+    if (sigCtx->plain) {
+        XFREE(sigCtx->plain, sigCtx->heap, DYNAMIC_TYPE_SIGNATURE);
+        sigCtx->plain = NULL;
+    }
+#endif
+#ifndef NO_ASN_CRYPT
+    if (sigCtx->key.ptr) {
+        switch (sigCtx->keyOID) {
+        #ifndef NO_RSA
+            case RSAk:
+                wc_FreeRsaKey(sigCtx->key.rsa);
+                XFREE(sigCtx->key.ptr, sigCtx->heap, DYNAMIC_TYPE_RSA);
+                break;
+        #endif /* !NO_RSA */
+        #ifdef HAVE_ECC
+            case ECDSAk:
+                wc_ecc_free(sigCtx->key.ecc);
+                XFREE(sigCtx->key.ecc, sigCtx->heap, DYNAMIC_TYPE_ECC);
+                break;
+        #endif /* HAVE_ECC */
+        #ifdef HAVE_ED25519
+            case ED25519k:
+                wc_ed25519_free(sigCtx->key.ed25519);
+                XFREE(sigCtx->key.ed25519, sigCtx->heap, DYNAMIC_TYPE_ED25519);
+                break;
+        #endif /* HAVE_ED25519 */
+        #ifdef HAVE_ED448
+            case ED448k:
+                wc_ed448_free(sigCtx->key.ed448);
+                XFREE(sigCtx->key.ed448, sigCtx->heap, DYNAMIC_TYPE_ED448);
+                break;
+        #endif /* HAVE_ED448 */
+            default:
+                break;
+        } /* switch (keyOID) */
+        sigCtx->key.ptr = NULL;
+    }
+#endif
+
+    /* reset state, we are done */
+    sigCtx->state = SIG_STATE_BEGIN;
+}
+
+#ifndef NO_ASN_CRYPT
+static int HashForSignature(const byte* buf, word32 bufSz, word32 sigOID,
+                            byte* digest, int* typeH, int* digestSz, int verify)
+{
+    int ret = 0;
+
+    (void)verify;
+
+    switch (sigOID) {
+    #if defined(WOLFSSL_MD2)
+        case CTC_MD2wRSA:
+            if (!verify) {
+                ret = HASH_TYPE_E;
+                WOLFSSL_MSG("MD2 not supported for signing");
+            }
+            else if ((ret = wc_Md2Hash(buf, bufSz, digest)) == 0) {
+                *typeH    = MD2h;
+                *digestSz = MD2_DIGEST_SIZE;
+            }
+        break;
+    #endif
+    #ifndef NO_MD5
+        case CTC_MD5wRSA:
+            if ((ret = wc_Md5Hash(buf, bufSz, digest)) == 0) {
+                *typeH    = MD5h;
+                *digestSz = WC_MD5_DIGEST_SIZE;
+            }
+            break;
+    #endif
+    #ifndef NO_SHA
+        case CTC_SHAwRSA:
+        case CTC_SHAwDSA:
+        case CTC_SHAwECDSA:
+            if ((ret = wc_ShaHash(buf, bufSz, digest)) == 0) {
+                *typeH    = SHAh;
+                *digestSz = WC_SHA_DIGEST_SIZE;
+            }
+            break;
+    #endif
+    #ifdef WOLFSSL_SHA224
+        case CTC_SHA224wRSA:
+        case CTC_SHA224wECDSA:
+            if ((ret = wc_Sha224Hash(buf, bufSz, digest)) == 0) {
+                *typeH    = SHA224h;
+                *digestSz = WC_SHA224_DIGEST_SIZE;
+            }
+            break;
+    #endif
+    #ifndef NO_SHA256
+        case CTC_SHA256wRSA:
+        case CTC_SHA256wECDSA:
+            if ((ret = wc_Sha256Hash(buf, bufSz, digest)) == 0) {
+                *typeH    = SHA256h;
+                *digestSz = WC_SHA256_DIGEST_SIZE;
+            }
+            break;
+    #endif
+    #ifdef WOLFSSL_SHA384
+        case CTC_SHA384wRSA:
+        case CTC_SHA384wECDSA:
+            if ((ret = wc_Sha384Hash(buf, bufSz, digest)) == 0) {
+                *typeH    = SHA384h;
+                *digestSz = WC_SHA384_DIGEST_SIZE;
+            }
+            break;
+    #endif
+    #ifdef WOLFSSL_SHA512
+        case CTC_SHA512wRSA:
+        case CTC_SHA512wECDSA:
+            if ((ret = wc_Sha512Hash(buf, bufSz, digest)) == 0) {
+                *typeH    = SHA512h;
+                *digestSz = WC_SHA512_DIGEST_SIZE;
+            }
+            break;
+    #endif
+    #ifdef HAVE_ED25519
+        case CTC_ED25519:
+            /* Hashes done in signing operation.
+             * Two dependent hashes with prefixes performed.
+             */
+            break;
+    #endif
+    #ifdef HAVE_ED448
+        case CTC_ED448:
+            /* Hashes done in signing operation.
+             * Two dependent hashes with prefixes performed.
+             */
+            break;
+    #endif
+        default:
+            ret = HASH_TYPE_E;
+            WOLFSSL_MSG("Hash for Signature has unsupported type");
+    }
+
+    return ret;
+}
+#endif /* !NO_ASN_CRYPT */
+
+/* Return codes: 0=Success, Negative (see error-crypt.h), ASN_SIG_CONFIRM_E */
+static int ConfirmSignature(SignatureCtx* sigCtx,
+    const byte* buf, word32 bufSz,
+    const byte* key, word32 keySz, word32 keyOID,
+    const byte* sig, word32 sigSz, word32 sigOID, byte* rsaKeyIdx)
+{
+    int ret = 0;
+#ifndef WOLFSSL_RENESAS_TSIP_TLS
+    (void)rsaKeyIdx;
+#endif
+    if (sigCtx == NULL || buf == NULL || bufSz == 0 || key == NULL ||
+        keySz == 0 || sig == NULL || sigSz == 0) {
+        return BAD_FUNC_ARG;
+    }
+
+    (void)key;
+    (void)keySz;
+    (void)sig;
+    (void)sigSz;
+
+    WOLFSSL_ENTER("ConfirmSignature");
+
+#ifndef NO_ASN_CRYPT
+    switch (sigCtx->state) {
+        case SIG_STATE_BEGIN:
+        {
+            sigCtx->keyOID = keyOID; /* must set early for cleanup */
+
+            sigCtx->digest = (byte*)XMALLOC(WC_MAX_DIGEST_SIZE, sigCtx->heap,
+                                                    DYNAMIC_TYPE_DIGEST);
+            if (sigCtx->digest == NULL) {
+                ERROR_OUT(MEMORY_E, exit_cs);
+            }
+
+            sigCtx->state = SIG_STATE_HASH;
+        } /* SIG_STATE_BEGIN */
+        FALL_THROUGH;
+
+        case SIG_STATE_HASH:
+        {
+            ret = HashForSignature(buf, bufSz, sigOID, sigCtx->digest,
+                                   &sigCtx->typeH, &sigCtx->digestSz, 1);
+            if (ret != 0) {
+                goto exit_cs;
+            }
+
+            sigCtx->state = SIG_STATE_KEY;
+        } /* SIG_STATE_HASH */
+        FALL_THROUGH;
+
+        case SIG_STATE_KEY:
+        {
+            switch (keyOID) {
+            #ifndef NO_RSA
+                case RSAk:
+                {
+                    word32 idx = 0;
+
+                    sigCtx->key.rsa = (RsaKey*)XMALLOC(sizeof(RsaKey),
+                                                sigCtx->heap, DYNAMIC_TYPE_RSA);
+                    sigCtx->plain = (byte*)XMALLOC(MAX_ENCODED_SIG_SZ,
+                                         sigCtx->heap, DYNAMIC_TYPE_SIGNATURE);
+                    if (sigCtx->key.rsa == NULL || sigCtx->plain == NULL) {
+                        ERROR_OUT(MEMORY_E, exit_cs);
+                    }
+                    if ((ret = wc_InitRsaKey_ex(sigCtx->key.rsa, sigCtx->heap,
+                                                        sigCtx->devId)) != 0) {
+                        goto exit_cs;
+                    }
+                    if (sigSz > MAX_ENCODED_SIG_SZ) {
+                        WOLFSSL_MSG("Verify Signature is too big");
+                        ERROR_OUT(BUFFER_E, exit_cs);
+                    }
+                    if ((ret = wc_RsaPublicKeyDecode(key, &idx, sigCtx->key.rsa,
+                                                                 keySz)) != 0) {
+                        WOLFSSL_MSG("ASN Key decode error RSA");
+                        goto exit_cs;
+                    }
+                    XMEMCPY(sigCtx->plain, sig, sigSz);
+                    sigCtx->out = NULL;
+
+                #ifdef WOLFSSL_ASYNC_CRYPT
+                    sigCtx->asyncDev = &sigCtx->key.rsa->asyncDev;
+                #endif
+                    break;
+                }
+            #endif /* !NO_RSA */
+            #ifdef HAVE_ECC
+                case ECDSAk:
+                {
+                    word32 idx = 0;
+
+                    sigCtx->verify = 0;
+                    sigCtx->key.ecc = (ecc_key*)XMALLOC(sizeof(ecc_key),
+                                                sigCtx->heap, DYNAMIC_TYPE_ECC);
+                    if (sigCtx->key.ecc == NULL) {
+                        ERROR_OUT(MEMORY_E, exit_cs);
+                    }
+                    if ((ret = wc_ecc_init_ex(sigCtx->key.ecc, sigCtx->heap,
+                                                          sigCtx->devId)) < 0) {
+                        goto exit_cs;
+                    }
+                    ret = wc_EccPublicKeyDecode(key, &idx, sigCtx->key.ecc,
+                                                                         keySz);
+                    if (ret < 0) {
+                        WOLFSSL_MSG("ASN Key import error ECC");
+                        goto exit_cs;
+                    }
+                #ifdef WOLFSSL_ASYNC_CRYPT
+                    sigCtx->asyncDev = &sigCtx->key.ecc->asyncDev;
+                #endif
+                    break;
+                }
+            #endif /* HAVE_ECC */
+            #ifdef HAVE_ED25519
+                case ED25519k:
+                {
+                    sigCtx->verify = 0;
+                    sigCtx->key.ed25519 = (ed25519_key*)XMALLOC(
+                                              sizeof(ed25519_key), sigCtx->heap,
+                                              DYNAMIC_TYPE_ED25519);
+                    if (sigCtx->key.ed25519 == NULL) {
+                        ERROR_OUT(MEMORY_E, exit_cs);
+                    }
+                    if ((ret = wc_ed25519_init(sigCtx->key.ed25519)) < 0) {
+                        goto exit_cs;
+                    }
+                    if ((ret = wc_ed25519_import_public(key, keySz,
+                                                    sigCtx->key.ed25519)) < 0) {
+                        WOLFSSL_MSG("ASN Key import error ED25519");
+                        goto exit_cs;
+                    }
+                #ifdef WOLFSSL_ASYNC_CRYPT
+                    sigCtx->asyncDev = &sigCtx->key.ed25519->asyncDev;
+                #endif
+                    break;
+                }
+            #endif
+            #ifdef HAVE_ED448
+                case ED448k:
+                {
+                    sigCtx->verify = 0;
+                    sigCtx->key.ed448 = (ed448_key*)XMALLOC(
+                                                sizeof(ed448_key), sigCtx->heap,
+                                                DYNAMIC_TYPE_ED448);
+                    if (sigCtx->key.ed448 == NULL) {
+                        ERROR_OUT(MEMORY_E, exit_cs);
+                    }
+                    if ((ret = wc_ed448_init(sigCtx->key.ed448)) < 0) {
+                        goto exit_cs;
+                    }
+                    if ((ret = wc_ed448_import_public(key, keySz,
+                                                      sigCtx->key.ed448)) < 0) {
+                        WOLFSSL_MSG("ASN Key import error ED448");
+                        goto exit_cs;
+                    }
+                #ifdef WOLFSSL_ASYNC_CRYPT
+                    sigCtx->asyncDev = &sigCtx->key.ed448->asyncDev;
+                #endif
+                    break;
+                }
+            #endif
+                default:
+                    WOLFSSL_MSG("Verify Key type unknown");
+                    ret = ASN_UNKNOWN_OID_E;
+                    break;
+            } /* switch (keyOID) */
+
+            if (ret != 0) {
+                goto exit_cs;
+            }
+
+            sigCtx->state = SIG_STATE_DO;
+
+        #ifdef WOLFSSL_ASYNC_CRYPT
+            if (sigCtx->devId != INVALID_DEVID && sigCtx->asyncDev && sigCtx->asyncCtx) {
+                /* make sure event is initialized */
+                WOLF_EVENT* event = &sigCtx->asyncDev->event;
+                ret = wolfAsync_EventInit(event, WOLF_EVENT_TYPE_ASYNC_WOLFSSL,
+                    sigCtx->asyncCtx, WC_ASYNC_FLAG_CALL_AGAIN);
+            }
+        #endif
+        } /* SIG_STATE_KEY */
+        FALL_THROUGH;
+
+        case SIG_STATE_DO:
+        {
+            switch (keyOID) {
+            #ifndef NO_RSA
+                case RSAk:
+                {
+                #ifdef HAVE_PK_CALLBACKS
+                    if (sigCtx->pkCbRsa) {
+                        ret = sigCtx->pkCbRsa(
+                                sigCtx->plain, sigSz, &sigCtx->out,
+                                key, keySz,
+                                sigCtx->pkCtxRsa);
+                    }
+                    else
+                #endif /* HAVE_PK_CALLBACKS */
+                    {
+                     #ifdef WOLFSSL_RENESAS_TSIP_TLS
+                        if (rsaKeyIdx != NULL)
+                        {
+                            ret = tsip_tls_CertVerify(buf, bufSz, sigCtx->plain,
+                                sigSz,
+                                sigCtx->pubkey_n_start - sigCtx->certBegin,
+                                sigCtx->pubkey_n_len - 1,
+                                sigCtx->pubkey_e_start - sigCtx->certBegin,
+                                sigCtx->pubkey_e_len - 1,
+                                rsaKeyIdx);
+
+                            if (ret == 0){
+                                sigCtx->verifyByTSIP = 1;
+                                ret = 0;
+                            } else {
+                                WOLFSSL_MSG("RSA Verify by tsip didn't match");
+                                ret = ASN_SIG_CONFIRM_E;
+                            }
+                        } else
+                    #endif
+                        ret = wc_RsaSSL_VerifyInline(sigCtx->plain, sigSz,
+                                                 &sigCtx->out, sigCtx->key.rsa);
+                    }
+                    break;
+                }
+            #endif /* !NO_RSA */
+            #if defined(HAVE_ECC)
+                case ECDSAk:
+                {
+                #ifdef HAVE_PK_CALLBACKS
+                    if (sigCtx->pkCbEcc) {
+                        ret = sigCtx->pkCbEcc(
+                                sig, sigSz,
+                                sigCtx->digest, sigCtx->digestSz,
+                                key, keySz, &sigCtx->verify,
+                                sigCtx->pkCtxEcc);
+                    }
+                    else
+                #endif /* HAVE_PK_CALLBACKS */
+                    {
+                        ret = wc_ecc_verify_hash(sig, sigSz, sigCtx->digest,
+                                            sigCtx->digestSz, &sigCtx->verify,
+                                            sigCtx->key.ecc);
+                    }
+                    break;
+                }
+            #endif /* HAVE_ECC */
+            #ifdef HAVE_ED25519
+                case ED25519k:
+                {
+                    ret = wc_ed25519_verify_msg(sig, sigSz, buf, bufSz,
+                                          &sigCtx->verify, sigCtx->key.ed25519);
+                    break;
+                }
+            #endif
+            #ifdef HAVE_ED448
+                case ED448k:
+                {
+                    ret = wc_ed448_verify_msg(sig, sigSz, buf, bufSz,
+                                             &sigCtx->verify, sigCtx->key.ed448,
+                                             NULL, 0);
+                    break;
+                }
+            #endif
+                default:
+                    break;
+            }  /* switch (keyOID) */
+
+        #ifdef WOLFSSL_ASYNC_CRYPT
+            if (ret == WC_PENDING_E) {
+                goto exit_cs;
+            }
+        #endif
+
+            if (ret < 0) {
+                /* treat all RSA errors as ASN_SIG_CONFIRM_E */
+                ret = ASN_SIG_CONFIRM_E;
+                goto exit_cs;
+            }
+
+            sigCtx->state = SIG_STATE_CHECK;
+        } /* SIG_STATE_DO */
+        FALL_THROUGH;
+
+        case SIG_STATE_CHECK:
+        {
+            switch (keyOID) {
+            #ifndef NO_RSA
+                case RSAk:
+                {
+                    int encodedSigSz, verifySz;
+                #ifdef WOLFSSL_RENESAS_TSIP
+                    if (sigCtx->verifyByTSIP == 1) break;
+                #endif
+                #ifdef WOLFSSL_SMALL_STACK
+                    byte* encodedSig = (byte*)XMALLOC(MAX_ENCODED_SIG_SZ,
+                                        sigCtx->heap, DYNAMIC_TYPE_TMP_BUFFER);
+                    if (encodedSig == NULL) {
+                        ERROR_OUT(MEMORY_E, exit_cs);
+                    }
+                #else
+                    byte encodedSig[MAX_ENCODED_SIG_SZ];
+                #endif
+
+                    verifySz = ret;
+
+                    /* make sure we're right justified */
+                    encodedSigSz = wc_EncodeSignature(encodedSig,
+                            sigCtx->digest, sigCtx->digestSz, sigCtx->typeH);
+                    if (encodedSigSz == verifySz && sigCtx->out != NULL &&
+                        XMEMCMP(sigCtx->out, encodedSig, encodedSigSz) == 0) {
+                        ret = 0;
+                    }
+                    else {
+                        WOLFSSL_MSG("RSA SSL verify match encode error");
+                        ret = ASN_SIG_CONFIRM_E;
+                    }
+
+                #ifdef WOLFSSL_SMALL_STACK
+                    XFREE(encodedSig, sigCtx->heap, DYNAMIC_TYPE_TMP_BUFFER);
+                #endif
+                    break;
+                }
+            #endif /* NO_RSA */
+            #ifdef HAVE_ECC
+                case ECDSAk:
+                {
+                    if (sigCtx->verify == 1) {
+                        ret = 0;
+                    }
+                    else {
+                        WOLFSSL_MSG("ECC Verify didn't match");
+                        ret = ASN_SIG_CONFIRM_E;
+                    }
+                    break;
+                }
+            #endif /* HAVE_ECC */
+            #ifdef HAVE_ED25519
+                case ED25519k:
+                {
+                    if (sigCtx->verify == 1) {
+                        ret = 0;
+                    }
+                    else {
+                        WOLFSSL_MSG("ED25519 Verify didn't match");
+                        ret = ASN_SIG_CONFIRM_E;
+                    }
+                    break;
+                }
+            #endif /* HAVE_ED25519 */
+            #ifdef HAVE_ED448
+                case ED448k:
+                {
+                    if (sigCtx->verify == 1) {
+                        ret = 0;
+                    }
+                    else {
+                        WOLFSSL_MSG("ED448 Verify didn't match");
+                        ret = ASN_SIG_CONFIRM_E;
+                    }
+                    break;
+                }
+            #endif /* HAVE_ED448 */
+                default:
+                    break;
+            }  /* switch (keyOID) */
+
+            break;
+        } /* SIG_STATE_CHECK */
+    } /* switch (sigCtx->state) */
+
+exit_cs:
+
+#endif /* !NO_ASN_CRYPT */
+
+    (void)keyOID;
+    (void)sigOID;
+
+    WOLFSSL_LEAVE("ConfirmSignature", ret);
+
+#ifdef WOLFSSL_ASYNC_CRYPT
+    if (ret == WC_PENDING_E)
+        return ret;
+#endif
+
+    FreeSignatureCtx(sigCtx);
+
+    return ret;
+}
+
+
+#ifndef IGNORE_NAME_CONSTRAINTS
+
+static int MatchBaseName(int type, const char* name, int nameSz,
+                         const char* base, int baseSz)
+{
+    if (base == NULL || baseSz <= 0 || name == NULL || nameSz <= 0 ||
+            name[0] == '.' || nameSz < baseSz ||
+            (type != ASN_RFC822_TYPE && type != ASN_DNS_TYPE))
+        return 0;
+
+    /* If an email type, handle special cases where the base is only
+     * a domain, or is an email address itself. */
+    if (type == ASN_RFC822_TYPE) {
+        const char* p = NULL;
+        int count = 0;
+
+        if (base[0] != '.') {
+            p = base;
+            count = 0;
+
+            /* find the '@' in the base */
+            while (*p != '@' && count < baseSz) {
+                count++;
+                p++;
+            }
+
+            /* No '@' in base, reset p to NULL */
+            if (count >= baseSz)
+                p = NULL;
+        }
+
+        if (p == NULL) {
+            /* Base isn't an email address, it is a domain name,
+             * wind the name forward one character past its '@'. */
+            p = name;
+            count = 0;
+            while (*p != '@' && count < baseSz) {
+                count++;
+                p++;
+            }
+
+            if (count < baseSz && *p == '@') {
+                name = p + 1;
+                nameSz -= count + 1;
+            }
+        }
+    }
+
+    if ((type == ASN_DNS_TYPE || type == ASN_RFC822_TYPE) && base[0] == '.') {
+        int szAdjust = nameSz - baseSz;
+        name += szAdjust;
+        nameSz -= szAdjust;
+    }
+
+    while (nameSz > 0) {
+        if (XTOLOWER((unsigned char)*name++) !=
+                                               XTOLOWER((unsigned char)*base++))
+            return 0;
+        nameSz--;
+    }
+
+    return 1;
+}
+
+
+static int ConfirmNameConstraints(Signer* signer, DecodedCert* cert)
+{
+    if (signer == NULL || cert == NULL)
+        return 0;
+
+    /* Check against the excluded list */
+    if (signer->excludedNames) {
+        Base_entry* base = signer->excludedNames;
+
+        while (base != NULL) {
+            switch (base->type) {
+                case ASN_DNS_TYPE:
+                {
+                    DNS_entry* name = cert->altNames;
+                    while (name != NULL) {
+                        if (MatchBaseName(ASN_DNS_TYPE,
+                                          name->name, name->len,
+                                          base->name, base->nameSz)) {
+                            return 0;
+                        }
+                        name = name->next;
+                    }
+                    break;
+                }
+                case ASN_RFC822_TYPE:
+                {
+                    DNS_entry* name = cert->altEmailNames;
+                    while (name != NULL) {
+                        if (MatchBaseName(ASN_RFC822_TYPE,
+                                          name->name, name->len,
+                                          base->name, base->nameSz)) {
+                            return 0;
+                        }
+                        name = name->next;
+                    }
+                    break;
+                }
+                case ASN_DIR_TYPE:
+                {
+                    /* allow permitted dirName smaller than actual subject */
+                    if (cert->subjectRawLen >= base->nameSz &&
+                        XMEMCMP(cert->subjectRaw, base->name,
+                                                        base->nameSz) == 0) {
+                        return 0;
+                    }
+                    break;
+                }
+            }; /* switch */
+            base = base->next;
+        }
+    }
+
+    /* Check against the permitted list */
+    if (signer->permittedNames != NULL) {
+        int needDns = 0;
+        int matchDns = 0;
+        int needEmail = 0;
+        int matchEmail = 0;
+        int needDir = 0;
+        int matchDir = 0;
+        Base_entry* base = signer->permittedNames;
+
+        while (base != NULL) {
+            switch (base->type) {
+                case ASN_DNS_TYPE:
+                {
+                    DNS_entry* name = cert->altNames;
+
+                    if (name != NULL)
+                        needDns = 1;
+
+                    while (name != NULL) {
+                        matchDns = MatchBaseName(ASN_DNS_TYPE,
+                                          name->name, name->len,
+                                          base->name, base->nameSz);
+                        name = name->next;
+                    }
+                    break;
+                }
+                case ASN_RFC822_TYPE:
+                {
+                    DNS_entry* name = cert->altEmailNames;
+
+                    if (name != NULL)
+                        needEmail = 1;
+
+                    while (name != NULL) {
+                        matchEmail = MatchBaseName(ASN_DNS_TYPE,
+                                          name->name, name->len,
+                                          base->name, base->nameSz);
+                        name = name->next;
+                    }
+                    break;
+                }
+                case ASN_DIR_TYPE:
+                {
+                    /* allow permitted dirName smaller than actual subject */
+                    needDir = 1;
+                    if (cert->subjectRaw != NULL &&
+                        cert->subjectRawLen >= base->nameSz &&
+                        XMEMCMP(cert->subjectRaw, base->name,
+                                                        base->nameSz) == 0) {
+                        matchDir = 1;
+                    }
+                    break;
+                }
+            } /* switch */
+            base = base->next;
+        }
+
+        if ((needDns   && !matchDns) ||
+            (needEmail && !matchEmail) ||
+            (needDir   && !matchDir)) {
+            return 0;
+        }
+    }
+
+    return 1;
+}
+
+#endif /* IGNORE_NAME_CONSTRAINTS */
+
+static int DecodeAltNames(const byte* input, int sz, DecodedCert* cert)
+{
+    word32 idx = 0;
+    int length = 0;
+
+    WOLFSSL_ENTER("DecodeAltNames");
+
+    if (GetSequence(input, &idx, &length, sz) < 0) {
+        WOLFSSL_MSG("\tBad Sequence");
+        return ASN_PARSE_E;
+    }
+
+    if (length == 0) {
+        /* RFC 5280 4.2.1.6.  Subject Alternative Name
+           If the subjectAltName extension is present, the sequence MUST
+           contain at least one entry. */
+        return ASN_PARSE_E;
+    }
+
+    cert->weOwnAltNames = 1;
+
+    while (length > 0) {
+        byte b = input[idx++];
+
+        length--;
+
+        /* Save DNS Type names in the altNames list. */
+        /* Save Other Type names in the cert's OidMap */
+        if (b == (ASN_CONTEXT_SPECIFIC | ASN_DNS_TYPE)) {
+            DNS_entry* dnsEntry;
+            int strLen;
+            word32 lenStartIdx = idx;
+
+            if (GetLength(input, &idx, &strLen, sz) < 0) {
+                WOLFSSL_MSG("\tfail: str length");
+                return ASN_PARSE_E;
+            }
+            length -= (idx - lenStartIdx);
+
+            dnsEntry = (DNS_entry*)XMALLOC(sizeof(DNS_entry), cert->heap,
+                                        DYNAMIC_TYPE_ALTNAME);
+            if (dnsEntry == NULL) {
+                WOLFSSL_MSG("\tOut of Memory");
+                return MEMORY_E;
+            }
+
+            dnsEntry->type = ASN_DNS_TYPE;
+            dnsEntry->name = (char*)XMALLOC(strLen + 1, cert->heap,
+                                         DYNAMIC_TYPE_ALTNAME);
+            if (dnsEntry->name == NULL) {
+                WOLFSSL_MSG("\tOut of Memory");
+                XFREE(dnsEntry, cert->heap, DYNAMIC_TYPE_ALTNAME);
+                return MEMORY_E;
+            }
+            dnsEntry->len = strLen;
+            XMEMCPY(dnsEntry->name, &input[idx], strLen);
+            dnsEntry->name[strLen] = '\0';
+
+            dnsEntry->next = cert->altNames;
+            cert->altNames = dnsEntry;
+
+            length -= strLen;
+            idx    += strLen;
+        }
+    #ifndef IGNORE_NAME_CONSTRAINTS
+        else if (b == (ASN_CONTEXT_SPECIFIC | ASN_RFC822_TYPE)) {
+            DNS_entry* emailEntry;
+            int strLen;
+            word32 lenStartIdx = idx;
+
+            if (GetLength(input, &idx, &strLen, sz) < 0) {
+                WOLFSSL_MSG("\tfail: str length");
+                return ASN_PARSE_E;
+            }
+            length -= (idx - lenStartIdx);
+
+            emailEntry = (DNS_entry*)XMALLOC(sizeof(DNS_entry), cert->heap,
+                                        DYNAMIC_TYPE_ALTNAME);
+            if (emailEntry == NULL) {
+                WOLFSSL_MSG("\tOut of Memory");
+                return MEMORY_E;
+            }
+
+            emailEntry->type = ASN_RFC822_TYPE;
+            emailEntry->name = (char*)XMALLOC(strLen + 1, cert->heap,
+                                         DYNAMIC_TYPE_ALTNAME);
+            if (emailEntry->name == NULL) {
+                WOLFSSL_MSG("\tOut of Memory");
+                XFREE(emailEntry, cert->heap, DYNAMIC_TYPE_ALTNAME);
+                return MEMORY_E;
+            }
+            emailEntry->len = strLen;
+            XMEMCPY(emailEntry->name, &input[idx], strLen);
+            emailEntry->name[strLen] = '\0';
+
+            emailEntry->next = cert->altEmailNames;
+            cert->altEmailNames = emailEntry;
+
+            length -= strLen;
+            idx    += strLen;
+        }
+        else if (b == (ASN_CONTEXT_SPECIFIC | ASN_URI_TYPE)) {
+            DNS_entry* uriEntry;
+            int strLen;
+            word32 lenStartIdx = idx;
+
+            WOLFSSL_MSG("\tPutting URI into list but not using");
+            if (GetLength(input, &idx, &strLen, sz) < 0) {
+                WOLFSSL_MSG("\tfail: str length");
+                return ASN_PARSE_E;
+            }
+            length -= (idx - lenStartIdx);
+
+            /* check that strLen at index is not past input buffer */
+            if (strLen + (int)idx > sz) {
+                return BUFFER_E;
+            }
+
+        #ifndef WOLFSSL_NO_ASN_STRICT
+            /* Verify RFC 5280 Sec 4.2.1.6 rule:
+                "The name MUST NOT be a relative URI" */
+
+            {
+                int i;
+
+                /* skip past scheme (i.e http,ftp,...) finding first ':' char */
+                for (i = 0; i < strLen; i++) {
+                    if (input[idx + i] == ':') {
+                        break;
+                    }
+                    if (input[idx + i] == '/') {
+                        i = strLen; /* error, found relative path since '/' was
+                                     * encountered before ':'. Returning error
+                                     * value in next if statement. */
+                    }
+                }
+
+                /* test if no ':' char was found and test that the next two
+                 * chars are // to match the pattern "://" */
+                if (i >= strLen - 2 || (input[idx + i + 1] != '/' ||
+                                        input[idx + i + 2] != '/')) {
+                    WOLFSSL_MSG("\tAlt Name must be absolute URI");
+                    return ASN_ALT_NAME_E;
+                }
+            }
+        #endif
+
+            uriEntry = (DNS_entry*)XMALLOC(sizeof(DNS_entry), cert->heap,
+                                        DYNAMIC_TYPE_ALTNAME);
+            if (uriEntry == NULL) {
+                WOLFSSL_MSG("\tOut of Memory");
+                return MEMORY_E;
+            }
+
+            uriEntry->type = ASN_URI_TYPE;
+            uriEntry->name = (char*)XMALLOC(strLen + 1, cert->heap,
+                                         DYNAMIC_TYPE_ALTNAME);
+            if (uriEntry->name == NULL) {
+                WOLFSSL_MSG("\tOut of Memory");
+                XFREE(uriEntry, cert->heap, DYNAMIC_TYPE_ALTNAME);
+                return MEMORY_E;
+            }
+            uriEntry->len = strLen;
+            XMEMCPY(uriEntry->name, &input[idx], strLen);
+            uriEntry->name[strLen] = '\0';
+
+            uriEntry->next = cert->altNames;
+            cert->altNames = uriEntry;
+
+            length -= strLen;
+            idx    += strLen;
+        }
+#if defined(WOLFSSL_QT) || defined(OPENSSL_ALL)
+        else if (b == (ASN_CONTEXT_SPECIFIC | ASN_IP_TYPE)) {
+            DNS_entry* ipAddr;
+            int strLen;
+            word32 lenStartIdx = idx;
+            WOLFSSL_MSG("Decoding Subject Alt. Name: IP Address");
+
+            if (GetLength(input, &idx, &strLen, sz) < 0) {
+                WOLFSSL_MSG("\tfail: str length");
+                return ASN_PARSE_E;
+            }
+            length -= (idx - lenStartIdx);
+            /* check that strLen at index is not past input buffer */
+            if (strLen + (int)idx > sz) {
+                return BUFFER_E;
+            }
+
+            ipAddr = (DNS_entry*)XMALLOC(sizeof(DNS_entry), cert->heap,
+                                        DYNAMIC_TYPE_ALTNAME);
+            if (ipAddr == NULL) {
+                WOLFSSL_MSG("\tOut of Memory");
+                return MEMORY_E;
+            }
+
+            ipAddr->type = ASN_IP_TYPE;
+            ipAddr->name = (char*)XMALLOC(strLen + 1, cert->heap,
+                                         DYNAMIC_TYPE_ALTNAME);
+            if (ipAddr->name == NULL) {
+                WOLFSSL_MSG("\tOut of Memory");
+                XFREE(ipAddr, cert->heap, DYNAMIC_TYPE_ALTNAME);
+                return MEMORY_E;
+            }
+            ipAddr->len = strLen;
+            XMEMCPY(ipAddr->name, &input[idx], strLen);
+            ipAddr->name[strLen] = '\0';
+
+            ipAddr->next   = cert->altNames;
+            cert->altNames = ipAddr;
+
+            length -= strLen;
+            idx    += strLen;
+        }
+#endif /* WOLFSSL_QT || OPENSSL_ALL */
+#endif /* IGNORE_NAME_CONSTRAINTS */
+#ifdef WOLFSSL_SEP
+        else if (b == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | ASN_OTHER_TYPE))
+        {
+            int strLen;
+            word32 lenStartIdx = idx;
+            word32 oid = 0;
+            int    ret;
+            byte   tag;
+
+            if (GetLength(input, &idx, &strLen, sz) < 0) {
+                WOLFSSL_MSG("\tfail: other name length");
+                return ASN_PARSE_E;
+            }
+            /* Consume the rest of this sequence. */
+            length -= (strLen + idx - lenStartIdx);
+
+            if (GetObjectId(input, &idx, &oid, oidCertAltNameType, sz) < 0) {
+                WOLFSSL_MSG("\tbad OID");
+                return ASN_PARSE_E;
+            }
+
+            if (oid != HW_NAME_OID) {
+                WOLFSSL_MSG("\tincorrect OID");
+                return ASN_PARSE_E;
+            }
+
+            if (GetASNTag(input, &idx, &tag, sz) < 0) {
+                return ASN_PARSE_E;
+            }
+
+            if (tag != (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED)) {
+                WOLFSSL_MSG("\twrong type");
+                return ASN_PARSE_E;
+            }
+
+            if (GetLength(input, &idx, &strLen, sz) < 0) {
+                WOLFSSL_MSG("\tfail: str len");
+                return ASN_PARSE_E;
+            }
+
+            if (GetSequence(input, &idx, &strLen, sz) < 0) {
+                WOLFSSL_MSG("\tBad Sequence");
+                return ASN_PARSE_E;
+            }
+
+            ret = GetASNObjectId(input, &idx, &strLen, sz);
+            if (ret != 0) {
+                WOLFSSL_MSG("\tbad OID");
+                return ret;
+            }
+
+            cert->hwType = (byte*)XMALLOC(strLen, cert->heap,
+                                          DYNAMIC_TYPE_X509_EXT);
+            if (cert->hwType == NULL) {
+                WOLFSSL_MSG("\tOut of Memory");
+                return MEMORY_E;
+            }
+
+            XMEMCPY(cert->hwType, &input[idx], strLen);
+            cert->hwTypeSz = strLen;
+            idx += strLen;
+
+            ret = GetOctetString(input, &idx, &strLen, sz);
+            if (ret < 0)
+                return ret;
+
+            cert->hwSerialNum = (byte*)XMALLOC(strLen + 1, cert->heap,
+                                               DYNAMIC_TYPE_X509_EXT);
+            if (cert->hwSerialNum == NULL) {
+                WOLFSSL_MSG("\tOut of Memory");
+                return MEMORY_E;
+            }
+
+            XMEMCPY(cert->hwSerialNum, &input[idx], strLen);
+            cert->hwSerialNum[strLen] = '\0';
+            cert->hwSerialNumSz = strLen;
+            idx += strLen;
+        }
+    #endif /* WOLFSSL_SEP */
+        else {
+            int strLen;
+            word32 lenStartIdx = idx;
+
+            WOLFSSL_MSG("\tUnsupported name type, skipping");
+
+            if (GetLength(input, &idx, &strLen, sz) < 0) {
+                WOLFSSL_MSG("\tfail: unsupported name length");
+                return ASN_PARSE_E;
+            }
+            length -= (strLen + idx - lenStartIdx);
+            idx += strLen;
+        }
+    }
+    return 0;
+}
+
+static int DecodeBasicCaConstraint(const byte* input, int sz, DecodedCert* cert)
+{
+    word32 idx = 0;
+    int length = 0;
+    int ret;
+
+    WOLFSSL_ENTER("DecodeBasicCaConstraint");
+
+    if (GetSequence(input, &idx, &length, sz) < 0) {
+        WOLFSSL_MSG("\tfail: bad SEQUENCE");
+        return ASN_PARSE_E;
+    }
+
+    if (length == 0)
+        return 0;
+
+    /* If the basic ca constraint is false, this extension may be named, but
+     * left empty. So, if the length is 0, just return. */
+
+    ret = GetBoolean(input, &idx, sz);
+
+#ifndef WOLFSSL_X509_BASICCONS_INT
+    if (ret < 0) {
+        WOLFSSL_MSG("\tfail: constraint not valid BOOLEAN");
+        return ret;
+    }
+
+    cert->isCA = (byte)ret;
+#else
+    if (ret < 0) {
+        if(input[idx] == ASN_INTEGER) {
+            /* For OpenSSL compatibility, if ASN_INTEGER it is valid format */
+            cert->isCA = FALSE;
+        } else return ret;
+    } else
+        cert->isCA = (byte)ret;
+#endif
+
+    /* If there isn't any more data, return. */
+    if (idx >= (word32)sz) {
+        return 0;
+    }
+
+    ret = GetInteger7Bit(input, &idx, sz);
+    if (ret < 0)
+        return ret;
+    cert->pathLength = (byte)ret;
+    cert->pathLengthSet = 1;
+
+    return 0;
+}
+
+
+#define CRLDP_FULL_NAME 0
+    /* From RFC3280 SS4.2.1.14, Distribution Point Name*/
+#define GENERALNAME_URI 6
+    /* From RFC3280 SS4.2.1.7, GeneralName */
+
+static int DecodeCrlDist(const byte* input, int sz, DecodedCert* cert)
+{
+    word32 idx = 0, localIdx;
+    int length = 0;
+    byte tag   = 0;
+
+    WOLFSSL_ENTER("DecodeCrlDist");
+
+    /* Unwrap the list of Distribution Points*/
+    if (GetSequence(input, &idx, &length, sz) < 0)
+        return ASN_PARSE_E;
+
+    /* Unwrap a single Distribution Point */
+    if (GetSequence(input, &idx, &length, sz) < 0)
+        return ASN_PARSE_E;
+
+    /* The Distribution Point has three explicit optional members
+     *  First check for a DistributionPointName
+     */
+    localIdx = idx;
+    if (GetASNTag(input, &localIdx, &tag, sz) == 0 &&
+            tag == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 0))
+    {
+        idx++;
+        if (GetLength(input, &idx, &length, sz) < 0)
+            return ASN_PARSE_E;
+
+        localIdx = idx;
+        if (GetASNTag(input, &localIdx, &tag, sz) == 0 &&
+                tag == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED |
+                    CRLDP_FULL_NAME))
+        {
+            idx++;
+            if (GetLength(input, &idx, &length, sz) < 0)
+                return ASN_PARSE_E;
+
+            localIdx = idx;
+            if (GetASNTag(input, &localIdx, &tag, sz) == 0 &&
+                    tag == (ASN_CONTEXT_SPECIFIC | GENERALNAME_URI))
+            {
+                idx++;
+                if (GetLength(input, &idx, &length, sz) < 0)
+                    return ASN_PARSE_E;
+
+                cert->extCrlInfoSz = length;
+                cert->extCrlInfo = input + idx;
+                idx += length;
+            }
+            else
+                /* This isn't a URI, skip it. */
+                idx += length;
+        }
+        else {
+            /* This isn't a FULLNAME, skip it. */
+            idx += length;
+        }
+    }
+
+    /* Check for reasonFlags */
+    localIdx = idx;
+    if (idx < (word32)sz &&
+        GetASNTag(input, &localIdx, &tag, sz) == 0 &&
+        tag == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 1))
+    {
+        idx++;
+        if (GetLength(input, &idx, &length, sz) < 0)
+            return ASN_PARSE_E;
+        idx += length;
+    }
+
+    /* Check for cRLIssuer */
+    localIdx = idx;
+    if (idx < (word32)sz &&
+        GetASNTag(input, &localIdx, &tag, sz) == 0 &&
+        tag == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 2))
+    {
+        idx++;
+        if (GetLength(input, &idx, &length, sz) < 0)
+            return ASN_PARSE_E;
+        idx += length;
+    }
+
+    if (idx < (word32)sz)
+    {
+        WOLFSSL_MSG("\tThere are more CRL Distribution Point records, "
+                   "but we only use the first one.");
+    }
+
+    return 0;
+}
+
+
+static int DecodeAuthInfo(const byte* input, int sz, DecodedCert* cert)
+/*
+ *  Read Authority Information Access records. If there are
+ *  any issues, return without saving the record.
+ */
+{
+    word32 idx = 0;
+    int length = 0;
+    int count  = 0;
+    byte b = 0;
+    word32 oid;
+
+    WOLFSSL_ENTER("DecodeAuthInfo");
+
+    /* Unwrap the list of AIAs */
+    if (GetSequence(input, &idx, &length, sz) < 0)
+        return ASN_PARSE_E;
+
+    while ((idx < (word32)sz) && (count < MAX_AIA_SZ)) {
+        /* Unwrap a single AIA */
+        if (GetSequence(input, &idx, &length, sz) < 0)
+            return ASN_PARSE_E;
+
+        oid = 0;
+        if (GetObjectId(input, &idx, &oid, oidCertAuthInfoType, sz) < 0)
+            return ASN_PARSE_E;
+
+        /* Only supporting URIs right now. */
+        if (GetASNTag(input, &idx, &b, sz) < 0)
+            return ASN_PARSE_E;
+
+        if (GetLength(input, &idx, &length, sz) < 0)
+            return ASN_PARSE_E;
+
+        /* Set ocsp entry */
+        if (b == (ASN_CONTEXT_SPECIFIC | GENERALNAME_URI) &&
+            oid == AIA_OCSP_OID)
+        {
+            cert->extAuthInfoSz = length;
+            cert->extAuthInfo = input + idx;
+            count++;
+        #if !defined(OPENSSL_ALL) || !defined(WOLFSSL_QT)
+            break;
+        #endif
+        }
+        #if defined(OPENSSL_ALL) || defined(WOLFSSL_QT)
+        /* Set CaIssuers entry */
+        else if ((b == (ASN_CONTEXT_SPECIFIC | GENERALNAME_URI)) &&
+            oid == AIA_CA_ISSUER_OID)
+        {
+            cert->extAuthInfoCaIssuerSz = length;
+            cert->extAuthInfoCaIssuer = input + idx;
+            count++;
+        }
+        #endif
+        idx += length;
+    }
+
+    return 0;
+}
+
+
+static int DecodeAuthKeyId(const byte* input, int sz, DecodedCert* cert)
+{
+    word32 idx = 0;
+    int length = 0, ret = 0;
+    byte tag;
+
+    WOLFSSL_ENTER("DecodeAuthKeyId");
+
+    if (GetSequence(input, &idx, &length, sz) < 0) {
+        WOLFSSL_MSG("\tfail: should be a SEQUENCE\n");
+        return ASN_PARSE_E;
+    }
+
+    if (GetASNTag(input, &idx, &tag, sz) < 0) {
+        return ASN_PARSE_E;
+    }
+
+    if (tag != (ASN_CONTEXT_SPECIFIC | 0)) {
+        WOLFSSL_MSG("\tinfo: OPTIONAL item 0, not available\n");
+        cert->extAuthKeyIdSet = 0;
+        return 0;
+    }
+
+    if (GetLength(input, &idx, &length, sz) <= 0) {
+        WOLFSSL_MSG("\tfail: extension data length");
+        return ASN_PARSE_E;
+    }
+
+#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
+    cert->extAuthKeyIdSrc = &input[idx];
+    cert->extAuthKeyIdSz = length;
+#endif /* OPENSSL_EXTRA */
+
+    if (length == KEYID_SIZE) {
+        XMEMCPY(cert->extAuthKeyId, input + idx, length);
+    }
+    else
+        ret = CalcHashId(input + idx, length, cert->extAuthKeyId);
+
+    return ret;
+}
+
+
+static int DecodeSubjKeyId(const byte* input, int sz, DecodedCert* cert)
+{
+    word32 idx = 0;
+    int length = 0, ret = 0;
+
+    WOLFSSL_ENTER("DecodeSubjKeyId");
+
+    if (sz <= 0)
+        return ASN_PARSE_E;
+
+    ret = GetOctetString(input, &idx, &length, sz);
+    if (ret < 0)
+        return ret;
+
+    #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
+        cert->extSubjKeyIdSrc = &input[idx];
+        cert->extSubjKeyIdSz = length;
+    #endif /* OPENSSL_EXTRA */
+
+    if (length == KEYID_SIZE) {
+        XMEMCPY(cert->extSubjKeyId, input + idx, length);
+    }
+    else
+        ret = CalcHashId(input + idx, length, cert->extSubjKeyId);
+
+    return ret;
+}
+
+
+static int DecodeKeyUsage(const byte* input, int sz, DecodedCert* cert)
+{
+    word32 idx = 0;
+    int length;
+    int ret;
+    WOLFSSL_ENTER("DecodeKeyUsage");
+
+    ret = CheckBitString(input, &idx, &length, sz, 0, NULL);
+    if (ret != 0)
+        return ret;
+
+    cert->extKeyUsage = (word16)(input[idx]);
+    if (length == 2)
+        cert->extKeyUsage |= (word16)(input[idx+1] << 8);
+
+    return 0;
+}
+
+
+static int DecodeExtKeyUsage(const byte* input, int sz, DecodedCert* cert)
+{
+    word32 idx = 0, oid;
+    int length, ret;
+
+    WOLFSSL_MSG("DecodeExtKeyUsage");
+
+    if (GetSequence(input, &idx, &length, sz) < 0) {
+        WOLFSSL_MSG("\tfail: should be a SEQUENCE");
+        return ASN_PARSE_E;
+    }
+
+#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
+    cert->extExtKeyUsageSrc = input + idx;
+    cert->extExtKeyUsageSz = length;
+#endif
+
+    while (idx < (word32)sz) {
+        ret = GetObjectId(input, &idx, &oid, oidCertKeyUseType, sz);
+        if (ret == ASN_UNKNOWN_OID_E)
+            continue;
+        else if (ret < 0)
+            return ret;
+
+        switch (oid) {
+            case EKU_ANY_OID:
+                cert->extExtKeyUsage |= EXTKEYUSE_ANY;
+                break;
+            case EKU_SERVER_AUTH_OID:
+                cert->extExtKeyUsage |= EXTKEYUSE_SERVER_AUTH;
+                break;
+            case EKU_CLIENT_AUTH_OID:
+                cert->extExtKeyUsage |= EXTKEYUSE_CLIENT_AUTH;
+                break;
+            case EKU_CODESIGNING_OID:
+                cert->extExtKeyUsage |= EXTKEYUSE_CODESIGN;
+                break;
+            case EKU_EMAILPROTECT_OID:
+                cert->extExtKeyUsage |= EXTKEYUSE_EMAILPROT;
+                break;
+            case EKU_TIMESTAMP_OID:
+                cert->extExtKeyUsage |= EXTKEYUSE_TIMESTAMP;
+                break;
+            case EKU_OCSP_SIGN_OID:
+                cert->extExtKeyUsage |= EXTKEYUSE_OCSP_SIGN;
+                break;
+        }
+
+    #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
+        cert->extExtKeyUsageCount++;
+    #endif
+    }
+
+    return 0;
+}
+
+
+#ifndef IGNORE_NAME_CONSTRAINTS
+#define ASN_TYPE_MASK 0xF
+static int DecodeSubtree(const byte* input, int sz,
+                         Base_entry** head, void* heap)
+{
+    word32 idx = 0;
+
+    (void)heap;
+
+    while (idx < (word32)sz) {
+        int seqLength, strLength;
+        word32 nameIdx;
+        byte b, bType;
+
+        if (GetSequence(input, &idx, &seqLength, sz) < 0) {
+            WOLFSSL_MSG("\tfail: should be a SEQUENCE");
+            return ASN_PARSE_E;
+        }
+        nameIdx = idx;
+        b = input[nameIdx++];
+
+        if (GetLength(input, &nameIdx, &strLength, sz) <= 0) {
+            WOLFSSL_MSG("\tinvalid length");
+            return ASN_PARSE_E;
+        }
+
+        /* Get type, LSB 4-bits */
+        bType = (b & ASN_TYPE_MASK);
+
+        if (bType == ASN_DNS_TYPE || bType == ASN_RFC822_TYPE ||
+                                                        bType == ASN_DIR_TYPE) {
+            Base_entry* entry;
+
+            /* if constructed has leading sequence */
+            if (b & ASN_CONSTRUCTED) {
+                if (GetSequence(input, &nameIdx, &strLength, sz) < 0) {
+                    WOLFSSL_MSG("\tfail: constructed be a SEQUENCE");
+                    return ASN_PARSE_E;
+                }
+            }
+
+            entry = (Base_entry*)XMALLOC(sizeof(Base_entry), heap,
+                                                          DYNAMIC_TYPE_ALTNAME);
+            if (entry == NULL) {
+                WOLFSSL_MSG("allocate error");
+                return MEMORY_E;
+            }
+
+            entry->name = (char*)XMALLOC(strLength, heap, DYNAMIC_TYPE_ALTNAME);
+            if (entry->name == NULL) {
+                WOLFSSL_MSG("allocate error");
+                XFREE(entry, heap, DYNAMIC_TYPE_ALTNAME);
+                return MEMORY_E;
+            }
+
+            XMEMCPY(entry->name, &input[nameIdx], strLength);
+            entry->nameSz = strLength;
+            entry->type = bType;
+
+            entry->next = *head;
+            *head = entry;
+        }
+
+        idx += seqLength;
+    }
+
+    return 0;
+}
+
+
+static int DecodeNameConstraints(const byte* input, int sz, DecodedCert* cert)
+{
+    word32 idx = 0;
+    int length = 0;
+
+    WOLFSSL_ENTER("DecodeNameConstraints");
+
+    if (GetSequence(input, &idx, &length, sz) < 0) {
+        WOLFSSL_MSG("\tfail: should be a SEQUENCE");
+        return ASN_PARSE_E;
+    }
+
+    while (idx < (word32)sz) {
+        byte b = input[idx++];
+        Base_entry** subtree = NULL;
+
+        if (GetLength(input, &idx, &length, sz) <= 0) {
+            WOLFSSL_MSG("\tinvalid length");
+            return ASN_PARSE_E;
+        }
+
+        if (b == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | 0))
+            subtree = &cert->permittedNames;
+        else if (b == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | 1))
+            subtree = &cert->excludedNames;
+        else {
+            WOLFSSL_MSG("\tinvalid subtree");
+            return ASN_PARSE_E;
+        }
+
+        DecodeSubtree(input + idx, length, subtree, cert->heap);
+
+        idx += length;
+    }
+
+    return 0;
+}
+#endif /* IGNORE_NAME_CONSTRAINTS */
+
+#if (defined(WOLFSSL_CERT_EXT) && !defined(WOLFSSL_SEP)) || defined(OPENSSL_EXTRA)
+
+/* Decode ITU-T X.690 OID format to a string representation
+ * return string length */
+int DecodePolicyOID(char *out, word32 outSz, const byte *in, word32 inSz)
+{
+    word32 val, inIdx = 0, outIdx = 0;
+    int w = 0;
+
+    if (out == NULL || in == NULL || outSz < 4 || inSz < 2)
+        return BAD_FUNC_ARG;
+
+    /* The first byte expands into b/40 dot b%40. */
+    val = in[inIdx++];
+
+    w = XSNPRINTF(out, outSz, "%u.%u", val / 40, val % 40);
+    if (w < 0)
+        goto exit;
+    outIdx += w;
+    val = 0;
+
+    while (inIdx < inSz && outIdx < outSz) {
+        /* extract the next OID digit from in to val */
+        /* first bit is used to set if value is coded on 1 or multiple bytes */
+        if (in[inIdx] & 0x80) {
+            val += in[inIdx] & 0x7F;
+            val *= 128;
+        }
+        else {
+            /* write val as text into out */
+            val += in[inIdx];
+            w = XSNPRINTF(out + outIdx, outSz - outIdx, ".%u", val);
+            if (w < 0)
+                goto exit;
+            outIdx += w;
+            val = 0;
+        }
+        inIdx++;
+    }
+    if (outIdx == outSz)
+        outIdx--;
+    out[outIdx] = 0;
+
+    w = (int)outIdx;
+
+exit:
+    return w;
+}
+#endif /* WOLFSSL_CERT_EXT && !WOLFSSL_SEP */
+
+#if defined(WOLFSSL_SEP) || defined(WOLFSSL_CERT_EXT) || defined(WOLFSSL_QT)
+    /* Reference: https://tools.ietf.org/html/rfc5280#section-4.2.1.4 */
+    static int DecodeCertPolicy(const byte* input, int sz, DecodedCert* cert)
+    {
+        word32 idx = 0;
+        word32 oldIdx;
+        int ret;
+        int total_length = 0, policy_length = 0, length = 0;
+    #if !defined(WOLFSSL_SEP) && defined(WOLFSSL_CERT_EXT) && \
+        !defined(WOLFSSL_DUP_CERTPOL)
+        int i;
+    #endif
+
+        WOLFSSL_ENTER("DecodeCertPolicy");
+        #if defined(WOLFSSL_SEP) || defined(WOLFSSL_CERT_EXT)
+        /* Check if cert is null before dereferencing below */
+        if (cert == NULL)
+            return BAD_FUNC_ARG;
+        #endif
+
+    #if defined(WOLFSSL_CERT_EXT)
+         cert->extCertPoliciesNb = 0;
+    #endif
+
+        if (GetSequence(input, &idx, &total_length, sz) < 0) {
+            WOLFSSL_MSG("\tGet CertPolicy total seq failed");
+            return ASN_PARSE_E;
+        }
+
+        /* Validate total length */
+        if (total_length > (sz - (int)idx)) {
+            WOLFSSL_MSG("\tCertPolicy length mismatch");
+            return ASN_PARSE_E;
+        }
+
+        /* Unwrap certificatePolicies */
+        do {
+            if (GetSequence(input, &idx, &policy_length, sz) < 0) {
+                WOLFSSL_MSG("\tGet CertPolicy seq failed");
+                return ASN_PARSE_E;
+            }
+
+            oldIdx = idx;
+            ret = GetASNObjectId(input, &idx, &length, sz);
+            if (ret != 0)
+                return ret;
+            policy_length -= idx - oldIdx;
+
+            if (length > 0) {
+                /* Verify length won't overrun buffer */
+                if (length > (sz - (int)idx)) {
+                    WOLFSSL_MSG("\tCertPolicy length exceeds input buffer");
+                    return ASN_PARSE_E;
+                }
+
+        #if defined(WOLFSSL_SEP)
+                cert->deviceType = (byte*)XMALLOC(length, cert->heap,
+                                                         DYNAMIC_TYPE_X509_EXT);
+                if (cert->deviceType == NULL) {
+                    WOLFSSL_MSG("\tCouldn't alloc memory for deviceType");
+                    return MEMORY_E;
+                }
+                cert->deviceTypeSz = length;
+                XMEMCPY(cert->deviceType, input + idx, length);
+                break;
+        #elif defined(WOLFSSL_CERT_EXT)
+                /* decode cert policy */
+                if (DecodePolicyOID(cert->extCertPolicies[
+                                       cert->extCertPoliciesNb], MAX_CERTPOL_SZ,
+                                       input + idx, length) <= 0) {
+                    WOLFSSL_MSG("\tCouldn't decode CertPolicy");
+                    return ASN_PARSE_E;
+                }
+            #ifndef WOLFSSL_DUP_CERTPOL
+                /* From RFC 5280 section 4.2.1.3 "A certificate policy OID MUST
+                 * NOT appear more than once in a certificate policies
+                 * extension". This is a sanity check for duplicates.
+                 * extCertPolicies should only have OID values, additional
+                 * qualifiers need to be stored in a separate array. */
+                for (i = 0; i < cert->extCertPoliciesNb; i++) {
+                    if (XMEMCMP(cert->extCertPolicies[i],
+                            cert->extCertPolicies[cert->extCertPoliciesNb],
+                            MAX_CERTPOL_SZ) == 0) {
+                            WOLFSSL_MSG("Duplicate policy OIDs not allowed");
+                            WOLFSSL_MSG("Use WOLFSSL_DUP_CERTPOL if wanted");
+                            return CERTPOLICIES_E;
+                    }
+                }
+            #endif /* !WOLFSSL_DUP_CERTPOL */
+                cert->extCertPoliciesNb++;
+        #else
+                WOLFSSL_LEAVE("DecodeCertPolicy : unsupported mode", 0);
+                return 0;
+        #endif
+            }
+            idx += policy_length;
+        } while((int)idx < total_length
+    #if defined(WOLFSSL_CERT_EXT)
+            && cert->extCertPoliciesNb < MAX_CERTPOL_NB
+    #endif
+        );
+
+        WOLFSSL_LEAVE("DecodeCertPolicy", 0);
+        return 0;
+    }
+#endif /* WOLFSSL_SEP */
+
+/* Macro to check if bit is set, if not sets and return success.
+    Otherwise returns failure */
+/* Macro required here because bit-field operation */
+#ifndef WOLFSSL_NO_ASN_STRICT
+    #define VERIFY_AND_SET_OID(bit) \
+        if (bit == 0) \
+            bit = 1; \
+        else \
+            return ASN_OBJECT_ID_E;
+#else
+    /* With no strict defined, the verify is skipped */
+#define VERIFY_AND_SET_OID(bit) bit = 1;
+#endif
+
+static int DecodeCertExtensions(DecodedCert* cert)
+/*
+ *  Processing the Certificate Extensions. This does not modify the current
+ *  index. It is works starting with the recorded extensions pointer.
+ */
+{
+    int ret = 0;
+    word32 idx = 0;
+    int sz = cert->extensionsSz;
+    const byte* input = cert->extensions;
+    int length;
+    word32 oid;
+    byte critical = 0;
+    byte criticalFail = 0;
+    byte tag = 0;
+
+    WOLFSSL_ENTER("DecodeCertExtensions");
+
+    if (input == NULL || sz == 0)
+        return BAD_FUNC_ARG;
+
+    if (GetASNTag(input, &idx, &tag, sz) < 0) {
+        return ASN_PARSE_E;
+    }
+
+    if (tag != ASN_EXTENSIONS) {
+        WOLFSSL_MSG("\tfail: should be an EXTENSIONS");
+        return ASN_PARSE_E;
+    }
+
+    if (GetLength(input, &idx, &length, sz) < 0) {
+        WOLFSSL_MSG("\tfail: invalid length");
+        return ASN_PARSE_E;
+    }
+
+    if (GetSequence(input, &idx, &length, sz) < 0) {
+        WOLFSSL_MSG("\tfail: should be a SEQUENCE (1)");
+        return ASN_PARSE_E;
+    }
+
+    while (idx < (word32)sz) {
+        word32 localIdx;
+
+        if (GetSequence(input, &idx, &length, sz) < 0) {
+            WOLFSSL_MSG("\tfail: should be a SEQUENCE");
+            return ASN_PARSE_E;
+        }
+
+        oid = 0;
+        if ((ret = GetObjectId(input, &idx, &oid, oidCertExtType, sz)) < 0) {
+            WOLFSSL_MSG("\tfail: OBJECT ID");
+            return ret;
+        }
+
+        /* check for critical flag */
+        critical = 0;
+        if ((idx + 1) > (word32)sz) {
+            WOLFSSL_MSG("\tfail: malformed buffer");
+            return BUFFER_E;
+        }
+
+        localIdx = idx;
+        if (GetASNTag(input, &localIdx, &tag, sz) == 0) {
+            if (tag == ASN_BOOLEAN) {
+                ret = GetBoolean(input, &idx, sz);
+                if (ret < 0) {
+                    WOLFSSL_MSG("\tfail: critical boolean");
+                    return ret;
+                }
+
+                critical = (byte)ret;
+            }
+        }
+
+        /* process the extension based on the OID */
+        ret = GetOctetString(input, &idx, &length, sz);
+        if (ret < 0) {
+            WOLFSSL_MSG("\tfail: bad OCTET STRING");
+            return ret;
+        }
+
+        switch (oid) {
+            case BASIC_CA_OID:
+                VERIFY_AND_SET_OID(cert->extBasicConstSet);
+                #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
+                    cert->extBasicConstCrit = critical;
+                #endif
+                if (DecodeBasicCaConstraint(&input[idx], length, cert) < 0)
+                    return ASN_PARSE_E;
+                break;
+
+            case CRL_DIST_OID:
+                VERIFY_AND_SET_OID(cert->extCRLdistSet);
+                #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
+                    cert->extCRLdistCrit = critical;
+                #endif
+                if (DecodeCrlDist(&input[idx], length, cert) < 0)
+                    return ASN_PARSE_E;
+                break;
+
+            case AUTH_INFO_OID:
+                VERIFY_AND_SET_OID(cert->extAuthInfoSet);
+                #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
+                    cert->extAuthInfoCrit = critical;
+                #endif
+                if (DecodeAuthInfo(&input[idx], length, cert) < 0)
+                    return ASN_PARSE_E;
+                break;
+
+            case ALT_NAMES_OID:
+                VERIFY_AND_SET_OID(cert->extSubjAltNameSet);
+                #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
+                    cert->extSubjAltNameCrit = critical;
+                #endif
+                ret = DecodeAltNames(&input[idx], length, cert);
+                if (ret < 0)
+                    return ret;
+                break;
+
+            case AUTH_KEY_OID:
+                VERIFY_AND_SET_OID(cert->extAuthKeyIdSet);
+                #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
+                    cert->extAuthKeyIdCrit = critical;
+                #endif
+                #ifndef WOLFSSL_ALLOW_CRIT_SKID
+                    /* This check is added due to RFC 5280 section 4.2.1.1
+                     * stating that conforming CA's must mark this extension
+                     * as non-critical. When parsing extensions check that
+                     * certificate was made in compliance with this. */
+                    if (critical) {
+                        WOLFSSL_MSG("Critical Auth Key ID is not allowed");
+                        WOLFSSL_MSG("Use macro WOLFSSL_ALLOW_CRIT_SKID if wanted");
+                        return ASN_CRIT_EXT_E;
+                    }
+                #endif
+                if (DecodeAuthKeyId(&input[idx], length, cert) < 0)
+                    return ASN_PARSE_E;
+                break;
+
+            case SUBJ_KEY_OID:
+                VERIFY_AND_SET_OID(cert->extSubjKeyIdSet);
+                #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
+                    cert->extSubjKeyIdCrit = critical;
+                #endif
+                #ifndef WOLFSSL_ALLOW_CRIT_SKID
+                    /* This check is added due to RFC 5280 section 4.2.1.2
+                     * stating that conforming CA's must mark this extension
+                     * as non-critical. When parsing extensions check that
+                     * certificate was made in compliance with this. */
+                    if (critical) {
+                        WOLFSSL_MSG("Critical Subject Key ID is not allowed");
+                        WOLFSSL_MSG("Use macro WOLFSSL_ALLOW_CRIT_SKID if wanted");
+                        return ASN_CRIT_EXT_E;
+                    }
+                #endif
+
+                if (DecodeSubjKeyId(&input[idx], length, cert) < 0)
+                    return ASN_PARSE_E;
+                break;
+
+            case CERT_POLICY_OID:
+                #if defined(WOLFSSL_SEP) || defined(WOLFSSL_QT)
+                    VERIFY_AND_SET_OID(cert->extCertPolicySet);
+                    #if defined(OPENSSL_EXTRA) || \
+                        defined(OPENSSL_EXTRA_X509_SMALL)
+                        cert->extCertPolicyCrit = critical;
+                    #endif
+                #endif
+                #if defined(WOLFSSL_SEP) || defined(WOLFSSL_CERT_EXT) || \
+                    defined(WOLFSSL_QT)
+                    if (DecodeCertPolicy(&input[idx], length, cert) < 0) {
+                        return ASN_PARSE_E;
+                    }
+                #else
+                    WOLFSSL_MSG("Certificate Policy extension not supported yet.");
+                #endif
+                break;
+
+            case KEY_USAGE_OID:
+                VERIFY_AND_SET_OID(cert->extKeyUsageSet);
+                #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
+                    cert->extKeyUsageCrit = critical;
+                #endif
+                if (DecodeKeyUsage(&input[idx], length, cert) < 0)
+                    return ASN_PARSE_E;
+                break;
+
+            case EXT_KEY_USAGE_OID:
+                VERIFY_AND_SET_OID(cert->extExtKeyUsageSet);
+                #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
+                    cert->extExtKeyUsageCrit = critical;
+                #endif
+                if (DecodeExtKeyUsage(&input[idx], length, cert) < 0)
+                    return ASN_PARSE_E;
+                break;
+
+            #ifndef IGNORE_NAME_CONSTRAINTS
+            case NAME_CONS_OID:
+            #ifndef WOLFSSL_NO_ASN_STRICT
+                /* Verify RFC 5280 Sec 4.2.1.10 rule:
+                    "The name constraints extension,
+                    which MUST be used only in a CA certificate" */
+                if (!cert->isCA) {
+                    WOLFSSL_MSG("Name constraints allowed only for CA certs");
+                    return ASN_NAME_INVALID_E;
+                }
+            #endif
+                VERIFY_AND_SET_OID(cert->extNameConstraintSet);
+                #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
+                    cert->extNameConstraintCrit = critical;
+                #endif
+                if (DecodeNameConstraints(&input[idx], length, cert) < 0)
+                    return ASN_PARSE_E;
+                break;
+            #endif /* IGNORE_NAME_CONSTRAINTS */
+
+            case INHIBIT_ANY_OID:
+                VERIFY_AND_SET_OID(cert->inhibitAnyOidSet);
+                WOLFSSL_MSG("Inhibit anyPolicy extension not supported yet.");
+                break;
+
+       #ifndef IGNORE_NETSCAPE_CERT_TYPE
+            case NETSCAPE_CT_OID:
+                WOLFSSL_MSG("Netscape certificate type extension not supported "
+                            "yet.");
+                if (CheckBitString(input, &idx, &length, idx + length, 0,
+                                                                    NULL) < 0) {
+                    return ASN_PARSE_E;
+                }
+                break;
+        #endif
+
+            default:
+            #ifndef WOLFSSL_NO_ASN_STRICT
+                /* While it is a failure to not support critical extensions,
+                 * still parse the certificate ignoring the unsupported
+                 * extension to allow caller to accept it with the verify
+                 * callback. */
+                if (critical)
+                    criticalFail = 1;
+            #endif
+            break;
+        }
+        idx += length;
+    }
+
+    return criticalFail ? ASN_CRIT_EXT_E : 0;
+}
+
+int ParseCert(DecodedCert* cert, int type, int verify, void* cm)
+{
+    int   ret;
+    char* ptr;
+
+    ret = ParseCertRelative(cert, type, verify, cm);
+    if (ret < 0)
+        return ret;
+
+    if (cert->subjectCNLen > 0) {
+        ptr = (char*) XMALLOC(cert->subjectCNLen + 1, cert->heap,
+                              DYNAMIC_TYPE_SUBJECT_CN);
+        if (ptr == NULL)
+            return MEMORY_E;
+        XMEMCPY(ptr, cert->subjectCN, cert->subjectCNLen);
+        ptr[cert->subjectCNLen] = '\0';
+        cert->subjectCN = ptr;
+        cert->subjectCNStored = 1;
+    }
+
+    if (cert->keyOID == RSAk &&
+                          cert->publicKey != NULL  && cert->pubKeySize > 0) {
+        ptr = (char*) XMALLOC(cert->pubKeySize, cert->heap,
+                              DYNAMIC_TYPE_PUBLIC_KEY);
+        if (ptr == NULL)
+            return MEMORY_E;
+        XMEMCPY(ptr, cert->publicKey, cert->pubKeySize);
+        cert->publicKey = (byte *)ptr;
+        cert->pubKeyStored = 1;
+    }
+
+    return ret;
+}
+
+/* from SSL proper, for locking can't do find here anymore */
+#ifdef __cplusplus
+    extern "C" {
+#endif
+    Signer* GetCA(void* signers, byte* hash);
+    #ifndef NO_SKID
+        Signer* GetCAByName(void* signers, byte* hash);
+    #endif
+#ifdef __cplusplus
+    }
+#endif
+
+#if defined(WOLFCRYPT_ONLY) || defined(NO_CERTS)
+
+/* dummy functions, not using wolfSSL so don't need actual ones */
+Signer* GetCA(void* signers, byte* hash)
+{
+    (void)hash;
+
+    return (Signer*)signers;
+}
+
+#ifndef NO_SKID
+Signer* GetCAByName(void* signers, byte* hash)
+{
+    (void)hash;
+
+    return (Signer*)signers;
+}
+#endif /* NO_SKID */
+
+#endif /* WOLFCRYPT_ONLY || NO_CERTS */
+
+#if defined(WOLFSSL_NO_TRUSTED_CERTS_VERIFY) && !defined(NO_SKID)
+static Signer* GetCABySubjectAndPubKey(DecodedCert* cert, void* cm)
+{
+    Signer* ca = NULL;
+    if (cert->extSubjKeyIdSet)
+        ca = GetCA(cm, cert->extSubjKeyId);
+    if (ca == NULL)
+        ca = GetCAByName(cm, cert->subjectHash);
+    if (ca) {
+        if ((ca->pubKeySize == cert->pubKeySize) &&
+               (XMEMCMP(ca->publicKey, cert->publicKey, ca->pubKeySize) == 0)) {
+            return ca;
+        }
+    }
+    return NULL;
+}
+#endif
+
+#if defined(WOLFSSL_SMALL_CERT_VERIFY) || defined(OPENSSL_EXTRA)
+/* Only quick step through the certificate to find fields that are then used
+ * in certificate signature verification.
+ * Must use the signature OID from the signed part of the certificate.
+ *
+ * This is only for minimizing dynamic memory usage during TLS certificate
+ * chain processing.
+ * Doesn't support:
+ *   OCSP Only: alt lookup using subject and pub key w/o sig check
+ */
+static int CheckCertSignature_ex(const byte* cert, word32 certSz, void* heap,
+        void* cm, const byte* pubKey, word32 pubKeySz, int pubKeyOID)
+{
+#ifndef WOLFSSL_SMALL_STACK
+    SignatureCtx  sigCtx[1];
+#else
+    SignatureCtx* sigCtx;
+#endif
+    byte          hash[KEYID_SIZE];
+    Signer*       ca = NULL;
+    word32        idx = 0;
+    int           len;
+    word32        tbsCertIdx = 0;
+    word32        sigIndex   = 0;
+    word32        signatureOID = 0;
+    word32        oid = 0;
+    word32        issuerIdx = 0;
+    word32        issuerSz  = 0;
+#ifndef NO_SKID
+    int           extLen = 0;
+    word32        extIdx = 0;
+    word32        extEndIdx = 0;
+    int           extAuthKeyIdSet = 0;
+#endif
+    int           ret = 0;
+    word32        localIdx;
+    byte          tag;
+
+
+    if (cert == NULL) {
+        return BAD_FUNC_ARG;
+    }
+
+#ifdef WOLFSSL_SMALL_STACK
+    sigCtx = (SignatureCtx*)XMALLOC(sizeof(*sigCtx), heap, DYNAMIC_TYPE_SIGNATURE);
+    if (sigCtx == NULL)
+        return MEMORY_E;
+#endif
+    InitSignatureCtx(sigCtx, heap, INVALID_DEVID);
+
+    /* Certificate SEQUENCE */
+    if (GetSequence(cert, &idx, &len, certSz) < 0)
+        ret = ASN_PARSE_E;
+    if (ret == 0) {
+        tbsCertIdx = idx;
+
+        /* TBSCertificate SEQUENCE */
+        if (GetSequence(cert, &idx, &len, certSz) < 0)
+            ret = ASN_PARSE_E;
+    }
+    if (ret == 0) {
+        sigIndex = len + idx;
+
+        if ((idx + 1) > certSz)
+            ret = BUFFER_E;
+    }
+    if (ret == 0) {
+        /* version - optional */
+        localIdx = idx;
+        if (GetASNTag(cert, &localIdx, &tag, certSz) == 0) {
+            if (tag == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED)) {
+                idx++;
+                if (GetLength(cert, &idx, &len, certSz) < 0)
+                    ret = ASN_PARSE_E;
+                idx += len;
+            }
+        }
+    }
+
+    if (ret == 0) {
+        /* serialNumber */
+        if (GetASNHeader(cert, ASN_INTEGER, &idx, &len, certSz) < 0)
+            ret = ASN_PARSE_E;
+    }
+    if (ret == 0) {
+        idx += len;
+
+        /* signature */
+        if (GetAlgoId(cert, &idx, &signatureOID, oidSigType, certSz) < 0)
+            ret = ASN_PARSE_E;
+    }
+
+    if (ret == 0) {
+        issuerIdx = idx;
+        /* issuer */
+        if (GetSequence(cert, &idx, &len, certSz) < 0)
+            ret = ASN_PARSE_E;
+    }
+    if (ret == 0) {
+        issuerSz = len + idx - issuerIdx;
+    }
+#ifndef NO_SKID
+    if (ret == 0) {
+        idx += len;
+
+        /* validity */
+        if (GetSequence(cert, &idx, &len, certSz) < 0)
+            ret = ASN_PARSE_E;
+    }
+    if (ret == 0) {
+        idx += len;
+
+        /* subject */
+        if (GetSequence(cert, &idx, &len, certSz) < 0)
+            ret = ASN_PARSE_E;
+    }
+    if (ret == 0) {
+        idx += len;
+
+        /* subjectPublicKeyInfo */
+        if (GetSequence(cert, &idx, &len, certSz) < 0)
+            ret = ASN_PARSE_E;
+    }
+    if (ret == 0) {
+        idx += len;
+
+        if ((idx + 1) > certSz)
+            ret = BUFFER_E;
+    }
+    if (ret == 0) {
+        /* issuerUniqueID - optional */
+        localIdx = idx;
+        if (GetASNTag(cert, &localIdx, &tag, certSz) == 0) {
+            if (tag == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | 1)) {
+                idx++;
+                if (GetLength(cert, &idx, &len, certSz) < 0)
+                    ret = ASN_PARSE_E;
+                idx += len;
+            }
+        }
+    }
+    if (ret == 0) {
+        if ((idx + 1) > certSz)
+            ret = BUFFER_E;
+    }
+    if (ret == 0) {
+        /* subjectUniqueID - optional */
+        localIdx = idx;
+        if (GetASNTag(cert, &localIdx, &tag, certSz) == 0) {
+            if (tag == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | 2)) {
+                idx++;
+                if (GetLength(cert, &idx, &len, certSz) < 0)
+                    ret = ASN_PARSE_E;
+                idx += len;
+            }
+        }
+    }
+
+    if (ret == 0) {
+        if ((idx + 1) > certSz)
+            ret = BUFFER_E;
+    }
+    /* extensions - optional */
+    localIdx = idx;
+    if (ret == 0 && GetASNTag(cert, &localIdx, &tag, certSz) == 0 &&
+            tag == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | 3)) {
+        idx++;
+        if (GetLength(cert, &idx, &extLen, certSz) < 0)
+            ret = ASN_PARSE_E;
+        if (ret == 0) {
+            if (GetSequence(cert, &idx, &extLen, certSz) < 0)
+                ret = ASN_PARSE_E;
+        }
+        if (ret == 0) {
+            extEndIdx = idx + extLen;
+
+            /* Check each extension for the ones we want. */
+            while (ret == 0 && idx < extEndIdx) {
+                if (GetSequence(cert, &idx, &len, certSz) < 0)
+                    ret = ASN_PARSE_E;
+                if (ret == 0) {
+                    extIdx = idx;
+                    if (GetObjectId(cert, &extIdx, &oid, oidCertExtType,
+                                                                  certSz) < 0) {
+                        ret = ASN_PARSE_E;
+                    }
+
+                    if (ret == 0) {
+                        if ((extIdx + 1) > certSz)
+                            ret = BUFFER_E;
+                    }
+                }
+
+                if (ret == 0) {
+                    localIdx = extIdx;
+                    if (GetASNTag(cert, &localIdx, &tag, certSz) == 0 &&
+                            tag == ASN_BOOLEAN) {
+                        if (GetBoolean(cert, &extIdx, certSz) < 0)
+                            ret = ASN_PARSE_E;
+                    }
+                }
+                if (ret == 0) {
+                    if (GetOctetString(cert, &extIdx, &extLen, certSz) < 0)
+                        ret = ASN_PARSE_E;
+                }
+
+                if (ret == 0) {
+                    switch (oid) {
+                    case AUTH_KEY_OID:
+                        if (GetSequence(cert, &extIdx, &extLen, certSz) < 0)
+                            ret = ASN_PARSE_E;
+
+                        if (ret == 0 && (extIdx + 1) >= certSz)
+                            ret = BUFFER_E;
+
+                        if (ret == 0 &&
+                                GetASNTag(cert, &extIdx, &tag, certSz) == 0 &&
+                                tag == (ASN_CONTEXT_SPECIFIC | 0)) {
+                            if (GetLength(cert, &extIdx, &extLen, certSz) <= 0)
+                                ret = ASN_PARSE_E;
+                            if (ret == 0) {
+                                extAuthKeyIdSet = 1;
+                                if (extLen == KEYID_SIZE)
+                                    XMEMCPY(hash, cert + extIdx, extLen);
+                                else {
+                                    ret = CalcHashId(cert + extIdx, extLen,
+                                                                          hash);
+                                }
+                            }
+                        }
+                        break;
+
+                    default:
+                        break;
+                    }
+                }
+                idx += len;
+            }
+        }
+    }
+
+    if (ret == 0 && pubKey == NULL) {
+        if (extAuthKeyIdSet)
+            ca = GetCA(cm, hash);
+        if (ca == NULL) {
+            ret = CalcHashId(cert + issuerIdx, issuerSz, hash);
+            if (ret == 0)
+                ca = GetCAByName(cm, hash);
+        }
+    }
+#else
+    if (ret == 0 && pubKey == NULL) {
+        ret = CalcHashId(cert + issuerIdx, issuerSz, hash);
+        if (ret == 0)
+            ca = GetCA(cm, hash);
+    }
+#endif /* !NO_SKID */
+    if (ca == NULL && pubKey == NULL)
+        ret = ASN_NO_SIGNER_E;
+
+    if (ret == 0) {
+        idx = sigIndex;
+        /* signatureAlgorithm */
+        if (GetAlgoId(cert, &idx, &oid, oidSigType, certSz) < 0)
+            ret = ASN_PARSE_E;
+    }
+    if (ret == 0) {
+        if (oid != signatureOID)
+            ret = ASN_SIG_OID_E;
+    }
+    if (ret == 0) {
+        /* signatureValue */
+        if (CheckBitString(cert, &idx, &len, certSz, 1, NULL) < 0)
+            ret = ASN_PARSE_E;
+    }
+
+    if (ret == 0) {
+        if (pubKey != NULL) {
+            ret = ConfirmSignature(sigCtx, cert + tbsCertIdx,
+                               sigIndex - tbsCertIdx,
+                               pubKey, pubKeySz, pubKeyOID,
+                               cert + idx, len, signatureOID, NULL);
+        }
+        else {
+            ret = ConfirmSignature(sigCtx, cert + tbsCertIdx,
+                               sigIndex - tbsCertIdx,
+                               ca->publicKey, ca->pubKeySize, ca->keyOID,
+                               cert + idx, len, signatureOID, NULL);
+        }
+        if (ret != 0) {
+            WOLFSSL_MSG("Confirm signature failed");
+        }
+    }
+
+    FreeSignatureCtx(sigCtx);
+#ifdef WOLFSSL_SMALL_STACK
+    if (sigCtx != NULL)
+        XFREE(sigCtx, heap, DYNAMIC_TYPE_SIGNATURE);
+#endif
+    return ret;
+}
+
+#ifdef OPENSSL_EXTRA
+/* Call CheckCertSignature_ex using a public key buffer for verification
+ */
+int CheckCertSignaturePubKey(const byte* cert, word32 certSz, void* heap,
+        const byte* pubKey, word32 pubKeySz, int pubKeyOID)
+{
+    return CheckCertSignature_ex(cert, certSz, heap, NULL,
+            pubKey, pubKeySz, pubKeyOID);
+}
+#endif /* OPENSSL_EXTRA */
+#ifdef WOLFSSL_SMALL_CERT_VERIFY
+/* Call CheckCertSignature_ex using a certificate manager (cm)
+ */
+int CheckCertSignature(const byte* cert, word32 certSz, void* heap, void* cm)
+{
+    return CheckCertSignature_ex(cert, certSz, heap, cm, NULL, 0, 0);
+}
+#endif /* WOLFSSL_SMALL_CERT_VERIFY */
+#endif /* WOLFSSL_SMALL_CERT_VERIFY || OPENSSL_EXTRA */
+
+int ParseCertRelative(DecodedCert* cert, int type, int verify, void* cm)
+{
+    int    ret = 0;
+    int    checkPathLen = 0;
+    int    decrementMaxPathLen = 0;
+    word32 confirmOID;
+#if defined(WOLFSSL_RENESAS_TSIP)
+    int    idx = 0;
+#endif
+    byte*  tsip_encRsaKeyIdx;
+
+    if (cert == NULL) {
+        return BAD_FUNC_ARG;
+    }
+
+    if (cert->sigCtx.state == SIG_STATE_BEGIN) {
+        cert->badDate = 0;
+        cert->criticalExt = 0;
+        if ((ret = DecodeToKey(cert, verify)) < 0) {
+            if (ret == ASN_BEFORE_DATE_E || ret == ASN_AFTER_DATE_E)
+                cert->badDate = ret;
+            else
+                return ret;
+        }
+
+        WOLFSSL_MSG("Parsed Past Key");
+
+        if (cert->srcIdx < cert->sigIndex) {
+        #ifndef ALLOW_V1_EXTENSIONS
+            if (cert->version < 2) {
+                WOLFSSL_MSG("\tv1 and v2 certs not allowed extensions");
+                return ASN_VERSION_E;
+            }
+        #endif
+
+            /* save extensions */
+            cert->extensions    = &cert->source[cert->srcIdx];
+            cert->extensionsSz  = cert->sigIndex - cert->srcIdx;
+            cert->extensionsIdx = cert->srcIdx;   /* for potential later use */
+
+            if ((ret = DecodeCertExtensions(cert)) < 0) {
+                if (ret == ASN_CRIT_EXT_E)
+                    cert->criticalExt = ret;
+                else
+                    return ret;
+            }
+
+            /* advance past extensions */
+            cert->srcIdx = cert->sigIndex;
+        }
+
+        if ((ret = GetAlgoId(cert->source, &cert->srcIdx, &confirmOID,
+                             oidSigType, cert->maxIdx)) < 0)
+            return ret;
+
+        if ((ret = GetSignature(cert)) < 0)
+            return ret;
+
+        if (confirmOID != cert->signatureOID)
+            return ASN_SIG_OID_E;
+
+    #ifndef NO_SKID
+        if (cert->extSubjKeyIdSet == 0 && cert->publicKey != NULL &&
+                                                         cert->pubKeySize > 0) {
+            ret = CalcHashId(cert->publicKey, cert->pubKeySize,
+                                                            cert->extSubjKeyId);
+            if (ret != 0)
+                return ret;
+        }
+    #endif /* !NO_SKID */
+
+        if (!cert->selfSigned || (verify != NO_VERIFY && type != CA_TYPE &&
+                                                   type != TRUSTED_PEER_TYPE)) {
+            cert->ca = NULL;
+    #ifndef NO_SKID
+            if (cert->extAuthKeyIdSet) {
+                cert->ca = GetCA(cm, cert->extAuthKeyId);
+            }
+            if (cert->ca == NULL && cert->extSubjKeyIdSet
+                                 && verify != VERIFY_OCSP) {
+                cert->ca = GetCA(cm, cert->extSubjKeyId);
+            }
+            if (cert->ca != NULL && XMEMCMP(cert->issuerHash,
+                                  cert->ca->subjectNameHash, KEYID_SIZE) != 0) {
+                cert->ca = NULL;
+            }
+            if (cert->ca == NULL) {
+                cert->ca = GetCAByName(cm, cert->issuerHash);
+                /* If AKID is available then this CA doesn't have the public
+                 * key required */
+                if (cert->ca && cert->extAuthKeyIdSet) {
+                    WOLFSSL_MSG("CA SKID doesn't match AKID");
+                    cert->ca = NULL;
+                }
+            }
+
+            /* OCSP Only: alt lookup using subject and pub key w/o sig check */
+        #ifdef WOLFSSL_NO_TRUSTED_CERTS_VERIFY
+            if (cert->ca == NULL && verify == VERIFY_OCSP) {
+                cert->ca = GetCABySubjectAndPubKey(cert, cm);
+                if (cert->ca) {
+                    ret = 0; /* success */
+                    goto exit_pcr;
+                }
+            }
+        #endif /* WOLFSSL_NO_TRUSTED_CERTS_VERIFY */
+    #else
+            cert->ca = GetCA(cm, cert->issuerHash);
+    #endif /* !NO_SKID */
+        }
+
+        if (cert->selfSigned) {
+            cert->maxPathLen = WOLFSSL_MAX_PATH_LEN;
+        } else {
+            /* RFC 5280 Section 4.2.1.9:
+             *
+             * load/receive check
+             *
+             * 1) Is CA boolean set?
+             *      No  - SKIP CHECK
+             *      Yes - Check key usage
+             * 2) Is Key usage extension present?
+             *      No  - goto 3
+             *      Yes - check keyCertSign assertion
+             *     2.a) Is keyCertSign asserted?
+             *          No  - goto 4
+             *          Yes - goto 3
+             * 3) Is pathLen set?
+             *      No  - goto 4
+             *      Yes - check pathLen against maxPathLen.
+             *      3.a) Is pathLen less than maxPathLen?
+             *           No - goto 4
+             *           Yes - set maxPathLen to pathLen and EXIT
+             * 4) Is maxPathLen > 0?
+             *      Yes - Reduce by 1
+             *      No  - ERROR
+             */
+
+            if (cert->ca && cert->pathLengthSet) {
+                cert->maxPathLen = cert->pathLength;
+                if (cert->isCA) {
+                    WOLFSSL_MSG("\tCA boolean set");
+                    if (cert->extKeyUsageSet) {
+                         WOLFSSL_MSG("\tExtension Key Usage Set");
+                         if ((cert->extKeyUsage & KEYUSE_KEY_CERT_SIGN) != 0) {
+                            checkPathLen = 1;
+                         } else {
+                            decrementMaxPathLen = 1;
+                         }
+                    } else {
+                        checkPathLen = 1;
+                    } /* !cert->ca check */
+                } /* cert is not a CA (assuming entity cert) */
+
+                if (checkPathLen && cert->pathLengthSet) {
+                    if (cert->pathLength < cert->ca->maxPathLen) {
+                        WOLFSSL_MSG("\tmaxPathLen status: set to pathLength");
+                        cert->maxPathLen = cert->pathLength;
+                    } else {
+                        decrementMaxPathLen = 1;
+                    }
+                }
+
+                if (decrementMaxPathLen && cert->ca->maxPathLen > 0) {
+                    WOLFSSL_MSG("\tmaxPathLen status: reduce by 1");
+                    cert->maxPathLen = cert->ca->maxPathLen - 1;
+                    if (verify != NO_VERIFY && type != CA_TYPE &&
+                                                    type != TRUSTED_PEER_TYPE) {
+                        WOLFSSL_MSG("\tmaxPathLen status: OK");
+                    }
+                } else if (decrementMaxPathLen && cert->ca->maxPathLen == 0) {
+                    cert->maxPathLen = 0;
+                    if (verify != NO_VERIFY && type != CA_TYPE &&
+                                                    type != TRUSTED_PEER_TYPE) {
+                        WOLFSSL_MSG("\tNon-entity cert, maxPathLen is 0");
+                        WOLFSSL_MSG("\tmaxPathLen status: ERROR");
+                        return ASN_PATHLEN_INV_E;
+                    }
+                }
+            } else if (cert->ca && cert->isCA) {
+                /* case where cert->pathLength extension is not set */
+                if (cert->ca->maxPathLen > 0) {
+                    cert->maxPathLen = cert->ca->maxPathLen - 1;
+                } else {
+                    cert->maxPathLen = 0;
+                    if (verify != NO_VERIFY && type != CA_TYPE &&
+                                                    type != TRUSTED_PEER_TYPE) {
+                        WOLFSSL_MSG("\tNon-entity cert, maxPathLen is 0");
+                        WOLFSSL_MSG("\tmaxPathLen status: ERROR");
+                        return ASN_PATHLEN_INV_E;
+                    }
+                }
+            }
+            #ifdef HAVE_OCSP
+            if (verify != NO_VERIFY && type != CA_TYPE &&
+                                                    type != TRUSTED_PEER_TYPE) {
+                if (cert->ca) {
+                    /* Need the CA's public key hash for OCSP */
+                    XMEMCPY(cert->issuerKeyHash, cert->ca->subjectKeyHash,
+                                                                    KEYID_SIZE);
+                }
+
+            }
+            #endif /* HAVE_OCSP */
+        }
+    }
+#if defined(WOLFSSL_RENESAS_TSIP)
+    /* prepare for TSIP TLS cert verification API use */
+    if (cert->keyOID == RSAk) {
+        /* to call TSIP API, it needs keys position info in bytes */
+        if ((ret = RsaPublicKeyDecodeRawIndex(cert->publicKey, (word32*)&idx,
+                                   cert->pubKeySize,
+                                   &cert->sigCtx.pubkey_n_start,
+                                   &cert->sigCtx.pubkey_n_len,
+                                   &cert->sigCtx.pubkey_e_start,
+                                   &cert->sigCtx.pubkey_e_len)) != 0) {
+            WOLFSSL_MSG("Decoding index from cert failed.");
+            return ret;
+        }
+        cert->sigCtx.certBegin = cert->certBegin;
+    }
+    /* check if we can use TSIP for cert verification */
+    /* if the ca is verified as tsip root ca.         */
+    /* TSIP can only handle 2048 bits(256 byte) key.  */
+    if (cert->ca && tsip_checkCA(cert->ca->cm_idx) != 0 &&
+        cert->sigCtx.pubkey_n_len == 256) {
+
+        /* assign memory to encrypted tsip Rsa key index */
+        if (!cert->tsip_encRsaKeyIdx)
+            cert->tsip_encRsaKeyIdx =
+                            (byte*)XMALLOC(TSIP_TLS_ENCPUBKEY_SZ_BY_CERTVRFY,
+                             cert->heap, DYNAMIC_TYPE_RSA);
+        if (cert->tsip_encRsaKeyIdx == NULL)
+                return MEMORY_E;
+    } else {
+        if (cert->ca) {
+            /* TSIP isn't usable */
+            if (tsip_checkCA(cert->ca->cm_idx) == 0)
+                WOLFSSL_MSG("TSIP isn't usable because the ca isn't verified "
+                            "by TSIP.");
+            else if (cert->sigCtx.pubkey_n_len != 256)
+                WOLFSSL_MSG("TSIP isn't usable because the ca isn't signed by "
+                            "RSA 2048.");
+            else
+                WOLFSSL_MSG("TSIP isn't usable");
+        }
+        cert->tsip_encRsaKeyIdx = NULL;
+    }
+
+    tsip_encRsaKeyIdx = cert->tsip_encRsaKeyIdx;
+#else
+    tsip_encRsaKeyIdx = NULL;
+#endif
+
+    if (verify != NO_VERIFY && type != CA_TYPE && type != TRUSTED_PEER_TYPE) {
+        if (cert->ca) {
+            if (verify == VERIFY || verify == VERIFY_OCSP ||
+                                                 verify == VERIFY_SKIP_DATE) {
+                /* try to confirm/verify signature */
+                if ((ret = ConfirmSignature(&cert->sigCtx,
+                        cert->source + cert->certBegin,
+                        cert->sigIndex - cert->certBegin,
+                        cert->ca->publicKey, cert->ca->pubKeySize,
+                        cert->ca->keyOID, cert->signature,
+                        cert->sigLength, cert->signatureOID,
+                        tsip_encRsaKeyIdx)) != 0) {
+                    if (ret != 0 && ret != WC_PENDING_E) {
+                        WOLFSSL_MSG("Confirm signature failed");
+                    }
+                    return ret;
+                }
+            }
+        #ifndef IGNORE_NAME_CONSTRAINTS
+            if (verify == VERIFY || verify == VERIFY_OCSP ||
+                        verify == VERIFY_NAME || verify == VERIFY_SKIP_DATE) {
+                /* check that this cert's name is permitted by the signer's
+                 * name constraints */
+                if (!ConfirmNameConstraints(cert->ca, cert)) {
+                    WOLFSSL_MSG("Confirm name constraint failed");
+                    return ASN_NAME_INVALID_E;
+                }
+            }
+        #endif /* IGNORE_NAME_CONSTRAINTS */
+        }
+        else {
+            /* no signer */
+            WOLFSSL_MSG("No CA signer to verify with");
+            return ASN_NO_SIGNER_E;
+        }
+    }
+
+#if defined(WOLFSSL_NO_TRUSTED_CERTS_VERIFY) && !defined(NO_SKID)
+exit_pcr:
+#endif
+
+    if (cert->badDate != 0) {
+        if (verify != VERIFY_SKIP_DATE) {
+            return cert->badDate;
+        }
+        WOLFSSL_MSG("Date error: Verify option is skipping");
+    }
+
+    if (cert->criticalExt != 0)
+        return cert->criticalExt;
+
+    return ret;
+}
+
+/* Create and init an new signer */
+Signer* MakeSigner(void* heap)
+{
+    Signer* signer = (Signer*) XMALLOC(sizeof(Signer), heap,
+                                       DYNAMIC_TYPE_SIGNER);
+    if (signer) {
+        XMEMSET(signer, 0, sizeof(Signer));
+    }
+    (void)heap;
+
+    return signer;
+}
+
+
+/* Free an individual signer */
+void FreeSigner(Signer* signer, void* heap)
+{
+    XFREE(signer->name, heap, DYNAMIC_TYPE_SUBJECT_CN);
+    XFREE((void*)signer->publicKey, heap, DYNAMIC_TYPE_PUBLIC_KEY);
+#ifndef IGNORE_NAME_CONSTRAINTS
+    if (signer->permittedNames)
+        FreeNameSubtrees(signer->permittedNames, heap);
+    if (signer->excludedNames)
+        FreeNameSubtrees(signer->excludedNames, heap);
+#endif
+#ifdef WOLFSSL_SIGNER_DER_CERT
+    FreeDer(&signer->derCert);
+#endif
+    XFREE(signer, heap, DYNAMIC_TYPE_SIGNER);
+
+    (void)heap;
+}
+
+
+/* Free the whole singer table with number of rows */
+void FreeSignerTable(Signer** table, int rows, void* heap)
+{
+    int i;
+
+    for (i = 0; i < rows; i++) {
+        Signer* signer = table[i];
+        while (signer) {
+            Signer* next = signer->next;
+            FreeSigner(signer, heap);
+            signer = next;
+        }
+        table[i] = NULL;
+    }
+}
+
+#ifdef WOLFSSL_TRUST_PEER_CERT
+/* Free an individual trusted peer cert */
+void FreeTrustedPeer(TrustedPeerCert* tp, void* heap)
+{
+    if (tp == NULL) {
+        return;
+    }
+
+    if (tp->name) {
+        XFREE(tp->name, heap, DYNAMIC_TYPE_SUBJECT_CN);
+    }
+
+    if (tp->sig) {
+        XFREE(tp->sig, heap, DYNAMIC_TYPE_SIGNATURE);
+    }
+#ifndef IGNORE_NAME_CONSTRAINTS
+    if (tp->permittedNames)
+        FreeNameSubtrees(tp->permittedNames, heap);
+    if (tp->excludedNames)
+        FreeNameSubtrees(tp->excludedNames, heap);
+#endif
+    XFREE(tp, heap, DYNAMIC_TYPE_CERT);
+
+    (void)heap;
+}
+
+/* Free the whole Trusted Peer linked list */
+void FreeTrustedPeerTable(TrustedPeerCert** table, int rows, void* heap)
+{
+    int i;
+
+    for (i = 0; i < rows; i++) {
+        TrustedPeerCert* tp = table[i];
+        while (tp) {
+            TrustedPeerCert* next = tp->next;
+            FreeTrustedPeer(tp, heap);
+            tp = next;
+        }
+        table[i] = NULL;
+    }
+}
+#endif /* WOLFSSL_TRUST_PEER_CERT */
+
+int SetMyVersion(word32 version, byte* output, int header)
+{
+    int i = 0;
+
+    if (output == NULL)
+        return BAD_FUNC_ARG;
+
+    if (header) {
+        output[i++] = ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED;
+        output[i++] = 3;
+    }
+    output[i++] = ASN_INTEGER;
+    output[i++] = 0x01;
+    output[i++] = (byte)version;
+
+    return i;
+}
+
+int SetSerialNumber(const byte* sn, word32 snSz, byte* output,
+    word32 outputSz, int maxSnSz)
+{
+    int i;
+    int snSzInt = (int)snSz;
+
+    if (sn == NULL || output == NULL || snSzInt < 0)
+        return BAD_FUNC_ARG;
+
+    /* remove leading zeros */
+    while (snSzInt > 0 && sn[0] == 0) {
+        snSzInt--;
+        sn++;
+    }
+    /* RFC 5280 - 4.1.2.2:
+     *   Serial numbers must be a positive value (and not zero) */
+    if (snSzInt == 0)
+        return BAD_FUNC_ARG;
+
+    if (sn[0] & 0x80)
+        maxSnSz--;
+    /* truncate if input is too long */
+    if (snSzInt > maxSnSz)
+        snSzInt = maxSnSz;
+
+    i = SetASNInt(snSzInt, sn[0], NULL);
+    /* truncate if input is too long */
+    if (snSzInt > (int)outputSz - i)
+        snSzInt = (int)outputSz - i;
+    /* sanity check number of bytes to copy */
+    if (snSzInt <= 0) {
+        return BUFFER_E;
+    }
+
+    /* write out ASN.1 Integer */
+    (void)SetASNInt(snSzInt, sn[0], output);
+    XMEMCPY(output + i, sn, snSzInt);
+
+    /* compute final length */
+    i += snSzInt;
+
+    return i;
+}
+
+#endif /* !NO_CERTS */
+
+int GetSerialNumber(const byte* input, word32* inOutIdx,
+    byte* serial, int* serialSz, word32 maxIdx)
+{
+    int result = 0;
+    int ret;
+
+    WOLFSSL_ENTER("GetSerialNumber");
+
+    if (serial == NULL || input == NULL || serialSz == NULL) {
+        return BAD_FUNC_ARG;
+    }
+
+    /* First byte is ASN type */
+    if ((*inOutIdx+1) > maxIdx) {
+        WOLFSSL_MSG("Bad idx first");
+        return BUFFER_E;
+    }
+
+    ret = GetASNInt(input, inOutIdx, serialSz, maxIdx);
+    if (ret != 0)
+        return ret;
+
+    if (*serialSz > EXTERNAL_SERIAL_SIZE) {
+        WOLFSSL_MSG("Serial size bad");
+        return ASN_PARSE_E;
+    }
+
+    /* return serial */
+    XMEMCPY(serial, &input[*inOutIdx], *serialSz);
+    *inOutIdx += *serialSz;
+
+    return result;
+}
+
+#ifndef NO_CERTS
+
+int AllocDer(DerBuffer** pDer, word32 length, int type, void* heap)
+{
+    int ret = BAD_FUNC_ARG;
+    if (pDer) {
+        int dynType = 0;
+        DerBuffer* der;
+
+        /* Determine dynamic type */
+        switch (type) {
+            case CA_TYPE:   dynType = DYNAMIC_TYPE_CA;   break;
+            case CERT_TYPE: dynType = DYNAMIC_TYPE_CERT; break;
+            case CRL_TYPE:  dynType = DYNAMIC_TYPE_CRL;  break;
+            case DSA_TYPE:  dynType = DYNAMIC_TYPE_DSA;  break;
+            case ECC_TYPE:  dynType = DYNAMIC_TYPE_ECC;  break;
+            case RSA_TYPE:  dynType = DYNAMIC_TYPE_RSA;  break;
+            default:        dynType = DYNAMIC_TYPE_KEY;  break;
+        }
+
+        /* Setup new buffer */
+        *pDer = (DerBuffer*)XMALLOC(sizeof(DerBuffer) + length, heap, dynType);
+        if (*pDer == NULL) {
+            return MEMORY_E;
+        }
+        XMEMSET(*pDer, 0, sizeof(DerBuffer) + length);
+
+        der = *pDer;
+        der->type = type;
+        der->dynType = dynType; /* Cache this for FreeDer */
+        der->heap = heap;
+        der->buffer = (byte*)der + sizeof(DerBuffer);
+        der->length = length;
+        ret = 0; /* Success */
+    }
+    return ret;
+}
+
+void FreeDer(DerBuffer** pDer)
+{
+    if (pDer && *pDer)
+    {
+        DerBuffer* der = (DerBuffer*)*pDer;
+
+        /* ForceZero private keys */
+        if (der->type == PRIVATEKEY_TYPE) {
+            ForceZero(der->buffer, der->length);
+        }
+        der->buffer = NULL;
+        der->length = 0;
+        XFREE(der, der->heap, der->dynType);
+
+        *pDer = NULL;
+    }
+}
+
+int wc_AllocDer(DerBuffer** pDer, word32 length, int type, void* heap)
+{
+    return AllocDer(pDer, length, type, heap);
+}
+void wc_FreeDer(DerBuffer** pDer)
+{
+    FreeDer(pDer);
+}
+
+
+#if defined(WOLFSSL_PEM_TO_DER) || defined(WOLFSSL_DER_TO_PEM)
+
+/* Max X509 header length indicates the max length + 2 ('\n', '\0') */
+#define MAX_X509_HEADER_SZ  (37 + 2)
+
+wcchar BEGIN_CERT           = "-----BEGIN CERTIFICATE-----";
+wcchar END_CERT             = "-----END CERTIFICATE-----";
+#ifdef WOLFSSL_CERT_REQ
+    wcchar BEGIN_CERT_REQ   = "-----BEGIN CERTIFICATE REQUEST-----";
+    wcchar END_CERT_REQ     = "-----END CERTIFICATE REQUEST-----";
+#endif
+#ifndef NO_DH
+    wcchar BEGIN_DH_PARAM   = "-----BEGIN DH PARAMETERS-----";
+    wcchar END_DH_PARAM     = "-----END DH PARAMETERS-----";
+#endif
+#ifndef NO_DSA
+    wcchar BEGIN_DSA_PARAM  = "-----BEGIN DSA PARAMETERS-----";
+    wcchar END_DSA_PARAM    = "-----END DSA PARAMETERS-----";
+#endif
+wcchar BEGIN_X509_CRL       = "-----BEGIN X509 CRL-----";
+wcchar END_X509_CRL         = "-----END X509 CRL-----";
+wcchar BEGIN_RSA_PRIV       = "-----BEGIN RSA PRIVATE KEY-----";
+wcchar END_RSA_PRIV         = "-----END RSA PRIVATE KEY-----";
+wcchar BEGIN_PRIV_KEY       = "-----BEGIN PRIVATE KEY-----";
+wcchar END_PRIV_KEY         = "-----END PRIVATE KEY-----";
+wcchar BEGIN_ENC_PRIV_KEY   = "-----BEGIN ENCRYPTED PRIVATE KEY-----";
+wcchar END_ENC_PRIV_KEY     = "-----END ENCRYPTED PRIVATE KEY-----";
+#ifdef HAVE_ECC
+    wcchar BEGIN_EC_PRIV    = "-----BEGIN EC PRIVATE KEY-----";
+    wcchar END_EC_PRIV      = "-----END EC PRIVATE KEY-----";
+#endif
+#if defined(HAVE_ECC) || defined(HAVE_ED25519) || defined(HAVE_ED448) || \
+                                                                !defined(NO_DSA)
+    wcchar BEGIN_DSA_PRIV   = "-----BEGIN DSA PRIVATE KEY-----";
+    wcchar END_DSA_PRIV     = "-----END DSA PRIVATE KEY-----";
+#endif
+#ifdef OPENSSL_EXTRA
+    const char BEGIN_PRIV_KEY_PREFIX[] = "-----BEGIN";
+    const char PRIV_KEY_SUFFIX[] = "PRIVATE KEY-----";
+    const char END_PRIV_KEY_PREFIX[]   = "-----END";
+#endif
+wcchar BEGIN_PUB_KEY        = "-----BEGIN PUBLIC KEY-----";
+wcchar END_PUB_KEY          = "-----END PUBLIC KEY-----";
+#if defined(HAVE_ED25519) || defined(HAVE_ED448)
+    wcchar BEGIN_EDDSA_PRIV = "-----BEGIN EDDSA PRIVATE KEY-----";
+    wcchar END_EDDSA_PRIV   = "-----END EDDSA PRIVATE KEY-----";
+#endif
+#ifdef HAVE_CRL
+    const char *const BEGIN_CRL = "-----BEGIN X509 CRL-----";
+    wcchar END_CRL   = "-----END X509 CRL-----";
+#endif
+
+
+static WC_INLINE char* SkipEndOfLineChars(char* line, const char* endOfLine)
+{
+    /* eat end of line characters */
+    while (line < endOfLine &&
+              (line[0] == '\r' || line[0] == '\n')) {
+        line++;
+    }
+    return line;
+}
+
+int wc_PemGetHeaderFooter(int type, const char** header, const char** footer)
+{
+    int ret = BAD_FUNC_ARG;
+
+    switch (type) {
+        case CA_TYPE:       /* same as below */
+        case TRUSTED_PEER_TYPE:
+        case CERT_TYPE:
+            if (header) *header = BEGIN_CERT;
+            if (footer) *footer = END_CERT;
+            ret = 0;
+            break;
+
+        case CRL_TYPE:
+            if (header) *header = BEGIN_X509_CRL;
+            if (footer) *footer = END_X509_CRL;
+            ret = 0;
+            break;
+    #ifndef NO_DH
+        case DH_PARAM_TYPE:
+            if (header) *header = BEGIN_DH_PARAM;
+            if (footer) *footer = END_DH_PARAM;
+            ret = 0;
+            break;
+    #endif
+    #ifndef NO_DSA
+        case DSA_PARAM_TYPE:
+            if (header) *header = BEGIN_DSA_PARAM;
+            if (footer) *footer = END_DSA_PARAM;
+            ret = 0;
+            break;
+    #endif
+    #ifdef WOLFSSL_CERT_REQ
+        case CERTREQ_TYPE:
+            if (header) *header = BEGIN_CERT_REQ;
+            if (footer) *footer = END_CERT_REQ;
+            ret = 0;
+            break;
+    #endif
+    #ifndef NO_DSA
+        case DSA_TYPE:
+        case DSA_PRIVATEKEY_TYPE:
+            if (header) *header = BEGIN_DSA_PRIV;
+            if (footer) *footer = END_DSA_PRIV;
+            ret = 0;
+            break;
+    #endif
+    #ifdef HAVE_ECC
+        case ECC_TYPE:
+        case ECC_PRIVATEKEY_TYPE:
+            if (header) *header = BEGIN_EC_PRIV;
+            if (footer) *footer = END_EC_PRIV;
+            ret = 0;
+            break;
+    #endif
+        case RSA_TYPE:
+        case PRIVATEKEY_TYPE:
+            if (header) *header = BEGIN_RSA_PRIV;
+            if (footer) *footer = END_RSA_PRIV;
+            ret = 0;
+            break;
+    #ifdef HAVE_ED25519
+        case ED25519_TYPE:
+    #endif
+    #ifdef HAVE_ED448
+        case ED448_TYPE:
+    #endif
+    #if defined(HAVE_ED25519) || defined(HAVE_ED448)
+        case EDDSA_PRIVATEKEY_TYPE:
+            if (header) *header = BEGIN_EDDSA_PRIV;
+            if (footer) *footer = END_EDDSA_PRIV;
+            ret = 0;
+            break;
+    #endif
+        case PUBLICKEY_TYPE:
+        case ECC_PUBLICKEY_TYPE:
+            if (header) *header = BEGIN_PUB_KEY;
+            if (footer) *footer = END_PUB_KEY;
+            ret = 0;
+            break;
+    #if !defined(NO_DH) && (defined(WOLFSSL_QT) || defined(OPENSSL_ALL))
+        case DH_PRIVATEKEY_TYPE:
+    #endif
+        case PKCS8_PRIVATEKEY_TYPE:
+            if (header) *header = BEGIN_PRIV_KEY;
+            if (footer) *footer = END_PRIV_KEY;
+            ret = 0;
+            break;
+        case PKCS8_ENC_PRIVATEKEY_TYPE:
+            if (header) *header = BEGIN_ENC_PRIV_KEY;
+            if (footer) *footer = END_ENC_PRIV_KEY;
+            ret = 0;
+            break;
+        default:
+            break;
+    }
+    return ret;
+}
+
+#ifdef WOLFSSL_ENCRYPTED_KEYS
+
+static wcchar kProcTypeHeader = "Proc-Type";
+static wcchar kDecInfoHeader = "DEK-Info";
+
+#ifdef WOLFSSL_PEM_TO_DER
+#ifndef NO_DES3
+    static wcchar kEncTypeDes = "DES-CBC";
+    static wcchar kEncTypeDes3 = "DES-EDE3-CBC";
+#endif
+#if !defined(NO_AES) && defined(HAVE_AES_CBC) && defined(WOLFSSL_AES_128)
+    static wcchar kEncTypeAesCbc128 = "AES-128-CBC";
+#endif
+#if !defined(NO_AES) && defined(HAVE_AES_CBC) && defined(WOLFSSL_AES_192)
+    static wcchar kEncTypeAesCbc192 = "AES-192-CBC";
+#endif
+#if !defined(NO_AES) && defined(HAVE_AES_CBC) && defined(WOLFSSL_AES_256)
+    static wcchar kEncTypeAesCbc256 = "AES-256-CBC";
+#endif
+
+int wc_EncryptedInfoGet(EncryptedInfo* info, const char* cipherInfo)
+{
+    int ret = 0;
+
+    if (info == NULL || cipherInfo == NULL)
+        return BAD_FUNC_ARG;
+
+    /* determine cipher information */
+#ifndef NO_DES3
+    if (XSTRNCMP(cipherInfo, kEncTypeDes, XSTRLEN(kEncTypeDes)) == 0) {
+        info->cipherType = WC_CIPHER_DES;
+        info->keySz = DES_KEY_SIZE;
+        if (info->ivSz == 0) info->ivSz  = DES_IV_SIZE;
+    }
+    else if (XSTRNCMP(cipherInfo, kEncTypeDes3, XSTRLEN(kEncTypeDes3)) == 0) {
+        info->cipherType = WC_CIPHER_DES3;
+        info->keySz = DES3_KEY_SIZE;
+        if (info->ivSz == 0) info->ivSz  = DES_IV_SIZE;
+    }
+    else
+#endif /* !NO_DES3 */
+#if !defined(NO_AES) && defined(HAVE_AES_CBC) && defined(WOLFSSL_AES_128)
+    if (XSTRNCMP(cipherInfo, kEncTypeAesCbc128, XSTRLEN(kEncTypeAesCbc128)) == 0) {
+        info->cipherType = WC_CIPHER_AES_CBC;
+        info->keySz = AES_128_KEY_SIZE;
+        if (info->ivSz == 0) info->ivSz  = AES_IV_SIZE;
+    }
+    else
+#endif
+#if !defined(NO_AES) && defined(HAVE_AES_CBC) && defined(WOLFSSL_AES_192)
+    if (XSTRNCMP(cipherInfo, kEncTypeAesCbc192, XSTRLEN(kEncTypeAesCbc192)) == 0) {
+        info->cipherType = WC_CIPHER_AES_CBC;
+        info->keySz = AES_192_KEY_SIZE;
+        if (info->ivSz == 0) info->ivSz  = AES_IV_SIZE;
+    }
+    else
+#endif
+#if !defined(NO_AES) && defined(HAVE_AES_CBC) && defined(WOLFSSL_AES_256)
+    if (XSTRNCMP(cipherInfo, kEncTypeAesCbc256, XSTRLEN(kEncTypeAesCbc256)) == 0) {
+        info->cipherType = WC_CIPHER_AES_CBC;
+        info->keySz = AES_256_KEY_SIZE;
+        if (info->ivSz == 0) info->ivSz  = AES_IV_SIZE;
+    }
+    else
+#endif
+    {
+        ret = NOT_COMPILED_IN;
+    }
+    return ret;
+}
+
+int wc_EncryptedInfoParse(EncryptedInfo* info, char** pBuffer, size_t bufSz)
+{
+    int err = 0;
+    char*  bufferStart;
+    char*  bufferEnd;
+    char*  line;
+    word32 lineSz;
+    char*  finish;
+    word32 finishSz;
+    char*  start = NULL;
+    word32 startSz;
+    char*  newline = NULL;
+
+    if (info == NULL || pBuffer == NULL || bufSz == 0)
+        return BAD_FUNC_ARG;
+
+    bufferStart = *pBuffer;
+    bufferEnd = bufferStart + bufSz;
+
+    /* find encrypted info marker */
+    line = XSTRNSTR(bufferStart, kProcTypeHeader,
+                    min((word32)bufSz, PEM_LINE_LEN));
+    if (line != NULL) {
+        if (line >= bufferEnd) {
+            return BUFFER_E;
+        }
+
+        lineSz = (word32)(bufferEnd - line);
+
+        /* find DEC-Info marker */
+        start = XSTRNSTR(line, kDecInfoHeader, min(lineSz, PEM_LINE_LEN));
+
+        if (start == NULL)
+            return BUFFER_E;
+
+        /* skip dec-info and ": " */
+        start += XSTRLEN(kDecInfoHeader);
+        if (start >= bufferEnd)
+            return BUFFER_E;
+
+        if (start[0] == ':') {
+            start++;
+            if (start >= bufferEnd)
+                return BUFFER_E;
+        }
+        if (start[0] == ' ')
+            start++;
+
+        startSz = (word32)(bufferEnd - start);
+        finish = XSTRNSTR(start, ",", min(startSz, PEM_LINE_LEN));
+
+        if ((start != NULL) && (finish != NULL) && (start < finish)) {
+            if (finish >= bufferEnd) {
+                return BUFFER_E;
+            }
+
+            finishSz = (word32)(bufferEnd - finish);
+            newline = XSTRNSTR(finish, "\r", min(finishSz, PEM_LINE_LEN));
+
+            /* get cipher name */
+            if (NAME_SZ < (finish - start)) /* buffer size of info->name */
+                return BUFFER_E;
+            if (XMEMCPY(info->name, start, finish - start) == NULL)
+                return BUFFER_E;
+            info->name[finish - start] = '\0'; /* null term */
+
+            /* populate info */
+            err = wc_EncryptedInfoGet(info, info->name);
+            if (err != 0)
+                return err;
+
+            /* get IV */
+            if (finishSz < info->ivSz + 1)
+                return BUFFER_E;
+
+            if (newline == NULL) {
+                newline = XSTRNSTR(finish, "\n", min(finishSz,
+                                                     PEM_LINE_LEN));
+            }
+            if ((newline != NULL) && (newline > finish)) {
+                finish++;
+                info->ivSz = (word32)(newline - finish);
+                if (info->ivSz > IV_SZ)
+                    return BUFFER_E;
+                if (XMEMCPY(info->iv, finish, info->ivSz) == NULL)
+                    return BUFFER_E;
+                info->set = 1;
+            }
+            else
+                return BUFFER_E;
+        }
+        else
+            return BUFFER_E;
+
+        /* eat end of line characters */
+        newline = SkipEndOfLineChars(newline, bufferEnd);
+
+        /* return new headerEnd */
+
+        *pBuffer = newline;
+    }
+
+    return err;
+}
+#endif /* WOLFSSL_PEM_TO_DER */
+
+#ifdef WOLFSSL_DER_TO_PEM
+static int wc_EncryptedInfoAppend(char* dest, int destSz, char* cipherInfo)
+{
+    if (cipherInfo != NULL) {
+        int cipherInfoStrLen = (int)XSTRLEN((char*)cipherInfo);
+
+        if (cipherInfoStrLen > HEADER_ENCRYPTED_KEY_SIZE - (9+14+10+3))
+            cipherInfoStrLen = HEADER_ENCRYPTED_KEY_SIZE - (9+14+10+3);
+
+        if (destSz - (int)XSTRLEN(dest) >= cipherInfoStrLen + (9+14+8+2+2+1)) {
+            /* strncat's src length needs to include the NULL */
+            XSTRNCAT(dest, kProcTypeHeader, 10);
+            XSTRNCAT(dest, ": 4,ENCRYPTED\n", 15);
+            XSTRNCAT(dest, kDecInfoHeader, 9);
+            XSTRNCAT(dest, ": ", 3);
+            XSTRNCAT(dest, cipherInfo, destSz - (int)XSTRLEN(dest) - 1);
+            XSTRNCAT(dest, "\n\n", 4);
+        }
+    }
+    return 0;
+}
+#endif /* WOLFSSL_DER_TO_PEM */
+#endif /* WOLFSSL_ENCRYPTED_KEYS */
+
+#ifdef WOLFSSL_DER_TO_PEM
+
+/* Used for compatibility API */
+int wc_DerToPem(const byte* der, word32 derSz,
+                byte* output, word32 outSz, int type)
+{
+    return wc_DerToPemEx(der, derSz, output, outSz, NULL, type);
+}
+
+/* convert der buffer to pem into output, can't do inplace, der and output
+   need to be different */
+int wc_DerToPemEx(const byte* der, word32 derSz, byte* output, word32 outSz,
+             byte *cipher_info, int type)
+{
+    const char* headerStr = NULL;
+    const char* footerStr = NULL;
+#ifdef WOLFSSL_SMALL_STACK
+    char* header = NULL;
+    char* footer = NULL;
+#else
+    char header[MAX_X509_HEADER_SZ + HEADER_ENCRYPTED_KEY_SIZE];
+    char footer[MAX_X509_HEADER_SZ];
+#endif
+    int headerLen = MAX_X509_HEADER_SZ + HEADER_ENCRYPTED_KEY_SIZE;
+    int footerLen = MAX_X509_HEADER_SZ;
+    int i;
+    int err;
+    int outLen;   /* return length or error */
+
+    (void)cipher_info;
+
+    if (der == output)      /* no in place conversion */
+        return BAD_FUNC_ARG;
+
+    err = wc_PemGetHeaderFooter(type, &headerStr, &footerStr);
+    if (err != 0)
+        return err;
+
+#ifdef WOLFSSL_SMALL_STACK
+    header = (char*)XMALLOC(headerLen, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    if (header == NULL)
+        return MEMORY_E;
+
+    footer = (char*)XMALLOC(footerLen, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    if (footer == NULL) {
+        XFREE(header, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+        return MEMORY_E;
+    }
+#endif
+
+    /* build header and footer based on type */
+    XSTRNCPY(header, headerStr, headerLen - 1);
+    header[headerLen - 2] = 0;
+    XSTRNCPY(footer, footerStr, footerLen - 1);
+    footer[footerLen - 2] = 0;
+
+    /* add new line to end */
+    XSTRNCAT(header, "\n", 2);
+    XSTRNCAT(footer, "\n", 2);
+
+#ifdef WOLFSSL_ENCRYPTED_KEYS
+    err = wc_EncryptedInfoAppend(header, headerLen, (char*)cipher_info);
+    if (err != 0) {
+    #ifdef WOLFSSL_SMALL_STACK
+        XFREE(header, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+        XFREE(footer, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    #endif
+        return err;
+    }
+#endif
+
+    headerLen = (int)XSTRLEN(header);
+    footerLen = (int)XSTRLEN(footer);
+
+    /* if null output and 0 size passed in then return size needed */
+    if (!output && outSz == 0) {
+#ifdef WOLFSSL_SMALL_STACK
+        XFREE(header, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+        XFREE(footer, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+#endif
+        outLen = 0;
+        if ((err = Base64_Encode(der, derSz, NULL, (word32*)&outLen))
+                != LENGTH_ONLY_E) {
+            return err;
+        }
+        return headerLen + footerLen + outLen;
+    }
+
+    if (!der || !output) {
+#ifdef WOLFSSL_SMALL_STACK
+        XFREE(header, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+        XFREE(footer, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+#endif
+        return BAD_FUNC_ARG;
+    }
+
+    /* don't even try if outSz too short */
+    if (outSz < headerLen + footerLen + derSz) {
+#ifdef WOLFSSL_SMALL_STACK
+        XFREE(header, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+        XFREE(footer, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+#endif
+        return BAD_FUNC_ARG;
+    }
+
+    /* header */
+    XMEMCPY(output, header, headerLen);
+    i = headerLen;
+
+#ifdef WOLFSSL_SMALL_STACK
+    XFREE(header, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+#endif
+
+    /* body */
+    outLen = outSz - (headerLen + footerLen);  /* input to Base64_Encode */
+    if ( (err = Base64_Encode(der, derSz, output + i, (word32*)&outLen)) < 0) {
+#ifdef WOLFSSL_SMALL_STACK
+        XFREE(footer, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+#endif
+        return err;
+    }
+    i += outLen;
+
+    /* footer */
+    if ( (i + footerLen) > (int)outSz) {
+#ifdef WOLFSSL_SMALL_STACK
+        XFREE(footer, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+#endif
+        return BAD_FUNC_ARG;
+    }
+    XMEMCPY(output + i, footer, footerLen);
+
+#ifdef WOLFSSL_SMALL_STACK
+    XFREE(footer, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+#endif
+
+    return outLen + headerLen + footerLen;
+}
+
+#endif /* WOLFSSL_DER_TO_PEM */
+
+#ifdef WOLFSSL_PEM_TO_DER
+
+/* Remove PEM header/footer, convert to ASN1, store any encrypted data
+   info->consumed tracks of PEM bytes consumed in case multiple parts */
+int PemToDer(const unsigned char* buff, long longSz, int type,
+              DerBuffer** pDer, void* heap, EncryptedInfo* info, int* keyFormat)
+{
+    const char* header      = NULL;
+    const char* footer      = NULL;
+    char*       headerEnd;
+    char*       footerEnd;
+    char*       consumedEnd;
+    char*       bufferEnd   = (char*)(buff + longSz);
+    long        neededSz;
+    int         ret         = 0;
+    int         sz          = (int)longSz;
+    int         encrypted_key = 0;
+    DerBuffer*  der;
+#if defined(HAVE_PKCS8) || defined(WOLFSSL_ENCRYPTED_KEYS)
+    word32      algId = 0;
+    #if defined(WOLFSSL_ENCRYPTED_KEYS) && !defined(NO_DES3) && !defined(NO_WOLFSSL_SKIP_TRAILING_PAD)
+        int     padVal = 0;
+    #endif
+#endif
+#ifdef OPENSSL_EXTRA
+    char        beginBuf[PEM_LINE_LEN + 1]; /* add 1 for null terminator */
+    char        endBuf[PEM_LINE_LEN + 1];   /* add 1 for null terminator */
+#endif
+
+    WOLFSSL_ENTER("PemToDer");
+
+    /* get PEM header and footer based on type */
+    ret = wc_PemGetHeaderFooter(type, &header, &footer);
+    if (ret != 0)
+        return ret;
+
+    /* map header if not found for type */
+    for (;;) {
+        headerEnd = XSTRNSTR((char*)buff, header, sz);
+
+        if (headerEnd) {
+            break;
+        } else
+        if (type == PRIVATEKEY_TYPE) {
+            if (header == BEGIN_RSA_PRIV) {
+                header =  BEGIN_PRIV_KEY;       footer = END_PRIV_KEY;
+            } else
+            if (header == BEGIN_PRIV_KEY) {
+                header =  BEGIN_ENC_PRIV_KEY;   footer = END_ENC_PRIV_KEY;
+            } else
+    #ifdef HAVE_ECC
+            if (header == BEGIN_ENC_PRIV_KEY) {
+                header =  BEGIN_EC_PRIV;        footer = END_EC_PRIV;
+            } else
+            if (header == BEGIN_EC_PRIV) {
+                header =  BEGIN_DSA_PRIV;       footer = END_DSA_PRIV;
+            } else
+    #endif
+    #if defined(HAVE_ED25519) || defined(HAVE_ED448)
+        #ifdef HAVE_ECC
+            if (header == BEGIN_DSA_PRIV)
+        #else
+            if (header == BEGIN_ENC_PRIV_KEY)
+        #endif
+            {
+                header =  BEGIN_EDDSA_PRIV;     footer = END_EDDSA_PRIV;
+            } else
+    #endif
+            {
+                break;
+            }
+        } else
+#ifdef HAVE_CRL
+        if ((type == CRL_TYPE) && (header != BEGIN_CRL)) {
+            header =  BEGIN_CRL;                footer = END_CRL;
+        } else
+#endif
+        {
+            break;
+        }
+    }
+
+    if (!headerEnd) {
+#ifdef OPENSSL_EXTRA
+        char* beginEnd;
+        int endLen;
+        /* see if there is a -----BEGIN * PRIVATE KEY----- header */
+        headerEnd = XSTRNSTR((char*)buff, PRIV_KEY_SUFFIX, sz);
+        if (headerEnd) {
+            beginEnd = headerEnd + XSTR_SIZEOF(PRIV_KEY_SUFFIX);
+            /* back up to BEGIN_PRIV_KEY_PREFIX */
+            headerEnd -= XSTR_SIZEOF(BEGIN_PRIV_KEY_PREFIX);
+            while (headerEnd > (char*)buff &&
+                    XSTRNCMP(headerEnd, BEGIN_PRIV_KEY_PREFIX,
+                            XSTR_SIZEOF(BEGIN_PRIV_KEY_PREFIX)) != 0) {
+                headerEnd--;
+            }
+            if (headerEnd <= (char*)buff ||
+                    XSTRNCMP(headerEnd, BEGIN_PRIV_KEY_PREFIX,
+                    XSTR_SIZEOF(BEGIN_PRIV_KEY_PREFIX)) != 0 ||
+                    beginEnd - headerEnd > PEM_LINE_LEN) {
+                WOLFSSL_MSG("Couldn't find PEM header");
+                return ASN_NO_PEM_HEADER;
+            }
+            /* headerEnd now points to beginning of header */
+            XMEMCPY(beginBuf, headerEnd, beginEnd - headerEnd);
+            beginBuf[beginEnd - headerEnd] = '\0';
+            /* look for matching footer */
+            footer = XSTRNSTR(beginEnd,
+                            beginBuf + XSTR_SIZEOF(BEGIN_PRIV_KEY_PREFIX),
+                            (unsigned int)((char*)buff + sz - beginEnd));
+            if (!footer) {
+                WOLFSSL_MSG("Couldn't find PEM footer");
+                return ASN_NO_PEM_HEADER;
+            }
+            footer -= XSTR_SIZEOF(END_PRIV_KEY_PREFIX);
+            endLen = (unsigned int)(beginEnd - headerEnd -
+                        (XSTR_SIZEOF(BEGIN_PRIV_KEY_PREFIX) -
+                                XSTR_SIZEOF(END_PRIV_KEY_PREFIX)));
+            XMEMCPY(endBuf, footer, endLen);
+            endBuf[endLen] = '\0';
+
+            header = beginBuf;
+            footer = endBuf;
+            headerEnd = beginEnd;
+        } else {
+            WOLFSSL_MSG("Couldn't find PEM header");
+            return ASN_NO_PEM_HEADER;
+        }
+#else
+        WOLFSSL_MSG("Couldn't find PEM header");
+        return ASN_NO_PEM_HEADER;
+#endif
+    } else {
+        headerEnd += XSTRLEN(header);
+    }
+
+    /* eat end of line characters */
+    headerEnd = SkipEndOfLineChars(headerEnd, bufferEnd);
+
+    if (type == PRIVATEKEY_TYPE) {
+        /* keyFormat is Key_Sum enum */
+        if (keyFormat) {
+        #ifdef HAVE_ECC
+            if (header == BEGIN_EC_PRIV)
+                *keyFormat = ECDSAk;
+        #endif
+        #if !defined(NO_DSA)
+            if (header == BEGIN_DSA_PRIV)
+                *keyFormat = DSAk;
+        #endif
+        }
+    }
+
+#ifdef WOLFSSL_ENCRYPTED_KEYS
+    if (info) {
+        ret = wc_EncryptedInfoParse(info, &headerEnd, bufferEnd - headerEnd);
+        if (ret < 0)
+            return ret;
+        if (info->set)
+            encrypted_key = 1;
+    }
+#endif /* WOLFSSL_ENCRYPTED_KEYS */
+
+    /* find footer */
+    footerEnd = XSTRNSTR(headerEnd, footer, (unsigned int)((char*)buff + sz - headerEnd));
+    if (!footerEnd) {
+        if (info)
+            info->consumed = longSz; /* No more certs if no footer */
+        return BUFFER_E;
+    }
+
+    consumedEnd = footerEnd + XSTRLEN(footer);
+
+    if (consumedEnd < bufferEnd) { /* handle no end of line on last line */
+        /* eat end of line characters */
+        consumedEnd = SkipEndOfLineChars(consumedEnd, bufferEnd);
+        /* skip possible null term */
+        if (consumedEnd < bufferEnd && consumedEnd[0] == '\0')
+            consumedEnd++;
+    }
+
+    if (info)
+        info->consumed = (long)(consumedEnd - (char*)buff);
+
+    /* set up der buffer */
+    neededSz = (long)(footerEnd - headerEnd);
+    if (neededSz > sz || neededSz <= 0)
+        return BUFFER_E;
+
+    ret = AllocDer(pDer, (word32)neededSz, type, heap);
+    if (ret < 0) {
+        return ret;
+    }
+    der = *pDer;
+
+    if (Base64_Decode((byte*)headerEnd, (word32)neededSz,
+                      der->buffer, &der->length) < 0)
+        return BUFFER_E;
+
+    if ((header == BEGIN_PRIV_KEY
+#ifdef OPENSSL_EXTRA
+         || header == beginBuf
+#endif
+#ifdef HAVE_ECC
+         || header == BEGIN_EC_PRIV
+#endif
+        ) && !encrypted_key)
+    {
+    #ifdef HAVE_PKCS8
+        /* pkcs8 key, convert and adjust length */
+        if ((ret = ToTraditional_ex(der->buffer, der->length, &algId)) > 0) {
+            der->length = ret;
+            if (keyFormat) {
+                *keyFormat = algId;
+            }
+        }
+        else {
+            /* ignore failure here and assume key is not pkcs8 wrapped */
+        }
+    #endif
+
+        return 0;
+    }
+
+#ifdef WOLFSSL_ENCRYPTED_KEYS
+    if (encrypted_key || header == BEGIN_ENC_PRIV_KEY) {
+        int   passwordSz = NAME_SZ;
+    #ifdef WOLFSSL_SMALL_STACK
+        char* password = NULL;
+    #else
+        char  password[NAME_SZ];
+    #endif
+
+        if (!info || !info->passwd_cb) {
+            WOLFSSL_MSG("No password callback set");
+            return NO_PASSWORD;
+        }
+
+    #ifdef WOLFSSL_SMALL_STACK
+        password = (char*)XMALLOC(passwordSz, heap, DYNAMIC_TYPE_STRING);
+        if (password == NULL)
+            return MEMORY_E;
+    #endif
+
+        /* get password */
+        ret = info->passwd_cb(password, passwordSz, PEM_PASS_READ,
+            info->passwd_userdata);
+        if (ret >= 0) {
+            passwordSz = ret;
+
+            /* convert and adjust length */
+            if (header == BEGIN_ENC_PRIV_KEY) {
+            #ifndef NO_PWDBASED
+                ret = ToTraditionalEnc(der->buffer, der->length,
+                                       password, passwordSz, &algId);
+
+                if (ret >= 0) {
+                    der->length = ret;
+                    if (keyFormat) {
+                        *keyFormat = algId;
+                    }
+                    ret = 0;
+                }
+            #else
+                ret = NOT_COMPILED_IN;
+            #endif
+            }
+            /* decrypt the key */
+            else {
+                if (passwordSz == 0) {
+                    /* The key is encrypted but does not have a password */
+                    WOLFSSL_MSG("No password for encrypted key");
+                    ret = NO_PASSWORD;
+                }
+                else {
+                    ret = wc_BufferKeyDecrypt(info, der->buffer, der->length,
+                        (byte*)password, passwordSz, WC_MD5);
+
+#ifndef NO_WOLFSSL_SKIP_TRAILING_PAD
+                #ifndef NO_DES3
+                    if (info->cipherType == WC_CIPHER_DES3) {
+                        padVal = der->buffer[der->length-1];
+                        if (padVal <= DES_BLOCK_SIZE) {
+                            der->length -= padVal;
+                        }
+                    }
+                #endif /* !NO_DES3 */
+#endif /* !NO_WOLFSSL_SKIP_TRAILING_PAD */
+                }
+            }
+#ifdef OPENSSL_EXTRA
+            if (ret) {
+                PEMerr(0, PEM_R_BAD_DECRYPT);
+            }
+#endif
+            ForceZero(password, passwordSz);
+        }
+#ifdef OPENSSL_EXTRA
+        else {
+            PEMerr(0, PEM_R_BAD_PASSWORD_READ);
+        }
+#endif
+
+    #ifdef WOLFSSL_SMALL_STACK
+        XFREE(password, heap, DYNAMIC_TYPE_STRING);
+    #endif
+    }
+#endif /* WOLFSSL_ENCRYPTED_KEYS */
+
+    return ret;
+}
+
+int wc_PemToDer(const unsigned char* buff, long longSz, int type,
+              DerBuffer** pDer, void* heap, EncryptedInfo* info, int* eccKey)
+{
+    return PemToDer(buff, longSz, type, pDer, heap, info, eccKey);
+}
+
+
+/* our KeyPemToDer password callback, password in userData */
+static WC_INLINE int OurPasswordCb(char* passwd, int sz, int rw, void* userdata)
+{
+    (void)rw;
+
+    if (userdata == NULL)
+        return 0;
+
+    XSTRNCPY(passwd, (char*)userdata, sz);
+    return min((word32)sz, (word32)XSTRLEN((char*)userdata));
+}
+
+/* Return bytes written to buff or < 0 for error */
+int wc_KeyPemToDer(const unsigned char* pem, int pemSz,
+                        unsigned char* buff, int buffSz, const char* pass)
+{
+    int            eccKey = 0;
+    int            ret;
+    DerBuffer*     der = NULL;
+#ifdef WOLFSSL_SMALL_STACK
+    EncryptedInfo* info = NULL;
+#else
+    EncryptedInfo  info[1];
+#endif
+
+    WOLFSSL_ENTER("wc_KeyPemToDer");
+
+    if (pem == NULL || buff == NULL || buffSz <= 0) {
+        WOLFSSL_MSG("Bad pem der args");
+        return BAD_FUNC_ARG;
+    }
+
+#ifdef WOLFSSL_SMALL_STACK
+    info = (EncryptedInfo*)XMALLOC(sizeof(EncryptedInfo), NULL,
+                                   DYNAMIC_TYPE_ENCRYPTEDINFO);
+    if (info == NULL)
+        return MEMORY_E;
+#endif
+
+    XMEMSET(info, 0, sizeof(EncryptedInfo));
+    info->passwd_cb = OurPasswordCb;
+    info->passwd_userdata = (void*)pass;
+
+    ret = PemToDer(pem, pemSz, PRIVATEKEY_TYPE, &der, NULL, info, &eccKey);
+
+#ifdef WOLFSSL_SMALL_STACK
+    XFREE(info, NULL, DYNAMIC_TYPE_ENCRYPTEDINFO);
+#endif
+
+    if (ret < 0 || der == NULL) {
+        WOLFSSL_MSG("Bad Pem To Der");
+    }
+    else {
+        if (der->length <= (word32)buffSz) {
+            XMEMCPY(buff, der->buffer, der->length);
+            ret = der->length;
+        }
+        else {
+            WOLFSSL_MSG("Bad der length");
+            ret = BAD_FUNC_ARG;
+        }
+    }
+
+    FreeDer(&der);
+    return ret;
+}
+
+
+/* Return bytes written to buff or < 0 for error */
+int wc_CertPemToDer(const unsigned char* pem, int pemSz,
+                        unsigned char* buff, int buffSz, int type)
+{
+    int            eccKey = 0;
+    int            ret;
+    DerBuffer*     der = NULL;
+
+    WOLFSSL_ENTER("wc_CertPemToDer");
+
+    if (pem == NULL || buff == NULL || buffSz <= 0) {
+        WOLFSSL_MSG("Bad pem der args");
+        return BAD_FUNC_ARG;
+    }
+
+    if (type != CERT_TYPE && type != CA_TYPE && type != CERTREQ_TYPE) {
+        WOLFSSL_MSG("Bad cert type");
+        return BAD_FUNC_ARG;
+    }
+
+
+    ret = PemToDer(pem, pemSz, type, &der, NULL, NULL, &eccKey);
+    if (ret < 0 || der == NULL) {
+        WOLFSSL_MSG("Bad Pem To Der");
+    }
+    else {
+        if (der->length <= (word32)buffSz) {
+            XMEMCPY(buff, der->buffer, der->length);
+            ret = der->length;
+        }
+        else {
+            WOLFSSL_MSG("Bad der length");
+            ret = BAD_FUNC_ARG;
+        }
+    }
+
+    FreeDer(&der);
+    return ret;
+}
+
+#endif /* WOLFSSL_PEM_TO_DER */
+#endif /* WOLFSSL_PEM_TO_DER || WOLFSSL_DER_TO_PEM */
+
+
+#ifdef WOLFSSL_PEM_TO_DER
+#if defined(WOLFSSL_CERT_EXT) || defined(WOLFSSL_PUB_PEM_TO_DER)
+/* Return bytes written to buff or < 0 for error */
+int wc_PubKeyPemToDer(const unsigned char* pem, int pemSz,
+                           unsigned char* buff, int buffSz)
+{
+    int ret;
+    DerBuffer* der = NULL;
+
+    WOLFSSL_ENTER("wc_PubKeyPemToDer");
+
+    if (pem == NULL || buff == NULL || buffSz <= 0) {
+        WOLFSSL_MSG("Bad pem der args");
+        return BAD_FUNC_ARG;
+    }
+
+    ret = PemToDer(pem, pemSz, PUBLICKEY_TYPE, &der, NULL, NULL, NULL);
+    if (ret < 0 || der == NULL) {
+        WOLFSSL_MSG("Bad Pem To Der");
+    }
+    else {
+        if (der->length <= (word32)buffSz) {
+            XMEMCPY(buff, der->buffer, der->length);
+            ret = der->length;
+        }
+        else {
+            WOLFSSL_MSG("Bad der length");
+            ret = BAD_FUNC_ARG;
+        }
+    }
+
+    FreeDer(&der);
+    return ret;
+}
+#endif /* WOLFSSL_CERT_EXT || WOLFSSL_PUB_PEM_TO_DER */
+#endif /* WOLFSSL_PEM_TO_DER */
+
+#ifndef NO_FILESYSTEM
+
+#ifdef WOLFSSL_CERT_GEN
+/* load pem cert from file into der buffer, return der size or error */
+int wc_PemCertToDer(const char* fileName, unsigned char* derBuf, int derSz)
+{
+#ifdef WOLFSSL_SMALL_STACK
+    byte   staticBuffer[1]; /* force XMALLOC */
+#else
+    byte   staticBuffer[FILE_BUFFER_SIZE];
+#endif
+    byte*  fileBuf = staticBuffer;
+    int    dynamic = 0;
+    int    ret     = 0;
+    long   sz      = 0;
+    XFILE  file;
+    DerBuffer* converted = NULL;
+
+    WOLFSSL_ENTER("wc_PemCertToDer");
+
+    if (fileName == NULL) {
+        ret = BAD_FUNC_ARG;
+    }
+    else {
+        file = XFOPEN(fileName, "rb");
+        if (file == XBADFILE) {
+            ret = BUFFER_E;
+        }
+    }
+
+    if (ret == 0) {
+        if(XFSEEK(file, 0, XSEEK_END) != 0)
+            ret = BUFFER_E;
+        sz = XFTELL(file);
+        XREWIND(file);
+
+        if (sz <= 0) {
+            ret = BUFFER_E;
+        }
+        else if (sz > (long)sizeof(staticBuffer)) {
+        #ifdef WOLFSSL_STATIC_MEMORY
+            WOLFSSL_MSG("File was larger then static buffer");
+            return MEMORY_E;
+        #endif
+            fileBuf = (byte*)XMALLOC(sz, NULL, DYNAMIC_TYPE_FILE);
+            if (fileBuf == NULL)
+                ret = MEMORY_E;
+            else
+                dynamic = 1;
+        }
+
+        if (ret == 0) {
+            if ( (ret = (int)XFREAD(fileBuf, 1, sz, file)) != sz) {
+                ret = BUFFER_E;
+            }
+        #ifdef WOLFSSL_PEM_TO_DER
+            else {
+                ret = PemToDer(fileBuf, sz, CA_TYPE, &converted,  0, NULL,NULL);
+            }
+        #endif
+
+            if (ret == 0) {
+                if (converted->length < (word32)derSz) {
+                    XMEMCPY(derBuf, converted->buffer, converted->length);
+                    ret = converted->length;
+                }
+                else
+                    ret = BUFFER_E;
+            }
+
+            FreeDer(&converted);
+        }
+
+        XFCLOSE(file);
+        if (dynamic)
+            XFREE(fileBuf, NULL, DYNAMIC_TYPE_FILE);
+    }
+
+    return ret;
+}
+#endif /* WOLFSSL_CERT_GEN */
+
+#if defined(WOLFSSL_CERT_EXT) || defined(WOLFSSL_PUB_PEM_TO_DER)
+/* load pem public key from file into der buffer, return der size or error */
+int wc_PemPubKeyToDer(const char* fileName,
+                           unsigned char* derBuf, int derSz)
+{
+#ifdef WOLFSSL_SMALL_STACK
+    byte   staticBuffer[1]; /* force XMALLOC */
+#else
+    byte   staticBuffer[FILE_BUFFER_SIZE];
+#endif
+    byte*  fileBuf = staticBuffer;
+    int    dynamic = 0;
+    int    ret     = 0;
+    long   sz      = 0;
+    XFILE  file;
+    DerBuffer* converted = NULL;
+
+    WOLFSSL_ENTER("wc_PemPubKeyToDer");
+
+    if (fileName == NULL) {
+        ret = BAD_FUNC_ARG;
+    }
+    else {
+        file = XFOPEN(fileName, "rb");
+        if (file == XBADFILE) {
+            ret = BUFFER_E;
+        }
+    }
+
+    if (ret == 0) {
+        if(XFSEEK(file, 0, XSEEK_END) != 0)
+            ret = BUFFER_E;
+        sz = XFTELL(file);
+        XREWIND(file);
+
+        if (sz <= 0) {
+            ret = BUFFER_E;
+        }
+        else if (sz > (long)sizeof(staticBuffer)) {
+        #ifdef WOLFSSL_STATIC_MEMORY
+            WOLFSSL_MSG("File was larger then static buffer");
+            return MEMORY_E;
+        #endif
+            fileBuf = (byte*)XMALLOC(sz, NULL, DYNAMIC_TYPE_FILE);
+            if (fileBuf == NULL)
+                ret = MEMORY_E;
+            else
+                dynamic = 1;
+        }
+        if (ret == 0) {
+            if ( (ret = (int)XFREAD(fileBuf, 1, sz, file)) != sz) {
+                ret = BUFFER_E;
+            }
+        #ifdef WOLFSSL_PEM_TO_DER
+            else {
+                ret = PemToDer(fileBuf, sz, PUBLICKEY_TYPE, &converted,
+                               0, NULL, NULL);
+            }
+        #endif
+
+            if (ret == 0) {
+                if (converted->length < (word32)derSz) {
+                    XMEMCPY(derBuf, converted->buffer, converted->length);
+                    ret = converted->length;
+                }
+                else
+                    ret = BUFFER_E;
+            }
+
+            FreeDer(&converted);
+        }
+
+        XFCLOSE(file);
+        if (dynamic)
+            XFREE(fileBuf, NULL, DYNAMIC_TYPE_FILE);
+    }
+
+    return ret;
+}
+#endif /* WOLFSSL_CERT_EXT || WOLFSSL_PUB_PEM_TO_DER */
+
+#endif /* !NO_FILESYSTEM */
+
+
+#if !defined(NO_RSA) && (defined(WOLFSSL_CERT_GEN) || \
+    ((defined(WOLFSSL_KEY_GEN) || defined(OPENSSL_EXTRA)) && !defined(HAVE_USER_RSA)))
+/* USER RSA ifdef portions used instead of refactor in consideration for
+   possible fips build */
+/* Write a public RSA key to output */
+static int SetRsaPublicKey(byte* output, RsaKey* key,
+                           int outLen, int with_header)
+{
+#ifdef WOLFSSL_SMALL_STACK
+    byte* n = NULL;
+    byte* e = NULL;
+#else
+    byte n[MAX_RSA_INT_SZ];
+    byte e[MAX_RSA_E_SZ];
+#endif
+    byte seq[MAX_SEQ_SZ];
+    byte bitString[1 + MAX_LENGTH_SZ + 1];
+    int  nSz;
+    int  eSz;
+    int  seqSz;
+    int  bitStringSz;
+    int  idx;
+
+    if (output == NULL || key == NULL || outLen < MAX_SEQ_SZ)
+        return BAD_FUNC_ARG;
+
+    /* n */
+#ifdef WOLFSSL_SMALL_STACK
+    n = (byte*)XMALLOC(MAX_RSA_INT_SZ, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
+    if (n == NULL)
+        return MEMORY_E;
+#endif
+
+#ifdef HAVE_USER_RSA
+    nSz = SetASNIntRSA(key->n, n);
+#else
+    nSz = SetASNIntMP(&key->n, MAX_RSA_INT_SZ, n);
+#endif
+    if (nSz < 0) {
+#ifdef WOLFSSL_SMALL_STACK
+        XFREE(n, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
+#endif
+        return nSz;
+    }
+
+    /* e */
+#ifdef WOLFSSL_SMALL_STACK
+    e = (byte*)XMALLOC(MAX_RSA_E_SZ, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
+    if (e == NULL) {
+#ifdef WOLFSSL_SMALL_STACK
+        XFREE(n, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
+#endif
+        return MEMORY_E;
+    }
+#endif
+
+#ifdef HAVE_USER_RSA
+    eSz = SetASNIntRSA(key->e, e);
+#else
+    eSz = SetASNIntMP(&key->e, MAX_RSA_INT_SZ, e);
+#endif
+    if (eSz < 0) {
+#ifdef WOLFSSL_SMALL_STACK
+        XFREE(n, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
+        XFREE(e, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
+#endif
+        return eSz;
+    }
+
+    seqSz  = SetSequence(nSz + eSz, seq);
+
+    /* check output size */
+    if ( (seqSz + nSz + eSz) > outLen) {
+#ifdef WOLFSSL_SMALL_STACK
+        XFREE(n,    key->heap, DYNAMIC_TYPE_TMP_BUFFER);
+        XFREE(e,    key->heap, DYNAMIC_TYPE_TMP_BUFFER);
+#endif
+        return BUFFER_E;
+    }
+
+    /* headers */
+    if (with_header) {
+        int  algoSz;
+#ifdef WOLFSSL_SMALL_STACK
+        byte* algo;
+
+        algo = (byte*)XMALLOC(MAX_ALGO_SZ, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
+        if (algo == NULL) {
+            XFREE(n, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
+            XFREE(e, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
+            return MEMORY_E;
+        }
+#else
+        byte algo[MAX_ALGO_SZ];
+#endif
+        algoSz = SetAlgoID(RSAk, algo, oidKeyType, 0);
+        bitStringSz  = SetBitString(seqSz + nSz + eSz, 0, bitString);
+
+        idx = SetSequence(nSz + eSz + seqSz + bitStringSz + algoSz, output);
+
+        /* check output size */
+        if ( (idx + algoSz + bitStringSz + seqSz + nSz + eSz) > outLen) {
+            #ifdef WOLFSSL_SMALL_STACK
+                XFREE(n,    key->heap, DYNAMIC_TYPE_TMP_BUFFER);
+                XFREE(e,    key->heap, DYNAMIC_TYPE_TMP_BUFFER);
+                XFREE(algo, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
+            #endif
+
+            return BUFFER_E;
+        }
+
+        /* algo */
+        XMEMCPY(output + idx, algo, algoSz);
+        idx += algoSz;
+        /* bit string */
+        XMEMCPY(output + idx, bitString, bitStringSz);
+        idx += bitStringSz;
+#ifdef WOLFSSL_SMALL_STACK
+        XFREE(algo, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
+#endif
+    }
+    else
+        idx = 0;
+
+    /* seq */
+    XMEMCPY(output + idx, seq, seqSz);
+    idx += seqSz;
+    /* n */
+    XMEMCPY(output + idx, n, nSz);
+    idx += nSz;
+    /* e */
+    XMEMCPY(output + idx, e, eSz);
+    idx += eSz;
+
+#ifdef WOLFSSL_SMALL_STACK
+    XFREE(n,    key->heap, DYNAMIC_TYPE_TMP_BUFFER);
+    XFREE(e,    key->heap, DYNAMIC_TYPE_TMP_BUFFER);
+#endif
+
+    return idx;
+}
+
+#endif /* !NO_RSA && (WOLFSSL_CERT_GEN || (WOLFSSL_KEY_GEN &&
+                                           !HAVE_USER_RSA))) */
+
+#if !defined(NO_RSA) && (defined(WOLFSSL_CERT_GEN) || defined(OPENSSL_EXTRA))
+int wc_RsaPublicKeyDerSize(RsaKey* key, int with_header)
+{
+    int  idx = 0;
+    int  nSz, eSz, seqSz, bitStringSz, algoSz;
+
+    if (key == NULL)
+        return BAD_FUNC_ARG;
+
+    /* n */
+#ifdef HAVE_USER_RSA
+    nSz = SetASNIntRSA(key->n, NULL);
+#else
+    nSz = SetASNIntMP(&key->n, MAX_RSA_INT_SZ, NULL);
+#endif
+    if (nSz < 0) {
+        return nSz;
+    }
+
+    /* e */
+#ifdef HAVE_USER_RSA
+    eSz = SetASNIntRSA(key->e, NULL);
+#else
+    eSz = SetASNIntMP(&key->e, MAX_RSA_INT_SZ, NULL);
+#endif
+    if (eSz < 0) {
+        return eSz;
+    }
+
+    seqSz  = SetSequence(nSz + eSz, NULL);
+
+    /* headers */
+    if (with_header) {
+        algoSz = SetAlgoID(RSAk, NULL, oidKeyType, 0);
+        bitStringSz = SetBitString(seqSz + nSz + eSz, 0, NULL);
+
+        idx += SetSequence(nSz + eSz + seqSz + bitStringSz + algoSz, NULL);
+
+        /* algo */
+        idx += algoSz;
+        /* bit string */
+        idx += bitStringSz;
+    }
+
+    /* seq */
+    idx += seqSz;
+    /* n */
+    idx += nSz;
+    /* e */
+    idx += eSz;
+
+    return idx;
+}
+
+#endif /* !NO_RSA && WOLFSSL_CERT_GEN */
+
+
+#if defined(WOLFSSL_KEY_GEN) && !defined(NO_RSA) && !defined(HAVE_USER_RSA)
+
+static mp_int* GetRsaInt(RsaKey* key, int idx)
+{
+    if (idx == 0)
+        return &key->n;
+    if (idx == 1)
+        return &key->e;
+    if (idx == 2)
+        return &key->d;
+    if (idx == 3)
+        return &key->p;
+    if (idx == 4)
+        return &key->q;
+    if (idx == 5)
+        return &key->dP;
+    if (idx == 6)
+        return &key->dQ;
+    if (idx == 7)
+        return &key->u;
+
+    return NULL;
+}
+
+
+/* Release Tmp RSA resources */
+static WC_INLINE void FreeTmpRsas(byte** tmps, void* heap)
+{
+    int i;
+
+    (void)heap;
+
+    for (i = 0; i < RSA_INTS; i++)
+        XFREE(tmps[i], heap, DYNAMIC_TYPE_RSA);
+}
+
+
+/* Convert RsaKey key to DER format, write to output (inLen), return bytes
+   written */
+int wc_RsaKeyToDer(RsaKey* key, byte* output, word32 inLen)
+{
+    word32 seqSz, verSz, rawLen, intTotalLen = 0;
+    word32 sizes[RSA_INTS];
+    int    i, j, outLen, ret = 0, mpSz;
+
+    byte  seq[MAX_SEQ_SZ];
+    byte  ver[MAX_VERSION_SZ];
+    byte* tmps[RSA_INTS];
+
+    if (!key)
+        return BAD_FUNC_ARG;
+
+    if (key->type != RSA_PRIVATE)
+        return BAD_FUNC_ARG;
+
+    for (i = 0; i < RSA_INTS; i++)
+        tmps[i] = NULL;
+
+    /* write all big ints from key to DER tmps */
+    for (i = 0; i < RSA_INTS; i++) {
+        mp_int* keyInt = GetRsaInt(key, i);
+
+        rawLen = mp_unsigned_bin_size(keyInt) + 1;
+        tmps[i] = (byte*)XMALLOC(rawLen + MAX_SEQ_SZ, key->heap,
+                                 DYNAMIC_TYPE_RSA);
+        if (tmps[i] == NULL) {
+            ret = MEMORY_E;
+            break;
+        }
+
+        mpSz = SetASNIntMP(keyInt, MAX_RSA_INT_SZ, tmps[i]);
+        if (mpSz < 0) {
+            ret = mpSz;
+            break;
+        }
+        intTotalLen += (sizes[i] = mpSz);
+    }
+
+    if (ret != 0) {
+        FreeTmpRsas(tmps, key->heap);
+        return ret;
+    }
+
+    /* make headers */
+    verSz = SetMyVersion(0, ver, FALSE);
+    seqSz = SetSequence(verSz + intTotalLen, seq);
+
+    outLen = seqSz + verSz + intTotalLen;
+    if (output) {
+        if (outLen > (int)inLen) {
+            FreeTmpRsas(tmps, key->heap);
+            return BAD_FUNC_ARG;
+        }
+
+        /* write to output */
+        XMEMCPY(output, seq, seqSz);
+        j = seqSz;
+        XMEMCPY(output + j, ver, verSz);
+        j += verSz;
+
+        for (i = 0; i < RSA_INTS; i++) {
+            XMEMCPY(output + j, tmps[i], sizes[i]);
+            j += sizes[i];
+        }
+    }
+    FreeTmpRsas(tmps, key->heap);
+
+    return outLen;
+}
+#endif
+
+#if (defined(WOLFSSL_KEY_GEN) || defined(OPENSSL_EXTRA)) && !defined(NO_RSA) && !defined(HAVE_USER_RSA)
+/* Convert Rsa Public key to DER format, write to output (inLen), return bytes
+   written */
+int wc_RsaKeyToPublicDer(RsaKey* key, byte* output, word32 inLen)
+{
+    return SetRsaPublicKey(output, key, inLen, 1);
+}
+
+#endif /* (WOLFSSL_KEY_GEN || OPENSSL_EXTRA) && !NO_RSA && !HAVE_USER_RSA */
+
+
+#ifdef WOLFSSL_CERT_GEN
+
+/* Initialize and Set Certificate defaults:
+   version    = 3 (0x2)
+   serial     = 0
+   sigType    = SHA_WITH_RSA
+   issuer     = blank
+   daysValid  = 500
+   selfSigned = 1 (true) use subject as issuer
+   subject    = blank
+*/
+int wc_InitCert(Cert* cert)
+{
+#ifdef WOLFSSL_MULTI_ATTRIB
+    int i = 0;
+#endif
+    if (cert == NULL) {
+        return BAD_FUNC_ARG;
+    }
+
+    XMEMSET(cert, 0, sizeof(Cert));
+
+    cert->version    = 2;   /* version 3 is hex 2 */
+#ifndef NO_SHA
+    cert->sigType    = CTC_SHAwRSA;
+#elif !defined(NO_SHA256)
+    cert->sigType    = CTC_SHA256wRSA;
+#else
+    cert->sigType    = 0;
+#endif
+    cert->daysValid  = 500;
+    cert->selfSigned = 1;
+    cert->keyType    = RSA_KEY;
+
+    cert->issuer.countryEnc = CTC_PRINTABLE;
+    cert->issuer.stateEnc = CTC_UTF8;
+    cert->issuer.localityEnc = CTC_UTF8;
+    cert->issuer.surEnc = CTC_UTF8;
+    cert->issuer.orgEnc = CTC_UTF8;
+    cert->issuer.unitEnc = CTC_UTF8;
+    cert->issuer.commonNameEnc = CTC_UTF8;
+
+    cert->subject.countryEnc = CTC_PRINTABLE;
+    cert->subject.stateEnc = CTC_UTF8;
+    cert->subject.localityEnc = CTC_UTF8;
+    cert->subject.surEnc = CTC_UTF8;
+    cert->subject.orgEnc = CTC_UTF8;
+    cert->subject.unitEnc = CTC_UTF8;
+    cert->subject.commonNameEnc = CTC_UTF8;
+
+#ifdef WOLFSSL_MULTI_ATTRIB
+    for (i = 0; i < CTC_MAX_ATTRIB; i++) {
+        cert->issuer.name[i].type   = CTC_UTF8;
+        cert->subject.name[i].type  = CTC_UTF8;
+    }
+#endif /* WOLFSSL_MULTI_ATTRIB */
+
+#ifdef WOLFSSL_HEAP_TEST
+    cert->heap = (void*)WOLFSSL_HEAP_TEST;
+#endif
+
+    return 0;
+}
+
+
+/* DER encoded x509 Certificate */
+typedef struct DerCert {
+    byte size[MAX_LENGTH_SZ];          /* length encoded */
+    byte version[MAX_VERSION_SZ];      /* version encoded */
+    byte serial[(int)CTC_SERIAL_SIZE + (int)MAX_LENGTH_SZ]; /* serial number encoded */
+    byte sigAlgo[MAX_ALGO_SZ];         /* signature algo encoded */
+    byte issuer[ASN_NAME_MAX];         /* issuer  encoded */
+    byte subject[ASN_NAME_MAX];        /* subject encoded */
+    byte validity[MAX_DATE_SIZE*2 + MAX_SEQ_SZ*2];  /* before and after dates */
+    byte publicKey[MAX_PUBLIC_KEY_SZ]; /* rsa / ntru public key encoded */
+    byte ca[MAX_CA_SZ];                /* basic constraint CA true size */
+    byte extensions[MAX_EXTENSIONS_SZ]; /* all extensions */
+#ifdef WOLFSSL_CERT_EXT
+    byte skid[MAX_KID_SZ];             /* Subject Key Identifier extension */
+    byte akid[MAX_KID_SZ];             /* Authority Key Identifier extension */
+    byte keyUsage[MAX_KEYUSAGE_SZ];    /* Key Usage extension */
+    byte extKeyUsage[MAX_EXTKEYUSAGE_SZ]; /* Extended Key Usage extension */
+    byte certPolicies[MAX_CERTPOL_NB*MAX_CERTPOL_SZ]; /* Certificate Policies */
+#endif
+#ifdef WOLFSSL_CERT_REQ
+    byte attrib[MAX_ATTRIB_SZ];        /* Cert req attributes encoded */
+#endif
+#ifdef WOLFSSL_ALT_NAMES
+    byte altNames[CTC_MAX_ALT_SIZE];   /* Alternative Names encoded */
+#endif
+    int  sizeSz;                       /* encoded size length */
+    int  versionSz;                    /* encoded version length */
+    int  serialSz;                     /* encoded serial length */
+    int  sigAlgoSz;                    /* encoded sig algo length */
+    int  issuerSz;                     /* encoded issuer length */
+    int  subjectSz;                    /* encoded subject length */
+    int  validitySz;                   /* encoded validity length */
+    int  publicKeySz;                  /* encoded public key length */
+    int  caSz;                         /* encoded CA extension length */
+#ifdef WOLFSSL_CERT_EXT
+    int  skidSz;                       /* encoded SKID extension length */
+    int  akidSz;                       /* encoded SKID extension length */
+    int  keyUsageSz;                   /* encoded KeyUsage extension length */
+    int  extKeyUsageSz;                /* encoded ExtendedKeyUsage extension length */
+    int  certPoliciesSz;               /* encoded CertPolicies extension length*/
+#endif
+#ifdef WOLFSSL_ALT_NAMES
+    int  altNamesSz;                   /* encoded AltNames extension length */
+#endif
+    int  extensionsSz;                 /* encoded extensions total length */
+    int  total;                        /* total encoded lengths */
+#ifdef WOLFSSL_CERT_REQ
+    int  attribSz;
+#endif
+} DerCert;
+
+
+#ifdef WOLFSSL_CERT_REQ
+
+/* Write a set header to output */
+static word32 SetPrintableString(word32 len, byte* output)
+{
+    output[0] = ASN_PRINTABLE_STRING;
+    return SetLength(len, output + 1) + 1;
+}
+
+static word32 SetUTF8String(word32 len, byte* output)
+{
+    output[0] = ASN_UTF8STRING;
+    return SetLength(len, output + 1) + 1;
+}
+
+#endif /* WOLFSSL_CERT_REQ */
+
+
+#ifndef WOLFSSL_CERT_GEN_CACHE
+/* wc_SetCert_Free is only public when WOLFSSL_CERT_GEN_CACHE is not defined */
+static
+#endif
+void wc_SetCert_Free(Cert* cert)
+{
+    if (cert != NULL) {
+        cert->der = NULL;
+        if (cert->decodedCert) {
+            FreeDecodedCert((DecodedCert*)cert->decodedCert);
+
+            XFREE(cert->decodedCert, cert->heap, DYNAMIC_TYPE_DCERT);
+            cert->decodedCert = NULL;
+        }
+    }
+}
+
+static int wc_SetCert_LoadDer(Cert* cert, const byte* der, word32 derSz)
+{
+    int ret;
+
+    if (cert == NULL) {
+        ret = BAD_FUNC_ARG;
+    }
+    else {
+        /* Allocate DecodedCert struct and Zero */
+        cert->decodedCert = (void*)XMALLOC(sizeof(DecodedCert), cert->heap,
+            DYNAMIC_TYPE_DCERT);
+
+        if (cert->decodedCert == NULL) {
+            ret = MEMORY_E;
+        }
+        else {
+            XMEMSET(cert->decodedCert, 0, sizeof(DecodedCert));
+
+            InitDecodedCert((DecodedCert*)cert->decodedCert, der, derSz,
+                    cert->heap);
+            ret = ParseCertRelative((DecodedCert*)cert->decodedCert,
+                    CERT_TYPE, 0, NULL);
+            if (ret >= 0) {
+                cert->der = (byte*)der;
+            }
+            else {
+                wc_SetCert_Free(cert);
+            }
+        }
+    }
+
+    return ret;
+}
+
+#endif /* WOLFSSL_CERT_GEN */
+
+
+#if defined(HAVE_ECC) && defined(HAVE_ECC_KEY_EXPORT)
+
+/* Write a public ECC key to output */
+static int SetEccPublicKey(byte* output, ecc_key* key, int with_header)
+{
+    byte bitString[1 + MAX_LENGTH_SZ + 1];
+    int  algoSz;
+    int  curveSz;
+    int  bitStringSz;
+    int  idx;
+    word32 pubSz = ECC_BUFSIZE;
+#ifdef WOLFSSL_SMALL_STACK
+    byte* algo = NULL;
+    byte* curve = NULL;
+    byte* pub;
+#else
+    byte algo[MAX_ALGO_SZ];
+    byte curve[MAX_ALGO_SZ];
+    byte pub[ECC_BUFSIZE];
+#endif
+    int ret;
+
+#ifdef WOLFSSL_SMALL_STACK
+    pub = (byte*)XMALLOC(ECC_BUFSIZE, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
+    if (pub == NULL)
+        return MEMORY_E;
+#endif
+
+#ifdef HAVE_SELFTEST
+    /* older version of ecc.c can not handle dp being NULL */
+    if (key != NULL && key->dp == NULL) {
+        ret = BAD_FUNC_ARG;
+    }
+    else {
+        ret = wc_ecc_export_x963(key, pub, &pubSz);
+    }
+#else
+    ret = wc_ecc_export_x963(key, pub, &pubSz);
+#endif
+    if (ret != 0) {
+#ifdef WOLFSSL_SMALL_STACK
+        XFREE(pub, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
+#endif
+        return ret;
+    }
+
+    /* headers */
+    if (with_header) {
+#ifdef WOLFSSL_SMALL_STACK
+        curve = (byte*)XMALLOC(MAX_ALGO_SZ, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
+        if (curve == NULL) {
+            XFREE(pub, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
+            return MEMORY_E;
+        }
+#endif
+        curveSz = SetCurve(key, curve);
+        if (curveSz <= 0) {
+#ifdef WOLFSSL_SMALL_STACK
+            XFREE(curve, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
+            XFREE(pub,   key->heap, DYNAMIC_TYPE_TMP_BUFFER);
+#endif
+            return curveSz;
+        }
+
+#ifdef WOLFSSL_SMALL_STACK
+        algo = (byte*)XMALLOC(MAX_ALGO_SZ, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
+        if (algo == NULL) {
+            XFREE(curve, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
+            XFREE(pub,   key->heap, DYNAMIC_TYPE_TMP_BUFFER);
+            return MEMORY_E;
+        }
+#endif
+        algoSz  = SetAlgoID(ECDSAk, algo, oidKeyType, curveSz);
+
+        bitStringSz = SetBitString(pubSz, 0, bitString);
+
+        idx = SetSequence(pubSz + curveSz + bitStringSz + algoSz, output);
+        /* algo */
+        if (output)
+            XMEMCPY(output + idx, algo, algoSz);
+        idx += algoSz;
+        /* curve */
+        if (output)
+            XMEMCPY(output + idx, curve, curveSz);
+        idx += curveSz;
+        /* bit string */
+        if (output)
+            XMEMCPY(output + idx, bitString, bitStringSz);
+        idx += bitStringSz;
+    }
+    else
+        idx = 0;
+
+    /* pub */
+    if (output)
+        XMEMCPY(output + idx, pub, pubSz);
+    idx += pubSz;
+
+#ifdef WOLFSSL_SMALL_STACK
+    if (with_header) {
+        XFREE(algo,  key->heap, DYNAMIC_TYPE_TMP_BUFFER);
+        XFREE(curve, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
+    }
+    XFREE(pub,   key->heap, DYNAMIC_TYPE_TMP_BUFFER);
+#endif
+
+    return idx;
+}
+
+
+/* returns the size of buffer used, the public ECC key in DER format is stored
+   in output buffer
+   with_AlgCurve is a flag for when to include a header that has the Algorithm
+   and Curve information */
+int wc_EccPublicKeyToDer(ecc_key* key, byte* output, word32 inLen,
+                                                              int with_AlgCurve)
+{
+    word32 infoSz = 0;
+    word32 keySz  = 0;
+    int ret;
+
+    if (key == NULL) {
+        return BAD_FUNC_ARG;
+    }
+
+    if (with_AlgCurve) {
+        /* buffer space for algorithm/curve */
+        infoSz += MAX_SEQ_SZ;
+        infoSz += 2 * MAX_ALGO_SZ;
+
+        /* buffer space for public key sequence */
+        infoSz += MAX_SEQ_SZ;
+        infoSz += TRAILING_ZERO;
+    }
+
+#ifdef HAVE_SELFTEST
+    /* older version of ecc.c can not handle dp being NULL */
+    if (key != NULL && key->dp == NULL) {
+        keySz = 1 + 2 * MAX_ECC_BYTES;
+        ret = LENGTH_ONLY_E;
+    }
+    else {
+        ret = wc_ecc_export_x963(key, NULL, &keySz);
+    }
+#else
+    ret = wc_ecc_export_x963(key, NULL, &keySz);
+#endif
+    if (ret != LENGTH_ONLY_E) {
+        WOLFSSL_MSG("Error in getting ECC public key size");
+        return ret;
+    }
+
+    /* if output null then just return size */
+    if (output == NULL) {
+        return keySz + infoSz;
+    }
+
+    if (inLen < keySz + infoSz) {
+        return BUFFER_E;
+    }
+
+    return SetEccPublicKey(output, key, with_AlgCurve);
+}
+
+int wc_EccPublicKeyDerSize(ecc_key* key, int with_AlgCurve)
+{
+    return wc_EccPublicKeyToDer(key, NULL, 0, with_AlgCurve);
+}
+
+#endif /* HAVE_ECC && HAVE_ECC_KEY_EXPORT */
+
+#if defined(HAVE_ED25519) && (defined(WOLFSSL_CERT_GEN) || \
+                              defined(WOLFSSL_KEY_GEN))
+
+/* Write a public ECC key to output */
+static int SetEd25519PublicKey(byte* output, ed25519_key* key, int with_header)
+{
+    byte bitString[1 + MAX_LENGTH_SZ + 1];
+    int  algoSz;
+    int  bitStringSz;
+    int  idx;
+    word32 pubSz = ED25519_PUB_KEY_SIZE;
+#ifdef WOLFSSL_SMALL_STACK
+    byte* algo = NULL;
+    byte* pub;
+#else
+    byte algo[MAX_ALGO_SZ];
+    byte pub[ED25519_PUB_KEY_SIZE];
+#endif
+
+#ifdef WOLFSSL_SMALL_STACK
+    pub = (byte*)XMALLOC(ECC_BUFSIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    if (pub == NULL)
+        return MEMORY_E;
+#endif
+
+    idx = wc_ed25519_export_public(key, pub, &pubSz);
+    if (idx != 0) {
+#ifdef WOLFSSL_SMALL_STACK
+        XFREE(pub, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
+#endif
+        return idx;
+    }
+
+    /* headers */
+    if (with_header) {
+#ifdef WOLFSSL_SMALL_STACK
+        algo = (byte*)XMALLOC(MAX_ALGO_SZ, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+        if (algo == NULL) {
+            XFREE(pub, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
+            return MEMORY_E;
+        }
+#endif
+        algoSz  = SetAlgoID(ED25519k, algo, oidKeyType, 0);
+
+        bitStringSz = SetBitString(pubSz, 0, bitString);
+
+        idx = SetSequence(pubSz + bitStringSz + algoSz, output);
+        /* algo */
+        XMEMCPY(output + idx, algo, algoSz);
+        idx += algoSz;
+        /* bit string */
+        XMEMCPY(output + idx, bitString, bitStringSz);
+        idx += bitStringSz;
+    }
+    else
+        idx = 0;
+
+    /* pub */
+    XMEMCPY(output + idx, pub, pubSz);
+    idx += pubSz;
+
+#ifdef WOLFSSL_SMALL_STACK
+    if (with_header) {
+        XFREE(algo, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    }
+    XFREE(pub, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+#endif
+
+    return idx;
+}
+
+int wc_Ed25519PublicKeyToDer(ed25519_key* key, byte* output, word32 inLen,
+                                                                    int withAlg)
+{
+    word32 infoSz = 0;
+    word32 keySz  = 0;
+    int ret;
+
+    if (output == NULL || key == NULL) {
+        return BAD_FUNC_ARG;
+    }
+
+    if (withAlg) {
+        /* buffer space for algorithm */
+        infoSz += MAX_SEQ_SZ;
+        infoSz += MAX_ALGO_SZ;
+
+        /* buffer space for public key sequence */
+        infoSz += MAX_SEQ_SZ;
+        infoSz += TRAILING_ZERO;
+    }
+
+    if ((ret = wc_ed25519_export_public(key, output, &keySz)) != BUFFER_E) {
+        WOLFSSL_MSG("Error in getting ECC public key size");
+        return ret;
+    }
+
+    if (inLen < keySz + infoSz) {
+        return BUFFER_E;
+    }
+
+    return SetEd25519PublicKey(output, key, withAlg);
+}
+#endif /* HAVE_ED25519 && (WOLFSSL_CERT_GEN || WOLFSSL_KEY_GEN) */
+#if defined(HAVE_ED448) && (defined(WOLFSSL_CERT_GEN) || \
+                                                       defined(WOLFSSL_KEY_GEN))
+
+/* Write a public ECC key to output */
+static int SetEd448PublicKey(byte* output, ed448_key* key, int with_header)
+{
+    byte bitString[1 + MAX_LENGTH_SZ + 1];
+    int  algoSz;
+    int  bitStringSz;
+    int  idx;
+    word32 pubSz = ED448_PUB_KEY_SIZE;
+#ifdef WOLFSSL_SMALL_STACK
+    byte* algo = NULL;
+    byte* pub = NULL;
+#else
+    byte algo[MAX_ALGO_SZ];
+    byte pub[ED448_PUB_KEY_SIZE];
+#endif
+
+#ifdef WOLFSSL_SMALL_STACK
+    pub = (byte*)XMALLOC(ECC_BUFSIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    if (pub == NULL)
+        return MEMORY_E;
+#endif
+
+    idx = wc_ed448_export_public(key, pub, &pubSz);
+    if (idx != 0) {
+#ifdef WOLFSSL_SMALL_STACK
+        XFREE(pub, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
+#endif
+        return idx;
+    }
+
+    /* headers */
+    if (with_header) {
+#ifdef WOLFSSL_SMALL_STACK
+        algo = (byte*)XMALLOC(MAX_ALGO_SZ, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+        if (algo == NULL) {
+            XFREE(pub, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
+            return MEMORY_E;
+        }
+#endif
+        algoSz  = SetAlgoID(ED448k, algo, oidKeyType, 0);
+
+        bitStringSz = SetBitString(pubSz, 0, bitString);
+
+        idx = SetSequence(pubSz + bitStringSz + algoSz, output);
+        /* algo */
+        XMEMCPY(output + idx, algo, algoSz);
+        idx += algoSz;
+        /* bit string */
+        XMEMCPY(output + idx, bitString, bitStringSz);
+        idx += bitStringSz;
+    }
+    else
+        idx = 0;
+
+    /* pub */
+    XMEMCPY(output + idx, pub, pubSz);
+    idx += pubSz;
+
+#ifdef WOLFSSL_SMALL_STACK
+    if (with_header) {
+        XFREE(algo, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    }
+    XFREE(pub, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+#endif
+
+    return idx;
+}
+
+int wc_Ed448PublicKeyToDer(ed448_key* key, byte* output, word32 inLen,
+                                                                    int withAlg)
+{
+    word32 infoSz = 0;
+    word32 keySz  = 0;
+    int ret;
+
+    if (output == NULL || key == NULL) {
+        return BAD_FUNC_ARG;
+    }
+
+    if (withAlg) {
+        /* buffer space for algorithm */
+        infoSz += MAX_SEQ_SZ;
+        infoSz += MAX_ALGO_SZ;
+
+        /* buffer space for public key sequence */
+        infoSz += MAX_SEQ_SZ;
+        infoSz += TRAILING_ZERO;
+    }
+
+    if ((ret = wc_ed448_export_public(key, output, &keySz)) != BUFFER_E) {
+        WOLFSSL_MSG("Error in getting ECC public key size");
+        return ret;
+    }
+
+    if (inLen < keySz + infoSz) {
+        return BUFFER_E;
+    }
+
+    return SetEd448PublicKey(output, key, withAlg);
+}
+#endif /* HAVE_ED448 && (WOLFSSL_CERT_GEN || WOLFSSL_KEY_GEN) */
+
+
+#ifdef WOLFSSL_CERT_GEN
+
+static WC_INLINE byte itob(int number)
+{
+    return (byte)number + 0x30;
+}
+
+
+/* write time to output, format */
+static void SetTime(struct tm* date, byte* output)
+{
+    int i = 0;
+
+    output[i++] = itob((date->tm_year % 10000) / 1000);
+    output[i++] = itob((date->tm_year % 1000)  /  100);
+    output[i++] = itob((date->tm_year % 100)   /   10);
+    output[i++] = itob( date->tm_year % 10);
+
+    output[i++] = itob(date->tm_mon / 10);
+    output[i++] = itob(date->tm_mon % 10);
+
+    output[i++] = itob(date->tm_mday / 10);
+    output[i++] = itob(date->tm_mday % 10);
+
+    output[i++] = itob(date->tm_hour / 10);
+    output[i++] = itob(date->tm_hour % 10);
+
+    output[i++] = itob(date->tm_min / 10);
+    output[i++] = itob(date->tm_min % 10);
+
+    output[i++] = itob(date->tm_sec / 10);
+    output[i++] = itob(date->tm_sec % 10);
+
+    output[i] = 'Z';  /* Zulu profile */
+}
+
+
+#ifdef WOLFSSL_ALT_NAMES
+
+/* Copy Dates from cert, return bytes written */
+static int CopyValidity(byte* output, Cert* cert)
+{
+    int seqSz;
+
+    WOLFSSL_ENTER("CopyValidity");
+
+    /* headers and output */
+    seqSz = SetSequence(cert->beforeDateSz + cert->afterDateSz, output);
+    if (output) {
+        XMEMCPY(output + seqSz, cert->beforeDate, cert->beforeDateSz);
+        XMEMCPY(output + seqSz + cert->beforeDateSz, cert->afterDate,
+                                                     cert->afterDateSz);
+    }
+    return seqSz + cert->beforeDateSz + cert->afterDateSz;
+}
+
+#endif
+
+
+/* Set Date validity from now until now + daysValid
+ * return size in bytes written to output, 0 on error */
+static int SetValidity(byte* output, int daysValid)
+{
+    byte before[MAX_DATE_SIZE];
+    byte  after[MAX_DATE_SIZE];
+
+    int beforeSz;
+    int afterSz;
+    int seqSz;
+
+    time_t now;
+    time_t then;
+    struct tm* tmpTime;
+    struct tm* expandedTime;
+    struct tm localTime;
+
+#if defined(NEED_TMP_TIME)
+    /* for use with gmtime_r */
+    struct tm tmpTimeStorage;
+    tmpTime = &tmpTimeStorage;
+#else
+    tmpTime = NULL;
+#endif
+    (void)tmpTime;
+
+    now = XTIME(0);
+
+    /* before now */
+    before[0] = ASN_GENERALIZED_TIME;
+    beforeSz = SetLength(ASN_GEN_TIME_SZ, before + 1) + 1;  /* gen tag */
+
+    /* subtract 1 day of seconds for more compliance */
+    then = now - 86400;
+    expandedTime = XGMTIME(&then, tmpTime);
+    if (expandedTime == NULL) {
+        WOLFSSL_MSG("XGMTIME failed");
+        return 0;   /* error */
+    }
+    localTime = *expandedTime;
+
+    /* adjust */
+    localTime.tm_year += 1900;
+    localTime.tm_mon +=    1;
+
+    SetTime(&localTime, before + beforeSz);
+    beforeSz += ASN_GEN_TIME_SZ;
+
+    after[0] = ASN_GENERALIZED_TIME;
+    afterSz  = SetLength(ASN_GEN_TIME_SZ, after + 1) + 1;  /* gen tag */
+
+    /* add daysValid of seconds */
+    then = now + (daysValid * (time_t)86400);
+    expandedTime = XGMTIME(&then, tmpTime);
+    if (expandedTime == NULL) {
+        WOLFSSL_MSG("XGMTIME failed");
+        return 0;   /* error */
+    }
+    localTime = *expandedTime;
+
+    /* adjust */
+    localTime.tm_year += 1900;
+    localTime.tm_mon  +=    1;
+
+    SetTime(&localTime, after + afterSz);
+    afterSz += ASN_GEN_TIME_SZ;
+
+    /* headers and output */
+    seqSz = SetSequence(beforeSz + afterSz, output);
+    XMEMCPY(output + seqSz, before, beforeSz);
+    XMEMCPY(output + seqSz + beforeSz, after, afterSz);
+
+    return seqSz + beforeSz + afterSz;
+}
+
+
+/* ASN Encoded Name field */
+typedef struct EncodedName {
+    int  nameLen;                /* actual string value length */
+    int  totalLen;               /* total encoded length */
+    int  type;                   /* type of name */
+    int  used;                   /* are we actually using this one */
+    byte encoded[CTC_NAME_SIZE * 2]; /* encoding */
+} EncodedName;
+
+
+/* Get Which Name from index */
+static const char* GetOneName(CertName* name, int idx)
+{
+    switch (idx) {
+    case 0:
+       return name->country;
+
+    case 1:
+       return name->state;
+
+    case 2:
+       return name->locality;
+
+    case 3:
+       return name->sur;
+
+    case 4:
+       return name->org;
+
+    case 5:
+       return name->unit;
+
+    case 6:
+       return name->commonName;
+
+    case 7:
+       return name->serialDev;
+
+#ifdef WOLFSSL_CERT_EXT
+    case 8:
+       return name->busCat;
+
+    case 9:
+#else
+    case 8:
+#endif
+       return name->email;
+
+    default:
+       return 0;
+    }
+}
+
+
+/* Get Which Name Encoding from index */
+static char GetNameType(CertName* name, int idx)
+{
+    switch (idx) {
+    case 0:
+       return name->countryEnc;
+
+    case 1:
+       return name->stateEnc;
+
+    case 2:
+       return name->localityEnc;
+
+    case 3:
+       return name->surEnc;
+
+    case 4:
+       return name->orgEnc;
+
+    case 5:
+       return name->unitEnc;
+
+    case 6:
+       return name->commonNameEnc;
+
+    case 7:
+       return name->serialDevEnc;
+
+#ifdef WOLFSSL_CERT_EXT
+    case 8:
+       return name->busCatEnc;
+
+    case 9:
+#else
+    case 8:
+#endif
+        /* FALL THROUGH */
+        /* The last index, email name, does not have encoding type.
+           The empty case here is to keep track of it for future reference. */
+    default:
+       return 0;
+    }
+}
+
+
+/* Get ASN Name from index */
+static byte GetNameId(int idx)
+{
+    switch (idx) {
+    case 0:
+       return ASN_COUNTRY_NAME;
+
+    case 1:
+       return ASN_STATE_NAME;
+
+    case 2:
+       return ASN_LOCALITY_NAME;
+
+    case 3:
+       return ASN_SUR_NAME;
+
+    case 4:
+       return ASN_ORG_NAME;
+
+    case 5:
+       return ASN_ORGUNIT_NAME;
+
+    case 6:
+       return ASN_COMMON_NAME;
+
+    case 7:
+       return ASN_SERIAL_NUMBER;
+
+#ifdef WOLFSSL_CERT_EXT
+    case 8:
+        return ASN_BUS_CAT;
+
+    case 9:
+#else
+    case 8:
+#endif
+        return ASN_EMAIL_NAME;
+
+    default:
+       return 0;
+    }
+}
+
+/*
+ Extensions ::= SEQUENCE OF Extension
+
+ Extension ::= SEQUENCE {
+ extnId     OBJECT IDENTIFIER,
+ critical   BOOLEAN DEFAULT FALSE,
+ extnValue  OCTET STRING }
+ */
+
+/* encode all extensions, return total bytes written */
+static int SetExtensions(byte* out, word32 outSz, int *IdxInOut,
+                         const byte* ext, int extSz)
+{
+    if (out == NULL || IdxInOut == NULL || ext == NULL)
+        return BAD_FUNC_ARG;
+
+    if (outSz < (word32)(*IdxInOut+extSz))
+        return BUFFER_E;
+
+    XMEMCPY(&out[*IdxInOut], ext, extSz);  /* extensions */
+    *IdxInOut += extSz;
+
+    return *IdxInOut;
+}
+
+/* encode extensions header, return total bytes written */
+static int SetExtensionsHeader(byte* out, word32 outSz, int extSz)
+{
+    byte sequence[MAX_SEQ_SZ];
+    byte len[MAX_LENGTH_SZ];
+    int seqSz, lenSz, idx = 0;
+
+    if (out == NULL)
+        return BAD_FUNC_ARG;
+
+    if (outSz < 3)
+        return BUFFER_E;
+
+    seqSz = SetSequence(extSz, sequence);
+
+    /* encode extensions length provided */
+    lenSz = SetLength(extSz+seqSz, len);
+
+    if (outSz < (word32)(lenSz+seqSz+1))
+        return BUFFER_E;
+
+    out[idx++] = ASN_EXTENSIONS; /* extensions id */
+    XMEMCPY(&out[idx], len, lenSz);  /* length */
+    idx += lenSz;
+
+    XMEMCPY(&out[idx], sequence, seqSz);  /* sequence */
+    idx += seqSz;
+
+    return idx;
+}
+
+
+/* encode CA basic constraint true, return total bytes written */
+static int SetCa(byte* out, word32 outSz)
+{
+    const byte ca[] = { 0x30, 0x0c, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x04,
+                               0x05, 0x30, 0x03, 0x01, 0x01, 0xff };
+
+    if (out == NULL)
+        return BAD_FUNC_ARG;
+
+    if (outSz < sizeof(ca))
+        return BUFFER_E;
+
+    XMEMCPY(out, ca, sizeof(ca));
+
+    return (int)sizeof(ca);
+}
+
+
+#ifdef WOLFSSL_CERT_EXT
+/* encode OID and associated value, return total bytes written */
+static int SetOidValue(byte* out, word32 outSz, const byte *oid, word32 oidSz,
+                       byte *in, word32 inSz)
+{
+    int idx = 0;
+
+    if (out == NULL || oid == NULL || in == NULL)
+        return BAD_FUNC_ARG;
+
+    if (outSz < 3)
+        return BUFFER_E;
+
+    /* sequence,  + 1 => byte to put value size */
+    idx = SetSequence(inSz + oidSz + 1, out);
+
+    if ((idx + inSz + oidSz + 1) > outSz)
+        return BUFFER_E;
+
+    XMEMCPY(out+idx, oid, oidSz);
+    idx += oidSz;
+    out[idx++] = (byte)inSz;
+    XMEMCPY(out+idx, in, inSz);
+
+    return (idx+inSz);
+}
+
+/* encode Subject Key Identifier, return total bytes written
+ * RFC5280 : non-critical */
+static int SetSKID(byte* output, word32 outSz, const byte *input, word32 length)
+{
+    byte skid_len[1 + MAX_LENGTH_SZ];
+    byte skid_enc_len[MAX_LENGTH_SZ];
+    int idx = 0, skid_lenSz, skid_enc_lenSz;
+    const byte skid_oid[] = { 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04 };
+
+    if (output == NULL || input == NULL)
+        return BAD_FUNC_ARG;
+
+    /* Octet String header */
+    skid_lenSz = SetOctetString(length, skid_len);
+
+    /* length of encoded value */
+    skid_enc_lenSz = SetLength(length + skid_lenSz, skid_enc_len);
+
+    if (outSz < 3)
+        return BUFFER_E;
+
+    idx = SetSequence(length + sizeof(skid_oid) + skid_lenSz + skid_enc_lenSz,
+                      output);
+
+    if ((length + sizeof(skid_oid) + skid_lenSz + skid_enc_lenSz) > outSz)
+        return BUFFER_E;
+
+    /* put oid */
+    XMEMCPY(output+idx, skid_oid, sizeof(skid_oid));
+    idx += sizeof(skid_oid);
+
+    /* put encoded len */
+    XMEMCPY(output+idx, skid_enc_len, skid_enc_lenSz);
+    idx += skid_enc_lenSz;
+
+    /* put octet header */
+    XMEMCPY(output+idx, skid_len, skid_lenSz);
+    idx += skid_lenSz;
+
+    /* put value */
+    XMEMCPY(output+idx, input, length);
+    idx += length;
+
+    return idx;
+}
+
+/* encode Authority Key Identifier, return total bytes written
+ * RFC5280 : non-critical */
+static int SetAKID(byte* output, word32 outSz,
+                                         byte *input, word32 length, void* heap)
+{
+    byte    *enc_val;
+    int     ret, enc_valSz;
+    const byte akid_oid[] = { 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04 };
+    const byte akid_cs[] = { 0x80 };
+
+    (void)heap;
+
+    if (output == NULL || input == NULL)
+        return BAD_FUNC_ARG;
+
+    enc_valSz = length + 3 + sizeof(akid_cs);
+    enc_val = (byte *)XMALLOC(enc_valSz, heap, DYNAMIC_TYPE_TMP_BUFFER);
+    if (enc_val == NULL)
+        return MEMORY_E;
+
+    /* sequence for ContentSpec & value */
+    ret = SetOidValue(enc_val, enc_valSz, akid_cs, sizeof(akid_cs),
+                      input, length);
+    if (ret > 0) {
+        enc_valSz = ret;
+
+        ret = SetOidValue(output, outSz, akid_oid, sizeof(akid_oid),
+                          enc_val, enc_valSz);
+    }
+
+    XFREE(enc_val, heap, DYNAMIC_TYPE_TMP_BUFFER);
+    return ret;
+}
+
+/* encode Key Usage, return total bytes written
+ * RFC5280 : critical */
+static int SetKeyUsage(byte* output, word32 outSz, word16 input)
+{
+    byte ku[5];
+    int  idx;
+    const byte keyusage_oid[] = { 0x06, 0x03, 0x55, 0x1d, 0x0f,
+                                         0x01, 0x01, 0xff, 0x04};
+    if (output == NULL)
+        return BAD_FUNC_ARG;
+
+    idx = SetBitString16Bit(input, ku);
+    return SetOidValue(output, outSz, keyusage_oid, sizeof(keyusage_oid),
+                       ku, idx);
+}
+
+static int SetOjectIdValue(byte* output, word32 outSz, int* idx,
+    const byte* oid, word32 oidSz)
+{
+    /* verify room */
+    if (*idx + 2 + oidSz >= outSz)
+        return ASN_PARSE_E;
+
+    *idx += SetObjectId(oidSz, &output[*idx]);
+    XMEMCPY(&output[*idx], oid, oidSz);
+    *idx += oidSz;
+
+    return 0;
+}
+
+/* encode Extended Key Usage (RFC 5280 4.2.1.12), return total bytes written */
+static int SetExtKeyUsage(Cert* cert, byte* output, word32 outSz, byte input)
+{
+    int idx = 0, oidListSz = 0, totalSz, ret = 0;
+    const byte extkeyusage_oid[] = { 0x06, 0x03, 0x55, 0x1d, 0x25 };
+
+    if (output == NULL)
+        return BAD_FUNC_ARG;
+
+    /* Skip to OID List */
+    totalSz = 2 + sizeof(extkeyusage_oid) + 4;
+    idx = totalSz;
+
+    /* Build OID List */
+    /* If any set, then just use it */
+    if (input & EXTKEYUSE_ANY) {
+        ret |= SetOjectIdValue(output, outSz, &idx,
+            extExtKeyUsageAnyOid, sizeof(extExtKeyUsageAnyOid));
+    }
+    else {
+        if (input & EXTKEYUSE_SERVER_AUTH)
+            ret |= SetOjectIdValue(output, outSz, &idx,
+                extExtKeyUsageServerAuthOid, sizeof(extExtKeyUsageServerAuthOid));
+        if (input & EXTKEYUSE_CLIENT_AUTH)
+            ret |= SetOjectIdValue(output, outSz, &idx,
+                extExtKeyUsageClientAuthOid, sizeof(extExtKeyUsageClientAuthOid));
+        if (input & EXTKEYUSE_CODESIGN)
+            ret |= SetOjectIdValue(output, outSz, &idx,
+                extExtKeyUsageCodeSigningOid, sizeof(extExtKeyUsageCodeSigningOid));
+        if (input & EXTKEYUSE_EMAILPROT)
+            ret |= SetOjectIdValue(output, outSz, &idx,
+                extExtKeyUsageEmailProtectOid, sizeof(extExtKeyUsageEmailProtectOid));
+        if (input & EXTKEYUSE_TIMESTAMP)
+            ret |= SetOjectIdValue(output, outSz, &idx,
+                extExtKeyUsageTimestampOid, sizeof(extExtKeyUsageTimestampOid));
+        if (input & EXTKEYUSE_OCSP_SIGN)
+            ret |= SetOjectIdValue(output, outSz, &idx,
+                extExtKeyUsageOcspSignOid, sizeof(extExtKeyUsageOcspSignOid));
+    #ifdef WOLFSSL_EKU_OID
+        /* iterate through OID values */
+        if (input & EXTKEYUSE_USER) {
+            int i, sz;
+            for (i = 0; i < CTC_MAX_EKU_NB; i++) {
+                sz = cert->extKeyUsageOIDSz[i];
+                if (sz > 0) {
+                    ret |= SetOjectIdValue(output, outSz, &idx,
+                        cert->extKeyUsageOID[i], sz);
+                }
+            }
+        }
+    #endif /* WOLFSSL_EKU_OID */
+    }
+    if (ret != 0)
+        return ASN_PARSE_E;
+
+    /* Calculate Sizes */
+    oidListSz = idx - totalSz;
+    totalSz = idx - 2; /* exclude first seq/len (2) */
+
+    /* 1. Seq + Total Len (2) */
+    idx = SetSequence(totalSz, output);
+
+    /* 2. Object ID (2) */
+    XMEMCPY(&output[idx], extkeyusage_oid, sizeof(extkeyusage_oid));
+    idx += sizeof(extkeyusage_oid);
+
+    /* 3. Octet String (2) */
+    idx += SetOctetString(totalSz - idx, &output[idx]);
+
+    /* 4. Seq + OidListLen (2) */
+    idx += SetSequence(oidListSz, &output[idx]);
+
+    /* 5. Oid List (already set in-place above) */
+    idx += oidListSz;
+
+    (void)cert;
+    return idx;
+}
+
+/* encode Certificate Policies, return total bytes written
+ * each input value must be ITU-T X.690 formatted : a.b.c...
+ * input must be an array of values with a NULL terminated for the latest
+ * RFC5280 : non-critical */
+static int SetCertificatePolicies(byte *output,
+                                  word32 outputSz,
+                                  char input[MAX_CERTPOL_NB][MAX_CERTPOL_SZ],
+                                  word16 nb_certpol,
+                                  void* heap)
+{
+    byte    oid[MAX_OID_SZ],
+            der_oid[MAX_CERTPOL_NB][MAX_OID_SZ],
+            out[MAX_CERTPOL_SZ];
+    word32  oidSz;
+    word32  outSz, i = 0, der_oidSz[MAX_CERTPOL_NB];
+    int     ret;
+
+    const byte certpol_oid[] = { 0x06, 0x03, 0x55, 0x1d, 0x20, 0x04 };
+    const byte oid_oid[] = { 0x06 };
+
+    if (output == NULL || input == NULL || nb_certpol > MAX_CERTPOL_NB)
+        return BAD_FUNC_ARG;
+
+    for (i = 0; i < nb_certpol; i++) {
+        oidSz = sizeof(oid);
+        XMEMSET(oid, 0, oidSz);
+
+        ret = EncodePolicyOID(oid, &oidSz, input[i], heap);
+        if (ret != 0)
+            return ret;
+
+        /* compute sequence value for the oid */
+        ret = SetOidValue(der_oid[i], MAX_OID_SZ, oid_oid,
+                          sizeof(oid_oid), oid, oidSz);
+        if (ret <= 0)
+            return ret;
+        else
+            der_oidSz[i] = (word32)ret;
+    }
+
+    /* concatenate oid, keep two byte for sequence/size of the created value */
+    for (i = 0, outSz = 2; i < nb_certpol; i++) {
+        XMEMCPY(out+outSz, der_oid[i], der_oidSz[i]);
+        outSz += der_oidSz[i];
+    }
+
+    /* add sequence */
+    ret = SetSequence(outSz-2, out);
+    if (ret <= 0)
+        return ret;
+
+    /* add Policy OID to compute final value */
+    return SetOidValue(output, outputSz, certpol_oid, sizeof(certpol_oid),
+                      out, outSz);
+}
+#endif /* WOLFSSL_CERT_EXT */
+
+
+#ifdef WOLFSSL_ALT_NAMES
+
+/* encode Alternative Names, return total bytes written */
+static int SetAltNames(byte *output, word32 outSz,
+        const byte *input, word32 length)
+{
+    byte san_len[1 + MAX_LENGTH_SZ];
+    int idx = 0, san_lenSz;
+    const byte san_oid[] = { 0x06, 0x03, 0x55, 0x1d, 0x11 };
+
+    if (output == NULL || input == NULL)
+        return BAD_FUNC_ARG;
+
+    if (outSz < length)
+        return BUFFER_E;
+
+    /* Octet String header */
+    san_lenSz = SetOctetString(length, san_len);
+
+    if (outSz < MAX_SEQ_SZ)
+        return BUFFER_E;
+
+    idx = SetSequence(length + sizeof(san_oid) + san_lenSz, output);
+
+    if ((length + sizeof(san_oid) + san_lenSz) > outSz)
+        return BUFFER_E;
+
+    /* put oid */
+    XMEMCPY(output+idx, san_oid, sizeof(san_oid));
+    idx += sizeof(san_oid);
+
+    /* put octet header */
+    XMEMCPY(output+idx, san_len, san_lenSz);
+    idx += san_lenSz;
+
+    /* put value */
+    XMEMCPY(output+idx, input, length);
+    idx += length;
+
+    return idx;
+}
+
+
+#ifdef WOLFSSL_CERT_GEN
+
+int FlattenAltNames(byte* output, word32 outputSz, const DNS_entry* names)
+{
+    word32 idx;
+    const DNS_entry* curName;
+    word32 namesSz = 0;
+
+    if (output == NULL)
+        return BAD_FUNC_ARG;
+
+    if (names == NULL)
+        return 0;
+
+    curName = names;
+    do {
+        namesSz += curName->len + 2 +
+            ((curName->len < ASN_LONG_LENGTH) ? 0
+             : BytePrecision(curName->len));
+        curName = curName->next;
+    } while (curName != NULL);
+
+    if (outputSz < MAX_SEQ_SZ + namesSz)
+        return BUFFER_E;
+
+    idx = SetSequence(namesSz, output);
+
+    curName = names;
+    do {
+        output[idx++] = ASN_CONTEXT_SPECIFIC | curName->type;
+        idx += SetLength(curName->len, output + idx);
+        XMEMCPY(output + idx, curName->name, curName->len);
+        idx += curName->len;
+        curName = curName->next;
+    } while (curName != NULL);
+
+    return idx;
+}
+
+#endif /* WOLFSSL_CERT_GEN */
+
+#endif /* WOLFSSL_ALT_NAMES */
+
+/* Encodes one attribute of the name (issuer/subject)
+ *
+ * name     structure to hold result of encoding
+ * nameStr  value to be encoded
+ * nameType type of encoding i.e CTC_UTF8
+ * type     id of attribute i.e ASN_COMMON_NAME
+ *
+ * returns length on success
+ */
+static int wc_EncodeName(EncodedName* name, const char* nameStr, char nameType,
+        byte type)
+{
+    word32 idx = 0;
+
+    if (nameStr) {
+        /* bottom up */
+        byte firstLen[1 + MAX_LENGTH_SZ];
+        byte secondLen[MAX_LENGTH_SZ];
+        byte sequence[MAX_SEQ_SZ];
+        byte set[MAX_SET_SZ];
+
+        int strLen  = (int)XSTRLEN(nameStr);
+        int thisLen = strLen;
+        int firstSz, secondSz, seqSz, setSz;
+
+        if (strLen == 0) { /* no user data for this item */
+            name->used = 0;
+            return 0;
+        }
+
+        /* Restrict country code size */
+        if (ASN_COUNTRY_NAME == type && strLen != CTC_COUNTRY_SIZE) {
+            return ASN_COUNTRY_SIZE_E;
+        }
+
+        secondSz = SetLength(strLen, secondLen);
+        thisLen += secondSz;
+        switch (type) {
+            case ASN_EMAIL_NAME: /* email */
+                thisLen += EMAIL_JOINT_LEN;
+                firstSz  = EMAIL_JOINT_LEN;
+                break;
+
+            case ASN_DOMAIN_COMPONENT:
+                thisLen += PILOT_JOINT_LEN;
+                firstSz  = PILOT_JOINT_LEN;
+                break;
+
+            default:
+                thisLen++;                                 /* str type */
+                thisLen += JOINT_LEN;
+                firstSz  = JOINT_LEN + 1;
+        }
+        thisLen++; /* id  type */
+        firstSz  = SetObjectId(firstSz, firstLen);
+        thisLen += firstSz;
+
+        seqSz = SetSequence(thisLen, sequence);
+        thisLen += seqSz;
+        setSz = SetSet(thisLen, set);
+        thisLen += setSz;
+
+        if (thisLen > (int)sizeof(name->encoded)) {
+            return BUFFER_E;
+        }
+
+        /* store it */
+        idx = 0;
+        /* set */
+        XMEMCPY(name->encoded, set, setSz);
+        idx += setSz;
+        /* seq */
+        XMEMCPY(name->encoded + idx, sequence, seqSz);
+        idx += seqSz;
+        /* asn object id */
+        XMEMCPY(name->encoded + idx, firstLen, firstSz);
+        idx += firstSz;
+        switch (type) {
+            case ASN_EMAIL_NAME:
+                {
+                    const byte EMAIL_OID[] = { 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,
+                                       0x01, 0x09, 0x01, 0x16 };
+                    /* email joint id */
+                    XMEMCPY(name->encoded + idx, EMAIL_OID, sizeof(EMAIL_OID));
+                    idx += (int)sizeof(EMAIL_OID);
+                }
+                break;
+
+            case ASN_DOMAIN_COMPONENT:
+                {
+                    const byte PILOT_OID[] = { 0x09, 0x92, 0x26, 0x89,
+                                    0x93, 0xF2, 0x2C, 0x64, 0x01
+                    };
+
+                    XMEMCPY(name->encoded + idx, PILOT_OID,
+                                                     sizeof(PILOT_OID));
+                    idx += (int)sizeof(PILOT_OID);
+                    /* id type */
+                    name->encoded[idx++] = type;
+                    /* str type */
+                    name->encoded[idx++] = nameType;
+                }
+                break;
+
+            default:
+                name->encoded[idx++] = 0x55;
+                name->encoded[idx++] = 0x04;
+                /* id type */
+                name->encoded[idx++] = type;
+                /* str type */
+                name->encoded[idx++] = nameType;
+        }
+        /* second length */
+        XMEMCPY(name->encoded + idx, secondLen, secondSz);
+        idx += secondSz;
+        /* str value */
+        XMEMCPY(name->encoded + idx, nameStr, strLen);
+        idx += strLen;
+
+        name->type = type;
+        name->totalLen = idx;
+        name->used = 1;
+    }
+    else
+        name->used = 0;
+
+    return idx;
+}
+
+/* encode CertName into output, return total bytes written */
+int SetName(byte* output, word32 outputSz, CertName* name)
+{
+    int          totalBytes = 0, i, idx;
+#ifdef WOLFSSL_SMALL_STACK
+    EncodedName* names = NULL;
+#else
+    EncodedName  names[NAME_ENTRIES];
+#endif
+#ifdef WOLFSSL_MULTI_ATTRIB
+    EncodedName addNames[CTC_MAX_ATTRIB];
+    int j, type;
+#endif
+
+    if (output == NULL || name == NULL)
+        return BAD_FUNC_ARG;
+
+    if (outputSz < 3)
+        return BUFFER_E;
+
+#ifdef WOLFSSL_SMALL_STACK
+    names = (EncodedName*)XMALLOC(sizeof(EncodedName) * NAME_ENTRIES, NULL,
+                                                       DYNAMIC_TYPE_TMP_BUFFER);
+    if (names == NULL)
+        return MEMORY_E;
+#endif
+
+    for (i = 0; i < NAME_ENTRIES; i++) {
+        int ret;
+        const char* nameStr = GetOneName(name, i);
+
+        ret = wc_EncodeName(&names[i], nameStr, GetNameType(name, i),
+                          GetNameId(i));
+        if (ret < 0) {
+        #ifdef WOLFSSL_SMALL_STACK
+                XFREE(names, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+        #endif
+                return BUFFER_E;
+        }
+        totalBytes += ret;
+    }
+#ifdef WOLFSSL_MULTI_ATTRIB
+    for (i = 0; i < CTC_MAX_ATTRIB; i++) {
+        if (name->name[i].sz > 0) {
+            int ret;
+            ret = wc_EncodeName(&addNames[i], name->name[i].value,
+                        name->name[i].type, name->name[i].id);
+            if (ret < 0) {
+            #ifdef WOLFSSL_SMALL_STACK
+                XFREE(names, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+            #endif
+                return BUFFER_E;
+            }
+            totalBytes += ret;
+        }
+        else {
+            addNames[i].used = 0;
+        }
+    }
+#endif /* WOLFSSL_MULTI_ATTRIB */
+
+    /* header */
+    idx = SetSequence(totalBytes, output);
+    totalBytes += idx;
+    if (totalBytes > ASN_NAME_MAX) {
+#ifdef WOLFSSL_SMALL_STACK
+        XFREE(names, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+#endif
+        return BUFFER_E;
+    }
+
+    for (i = 0; i < NAME_ENTRIES; i++) {
+    #ifdef WOLFSSL_MULTI_ATTRIB
+        type = GetNameId(i);
+
+        /* list all DC values before OUs */
+        if (type == ASN_ORGUNIT_NAME) {
+            type = ASN_DOMAIN_COMPONENT;
+            for (j = 0; j < CTC_MAX_ATTRIB; j++) {
+                if (name->name[j].sz > 0 && type == name->name[j].id) {
+                    if (outputSz < (word32)(idx+addNames[j].totalLen)) {
+                    #ifdef WOLFSSL_SMALL_STACK
+                        XFREE(names, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+                    #endif
+                        return BUFFER_E;
+                    }
+
+                    XMEMCPY(output + idx, addNames[j].encoded,
+                            addNames[j].totalLen);
+                    idx += addNames[j].totalLen;
+                }
+            }
+            type = ASN_ORGUNIT_NAME;
+        }
+
+        /* write all similar types to the buffer */
+        for (j = 0; j < CTC_MAX_ATTRIB; j++) {
+            if (name->name[j].sz > 0 && type == name->name[j].id) {
+                if (outputSz < (word32)(idx+addNames[j].totalLen)) {
+                #ifdef WOLFSSL_SMALL_STACK
+                    XFREE(names, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+                #endif
+                    return BUFFER_E;
+                }
+
+                XMEMCPY(output + idx, addNames[j].encoded,
+                        addNames[j].totalLen);
+                idx += addNames[j].totalLen;
+            }
+        }
+    #endif /* WOLFSSL_MULTI_ATTRIB */
+
+        if (names[i].used) {
+            if (outputSz < (word32)(idx+names[i].totalLen)) {
+#ifdef WOLFSSL_SMALL_STACK
+                XFREE(names, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+#endif
+                return BUFFER_E;
+            }
+
+            XMEMCPY(output + idx, names[i].encoded, names[i].totalLen);
+            idx += names[i].totalLen;
+        }
+    }
+
+#ifdef WOLFSSL_SMALL_STACK
+    XFREE(names, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+#endif
+
+    return totalBytes;
+}
+
+/* encode info from cert into DER encoded format */
+static int EncodeCert(Cert* cert, DerCert* der, RsaKey* rsaKey, ecc_key* eccKey,
+                      WC_RNG* rng, const byte* ntruKey, word16 ntruSz,
+                      ed25519_key* ed25519Key, ed448_key* ed448Key)
+{
+    int ret;
+
+    if (cert == NULL || der == NULL || rng == NULL)
+        return BAD_FUNC_ARG;
+
+    /* make sure at least one key type is provided */
+    if (rsaKey == NULL && eccKey == NULL && ed25519Key == NULL &&
+                                          ed448Key == NULL && ntruKey == NULL) {
+        return PUBLIC_KEY_E;
+    }
+
+    /* init */
+    XMEMSET(der, 0, sizeof(DerCert));
+
+    /* version */
+    der->versionSz = SetMyVersion(cert->version, der->version, TRUE);
+
+    /* serial number (must be positive) */
+    if (cert->serialSz == 0) {
+        /* generate random serial */
+        cert->serialSz = CTC_GEN_SERIAL_SZ;
+        ret = wc_RNG_GenerateBlock(rng, cert->serial, cert->serialSz);
+        if (ret != 0)
+            return ret;
+        /* Clear the top bit to avoid a negative value */
+        cert->serial[0] &= 0x7f;
+    }
+    der->serialSz = SetSerialNumber(cert->serial, cert->serialSz, der->serial,
+        sizeof(der->serial), CTC_SERIAL_SIZE);
+    if (der->serialSz < 0)
+        return der->serialSz;
+
+    /* signature algo */
+    der->sigAlgoSz = SetAlgoID(cert->sigType, der->sigAlgo, oidSigType, 0);
+    if (der->sigAlgoSz <= 0)
+        return ALGO_ID_E;
+
+    /* public key */
+#ifndef NO_RSA
+    if (cert->keyType == RSA_KEY) {
+        if (rsaKey == NULL)
+            return PUBLIC_KEY_E;
+        der->publicKeySz = SetRsaPublicKey(der->publicKey, rsaKey,
+                                           sizeof(der->publicKey), 1);
+    }
+#endif
+
+#ifdef HAVE_ECC
+    if (cert->keyType == ECC_KEY) {
+        if (eccKey == NULL)
+            return PUBLIC_KEY_E;
+        der->publicKeySz = SetEccPublicKey(der->publicKey, eccKey, 1);
+    }
+#endif
+
+#ifdef HAVE_ED25519
+    if (cert->keyType == ED25519_KEY) {
+        if (ed25519Key == NULL)
+            return PUBLIC_KEY_E;
+        der->publicKeySz = SetEd25519PublicKey(der->publicKey, ed25519Key, 1);
+    }
+#endif
+
+#ifdef HAVE_ED448
+    if (cert->keyType == ED448_KEY) {
+        if (ed448Key == NULL)
+            return PUBLIC_KEY_E;
+        der->publicKeySz = SetEd448PublicKey(der->publicKey, ed448Key, 1);
+    }
+#endif
+
+#ifdef HAVE_NTRU
+    if (cert->keyType == NTRU_KEY) {
+        word32 rc;
+        word16 encodedSz;
+
+        if (ntruKey == NULL)
+            return PUBLIC_KEY_E;
+
+        rc  = ntru_crypto_ntru_encrypt_publicKey2SubjectPublicKeyInfo(ntruSz,
+                                                   ntruKey, &encodedSz, NULL);
+        if (rc != NTRU_OK)
+            return PUBLIC_KEY_E;
+        if (encodedSz > MAX_PUBLIC_KEY_SZ)
+            return PUBLIC_KEY_E;
+
+        rc  = ntru_crypto_ntru_encrypt_publicKey2SubjectPublicKeyInfo(ntruSz,
+                                         ntruKey, &encodedSz, der->publicKey);
+        if (rc != NTRU_OK)
+            return PUBLIC_KEY_E;
+
+        der->publicKeySz = encodedSz;
+    }
+#else
+    (void)ntruSz;
+#endif /* HAVE_NTRU */
+
+    if (der->publicKeySz <= 0)
+        return PUBLIC_KEY_E;
+
+    der->validitySz = 0;
+#ifdef WOLFSSL_ALT_NAMES
+    /* date validity copy ? */
+    if (cert->beforeDateSz && cert->afterDateSz) {
+        der->validitySz = CopyValidity(der->validity, cert);
+        if (der->validitySz <= 0)
+            return DATE_E;
+    }
+#endif
+
+    /* date validity */
+    if (der->validitySz == 0) {
+        der->validitySz = SetValidity(der->validity, cert->daysValid);
+        if (der->validitySz <= 0)
+            return DATE_E;
+    }
+
+    /* subject name */
+#ifdef WOLFSSL_CERT_EXT
+    if (XSTRLEN((const char*)cert->sbjRaw) > 0) {
+        /* Use the raw subject */
+        int idx;
+
+        der->subjectSz = min(sizeof(der->subject),
+                (word32)XSTRLEN((const char*)cert->sbjRaw));
+        /* header */
+        idx = SetSequence(der->subjectSz, der->subject);
+        if (der->subjectSz + idx > (int)sizeof(der->subject)) {
+            return SUBJECT_E;
+        }
+
+        XMEMCPY((char*)der->subject + idx, (const char*)cert->sbjRaw,
+                der->subjectSz);
+        der->subjectSz += idx;
+    }
+    else
+#endif
+    {
+        /* Use the name structure */
+        der->subjectSz = SetName(der->subject, sizeof(der->subject),
+                &cert->subject);
+    }
+    if (der->subjectSz <= 0)
+        return SUBJECT_E;
+
+    /* issuer name */
+#ifdef WOLFSSL_CERT_EXT
+    if (XSTRLEN((const char*)cert->issRaw) > 0) {
+        /* Use the raw issuer */
+        int idx;
+
+        der->issuerSz = min(sizeof(der->issuer),
+                (word32)XSTRLEN((const char*)cert->issRaw));
+        /* header */
+        idx = SetSequence(der->issuerSz, der->issuer);
+        if (der->issuerSz + idx > (int)sizeof(der->issuer)) {
+            return ISSUER_E;
+        }
+
+        XMEMCPY((char*)der->issuer + idx, (const char*)cert->issRaw,
+                der->issuerSz);
+        der->issuerSz += idx;
+    }
+    else
+#endif
+    {
+        /* Use the name structure */
+        der->issuerSz = SetName(der->issuer, sizeof(der->issuer),
+                cert->selfSigned ? &cert->subject : &cert->issuer);
+    }
+    if (der->issuerSz <= 0)
+        return ISSUER_E;
+
+    /* set the extensions */
+    der->extensionsSz = 0;
+
+    /* CA */
+    if (cert->isCA) {
+        der->caSz = SetCa(der->ca, sizeof(der->ca));
+        if (der->caSz <= 0)
+            return CA_TRUE_E;
+
+        der->extensionsSz += der->caSz;
+    }
+    else
+        der->caSz = 0;
+
+#ifdef WOLFSSL_ALT_NAMES
+    /* Alternative Name */
+    if (cert->altNamesSz) {
+        der->altNamesSz = SetAltNames(der->altNames, sizeof(der->altNames),
+                                      cert->altNames, cert->altNamesSz);
+        if (der->altNamesSz <= 0)
+            return ALT_NAME_E;
+
+        der->extensionsSz += der->altNamesSz;
+    }
+    else
+        der->altNamesSz = 0;
+#endif
+
+#ifdef WOLFSSL_CERT_EXT
+    /* SKID */
+    if (cert->skidSz) {
+        /* check the provided SKID size */
+        if (cert->skidSz > (int)min(CTC_MAX_SKID_SIZE, sizeof(der->skid)))
+            return SKID_E;
+
+        /* Note: different skid buffers sizes for der (MAX_KID_SZ) and
+            cert (CTC_MAX_SKID_SIZE). */
+        der->skidSz = SetSKID(der->skid, sizeof(der->skid),
+                              cert->skid, cert->skidSz);
+        if (der->skidSz <= 0)
+            return SKID_E;
+
+        der->extensionsSz += der->skidSz;
+    }
+    else
+        der->skidSz = 0;
+
+    /* AKID */
+    if (cert->akidSz) {
+        /* check the provided AKID size */
+        if (cert->akidSz > (int)min(CTC_MAX_AKID_SIZE, sizeof(der->akid)))
+            return AKID_E;
+
+        der->akidSz = SetAKID(der->akid, sizeof(der->akid),
+                              cert->akid, cert->akidSz, cert->heap);
+        if (der->akidSz <= 0)
+            return AKID_E;
+
+        der->extensionsSz += der->akidSz;
+    }
+    else
+        der->akidSz = 0;
+
+    /* Key Usage */
+    if (cert->keyUsage != 0){
+        der->keyUsageSz = SetKeyUsage(der->keyUsage, sizeof(der->keyUsage),
+                                      cert->keyUsage);
+        if (der->keyUsageSz <= 0)
+            return KEYUSAGE_E;
+
+        der->extensionsSz += der->keyUsageSz;
+    }
+    else
+        der->keyUsageSz = 0;
+
+    /* Extended Key Usage */
+    if (cert->extKeyUsage != 0){
+        der->extKeyUsageSz = SetExtKeyUsage(cert, der->extKeyUsage,
+                                sizeof(der->extKeyUsage), cert->extKeyUsage);
+        if (der->extKeyUsageSz <= 0)
+            return EXTKEYUSAGE_E;
+
+        der->extensionsSz += der->extKeyUsageSz;
+    }
+    else
+        der->extKeyUsageSz = 0;
+
+    /* Certificate Policies */
+    if (cert->certPoliciesNb != 0) {
+        der->certPoliciesSz = SetCertificatePolicies(der->certPolicies,
+                                                     sizeof(der->certPolicies),
+                                                     cert->certPolicies,
+                                                     cert->certPoliciesNb,
+                                                     cert->heap);
+        if (der->certPoliciesSz <= 0)
+            return CERTPOLICIES_E;
+
+        der->extensionsSz += der->certPoliciesSz;
+    }
+    else
+        der->certPoliciesSz = 0;
+#endif /* WOLFSSL_CERT_EXT */
+
+    /* put extensions */
+    if (der->extensionsSz > 0) {
+
+        /* put the start of extensions sequence (ID, Size) */
+        der->extensionsSz = SetExtensionsHeader(der->extensions,
+                                                sizeof(der->extensions),
+                                                der->extensionsSz);
+        if (der->extensionsSz <= 0)
+            return EXTENSIONS_E;
+
+        /* put CA */
+        if (der->caSz) {
+            ret = SetExtensions(der->extensions, sizeof(der->extensions),
+                                &der->extensionsSz,
+                                der->ca, der->caSz);
+            if (ret == 0)
+                return EXTENSIONS_E;
+        }
+
+#ifdef WOLFSSL_ALT_NAMES
+        /* put Alternative Names */
+        if (der->altNamesSz) {
+            ret = SetExtensions(der->extensions, sizeof(der->extensions),
+                                &der->extensionsSz,
+                                der->altNames, der->altNamesSz);
+            if (ret <= 0)
+                return EXTENSIONS_E;
+        }
+#endif
+
+#ifdef WOLFSSL_CERT_EXT
+        /* put SKID */
+        if (der->skidSz) {
+            ret = SetExtensions(der->extensions, sizeof(der->extensions),
+                                &der->extensionsSz,
+                                der->skid, der->skidSz);
+            if (ret <= 0)
+                return EXTENSIONS_E;
+        }
+
+        /* put AKID */
+        if (der->akidSz) {
+            ret = SetExtensions(der->extensions, sizeof(der->extensions),
+                                &der->extensionsSz,
+                                der->akid, der->akidSz);
+            if (ret <= 0)
+                return EXTENSIONS_E;
+        }
+
+        /* put KeyUsage */
+        if (der->keyUsageSz) {
+            ret = SetExtensions(der->extensions, sizeof(der->extensions),
+                                &der->extensionsSz,
+                                der->keyUsage, der->keyUsageSz);
+            if (ret <= 0)
+                return EXTENSIONS_E;
+        }
+
+        /* put ExtendedKeyUsage */
+        if (der->extKeyUsageSz) {
+            ret = SetExtensions(der->extensions, sizeof(der->extensions),
+                                &der->extensionsSz,
+                                der->extKeyUsage, der->extKeyUsageSz);
+            if (ret <= 0)
+                return EXTENSIONS_E;
+        }
+
+        /* put Certificate Policies */
+        if (der->certPoliciesSz) {
+            ret = SetExtensions(der->extensions, sizeof(der->extensions),
+                                &der->extensionsSz,
+                                der->certPolicies, der->certPoliciesSz);
+            if (ret <= 0)
+                return EXTENSIONS_E;
+        }
+#endif /* WOLFSSL_CERT_EXT */
+    }
+
+    der->total = der->versionSz + der->serialSz + der->sigAlgoSz +
+        der->publicKeySz + der->validitySz + der->subjectSz + der->issuerSz +
+        der->extensionsSz;
+
+    return 0;
+}
+
+
+/* write DER encoded cert to buffer, size already checked */
+static int WriteCertBody(DerCert* der, byte* buf)
+{
+    int idx;
+
+    /* signed part header */
+    idx = SetSequence(der->total, buf);
+    /* version */
+    XMEMCPY(buf + idx, der->version, der->versionSz);
+    idx += der->versionSz;
+    /* serial */
+    XMEMCPY(buf + idx, der->serial, der->serialSz);
+    idx += der->serialSz;
+    /* sig algo */
+    XMEMCPY(buf + idx, der->sigAlgo, der->sigAlgoSz);
+    idx += der->sigAlgoSz;
+    /* issuer */
+    XMEMCPY(buf + idx, der->issuer, der->issuerSz);
+    idx += der->issuerSz;
+    /* validity */
+    XMEMCPY(buf + idx, der->validity, der->validitySz);
+    idx += der->validitySz;
+    /* subject */
+    XMEMCPY(buf + idx, der->subject, der->subjectSz);
+    idx += der->subjectSz;
+    /* public key */
+    XMEMCPY(buf + idx, der->publicKey, der->publicKeySz);
+    idx += der->publicKeySz;
+    if (der->extensionsSz) {
+        /* extensions */
+        XMEMCPY(buf + idx, der->extensions, min(der->extensionsSz,
+                                                   (int)sizeof(der->extensions)));
+        idx += der->extensionsSz;
+    }
+
+    return idx;
+}
+
+
+/* Make RSA signature from buffer (sz), write to sig (sigSz) */
+static int MakeSignature(CertSignCtx* certSignCtx, const byte* buf, int sz,
+    byte* sig, int sigSz, RsaKey* rsaKey, ecc_key* eccKey,
+    ed25519_key* ed25519Key, ed448_key* ed448Key, WC_RNG* rng, int sigAlgoType,
+    void* heap)
+{
+    int digestSz = 0, typeH = 0, ret = 0;
+
+    (void)digestSz;
+    (void)typeH;
+    (void)buf;
+    (void)sz;
+    (void)sig;
+    (void)sigSz;
+    (void)rsaKey;
+    (void)eccKey;
+    (void)ed25519Key;
+    (void)ed448Key;
+    (void)rng;
+    (void)heap;
+
+    switch (certSignCtx->state) {
+    case CERTSIGN_STATE_BEGIN:
+    case CERTSIGN_STATE_DIGEST:
+
+        certSignCtx->state = CERTSIGN_STATE_DIGEST;
+        certSignCtx->digest = (byte*)XMALLOC(WC_MAX_DIGEST_SIZE, heap,
+            DYNAMIC_TYPE_TMP_BUFFER);
+        if (certSignCtx->digest == NULL) {
+            ret = MEMORY_E; goto exit_ms;
+        }
+
+        ret = HashForSignature(buf, sz, sigAlgoType, certSignCtx->digest,
+                               &typeH, &digestSz, 0);
+        /* set next state, since WC_PENDING_E rentry for these are not "call again" */
+        certSignCtx->state = CERTSIGN_STATE_ENCODE;
+        if (ret != 0) {
+            goto exit_ms;
+        }
+        FALL_THROUGH;
+
+    case CERTSIGN_STATE_ENCODE:
+    #ifndef NO_RSA
+        if (rsaKey) {
+            certSignCtx->encSig = (byte*)XMALLOC(MAX_DER_DIGEST_SZ, heap,
+                DYNAMIC_TYPE_TMP_BUFFER);
+            if (certSignCtx->encSig == NULL) {
+                ret = MEMORY_E; goto exit_ms;
+            }
+
+            /* signature */
+            certSignCtx->encSigSz = wc_EncodeSignature(certSignCtx->encSig,
+                                          certSignCtx->digest, digestSz, typeH);
+        }
+    #endif /* !NO_RSA */
+        FALL_THROUGH;
+
+    case CERTSIGN_STATE_DO:
+        certSignCtx->state = CERTSIGN_STATE_DO;
+        ret = ALGO_ID_E; /* default to error */
+
+    #ifndef NO_RSA
+        if (rsaKey) {
+            /* signature */
+            ret = wc_RsaSSL_Sign(certSignCtx->encSig, certSignCtx->encSigSz,
+                                 sig, sigSz, rsaKey, rng);
+        }
+    #endif /* !NO_RSA */
+
+    #ifdef HAVE_ECC
+        if (!rsaKey && eccKey) {
+            word32 outSz = sigSz;
+
+            ret = wc_ecc_sign_hash(certSignCtx->digest, digestSz,
+                                   sig, &outSz, rng, eccKey);
+            if (ret == 0)
+                ret = outSz;
+        }
+    #endif /* HAVE_ECC */
+
+    #ifdef HAVE_ED25519
+        if (!rsaKey && !eccKey && ed25519Key) {
+            word32 outSz = sigSz;
+
+            ret = wc_ed25519_sign_msg(buf, sz, sig, &outSz, ed25519Key);
+            if (ret == 0)
+                ret = outSz;
+        }
+    #endif /* HAVE_ECC */
+
+    #ifdef HAVE_ED448
+        if (!rsaKey && !eccKey && !ed25519Key && ed448Key) {
+            word32 outSz = sigSz;
+
+            ret = wc_ed448_sign_msg(buf, sz, sig, &outSz, ed448Key, NULL, 0);
+            if (ret == 0)
+                ret = outSz;
+        }
+    #endif /* HAVE_ECC */
+        break;
+    }
+
+exit_ms:
+
+#ifdef WOLFSSL_ASYNC_CRYPT
+    if (ret == WC_PENDING_E) {
+        return ret;
+    }
+#endif
+
+#ifndef NO_RSA
+    if (rsaKey) {
+        XFREE(certSignCtx->encSig, heap, DYNAMIC_TYPE_TMP_BUFFER);
+    }
+#endif /* !NO_RSA */
+
+    XFREE(certSignCtx->digest, heap, DYNAMIC_TYPE_TMP_BUFFER);
+    certSignCtx->digest = NULL;
+
+    /* reset state */
+    certSignCtx->state = CERTSIGN_STATE_BEGIN;
+
+    return ret;
+}
+
+
+/* add signature to end of buffer, size of buffer assumed checked, return
+   new length */
+static int AddSignature(byte* buf, int bodySz, const byte* sig, int sigSz,
+                        int sigAlgoType)
+{
+    byte seq[MAX_SEQ_SZ];
+    int  idx = bodySz, seqSz;
+
+    /* algo */
+    idx += SetAlgoID(sigAlgoType, buf ? buf + idx : NULL, oidSigType, 0);
+    /* bit string */
+    idx += SetBitString(sigSz, 0, buf ? buf + idx : NULL);
+    /* signature */
+    if (buf)
+        XMEMCPY(buf + idx, sig, sigSz);
+    idx += sigSz;
+
+    /* make room for overall header */
+    seqSz = SetSequence(idx, seq);
+    if (buf) {
+        XMEMMOVE(buf + seqSz, buf, idx);
+        XMEMCPY(buf, seq, seqSz);
+    }
+
+    return idx + seqSz;
+}
+
+
+/* Make an x509 Certificate v3 any key type from cert input, write to buffer */
+static int MakeAnyCert(Cert* cert, byte* derBuffer, word32 derSz,
+                       RsaKey* rsaKey, ecc_key* eccKey, WC_RNG* rng,
+                       const byte* ntruKey, word16 ntruSz,
+                       ed25519_key* ed25519Key, ed448_key* ed448Key)
+{
+    int ret;
+#ifdef WOLFSSL_SMALL_STACK
+    DerCert* der;
+#else
+    DerCert der[1];
+#endif
+
+    if (derBuffer == NULL) {
+        return BAD_FUNC_ARG;
+    }
+
+    cert->keyType = eccKey ? ECC_KEY : (rsaKey ? RSA_KEY :
+            (ed25519Key ? ED25519_KEY : (ed448Key ? ED448_KEY : NTRU_KEY)));
+
+#ifdef WOLFSSL_SMALL_STACK
+    der = (DerCert*)XMALLOC(sizeof(DerCert), cert->heap, DYNAMIC_TYPE_TMP_BUFFER);
+    if (der == NULL)
+        return MEMORY_E;
+#endif
+
+    ret = EncodeCert(cert, der, rsaKey, eccKey, rng, ntruKey, ntruSz,
+                     ed25519Key, ed448Key);
+    if (ret == 0) {
+        if (der->total + MAX_SEQ_SZ * 2 > (int)derSz)
+            ret = BUFFER_E;
+        else
+            ret = cert->bodySz = WriteCertBody(der, derBuffer);
+    }
+
+#ifdef WOLFSSL_SMALL_STACK
+    XFREE(der, cert->heap, DYNAMIC_TYPE_TMP_BUFFER);
+#endif
+
+    return ret;
+}
+
+
+/* Make an x509 Certificate v3 RSA or ECC from cert input, write to buffer */
+int wc_MakeCert_ex(Cert* cert, byte* derBuffer, word32 derSz, int keyType,
+                   void* key, WC_RNG* rng)
+{
+    RsaKey*      rsaKey = NULL;
+    ecc_key*     eccKey = NULL;
+    ed25519_key* ed25519Key = NULL;
+    ed448_key*   ed448Key = NULL;
+
+    if (keyType == RSA_TYPE)
+        rsaKey = (RsaKey*)key;
+    else if (keyType == ECC_TYPE)
+        eccKey = (ecc_key*)key;
+    else if (keyType == ED25519_TYPE)
+        ed25519Key = (ed25519_key*)key;
+    else if (keyType == ED448_TYPE)
+        ed448Key = (ed448_key*)key;
+
+    return MakeAnyCert(cert, derBuffer, derSz, rsaKey, eccKey, rng, NULL, 0,
+                       ed25519Key, ed448Key);
+}
+/* Make an x509 Certificate v3 RSA or ECC from cert input, write to buffer */
+int wc_MakeCert(Cert* cert, byte* derBuffer, word32 derSz, RsaKey* rsaKey,
+             ecc_key* eccKey, WC_RNG* rng)
+{
+    return MakeAnyCert(cert, derBuffer, derSz, rsaKey, eccKey, rng, NULL, 0,
+                       NULL, NULL);
+}
+
+
+#ifdef HAVE_NTRU
+
+int wc_MakeNtruCert(Cert* cert, byte* derBuffer, word32 derSz,
+                  const byte* ntruKey, word16 keySz, WC_RNG* rng)
+{
+    return MakeAnyCert(cert, derBuffer, derSz, NULL, NULL, rng, ntruKey, keySz, NULL);
+}
+
+#endif /* HAVE_NTRU */
+
+
+#ifdef WOLFSSL_CERT_REQ
+
+static int SetReqAttrib(byte* output, char* pw, int pwPrintableString,
+                        int extSz)
+{
+    const byte cpOid[] =
+        { ASN_OBJECT_ID, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01,
+                         0x09, 0x07 };
+    const byte erOid[] =
+        { ASN_OBJECT_ID, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01,
+                         0x09, 0x0e };
+
+    int sz      = 0; /* overall size */
+    int cpSz    = 0; /* Challenge Password section size */
+    int cpSeqSz = 0;
+    int cpSetSz = 0;
+    int cpStrSz = 0;
+    int pwSz    = 0;
+    int erSz    = 0; /* Extension Request section size */
+    int erSeqSz = 0;
+    int erSetSz = 0;
+    byte cpSeq[MAX_SEQ_SZ];
+    byte cpSet[MAX_SET_SZ];
+    byte cpStr[MAX_PRSTR_SZ];
+    byte erSeq[MAX_SEQ_SZ];
+    byte erSet[MAX_SET_SZ];
+
+    output[0] = 0xa0;
+    sz++;
+
+    if (pw && pw[0]) {
+        pwSz = (int)XSTRLEN(pw);
+        if (pwPrintableString) {
+            cpStrSz = SetPrintableString(pwSz, cpStr);
+        } else {
+            cpStrSz = SetUTF8String(pwSz, cpStr);
+        }
+        cpSetSz = SetSet(cpStrSz + pwSz, cpSet);
+        cpSeqSz = SetSequence(sizeof(cpOid) + cpSetSz + cpStrSz + pwSz, cpSeq);
+        cpSz = cpSeqSz + sizeof(cpOid) + cpSetSz + cpStrSz + pwSz;
+    }
+
+    if (extSz) {
+        erSetSz = SetSet(extSz, erSet);
+        erSeqSz = SetSequence(erSetSz + sizeof(erOid) + extSz, erSeq);
+        erSz = extSz + erSetSz + erSeqSz + sizeof(erOid);
+    }
+
+    /* Put the pieces together. */
+    sz += SetLength(cpSz + erSz, &output[sz]);
+
+    if (cpSz) {
+        XMEMCPY(&output[sz], cpSeq, cpSeqSz);
+        sz += cpSeqSz;
+        XMEMCPY(&output[sz], cpOid, sizeof(cpOid));
+        sz += sizeof(cpOid);
+        XMEMCPY(&output[sz], cpSet, cpSetSz);
+        sz += cpSetSz;
+        XMEMCPY(&output[sz], cpStr, cpStrSz);
+        sz += cpStrSz;
+        XMEMCPY(&output[sz], pw, pwSz);
+        sz += pwSz;
+    }
+
+    if (erSz) {
+        XMEMCPY(&output[sz], erSeq, erSeqSz);
+        sz += erSeqSz;
+        XMEMCPY(&output[sz], erOid, sizeof(erOid));
+        sz += sizeof(erOid);
+        XMEMCPY(&output[sz], erSet, erSetSz);
+        sz += erSetSz;
+        /* The actual extension data will be tacked onto the output later. */
+    }
+
+    return sz;
+}
+
+
+/* encode info from cert into DER encoded format */
+static int EncodeCertReq(Cert* cert, DerCert* der, RsaKey* rsaKey,
+                         ecc_key* eccKey, ed25519_key* ed25519Key,
+                         ed448_key* ed448Key)
+{
+    (void)eccKey;
+    (void)ed25519Key;
+    (void)ed448Key;
+
+    if (cert == NULL || der == NULL)
+        return BAD_FUNC_ARG;
+
+    if (rsaKey == NULL && eccKey == NULL && ed25519Key == NULL &&
+                                                             ed448Key == NULL) {
+            return PUBLIC_KEY_E;
+    }
+
+    /* init */
+    XMEMSET(der, 0, sizeof(DerCert));
+
+    /* version */
+    der->versionSz = SetMyVersion(cert->version, der->version, FALSE);
+
+    /* subject name */
+    der->subjectSz = SetName(der->subject, sizeof(der->subject), &cert->subject);
+    if (der->subjectSz <= 0)
+        return SUBJECT_E;
+
+    /* public key */
+#ifndef NO_RSA
+    if (cert->keyType == RSA_KEY) {
+        if (rsaKey == NULL)
+            return PUBLIC_KEY_E;
+        der->publicKeySz = SetRsaPublicKey(der->publicKey, rsaKey,
+                                           sizeof(der->publicKey), 1);
+    }
+#endif
+
+#ifdef HAVE_ECC
+    if (cert->keyType == ECC_KEY) {
+        der->publicKeySz = SetEccPublicKey(der->publicKey, eccKey, 1);
+    }
+#endif
+
+#ifdef HAVE_ED25519
+    if (cert->keyType == ED25519_KEY) {
+        if (ed25519Key == NULL)
+            return PUBLIC_KEY_E;
+        der->publicKeySz = SetEd25519PublicKey(der->publicKey, ed25519Key, 1);
+    }
+#endif
+
+#ifdef HAVE_ED448
+    if (cert->keyType == ED448_KEY) {
+        if (ed448Key == NULL)
+            return PUBLIC_KEY_E;
+        der->publicKeySz = SetEd448PublicKey(der->publicKey, ed448Key, 1);
+    }
+#endif
+    if (der->publicKeySz <= 0)
+        return PUBLIC_KEY_E;
+
+    /* set the extensions */
+    der->extensionsSz = 0;
+
+    /* CA */
+    if (cert->isCA) {
+        der->caSz = SetCa(der->ca, sizeof(der->ca));
+        if (der->caSz <= 0)
+            return CA_TRUE_E;
+
+        der->extensionsSz += der->caSz;
+    }
+    else
+        der->caSz = 0;
+
+#ifdef WOLFSSL_CERT_EXT
+    /* SKID */
+    if (cert->skidSz) {
+        /* check the provided SKID size */
+        if (cert->skidSz > (int)min(CTC_MAX_SKID_SIZE, sizeof(der->skid)))
+            return SKID_E;
+
+        der->skidSz = SetSKID(der->skid, sizeof(der->skid),
+                              cert->skid, cert->skidSz);
+        if (der->skidSz <= 0)
+            return SKID_E;
+
+        der->extensionsSz += der->skidSz;
+    }
+    else
+        der->skidSz = 0;
+
+    /* Key Usage */
+    if (cert->keyUsage != 0){
+        der->keyUsageSz = SetKeyUsage(der->keyUsage, sizeof(der->keyUsage),
+                                      cert->keyUsage);
+        if (der->keyUsageSz <= 0)
+            return KEYUSAGE_E;
+
+        der->extensionsSz += der->keyUsageSz;
+    }
+    else
+        der->keyUsageSz = 0;
+
+    /* Extended Key Usage */
+    if (cert->extKeyUsage != 0){
+        der->extKeyUsageSz = SetExtKeyUsage(cert, der->extKeyUsage,
+                                sizeof(der->extKeyUsage), cert->extKeyUsage);
+        if (der->extKeyUsageSz <= 0)
+            return EXTKEYUSAGE_E;
+
+        der->extensionsSz += der->extKeyUsageSz;
+    }
+    else
+        der->extKeyUsageSz = 0;
+
+#endif /* WOLFSSL_CERT_EXT */
+
+    /* put extensions */
+    if (der->extensionsSz > 0) {
+        int ret;
+
+        /* put the start of sequence (ID, Size) */
+        der->extensionsSz = SetSequence(der->extensionsSz, der->extensions);
+        if (der->extensionsSz <= 0)
+            return EXTENSIONS_E;
+
+        /* put CA */
+        if (der->caSz) {
+            ret = SetExtensions(der->extensions, sizeof(der->extensions),
+                                &der->extensionsSz,
+                                der->ca, der->caSz);
+            if (ret <= 0)
+                return EXTENSIONS_E;
+        }
+
+#ifdef WOLFSSL_CERT_EXT
+        /* put SKID */
+        if (der->skidSz) {
+            ret = SetExtensions(der->extensions, sizeof(der->extensions),
+                                &der->extensionsSz,
+                                der->skid, der->skidSz);
+            if (ret <= 0)
+                return EXTENSIONS_E;
+        }
+
+        /* put AKID */
+        if (der->akidSz) {
+            ret = SetExtensions(der->extensions, sizeof(der->extensions),
+                                &der->extensionsSz,
+                                der->akid, der->akidSz);
+            if (ret <= 0)
+                return EXTENSIONS_E;
+        }
+
+        /* put KeyUsage */
+        if (der->keyUsageSz) {
+            ret = SetExtensions(der->extensions, sizeof(der->extensions),
+                                &der->extensionsSz,
+                                der->keyUsage, der->keyUsageSz);
+            if (ret <= 0)
+                return EXTENSIONS_E;
+        }
+
+        /* put ExtendedKeyUsage */
+        if (der->extKeyUsageSz) {
+            ret = SetExtensions(der->extensions, sizeof(der->extensions),
+                                &der->extensionsSz,
+                                der->extKeyUsage, der->extKeyUsageSz);
+            if (ret <= 0)
+                return EXTENSIONS_E;
+        }
+
+#endif /* WOLFSSL_CERT_EXT */
+    }
+
+    der->attribSz = SetReqAttrib(der->attrib, cert->challengePw,
+                                 cert->challengePwPrintableString,
+                                 der->extensionsSz);
+    if (der->attribSz <= 0)
+        return REQ_ATTRIBUTE_E;
+
+    der->total = der->versionSz + der->subjectSz + der->publicKeySz +
+        der->extensionsSz + der->attribSz;
+
+    return 0;
+}
+
+
+/* write DER encoded cert req to buffer, size already checked */
+static int WriteCertReqBody(DerCert* der, byte* buf)
+{
+    int idx;
+
+    /* signed part header */
+    idx = SetSequence(der->total, buf);
+    /* version */
+    if (buf)
+        XMEMCPY(buf + idx, der->version, der->versionSz);
+    idx += der->versionSz;
+    /* subject */
+    if (buf)
+        XMEMCPY(buf + idx, der->subject, der->subjectSz);
+    idx += der->subjectSz;
+    /* public key */
+    if (buf)
+        XMEMCPY(buf + idx, der->publicKey, der->publicKeySz);
+    idx += der->publicKeySz;
+    /* attributes */
+    if (buf)
+        XMEMCPY(buf + idx, der->attrib, der->attribSz);
+    idx += der->attribSz;
+    /* extensions */
+    if (der->extensionsSz) {
+        if (buf)
+            XMEMCPY(buf + idx, der->extensions, min(der->extensionsSz,
+                                               (int)sizeof(der->extensions)));
+        idx += der->extensionsSz;
+    }
+
+    return idx;
+}
+
+
+static int MakeCertReq(Cert* cert, byte* derBuffer, word32 derSz,
+                   RsaKey* rsaKey, ecc_key* eccKey, ed25519_key* ed25519Key,
+                   ed448_key* ed448Key)
+{
+    int ret;
+#ifdef WOLFSSL_SMALL_STACK
+    DerCert* der;
+#else
+    DerCert der[1];
+#endif
+
+    cert->keyType = eccKey ? ECC_KEY : (ed25519Key ? ED25519_KEY :
+                                       (ed448Key ? ED448_KEY: RSA_KEY));
+
+#ifdef WOLFSSL_SMALL_STACK
+    der = (DerCert*)XMALLOC(sizeof(DerCert), cert->heap,
+                                                    DYNAMIC_TYPE_TMP_BUFFER);
+    if (der == NULL)
+        return MEMORY_E;
+#endif
+
+    ret = EncodeCertReq(cert, der, rsaKey, eccKey, ed25519Key, ed448Key);
+
+    if (ret == 0) {
+        if (der->total + MAX_SEQ_SZ * 2 > (int)derSz)
+            ret = BUFFER_E;
+        else
+            ret = cert->bodySz = WriteCertReqBody(der, derBuffer);
+    }
+
+#ifdef WOLFSSL_SMALL_STACK
+    XFREE(der, cert->heap, DYNAMIC_TYPE_TMP_BUFFER);
+#endif
+
+    return ret;
+}
+
+int wc_MakeCertReq_ex(Cert* cert, byte* derBuffer, word32 derSz, int keyType,
+                      void* key)
+{
+    RsaKey*      rsaKey = NULL;
+    ecc_key*     eccKey = NULL;
+    ed25519_key* ed25519Key = NULL;
+    ed448_key*   ed448Key = NULL;
+
+    if (keyType == RSA_TYPE)
+        rsaKey = (RsaKey*)key;
+    else if (keyType == ECC_TYPE)
+        eccKey = (ecc_key*)key;
+    else if (keyType == ED25519_TYPE)
+        ed25519Key = (ed25519_key*)key;
+    else if (keyType == ED448_TYPE)
+        ed448Key = (ed448_key*)key;
+
+    return MakeCertReq(cert, derBuffer, derSz, rsaKey, eccKey, ed25519Key,
+                       ed448Key);
+}
+
+int wc_MakeCertReq(Cert* cert, byte* derBuffer, word32 derSz,
+                   RsaKey* rsaKey, ecc_key* eccKey)
+{
+    return MakeCertReq(cert, derBuffer, derSz, rsaKey, eccKey, NULL, NULL);
+}
+#endif /* WOLFSSL_CERT_REQ */
+
+
+static int SignCert(int requestSz, int sType, byte* buf, word32 buffSz,
+                    RsaKey* rsaKey, ecc_key* eccKey, ed25519_key* ed25519Key,
+                    ed448_key* ed448Key, WC_RNG* rng)
+{
+    int sigSz = 0;
+    void* heap = NULL;
+    CertSignCtx* certSignCtx;
+#ifndef WOLFSSL_ASYNC_CRYPT
+    CertSignCtx  certSignCtx_lcl;
+
+    certSignCtx = &certSignCtx_lcl;
+    XMEMSET(certSignCtx, 0, sizeof(CertSignCtx));
+#else
+    certSignCtx = NULL;
+#endif
+
+    if (requestSz < 0)
+        return requestSz;
+
+    /* locate ctx */
+    if (rsaKey) {
+    #ifndef NO_RSA
+    #ifdef WOLFSSL_ASYNC_CRYPT
+        certSignCtx = &rsaKey->certSignCtx;
+    #endif
+        heap = rsaKey->heap;
+    #else
+        return NOT_COMPILED_IN;
+    #endif /* NO_RSA */
+    }
+    else if (eccKey) {
+    #ifdef HAVE_ECC
+    #ifdef WOLFSSL_ASYNC_CRYPT
+        certSignCtx = &eccKey->certSignCtx;
+    #endif
+        heap = eccKey->heap;
+    #else
+        return NOT_COMPILED_IN;
+    #endif /* HAVE_ECC */
+    }
+
+#ifdef WOLFSSL_ASYNC_CRYPT
+    if (certSignCtx == NULL) {
+        return BAD_FUNC_ARG;
+    }
+#endif
+
+    if (certSignCtx->sig == NULL) {
+        certSignCtx->sig = (byte*)XMALLOC(MAX_ENCODED_SIG_SZ, heap,
+            DYNAMIC_TYPE_TMP_BUFFER);
+        if (certSignCtx->sig == NULL)
+            return MEMORY_E;
+    }
+
+    sigSz = MakeSignature(certSignCtx, buf, requestSz, certSignCtx->sig,
+        MAX_ENCODED_SIG_SZ, rsaKey, eccKey, ed25519Key, ed448Key, rng, sType,
+        heap);
+#ifdef WOLFSSL_ASYNC_CRYPT
+    if (sigSz == WC_PENDING_E) {
+        /* Not free'ing certSignCtx->sig here because it could still be in use
+         * with async operations. */
+        return sigSz;
+    }
+#endif
+
+    if (sigSz >= 0) {
+        if (requestSz + MAX_SEQ_SZ * 2 + sigSz > (int)buffSz)
+            sigSz = BUFFER_E;
+        else
+            sigSz = AddSignature(buf, requestSz, certSignCtx->sig, sigSz,
+                                 sType);
+    }
+
+    XFREE(certSignCtx->sig, heap, DYNAMIC_TYPE_TMP_BUFFER);
+    certSignCtx->sig = NULL;
+
+    return sigSz;
+}
+
+int wc_SignCert_ex(int requestSz, int sType, byte* buf, word32 buffSz,
+                   int keyType, void* key, WC_RNG* rng)
+{
+    RsaKey*      rsaKey = NULL;
+    ecc_key*     eccKey = NULL;
+    ed25519_key* ed25519Key = NULL;
+    ed448_key*   ed448Key = NULL;
+
+    if (keyType == RSA_TYPE)
+        rsaKey = (RsaKey*)key;
+    else if (keyType == ECC_TYPE)
+        eccKey = (ecc_key*)key;
+    else if (keyType == ED25519_TYPE)
+        ed25519Key = (ed25519_key*)key;
+    else if (keyType == ED448_TYPE)
+        ed448Key = (ed448_key*)key;
+
+    return SignCert(requestSz, sType, buf, buffSz, rsaKey, eccKey, ed25519Key,
+                    ed448Key, rng);
+}
+
+int wc_SignCert(int requestSz, int sType, byte* buf, word32 buffSz,
+                RsaKey* rsaKey, ecc_key* eccKey, WC_RNG* rng)
+{
+    return SignCert(requestSz, sType, buf, buffSz, rsaKey, eccKey, NULL, NULL,
+                    rng);
+}
+
+int wc_MakeSelfCert(Cert* cert, byte* buf, word32 buffSz,
+                    RsaKey* key, WC_RNG* rng)
+{
+    int ret;
+
+    ret = wc_MakeCert(cert, buf, buffSz, key, NULL, rng);
+    if (ret < 0)
+        return ret;
+
+    return wc_SignCert(cert->bodySz, cert->sigType,
+                       buf, buffSz, key, NULL, rng);
+}
+
+
+#ifdef WOLFSSL_CERT_EXT
+
+/* Get raw subject from cert, which may contain OIDs not parsed by Decode.
+   The raw subject pointer will only be valid while "cert" is valid. */
+int wc_GetSubjectRaw(byte **subjectRaw, Cert *cert)
+{
+    int rc = BAD_FUNC_ARG;
+    if ((subjectRaw != NULL) && (cert != NULL)) {
+        *subjectRaw = cert->sbjRaw;
+        rc = 0;
+    }
+    return rc;
+}
+
+/* Set KID from public key */
+static int SetKeyIdFromPublicKey(Cert *cert, RsaKey *rsakey, ecc_key *eckey,
+                                 byte *ntruKey, word16 ntruKeySz,
+                                 ed25519_key* ed25519Key, ed448_key* ed448Key,
+                                 int kid_type)
+{
+    byte *buf;
+    int   bufferSz, ret;
+
+    if (cert == NULL ||
+        (rsakey == NULL && eckey == NULL && ntruKey == NULL &&
+                                      ed25519Key == NULL && ed448Key == NULL) ||
+        (kid_type != SKID_TYPE && kid_type != AKID_TYPE))
+        return BAD_FUNC_ARG;
+
+    buf = (byte *)XMALLOC(MAX_PUBLIC_KEY_SZ, cert->heap,
+                                                       DYNAMIC_TYPE_TMP_BUFFER);
+    if (buf == NULL)
+        return MEMORY_E;
+
+    /* Public Key */
+    bufferSz = -1;
+#ifndef NO_RSA
+    /* RSA public key */
+    if (rsakey != NULL)
+        bufferSz = SetRsaPublicKey(buf, rsakey, MAX_PUBLIC_KEY_SZ, 0);
+#endif
+#ifdef HAVE_ECC
+    /* ECC public key */
+    if (eckey != NULL)
+        bufferSz = SetEccPublicKey(buf, eckey, 0);
+#endif
+#ifdef HAVE_NTRU
+    /* NTRU public key */
+    if (ntruKey != NULL) {
+        bufferSz = MAX_PUBLIC_KEY_SZ;
+        ret = ntru_crypto_ntru_encrypt_publicKey2SubjectPublicKeyInfo(
+                        ntruKeySz, ntruKey, (word16 *)(&bufferSz), buf);
+        if (ret != NTRU_OK)
+            bufferSz = -1;
+    }
+#else
+    (void)ntruKeySz;
+#endif
+#ifdef HAVE_ED25519
+    /* ED25519 public key */
+    if (ed25519Key != NULL)
+        bufferSz = SetEd25519PublicKey(buf, ed25519Key, 0);
+#endif
+#ifdef HAVE_ED448
+    /* ED448 public key */
+    if (ed448Key != NULL)
+        bufferSz = SetEd448PublicKey(buffer, ed448Key, 0);
+#endif
+
+    if (bufferSz <= 0) {
+        XFREE(buf, cert->heap, DYNAMIC_TYPE_TMP_BUFFER);
+        return PUBLIC_KEY_E;
+    }
+
+    /* Compute SKID by hashing public key */
+    if (kid_type == SKID_TYPE) {
+        ret = CalcHashId(buf, bufferSz, cert->skid);
+        cert->skidSz = KEYID_SIZE;
+    }
+    else if (kid_type == AKID_TYPE) {
+        ret = CalcHashId(buf, bufferSz, cert->akid);
+        cert->akidSz = KEYID_SIZE;
+    }
+    else
+        ret = BAD_FUNC_ARG;
+
+    XFREE(buf, cert->heap, DYNAMIC_TYPE_TMP_BUFFER);
+    return ret;
+}
+
+int wc_SetSubjectKeyIdFromPublicKey_ex(Cert *cert, int keyType, void* key)
+{
+    RsaKey*      rsaKey = NULL;
+    ecc_key*     eccKey = NULL;
+    ed25519_key* ed25519Key = NULL;
+    ed448_key*   ed448Key = NULL;
+
+    if (keyType == RSA_TYPE)
+        rsaKey = (RsaKey*)key;
+    else if (keyType == ECC_TYPE)
+        eccKey = (ecc_key*)key;
+    else if (keyType == ED25519_TYPE)
+        ed25519Key = (ed25519_key*)key;
+    else if (keyType == ED448_TYPE)
+        ed448Key = (ed448_key*)key;
+
+    return SetKeyIdFromPublicKey(cert, rsaKey, eccKey, NULL, 0, ed25519Key,
+                                 ed448Key, SKID_TYPE);
+}
+
+/* Set SKID from RSA or ECC public key */
+int wc_SetSubjectKeyIdFromPublicKey(Cert *cert, RsaKey *rsakey, ecc_key *eckey)
+{
+    return SetKeyIdFromPublicKey(cert, rsakey, eckey, NULL, 0, NULL, NULL,
+                                 SKID_TYPE);
+}
+
+#ifdef HAVE_NTRU
+/* Set SKID from NTRU public key */
+int wc_SetSubjectKeyIdFromNtruPublicKey(Cert *cert,
+                                        byte *ntruKey, word16 ntruKeySz)
+{
+    return SetKeyIdFromPublicKey(cert, NULL,NULL,ntruKey, ntruKeySz, NULL, NULL,
+                                 SKID_TYPE);
+}
+#endif
+
+int wc_SetAuthKeyIdFromPublicKey_ex(Cert *cert, int keyType, void* key)
+{
+    RsaKey*      rsaKey = NULL;
+    ecc_key*     eccKey = NULL;
+    ed25519_key* ed25519Key = NULL;
+    ed448_key*   ed448Key = NULL;
+
+    if (keyType == RSA_TYPE)
+        rsaKey = (RsaKey*)key;
+    else if (keyType == ECC_TYPE)
+        eccKey = (ecc_key*)key;
+    else if (keyType == ED25519_TYPE)
+        ed25519Key = (ed25519_key*)key;
+    else if (keyType == ED448_TYPE)
+        ed448Key = (ed448_key*)key;
+
+    return SetKeyIdFromPublicKey(cert, rsaKey, eccKey, NULL, 0, ed25519Key,
+                                 ed448Key, AKID_TYPE);
+}
+
+/* Set SKID from RSA or ECC public key */
+int wc_SetAuthKeyIdFromPublicKey(Cert *cert, RsaKey *rsakey, ecc_key *eckey)
+{
+    return SetKeyIdFromPublicKey(cert, rsakey, eckey, NULL, 0, NULL, NULL,
+                                 AKID_TYPE);
+}
+
+
+#if !defined(NO_FILESYSTEM) && !defined(NO_ASN_CRYPT)
+
+/* Set SKID from public key file in PEM */
+int wc_SetSubjectKeyId(Cert *cert, const char* file)
+{
+    int     ret, derSz;
+    byte*   der;
+    word32  idx;
+    RsaKey  *rsakey = NULL;
+    ecc_key *eckey = NULL;
+
+    if (cert == NULL || file == NULL)
+        return BAD_FUNC_ARG;
+
+    der = (byte*)XMALLOC(MAX_PUBLIC_KEY_SZ, cert->heap, DYNAMIC_TYPE_CERT);
+    if (der == NULL) {
+        WOLFSSL_MSG("wc_SetSubjectKeyId memory Problem");
+        return MEMORY_E;
+    }
+    derSz = MAX_PUBLIC_KEY_SZ;
+
+    XMEMSET(der, 0, derSz);
+    derSz = wc_PemPubKeyToDer(file, der, derSz);
+    if (derSz <= 0) {
+        XFREE(der, cert->heap, DYNAMIC_TYPE_CERT);
+        return derSz;
+    }
+
+    /* Load PubKey in internal structure */
+#ifndef NO_RSA
+    rsakey = (RsaKey*) XMALLOC(sizeof(RsaKey), cert->heap, DYNAMIC_TYPE_RSA);
+    if (rsakey == NULL) {
+        XFREE(der, cert->heap, DYNAMIC_TYPE_CERT);
+        return MEMORY_E;
+    }
+
+    if (wc_InitRsaKey(rsakey, cert->heap) != 0) {
+        WOLFSSL_MSG("wc_InitRsaKey failure");
+        XFREE(rsakey, cert->heap, DYNAMIC_TYPE_RSA);
+        XFREE(der, cert->heap, DYNAMIC_TYPE_CERT);
+        return MEMORY_E;
+    }
+
+    idx = 0;
+    ret = wc_RsaPublicKeyDecode(der, &idx, rsakey, derSz);
+    if (ret != 0)
+#endif
+    {
+#ifndef NO_RSA
+        WOLFSSL_MSG("wc_RsaPublicKeyDecode failed");
+        wc_FreeRsaKey(rsakey);
+        XFREE(rsakey, cert->heap, DYNAMIC_TYPE_RSA);
+        rsakey = NULL;
+#endif
+#ifdef HAVE_ECC
+        /* Check to load ecc public key */
+        eckey = (ecc_key*) XMALLOC(sizeof(ecc_key), cert->heap,
+                                                              DYNAMIC_TYPE_ECC);
+        if (eckey == NULL) {
+            XFREE(der, cert->heap, DYNAMIC_TYPE_CERT);
+            return MEMORY_E;
+        }
+
+        if (wc_ecc_init(eckey) != 0) {
+            WOLFSSL_MSG("wc_ecc_init failure");
+            wc_ecc_free(eckey);
+            XFREE(eckey, cert->heap, DYNAMIC_TYPE_ECC);
+            XFREE(der, cert->heap, DYNAMIC_TYPE_CERT);
+            return MEMORY_E;
+        }
+
+        idx = 0;
+        ret = wc_EccPublicKeyDecode(der, &idx, eckey, derSz);
+        if (ret != 0) {
+            WOLFSSL_MSG("wc_EccPublicKeyDecode failed");
+            XFREE(der, cert->heap, DYNAMIC_TYPE_CERT);
+            wc_ecc_free(eckey);
+            XFREE(eckey, cert->heap, DYNAMIC_TYPE_ECC);
+            return PUBLIC_KEY_E;
+        }
+#else
+        XFREE(der, cert->heap, DYNAMIC_TYPE_CERT);
+        return PUBLIC_KEY_E;
+#endif /* HAVE_ECC */
+    }
+
+    XFREE(der, cert->heap, DYNAMIC_TYPE_CERT);
+
+    ret = wc_SetSubjectKeyIdFromPublicKey(cert, rsakey, eckey);
+
+#ifndef NO_RSA
+    wc_FreeRsaKey(rsakey);
+    XFREE(rsakey, cert->heap, DYNAMIC_TYPE_RSA);
+#endif
+#ifdef HAVE_ECC
+    wc_ecc_free(eckey);
+    XFREE(eckey, cert->heap, DYNAMIC_TYPE_ECC);
+#endif
+    return ret;
+}
+
+#endif /* !NO_FILESYSTEM && !NO_ASN_CRYPT */
+
+static int SetAuthKeyIdFromDcert(Cert* cert, DecodedCert* decoded)
+{
+    int ret = 0;
+
+    /* Subject Key Id not found !! */
+    if (decoded->extSubjKeyIdSet == 0) {
+        ret = ASN_NO_SKID;
+    }
+
+    /* SKID invalid size */
+    else if (sizeof(cert->akid) < sizeof(decoded->extSubjKeyId)) {
+        ret = MEMORY_E;
+    }
+
+    else {
+        /* Put the SKID of CA to AKID of certificate */
+        XMEMCPY(cert->akid, decoded->extSubjKeyId, KEYID_SIZE);
+        cert->akidSz = KEYID_SIZE;
+    }
+
+    return ret;
+}
+
+/* Set AKID from certificate contains in buffer (DER encoded) */
+int wc_SetAuthKeyIdFromCert(Cert *cert, const byte *der, int derSz)
+{
+    int ret = 0;
+
+    if (cert == NULL) {
+        ret = BAD_FUNC_ARG;
+    }
+    else {
+        /* Check if decodedCert is cached */
+        if (cert->der != der) {
+            /* Allocate cache for the decoded cert */
+            ret = wc_SetCert_LoadDer(cert, der, derSz);
+        }
+
+        if (ret >= 0) {
+            ret = SetAuthKeyIdFromDcert(cert, (DecodedCert*)cert->decodedCert);
+#ifndef WOLFSSL_CERT_GEN_CACHE
+            wc_SetCert_Free(cert);
+#endif
+        }
+    }
+
+    return ret;
+}
+
+
+#ifndef NO_FILESYSTEM
+
+/* Set AKID from certificate file in PEM */
+int wc_SetAuthKeyId(Cert *cert, const char* file)
+{
+    int         ret;
+    int         derSz;
+    byte*       der;
+
+    if (cert == NULL || file == NULL)
+        return BAD_FUNC_ARG;
+
+    der = (byte*)XMALLOC(EIGHTK_BUF, cert->heap, DYNAMIC_TYPE_CERT);
+    if (der == NULL) {
+        WOLFSSL_MSG("wc_SetAuthKeyId OOF Problem");
+        return MEMORY_E;
+    }
+
+    derSz = wc_PemCertToDer(file, der, EIGHTK_BUF);
+    if (derSz <= 0)
+    {
+        XFREE(der, cert->heap, DYNAMIC_TYPE_CERT);
+        return derSz;
+    }
+
+    ret = wc_SetAuthKeyIdFromCert(cert, der, derSz);
+    XFREE(der, cert->heap, DYNAMIC_TYPE_CERT);
+
+    return ret;
+}
+
+#endif /* !NO_FILESYSTEM */
+
+/* Set KeyUsage from human readable string */
+int wc_SetKeyUsage(Cert *cert, const char *value)
+{
+    int ret = 0;
+    char *token, *str, *ptr;
+    word32 len;
+
+    if (cert == NULL || value == NULL)
+        return BAD_FUNC_ARG;
+
+    cert->keyUsage = 0;
+
+    /* duplicate string (including terminator) */
+    len = (word32)XSTRLEN(value);
+    str = (char*)XMALLOC(len+1, cert->heap, DYNAMIC_TYPE_TMP_BUFFER);
+    if (str == NULL)
+        return MEMORY_E;
+    XMEMCPY(str, value, len+1);
+
+    /* parse value, and set corresponding Key Usage value */
+    if ((token = XSTRTOK(str, ",", &ptr)) == NULL) {
+        XFREE(str, cert->heap, DYNAMIC_TYPE_TMP_BUFFER);
+        return KEYUSAGE_E;
+    }
+    while (token != NULL)
+    {
+        len = (word32)XSTRLEN(token);
+
+        if (!XSTRNCASECMP(token, "digitalSignature", len))
+            cert->keyUsage |= KEYUSE_DIGITAL_SIG;
+        else if (!XSTRNCASECMP(token, "nonRepudiation", len) ||
+                 !XSTRNCASECMP(token, "contentCommitment", len))
+            cert->keyUsage |= KEYUSE_CONTENT_COMMIT;
+        else if (!XSTRNCASECMP(token, "keyEncipherment", len))
+            cert->keyUsage |= KEYUSE_KEY_ENCIPHER;
+        else if (!XSTRNCASECMP(token, "dataEncipherment", len))
+            cert->keyUsage |= KEYUSE_DATA_ENCIPHER;
+        else if (!XSTRNCASECMP(token, "keyAgreement", len))
+            cert->keyUsage |= KEYUSE_KEY_AGREE;
+        else if (!XSTRNCASECMP(token, "keyCertSign", len))
+            cert->keyUsage |= KEYUSE_KEY_CERT_SIGN;
+        else if (!XSTRNCASECMP(token, "cRLSign", len))
+            cert->keyUsage |= KEYUSE_CRL_SIGN;
+        else if (!XSTRNCASECMP(token, "encipherOnly", len))
+            cert->keyUsage |= KEYUSE_ENCIPHER_ONLY;
+        else if (!XSTRNCASECMP(token, "decipherOnly", len))
+            cert->keyUsage |= KEYUSE_DECIPHER_ONLY;
+        else {
+            ret = KEYUSAGE_E;
+            break;
+        }
+
+        token = XSTRTOK(NULL, ",", &ptr);
+    }
+
+    XFREE(str, cert->heap, DYNAMIC_TYPE_TMP_BUFFER);
+    return ret;
+}
+
+/* Set ExtendedKeyUsage from human readable string */
+int wc_SetExtKeyUsage(Cert *cert, const char *value)
+{
+    int ret = 0;
+    char *token, *str, *ptr;
+    word32 len;
+
+    if (cert == NULL || value == NULL)
+        return BAD_FUNC_ARG;
+
+    cert->extKeyUsage = 0;
+
+    /* duplicate string (including terminator) */
+    len = (word32)XSTRLEN(value);
+    str = (char*)XMALLOC(len+1, cert->heap, DYNAMIC_TYPE_TMP_BUFFER);
+    if (str == NULL)
+        return MEMORY_E;
+    XMEMCPY(str, value, len+1);
+
+    /* parse value, and set corresponding Key Usage value */
+    if ((token = XSTRTOK(str, ",", &ptr)) == NULL) {
+        XFREE(str, cert->heap, DYNAMIC_TYPE_TMP_BUFFER);
+        return EXTKEYUSAGE_E;
+    }
+
+    while (token != NULL)
+    {
+        len = (word32)XSTRLEN(token);
+
+        if (!XSTRNCASECMP(token, "any", len))
+            cert->extKeyUsage |= EXTKEYUSE_ANY;
+        else if (!XSTRNCASECMP(token, "serverAuth", len))
+            cert->extKeyUsage |= EXTKEYUSE_SERVER_AUTH;
+        else if (!XSTRNCASECMP(token, "clientAuth", len))
+            cert->extKeyUsage |= EXTKEYUSE_CLIENT_AUTH;
+        else if (!XSTRNCASECMP(token, "codeSigning", len))
+            cert->extKeyUsage |= EXTKEYUSE_CODESIGN;
+        else if (!XSTRNCASECMP(token, "emailProtection", len))
+            cert->extKeyUsage |= EXTKEYUSE_EMAILPROT;
+        else if (!XSTRNCASECMP(token, "timeStamping", len))
+            cert->extKeyUsage |= EXTKEYUSE_TIMESTAMP;
+        else if (!XSTRNCASECMP(token, "OCSPSigning", len))
+            cert->extKeyUsage |= EXTKEYUSE_OCSP_SIGN;
+        else {
+            ret = EXTKEYUSAGE_E;
+            break;
+        }
+
+        token = XSTRTOK(NULL, ",", &ptr);
+    }
+
+    XFREE(str, cert->heap, DYNAMIC_TYPE_TMP_BUFFER);
+    return ret;
+}
+
+#ifdef WOLFSSL_EKU_OID
+/*
+ * cert structure to set EKU oid in
+ * oid  the oid in byte representation
+ * sz   size of oid buffer
+ * idx  index of array to place oid
+ *
+ * returns 0 on success
+ */
+int wc_SetExtKeyUsageOID(Cert *cert, const char *in, word32 sz, byte idx,
+        void* heap)
+{
+    byte oid[MAX_OID_SZ];
+    word32 oidSz = MAX_OID_SZ;
+
+    if (idx >= CTC_MAX_EKU_NB || sz >= CTC_MAX_EKU_OID_SZ) {
+        WOLFSSL_MSG("Either idx or sz was too large");
+        return BAD_FUNC_ARG;
+    }
+
+    if (EncodePolicyOID(oid, &oidSz, in, heap) != 0) {
+        return BUFFER_E;
+    }
+
+    XMEMCPY(cert->extKeyUsageOID[idx], oid, oidSz);
+    cert->extKeyUsageOIDSz[idx] = oidSz;
+    cert->extKeyUsage |= EXTKEYUSE_USER;
+
+    return 0;
+}
+#endif /* WOLFSSL_EKU_OID */
+#endif /* WOLFSSL_CERT_EXT */
+
+
+#ifdef WOLFSSL_ALT_NAMES
+
+static int SetAltNamesFromDcert(Cert* cert, DecodedCert* decoded)
+{
+    int ret = 0;
+    byte tag;
+
+    if (decoded->extensions) {
+        int    length;
+        word32 maxExtensionsIdx;
+
+        decoded->srcIdx = decoded->extensionsIdx;
+        if (GetASNTag(decoded->source, &decoded->srcIdx, &tag, decoded->maxIdx)
+                != 0) {
+            return ASN_PARSE_E;
+        }
+
+        if (tag != ASN_EXTENSIONS) {
+            ret = ASN_PARSE_E;
+        }
+        else if (GetLength(decoded->source, &decoded->srcIdx, &length,
+                                                         decoded->maxIdx) < 0) {
+            ret = ASN_PARSE_E;
+        }
+        else if (GetSequence(decoded->source, &decoded->srcIdx, &length,
+                                                         decoded->maxIdx) < 0) {
+            ret = ASN_PARSE_E;
+        }
+        else {
+            maxExtensionsIdx = decoded->srcIdx + length;
+
+            while (decoded->srcIdx < maxExtensionsIdx) {
+                word32 oid;
+                word32 startIdx = decoded->srcIdx;
+                word32 tmpIdx;
+
+                if (GetSequence(decoded->source, &decoded->srcIdx, &length,
+                            decoded->maxIdx) < 0) {
+                    ret = ASN_PARSE_E;
+                    break;
+                }
+
+                tmpIdx = decoded->srcIdx;
+                decoded->srcIdx = startIdx;
+
+                if (GetAlgoId(decoded->source, &decoded->srcIdx, &oid,
+                              oidCertExtType, decoded->maxIdx) < 0) {
+                    ret = ASN_PARSE_E;
+                    break;
+                }
+
+                if (oid == ALT_NAMES_OID) {
+                    cert->altNamesSz = length + (tmpIdx - startIdx);
+
+                    if (cert->altNamesSz < (int)sizeof(cert->altNames))
+                        XMEMCPY(cert->altNames, &decoded->source[startIdx],
+                                cert->altNamesSz);
+                    else {
+                        cert->altNamesSz = 0;
+                        WOLFSSL_MSG("AltNames extensions too big");
+                        ret = ALT_NAME_E;
+                        break;
+                    }
+                }
+                decoded->srcIdx = tmpIdx + length;
+            }
+        }
+    }
+
+    return ret;
+}
+
+#ifndef NO_FILESYSTEM
+
+/* Set Alt Names from der cert, return 0 on success */
+static int SetAltNamesFromCert(Cert* cert, const byte* der, int derSz)
+{
+    int ret;
+#ifdef WOLFSSL_SMALL_STACK
+    DecodedCert* decoded;
+#else
+    DecodedCert decoded[1];
+#endif
+
+    if (derSz < 0)
+        return derSz;
+
+#ifdef WOLFSSL_SMALL_STACK
+    decoded = (DecodedCert*)XMALLOC(sizeof(DecodedCert), cert->heap,
+                                                       DYNAMIC_TYPE_TMP_BUFFER);
+    if (decoded == NULL)
+        return MEMORY_E;
+#endif
+
+    InitDecodedCert(decoded, der, derSz, NULL);
+    ret = ParseCertRelative(decoded, CA_TYPE, NO_VERIFY, 0);
+
+    if (ret < 0) {
+        WOLFSSL_MSG("ParseCertRelative error");
+    }
+    else {
+        ret = SetAltNamesFromDcert(cert, decoded);
+    }
+
+    FreeDecodedCert(decoded);
+#ifdef WOLFSSL_SMALL_STACK
+    XFREE(decoded, cert->heap, DYNAMIC_TYPE_TMP_BUFFER);
+#endif
+
+    return ret < 0 ? ret : 0;
+}
+
+#endif
+
+static int SetDatesFromDcert(Cert* cert, DecodedCert* decoded)
+{
+    int ret = 0;
+
+    if (decoded->beforeDate == NULL || decoded->afterDate == NULL) {
+        WOLFSSL_MSG("Couldn't extract dates");
+        ret = -1;
+    }
+    else if (decoded->beforeDateLen > MAX_DATE_SIZE ||
+                                        decoded->afterDateLen > MAX_DATE_SIZE) {
+        WOLFSSL_MSG("Bad date size");
+        ret = -1;
+    }
+    else {
+        XMEMCPY(cert->beforeDate, decoded->beforeDate, decoded->beforeDateLen);
+        XMEMCPY(cert->afterDate,  decoded->afterDate,  decoded->afterDateLen);
+
+        cert->beforeDateSz = decoded->beforeDateLen;
+        cert->afterDateSz  = decoded->afterDateLen;
+    }
+
+    return ret;
+}
+
+#endif /* WOLFSSL_ALT_NAMES */
+
+static void SetNameFromDcert(CertName* cn, DecodedCert* decoded)
+{
+    int sz;
+
+    if (decoded->subjectCN) {
+        sz = (decoded->subjectCNLen < CTC_NAME_SIZE) ? decoded->subjectCNLen
+                                                     : CTC_NAME_SIZE - 1;
+        XSTRNCPY(cn->commonName, decoded->subjectCN, sz);
+        cn->commonName[sz] = '\0';
+        cn->commonNameEnc = decoded->subjectCNEnc;
+    }
+    if (decoded->subjectC) {
+        sz = (decoded->subjectCLen < CTC_NAME_SIZE) ? decoded->subjectCLen
+                                                    : CTC_NAME_SIZE - 1;
+        XSTRNCPY(cn->country, decoded->subjectC, sz);
+        cn->country[sz] = '\0';
+        cn->countryEnc = decoded->subjectCEnc;
+    }
+    if (decoded->subjectST) {
+        sz = (decoded->subjectSTLen < CTC_NAME_SIZE) ? decoded->subjectSTLen
+                                                     : CTC_NAME_SIZE - 1;
+        XSTRNCPY(cn->state, decoded->subjectST, sz);
+        cn->state[sz] = '\0';
+        cn->stateEnc = decoded->subjectSTEnc;
+    }
+    if (decoded->subjectL) {
+        sz = (decoded->subjectLLen < CTC_NAME_SIZE) ? decoded->subjectLLen
+                                                    : CTC_NAME_SIZE - 1;
+        XSTRNCPY(cn->locality, decoded->subjectL, sz);
+        cn->locality[sz] = '\0';
+        cn->localityEnc = decoded->subjectLEnc;
+    }
+    if (decoded->subjectO) {
+        sz = (decoded->subjectOLen < CTC_NAME_SIZE) ? decoded->subjectOLen
+                                                    : CTC_NAME_SIZE - 1;
+        XSTRNCPY(cn->org, decoded->subjectO, sz);
+        cn->org[sz] = '\0';
+        cn->orgEnc = decoded->subjectOEnc;
+    }
+    if (decoded->subjectOU) {
+        sz = (decoded->subjectOULen < CTC_NAME_SIZE) ? decoded->subjectOULen
+                                                     : CTC_NAME_SIZE - 1;
+        XSTRNCPY(cn->unit, decoded->subjectOU, sz);
+        cn->unit[sz] = '\0';
+        cn->unitEnc = decoded->subjectOUEnc;
+    }
+    if (decoded->subjectSN) {
+        sz = (decoded->subjectSNLen < CTC_NAME_SIZE) ? decoded->subjectSNLen
+                                                     : CTC_NAME_SIZE - 1;
+        XSTRNCPY(cn->sur, decoded->subjectSN, sz);
+        cn->sur[sz] = '\0';
+        cn->surEnc = decoded->subjectSNEnc;
+    }
+    if (decoded->subjectSND) {
+        sz = (decoded->subjectSNDLen < CTC_NAME_SIZE) ? decoded->subjectSNDLen
+                                                     : CTC_NAME_SIZE - 1;
+        XSTRNCPY(cn->serialDev, decoded->subjectSND, sz);
+        cn->serialDev[sz] = '\0';
+        cn->serialDevEnc = decoded->subjectSNDEnc;
+    }
+#ifdef WOLFSSL_CERT_EXT
+    if (decoded->subjectBC) {
+        sz = (decoded->subjectBCLen < CTC_NAME_SIZE) ? decoded->subjectBCLen
+                                                     : CTC_NAME_SIZE - 1;
+        XSTRNCPY(cn->busCat, decoded->subjectBC, sz);
+        cn->busCat[sz] = '\0';
+        cn->busCatEnc = decoded->subjectBCEnc;
+    }
+    if (decoded->subjectJC) {
+        sz = (decoded->subjectJCLen < CTC_NAME_SIZE) ? decoded->subjectJCLen
+                                                     : CTC_NAME_SIZE - 1;
+        XSTRNCPY(cn->joiC, decoded->subjectJC, sz);
+        cn->joiC[sz] = '\0';
+        cn->joiCEnc = decoded->subjectJCEnc;
+    }
+    if (decoded->subjectJS) {
+        sz = (decoded->subjectJSLen < CTC_NAME_SIZE) ? decoded->subjectJSLen
+                                                     : CTC_NAME_SIZE - 1;
+        XSTRNCPY(cn->joiSt, decoded->subjectJS, sz);
+        cn->joiSt[sz] = '\0';
+        cn->joiStEnc = decoded->subjectJSEnc;
+    }
+#endif
+    if (decoded->subjectEmail) {
+        sz = (decoded->subjectEmailLen < CTC_NAME_SIZE)
+           ?  decoded->subjectEmailLen : CTC_NAME_SIZE - 1;
+        XSTRNCPY(cn->email, decoded->subjectEmail, sz);
+        cn->email[sz] = '\0';
+    }
+}
+
+#ifndef NO_FILESYSTEM
+
+/* Set cn name from der buffer, return 0 on success */
+static int SetNameFromCert(CertName* cn, const byte* der, int derSz)
+{
+    int ret;
+#ifdef WOLFSSL_SMALL_STACK
+    DecodedCert* decoded;
+#else
+    DecodedCert decoded[1];
+#endif
+
+    if (derSz < 0)
+        return derSz;
+
+#ifdef WOLFSSL_SMALL_STACK
+    decoded = (DecodedCert*)XMALLOC(sizeof(DecodedCert), NULL,
+                                                       DYNAMIC_TYPE_TMP_BUFFER);
+    if (decoded == NULL)
+        return MEMORY_E;
+#endif
+
+    InitDecodedCert(decoded, der, derSz, NULL);
+    ret = ParseCertRelative(decoded, CA_TYPE, NO_VERIFY, 0);
+
+    if (ret < 0) {
+        WOLFSSL_MSG("ParseCertRelative error");
+    }
+    else {
+        SetNameFromDcert(cn, decoded);
+    }
+
+    FreeDecodedCert(decoded);
+
+#ifdef WOLFSSL_SMALL_STACK
+    XFREE(decoded, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+#endif
+
+    return ret < 0 ? ret : 0;
+}
+
+/* Set cert issuer from issuerFile in PEM */
+int wc_SetIssuer(Cert* cert, const char* issuerFile)
+{
+    int         ret;
+    int         derSz;
+    byte*       der;
+
+    if (cert == NULL) {
+        return BAD_FUNC_ARG;
+    }
+
+    der = (byte*)XMALLOC(EIGHTK_BUF, cert->heap, DYNAMIC_TYPE_CERT);
+    if (der == NULL) {
+        WOLFSSL_MSG("wc_SetIssuer OOF Problem");
+        return MEMORY_E;
+    }
+    derSz = wc_PemCertToDer(issuerFile, der, EIGHTK_BUF);
+    cert->selfSigned = 0;
+    ret = SetNameFromCert(&cert->issuer, der, derSz);
+    XFREE(der, cert->heap, DYNAMIC_TYPE_CERT);
+
+    return ret;
+}
+
+
+/* Set cert subject from subjectFile in PEM */
+int wc_SetSubject(Cert* cert, const char* subjectFile)
+{
+    int         ret;
+    int         derSz;
+    byte*       der;
+
+    if (cert == NULL) {
+        return BAD_FUNC_ARG;
+    }
+
+    der = (byte*)XMALLOC(EIGHTK_BUF, cert->heap, DYNAMIC_TYPE_CERT);
+    if (der == NULL) {
+        WOLFSSL_MSG("wc_SetSubject OOF Problem");
+        return MEMORY_E;
+    }
+
+    derSz = wc_PemCertToDer(subjectFile, der, EIGHTK_BUF);
+    ret = SetNameFromCert(&cert->subject, der, derSz);
+    XFREE(der, cert->heap, DYNAMIC_TYPE_CERT);
+
+    return ret;
+}
+
+#ifdef WOLFSSL_ALT_NAMES
+
+/* Set alt names from file in PEM */
+int wc_SetAltNames(Cert* cert, const char* file)
+{
+    int         ret;
+    int         derSz;
+    byte*       der;
+
+    if (cert == NULL) {
+        return BAD_FUNC_ARG;
+    }
+
+    der = (byte*)XMALLOC(EIGHTK_BUF, cert->heap, DYNAMIC_TYPE_CERT);
+    if (der == NULL) {
+        WOLFSSL_MSG("wc_SetAltNames OOF Problem");
+        return MEMORY_E;
+    }
+    derSz = wc_PemCertToDer(file, der, EIGHTK_BUF);
+    ret = SetAltNamesFromCert(cert, der, derSz);
+    XFREE(der, cert->heap, DYNAMIC_TYPE_CERT);
+
+    return ret;
+}
+
+#endif /* WOLFSSL_ALT_NAMES */
+
+#endif /* !NO_FILESYSTEM */
+
+/* Set cert issuer from DER buffer */
+int wc_SetIssuerBuffer(Cert* cert, const byte* der, int derSz)
+{
+    int ret = 0;
+
+    if (cert == NULL) {
+        ret = BAD_FUNC_ARG;
+    }
+    else {
+        cert->selfSigned = 0;
+
+        /* Check if decodedCert is cached */
+        if (cert->der != der) {
+            /* Allocate cache for the decoded cert */
+            ret = wc_SetCert_LoadDer(cert, der, derSz);
+        }
+
+        if (ret >= 0) {
+            SetNameFromDcert(&cert->issuer, (DecodedCert*)cert->decodedCert);
+#ifndef WOLFSSL_CERT_GEN_CACHE
+            wc_SetCert_Free(cert);
+#endif
+        }
+    }
+
+    return ret;
+}
+
+/* Set cert subject from DER buffer */
+int wc_SetSubjectBuffer(Cert* cert, const byte* der, int derSz)
+{
+    int ret = 0;
+
+    if (cert == NULL) {
+        ret = BAD_FUNC_ARG;
+    }
+    else {
+        /* Check if decodedCert is cached */
+        if (cert->der != der) {
+            /* Allocate cache for the decoded cert */
+            ret = wc_SetCert_LoadDer(cert, der, derSz);
+        }
+
+        if (ret >= 0) {
+            SetNameFromDcert(&cert->subject, (DecodedCert*)cert->decodedCert);
+#ifndef WOLFSSL_CERT_GEN_CACHE
+            wc_SetCert_Free(cert);
+#endif
+        }
+    }
+
+    return ret;
+}
+#ifdef WOLFSSL_CERT_EXT
+/* Set cert raw subject from DER buffer */
+int wc_SetSubjectRaw(Cert* cert, const byte* der, int derSz)
+{
+    int ret = 0;
+
+    if (cert == NULL) {
+        ret = BAD_FUNC_ARG;
+    }
+    else {
+        /* Check if decodedCert is cached */
+        if (cert->der != der) {
+            /* Allocate cache for the decoded cert */
+            ret = wc_SetCert_LoadDer(cert, der, derSz);
+        }
+
+        if (ret >= 0) {
+            if ((((DecodedCert*)cert->decodedCert)->subjectRaw) &&
+                (((DecodedCert*)cert->decodedCert)->subjectRawLen <=
+                        (int)sizeof(CertName))) {
+                XMEMCPY(cert->sbjRaw,
+                        ((DecodedCert*)cert->decodedCert)->subjectRaw,
+                        ((DecodedCert*)cert->decodedCert)->subjectRawLen);
+            }
+#ifndef WOLFSSL_CERT_GEN_CACHE
+            wc_SetCert_Free(cert);
+#endif
+        }
+    }
+
+    return ret;
+}
+
+/* Set cert raw issuer from DER buffer */
+int wc_SetIssuerRaw(Cert* cert, const byte* der, int derSz)
+{
+    int ret = 0;
+
+    if (cert == NULL) {
+        ret = BAD_FUNC_ARG;
+    }
+    else {
+        /* Check if decodedCert is cached */
+        if (cert->der != der) {
+            /* Allocate cache for the decoded cert */
+            ret = wc_SetCert_LoadDer(cert, der, derSz);
+        }
+
+        if (ret >= 0) {
+            if ((((DecodedCert*)cert->decodedCert)->issuerRaw) &&
+                (((DecodedCert*)cert->decodedCert)->issuerRawLen <=
+                        (int)sizeof(CertName))) {
+                XMEMCPY(cert->issRaw,
+                        ((DecodedCert*)cert->decodedCert)->issuerRaw,
+                        ((DecodedCert*)cert->decodedCert)->issuerRawLen);
+            }
+#ifndef WOLFSSL_CERT_GEN_CACHE
+            wc_SetCert_Free(cert);
+#endif
+        }
+    }
+    return ret;
+}
+#endif
+
+#ifdef WOLFSSL_ALT_NAMES
+
+/* Set cert alt names from DER buffer */
+int wc_SetAltNamesBuffer(Cert* cert, const byte* der, int derSz)
+{
+    int ret = 0;
+
+    if (cert == NULL) {
+     ret = BAD_FUNC_ARG;
+    }
+    else {
+        /* Check if decodedCert is cached */
+        if (cert->der != der) {
+            /* Allocate cache for the decoded cert */
+            ret = wc_SetCert_LoadDer(cert, der, derSz);
+        }
+
+        if (ret >= 0) {
+            ret = SetAltNamesFromDcert(cert, (DecodedCert*)cert->decodedCert);
+#ifndef WOLFSSL_CERT_GEN_CACHE
+            wc_SetCert_Free(cert);
+#endif
+       }
+    }
+
+    return(ret);
+}
+
+/* Set cert dates from DER buffer */
+int wc_SetDatesBuffer(Cert* cert, const byte* der, int derSz)
+{
+    int ret = 0;
+
+    if (cert == NULL) {
+     ret = BAD_FUNC_ARG;
+    }
+    else {
+        /* Check if decodedCert is cached */
+        if (cert->der != der) {
+            /* Allocate cache for the decoded cert */
+            ret = wc_SetCert_LoadDer(cert, der, derSz);
+        }
+
+        if (ret >= 0) {
+            ret = SetDatesFromDcert(cert, (DecodedCert*)cert->decodedCert);
+#ifndef WOLFSSL_CERT_GEN_CACHE
+            wc_SetCert_Free(cert);
+#endif
+        }
+    }
+
+    return(ret);
+}
+
+#endif /* WOLFSSL_ALT_NAMES */
+
+#endif /* WOLFSSL_CERT_GEN */
+
+#if (defined(WOLFSSL_CERT_GEN) && defined(WOLFSSL_CERT_EXT)) \
+        || defined(OPENSSL_EXTRA)
+/* Encode OID string representation to ITU-T X.690 format */
+int EncodePolicyOID(byte *out, word32 *outSz, const char *in, void* heap)
+{
+    word32 val, idx = 0, nb_val;
+    char *token, *str, *ptr;
+    word32 len;
+
+    (void)heap;
+
+    if (out == NULL || outSz == NULL || *outSz < 2 || in == NULL)
+        return BAD_FUNC_ARG;
+
+    /* duplicate string (including terminator) */
+    len = (word32)XSTRLEN(in);
+    str = (char *)XMALLOC(len+1, heap, DYNAMIC_TYPE_TMP_BUFFER);
+    if (str == NULL)
+        return MEMORY_E;
+    XMEMCPY(str, in, len+1);
+
+    nb_val = 0;
+
+    /* parse value, and set corresponding Policy OID value */
+    token = XSTRTOK(str, ".", &ptr);
+    while (token != NULL)
+    {
+        val = (word32)XATOI(token);
+
+        if (nb_val == 0) {
+            if (val > 2) {
+                XFREE(str, heap, DYNAMIC_TYPE_TMP_BUFFER);
+                return ASN_OBJECT_ID_E;
+            }
+
+            out[idx] = (byte)(40 * val);
+        }
+        else if (nb_val == 1) {
+            if (val > 127) {
+                XFREE(str, heap, DYNAMIC_TYPE_TMP_BUFFER);
+                return ASN_OBJECT_ID_E;
+            }
+
+            if (idx > *outSz) {
+                XFREE(str, heap, DYNAMIC_TYPE_TMP_BUFFER);
+                return BUFFER_E;
+            }
+
+            out[idx++] += (byte)val;
+        }
+        else {
+            word32  tb = 0, x;
+            int     i = 0;
+            byte    oid[MAX_OID_SZ];
+
+            while (val >= 128) {
+                x = val % 128;
+                val /= 128;
+                oid[i++] = (byte) (((tb++) ? 0x80 : 0) | x);
+            }
+
+            if ((idx+(word32)i) > *outSz) {
+                XFREE(str, heap, DYNAMIC_TYPE_TMP_BUFFER);
+                return BUFFER_E;
+            }
+
+            oid[i] = (byte) (((tb++) ? 0x80 : 0) | val);
+
+            /* push value in the right order */
+            while (i >= 0)
+                out[idx++] = oid[i--];
+        }
+
+        token = XSTRTOK(NULL, ".", &ptr);
+        nb_val++;
+    }
+
+    *outSz = idx;
+
+    XFREE(str, heap, DYNAMIC_TYPE_TMP_BUFFER);
+    return 0;
+}
+#endif /* WOLFSSL_CERT_EXT || OPENSSL_EXTRA */
+
+#endif /* !NO_CERTS */
+
+#if !defined(NO_DH) && (defined(WOLFSSL_QT) || defined(OPENSSL_ALL))
+/* Helper function for wolfSSL_i2d_DHparams */
+int StoreDHparams(byte* out, word32* outLen, mp_int* p, mp_int* g)
+{
+    word32 idx = 0;
+    int pSz;
+    int gSz;
+    unsigned int tmp;
+    word32 headerSz = 4; /* 2*ASN_TAG + 2*LEN(ENUM) */
+
+    /* If the leading bit on the INTEGER is a 1, add a leading zero */
+    int pLeadingZero = mp_leading_bit(p);
+    int gLeadingZero = mp_leading_bit(g);
+    int pLen = mp_unsigned_bin_size(p);
+    int gLen = mp_unsigned_bin_size(g);
+
+    WOLFSSL_ENTER("StoreDHparams");
+    if (out == NULL) {
+        WOLFSSL_MSG("Null buffer error");
+        return BUFFER_E;
+    }
+
+    tmp = pLeadingZero + gLeadingZero + pLen + gLen;
+    if (*outLen < (tmp + headerSz)) {
+        return BUFFER_E;
+    }
+
+    /* Set sequence */
+    idx = SetSequence(tmp + headerSz + 2, out);
+
+    /* Encode p */
+    pSz = SetASNIntMP(p, -1, &out[idx]);
+    if (pSz < 0) {
+        WOLFSSL_MSG("SetASNIntMP failed");
+        return pSz;
+    }
+    idx += pSz;
+
+    /* Encode g */
+    gSz = SetASNIntMP(g, -1, &out[idx]);
+    if (gSz < 0) {
+        WOLFSSL_MSG("SetASNIntMP failed");
+        return gSz;
+    }
+    idx += gSz;
+
+    *outLen = idx;
+
+    return 0;
+}
+#endif /* !NO_DH && WOLFSSL_QT || OPENSSL_ALL */
+
+#ifdef HAVE_ECC
+
+/* Der Encode r & s ints into out, outLen is (in/out) size */
+int StoreECC_DSA_Sig(byte* out, word32* outLen, mp_int* r, mp_int* s)
+{
+    word32 idx = 0;
+    int    rSz;                           /* encoding size */
+    int    sSz;
+    word32 headerSz = 4;   /* 2*ASN_TAG + 2*LEN(ENUM) */
+
+    /* If the leading bit on the INTEGER is a 1, add a leading zero */
+    int rLeadingZero = mp_leading_bit(r);
+    int sLeadingZero = mp_leading_bit(s);
+    int rLen = mp_unsigned_bin_size(r);   /* big int size */
+    int sLen = mp_unsigned_bin_size(s);
+
+    if (*outLen < (rLen + rLeadingZero + sLen + sLeadingZero +
+                   headerSz + 2))  /* SEQ_TAG + LEN(ENUM) */
+        return BUFFER_E;
+
+    idx = SetSequence(rLen + rLeadingZero + sLen+sLeadingZero + headerSz, out);
+
+    /* store r */
+    rSz = SetASNIntMP(r, -1, &out[idx]);
+    if (rSz < 0)
+        return rSz;
+    idx += rSz;
+
+    /* store s */
+    sSz = SetASNIntMP(s, -1, &out[idx]);
+    if (sSz < 0)
+        return sSz;
+    idx += sSz;
+
+    *outLen = idx;
+
+    return 0;
+}
+
+
+/* Der Decode ECC-DSA Signature, r & s stored as big ints */
+int DecodeECC_DSA_Sig(const byte* sig, word32 sigLen, mp_int* r, mp_int* s)
+{
+    word32 idx = 0;
+    int    len = 0;
+
+    if (GetSequence(sig, &idx, &len, sigLen) < 0) {
+        return ASN_ECC_KEY_E;
+    }
+
+#ifndef NO_STRICT_ECDSA_LEN
+    /* enable strict length checking for signature */
+    if (sigLen != idx + (word32)len) {
+        return ASN_ECC_KEY_E;
+    }
+#else
+    /* allow extra signature bytes at end */
+    if ((word32)len > (sigLen - idx)) {
+        return ASN_ECC_KEY_E;
+    }
+#endif
+
+    if (GetInt(r, sig, &idx, sigLen) < 0) {
+        return ASN_ECC_KEY_E;
+    }
+
+    if (GetInt(s, sig, &idx, sigLen) < 0) {
+        return ASN_ECC_KEY_E;
+    }
+
+    return 0;
+}
+
+
+int wc_EccPrivateKeyDecode(const byte* input, word32* inOutIdx, ecc_key* key,
+                        word32 inSz)
+{
+    word32 oidSum;
+    int    version, length;
+    int    privSz, pubSz = 0;
+    byte   b;
+    int    ret = 0;
+    int    curve_id = ECC_CURVE_DEF;
+#ifdef WOLFSSL_SMALL_STACK
+    byte* priv;
+    byte* pub;
+#else
+    byte priv[ECC_MAXSIZE+1];
+    byte pub[2*(ECC_MAXSIZE+1)]; /* public key has two parts plus header */
+#endif
+    byte* pubData = NULL;
+
+    if (input == NULL || inOutIdx == NULL || key == NULL || inSz == 0)
+        return BAD_FUNC_ARG;
+
+    if (GetSequence(input, inOutIdx, &length, inSz) < 0)
+        return ASN_PARSE_E;
+
+    if (GetMyVersion(input, inOutIdx, &version, inSz) < 0)
+        return ASN_PARSE_E;
+
+    if (*inOutIdx >= inSz)
+        return ASN_PARSE_E;
+
+    b = input[*inOutIdx];
+    *inOutIdx += 1;
+
+    /* priv type */
+    if (b != 4 && b != 6 && b != 7)
+        return ASN_PARSE_E;
+
+    if (GetLength(input, inOutIdx, &length, inSz) < 0)
+        return ASN_PARSE_E;
+
+    if (length > ECC_MAXSIZE)
+        return BUFFER_E;
+
+#ifdef WOLFSSL_SMALL_STACK
+    priv = (byte*)XMALLOC(ECC_MAXSIZE+1, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
+    if (priv == NULL)
+        return MEMORY_E;
+
+    pub = (byte*)XMALLOC(2*(ECC_MAXSIZE+1), key->heap, DYNAMIC_TYPE_TMP_BUFFER);
+    if (pub == NULL) {
+        XFREE(priv, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
+        return MEMORY_E;
+    }
+#endif
+
+    /* priv key */
+    privSz = length;
+    XMEMCPY(priv, &input[*inOutIdx], privSz);
+    *inOutIdx += length;
+
+    if ((*inOutIdx + 1) < inSz) {
+        /* prefix 0, may have */
+        b = input[*inOutIdx];
+        if (b == ECC_PREFIX_0) {
+            *inOutIdx += 1;
+
+            if (GetLength(input, inOutIdx, &length, inSz) <= 0)
+                ret = ASN_PARSE_E;
+            else {
+                ret = GetObjectId(input, inOutIdx, &oidSum, oidIgnoreType,
+                                  inSz);
+                if (ret == 0) {
+                    if ((ret = CheckCurve(oidSum)) < 0)
+                        ret = ECC_CURVE_OID_E;
+                    else {
+                        curve_id = ret;
+                        ret = 0;
+                    }
+                }
+            }
+        }
+    }
+
+    if (ret == 0 && (*inOutIdx + 1) < inSz) {
+        /* prefix 1 */
+        b = input[*inOutIdx];
+        *inOutIdx += 1;
+
+        if (b != ECC_PREFIX_1) {
+            ret = ASN_ECC_KEY_E;
+        }
+        else if (GetLength(input, inOutIdx, &length, inSz) <= 0) {
+            ret = ASN_PARSE_E;
+        }
+        else {
+            /* key header */
+            ret = CheckBitString(input, inOutIdx, &length, inSz, 0, NULL);
+            if (ret == 0) {
+                /* pub key */
+                pubSz = length;
+                if (pubSz < 2*(ECC_MAXSIZE+1)) {
+                    XMEMCPY(pub, &input[*inOutIdx], pubSz);
+                    *inOutIdx += length;
+                    pubData = pub;
+                }
+                else
+                    ret = BUFFER_E;
+            }
+        }
+    }
+
+    if (ret == 0) {
+        ret = wc_ecc_import_private_key_ex(priv, privSz, pubData, pubSz, key,
+                                                                      curve_id);
+    }
+
+#ifdef WOLFSSL_SMALL_STACK
+    XFREE(priv, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
+    XFREE(pub,  key->heap, DYNAMIC_TYPE_TMP_BUFFER);
+#endif
+
+    return ret;
+}
+
+
+#ifdef WOLFSSL_CUSTOM_CURVES
+static void ByteToHex(byte n, char* str)
+{
+    const char hexChar[] = { '0', '1', '2', '3', '4', '5', '6', '7',
+                                    '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
+
+    str[0] = hexChar[n >> 4];
+    str[1] = hexChar[n & 0xf];
+}
+
+/* returns 0 on success */
+static int ASNToHexString(const byte* input, word32* inOutIdx, char** out,
+                          word32 inSz, void* heap, int heapType)
+{
+    int len;
+    int i;
+    char* str;
+    word32 localIdx;
+    byte   tag;
+
+    if (*inOutIdx >= inSz) {
+        return BUFFER_E;
+    }
+
+    localIdx = *inOutIdx;
+    if (GetASNTag(input, &localIdx, &tag, inSz) == 0 && tag == ASN_INTEGER) {
+        if (GetASNInt(input, inOutIdx, &len, inSz) < 0)
+            return ASN_PARSE_E;
+    }
+    else {
+        if (GetOctetString(input, inOutIdx, &len, inSz) < 0)
+            return ASN_PARSE_E;
+    }
+
+    str = (char*)XMALLOC(len * 2 + 1, heap, heapType);
+    for (i=0; i<len; i++)
+        ByteToHex(input[*inOutIdx + i], str + i*2);
+    str[len*2] = '\0';
+
+    *inOutIdx += len;
+    *out = str;
+
+    (void)heap;
+    (void)heapType;
+
+    return 0;
+}
+#endif /* WOLFSSL_CUSTOM_CURVES */
+
+#ifdef WOLFSSL_CUSTOM_CURVES
+static int EccKeyParamCopy(char** dst, char* src)
+{
+    int ret = 0;
+#ifdef WOLFSSL_ECC_CURVE_STATIC
+    word32 length;
+#endif
+
+    if (dst == NULL || src == NULL)
+        return BAD_FUNC_ARG;
+
+#ifndef WOLFSSL_ECC_CURVE_STATIC
+    *dst = src;
+#else
+    length = (int)XSTRLEN(src) + 1;
+    if (length > MAX_ECC_STRING) {
+        WOLFSSL_MSG("ECC Param too large for buffer");
+        ret = BUFFER_E;
+    }
+    else {
+        XSTRNCPY(*dst, src, length);
+    }
+    XFREE(src, key->heap, DYNAMIC_TYPE_ECC_BUFFER);
+#endif
+
+    return ret;
+}
+#endif /* WOLFSSL_CUSTOM_CURVES */
+
+int wc_EccPublicKeyDecode(const byte* input, word32* inOutIdx,
+                          ecc_key* key, word32 inSz)
+{
+    int    length;
+    int    ret;
+    int    curve_id = ECC_CURVE_DEF;
+    word32 oidSum, localIdx;
+    byte   tag;
+
+    if (input == NULL || inOutIdx == NULL || key == NULL || inSz == 0)
+        return BAD_FUNC_ARG;
+
+    if (GetSequence(input, inOutIdx, &length, inSz) < 0)
+        return ASN_PARSE_E;
+
+    if (GetSequence(input, inOutIdx, &length, inSz) < 0)
+        return ASN_PARSE_E;
+
+    ret = SkipObjectId(input, inOutIdx, inSz);
+    if (ret != 0)
+        return ret;
+
+    if (*inOutIdx >= inSz) {
+        return BUFFER_E;
+    }
+
+    localIdx = *inOutIdx;
+    if (GetASNTag(input, &localIdx, &tag, inSz) == 0 &&
+            tag == (ASN_SEQUENCE | ASN_CONSTRUCTED)) {
+#ifdef WOLFSSL_CUSTOM_CURVES
+        ecc_set_type* curve;
+        int len;
+        char* point = NULL;
+
+        ret = 0;
+
+        curve = (ecc_set_type*)XMALLOC(sizeof(*curve), key->heap,
+                                                       DYNAMIC_TYPE_ECC_BUFFER);
+        if (curve == NULL)
+            ret = MEMORY_E;
+
+        if (ret == 0) {
+            static const char customName[] = "Custom";
+            XMEMSET(curve, 0, sizeof(*curve));
+        #ifndef WOLFSSL_ECC_CURVE_STATIC
+            curve->name = customName;
+        #else
+            XMEMCPY((void*)curve->name, customName, sizeof(customName));
+        #endif
+            curve->id = ECC_CURVE_CUSTOM;
+
+            if (GetSequence(input, inOutIdx, &length, inSz) < 0)
+                ret = ASN_PARSE_E;
+        }
+
+        if (ret == 0) {
+            GetInteger7Bit(input, inOutIdx, inSz);
+            if (GetSequence(input, inOutIdx, &length, inSz) < 0)
+                ret = ASN_PARSE_E;
+        }
+        if (ret == 0) {
+            char* p = NULL;
+            SkipObjectId(input, inOutIdx, inSz);
+            ret = ASNToHexString(input, inOutIdx, &p, inSz,
+                                            key->heap, DYNAMIC_TYPE_ECC_BUFFER);
+            if (ret == 0)
+                ret = EccKeyParamCopy((char**)&curve->prime, p);
+        }
+        if (ret == 0) {
+            curve->size = (int)XSTRLEN(curve->prime) / 2;
+
+            if (GetSequence(input, inOutIdx, &length, inSz) < 0)
+                ret = ASN_PARSE_E;
+        }
+        if (ret == 0) {
+            char* af = NULL;
+            ret = ASNToHexString(input, inOutIdx, &af, inSz,
+                                            key->heap, DYNAMIC_TYPE_ECC_BUFFER);
+            if (ret == 0)
+                ret = EccKeyParamCopy((char**)&curve->Af, af);
+        }
+        if (ret == 0) {
+            char* bf = NULL;
+            ret = ASNToHexString(input, inOutIdx, &bf, inSz,
+                                            key->heap, DYNAMIC_TYPE_ECC_BUFFER);
+            if (ret == 0)
+                ret = EccKeyParamCopy((char**)&curve->Bf, bf);
+        }
+        if (ret == 0) {
+            localIdx = *inOutIdx;
+            if (*inOutIdx < inSz && GetASNTag(input, &localIdx, &tag, inSz)
+                    == 0 && tag == ASN_BIT_STRING) {
+                len = 0;
+                ret = GetASNHeader(input, ASN_BIT_STRING, inOutIdx, &len, inSz);
+                *inOutIdx += len;
+            }
+        }
+        if (ret == 0) {
+            ret = ASNToHexString(input, inOutIdx, (char**)&point, inSz,
+                                            key->heap, DYNAMIC_TYPE_ECC_BUFFER);
+
+            /* sanity check that point buffer is not smaller than the expected
+             * size to hold ( 0 4 || Gx || Gy )
+             * where Gx and Gy are each the size of curve->size * 2 */
+            if (ret == 0 && (int)XSTRLEN(point) < (curve->size * 4) + 2) {
+                XFREE(point, key->heap, DYNAMIC_TYPE_ECC_BUFFER);
+                ret = BUFFER_E;
+            }
+        }
+        if (ret == 0) {
+        #ifndef WOLFSSL_ECC_CURVE_STATIC
+            curve->Gx = (const char*)XMALLOC(curve->size * 2 + 2, key->heap,
+                                                       DYNAMIC_TYPE_ECC_BUFFER);
+            curve->Gy = (const char*)XMALLOC(curve->size * 2 + 2, key->heap,
+                                                       DYNAMIC_TYPE_ECC_BUFFER);
+            if (curve->Gx == NULL || curve->Gy == NULL) {
+                XFREE(point, key->heap, DYNAMIC_TYPE_ECC_BUFFER);
+                ret = MEMORY_E;
+            }
+        #else
+            if (curve->size * 2 + 2 > MAX_ECC_STRING) {
+                WOLFSSL_MSG("curve size is too large to fit in buffer");
+                ret = BUFFER_E;
+            }
+        #endif
+        }
+        if (ret == 0) {
+            char* o = NULL;
+
+            XMEMCPY((char*)curve->Gx, point + 2, curve->size * 2);
+            XMEMCPY((char*)curve->Gy, point + curve->size * 2 + 2,
+                                                               curve->size * 2);
+            ((char*)curve->Gx)[curve->size * 2] = '\0';
+            ((char*)curve->Gy)[curve->size * 2] = '\0';
+            XFREE(point, key->heap, DYNAMIC_TYPE_ECC_BUFFER);
+            ret = ASNToHexString(input, inOutIdx, &o, inSz,
+                                            key->heap, DYNAMIC_TYPE_ECC_BUFFER);
+            if (ret == 0)
+                ret = EccKeyParamCopy((char**)&curve->order, o);
+        }
+        if (ret == 0) {
+            curve->cofactor = GetInteger7Bit(input, inOutIdx, inSz);
+
+        #ifndef WOLFSSL_ECC_CURVE_STATIC
+            curve->oid = NULL;
+        #else
+            XMEMSET((void*)curve->oid, 0, sizeof(curve->oid));
+        #endif
+            curve->oidSz = 0;
+            curve->oidSum = 0;
+
+            if (wc_ecc_set_custom_curve(key, curve) < 0) {
+                ret = ASN_PARSE_E;
+            }
+        #ifdef WOLFSSL_CUSTOM_CURVES
+            key->deallocSet = 1;
+        #endif
+            curve = NULL;
+        }
+        if (curve != NULL)
+            wc_ecc_free_curve(curve, key->heap);
+
+        if (ret < 0)
+            return ret;
+#else
+        return ASN_PARSE_E;
+#endif /* WOLFSSL_CUSTOM_CURVES */
+    }
+    else {
+        /* ecc params information */
+        ret = GetObjectId(input, inOutIdx, &oidSum, oidIgnoreType, inSz);
+        if (ret != 0)
+            return ret;
+
+        /* get curve id */
+        curve_id = wc_ecc_get_oid(oidSum, NULL, 0);
+        if (curve_id < 0)
+            return ECC_CURVE_OID_E;
+    }
+
+    /* key header */
+    ret = CheckBitString(input, inOutIdx, &length, inSz, 1, NULL);
+    if (ret != 0)
+        return ret;
+
+    /* This is the raw point data compressed or uncompressed. */
+    if (wc_ecc_import_x963_ex(input + *inOutIdx, length, key,
+                                                            curve_id) != 0) {
+        return ASN_ECC_KEY_E;
+    }
+
+    *inOutIdx += length;
+
+    return 0;
+}
+
+#if defined(HAVE_ECC_KEY_EXPORT) && !defined(NO_ASN_CRYPT)
+/* build DER formatted ECC key, include optional public key if requested,
+ * return length on success, negative on error */
+static int wc_BuildEccKeyDer(ecc_key* key, byte* output, word32 inLen,
+                             int pubIn)
+{
+    byte   curve[MAX_ALGO_SZ+2];
+    byte   ver[MAX_VERSION_SZ];
+    byte   seq[MAX_SEQ_SZ];
+    byte   *prv = NULL, *pub = NULL;
+    int    ret, totalSz, curveSz, verSz;
+    int    privHdrSz  = ASN_ECC_HEADER_SZ;
+    int    pubHdrSz   = ASN_ECC_CONTEXT_SZ + ASN_ECC_HEADER_SZ;
+
+    word32 idx = 0, prvidx = 0, pubidx = 0, curveidx = 0;
+    word32 seqSz, privSz, pubSz = ECC_BUFSIZE;
+
+    if (key == NULL || output == NULL || inLen == 0)
+        return BAD_FUNC_ARG;
+
+    /* curve */
+    curve[curveidx++] = ECC_PREFIX_0;
+    curveidx++ /* to put the size after computation */;
+    curveSz = SetCurve(key, curve+curveidx);
+    if (curveSz < 0)
+        return curveSz;
+    /* set computed size */
+    curve[1] = (byte)curveSz;
+    curveidx += curveSz;
+
+    /* private */
+    privSz = key->dp->size;
+    prv = (byte*)XMALLOC(privSz + privHdrSz + MAX_SEQ_SZ,
+                         key->heap, DYNAMIC_TYPE_TMP_BUFFER);
+    if (prv == NULL) {
+        return MEMORY_E;
+    }
+    prvidx += SetOctetString8Bit(key->dp->size, &prv[prvidx]);
+    ret = wc_ecc_export_private_only(key, prv + prvidx, &privSz);
+    if (ret < 0) {
+        XFREE(prv, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
+        return ret;
+    }
+    prvidx += privSz;
+
+    /* pubIn */
+    if (pubIn) {
+        ret = wc_ecc_export_x963(key, NULL, &pubSz);
+        if (ret != LENGTH_ONLY_E) {
+            XFREE(prv, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
+            return ret;
+        }
+
+        pub = (byte*)XMALLOC(pubSz + pubHdrSz + MAX_SEQ_SZ,
+                             key->heap, DYNAMIC_TYPE_TMP_BUFFER);
+        if (pub == NULL) {
+            XFREE(prv, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
+            return MEMORY_E;
+        }
+
+        pub[pubidx++] = ECC_PREFIX_1;
+        if (pubSz > 128) /* leading zero + extra size byte */
+            pubidx += SetLength(pubSz + ASN_ECC_CONTEXT_SZ + 2, pub+pubidx);
+        else /* leading zero */
+            pubidx += SetLength(pubSz + ASN_ECC_CONTEXT_SZ + 1, pub+pubidx);
+
+        /* SetBitString adds leading zero */
+        pubidx += SetBitString(pubSz, 0, pub + pubidx);
+        ret = wc_ecc_export_x963(key, pub + pubidx, &pubSz);
+        if (ret != 0) {
+            XFREE(prv, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
+            XFREE(pub, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
+            return ret;
+        }
+        pubidx += pubSz;
+    }
+
+    /* make headers */
+    verSz = SetMyVersion(1, ver, FALSE);
+    seqSz = SetSequence(verSz + prvidx + pubidx + curveidx, seq);
+
+    totalSz = prvidx + pubidx + curveidx + verSz + seqSz;
+    if (totalSz > (int)inLen) {
+        XFREE(prv, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
+        if (pubIn) {
+            XFREE(pub, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
+        }
+        return BAD_FUNC_ARG;
+    }
+
+    /* write out */
+    /* seq */
+    XMEMCPY(output + idx, seq, seqSz);
+    idx = seqSz;
+
+    /* ver */
+    XMEMCPY(output + idx, ver, verSz);
+    idx += verSz;
+
+    /* private */
+    XMEMCPY(output + idx, prv, prvidx);
+    idx += prvidx;
+    XFREE(prv, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
+
+    /* curve */
+    XMEMCPY(output + idx, curve, curveidx);
+    idx += curveidx;
+
+    /* pubIn */
+    if (pubIn) {
+        XMEMCPY(output + idx, pub, pubidx);
+        /* idx += pubidx;  not used after write, if more data remove comment */
+        XFREE(pub, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
+    }
+
+    return totalSz;
+}
+
+/* Write a Private ecc key, including public to DER format,
+ * length on success else < 0 */
+int wc_EccKeyToDer(ecc_key* key, byte* output, word32 inLen)
+{
+    return wc_BuildEccKeyDer(key, output, inLen, 1);
+}
+
+
+/* Write only private ecc key to DER format,
+ * length on success else < 0 */
+int wc_EccPrivateKeyToDer(ecc_key* key, byte* output, word32 inLen)
+{
+    return wc_BuildEccKeyDer(key, output, inLen, 0);
+}
+
+#ifdef HAVE_PKCS8
+/* Write only private ecc key to unencrypted PKCS#8 format.
+ *
+ * If output is NULL, places required PKCS#8 buffer size in outLen and
+ * returns LENGTH_ONLY_E.
+ *
+ * return length on success else < 0 */
+int wc_EccPrivateKeyToPKCS8(ecc_key* key, byte* output, word32* outLen)
+{
+    int ret, tmpDerSz;
+    int algoID = 0;
+    word32 oidSz = 0;
+    word32 pkcs8Sz = 0;
+    const byte* curveOID = NULL;
+    byte* tmpDer = NULL;
+
+    if (key == NULL || outLen == NULL)
+        return BAD_FUNC_ARG;
+
+    /* set algoID, get curve OID */
+    algoID = ECDSAk;
+    ret = wc_ecc_get_oid(key->dp->oidSum, &curveOID, &oidSz);
+    if (ret < 0)
+        return ret;
+
+    /* temp buffer for plain DER key */
+    tmpDer = (byte*)XMALLOC(ECC_BUFSIZE, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
+    if (tmpDer == NULL)
+        return MEMORY_E;
+
+    XMEMSET(tmpDer, 0, ECC_BUFSIZE);
+
+    tmpDerSz = wc_BuildEccKeyDer(key, tmpDer, ECC_BUFSIZE, 0);
+    if (tmpDerSz < 0) {
+        XFREE(tmpDer, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
+        return tmpDerSz;
+    }
+
+    /* get pkcs8 expected output size */
+    ret = wc_CreatePKCS8Key(NULL, &pkcs8Sz, tmpDer, tmpDerSz, algoID,
+                            curveOID, oidSz);
+    if (ret != LENGTH_ONLY_E) {
+        XFREE(tmpDer, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
+        return ret;
+    }
+
+    if (output == NULL) {
+        XFREE(tmpDer, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
+        *outLen = pkcs8Sz;
+        return LENGTH_ONLY_E;
+
+    } else if (*outLen < pkcs8Sz) {
+        XFREE(tmpDer, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
+        WOLFSSL_MSG("Input buffer too small for ECC PKCS#8 key");
+        return BUFFER_E;
+    }
+
+    ret = wc_CreatePKCS8Key(output, &pkcs8Sz, tmpDer, tmpDerSz,
+                            algoID, curveOID, oidSz);
+    if (ret < 0) {
+        XFREE(tmpDer, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
+        return ret;
+    }
+
+    XFREE(tmpDer, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
+
+    *outLen = ret;
+    return ret;
+}
+#endif /* HAVE_PKCS8 */
+#endif /* HAVE_ECC_KEY_EXPORT && !NO_ASN_CRYPT */
+#endif /* HAVE_ECC */
+
+
+#ifdef HAVE_ED25519
+
+int wc_Ed25519PrivateKeyDecode(const byte* input, word32* inOutIdx,
+                               ed25519_key* key, word32 inSz)
+{
+    word32      oid;
+    int         ret, version, length, endKeyIdx, privSz, pubSz;
+    const byte* priv;
+    const byte* pub;
+
+    if (input == NULL || inOutIdx == NULL || key == NULL || inSz == 0)
+        return BAD_FUNC_ARG;
+
+    if (GetSequence(input, inOutIdx, &length, inSz) >= 0) {
+        endKeyIdx = *inOutIdx + length;
+
+        if (GetMyVersion(input, inOutIdx, &version, inSz) < 0)
+            return ASN_PARSE_E;
+        if (version != 0) {
+            WOLFSSL_MSG("Unrecognized version of ED25519 private key");
+            return ASN_PARSE_E;
+        }
+
+        if (GetAlgoId(input, inOutIdx, &oid, oidKeyType, inSz) < 0)
+            return ASN_PARSE_E;
+        if (oid != ED25519k)
+            return ASN_PARSE_E;
+
+        if (GetOctetString(input, inOutIdx, &length, inSz) < 0)
+            return ASN_PARSE_E;
+
+        if (GetOctetString(input, inOutIdx, &privSz, inSz) < 0)
+            return ASN_PARSE_E;
+
+        priv = input + *inOutIdx;
+        *inOutIdx += privSz;
+    }
+    else {
+        if (GetOctetString(input, inOutIdx, &privSz, inSz) < 0)
+            return ASN_PARSE_E;
+
+        if (privSz != 32)
+            return ASN_PARSE_E;
+
+        priv = input + *inOutIdx;
+        *inOutIdx += privSz;
+        endKeyIdx = *inOutIdx;
+    }
+
+    if (endKeyIdx == (int)*inOutIdx) {
+        ret = wc_ed25519_import_private_only(priv, privSz, key);
+    }
+    else {
+        if (GetASNHeader(input, ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | 1,
+                         inOutIdx, &length, inSz) < 0) {
+            return ASN_PARSE_E;
+        }
+        if (GetOctetString(input, inOutIdx, &pubSz, inSz) < 0)
+            return ASN_PARSE_E;
+        pub = input + *inOutIdx;
+        *inOutIdx += pubSz;
+
+        ret = wc_ed25519_import_private_key(priv, privSz, pub, pubSz, key);
+    }
+    if (ret == 0 && endKeyIdx != (int)*inOutIdx)
+        return ASN_PARSE_E;
+
+    return ret;
+}
+
+
+int wc_Ed25519PublicKeyDecode(const byte* input, word32* inOutIdx,
+                              ed25519_key* key, word32 inSz)
+{
+    int    length;
+    int    ret;
+
+    if (input == NULL || inOutIdx == NULL || key == NULL || inSz == 0)
+        return BAD_FUNC_ARG;
+
+    if (GetSequence(input, inOutIdx, &length, inSz) < 0)
+        return ASN_PARSE_E;
+
+    if (GetSequence(input, inOutIdx, &length, inSz) < 0)
+        return ASN_PARSE_E;
+
+    ret = SkipObjectId(input, inOutIdx, inSz);
+    if (ret != 0)
+        return ret;
+
+    /* key header */
+    ret = CheckBitString(input, inOutIdx, NULL, inSz, 1, NULL);
+    if (ret != 0)
+        return ret;
+
+    /* This is the raw point data compressed or uncompressed. */
+    if (wc_ed25519_import_public(input + *inOutIdx, inSz - *inOutIdx, key) != 0)
+        return ASN_ECC_KEY_E;
+
+    return 0;
+}
+
+
+#ifdef WOLFSSL_KEY_GEN
+
+/* build DER formatted ED25519 key,
+ * return length on success, negative on error */
+static int wc_BuildEd25519KeyDer(ed25519_key* key, byte* output, word32 inLen,
+                                 int pubOut)
+{
+    byte   algoArray[MAX_ALGO_SZ];
+    byte   ver[MAX_VERSION_SZ];
+    byte   seq[MAX_SEQ_SZ];
+    int    ret;
+    word32 idx = 0, seqSz, verSz, algoSz, privSz, pubSz = 0;
+
+    if (key == NULL || output == NULL || inLen == 0)
+        return BAD_FUNC_ARG;
+
+    if (pubOut)
+        pubSz = 2 + 2 + ED25519_PUB_KEY_SIZE;
+    privSz = 2 + 2 + ED25519_KEY_SIZE;
+    algoSz = SetAlgoID(ED25519k, algoArray, oidKeyType, 0);
+    verSz  = SetMyVersion(0, ver, FALSE);
+    seqSz  = SetSequence(verSz + algoSz + privSz + pubSz, seq);
+
+    if (seqSz + verSz + algoSz + privSz + pubSz > inLen)
+        return BAD_FUNC_ARG;
+
+    /* write out */
+    /* seq */
+    XMEMCPY(output + idx, seq, seqSz);
+    idx = seqSz;
+    /* ver */
+    XMEMCPY(output + idx, ver, verSz);
+    idx += verSz;
+    /* algo */
+    XMEMCPY(output + idx, algoArray, algoSz);
+    idx += algoSz;
+    /* privKey */
+    idx += SetOctetString(2 + ED25519_KEY_SIZE, output + idx);
+    idx += SetOctetString(ED25519_KEY_SIZE, output + idx);
+    ret = wc_ed25519_export_private_only(key, output + idx, &privSz);
+    if (ret != 0)
+        return ret;
+    idx += privSz;
+    /* pubKey */
+    if (pubOut) {
+        idx += SetExplicit(1, 2 + ED25519_PUB_KEY_SIZE, output + idx);
+        idx += SetOctetString(ED25519_KEY_SIZE, output + idx);
+        ret = wc_ed25519_export_public(key, output + idx, &pubSz);
+        if (ret != 0)
+            return ret;
+        idx += pubSz;
+    }
+
+    return idx;
+}
+
+/* Write a Private ecc key, including public to DER format,
+ * length on success else < 0 */
+int wc_Ed25519KeyToDer(ed25519_key* key, byte* output, word32 inLen)
+{
+    return wc_BuildEd25519KeyDer(key, output, inLen, 1);
+}
+
+
+
+/* Write only private ecc key to DER format,
+ * length on success else < 0 */
+int wc_Ed25519PrivateKeyToDer(ed25519_key* key, byte* output, word32 inLen)
+{
+    return wc_BuildEd25519KeyDer(key, output, inLen, 0);
+}
+
+#endif /* WOLFSSL_KEY_GEN */
+
+#endif /* HAVE_ED25519 */
+
+#ifdef HAVE_ED448
+
+int wc_Ed448PrivateKeyDecode(const byte* input, word32* inOutIdx,
+                             ed448_key* key, word32 inSz)
+{
+    word32      oid;
+    int         ret, version, length, endKeyIdx, privSz, pubSz;
+    const byte* priv;
+    const byte* pub;
+
+    if (input == NULL || inOutIdx == NULL || key == NULL || inSz == 0)
+        return BAD_FUNC_ARG;
+
+    if (GetSequence(input, inOutIdx, &length, inSz) >= 0) {
+        endKeyIdx = *inOutIdx + length;
+
+        if (GetMyVersion(input, inOutIdx, &version, inSz) < 0)
+            return ASN_PARSE_E;
+        if (version != 0) {
+            WOLFSSL_MSG("Unrecognized version of ED448 private key");
+            return ASN_PARSE_E;
+        }
+
+        if (GetAlgoId(input, inOutIdx, &oid, oidKeyType, inSz) < 0)
+            return ASN_PARSE_E;
+        if (oid != ED448k)
+            return ASN_PARSE_E;
+
+        if (GetOctetString(input, inOutIdx, &length, inSz) < 0)
+            return ASN_PARSE_E;
+
+        if (GetOctetString(input, inOutIdx, &privSz, inSz) < 0)
+            return ASN_PARSE_E;
+
+        priv = input + *inOutIdx;
+        *inOutIdx += privSz;
+    }
+    else {
+        if (GetOctetString(input, inOutIdx, &privSz, inSz) < 0)
+            return ASN_PARSE_E;
+
+        if (privSz != 57)
+            return ASN_PARSE_E;
+
+        priv = input + *inOutIdx;
+        *inOutIdx += privSz;
+        endKeyIdx = *inOutIdx;
+    }
+
+    if (endKeyIdx == (int)*inOutIdx) {
+        ret = wc_ed448_import_private_only(priv, privSz, key);
+    }
+    else {
+        if (GetASNHeader(input, ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | 1,
+                         inOutIdx, &length, inSz) < 0) {
+            return ASN_PARSE_E;
+        }
+        if (GetOctetString(input, inOutIdx, &pubSz, inSz) < 0)
+            return ASN_PARSE_E;
+        pub = input + *inOutIdx;
+        *inOutIdx += pubSz;
+
+        ret = wc_ed448_import_private_key(priv, privSz, pub, pubSz, key);
+    }
+    if (ret == 0 && endKeyIdx != (int)*inOutIdx)
+        return ASN_PARSE_E;
+
+    return ret;
+}
+
+
+int wc_Ed448PublicKeyDecode(const byte* input, word32* inOutIdx,
+                            ed448_key* key, word32 inSz)
+{
+    int    length;
+    int    ret;
+
+    if (input == NULL || inOutIdx == NULL || key == NULL || inSz == 0)
+        return BAD_FUNC_ARG;
+
+    if (GetSequence(input, inOutIdx, &length, inSz) < 0)
+        return ASN_PARSE_E;
+
+    if (GetSequence(input, inOutIdx, &length, inSz) < 0)
+        return ASN_PARSE_E;
+
+    ret = SkipObjectId(input, inOutIdx, inSz);
+    if (ret != 0)
+        return ret;
+
+    /* key header */
+    ret = CheckBitString(input, inOutIdx, NULL, inSz, 1, NULL);
+    if (ret != 0)
+        return ret;
+
+    /* This is the raw point data compressed or uncompressed. */
+    if (wc_ed448_import_public(input + *inOutIdx, inSz - *inOutIdx, key) != 0)
+        return ASN_ECC_KEY_E;
+
+    return 0;
+}
+
+
+#ifdef WOLFSSL_KEY_GEN
+
+/* build DER formatted ED448 key,
+ * return length on success, negative on error */
+static int wc_BuildEd448KeyDer(ed448_key* key, byte* output, word32 inLen,
+                               int pubOut)
+{
+    byte   algoArray[MAX_ALGO_SZ];
+    byte   ver[MAX_VERSION_SZ];
+    byte   seq[MAX_SEQ_SZ];
+    int    ret;
+    word32 idx = 0, seqSz, verSz, algoSz, privSz, pubSz = 0;
+
+    if (key == NULL || output == NULL || inLen == 0)
+        return BAD_FUNC_ARG;
+
+    if (pubOut) {
+        pubSz = 2 + 2 + ED448_PUB_KEY_SIZE;
+    }
+    privSz = 2 + 2 + ED448_KEY_SIZE;
+    algoSz = SetAlgoID(ED448k, algoArray, oidKeyType, 0);
+    verSz  = SetMyVersion(0, ver, FALSE);
+    seqSz  = SetSequence(verSz + algoSz + privSz + pubSz, seq);
+
+    if (seqSz + verSz + algoSz + privSz + pubSz > inLen)
+        return BAD_FUNC_ARG;
+
+    /* write out */
+    /* seq */
+    XMEMCPY(output + idx, seq, seqSz);
+    idx = seqSz;
+    /* ver */
+    XMEMCPY(output + idx, ver, verSz);
+    idx += verSz;
+    /* algo */
+    XMEMCPY(output + idx, algoArray, algoSz);
+    idx += algoSz;
+    /* privKey */
+    idx += SetOctetString(2 + ED448_KEY_SIZE, output + idx);
+    idx += SetOctetString(ED448_KEY_SIZE, output + idx);
+    ret = wc_ed448_export_private_only(key, output + idx, &privSz);
+    if (ret != 0)
+        return ret;
+    idx += privSz;
+    /* pubKey */
+    if (pubOut) {
+        idx += SetExplicit(1, 2 + ED448_PUB_KEY_SIZE, output + idx);
+        idx += SetOctetString(ED448_KEY_SIZE, output + idx);
+        ret = wc_ed448_export_public(key, output + idx, &pubSz);
+        if (ret != 0)
+            return ret;
+        idx += pubSz;
+    }
+
+    return idx;
+}
+
+/* Write a Private ecc key, including public to DER format,
+ * length on success else < 0 */
+int wc_Ed448KeyToDer(ed448_key* key, byte* output, word32 inLen)
+{
+    return wc_BuildEd448KeyDer(key, output, inLen, 1);
+}
+
+
+
+/* Write only private ecc key to DER format,
+ * length on success else < 0 */
+int wc_Ed448PrivateKeyToDer(ed448_key* key, byte* output, word32 inLen)
+{
+    return wc_BuildEd448KeyDer(key, output, inLen, 0);
+}
+
+#endif /* WOLFSSL_KEY_GEN */
+
+#endif /* HAVE_ED448 */
+
+#if defined(HAVE_OCSP) || defined(HAVE_CRL)
+
+/* Get raw Date only, no processing, 0 on success */
+static int GetBasicDate(const byte* source, word32* idx, byte* date,
+                        byte* format, int maxIdx)
+{
+    int    ret, length;
+    const byte *datePtr = NULL;
+
+    WOLFSSL_ENTER("GetBasicDate");
+
+    ret = GetDateInfo(source, idx, &datePtr, format, &length, maxIdx);
+    if (ret < 0)
+        return ret;
+
+    XMEMCPY(date, datePtr, length);
+
+    return 0;
+}
+
+#endif /* HAVE_OCSP || HAVE_CRL */
+
+
+#ifdef HAVE_OCSP
+
+static int GetEnumerated(const byte* input, word32* inOutIdx, int *value,
+        int sz)
+{
+    word32 idx = *inOutIdx;
+    word32 len;
+    byte   tag;
+
+    WOLFSSL_ENTER("GetEnumerated");
+
+    *value = 0;
+
+    if (GetASNTag(input, &idx, &tag, sz) < 0)
+        return ASN_PARSE_E;
+
+    if (tag != ASN_ENUMERATED)
+        return ASN_PARSE_E;
+
+    if ((int)idx >= sz)
+        return BUFFER_E;
+
+    len = input[idx++];
+    if (len > 4 || (int)(len + idx) > sz)
+        return ASN_PARSE_E;
+
+    while (len--) {
+        *value  = *value << 8 | input[idx++];
+    }
+
+    *inOutIdx = idx;
+
+    return *value;
+}
+
+
+static int DecodeSingleResponse(byte* source,
+                            word32* ioIndex, OcspResponse* resp, word32 size)
+{
+    word32 idx = *ioIndex, prevIndex, oid, localIdx;
+    int length, wrapperSz;
+    CertStatus* cs = resp->status;
+    int ret;
+    byte tag;
+
+    WOLFSSL_ENTER("DecodeSingleResponse");
+
+    /* Outer wrapper of the SEQUENCE OF Single Responses. */
+    if (GetSequence(source, &idx, &wrapperSz, size) < 0)
+        return ASN_PARSE_E;
+
+    prevIndex = idx;
+
+    /* When making a request, we only request one status on one certificate
+     * at a time. There should only be one SingleResponse */
+
+    /* Wrapper around the Single Response */
+    if (GetSequence(source, &idx, &length, size) < 0)
+        return ASN_PARSE_E;
+
+    /* Wrapper around the CertID */
+    if (GetSequence(source, &idx, &length, size) < 0)
+        return ASN_PARSE_E;
+    /* Skip the hash algorithm */
+    if (GetAlgoId(source, &idx, &oid, oidIgnoreType, size) < 0)
+        return ASN_PARSE_E;
+    /* Save reference to the hash of CN */
+    ret = GetOctetString(source, &idx, &length, size);
+    if (ret < 0)
+        return ret;
+    resp->issuerHash = source + idx;
+    idx += length;
+    /* Save reference to the hash of the issuer public key */
+    ret = GetOctetString(source, &idx, &length, size);
+    if (ret < 0)
+        return ret;
+    resp->issuerKeyHash = source + idx;
+    idx += length;
+
+    /* Get serial number */
+    if (GetSerialNumber(source, &idx, cs->serial, &cs->serialSz, size) < 0)
+        return ASN_PARSE_E;
+
+    if ( idx >= size )
+        return BUFFER_E;
+
+    /* CertStatus */
+    switch (source[idx++])
+    {
+        case (ASN_CONTEXT_SPECIFIC | CERT_GOOD):
+            cs->status = CERT_GOOD;
+            idx++;
+            break;
+        case (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | CERT_REVOKED):
+            cs->status = CERT_REVOKED;
+            if (GetLength(source, &idx, &length, size) < 0)
+                return ASN_PARSE_E;
+            idx += length;
+            break;
+        case (ASN_CONTEXT_SPECIFIC | CERT_UNKNOWN):
+            cs->status = CERT_UNKNOWN;
+            idx++;
+            break;
+        default:
+            return ASN_PARSE_E;
+    }
+
+#if defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY)
+    cs->thisDateAsn = source + idx;
+    localIdx = 0;
+    if (GetDateInfo(cs->thisDateAsn, &localIdx, NULL,
+                    (byte*)&cs->thisDateParsed.type,
+                    &cs->thisDateParsed.length, size) < 0)
+        return ASN_PARSE_E;
+    XMEMCPY(cs->thisDateParsed.data,
+            cs->thisDateAsn + localIdx - cs->thisDateParsed.length,
+            cs->thisDateParsed.length);
+#endif
+    if (GetBasicDate(source, &idx, cs->thisDate,
+                                                &cs->thisDateFormat, size) < 0)
+        return ASN_PARSE_E;
+
+#ifndef NO_ASN_TIME
+#ifndef WOLFSSL_NO_OCSP_DATE_CHECK
+    if (!XVALIDATE_DATE(cs->thisDate, cs->thisDateFormat, BEFORE))
+        return ASN_BEFORE_DATE_E;
+#endif
+#endif
+
+    /* The following items are optional. Only check for them if there is more
+     * unprocessed data in the singleResponse wrapper. */
+
+    localIdx = idx;
+    if (((int)(idx - prevIndex) < wrapperSz) &&
+        GetASNTag(source, &localIdx, &tag, size) == 0 &&
+        tag == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 0))
+    {
+        idx++;
+        if (GetLength(source, &idx, &length, size) < 0)
+            return ASN_PARSE_E;
+#if defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY)
+        cs->nextDateAsn = source + idx;
+        localIdx = 0;
+        if (GetDateInfo(cs->nextDateAsn, &localIdx, NULL,
+                        (byte*)&cs->nextDateParsed.type,
+                        &cs->nextDateParsed.length, size) < 0)
+            return ASN_PARSE_E;
+        XMEMCPY(cs->nextDateParsed.data,
+                cs->nextDateAsn + localIdx - cs->nextDateParsed.length,
+                cs->nextDateParsed.length);
+#endif
+        if (GetBasicDate(source, &idx, cs->nextDate,
+                                                &cs->nextDateFormat, size) < 0)
+            return ASN_PARSE_E;
+
+#ifndef NO_ASN_TIME
+#ifndef WOLFSSL_NO_OCSP_DATE_CHECK
+        if (!XVALIDATE_DATE(cs->nextDate, cs->nextDateFormat, AFTER))
+            return ASN_AFTER_DATE_E;
+#endif
+#endif
+    }
+
+    localIdx = idx;
+    if (((int)(idx - prevIndex) < wrapperSz) &&
+        GetASNTag(source, &localIdx, &tag, size) == 0 &&
+        tag == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 1))
+    {
+        idx++;
+        if (GetLength(source, &idx, &length, size) < 0)
+            return ASN_PARSE_E;
+        idx += length;
+    }
+
+    *ioIndex = idx;
+
+    return 0;
+}
+
+static int DecodeOcspRespExtensions(byte* source,
+                            word32* ioIndex, OcspResponse* resp, word32 sz)
+{
+    word32 idx = *ioIndex;
+    int length;
+    int ext_bound; /* boundary index for the sequence of extensions */
+    word32 oid;
+    int ret;
+    byte tag;
+
+    WOLFSSL_ENTER("DecodeOcspRespExtensions");
+
+    if ((idx + 1) > sz)
+        return BUFFER_E;
+
+    if (GetASNTag(source, &idx, &tag, sz) < 0)
+        return ASN_PARSE_E;
+
+    if (tag != (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 1))
+        return ASN_PARSE_E;
+
+    if (GetLength(source, &idx, &length, sz) < 0)
+        return ASN_PARSE_E;
+
+    if (GetSequence(source, &idx, &length, sz) < 0)
+        return ASN_PARSE_E;
+
+    ext_bound = idx + length;
+
+    while (idx < (word32)ext_bound) {
+        word32 localIdx;
+
+        if (GetSequence(source, &idx, &length, sz) < 0) {
+            WOLFSSL_MSG("\tfail: should be a SEQUENCE");
+            return ASN_PARSE_E;
+        }
+
+        oid = 0;
+        if (GetObjectId(source, &idx, &oid, oidOcspType, sz) < 0) {
+            WOLFSSL_MSG("\tfail: OBJECT ID");
+            return ASN_PARSE_E;
+        }
+
+        /* check for critical flag */
+        if ((idx + 1) > (word32)sz) {
+            WOLFSSL_MSG("\tfail: malformed buffer");
+            return BUFFER_E;
+        }
+
+        localIdx = idx;
+        if (GetASNTag(source, &localIdx, &tag, sz) == 0 && tag == ASN_BOOLEAN) {
+            WOLFSSL_MSG("\tfound optional critical flag, moving past");
+            ret = GetBoolean(source, &idx, sz);
+            if (ret < 0)
+                return ret;
+        }
+
+        ret = GetOctetString(source, &idx, &length, sz);
+        if (ret < 0)
+            return ret;
+
+        if (oid == OCSP_NONCE_OID) {
+            /* get data inside extra OCTET_STRING */
+            ret = GetOctetString(source, &idx, &length, sz);
+            if (ret < 0)
+                return ret;
+
+            resp->nonce = source + idx;
+            resp->nonceSz = length;
+        }
+
+        idx += length;
+    }
+
+    *ioIndex = idx;
+    return 0;
+}
+
+
+static int DecodeResponseData(byte* source,
+                            word32* ioIndex, OcspResponse* resp, word32 size)
+{
+    word32 idx = *ioIndex, prev_idx, localIdx;
+    int length;
+    int version;
+    int ret;
+    byte tag;
+
+    WOLFSSL_ENTER("DecodeResponseData");
+
+    resp->response = source + idx;
+    prev_idx = idx;
+    if (GetSequence(source, &idx, &length, size) < 0)
+        return ASN_PARSE_E;
+    resp->responseSz = length + idx - prev_idx;
+
+    /* Get version. It is an EXPLICIT[0] DEFAULT(0) value. If this
+     * item isn't an EXPLICIT[0], then set version to zero and move
+     * onto the next item.
+     */
+    localIdx = idx;
+    if (GetASNTag(source, &localIdx, &tag, size) == 0 &&
+            tag == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED))
+    {
+        idx += 2; /* Eat the value and length */
+        if (GetMyVersion(source, &idx, &version, size) < 0)
+            return ASN_PARSE_E;
+    } else
+        version = 0;
+
+    localIdx = idx;
+    if (GetASNTag(source, &localIdx, &tag, size) == 0 &&
+        ( tag == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | 1) ||
+          tag == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | 2) ))
+    {
+        idx++; /* advance past ASN tag */
+        if (GetLength(source, &idx, &length, size) < 0)
+            return ASN_PARSE_E;
+        idx += length;
+    }
+    else
+        return ASN_PARSE_E;
+
+    /* save pointer to the producedAt time */
+    if (GetBasicDate(source, &idx, resp->producedDate,
+                                        &resp->producedDateFormat, size) < 0)
+        return ASN_PARSE_E;
+
+    if ((ret = DecodeSingleResponse(source, &idx, resp, size)) < 0)
+        return ret; /* ASN_PARSE_E, ASN_BEFORE_DATE_E, ASN_AFTER_DATE_E */
+
+    /*
+     * Check the length of the ResponseData against the current index to
+     * see if there are extensions, they are optional.
+     */
+    if (idx - prev_idx < resp->responseSz)
+        if (DecodeOcspRespExtensions(source, &idx, resp, size) < 0)
+            return ASN_PARSE_E;
+
+    *ioIndex = idx;
+    return 0;
+}
+
+
+#ifndef WOLFSSL_NO_OCSP_OPTIONAL_CERTS
+
+static int DecodeCerts(byte* source,
+                            word32* ioIndex, OcspResponse* resp, word32 size)
+{
+    word32 idx = *ioIndex;
+    byte tag;
+
+    WOLFSSL_ENTER("DecodeCerts");
+
+    if (GetASNTag(source, &idx, &tag, size) < 0)
+        return ASN_PARSE_E;
+
+    if (tag == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC))
+    {
+        int length;
+
+        if (GetLength(source, &idx, &length, size) < 0)
+            return ASN_PARSE_E;
+
+        if (GetSequence(source, &idx, &length, size) < 0)
+            return ASN_PARSE_E;
+
+        resp->cert = source + idx;
+        resp->certSz = length;
+
+        idx += length;
+    }
+    *ioIndex = idx;
+    return 0;
+}
+
+#endif /* WOLFSSL_NO_OCSP_OPTIONAL_CERTS */
+
+
+static int DecodeBasicOcspResponse(byte* source, word32* ioIndex,
+            OcspResponse* resp, word32 size, void* cm, void* heap, int noVerify)
+{
+    int    length;
+    word32 idx = *ioIndex;
+    word32 end_index;
+    int    ret;
+    int    sigLength;
+
+    WOLFSSL_ENTER("DecodeBasicOcspResponse");
+    (void)heap;
+
+    if (GetSequence(source, &idx, &length, size) < 0)
+        return ASN_PARSE_E;
+
+    if (idx + length > size)
+        return ASN_INPUT_E;
+    end_index = idx + length;
+
+    if ((ret = DecodeResponseData(source, &idx, resp, size)) < 0)
+        return ret; /* ASN_PARSE_E, ASN_BEFORE_DATE_E, ASN_AFTER_DATE_E */
+
+    /* Get the signature algorithm */
+    if (GetAlgoId(source, &idx, &resp->sigOID, oidSigType, size) < 0)
+        return ASN_PARSE_E;
+
+    ret = CheckBitString(source, &idx, &sigLength, size, 1, NULL);
+    if (ret != 0)
+        return ret;
+
+    resp->sigSz = sigLength;
+    resp->sig = source + idx;
+    idx += sigLength;
+
+    /*
+     * Check the length of the BasicOcspResponse against the current index to
+     * see if there are certificates, they are optional.
+     */
+#ifndef WOLFSSL_NO_OCSP_OPTIONAL_CERTS
+    if (idx < end_index)
+    {
+        DecodedCert cert;
+
+        if (DecodeCerts(source, &idx, resp, size) < 0)
+            return ASN_PARSE_E;
+
+        InitDecodedCert(&cert, resp->cert, resp->certSz, heap);
+
+        /* Don't verify if we don't have access to Cert Manager. */
+        ret = ParseCertRelative(&cert, CERT_TYPE,
+                                noVerify ? NO_VERIFY : VERIFY_OCSP, cm);
+        if (ret < 0) {
+            WOLFSSL_MSG("\tOCSP Responder certificate parsing failed");
+            FreeDecodedCert(&cert);
+            return ret;
+        }
+
+#ifndef WOLFSSL_NO_OCSP_ISSUER_CHECK
+        if ((cert.extExtKeyUsage & EXTKEYUSE_OCSP_SIGN) == 0) {
+            if (XMEMCMP(cert.subjectHash,
+                        resp->issuerHash, KEYID_SIZE) == 0) {
+                WOLFSSL_MSG("\tOCSP Response signed by issuer");
+            }
+            else {
+                WOLFSSL_MSG("\tOCSP Responder key usage check failed");
+    #ifdef OPENSSL_EXTRA
+                resp->verifyError = OCSP_BAD_ISSUER;
+    #else
+                FreeDecodedCert(&cert);
+                return BAD_OCSP_RESPONDER;
+    #endif
+            }
+        }
+#endif
+
+        /* ConfirmSignature is blocking here */
+        ret = ConfirmSignature(&cert.sigCtx,
+            resp->response, resp->responseSz,
+            cert.publicKey, cert.pubKeySize, cert.keyOID,
+            resp->sig, resp->sigSz, resp->sigOID, NULL);
+
+        FreeDecodedCert(&cert);
+
+        if (ret != 0) {
+            WOLFSSL_MSG("\tOCSP Confirm signature failed");
+            return ASN_OCSP_CONFIRM_E;
+        }
+    }
+    else
+#endif /* WOLFSSL_NO_OCSP_OPTIONAL_CERTS */
+    {
+        Signer* ca;
+        int sigValid = -1;
+
+        #ifndef NO_SKID
+            ca = GetCA(cm, resp->issuerKeyHash);
+        #else
+            ca = GetCA(cm, resp->issuerHash);
+        #endif
+
+        if (ca) {
+            SignatureCtx sigCtx;
+            InitSignatureCtx(&sigCtx, heap, INVALID_DEVID);
+
+            /* ConfirmSignature is blocking here */
+            sigValid = ConfirmSignature(&sigCtx, resp->response,
+                resp->responseSz, ca->publicKey, ca->pubKeySize, ca->keyOID,
+                                resp->sig, resp->sigSz, resp->sigOID, NULL);
+        }
+        if (ca == NULL || sigValid != 0) {
+            WOLFSSL_MSG("\tOCSP Confirm signature failed");
+            return ASN_OCSP_CONFIRM_E;
+        }
+
+        (void)noVerify;
+    }
+
+    *ioIndex = idx;
+    return 0;
+}
+
+
+void InitOcspResponse(OcspResponse* resp, CertStatus* status,
+                                                    byte* source, word32 inSz)
+{
+    WOLFSSL_ENTER("InitOcspResponse");
+
+    XMEMSET(status, 0, sizeof(CertStatus));
+    XMEMSET(resp,   0, sizeof(OcspResponse));
+
+    resp->responseStatus = -1;
+    resp->status         = status;
+    resp->source         = source;
+    resp->maxIdx         = inSz;
+}
+
+
+int OcspResponseDecode(OcspResponse* resp, void* cm, void* heap, int noVerify)
+{
+    int ret;
+    int length = 0;
+    word32 idx = 0;
+    byte* source = resp->source;
+    word32 size = resp->maxIdx;
+    word32 oid;
+    byte   tag;
+
+    WOLFSSL_ENTER("OcspResponseDecode");
+
+    /* peel the outer SEQUENCE wrapper */
+    if (GetSequence(source, &idx, &length, size) < 0)
+        return ASN_PARSE_E;
+
+    /* First get the responseStatus, an ENUMERATED */
+    if (GetEnumerated(source, &idx, &resp->responseStatus, size) < 0)
+        return ASN_PARSE_E;
+
+    if (resp->responseStatus != OCSP_SUCCESSFUL)
+        return 0;
+
+    /* Next is an EXPLICIT record called ResponseBytes, OPTIONAL */
+    if (idx >= size)
+        return ASN_INPUT_E;
+    if (GetASNTag(source, &idx, &tag, size) < 0)
+        return ASN_PARSE_E;
+    if (tag != (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC))
+        return ASN_PARSE_E;
+    if (GetLength(source, &idx, &length, size) < 0)
+        return ASN_PARSE_E;
+
+    /* Get the responseBytes SEQUENCE */
+    if (GetSequence(source, &idx, &length, size) < 0)
+        return ASN_PARSE_E;
+
+    /* Check ObjectID for the resposeBytes */
+    if (GetObjectId(source, &idx, &oid, oidOcspType, size) < 0)
+        return ASN_PARSE_E;
+    if (oid != OCSP_BASIC_OID)
+        return ASN_PARSE_E;
+    ret = GetOctetString(source, &idx, &length, size);
+    if (ret < 0)
+        return ret;
+
+    ret = DecodeBasicOcspResponse(source, &idx, resp, size, cm, heap, noVerify);
+    if (ret < 0)
+        return ret;
+
+    return 0;
+}
+
+
+word32 EncodeOcspRequestExtensions(OcspRequest* req, byte* output, word32 size)
+{
+    const byte NonceObjId[] = { 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07,
+                                       0x30, 0x01, 0x02 };
+    byte seqArray[5][MAX_SEQ_SZ];
+    word32 seqSz[5], totalSz = (word32)sizeof(NonceObjId);
+
+    WOLFSSL_ENTER("SetOcspReqExtensions");
+
+    if (!req || !output || !req->nonceSz)
+        return 0;
+
+    totalSz += req->nonceSz;
+    totalSz += seqSz[0] = SetOctetString(req->nonceSz, seqArray[0]);
+    totalSz += seqSz[1] = SetOctetString(req->nonceSz + seqSz[0], seqArray[1]);
+    totalSz += seqSz[2] = SetObjectId(sizeof(NonceObjId), seqArray[2]);
+    totalSz += seqSz[3] = SetSequence(totalSz, seqArray[3]);
+    totalSz += seqSz[4] = SetSequence(totalSz, seqArray[4]);
+
+    if (totalSz > size)
+        return 0;
+
+    totalSz = 0;
+
+    XMEMCPY(output + totalSz, seqArray[4], seqSz[4]);
+    totalSz += seqSz[4];
+
+    XMEMCPY(output + totalSz, seqArray[3], seqSz[3]);
+    totalSz += seqSz[3];
+
+    XMEMCPY(output + totalSz, seqArray[2], seqSz[2]);
+    totalSz += seqSz[2];
+
+    XMEMCPY(output + totalSz, NonceObjId, sizeof(NonceObjId));
+    totalSz += (word32)sizeof(NonceObjId);
+
+    XMEMCPY(output + totalSz, seqArray[1], seqSz[1]);
+    totalSz += seqSz[1];
+
+    XMEMCPY(output + totalSz, seqArray[0], seqSz[0]);
+    totalSz += seqSz[0];
+
+    XMEMCPY(output + totalSz, req->nonce, req->nonceSz);
+    totalSz += req->nonceSz;
+
+    return totalSz;
+}
+
+
+int EncodeOcspRequest(OcspRequest* req, byte* output, word32 size)
+{
+    byte seqArray[5][MAX_SEQ_SZ];
+    /* The ASN.1 of the OCSP Request is an onion of sequences */
+    byte algoArray[MAX_ALGO_SZ];
+    byte issuerArray[MAX_ENCODED_DIG_SZ];
+    byte issuerKeyArray[MAX_ENCODED_DIG_SZ];
+    byte snArray[MAX_SN_SZ];
+    byte extArray[MAX_OCSP_EXT_SZ];
+    word32 seqSz[5], algoSz, issuerSz, issuerKeySz, extSz, totalSz;
+    int i, snSz;
+
+    WOLFSSL_ENTER("EncodeOcspRequest");
+
+#ifdef NO_SHA
+    algoSz = SetAlgoID(SHA256h, algoArray, oidHashType, 0);
+#else
+    algoSz = SetAlgoID(SHAh, algoArray, oidHashType, 0);
+#endif
+
+    issuerSz    = SetDigest(req->issuerHash,    KEYID_SIZE,    issuerArray);
+    issuerKeySz = SetDigest(req->issuerKeyHash, KEYID_SIZE,    issuerKeyArray);
+    snSz        = SetSerialNumber(req->serial,  req->serialSz, snArray,
+                                                          MAX_SN_SZ, MAX_SN_SZ);
+    extSz       = 0;
+
+    if (snSz < 0)
+        return snSz;
+
+    if (req->nonceSz) {
+        /* TLS Extensions use this function too - put extensions after
+         * ASN.1: Context Specific [2].
+         */
+        extSz = EncodeOcspRequestExtensions(req, extArray + 2,
+                                            OCSP_NONCE_EXT_SZ);
+        extSz += SetExplicit(2, extSz, extArray);
+    }
+
+    totalSz = algoSz + issuerSz + issuerKeySz + snSz;
+    for (i = 4; i >= 0; i--) {
+        seqSz[i] = SetSequence(totalSz, seqArray[i]);
+        totalSz += seqSz[i];
+        if (i == 2) totalSz += extSz;
+    }
+
+    if (output == NULL)
+        return totalSz;
+    if (totalSz > size)
+        return BUFFER_E;
+
+    totalSz = 0;
+    for (i = 0; i < 5; i++) {
+        XMEMCPY(output + totalSz, seqArray[i], seqSz[i]);
+        totalSz += seqSz[i];
+    }
+
+    XMEMCPY(output + totalSz, algoArray, algoSz);
+    totalSz += algoSz;
+
+    XMEMCPY(output + totalSz, issuerArray, issuerSz);
+    totalSz += issuerSz;
+
+    XMEMCPY(output + totalSz, issuerKeyArray, issuerKeySz);
+    totalSz += issuerKeySz;
+
+    XMEMCPY(output + totalSz, snArray, snSz);
+    totalSz += snSz;
+
+    if (extSz != 0) {
+        XMEMCPY(output + totalSz, extArray, extSz);
+        totalSz += extSz;
+    }
+
+    return totalSz;
+}
+
+
+int InitOcspRequest(OcspRequest* req, DecodedCert* cert, byte useNonce,
+                                                                     void* heap)
+{
+    int ret;
+
+    WOLFSSL_ENTER("InitOcspRequest");
+
+    if (req == NULL)
+        return BAD_FUNC_ARG;
+
+    ForceZero(req, sizeof(OcspRequest));
+    req->heap = heap;
+
+    if (cert) {
+        XMEMCPY(req->issuerHash,    cert->issuerHash,    KEYID_SIZE);
+        XMEMCPY(req->issuerKeyHash, cert->issuerKeyHash, KEYID_SIZE);
+
+        req->serial = (byte*)XMALLOC(cert->serialSz, req->heap,
+                                                     DYNAMIC_TYPE_OCSP_REQUEST);
+        if (req->serial == NULL)
+            return MEMORY_E;
+
+        XMEMCPY(req->serial, cert->serial, cert->serialSz);
+        req->serialSz = cert->serialSz;
+
+        if (cert->extAuthInfoSz != 0 && cert->extAuthInfo != NULL) {
+            req->url = (byte*)XMALLOC(cert->extAuthInfoSz + 1, req->heap,
+                                                     DYNAMIC_TYPE_OCSP_REQUEST);
+            if (req->url == NULL) {
+                XFREE(req->serial, req->heap, DYNAMIC_TYPE_OCSP);
+                return MEMORY_E;
+            }
+
+            XMEMCPY(req->url, cert->extAuthInfo, cert->extAuthInfoSz);
+            req->urlSz = cert->extAuthInfoSz;
+            req->url[req->urlSz] = 0;
+        }
+    }
+
+    if (useNonce) {
+        WC_RNG rng;
+
+    #ifndef HAVE_FIPS
+        ret = wc_InitRng_ex(&rng, req->heap, INVALID_DEVID);
+    #else
+        ret = wc_InitRng(&rng);
+    #endif
+        if (ret != 0) {
+            WOLFSSL_MSG("\tCannot initialize RNG. Skipping the OSCP Nonce.");
+        } else {
+            if (wc_RNG_GenerateBlock(&rng, req->nonce, MAX_OCSP_NONCE_SZ) != 0)
+                WOLFSSL_MSG("\tCannot run RNG. Skipping the OSCP Nonce.");
+            else
+                req->nonceSz = MAX_OCSP_NONCE_SZ;
+
+            wc_FreeRng(&rng);
+        }
+    }
+
+    return 0;
+}
+
+void FreeOcspRequest(OcspRequest* req)
+{
+    WOLFSSL_ENTER("FreeOcspRequest");
+
+    if (req) {
+        if (req->serial)
+            XFREE(req->serial, req->heap, DYNAMIC_TYPE_OCSP_REQUEST);
+        req->serial = NULL;
+
+#ifdef OPENSSL_EXTRA
+        if (req->serialInt) {
+            if (req->serialInt->isDynamic) {
+                XFREE(req->serialInt->data, NULL, DYNAMIC_TYPE_OPENSSL);
+            }
+            XFREE(req->serialInt, NULL, DYNAMIC_TYPE_OPENSSL);
+        }
+        req->serialInt = NULL;
+#endif
+
+        if (req->url)
+            XFREE(req->url, req->heap, DYNAMIC_TYPE_OCSP_REQUEST);
+        req->url = NULL;
+    }
+}
+
+
+int CompareOcspReqResp(OcspRequest* req, OcspResponse* resp)
+{
+    int cmp;
+
+    WOLFSSL_ENTER("CompareOcspReqResp");
+
+    if (req == NULL)
+    {
+        WOLFSSL_MSG("\tReq missing");
+        return -1;
+    }
+
+    if (resp == NULL)
+    {
+        WOLFSSL_MSG("\tResp missing");
+        return 1;
+    }
+
+    /* Nonces are not critical. The responder may not necessarily add
+     * the nonce to the response. */
+    if (req->nonceSz
+#ifndef WOLFSSL_FORCE_OCSP_NONCE_CHECK
+            && resp->nonceSz != 0
+#endif
+    ) {
+        cmp = req->nonceSz - resp->nonceSz;
+        if (cmp != 0)
+        {
+            WOLFSSL_MSG("\tnonceSz mismatch");
+            return cmp;
+        }
+
+        cmp = XMEMCMP(req->nonce, resp->nonce, req->nonceSz);
+        if (cmp != 0)
+        {
+            WOLFSSL_MSG("\tnonce mismatch");
+            return cmp;
+        }
+    }
+
+    cmp = XMEMCMP(req->issuerHash, resp->issuerHash, KEYID_SIZE);
+    if (cmp != 0)
+    {
+        WOLFSSL_MSG("\tissuerHash mismatch");
+        return cmp;
+    }
+
+    cmp = XMEMCMP(req->issuerKeyHash, resp->issuerKeyHash, KEYID_SIZE);
+    if (cmp != 0)
+    {
+        WOLFSSL_MSG("\tissuerKeyHash mismatch");
+        return cmp;
+    }
+
+    cmp = req->serialSz - resp->status->serialSz;
+    if (cmp != 0)
+    {
+        WOLFSSL_MSG("\tserialSz mismatch");
+        return cmp;
+    }
+
+    cmp = XMEMCMP(req->serial, resp->status->serial, req->serialSz);
+    if (cmp != 0)
+    {
+        WOLFSSL_MSG("\tserial mismatch");
+        return cmp;
+    }
+
+    return 0;
+}
+
+#endif /* HAVE_OCSP */
+
+
+/* store WC_SHA hash of NAME */
+int GetNameHash(const byte* source, word32* idx, byte* hash,
+                             int maxIdx)
+{
+    int    length;  /* length of all distinguished names */
+    int    ret;
+    word32 dummy;
+    byte   tag;
+
+    WOLFSSL_ENTER("GetNameHash");
+
+    dummy = *idx;
+    if (GetASNTag(source, &dummy, &tag, maxIdx) == 0 && tag == ASN_OBJECT_ID) {
+        WOLFSSL_MSG("Trying optional prefix...");
+
+        if (GetLength(source, idx, &length, maxIdx) < 0)
+            return ASN_PARSE_E;
+
+        *idx += length;
+        WOLFSSL_MSG("Got optional prefix");
+    }
+
+    /* For OCSP, RFC2560 section 4.1.1 states the issuer hash should be
+     * calculated over the entire DER encoding of the Name field, including
+     * the tag and length. */
+    dummy = *idx;
+    if (GetSequence(source, idx, &length, maxIdx) < 0)
+        return ASN_PARSE_E;
+
+    ret = CalcHashId(source + dummy, length + *idx - dummy, hash);
+
+    *idx += length;
+
+    return ret;
+}
+
+
+#ifdef HAVE_CRL
+
+/* initialize decoded CRL */
+void InitDecodedCRL(DecodedCRL* dcrl, void* heap)
+{
+    WOLFSSL_MSG("InitDecodedCRL");
+
+    XMEMSET(dcrl, 0, sizeof(DecodedCRL));
+    dcrl->heap = heap;
+    #ifdef WOLFSSL_HEAP_TEST
+        dcrl->heap = (void*)WOLFSSL_HEAP_TEST;
+    #endif
+}
+
+
+/* free decoded CRL resources */
+void FreeDecodedCRL(DecodedCRL* dcrl)
+{
+    RevokedCert* tmp = dcrl->certs;
+
+    WOLFSSL_MSG("FreeDecodedCRL");
+
+    while(tmp) {
+        RevokedCert* next = tmp->next;
+        XFREE(tmp, dcrl->heap, DYNAMIC_TYPE_REVOKED);
+        tmp = next;
+    }
+}
+
+
+/* Get Revoked Cert list, 0 on success */
+static int GetRevoked(const byte* buff, word32* idx, DecodedCRL* dcrl,
+                      int maxIdx)
+{
+    int    ret, len;
+    word32 end;
+    byte   b;
+    RevokedCert* rc;
+
+    WOLFSSL_ENTER("GetRevoked");
+
+    if (GetSequence(buff, idx, &len, maxIdx) < 0)
+        return ASN_PARSE_E;
+
+    end = *idx + len;
+
+    rc = (RevokedCert*)XMALLOC(sizeof(RevokedCert), dcrl->heap,
+                                                          DYNAMIC_TYPE_REVOKED);
+    if (rc == NULL) {
+        WOLFSSL_MSG("Alloc Revoked Cert failed");
+        return MEMORY_E;
+    }
+
+    if (GetSerialNumber(buff, idx, rc->serialNumber, &rc->serialSz,
+                                                                maxIdx) < 0) {
+        XFREE(rc, dcrl->heap, DYNAMIC_TYPE_REVOKED);
+        return ASN_PARSE_E;
+    }
+
+    /* add to list */
+    rc->next = dcrl->certs;
+    dcrl->certs = rc;
+    dcrl->totalCerts++;
+
+    /* get date */
+    ret = GetDateInfo(buff, idx, NULL, &b, NULL, maxIdx);
+    if (ret < 0) {
+        WOLFSSL_MSG("Expecting Date");
+        return ret;
+    }
+
+    /* skip extensions */
+    *idx = end;
+
+    return 0;
+}
+
+
+/* Get CRL Signature, 0 on success */
+static int GetCRL_Signature(const byte* source, word32* idx, DecodedCRL* dcrl,
+                            int maxIdx)
+{
+    int    length;
+    int    ret;
+
+    WOLFSSL_ENTER("GetCRL_Signature");
+
+    ret = CheckBitString(source, idx, &length, maxIdx, 1, NULL);
+    if (ret != 0)
+        return ret;
+    dcrl->sigLength = length;
+
+    dcrl->signature = (byte*)&source[*idx];
+    *idx += dcrl->sigLength;
+
+    return 0;
+}
+
+int VerifyCRL_Signature(SignatureCtx* sigCtx, const byte* toBeSigned,
+                        word32 tbsSz, const byte* signature, word32 sigSz,
+                        word32 signatureOID, Signer *ca, void* heap)
+{
+    /* try to confirm/verify signature */
+#ifndef IGNORE_KEY_EXTENSIONS
+    if ((ca->keyUsage & KEYUSE_CRL_SIGN) == 0) {
+        WOLFSSL_MSG("CA cannot sign CRLs");
+        return ASN_CRL_NO_SIGNER_E;
+    }
+#endif /* IGNORE_KEY_EXTENSIONS */
+
+    InitSignatureCtx(sigCtx, heap, INVALID_DEVID);
+    if (ConfirmSignature(sigCtx, toBeSigned, tbsSz, ca->publicKey,
+                         ca->pubKeySize, ca->keyOID, signature, sigSz,
+                         signatureOID, NULL) != 0) {
+        WOLFSSL_MSG("CRL Confirm signature failed");
+        return ASN_CRL_CONFIRM_E;
+    }
+
+    return 0;
+}
+
+
+static int ParseCRL_CertList(DecodedCRL* dcrl, const byte* buf,
+        word32* inOutIdx, int sz)
+{
+    word32 oid, dateIdx, idx, checkIdx;
+    int version, doNextDate = 1;
+    byte tag;
+
+    if (dcrl == NULL || inOutIdx == NULL || buf == NULL) {
+        return BAD_FUNC_ARG;
+    }
+
+    /* may have version */
+    idx = *inOutIdx;
+
+    checkIdx = idx;
+    if (GetASNTag(buf, &checkIdx, &tag, sz) == 0 && tag == ASN_INTEGER) {
+        if (GetMyVersion(buf, &idx, &version, sz) < 0)
+            return ASN_PARSE_E;
+    }
+
+    if (GetAlgoId(buf, &idx, &oid, oidIgnoreType, sz) < 0)
+        return ASN_PARSE_E;
+
+    if (GetNameHash(buf, &idx, dcrl->issuerHash, sz) < 0)
+        return ASN_PARSE_E;
+
+    if (GetBasicDate(buf, &idx, dcrl->lastDate, &dcrl->lastDateFormat, sz) < 0)
+        return ASN_PARSE_E;
+
+    dateIdx = idx;
+
+    if (GetBasicDate(buf, &idx, dcrl->nextDate, &dcrl->nextDateFormat, sz) < 0)
+    {
+#ifndef WOLFSSL_NO_CRL_NEXT_DATE
+        (void)dateIdx;
+        return ASN_PARSE_E;
+#else
+        dcrl->nextDateFormat = ASN_OTHER_TYPE;  /* skip flag */
+        doNextDate = 0;
+        idx = dateIdx;
+#endif
+    }
+
+    if (doNextDate) {
+#ifndef NO_ASN_TIME
+        if (!XVALIDATE_DATE(dcrl->nextDate, dcrl->nextDateFormat, AFTER)) {
+            WOLFSSL_MSG("CRL after date is no longer valid");
+            return ASN_AFTER_DATE_E;
+        }
+#endif
+    }
+
+    checkIdx = idx;
+    if (idx != dcrl->sigIndex &&
+           GetASNTag(buf, &checkIdx, &tag, sz) == 0 && tag != CRL_EXTENSIONS) {
+
+        int len;
+
+        if (GetSequence(buf, &idx, &len, sz) < 0)
+            return ASN_PARSE_E;
+        len += idx;
+
+        while (idx < (word32)len) {
+            if (GetRevoked(buf, &idx, dcrl, len) < 0)
+                return ASN_PARSE_E;
+        }
+    }
+
+    *inOutIdx = idx;
+
+    return 0;
+}
+
+
+#ifndef NO_SKID
+static int ParseCRL_AuthKeyIdExt(const byte* input, int sz, DecodedCRL* dcrl)
+{
+    word32 idx = 0;
+    int length = 0, ret = 0;
+    byte tag;
+
+    WOLFSSL_ENTER("ParseCRL_AuthKeyIdExt");
+
+    if (GetSequence(input, &idx, &length, sz) < 0) {
+        WOLFSSL_MSG("\tfail: should be a SEQUENCE\n");
+        return ASN_PARSE_E;
+    }
+
+    if (GetASNTag(input, &idx, &tag, sz) < 0) {
+        return ASN_PARSE_E;
+    }
+
+    if (tag != (ASN_CONTEXT_SPECIFIC | 0)) {
+        WOLFSSL_MSG("\tinfo: OPTIONAL item 0, not available\n");
+        return 0;
+    }
+
+    if (GetLength(input, &idx, &length, sz) <= 0) {
+        WOLFSSL_MSG("\tfail: extension data length");
+        return ASN_PARSE_E;
+    }
+
+    dcrl->extAuthKeyIdSet = 1;
+    if (length == KEYID_SIZE) {
+        XMEMCPY(dcrl->extAuthKeyId, input + idx, length);
+    }
+    else {
+        ret = CalcHashId(input + idx, length, dcrl->extAuthKeyId);
+    }
+
+    return ret;
+}
+#endif
+
+
+static int ParseCRL_Extensions(DecodedCRL* dcrl, const byte* buf,
+        word32* inOutIdx, word32 sz)
+{
+    int length;
+    word32 idx;
+    word32 ext_bound; /* boundary index for the sequence of extensions */
+    word32 oid;
+    byte tag;
+
+    WOLFSSL_ENTER("ParseCRL_Extensions");
+    (void)dcrl;
+
+    if (inOutIdx == NULL)
+        return BAD_FUNC_ARG;
+
+    idx = *inOutIdx;
+
+    /* CRL Extensions are optional */
+    if ((idx + 1) > sz)
+        return 0;
+
+    /* CRL Extensions are optional */
+    if (GetASNTag(buf, &idx, &tag, sz) < 0)
+        return 0;
+
+    /* CRL Extensions are optional */
+    if (tag != (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 0))
+        return 0;
+
+    if (GetLength(buf, &idx, &length, sz) < 0)
+        return ASN_PARSE_E;
+
+    if (GetSequence(buf, &idx, &length, sz) < 0)
+        return ASN_PARSE_E;
+
+    ext_bound = idx + length;
+
+    while (idx < (word32)ext_bound) {
+        word32 localIdx;
+        int ret;
+
+        if (GetSequence(buf, &idx, &length, sz) < 0) {
+            WOLFSSL_MSG("\tfail: should be a SEQUENCE");
+            return ASN_PARSE_E;
+        }
+
+        oid = 0;
+        if (GetObjectId(buf, &idx, &oid, oidCrlExtType, sz) < 0) {
+            WOLFSSL_MSG("\tfail: OBJECT ID");
+            return ASN_PARSE_E;
+        }
+
+        /* check for critical flag */
+        if ((idx + 1) > (word32)sz) {
+            WOLFSSL_MSG("\tfail: malformed buffer");
+            return BUFFER_E;
+        }
+
+        localIdx = idx;
+        if (GetASNTag(buf, &localIdx, &tag, sz) == 0 && tag == ASN_BOOLEAN) {
+            WOLFSSL_MSG("\tfound optional critical flag, moving past");
+            ret = GetBoolean(buf, &idx, sz);
+            if (ret < 0)
+                return ret;
+        }
+
+        ret = GetOctetString(buf, &idx, &length, sz);
+        if (ret < 0)
+            return ret;
+
+        if (oid == AUTH_KEY_OID) {
+        #ifndef NO_SKID
+            ret = ParseCRL_AuthKeyIdExt(buf + idx, length, dcrl);
+            if (ret < 0) {
+                WOLFSSL_MSG("\tcouldn't parse AuthKeyId extension");
+                return ret;
+            }
+        #endif
+        }
+
+        idx += length;
+    }
+
+    *inOutIdx = idx;
+
+    return 0;
+}
+
+
+/* prase crl buffer into decoded state, 0 on success */
+int ParseCRL(DecodedCRL* dcrl, const byte* buff, word32 sz, void* cm)
+{
+    int          len;
+    word32       idx = 0;
+    Signer*      ca = NULL;
+    SignatureCtx sigCtx;
+
+    WOLFSSL_MSG("ParseCRL");
+
+    /* raw crl hash */
+    /* hash here if needed for optimized comparisons
+     * wc_Sha sha;
+     * wc_InitSha(&sha);
+     * wc_ShaUpdate(&sha, buff, sz);
+     * wc_ShaFinal(&sha, dcrl->crlHash); */
+
+    if (GetSequence(buff, &idx, &len, sz) < 0)
+        return ASN_PARSE_E;
+
+    dcrl->certBegin = idx;
+    /* Normalize sz for the length inside the outer sequence. */
+    sz = len + idx;
+
+    if (GetSequence(buff, &idx, &len, sz) < 0)
+        return ASN_PARSE_E;
+    dcrl->sigIndex = len + idx;
+
+    if (ParseCRL_CertList(dcrl, buff, &idx, idx + len) < 0)
+        return ASN_PARSE_E;
+
+    if (ParseCRL_Extensions(dcrl, buff, &idx, idx + len) < 0)
+        return ASN_PARSE_E;
+
+    idx = dcrl->sigIndex;
+
+    if (GetAlgoId(buff, &idx, &dcrl->signatureOID, oidSigType, sz) < 0)
+        return ASN_PARSE_E;
+
+    if (GetCRL_Signature(buff, &idx, dcrl, sz) < 0)
+        return ASN_PARSE_E;
+
+    /* openssl doesn't add skid by default for CRLs cause firefox chokes
+       if experiencing issues uncomment NO_SKID define in CRL section of
+       wolfssl/wolfcrypt/settings.h */
+#ifndef NO_SKID
+    if (dcrl->extAuthKeyIdSet) {
+        ca = GetCA(cm, dcrl->extAuthKeyId); /* more unique than issuerHash */
+    }
+    if (ca != NULL && XMEMCMP(dcrl->issuerHash, ca->subjectNameHash,
+                KEYID_SIZE) != 0) {
+        ca = NULL;
+    }
+    if (ca == NULL) {
+        ca = GetCAByName(cm, dcrl->issuerHash); /* last resort */
+        /* If AKID is available then this CA doesn't have the public
+         * key required */
+        if (ca && dcrl->extAuthKeyIdSet) {
+            WOLFSSL_MSG("CA SKID doesn't match AKID");
+            ca = NULL;
+        }
+    }
+#else
+    ca = GetCA(cm, dcrl->issuerHash);
+#endif /* !NO_SKID */
+    WOLFSSL_MSG("About to verify CRL signature");
+
+    if (ca == NULL) {
+        WOLFSSL_MSG("Did NOT find CRL issuer CA");
+        return ASN_CRL_NO_SIGNER_E;
+    }
+
+    WOLFSSL_MSG("Found CRL issuer CA");
+    return VerifyCRL_Signature(&sigCtx, buff + dcrl->certBegin,
+           dcrl->sigIndex - dcrl->certBegin, dcrl->signature, dcrl->sigLength,
+           dcrl->signatureOID, ca, dcrl->heap);
+}
+
+#endif /* HAVE_CRL */
+
+
+
+#ifdef WOLFSSL_CERT_PIV
+
+int wc_ParseCertPIV(wc_CertPIV* piv, const byte* buf, word32 totalSz)
+{
+    int length = 0;
+    word32 idx = 0;
+
+    WOLFSSL_ENTER("wc_ParseCertPIV");
+
+    if (piv == NULL || buf == NULL || totalSz == 0)
+        return BAD_FUNC_ARG;
+
+    XMEMSET(piv, 0, sizeof(wc_CertPIV));
+
+    /* Detect Identiv PIV (with 0x0A, 0x0B and 0x0C sections) */
+    /* Certificate (0A 82 05FA) */
+    if (GetASNHeader(buf, ASN_PIV_CERT, &idx, &length, totalSz) >= 0) {
+        /* Identiv Type PIV card */
+        piv->isIdentiv = 1;
+
+        piv->cert =   &buf[idx];
+        piv->certSz = length;
+        idx += length;
+
+        /* Nonce (0B 14) */
+        if (GetASNHeader(buf, ASN_PIV_NONCE, &idx, &length, totalSz) >= 0) {
+            piv->nonce =   &buf[idx];
+            piv->nonceSz = length;
+            idx += length;
+        }
+
+        /* Signed Nonce (0C 82 0100) */
+        if (GetASNHeader(buf, ASN_PIV_SIGNED_NONCE, &idx, &length, totalSz) >= 0) {
+            piv->signedNonce =   &buf[idx];
+            piv->signedNonceSz = length;
+        }
+
+        idx = 0;
+        buf = piv->cert;
+        totalSz = piv->certSz;
+    }
+
+    /* Certificate Buffer Total Size (53 82 05F6) */
+    if (GetASNHeader(buf, ASN_APPLICATION | ASN_PRINTABLE_STRING, &idx,
+                                                   &length, totalSz) < 0) {
+        return ASN_PARSE_E;
+    }
+    /* PIV Certificate (70 82 05ED) */
+    if (GetASNHeader(buf, ASN_PIV_TAG_CERT, &idx, &length,
+                                                         totalSz) < 0) {
+        return ASN_PARSE_E;
+    }
+
+    /* Capture certificate buffer pointer and length */
+    piv->cert =   &buf[idx];
+    piv->certSz = length;
+    idx += length;
+
+    /* PIV Certificate Info (71 01 00) */
+    if (GetASNHeader(buf, ASN_PIV_TAG_CERT_INFO, &idx, &length,
+                                                        totalSz) >= 0) {
+        if (length >= 1) {
+            piv->compression = (buf[idx] & ASN_PIV_CERT_INFO_COMPRESSED);
+            piv->isX509 =      (buf[idx] & ASN_PIV_CERT_INFO_ISX509);
+        }
+        idx += length;
+    }
+
+    /* PIV Error Detection (FE 00) */
+    if (GetASNHeader(buf, ASN_PIV_TAG_ERR_DET, &idx, &length,
+                                                        totalSz) >= 0) {
+        piv->certErrDet =   &buf[idx];
+        piv->certErrDetSz = length;
+        idx += length;
+    }
+
+    return 0;
+}
+
+#endif /* WOLFSSL_CERT_PIV */
+
+
+#undef ERROR_OUT
+
+#endif /* !NO_ASN */
+
+#ifdef WOLFSSL_SEP
+
+
+#endif /* WOLFSSL_SEP */
Index: azure_iot_hub_f767zi/trunk/wolfssl-4.4.0/wolfcrypt/src/blake2b.c
===================================================================
--- azure_iot_hub_f767zi/trunk/wolfssl-4.4.0/wolfcrypt/src/blake2b.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/wolfssl-4.4.0/wolfcrypt/src/blake2b.c	(revision 457)
@@ -0,0 +1,452 @@
+/*
+   BLAKE2 reference source code package - reference C implementations
+
+   Written in 2012 by Samuel Neves <sneves@dei.uc.pt>
+
+   To the extent possible under law, the author(s) have dedicated all copyright
+   and related and neighboring rights to this software to the public domain
+   worldwide. This software is distributed without any warranty.
+
+   You should have received a copy of the CC0 Public Domain Dedication along with
+   this software. If not, see <http://creativecommons.org/publicdomain/zero/1.0/>.
+*/
+/* blake2b.c
+ *
+ * Copyright (C) 2006-2020 wolfSSL Inc.
+ *
+ * This file is part of wolfSSL.
+ *
+ * wolfSSL is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * wolfSSL is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
+ */
+
+
+
+#ifdef HAVE_CONFIG_H
+    #include <config.h>
+#endif
+
+#include <wolfssl/wolfcrypt/settings.h>
+
+#ifdef HAVE_BLAKE2
+
+#include <wolfssl/wolfcrypt/blake2.h>
+#include <wolfssl/wolfcrypt/blake2-impl.h>
+
+
+static const word64 blake2b_IV[8] =
+{
+  0x6a09e667f3bcc908ULL, 0xbb67ae8584caa73bULL,
+  0x3c6ef372fe94f82bULL, 0xa54ff53a5f1d36f1ULL,
+  0x510e527fade682d1ULL, 0x9b05688c2b3e6c1fULL,
+  0x1f83d9abfb41bd6bULL, 0x5be0cd19137e2179ULL
+};
+
+static const byte blake2b_sigma[12][16] =
+{
+  {  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15 } ,
+  { 14, 10,  4,  8,  9, 15, 13,  6,  1, 12,  0,  2, 11,  7,  5,  3 } ,
+  { 11,  8, 12,  0,  5,  2, 15, 13, 10, 14,  3,  6,  7,  1,  9,  4 } ,
+  {  7,  9,  3,  1, 13, 12, 11, 14,  2,  6,  5, 10,  4,  0, 15,  8 } ,
+  {  9,  0,  5,  7,  2,  4, 10, 15, 14,  1, 11, 12,  6,  8,  3, 13 } ,
+  {  2, 12,  6, 10,  0, 11,  8,  3,  4, 13,  7,  5, 15, 14,  1,  9 } ,
+  { 12,  5,  1, 15, 14, 13,  4, 10,  0,  7,  6,  3,  9,  2,  8, 11 } ,
+  { 13, 11,  7, 14, 12,  1,  3,  9,  5,  0, 15,  4,  8,  6,  2, 10 } ,
+  {  6, 15, 14,  9, 11,  3,  0,  8, 12,  2, 13,  7,  1,  4, 10,  5 } ,
+  { 10,  2,  8,  4,  7,  6,  1,  5, 15, 11,  9, 14,  3, 12, 13 , 0 } ,
+  {  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15 } ,
+  { 14, 10,  4,  8,  9, 15, 13,  6,  1, 12,  0,  2, 11,  7,  5,  3 }
+};
+
+
+static WC_INLINE int blake2b_set_lastnode( blake2b_state *S )
+{
+  S->f[1] = ~0ULL;
+  return 0;
+}
+
+/* Some helper functions, not necessarily useful */
+static WC_INLINE int blake2b_set_lastblock( blake2b_state *S )
+{
+  if( S->last_node ) blake2b_set_lastnode( S );
+
+  S->f[0] = ~0ULL;
+  return 0;
+}
+
+static WC_INLINE int blake2b_increment_counter( blake2b_state *S, const word64
+                                             inc )
+{
+  S->t[0] += inc;
+  S->t[1] += ( S->t[0] < inc );
+  return 0;
+}
+
+static WC_INLINE int blake2b_init0( blake2b_state *S )
+{
+  int i;
+  XMEMSET( S, 0, sizeof( blake2b_state ) );
+
+  for( i = 0; i < 8; ++i ) S->h[i] = blake2b_IV[i];
+
+  return 0;
+}
+
+/* init xors IV with input parameter block */
+int blake2b_init_param( blake2b_state *S, const blake2b_param *P )
+{
+  word32 i;
+  byte *p ;
+  blake2b_init0( S );
+  p =  ( byte * )( P );
+
+  /* IV XOR ParamBlock */
+  for( i = 0; i < 8; ++i )
+    S->h[i] ^= load64( p + sizeof( S->h[i] ) * i );
+
+  return 0;
+}
+
+
+
+int blake2b_init( blake2b_state *S, const byte outlen )
+{
+  blake2b_param P[1];
+
+  if ( ( !outlen ) || ( outlen > BLAKE2B_OUTBYTES ) ) return -1;
+
+#ifdef WOLFSSL_BLAKE2B_INIT_EACH_FIELD
+  P->digest_length = outlen;
+  P->key_length    = 0;
+  P->fanout        = 1;
+  P->depth         = 1;
+  store32( &P->leaf_length, 0 );
+  store64( &P->node_offset, 0 );
+  P->node_depth    = 0;
+  P->inner_length  = 0;
+  XMEMSET( P->reserved, 0, sizeof( P->reserved ) );
+  XMEMSET( P->salt,     0, sizeof( P->salt ) );
+  XMEMSET( P->personal, 0, sizeof( P->personal ) );
+#else
+  XMEMSET( P, 0, sizeof( *P ) );
+  P->digest_length = outlen;
+  P->fanout        = 1;
+  P->depth         = 1;
+#endif
+  return blake2b_init_param( S, P );
+}
+
+
+int blake2b_init_key( blake2b_state *S, const byte outlen, const void *key,
+                      const byte keylen )
+{
+  blake2b_param P[1];
+
+  if ( ( !outlen ) || ( outlen > BLAKE2B_OUTBYTES ) ) return -1;
+
+  if ( !key || !keylen || keylen > BLAKE2B_KEYBYTES ) return -1;
+
+#ifdef WOLFSSL_BLAKE2B_INIT_EACH_FIELD
+  P->digest_length = outlen;
+  P->key_length    = keylen;
+  P->fanout        = 1;
+  P->depth         = 1;
+  store32( &P->leaf_length, 0 );
+  store64( &P->node_offset, 0 );
+  P->node_depth    = 0;
+  P->inner_length  = 0;
+  XMEMSET( P->reserved, 0, sizeof( P->reserved ) );
+  XMEMSET( P->salt,     0, sizeof( P->salt ) );
+  XMEMSET( P->personal, 0, sizeof( P->personal ) );
+#else
+  XMEMSET( P, 0, sizeof( *P ) );
+  P->digest_length = outlen;
+  P->key_length    = keylen;
+  P->fanout        = 1;
+  P->depth         = 1;
+#endif
+
+  if( blake2b_init_param( S, P ) < 0 ) return -1;
+
+  {
+#ifdef WOLFSSL_SMALL_STACK
+    byte* block;
+
+    block = (byte*)XMALLOC(BLAKE2B_BLOCKBYTES, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+
+    if ( block == NULL ) return -1;
+#else
+    byte block[BLAKE2B_BLOCKBYTES];
+#endif
+
+    XMEMSET( block, 0, BLAKE2B_BLOCKBYTES );
+    XMEMCPY( block, key, keylen );
+    blake2b_update( S, block, BLAKE2B_BLOCKBYTES );
+    secure_zero_memory( block, BLAKE2B_BLOCKBYTES ); /* Burn the key from */
+                                                     /* memory */
+
+#ifdef WOLFSSL_SMALL_STACK
+    XFREE(block, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+#endif
+  }
+  return 0;
+}
+
+static int blake2b_compress( blake2b_state *S,
+                             const byte block[BLAKE2B_BLOCKBYTES] )
+{
+  int i;
+
+#ifdef WOLFSSL_SMALL_STACK
+  word64* m;
+  word64* v;
+
+  m = (word64*)XMALLOC(sizeof(word64) * 16, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+
+  if ( m == NULL ) return -1;
+
+  v = (word64*)XMALLOC(sizeof(word64) * 16, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+
+  if ( v == NULL )
+  {
+    XFREE(m, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    return -1;
+  }
+#else
+  word64 m[16];
+  word64 v[16];
+#endif
+
+  for( i = 0; i < 16; ++i )
+    m[i] = load64( block + i * sizeof( m[i] ) );
+
+  for( i = 0; i < 8; ++i )
+    v[i] = S->h[i];
+
+  v[ 8] = blake2b_IV[0];
+  v[ 9] = blake2b_IV[1];
+  v[10] = blake2b_IV[2];
+  v[11] = blake2b_IV[3];
+  v[12] = S->t[0] ^ blake2b_IV[4];
+  v[13] = S->t[1] ^ blake2b_IV[5];
+  v[14] = S->f[0] ^ blake2b_IV[6];
+  v[15] = S->f[1] ^ blake2b_IV[7];
+#define G(r,i,a,b,c,d) \
+  do { \
+    a = a + b + m[blake2b_sigma[r][2*i+0]]; \
+    d = rotr64(d ^ a, 32); \
+    c = c + d; \
+    b = rotr64(b ^ c, 24); \
+    a = a + b + m[blake2b_sigma[r][2*i+1]]; \
+    d = rotr64(d ^ a, 16); \
+    c = c + d; \
+    b = rotr64(b ^ c, 63); \
+  } while(0)
+#define ROUND(r)  \
+  do { \
+    G(r,0,v[ 0],v[ 4],v[ 8],v[12]); \
+    G(r,1,v[ 1],v[ 5],v[ 9],v[13]); \
+    G(r,2,v[ 2],v[ 6],v[10],v[14]); \
+    G(r,3,v[ 3],v[ 7],v[11],v[15]); \
+    G(r,4,v[ 0],v[ 5],v[10],v[15]); \
+    G(r,5,v[ 1],v[ 6],v[11],v[12]); \
+    G(r,6,v[ 2],v[ 7],v[ 8],v[13]); \
+    G(r,7,v[ 3],v[ 4],v[ 9],v[14]); \
+  } while(0)
+  ROUND( 0 );
+  ROUND( 1 );
+  ROUND( 2 );
+  ROUND( 3 );
+  ROUND( 4 );
+  ROUND( 5 );
+  ROUND( 6 );
+  ROUND( 7 );
+  ROUND( 8 );
+  ROUND( 9 );
+  ROUND( 10 );
+  ROUND( 11 );
+
+  for( i = 0; i < 8; ++i )
+    S->h[i] = S->h[i] ^ v[i] ^ v[i + 8];
+
+#undef G
+#undef ROUND
+
+#ifdef WOLFSSL_SMALL_STACK
+  XFREE(m, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+  XFREE(v, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+#endif
+
+  return 0;
+}
+
+/* inlen now in bytes */
+int blake2b_update( blake2b_state *S, const byte *in, word64 inlen )
+{
+  while( inlen > 0 )
+  {
+    word64 left = S->buflen;
+    word64 fill = 2 * BLAKE2B_BLOCKBYTES - left;
+
+    if( inlen > fill )
+    {
+      XMEMCPY( S->buf + left, in, (wolfssl_word)fill ); /* Fill buffer */
+      S->buflen += fill;
+      blake2b_increment_counter( S, BLAKE2B_BLOCKBYTES );
+
+      if ( blake2b_compress( S, S->buf ) < 0 ) return -1; /* Compress */
+
+      XMEMCPY( S->buf, S->buf + BLAKE2B_BLOCKBYTES, BLAKE2B_BLOCKBYTES );
+              /* Shift buffer left */
+      S->buflen -= BLAKE2B_BLOCKBYTES;
+      in += fill;
+      inlen -= fill;
+    }
+    else /* inlen <= fill */
+    {
+      XMEMCPY( S->buf + left, in, (wolfssl_word)inlen );
+      S->buflen += inlen; /* Be lazy, do not compress */
+      inlen = 0;
+    }
+  }
+
+  return 0;
+}
+
+/* Is this correct? */
+int blake2b_final( blake2b_state *S, byte *out, byte outlen )
+{
+  byte buffer[BLAKE2B_OUTBYTES];
+  int     i;
+
+  if( S->buflen > BLAKE2B_BLOCKBYTES )
+  {
+    blake2b_increment_counter( S, BLAKE2B_BLOCKBYTES );
+
+    if ( blake2b_compress( S, S->buf ) < 0 ) return -1;
+
+    S->buflen -= BLAKE2B_BLOCKBYTES;
+    XMEMCPY( S->buf, S->buf + BLAKE2B_BLOCKBYTES, (wolfssl_word)S->buflen );
+  }
+
+  blake2b_increment_counter( S, S->buflen );
+  blake2b_set_lastblock( S );
+  XMEMSET( S->buf + S->buflen, 0, (wolfssl_word)(2 * BLAKE2B_BLOCKBYTES - S->buflen) );
+         /* Padding */
+  if ( blake2b_compress( S, S->buf ) < 0 ) return -1;
+
+  for( i = 0; i < 8; ++i ) /* Output full hash to temp buffer */
+    store64( buffer + sizeof( S->h[i] ) * i, S->h[i] );
+
+  XMEMCPY( out, buffer, outlen );
+  return 0;
+}
+
+/* inlen, at least, should be word64. Others can be size_t. */
+int blake2b( byte *out, const void *in, const void *key, const byte outlen,
+             const word64 inlen, byte keylen )
+{
+  blake2b_state S[1];
+
+  /* Verify parameters */
+  if ( NULL == in ) return -1;
+
+  if ( NULL == out ) return -1;
+
+  if( NULL == key ) keylen = 0;
+
+  if( keylen > 0 )
+  {
+    if( blake2b_init_key( S, outlen, key, keylen ) < 0 ) return -1;
+  }
+  else
+  {
+    if( blake2b_init( S, outlen ) < 0 ) return -1;
+  }
+
+  if ( blake2b_update( S, ( byte * )in, inlen ) < 0) return -1;
+
+  return blake2b_final( S, out, outlen );
+}
+
+#if defined(BLAKE2B_SELFTEST)
+#include <string.h>
+#include "blake2-kat.h"
+int main( int argc, char **argv )
+{
+  byte key[BLAKE2B_KEYBYTES];
+  byte buf[KAT_LENGTH];
+
+  for( word32 i = 0; i < BLAKE2B_KEYBYTES; ++i )
+    key[i] = ( byte )i;
+
+  for( word32 i = 0; i < KAT_LENGTH; ++i )
+    buf[i] = ( byte )i;
+
+  for( word32 i = 0; i < KAT_LENGTH; ++i )
+  {
+    byte hash[BLAKE2B_OUTBYTES];
+    if ( blake2b( hash, buf, key, BLAKE2B_OUTBYTES, i, BLAKE2B_KEYBYTES ) < 0 )
+    {
+      puts( "error" );
+      return -1;
+    }
+
+    if( 0 != XMEMCMP( hash, blake2b_keyed_kat[i], BLAKE2B_OUTBYTES ) )
+    {
+      puts( "error" );
+      return -1;
+    }
+  }
+
+  puts( "ok" );
+  return 0;
+}
+#endif
+
+
+/* wolfCrypt API */
+
+/* Init Blake2b digest, track size in case final doesn't want to "remember" */
+int wc_InitBlake2b(Blake2b* b2b, word32 digestSz)
+{
+    if (b2b == NULL){
+        return -1;
+    }
+    b2b->digestSz = digestSz;
+
+    return blake2b_init(b2b->S, (byte)digestSz);
+}
+
+
+/* Blake2b Update */
+int wc_Blake2bUpdate(Blake2b* b2b, const byte* data, word32 sz)
+{
+    return blake2b_update(b2b->S, data, sz);
+}
+
+
+/* Blake2b Final, if pass in zero size we use init digestSz */
+int wc_Blake2bFinal(Blake2b* b2b, byte* final, word32 requestSz)
+{
+    word32 sz = requestSz ? requestSz : b2b->digestSz;
+
+    return blake2b_final(b2b->S, final, (byte)sz);
+}
+
+
+/* end CTaoCrypt API */
+
+#endif  /* HAVE_BLAKE2 */
+
Index: azure_iot_hub_f767zi/trunk/wolfssl-4.4.0/wolfcrypt/src/camellia.c
===================================================================
--- azure_iot_hub_f767zi/trunk/wolfssl-4.4.0/wolfcrypt/src/camellia.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/wolfssl-4.4.0/wolfcrypt/src/camellia.c	(revision 457)
@@ -0,0 +1,1644 @@
+/* camellia.c ver 1.2.0
+ *
+ * Copyright (c) 2006,2007
+ * NTT (Nippon Telegraph and Telephone Corporation) . 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 as
+ *   the first lines of this file unmodified.
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NTT ``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 NTT 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.
+ */
+
+/* camellia.c
+ *
+ * Copyright (C) 2006-2020 wolfSSL Inc.
+ *
+ * This file is part of wolfSSL.
+ *
+ * wolfSSL is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * wolfSSL is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
+ */
+
+
+/*
+ * Algorithm Specification
+ *  http://info.isl.ntt.co.jp/crypt/eng/camellia/specifications.html
+ */
+
+
+#ifdef HAVE_CONFIG_H
+    #include <config.h>
+#endif
+
+#include <wolfssl/wolfcrypt/settings.h>
+
+#ifdef HAVE_CAMELLIA
+
+#include <wolfssl/wolfcrypt/camellia.h>
+#include <wolfssl/wolfcrypt/error-crypt.h>
+#include <wolfssl/wolfcrypt/logging.h>
+#ifdef NO_INLINE
+    #include <wolfssl/wolfcrypt/misc.h>
+#else
+    #define WOLFSSL_MISC_INCLUDED
+    #include <wolfcrypt/src/misc.c>
+#endif
+
+/* u32 must be 32bit word */
+typedef unsigned int u32;
+typedef unsigned char u8;
+
+/* key constants */
+
+#define CAMELLIA_SIGMA1L ((u32)0xA09E667FL)
+#define CAMELLIA_SIGMA1R ((u32)0x3BCC908BL)
+#define CAMELLIA_SIGMA2L ((u32)0xB67AE858L)
+#define CAMELLIA_SIGMA2R ((u32)0x4CAA73B2L)
+#define CAMELLIA_SIGMA3L ((u32)0xC6EF372FL)
+#define CAMELLIA_SIGMA3R ((u32)0xE94F82BEL)
+#define CAMELLIA_SIGMA4L ((u32)0x54FF53A5L)
+#define CAMELLIA_SIGMA4R ((u32)0xF1D36F1CL)
+#define CAMELLIA_SIGMA5L ((u32)0x10E527FAL)
+#define CAMELLIA_SIGMA5R ((u32)0xDE682D1DL)
+#define CAMELLIA_SIGMA6L ((u32)0xB05688C2L)
+#define CAMELLIA_SIGMA6R ((u32)0xB3E6C1FDL)
+
+/*
+ *  macros
+ */
+
+
+#if defined(_MSC_VER)
+
+# define SWAP(x) (_lrotl(x, 8) & 0x00ff00ff | _lrotr(x, 8) & 0xff00ff00)
+# define GETU32(p) SWAP(*((u32 *)(p)))
+# define PUTU32(ct, st) {*((u32 *)(ct)) = SWAP((st));}
+
+#else /* not MS-VC */
+
+# define GETU32(pt)				\
+    (((u32)(pt)[0] << 24)			\
+     ^ ((u32)(pt)[1] << 16)			\
+     ^ ((u32)(pt)[2] <<  8)			\
+     ^ ((u32)(pt)[3]))
+
+# define PUTU32(ct, st)  {			\
+	(ct)[0] = (u8)((st) >> 24);		\
+	(ct)[1] = (u8)((st) >> 16);		\
+	(ct)[2] = (u8)((st) >>  8);		\
+	(ct)[3] = (u8)(st); }
+
+#endif
+
+#define CamelliaSubkeyL(INDEX) (subkey[(INDEX)*2])
+#define CamelliaSubkeyR(INDEX) (subkey[(INDEX)*2 + 1])
+
+/* rotation right shift 1byte */
+#define CAMELLIA_RR8(x) (((x) >> 8) + ((x) << 24))
+/* rotation left shift 1bit */
+#define CAMELLIA_RL1(x) (((x) << 1) + ((x) >> 31))
+/* rotation left shift 1byte */
+#define CAMELLIA_RL8(x) (((x) << 8) + ((x) >> 24))
+
+#define CAMELLIA_ROLDQ(ll, lr, rl, rr, w0, w1, bits)	\
+    do {						\
+	w0 = ll;					\
+	ll = (ll << bits) + (lr >> (32 - bits));	\
+	lr = (lr << bits) + (rl >> (32 - bits));	\
+	rl = (rl << bits) + (rr >> (32 - bits));	\
+	rr = (rr << bits) + (w0 >> (32 - bits));	\
+    } while(0)
+
+#define CAMELLIA_ROLDQo32(ll, lr, rl, rr, w0, w1, bits)	\
+    do {						\
+	w0 = ll;					\
+	w1 = lr;					\
+	ll = (lr << (bits - 32)) + (rl >> (64 - bits));	\
+	lr = (rl << (bits - 32)) + (rr >> (64 - bits));	\
+	rl = (rr << (bits - 32)) + (w0 >> (64 - bits));	\
+	rr = (w0 << (bits - 32)) + (w1 >> (64 - bits));	\
+    } while(0)
+
+#define CAMELLIA_SP1110(INDEX) (camellia_sp1110[(INDEX)])
+#define CAMELLIA_SP0222(INDEX) (camellia_sp0222[(INDEX)])
+#define CAMELLIA_SP3033(INDEX) (camellia_sp3033[(INDEX)])
+#define CAMELLIA_SP4404(INDEX) (camellia_sp4404[(INDEX)])
+
+#define CAMELLIA_F(xl, xr, kl, kr, yl, yr, il, ir, t0, t1)	\
+    do {							\
+	il = xl ^ kl;						\
+	ir = xr ^ kr;						\
+	t0 = il >> 16;						\
+	t1 = ir >> 16;						\
+	yl = CAMELLIA_SP1110(ir & 0xff)				\
+	    ^ CAMELLIA_SP0222((t1 >> 8) & 0xff)			\
+	    ^ CAMELLIA_SP3033(t1 & 0xff)			\
+	    ^ CAMELLIA_SP4404((ir >> 8) & 0xff);		\
+	yr = CAMELLIA_SP1110((t0 >> 8) & 0xff)			\
+	    ^ CAMELLIA_SP0222(t0 & 0xff)			\
+	    ^ CAMELLIA_SP3033((il >> 8) & 0xff)			\
+	    ^ CAMELLIA_SP4404(il & 0xff);			\
+	yl ^= yr;						\
+	yr = CAMELLIA_RR8(yr);					\
+	yr ^= yl;						\
+    } while(0)
+
+
+/*
+ * for speed up
+ *
+ */
+#define CAMELLIA_FLS(ll, lr, rl, rr, kll, klr, krl, krr, t0, t1, t2, t3) \
+    do {								\
+	t0 = kll;							\
+	t0 &= ll;							\
+	lr ^= CAMELLIA_RL1(t0);						\
+	t1 = klr;							\
+	t1 |= lr;							\
+	ll ^= t1;							\
+									\
+	t2 = krr;							\
+	t2 |= rr;							\
+	rl ^= t2;							\
+	t3 = krl;							\
+	t3 &= rl;							\
+	rr ^= CAMELLIA_RL1(t3);						\
+    } while(0)
+
+#define CAMELLIA_ROUNDSM(xl, xr, kl, kr, yl, yr, il, ir, t0, t1)	\
+    do {								\
+	ir = CAMELLIA_SP1110(xr & 0xff)					\
+	    ^ CAMELLIA_SP0222((xr >> 24) & 0xff)			\
+	    ^ CAMELLIA_SP3033((xr >> 16) & 0xff)			\
+	    ^ CAMELLIA_SP4404((xr >> 8) & 0xff);			\
+	il = CAMELLIA_SP1110((xl >> 24) & 0xff)				\
+	    ^ CAMELLIA_SP0222((xl >> 16) & 0xff)			\
+	    ^ CAMELLIA_SP3033((xl >> 8) & 0xff)				\
+	    ^ CAMELLIA_SP4404(xl & 0xff);				\
+	il ^= kl;							\
+	ir ^= kr;							\
+	ir ^= il;							\
+	il = CAMELLIA_RR8(il);						\
+	il ^= ir;							\
+	yl ^= ir;							\
+	yr ^= il;							\
+    } while(0)
+
+
+static const u32 camellia_sp1110[256] = {
+    0x70707000,0x82828200,0x2c2c2c00,0xececec00,
+    0xb3b3b300,0x27272700,0xc0c0c000,0xe5e5e500,
+    0xe4e4e400,0x85858500,0x57575700,0x35353500,
+    0xeaeaea00,0x0c0c0c00,0xaeaeae00,0x41414100,
+    0x23232300,0xefefef00,0x6b6b6b00,0x93939300,
+    0x45454500,0x19191900,0xa5a5a500,0x21212100,
+    0xededed00,0x0e0e0e00,0x4f4f4f00,0x4e4e4e00,
+    0x1d1d1d00,0x65656500,0x92929200,0xbdbdbd00,
+    0x86868600,0xb8b8b800,0xafafaf00,0x8f8f8f00,
+    0x7c7c7c00,0xebebeb00,0x1f1f1f00,0xcecece00,
+    0x3e3e3e00,0x30303000,0xdcdcdc00,0x5f5f5f00,
+    0x5e5e5e00,0xc5c5c500,0x0b0b0b00,0x1a1a1a00,
+    0xa6a6a600,0xe1e1e100,0x39393900,0xcacaca00,
+    0xd5d5d500,0x47474700,0x5d5d5d00,0x3d3d3d00,
+    0xd9d9d900,0x01010100,0x5a5a5a00,0xd6d6d600,
+    0x51515100,0x56565600,0x6c6c6c00,0x4d4d4d00,
+    0x8b8b8b00,0x0d0d0d00,0x9a9a9a00,0x66666600,
+    0xfbfbfb00,0xcccccc00,0xb0b0b000,0x2d2d2d00,
+    0x74747400,0x12121200,0x2b2b2b00,0x20202000,
+    0xf0f0f000,0xb1b1b100,0x84848400,0x99999900,
+    0xdfdfdf00,0x4c4c4c00,0xcbcbcb00,0xc2c2c200,
+    0x34343400,0x7e7e7e00,0x76767600,0x05050500,
+    0x6d6d6d00,0xb7b7b700,0xa9a9a900,0x31313100,
+    0xd1d1d100,0x17171700,0x04040400,0xd7d7d700,
+    0x14141400,0x58585800,0x3a3a3a00,0x61616100,
+    0xdedede00,0x1b1b1b00,0x11111100,0x1c1c1c00,
+    0x32323200,0x0f0f0f00,0x9c9c9c00,0x16161600,
+    0x53535300,0x18181800,0xf2f2f200,0x22222200,
+    0xfefefe00,0x44444400,0xcfcfcf00,0xb2b2b200,
+    0xc3c3c300,0xb5b5b500,0x7a7a7a00,0x91919100,
+    0x24242400,0x08080800,0xe8e8e800,0xa8a8a800,
+    0x60606000,0xfcfcfc00,0x69696900,0x50505000,
+    0xaaaaaa00,0xd0d0d000,0xa0a0a000,0x7d7d7d00,
+    0xa1a1a100,0x89898900,0x62626200,0x97979700,
+    0x54545400,0x5b5b5b00,0x1e1e1e00,0x95959500,
+    0xe0e0e000,0xffffff00,0x64646400,0xd2d2d200,
+    0x10101000,0xc4c4c400,0x00000000,0x48484800,
+    0xa3a3a300,0xf7f7f700,0x75757500,0xdbdbdb00,
+    0x8a8a8a00,0x03030300,0xe6e6e600,0xdadada00,
+    0x09090900,0x3f3f3f00,0xdddddd00,0x94949400,
+    0x87878700,0x5c5c5c00,0x83838300,0x02020200,
+    0xcdcdcd00,0x4a4a4a00,0x90909000,0x33333300,
+    0x73737300,0x67676700,0xf6f6f600,0xf3f3f300,
+    0x9d9d9d00,0x7f7f7f00,0xbfbfbf00,0xe2e2e200,
+    0x52525200,0x9b9b9b00,0xd8d8d800,0x26262600,
+    0xc8c8c800,0x37373700,0xc6c6c600,0x3b3b3b00,
+    0x81818100,0x96969600,0x6f6f6f00,0x4b4b4b00,
+    0x13131300,0xbebebe00,0x63636300,0x2e2e2e00,
+    0xe9e9e900,0x79797900,0xa7a7a700,0x8c8c8c00,
+    0x9f9f9f00,0x6e6e6e00,0xbcbcbc00,0x8e8e8e00,
+    0x29292900,0xf5f5f500,0xf9f9f900,0xb6b6b600,
+    0x2f2f2f00,0xfdfdfd00,0xb4b4b400,0x59595900,
+    0x78787800,0x98989800,0x06060600,0x6a6a6a00,
+    0xe7e7e700,0x46464600,0x71717100,0xbababa00,
+    0xd4d4d400,0x25252500,0xababab00,0x42424200,
+    0x88888800,0xa2a2a200,0x8d8d8d00,0xfafafa00,
+    0x72727200,0x07070700,0xb9b9b900,0x55555500,
+    0xf8f8f800,0xeeeeee00,0xacacac00,0x0a0a0a00,
+    0x36363600,0x49494900,0x2a2a2a00,0x68686800,
+    0x3c3c3c00,0x38383800,0xf1f1f100,0xa4a4a400,
+    0x40404000,0x28282800,0xd3d3d300,0x7b7b7b00,
+    0xbbbbbb00,0xc9c9c900,0x43434300,0xc1c1c100,
+    0x15151500,0xe3e3e300,0xadadad00,0xf4f4f400,
+    0x77777700,0xc7c7c700,0x80808000,0x9e9e9e00,
+};
+
+static const u32 camellia_sp0222[256] = {
+    0x00e0e0e0,0x00050505,0x00585858,0x00d9d9d9,
+    0x00676767,0x004e4e4e,0x00818181,0x00cbcbcb,
+    0x00c9c9c9,0x000b0b0b,0x00aeaeae,0x006a6a6a,
+    0x00d5d5d5,0x00181818,0x005d5d5d,0x00828282,
+    0x00464646,0x00dfdfdf,0x00d6d6d6,0x00272727,
+    0x008a8a8a,0x00323232,0x004b4b4b,0x00424242,
+    0x00dbdbdb,0x001c1c1c,0x009e9e9e,0x009c9c9c,
+    0x003a3a3a,0x00cacaca,0x00252525,0x007b7b7b,
+    0x000d0d0d,0x00717171,0x005f5f5f,0x001f1f1f,
+    0x00f8f8f8,0x00d7d7d7,0x003e3e3e,0x009d9d9d,
+    0x007c7c7c,0x00606060,0x00b9b9b9,0x00bebebe,
+    0x00bcbcbc,0x008b8b8b,0x00161616,0x00343434,
+    0x004d4d4d,0x00c3c3c3,0x00727272,0x00959595,
+    0x00ababab,0x008e8e8e,0x00bababa,0x007a7a7a,
+    0x00b3b3b3,0x00020202,0x00b4b4b4,0x00adadad,
+    0x00a2a2a2,0x00acacac,0x00d8d8d8,0x009a9a9a,
+    0x00171717,0x001a1a1a,0x00353535,0x00cccccc,
+    0x00f7f7f7,0x00999999,0x00616161,0x005a5a5a,
+    0x00e8e8e8,0x00242424,0x00565656,0x00404040,
+    0x00e1e1e1,0x00636363,0x00090909,0x00333333,
+    0x00bfbfbf,0x00989898,0x00979797,0x00858585,
+    0x00686868,0x00fcfcfc,0x00ececec,0x000a0a0a,
+    0x00dadada,0x006f6f6f,0x00535353,0x00626262,
+    0x00a3a3a3,0x002e2e2e,0x00080808,0x00afafaf,
+    0x00282828,0x00b0b0b0,0x00747474,0x00c2c2c2,
+    0x00bdbdbd,0x00363636,0x00222222,0x00383838,
+    0x00646464,0x001e1e1e,0x00393939,0x002c2c2c,
+    0x00a6a6a6,0x00303030,0x00e5e5e5,0x00444444,
+    0x00fdfdfd,0x00888888,0x009f9f9f,0x00656565,
+    0x00878787,0x006b6b6b,0x00f4f4f4,0x00232323,
+    0x00484848,0x00101010,0x00d1d1d1,0x00515151,
+    0x00c0c0c0,0x00f9f9f9,0x00d2d2d2,0x00a0a0a0,
+    0x00555555,0x00a1a1a1,0x00414141,0x00fafafa,
+    0x00434343,0x00131313,0x00c4c4c4,0x002f2f2f,
+    0x00a8a8a8,0x00b6b6b6,0x003c3c3c,0x002b2b2b,
+    0x00c1c1c1,0x00ffffff,0x00c8c8c8,0x00a5a5a5,
+    0x00202020,0x00898989,0x00000000,0x00909090,
+    0x00474747,0x00efefef,0x00eaeaea,0x00b7b7b7,
+    0x00151515,0x00060606,0x00cdcdcd,0x00b5b5b5,
+    0x00121212,0x007e7e7e,0x00bbbbbb,0x00292929,
+    0x000f0f0f,0x00b8b8b8,0x00070707,0x00040404,
+    0x009b9b9b,0x00949494,0x00212121,0x00666666,
+    0x00e6e6e6,0x00cecece,0x00ededed,0x00e7e7e7,
+    0x003b3b3b,0x00fefefe,0x007f7f7f,0x00c5c5c5,
+    0x00a4a4a4,0x00373737,0x00b1b1b1,0x004c4c4c,
+    0x00919191,0x006e6e6e,0x008d8d8d,0x00767676,
+    0x00030303,0x002d2d2d,0x00dedede,0x00969696,
+    0x00262626,0x007d7d7d,0x00c6c6c6,0x005c5c5c,
+    0x00d3d3d3,0x00f2f2f2,0x004f4f4f,0x00191919,
+    0x003f3f3f,0x00dcdcdc,0x00797979,0x001d1d1d,
+    0x00525252,0x00ebebeb,0x00f3f3f3,0x006d6d6d,
+    0x005e5e5e,0x00fbfbfb,0x00696969,0x00b2b2b2,
+    0x00f0f0f0,0x00313131,0x000c0c0c,0x00d4d4d4,
+    0x00cfcfcf,0x008c8c8c,0x00e2e2e2,0x00757575,
+    0x00a9a9a9,0x004a4a4a,0x00575757,0x00848484,
+    0x00111111,0x00454545,0x001b1b1b,0x00f5f5f5,
+    0x00e4e4e4,0x000e0e0e,0x00737373,0x00aaaaaa,
+    0x00f1f1f1,0x00dddddd,0x00595959,0x00141414,
+    0x006c6c6c,0x00929292,0x00545454,0x00d0d0d0,
+    0x00787878,0x00707070,0x00e3e3e3,0x00494949,
+    0x00808080,0x00505050,0x00a7a7a7,0x00f6f6f6,
+    0x00777777,0x00939393,0x00868686,0x00838383,
+    0x002a2a2a,0x00c7c7c7,0x005b5b5b,0x00e9e9e9,
+    0x00eeeeee,0x008f8f8f,0x00010101,0x003d3d3d,
+};
+
+static const u32 camellia_sp3033[256] = {
+    0x38003838,0x41004141,0x16001616,0x76007676,
+    0xd900d9d9,0x93009393,0x60006060,0xf200f2f2,
+    0x72007272,0xc200c2c2,0xab00abab,0x9a009a9a,
+    0x75007575,0x06000606,0x57005757,0xa000a0a0,
+    0x91009191,0xf700f7f7,0xb500b5b5,0xc900c9c9,
+    0xa200a2a2,0x8c008c8c,0xd200d2d2,0x90009090,
+    0xf600f6f6,0x07000707,0xa700a7a7,0x27002727,
+    0x8e008e8e,0xb200b2b2,0x49004949,0xde00dede,
+    0x43004343,0x5c005c5c,0xd700d7d7,0xc700c7c7,
+    0x3e003e3e,0xf500f5f5,0x8f008f8f,0x67006767,
+    0x1f001f1f,0x18001818,0x6e006e6e,0xaf00afaf,
+    0x2f002f2f,0xe200e2e2,0x85008585,0x0d000d0d,
+    0x53005353,0xf000f0f0,0x9c009c9c,0x65006565,
+    0xea00eaea,0xa300a3a3,0xae00aeae,0x9e009e9e,
+    0xec00ecec,0x80008080,0x2d002d2d,0x6b006b6b,
+    0xa800a8a8,0x2b002b2b,0x36003636,0xa600a6a6,
+    0xc500c5c5,0x86008686,0x4d004d4d,0x33003333,
+    0xfd00fdfd,0x66006666,0x58005858,0x96009696,
+    0x3a003a3a,0x09000909,0x95009595,0x10001010,
+    0x78007878,0xd800d8d8,0x42004242,0xcc00cccc,
+    0xef00efef,0x26002626,0xe500e5e5,0x61006161,
+    0x1a001a1a,0x3f003f3f,0x3b003b3b,0x82008282,
+    0xb600b6b6,0xdb00dbdb,0xd400d4d4,0x98009898,
+    0xe800e8e8,0x8b008b8b,0x02000202,0xeb00ebeb,
+    0x0a000a0a,0x2c002c2c,0x1d001d1d,0xb000b0b0,
+    0x6f006f6f,0x8d008d8d,0x88008888,0x0e000e0e,
+    0x19001919,0x87008787,0x4e004e4e,0x0b000b0b,
+    0xa900a9a9,0x0c000c0c,0x79007979,0x11001111,
+    0x7f007f7f,0x22002222,0xe700e7e7,0x59005959,
+    0xe100e1e1,0xda00dada,0x3d003d3d,0xc800c8c8,
+    0x12001212,0x04000404,0x74007474,0x54005454,
+    0x30003030,0x7e007e7e,0xb400b4b4,0x28002828,
+    0x55005555,0x68006868,0x50005050,0xbe00bebe,
+    0xd000d0d0,0xc400c4c4,0x31003131,0xcb00cbcb,
+    0x2a002a2a,0xad00adad,0x0f000f0f,0xca00caca,
+    0x70007070,0xff00ffff,0x32003232,0x69006969,
+    0x08000808,0x62006262,0x00000000,0x24002424,
+    0xd100d1d1,0xfb00fbfb,0xba00baba,0xed00eded,
+    0x45004545,0x81008181,0x73007373,0x6d006d6d,
+    0x84008484,0x9f009f9f,0xee00eeee,0x4a004a4a,
+    0xc300c3c3,0x2e002e2e,0xc100c1c1,0x01000101,
+    0xe600e6e6,0x25002525,0x48004848,0x99009999,
+    0xb900b9b9,0xb300b3b3,0x7b007b7b,0xf900f9f9,
+    0xce00cece,0xbf00bfbf,0xdf00dfdf,0x71007171,
+    0x29002929,0xcd00cdcd,0x6c006c6c,0x13001313,
+    0x64006464,0x9b009b9b,0x63006363,0x9d009d9d,
+    0xc000c0c0,0x4b004b4b,0xb700b7b7,0xa500a5a5,
+    0x89008989,0x5f005f5f,0xb100b1b1,0x17001717,
+    0xf400f4f4,0xbc00bcbc,0xd300d3d3,0x46004646,
+    0xcf00cfcf,0x37003737,0x5e005e5e,0x47004747,
+    0x94009494,0xfa00fafa,0xfc00fcfc,0x5b005b5b,
+    0x97009797,0xfe00fefe,0x5a005a5a,0xac00acac,
+    0x3c003c3c,0x4c004c4c,0x03000303,0x35003535,
+    0xf300f3f3,0x23002323,0xb800b8b8,0x5d005d5d,
+    0x6a006a6a,0x92009292,0xd500d5d5,0x21002121,
+    0x44004444,0x51005151,0xc600c6c6,0x7d007d7d,
+    0x39003939,0x83008383,0xdc00dcdc,0xaa00aaaa,
+    0x7c007c7c,0x77007777,0x56005656,0x05000505,
+    0x1b001b1b,0xa400a4a4,0x15001515,0x34003434,
+    0x1e001e1e,0x1c001c1c,0xf800f8f8,0x52005252,
+    0x20002020,0x14001414,0xe900e9e9,0xbd00bdbd,
+    0xdd00dddd,0xe400e4e4,0xa100a1a1,0xe000e0e0,
+    0x8a008a8a,0xf100f1f1,0xd600d6d6,0x7a007a7a,
+    0xbb00bbbb,0xe300e3e3,0x40004040,0x4f004f4f,
+};
+
+static const u32 camellia_sp4404[256] = {
+    0x70700070,0x2c2c002c,0xb3b300b3,0xc0c000c0,
+    0xe4e400e4,0x57570057,0xeaea00ea,0xaeae00ae,
+    0x23230023,0x6b6b006b,0x45450045,0xa5a500a5,
+    0xeded00ed,0x4f4f004f,0x1d1d001d,0x92920092,
+    0x86860086,0xafaf00af,0x7c7c007c,0x1f1f001f,
+    0x3e3e003e,0xdcdc00dc,0x5e5e005e,0x0b0b000b,
+    0xa6a600a6,0x39390039,0xd5d500d5,0x5d5d005d,
+    0xd9d900d9,0x5a5a005a,0x51510051,0x6c6c006c,
+    0x8b8b008b,0x9a9a009a,0xfbfb00fb,0xb0b000b0,
+    0x74740074,0x2b2b002b,0xf0f000f0,0x84840084,
+    0xdfdf00df,0xcbcb00cb,0x34340034,0x76760076,
+    0x6d6d006d,0xa9a900a9,0xd1d100d1,0x04040004,
+    0x14140014,0x3a3a003a,0xdede00de,0x11110011,
+    0x32320032,0x9c9c009c,0x53530053,0xf2f200f2,
+    0xfefe00fe,0xcfcf00cf,0xc3c300c3,0x7a7a007a,
+    0x24240024,0xe8e800e8,0x60600060,0x69690069,
+    0xaaaa00aa,0xa0a000a0,0xa1a100a1,0x62620062,
+    0x54540054,0x1e1e001e,0xe0e000e0,0x64640064,
+    0x10100010,0x00000000,0xa3a300a3,0x75750075,
+    0x8a8a008a,0xe6e600e6,0x09090009,0xdddd00dd,
+    0x87870087,0x83830083,0xcdcd00cd,0x90900090,
+    0x73730073,0xf6f600f6,0x9d9d009d,0xbfbf00bf,
+    0x52520052,0xd8d800d8,0xc8c800c8,0xc6c600c6,
+    0x81810081,0x6f6f006f,0x13130013,0x63630063,
+    0xe9e900e9,0xa7a700a7,0x9f9f009f,0xbcbc00bc,
+    0x29290029,0xf9f900f9,0x2f2f002f,0xb4b400b4,
+    0x78780078,0x06060006,0xe7e700e7,0x71710071,
+    0xd4d400d4,0xabab00ab,0x88880088,0x8d8d008d,
+    0x72720072,0xb9b900b9,0xf8f800f8,0xacac00ac,
+    0x36360036,0x2a2a002a,0x3c3c003c,0xf1f100f1,
+    0x40400040,0xd3d300d3,0xbbbb00bb,0x43430043,
+    0x15150015,0xadad00ad,0x77770077,0x80800080,
+    0x82820082,0xecec00ec,0x27270027,0xe5e500e5,
+    0x85850085,0x35350035,0x0c0c000c,0x41410041,
+    0xefef00ef,0x93930093,0x19190019,0x21210021,
+    0x0e0e000e,0x4e4e004e,0x65650065,0xbdbd00bd,
+    0xb8b800b8,0x8f8f008f,0xebeb00eb,0xcece00ce,
+    0x30300030,0x5f5f005f,0xc5c500c5,0x1a1a001a,
+    0xe1e100e1,0xcaca00ca,0x47470047,0x3d3d003d,
+    0x01010001,0xd6d600d6,0x56560056,0x4d4d004d,
+    0x0d0d000d,0x66660066,0xcccc00cc,0x2d2d002d,
+    0x12120012,0x20200020,0xb1b100b1,0x99990099,
+    0x4c4c004c,0xc2c200c2,0x7e7e007e,0x05050005,
+    0xb7b700b7,0x31310031,0x17170017,0xd7d700d7,
+    0x58580058,0x61610061,0x1b1b001b,0x1c1c001c,
+    0x0f0f000f,0x16160016,0x18180018,0x22220022,
+    0x44440044,0xb2b200b2,0xb5b500b5,0x91910091,
+    0x08080008,0xa8a800a8,0xfcfc00fc,0x50500050,
+    0xd0d000d0,0x7d7d007d,0x89890089,0x97970097,
+    0x5b5b005b,0x95950095,0xffff00ff,0xd2d200d2,
+    0xc4c400c4,0x48480048,0xf7f700f7,0xdbdb00db,
+    0x03030003,0xdada00da,0x3f3f003f,0x94940094,
+    0x5c5c005c,0x02020002,0x4a4a004a,0x33330033,
+    0x67670067,0xf3f300f3,0x7f7f007f,0xe2e200e2,
+    0x9b9b009b,0x26260026,0x37370037,0x3b3b003b,
+    0x96960096,0x4b4b004b,0xbebe00be,0x2e2e002e,
+    0x79790079,0x8c8c008c,0x6e6e006e,0x8e8e008e,
+    0xf5f500f5,0xb6b600b6,0xfdfd00fd,0x59590059,
+    0x98980098,0x6a6a006a,0x46460046,0xbaba00ba,
+    0x25250025,0x42420042,0xa2a200a2,0xfafa00fa,
+    0x07070007,0x55550055,0xeeee00ee,0x0a0a000a,
+    0x49490049,0x68680068,0x38380038,0xa4a400a4,
+    0x28280028,0x7b7b007b,0xc9c900c9,0xc1c100c1,
+    0xe3e300e3,0xf4f400f4,0xc7c700c7,0x9e9e009e,
+};
+
+
+/**
+ * Stuff related to the Camellia key schedule
+ */
+#define subl(x) subL[(x)]
+#define subr(x) subR[(x)]
+
+static int camellia_setup128(const unsigned char *key, u32 *subkey)
+{
+    u32 kll, klr, krl, krr;
+    u32 il, ir, t0, t1, w0, w1;
+    u32 kw4l, kw4r, dw, tl, tr;
+
+#ifdef WOLFSSL_SMALL_STACK
+    u32* subL;
+    u32* subR;
+
+    subL = (u32*) XMALLOC(sizeof(u32) * 26, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    if (subL == NULL)
+        return MEMORY_E;
+
+    subR = (u32*) XMALLOC(sizeof(u32) * 26, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    if (subR == NULL) {
+        XFREE(subL, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+        return MEMORY_E;
+    }
+#else
+    u32 subL[26];
+    u32 subR[26];
+#endif
+
+    /**
+     *  k == kll || klr || krl || krr (|| is concatenation)
+     */
+    kll = GETU32(key     );
+    klr = GETU32(key +  4);
+    krl = GETU32(key +  8);
+    krr = GETU32(key + 12);
+    /**
+     * generate KL dependent subkeys
+     */
+    subl(0) = kll; subr(0) = klr;
+    subl(1) = krl; subr(1) = krr;
+    CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 15);
+    subl(4) = kll; subr(4) = klr;
+    subl(5) = krl; subr(5) = krr;
+    CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 30);
+    subl(10) = kll; subr(10) = klr;
+    subl(11) = krl; subr(11) = krr;
+    CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 15);
+    subl(13) = krl; subr(13) = krr;
+    CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 17);
+    subl(16) = kll; subr(16) = klr;
+    subl(17) = krl; subr(17) = krr;
+    CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 17);
+    subl(18) = kll; subr(18) = klr;
+    subl(19) = krl; subr(19) = krr;
+    CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 17);
+    subl(22) = kll; subr(22) = klr;
+    subl(23) = krl; subr(23) = krr;
+
+    /* generate KA */
+    kll = subl(0); klr = subr(0);
+    krl = subl(1); krr = subr(1);
+    CAMELLIA_F(kll, klr,
+	       CAMELLIA_SIGMA1L, CAMELLIA_SIGMA1R,
+	       w0, w1, il, ir, t0, t1);
+    krl ^= w0; krr ^= w1;
+    CAMELLIA_F(krl, krr,
+	       CAMELLIA_SIGMA2L, CAMELLIA_SIGMA2R,
+	       kll, klr, il, ir, t0, t1);
+    CAMELLIA_F(kll, klr,
+	       CAMELLIA_SIGMA3L, CAMELLIA_SIGMA3R,
+	       krl, krr, il, ir, t0, t1);
+    krl ^= w0; krr ^= w1;
+    CAMELLIA_F(krl, krr,
+	       CAMELLIA_SIGMA4L, CAMELLIA_SIGMA4R,
+	       w0, w1, il, ir, t0, t1);
+    kll ^= w0; klr ^= w1;
+
+    /* generate KA dependent subkeys */
+    subl(2) = kll; subr(2) = klr;
+    subl(3) = krl; subr(3) = krr;
+    CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 15);
+    subl(6) = kll; subr(6) = klr;
+    subl(7) = krl; subr(7) = krr;
+    CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 15);
+    subl(8) = kll; subr(8) = klr;
+    subl(9) = krl; subr(9) = krr;
+    CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 15);
+    subl(12) = kll; subr(12) = klr;
+    CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 15);
+    subl(14) = kll; subr(14) = klr;
+    subl(15) = krl; subr(15) = krr;
+    CAMELLIA_ROLDQo32(kll, klr, krl, krr, w0, w1, 34);
+    subl(20) = kll; subr(20) = klr;
+    subl(21) = krl; subr(21) = krr;
+    CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 17);
+    subl(24) = kll; subr(24) = klr;
+    subl(25) = krl; subr(25) = krr;
+
+
+    /* absorb kw2 to other subkeys */
+    subl(3) ^= subl(1); subr(3) ^= subr(1);
+    subl(5) ^= subl(1); subr(5) ^= subr(1);
+    subl(7) ^= subl(1); subr(7) ^= subr(1);
+    subl(1) ^= subr(1) & ~subr(9);
+    dw = subl(1) & subl(9), subr(1) ^= CAMELLIA_RL1(dw);
+    subl(11) ^= subl(1); subr(11) ^= subr(1);
+    subl(13) ^= subl(1); subr(13) ^= subr(1);
+    subl(15) ^= subl(1); subr(15) ^= subr(1);
+    subl(1) ^= subr(1) & ~subr(17);
+    dw = subl(1) & subl(17), subr(1) ^= CAMELLIA_RL1(dw);
+    subl(19) ^= subl(1); subr(19) ^= subr(1);
+    subl(21) ^= subl(1); subr(21) ^= subr(1);
+    subl(23) ^= subl(1); subr(23) ^= subr(1);
+    subl(24) ^= subl(1); subr(24) ^= subr(1);
+
+    /* absorb kw4 to other subkeys */
+    kw4l = subl(25); kw4r = subr(25);
+    subl(22) ^= kw4l; subr(22) ^= kw4r;
+    subl(20) ^= kw4l; subr(20) ^= kw4r;
+    subl(18) ^= kw4l; subr(18) ^= kw4r;
+    kw4l ^= kw4r & ~subr(16);
+    dw = kw4l & subl(16), kw4r ^= CAMELLIA_RL1(dw);
+    subl(14) ^= kw4l; subr(14) ^= kw4r;
+    subl(12) ^= kw4l; subr(12) ^= kw4r;
+    subl(10) ^= kw4l; subr(10) ^= kw4r;
+    kw4l ^= kw4r & ~subr(8);
+    dw = kw4l & subl(8), kw4r ^= CAMELLIA_RL1(dw);
+    subl(6) ^= kw4l; subr(6) ^= kw4r;
+    subl(4) ^= kw4l; subr(4) ^= kw4r;
+    subl(2) ^= kw4l; subr(2) ^= kw4r;
+    subl(0) ^= kw4l; subr(0) ^= kw4r;
+
+    /* key XOR is end of F-function */
+    CamelliaSubkeyL(0) = subl(0) ^ subl(2);
+    CamelliaSubkeyR(0) = subr(0) ^ subr(2);
+    CamelliaSubkeyL(2) = subl(3);
+    CamelliaSubkeyR(2) = subr(3);
+    CamelliaSubkeyL(3) = subl(2) ^ subl(4);
+    CamelliaSubkeyR(3) = subr(2) ^ subr(4);
+    CamelliaSubkeyL(4) = subl(3) ^ subl(5);
+    CamelliaSubkeyR(4) = subr(3) ^ subr(5);
+    CamelliaSubkeyL(5) = subl(4) ^ subl(6);
+    CamelliaSubkeyR(5) = subr(4) ^ subr(6);
+    CamelliaSubkeyL(6) = subl(5) ^ subl(7);
+    CamelliaSubkeyR(6) = subr(5) ^ subr(7);
+    tl = subl(10) ^ (subr(10) & ~subr(8));
+    dw = tl & subl(8), tr = subr(10) ^ CAMELLIA_RL1(dw);
+    CamelliaSubkeyL(7) = subl(6) ^ tl;
+    CamelliaSubkeyR(7) = subr(6) ^ tr;
+    CamelliaSubkeyL(8) = subl(8);
+    CamelliaSubkeyR(8) = subr(8);
+    CamelliaSubkeyL(9) = subl(9);
+    CamelliaSubkeyR(9) = subr(9);
+    tl = subl(7) ^ (subr(7) & ~subr(9));
+    dw = tl & subl(9), tr = subr(7) ^ CAMELLIA_RL1(dw);
+    CamelliaSubkeyL(10) = tl ^ subl(11);
+    CamelliaSubkeyR(10) = tr ^ subr(11);
+    CamelliaSubkeyL(11) = subl(10) ^ subl(12);
+    CamelliaSubkeyR(11) = subr(10) ^ subr(12);
+    CamelliaSubkeyL(12) = subl(11) ^ subl(13);
+    CamelliaSubkeyR(12) = subr(11) ^ subr(13);
+    CamelliaSubkeyL(13) = subl(12) ^ subl(14);
+    CamelliaSubkeyR(13) = subr(12) ^ subr(14);
+    CamelliaSubkeyL(14) = subl(13) ^ subl(15);
+    CamelliaSubkeyR(14) = subr(13) ^ subr(15);
+    tl = subl(18) ^ (subr(18) & ~subr(16));
+    dw = tl & subl(16),	tr = subr(18) ^ CAMELLIA_RL1(dw);
+    CamelliaSubkeyL(15) = subl(14) ^ tl;
+    CamelliaSubkeyR(15) = subr(14) ^ tr;
+    CamelliaSubkeyL(16) = subl(16);
+    CamelliaSubkeyR(16) = subr(16);
+    CamelliaSubkeyL(17) = subl(17);
+    CamelliaSubkeyR(17) = subr(17);
+    tl = subl(15) ^ (subr(15) & ~subr(17));
+    dw = tl & subl(17),	tr = subr(15) ^ CAMELLIA_RL1(dw);
+    CamelliaSubkeyL(18) = tl ^ subl(19);
+    CamelliaSubkeyR(18) = tr ^ subr(19);
+    CamelliaSubkeyL(19) = subl(18) ^ subl(20);
+    CamelliaSubkeyR(19) = subr(18) ^ subr(20);
+    CamelliaSubkeyL(20) = subl(19) ^ subl(21);
+    CamelliaSubkeyR(20) = subr(19) ^ subr(21);
+    CamelliaSubkeyL(21) = subl(20) ^ subl(22);
+    CamelliaSubkeyR(21) = subr(20) ^ subr(22);
+    CamelliaSubkeyL(22) = subl(21) ^ subl(23);
+    CamelliaSubkeyR(22) = subr(21) ^ subr(23);
+    CamelliaSubkeyL(23) = subl(22);
+    CamelliaSubkeyR(23) = subr(22);
+    CamelliaSubkeyL(24) = subl(24) ^ subl(23);
+    CamelliaSubkeyR(24) = subr(24) ^ subr(23);
+
+    /* apply the inverse of the last half of P-function */
+    dw = CamelliaSubkeyL(2) ^ CamelliaSubkeyR(2), dw = CAMELLIA_RL8(dw);
+    CamelliaSubkeyR(2) = CamelliaSubkeyL(2) ^ dw, CamelliaSubkeyL(2) = dw;
+    dw = CamelliaSubkeyL(3) ^ CamelliaSubkeyR(3), dw = CAMELLIA_RL8(dw);
+    CamelliaSubkeyR(3) = CamelliaSubkeyL(3) ^ dw, CamelliaSubkeyL(3) = dw;
+    dw = CamelliaSubkeyL(4) ^ CamelliaSubkeyR(4), dw = CAMELLIA_RL8(dw);
+    CamelliaSubkeyR(4) = CamelliaSubkeyL(4) ^ dw, CamelliaSubkeyL(4) = dw;
+    dw = CamelliaSubkeyL(5) ^ CamelliaSubkeyR(5), dw = CAMELLIA_RL8(dw);
+    CamelliaSubkeyR(5) = CamelliaSubkeyL(5) ^ dw, CamelliaSubkeyL(5) = dw;
+    dw = CamelliaSubkeyL(6) ^ CamelliaSubkeyR(6), dw = CAMELLIA_RL8(dw);
+    CamelliaSubkeyR(6) = CamelliaSubkeyL(6) ^ dw, CamelliaSubkeyL(6) = dw;
+    dw = CamelliaSubkeyL(7) ^ CamelliaSubkeyR(7), dw = CAMELLIA_RL8(dw);
+    CamelliaSubkeyR(7) = CamelliaSubkeyL(7) ^ dw, CamelliaSubkeyL(7) = dw;
+    dw = CamelliaSubkeyL(10) ^ CamelliaSubkeyR(10), dw = CAMELLIA_RL8(dw);
+    CamelliaSubkeyR(10) = CamelliaSubkeyL(10) ^ dw, CamelliaSubkeyL(10) = dw;
+    dw = CamelliaSubkeyL(11) ^ CamelliaSubkeyR(11), dw = CAMELLIA_RL8(dw);
+    CamelliaSubkeyR(11) = CamelliaSubkeyL(11) ^ dw, CamelliaSubkeyL(11) = dw;
+    dw = CamelliaSubkeyL(12) ^ CamelliaSubkeyR(12), dw = CAMELLIA_RL8(dw);
+    CamelliaSubkeyR(12) = CamelliaSubkeyL(12) ^ dw, CamelliaSubkeyL(12) = dw;
+    dw = CamelliaSubkeyL(13) ^ CamelliaSubkeyR(13), dw = CAMELLIA_RL8(dw);
+    CamelliaSubkeyR(13) = CamelliaSubkeyL(13) ^ dw, CamelliaSubkeyL(13) = dw;
+    dw = CamelliaSubkeyL(14) ^ CamelliaSubkeyR(14), dw = CAMELLIA_RL8(dw);
+    CamelliaSubkeyR(14) = CamelliaSubkeyL(14) ^ dw, CamelliaSubkeyL(14) = dw;
+    dw = CamelliaSubkeyL(15) ^ CamelliaSubkeyR(15), dw = CAMELLIA_RL8(dw);
+    CamelliaSubkeyR(15) = CamelliaSubkeyL(15) ^ dw, CamelliaSubkeyL(15) = dw;
+    dw = CamelliaSubkeyL(18) ^ CamelliaSubkeyR(18), dw = CAMELLIA_RL8(dw);
+    CamelliaSubkeyR(18) = CamelliaSubkeyL(18) ^ dw, CamelliaSubkeyL(18) = dw;
+    dw = CamelliaSubkeyL(19) ^ CamelliaSubkeyR(19), dw = CAMELLIA_RL8(dw);
+    CamelliaSubkeyR(19) = CamelliaSubkeyL(19) ^ dw, CamelliaSubkeyL(19) = dw;
+    dw = CamelliaSubkeyL(20) ^ CamelliaSubkeyR(20), dw = CAMELLIA_RL8(dw);
+    CamelliaSubkeyR(20) = CamelliaSubkeyL(20) ^ dw, CamelliaSubkeyL(20) = dw;
+    dw = CamelliaSubkeyL(21) ^ CamelliaSubkeyR(21), dw = CAMELLIA_RL8(dw);
+    CamelliaSubkeyR(21) = CamelliaSubkeyL(21) ^ dw, CamelliaSubkeyL(21) = dw;
+    dw = CamelliaSubkeyL(22) ^ CamelliaSubkeyR(22), dw = CAMELLIA_RL8(dw);
+    CamelliaSubkeyR(22) = CamelliaSubkeyL(22) ^ dw, CamelliaSubkeyL(22) = dw;
+    dw = CamelliaSubkeyL(23) ^ CamelliaSubkeyR(23), dw = CAMELLIA_RL8(dw);
+    CamelliaSubkeyR(23) = CamelliaSubkeyL(23) ^ dw, CamelliaSubkeyL(23) = dw;
+
+#ifdef WOLFSSL_SMALL_STACK
+    XFREE(subL, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    XFREE(subR, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+#endif
+
+    return 0;
+}
+
+static int camellia_setup256(const unsigned char *key, u32 *subkey)
+{
+    u32 kll,klr,krl,krr;           /* left half of key */
+    u32 krll,krlr,krrl,krrr;       /* right half of key */
+    u32 il, ir, t0, t1, w0, w1;    /* temporary variables */
+    u32 kw4l, kw4r, dw, tl, tr;
+
+#ifdef WOLFSSL_SMALL_STACK
+    u32* subL;
+    u32* subR;
+
+    subL = (u32*) XMALLOC(sizeof(u32) * 34, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    if (subL == NULL)
+        return MEMORY_E;
+
+    subR = (u32*) XMALLOC(sizeof(u32) * 34, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    if (subR == NULL) {
+        XFREE(subL, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+        return MEMORY_E;
+    }
+#else
+    u32 subL[34];
+    u32 subR[34];
+#endif
+
+    /**
+     *  key = (kll || klr || krl || krr || krll || krlr || krrl || krrr)
+     *  (|| is concatenation)
+     */
+
+    kll  = GETU32(key     );
+    klr  = GETU32(key +  4);
+    krl  = GETU32(key +  8);
+    krr  = GETU32(key + 12);
+    krll = GETU32(key + 16);
+    krlr = GETU32(key + 20);
+    krrl = GETU32(key + 24);
+    krrr = GETU32(key + 28);
+
+    /* generate KL dependent subkeys */
+    subl(0) = kll; subr(0) = klr;
+    subl(1) = krl; subr(1) = krr;
+    CAMELLIA_ROLDQo32(kll, klr, krl, krr, w0, w1, 45);
+    subl(12) = kll; subr(12) = klr;
+    subl(13) = krl; subr(13) = krr;
+    CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 15);
+    subl(16) = kll; subr(16) = klr;
+    subl(17) = krl; subr(17) = krr;
+    CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 17);
+    subl(22) = kll; subr(22) = klr;
+    subl(23) = krl; subr(23) = krr;
+    CAMELLIA_ROLDQo32(kll, klr, krl, krr, w0, w1, 34);
+    subl(30) = kll; subr(30) = klr;
+    subl(31) = krl; subr(31) = krr;
+
+    /* generate KR dependent subkeys */
+    CAMELLIA_ROLDQ(krll, krlr, krrl, krrr, w0, w1, 15);
+    subl(4) = krll; subr(4) = krlr;
+    subl(5) = krrl; subr(5) = krrr;
+    CAMELLIA_ROLDQ(krll, krlr, krrl, krrr, w0, w1, 15);
+    subl(8) = krll; subr(8) = krlr;
+    subl(9) = krrl; subr(9) = krrr;
+    CAMELLIA_ROLDQ(krll, krlr, krrl, krrr, w0, w1, 30);
+    subl(18) = krll; subr(18) = krlr;
+    subl(19) = krrl; subr(19) = krrr;
+    CAMELLIA_ROLDQo32(krll, krlr, krrl, krrr, w0, w1, 34);
+    subl(26) = krll; subr(26) = krlr;
+    subl(27) = krrl; subr(27) = krrr;
+    CAMELLIA_ROLDQo32(krll, krlr, krrl, krrr, w0, w1, 34);
+
+    /* generate KA */
+    kll = subl(0) ^ krll; klr = subr(0) ^ krlr;
+    krl = subl(1) ^ krrl; krr = subr(1) ^ krrr;
+    CAMELLIA_F(kll, klr,
+	       CAMELLIA_SIGMA1L, CAMELLIA_SIGMA1R,
+	       w0, w1, il, ir, t0, t1);
+    krl ^= w0; krr ^= w1;
+    CAMELLIA_F(krl, krr,
+	       CAMELLIA_SIGMA2L, CAMELLIA_SIGMA2R,
+	       kll, klr, il, ir, t0, t1);
+    kll ^= krll; klr ^= krlr;
+    CAMELLIA_F(kll, klr,
+	       CAMELLIA_SIGMA3L, CAMELLIA_SIGMA3R,
+	       krl, krr, il, ir, t0, t1);
+    krl ^= w0 ^ krrl; krr ^= w1 ^ krrr;
+    CAMELLIA_F(krl, krr,
+	       CAMELLIA_SIGMA4L, CAMELLIA_SIGMA4R,
+	       w0, w1, il, ir, t0, t1);
+    kll ^= w0; klr ^= w1;
+
+    /* generate KB */
+    krll ^= kll; krlr ^= klr;
+    krrl ^= krl; krrr ^= krr;
+    CAMELLIA_F(krll, krlr,
+	       CAMELLIA_SIGMA5L, CAMELLIA_SIGMA5R,
+	       w0, w1, il, ir, t0, t1);
+    krrl ^= w0; krrr ^= w1;
+    CAMELLIA_F(krrl, krrr,
+	       CAMELLIA_SIGMA6L, CAMELLIA_SIGMA6R,
+	       w0, w1, il, ir, t0, t1);
+    krll ^= w0; krlr ^= w1;
+
+    /* generate KA dependent subkeys */
+    CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 15);
+    subl(6) = kll; subr(6) = klr;
+    subl(7) = krl; subr(7) = krr;
+    CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 30);
+    subl(14) = kll; subr(14) = klr;
+    subl(15) = krl; subr(15) = krr;
+    subl(24) = klr; subr(24) = krl;
+    subl(25) = krr; subr(25) = kll;
+    CAMELLIA_ROLDQo32(kll, klr, krl, krr, w0, w1, 49);
+    subl(28) = kll; subr(28) = klr;
+    subl(29) = krl; subr(29) = krr;
+
+    /* generate KB dependent subkeys */
+    subl(2) = krll; subr(2) = krlr;
+    subl(3) = krrl; subr(3) = krrr;
+    CAMELLIA_ROLDQ(krll, krlr, krrl, krrr, w0, w1, 30);
+    subl(10) = krll; subr(10) = krlr;
+    subl(11) = krrl; subr(11) = krrr;
+    CAMELLIA_ROLDQ(krll, krlr, krrl, krrr, w0, w1, 30);
+    subl(20) = krll; subr(20) = krlr;
+    subl(21) = krrl; subr(21) = krrr;
+    CAMELLIA_ROLDQo32(krll, krlr, krrl, krrr, w0, w1, 51);
+    subl(32) = krll; subr(32) = krlr;
+    subl(33) = krrl; subr(33) = krrr;
+
+    /* absorb kw2 to other subkeys */
+    subl(3) ^= subl(1); subr(3) ^= subr(1);
+    subl(5) ^= subl(1); subr(5) ^= subr(1);
+    subl(7) ^= subl(1); subr(7) ^= subr(1);
+    subl(1) ^= subr(1) & ~subr(9);
+    dw = subl(1) & subl(9), subr(1) ^= CAMELLIA_RL1(dw);
+    subl(11) ^= subl(1); subr(11) ^= subr(1);
+    subl(13) ^= subl(1); subr(13) ^= subr(1);
+    subl(15) ^= subl(1); subr(15) ^= subr(1);
+    subl(1) ^= subr(1) & ~subr(17);
+    dw = subl(1) & subl(17), subr(1) ^= CAMELLIA_RL1(dw);
+    subl(19) ^= subl(1); subr(19) ^= subr(1);
+    subl(21) ^= subl(1); subr(21) ^= subr(1);
+    subl(23) ^= subl(1); subr(23) ^= subr(1);
+    subl(1) ^= subr(1) & ~subr(25);
+    dw = subl(1) & subl(25), subr(1) ^= CAMELLIA_RL1(dw);
+    subl(27) ^= subl(1); subr(27) ^= subr(1);
+    subl(29) ^= subl(1); subr(29) ^= subr(1);
+    subl(31) ^= subl(1); subr(31) ^= subr(1);
+    subl(32) ^= subl(1); subr(32) ^= subr(1);
+
+    /* absorb kw4 to other subkeys */
+    kw4l = subl(33); kw4r = subr(33);
+    subl(30) ^= kw4l; subr(30) ^= kw4r;
+    subl(28) ^= kw4l; subr(28) ^= kw4r;
+    subl(26) ^= kw4l; subr(26) ^= kw4r;
+    kw4l ^= kw4r & ~subr(24);
+    dw = kw4l & subl(24), kw4r ^= CAMELLIA_RL1(dw);
+    subl(22) ^= kw4l; subr(22) ^= kw4r;
+    subl(20) ^= kw4l; subr(20) ^= kw4r;
+    subl(18) ^= kw4l; subr(18) ^= kw4r;
+    kw4l ^= kw4r & ~subr(16);
+    dw = kw4l & subl(16), kw4r ^= CAMELLIA_RL1(dw);
+    subl(14) ^= kw4l; subr(14) ^= kw4r;
+    subl(12) ^= kw4l; subr(12) ^= kw4r;
+    subl(10) ^= kw4l; subr(10) ^= kw4r;
+    kw4l ^= kw4r & ~subr(8);
+    dw = kw4l & subl(8), kw4r ^= CAMELLIA_RL1(dw);
+    subl(6) ^= kw4l; subr(6) ^= kw4r;
+    subl(4) ^= kw4l; subr(4) ^= kw4r;
+    subl(2) ^= kw4l; subr(2) ^= kw4r;
+    subl(0) ^= kw4l; subr(0) ^= kw4r;
+
+    /* key XOR is end of F-function */
+    CamelliaSubkeyL(0) = subl(0) ^ subl(2);
+    CamelliaSubkeyR(0) = subr(0) ^ subr(2);
+    CamelliaSubkeyL(2) = subl(3);
+    CamelliaSubkeyR(2) = subr(3);
+    CamelliaSubkeyL(3) = subl(2) ^ subl(4);
+    CamelliaSubkeyR(3) = subr(2) ^ subr(4);
+    CamelliaSubkeyL(4) = subl(3) ^ subl(5);
+    CamelliaSubkeyR(4) = subr(3) ^ subr(5);
+    CamelliaSubkeyL(5) = subl(4) ^ subl(6);
+    CamelliaSubkeyR(5) = subr(4) ^ subr(6);
+    CamelliaSubkeyL(6) = subl(5) ^ subl(7);
+    CamelliaSubkeyR(6) = subr(5) ^ subr(7);
+    tl = subl(10) ^ (subr(10) & ~subr(8));
+    dw = tl & subl(8), tr = subr(10) ^ CAMELLIA_RL1(dw);
+    CamelliaSubkeyL(7) = subl(6) ^ tl;
+    CamelliaSubkeyR(7) = subr(6) ^ tr;
+    CamelliaSubkeyL(8) = subl(8);
+    CamelliaSubkeyR(8) = subr(8);
+    CamelliaSubkeyL(9) = subl(9);
+    CamelliaSubkeyR(9) = subr(9);
+    tl = subl(7) ^ (subr(7) & ~subr(9));
+    dw = tl & subl(9), tr = subr(7) ^ CAMELLIA_RL1(dw);
+    CamelliaSubkeyL(10) = tl ^ subl(11);
+    CamelliaSubkeyR(10) = tr ^ subr(11);
+    CamelliaSubkeyL(11) = subl(10) ^ subl(12);
+    CamelliaSubkeyR(11) = subr(10) ^ subr(12);
+    CamelliaSubkeyL(12) = subl(11) ^ subl(13);
+    CamelliaSubkeyR(12) = subr(11) ^ subr(13);
+    CamelliaSubkeyL(13) = subl(12) ^ subl(14);
+    CamelliaSubkeyR(13) = subr(12) ^ subr(14);
+    CamelliaSubkeyL(14) = subl(13) ^ subl(15);
+    CamelliaSubkeyR(14) = subr(13) ^ subr(15);
+    tl = subl(18) ^ (subr(18) & ~subr(16));
+    dw = tl & subl(16), tr = subr(18) ^ CAMELLIA_RL1(dw);
+    CamelliaSubkeyL(15) = subl(14) ^ tl;
+    CamelliaSubkeyR(15) = subr(14) ^ tr;
+    CamelliaSubkeyL(16) = subl(16);
+    CamelliaSubkeyR(16) = subr(16);
+    CamelliaSubkeyL(17) = subl(17);
+    CamelliaSubkeyR(17) = subr(17);
+    tl = subl(15) ^ (subr(15) & ~subr(17));
+    dw = tl & subl(17), tr = subr(15) ^ CAMELLIA_RL1(dw);
+    CamelliaSubkeyL(18) = tl ^ subl(19);
+    CamelliaSubkeyR(18) = tr ^ subr(19);
+    CamelliaSubkeyL(19) = subl(18) ^ subl(20);
+    CamelliaSubkeyR(19) = subr(18) ^ subr(20);
+    CamelliaSubkeyL(20) = subl(19) ^ subl(21);
+    CamelliaSubkeyR(20) = subr(19) ^ subr(21);
+    CamelliaSubkeyL(21) = subl(20) ^ subl(22);
+    CamelliaSubkeyR(21) = subr(20) ^ subr(22);
+    CamelliaSubkeyL(22) = subl(21) ^ subl(23);
+    CamelliaSubkeyR(22) = subr(21) ^ subr(23);
+    tl = subl(26) ^ (subr(26) & ~subr(24));
+    dw = tl & subl(24), tr = subr(26) ^ CAMELLIA_RL1(dw);
+    CamelliaSubkeyL(23) = subl(22) ^ tl;
+    CamelliaSubkeyR(23) = subr(22) ^ tr;
+    CamelliaSubkeyL(24) = subl(24);
+    CamelliaSubkeyR(24) = subr(24);
+    CamelliaSubkeyL(25) = subl(25);
+    CamelliaSubkeyR(25) = subr(25);
+    tl = subl(23) ^ (subr(23) &  ~subr(25));
+    dw = tl & subl(25), tr = subr(23) ^ CAMELLIA_RL1(dw);
+    CamelliaSubkeyL(26) = tl ^ subl(27);
+    CamelliaSubkeyR(26) = tr ^ subr(27);
+    CamelliaSubkeyL(27) = subl(26) ^ subl(28);
+    CamelliaSubkeyR(27) = subr(26) ^ subr(28);
+    CamelliaSubkeyL(28) = subl(27) ^ subl(29);
+    CamelliaSubkeyR(28) = subr(27) ^ subr(29);
+    CamelliaSubkeyL(29) = subl(28) ^ subl(30);
+    CamelliaSubkeyR(29) = subr(28) ^ subr(30);
+    CamelliaSubkeyL(30) = subl(29) ^ subl(31);
+    CamelliaSubkeyR(30) = subr(29) ^ subr(31);
+    CamelliaSubkeyL(31) = subl(30);
+    CamelliaSubkeyR(31) = subr(30);
+    CamelliaSubkeyL(32) = subl(32) ^ subl(31);
+    CamelliaSubkeyR(32) = subr(32) ^ subr(31);
+
+    /* apply the inverse of the last half of P-function */
+    dw = CamelliaSubkeyL(2) ^ CamelliaSubkeyR(2), dw = CAMELLIA_RL8(dw);
+    CamelliaSubkeyR(2) = CamelliaSubkeyL(2) ^ dw, CamelliaSubkeyL(2) = dw;
+    dw = CamelliaSubkeyL(3) ^ CamelliaSubkeyR(3), dw = CAMELLIA_RL8(dw);
+    CamelliaSubkeyR(3) = CamelliaSubkeyL(3) ^ dw, CamelliaSubkeyL(3) = dw;
+    dw = CamelliaSubkeyL(4) ^ CamelliaSubkeyR(4), dw = CAMELLIA_RL8(dw);
+    CamelliaSubkeyR(4) = CamelliaSubkeyL(4) ^ dw, CamelliaSubkeyL(4) = dw;
+    dw = CamelliaSubkeyL(5) ^ CamelliaSubkeyR(5), dw = CAMELLIA_RL8(dw);
+    CamelliaSubkeyR(5) = CamelliaSubkeyL(5) ^ dw, CamelliaSubkeyL(5) = dw;
+    dw = CamelliaSubkeyL(6) ^ CamelliaSubkeyR(6), dw = CAMELLIA_RL8(dw);
+    CamelliaSubkeyR(6) = CamelliaSubkeyL(6) ^ dw, CamelliaSubkeyL(6) = dw;
+    dw = CamelliaSubkeyL(7) ^ CamelliaSubkeyR(7), dw = CAMELLIA_RL8(dw);
+    CamelliaSubkeyR(7) = CamelliaSubkeyL(7) ^ dw, CamelliaSubkeyL(7) = dw;
+    dw = CamelliaSubkeyL(10) ^ CamelliaSubkeyR(10), dw = CAMELLIA_RL8(dw);
+    CamelliaSubkeyR(10) = CamelliaSubkeyL(10) ^ dw, CamelliaSubkeyL(10) = dw;
+    dw = CamelliaSubkeyL(11) ^ CamelliaSubkeyR(11), dw = CAMELLIA_RL8(dw);
+    CamelliaSubkeyR(11) = CamelliaSubkeyL(11) ^ dw, CamelliaSubkeyL(11) = dw;
+    dw = CamelliaSubkeyL(12) ^ CamelliaSubkeyR(12), dw = CAMELLIA_RL8(dw);
+    CamelliaSubkeyR(12) = CamelliaSubkeyL(12) ^ dw, CamelliaSubkeyL(12) = dw;
+    dw = CamelliaSubkeyL(13) ^ CamelliaSubkeyR(13), dw = CAMELLIA_RL8(dw);
+    CamelliaSubkeyR(13) = CamelliaSubkeyL(13) ^ dw, CamelliaSubkeyL(13) = dw;
+    dw = CamelliaSubkeyL(14) ^ CamelliaSubkeyR(14), dw = CAMELLIA_RL8(dw);
+    CamelliaSubkeyR(14) = CamelliaSubkeyL(14) ^ dw, CamelliaSubkeyL(14) = dw;
+    dw = CamelliaSubkeyL(15) ^ CamelliaSubkeyR(15), dw = CAMELLIA_RL8(dw);
+    CamelliaSubkeyR(15) = CamelliaSubkeyL(15) ^ dw, CamelliaSubkeyL(15) = dw;
+    dw = CamelliaSubkeyL(18) ^ CamelliaSubkeyR(18), dw = CAMELLIA_RL8(dw);
+    CamelliaSubkeyR(18) = CamelliaSubkeyL(18) ^ dw, CamelliaSubkeyL(18) = dw;
+    dw = CamelliaSubkeyL(19) ^ CamelliaSubkeyR(19), dw = CAMELLIA_RL8(dw);
+    CamelliaSubkeyR(19) = CamelliaSubkeyL(19) ^ dw, CamelliaSubkeyL(19) = dw;
+    dw = CamelliaSubkeyL(20) ^ CamelliaSubkeyR(20), dw = CAMELLIA_RL8(dw);
+    CamelliaSubkeyR(20) = CamelliaSubkeyL(20) ^ dw, CamelliaSubkeyL(20) = dw;
+    dw = CamelliaSubkeyL(21) ^ CamelliaSubkeyR(21), dw = CAMELLIA_RL8(dw);
+    CamelliaSubkeyR(21) = CamelliaSubkeyL(21) ^ dw, CamelliaSubkeyL(21) = dw;
+    dw = CamelliaSubkeyL(22) ^ CamelliaSubkeyR(22), dw = CAMELLIA_RL8(dw);
+    CamelliaSubkeyR(22) = CamelliaSubkeyL(22) ^ dw, CamelliaSubkeyL(22) = dw;
+    dw = CamelliaSubkeyL(23) ^ CamelliaSubkeyR(23), dw = CAMELLIA_RL8(dw);
+    CamelliaSubkeyR(23) = CamelliaSubkeyL(23) ^ dw, CamelliaSubkeyL(23) = dw;
+    dw = CamelliaSubkeyL(26) ^ CamelliaSubkeyR(26), dw = CAMELLIA_RL8(dw);
+    CamelliaSubkeyR(26) = CamelliaSubkeyL(26) ^ dw, CamelliaSubkeyL(26) = dw;
+    dw = CamelliaSubkeyL(27) ^ CamelliaSubkeyR(27), dw = CAMELLIA_RL8(dw);
+    CamelliaSubkeyR(27) = CamelliaSubkeyL(27) ^ dw, CamelliaSubkeyL(27) = dw;
+    dw = CamelliaSubkeyL(28) ^ CamelliaSubkeyR(28), dw = CAMELLIA_RL8(dw);
+    CamelliaSubkeyR(28) = CamelliaSubkeyL(28) ^ dw, CamelliaSubkeyL(28) = dw;
+    dw = CamelliaSubkeyL(29) ^ CamelliaSubkeyR(29), dw = CAMELLIA_RL8(dw);
+    CamelliaSubkeyR(29) = CamelliaSubkeyL(29) ^ dw, CamelliaSubkeyL(29) = dw;
+    dw = CamelliaSubkeyL(30) ^ CamelliaSubkeyR(30), dw = CAMELLIA_RL8(dw);
+    CamelliaSubkeyR(30) = CamelliaSubkeyL(30) ^ dw, CamelliaSubkeyL(30) = dw;
+    dw = CamelliaSubkeyL(31) ^ CamelliaSubkeyR(31), dw = CAMELLIA_RL8(dw);
+    CamelliaSubkeyR(31) = CamelliaSubkeyL(31) ^ dw,CamelliaSubkeyL(31) = dw;
+
+#ifdef WOLFSSL_SMALL_STACK
+    XFREE(subL, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    XFREE(subR, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+#endif
+
+    return 0;
+}
+
+static int camellia_setup192(const unsigned char *key, u32 *subkey)
+{
+    unsigned char kk[32];
+    u32 krll, krlr, krrl,krrr;
+
+    XMEMCPY(kk, key, 24);
+    XMEMCPY((unsigned char *)&krll, key+16,4);
+    XMEMCPY((unsigned char *)&krlr, key+20,4);
+    krrl = ~krll;
+    krrr = ~krlr;
+    XMEMCPY(kk+24, (unsigned char *)&krrl, 4);
+    XMEMCPY(kk+28, (unsigned char *)&krrr, 4);
+
+    return camellia_setup256(kk, subkey);
+}
+
+
+/**
+ * Stuff related to camellia encryption/decryption
+ *
+ * "io" must be 4byte aligned and big-endian data.
+ */
+static void camellia_encrypt128(const u32 *subkey, u32 *io)
+{
+    u32 il, ir, t0, t1;
+
+    /* pre whitening but absorb kw2*/
+    io[0] ^= CamelliaSubkeyL(0);
+    io[1] ^= CamelliaSubkeyR(0);
+    /* main iteration */
+
+    CAMELLIA_ROUNDSM(io[0],io[1],
+		     CamelliaSubkeyL(2),CamelliaSubkeyR(2),
+		     io[2],io[3],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[2],io[3],
+		     CamelliaSubkeyL(3),CamelliaSubkeyR(3),
+		     io[0],io[1],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[0],io[1],
+		     CamelliaSubkeyL(4),CamelliaSubkeyR(4),
+		     io[2],io[3],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[2],io[3],
+		     CamelliaSubkeyL(5),CamelliaSubkeyR(5),
+		     io[0],io[1],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[0],io[1],
+		     CamelliaSubkeyL(6),CamelliaSubkeyR(6),
+		     io[2],io[3],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[2],io[3],
+		     CamelliaSubkeyL(7),CamelliaSubkeyR(7),
+		     io[0],io[1],il,ir,t0,t1);
+
+    CAMELLIA_FLS(io[0],io[1],io[2],io[3],
+		 CamelliaSubkeyL(8),CamelliaSubkeyR(8),
+		 CamelliaSubkeyL(9),CamelliaSubkeyR(9),
+		 t0,t1,il,ir);
+
+    CAMELLIA_ROUNDSM(io[0],io[1],
+		     CamelliaSubkeyL(10),CamelliaSubkeyR(10),
+		     io[2],io[3],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[2],io[3],
+		     CamelliaSubkeyL(11),CamelliaSubkeyR(11),
+		     io[0],io[1],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[0],io[1],
+		     CamelliaSubkeyL(12),CamelliaSubkeyR(12),
+		     io[2],io[3],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[2],io[3],
+		     CamelliaSubkeyL(13),CamelliaSubkeyR(13),
+		     io[0],io[1],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[0],io[1],
+		     CamelliaSubkeyL(14),CamelliaSubkeyR(14),
+		     io[2],io[3],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[2],io[3],
+		     CamelliaSubkeyL(15),CamelliaSubkeyR(15),
+		     io[0],io[1],il,ir,t0,t1);
+
+    CAMELLIA_FLS(io[0],io[1],io[2],io[3],
+		 CamelliaSubkeyL(16),CamelliaSubkeyR(16),
+		 CamelliaSubkeyL(17),CamelliaSubkeyR(17),
+		 t0,t1,il,ir);
+
+    CAMELLIA_ROUNDSM(io[0],io[1],
+		     CamelliaSubkeyL(18),CamelliaSubkeyR(18),
+		     io[2],io[3],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[2],io[3],
+		     CamelliaSubkeyL(19),CamelliaSubkeyR(19),
+		     io[0],io[1],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[0],io[1],
+		     CamelliaSubkeyL(20),CamelliaSubkeyR(20),
+		     io[2],io[3],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[2],io[3],
+		     CamelliaSubkeyL(21),CamelliaSubkeyR(21),
+		     io[0],io[1],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[0],io[1],
+		     CamelliaSubkeyL(22),CamelliaSubkeyR(22),
+		     io[2],io[3],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[2],io[3],
+		     CamelliaSubkeyL(23),CamelliaSubkeyR(23),
+		     io[0],io[1],il,ir,t0,t1);
+
+    /* post whitening but kw4 */
+    io[2] ^= CamelliaSubkeyL(24);
+    io[3] ^= CamelliaSubkeyR(24);
+
+    t0 = io[0];
+    t1 = io[1];
+    io[0] = io[2];
+    io[1] = io[3];
+    io[2] = t0;
+    io[3] = t1;
+
+    return;
+}
+
+static void camellia_decrypt128(const u32 *subkey, u32 *io)
+{
+    u32 il,ir,t0,t1;               /* temporary variables */
+
+    /* pre whitening but absorb kw2*/
+    io[0] ^= CamelliaSubkeyL(24);
+    io[1] ^= CamelliaSubkeyR(24);
+
+    /* main iteration */
+    CAMELLIA_ROUNDSM(io[0],io[1],
+		     CamelliaSubkeyL(23),CamelliaSubkeyR(23),
+		     io[2],io[3],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[2],io[3],
+		     CamelliaSubkeyL(22),CamelliaSubkeyR(22),
+		     io[0],io[1],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[0],io[1],
+		     CamelliaSubkeyL(21),CamelliaSubkeyR(21),
+		     io[2],io[3],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[2],io[3],
+		     CamelliaSubkeyL(20),CamelliaSubkeyR(20),
+		     io[0],io[1],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[0],io[1],
+		     CamelliaSubkeyL(19),CamelliaSubkeyR(19),
+		     io[2],io[3],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[2],io[3],
+		     CamelliaSubkeyL(18),CamelliaSubkeyR(18),
+		     io[0],io[1],il,ir,t0,t1);
+
+    CAMELLIA_FLS(io[0],io[1],io[2],io[3],
+		 CamelliaSubkeyL(17),CamelliaSubkeyR(17),
+		 CamelliaSubkeyL(16),CamelliaSubkeyR(16),
+		 t0,t1,il,ir);
+
+    CAMELLIA_ROUNDSM(io[0],io[1],
+		     CamelliaSubkeyL(15),CamelliaSubkeyR(15),
+		     io[2],io[3],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[2],io[3],
+		     CamelliaSubkeyL(14),CamelliaSubkeyR(14),
+		     io[0],io[1],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[0],io[1],
+		     CamelliaSubkeyL(13),CamelliaSubkeyR(13),
+		     io[2],io[3],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[2],io[3],
+		     CamelliaSubkeyL(12),CamelliaSubkeyR(12),
+		     io[0],io[1],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[0],io[1],
+		     CamelliaSubkeyL(11),CamelliaSubkeyR(11),
+		     io[2],io[3],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[2],io[3],
+		     CamelliaSubkeyL(10),CamelliaSubkeyR(10),
+		     io[0],io[1],il,ir,t0,t1);
+
+    CAMELLIA_FLS(io[0],io[1],io[2],io[3],
+		 CamelliaSubkeyL(9),CamelliaSubkeyR(9),
+		 CamelliaSubkeyL(8),CamelliaSubkeyR(8),
+		 t0,t1,il,ir);
+
+    CAMELLIA_ROUNDSM(io[0],io[1],
+		     CamelliaSubkeyL(7),CamelliaSubkeyR(7),
+		     io[2],io[3],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[2],io[3],
+		     CamelliaSubkeyL(6),CamelliaSubkeyR(6),
+		     io[0],io[1],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[0],io[1],
+		     CamelliaSubkeyL(5),CamelliaSubkeyR(5),
+		     io[2],io[3],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[2],io[3],
+		     CamelliaSubkeyL(4),CamelliaSubkeyR(4),
+		     io[0],io[1],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[0],io[1],
+		     CamelliaSubkeyL(3),CamelliaSubkeyR(3),
+		     io[2],io[3],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[2],io[3],
+		     CamelliaSubkeyL(2),CamelliaSubkeyR(2),
+		     io[0],io[1],il,ir,t0,t1);
+
+    /* post whitening but kw4 */
+    io[2] ^= CamelliaSubkeyL(0);
+    io[3] ^= CamelliaSubkeyR(0);
+
+    t0 = io[0];
+    t1 = io[1];
+    io[0] = io[2];
+    io[1] = io[3];
+    io[2] = t0;
+    io[3] = t1;
+
+    return;
+}
+
+/**
+ * stuff for 192 and 256bit encryption/decryption
+ */
+static void camellia_encrypt256(const u32 *subkey, u32 *io)
+{
+    u32 il,ir,t0,t1;           /* temporary variables */
+
+    /* pre whitening but absorb kw2*/
+    io[0] ^= CamelliaSubkeyL(0);
+    io[1] ^= CamelliaSubkeyR(0);
+
+    /* main iteration */
+    CAMELLIA_ROUNDSM(io[0],io[1],
+		     CamelliaSubkeyL(2),CamelliaSubkeyR(2),
+		     io[2],io[3],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[2],io[3],
+		     CamelliaSubkeyL(3),CamelliaSubkeyR(3),
+		     io[0],io[1],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[0],io[1],
+		     CamelliaSubkeyL(4),CamelliaSubkeyR(4),
+		     io[2],io[3],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[2],io[3],
+		     CamelliaSubkeyL(5),CamelliaSubkeyR(5),
+		     io[0],io[1],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[0],io[1],
+		     CamelliaSubkeyL(6),CamelliaSubkeyR(6),
+		     io[2],io[3],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[2],io[3],
+		     CamelliaSubkeyL(7),CamelliaSubkeyR(7),
+		     io[0],io[1],il,ir,t0,t1);
+
+    CAMELLIA_FLS(io[0],io[1],io[2],io[3],
+		 CamelliaSubkeyL(8),CamelliaSubkeyR(8),
+		 CamelliaSubkeyL(9),CamelliaSubkeyR(9),
+		 t0,t1,il,ir);
+
+    CAMELLIA_ROUNDSM(io[0],io[1],
+		     CamelliaSubkeyL(10),CamelliaSubkeyR(10),
+		     io[2],io[3],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[2],io[3],
+		     CamelliaSubkeyL(11),CamelliaSubkeyR(11),
+		     io[0],io[1],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[0],io[1],
+		     CamelliaSubkeyL(12),CamelliaSubkeyR(12),
+		     io[2],io[3],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[2],io[3],
+		     CamelliaSubkeyL(13),CamelliaSubkeyR(13),
+		     io[0],io[1],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[0],io[1],
+		     CamelliaSubkeyL(14),CamelliaSubkeyR(14),
+		     io[2],io[3],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[2],io[3],
+		     CamelliaSubkeyL(15),CamelliaSubkeyR(15),
+		     io[0],io[1],il,ir,t0,t1);
+
+    CAMELLIA_FLS(io[0],io[1],io[2],io[3],
+		 CamelliaSubkeyL(16),CamelliaSubkeyR(16),
+		 CamelliaSubkeyL(17),CamelliaSubkeyR(17),
+		 t0,t1,il,ir);
+
+    CAMELLIA_ROUNDSM(io[0],io[1],
+		     CamelliaSubkeyL(18),CamelliaSubkeyR(18),
+		     io[2],io[3],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[2],io[3],
+		     CamelliaSubkeyL(19),CamelliaSubkeyR(19),
+		     io[0],io[1],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[0],io[1],
+		     CamelliaSubkeyL(20),CamelliaSubkeyR(20),
+		     io[2],io[3],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[2],io[3],
+		     CamelliaSubkeyL(21),CamelliaSubkeyR(21),
+		     io[0],io[1],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[0],io[1],
+		     CamelliaSubkeyL(22),CamelliaSubkeyR(22),
+		     io[2],io[3],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[2],io[3],
+		     CamelliaSubkeyL(23),CamelliaSubkeyR(23),
+		     io[0],io[1],il,ir,t0,t1);
+
+    CAMELLIA_FLS(io[0],io[1],io[2],io[3],
+		 CamelliaSubkeyL(24),CamelliaSubkeyR(24),
+		 CamelliaSubkeyL(25),CamelliaSubkeyR(25),
+		 t0,t1,il,ir);
+
+    CAMELLIA_ROUNDSM(io[0],io[1],
+		     CamelliaSubkeyL(26),CamelliaSubkeyR(26),
+		     io[2],io[3],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[2],io[3],
+		     CamelliaSubkeyL(27),CamelliaSubkeyR(27),
+		     io[0],io[1],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[0],io[1],
+		     CamelliaSubkeyL(28),CamelliaSubkeyR(28),
+		     io[2],io[3],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[2],io[3],
+		     CamelliaSubkeyL(29),CamelliaSubkeyR(29),
+		     io[0],io[1],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[0],io[1],
+		     CamelliaSubkeyL(30),CamelliaSubkeyR(30),
+		     io[2],io[3],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[2],io[3],
+		     CamelliaSubkeyL(31),CamelliaSubkeyR(31),
+		     io[0],io[1],il,ir,t0,t1);
+
+    /* post whitening but kw4 */
+    io[2] ^= CamelliaSubkeyL(32);
+    io[3] ^= CamelliaSubkeyR(32);
+
+    t0 = io[0];
+    t1 = io[1];
+    io[0] = io[2];
+    io[1] = io[3];
+    io[2] = t0;
+    io[3] = t1;
+
+    return;
+}
+
+static void camellia_decrypt256(const u32 *subkey, u32 *io)
+{
+    u32 il,ir,t0,t1;           /* temporary variables */
+
+    /* pre whitening but absorb kw2*/
+    io[0] ^= CamelliaSubkeyL(32);
+    io[1] ^= CamelliaSubkeyR(32);
+
+    /* main iteration */
+    CAMELLIA_ROUNDSM(io[0],io[1],
+		     CamelliaSubkeyL(31),CamelliaSubkeyR(31),
+		     io[2],io[3],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[2],io[3],
+		     CamelliaSubkeyL(30),CamelliaSubkeyR(30),
+		     io[0],io[1],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[0],io[1],
+		     CamelliaSubkeyL(29),CamelliaSubkeyR(29),
+		     io[2],io[3],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[2],io[3],
+		     CamelliaSubkeyL(28),CamelliaSubkeyR(28),
+		     io[0],io[1],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[0],io[1],
+		     CamelliaSubkeyL(27),CamelliaSubkeyR(27),
+		     io[2],io[3],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[2],io[3],
+		     CamelliaSubkeyL(26),CamelliaSubkeyR(26),
+		     io[0],io[1],il,ir,t0,t1);
+
+    CAMELLIA_FLS(io[0],io[1],io[2],io[3],
+		 CamelliaSubkeyL(25),CamelliaSubkeyR(25),
+		 CamelliaSubkeyL(24),CamelliaSubkeyR(24),
+		 t0,t1,il,ir);
+
+    CAMELLIA_ROUNDSM(io[0],io[1],
+		     CamelliaSubkeyL(23),CamelliaSubkeyR(23),
+		     io[2],io[3],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[2],io[3],
+		     CamelliaSubkeyL(22),CamelliaSubkeyR(22),
+		     io[0],io[1],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[0],io[1],
+		     CamelliaSubkeyL(21),CamelliaSubkeyR(21),
+		     io[2],io[3],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[2],io[3],
+		     CamelliaSubkeyL(20),CamelliaSubkeyR(20),
+		     io[0],io[1],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[0],io[1],
+		     CamelliaSubkeyL(19),CamelliaSubkeyR(19),
+		     io[2],io[3],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[2],io[3],
+		     CamelliaSubkeyL(18),CamelliaSubkeyR(18),
+		     io[0],io[1],il,ir,t0,t1);
+
+    CAMELLIA_FLS(io[0],io[1],io[2],io[3],
+		 CamelliaSubkeyL(17),CamelliaSubkeyR(17),
+		 CamelliaSubkeyL(16),CamelliaSubkeyR(16),
+		 t0,t1,il,ir);
+
+    CAMELLIA_ROUNDSM(io[0],io[1],
+		     CamelliaSubkeyL(15),CamelliaSubkeyR(15),
+		     io[2],io[3],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[2],io[3],
+		     CamelliaSubkeyL(14),CamelliaSubkeyR(14),
+		     io[0],io[1],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[0],io[1],
+		     CamelliaSubkeyL(13),CamelliaSubkeyR(13),
+		     io[2],io[3],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[2],io[3],
+		     CamelliaSubkeyL(12),CamelliaSubkeyR(12),
+		     io[0],io[1],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[0],io[1],
+		     CamelliaSubkeyL(11),CamelliaSubkeyR(11),
+		     io[2],io[3],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[2],io[3],
+		     CamelliaSubkeyL(10),CamelliaSubkeyR(10),
+		     io[0],io[1],il,ir,t0,t1);
+
+    CAMELLIA_FLS(io[0],io[1],io[2],io[3],
+		 CamelliaSubkeyL(9),CamelliaSubkeyR(9),
+		 CamelliaSubkeyL(8),CamelliaSubkeyR(8),
+		 t0,t1,il,ir);
+
+    CAMELLIA_ROUNDSM(io[0],io[1],
+		     CamelliaSubkeyL(7),CamelliaSubkeyR(7),
+		     io[2],io[3],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[2],io[3],
+		     CamelliaSubkeyL(6),CamelliaSubkeyR(6),
+		     io[0],io[1],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[0],io[1],
+		     CamelliaSubkeyL(5),CamelliaSubkeyR(5),
+		     io[2],io[3],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[2],io[3],
+		     CamelliaSubkeyL(4),CamelliaSubkeyR(4),
+		     io[0],io[1],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[0],io[1],
+		     CamelliaSubkeyL(3),CamelliaSubkeyR(3),
+		     io[2],io[3],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[2],io[3],
+		     CamelliaSubkeyL(2),CamelliaSubkeyR(2),
+		     io[0],io[1],il,ir,t0,t1);
+
+    /* post whitening but kw4 */
+    io[2] ^= CamelliaSubkeyL(0);
+    io[3] ^= CamelliaSubkeyR(0);
+
+    t0 = io[0];
+    t1 = io[1];
+    io[0] = io[2];
+    io[1] = io[3];
+    io[2] = t0;
+    io[3] = t1;
+
+    return;
+}
+
+/***
+ *
+ * API for compatibility
+ */
+
+static void Camellia_EncryptBlock(const int keyBitLength,
+			   const unsigned char *plaintext,
+			   const KEY_TABLE_TYPE keyTable,
+			   unsigned char *ciphertext)
+{
+    u32 tmp[4];
+
+    tmp[0] = GETU32(plaintext);
+    tmp[1] = GETU32(plaintext + 4);
+    tmp[2] = GETU32(plaintext + 8);
+    tmp[3] = GETU32(plaintext + 12);
+
+    switch (keyBitLength) {
+    case 128:
+	camellia_encrypt128(keyTable, tmp);
+	break;
+    case 192:
+	/* fall through */
+    case 256:
+	camellia_encrypt256(keyTable, tmp);
+	break;
+    default:
+	break;
+    }
+
+    PUTU32(ciphertext, tmp[0]);
+    PUTU32(ciphertext + 4, tmp[1]);
+    PUTU32(ciphertext + 8, tmp[2]);
+    PUTU32(ciphertext + 12, tmp[3]);
+}
+
+static void Camellia_DecryptBlock(const int keyBitLength,
+			   const unsigned char *ciphertext,
+			   const KEY_TABLE_TYPE keyTable,
+			   unsigned char *plaintext)
+{
+    u32 tmp[4];
+
+    tmp[0] = GETU32(ciphertext);
+    tmp[1] = GETU32(ciphertext + 4);
+    tmp[2] = GETU32(ciphertext + 8);
+    tmp[3] = GETU32(ciphertext + 12);
+
+    switch (keyBitLength) {
+    case 128:
+	camellia_decrypt128(keyTable, tmp);
+	break;
+    case 192:
+	/* fall through */
+    case 256:
+	camellia_decrypt256(keyTable, tmp);
+	break;
+    default:
+	break;
+    }
+    PUTU32(plaintext, tmp[0]);
+    PUTU32(plaintext + 4, tmp[1]);
+    PUTU32(plaintext + 8, tmp[2]);
+    PUTU32(plaintext + 12, tmp[3]);
+}
+
+
+
+/* wolfCrypt wrappers to the Camellia code */
+
+int wc_CamelliaSetKey(Camellia* cam, const byte* key, word32 len, const byte* iv)
+{
+    int ret = 0;
+
+    if (cam == NULL) return BAD_FUNC_ARG;
+
+    XMEMSET(cam->key, 0, sizeof(KEY_TABLE_TYPE));
+
+    switch (len) {
+        case 16:
+        	ret = camellia_setup128(key, cam->key);
+            break;
+        case 24:
+        	ret = camellia_setup192(key, cam->key);
+            break;
+        case 32:
+            ret = camellia_setup256(key, cam->key);
+            break;
+        default:
+            return BAD_FUNC_ARG;
+    }
+
+    if (ret != 0)
+        return ret;
+
+    cam->keySz = len * 8;
+
+    return wc_CamelliaSetIV(cam, iv);
+}
+
+
+int wc_CamelliaSetIV(Camellia* cam, const byte* iv)
+{
+    if (cam == NULL)
+        return BAD_FUNC_ARG;
+
+    if (iv)
+        XMEMCPY(cam->reg, iv, CAMELLIA_BLOCK_SIZE);
+    else
+        XMEMSET(cam->reg,  0, CAMELLIA_BLOCK_SIZE);
+
+    return 0;
+}
+
+
+int wc_CamelliaEncryptDirect(Camellia* cam, byte* out, const byte* in)
+{
+    if (cam == NULL || out == NULL || in == NULL) {
+        return BAD_FUNC_ARG;
+    }
+    Camellia_EncryptBlock(cam->keySz, in, cam->key, out);
+
+    return 0;
+}
+
+
+int wc_CamelliaDecryptDirect(Camellia* cam, byte* out, const byte* in)
+{
+    if (cam == NULL || out == NULL || in == NULL) {
+        return BAD_FUNC_ARG;
+    }
+    Camellia_DecryptBlock(cam->keySz, in, cam->key, out);
+
+    return 0;
+}
+
+
+int wc_CamelliaCbcEncrypt(Camellia* cam, byte* out, const byte* in, word32 sz)
+{
+    word32 blocks;
+    if (cam == NULL || out == NULL || in == NULL) {
+        return BAD_FUNC_ARG;
+    }
+    blocks = sz / CAMELLIA_BLOCK_SIZE;
+
+    while (blocks--) {
+        xorbuf((byte*)cam->reg, in, CAMELLIA_BLOCK_SIZE);
+        Camellia_EncryptBlock(cam->keySz, (byte*)cam->reg,
+                                                     cam->key, (byte*)cam->reg);
+        XMEMCPY(out, cam->reg, CAMELLIA_BLOCK_SIZE);
+
+        out += CAMELLIA_BLOCK_SIZE;
+        in  += CAMELLIA_BLOCK_SIZE;
+    }
+
+    return 0;
+}
+
+
+int wc_CamelliaCbcDecrypt(Camellia* cam, byte* out, const byte* in, word32 sz)
+{
+    word32 blocks;
+    if (cam == NULL || out == NULL || in == NULL) {
+        return BAD_FUNC_ARG;
+    }
+    blocks = sz / CAMELLIA_BLOCK_SIZE;
+
+    while (blocks--) {
+        XMEMCPY(cam->tmp, in, CAMELLIA_BLOCK_SIZE);
+        Camellia_DecryptBlock(cam->keySz, (byte*)cam->tmp, cam->key, out);
+        xorbuf(out, (byte*)cam->reg, CAMELLIA_BLOCK_SIZE);
+        XMEMCPY(cam->reg, cam->tmp, CAMELLIA_BLOCK_SIZE);
+
+        out += CAMELLIA_BLOCK_SIZE;
+        in  += CAMELLIA_BLOCK_SIZE;
+    }
+
+    return 0;
+}
+
+
+#endif /* HAVE_CAMELLIA */
+
Index: azure_iot_hub_f767zi/trunk/wolfssl-4.4.0/wolfcrypt/src/coding.c
===================================================================
--- azure_iot_hub_f767zi/trunk/wolfssl-4.4.0/wolfcrypt/src/coding.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/wolfssl-4.4.0/wolfcrypt/src/coding.c	(revision 457)
@@ -0,0 +1,511 @@
+/* coding.c
+ *
+ * Copyright (C) 2006-2020 wolfSSL Inc.
+ *
+ * This file is part of wolfSSL.
+ *
+ * wolfSSL is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * wolfSSL is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
+ */
+
+
+#ifdef HAVE_CONFIG_H
+    #include <config.h>
+#endif
+
+#include <wolfssl/wolfcrypt/settings.h>
+
+#ifndef NO_CODING
+
+#include <wolfssl/wolfcrypt/coding.h>
+#include <wolfssl/wolfcrypt/error-crypt.h>
+#include <wolfssl/wolfcrypt/logging.h>
+
+
+enum {
+    BAD         = 0xFF,  /* invalid encoding */
+    PAD         = '=',
+    PEM_LINE_SZ = 64,
+    BASE64_MIN  = 0x2B,
+    BASE16_MIN  = 0x30,
+};
+
+
+#ifdef WOLFSSL_BASE64_DECODE
+
+static
+const byte base64Decode[] = { 62, BAD, BAD, BAD, 63,   /* + starts at 0x2B */
+                              52, 53, 54, 55, 56, 57, 58, 59, 60, 61,
+                              BAD, BAD, BAD, BAD, BAD, BAD, BAD,
+                              0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
+                              10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
+                              20, 21, 22, 23, 24, 25,
+                              BAD, BAD, BAD, BAD, BAD, BAD,
+                              26, 27, 28, 29, 30, 31, 32, 33, 34, 35,
+                              36, 37, 38, 39, 40, 41, 42, 43, 44, 45,
+                              46, 47, 48, 49, 50, 51
+                            };
+
+static WC_INLINE int Base64_SkipNewline(const byte* in, word32 *inLen, word32 *outJ)
+{
+    word32 len = *inLen;
+    word32 j = *outJ;
+    if (len && (in[j] == ' ' || in[j] == '\r' || in[j] == '\n')) {
+        byte endLine = in[j++];
+        len--;
+        while (len && endLine == ' ') {   /* allow trailing whitespace */
+            endLine = in[j++];
+            len--;
+        }
+        if (endLine == '\r') {
+            if (len) {
+                endLine = in[j++];
+                len--;
+            }
+        }
+        if (endLine != '\n') {
+            WOLFSSL_MSG("Bad end of line in Base64 Decode");
+            return ASN_INPUT_E;
+        }
+    }
+    if (!len) {
+        return BUFFER_E;
+    }
+    *inLen = len;
+    *outJ = j;
+    return 0;
+}
+
+int Base64_Decode(const byte* in, word32 inLen, byte* out, word32* outLen)
+{
+    word32 i = 0;
+    word32 j = 0;
+    word32 plainSz = inLen - ((inLen + (PEM_LINE_SZ - 1)) / PEM_LINE_SZ );
+    int ret;
+    const byte maxIdx = (byte)sizeof(base64Decode) + BASE64_MIN - 1;
+
+    plainSz = (plainSz * 3 + 3) / 4;
+    if (plainSz > *outLen) return BAD_FUNC_ARG;
+
+    while (inLen > 3) {
+        int pad3 = 0;
+        int pad4 = 0;
+
+        byte b1, b2, b3;
+        byte e1, e2, e3, e4;
+        if ((ret = Base64_SkipNewline(in, &inLen, &j)) != 0) {
+            if (ret == BUFFER_E) {
+                /* Running out of buffer here is not an error */
+                break;
+            }
+            return ret;
+        }
+        e1 = in[j++];
+        if (e1 == '\0') {
+            break;
+        }
+        inLen--;
+        if ((ret = Base64_SkipNewline(in, &inLen, &j)) != 0) {
+            return ret;
+        }
+        e2 = in[j++];
+        inLen--;
+        if ((ret = Base64_SkipNewline(in, &inLen, &j)) != 0) {
+            return ret;
+        }
+        e3 = in[j++];
+        inLen--;
+        if ((ret = Base64_SkipNewline(in, &inLen, &j)) != 0) {
+            return ret;
+        }
+        e4 = in[j++];
+        inLen--;
+
+        if (e1 == 0)            /* end file 0's */
+            break;
+        if (e3 == PAD)
+            pad3 = 1;
+        if (e4 == PAD)
+            pad4 = 1;
+
+        if (e1 < BASE64_MIN || e2 < BASE64_MIN || e3 < BASE64_MIN || e4 < BASE64_MIN) {
+            WOLFSSL_MSG("Bad Base64 Decode data, too small");
+            return ASN_INPUT_E;
+        }
+
+        if (e1 > maxIdx || e2 > maxIdx || e3 > maxIdx || e4 > maxIdx) {
+            WOLFSSL_MSG("Bad Base64 Decode data, too big");
+            return ASN_INPUT_E;
+        }
+
+        if (i + 1 + !pad3 + !pad4 > *outLen) {
+            WOLFSSL_MSG("Bad Base64 Decode out buffer, too small");
+            return BAD_FUNC_ARG;
+        }
+
+        e1 = base64Decode[e1 - BASE64_MIN];
+        e2 = base64Decode[e2 - BASE64_MIN];
+        e3 = (e3 == PAD) ? 0 : base64Decode[e3 - BASE64_MIN];
+        e4 = (e4 == PAD) ? 0 : base64Decode[e4 - BASE64_MIN];
+
+        b1 = (byte)((e1 << 2) | (e2 >> 4));
+        b2 = (byte)(((e2 & 0xF) << 4) | (e3 >> 2));
+        b3 = (byte)(((e3 & 0x3) << 6) | e4);
+
+        out[i++] = b1;
+        if (!pad3)
+            out[i++] = b2;
+        if (!pad4)
+            out[i++] = b3;
+        else
+            break;
+    }
+/* If the output buffer has a room for an extra byte, add a null terminator */
+    if (out && *outLen > i)
+        out[i]= '\0';
+
+    *outLen = i;
+
+    return 0;
+}
+
+#endif /* WOLFSSL_BASE64_DECODE */
+
+#if defined(WOLFSSL_BASE64_ENCODE)
+
+static
+const byte base64Encode[] = { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J',
+                              'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T',
+                              'U', 'V', 'W', 'X', 'Y', 'Z',
+                              'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j',
+                              'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't',
+                              'u', 'v', 'w', 'x', 'y', 'z',
+                              '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
+                              '+', '/'
+                            };
+
+
+/* make sure *i (idx) won't exceed max, store and possibly escape to out,
+ * raw means use e w/o decode,  0 on success */
+static int CEscape(int escaped, byte e, byte* out, word32* i, word32 max,
+                  int raw, int getSzOnly)
+{
+    int    doEscape = 0;
+    word32 needed = 1;
+    word32 idx = *i;
+
+    byte basic;
+    byte plus    = 0;
+    byte equals  = 0;
+    byte newline = 0;
+
+    if (raw)
+        basic = e;
+    else
+        basic = base64Encode[e];
+
+    /* check whether to escape. Only escape for EncodeEsc */
+    if (escaped == WC_ESC_NL_ENC) {
+        switch ((char)basic) {
+            case '+' :
+                plus     = 1;
+                doEscape = 1;
+                needed  += 2;
+                break;
+            case '=' :
+                equals   = 1;
+                doEscape = 1;
+                needed  += 2;
+                break;
+            case '\n' :
+                newline  = 1;
+                doEscape = 1;
+                needed  += 2;
+                break;
+            default:
+                /* do nothing */
+                break;
+        }
+    }
+
+    /* check size */
+    if ( (idx+needed) > max && !getSzOnly) {
+        WOLFSSL_MSG("Escape buffer max too small");
+        return BUFFER_E;
+    }
+
+    /* store it */
+    if (doEscape == 0) {
+        if(getSzOnly)
+            idx++;
+        else
+            out[idx++] = basic;
+    }
+    else {
+        if(getSzOnly)
+            idx+=3;
+        else {
+            out[idx++] = '%';  /* start escape */
+
+            if (plus) {
+                out[idx++] = '2';
+                out[idx++] = 'B';
+            }
+            else if (equals) {
+                out[idx++] = '3';
+                out[idx++] = 'D';
+            }
+            else if (newline) {
+                out[idx++] = '0';
+                out[idx++] = 'A';
+            }
+        }
+    }
+    *i = idx;
+
+    return 0;
+}
+
+
+/* internal worker, handles both escaped and normal line endings.
+   If out buffer is NULL, will return sz needed in outLen */
+static int DoBase64_Encode(const byte* in, word32 inLen, byte* out,
+                           word32* outLen, int escaped)
+{
+    int    ret = 0;
+    word32 i = 0,
+           j = 0,
+           n = 0;   /* new line counter */
+
+    int    getSzOnly = (out == NULL);
+
+    word32 outSz = (inLen + 3 - 1) / 3 * 4;
+    word32 addSz = (outSz + PEM_LINE_SZ - 1) / PEM_LINE_SZ;  /* new lines */
+
+    if (escaped == WC_ESC_NL_ENC)
+        addSz *= 3;   /* instead of just \n, we're doing %0A triplet */
+    else if (escaped == WC_NO_NL_ENC)
+        addSz = 0;    /* encode without \n */
+
+    outSz += addSz;
+
+    /* if escaped we can't predetermine size for one pass encoding, but
+     * make sure we have enough if no escapes are in input
+     * Also need to ensure outLen valid before dereference */
+    if (!outLen || (outSz > *outLen && !getSzOnly)) return BAD_FUNC_ARG;
+
+    while (inLen > 2) {
+        byte b1 = in[j++];
+        byte b2 = in[j++];
+        byte b3 = in[j++];
+
+        /* encoded idx */
+        byte e1 = b1 >> 2;
+        byte e2 = (byte)(((b1 & 0x3) << 4) | (b2 >> 4));
+        byte e3 = (byte)(((b2 & 0xF) << 2) | (b3 >> 6));
+        byte e4 = b3 & 0x3F;
+
+        /* store */
+        ret = CEscape(escaped, e1, out, &i, *outLen, 0, getSzOnly);
+        if (ret != 0) break;
+        ret = CEscape(escaped, e2, out, &i, *outLen, 0, getSzOnly);
+        if (ret != 0) break;
+        ret = CEscape(escaped, e3, out, &i, *outLen, 0, getSzOnly);
+        if (ret != 0) break;
+        ret = CEscape(escaped, e4, out, &i, *outLen, 0, getSzOnly);
+        if (ret != 0) break;
+
+        inLen -= 3;
+
+        /* Insert newline after PEM_LINE_SZ, unless no \n requested */
+        if (escaped != WC_NO_NL_ENC && (++n % (PEM_LINE_SZ/4)) == 0 && inLen) {
+            ret = CEscape(escaped, '\n', out, &i, *outLen, 1, getSzOnly);
+            if (ret != 0) break;
+        }
+    }
+
+    /* last integral */
+    if (inLen && ret == 0) {
+        int twoBytes = (inLen == 2);
+
+        byte b1 = in[j++];
+        byte b2 = (twoBytes) ? in[j++] : 0;
+
+        byte e1 = b1 >> 2;
+        byte e2 = (byte)(((b1 & 0x3) << 4) | (b2 >> 4));
+        byte e3 = (byte)((b2 & 0xF) << 2);
+
+        ret = CEscape(escaped, e1, out, &i, *outLen, 0, getSzOnly);
+        if (ret == 0)
+            ret = CEscape(escaped, e2, out, &i, *outLen, 0, getSzOnly);
+        if (ret == 0) {
+            /* third */
+            if (twoBytes)
+                ret = CEscape(escaped, e3, out, &i, *outLen, 0, getSzOnly);
+            else
+                ret = CEscape(escaped, '=', out, &i, *outLen, 1, getSzOnly);
+        }
+        /* fourth always pad */
+        if (ret == 0)
+            ret = CEscape(escaped, '=', out, &i, *outLen, 1, getSzOnly);
+    }
+
+    if (ret == 0 && escaped != WC_NO_NL_ENC)
+        ret = CEscape(escaped, '\n', out, &i, *outLen, 1, getSzOnly);
+
+    if (i != outSz && escaped != 1 && ret == 0)
+        return ASN_INPUT_E;
+/* If the output buffer has a room for an extra byte, add a null terminator */
+    if (out && *outLen > i)
+        out[i]= '\0';
+
+    *outLen = i;
+
+    if (ret == 0)
+        return getSzOnly ? LENGTH_ONLY_E : 0;
+
+    return ret;
+}
+
+
+/* Base64 Encode, PEM style, with \n line endings */
+int Base64_Encode(const byte* in, word32 inLen, byte* out, word32* outLen)
+{
+    return DoBase64_Encode(in, inLen, out, outLen, WC_STD_ENC);
+}
+
+
+/* Base64 Encode, with %0A escaped line endings instead of \n */
+int Base64_EncodeEsc(const byte* in, word32 inLen, byte* out, word32* outLen)
+{
+    return DoBase64_Encode(in, inLen, out, outLen, WC_ESC_NL_ENC);
+}
+
+int Base64_Encode_NoNl(const byte* in, word32 inLen, byte* out, word32* outLen)
+{
+    return DoBase64_Encode(in, inLen, out, outLen, WC_NO_NL_ENC);
+}
+
+#endif /* WOLFSSL_BASE64_ENCODE */
+
+
+#ifdef WOLFSSL_BASE16
+
+static
+const byte hexDecode[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
+                           BAD, BAD, BAD, BAD, BAD, BAD, BAD,
+                           10, 11, 12, 13, 14, 15,  /* upper case A-F */
+                           BAD, BAD, BAD, BAD, BAD, BAD, BAD, BAD,
+                           BAD, BAD, BAD, BAD, BAD, BAD, BAD, BAD,
+                           BAD, BAD, BAD, BAD, BAD, BAD, BAD, BAD,
+                           BAD, BAD,  /* G - ` */
+                           10, 11, 12, 13, 14, 15   /* lower case a-f */
+                         };  /* A starts at 0x41 not 0x3A */
+
+int Base16_Decode(const byte* in, word32 inLen, byte* out, word32* outLen)
+{
+    word32 inIdx  = 0;
+    word32 outIdx = 0;
+
+    if (in == NULL || out == NULL || outLen == NULL)
+        return BAD_FUNC_ARG;
+
+    if (inLen == 1 && *outLen && in) {
+        byte b = in[inIdx++] - BASE16_MIN;  /* 0 starts at 0x30 */
+
+        /* sanity check */
+        if (b >=  sizeof(hexDecode)/sizeof(hexDecode[0]))
+            return ASN_INPUT_E;
+
+        b  = hexDecode[b];
+
+        if (b == BAD)
+            return ASN_INPUT_E;
+
+        out[outIdx++] = b;
+
+        *outLen = outIdx;
+        return 0;
+    }
+
+    if (inLen % 2)
+        return BAD_FUNC_ARG;
+
+    if (*outLen < (inLen / 2))
+        return BAD_FUNC_ARG;
+
+    while (inLen) {
+        byte b  = in[inIdx++] - BASE16_MIN;  /* 0 starts at 0x30 */
+        byte b2 = in[inIdx++] - BASE16_MIN;
+
+        /* sanity checks */
+        if (b >=  sizeof(hexDecode)/sizeof(hexDecode[0]))
+            return ASN_INPUT_E;
+        if (b2 >= sizeof(hexDecode)/sizeof(hexDecode[0]))
+            return ASN_INPUT_E;
+
+        b  = hexDecode[b];
+        b2 = hexDecode[b2];
+
+        if (b == BAD || b2 == BAD)
+            return ASN_INPUT_E;
+
+        out[outIdx++] = (byte)((b << 4) | b2);
+        inLen -= 2;
+    }
+
+    *outLen = outIdx;
+    return 0;
+}
+
+int Base16_Encode(const byte* in, word32 inLen, byte* out, word32* outLen)
+{
+    word32 outIdx = 0;
+    word32 i;
+    byte   hb, lb;
+
+    if (in == NULL || out == NULL || outLen == NULL)
+        return BAD_FUNC_ARG;
+
+    if (*outLen < (2 * inLen + 1))
+        return BAD_FUNC_ARG;
+
+    for (i = 0; i < inLen; i++) {
+        hb = in[i] >> 4;
+        lb = in[i] & 0x0f;
+
+        /* ASCII value */
+        hb += '0';
+        if (hb > '9')
+            hb += 7;
+
+        /* ASCII value */
+        lb += '0';
+        if (lb>'9')
+            lb += 7;
+
+        out[outIdx++] = hb;
+        out[outIdx++] = lb;
+    }
+
+    /* force 0 at this end */
+    out[outIdx++] = 0;
+
+    *outLen = outIdx;
+    return 0;
+}
+
+#endif /* WOLFSSL_BASE16 */
+
+#endif /* !NO_CODING */
Index: azure_iot_hub_f767zi/trunk/wolfssl-4.4.0/wolfcrypt/src/des3.c
===================================================================
--- azure_iot_hub_f767zi/trunk/wolfssl-4.4.0/wolfcrypt/src/des3.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/wolfssl-4.4.0/wolfcrypt/src/des3.c	(revision 457)
@@ -0,0 +1,1825 @@
+/* des3.c
+ *
+ * Copyright (C) 2006-2020 wolfSSL Inc.
+ *
+ * This file is part of wolfSSL.
+ *
+ * wolfSSL is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * wolfSSL is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
+ */
+
+
+#ifdef HAVE_CONFIG_H
+    #include <config.h>
+#endif
+
+#include <wolfssl/wolfcrypt/settings.h>
+#include <wolfssl/wolfcrypt/error-crypt.h>
+#include <wolfssl/wolfcrypt/logging.h>
+
+
+#ifndef NO_DES3
+
+#if defined(HAVE_FIPS) && \
+	defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION >= 2)
+
+    /* set NO_WRAPPERS before headers, use direct internal f()s not wrappers */
+    #define FIPS_NO_WRAPPERS
+
+    #ifdef USE_WINDOWS_API
+        #pragma code_seg(".fipsA$i")
+        #pragma const_seg(".fipsB$i")
+    #endif
+#endif
+
+#include <wolfssl/wolfcrypt/des3.h>
+
+#ifdef WOLF_CRYPTO_CB
+    #include <wolfssl/wolfcrypt/cryptocb.h>
+#endif
+
+/* fips wrapper calls, user can call direct */
+#if defined(HAVE_FIPS) && \
+    (!defined(HAVE_FIPS_VERSION) || (HAVE_FIPS_VERSION < 2))
+
+    int wc_Des_SetKey(Des* des, const byte* key, const byte* iv, int dir)
+    {
+        return Des_SetKey(des, key, iv, dir);
+    }
+    int wc_Des3_SetKey(Des3* des, const byte* key, const byte* iv, int dir)
+    {
+        if (des == NULL || key == NULL || dir < 0) {
+            return BAD_FUNC_ARG;
+        }
+
+        return Des3_SetKey_fips(des, key, iv, dir);
+    }
+    int wc_Des_CbcEncrypt(Des* des, byte* out, const byte* in, word32 sz)
+    {
+        return Des_CbcEncrypt(des, out, in, sz);
+    }
+    int wc_Des_CbcDecrypt(Des* des, byte* out, const byte* in, word32 sz)
+    {
+        return Des_CbcDecrypt(des, out, in, sz);
+    }
+    int wc_Des3_CbcEncrypt(Des3* des, byte* out, const byte* in, word32 sz)
+    {
+        if (des == NULL || out == NULL || in == NULL) {
+            return BAD_FUNC_ARG;
+        }
+        return Des3_CbcEncrypt_fips(des, out, in, sz);
+    }
+    int wc_Des3_CbcDecrypt(Des3* des, byte* out, const byte* in, word32 sz)
+    {
+        if (des == NULL || out == NULL || in == NULL) {
+            return BAD_FUNC_ARG;
+        }
+        return Des3_CbcDecrypt_fips(des, out, in, sz);
+    }
+
+    #ifdef WOLFSSL_DES_ECB
+        /* One block, compatibility only */
+        int wc_Des_EcbEncrypt(Des* des, byte* out, const byte* in, word32 sz)
+        {
+            return Des_EcbEncrypt(des, out, in, sz);
+        }
+        int wc_Des3_EcbEncrypt(Des3* des, byte* out, const byte* in, word32 sz)
+        {
+            return Des3_EcbEncrypt(des, out, in, sz);
+        }
+    #endif /* WOLFSSL_DES_ECB */
+
+    void wc_Des_SetIV(Des* des, const byte* iv)
+    {
+        Des_SetIV(des, iv);
+    }
+    int wc_Des3_SetIV(Des3* des, const byte* iv)
+    {
+        return Des3_SetIV_fips(des, iv);
+    }
+
+    int wc_Des3Init(Des3* des3, void* heap, int devId)
+    {
+        (void)des3;
+        (void)heap;
+        (void)devId;
+        /* FIPS doesn't support:
+            return Des3Init(des3, heap, devId); */
+        return 0;
+    }
+    void wc_Des3Free(Des3* des3)
+    {
+        (void)des3;
+        /* FIPS doesn't support:
+            Des3Free(des3); */
+    }
+
+#else /* else build without fips, or for FIPS v2 */
+
+
+#if defined(WOLFSSL_TI_CRYPT)
+    #include <wolfcrypt/src/port/ti/ti-des3.c>
+#else
+
+
+#ifdef NO_INLINE
+    #include <wolfssl/wolfcrypt/misc.h>
+#else
+    #define WOLFSSL_MISC_INCLUDED
+    #include <wolfcrypt/src/misc.c>
+#endif
+
+
+/* Hardware Acceleration */
+#if defined(STM32_CRYPTO)
+
+    /*
+     * STM32F2/F4 hardware DES/3DES support through the standard
+     * peripheral library. (See note in README).
+     */
+
+    int wc_Des_SetKey(Des* des, const byte* key, const byte* iv, int dir)
+    {
+        word32 *dkey = des->key;
+
+        (void)dir;
+
+        XMEMCPY(dkey, key, 8);
+    #ifndef WOLFSSL_STM32_CUBEMX
+        ByteReverseWords(dkey, dkey, 8);
+    #endif
+
+        wc_Des_SetIV(des, iv);
+
+        return 0;
+    }
+
+    int wc_Des3_SetKey(Des3* des, const byte* key, const byte* iv, int dir)
+    {
+        if (des == NULL || key == NULL)
+            return BAD_FUNC_ARG;
+
+        (void)dir;
+
+    #ifndef WOLFSSL_STM32_CUBEMX
+        {
+            word32 *dkey1 = des->key[0];
+            word32 *dkey2 = des->key[1];
+            word32 *dkey3 = des->key[2];
+
+            XMEMCPY(dkey1, key, 8);         /* set key 1 */
+            XMEMCPY(dkey2, key + 8, 8);     /* set key 2 */
+            XMEMCPY(dkey3, key + 16, 8);    /* set key 3 */
+
+            ByteReverseWords(dkey1, dkey1, 8);
+            ByteReverseWords(dkey2, dkey2, 8);
+            ByteReverseWords(dkey3, dkey3, 8);
+        }
+    #else
+        XMEMCPY(des->key[0], key, DES3_KEYLEN); /* CUBEMX wants keys in sequential memory */
+    #endif
+
+        return wc_Des3_SetIV(des, iv);
+    }
+
+    static void DesCrypt(Des* des, byte* out, const byte* in, word32 sz,
+                  int dir, int mode)
+    {
+        int ret;
+    #ifdef WOLFSSL_STM32_CUBEMX
+        CRYP_HandleTypeDef hcryp;
+    #else
+        word32 *dkey, *iv;
+        CRYP_InitTypeDef DES_CRYP_InitStructure;
+        CRYP_KeyInitTypeDef DES_CRYP_KeyInitStructure;
+        CRYP_IVInitTypeDef DES_CRYP_IVInitStructure;
+    #endif
+
+        ret = wolfSSL_CryptHwMutexLock();
+        if (ret != 0) {
+            return;
+        }
+
+    #ifdef WOLFSSL_STM32_CUBEMX
+        XMEMSET(&hcryp, 0, sizeof(CRYP_HandleTypeDef));
+        hcryp.Instance = CRYP;
+        hcryp.Init.KeySize  = CRYP_KEYSIZE_128B;
+        hcryp.Init.DataType = CRYP_DATATYPE_8B;
+        hcryp.Init.pKey = (uint8_t*)des->key;
+        hcryp.Init.pInitVect = (uint8_t*)des->reg;
+
+        HAL_CRYP_Init(&hcryp);
+
+        while (sz > 0) {
+            /* if input and output same will overwrite input iv */
+            XMEMCPY(des->tmp, in + sz - DES_BLOCK_SIZE, DES_BLOCK_SIZE);
+
+            if (mode == DES_CBC) {
+                if (dir == DES_ENCRYPTION) {
+                    HAL_CRYP_DESCBC_Encrypt(&hcryp, (uint8_t*)in,
+                                    DES_BLOCK_SIZE, out, STM32_HAL_TIMEOUT);
+                }
+                else {
+                    HAL_CRYP_DESCBC_Decrypt(&hcryp, (uint8_t*)in,
+                                    DES_BLOCK_SIZE, out, STM32_HAL_TIMEOUT);
+                }
+            }
+            else {
+                if (dir == DES_ENCRYPTION) {
+                    HAL_CRYP_DESECB_Encrypt(&hcryp, (uint8_t*)in,
+                                    DES_BLOCK_SIZE, out, STM32_HAL_TIMEOUT);
+                }
+                else {
+                    HAL_CRYP_DESECB_Decrypt(&hcryp, (uint8_t*)in,
+                                    DES_BLOCK_SIZE, out, STM32_HAL_TIMEOUT);
+                }
+            }
+
+            /* store iv for next call */
+            XMEMCPY(des->reg, des->tmp, DES_BLOCK_SIZE);
+
+            sz  -= DES_BLOCK_SIZE;
+            in  += DES_BLOCK_SIZE;
+            out += DES_BLOCK_SIZE;
+        }
+
+        HAL_CRYP_DeInit(&hcryp);
+    #else
+        dkey = des->key;
+        iv = des->reg;
+
+        /* crypto structure initialization */
+        CRYP_KeyStructInit(&DES_CRYP_KeyInitStructure);
+        CRYP_StructInit(&DES_CRYP_InitStructure);
+        CRYP_IVStructInit(&DES_CRYP_IVInitStructure);
+
+        /* reset registers to their default values */
+        CRYP_DeInit();
+
+        /* set direction, mode, and datatype */
+        if (dir == DES_ENCRYPTION) {
+            DES_CRYP_InitStructure.CRYP_AlgoDir  = CRYP_AlgoDir_Encrypt;
+        } else { /* DES_DECRYPTION */
+            DES_CRYP_InitStructure.CRYP_AlgoDir  = CRYP_AlgoDir_Decrypt;
+        }
+
+        if (mode == DES_CBC) {
+            DES_CRYP_InitStructure.CRYP_AlgoMode = CRYP_AlgoMode_DES_CBC;
+        } else { /* DES_ECB */
+            DES_CRYP_InitStructure.CRYP_AlgoMode = CRYP_AlgoMode_DES_ECB;
+        }
+
+        DES_CRYP_InitStructure.CRYP_DataType = CRYP_DataType_8b;
+        CRYP_Init(&DES_CRYP_InitStructure);
+
+        /* load key into correct registers */
+        DES_CRYP_KeyInitStructure.CRYP_Key1Left  = dkey[0];
+        DES_CRYP_KeyInitStructure.CRYP_Key1Right = dkey[1];
+        CRYP_KeyInit(&DES_CRYP_KeyInitStructure);
+
+        /* set iv */
+        ByteReverseWords(iv, iv, DES_BLOCK_SIZE);
+        DES_CRYP_IVInitStructure.CRYP_IV0Left  = iv[0];
+        DES_CRYP_IVInitStructure.CRYP_IV0Right = iv[1];
+        CRYP_IVInit(&DES_CRYP_IVInitStructure);
+
+        /* enable crypto processor */
+        CRYP_Cmd(ENABLE);
+
+        while (sz > 0) {
+            /* flush IN/OUT FIFOs */
+            CRYP_FIFOFlush();
+
+            /* if input and output same will overwrite input iv */
+            XMEMCPY(des->tmp, in + sz - DES_BLOCK_SIZE, DES_BLOCK_SIZE);
+
+            CRYP_DataIn(*(uint32_t*)&in[0]);
+            CRYP_DataIn(*(uint32_t*)&in[4]);
+
+            /* wait until the complete message has been processed */
+            while(CRYP_GetFlagStatus(CRYP_FLAG_BUSY) != RESET) {}
+
+            *(uint32_t*)&out[0]  = CRYP_DataOut();
+            *(uint32_t*)&out[4]  = CRYP_DataOut();
+
+            /* store iv for next call */
+            XMEMCPY(des->reg, des->tmp, DES_BLOCK_SIZE);
+
+            sz  -= DES_BLOCK_SIZE;
+            in  += DES_BLOCK_SIZE;
+            out += DES_BLOCK_SIZE;
+        }
+
+        /* disable crypto processor */
+        CRYP_Cmd(DISABLE);
+    #endif /* WOLFSSL_STM32_CUBEMX */
+        wolfSSL_CryptHwMutexUnLock();
+    }
+
+    int wc_Des_CbcEncrypt(Des* des, byte* out, const byte* in, word32 sz)
+    {
+        DesCrypt(des, out, in, sz, DES_ENCRYPTION, DES_CBC);
+        return 0;
+    }
+
+    int wc_Des_CbcDecrypt(Des* des, byte* out, const byte* in, word32 sz)
+    {
+        DesCrypt(des, out, in, sz, DES_DECRYPTION, DES_CBC);
+        return 0;
+    }
+
+    int wc_Des_EcbEncrypt(Des* des, byte* out, const byte* in, word32 sz)
+    {
+        DesCrypt(des, out, in, sz, DES_ENCRYPTION, DES_ECB);
+        return 0;
+    }
+
+    static void Des3Crypt(Des3* des, byte* out, const byte* in, word32 sz,
+                   int dir)
+    {
+        if (des == NULL || out == NULL || in == NULL)
+            return BAD_FUNC_ARG;
+
+    #ifdef WOLFSSL_STM32_CUBEMX
+        {
+            CRYP_HandleTypeDef hcryp;
+
+            XMEMSET(&hcryp, 0, sizeof(CRYP_HandleTypeDef));
+            hcryp.Instance = CRYP;
+            hcryp.Init.KeySize  = CRYP_KEYSIZE_128B;
+            hcryp.Init.DataType = CRYP_DATATYPE_8B;
+            hcryp.Init.pKey = (uint8_t*)des->key;
+            hcryp.Init.pInitVect = (uint8_t*)des->reg;
+
+            HAL_CRYP_Init(&hcryp);
+
+            while (sz > 0)
+            {
+                if (dir == DES_ENCRYPTION) {
+                    HAL_CRYP_TDESCBC_Encrypt(&hcryp, (byte*)in,
+                                       DES_BLOCK_SIZE, out, STM32_HAL_TIMEOUT);
+                }
+                else {
+                    HAL_CRYP_TDESCBC_Decrypt(&hcryp, (byte*)in,
+                                       DES_BLOCK_SIZE, out, STM32_HAL_TIMEOUT);
+                }
+
+                /* store iv for next call */
+                XMEMCPY(des->reg, out + sz - DES_BLOCK_SIZE, DES_BLOCK_SIZE);
+
+                sz  -= DES_BLOCK_SIZE;
+                in  += DES_BLOCK_SIZE;
+                out += DES_BLOCK_SIZE;
+            }
+
+            HAL_CRYP_DeInit(&hcryp);
+        }
+    #else
+        {
+            word32 *dkey1, *dkey2, *dkey3, *iv;
+            CRYP_InitTypeDef DES3_CRYP_InitStructure;
+            CRYP_KeyInitTypeDef DES3_CRYP_KeyInitStructure;
+            CRYP_IVInitTypeDef DES3_CRYP_IVInitStructure;
+
+            dkey1 = des->key[0];
+            dkey2 = des->key[1];
+            dkey3 = des->key[2];
+            iv = des->reg;
+
+            /* crypto structure initialization */
+            CRYP_KeyStructInit(&DES3_CRYP_KeyInitStructure);
+            CRYP_StructInit(&DES3_CRYP_InitStructure);
+            CRYP_IVStructInit(&DES3_CRYP_IVInitStructure);
+
+            /* reset registers to their default values */
+            CRYP_DeInit();
+
+            /* set direction, mode, and datatype */
+            if (dir == DES_ENCRYPTION) {
+                DES3_CRYP_InitStructure.CRYP_AlgoDir  = CRYP_AlgoDir_Encrypt;
+            } else {
+                DES3_CRYP_InitStructure.CRYP_AlgoDir  = CRYP_AlgoDir_Decrypt;
+            }
+
+            DES3_CRYP_InitStructure.CRYP_AlgoMode = CRYP_AlgoMode_TDES_CBC;
+            DES3_CRYP_InitStructure.CRYP_DataType = CRYP_DataType_8b;
+            CRYP_Init(&DES3_CRYP_InitStructure);
+
+            /* load key into correct registers */
+            DES3_CRYP_KeyInitStructure.CRYP_Key1Left  = dkey1[0];
+            DES3_CRYP_KeyInitStructure.CRYP_Key1Right = dkey1[1];
+            DES3_CRYP_KeyInitStructure.CRYP_Key2Left  = dkey2[0];
+            DES3_CRYP_KeyInitStructure.CRYP_Key2Right = dkey2[1];
+            DES3_CRYP_KeyInitStructure.CRYP_Key3Left  = dkey3[0];
+            DES3_CRYP_KeyInitStructure.CRYP_Key3Right = dkey3[1];
+            CRYP_KeyInit(&DES3_CRYP_KeyInitStructure);
+
+            /* set iv */
+            ByteReverseWords(iv, iv, DES_BLOCK_SIZE);
+            DES3_CRYP_IVInitStructure.CRYP_IV0Left  = iv[0];
+            DES3_CRYP_IVInitStructure.CRYP_IV0Right = iv[1];
+            CRYP_IVInit(&DES3_CRYP_IVInitStructure);
+
+            /* enable crypto processor */
+            CRYP_Cmd(ENABLE);
+
+            while (sz > 0)
+            {
+                /* flush IN/OUT FIFOs */
+                CRYP_FIFOFlush();
+
+                CRYP_DataIn(*(uint32_t*)&in[0]);
+                CRYP_DataIn(*(uint32_t*)&in[4]);
+
+                /* wait until the complete message has been processed */
+                while(CRYP_GetFlagStatus(CRYP_FLAG_BUSY) != RESET) {}
+
+                *(uint32_t*)&out[0]  = CRYP_DataOut();
+                *(uint32_t*)&out[4]  = CRYP_DataOut();
+
+                /* store iv for next call */
+                XMEMCPY(des->reg, out + sz - DES_BLOCK_SIZE, DES_BLOCK_SIZE);
+
+                sz  -= DES_BLOCK_SIZE;
+                in  += DES_BLOCK_SIZE;
+                out += DES_BLOCK_SIZE;
+            }
+
+            /* disable crypto processor */
+            CRYP_Cmd(DISABLE);
+        }
+    #endif /* WOLFSSL_STM32_CUBEMX */
+    }
+
+    int wc_Des3_CbcEncrypt(Des3* des, byte* out, const byte* in, word32 sz)
+    {
+        Des3Crypt(des, out, in, sz, DES_ENCRYPTION);
+        return 0;
+    }
+
+    int wc_Des3_CbcDecrypt(Des3* des, byte* out, const byte* in, word32 sz)
+    {
+        Des3Crypt(des, out, in, sz, DES_DECRYPTION);
+        return 0;
+    }
+
+#elif defined(HAVE_COLDFIRE_SEC)
+
+    #include <wolfssl/ctaocrypt/types.h>
+
+    #include "sec.h"
+    #include "mcf5475_sec.h"
+    #include "mcf5475_siu.h"
+
+    #if defined (HAVE_THREADX)
+    #include "memory_pools.h"
+    extern TX_BYTE_POOL mp_ncached;  /* Non Cached memory pool */
+    #endif
+
+    #define DES_BUFFER_SIZE (DES_BLOCK_SIZE * 64)
+    static unsigned char *desBuffIn = NULL;
+    static unsigned char *desBuffOut = NULL;
+    static byte *secIV;
+    static byte *secKey;
+    static volatile SECdescriptorType *secDesc;
+
+    static wolfSSL_Mutex Mutex_DesSEC;
+
+    #define SEC_DESC_DES_CBC_ENCRYPT  0x20500010
+    #define SEC_DESC_DES_CBC_DECRYPT  0x20400010
+    #define SEC_DESC_DES3_CBC_ENCRYPT 0x20700010
+    #define SEC_DESC_DES3_CBC_DECRYPT 0x20600010
+
+    #define DES_IVLEN 8
+    #define DES_KEYLEN 8
+    #define DES3_IVLEN 8
+    #define DES3_KEYLEN 24
+
+    extern volatile unsigned char __MBAR[];
+
+    static void wc_Des_Cbc(byte* out, const byte* in, word32 sz,
+                        byte *key, byte *iv, word32 desc)
+    {
+        #ifdef DEBUG_WOLFSSL
+        int ret;  int stat1,stat2;
+    	  #endif
+        int size;
+        volatile int v;
+
+        wc_LockMutex(&Mutex_DesSEC) ;
+
+        secDesc->length1 = 0x0;
+        secDesc->pointer1 = NULL;
+        if((desc==SEC_DESC_DES_CBC_ENCRYPT)||(desc==SEC_DESC_DES_CBC_DECRYPT)){
+            secDesc->length2 = DES_IVLEN;
+            secDesc->length3 = DES_KEYLEN;
+        } else {
+            secDesc->length2 = DES3_IVLEN;
+            secDesc->length3 = DES3_KEYLEN;
+        }
+        secDesc->pointer2 = secIV;
+        secDesc->pointer3 = secKey;
+        secDesc->pointer4 = desBuffIn;
+        secDesc->pointer5 = desBuffOut;
+        secDesc->length6 = 0;
+        secDesc->pointer6 = NULL;
+        secDesc->length7 = 0x0;
+        secDesc->pointer7 = NULL;
+        secDesc->nextDescriptorPtr = NULL;
+
+        while(sz) {
+            XMEMCPY(secIV, iv, secDesc->length2);
+            if((sz%DES_BUFFER_SIZE) == sz) {
+                size = sz;
+                sz = 0;
+            } else {
+                size = DES_BUFFER_SIZE;
+                sz -= DES_BUFFER_SIZE;
+            }
+
+            XMEMCPY(desBuffIn, in, size);
+            XMEMCPY(secKey, key, secDesc->length3);
+
+            secDesc->header = desc;
+            secDesc->length4 = size;
+            secDesc->length5 = size;
+            /* Point SEC to the location of the descriptor */
+            MCF_SEC_FR0 = (uint32)secDesc;
+            /* Initialize SEC and wait for encryption to complete */
+            MCF_SEC_CCCR0 = 0x0000001a;
+            /* poll SISR to determine when channel is complete */
+            v=0;
+            while((secDesc->header>> 24) != 0xff) {
+                if(v++ > 1000)break;
+            }
+
+        #ifdef DEBUG_WOLFSSL
+            ret = MCF_SEC_SISRH;
+            stat1 = MCF_SEC_DSR;
+            stat2 = MCF_SEC_DISR;
+            if(ret & 0xe0000000) {
+                /* db_printf("Des_Cbc(%x):ISRH=%08x, DSR=%08x, DISR=%08x\n", desc, ret, stat1, stat2); */
+            }
+        #endif
+
+            XMEMCPY(out, desBuffOut, size);
+
+            if ((desc==SEC_DESC_DES3_CBC_ENCRYPT)||(desc==SEC_DESC_DES_CBC_ENCRYPT)) {
+                XMEMCPY((void*)iv, (void*)&(out[size-secDesc->length2]), secDesc->length2);
+            } else {
+                XMEMCPY((void*)iv, (void*)&(in[size-secDesc->length2]), secDesc->length2);
+            }
+
+            in  += size;
+            out += size;
+
+        }
+        wc_UnLockMutex(&Mutex_DesSEC) ;
+
+    }
+
+
+    int wc_Des_CbcEncrypt(Des* des, byte* out, const byte* in, word32 sz)
+    {
+        wc_Des_Cbc(out, in, sz,  (byte *)des->key,  (byte *)des->reg, SEC_DESC_DES_CBC_ENCRYPT);
+        return 0;
+    }
+
+    int wc_Des_CbcDecrypt(Des* des, byte* out, const byte* in, word32 sz)
+    {
+        wc_Des_Cbc(out, in, sz,   (byte *)des->key,  (byte *)des->reg, SEC_DESC_DES_CBC_DECRYPT);
+        return 0;
+    }
+
+    int wc_Des3_CbcEncrypt(Des3* des3, byte* out, const byte* in, word32 sz)
+    {
+        wc_Des_Cbc(out, in, sz,  (byte *)des3->key,  (byte *)des3->reg, SEC_DESC_DES3_CBC_ENCRYPT);
+    	  return 0;
+    }
+
+
+    int wc_Des3_CbcDecrypt(Des3* des3, byte* out, const byte* in, word32 sz)
+    {
+        wc_Des_Cbc(out, in, sz,   (byte *)des3->key,  (byte *)des3->reg, SEC_DESC_DES3_CBC_DECRYPT);
+    	  return 0;
+    }
+
+    static void setParity(byte *buf, int len)
+    {
+        int i, j;
+        byte v;
+        int bits;
+
+        for (i=0; i<len; i++) {
+            v = buf[i] >> 1;
+            buf[i] = v << 1;
+            bits = 0;
+            for (j=0; j<7; j++) {
+                bits += (v&0x1);
+                v = v >> 1;
+            }
+            buf[i] |= (1 - (bits&0x1));
+        }
+
+    }
+
+    int wc_Des_SetKey(Des* des, const byte* key, const byte* iv, int dir)
+    {
+        if(desBuffIn == NULL) {
+        #if defined (HAVE_THREADX)
+    			  int s1, s2, s3, s4, s5;
+            s5 = tx_byte_allocate(&mp_ncached,(void *)&secDesc,
+                                                         sizeof(SECdescriptorType), TX_NO_WAIT);
+            s1 = tx_byte_allocate(&mp_ncached,(void *)&desBuffIn,  DES_BUFFER_SIZE, TX_NO_WAIT);
+            s2 = tx_byte_allocate(&mp_ncached,(void *)&desBuffOut, DES_BUFFER_SIZE, TX_NO_WAIT);
+            /* Don't know des or des3 to be used. Allocate larger buffers */
+            s3 = tx_byte_allocate(&mp_ncached,(void *)&secKey,     DES3_KEYLEN,TX_NO_WAIT);
+            s4 = tx_byte_allocate(&mp_ncached,(void *)&secIV,      DES3_IVLEN,  TX_NO_WAIT);
+        #else
+            #warning "Allocate non-Cache buffers"
+        #endif
+
+            InitMutex(&Mutex_DesSEC);
+        }
+
+        XMEMCPY(des->key, key, DES_KEYLEN);
+        setParity((byte *)des->key, DES_KEYLEN);
+
+        if (iv) {
+            XMEMCPY(des->reg, iv, DES_IVLEN);
+        }   else {
+            XMEMSET(des->reg, 0x0, DES_IVLEN);
+        }
+    		return 0;
+    }
+
+    int wc_Des3_SetKey(Des3* des3, const byte* key, const byte* iv, int dir)
+    {
+        if (des3 == NULL || key == NULL) {
+            return BAD_FUNC_ARG;
+        }
+
+        if (desBuffIn == NULL) {
+        #if defined (HAVE_THREADX)
+            int s1, s2, s3, s4, s5;
+            s5 = tx_byte_allocate(&mp_ncached,(void *)&secDesc,
+                                                         sizeof(SECdescriptorType), TX_NO_WAIT);
+            s1 = tx_byte_allocate(&mp_ncached,(void *)&desBuffIn,  DES_BUFFER_SIZE, TX_NO_WAIT);
+            s2 = tx_byte_allocate(&mp_ncached,(void *)&desBuffOut, DES_BUFFER_SIZE, TX_NO_WAIT);
+            s3 = tx_byte_allocate(&mp_ncached,(void *)&secKey,     DES3_KEYLEN,TX_NO_WAIT);
+            s4 = tx_byte_allocate(&mp_ncached,(void *)&secIV,      DES3_IVLEN,  TX_NO_WAIT);
+        #else
+            #warning "Allocate non-Cache buffers"
+        #endif
+
+            InitMutex(&Mutex_DesSEC);
+        }
+
+        XMEMCPY(des3->key[0], key, DES3_KEYLEN);
+        setParity((byte *)des3->key[0], DES3_KEYLEN);
+
+        if (iv) {
+            XMEMCPY(des3->reg, iv, DES3_IVLEN);
+        }   else {
+            XMEMSET(des3->reg, 0x0, DES3_IVLEN);
+        }
+        return 0;
+
+    }
+#elif defined(FREESCALE_LTC_DES)
+
+    #include "fsl_ltc.h"
+    int wc_Des_SetKey(Des* des, const byte* key, const byte* iv, int dir)
+    {
+        byte* dkey;
+
+        if (des == NULL || key == NULL) {
+            return BAD_FUNC_ARG;
+        }
+
+        dkey = (byte*)des->key;
+
+        XMEMCPY(dkey, key, 8);
+
+        wc_Des_SetIV(des, iv);
+
+        return 0;
+    }
+
+    int wc_Des3_SetKey(Des3* des, const byte* key, const byte* iv, int dir)
+    {
+        int ret = 0;
+        byte* dkey1 = (byte*)des->key[0];
+        byte* dkey2 = (byte*)des->key[1];
+        byte* dkey3 = (byte*)des->key[2];
+
+        XMEMCPY(dkey1, key, 8);         /* set key 1 */
+        XMEMCPY(dkey2, key + 8, 8);     /* set key 2 */
+        XMEMCPY(dkey3, key + 16, 8);    /* set key 3 */
+
+        ret = wc_Des3_SetIV(des, iv);
+        if (ret != 0)
+            return ret;
+
+        return ret;
+    }
+
+    int wc_Des_CbcEncrypt(Des* des, byte* out, const byte* in, word32 sz)
+    {
+        status_t status;
+        status = LTC_DES_EncryptCbc(LTC_BASE, in, out, sz, (byte*)des->reg, (byte*)des->key);
+        if (status == kStatus_Success)
+            return 0;
+        else
+            return -1;
+    }
+
+    int wc_Des_CbcDecrypt(Des* des, byte* out, const byte* in, word32 sz)
+    {
+        status_t status;
+        status = LTC_DES_DecryptCbc(LTC_BASE, in, out, sz, (byte*)des->reg, (byte*)des->key);
+        if (status == kStatus_Success)
+            return 0;
+        else
+            return -1;
+    }
+
+    int wc_Des3_CbcEncrypt(Des3* des, byte* out, const byte* in, word32 sz)
+    {
+        status_t status;
+        status = LTC_DES3_EncryptCbc(LTC_BASE,
+                                 in,
+                                 out,
+                                 sz,
+                                 (byte*)des->reg,
+                                 (byte*)des->key[0],
+                                 (byte*)des->key[1],
+                                 (byte*)des->key[2]);
+        if (status == kStatus_Success)
+            return 0;
+        else
+            return -1;
+    }
+
+    int wc_Des3_CbcDecrypt(Des3* des, byte* out, const byte* in, word32 sz)
+    {
+        status_t status;
+        status = LTC_DES3_DecryptCbc(LTC_BASE,
+                                 in,
+                                 out,
+                                 sz,
+                                 (byte*)des->reg,
+                                 (byte*)des->key[0],
+                                 (byte*)des->key[1],
+                                 (byte*)des->key[2]);
+        if (status == kStatus_Success)
+            return 0;
+        else
+            return -1;
+
+    }
+
+#elif defined(FREESCALE_MMCAU)
+    /*
+     * Freescale mmCAU hardware DES/3DES support through the CAU/mmCAU library.
+     * Documentation located in ColdFire/ColdFire+ CAU and Kinetis mmCAU
+     * Software Library User Guide (See note in README).
+     */
+    #ifdef FREESCALE_MMCAU_CLASSIC
+        #include "cau_api.h"
+    #else
+        #include "fsl_mmcau.h"
+    #endif
+
+    const unsigned char parityLookup[128] = {
+        1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1,0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0,
+        0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0,1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1,
+        0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0,1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1,
+        1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1,0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0
+     };
+
+    int wc_Des_SetKey(Des* des, const byte* key, const byte* iv, int dir)
+    {
+        int i = 0;
+        byte* dkey;
+
+
+        if (des == NULL || key == NULL) {
+            return BAD_FUNC_ARG;
+        }
+
+        dkey = (byte*)des->key;
+
+        XMEMCPY(dkey, key, 8);
+
+        wc_Des_SetIV(des, iv);
+
+        /* fix key parity, if needed */
+        for (i = 0; i < 8; i++) {
+            dkey[i] = ((dkey[i] & 0xFE) | parityLookup[dkey[i] >> 1]);
+        }
+
+        return 0;
+    }
+
+    int wc_Des3_SetKey(Des3* des, const byte* key, const byte* iv, int dir)
+    {
+        int i = 0, ret = 0;
+        byte* dkey1 = (byte*)des->key[0];
+        byte* dkey2 = (byte*)des->key[1];
+        byte* dkey3 = (byte*)des->key[2];
+
+        XMEMCPY(dkey1, key, 8);         /* set key 1 */
+        XMEMCPY(dkey2, key + 8, 8);     /* set key 2 */
+        XMEMCPY(dkey3, key + 16, 8);    /* set key 3 */
+
+        ret = wc_Des3_SetIV(des, iv);
+        if (ret != 0)
+            return ret;
+
+        /* fix key parity if needed */
+        for (i = 0; i < 8; i++)
+           dkey1[i] = ((dkey1[i] & 0xFE) | parityLookup[dkey1[i] >> 1]);
+
+        for (i = 0; i < 8; i++)
+           dkey2[i] = ((dkey2[i] & 0xFE) | parityLookup[dkey2[i] >> 1]);
+
+        for (i = 0; i < 8; i++)
+           dkey3[i] = ((dkey3[i] & 0xFE) | parityLookup[dkey3[i] >> 1]);
+
+        return ret;
+    }
+
+    int wc_Des_CbcEncrypt(Des* des, byte* out, const byte* in, word32 sz)
+    {
+        int i;
+        int offset = 0;
+        int len = sz;
+        int ret = 0;
+        byte *iv;
+        byte temp_block[DES_BLOCK_SIZE];
+
+        iv = (byte*)des->reg;
+
+    #ifdef FREESCALE_MMCAU_CLASSIC
+        if ((wolfssl_word)out % WOLFSSL_MMCAU_ALIGNMENT) {
+            WOLFSSL_MSG("Bad cau_des_encrypt alignment");
+            return BAD_ALIGN_E;
+        }
+    #endif
+
+        while (len > 0)
+        {
+            XMEMCPY(temp_block, in + offset, DES_BLOCK_SIZE);
+
+            /* XOR block with IV for CBC */
+            for (i = 0; i < DES_BLOCK_SIZE; i++)
+                temp_block[i] ^= iv[i];
+
+            ret = wolfSSL_CryptHwMutexLock();
+            if(ret != 0) {
+                return ret;
+            }
+        #ifdef FREESCALE_MMCAU_CLASSIC
+            cau_des_encrypt(temp_block, (byte*)des->key, out + offset);
+        #else
+            MMCAU_DES_EncryptEcb(temp_block, (byte*)des->key, out + offset);
+        #endif
+            wolfSSL_CryptHwMutexUnLock();
+
+            len    -= DES_BLOCK_SIZE;
+            offset += DES_BLOCK_SIZE;
+
+            /* store IV for next block */
+            XMEMCPY(iv, out + offset - DES_BLOCK_SIZE, DES_BLOCK_SIZE);
+        }
+
+        return ret;
+    }
+
+    int wc_Des_CbcDecrypt(Des* des, byte* out, const byte* in, word32 sz)
+    {
+        int i;
+        int offset = 0;
+        int len = sz;
+        int ret = 0;
+        byte* iv;
+        byte temp_block[DES_BLOCK_SIZE];
+
+        iv = (byte*)des->reg;
+
+    #ifdef FREESCALE_MMCAU_CLASSIC
+        if ((wolfssl_word)out % WOLFSSL_MMCAU_ALIGNMENT) {
+            WOLFSSL_MSG("Bad cau_des_decrypt alignment");
+            return BAD_ALIGN_E;
+        }
+    #endif
+
+        while (len > 0)
+        {
+            XMEMCPY(temp_block, in + offset, DES_BLOCK_SIZE);
+
+            ret = wolfSSL_CryptHwMutexLock();
+            if(ret != 0) {
+                return ret;
+            }
+
+        #ifdef FREESCALE_MMCAU_CLASSIC
+            cau_des_decrypt(in + offset, (byte*)des->key, out + offset);
+        #else
+            MMCAU_DES_DecryptEcb(in + offset, (byte*)des->key, out + offset);
+        #endif
+            wolfSSL_CryptHwMutexUnLock();
+
+            /* XOR block with IV for CBC */
+            for (i = 0; i < DES_BLOCK_SIZE; i++)
+                (out + offset)[i] ^= iv[i];
+
+            /* store IV for next block */
+            XMEMCPY(iv, temp_block, DES_BLOCK_SIZE);
+
+            len     -= DES_BLOCK_SIZE;
+            offset += DES_BLOCK_SIZE;
+        }
+
+        return ret;
+    }
+
+    int wc_Des3_CbcEncrypt(Des3* des, byte* out, const byte* in, word32 sz)
+    {
+        int i;
+        int offset = 0;
+        int len = sz;
+        int ret = 0;
+
+        byte *iv;
+        byte temp_block[DES_BLOCK_SIZE];
+
+        iv = (byte*)des->reg;
+
+    #ifdef FREESCALE_MMCAU_CLASSIC
+        if ((wolfssl_word)out % WOLFSSL_MMCAU_ALIGNMENT) {
+            WOLFSSL_MSG("Bad 3ede cau_des_encrypt alignment");
+            return BAD_ALIGN_E;
+        }
+    #endif
+
+        while (len > 0)
+        {
+            XMEMCPY(temp_block, in + offset, DES_BLOCK_SIZE);
+
+            /* XOR block with IV for CBC */
+            for (i = 0; i < DES_BLOCK_SIZE; i++)
+                temp_block[i] ^= iv[i];
+
+            ret = wolfSSL_CryptHwMutexLock();
+            if(ret != 0) {
+                return ret;
+            }
+    #ifdef FREESCALE_MMCAU_CLASSIC
+            cau_des_encrypt(temp_block,   (byte*)des->key[0], out + offset);
+            cau_des_decrypt(out + offset, (byte*)des->key[1], out + offset);
+            cau_des_encrypt(out + offset, (byte*)des->key[2], out + offset);
+    #else
+            MMCAU_DES_EncryptEcb(temp_block  , (byte*)des->key[0], out + offset);
+            MMCAU_DES_DecryptEcb(out + offset, (byte*)des->key[1], out + offset);
+            MMCAU_DES_EncryptEcb(out + offset, (byte*)des->key[2], out + offset);
+    #endif
+            wolfSSL_CryptHwMutexUnLock();
+
+            len    -= DES_BLOCK_SIZE;
+            offset += DES_BLOCK_SIZE;
+
+            /* store IV for next block */
+            XMEMCPY(iv, out + offset - DES_BLOCK_SIZE, DES_BLOCK_SIZE);
+        }
+
+        return ret;
+    }
+
+    int wc_Des3_CbcDecrypt(Des3* des, byte* out, const byte* in, word32 sz)
+    {
+        int i;
+        int offset = 0;
+        int len = sz;
+        int ret = 0;
+
+        byte* iv;
+        byte temp_block[DES_BLOCK_SIZE];
+
+        iv = (byte*)des->reg;
+
+    #ifdef FREESCALE_MMCAU_CLASSIC
+        if ((wolfssl_word)out % WOLFSSL_MMCAU_ALIGNMENT) {
+            WOLFSSL_MSG("Bad 3ede cau_des_decrypt alignment");
+            return BAD_ALIGN_E;
+        }
+    #endif
+
+        while (len > 0)
+        {
+            XMEMCPY(temp_block, in + offset, DES_BLOCK_SIZE);
+
+            ret = wolfSSL_CryptHwMutexLock();
+            if(ret != 0) {
+                return ret;
+            }
+        #ifdef FREESCALE_MMCAU_CLASSIC
+            cau_des_decrypt(in + offset,  (byte*)des->key[2], out + offset);
+            cau_des_encrypt(out + offset, (byte*)des->key[1], out + offset);
+            cau_des_decrypt(out + offset, (byte*)des->key[0], out + offset);
+        #else
+            MMCAU_DES_DecryptEcb(in + offset , (byte*)des->key[2], out + offset);
+            MMCAU_DES_EncryptEcb(out + offset, (byte*)des->key[1], out + offset);
+            MMCAU_DES_DecryptEcb(out + offset, (byte*)des->key[0], out + offset);
+        #endif
+            wolfSSL_CryptHwMutexUnLock();
+
+            /* XOR block with IV for CBC */
+            for (i = 0; i < DES_BLOCK_SIZE; i++)
+                (out + offset)[i] ^= iv[i];
+
+            /* store IV for next block */
+            XMEMCPY(iv, temp_block, DES_BLOCK_SIZE);
+
+            len    -= DES_BLOCK_SIZE;
+            offset += DES_BLOCK_SIZE;
+        }
+
+        return ret;
+    }
+
+
+#elif defined(WOLFSSL_PIC32MZ_CRYPT)
+
+    /* PIC32MZ DES hardware requires size multiple of block size */
+    #include <wolfssl/wolfcrypt/port/pic32/pic32mz-crypt.h>
+
+    int wc_Des_SetKey(Des* des, const byte* key, const byte* iv, int dir)
+    {
+        if (des == NULL || key == NULL || iv == NULL)
+            return BAD_FUNC_ARG;
+
+        XMEMCPY(des->key, key, DES_KEYLEN);
+        XMEMCPY(des->reg, iv, DES_IVLEN);
+
+        return 0;
+    }
+
+    int wc_Des3_SetKey(Des3* des, const byte* key, const byte* iv, int dir)
+    {
+        if (des == NULL || key == NULL || iv == NULL)
+            return BAD_FUNC_ARG;
+
+        XMEMCPY(des->key[0], key, DES3_KEYLEN);
+        XMEMCPY(des->reg, iv, DES3_IVLEN);
+
+        return 0;
+    }
+
+    int wc_Des_CbcEncrypt(Des* des, byte* out, const byte* in, word32 sz)
+    {
+        word32 blocks = sz / DES_BLOCK_SIZE;
+
+        if (des == NULL || out == NULL || in == NULL)
+            return BAD_FUNC_ARG;
+
+        return wc_Pic32DesCrypt(des->key, DES_KEYLEN, des->reg, DES_IVLEN,
+            out, in, (blocks * DES_BLOCK_SIZE),
+            PIC32_ENCRYPTION, PIC32_ALGO_DES, PIC32_CRYPTOALGO_CBC);
+    }
+
+    int wc_Des_CbcDecrypt(Des* des, byte* out, const byte* in, word32 sz)
+    {
+        word32 blocks = sz / DES_BLOCK_SIZE;
+
+        if (des == NULL || out == NULL || in == NULL)
+            return BAD_FUNC_ARG;
+
+        return wc_Pic32DesCrypt(des->key, DES_KEYLEN, des->reg, DES_IVLEN,
+            out, in, (blocks * DES_BLOCK_SIZE),
+            PIC32_DECRYPTION, PIC32_ALGO_DES, PIC32_CRYPTOALGO_CBC);
+    }
+
+    int wc_Des3_CbcEncrypt(Des3* des, byte* out, const byte* in, word32 sz)
+    {
+        word32 blocks = sz / DES_BLOCK_SIZE;
+
+        if (des == NULL || out == NULL || in == NULL)
+            return BAD_FUNC_ARG;
+
+        return wc_Pic32DesCrypt(des->key[0], DES3_KEYLEN, des->reg, DES3_IVLEN,
+            out, in, (blocks * DES_BLOCK_SIZE),
+            PIC32_ENCRYPTION, PIC32_ALGO_TDES, PIC32_CRYPTOALGO_TCBC);
+    }
+
+    int wc_Des3_CbcDecrypt(Des3* des, byte* out, const byte* in, word32 sz)
+    {
+        word32 blocks = sz / DES_BLOCK_SIZE;
+
+        if (des == NULL || out == NULL || in == NULL)
+            return BAD_FUNC_ARG;
+
+        return wc_Pic32DesCrypt(des->key[0], DES3_KEYLEN, des->reg, DES3_IVLEN,
+            out, in, (blocks * DES_BLOCK_SIZE),
+            PIC32_DECRYPTION, PIC32_ALGO_TDES, PIC32_CRYPTOALGO_TCBC);
+    }
+
+    #ifdef WOLFSSL_DES_ECB
+        int wc_Des_EcbEncrypt(Des* des, byte* out, const byte* in, word32 sz)
+        {
+            word32 blocks = sz / DES_BLOCK_SIZE;
+
+            if (des == NULL || out == NULL || in == NULL)
+                return BAD_FUNC_ARG;
+
+            return wc_Pic32DesCrypt(des->key, DES_KEYLEN, des->reg, DES_IVLEN,
+                out, in, (blocks * DES_BLOCK_SIZE),
+                    PIC32_ENCRYPTION, PIC32_ALGO_DES, PIC32_CRYPTOALGO_ECB);
+        }
+
+        int wc_Des3_EcbEncrypt(Des3* des, byte* out, const byte* in, word32 sz)
+        {
+            word32 blocks = sz / DES_BLOCK_SIZE;
+
+            if (des == NULL || out == NULL || in == NULL)
+                return BAD_FUNC_ARG;
+
+            return wc_Pic32DesCrypt(des->key[0], DES3_KEYLEN, des->reg, DES3_IVLEN,
+                out, in, (blocks * DES_BLOCK_SIZE),
+                PIC32_ENCRYPTION, PIC32_ALGO_TDES, PIC32_CRYPTOALGO_TECB);
+        }
+    #endif /* WOLFSSL_DES_ECB */
+
+#else
+    #define NEED_SOFT_DES
+
+#endif
+
+
+#ifdef NEED_SOFT_DES
+
+    /* permuted choice table (key) */
+    static const byte pc1[] = {
+           57, 49, 41, 33, 25, 17,  9,
+            1, 58, 50, 42, 34, 26, 18,
+           10,  2, 59, 51, 43, 35, 27,
+           19, 11,  3, 60, 52, 44, 36,
+
+           63, 55, 47, 39, 31, 23, 15,
+            7, 62, 54, 46, 38, 30, 22,
+           14,  6, 61, 53, 45, 37, 29,
+           21, 13,  5, 28, 20, 12,  4
+    };
+
+    /* number left rotations of pc1 */
+    static const byte totrot[] = {
+           1,2,4,6,8,10,12,14,15,17,19,21,23,25,27,28
+    };
+
+    /* permuted choice key (table) */
+    static const byte pc2[] = {
+           14, 17, 11, 24,  1,  5,
+            3, 28, 15,  6, 21, 10,
+           23, 19, 12,  4, 26,  8,
+           16,  7, 27, 20, 13,  2,
+           41, 52, 31, 37, 47, 55,
+           30, 40, 51, 45, 33, 48,
+           44, 49, 39, 56, 34, 53,
+           46, 42, 50, 36, 29, 32
+    };
+
+    /* End of DES-defined tables */
+
+    /* bit 0 is left-most in byte */
+    static const int bytebit[] = {
+        0200,0100,040,020,010,04,02,01
+    };
+
+    static const word32 Spbox[8][64] = {
+    {   0x01010400,0x00000000,0x00010000,0x01010404,
+        0x01010004,0x00010404,0x00000004,0x00010000,
+        0x00000400,0x01010400,0x01010404,0x00000400,
+        0x01000404,0x01010004,0x01000000,0x00000004,
+        0x00000404,0x01000400,0x01000400,0x00010400,
+        0x00010400,0x01010000,0x01010000,0x01000404,
+        0x00010004,0x01000004,0x01000004,0x00010004,
+        0x00000000,0x00000404,0x00010404,0x01000000,
+        0x00010000,0x01010404,0x00000004,0x01010000,
+        0x01010400,0x01000000,0x01000000,0x00000400,
+        0x01010004,0x00010000,0x00010400,0x01000004,
+        0x00000400,0x00000004,0x01000404,0x00010404,
+        0x01010404,0x00010004,0x01010000,0x01000404,
+        0x01000004,0x00000404,0x00010404,0x01010400,
+        0x00000404,0x01000400,0x01000400,0x00000000,
+        0x00010004,0x00010400,0x00000000,0x01010004},
+    {   0x80108020,0x80008000,0x00008000,0x00108020,
+        0x00100000,0x00000020,0x80100020,0x80008020,
+        0x80000020,0x80108020,0x80108000,0x80000000,
+        0x80008000,0x00100000,0x00000020,0x80100020,
+        0x00108000,0x00100020,0x80008020,0x00000000,
+        0x80000000,0x00008000,0x00108020,0x80100000,
+        0x00100020,0x80000020,0x00000000,0x00108000,
+        0x00008020,0x80108000,0x80100000,0x00008020,
+        0x00000000,0x00108020,0x80100020,0x00100000,
+        0x80008020,0x80100000,0x80108000,0x00008000,
+        0x80100000,0x80008000,0x00000020,0x80108020,
+        0x00108020,0x00000020,0x00008000,0x80000000,
+        0x00008020,0x80108000,0x00100000,0x80000020,
+        0x00100020,0x80008020,0x80000020,0x00100020,
+        0x00108000,0x00000000,0x80008000,0x00008020,
+        0x80000000,0x80100020,0x80108020,0x00108000},
+    {   0x00000208,0x08020200,0x00000000,0x08020008,
+        0x08000200,0x00000000,0x00020208,0x08000200,
+        0x00020008,0x08000008,0x08000008,0x00020000,
+        0x08020208,0x00020008,0x08020000,0x00000208,
+        0x08000000,0x00000008,0x08020200,0x00000200,
+        0x00020200,0x08020000,0x08020008,0x00020208,
+        0x08000208,0x00020200,0x00020000,0x08000208,
+        0x00000008,0x08020208,0x00000200,0x08000000,
+        0x08020200,0x08000000,0x00020008,0x00000208,
+        0x00020000,0x08020200,0x08000200,0x00000000,
+        0x00000200,0x00020008,0x08020208,0x08000200,
+        0x08000008,0x00000200,0x00000000,0x08020008,
+        0x08000208,0x00020000,0x08000000,0x08020208,
+        0x00000008,0x00020208,0x00020200,0x08000008,
+        0x08020000,0x08000208,0x00000208,0x08020000,
+        0x00020208,0x00000008,0x08020008,0x00020200},
+    {   0x00802001,0x00002081,0x00002081,0x00000080,
+        0x00802080,0x00800081,0x00800001,0x00002001,
+        0x00000000,0x00802000,0x00802000,0x00802081,
+        0x00000081,0x00000000,0x00800080,0x00800001,
+        0x00000001,0x00002000,0x00800000,0x00802001,
+        0x00000080,0x00800000,0x00002001,0x00002080,
+        0x00800081,0x00000001,0x00002080,0x00800080,
+        0x00002000,0x00802080,0x00802081,0x00000081,
+        0x00800080,0x00800001,0x00802000,0x00802081,
+        0x00000081,0x00000000,0x00000000,0x00802000,
+        0x00002080,0x00800080,0x00800081,0x00000001,
+        0x00802001,0x00002081,0x00002081,0x00000080,
+        0x00802081,0x00000081,0x00000001,0x00002000,
+        0x00800001,0x00002001,0x00802080,0x00800081,
+        0x00002001,0x00002080,0x00800000,0x00802001,
+        0x00000080,0x00800000,0x00002000,0x00802080},
+    {   0x00000100,0x02080100,0x02080000,0x42000100,
+        0x00080000,0x00000100,0x40000000,0x02080000,
+        0x40080100,0x00080000,0x02000100,0x40080100,
+        0x42000100,0x42080000,0x00080100,0x40000000,
+        0x02000000,0x40080000,0x40080000,0x00000000,
+        0x40000100,0x42080100,0x42080100,0x02000100,
+        0x42080000,0x40000100,0x00000000,0x42000000,
+        0x02080100,0x02000000,0x42000000,0x00080100,
+        0x00080000,0x42000100,0x00000100,0x02000000,
+        0x40000000,0x02080000,0x42000100,0x40080100,
+        0x02000100,0x40000000,0x42080000,0x02080100,
+        0x40080100,0x00000100,0x02000000,0x42080000,
+        0x42080100,0x00080100,0x42000000,0x42080100,
+        0x02080000,0x00000000,0x40080000,0x42000000,
+        0x00080100,0x02000100,0x40000100,0x00080000,
+        0x00000000,0x40080000,0x02080100,0x40000100},
+    {   0x20000010,0x20400000,0x00004000,0x20404010,
+        0x20400000,0x00000010,0x20404010,0x00400000,
+        0x20004000,0x00404010,0x00400000,0x20000010,
+        0x00400010,0x20004000,0x20000000,0x00004010,
+        0x00000000,0x00400010,0x20004010,0x00004000,
+        0x00404000,0x20004010,0x00000010,0x20400010,
+        0x20400010,0x00000000,0x00404010,0x20404000,
+        0x00004010,0x00404000,0x20404000,0x20000000,
+        0x20004000,0x00000010,0x20400010,0x00404000,
+        0x20404010,0x00400000,0x00004010,0x20000010,
+        0x00400000,0x20004000,0x20000000,0x00004010,
+        0x20000010,0x20404010,0x00404000,0x20400000,
+        0x00404010,0x20404000,0x00000000,0x20400010,
+        0x00000010,0x00004000,0x20400000,0x00404010,
+        0x00004000,0x00400010,0x20004010,0x00000000,
+        0x20404000,0x20000000,0x00400010,0x20004010},
+    {   0x00200000,0x04200002,0x04000802,0x00000000,
+        0x00000800,0x04000802,0x00200802,0x04200800,
+        0x04200802,0x00200000,0x00000000,0x04000002,
+        0x00000002,0x04000000,0x04200002,0x00000802,
+        0x04000800,0x00200802,0x00200002,0x04000800,
+        0x04000002,0x04200000,0x04200800,0x00200002,
+        0x04200000,0x00000800,0x00000802,0x04200802,
+        0x00200800,0x00000002,0x04000000,0x00200800,
+        0x04000000,0x00200800,0x00200000,0x04000802,
+        0x04000802,0x04200002,0x04200002,0x00000002,
+        0x00200002,0x04000000,0x04000800,0x00200000,
+        0x04200800,0x00000802,0x00200802,0x04200800,
+        0x00000802,0x04000002,0x04200802,0x04200000,
+        0x00200800,0x00000000,0x00000002,0x04200802,
+        0x00000000,0x00200802,0x04200000,0x00000800,
+        0x04000002,0x04000800,0x00000800,0x00200002},
+    {   0x10001040,0x00001000,0x00040000,0x10041040,
+        0x10000000,0x10001040,0x00000040,0x10000000,
+        0x00040040,0x10040000,0x10041040,0x00041000,
+        0x10041000,0x00041040,0x00001000,0x00000040,
+        0x10040000,0x10000040,0x10001000,0x00001040,
+        0x00041000,0x00040040,0x10040040,0x10041000,
+        0x00001040,0x00000000,0x00000000,0x10040040,
+        0x10000040,0x10001000,0x00041040,0x00040000,
+        0x00041040,0x00040000,0x10041000,0x00001000,
+        0x00000040,0x10040040,0x00001000,0x00041040,
+        0x10001000,0x00000040,0x10000040,0x10040000,
+        0x10040040,0x10000000,0x00040000,0x10001040,
+        0x00000000,0x10041040,0x00040040,0x10000040,
+        0x10040000,0x10001000,0x10001040,0x00000000,
+        0x10041040,0x00041000,0x00041000,0x00001040,
+        0x00001040,0x00040040,0x10000000,0x10041000}
+    };
+
+    static WC_INLINE void IPERM(word32* left, word32* right)
+    {
+        word32 work;
+
+        *right = rotlFixed(*right, 4U);
+        work = (*left ^ *right) & 0xf0f0f0f0;
+        *left ^= work;
+
+        *right = rotrFixed(*right^work, 20U);
+        work = (*left ^ *right) & 0xffff0000;
+        *left ^= work;
+
+        *right = rotrFixed(*right^work, 18U);
+        work = (*left ^ *right) & 0x33333333;
+        *left ^= work;
+
+        *right = rotrFixed(*right^work, 6U);
+        work = (*left ^ *right) & 0x00ff00ff;
+        *left ^= work;
+
+        *right = rotlFixed(*right^work, 9U);
+        work = (*left ^ *right) & 0xaaaaaaaa;
+        *left = rotlFixed(*left^work, 1U);
+        *right ^= work;
+    }
+
+    static WC_INLINE void FPERM(word32* left, word32* right)
+    {
+        word32 work;
+
+        *right = rotrFixed(*right, 1U);
+        work = (*left ^ *right) & 0xaaaaaaaa;
+        *right ^= work;
+
+        *left = rotrFixed(*left^work, 9U);
+        work = (*left ^ *right) & 0x00ff00ff;
+        *right ^= work;
+
+        *left = rotlFixed(*left^work, 6U);
+        work = (*left ^ *right) & 0x33333333;
+        *right ^= work;
+
+        *left = rotlFixed(*left^work, 18U);
+        work = (*left ^ *right) & 0xffff0000;
+        *right ^= work;
+
+        *left = rotlFixed(*left^work, 20U);
+        work = (*left ^ *right) & 0xf0f0f0f0;
+        *right ^= work;
+
+        *left = rotrFixed(*left^work, 4U);
+    }
+
+    static int DesSetKey(const byte* key, int dir, word32* out)
+    {
+        #define DES_KEY_BUFFER_SIZE (56+56+8)
+    #ifdef WOLFSSL_SMALL_STACK
+        byte* buffer = (byte*)XMALLOC(DES_KEY_BUFFER_SIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+
+        if (buffer == NULL)
+            return MEMORY_E;
+    #else
+        byte buffer[DES_KEY_BUFFER_SIZE];
+    #endif
+
+        {
+            byte* const  pc1m = buffer;            /* place to modify pc1 into */
+            byte* const  pcr  = pc1m + 56;         /* place to rotate pc1 into */
+            byte* const  ks   = pcr  + 56;
+            register int i, j, l;
+            int          m;
+
+            for (j = 0; j < 56; j++) {             /* convert pc1 to bits of key  */
+                l = pc1[j] - 1;                    /* integer bit location        */
+                m = l & 07;                        /* find bit                    */
+                pc1m[j] = (key[l >> 3] &           /* find which key byte l is in */
+                    bytebit[m])                    /* and which bit of that byte  */
+                    ? 1 : 0;                       /* and store 1-bit result      */
+            }
+
+            for (i = 0; i < 16; i++) {            /* key chunk for each iteration */
+                XMEMSET(ks, 0, 8);                /* Clear key schedule */
+
+                for (j = 0; j < 56; j++)          /* rotate pc1 the right amount  */
+                    pcr[j] =
+                          pc1m[(l = j + totrot[i]) < (j < 28 ? 28 : 56) ? l : l-28];
+
+                /* rotate left and right halves independently */
+                for (j = 0; j < 48; j++) {        /* select bits individually     */
+                    if (pcr[pc2[j] - 1]) {        /* check bit that goes to ks[j] */
+                        l= j % 6;                 /* mask it in if it's there     */
+                        ks[j/6] |= bytebit[l] >> 2;
+                    }
+                }
+
+                /* Now convert to odd/even interleaved form for use in F */
+                out[2*i] = ((word32) ks[0] << 24)
+                         | ((word32) ks[2] << 16)
+                         | ((word32) ks[4] << 8)
+                         | ((word32) ks[6]);
+
+                out[2*i + 1] = ((word32) ks[1] << 24)
+                             | ((word32) ks[3] << 16)
+                             | ((word32) ks[5] << 8)
+                             | ((word32) ks[7]);
+            }
+
+            /* reverse key schedule order */
+            if (dir == DES_DECRYPTION) {
+                for (i = 0; i < 16; i += 2) {
+                    word32 swap = out[i];
+                    out[i] = out[DES_KS_SIZE - 2 - i];
+                    out[DES_KS_SIZE - 2 - i] = swap;
+
+                    swap = out[i + 1];
+                    out[i + 1] = out[DES_KS_SIZE - 1 - i];
+                    out[DES_KS_SIZE - 1 - i] = swap;
+                }
+            }
+
+    #ifdef WOLFSSL_SMALL_STACK
+            XFREE(buffer, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    #endif
+        }
+
+        return 0;
+    }
+
+    int wc_Des_SetKey(Des* des, const byte* key, const byte* iv, int dir)
+    {
+        wc_Des_SetIV(des, iv);
+
+        return DesSetKey(key, dir, des->key);
+    }
+
+    int wc_Des3_SetKey(Des3* des, const byte* key, const byte* iv, int dir)
+    {
+        int ret;
+
+        if (des == NULL || key == NULL || dir < 0) {
+            return BAD_FUNC_ARG;
+        }
+
+    #if defined(WOLF_CRYPTO_CB) || \
+        (defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_3DES))
+        #ifdef WOLF_CRYPTO_CB
+        if (des->devId != INVALID_DEVID)
+        #endif
+        {
+            XMEMCPY(des->devKey, key, DES3_KEYLEN);
+        }
+    #endif
+
+        ret = DesSetKey(key + (dir == DES_ENCRYPTION ? 0:16), dir, des->key[0]);
+        if (ret != 0)
+            return ret;
+
+        ret = DesSetKey(key + 8, !dir, des->key[1]);
+        if (ret != 0)
+            return ret;
+
+        ret = DesSetKey(key + (dir == DES_DECRYPTION ? 0:16), dir, des->key[2]);
+        if (ret != 0)
+            return ret;
+
+        return wc_Des3_SetIV(des, iv);
+    }
+
+    static void DesRawProcessBlock(word32* lIn, word32* rIn, const word32* kptr)
+    {
+        word32 l = *lIn, r = *rIn, i;
+
+        for (i=0; i<8; i++)
+        {
+            word32 work = rotrFixed(r, 4U) ^ kptr[4*i+0];
+            l ^= Spbox[6][(work) & 0x3f]
+              ^  Spbox[4][(work >> 8) & 0x3f]
+              ^  Spbox[2][(work >> 16) & 0x3f]
+              ^  Spbox[0][(work >> 24) & 0x3f];
+            work = r ^ kptr[4*i+1];
+            l ^= Spbox[7][(work) & 0x3f]
+              ^  Spbox[5][(work >> 8) & 0x3f]
+              ^  Spbox[3][(work >> 16) & 0x3f]
+              ^  Spbox[1][(work >> 24) & 0x3f];
+
+            work = rotrFixed(l, 4U) ^ kptr[4*i+2];
+            r ^= Spbox[6][(work) & 0x3f]
+              ^  Spbox[4][(work >> 8) & 0x3f]
+              ^  Spbox[2][(work >> 16) & 0x3f]
+              ^  Spbox[0][(work >> 24) & 0x3f];
+            work = l ^ kptr[4*i+3];
+            r ^= Spbox[7][(work) & 0x3f]
+              ^  Spbox[5][(work >> 8) & 0x3f]
+              ^  Spbox[3][(work >> 16) & 0x3f]
+              ^  Spbox[1][(work >> 24) & 0x3f];
+        }
+
+        *lIn = l; *rIn = r;
+    }
+
+    static void DesProcessBlock(Des* des, const byte* in, byte* out)
+    {
+        word32 l, r;
+
+        XMEMCPY(&l, in, sizeof(l));
+        XMEMCPY(&r, in + sizeof(l), sizeof(r));
+        #ifdef LITTLE_ENDIAN_ORDER
+            l = ByteReverseWord32(l);
+            r = ByteReverseWord32(r);
+        #endif
+        IPERM(&l,&r);
+
+        DesRawProcessBlock(&l, &r, des->key);
+
+        FPERM(&l,&r);
+        #ifdef LITTLE_ENDIAN_ORDER
+            l = ByteReverseWord32(l);
+            r = ByteReverseWord32(r);
+        #endif
+        XMEMCPY(out, &r, sizeof(r));
+        XMEMCPY(out + sizeof(r), &l, sizeof(l));
+    }
+
+    static void Des3ProcessBlock(Des3* des, const byte* in, byte* out)
+    {
+        word32 l, r;
+
+        XMEMCPY(&l, in, sizeof(l));
+        XMEMCPY(&r, in + sizeof(l), sizeof(r));
+        #ifdef LITTLE_ENDIAN_ORDER
+            l = ByteReverseWord32(l);
+            r = ByteReverseWord32(r);
+        #endif
+        IPERM(&l,&r);
+
+        DesRawProcessBlock(&l, &r, des->key[0]);
+        DesRawProcessBlock(&r, &l, des->key[1]);
+        DesRawProcessBlock(&l, &r, des->key[2]);
+
+        FPERM(&l,&r);
+        #ifdef LITTLE_ENDIAN_ORDER
+            l = ByteReverseWord32(l);
+            r = ByteReverseWord32(r);
+        #endif
+        XMEMCPY(out, &r, sizeof(r));
+        XMEMCPY(out + sizeof(r), &l, sizeof(l));
+    }
+
+    int wc_Des_CbcEncrypt(Des* des, byte* out, const byte* in, word32 sz)
+    {
+        word32 blocks = sz / DES_BLOCK_SIZE;
+
+        while (blocks--) {
+            xorbuf((byte*)des->reg, in, DES_BLOCK_SIZE);
+            DesProcessBlock(des, (byte*)des->reg, (byte*)des->reg);
+            XMEMCPY(out, des->reg, DES_BLOCK_SIZE);
+
+            out += DES_BLOCK_SIZE;
+            in  += DES_BLOCK_SIZE;
+        }
+        return 0;
+    }
+
+    int wc_Des_CbcDecrypt(Des* des, byte* out, const byte* in, word32 sz)
+    {
+        word32 blocks = sz / DES_BLOCK_SIZE;
+
+        while (blocks--) {
+            XMEMCPY(des->tmp, in, DES_BLOCK_SIZE);
+            DesProcessBlock(des, (byte*)des->tmp, out);
+            xorbuf(out, (byte*)des->reg, DES_BLOCK_SIZE);
+            XMEMCPY(des->reg, des->tmp, DES_BLOCK_SIZE);
+
+            out += DES_BLOCK_SIZE;
+            in  += DES_BLOCK_SIZE;
+        }
+        return 0;
+    }
+
+    int wc_Des3_CbcEncrypt(Des3* des, byte* out, const byte* in, word32 sz)
+    {
+        word32 blocks;
+
+        if (des == NULL || out == NULL || in == NULL) {
+            return BAD_FUNC_ARG;
+        }
+
+    #ifdef WOLF_CRYPTO_CB
+        if (des->devId != INVALID_DEVID) {
+            int ret = wc_CryptoCb_Des3Encrypt(des, out, in, sz);
+            if (ret != CRYPTOCB_UNAVAILABLE)
+                return ret;
+            /* fall-through when unavailable */
+        }
+    #endif
+
+    #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_3DES)
+        if (des->asyncDev.marker == WOLFSSL_ASYNC_MARKER_3DES &&
+                                            sz >= WC_ASYNC_THRESH_DES3_CBC) {
+        #if defined(HAVE_CAVIUM)
+            return NitroxDes3CbcEncrypt(des, out, in, sz);
+        #elif defined(HAVE_INTEL_QA)
+            return IntelQaSymDes3CbcEncrypt(&des->asyncDev, out, in, sz,
+                (const byte*)des->devKey, DES3_KEYLEN, (byte*)des->reg, DES3_IVLEN);
+        #else /* WOLFSSL_ASYNC_CRYPT_TEST */
+            if (wc_AsyncTestInit(&des->asyncDev, ASYNC_TEST_DES3_CBC_ENCRYPT)) {
+                WC_ASYNC_TEST* testDev = &des->asyncDev.test;
+                testDev->des.des = des;
+                testDev->des.out = out;
+                testDev->des.in = in;
+                testDev->des.sz = sz;
+                return WC_PENDING_E;
+            }
+        #endif
+        }
+    #endif /* WOLFSSL_ASYNC_CRYPT */
+
+        blocks = sz / DES_BLOCK_SIZE;
+        while (blocks--) {
+            xorbuf((byte*)des->reg, in, DES_BLOCK_SIZE);
+            Des3ProcessBlock(des, (byte*)des->reg, (byte*)des->reg);
+            XMEMCPY(out, des->reg, DES_BLOCK_SIZE);
+
+            out += DES_BLOCK_SIZE;
+            in  += DES_BLOCK_SIZE;
+        }
+        return 0;
+    }
+
+
+    int wc_Des3_CbcDecrypt(Des3* des, byte* out, const byte* in, word32 sz)
+    {
+        word32 blocks;
+
+        if (des == NULL || out == NULL || in == NULL) {
+            return BAD_FUNC_ARG;
+        }
+
+    #ifdef WOLF_CRYPTO_CB
+        if (des->devId != INVALID_DEVID) {
+            int ret = wc_CryptoCb_Des3Decrypt(des, out, in, sz);
+            if (ret != CRYPTOCB_UNAVAILABLE)
+                return ret;
+            /* fall-through when unavailable */
+        }
+    #endif
+
+    #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_3DES)
+        if (des->asyncDev.marker == WOLFSSL_ASYNC_MARKER_3DES &&
+                                            sz >= WC_ASYNC_THRESH_DES3_CBC) {
+        #if defined(HAVE_CAVIUM)
+            return NitroxDes3CbcDecrypt(des, out, in, sz);
+        #elif defined(HAVE_INTEL_QA)
+            return IntelQaSymDes3CbcDecrypt(&des->asyncDev, out, in, sz,
+                (const byte*)des->devKey, DES3_KEYLEN, (byte*)des->reg, DES3_IVLEN);
+        #else /* WOLFSSL_ASYNC_CRYPT_TEST */
+            if (wc_AsyncTestInit(&des->asyncDev, ASYNC_TEST_DES3_CBC_DECRYPT)) {
+                WC_ASYNC_TEST* testDev = &des->asyncDev.test;
+                testDev->des.des = des;
+                testDev->des.out = out;
+                testDev->des.in = in;
+                testDev->des.sz = sz;
+                return WC_PENDING_E;
+            }
+        #endif
+        }
+    #endif /* WOLFSSL_ASYNC_CRYPT */
+
+        blocks = sz / DES_BLOCK_SIZE;
+        while (blocks--) {
+            XMEMCPY(des->tmp, in, DES_BLOCK_SIZE);
+            Des3ProcessBlock(des, (byte*)des->tmp, out);
+            xorbuf(out, (byte*)des->reg, DES_BLOCK_SIZE);
+            XMEMCPY(des->reg, des->tmp, DES_BLOCK_SIZE);
+
+            out += DES_BLOCK_SIZE;
+            in  += DES_BLOCK_SIZE;
+        }
+        return 0;
+    }
+
+    #ifdef WOLFSSL_DES_ECB
+        /* One block, compatibility only */
+        int wc_Des_EcbEncrypt(Des* des, byte* out, const byte* in, word32 sz)
+        {
+            word32 blocks = sz / DES_BLOCK_SIZE;
+
+            if (des == NULL || out == NULL || in == NULL) {
+                return BAD_FUNC_ARG;
+            }
+
+            while (blocks--) {
+                DesProcessBlock(des, in, out);
+
+                out += DES_BLOCK_SIZE;
+                in  += DES_BLOCK_SIZE;
+            }
+            return 0;
+        }
+
+        int wc_Des3_EcbEncrypt(Des3* des, byte* out, const byte* in, word32 sz)
+        {
+            word32 blocks = sz / DES_BLOCK_SIZE;
+
+            if (des == NULL || out == NULL || in == NULL) {
+                return BAD_FUNC_ARG;
+            }
+
+            while (blocks--) {
+                Des3ProcessBlock(des, in, out);
+
+                out += DES_BLOCK_SIZE;
+                in  += DES_BLOCK_SIZE;
+            }
+            return 0;
+        }
+    #endif /* WOLFSSL_DES_ECB */
+
+#endif /* NEED_SOFT_DES */
+
+
+void wc_Des_SetIV(Des* des, const byte* iv)
+{
+    if (des && iv)
+        XMEMCPY(des->reg, iv, DES_BLOCK_SIZE);
+    else if (des)
+        XMEMSET(des->reg,  0, DES_BLOCK_SIZE);
+}
+
+int wc_Des3_SetIV(Des3* des, const byte* iv)
+{
+    if (des == NULL) {
+        return BAD_FUNC_ARG;
+    }
+    if (des && iv)
+        XMEMCPY(des->reg, iv, DES_BLOCK_SIZE);
+    else if (des)
+        XMEMSET(des->reg,  0, DES_BLOCK_SIZE);
+
+    return 0;
+}
+
+
+/* Initialize Des3 for use with async device */
+int wc_Des3Init(Des3* des3, void* heap, int devId)
+{
+    int ret = 0;
+    if (des3 == NULL)
+        return BAD_FUNC_ARG;
+
+    des3->heap = heap;
+
+#ifdef WOLF_CRYPTO_CB
+    des3->devId = devId;
+    des3->devCtx = NULL;
+#else
+    (void)devId;
+#endif
+
+#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_3DES)
+    ret = wolfAsync_DevCtxInit(&des3->asyncDev, WOLFSSL_ASYNC_MARKER_3DES,
+                                                        des3->heap, devId);
+#endif
+
+    return ret;
+}
+
+/* Free Des3 from use with async device */
+void wc_Des3Free(Des3* des3)
+{
+    if (des3 == NULL)
+        return;
+
+#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_3DES)
+    wolfAsync_DevCtxFree(&des3->asyncDev, WOLFSSL_ASYNC_MARKER_3DES);
+#endif /* WOLFSSL_ASYNC_CRYPT */
+#if defined(WOLF_CRYPTO_CB) || \
+        (defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_3DES))
+    ForceZero(des3->devKey, sizeof(des3->devKey));
+#endif
+}
+
+#endif /* WOLFSSL_TI_CRYPT */
+#endif /* HAVE_FIPS */
+#endif /* NO_DES3 */
Index: azure_iot_hub_f767zi/trunk/wolfssl-4.4.0/wolfcrypt/src/dh.c
===================================================================
--- azure_iot_hub_f767zi/trunk/wolfssl-4.4.0/wolfcrypt/src/dh.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/wolfssl-4.4.0/wolfcrypt/src/dh.c	(revision 457)
@@ -0,0 +1,2491 @@
+/* dh.c
+ *
+ * Copyright (C) 2006-2020 wolfSSL Inc.
+ *
+ * This file is part of wolfSSL.
+ *
+ * wolfSSL is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * wolfSSL is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
+ */
+
+
+#ifdef HAVE_CONFIG_H
+    #include <config.h>
+#endif
+
+#include <wolfssl/wolfcrypt/settings.h>
+
+#ifndef NO_DH
+
+#if defined(HAVE_FIPS) && \
+    defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION >= 2)
+
+    /* set NO_WRAPPERS before headers, use direct internal f()s not wrappers */
+    #define FIPS_NO_WRAPPERS
+
+    #ifdef USE_WINDOWS_API
+        #pragma code_seg(".fipsA$m")
+        #pragma const_seg(".fipsB$m")
+    #endif
+#endif
+
+#include <wolfssl/wolfcrypt/dh.h>
+#include <wolfssl/wolfcrypt/error-crypt.h>
+#include <wolfssl/wolfcrypt/logging.h>
+
+#ifdef WOLFSSL_HAVE_SP_DH
+#include <wolfssl/wolfcrypt/sp.h>
+#endif
+
+#ifdef NO_INLINE
+    #include <wolfssl/wolfcrypt/misc.h>
+#else
+    #define WOLFSSL_MISC_INCLUDED
+    #include <wolfcrypt/src/misc.c>
+#endif
+
+
+/*
+Possible DH enable options:
+ * NO_RSA:              Overall control of DH                 default: on (not defined)
+ * WOLFSSL_OLD_PRIME_CHECK: Disables the new prime number check. It does not
+                        directly effect this file, but it does speed up DH
+                        removing the testing. It is not recommended to
+                        disable the prime checking.           default: off
+
+*/
+
+
+#if !defined(USER_MATH_LIB) && !defined(WOLFSSL_DH_CONST)
+    #include <math.h>
+    #define XPOW(x,y) pow((x),(y))
+    #define XLOG(x)   log((x))
+#else
+    /* user's own math lib */
+#endif
+
+#ifdef HAVE_FFDHE_2048
+static const byte dh_ffdhe2048_p[] = {
+    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+    0xAD, 0xF8, 0x54, 0x58, 0xA2, 0xBB, 0x4A, 0x9A,
+    0xAF, 0xDC, 0x56, 0x20, 0x27, 0x3D, 0x3C, 0xF1,
+    0xD8, 0xB9, 0xC5, 0x83, 0xCE, 0x2D, 0x36, 0x95,
+    0xA9, 0xE1, 0x36, 0x41, 0x14, 0x64, 0x33, 0xFB,
+    0xCC, 0x93, 0x9D, 0xCE, 0x24, 0x9B, 0x3E, 0xF9,
+    0x7D, 0x2F, 0xE3, 0x63, 0x63, 0x0C, 0x75, 0xD8,
+    0xF6, 0x81, 0xB2, 0x02, 0xAE, 0xC4, 0x61, 0x7A,
+    0xD3, 0xDF, 0x1E, 0xD5, 0xD5, 0xFD, 0x65, 0x61,
+    0x24, 0x33, 0xF5, 0x1F, 0x5F, 0x06, 0x6E, 0xD0,
+    0x85, 0x63, 0x65, 0x55, 0x3D, 0xED, 0x1A, 0xF3,
+    0xB5, 0x57, 0x13, 0x5E, 0x7F, 0x57, 0xC9, 0x35,
+    0x98, 0x4F, 0x0C, 0x70, 0xE0, 0xE6, 0x8B, 0x77,
+    0xE2, 0xA6, 0x89, 0xDA, 0xF3, 0xEF, 0xE8, 0x72,
+    0x1D, 0xF1, 0x58, 0xA1, 0x36, 0xAD, 0xE7, 0x35,
+    0x30, 0xAC, 0xCA, 0x4F, 0x48, 0x3A, 0x79, 0x7A,
+    0xBC, 0x0A, 0xB1, 0x82, 0xB3, 0x24, 0xFB, 0x61,
+    0xD1, 0x08, 0xA9, 0x4B, 0xB2, 0xC8, 0xE3, 0xFB,
+    0xB9, 0x6A, 0xDA, 0xB7, 0x60, 0xD7, 0xF4, 0x68,
+    0x1D, 0x4F, 0x42, 0xA3, 0xDE, 0x39, 0x4D, 0xF4,
+    0xAE, 0x56, 0xED, 0xE7, 0x63, 0x72, 0xBB, 0x19,
+    0x0B, 0x07, 0xA7, 0xC8, 0xEE, 0x0A, 0x6D, 0x70,
+    0x9E, 0x02, 0xFC, 0xE1, 0xCD, 0xF7, 0xE2, 0xEC,
+    0xC0, 0x34, 0x04, 0xCD, 0x28, 0x34, 0x2F, 0x61,
+    0x91, 0x72, 0xFE, 0x9C, 0xE9, 0x85, 0x83, 0xFF,
+    0x8E, 0x4F, 0x12, 0x32, 0xEE, 0xF2, 0x81, 0x83,
+    0xC3, 0xFE, 0x3B, 0x1B, 0x4C, 0x6F, 0xAD, 0x73,
+    0x3B, 0xB5, 0xFC, 0xBC, 0x2E, 0xC2, 0x20, 0x05,
+    0xC5, 0x8E, 0xF1, 0x83, 0x7D, 0x16, 0x83, 0xB2,
+    0xC6, 0xF3, 0x4A, 0x26, 0xC1, 0xB2, 0xEF, 0xFA,
+    0x88, 0x6B, 0x42, 0x38, 0x61, 0x28, 0x5C, 0x97,
+    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
+};
+static const byte dh_ffdhe2048_g[] = { 0x02 };
+#ifdef HAVE_FFDHE_Q
+static const byte dh_ffdhe2048_q[] = {
+    0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+    0xD6, 0xFC, 0x2A, 0x2C, 0x51, 0x5D, 0xA5, 0x4D,
+    0x57, 0xEE, 0x2B, 0x10, 0x13, 0x9E, 0x9E, 0x78,
+    0xEC, 0x5C, 0xE2, 0xC1, 0xE7, 0x16, 0x9B, 0x4A,
+    0xD4, 0xF0, 0x9B, 0x20, 0x8A, 0x32, 0x19, 0xFD,
+    0xE6, 0x49, 0xCE, 0xE7, 0x12, 0x4D, 0x9F, 0x7C,
+    0xBE, 0x97, 0xF1, 0xB1, 0xB1, 0x86, 0x3A, 0xEC,
+    0x7B, 0x40, 0xD9, 0x01, 0x57, 0x62, 0x30, 0xBD,
+    0x69, 0xEF, 0x8F, 0x6A, 0xEA, 0xFE, 0xB2, 0xB0,
+    0x92, 0x19, 0xFA, 0x8F, 0xAF, 0x83, 0x37, 0x68,
+    0x42, 0xB1, 0xB2, 0xAA, 0x9E, 0xF6, 0x8D, 0x79,
+    0xDA, 0xAB, 0x89, 0xAF, 0x3F, 0xAB, 0xE4, 0x9A,
+    0xCC, 0x27, 0x86, 0x38, 0x70, 0x73, 0x45, 0xBB,
+    0xF1, 0x53, 0x44, 0xED, 0x79, 0xF7, 0xF4, 0x39,
+    0x0E, 0xF8, 0xAC, 0x50, 0x9B, 0x56, 0xF3, 0x9A,
+    0x98, 0x56, 0x65, 0x27, 0xA4, 0x1D, 0x3C, 0xBD,
+    0x5E, 0x05, 0x58, 0xC1, 0x59, 0x92, 0x7D, 0xB0,
+    0xE8, 0x84, 0x54, 0xA5, 0xD9, 0x64, 0x71, 0xFD,
+    0xDC, 0xB5, 0x6D, 0x5B, 0xB0, 0x6B, 0xFA, 0x34,
+    0x0E, 0xA7, 0xA1, 0x51, 0xEF, 0x1C, 0xA6, 0xFA,
+    0x57, 0x2B, 0x76, 0xF3, 0xB1, 0xB9, 0x5D, 0x8C,
+    0x85, 0x83, 0xD3, 0xE4, 0x77, 0x05, 0x36, 0xB8,
+    0x4F, 0x01, 0x7E, 0x70, 0xE6, 0xFB, 0xF1, 0x76,
+    0x60, 0x1A, 0x02, 0x66, 0x94, 0x1A, 0x17, 0xB0,
+    0xC8, 0xB9, 0x7F, 0x4E, 0x74, 0xC2, 0xC1, 0xFF,
+    0xC7, 0x27, 0x89, 0x19, 0x77, 0x79, 0x40, 0xC1,
+    0xE1, 0xFF, 0x1D, 0x8D, 0xA6, 0x37, 0xD6, 0xB9,
+    0x9D, 0xDA, 0xFE, 0x5E, 0x17, 0x61, 0x10, 0x02,
+    0xE2, 0xC7, 0x78, 0xC1, 0xBE, 0x8B, 0x41, 0xD9,
+    0x63, 0x79, 0xA5, 0x13, 0x60, 0xD9, 0x77, 0xFD,
+    0x44, 0x35, 0xA1, 0x1C, 0x30, 0x94, 0x2E, 0x4B,
+    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
+};
+#endif /* HAVE_FFDHE_Q */
+
+const DhParams* wc_Dh_ffdhe2048_Get(void)
+{
+    static const DhParams ffdhe2048 = {
+        #ifdef HAVE_FFDHE_Q
+            dh_ffdhe2048_q, sizeof(dh_ffdhe2048_q),
+        #endif /* HAVE_FFDHE_Q */
+        dh_ffdhe2048_p, sizeof(dh_ffdhe2048_p),
+        dh_ffdhe2048_g, sizeof(dh_ffdhe2048_g)
+    };
+    return &ffdhe2048;
+}
+#endif
+
+#ifdef HAVE_FFDHE_3072
+static const byte dh_ffdhe3072_p[] = {
+    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+    0xAD, 0xF8, 0x54, 0x58, 0xA2, 0xBB, 0x4A, 0x9A,
+    0xAF, 0xDC, 0x56, 0x20, 0x27, 0x3D, 0x3C, 0xF1,
+    0xD8, 0xB9, 0xC5, 0x83, 0xCE, 0x2D, 0x36, 0x95,
+    0xA9, 0xE1, 0x36, 0x41, 0x14, 0x64, 0x33, 0xFB,
+    0xCC, 0x93, 0x9D, 0xCE, 0x24, 0x9B, 0x3E, 0xF9,
+    0x7D, 0x2F, 0xE3, 0x63, 0x63, 0x0C, 0x75, 0xD8,
+    0xF6, 0x81, 0xB2, 0x02, 0xAE, 0xC4, 0x61, 0x7A,
+    0xD3, 0xDF, 0x1E, 0xD5, 0xD5, 0xFD, 0x65, 0x61,
+    0x24, 0x33, 0xF5, 0x1F, 0x5F, 0x06, 0x6E, 0xD0,
+    0x85, 0x63, 0x65, 0x55, 0x3D, 0xED, 0x1A, 0xF3,
+    0xB5, 0x57, 0x13, 0x5E, 0x7F, 0x57, 0xC9, 0x35,
+    0x98, 0x4F, 0x0C, 0x70, 0xE0, 0xE6, 0x8B, 0x77,
+    0xE2, 0xA6, 0x89, 0xDA, 0xF3, 0xEF, 0xE8, 0x72,
+    0x1D, 0xF1, 0x58, 0xA1, 0x36, 0xAD, 0xE7, 0x35,
+    0x30, 0xAC, 0xCA, 0x4F, 0x48, 0x3A, 0x79, 0x7A,
+    0xBC, 0x0A, 0xB1, 0x82, 0xB3, 0x24, 0xFB, 0x61,
+    0xD1, 0x08, 0xA9, 0x4B, 0xB2, 0xC8, 0xE3, 0xFB,
+    0xB9, 0x6A, 0xDA, 0xB7, 0x60, 0xD7, 0xF4, 0x68,
+    0x1D, 0x4F, 0x42, 0xA3, 0xDE, 0x39, 0x4D, 0xF4,
+    0xAE, 0x56, 0xED, 0xE7, 0x63, 0x72, 0xBB, 0x19,
+    0x0B, 0x07, 0xA7, 0xC8, 0xEE, 0x0A, 0x6D, 0x70,
+    0x9E, 0x02, 0xFC, 0xE1, 0xCD, 0xF7, 0xE2, 0xEC,
+    0xC0, 0x34, 0x04, 0xCD, 0x28, 0x34, 0x2F, 0x61,
+    0x91, 0x72, 0xFE, 0x9C, 0xE9, 0x85, 0x83, 0xFF,
+    0x8E, 0x4F, 0x12, 0x32, 0xEE, 0xF2, 0x81, 0x83,
+    0xC3, 0xFE, 0x3B, 0x1B, 0x4C, 0x6F, 0xAD, 0x73,
+    0x3B, 0xB5, 0xFC, 0xBC, 0x2E, 0xC2, 0x20, 0x05,
+    0xC5, 0x8E, 0xF1, 0x83, 0x7D, 0x16, 0x83, 0xB2,
+    0xC6, 0xF3, 0x4A, 0x26, 0xC1, 0xB2, 0xEF, 0xFA,
+    0x88, 0x6B, 0x42, 0x38, 0x61, 0x1F, 0xCF, 0xDC,
+    0xDE, 0x35, 0x5B, 0x3B, 0x65, 0x19, 0x03, 0x5B,
+    0xBC, 0x34, 0xF4, 0xDE, 0xF9, 0x9C, 0x02, 0x38,
+    0x61, 0xB4, 0x6F, 0xC9, 0xD6, 0xE6, 0xC9, 0x07,
+    0x7A, 0xD9, 0x1D, 0x26, 0x91, 0xF7, 0xF7, 0xEE,
+    0x59, 0x8C, 0xB0, 0xFA, 0xC1, 0x86, 0xD9, 0x1C,
+    0xAE, 0xFE, 0x13, 0x09, 0x85, 0x13, 0x92, 0x70,
+    0xB4, 0x13, 0x0C, 0x93, 0xBC, 0x43, 0x79, 0x44,
+    0xF4, 0xFD, 0x44, 0x52, 0xE2, 0xD7, 0x4D, 0xD3,
+    0x64, 0xF2, 0xE2, 0x1E, 0x71, 0xF5, 0x4B, 0xFF,
+    0x5C, 0xAE, 0x82, 0xAB, 0x9C, 0x9D, 0xF6, 0x9E,
+    0xE8, 0x6D, 0x2B, 0xC5, 0x22, 0x36, 0x3A, 0x0D,
+    0xAB, 0xC5, 0x21, 0x97, 0x9B, 0x0D, 0xEA, 0xDA,
+    0x1D, 0xBF, 0x9A, 0x42, 0xD5, 0xC4, 0x48, 0x4E,
+    0x0A, 0xBC, 0xD0, 0x6B, 0xFA, 0x53, 0xDD, 0xEF,
+    0x3C, 0x1B, 0x20, 0xEE, 0x3F, 0xD5, 0x9D, 0x7C,
+    0x25, 0xE4, 0x1D, 0x2B, 0x66, 0xC6, 0x2E, 0x37,
+    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
+};
+static const byte dh_ffdhe3072_g[] = { 0x02 };
+#ifdef HAVE_FFDHE_Q
+static const byte dh_ffdhe3072_q[] = {
+    0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+    0xD6, 0xFC, 0x2A, 0x2C, 0x51, 0x5D, 0xA5, 0x4D,
+    0x57, 0xEE, 0x2B, 0x10, 0x13, 0x9E, 0x9E, 0x78,
+    0xEC, 0x5C, 0xE2, 0xC1, 0xE7, 0x16, 0x9B, 0x4A,
+    0xD4, 0xF0, 0x9B, 0x20, 0x8A, 0x32, 0x19, 0xFD,
+    0xE6, 0x49, 0xCE, 0xE7, 0x12, 0x4D, 0x9F, 0x7C,
+    0xBE, 0x97, 0xF1, 0xB1, 0xB1, 0x86, 0x3A, 0xEC,
+    0x7B, 0x40, 0xD9, 0x01, 0x57, 0x62, 0x30, 0xBD,
+    0x69, 0xEF, 0x8F, 0x6A, 0xEA, 0xFE, 0xB2, 0xB0,
+    0x92, 0x19, 0xFA, 0x8F, 0xAF, 0x83, 0x37, 0x68,
+    0x42, 0xB1, 0xB2, 0xAA, 0x9E, 0xF6, 0x8D, 0x79,
+    0xDA, 0xAB, 0x89, 0xAF, 0x3F, 0xAB, 0xE4, 0x9A,
+    0xCC, 0x27, 0x86, 0x38, 0x70, 0x73, 0x45, 0xBB,
+    0xF1, 0x53, 0x44, 0xED, 0x79, 0xF7, 0xF4, 0x39,
+    0x0E, 0xF8, 0xAC, 0x50, 0x9B, 0x56, 0xF3, 0x9A,
+    0x98, 0x56, 0x65, 0x27, 0xA4, 0x1D, 0x3C, 0xBD,
+    0x5E, 0x05, 0x58, 0xC1, 0x59, 0x92, 0x7D, 0xB0,
+    0xE8, 0x84, 0x54, 0xA5, 0xD9, 0x64, 0x71, 0xFD,
+    0xDC, 0xB5, 0x6D, 0x5B, 0xB0, 0x6B, 0xFA, 0x34,
+    0x0E, 0xA7, 0xA1, 0x51, 0xEF, 0x1C, 0xA6, 0xFA,
+    0x57, 0x2B, 0x76, 0xF3, 0xB1, 0xB9, 0x5D, 0x8C,
+    0x85, 0x83, 0xD3, 0xE4, 0x77, 0x05, 0x36, 0xB8,
+    0x4F, 0x01, 0x7E, 0x70, 0xE6, 0xFB, 0xF1, 0x76,
+    0x60, 0x1A, 0x02, 0x66, 0x94, 0x1A, 0x17, 0xB0,
+    0xC8, 0xB9, 0x7F, 0x4E, 0x74, 0xC2, 0xC1, 0xFF,
+    0xC7, 0x27, 0x89, 0x19, 0x77, 0x79, 0x40, 0xC1,
+    0xE1, 0xFF, 0x1D, 0x8D, 0xA6, 0x37, 0xD6, 0xB9,
+    0x9D, 0xDA, 0xFE, 0x5E, 0x17, 0x61, 0x10, 0x02,
+    0xE2, 0xC7, 0x78, 0xC1, 0xBE, 0x8B, 0x41, 0xD9,
+    0x63, 0x79, 0xA5, 0x13, 0x60, 0xD9, 0x77, 0xFD,
+    0x44, 0x35, 0xA1, 0x1C, 0x30, 0x8F, 0xE7, 0xEE,
+    0x6F, 0x1A, 0xAD, 0x9D, 0xB2, 0x8C, 0x81, 0xAD,
+    0xDE, 0x1A, 0x7A, 0x6F, 0x7C, 0xCE, 0x01, 0x1C,
+    0x30, 0xDA, 0x37, 0xE4, 0xEB, 0x73, 0x64, 0x83,
+    0xBD, 0x6C, 0x8E, 0x93, 0x48, 0xFB, 0xFB, 0xF7,
+    0x2C, 0xC6, 0x58, 0x7D, 0x60, 0xC3, 0x6C, 0x8E,
+    0x57, 0x7F, 0x09, 0x84, 0xC2, 0x89, 0xC9, 0x38,
+    0x5A, 0x09, 0x86, 0x49, 0xDE, 0x21, 0xBC, 0xA2,
+    0x7A, 0x7E, 0xA2, 0x29, 0x71, 0x6B, 0xA6, 0xE9,
+    0xB2, 0x79, 0x71, 0x0F, 0x38, 0xFA, 0xA5, 0xFF,
+    0xAE, 0x57, 0x41, 0x55, 0xCE, 0x4E, 0xFB, 0x4F,
+    0x74, 0x36, 0x95, 0xE2, 0x91, 0x1B, 0x1D, 0x06,
+    0xD5, 0xE2, 0x90, 0xCB, 0xCD, 0x86, 0xF5, 0x6D,
+    0x0E, 0xDF, 0xCD, 0x21, 0x6A, 0xE2, 0x24, 0x27,
+    0x05, 0x5E, 0x68, 0x35, 0xFD, 0x29, 0xEE, 0xF7,
+    0x9E, 0x0D, 0x90, 0x77, 0x1F, 0xEA, 0xCE, 0xBE,
+    0x12, 0xF2, 0x0E, 0x95, 0xB3, 0x63, 0x17, 0x1B,
+    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
+};
+#endif /* HAVE_FFDHE_Q */
+
+const DhParams* wc_Dh_ffdhe3072_Get(void)
+{
+    static const DhParams ffdhe3072 = {
+        #ifdef HAVE_FFDHE_Q
+            dh_ffdhe3072_q, sizeof(dh_ffdhe3072_q),
+        #endif /* HAVE_FFDHE_Q */
+        dh_ffdhe3072_p, sizeof(dh_ffdhe3072_p),
+        dh_ffdhe3072_g, sizeof(dh_ffdhe3072_g)
+    };
+    return &ffdhe3072;
+}
+#endif
+
+#ifdef HAVE_FFDHE_4096
+static const byte dh_ffdhe4096_p[] = {
+    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+    0xAD, 0xF8, 0x54, 0x58, 0xA2, 0xBB, 0x4A, 0x9A,
+    0xAF, 0xDC, 0x56, 0x20, 0x27, 0x3D, 0x3C, 0xF1,
+    0xD8, 0xB9, 0xC5, 0x83, 0xCE, 0x2D, 0x36, 0x95,
+    0xA9, 0xE1, 0x36, 0x41, 0x14, 0x64, 0x33, 0xFB,
+    0xCC, 0x93, 0x9D, 0xCE, 0x24, 0x9B, 0x3E, 0xF9,
+    0x7D, 0x2F, 0xE3, 0x63, 0x63, 0x0C, 0x75, 0xD8,
+    0xF6, 0x81, 0xB2, 0x02, 0xAE, 0xC4, 0x61, 0x7A,
+    0xD3, 0xDF, 0x1E, 0xD5, 0xD5, 0xFD, 0x65, 0x61,
+    0x24, 0x33, 0xF5, 0x1F, 0x5F, 0x06, 0x6E, 0xD0,
+    0x85, 0x63, 0x65, 0x55, 0x3D, 0xED, 0x1A, 0xF3,
+    0xB5, 0x57, 0x13, 0x5E, 0x7F, 0x57, 0xC9, 0x35,
+    0x98, 0x4F, 0x0C, 0x70, 0xE0, 0xE6, 0x8B, 0x77,
+    0xE2, 0xA6, 0x89, 0xDA, 0xF3, 0xEF, 0xE8, 0x72,
+    0x1D, 0xF1, 0x58, 0xA1, 0x36, 0xAD, 0xE7, 0x35,
+    0x30, 0xAC, 0xCA, 0x4F, 0x48, 0x3A, 0x79, 0x7A,
+    0xBC, 0x0A, 0xB1, 0x82, 0xB3, 0x24, 0xFB, 0x61,
+    0xD1, 0x08, 0xA9, 0x4B, 0xB2, 0xC8, 0xE3, 0xFB,
+    0xB9, 0x6A, 0xDA, 0xB7, 0x60, 0xD7, 0xF4, 0x68,
+    0x1D, 0x4F, 0x42, 0xA3, 0xDE, 0x39, 0x4D, 0xF4,
+    0xAE, 0x56, 0xED, 0xE7, 0x63, 0x72, 0xBB, 0x19,
+    0x0B, 0x07, 0xA7, 0xC8, 0xEE, 0x0A, 0x6D, 0x70,
+    0x9E, 0x02, 0xFC, 0xE1, 0xCD, 0xF7, 0xE2, 0xEC,
+    0xC0, 0x34, 0x04, 0xCD, 0x28, 0x34, 0x2F, 0x61,
+    0x91, 0x72, 0xFE, 0x9C, 0xE9, 0x85, 0x83, 0xFF,
+    0x8E, 0x4F, 0x12, 0x32, 0xEE, 0xF2, 0x81, 0x83,
+    0xC3, 0xFE, 0x3B, 0x1B, 0x4C, 0x6F, 0xAD, 0x73,
+    0x3B, 0xB5, 0xFC, 0xBC, 0x2E, 0xC2, 0x20, 0x05,
+    0xC5, 0x8E, 0xF1, 0x83, 0x7D, 0x16, 0x83, 0xB2,
+    0xC6, 0xF3, 0x4A, 0x26, 0xC1, 0xB2, 0xEF, 0xFA,
+    0x88, 0x6B, 0x42, 0x38, 0x61, 0x1F, 0xCF, 0xDC,
+    0xDE, 0x35, 0x5B, 0x3B, 0x65, 0x19, 0x03, 0x5B,
+    0xBC, 0x34, 0xF4, 0xDE, 0xF9, 0x9C, 0x02, 0x38,
+    0x61, 0xB4, 0x6F, 0xC9, 0xD6, 0xE6, 0xC9, 0x07,
+    0x7A, 0xD9, 0x1D, 0x26, 0x91, 0xF7, 0xF7, 0xEE,
+    0x59, 0x8C, 0xB0, 0xFA, 0xC1, 0x86, 0xD9, 0x1C,
+    0xAE, 0xFE, 0x13, 0x09, 0x85, 0x13, 0x92, 0x70,
+    0xB4, 0x13, 0x0C, 0x93, 0xBC, 0x43, 0x79, 0x44,
+    0xF4, 0xFD, 0x44, 0x52, 0xE2, 0xD7, 0x4D, 0xD3,
+    0x64, 0xF2, 0xE2, 0x1E, 0x71, 0xF5, 0x4B, 0xFF,
+    0x5C, 0xAE, 0x82, 0xAB, 0x9C, 0x9D, 0xF6, 0x9E,
+    0xE8, 0x6D, 0x2B, 0xC5, 0x22, 0x36, 0x3A, 0x0D,
+    0xAB, 0xC5, 0x21, 0x97, 0x9B, 0x0D, 0xEA, 0xDA,
+    0x1D, 0xBF, 0x9A, 0x42, 0xD5, 0xC4, 0x48, 0x4E,
+    0x0A, 0xBC, 0xD0, 0x6B, 0xFA, 0x53, 0xDD, 0xEF,
+    0x3C, 0x1B, 0x20, 0xEE, 0x3F, 0xD5, 0x9D, 0x7C,
+    0x25, 0xE4, 0x1D, 0x2B, 0x66, 0x9E, 0x1E, 0xF1,
+    0x6E, 0x6F, 0x52, 0xC3, 0x16, 0x4D, 0xF4, 0xFB,
+    0x79, 0x30, 0xE9, 0xE4, 0xE5, 0x88, 0x57, 0xB6,
+    0xAC, 0x7D, 0x5F, 0x42, 0xD6, 0x9F, 0x6D, 0x18,
+    0x77, 0x63, 0xCF, 0x1D, 0x55, 0x03, 0x40, 0x04,
+    0x87, 0xF5, 0x5B, 0xA5, 0x7E, 0x31, 0xCC, 0x7A,
+    0x71, 0x35, 0xC8, 0x86, 0xEF, 0xB4, 0x31, 0x8A,
+    0xED, 0x6A, 0x1E, 0x01, 0x2D, 0x9E, 0x68, 0x32,
+    0xA9, 0x07, 0x60, 0x0A, 0x91, 0x81, 0x30, 0xC4,
+    0x6D, 0xC7, 0x78, 0xF9, 0x71, 0xAD, 0x00, 0x38,
+    0x09, 0x29, 0x99, 0xA3, 0x33, 0xCB, 0x8B, 0x7A,
+    0x1A, 0x1D, 0xB9, 0x3D, 0x71, 0x40, 0x00, 0x3C,
+    0x2A, 0x4E, 0xCE, 0xA9, 0xF9, 0x8D, 0x0A, 0xCC,
+    0x0A, 0x82, 0x91, 0xCD, 0xCE, 0xC9, 0x7D, 0xCF,
+    0x8E, 0xC9, 0xB5, 0x5A, 0x7F, 0x88, 0xA4, 0x6B,
+    0x4D, 0xB5, 0xA8, 0x51, 0xF4, 0x41, 0x82, 0xE1,
+    0xC6, 0x8A, 0x00, 0x7E, 0x5E, 0x65, 0x5F, 0x6A,
+    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
+};
+static const byte dh_ffdhe4096_g[] = { 0x02 };
+#ifdef HAVE_FFDHE_Q
+static const byte dh_ffdhe4096_q[] = {
+    0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+    0xD6, 0xFC, 0x2A, 0x2C, 0x51, 0x5D, 0xA5, 0x4D,
+    0x57, 0xEE, 0x2B, 0x10, 0x13, 0x9E, 0x9E, 0x78,
+    0xEC, 0x5C, 0xE2, 0xC1, 0xE7, 0x16, 0x9B, 0x4A,
+    0xD4, 0xF0, 0x9B, 0x20, 0x8A, 0x32, 0x19, 0xFD,
+    0xE6, 0x49, 0xCE, 0xE7, 0x12, 0x4D, 0x9F, 0x7C,
+    0xBE, 0x97, 0xF1, 0xB1, 0xB1, 0x86, 0x3A, 0xEC,
+    0x7B, 0x40, 0xD9, 0x01, 0x57, 0x62, 0x30, 0xBD,
+    0x69, 0xEF, 0x8F, 0x6A, 0xEA, 0xFE, 0xB2, 0xB0,
+    0x92, 0x19, 0xFA, 0x8F, 0xAF, 0x83, 0x37, 0x68,
+    0x42, 0xB1, 0xB2, 0xAA, 0x9E, 0xF6, 0x8D, 0x79,
+    0xDA, 0xAB, 0x89, 0xAF, 0x3F, 0xAB, 0xE4, 0x9A,
+    0xCC, 0x27, 0x86, 0x38, 0x70, 0x73, 0x45, 0xBB,
+    0xF1, 0x53, 0x44, 0xED, 0x79, 0xF7, 0xF4, 0x39,
+    0x0E, 0xF8, 0xAC, 0x50, 0x9B, 0x56, 0xF3, 0x9A,
+    0x98, 0x56, 0x65, 0x27, 0xA4, 0x1D, 0x3C, 0xBD,
+    0x5E, 0x05, 0x58, 0xC1, 0x59, 0x92, 0x7D, 0xB0,
+    0xE8, 0x84, 0x54, 0xA5, 0xD9, 0x64, 0x71, 0xFD,
+    0xDC, 0xB5, 0x6D, 0x5B, 0xB0, 0x6B, 0xFA, 0x34,
+    0x0E, 0xA7, 0xA1, 0x51, 0xEF, 0x1C, 0xA6, 0xFA,
+    0x57, 0x2B, 0x76, 0xF3, 0xB1, 0xB9, 0x5D, 0x8C,
+    0x85, 0x83, 0xD3, 0xE4, 0x77, 0x05, 0x36, 0xB8,
+    0x4F, 0x01, 0x7E, 0x70, 0xE6, 0xFB, 0xF1, 0x76,
+    0x60, 0x1A, 0x02, 0x66, 0x94, 0x1A, 0x17, 0xB0,
+    0xC8, 0xB9, 0x7F, 0x4E, 0x74, 0xC2, 0xC1, 0xFF,
+    0xC7, 0x27, 0x89, 0x19, 0x77, 0x79, 0x40, 0xC1,
+    0xE1, 0xFF, 0x1D, 0x8D, 0xA6, 0x37, 0xD6, 0xB9,
+    0x9D, 0xDA, 0xFE, 0x5E, 0x17, 0x61, 0x10, 0x02,
+    0xE2, 0xC7, 0x78, 0xC1, 0xBE, 0x8B, 0x41, 0xD9,
+    0x63, 0x79, 0xA5, 0x13, 0x60, 0xD9, 0x77, 0xFD,
+    0x44, 0x35, 0xA1, 0x1C, 0x30, 0x8F, 0xE7, 0xEE,
+    0x6F, 0x1A, 0xAD, 0x9D, 0xB2, 0x8C, 0x81, 0xAD,
+    0xDE, 0x1A, 0x7A, 0x6F, 0x7C, 0xCE, 0x01, 0x1C,
+    0x30, 0xDA, 0x37, 0xE4, 0xEB, 0x73, 0x64, 0x83,
+    0xBD, 0x6C, 0x8E, 0x93, 0x48, 0xFB, 0xFB, 0xF7,
+    0x2C, 0xC6, 0x58, 0x7D, 0x60, 0xC3, 0x6C, 0x8E,
+    0x57, 0x7F, 0x09, 0x84, 0xC2, 0x89, 0xC9, 0x38,
+    0x5A, 0x09, 0x86, 0x49, 0xDE, 0x21, 0xBC, 0xA2,
+    0x7A, 0x7E, 0xA2, 0x29, 0x71, 0x6B, 0xA6, 0xE9,
+    0xB2, 0x79, 0x71, 0x0F, 0x38, 0xFA, 0xA5, 0xFF,
+    0xAE, 0x57, 0x41, 0x55, 0xCE, 0x4E, 0xFB, 0x4F,
+    0x74, 0x36, 0x95, 0xE2, 0x91, 0x1B, 0x1D, 0x06,
+    0xD5, 0xE2, 0x90, 0xCB, 0xCD, 0x86, 0xF5, 0x6D,
+    0x0E, 0xDF, 0xCD, 0x21, 0x6A, 0xE2, 0x24, 0x27,
+    0x05, 0x5E, 0x68, 0x35, 0xFD, 0x29, 0xEE, 0xF7,
+    0x9E, 0x0D, 0x90, 0x77, 0x1F, 0xEA, 0xCE, 0xBE,
+    0x12, 0xF2, 0x0E, 0x95, 0xB3, 0x4F, 0x0F, 0x78,
+    0xB7, 0x37, 0xA9, 0x61, 0x8B, 0x26, 0xFA, 0x7D,
+    0xBC, 0x98, 0x74, 0xF2, 0x72, 0xC4, 0x2B, 0xDB,
+    0x56, 0x3E, 0xAF, 0xA1, 0x6B, 0x4F, 0xB6, 0x8C,
+    0x3B, 0xB1, 0xE7, 0x8E, 0xAA, 0x81, 0xA0, 0x02,
+    0x43, 0xFA, 0xAD, 0xD2, 0xBF, 0x18, 0xE6, 0x3D,
+    0x38, 0x9A, 0xE4, 0x43, 0x77, 0xDA, 0x18, 0xC5,
+    0x76, 0xB5, 0x0F, 0x00, 0x96, 0xCF, 0x34, 0x19,
+    0x54, 0x83, 0xB0, 0x05, 0x48, 0xC0, 0x98, 0x62,
+    0x36, 0xE3, 0xBC, 0x7C, 0xB8, 0xD6, 0x80, 0x1C,
+    0x04, 0x94, 0xCC, 0xD1, 0x99, 0xE5, 0xC5, 0xBD,
+    0x0D, 0x0E, 0xDC, 0x9E, 0xB8, 0xA0, 0x00, 0x1E,
+    0x15, 0x27, 0x67, 0x54, 0xFC, 0xC6, 0x85, 0x66,
+    0x05, 0x41, 0x48, 0xE6, 0xE7, 0x64, 0xBE, 0xE7,
+    0xC7, 0x64, 0xDA, 0xAD, 0x3F, 0xC4, 0x52, 0x35,
+    0xA6, 0xDA, 0xD4, 0x28, 0xFA, 0x20, 0xC1, 0x70,
+    0xE3, 0x45, 0x00, 0x3F, 0x2F, 0x32, 0xAF, 0xB5,
+    0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
+};
+#endif /* HAVE_FFDHE_Q */
+
+const DhParams* wc_Dh_ffdhe4096_Get(void)
+{
+    static const DhParams ffdhe4096 = {
+        #ifdef HAVE_FFDHE_Q
+            dh_ffdhe4096_q, sizeof(dh_ffdhe4096_q),
+        #endif /* HAVE_FFDHE_Q */
+        dh_ffdhe4096_p, sizeof(dh_ffdhe4096_p),
+        dh_ffdhe4096_g, sizeof(dh_ffdhe4096_g)
+    };
+    return &ffdhe4096;
+}
+#endif
+
+#ifdef HAVE_FFDHE_6144
+static const byte dh_ffdhe6144_p[] = {
+    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+    0xAD, 0xF8, 0x54, 0x58, 0xA2, 0xBB, 0x4A, 0x9A,
+    0xAF, 0xDC, 0x56, 0x20, 0x27, 0x3D, 0x3C, 0xF1,
+    0xD8, 0xB9, 0xC5, 0x83, 0xCE, 0x2D, 0x36, 0x95,
+    0xA9, 0xE1, 0x36, 0x41, 0x14, 0x64, 0x33, 0xFB,
+    0xCC, 0x93, 0x9D, 0xCE, 0x24, 0x9B, 0x3E, 0xF9,
+    0x7D, 0x2F, 0xE3, 0x63, 0x63, 0x0C, 0x75, 0xD8,
+    0xF6, 0x81, 0xB2, 0x02, 0xAE, 0xC4, 0x61, 0x7A,
+    0xD3, 0xDF, 0x1E, 0xD5, 0xD5, 0xFD, 0x65, 0x61,
+    0x24, 0x33, 0xF5, 0x1F, 0x5F, 0x06, 0x6E, 0xD0,
+    0x85, 0x63, 0x65, 0x55, 0x3D, 0xED, 0x1A, 0xF3,
+    0xB5, 0x57, 0x13, 0x5E, 0x7F, 0x57, 0xC9, 0x35,
+    0x98, 0x4F, 0x0C, 0x70, 0xE0, 0xE6, 0x8B, 0x77,
+    0xE2, 0xA6, 0x89, 0xDA, 0xF3, 0xEF, 0xE8, 0x72,
+    0x1D, 0xF1, 0x58, 0xA1, 0x36, 0xAD, 0xE7, 0x35,
+    0x30, 0xAC, 0xCA, 0x4F, 0x48, 0x3A, 0x79, 0x7A,
+    0xBC, 0x0A, 0xB1, 0x82, 0xB3, 0x24, 0xFB, 0x61,
+    0xD1, 0x08, 0xA9, 0x4B, 0xB2, 0xC8, 0xE3, 0xFB,
+    0xB9, 0x6A, 0xDA, 0xB7, 0x60, 0xD7, 0xF4, 0x68,
+    0x1D, 0x4F, 0x42, 0xA3, 0xDE, 0x39, 0x4D, 0xF4,
+    0xAE, 0x56, 0xED, 0xE7, 0x63, 0x72, 0xBB, 0x19,
+    0x0B, 0x07, 0xA7, 0xC8, 0xEE, 0x0A, 0x6D, 0x70,
+    0x9E, 0x02, 0xFC, 0xE1, 0xCD, 0xF7, 0xE2, 0xEC,
+    0xC0, 0x34, 0x04, 0xCD, 0x28, 0x34, 0x2F, 0x61,
+    0x91, 0x72, 0xFE, 0x9C, 0xE9, 0x85, 0x83, 0xFF,
+    0x8E, 0x4F, 0x12, 0x32, 0xEE, 0xF2, 0x81, 0x83,
+    0xC3, 0xFE, 0x3B, 0x1B, 0x4C, 0x6F, 0xAD, 0x73,
+    0x3B, 0xB5, 0xFC, 0xBC, 0x2E, 0xC2, 0x20, 0x05,
+    0xC5, 0x8E, 0xF1, 0x83, 0x7D, 0x16, 0x83, 0xB2,
+    0xC6, 0xF3, 0x4A, 0x26, 0xC1, 0xB2, 0xEF, 0xFA,
+    0x88, 0x6B, 0x42, 0x38, 0x61, 0x1F, 0xCF, 0xDC,
+    0xDE, 0x35, 0x5B, 0x3B, 0x65, 0x19, 0x03, 0x5B,
+    0xBC, 0x34, 0xF4, 0xDE, 0xF9, 0x9C, 0x02, 0x38,
+    0x61, 0xB4, 0x6F, 0xC9, 0xD6, 0xE6, 0xC9, 0x07,
+    0x7A, 0xD9, 0x1D, 0x26, 0x91, 0xF7, 0xF7, 0xEE,
+    0x59, 0x8C, 0xB0, 0xFA, 0xC1, 0x86, 0xD9, 0x1C,
+    0xAE, 0xFE, 0x13, 0x09, 0x85, 0x13, 0x92, 0x70,
+    0xB4, 0x13, 0x0C, 0x93, 0xBC, 0x43, 0x79, 0x44,
+    0xF4, 0xFD, 0x44, 0x52, 0xE2, 0xD7, 0x4D, 0xD3,
+    0x64, 0xF2, 0xE2, 0x1E, 0x71, 0xF5, 0x4B, 0xFF,
+    0x5C, 0xAE, 0x82, 0xAB, 0x9C, 0x9D, 0xF6, 0x9E,
+    0xE8, 0x6D, 0x2B, 0xC5, 0x22, 0x36, 0x3A, 0x0D,
+    0xAB, 0xC5, 0x21, 0x97, 0x9B, 0x0D, 0xEA, 0xDA,
+    0x1D, 0xBF, 0x9A, 0x42, 0xD5, 0xC4, 0x48, 0x4E,
+    0x0A, 0xBC, 0xD0, 0x6B, 0xFA, 0x53, 0xDD, 0xEF,
+    0x3C, 0x1B, 0x20, 0xEE, 0x3F, 0xD5, 0x9D, 0x7C,
+    0x25, 0xE4, 0x1D, 0x2B, 0x66, 0x9E, 0x1E, 0xF1,
+    0x6E, 0x6F, 0x52, 0xC3, 0x16, 0x4D, 0xF4, 0xFB,
+    0x79, 0x30, 0xE9, 0xE4, 0xE5, 0x88, 0x57, 0xB6,
+    0xAC, 0x7D, 0x5F, 0x42, 0xD6, 0x9F, 0x6D, 0x18,
+    0x77, 0x63, 0xCF, 0x1D, 0x55, 0x03, 0x40, 0x04,
+    0x87, 0xF5, 0x5B, 0xA5, 0x7E, 0x31, 0xCC, 0x7A,
+    0x71, 0x35, 0xC8, 0x86, 0xEF, 0xB4, 0x31, 0x8A,
+    0xED, 0x6A, 0x1E, 0x01, 0x2D, 0x9E, 0x68, 0x32,
+    0xA9, 0x07, 0x60, 0x0A, 0x91, 0x81, 0x30, 0xC4,
+    0x6D, 0xC7, 0x78, 0xF9, 0x71, 0xAD, 0x00, 0x38,
+    0x09, 0x29, 0x99, 0xA3, 0x33, 0xCB, 0x8B, 0x7A,
+    0x1A, 0x1D, 0xB9, 0x3D, 0x71, 0x40, 0x00, 0x3C,
+    0x2A, 0x4E, 0xCE, 0xA9, 0xF9, 0x8D, 0x0A, 0xCC,
+    0x0A, 0x82, 0x91, 0xCD, 0xCE, 0xC9, 0x7D, 0xCF,
+    0x8E, 0xC9, 0xB5, 0x5A, 0x7F, 0x88, 0xA4, 0x6B,
+    0x4D, 0xB5, 0xA8, 0x51, 0xF4, 0x41, 0x82, 0xE1,
+    0xC6, 0x8A, 0x00, 0x7E, 0x5E, 0x0D, 0xD9, 0x02,
+    0x0B, 0xFD, 0x64, 0xB6, 0x45, 0x03, 0x6C, 0x7A,
+    0x4E, 0x67, 0x7D, 0x2C, 0x38, 0x53, 0x2A, 0x3A,
+    0x23, 0xBA, 0x44, 0x42, 0xCA, 0xF5, 0x3E, 0xA6,
+    0x3B, 0xB4, 0x54, 0x32, 0x9B, 0x76, 0x24, 0xC8,
+    0x91, 0x7B, 0xDD, 0x64, 0xB1, 0xC0, 0xFD, 0x4C,
+    0xB3, 0x8E, 0x8C, 0x33, 0x4C, 0x70, 0x1C, 0x3A,
+    0xCD, 0xAD, 0x06, 0x57, 0xFC, 0xCF, 0xEC, 0x71,
+    0x9B, 0x1F, 0x5C, 0x3E, 0x4E, 0x46, 0x04, 0x1F,
+    0x38, 0x81, 0x47, 0xFB, 0x4C, 0xFD, 0xB4, 0x77,
+    0xA5, 0x24, 0x71, 0xF7, 0xA9, 0xA9, 0x69, 0x10,
+    0xB8, 0x55, 0x32, 0x2E, 0xDB, 0x63, 0x40, 0xD8,
+    0xA0, 0x0E, 0xF0, 0x92, 0x35, 0x05, 0x11, 0xE3,
+    0x0A, 0xBE, 0xC1, 0xFF, 0xF9, 0xE3, 0xA2, 0x6E,
+    0x7F, 0xB2, 0x9F, 0x8C, 0x18, 0x30, 0x23, 0xC3,
+    0x58, 0x7E, 0x38, 0xDA, 0x00, 0x77, 0xD9, 0xB4,
+    0x76, 0x3E, 0x4E, 0x4B, 0x94, 0xB2, 0xBB, 0xC1,
+    0x94, 0xC6, 0x65, 0x1E, 0x77, 0xCA, 0xF9, 0x92,
+    0xEE, 0xAA, 0xC0, 0x23, 0x2A, 0x28, 0x1B, 0xF6,
+    0xB3, 0xA7, 0x39, 0xC1, 0x22, 0x61, 0x16, 0x82,
+    0x0A, 0xE8, 0xDB, 0x58, 0x47, 0xA6, 0x7C, 0xBE,
+    0xF9, 0xC9, 0x09, 0x1B, 0x46, 0x2D, 0x53, 0x8C,
+    0xD7, 0x2B, 0x03, 0x74, 0x6A, 0xE7, 0x7F, 0x5E,
+    0x62, 0x29, 0x2C, 0x31, 0x15, 0x62, 0xA8, 0x46,
+    0x50, 0x5D, 0xC8, 0x2D, 0xB8, 0x54, 0x33, 0x8A,
+    0xE4, 0x9F, 0x52, 0x35, 0xC9, 0x5B, 0x91, 0x17,
+    0x8C, 0xCF, 0x2D, 0xD5, 0xCA, 0xCE, 0xF4, 0x03,
+    0xEC, 0x9D, 0x18, 0x10, 0xC6, 0x27, 0x2B, 0x04,
+    0x5B, 0x3B, 0x71, 0xF9, 0xDC, 0x6B, 0x80, 0xD6,
+    0x3F, 0xDD, 0x4A, 0x8E, 0x9A, 0xDB, 0x1E, 0x69,
+    0x62, 0xA6, 0x95, 0x26, 0xD4, 0x31, 0x61, 0xC1,
+    0xA4, 0x1D, 0x57, 0x0D, 0x79, 0x38, 0xDA, 0xD4,
+    0xA4, 0x0E, 0x32, 0x9C, 0xD0, 0xE4, 0x0E, 0x65,
+    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
+};
+static const byte dh_ffdhe6144_g[] = { 0x02 };
+#ifdef HAVE_FFDHE_Q
+static const byte dh_ffdhe6144_q[] = {
+    0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+    0xD6, 0xFC, 0x2A, 0x2C, 0x51, 0x5D, 0xA5, 0x4D,
+    0x57, 0xEE, 0x2B, 0x10, 0x13, 0x9E, 0x9E, 0x78,
+    0xEC, 0x5C, 0xE2, 0xC1, 0xE7, 0x16, 0x9B, 0x4A,
+    0xD4, 0xF0, 0x9B, 0x20, 0x8A, 0x32, 0x19, 0xFD,
+    0xE6, 0x49, 0xCE, 0xE7, 0x12, 0x4D, 0x9F, 0x7C,
+    0xBE, 0x97, 0xF1, 0xB1, 0xB1, 0x86, 0x3A, 0xEC,
+    0x7B, 0x40, 0xD9, 0x01, 0x57, 0x62, 0x30, 0xBD,
+    0x69, 0xEF, 0x8F, 0x6A, 0xEA, 0xFE, 0xB2, 0xB0,
+    0x92, 0x19, 0xFA, 0x8F, 0xAF, 0x83, 0x37, 0x68,
+    0x42, 0xB1, 0xB2, 0xAA, 0x9E, 0xF6, 0x8D, 0x79,
+    0xDA, 0xAB, 0x89, 0xAF, 0x3F, 0xAB, 0xE4, 0x9A,
+    0xCC, 0x27, 0x86, 0x38, 0x70, 0x73, 0x45, 0xBB,
+    0xF1, 0x53, 0x44, 0xED, 0x79, 0xF7, 0xF4, 0x39,
+    0x0E, 0xF8, 0xAC, 0x50, 0x9B, 0x56, 0xF3, 0x9A,
+    0x98, 0x56, 0x65, 0x27, 0xA4, 0x1D, 0x3C, 0xBD,
+    0x5E, 0x05, 0x58, 0xC1, 0x59, 0x92, 0x7D, 0xB0,
+    0xE8, 0x84, 0x54, 0xA5, 0xD9, 0x64, 0x71, 0xFD,
+    0xDC, 0xB5, 0x6D, 0x5B, 0xB0, 0x6B, 0xFA, 0x34,
+    0x0E, 0xA7, 0xA1, 0x51, 0xEF, 0x1C, 0xA6, 0xFA,
+    0x57, 0x2B, 0x76, 0xF3, 0xB1, 0xB9, 0x5D, 0x8C,
+    0x85, 0x83, 0xD3, 0xE4, 0x77, 0x05, 0x36, 0xB8,
+    0x4F, 0x01, 0x7E, 0x70, 0xE6, 0xFB, 0xF1, 0x76,
+    0x60, 0x1A, 0x02, 0x66, 0x94, 0x1A, 0x17, 0xB0,
+    0xC8, 0xB9, 0x7F, 0x4E, 0x74, 0xC2, 0xC1, 0xFF,
+    0xC7, 0x27, 0x89, 0x19, 0x77, 0x79, 0x40, 0xC1,
+    0xE1, 0xFF, 0x1D, 0x8D, 0xA6, 0x37, 0xD6, 0xB9,
+    0x9D, 0xDA, 0xFE, 0x5E, 0x17, 0x61, 0x10, 0x02,
+    0xE2, 0xC7, 0x78, 0xC1, 0xBE, 0x8B, 0x41, 0xD9,
+    0x63, 0x79, 0xA5, 0x13, 0x60, 0xD9, 0x77, 0xFD,
+    0x44, 0x35, 0xA1, 0x1C, 0x30, 0x8F, 0xE7, 0xEE,
+    0x6F, 0x1A, 0xAD, 0x9D, 0xB2, 0x8C, 0x81, 0xAD,
+    0xDE, 0x1A, 0x7A, 0x6F, 0x7C, 0xCE, 0x01, 0x1C,
+    0x30, 0xDA, 0x37, 0xE4, 0xEB, 0x73, 0x64, 0x83,
+    0xBD, 0x6C, 0x8E, 0x93, 0x48, 0xFB, 0xFB, 0xF7,
+    0x2C, 0xC6, 0x58, 0x7D, 0x60, 0xC3, 0x6C, 0x8E,
+    0x57, 0x7F, 0x09, 0x84, 0xC2, 0x89, 0xC9, 0x38,
+    0x5A, 0x09, 0x86, 0x49, 0xDE, 0x21, 0xBC, 0xA2,
+    0x7A, 0x7E, 0xA2, 0x29, 0x71, 0x6B, 0xA6, 0xE9,
+    0xB2, 0x79, 0x71, 0x0F, 0x38, 0xFA, 0xA5, 0xFF,
+    0xAE, 0x57, 0x41, 0x55, 0xCE, 0x4E, 0xFB, 0x4F,
+    0x74, 0x36, 0x95, 0xE2, 0x91, 0x1B, 0x1D, 0x06,
+    0xD5, 0xE2, 0x90, 0xCB, 0xCD, 0x86, 0xF5, 0x6D,
+    0x0E, 0xDF, 0xCD, 0x21, 0x6A, 0xE2, 0x24, 0x27,
+    0x05, 0x5E, 0x68, 0x35, 0xFD, 0x29, 0xEE, 0xF7,
+    0x9E, 0x0D, 0x90, 0x77, 0x1F, 0xEA, 0xCE, 0xBE,
+    0x12, 0xF2, 0x0E, 0x95, 0xB3, 0x4F, 0x0F, 0x78,
+    0xB7, 0x37, 0xA9, 0x61, 0x8B, 0x26, 0xFA, 0x7D,
+    0xBC, 0x98, 0x74, 0xF2, 0x72, 0xC4, 0x2B, 0xDB,
+    0x56, 0x3E, 0xAF, 0xA1, 0x6B, 0x4F, 0xB6, 0x8C,
+    0x3B, 0xB1, 0xE7, 0x8E, 0xAA, 0x81, 0xA0, 0x02,
+    0x43, 0xFA, 0xAD, 0xD2, 0xBF, 0x18, 0xE6, 0x3D,
+    0x38, 0x9A, 0xE4, 0x43, 0x77, 0xDA, 0x18, 0xC5,
+    0x76, 0xB5, 0x0F, 0x00, 0x96, 0xCF, 0x34, 0x19,
+    0x54, 0x83, 0xB0, 0x05, 0x48, 0xC0, 0x98, 0x62,
+    0x36, 0xE3, 0xBC, 0x7C, 0xB8, 0xD6, 0x80, 0x1C,
+    0x04, 0x94, 0xCC, 0xD1, 0x99, 0xE5, 0xC5, 0xBD,
+    0x0D, 0x0E, 0xDC, 0x9E, 0xB8, 0xA0, 0x00, 0x1E,
+    0x15, 0x27, 0x67, 0x54, 0xFC, 0xC6, 0x85, 0x66,
+    0x05, 0x41, 0x48, 0xE6, 0xE7, 0x64, 0xBE, 0xE7,
+    0xC7, 0x64, 0xDA, 0xAD, 0x3F, 0xC4, 0x52, 0x35,
+    0xA6, 0xDA, 0xD4, 0x28, 0xFA, 0x20, 0xC1, 0x70,
+    0xE3, 0x45, 0x00, 0x3F, 0x2F, 0x06, 0xEC, 0x81,
+    0x05, 0xFE, 0xB2, 0x5B, 0x22, 0x81, 0xB6, 0x3D,
+    0x27, 0x33, 0xBE, 0x96, 0x1C, 0x29, 0x95, 0x1D,
+    0x11, 0xDD, 0x22, 0x21, 0x65, 0x7A, 0x9F, 0x53,
+    0x1D, 0xDA, 0x2A, 0x19, 0x4D, 0xBB, 0x12, 0x64,
+    0x48, 0xBD, 0xEE, 0xB2, 0x58, 0xE0, 0x7E, 0xA6,
+    0x59, 0xC7, 0x46, 0x19, 0xA6, 0x38, 0x0E, 0x1D,
+    0x66, 0xD6, 0x83, 0x2B, 0xFE, 0x67, 0xF6, 0x38,
+    0xCD, 0x8F, 0xAE, 0x1F, 0x27, 0x23, 0x02, 0x0F,
+    0x9C, 0x40, 0xA3, 0xFD, 0xA6, 0x7E, 0xDA, 0x3B,
+    0xD2, 0x92, 0x38, 0xFB, 0xD4, 0xD4, 0xB4, 0x88,
+    0x5C, 0x2A, 0x99, 0x17, 0x6D, 0xB1, 0xA0, 0x6C,
+    0x50, 0x07, 0x78, 0x49, 0x1A, 0x82, 0x88, 0xF1,
+    0x85, 0x5F, 0x60, 0xFF, 0xFC, 0xF1, 0xD1, 0x37,
+    0x3F, 0xD9, 0x4F, 0xC6, 0x0C, 0x18, 0x11, 0xE1,
+    0xAC, 0x3F, 0x1C, 0x6D, 0x00, 0x3B, 0xEC, 0xDA,
+    0x3B, 0x1F, 0x27, 0x25, 0xCA, 0x59, 0x5D, 0xE0,
+    0xCA, 0x63, 0x32, 0x8F, 0x3B, 0xE5, 0x7C, 0xC9,
+    0x77, 0x55, 0x60, 0x11, 0x95, 0x14, 0x0D, 0xFB,
+    0x59, 0xD3, 0x9C, 0xE0, 0x91, 0x30, 0x8B, 0x41,
+    0x05, 0x74, 0x6D, 0xAC, 0x23, 0xD3, 0x3E, 0x5F,
+    0x7C, 0xE4, 0x84, 0x8D, 0xA3, 0x16, 0xA9, 0xC6,
+    0x6B, 0x95, 0x81, 0xBA, 0x35, 0x73, 0xBF, 0xAF,
+    0x31, 0x14, 0x96, 0x18, 0x8A, 0xB1, 0x54, 0x23,
+    0x28, 0x2E, 0xE4, 0x16, 0xDC, 0x2A, 0x19, 0xC5,
+    0x72, 0x4F, 0xA9, 0x1A, 0xE4, 0xAD, 0xC8, 0x8B,
+    0xC6, 0x67, 0x96, 0xEA, 0xE5, 0x67, 0x7A, 0x01,
+    0xF6, 0x4E, 0x8C, 0x08, 0x63, 0x13, 0x95, 0x82,
+    0x2D, 0x9D, 0xB8, 0xFC, 0xEE, 0x35, 0xC0, 0x6B,
+    0x1F, 0xEE, 0xA5, 0x47, 0x4D, 0x6D, 0x8F, 0x34,
+    0xB1, 0x53, 0x4A, 0x93, 0x6A, 0x18, 0xB0, 0xE0,
+    0xD2, 0x0E, 0xAB, 0x86, 0xBC, 0x9C, 0x6D, 0x6A,
+    0x52, 0x07, 0x19, 0x4E, 0x68, 0x72, 0x07, 0x32,
+    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
+};
+#endif /* HAVE_FFDHE_Q */
+
+const DhParams* wc_Dh_ffdhe6144_Get(void)
+{
+    static const DhParams ffdhe6144 = {
+        #ifdef HAVE_FFDHE_Q
+            dh_ffdhe6144_q, sizeof(dh_ffdhe6144_q),
+        #endif /* HAVE_FFDHE_Q */
+        dh_ffdhe6144_p, sizeof(dh_ffdhe6144_p),
+        dh_ffdhe6144_g, sizeof(dh_ffdhe6144_g)
+    };
+    return &ffdhe6144;
+}
+#endif
+
+#ifdef HAVE_FFDHE_8192
+static const byte dh_ffdhe8192_p[] = {
+    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+    0xAD, 0xF8, 0x54, 0x58, 0xA2, 0xBB, 0x4A, 0x9A,
+    0xAF, 0xDC, 0x56, 0x20, 0x27, 0x3D, 0x3C, 0xF1,
+    0xD8, 0xB9, 0xC5, 0x83, 0xCE, 0x2D, 0x36, 0x95,
+    0xA9, 0xE1, 0x36, 0x41, 0x14, 0x64, 0x33, 0xFB,
+    0xCC, 0x93, 0x9D, 0xCE, 0x24, 0x9B, 0x3E, 0xF9,
+    0x7D, 0x2F, 0xE3, 0x63, 0x63, 0x0C, 0x75, 0xD8,
+    0xF6, 0x81, 0xB2, 0x02, 0xAE, 0xC4, 0x61, 0x7A,
+    0xD3, 0xDF, 0x1E, 0xD5, 0xD5, 0xFD, 0x65, 0x61,
+    0x24, 0x33, 0xF5, 0x1F, 0x5F, 0x06, 0x6E, 0xD0,
+    0x85, 0x63, 0x65, 0x55, 0x3D, 0xED, 0x1A, 0xF3,
+    0xB5, 0x57, 0x13, 0x5E, 0x7F, 0x57, 0xC9, 0x35,
+    0x98, 0x4F, 0x0C, 0x70, 0xE0, 0xE6, 0x8B, 0x77,
+    0xE2, 0xA6, 0x89, 0xDA, 0xF3, 0xEF, 0xE8, 0x72,
+    0x1D, 0xF1, 0x58, 0xA1, 0x36, 0xAD, 0xE7, 0x35,
+    0x30, 0xAC, 0xCA, 0x4F, 0x48, 0x3A, 0x79, 0x7A,
+    0xBC, 0x0A, 0xB1, 0x82, 0xB3, 0x24, 0xFB, 0x61,
+    0xD1, 0x08, 0xA9, 0x4B, 0xB2, 0xC8, 0xE3, 0xFB,
+    0xB9, 0x6A, 0xDA, 0xB7, 0x60, 0xD7, 0xF4, 0x68,
+    0x1D, 0x4F, 0x42, 0xA3, 0xDE, 0x39, 0x4D, 0xF4,
+    0xAE, 0x56, 0xED, 0xE7, 0x63, 0x72, 0xBB, 0x19,
+    0x0B, 0x07, 0xA7, 0xC8, 0xEE, 0x0A, 0x6D, 0x70,
+    0x9E, 0x02, 0xFC, 0xE1, 0xCD, 0xF7, 0xE2, 0xEC,
+    0xC0, 0x34, 0x04, 0xCD, 0x28, 0x34, 0x2F, 0x61,
+    0x91, 0x72, 0xFE, 0x9C, 0xE9, 0x85, 0x83, 0xFF,
+    0x8E, 0x4F, 0x12, 0x32, 0xEE, 0xF2, 0x81, 0x83,
+    0xC3, 0xFE, 0x3B, 0x1B, 0x4C, 0x6F, 0xAD, 0x73,
+    0x3B, 0xB5, 0xFC, 0xBC, 0x2E, 0xC2, 0x20, 0x05,
+    0xC5, 0x8E, 0xF1, 0x83, 0x7D, 0x16, 0x83, 0xB2,
+    0xC6, 0xF3, 0x4A, 0x26, 0xC1, 0xB2, 0xEF, 0xFA,
+    0x88, 0x6B, 0x42, 0x38, 0x61, 0x1F, 0xCF, 0xDC,
+    0xDE, 0x35, 0x5B, 0x3B, 0x65, 0x19, 0x03, 0x5B,
+    0xBC, 0x34, 0xF4, 0xDE, 0xF9, 0x9C, 0x02, 0x38,
+    0x61, 0xB4, 0x6F, 0xC9, 0xD6, 0xE6, 0xC9, 0x07,
+    0x7A, 0xD9, 0x1D, 0x26, 0x91, 0xF7, 0xF7, 0xEE,
+    0x59, 0x8C, 0xB0, 0xFA, 0xC1, 0x86, 0xD9, 0x1C,
+    0xAE, 0xFE, 0x13, 0x09, 0x85, 0x13, 0x92, 0x70,
+    0xB4, 0x13, 0x0C, 0x93, 0xBC, 0x43, 0x79, 0x44,
+    0xF4, 0xFD, 0x44, 0x52, 0xE2, 0xD7, 0x4D, 0xD3,
+    0x64, 0xF2, 0xE2, 0x1E, 0x71, 0xF5, 0x4B, 0xFF,
+    0x5C, 0xAE, 0x82, 0xAB, 0x9C, 0x9D, 0xF6, 0x9E,
+    0xE8, 0x6D, 0x2B, 0xC5, 0x22, 0x36, 0x3A, 0x0D,
+    0xAB, 0xC5, 0x21, 0x97, 0x9B, 0x0D, 0xEA, 0xDA,
+    0x1D, 0xBF, 0x9A, 0x42, 0xD5, 0xC4, 0x48, 0x4E,
+    0x0A, 0xBC, 0xD0, 0x6B, 0xFA, 0x53, 0xDD, 0xEF,
+    0x3C, 0x1B, 0x20, 0xEE, 0x3F, 0xD5, 0x9D, 0x7C,
+    0x25, 0xE4, 0x1D, 0x2B, 0x66, 0x9E, 0x1E, 0xF1,
+    0x6E, 0x6F, 0x52, 0xC3, 0x16, 0x4D, 0xF4, 0xFB,
+    0x79, 0x30, 0xE9, 0xE4, 0xE5, 0x88, 0x57, 0xB6,
+    0xAC, 0x7D, 0x5F, 0x42, 0xD6, 0x9F, 0x6D, 0x18,
+    0x77, 0x63, 0xCF, 0x1D, 0x55, 0x03, 0x40, 0x04,
+    0x87, 0xF5, 0x5B, 0xA5, 0x7E, 0x31, 0xCC, 0x7A,
+    0x71, 0x35, 0xC8, 0x86, 0xEF, 0xB4, 0x31, 0x8A,
+    0xED, 0x6A, 0x1E, 0x01, 0x2D, 0x9E, 0x68, 0x32,
+    0xA9, 0x07, 0x60, 0x0A, 0x91, 0x81, 0x30, 0xC4,
+    0x6D, 0xC7, 0x78, 0xF9, 0x71, 0xAD, 0x00, 0x38,
+    0x09, 0x29, 0x99, 0xA3, 0x33, 0xCB, 0x8B, 0x7A,
+    0x1A, 0x1D, 0xB9, 0x3D, 0x71, 0x40, 0x00, 0x3C,
+    0x2A, 0x4E, 0xCE, 0xA9, 0xF9, 0x8D, 0x0A, 0xCC,
+    0x0A, 0x82, 0x91, 0xCD, 0xCE, 0xC9, 0x7D, 0xCF,
+    0x8E, 0xC9, 0xB5, 0x5A, 0x7F, 0x88, 0xA4, 0x6B,
+    0x4D, 0xB5, 0xA8, 0x51, 0xF4, 0x41, 0x82, 0xE1,
+    0xC6, 0x8A, 0x00, 0x7E, 0x5E, 0x0D, 0xD9, 0x02,
+    0x0B, 0xFD, 0x64, 0xB6, 0x45, 0x03, 0x6C, 0x7A,
+    0x4E, 0x67, 0x7D, 0x2C, 0x38, 0x53, 0x2A, 0x3A,
+    0x23, 0xBA, 0x44, 0x42, 0xCA, 0xF5, 0x3E, 0xA6,
+    0x3B, 0xB4, 0x54, 0x32, 0x9B, 0x76, 0x24, 0xC8,
+    0x91, 0x7B, 0xDD, 0x64, 0xB1, 0xC0, 0xFD, 0x4C,
+    0xB3, 0x8E, 0x8C, 0x33, 0x4C, 0x70, 0x1C, 0x3A,
+    0xCD, 0xAD, 0x06, 0x57, 0xFC, 0xCF, 0xEC, 0x71,
+    0x9B, 0x1F, 0x5C, 0x3E, 0x4E, 0x46, 0x04, 0x1F,
+    0x38, 0x81, 0x47, 0xFB, 0x4C, 0xFD, 0xB4, 0x77,
+    0xA5, 0x24, 0x71, 0xF7, 0xA9, 0xA9, 0x69, 0x10,
+    0xB8, 0x55, 0x32, 0x2E, 0xDB, 0x63, 0x40, 0xD8,
+    0xA0, 0x0E, 0xF0, 0x92, 0x35, 0x05, 0x11, 0xE3,
+    0x0A, 0xBE, 0xC1, 0xFF, 0xF9, 0xE3, 0xA2, 0x6E,
+    0x7F, 0xB2, 0x9F, 0x8C, 0x18, 0x30, 0x23, 0xC3,
+    0x58, 0x7E, 0x38, 0xDA, 0x00, 0x77, 0xD9, 0xB4,
+    0x76, 0x3E, 0x4E, 0x4B, 0x94, 0xB2, 0xBB, 0xC1,
+    0x94, 0xC6, 0x65, 0x1E, 0x77, 0xCA, 0xF9, 0x92,
+    0xEE, 0xAA, 0xC0, 0x23, 0x2A, 0x28, 0x1B, 0xF6,
+    0xB3, 0xA7, 0x39, 0xC1, 0x22, 0x61, 0x16, 0x82,
+    0x0A, 0xE8, 0xDB, 0x58, 0x47, 0xA6, 0x7C, 0xBE,
+    0xF9, 0xC9, 0x09, 0x1B, 0x46, 0x2D, 0x53, 0x8C,
+    0xD7, 0x2B, 0x03, 0x74, 0x6A, 0xE7, 0x7F, 0x5E,
+    0x62, 0x29, 0x2C, 0x31, 0x15, 0x62, 0xA8, 0x46,
+    0x50, 0x5D, 0xC8, 0x2D, 0xB8, 0x54, 0x33, 0x8A,
+    0xE4, 0x9F, 0x52, 0x35, 0xC9, 0x5B, 0x91, 0x17,
+    0x8C, 0xCF, 0x2D, 0xD5, 0xCA, 0xCE, 0xF4, 0x03,
+    0xEC, 0x9D, 0x18, 0x10, 0xC6, 0x27, 0x2B, 0x04,
+    0x5B, 0x3B, 0x71, 0xF9, 0xDC, 0x6B, 0x80, 0xD6,
+    0x3F, 0xDD, 0x4A, 0x8E, 0x9A, 0xDB, 0x1E, 0x69,
+    0x62, 0xA6, 0x95, 0x26, 0xD4, 0x31, 0x61, 0xC1,
+    0xA4, 0x1D, 0x57, 0x0D, 0x79, 0x38, 0xDA, 0xD4,
+    0xA4, 0x0E, 0x32, 0x9C, 0xCF, 0xF4, 0x6A, 0xAA,
+    0x36, 0xAD, 0x00, 0x4C, 0xF6, 0x00, 0xC8, 0x38,
+    0x1E, 0x42, 0x5A, 0x31, 0xD9, 0x51, 0xAE, 0x64,
+    0xFD, 0xB2, 0x3F, 0xCE, 0xC9, 0x50, 0x9D, 0x43,
+    0x68, 0x7F, 0xEB, 0x69, 0xED, 0xD1, 0xCC, 0x5E,
+    0x0B, 0x8C, 0xC3, 0xBD, 0xF6, 0x4B, 0x10, 0xEF,
+    0x86, 0xB6, 0x31, 0x42, 0xA3, 0xAB, 0x88, 0x29,
+    0x55, 0x5B, 0x2F, 0x74, 0x7C, 0x93, 0x26, 0x65,
+    0xCB, 0x2C, 0x0F, 0x1C, 0xC0, 0x1B, 0xD7, 0x02,
+    0x29, 0x38, 0x88, 0x39, 0xD2, 0xAF, 0x05, 0xE4,
+    0x54, 0x50, 0x4A, 0xC7, 0x8B, 0x75, 0x82, 0x82,
+    0x28, 0x46, 0xC0, 0xBA, 0x35, 0xC3, 0x5F, 0x5C,
+    0x59, 0x16, 0x0C, 0xC0, 0x46, 0xFD, 0x82, 0x51,
+    0x54, 0x1F, 0xC6, 0x8C, 0x9C, 0x86, 0xB0, 0x22,
+    0xBB, 0x70, 0x99, 0x87, 0x6A, 0x46, 0x0E, 0x74,
+    0x51, 0xA8, 0xA9, 0x31, 0x09, 0x70, 0x3F, 0xEE,
+    0x1C, 0x21, 0x7E, 0x6C, 0x38, 0x26, 0xE5, 0x2C,
+    0x51, 0xAA, 0x69, 0x1E, 0x0E, 0x42, 0x3C, 0xFC,
+    0x99, 0xE9, 0xE3, 0x16, 0x50, 0xC1, 0x21, 0x7B,
+    0x62, 0x48, 0x16, 0xCD, 0xAD, 0x9A, 0x95, 0xF9,
+    0xD5, 0xB8, 0x01, 0x94, 0x88, 0xD9, 0xC0, 0xA0,
+    0xA1, 0xFE, 0x30, 0x75, 0xA5, 0x77, 0xE2, 0x31,
+    0x83, 0xF8, 0x1D, 0x4A, 0x3F, 0x2F, 0xA4, 0x57,
+    0x1E, 0xFC, 0x8C, 0xE0, 0xBA, 0x8A, 0x4F, 0xE8,
+    0xB6, 0x85, 0x5D, 0xFE, 0x72, 0xB0, 0xA6, 0x6E,
+    0xDE, 0xD2, 0xFB, 0xAB, 0xFB, 0xE5, 0x8A, 0x30,
+    0xFA, 0xFA, 0xBE, 0x1C, 0x5D, 0x71, 0xA8, 0x7E,
+    0x2F, 0x74, 0x1E, 0xF8, 0xC1, 0xFE, 0x86, 0xFE,
+    0xA6, 0xBB, 0xFD, 0xE5, 0x30, 0x67, 0x7F, 0x0D,
+    0x97, 0xD1, 0x1D, 0x49, 0xF7, 0xA8, 0x44, 0x3D,
+    0x08, 0x22, 0xE5, 0x06, 0xA9, 0xF4, 0x61, 0x4E,
+    0x01, 0x1E, 0x2A, 0x94, 0x83, 0x8F, 0xF8, 0x8C,
+    0xD6, 0x8C, 0x8B, 0xB7, 0xC5, 0xC6, 0x42, 0x4C,
+    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
+};
+static const byte dh_ffdhe8192_g[] = { 0x02 };
+#ifdef HAVE_FFDHE_Q
+static const byte dh_ffdhe8192_q[] = {
+    0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+    0xD6, 0xFC, 0x2A, 0x2C, 0x51, 0x5D, 0xA5, 0x4D,
+    0x57, 0xEE, 0x2B, 0x10, 0x13, 0x9E, 0x9E, 0x78,
+    0xEC, 0x5C, 0xE2, 0xC1, 0xE7, 0x16, 0x9B, 0x4A,
+    0xD4, 0xF0, 0x9B, 0x20, 0x8A, 0x32, 0x19, 0xFD,
+    0xE6, 0x49, 0xCE, 0xE7, 0x12, 0x4D, 0x9F, 0x7C,
+    0xBE, 0x97, 0xF1, 0xB1, 0xB1, 0x86, 0x3A, 0xEC,
+    0x7B, 0x40, 0xD9, 0x01, 0x57, 0x62, 0x30, 0xBD,
+    0x69, 0xEF, 0x8F, 0x6A, 0xEA, 0xFE, 0xB2, 0xB0,
+    0x92, 0x19, 0xFA, 0x8F, 0xAF, 0x83, 0x37, 0x68,
+    0x42, 0xB1, 0xB2, 0xAA, 0x9E, 0xF6, 0x8D, 0x79,
+    0xDA, 0xAB, 0x89, 0xAF, 0x3F, 0xAB, 0xE4, 0x9A,
+    0xCC, 0x27, 0x86, 0x38, 0x70, 0x73, 0x45, 0xBB,
+    0xF1, 0x53, 0x44, 0xED, 0x79, 0xF7, 0xF4, 0x39,
+    0x0E, 0xF8, 0xAC, 0x50, 0x9B, 0x56, 0xF3, 0x9A,
+    0x98, 0x56, 0x65, 0x27, 0xA4, 0x1D, 0x3C, 0xBD,
+    0x5E, 0x05, 0x58, 0xC1, 0x59, 0x92, 0x7D, 0xB0,
+    0xE8, 0x84, 0x54, 0xA5, 0xD9, 0x64, 0x71, 0xFD,
+    0xDC, 0xB5, 0x6D, 0x5B, 0xB0, 0x6B, 0xFA, 0x34,
+    0x0E, 0xA7, 0xA1, 0x51, 0xEF, 0x1C, 0xA6, 0xFA,
+    0x57, 0x2B, 0x76, 0xF3, 0xB1, 0xB9, 0x5D, 0x8C,
+    0x85, 0x83, 0xD3, 0xE4, 0x77, 0x05, 0x36, 0xB8,
+    0x4F, 0x01, 0x7E, 0x70, 0xE6, 0xFB, 0xF1, 0x76,
+    0x60, 0x1A, 0x02, 0x66, 0x94, 0x1A, 0x17, 0xB0,
+    0xC8, 0xB9, 0x7F, 0x4E, 0x74, 0xC2, 0xC1, 0xFF,
+    0xC7, 0x27, 0x89, 0x19, 0x77, 0x79, 0x40, 0xC1,
+    0xE1, 0xFF, 0x1D, 0x8D, 0xA6, 0x37, 0xD6, 0xB9,
+    0x9D, 0xDA, 0xFE, 0x5E, 0x17, 0x61, 0x10, 0x02,
+    0xE2, 0xC7, 0x78, 0xC1, 0xBE, 0x8B, 0x41, 0xD9,
+    0x63, 0x79, 0xA5, 0x13, 0x60, 0xD9, 0x77, 0xFD,
+    0x44, 0x35, 0xA1, 0x1C, 0x30, 0x8F, 0xE7, 0xEE,
+    0x6F, 0x1A, 0xAD, 0x9D, 0xB2, 0x8C, 0x81, 0xAD,
+    0xDE, 0x1A, 0x7A, 0x6F, 0x7C, 0xCE, 0x01, 0x1C,
+    0x30, 0xDA, 0x37, 0xE4, 0xEB, 0x73, 0x64, 0x83,
+    0xBD, 0x6C, 0x8E, 0x93, 0x48, 0xFB, 0xFB, 0xF7,
+    0x2C, 0xC6, 0x58, 0x7D, 0x60, 0xC3, 0x6C, 0x8E,
+    0x57, 0x7F, 0x09, 0x84, 0xC2, 0x89, 0xC9, 0x38,
+    0x5A, 0x09, 0x86, 0x49, 0xDE, 0x21, 0xBC, 0xA2,
+    0x7A, 0x7E, 0xA2, 0x29, 0x71, 0x6B, 0xA6, 0xE9,
+    0xB2, 0x79, 0x71, 0x0F, 0x38, 0xFA, 0xA5, 0xFF,
+    0xAE, 0x57, 0x41, 0x55, 0xCE, 0x4E, 0xFB, 0x4F,
+    0x74, 0x36, 0x95, 0xE2, 0x91, 0x1B, 0x1D, 0x06,
+    0xD5, 0xE2, 0x90, 0xCB, 0xCD, 0x86, 0xF5, 0x6D,
+    0x0E, 0xDF, 0xCD, 0x21, 0x6A, 0xE2, 0x24, 0x27,
+    0x05, 0x5E, 0x68, 0x35, 0xFD, 0x29, 0xEE, 0xF7,
+    0x9E, 0x0D, 0x90, 0x77, 0x1F, 0xEA, 0xCE, 0xBE,
+    0x12, 0xF2, 0x0E, 0x95, 0xB3, 0x4F, 0x0F, 0x78,
+    0xB7, 0x37, 0xA9, 0x61, 0x8B, 0x26, 0xFA, 0x7D,
+    0xBC, 0x98, 0x74, 0xF2, 0x72, 0xC4, 0x2B, 0xDB,
+    0x56, 0x3E, 0xAF, 0xA1, 0x6B, 0x4F, 0xB6, 0x8C,
+    0x3B, 0xB1, 0xE7, 0x8E, 0xAA, 0x81, 0xA0, 0x02,
+    0x43, 0xFA, 0xAD, 0xD2, 0xBF, 0x18, 0xE6, 0x3D,
+    0x38, 0x9A, 0xE4, 0x43, 0x77, 0xDA, 0x18, 0xC5,
+    0x76, 0xB5, 0x0F, 0x00, 0x96, 0xCF, 0x34, 0x19,
+    0x54, 0x83, 0xB0, 0x05, 0x48, 0xC0, 0x98, 0x62,
+    0x36, 0xE3, 0xBC, 0x7C, 0xB8, 0xD6, 0x80, 0x1C,
+    0x04, 0x94, 0xCC, 0xD1, 0x99, 0xE5, 0xC5, 0xBD,
+    0x0D, 0x0E, 0xDC, 0x9E, 0xB8, 0xA0, 0x00, 0x1E,
+    0x15, 0x27, 0x67, 0x54, 0xFC, 0xC6, 0x85, 0x66,
+    0x05, 0x41, 0x48, 0xE6, 0xE7, 0x64, 0xBE, 0xE7,
+    0xC7, 0x64, 0xDA, 0xAD, 0x3F, 0xC4, 0x52, 0x35,
+    0xA6, 0xDA, 0xD4, 0x28, 0xFA, 0x20, 0xC1, 0x70,
+    0xE3, 0x45, 0x00, 0x3F, 0x2F, 0x06, 0xEC, 0x81,
+    0x05, 0xFE, 0xB2, 0x5B, 0x22, 0x81, 0xB6, 0x3D,
+    0x27, 0x33, 0xBE, 0x96, 0x1C, 0x29, 0x95, 0x1D,
+    0x11, 0xDD, 0x22, 0x21, 0x65, 0x7A, 0x9F, 0x53,
+    0x1D, 0xDA, 0x2A, 0x19, 0x4D, 0xBB, 0x12, 0x64,
+    0x48, 0xBD, 0xEE, 0xB2, 0x58, 0xE0, 0x7E, 0xA6,
+    0x59, 0xC7, 0x46, 0x19, 0xA6, 0x38, 0x0E, 0x1D,
+    0x66, 0xD6, 0x83, 0x2B, 0xFE, 0x67, 0xF6, 0x38,
+    0xCD, 0x8F, 0xAE, 0x1F, 0x27, 0x23, 0x02, 0x0F,
+    0x9C, 0x40, 0xA3, 0xFD, 0xA6, 0x7E, 0xDA, 0x3B,
+    0xD2, 0x92, 0x38, 0xFB, 0xD4, 0xD4, 0xB4, 0x88,
+    0x5C, 0x2A, 0x99, 0x17, 0x6D, 0xB1, 0xA0, 0x6C,
+    0x50, 0x07, 0x78, 0x49, 0x1A, 0x82, 0x88, 0xF1,
+    0x85, 0x5F, 0x60, 0xFF, 0xFC, 0xF1, 0xD1, 0x37,
+    0x3F, 0xD9, 0x4F, 0xC6, 0x0C, 0x18, 0x11, 0xE1,
+    0xAC, 0x3F, 0x1C, 0x6D, 0x00, 0x3B, 0xEC, 0xDA,
+    0x3B, 0x1F, 0x27, 0x25, 0xCA, 0x59, 0x5D, 0xE0,
+    0xCA, 0x63, 0x32, 0x8F, 0x3B, 0xE5, 0x7C, 0xC9,
+    0x77, 0x55, 0x60, 0x11, 0x95, 0x14, 0x0D, 0xFB,
+    0x59, 0xD3, 0x9C, 0xE0, 0x91, 0x30, 0x8B, 0x41,
+    0x05, 0x74, 0x6D, 0xAC, 0x23, 0xD3, 0x3E, 0x5F,
+    0x7C, 0xE4, 0x84, 0x8D, 0xA3, 0x16, 0xA9, 0xC6,
+    0x6B, 0x95, 0x81, 0xBA, 0x35, 0x73, 0xBF, 0xAF,
+    0x31, 0x14, 0x96, 0x18, 0x8A, 0xB1, 0x54, 0x23,
+    0x28, 0x2E, 0xE4, 0x16, 0xDC, 0x2A, 0x19, 0xC5,
+    0x72, 0x4F, 0xA9, 0x1A, 0xE4, 0xAD, 0xC8, 0x8B,
+    0xC6, 0x67, 0x96, 0xEA, 0xE5, 0x67, 0x7A, 0x01,
+    0xF6, 0x4E, 0x8C, 0x08, 0x63, 0x13, 0x95, 0x82,
+    0x2D, 0x9D, 0xB8, 0xFC, 0xEE, 0x35, 0xC0, 0x6B,
+    0x1F, 0xEE, 0xA5, 0x47, 0x4D, 0x6D, 0x8F, 0x34,
+    0xB1, 0x53, 0x4A, 0x93, 0x6A, 0x18, 0xB0, 0xE0,
+    0xD2, 0x0E, 0xAB, 0x86, 0xBC, 0x9C, 0x6D, 0x6A,
+    0x52, 0x07, 0x19, 0x4E, 0x67, 0xFA, 0x35, 0x55,
+    0x1B, 0x56, 0x80, 0x26, 0x7B, 0x00, 0x64, 0x1C,
+    0x0F, 0x21, 0x2D, 0x18, 0xEC, 0xA8, 0xD7, 0x32,
+    0x7E, 0xD9, 0x1F, 0xE7, 0x64, 0xA8, 0x4E, 0xA1,
+    0xB4, 0x3F, 0xF5, 0xB4, 0xF6, 0xE8, 0xE6, 0x2F,
+    0x05, 0xC6, 0x61, 0xDE, 0xFB, 0x25, 0x88, 0x77,
+    0xC3, 0x5B, 0x18, 0xA1, 0x51, 0xD5, 0xC4, 0x14,
+    0xAA, 0xAD, 0x97, 0xBA, 0x3E, 0x49, 0x93, 0x32,
+    0xE5, 0x96, 0x07, 0x8E, 0x60, 0x0D, 0xEB, 0x81,
+    0x14, 0x9C, 0x44, 0x1C, 0xE9, 0x57, 0x82, 0xF2,
+    0x2A, 0x28, 0x25, 0x63, 0xC5, 0xBA, 0xC1, 0x41,
+    0x14, 0x23, 0x60, 0x5D, 0x1A, 0xE1, 0xAF, 0xAE,
+    0x2C, 0x8B, 0x06, 0x60, 0x23, 0x7E, 0xC1, 0x28,
+    0xAA, 0x0F, 0xE3, 0x46, 0x4E, 0x43, 0x58, 0x11,
+    0x5D, 0xB8, 0x4C, 0xC3, 0xB5, 0x23, 0x07, 0x3A,
+    0x28, 0xD4, 0x54, 0x98, 0x84, 0xB8, 0x1F, 0xF7,
+    0x0E, 0x10, 0xBF, 0x36, 0x1C, 0x13, 0x72, 0x96,
+    0x28, 0xD5, 0x34, 0x8F, 0x07, 0x21, 0x1E, 0x7E,
+    0x4C, 0xF4, 0xF1, 0x8B, 0x28, 0x60, 0x90, 0xBD,
+    0xB1, 0x24, 0x0B, 0x66, 0xD6, 0xCD, 0x4A, 0xFC,
+    0xEA, 0xDC, 0x00, 0xCA, 0x44, 0x6C, 0xE0, 0x50,
+    0x50, 0xFF, 0x18, 0x3A, 0xD2, 0xBB, 0xF1, 0x18,
+    0xC1, 0xFC, 0x0E, 0xA5, 0x1F, 0x97, 0xD2, 0x2B,
+    0x8F, 0x7E, 0x46, 0x70, 0x5D, 0x45, 0x27, 0xF4,
+    0x5B, 0x42, 0xAE, 0xFF, 0x39, 0x58, 0x53, 0x37,
+    0x6F, 0x69, 0x7D, 0xD5, 0xFD, 0xF2, 0xC5, 0x18,
+    0x7D, 0x7D, 0x5F, 0x0E, 0x2E, 0xB8, 0xD4, 0x3F,
+    0x17, 0xBA, 0x0F, 0x7C, 0x60, 0xFF, 0x43, 0x7F,
+    0x53, 0x5D, 0xFE, 0xF2, 0x98, 0x33, 0xBF, 0x86,
+    0xCB, 0xE8, 0x8E, 0xA4, 0xFB, 0xD4, 0x22, 0x1E,
+    0x84, 0x11, 0x72, 0x83, 0x54, 0xFA, 0x30, 0xA7,
+    0x00, 0x8F, 0x15, 0x4A, 0x41, 0xC7, 0xFC, 0x46,
+    0x6B, 0x46, 0x45, 0xDB, 0xE2, 0xE3, 0x21, 0x26,
+    0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
+};
+#endif /* HAVE_FFDHE_Q */
+
+const DhParams* wc_Dh_ffdhe8192_Get(void)
+{
+    static const DhParams ffdhe8192 = {
+        #ifdef HAVE_FFDHE_Q
+            dh_ffdhe8192_q, sizeof(dh_ffdhe8192_q),
+        #endif /* HAVE_FFDHE_Q */
+        dh_ffdhe8192_p, sizeof(dh_ffdhe8192_p),
+        dh_ffdhe8192_g, sizeof(dh_ffdhe8192_g)
+    };
+    return &ffdhe8192;
+}
+#endif
+
+int wc_InitDhKey_ex(DhKey* key, void* heap, int devId)
+{
+    int ret = 0;
+
+    if (key == NULL)
+        return BAD_FUNC_ARG;
+
+    key->heap = heap; /* for XMALLOC/XFREE in future */
+
+#if !defined(WOLFSSL_QT) && !defined(OPENSSL_ALL)
+    if (mp_init_multi(&key->p, &key->g, &key->q, NULL, NULL, NULL) != MP_OKAY)
+#else
+    if (mp_init_multi(&key->p,&key->g,&key->q,&key->pub,&key->priv,NULL) != MP_OKAY)
+#endif
+        return MEMORY_E;
+
+#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_DH)
+    /* handle as async */
+    ret = wolfAsync_DevCtxInit(&key->asyncDev, WOLFSSL_ASYNC_MARKER_DH,
+        key->heap, devId);
+#else
+    (void)devId;
+#endif
+
+    return ret;
+}
+
+int wc_InitDhKey(DhKey* key)
+{
+    return wc_InitDhKey_ex(key, NULL, INVALID_DEVID);
+}
+
+
+int wc_FreeDhKey(DhKey* key)
+{
+    if (key) {
+        mp_clear(&key->p);
+        mp_clear(&key->g);
+        mp_clear(&key->q);
+
+    #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_DH)
+        wolfAsync_DevCtxFree(&key->asyncDev, WOLFSSL_ASYNC_MARKER_DH);
+    #endif
+    }
+    return 0;
+}
+
+
+#ifndef WC_NO_RNG
+/* if defined to not use floating point values do not compile in */
+#ifndef WOLFSSL_DH_CONST
+    static word32 DiscreteLogWorkFactor(word32 n)
+    {
+        /* assuming discrete log takes about the same time as factoring */
+        if (n < 5)
+            return 0;
+        else
+            return (word32)(2.4 * XPOW((double)n, 1.0/3.0) *
+                    XPOW(XLOG((double)n), 2.0/3.0) - 5);
+    }
+#endif /* WOLFSSL_DH_CONST*/
+
+
+/* if not using fixed points use DiscreteLogWorkFactor function for unusual size
+   otherwise round up on size needed */
+#ifndef WOLFSSL_DH_CONST
+    #define WOLFSSL_DH_ROUND(x)
+#else
+    #define WOLFSSL_DH_ROUND(x) \
+        do {                    \
+            if (x % 128) {      \
+                x &= 0xffffff80;\
+                x += 128;       \
+            }                   \
+        }                       \
+        while (0)
+#endif
+
+
+#ifndef WOLFSSL_NO_DH186
+/* validate that (L,N) match allowed sizes from SP 800-56A, Section 5.5.1.1.
+ * modLen - represents L, the size of p in bits
+ * divLen - represents N, the size of q in bits
+ * return 0 on success, -1 on error */
+static int CheckDhLN(int modLen, int divLen)
+{
+    int ret = -1;
+
+    switch (modLen) {
+        /* FA */
+        case 1024:
+            if (divLen == 160)
+                ret = 0;
+            break;
+        /* FB, FC */
+        case 2048:
+            if (divLen == 224 || divLen == 256)
+                ret = 0;
+            break;
+        default:
+            break;
+    }
+
+    return ret;
+}
+
+
+/* Create DH private key
+ *
+ * Based on NIST FIPS 186-4,
+ * "B.1.1 Key Pair Generation Using Extra Random Bits"
+ *
+ * dh     - pointer to initialized DhKey structure, needs to have dh->q
+ * rng    - pointer to initialized WC_RNG structure
+ * priv   - output location for generated private key
+ * privSz - IN/OUT, size of priv buffer, size of generated private key
+ *
+ * return 0 on success, negative on error */
+static int GeneratePrivateDh186(DhKey* key, WC_RNG* rng, byte* priv,
+                                word32* privSz)
+{
+    byte* cBuf;
+    int qSz, pSz, cSz, err;
+#ifdef WOLFSSL_SMALL_STACK
+    mp_int* tmpQ = NULL;
+    mp_int* tmpX = NULL;
+#else
+    mp_int tmpQ[1], tmpX[1];
+#endif
+
+    /* Parameters validated in calling functions. */
+
+    if (mp_iszero(&key->q) == MP_YES) {
+        WOLFSSL_MSG("DH q parameter needed for FIPS 186-4 key generation");
+        return BAD_FUNC_ARG;
+    }
+
+    qSz = mp_unsigned_bin_size(&key->q);
+    pSz = mp_unsigned_bin_size(&key->p);
+
+    /* verify (L,N) pair bit lengths */
+    if (CheckDhLN(pSz * WOLFSSL_BIT_SIZE, qSz * WOLFSSL_BIT_SIZE) != 0) {
+        WOLFSSL_MSG("DH param sizes do not match SP 800-56A requirements");
+        return BAD_FUNC_ARG;
+    }
+
+    /* generate extra 64 bits so that bias from mod function is negligible */
+    cSz = qSz + (64 / WOLFSSL_BIT_SIZE);
+    cBuf = (byte*)XMALLOC(cSz, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
+    if (cBuf == NULL) {
+        return MEMORY_E;
+    }
+#ifdef WOLFSSL_SMALL_STACK
+    tmpQ = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_DH);
+    if (tmpQ == NULL) {
+        XFREE(cBuf, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
+        return MEMORY_E;
+    }
+    tmpX = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_DH);
+    if (tmpX == NULL) {
+        XFREE(cBuf, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
+        XFREE(tmpQ, key->heap, DYNAMIC_TYPE_DH);
+        return MEMORY_E;
+    }
+#endif
+
+
+    if ((err = mp_init_multi(tmpX, tmpQ, NULL, NULL, NULL, NULL))
+                   != MP_OKAY) {
+        XFREE(cBuf, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
+#ifdef WOLFSSL_SMALL_STACK
+        XFREE(tmpQ, key->heap, DYNAMIC_TYPE_DH);
+        XFREE(tmpX, key->heap, DYNAMIC_TYPE_DH);
+#endif
+        return err;
+    }
+
+    do {
+        /* generate N+64 bits (c) from RBG into tmpX, making sure positive.
+         * Hash_DRBG uses SHA-256 which matches maximum
+         * requested_security_strength of (L,N) */
+        err = wc_RNG_GenerateBlock(rng, cBuf, cSz);
+        if (err == MP_OKAY)
+            err = mp_read_unsigned_bin(tmpX, cBuf, cSz);
+        if (err != MP_OKAY) {
+            mp_clear(tmpX);
+            mp_clear(tmpQ);
+            XFREE(cBuf, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
+#ifdef WOLFSSL_SMALL_STACK
+            XFREE(tmpQ, key->heap, DYNAMIC_TYPE_DH);
+            XFREE(tmpX, key->heap, DYNAMIC_TYPE_DH);
+#endif
+            return err;
+        }
+    } while (mp_cmp_d(tmpX, 1) != MP_GT);
+
+    ForceZero(cBuf, cSz);
+    XFREE(cBuf, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
+
+    /* tmpQ = q - 1 */
+    if (err == MP_OKAY)
+        err = mp_copy(&key->q, tmpQ);
+
+    if (err == MP_OKAY)
+        err = mp_sub_d(tmpQ, 1, tmpQ);
+
+    /* x = c mod (q-1), tmpX holds c */
+    if (err == MP_OKAY)
+        err = mp_mod(tmpX, tmpQ, tmpX);
+
+    /* x = c mod (q-1) + 1 */
+    if (err == MP_OKAY)
+        err = mp_add_d(tmpX, 1, tmpX);
+
+    /* copy tmpX into priv */
+    if (err == MP_OKAY) {
+        pSz = mp_unsigned_bin_size(tmpX);
+        if (pSz > (int)*privSz) {
+            WOLFSSL_MSG("DH private key output buffer too small");
+            err = BAD_FUNC_ARG;
+        } else {
+            *privSz = pSz;
+            err = mp_to_unsigned_bin(tmpX, priv);
+        }
+    }
+
+    mp_forcezero(tmpX);
+    mp_clear(tmpX);
+    mp_clear(tmpQ);
+#ifdef WOLFSSL_SMALL_STACK
+    XFREE(tmpQ, key->heap, DYNAMIC_TYPE_DH);
+    XFREE(tmpX, key->heap, DYNAMIC_TYPE_DH);
+#endif
+
+    return err;
+}
+#endif /* WOLFSSL_NO_DH186 */
+#endif /* !WC_NO_RNG */
+
+static int GeneratePrivateDh(DhKey* key, WC_RNG* rng, byte* priv,
+                             word32* privSz)
+{
+#ifndef WC_NO_RNG
+    int ret = 0;
+    word32 sz = 0;
+
+#ifndef WOLFSSL_NO_DH186
+    if (mp_iszero(&key->q) == MP_NO) {
+
+        /* q param available, use NIST FIPS 186-4, "B.1.1 Key Pair
+         * Generation Using Extra Random Bits" */
+        ret = GeneratePrivateDh186(key, rng, priv, privSz);
+
+    } else
+#endif
+    {
+
+        sz = mp_unsigned_bin_size(&key->p);
+
+        /* Table of predetermined values from the operation
+           2 * DiscreteLogWorkFactor(sz * WOLFSSL_BIT_SIZE) /
+           WOLFSSL_BIT_SIZE + 1
+           Sizes in table checked against RFC 3526
+         */
+        WOLFSSL_DH_ROUND(sz); /* if using fixed points only, then round up */
+        switch (sz) {
+            case 128:  sz = 21; break;
+            case 256:  sz = 29; break;
+            case 384:  sz = 34; break;
+            case 512:  sz = 39; break;
+            case 640:  sz = 42; break;
+            case 768:  sz = 46; break;
+            case 896:  sz = 49; break;
+            case 1024: sz = 52; break;
+            default:
+            #ifndef WOLFSSL_DH_CONST
+                /* if using floating points and size of p is not in table */
+                sz = min(sz, 2 * DiscreteLogWorkFactor(sz * WOLFSSL_BIT_SIZE) /
+                                           WOLFSSL_BIT_SIZE + 1);
+                break;
+            #else
+                return BAD_FUNC_ARG;
+            #endif
+        }
+
+        ret = wc_RNG_GenerateBlock(rng, priv, sz);
+
+        if (ret == 0) {
+            priv[0] |= 0x0C;
+            *privSz = sz;
+        }
+    }
+
+    return ret;
+#else
+    (void)key;
+    (void)rng;
+    (void)priv;
+    (void)privSz;
+    return NOT_COMPILED_IN;
+#endif /* WC_NO_RNG */
+}
+
+
+static int GeneratePublicDh(DhKey* key, byte* priv, word32 privSz,
+    byte* pub, word32* pubSz)
+{
+    int ret = 0;
+#ifndef WOLFSSL_SP_MATH
+#ifdef WOLFSSL_SMALL_STACK
+    mp_int* x;
+    mp_int* y;
+#else
+    mp_int x[1];
+    mp_int y[1];
+#endif
+#endif
+
+#ifdef WOLFSSL_HAVE_SP_DH
+#ifndef WOLFSSL_SP_NO_2048
+    if (mp_count_bits(&key->p) == 2048)
+        return sp_DhExp_2048(&key->g, priv, privSz, &key->p, pub, pubSz);
+#endif
+#ifndef WOLFSSL_SP_NO_3072
+    if (mp_count_bits(&key->p) == 3072)
+        return sp_DhExp_3072(&key->g, priv, privSz, &key->p, pub, pubSz);
+#endif
+#ifdef WOLFSSL_SP_4096
+    if (mp_count_bits(&key->p) == 4096)
+        return sp_DhExp_4096(&key->g, priv, privSz, &key->p, pub, pubSz);
+#endif
+#endif
+
+#ifndef WOLFSSL_SP_MATH
+#ifdef WOLFSSL_SMALL_STACK
+    x = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_DH);
+    if (x == NULL)
+        return MEMORY_E;
+    y = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_DH);
+    if (y == NULL) {
+        XFREE(x, key->heap, DYNAMIC_TYPE_DH);
+        return MEMORY_E;
+    }
+#endif
+    if (mp_init_multi(x, y, 0, 0, 0, 0) != MP_OKAY) {
+    #ifdef WOLFSSL_SMALL_STACK
+        XFREE(y, key->heap, DYNAMIC_TYPE_DH);
+        XFREE(x, key->heap, DYNAMIC_TYPE_DH);
+    #endif
+        return MP_INIT_E;
+    }
+
+    if (mp_read_unsigned_bin(x, priv, privSz) != MP_OKAY)
+        ret = MP_READ_E;
+
+    if (ret == 0 && mp_exptmod(&key->g, x, &key->p, y) != MP_OKAY)
+        ret = MP_EXPTMOD_E;
+
+    if (ret == 0 && mp_to_unsigned_bin(y, pub) != MP_OKAY)
+        ret = MP_TO_E;
+
+    if (ret == 0)
+        *pubSz = mp_unsigned_bin_size(y);
+
+    mp_clear(y);
+    mp_clear(x);
+#ifdef WOLFSSL_SMALL_STACK
+    XFREE(y, key->heap, DYNAMIC_TYPE_DH);
+    XFREE(x, key->heap, DYNAMIC_TYPE_DH);
+#endif
+#else
+    ret = WC_KEY_SIZE_E;
+#endif
+
+    return ret;
+}
+
+static int wc_DhGenerateKeyPair_Sync(DhKey* key, WC_RNG* rng,
+    byte* priv, word32* privSz, byte* pub, word32* pubSz)
+{
+    int ret;
+
+    if (key == NULL || rng == NULL || priv == NULL || privSz == NULL ||
+        pub == NULL || pubSz == NULL) {
+        return BAD_FUNC_ARG;
+    }
+
+    ret = GeneratePrivateDh(key, rng, priv, privSz);
+
+    return (ret != 0) ? ret : GeneratePublicDh(key, priv, *privSz, pub, pubSz);
+}
+
+#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_DH)
+static int wc_DhGenerateKeyPair_Async(DhKey* key, WC_RNG* rng,
+    byte* priv, word32* privSz, byte* pub, word32* pubSz)
+{
+    int ret;
+
+#if defined(HAVE_INTEL_QA)
+    word32 pBits;
+
+    /* QAT DH sizes: 768, 1024, 1536, 2048, 3072 and 4096 bits */
+    pBits = mp_unsigned_bin_size(&key->p) * 8;
+    if (pBits == 768 ||  pBits == 1024 || pBits == 1536 ||
+        pBits == 2048 || pBits == 3072 || pBits == 4096) {
+        mp_int x;
+
+        ret = mp_init(&x);
+        if (ret != MP_OKAY)
+            return ret;
+
+        ret = GeneratePrivateDh(key, rng, priv, privSz);
+        if (ret == 0)
+            ret = mp_read_unsigned_bin(&x, priv, *privSz);
+        if (ret == MP_OKAY)
+            ret = wc_mp_to_bigint(&x, &x.raw);
+        if (ret == MP_OKAY)
+            ret = wc_mp_to_bigint(&key->p, &key->p.raw);
+        if (ret == MP_OKAY)
+            ret = wc_mp_to_bigint(&key->g, &key->g.raw);
+        if (ret == MP_OKAY)
+            ret = IntelQaDhKeyGen(&key->asyncDev, &key->p.raw, &key->g.raw,
+                &x.raw, pub, pubSz);
+        mp_clear(&x);
+
+        return ret;
+    }
+
+#elif defined(HAVE_CAVIUM)
+    /* TODO: Not implemented - use software for now */
+
+#else /* WOLFSSL_ASYNC_CRYPT_TEST */
+    if (wc_AsyncTestInit(&key->asyncDev, ASYNC_TEST_DH_GEN)) {
+        WC_ASYNC_TEST* testDev = &key->asyncDev.test;
+        testDev->dhGen.key = key;
+        testDev->dhGen.rng = rng;
+        testDev->dhGen.priv = priv;
+        testDev->dhGen.privSz = privSz;
+        testDev->dhGen.pub = pub;
+        testDev->dhGen.pubSz = pubSz;
+        return WC_PENDING_E;
+    }
+#endif
+
+    /* otherwise use software DH */
+    ret = wc_DhGenerateKeyPair_Sync(key, rng, priv, privSz, pub, pubSz);
+
+    return ret;
+}
+#endif /* WOLFSSL_ASYNC_CRYPT && WC_ASYNC_ENABLE_DH */
+
+
+/* Check DH Public Key for invalid numbers, optionally allowing
+ * the public key to be checked against the large prime (q).
+ * Check per process in SP 800-56Ar3, section 5.6.2.3.1.
+ *
+ * key     DH key group parameters.
+ * pub     Public Key.
+ * pubSz   Public Key size.
+ * prime   Large prime (q), optionally NULL to skip check
+ * primeSz Size of large prime
+ *
+ *  returns 0 on success or error code
+ */
+int wc_DhCheckPubKey_ex(DhKey* key, const byte* pub, word32 pubSz,
+                        const byte* prime, word32 primeSz)
+{
+    int ret = 0;
+#ifdef WOLFSSL_SMALL_STACK
+    mp_int* y = NULL;
+    mp_int* p = NULL;
+    mp_int* q = NULL;
+#else
+    mp_int y[1];
+    mp_int p[1];
+    mp_int q[1];
+#endif
+
+    if (key == NULL || pub == NULL) {
+        return BAD_FUNC_ARG;
+    }
+
+#ifdef WOLFSSL_SMALL_STACK
+    y = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_DH);
+    if (y == NULL)
+        return MEMORY_E;
+    p = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_DH);
+    if (p == NULL) {
+        XFREE(y, key->heap, DYNAMIC_TYPE_DH);
+        return MEMORY_E;
+    }
+    q = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_DH);
+    if (q == NULL) {
+        XFREE(p, key->heap, DYNAMIC_TYPE_DH);
+        XFREE(y, key->heap, DYNAMIC_TYPE_DH);
+        return MEMORY_E;
+    }
+#endif
+
+    if (mp_init_multi(y, p, q, NULL, NULL, NULL) != MP_OKAY) {
+    #ifdef WOLFSSL_SMALL_STACK
+        XFREE(q, key->heap, DYNAMIC_TYPE_DH);
+        XFREE(p, key->heap, DYNAMIC_TYPE_DH);
+        XFREE(y, key->heap, DYNAMIC_TYPE_DH);
+    #endif
+        return MP_INIT_E;
+    }
+
+    if (mp_read_unsigned_bin(y, pub, pubSz) != MP_OKAY) {
+        ret = MP_READ_E;
+    }
+
+    if (ret == 0 && prime != NULL) {
+        if (mp_read_unsigned_bin(q, prime, primeSz) != MP_OKAY)
+            ret = MP_READ_E;
+
+    } else if (mp_iszero(&key->q) == MP_NO) {
+        /* use q available in DhKey */
+        if (mp_copy(&key->q, q) != MP_OKAY)
+            ret = MP_INIT_E;
+    }
+
+    /* SP 800-56Ar3, section 5.6.2.3.1, process step 1 */
+    /* pub (y) should not be 0 or 1 */
+    if (ret == 0 && mp_cmp_d(y, 2) == MP_LT) {
+        ret = MP_CMP_E;
+    }
+
+    /* pub (y) shouldn't be greater than or equal to p - 1 */
+    if (ret == 0 && mp_copy(&key->p, p) != MP_OKAY) {
+        ret = MP_INIT_E;
+    }
+    if (ret == 0 && mp_sub_d(p, 2, p) != MP_OKAY) {
+        ret = MP_SUB_E;
+    }
+    if (ret == 0 && mp_cmp(y, p) == MP_GT) {
+        ret = MP_CMP_E;
+    }
+
+    if (ret == 0 && (prime != NULL || (mp_iszero(&key->q) == MP_NO) )) {
+
+        /* restore key->p into p */
+        if (mp_copy(&key->p, p) != MP_OKAY)
+            ret = MP_INIT_E;
+    }
+
+    if (ret == 0 && prime != NULL) {
+#ifdef WOLFSSL_HAVE_SP_DH
+#ifndef WOLFSSL_SP_NO_2048
+        if (mp_count_bits(&key->p) == 2048) {
+            ret = sp_ModExp_2048(y, q, p, y);
+            if (ret != 0)
+                ret = MP_EXPTMOD_E;
+        }
+        else
+#endif
+#ifndef WOLFSSL_SP_NO_3072
+        if (mp_count_bits(&key->p) == 3072) {
+            ret = sp_ModExp_3072(y, q, p, y);
+            if (ret != 0)
+                ret = MP_EXPTMOD_E;
+        }
+        else
+#endif
+#ifdef WOLFSSL_SP_NO_4096
+        if (mp_count_bits(&key->p) == 4096) {
+            ret = sp_ModExp_4096(y, q, p, y);
+            if (ret != 0)
+                ret = MP_EXPTMOD_E;
+        }
+        else
+#endif
+#endif
+
+        {
+    /* SP 800-56Ar3, section 5.6.2.3.1, process step 2 */
+#ifndef WOLFSSL_SP_MATH
+            /* calculate (y^q) mod(p), store back into y */
+            if (mp_exptmod(y, q, p, y) != MP_OKAY)
+                ret = MP_EXPTMOD_E;
+#else
+            ret = WC_KEY_SIZE_E;
+#endif
+        }
+
+        /* verify above == 1 */
+        if (ret == 0 && mp_cmp_d(y, 1) != MP_EQ)
+            ret = MP_CMP_E;
+    }
+
+    mp_clear(y);
+    mp_clear(p);
+    mp_clear(q);
+#ifdef WOLFSSL_SMALL_STACK
+    XFREE(q, key->heap, DYNAMIC_TYPE_DH);
+    XFREE(p, key->heap, DYNAMIC_TYPE_DH);
+    XFREE(y, key->heap, DYNAMIC_TYPE_DH);
+#endif
+
+    return ret;
+}
+
+
+/* Check DH Public Key for invalid numbers
+ *
+ * key   DH key group parameters.
+ * pub   Public Key.
+ * pubSz Public Key size.
+ *
+ *  returns 0 on success or error code
+ */
+int wc_DhCheckPubKey(DhKey* key, const byte* pub, word32 pubSz)
+{
+    return wc_DhCheckPubKey_ex(key, pub, pubSz, NULL, 0);
+}
+
+
+/**
+ * Quick validity check of public key value against prime.
+ * Checks are:
+ *   - Public key not 0 or 1
+ *   - Public key not equal to prime or prime - 1
+ *   - Public key not bigger than prime.
+ *
+ * prime    Big-endian encoding of prime in bytes.
+ * primeSz  Size of prime in bytes.
+ * pub      Big-endian encoding of public key in bytes.
+ * pubSz    Size of public key in bytes.
+ */
+int wc_DhCheckPubValue(const byte* prime, word32 primeSz, const byte* pub,
+                       word32 pubSz)
+{
+    int ret = 0;
+    word32 i;
+
+    for (i = 0; i < pubSz && pub[i] == 0; i++) {
+    }
+    pubSz -= i;
+    pub += i;
+
+    if (pubSz == 0 || (pubSz == 1 && pub[0] == 1))
+        ret = MP_VAL;
+    else if (pubSz == primeSz) {
+        for (i = 0; i < pubSz-1 && pub[i] == prime[i]; i++) {
+        }
+        if (i == pubSz-1 && (pub[i] == prime[i] || pub[i] == prime[i] - 1))
+            ret = MP_VAL;
+        else if (pub[i] > prime[i])
+            ret = MP_VAL;
+    }
+    else if (pubSz > primeSz)
+        ret = MP_VAL;
+
+    return ret;
+}
+
+
+/* Check DH Private Key for invalid numbers, optionally allowing
+ * the private key to be checked against the large prime (q).
+ * Check per process in SP 800-56Ar3, section 5.6.2.1.2.
+ *
+ * key     DH key group parameters.
+ * priv    Private Key.
+ * privSz  Private Key size.
+ * prime   Large prime (q), optionally NULL to skip check
+ * primeSz Size of large prime
+ *
+ *  returns 0 on success or error code
+ */
+int wc_DhCheckPrivKey_ex(DhKey* key, const byte* priv, word32 privSz,
+                         const byte* prime, word32 primeSz)
+{
+    int ret = 0;
+#ifdef WOLFSSL_SMALL_STACK
+    mp_int* x = NULL;
+    mp_int* q = NULL;
+#else
+    mp_int x[1];
+    mp_int q[1];
+#endif
+
+    if (key == NULL || priv == NULL) {
+        return BAD_FUNC_ARG;
+    }
+
+#ifdef WOLFSSL_SMALL_STACK
+    x = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_DH);
+    if (x == NULL)
+        return MEMORY_E;
+    q = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_DH);
+    if (q == NULL) {
+        XFREE(x, key->heap, DYNAMIC_TYPE_DH);
+        return MEMORY_E;
+    }
+#endif
+
+    if (mp_init_multi(x, q, NULL, NULL, NULL, NULL) != MP_OKAY) {
+    #ifdef WOLFSSL_SMALL_STACK
+        XFREE(q, key->heap, DYNAMIC_TYPE_DH);
+        XFREE(x, key->heap, DYNAMIC_TYPE_DH);
+    #endif
+        return MP_INIT_E;
+    }
+
+    if (mp_read_unsigned_bin(x, priv, privSz) != MP_OKAY) {
+        ret = MP_READ_E;
+    }
+
+    if (ret == 0) {
+        if (prime != NULL) {
+            if (mp_read_unsigned_bin(q, prime, primeSz) != MP_OKAY)
+                ret = MP_READ_E;
+        }
+        else if (mp_iszero(&key->q) == MP_NO) {
+            /* use q available in DhKey */
+            if (mp_copy(&key->q, q) != MP_OKAY)
+                ret = MP_INIT_E;
+        }
+    }
+
+    /* priv (x) should not be 0 */
+    if (ret == 0) {
+        if (mp_cmp_d(x, 0) == MP_EQ)
+            ret = MP_CMP_E;
+    }
+
+    if (ret == 0) {
+        if (mp_iszero(q) == MP_NO) {
+            /* priv (x) shouldn't be greater than q - 1 */
+            if (ret == 0) {
+                if (mp_copy(&key->q, q) != MP_OKAY)
+                    ret = MP_INIT_E;
+            }
+            if (ret == 0) {
+                if (mp_sub_d(q, 1, q) != MP_OKAY)
+                    ret = MP_SUB_E;
+            }
+            if (ret == 0) {
+                if (mp_cmp(x, q) == MP_GT)
+                    ret = DH_CHECK_PRIV_E;
+            }
+        }
+    }
+
+    mp_clear(x);
+    mp_clear(q);
+#ifdef WOLFSSL_SMALL_STACK
+    XFREE(q, key->heap, DYNAMIC_TYPE_DH);
+    XFREE(x, key->heap, DYNAMIC_TYPE_DH);
+#endif
+
+    return ret;
+}
+
+
+/* Check DH Private Key for invalid numbers
+ *
+ * key    DH key group parameters.
+ * priv   Private Key.
+ * privSz Private Key size.
+ *
+ *  returns 0 on success or error code
+ */
+int wc_DhCheckPrivKey(DhKey* key, const byte* priv, word32 privSz)
+{
+    return wc_DhCheckPrivKey_ex(key, priv, privSz, NULL, 0);
+}
+
+
+/* Check DH Keys for pair-wise consistency per process in
+ * SP 800-56Ar3, section 5.6.2.1.4, method (b) for FFC.
+ *
+ * key    DH key group parameters.
+ * pub    Public Key.
+ * pubSz  Public Key size.
+ * priv   Private Key.
+ * privSz Private Key size.
+ *
+ *  returns 0 on success or error code
+ */
+int wc_DhCheckKeyPair(DhKey* key, const byte* pub, word32 pubSz,
+                      const byte* priv, word32 privSz)
+{
+#ifdef WOLFSSL_SMALL_STACK
+    mp_int* publicKey = NULL;
+    mp_int* privateKey = NULL;
+    mp_int* checkKey = NULL;
+#else
+    mp_int publicKey[1];
+    mp_int privateKey[1];
+    mp_int checkKey[1];
+#endif
+    int ret = 0;
+
+    if (key == NULL || pub == NULL || priv == NULL)
+        return BAD_FUNC_ARG;
+
+#ifdef WOLFSSL_SMALL_STACK
+    publicKey = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_DH);
+    if (publicKey == NULL)
+        return MEMORY_E;
+    privateKey = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_DH);
+    if (privateKey == NULL) {
+        XFREE(publicKey, key->heap, DYNAMIC_TYPE_DH);
+        return MEMORY_E;
+    }
+    checkKey = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_DH);
+    if (checkKey == NULL) {
+        XFREE(privateKey, key->heap, DYNAMIC_TYPE_DH);
+        XFREE(publicKey, key->heap, DYNAMIC_TYPE_DH);
+        return MEMORY_E;
+    }
+#endif
+
+    if (mp_init_multi(publicKey, privateKey, checkKey,
+                      NULL, NULL, NULL) != MP_OKAY) {
+
+    #ifdef WOLFSSL_SMALL_STACK
+        XFREE(privateKey, key->heap, DYNAMIC_TYPE_DH);
+        XFREE(publicKey, key->heap, DYNAMIC_TYPE_DH);
+        XFREE(checkKey, key->heap, DYNAMIC_TYPE_DH);
+    #endif
+        return MP_INIT_E;
+    }
+
+    /* Load the private and public keys into big integers. */
+    if (mp_read_unsigned_bin(publicKey, pub, pubSz) != MP_OKAY ||
+        mp_read_unsigned_bin(privateKey, priv, privSz) != MP_OKAY) {
+
+        ret = MP_READ_E;
+    }
+
+    /* Calculate checkKey = g^privateKey mod p */
+    if (ret == 0) {
+#ifdef WOLFSSL_HAVE_SP_DH
+#ifndef WOLFSSL_SP_NO_2048
+        if (mp_count_bits(&key->p) == 2048) {
+            ret = sp_ModExp_2048(&key->g, privateKey, &key->p, checkKey);
+            if (ret != 0)
+                ret = MP_EXPTMOD_E;
+        }
+        else
+#endif
+#ifndef WOLFSSL_SP_NO_3072
+        if (mp_count_bits(&key->p) == 3072) {
+            ret = sp_ModExp_3072(&key->g, privateKey, &key->p, checkKey);
+            if (ret != 0)
+                ret = MP_EXPTMOD_E;
+        }
+        else
+#endif
+#ifdef WOLFSSL_SP_4096
+        if (mp_count_bits(&key->p) == 4096) {
+            ret = sp_ModExp_4096(&key->g, privateKey, &key->p, checkKey);
+            if (ret != 0)
+                ret = MP_EXPTMOD_E;
+        }
+        else
+#endif
+#endif
+        {
+#ifndef WOLFSSL_SP_MATH
+            if (mp_exptmod(&key->g, privateKey, &key->p, checkKey) != MP_OKAY)
+                ret = MP_EXPTMOD_E;
+#else
+            ret = WC_KEY_SIZE_E;
+#endif
+        }
+    }
+
+    /* Compare the calculated public key to the supplied check value. */
+    if (ret == 0) {
+        if (mp_cmp(checkKey, publicKey) != MP_EQ)
+            ret = MP_CMP_E;
+    }
+
+    mp_forcezero(privateKey);
+    mp_clear(privateKey);
+    mp_clear(publicKey);
+    mp_clear(checkKey);
+#ifdef WOLFSSL_SMALL_STACK
+    XFREE(checkKey, key->heap, DYNAMIC_TYPE_DH);
+    XFREE(privateKey, key->heap, DYNAMIC_TYPE_DH);
+    XFREE(publicKey, key->heap, DYNAMIC_TYPE_DH);
+#endif
+
+    return ret;
+}
+
+
+int wc_DhGenerateKeyPair(DhKey* key, WC_RNG* rng,
+    byte* priv, word32* privSz, byte* pub, word32* pubSz)
+{
+    int ret;
+
+    if (key == NULL || rng == NULL || priv == NULL || privSz == NULL ||
+                                                pub == NULL || pubSz == NULL) {
+        return BAD_FUNC_ARG;
+    }
+
+#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_DH)
+    if (key->asyncDev.marker == WOLFSSL_ASYNC_MARKER_DH) {
+        ret = wc_DhGenerateKeyPair_Async(key, rng, priv, privSz, pub, pubSz);
+    }
+    else
+#endif
+    {
+        ret = wc_DhGenerateKeyPair_Sync(key, rng, priv, privSz, pub, pubSz);
+    }
+
+    return ret;
+}
+
+
+static int wc_DhAgree_Sync(DhKey* key, byte* agree, word32* agreeSz,
+    const byte* priv, word32 privSz, const byte* otherPub, word32 pubSz)
+{
+    int ret = 0;
+#ifdef WOLFSSL_SMALL_STACK
+    mp_int* y;
+#ifndef WOLFSSL_SP_MATH
+    mp_int* x;
+    mp_int* z;
+#endif
+#else
+    mp_int y[1];
+#ifndef WOLFSSL_SP_MATH
+    mp_int x[1];
+    mp_int z[1];
+#endif
+#endif
+
+#ifdef WOLFSSL_VALIDATE_FFC_IMPORT
+    if (wc_DhCheckPrivKey(key, priv, privSz) != 0) {
+        WOLFSSL_MSG("wc_DhAgree wc_DhCheckPrivKey failed");
+        return DH_CHECK_PRIV_E;
+    }
+
+    if (wc_DhCheckPubKey(key, otherPub, pubSz) != 0) {
+        WOLFSSL_MSG("wc_DhAgree wc_DhCheckPubKey failed");
+        return DH_CHECK_PUB_E;
+    }
+#endif
+
+#ifdef WOLFSSL_SMALL_STACK
+    y = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_DH);
+    if (y == NULL)
+        return MEMORY_E;
+#ifndef WOLFSSL_SP_MATH
+    x = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_DH);
+    if (x == NULL) {
+        XFREE(y, key->heap, DYNAMIC_TYPE_DH);
+        return MEMORY_E;
+    }
+    z = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_DH);
+    if (z == NULL) {
+        XFREE(x, key->heap, DYNAMIC_TYPE_DH);
+        XFREE(y, key->heap, DYNAMIC_TYPE_DH);
+        return MEMORY_E;
+    }
+#endif
+#endif
+
+#ifdef WOLFSSL_HAVE_SP_DH
+#ifndef WOLFSSL_SP_NO_2048
+    if (mp_count_bits(&key->p) == 2048) {
+        if (mp_init(y) != MP_OKAY)
+            return MP_INIT_E;
+
+        if (ret == 0 && mp_read_unsigned_bin(y, otherPub, pubSz) != MP_OKAY)
+            ret = MP_READ_E;
+
+        if (ret == 0)
+            ret = sp_DhExp_2048(y, priv, privSz, &key->p, agree, agreeSz);
+
+        mp_clear(y);
+    #ifdef WOLFSSL_SMALL_STACK
+    #ifndef WOLFSSL_SP_MATH
+        XFREE(z, key->heap, DYNAMIC_TYPE_DH);
+        XFREE(x, key->heap, DYNAMIC_TYPE_DH);
+    #endif
+        XFREE(y, key->heap, DYNAMIC_TYPE_DH);
+    #endif
+        return ret;
+    }
+#endif
+#ifndef WOLFSSL_SP_NO_3072
+    if (mp_count_bits(&key->p) == 3072) {
+        if (mp_init(y) != MP_OKAY)
+            return MP_INIT_E;
+
+        if (ret == 0 && mp_read_unsigned_bin(y, otherPub, pubSz) != MP_OKAY)
+            ret = MP_READ_E;
+
+        if (ret == 0)
+            ret = sp_DhExp_3072(y, priv, privSz, &key->p, agree, agreeSz);
+
+        mp_clear(y);
+    #ifdef WOLFSSL_SMALL_STACK
+    #ifndef WOLFSSL_SP_MATH
+        XFREE(z, key->heap, DYNAMIC_TYPE_DH);
+        XFREE(x, key->heap, DYNAMIC_TYPE_DH);
+    #endif
+        XFREE(y, key->heap, DYNAMIC_TYPE_DH);
+    #endif
+        return ret;
+    }
+#endif
+#ifdef WOLFSSL_SP_4096
+    if (mp_count_bits(&key->p) == 4096) {
+        if (mp_init(y) != MP_OKAY)
+            return MP_INIT_E;
+
+        if (ret == 0 && mp_read_unsigned_bin(y, otherPub, pubSz) != MP_OKAY)
+            ret = MP_READ_E;
+
+        if (ret == 0)
+            ret = sp_DhExp_4096(y, priv, privSz, &key->p, agree, agreeSz);
+
+        mp_clear(y);
+    #ifdef WOLFSSL_SMALL_STACK
+    #ifndef WOLFSSL_SP_MATH
+        XFREE(z, key->heap, DYNAMIC_TYPE_DH);
+        XFREE(x, key->heap, DYNAMIC_TYPE_DH);
+    #endif
+        XFREE(y, key->heap, DYNAMIC_TYPE_DH);
+    #endif
+        return ret;
+    }
+#endif
+#endif
+
+#ifndef WOLFSSL_SP_MATH
+    if (mp_init_multi(x, y, z, 0, 0, 0) != MP_OKAY) {
+    #ifdef WOLFSSL_SMALL_STACK
+        XFREE(z, key->heap, DYNAMIC_TYPE_DH);
+        XFREE(x, key->heap, DYNAMIC_TYPE_DH);
+        XFREE(y, key->heap, DYNAMIC_TYPE_DH);
+    #endif
+        return MP_INIT_E;
+    }
+
+    if (mp_read_unsigned_bin(x, priv, privSz) != MP_OKAY)
+        ret = MP_READ_E;
+
+    if (ret == 0 && mp_read_unsigned_bin(y, otherPub, pubSz) != MP_OKAY)
+        ret = MP_READ_E;
+
+    if (ret == 0 && mp_exptmod(y, x, &key->p, z) != MP_OKAY)
+        ret = MP_EXPTMOD_E;
+
+    /* make sure z is not one (SP800-56A, 5.7.1.1) */
+    if (ret == 0 && (mp_cmp_d(z, 1) == MP_EQ))
+        ret = MP_VAL;
+
+    if (ret == 0 && mp_to_unsigned_bin(z, agree) != MP_OKAY)
+        ret = MP_TO_E;
+
+    if (ret == 0)
+        *agreeSz = mp_unsigned_bin_size(z);
+
+    mp_clear(z);
+    mp_clear(y);
+    mp_forcezero(x);
+#endif
+
+#ifdef WOLFSSL_SMALL_STACK
+#ifndef WOLFSSL_SP_MATH
+    XFREE(z, key->heap, DYNAMIC_TYPE_DH);
+    XFREE(x, key->heap, DYNAMIC_TYPE_DH);
+#endif
+    XFREE(y, key->heap, DYNAMIC_TYPE_DH);
+#endif
+
+    return ret;
+}
+
+#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_DH)
+static int wc_DhAgree_Async(DhKey* key, byte* agree, word32* agreeSz,
+    const byte* priv, word32 privSz, const byte* otherPub, word32 pubSz)
+{
+    int ret;
+
+#if defined(HAVE_INTEL_QA)
+    word32 pBits;
+
+    /* QAT DH sizes: 768, 1024, 1536, 2048, 3072 and 4096 bits */
+    pBits = mp_unsigned_bin_size(&key->p) * 8;
+    if (pBits == 768 ||  pBits == 1024 || pBits == 1536 ||
+        pBits == 2048 || pBits == 3072 || pBits == 4096) {
+        ret = wc_mp_to_bigint(&key->p, &key->p.raw);
+        if (ret == MP_OKAY)
+            ret = IntelQaDhAgree(&key->asyncDev, &key->p.raw,
+                agree, agreeSz, priv, privSz, otherPub, pubSz);
+        return ret;
+    }
+
+#elif defined(HAVE_CAVIUM)
+    /* TODO: Not implemented - use software for now */
+
+#else /* WOLFSSL_ASYNC_CRYPT_TEST */
+    if (wc_AsyncTestInit(&key->asyncDev, ASYNC_TEST_DH_AGREE)) {
+        WC_ASYNC_TEST* testDev = &key->asyncDev.test;
+        testDev->dhAgree.key = key;
+        testDev->dhAgree.agree = agree;
+        testDev->dhAgree.agreeSz = agreeSz;
+        testDev->dhAgree.priv = priv;
+        testDev->dhAgree.privSz = privSz;
+        testDev->dhAgree.otherPub = otherPub;
+        testDev->dhAgree.pubSz = pubSz;
+        return WC_PENDING_E;
+    }
+#endif
+
+    /* otherwise use software DH */
+    ret = wc_DhAgree_Sync(key, agree, agreeSz, priv, privSz, otherPub, pubSz);
+
+    return ret;
+}
+#endif /* WOLFSSL_ASYNC_CRYPT */
+
+int wc_DhAgree(DhKey* key, byte* agree, word32* agreeSz, const byte* priv,
+            word32 privSz, const byte* otherPub, word32 pubSz)
+{
+    int ret = 0;
+
+    if (key == NULL || agree == NULL || agreeSz == NULL || priv == NULL ||
+                                                            otherPub == NULL) {
+        return BAD_FUNC_ARG;
+    }
+
+#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_DH)
+    if (key->asyncDev.marker == WOLFSSL_ASYNC_MARKER_DH) {
+        ret = wc_DhAgree_Async(key, agree, agreeSz, priv, privSz, otherPub, pubSz);
+    }
+    else
+#endif
+    {
+        ret = wc_DhAgree_Sync(key, agree, agreeSz, priv, privSz, otherPub, pubSz);
+    }
+
+    return ret;
+}
+
+#if defined(WOLFSSL_QT) || defined(OPENSSL_ALL)
+/* Sets private and public key in DhKey if both are available, otherwise sets
+    either private or public key, depending on which is available.
+    Returns WOLFSSL_SUCCESS if at least one of the keys was set. */
+WOLFSSL_LOCAL int wc_DhSetFullKeys(DhKey* key,const byte* priv_key,word32 privSz,
+                                   const byte* pub_key, word32 pubSz)
+{
+    byte havePriv = 0;
+    byte havePub = 0;
+    mp_int* keyPriv = NULL;
+    mp_int* keyPub  = NULL;
+
+    if (key == NULL) {
+        return BAD_FUNC_ARG;
+    }
+
+    havePriv = ( (priv_key != NULL) && (privSz > 0) );
+    havePub  = ( (pub_key  != NULL) && (pubSz  > 0) );
+
+    if (!havePub && !havePriv) {
+        WOLFSSL_MSG("No Public or Private Key to Set");
+        return BAD_FUNC_ARG;
+    }
+    /* Set Private Key */
+    if (havePriv == TRUE) {
+        /* may have leading 0 */
+        if (priv_key[0] == 0) {
+            privSz--; priv_key++;
+        }
+        if (mp_init(&key->priv) != MP_OKAY)
+            havePriv = FALSE;
+    }
+
+    if (havePriv == TRUE) {
+        if (mp_read_unsigned_bin(&key->priv, priv_key, privSz) != MP_OKAY) {
+            havePriv = FALSE;
+        } else {
+            keyPriv = &key->priv;
+            WOLFSSL_MSG("DH Private Key Set.");
+        }
+    }
+
+    /* Set Public Key */
+    if (havePub == TRUE) {
+        /* may have leading 0 */
+        if (pub_key[0] == 0) {
+            pubSz--; pub_key++;
+        }
+        if (mp_init(&key->pub) != MP_OKAY)
+            havePub = FALSE;
+    }
+
+    if (havePub == TRUE) {
+        if (mp_read_unsigned_bin(&key->pub, pub_key, pubSz) != MP_OKAY) {
+            havePub = FALSE;
+        } else {
+            keyPub = &key->pub;
+            WOLFSSL_MSG("DH Public Key Set.");
+        }
+    }
+    /* Free Memory if error occured */
+    if (havePriv == FALSE && keyPriv != NULL)
+        mp_clear(keyPriv);
+    if (havePub == FALSE && keyPub != NULL)
+        mp_clear(keyPub);
+
+    /* WOLFSSL_SUCCESS if private or public was set else WOLFSSL_FAILURE */
+    return havePriv || havePub;
+}
+#endif
+
+static int _DhSetKey(DhKey* key, const byte* p, word32 pSz, const byte* g,
+                   word32 gSz, const byte* q, word32 qSz, int trusted,
+                   WC_RNG* rng)
+{
+    int ret = 0;
+    mp_int* keyP = NULL;
+    mp_int* keyG = NULL;
+
+    if (key == NULL || p == NULL || g == NULL || pSz == 0 || gSz == 0) {
+        ret = BAD_FUNC_ARG;
+    }
+
+    if (ret == 0) {
+        /* may have leading 0 */
+        if (p[0] == 0) {
+            pSz--; p++;
+        }
+
+        if (g[0] == 0) {
+            gSz--; g++;
+        }
+
+        if (q != NULL) {
+            if (q[0] == 0) {
+                qSz--; q++;
+            }
+        }
+
+        if (mp_init(&key->p) != MP_OKAY)
+            ret = MP_INIT_E;
+    }
+
+    if (ret == 0) {
+        if (mp_read_unsigned_bin(&key->p, p, pSz) != MP_OKAY)
+            ret = ASN_DH_KEY_E;
+        else
+            keyP = &key->p;
+    }
+
+    if (ret == 0 && !trusted) {
+        int isPrime = 0;
+        if (rng != NULL)
+            ret = mp_prime_is_prime_ex(keyP, 8, &isPrime, rng);
+        else
+            ret = mp_prime_is_prime(keyP, 8, &isPrime);
+
+        if (ret == 0 && isPrime == 0)
+            ret = DH_CHECK_PUB_E;
+    }
+
+    if (ret == 0 && mp_init(&key->g) != MP_OKAY)
+        ret = MP_INIT_E;
+    if (ret == 0) {
+        if (mp_read_unsigned_bin(&key->g, g, gSz) != MP_OKAY)
+            ret = ASN_DH_KEY_E;
+        else
+            keyG = &key->g;
+    }
+
+    if (ret == 0 && q != NULL) {
+        if (mp_init(&key->q) != MP_OKAY)
+            ret = MP_INIT_E;
+    }
+    if (ret == 0 && q != NULL) {
+        if (mp_read_unsigned_bin(&key->q, q, qSz) != MP_OKAY)
+            ret = MP_INIT_E;
+    }
+
+    if (ret != 0 && key != NULL) {
+        if (keyG)
+            mp_clear(keyG);
+        if (keyP)
+            mp_clear(keyP);
+    }
+
+    return ret;
+}
+
+
+int wc_DhSetCheckKey(DhKey* key, const byte* p, word32 pSz, const byte* g,
+                   word32 gSz, const byte* q, word32 qSz, int trusted,
+                   WC_RNG* rng)
+{
+    return _DhSetKey(key, p, pSz, g, gSz, q, qSz, trusted, rng);
+}
+
+
+int wc_DhSetKey_ex(DhKey* key, const byte* p, word32 pSz, const byte* g,
+                   word32 gSz, const byte* q, word32 qSz)
+{
+    return _DhSetKey(key, p, pSz, g, gSz, q, qSz, 1, NULL);
+}
+
+
+/* not in asn anymore since no actual asn types used */
+int wc_DhSetKey(DhKey* key, const byte* p, word32 pSz, const byte* g,
+                word32 gSz)
+{
+    return _DhSetKey(key, p, pSz, g, gSz, NULL, 0, 1, NULL);
+}
+
+
+#ifdef WOLFSSL_KEY_GEN
+
+/* modulus_size in bits */
+int wc_DhGenerateParams(WC_RNG *rng, int modSz, DhKey *dh)
+{
+    mp_int  tmp, tmp2;
+    int     groupSz = 0, bufSz = 0,
+            primeCheckCount = 0,
+            primeCheck = MP_NO,
+            ret = 0;
+    unsigned char *buf = NULL;
+
+    if (rng == NULL || dh == NULL)
+        ret = BAD_FUNC_ARG;
+
+    /* set group size in bytes from modulus size
+     * FIPS 186-4 defines valid values (1024, 160) (2048, 256) (3072, 256)
+     */
+    if (ret == 0) {
+        switch (modSz) {
+            case 1024:
+                groupSz = 20;
+                break;
+            case 2048:
+            case 3072:
+                groupSz = 32;
+                break;
+            default:
+                ret = BAD_FUNC_ARG;
+                break;
+        }
+    }
+
+    if (ret == 0) {
+        /* modulus size in bytes */
+        modSz /= WOLFSSL_BIT_SIZE;
+        bufSz = modSz - groupSz;
+
+        /* allocate ram */
+        buf = (unsigned char *)XMALLOC(bufSz,
+                                       dh->heap, DYNAMIC_TYPE_TMP_BUFFER);
+        if (buf == NULL)
+            ret = MEMORY_E;
+    }
+
+    /* make a random string that will be multiplied against q */
+    if (ret == 0)
+        ret = wc_RNG_GenerateBlock(rng, buf, bufSz);
+
+    if (ret == 0) {
+        /* force magnitude */
+        buf[0] |= 0xC0;
+        /* force even */
+        buf[bufSz - 1] &= ~1;
+
+        if (mp_init_multi(&tmp, &tmp2, &dh->p, &dh->q, &dh->g, 0)
+                != MP_OKAY) {
+            ret = MP_INIT_E;
+        }
+    }
+
+    if (ret == 0) {
+        if (mp_read_unsigned_bin(&tmp2, buf, bufSz) != MP_OKAY)
+            ret = MP_READ_E;
+    }
+
+    /* make our prime q */
+    if (ret == 0) {
+        if (mp_rand_prime(&dh->q, groupSz, rng, NULL) != MP_OKAY)
+            ret = PRIME_GEN_E;
+    }
+
+    /* p = random * q */
+    if (ret == 0) {
+        if (mp_mul(&dh->q, &tmp2, &dh->p) != MP_OKAY)
+            ret = MP_MUL_E;
+    }
+
+    /* p = random * q + 1, so q is a prime divisor of p-1 */
+    if (ret == 0) {
+        if (mp_add_d(&dh->p, 1, &dh->p) != MP_OKAY)
+            ret = MP_ADD_E;
+    }
+
+    /* tmp = 2q  */
+    if (ret == 0) {
+        if (mp_add(&dh->q, &dh->q, &tmp) != MP_OKAY)
+            ret = MP_ADD_E;
+    }
+
+    /* loop until p is prime */
+    if (ret == 0) {
+        do {
+            if (mp_prime_is_prime_ex(&dh->p, 8, &primeCheck, rng) != MP_OKAY)
+                ret = PRIME_GEN_E;
+
+            if (primeCheck != MP_YES) {
+                /* p += 2q */
+                if (mp_add(&tmp, &dh->p, &dh->p) != MP_OKAY)
+                    ret = MP_ADD_E;
+                else
+                    primeCheckCount++;
+            }
+        } while (ret == 0 && primeCheck == MP_NO);
+    }
+
+    /* tmp2 += (2*loop_check_prime)
+     * to have p = (q * tmp2) + 1 prime
+     */
+    if ((ret == 0) && (primeCheckCount)) {
+        if (mp_add_d(&tmp2, 2 * primeCheckCount, &tmp2) != MP_OKAY)
+            ret = MP_ADD_E;
+    }
+
+    /* find a value g for which g^tmp2 != 1 */
+    if ((ret == 0) && (mp_set(&dh->g, 1) != MP_OKAY))
+        ret = MP_ZERO_E;
+
+    if (ret == 0) {
+        do {
+            if (mp_add_d(&dh->g, 1, &dh->g) != MP_OKAY)
+                ret = MP_ADD_E;
+            else if (mp_exptmod(&dh->g, &tmp2, &dh->p, &tmp) != MP_OKAY)
+                ret = MP_EXPTMOD_E;
+        } while (ret == 0 && mp_cmp_d(&tmp, 1) == MP_EQ);
+    }
+
+    if (ret == 0) {
+        /* at this point tmp generates a group of order q mod p */
+        mp_exch(&tmp, &dh->g);
+    }
+
+    /* clear the parameters if there was an error */
+    if ((ret != 0) && (dh != NULL)) {
+        mp_clear(&dh->q);
+        mp_clear(&dh->p);
+        mp_clear(&dh->g);
+    }
+
+    if (buf != NULL) {
+        ForceZero(buf, bufSz);
+        if (dh != NULL) {
+            XFREE(buf, dh->heap, DYNAMIC_TYPE_TMP_BUFFER);
+        }
+    }
+    mp_clear(&tmp);
+    mp_clear(&tmp2);
+
+    return ret;
+}
+
+
+/* Export raw DH parameters from DhKey structure
+ *
+ * dh   - pointer to initialized DhKey structure
+ * p    - output location for DH (p) parameter
+ * pSz  - [IN/OUT] size of output buffer for p, size of p
+ * q    - output location for DH (q) parameter
+ * qSz  - [IN/OUT] size of output buffer for q, size of q
+ * g    - output location for DH (g) parameter
+ * gSz  - [IN/OUT] size of output buffer for g, size of g
+ *
+ * If p, q, and g pointers are all passed in as NULL, the function
+ * will set pSz, qSz, and gSz to the required output buffer sizes for p,
+ * q, and g. In this case, the function will return LENGTH_ONLY_E.
+ *
+ * returns 0 on success, negative upon failure
+ */
+int wc_DhExportParamsRaw(DhKey* dh, byte* p, word32* pSz,
+                         byte* q, word32* qSz, byte* g, word32* gSz)
+{
+    int ret = 0;
+    word32 pLen = 0, qLen = 0, gLen = 0;
+
+    if (dh == NULL || pSz == NULL || qSz == NULL || gSz == NULL)
+        ret = BAD_FUNC_ARG;
+
+    /* get required output buffer sizes */
+    if (ret == 0) {
+        pLen = mp_unsigned_bin_size(&dh->p);
+        qLen = mp_unsigned_bin_size(&dh->q);
+        gLen = mp_unsigned_bin_size(&dh->g);
+
+        /* return buffer sizes and LENGTH_ONLY_E if buffers are NULL */
+        if (p == NULL && q == NULL && g == NULL) {
+            *pSz = pLen;
+            *qSz = qLen;
+            *gSz = gLen;
+            ret = LENGTH_ONLY_E;
+        }
+    }
+
+    if (ret == 0) {
+        if (p == NULL || q == NULL || g == NULL)
+            ret = BAD_FUNC_ARG;
+    }
+
+    /* export p */
+    if (ret == 0) {
+        if (*pSz < pLen) {
+            WOLFSSL_MSG("Output buffer for DH p parameter too small, "
+                        "required size placed into pSz");
+            *pSz = pLen;
+            ret = BUFFER_E;
+        }
+    }
+
+    if (ret == 0) {
+        *pSz = pLen;
+        if (mp_to_unsigned_bin(&dh->p, p) != MP_OKAY)
+            ret = MP_TO_E;
+    }
+
+    /* export q */
+    if (ret == 0) {
+        if (*qSz < qLen) {
+            WOLFSSL_MSG("Output buffer for DH q parameter too small, "
+                        "required size placed into qSz");
+            *qSz = qLen;
+            ret = BUFFER_E;
+        }
+    }
+
+    if (ret == 0) {
+        *qSz = qLen;
+        if (mp_to_unsigned_bin(&dh->q, q) != MP_OKAY)
+            ret = MP_TO_E;
+    }
+
+    /* export g */
+    if (ret == 0) {
+        if (*gSz < gLen) {
+            WOLFSSL_MSG("Output buffer for DH g parameter too small, "
+                        "required size placed into gSz");
+            *gSz = gLen;
+            ret = BUFFER_E;
+        }
+    }
+
+    if (ret == 0) {
+        *gSz = gLen;
+        if (mp_to_unsigned_bin(&dh->g, g) != MP_OKAY)
+            ret = MP_TO_E;
+    }
+
+    return ret;
+}
+
+#endif /* WOLFSSL_KEY_GEN */
+
+#endif /* NO_DH */
Index: azure_iot_hub_f767zi/trunk/wolfssl-4.4.0/wolfcrypt/src/dsa.c
===================================================================
--- azure_iot_hub_f767zi/trunk/wolfssl-4.4.0/wolfcrypt/src/dsa.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/wolfssl-4.4.0/wolfcrypt/src/dsa.c	(revision 457)
@@ -0,0 +1,920 @@
+/* dsa.c
+ *
+ * Copyright (C) 2006-2020 wolfSSL Inc.
+ *
+ * This file is part of wolfSSL.
+ *
+ * wolfSSL is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * wolfSSL is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
+ */
+
+
+#ifdef HAVE_CONFIG_H
+    #include <config.h>
+#endif
+
+#include <wolfssl/wolfcrypt/settings.h>
+
+#ifndef NO_DSA
+
+#include <wolfssl/wolfcrypt/random.h>
+#include <wolfssl/wolfcrypt/integer.h>
+#include <wolfssl/wolfcrypt/error-crypt.h>
+#include <wolfssl/wolfcrypt/logging.h>
+#include <wolfssl/wolfcrypt/sha.h>
+#include <wolfssl/wolfcrypt/dsa.h>
+
+#ifdef NO_INLINE
+    #include <wolfssl/wolfcrypt/misc.h>
+#else
+    #define WOLFSSL_MISC_INCLUDED
+    #include <wolfcrypt/src/misc.c>
+#endif
+
+int wc_InitDsaKey(DsaKey* key)
+{
+    if (key == NULL)
+        return BAD_FUNC_ARG;
+
+    key->type = -1;  /* haven't decided yet */
+    key->heap = NULL;
+
+    return mp_init_multi(
+        /* public  alloc parts */
+        &key->p,
+        &key->q,
+        &key->g,
+        &key->y,
+
+        /* private alloc parts */
+        &key->x,
+        NULL
+    );
+}
+
+
+int wc_InitDsaKey_h(DsaKey* key, void* h)
+{
+    int ret = wc_InitDsaKey(key);
+    if (ret == 0)
+        key->heap = h;
+
+    return ret;
+}
+
+
+void wc_FreeDsaKey(DsaKey* key)
+{
+    if (key == NULL)
+        return;
+
+    if (key->type == DSA_PRIVATE)
+        mp_forcezero(&key->x);
+
+    mp_clear(&key->x);
+    mp_clear(&key->y);
+    mp_clear(&key->g);
+    mp_clear(&key->q);
+    mp_clear(&key->p);
+}
+
+
+/* validate that (L,N) match allowed sizes from FIPS 186-4, Section 4.2.
+ * modLen - represents L, the size of p (prime modulus) in bits
+ * divLen - represents N, the size of q (prime divisor) in bits
+ * return 0 on success, -1 on error */
+static int CheckDsaLN(int modLen, int divLen)
+{
+    int ret = -1;
+
+    switch (modLen) {
+        case 1024:
+            if (divLen == 160)
+                ret = 0;
+            break;
+        case 2048:
+            if (divLen == 224 || divLen == 256)
+                ret = 0;
+            break;
+        case 3072:
+            if (divLen == 256)
+                ret = 0;
+            break;
+        default:
+            break;
+    }
+
+    return ret;
+}
+
+
+#ifdef WOLFSSL_KEY_GEN
+
+/* Create DSA key pair (&dsa->x, &dsa->y)
+ *
+ * Based on NIST FIPS 186-4,
+ * "B.1.1 Key Pair Generation Using Extra Random Bits"
+ *
+ * rng - pointer to initialized WC_RNG structure
+ * dsa - pointer to initialized DsaKey structure, will hold generated key
+ *
+ * return 0 on success, negative on error */
+int wc_MakeDsaKey(WC_RNG *rng, DsaKey *dsa)
+{
+    byte* cBuf;
+    int qSz, pSz, cSz, err;
+    mp_int tmpQ;
+
+    if (rng == NULL || dsa == NULL)
+        return BAD_FUNC_ARG;
+
+    qSz = mp_unsigned_bin_size(&dsa->q);
+    pSz = mp_unsigned_bin_size(&dsa->p);
+
+    /* verify (L,N) pair bit lengths */
+    if (CheckDsaLN(pSz * WOLFSSL_BIT_SIZE, qSz * WOLFSSL_BIT_SIZE) != 0)
+        return BAD_FUNC_ARG;
+
+    /* generate extra 64 bits so that bias from mod function is negligible */
+    cSz = qSz + (64 / WOLFSSL_BIT_SIZE);
+    cBuf = (byte*)XMALLOC(cSz, dsa->heap, DYNAMIC_TYPE_TMP_BUFFER);
+    if (cBuf == NULL) {
+        return MEMORY_E;
+    }
+
+    if ((err = mp_init_multi(&dsa->x, &dsa->y, &tmpQ, NULL, NULL, NULL))
+                   != MP_OKAY) {
+        XFREE(cBuf, dsa->heap, DYNAMIC_TYPE_TMP_BUFFER);
+        return err;
+    }
+
+    do {
+        /* generate N+64 bits (c) from RBG into &dsa->x, making sure positive.
+         * Hash_DRBG uses SHA-256 which matches maximum
+         * requested_security_strength of (L,N) */
+        err = wc_RNG_GenerateBlock(rng, cBuf, cSz);
+        if (err != MP_OKAY) {
+            mp_clear(&dsa->x);
+            mp_clear(&dsa->y);
+            mp_clear(&tmpQ);
+            XFREE(cBuf, dsa->heap, DYNAMIC_TYPE_TMP_BUFFER);
+            return err;
+        }
+
+        err = mp_read_unsigned_bin(&dsa->x, cBuf, cSz);
+        if (err != MP_OKAY) {
+            mp_clear(&dsa->x);
+            mp_clear(&dsa->y);
+            mp_clear(&tmpQ);
+            XFREE(cBuf, dsa->heap, DYNAMIC_TYPE_TMP_BUFFER);
+            return err;
+        }
+    } while (mp_cmp_d(&dsa->x, 1) != MP_GT);
+
+    XFREE(cBuf, dsa->heap, DYNAMIC_TYPE_TMP_BUFFER);
+
+    /* tmpQ = q - 1 */
+    if (err == MP_OKAY)
+        err = mp_copy(&dsa->q, &tmpQ);
+
+    if (err == MP_OKAY)
+        err = mp_sub_d(&tmpQ, 1, &tmpQ);
+
+    /* x = c mod (q-1), &dsa->x holds c */
+    if (err == MP_OKAY)
+        err = mp_mod(&dsa->x, &tmpQ, &dsa->x);
+
+    /* x = c mod (q-1) + 1 */
+    if (err == MP_OKAY)
+        err = mp_add_d(&dsa->x, 1, &dsa->x);
+
+    /* public key : y = g^x mod p */
+    if (err == MP_OKAY)
+        err = mp_exptmod_ex(&dsa->g, &dsa->x, dsa->q.used, &dsa->p, &dsa->y);
+
+    if (err == MP_OKAY)
+        dsa->type = DSA_PRIVATE;
+
+    if (err != MP_OKAY) {
+        mp_clear(&dsa->x);
+        mp_clear(&dsa->y);
+    }
+    mp_clear(&tmpQ);
+
+    return err;
+}
+
+
+/* modulus_size in bits */
+int wc_MakeDsaParameters(WC_RNG *rng, int modulus_size, DsaKey *dsa)
+{
+    mp_int  tmp, tmp2;
+    int     err, msize, qsize,
+            loop_check_prime = 0,
+            check_prime = MP_NO;
+    unsigned char   *buf;
+
+    if (rng == NULL || dsa == NULL)
+        return BAD_FUNC_ARG;
+
+    /* set group size in bytes from modulus size
+     * FIPS 186-4 defines valid values (1024, 160) (2048, 256) (3072, 256)
+     */
+    switch (modulus_size) {
+        case 1024:
+            qsize = 20;
+            break;
+        case 2048:
+        case 3072:
+            qsize = 32;
+            break;
+        default:
+            return BAD_FUNC_ARG;
+    }
+
+    /* modulus size in bytes */
+    msize = modulus_size / WOLFSSL_BIT_SIZE;
+
+    /* allocate ram */
+    buf = (unsigned char *)XMALLOC(msize - qsize,
+                                   dsa->heap, DYNAMIC_TYPE_TMP_BUFFER);
+    if (buf == NULL) {
+        return MEMORY_E;
+    }
+
+    /* make a random string that will be multiplied against q */
+    err = wc_RNG_GenerateBlock(rng, buf, msize - qsize);
+    if (err != MP_OKAY) {
+        XFREE(buf, dsa->heap, DYNAMIC_TYPE_TMP_BUFFER);
+        return err;
+    }
+
+    /* force magnitude */
+    buf[0] |= 0xC0;
+
+    /* force even */
+    buf[msize - qsize - 1] &= ~1;
+
+    if (mp_init_multi(&tmp2, &dsa->p, &dsa->q, 0, 0, 0) != MP_OKAY) {
+        mp_clear(&dsa->q);
+        XFREE(buf, dsa->heap, DYNAMIC_TYPE_TMP_BUFFER);
+        return MP_INIT_E;
+    }
+
+    err = mp_read_unsigned_bin(&tmp2, buf, msize - qsize);
+    if (err != MP_OKAY) {
+        mp_clear(&dsa->q);
+        mp_clear(&dsa->p);
+        mp_clear(&tmp2);
+        XFREE(buf, dsa->heap, DYNAMIC_TYPE_TMP_BUFFER);
+        return err;
+    }
+    XFREE(buf, dsa->heap, DYNAMIC_TYPE_TMP_BUFFER);
+
+    /* make our prime q */
+    err = mp_rand_prime(&dsa->q, qsize, rng, NULL);
+    if (err != MP_OKAY) {
+        mp_clear(&dsa->q);
+        mp_clear(&dsa->p);
+        mp_clear(&tmp2);
+        return err;
+    }
+
+    /* p = random * q */
+    err = mp_mul(&dsa->q, &tmp2, &dsa->p);
+    if (err != MP_OKAY) {
+        mp_clear(&dsa->q);
+        mp_clear(&dsa->p);
+        mp_clear(&tmp2);
+        return err;
+    }
+
+    /* p = random * q + 1, so q is a prime divisor of p-1 */
+    err = mp_add_d(&dsa->p, 1, &dsa->p);
+    if (err != MP_OKAY) {
+        mp_clear(&dsa->q);
+        mp_clear(&dsa->p);
+        mp_clear(&tmp2);
+        return err;
+    }
+
+    if (mp_init(&tmp) != MP_OKAY) {
+        mp_clear(&dsa->q);
+        mp_clear(&dsa->p);
+        mp_clear(&tmp2);
+        return MP_INIT_E;
+    }
+
+    /* tmp = 2q  */
+    err = mp_add(&dsa->q, &dsa->q, &tmp);
+    if (err != MP_OKAY) {
+        mp_clear(&dsa->q);
+        mp_clear(&dsa->p);
+        mp_clear(&tmp);
+        mp_clear(&tmp2);
+        return err;
+    }
+
+    /* loop until p is prime */
+    while (check_prime == MP_NO) {
+        err = mp_prime_is_prime_ex(&dsa->p, 8, &check_prime, rng);
+        if (err != MP_OKAY) {
+            mp_clear(&dsa->q);
+            mp_clear(&dsa->p);
+            mp_clear(&tmp);
+            mp_clear(&tmp2);
+            return err;
+        }
+
+        if (check_prime != MP_YES) {
+            /* p += 2q */
+            err = mp_add(&tmp, &dsa->p, &dsa->p);
+            if (err != MP_OKAY) {
+                mp_clear(&dsa->q);
+                mp_clear(&dsa->p);
+                mp_clear(&tmp);
+                mp_clear(&tmp2);
+                return err;
+            }
+
+            loop_check_prime++;
+        }
+    }
+
+    /* tmp2 += (2*loop_check_prime)
+     * to have p = (q * tmp2) + 1 prime
+     */
+    if (loop_check_prime) {
+        err = mp_add_d(&tmp2, 2*loop_check_prime, &tmp2);
+        if (err != MP_OKAY) {
+            mp_clear(&dsa->q);
+            mp_clear(&dsa->p);
+            mp_clear(&tmp);
+            mp_clear(&tmp2);
+            return err;
+        }
+    }
+
+    if (mp_init(&dsa->g) != MP_OKAY) {
+        mp_clear(&dsa->q);
+        mp_clear(&dsa->p);
+        mp_clear(&tmp);
+        mp_clear(&tmp2);
+        return MP_INIT_E;
+    }
+
+    /* find a value g for which g^tmp2 != 1 */
+    if (mp_set(&dsa->g, 1) != MP_OKAY) {
+        mp_clear(&dsa->q);
+        mp_clear(&dsa->p);
+        mp_clear(&tmp);
+        mp_clear(&tmp2);
+        return MP_INIT_E;
+    }
+
+    do {
+        err = mp_add_d(&dsa->g, 1, &dsa->g);
+        if (err != MP_OKAY) {
+            mp_clear(&dsa->q);
+            mp_clear(&dsa->p);
+            mp_clear(&dsa->g);
+            mp_clear(&tmp);
+            mp_clear(&tmp2);
+            return err;
+        }
+
+        err = mp_exptmod(&dsa->g, &tmp2, &dsa->p, &tmp);
+        if (err != MP_OKAY) {
+            mp_clear(&dsa->q);
+            mp_clear(&dsa->p);
+            mp_clear(&dsa->g);
+            mp_clear(&tmp);
+            mp_clear(&tmp2);
+            return err;
+        }
+
+    } while (mp_cmp_d(&tmp, 1) == MP_EQ);
+
+    /* at this point tmp generates a group of order q mod p */
+    mp_exch(&tmp, &dsa->g);
+
+    mp_clear(&tmp);
+    mp_clear(&tmp2);
+
+    return MP_OKAY;
+}
+#endif /* WOLFSSL_KEY_GEN */
+
+
+static int _DsaImportParamsRaw(DsaKey* dsa, const char* p, const char* q,
+                          const char* g, int trusted, WC_RNG* rng)
+{
+    int err;
+    word32 pSz, qSz;
+
+    if (dsa == NULL || p == NULL || q == NULL || g == NULL)
+        return BAD_FUNC_ARG;
+
+    /* read p */
+    err = mp_read_radix(&dsa->p, p, MP_RADIX_HEX);
+    if (err == MP_OKAY && !trusted) {
+        int isPrime = 1;
+        if (rng == NULL)
+            err = mp_prime_is_prime(&dsa->p, 8, &isPrime);
+        else
+            err = mp_prime_is_prime_ex(&dsa->p, 8, &isPrime, rng);
+
+        if (err == MP_OKAY) {
+            if (!isPrime)
+                err = DH_CHECK_PUB_E;
+        }
+    }
+
+    /* read q */
+    if (err == MP_OKAY)
+        err = mp_read_radix(&dsa->q, q, MP_RADIX_HEX);
+
+    /* read g */
+    if (err == MP_OKAY)
+        err = mp_read_radix(&dsa->g, g, MP_RADIX_HEX);
+
+    /* verify (L,N) pair bit lengths */
+    pSz = mp_unsigned_bin_size(&dsa->p);
+    qSz = mp_unsigned_bin_size(&dsa->q);
+
+    if (CheckDsaLN(pSz * WOLFSSL_BIT_SIZE, qSz * WOLFSSL_BIT_SIZE) != 0) {
+        WOLFSSL_MSG("Invalid DSA p or q parameter size");
+        err = BAD_FUNC_ARG;
+    }
+
+    if (err != MP_OKAY) {
+        mp_clear(&dsa->p);
+        mp_clear(&dsa->q);
+        mp_clear(&dsa->g);
+    }
+
+    return err;
+}
+
+
+/* Import raw DSA parameters into DsaKey structure for use with wc_MakeDsaKey(),
+ * input parameters (p,q,g) should be represented as ASCII hex values.
+ *
+ * dsa  - pointer to initialized DsaKey structure
+ * p    - DSA (p) parameter, ASCII hex string
+ * pSz  - length of p
+ * q    - DSA (q) parameter, ASCII hex string
+ * qSz  - length of q
+ * g    - DSA (g) parameter, ASCII hex string
+ * gSz  - length of g
+ *
+ * returns 0 on success, negative upon failure
+ */
+int wc_DsaImportParamsRaw(DsaKey* dsa, const char* p, const char* q,
+                          const char* g)
+{
+    return _DsaImportParamsRaw(dsa, p, q, g, 1, NULL);
+}
+
+
+/* Import raw DSA parameters into DsaKey structure for use with wc_MakeDsaKey(),
+ * input parameters (p,q,g) should be represented as ASCII hex values. Check
+ * that the p value is probably prime.
+ *
+ * dsa  - pointer to initialized DsaKey structure
+ * p    - DSA (p) parameter, ASCII hex string
+ * pSz  - length of p
+ * q    - DSA (q) parameter, ASCII hex string
+ * qSz  - length of q
+ * g    - DSA (g) parameter, ASCII hex string
+ * gSz  - length of g
+ * trusted - trust that p is OK
+ * rng  - random number generator for the prime test
+ *
+ * returns 0 on success, negative upon failure
+ */
+int wc_DsaImportParamsRawCheck(DsaKey* dsa, const char* p, const char* q,
+                          const char* g, int trusted, WC_RNG* rng)
+{
+    return _DsaImportParamsRaw(dsa, p, q, g, trusted, rng);
+}
+
+
+/* Export raw DSA parameters from DsaKey structure
+ *
+ * dsa  - pointer to initialized DsaKey structure
+ * p    - output location for DSA (p) parameter
+ * pSz  - [IN/OUT] size of output buffer for p, size of p
+ * q    - output location for DSA (q) parameter
+ * qSz  - [IN/OUT] size of output buffer for q, size of q
+ * g    - output location for DSA (g) parameter
+ * gSz  - [IN/OUT] size of output buffer for g, size of g
+ *
+ * If p, q, and g pointers are all passed in as NULL, the function
+ * will set pSz, qSz, and gSz to the required output buffer sizes for p,
+ * q, and g. In this case, the function will return LENGTH_ONLY_E.
+ *
+ * returns 0 on success, negative upon failure
+ */
+int wc_DsaExportParamsRaw(DsaKey* dsa, byte* p, word32* pSz,
+                          byte* q, word32* qSz, byte* g, word32* gSz)
+{
+    int err;
+    word32 pLen, qLen, gLen;
+
+    if (dsa == NULL || pSz == NULL || qSz == NULL || gSz == NULL)
+        return BAD_FUNC_ARG;
+
+    /* get required output buffer sizes */
+    pLen = mp_unsigned_bin_size(&dsa->p);
+    qLen = mp_unsigned_bin_size(&dsa->q);
+    gLen = mp_unsigned_bin_size(&dsa->g);
+
+    /* return buffer sizes and LENGTH_ONLY_E if buffers are NULL */
+    if (p == NULL && q == NULL && g == NULL) {
+        *pSz = pLen;
+        *qSz = qLen;
+        *gSz = gLen;
+        return LENGTH_ONLY_E;
+    }
+
+    if (p == NULL || q == NULL || g == NULL)
+        return BAD_FUNC_ARG;
+
+    /* export p */
+    if (*pSz < pLen) {
+        WOLFSSL_MSG("Output buffer for DSA p parameter too small, "
+                    "required size placed into pSz");
+        *pSz = pLen;
+        return BUFFER_E;
+    }
+    *pSz = pLen;
+    err = mp_to_unsigned_bin(&dsa->p, p);
+
+    /* export q */
+    if (err == MP_OKAY) {
+        if (*qSz < qLen) {
+            WOLFSSL_MSG("Output buffer for DSA q parameter too small, "
+                        "required size placed into qSz");
+            *qSz = qLen;
+            return BUFFER_E;
+        }
+        *qSz = qLen;
+        err = mp_to_unsigned_bin(&dsa->q, q);
+    }
+
+    /* export g */
+    if (err == MP_OKAY) {
+        if (*gSz < gLen) {
+            WOLFSSL_MSG("Output buffer for DSA g parameter too small, "
+                        "required size placed into gSz");
+            *gSz = gLen;
+            return BUFFER_E;
+        }
+        *gSz = gLen;
+        err = mp_to_unsigned_bin(&dsa->g, g);
+    }
+
+    return err;
+}
+
+
+/* Export raw DSA key (x, y) from DsaKey structure
+ *
+ * dsa  - pointer to initialized DsaKey structure
+ * x    - output location for private key
+ * xSz  - [IN/OUT] size of output buffer for x, size of x
+ * y    - output location for public key
+ * ySz  - [IN/OUT] size of output buffer for y, size of y
+ *
+ * If x and y pointers are all passed in as NULL, the function
+ * will set xSz and ySz to the required output buffer sizes for x
+ * and y. In this case, the function will return LENGTH_ONLY_E.
+ *
+ * returns 0 on success, negative upon failure
+ */
+int wc_DsaExportKeyRaw(DsaKey* dsa, byte* x, word32* xSz, byte* y, word32* ySz)
+{
+    int err;
+    word32 xLen, yLen;
+
+    if (dsa == NULL || xSz == NULL || ySz == NULL)
+        return BAD_FUNC_ARG;
+
+    /* get required output buffer sizes */
+    xLen = mp_unsigned_bin_size(&dsa->x);
+    yLen = mp_unsigned_bin_size(&dsa->y);
+
+    /* return buffer sizes and LENGTH_ONLY_E if buffers are NULL */
+    if (x == NULL && y == NULL) {
+        *xSz = xLen;
+        *ySz = yLen;
+        return LENGTH_ONLY_E;
+    }
+
+    if (x == NULL || y == NULL)
+        return BAD_FUNC_ARG;
+
+    /* export x */
+    if (*xSz < xLen) {
+        WOLFSSL_MSG("Output buffer for DSA private key (x) too small, "
+                    "required size placed into xSz");
+        *xSz = xLen;
+        return BUFFER_E;
+    }
+    *xSz = xLen;
+    err = mp_to_unsigned_bin(&dsa->x, x);
+
+    /* export y */
+    if (err == MP_OKAY) {
+        if (*ySz < yLen) {
+            WOLFSSL_MSG("Output buffer to DSA public key (y) too small, "
+                        "required size placed into ySz");
+            *ySz = yLen;
+            return BUFFER_E;
+        }
+        *ySz = yLen;
+        err = mp_to_unsigned_bin(&dsa->y, y);
+    }
+
+    return err;
+}
+
+
+int wc_DsaSign(const byte* digest, byte* out, DsaKey* key, WC_RNG* rng)
+{
+    mp_int  k, kInv, r, s, H;
+#ifndef WOLFSSL_MP_INVMOD_CONSTANT_TIME
+    mp_int  b;
+#endif
+    mp_int* qMinus1;
+    int     ret = 0, sz;
+    byte    buffer[DSA_HALF_SIZE];
+    byte*   tmp;  /* initial output pointer */
+
+    if (digest == NULL || out == NULL || key == NULL || rng == NULL) {
+        return BAD_FUNC_ARG;
+    }
+
+    tmp = out;
+
+    sz = min((int)sizeof(buffer), mp_unsigned_bin_size(&key->q));
+
+#ifdef WOLFSSL_MP_INVMOD_CONSTANT_TIME
+    if (mp_init_multi(&k, &kInv, &r, &s, &H, 0) != MP_OKAY)
+#else
+    if (mp_init_multi(&k, &kInv, &r, &s, &H, &b) != MP_OKAY)
+#endif
+    {
+        return MP_INIT_E;
+    }
+    qMinus1 = &kInv;
+
+    /* NIST FIPS 186-4: B.2.2
+     * Per-Message Secret Number Generation by Testing Candidates
+     * Generate k in range [1, q-1].
+     *   Check that k is less than q-1: range [0, q-2].
+     *   Add 1 to k: range [1, q-1].
+     */
+    if (mp_sub_d(&key->q, 1, qMinus1))
+        ret = MP_SUB_E;
+
+    if (ret == 0) {
+        do {
+            /* Step 4: generate k */
+            ret = wc_RNG_GenerateBlock(rng, buffer, sz);
+
+            /* Step 5 */
+            if (ret == 0 && mp_read_unsigned_bin(&k, buffer, sz) != MP_OKAY)
+                ret = MP_READ_E;
+
+            /* k is a random numnber and it should be less than q-1
+             * if k greater than repeat
+             */
+        /* Step 6 */
+        } while (ret == 0 && mp_cmp(&k, qMinus1) != MP_LT);
+    }
+    /* Step 7 */
+    if (ret == 0 && mp_add_d(&k, 1, &k) != MP_OKAY)
+        ret = MP_MOD_E;
+
+#ifdef WOLFSSL_MP_INVMOD_CONSTANT_TIME
+    /* inverse k mod q */
+    if (ret == 0 && mp_invmod(&k, &key->q, &kInv) != MP_OKAY)
+        ret = MP_INVMOD_E;
+
+    /* generate r, r = (g exp k mod p) mod q */
+    if (ret == 0 && mp_exptmod_ex(&key->g, &k, key->q.used, &key->p,
+                                                               &r) != MP_OKAY) {
+        ret = MP_EXPTMOD_E;
+    }
+
+    if (ret == 0 && mp_mod(&r, &key->q, &r) != MP_OKAY)
+        ret = MP_MOD_E;
+
+    /* generate H from sha digest */
+    if (ret == 0 && mp_read_unsigned_bin(&H, digest,WC_SHA_DIGEST_SIZE) != MP_OKAY)
+        ret = MP_READ_E;
+
+    /* generate s, s = (kInv * (H + x*r)) % q */
+    if (ret == 0 && mp_mul(&key->x, &r, &s) != MP_OKAY)
+        ret = MP_MUL_E;
+
+    if (ret == 0 && mp_add(&s, &H, &s) != MP_OKAY)
+        ret = MP_ADD_E;
+
+    if (ret == 0 && mp_mulmod(&s, &kInv, &key->q, &s) != MP_OKAY)
+        ret = MP_MULMOD_E;
+#else
+    /* Blinding value
+     * Generate b in range [1, q-1].
+     */
+    if (ret == 0) {
+        do {
+            ret = wc_RNG_GenerateBlock(rng, buffer, sz);
+            if (ret == 0 && mp_read_unsigned_bin(&b, buffer, sz) != MP_OKAY)
+                ret = MP_READ_E;
+        } while (ret == 0 && mp_cmp(&b, qMinus1) != MP_LT);
+    }
+    if (ret == 0 && mp_add_d(&b, 1, &b) != MP_OKAY)
+        ret = MP_MOD_E;
+
+    /* set H from sha digest */
+    if (ret == 0 && mp_read_unsigned_bin(&H, digest,
+                                               WC_SHA_DIGEST_SIZE) != MP_OKAY) {
+        ret = MP_READ_E;
+    }
+
+    /* generate r, r = (g exp k mod p) mod q */
+    if (ret == 0 && mp_exptmod_ex(&key->g, &k, key->q.used, &key->p,
+                                                               &r) != MP_OKAY) {
+        ret = MP_EXPTMOD_E;
+    }
+
+    /* calculate s = (H + xr)/k
+                   = b.(H/k.b + x.r/k.b) */
+
+    /* k = k.b */
+    if (ret == 0 && mp_mulmod(&k, &b, &key->q, &k) != MP_OKAY)
+        ret = MP_MULMOD_E;
+
+    /* kInv = 1/k.b mod q */
+    if (ret == 0 && mp_invmod(&k, &key->q, &kInv) != MP_OKAY)
+        ret = MP_INVMOD_E;
+
+    if (ret == 0 && mp_mod(&r, &key->q, &r) != MP_OKAY)
+        ret = MP_MOD_E;
+
+    /* s = x.r */
+    if (ret == 0 && mp_mul(&key->x, &r, &s) != MP_OKAY)
+        ret = MP_MUL_E;
+
+    /* s = x.r/k.b */
+    if (ret == 0 && mp_mulmod(&s, &kInv, &key->q, &s) != MP_OKAY)
+        ret = MP_MULMOD_E;
+
+    /* H = H/k.b */
+    if (ret == 0 && mp_mulmod(&H, &kInv, &key->q, &H) != MP_OKAY)
+        ret = MP_MULMOD_E;
+
+    /* s = H/k.b + x.r/k.b
+         = (H + x.r)/k.b */
+    if (ret == 0 && mp_add(&s, &H, &s) != MP_OKAY)
+        ret = MP_ADD_E;
+
+    /* s = b.(e + x.r)/k.b
+         = (e + x.r)/k */
+    if (ret == 0 && mp_mulmod(&s, &b, &key->q, &s) != MP_OKAY)
+        ret = MP_MULMOD_E;
+
+    /* s = (e + x.r)/k */
+    if (ret == 0 && mp_mod(&s, &key->q, &s) != MP_OKAY)
+        ret = MP_MOD_E;
+#endif
+
+    /* detect zero r or s */
+    if (ret == 0 && (mp_iszero(&r) == MP_YES || mp_iszero(&s) == MP_YES))
+        ret = MP_ZERO_E;
+
+    /* write out */
+    if (ret == 0)  {
+        int rSz = mp_unsigned_bin_size(&r);
+        int sSz = mp_unsigned_bin_size(&s);
+
+        while (rSz++ < DSA_HALF_SIZE) {
+            *out++ = 0x00;  /* pad front with zeros */
+        }
+
+        if (mp_to_unsigned_bin(&r, out) != MP_OKAY)
+            ret = MP_TO_E;
+        else {
+            out = tmp + DSA_HALF_SIZE;  /* advance to s in output */
+            while (sSz++ < DSA_HALF_SIZE) {
+                *out++ = 0x00;  /* pad front with zeros */
+            }
+            ret = mp_to_unsigned_bin(&s, out);
+        }
+    }
+
+    ForceZero(buffer, sz);
+    mp_forcezero(&kInv);
+    mp_forcezero(&k);
+#ifndef WOLFSSL_MP_INVMOD_CONSTANT_TIME
+    mp_forcezero(&b);
+
+    mp_clear(&b);
+#endif
+    mp_clear(&H);
+    mp_clear(&s);
+    mp_clear(&r);
+    mp_clear(&kInv);
+    mp_clear(&k);
+
+    return ret;
+}
+
+
+int wc_DsaVerify(const byte* digest, const byte* sig, DsaKey* key, int* answer)
+{
+    mp_int w, u1, u2, v, r, s;
+    int    ret = 0;
+
+    if (digest == NULL || sig == NULL || key == NULL || answer == NULL) {
+        return BAD_FUNC_ARG;
+    }
+
+    if (mp_init_multi(&w, &u1, &u2, &v, &r, &s) != MP_OKAY)
+        return MP_INIT_E;
+
+    /* set r and s from signature */
+    if (mp_read_unsigned_bin(&r, sig, DSA_HALF_SIZE) != MP_OKAY ||
+        mp_read_unsigned_bin(&s, sig + DSA_HALF_SIZE, DSA_HALF_SIZE) != MP_OKAY)
+        ret = MP_READ_E;
+
+    /* sanity checks */
+    if (ret == 0) {
+        if (mp_iszero(&r) == MP_YES || mp_iszero(&s) == MP_YES ||
+                mp_cmp(&r, &key->q) != MP_LT || mp_cmp(&s, &key->q) != MP_LT) {
+            ret = MP_ZERO_E;
+        }
+    }
+
+    /* put H into u1 from sha digest */
+    if (ret == 0 && mp_read_unsigned_bin(&u1,digest,WC_SHA_DIGEST_SIZE) != MP_OKAY)
+        ret = MP_READ_E;
+
+    /* w = s invmod q */
+    if (ret == 0 && mp_invmod(&s, &key->q, &w) != MP_OKAY)
+        ret = MP_INVMOD_E;
+
+    /* u1 = (H * w) % q */
+    if (ret == 0 && mp_mulmod(&u1, &w, &key->q, &u1) != MP_OKAY)
+        ret = MP_MULMOD_E;
+
+    /* u2 = (r * w) % q */
+    if (ret == 0 && mp_mulmod(&r, &w, &key->q, &u2) != MP_OKAY)
+        ret = MP_MULMOD_E;
+
+    /* verify v = ((g^u1 * y^u2) mod p) mod q */
+    if (ret == 0 && mp_exptmod(&key->g, &u1, &key->p, &u1) != MP_OKAY)
+        ret = MP_EXPTMOD_E;
+
+    if (ret == 0 && mp_exptmod(&key->y, &u2, &key->p, &u2) != MP_OKAY)
+        ret = MP_EXPTMOD_E;
+
+    if (ret == 0 && mp_mulmod(&u1, &u2, &key->p, &v) != MP_OKAY)
+        ret = MP_MULMOD_E;
+
+    if (ret == 0 && mp_mod(&v, &key->q, &v) != MP_OKAY)
+        ret = MP_MULMOD_E;
+
+    /* do they match */
+    if (ret == 0 && mp_cmp(&r, &v) == MP_EQ)
+        *answer = 1;
+    else
+        *answer = 0;
+
+    mp_clear(&s);
+    mp_clear(&r);
+    mp_clear(&u1);
+    mp_clear(&u2);
+    mp_clear(&w);
+    mp_clear(&v);
+
+    return ret;
+}
+
+
+#endif /* NO_DSA */
+
Index: azure_iot_hub_f767zi/trunk/wolfssl-4.4.0/wolfcrypt/src/ecc.c
===================================================================
--- azure_iot_hub_f767zi/trunk/wolfssl-4.4.0/wolfcrypt/src/ecc.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/wolfssl-4.4.0/wolfcrypt/src/ecc.c	(revision 457)
@@ -0,0 +1,10761 @@
+/* ecc.c
+ *
+ * Copyright (C) 2006-2020 wolfSSL Inc.
+ *
+ * This file is part of wolfSSL.
+ *
+ * wolfSSL is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * wolfSSL is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
+ */
+
+
+
+#ifdef HAVE_CONFIG_H
+    #include <config.h>
+#endif
+
+/* in case user set HAVE_ECC there */
+#include <wolfssl/wolfcrypt/settings.h>
+
+/* public ASN interface */
+#include <wolfssl/wolfcrypt/asn_public.h>
+
+/*
+Possible ECC enable options:
+ * HAVE_ECC:            Overall control of ECC                  default: on
+ * HAVE_ECC_ENCRYPT:    ECC encrypt/decrypt w/AES and HKDF      default: off
+ * HAVE_ECC_SIGN:       ECC sign                                default: on
+ * HAVE_ECC_VERIFY:     ECC verify                              default: on
+ * HAVE_ECC_DHE:        ECC build shared secret                 default: on
+ * HAVE_ECC_CDH:        ECC cofactor DH shared secret           default: off
+ * HAVE_ECC_KEY_IMPORT: ECC Key import                          default: on
+ * HAVE_ECC_KEY_EXPORT: ECC Key export                          default: on
+ * ECC_SHAMIR:          Enables Shamir calc method              default: on
+ * HAVE_COMP_KEY:       Enables compressed key                  default: off
+ * WOLFSSL_VALIDATE_ECC_IMPORT: Validate ECC key on import      default: off
+ * WOLFSSL_VALIDATE_ECC_KEYGEN: Validate ECC key gen            default: off
+ * WOLFSSL_CUSTOM_CURVES: Allow non-standard curves.            default: off
+ *                        Includes the curve "a" variable in calculation
+ * ECC_DUMP_OID:        Enables dump of OID encoding and sum    default: off
+ * ECC_CACHE_CURVE:     Enables cache of curve info to improve perofrmance
+                                                                default: off
+ * FP_ECC:              ECC Fixed Point Cache                   default: off
+ * USE_ECC_B_PARAM:     Enable ECC curve B param                default: off
+                         (on for HAVE_COMP_KEY)
+ * WOLFSSL_ECC_CURVE_STATIC:                                    default off (on for windows)
+                        For the ECC curve paramaters `ecc_set_type` use fixed
+                        array for hex string
+ */
+
+/*
+ECC Curve Types:
+ * NO_ECC_SECP          Disables SECP curves                    default: off (not defined)
+ * HAVE_ECC_SECPR2      Enables SECP R2 curves                  default: off
+ * HAVE_ECC_SECPR3      Enables SECP R3 curves                  default: off
+ * HAVE_ECC_BRAINPOOL   Enables Brainpool curves                default: off
+ * HAVE_ECC_KOBLITZ     Enables Koblitz curves                  default: off
+ */
+
+/*
+ECC Curve Sizes:
+ * ECC_USER_CURVES: Allows custom combination of key sizes below
+ * HAVE_ALL_CURVES: Enable all key sizes (on unless ECC_USER_CURVES is defined)
+ * HAVE_ECC112: 112 bit key
+ * HAVE_ECC128: 128 bit key
+ * HAVE_ECC160: 160 bit key
+ * HAVE_ECC192: 192 bit key
+ * HAVE_ECC224: 224 bit key
+ * HAVE_ECC239: 239 bit key
+ * NO_ECC256: Disables 256 bit key (on by default)
+ * HAVE_ECC320: 320 bit key
+ * HAVE_ECC384: 384 bit key
+ * HAVE_ECC512: 512 bit key
+ * HAVE_ECC521: 521 bit key
+ */
+
+
+#ifdef HAVE_ECC
+
+/* Make sure custom curves is enabled for Brainpool or Koblitz curve types */
+#if (defined(HAVE_ECC_BRAINPOOL) || defined(HAVE_ECC_KOBLITZ)) &&\
+    !defined(WOLFSSL_CUSTOM_CURVES)
+    #error Brainpool and Koblitz curves requires WOLFSSL_CUSTOM_CURVES
+#endif
+
+#if defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION >= 2)
+    /* set NO_WRAPPERS before headers, use direct internal f()s not wrappers */
+    #define FIPS_NO_WRAPPERS
+
+	#ifdef USE_WINDOWS_API
+		#pragma code_seg(".fipsA$f")
+		#pragma const_seg(".fipsB$f")
+	#endif
+#endif
+
+#include <wolfssl/wolfcrypt/ecc.h>
+#include <wolfssl/wolfcrypt/asn.h>
+#include <wolfssl/wolfcrypt/error-crypt.h>
+#include <wolfssl/wolfcrypt/logging.h>
+#include <wolfssl/wolfcrypt/types.h>
+
+#ifdef WOLFSSL_HAVE_SP_ECC
+#include <wolfssl/wolfcrypt/sp.h>
+#endif
+
+#ifdef HAVE_ECC_ENCRYPT
+    #include <wolfssl/wolfcrypt/hmac.h>
+    #include <wolfssl/wolfcrypt/aes.h>
+#endif
+
+#ifdef HAVE_X963_KDF
+    #include <wolfssl/wolfcrypt/hash.h>
+#endif
+
+#ifdef WOLF_CRYPTO_CB
+    #include <wolfssl/wolfcrypt/cryptocb.h>
+#endif
+
+#ifdef NO_INLINE
+    #include <wolfssl/wolfcrypt/misc.h>
+#else
+    #define WOLFSSL_MISC_INCLUDED
+    #include <wolfcrypt/src/misc.c>
+#endif
+
+#if defined(FREESCALE_LTC_ECC)
+    #include <wolfssl/wolfcrypt/port/nxp/ksdk_port.h>
+#endif
+
+#if defined(WOLFSSL_STM32_PKA)
+    #include <wolfssl/wolfcrypt/port/st/stm32.h>
+#endif
+
+#ifdef WOLFSSL_SP_MATH
+    #define GEN_MEM_ERR MP_MEM
+#elif defined(USE_FAST_MATH)
+    #define GEN_MEM_ERR FP_MEM
+#else
+    #define GEN_MEM_ERR MP_MEM
+#endif
+
+
+/* internal ECC states */
+enum {
+    ECC_STATE_NONE = 0,
+
+    ECC_STATE_SHARED_SEC_GEN,
+    ECC_STATE_SHARED_SEC_RES,
+
+    ECC_STATE_SIGN_DO,
+    ECC_STATE_SIGN_ENCODE,
+
+    ECC_STATE_VERIFY_DECODE,
+    ECC_STATE_VERIFY_DO,
+    ECC_STATE_VERIFY_RES,
+};
+
+
+/* map
+   ptmul -> mulmod
+*/
+
+/* 256-bit curve on by default whether user curves or not */
+#if defined(HAVE_ECC112) || defined(HAVE_ALL_CURVES)
+    #define ECC112
+#endif
+#if defined(HAVE_ECC128) || defined(HAVE_ALL_CURVES)
+    #define ECC128
+#endif
+#if defined(HAVE_ECC160) || defined(HAVE_ALL_CURVES)
+    #define ECC160
+#endif
+#if defined(HAVE_ECC192) || defined(HAVE_ALL_CURVES)
+    #define ECC192
+#endif
+#if defined(HAVE_ECC224) || defined(HAVE_ALL_CURVES)
+    #define ECC224
+#endif
+#if defined(HAVE_ECC239) || defined(HAVE_ALL_CURVES)
+    #define ECC239
+#endif
+#if !defined(NO_ECC256)  || defined(HAVE_ALL_CURVES)
+    #define ECC256
+#endif
+#if defined(HAVE_ECC320) || defined(HAVE_ALL_CURVES)
+    #define ECC320
+#endif
+#if defined(HAVE_ECC384) || defined(HAVE_ALL_CURVES)
+    #define ECC384
+#endif
+#if defined(HAVE_ECC512) || defined(HAVE_ALL_CURVES)
+    #define ECC512
+#endif
+#if defined(HAVE_ECC521) || defined(HAVE_ALL_CURVES)
+    #define ECC521
+#endif
+
+/* The encoded OID's for ECC curves */
+#ifdef ECC112
+    #ifndef NO_ECC_SECP
+        #ifdef HAVE_OID_ENCODING
+            #define CODED_SECP112R1    {1,3,132,0,6}
+            #define CODED_SECP112R1_SZ 5
+        #else
+            #define CODED_SECP112R1    {0x2B,0x81,0x04,0x00,0x06}
+            #define CODED_SECP112R1_SZ 5
+        #endif
+        #ifndef WOLFSSL_ECC_CURVE_STATIC
+            static const ecc_oid_t ecc_oid_secp112r1[] = CODED_SECP112R1;
+        #else
+            #define ecc_oid_secp112r1 CODED_SECP112R1
+        #endif
+        #define ecc_oid_secp112r1_sz CODED_SECP112R1_SZ
+    #endif /* !NO_ECC_SECP */
+    #ifdef HAVE_ECC_SECPR2
+        #ifdef HAVE_OID_ENCODING
+            #define CODED_SECP112R2    {1,3,132,0,7}
+            #define CODED_SECP112R2_SZ 5
+        #else
+            #define CODED_SECP112R2    {0x2B,0x81,0x04,0x00,0x07}
+            #define CODED_SECP112R2_SZ 5
+        #endif
+        #ifndef WOLFSSL_ECC_CURVE_STATIC
+            static const ecc_oid_t ecc_oid_secp112r2[] = CODED_SECP112R2;
+        #else
+            #define ecc_oid_secp112r2 CODED_SECP112R2
+        #endif
+        #define ecc_oid_secp112r2_sz CODED_SECP112R2_SZ
+    #endif /* HAVE_ECC_SECPR2 */
+#endif /* ECC112 */
+#ifdef ECC128
+    #ifndef NO_ECC_SECP
+        #ifdef HAVE_OID_ENCODING
+            #define CODED_SECP128R1    {1,3,132,0,28}
+            #define CODED_SECP128R1_SZ 5
+        #else
+            #define CODED_SECP128R1    {0x2B,0x81,0x04,0x00,0x1C}
+            #define CODED_SECP128R1_SZ 5
+        #endif
+        #ifndef WOLFSSL_ECC_CURVE_STATIC
+            static const ecc_oid_t ecc_oid_secp128r1[] = CODED_SECP128R1;
+        #else
+            #define ecc_oid_secp128r1 CODED_SECP128R1
+        #endif
+        #define ecc_oid_secp128r1_sz CODED_SECP128R1_SZ
+    #endif /* !NO_ECC_SECP */
+    #ifdef HAVE_ECC_SECPR2
+        #ifdef HAVE_OID_ENCODING
+            #define CODED_SECP128R2    {1,3,132,0,29}
+            #define CODED_SECP128R2_SZ 5
+        #else
+            #define CODED_SECP128R2    {0x2B,0x81,0x04,0x00,0x1D}
+            #define CODED_SECP128R2_SZ 5
+        #endif
+        #ifndef WOLFSSL_ECC_CURVE_STATIC
+            static const ecc_oid_t ecc_oid_secp128r2[] = CODED_SECP128R2;
+        #else
+            #define ecc_oid_secp128r2 CODED_SECP128R2
+        #endif
+        #define ecc_oid_secp128r2_sz CODED_SECP128R2_SZ
+    #endif /* HAVE_ECC_SECPR2 */
+#endif /* ECC128 */
+#ifdef ECC160
+    #ifndef NO_ECC_SECP
+        #ifdef HAVE_OID_ENCODING
+            #define CODED_SECP160R1    {1,3,132,0,8}
+            #define CODED_SECP160R1_SZ 5
+        #else
+            #define CODED_SECP160R1    {0x2B,0x81,0x04,0x00,0x08}
+            #define CODED_SECP160R1_SZ 5
+        #endif
+        #ifndef WOLFSSL_ECC_CURVE_STATIC
+            static const ecc_oid_t ecc_oid_secp160r1[] = CODED_SECP160R1;
+        #else
+            #define ecc_oid_secp160r1 CODED_SECP160R1
+        #endif
+        #define ecc_oid_secp160r1_sz CODED_SECP160R1_SZ
+    #endif /* !NO_ECC_SECP */
+    #ifdef HAVE_ECC_SECPR2
+        #ifdef HAVE_OID_ENCODING
+            #define CODED_SECP160R2    {1,3,132,0,30}
+            #define CODED_SECP160R2_SZ 5
+        #else
+            #define CODED_SECP160R2    {0x2B,0x81,0x04,0x00,0x1E}
+            #define CODED_SECP160R2_SZ 5
+        #endif
+        #ifndef WOLFSSL_ECC_CURVE_STATIC
+            static const ecc_oid_t ecc_oid_secp160r2[] = CODED_SECP160R2;
+        #else
+            #define ecc_oid_secp160r2 CODED_SECP160R2
+        #endif
+        #define ecc_oid_secp160r2_sz CODED_SECP160R2_SZ
+    #endif /* HAVE_ECC_SECPR2 */
+    #ifdef HAVE_ECC_KOBLITZ
+        #ifdef HAVE_OID_ENCODING
+            #define CODED_SECP160K1    {1,3,132,0,9}
+            #define CODED_SECP160K1_SZ 5
+        #else
+            #define CODED_SECP160K1    {0x2B,0x81,0x04,0x00,0x09}
+            #define CODED_SECP160K1_SZ 5
+        #endif
+        #ifndef WOLFSSL_ECC_CURVE_STATIC
+            static const ecc_oid_t ecc_oid_secp160k1[] = CODED_SECP160K1;
+        #else
+            #define ecc_oid_secp160k1 CODED_SECP160K1
+        #endif
+        #define ecc_oid_secp160k1_sz CODED_SECP160K1_SZ
+    #endif /* HAVE_ECC_KOBLITZ */
+    #ifdef HAVE_ECC_BRAINPOOL
+        #ifdef HAVE_OID_ENCODING
+            #define CODED_BRAINPOOLP160R1    {1,3,36,3,3,2,8,1,1,1}
+            #define CODED_BRAINPOOLP160R1_SZ 10
+        #else
+            #define CODED_BRAINPOOLP160R1    {0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x01}
+            #define CODED_BRAINPOOLP160R1_SZ 9
+        #endif
+        #ifndef WOLFSSL_ECC_CURVE_STATIC
+            static const ecc_oid_t ecc_oid_brainpoolp160r1[] = CODED_BRAINPOOLP160R1;
+        #else
+            #define ecc_oid_brainpoolp160r1 CODED_BRAINPOOLP160R1
+        #endif
+        #define ecc_oid_brainpoolp160r1_sz CODED_BRAINPOOLP160R1_SZ
+    #endif /* HAVE_ECC_BRAINPOOL */
+#endif /* ECC160 */
+#ifdef ECC192
+    #ifndef NO_ECC_SECP
+        #ifdef HAVE_OID_ENCODING
+            #define CODED_SECP192R1    {1,2,840,10045,3,1,1}
+            #define CODED_SECP192R1_SZ 7
+        #else
+            #define CODED_SECP192R1    {0x2A,0x86,0x48,0xCE,0x3D,0x03,0x01,0x01}
+            #define CODED_SECP192R1_SZ 8
+        #endif
+        #ifndef WOLFSSL_ECC_CURVE_STATIC
+            static const ecc_oid_t ecc_oid_secp192r1[] = CODED_SECP192R1;
+        #else
+            #define ecc_oid_secp192r1 CODED_SECP192R1
+        #endif
+        #define ecc_oid_secp192r1_sz CODED_SECP192R1_SZ
+    #endif /* !NO_ECC_SECP */
+    #ifdef HAVE_ECC_SECPR2
+        #ifdef HAVE_OID_ENCODING
+            #define CODED_PRIME192V2    {1,2,840,10045,3,1,2}
+            #define CODED_PRIME192V2_SZ 7
+        #else
+            #define CODED_PRIME192V2    {0x2A,0x86,0x48,0xCE,0x3D,0x03,0x01,0x02}
+            #define CODED_PRIME192V2_SZ 8
+        #endif
+        #ifndef WOLFSSL_ECC_CURVE_STATIC
+            static const ecc_oid_t ecc_oid_prime192v2[] = CODED_PRIME192V2;
+        #else
+            #define ecc_oid_prime192v2 CODED_PRIME192V2
+        #endif
+        #define ecc_oid_prime192v2_sz CODED_PRIME192V2_SZ
+    #endif /* HAVE_ECC_SECPR2 */
+    #ifdef HAVE_ECC_SECPR3
+        #ifdef HAVE_OID_ENCODING
+            #define CODED_PRIME192V3    {1,2,840,10045,3,1,3}
+            #define CODED_PRIME192V3_SZ 7
+        #else
+            #define CODED_PRIME192V3    {0x2A,0x86,0x48,0xCE,0x3D,0x03,0x01,0x03}
+            #define CODED_PRIME192V3_SZ 8
+        #endif
+        #ifndef WOLFSSL_ECC_CURVE_STATIC
+            static const ecc_oid_t ecc_oid_prime192v3[] = CODED_PRIME192V3;
+        #else
+            #define ecc_oid_prime192v3 CODED_PRIME192V3
+        #endif
+        #define ecc_oid_prime192v3_sz CODED_PRIME192V3_SZ
+    #endif /* HAVE_ECC_SECPR3 */
+    #ifdef HAVE_ECC_KOBLITZ
+        #ifdef HAVE_OID_ENCODING
+            #define CODED_SECP192K1    {1,3,132,0,31}
+            #define CODED_SECP192K1_SZ 5
+        #else
+            #define CODED_SECP192K1    {0x2B,0x81,0x04,0x00,0x1F}
+            #define CODED_SECP192K1_SZ 5
+        #endif
+        #ifndef WOLFSSL_ECC_CURVE_STATIC
+            static const ecc_oid_t ecc_oid_secp192k1[] = CODED_SECP192K1;
+        #else
+            #define ecc_oid_secp192k1 CODED_SECP192K1
+        #endif
+        #define ecc_oid_secp192k1_sz CODED_SECP192K1_SZ
+    #endif /* HAVE_ECC_KOBLITZ */
+    #ifdef HAVE_ECC_BRAINPOOL
+        #ifdef HAVE_OID_ENCODING
+            #define CODED_BRAINPOOLP192R1    {1,3,36,3,3,2,8,1,1,3}
+            #define CODED_BRAINPOOLP192R1_SZ 10
+        #else
+            #define CODED_BRAINPOOLP192R1    {0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x03}
+            #define CODED_BRAINPOOLP192R1_SZ 9
+        #endif
+        #ifndef WOLFSSL_ECC_CURVE_STATIC
+            static const ecc_oid_t ecc_oid_brainpoolp192r1[] = CODED_BRAINPOOLP192R1;
+        #else
+            #define ecc_oid_brainpoolp192r1 CODED_BRAINPOOLP192R1
+        #endif
+        #define ecc_oid_brainpoolp192r1_sz CODED_BRAINPOOLP192R1_SZ
+    #endif /* HAVE_ECC_BRAINPOOL */
+#endif /* ECC192 */
+#ifdef ECC224
+    #ifndef NO_ECC_SECP
+        #ifdef HAVE_OID_ENCODING
+            #define CODED_SECP224R1    {1,3,132,0,33}
+            #define CODED_SECP224R1_SZ 5
+        #else
+            #define CODED_SECP224R1    {0x2B,0x81,0x04,0x00,0x21}
+            #define CODED_SECP224R1_SZ 5
+        #endif
+        #ifndef WOLFSSL_ECC_CURVE_STATIC
+            static const ecc_oid_t ecc_oid_secp224r1[] = CODED_SECP224R1;
+        #else
+            #define ecc_oid_secp224r1 CODED_SECP224R1
+        #endif
+        #define ecc_oid_secp224r1_sz CODED_SECP224R1_SZ
+    #endif /* !NO_ECC_SECP */
+    #ifdef HAVE_ECC_KOBLITZ
+        #ifdef HAVE_OID_ENCODING
+            #define CODED_SECP224K1    {1,3,132,0,32}
+            #define CODED_SECP224K1_SZ 5
+        #else
+            #define CODED_SECP224K1    {0x2B,0x81,0x04,0x00,0x20}
+            #define CODED_SECP224K1_SZ 5
+        #endif
+        #ifndef WOLFSSL_ECC_CURVE_STATIC
+            static const ecc_oid_t ecc_oid_secp224k1[] = CODED_SECP224K1;
+        #else
+            #define ecc_oid_secp224k1 CODED_SECP224K1
+        #endif
+        #define ecc_oid_secp224k1_sz CODED_SECP224K1_SZ
+    #endif /* HAVE_ECC_KOBLITZ */
+    #ifdef HAVE_ECC_BRAINPOOL
+        #ifdef HAVE_OID_ENCODING
+            #define CODED_BRAINPOOLP224R1    {1,3,36,3,3,2,8,1,1,5}
+            #define CODED_BRAINPOOLP224R1_SZ 10
+        #else
+            #define CODED_BRAINPOOLP224R1    {0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x05}
+            #define CODED_BRAINPOOLP224R1_SZ 9
+        #endif
+        #ifndef WOLFSSL_ECC_CURVE_STATIC
+            static const ecc_oid_t ecc_oid_brainpoolp224r1[] = CODED_BRAINPOOLP224R1;
+        #else
+            #define ecc_oid_brainpoolp224r1 CODED_BRAINPOOLP224R1
+        #endif
+        #define ecc_oid_brainpoolp224r1_sz CODED_BRAINPOOLP224R1_SZ
+    #endif /* HAVE_ECC_BRAINPOOL */
+#endif /* ECC224 */
+#ifdef ECC239
+    #ifndef NO_ECC_SECP
+        #ifdef HAVE_OID_ENCODING
+            #define CODED_PRIME239V1    {1,2,840,10045,3,1,4}
+            #define CODED_PRIME239V1_SZ 7
+        #else
+            #define CODED_PRIME239V1    {0x2A,0x86,0x48,0xCE,0x3D,0x03,0x01,0x04}
+            #define CODED_PRIME239V1_SZ 8
+        #endif
+        #ifndef WOLFSSL_ECC_CURVE_STATIC
+            static const ecc_oid_t ecc_oid_prime239v1[] = CODED_PRIME239V1;
+        #else
+            #define ecc_oid_prime239v1 CODED_PRIME239V1
+        #endif
+        #define ecc_oid_prime239v1_sz CODED_PRIME239V1_SZ
+    #endif /* !NO_ECC_SECP */
+    #ifdef HAVE_ECC_SECPR2
+        #ifdef HAVE_OID_ENCODING
+            #define CODED_PRIME239V2    {1,2,840,10045,3,1,5}
+            #define CODED_PRIME239V2_SZ 7
+        #else
+            #define CODED_PRIME239V2    {0x2A,0x86,0x48,0xCE,0x3D,0x03,0x01,0x05}
+            #define CODED_PRIME239V2_SZ 8
+        #endif
+        #ifndef WOLFSSL_ECC_CURVE_STATIC
+            static const ecc_oid_t ecc_oid_prime239v2[] = CODED_PRIME239V2;
+        #else
+            #define ecc_oid_prime239v2 CODED_PRIME239V2
+        #endif
+        #define ecc_oid_prime239v2_sz CODED_PRIME239V2_SZ
+    #endif /* HAVE_ECC_SECPR2 */
+    #ifdef HAVE_ECC_SECPR3
+        #ifdef HAVE_OID_ENCODING
+            #define CODED_PRIME239V3    {1,2,840,10045,3,1,6}
+            #define CODED_PRIME239V3_SZ 7
+        #else
+            #define CODED_PRIME239V3    {0x2A,0x86,0x48,0xCE,0x3D,0x03,0x01,0x06}
+            #define CODED_PRIME239V3_SZ 8
+        #endif
+        #ifndef WOLFSSL_ECC_CURVE_STATIC
+            static const ecc_oid_t ecc_oid_prime239v3[] = CODED_PRIME239V3;
+        #else
+            #define ecc_oid_prime239v3 CODED_PRIME239V3
+        #endif
+        #define ecc_oid_prime239v3_sz CODED_PRIME239V3_SZ
+    #endif /* HAVE_ECC_SECPR3 */
+#endif /* ECC239 */
+#ifdef ECC256
+    #ifndef NO_ECC_SECP
+        #ifdef HAVE_OID_ENCODING
+            #define CODED_SECP256R1    {1,2,840,10045,3,1,7}
+            #define CODED_SECP256R1_SZ 7
+        #else
+            #define CODED_SECP256R1    {0x2A,0x86,0x48,0xCE,0x3D,0x03,0x01,0x07}
+            #define CODED_SECP256R1_SZ 8
+        #endif
+        #ifndef WOLFSSL_ECC_CURVE_STATIC
+            static const ecc_oid_t ecc_oid_secp256r1[] = CODED_SECP256R1;
+        #else
+            #define ecc_oid_secp256r1 CODED_SECP256R1
+        #endif
+        #define ecc_oid_secp256r1_sz CODED_SECP256R1_SZ
+    #endif /* !NO_ECC_SECP */
+    #ifdef HAVE_ECC_KOBLITZ
+        #ifdef HAVE_OID_ENCODING
+            #define CODED_SECP256K1    {1,3,132,0,10}
+            #define CODED_SECP256K1_SZ 5
+        #else
+            #define CODED_SECP256K1    {0x2B,0x81,0x04,0x00,0x0A}
+            #define CODED_SECP256K1_SZ 5
+        #endif
+        #ifndef WOLFSSL_ECC_CURVE_STATIC
+            static const ecc_oid_t ecc_oid_secp256k1[] = CODED_SECP256K1;
+        #else
+            #define ecc_oid_secp256k1 CODED_SECP256K1
+        #endif
+        #define ecc_oid_secp256k1_sz CODED_SECP256K1_SZ
+    #endif /* HAVE_ECC_KOBLITZ */
+    #ifdef HAVE_ECC_BRAINPOOL
+        #ifdef HAVE_OID_ENCODING
+            #define CODED_BRAINPOOLP256R1    {1,3,36,3,3,2,8,1,1,7}
+            #define CODED_BRAINPOOLP256R1_SZ 10
+        #else
+            #define CODED_BRAINPOOLP256R1    {0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x07}
+            #define CODED_BRAINPOOLP256R1_SZ 9
+        #endif
+        #ifndef WOLFSSL_ECC_CURVE_STATIC
+            static const ecc_oid_t ecc_oid_brainpoolp256r1[] = CODED_BRAINPOOLP256R1;
+        #else
+            #define ecc_oid_brainpoolp256r1 CODED_BRAINPOOLP256R1
+        #endif
+        #define ecc_oid_brainpoolp256r1_sz CODED_BRAINPOOLP256R1_SZ
+    #endif /* HAVE_ECC_BRAINPOOL */
+#endif /* ECC256 */
+#ifdef ECC320
+    #ifdef HAVE_ECC_BRAINPOOL
+        #ifdef HAVE_OID_ENCODING
+            #define CODED_BRAINPOOLP320R1    {1,3,36,3,3,2,8,1,1,9}
+            #define CODED_BRAINPOOLP320R1_SZ 10
+        #else
+            #define CODED_BRAINPOOLP320R1    {0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x09}
+            #define CODED_BRAINPOOLP320R1_SZ 9
+        #endif
+        #ifndef WOLFSSL_ECC_CURVE_STATIC
+            static const ecc_oid_t ecc_oid_brainpoolp320r1[] = CODED_BRAINPOOLP320R1;
+        #else
+            #define ecc_oid_brainpoolp320r1 CODED_BRAINPOOLP320R1
+        #endif
+        #define ecc_oid_brainpoolp320r1_sz CODED_BRAINPOOLP320R1_SZ
+    #endif /* HAVE_ECC_BRAINPOOL */
+#endif /* ECC320 */
+#ifdef ECC384
+    #ifndef NO_ECC_SECP
+        #ifdef HAVE_OID_ENCODING
+            #define CODED_SECP384R1    {1,3,132,0,34}
+            #define CODED_SECP384R1_SZ 5
+        #else
+            #define CODED_SECP384R1    {0x2B,0x81,0x04,0x00,0x22}
+            #define CODED_SECP384R1_SZ 5
+        #endif
+        #ifndef WOLFSSL_ECC_CURVE_STATIC
+            static const ecc_oid_t ecc_oid_secp384r1[] = CODED_SECP384R1;
+            #define CODED_SECP384R1_OID ecc_oid_secp384r1
+        #else
+			#define ecc_oid_secp384r1 CODED_SECP384R1
+        #endif
+        #define ecc_oid_secp384r1_sz CODED_SECP384R1_SZ
+    #endif /* !NO_ECC_SECP */
+    #ifdef HAVE_ECC_BRAINPOOL
+        #ifdef HAVE_OID_ENCODING
+            #define CODED_BRAINPOOLP384R1    {1,3,36,3,3,2,8,1,1,11}
+            #define CODED_BRAINPOOLP384R1_SZ 10
+        #else
+            #define CODED_BRAINPOOLP384R1    {0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x0B}
+            #define CODED_BRAINPOOLP384R1_SZ 9
+        #endif
+        #ifndef WOLFSSL_ECC_CURVE_STATIC
+            static const ecc_oid_t ecc_oid_brainpoolp384r1[] = CODED_BRAINPOOLP384R1;
+        #else
+            #define ecc_oid_brainpoolp384r1 CODED_BRAINPOOLP384R1
+        #endif
+        #define ecc_oid_brainpoolp384r1_sz CODED_BRAINPOOLP384R1_SZ
+    #endif /* HAVE_ECC_BRAINPOOL */
+#endif /* ECC384 */
+#ifdef ECC512
+    #ifdef HAVE_ECC_BRAINPOOL
+        #ifdef HAVE_OID_ENCODING
+            #define CODED_BRAINPOOLP512R1    {1,3,36,3,3,2,8,1,1,13}
+            #define CODED_BRAINPOOLP512R1_SZ 10
+        #else
+            #define CODED_BRAINPOOLP512R1    {0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x0D}
+            #define CODED_BRAINPOOLP512R1_SZ 9
+        #endif
+        #ifndef WOLFSSL_ECC_CURVE_STATIC
+            static const ecc_oid_t ecc_oid_brainpoolp512r1[] = CODED_BRAINPOOLP512R1;
+        #else
+            #define ecc_oid_brainpoolp512r1 CODED_BRAINPOOLP512R1
+        #endif
+        #define ecc_oid_brainpoolp512r1_sz CODED_BRAINPOOLP512R1_SZ
+    #endif /* HAVE_ECC_BRAINPOOL */
+#endif /* ECC512 */
+#ifdef ECC521
+    #ifndef NO_ECC_SECP
+        #ifdef HAVE_OID_ENCODING
+            #define CODED_SECP521R1     {1,3,132,0,35}
+            #define CODED_SECP521R1_SZ 5
+        #else
+            #define CODED_SECP521R1     {0x2B,0x81,0x04,0x00,0x23}
+            #define CODED_SECP521R1_SZ 5
+        #endif
+        #ifndef WOLFSSL_ECC_CURVE_STATIC
+            static const ecc_oid_t ecc_oid_secp521r1[] = CODED_SECP521R1;
+        #else
+            #define ecc_oid_secp521r1 CODED_SECP521R1
+        #endif
+        #define ecc_oid_secp521r1_sz CODED_SECP521R1_SZ
+    #endif /* !NO_ECC_SECP */
+#endif /* ECC521 */
+
+
+/* This holds the key settings.
+   ***MUST*** be organized by size from smallest to largest. */
+
+const ecc_set_type ecc_sets[] = {
+#ifdef ECC112
+    #ifndef NO_ECC_SECP
+    {
+        14,                             /* size/bytes */
+        ECC_SECP112R1,                  /* ID         */
+        "SECP112R1",                    /* curve name */
+        "DB7C2ABF62E35E668076BEAD208B", /* prime      */
+        "DB7C2ABF62E35E668076BEAD2088", /* A          */
+        "659EF8BA043916EEDE8911702B22", /* B          */
+        "DB7C2ABF62E35E7628DFAC6561C5", /* order      */
+        "9487239995A5EE76B55F9C2F098",  /* Gx         */
+        "A89CE5AF8724C0A23E0E0FF77500", /* Gy         */
+        ecc_oid_secp112r1,              /* oid/oidSz  */
+        ecc_oid_secp112r1_sz,
+        ECC_SECP112R1_OID,              /* oid sum    */
+        1,                              /* cofactor   */
+    },
+    #endif /* !NO_ECC_SECP */
+    #ifdef HAVE_ECC_SECPR2
+    {
+        14,                             /* size/bytes */
+        ECC_SECP112R2,                  /* ID         */
+        "SECP112R2",                    /* curve name */
+        "DB7C2ABF62E35E668076BEAD208B", /* prime      */
+        "6127C24C05F38A0AAAF65C0EF02C", /* A          */
+        "51DEF1815DB5ED74FCC34C85D709", /* B          */
+        "36DF0AAFD8B8D7597CA10520D04B", /* order      */
+        "4BA30AB5E892B4E1649DD0928643", /* Gx         */
+        "ADCD46F5882E3747DEF36E956E97", /* Gy         */
+        ecc_oid_secp112r2,              /* oid/oidSz  */
+        ecc_oid_secp112r2_sz,
+        ECC_SECP112R2_OID,              /* oid sum    */
+        4,                              /* cofactor   */
+    },
+    #endif /* HAVE_ECC_SECPR2 */
+#endif /* ECC112 */
+#ifdef ECC128
+    #ifndef NO_ECC_SECP
+    {
+        16,                                 /* size/bytes */
+        ECC_SECP128R1,                      /* ID         */
+        "SECP128R1",                        /* curve name */
+        "FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFF", /* prime      */
+        "FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFC", /* A          */
+        "E87579C11079F43DD824993C2CEE5ED3", /* B          */
+        "FFFFFFFE0000000075A30D1B9038A115", /* order      */
+        "161FF7528B899B2D0C28607CA52C5B86", /* Gx         */
+        "CF5AC8395BAFEB13C02DA292DDED7A83", /* Gy         */
+        ecc_oid_secp128r1,                  /* oid/oidSz  */
+        ecc_oid_secp128r1_sz,
+        ECC_SECP128R1_OID,                  /* oid sum    */
+        1,                                  /* cofactor   */
+    },
+    #endif /* !NO_ECC_SECP */
+    #ifdef HAVE_ECC_SECPR2
+    {
+        16,                                 /* size/bytes */
+        ECC_SECP128R2,                      /* ID         */
+        "SECP128R2",                        /* curve name */
+        "FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFF", /* prime      */
+        "D6031998D1B3BBFEBF59CC9BBFF9AEE1", /* A          */
+        "5EEEFCA380D02919DC2C6558BB6D8A5D", /* B          */
+        "3FFFFFFF7FFFFFFFBE0024720613B5A3", /* order      */
+        "7B6AA5D85E572983E6FB32A7CDEBC140", /* Gx         */
+        "27B6916A894D3AEE7106FE805FC34B44", /* Gy         */
+        ecc_oid_secp128r2,                  /* oid/oidSz  */
+        ecc_oid_secp128r2_sz,
+        ECC_SECP128R2_OID,                  /* oid sum    */
+        4,                                  /* cofactor   */
+    },
+    #endif /* HAVE_ECC_SECPR2 */
+#endif /* ECC128 */
+#ifdef ECC160
+    #ifndef NO_ECC_SECP
+    {
+        20,                                         /* size/bytes */
+        ECC_SECP160R1,                              /* ID         */
+        "SECP160R1",                                /* curve name */
+        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFF", /* prime      */
+        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFC", /* A          */
+        "1C97BEFC54BD7A8B65ACF89F81D4D4ADC565FA45", /* B          */
+        "100000000000000000001F4C8F927AED3CA752257",/* order      */
+        "4A96B5688EF573284664698968C38BB913CBFC82", /* Gx         */
+        "23A628553168947D59DCC912042351377AC5FB32", /* Gy         */
+        ecc_oid_secp160r1,                          /* oid/oidSz  */
+        ecc_oid_secp160r1_sz,
+        ECC_SECP160R1_OID,                          /* oid sum    */
+        1,                                          /* cofactor   */
+    },
+    #endif /* !NO_ECC_SECP */
+    #ifdef HAVE_ECC_SECPR2
+    {
+        20,                                         /* size/bytes */
+        ECC_SECP160R2,                              /* ID         */
+        "SECP160R2",                                /* curve name */
+        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFAC73", /* prime      */
+        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFAC70", /* A          */
+        "B4E134D3FB59EB8BAB57274904664D5AF50388BA", /* B          */
+        "100000000000000000000351EE786A818F3A1A16B",/* order      */
+        "52DCB034293A117E1F4FF11B30F7199D3144CE6D", /* Gx         */
+        "FEAFFEF2E331F296E071FA0DF9982CFEA7D43F2E", /* Gy         */
+        ecc_oid_secp160r2,                          /* oid/oidSz  */
+        ecc_oid_secp160r2_sz,
+        ECC_SECP160R2_OID,                          /* oid sum    */
+        1,                                          /* cofactor   */
+    },
+    #endif /* HAVE_ECC_SECPR2 */
+    #ifdef HAVE_ECC_KOBLITZ
+    {
+        20,                                         /* size/bytes */
+        ECC_SECP160K1,                              /* ID         */
+        "SECP160K1",                                /* curve name */
+        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFAC73", /* prime      */
+        "0000000000000000000000000000000000000000", /* A          */
+        "0000000000000000000000000000000000000007", /* B          */
+        "100000000000000000001B8FA16DFAB9ACA16B6B3",/* order      */
+        "3B4C382CE37AA192A4019E763036F4F5DD4D7EBB", /* Gx         */
+        "938CF935318FDCED6BC28286531733C3F03C4FEE", /* Gy         */
+        ecc_oid_secp160k1,                          /* oid/oidSz  */
+        ecc_oid_secp160k1_sz,
+        ECC_SECP160K1_OID,                          /* oid sum    */
+        1,                                          /* cofactor   */
+    },
+    #endif /* HAVE_ECC_KOBLITZ */
+    #ifdef HAVE_ECC_BRAINPOOL
+    {
+        20,                                         /* size/bytes */
+        ECC_BRAINPOOLP160R1,                        /* ID         */
+        "BRAINPOOLP160R1",                          /* curve name */
+        "E95E4A5F737059DC60DFC7AD95B3D8139515620F", /* prime      */
+        "340E7BE2A280EB74E2BE61BADA745D97E8F7C300", /* A          */
+        "1E589A8595423412134FAA2DBDEC95C8D8675E58", /* B          */
+        "E95E4A5F737059DC60DF5991D45029409E60FC09", /* order      */
+        "BED5AF16EA3F6A4F62938C4631EB5AF7BDBCDBC3", /* Gx         */
+        "1667CB477A1A8EC338F94741669C976316DA6321", /* Gy         */
+        ecc_oid_brainpoolp160r1,                    /* oid/oidSz  */
+        ecc_oid_brainpoolp160r1_sz,
+        ECC_BRAINPOOLP160R1_OID,                    /* oid sum    */
+        1,                                          /* cofactor   */
+    },
+    #endif /* HAVE_ECC_BRAINPOOL */
+#endif /* ECC160 */
+#ifdef ECC192
+    #ifndef NO_ECC_SECP
+    {
+        24,                                                 /* size/bytes */
+        ECC_SECP192R1,                                      /* ID         */
+        "SECP192R1",                                        /* curve name */
+        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF", /* prime      */
+        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC", /* A          */
+        "64210519E59C80E70FA7E9AB72243049FEB8DEECC146B9B1", /* B          */
+        "FFFFFFFFFFFFFFFFFFFFFFFF99DEF836146BC9B1B4D22831", /* order      */
+        "188DA80EB03090F67CBF20EB43A18800F4FF0AFD82FF1012", /* Gx         */
+        "7192B95FFC8DA78631011ED6B24CDD573F977A11E794811",  /* Gy         */
+        ecc_oid_secp192r1,                                  /* oid/oidSz  */
+        ecc_oid_secp192r1_sz,
+        ECC_SECP192R1_OID,                                  /* oid sum    */
+        1,                                                  /* cofactor   */
+    },
+    #endif /* !NO_ECC_SECP */
+    #ifdef HAVE_ECC_SECPR2
+    {
+        24,                                                 /* size/bytes */
+        ECC_PRIME192V2,                                     /* ID         */
+        "PRIME192V2",                                       /* curve name */
+        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF", /* prime      */
+        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC", /* A          */
+        "CC22D6DFB95C6B25E49C0D6364A4E5980C393AA21668D953", /* B          */
+        "FFFFFFFFFFFFFFFFFFFFFFFE5FB1A724DC80418648D8DD31", /* order      */
+        "EEA2BAE7E1497842F2DE7769CFE9C989C072AD696F48034A", /* Gx         */
+        "6574D11D69B6EC7A672BB82A083DF2F2B0847DE970B2DE15", /* Gy         */
+        ecc_oid_prime192v2,                                 /* oid/oidSz  */
+        ecc_oid_prime192v2_sz,
+        ECC_PRIME192V2_OID,                                 /* oid sum    */
+        1,                                                  /* cofactor   */
+    },
+    #endif /* HAVE_ECC_SECPR2 */
+    #ifdef HAVE_ECC_SECPR3
+    {
+        24,                                                 /* size/bytes */
+        ECC_PRIME192V3,                                     /* ID         */
+        "PRIME192V3",                                       /* curve name */
+        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF", /* prime      */
+        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC", /* A          */
+        "22123DC2395A05CAA7423DAECCC94760A7D462256BD56916", /* B          */
+        "FFFFFFFFFFFFFFFFFFFFFFFF7A62D031C83F4294F640EC13", /* order      */
+        "7D29778100C65A1DA1783716588DCE2B8B4AEE8E228F1896", /* Gx         */
+        "38A90F22637337334B49DCB66A6DC8F9978ACA7648A943B0", /* Gy         */
+        ecc_oid_prime192v3,                                 /* oid/oidSz  */
+        ecc_oid_prime192v3_sz,
+        ECC_PRIME192V3_OID,                                 /* oid sum    */
+        1,                                                  /* cofactor   */
+    },
+    #endif /* HAVE_ECC_SECPR3 */
+    #ifdef HAVE_ECC_KOBLITZ
+    {
+        24,                                                 /* size/bytes */
+        ECC_SECP192K1,                                      /* ID         */
+        "SECP192K1",                                        /* curve name */
+        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFEE37", /* prime      */
+        "000000000000000000000000000000000000000000000000", /* A          */
+        "000000000000000000000000000000000000000000000003", /* B          */
+        "FFFFFFFFFFFFFFFFFFFFFFFE26F2FC170F69466A74DEFD8D", /* order      */
+        "DB4FF10EC057E9AE26B07D0280B7F4341DA5D1B1EAE06C7D", /* Gx         */
+        "9B2F2F6D9C5628A7844163D015BE86344082AA88D95E2F9D", /* Gy         */
+        ecc_oid_secp192k1,                                  /* oid/oidSz  */
+        ecc_oid_secp192k1_sz,
+        ECC_SECP192K1_OID,                                  /* oid sum    */
+        1,                                                  /* cofactor   */
+    },
+    #endif /* HAVE_ECC_KOBLITZ */
+    #ifdef HAVE_ECC_BRAINPOOL
+    {
+        24,                                                 /* size/bytes */
+        ECC_BRAINPOOLP192R1,                                /* ID         */
+        "BRAINPOOLP192R1",                                  /* curve name */
+        "C302F41D932A36CDA7A3463093D18DB78FCE476DE1A86297", /* prime      */
+        "6A91174076B1E0E19C39C031FE8685C1CAE040E5C69A28EF", /* A          */
+        "469A28EF7C28CCA3DC721D044F4496BCCA7EF4146FBF25C9", /* B          */
+        "C302F41D932A36CDA7A3462F9E9E916B5BE8F1029AC4ACC1", /* order      */
+        "C0A0647EAAB6A48753B033C56CB0F0900A2F5C4853375FD6", /* Gx         */
+        "14B690866ABD5BB88B5F4828C1490002E6773FA2FA299B8F", /* Gy         */
+        ecc_oid_brainpoolp192r1,                            /* oid/oidSz  */
+        ecc_oid_brainpoolp192r1_sz,
+        ECC_BRAINPOOLP192R1_OID,                            /* oid sum    */
+        1,                                                  /* cofactor   */
+    },
+    #endif /* HAVE_ECC_BRAINPOOL */
+#endif /* ECC192 */
+#ifdef ECC224
+    #ifndef NO_ECC_SECP
+    {
+        28,                                                         /* size/bytes */
+        ECC_SECP224R1,                                              /* ID         */
+        "SECP224R1",                                                /* curve name */
+        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000001", /* prime      */
+        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFE", /* A          */
+        "B4050A850C04B3ABF54132565044B0B7D7BFD8BA270B39432355FFB4", /* B          */
+        "FFFFFFFFFFFFFFFFFFFFFFFFFFFF16A2E0B8F03E13DD29455C5C2A3D", /* order      */
+        "B70E0CBD6BB4BF7F321390B94A03C1D356C21122343280D6115C1D21", /* Gx         */
+        "BD376388B5F723FB4C22DFE6CD4375A05A07476444D5819985007E34", /* Gy         */
+        ecc_oid_secp224r1,                                          /* oid/oidSz  */
+        ecc_oid_secp224r1_sz,
+        ECC_SECP224R1_OID,                                          /* oid sum    */
+        1,                                                          /* cofactor   */
+    },
+    #endif /* !NO_ECC_SECP */
+    #ifdef HAVE_ECC_KOBLITZ
+    {
+        28,                                                         /* size/bytes */
+        ECC_SECP224K1,                                              /* ID         */
+        "SECP224K1",                                                /* curve name */
+        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFE56D", /* prime      */
+        "00000000000000000000000000000000000000000000000000000000", /* A          */
+        "00000000000000000000000000000000000000000000000000000005", /* B          */
+        "10000000000000000000000000001DCE8D2EC6184CAF0A971769FB1F7",/* order      */
+        "A1455B334DF099DF30FC28A169A467E9E47075A90F7E650EB6B7A45C", /* Gx         */
+        "7E089FED7FBA344282CAFBD6F7E319F7C0B0BD59E2CA4BDB556D61A5", /* Gy         */
+        ecc_oid_secp224k1,                                          /* oid/oidSz  */
+        ecc_oid_secp224k1_sz,
+        ECC_SECP224K1_OID,                                          /* oid sum    */
+        1,                                                          /* cofactor   */
+    },
+    #endif /* HAVE_ECC_KOBLITZ */
+    #ifdef HAVE_ECC_BRAINPOOL
+    {
+        28,                                                         /* size/bytes */
+        ECC_BRAINPOOLP224R1,                                        /* ID         */
+        "BRAINPOOLP224R1",                                          /* curve name */
+        "D7C134AA264366862A18302575D1D787B09F075797DA89F57EC8C0FF", /* prime      */
+        "68A5E62CA9CE6C1C299803A6C1530B514E182AD8B0042A59CAD29F43", /* A          */
+        "2580F63CCFE44138870713B1A92369E33E2135D266DBB372386C400B", /* B          */
+        "D7C134AA264366862A18302575D0FB98D116BC4B6DDEBCA3A5A7939F", /* order      */
+        "0D9029AD2C7E5CF4340823B2A87DC68C9E4CE3174C1E6EFDEE12C07D", /* Gx         */
+        "58AA56F772C0726F24C6B89E4ECDAC24354B9E99CAA3F6D3761402CD", /* Gy         */
+        ecc_oid_brainpoolp224r1,                                    /* oid/oidSz  */
+        ecc_oid_brainpoolp224r1_sz,
+        ECC_BRAINPOOLP224R1_OID,                                    /* oid sum    */
+        1,                                                          /* cofactor   */
+    },
+    #endif /* HAVE_ECC_BRAINPOOL */
+#endif /* ECC224 */
+#ifdef ECC239
+    #ifndef NO_ECC_SECP
+    {
+        30,                                                             /* size/bytes */
+        ECC_PRIME239V1,                                                 /* ID         */
+        "PRIME239V1",                                                   /* curve name */
+        "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFF", /* prime      */
+        "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFC", /* A          */
+        "6B016C3BDCF18941D0D654921475CA71A9DB2FB27D1D37796185C2942C0A", /* B          */
+        "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFF9E5E9A9F5D9071FBD1522688909D0B", /* order      */
+        "0FFA963CDCA8816CCC33B8642BEDF905C3D358573D3F27FBBD3B3CB9AAAF", /* Gx         */
+        "7DEBE8E4E90A5DAE6E4054CA530BA04654B36818CE226B39FCCB7B02F1AE", /* Gy         */
+        ecc_oid_prime239v1,                                             /* oid/oidSz  */
+        ecc_oid_prime239v1_sz,
+        ECC_PRIME239V1_OID,                                             /* oid sum    */
+        1,                                                              /* cofactor   */
+    },
+    #endif /* !NO_ECC_SECP */
+    #ifdef HAVE_ECC_SECPR2
+    {
+        30,                                                             /* size/bytes */
+        ECC_PRIME239V2,                                                 /* ID         */
+        "PRIME239V2",                                                   /* curve name */
+        "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFF", /* prime      */
+        "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFC", /* A          */
+        "617FAB6832576CBBFED50D99F0249C3FEE58B94BA0038C7AE84C8C832F2C", /* B          */
+        "7FFFFFFFFFFFFFFFFFFFFFFF800000CFA7E8594377D414C03821BC582063", /* order      */
+        "38AF09D98727705120C921BB5E9E26296A3CDCF2F35757A0EAFD87B830E7", /* Gx         */
+        "5B0125E4DBEA0EC7206DA0FC01D9B081329FB555DE6EF460237DFF8BE4BA", /* Gy         */
+        ecc_oid_prime239v2,                                             /* oid/oidSz  */
+        ecc_oid_prime239v2_sz,
+        ECC_PRIME239V2_OID,                                             /* oid sum    */
+        1,                                                              /* cofactor   */
+    },
+    #endif /* HAVE_ECC_SECPR2 */
+    #ifdef HAVE_ECC_SECPR3
+    {
+        30,                                                             /* size/bytes */
+        ECC_PRIME239V3,                                                 /* ID         */
+        "PRIME239V3",                                                   /* curve name */
+        "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFF", /* prime      */
+        "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFC", /* A          */
+        "255705FA2A306654B1F4CB03D6A750A30C250102D4988717D9BA15AB6D3E", /* B          */
+        "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFF975DEB41B3A6057C3C432146526551", /* order      */
+        "6768AE8E18BB92CFCF005C949AA2C6D94853D0E660BBF854B1C9505FE95A", /* Gx         */
+        "1607E6898F390C06BC1D552BAD226F3B6FCFE48B6E818499AF18E3ED6CF3", /* Gy         */
+        ecc_oid_prime239v3,                                             /* oid/oidSz  */
+        ecc_oid_prime239v3_sz,
+        ECC_PRIME239V3_OID,                                             /* oid sum    */
+        1,                                                              /* cofactor   */
+    },
+    #endif /* HAVE_ECC_SECPR3 */
+#endif /* ECC239 */
+#ifdef ECC256
+    #ifndef NO_ECC_SECP
+    {
+        32,                                                                 /* size/bytes */
+        ECC_SECP256R1,                                                      /* ID         */
+        "SECP256R1",                                                        /* curve name */
+        "FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF", /* prime      */
+        "FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC", /* A          */
+        "5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B", /* B          */
+        "FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551", /* order      */
+        "6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296", /* Gx         */
+        "4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5", /* Gy         */
+		ecc_oid_secp256r1,                                                  /* oid/oidSz  */
+        ecc_oid_secp256r1_sz,
+        ECC_SECP256R1_OID,                                                  /* oid sum    */
+        1,                                                                  /* cofactor   */
+    },
+    #endif /* !NO_ECC_SECP */
+    #ifdef HAVE_ECC_KOBLITZ
+    {
+        32,                                                                 /* size/bytes */
+        ECC_SECP256K1,                                                      /* ID         */
+        "SECP256K1",                                                        /* curve name */
+        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F", /* prime      */
+        "0000000000000000000000000000000000000000000000000000000000000000", /* A          */
+        "0000000000000000000000000000000000000000000000000000000000000007", /* B          */
+        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141", /* order      */
+        "79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798", /* Gx         */
+        "483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8", /* Gy         */
+        ecc_oid_secp256k1,                                                  /* oid/oidSz  */
+        ecc_oid_secp256k1_sz,
+        ECC_SECP256K1_OID,                                                  /* oid sum    */
+        1,                                                                  /* cofactor   */
+    },
+    #endif /* HAVE_ECC_KOBLITZ */
+    #ifdef HAVE_ECC_BRAINPOOL
+    {
+        32,                                                                 /* size/bytes */
+        ECC_BRAINPOOLP256R1,                                                /* ID         */
+        "BRAINPOOLP256R1",                                                  /* curve name */
+        "A9FB57DBA1EEA9BC3E660A909D838D726E3BF623D52620282013481D1F6E5377", /* prime      */
+        "7D5A0975FC2C3057EEF67530417AFFE7FB8055C126DC5C6CE94A4B44F330B5D9", /* A          */
+        "26DC5C6CE94A4B44F330B5D9BBD77CBF958416295CF7E1CE6BCCDC18FF8C07B6", /* B          */
+        "A9FB57DBA1EEA9BC3E660A909D838D718C397AA3B561A6F7901E0E82974856A7", /* order      */
+        "8BD2AEB9CB7E57CB2C4B482FFC81B7AFB9DE27E1E3BD23C23A4453BD9ACE3262", /* Gx         */
+        "547EF835C3DAC4FD97F8461A14611DC9C27745132DED8E545C1D54C72F046997", /* Gy         */
+        ecc_oid_brainpoolp256r1,                                            /* oid/oidSz  */
+        ecc_oid_brainpoolp256r1_sz,
+        ECC_BRAINPOOLP256R1_OID,                                            /* oid sum    */
+        1,                                                                  /* cofactor   */
+    },
+    #endif /* HAVE_ECC_BRAINPOOL */
+#endif /* ECC256 */
+#ifdef ECC320
+    #ifdef HAVE_ECC_BRAINPOOL
+    {
+        40,                                                                                 /* size/bytes */
+        ECC_BRAINPOOLP320R1,                                                                /* ID         */
+        "BRAINPOOLP320R1",                                                                  /* curve name */
+        "D35E472036BC4FB7E13C785ED201E065F98FCFA6F6F40DEF4F92B9EC7893EC28FCD412B1F1B32E27", /* prime      */
+        "3EE30B568FBAB0F883CCEBD46D3F3BB8A2A73513F5EB79DA66190EB085FFA9F492F375A97D860EB4", /* A          */
+        "520883949DFDBC42D3AD198640688A6FE13F41349554B49ACC31DCCD884539816F5EB4AC8FB1F1A6", /* B          */
+        "D35E472036BC4FB7E13C785ED201E065F98FCFA5B68F12A32D482EC7EE8658E98691555B44C59311", /* order      */
+        "43BD7E9AFB53D8B85289BCC48EE5BFE6F20137D10A087EB6E7871E2A10A599C710AF8D0D39E20611", /* Gx         */
+        "14FDD05545EC1CC8AB4093247F77275E0743FFED117182EAA9C77877AAAC6AC7D35245D1692E8EE1", /* Gy         */
+        ecc_oid_brainpoolp320r1, ecc_oid_brainpoolp320r1_sz,                                /* oid/oidSz  */
+        ECC_BRAINPOOLP320R1_OID,                                                            /* oid sum    */
+        1,                                                                                  /* cofactor   */
+    },
+    #endif /* HAVE_ECC_BRAINPOOL */
+#endif /* ECC320 */
+#ifdef ECC384
+    #ifndef NO_ECC_SECP
+    {
+        48,                                                                                                 /* size/bytes */
+        ECC_SECP384R1,                                                                                      /* ID         */
+        "SECP384R1",                                                                                        /* curve name */
+        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFF", /* prime      */
+        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFC", /* A          */
+        "B3312FA7E23EE7E4988E056BE3F82D19181D9C6EFE8141120314088F5013875AC656398D8A2ED19D2A85C8EDD3EC2AEF", /* B          */
+        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7634D81F4372DDF581A0DB248B0A77AECEC196ACCC52973", /* order      */
+        "AA87CA22BE8B05378EB1C71EF320AD746E1D3B628BA79B9859F741E082542A385502F25DBF55296C3A545E3872760AB7", /* Gx         */
+        "3617DE4A96262C6F5D9E98BF9292DC29F8F41DBD289A147CE9DA3113B5F0B8C00A60B1CE1D7E819D7A431D7C90EA0E5F", /* Gy         */
+        ecc_oid_secp384r1, ecc_oid_secp384r1_sz,                                                            /* oid/oidSz  */
+        ECC_SECP384R1_OID,                                                                                  /* oid sum    */
+        1,                                                                                                  /* cofactor   */
+    },
+    #endif /* !NO_ECC_SECP */
+    #ifdef HAVE_ECC_BRAINPOOL
+    {
+        48,                                                                                                 /* size/bytes */
+        ECC_BRAINPOOLP384R1,                                                                                /* ID         */
+        "BRAINPOOLP384R1",                                                                                  /* curve name */
+        "8CB91E82A3386D280F5D6F7E50E641DF152F7109ED5456B412B1DA197FB71123ACD3A729901D1A71874700133107EC53", /* prime      */
+        "7BC382C63D8C150C3C72080ACE05AFA0C2BEA28E4FB22787139165EFBA91F90F8AA5814A503AD4EB04A8C7DD22CE2826", /* A          */
+        "04A8C7DD22CE28268B39B55416F0447C2FB77DE107DCD2A62E880EA53EEB62D57CB4390295DBC9943AB78696FA504C11", /* B          */
+        "8CB91E82A3386D280F5D6F7E50E641DF152F7109ED5456B31F166E6CAC0425A7CF3AB6AF6B7FC3103B883202E9046565", /* order      */
+        "1D1C64F068CF45FFA2A63A81B7C13F6B8847A3E77EF14FE3DB7FCAFE0CBD10E8E826E03436D646AAEF87B2E247D4AF1E", /* Gx         */
+        "8ABE1D7520F9C2A45CB1EB8E95CFD55262B70B29FEEC5864E19C054FF99129280E4646217791811142820341263C5315", /* Gy         */
+        ecc_oid_brainpoolp384r1, ecc_oid_brainpoolp384r1_sz,                                                /* oid/oidSz  */
+        ECC_BRAINPOOLP384R1_OID,                                                                            /* oid sum    */
+        1,                                                                                                  /* cofactor   */
+    },
+    #endif /* HAVE_ECC_BRAINPOOL */
+#endif /* ECC384 */
+#ifdef ECC512
+    #ifdef HAVE_ECC_BRAINPOOL
+    {
+        64,                                                                                                                                 /* size/bytes */
+        ECC_BRAINPOOLP512R1,                                                                                                                /* ID         */
+        "BRAINPOOLP512R1",                                                                                                                  /* curve name */
+        "AADD9DB8DBE9C48B3FD4E6AE33C9FC07CB308DB3B3C9D20ED6639CCA703308717D4D9B009BC66842AECDA12AE6A380E62881FF2F2D82C68528AA6056583A48F3", /* prime      */
+        "7830A3318B603B89E2327145AC234CC594CBDD8D3DF91610A83441CAEA9863BC2DED5D5AA8253AA10A2EF1C98B9AC8B57F1117A72BF2C7B9E7C1AC4D77FC94CA", /* A          */
+        "3DF91610A83441CAEA9863BC2DED5D5AA8253AA10A2EF1C98B9AC8B57F1117A72BF2C7B9E7C1AC4D77FC94CADC083E67984050B75EBAE5DD2809BD638016F723", /* B          */
+        "AADD9DB8DBE9C48B3FD4E6AE33C9FC07CB308DB3B3C9D20ED6639CCA70330870553E5C414CA92619418661197FAC10471DB1D381085DDADDB58796829CA90069", /* order      */
+        "81AEE4BDD82ED9645A21322E9C4C6A9385ED9F70B5D916C1B43B62EEF4D0098EFF3B1F78E2D0D48D50D1687B93B97D5F7C6D5047406A5E688B352209BCB9F822", /* Gx         */
+        "7DDE385D566332ECC0EABFA9CF7822FDF209F70024A57B1AA000C55B881F8111B2DCDE494A5F485E5BCA4BD88A2763AED1CA2B2FA8F0540678CD1E0F3AD80892", /* Gy         */
+        ecc_oid_brainpoolp512r1, ecc_oid_brainpoolp512r1_sz,                                                                                /* oid/oidSz  */
+        ECC_BRAINPOOLP512R1_OID,                                                                                                            /* oid sum    */
+        1,                                                                                                                                  /* cofactor   */
+    },
+    #endif /* HAVE_ECC_BRAINPOOL */
+#endif /* ECC512 */
+#ifdef ECC521
+    #ifndef NO_ECC_SECP
+    {
+        66,                                                                                                                                    /* size/bytes */
+        ECC_SECP521R1,                                                                                                                         /* ID         */
+        "SECP521R1",                                                                                                                           /* curve name */
+        "1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", /* prime      */
+        "1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC", /* A          */
+        "51953EB9618E1C9A1F929A21A0B68540EEA2DA725B99B315F3B8B489918EF109E156193951EC7E937B1652C0BD3BB1BF073573DF883D2C34F1EF451FD46B503F00",  /* B          */
+        "1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA51868783BF2F966B7FCC0148F709A5D03BB5C9B8899C47AEBB6FB71E91386409", /* order      */
+        "C6858E06B70404E9CD9E3ECB662395B4429C648139053FB521F828AF606B4D3DBAA14B5E77EFE75928FE1DC127A2FFA8DE3348B3C1856A429BF97E7E31C2E5BD66",  /* Gx         */
+        "11839296A789A3BC0045C8A5FB42C7D1BD998F54449579B446817AFBD17273E662C97EE72995EF42640C550B9013FAD0761353C7086A272C24088BE94769FD16650", /* Gy         */
+        ecc_oid_secp521r1, ecc_oid_secp521r1_sz,                                                                                               /* oid/oidSz  */
+        ECC_SECP521R1_OID,                                                                                                                     /* oid sum    */
+        1,                                                                                                                                     /* cofactor   */
+    },
+    #endif /* !NO_ECC_SECP */
+#endif /* ECC521 */
+#if defined(WOLFSSL_CUSTOM_CURVES) && defined(ECC_CACHE_CURVE)
+    /* place holder for custom curve index for cache */
+    {
+        1, /* non-zero */
+        ECC_CURVE_CUSTOM,
+        #ifndef WOLFSSL_ECC_CURVE_STATIC
+            NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+        #else
+            {0},{0},{0},{0},{0},{0},{0},{0},
+        #endif
+        0, 0, 0
+    },
+#endif
+    {
+        0,
+        ECC_CURVE_INVALID,
+        #ifndef WOLFSSL_ECC_CURVE_STATIC
+            NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+        #else
+            {0},{0},{0},{0},{0},{0},{0},{0},
+        #endif
+        0, 0, 0
+    }
+};
+#define ECC_SET_COUNT   (sizeof(ecc_sets)/sizeof(ecc_set_type))
+const size_t ecc_sets_count = ECC_SET_COUNT - 1;
+
+
+#ifdef HAVE_OID_ENCODING
+    /* encoded OID cache */
+    typedef struct {
+        word32 oidSz;
+        byte oid[ECC_MAX_OID_LEN];
+    } oid_cache_t;
+    static oid_cache_t ecc_oid_cache[ECC_SET_COUNT];
+#endif
+
+
+#ifdef HAVE_COMP_KEY
+static int wc_ecc_export_x963_compressed(ecc_key*, byte* out, word32* outLen);
+#endif
+
+
+#if (defined(WOLFSSL_VALIDATE_ECC_KEYGEN) || !defined(WOLFSSL_SP_MATH)) && \
+    !defined(WOLFSSL_ATECC508A)
+static int ecc_check_pubkey_order(ecc_key* key, ecc_point* pubkey, mp_int* a,
+        mp_int* prime, mp_int* order);
+#endif
+
+int mp_jacobi(mp_int* a, mp_int* n, int* c);
+int mp_sqrtmod_prime(mp_int* n, mp_int* prime, mp_int* ret);
+
+
+/* Curve Specs */
+typedef struct ecc_curve_spec {
+    const ecc_set_type* dp;
+
+    mp_int* prime;
+    mp_int* Af;
+    #ifdef USE_ECC_B_PARAM
+        mp_int* Bf;
+    #endif
+    mp_int* order;
+    mp_int* Gx;
+    mp_int* Gy;
+
+#ifdef ECC_CACHE_CURVE
+    mp_int prime_lcl;
+    mp_int Af_lcl;
+    #ifdef USE_ECC_B_PARAM
+        mp_int Bf_lcl;
+    #endif
+    mp_int order_lcl;
+    mp_int Gx_lcl;
+    mp_int Gy_lcl;
+#else
+    mp_int* spec_ints;
+    word32 spec_count;
+    word32 spec_use;
+#endif
+
+    byte load_mask;
+} ecc_curve_spec;
+
+enum ecc_curve_load_mask {
+    ECC_CURVE_FIELD_NONE    = 0x00,
+    ECC_CURVE_FIELD_PRIME   = 0x01,
+    ECC_CURVE_FIELD_AF      = 0x02,
+#ifdef USE_ECC_B_PARAM
+    ECC_CURVE_FIELD_BF      = 0x04,
+#endif
+    ECC_CURVE_FIELD_ORDER   = 0x08,
+    ECC_CURVE_FIELD_GX      = 0x10,
+    ECC_CURVE_FIELD_GY      = 0x20,
+#ifdef USE_ECC_B_PARAM
+    ECC_CURVE_FIELD_ALL     = 0x3F,
+    ECC_CURVE_FIELD_COUNT   = 6,
+#else
+    ECC_CURVE_FIELD_ALL     = 0x3B,
+    ECC_CURVE_FIELD_COUNT   = 5,
+#endif
+};
+
+#ifdef ECC_CACHE_CURVE
+    /* cache (mp_int) of the curve parameters */
+    static ecc_curve_spec* ecc_curve_spec_cache[ECC_SET_COUNT];
+    #ifndef SINGLE_THREADED
+        static wolfSSL_Mutex ecc_curve_cache_mutex;
+    #endif
+
+    #define DECLARE_CURVE_SPECS(curve, intcount) ecc_curve_spec* curve = NULL
+    #define ALLOC_CURVE_SPECS(intcount)
+    #define FREE_CURVE_SPECS()
+#elif defined(WOLFSSL_SMALL_STACK)
+    #define DECLARE_CURVE_SPECS(curve, intcount)                        \
+        mp_int* spec_ints = NULL;                                       \
+        ecc_curve_spec curve_lcl;                                       \
+        ecc_curve_spec* curve = &curve_lcl;                             \
+        XMEMSET(curve, 0, sizeof(ecc_curve_spec));                      \
+        curve->spec_count = intcount
+
+    #define ALLOC_CURVE_SPECS(intcount)                                 \
+        spec_ints = (mp_int*)XMALLOC(sizeof(mp_int) * (intcount), NULL, \
+                            DYNAMIC_TYPE_ECC);                          \
+        if (spec_ints == NULL)                                          \
+            return MEMORY_E;                                            \
+        curve->spec_ints = spec_ints
+    #define FREE_CURVE_SPECS()                                          \
+        XFREE(spec_ints, NULL, DYNAMIC_TYPE_ECC)
+#else
+    #define DECLARE_CURVE_SPECS(curve, intcount) \
+        mp_int spec_ints[(intcount)]; \
+        ecc_curve_spec curve_lcl; \
+        ecc_curve_spec* curve = &curve_lcl; \
+        XMEMSET(curve, 0, sizeof(ecc_curve_spec)); \
+        curve->spec_ints = spec_ints; \
+        curve->spec_count = intcount
+    #define ALLOC_CURVE_SPECS(intcount)
+    #define FREE_CURVE_SPECS()
+#endif /* ECC_CACHE_CURVE */
+
+static void _wc_ecc_curve_free(ecc_curve_spec* curve)
+{
+    if (curve == NULL) {
+        return;
+    }
+
+    if (curve->load_mask & ECC_CURVE_FIELD_PRIME)
+        mp_clear(curve->prime);
+    if (curve->load_mask & ECC_CURVE_FIELD_AF)
+        mp_clear(curve->Af);
+#ifdef USE_ECC_B_PARAM
+    if (curve->load_mask & ECC_CURVE_FIELD_BF)
+        mp_clear(curve->Bf);
+#endif
+    if (curve->load_mask & ECC_CURVE_FIELD_ORDER)
+        mp_clear(curve->order);
+    if (curve->load_mask & ECC_CURVE_FIELD_GX)
+        mp_clear(curve->Gx);
+    if (curve->load_mask & ECC_CURVE_FIELD_GY)
+        mp_clear(curve->Gy);
+
+    curve->load_mask = 0;
+}
+
+static void wc_ecc_curve_free(ecc_curve_spec* curve)
+{
+    /* don't free cached curves */
+#ifndef ECC_CACHE_CURVE
+    _wc_ecc_curve_free(curve);
+#endif
+    (void)curve;
+}
+
+static int wc_ecc_curve_load_item(const char* src, mp_int** dst,
+    ecc_curve_spec* curve, byte mask)
+{
+    int err;
+
+#ifndef ECC_CACHE_CURVE
+    /* get mp_int from temp */
+    if (curve->spec_use >= curve->spec_count) {
+        WOLFSSL_MSG("Invalid DECLARE_CURVE_SPECS count");
+        return ECC_BAD_ARG_E;
+    }
+    *dst = &curve->spec_ints[curve->spec_use++];
+#endif
+
+    err = mp_init(*dst);
+    if (err == MP_OKAY) {
+        curve->load_mask |= mask;
+
+        err = mp_read_radix(*dst, src, MP_RADIX_HEX);
+
+    #ifdef HAVE_WOLF_BIGINT
+        if (err == MP_OKAY)
+            err = wc_mp_to_bigint(*dst, &(*dst)->raw);
+    #endif
+    }
+    return err;
+}
+
+static int wc_ecc_curve_load(const ecc_set_type* dp, ecc_curve_spec** pCurve,
+    byte load_mask)
+{
+    int ret = 0, x;
+    ecc_curve_spec* curve;
+    byte load_items = 0; /* mask of items to load */
+
+    if (dp == NULL || pCurve == NULL)
+        return BAD_FUNC_ARG;
+
+#ifdef ECC_CACHE_CURVE
+    x = wc_ecc_get_curve_idx(dp->id);
+    if (x == ECC_CURVE_INVALID)
+        return ECC_BAD_ARG_E;
+
+#if !defined(SINGLE_THREADED)
+    ret = wc_LockMutex(&ecc_curve_cache_mutex);
+    if (ret != 0) {
+        return ret;
+    }
+#endif
+
+    /* make sure cache has been allocated */
+    if (ecc_curve_spec_cache[x] == NULL) {
+        ecc_curve_spec_cache[x] = (ecc_curve_spec*)XMALLOC(
+            sizeof(ecc_curve_spec), NULL, DYNAMIC_TYPE_ECC);
+        if (ecc_curve_spec_cache[x] == NULL) {
+        #if defined(ECC_CACHE_CURVE) && !defined(SINGLE_THREADED)
+            wc_UnLockMutex(&ecc_curve_cache_mutex);
+        #endif
+            return MEMORY_E;
+        }
+        XMEMSET(ecc_curve_spec_cache[x], 0, sizeof(ecc_curve_spec));
+    }
+
+    /* set curve pointer to cache */
+    *pCurve = ecc_curve_spec_cache[x];
+
+#endif /* ECC_CACHE_CURVE */
+    curve = *pCurve;
+
+    /* make sure the curve is initialized */
+    if (curve->dp != dp) {
+        curve->load_mask = 0;
+
+    #ifdef ECC_CACHE_CURVE
+        curve->prime = &curve->prime_lcl;
+        curve->Af = &curve->Af_lcl;
+        #ifdef USE_ECC_B_PARAM
+            curve->Bf = &curve->Bf_lcl;
+        #endif
+        curve->order = &curve->order_lcl;
+        curve->Gx = &curve->Gx_lcl;
+        curve->Gy = &curve->Gy_lcl;
+    #endif
+    }
+    curve->dp = dp; /* set dp info */
+
+    /* determine items to load */
+    load_items = (((byte)~(word32)curve->load_mask) & load_mask);
+    curve->load_mask |= load_items;
+
+    /* load items */
+    x = 0;
+    if (load_items & ECC_CURVE_FIELD_PRIME)
+        x += wc_ecc_curve_load_item(dp->prime, &curve->prime, curve,
+            ECC_CURVE_FIELD_PRIME);
+    if (load_items & ECC_CURVE_FIELD_AF)
+        x += wc_ecc_curve_load_item(dp->Af, &curve->Af, curve,
+            ECC_CURVE_FIELD_AF);
+#ifdef USE_ECC_B_PARAM
+    if (load_items & ECC_CURVE_FIELD_BF)
+        x += wc_ecc_curve_load_item(dp->Bf, &curve->Bf, curve,
+            ECC_CURVE_FIELD_BF);
+#endif
+    if (load_items & ECC_CURVE_FIELD_ORDER)
+        x += wc_ecc_curve_load_item(dp->order, &curve->order, curve,
+            ECC_CURVE_FIELD_ORDER);
+    if (load_items & ECC_CURVE_FIELD_GX)
+        x += wc_ecc_curve_load_item(dp->Gx, &curve->Gx, curve,
+            ECC_CURVE_FIELD_GX);
+    if (load_items & ECC_CURVE_FIELD_GY)
+        x += wc_ecc_curve_load_item(dp->Gy, &curve->Gy, curve,
+            ECC_CURVE_FIELD_GY);
+
+    /* check for error */
+    if (x != 0) {
+        wc_ecc_curve_free(curve);
+        ret = MP_READ_E;
+    }
+
+#if defined(ECC_CACHE_CURVE) && !defined(SINGLE_THREADED)
+    wc_UnLockMutex(&ecc_curve_cache_mutex);
+#endif
+
+    return ret;
+}
+
+#ifdef ECC_CACHE_CURVE
+int wc_ecc_curve_cache_init(void)
+{
+    int ret = 0;
+#if defined(ECC_CACHE_CURVE) && !defined(SINGLE_THREADED)
+    ret = wc_InitMutex(&ecc_curve_cache_mutex);
+#endif
+    return ret;
+}
+
+void wc_ecc_curve_cache_free(void)
+{
+    int x;
+
+    /* free all ECC curve caches */
+    for (x = 0; x < (int)ECC_SET_COUNT; x++) {
+        if (ecc_curve_spec_cache[x]) {
+            _wc_ecc_curve_free(ecc_curve_spec_cache[x]);
+            XFREE(ecc_curve_spec_cache[x], NULL, DYNAMIC_TYPE_ECC);
+            ecc_curve_spec_cache[x] = NULL;
+        }
+    }
+
+#if defined(ECC_CACHE_CURVE) && !defined(SINGLE_THREADED)
+    wc_FreeMutex(&ecc_curve_cache_mutex);
+#endif
+}
+#endif /* ECC_CACHE_CURVE */
+
+
+/* Retrieve the curve name for the ECC curve id.
+ *
+ * curve_id  The id of the curve.
+ * returns the name stored from the curve if available, otherwise NULL.
+ */
+const char* wc_ecc_get_name(int curve_id)
+{
+    int curve_idx = wc_ecc_get_curve_idx(curve_id);
+    if (curve_idx == ECC_CURVE_INVALID)
+        return NULL;
+    return ecc_sets[curve_idx].name;
+}
+
+int wc_ecc_set_curve(ecc_key* key, int keysize, int curve_id)
+{
+    if (keysize <= 0 && curve_id < 0) {
+        return BAD_FUNC_ARG;
+    }
+
+    if (keysize > ECC_MAXSIZE) {
+        return ECC_BAD_ARG_E;
+    }
+
+    /* handle custom case */
+    if (key->idx != ECC_CUSTOM_IDX) {
+        int x;
+
+        /* default values */
+        key->idx = 0;
+        key->dp = NULL;
+
+        /* find ecc_set based on curve_id or key size */
+        for (x = 0; ecc_sets[x].size != 0; x++) {
+            if (curve_id > ECC_CURVE_DEF) {
+                if (curve_id == ecc_sets[x].id)
+                  break;
+            }
+            else if (keysize <= ecc_sets[x].size) {
+                break;
+            }
+        }
+        if (ecc_sets[x].size == 0) {
+            WOLFSSL_MSG("ECC Curve not found");
+            return ECC_CURVE_OID_E;
+        }
+
+        key->idx = x;
+        key->dp  = &ecc_sets[x];
+    }
+
+    return 0;
+}
+
+
+#ifdef ALT_ECC_SIZE
+static void alt_fp_init(mp_int* a)
+{
+    a->size = FP_SIZE_ECC;
+    mp_zero(a);
+}
+#endif /* ALT_ECC_SIZE */
+
+
+#ifndef WOLFSSL_ATECC508A
+
+#if !defined(WOLFSSL_SP_MATH) || defined(WOLFSSL_PUBLIC_ECC_ADD_DBL)
+
+/**
+   Add two ECC points
+   P        The point to add
+   Q        The point to add
+   R        [out] The destination of the double
+   a        ECC curve parameter a
+   modulus  The modulus of the field the ECC curve is in
+   mp       The "b" value from montgomery_setup()
+   return   MP_OKAY on success
+*/
+int ecc_projective_add_point(ecc_point* P, ecc_point* Q, ecc_point* R,
+                             mp_int* a, mp_int* modulus, mp_digit mp)
+{
+#ifndef WOLFSSL_SP_MATH
+#ifdef WOLFSSL_SMALL_STACK
+   mp_int* t1 = NULL;
+   mp_int* t2 = NULL;
+#ifdef ALT_ECC_SIZE
+   mp_int* rx = NULL;
+   mp_int* ry = NULL;
+   mp_int* rz = NULL;
+#endif
+#else
+   mp_int  t1[1], t2[1];
+#ifdef ALT_ECC_SIZE
+   mp_int  rx[1], ry[1], rz[1];
+#endif
+#endif
+   mp_int  *x, *y, *z;
+   int     err;
+
+   if (P == NULL || Q == NULL || R == NULL || modulus == NULL) {
+       return ECC_BAD_ARG_E;
+   }
+
+   /* if Q == R then swap P and Q, so we don't require a local x,y,z */
+   if (Q == R) {
+      ecc_point* tPt  = P;
+      P = Q;
+      Q = tPt;
+   }
+
+#ifdef WOLFSSL_SMALL_STACK
+#ifdef WOLFSSL_SMALL_STACK_CACHE
+   if (R->key != NULL) {
+       t1 = R->key->t1;
+       t2 = R->key->t2;
+#ifdef ALT_ECC_SIZE
+       rx = R->key->x;
+       ry = R->key->y;
+       rz = R->key->z;
+#endif
+   }
+   else
+#endif /* WOLFSSL_SMALL_STACK_CACHE */
+   {
+       t1 = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);
+       t2 = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);
+       if (t1 == NULL || t2 == NULL) {
+           XFREE(t1, NULL, DYNAMIC_TYPE_ECC);
+           XFREE(t2, NULL, DYNAMIC_TYPE_ECC);
+           return MEMORY_E;
+       }
+#ifdef ALT_ECC_SIZE
+       rx = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);
+       ry = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);
+       rz = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);
+       if (rx == NULL || ry == NULL || rz == NULL) {
+           XFREE(rz, NULL, DYNAMIC_TYPE_ECC);
+           XFREE(ry, NULL, DYNAMIC_TYPE_ECC);
+           XFREE(rx, NULL, DYNAMIC_TYPE_ECC);
+           XFREE(t2, NULL, DYNAMIC_TYPE_ECC);
+           XFREE(t1, NULL, DYNAMIC_TYPE_ECC);
+           return MEMORY_E;
+       }
+#endif
+   }
+#endif /* WOLFSSL_SMALL_STACK */
+
+   if ((err = mp_init_multi(t1, t2, NULL, NULL, NULL, NULL)) != MP_OKAY) {
+#ifdef WOLFSSL_SMALL_STACK
+   #ifdef WOLFSSL_SMALL_STACK_CACHE
+       if (R->key == NULL)
+   #endif
+       {
+       #ifdef ALT_ECC_SIZE
+          XFREE(rz, NULL, DYNAMIC_TYPE_ECC);
+          XFREE(ry, NULL, DYNAMIC_TYPE_ECC);
+          XFREE(rx, NULL, DYNAMIC_TYPE_ECC);
+       #endif
+          XFREE(t2, NULL, DYNAMIC_TYPE_ECC);
+          XFREE(t1, NULL, DYNAMIC_TYPE_ECC);
+       }
+#endif
+      return err;
+   }
+
+   /* should we dbl instead? */
+   if (err == MP_OKAY)
+       err = mp_sub(modulus, Q->y, t1);
+   if (err == MP_OKAY) {
+       if ( (mp_cmp(P->x, Q->x) == MP_EQ) &&
+            (get_digit_count(Q->z) && mp_cmp(P->z, Q->z) == MP_EQ) &&
+            (mp_cmp(P->y, Q->y) == MP_EQ || mp_cmp(P->y, t1) == MP_EQ)) {
+           mp_clear(t1);
+           mp_clear(t2);
+    #ifdef WOLFSSL_SMALL_STACK
+       #ifdef WOLFSSL_SMALL_STACK_CACHE
+           if (R->key == NULL)
+       #endif
+           {
+            #ifdef ALT_ECC_SIZE
+               XFREE(rz, NULL, DYNAMIC_TYPE_ECC);
+               XFREE(ry, NULL, DYNAMIC_TYPE_ECC);
+               XFREE(rx, NULL, DYNAMIC_TYPE_ECC);
+            #endif
+               XFREE(t2, NULL, DYNAMIC_TYPE_ECC);
+               XFREE(t1, NULL, DYNAMIC_TYPE_ECC);
+           }
+        #endif
+          return ecc_projective_dbl_point(P, R, a, modulus, mp);
+       }
+   }
+
+   if (err != MP_OKAY) {
+      goto done;
+   }
+
+/* If use ALT_ECC_SIZE we need to use local stack variable since
+   ecc_point x,y,z is reduced size */
+#ifdef ALT_ECC_SIZE
+   /* Use local stack variable */
+   x = rx;
+   y = ry;
+   z = rz;
+
+   if ((err = mp_init_multi(x, y, z, NULL, NULL, NULL)) != MP_OKAY) {
+      goto done;
+   }
+#else
+   /* Use destination directly */
+   x = R->x;
+   y = R->y;
+   z = R->z;
+#endif
+
+   if (err == MP_OKAY)
+       err = mp_copy(P->x, x);
+   if (err == MP_OKAY)
+       err = mp_copy(P->y, y);
+   if (err == MP_OKAY)
+       err = mp_copy(P->z, z);
+
+   /* if Z is one then these are no-operations */
+   if (err == MP_OKAY) {
+       if (!mp_iszero(Q->z)) {
+           /* T1 = Z' * Z' */
+           err = mp_sqr(Q->z, t1);
+           if (err == MP_OKAY)
+               err = mp_montgomery_reduce(t1, modulus, mp);
+
+           /* X = X * T1 */
+           if (err == MP_OKAY)
+               err = mp_mul(t1, x, x);
+           if (err == MP_OKAY)
+               err = mp_montgomery_reduce(x, modulus, mp);
+
+           /* T1 = Z' * T1 */
+           if (err == MP_OKAY)
+               err = mp_mul(Q->z, t1, t1);
+           if (err == MP_OKAY)
+               err = mp_montgomery_reduce(t1, modulus, mp);
+
+           /* Y = Y * T1 */
+           if (err == MP_OKAY)
+               err = mp_mul(t1, y, y);
+           if (err == MP_OKAY)
+               err = mp_montgomery_reduce(y, modulus, mp);
+       }
+   }
+
+   /* T1 = Z*Z */
+   if (err == MP_OKAY)
+       err = mp_sqr(z, t1);
+   if (err == MP_OKAY)
+       err = mp_montgomery_reduce(t1, modulus, mp);
+
+   /* T2 = X' * T1 */
+   if (err == MP_OKAY)
+       err = mp_mul(Q->x, t1, t2);
+   if (err == MP_OKAY)
+       err = mp_montgomery_reduce(t2, modulus, mp);
+
+   /* T1 = Z * T1 */
+   if (err == MP_OKAY)
+       err = mp_mul(z, t1, t1);
+   if (err == MP_OKAY)
+       err = mp_montgomery_reduce(t1, modulus, mp);
+
+   /* T1 = Y' * T1 */
+   if (err == MP_OKAY)
+       err = mp_mul(Q->y, t1, t1);
+   if (err == MP_OKAY)
+       err = mp_montgomery_reduce(t1, modulus, mp);
+
+   /* Y = Y - T1 */
+   if (err == MP_OKAY)
+       err = mp_sub(y, t1, y);
+   if (err == MP_OKAY) {
+       if (mp_isneg(y))
+           err = mp_add(y, modulus, y);
+   }
+   /* T1 = 2T1 */
+   if (err == MP_OKAY)
+       err = mp_add(t1, t1, t1);
+   if (err == MP_OKAY) {
+       if (mp_cmp(t1, modulus) != MP_LT)
+           err = mp_sub(t1, modulus, t1);
+   }
+   /* T1 = Y + T1 */
+   if (err == MP_OKAY)
+       err = mp_add(t1, y, t1);
+   if (err == MP_OKAY) {
+       if (mp_cmp(t1, modulus) != MP_LT)
+           err = mp_sub(t1, modulus, t1);
+   }
+   /* X = X - T2 */
+   if (err == MP_OKAY)
+       err = mp_sub(x, t2, x);
+   if (err == MP_OKAY) {
+       if (mp_isneg(x))
+           err = mp_add(x, modulus, x);
+   }
+   /* T2 = 2T2 */
+   if (err == MP_OKAY)
+       err = mp_add(t2, t2, t2);
+   if (err == MP_OKAY) {
+       if (mp_cmp(t2, modulus) != MP_LT)
+           err = mp_sub(t2, modulus, t2);
+   }
+   /* T2 = X + T2 */
+   if (err == MP_OKAY)
+       err = mp_add(t2, x, t2);
+   if (err == MP_OKAY) {
+       if (mp_cmp(t2, modulus) != MP_LT)
+           err = mp_sub(t2, modulus, t2);
+   }
+
+   if (err == MP_OKAY) {
+       if (!mp_iszero(Q->z)) {
+           /* Z = Z * Z' */
+           err = mp_mul(z, Q->z, z);
+           if (err == MP_OKAY)
+               err = mp_montgomery_reduce(z, modulus, mp);
+       }
+   }
+
+   /* Z = Z * X */
+   if (err == MP_OKAY)
+       err = mp_mul(z, x, z);
+   if (err == MP_OKAY)
+       err = mp_montgomery_reduce(z, modulus, mp);
+
+   /* T1 = T1 * X  */
+   if (err == MP_OKAY)
+       err = mp_mul(t1, x, t1);
+   if (err == MP_OKAY)
+       err = mp_montgomery_reduce(t1, modulus, mp);
+
+   /* X = X * X */
+   if (err == MP_OKAY)
+       err = mp_sqr(x, x);
+   if (err == MP_OKAY)
+       err = mp_montgomery_reduce(x, modulus, mp);
+
+   /* T2 = T2 * x */
+   if (err == MP_OKAY)
+       err = mp_mul(t2, x, t2);
+   if (err == MP_OKAY)
+       err = mp_montgomery_reduce(t2, modulus, mp);
+
+   /* T1 = T1 * X  */
+   if (err == MP_OKAY)
+       err = mp_mul(t1, x, t1);
+   if (err == MP_OKAY)
+       err = mp_montgomery_reduce(t1, modulus, mp);
+
+   /* X = Y*Y */
+   if (err == MP_OKAY)
+       err = mp_sqr(y, x);
+   if (err == MP_OKAY)
+       err = mp_montgomery_reduce(x, modulus, mp);
+
+   /* X = X - T2 */
+   if (err == MP_OKAY)
+       err = mp_sub(x, t2, x);
+   if (err == MP_OKAY) {
+       if (mp_isneg(x))
+           err = mp_add(x, modulus, x);
+   }
+   /* T2 = T2 - X */
+   if (err == MP_OKAY)
+       err = mp_sub(t2, x, t2);
+   if (err == MP_OKAY) {
+       if (mp_isneg(t2))
+           err = mp_add(t2, modulus, t2);
+   }
+   /* T2 = T2 - X */
+   if (err == MP_OKAY)
+       err = mp_sub(t2, x, t2);
+   if (err == MP_OKAY) {
+       if (mp_isneg(t2))
+           err = mp_add(t2, modulus, t2);
+   }
+   /* T2 = T2 * Y */
+   if (err == MP_OKAY)
+       err = mp_mul(t2, y, t2);
+   if (err == MP_OKAY)
+       err = mp_montgomery_reduce(t2, modulus, mp);
+
+   /* Y = T2 - T1 */
+   if (err == MP_OKAY)
+       err = mp_sub(t2, t1, y);
+   if (err == MP_OKAY) {
+       if (mp_isneg(y))
+           err = mp_add(y, modulus, y);
+   }
+   /* Y = Y/2 */
+   if (err == MP_OKAY) {
+       if (mp_isodd(y) == MP_YES)
+           err = mp_add(y, modulus, y);
+   }
+   if (err == MP_OKAY)
+       err = mp_div_2(y, y);
+
+#ifdef ALT_ECC_SIZE
+   if (err == MP_OKAY)
+       err = mp_copy(x, R->x);
+   if (err == MP_OKAY)
+       err = mp_copy(y, R->y);
+   if (err == MP_OKAY)
+       err = mp_copy(z, R->z);
+#endif
+
+done:
+
+   /* clean up */
+   mp_clear(t1);
+   mp_clear(t2);
+#ifdef WOLFSSL_SMALL_STACK
+#ifdef WOLFSSL_SMALL_STACK_CACHE
+   if (R->key == NULL)
+#endif
+   {
+   #ifdef ALT_ECC_SIZE
+      XFREE(rz, NULL, DYNAMIC_TYPE_ECC);
+      XFREE(ry, NULL, DYNAMIC_TYPE_ECC);
+      XFREE(rx, NULL, DYNAMIC_TYPE_ECC);
+   #endif
+      XFREE(t2, NULL, DYNAMIC_TYPE_ECC);
+      XFREE(t1, NULL, DYNAMIC_TYPE_ECC);
+   }
+#endif
+
+   return err;
+#else
+    if (P == NULL || Q == NULL || R == NULL || modulus == NULL) {
+        return ECC_BAD_ARG_E;
+    }
+
+    (void)a;
+    (void)mp;
+
+#ifndef WOLFSSL_SP_NO_256
+    if (mp_count_bits(modulus) == 256) {
+        return sp_ecc_proj_add_point_256(P->x, P->y, P->z, Q->x, Q->y, Q->z,
+                                         R->x, R->y, R->z);
+    }
+#endif
+#ifdef WOLFSSL_SP_384
+    if (mp_count_bits(modulus) == 384) {
+        return sp_ecc_proj_add_point_384(P->x, P->y, P->z, Q->x, Q->y, Q->z,
+                                         R->x, R->y, R->z);
+    }
+#endif
+    return ECC_BAD_ARG_E;
+#endif
+}
+
+/* ### Point doubling in Jacobian coordinate system ###
+ *
+ * let us have a curve:                 y^2 = x^3 + a*x + b
+ * in Jacobian coordinates it becomes:  y^2 = x^3 + a*x*z^4 + b*z^6
+ *
+ * The doubling of P = (Xp, Yp, Zp) is given by R = (Xr, Yr, Zr) where:
+ * Xr = M^2 - 2*S
+ * Yr = M * (S - Xr) - 8*T
+ * Zr = 2 * Yp * Zp
+ *
+ * M = 3 * Xp^2 + a*Zp^4
+ * T = Yp^4
+ * S = 4 * Xp * Yp^2
+ *
+ * SPECIAL CASE: when a == 3 we can compute M as
+ * M = 3 * (Xp^2 - Zp^4) = 3 * (Xp + Zp^2) * (Xp - Zp^2)
+ */
+
+/**
+   Double an ECC point
+   P   The point to double
+   R   [out] The destination of the double
+   a   ECC curve parameter a
+   modulus  The modulus of the field the ECC curve is in
+   mp       The "b" value from montgomery_setup()
+   return   MP_OKAY on success
+*/
+int ecc_projective_dbl_point(ecc_point *P, ecc_point *R, mp_int* a,
+                                       mp_int* modulus, mp_digit mp)
+{
+#ifndef WOLFSSL_SP_MATH
+#ifdef WOLFSSL_SMALL_STACK
+   mp_int* t1 = NULL;
+   mp_int* t2 = NULL;
+#ifdef ALT_ECC_SIZE
+   mp_int* rx = NULL;
+   mp_int* ry = NULL;
+   mp_int* rz = NULL;
+#endif
+#else
+   mp_int  t1[1], t2[1];
+#ifdef ALT_ECC_SIZE
+   mp_int  rx[1], ry[1], rz[1];
+#endif
+#endif
+   mp_int *x, *y, *z;
+   int    err;
+
+   if (P == NULL || R == NULL || modulus == NULL)
+       return ECC_BAD_ARG_E;
+
+#ifdef WOLFSSL_SMALL_STACK
+#ifdef WOLFSSL_SMALL_STACK_CACHE
+   if (R->key != NULL) {
+       t1 = R->key->t1;
+       t2 = R->key->t2;
+   #ifdef ALT_ECC_SIZE
+       rx = R->key->x;
+       ry = R->key->y;
+       rz = R->key->z;
+   #endif
+   }
+   else
+#endif /* WOLFSSL_SMALL_STACK_CACHE */
+   {
+       t1 = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);
+       t2 = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);
+       if (t1 == NULL || t2 == NULL) {
+           XFREE(t2, NULL, DYNAMIC_TYPE_ECC);
+           XFREE(t1, NULL, DYNAMIC_TYPE_ECC);
+           return MEMORY_E;
+       }
+    #ifdef ALT_ECC_SIZE
+       rx = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);
+       ry = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);
+       rz = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);
+       if (rx == NULL || ry == NULL || rz == NULL) {
+           XFREE(rz, NULL, DYNAMIC_TYPE_ECC);
+           XFREE(ry, NULL, DYNAMIC_TYPE_ECC);
+           XFREE(rx, NULL, DYNAMIC_TYPE_ECC);
+           XFREE(t2, NULL, DYNAMIC_TYPE_ECC);
+           XFREE(t1, NULL, DYNAMIC_TYPE_ECC);
+           return MEMORY_E;
+       }
+    #endif
+    }
+#endif
+
+   if ((err = mp_init_multi(t1, t2, NULL, NULL, NULL, NULL)) != MP_OKAY) {
+#ifdef WOLFSSL_SMALL_STACK
+#ifdef WOLFSSL_SMALL_STACK_CACHE
+    if (R->key == NULL)
+#endif
+    {
+    #ifdef ALT_ECC_SIZE
+       XFREE(rz, NULL, DYNAMIC_TYPE_ECC);
+       XFREE(ry, NULL, DYNAMIC_TYPE_ECC);
+       XFREE(rx, NULL, DYNAMIC_TYPE_ECC);
+    #endif
+       XFREE(t2, NULL, DYNAMIC_TYPE_ECC);
+       XFREE(t1, NULL, DYNAMIC_TYPE_ECC);
+     }
+#endif
+      return err;
+   }
+
+/* If use ALT_ECC_SIZE we need to use local stack variable since
+   ecc_point x,y,z is reduced size */
+#ifdef ALT_ECC_SIZE
+   /* Use local stack variable */
+   x = rx;
+   y = ry;
+   z = rz;
+
+   if ((err = mp_init_multi(x, y, z, NULL, NULL, NULL)) != MP_OKAY) {
+       mp_clear(t1);
+       mp_clear(t2);
+    #ifdef WOLFSSL_SMALL_STACK
+    #ifdef WOLFSSL_SMALL_STACK_CACHE
+       if (R->key == NULL)
+    #endif
+       {
+       #ifdef ALT_ECC_SIZE
+          XFREE(rz, NULL, DYNAMIC_TYPE_ECC);
+          XFREE(ry, NULL, DYNAMIC_TYPE_ECC);
+          XFREE(rx, NULL, DYNAMIC_TYPE_ECC);
+       #endif
+          XFREE(t2, NULL, DYNAMIC_TYPE_ECC);
+          XFREE(t1, NULL, DYNAMIC_TYPE_ECC);
+       }
+    #endif
+       return err;
+   }
+#else
+   /* Use destination directly */
+   x = R->x;
+   y = R->y;
+   z = R->z;
+#endif
+
+   if (err == MP_OKAY)
+       err = mp_copy(P->x, x);
+   if (err == MP_OKAY)
+       err = mp_copy(P->y, y);
+   if (err == MP_OKAY)
+       err = mp_copy(P->z, z);
+
+   /* T1 = Z * Z */
+   if (err == MP_OKAY)
+       err = mp_sqr(z, t1);
+   if (err == MP_OKAY)
+       err = mp_montgomery_reduce(t1, modulus, mp);
+
+   /* Z = Y * Z */
+   if (err == MP_OKAY)
+       err = mp_mul(z, y, z);
+   if (err == MP_OKAY)
+       err = mp_montgomery_reduce(z, modulus, mp);
+
+   /* Z = 2Z */
+   if (err == MP_OKAY)
+       err = mp_add(z, z, z);
+   if (err == MP_OKAY) {
+       if (mp_cmp(z, modulus) != MP_LT)
+           err = mp_sub(z, modulus, z);
+   }
+
+   /* Determine if curve "a" should be used in calc */
+#ifdef WOLFSSL_CUSTOM_CURVES
+   if (err == MP_OKAY) {
+      /* Use a and prime to determine if a == 3 */
+      err = mp_submod(modulus, a, modulus, t2);
+   }
+   if (err == MP_OKAY && mp_cmp_d(t2, 3) != MP_EQ) {
+      /* use "a" in calc */
+
+      /* T2 = T1 * T1 */
+      if (err == MP_OKAY)
+          err = mp_sqr(t1, t2);
+      if (err == MP_OKAY)
+          err = mp_montgomery_reduce(t2, modulus, mp);
+      /* T1 = T2 * a */
+      if (err == MP_OKAY)
+          err = mp_mulmod(t2, a, modulus, t1);
+      /* T2 = X * X */
+      if (err == MP_OKAY)
+          err = mp_sqr(x, t2);
+      if (err == MP_OKAY)
+          err = mp_montgomery_reduce(t2, modulus, mp);
+      /* T1 = T2 + T1 */
+      if (err == MP_OKAY)
+          err = mp_add(t1, t2, t1);
+      if (err == MP_OKAY) {
+         if (mp_cmp(t1, modulus) != MP_LT)
+            err = mp_sub(t1, modulus, t1);
+      }
+      /* T1 = T2 + T1 */
+      if (err == MP_OKAY)
+          err = mp_add(t1, t2, t1);
+      if (err == MP_OKAY) {
+          if (mp_cmp(t1, modulus) != MP_LT)
+              err = mp_sub(t1, modulus, t1);
+      }
+      /* T1 = T2 + T1 */
+      if (err == MP_OKAY)
+          err = mp_add(t1, t2, t1);
+      if (err == MP_OKAY) {
+         if (mp_cmp(t1, modulus) != MP_LT)
+            err = mp_sub(t1, modulus, t1);
+      }
+   }
+   else
+#endif /* WOLFSSL_CUSTOM_CURVES */
+   {
+      /* assumes "a" == 3 */
+      (void)a;
+
+      /* T2 = X - T1 */
+      if (err == MP_OKAY)
+          err = mp_sub(x, t1, t2);
+      if (err == MP_OKAY) {
+          if (mp_isneg(t2))
+              err = mp_add(t2, modulus, t2);
+      }
+      /* T1 = X + T1 */
+      if (err == MP_OKAY)
+          err = mp_add(t1, x, t1);
+      if (err == MP_OKAY) {
+          if (mp_cmp(t1, modulus) != MP_LT)
+              err = mp_sub(t1, modulus, t1);
+      }
+      /* T2 = T1 * T2 */
+      if (err == MP_OKAY)
+          err = mp_mul(t1, t2, t2);
+      if (err == MP_OKAY)
+          err = mp_montgomery_reduce(t2, modulus, mp);
+
+      /* T1 = 2T2 */
+      if (err == MP_OKAY)
+          err = mp_add(t2, t2, t1);
+      if (err == MP_OKAY) {
+          if (mp_cmp(t1, modulus) != MP_LT)
+              err = mp_sub(t1, modulus, t1);
+      }
+      /* T1 = T1 + T2 */
+      if (err == MP_OKAY)
+          err = mp_add(t1, t2, t1);
+      if (err == MP_OKAY) {
+          if (mp_cmp(t1, modulus) != MP_LT)
+              err = mp_sub(t1, modulus, t1);
+      }
+   }
+
+   /* Y = 2Y */
+   if (err == MP_OKAY)
+       err = mp_add(y, y, y);
+   if (err == MP_OKAY) {
+       if (mp_cmp(y, modulus) != MP_LT)
+           err = mp_sub(y, modulus, y);
+   }
+   /* Y = Y * Y */
+   if (err == MP_OKAY)
+       err = mp_sqr(y, y);
+   if (err == MP_OKAY)
+       err = mp_montgomery_reduce(y, modulus, mp);
+
+   /* T2 = Y * Y */
+   if (err == MP_OKAY)
+       err = mp_sqr(y, t2);
+   if (err == MP_OKAY)
+       err = mp_montgomery_reduce(t2, modulus, mp);
+
+   /* T2 = T2/2 */
+   if (err == MP_OKAY) {
+       if (mp_isodd(t2) == MP_YES)
+           err = mp_add(t2, modulus, t2);
+   }
+   if (err == MP_OKAY)
+       err = mp_div_2(t2, t2);
+
+   /* Y = Y * X */
+   if (err == MP_OKAY)
+       err = mp_mul(y, x, y);
+   if (err == MP_OKAY)
+       err = mp_montgomery_reduce(y, modulus, mp);
+
+   /* X = T1 * T1 */
+   if (err == MP_OKAY)
+       err = mp_sqr(t1, x);
+   if (err == MP_OKAY)
+       err = mp_montgomery_reduce(x, modulus, mp);
+
+   /* X = X - Y */
+   if (err == MP_OKAY)
+       err = mp_sub(x, y, x);
+   if (err == MP_OKAY) {
+       if (mp_isneg(x))
+           err = mp_add(x, modulus, x);
+   }
+   /* X = X - Y */
+   if (err == MP_OKAY)
+       err = mp_sub(x, y, x);
+   if (err == MP_OKAY) {
+       if (mp_isneg(x))
+           err = mp_add(x, modulus, x);
+   }
+
+   /* Y = Y - X */
+   if (err == MP_OKAY)
+       err = mp_sub(y, x, y);
+   if (err == MP_OKAY) {
+       if (mp_isneg(y))
+           err = mp_add(y, modulus, y);
+   }
+   /* Y = Y * T1 */
+   if (err == MP_OKAY)
+       err = mp_mul(y, t1, y);
+   if (err == MP_OKAY)
+       err = mp_montgomery_reduce(y, modulus, mp);
+
+   /* Y = Y - T2 */
+   if (err == MP_OKAY)
+       err = mp_sub(y, t2, y);
+   if (err == MP_OKAY) {
+       if (mp_isneg(y))
+           err = mp_add(y, modulus, y);
+   }
+
+#ifdef ALT_ECC_SIZE
+   if (err == MP_OKAY)
+       err = mp_copy(x, R->x);
+   if (err == MP_OKAY)
+       err = mp_copy(y, R->y);
+   if (err == MP_OKAY)
+       err = mp_copy(z, R->z);
+#endif
+
+   /* clean up */
+   mp_clear(t1);
+   mp_clear(t2);
+
+#ifdef WOLFSSL_SMALL_STACK
+#ifdef WOLFSSL_SMALL_STACK_CACHE
+   if (R->key == NULL)
+#endif
+   {
+    #ifdef ALT_ECC_SIZE
+       XFREE(rz, NULL, DYNAMIC_TYPE_ECC);
+       XFREE(ry, NULL, DYNAMIC_TYPE_ECC);
+       XFREE(rx, NULL, DYNAMIC_TYPE_ECC);
+    #endif
+       XFREE(t2, NULL, DYNAMIC_TYPE_ECC);
+       XFREE(t1, NULL, DYNAMIC_TYPE_ECC);
+    }
+#endif
+
+   return err;
+#else
+    if (P == NULL || R == NULL || modulus == NULL)
+        return ECC_BAD_ARG_E;
+
+    (void)a;
+    (void)mp;
+
+#ifndef WOLFSSL_SP_NO_256
+    if (mp_count_bits(modulus) == 256) {
+        return sp_ecc_proj_dbl_point_256(P->x, P->y, P->z, R->x, R->y, R->z);
+    }
+#endif
+#ifdef WOLFSSL_SP_384
+    if (mp_count_bits(modulus) == 384) {
+        return sp_ecc_proj_dbl_point_384(P->x, P->y, P->z, R->x, R->y, R->z);
+    }
+#endif
+    return ECC_BAD_ARG_E;
+#endif
+}
+
+
+/**
+  Map a projective Jacobian point back to affine space
+  P        [in/out] The point to map
+  modulus  The modulus of the field the ECC curve is in
+  mp       The "b" value from montgomery_setup()
+  ct       Operation should be constant time.
+  return   MP_OKAY on success
+*/
+int ecc_map_ex(ecc_point* P, mp_int* modulus, mp_digit mp, int ct)
+{
+#ifndef WOLFSSL_SP_MATH
+#ifdef WOLFSSL_SMALL_STACK
+   mp_int* t1 = NULL;
+   mp_int* t2 = NULL;
+#ifdef ALT_ECC_SIZE
+   mp_int* rx = NULL;
+   mp_int* ry = NULL;
+   mp_int* rz = NULL;
+#endif
+#else
+   mp_int  t1[1], t2[1];
+#ifdef ALT_ECC_SIZE
+   mp_int  rx[1], ry[1], rz[1];
+#endif
+#endif /* WOLFSSL_SMALL_STACK */
+   mp_int *x, *y, *z;
+   int    err;
+
+   (void)ct;
+
+   if (P == NULL || modulus == NULL)
+       return ECC_BAD_ARG_E;
+
+   /* special case for point at infinity */
+   if (mp_cmp_d(P->z, 0) == MP_EQ) {
+       err = mp_set(P->x, 0);
+       if (err == MP_OKAY)
+           err = mp_set(P->y, 0);
+       if (err == MP_OKAY)
+           err = mp_set(P->z, 1);
+       return err;
+   }
+
+#ifdef WOLFSSL_SMALL_STACK
+#ifdef WOLFSSL_SMALL_STACK_CACHE
+   if (P->key != NULL) {
+       t1 = P->key->t1;
+       t2 = P->key->t2;
+   #ifdef ALT_ECC_SIZE
+       rx = P->key->x;
+       ry = P->key->y;
+       rz = P->key->z;
+   #endif
+   }
+   else
+#endif /* WOLFSSL_SMALL_STACK_CACHE */
+   {
+       t1 = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);
+       t2 = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);
+       if (t1 == NULL || t2 == NULL) {
+           XFREE(t2, NULL, DYNAMIC_TYPE_ECC);
+           XFREE(t1, NULL, DYNAMIC_TYPE_ECC);
+           return MEMORY_E;
+       }
+#ifdef ALT_ECC_SIZE
+       rx = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);
+       ry = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);
+       rz = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);
+       if (rx == NULL || ry == NULL || rz == NULL) {
+           XFREE(rz, NULL, DYNAMIC_TYPE_ECC);
+           XFREE(ry, NULL, DYNAMIC_TYPE_ECC);
+           XFREE(rx, NULL, DYNAMIC_TYPE_ECC);
+           XFREE(t2, NULL, DYNAMIC_TYPE_ECC);
+           XFREE(t1, NULL, DYNAMIC_TYPE_ECC);
+           return MEMORY_E;
+       }
+#endif
+   }
+#endif /* WOLFSSL_SMALL_STACK */
+
+   if ((err = mp_init_multi(t1, t2, NULL, NULL, NULL, NULL)) != MP_OKAY) {
+#ifdef WOLFSSL_SMALL_STACK
+#ifdef WOLFSSL_SMALL_STACK_CACHE
+      if (P->key == NULL)
+#endif
+      {
+      #ifdef ALT_ECC_SIZE
+         XFREE(rz, NULL, DYNAMIC_TYPE_ECC);
+         XFREE(ry, NULL, DYNAMIC_TYPE_ECC);
+         XFREE(rx, NULL, DYNAMIC_TYPE_ECC);
+      #endif
+         XFREE(t2, NULL, DYNAMIC_TYPE_ECC);
+         XFREE(t1, NULL, DYNAMIC_TYPE_ECC);
+      }
+#endif
+      return MEMORY_E;
+   }
+
+#ifdef ALT_ECC_SIZE
+   /* Use local stack variable */
+   x = rx;
+   y = ry;
+   z = rz;
+
+   if ((err = mp_init_multi(x, y, z, NULL, NULL, NULL)) != MP_OKAY) {
+       goto done;
+   }
+
+   if (err == MP_OKAY)
+       err = mp_copy(P->x, x);
+   if (err == MP_OKAY)
+       err = mp_copy(P->y, y);
+   if (err == MP_OKAY)
+       err = mp_copy(P->z, z);
+
+   if (err != MP_OKAY) {
+      goto done;
+   }
+#else
+   /* Use destination directly */
+   x = P->x;
+   y = P->y;
+   z = P->z;
+#endif
+
+   /* get 1/z */
+   if (err == MP_OKAY) {
+#if defined(ECC_TIMING_RESISTANT) && defined(USE_FAST_MATH)
+       if (ct) {
+           err = mp_invmod_mont_ct(z, modulus, t1, mp);
+           if (err == MP_OKAY)
+               err = mp_montgomery_reduce(t1, modulus, mp);
+       }
+       else
+#endif
+       {
+           /* first map z back to normal */
+           err = mp_montgomery_reduce(z, modulus, mp);
+           if (err == MP_OKAY)
+               err = mp_invmod(z, modulus, t1);
+       }
+   }
+
+   /* get 1/z^2 and 1/z^3 */
+   if (err == MP_OKAY)
+       err = mp_sqr(t1, t2);
+   if (err == MP_OKAY)
+       err = mp_mod(t2, modulus, t2);
+   if (err == MP_OKAY)
+       err = mp_mul(t1, t2, t1);
+   if (err == MP_OKAY)
+       err = mp_mod(t1, modulus, t1);
+
+   /* multiply against x/y */
+   if (err == MP_OKAY)
+       err = mp_mul(x, t2, x);
+   if (err == MP_OKAY)
+       err = mp_montgomery_reduce(x, modulus, mp);
+   if (err == MP_OKAY)
+       err = mp_mul(y, t1, y);
+   if (err == MP_OKAY)
+       err = mp_montgomery_reduce(y, modulus, mp);
+
+   if (err == MP_OKAY)
+       err = mp_set(z, 1);
+
+#ifdef ALT_ECC_SIZE
+   /* return result */
+   if (err == MP_OKAY)
+      err = mp_copy(x, P->x);
+   if (err == MP_OKAY)
+      err = mp_copy(y, P->y);
+   if (err == MP_OKAY)
+      err = mp_copy(z, P->z);
+
+done:
+#endif
+
+   /* clean up */
+   mp_clear(t1);
+   mp_clear(t2);
+
+#ifdef WOLFSSL_SMALL_STACK
+#ifdef WOLFSSL_SMALL_STACK_CACHE
+   if (P->key == NULL)
+#endif
+   {
+   #ifdef ALT_ECC_SIZE
+      XFREE(rz, NULL, DYNAMIC_TYPE_ECC);
+      XFREE(ry, NULL, DYNAMIC_TYPE_ECC);
+      XFREE(rx, NULL, DYNAMIC_TYPE_ECC);
+   #endif
+      XFREE(t2, NULL, DYNAMIC_TYPE_ECC);
+      XFREE(t1, NULL, DYNAMIC_TYPE_ECC);
+   }
+#endif
+
+   return err;
+#else
+    if (P == NULL || modulus == NULL)
+        return ECC_BAD_ARG_E;
+
+    (void)mp;
+
+#ifndef WOLFSSL_SP_NO_256
+    if (mp_count_bits(modulus) == 256) {
+        return sp_ecc_map_256(P->x, P->y, P->z);
+    }
+#endif
+#ifdef WOLFSSL_SP_384
+    if (mp_count_bits(modulus) == 384) {
+        return sp_ecc_map_384(P->x, P->y, P->z);
+    }
+#endif
+    return ECC_BAD_ARG_E;
+#endif
+}
+
+int ecc_map(ecc_point* P, mp_int* modulus, mp_digit mp)
+{
+    return ecc_map_ex(P, modulus, mp, 0);
+}
+#endif /* !WOLFSSL_SP_MATH || WOLFSSL_PUBLIC_ECC_ADD_DBL */
+
+#if !defined(FREESCALE_LTC_ECC) && !defined(WOLFSSL_STM32_PKA)
+
+#if !defined(FP_ECC) || !defined(WOLFSSL_SP_MATH)
+/**
+   Perform a point multiplication
+   k    The scalar to multiply by
+   G    The base point
+   R    [out] Destination for kG
+   a    ECC curve parameter a
+   modulus  The modulus of the field the ECC curve is in
+   map      Boolean whether to map back to affine or not
+                (1==map, 0 == leave in projective)
+   return MP_OKAY on success
+*/
+#ifdef FP_ECC
+static int normal_ecc_mulmod(mp_int* k, ecc_point *G, ecc_point *R,
+                  mp_int* a, mp_int* modulus, int map,
+                  void* heap)
+#else
+int wc_ecc_mulmod_ex(mp_int* k, ecc_point *G, ecc_point *R,
+                  mp_int* a, mp_int* modulus, int map,
+                  void* heap)
+#endif
+{
+#ifndef WOLFSSL_SP_MATH
+#ifndef ECC_TIMING_RESISTANT
+   /* size of sliding window, don't change this! */
+   #define WINSIZE  4
+   #define M_POINTS 8
+   int           first = 1, bitbuf = 0, bitcpy = 0, j;
+#elif defined(WC_NO_CACHE_RESISTANT)
+   #define M_POINTS 4
+#else
+   #define M_POINTS 5
+#endif
+
+   ecc_point     *tG, *M[M_POINTS];
+   int           i, err;
+#ifdef WOLFSSL_SMALL_STACK_CACHE
+   ecc_key       key;
+#endif
+#ifdef WOLFSSL_SMALL_STACK
+   mp_int*       mu = NULL;
+#else
+   mp_int        mu[1];
+#endif
+   mp_digit      mp;
+   mp_digit      buf;
+   int           bitcnt = 0, mode = 0, digidx = 0;
+
+   if (k == NULL || G == NULL || R == NULL || modulus == NULL) {
+       return ECC_BAD_ARG_E;
+   }
+
+   /* init variables */
+   tG = NULL;
+   XMEMSET(M, 0, sizeof(M));
+#ifdef WOLFSSL_SMALL_STACK
+   mu = (mp_int*)XMALLOC(sizeof(mp_int), heap, DYNAMIC_TYPE_ECC);
+   if (mu == NULL)
+       return MEMORY_E;
+#endif
+#ifdef WOLFSSL_SMALL_STACK_CACHE
+   key.t1 = (mp_int*)XMALLOC(sizeof(mp_int), heap, DYNAMIC_TYPE_ECC);
+   key.t2 = (mp_int*)XMALLOC(sizeof(mp_int), heap, DYNAMIC_TYPE_ECC);
+#ifdef ALT_ECC_SIZE
+   key.x = (mp_int*)XMALLOC(sizeof(mp_int), heap, DYNAMIC_TYPE_ECC);
+   key.y = (mp_int*)XMALLOC(sizeof(mp_int), heap, DYNAMIC_TYPE_ECC);
+   key.z = (mp_int*)XMALLOC(sizeof(mp_int), heap, DYNAMIC_TYPE_ECC);
+#endif
+   if (key.t1 == NULL || key.t2 == NULL
+#ifdef ALT_ECC_SIZE
+      || key.x == NULL || key.y == NULL || key.z == NULL
+#endif
+   ) {
+#ifdef ALT_ECC_SIZE
+       XFREE(key.z, heap, DYNAMIC_TYPE_ECC);
+       XFREE(key.y, heap, DYNAMIC_TYPE_ECC);
+       XFREE(key.x, heap, DYNAMIC_TYPE_ECC);
+#endif
+       XFREE(key.t2, heap, DYNAMIC_TYPE_ECC);
+       XFREE(key.t1, heap, DYNAMIC_TYPE_ECC);
+       XFREE(mu, heap, DYNAMIC_TYPE_ECC);
+       return MEMORY_E;
+   }
+#endif /* WOLFSSL_SMALL_STACK_CACHE */
+
+   /* init montgomery reduction */
+   if ((err = mp_montgomery_setup(modulus, &mp)) != MP_OKAY) {
+#ifdef WOLFSSL_SMALL_STACK_CACHE
+#ifdef ALT_ECC_SIZE
+       XFREE(key.z, heap, DYNAMIC_TYPE_ECC);
+       XFREE(key.y, heap, DYNAMIC_TYPE_ECC);
+       XFREE(key.x, heap, DYNAMIC_TYPE_ECC);
+#endif
+       XFREE(key.t2, heap, DYNAMIC_TYPE_ECC);
+       XFREE(key.t1, heap, DYNAMIC_TYPE_ECC);
+#endif /* WOLFSSL_SMALL_STACK_CACHE */
+#ifdef WOLFSSL_SMALL_STACK
+       XFREE(mu, heap, DYNAMIC_TYPE_ECC);
+#endif
+       return err;
+   }
+
+   if ((err = mp_init(mu)) != MP_OKAY) {
+#ifdef WOLFSSL_SMALL_STACK_CACHE
+#ifdef ALT_ECC_SIZE
+       XFREE(key.z, heap, DYNAMIC_TYPE_ECC);
+       XFREE(key.y, heap, DYNAMIC_TYPE_ECC);
+       XFREE(key.x, heap, DYNAMIC_TYPE_ECC);
+#endif
+       XFREE(key.t2, heap, DYNAMIC_TYPE_ECC);
+       XFREE(key.t1, heap, DYNAMIC_TYPE_ECC);
+#endif /* WOLFSSL_SMALL_STACK_CACHE */
+#ifdef WOLFSSL_SMALL_STACK
+       XFREE(mu, heap, DYNAMIC_TYPE_ECC);
+#endif
+       return err;
+   }
+   if ((err = mp_montgomery_calc_normalization(mu, modulus)) != MP_OKAY) {
+       mp_clear(mu);
+#ifdef WOLFSSL_SMALL_STACK_CACHE
+#ifdef ALT_ECC_SIZE
+       XFREE(key.z, heap, DYNAMIC_TYPE_ECC);
+       XFREE(key.y, heap, DYNAMIC_TYPE_ECC);
+       XFREE(key.x, heap, DYNAMIC_TYPE_ECC);
+#endif
+       XFREE(key.t2, heap, DYNAMIC_TYPE_ECC);
+       XFREE(key.t1, heap, DYNAMIC_TYPE_ECC);
+#endif /* WOLFSSL_SMALL_STACK_CACHE */
+#ifdef WOLFSSL_SMALL_STACK
+       XFREE(mu, heap, DYNAMIC_TYPE_ECC);
+#endif
+       return err;
+   }
+
+  /* alloc ram for window temps */
+  for (i = 0; i < M_POINTS; i++) {
+      M[i] = wc_ecc_new_point_h(heap);
+      if (M[i] == NULL) {
+         mp_clear(mu);
+         err = MEMORY_E; goto exit;
+      }
+#ifdef WOLFSSL_SMALL_STACK_CACHE
+      M[i]->key = &key;
+#endif
+  }
+
+   /* make a copy of G in case R==G */
+   tG = wc_ecc_new_point_h(heap);
+   if (tG == NULL)
+       err = MEMORY_E;
+
+   /* tG = G  and convert to montgomery */
+   if (err == MP_OKAY) {
+       if (mp_cmp_d(mu, 1) == MP_EQ) {
+           err = mp_copy(G->x, tG->x);
+           if (err == MP_OKAY)
+               err = mp_copy(G->y, tG->y);
+           if (err == MP_OKAY)
+               err = mp_copy(G->z, tG->z);
+       } else {
+           err = mp_mulmod(G->x, mu, modulus, tG->x);
+           if (err == MP_OKAY)
+               err = mp_mulmod(G->y, mu, modulus, tG->y);
+           if (err == MP_OKAY)
+               err = mp_mulmod(G->z, mu, modulus, tG->z);
+       }
+   }
+
+   /* done with mu */
+   mp_clear(mu);
+
+#ifdef WOLFSSL_SMALL_STACK_CACHE
+   R->key = &key;
+#endif
+#ifndef ECC_TIMING_RESISTANT
+
+   /* calc the M tab, which holds kG for k==8..15 */
+   /* M[0] == 8G */
+   if (err == MP_OKAY)
+       err = ecc_projective_dbl_point(tG, M[0], a, modulus, mp);
+   if (err == MP_OKAY)
+       err = ecc_projective_dbl_point(M[0], M[0], a, modulus, mp);
+   if (err == MP_OKAY)
+       err = ecc_projective_dbl_point(M[0], M[0], a, modulus, mp);
+
+   /* now find (8+k)G for k=1..7 */
+   if (err == MP_OKAY)
+       for (j = 9; j < 16; j++) {
+           err = ecc_projective_add_point(M[j-9], tG, M[j-M_POINTS], a, modulus,
+                                                                            mp);
+           if (err != MP_OKAY) break;
+       }
+
+   /* setup sliding window */
+   if (err == MP_OKAY) {
+       mode   = 0;
+       bitcnt = 1;
+       buf    = 0;
+       digidx = get_digit_count(k) - 1;
+       bitcpy = bitbuf = 0;
+       first  = 1;
+
+       /* perform ops */
+       for (;;) {
+           /* grab next digit as required */
+           if (--bitcnt == 0) {
+               if (digidx == -1) {
+                   break;
+               }
+               buf    = get_digit(k, digidx);
+               bitcnt = (int) DIGIT_BIT;
+               --digidx;
+           }
+
+           /* grab the next msb from the ltiplicand */
+           i = (int)(buf >> (DIGIT_BIT - 1)) & 1;
+           buf <<= 1;
+
+           /* skip leading zero bits */
+           if (mode == 0 && i == 0)
+               continue;
+
+           /* if the bit is zero and mode == 1 then we double */
+           if (mode == 1 && i == 0) {
+               err = ecc_projective_dbl_point(R, R, a, modulus, mp);
+               if (err != MP_OKAY) break;
+               continue;
+           }
+
+           /* else we add it to the window */
+           bitbuf |= (i << (WINSIZE - ++bitcpy));
+           mode = 2;
+
+           if (bitcpy == WINSIZE) {
+               /* if this is the first window we do a simple copy */
+               if (first == 1) {
+                   /* R = kG [k = first window] */
+                   err = mp_copy(M[bitbuf-M_POINTS]->x, R->x);
+                   if (err != MP_OKAY) break;
+
+                   err = mp_copy(M[bitbuf-M_POINTS]->y, R->y);
+                   if (err != MP_OKAY) break;
+
+                   err = mp_copy(M[bitbuf-M_POINTS]->z, R->z);
+                   first = 0;
+               } else {
+                   /* normal window */
+                   /* ok window is filled so double as required and add  */
+                   /* double first */
+                   for (j = 0; j < WINSIZE; j++) {
+                       err = ecc_projective_dbl_point(R, R, a, modulus, mp);
+                       if (err != MP_OKAY) break;
+                   }
+                   if (err != MP_OKAY) break;  /* out of first for(;;) */
+
+                   /* then add, bitbuf will be 8..15 [8..2^WINSIZE] guaranteed */
+                   err = ecc_projective_add_point(R, M[bitbuf-M_POINTS], R, a,
+                                                                   modulus, mp);
+               }
+               if (err != MP_OKAY) break;
+               /* empty window and reset */
+               bitcpy = bitbuf = 0;
+               mode = 1;
+           }
+       }
+   }
+
+   /* if bits remain then double/add */
+   if (err == MP_OKAY) {
+       if (mode == 2 && bitcpy > 0) {
+           /* double then add */
+           for (j = 0; j < bitcpy; j++) {
+               /* only double if we have had at least one add first */
+               if (first == 0) {
+                   err = ecc_projective_dbl_point(R, R, a, modulus, mp);
+                   if (err != MP_OKAY) break;
+               }
+
+               bitbuf <<= 1;
+               if ((bitbuf & (1 << WINSIZE)) != 0) {
+                   if (first == 1) {
+                       /* first add, so copy */
+                       err = mp_copy(tG->x, R->x);
+                       if (err != MP_OKAY) break;
+
+                       err = mp_copy(tG->y, R->y);
+                       if (err != MP_OKAY) break;
+
+                       err = mp_copy(tG->z, R->z);
+                       if (err != MP_OKAY) break;
+                       first = 0;
+                   } else {
+                       /* then add */
+                       err = ecc_projective_add_point(R, tG, R, a, modulus, mp);
+                       if (err != MP_OKAY) break;
+                   }
+               }
+           }
+       }
+   }
+
+   #undef WINSIZE
+
+#else /* ECC_TIMING_RESISTANT */
+
+   /* calc the M tab */
+   /* M[0] == G */
+   if (err == MP_OKAY)
+       err = mp_copy(tG->x, M[0]->x);
+   if (err == MP_OKAY)
+       err = mp_copy(tG->y, M[0]->y);
+   if (err == MP_OKAY)
+       err = mp_copy(tG->z, M[0]->z);
+
+   /* M[1] == 2G */
+   if (err == MP_OKAY)
+       err = ecc_projective_dbl_point(tG, M[1], a, modulus, mp);
+#ifdef WC_NO_CACHE_RESISTANT
+   if (err == MP_OKAY)
+       err = wc_ecc_copy_point(M[0], M[2]);
+#else
+   if (err == MP_OKAY)
+       err = wc_ecc_copy_point(M[0], M[3]);
+   if (err == MP_OKAY)
+       err = wc_ecc_copy_point(M[1], M[4]);
+#endif
+
+   /* setup sliding window */
+   mode   = 0;
+   bitcnt = 1;
+   buf    = 0;
+   digidx = get_digit_count(modulus) - 1;
+   /* The order MAY be 1 bit longer than the modulus. */
+   digidx += (modulus->dp[digidx] >> (DIGIT_BIT-1));
+
+   /* perform ops */
+   if (err == MP_OKAY) {
+       for (;;) {
+           /* grab next digit as required */
+           if (--bitcnt == 0) {
+               if (digidx == -1) {
+                   break;
+               }
+               buf = get_digit(k, digidx);
+               bitcnt = (int)DIGIT_BIT;
+               --digidx;
+           }
+
+           /* grab the next msb from the multiplicand */
+           i = (buf >> (DIGIT_BIT - 1)) & 1;
+           buf <<= 1;
+
+#ifdef WC_NO_CACHE_RESISTANT
+           if (mode == 0) {
+               /* timing resistant - dummy operations */
+               if (err == MP_OKAY)
+                   err = ecc_projective_add_point(M[1], M[2], M[2], a, modulus,
+                                                  mp);
+               if (err == MP_OKAY)
+                   err = ecc_projective_dbl_point(M[2], M[3], a, modulus, mp);
+           }
+           else {
+               if (err == MP_OKAY)
+                   err = ecc_projective_add_point(M[0], M[1], M[i^1], a,
+                                                  modulus, mp);
+               if (err == MP_OKAY)
+                   err = ecc_projective_dbl_point(M[i], M[i], a, modulus, mp);
+           }
+#else
+           if (err == MP_OKAY)
+               err = ecc_projective_add_point(M[0], M[1], M[2], a, modulus, mp);
+           if (err == MP_OKAY)
+               err = mp_cond_copy(M[2]->x, i, M[0]->x);
+           if (err == MP_OKAY)
+               err = mp_cond_copy(M[2]->y, i, M[0]->y);
+           if (err == MP_OKAY)
+               err = mp_cond_copy(M[2]->z, i, M[0]->z);
+           if (err == MP_OKAY)
+               err = mp_cond_copy(M[2]->x, i ^ 1, M[1]->x);
+           if (err == MP_OKAY)
+               err = mp_cond_copy(M[2]->y, i ^ 1, M[1]->y);
+           if (err == MP_OKAY)
+               err = mp_cond_copy(M[2]->z, i ^ 1, M[1]->z);
+
+           if (err == MP_OKAY)
+               err = mp_cond_copy(M[0]->x, i ^ 1, M[2]->x);
+           if (err == MP_OKAY)
+               err = mp_cond_copy(M[0]->y, i ^ 1, M[2]->y);
+           if (err == MP_OKAY)
+               err = mp_cond_copy(M[0]->z, i ^ 1, M[2]->z);
+           if (err == MP_OKAY)
+               err = mp_cond_copy(M[1]->x, i, M[2]->x);
+           if (err == MP_OKAY)
+               err = mp_cond_copy(M[1]->y, i, M[2]->y);
+           if (err == MP_OKAY)
+               err = mp_cond_copy(M[1]->z, i, M[2]->z);
+
+           if (err == MP_OKAY)
+               err = ecc_projective_dbl_point(M[2], M[2], a, modulus, mp);
+           if (err == MP_OKAY)
+               err = mp_cond_copy(M[2]->x, i ^ 1, M[0]->x);
+           if (err == MP_OKAY)
+               err = mp_cond_copy(M[2]->y, i ^ 1, M[0]->y);
+           if (err == MP_OKAY)
+               err = mp_cond_copy(M[2]->z, i ^ 1, M[0]->z);
+           if (err == MP_OKAY)
+               err = mp_cond_copy(M[2]->x, i, M[1]->x);
+           if (err == MP_OKAY)
+               err = mp_cond_copy(M[2]->y, i, M[1]->y);
+           if (err == MP_OKAY)
+               err = mp_cond_copy(M[2]->z, i, M[1]->z);
+
+           if (err == MP_OKAY)
+               err = mp_cond_copy(M[3]->x, (mode ^ 1) & i, M[0]->x);
+           if (err == MP_OKAY)
+               err = mp_cond_copy(M[3]->y, (mode ^ 1) & i, M[0]->y);
+           if (err == MP_OKAY)
+               err = mp_cond_copy(M[3]->z, (mode ^ 1) & i, M[0]->z);
+           if (err == MP_OKAY)
+               err = mp_cond_copy(M[4]->x, (mode ^ 1) & i, M[1]->x);
+           if (err == MP_OKAY)
+               err = mp_cond_copy(M[4]->y, (mode ^ 1) & i, M[1]->y);
+           if (err == MP_OKAY)
+               err = mp_cond_copy(M[4]->z, (mode ^ 1) & i, M[1]->z);
+#endif /* WC_NO_CACHE_RESISTANT */
+
+           if (err != MP_OKAY)
+               break;
+
+           mode |= i;
+       } /* end for */
+   }
+
+   /* copy result out */
+   if (err == MP_OKAY)
+       err = mp_copy(M[0]->x, R->x);
+   if (err == MP_OKAY)
+       err = mp_copy(M[0]->y, R->y);
+   if (err == MP_OKAY)
+       err = mp_copy(M[0]->z, R->z);
+
+#endif /* ECC_TIMING_RESISTANT */
+
+   /* map R back from projective space */
+   if (err == MP_OKAY && map)
+       err = ecc_map(R, modulus, mp);
+
+exit:
+
+   /* done */
+   wc_ecc_del_point_h(tG, heap);
+   for (i = 0; i < M_POINTS; i++) {
+       wc_ecc_del_point_h(M[i], heap);
+   }
+#ifdef WOLFSSL_SMALL_STACK_CACHE
+   R->key = NULL;
+#ifdef ALT_ECC_SIZE
+   XFREE(key.z, heap, DYNAMIC_TYPE_ECC);
+   XFREE(key.y, heap, DYNAMIC_TYPE_ECC);
+   XFREE(key.x, heap, DYNAMIC_TYPE_ECC);
+#endif
+   XFREE(key.t2, heap, DYNAMIC_TYPE_ECC);
+   XFREE(key.t1, heap, DYNAMIC_TYPE_ECC);
+#endif /* WOLFSSL_SMALL_STACK_CACHE */
+#ifdef WOLFSSL_SMALL_STACK
+   XFREE(mu, heap, DYNAMIC_TYPE_ECC);
+#endif
+
+   return err;
+#else
+   if (k == NULL || G == NULL || R == NULL || modulus == NULL) {
+       return ECC_BAD_ARG_E;
+   }
+
+   (void)a;
+
+#ifndef WOLFSSL_SP_NO_256
+   if (mp_count_bits(modulus) == 256) {
+       return sp_ecc_mulmod_256(k, G, R, map, heap);
+   }
+#endif
+#ifdef WOLFSSL_SP_384
+   if (mp_count_bits(modulus) == 384) {
+       return sp_ecc_mulmod_384(k, G, R, map, heap);
+   }
+#endif
+   return ECC_BAD_ARG_E;
+#endif
+}
+
+#endif /* !FP_ECC || !WOLFSSL_SP_MATH */
+
+#endif /* !FREESCALE_LTC_ECC && !WOLFSSL_STM32_PKA */
+
+/** ECC Fixed Point mulmod global
+    k        The multiplicand
+    G        Base point to multiply
+    R        [out] Destination of product
+    a        ECC curve parameter a
+    modulus  The modulus for the curve
+    map      [boolean] If non-zero maps the point back to affine coordinates,
+             otherwise it's left in jacobian-montgomery form
+    return MP_OKAY if successful
+*/
+int wc_ecc_mulmod(mp_int* k, ecc_point *G, ecc_point *R, mp_int* a,
+                  mp_int* modulus, int map)
+{
+    return wc_ecc_mulmod_ex(k, G, R, a, modulus, map, NULL);
+}
+
+#endif /* !WOLFSSL_ATECC508A */
+
+/**
+ * use a heap hint when creating new ecc_point
+ * return an allocated point on success or NULL on failure
+ */
+ecc_point* wc_ecc_new_point_h(void* heap)
+{
+   ecc_point* p;
+
+   (void)heap;
+
+   p = (ecc_point*)XMALLOC(sizeof(ecc_point), heap, DYNAMIC_TYPE_ECC);
+   if (p == NULL) {
+      return NULL;
+   }
+   XMEMSET(p, 0, sizeof(ecc_point));
+
+#ifndef ALT_ECC_SIZE
+   if (mp_init_multi(p->x, p->y, p->z, NULL, NULL, NULL) != MP_OKAY) {
+      XFREE(p, heap, DYNAMIC_TYPE_ECC);
+      return NULL;
+   }
+#else
+   p->x = (mp_int*)&p->xyz[0];
+   p->y = (mp_int*)&p->xyz[1];
+   p->z = (mp_int*)&p->xyz[2];
+   alt_fp_init(p->x);
+   alt_fp_init(p->y);
+   alt_fp_init(p->z);
+#endif
+
+   return p;
+}
+
+
+/**
+   Allocate a new ECC point
+   return A newly allocated point or NULL on error
+*/
+ecc_point* wc_ecc_new_point(void)
+{
+  return wc_ecc_new_point_h(NULL);
+}
+
+
+void wc_ecc_del_point_h(ecc_point* p, void* heap)
+{
+   /* prevents free'ing null arguments */
+   if (p != NULL) {
+      mp_clear(p->x);
+      mp_clear(p->y);
+      mp_clear(p->z);
+      XFREE(p, heap, DYNAMIC_TYPE_ECC);
+   }
+   (void)heap;
+}
+
+
+/** Free an ECC point from memory
+  p   The point to free
+*/
+void wc_ecc_del_point(ecc_point* p)
+{
+    wc_ecc_del_point_h(p, NULL);
+}
+
+
+/** Copy the value of a point to an other one
+  p    The point to copy
+  r    The created point
+*/
+int wc_ecc_copy_point(ecc_point* p, ecc_point *r)
+{
+    int ret;
+
+    /* prevents null arguments */
+    if (p == NULL || r == NULL)
+        return ECC_BAD_ARG_E;
+
+    ret = mp_copy(p->x, r->x);
+    if (ret != MP_OKAY)
+        return ret;
+    ret = mp_copy(p->y, r->y);
+    if (ret != MP_OKAY)
+        return ret;
+    ret = mp_copy(p->z, r->z);
+    if (ret != MP_OKAY)
+        return ret;
+
+    return MP_OKAY;
+}
+
+/** Compare the value of a point with an other one
+ a    The point to compare
+ b    The other point to compare
+
+ return MP_EQ if equal, MP_LT/MP_GT if not, < 0 in case of error
+ */
+int wc_ecc_cmp_point(ecc_point* a, ecc_point *b)
+{
+    int ret;
+
+    /* prevents null arguments */
+    if (a == NULL || b == NULL)
+        return BAD_FUNC_ARG;
+
+    ret = mp_cmp(a->x, b->x);
+    if (ret != MP_EQ)
+        return ret;
+    ret = mp_cmp(a->y, b->y);
+    if (ret != MP_EQ)
+        return ret;
+    ret = mp_cmp(a->z, b->z);
+    if (ret != MP_EQ)
+        return ret;
+
+    return MP_EQ;
+}
+
+
+/** Returns whether an ECC idx is valid or not
+  n      The idx number to check
+  return 1 if valid, 0 if not
+*/
+int wc_ecc_is_valid_idx(int n)
+{
+   int x;
+
+   for (x = 0; ecc_sets[x].size != 0; x++)
+       ;
+   /* -1 is a valid index --- indicating that the domain params
+      were supplied by the user */
+   if ((n >= ECC_CUSTOM_IDX) && (n < x)) {
+      return 1;
+   }
+
+   return 0;
+}
+
+int wc_ecc_get_curve_idx(int curve_id)
+{
+    int curve_idx;
+    for (curve_idx = 0; ecc_sets[curve_idx].size != 0; curve_idx++) {
+        if (curve_id == ecc_sets[curve_idx].id)
+            break;
+    }
+    if (ecc_sets[curve_idx].size == 0) {
+        return ECC_CURVE_INVALID;
+    }
+    return curve_idx;
+}
+
+int wc_ecc_get_curve_id(int curve_idx)
+{
+    if (wc_ecc_is_valid_idx(curve_idx)) {
+        return ecc_sets[curve_idx].id;
+    }
+    return ECC_CURVE_INVALID;
+}
+
+/* Returns the curve size that corresponds to a given ecc_curve_id identifier
+ *
+ * id      curve id, from ecc_curve_id enum in ecc.h
+ * return  curve size, from ecc_sets[] on success, negative on error
+ */
+int wc_ecc_get_curve_size_from_id(int curve_id)
+{
+    int curve_idx = wc_ecc_get_curve_idx(curve_id);
+    if (curve_idx == ECC_CURVE_INVALID)
+        return ECC_BAD_ARG_E;
+    return ecc_sets[curve_idx].size;
+}
+
+/* Returns the curve index that corresponds to a given curve name in
+ * ecc_sets[] of ecc.c
+ *
+ * name    curve name, from ecc_sets[].name in ecc.c
+ * return  curve index in ecc_sets[] on success, negative on error
+ */
+int wc_ecc_get_curve_idx_from_name(const char* curveName)
+{
+    int curve_idx;
+    word32 len;
+
+    if (curveName == NULL)
+        return BAD_FUNC_ARG;
+
+    len = (word32)XSTRLEN(curveName);
+
+    for (curve_idx = 0; ecc_sets[curve_idx].size != 0; curve_idx++) {
+        if (
+        #ifndef WOLFSSL_ECC_CURVE_STATIC
+            ecc_sets[curve_idx].name &&
+        #endif
+                XSTRNCASECMP(ecc_sets[curve_idx].name, curveName, len) == 0) {
+            break;
+        }
+    }
+    if (ecc_sets[curve_idx].size == 0) {
+        WOLFSSL_MSG("ecc_set curve name not found");
+        return ECC_CURVE_INVALID;
+    }
+    return curve_idx;
+}
+
+/* Returns the curve size that corresponds to a given curve name,
+ * as listed in ecc_sets[] of ecc.c.
+ *
+ * name    curve name, from ecc_sets[].name in ecc.c
+ * return  curve size, from ecc_sets[] on success, negative on error
+ */
+int wc_ecc_get_curve_size_from_name(const char* curveName)
+{
+    int curve_idx;
+
+    if (curveName == NULL)
+        return BAD_FUNC_ARG;
+
+    curve_idx = wc_ecc_get_curve_idx_from_name(curveName);
+    if (curve_idx < 0)
+        return curve_idx;
+
+    return ecc_sets[curve_idx].size;
+}
+
+/* Returns the curve id that corresponds to a given curve name,
+ * as listed in ecc_sets[] of ecc.c.
+ *
+ * name   curve name, from ecc_sets[].name in ecc.c
+ * return curve id, from ecc_sets[] on success, negative on error
+ */
+int wc_ecc_get_curve_id_from_name(const char* curveName)
+{
+    int curve_idx;
+
+    if (curveName == NULL)
+        return BAD_FUNC_ARG;
+
+    curve_idx = wc_ecc_get_curve_idx_from_name(curveName);
+    if (curve_idx < 0)
+        return curve_idx;
+
+    return ecc_sets[curve_idx].id;
+}
+
+/* Compares a curve parameter (hex, from ecc_sets[]) to given input
+ * parameter for equality.
+ * encType is WC_TYPE_UNSIGNED_BIN or WC_TYPE_HEX_STR
+ * Returns MP_EQ on success, negative on error */
+static int wc_ecc_cmp_param(const char* curveParam,
+                            const byte* param, word32 paramSz, int encType)
+{
+    int err = MP_OKAY;
+#ifdef WOLFSSL_SMALL_STACK
+    mp_int* a = NULL;
+    mp_int* b = NULL;
+#else
+    mp_int  a[1], b[1];
+#endif
+
+    if (param == NULL || curveParam == NULL)
+        return BAD_FUNC_ARG;
+
+    if (encType == WC_TYPE_HEX_STR)
+        return XSTRNCMP(curveParam, (char*) param, paramSz);
+
+#ifdef WOLFSSL_SMALL_STACK
+    a = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);
+    if (a == NULL)
+        return MEMORY_E;
+    b = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);
+    if (b == NULL) {
+        XFREE(a, NULL, DYNAMIC_TYPE_ECC);
+        return MEMORY_E;
+    }
+#endif
+
+    if ((err = mp_init_multi(a, b, NULL, NULL, NULL, NULL)) != MP_OKAY) {
+    #ifdef WOLFSSL_SMALL_STACK
+        XFREE(a, NULL, DYNAMIC_TYPE_ECC);
+        XFREE(b, NULL, DYNAMIC_TYPE_ECC);
+    #endif
+        return err;
+    }
+
+    if (err == MP_OKAY) {
+        err = mp_read_unsigned_bin(a, param, paramSz);
+    }
+    if (err == MP_OKAY)
+        err = mp_read_radix(b, curveParam, MP_RADIX_HEX);
+
+    if (err == MP_OKAY) {
+        if (mp_cmp(a, b) != MP_EQ) {
+            err = -1;
+        } else {
+            err = MP_EQ;
+        }
+    }
+
+    mp_clear(a);
+    mp_clear(b);
+#ifdef WOLFSSL_SMALL_STACK
+    XFREE(b, NULL, DYNAMIC_TYPE_ECC);
+    XFREE(a, NULL, DYNAMIC_TYPE_ECC);
+#endif
+
+    return err;
+}
+
+/* Returns the curve id in ecc_sets[] that corresponds to a given set of
+ * curve parameters.
+ *
+ * fieldSize  the field size in bits
+ * prime      prime of the finite field
+ * primeSz    size of prime in octets
+ * Af         first coefficient a of the curve
+ * AfSz       size of Af in octets
+ * Bf         second coefficient b of the curve
+ * BfSz       size of Bf in octets
+ * order      curve order
+ * orderSz    size of curve in octets
+ * Gx         affine x coordinate of base point
+ * GxSz       size of Gx in octets
+ * Gy         affine y coordinate of base point
+ * GySz       size of Gy in octets
+ * cofactor   curve cofactor
+ *
+ * return curve id, from ecc_sets[] on success, negative on error
+ */
+int wc_ecc_get_curve_id_from_params(int fieldSize,
+        const byte* prime, word32 primeSz, const byte* Af, word32 AfSz,
+        const byte* Bf, word32 BfSz, const byte* order, word32 orderSz,
+        const byte* Gx, word32 GxSz, const byte* Gy, word32 GySz, int cofactor)
+{
+    int idx;
+    int curveSz;
+
+    if (prime == NULL || Af == NULL || Bf == NULL || order == NULL ||
+        Gx == NULL || Gy == NULL)
+        return BAD_FUNC_ARG;
+
+    curveSz = (fieldSize + 1) / 8;    /* round up */
+
+    for (idx = 0; ecc_sets[idx].size != 0; idx++) {
+        if (curveSz == ecc_sets[idx].size) {
+            if ((wc_ecc_cmp_param(ecc_sets[idx].prime, prime,
+                            primeSz, WC_TYPE_UNSIGNED_BIN) == MP_EQ) &&
+                (wc_ecc_cmp_param(ecc_sets[idx].Af, Af, AfSz,
+                                  WC_TYPE_UNSIGNED_BIN) == MP_EQ) &&
+                (wc_ecc_cmp_param(ecc_sets[idx].Bf, Bf, BfSz,
+                                  WC_TYPE_UNSIGNED_BIN) == MP_EQ) &&
+                (wc_ecc_cmp_param(ecc_sets[idx].order, order,
+                                  orderSz, WC_TYPE_UNSIGNED_BIN) == MP_EQ) &&
+                (wc_ecc_cmp_param(ecc_sets[idx].Gx, Gx, GxSz,
+                                  WC_TYPE_UNSIGNED_BIN) == MP_EQ) &&
+                (wc_ecc_cmp_param(ecc_sets[idx].Gy, Gy, GySz,
+                                  WC_TYPE_UNSIGNED_BIN) == MP_EQ) &&
+                (cofactor == ecc_sets[idx].cofactor)) {
+                    break;
+            }
+        }
+    }
+
+    if (ecc_sets[idx].size == 0)
+        return ECC_CURVE_INVALID;
+
+    return ecc_sets[idx].id;
+}
+
+/* Returns the curve id in ecc_sets[] that corresponds
+ * to a given domain parameters pointer.
+ *
+ * dp   domain parameters pointer
+ *
+ * return curve id, from ecc_sets[] on success, negative on error
+ */
+int wc_ecc_get_curve_id_from_dp_params(const ecc_set_type* dp)
+{
+    int idx;
+
+    if (dp == NULL
+    #ifndef WOLFSSL_ECC_CURVE_STATIC
+         || dp->prime == NULL ||  dp->Af == NULL ||
+        dp->Bf == NULL || dp->order == NULL || dp->Gx == NULL || dp->Gy == NULL
+    #endif
+    ) {
+        return BAD_FUNC_ARG;
+    }
+
+    for (idx = 0; ecc_sets[idx].size != 0; idx++) {
+        if (dp->size == ecc_sets[idx].size) {
+            if ((wc_ecc_cmp_param(ecc_sets[idx].prime, (const byte*)dp->prime,
+                    (word32)XSTRLEN(dp->prime), WC_TYPE_HEX_STR) == MP_EQ) &&
+                (wc_ecc_cmp_param(ecc_sets[idx].Af, (const byte*)dp->Af,
+                    (word32)XSTRLEN(dp->Af),WC_TYPE_HEX_STR) == MP_EQ) &&
+                (wc_ecc_cmp_param(ecc_sets[idx].Bf, (const byte*)dp->Bf,
+                    (word32)XSTRLEN(dp->Bf),WC_TYPE_HEX_STR) == MP_EQ) &&
+                (wc_ecc_cmp_param(ecc_sets[idx].order, (const byte*)dp->order,
+                    (word32)XSTRLEN(dp->order),WC_TYPE_HEX_STR) == MP_EQ) &&
+                (wc_ecc_cmp_param(ecc_sets[idx].Gx, (const byte*)dp->Gx,
+                    (word32)XSTRLEN(dp->Gx),WC_TYPE_HEX_STR) == MP_EQ) &&
+                (wc_ecc_cmp_param(ecc_sets[idx].Gy, (const byte*)dp->Gy,
+                    (word32)XSTRLEN(dp->Gy),WC_TYPE_HEX_STR) == MP_EQ) &&
+                (dp->cofactor == ecc_sets[idx].cofactor)) {
+                    break;
+            }
+        }
+    }
+
+    if (ecc_sets[idx].size == 0)
+        return ECC_CURVE_INVALID;
+
+    return ecc_sets[idx].id;
+}
+
+/* Returns the curve id that corresponds to a given OID,
+ * as listed in ecc_sets[] of ecc.c.
+ *
+ * oid   OID, from ecc_sets[].name in ecc.c
+ * len   OID len, from ecc_sets[].name in ecc.c
+ * return curve id, from ecc_sets[] on success, negative on error
+ */
+int wc_ecc_get_curve_id_from_oid(const byte* oid, word32 len)
+{
+    int curve_idx;
+
+    if (oid == NULL)
+        return BAD_FUNC_ARG;
+
+    for (curve_idx = 0; ecc_sets[curve_idx].size != 0; curve_idx++) {
+        if (
+        #ifndef WOLFSSL_ECC_CURVE_STATIC
+            ecc_sets[curve_idx].oid &&
+        #endif
+            ecc_sets[curve_idx].oidSz == len &&
+                              XMEMCMP(ecc_sets[curve_idx].oid, oid, len) == 0) {
+            break;
+        }
+    }
+    if (ecc_sets[curve_idx].size == 0) {
+        WOLFSSL_MSG("ecc_set curve name not found");
+        return ECC_CURVE_INVALID;
+    }
+
+    return ecc_sets[curve_idx].id;
+}
+
+/* Get curve parameters using curve index */
+const ecc_set_type* wc_ecc_get_curve_params(int curve_idx)
+{
+    const ecc_set_type* ecc_set = NULL;
+
+    if (curve_idx >= 0 && curve_idx < (int)ECC_SET_COUNT) {
+        ecc_set = &ecc_sets[curve_idx];
+    }
+    return ecc_set;
+}
+
+
+#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC)
+static WC_INLINE int wc_ecc_alloc_mpint(ecc_key* key, mp_int** mp)
+{
+   if (key == NULL || mp == NULL)
+      return BAD_FUNC_ARG;
+   if (*mp == NULL) {
+      *mp = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_BIGINT);
+      if (*mp == NULL) {
+         return MEMORY_E;
+      }
+      XMEMSET(*mp, 0, sizeof(mp_int));
+   }
+   return 0;
+}
+static WC_INLINE void wc_ecc_free_mpint(ecc_key* key, mp_int** mp)
+{
+   if (key && mp && *mp) {
+      mp_clear(*mp);
+      XFREE(*mp, key->heap, DYNAMIC_TYPE_BIGINT);
+      *mp = NULL;
+   }
+}
+
+static int wc_ecc_alloc_async(ecc_key* key)
+{
+    int err = wc_ecc_alloc_mpint(key, &key->r);
+    if (err == 0)
+        err = wc_ecc_alloc_mpint(key, &key->s);
+    return err;
+}
+
+static void wc_ecc_free_async(ecc_key* key)
+{
+    wc_ecc_free_mpint(key, &key->r);
+    wc_ecc_free_mpint(key, &key->s);
+#ifdef HAVE_CAVIUM_V
+    wc_ecc_free_mpint(key, &key->e);
+    wc_ecc_free_mpint(key, &key->signK);
+#endif /* HAVE_CAVIUM_V */
+}
+#endif /* WOLFSSL_ASYNC_CRYPT && WC_ASYNC_ENABLE_ECC */
+
+
+#ifdef HAVE_ECC_DHE
+/**
+  Create an ECC shared secret between two keys
+  private_key      The private ECC key (heap hint based off of private key)
+  public_key       The public key
+  out              [out] Destination of the shared secret
+                         Conforms to EC-DH from ANSI X9.63
+  outlen           [in/out] The max size and resulting size of the shared secret
+  return           MP_OKAY if successful
+*/
+int wc_ecc_shared_secret(ecc_key* private_key, ecc_key* public_key, byte* out,
+                      word32* outlen)
+{
+   int err;
+#if defined(WOLFSSL_CRYPTOCELL) && !defined(WOLFSSL_ATECC508A)
+   CRYS_ECDH_TempData_t tempBuff;
+#endif
+   if (private_key == NULL || public_key == NULL || out == NULL ||
+                                                            outlen == NULL) {
+       return BAD_FUNC_ARG;
+   }
+
+#ifdef WOLF_CRYPTO_CB
+    if (private_key->devId != INVALID_DEVID) {
+        err = wc_CryptoCb_Ecdh(private_key, public_key, out, outlen);
+        if (err != CRYPTOCB_UNAVAILABLE)
+            return err;
+        /* fall-through when unavailable */
+    }
+#endif
+
+   /* type valid? */
+   if (private_key->type != ECC_PRIVATEKEY &&
+           private_key->type != ECC_PRIVATEKEY_ONLY) {
+      return ECC_BAD_ARG_E;
+   }
+
+   /* Verify domain params supplied */
+   if (wc_ecc_is_valid_idx(private_key->idx) == 0 ||
+       wc_ecc_is_valid_idx(public_key->idx)  == 0) {
+      return ECC_BAD_ARG_E;
+   }
+
+   /* Verify curve id matches */
+   if (private_key->dp->id != public_key->dp->id) {
+      return ECC_BAD_ARG_E;
+   }
+
+#ifdef WOLFSSL_ATECC508A
+   /* For SECP256R1 use hardware */
+   if (private_key->dp->id == ECC_SECP256R1) {
+       err = atmel_ecc_create_pms(private_key->slot, public_key->pubkey_raw, out);
+       *outlen = private_key->dp->size;
+   }
+   else {
+      err = NOT_COMPILED_IN;
+   }
+#elif defined(WOLFSSL_CRYPTOCELL)
+
+    /* generate a secret*/
+    err = CRYS_ECDH_SVDP_DH(&public_key->ctx.pubKey,
+                            &private_key->ctx.privKey,
+                            out,
+                            outlen,
+                            &tempBuff);
+
+    if (err != SA_SILIB_RET_OK){
+        WOLFSSL_MSG("CRYS_ECDH_SVDP_DH for secret failed");
+        return err;
+    }
+
+#else
+   err = wc_ecc_shared_secret_ex(private_key, &public_key->pubkey, out, outlen);
+#endif /* WOLFSSL_ATECC508A */
+
+   return err;
+}
+
+
+#if !defined(WOLFSSL_ATECC508A) && !defined(WOLFSSL_CRYPTOCELL)
+
+static int wc_ecc_shared_secret_gen_sync(ecc_key* private_key, ecc_point* point,
+                               byte* out, word32* outlen, ecc_curve_spec* curve)
+{
+    int err;
+#ifndef WOLFSSL_SP_MATH
+    ecc_point* result = NULL;
+    word32 x = 0;
+#endif
+    mp_int* k = &private_key->k;
+#ifdef HAVE_ECC_CDH
+    mp_int k_lcl;
+
+    /* if cofactor flag has been set */
+    if (private_key->flags & WC_ECC_FLAG_COFACTOR) {
+        mp_digit cofactor = (mp_digit)private_key->dp->cofactor;
+        /* only perform cofactor calc if not equal to 1 */
+        if (cofactor != 1) {
+            k = &k_lcl;
+            if (mp_init(k) != MP_OKAY)
+                return MEMORY_E;
+            /* multiply cofactor times private key "k" */
+            err = mp_mul_d(&private_key->k, cofactor, k);
+            if (err != MP_OKAY) {
+                mp_clear(k);
+                return err;
+            }
+        }
+    }
+#endif
+
+#ifdef WOLFSSL_HAVE_SP_ECC
+#ifndef WOLFSSL_SP_NO_256
+    if (private_key->idx != ECC_CUSTOM_IDX &&
+                               ecc_sets[private_key->idx].id == ECC_SECP256R1) {
+        err = sp_ecc_secret_gen_256(k, point, out, outlen, private_key->heap);
+    }
+    else
+#endif
+#ifdef WOLFSSL_SP_384
+    if (private_key->idx != ECC_CUSTOM_IDX &&
+                               ecc_sets[private_key->idx].id == ECC_SECP384R1) {
+        err = sp_ecc_secret_gen_384(k, point, out, outlen, private_key->heap);
+    }
+    else
+#endif
+#endif
+#ifdef WOLFSSL_SP_MATH
+    {
+        err = WC_KEY_SIZE_E;
+
+        (void)curve;
+    }
+#else
+    {
+        mp_digit mp = 0;
+
+        /* make new point */
+        result = wc_ecc_new_point_h(private_key->heap);
+        if (result == NULL) {
+#ifdef HAVE_ECC_CDH
+            if (k == &k_lcl)
+                mp_clear(k);
+#endif
+            return MEMORY_E;
+        }
+
+        /* Map in a separate call as this should be constant time */
+        err = wc_ecc_mulmod_ex(k, point, result, curve->Af, curve->prime, 0,
+                                                             private_key->heap);
+        if (err == MP_OKAY) {
+            err = mp_montgomery_setup(curve->prime, &mp);
+        }
+        if (err == MP_OKAY) {
+            /* Use constant time map if compiled in */
+            err = ecc_map_ex(result, curve->prime, mp, 1);
+        }
+        if (err == MP_OKAY) {
+            x = mp_unsigned_bin_size(curve->prime);
+            if (*outlen < x || (int)x < mp_unsigned_bin_size(result->x)) {
+                err = BUFFER_E;
+            }
+        }
+
+        if (err == MP_OKAY) {
+            XMEMSET(out, 0, x);
+            err = mp_to_unsigned_bin(result->x,out +
+                                     (x - mp_unsigned_bin_size(result->x)));
+        }
+        *outlen = x;
+
+        wc_ecc_del_point_h(result, private_key->heap);
+    }
+#endif
+#ifdef HAVE_ECC_CDH
+    if (k == &k_lcl)
+        mp_clear(k);
+#endif
+
+    return err;
+}
+
+#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC)
+static int wc_ecc_shared_secret_gen_async(ecc_key* private_key,
+            ecc_point* point, byte* out, word32 *outlen,
+            ecc_curve_spec* curve)
+{
+    int err;
+
+#if defined(HAVE_CAVIUM_V) || defined(HAVE_INTEL_QA)
+#ifdef HAVE_CAVIUM_V
+    /* verify the curve is supported by hardware */
+    if (NitroxEccIsCurveSupported(private_key))
+#endif
+    {
+        word32 keySz = private_key->dp->size;
+
+        /* sync public key x/y */
+        err = wc_mp_to_bigint_sz(&private_key->k, &private_key->k.raw, keySz);
+        if (err == MP_OKAY)
+            err = wc_mp_to_bigint_sz(point->x, &point->x->raw, keySz);
+        if (err == MP_OKAY)
+            err = wc_mp_to_bigint_sz(point->y, &point->y->raw, keySz);
+    #ifdef HAVE_CAVIUM_V
+        /* allocate buffer for output */
+        if (err == MP_OKAY)
+            err = wc_ecc_alloc_mpint(private_key, &private_key->e);
+        if (err == MP_OKAY)
+            err = wc_bigint_alloc(&private_key->e->raw,
+                NitroxEccGetSize(private_key)*2);
+        if (err == MP_OKAY)
+            err = NitroxEcdh(private_key,
+                &private_key->k.raw, &point->x->raw, &point->y->raw,
+                private_key->e->raw.buf, &private_key->e->raw.len,
+                &curve->prime->raw);
+    #else
+        if (err == MP_OKAY)
+            err = wc_ecc_curve_load(private_key->dp, &curve, ECC_CURVE_FIELD_BF);
+        if (err == MP_OKAY)
+            err = IntelQaEcdh(&private_key->asyncDev,
+                &private_key->k.raw, &point->x->raw, &point->y->raw,
+                out, outlen,
+                &curve->Af->raw, &curve->Bf->raw, &curve->prime->raw,
+                private_key->dp->cofactor);
+    #endif
+        return err;
+    }
+#elif defined(WOLFSSL_ASYNC_CRYPT_TEST)
+    if (wc_AsyncTestInit(&private_key->asyncDev, ASYNC_TEST_ECC_SHARED_SEC)) {
+        WC_ASYNC_TEST* testDev = &private_key->asyncDev.test;
+        testDev->eccSharedSec.private_key = private_key;
+        testDev->eccSharedSec.public_point = point;
+        testDev->eccSharedSec.out = out;
+        testDev->eccSharedSec.outLen = outlen;
+        return WC_PENDING_E;
+    }
+#endif
+
+    /* use sync in other cases */
+    err = wc_ecc_shared_secret_gen_sync(private_key, point, out, outlen, curve);
+
+    return err;
+}
+#endif /* WOLFSSL_ASYNC_CRYPT && WC_ASYNC_ENABLE_ECC */
+
+int wc_ecc_shared_secret_gen(ecc_key* private_key, ecc_point* point,
+                                                    byte* out, word32 *outlen)
+{
+    int err;
+    DECLARE_CURVE_SPECS(curve, 2);
+
+    if (private_key == NULL || point == NULL || out == NULL ||
+                                                            outlen == NULL) {
+        return BAD_FUNC_ARG;
+    }
+
+    /* load curve info */
+    ALLOC_CURVE_SPECS(2);
+    err = wc_ecc_curve_load(private_key->dp, &curve,
+        (ECC_CURVE_FIELD_PRIME | ECC_CURVE_FIELD_AF));
+    if (err != MP_OKAY) {
+        FREE_CURVE_SPECS();
+        return err;
+    }
+
+#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC)
+    if (private_key->asyncDev.marker == WOLFSSL_ASYNC_MARKER_ECC) {
+        err = wc_ecc_shared_secret_gen_async(private_key, point,
+            out, outlen, curve);
+    }
+    else
+#endif
+    {
+        err = wc_ecc_shared_secret_gen_sync(private_key, point,
+            out, outlen, curve);
+    }
+
+    wc_ecc_curve_free(curve);
+    FREE_CURVE_SPECS();
+
+    return err;
+}
+
+/**
+ Create an ECC shared secret between private key and public point
+ private_key      The private ECC key (heap hint based on private key)
+ point            The point to use (public key)
+ out              [out] Destination of the shared secret
+                        Conforms to EC-DH from ANSI X9.63
+ outlen           [in/out] The max size and resulting size of the shared secret
+ return           MP_OKAY if successful
+*/
+int wc_ecc_shared_secret_ex(ecc_key* private_key, ecc_point* point,
+                            byte* out, word32 *outlen)
+{
+    int err;
+
+    if (private_key == NULL || point == NULL || out == NULL ||
+                                                            outlen == NULL) {
+        return BAD_FUNC_ARG;
+    }
+
+    /* type valid? */
+    if (private_key->type != ECC_PRIVATEKEY &&
+            private_key->type != ECC_PRIVATEKEY_ONLY) {
+        return ECC_BAD_ARG_E;
+    }
+
+    /* Verify domain params supplied */
+    if (wc_ecc_is_valid_idx(private_key->idx) == 0)
+        return ECC_BAD_ARG_E;
+
+    switch(private_key->state) {
+        case ECC_STATE_NONE:
+        case ECC_STATE_SHARED_SEC_GEN:
+            private_key->state = ECC_STATE_SHARED_SEC_GEN;
+
+            err = wc_ecc_shared_secret_gen(private_key, point, out, outlen);
+            if (err < 0) {
+                break;
+            }
+            FALL_THROUGH;
+
+        case ECC_STATE_SHARED_SEC_RES:
+            private_key->state = ECC_STATE_SHARED_SEC_RES;
+        #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC)
+            if (private_key->asyncDev.marker == WOLFSSL_ASYNC_MARKER_ECC) {
+            #ifdef HAVE_CAVIUM_V
+                /* verify the curve is supported by hardware */
+                if (NitroxEccIsCurveSupported(private_key)) {
+                    /* copy output */
+                    *outlen = private_key->dp->size;
+                    XMEMCPY(out, private_key->e->raw.buf, *outlen);
+                }
+            #endif /* HAVE_CAVIUM_V */
+            }
+        #endif /* WOLFSSL_ASYNC_CRYPT */
+            err = 0;
+            break;
+
+        default:
+            err = BAD_STATE_E;
+    } /* switch */
+
+    /* if async pending then return and skip done cleanup below */
+    if (err == WC_PENDING_E) {
+        private_key->state++;
+        return err;
+    }
+
+    /* cleanup */
+#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC)
+    wc_ecc_free_async(private_key);
+#endif
+    private_key->state = ECC_STATE_NONE;
+
+    return err;
+}
+#endif /* !WOLFSSL_ATECC508A && !WOLFSSL_CRYPTOCELL */
+#endif /* HAVE_ECC_DHE */
+
+
+#if !defined(WOLFSSL_ATECC508A) && !defined(WOLFSSL_CRYPTOCELL)
+/* return 1 if point is at infinity, 0 if not, < 0 on error */
+int wc_ecc_point_is_at_infinity(ecc_point* p)
+{
+    if (p == NULL)
+        return BAD_FUNC_ARG;
+
+    if (get_digit_count(p->x) == 0 && get_digit_count(p->y) == 0)
+        return 1;
+
+    return 0;
+}
+
+/* generate random and ensure its greater than 0 and less than order */
+int wc_ecc_gen_k(WC_RNG* rng, int size, mp_int* k, mp_int* order)
+{
+#ifndef WC_NO_RNG
+    int err;
+    byte buf[ECC_MAXSIZE_GEN];
+
+    /*generate 8 extra bytes to mitigate bias from the modulo operation below*/
+    /*see section A.1.2 in 'Suite B Implementor's Guide to FIPS 186-3 (ECDSA)'*/
+    size += 8;
+
+    /* make up random string */
+    err = wc_RNG_GenerateBlock(rng, buf, size);
+
+    /* load random buffer data into k */
+    if (err == 0)
+        err = mp_read_unsigned_bin(k, (byte*)buf, size);
+
+    /* the key should be smaller than the order of base point */
+    if (err == MP_OKAY) {
+        if (mp_cmp(k, order) != MP_LT) {
+            err = mp_mod(k, order, k);
+        }
+    }
+
+    /* quick sanity check to make sure we're not dealing with a 0 key */
+    if (err == MP_OKAY) {
+        if (mp_iszero(k) == MP_YES)
+          err = MP_ZERO_E;
+    }
+
+    ForceZero(buf, ECC_MAXSIZE);
+
+    return err;
+#else
+    (void)rng;
+    (void)size;
+    (void)k;
+    (void)order;
+    return NOT_COMPILED_IN;
+#endif /* !WC_NO_RNG */
+}
+#endif /* !WOLFSSL_ATECC508A && !WOLFSSL_CRYPTOCELL */
+
+static WC_INLINE void wc_ecc_reset(ecc_key* key)
+{
+    /* make sure required key variables are reset */
+    key->state = ECC_STATE_NONE;
+}
+
+
+/* create the public ECC key from a private key
+ *
+ * key     an initialized private key to generate public part from
+ * curveIn [in]curve for key, can be NULL
+ * pubOut  [out]ecc_point holding the public key, if NULL then public key part
+ *         is cached in key instead.
+ *
+ * Note this function is local to the file because of the argument type
+ *      ecc_curve_spec. Having this argument allows for not having to load the
+ *      curve type multiple times when generating a key with wc_ecc_make_key().
+ *
+ * returns MP_OKAY on success
+ */
+static int wc_ecc_make_pub_ex(ecc_key* key, ecc_curve_spec* curveIn,
+        ecc_point* pubOut)
+{
+    int err = MP_OKAY;
+#ifndef WOLFSSL_ATECC508A
+#ifndef WOLFSSL_SP_MATH
+    ecc_point* base = NULL;
+#endif
+    ecc_point* pub;
+    DECLARE_CURVE_SPECS(curve, ECC_CURVE_FIELD_COUNT);
+#endif /* !WOLFSSL_ATECC508A */
+
+    if (key == NULL) {
+        return BAD_FUNC_ARG;
+    }
+
+#ifndef WOLFSSL_ATECC508A
+
+    /* if ecc_point passed in then use it as output for public key point */
+    if (pubOut != NULL) {
+        pub = pubOut;
+    }
+    else {
+        /* caching public key making it a ECC_PRIVATEKEY instead of
+           ECC_PRIVATEKEY_ONLY */
+        pub = &key->pubkey;
+        key->type = ECC_PRIVATEKEY_ONLY;
+    }
+
+    /* avoid loading the curve unless it is not passed in */
+    if (curveIn != NULL) {
+        curve = curveIn;
+    }
+    else {
+        /* load curve info */
+        if (err == MP_OKAY) {
+            ALLOC_CURVE_SPECS(ECC_CURVE_FIELD_COUNT);
+            err = wc_ecc_curve_load(key->dp, &curve, ECC_CURVE_FIELD_ALL);
+        }
+    }
+
+    if (err == MP_OKAY) {
+    #ifndef ALT_ECC_SIZE
+        err = mp_init_multi(pub->x, pub->y, pub->z, NULL, NULL, NULL);
+    #else
+        pub->x = (mp_int*)&pub->xyz[0];
+        pub->y = (mp_int*)&pub->xyz[1];
+        pub->z = (mp_int*)&pub->xyz[2];
+        alt_fp_init(pub->x);
+        alt_fp_init(pub->y);
+        alt_fp_init(pub->z);
+    #endif
+    }
+
+
+    if (err != MP_OKAY) {
+    }
+    else
+#ifdef WOLFSSL_HAVE_SP_ECC
+#ifndef WOLFSSL_SP_NO_256
+    if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SECP256R1) {
+        err = sp_ecc_mulmod_base_256(&key->k, pub, 1, key->heap);
+    }
+    else
+#endif
+#ifdef WOLFSSL_SP_384
+    if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SECP384R1) {
+        err = sp_ecc_mulmod_base_384(&key->k, pub, 1, key->heap);
+    }
+    else
+#endif
+#endif
+#ifdef WOLFSSL_SP_MATH
+        err = WC_KEY_SIZE_E;
+#else
+    {
+        mp_digit mp;
+
+        base = wc_ecc_new_point_h(key->heap);
+        if (base == NULL)
+            err = MEMORY_E;
+        /* read in the x/y for this key */
+        if (err == MP_OKAY)
+            err = mp_copy(curve->Gx, base->x);
+        if (err == MP_OKAY)
+            err = mp_copy(curve->Gy, base->y);
+        if (err == MP_OKAY)
+            err = mp_set(base->z, 1);
+
+        /* make the public key */
+        if (err == MP_OKAY) {
+            /* Map in a separate call as this should be constant time */
+            err = wc_ecc_mulmod_ex(&key->k, base, pub, curve->Af, curve->prime,
+                                                                  0, key->heap);
+            if (err == MP_MEM) {
+               err = MEMORY_E;
+            }
+        }
+        if (err == MP_OKAY) {
+            err = mp_montgomery_setup(curve->prime, &mp);
+        }
+        if (err == MP_OKAY) {
+            /* Use constant time map if compiled in */
+            err = ecc_map_ex(pub, curve->prime, mp, 1);
+        }
+
+        wc_ecc_del_point_h(base, key->heap);
+    }
+#endif
+
+#ifdef WOLFSSL_VALIDATE_ECC_KEYGEN
+    /* validate the public key, order * pubkey = point at infinity */
+    if (err == MP_OKAY)
+        err = ecc_check_pubkey_order(key, pub, curve->Af, curve->prime,
+                curve->order);
+#endif /* WOLFSSL_VALIDATE_KEYGEN */
+
+    if (err != MP_OKAY) {
+        /* clean up if failed */
+    #ifndef ALT_ECC_SIZE
+        mp_clear(pub->x);
+        mp_clear(pub->y);
+        mp_clear(pub->z);
+    #endif
+    }
+
+    /* free up local curve */
+    if (curveIn == NULL) {
+        wc_ecc_curve_free(curve);
+        FREE_CURVE_SPECS();
+    }
+
+#else
+    (void)curveIn;
+    err = NOT_COMPILED_IN;
+#endif /* WOLFSSL_ATECC508A */
+
+    /* change key state if public part is cached */
+    if (key->type == ECC_PRIVATEKEY_ONLY && pubOut == NULL) {
+        key->type = ECC_PRIVATEKEY;
+    }
+
+    return err;
+}
+
+
+/* create the public ECC key from a private key
+ *
+ * key     an initialized private key to generate public part from
+ * pubOut  [out]ecc_point holding the public key, if NULL then public key part
+ *         is cached in key instead.
+ *
+ *
+ * returns MP_OKAY on success
+ */
+int wc_ecc_make_pub(ecc_key* key, ecc_point* pubOut)
+{
+    WOLFSSL_ENTER("wc_ecc_make_pub");
+
+    return wc_ecc_make_pub_ex(key, NULL, pubOut);
+}
+
+
+WOLFSSL_ABI
+int wc_ecc_make_key_ex(WC_RNG* rng, int keysize, ecc_key* key, int curve_id)
+{
+    int err;
+#if !defined(WOLFSSL_ATECC508A) && !defined(WOLFSSL_CRYPTOCELL)
+#ifndef WOLFSSL_SP_MATH
+    DECLARE_CURVE_SPECS(curve, ECC_CURVE_FIELD_COUNT);
+#endif
+#endif /* !WOLFSSL_ATECC508A */
+#if defined(WOLFSSL_CRYPTOCELL) && !defined(WOLFSSL_ATECC508A)
+    const CRYS_ECPKI_Domain_t*  pDomain;
+    CRYS_ECPKI_KG_TempData_t    tempBuff;
+    CRYS_ECPKI_KG_FipsContext_t fipsCtx;
+    byte ucompressed_key[ECC_MAX_CRYPTO_HW_SIZE*2 + 1];
+    word32 raw_size = 0;
+#endif
+    if (key == NULL || rng == NULL) {
+        return BAD_FUNC_ARG;
+    }
+
+    /* make sure required variables are reset */
+    wc_ecc_reset(key);
+
+    err = wc_ecc_set_curve(key, keysize, curve_id);
+    if (err != 0) {
+        return err;
+    }
+
+#ifdef WOLF_CRYPTO_CB
+    if (key->devId != INVALID_DEVID) {
+        err = wc_CryptoCb_MakeEccKey(rng, keysize, key, curve_id);
+        if (err != CRYPTOCB_UNAVAILABLE)
+            return err;
+        /* fall-through when unavailable */
+    }
+#endif
+
+#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC)
+    if (key->asyncDev.marker == WOLFSSL_ASYNC_MARKER_ECC) {
+    #ifdef HAVE_CAVIUM
+        /* TODO: Not implemented */
+    #elif defined(HAVE_INTEL_QA)
+        /* TODO: Not implemented */
+    #else
+        if (wc_AsyncTestInit(&key->asyncDev, ASYNC_TEST_ECC_MAKE)) {
+            WC_ASYNC_TEST* testDev = &key->asyncDev.test;
+            testDev->eccMake.rng = rng;
+            testDev->eccMake.key = key;
+            testDev->eccMake.size = keysize;
+            testDev->eccMake.curve_id = curve_id;
+            return WC_PENDING_E;
+        }
+    #endif
+    }
+#endif /* WOLFSSL_ASYNC_CRYPT && WC_ASYNC_ENABLE_ECC */
+
+#ifdef WOLFSSL_ATECC508A
+   if (key->dp->id == ECC_SECP256R1) {
+       key->type = ECC_PRIVATEKEY;
+       key->slot = atmel_ecc_alloc(ATMEL_SLOT_ECDHE);
+       err = atmel_ecc_create_key(key->slot, key->pubkey_raw);
+
+       /* populate key->pubkey */
+       if (err == 0
+       #ifdef ALT_ECC_SIZE
+          && key->pubkey.x
+       #endif
+       ) {
+           err = mp_read_unsigned_bin(key->pubkey.x, key->pubkey_raw,
+                                      ECC_MAX_CRYPTO_HW_SIZE);
+       }
+       if (err == 0
+       #ifdef ALT_ECC_SIZE
+          && key->pubkey.y
+       #endif
+       ) {
+           err = mp_read_unsigned_bin(key->pubkey.y,
+                                      key->pubkey_raw + ECC_MAX_CRYPTO_HW_SIZE,
+                                      ECC_MAX_CRYPTO_HW_SIZE);
+       }
+   }
+   else {
+      err = NOT_COMPILED_IN;
+   }
+#elif defined(WOLFSSL_CRYPTOCELL)
+
+    pDomain = CRYS_ECPKI_GetEcDomain(cc310_mapCurve(curve_id));
+    raw_size = (word32)(key->dp->size)*2 + 1;
+
+    /* generate first key pair */
+    err = CRYS_ECPKI_GenKeyPair(&wc_rndState,
+                                wc_rndGenVectFunc,
+                                pDomain,
+                                &key->ctx.privKey,
+                                &key->ctx.pubKey,
+                                &tempBuff,
+                                &fipsCtx);
+
+    if (err != SA_SILIB_RET_OK){
+        WOLFSSL_MSG("CRYS_ECPKI_GenKeyPair for key pair failed");
+        return err;
+    }
+    key->type = ECC_PRIVATEKEY;
+
+    err = CRYS_ECPKI_ExportPublKey(&key->ctx.pubKey,
+                                   CRYS_EC_PointUncompressed,
+                                   &ucompressed_key[0],
+                                   &raw_size);
+
+    if (err == SA_SILIB_RET_OK && key->pubkey.x && key->pubkey.y) {
+        err = mp_read_unsigned_bin(key->pubkey.x,
+                                   &ucompressed_key[1], key->dp->size);
+        if (err == MP_OKAY) {
+            err = mp_read_unsigned_bin(key->pubkey.y,
+                            &ucompressed_key[1+key->dp->size],key->dp->size);
+        }
+    }
+    raw_size = key->dp->size;
+    if (err == MP_OKAY) {
+        err = CRYS_ECPKI_ExportPrivKey(&key->ctx.privKey,
+                                       ucompressed_key,
+                                       &raw_size);
+    }
+
+    if (err == SA_SILIB_RET_OK) {
+        err = mp_read_unsigned_bin(&key->k, ucompressed_key, raw_size);
+    }
+
+#else
+
+#ifdef WOLFSSL_HAVE_SP_ECC
+#ifndef WOLFSSL_SP_NO_256
+    if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SECP256R1) {
+        err = sp_ecc_make_key_256(rng, &key->k, &key->pubkey, key->heap);
+        if (err == MP_OKAY) {
+            key->type = ECC_PRIVATEKEY;
+        }
+    }
+    else
+#endif
+#ifdef WOLFSSL_SP_384
+    if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SECP384R1) {
+        err = sp_ecc_make_key_384(rng, &key->k, &key->pubkey, key->heap);
+        if (err == MP_OKAY) {
+            key->type = ECC_PRIVATEKEY;
+        }
+    }
+    else
+#endif
+#endif /* WOLFSSL_HAVE_SP_ECC */
+
+   { /* software key gen */
+#ifdef WOLFSSL_SP_MATH
+        err = WC_KEY_SIZE_E;
+#else
+
+        /* setup the key variables */
+        err = mp_init(&key->k);
+
+        /* load curve info */
+        if (err == MP_OKAY) {
+            ALLOC_CURVE_SPECS(ECC_CURVE_FIELD_COUNT);
+            err = wc_ecc_curve_load(key->dp, &curve, ECC_CURVE_FIELD_ALL);
+        }
+
+        /* generate k */
+        if (err == MP_OKAY)
+            err = wc_ecc_gen_k(rng, key->dp->size, &key->k, curve->order);
+
+        /* generate public key from k */
+        if (err == MP_OKAY)
+            err = wc_ecc_make_pub_ex(key, curve, NULL);
+
+        if (err == MP_OKAY)
+            key->type = ECC_PRIVATEKEY;
+
+        /* cleanup these on failure case only */
+        if (err != MP_OKAY) {
+            /* clean up */
+            mp_forcezero(&key->k);
+        }
+
+        /* cleanup allocations */
+        wc_ecc_curve_free(curve);
+        FREE_CURVE_SPECS();
+#endif /* WOLFSSL_SP_MATH */
+    }
+
+#ifdef HAVE_WOLF_BIGINT
+    if (err == MP_OKAY)
+         err = wc_mp_to_bigint(&key->k, &key->k.raw);
+    if (err == MP_OKAY)
+         err = wc_mp_to_bigint(key->pubkey.x, &key->pubkey.x->raw);
+    if (err == MP_OKAY)
+         err = wc_mp_to_bigint(key->pubkey.y, &key->pubkey.y->raw);
+    if (err == MP_OKAY)
+         err = wc_mp_to_bigint(key->pubkey.z, &key->pubkey.z->raw);
+#endif
+
+#endif /* WOLFSSL_ATECC508A */
+
+    return err;
+}
+
+#ifdef ECC_DUMP_OID
+/* Optional dump of encoded OID for adding new curves */
+static int mOidDumpDone;
+static void wc_ecc_dump_oids(void)
+{
+    int x;
+
+    if (mOidDumpDone) {
+        return;
+    }
+
+    /* find matching OID sum (based on encoded value) */
+    for (x = 0; ecc_sets[x].size != 0; x++) {
+        int i;
+        byte* oid;
+        word32 oidSz, sum = 0;
+
+        printf("ECC %s (%d):\n", ecc_sets[x].name, x);
+
+    #ifdef HAVE_OID_ENCODING
+        byte oidEnc[ECC_MAX_OID_LEN];
+
+        oid = oidEnc;
+        oidSz = ECC_MAX_OID_LEN;
+
+        printf("OID: ");
+        for (i = 0; i < (int)ecc_sets[x].oidSz; i++) {
+            printf("%d.", ecc_sets[x].oid[i]);
+        }
+        printf("\n");
+
+        EncodeObjectId(ecc_sets[x].oid, ecc_sets[x].oidSz, oidEnc, &oidSz);
+    #else
+        oid = (byte*)ecc_sets[x].oid;
+        oidSz = ecc_sets[x].oidSz;
+    #endif
+
+        printf("OID Encoded: ");
+        for (i = 0; i < (int)oidSz; i++) {
+            printf("0x%02X,", oid[i]);
+        }
+        printf("\n");
+
+        for (i = 0; i < (int)oidSz; i++) {
+            sum += oid[i];
+        }
+        printf("Sum: %d\n", sum);
+
+        /* validate sum */
+        if (ecc_sets[x].oidSum != sum) {
+            printf("  Sum %d Not Valid!\n", ecc_sets[x].oidSum);
+        }
+    }
+    mOidDumpDone = 1;
+}
+#endif /* ECC_DUMP_OID */
+
+
+WOLFSSL_ABI
+ecc_key* wc_ecc_key_new(void* heap)
+{
+    ecc_key* key;
+
+    key = (ecc_key*)XMALLOC(sizeof(ecc_key), heap, DYNAMIC_TYPE_ECC);
+    if (key) {
+        if (wc_ecc_init_ex(key, heap, INVALID_DEVID) != 0) {
+            XFREE(key, heap, DYNAMIC_TYPE_ECC);
+            key = NULL;
+        }
+    }
+
+    return key;
+}
+
+
+WOLFSSL_ABI
+void wc_ecc_key_free(ecc_key* key)
+{
+    if (key) {
+        void* heap = key->heap;
+
+        wc_ecc_free(key);
+        ForceZero(key, sizeof(ecc_key));
+        XFREE(key, heap, DYNAMIC_TYPE_ECC);
+        (void)heap;
+    }
+}
+
+
+/**
+ Make a new ECC key
+ rng          An active RNG state
+ keysize      The keysize for the new key (in octets from 20 to 65 bytes)
+ key          [out] Destination of the newly created key
+ return       MP_OKAY if successful,
+ upon error all allocated memory will be freed
+ */
+int wc_ecc_make_key(WC_RNG* rng, int keysize, ecc_key* key)
+{
+    return wc_ecc_make_key_ex(rng, keysize, key, ECC_CURVE_DEF);
+}
+
+/* Setup dynamic pointers if using normal math for proper freeing */
+WOLFSSL_ABI
+int wc_ecc_init_ex(ecc_key* key, void* heap, int devId)
+{
+    int ret = 0;
+
+    if (key == NULL) {
+        return BAD_FUNC_ARG;
+    }
+
+#ifdef ECC_DUMP_OID
+    wc_ecc_dump_oids();
+#endif
+
+    XMEMSET(key, 0, sizeof(ecc_key));
+    key->state = ECC_STATE_NONE;
+
+#if defined(PLUTON_CRYPTO_ECC) || defined(WOLF_CRYPTO_CB)
+    key->devId = devId;
+#else
+    (void)devId;
+#endif
+
+#ifdef WOLFSSL_ATECC508A
+    key->slot = ATECC_INVALID_SLOT;
+#else
+#ifdef ALT_ECC_SIZE
+    key->pubkey.x = (mp_int*)&key->pubkey.xyz[0];
+    key->pubkey.y = (mp_int*)&key->pubkey.xyz[1];
+    key->pubkey.z = (mp_int*)&key->pubkey.xyz[2];
+    alt_fp_init(key->pubkey.x);
+    alt_fp_init(key->pubkey.y);
+    alt_fp_init(key->pubkey.z);
+    ret = mp_init(&key->k);
+    if (ret != MP_OKAY) {
+        return MEMORY_E;
+    }
+#else
+    ret = mp_init_multi(&key->k, key->pubkey.x, key->pubkey.y, key->pubkey.z,
+                                                                    NULL, NULL);
+    if (ret != MP_OKAY) {
+        return MEMORY_E;
+    }
+#endif /* ALT_ECC_SIZE */
+#endif /* WOLFSSL_ATECC508A */
+
+#ifdef WOLFSSL_HEAP_TEST
+    key->heap = (void*)WOLFSSL_HEAP_TEST;
+#else
+    key->heap = heap;
+#endif
+
+#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC)
+    /* handle as async */
+    ret = wolfAsync_DevCtxInit(&key->asyncDev, WOLFSSL_ASYNC_MARKER_ECC,
+                                                            key->heap, devId);
+#endif
+
+#if defined(WOLFSSL_DSP)
+    key->handle = -1;
+#endif
+    return ret;
+}
+
+int wc_ecc_init(ecc_key* key)
+{
+    return wc_ecc_init_ex(key, NULL, INVALID_DEVID);
+}
+
+#ifdef HAVE_PKCS11
+int wc_ecc_init_id(ecc_key* key, unsigned char* id, int len, void* heap,
+                   int devId)
+{
+    int ret = 0;
+
+    if (key == NULL)
+        ret = BAD_FUNC_ARG;
+    if (ret == 0 && (len < 0 || len > ECC_MAX_ID_LEN))
+        ret = BUFFER_E;
+
+    if (ret == 0)
+        ret = wc_ecc_init_ex(key, heap, devId);
+
+    if (ret == 0 && id != NULL && len != 0) {
+        XMEMCPY(key->id, id, len);
+        key->idLen = len;
+    }
+
+    return ret;
+}
+#endif
+
+int wc_ecc_set_flags(ecc_key* key, word32 flags)
+{
+    if (key == NULL) {
+        return BAD_FUNC_ARG;
+    }
+    key->flags |= flags;
+    return 0;
+}
+
+
+static int wc_ecc_get_curve_order_bit_count(const ecc_set_type* dp)
+{
+    int err;
+    word32 orderBits;
+    DECLARE_CURVE_SPECS(curve, 1);
+
+    ALLOC_CURVE_SPECS(1);
+    err = wc_ecc_curve_load(dp, &curve, ECC_CURVE_FIELD_ORDER);
+    if (err != 0) {
+       FREE_CURVE_SPECS();
+       return err;
+    }
+    orderBits = mp_count_bits(curve->order);
+
+    wc_ecc_curve_free(curve);
+    FREE_CURVE_SPECS();
+    return (int)orderBits;
+}
+
+#ifdef HAVE_ECC_SIGN
+
+#ifndef NO_ASN
+
+#if defined(WOLFSSL_ATECC508A) || defined(PLUTON_CRYPTO_ECC) || \
+    defined(WOLFSSL_CRYPTOCELL)
+static int wc_ecc_sign_hash_hw(const byte* in, word32 inlen,
+    mp_int* r, mp_int* s, byte* out, word32 *outlen, WC_RNG* rng,
+    ecc_key* key)
+{
+    int err;
+#ifdef PLUTON_CRYPTO_ECC
+    if (key->devId != INVALID_DEVID) /* use hardware */
+#endif
+    {
+    #if defined(WOLFSSL_CRYPTOCELL) && !defined(WOLFSSL_ATECC508A)
+        CRYS_ECDSA_SignUserContext_t sigCtxTemp;
+        word32 raw_sig_size = *outlen;
+        word32 msgLenInBytes = inlen;
+        CRYS_ECPKI_HASH_OpMode_t hash_mode;
+    #endif
+        word32 keysize = (word32)key->dp->size;
+        word32 orderBits = wc_ecc_get_curve_order_bit_count(key->dp);
+
+        /* Check args */
+        if (keysize > ECC_MAX_CRYPTO_HW_SIZE || *outlen < keysize*2) {
+            return ECC_BAD_ARG_E;
+        }
+
+    #if defined(WOLFSSL_ATECC508A)
+        key->slot = atmel_ecc_alloc(ATMEL_SLOT_DEVICE);
+        if (key->slot == ATECC_INVALID_SLOT) {
+            return ECC_BAD_ARG_E;
+        }
+
+        /* Sign: Result is 32-bytes of R then 32-bytes of S */
+        err = atmel_ecc_sign(key->slot, in, out);
+        if (err != 0) {
+           return err;
+        }
+    #elif defined(PLUTON_CRYPTO_ECC)
+        {
+            /* if the input is larger than curve order, we must truncate */
+            if ((inlen * WOLFSSL_BIT_SIZE) > orderBits) {
+               inlen = (orderBits + WOLFSSL_BIT_SIZE - 1) / WOLFSSL_BIT_SIZE;
+            }
+
+            /* perform ECC sign */
+            word32 raw_sig_size = *outlen;
+            err = Crypto_EccSign(in, inlen, out, &raw_sig_size);
+            if (err != CRYPTO_RES_SUCCESS || raw_sig_size != keysize*2){
+               return BAD_COND_E;
+            }
+        }
+    #elif defined(WOLFSSL_CRYPTOCELL)
+
+        hash_mode = cc310_hashModeECC(msgLenInBytes);
+        if (hash_mode == CRYS_ECPKI_HASH_OpModeLast) {
+            hash_mode = cc310_hashModeECC(keysize);
+            hash_mode = CRYS_ECPKI_HASH_SHA256_mode;
+        }
+
+        /* truncate if hash is longer than key size */
+        if (msgLenInBytes > keysize) {
+            msgLenInBytes = keysize;
+        }
+
+        /* create signature from an input buffer using a private key*/
+        err = CRYS_ECDSA_Sign(&wc_rndState,
+                               wc_rndGenVectFunc,
+                               &sigCtxTemp,
+                               &key->ctx.privKey,
+                               hash_mode,
+                               (byte*)in,
+                               msgLenInBytes,
+                               out,
+                               &raw_sig_size);
+
+        if (err != SA_SILIB_RET_OK){
+            WOLFSSL_MSG("CRYS_ECDSA_Sign failed");
+            return err;
+        }
+    #endif
+
+        /* Load R and S */
+        err = mp_read_unsigned_bin(r, &out[0], keysize);
+        if (err != MP_OKAY) {
+            return err;
+        }
+        err = mp_read_unsigned_bin(s, &out[keysize], keysize);
+        if (err != MP_OKAY) {
+            return err;
+        }
+
+        /* Check for zeros */
+        if (mp_iszero(r) || mp_iszero(s)) {
+            return MP_ZERO_E;
+        }
+    }
+#ifdef PLUTON_CRYPTO_ECC
+    else {
+        err = wc_ecc_sign_hash_ex(in, inlen, rng, key, r, s);
+    }
+#endif
+    (void)rng;
+
+    return err;
+}
+#endif /* WOLFSSL_ATECC508A || PLUTON_CRYPTO_ECC || WOLFSSL_CRYPTOCELL */
+
+#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC)
+static int wc_ecc_sign_hash_async(const byte* in, word32 inlen, byte* out,
+    word32 *outlen, WC_RNG* rng, ecc_key* key)
+{
+    int err;
+    mp_int *r = NULL, *s = NULL;
+
+    if (in == NULL || out == NULL || outlen == NULL || key == NULL ||
+                                                                rng == NULL) {
+        return ECC_BAD_ARG_E;
+    }
+
+    err = wc_ecc_alloc_async(key);
+    if (err != 0) {
+        return err;
+    }
+    r = key->r;
+    s = key->s;
+
+    switch(key->state) {
+        case ECC_STATE_NONE:
+        case ECC_STATE_SIGN_DO:
+            key->state = ECC_STATE_SIGN_DO;
+
+            if ((err = mp_init_multi(r, s, NULL, NULL, NULL, NULL)) != MP_OKAY){
+                break;
+            }
+
+            err = wc_ecc_sign_hash_ex(in, inlen, rng, key, r, s);
+            if (err < 0) {
+                break;
+            }
+
+            FALL_THROUGH;
+
+        case ECC_STATE_SIGN_ENCODE:
+            key->state = ECC_STATE_SIGN_ENCODE;
+
+            if (key->asyncDev.marker == WOLFSSL_ASYNC_MARKER_ECC) {
+                #ifdef HAVE_CAVIUM_V
+                    /* Nitrox requires r and s in sep buffer, so split it */
+                    NitroxEccRsSplit(key, &r->raw, &s->raw);
+                #endif
+                #ifndef WOLFSSL_ASYNC_CRYPT_TEST
+                    /* only do this if not simulator, since it overwrites result */
+                    wc_bigint_to_mp(&r->raw, r);
+                    wc_bigint_to_mp(&s->raw, s);
+                #endif
+            }
+
+            /* encoded with DSA header */
+            err = StoreECC_DSA_Sig(out, outlen, r, s);
+
+            /* done with R/S */
+            mp_clear(r);
+            mp_clear(s);
+            break;
+
+        default:
+            err = BAD_STATE_E;
+            break;
+    }
+
+    /* if async pending then return and skip done cleanup below */
+    if (err == WC_PENDING_E) {
+        key->state++;
+        return err;
+    }
+
+    /* cleanup */
+    wc_ecc_free_async(key);
+    key->state = ECC_STATE_NONE;
+
+    return err;
+}
+#endif /* WOLFSSL_ASYNC_CRYPT && WC_ASYNC_ENABLE_ECC */
+
+/**
+ Sign a message digest
+ in        The message digest to sign
+ inlen     The length of the digest
+ out       [out] The destination for the signature
+ outlen    [in/out] The max size and resulting size of the signature
+ key       A private ECC key
+ return    MP_OKAY if successful
+ */
+WOLFSSL_ABI
+int wc_ecc_sign_hash(const byte* in, word32 inlen, byte* out, word32 *outlen,
+                     WC_RNG* rng, ecc_key* key)
+{
+    int err;
+#if !defined(WOLFSSL_ASYNC_CRYPT) || !defined(WC_ASYNC_ENABLE_ECC)
+#ifdef WOLFSSL_SMALL_STACK
+    mp_int *r = NULL, *s = NULL;
+#else
+    mp_int r[1], s[1];
+#endif
+#endif
+
+    if (in == NULL || out == NULL || outlen == NULL || key == NULL ||
+                                                                rng == NULL) {
+        return ECC_BAD_ARG_E;
+    }
+
+#ifdef WOLF_CRYPTO_CB
+    if (key->devId != INVALID_DEVID) {
+        err = wc_CryptoCb_EccSign(in, inlen, out, outlen, rng, key);
+        if (err != CRYPTOCB_UNAVAILABLE)
+            return err;
+        /* fall-through when unavailable */
+    }
+#endif
+
+#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC)
+    /* handle async cases */
+    err = wc_ecc_sign_hash_async(in, inlen, out, outlen, rng, key);
+#else
+
+#ifdef WOLFSSL_SMALL_STACK
+    r = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_ECC);
+    if (r == NULL)
+        return MEMORY_E;
+    s = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_ECC);
+    if (s == NULL) {
+        XFREE(r, key->heap, DYNAMIC_TYPE_ECC);
+        return MEMORY_E;
+    }
+#endif
+    XMEMSET(r, 0, sizeof(mp_int));
+    XMEMSET(s, 0, sizeof(mp_int));
+
+    if ((err = mp_init_multi(r, s, NULL, NULL, NULL, NULL)) != MP_OKAY){
+    #ifdef WOLFSSL_SMALL_STACK
+        XFREE(s, key->heap, DYNAMIC_TYPE_ECC);
+        XFREE(r, key->heap, DYNAMIC_TYPE_ECC);
+    #endif
+        return err;
+    }
+
+/* hardware crypto */
+#if defined(WOLFSSL_ATECC508A) || defined(PLUTON_CRYPTO_ECC) || defined(WOLFSSL_CRYPTOCELL)
+    err = wc_ecc_sign_hash_hw(in, inlen, r, s, out, outlen, rng, key);
+#else
+    err = wc_ecc_sign_hash_ex(in, inlen, rng, key, r, s);
+#endif
+    if (err < 0) {
+    #ifdef WOLFSSL_SMALL_STACK
+        XFREE(s, key->heap, DYNAMIC_TYPE_ECC);
+        XFREE(r, key->heap, DYNAMIC_TYPE_ECC);
+    #endif
+        return err;
+    }
+
+    /* encoded with DSA header */
+    err = StoreECC_DSA_Sig(out, outlen, r, s);
+
+    /* cleanup */
+    mp_clear(r);
+    mp_clear(s);
+
+#ifdef WOLFSSL_SMALL_STACK
+    XFREE(s, key->heap, DYNAMIC_TYPE_ECC);
+    XFREE(r, key->heap, DYNAMIC_TYPE_ECC);
+#endif
+#endif /* WOLFSSL_ASYNC_CRYPT */
+
+    return err;
+}
+#endif /* !NO_ASN */
+
+#if defined(WOLFSSL_STM32_PKA)
+int wc_ecc_sign_hash_ex(const byte* in, word32 inlen, WC_RNG* rng,
+                     ecc_key* key, mp_int *r, mp_int *s)
+{
+    return stm32_ecc_sign_hash_ex(in, inlen, rng, key, r, s);
+}
+#elif !defined(WOLFSSL_ATECC508A) && !defined(WOLFSSL_CRYPTOCELL)
+/**
+  Sign a message digest
+  in        The message digest to sign
+  inlen     The length of the digest
+  key       A private ECC key
+  r         [out] The destination for r component of the signature
+  s         [out] The destination for s component of the signature
+  return    MP_OKAY if successful
+*/
+int wc_ecc_sign_hash_ex(const byte* in, word32 inlen, WC_RNG* rng,
+                     ecc_key* key, mp_int *r, mp_int *s)
+{
+   int    err = 0;
+#ifndef WOLFSSL_SP_MATH
+   mp_int* e;
+#if (!defined(WOLFSSL_ASYNC_CRYPT) || !defined(HAVE_CAVIUM_V)) && \
+                                                   !defined(WOLFSSL_SMALL_STACK)
+   mp_int  e_lcl;
+#endif
+
+#if defined(WOLFSSL_ECDSA_SET_K) || \
+    (defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC) && \
+    (defined(HAVE_CAVIUM_V) || defined(HAVE_INTEL_QA)))
+   DECLARE_CURVE_SPECS(curve, ECC_CURVE_FIELD_COUNT);
+#else
+   DECLARE_CURVE_SPECS(curve, 1);
+#endif
+#endif /* !WOLFSSL_SP_MATH */
+
+   if (in == NULL || r == NULL || s == NULL || key == NULL || rng == NULL) {
+       return ECC_BAD_ARG_E;
+   }
+
+   /* is this a private key? */
+   if (key->type != ECC_PRIVATEKEY && key->type != ECC_PRIVATEKEY_ONLY) {
+      return ECC_BAD_ARG_E;
+   }
+
+   /* is the IDX valid ?  */
+   if (wc_ecc_is_valid_idx(key->idx) != 1) {
+      return ECC_BAD_ARG_E;
+   }
+
+#ifdef WOLFSSL_SP_MATH
+#ifndef WOLFSSL_SP_NO_256
+    if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SECP256R1) {
+    #ifndef WOLFSSL_ECDSA_SET_K
+        return sp_ecc_sign_256(in, inlen, rng, &key->k, r, s, NULL, key->heap);
+    #else
+        return sp_ecc_sign_256(in, inlen, rng, &key->k, r, s, key->sign_k,
+                                                                     key->heap);
+    #endif
+    }
+#endif
+#ifdef WOLFSSL_SP_384
+    if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SECP384R1) {
+    #ifndef WOLFSSL_ECDSA_SET_K
+        return sp_ecc_sign_384(in, inlen, rng, &key->k, r, s, NULL, key->heap);
+    #else
+        return sp_ecc_sign_384(in, inlen, rng, &key->k, r, s, key->sign_k,
+                                                                     key->heap);
+    #endif
+    }
+#endif
+    return WC_KEY_SIZE_E;
+#else
+#ifdef WOLFSSL_HAVE_SP_ECC
+    #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC)
+    if (key->asyncDev.marker != WOLFSSL_ASYNC_MARKER_ECC)
+    #endif
+    {
+#ifndef WOLFSSL_SP_NO_256
+        if (key->idx != ECC_CUSTOM_IDX &&
+                                       ecc_sets[key->idx].id == ECC_SECP256R1) {
+        #ifndef WOLFSSL_ECDSA_SET_K
+            return sp_ecc_sign_256(in, inlen, rng, &key->k, r, s, NULL,
+                                                                     key->heap);
+        #else
+            return sp_ecc_sign_256(in, inlen, rng, &key->k, r, s, key->sign_k,
+                                                                     key->heap);
+        #endif
+        }
+#endif
+#ifdef WOLFSSL_SP_384
+        if (key->idx != ECC_CUSTOM_IDX &&
+                                       ecc_sets[key->idx].id == ECC_SECP384R1) {
+        #ifndef WOLFSSL_ECDSA_SET_K
+            return sp_ecc_sign_384(in, inlen, rng, &key->k, r, s, NULL,
+                                                                     key->heap);
+        #else
+            return sp_ecc_sign_384(in, inlen, rng, &key->k, r, s, key->sign_k,
+                                                                     key->heap);
+        #endif
+        }
+#endif
+    }
+#endif /* WOLFSSL_HAVE_SP_ECC */
+
+
+#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC) && \
+       defined(WOLFSSL_ASYNC_CRYPT_TEST)
+    if (key->asyncDev.marker == WOLFSSL_ASYNC_MARKER_ECC) {
+        if (wc_AsyncTestInit(&key->asyncDev, ASYNC_TEST_ECC_SIGN)) {
+            WC_ASYNC_TEST* testDev = &key->asyncDev.test;
+            testDev->eccSign.in = in;
+            testDev->eccSign.inSz = inlen;
+            testDev->eccSign.rng = rng;
+            testDev->eccSign.key = key;
+            testDev->eccSign.r = r;
+            testDev->eccSign.s = s;
+            return WC_PENDING_E;
+        }
+    }
+#endif
+
+#if defined(WOLFSSL_ASYNC_CRYPT) && defined(HAVE_CAVIUM_V)
+   err = wc_ecc_alloc_mpint(key, &key->e);
+   if (err != 0) {
+      return err;
+   }
+   e = key->e;
+#elif !defined(WOLFSSL_SMALL_STACK)
+   e = &e_lcl;
+#else
+   e = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_ECC);
+   if (e == NULL) {
+      return MEMORY_E;
+   }
+#endif
+
+   /* get the hash and load it as a bignum into 'e' */
+   /* init the bignums */
+   if ((err = mp_init(e)) != MP_OKAY) {
+   #ifdef WOLFSSL_SMALL_STACK
+      XFREE(e, key->heap, DYNAMIC_TYPE_ECC);
+   #endif
+      return err;
+   }
+
+   /* load curve info */
+#if defined(WOLFSSL_ECDSA_SET_K)
+   ALLOC_CURVE_SPECS(ECC_CURVE_FIELD_COUNT);
+   err = wc_ecc_curve_load(key->dp, &curve, ECC_CURVE_FIELD_ALL);
+#else
+   #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC) && \
+      (defined(HAVE_CAVIUM_V) || defined(HAVE_INTEL_QA))
+   if (key->asyncDev.marker == WOLFSSL_ASYNC_MARKER_ECC) {
+      ALLOC_CURVE_SPECS(ECC_CURVE_FIELD_COUNT);
+      err = wc_ecc_curve_load(key->dp, &curve, ECC_CURVE_FIELD_ALL);
+   }
+   else
+   #endif
+   {
+      ALLOC_CURVE_SPECS(1);
+      err = wc_ecc_curve_load(key->dp, &curve, ECC_CURVE_FIELD_ORDER);
+   }
+#endif
+
+   /* load digest into e */
+   if (err == MP_OKAY) {
+       /* we may need to truncate if hash is longer than key size */
+       word32 orderBits = mp_count_bits(curve->order);
+
+       /* truncate down to byte size, may be all that's needed */
+       if ((WOLFSSL_BIT_SIZE * inlen) > orderBits)
+           inlen = (orderBits + WOLFSSL_BIT_SIZE - 1) / WOLFSSL_BIT_SIZE;
+       err = mp_read_unsigned_bin(e, (byte*)in, inlen);
+
+       /* may still need bit truncation too */
+       if (err == MP_OKAY && (WOLFSSL_BIT_SIZE * inlen) > orderBits)
+           mp_rshb(e, WOLFSSL_BIT_SIZE - (orderBits & 0x7));
+   }
+
+   /* make up a key and export the public copy */
+   if (err == MP_OKAY) {
+       int      loop_check = 0;
+   #ifdef WOLFSSL_SMALL_STACK
+       ecc_key* pubkey;
+   #else
+       ecc_key  pubkey[1];
+   #endif
+
+   #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC)
+        if (key->asyncDev.marker == WOLFSSL_ASYNC_MARKER_ECC) {
+        #if defined(HAVE_CAVIUM_V) || defined(HAVE_INTEL_QA)
+        #ifdef HAVE_CAVIUM_V
+            if (NitroxEccIsCurveSupported(key))
+        #endif
+            {
+               word32 keySz = key->dp->size;
+               mp_int* k;
+            #ifdef HAVE_CAVIUM_V
+               err = wc_ecc_alloc_mpint(key, &key->signK);
+               if (err != 0)
+                  return err;
+               k = key->signK;
+            #else
+               mp_int k_lcl;
+               k = &k_lcl;
+            #endif
+
+               err = mp_init(k);
+
+                /* make sure r and s are allocated */
+           #ifdef HAVE_CAVIUM_V
+               /* Nitrox V needs single buffer for R and S */
+               if (err == MP_OKAY)
+                   err = wc_bigint_alloc(&key->r->raw, NitroxEccGetSize(key)*2);
+               /* Nitrox V only needs Prime and Order */
+               if (err == MP_OKAY)
+                   err = wc_ecc_curve_load(key->dp, &curve,
+                        (ECC_CURVE_FIELD_PRIME | ECC_CURVE_FIELD_ORDER));
+           #else
+               if (err == MP_OKAY)
+                   err = wc_bigint_alloc(&key->r->raw, key->dp->size);
+               if (err == MP_OKAY)
+                   err = wc_ecc_curve_load(key->dp, &curve, ECC_CURVE_FIELD_ALL);
+           #endif
+               if (err == MP_OKAY)
+                   err = wc_bigint_alloc(&key->s->raw, key->dp->size);
+
+               /* load e and k */
+               if (err == MP_OKAY)
+                   err = wc_mp_to_bigint_sz(e, &e->raw, keySz);
+               if (err == MP_OKAY)
+                   err = wc_mp_to_bigint_sz(&key->k, &key->k.raw, keySz);
+               if (err == MP_OKAY)
+                   err = wc_ecc_gen_k(rng, key->dp->size, k, curve->order);
+               if (err == MP_OKAY)
+                   err = wc_mp_to_bigint_sz(k, &k->raw, keySz);
+
+           #ifdef HAVE_CAVIUM_V
+               if (err == MP_OKAY)
+                   err = NitroxEcdsaSign(key, &e->raw, &key->k.raw, &k->raw,
+                    &r->raw, &s->raw, &curve->prime->raw, &curve->order->raw);
+           #else
+               if (err == MP_OKAY)
+                   err = IntelQaEcdsaSign(&key->asyncDev, &e->raw, &key->k.raw,
+                      &k->raw, &r->raw, &s->raw, &curve->Af->raw, &curve->Bf->raw,
+                      &curve->prime->raw, &curve->order->raw, &curve->Gx->raw,
+                      &curve->Gy->raw);
+           #endif
+
+           #ifndef HAVE_CAVIUM_V
+               mp_clear(e);
+               mp_clear(k);
+           #endif
+               wc_ecc_curve_free(curve);
+               FREE_CURVE_SPECS();
+
+               return err;
+           }
+       #endif /* HAVE_CAVIUM_V || HAVE_INTEL_QA */
+       }
+   #endif /* WOLFSSL_ASYNC_CRYPT && WC_ASYNC_ENABLE_ECC */
+
+   #ifdef WOLFSSL_SMALL_STACK
+       pubkey = (ecc_key*)XMALLOC(sizeof(ecc_key), key->heap, DYNAMIC_TYPE_ECC);
+       if (pubkey == NULL)
+           err = MEMORY_E;
+   #endif
+
+       /* don't use async for key, since we don't support async return here */
+       if (err == MP_OKAY && (err = wc_ecc_init_ex(pubkey, key->heap,
+                                                   INVALID_DEVID)) == MP_OKAY) {
+       #ifdef WOLFSSL_SMALL_STACK
+           mp_int* b = NULL;
+       #else
+           mp_int  b[1];
+       #endif
+
+       #ifdef WOLFSSL_SMALL_STACK
+           if (err == MP_OKAY) {
+               b = (mp_int*)XMALLOC(sizeof(mp_int), key->heap,
+                                                              DYNAMIC_TYPE_ECC);
+               if (b == NULL)
+                   err = MEMORY_E;
+           }
+       #endif
+
+           if (err == MP_OKAY) {
+               err = mp_init(b);
+           }
+
+       #ifdef WOLFSSL_CUSTOM_CURVES
+           /* if custom curve, apply params to pubkey */
+           if (err == MP_OKAY && key->idx == ECC_CUSTOM_IDX) {
+               err = wc_ecc_set_custom_curve(pubkey, key->dp);
+           }
+       #endif
+
+           if (err == MP_OKAY) {
+               /* Generate blinding value - non-zero value. */
+               do {
+                   if (++loop_check > 64) {
+                        err = RNG_FAILURE_E;
+                        break;
+                   }
+
+                   err = wc_ecc_gen_k(rng, key->dp->size, b, curve->order);
+               }
+               while (err == MP_ZERO_E);
+               loop_check = 0;
+           }
+
+           for (; err == MP_OKAY;) {
+               if (++loop_check > 64) {
+                    err = RNG_FAILURE_E;
+                    break;
+               }
+       #ifdef WOLFSSL_ECDSA_SET_K
+               if (key->sign_k != NULL) {
+                   if (loop_check > 1) {
+                      err = RNG_FAILURE_E;
+                      break;
+                   }
+
+                   err = mp_copy(key->sign_k, &pubkey->k);
+                   if (err != MP_OKAY) break;
+
+                   mp_forcezero(key->sign_k);
+                   mp_free(key->sign_k);
+                   XFREE(key->sign_k, key->heap, DYNAMIC_TYPE_ECC);
+                   key->sign_k = NULL;
+                   err = wc_ecc_make_pub_ex(pubkey, curve, NULL);
+               }
+               else
+       #endif
+               {
+                   err = wc_ecc_make_key_ex(rng, key->dp->size, pubkey,
+                                                                   key->dp->id);
+               }
+               if (err != MP_OKAY) break;
+
+               /* find r = x1 mod n */
+               err = mp_mod(pubkey->pubkey.x, curve->order, r);
+               if (err != MP_OKAY) break;
+
+               if (mp_iszero(r) == MP_YES) {
+                #ifndef ALT_ECC_SIZE
+                   mp_clear(pubkey->pubkey.x);
+                   mp_clear(pubkey->pubkey.y);
+                   mp_clear(pubkey->pubkey.z);
+                #endif
+                   mp_forcezero(&pubkey->k);
+               }
+               else {
+                   /* find s = (e + xr)/k
+                             = b.(e/k.b + x.r/k.b) */
+
+                   /* k = k.b */
+                   err = mp_mulmod(&pubkey->k, b, curve->order, &pubkey->k);
+                   if (err != MP_OKAY) break;
+
+                   /* k = 1/k.b */
+                   err = mp_invmod(&pubkey->k, curve->order, &pubkey->k);
+                   if (err != MP_OKAY) break;
+
+                   /* s = x.r */
+                   err = mp_mulmod(&key->k, r, curve->order, s);
+                   if (err != MP_OKAY) break;
+
+                   /* s = x.r/k.b */
+                   err = mp_mulmod(&pubkey->k, s, curve->order, s);
+                   if (err != MP_OKAY) break;
+
+                   /* e = e/k.b */
+                   err = mp_mulmod(&pubkey->k, e, curve->order, e);
+                   if (err != MP_OKAY) break;
+
+                   /* s = e/k.b + x.r/k.b
+                        = (e + x.r)/k.b */
+                   err = mp_add(e, s, s);
+                   if (err != MP_OKAY) break;
+
+                   /* s = b.(e + x.r)/k.b
+                        = (e + x.r)/k */
+                   err = mp_mulmod(s, b, curve->order, s);
+                   if (err != MP_OKAY) break;
+
+                   /* s = (e + xr)/k */
+                   err = mp_mod(s, curve->order, s);
+                   if (err != MP_OKAY) break;
+
+                   if (mp_iszero(s) == MP_NO)
+                       break;
+                }
+           }
+           mp_clear(b);
+           mp_free(b);
+       #ifdef WOLFSSL_SMALL_STACK
+           XFREE(b, key->heap, DYNAMIC_TYPE_ECC);
+       #endif
+           wc_ecc_free(pubkey);
+       #ifdef WOLFSSL_SMALL_STACK
+           XFREE(pubkey, key->heap, DYNAMIC_TYPE_ECC);
+       #endif
+       }
+   }
+
+   mp_clear(e);
+   wc_ecc_curve_free(curve);
+#ifdef WOLFSSL_SMALL_STACK
+   XFREE(e, key->heap, DYNAMIC_TYPE_ECC);
+#endif
+   FREE_CURVE_SPECS();
+#endif /* WOLFSSL_SP_MATH */
+
+   return err;
+}
+
+#ifdef WOLFSSL_ECDSA_SET_K
+int wc_ecc_sign_set_k(const byte* k, word32 klen, ecc_key* key)
+{
+    int ret = 0;
+
+    if (k == NULL || klen == 0 || key == NULL) {
+        ret = BAD_FUNC_ARG;
+    }
+
+    if (ret == 0) {
+        if (key->sign_k == NULL) {
+            key->sign_k = (mp_int*)XMALLOC(sizeof(mp_int), key->heap,
+                                                              DYNAMIC_TYPE_ECC);
+            if (key->sign_k == NULL) {
+                ret = MEMORY_E;
+            }
+        }
+    }
+
+    if (ret == 0) {
+        ret = mp_init(key->sign_k);
+    }
+    if (ret == 0) {
+        ret = mp_read_unsigned_bin(key->sign_k, k, klen);
+    }
+
+    return ret;
+}
+#endif /* WOLFSSL_ECDSA_SET_K */
+#endif /* WOLFSSL_ATECC508A && WOLFSSL_CRYPTOCELL*/
+
+#endif /* HAVE_ECC_SIGN */
+
+#ifdef WOLFSSL_CUSTOM_CURVES
+void wc_ecc_free_curve(const ecc_set_type* curve, void* heap)
+{
+#ifndef WOLFSSL_ECC_CURVE_STATIC
+    if (curve->prime != NULL)
+        XFREE((void*)curve->prime, heap, DYNAMIC_TYPE_ECC_BUFFER);
+    if (curve->Af != NULL)
+        XFREE((void*)curve->Af, heap, DYNAMIC_TYPE_ECC_BUFFER);
+    if (curve->Bf != NULL)
+        XFREE((void*)curve->Bf, heap, DYNAMIC_TYPE_ECC_BUFFER);
+    if (curve->order != NULL)
+        XFREE((void*)curve->order, heap, DYNAMIC_TYPE_ECC_BUFFER);
+    if (curve->Gx != NULL)
+        XFREE((void*)curve->Gx, heap, DYNAMIC_TYPE_ECC_BUFFER);
+    if (curve->Gy != NULL)
+        XFREE((void*)curve->Gy, heap, DYNAMIC_TYPE_ECC_BUFFER);
+#endif
+
+    XFREE((void*)curve, heap, DYNAMIC_TYPE_ECC_BUFFER);
+
+    (void)heap;
+}
+#endif /* WOLFSSL_CUSTOM_CURVES */
+
+/**
+  Free an ECC key from memory
+  key   The key you wish to free
+*/
+WOLFSSL_ABI
+int wc_ecc_free(ecc_key* key)
+{
+    if (key == NULL) {
+        return 0;
+    }
+
+#ifdef WOLFSSL_ECDSA_SET_K
+    if (key->sign_k != NULL) {
+        mp_forcezero(key->sign_k);
+        mp_free(key->sign_k);
+        XFREE(key->sign_k, key->heap, DYNAMIC_TYPE_ECC);
+    }
+#endif
+
+#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC)
+    #ifdef WC_ASYNC_ENABLE_ECC
+    wolfAsync_DevCtxFree(&key->asyncDev, WOLFSSL_ASYNC_MARKER_ECC);
+    #endif
+    wc_ecc_free_async(key);
+#endif
+
+#ifdef WOLFSSL_ATECC508A
+    atmel_ecc_free(key->slot);
+    key->slot = ATECC_INVALID_SLOT;
+#endif /* WOLFSSL_ATECC508A */
+
+    mp_clear(key->pubkey.x);
+    mp_clear(key->pubkey.y);
+    mp_clear(key->pubkey.z);
+
+    mp_forcezero(&key->k);
+
+#ifdef WOLFSSL_CUSTOM_CURVES
+    if (key->deallocSet && key->dp != NULL)
+        wc_ecc_free_curve(key->dp, key->heap);
+#endif
+
+    return 0;
+}
+
+#if !defined(WOLFSSL_SP_MATH) && !defined(WOLFSSL_ATECC508A) && !defined(WOLFSSL_CRYPTOCELL)
+#ifdef ECC_SHAMIR
+
+/** Computes kA*A + kB*B = C using Shamir's Trick
+  A        First point to multiply
+  kA       What to multiple A by
+  B        Second point to multiply
+  kB       What to multiple B by
+  C        [out] Destination point (can overlap with A or B)
+  a        ECC curve parameter a
+  modulus  Modulus for curve
+  return MP_OKAY on success
+*/
+#ifdef FP_ECC
+static int normal_ecc_mul2add(ecc_point* A, mp_int* kA,
+                             ecc_point* B, mp_int* kB,
+                             ecc_point* C, mp_int* a, mp_int* modulus,
+                             void* heap)
+#else
+int ecc_mul2add(ecc_point* A, mp_int* kA,
+                    ecc_point* B, mp_int* kB,
+                    ecc_point* C, mp_int* a, mp_int* modulus,
+                    void* heap)
+#endif
+{
+#ifdef WOLFSSL_SMALL_STACK_CACHE
+  ecc_key        key;
+#endif
+#ifdef WOLFSSL_SMALL_STACK
+  ecc_point**    precomp = NULL;
+#else
+  ecc_point*     precomp[SHAMIR_PRECOMP_SZ];
+#endif
+  unsigned       bitbufA, bitbufB, lenA, lenB, len, nA, nB, nibble;
+  unsigned char* tA;
+  unsigned char* tB;
+  int            err = MP_OKAY, first, x, y;
+  mp_digit       mp = 0;
+
+  /* argchks */
+  if (A == NULL || kA == NULL || B == NULL || kB == NULL || C == NULL ||
+                                                         modulus == NULL) {
+     return ECC_BAD_ARG_E;
+  }
+
+  /* allocate memory */
+  tA = (unsigned char*)XMALLOC(ECC_BUFSIZE, heap, DYNAMIC_TYPE_ECC_BUFFER);
+  if (tA == NULL) {
+     return GEN_MEM_ERR;
+  }
+  tB = (unsigned char*)XMALLOC(ECC_BUFSIZE, heap, DYNAMIC_TYPE_ECC_BUFFER);
+  if (tB == NULL) {
+     XFREE(tA, heap, DYNAMIC_TYPE_ECC_BUFFER);
+     return GEN_MEM_ERR;
+  }
+#ifdef WOLFSSL_SMALL_STACK
+  precomp = (ecc_point**)XMALLOC(sizeof(ecc_point*) * SHAMIR_PRECOMP_SZ, heap,
+                                                       DYNAMIC_TYPE_ECC_BUFFER);
+  if (precomp == NULL) {
+     XFREE(tB, heap, DYNAMIC_TYPE_ECC_BUFFER);
+     XFREE(tA, heap, DYNAMIC_TYPE_ECC_BUFFER);
+     return GEN_MEM_ERR;
+  }
+#endif
+#ifdef WOLFSSL_SMALL_STACK_CACHE
+  key.t1 = (mp_int*)XMALLOC(sizeof(mp_int), heap, DYNAMIC_TYPE_ECC);
+  key.t2 = (mp_int*)XMALLOC(sizeof(mp_int), heap, DYNAMIC_TYPE_ECC);
+#ifdef ALT_ECC_SIZE
+  key.x = (mp_int*)XMALLOC(sizeof(mp_int), heap, DYNAMIC_TYPE_ECC);
+  key.y = (mp_int*)XMALLOC(sizeof(mp_int), heap, DYNAMIC_TYPE_ECC);
+  key.z = (mp_int*)XMALLOC(sizeof(mp_int), heap, DYNAMIC_TYPE_ECC);
+#endif
+  if (key.t1 == NULL || key.t2 == NULL
+#ifdef ALT_ECC_SIZE
+     || key.x == NULL || key.y == NULL || key.z == NULL
+#endif
+  ) {
+#ifdef ALT_ECC_SIZE
+      XFREE(key.z, heap, DYNAMIC_TYPE_ECC);
+      XFREE(key.y, heap, DYNAMIC_TYPE_ECC);
+      XFREE(key.x, heap, DYNAMIC_TYPE_ECC);
+#endif
+      XFREE(key.t2, heap, DYNAMIC_TYPE_ECC);
+      XFREE(key.t1, heap, DYNAMIC_TYPE_ECC);
+      XFREE(precomp, heap, DYNAMIC_TYPE_ECC_BUFFER);
+      XFREE(tB, heap, DYNAMIC_TYPE_ECC_BUFFER);
+      XFREE(tA, heap, DYNAMIC_TYPE_ECC_BUFFER);
+      return MEMORY_E;
+  }
+  C->key = &key;
+#endif /* WOLFSSL_SMALL_STACK_CACHE */
+
+  /* init variables */
+  XMEMSET(tA, 0, ECC_BUFSIZE);
+  XMEMSET(tB, 0, ECC_BUFSIZE);
+#ifndef WOLFSSL_SMALL_STACK
+  XMEMSET(precomp, 0, sizeof(precomp));
+#else
+  XMEMSET(precomp, 0, sizeof(ecc_point*) * SHAMIR_PRECOMP_SZ);
+#endif
+
+  /* get sizes */
+  lenA = mp_unsigned_bin_size(kA);
+  lenB = mp_unsigned_bin_size(kB);
+  len  = MAX(lenA, lenB);
+
+  /* sanity check */
+  if ((lenA > ECC_BUFSIZE) || (lenB > ECC_BUFSIZE)) {
+    err = BAD_FUNC_ARG;
+  }
+
+  if (err == MP_OKAY) {
+    /* extract and justify kA */
+    err = mp_to_unsigned_bin(kA, (len - lenA) + tA);
+
+    /* extract and justify kB */
+    if (err == MP_OKAY)
+        err = mp_to_unsigned_bin(kB, (len - lenB) + tB);
+
+    /* allocate the table */
+    if (err == MP_OKAY) {
+        for (x = 0; x < SHAMIR_PRECOMP_SZ; x++) {
+            precomp[x] = wc_ecc_new_point_h(heap);
+            if (precomp[x] == NULL) {
+                err = GEN_MEM_ERR;
+                break;
+            }
+        #ifdef WOLFSSL_SMALL_STACK_CACHE
+            precomp[x]->key = &key;
+        #endif
+        }
+    }
+  }
+
+  if (err == MP_OKAY)
+    /* init montgomery reduction */
+    err = mp_montgomery_setup(modulus, &mp);
+
+  if (err == MP_OKAY) {
+  #ifdef WOLFSSL_SMALL_STACK
+    mp_int* mu;
+  #else
+    mp_int  mu[1];
+  #endif
+  #ifdef WOLFSSL_SMALL_STACK
+    mu = (mp_int*)XMALLOC(sizeof(mp_int), heap, DYNAMIC_TYPE_ECC);
+    if (mu == NULL)
+        err = MEMORY_E;
+  #endif
+    if (err == MP_OKAY) {
+        err = mp_init(mu);
+    }
+    if (err == MP_OKAY) {
+      err = mp_montgomery_calc_normalization(mu, modulus);
+
+      if (err == MP_OKAY)
+        /* copy ones ... */
+        err = mp_mulmod(A->x, mu, modulus, precomp[1]->x);
+
+      if (err == MP_OKAY)
+        err = mp_mulmod(A->y, mu, modulus, precomp[1]->y);
+      if (err == MP_OKAY)
+        err = mp_mulmod(A->z, mu, modulus, precomp[1]->z);
+
+      if (err == MP_OKAY)
+        err = mp_mulmod(B->x, mu, modulus, precomp[1<<2]->x);
+      if (err == MP_OKAY)
+        err = mp_mulmod(B->y, mu, modulus, precomp[1<<2]->y);
+      if (err == MP_OKAY)
+        err = mp_mulmod(B->z, mu, modulus, precomp[1<<2]->z);
+
+      /* done with mu */
+      mp_clear(mu);
+    }
+  #ifdef WOLFSSL_SMALL_STACK
+    if (mu != NULL) {
+      XFREE(mu, heap, DYNAMIC_TYPE_ECC);
+    }
+  #endif
+  }
+
+  if (err == MP_OKAY)
+    /* precomp [i,0](A + B) table */
+    err = ecc_projective_dbl_point(precomp[1], precomp[2], a, modulus, mp);
+
+  if (err == MP_OKAY)
+    err = ecc_projective_add_point(precomp[1], precomp[2], precomp[3],
+                                   a, modulus, mp);
+  if (err == MP_OKAY)
+    /* precomp [0,i](A + B) table */
+    err = ecc_projective_dbl_point(precomp[1<<2], precomp[2<<2], a, modulus, mp);
+
+  if (err == MP_OKAY)
+    err = ecc_projective_add_point(precomp[1<<2], precomp[2<<2], precomp[3<<2],
+                                   a, modulus, mp);
+
+  if (err == MP_OKAY) {
+    /* precomp [i,j](A + B) table (i != 0, j != 0) */
+    for (x = 1; x < 4; x++) {
+      for (y = 1; y < 4; y++) {
+        if (err == MP_OKAY) {
+          err = ecc_projective_add_point(precomp[x], precomp[(y<<2)],
+                                             precomp[x+(y<<2)], a, modulus, mp);
+        }
+      }
+    }
+  }
+
+  if (err == MP_OKAY) {
+    nibble  = 3;
+    first   = 1;
+    bitbufA = tA[0];
+    bitbufB = tB[0];
+
+    /* for every byte of the multiplicands */
+    for (x = 0;; ) {
+        /* grab a nibble */
+        if (++nibble == 4) {
+            if (x == (int)len) break;
+            bitbufA = tA[x];
+            bitbufB = tB[x];
+            nibble  = 0;
+            x++;
+        }
+
+        /* extract two bits from both, shift/update */
+        nA = (bitbufA >> 6) & 0x03;
+        nB = (bitbufB >> 6) & 0x03;
+        bitbufA = (bitbufA << 2) & 0xFF;
+        bitbufB = (bitbufB << 2) & 0xFF;
+
+        /* if both zero, if first, continue */
+        if ((nA == 0) && (nB == 0) && (first == 1)) {
+            continue;
+        }
+
+        /* double twice, only if this isn't the first */
+        if (first == 0) {
+            /* double twice */
+            if (err == MP_OKAY)
+                err = ecc_projective_dbl_point(C, C, a, modulus, mp);
+            if (err == MP_OKAY)
+                err = ecc_projective_dbl_point(C, C, a, modulus, mp);
+            else
+                break;
+        }
+
+        /* if not both zero */
+        if ((nA != 0) || (nB != 0)) {
+            if (first == 1) {
+                /* if first, copy from table */
+                first = 0;
+                if (err == MP_OKAY)
+                    err = mp_copy(precomp[nA + (nB<<2)]->x, C->x);
+
+                if (err == MP_OKAY)
+                    err = mp_copy(precomp[nA + (nB<<2)]->y, C->y);
+
+                if (err == MP_OKAY)
+                    err = mp_copy(precomp[nA + (nB<<2)]->z, C->z);
+                else
+                    break;
+            } else {
+                /* if not first, add from table */
+                if (err == MP_OKAY)
+                    err = ecc_projective_add_point(C, precomp[nA + (nB<<2)], C,
+                                                   a, modulus, mp);
+                if (err != MP_OKAY)
+                    break;
+                if (mp_iszero(C->z)) {
+                    /* When all zero then should have done an add */
+                    if (mp_iszero(C->x) && mp_iszero(C->y)) {
+                        err = ecc_projective_dbl_point(precomp[nA + (nB<<2)], C,
+                                                       a, modulus, mp);
+                        if (err != MP_OKAY)
+                            break;
+                    }
+                    /* When only Z zero then result is infinity */
+                    else {
+                        err = mp_set(C->x, 0);
+                        if (err != MP_OKAY)
+                            break;
+                        err = mp_set(C->y, 0);
+                        if (err != MP_OKAY)
+                            break;
+                        err = mp_set(C->z, 1);
+                        if (err != MP_OKAY)
+                            break;
+                        first = 1;
+                    }
+                }
+            }
+        }
+    }
+  }
+
+  /* reduce to affine */
+  if (err == MP_OKAY)
+    err = ecc_map(C, modulus, mp);
+
+  /* clean up */
+  for (x = 0; x < SHAMIR_PRECOMP_SZ; x++) {
+     wc_ecc_del_point_h(precomp[x], heap);
+  }
+
+  ForceZero(tA, ECC_BUFSIZE);
+  ForceZero(tB, ECC_BUFSIZE);
+#ifdef WOLFSSL_SMALL_STACK_CACHE
+#ifdef ALT_ECC_SIZE
+  XFREE(key.z, heap, DYNAMIC_TYPE_ECC);
+  XFREE(key.y, heap, DYNAMIC_TYPE_ECC);
+  XFREE(key.x, heap, DYNAMIC_TYPE_ECC);
+#endif
+  XFREE(key.t2, heap, DYNAMIC_TYPE_ECC);
+  XFREE(key.t1, heap, DYNAMIC_TYPE_ECC);
+  C->key = NULL;
+#endif
+#ifdef WOLFSSL_SMALL_STACK
+  XFREE(precomp, heap, DYNAMIC_TYPE_ECC_BUFFER);
+#endif
+  XFREE(tB, heap, DYNAMIC_TYPE_ECC_BUFFER);
+  XFREE(tA, heap, DYNAMIC_TYPE_ECC_BUFFER);
+
+  return err;
+}
+
+#endif /* ECC_SHAMIR */
+#endif /* !WOLFSSL_SP_MATH && !WOLFSSL_ATECC508A && !WOLFSSL_CRYPTOCEL*/
+
+
+#ifdef HAVE_ECC_VERIFY
+#ifndef NO_ASN
+/* verify
+ *
+ * w  = s^-1 mod n
+ * u1 = xw
+ * u2 = rw
+ * X = u1*G + u2*Q
+ * v = X_x1 mod n
+ * accept if v == r
+ */
+
+/**
+ Verify an ECC signature
+ sig         The signature to verify
+ siglen      The length of the signature (octets)
+ hash        The hash (message digest) that was signed
+ hashlen     The length of the hash (octets)
+ res         Result of signature, 1==valid, 0==invalid
+ key         The corresponding public ECC key
+ return      MP_OKAY if successful (even if the signature is not valid)
+ */
+int wc_ecc_verify_hash(const byte* sig, word32 siglen, const byte* hash,
+                       word32 hashlen, int* res, ecc_key* key)
+{
+    int err;
+    mp_int *r = NULL, *s = NULL;
+#if (!defined(WOLFSSL_ASYNC_CRYPT) || !defined(WC_ASYNC_ENABLE_ECC)) && \
+    !defined(WOLFSSL_SMALL_STACK)
+    mp_int r_lcl, s_lcl;
+#endif
+
+    if (sig == NULL || hash == NULL || res == NULL || key == NULL) {
+        return ECC_BAD_ARG_E;
+    }
+
+#ifdef WOLF_CRYPTO_CB
+    if (key->devId != INVALID_DEVID) {
+        err = wc_CryptoCb_EccVerify(sig, siglen, hash, hashlen, res, key);
+        if (err != CRYPTOCB_UNAVAILABLE)
+            return err;
+        /* fall-through when unavailable */
+    }
+#endif
+
+#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC)
+    err = wc_ecc_alloc_async(key);
+    if (err != 0)
+        return err;
+    r = key->r;
+    s = key->s;
+#else
+    #ifndef WOLFSSL_SMALL_STACK
+    r = &r_lcl;
+    s = &s_lcl;
+    #else
+    r = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_ECC);
+    if (r == NULL)
+        return MEMORY_E;
+    s = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_ECC);
+    if (s == NULL) {
+        XFREE(r, key->heap, DYNAMIC_TYPE_ECC);
+        return MEMORY_E;
+    }
+    #endif
+    XMEMSET(r, 0, sizeof(mp_int));
+    XMEMSET(s, 0, sizeof(mp_int));
+#endif /* WOLFSSL_ASYNC_CRYPT */
+
+    switch (key->state) {
+        case ECC_STATE_NONE:
+        case ECC_STATE_VERIFY_DECODE:
+            key->state = ECC_STATE_VERIFY_DECODE;
+
+            /* default to invalid signature */
+            *res = 0;
+
+            /* Note, DecodeECC_DSA_Sig() calls mp_init() on r and s.
+             * If either of those don't allocate correctly, none of
+             * the rest of this function will execute, and everything
+             * gets cleaned up at the end. */
+            /* decode DSA header */
+            err = DecodeECC_DSA_Sig(sig, siglen, r, s);
+            if (err < 0) {
+                break;
+            }
+            FALL_THROUGH;
+
+        case ECC_STATE_VERIFY_DO:
+            key->state = ECC_STATE_VERIFY_DO;
+
+            err = wc_ecc_verify_hash_ex(r, s, hash, hashlen, res, key);
+
+        #ifndef WOLFSSL_ASYNC_CRYPT
+            /* done with R/S */
+            mp_clear(r);
+            mp_clear(s);
+        #ifdef WOLFSSL_SMALL_STACK
+            XFREE(s, key->heap, DYNAMIC_TYPE_ECC);
+            XFREE(r, key->heap, DYNAMIC_TYPE_ECC);
+            r = NULL;
+            s = NULL;
+        #endif
+        #endif
+
+            if (err < 0) {
+                break;
+            }
+            FALL_THROUGH;
+
+        case ECC_STATE_VERIFY_RES:
+            key->state = ECC_STATE_VERIFY_RES;
+            err = 0;
+            break;
+
+        default:
+            err = BAD_STATE_E;
+    }
+
+    /* if async pending then return and skip done cleanup below */
+    if (err == WC_PENDING_E) {
+        key->state++;
+        return err;
+    }
+
+    /* cleanup */
+#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC)
+    wc_ecc_free_async(key);
+#elif defined(WOLFSSL_SMALL_STACK)
+    XFREE(s, key->heap, DYNAMIC_TYPE_ECC);
+    XFREE(r, key->heap, DYNAMIC_TYPE_ECC);
+    r = NULL;
+    s = NULL;
+#endif
+
+    key->state = ECC_STATE_NONE;
+
+    return err;
+}
+#endif /* !NO_ASN */
+
+
+/**
+   Verify an ECC signature
+   r           The signature R component to verify
+   s           The signature S component to verify
+   hash        The hash (message digest) that was signed
+   hashlen     The length of the hash (octets)
+   res         Result of signature, 1==valid, 0==invalid
+   key         The corresponding public ECC key
+   return      MP_OKAY if successful (even if the signature is not valid)
+*/
+
+int wc_ecc_verify_hash_ex(mp_int *r, mp_int *s, const byte* hash,
+                    word32 hashlen, int* res, ecc_key* key)
+#if defined(WOLFSSL_STM32_PKA)
+{
+    return stm32_ecc_verify_hash_ex(r, s, hash, hashlen, res, key);
+}
+#else
+{
+   int           err;
+   word32        keySz;
+#ifdef WOLFSSL_ATECC508A
+   byte sigRS[ATECC_KEY_SIZE*2];
+#elif defined(WOLFSSL_CRYPTOCELL)
+   byte sigRS[ECC_MAX_CRYPTO_HW_SIZE*2];
+   CRYS_ECDSA_VerifyUserContext_t sigCtxTemp;
+   word32 msgLenInBytes = hashlen;
+   CRYS_ECPKI_HASH_OpMode_t hash_mode;
+#elif !defined(WOLFSSL_SP_MATH) || defined(FREESCALE_LTC_ECC)
+   int          did_init = 0;
+   ecc_point    *mG = NULL, *mQ = NULL;
+   #ifdef WOLFSSL_SMALL_STACK
+   mp_int*       v = NULL;
+   mp_int*       w = NULL;
+   mp_int*       u1 = NULL;
+   mp_int*       u2 = NULL;
+      #if !defined(WOLFSSL_ASYNC_CRYPT) || !defined(HAVE_CAVIUM_V)
+   mp_int*       e_lcl = NULL;
+      #endif
+   #else /* WOLFSSL_SMALL_STACK */
+   mp_int        v[1];
+   mp_int        w[1];
+   mp_int        u1[1];
+   mp_int        u2[1];
+      #if !defined(WOLFSSL_ASYNC_CRYPT) || !defined(HAVE_CAVIUM_V)
+   mp_int        e_lcl[1];
+      #endif
+   #endif /* WOLFSSL_SMALL_STACK */
+   mp_int*       e;
+   DECLARE_CURVE_SPECS(curve, ECC_CURVE_FIELD_COUNT);
+#endif
+
+   if (r == NULL || s == NULL || hash == NULL || res == NULL || key == NULL)
+       return ECC_BAD_ARG_E;
+
+   /* default to invalid signature */
+   *res = 0;
+
+   /* is the IDX valid ?  */
+   if (wc_ecc_is_valid_idx(key->idx) != 1) {
+      return ECC_BAD_ARG_E;
+   }
+
+   keySz = key->dp->size;
+
+#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC) && \
+       defined(WOLFSSL_ASYNC_CRYPT_TEST)
+    if (key->asyncDev.marker == WOLFSSL_ASYNC_MARKER_ECC) {
+        if (wc_AsyncTestInit(&key->asyncDev, ASYNC_TEST_ECC_VERIFY)) {
+            WC_ASYNC_TEST* testDev = &key->asyncDev.test;
+            testDev->eccVerify.r = r;
+            testDev->eccVerify.s = s;
+            testDev->eccVerify.hash = hash;
+            testDev->eccVerify.hashlen = hashlen;
+            testDev->eccVerify.stat = res;
+            testDev->eccVerify.key = key;
+            return WC_PENDING_E;
+        }
+    }
+#endif
+
+#ifdef WOLFSSL_ATECC508A
+    /* Extract R and S */
+    err = mp_to_unsigned_bin(r, &sigRS[0]);
+    if (err != MP_OKAY) {
+        return err;
+    }
+    err = mp_to_unsigned_bin(s, &sigRS[keySz]);
+    if (err != MP_OKAY) {
+        return err;
+    }
+
+    err = atmel_ecc_verify(hash, sigRS, key->pubkey_raw, res);
+    if (err != 0) {
+       return err;
+    }
+    (void)hashlen;
+#elif defined(WOLFSSL_CRYPTOCELL)
+
+   /* Extract R and S */
+
+   err = mp_to_unsigned_bin(r, &sigRS[0]);
+   if (err != MP_OKAY) {
+       return err;
+   }
+   err = mp_to_unsigned_bin(s, &sigRS[keySz]);
+   if (err != MP_OKAY) {
+       return err;
+   }
+
+   hash_mode = cc310_hashModeECC(msgLenInBytes);
+   if (hash_mode == CRYS_ECPKI_HASH_OpModeLast) {
+       /* hash_mode = */ cc310_hashModeECC(keySz);
+       hash_mode = CRYS_ECPKI_HASH_SHA256_mode;
+   }
+   /* truncate if hash is longer than key size */
+   if (msgLenInBytes > keySz) {
+       msgLenInBytes = keySz;
+   }
+
+   /* verify the signature using the public key */
+   err = CRYS_ECDSA_Verify(&sigCtxTemp,
+                           &key->ctx.pubKey,
+                           hash_mode,
+                           &sigRS[0],
+                           keySz*2,
+                           (byte*)hash,
+                           msgLenInBytes);
+
+   if (err != SA_SILIB_RET_OK) {
+       WOLFSSL_MSG("CRYS_ECDSA_Verify failed");
+       return err;
+   }
+   /* valid signature if we get to this point */
+   *res = 1;
+#else
+  /* checking if private key with no public part */
+  if (key->type == ECC_PRIVATEKEY_ONLY) {
+      WOLFSSL_MSG("Verify called with private key, generating public part");
+      err = wc_ecc_make_pub_ex(key, NULL, NULL);
+      if (err != MP_OKAY) {
+           WOLFSSL_MSG("Unable to extract public key");
+           return err;
+      }
+  }
+
+#if defined(WOLFSSL_DSP) && !defined(FREESCALE_LTC_ECC)
+  if (key->handle != -1) {
+      return sp_dsp_ecc_verify_256(key->handle, hash, hashlen, key->pubkey.x, key->pubkey.y,
+                                           key->pubkey.z, r, s, res, key->heap);
+  }
+  if (wolfSSL_GetHandleCbSet() == 1) {
+      return sp_dsp_ecc_verify_256(0, hash, hashlen, key->pubkey.x, key->pubkey.y,
+                                           key->pubkey.z, r, s, res, key->heap);
+  }
+#endif
+#if defined(WOLFSSL_SP_MATH) && !defined(FREESCALE_LTC_ECC)
+#ifndef WOLFSSL_SP_NO_256
+  if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SECP256R1) {
+      return sp_ecc_verify_256(hash, hashlen, key->pubkey.x, key->pubkey.y,
+                                           key->pubkey.z, r, s, res, key->heap);
+  }
+#endif
+#ifdef WOLFSSL_SP_384
+  if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SECP384R1) {
+      return sp_ecc_verify_384(hash, hashlen, key->pubkey.x, key->pubkey.y,
+                                           key->pubkey.z, r, s, res, key->heap);
+  }
+#endif
+  return WC_KEY_SIZE_E;
+#else
+#if defined WOLFSSL_HAVE_SP_ECC && !defined(FREESCALE_LTC_ECC)
+    #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC)
+    if (key->asyncDev.marker != WOLFSSL_ASYNC_MARKER_ECC)
+    #endif
+    {
+#ifndef WOLFSSL_SP_NO_256
+        if (key->idx != ECC_CUSTOM_IDX &&
+                                       ecc_sets[key->idx].id == ECC_SECP256R1) {
+            return sp_ecc_verify_256(hash, hashlen, key->pubkey.x,
+                                         key->pubkey.y, key->pubkey.z,r, s, res,
+                                         key->heap);
+        }
+#endif /* WOLFSSL_SP_NO_256 */
+#ifdef WOLFSSL_SP_384
+        if (key->idx != ECC_CUSTOM_IDX &&
+                                       ecc_sets[key->idx].id == ECC_SECP384R1) {
+            return sp_ecc_verify_384(hash, hashlen, key->pubkey.x,
+                                         key->pubkey.y, key->pubkey.z,r, s, res,
+                                         key->heap);
+        }
+#endif /* WOLFSSL_SP_384 */
+    }
+#endif /* WOLFSSL_HAVE_SP_ECC */
+
+   ALLOC_CURVE_SPECS(ECC_CURVE_FIELD_COUNT);
+
+#if defined(WOLFSSL_ASYNC_CRYPT) && defined(HAVE_CAVIUM_V)
+   err = wc_ecc_alloc_mpint(key, &key->e);
+   if (err != 0) {
+      FREE_CURVE_SPECS();
+      return err;
+   }
+   e = key->e;
+#else
+#ifdef WOLFSSL_SMALL_STACK
+   e_lcl = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_ECC);
+   if (e_lcl == NULL) {
+       FREE_CURVE_SPECS();
+       return MEMORY_E;
+   }
+#endif
+   e = e_lcl;
+#endif /* WOLFSSL_ASYNC_CRYPT && HAVE_CAVIUM_V */
+
+   err = mp_init(e);
+   if (err != MP_OKAY)
+      return MEMORY_E;
+
+   /* read in the specs for this curve */
+   err = wc_ecc_curve_load(key->dp, &curve, ECC_CURVE_FIELD_ALL);
+
+   /* check for zero */
+   if (err == MP_OKAY) {
+       if (mp_iszero(r) == MP_YES || mp_iszero(s) == MP_YES ||
+           mp_cmp(r, curve->order) != MP_LT ||
+           mp_cmp(s, curve->order) != MP_LT) {
+           err = MP_ZERO_E;
+       }
+   }
+
+   /* read hash */
+   if (err == MP_OKAY) {
+       /* we may need to truncate if hash is longer than key size */
+       unsigned int orderBits = mp_count_bits(curve->order);
+
+       /* truncate down to byte size, may be all that's needed */
+       if ( (WOLFSSL_BIT_SIZE * hashlen) > orderBits)
+           hashlen = (orderBits + WOLFSSL_BIT_SIZE - 1) / WOLFSSL_BIT_SIZE;
+       err = mp_read_unsigned_bin(e, hash, hashlen);
+
+       /* may still need bit truncation too */
+       if (err == MP_OKAY && (WOLFSSL_BIT_SIZE * hashlen) > orderBits)
+           mp_rshb(e, WOLFSSL_BIT_SIZE - (orderBits & 0x7));
+   }
+
+   /* check for async hardware acceleration */
+#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC)
+   if (key->asyncDev.marker == WOLFSSL_ASYNC_MARKER_ECC) {
+   #if defined(HAVE_CAVIUM_V) || defined(HAVE_INTEL_QA)
+   #ifdef HAVE_CAVIUM_V
+      if (NitroxEccIsCurveSupported(key))
+   #endif
+      {
+          err = wc_mp_to_bigint_sz(e, &e->raw, keySz);
+          if (err == MP_OKAY)
+              err = wc_mp_to_bigint_sz(key->pubkey.x, &key->pubkey.x->raw, keySz);
+          if (err == MP_OKAY)
+              err = wc_mp_to_bigint_sz(key->pubkey.y, &key->pubkey.y->raw, keySz);
+          if (err == MP_OKAY)
+          #ifdef HAVE_CAVIUM_V
+              err = NitroxEcdsaVerify(key, &e->raw, &key->pubkey.x->raw,
+                    &key->pubkey.y->raw, &r->raw, &s->raw,
+                    &curve->prime->raw, &curve->order->raw, res);
+          #else
+              err = IntelQaEcdsaVerify(&key->asyncDev, &e->raw, &key->pubkey.x->raw,
+                    &key->pubkey.y->raw, &r->raw, &s->raw, &curve->Af->raw,
+                    &curve->Bf->raw, &curve->prime->raw, &curve->order->raw,
+                    &curve->Gx->raw, &curve->Gy->raw, res);
+          #endif
+
+      #ifndef HAVE_CAVIUM_V
+          mp_clear(e);
+      #endif
+          wc_ecc_curve_free(curve);
+          FREE_CURVE_SPECS();
+
+          return err;
+      }
+   #endif /* HAVE_CAVIUM_V || HAVE_INTEL_QA */
+   }
+#endif /* WOLFSSL_ASYNC_CRYPT && WC_ASYNC_ENABLE_ECC */
+
+#ifdef WOLFSSL_SMALL_STACK
+   if (err == MP_OKAY) {
+       v = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_ECC);
+       if (v == NULL)
+           err = MEMORY_E;
+   }
+   if (err == MP_OKAY) {
+       w = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_ECC);
+       if (w == NULL)
+           err = MEMORY_E;
+   }
+   if (err == MP_OKAY) {
+       u1 = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_ECC);
+       if (u1 == NULL)
+           err = MEMORY_E;
+   }
+   if (err == MP_OKAY) {
+       u2 = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_ECC);
+       if (u2 == NULL)
+           err = MEMORY_E;
+   }
+#endif
+
+   /* allocate ints */
+   if (err == MP_OKAY) {
+       if ((err = mp_init_multi(v, w, u1, u2, NULL, NULL)) != MP_OKAY) {
+          err = MEMORY_E;
+       }
+       did_init = 1;
+   }
+
+   /* allocate points */
+   if (err == MP_OKAY) {
+       mG = wc_ecc_new_point_h(key->heap);
+       mQ = wc_ecc_new_point_h(key->heap);
+       if (mQ  == NULL || mG == NULL)
+          err = MEMORY_E;
+   }
+
+   /*  w  = s^-1 mod n */
+   if (err == MP_OKAY)
+       err = mp_invmod(s, curve->order, w);
+
+   /* u1 = ew */
+   if (err == MP_OKAY)
+       err = mp_mulmod(e, w, curve->order, u1);
+
+   /* u2 = rw */
+   if (err == MP_OKAY)
+       err = mp_mulmod(r, w, curve->order, u2);
+
+   /* find mG and mQ */
+   if (err == MP_OKAY)
+       err = mp_copy(curve->Gx, mG->x);
+   if (err == MP_OKAY)
+       err = mp_copy(curve->Gy, mG->y);
+   if (err == MP_OKAY)
+       err = mp_set(mG->z, 1);
+
+   if (err == MP_OKAY)
+       err = mp_copy(key->pubkey.x, mQ->x);
+   if (err == MP_OKAY)
+       err = mp_copy(key->pubkey.y, mQ->y);
+   if (err == MP_OKAY)
+       err = mp_copy(key->pubkey.z, mQ->z);
+
+#if defined(FREESCALE_LTC_ECC)
+   /* use PKHA to compute u1*mG + u2*mQ */
+   if (err == MP_OKAY)
+       err = wc_ecc_mulmod_ex(u1, mG, mG, curve->Af, curve->prime, 0, key->heap);
+   if (err == MP_OKAY)
+       err = wc_ecc_mulmod_ex(u2, mQ, mQ, curve->Af, curve->prime, 0, key->heap);
+   if (err == MP_OKAY)
+       err = wc_ecc_point_add(mG, mQ, mG, curve->prime);
+#else
+#ifndef ECC_SHAMIR
+    if (err == MP_OKAY)
+    {
+        mp_digit mp = 0;
+
+        if (!mp_iszero(u1)) {
+            /* compute u1*mG + u2*mQ = mG */
+            err = wc_ecc_mulmod_ex(u1, mG, mG, curve->Af, curve->prime, 0,
+                                                                     key->heap);
+            if (err == MP_OKAY) {
+                err = wc_ecc_mulmod_ex(u2, mQ, mQ, curve->Af, curve->prime, 0,
+                                                                     key->heap);
+            }
+
+            /* find the montgomery mp */
+            if (err == MP_OKAY)
+                err = mp_montgomery_setup(curve->prime, &mp);
+
+            /* add them */
+            if (err == MP_OKAY)
+                err = ecc_projective_add_point(mQ, mG, mG, curve->Af,
+                                                              curve->prime, mp);
+            if (err == MP_OKAY && mp_iszero(mG->z)) {
+                /* When all zero then should have done an add */
+                if (mp_iszero(mG->x) && mp_iszero(mG->y)) {
+                    err = ecc_projective_dbl_point(mQ, mG, curve->Af,
+                                                              curve->prime, mp);
+                }
+                /* When only Z zero then result is infinity */
+                else {
+                    err = mp_set(mG->x, 0);
+                    if (err == MP_OKAY)
+                        err = mp_set(mG->y, 0);
+                    if (err == MP_OKAY)
+                        err = mp_set(mG->z, 1);
+                }
+            }
+        }
+        else {
+            /* compute 0*mG + u2*mQ = mG */
+            err = wc_ecc_mulmod_ex(u2, mQ, mG, curve->Af, curve->prime, 0,
+                                                                     key->heap);
+            /* find the montgomery mp */
+            if (err == MP_OKAY)
+                err = mp_montgomery_setup(curve->prime, &mp);
+        }
+
+        /* reduce */
+        if (err == MP_OKAY)
+            err = ecc_map(mG, curve->prime, mp);
+    }
+#else
+    /* use Shamir's trick to compute u1*mG + u2*mQ using half the doubles */
+    if (err == MP_OKAY) {
+        err = ecc_mul2add(mG, u1, mQ, u2, mG, curve->Af, curve->prime,
+                                                                     key->heap);
+    }
+#endif /* ECC_SHAMIR */
+#endif /* FREESCALE_LTC_ECC */
+   /* v = X_x1 mod n */
+   if (err == MP_OKAY)
+       err = mp_mod(mG->x, curve->order, v);
+
+   /* does v == r */
+   if (err == MP_OKAY) {
+       if (mp_cmp(v, r) == MP_EQ)
+           *res = 1;
+   }
+
+   /* cleanup */
+   wc_ecc_del_point_h(mG, key->heap);
+   wc_ecc_del_point_h(mQ, key->heap);
+
+   mp_clear(e);
+   if (did_init) {
+       mp_clear(v);
+       mp_clear(w);
+       mp_clear(u1);
+       mp_clear(u2);
+   }
+#ifdef WOLFSSL_SMALL_STACK
+   XFREE(u2, key->heap, DYNAMIC_TYPE_ECC);
+   XFREE(u1, key->heap, DYNAMIC_TYPE_ECC);
+   XFREE(w, key->heap, DYNAMIC_TYPE_ECC);
+   XFREE(v, key->heap, DYNAMIC_TYPE_ECC);
+#if !defined(WOLFSSL_ASYNC_CRYPT) || !defined(HAVE_CAVIUM_V)
+   XFREE(e_lcl, key->heap, DYNAMIC_TYPE_ECC);
+#endif
+#endif
+
+   wc_ecc_curve_free(curve);
+   FREE_CURVE_SPECS();
+
+#endif /* WOLFSSL_SP_MATH */
+#endif /* WOLFSSL_ATECC508A */
+
+   (void)keySz;
+   (void)hashlen;
+
+   return err;
+}
+#endif /* WOLFSSL_STM32_PKA */
+#endif /* HAVE_ECC_VERIFY */
+
+#ifdef HAVE_ECC_KEY_IMPORT
+/* import point from der
+ * if shortKeySize != 0 then keysize is always (inLen-1)>>1 */
+int wc_ecc_import_point_der_ex(byte* in, word32 inLen, const int curve_idx,
+                               ecc_point* point, int shortKeySize)
+{
+    int err = 0;
+#ifdef HAVE_COMP_KEY
+    int compressed = 0;
+#endif
+    int keysize;
+    byte pointType;
+
+#ifndef HAVE_COMP_KEY
+    (void)shortKeySize;
+#endif
+
+    if (in == NULL || point == NULL || (curve_idx < 0) ||
+        (wc_ecc_is_valid_idx(curve_idx) == 0))
+        return ECC_BAD_ARG_E;
+
+    /* must be odd */
+    if ((inLen & 1) == 0) {
+        return ECC_BAD_ARG_E;
+    }
+
+    /* init point */
+#ifdef ALT_ECC_SIZE
+    point->x = (mp_int*)&point->xyz[0];
+    point->y = (mp_int*)&point->xyz[1];
+    point->z = (mp_int*)&point->xyz[2];
+    alt_fp_init(point->x);
+    alt_fp_init(point->y);
+    alt_fp_init(point->z);
+#else
+    err = mp_init_multi(point->x, point->y, point->z, NULL, NULL, NULL);
+#endif
+    if (err != MP_OKAY)
+        return MEMORY_E;
+
+    /* check for point type (4, 2, or 3) */
+    pointType = in[0];
+    if (pointType != ECC_POINT_UNCOMP && pointType != ECC_POINT_COMP_EVEN &&
+                                         pointType != ECC_POINT_COMP_ODD) {
+        err = ASN_PARSE_E;
+    }
+
+    if (pointType == ECC_POINT_COMP_EVEN || pointType == ECC_POINT_COMP_ODD) {
+#ifdef HAVE_COMP_KEY
+        compressed = 1;
+#else
+        err = NOT_COMPILED_IN;
+#endif
+    }
+
+    /* adjust to skip first byte */
+    inLen -= 1;
+    in += 1;
+
+    /* calculate key size based on inLen / 2 if uncompressed or shortKeySize
+     * is true */
+#ifdef HAVE_COMP_KEY
+    keysize = compressed && !shortKeySize ? inLen : inLen>>1;
+#else
+    keysize = inLen>>1;
+#endif
+
+    /* read data */
+    if (err == MP_OKAY)
+        err = mp_read_unsigned_bin(point->x, (byte*)in, keysize);
+
+#ifdef HAVE_COMP_KEY
+    if (err == MP_OKAY && compressed == 1) {   /* build y */
+#ifndef WOLFSSL_SP_MATH
+        int did_init = 0;
+        mp_int t1, t2;
+        DECLARE_CURVE_SPECS(curve, 3);
+
+        ALLOC_CURVE_SPECS(3);
+
+        if (mp_init_multi(&t1, &t2, NULL, NULL, NULL, NULL) != MP_OKAY)
+            err = MEMORY_E;
+        else
+            did_init = 1;
+
+        /* load curve info */
+        if (err == MP_OKAY)
+            err = wc_ecc_curve_load(&ecc_sets[curve_idx], &curve,
+                (ECC_CURVE_FIELD_PRIME | ECC_CURVE_FIELD_AF |
+                    ECC_CURVE_FIELD_BF));
+
+        /* compute x^3 */
+        if (err == MP_OKAY)
+            err = mp_sqr(point->x, &t1);
+        if (err == MP_OKAY)
+            err = mp_mulmod(&t1, point->x, curve->prime, &t1);
+
+        /* compute x^3 + a*x */
+        if (err == MP_OKAY)
+            err = mp_mulmod(curve->Af, point->x, curve->prime, &t2);
+        if (err == MP_OKAY)
+            err = mp_add(&t1, &t2, &t1);
+
+        /* compute x^3 + a*x + b */
+        if (err == MP_OKAY)
+            err = mp_add(&t1, curve->Bf, &t1);
+
+        /* compute sqrt(x^3 + a*x + b) */
+        if (err == MP_OKAY)
+            err = mp_sqrtmod_prime(&t1, curve->prime, &t2);
+
+        /* adjust y */
+        if (err == MP_OKAY) {
+            if ((mp_isodd(&t2) == MP_YES && pointType == ECC_POINT_COMP_ODD) ||
+                (mp_isodd(&t2) == MP_NO &&  pointType == ECC_POINT_COMP_EVEN)) {
+                err = mp_mod(&t2, curve->prime, point->y);
+            }
+            else {
+                err = mp_submod(curve->prime, &t2, curve->prime, point->y);
+            }
+        }
+
+        if (did_init) {
+            mp_clear(&t2);
+            mp_clear(&t1);
+        }
+
+        wc_ecc_curve_free(curve);
+        FREE_CURVE_SPECS();
+#else
+    #ifndef WOLFSSL_SP_NO_256
+        if (curve_idx != ECC_CUSTOM_IDX &&
+                                      ecc_sets[curve_idx].id == ECC_SECP256R1) {
+            sp_ecc_uncompress_256(point->x, pointType, point->y);
+        }
+        else
+    #endif
+    #ifdef WOLFSSL_SP_384
+        if (curve_idx != ECC_CUSTOM_IDX &&
+                                      ecc_sets[curve_idx].id == ECC_SECP384R1) {
+            sp_ecc_uncompress_384(point->x, pointType, point->y);
+        }
+        else
+    #endif
+        {
+            err = WC_KEY_SIZE_E;
+        }
+#endif
+    }
+#endif
+
+    if (err == MP_OKAY) {
+#ifdef HAVE_COMP_KEY
+        if (compressed == 0)
+#endif
+            err = mp_read_unsigned_bin(point->y, (byte*)in + keysize, keysize);
+     }
+    if (err == MP_OKAY)
+        err = mp_set(point->z, 1);
+
+    if (err != MP_OKAY) {
+        mp_clear(point->x);
+        mp_clear(point->y);
+        mp_clear(point->z);
+    }
+
+    return err;
+}
+
+/* function for backwards compatiblity with previous implementations */
+int wc_ecc_import_point_der(byte* in, word32 inLen, const int curve_idx,
+                            ecc_point* point)
+{
+    return wc_ecc_import_point_der_ex(in, inLen, curve_idx, point, 1);
+}
+#endif /* HAVE_ECC_KEY_IMPORT */
+
+#ifdef HAVE_ECC_KEY_EXPORT
+/* export point to der */
+
+int wc_ecc_export_point_der_ex(const int curve_idx, ecc_point* point, byte* out,
+                               word32* outLen, int compressed)
+{
+    if (compressed == 0)
+        return wc_ecc_export_point_der(curve_idx, point, out, outLen);
+#ifdef HAVE_COMP_KEY
+    else
+        return wc_ecc_export_point_der_compressed(curve_idx, point, out, outLen);
+#else
+    return NOT_COMPILED_IN;
+#endif
+}
+
+int wc_ecc_export_point_der(const int curve_idx, ecc_point* point, byte* out,
+                            word32* outLen)
+{
+    int    ret = MP_OKAY;
+    word32 numlen;
+#ifdef WOLFSSL_SMALL_STACK
+    byte*  buf;
+#else
+    byte   buf[ECC_BUFSIZE];
+#endif
+
+    if ((curve_idx < 0) || (wc_ecc_is_valid_idx(curve_idx) == 0))
+        return ECC_BAD_ARG_E;
+
+    numlen = ecc_sets[curve_idx].size;
+
+    /* return length needed only */
+    if (point != NULL && out == NULL && outLen != NULL) {
+        *outLen = 1 + 2*numlen;
+        return LENGTH_ONLY_E;
+    }
+
+    if (point == NULL || out == NULL || outLen == NULL)
+        return ECC_BAD_ARG_E;
+
+    if (*outLen < (1 + 2*numlen)) {
+        *outLen = 1 + 2*numlen;
+        return BUFFER_E;
+    }
+
+    /* store byte point type */
+    out[0] = ECC_POINT_UNCOMP;
+
+#ifdef WOLFSSL_SMALL_STACK
+    buf = (byte*)XMALLOC(ECC_BUFSIZE, NULL, DYNAMIC_TYPE_ECC_BUFFER);
+    if (buf == NULL)
+        return MEMORY_E;
+#endif
+
+    /* pad and store x */
+    XMEMSET(buf, 0, ECC_BUFSIZE);
+    ret = mp_to_unsigned_bin(point->x, buf +
+                                 (numlen - mp_unsigned_bin_size(point->x)));
+    if (ret != MP_OKAY)
+        goto done;
+    XMEMCPY(out+1, buf, numlen);
+
+    /* pad and store y */
+    XMEMSET(buf, 0, ECC_BUFSIZE);
+    ret = mp_to_unsigned_bin(point->y, buf +
+                                 (numlen - mp_unsigned_bin_size(point->y)));
+    if (ret != MP_OKAY)
+        goto done;
+    XMEMCPY(out+1+numlen, buf, numlen);
+
+    *outLen = 1 + 2*numlen;
+
+done:
+#ifdef WOLFSSL_SMALL_STACK
+    XFREE(buf, NULL, DYNAMIC_TYPE_ECC_BUFFER);
+#endif
+
+    return ret;
+}
+
+
+/* export point to der */
+#ifdef HAVE_COMP_KEY
+int wc_ecc_export_point_der_compressed(const int curve_idx, ecc_point* point,
+                                       byte* out, word32* outLen)
+{
+    int    ret = MP_OKAY;
+    word32 numlen;
+    word32 output_len;
+#ifdef WOLFSSL_SMALL_STACK
+    byte*  buf;
+#else
+    byte   buf[ECC_BUFSIZE];
+#endif
+
+    if ((curve_idx < 0) || (wc_ecc_is_valid_idx(curve_idx) == 0))
+        return ECC_BAD_ARG_E;
+
+    numlen = ecc_sets[curve_idx].size;
+    output_len = 1 + numlen; /* y point type + x */
+
+    /* return length needed only */
+    if (point != NULL && out == NULL && outLen != NULL) {
+        *outLen = output_len;
+        return LENGTH_ONLY_E;
+    }
+
+    if (point == NULL || out == NULL || outLen == NULL)
+        return ECC_BAD_ARG_E;
+
+
+    if (*outLen < output_len) {
+        *outLen = output_len;
+        return BUFFER_E;
+    }
+
+    /* store byte point type */
+    out[0] = mp_isodd(point->y) == MP_YES ? ECC_POINT_COMP_ODD :
+                                            ECC_POINT_COMP_EVEN;
+
+#ifdef WOLFSSL_SMALL_STACK
+    buf = (byte*)XMALLOC(ECC_BUFSIZE, NULL, DYNAMIC_TYPE_ECC_BUFFER);
+    if (buf == NULL)
+        return MEMORY_E;
+#endif
+
+    /* pad and store x */
+    XMEMSET(buf, 0, ECC_BUFSIZE);
+    ret = mp_to_unsigned_bin(point->x, buf +
+                                 (numlen - mp_unsigned_bin_size(point->x)));
+    if (ret != MP_OKAY)
+        goto done;
+    XMEMCPY(out+1, buf, numlen);
+
+    *outLen = output_len;
+
+done:
+#ifdef WOLFSSL_SMALL_STACK
+    XFREE(buf, NULL, DYNAMIC_TYPE_ECC_BUFFER);
+#endif
+
+    return ret;
+}
+#endif /* HAVE_COMP_KEY */
+
+/* export public ECC key in ANSI X9.63 format */
+int wc_ecc_export_x963(ecc_key* key, byte* out, word32* outLen)
+{
+   int    ret = MP_OKAY;
+   word32 numlen;
+#ifdef WOLFSSL_SMALL_STACK
+   byte*  buf;
+#else
+   byte   buf[ECC_BUFSIZE];
+#endif
+   word32 pubxlen, pubylen;
+
+   /* return length needed only */
+   if (key != NULL && out == NULL && outLen != NULL) {
+      /* if key hasn't been setup assume max bytes for size estimation */
+      numlen = key->dp ? key->dp->size : MAX_ECC_BYTES;
+      *outLen = 1 + 2*numlen;
+      return LENGTH_ONLY_E;
+   }
+
+   if (key == NULL || out == NULL || outLen == NULL)
+      return ECC_BAD_ARG_E;
+
+   if (key->type == ECC_PRIVATEKEY_ONLY)
+       return ECC_PRIVATEONLY_E;
+
+   if (wc_ecc_is_valid_idx(key->idx) == 0 || key->dp == NULL) {
+      return ECC_BAD_ARG_E;
+   }
+   numlen = key->dp->size;
+
+    /* verify room in out buffer */
+   if (*outLen < (1 + 2*numlen)) {
+      *outLen = 1 + 2*numlen;
+      return BUFFER_E;
+   }
+
+   /* verify public key length is less than key size */
+   pubxlen = mp_unsigned_bin_size(key->pubkey.x);
+   pubylen = mp_unsigned_bin_size(key->pubkey.y);
+   if ((pubxlen > numlen) || (pubylen > numlen)) {
+      WOLFSSL_MSG("Public key x/y invalid!");
+      return BUFFER_E;
+   }
+
+   /* store byte point type */
+   out[0] = ECC_POINT_UNCOMP;
+
+#ifdef WOLFSSL_SMALL_STACK
+   buf = (byte*)XMALLOC(ECC_BUFSIZE, NULL, DYNAMIC_TYPE_ECC_BUFFER);
+   if (buf == NULL)
+      return MEMORY_E;
+#endif
+
+   /* pad and store x */
+   XMEMSET(buf, 0, ECC_BUFSIZE);
+   ret = mp_to_unsigned_bin(key->pubkey.x, buf + (numlen - pubxlen));
+   if (ret != MP_OKAY)
+      goto done;
+   XMEMCPY(out+1, buf, numlen);
+
+   /* pad and store y */
+   XMEMSET(buf, 0, ECC_BUFSIZE);
+   ret = mp_to_unsigned_bin(key->pubkey.y, buf + (numlen - pubylen));
+   if (ret != MP_OKAY)
+      goto done;
+   XMEMCPY(out+1+numlen, buf, numlen);
+
+   *outLen = 1 + 2*numlen;
+
+done:
+#ifdef WOLFSSL_SMALL_STACK
+   XFREE(buf, NULL, DYNAMIC_TYPE_ECC_BUFFER);
+#endif
+
+   return ret;
+}
+
+
+/* export public ECC key in ANSI X9.63 format, extended with
+ * compression option */
+int wc_ecc_export_x963_ex(ecc_key* key, byte* out, word32* outLen,
+                          int compressed)
+{
+    if (compressed == 0)
+        return wc_ecc_export_x963(key, out, outLen);
+#ifdef HAVE_COMP_KEY
+    else
+        return wc_ecc_export_x963_compressed(key, out, outLen);
+#else
+    return NOT_COMPILED_IN;
+#endif
+}
+#endif /* HAVE_ECC_KEY_EXPORT */
+
+
+#if !defined(WOLFSSL_ATECC508A) && !defined(WOLFSSL_CRYPTOCELL)
+
+/* is ecc point on curve described by dp ? */
+int wc_ecc_is_point(ecc_point* ecp, mp_int* a, mp_int* b, mp_int* prime)
+{
+#ifndef WOLFSSL_SP_MATH
+   int err;
+#ifdef WOLFSSL_SMALL_STACK
+   mp_int* t1;
+   mp_int* t2;
+#else
+   mp_int  t1[1], t2[1];
+#endif
+
+#ifdef WOLFSSL_SMALL_STACK
+   t1 = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);
+   if (t1 == NULL)
+       return MEMORY_E;
+   t2 = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);
+   if (t2 == NULL) {
+       XFREE(t1, NULL, DYNAMIC_TYPE_ECC);
+       return MEMORY_E;
+   }
+#endif
+
+   if ((err = mp_init_multi(t1, t2, NULL, NULL, NULL, NULL)) != MP_OKAY) {
+   #ifdef WOLFSSL_SMALL_STACK
+      XFREE(t2, NULL, DYNAMIC_TYPE_ECC);
+      XFREE(t1, NULL, DYNAMIC_TYPE_ECC);
+   #endif
+      return err;
+   }
+
+   /* compute y^2 */
+   if (err == MP_OKAY)
+       err = mp_sqr(ecp->y, t1);
+
+   /* compute x^3 */
+   if (err == MP_OKAY)
+       err = mp_sqr(ecp->x, t2);
+   if (err == MP_OKAY)
+       err = mp_mod(t2, prime, t2);
+   if (err == MP_OKAY)
+       err = mp_mul(ecp->x, t2, t2);
+
+   /* compute y^2 - x^3 */
+   if (err == MP_OKAY)
+       err = mp_sub(t1, t2, t1);
+
+   /* Determine if curve "a" should be used in calc */
+#ifdef WOLFSSL_CUSTOM_CURVES
+   if (err == MP_OKAY) {
+      /* Use a and prime to determine if a == 3 */
+      err = mp_set(t2, 0);
+      if (err == MP_OKAY)
+          err = mp_submod(prime, a, prime, t2);
+   }
+   if (err == MP_OKAY && mp_cmp_d(t2, 3) != MP_EQ) {
+      /* compute y^2 - x^3 + a*x */
+      if (err == MP_OKAY)
+          err = mp_mulmod(t2, ecp->x, prime, t2);
+      if (err == MP_OKAY)
+          err = mp_addmod(t1, t2, prime, t1);
+   }
+   else
+#endif /* WOLFSSL_CUSTOM_CURVES */
+   {
+      /* assumes "a" == 3 */
+      (void)a;
+
+      /* compute y^2 - x^3 + 3x */
+      if (err == MP_OKAY)
+          err = mp_add(t1, ecp->x, t1);
+      if (err == MP_OKAY)
+          err = mp_add(t1, ecp->x, t1);
+      if (err == MP_OKAY)
+          err = mp_add(t1, ecp->x, t1);
+      if (err == MP_OKAY)
+          err = mp_mod(t1, prime, t1);
+  }
+
+   /* adjust range (0, prime) */
+   while (err == MP_OKAY && mp_isneg(t1)) {
+      err = mp_add(t1, prime, t1);
+   }
+   while (err == MP_OKAY && mp_cmp(t1, prime) != MP_LT) {
+      err = mp_sub(t1, prime, t1);
+   }
+
+   /* compare to b */
+   if (err == MP_OKAY) {
+       if (mp_cmp(t1, b) != MP_EQ) {
+          err = MP_VAL;
+       } else {
+          err = MP_OKAY;
+       }
+   }
+
+   mp_clear(t1);
+   mp_clear(t2);
+#ifdef WOLFSSL_SMALL_STACK
+   XFREE(t2, NULL, DYNAMIC_TYPE_ECC);
+   XFREE(t1, NULL, DYNAMIC_TYPE_ECC);
+#endif
+
+   return err;
+#else
+   (void)a;
+   (void)b;
+
+#ifndef WOLFSSL_SP_NO_256
+   if (mp_count_bits(prime) == 256) {
+       return sp_ecc_is_point_256(ecp->x, ecp->y);
+   }
+#endif
+#ifdef WOLFSSL_SP_384
+   if (mp_count_bits(prime) == 384) {
+       return sp_ecc_is_point_384(ecp->x, ecp->y);
+   }
+#endif
+   return WC_KEY_SIZE_E;
+#endif
+}
+
+#ifndef WOLFSSL_SP_MATH
+/* validate privkey * generator == pubkey, 0 on success */
+static int ecc_check_privkey_gen(ecc_key* key, mp_int* a, mp_int* prime)
+{
+    int        err = MP_OKAY;
+    ecc_point* base = NULL;
+    ecc_point* res  = NULL;
+    DECLARE_CURVE_SPECS(curve, 2);
+
+    if (key == NULL)
+        return BAD_FUNC_ARG;
+
+    ALLOC_CURVE_SPECS(2);
+
+    res = wc_ecc_new_point_h(key->heap);
+    if (res == NULL)
+        err = MEMORY_E;
+
+#ifdef WOLFSSL_HAVE_SP_ECC
+#ifndef WOLFSSL_SP_NO_256
+    if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SECP256R1) {
+        if (err == MP_OKAY) {
+            err = sp_ecc_mulmod_base_256(&key->k, res, 1, key->heap);
+        }
+    }
+    else
+#endif
+#ifdef WOLFSSL_SP_384
+    if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SECP384R1) {
+        if (err == MP_OKAY) {
+            err = sp_ecc_mulmod_base_384(&key->k, res, 1, key->heap);
+        }
+    }
+    else
+#endif
+#endif
+    {
+        base = wc_ecc_new_point_h(key->heap);
+        if (base == NULL)
+            err = MEMORY_E;
+
+        if (err == MP_OKAY) {
+            /* load curve info */
+            err = wc_ecc_curve_load(key->dp, &curve,
+                                      (ECC_CURVE_FIELD_GX | ECC_CURVE_FIELD_GY));
+        }
+
+        /* set up base generator */
+        if (err == MP_OKAY)
+            err = mp_copy(curve->Gx, base->x);
+        if (err == MP_OKAY)
+            err = mp_copy(curve->Gy, base->y);
+        if (err == MP_OKAY)
+            err = mp_set(base->z, 1);
+
+        if (err == MP_OKAY)
+            err = wc_ecc_mulmod_ex(&key->k, base, res, a, prime, 1, key->heap);
+    }
+
+    if (err == MP_OKAY) {
+        /* compare result to public key */
+        if (mp_cmp(res->x, key->pubkey.x) != MP_EQ ||
+            mp_cmp(res->y, key->pubkey.y) != MP_EQ ||
+            mp_cmp(res->z, key->pubkey.z) != MP_EQ) {
+            /* didn't match */
+            err = ECC_PRIV_KEY_E;
+        }
+    }
+
+    wc_ecc_curve_free(curve);
+    wc_ecc_del_point_h(res, key->heap);
+    wc_ecc_del_point_h(base, key->heap);
+    FREE_CURVE_SPECS();
+
+    return err;
+}
+#endif
+
+#ifdef WOLFSSL_VALIDATE_ECC_IMPORT
+
+/* check privkey generator helper, creates prime needed */
+static int ecc_check_privkey_gen_helper(ecc_key* key)
+{
+    int    err;
+#ifndef WOLFSSL_ATECC508A
+    DECLARE_CURVE_SPECS(curve, 2);
+#endif
+
+    if (key == NULL)
+        return BAD_FUNC_ARG;
+
+#ifdef WOLFSSL_ATECC508A
+    /* Hardware based private key, so this operation is not supported */
+    err = MP_OKAY; /* just report success */
+
+#else
+    ALLOC_CURVE_SPECS(2);
+
+    /* load curve info */
+    err = wc_ecc_curve_load(key->dp, &curve,
+        (ECC_CURVE_FIELD_PRIME | ECC_CURVE_FIELD_AF));
+
+    if (err == MP_OKAY)
+        err = ecc_check_privkey_gen(key, curve->Af, curve->prime);
+
+    wc_ecc_curve_free(curve);
+    FREE_CURVE_SPECS();
+
+#endif /* WOLFSSL_ATECC508A */
+
+    return err;
+}
+
+#endif /* WOLFSSL_VALIDATE_ECC_IMPORT */
+
+#if defined(WOLFSSL_VALIDATE_ECC_KEYGEN) || !defined(WOLFSSL_SP_MATH)
+/* validate order * pubkey = point at infinity, 0 on success */
+static int ecc_check_pubkey_order(ecc_key* key, ecc_point* pubkey, mp_int* a,
+        mp_int* prime, mp_int* order)
+{
+    ecc_point* inf = NULL;
+    int        err;
+
+    if (key == NULL)
+        return BAD_FUNC_ARG;
+
+    inf = wc_ecc_new_point_h(key->heap);
+    if (inf == NULL)
+        err = MEMORY_E;
+    else {
+#ifdef WOLFSSL_HAVE_SP_ECC
+#ifndef WOLFSSL_SP_NO_256
+        if (key->idx != ECC_CUSTOM_IDX &&
+                                       ecc_sets[key->idx].id == ECC_SECP256R1) {
+            err = sp_ecc_mulmod_256(order, pubkey, inf, 1, key->heap);
+        }
+        else
+#endif
+#ifdef WOLFSSL_SP_384
+        if (key->idx != ECC_CUSTOM_IDX &&
+                                       ecc_sets[key->idx].id == ECC_SECP384R1) {
+            err = sp_ecc_mulmod_384(order, pubkey, inf, 1, key->heap);
+        }
+        else
+#endif
+#endif
+#ifndef WOLFSSL_SP_MATH
+            err = wc_ecc_mulmod_ex(order, pubkey, inf, a, prime, 1, key->heap);
+        if (err == MP_OKAY && !wc_ecc_point_is_at_infinity(inf))
+            err = ECC_INF_E;
+#else
+            (void)a;
+            (void)prime;
+
+            err = WC_KEY_SIZE_E;
+#endif
+    }
+
+    wc_ecc_del_point_h(inf, key->heap);
+
+    return err;
+}
+#endif
+#endif /* !WOLFSSL_ATECC508A && !WOLFSSL_CRYPTOCELL*/
+
+#ifdef OPENSSL_EXTRA
+int wc_ecc_get_generator(ecc_point* ecp, int curve_idx)
+{
+    int err = MP_OKAY;
+    DECLARE_CURVE_SPECS(curve, 2);
+
+    if (!ecp || curve_idx < 0 || curve_idx > (int)(ECC_SET_COUNT-1))
+        return BAD_FUNC_ARG;
+
+    ALLOC_CURVE_SPECS(2);
+
+    err = wc_ecc_curve_load(&ecc_sets[curve_idx], &curve,
+                            (ECC_CURVE_FIELD_GX | ECC_CURVE_FIELD_GY));
+    if (err == MP_OKAY)
+        err = mp_copy(curve->Gx, ecp->x);
+    if (err == MP_OKAY)
+        err = mp_copy(curve->Gy, ecp->y);
+    if (err == MP_OKAY)
+        err = mp_set(ecp->z, 1);
+
+    wc_ecc_curve_free(curve);
+    FREE_CURVE_SPECS();
+
+    return err;
+}
+#endif /* OPENSSLALL */
+
+/* perform sanity checks on ecc key validity, 0 on success */
+int wc_ecc_check_key(ecc_key* key)
+{
+    int    err;
+#ifndef WOLFSSL_SP_MATH
+#if !defined(WOLFSSL_ATECC508A) && !defined(WOLFSSL_CRYPTOCELL)
+    mp_int* b = NULL;
+#ifdef USE_ECC_B_PARAM
+    DECLARE_CURVE_SPECS(curve, 4);
+#else
+#ifndef WOLFSSL_SMALL_STACK
+    mp_int b_lcl;
+#endif
+    DECLARE_CURVE_SPECS(curve, 3);
+#endif /* USE_ECC_B_PARAM */
+#endif /* WOLFSSL_ATECC508A */
+
+    if (key == NULL)
+        return BAD_FUNC_ARG;
+
+#if defined(WOLFSSL_ATECC508A) || defined(WOLFSSL_CRYPTOCELL)
+
+    err = 0; /* consider key check success on ATECC508A */
+
+#else
+    #ifdef USE_ECC_B_PARAM
+        ALLOC_CURVE_SPECS(4);
+    #else
+        ALLOC_CURVE_SPECS(3);
+        #ifndef WOLFSSL_SMALL_STACK
+            b = &b_lcl;
+        #else
+            b = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_ECC);
+            if (b == NULL) {
+                FREE_CURVE_SPECS();
+                return MEMORY_E;
+            }
+        #endif
+        XMEMSET(b, 0, sizeof(mp_int));
+    #endif
+
+    /* SP 800-56Ar3, section 5.6.2.3.3, process step 1 */
+    /* pubkey point cannot be at infinity */
+    if (wc_ecc_point_is_at_infinity(&key->pubkey)) {
+    #ifdef WOLFSSL_SMALL_STACK
+        XFREE(b, key->heap, DYNAMIC_TYPE_ECC);
+    #endif
+        FREE_CURVE_SPECS();
+        return ECC_INF_E;
+    }
+
+    /* load curve info */
+    err = wc_ecc_curve_load(key->dp, &curve, (ECC_CURVE_FIELD_PRIME |
+            ECC_CURVE_FIELD_AF | ECC_CURVE_FIELD_ORDER
+#ifdef USE_ECC_B_PARAM
+            | ECC_CURVE_FIELD_BF
+#endif
+    ));
+
+#ifndef USE_ECC_B_PARAM
+    /* load curve b parameter */
+    if (err == MP_OKAY)
+        err = mp_init(b);
+    if (err == MP_OKAY)
+        err = mp_read_radix(b, key->dp->Bf, MP_RADIX_HEX);
+#else
+    if (err == MP_OKAY)
+        b = curve->Bf;
+#endif
+
+    /* SP 800-56Ar3, section 5.6.2.3.3, process step 2 */
+    /* Qx must be in the range [0, p-1] */
+    if (err == MP_OKAY) {
+        if (mp_cmp(key->pubkey.x, curve->prime) != MP_LT)
+            err = ECC_OUT_OF_RANGE_E;
+    }
+
+    /* Qy must be in the range [0, p-1] */
+    if (err == MP_OKAY) {
+        if (mp_cmp(key->pubkey.y, curve->prime) != MP_LT)
+            err = ECC_OUT_OF_RANGE_E;
+    }
+
+    /* SP 800-56Ar3, section 5.6.2.3.3, process steps 3 */
+    /* make sure point is actually on curve */
+    if (err == MP_OKAY)
+        err = wc_ecc_is_point(&key->pubkey, curve->Af, b, curve->prime);
+
+    /* SP 800-56Ar3, section 5.6.2.3.3, process steps 4 */
+    /* pubkey * order must be at infinity */
+    if (err == MP_OKAY)
+        err = ecc_check_pubkey_order(key, &key->pubkey, curve->Af, curve->prime,
+                curve->order);
+
+    /* SP 800-56Ar3, section 5.6.2.1.4, method (b) for ECC */
+    /* private * base generator must equal pubkey */
+    if (err == MP_OKAY && key->type == ECC_PRIVATEKEY)
+        err = ecc_check_privkey_gen(key, curve->Af, curve->prime);
+
+    wc_ecc_curve_free(curve);
+
+#ifndef USE_ECC_B_PARAM
+    mp_clear(b);
+    #ifdef WOLFSSL_SMALL_STACK
+        XFREE(b, key->heap, DYNAMIC_TYPE_ECC);
+    #endif
+#endif
+
+    FREE_CURVE_SPECS();
+
+#endif /* WOLFSSL_ATECC508A */
+#else
+    if (key == NULL)
+        return BAD_FUNC_ARG;
+
+    /* pubkey point cannot be at infinity */
+#ifndef WOLFSSL_SP_NO_256
+    if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SECP256R1) {
+        err = sp_ecc_check_key_256(key->pubkey.x, key->pubkey.y, &key->k,
+                                                                     key->heap);
+    }
+    else
+#endif
+#ifdef WOLFSSL_SP_384
+    if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SECP384R1) {
+        err = sp_ecc_check_key_384(key->pubkey.x, key->pubkey.y, &key->k,
+                                                                     key->heap);
+    }
+    else
+#endif
+    {
+        err = WC_KEY_SIZE_E;
+    }
+#endif
+
+    return err;
+}
+
+#ifdef HAVE_ECC_KEY_IMPORT
+/* import public ECC key in ANSI X9.63 format */
+int wc_ecc_import_x963_ex(const byte* in, word32 inLen, ecc_key* key,
+                          int curve_id)
+{
+    int err = MP_OKAY;
+#ifdef HAVE_COMP_KEY
+    int compressed = 0;
+#endif
+    int keysize = 0;
+    byte pointType;
+
+    if (in == NULL || key == NULL)
+        return BAD_FUNC_ARG;
+
+    /* must be odd */
+    if ((inLen & 1) == 0) {
+        return ECC_BAD_ARG_E;
+    }
+
+    /* make sure required variables are reset */
+    wc_ecc_reset(key);
+
+    /* init key */
+    #ifdef ALT_ECC_SIZE
+        key->pubkey.x = (mp_int*)&key->pubkey.xyz[0];
+        key->pubkey.y = (mp_int*)&key->pubkey.xyz[1];
+        key->pubkey.z = (mp_int*)&key->pubkey.xyz[2];
+        alt_fp_init(key->pubkey.x);
+        alt_fp_init(key->pubkey.y);
+        alt_fp_init(key->pubkey.z);
+        err = mp_init(&key->k);
+    #else
+        err = mp_init_multi(&key->k,
+                    key->pubkey.x, key->pubkey.y, key->pubkey.z, NULL, NULL);
+    #endif
+    if (err != MP_OKAY)
+        return MEMORY_E;
+
+    /* check for point type (4, 2, or 3) */
+    pointType = in[0];
+    if (pointType != ECC_POINT_UNCOMP && pointType != ECC_POINT_COMP_EVEN &&
+                                         pointType != ECC_POINT_COMP_ODD) {
+        err = ASN_PARSE_E;
+    }
+
+    if (pointType == ECC_POINT_COMP_EVEN || pointType == ECC_POINT_COMP_ODD) {
+    #ifdef HAVE_COMP_KEY
+        compressed = 1;
+    #else
+        err = NOT_COMPILED_IN;
+    #endif
+    }
+
+    /* adjust to skip first byte */
+    inLen -= 1;
+    in += 1;
+
+#ifdef WOLFSSL_ATECC508A
+    /* For SECP256R1 only save raw public key for hardware */
+    if (curve_id == ECC_SECP256R1 && inLen <= sizeof(key->pubkey_raw)) {
+    #ifdef HAVE_COMP_KEY
+        if (!compressed)
+    #endif
+            XMEMCPY(key->pubkey_raw, (byte*)in, inLen);
+    }
+#endif
+
+    if (err == MP_OKAY) {
+    #ifdef HAVE_COMP_KEY
+        /* adjust inLen if compressed */
+        if (compressed)
+            inLen = inLen*2 + 1;  /* used uncompressed len */
+    #endif
+
+        /* determine key size */
+        keysize = (inLen>>1);
+        err = wc_ecc_set_curve(key, keysize, curve_id);
+        key->type = ECC_PUBLICKEY;
+    }
+
+    /* read data */
+    if (err == MP_OKAY)
+        err = mp_read_unsigned_bin(key->pubkey.x, (byte*)in, keysize);
+
+#ifdef HAVE_COMP_KEY
+    if (err == MP_OKAY && compressed == 1) {   /* build y */
+#ifndef WOLFSSL_SP_MATH
+        mp_int t1, t2;
+        int did_init = 0;
+
+        DECLARE_CURVE_SPECS(curve, 3);
+        ALLOC_CURVE_SPECS(3);
+
+        if (mp_init_multi(&t1, &t2, NULL, NULL, NULL, NULL) != MP_OKAY)
+            err = MEMORY_E;
+        else
+            did_init = 1;
+
+        /* load curve info */
+        if (err == MP_OKAY)
+            err = wc_ecc_curve_load(key->dp, &curve,
+                (ECC_CURVE_FIELD_PRIME | ECC_CURVE_FIELD_AF |
+                 ECC_CURVE_FIELD_BF));
+
+        /* compute x^3 */
+        if (err == MP_OKAY)
+            err = mp_sqr(key->pubkey.x, &t1);
+        if (err == MP_OKAY)
+            err = mp_mulmod(&t1, key->pubkey.x, curve->prime, &t1);
+
+        /* compute x^3 + a*x */
+        if (err == MP_OKAY)
+            err = mp_mulmod(curve->Af, key->pubkey.x, curve->prime, &t2);
+        if (err == MP_OKAY)
+            err = mp_add(&t1, &t2, &t1);
+
+        /* compute x^3 + a*x + b */
+        if (err == MP_OKAY)
+            err = mp_add(&t1, curve->Bf, &t1);
+
+        /* compute sqrt(x^3 + a*x + b) */
+        if (err == MP_OKAY)
+            err = mp_sqrtmod_prime(&t1, curve->prime, &t2);
+
+        /* adjust y */
+        if (err == MP_OKAY) {
+            if ((mp_isodd(&t2) == MP_YES && pointType == ECC_POINT_COMP_ODD) ||
+                (mp_isodd(&t2) == MP_NO &&  pointType == ECC_POINT_COMP_EVEN)) {
+                err = mp_mod(&t2, curve->prime, &t2);
+            }
+            else {
+                err = mp_submod(curve->prime, &t2, curve->prime, &t2);
+            }
+            if (err == MP_OKAY)
+                err = mp_copy(&t2, key->pubkey.y);
+        }
+
+        if (did_init) {
+            mp_clear(&t2);
+            mp_clear(&t1);
+        }
+
+        wc_ecc_curve_free(curve);
+        FREE_CURVE_SPECS();
+#else
+    #ifndef WOLFSSL_SP_NO_256
+        if (key->dp->id == ECC_SECP256R1) {
+            sp_ecc_uncompress_256(key->pubkey.x, pointType, key->pubkey.y);
+        }
+        else
+    #endif
+    #ifdef WOLFSSL_SP_384
+        if (key->dp->id == ECC_SECP384R1) {
+            sp_ecc_uncompress_384(key->pubkey.x, pointType, key->pubkey.y);
+        }
+        else
+    #endif
+        {
+            err = WC_KEY_SIZE_E;
+        }
+#endif
+    }
+#endif /* HAVE_COMP_KEY */
+
+    if (err == MP_OKAY) {
+    #ifdef HAVE_COMP_KEY
+        if (compressed == 0)
+    #endif
+        {
+            err = mp_read_unsigned_bin(key->pubkey.y, (byte*)in + keysize,
+                                                                      keysize);
+        }
+    }
+    if (err == MP_OKAY)
+        err = mp_set(key->pubkey.z, 1);
+
+#ifdef WOLFSSL_VALIDATE_ECC_IMPORT
+    if (err == MP_OKAY)
+        err = wc_ecc_check_key(key);
+#endif
+
+    if (err != MP_OKAY) {
+        mp_clear(key->pubkey.x);
+        mp_clear(key->pubkey.y);
+        mp_clear(key->pubkey.z);
+        mp_clear(&key->k);
+    }
+
+    return err;
+}
+
+WOLFSSL_ABI
+int wc_ecc_import_x963(const byte* in, word32 inLen, ecc_key* key)
+{
+    return wc_ecc_import_x963_ex(in, inLen, key, ECC_CURVE_DEF);
+}
+#endif /* HAVE_ECC_KEY_IMPORT */
+
+#ifdef HAVE_ECC_KEY_EXPORT
+
+/* export ecc key to component form, d is optional if only exporting public
+ * encType is WC_TYPE_UNSIGNED_BIN or WC_TYPE_HEX_STR
+ * return MP_OKAY on success */
+int wc_ecc_export_ex(ecc_key* key, byte* qx, word32* qxLen,
+                 byte* qy, word32* qyLen, byte* d, word32* dLen, int encType)
+{
+    int err = 0;
+    word32 keySz;
+
+    if (key == NULL) {
+        return BAD_FUNC_ARG;
+    }
+
+    if (wc_ecc_is_valid_idx(key->idx) == 0) {
+        return ECC_BAD_ARG_E;
+    }
+    keySz = key->dp->size;
+
+    /* private key, d */
+    if (d != NULL) {
+        if (dLen == NULL ||
+            (key->type != ECC_PRIVATEKEY && key->type != ECC_PRIVATEKEY_ONLY))
+            return BAD_FUNC_ARG;
+
+    #ifdef WOLFSSL_ATECC508A
+        /* Hardware cannot export private portion */
+        return NOT_COMPILED_IN;
+    #else
+        err = wc_export_int(&key->k, d, dLen, keySz, encType);
+        if (err != MP_OKAY)
+            return err;
+    #endif
+    }
+
+    /* public x component */
+    if (qx != NULL) {
+        if (qxLen == NULL || key->type == ECC_PRIVATEKEY_ONLY)
+            return BAD_FUNC_ARG;
+
+        err = wc_export_int(key->pubkey.x, qx, qxLen, keySz, encType);
+        if (err != MP_OKAY)
+            return err;
+    }
+
+    /* public y component */
+    if (qy != NULL) {
+        if (qyLen == NULL || key->type == ECC_PRIVATEKEY_ONLY)
+            return BAD_FUNC_ARG;
+
+        err = wc_export_int(key->pubkey.y, qy, qyLen, keySz, encType);
+        if (err != MP_OKAY)
+            return err;
+    }
+
+    return err;
+}
+
+
+/* export ecc private key only raw, outLen is in/out size as unsigned bin
+   return MP_OKAY on success */
+int wc_ecc_export_private_only(ecc_key* key, byte* out, word32* outLen)
+{
+    if (out == NULL || outLen == NULL) {
+        return BAD_FUNC_ARG;
+    }
+
+    return wc_ecc_export_ex(key, NULL, NULL, NULL, NULL, out, outLen,
+        WC_TYPE_UNSIGNED_BIN);
+}
+
+/* export public key to raw elements including public (Qx,Qy) as unsigned bin
+ * return MP_OKAY on success, negative on error */
+int wc_ecc_export_public_raw(ecc_key* key, byte* qx, word32* qxLen,
+                             byte* qy, word32* qyLen)
+{
+    if (qx == NULL || qxLen == NULL || qy == NULL || qyLen == NULL) {
+        return BAD_FUNC_ARG;
+    }
+
+    return wc_ecc_export_ex(key, qx, qxLen, qy, qyLen, NULL, NULL,
+        WC_TYPE_UNSIGNED_BIN);
+}
+
+/* export ecc key to raw elements including public (Qx,Qy) and
+ *   private (d) as unsigned bin
+ * return MP_OKAY on success, negative on error */
+int wc_ecc_export_private_raw(ecc_key* key, byte* qx, word32* qxLen,
+                              byte* qy, word32* qyLen, byte* d, word32* dLen)
+{
+    return wc_ecc_export_ex(key, qx, qxLen, qy, qyLen, d, dLen,
+        WC_TYPE_UNSIGNED_BIN);
+}
+
+#endif /* HAVE_ECC_KEY_EXPORT */
+
+#ifdef HAVE_ECC_KEY_IMPORT
+/* import private key, public part optional if (pub) passed as NULL */
+int wc_ecc_import_private_key_ex(const byte* priv, word32 privSz,
+                                 const byte* pub, word32 pubSz, ecc_key* key,
+                                 int curve_id)
+{
+    int ret;
+#if defined(WOLFSSL_CRYPTOCELL) && !defined(WOLFSSL_ATECC508A)
+    const CRYS_ECPKI_Domain_t* pDomain;
+    CRYS_ECPKI_BUILD_TempData_t tempBuff;
+#endif
+    if (key == NULL || priv == NULL)
+        return BAD_FUNC_ARG;
+
+    /* public optional, NULL if only importing private */
+    if (pub != NULL) {
+    #ifndef NO_ASN
+        word32 idx = 0;
+        ret = wc_ecc_import_x963_ex(pub, pubSz, key, curve_id);
+        if (ret < 0)
+            ret = wc_EccPublicKeyDecode(pub, &idx, key, pubSz);
+        key->type = ECC_PRIVATEKEY;
+    #else
+        ret = NOT_COMPILED_IN;
+    #endif
+    }
+    else {
+        /* make sure required variables are reset */
+        wc_ecc_reset(key);
+
+        /* set key size */
+        ret = wc_ecc_set_curve(key, privSz, curve_id);
+        key->type = ECC_PRIVATEKEY_ONLY;
+    }
+
+    if (ret != 0)
+        return ret;
+
+#ifdef WOLFSSL_ATECC508A
+    /* Hardware does not support loading private keys */
+    return NOT_COMPILED_IN;
+#elif defined(WOLFSSL_CRYPTOCELL)
+    pDomain = CRYS_ECPKI_GetEcDomain(cc310_mapCurve(curve_id));
+
+    if (pub != NULL && pub[0] != '\0') {
+        /* create public key from external key buffer */
+        ret = CRYS_ECPKI_BuildPublKeyFullCheck(pDomain,
+                                               (byte*)pub,
+                                               pubSz,
+                                               &key->ctx.pubKey,
+                                               &tempBuff);
+
+        if (ret != SA_SILIB_RET_OK){
+            WOLFSSL_MSG("CRYS_ECPKI_BuildPublKeyFullCheck failed");
+            return ret;
+        }
+    }
+    /* import private key */
+    if (priv != NULL && priv[0] != '\0') {
+
+        /* Create private key from external key buffer*/
+        ret = CRYS_ECPKI_BuildPrivKey(pDomain,
+                                      priv,
+                                      privSz,
+                                      &key->ctx.privKey);
+
+        if (ret != SA_SILIB_RET_OK) {
+            WOLFSSL_MSG("CRYS_ECPKI_BuildPrivKey failed");
+            return ret;
+        }
+
+        ret = mp_read_unsigned_bin(&key->k, priv, privSz);
+    }
+
+#else
+
+    ret = mp_read_unsigned_bin(&key->k, priv, privSz);
+#ifdef HAVE_WOLF_BIGINT
+    if (ret == 0 &&
+                  wc_bigint_from_unsigned_bin(&key->k.raw, priv, privSz) != 0) {
+        mp_clear(&key->k);
+        ret = ASN_GETINT_E;
+    }
+#endif /* HAVE_WOLF_BIGINT */
+
+
+#endif /* WOLFSSL_ATECC508A */
+
+#ifdef WOLFSSL_VALIDATE_ECC_IMPORT
+    if ((pub != NULL) && (ret == MP_OKAY))
+        /* public key needed to perform key validation */
+        ret = ecc_check_privkey_gen_helper(key);
+#endif
+
+    return ret;
+}
+
+/* ecc private key import, public key in ANSI X9.63 format, private raw */
+int wc_ecc_import_private_key(const byte* priv, word32 privSz, const byte* pub,
+                           word32 pubSz, ecc_key* key)
+{
+    return wc_ecc_import_private_key_ex(priv, privSz, pub, pubSz, key,
+                                                                ECC_CURVE_DEF);
+}
+#endif /* HAVE_ECC_KEY_IMPORT */
+
+#ifndef NO_ASN
+/**
+   Convert ECC R,S to signature
+   r       R component of signature
+   s       S component of signature
+   out     DER-encoded ECDSA signature
+   outlen  [in/out] output buffer size, output signature size
+   return  MP_OKAY on success
+*/
+int wc_ecc_rs_to_sig(const char* r, const char* s, byte* out, word32* outlen)
+{
+    int err;
+#ifdef WOLFSSL_SMALL_STACK
+    mp_int* rtmp = NULL;
+    mp_int* stmp = NULL;
+#else
+    mp_int  rtmp[1];
+    mp_int  stmp[1];
+#endif
+
+    if (r == NULL || s == NULL || out == NULL || outlen == NULL)
+        return ECC_BAD_ARG_E;
+
+#ifdef WOLFSSL_SMALL_STACK
+    rtmp = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);
+    if (rtmp == NULL)
+        return MEMORY_E;
+    stmp = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);
+    if (stmp == NULL) {
+        XFREE(rtmp, NULL, DYNAMIC_TYPE_ECC);
+        return MEMORY_E;
+    }
+#endif
+
+    err = mp_init_multi(rtmp, stmp, NULL, NULL, NULL, NULL);
+    if (err != MP_OKAY) {
+    #ifdef WOLFSSL_SMALL_STACK
+        XFREE(stmp, NULL, DYNAMIC_TYPE_ECC);
+        XFREE(rtmp, NULL, DYNAMIC_TYPE_ECC);
+    #endif
+        return err;
+    }
+
+    err = mp_read_radix(rtmp, r, MP_RADIX_HEX);
+    if (err == MP_OKAY)
+        err = mp_read_radix(stmp, s, MP_RADIX_HEX);
+
+    /* convert mp_ints to ECDSA sig, initializes rtmp and stmp internally */
+    if (err == MP_OKAY)
+        err = StoreECC_DSA_Sig(out, outlen, rtmp, stmp);
+
+    if (err == MP_OKAY) {
+        if (mp_iszero(rtmp) == MP_YES || mp_iszero(stmp) == MP_YES)
+            err = MP_ZERO_E;
+    }
+
+    mp_clear(rtmp);
+    mp_clear(stmp);
+#ifdef WOLFSSL_SMALL_STACK
+    XFREE(stmp, NULL, DYNAMIC_TYPE_ECC);
+    XFREE(rtmp, NULL, DYNAMIC_TYPE_ECC);
+#endif
+
+    return err;
+}
+
+/**
+   Convert ECC R,S raw unsigned bin to signature
+   r       R component of signature
+   rSz     R size
+   s       S component of signature
+   sSz     S size
+   out     DER-encoded ECDSA signature
+   outlen  [in/out] output buffer size, output signature size
+   return  MP_OKAY on success
+*/
+int wc_ecc_rs_raw_to_sig(const byte* r, word32 rSz, const byte* s, word32 sSz,
+    byte* out, word32* outlen)
+{
+    int err;
+#ifdef WOLFSSL_SMALL_STACK
+    mp_int* rtmp = NULL;
+    mp_int* stmp = NULL;
+#else
+    mp_int  rtmp[1];
+    mp_int  stmp[1];
+#endif
+
+    if (r == NULL || s == NULL || out == NULL || outlen == NULL)
+        return ECC_BAD_ARG_E;
+
+#ifdef WOLFSSL_SMALL_STACK
+    rtmp = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);
+    if (rtmp == NULL)
+        return MEMORY_E;
+    stmp = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);
+    if (stmp == NULL) {
+        XFREE(rtmp, NULL, DYNAMIC_TYPE_ECC);
+        return MEMORY_E;
+    }
+#endif
+
+    err = mp_init_multi(rtmp, stmp, NULL, NULL, NULL, NULL);
+    if (err != MP_OKAY) {
+    #ifdef WOLFSSL_SMALL_STACK
+        XFREE(stmp, NULL, DYNAMIC_TYPE_ECC);
+        XFREE(rtmp, NULL, DYNAMIC_TYPE_ECC);
+    #endif
+        return err;
+    }
+
+    err = mp_read_unsigned_bin(rtmp, r, rSz);
+    if (err == MP_OKAY)
+        err = mp_read_unsigned_bin(stmp, s, sSz);
+
+    /* convert mp_ints to ECDSA sig, initializes rtmp and stmp internally */
+    if (err == MP_OKAY)
+        err = StoreECC_DSA_Sig(out, outlen, rtmp, stmp);
+
+    if (err == MP_OKAY) {
+        if (mp_iszero(rtmp) == MP_YES || mp_iszero(stmp) == MP_YES)
+            err = MP_ZERO_E;
+    }
+
+    mp_clear(rtmp);
+    mp_clear(stmp);
+#ifdef WOLFSSL_SMALL_STACK
+    XFREE(stmp, NULL, DYNAMIC_TYPE_ECC);
+    XFREE(rtmp, NULL, DYNAMIC_TYPE_ECC);
+#endif
+
+    return err;
+}
+
+/**
+   Convert ECC signature to R,S
+   sig     DER-encoded ECDSA signature
+   sigLen  length of signature in octets
+   r       R component of signature
+   rLen    [in/out] output "r" buffer size, output "r" size
+   s       S component of signature
+   sLen    [in/out] output "s" buffer size, output "s" size
+   return  MP_OKAY on success, negative on error
+*/
+int wc_ecc_sig_to_rs(const byte* sig, word32 sigLen, byte* r, word32* rLen,
+                     byte* s, word32* sLen)
+{
+    int err;
+    int tmp_valid = 0;
+    word32 x = 0;
+#ifdef WOLFSSL_SMALL_STACK
+    mp_int* rtmp = NULL;
+    mp_int* stmp = NULL;
+#else
+    mp_int  rtmp[1];
+    mp_int  stmp[1];
+#endif
+
+    if (sig == NULL || r == NULL || rLen == NULL || s == NULL || sLen == NULL)
+        return ECC_BAD_ARG_E;
+
+#ifdef WOLFSSL_SMALL_STACK
+    rtmp = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);
+    if (rtmp == NULL)
+        return MEMORY_E;
+    stmp = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);
+    if (stmp == NULL) {
+        XFREE(rtmp, NULL, DYNAMIC_TYPE_ECC);
+        return MEMORY_E;
+    }
+#endif
+
+    err = DecodeECC_DSA_Sig(sig, sigLen, rtmp, stmp);
+
+    /* rtmp and stmp are initialized */
+    if (err == MP_OKAY) {
+        tmp_valid = 1;
+
+        /* extract r */
+        x = mp_unsigned_bin_size(rtmp);
+        if (*rLen < x)
+            err = BUFFER_E;
+    }
+    if (err == MP_OKAY) {
+        *rLen = x;
+        err = mp_to_unsigned_bin(rtmp, r);
+    }
+
+    /* extract s */
+    if (err == MP_OKAY) {
+        x = mp_unsigned_bin_size(stmp);
+        if (*sLen < x)
+            err = BUFFER_E;
+
+        if (err == MP_OKAY) {
+            *sLen = x;
+            err = mp_to_unsigned_bin(stmp, s);
+        }
+    }
+
+    if (tmp_valid) {
+        mp_clear(rtmp);
+        mp_clear(stmp);
+    }
+#ifdef WOLFSSL_SMALL_STACK
+    XFREE(stmp, NULL, DYNAMIC_TYPE_ECC);
+    XFREE(rtmp, NULL, DYNAMIC_TYPE_ECC);
+#endif
+
+    return err;
+}
+#endif /* !NO_ASN */
+
+#ifdef HAVE_ECC_KEY_IMPORT
+static int wc_ecc_import_raw_private(ecc_key* key, const char* qx,
+          const char* qy, const char* d, int curve_id, int encType)
+{
+    int err = MP_OKAY;
+#if defined(WOLFSSL_CRYPTOCELL) && !defined(WOLFSSL_ATECC508A)
+    const CRYS_ECPKI_Domain_t* pDomain;
+    CRYS_ECPKI_BUILD_TempData_t tempBuff;
+    byte key_raw[ECC_MAX_CRYPTO_HW_SIZE*2 + 1];
+    word32 keySz = 0;
+#endif
+    /* if d is NULL, only import as public key using Qx,Qy */
+    if (key == NULL || qx == NULL || qy == NULL) {
+        return BAD_FUNC_ARG;
+    }
+
+    /* make sure required variables are reset */
+    wc_ecc_reset(key);
+
+    /* set curve type and index */
+    err = wc_ecc_set_curve(key, 0, curve_id);
+    if (err != 0) {
+        return err;
+    }
+
+    /* init key */
+#ifdef ALT_ECC_SIZE
+    key->pubkey.x = (mp_int*)&key->pubkey.xyz[0];
+    key->pubkey.y = (mp_int*)&key->pubkey.xyz[1];
+    key->pubkey.z = (mp_int*)&key->pubkey.xyz[2];
+    alt_fp_init(key->pubkey.x);
+    alt_fp_init(key->pubkey.y);
+    alt_fp_init(key->pubkey.z);
+    err = mp_init(&key->k);
+#else
+    err = mp_init_multi(&key->k, key->pubkey.x, key->pubkey.y, key->pubkey.z,
+                                                                  NULL, NULL);
+#endif
+    if (err != MP_OKAY)
+        return MEMORY_E;
+
+    /* read Qx */
+    if (err == MP_OKAY) {
+        if (encType == WC_TYPE_HEX_STR)
+            err = mp_read_radix(key->pubkey.x, qx, MP_RADIX_HEX);
+        else
+            err = mp_read_unsigned_bin(key->pubkey.x, (const byte*)qx,
+                key->dp->size);
+    }
+
+    /* read Qy */
+    if (err == MP_OKAY) {
+        if (encType == WC_TYPE_HEX_STR)
+            err = mp_read_radix(key->pubkey.y, qy, MP_RADIX_HEX);
+        else
+            err = mp_read_unsigned_bin(key->pubkey.y, (const byte*)qy,
+                key->dp->size);
+
+    }
+
+    if (err == MP_OKAY)
+        err = mp_set(key->pubkey.z, 1);
+
+#ifdef WOLFSSL_ATECC508A
+    /* For SECP256R1 only save raw public key for hardware */
+    if (err == MP_OKAY && curve_id == ECC_SECP256R1) {
+        word32 keySz = key->dp->size;
+        err = wc_export_int(key->pubkey.x, key->pubkey_raw,
+            &keySz, keySz, WC_TYPE_UNSIGNED_BIN);
+        if (err == MP_OKAY)
+            err = wc_export_int(key->pubkey.y, &key->pubkey_raw[keySz],
+                &keySz, keySz, WC_TYPE_UNSIGNED_BIN);
+    }
+#elif defined(WOLFSSL_CRYPTOCELL)
+    if (err == MP_OKAY) {
+        key_raw[0] = ECC_POINT_UNCOMP;
+        keySz = (word32)key->dp->size;
+        err = wc_export_int(key->pubkey.x, &key_raw[1], &keySz, keySz,
+            WC_TYPE_UNSIGNED_BIN);
+        if (err == MP_OKAY) {
+            err = wc_export_int(key->pubkey.y, &key_raw[1+keySz],
+                &keySz, keySz, WC_TYPE_UNSIGNED_BIN);
+        }
+
+        if (err == MP_OKAY) {
+            pDomain = CRYS_ECPKI_GetEcDomain(cc310_mapCurve(curve_id));
+
+            /* create public key from external key buffer */
+            err = CRYS_ECPKI_BuildPublKeyFullCheck(pDomain,
+                                                   key_raw,
+                                                   keySz*2 + 1,
+                                                   &key->ctx.pubKey,
+                                                   &tempBuff);
+        }
+
+        if (err != SA_SILIB_RET_OK){
+            WOLFSSL_MSG("CRYS_ECPKI_BuildPublKeyFullCheck failed");
+            return err;
+        }
+    }
+
+#endif
+
+    /* import private key */
+    if (err == MP_OKAY) {
+        if (d != NULL && d[0] != '\0') {
+        #ifdef WOLFSSL_ATECC508A
+            /* Hardware doesn't support loading private key */
+            err = NOT_COMPILED_IN;
+
+        #elif defined(WOLFSSL_CRYPTOCELL)
+
+            key->type = ECC_PRIVATEKEY;
+
+            if (encType == WC_TYPE_HEX_STR)
+                err = mp_read_radix(&key->k, d, MP_RADIX_HEX);
+            else
+                err = mp_read_unsigned_bin(&key->k, (const byte*)d,
+                    key->dp->size);
+            if (err == MP_OKAY) {
+                err = wc_export_int(&key->k, &key_raw[0], &keySz, keySz,
+                    WC_TYPE_UNSIGNED_BIN);
+            }
+
+            if (err == MP_OKAY) {
+                /* Create private key from external key buffer*/
+                err = CRYS_ECPKI_BuildPrivKey(pDomain,
+                                              key_raw,
+                                              keySz,
+                                              &key->ctx.privKey);
+
+                if (err != SA_SILIB_RET_OK){
+                    WOLFSSL_MSG("CRYS_ECPKI_BuildPrivKey failed");
+                    return err;
+                }
+            }
+
+        #else
+            key->type = ECC_PRIVATEKEY;
+
+            if (encType == WC_TYPE_HEX_STR)
+                err = mp_read_radix(&key->k, d, MP_RADIX_HEX);
+            else
+                err = mp_read_unsigned_bin(&key->k, (const byte*)d,
+                    key->dp->size);
+        #endif /* WOLFSSL_ATECC508A */
+        } else {
+            key->type = ECC_PUBLICKEY;
+        }
+    }
+
+#ifdef WOLFSSL_VALIDATE_ECC_IMPORT
+    if (err == MP_OKAY)
+        err = wc_ecc_check_key(key);
+#endif
+
+    if (err != MP_OKAY) {
+        mp_clear(key->pubkey.x);
+        mp_clear(key->pubkey.y);
+        mp_clear(key->pubkey.z);
+        mp_clear(&key->k);
+    }
+
+    return err;
+}
+
+/**
+   Import raw ECC key
+   key       The destination ecc_key structure
+   qx        x component of the public key, as ASCII hex string
+   qy        y component of the public key, as ASCII hex string
+   d         private key, as ASCII hex string, optional if importing public
+             key only
+   dp        Custom ecc_set_type
+   return    MP_OKAY on success
+*/
+int wc_ecc_import_raw_ex(ecc_key* key, const char* qx, const char* qy,
+                   const char* d, int curve_id)
+{
+    return wc_ecc_import_raw_private(key, qx, qy, d, curve_id,
+        WC_TYPE_HEX_STR);
+
+}
+
+/* Import x, y and optional private (d) as unsigned binary */
+int wc_ecc_import_unsigned(ecc_key* key, byte* qx, byte* qy,
+                   byte* d, int curve_id)
+{
+    return wc_ecc_import_raw_private(key, (const char*)qx, (const char*)qy,
+        (const char*)d, curve_id, WC_TYPE_UNSIGNED_BIN);
+}
+
+/**
+   Import raw ECC key
+   key       The destination ecc_key structure
+   qx        x component of the public key, as ASCII hex string
+   qy        y component of the public key, as ASCII hex string
+   d         private key, as ASCII hex string, optional if importing public
+             key only
+   curveName ECC curve name, from ecc_sets[]
+   return    MP_OKAY on success
+*/
+int wc_ecc_import_raw(ecc_key* key, const char* qx, const char* qy,
+                   const char* d, const char* curveName)
+{
+    int err, x;
+
+    /* if d is NULL, only import as public key using Qx,Qy */
+    if (key == NULL || qx == NULL || qy == NULL || curveName == NULL) {
+        return BAD_FUNC_ARG;
+    }
+
+    /* set curve type and index */
+    for (x = 0; ecc_sets[x].size != 0; x++) {
+        if (XSTRNCMP(ecc_sets[x].name, curveName,
+                     XSTRLEN(curveName)) == 0) {
+            break;
+        }
+    }
+
+    if (ecc_sets[x].size == 0) {
+        WOLFSSL_MSG("ecc_set curve name not found");
+        err = ASN_PARSE_E;
+    } else {
+        return wc_ecc_import_raw_private(key, qx, qy, d, ecc_sets[x].id,
+            WC_TYPE_HEX_STR);
+    }
+
+    return err;
+}
+#endif /* HAVE_ECC_KEY_IMPORT */
+
+/* key size in octets */
+int wc_ecc_size(ecc_key* key)
+{
+    if (key == NULL)
+        return 0;
+
+    return key->dp->size;
+}
+
+/* maximum signature size based on key size */
+int wc_ecc_sig_size_calc(int sz)
+{
+    int maxSigSz = 0;
+
+    /* calculate based on key bits */
+    /* maximum possible signature header size is 7 bytes plus 2 bytes padding */
+    maxSigSz = (sz * 2) + SIG_HEADER_SZ + ECC_MAX_PAD_SZ;
+
+    /* if total length is less than 128 + SEQ(1)+LEN(1) then subtract 1 */
+    if (maxSigSz < (128 + 2)) {
+        maxSigSz -= 1;
+    }
+
+    return maxSigSz;
+}
+
+/* maximum signature size based on actual key curve */
+int wc_ecc_sig_size(ecc_key* key)
+{
+    int maxSigSz;
+    int orderBits, keySz;
+
+    if (key == NULL || key->dp == NULL)
+        return 0;
+
+    /* the signature r and s will always be less than order */
+    /* if the order MSB (top bit of byte) is set then ASN encoding needs
+        extra byte for r and s, so add 2 */
+    keySz = key->dp->size;
+    orderBits = wc_ecc_get_curve_order_bit_count(key->dp);
+    if (orderBits > keySz * 8) {
+        keySz = (orderBits + 7) / 8;
+    }
+    /* maximum possible signature header size is 7 bytes */
+    maxSigSz = (keySz * 2) + SIG_HEADER_SZ;
+    if ((orderBits % 8) == 0) {
+        /* MSB can be set, so add 2 */
+        maxSigSz += ECC_MAX_PAD_SZ;
+    }
+    /* if total length is less than 128 + SEQ(1)+LEN(1) then subtract 1 */
+    if (maxSigSz < (128 + 2)) {
+        maxSigSz -= 1;
+    }
+
+    return maxSigSz;
+}
+
+
+#ifdef FP_ECC
+
+/* fixed point ECC cache */
+/* number of entries in the cache */
+#ifndef FP_ENTRIES
+    #define FP_ENTRIES 15
+#endif
+
+/* number of bits in LUT */
+#ifndef FP_LUT
+    #define FP_LUT     8U
+#endif
+
+#ifdef ECC_SHAMIR
+    /* Sharmir requires a bigger LUT, TAO */
+    #if (FP_LUT > 12) || (FP_LUT < 4)
+        #error FP_LUT must be between 4 and 12 inclusively
+    #endif
+#else
+    #if (FP_LUT > 12) || (FP_LUT < 2)
+        #error FP_LUT must be between 2 and 12 inclusively
+    #endif
+#endif
+
+
+#ifndef WOLFSSL_SP_MATH
+
+/** Our FP cache */
+typedef struct {
+   ecc_point* g;               /* cached COPY of base point */
+   ecc_point* LUT[1U<<FP_LUT]; /* fixed point lookup */
+   mp_int     mu;              /* copy of the montgomery constant */
+   int        lru_count;       /* amount of times this entry has been used */
+   int        lock;            /* flag to indicate cache eviction */
+                               /* permitted (0) or not (1) */
+} fp_cache_t;
+
+/* if HAVE_THREAD_LS this cache is per thread, no locking needed */
+static THREAD_LS_T fp_cache_t fp_cache[FP_ENTRIES];
+
+#ifndef HAVE_THREAD_LS
+    static volatile int initMutex = 0;  /* prevent multiple mutex inits */
+    static wolfSSL_Mutex ecc_fp_lock;
+#endif /* HAVE_THREAD_LS */
+
+/* simple table to help direct the generation of the LUT */
+static const struct {
+   int ham, terma, termb;
+} lut_orders[] = {
+   { 0, 0, 0 }, { 1, 0, 0 }, { 1, 0, 0 }, { 2, 1, 2 }, { 1, 0, 0 }, { 2, 1, 4 }, { 2, 2, 4 }, { 3, 3, 4 },
+   { 1, 0, 0 }, { 2, 1, 8 }, { 2, 2, 8 }, { 3, 3, 8 }, { 2, 4, 8 }, { 3, 5, 8 }, { 3, 6, 8 }, { 4, 7, 8 },
+   { 1, 0, 0 }, { 2, 1, 16 }, { 2, 2, 16 }, { 3, 3, 16 }, { 2, 4, 16 }, { 3, 5, 16 }, { 3, 6, 16 }, { 4, 7, 16 },
+   { 2, 8, 16 }, { 3, 9, 16 }, { 3, 10, 16 }, { 4, 11, 16 }, { 3, 12, 16 }, { 4, 13, 16 }, { 4, 14, 16 }, { 5, 15, 16 },
+   { 1, 0, 0 }, { 2, 1, 32 }, { 2, 2, 32 }, { 3, 3, 32 }, { 2, 4, 32 }, { 3, 5, 32 }, { 3, 6, 32 }, { 4, 7, 32 },
+   { 2, 8, 32 }, { 3, 9, 32 }, { 3, 10, 32 }, { 4, 11, 32 }, { 3, 12, 32 }, { 4, 13, 32 }, { 4, 14, 32 }, { 5, 15, 32 },
+   { 2, 16, 32 }, { 3, 17, 32 }, { 3, 18, 32 }, { 4, 19, 32 }, { 3, 20, 32 }, { 4, 21, 32 }, { 4, 22, 32 }, { 5, 23, 32 },
+   { 3, 24, 32 }, { 4, 25, 32 }, { 4, 26, 32 }, { 5, 27, 32 }, { 4, 28, 32 }, { 5, 29, 32 }, { 5, 30, 32 }, { 6, 31, 32 },
+#if FP_LUT > 6
+   { 1, 0, 0 }, { 2, 1, 64 }, { 2, 2, 64 }, { 3, 3, 64 }, { 2, 4, 64 }, { 3, 5, 64 }, { 3, 6, 64 }, { 4, 7, 64 },
+   { 2, 8, 64 }, { 3, 9, 64 }, { 3, 10, 64 }, { 4, 11, 64 }, { 3, 12, 64 }, { 4, 13, 64 }, { 4, 14, 64 }, { 5, 15, 64 },
+   { 2, 16, 64 }, { 3, 17, 64 }, { 3, 18, 64 }, { 4, 19, 64 }, { 3, 20, 64 }, { 4, 21, 64 }, { 4, 22, 64 }, { 5, 23, 64 },
+   { 3, 24, 64 }, { 4, 25, 64 }, { 4, 26, 64 }, { 5, 27, 64 }, { 4, 28, 64 }, { 5, 29, 64 }, { 5, 30, 64 }, { 6, 31, 64 },
+   { 2, 32, 64 }, { 3, 33, 64 }, { 3, 34, 64 }, { 4, 35, 64 }, { 3, 36, 64 }, { 4, 37, 64 }, { 4, 38, 64 }, { 5, 39, 64 },
+   { 3, 40, 64 }, { 4, 41, 64 }, { 4, 42, 64 }, { 5, 43, 64 }, { 4, 44, 64 }, { 5, 45, 64 }, { 5, 46, 64 }, { 6, 47, 64 },
+   { 3, 48, 64 }, { 4, 49, 64 }, { 4, 50, 64 }, { 5, 51, 64 }, { 4, 52, 64 }, { 5, 53, 64 }, { 5, 54, 64 }, { 6, 55, 64 },
+   { 4, 56, 64 }, { 5, 57, 64 }, { 5, 58, 64 }, { 6, 59, 64 }, { 5, 60, 64 }, { 6, 61, 64 }, { 6, 62, 64 }, { 7, 63, 64 },
+#if FP_LUT > 7
+   { 1, 0, 0 }, { 2, 1, 128 }, { 2, 2, 128 }, { 3, 3, 128 }, { 2, 4, 128 }, { 3, 5, 128 }, { 3, 6, 128 }, { 4, 7, 128 },
+   { 2, 8, 128 }, { 3, 9, 128 }, { 3, 10, 128 }, { 4, 11, 128 }, { 3, 12, 128 }, { 4, 13, 128 }, { 4, 14, 128 }, { 5, 15, 128 },
+   { 2, 16, 128 }, { 3, 17, 128 }, { 3, 18, 128 }, { 4, 19, 128 }, { 3, 20, 128 }, { 4, 21, 128 }, { 4, 22, 128 }, { 5, 23, 128 },
+   { 3, 24, 128 }, { 4, 25, 128 }, { 4, 26, 128 }, { 5, 27, 128 }, { 4, 28, 128 }, { 5, 29, 128 }, { 5, 30, 128 }, { 6, 31, 128 },
+   { 2, 32, 128 }, { 3, 33, 128 }, { 3, 34, 128 }, { 4, 35, 128 }, { 3, 36, 128 }, { 4, 37, 128 }, { 4, 38, 128 }, { 5, 39, 128 },
+   { 3, 40, 128 }, { 4, 41, 128 }, { 4, 42, 128 }, { 5, 43, 128 }, { 4, 44, 128 }, { 5, 45, 128 }, { 5, 46, 128 }, { 6, 47, 128 },
+   { 3, 48, 128 }, { 4, 49, 128 }, { 4, 50, 128 }, { 5, 51, 128 }, { 4, 52, 128 }, { 5, 53, 128 }, { 5, 54, 128 }, { 6, 55, 128 },
+   { 4, 56, 128 }, { 5, 57, 128 }, { 5, 58, 128 }, { 6, 59, 128 }, { 5, 60, 128 }, { 6, 61, 128 }, { 6, 62, 128 }, { 7, 63, 128 },
+   { 2, 64, 128 }, { 3, 65, 128 }, { 3, 66, 128 }, { 4, 67, 128 }, { 3, 68, 128 }, { 4, 69, 128 }, { 4, 70, 128 }, { 5, 71, 128 },
+   { 3, 72, 128 }, { 4, 73, 128 }, { 4, 74, 128 }, { 5, 75, 128 }, { 4, 76, 128 }, { 5, 77, 128 }, { 5, 78, 128 }, { 6, 79, 128 },
+   { 3, 80, 128 }, { 4, 81, 128 }, { 4, 82, 128 }, { 5, 83, 128 }, { 4, 84, 128 }, { 5, 85, 128 }, { 5, 86, 128 }, { 6, 87, 128 },
+   { 4, 88, 128 }, { 5, 89, 128 }, { 5, 90, 128 }, { 6, 91, 128 }, { 5, 92, 128 }, { 6, 93, 128 }, { 6, 94, 128 }, { 7, 95, 128 },
+   { 3, 96, 128 }, { 4, 97, 128 }, { 4, 98, 128 }, { 5, 99, 128 }, { 4, 100, 128 }, { 5, 101, 128 }, { 5, 102, 128 }, { 6, 103, 128 },
+   { 4, 104, 128 }, { 5, 105, 128 }, { 5, 106, 128 }, { 6, 107, 128 }, { 5, 108, 128 }, { 6, 109, 128 }, { 6, 110, 128 }, { 7, 111, 128 },
+   { 4, 112, 128 }, { 5, 113, 128 }, { 5, 114, 128 }, { 6, 115, 128 }, { 5, 116, 128 }, { 6, 117, 128 }, { 6, 118, 128 }, { 7, 119, 128 },
+   { 5, 120, 128 }, { 6, 121, 128 }, { 6, 122, 128 }, { 7, 123, 128 }, { 6, 124, 128 }, { 7, 125, 128 }, { 7, 126, 128 }, { 8, 127, 128 },
+#if FP_LUT > 8
+   { 1, 0, 0 }, { 2, 1, 256 }, { 2, 2, 256 }, { 3, 3, 256 }, { 2, 4, 256 }, { 3, 5, 256 }, { 3, 6, 256 }, { 4, 7, 256 },
+   { 2, 8, 256 }, { 3, 9, 256 }, { 3, 10, 256 }, { 4, 11, 256 }, { 3, 12, 256 }, { 4, 13, 256 }, { 4, 14, 256 }, { 5, 15, 256 },
+   { 2, 16, 256 }, { 3, 17, 256 }, { 3, 18, 256 }, { 4, 19, 256 }, { 3, 20, 256 }, { 4, 21, 256 }, { 4, 22, 256 }, { 5, 23, 256 },
+   { 3, 24, 256 }, { 4, 25, 256 }, { 4, 26, 256 }, { 5, 27, 256 }, { 4, 28, 256 }, { 5, 29, 256 }, { 5, 30, 256 }, { 6, 31, 256 },
+   { 2, 32, 256 }, { 3, 33, 256 }, { 3, 34, 256 }, { 4, 35, 256 }, { 3, 36, 256 }, { 4, 37, 256 }, { 4, 38, 256 }, { 5, 39, 256 },
+   { 3, 40, 256 }, { 4, 41, 256 }, { 4, 42, 256 }, { 5, 43, 256 }, { 4, 44, 256 }, { 5, 45, 256 }, { 5, 46, 256 }, { 6, 47, 256 },
+   { 3, 48, 256 }, { 4, 49, 256 }, { 4, 50, 256 }, { 5, 51, 256 }, { 4, 52, 256 }, { 5, 53, 256 }, { 5, 54, 256 }, { 6, 55, 256 },
+   { 4, 56, 256 }, { 5, 57, 256 }, { 5, 58, 256 }, { 6, 59, 256 }, { 5, 60, 256 }, { 6, 61, 256 }, { 6, 62, 256 }, { 7, 63, 256 },
+   { 2, 64, 256 }, { 3, 65, 256 }, { 3, 66, 256 }, { 4, 67, 256 }, { 3, 68, 256 }, { 4, 69, 256 }, { 4, 70, 256 }, { 5, 71, 256 },
+   { 3, 72, 256 }, { 4, 73, 256 }, { 4, 74, 256 }, { 5, 75, 256 }, { 4, 76, 256 }, { 5, 77, 256 }, { 5, 78, 256 }, { 6, 79, 256 },
+   { 3, 80, 256 }, { 4, 81, 256 }, { 4, 82, 256 }, { 5, 83, 256 }, { 4, 84, 256 }, { 5, 85, 256 }, { 5, 86, 256 }, { 6, 87, 256 },
+   { 4, 88, 256 }, { 5, 89, 256 }, { 5, 90, 256 }, { 6, 91, 256 }, { 5, 92, 256 }, { 6, 93, 256 }, { 6, 94, 256 }, { 7, 95, 256 },
+   { 3, 96, 256 }, { 4, 97, 256 }, { 4, 98, 256 }, { 5, 99, 256 }, { 4, 100, 256 }, { 5, 101, 256 }, { 5, 102, 256 }, { 6, 103, 256 },
+   { 4, 104, 256 }, { 5, 105, 256 }, { 5, 106, 256 }, { 6, 107, 256 }, { 5, 108, 256 }, { 6, 109, 256 }, { 6, 110, 256 }, { 7, 111, 256 },
+   { 4, 112, 256 }, { 5, 113, 256 }, { 5, 114, 256 }, { 6, 115, 256 }, { 5, 116, 256 }, { 6, 117, 256 }, { 6, 118, 256 }, { 7, 119, 256 },
+   { 5, 120, 256 }, { 6, 121, 256 }, { 6, 122, 256 }, { 7, 123, 256 }, { 6, 124, 256 }, { 7, 125, 256 }, { 7, 126, 256 }, { 8, 127, 256 },
+   { 2, 128, 256 }, { 3, 129, 256 }, { 3, 130, 256 }, { 4, 131, 256 }, { 3, 132, 256 }, { 4, 133, 256 }, { 4, 134, 256 }, { 5, 135, 256 },
+   { 3, 136, 256 }, { 4, 137, 256 }, { 4, 138, 256 }, { 5, 139, 256 }, { 4, 140, 256 }, { 5, 141, 256 }, { 5, 142, 256 }, { 6, 143, 256 },
+   { 3, 144, 256 }, { 4, 145, 256 }, { 4, 146, 256 }, { 5, 147, 256 }, { 4, 148, 256 }, { 5, 149, 256 }, { 5, 150, 256 }, { 6, 151, 256 },
+   { 4, 152, 256 }, { 5, 153, 256 }, { 5, 154, 256 }, { 6, 155, 256 }, { 5, 156, 256 }, { 6, 157, 256 }, { 6, 158, 256 }, { 7, 159, 256 },
+   { 3, 160, 256 }, { 4, 161, 256 }, { 4, 162, 256 }, { 5, 163, 256 }, { 4, 164, 256 }, { 5, 165, 256 }, { 5, 166, 256 }, { 6, 167, 256 },
+   { 4, 168, 256 }, { 5, 169, 256 }, { 5, 170, 256 }, { 6, 171, 256 }, { 5, 172, 256 }, { 6, 173, 256 }, { 6, 174, 256 }, { 7, 175, 256 },
+   { 4, 176, 256 }, { 5, 177, 256 }, { 5, 178, 256 }, { 6, 179, 256 }, { 5, 180, 256 }, { 6, 181, 256 }, { 6, 182, 256 }, { 7, 183, 256 },
+   { 5, 184, 256 }, { 6, 185, 256 }, { 6, 186, 256 }, { 7, 187, 256 }, { 6, 188, 256 }, { 7, 189, 256 }, { 7, 190, 256 }, { 8, 191, 256 },
+   { 3, 192, 256 }, { 4, 193, 256 }, { 4, 194, 256 }, { 5, 195, 256 }, { 4, 196, 256 }, { 5, 197, 256 }, { 5, 198, 256 }, { 6, 199, 256 },
+   { 4, 200, 256 }, { 5, 201, 256 }, { 5, 202, 256 }, { 6, 203, 256 }, { 5, 204, 256 }, { 6, 205, 256 }, { 6, 206, 256 }, { 7, 207, 256 },
+   { 4, 208, 256 }, { 5, 209, 256 }, { 5, 210, 256 }, { 6, 211, 256 }, { 5, 212, 256 }, { 6, 213, 256 }, { 6, 214, 256 }, { 7, 215, 256 },
+   { 5, 216, 256 }, { 6, 217, 256 }, { 6, 218, 256 }, { 7, 219, 256 }, { 6, 220, 256 }, { 7, 221, 256 }, { 7, 222, 256 }, { 8, 223, 256 },
+   { 4, 224, 256 }, { 5, 225, 256 }, { 5, 226, 256 }, { 6, 227, 256 }, { 5, 228, 256 }, { 6, 229, 256 }, { 6, 230, 256 }, { 7, 231, 256 },
+   { 5, 232, 256 }, { 6, 233, 256 }, { 6, 234, 256 }, { 7, 235, 256 }, { 6, 236, 256 }, { 7, 237, 256 }, { 7, 238, 256 }, { 8, 239, 256 },
+   { 5, 240, 256 }, { 6, 241, 256 }, { 6, 242, 256 }, { 7, 243, 256 }, { 6, 244, 256 }, { 7, 245, 256 }, { 7, 246, 256 }, { 8, 247, 256 },
+   { 6, 248, 256 }, { 7, 249, 256 }, { 7, 250, 256 }, { 8, 251, 256 }, { 7, 252, 256 }, { 8, 253, 256 }, { 8, 254, 256 }, { 9, 255, 256 },
+#if FP_LUT > 9
+   { 1, 0, 0 }, { 2, 1, 512 }, { 2, 2, 512 }, { 3, 3, 512 }, { 2, 4, 512 }, { 3, 5, 512 }, { 3, 6, 512 }, { 4, 7, 512 },
+   { 2, 8, 512 }, { 3, 9, 512 }, { 3, 10, 512 }, { 4, 11, 512 }, { 3, 12, 512 }, { 4, 13, 512 }, { 4, 14, 512 }, { 5, 15, 512 },
+   { 2, 16, 512 }, { 3, 17, 512 }, { 3, 18, 512 }, { 4, 19, 512 }, { 3, 20, 512 }, { 4, 21, 512 }, { 4, 22, 512 }, { 5, 23, 512 },
+   { 3, 24, 512 }, { 4, 25, 512 }, { 4, 26, 512 }, { 5, 27, 512 }, { 4, 28, 512 }, { 5, 29, 512 }, { 5, 30, 512 }, { 6, 31, 512 },
+   { 2, 32, 512 }, { 3, 33, 512 }, { 3, 34, 512 }, { 4, 35, 512 }, { 3, 36, 512 }, { 4, 37, 512 }, { 4, 38, 512 }, { 5, 39, 512 },
+   { 3, 40, 512 }, { 4, 41, 512 }, { 4, 42, 512 }, { 5, 43, 512 }, { 4, 44, 512 }, { 5, 45, 512 }, { 5, 46, 512 }, { 6, 47, 512 },
+   { 3, 48, 512 }, { 4, 49, 512 }, { 4, 50, 512 }, { 5, 51, 512 }, { 4, 52, 512 }, { 5, 53, 512 }, { 5, 54, 512 }, { 6, 55, 512 },
+   { 4, 56, 512 }, { 5, 57, 512 }, { 5, 58, 512 }, { 6, 59, 512 }, { 5, 60, 512 }, { 6, 61, 512 }, { 6, 62, 512 }, { 7, 63, 512 },
+   { 2, 64, 512 }, { 3, 65, 512 }, { 3, 66, 512 }, { 4, 67, 512 }, { 3, 68, 512 }, { 4, 69, 512 }, { 4, 70, 512 }, { 5, 71, 512 },
+   { 3, 72, 512 }, { 4, 73, 512 }, { 4, 74, 512 }, { 5, 75, 512 }, { 4, 76, 512 }, { 5, 77, 512 }, { 5, 78, 512 }, { 6, 79, 512 },
+   { 3, 80, 512 }, { 4, 81, 512 }, { 4, 82, 512 }, { 5, 83, 512 }, { 4, 84, 512 }, { 5, 85, 512 }, { 5, 86, 512 }, { 6, 87, 512 },
+   { 4, 88, 512 }, { 5, 89, 512 }, { 5, 90, 512 }, { 6, 91, 512 }, { 5, 92, 512 }, { 6, 93, 512 }, { 6, 94, 512 }, { 7, 95, 512 },
+   { 3, 96, 512 }, { 4, 97, 512 }, { 4, 98, 512 }, { 5, 99, 512 }, { 4, 100, 512 }, { 5, 101, 512 }, { 5, 102, 512 }, { 6, 103, 512 },
+   { 4, 104, 512 }, { 5, 105, 512 }, { 5, 106, 512 }, { 6, 107, 512 }, { 5, 108, 512 }, { 6, 109, 512 }, { 6, 110, 512 }, { 7, 111, 512 },
+   { 4, 112, 512 }, { 5, 113, 512 }, { 5, 114, 512 }, { 6, 115, 512 }, { 5, 116, 512 }, { 6, 117, 512 }, { 6, 118, 512 }, { 7, 119, 512 },
+   { 5, 120, 512 }, { 6, 121, 512 }, { 6, 122, 512 }, { 7, 123, 512 }, { 6, 124, 512 }, { 7, 125, 512 }, { 7, 126, 512 }, { 8, 127, 512 },
+   { 2, 128, 512 }, { 3, 129, 512 }, { 3, 130, 512 }, { 4, 131, 512 }, { 3, 132, 512 }, { 4, 133, 512 }, { 4, 134, 512 }, { 5, 135, 512 },
+   { 3, 136, 512 }, { 4, 137, 512 }, { 4, 138, 512 }, { 5, 139, 512 }, { 4, 140, 512 }, { 5, 141, 512 }, { 5, 142, 512 }, { 6, 143, 512 },
+   { 3, 144, 512 }, { 4, 145, 512 }, { 4, 146, 512 }, { 5, 147, 512 }, { 4, 148, 512 }, { 5, 149, 512 }, { 5, 150, 512 }, { 6, 151, 512 },
+   { 4, 152, 512 }, { 5, 153, 512 }, { 5, 154, 512 }, { 6, 155, 512 }, { 5, 156, 512 }, { 6, 157, 512 }, { 6, 158, 512 }, { 7, 159, 512 },
+   { 3, 160, 512 }, { 4, 161, 512 }, { 4, 162, 512 }, { 5, 163, 512 }, { 4, 164, 512 }, { 5, 165, 512 }, { 5, 166, 512 }, { 6, 167, 512 },
+   { 4, 168, 512 }, { 5, 169, 512 }, { 5, 170, 512 }, { 6, 171, 512 }, { 5, 172, 512 }, { 6, 173, 512 }, { 6, 174, 512 }, { 7, 175, 512 },
+   { 4, 176, 512 }, { 5, 177, 512 }, { 5, 178, 512 }, { 6, 179, 512 }, { 5, 180, 512 }, { 6, 181, 512 }, { 6, 182, 512 }, { 7, 183, 512 },
+   { 5, 184, 512 }, { 6, 185, 512 }, { 6, 186, 512 }, { 7, 187, 512 }, { 6, 188, 512 }, { 7, 189, 512 }, { 7, 190, 512 }, { 8, 191, 512 },
+   { 3, 192, 512 }, { 4, 193, 512 }, { 4, 194, 512 }, { 5, 195, 512 }, { 4, 196, 512 }, { 5, 197, 512 }, { 5, 198, 512 }, { 6, 199, 512 },
+   { 4, 200, 512 }, { 5, 201, 512 }, { 5, 202, 512 }, { 6, 203, 512 }, { 5, 204, 512 }, { 6, 205, 512 }, { 6, 206, 512 }, { 7, 207, 512 },
+   { 4, 208, 512 }, { 5, 209, 512 }, { 5, 210, 512 }, { 6, 211, 512 }, { 5, 212, 512 }, { 6, 213, 512 }, { 6, 214, 512 }, { 7, 215, 512 },
+   { 5, 216, 512 }, { 6, 217, 512 }, { 6, 218, 512 }, { 7, 219, 512 }, { 6, 220, 512 }, { 7, 221, 512 }, { 7, 222, 512 }, { 8, 223, 512 },
+   { 4, 224, 512 }, { 5, 225, 512 }, { 5, 226, 512 }, { 6, 227, 512 }, { 5, 228, 512 }, { 6, 229, 512 }, { 6, 230, 512 }, { 7, 231, 512 },
+   { 5, 232, 512 }, { 6, 233, 512 }, { 6, 234, 512 }, { 7, 235, 512 }, { 6, 236, 512 }, { 7, 237, 512 }, { 7, 238, 512 }, { 8, 239, 512 },
+   { 5, 240, 512 }, { 6, 241, 512 }, { 6, 242, 512 }, { 7, 243, 512 }, { 6, 244, 512 }, { 7, 245, 512 }, { 7, 246, 512 }, { 8, 247, 512 },
+   { 6, 248, 512 }, { 7, 249, 512 }, { 7, 250, 512 }, { 8, 251, 512 }, { 7, 252, 512 }, { 8, 253, 512 }, { 8, 254, 512 }, { 9, 255, 512 },
+   { 2, 256, 512 }, { 3, 257, 512 }, { 3, 258, 512 }, { 4, 259, 512 }, { 3, 260, 512 }, { 4, 261, 512 }, { 4, 262, 512 }, { 5, 263, 512 },
+   { 3, 264, 512 }, { 4, 265, 512 }, { 4, 266, 512 }, { 5, 267, 512 }, { 4, 268, 512 }, { 5, 269, 512 }, { 5, 270, 512 }, { 6, 271, 512 },
+   { 3, 272, 512 }, { 4, 273, 512 }, { 4, 274, 512 }, { 5, 275, 512 }, { 4, 276, 512 }, { 5, 277, 512 }, { 5, 278, 512 }, { 6, 279, 512 },
+   { 4, 280, 512 }, { 5, 281, 512 }, { 5, 282, 512 }, { 6, 283, 512 }, { 5, 284, 512 }, { 6, 285, 512 }, { 6, 286, 512 }, { 7, 287, 512 },
+   { 3, 288, 512 }, { 4, 289, 512 }, { 4, 290, 512 }, { 5, 291, 512 }, { 4, 292, 512 }, { 5, 293, 512 }, { 5, 294, 512 }, { 6, 295, 512 },
+   { 4, 296, 512 }, { 5, 297, 512 }, { 5, 298, 512 }, { 6, 299, 512 }, { 5, 300, 512 }, { 6, 301, 512 }, { 6, 302, 512 }, { 7, 303, 512 },
+   { 4, 304, 512 }, { 5, 305, 512 }, { 5, 306, 512 }, { 6, 307, 512 }, { 5, 308, 512 }, { 6, 309, 512 }, { 6, 310, 512 }, { 7, 311, 512 },
+   { 5, 312, 512 }, { 6, 313, 512 }, { 6, 314, 512 }, { 7, 315, 512 }, { 6, 316, 512 }, { 7, 317, 512 }, { 7, 318, 512 }, { 8, 319, 512 },
+   { 3, 320, 512 }, { 4, 321, 512 }, { 4, 322, 512 }, { 5, 323, 512 }, { 4, 324, 512 }, { 5, 325, 512 }, { 5, 326, 512 }, { 6, 327, 512 },
+   { 4, 328, 512 }, { 5, 329, 512 }, { 5, 330, 512 }, { 6, 331, 512 }, { 5, 332, 512 }, { 6, 333, 512 }, { 6, 334, 512 }, { 7, 335, 512 },
+   { 4, 336, 512 }, { 5, 337, 512 }, { 5, 338, 512 }, { 6, 339, 512 }, { 5, 340, 512 }, { 6, 341, 512 }, { 6, 342, 512 }, { 7, 343, 512 },
+   { 5, 344, 512 }, { 6, 345, 512 }, { 6, 346, 512 }, { 7, 347, 512 }, { 6, 348, 512 }, { 7, 349, 512 }, { 7, 350, 512 }, { 8, 351, 512 },
+   { 4, 352, 512 }, { 5, 353, 512 }, { 5, 354, 512 }, { 6, 355, 512 }, { 5, 356, 512 }, { 6, 357, 512 }, { 6, 358, 512 }, { 7, 359, 512 },
+   { 5, 360, 512 }, { 6, 361, 512 }, { 6, 362, 512 }, { 7, 363, 512 }, { 6, 364, 512 }, { 7, 365, 512 }, { 7, 366, 512 }, { 8, 367, 512 },
+   { 5, 368, 512 }, { 6, 369, 512 }, { 6, 370, 512 }, { 7, 371, 512 }, { 6, 372, 512 }, { 7, 373, 512 }, { 7, 374, 512 }, { 8, 375, 512 },
+   { 6, 376, 512 }, { 7, 377, 512 }, { 7, 378, 512 }, { 8, 379, 512 }, { 7, 380, 512 }, { 8, 381, 512 }, { 8, 382, 512 }, { 9, 383, 512 },
+   { 3, 384, 512 }, { 4, 385, 512 }, { 4, 386, 512 }, { 5, 387, 512 }, { 4, 388, 512 }, { 5, 389, 512 }, { 5, 390, 512 }, { 6, 391, 512 },
+   { 4, 392, 512 }, { 5, 393, 512 }, { 5, 394, 512 }, { 6, 395, 512 }, { 5, 396, 512 }, { 6, 397, 512 }, { 6, 398, 512 }, { 7, 399, 512 },
+   { 4, 400, 512 }, { 5, 401, 512 }, { 5, 402, 512 }, { 6, 403, 512 }, { 5, 404, 512 }, { 6, 405, 512 }, { 6, 406, 512 }, { 7, 407, 512 },
+   { 5, 408, 512 }, { 6, 409, 512 }, { 6, 410, 512 }, { 7, 411, 512 }, { 6, 412, 512 }, { 7, 413, 512 }, { 7, 414, 512 }, { 8, 415, 512 },
+   { 4, 416, 512 }, { 5, 417, 512 }, { 5, 418, 512 }, { 6, 419, 512 }, { 5, 420, 512 }, { 6, 421, 512 }, { 6, 422, 512 }, { 7, 423, 512 },
+   { 5, 424, 512 }, { 6, 425, 512 }, { 6, 426, 512 }, { 7, 427, 512 }, { 6, 428, 512 }, { 7, 429, 512 }, { 7, 430, 512 }, { 8, 431, 512 },
+   { 5, 432, 512 }, { 6, 433, 512 }, { 6, 434, 512 }, { 7, 435, 512 }, { 6, 436, 512 }, { 7, 437, 512 }, { 7, 438, 512 }, { 8, 439, 512 },
+   { 6, 440, 512 }, { 7, 441, 512 }, { 7, 442, 512 }, { 8, 443, 512 }, { 7, 444, 512 }, { 8, 445, 512 }, { 8, 446, 512 }, { 9, 447, 512 },
+   { 4, 448, 512 }, { 5, 449, 512 }, { 5, 450, 512 }, { 6, 451, 512 }, { 5, 452, 512 }, { 6, 453, 512 }, { 6, 454, 512 }, { 7, 455, 512 },
+   { 5, 456, 512 }, { 6, 457, 512 }, { 6, 458, 512 }, { 7, 459, 512 }, { 6, 460, 512 }, { 7, 461, 512 }, { 7, 462, 512 }, { 8, 463, 512 },
+   { 5, 464, 512 }, { 6, 465, 512 }, { 6, 466, 512 }, { 7, 467, 512 }, { 6, 468, 512 }, { 7, 469, 512 }, { 7, 470, 512 }, { 8, 471, 512 },
+   { 6, 472, 512 }, { 7, 473, 512 }, { 7, 474, 512 }, { 8, 475, 512 }, { 7, 476, 512 }, { 8, 477, 512 }, { 8, 478, 512 }, { 9, 479, 512 },
+   { 5, 480, 512 }, { 6, 481, 512 }, { 6, 482, 512 }, { 7, 483, 512 }, { 6, 484, 512 }, { 7, 485, 512 }, { 7, 486, 512 }, { 8, 487, 512 },
+   { 6, 488, 512 }, { 7, 489, 512 }, { 7, 490, 512 }, { 8, 491, 512 }, { 7, 492, 512 }, { 8, 493, 512 }, { 8, 494, 512 }, { 9, 495, 512 },
+   { 6, 496, 512 }, { 7, 497, 512 }, { 7, 498, 512 }, { 8, 499, 512 }, { 7, 500, 512 }, { 8, 501, 512 }, { 8, 502, 512 }, { 9, 503, 512 },
+   { 7, 504, 512 }, { 8, 505, 512 }, { 8, 506, 512 }, { 9, 507, 512 }, { 8, 508, 512 }, { 9, 509, 512 }, { 9, 510, 512 }, { 10, 511, 512 },
+#if FP_LUT > 10
+   { 1, 0, 0 }, { 2, 1, 1024 }, { 2, 2, 1024 }, { 3, 3, 1024 }, { 2, 4, 1024 }, { 3, 5, 1024 }, { 3, 6, 1024 }, { 4, 7, 1024 },
+   { 2, 8, 1024 }, { 3, 9, 1024 }, { 3, 10, 1024 }, { 4, 11, 1024 }, { 3, 12, 1024 }, { 4, 13, 1024 }, { 4, 14, 1024 }, { 5, 15, 1024 },
+   { 2, 16, 1024 }, { 3, 17, 1024 }, { 3, 18, 1024 }, { 4, 19, 1024 }, { 3, 20, 1024 }, { 4, 21, 1024 }, { 4, 22, 1024 }, { 5, 23, 1024 },
+   { 3, 24, 1024 }, { 4, 25, 1024 }, { 4, 26, 1024 }, { 5, 27, 1024 }, { 4, 28, 1024 }, { 5, 29, 1024 }, { 5, 30, 1024 }, { 6, 31, 1024 },
+   { 2, 32, 1024 }, { 3, 33, 1024 }, { 3, 34, 1024 }, { 4, 35, 1024 }, { 3, 36, 1024 }, { 4, 37, 1024 }, { 4, 38, 1024 }, { 5, 39, 1024 },
+   { 3, 40, 1024 }, { 4, 41, 1024 }, { 4, 42, 1024 }, { 5, 43, 1024 }, { 4, 44, 1024 }, { 5, 45, 1024 }, { 5, 46, 1024 }, { 6, 47, 1024 },
+   { 3, 48, 1024 }, { 4, 49, 1024 }, { 4, 50, 1024 }, { 5, 51, 1024 }, { 4, 52, 1024 }, { 5, 53, 1024 }, { 5, 54, 1024 }, { 6, 55, 1024 },
+   { 4, 56, 1024 }, { 5, 57, 1024 }, { 5, 58, 1024 }, { 6, 59, 1024 }, { 5, 60, 1024 }, { 6, 61, 1024 }, { 6, 62, 1024 }, { 7, 63, 1024 },
+   { 2, 64, 1024 }, { 3, 65, 1024 }, { 3, 66, 1024 }, { 4, 67, 1024 }, { 3, 68, 1024 }, { 4, 69, 1024 }, { 4, 70, 1024 }, { 5, 71, 1024 },
+   { 3, 72, 1024 }, { 4, 73, 1024 }, { 4, 74, 1024 }, { 5, 75, 1024 }, { 4, 76, 1024 }, { 5, 77, 1024 }, { 5, 78, 1024 }, { 6, 79, 1024 },
+   { 3, 80, 1024 }, { 4, 81, 1024 }, { 4, 82, 1024 }, { 5, 83, 1024 }, { 4, 84, 1024 }, { 5, 85, 1024 }, { 5, 86, 1024 }, { 6, 87, 1024 },
+   { 4, 88, 1024 }, { 5, 89, 1024 }, { 5, 90, 1024 }, { 6, 91, 1024 }, { 5, 92, 1024 }, { 6, 93, 1024 }, { 6, 94, 1024 }, { 7, 95, 1024 },
+   { 3, 96, 1024 }, { 4, 97, 1024 }, { 4, 98, 1024 }, { 5, 99, 1024 }, { 4, 100, 1024 }, { 5, 101, 1024 }, { 5, 102, 1024 }, { 6, 103, 1024 },
+   { 4, 104, 1024 }, { 5, 105, 1024 }, { 5, 106, 1024 }, { 6, 107, 1024 }, { 5, 108, 1024 }, { 6, 109, 1024 }, { 6, 110, 1024 }, { 7, 111, 1024 },
+   { 4, 112, 1024 }, { 5, 113, 1024 }, { 5, 114, 1024 }, { 6, 115, 1024 }, { 5, 116, 1024 }, { 6, 117, 1024 }, { 6, 118, 1024 }, { 7, 119, 1024 },
+   { 5, 120, 1024 }, { 6, 121, 1024 }, { 6, 122, 1024 }, { 7, 123, 1024 }, { 6, 124, 1024 }, { 7, 125, 1024 }, { 7, 126, 1024 }, { 8, 127, 1024 },
+   { 2, 128, 1024 }, { 3, 129, 1024 }, { 3, 130, 1024 }, { 4, 131, 1024 }, { 3, 132, 1024 }, { 4, 133, 1024 }, { 4, 134, 1024 }, { 5, 135, 1024 },
+   { 3, 136, 1024 }, { 4, 137, 1024 }, { 4, 138, 1024 }, { 5, 139, 1024 }, { 4, 140, 1024 }, { 5, 141, 1024 }, { 5, 142, 1024 }, { 6, 143, 1024 },
+   { 3, 144, 1024 }, { 4, 145, 1024 }, { 4, 146, 1024 }, { 5, 147, 1024 }, { 4, 148, 1024 }, { 5, 149, 1024 }, { 5, 150, 1024 }, { 6, 151, 1024 },
+   { 4, 152, 1024 }, { 5, 153, 1024 }, { 5, 154, 1024 }, { 6, 155, 1024 }, { 5, 156, 1024 }, { 6, 157, 1024 }, { 6, 158, 1024 }, { 7, 159, 1024 },
+   { 3, 160, 1024 }, { 4, 161, 1024 }, { 4, 162, 1024 }, { 5, 163, 1024 }, { 4, 164, 1024 }, { 5, 165, 1024 }, { 5, 166, 1024 }, { 6, 167, 1024 },
+   { 4, 168, 1024 }, { 5, 169, 1024 }, { 5, 170, 1024 }, { 6, 171, 1024 }, { 5, 172, 1024 }, { 6, 173, 1024 }, { 6, 174, 1024 }, { 7, 175, 1024 },
+   { 4, 176, 1024 }, { 5, 177, 1024 }, { 5, 178, 1024 }, { 6, 179, 1024 }, { 5, 180, 1024 }, { 6, 181, 1024 }, { 6, 182, 1024 }, { 7, 183, 1024 },
+   { 5, 184, 1024 }, { 6, 185, 1024 }, { 6, 186, 1024 }, { 7, 187, 1024 }, { 6, 188, 1024 }, { 7, 189, 1024 }, { 7, 190, 1024 }, { 8, 191, 1024 },
+   { 3, 192, 1024 }, { 4, 193, 1024 }, { 4, 194, 1024 }, { 5, 195, 1024 }, { 4, 196, 1024 }, { 5, 197, 1024 }, { 5, 198, 1024 }, { 6, 199, 1024 },
+   { 4, 200, 1024 }, { 5, 201, 1024 }, { 5, 202, 1024 }, { 6, 203, 1024 }, { 5, 204, 1024 }, { 6, 205, 1024 }, { 6, 206, 1024 }, { 7, 207, 1024 },
+   { 4, 208, 1024 }, { 5, 209, 1024 }, { 5, 210, 1024 }, { 6, 211, 1024 }, { 5, 212, 1024 }, { 6, 213, 1024 }, { 6, 214, 1024 }, { 7, 215, 1024 },
+   { 5, 216, 1024 }, { 6, 217, 1024 }, { 6, 218, 1024 }, { 7, 219, 1024 }, { 6, 220, 1024 }, { 7, 221, 1024 }, { 7, 222, 1024 }, { 8, 223, 1024 },
+   { 4, 224, 1024 }, { 5, 225, 1024 }, { 5, 226, 1024 }, { 6, 227, 1024 }, { 5, 228, 1024 }, { 6, 229, 1024 }, { 6, 230, 1024 }, { 7, 231, 1024 },
+   { 5, 232, 1024 }, { 6, 233, 1024 }, { 6, 234, 1024 }, { 7, 235, 1024 }, { 6, 236, 1024 }, { 7, 237, 1024 }, { 7, 238, 1024 }, { 8, 239, 1024 },
+   { 5, 240, 1024 }, { 6, 241, 1024 }, { 6, 242, 1024 }, { 7, 243, 1024 }, { 6, 244, 1024 }, { 7, 245, 1024 }, { 7, 246, 1024 }, { 8, 247, 1024 },
+   { 6, 248, 1024 }, { 7, 249, 1024 }, { 7, 250, 1024 }, { 8, 251, 1024 }, { 7, 252, 1024 }, { 8, 253, 1024 }, { 8, 254, 1024 }, { 9, 255, 1024 },
+   { 2, 256, 1024 }, { 3, 257, 1024 }, { 3, 258, 1024 }, { 4, 259, 1024 }, { 3, 260, 1024 }, { 4, 261, 1024 }, { 4, 262, 1024 }, { 5, 263, 1024 },
+   { 3, 264, 1024 }, { 4, 265, 1024 }, { 4, 266, 1024 }, { 5, 267, 1024 }, { 4, 268, 1024 }, { 5, 269, 1024 }, { 5, 270, 1024 }, { 6, 271, 1024 },
+   { 3, 272, 1024 }, { 4, 273, 1024 }, { 4, 274, 1024 }, { 5, 275, 1024 }, { 4, 276, 1024 }, { 5, 277, 1024 }, { 5, 278, 1024 }, { 6, 279, 1024 },
+   { 4, 280, 1024 }, { 5, 281, 1024 }, { 5, 282, 1024 }, { 6, 283, 1024 }, { 5, 284, 1024 }, { 6, 285, 1024 }, { 6, 286, 1024 }, { 7, 287, 1024 },
+   { 3, 288, 1024 }, { 4, 289, 1024 }, { 4, 290, 1024 }, { 5, 291, 1024 }, { 4, 292, 1024 }, { 5, 293, 1024 }, { 5, 294, 1024 }, { 6, 295, 1024 },
+   { 4, 296, 1024 }, { 5, 297, 1024 }, { 5, 298, 1024 }, { 6, 299, 1024 }, { 5, 300, 1024 }, { 6, 301, 1024 }, { 6, 302, 1024 }, { 7, 303, 1024 },
+   { 4, 304, 1024 }, { 5, 305, 1024 }, { 5, 306, 1024 }, { 6, 307, 1024 }, { 5, 308, 1024 }, { 6, 309, 1024 }, { 6, 310, 1024 }, { 7, 311, 1024 },
+   { 5, 312, 1024 }, { 6, 313, 1024 }, { 6, 314, 1024 }, { 7, 315, 1024 }, { 6, 316, 1024 }, { 7, 317, 1024 }, { 7, 318, 1024 }, { 8, 319, 1024 },
+   { 3, 320, 1024 }, { 4, 321, 1024 }, { 4, 322, 1024 }, { 5, 323, 1024 }, { 4, 324, 1024 }, { 5, 325, 1024 }, { 5, 326, 1024 }, { 6, 327, 1024 },
+   { 4, 328, 1024 }, { 5, 329, 1024 }, { 5, 330, 1024 }, { 6, 331, 1024 }, { 5, 332, 1024 }, { 6, 333, 1024 }, { 6, 334, 1024 }, { 7, 335, 1024 },
+   { 4, 336, 1024 }, { 5, 337, 1024 }, { 5, 338, 1024 }, { 6, 339, 1024 }, { 5, 340, 1024 }, { 6, 341, 1024 }, { 6, 342, 1024 }, { 7, 343, 1024 },
+   { 5, 344, 1024 }, { 6, 345, 1024 }, { 6, 346, 1024 }, { 7, 347, 1024 }, { 6, 348, 1024 }, { 7, 349, 1024 }, { 7, 350, 1024 }, { 8, 351, 1024 },
+   { 4, 352, 1024 }, { 5, 353, 1024 }, { 5, 354, 1024 }, { 6, 355, 1024 }, { 5, 356, 1024 }, { 6, 357, 1024 }, { 6, 358, 1024 }, { 7, 359, 1024 },
+   { 5, 360, 1024 }, { 6, 361, 1024 }, { 6, 362, 1024 }, { 7, 363, 1024 }, { 6, 364, 1024 }, { 7, 365, 1024 }, { 7, 366, 1024 }, { 8, 367, 1024 },
+   { 5, 368, 1024 }, { 6, 369, 1024 }, { 6, 370, 1024 }, { 7, 371, 1024 }, { 6, 372, 1024 }, { 7, 373, 1024 }, { 7, 374, 1024 }, { 8, 375, 1024 },
+   { 6, 376, 1024 }, { 7, 377, 1024 }, { 7, 378, 1024 }, { 8, 379, 1024 }, { 7, 380, 1024 }, { 8, 381, 1024 }, { 8, 382, 1024 }, { 9, 383, 1024 },
+   { 3, 384, 1024 }, { 4, 385, 1024 }, { 4, 386, 1024 }, { 5, 387, 1024 }, { 4, 388, 1024 }, { 5, 389, 1024 }, { 5, 390, 1024 }, { 6, 391, 1024 },
+   { 4, 392, 1024 }, { 5, 393, 1024 }, { 5, 394, 1024 }, { 6, 395, 1024 }, { 5, 396, 1024 }, { 6, 397, 1024 }, { 6, 398, 1024 }, { 7, 399, 1024 },
+   { 4, 400, 1024 }, { 5, 401, 1024 }, { 5, 402, 1024 }, { 6, 403, 1024 }, { 5, 404, 1024 }, { 6, 405, 1024 }, { 6, 406, 1024 }, { 7, 407, 1024 },
+   { 5, 408, 1024 }, { 6, 409, 1024 }, { 6, 410, 1024 }, { 7, 411, 1024 }, { 6, 412, 1024 }, { 7, 413, 1024 }, { 7, 414, 1024 }, { 8, 415, 1024 },
+   { 4, 416, 1024 }, { 5, 417, 1024 }, { 5, 418, 1024 }, { 6, 419, 1024 }, { 5, 420, 1024 }, { 6, 421, 1024 }, { 6, 422, 1024 }, { 7, 423, 1024 },
+   { 5, 424, 1024 }, { 6, 425, 1024 }, { 6, 426, 1024 }, { 7, 427, 1024 }, { 6, 428, 1024 }, { 7, 429, 1024 }, { 7, 430, 1024 }, { 8, 431, 1024 },
+   { 5, 432, 1024 }, { 6, 433, 1024 }, { 6, 434, 1024 }, { 7, 435, 1024 }, { 6, 436, 1024 }, { 7, 437, 1024 }, { 7, 438, 1024 }, { 8, 439, 1024 },
+   { 6, 440, 1024 }, { 7, 441, 1024 }, { 7, 442, 1024 }, { 8, 443, 1024 }, { 7, 444, 1024 }, { 8, 445, 1024 }, { 8, 446, 1024 }, { 9, 447, 1024 },
+   { 4, 448, 1024 }, { 5, 449, 1024 }, { 5, 450, 1024 }, { 6, 451, 1024 }, { 5, 452, 1024 }, { 6, 453, 1024 }, { 6, 454, 1024 }, { 7, 455, 1024 },
+   { 5, 456, 1024 }, { 6, 457, 1024 }, { 6, 458, 1024 }, { 7, 459, 1024 }, { 6, 460, 1024 }, { 7, 461, 1024 }, { 7, 462, 1024 }, { 8, 463, 1024 },
+   { 5, 464, 1024 }, { 6, 465, 1024 }, { 6, 466, 1024 }, { 7, 467, 1024 }, { 6, 468, 1024 }, { 7, 469, 1024 }, { 7, 470, 1024 }, { 8, 471, 1024 },
+   { 6, 472, 1024 }, { 7, 473, 1024 }, { 7, 474, 1024 }, { 8, 475, 1024 }, { 7, 476, 1024 }, { 8, 477, 1024 }, { 8, 478, 1024 }, { 9, 479, 1024 },
+   { 5, 480, 1024 }, { 6, 481, 1024 }, { 6, 482, 1024 }, { 7, 483, 1024 }, { 6, 484, 1024 }, { 7, 485, 1024 }, { 7, 486, 1024 }, { 8, 487, 1024 },
+   { 6, 488, 1024 }, { 7, 489, 1024 }, { 7, 490, 1024 }, { 8, 491, 1024 }, { 7, 492, 1024 }, { 8, 493, 1024 }, { 8, 494, 1024 }, { 9, 495, 1024 },
+   { 6, 496, 1024 }, { 7, 497, 1024 }, { 7, 498, 1024 }, { 8, 499, 1024 }, { 7, 500, 1024 }, { 8, 501, 1024 }, { 8, 502, 1024 }, { 9, 503, 1024 },
+   { 7, 504, 1024 }, { 8, 505, 1024 }, { 8, 506, 1024 }, { 9, 507, 1024 }, { 8, 508, 1024 }, { 9, 509, 1024 }, { 9, 510, 1024 }, { 10, 511, 1024 },
+   { 2, 512, 1024 }, { 3, 513, 1024 }, { 3, 514, 1024 }, { 4, 515, 1024 }, { 3, 516, 1024 }, { 4, 517, 1024 }, { 4, 518, 1024 }, { 5, 519, 1024 },
+   { 3, 520, 1024 }, { 4, 521, 1024 }, { 4, 522, 1024 }, { 5, 523, 1024 }, { 4, 524, 1024 }, { 5, 525, 1024 }, { 5, 526, 1024 }, { 6, 527, 1024 },
+   { 3, 528, 1024 }, { 4, 529, 1024 }, { 4, 530, 1024 }, { 5, 531, 1024 }, { 4, 532, 1024 }, { 5, 533, 1024 }, { 5, 534, 1024 }, { 6, 535, 1024 },
+   { 4, 536, 1024 }, { 5, 537, 1024 }, { 5, 538, 1024 }, { 6, 539, 1024 }, { 5, 540, 1024 }, { 6, 541, 1024 }, { 6, 542, 1024 }, { 7, 543, 1024 },
+   { 3, 544, 1024 }, { 4, 545, 1024 }, { 4, 546, 1024 }, { 5, 547, 1024 }, { 4, 548, 1024 }, { 5, 549, 1024 }, { 5, 550, 1024 }, { 6, 551, 1024 },
+   { 4, 552, 1024 }, { 5, 553, 1024 }, { 5, 554, 1024 }, { 6, 555, 1024 }, { 5, 556, 1024 }, { 6, 557, 1024 }, { 6, 558, 1024 }, { 7, 559, 1024 },
+   { 4, 560, 1024 }, { 5, 561, 1024 }, { 5, 562, 1024 }, { 6, 563, 1024 }, { 5, 564, 1024 }, { 6, 565, 1024 }, { 6, 566, 1024 }, { 7, 567, 1024 },
+   { 5, 568, 1024 }, { 6, 569, 1024 }, { 6, 570, 1024 }, { 7, 571, 1024 }, { 6, 572, 1024 }, { 7, 573, 1024 }, { 7, 574, 1024 }, { 8, 575, 1024 },
+   { 3, 576, 1024 }, { 4, 577, 1024 }, { 4, 578, 1024 }, { 5, 579, 1024 }, { 4, 580, 1024 }, { 5, 581, 1024 }, { 5, 582, 1024 }, { 6, 583, 1024 },
+   { 4, 584, 1024 }, { 5, 585, 1024 }, { 5, 586, 1024 }, { 6, 587, 1024 }, { 5, 588, 1024 }, { 6, 589, 1024 }, { 6, 590, 1024 }, { 7, 591, 1024 },
+   { 4, 592, 1024 }, { 5, 593, 1024 }, { 5, 594, 1024 }, { 6, 595, 1024 }, { 5, 596, 1024 }, { 6, 597, 1024 }, { 6, 598, 1024 }, { 7, 599, 1024 },
+   { 5, 600, 1024 }, { 6, 601, 1024 }, { 6, 602, 1024 }, { 7, 603, 1024 }, { 6, 604, 1024 }, { 7, 605, 1024 }, { 7, 606, 1024 }, { 8, 607, 1024 },
+   { 4, 608, 1024 }, { 5, 609, 1024 }, { 5, 610, 1024 }, { 6, 611, 1024 }, { 5, 612, 1024 }, { 6, 613, 1024 }, { 6, 614, 1024 }, { 7, 615, 1024 },
+   { 5, 616, 1024 }, { 6, 617, 1024 }, { 6, 618, 1024 }, { 7, 619, 1024 }, { 6, 620, 1024 }, { 7, 621, 1024 }, { 7, 622, 1024 }, { 8, 623, 1024 },
+   { 5, 624, 1024 }, { 6, 625, 1024 }, { 6, 626, 1024 }, { 7, 627, 1024 }, { 6, 628, 1024 }, { 7, 629, 1024 }, { 7, 630, 1024 }, { 8, 631, 1024 },
+   { 6, 632, 1024 }, { 7, 633, 1024 }, { 7, 634, 1024 }, { 8, 635, 1024 }, { 7, 636, 1024 }, { 8, 637, 1024 }, { 8, 638, 1024 }, { 9, 639, 1024 },
+   { 3, 640, 1024 }, { 4, 641, 1024 }, { 4, 642, 1024 }, { 5, 643, 1024 }, { 4, 644, 1024 }, { 5, 645, 1024 }, { 5, 646, 1024 }, { 6, 647, 1024 },
+   { 4, 648, 1024 }, { 5, 649, 1024 }, { 5, 650, 1024 }, { 6, 651, 1024 }, { 5, 652, 1024 }, { 6, 653, 1024 }, { 6, 654, 1024 }, { 7, 655, 1024 },
+   { 4, 656, 1024 }, { 5, 657, 1024 }, { 5, 658, 1024 }, { 6, 659, 1024 }, { 5, 660, 1024 }, { 6, 661, 1024 }, { 6, 662, 1024 }, { 7, 663, 1024 },
+   { 5, 664, 1024 }, { 6, 665, 1024 }, { 6, 666, 1024 }, { 7, 667, 1024 }, { 6, 668, 1024 }, { 7, 669, 1024 }, { 7, 670, 1024 }, { 8, 671, 1024 },
+   { 4, 672, 1024 }, { 5, 673, 1024 }, { 5, 674, 1024 }, { 6, 675, 1024 }, { 5, 676, 1024 }, { 6, 677, 1024 }, { 6, 678, 1024 }, { 7, 679, 1024 },
+   { 5, 680, 1024 }, { 6, 681, 1024 }, { 6, 682, 1024 }, { 7, 683, 1024 }, { 6, 684, 1024 }, { 7, 685, 1024 }, { 7, 686, 1024 }, { 8, 687, 1024 },
+   { 5, 688, 1024 }, { 6, 689, 1024 }, { 6, 690, 1024 }, { 7, 691, 1024 }, { 6, 692, 1024 }, { 7, 693, 1024 }, { 7, 694, 1024 }, { 8, 695, 1024 },
+   { 6, 696, 1024 }, { 7, 697, 1024 }, { 7, 698, 1024 }, { 8, 699, 1024 }, { 7, 700, 1024 }, { 8, 701, 1024 }, { 8, 702, 1024 }, { 9, 703, 1024 },
+   { 4, 704, 1024 }, { 5, 705, 1024 }, { 5, 706, 1024 }, { 6, 707, 1024 }, { 5, 708, 1024 }, { 6, 709, 1024 }, { 6, 710, 1024 }, { 7, 711, 1024 },
+   { 5, 712, 1024 }, { 6, 713, 1024 }, { 6, 714, 1024 }, { 7, 715, 1024 }, { 6, 716, 1024 }, { 7, 717, 1024 }, { 7, 718, 1024 }, { 8, 719, 1024 },
+   { 5, 720, 1024 }, { 6, 721, 1024 }, { 6, 722, 1024 }, { 7, 723, 1024 }, { 6, 724, 1024 }, { 7, 725, 1024 }, { 7, 726, 1024 }, { 8, 727, 1024 },
+   { 6, 728, 1024 }, { 7, 729, 1024 }, { 7, 730, 1024 }, { 8, 731, 1024 }, { 7, 732, 1024 }, { 8, 733, 1024 }, { 8, 734, 1024 }, { 9, 735, 1024 },
+   { 5, 736, 1024 }, { 6, 737, 1024 }, { 6, 738, 1024 }, { 7, 739, 1024 }, { 6, 740, 1024 }, { 7, 741, 1024 }, { 7, 742, 1024 }, { 8, 743, 1024 },
+   { 6, 744, 1024 }, { 7, 745, 1024 }, { 7, 746, 1024 }, { 8, 747, 1024 }, { 7, 748, 1024 }, { 8, 749, 1024 }, { 8, 750, 1024 }, { 9, 751, 1024 },
+   { 6, 752, 1024 }, { 7, 753, 1024 }, { 7, 754, 1024 }, { 8, 755, 1024 }, { 7, 756, 1024 }, { 8, 757, 1024 }, { 8, 758, 1024 }, { 9, 759, 1024 },
+   { 7, 760, 1024 }, { 8, 761, 1024 }, { 8, 762, 1024 }, { 9, 763, 1024 }, { 8, 764, 1024 }, { 9, 765, 1024 }, { 9, 766, 1024 }, { 10, 767, 1024 },
+   { 3, 768, 1024 }, { 4, 769, 1024 }, { 4, 770, 1024 }, { 5, 771, 1024 }, { 4, 772, 1024 }, { 5, 773, 1024 }, { 5, 774, 1024 }, { 6, 775, 1024 },
+   { 4, 776, 1024 }, { 5, 777, 1024 }, { 5, 778, 1024 }, { 6, 779, 1024 }, { 5, 780, 1024 }, { 6, 781, 1024 }, { 6, 782, 1024 }, { 7, 783, 1024 },
+   { 4, 784, 1024 }, { 5, 785, 1024 }, { 5, 786, 1024 }, { 6, 787, 1024 }, { 5, 788, 1024 }, { 6, 789, 1024 }, { 6, 790, 1024 }, { 7, 791, 1024 },
+   { 5, 792, 1024 }, { 6, 793, 1024 }, { 6, 794, 1024 }, { 7, 795, 1024 }, { 6, 796, 1024 }, { 7, 797, 1024 }, { 7, 798, 1024 }, { 8, 799, 1024 },
+   { 4, 800, 1024 }, { 5, 801, 1024 }, { 5, 802, 1024 }, { 6, 803, 1024 }, { 5, 804, 1024 }, { 6, 805, 1024 }, { 6, 806, 1024 }, { 7, 807, 1024 },
+   { 5, 808, 1024 }, { 6, 809, 1024 }, { 6, 810, 1024 }, { 7, 811, 1024 }, { 6, 812, 1024 }, { 7, 813, 1024 }, { 7, 814, 1024 }, { 8, 815, 1024 },
+   { 5, 816, 1024 }, { 6, 817, 1024 }, { 6, 818, 1024 }, { 7, 819, 1024 }, { 6, 820, 1024 }, { 7, 821, 1024 }, { 7, 822, 1024 }, { 8, 823, 1024 },
+   { 6, 824, 1024 }, { 7, 825, 1024 }, { 7, 826, 1024 }, { 8, 827, 1024 }, { 7, 828, 1024 }, { 8, 829, 1024 }, { 8, 830, 1024 }, { 9, 831, 1024 },
+   { 4, 832, 1024 }, { 5, 833, 1024 }, { 5, 834, 1024 }, { 6, 835, 1024 }, { 5, 836, 1024 }, { 6, 837, 1024 }, { 6, 838, 1024 }, { 7, 839, 1024 },
+   { 5, 840, 1024 }, { 6, 841, 1024 }, { 6, 842, 1024 }, { 7, 843, 1024 }, { 6, 844, 1024 }, { 7, 845, 1024 }, { 7, 846, 1024 }, { 8, 847, 1024 },
+   { 5, 848, 1024 }, { 6, 849, 1024 }, { 6, 850, 1024 }, { 7, 851, 1024 }, { 6, 852, 1024 }, { 7, 853, 1024 }, { 7, 854, 1024 }, { 8, 855, 1024 },
+   { 6, 856, 1024 }, { 7, 857, 1024 }, { 7, 858, 1024 }, { 8, 859, 1024 }, { 7, 860, 1024 }, { 8, 861, 1024 }, { 8, 862, 1024 }, { 9, 863, 1024 },
+   { 5, 864, 1024 }, { 6, 865, 1024 }, { 6, 866, 1024 }, { 7, 867, 1024 }, { 6, 868, 1024 }, { 7, 869, 1024 }, { 7, 870, 1024 }, { 8, 871, 1024 },
+   { 6, 872, 1024 }, { 7, 873, 1024 }, { 7, 874, 1024 }, { 8, 875, 1024 }, { 7, 876, 1024 }, { 8, 877, 1024 }, { 8, 878, 1024 }, { 9, 879, 1024 },
+   { 6, 880, 1024 }, { 7, 881, 1024 }, { 7, 882, 1024 }, { 8, 883, 1024 }, { 7, 884, 1024 }, { 8, 885, 1024 }, { 8, 886, 1024 }, { 9, 887, 1024 },
+   { 7, 888, 1024 }, { 8, 889, 1024 }, { 8, 890, 1024 }, { 9, 891, 1024 }, { 8, 892, 1024 }, { 9, 893, 1024 }, { 9, 894, 1024 }, { 10, 895, 1024 },
+   { 4, 896, 1024 }, { 5, 897, 1024 }, { 5, 898, 1024 }, { 6, 899, 1024 }, { 5, 900, 1024 }, { 6, 901, 1024 }, { 6, 902, 1024 }, { 7, 903, 1024 },
+   { 5, 904, 1024 }, { 6, 905, 1024 }, { 6, 906, 1024 }, { 7, 907, 1024 }, { 6, 908, 1024 }, { 7, 909, 1024 }, { 7, 910, 1024 }, { 8, 911, 1024 },
+   { 5, 912, 1024 }, { 6, 913, 1024 }, { 6, 914, 1024 }, { 7, 915, 1024 }, { 6, 916, 1024 }, { 7, 917, 1024 }, { 7, 918, 1024 }, { 8, 919, 1024 },
+   { 6, 920, 1024 }, { 7, 921, 1024 }, { 7, 922, 1024 }, { 8, 923, 1024 }, { 7, 924, 1024 }, { 8, 925, 1024 }, { 8, 926, 1024 }, { 9, 927, 1024 },
+   { 5, 928, 1024 }, { 6, 929, 1024 }, { 6, 930, 1024 }, { 7, 931, 1024 }, { 6, 932, 1024 }, { 7, 933, 1024 }, { 7, 934, 1024 }, { 8, 935, 1024 },
+   { 6, 936, 1024 }, { 7, 937, 1024 }, { 7, 938, 1024 }, { 8, 939, 1024 }, { 7, 940, 1024 }, { 8, 941, 1024 }, { 8, 942, 1024 }, { 9, 943, 1024 },
+   { 6, 944, 1024 }, { 7, 945, 1024 }, { 7, 946, 1024 }, { 8, 947, 1024 }, { 7, 948, 1024 }, { 8, 949, 1024 }, { 8, 950, 1024 }, { 9, 951, 1024 },
+   { 7, 952, 1024 }, { 8, 953, 1024 }, { 8, 954, 1024 }, { 9, 955, 1024 }, { 8, 956, 1024 }, { 9, 957, 1024 }, { 9, 958, 1024 }, { 10, 959, 1024 },
+   { 5, 960, 1024 }, { 6, 961, 1024 }, { 6, 962, 1024 }, { 7, 963, 1024 }, { 6, 964, 1024 }, { 7, 965, 1024 }, { 7, 966, 1024 }, { 8, 967, 1024 },
+   { 6, 968, 1024 }, { 7, 969, 1024 }, { 7, 970, 1024 }, { 8, 971, 1024 }, { 7, 972, 1024 }, { 8, 973, 1024 }, { 8, 974, 1024 }, { 9, 975, 1024 },
+   { 6, 976, 1024 }, { 7, 977, 1024 }, { 7, 978, 1024 }, { 8, 979, 1024 }, { 7, 980, 1024 }, { 8, 981, 1024 }, { 8, 982, 1024 }, { 9, 983, 1024 },
+   { 7, 984, 1024 }, { 8, 985, 1024 }, { 8, 986, 1024 }, { 9, 987, 1024 }, { 8, 988, 1024 }, { 9, 989, 1024 }, { 9, 990, 1024 }, { 10, 991, 1024 },
+   { 6, 992, 1024 }, { 7, 993, 1024 }, { 7, 994, 1024 }, { 8, 995, 1024 }, { 7, 996, 1024 }, { 8, 997, 1024 }, { 8, 998, 1024 }, { 9, 999, 1024 },
+   { 7, 1000, 1024 }, { 8, 1001, 1024 }, { 8, 1002, 1024 }, { 9, 1003, 1024 }, { 8, 1004, 1024 }, { 9, 1005, 1024 }, { 9, 1006, 1024 }, { 10, 1007, 1024 },
+   { 7, 1008, 1024 }, { 8, 1009, 1024 }, { 8, 1010, 1024 }, { 9, 1011, 1024 }, { 8, 1012, 1024 }, { 9, 1013, 1024 }, { 9, 1014, 1024 }, { 10, 1015, 1024 },
+   { 8, 1016, 1024 }, { 9, 1017, 1024 }, { 9, 1018, 1024 }, { 10, 1019, 1024 }, { 9, 1020, 1024 }, { 10, 1021, 1024 }, { 10, 1022, 1024 }, { 11, 1023, 1024 },
+#if FP_LUT > 11
+   { 1, 0, 0 }, { 2, 1, 2048 }, { 2, 2, 2048 }, { 3, 3, 2048 }, { 2, 4, 2048 }, { 3, 5, 2048 }, { 3, 6, 2048 }, { 4, 7, 2048 },
+   { 2, 8, 2048 }, { 3, 9, 2048 }, { 3, 10, 2048 }, { 4, 11, 2048 }, { 3, 12, 2048 }, { 4, 13, 2048 }, { 4, 14, 2048 }, { 5, 15, 2048 },
+   { 2, 16, 2048 }, { 3, 17, 2048 }, { 3, 18, 2048 }, { 4, 19, 2048 }, { 3, 20, 2048 }, { 4, 21, 2048 }, { 4, 22, 2048 }, { 5, 23, 2048 },
+   { 3, 24, 2048 }, { 4, 25, 2048 }, { 4, 26, 2048 }, { 5, 27, 2048 }, { 4, 28, 2048 }, { 5, 29, 2048 }, { 5, 30, 2048 }, { 6, 31, 2048 },
+   { 2, 32, 2048 }, { 3, 33, 2048 }, { 3, 34, 2048 }, { 4, 35, 2048 }, { 3, 36, 2048 }, { 4, 37, 2048 }, { 4, 38, 2048 }, { 5, 39, 2048 },
+   { 3, 40, 2048 }, { 4, 41, 2048 }, { 4, 42, 2048 }, { 5, 43, 2048 }, { 4, 44, 2048 }, { 5, 45, 2048 }, { 5, 46, 2048 }, { 6, 47, 2048 },
+   { 3, 48, 2048 }, { 4, 49, 2048 }, { 4, 50, 2048 }, { 5, 51, 2048 }, { 4, 52, 2048 }, { 5, 53, 2048 }, { 5, 54, 2048 }, { 6, 55, 2048 },
+   { 4, 56, 2048 }, { 5, 57, 2048 }, { 5, 58, 2048 }, { 6, 59, 2048 }, { 5, 60, 2048 }, { 6, 61, 2048 }, { 6, 62, 2048 }, { 7, 63, 2048 },
+   { 2, 64, 2048 }, { 3, 65, 2048 }, { 3, 66, 2048 }, { 4, 67, 2048 }, { 3, 68, 2048 }, { 4, 69, 2048 }, { 4, 70, 2048 }, { 5, 71, 2048 },
+   { 3, 72, 2048 }, { 4, 73, 2048 }, { 4, 74, 2048 }, { 5, 75, 2048 }, { 4, 76, 2048 }, { 5, 77, 2048 }, { 5, 78, 2048 }, { 6, 79, 2048 },
+   { 3, 80, 2048 }, { 4, 81, 2048 }, { 4, 82, 2048 }, { 5, 83, 2048 }, { 4, 84, 2048 }, { 5, 85, 2048 }, { 5, 86, 2048 }, { 6, 87, 2048 },
+   { 4, 88, 2048 }, { 5, 89, 2048 }, { 5, 90, 2048 }, { 6, 91, 2048 }, { 5, 92, 2048 }, { 6, 93, 2048 }, { 6, 94, 2048 }, { 7, 95, 2048 },
+   { 3, 96, 2048 }, { 4, 97, 2048 }, { 4, 98, 2048 }, { 5, 99, 2048 }, { 4, 100, 2048 }, { 5, 101, 2048 }, { 5, 102, 2048 }, { 6, 103, 2048 },
+   { 4, 104, 2048 }, { 5, 105, 2048 }, { 5, 106, 2048 }, { 6, 107, 2048 }, { 5, 108, 2048 }, { 6, 109, 2048 }, { 6, 110, 2048 }, { 7, 111, 2048 },
+   { 4, 112, 2048 }, { 5, 113, 2048 }, { 5, 114, 2048 }, { 6, 115, 2048 }, { 5, 116, 2048 }, { 6, 117, 2048 }, { 6, 118, 2048 }, { 7, 119, 2048 },
+   { 5, 120, 2048 }, { 6, 121, 2048 }, { 6, 122, 2048 }, { 7, 123, 2048 }, { 6, 124, 2048 }, { 7, 125, 2048 }, { 7, 126, 2048 }, { 8, 127, 2048 },
+   { 2, 128, 2048 }, { 3, 129, 2048 }, { 3, 130, 2048 }, { 4, 131, 2048 }, { 3, 132, 2048 }, { 4, 133, 2048 }, { 4, 134, 2048 }, { 5, 135, 2048 },
+   { 3, 136, 2048 }, { 4, 137, 2048 }, { 4, 138, 2048 }, { 5, 139, 2048 }, { 4, 140, 2048 }, { 5, 141, 2048 }, { 5, 142, 2048 }, { 6, 143, 2048 },
+   { 3, 144, 2048 }, { 4, 145, 2048 }, { 4, 146, 2048 }, { 5, 147, 2048 }, { 4, 148, 2048 }, { 5, 149, 2048 }, { 5, 150, 2048 }, { 6, 151, 2048 },
+   { 4, 152, 2048 }, { 5, 153, 2048 }, { 5, 154, 2048 }, { 6, 155, 2048 }, { 5, 156, 2048 }, { 6, 157, 2048 }, { 6, 158, 2048 }, { 7, 159, 2048 },
+   { 3, 160, 2048 }, { 4, 161, 2048 }, { 4, 162, 2048 }, { 5, 163, 2048 }, { 4, 164, 2048 }, { 5, 165, 2048 }, { 5, 166, 2048 }, { 6, 167, 2048 },
+   { 4, 168, 2048 }, { 5, 169, 2048 }, { 5, 170, 2048 }, { 6, 171, 2048 }, { 5, 172, 2048 }, { 6, 173, 2048 }, { 6, 174, 2048 }, { 7, 175, 2048 },
+   { 4, 176, 2048 }, { 5, 177, 2048 }, { 5, 178, 2048 }, { 6, 179, 2048 }, { 5, 180, 2048 }, { 6, 181, 2048 }, { 6, 182, 2048 }, { 7, 183, 2048 },
+   { 5, 184, 2048 }, { 6, 185, 2048 }, { 6, 186, 2048 }, { 7, 187, 2048 }, { 6, 188, 2048 }, { 7, 189, 2048 }, { 7, 190, 2048 }, { 8, 191, 2048 },
+   { 3, 192, 2048 }, { 4, 193, 2048 }, { 4, 194, 2048 }, { 5, 195, 2048 }, { 4, 196, 2048 }, { 5, 197, 2048 }, { 5, 198, 2048 }, { 6, 199, 2048 },
+   { 4, 200, 2048 }, { 5, 201, 2048 }, { 5, 202, 2048 }, { 6, 203, 2048 }, { 5, 204, 2048 }, { 6, 205, 2048 }, { 6, 206, 2048 }, { 7, 207, 2048 },
+   { 4, 208, 2048 }, { 5, 209, 2048 }, { 5, 210, 2048 }, { 6, 211, 2048 }, { 5, 212, 2048 }, { 6, 213, 2048 }, { 6, 214, 2048 }, { 7, 215, 2048 },
+   { 5, 216, 2048 }, { 6, 217, 2048 }, { 6, 218, 2048 }, { 7, 219, 2048 }, { 6, 220, 2048 }, { 7, 221, 2048 }, { 7, 222, 2048 }, { 8, 223, 2048 },
+   { 4, 224, 2048 }, { 5, 225, 2048 }, { 5, 226, 2048 }, { 6, 227, 2048 }, { 5, 228, 2048 }, { 6, 229, 2048 }, { 6, 230, 2048 }, { 7, 231, 2048 },
+   { 5, 232, 2048 }, { 6, 233, 2048 }, { 6, 234, 2048 }, { 7, 235, 2048 }, { 6, 236, 2048 }, { 7, 237, 2048 }, { 7, 238, 2048 }, { 8, 239, 2048 },
+   { 5, 240, 2048 }, { 6, 241, 2048 }, { 6, 242, 2048 }, { 7, 243, 2048 }, { 6, 244, 2048 }, { 7, 245, 2048 }, { 7, 246, 2048 }, { 8, 247, 2048 },
+   { 6, 248, 2048 }, { 7, 249, 2048 }, { 7, 250, 2048 }, { 8, 251, 2048 }, { 7, 252, 2048 }, { 8, 253, 2048 }, { 8, 254, 2048 }, { 9, 255, 2048 },
+   { 2, 256, 2048 }, { 3, 257, 2048 }, { 3, 258, 2048 }, { 4, 259, 2048 }, { 3, 260, 2048 }, { 4, 261, 2048 }, { 4, 262, 2048 }, { 5, 263, 2048 },
+   { 3, 264, 2048 }, { 4, 265, 2048 }, { 4, 266, 2048 }, { 5, 267, 2048 }, { 4, 268, 2048 }, { 5, 269, 2048 }, { 5, 270, 2048 }, { 6, 271, 2048 },
+   { 3, 272, 2048 }, { 4, 273, 2048 }, { 4, 274, 2048 }, { 5, 275, 2048 }, { 4, 276, 2048 }, { 5, 277, 2048 }, { 5, 278, 2048 }, { 6, 279, 2048 },
+   { 4, 280, 2048 }, { 5, 281, 2048 }, { 5, 282, 2048 }, { 6, 283, 2048 }, { 5, 284, 2048 }, { 6, 285, 2048 }, { 6, 286, 2048 }, { 7, 287, 2048 },
+   { 3, 288, 2048 }, { 4, 289, 2048 }, { 4, 290, 2048 }, { 5, 291, 2048 }, { 4, 292, 2048 }, { 5, 293, 2048 }, { 5, 294, 2048 }, { 6, 295, 2048 },
+   { 4, 296, 2048 }, { 5, 297, 2048 }, { 5, 298, 2048 }, { 6, 299, 2048 }, { 5, 300, 2048 }, { 6, 301, 2048 }, { 6, 302, 2048 }, { 7, 303, 2048 },
+   { 4, 304, 2048 }, { 5, 305, 2048 }, { 5, 306, 2048 }, { 6, 307, 2048 }, { 5, 308, 2048 }, { 6, 309, 2048 }, { 6, 310, 2048 }, { 7, 311, 2048 },
+   { 5, 312, 2048 }, { 6, 313, 2048 }, { 6, 314, 2048 }, { 7, 315, 2048 }, { 6, 316, 2048 }, { 7, 317, 2048 }, { 7, 318, 2048 }, { 8, 319, 2048 },
+   { 3, 320, 2048 }, { 4, 321, 2048 }, { 4, 322, 2048 }, { 5, 323, 2048 }, { 4, 324, 2048 }, { 5, 325, 2048 }, { 5, 326, 2048 }, { 6, 327, 2048 },
+   { 4, 328, 2048 }, { 5, 329, 2048 }, { 5, 330, 2048 }, { 6, 331, 2048 }, { 5, 332, 2048 }, { 6, 333, 2048 }, { 6, 334, 2048 }, { 7, 335, 2048 },
+   { 4, 336, 2048 }, { 5, 337, 2048 }, { 5, 338, 2048 }, { 6, 339, 2048 }, { 5, 340, 2048 }, { 6, 341, 2048 }, { 6, 342, 2048 }, { 7, 343, 2048 },
+   { 5, 344, 2048 }, { 6, 345, 2048 }, { 6, 346, 2048 }, { 7, 347, 2048 }, { 6, 348, 2048 }, { 7, 349, 2048 }, { 7, 350, 2048 }, { 8, 351, 2048 },
+   { 4, 352, 2048 }, { 5, 353, 2048 }, { 5, 354, 2048 }, { 6, 355, 2048 }, { 5, 356, 2048 }, { 6, 357, 2048 }, { 6, 358, 2048 }, { 7, 359, 2048 },
+   { 5, 360, 2048 }, { 6, 361, 2048 }, { 6, 362, 2048 }, { 7, 363, 2048 }, { 6, 364, 2048 }, { 7, 365, 2048 }, { 7, 366, 2048 }, { 8, 367, 2048 },
+   { 5, 368, 2048 }, { 6, 369, 2048 }, { 6, 370, 2048 }, { 7, 371, 2048 }, { 6, 372, 2048 }, { 7, 373, 2048 }, { 7, 374, 2048 }, { 8, 375, 2048 },
+   { 6, 376, 2048 }, { 7, 377, 2048 }, { 7, 378, 2048 }, { 8, 379, 2048 }, { 7, 380, 2048 }, { 8, 381, 2048 }, { 8, 382, 2048 }, { 9, 383, 2048 },
+   { 3, 384, 2048 }, { 4, 385, 2048 }, { 4, 386, 2048 }, { 5, 387, 2048 }, { 4, 388, 2048 }, { 5, 389, 2048 }, { 5, 390, 2048 }, { 6, 391, 2048 },
+   { 4, 392, 2048 }, { 5, 393, 2048 }, { 5, 394, 2048 }, { 6, 395, 2048 }, { 5, 396, 2048 }, { 6, 397, 2048 }, { 6, 398, 2048 }, { 7, 399, 2048 },
+   { 4, 400, 2048 }, { 5, 401, 2048 }, { 5, 402, 2048 }, { 6, 403, 2048 }, { 5, 404, 2048 }, { 6, 405, 2048 }, { 6, 406, 2048 }, { 7, 407, 2048 },
+   { 5, 408, 2048 }, { 6, 409, 2048 }, { 6, 410, 2048 }, { 7, 411, 2048 }, { 6, 412, 2048 }, { 7, 413, 2048 }, { 7, 414, 2048 }, { 8, 415, 2048 },
+   { 4, 416, 2048 }, { 5, 417, 2048 }, { 5, 418, 2048 }, { 6, 419, 2048 }, { 5, 420, 2048 }, { 6, 421, 2048 }, { 6, 422, 2048 }, { 7, 423, 2048 },
+   { 5, 424, 2048 }, { 6, 425, 2048 }, { 6, 426, 2048 }, { 7, 427, 2048 }, { 6, 428, 2048 }, { 7, 429, 2048 }, { 7, 430, 2048 }, { 8, 431, 2048 },
+   { 5, 432, 2048 }, { 6, 433, 2048 }, { 6, 434, 2048 }, { 7, 435, 2048 }, { 6, 436, 2048 }, { 7, 437, 2048 }, { 7, 438, 2048 }, { 8, 439, 2048 },
+   { 6, 440, 2048 }, { 7, 441, 2048 }, { 7, 442, 2048 }, { 8, 443, 2048 }, { 7, 444, 2048 }, { 8, 445, 2048 }, { 8, 446, 2048 }, { 9, 447, 2048 },
+   { 4, 448, 2048 }, { 5, 449, 2048 }, { 5, 450, 2048 }, { 6, 451, 2048 }, { 5, 452, 2048 }, { 6, 453, 2048 }, { 6, 454, 2048 }, { 7, 455, 2048 },
+   { 5, 456, 2048 }, { 6, 457, 2048 }, { 6, 458, 2048 }, { 7, 459, 2048 }, { 6, 460, 2048 }, { 7, 461, 2048 }, { 7, 462, 2048 }, { 8, 463, 2048 },
+   { 5, 464, 2048 }, { 6, 465, 2048 }, { 6, 466, 2048 }, { 7, 467, 2048 }, { 6, 468, 2048 }, { 7, 469, 2048 }, { 7, 470, 2048 }, { 8, 471, 2048 },
+   { 6, 472, 2048 }, { 7, 473, 2048 }, { 7, 474, 2048 }, { 8, 475, 2048 }, { 7, 476, 2048 }, { 8, 477, 2048 }, { 8, 478, 2048 }, { 9, 479, 2048 },
+   { 5, 480, 2048 }, { 6, 481, 2048 }, { 6, 482, 2048 }, { 7, 483, 2048 }, { 6, 484, 2048 }, { 7, 485, 2048 }, { 7, 486, 2048 }, { 8, 487, 2048 },
+   { 6, 488, 2048 }, { 7, 489, 2048 }, { 7, 490, 2048 }, { 8, 491, 2048 }, { 7, 492, 2048 }, { 8, 493, 2048 }, { 8, 494, 2048 }, { 9, 495, 2048 },
+   { 6, 496, 2048 }, { 7, 497, 2048 }, { 7, 498, 2048 }, { 8, 499, 2048 }, { 7, 500, 2048 }, { 8, 501, 2048 }, { 8, 502, 2048 }, { 9, 503, 2048 },
+   { 7, 504, 2048 }, { 8, 505, 2048 }, { 8, 506, 2048 }, { 9, 507, 2048 }, { 8, 508, 2048 }, { 9, 509, 2048 }, { 9, 510, 2048 }, { 10, 511, 2048 },
+   { 2, 512, 2048 }, { 3, 513, 2048 }, { 3, 514, 2048 }, { 4, 515, 2048 }, { 3, 516, 2048 }, { 4, 517, 2048 }, { 4, 518, 2048 }, { 5, 519, 2048 },
+   { 3, 520, 2048 }, { 4, 521, 2048 }, { 4, 522, 2048 }, { 5, 523, 2048 }, { 4, 524, 2048 }, { 5, 525, 2048 }, { 5, 526, 2048 }, { 6, 527, 2048 },
+   { 3, 528, 2048 }, { 4, 529, 2048 }, { 4, 530, 2048 }, { 5, 531, 2048 }, { 4, 532, 2048 }, { 5, 533, 2048 }, { 5, 534, 2048 }, { 6, 535, 2048 },
+   { 4, 536, 2048 }, { 5, 537, 2048 }, { 5, 538, 2048 }, { 6, 539, 2048 }, { 5, 540, 2048 }, { 6, 541, 2048 }, { 6, 542, 2048 }, { 7, 543, 2048 },
+   { 3, 544, 2048 }, { 4, 545, 2048 }, { 4, 546, 2048 }, { 5, 547, 2048 }, { 4, 548, 2048 }, { 5, 549, 2048 }, { 5, 550, 2048 }, { 6, 551, 2048 },
+   { 4, 552, 2048 }, { 5, 553, 2048 }, { 5, 554, 2048 }, { 6, 555, 2048 }, { 5, 556, 2048 }, { 6, 557, 2048 }, { 6, 558, 2048 }, { 7, 559, 2048 },
+   { 4, 560, 2048 }, { 5, 561, 2048 }, { 5, 562, 2048 }, { 6, 563, 2048 }, { 5, 564, 2048 }, { 6, 565, 2048 }, { 6, 566, 2048 }, { 7, 567, 2048 },
+   { 5, 568, 2048 }, { 6, 569, 2048 }, { 6, 570, 2048 }, { 7, 571, 2048 }, { 6, 572, 2048 }, { 7, 573, 2048 }, { 7, 574, 2048 }, { 8, 575, 2048 },
+   { 3, 576, 2048 }, { 4, 577, 2048 }, { 4, 578, 2048 }, { 5, 579, 2048 }, { 4, 580, 2048 }, { 5, 581, 2048 }, { 5, 582, 2048 }, { 6, 583, 2048 },
+   { 4, 584, 2048 }, { 5, 585, 2048 }, { 5, 586, 2048 }, { 6, 587, 2048 }, { 5, 588, 2048 }, { 6, 589, 2048 }, { 6, 590, 2048 }, { 7, 591, 2048 },
+   { 4, 592, 2048 }, { 5, 593, 2048 }, { 5, 594, 2048 }, { 6, 595, 2048 }, { 5, 596, 2048 }, { 6, 597, 2048 }, { 6, 598, 2048 }, { 7, 599, 2048 },
+   { 5, 600, 2048 }, { 6, 601, 2048 }, { 6, 602, 2048 }, { 7, 603, 2048 }, { 6, 604, 2048 }, { 7, 605, 2048 }, { 7, 606, 2048 }, { 8, 607, 2048 },
+   { 4, 608, 2048 }, { 5, 609, 2048 }, { 5, 610, 2048 }, { 6, 611, 2048 }, { 5, 612, 2048 }, { 6, 613, 2048 }, { 6, 614, 2048 }, { 7, 615, 2048 },
+   { 5, 616, 2048 }, { 6, 617, 2048 }, { 6, 618, 2048 }, { 7, 619, 2048 }, { 6, 620, 2048 }, { 7, 621, 2048 }, { 7, 622, 2048 }, { 8, 623, 2048 },
+   { 5, 624, 2048 }, { 6, 625, 2048 }, { 6, 626, 2048 }, { 7, 627, 2048 }, { 6, 628, 2048 }, { 7, 629, 2048 }, { 7, 630, 2048 }, { 8, 631, 2048 },
+   { 6, 632, 2048 }, { 7, 633, 2048 }, { 7, 634, 2048 }, { 8, 635, 2048 }, { 7, 636, 2048 }, { 8, 637, 2048 }, { 8, 638, 2048 }, { 9, 639, 2048 },
+   { 3, 640, 2048 }, { 4, 641, 2048 }, { 4, 642, 2048 }, { 5, 643, 2048 }, { 4, 644, 2048 }, { 5, 645, 2048 }, { 5, 646, 2048 }, { 6, 647, 2048 },
+   { 4, 648, 2048 }, { 5, 649, 2048 }, { 5, 650, 2048 }, { 6, 651, 2048 }, { 5, 652, 2048 }, { 6, 653, 2048 }, { 6, 654, 2048 }, { 7, 655, 2048 },
+   { 4, 656, 2048 }, { 5, 657, 2048 }, { 5, 658, 2048 }, { 6, 659, 2048 }, { 5, 660, 2048 }, { 6, 661, 2048 }, { 6, 662, 2048 }, { 7, 663, 2048 },
+   { 5, 664, 2048 }, { 6, 665, 2048 }, { 6, 666, 2048 }, { 7, 667, 2048 }, { 6, 668, 2048 }, { 7, 669, 2048 }, { 7, 670, 2048 }, { 8, 671, 2048 },
+   { 4, 672, 2048 }, { 5, 673, 2048 }, { 5, 674, 2048 }, { 6, 675, 2048 }, { 5, 676, 2048 }, { 6, 677, 2048 }, { 6, 678, 2048 }, { 7, 679, 2048 },
+   { 5, 680, 2048 }, { 6, 681, 2048 }, { 6, 682, 2048 }, { 7, 683, 2048 }, { 6, 684, 2048 }, { 7, 685, 2048 }, { 7, 686, 2048 }, { 8, 687, 2048 },
+   { 5, 688, 2048 }, { 6, 689, 2048 }, { 6, 690, 2048 }, { 7, 691, 2048 }, { 6, 692, 2048 }, { 7, 693, 2048 }, { 7, 694, 2048 }, { 8, 695, 2048 },
+   { 6, 696, 2048 }, { 7, 697, 2048 }, { 7, 698, 2048 }, { 8, 699, 2048 }, { 7, 700, 2048 }, { 8, 701, 2048 }, { 8, 702, 2048 }, { 9, 703, 2048 },
+   { 4, 704, 2048 }, { 5, 705, 2048 }, { 5, 706, 2048 }, { 6, 707, 2048 }, { 5, 708, 2048 }, { 6, 709, 2048 }, { 6, 710, 2048 }, { 7, 711, 2048 },
+   { 5, 712, 2048 }, { 6, 713, 2048 }, { 6, 714, 2048 }, { 7, 715, 2048 }, { 6, 716, 2048 }, { 7, 717, 2048 }, { 7, 718, 2048 }, { 8, 719, 2048 },
+   { 5, 720, 2048 }, { 6, 721, 2048 }, { 6, 722, 2048 }, { 7, 723, 2048 }, { 6, 724, 2048 }, { 7, 725, 2048 }, { 7, 726, 2048 }, { 8, 727, 2048 },
+   { 6, 728, 2048 }, { 7, 729, 2048 }, { 7, 730, 2048 }, { 8, 731, 2048 }, { 7, 732, 2048 }, { 8, 733, 2048 }, { 8, 734, 2048 }, { 9, 735, 2048 },
+   { 5, 736, 2048 }, { 6, 737, 2048 }, { 6, 738, 2048 }, { 7, 739, 2048 }, { 6, 740, 2048 }, { 7, 741, 2048 }, { 7, 742, 2048 }, { 8, 743, 2048 },
+   { 6, 744, 2048 }, { 7, 745, 2048 }, { 7, 746, 2048 }, { 8, 747, 2048 }, { 7, 748, 2048 }, { 8, 749, 2048 }, { 8, 750, 2048 }, { 9, 751, 2048 },
+   { 6, 752, 2048 }, { 7, 753, 2048 }, { 7, 754, 2048 }, { 8, 755, 2048 }, { 7, 756, 2048 }, { 8, 757, 2048 }, { 8, 758, 2048 }, { 9, 759, 2048 },
+   { 7, 760, 2048 }, { 8, 761, 2048 }, { 8, 762, 2048 }, { 9, 763, 2048 }, { 8, 764, 2048 }, { 9, 765, 2048 }, { 9, 766, 2048 }, { 10, 767, 2048 },
+   { 3, 768, 2048 }, { 4, 769, 2048 }, { 4, 770, 2048 }, { 5, 771, 2048 }, { 4, 772, 2048 }, { 5, 773, 2048 }, { 5, 774, 2048 }, { 6, 775, 2048 },
+   { 4, 776, 2048 }, { 5, 777, 2048 }, { 5, 778, 2048 }, { 6, 779, 2048 }, { 5, 780, 2048 }, { 6, 781, 2048 }, { 6, 782, 2048 }, { 7, 783, 2048 },
+   { 4, 784, 2048 }, { 5, 785, 2048 }, { 5, 786, 2048 }, { 6, 787, 2048 }, { 5, 788, 2048 }, { 6, 789, 2048 }, { 6, 790, 2048 }, { 7, 791, 2048 },
+   { 5, 792, 2048 }, { 6, 793, 2048 }, { 6, 794, 2048 }, { 7, 795, 2048 }, { 6, 796, 2048 }, { 7, 797, 2048 }, { 7, 798, 2048 }, { 8, 799, 2048 },
+   { 4, 800, 2048 }, { 5, 801, 2048 }, { 5, 802, 2048 }, { 6, 803, 2048 }, { 5, 804, 2048 }, { 6, 805, 2048 }, { 6, 806, 2048 }, { 7, 807, 2048 },
+   { 5, 808, 2048 }, { 6, 809, 2048 }, { 6, 810, 2048 }, { 7, 811, 2048 }, { 6, 812, 2048 }, { 7, 813, 2048 }, { 7, 814, 2048 }, { 8, 815, 2048 },
+   { 5, 816, 2048 }, { 6, 817, 2048 }, { 6, 818, 2048 }, { 7, 819, 2048 }, { 6, 820, 2048 }, { 7, 821, 2048 }, { 7, 822, 2048 }, { 8, 823, 2048 },
+   { 6, 824, 2048 }, { 7, 825, 2048 }, { 7, 826, 2048 }, { 8, 827, 2048 }, { 7, 828, 2048 }, { 8, 829, 2048 }, { 8, 830, 2048 }, { 9, 831, 2048 },
+   { 4, 832, 2048 }, { 5, 833, 2048 }, { 5, 834, 2048 }, { 6, 835, 2048 }, { 5, 836, 2048 }, { 6, 837, 2048 }, { 6, 838, 2048 }, { 7, 839, 2048 },
+   { 5, 840, 2048 }, { 6, 841, 2048 }, { 6, 842, 2048 }, { 7, 843, 2048 }, { 6, 844, 2048 }, { 7, 845, 2048 }, { 7, 846, 2048 }, { 8, 847, 2048 },
+   { 5, 848, 2048 }, { 6, 849, 2048 }, { 6, 850, 2048 }, { 7, 851, 2048 }, { 6, 852, 2048 }, { 7, 853, 2048 }, { 7, 854, 2048 }, { 8, 855, 2048 },
+   { 6, 856, 2048 }, { 7, 857, 2048 }, { 7, 858, 2048 }, { 8, 859, 2048 }, { 7, 860, 2048 }, { 8, 861, 2048 }, { 8, 862, 2048 }, { 9, 863, 2048 },
+   { 5, 864, 2048 }, { 6, 865, 2048 }, { 6, 866, 2048 }, { 7, 867, 2048 }, { 6, 868, 2048 }, { 7, 869, 2048 }, { 7, 870, 2048 }, { 8, 871, 2048 },
+   { 6, 872, 2048 }, { 7, 873, 2048 }, { 7, 874, 2048 }, { 8, 875, 2048 }, { 7, 876, 2048 }, { 8, 877, 2048 }, { 8, 878, 2048 }, { 9, 879, 2048 },
+   { 6, 880, 2048 }, { 7, 881, 2048 }, { 7, 882, 2048 }, { 8, 883, 2048 }, { 7, 884, 2048 }, { 8, 885, 2048 }, { 8, 886, 2048 }, { 9, 887, 2048 },
+   { 7, 888, 2048 }, { 8, 889, 2048 }, { 8, 890, 2048 }, { 9, 891, 2048 }, { 8, 892, 2048 }, { 9, 893, 2048 }, { 9, 894, 2048 }, { 10, 895, 2048 },
+   { 4, 896, 2048 }, { 5, 897, 2048 }, { 5, 898, 2048 }, { 6, 899, 2048 }, { 5, 900, 2048 }, { 6, 901, 2048 }, { 6, 902, 2048 }, { 7, 903, 2048 },
+   { 5, 904, 2048 }, { 6, 905, 2048 }, { 6, 906, 2048 }, { 7, 907, 2048 }, { 6, 908, 2048 }, { 7, 909, 2048 }, { 7, 910, 2048 }, { 8, 911, 2048 },
+   { 5, 912, 2048 }, { 6, 913, 2048 }, { 6, 914, 2048 }, { 7, 915, 2048 }, { 6, 916, 2048 }, { 7, 917, 2048 }, { 7, 918, 2048 }, { 8, 919, 2048 },
+   { 6, 920, 2048 }, { 7, 921, 2048 }, { 7, 922, 2048 }, { 8, 923, 2048 }, { 7, 924, 2048 }, { 8, 925, 2048 }, { 8, 926, 2048 }, { 9, 927, 2048 },
+   { 5, 928, 2048 }, { 6, 929, 2048 }, { 6, 930, 2048 }, { 7, 931, 2048 }, { 6, 932, 2048 }, { 7, 933, 2048 }, { 7, 934, 2048 }, { 8, 935, 2048 },
+   { 6, 936, 2048 }, { 7, 937, 2048 }, { 7, 938, 2048 }, { 8, 939, 2048 }, { 7, 940, 2048 }, { 8, 941, 2048 }, { 8, 942, 2048 }, { 9, 943, 2048 },
+   { 6, 944, 2048 }, { 7, 945, 2048 }, { 7, 946, 2048 }, { 8, 947, 2048 }, { 7, 948, 2048 }, { 8, 949, 2048 }, { 8, 950, 2048 }, { 9, 951, 2048 },
+   { 7, 952, 2048 }, { 8, 953, 2048 }, { 8, 954, 2048 }, { 9, 955, 2048 }, { 8, 956, 2048 }, { 9, 957, 2048 }, { 9, 958, 2048 }, { 10, 959, 2048 },
+   { 5, 960, 2048 }, { 6, 961, 2048 }, { 6, 962, 2048 }, { 7, 963, 2048 }, { 6, 964, 2048 }, { 7, 965, 2048 }, { 7, 966, 2048 }, { 8, 967, 2048 },
+   { 6, 968, 2048 }, { 7, 969, 2048 }, { 7, 970, 2048 }, { 8, 971, 2048 }, { 7, 972, 2048 }, { 8, 973, 2048 }, { 8, 974, 2048 }, { 9, 975, 2048 },
+   { 6, 976, 2048 }, { 7, 977, 2048 }, { 7, 978, 2048 }, { 8, 979, 2048 }, { 7, 980, 2048 }, { 8, 981, 2048 }, { 8, 982, 2048 }, { 9, 983, 2048 },
+   { 7, 984, 2048 }, { 8, 985, 2048 }, { 8, 986, 2048 }, { 9, 987, 2048 }, { 8, 988, 2048 }, { 9, 989, 2048 }, { 9, 990, 2048 }, { 10, 991, 2048 },
+   { 6, 992, 2048 }, { 7, 993, 2048 }, { 7, 994, 2048 }, { 8, 995, 2048 }, { 7, 996, 2048 }, { 8, 997, 2048 }, { 8, 998, 2048 }, { 9, 999, 2048 },
+   { 7, 1000, 2048 }, { 8, 1001, 2048 }, { 8, 1002, 2048 }, { 9, 1003, 2048 }, { 8, 1004, 2048 }, { 9, 1005, 2048 }, { 9, 1006, 2048 }, { 10, 1007, 2048 },
+   { 7, 1008, 2048 }, { 8, 1009, 2048 }, { 8, 1010, 2048 }, { 9, 1011, 2048 }, { 8, 1012, 2048 }, { 9, 1013, 2048 }, { 9, 1014, 2048 }, { 10, 1015, 2048 },
+   { 8, 1016, 2048 }, { 9, 1017, 2048 }, { 9, 1018, 2048 }, { 10, 1019, 2048 }, { 9, 1020, 2048 }, { 10, 1021, 2048 }, { 10, 1022, 2048 }, { 11, 1023, 2048 },
+   { 2, 1024, 2048 }, { 3, 1025, 2048 }, { 3, 1026, 2048 }, { 4, 1027, 2048 }, { 3, 1028, 2048 }, { 4, 1029, 2048 }, { 4, 1030, 2048 }, { 5, 1031, 2048 },
+   { 3, 1032, 2048 }, { 4, 1033, 2048 }, { 4, 1034, 2048 }, { 5, 1035, 2048 }, { 4, 1036, 2048 }, { 5, 1037, 2048 }, { 5, 1038, 2048 }, { 6, 1039, 2048 },
+   { 3, 1040, 2048 }, { 4, 1041, 2048 }, { 4, 1042, 2048 }, { 5, 1043, 2048 }, { 4, 1044, 2048 }, { 5, 1045, 2048 }, { 5, 1046, 2048 }, { 6, 1047, 2048 },
+   { 4, 1048, 2048 }, { 5, 1049, 2048 }, { 5, 1050, 2048 }, { 6, 1051, 2048 }, { 5, 1052, 2048 }, { 6, 1053, 2048 }, { 6, 1054, 2048 }, { 7, 1055, 2048 },
+   { 3, 1056, 2048 }, { 4, 1057, 2048 }, { 4, 1058, 2048 }, { 5, 1059, 2048 }, { 4, 1060, 2048 }, { 5, 1061, 2048 }, { 5, 1062, 2048 }, { 6, 1063, 2048 },
+   { 4, 1064, 2048 }, { 5, 1065, 2048 }, { 5, 1066, 2048 }, { 6, 1067, 2048 }, { 5, 1068, 2048 }, { 6, 1069, 2048 }, { 6, 1070, 2048 }, { 7, 1071, 2048 },
+   { 4, 1072, 2048 }, { 5, 1073, 2048 }, { 5, 1074, 2048 }, { 6, 1075, 2048 }, { 5, 1076, 2048 }, { 6, 1077, 2048 }, { 6, 1078, 2048 }, { 7, 1079, 2048 },
+   { 5, 1080, 2048 }, { 6, 1081, 2048 }, { 6, 1082, 2048 }, { 7, 1083, 2048 }, { 6, 1084, 2048 }, { 7, 1085, 2048 }, { 7, 1086, 2048 }, { 8, 1087, 2048 },
+   { 3, 1088, 2048 }, { 4, 1089, 2048 }, { 4, 1090, 2048 }, { 5, 1091, 2048 }, { 4, 1092, 2048 }, { 5, 1093, 2048 }, { 5, 1094, 2048 }, { 6, 1095, 2048 },
+   { 4, 1096, 2048 }, { 5, 1097, 2048 }, { 5, 1098, 2048 }, { 6, 1099, 2048 }, { 5, 1100, 2048 }, { 6, 1101, 2048 }, { 6, 1102, 2048 }, { 7, 1103, 2048 },
+   { 4, 1104, 2048 }, { 5, 1105, 2048 }, { 5, 1106, 2048 }, { 6, 1107, 2048 }, { 5, 1108, 2048 }, { 6, 1109, 2048 }, { 6, 1110, 2048 }, { 7, 1111, 2048 },
+   { 5, 1112, 2048 }, { 6, 1113, 2048 }, { 6, 1114, 2048 }, { 7, 1115, 2048 }, { 6, 1116, 2048 }, { 7, 1117, 2048 }, { 7, 1118, 2048 }, { 8, 1119, 2048 },
+   { 4, 1120, 2048 }, { 5, 1121, 2048 }, { 5, 1122, 2048 }, { 6, 1123, 2048 }, { 5, 1124, 2048 }, { 6, 1125, 2048 }, { 6, 1126, 2048 }, { 7, 1127, 2048 },
+   { 5, 1128, 2048 }, { 6, 1129, 2048 }, { 6, 1130, 2048 }, { 7, 1131, 2048 }, { 6, 1132, 2048 }, { 7, 1133, 2048 }, { 7, 1134, 2048 }, { 8, 1135, 2048 },
+   { 5, 1136, 2048 }, { 6, 1137, 2048 }, { 6, 1138, 2048 }, { 7, 1139, 2048 }, { 6, 1140, 2048 }, { 7, 1141, 2048 }, { 7, 1142, 2048 }, { 8, 1143, 2048 },
+   { 6, 1144, 2048 }, { 7, 1145, 2048 }, { 7, 1146, 2048 }, { 8, 1147, 2048 }, { 7, 1148, 2048 }, { 8, 1149, 2048 }, { 8, 1150, 2048 }, { 9, 1151, 2048 },
+   { 3, 1152, 2048 }, { 4, 1153, 2048 }, { 4, 1154, 2048 }, { 5, 1155, 2048 }, { 4, 1156, 2048 }, { 5, 1157, 2048 }, { 5, 1158, 2048 }, { 6, 1159, 2048 },
+   { 4, 1160, 2048 }, { 5, 1161, 2048 }, { 5, 1162, 2048 }, { 6, 1163, 2048 }, { 5, 1164, 2048 }, { 6, 1165, 2048 }, { 6, 1166, 2048 }, { 7, 1167, 2048 },
+   { 4, 1168, 2048 }, { 5, 1169, 2048 }, { 5, 1170, 2048 }, { 6, 1171, 2048 }, { 5, 1172, 2048 }, { 6, 1173, 2048 }, { 6, 1174, 2048 }, { 7, 1175, 2048 },
+   { 5, 1176, 2048 }, { 6, 1177, 2048 }, { 6, 1178, 2048 }, { 7, 1179, 2048 }, { 6, 1180, 2048 }, { 7, 1181, 2048 }, { 7, 1182, 2048 }, { 8, 1183, 2048 },
+   { 4, 1184, 2048 }, { 5, 1185, 2048 }, { 5, 1186, 2048 }, { 6, 1187, 2048 }, { 5, 1188, 2048 }, { 6, 1189, 2048 }, { 6, 1190, 2048 }, { 7, 1191, 2048 },
+   { 5, 1192, 2048 }, { 6, 1193, 2048 }, { 6, 1194, 2048 }, { 7, 1195, 2048 }, { 6, 1196, 2048 }, { 7, 1197, 2048 }, { 7, 1198, 2048 }, { 8, 1199, 2048 },
+   { 5, 1200, 2048 }, { 6, 1201, 2048 }, { 6, 1202, 2048 }, { 7, 1203, 2048 }, { 6, 1204, 2048 }, { 7, 1205, 2048 }, { 7, 1206, 2048 }, { 8, 1207, 2048 },
+   { 6, 1208, 2048 }, { 7, 1209, 2048 }, { 7, 1210, 2048 }, { 8, 1211, 2048 }, { 7, 1212, 2048 }, { 8, 1213, 2048 }, { 8, 1214, 2048 }, { 9, 1215, 2048 },
+   { 4, 1216, 2048 }, { 5, 1217, 2048 }, { 5, 1218, 2048 }, { 6, 1219, 2048 }, { 5, 1220, 2048 }, { 6, 1221, 2048 }, { 6, 1222, 2048 }, { 7, 1223, 2048 },
+   { 5, 1224, 2048 }, { 6, 1225, 2048 }, { 6, 1226, 2048 }, { 7, 1227, 2048 }, { 6, 1228, 2048 }, { 7, 1229, 2048 }, { 7, 1230, 2048 }, { 8, 1231, 2048 },
+   { 5, 1232, 2048 }, { 6, 1233, 2048 }, { 6, 1234, 2048 }, { 7, 1235, 2048 }, { 6, 1236, 2048 }, { 7, 1237, 2048 }, { 7, 1238, 2048 }, { 8, 1239, 2048 },
+   { 6, 1240, 2048 }, { 7, 1241, 2048 }, { 7, 1242, 2048 }, { 8, 1243, 2048 }, { 7, 1244, 2048 }, { 8, 1245, 2048 }, { 8, 1246, 2048 }, { 9, 1247, 2048 },
+   { 5, 1248, 2048 }, { 6, 1249, 2048 }, { 6, 1250, 2048 }, { 7, 1251, 2048 }, { 6, 1252, 2048 }, { 7, 1253, 2048 }, { 7, 1254, 2048 }, { 8, 1255, 2048 },
+   { 6, 1256, 2048 }, { 7, 1257, 2048 }, { 7, 1258, 2048 }, { 8, 1259, 2048 }, { 7, 1260, 2048 }, { 8, 1261, 2048 }, { 8, 1262, 2048 }, { 9, 1263, 2048 },
+   { 6, 1264, 2048 }, { 7, 1265, 2048 }, { 7, 1266, 2048 }, { 8, 1267, 2048 }, { 7, 1268, 2048 }, { 8, 1269, 2048 }, { 8, 1270, 2048 }, { 9, 1271, 2048 },
+   { 7, 1272, 2048 }, { 8, 1273, 2048 }, { 8, 1274, 2048 }, { 9, 1275, 2048 }, { 8, 1276, 2048 }, { 9, 1277, 2048 }, { 9, 1278, 2048 }, { 10, 1279, 2048 },
+   { 3, 1280, 2048 }, { 4, 1281, 2048 }, { 4, 1282, 2048 }, { 5, 1283, 2048 }, { 4, 1284, 2048 }, { 5, 1285, 2048 }, { 5, 1286, 2048 }, { 6, 1287, 2048 },
+   { 4, 1288, 2048 }, { 5, 1289, 2048 }, { 5, 1290, 2048 }, { 6, 1291, 2048 }, { 5, 1292, 2048 }, { 6, 1293, 2048 }, { 6, 1294, 2048 }, { 7, 1295, 2048 },
+   { 4, 1296, 2048 }, { 5, 1297, 2048 }, { 5, 1298, 2048 }, { 6, 1299, 2048 }, { 5, 1300, 2048 }, { 6, 1301, 2048 }, { 6, 1302, 2048 }, { 7, 1303, 2048 },
+   { 5, 1304, 2048 }, { 6, 1305, 2048 }, { 6, 1306, 2048 }, { 7, 1307, 2048 }, { 6, 1308, 2048 }, { 7, 1309, 2048 }, { 7, 1310, 2048 }, { 8, 1311, 2048 },
+   { 4, 1312, 2048 }, { 5, 1313, 2048 }, { 5, 1314, 2048 }, { 6, 1315, 2048 }, { 5, 1316, 2048 }, { 6, 1317, 2048 }, { 6, 1318, 2048 }, { 7, 1319, 2048 },
+   { 5, 1320, 2048 }, { 6, 1321, 2048 }, { 6, 1322, 2048 }, { 7, 1323, 2048 }, { 6, 1324, 2048 }, { 7, 1325, 2048 }, { 7, 1326, 2048 }, { 8, 1327, 2048 },
+   { 5, 1328, 2048 }, { 6, 1329, 2048 }, { 6, 1330, 2048 }, { 7, 1331, 2048 }, { 6, 1332, 2048 }, { 7, 1333, 2048 }, { 7, 1334, 2048 }, { 8, 1335, 2048 },
+   { 6, 1336, 2048 }, { 7, 1337, 2048 }, { 7, 1338, 2048 }, { 8, 1339, 2048 }, { 7, 1340, 2048 }, { 8, 1341, 2048 }, { 8, 1342, 2048 }, { 9, 1343, 2048 },
+   { 4, 1344, 2048 }, { 5, 1345, 2048 }, { 5, 1346, 2048 }, { 6, 1347, 2048 }, { 5, 1348, 2048 }, { 6, 1349, 2048 }, { 6, 1350, 2048 }, { 7, 1351, 2048 },
+   { 5, 1352, 2048 }, { 6, 1353, 2048 }, { 6, 1354, 2048 }, { 7, 1355, 2048 }, { 6, 1356, 2048 }, { 7, 1357, 2048 }, { 7, 1358, 2048 }, { 8, 1359, 2048 },
+   { 5, 1360, 2048 }, { 6, 1361, 2048 }, { 6, 1362, 2048 }, { 7, 1363, 2048 }, { 6, 1364, 2048 }, { 7, 1365, 2048 }, { 7, 1366, 2048 }, { 8, 1367, 2048 },
+   { 6, 1368, 2048 }, { 7, 1369, 2048 }, { 7, 1370, 2048 }, { 8, 1371, 2048 }, { 7, 1372, 2048 }, { 8, 1373, 2048 }, { 8, 1374, 2048 }, { 9, 1375, 2048 },
+   { 5, 1376, 2048 }, { 6, 1377, 2048 }, { 6, 1378, 2048 }, { 7, 1379, 2048 }, { 6, 1380, 2048 }, { 7, 1381, 2048 }, { 7, 1382, 2048 }, { 8, 1383, 2048 },
+   { 6, 1384, 2048 }, { 7, 1385, 2048 }, { 7, 1386, 2048 }, { 8, 1387, 2048 }, { 7, 1388, 2048 }, { 8, 1389, 2048 }, { 8, 1390, 2048 }, { 9, 1391, 2048 },
+   { 6, 1392, 2048 }, { 7, 1393, 2048 }, { 7, 1394, 2048 }, { 8, 1395, 2048 }, { 7, 1396, 2048 }, { 8, 1397, 2048 }, { 8, 1398, 2048 }, { 9, 1399, 2048 },
+   { 7, 1400, 2048 }, { 8, 1401, 2048 }, { 8, 1402, 2048 }, { 9, 1403, 2048 }, { 8, 1404, 2048 }, { 9, 1405, 2048 }, { 9, 1406, 2048 }, { 10, 1407, 2048 },
+   { 4, 1408, 2048 }, { 5, 1409, 2048 }, { 5, 1410, 2048 }, { 6, 1411, 2048 }, { 5, 1412, 2048 }, { 6, 1413, 2048 }, { 6, 1414, 2048 }, { 7, 1415, 2048 },
+   { 5, 1416, 2048 }, { 6, 1417, 2048 }, { 6, 1418, 2048 }, { 7, 1419, 2048 }, { 6, 1420, 2048 }, { 7, 1421, 2048 }, { 7, 1422, 2048 }, { 8, 1423, 2048 },
+   { 5, 1424, 2048 }, { 6, 1425, 2048 }, { 6, 1426, 2048 }, { 7, 1427, 2048 }, { 6, 1428, 2048 }, { 7, 1429, 2048 }, { 7, 1430, 2048 }, { 8, 1431, 2048 },
+   { 6, 1432, 2048 }, { 7, 1433, 2048 }, { 7, 1434, 2048 }, { 8, 1435, 2048 }, { 7, 1436, 2048 }, { 8, 1437, 2048 }, { 8, 1438, 2048 }, { 9, 1439, 2048 },
+   { 5, 1440, 2048 }, { 6, 1441, 2048 }, { 6, 1442, 2048 }, { 7, 1443, 2048 }, { 6, 1444, 2048 }, { 7, 1445, 2048 }, { 7, 1446, 2048 }, { 8, 1447, 2048 },
+   { 6, 1448, 2048 }, { 7, 1449, 2048 }, { 7, 1450, 2048 }, { 8, 1451, 2048 }, { 7, 1452, 2048 }, { 8, 1453, 2048 }, { 8, 1454, 2048 }, { 9, 1455, 2048 },
+   { 6, 1456, 2048 }, { 7, 1457, 2048 }, { 7, 1458, 2048 }, { 8, 1459, 2048 }, { 7, 1460, 2048 }, { 8, 1461, 2048 }, { 8, 1462, 2048 }, { 9, 1463, 2048 },
+   { 7, 1464, 2048 }, { 8, 1465, 2048 }, { 8, 1466, 2048 }, { 9, 1467, 2048 }, { 8, 1468, 2048 }, { 9, 1469, 2048 }, { 9, 1470, 2048 }, { 10, 1471, 2048 },
+   { 5, 1472, 2048 }, { 6, 1473, 2048 }, { 6, 1474, 2048 }, { 7, 1475, 2048 }, { 6, 1476, 2048 }, { 7, 1477, 2048 }, { 7, 1478, 2048 }, { 8, 1479, 2048 },
+   { 6, 1480, 2048 }, { 7, 1481, 2048 }, { 7, 1482, 2048 }, { 8, 1483, 2048 }, { 7, 1484, 2048 }, { 8, 1485, 2048 }, { 8, 1486, 2048 }, { 9, 1487, 2048 },
+   { 6, 1488, 2048 }, { 7, 1489, 2048 }, { 7, 1490, 2048 }, { 8, 1491, 2048 }, { 7, 1492, 2048 }, { 8, 1493, 2048 }, { 8, 1494, 2048 }, { 9, 1495, 2048 },
+   { 7, 1496, 2048 }, { 8, 1497, 2048 }, { 8, 1498, 2048 }, { 9, 1499, 2048 }, { 8, 1500, 2048 }, { 9, 1501, 2048 }, { 9, 1502, 2048 }, { 10, 1503, 2048 },
+   { 6, 1504, 2048 }, { 7, 1505, 2048 }, { 7, 1506, 2048 }, { 8, 1507, 2048 }, { 7, 1508, 2048 }, { 8, 1509, 2048 }, { 8, 1510, 2048 }, { 9, 1511, 2048 },
+   { 7, 1512, 2048 }, { 8, 1513, 2048 }, { 8, 1514, 2048 }, { 9, 1515, 2048 }, { 8, 1516, 2048 }, { 9, 1517, 2048 }, { 9, 1518, 2048 }, { 10, 1519, 2048 },
+   { 7, 1520, 2048 }, { 8, 1521, 2048 }, { 8, 1522, 2048 }, { 9, 1523, 2048 }, { 8, 1524, 2048 }, { 9, 1525, 2048 }, { 9, 1526, 2048 }, { 10, 1527, 2048 },
+   { 8, 1528, 2048 }, { 9, 1529, 2048 }, { 9, 1530, 2048 }, { 10, 1531, 2048 }, { 9, 1532, 2048 }, { 10, 1533, 2048 }, { 10, 1534, 2048 }, { 11, 1535, 2048 },
+   { 3, 1536, 2048 }, { 4, 1537, 2048 }, { 4, 1538, 2048 }, { 5, 1539, 2048 }, { 4, 1540, 2048 }, { 5, 1541, 2048 }, { 5, 1542, 2048 }, { 6, 1543, 2048 },
+   { 4, 1544, 2048 }, { 5, 1545, 2048 }, { 5, 1546, 2048 }, { 6, 1547, 2048 }, { 5, 1548, 2048 }, { 6, 1549, 2048 }, { 6, 1550, 2048 }, { 7, 1551, 2048 },
+   { 4, 1552, 2048 }, { 5, 1553, 2048 }, { 5, 1554, 2048 }, { 6, 1555, 2048 }, { 5, 1556, 2048 }, { 6, 1557, 2048 }, { 6, 1558, 2048 }, { 7, 1559, 2048 },
+   { 5, 1560, 2048 }, { 6, 1561, 2048 }, { 6, 1562, 2048 }, { 7, 1563, 2048 }, { 6, 1564, 2048 }, { 7, 1565, 2048 }, { 7, 1566, 2048 }, { 8, 1567, 2048 },
+   { 4, 1568, 2048 }, { 5, 1569, 2048 }, { 5, 1570, 2048 }, { 6, 1571, 2048 }, { 5, 1572, 2048 }, { 6, 1573, 2048 }, { 6, 1574, 2048 }, { 7, 1575, 2048 },
+   { 5, 1576, 2048 }, { 6, 1577, 2048 }, { 6, 1578, 2048 }, { 7, 1579, 2048 }, { 6, 1580, 2048 }, { 7, 1581, 2048 }, { 7, 1582, 2048 }, { 8, 1583, 2048 },
+   { 5, 1584, 2048 }, { 6, 1585, 2048 }, { 6, 1586, 2048 }, { 7, 1587, 2048 }, { 6, 1588, 2048 }, { 7, 1589, 2048 }, { 7, 1590, 2048 }, { 8, 1591, 2048 },
+   { 6, 1592, 2048 }, { 7, 1593, 2048 }, { 7, 1594, 2048 }, { 8, 1595, 2048 }, { 7, 1596, 2048 }, { 8, 1597, 2048 }, { 8, 1598, 2048 }, { 9, 1599, 2048 },
+   { 4, 1600, 2048 }, { 5, 1601, 2048 }, { 5, 1602, 2048 }, { 6, 1603, 2048 }, { 5, 1604, 2048 }, { 6, 1605, 2048 }, { 6, 1606, 2048 }, { 7, 1607, 2048 },
+   { 5, 1608, 2048 }, { 6, 1609, 2048 }, { 6, 1610, 2048 }, { 7, 1611, 2048 }, { 6, 1612, 2048 }, { 7, 1613, 2048 }, { 7, 1614, 2048 }, { 8, 1615, 2048 },
+   { 5, 1616, 2048 }, { 6, 1617, 2048 }, { 6, 1618, 2048 }, { 7, 1619, 2048 }, { 6, 1620, 2048 }, { 7, 1621, 2048 }, { 7, 1622, 2048 }, { 8, 1623, 2048 },
+   { 6, 1624, 2048 }, { 7, 1625, 2048 }, { 7, 1626, 2048 }, { 8, 1627, 2048 }, { 7, 1628, 2048 }, { 8, 1629, 2048 }, { 8, 1630, 2048 }, { 9, 1631, 2048 },
+   { 5, 1632, 2048 }, { 6, 1633, 2048 }, { 6, 1634, 2048 }, { 7, 1635, 2048 }, { 6, 1636, 2048 }, { 7, 1637, 2048 }, { 7, 1638, 2048 }, { 8, 1639, 2048 },
+   { 6, 1640, 2048 }, { 7, 1641, 2048 }, { 7, 1642, 2048 }, { 8, 1643, 2048 }, { 7, 1644, 2048 }, { 8, 1645, 2048 }, { 8, 1646, 2048 }, { 9, 1647, 2048 },
+   { 6, 1648, 2048 }, { 7, 1649, 2048 }, { 7, 1650, 2048 }, { 8, 1651, 2048 }, { 7, 1652, 2048 }, { 8, 1653, 2048 }, { 8, 1654, 2048 }, { 9, 1655, 2048 },
+   { 7, 1656, 2048 }, { 8, 1657, 2048 }, { 8, 1658, 2048 }, { 9, 1659, 2048 }, { 8, 1660, 2048 }, { 9, 1661, 2048 }, { 9, 1662, 2048 }, { 10, 1663, 2048 },
+   { 4, 1664, 2048 }, { 5, 1665, 2048 }, { 5, 1666, 2048 }, { 6, 1667, 2048 }, { 5, 1668, 2048 }, { 6, 1669, 2048 }, { 6, 1670, 2048 }, { 7, 1671, 2048 },
+   { 5, 1672, 2048 }, { 6, 1673, 2048 }, { 6, 1674, 2048 }, { 7, 1675, 2048 }, { 6, 1676, 2048 }, { 7, 1677, 2048 }, { 7, 1678, 2048 }, { 8, 1679, 2048 },
+   { 5, 1680, 2048 }, { 6, 1681, 2048 }, { 6, 1682, 2048 }, { 7, 1683, 2048 }, { 6, 1684, 2048 }, { 7, 1685, 2048 }, { 7, 1686, 2048 }, { 8, 1687, 2048 },
+   { 6, 1688, 2048 }, { 7, 1689, 2048 }, { 7, 1690, 2048 }, { 8, 1691, 2048 }, { 7, 1692, 2048 }, { 8, 1693, 2048 }, { 8, 1694, 2048 }, { 9, 1695, 2048 },
+   { 5, 1696, 2048 }, { 6, 1697, 2048 }, { 6, 1698, 2048 }, { 7, 1699, 2048 }, { 6, 1700, 2048 }, { 7, 1701, 2048 }, { 7, 1702, 2048 }, { 8, 1703, 2048 },
+   { 6, 1704, 2048 }, { 7, 1705, 2048 }, { 7, 1706, 2048 }, { 8, 1707, 2048 }, { 7, 1708, 2048 }, { 8, 1709, 2048 }, { 8, 1710, 2048 }, { 9, 1711, 2048 },
+   { 6, 1712, 2048 }, { 7, 1713, 2048 }, { 7, 1714, 2048 }, { 8, 1715, 2048 }, { 7, 1716, 2048 }, { 8, 1717, 2048 }, { 8, 1718, 2048 }, { 9, 1719, 2048 },
+   { 7, 1720, 2048 }, { 8, 1721, 2048 }, { 8, 1722, 2048 }, { 9, 1723, 2048 }, { 8, 1724, 2048 }, { 9, 1725, 2048 }, { 9, 1726, 2048 }, { 10, 1727, 2048 },
+   { 5, 1728, 2048 }, { 6, 1729, 2048 }, { 6, 1730, 2048 }, { 7, 1731, 2048 }, { 6, 1732, 2048 }, { 7, 1733, 2048 }, { 7, 1734, 2048 }, { 8, 1735, 2048 },
+   { 6, 1736, 2048 }, { 7, 1737, 2048 }, { 7, 1738, 2048 }, { 8, 1739, 2048 }, { 7, 1740, 2048 }, { 8, 1741, 2048 }, { 8, 1742, 2048 }, { 9, 1743, 2048 },
+   { 6, 1744, 2048 }, { 7, 1745, 2048 }, { 7, 1746, 2048 }, { 8, 1747, 2048 }, { 7, 1748, 2048 }, { 8, 1749, 2048 }, { 8, 1750, 2048 }, { 9, 1751, 2048 },
+   { 7, 1752, 2048 }, { 8, 1753, 2048 }, { 8, 1754, 2048 }, { 9, 1755, 2048 }, { 8, 1756, 2048 }, { 9, 1757, 2048 }, { 9, 1758, 2048 }, { 10, 1759, 2048 },
+   { 6, 1760, 2048 }, { 7, 1761, 2048 }, { 7, 1762, 2048 }, { 8, 1763, 2048 }, { 7, 1764, 2048 }, { 8, 1765, 2048 }, { 8, 1766, 2048 }, { 9, 1767, 2048 },
+   { 7, 1768, 2048 }, { 8, 1769, 2048 }, { 8, 1770, 2048 }, { 9, 1771, 2048 }, { 8, 1772, 2048 }, { 9, 1773, 2048 }, { 9, 1774, 2048 }, { 10, 1775, 2048 },
+   { 7, 1776, 2048 }, { 8, 1777, 2048 }, { 8, 1778, 2048 }, { 9, 1779, 2048 }, { 8, 1780, 2048 }, { 9, 1781, 2048 }, { 9, 1782, 2048 }, { 10, 1783, 2048 },
+   { 8, 1784, 2048 }, { 9, 1785, 2048 }, { 9, 1786, 2048 }, { 10, 1787, 2048 }, { 9, 1788, 2048 }, { 10, 1789, 2048 }, { 10, 1790, 2048 }, { 11, 1791, 2048 },
+   { 4, 1792, 2048 }, { 5, 1793, 2048 }, { 5, 1794, 2048 }, { 6, 1795, 2048 }, { 5, 1796, 2048 }, { 6, 1797, 2048 }, { 6, 1798, 2048 }, { 7, 1799, 2048 },
+   { 5, 1800, 2048 }, { 6, 1801, 2048 }, { 6, 1802, 2048 }, { 7, 1803, 2048 }, { 6, 1804, 2048 }, { 7, 1805, 2048 }, { 7, 1806, 2048 }, { 8, 1807, 2048 },
+   { 5, 1808, 2048 }, { 6, 1809, 2048 }, { 6, 1810, 2048 }, { 7, 1811, 2048 }, { 6, 1812, 2048 }, { 7, 1813, 2048 }, { 7, 1814, 2048 }, { 8, 1815, 2048 },
+   { 6, 1816, 2048 }, { 7, 1817, 2048 }, { 7, 1818, 2048 }, { 8, 1819, 2048 }, { 7, 1820, 2048 }, { 8, 1821, 2048 }, { 8, 1822, 2048 }, { 9, 1823, 2048 },
+   { 5, 1824, 2048 }, { 6, 1825, 2048 }, { 6, 1826, 2048 }, { 7, 1827, 2048 }, { 6, 1828, 2048 }, { 7, 1829, 2048 }, { 7, 1830, 2048 }, { 8, 1831, 2048 },
+   { 6, 1832, 2048 }, { 7, 1833, 2048 }, { 7, 1834, 2048 }, { 8, 1835, 2048 }, { 7, 1836, 2048 }, { 8, 1837, 2048 }, { 8, 1838, 2048 }, { 9, 1839, 2048 },
+   { 6, 1840, 2048 }, { 7, 1841, 2048 }, { 7, 1842, 2048 }, { 8, 1843, 2048 }, { 7, 1844, 2048 }, { 8, 1845, 2048 }, { 8, 1846, 2048 }, { 9, 1847, 2048 },
+   { 7, 1848, 2048 }, { 8, 1849, 2048 }, { 8, 1850, 2048 }, { 9, 1851, 2048 }, { 8, 1852, 2048 }, { 9, 1853, 2048 }, { 9, 1854, 2048 }, { 10, 1855, 2048 },
+   { 5, 1856, 2048 }, { 6, 1857, 2048 }, { 6, 1858, 2048 }, { 7, 1859, 2048 }, { 6, 1860, 2048 }, { 7, 1861, 2048 }, { 7, 1862, 2048 }, { 8, 1863, 2048 },
+   { 6, 1864, 2048 }, { 7, 1865, 2048 }, { 7, 1866, 2048 }, { 8, 1867, 2048 }, { 7, 1868, 2048 }, { 8, 1869, 2048 }, { 8, 1870, 2048 }, { 9, 1871, 2048 },
+   { 6, 1872, 2048 }, { 7, 1873, 2048 }, { 7, 1874, 2048 }, { 8, 1875, 2048 }, { 7, 1876, 2048 }, { 8, 1877, 2048 }, { 8, 1878, 2048 }, { 9, 1879, 2048 },
+   { 7, 1880, 2048 }, { 8, 1881, 2048 }, { 8, 1882, 2048 }, { 9, 1883, 2048 }, { 8, 1884, 2048 }, { 9, 1885, 2048 }, { 9, 1886, 2048 }, { 10, 1887, 2048 },
+   { 6, 1888, 2048 }, { 7, 1889, 2048 }, { 7, 1890, 2048 }, { 8, 1891, 2048 }, { 7, 1892, 2048 }, { 8, 1893, 2048 }, { 8, 1894, 2048 }, { 9, 1895, 2048 },
+   { 7, 1896, 2048 }, { 8, 1897, 2048 }, { 8, 1898, 2048 }, { 9, 1899, 2048 }, { 8, 1900, 2048 }, { 9, 1901, 2048 }, { 9, 1902, 2048 }, { 10, 1903, 2048 },
+   { 7, 1904, 2048 }, { 8, 1905, 2048 }, { 8, 1906, 2048 }, { 9, 1907, 2048 }, { 8, 1908, 2048 }, { 9, 1909, 2048 }, { 9, 1910, 2048 }, { 10, 1911, 2048 },
+   { 8, 1912, 2048 }, { 9, 1913, 2048 }, { 9, 1914, 2048 }, { 10, 1915, 2048 }, { 9, 1916, 2048 }, { 10, 1917, 2048 }, { 10, 1918, 2048 }, { 11, 1919, 2048 },
+   { 5, 1920, 2048 }, { 6, 1921, 2048 }, { 6, 1922, 2048 }, { 7, 1923, 2048 }, { 6, 1924, 2048 }, { 7, 1925, 2048 }, { 7, 1926, 2048 }, { 8, 1927, 2048 },
+   { 6, 1928, 2048 }, { 7, 1929, 2048 }, { 7, 1930, 2048 }, { 8, 1931, 2048 }, { 7, 1932, 2048 }, { 8, 1933, 2048 }, { 8, 1934, 2048 }, { 9, 1935, 2048 },
+   { 6, 1936, 2048 }, { 7, 1937, 2048 }, { 7, 1938, 2048 }, { 8, 1939, 2048 }, { 7, 1940, 2048 }, { 8, 1941, 2048 }, { 8, 1942, 2048 }, { 9, 1943, 2048 },
+   { 7, 1944, 2048 }, { 8, 1945, 2048 }, { 8, 1946, 2048 }, { 9, 1947, 2048 }, { 8, 1948, 2048 }, { 9, 1949, 2048 }, { 9, 1950, 2048 }, { 10, 1951, 2048 },
+   { 6, 1952, 2048 }, { 7, 1953, 2048 }, { 7, 1954, 2048 }, { 8, 1955, 2048 }, { 7, 1956, 2048 }, { 8, 1957, 2048 }, { 8, 1958, 2048 }, { 9, 1959, 2048 },
+   { 7, 1960, 2048 }, { 8, 1961, 2048 }, { 8, 1962, 2048 }, { 9, 1963, 2048 }, { 8, 1964, 2048 }, { 9, 1965, 2048 }, { 9, 1966, 2048 }, { 10, 1967, 2048 },
+   { 7, 1968, 2048 }, { 8, 1969, 2048 }, { 8, 1970, 2048 }, { 9, 1971, 2048 }, { 8, 1972, 2048 }, { 9, 1973, 2048 }, { 9, 1974, 2048 }, { 10, 1975, 2048 },
+   { 8, 1976, 2048 }, { 9, 1977, 2048 }, { 9, 1978, 2048 }, { 10, 1979, 2048 }, { 9, 1980, 2048 }, { 10, 1981, 2048 }, { 10, 1982, 2048 }, { 11, 1983, 2048 },
+   { 6, 1984, 2048 }, { 7, 1985, 2048 }, { 7, 1986, 2048 }, { 8, 1987, 2048 }, { 7, 1988, 2048 }, { 8, 1989, 2048 }, { 8, 1990, 2048 }, { 9, 1991, 2048 },
+   { 7, 1992, 2048 }, { 8, 1993, 2048 }, { 8, 1994, 2048 }, { 9, 1995, 2048 }, { 8, 1996, 2048 }, { 9, 1997, 2048 }, { 9, 1998, 2048 }, { 10, 1999, 2048 },
+   { 7, 2000, 2048 }, { 8, 2001, 2048 }, { 8, 2002, 2048 }, { 9, 2003, 2048 }, { 8, 2004, 2048 }, { 9, 2005, 2048 }, { 9, 2006, 2048 }, { 10, 2007, 2048 },
+   { 8, 2008, 2048 }, { 9, 2009, 2048 }, { 9, 2010, 2048 }, { 10, 2011, 2048 }, { 9, 2012, 2048 }, { 10, 2013, 2048 }, { 10, 2014, 2048 }, { 11, 2015, 2048 },
+   { 7, 2016, 2048 }, { 8, 2017, 2048 }, { 8, 2018, 2048 }, { 9, 2019, 2048 }, { 8, 2020, 2048 }, { 9, 2021, 2048 }, { 9, 2022, 2048 }, { 10, 2023, 2048 },
+   { 8, 2024, 2048 }, { 9, 2025, 2048 }, { 9, 2026, 2048 }, { 10, 2027, 2048 }, { 9, 2028, 2048 }, { 10, 2029, 2048 }, { 10, 2030, 2048 }, { 11, 2031, 2048 },
+   { 8, 2032, 2048 }, { 9, 2033, 2048 }, { 9, 2034, 2048 }, { 10, 2035, 2048 }, { 9, 2036, 2048 }, { 10, 2037, 2048 }, { 10, 2038, 2048 }, { 11, 2039, 2048 },
+   { 9, 2040, 2048 }, { 10, 2041, 2048 }, { 10, 2042, 2048 }, { 11, 2043, 2048 }, { 10, 2044, 2048 }, { 11, 2045, 2048 }, { 11, 2046, 2048 }, { 12, 2047, 2048 },
+#endif
+#endif
+#endif
+#endif
+#endif
+#endif
+};
+
+
+/* find a hole and free as required, return -1 if no hole found */
+static int find_hole(void)
+{
+   unsigned x;
+   int      y, z;
+   for (z = -1, y = INT_MAX, x = 0; x < FP_ENTRIES; x++) {
+       if (fp_cache[x].lru_count < y && fp_cache[x].lock == 0) {
+          z = x;
+          y = fp_cache[x].lru_count;
+       }
+   }
+
+   /* decrease all */
+   for (x = 0; x < FP_ENTRIES; x++) {
+      if (fp_cache[x].lru_count > 3) {
+         --(fp_cache[x].lru_count);
+      }
+   }
+
+   /* free entry z */
+   if (z >= 0 && fp_cache[z].g) {
+      mp_clear(&fp_cache[z].mu);
+      wc_ecc_del_point(fp_cache[z].g);
+      fp_cache[z].g  = NULL;
+      for (x = 0; x < (1U<<FP_LUT); x++) {
+         wc_ecc_del_point(fp_cache[z].LUT[x]);
+         fp_cache[z].LUT[x] = NULL;
+      }
+      fp_cache[z].lru_count = 0;
+   }
+   return z;
+}
+
+/* determine if a base is already in the cache and if so, where */
+static int find_base(ecc_point* g)
+{
+   int x;
+   for (x = 0; x < FP_ENTRIES; x++) {
+      if (fp_cache[x].g != NULL &&
+          mp_cmp(fp_cache[x].g->x, g->x) == MP_EQ &&
+          mp_cmp(fp_cache[x].g->y, g->y) == MP_EQ &&
+          mp_cmp(fp_cache[x].g->z, g->z) == MP_EQ) {
+         break;
+      }
+   }
+   if (x == FP_ENTRIES) {
+      x = -1;
+   }
+   return x;
+}
+
+/* add a new base to the cache */
+static int add_entry(int idx, ecc_point *g)
+{
+   unsigned x, y;
+
+   /* allocate base and LUT */
+   fp_cache[idx].g = wc_ecc_new_point();
+   if (fp_cache[idx].g == NULL) {
+      return GEN_MEM_ERR;
+   }
+
+   /* copy x and y */
+   if ((mp_copy(g->x, fp_cache[idx].g->x) != MP_OKAY) ||
+       (mp_copy(g->y, fp_cache[idx].g->y) != MP_OKAY) ||
+       (mp_copy(g->z, fp_cache[idx].g->z) != MP_OKAY)) {
+      wc_ecc_del_point(fp_cache[idx].g);
+      fp_cache[idx].g = NULL;
+      return GEN_MEM_ERR;
+   }
+
+   for (x = 0; x < (1U<<FP_LUT); x++) {
+      fp_cache[idx].LUT[x] = wc_ecc_new_point();
+      if (fp_cache[idx].LUT[x] == NULL) {
+         for (y = 0; y < x; y++) {
+            wc_ecc_del_point(fp_cache[idx].LUT[y]);
+            fp_cache[idx].LUT[y] = NULL;
+         }
+         wc_ecc_del_point(fp_cache[idx].g);
+         fp_cache[idx].g         = NULL;
+         fp_cache[idx].lru_count = 0;
+         return GEN_MEM_ERR;
+      }
+   }
+
+   fp_cache[idx].lru_count = 0;
+
+   return MP_OKAY;
+}
+#endif
+
+#ifndef WOLFSSL_SP_MATH
+/* build the LUT by spacing the bits of the input by #modulus/FP_LUT bits apart
+ *
+ * The algorithm builds patterns in increasing bit order by first making all
+ * single bit input patterns, then all two bit input patterns and so on
+ */
+static int build_lut(int idx, mp_int* a, mp_int* modulus, mp_digit mp,
+    mp_int* mu)
+{
+   int err;
+   unsigned x, y, bitlen, lut_gap;
+   mp_int tmp;
+
+   if (mp_init(&tmp) != MP_OKAY)
+       return GEN_MEM_ERR;
+
+   /* sanity check to make sure lut_order table is of correct size,
+      should compile out to a NOP if true */
+   if ((sizeof(lut_orders) / sizeof(lut_orders[0])) < (1U<<FP_LUT)) {
+       err = BAD_FUNC_ARG;
+   }
+   else {
+    /* get bitlen and round up to next multiple of FP_LUT */
+    bitlen  = mp_unsigned_bin_size(modulus) << 3;
+    x       = bitlen % FP_LUT;
+    if (x) {
+      bitlen += FP_LUT - x;
+    }
+    lut_gap = bitlen / FP_LUT;
+
+    /* init the mu */
+    err = mp_init_copy(&fp_cache[idx].mu, mu);
+   }
+
+   /* copy base */
+   if (err == MP_OKAY) {
+     if ((mp_mulmod(fp_cache[idx].g->x, mu, modulus,
+                  fp_cache[idx].LUT[1]->x) != MP_OKAY) ||
+         (mp_mulmod(fp_cache[idx].g->y, mu, modulus,
+                  fp_cache[idx].LUT[1]->y) != MP_OKAY) ||
+         (mp_mulmod(fp_cache[idx].g->z, mu, modulus,
+                  fp_cache[idx].LUT[1]->z) != MP_OKAY)) {
+       err = MP_MULMOD_E;
+     }
+   }
+
+   /* make all single bit entries */
+   for (x = 1; x < FP_LUT; x++) {
+      if (err != MP_OKAY)
+          break;
+      if ((mp_copy(fp_cache[idx].LUT[1<<(x-1)]->x,
+                   fp_cache[idx].LUT[1<<x]->x) != MP_OKAY) ||
+          (mp_copy(fp_cache[idx].LUT[1<<(x-1)]->y,
+                   fp_cache[idx].LUT[1<<x]->y) != MP_OKAY) ||
+          (mp_copy(fp_cache[idx].LUT[1<<(x-1)]->z,
+                   fp_cache[idx].LUT[1<<x]->z) != MP_OKAY)){
+          err = MP_INIT_E;
+          break;
+      } else {
+
+         /* now double it bitlen/FP_LUT times */
+         for (y = 0; y < lut_gap; y++) {
+             if ((err = ecc_projective_dbl_point(fp_cache[idx].LUT[1<<x],
+                            fp_cache[idx].LUT[1<<x], a, modulus, mp)) != MP_OKAY) {
+                 break;
+             }
+         }
+     }
+  }
+
+   /* now make all entries in increase order of hamming weight */
+   for (x = 2; x <= FP_LUT; x++) {
+       if (err != MP_OKAY)
+           break;
+       for (y = 0; y < (1UL<<FP_LUT); y++) {
+           if (lut_orders[y].ham != (int)x) continue;
+
+           /* perform the add */
+           if ((err = ecc_projective_add_point(
+                           fp_cache[idx].LUT[lut_orders[y].terma],
+                           fp_cache[idx].LUT[lut_orders[y].termb],
+                           fp_cache[idx].LUT[y], a, modulus, mp)) != MP_OKAY) {
+              break;
+           }
+       }
+   }
+
+   /* now map all entries back to affine space to make point addition faster */
+   for (x = 1; x < (1UL<<FP_LUT); x++) {
+       if (err != MP_OKAY)
+           break;
+
+       /* convert z to normal from montgomery */
+       err = mp_montgomery_reduce(fp_cache[idx].LUT[x]->z, modulus, mp);
+
+       /* invert it */
+       if (err == MP_OKAY)
+         err = mp_invmod(fp_cache[idx].LUT[x]->z, modulus,
+                         fp_cache[idx].LUT[x]->z);
+
+       if (err == MP_OKAY)
+         /* now square it */
+         err = mp_sqrmod(fp_cache[idx].LUT[x]->z, modulus, &tmp);
+
+       if (err == MP_OKAY)
+         /* fix x */
+         err = mp_mulmod(fp_cache[idx].LUT[x]->x, &tmp, modulus,
+                         fp_cache[idx].LUT[x]->x);
+
+       if (err == MP_OKAY)
+         /* get 1/z^3 */
+         err = mp_mulmod(&tmp, fp_cache[idx].LUT[x]->z, modulus, &tmp);
+
+       if (err == MP_OKAY)
+         /* fix y */
+         err = mp_mulmod(fp_cache[idx].LUT[x]->y, &tmp, modulus,
+                         fp_cache[idx].LUT[x]->y);
+
+       if (err == MP_OKAY)
+         /* free z */
+         mp_clear(fp_cache[idx].LUT[x]->z);
+   }
+
+   mp_clear(&tmp);
+
+   if (err == MP_OKAY)
+     return MP_OKAY;
+
+   /* err cleanup */
+   for (y = 0; y < (1U<<FP_LUT); y++) {
+      wc_ecc_del_point(fp_cache[idx].LUT[y]);
+      fp_cache[idx].LUT[y] = NULL;
+   }
+   wc_ecc_del_point(fp_cache[idx].g);
+   fp_cache[idx].g         = NULL;
+   fp_cache[idx].lru_count = 0;
+   mp_clear(&fp_cache[idx].mu);
+
+   return err;
+}
+
+/* perform a fixed point ECC mulmod */
+static int accel_fp_mul(int idx, mp_int* k, ecc_point *R, mp_int* a,
+                        mp_int* modulus, mp_digit mp, int map)
+{
+#define KB_SIZE 128
+
+#ifdef WOLFSSL_SMALL_STACK
+   unsigned char* kb = NULL;
+#else
+   unsigned char kb[KB_SIZE];
+#endif
+   int      x, err;
+   unsigned y, z = 0, bitlen, bitpos, lut_gap, first;
+   mp_int   tk, order;
+
+   if (mp_init_multi(&tk, &order, NULL, NULL, NULL, NULL) != MP_OKAY)
+       return MP_INIT_E;
+
+   /* if it's smaller than modulus we fine */
+   if (mp_unsigned_bin_size(k) > mp_unsigned_bin_size(modulus)) {
+      /* find order */
+      y = mp_unsigned_bin_size(modulus);
+      for (x = 0; ecc_sets[x].size; x++) {
+         if (y <= (unsigned)ecc_sets[x].size) break;
+      }
+
+      /* back off if we are on the 521 bit curve */
+      if (y == 66) --x;
+
+      if ((err = mp_read_radix(&order, ecc_sets[x].order,
+                                                MP_RADIX_HEX)) != MP_OKAY) {
+         goto done;
+      }
+
+      /* k must be less than modulus */
+      if (mp_cmp(k, &order) != MP_LT) {
+         if ((err = mp_mod(k, &order, &tk)) != MP_OKAY) {
+            goto done;
+         }
+      } else {
+         if ((err = mp_copy(k, &tk)) != MP_OKAY) {
+            goto done;
+         }
+      }
+   } else {
+      if ((err = mp_copy(k, &tk)) != MP_OKAY) {
+         goto done;
+      }
+   }
+
+   /* get bitlen and round up to next multiple of FP_LUT */
+   bitlen  = mp_unsigned_bin_size(modulus) << 3;
+   x       = bitlen % FP_LUT;
+   if (x) {
+      bitlen += FP_LUT - x;
+   }
+   lut_gap = bitlen / FP_LUT;
+
+   /* get the k value */
+   if (mp_unsigned_bin_size(&tk) > (int)(KB_SIZE - 2)) {
+      err = BUFFER_E; goto done;
+   }
+
+   /* store k */
+#ifdef WOLFSSL_SMALL_STACK
+   kb = (unsigned char*)XMALLOC(KB_SIZE, NULL, DYNAMIC_TYPE_ECC_BUFFER);
+   if (kb == NULL) {
+      err = MEMORY_E; goto done;
+   }
+#endif
+
+   XMEMSET(kb, 0, KB_SIZE);
+   if ((err = mp_to_unsigned_bin(&tk, kb)) == MP_OKAY) {
+      /* let's reverse kb so it's little endian */
+      x = 0;
+      y = mp_unsigned_bin_size(&tk);
+      if (y > 0) {
+          y -= 1;
+      }
+
+      while ((unsigned)x < y) {
+         z = kb[x]; kb[x] = kb[y]; kb[y] = (byte)z;
+         ++x; --y;
+      }
+
+      /* at this point we can start, yipee */
+      first = 1;
+      for (x = lut_gap-1; x >= 0; x--) {
+          /* extract FP_LUT bits from kb spread out by lut_gap bits and offset
+             by x bits from the start */
+          bitpos = x;
+          for (y = z = 0; y < FP_LUT; y++) {
+             z |= ((kb[bitpos>>3] >> (bitpos&7)) & 1) << y;
+             bitpos += lut_gap;  /* it's y*lut_gap + x, but here we can avoid
+                                    the mult in each loop */
+          }
+
+          /* double if not first */
+          if (!first) {
+             if ((err = ecc_projective_dbl_point(R, R, a, modulus,
+                                                              mp)) != MP_OKAY) {
+                break;
+             }
+          }
+
+          /* add if not first, otherwise copy */
+          if (!first && z) {
+             if ((err = ecc_projective_add_point(R, fp_cache[idx].LUT[z], R, a,
+                                                     modulus, mp)) != MP_OKAY) {
+                break;
+             }
+             if (mp_iszero(R->z)) {
+                 /* When all zero then should have done an add */
+                 if (mp_iszero(R->x) && mp_iszero(R->y)) {
+                     if ((err = ecc_projective_dbl_point(fp_cache[idx].LUT[z],
+                                               R, a, modulus, mp)) != MP_OKAY) {
+                         break;
+                     }
+                 }
+                 /* When only Z zero then result is infinity */
+                 else {
+                    err = mp_set(R->x, 0);
+                    if (err != MP_OKAY) {
+                       break;
+                    }
+                    err = mp_set(R->y, 0);
+                    if (err != MP_OKAY) {
+                       break;
+                    }
+                    err = mp_copy(&fp_cache[idx].mu, R->z);
+                    if (err != MP_OKAY) {
+                       break;
+                    }
+                    first = 1;
+                 }
+             }
+          } else if (z) {
+             if ((mp_copy(fp_cache[idx].LUT[z]->x, R->x) != MP_OKAY) ||
+                 (mp_copy(fp_cache[idx].LUT[z]->y, R->y) != MP_OKAY) ||
+                 (mp_copy(&fp_cache[idx].mu,       R->z) != MP_OKAY)) {
+                 err = GEN_MEM_ERR;
+                 break;
+             }
+             first = 0;
+          }
+      }
+   }
+
+   if (err == MP_OKAY) {
+      (void) z; /* Acknowledge the unused assignment */
+      ForceZero(kb, KB_SIZE);
+
+      /* map R back from projective space */
+      if (map) {
+         err = ecc_map(R, modulus, mp);
+      } else {
+         err = MP_OKAY;
+      }
+   }
+
+done:
+   /* cleanup */
+   mp_clear(&order);
+   mp_clear(&tk);
+
+#ifdef WOLFSSL_SMALL_STACK
+   XFREE(kb, NULL, DYNAMIC_TYPE_ECC_BUFFER);
+#endif
+
+#undef KB_SIZE
+
+   return err;
+}
+#endif
+
+#ifdef ECC_SHAMIR
+#ifndef WOLFSSL_SP_MATH
+/* perform a fixed point ECC mulmod */
+static int accel_fp_mul2add(int idx1, int idx2,
+                            mp_int* kA, mp_int* kB,
+                            ecc_point *R, mp_int* a,
+                            mp_int* modulus, mp_digit mp)
+{
+#define KB_SIZE 128
+
+#ifdef WOLFSSL_SMALL_STACK
+   unsigned char* kb[2] = {NULL, NULL};
+#else
+   unsigned char kb[2][KB_SIZE];
+#endif
+   int      x, err;
+   unsigned y, z, bitlen, bitpos, lut_gap, first, zA, zB;
+   mp_int tka, tkb, order;
+
+   if (mp_init_multi(&tka, &tkb, &order, NULL, NULL, NULL) != MP_OKAY)
+       return MP_INIT_E;
+
+   /* if it's smaller than modulus we fine */
+   if (mp_unsigned_bin_size(kA) > mp_unsigned_bin_size(modulus)) {
+      /* find order */
+      y = mp_unsigned_bin_size(modulus);
+      for (x = 0; ecc_sets[x].size; x++) {
+         if (y <= (unsigned)ecc_sets[x].size) break;
+      }
+
+      /* back off if we are on the 521 bit curve */
+      if (y == 66) --x;
+
+      if ((err = mp_read_radix(&order, ecc_sets[x].order,
+                                                MP_RADIX_HEX)) != MP_OKAY) {
+         goto done;
+      }
+
+      /* kA must be less than modulus */
+      if (mp_cmp(kA, &order) != MP_LT) {
+         if ((err = mp_mod(kA, &order, &tka)) != MP_OKAY) {
+            goto done;
+         }
+      } else {
+         if ((err = mp_copy(kA, &tka)) != MP_OKAY) {
+            goto done;
+         }
+      }
+   } else {
+      if ((err = mp_copy(kA, &tka)) != MP_OKAY) {
+         goto done;
+      }
+   }
+
+   /* if it's smaller than modulus we fine */
+   if (mp_unsigned_bin_size(kB) > mp_unsigned_bin_size(modulus)) {
+      /* find order */
+      y = mp_unsigned_bin_size(modulus);
+      for (x = 0; ecc_sets[x].size; x++) {
+         if (y <= (unsigned)ecc_sets[x].size) break;
+      }
+
+      /* back off if we are on the 521 bit curve */
+      if (y == 66) --x;
+
+      if ((err = mp_read_radix(&order, ecc_sets[x].order,
+                                                MP_RADIX_HEX)) != MP_OKAY) {
+         goto done;
+      }
+
+      /* kB must be less than modulus */
+      if (mp_cmp(kB, &order) != MP_LT) {
+         if ((err = mp_mod(kB, &order, &tkb)) != MP_OKAY) {
+            goto done;
+         }
+      } else {
+         if ((err = mp_copy(kB, &tkb)) != MP_OKAY) {
+            goto done;
+         }
+      }
+   } else {
+      if ((err = mp_copy(kB, &tkb)) != MP_OKAY) {
+         goto done;
+      }
+   }
+
+   /* get bitlen and round up to next multiple of FP_LUT */
+   bitlen  = mp_unsigned_bin_size(modulus) << 3;
+   x       = bitlen % FP_LUT;
+   if (x) {
+      bitlen += FP_LUT - x;
+   }
+   lut_gap = bitlen / FP_LUT;
+
+   /* get the k value */
+   if ((mp_unsigned_bin_size(&tka) > (int)(KB_SIZE - 2)) ||
+       (mp_unsigned_bin_size(&tkb) > (int)(KB_SIZE - 2))  ) {
+      err = BUFFER_E; goto done;
+   }
+
+   /* store k */
+#ifdef WOLFSSL_SMALL_STACK
+   kb[0] = (unsigned char*)XMALLOC(KB_SIZE, NULL, DYNAMIC_TYPE_ECC_BUFFER);
+   if (kb[0] == NULL) {
+      err = MEMORY_E; goto done;
+   }
+#endif
+
+   XMEMSET(kb[0], 0, KB_SIZE);
+   if ((err = mp_to_unsigned_bin(&tka, kb[0])) != MP_OKAY) {
+      goto done;
+   }
+
+   /* let's reverse kb so it's little endian */
+   x = 0;
+   y = mp_unsigned_bin_size(&tka);
+   if (y > 0) {
+       y -= 1;
+   }
+   mp_clear(&tka);
+   while ((unsigned)x < y) {
+      z = kb[0][x]; kb[0][x] = kb[0][y]; kb[0][y] = (byte)z;
+      ++x; --y;
+   }
+
+   /* store b */
+#ifdef WOLFSSL_SMALL_STACK
+   kb[1] = (unsigned char*)XMALLOC(KB_SIZE, NULL, DYNAMIC_TYPE_ECC_BUFFER);
+   if (kb[1] == NULL) {
+      err = MEMORY_E; goto done;
+   }
+#endif
+
+   XMEMSET(kb[1], 0, KB_SIZE);
+   if ((err = mp_to_unsigned_bin(&tkb, kb[1])) == MP_OKAY) {
+      x = 0;
+      y = mp_unsigned_bin_size(&tkb);
+      if (y > 0) {
+          y -= 1;
+      }
+
+      while ((unsigned)x < y) {
+         z = kb[1][x]; kb[1][x] = kb[1][y]; kb[1][y] = (byte)z;
+         ++x; --y;
+      }
+
+      /* at this point we can start, yipee */
+      first = 1;
+      for (x = lut_gap-1; x >= 0; x--) {
+          /* extract FP_LUT bits from kb spread out by lut_gap bits and
+             offset by x bits from the start */
+          bitpos = x;
+          for (y = zA = zB = 0; y < FP_LUT; y++) {
+             zA |= ((kb[0][bitpos>>3] >> (bitpos&7)) & 1) << y;
+             zB |= ((kb[1][bitpos>>3] >> (bitpos&7)) & 1) << y;
+             bitpos += lut_gap;    /* it's y*lut_gap + x, but here we can avoid
+                                      the mult in each loop */
+          }
+
+          /* double if not first */
+          if (!first) {
+             if ((err = ecc_projective_dbl_point(R, R, a, modulus,
+                                                              mp)) != MP_OKAY) {
+                break;
+             }
+
+             /* add if not first, otherwise copy */
+             if (zA) {
+                if ((err = ecc_projective_add_point(R, fp_cache[idx1].LUT[zA],
+                                               R, a, modulus, mp)) != MP_OKAY) {
+                   break;
+                }
+                if (mp_iszero(R->z)) {
+                    /* When all zero then should have done an add */
+                    if (mp_iszero(R->x) && mp_iszero(R->y)) {
+                        if ((err = ecc_projective_dbl_point(
+                                                  fp_cache[idx1].LUT[zA], R,
+                                                  a, modulus, mp)) != MP_OKAY) {
+                            break;
+                        }
+                    }
+                    /* When only Z zero then result is infinity */
+                    else {
+                       err = mp_set(R->x, 0);
+                       if (err != MP_OKAY) {
+                          break;
+                       }
+                       err = mp_set(R->y, 0);
+                       if (err != MP_OKAY) {
+                          break;
+                       }
+                       err = mp_copy(&fp_cache[idx1].mu, R->z);
+                       if (err != MP_OKAY) {
+                          break;
+                       }
+                       first = 1;
+                    }
+                }
+             }
+
+             if (zB) {
+                if ((err = ecc_projective_add_point(R, fp_cache[idx2].LUT[zB],
+                                               R, a, modulus, mp)) != MP_OKAY) {
+                   break;
+                }
+                if (mp_iszero(R->z)) {
+                    /* When all zero then should have done an add */
+                    if (mp_iszero(R->x) && mp_iszero(R->y)) {
+                        if ((err = ecc_projective_dbl_point(
+                                                  fp_cache[idx2].LUT[zB], R,
+                                                  a, modulus, mp)) != MP_OKAY) {
+                            break;
+                        }
+                    }
+                    /* When only Z zero then result is infinity */
+                    else {
+                       err = mp_set(R->x, 0);
+                       if (err != MP_OKAY) {
+                          break;
+                       }
+                       err = mp_set(R->y, 0);
+                       if (err != MP_OKAY) {
+                          break;
+                       }
+                       err = mp_copy(&fp_cache[idx2].mu, R->z);
+                       if (err != MP_OKAY) {
+                          break;
+                       }
+                       first = 1;
+                    }
+                }
+             }
+          } else {
+             if (zA) {
+                 if ((mp_copy(fp_cache[idx1].LUT[zA]->x, R->x) != MP_OKAY) ||
+                     (mp_copy(fp_cache[idx1].LUT[zA]->y, R->y) != MP_OKAY) ||
+                     (mp_copy(&fp_cache[idx1].mu,        R->z) != MP_OKAY)) {
+                     err = GEN_MEM_ERR;
+                     break;
+                 }
+                    first = 0;
+             }
+             if (zB && first == 0) {
+                if (zB) {
+                   if ((err = ecc_projective_add_point(R,
+                        fp_cache[idx2].LUT[zB], R, a, modulus, mp)) != MP_OKAY){
+                      break;
+                   }
+                   if (mp_iszero(R->z)) {
+                       /* When all zero then should have done an add */
+                       if (mp_iszero(R->x) && mp_iszero(R->y)) {
+                           if ((err = ecc_projective_dbl_point(
+                                                  fp_cache[idx2].LUT[zB], R,
+                                                  a, modulus, mp)) != MP_OKAY) {
+                               break;
+                           }
+                       }
+                       /* When only Z zero then result is infinity */
+                       else {
+                          err = mp_set(R->x, 0);
+                          if (err != MP_OKAY) {
+                             break;
+                          }
+                          err = mp_set(R->y, 0);
+                          if (err != MP_OKAY) {
+                             break;
+                          }
+                          err = mp_copy(&fp_cache[idx2].mu, R->z);
+                          if (err != MP_OKAY) {
+                             break;
+                          }
+                          first = 1;
+                       }
+                   }
+                }
+             } else if (zB && first == 1) {
+                 if ((mp_copy(fp_cache[idx2].LUT[zB]->x, R->x) != MP_OKAY) ||
+                     (mp_copy(fp_cache[idx2].LUT[zB]->y, R->y) != MP_OKAY) ||
+                     (mp_copy(&fp_cache[idx2].mu,        R->z) != MP_OKAY)) {
+                     err = GEN_MEM_ERR;
+                     break;
+                 }
+                    first = 0;
+             }
+          }
+      }
+   }
+
+done:
+   /* cleanup */
+   mp_clear(&tkb);
+   mp_clear(&tka);
+   mp_clear(&order);
+
+#ifdef WOLFSSL_SMALL_STACK
+   if (kb[0])
+#endif
+      ForceZero(kb[0], KB_SIZE);
+#ifdef WOLFSSL_SMALL_STACK
+   if (kb[1])
+#endif
+      ForceZero(kb[1], KB_SIZE);
+
+#ifdef WOLFSSL_SMALL_STACK
+   XFREE(kb[0], NULL, DYNAMIC_TYPE_ECC_BUFFER);
+   XFREE(kb[1], NULL, DYNAMIC_TYPE_ECC_BUFFER);
+#endif
+
+#undef KB_SIZE
+
+    if (err != MP_OKAY)
+        return err;
+
+   return ecc_map(R, modulus, mp);
+}
+
+
+/** ECC Fixed Point mulmod global with heap hint used
+  Computes kA*A + kB*B = C using Shamir's Trick
+  A        First point to multiply
+  kA       What to multiple A by
+  B        Second point to multiply
+  kB       What to multiple B by
+  C        [out] Destination point (can overlap with A or B)
+  a        ECC curve parameter a
+  modulus  Modulus for curve
+  return MP_OKAY on success
+*/
+int ecc_mul2add(ecc_point* A, mp_int* kA,
+                ecc_point* B, mp_int* kB,
+                ecc_point* C, mp_int* a, mp_int* modulus, void* heap)
+{
+   int  idx1 = -1, idx2 = -1, err, mpInit = 0;
+   mp_digit mp;
+   mp_int   mu;
+
+   err = mp_init(&mu);
+   if (err != MP_OKAY)
+       return err;
+
+#ifndef HAVE_THREAD_LS
+   if (initMutex == 0) {
+        wc_InitMutex(&ecc_fp_lock);
+        initMutex = 1;
+   }
+   if (wc_LockMutex(&ecc_fp_lock) != 0)
+      return BAD_MUTEX_E;
+#endif /* HAVE_THREAD_LS */
+
+      /* find point */
+      idx1 = find_base(A);
+
+      /* no entry? */
+      if (idx1 == -1) {
+         /* find hole and add it */
+         if ((idx1 = find_hole()) >= 0) {
+            err = add_entry(idx1, A);
+         }
+      }
+      if (err == MP_OKAY && idx1 != -1) {
+         /* increment LRU */
+         ++(fp_cache[idx1].lru_count);
+      }
+
+      if (err == MP_OKAY) {
+        /* find point */
+        idx2 = find_base(B);
+
+        /* no entry? */
+        if (idx2 == -1) {
+           /* find hole and add it */
+           if ((idx2 = find_hole()) >= 0)
+              err = add_entry(idx2, B);
+         }
+      }
+
+      if (err == MP_OKAY && idx2 != -1) {
+         /* increment LRU */
+         ++(fp_cache[idx2].lru_count);
+      }
+
+      if (err == MP_OKAY) {
+        /* if it's 2 build the LUT, if it's higher just use the LUT */
+        if (idx1 >= 0 && fp_cache[idx1].lru_count == 2) {
+           /* compute mp */
+           err = mp_montgomery_setup(modulus, &mp);
+
+           if (err == MP_OKAY) {
+             mpInit = 1;
+             err = mp_montgomery_calc_normalization(&mu, modulus);
+           }
+
+           if (err == MP_OKAY)
+             /* build the LUT */
+               err = build_lut(idx1, a, modulus, mp, &mu);
+        }
+      }
+
+      if (err == MP_OKAY) {
+        /* if it's 2 build the LUT, if it's higher just use the LUT */
+        if (idx2 >= 0 && fp_cache[idx2].lru_count == 2) {
+           if (mpInit == 0) {
+                /* compute mp */
+                err = mp_montgomery_setup(modulus, &mp);
+                if (err == MP_OKAY) {
+                    mpInit = 1;
+                    err = mp_montgomery_calc_normalization(&mu, modulus);
+                }
+            }
+
+            if (err == MP_OKAY)
+            /* build the LUT */
+              err = build_lut(idx2, a, modulus, mp, &mu);
+        }
+      }
+
+
+      if (err == MP_OKAY) {
+        if (idx1 >=0 && idx2 >= 0 && fp_cache[idx1].lru_count >= 2 &&
+                                     fp_cache[idx2].lru_count >= 2) {
+           if (mpInit == 0) {
+              /* compute mp */
+              err = mp_montgomery_setup(modulus, &mp);
+           }
+           if (err == MP_OKAY)
+             err = accel_fp_mul2add(idx1, idx2, kA, kB, C, a, modulus, mp);
+        } else {
+           err = normal_ecc_mul2add(A, kA, B, kB, C, a, modulus, heap);
+        }
+    }
+
+#ifndef HAVE_THREAD_LS
+    wc_UnLockMutex(&ecc_fp_lock);
+#endif /* HAVE_THREAD_LS */
+    mp_clear(&mu);
+
+    return err;
+}
+#endif
+#endif /* ECC_SHAMIR */
+
+/** ECC Fixed Point mulmod global
+    k        The multiplicand
+    G        Base point to multiply
+    R        [out] Destination of product
+    a        ECC curve parameter a
+    modulus  The modulus for the curve
+    map      [boolean] If non-zero maps the point back to affine coordinates,
+             otherwise it's left in jacobian-montgomery form
+    return MP_OKAY if successful
+*/
+int wc_ecc_mulmod_ex(mp_int* k, ecc_point *G, ecc_point *R, mp_int* a,
+    mp_int* modulus, int map, void* heap)
+{
+#ifndef WOLFSSL_SP_MATH
+   int   idx, err = MP_OKAY;
+   mp_digit mp;
+   mp_int   mu;
+   int      mpSetup = 0;
+
+   if (k == NULL || G == NULL || R == NULL || a == NULL || modulus == NULL) {
+       return ECC_BAD_ARG_E;
+   }
+
+   if (mp_init(&mu) != MP_OKAY)
+       return MP_INIT_E;
+
+#ifndef HAVE_THREAD_LS
+   if (initMutex == 0) {
+        wc_InitMutex(&ecc_fp_lock);
+        initMutex = 1;
+   }
+
+   if (wc_LockMutex(&ecc_fp_lock) != 0)
+      return BAD_MUTEX_E;
+#endif /* HAVE_THREAD_LS */
+
+      /* find point */
+      idx = find_base(G);
+
+      /* no entry? */
+      if (idx == -1) {
+         /* find hole and add it */
+         idx = find_hole();
+
+         if (idx >= 0)
+            err = add_entry(idx, G);
+      }
+      if (err == MP_OKAY && idx >= 0) {
+         /* increment LRU */
+         ++(fp_cache[idx].lru_count);
+      }
+
+
+      if (err == MP_OKAY) {
+        /* if it's 2 build the LUT, if it's higher just use the LUT */
+        if (idx >= 0 && fp_cache[idx].lru_count == 2) {
+           /* compute mp */
+           err = mp_montgomery_setup(modulus, &mp);
+
+           if (err == MP_OKAY) {
+             /* compute mu */
+             mpSetup = 1;
+             err = mp_montgomery_calc_normalization(&mu, modulus);
+           }
+
+           if (err == MP_OKAY)
+             /* build the LUT */
+             err = build_lut(idx, a, modulus, mp, &mu);
+        }
+      }
+
+      if (err == MP_OKAY) {
+        if (idx >= 0 && fp_cache[idx].lru_count >= 2) {
+           if (mpSetup == 0) {
+              /* compute mp */
+              err = mp_montgomery_setup(modulus, &mp);
+           }
+           if (err == MP_OKAY)
+             err = accel_fp_mul(idx, k, R, a, modulus, mp, map);
+        } else {
+           err = normal_ecc_mulmod(k, G, R, a, modulus, map, heap);
+        }
+     }
+
+#ifndef HAVE_THREAD_LS
+    wc_UnLockMutex(&ecc_fp_lock);
+#endif /* HAVE_THREAD_LS */
+    mp_clear(&mu);
+
+    return err;
+#else
+    if (k == NULL || G == NULL || R == NULL || a == NULL || modulus == NULL) {
+        return ECC_BAD_ARG_E;
+    }
+
+#ifndef WOLFSSL_SP_NO_256
+    if (mp_count_bits(modulus) == 256) {
+        return sp_ecc_mulmod_256(k, G, R, map, heap);
+    }
+#endif
+#ifdef WOLFSSL_SP_384
+    if (mp_count_bits(modulus) == 384) {
+        return sp_ecc_mulmod_384(k, G, R, map, heap);
+    }
+#endif
+    return WC_KEY_SIZE_E;
+#endif
+}
+
+#ifndef WOLFSSL_SP_MATH
+/* helper function for freeing the cache ...
+   must be called with the cache mutex locked */
+static void wc_ecc_fp_free_cache(void)
+{
+   unsigned x, y;
+   for (x = 0; x < FP_ENTRIES; x++) {
+      if (fp_cache[x].g != NULL) {
+         for (y = 0; y < (1U<<FP_LUT); y++) {
+            wc_ecc_del_point(fp_cache[x].LUT[y]);
+            fp_cache[x].LUT[y] = NULL;
+         }
+         wc_ecc_del_point(fp_cache[x].g);
+         fp_cache[x].g         = NULL;
+         mp_clear(&fp_cache[x].mu);
+         fp_cache[x].lru_count = 0;
+         fp_cache[x].lock = 0;
+      }
+   }
+}
+#endif
+
+/** Free the Fixed Point cache */
+void wc_ecc_fp_free(void)
+{
+#ifndef WOLFSSL_SP_MATH
+#ifndef HAVE_THREAD_LS
+   if (initMutex == 0) {
+        wc_InitMutex(&ecc_fp_lock);
+        initMutex = 1;
+   }
+
+   if (wc_LockMutex(&ecc_fp_lock) == 0) {
+#endif /* HAVE_THREAD_LS */
+
+       wc_ecc_fp_free_cache();
+
+#ifndef HAVE_THREAD_LS
+       wc_UnLockMutex(&ecc_fp_lock);
+       wc_FreeMutex(&ecc_fp_lock);
+       initMutex = 0;
+   }
+#endif /* HAVE_THREAD_LS */
+#endif
+}
+
+
+#endif /* FP_ECC */
+
+#ifdef HAVE_ECC_ENCRYPT
+
+
+enum ecCliState {
+    ecCLI_INIT      = 1,
+    ecCLI_SALT_GET  = 2,
+    ecCLI_SALT_SET  = 3,
+    ecCLI_SENT_REQ  = 4,
+    ecCLI_RECV_RESP = 5,
+    ecCLI_BAD_STATE = 99
+};
+
+enum ecSrvState {
+    ecSRV_INIT      = 1,
+    ecSRV_SALT_GET  = 2,
+    ecSRV_SALT_SET  = 3,
+    ecSRV_RECV_REQ  = 4,
+    ecSRV_SENT_RESP = 5,
+    ecSRV_BAD_STATE = 99
+};
+
+
+struct ecEncCtx {
+    const byte* kdfSalt;   /* optional salt for kdf */
+    const byte* kdfInfo;   /* optional info for kdf */
+    const byte* macSalt;   /* optional salt for mac */
+    word32    kdfSaltSz;   /* size of kdfSalt */
+    word32    kdfInfoSz;   /* size of kdfInfo */
+    word32    macSaltSz;   /* size of macSalt */
+    void*     heap;        /* heap hint for memory used */
+    byte      clientSalt[EXCHANGE_SALT_SZ];  /* for msg exchange */
+    byte      serverSalt[EXCHANGE_SALT_SZ];  /* for msg exchange */
+    byte      encAlgo;     /* which encryption type */
+    byte      kdfAlgo;     /* which key derivation function type */
+    byte      macAlgo;     /* which mac function type */
+    byte      protocol;    /* are we REQ_RESP client or server ? */
+    byte      cliSt;       /* protocol state, for sanity checks */
+    byte      srvSt;       /* protocol state, for sanity checks */
+};
+
+
+const byte* wc_ecc_ctx_get_own_salt(ecEncCtx* ctx)
+{
+    if (ctx == NULL || ctx->protocol == 0)
+        return NULL;
+
+    if (ctx->protocol == REQ_RESP_CLIENT) {
+        if (ctx->cliSt == ecCLI_INIT) {
+            ctx->cliSt =  ecCLI_SALT_GET;
+            return ctx->clientSalt;
+        }
+        else {
+            ctx->cliSt = ecCLI_BAD_STATE;
+            return NULL;
+        }
+    }
+    else if (ctx->protocol == REQ_RESP_SERVER) {
+        if (ctx->srvSt == ecSRV_INIT) {
+            ctx->srvSt =  ecSRV_SALT_GET;
+            return ctx->serverSalt;
+        }
+        else {
+            ctx->srvSt = ecSRV_BAD_STATE;
+            return NULL;
+        }
+    }
+
+    return NULL;
+}
+
+
+/* optional set info, can be called before or after set_peer_salt */
+int wc_ecc_ctx_set_info(ecEncCtx* ctx, const byte* info, int sz)
+{
+    if (ctx == NULL || info == 0 || sz < 0)
+        return BAD_FUNC_ARG;
+
+    ctx->kdfInfo   = info;
+    ctx->kdfInfoSz = sz;
+
+    return 0;
+}
+
+
+static const char* exchange_info = "Secure Message Exchange";
+
+int wc_ecc_ctx_set_peer_salt(ecEncCtx* ctx, const byte* salt)
+{
+    byte tmp[EXCHANGE_SALT_SZ/2];
+    int  halfSz = EXCHANGE_SALT_SZ/2;
+
+    if (ctx == NULL || ctx->protocol == 0 || salt == NULL)
+        return BAD_FUNC_ARG;
+
+    if (ctx->protocol == REQ_RESP_CLIENT) {
+        XMEMCPY(ctx->serverSalt, salt, EXCHANGE_SALT_SZ);
+        if (ctx->cliSt == ecCLI_SALT_GET)
+            ctx->cliSt =  ecCLI_SALT_SET;
+        else {
+            ctx->cliSt =  ecCLI_BAD_STATE;
+            return BAD_STATE_E;
+        }
+    }
+    else {
+        XMEMCPY(ctx->clientSalt, salt, EXCHANGE_SALT_SZ);
+        if (ctx->srvSt == ecSRV_SALT_GET)
+            ctx->srvSt =  ecSRV_SALT_SET;
+        else {
+            ctx->srvSt =  ecSRV_BAD_STATE;
+            return BAD_STATE_E;
+        }
+    }
+
+    /* mix half and half */
+    /* tmp stores 2nd half of client before overwrite */
+    XMEMCPY(tmp, ctx->clientSalt + halfSz, halfSz);
+    XMEMCPY(ctx->clientSalt + halfSz, ctx->serverSalt, halfSz);
+    XMEMCPY(ctx->serverSalt, tmp, halfSz);
+
+    ctx->kdfSalt   = ctx->clientSalt;
+    ctx->kdfSaltSz = EXCHANGE_SALT_SZ;
+
+    ctx->macSalt   = ctx->serverSalt;
+    ctx->macSaltSz = EXCHANGE_SALT_SZ;
+
+    if (ctx->kdfInfo == NULL) {
+        /* default info */
+        ctx->kdfInfo   = (const byte*)exchange_info;
+        ctx->kdfInfoSz = EXCHANGE_INFO_SZ;
+    }
+
+    return 0;
+}
+
+
+static int ecc_ctx_set_salt(ecEncCtx* ctx, int flags, WC_RNG* rng)
+{
+    byte* saltBuffer = NULL;
+
+    if (ctx == NULL || rng == NULL || flags == 0)
+        return BAD_FUNC_ARG;
+
+    saltBuffer = (flags == REQ_RESP_CLIENT) ? ctx->clientSalt : ctx->serverSalt;
+
+    return wc_RNG_GenerateBlock(rng, saltBuffer, EXCHANGE_SALT_SZ);
+}
+
+
+static void ecc_ctx_init(ecEncCtx* ctx, int flags)
+{
+    if (ctx) {
+        XMEMSET(ctx, 0, sizeof(ecEncCtx));
+
+        ctx->encAlgo  = ecAES_128_CBC;
+        ctx->kdfAlgo  = ecHKDF_SHA256;
+        ctx->macAlgo  = ecHMAC_SHA256;
+        ctx->protocol = (byte)flags;
+
+        if (flags == REQ_RESP_CLIENT)
+            ctx->cliSt = ecCLI_INIT;
+        if (flags == REQ_RESP_SERVER)
+            ctx->srvSt = ecSRV_INIT;
+    }
+}
+
+
+/* allow ecc context reset so user doesn't have to init/free for reuse */
+int wc_ecc_ctx_reset(ecEncCtx* ctx, WC_RNG* rng)
+{
+    if (ctx == NULL || rng == NULL)
+        return BAD_FUNC_ARG;
+
+    ecc_ctx_init(ctx, ctx->protocol);
+    return ecc_ctx_set_salt(ctx, ctx->protocol, rng);
+}
+
+
+ecEncCtx* wc_ecc_ctx_new_ex(int flags, WC_RNG* rng, void* heap)
+{
+    int       ret = 0;
+    ecEncCtx* ctx = (ecEncCtx*)XMALLOC(sizeof(ecEncCtx), heap,
+                                                              DYNAMIC_TYPE_ECC);
+
+    if (ctx) {
+        ctx->protocol = (byte)flags;
+        ctx->heap     = heap;
+    }
+
+    ret = wc_ecc_ctx_reset(ctx, rng);
+    if (ret != 0) {
+        wc_ecc_ctx_free(ctx);
+        ctx = NULL;
+    }
+
+    return ctx;
+}
+
+
+/* alloc/init and set defaults, return new Context  */
+ecEncCtx* wc_ecc_ctx_new(int flags, WC_RNG* rng)
+{
+    return wc_ecc_ctx_new_ex(flags, rng, NULL);
+}
+
+
+/* free any resources, clear any keys */
+void wc_ecc_ctx_free(ecEncCtx* ctx)
+{
+    if (ctx) {
+        ForceZero(ctx, sizeof(ecEncCtx));
+        XFREE(ctx, ctx->heap, DYNAMIC_TYPE_ECC);
+    }
+}
+
+
+static int ecc_get_key_sizes(ecEncCtx* ctx, int* encKeySz, int* ivSz,
+                             int* keysLen, word32* digestSz, word32* blockSz)
+{
+    if (ctx) {
+        switch (ctx->encAlgo) {
+            case ecAES_128_CBC:
+                *encKeySz = KEY_SIZE_128;
+                *ivSz     = IV_SIZE_128;
+                *blockSz  = AES_BLOCK_SIZE;
+                break;
+            default:
+                return BAD_FUNC_ARG;
+        }
+
+        switch (ctx->macAlgo) {
+            case ecHMAC_SHA256:
+                *digestSz = WC_SHA256_DIGEST_SIZE;
+                break;
+            default:
+                return BAD_FUNC_ARG;
+        }
+    } else
+        return BAD_FUNC_ARG;
+
+    *keysLen  = *encKeySz + *ivSz + *digestSz;
+
+    return 0;
+}
+
+
+/* ecc encrypt with shared secret run through kdf
+   ctx holds non default algos and inputs
+   msgSz should be the right size for encAlgo, i.e., already padded
+   return 0 on success */
+int wc_ecc_encrypt(ecc_key* privKey, ecc_key* pubKey, const byte* msg,
+                word32 msgSz, byte* out, word32* outSz, ecEncCtx* ctx)
+{
+    int          ret = 0;
+    word32       blockSz;
+    word32       digestSz;
+    ecEncCtx     localCtx;
+#ifdef WOLFSSL_SMALL_STACK
+    byte*        sharedSecret;
+    byte*        keys;
+#else
+    byte         sharedSecret[ECC_MAXSIZE];  /* 521 max size */
+    byte         keys[ECC_BUFSIZE];         /* max size */
+#endif
+    word32       sharedSz = ECC_MAXSIZE;
+    int          keysLen;
+    int          encKeySz;
+    int          ivSz;
+    int          offset = 0;         /* keys offset if doing msg exchange */
+    byte*        encKey;
+    byte*        encIv;
+    byte*        macKey;
+
+    if (privKey == NULL || pubKey == NULL || msg == NULL || out == NULL ||
+                           outSz  == NULL)
+        return BAD_FUNC_ARG;
+
+    if (ctx == NULL) {  /* use defaults */
+        ecc_ctx_init(&localCtx, 0);
+        ctx = &localCtx;
+    }
+
+    ret = ecc_get_key_sizes(ctx, &encKeySz, &ivSz, &keysLen, &digestSz,
+                            &blockSz);
+    if (ret != 0)
+        return ret;
+
+    if (ctx->protocol == REQ_RESP_SERVER) {
+        offset = keysLen;
+        keysLen *= 2;
+
+        if (ctx->srvSt != ecSRV_RECV_REQ)
+            return BAD_STATE_E;
+
+        ctx->srvSt = ecSRV_BAD_STATE; /* we're done no more ops allowed */
+    }
+    else if (ctx->protocol == REQ_RESP_CLIENT) {
+        if (ctx->cliSt != ecCLI_SALT_SET)
+            return BAD_STATE_E;
+
+        ctx->cliSt = ecCLI_SENT_REQ; /* only do this once */
+    }
+
+    if (keysLen > ECC_BUFSIZE) /* keys size */
+        return BUFFER_E;
+
+    if ( (msgSz%blockSz) != 0)
+        return BAD_PADDING_E;
+
+    if (*outSz < (msgSz + digestSz))
+        return BUFFER_E;
+
+#ifdef WOLFSSL_SMALL_STACK
+    sharedSecret = (byte*)XMALLOC(ECC_MAXSIZE, NULL, DYNAMIC_TYPE_ECC_BUFFER);
+    if (sharedSecret == NULL)
+        return MEMORY_E;
+
+    keys = (byte*)XMALLOC(ECC_BUFSIZE, NULL, DYNAMIC_TYPE_ECC_BUFFER);
+    if (keys == NULL) {
+        XFREE(sharedSecret, NULL, DYNAMIC_TYPE_ECC_BUFFER);
+        return MEMORY_E;
+    }
+#endif
+
+    do {
+    #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC)
+        ret = wc_AsyncWait(ret, &privKey->asyncDev, WC_ASYNC_FLAG_CALL_AGAIN);
+        if (ret != 0)
+            break;
+    #endif
+        ret = wc_ecc_shared_secret(privKey, pubKey, sharedSecret, &sharedSz);
+    } while (ret == WC_PENDING_E);
+    if (ret == 0) {
+       switch (ctx->kdfAlgo) {
+           case ecHKDF_SHA256 :
+               ret = wc_HKDF(WC_SHA256, sharedSecret, sharedSz, ctx->kdfSalt,
+                          ctx->kdfSaltSz, ctx->kdfInfo, ctx->kdfInfoSz,
+                          keys, keysLen);
+               break;
+
+           default:
+               ret = BAD_FUNC_ARG;
+               break;
+       }
+    }
+
+    if (ret == 0) {
+       encKey = keys + offset;
+       encIv  = encKey + encKeySz;
+       macKey = encKey + encKeySz + ivSz;
+
+       switch (ctx->encAlgo) {
+           case ecAES_128_CBC:
+               {
+                   Aes aes;
+                   ret = wc_AesInit(&aes, NULL, INVALID_DEVID);
+                   if (ret == 0) {
+                       ret = wc_AesSetKey(&aes, encKey, KEY_SIZE_128, encIv,
+                                                                AES_ENCRYPTION);
+                       if (ret == 0) {
+                           ret = wc_AesCbcEncrypt(&aes, out, msg, msgSz);
+                       #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_AES)
+                           ret = wc_AsyncWait(ret, &aes.asyncDev,
+                                              WC_ASYNC_FLAG_NONE);
+                       #endif
+                       }
+                       wc_AesFree(&aes);
+                   }
+                   if (ret != 0)
+                      break;
+               }
+               break;
+
+           default:
+               ret = BAD_FUNC_ARG;
+               break;
+       }
+    }
+
+    if (ret == 0) {
+       switch (ctx->macAlgo) {
+           case ecHMAC_SHA256:
+               {
+                   Hmac hmac;
+                   ret = wc_HmacInit(&hmac, NULL, INVALID_DEVID);
+                   if (ret == 0) {
+                       ret = wc_HmacSetKey(&hmac, WC_SHA256, macKey, WC_SHA256_DIGEST_SIZE);
+                       if (ret == 0)
+                           ret = wc_HmacUpdate(&hmac, out, msgSz);
+                       if (ret == 0)
+                           ret = wc_HmacUpdate(&hmac, ctx->macSalt, ctx->macSaltSz);
+                       if (ret == 0)
+                           ret = wc_HmacFinal(&hmac, out+msgSz);
+                       wc_HmacFree(&hmac);
+                   }
+               }
+               break;
+
+           default:
+               ret = BAD_FUNC_ARG;
+               break;
+       }
+    }
+
+    if (ret == 0)
+       *outSz = msgSz + digestSz;
+
+#ifdef WOLFSSL_SMALL_STACK
+    XFREE(sharedSecret, NULL, DYNAMIC_TYPE_ECC_BUFFER);
+    XFREE(keys, NULL, DYNAMIC_TYPE_ECC_BUFFER);
+#endif
+
+    return ret;
+}
+
+
+/* ecc decrypt with shared secret run through kdf
+   ctx holds non default algos and inputs
+   return 0 on success */
+int wc_ecc_decrypt(ecc_key* privKey, ecc_key* pubKey, const byte* msg,
+                word32 msgSz, byte* out, word32* outSz, ecEncCtx* ctx)
+{
+    int          ret = 0;
+    word32       blockSz;
+    word32       digestSz;
+    ecEncCtx     localCtx;
+#ifdef WOLFSSL_SMALL_STACK
+    byte*        sharedSecret;
+    byte*        keys;
+#else
+    byte         sharedSecret[ECC_MAXSIZE];  /* 521 max size */
+    byte         keys[ECC_BUFSIZE];         /* max size */
+#endif
+    word32       sharedSz = ECC_MAXSIZE;
+    int          keysLen;
+    int          encKeySz;
+    int          ivSz;
+    int          offset = 0;       /* in case using msg exchange */
+    byte*        encKey;
+    byte*        encIv;
+    byte*        macKey;
+
+    if (privKey == NULL || pubKey == NULL || msg == NULL || out == NULL ||
+                           outSz  == NULL)
+        return BAD_FUNC_ARG;
+
+    if (ctx == NULL) {  /* use defaults */
+        ecc_ctx_init(&localCtx, 0);
+        ctx = &localCtx;
+    }
+
+    ret = ecc_get_key_sizes(ctx, &encKeySz, &ivSz, &keysLen, &digestSz,
+                            &blockSz);
+    if (ret != 0)
+        return ret;
+
+    if (ctx->protocol == REQ_RESP_CLIENT) {
+        offset = keysLen;
+        keysLen *= 2;
+
+        if (ctx->cliSt != ecCLI_SENT_REQ)
+            return BAD_STATE_E;
+
+        ctx->cliSt = ecSRV_BAD_STATE; /* we're done no more ops allowed */
+    }
+    else if (ctx->protocol == REQ_RESP_SERVER) {
+        if (ctx->srvSt != ecSRV_SALT_SET)
+            return BAD_STATE_E;
+
+        ctx->srvSt = ecSRV_RECV_REQ; /* only do this once */
+    }
+
+    if (keysLen > ECC_BUFSIZE) /* keys size */
+        return BUFFER_E;
+
+    if ( ((msgSz-digestSz) % blockSz) != 0)
+        return BAD_PADDING_E;
+
+    if (*outSz < (msgSz - digestSz))
+        return BUFFER_E;
+
+#ifdef WOLFSSL_SMALL_STACK
+    sharedSecret = (byte*)XMALLOC(ECC_MAXSIZE, NULL, DYNAMIC_TYPE_ECC_BUFFER);
+    if (sharedSecret == NULL)
+        return MEMORY_E;
+
+    keys = (byte*)XMALLOC(ECC_BUFSIZE, NULL, DYNAMIC_TYPE_ECC_BUFFER);
+    if (keys == NULL) {
+        XFREE(sharedSecret, NULL, DYNAMIC_TYPE_ECC_BUFFER);
+        return MEMORY_E;
+    }
+#endif
+
+    do {
+    #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC)
+        ret = wc_AsyncWait(ret, &privKey->asyncDev, WC_ASYNC_FLAG_CALL_AGAIN);
+        if (ret != 0)
+            break;
+    #endif
+        ret = wc_ecc_shared_secret(privKey, pubKey, sharedSecret, &sharedSz);
+    } while (ret == WC_PENDING_E);
+    if (ret == 0) {
+       switch (ctx->kdfAlgo) {
+           case ecHKDF_SHA256 :
+               ret = wc_HKDF(WC_SHA256, sharedSecret, sharedSz, ctx->kdfSalt,
+                          ctx->kdfSaltSz, ctx->kdfInfo, ctx->kdfInfoSz,
+                          keys, keysLen);
+               break;
+
+           default:
+               ret = BAD_FUNC_ARG;
+               break;
+       }
+    }
+
+    if (ret == 0) {
+       encKey = keys + offset;
+       encIv  = encKey + encKeySz;
+       macKey = encKey + encKeySz + ivSz;
+
+       switch (ctx->macAlgo) {
+           case ecHMAC_SHA256:
+           {
+               byte verify[WC_SHA256_DIGEST_SIZE];
+               Hmac hmac;
+
+               ret = wc_HmacInit(&hmac, NULL, INVALID_DEVID);
+               if (ret == 0) {
+                   ret = wc_HmacSetKey(&hmac, WC_SHA256, macKey, WC_SHA256_DIGEST_SIZE);
+                   if (ret == 0)
+                       ret = wc_HmacUpdate(&hmac, msg, msgSz-digestSz);
+                   if (ret == 0)
+                       ret = wc_HmacUpdate(&hmac, ctx->macSalt, ctx->macSaltSz);
+                   if (ret == 0)
+                       ret = wc_HmacFinal(&hmac, verify);
+                   if (ret == 0) {
+                      if (XMEMCMP(verify, msg + msgSz - digestSz, digestSz) != 0)
+                          ret = -1;
+                   }
+
+                   wc_HmacFree(&hmac);
+               }
+               break;
+           }
+
+           default:
+               ret = BAD_FUNC_ARG;
+               break;
+       }
+    }
+
+    if (ret == 0) {
+       switch (ctx->encAlgo) {
+    #ifdef HAVE_AES_CBC
+           case ecAES_128_CBC:
+               {
+                   Aes aes;
+                   ret = wc_AesSetKey(&aes, encKey, KEY_SIZE_128, encIv,
+                                                                AES_DECRYPTION);
+                   if (ret != 0)
+                       break;
+                   ret = wc_AesCbcDecrypt(&aes, out, msg, msgSz-digestSz);
+                #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_AES)
+                   ret = wc_AsyncWait(ret, &aes.asyncDev, WC_ASYNC_FLAG_NONE);
+                #endif
+               }
+               break;
+    #endif
+           default:
+               ret = BAD_FUNC_ARG;
+               break;
+       }
+    }
+
+    if (ret == 0)
+       *outSz = msgSz - digestSz;
+
+#ifdef WOLFSSL_SMALL_STACK
+    XFREE(sharedSecret, NULL, DYNAMIC_TYPE_ECC_BUFFER);
+    XFREE(keys, NULL, DYNAMIC_TYPE_ECC_BUFFER);
+#endif
+
+    return ret;
+}
+
+
+#endif /* HAVE_ECC_ENCRYPT */
+
+
+#ifdef HAVE_COMP_KEY
+#if !defined(WOLFSSL_ATECC508A) && !defined(WOLFSSL_CRYPTOCELL)
+
+#ifndef WOLFSSL_SP_MATH
+int do_mp_jacobi(mp_int* a, mp_int* n, int* c);
+
+int do_mp_jacobi(mp_int* a, mp_int* n, int* c)
+{
+  int      k, s, res;
+  int      r = 0; /* initialize to help static analysis out */
+  mp_digit residue;
+
+  /* if a < 0 return MP_VAL */
+  if (mp_isneg(a) == MP_YES) {
+     return MP_VAL;
+  }
+
+  /* if n <= 0 return MP_VAL */
+  if (mp_cmp_d(n, 0) != MP_GT) {
+     return MP_VAL;
+  }
+
+  /* step 1. handle case of a == 0 */
+  if (mp_iszero (a) == MP_YES) {
+     /* special case of a == 0 and n == 1 */
+     if (mp_cmp_d (n, 1) == MP_EQ) {
+       *c = 1;
+     } else {
+       *c = 0;
+     }
+     return MP_OKAY;
+  }
+
+  /* step 2.  if a == 1, return 1 */
+  if (mp_cmp_d (a, 1) == MP_EQ) {
+    *c = 1;
+    return MP_OKAY;
+  }
+
+  /* default */
+  s = 0;
+
+  /* divide out larger power of two */
+  k = mp_cnt_lsb(a);
+  res = mp_div_2d(a, k, a, NULL);
+
+  if (res == MP_OKAY) {
+    /* step 4.  if e is even set s=1 */
+    if ((k & 1) == 0) {
+      s = 1;
+    } else {
+      /* else set s=1 if p = 1/7 (mod 8) or s=-1 if p = 3/5 (mod 8) */
+      residue = n->dp[0] & 7;
+
+      if (residue == 1 || residue == 7) {
+        s = 1;
+      } else if (residue == 3 || residue == 5) {
+        s = -1;
+      }
+    }
+
+    /* step 5.  if p == 3 (mod 4) *and* a == 3 (mod 4) then s = -s */
+    if ( ((n->dp[0] & 3) == 3) && ((a->dp[0] & 3) == 3)) {
+      s = -s;
+    }
+  }
+
+  if (res == MP_OKAY) {
+    /* if a == 1 we're done */
+    if (mp_cmp_d(a, 1) == MP_EQ) {
+      *c = s;
+    } else {
+      /* n1 = n mod a */
+      res = mp_mod (n, a, n);
+      if (res == MP_OKAY)
+        res = do_mp_jacobi(n, a, &r);
+
+      if (res == MP_OKAY)
+        *c = s * r;
+    }
+  }
+
+  return res;
+}
+
+
+/* computes the jacobi c = (a | n) (or Legendre if n is prime)
+ * HAC pp. 73 Algorithm 2.149
+ * HAC is wrong here, as the special case of (0 | 1) is not
+ * handled correctly.
+ */
+int mp_jacobi(mp_int* a, mp_int* n, int* c)
+{
+    mp_int   a1, n1;
+    int      res;
+
+    /* step 3.  write a = a1 * 2**k  */
+    if ((res = mp_init_multi(&a1, &n1, NULL, NULL, NULL, NULL)) != MP_OKAY) {
+        return res;
+    }
+
+    if ((res = mp_copy(a, &a1)) != MP_OKAY) {
+        goto done;
+    }
+
+    if ((res = mp_copy(n, &n1)) != MP_OKAY) {
+        goto done;
+    }
+
+    res = do_mp_jacobi(&a1, &n1, c);
+
+done:
+  /* cleanup */
+  mp_clear(&n1);
+  mp_clear(&a1);
+
+  return res;
+}
+
+
+/* Solves the modular equation x^2 = n (mod p)
+ * where prime number is greater than 2 (odd prime).
+ * The result is returned in the third argument x
+ * the function returns MP_OKAY on success, MP_VAL or another error on failure
+ */
+int mp_sqrtmod_prime(mp_int* n, mp_int* prime, mp_int* ret)
+{
+#ifdef SQRTMOD_USE_MOD_EXP
+  int res;
+
+  mp_int e;
+
+  res = mp_init(&e);
+  if (res == MP_OKAY)
+      res = mp_add_d(prime, 1, &e);
+  if (res == MP_OKAY)
+      res = mp_div_2d(&e, 2, &e, NULL);
+  if (res == MP_OKAY)
+      res = mp_exptmod(n, &e, prime, ret);
+
+  mp_clear(&e);
+
+  return res;
+#else
+  int res, legendre, done = 0;
+  mp_int t1, C, Q, S, Z, M, T, R, two;
+  mp_digit i;
+
+  /* first handle the simple cases n = 0 or n = 1 */
+  if (mp_cmp_d(n, 0) == MP_EQ) {
+    mp_zero(ret);
+    return MP_OKAY;
+  }
+  if (mp_cmp_d(n, 1) == MP_EQ) {
+    return mp_set(ret, 1);
+  }
+
+  /* prime must be odd */
+  if (mp_cmp_d(prime, 2) == MP_EQ) {
+    return MP_VAL;
+  }
+
+  /* is quadratic non-residue mod prime */
+  if ((res = mp_jacobi(n, prime, &legendre)) != MP_OKAY) {
+    return res;
+  }
+  if (legendre == -1) {
+    return MP_VAL;
+  }
+
+  if ((res = mp_init_multi(&t1, &C, &Q, &S, &Z, &M)) != MP_OKAY)
+    return res;
+
+  if ((res = mp_init_multi(&T, &R, &two, NULL, NULL, NULL))
+                          != MP_OKAY) {
+    mp_clear(&t1); mp_clear(&C); mp_clear(&Q); mp_clear(&S); mp_clear(&Z);
+    mp_clear(&M);
+    return res;
+  }
+
+  /* SPECIAL CASE: if prime mod 4 == 3
+   * compute directly: res = n^(prime+1)/4 mod prime
+   * Handbook of Applied Cryptography algorithm 3.36
+   */
+  res = mp_mod_d(prime, 4, &i);
+  if (res == MP_OKAY && i == 3) {
+    res = mp_add_d(prime, 1, &t1);
+
+    if (res == MP_OKAY)
+      res = mp_div_2(&t1, &t1);
+    if (res == MP_OKAY)
+      res = mp_div_2(&t1, &t1);
+    if (res == MP_OKAY)
+      res = mp_exptmod(n, &t1, prime, ret);
+
+    done = 1;
+  }
+
+  /* NOW: TonelliShanks algorithm */
+  if (res == MP_OKAY && done == 0) {
+
+    /* factor out powers of 2 from prime-1, defining Q and S
+    *                                      as: prime-1 = Q*2^S */
+    /* Q = prime - 1 */
+    res = mp_copy(prime, &Q);
+    if (res == MP_OKAY)
+      res = mp_sub_d(&Q, 1, &Q);
+
+    /* S = 0 */
+    if (res == MP_OKAY)
+      mp_zero(&S);
+
+    while (res == MP_OKAY && mp_iseven(&Q) == MP_YES) {
+      /* Q = Q / 2 */
+      res = mp_div_2(&Q, &Q);
+
+      /* S = S + 1 */
+      if (res == MP_OKAY)
+        res = mp_add_d(&S, 1, &S);
+    }
+
+    /* find a Z such that the Legendre symbol (Z|prime) == -1 */
+    /* Z = 2 */
+    if (res == MP_OKAY)
+      res = mp_set_int(&Z, 2);
+
+    while (res == MP_OKAY) {
+      res = mp_jacobi(&Z, prime, &legendre);
+      if (res == MP_OKAY && legendre == -1)
+        break;
+
+      /* Z = Z + 1 */
+      if (res == MP_OKAY)
+        res = mp_add_d(&Z, 1, &Z);
+    }
+
+    /* C = Z ^ Q mod prime */
+    if (res == MP_OKAY)
+      res = mp_exptmod(&Z, &Q, prime, &C);
+
+    /* t1 = (Q + 1) / 2 */
+    if (res == MP_OKAY)
+      res = mp_add_d(&Q, 1, &t1);
+    if (res == MP_OKAY)
+      res = mp_div_2(&t1, &t1);
+
+    /* R = n ^ ((Q + 1) / 2) mod prime */
+    if (res == MP_OKAY)
+      res = mp_exptmod(n, &t1, prime, &R);
+
+    /* T = n ^ Q mod prime */
+    if (res == MP_OKAY)
+      res = mp_exptmod(n, &Q, prime, &T);
+
+    /* M = S */
+    if (res == MP_OKAY)
+      res = mp_copy(&S, &M);
+
+    if (res == MP_OKAY)
+      res = mp_set_int(&two, 2);
+
+    while (res == MP_OKAY && done == 0) {
+      res = mp_copy(&T, &t1);
+
+      /* reduce to 1 and count */
+      i = 0;
+      while (res == MP_OKAY) {
+        if (mp_cmp_d(&t1, 1) == MP_EQ)
+            break;
+        res = mp_exptmod(&t1, &two, prime, &t1);
+        if (res == MP_OKAY)
+          i++;
+      }
+      if (res == MP_OKAY && i == 0) {
+        res = mp_copy(&R, ret);
+        done = 1;
+      }
+
+      if (done == 0) {
+        /* t1 = 2 ^ (M - i - 1) */
+        if (res == MP_OKAY)
+          res = mp_sub_d(&M, i, &t1);
+        if (res == MP_OKAY)
+          res = mp_sub_d(&t1, 1, &t1);
+        if (res == MP_OKAY)
+          res = mp_exptmod(&two, &t1, prime, &t1);
+
+        /* t1 = C ^ (2 ^ (M - i - 1)) mod prime */
+        if (res == MP_OKAY)
+          res = mp_exptmod(&C, &t1, prime, &t1);
+
+        /* C = (t1 * t1) mod prime */
+        if (res == MP_OKAY)
+          res = mp_sqrmod(&t1, prime, &C);
+
+        /* R = (R * t1) mod prime */
+        if (res == MP_OKAY)
+          res = mp_mulmod(&R, &t1, prime, &R);
+
+        /* T = (T * C) mod prime */
+        if (res == MP_OKAY)
+          res = mp_mulmod(&T, &C, prime, &T);
+
+        /* M = i */
+        if (res == MP_OKAY)
+          res = mp_set(&M, i);
+      }
+    }
+  }
+
+  /* done */
+  mp_clear(&t1);
+  mp_clear(&C);
+  mp_clear(&Q);
+  mp_clear(&S);
+  mp_clear(&Z);
+  mp_clear(&M);
+  mp_clear(&T);
+  mp_clear(&R);
+  mp_clear(&two);
+
+  return res;
+#endif
+}
+#endif
+#endif /* !WOLFSSL_ATECC508A && !WOLFSSL_CRYPTOCELL */
+
+
+/* export public ECC key in ANSI X9.63 format compressed */
+static int wc_ecc_export_x963_compressed(ecc_key* key, byte* out, word32* outLen)
+{
+   word32 numlen;
+   int    ret = MP_OKAY;
+
+   if (key == NULL || out == NULL || outLen == NULL)
+       return BAD_FUNC_ARG;
+
+   if (wc_ecc_is_valid_idx(key->idx) == 0) {
+      return ECC_BAD_ARG_E;
+   }
+   numlen = key->dp->size;
+
+   if (*outLen < (1 + numlen)) {
+      *outLen = 1 + numlen;
+      return BUFFER_E;
+   }
+
+   /* store first byte */
+   out[0] = mp_isodd(key->pubkey.y) == MP_YES ? ECC_POINT_COMP_ODD : ECC_POINT_COMP_EVEN;
+
+   /* pad and store x */
+   XMEMSET(out+1, 0, numlen);
+   ret = mp_to_unsigned_bin(key->pubkey.x,
+                       out+1 + (numlen - mp_unsigned_bin_size(key->pubkey.x)));
+   *outLen = 1 + numlen;
+
+   return ret;
+}
+
+#endif /* HAVE_COMP_KEY */
+
+
+int wc_ecc_get_oid(word32 oidSum, const byte** oid, word32* oidSz)
+{
+    int x;
+
+    if (oidSum == 0) {
+        return BAD_FUNC_ARG;
+    }
+
+    /* find matching OID sum (based on encoded value) */
+    for (x = 0; ecc_sets[x].size != 0; x++) {
+        if (ecc_sets[x].oidSum == oidSum) {
+            int ret;
+        #ifdef HAVE_OID_ENCODING
+            ret = 0;
+            /* check cache */
+            oid_cache_t* o = &ecc_oid_cache[x];
+            if (o->oidSz == 0) {
+                o->oidSz = sizeof(o->oid);
+                ret = EncodeObjectId(ecc_sets[x].oid, ecc_sets[x].oidSz,
+                                                            o->oid, &o->oidSz);
+            }
+            if (oidSz) {
+                *oidSz = o->oidSz;
+            }
+            if (oid) {
+                *oid = o->oid;
+            }
+            /* on success return curve id */
+            if (ret == 0) {
+                ret = ecc_sets[x].id;
+            }
+        #else
+            if (oidSz) {
+                *oidSz = ecc_sets[x].oidSz;
+            }
+            if (oid) {
+                *oid = ecc_sets[x].oid;
+            }
+            ret = ecc_sets[x].id;
+        #endif
+            return ret;
+        }
+    }
+
+    return NOT_COMPILED_IN;
+}
+
+#ifdef WOLFSSL_CUSTOM_CURVES
+int wc_ecc_set_custom_curve(ecc_key* key, const ecc_set_type* dp)
+{
+    if (key == NULL || dp == NULL) {
+        return BAD_FUNC_ARG;
+    }
+
+    key->idx = ECC_CUSTOM_IDX;
+    key->dp = dp;
+
+    return 0;
+}
+#endif /* WOLFSSL_CUSTOM_CURVES */
+
+#ifdef HAVE_X963_KDF
+
+static WC_INLINE void IncrementX963KdfCounter(byte* inOutCtr)
+{
+    int i;
+
+    /* in network byte order so start at end and work back */
+    for (i = 3; i >= 0; i--) {
+        if (++inOutCtr[i])  /* we're done unless we overflow */
+            return;
+    }
+}
+
+/* ASN X9.63 Key Derivation Function (SEC1) */
+int wc_X963_KDF(enum wc_HashType type, const byte* secret, word32 secretSz,
+                const byte* sinfo, word32 sinfoSz, byte* out, word32 outSz)
+{
+    int ret, i;
+    int digestSz, copySz;
+    int remaining = outSz;
+    byte* outIdx;
+    byte  counter[4];
+    byte  tmp[WC_MAX_DIGEST_SIZE];
+
+#ifdef WOLFSSL_SMALL_STACK
+    wc_HashAlg* hash;
+#else
+    wc_HashAlg hash[1];
+#endif
+
+    if (secret == NULL || secretSz == 0 || out == NULL)
+        return BAD_FUNC_ARG;
+
+    /* X9.63 allowed algos only */
+    if (type != WC_HASH_TYPE_SHA    && type != WC_HASH_TYPE_SHA224 &&
+        type != WC_HASH_TYPE_SHA256 && type != WC_HASH_TYPE_SHA384 &&
+        type != WC_HASH_TYPE_SHA512)
+        return BAD_FUNC_ARG;
+
+    digestSz = wc_HashGetDigestSize(type);
+    if (digestSz < 0)
+        return digestSz;
+
+#ifdef WOLFSSL_SMALL_STACK
+    hash = (wc_HashAlg*)XMALLOC(sizeof(wc_HashAlg), NULL,
+                                DYNAMIC_TYPE_HASHES);
+    if (hash == NULL)
+        return MEMORY_E;
+#endif
+
+    ret = wc_HashInit(hash, type);
+    if (ret != 0) {
+#ifdef WOLFSSL_SMALL_STACK
+        XFREE(hash, NULL, DYNAMIC_TYPE_HASHES);
+#endif
+        return ret;
+    }
+
+    outIdx = out;
+    XMEMSET(counter, 0, sizeof(counter));
+
+    for (i = 1; remaining > 0; i++) {
+
+        IncrementX963KdfCounter(counter);
+
+        ret = wc_HashUpdate(hash, type, secret, secretSz);
+        if (ret != 0) {
+            break;
+        }
+
+        ret = wc_HashUpdate(hash, type, counter, sizeof(counter));
+        if (ret != 0) {
+            break;
+        }
+
+        if (sinfo) {
+            ret = wc_HashUpdate(hash, type, sinfo, sinfoSz);
+            if (ret != 0) {
+                break;
+            }
+        }
+
+        ret = wc_HashFinal(hash, type, tmp);
+        if (ret != 0) {
+            break;
+        }
+
+        copySz = min(remaining, digestSz);
+        XMEMCPY(outIdx, tmp, copySz);
+
+        remaining -= copySz;
+        outIdx += copySz;
+    }
+
+    wc_HashFree(hash, type);
+
+#ifdef WOLFSSL_SMALL_STACK
+     XFREE(hash, NULL, DYNAMIC_TYPE_HASHES);
+#endif
+
+    return ret;
+}
+#endif /* HAVE_X963_KDF */
+
+#endif /* HAVE_ECC */
Index: azure_iot_hub_f767zi/trunk/wolfssl-4.4.0/wolfcrypt/src/error.c
===================================================================
--- azure_iot_hub_f767zi/trunk/wolfssl-4.4.0/wolfcrypt/src/error.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/wolfssl-4.4.0/wolfcrypt/src/error.c	(revision 457)
@@ -0,0 +1,530 @@
+/* error.c
+ *
+ * Copyright (C) 2006-2020 wolfSSL Inc.
+ *
+ * This file is part of wolfSSL.
+ *
+ * wolfSSL is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * wolfSSL is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
+ */
+
+
+#ifdef HAVE_CONFIG_H
+    #include <config.h>
+#endif
+
+#include <wolfssl/wolfcrypt/settings.h>
+
+#include <wolfssl/wolfcrypt/error-crypt.h>
+
+#ifdef _MSC_VER
+    /* 4996 warning to use MS extensions e.g., strcpy_s instead of XSTRNCPY */
+    #pragma warning(disable: 4996)
+#endif
+
+#ifndef NO_ERROR_STRINGS
+const char* wc_GetErrorString(int error)
+{
+    switch (error) {
+
+    case OPEN_RAN_E :
+        return "opening random device error";
+
+    case READ_RAN_E :
+        return "reading random device error";
+
+    case WINCRYPT_E :
+        return "windows crypt init error";
+
+    case CRYPTGEN_E :
+        return "windows crypt generation error";
+
+    case RAN_BLOCK_E :
+        return "random device read would block error";
+
+    case BAD_MUTEX_E :
+        return "Bad mutex, operation failed";
+
+    case WC_TIMEOUT_E:
+        return "Timeout error";
+
+    case WC_PENDING_E:
+        return "wolfCrypt Operation Pending (would block / eagain) error";
+
+    case WC_NOT_PENDING_E:
+        return "wolfCrypt operation not pending error";
+
+    case MP_INIT_E :
+        return "mp_init error state";
+
+    case MP_READ_E :
+        return "mp_read error state";
+
+    case MP_EXPTMOD_E :
+        return "mp_exptmod error state";
+
+    case MP_TO_E :
+        return "mp_to_xxx error state, can't convert";
+
+    case MP_SUB_E :
+        return "mp_sub error state, can't subtract";
+
+    case MP_ADD_E :
+        return "mp_add error state, can't add";
+
+    case MP_MUL_E :
+        return "mp_mul error state, can't multiply";
+
+    case MP_MULMOD_E :
+        return "mp_mulmod error state, can't multiply mod";
+
+    case MP_MOD_E :
+        return "mp_mod error state, can't mod";
+
+    case MP_INVMOD_E :
+        return "mp_invmod error state, can't inv mod";
+
+    case MP_CMP_E :
+        return "mp_cmp error state";
+
+    case MP_ZERO_E :
+        return "mp zero result, not expected";
+
+    case MEMORY_E :
+        return "out of memory error";
+
+    case VAR_STATE_CHANGE_E :
+        return "Variable state modified by different thread";
+
+    case RSA_WRONG_TYPE_E :
+        return "RSA wrong block type for RSA function";
+
+    case RSA_BUFFER_E :
+        return "RSA buffer error, output too small or input too big";
+
+    case BUFFER_E :
+        return "Buffer error, output too small or input too big";
+
+    case ALGO_ID_E :
+        return "Setting Cert AlgoID error";
+
+    case PUBLIC_KEY_E :
+        return "Setting Cert Public Key error";
+
+    case DATE_E :
+        return "Setting Cert Date validity error";
+
+    case SUBJECT_E :
+        return "Setting Cert Subject name error";
+
+    case ISSUER_E :
+        return "Setting Cert Issuer name error";
+
+    case CA_TRUE_E :
+        return "Setting basic constraint CA true error";
+
+    case EXTENSIONS_E :
+        return "Setting extensions error";
+
+    case ASN_PARSE_E :
+        return "ASN parsing error, invalid input";
+
+    case ASN_VERSION_E :
+        return "ASN version error, invalid number";
+
+    case ASN_GETINT_E :
+        return "ASN get big int error, invalid data";
+
+    case ASN_RSA_KEY_E :
+        return "ASN key init error, invalid input";
+
+    case ASN_OBJECT_ID_E :
+        return "ASN object id error, invalid id";
+
+    case ASN_TAG_NULL_E :
+        return "ASN tag error, not null";
+
+    case ASN_EXPECT_0_E :
+        return "ASN expect error, not zero";
+
+    case ASN_BITSTR_E :
+        return "ASN bit string error, wrong id";
+
+    case ASN_UNKNOWN_OID_E :
+        return "ASN oid error, unknown sum id";
+
+    case ASN_DATE_SZ_E :
+        return "ASN date error, bad size";
+
+    case ASN_BEFORE_DATE_E :
+        return "ASN date error, current date before";
+
+    case ASN_AFTER_DATE_E :
+        return "ASN date error, current date after";
+
+    case ASN_SIG_OID_E :
+        return "ASN signature error, mismatched oid";
+
+    case ASN_TIME_E :
+        return "ASN time error, unknown time type";
+
+    case ASN_INPUT_E :
+        return "ASN input error, not enough data";
+
+    case ASN_SIG_CONFIRM_E :
+        return "ASN sig error, confirm failure";
+
+    case ASN_SIG_HASH_E :
+        return "ASN sig error, unsupported hash type";
+
+    case ASN_SIG_KEY_E :
+        return "ASN sig error, unsupported key type";
+
+    case ASN_DH_KEY_E :
+        return "ASN key init error, invalid input";
+
+    case ASN_NTRU_KEY_E :
+        return "ASN NTRU key decode error, invalid input";
+
+    case ASN_CRIT_EXT_E:
+        return "X.509 Critical extension ignored or invalid";
+
+    case ASN_ALT_NAME_E:
+        return "ASN alternate name error";
+
+    case ECC_BAD_ARG_E :
+        return "ECC input argument wrong type, invalid input";
+
+    case ASN_ECC_KEY_E :
+        return "ECC ASN1 bad key data, invalid input";
+
+    case ECC_CURVE_OID_E :
+        return "ECC curve sum OID unsupported, invalid input";
+
+    case BAD_FUNC_ARG :
+        return "Bad function argument";
+
+    case NOT_COMPILED_IN :
+        return "Feature not compiled in";
+
+    case UNICODE_SIZE_E :
+        return "Unicode password too big";
+
+    case NO_PASSWORD :
+        return "No password provided by user";
+
+    case ALT_NAME_E :
+        return "Alt Name problem, too big";
+
+    case AES_GCM_AUTH_E:
+        return "AES-GCM Authentication check fail";
+
+    case AES_CCM_AUTH_E:
+        return "AES-CCM Authentication check fail";
+
+    case ASYNC_INIT_E:
+        return "Async Init error";
+
+    case COMPRESS_INIT_E:
+        return "Compress Init error";
+
+    case COMPRESS_E:
+        return "Compress error";
+
+    case DECOMPRESS_INIT_E:
+        return "DeCompress Init error";
+
+    case DECOMPRESS_E:
+        return "DeCompress error";
+
+    case BAD_ALIGN_E:
+        return "Bad alignment error, no alloc help";
+
+    case ASN_NO_SIGNER_E :
+        return "ASN no signer error to confirm failure";
+
+    case ASN_CRL_CONFIRM_E :
+        return "ASN CRL sig error, confirm failure";
+
+    case ASN_CRL_NO_SIGNER_E :
+        return "ASN CRL no signer error to confirm failure";
+
+    case ASN_OCSP_CONFIRM_E :
+        return "ASN OCSP sig error, confirm failure";
+
+    case ASN_NO_PEM_HEADER:
+        return "ASN no PEM Header Error";
+
+    case BAD_STATE_E:
+        return "Bad state operation";
+
+    case BAD_PADDING_E:
+        return "Bad padding, message wrong length";
+
+    case REQ_ATTRIBUTE_E:
+        return "Setting cert request attributes error";
+
+    case PKCS7_OID_E:
+        return "PKCS#7 error: mismatched OID value";
+
+    case PKCS7_RECIP_E:
+        return "PKCS#7 error: no matching recipient found";
+
+    case WC_PKCS7_WANT_READ_E:
+        return "PKCS#7 operations wants more input, call again";
+
+    case FIPS_NOT_ALLOWED_E:
+        return "FIPS mode not allowed error";
+
+    case ASN_NAME_INVALID_E:
+        return "Name Constraint error";
+
+    case RNG_FAILURE_E:
+        return "Random Number Generator failed";
+
+    case HMAC_MIN_KEYLEN_E:
+        return "FIPS Mode HMAC Minimum Key Length error";
+
+    case RSA_PAD_E:
+        return "Rsa Padding error";
+
+    case LENGTH_ONLY_E:
+        return "Output length only set, not for other use error";
+
+    case IN_CORE_FIPS_E:
+        return "In Core Integrity check FIPS error";
+
+    case AES_KAT_FIPS_E:
+        return "AES Known Answer Test check FIPS error";
+
+    case DES3_KAT_FIPS_E:
+        return "DES3 Known Answer Test check FIPS error";
+
+    case HMAC_KAT_FIPS_E:
+        return "HMAC Known Answer Test check FIPS error";
+
+    case RSA_KAT_FIPS_E:
+        return "RSA Known Answer Test check FIPS error";
+
+    case DRBG_KAT_FIPS_E:
+        return "DRBG Known Answer Test check FIPS error";
+
+    case DRBG_CONT_FIPS_E:
+        return "DRBG Continuous Test FIPS error";
+
+    case AESGCM_KAT_FIPS_E:
+        return "AESGCM Known Answer Test check FIPS error";
+
+    case THREAD_STORE_KEY_E:
+        return "Thread Storage Key Create error";
+
+    case THREAD_STORE_SET_E:
+        return "Thread Storage Set error";
+
+    case MAC_CMP_FAILED_E:
+        return "MAC comparison failed";
+
+    case IS_POINT_E:
+        return "ECC is point on curve failed";
+
+    case ECC_INF_E:
+        return " ECC point at infinity error";
+
+    case ECC_OUT_OF_RANGE_E:
+        return " ECC Qx or Qy out of range error";
+
+    case ECC_PRIV_KEY_E:
+        return " ECC private key is not valid error";
+
+    case SRP_CALL_ORDER_E:
+        return "SRP function called in the wrong order error";
+
+    case SRP_VERIFY_E:
+        return "SRP proof verification error";
+
+    case SRP_BAD_KEY_E:
+        return "SRP bad key values error";
+
+    case ASN_NO_SKID:
+        return "ASN no Subject Key Identifier found error";
+
+    case ASN_NO_AKID:
+        return "ASN no Authority Key Identifier found error";
+
+    case ASN_NO_KEYUSAGE:
+        return "ASN no Key Usage found error";
+
+    case SKID_E:
+        return "Setting Subject Key Identifier error";
+
+    case AKID_E:
+        return "Setting Authority Key Identifier error";
+
+    case KEYUSAGE_E:
+        return "Key Usage value error";
+
+    case EXTKEYUSAGE_E:
+        return "Extended Key Usage value error";
+
+    case CERTPOLICIES_E:
+        return "Setting Certificate Policies error";
+
+    case WC_INIT_E:
+        return "wolfCrypt Initialize Failure error";
+
+    case SIG_VERIFY_E:
+        return "Signature verify error";
+
+    case BAD_COND_E:
+        return "Bad condition variable operation error";
+
+    case SIG_TYPE_E:
+        return "Signature type not enabled/available";
+
+    case HASH_TYPE_E:
+        return "Hash type not enabled/available";
+
+    case WC_KEY_SIZE_E:
+        return "Key size error, either too small or large";
+
+    case ASN_COUNTRY_SIZE_E:
+        return "Country code size error, either too small or large";
+
+    case MISSING_RNG_E:
+        return "RNG required but not provided";
+
+    case ASN_PATHLEN_SIZE_E:
+        return "ASN CA path length value too large error";
+
+    case ASN_PATHLEN_INV_E:
+        return "ASN CA path length larger than signer error";
+
+    case BAD_KEYWRAP_ALG_E:
+        return "Unsupported key wrap algorithm error";
+
+    case BAD_KEYWRAP_IV_E:
+        return "Decrypted AES key wrap IV does not match expected";
+
+    case WC_CLEANUP_E:
+        return "wolfcrypt cleanup failed";
+
+    case ECC_CDH_KAT_FIPS_E:
+        return "wolfcrypt FIPS ECC CDH Known Answer Test Failure";
+
+    case DH_CHECK_PUB_E:
+        return "DH Check Public Key failure";
+
+    case BAD_PATH_ERROR:
+        return "Bad path for opendir error";
+
+    case ASYNC_OP_E:
+        return "Async operation error";
+
+    case BAD_OCSP_RESPONDER:
+        return "Invalid OCSP Responder, missing specific key usage extensions";
+
+    case ECC_PRIVATEONLY_E:
+        return "Invalid use of private only ECC key";
+
+    case WC_HW_E:
+        return "Error with hardware crypto use";
+
+    case WC_HW_WAIT_E:
+        return "Hardware waiting on resource";
+
+    case PSS_SALTLEN_E:
+        return "PSS - Length of salt is too big for hash algorithm";
+
+    case PRIME_GEN_E:
+        return "Unable to find a prime for RSA key";
+
+    case BER_INDEF_E:
+        return "Unable to decode an indefinite length encoded message";
+
+    case RSA_OUT_OF_RANGE_E:
+        return "Ciphertext to decrypt is out of range";
+
+    case RSAPSS_PAT_FIPS_E:
+        return "wolfcrypt FIPS RSA-PSS Pairwise Agreement Test Failure";
+
+    case ECDSA_PAT_FIPS_E:
+        return "wolfcrypt FIPS ECDSA Pairwise Agreement Test Failure";
+
+    case DH_KAT_FIPS_E:
+        return "wolfcrypt FIPS DH Known Answer Test Failure";
+
+    case AESCCM_KAT_FIPS_E:
+        return "AESCCM Known Answer Test check FIPS error";
+
+    case SHA3_KAT_FIPS_E:
+        return "SHA-3 Known Answer Test check FIPS error";
+
+    case ECDHE_KAT_FIPS_E:
+        return "wolfcrypt FIPS ECDHE Known Answer Test Failure";
+
+    case AES_GCM_OVERFLOW_E:
+        return "AES-GCM invocation counter overflow";
+
+    case AES_CCM_OVERFLOW_E:
+        return "AES-CCM invocation counter overflow";
+
+    case RSA_KEY_PAIR_E:
+        return "RSA Key Pair-Wise Consistency check fail";
+
+    case DH_CHECK_PRIV_E:
+        return "DH Check Private Key failure";
+
+    case WC_AFALG_SOCK_E:
+        return "AF_ALG socket error";
+
+    case WC_DEVCRYPTO_E:
+        return "Error with /dev/crypto";
+
+    case ZLIB_INIT_ERROR:
+        return "zlib init error";
+
+    case ZLIB_COMPRESS_ERROR:
+        return "zlib compress error";
+
+    case ZLIB_DECOMPRESS_ERROR:
+        return "zlib decompress error";
+
+    case PKCS7_NO_SIGNER_E:
+        return "No signer in PKCS#7 signed data";
+
+    case CRYPTOCB_UNAVAILABLE:
+        return "Crypto callback unavailable";
+
+    case PKCS7_SIGNEEDS_CHECK:
+        return "Signature found but no certificate to verify";
+
+    case PSS_SALTLEN_RECOVER_E:
+        return "PSS - Salt length unable to be recovered";
+
+    case ASN_SELF_SIGNED_E:
+        return "ASN self-signed certificate error";
+
+    default:
+        return "unknown error number";
+
+    }
+}
+
+void wc_ErrorString(int error, char* buffer)
+{
+    XSTRNCPY(buffer, wc_GetErrorString(error), WOLFSSL_MAX_ERROR_SZ);
+    buffer[WOLFSSL_MAX_ERROR_SZ-1] = 0;
+}
+#endif /* !NO_ERROR_STRINGS */
+
Index: azure_iot_hub_f767zi/trunk/wolfssl-4.4.0/wolfcrypt/src/evp.c
===================================================================
--- azure_iot_hub_f767zi/trunk/wolfssl-4.4.0/wolfcrypt/src/evp.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/wolfssl-4.4.0/wolfcrypt/src/evp.c	(revision 457)
@@ -0,0 +1,6595 @@
+/* evp.c
+ *
+ * Copyright (C) 2006-2020 wolfSSL Inc.
+ *
+ * This file is part of wolfSSL.
+ *
+ * wolfSSL is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * wolfSSL is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
+ */
+
+#if !defined(WOLFSSL_EVP_INCLUDED)
+    #ifndef WOLFSSL_IGNORE_FILE_WARN
+        #warning evp.c does not need to be compiled separately from ssl.c
+    #endif
+#elif defined(WOLFCRYPT_ONLY)
+#else
+
+#ifdef HAVE_CONFIG_H
+    #include <config.h>
+#endif
+
+#include <wolfssl/wolfcrypt/settings.h>
+
+#include <wolfssl/openssl/ecdsa.h>
+#include <wolfssl/openssl/evp.h>
+
+#if defined(OPENSSL_EXTRA)
+
+#ifndef NO_AES
+    #ifdef HAVE_AES_CBC
+    #ifdef WOLFSSL_AES_128
+        static char *EVP_AES_128_CBC = NULL;
+    #endif
+    #ifdef WOLFSSL_AES_192
+        static char *EVP_AES_192_CBC = NULL;
+    #endif
+    #ifdef WOLFSSL_AES_256
+        static char *EVP_AES_256_CBC = NULL;
+    #endif
+    #endif /* HAVE_AES_CBC */
+
+    #ifdef WOLFSSL_AES_OFB
+    #ifdef WOLFSSL_AES_128
+        static char *EVP_AES_128_OFB = NULL;
+    #endif
+    #ifdef WOLFSSL_AES_192
+        static char *EVP_AES_192_OFB = NULL;
+    #endif
+    #ifdef WOLFSSL_AES_256
+        static char *EVP_AES_256_OFB = NULL;
+    #endif
+    #endif /* WOLFSSL_AES_OFB */
+
+    #ifdef WOLFSSL_AES_XTS
+    #ifdef WOLFSSL_AES_128
+        static char *EVP_AES_128_XTS = NULL;
+    #endif
+    #ifdef WOLFSSL_AES_256
+        static char *EVP_AES_256_XTS = NULL;
+    #endif
+    #endif /* WOLFSSL_AES_XTS */
+
+    #ifdef WOLFSSL_AES_CFB
+    #ifdef WOLFSSL_AES_128
+        static char *EVP_AES_128_CFB1 = NULL;
+    #endif
+    #ifdef WOLFSSL_AES_192
+        static char *EVP_AES_192_CFB1 = NULL;
+    #endif
+    #ifdef WOLFSSL_AES_256
+        static char *EVP_AES_256_CFB1 = NULL;
+    #endif
+
+    #ifdef WOLFSSL_AES_128
+        static char *EVP_AES_128_CFB8 = NULL;
+    #endif
+    #ifdef WOLFSSL_AES_192
+        static char *EVP_AES_192_CFB8 = NULL;
+    #endif
+    #ifdef WOLFSSL_AES_256
+        static char *EVP_AES_256_CFB8 = NULL;
+    #endif
+
+    #ifdef WOLFSSL_AES_128
+        static char *EVP_AES_128_CFB128 = NULL;
+    #endif
+    #ifdef WOLFSSL_AES_192
+        static char *EVP_AES_192_CFB128 = NULL;
+    #endif
+    #ifdef WOLFSSL_AES_256
+        static char *EVP_AES_256_CFB128 = NULL;
+    #endif
+    #endif /* WOLFSSL_AES_CFB */
+
+    #ifdef HAVE_AESGCM
+        #ifdef WOLFSSL_AES_128
+            static char *EVP_AES_128_GCM = NULL;
+        #endif
+        #ifdef WOLFSSL_AES_192
+            static char *EVP_AES_192_GCM = NULL;
+        #endif
+        #ifdef WOLFSSL_AES_256
+            static char *EVP_AES_256_GCM = NULL;
+        #endif
+    #endif /* HAVE_AESGCM */
+    #ifdef WOLFSSL_AES_128
+        static char *EVP_AES_128_CTR = NULL;
+    #endif
+    #ifdef WOLFSSL_AES_192
+        static char *EVP_AES_192_CTR = NULL;
+    #endif
+    #ifdef WOLFSSL_AES_256
+        static char *EVP_AES_256_CTR = NULL;
+    #endif
+
+    #ifdef WOLFSSL_AES_128
+        static char *EVP_AES_128_ECB = NULL;
+    #endif
+    #ifdef WOLFSSL_AES_192
+        static char *EVP_AES_192_ECB = NULL;
+    #endif
+    #ifdef WOLFSSL_AES_256
+        static char *EVP_AES_256_ECB = NULL;
+    #endif
+        #define      EVP_AES_SIZE 11
+    #ifdef WOLFSSL_AES_CFB
+        #define      EVP_AESCFB_SIZE 14
+    #endif
+#endif
+
+#ifndef NO_DES3
+    static char *EVP_DES_CBC = NULL;
+    static char *EVP_DES_ECB = NULL;
+
+    static char *EVP_DES_EDE3_CBC = NULL;
+    static char *EVP_DES_EDE3_ECB = NULL;
+
+    #define EVP_DES_SIZE 7
+    #define EVP_DES_EDE3_SIZE 12
+#endif
+
+#ifdef HAVE_IDEA
+    static char *EVP_IDEA_CBC;
+    #define EVP_IDEA_SIZE 8
+#endif
+
+static unsigned int cipherType(const WOLFSSL_EVP_CIPHER *cipher);
+
+
+/* Getter function for cipher key length
+ *
+ * c  WOLFSSL_EVP_CIPHER structure to get key length from
+ *
+ * NOTE: OpenSSL_add_all_ciphers() should be called first before using this
+ *       function
+ *
+ * Returns size of key in bytes
+ */
+int wolfSSL_EVP_Cipher_key_length(const WOLFSSL_EVP_CIPHER* c)
+{
+    WOLFSSL_ENTER("wolfSSL_EVP_Cipher_key_length");
+
+    if (c == NULL) {
+        return 0;
+    }
+
+    switch (cipherType(c)) {
+#if !defined(NO_AES)
+  #if defined(HAVE_AES_CBC)
+      case AES_128_CBC_TYPE: return 16;
+      case AES_192_CBC_TYPE: return 24;
+      case AES_256_CBC_TYPE: return 32;
+  #endif
+  #if defined(WOLFSSL_AES_CFB)
+      case AES_128_CFB1_TYPE: return 16;
+      case AES_192_CFB1_TYPE: return 24;
+      case AES_256_CFB1_TYPE: return 32;
+      case AES_128_CFB8_TYPE: return 16;
+      case AES_192_CFB8_TYPE: return 24;
+      case AES_256_CFB8_TYPE: return 32;
+      case AES_128_CFB128_TYPE: return 16;
+      case AES_192_CFB128_TYPE: return 24;
+      case AES_256_CFB128_TYPE: return 32;
+  #endif
+  #if defined(WOLFSSL_AES_OFB)
+      case AES_128_OFB_TYPE: return 16;
+      case AES_192_OFB_TYPE: return 24;
+      case AES_256_OFB_TYPE: return 32;
+  #endif
+  #if defined(WOLFSSL_AES_XTS)
+      case AES_128_XTS_TYPE: return 16;
+      case AES_256_XTS_TYPE: return 32;
+  #endif
+  #if defined(HAVE_AESGCM)
+      case AES_128_GCM_TYPE: return 16;
+      case AES_192_GCM_TYPE: return 24;
+      case AES_256_GCM_TYPE: return 32;
+  #endif
+  #if defined(WOLFSSL_AES_COUNTER)
+      case AES_128_CTR_TYPE: return 16;
+      case AES_192_CTR_TYPE: return 24;
+      case AES_256_CTR_TYPE: return 32;
+  #endif
+  #if defined(HAVE_AES_ECB)
+      case AES_128_ECB_TYPE: return 16;
+      case AES_192_ECB_TYPE: return 24;
+      case AES_256_ECB_TYPE: return 32;
+  #endif
+#endif /* !NO_AES */
+  #ifndef NO_DES3
+      case DES_CBC_TYPE:      return 8;
+      case DES_EDE3_CBC_TYPE: return 24;
+      case DES_ECB_TYPE:      return 8;
+      case DES_EDE3_ECB_TYPE: return 24;
+  #endif
+      default:
+          return 0;
+      }
+}
+
+
+int  wolfSSL_EVP_EncryptInit(WOLFSSL_EVP_CIPHER_CTX* ctx,
+                                        const WOLFSSL_EVP_CIPHER* type,
+                                        const unsigned char* key,
+                                        const unsigned char* iv)
+{
+    return wolfSSL_EVP_CipherInit(ctx, type, (byte*)key, (byte*)iv, 1);
+}
+
+int  wolfSSL_EVP_EncryptInit_ex(WOLFSSL_EVP_CIPHER_CTX* ctx,
+                                        const WOLFSSL_EVP_CIPHER* type,
+                                        WOLFSSL_ENGINE *impl,
+                                        const unsigned char* key,
+                                        const unsigned char* iv)
+{
+    (void) impl;
+    return wolfSSL_EVP_CipherInit(ctx, type, (byte*)key, (byte*)iv, 1);
+}
+
+int  wolfSSL_EVP_DecryptInit(WOLFSSL_EVP_CIPHER_CTX* ctx,
+                                        const WOLFSSL_EVP_CIPHER* type,
+                                        const unsigned char* key,
+                                        const unsigned char* iv)
+{
+    WOLFSSL_ENTER("wolfSSL_EVP_CipherInit");
+    return wolfSSL_EVP_CipherInit(ctx, type, (byte*)key, (byte*)iv, 0);
+}
+
+int  wolfSSL_EVP_DecryptInit_ex(WOLFSSL_EVP_CIPHER_CTX* ctx,
+                                        const WOLFSSL_EVP_CIPHER* type,
+                                        WOLFSSL_ENGINE *impl,
+                                        const unsigned char* key,
+                                        const unsigned char* iv)
+{
+    (void) impl;
+    WOLFSSL_ENTER("wolfSSL_EVP_DecryptInit");
+    return wolfSSL_EVP_CipherInit(ctx, type, (byte*)key, (byte*)iv, 0);
+}
+
+
+WOLFSSL_EVP_CIPHER_CTX *wolfSSL_EVP_CIPHER_CTX_new(void)
+{
+    WOLFSSL_EVP_CIPHER_CTX *ctx = (WOLFSSL_EVP_CIPHER_CTX*)XMALLOC(sizeof *ctx,
+                                                 NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    if (ctx) {
+        WOLFSSL_ENTER("wolfSSL_EVP_CIPHER_CTX_new");
+        wolfSSL_EVP_CIPHER_CTX_init(ctx);
+    }
+    return ctx;
+}
+
+void wolfSSL_EVP_CIPHER_CTX_free(WOLFSSL_EVP_CIPHER_CTX *ctx)
+{
+    if (ctx) {
+        WOLFSSL_ENTER("wolfSSL_EVP_CIPHER_CTX_free");
+        wolfSSL_EVP_CIPHER_CTX_cleanup(ctx);
+        XFREE(ctx, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    }
+}
+
+int wolfSSL_EVP_CIPHER_CTX_reset(WOLFSSL_EVP_CIPHER_CTX *ctx)
+{
+    int ret = WOLFSSL_FAILURE;
+
+    if (ctx != NULL) {
+        WOLFSSL_ENTER("wolfSSL_EVP_CIPHER_CTX_reset");
+        wolfSSL_EVP_CIPHER_CTX_cleanup(ctx);
+        ret = WOLFSSL_SUCCESS;
+    }
+
+    return ret;
+}
+
+unsigned long wolfSSL_EVP_CIPHER_CTX_mode(const WOLFSSL_EVP_CIPHER_CTX *ctx)
+{
+  if (ctx == NULL) return 0;
+  return ctx->flags & WOLFSSL_EVP_CIPH_MODE;
+}
+
+int  wolfSSL_EVP_EncryptFinal(WOLFSSL_EVP_CIPHER_CTX *ctx,
+                                   unsigned char *out, int *outl)
+{
+    if (ctx && ctx->enc) {
+        WOLFSSL_ENTER("wolfSSL_EVP_EncryptFinal");
+        return wolfSSL_EVP_CipherFinal(ctx, out, outl);
+    }
+    else
+        return WOLFSSL_FAILURE;
+}
+
+
+int  wolfSSL_EVP_CipherInit_ex(WOLFSSL_EVP_CIPHER_CTX* ctx,
+                                    const WOLFSSL_EVP_CIPHER* type,
+                                    WOLFSSL_ENGINE *impl,
+                                    const unsigned char* key,
+                                    const unsigned char* iv,
+                                    int enc)
+{
+    (void)impl;
+    return wolfSSL_EVP_CipherInit(ctx, type, key, iv, enc);
+}
+
+int  wolfSSL_EVP_EncryptFinal_ex(WOLFSSL_EVP_CIPHER_CTX *ctx,
+                                   unsigned char *out, int *outl)
+{
+    if (ctx && ctx->enc) {
+        WOLFSSL_ENTER("wolfSSL_EVP_EncryptFinal_ex");
+        return wolfSSL_EVP_CipherFinal(ctx, out, outl);
+    }
+    else
+        return WOLFSSL_FAILURE;
+}
+
+int  wolfSSL_EVP_DecryptFinal(WOLFSSL_EVP_CIPHER_CTX *ctx,
+                                   unsigned char *out, int *outl)
+{
+    if (ctx && !ctx->enc) {
+        WOLFSSL_ENTER("wolfSSL_EVP_DecryptFinal");
+        return wolfSSL_EVP_CipherFinal(ctx, out, outl);
+    }
+    else {
+        return WOLFSSL_FAILURE;
+    }
+}
+
+int  wolfSSL_EVP_DecryptFinal_ex(WOLFSSL_EVP_CIPHER_CTX *ctx,
+                                   unsigned char *out, int *outl)
+{
+    if (ctx && !ctx->enc) {
+        WOLFSSL_ENTER("wolfSSL_EVP_DecryptFinal_ex");
+        return wolfSSL_EVP_CipherFinal(ctx, out, outl);
+    }
+    else {
+        return WOLFSSL_FAILURE;
+    }
+}
+
+
+int wolfSSL_EVP_DigestInit_ex(WOLFSSL_EVP_MD_CTX* ctx,
+                                     const WOLFSSL_EVP_MD* type,
+                                     WOLFSSL_ENGINE *impl)
+{
+    (void) impl;
+    WOLFSSL_ENTER("wolfSSL_EVP_DigestInit_ex");
+    return wolfSSL_EVP_DigestInit(ctx, type);
+}
+
+#ifdef DEBUG_WOLFSSL_EVP
+#define PRINT_BUF(b, sz) { int _i; for(_i=0; _i<(sz); _i++) { \
+  printf("%02x(%c),", (b)[_i], (b)[_i]); if ((_i+1)%8==0)printf("\n");}}
+#else
+#define PRINT_BUF(b, sz)
+#endif
+
+static int fillBuff(WOLFSSL_EVP_CIPHER_CTX *ctx, const unsigned char *in, int sz)
+{
+    int fill;
+
+    if (sz > 0) {
+        if ((sz+ctx->bufUsed) > ctx->block_size) {
+            fill = ctx->block_size - ctx->bufUsed;
+        } else {
+            fill = sz;
+        }
+        XMEMCPY(&(ctx->buf[ctx->bufUsed]), in, fill);
+        ctx->bufUsed += fill;
+        return fill;
+    } else return 0;
+}
+
+static int evpCipherBlock(WOLFSSL_EVP_CIPHER_CTX *ctx,
+                                   unsigned char *out,
+                                   const unsigned char *in, int inl)
+{
+    int ret = 0;
+
+    switch (ctx->cipherType) {
+#if !defined(NO_AES)
+    #if defined(HAVE_AES_CBC)
+        case AES_128_CBC_TYPE:
+        case AES_192_CBC_TYPE:
+        case AES_256_CBC_TYPE:
+            if (ctx->enc)
+                ret = wc_AesCbcEncrypt(&ctx->cipher.aes, out, in, inl);
+            else
+                ret = wc_AesCbcDecrypt(&ctx->cipher.aes, out, in, inl);
+            break;
+    #endif
+    #if defined(HAVE_AESGCM)
+        case AES_128_GCM_TYPE:
+        case AES_192_GCM_TYPE:
+        case AES_256_GCM_TYPE:
+            if (ctx->enc) {
+                if (out){
+                    /* encrypt confidential data*/
+                    ret = wc_AesGcmEncrypt(&ctx->cipher.aes, out, in, inl,
+                              ctx->iv, ctx->ivSz, ctx->authTag, ctx->authTagSz,
+                              NULL, 0);
+                }
+                else {
+                    /* authenticated, non-confidential data */
+                    ret = wc_AesGcmEncrypt(&ctx->cipher.aes, NULL, NULL, 0,
+                              ctx->iv, ctx->ivSz, ctx->authTag, ctx->authTagSz,
+                              in, inl);
+                    /* Reset partial authTag error for AAD*/
+                    if (ret == AES_GCM_AUTH_E)
+                        ret = 0;
+                }
+            }
+            else {
+                if (out){
+                    /* decrypt confidential data*/
+                    ret = wc_AesGcmDecrypt(&ctx->cipher.aes, out, in, inl,
+                              ctx->iv, ctx->ivSz, ctx->authTag, ctx->authTagSz,
+                              NULL, 0);
+                }
+                else {
+                    /* authenticated, non-confidential data*/
+                    ret = wc_AesGcmDecrypt(&ctx->cipher.aes, NULL, NULL, 0,
+                              ctx->iv, ctx->ivSz,
+                              ctx->authTag, ctx->authTagSz,
+                              in, inl);
+                    /* Reset partial authTag error for AAD*/
+                    if (ret == AES_GCM_AUTH_E)
+                        ret = 0;
+                }
+            }
+            break;
+    #endif
+    #if defined(WOLFSSL_AES_COUNTER)
+        case AES_128_CTR_TYPE:
+        case AES_192_CTR_TYPE:
+        case AES_256_CTR_TYPE:
+            ret = wc_AesCtrEncrypt(&ctx->cipher.aes, out, in, inl);
+            break;
+    #endif
+    #if defined(HAVE_AES_ECB)
+        case AES_128_ECB_TYPE:
+        case AES_192_ECB_TYPE:
+        case AES_256_ECB_TYPE:
+            if (ctx->enc)
+                ret = wc_AesEcbEncrypt(&ctx->cipher.aes, out, in, inl);
+            else
+                ret = wc_AesEcbDecrypt(&ctx->cipher.aes, out, in, inl);
+            break;
+    #endif
+    #if defined(WOLFSSL_AES_OFB)
+        case AES_128_OFB_TYPE:
+        case AES_192_OFB_TYPE:
+        case AES_256_OFB_TYPE:
+            if (ctx->enc)
+                ret = wc_AesOfbEncrypt(&ctx->cipher.aes, out, in, inl);
+            else
+                ret = wc_AesOfbDecrypt(&ctx->cipher.aes, out, in, inl);
+            break;
+    #endif
+    #if defined(WOLFSSL_AES_CFB)
+    #if !defined(HAVE_SELFTEST) && !defined(HAVE_FIPS)
+        case AES_128_CFB1_TYPE:
+        case AES_192_CFB1_TYPE:
+        case AES_256_CFB1_TYPE:
+            if (ctx->enc)
+                ret = wc_AesCfb1Encrypt(&ctx->cipher.aes, out, in,
+                        inl * WOLFSSL_BIT_SIZE);
+            else
+                ret = wc_AesCfb1Decrypt(&ctx->cipher.aes, out, in,
+                        inl * WOLFSSL_BIT_SIZE);
+            break;
+
+        case AES_128_CFB8_TYPE:
+        case AES_192_CFB8_TYPE:
+        case AES_256_CFB8_TYPE:
+            if (ctx->enc)
+                ret = wc_AesCfb8Encrypt(&ctx->cipher.aes, out, in, inl);
+            else
+                ret = wc_AesCfb8Decrypt(&ctx->cipher.aes, out, in, inl);
+            break;
+    #endif /* !HAVE_SELFTEST && !HAVE_FIPS */
+
+        case AES_128_CFB128_TYPE:
+        case AES_192_CFB128_TYPE:
+        case AES_256_CFB128_TYPE:
+            if (ctx->enc)
+                ret = wc_AesCfbEncrypt(&ctx->cipher.aes, out, in, inl);
+            else
+                ret = wc_AesCfbDecrypt(&ctx->cipher.aes, out, in, inl);
+            break;
+    #endif
+#if defined(WOLFSSL_AES_XTS)
+    case AES_128_XTS_TYPE:
+    case AES_256_XTS_TYPE:
+        if (ctx->enc)
+            ret = wc_AesXtsEncrypt(&ctx->cipher.xts, out, in, inl,
+                    ctx->iv, ctx->ivSz);
+        else
+            ret = wc_AesXtsDecrypt(&ctx->cipher.xts, out, in, inl,
+                    ctx->iv, ctx->ivSz);
+        break;
+#endif
+#endif /* !NO_AES */
+    #ifndef NO_DES3
+        case DES_CBC_TYPE:
+            if (ctx->enc)
+                ret = wc_Des_CbcEncrypt(&ctx->cipher.des, out, in, inl);
+            else
+                ret = wc_Des_CbcDecrypt(&ctx->cipher.des, out, in, inl);
+            break;
+        case DES_EDE3_CBC_TYPE:
+            if (ctx->enc)
+                ret = wc_Des3_CbcEncrypt(&ctx->cipher.des3, out, in, inl);
+            else
+                ret = wc_Des3_CbcDecrypt(&ctx->cipher.des3, out, in, inl);
+            break;
+        #if defined(WOLFSSL_DES_ECB)
+        case DES_ECB_TYPE:
+            ret = wc_Des_EcbEncrypt(&ctx->cipher.des, out, in, inl);
+            break;
+        case DES_EDE3_ECB_TYPE:
+            ret = wc_Des3_EcbEncrypt(&ctx->cipher.des3, out, in, inl);
+            break;
+        #endif
+    #endif
+    #ifndef NO_RC4
+        case ARC4_TYPE:
+            wc_Arc4Process(&ctx->cipher.arc4, out, in, inl);
+        break;
+    #endif
+        default:
+            return WOLFSSL_FAILURE;
+    }
+
+    if (ret != 0)
+        return WOLFSSL_FAILURE; /* failure */
+
+    (void)in;
+    (void)inl;
+    (void)out;
+
+    return WOLFSSL_SUCCESS; /* success */
+}
+
+#if defined(HAVE_AESGCM)
+static int wolfSSL_EVP_CipherUpdate_GCM(WOLFSSL_EVP_CIPHER_CTX *ctx,
+                                   unsigned char *out, int *outl,
+                                   const unsigned char *in, int inl)
+{
+    /* process blocks */
+    if (evpCipherBlock(ctx, out, in, inl) == 0)
+        return WOLFSSL_FAILURE;
+    *outl = inl;
+    return WOLFSSL_SUCCESS;
+}
+#endif
+
+/* returns WOLFSSL_SUCCESS on success and WOLFSSL_FAILURE on failure */
+WOLFSSL_API int wolfSSL_EVP_CipherUpdate(WOLFSSL_EVP_CIPHER_CTX *ctx,
+                                   unsigned char *out, int *outl,
+                                   const unsigned char *in, int inl)
+{
+    int blocks;
+    int fill;
+
+    WOLFSSL_ENTER("wolfSSL_EVP_CipherUpdate");
+    if ((ctx == NULL) || (inl < 0) || (outl == NULL)|| (in == NULL)) {
+        WOLFSSL_MSG("Bad argument");
+        return WOLFSSL_FAILURE;
+    }
+
+    *outl = 0;
+    if (inl == 0) {
+        return WOLFSSL_SUCCESS;
+    }
+
+#if !defined(NO_AES) && defined(HAVE_AESGCM)
+        switch (ctx->cipherType) {
+            case AES_128_GCM_TYPE:
+            case AES_192_GCM_TYPE:
+            case AES_256_GCM_TYPE:
+/* if out == NULL, in/inl contains the additional authenticated data for GCM */
+                return wolfSSL_EVP_CipherUpdate_GCM(ctx, out, outl, in, inl);
+            default:
+                /* fall-through */
+                break;
+        }
+#endif /* !defined(NO_AES) && defined(HAVE_AESGCM) */
+
+    if (out == NULL) {
+        return WOLFSSL_FAILURE;
+    }
+
+
+    if (ctx->bufUsed > 0) { /* concatenate them if there is anything */
+        fill = fillBuff(ctx, in, inl);
+        inl -= fill;
+        in  += fill;
+    }
+
+    /* check if the buff is full, and if so flash it out */
+    if (ctx->bufUsed == ctx->block_size) {
+        byte* output = out;
+
+        /* During decryption we save the last block to check padding on Final.
+         * Update the last block stored if one has already been stored */
+        if (ctx->enc == 0) {
+            if (ctx->lastUsed == 1) {
+                XMEMCPY(out, ctx->lastBlock, ctx->block_size);
+                *outl+= ctx->block_size;
+                out  += ctx->block_size;
+            }
+            output = ctx->lastBlock; /* redirect output to last block buffer */
+            ctx->lastUsed = 1;
+        }
+
+        PRINT_BUF(ctx->buf, ctx->block_size);
+        if (evpCipherBlock(ctx, output, ctx->buf, ctx->block_size) == 0) {
+            return WOLFSSL_FAILURE;
+        }
+        PRINT_BUF(out, ctx->block_size);
+        ctx->bufUsed = 0;
+
+        /* if doing encryption update the new output block, decryption will
+         * always have the last block saved for when Final is called */
+        if ((ctx->enc != 0)) {
+            *outl+= ctx->block_size;
+            out  += ctx->block_size;
+        }
+    }
+
+    blocks = inl / ctx->block_size;
+    if (blocks > 0) {
+        /* During decryption we save the last block to check padding on Final.
+         * Update the last block stored if one has already been stored */
+        if ((ctx->enc == 0) && (ctx->lastUsed == 1)) {
+            PRINT_BUF(ctx->lastBlock, ctx->block_size);
+            XMEMCPY(out, ctx->lastBlock, ctx->block_size);
+            *outl += ctx->block_size;
+            out += ctx->block_size;
+            ctx->lastUsed = 0;
+        }
+
+        /* process blocks */
+        if (evpCipherBlock(ctx, out, in, blocks * ctx->block_size) == 0) {
+            return WOLFSSL_FAILURE;
+        }
+        PRINT_BUF(in, ctx->block_size*blocks);
+        PRINT_BUF(out,ctx->block_size*blocks);
+        inl  -= ctx->block_size * blocks;
+        in   += ctx->block_size * blocks;
+        if (ctx->enc == 0) {
+            if ((ctx->flags & WOLFSSL_EVP_CIPH_NO_PADDING) ||
+                    (ctx->block_size == 1)) {
+                ctx->lastUsed = 0;
+                *outl += ctx->block_size * blocks;
+            } else {
+                /* in the case of decryption and padding, store the last block
+                 * here in order to verify the padding when Final is called */
+                if (inl == 0) { /* if not 0 then we know leftovers are checked*/
+                    ctx->lastUsed = 1;
+                    blocks = blocks - 1; /* save last block to check padding in
+                                          * EVP_CipherFinal call */
+                    XMEMCPY(ctx->lastBlock, &out[ctx->block_size * blocks],
+                            ctx->block_size);
+                }
+                *outl += ctx->block_size * blocks;
+            }
+        } else {
+            *outl += ctx->block_size * blocks;
+        }
+    }
+
+
+    if (inl > 0) {
+        /* put fraction into buff */
+        fillBuff(ctx, in, inl);
+        /* no increase of outl */
+    }
+    (void)out; /* silence warning in case not read */
+
+    return WOLFSSL_SUCCESS;
+}
+
+static void padBlock(WOLFSSL_EVP_CIPHER_CTX *ctx)
+{
+    int i;
+    for (i = ctx->bufUsed; i < ctx->block_size; i++)
+        ctx->buf[i] = (byte)(ctx->block_size - ctx->bufUsed);
+}
+
+static int checkPad(WOLFSSL_EVP_CIPHER_CTX *ctx, unsigned char *buff)
+{
+    int i;
+    int n;
+    n = buff[ctx->block_size-1];
+    if (n > ctx->block_size) return -1;
+    for (i = 0; i < n; i++) {
+        if (buff[ctx->block_size-i-1] != n)
+            return -1;
+    }
+    return ctx->block_size - n;
+}
+
+int  wolfSSL_EVP_CipherFinal(WOLFSSL_EVP_CIPHER_CTX *ctx,
+                                   unsigned char *out, int *outl)
+{
+    int fl;
+    int ret = WOLFSSL_SUCCESS;
+    if (!ctx || !outl)
+        return WOLFSSL_FAILURE;
+
+    WOLFSSL_ENTER("wolfSSL_EVP_CipherFinal");
+
+#if !defined(NO_AES) && defined(HAVE_AESGCM)
+        switch (ctx->cipherType) {
+            case AES_128_GCM_TYPE:
+            case AES_192_GCM_TYPE:
+            case AES_256_GCM_TYPE:
+                *outl = 0;
+                /* Clear IV, since IV reuse is not recommended for AES GCM. */
+                XMEMSET(ctx->iv, 0, AES_BLOCK_SIZE);
+                return WOLFSSL_SUCCESS;
+            default:
+                /* fall-through */
+                break;
+        }
+#endif /* !NO_AES && HAVE_AESGCM */
+
+    if (!out)
+        return WOLFSSL_FAILURE;
+
+    if (ctx->flags & WOLFSSL_EVP_CIPH_NO_PADDING) {
+        if (ctx->bufUsed != 0) return WOLFSSL_FAILURE;
+        *outl = 0;
+    }
+    else if (ctx->enc) {
+        if (ctx->block_size == 1) {
+            *outl = 0;
+        }
+        else if ((ctx->bufUsed >= 0) && (ctx->block_size != 1)) {
+            padBlock(ctx);
+            PRINT_BUF(ctx->buf, ctx->block_size);
+            if (evpCipherBlock(ctx, out, ctx->buf, ctx->block_size) == 0) {
+                WOLFSSL_MSG("Final Cipher Block failed");
+                ret = WOLFSSL_FAILURE;
+            }
+            else {
+                PRINT_BUF(out, ctx->block_size);
+                *outl = ctx->block_size;
+            }
+        }
+    }
+    else {
+        if (ctx->block_size == 1) {
+            *outl = 0;
+        }
+        else if ((ctx->bufUsed % ctx->block_size) != 0) {
+            *outl = 0;
+            /* not enough padding for decrypt */
+            WOLFSSL_MSG("Final Cipher Block not enough padding");
+            ret = WOLFSSL_FAILURE;
+        }
+        else if (ctx->lastUsed) {
+            PRINT_BUF(ctx->lastBlock, ctx->block_size);
+            if ((fl = checkPad(ctx, ctx->lastBlock)) >= 0) {
+                XMEMCPY(out, ctx->lastBlock, fl);
+                *outl = fl;
+                if (ctx->lastUsed == 0 && ctx->bufUsed == 0) {
+                    /* return error in cases where the block length is incorrect */
+                    WOLFSSL_MSG("Final Cipher Block bad length");
+                    ret = WOLFSSL_FAILURE;
+                }
+            }
+            else {
+                ret = WOLFSSL_FAILURE;
+            }
+        }
+        else if (ctx->lastUsed == 0 && ctx->bufUsed == 0) {
+            /* return error in cases where the block length is incorrect */
+            ret = WOLFSSL_FAILURE;
+        }
+    }
+    if (ret == WOLFSSL_SUCCESS) {
+        /* reset cipher state after final */
+        wolfSSL_EVP_CipherInit(ctx, NULL, NULL, NULL, -1);
+    }
+    return ret;
+}
+
+
+#ifdef WOLFSSL_EVP_DECRYPT_LEGACY
+/* This is a version of DecryptFinal to work with data encrypted with
+ * wolfSSL_EVP_EncryptFinal() with the broken padding. (pre-v3.12.0)
+ * Only call this after wolfSSL_EVP_CipherFinal() fails on a decrypt.
+ * Note, you don't know if the padding is good or bad with the old
+ * encrypt, but it is likely to be or bad. It will update the output
+ * length with the block_size so the last block is still captured. */
+WOLFSSL_API int  wolfSSL_EVP_DecryptFinal_legacy(WOLFSSL_EVP_CIPHER_CTX *ctx,
+        unsigned char *out, int *outl)
+{
+    int fl;
+    if (ctx == NULL || out == NULL || outl == NULL)
+        return BAD_FUNC_ARG;
+
+    WOLFSSL_ENTER("wolfSSL_EVP_DecryptFinal_legacy");
+    if (ctx->block_size == 1) {
+        *outl = 0;
+        return WOLFSSL_SUCCESS;
+    }
+    if ((ctx->bufUsed % ctx->block_size) != 0) {
+        *outl = 0;
+        /* not enough padding for decrypt */
+        return WOLFSSL_FAILURE;
+    }
+    /* The original behavior of CipherFinal() was like it is now,
+     * but checkPad would return 0 in case of a bad pad. It would
+     * treat the pad as 0, and leave the data in the output buffer,
+     * and not try to copy anything. This converts checkPad's -1 error
+     * code to block_size.
+     */
+    if (ctx->lastUsed) {
+        PRINT_BUF(ctx->lastBlock, ctx->block_size);
+        if ((fl = checkPad(ctx, ctx->lastBlock)) < 0) {
+            fl = ctx->block_size;
+        }
+        else {
+            XMEMCPY(out, ctx->lastBlock, fl);
+        }
+        *outl = fl;
+    }
+    /* return error in cases where the block length is incorrect */
+    if (ctx->lastUsed == 0 && ctx->bufUsed == 0) {
+        return WOLFSSL_FAILURE;
+    }
+
+    return WOLFSSL_SUCCESS;
+}
+#endif
+
+
+int wolfSSL_EVP_CIPHER_CTX_block_size(const WOLFSSL_EVP_CIPHER_CTX *ctx)
+{
+    if (ctx == NULL) return BAD_FUNC_ARG;
+    switch (ctx->cipherType) {
+#if !defined(NO_AES) || !defined(NO_DES3)
+#if !defined(NO_AES)
+#if defined(HAVE_AES_CBC)
+    case AES_128_CBC_TYPE:
+    case AES_192_CBC_TYPE:
+    case AES_256_CBC_TYPE:
+#endif
+#if defined(HAVE_AESGCM)
+    case AES_128_GCM_TYPE:
+    case AES_192_GCM_TYPE:
+    case AES_256_GCM_TYPE:
+#endif
+#if defined(WOLFSSL_AES_COUNTER)
+    case AES_128_CTR_TYPE:
+    case AES_192_CTR_TYPE:
+    case AES_256_CTR_TYPE:
+#endif
+#if defined(WOLFSSL_AES_CFB)
+    case AES_128_CFB1_TYPE:
+    case AES_192_CFB1_TYPE:
+    case AES_256_CFB1_TYPE:
+    case AES_128_CFB8_TYPE:
+    case AES_192_CFB8_TYPE:
+    case AES_256_CFB8_TYPE:
+    case AES_128_CFB128_TYPE:
+    case AES_192_CFB128_TYPE:
+    case AES_256_CFB128_TYPE:
+#endif
+#if defined(WOLFSSL_AES_OFB)
+    case AES_128_OFB_TYPE:
+    case AES_192_OFB_TYPE:
+    case AES_256_OFB_TYPE:
+#endif
+#if defined(WOLFSSL_AES_XTS)
+    case AES_128_XTS_TYPE:
+    case AES_256_XTS_TYPE:
+#endif
+
+    case AES_128_ECB_TYPE:
+    case AES_192_ECB_TYPE:
+    case AES_256_ECB_TYPE:
+#endif /* !NO_AES */
+#ifndef NO_DES3
+    case DES_CBC_TYPE:
+    case DES_ECB_TYPE:
+    case DES_EDE3_CBC_TYPE:
+    case DES_EDE3_ECB_TYPE:
+#endif
+        return ctx->block_size;
+#endif /* !NO_AES || !NO_DES3 */
+    default:
+        return 0;
+    }
+}
+
+static unsigned int cipherType(const WOLFSSL_EVP_CIPHER *cipher)
+{
+    if (cipher == NULL) return 0; /* dummy for #ifdef */
+#ifndef NO_DES3
+    else if (EVP_DES_CBC && XSTRNCMP(cipher, EVP_DES_CBC, EVP_DES_SIZE) == 0)
+        return DES_CBC_TYPE;
+    else if (EVP_DES_EDE3_CBC && XSTRNCMP(cipher, EVP_DES_EDE3_CBC, EVP_DES_EDE3_SIZE) == 0)
+        return DES_EDE3_CBC_TYPE;
+#if !defined(NO_DES3)
+    else if (EVP_DES_ECB && XSTRNCMP(cipher, EVP_DES_ECB, EVP_DES_SIZE) == 0)
+        return DES_ECB_TYPE;
+    else if (EVP_DES_EDE3_ECB && XSTRNCMP(cipher, EVP_DES_EDE3_ECB, EVP_DES_EDE3_SIZE) == 0)
+        return DES_EDE3_ECB_TYPE;
+#endif /* NO_DES3 && HAVE_AES_ECB */
+#endif
+#if !defined(NO_AES)
+#if defined(HAVE_AES_CBC)
+    #ifdef WOLFSSL_AES_128
+    else if (EVP_AES_128_CBC && XSTRNCMP(cipher, EVP_AES_128_CBC, EVP_AES_SIZE) == 0)
+        return AES_128_CBC_TYPE;
+    #endif
+    #ifdef WOLFSSL_AES_192
+    else if (EVP_AES_192_CBC && XSTRNCMP(cipher, EVP_AES_192_CBC, EVP_AES_SIZE) == 0)
+        return AES_192_CBC_TYPE;
+    #endif
+    #ifdef WOLFSSL_AES_256
+    else if (EVP_AES_256_CBC && XSTRNCMP(cipher, EVP_AES_256_CBC, EVP_AES_SIZE) == 0)
+        return AES_256_CBC_TYPE;
+    #endif
+#endif /* HAVE_AES_CBC */
+#if defined(HAVE_AESGCM)
+    #ifdef WOLFSSL_AES_128
+    else if (EVP_AES_128_GCM && XSTRNCMP(cipher, EVP_AES_128_GCM, EVP_AES_SIZE) == 0)
+        return AES_128_GCM_TYPE;
+    #endif
+    #ifdef WOLFSSL_AES_192
+    else if (EVP_AES_192_GCM && XSTRNCMP(cipher, EVP_AES_192_GCM, EVP_AES_SIZE) == 0)
+        return AES_192_GCM_TYPE;
+    #endif
+    #ifdef WOLFSSL_AES_256
+    else if (EVP_AES_256_GCM && XSTRNCMP(cipher, EVP_AES_256_GCM, EVP_AES_SIZE) == 0)
+        return AES_256_GCM_TYPE;
+    #endif
+#endif /* HAVE_AESGCM */
+#if defined(WOLFSSL_AES_COUNTER)
+    #ifdef WOLFSSL_AES_128
+    else if (EVP_AES_128_CTR && XSTRNCMP(cipher, EVP_AES_128_CTR, EVP_AES_SIZE) == 0)
+        return AES_128_CTR_TYPE;
+    #endif
+    #ifdef WOLFSSL_AES_192
+    else if (EVP_AES_192_CTR && XSTRNCMP(cipher, EVP_AES_192_CTR, EVP_AES_SIZE) == 0)
+        return AES_192_CTR_TYPE;
+    #endif
+    #ifdef WOLFSSL_AES_256
+    else if (EVP_AES_256_CTR && XSTRNCMP(cipher, EVP_AES_256_CTR, EVP_AES_SIZE) == 0)
+        return AES_256_CTR_TYPE;
+    #endif
+#endif /* HAVE_AES_CBC */
+#if defined(HAVE_AES_ECB)
+    #ifdef WOLFSSL_AES_128
+    else if (EVP_AES_128_ECB && XSTRNCMP(cipher, EVP_AES_128_ECB, EVP_AES_SIZE) == 0)
+        return AES_128_ECB_TYPE;
+    #endif
+    #ifdef WOLFSSL_AES_192
+    else if (EVP_AES_192_ECB && XSTRNCMP(cipher, EVP_AES_192_ECB, EVP_AES_SIZE) == 0)
+        return AES_192_ECB_TYPE;
+    #endif
+    #ifdef WOLFSSL_AES_256
+    else if (EVP_AES_256_ECB && XSTRNCMP(cipher, EVP_AES_256_ECB, EVP_AES_SIZE) == 0)
+        return AES_256_ECB_TYPE;
+    #endif
+#endif /*HAVE_AES_CBC */
+#if defined(WOLFSSL_AES_XTS)
+    #ifdef WOLFSSL_AES_128
+    else if (EVP_AES_128_XTS && XSTRNCMP(cipher, EVP_AES_128_XTS, EVP_AES_SIZE) == 0)
+        return AES_128_XTS_TYPE;
+    #endif
+    #ifdef WOLFSSL_AES_256
+    else if (EVP_AES_256_XTS && XSTRNCMP(cipher, EVP_AES_256_XTS, EVP_AES_SIZE) == 0)
+        return AES_256_XTS_TYPE;
+    #endif
+#endif /* WOLFSSL_AES_XTS */
+#if defined(WOLFSSL_AES_CFB)
+    #ifdef WOLFSSL_AES_128
+    else if (EVP_AES_128_CFB1 && XSTRNCMP(cipher, EVP_AES_128_CFB1, EVP_AESCFB_SIZE) == 0)
+        return AES_128_CFB1_TYPE;
+    #endif
+    #ifdef WOLFSSL_AES_192
+    else if (EVP_AES_192_CFB1 && XSTRNCMP(cipher, EVP_AES_192_CFB1, EVP_AESCFB_SIZE) == 0)
+        return AES_192_CFB1_TYPE;
+    #endif
+    #ifdef WOLFSSL_AES_256
+    else if (EVP_AES_256_CFB1 && XSTRNCMP(cipher, EVP_AES_256_CFB1, EVP_AESCFB_SIZE) == 0)
+        return AES_256_CFB1_TYPE;
+    #endif
+    #ifdef WOLFSSL_AES_128
+    else if (EVP_AES_128_CFB8 && XSTRNCMP(cipher, EVP_AES_128_CFB8, EVP_AESCFB_SIZE) == 0)
+        return AES_128_CFB8_TYPE;
+    #endif
+    #ifdef WOLFSSL_AES_192
+    else if (EVP_AES_192_CFB8 && XSTRNCMP(cipher, EVP_AES_192_CFB8, EVP_AESCFB_SIZE) == 0)
+        return AES_192_CFB8_TYPE;
+    #endif
+    #ifdef WOLFSSL_AES_256
+    else if (EVP_AES_256_CFB8 && XSTRNCMP(cipher, EVP_AES_256_CFB8, EVP_AESCFB_SIZE) == 0)
+        return AES_256_CFB8_TYPE;
+    #endif
+    #ifdef WOLFSSL_AES_128
+    else if (EVP_AES_128_CFB128 && XSTRNCMP(cipher, EVP_AES_128_CFB128, EVP_AESCFB_SIZE) == 0)
+        return AES_128_CFB128_TYPE;
+    #endif
+    #ifdef WOLFSSL_AES_192
+    else if (EVP_AES_192_CFB128 && XSTRNCMP(cipher, EVP_AES_192_CFB128, EVP_AESCFB_SIZE) == 0)
+        return AES_192_CFB128_TYPE;
+    #endif
+    #ifdef WOLFSSL_AES_256
+    else if (EVP_AES_256_CFB128 && XSTRNCMP(cipher, EVP_AES_256_CFB128, EVP_AESCFB_SIZE) == 0)
+        return AES_256_CFB128_TYPE;
+    #endif
+#endif /*HAVE_AES_CBC */
+#endif /* !NO_AES */
+      else return 0;
+}
+
+int wolfSSL_EVP_CIPHER_block_size(const WOLFSSL_EVP_CIPHER *cipher)
+{
+  if (cipher == NULL) return BAD_FUNC_ARG;
+  switch (cipherType(cipher)) {
+#if !defined(NO_AES)
+  #if defined(HAVE_AES_CBC)
+      case AES_128_CBC_TYPE:
+      case AES_192_CBC_TYPE:
+      case AES_256_CBC_TYPE:
+          return AES_BLOCK_SIZE;
+  #endif
+  #if defined(HAVE_AESGCM)
+      case AES_128_GCM_TYPE:
+      case AES_192_GCM_TYPE:
+      case AES_256_GCM_TYPE:
+          return AES_BLOCK_SIZE;
+  #endif
+  #if defined(WOLFSSL_AES_COUNTER)
+      case AES_128_CTR_TYPE:
+      case AES_192_CTR_TYPE:
+      case AES_256_CTR_TYPE:
+          return AES_BLOCK_SIZE;
+  #endif
+  #if defined(HAVE_AES_ECB)
+      case AES_128_ECB_TYPE:
+      case AES_192_ECB_TYPE:
+      case AES_256_ECB_TYPE:
+          return AES_BLOCK_SIZE;
+  #endif
+#endif /* NO_AES */
+  #ifndef NO_DES3
+      case DES_CBC_TYPE: return 8;
+      case DES_EDE3_CBC_TYPE: return 8;
+      case DES_ECB_TYPE: return 8;
+      case DES_EDE3_ECB_TYPE: return 8;
+  #endif
+      default:
+          return 0;
+      }
+}
+
+unsigned long WOLFSSL_CIPHER_mode(const WOLFSSL_EVP_CIPHER *cipher)
+{
+    switch (cipherType(cipher)) {
+#if !defined(NO_AES)
+    #if defined(HAVE_AES_CBC)
+        case AES_128_CBC_TYPE:
+        case AES_192_CBC_TYPE:
+        case AES_256_CBC_TYPE:
+            return WOLFSSL_EVP_CIPH_CBC_MODE;
+    #endif
+    #if defined(HAVE_AESGCM)
+        case AES_128_GCM_TYPE:
+        case AES_192_GCM_TYPE:
+        case AES_256_GCM_TYPE:
+            return WOLFSSL_EVP_CIPH_GCM_MODE;
+    #endif
+    #if defined(WOLFSSL_AES_COUNTER)
+        case AES_128_CTR_TYPE:
+        case AES_192_CTR_TYPE:
+        case AES_256_CTR_TYPE:
+            return WOLFSSL_EVP_CIPH_CTR_MODE;
+    #endif
+        case AES_128_ECB_TYPE:
+        case AES_192_ECB_TYPE:
+        case AES_256_ECB_TYPE:
+            return WOLFSSL_EVP_CIPH_ECB_MODE;
+#endif /* NO_ASE */
+    #ifndef NO_DES3
+        case DES_CBC_TYPE:
+        case DES_EDE3_CBC_TYPE:
+            return WOLFSSL_EVP_CIPH_CBC_MODE;
+        case DES_ECB_TYPE:
+        case DES_EDE3_ECB_TYPE:
+            return WOLFSSL_EVP_CIPH_ECB_MODE;
+    #endif
+    #ifndef NO_RC4
+        case ARC4_TYPE:
+            return EVP_CIPH_STREAM_CIPHER;
+    #endif
+        default:
+            return 0;
+        }
+}
+
+unsigned long WOLFSSL_EVP_CIPHER_mode(const WOLFSSL_EVP_CIPHER *cipher)
+{
+  if (cipher == NULL) return 0;
+  return WOLFSSL_CIPHER_mode(cipher);
+}
+
+void wolfSSL_EVP_CIPHER_CTX_set_flags(WOLFSSL_EVP_CIPHER_CTX *ctx, int flags)
+{
+    if (ctx != NULL) {
+        ctx->flags |= flags;
+    }
+}
+
+void wolfSSL_EVP_CIPHER_CTX_clear_flags(WOLFSSL_EVP_CIPHER_CTX *ctx, int flags)
+{
+    if (ctx != NULL) {
+        ctx->flags &= ~flags;
+    }
+}
+
+unsigned long wolfSSL_EVP_CIPHER_flags(const WOLFSSL_EVP_CIPHER *cipher)
+{
+  if (cipher == NULL) return 0;
+  return WOLFSSL_CIPHER_mode(cipher);
+}
+
+int  wolfSSL_EVP_CIPHER_CTX_set_padding(WOLFSSL_EVP_CIPHER_CTX *ctx, int padding)
+{
+  if (ctx == NULL) return BAD_FUNC_ARG;
+  if (padding) {
+      ctx->flags &= ~WOLFSSL_EVP_CIPH_NO_PADDING;
+  }
+  else {
+      ctx->flags |=  WOLFSSL_EVP_CIPH_NO_PADDING;
+  }
+  return 1;
+}
+
+int wolfSSL_EVP_add_digest(const WOLFSSL_EVP_MD *digest)
+{
+    (void)digest;
+    /* nothing to do */
+    return 0;
+}
+
+
+/* Frees the WOLFSSL_EVP_PKEY_CTX passed in.
+ *
+ * return WOLFSSL_SUCCESS on success
+ */
+int wolfSSL_EVP_PKEY_CTX_free(WOLFSSL_EVP_PKEY_CTX *ctx)
+{
+    if (ctx == NULL) return 0;
+    WOLFSSL_ENTER("EVP_PKEY_CTX_free");
+    if (ctx->pkey != NULL)
+        wolfSSL_EVP_PKEY_free(ctx->pkey);
+    if (ctx->peerKey != NULL)
+        wolfSSL_EVP_PKEY_free(ctx->peerKey);
+    XFREE(ctx, NULL, DYNAMIC_TYPE_PUBLIC_KEY);
+    return WOLFSSL_SUCCESS;
+}
+
+
+/* Creates a new WOLFSSL_EVP_PKEY_CTX structure.
+ *
+ * pkey  key structure to use with new WOLFSSL_EVP_PEKY_CTX
+ * e     engine to use. It should be NULL at this time.
+ *
+ * return the new structure on success and NULL if failed.
+ */
+WOLFSSL_EVP_PKEY_CTX *wolfSSL_EVP_PKEY_CTX_new(WOLFSSL_EVP_PKEY *pkey, WOLFSSL_ENGINE *e)
+{
+    WOLFSSL_EVP_PKEY_CTX* ctx;
+    int type = NID_undef;
+
+    if (pkey == NULL) return 0;
+    if (e != NULL) return 0;
+    WOLFSSL_ENTER("EVP_PKEY_CTX_new");
+
+    ctx = (WOLFSSL_EVP_PKEY_CTX*)XMALLOC(sizeof(WOLFSSL_EVP_PKEY_CTX), NULL,
+            DYNAMIC_TYPE_PUBLIC_KEY);
+    if (ctx == NULL) return NULL;
+    XMEMSET(ctx, 0, sizeof(WOLFSSL_EVP_PKEY_CTX));
+    ctx->pkey = pkey;
+#if !defined(NO_RSA) && !defined(HAVE_USER_RSA)
+    ctx->padding = RSA_PKCS1_PADDING;
+#endif
+    type = wolfSSL_EVP_PKEY_type(pkey->type);
+
+    if (type != NID_undef) {
+        if (wc_LockMutex(&pkey->refMutex) != 0) {
+            WOLFSSL_MSG("Couldn't lock pkey mutex");
+        }
+        pkey->references++;
+
+        wc_UnLockMutex(&pkey->refMutex);
+    }
+    return ctx;
+}
+
+
+/* Sets the type of RSA padding to use.
+ *
+ * ctx     structure to set padding in.
+ * padding RSA padding type
+ *
+ * returns WOLFSSL_SUCCESS on success.
+ */
+int wolfSSL_EVP_PKEY_CTX_set_rsa_padding(WOLFSSL_EVP_PKEY_CTX *ctx, int padding)
+{
+    if (ctx == NULL) return 0;
+    WOLFSSL_ENTER("EVP_PKEY_CTX_set_rsa_padding");
+    ctx->padding = padding;
+    return WOLFSSL_SUCCESS;
+}
+
+/* create a PKEY contxt and return it */
+WOLFSSL_EVP_PKEY_CTX *wolfSSL_EVP_PKEY_CTX_new_id(int id, WOLFSSL_ENGINE *e)
+{
+    WOLFSSL_EVP_PKEY* pkey;
+    WOLFSSL_EVP_PKEY_CTX* ctx = NULL;
+
+    WOLFSSL_ENTER("wolfSSL_EVP_PKEY_CTX_new_id");
+
+    pkey = wolfSSL_EVP_PKEY_new_ex(NULL);
+    if (pkey) {
+        pkey->type = id;
+        ctx = wolfSSL_EVP_PKEY_CTX_new(pkey, e);
+        if (ctx == NULL) {
+            wolfSSL_EVP_PKEY_free(pkey);
+        }
+    }
+    return ctx;
+}
+
+/* Returns WOLFSSL_SUCCESS or error */
+int wolfSSL_EVP_PKEY_CTX_set_rsa_keygen_bits(WOLFSSL_EVP_PKEY_CTX *ctx, int bits)
+{
+    if (ctx) {
+        ctx->nbits = bits;
+    }
+    return WOLFSSL_SUCCESS;
+}
+
+
+int wolfSSL_EVP_PKEY_derive_init(WOLFSSL_EVP_PKEY_CTX *ctx)
+{
+    WOLFSSL_ENTER("wolfSSL_EVP_PKEY_derive_init");
+
+    if (!ctx) {
+        return WOLFSSL_FAILURE;
+    }
+    wolfSSL_EVP_PKEY_free(ctx->peerKey);
+    ctx->op = EVP_PKEY_OP_DERIVE;
+    ctx->padding = 0;
+    ctx->nbits = 0;
+    return WOLFSSL_SUCCESS;
+}
+
+int wolfSSL_EVP_PKEY_derive_set_peer(WOLFSSL_EVP_PKEY_CTX *ctx, WOLFSSL_EVP_PKEY *peer)
+{
+    WOLFSSL_ENTER("wolfSSL_EVP_PKEY_derive_set_peer");
+
+    if (!ctx || ctx->op != EVP_PKEY_OP_DERIVE) {
+        return WOLFSSL_FAILURE;
+    }
+    wolfSSL_EVP_PKEY_free(ctx->peerKey);
+    ctx->peerKey = peer;
+    if (!wolfSSL_EVP_PKEY_up_ref(peer)) {
+        ctx->peerKey = NULL;
+        return WOLFSSL_FAILURE;
+    }
+    return WOLFSSL_SUCCESS;
+}
+
+#if !defined(NO_DH) && defined(HAVE_ECC)
+int wolfSSL_EVP_PKEY_derive(WOLFSSL_EVP_PKEY_CTX *ctx, unsigned char *key, size_t *keylen)
+{
+    int len;
+
+    WOLFSSL_ENTER("wolfSSL_EVP_PKEY_derive");
+
+    if (!ctx || ctx->op != EVP_PKEY_OP_DERIVE || !ctx->pkey || !ctx->peerKey || !keylen
+            || ctx->pkey->type != ctx->peerKey->type) {
+        return WOLFSSL_FAILURE;
+    }
+    switch (ctx->pkey->type) {
+#ifndef NO_DH
+    case EVP_PKEY_DH:
+        /* Use DH */
+        if (!ctx->pkey->dh || !ctx->peerKey->dh || !ctx->peerKey->dh->pub_key) {
+            return WOLFSSL_FAILURE;
+        }
+        if ((len = wolfSSL_DH_size(ctx->pkey->dh)) <= 0) {
+            return WOLFSSL_FAILURE;
+        }
+        if (key) {
+            if (*keylen < (size_t)len) {
+                return WOLFSSL_FAILURE;
+            }
+            if (wolfSSL_DH_compute_key(key, ctx->peerKey->dh->pub_key,
+                                       ctx->pkey->dh) != len) {
+                return WOLFSSL_FAILURE;
+            }
+        }
+        *keylen = (size_t)len;
+        break;
+#endif
+#ifdef HAVE_ECC
+    case EVP_PKEY_EC:
+        /* Use ECDH */
+        if (!ctx->pkey->ecc || !ctx->peerKey->ecc) {
+            return WOLFSSL_FAILURE;
+        }
+        /* set internal key if not done */
+        if (!ctx->pkey->ecc->inSet) {
+            if (SetECKeyInternal(ctx->pkey->ecc) != WOLFSSL_SUCCESS) {
+                WOLFSSL_MSG("SetECKeyInternal failed");
+                return WOLFSSL_FAILURE;
+            }
+        }
+        if (!ctx->peerKey->ecc->exSet || !ctx->peerKey->ecc->pub_key->internal) {
+            if (SetECKeyExternal(ctx->peerKey->ecc) != WOLFSSL_SUCCESS) {
+                WOLFSSL_MSG("SetECKeyExternal failed");
+                return WOLFSSL_FAILURE;
+            }
+        }
+        if (!(len = wc_ecc_size((ecc_key*)ctx->pkey->ecc->internal))) {
+            return WOLFSSL_FAILURE;
+        }
+        if (key) {
+            word32 len32 = (word32)len;
+            if (*keylen < len32) {
+                WOLFSSL_MSG("buffer too short");
+                return WOLFSSL_FAILURE;
+            }
+            if (wc_ecc_shared_secret_ssh((ecc_key*)ctx->pkey->ecc->internal,
+                                         (ecc_point*)ctx->peerKey->ecc->pub_key->internal,
+                                         key, &len32) != MP_OKAY) {
+                WOLFSSL_MSG("wc_ecc_shared_secret failed");
+                return WOLFSSL_FAILURE;
+            }
+            len = (int)len32;
+        }
+        *keylen = (size_t)len;
+        break;
+#endif
+    default:
+        WOLFSSL_MSG("Unknown key type");
+        return WOLFSSL_FAILURE;
+    }
+    return WOLFSSL_SUCCESS;
+}
+#endif
+
+/* Uses the WOLFSSL_EVP_PKEY_CTX to decrypt a buffer.
+ *
+ * ctx    structure to decrypt with
+ * out    buffer to hold the results
+ * outlen initially holds size of out buffer and gets set to decrypt result size
+ * in     buffer decrypt
+ * inlen  length of in buffer
+ *
+ * returns WOLFSSL_SUCCESS on success.
+ */
+int wolfSSL_EVP_PKEY_decrypt(WOLFSSL_EVP_PKEY_CTX *ctx,
+                     unsigned char *out, size_t *outlen,
+                     const unsigned char *in, size_t inlen)
+{
+    int len = 0;
+
+    if (ctx == NULL) return 0;
+    WOLFSSL_ENTER("EVP_PKEY_decrypt");
+
+    (void)out;
+    (void)outlen;
+    (void)in;
+    (void)inlen;
+    (void)len;
+
+    switch (ctx->pkey->type) {
+#if !defined(NO_RSA) && !defined(HAVE_USER_RSA)
+    case EVP_PKEY_RSA:
+        len = wolfSSL_RSA_private_decrypt((int)inlen, (unsigned char*)in, out,
+              ctx->pkey->rsa, ctx->padding);
+        if (len < 0) break;
+        else {
+            *outlen = len;
+            return WOLFSSL_SUCCESS;
+        }
+#endif /* NO_RSA */
+
+    case EVP_PKEY_EC:
+        WOLFSSL_MSG("not implemented");
+        FALL_THROUGH;
+    default:
+        break;
+    }
+    return WOLFSSL_FAILURE;
+}
+
+
+/* Initialize a WOLFSSL_EVP_PKEY_CTX structure for decryption
+ *
+ * ctx    WOLFSSL_EVP_PKEY_CTX structure to use with decryption
+ *
+ * Returns WOLFSSL_FAILURE on failure and WOLFSSL_SUCCESS on success
+ */
+int wolfSSL_EVP_PKEY_decrypt_init(WOLFSSL_EVP_PKEY_CTX *ctx)
+{
+    if (ctx == NULL) return WOLFSSL_FAILURE;
+    WOLFSSL_ENTER("EVP_PKEY_decrypt_init");
+    switch (ctx->pkey->type) {
+    case EVP_PKEY_RSA:
+        ctx->op = EVP_PKEY_OP_DECRYPT;
+        return WOLFSSL_SUCCESS;
+    case EVP_PKEY_EC:
+        WOLFSSL_MSG("not implemented");
+        FALL_THROUGH;
+    default:
+        break;
+    }
+    return WOLFSSL_FAILURE;
+}
+
+
+/* Use a WOLFSSL_EVP_PKEY_CTX structure to encrypt data
+ *
+ * ctx    WOLFSSL_EVP_PKEY_CTX structure to use with encryption
+ * out    buffer to hold encrypted data
+ * outlen length of out buffer
+ * in     data to be encrypted
+ * inlen  length of in buffer
+ *
+ * Returns WOLFSSL_FAILURE on failure and WOLFSSL_SUCCESS on success
+ */
+int wolfSSL_EVP_PKEY_encrypt(WOLFSSL_EVP_PKEY_CTX *ctx,
+                     unsigned char *out, size_t *outlen,
+                     const unsigned char *in, size_t inlen)
+{
+    int len = 0;
+    if (ctx == NULL) return WOLFSSL_FAILURE;
+    WOLFSSL_ENTER("EVP_PKEY_encrypt");
+    if (ctx->op != EVP_PKEY_OP_ENCRYPT) return WOLFSSL_FAILURE;
+
+    (void)out;
+    (void)outlen;
+    (void)in;
+    (void)inlen;
+    (void)len;
+    switch (ctx->pkey->type) {
+#if !defined(NO_RSA) && !defined(HAVE_USER_RSA)
+    case EVP_PKEY_RSA:
+        len = wolfSSL_RSA_public_encrypt((int)inlen, (unsigned char *)in, out,
+                  ctx->pkey->rsa, ctx->padding);
+        if (len < 0)
+            break;
+        else {
+            *outlen = len;
+            return WOLFSSL_SUCCESS;
+        }
+#endif /* NO_RSA */
+
+    case EVP_PKEY_EC:
+        WOLFSSL_MSG("not implemented");
+        FALL_THROUGH;
+    default:
+        break;
+    }
+    return WOLFSSL_FAILURE;
+}
+
+
+/* Initialize a WOLFSSL_EVP_PKEY_CTX structure to encrypt data
+ *
+ * ctx    WOLFSSL_EVP_PKEY_CTX structure to use with encryption
+ *
+ * Returns WOLFSSL_FAILURE on failure and WOLFSSL_SUCCESS on success
+ */
+int wolfSSL_EVP_PKEY_encrypt_init(WOLFSSL_EVP_PKEY_CTX *ctx)
+{
+    if (ctx == NULL) return WOLFSSL_FAILURE;
+    WOLFSSL_ENTER("EVP_PKEY_encrypt_init");
+
+    switch (ctx->pkey->type) {
+    case EVP_PKEY_RSA:
+        ctx->op = EVP_PKEY_OP_ENCRYPT;
+        return WOLFSSL_SUCCESS;
+    case EVP_PKEY_EC:
+        WOLFSSL_MSG("not implemented");
+        FALL_THROUGH;
+    default:
+        break;
+    }
+    return WOLFSSL_FAILURE;
+}
+/******************************************************************************
+* wolfSSL_EVP_PKEY_sign_init -  initializes a public key algorithm context for
+* a signing operation.
+*
+* RETURNS:
+* returns WOLFSSL_SUCCESS on success, otherwise returns -2
+*/
+WOLFSSL_API int wolfSSL_EVP_PKEY_sign_init(WOLFSSL_EVP_PKEY_CTX *ctx)
+{
+    int ret = -2;
+
+    WOLFSSL_MSG("wolfSSL_EVP_PKEY_sign_init");
+    if (!ctx  || !ctx->pkey)
+        return ret;
+
+    switch (ctx->pkey->type) {
+        case EVP_PKEY_RSA:
+            ctx->op = EVP_PKEY_OP_SIGN;
+            ret = WOLFSSL_SUCCESS;
+            break;
+        case EVP_PKEY_EC:
+            WOLFSSL_MSG("not implemented");
+            FALL_THROUGH;
+        default:
+            ret = -2;
+    }
+    return ret;
+}
+/******************************************************************************
+* wolfSSL_EVP_PKEY_sign - performs a public key signing operation using ctx
+* The data to be signed should be hashed since the function does not hash the data.
+*
+* RETURNS:
+* returns WOLFSSL_SUCCESS on success, otherwise returns WOLFSSL_FAILURE
+*/
+
+WOLFSSL_API int wolfSSL_EVP_PKEY_sign(WOLFSSL_EVP_PKEY_CTX *ctx, unsigned char *sig,
+                        size_t *siglen, const unsigned char *tbs, size_t tbslen)
+{
+    int len = 0;
+
+    WOLFSSL_MSG("wolfSSL_EVP_PKEY_sign");
+
+    if (!ctx || ctx->op != EVP_PKEY_OP_SIGN || !ctx->pkey)
+        return WOLFSSL_FAILURE;
+
+    (void)sig;
+    (void)siglen;
+    (void)tbs;
+    (void)tbslen;
+    (void)len;
+
+    switch (ctx->pkey->type) {
+#if !defined(NO_RSA) && !defined(HAVE_USER_RSA)
+    case EVP_PKEY_RSA:
+        len = wolfSSL_RSA_private_encrypt((int)tbslen, (unsigned char*)tbs, sig,
+              ctx->pkey->rsa, ctx->padding);
+        if (len < 0)
+            break;
+        else {
+            *siglen = len;
+            return WOLFSSL_SUCCESS;
+        }
+#endif /* NO_RSA */
+
+    case EVP_PKEY_EC:
+        WOLFSSL_MSG("not implemented");
+        FALL_THROUGH;
+    default:
+        break;
+    }
+    return WOLFSSL_FAILURE;
+}
+
+/* Get the size in bits for WOLFSSL_EVP_PKEY key
+ *
+ * pkey WOLFSSL_EVP_PKEY structure to get key size of
+ *
+ * returns the size in bits of key on success
+ */
+int wolfSSL_EVP_PKEY_bits(const WOLFSSL_EVP_PKEY *pkey)
+{
+    int bytes;
+
+    if (pkey == NULL) return 0;
+    WOLFSSL_ENTER("EVP_PKEY_bits");
+    if ((bytes = wolfSSL_EVP_PKEY_size((WOLFSSL_EVP_PKEY*)pkey)) ==0) return 0;
+    return bytes*8;
+}
+
+
+int wolfSSL_EVP_PKEY_keygen_init(WOLFSSL_EVP_PKEY_CTX *ctx)
+{
+    (void)ctx;
+    return WOLFSSL_SUCCESS;
+}
+
+int wolfSSL_EVP_PKEY_keygen(WOLFSSL_EVP_PKEY_CTX *ctx,
+  WOLFSSL_EVP_PKEY **ppkey)
+{
+    int ret = WOLFSSL_FAILURE;
+    int ownPkey = 0;
+    WOLFSSL_EVP_PKEY* pkey;
+
+    if (ctx == NULL || ppkey == NULL) {
+        return BAD_FUNC_ARG;
+    }
+
+    pkey = *ppkey;
+    if (pkey == NULL) {
+        ownPkey = 1;
+        pkey = wolfSSL_EVP_PKEY_new();
+
+        if (pkey == NULL)
+            return ret;
+    }
+
+    switch (pkey->type) {
+#if !defined(HAVE_FAST_RSA) && defined(WOLFSSL_KEY_GEN) && \
+    !defined(NO_RSA) && !defined(HAVE_USER_RSA)
+        case EVP_PKEY_RSA:
+            pkey->rsa = wolfSSL_RSA_generate_key(ctx->nbits, WC_RSA_EXPONENT,
+                NULL, NULL);
+            if (pkey->rsa) {
+                pkey->ownRsa = 1;
+                pkey->pkey_sz = wolfSSL_i2d_RSAPrivateKey(pkey->rsa,
+                        (unsigned char**)&pkey->pkey.ptr);
+                ret = WOLFSSL_SUCCESS;
+            }
+            break;
+#endif
+#ifdef HAVE_ECC
+        case EVP_PKEY_EC:
+            pkey->ecc = wolfSSL_EC_KEY_new();
+            if (pkey->ecc) {
+                ret = wolfSSL_EC_KEY_generate_key(pkey->ecc);
+                if (ret == WOLFSSL_SUCCESS) {
+                    pkey->ownEcc = 1;
+                }
+            }
+#endif
+        default:
+            break;
+    }
+
+    if (ret != WOLFSSL_SUCCESS && ownPkey) {
+        wolfSSL_EVP_PKEY_free(pkey);
+        pkey = NULL;
+    }
+
+    *ppkey = pkey;
+
+    return ret;
+}
+
+/* Get the size in bytes for WOLFSSL_EVP_PKEY key
+ *
+ * pkey WOLFSSL_EVP_PKEY structure to get key size of
+ *
+ * returns the size of a key on success which is the maximum size of a
+ *         signature
+ */
+int wolfSSL_EVP_PKEY_size(WOLFSSL_EVP_PKEY *pkey)
+{
+    if (pkey == NULL) return 0;
+    WOLFSSL_ENTER("EVP_PKEY_size");
+
+    switch (pkey->type) {
+#ifndef NO_RSA
+    case EVP_PKEY_RSA:
+        return (int)wolfSSL_RSA_size((const WOLFSSL_RSA*)(pkey->rsa));
+#endif /* !NO_RSA */
+
+#ifdef HAVE_ECC
+    case EVP_PKEY_EC:
+        if (pkey->ecc == NULL || pkey->ecc->internal == NULL) {
+            WOLFSSL_MSG("No ECC key has been set");
+            break;
+        }
+        return wc_ecc_size((ecc_key*)(pkey->ecc->internal));
+#endif /* HAVE_ECC */
+
+    default:
+        break;
+    }
+    return 0;
+}
+
+#ifndef NO_WOLFSSL_STUB
+WOLFSSL_API int wolfSSL_EVP_PKEY_missing_parameters(WOLFSSL_EVP_PKEY *pkey)
+{
+    (void)pkey;
+    /* not using missing params callback and returning zero to indicate success */
+    return 0;
+}
+#endif
+
+WOLFSSL_API int wolfSSL_EVP_PKEY_cmp(const WOLFSSL_EVP_PKEY *a, const WOLFSSL_EVP_PKEY *b)
+{
+    int ret = -1; /* failure */
+    int a_sz = 0, b_sz = 0;
+
+    if (a == NULL || b == NULL)
+        return ret;
+
+    /* check its the same type of key */
+    if (a->type != b->type)
+        return ret;
+
+    /* get size based on key type */
+    switch (a->type) {
+#ifndef NO_RSA
+    case EVP_PKEY_RSA:
+        a_sz = (int)wolfSSL_RSA_size((const WOLFSSL_RSA*)(a->rsa));
+        b_sz = (int)wolfSSL_RSA_size((const WOLFSSL_RSA*)(b->rsa));
+        break;
+#endif /* !NO_RSA */
+#ifdef HAVE_ECC
+    case EVP_PKEY_EC:
+        if (a->ecc == NULL || a->ecc->internal == NULL ||
+            b->ecc == NULL || b->ecc->internal == NULL) {
+            return ret;
+        }
+        a_sz = wc_ecc_size((ecc_key*)(a->ecc->internal));
+        b_sz = wc_ecc_size((ecc_key*)(b->ecc->internal));
+        break;
+#endif /* HAVE_ECC */
+    default:
+        break;
+    } /* switch (a->type) */
+
+    /* check size */
+    if (a_sz <= 0 || b_sz <= 0 || a_sz != b_sz) {
+        return ret;
+    }
+
+    /* check public key size */
+    if (a->pkey_sz > 0 && b->pkey_sz > 0 && a->pkey_sz != b->pkey_sz) {
+        return ret;
+    }
+
+    /* check public key */
+    if (a->pkey.ptr && b->pkey.ptr) {
+        if (XMEMCMP(a->pkey.ptr, b->pkey.ptr, a->pkey_sz) != 0) {
+            return ret;
+        }
+    }
+    ret = 0; /* success */
+
+    return ret;
+}
+
+/* Initialize structure for signing
+ *
+ * ctx  WOLFSSL_EVP_MD_CTX structure to initialize
+ * type is the type of message digest to use
+ *
+ * returns WOLFSSL_SUCCESS on success
+ */
+int wolfSSL_EVP_SignInit(WOLFSSL_EVP_MD_CTX *ctx, const WOLFSSL_EVP_MD *type)
+{
+    if (ctx == NULL) return WOLFSSL_FAILURE;
+    WOLFSSL_ENTER("EVP_SignInit");
+    return wolfSSL_EVP_DigestInit(ctx,type);
+}
+
+WOLFSSL_API int wolfSSL_EVP_SignInit_ex(WOLFSSL_EVP_MD_CTX* ctx,
+                                     const WOLFSSL_EVP_MD* type,
+                                     WOLFSSL_ENGINE *impl)
+{
+    if (ctx == NULL) return WOLFSSL_FAILURE;
+    WOLFSSL_ENTER("EVP_SignInit");
+    return wolfSSL_EVP_DigestInit_ex(ctx,type,impl);
+}
+
+
+/* Update structure with data for signing
+ *
+ * ctx  WOLFSSL_EVP_MD_CTX structure to update
+ * data buffer holding data to update with for sign
+ * len  length of data buffer
+ *
+ * returns WOLFSSL_SUCCESS on success
+ */
+int wolfSSL_EVP_SignUpdate(WOLFSSL_EVP_MD_CTX *ctx, const void *data, size_t len)
+{
+    if (ctx == NULL) return 0;
+    WOLFSSL_ENTER("EVP_SignUpdate(");
+    return wolfSSL_EVP_DigestUpdate(ctx, data, len);
+}
+
+static const struct s_ent {
+    const int macType;
+    const int nid;
+    const char *name;
+} md_tbl[] = {
+#ifndef NO_MD4
+    {WC_HASH_TYPE_MD4, NID_md4, "MD4"},
+#endif /* NO_MD4 */
+
+#ifndef NO_MD5
+    {WC_HASH_TYPE_MD5, NID_md5, "MD5"},
+#endif /* NO_MD5 */
+
+#ifndef NO_SHA
+    {WC_HASH_TYPE_SHA, NID_sha1, "SHA"},
+#endif /* NO_SHA */
+
+#ifdef WOLFSSL_SHA224
+    {WC_HASH_TYPE_SHA224, NID_sha224, "SHA224"},
+#endif /* WOLFSSL_SHA224 */
+#ifndef NO_SHA256
+    {WC_HASH_TYPE_SHA256, NID_sha256, "SHA256"},
+#endif
+
+#ifdef WOLFSSL_SHA384
+    {WC_HASH_TYPE_SHA384, NID_sha384, "SHA384"},
+#endif /* WOLFSSL_SHA384 */
+#ifdef WOLFSSL_SHA512
+    {WC_HASH_TYPE_SHA512, NID_sha512, "SHA512"},
+#endif /* WOLFSSL_SHA512 */
+#ifndef WOLFSSL_NOSHA3_224
+    {WC_HASH_TYPE_SHA3_224, NID_sha3_224, "SHA3_224"},
+#endif
+#ifndef WOLFSSL_NOSHA3_256
+    {WC_HASH_TYPE_SHA3_256, NID_sha3_256, "SHA3_256"},
+#endif
+    {WC_HASH_TYPE_SHA3_384, NID_sha3_384, "SHA3_384"},
+#ifndef WOLFSSL_NOSHA3_512
+    {WC_HASH_TYPE_SHA3_512, NID_sha3_512, "SHA3_512"},
+#endif
+    {0, 0, NULL}
+};
+
+static int wolfSSL_EVP_md2macType(const WOLFSSL_EVP_MD *md)
+{
+    const struct s_ent *ent ;
+
+    if (md != NULL) {
+        for( ent = md_tbl; ent->name != NULL; ent++) {
+            if(XSTRNCMP((const char *)md, ent->name, XSTRLEN(ent->name)+1) == 0) {
+                return ent->macType;
+            }
+        }
+    }
+    return WC_HASH_TYPE_NONE;
+}
+
+/* Finalize structure for signing
+ *
+ * ctx    WOLFSSL_EVP_MD_CTX structure to finalize
+ * sigret buffer to hold resulting signature
+ * siglen length of sigret buffer
+ * pkey   key to sign with
+ *
+ * returns WOLFSSL_SUCCESS on success and WOLFSSL_FAILURE on failure
+ */
+int wolfSSL_EVP_SignFinal(WOLFSSL_EVP_MD_CTX *ctx, unsigned char *sigret,
+                  unsigned int *siglen, WOLFSSL_EVP_PKEY *pkey)
+{
+    unsigned int mdsize;
+    unsigned char md[WC_MAX_DIGEST_SIZE];
+    int ret;
+    if (ctx == NULL) return WOLFSSL_FAILURE;
+    WOLFSSL_ENTER("EVP_SignFinal");
+
+    ret = wolfSSL_EVP_DigestFinal(ctx, md, &mdsize);
+    if (ret <= 0) return ret;
+
+    (void)sigret;
+    (void)siglen;
+
+    switch (pkey->type) {
+#if !defined(NO_RSA) && !defined(HAVE_USER_RSA)
+    case EVP_PKEY_RSA: {
+        int nid = wolfSSL_EVP_MD_type(wolfSSL_EVP_MD_CTX_md(ctx));
+        if (nid < 0) break;
+        return wolfSSL_RSA_sign(nid, md, mdsize, sigret,
+                                siglen, pkey->rsa);
+    }
+#endif /* NO_RSA */
+
+    case EVP_PKEY_DSA:
+    case EVP_PKEY_EC:
+        WOLFSSL_MSG("not implemented");
+        FALL_THROUGH;
+    default:
+        break;
+    }
+    return WOLFSSL_FAILURE;
+}
+
+
+/* Initialize structure for verifying signature
+ *
+ * ctx  WOLFSSL_EVP_MD_CTX structure to initialize
+ * type is the type of message digest to use
+ *
+ * returns WOLFSSL_SUCCESS on success
+ */
+int wolfSSL_EVP_VerifyInit(WOLFSSL_EVP_MD_CTX *ctx, const WOLFSSL_EVP_MD *type)
+{
+    if (ctx == NULL) return WOLFSSL_FAILURE;
+    WOLFSSL_ENTER("EVP_VerifyInit");
+    return wolfSSL_EVP_DigestInit(ctx,type);
+}
+
+
+/* Update structure for verifying signature
+ *
+ * ctx  WOLFSSL_EVP_MD_CTX structure to update
+ * data buffer holding data to update with for verify
+ * len  length of data buffer
+ *
+ * returns WOLFSSL_SUCCESS on success and WOLFSSL_FAILURE on failure
+ */
+int wolfSSL_EVP_VerifyUpdate(WOLFSSL_EVP_MD_CTX *ctx, const void *data, size_t len)
+{
+    if (ctx == NULL) return WOLFSSL_FAILURE;
+    WOLFSSL_ENTER("EVP_VerifyUpdate");
+    return wolfSSL_EVP_DigestUpdate(ctx, data, len);
+}
+
+
+/* Finalize structure for verifying signature
+ *
+ * ctx    WOLFSSL_EVP_MD_CTX structure to finalize
+ * sig    buffer holding signature
+ * siglen length of sig buffer
+ * pkey   key to verify with
+ *
+ * returns WOLFSSL_SUCCESS on success and WOLFSSL_FAILURE on failure
+ */
+int wolfSSL_EVP_VerifyFinal(WOLFSSL_EVP_MD_CTX *ctx,
+        unsigned char*sig, unsigned int siglen, WOLFSSL_EVP_PKEY *pkey)
+{
+    int ret;
+    unsigned char md[WC_MAX_DIGEST_SIZE];
+    unsigned int mdsize;
+
+    if (ctx == NULL) return WOLFSSL_FAILURE;
+    WOLFSSL_ENTER("EVP_VerifyFinal");
+    ret = wolfSSL_EVP_DigestFinal(ctx, md, &mdsize);
+    if (ret <= 0) return ret;
+
+    (void)sig;
+    (void)siglen;
+
+    switch (pkey->type) {
+#if !defined(NO_RSA) && !defined(HAVE_USER_RSA)
+    case EVP_PKEY_RSA: {
+        int nid = wolfSSL_EVP_MD_type(wolfSSL_EVP_MD_CTX_md(ctx));
+        if (nid < 0) break;
+        return wolfSSL_RSA_verify(nid, md, mdsize, sig,
+                (unsigned int)siglen, pkey->rsa);
+    }
+#endif /* NO_RSA */
+
+    case EVP_PKEY_DSA:
+    case EVP_PKEY_EC:
+        WOLFSSL_MSG("not implemented");
+        FALL_THROUGH;
+    default:
+        break;
+    }
+    return WOLFSSL_FAILURE;
+}
+
+int wolfSSL_EVP_add_cipher(const WOLFSSL_EVP_CIPHER *cipher)
+{
+    (void)cipher;
+    /* nothing to do */
+    return 0;
+}
+
+
+WOLFSSL_EVP_PKEY* wolfSSL_EVP_PKEY_new_mac_key(int type, ENGINE* e,
+                                          const unsigned char* key, int keylen)
+{
+    WOLFSSL_EVP_PKEY* pkey;
+
+    (void)e;
+
+    if (type != EVP_PKEY_HMAC || (key == NULL && keylen != 0))
+        return NULL;
+
+    pkey = wolfSSL_EVP_PKEY_new();
+    if (pkey != NULL) {
+        pkey->pkey.ptr = (char*)XMALLOC(keylen, NULL, DYNAMIC_TYPE_PUBLIC_KEY);
+        if (pkey->pkey.ptr == NULL && keylen > 0) {
+            wolfSSL_EVP_PKEY_free(pkey);
+            pkey = NULL;
+        }
+        else {
+            XMEMCPY(pkey->pkey.ptr, key, keylen);
+            pkey->pkey_sz = keylen;
+            pkey->type = pkey->save_type = type;
+        }
+    }
+
+    return pkey;
+}
+
+
+const unsigned char* wolfSSL_EVP_PKEY_get0_hmac(const WOLFSSL_EVP_PKEY* pkey,
+                                                size_t* len)
+{
+    if (pkey == NULL || len == NULL)
+        return NULL;
+
+    *len = (size_t)pkey->pkey_sz;
+
+    return (const unsigned char*)pkey->pkey.ptr;
+}
+
+
+/* Initialize an EVP_DigestSign/Verify operation.
+ * Initialize a digest for RSA and ECC keys, or HMAC for HMAC key.
+ */
+static int wolfSSL_evp_digest_pk_init(WOLFSSL_EVP_MD_CTX *ctx,
+                                      WOLFSSL_EVP_PKEY_CTX **pctx,
+                                      const WOLFSSL_EVP_MD *type,
+                                      WOLFSSL_ENGINE *e,
+                                      WOLFSSL_EVP_PKEY *pkey)
+{
+    if (pkey->type == EVP_PKEY_HMAC) {
+        int                  hashType;
+        const unsigned char* key;
+        size_t               keySz;
+
+        if (XSTRNCMP(type, "SHA256", 6) == 0) {
+            hashType = WC_SHA256;
+        }
+    #ifdef WOLFSSL_SHA224
+        else if (XSTRNCMP(type, "SHA224", 6) == 0) {
+            hashType = WC_SHA224;
+        }
+    #endif
+    #ifdef WOLFSSL_SHA384
+        else if (XSTRNCMP(type, "SHA384", 6) == 0) {
+            hashType = WC_SHA384;
+        }
+    #endif
+    #ifdef WOLFSSL_SHA512
+        else if (XSTRNCMP(type, "SHA512", 6) == 0) {
+            hashType = WC_SHA512;
+        }
+    #endif
+    #ifndef NO_MD5
+        else if (XSTRNCMP(type, "MD5", 3) == 0) {
+            hashType = WC_MD5;
+        }
+    #endif
+    #ifndef NO_SHA
+        /* has to be last since would pick or 224, 256, 384, or 512 too */
+        else if (XSTRNCMP(type, "SHA", 3) == 0) {
+             hashType = WC_SHA;
+        }
+    #endif /* NO_SHA */
+        else
+             return BAD_FUNC_ARG;
+
+        key = wolfSSL_EVP_PKEY_get0_hmac(pkey, &keySz);
+
+        if (wc_HmacInit(&ctx->hash.hmac, NULL, INVALID_DEVID) != 0)
+            return WOLFSSL_FAILURE;
+
+        if (wc_HmacSetKey(&ctx->hash.hmac, hashType, key, (word32)keySz) != 0)
+            return WOLFSSL_FAILURE;
+
+        ctx->macType = NID_hmac;
+    }
+    else {
+        int ret;
+
+        if (ctx->pctx == NULL) {
+            ctx->pctx = wolfSSL_EVP_PKEY_CTX_new(pkey, e);
+            if (ctx->pctx == NULL)
+                return WOLFSSL_FAILURE;
+        }
+
+        ret = wolfSSL_EVP_DigestInit(ctx, type);
+        if (ret == WOLFSSL_SUCCESS && pctx != NULL)
+            *pctx = ctx->pctx;
+        return ret;
+    }
+
+    return WOLFSSL_SUCCESS;
+}
+
+/* Update an EVP_DigestSign/Verify operation.
+ * Update a digest for RSA and ECC keys, or HMAC for HMAC key.
+ */
+static int wolfssl_evp_digest_pk_update(WOLFSSL_EVP_MD_CTX *ctx,
+                                        const void *d, unsigned int cnt)
+{
+    if (ctx->pctx == NULL) {
+        if (ctx->macType != NID_hmac)
+            return WOLFSSL_FAILURE;
+
+        if (wc_HmacUpdate(&ctx->hash.hmac, (const byte *)d, cnt) != 0)
+            return WOLFSSL_FAILURE;
+
+        return WOLFSSL_SUCCESS;
+    }
+    else
+        return wolfSSL_EVP_DigestUpdate(ctx, d, cnt);
+}
+
+/* Finalize an EVP_DigestSign/Verify operation - common part only.
+ * Finalize a digest for RSA and ECC keys, or HMAC for HMAC key.
+ * Copies the digest so that you can keep updating.
+ */
+static int wolfssl_evp_digest_pk_final(WOLFSSL_EVP_MD_CTX *ctx,
+                                       unsigned char *md, unsigned int* mdlen)
+{
+    int  ret;
+
+    if (ctx->pctx == NULL) {
+        Hmac hmacCopy;
+
+        if (ctx->macType != NID_hmac)
+            return WOLFSSL_FAILURE;
+
+        if (wolfSSL_HmacCopy(&hmacCopy, &ctx->hash.hmac) != WOLFSSL_SUCCESS)
+            return WOLFSSL_FAILURE;
+        ret = wc_HmacFinal(&hmacCopy, md) == 0;
+        wc_HmacFree(&hmacCopy);
+        return ret;
+    }
+    else {
+        WOLFSSL_EVP_MD_CTX ctxCopy;
+
+        if (wolfSSL_EVP_MD_CTX_copy_ex(&ctxCopy, ctx) != WOLFSSL_SUCCESS)
+            return WOLFSSL_FAILURE;
+
+        ret = wolfSSL_EVP_DigestFinal(&ctxCopy, md, mdlen);
+        wolfSSL_EVP_MD_CTX_cleanup(&ctxCopy);
+        return ret;
+    }
+}
+
+/* Get the length of the mac based on the digest algorithm. */
+static int wolfssl_mac_len(unsigned char macType)
+{
+    int hashLen;
+
+    switch (macType) {
+    #ifndef NO_MD5
+        case WC_MD5:
+            hashLen = WC_MD5_DIGEST_SIZE;
+            break;
+    #endif /* !NO_MD5 */
+
+    #ifndef NO_SHA
+        case WC_SHA:
+            hashLen = WC_SHA_DIGEST_SIZE;
+            break;
+    #endif /* !NO_SHA */
+
+    #ifdef WOLFSSL_SHA224
+        case WC_SHA224:
+            hashLen = WC_SHA224_DIGEST_SIZE;
+            break;
+    #endif /* WOLFSSL_SHA224 */
+
+    #ifndef NO_SHA256
+        case WC_SHA256:
+            hashLen = WC_SHA256_DIGEST_SIZE;
+            break;
+    #endif /* !NO_SHA256 */
+
+    #ifdef WOLFSSL_SHA384
+        case WC_SHA384:
+            hashLen = WC_SHA384_DIGEST_SIZE;
+            break;
+    #endif /* WOLFSSL_SHA384 */
+    #ifdef WOLFSSL_SHA512
+        case WC_SHA512:
+            hashLen = WC_SHA512_DIGEST_SIZE;
+            break;
+    #endif /* WOLFSSL_SHA512 */
+
+    #ifdef HAVE_BLAKE2
+        case BLAKE2B_ID:
+            hashLen = BLAKE2B_OUTBYTES;
+            break;
+    #endif /* HAVE_BLAKE2 */
+
+        default:
+            hashLen = 0;
+    }
+
+    return hashLen;
+}
+
+int wolfSSL_EVP_DigestSignInit(WOLFSSL_EVP_MD_CTX *ctx,
+                               WOLFSSL_EVP_PKEY_CTX **pctx,
+                               const WOLFSSL_EVP_MD *type,
+                               WOLFSSL_ENGINE *e,
+                               WOLFSSL_EVP_PKEY *pkey)
+{
+    WOLFSSL_ENTER("EVP_DigestSignInit");
+
+    if (ctx == NULL || type == NULL || pkey == NULL)
+        return BAD_FUNC_ARG;
+
+    return wolfSSL_evp_digest_pk_init(ctx, pctx, type, e, pkey);
+}
+
+
+int wolfSSL_EVP_DigestSignUpdate(WOLFSSL_EVP_MD_CTX *ctx, const void *d,
+                                 unsigned int cnt)
+{
+    WOLFSSL_ENTER("EVP_DigestSignUpdate");
+
+    if (ctx == NULL || d == NULL)
+        return BAD_FUNC_ARG;
+
+    return wolfssl_evp_digest_pk_update(ctx, d, cnt);
+}
+
+int wolfSSL_EVP_DigestSignFinal(WOLFSSL_EVP_MD_CTX *ctx, unsigned char *sig,
+                                size_t *siglen)
+{
+    unsigned char digest[WC_MAX_DIGEST_SIZE];
+    unsigned int  hashLen;
+    int           ret = WOLFSSL_FAILURE;
+
+    WOLFSSL_ENTER("EVP_DigestSignFinal");
+
+    if (ctx == NULL || siglen == NULL)
+        return WOLFSSL_FAILURE;
+
+    /* Return the maximum size of the signaure when sig is NULL. */
+    if (ctx->pctx == NULL) {
+        if (ctx->macType != NID_hmac)
+            return WOLFSSL_FAILURE;
+
+        hashLen = wolfssl_mac_len(ctx->hash.hmac.macType);
+
+        if (sig == NULL) {
+            *siglen = hashLen;
+            return WOLFSSL_SUCCESS;
+        }
+    }
+#ifndef NO_RSA
+    else if (ctx->pctx->pkey->type == EVP_PKEY_RSA) {
+        if (sig == NULL) {
+            *siglen = wolfSSL_RSA_size(ctx->pctx->pkey->rsa);
+            return WOLFSSL_SUCCESS;
+        }
+    }
+#endif /* !NO_RSA */
+#ifdef HAVE_ECC
+    else if (ctx->pctx->pkey->type == EVP_PKEY_EC) {
+        if (sig == NULL) {
+            /* SEQ + INT + INT */
+            *siglen = ecc_sets[ctx->pctx->pkey->ecc->group->curve_idx].size * 2
+                    + 8;
+            return WOLFSSL_SUCCESS;
+        }
+    }
+#endif
+
+    if (wolfssl_evp_digest_pk_final(ctx, digest, &hashLen) <= 0)
+        return WOLFSSL_FAILURE;
+
+    if (ctx->pctx == NULL) {
+        /* Copy the HMAC result as signature. */
+        if ((unsigned int)(*siglen) > hashLen)
+            *siglen = hashLen;
+        /* May be a truncated signature. */
+
+        XMEMCPY(sig, digest, *siglen);
+        ret = WOLFSSL_SUCCESS;
+    }
+    else {
+        /* Sign the digest. */
+        switch (ctx->pctx->pkey->type) {
+    #if !defined(NO_RSA) && !defined(HAVE_USER_RSA)
+        case EVP_PKEY_RSA: {
+            unsigned int sigSz;
+            int nid = wolfSSL_EVP_MD_type(wolfSSL_EVP_MD_CTX_md(ctx));
+            if (nid < 0)
+                break;
+            ret = wolfSSL_RSA_sign(nid, digest, hashLen, sig, &sigSz,
+                                   ctx->pctx->pkey->rsa);
+            if (ret >= 0)
+                *siglen = sigSz;
+            break;
+        }
+    #endif /* NO_RSA */
+
+    #ifdef HAVE_ECC
+        case EVP_PKEY_EC: {
+            WOLFSSL_ECDSA_SIG *ecdsaSig;
+            ecdsaSig = wolfSSL_ECDSA_do_sign(digest, hashLen,
+                                             ctx->pctx->pkey->ecc);
+            if (ecdsaSig == NULL)
+                break;
+            *siglen = wolfSSL_i2d_ECDSA_SIG(ecdsaSig, &sig);
+            wolfSSL_ECDSA_SIG_free(ecdsaSig);
+            ret = WOLFSSL_SUCCESS;
+            break;
+        }
+    #endif
+        default:
+            break;
+        }
+    }
+
+    ForceZero(digest, sizeof(digest));
+    return ret;
+}
+int wolfSSL_EVP_DigestVerifyInit(WOLFSSL_EVP_MD_CTX *ctx,
+                                 WOLFSSL_EVP_PKEY_CTX **pctx,
+                                 const WOLFSSL_EVP_MD *type,
+                                 WOLFSSL_ENGINE *e,
+                                 WOLFSSL_EVP_PKEY *pkey)
+{
+    WOLFSSL_ENTER("EVP_DigestVerifyInit");
+
+    if (ctx == NULL || type == NULL || pkey == NULL)
+        return BAD_FUNC_ARG;
+
+    return wolfSSL_evp_digest_pk_init(ctx, pctx, type, e, pkey);
+}
+
+
+int wolfSSL_EVP_DigestVerifyUpdate(WOLFSSL_EVP_MD_CTX *ctx, const void *d,
+                                   size_t cnt)
+{
+    WOLFSSL_ENTER("EVP_DigestVerifyUpdate");
+
+    if (ctx == NULL || d == NULL)
+        return BAD_FUNC_ARG;
+
+    return wolfssl_evp_digest_pk_update(ctx, d, (unsigned int)cnt);
+}
+
+
+int wolfSSL_EVP_DigestVerifyFinal(WOLFSSL_EVP_MD_CTX *ctx,
+                                  const unsigned char *sig, size_t siglen)
+{
+    unsigned char digest[WC_MAX_DIGEST_SIZE];
+    unsigned int  hashLen;
+
+    WOLFSSL_ENTER("EVP_DigestVerifyFinal");
+
+    if (ctx == NULL || sig == NULL)
+        return WOLFSSL_FAILURE;
+
+    if (ctx->pctx == NULL) {
+        if (ctx->macType != NID_hmac)
+            return WOLFSSL_FAILURE;
+
+        hashLen = wolfssl_mac_len(ctx->hash.hmac.macType);
+
+        if (siglen > hashLen)
+            return WOLFSSL_FAILURE;
+        /* May be a truncated signature. */
+    }
+
+    if (wolfssl_evp_digest_pk_final(ctx, digest, &hashLen) <= 0)
+        return WOLFSSL_FAILURE;
+
+    if (ctx->pctx == NULL) {
+        /* Check HMAC result matches the signature. */
+        if (XMEMCMP(sig, digest, siglen) == 0)
+            return WOLFSSL_SUCCESS;
+        return WOLFSSL_FAILURE;
+    }
+    else {
+        /* Verify the signature with the digest. */
+        switch (ctx->pctx->pkey->type) {
+    #if !defined(NO_RSA) && !defined(HAVE_USER_RSA)
+        case EVP_PKEY_RSA: {
+            int nid = wolfSSL_EVP_MD_type(wolfSSL_EVP_MD_CTX_md(ctx));
+            if (nid < 0)
+                return WOLFSSL_FAILURE;
+            return wolfSSL_RSA_verify(nid, digest, hashLen, sig,
+                                      (unsigned int)siglen,
+                                      ctx->pctx->pkey->rsa);
+        }
+    #endif /* NO_RSA */
+
+    #ifdef HAVE_ECC
+        case EVP_PKEY_EC: {
+            int ret;
+            WOLFSSL_ECDSA_SIG *ecdsaSig;
+            ecdsaSig = wolfSSL_d2i_ECDSA_SIG(NULL, &sig, (long)siglen);
+            if (ecdsaSig == NULL)
+                return WOLFSSL_FAILURE;
+            ret = wolfSSL_ECDSA_do_verify(digest, hashLen, ecdsaSig,
+                                          ctx->pctx->pkey->ecc);
+            wolfSSL_ECDSA_SIG_free(ecdsaSig);
+            return ret;
+        }
+    #endif
+        default:
+            break;
+        }
+    }
+
+    return WOLFSSL_FAILURE;
+}
+
+
+#ifdef WOLFSSL_APACHE_HTTPD
+#if !defined(USE_WINDOWS_API) && !defined(MICROCHIP_PIC32)
+    #include <termios.h>
+#endif
+
+#ifndef XGETPASSWD
+    static int XGETPASSWD(char* buf, int bufSz) {
+        int ret = WOLFSSL_SUCCESS;
+
+        /* turn off echo for passwords */
+    #ifdef USE_WINDOWS_API
+        DWORD originalTerm;
+        DWORD newTerm;
+        CONSOLE_SCREEN_BUFFER_INFO screenOrig;
+        HANDLE stdinHandle = GetStdHandle(STD_INPUT_HANDLE);
+        if (GetConsoleMode(stdinHandle, &originalTerm) == 0) {
+            WOLFSSL_MSG("Couldn't get the original terminal settings");
+            return WOLFSSL_FAILURE;
+        }
+        newTerm = originalTerm;
+        newTerm &= ~ENABLE_ECHO_INPUT;
+        if (SetConsoleMode(stdinHandle, newTerm) == 0) {
+            WOLFSSL_MSG("Couldn't turn off echo");
+            return WOLFSSL_FAILURE;
+        }
+    #else
+        struct termios originalTerm;
+        struct termios newTerm;
+        if (tcgetattr(STDIN_FILENO, &originalTerm) != 0) {
+            WOLFSSL_MSG("Couldn't get the original terminal settings");
+            return WOLFSSL_FAILURE;
+        }
+        XMEMCPY(&newTerm, &originalTerm, sizeof(struct termios));
+
+        newTerm.c_lflag &= ~ECHO;
+        newTerm.c_lflag |= (ICANON | ECHONL);
+        if (tcsetattr(STDIN_FILENO, TCSANOW, &newTerm) != 0) {
+            WOLFSSL_MSG("Couldn't turn off echo");
+            return WOLFSSL_FAILURE;
+        }
+    #endif
+
+        if (XFGETS(buf, bufSz, stdin) == NULL) {
+            ret = WOLFSSL_FAILURE;
+        }
+
+        /* restore default echo */
+    #ifdef USE_WINDOWS_API
+        if (SetConsoleMode(stdinHandle, originalTerm) == 0) {
+            WOLFSSL_MSG("Couldn't restore the terminal settings");
+            return WOLFSSL_FAILURE;
+        }
+    #else
+        if (tcsetattr(STDIN_FILENO, TCSANOW, &originalTerm) != 0) {
+            WOLFSSL_MSG("Couldn't restore the terminal settings");
+            return WOLFSSL_FAILURE;
+        }
+    #endif
+        return ret;
+    }
+#endif
+
+/* returns 0 on success and -2 or -1 on failure */
+int wolfSSL_EVP_read_pw_string(char* buf, int bufSz, const char* banner, int v)
+{
+    printf("%s", banner);
+    if (XGETPASSWD(buf, bufSz) == WOLFSSL_FAILURE) {
+        return -1;
+    }
+    (void)v; /* fgets always sanity checks size of input vs buffer */
+    return 0;
+}
+#endif /* WOLFSSL_APACHE_HTTPD */
+
+#if !defined(NO_PWDBASED) && !defined(NO_SHA)
+int wolfSSL_PKCS5_PBKDF2_HMAC_SHA1(const char *pass, int passlen,
+                                               const unsigned char *salt,
+                                               int saltlen, int iter,
+                                               int keylen, unsigned char *out)
+{
+    const char *nostring = "";
+    int ret = 0;
+
+    if (pass == NULL) {
+        passlen = 0;
+        pass = nostring;
+    }
+    else if (passlen == -1) {
+        passlen = (int)XSTRLEN(pass);
+    }
+
+    ret = wc_PBKDF2((byte*)out, (byte*)pass, passlen, (byte*)salt, saltlen,
+                    iter, keylen, WC_SHA);
+    if (ret == 0)
+        return WOLFSSL_SUCCESS;
+    else
+        return WOLFSSL_FAILURE;
+}
+#endif /* !NO_PWDBASED !NO_SHA*/
+
+#if !defined(NO_PWDBASED)
+WOLFSSL_API int wolfSSL_PKCS5_PBKDF2_HMAC(const char *pass, int passlen,
+                                           const unsigned char *salt,
+                                           int saltlen, int iter,
+                                           const WOLFSSL_EVP_MD *digest,
+                                           int keylen, unsigned char *out)
+{
+    const char *nostring = "";
+    int ret = 0;
+
+    if (pass == NULL) {
+        passlen = 0;
+        pass = nostring;
+    } else if (passlen == -1) {
+        passlen = (int)XSTRLEN(pass);
+    }
+
+    ret = wc_PBKDF2((byte*)out, (byte*)pass, passlen, (byte*)salt, saltlen,
+                    iter, keylen, wolfSSL_EVP_md2macType(digest));
+    if (ret == 0)
+        return WOLFSSL_SUCCESS;
+    else
+        return WOLFSSL_FAILURE;
+}
+#endif /* !NO_PWDBASED */
+
+static const struct cipher{
+        unsigned char type;
+        const char *name;
+        int nid;
+} cipher_tbl[] = {
+
+#ifndef NO_AES
+    #ifdef WOLFSSL_AES_128
+    {AES_128_CBC_TYPE, "AES-128-CBC", NID_aes_128_cbc},
+    #endif
+    #ifdef WOLFSSL_AES_192
+    {AES_192_CBC_TYPE, "AES-192-CBC", NID_aes_192_cbc},
+    #endif
+    #ifdef WOLFSSL_AES_256
+    {AES_256_CBC_TYPE, "AES-256-CBC", NID_aes_256_cbc},
+    #endif
+
+    #ifdef WOLFSSL_AES_128
+    {AES_128_CFB1_TYPE, "AES-128-CFB1", NID_aes_128_cfb1},
+    #endif
+    #ifdef WOLFSSL_AES_192
+    {AES_192_CFB1_TYPE, "AES-192-CFB1", NID_aes_192_cfb1},
+    #endif
+    #ifdef WOLFSSL_AES_256
+    {AES_256_CFB1_TYPE, "AES-256-CFB1", NID_aes_256_cfb1},
+    #endif
+
+    #ifdef WOLFSSL_AES_128
+    {AES_128_CFB8_TYPE, "AES-128-CFB8", NID_aes_128_cfb8},
+    #endif
+    #ifdef WOLFSSL_AES_192
+    {AES_192_CFB8_TYPE, "AES-192-CFB8", NID_aes_192_cfb8},
+    #endif
+    #ifdef WOLFSSL_AES_256
+    {AES_256_CFB8_TYPE, "AES-256-CFB8", NID_aes_256_cfb8},
+    #endif
+
+    #ifdef WOLFSSL_AES_128
+    {AES_128_CFB128_TYPE, "AES-128-CFB128", NID_aes_128_cfb128},
+    #endif
+    #ifdef WOLFSSL_AES_192
+    {AES_192_CFB128_TYPE, "AES-192-CFB128", NID_aes_192_cfb128},
+    #endif
+    #ifdef WOLFSSL_AES_256
+    {AES_256_CFB128_TYPE, "AES-256-CFB128", NID_aes_256_cfb128},
+    #endif
+
+    #ifdef WOLFSSL_AES_128
+    {AES_128_OFB_TYPE, "AES-128-OFB", NID_aes_128_ofb},
+    #endif
+    #ifdef WOLFSSL_AES_192
+    {AES_192_OFB_TYPE, "AES-192-OFB", NID_aes_192_ofb},
+    #endif
+    #ifdef WOLFSSL_AES_256
+    {AES_256_OFB_TYPE, "AES-256-OFB", NID_aes_256_ofb},
+    #endif
+
+    #ifdef WOLFSSL_AES_128
+    {AES_128_XTS_TYPE, "AES-128-XTS", NID_aes_128_xts},
+    #endif
+    #ifdef WOLFSSL_AES_256
+    {AES_256_XTS_TYPE, "AES-256-XTS", NID_aes_256_xts},
+    #endif
+
+    #ifdef WOLFSSL_AES_128
+    {AES_128_GCM_TYPE, "AES-128-GCM", NID_aes_128_gcm},
+    #endif
+    #ifdef WOLFSSL_AES_192
+    {AES_192_GCM_TYPE, "AES-192-GCM", NID_aes_192_gcm},
+    #endif
+    #ifdef WOLFSSL_AES_256
+    {AES_256_GCM_TYPE, "AES-256-GCM", NID_aes_256_gcm},
+    #endif
+    #ifdef WOLFSSL_AES_128
+        {AES_128_CTR_TYPE, "AES-128-CTR", NID_aes_128_ctr},
+    #endif
+    #ifdef WOLFSSL_AES_192
+        {AES_192_CTR_TYPE, "AES-192-CTR", NID_aes_192_ctr},
+    #endif
+    #ifdef WOLFSSL_AES_256
+        {AES_256_CTR_TYPE, "AES-256-CTR", NID_aes_256_ctr},
+    #endif
+
+    #ifdef WOLFSSL_AES_128
+        {AES_128_ECB_TYPE, "AES-128-ECB", NID_aes_128_ecb},
+    #endif
+    #ifdef WOLFSSL_AES_192
+        {AES_192_ECB_TYPE, "AES-192-ECB", NID_aes_192_ecb},
+    #endif
+    #ifdef WOLFSSL_AES_256
+        {AES_256_ECB_TYPE, "AES-256-ECB", NID_aes_256_ecb},
+    #endif
+
+#endif
+
+#ifndef NO_DES3
+    {DES_CBC_TYPE, "DES-CBC", NID_des_cbc},
+    {DES_ECB_TYPE, "DES-ECB", NID_des_ecb},
+
+    {DES_EDE3_CBC_TYPE, "DES-EDE3-CBC", NID_des_ede3_cbc},
+    {DES_EDE3_ECB_TYPE, "DES-EDE3-ECB", NID_des_ede3_ecb},
+#endif
+
+#ifndef NO_RC4
+    {ARC4_TYPE, "ARC4", NID_undef},
+#endif
+
+#ifdef HAVE_IDEA
+    {IDEA_CBC_TYPE, "IDEA-CBC", NID_idea_cbc},
+#endif
+    { 0, NULL, 0}
+};
+
+/* returns cipher using provided ctx type */
+const WOLFSSL_EVP_CIPHER *wolfSSL_EVP_CIPHER_CTX_cipher(
+    const WOLFSSL_EVP_CIPHER_CTX *ctx)
+{
+    const struct cipher* c;
+
+    if (!ctx || !ctx->cipherType) {
+        return NULL;
+    }
+
+    for (c = cipher_tbl; c->type != 0; c++) {
+        if (ctx->cipherType == c->type) {
+            return wolfSSL_EVP_get_cipherbyname(c->name);
+        }
+    }
+
+    return NULL;
+}
+
+int wolfSSL_EVP_CIPHER_nid(const WOLFSSL_EVP_CIPHER *cipher)
+{
+    const struct cipher* c;
+
+    if (!cipher) {
+        return 0;
+    }
+
+    for (c = cipher_tbl; c->type != 0; c++) {
+        if (XSTRNCMP(cipher, c->name, XSTRLEN(c->name)+1) == 0) {
+            return c->nid;
+        }
+    }
+
+    return 0;
+}
+
+const WOLFSSL_EVP_CIPHER *wolfSSL_EVP_get_cipherbyname(const char *name)
+{
+
+    static const struct alias {
+        const char *name;
+        const char *alias;
+    } alias_tbl[] =
+    {
+#ifndef NO_DES3
+        {"DES-CBC", "DES"},
+        {"DES-CBC", "des"},
+        {"DES-ECB", "DES-ECB"},
+        {"DES-ECB", "des-ecb"},
+        {"DES-EDE3-CBC", "DES3"},
+        {"DES-EDE3-CBC", "des3"},
+        {"DES-EDE3-ECB", "DES-EDE3"},
+        {"DES-EDE3-ECB", "des-ede3"},
+        {"DES-EDE3-ECB", "des-ede3-ecb"},
+#endif
+#ifdef HAVE_IDEA
+        {"IDEA-CBC", "IDEA"},
+        {"IDEA-CBC", "idea"},
+#endif
+#ifndef NO_AES
+    #ifdef HAVE_AES_CBC
+        #ifdef WOLFSSL_AES_128
+        {"AES-128-CBC", "AES128-CBC"},
+        {"AES-128-CBC", "aes128-cbc"},
+        #endif
+        #ifdef WOLFSSL_AES_192
+        {"AES-192-CBC", "AES192-CBC"},
+        {"AES-192-CBC", "aes192-cbc"},
+        #endif
+        #ifdef WOLFSSL_AES_256
+        {"AES-256-CBC", "AES256-CBC"},
+        {"AES-256-CBC", "aes256-cbc"},
+        #endif
+    #endif
+    #ifdef WOLFSSL_AES_128
+        {"AES-128-ECB", "AES128-ECB"},
+        {"AES-128-ECB", "aes128-ecb"},
+    #endif
+    #ifdef WOLFSSL_AES_192
+        {"AES-192-ECB", "AES192-ECB"},
+        {"AES-192-ECB", "aes192-ecb"},
+    #endif
+    #ifdef WOLFSSL_AES_256
+        {"AES-256-ECB", "AES256-ECB"},
+    #endif
+    #ifdef HAVE_AESGCM
+        #ifdef WOLFSSL_AES_128
+        {"AES-128-GCM", "aes-128-gcm"},
+        {"AES-128-GCM", "id-aes128-GCM"},
+        #endif
+        #ifdef WOLFSSL_AES_192
+        {"AES-192-GCM", "aes-192-gcm"},
+        {"AES-192-GCM", "id-aes192-GCM"},
+        #endif
+        #ifdef WOLFSSL_AES_256
+        {"AES-256-GCM", "aes-256-gcm"},
+        {"AES-256-GCM", "id-aes256-GCM"},
+        #endif
+    #endif
+#endif
+#ifndef NO_RC4
+        {"ARC4", "RC4"},
+#endif
+        { NULL, NULL}
+    };
+
+    const struct cipher *ent;
+    const struct alias  *al;
+
+    WOLFSSL_ENTER("EVP_get_cipherbyname");
+
+    for( al = alias_tbl; al->name != NULL; al++)
+        if(XSTRNCMP(name, al->alias, XSTRLEN(al->alias)+1) == 0) {
+            name = al->name;
+            break;
+        }
+
+    for( ent = cipher_tbl; ent->name != NULL; ent++)
+        if(XSTRNCMP(name, ent->name, XSTRLEN(ent->name)+1) == 0) {
+            return (WOLFSSL_EVP_CIPHER *)ent->name;
+        }
+
+    return NULL;
+}
+
+/*
+ * return an EVP_CIPHER structure when cipher NID is passed.
+ *
+ * id  cipher NID
+ *
+ * return WOLFSSL_EVP_CIPHER
+*/
+const WOLFSSL_EVP_CIPHER *wolfSSL_EVP_get_cipherbynid(int id)
+{
+    WOLFSSL_ENTER("EVP_get_cipherbynid");
+
+    switch(id) {
+
+#ifndef NO_AES
+    #ifdef HAVE_AES_CBC
+        #ifdef WOLFSSL_AES_128
+        case NID_aes_128_cbc:
+            return wolfSSL_EVP_aes_128_cbc();
+        #endif
+        #ifdef WOLFSSL_AES_192
+        case NID_aes_192_cbc:
+            return wolfSSL_EVP_aes_192_cbc();
+        #endif
+        #ifdef WOLFSSL_AES_256
+        case NID_aes_256_cbc:
+            return wolfSSL_EVP_aes_256_cbc();
+        #endif
+    #endif
+    #ifdef WOLFSSL_AES_COUNTER
+        #ifdef WOLFSSL_AES_128
+        case NID_aes_128_ctr:
+            return wolfSSL_EVP_aes_128_ctr();
+        #endif
+        #ifdef WOLFSSL_AES_192
+        case NID_aes_192_ctr:
+            return wolfSSL_EVP_aes_192_ctr();
+        #endif
+        #ifdef WOLFSSL_AES_256
+        case NID_aes_256_ctr:
+            return wolfSSL_EVP_aes_256_ctr();
+        #endif
+    #endif /* WOLFSSL_AES_COUNTER */
+    #ifdef HAVE_AES_ECB
+        #ifdef WOLFSSL_AES_128
+        case NID_aes_128_ecb:
+            return wolfSSL_EVP_aes_128_ecb();
+        #endif
+        #ifdef WOLFSSL_AES_192
+        case NID_aes_192_ecb:
+            return wolfSSL_EVP_aes_192_ecb();
+        #endif
+        #ifdef WOLFSSL_AES_256
+        case NID_aes_256_ecb:
+            return wolfSSL_EVP_aes_256_ecb();
+        #endif
+    #endif /* HAVE_AES_ECB */
+    #ifdef HAVE_AESGCM
+        #ifdef WOLFSSL_AES_128
+        case NID_aes_128_gcm:
+            return wolfSSL_EVP_aes_128_gcm();
+        #endif
+        #ifdef WOLFSSL_AES_192
+        case NID_aes_192_gcm:
+            return wolfSSL_EVP_aes_192_gcm();
+        #endif
+        #ifdef WOLFSSL_AES_256
+        case NID_aes_256_gcm:
+            return wolfSSL_EVP_aes_256_gcm();
+        #endif
+    #endif
+#endif
+
+#ifndef NO_DES3
+        case NID_des_cbc:
+            return wolfSSL_EVP_des_cbc();
+#ifdef WOLFSSL_DES_ECB
+        case NID_des_ecb:
+            return wolfSSL_EVP_des_ecb();
+#endif
+        case NID_des_ede3_cbc:
+            return wolfSSL_EVP_des_ede3_cbc();
+#ifdef WOLFSSL_DES_ECB
+        case NID_des_ede3_ecb:
+            return wolfSSL_EVP_des_ede3_ecb();
+#endif
+#endif /*NO_DES3*/
+
+#ifdef HAVE_IDEA
+        case NID_idea_cbc:
+            return wolfSSL_EVP_idea_cbc();
+#endif
+
+        default:
+            WOLFSSL_MSG("Bad cipher id value");
+    }
+
+    return NULL;
+}
+
+void wolfSSL_EVP_init(void)
+{
+#ifndef NO_AES
+    #ifdef HAVE_AES_CBC
+        #ifdef WOLFSSL_AES_128
+        EVP_AES_128_CBC = (char *)EVP_get_cipherbyname("AES-128-CBC");
+        #endif
+        #ifdef WOLFSSL_AES_192
+        EVP_AES_192_CBC = (char *)EVP_get_cipherbyname("AES-192-CBC");
+        #endif
+        #ifdef WOLFSSL_AES_256
+        EVP_AES_256_CBC = (char *)EVP_get_cipherbyname("AES-256-CBC");
+        #endif
+    #endif /* HAVE_AES_CBC */
+
+    #ifdef WOLFSSL_AES_CFB
+        #ifdef WOLFSSL_AES_128
+        EVP_AES_128_CFB1 = (char *)EVP_get_cipherbyname("AES-128-CFB1");
+        #endif
+
+        #ifdef WOLFSSL_AES_192
+        EVP_AES_192_CFB1 = (char *)EVP_get_cipherbyname("AES-192-CFB1");
+        #endif
+
+        #ifdef WOLFSSL_AES_256
+        EVP_AES_256_CFB1 = (char *)EVP_get_cipherbyname("AES-256-CFB1");
+        #endif
+
+        #ifdef WOLFSSL_AES_128
+        EVP_AES_128_CFB8 = (char *)EVP_get_cipherbyname("AES-128-CFB8");
+        #endif
+
+        #ifdef WOLFSSL_AES_192
+        EVP_AES_192_CFB8 = (char *)EVP_get_cipherbyname("AES-192-CFB8");
+        #endif
+
+        #ifdef WOLFSSL_AES_256
+        EVP_AES_256_CFB8 = (char *)EVP_get_cipherbyname("AES-256-CFB8");
+        #endif
+
+        #ifdef WOLFSSL_AES_128
+        EVP_AES_128_CFB128 = (char *)EVP_get_cipherbyname("AES-128-CFB128");
+        #endif
+
+        #ifdef WOLFSSL_AES_192
+        EVP_AES_192_CFB128 = (char *)EVP_get_cipherbyname("AES-192-CFB128");
+        #endif
+
+        #ifdef WOLFSSL_AES_256
+        EVP_AES_256_CFB128 = (char *)EVP_get_cipherbyname("AES-256-CFB128");
+        #endif
+    #endif /* WOLFSSL_AES_CFB */
+
+    #ifdef WOLFSSL_AES_OFB
+        #ifdef WOLFSSL_AES_128
+        EVP_AES_128_OFB = (char *)EVP_get_cipherbyname("AES-128-OFB");
+        #endif
+
+        #ifdef WOLFSSL_AES_192
+        EVP_AES_192_OFB = (char *)EVP_get_cipherbyname("AES-192-OFB");
+        #endif
+
+        #ifdef WOLFSSL_AES_256
+        EVP_AES_256_OFB = (char *)EVP_get_cipherbyname("AES-256-OFB");
+        #endif
+    #endif /* WOLFSSL_AES_OFB */
+
+    #ifdef WOLFSSL_AES_XTS
+        #ifdef WOLFSSL_AES_128
+        EVP_AES_128_XTS = (char *)EVP_get_cipherbyname("AES-128-XTS");
+        #endif
+
+        #ifdef WOLFSSL_AES_256
+        EVP_AES_256_XTS = (char *)EVP_get_cipherbyname("AES-256-XTS");
+        #endif
+    #endif /* WOLFSSL_AES_XTS */
+
+    #ifdef HAVE_AESGCM
+        #ifdef WOLFSSL_AES_128
+        EVP_AES_128_GCM = (char *)EVP_get_cipherbyname("AES-128-GCM");
+        #endif
+        #ifdef WOLFSSL_AES_192
+        EVP_AES_192_GCM = (char *)EVP_get_cipherbyname("AES-192-GCM");
+        #endif
+        #ifdef WOLFSSL_AES_256
+        EVP_AES_256_GCM = (char *)EVP_get_cipherbyname("AES-256-GCM");
+        #endif
+    #endif /* HAVE_AESGCM*/
+        #ifdef WOLFSSL_AES_128
+        EVP_AES_128_CTR = (char *)EVP_get_cipherbyname("AES-128-CTR");
+        #endif
+        #ifdef WOLFSSL_AES_192
+        EVP_AES_192_CTR = (char *)EVP_get_cipherbyname("AES-192-CTR");
+        #endif
+        #ifdef WOLFSSL_AES_256
+        EVP_AES_256_CTR = (char *)EVP_get_cipherbyname("AES-256-CTR");
+        #endif
+
+        #ifdef WOLFSSL_AES_128
+        EVP_AES_128_ECB = (char *)EVP_get_cipherbyname("AES-128-ECB");
+        #endif
+        #ifdef WOLFSSL_AES_192
+        EVP_AES_192_ECB = (char *)EVP_get_cipherbyname("AES-192-ECB");
+        #endif
+        #ifdef WOLFSSL_AES_256
+        EVP_AES_256_ECB = (char *)EVP_get_cipherbyname("AES-256-ECB");
+        #endif
+#endif /* ifndef NO_AES*/
+
+#ifndef NO_DES3
+    EVP_DES_CBC = (char *)EVP_get_cipherbyname("DES-CBC");
+    EVP_DES_ECB = (char *)EVP_get_cipherbyname("DES-ECB");
+
+    EVP_DES_EDE3_CBC = (char *)EVP_get_cipherbyname("DES-EDE3-CBC");
+    EVP_DES_EDE3_ECB = (char *)EVP_get_cipherbyname("DES-EDE3-ECB");
+#endif
+
+#ifdef HAVE_IDEA
+    EVP_IDEA_CBC = (char *)EVP_get_cipherbyname("IDEA-CBC");
+#endif
+}
+
+#if !defined(NO_PWDBASED)
+int wolfSSL_EVP_get_hashinfo(const WOLFSSL_EVP_MD* evp,
+    int* pHash, int* pHashSz)
+{
+    enum wc_HashType hash = WC_HASH_TYPE_NONE;
+    int hashSz;
+
+    if (XSTRLEN(evp) < 3) {
+        /* do not try comparing strings if size is too small */
+        return WOLFSSL_FAILURE;
+    }
+
+    if (XSTRNCMP("SHA", evp, 3) == 0) {
+        if (XSTRLEN(evp) > 3) {
+        #ifndef NO_SHA256
+            if (XSTRNCMP("SHA256", evp, 6) == 0) {
+                hash = WC_HASH_TYPE_SHA256;
+            }
+            else
+        #endif
+        #ifdef WOLFSSL_SHA384
+            if (XSTRNCMP("SHA384", evp, 6) == 0) {
+                hash = WC_HASH_TYPE_SHA384;
+            }
+            else
+        #endif
+        #ifdef WOLFSSL_SHA512
+            if (XSTRNCMP("SHA512", evp, 6) == 0) {
+                hash = WC_HASH_TYPE_SHA512;
+            }
+            else
+        #endif
+            {
+                WOLFSSL_MSG("Unknown SHA hash");
+            }
+        }
+        else {
+            hash = WC_HASH_TYPE_SHA;
+        }
+    }
+#ifdef WOLFSSL_MD2
+    else if (XSTRNCMP("MD2", evp, 3) == 0) {
+        hash = WC_HASH_TYPE_MD2;
+    }
+#endif
+#ifndef NO_MD4
+    else if (XSTRNCMP("MD4", evp, 3) == 0) {
+        hash = WC_HASH_TYPE_MD4;
+    }
+#endif
+#ifndef NO_MD5
+    else if (XSTRNCMP("MD5", evp, 3) == 0) {
+        hash = WC_HASH_TYPE_MD5;
+    }
+#endif
+
+    if (pHash)
+        *pHash = hash;
+
+    hashSz = wc_HashGetDigestSize(hash);
+    if (pHashSz)
+        *pHashSz = hashSz;
+
+    if (hashSz < 0) {
+        return WOLFSSL_FAILURE;
+    }
+
+    return WOLFSSL_SUCCESS;
+}
+
+/* this function makes the assumption that out buffer is big enough for digest*/
+int wolfSSL_EVP_Digest(const unsigned char* in, int inSz, unsigned char* out,
+                              unsigned int* outSz, const WOLFSSL_EVP_MD* evp,
+                              WOLFSSL_ENGINE* eng)
+{
+    int err;
+    int hashType = WC_HASH_TYPE_NONE;
+    int hashSz;
+
+    WOLFSSL_ENTER("wolfSSL_EVP_Digest");
+    if (in == NULL || out == NULL || evp == NULL) {
+        WOLFSSL_MSG("Null argument passed in");
+        return WOLFSSL_FAILURE;
+    }
+
+    err = wolfSSL_EVP_get_hashinfo(evp, &hashType, &hashSz);
+    if (err != WOLFSSL_SUCCESS)
+        return err;
+
+    if (wc_Hash((enum wc_HashType)hashType, in, inSz, out, hashSz) != 0) {
+        return WOLFSSL_FAILURE;
+    }
+
+    if (outSz != NULL)
+        *outSz = hashSz;
+
+    (void)eng;
+    return WOLFSSL_SUCCESS;
+}
+#endif
+
+const WOLFSSL_EVP_MD *wolfSSL_EVP_get_digestbyname(const char *name)
+{
+    static const struct alias {
+        const char *name;
+        const char *alias;
+    } alias_tbl[] =
+    {
+        {"MD4", "ssl3-md4"},
+        {"MD5", "ssl3-md5"},
+        {"SHA", "ssl3-sha1"},
+        {"SHA", "SHA1"},
+        { NULL, NULL}
+    };
+
+    const struct alias  *al;
+    const struct s_ent *ent;
+
+
+    for (al = alias_tbl; al->name != NULL; al++)
+        if(XSTRNCMP(name, al->alias, XSTRLEN(al->alias)+1) == 0) {
+            name = al->name;
+            break;
+        }
+
+    for (ent = md_tbl; ent->name != NULL; ent++)
+        if(XSTRNCMP(name, ent->name, XSTRLEN(ent->name)+1) == 0) {
+            return (EVP_MD *)ent->name;
+        }
+    return NULL;
+}
+
+int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD *md)
+{
+    const struct s_ent *ent ;
+    WOLFSSL_ENTER("EVP_MD_type");
+    for( ent = md_tbl; ent->name != NULL; ent++){
+        if(XSTRNCMP((const char *)md, ent->name, XSTRLEN(ent->name)+1) == 0) {
+            return ent->nid;
+        }
+    }
+    return 0;
+}
+
+#ifndef NO_MD4
+
+    /* return a pointer to MD4 EVP type */
+    const WOLFSSL_EVP_MD* wolfSSL_EVP_md4(void)
+    {
+        WOLFSSL_ENTER("wolfSSL_EVP_md4");
+        return EVP_get_digestbyname("MD4");
+    }
+
+#endif /* !NO_MD4 */
+
+
+#ifndef NO_MD5
+
+    const WOLFSSL_EVP_MD* wolfSSL_EVP_md5(void)
+    {
+        WOLFSSL_ENTER("EVP_md5");
+        return EVP_get_digestbyname("MD5");
+    }
+
+#endif /* !NO_MD5 */
+
+
+#ifndef NO_WOLFSSL_STUB
+    const WOLFSSL_EVP_MD* wolfSSL_EVP_mdc2(void)
+    {
+        WOLFSSL_STUB("EVP_mdc2");
+        return NULL;
+    }
+#endif
+
+#ifndef NO_SHA
+    const WOLFSSL_EVP_MD* wolfSSL_EVP_sha1(void)
+    {
+        WOLFSSL_ENTER("EVP_sha1");
+        return EVP_get_digestbyname("SHA");
+    }
+#endif /* NO_SHA */
+
+#ifdef WOLFSSL_SHA224
+
+    const WOLFSSL_EVP_MD* wolfSSL_EVP_sha224(void)
+    {
+        WOLFSSL_ENTER("EVP_sha224");
+        return EVP_get_digestbyname("SHA224");
+    }
+
+#endif /* WOLFSSL_SHA224 */
+
+
+    const WOLFSSL_EVP_MD* wolfSSL_EVP_sha256(void)
+    {
+        WOLFSSL_ENTER("EVP_sha256");
+        return EVP_get_digestbyname("SHA256");
+    }
+
+#ifdef WOLFSSL_SHA384
+
+    const WOLFSSL_EVP_MD* wolfSSL_EVP_sha384(void)
+    {
+        WOLFSSL_ENTER("EVP_sha384");
+        return EVP_get_digestbyname("SHA384");
+    }
+
+#endif /* WOLFSSL_SHA384 */
+
+#ifdef WOLFSSL_SHA512
+
+    const WOLFSSL_EVP_MD* wolfSSL_EVP_sha512(void)
+    {
+        WOLFSSL_ENTER("EVP_sha512");
+        return EVP_get_digestbyname("SHA512");
+    }
+
+#endif /* WOLFSSL_SHA512 */
+
+#ifdef WOLFSSL_SHA3
+#ifndef WOLFSSL_NOSHA3_224
+    const WOLFSSL_EVP_MD* wolfSSL_EVP_sha3_224(void)
+    {
+        WOLFSSL_ENTER("EVP_sha3_224");
+        return EVP_get_digestbyname("SHA3_224");
+    }
+#endif /* WOLFSSL_NOSHA3_224 */
+
+
+#ifndef WOLFSSL_NOSHA3_256
+    const WOLFSSL_EVP_MD* wolfSSL_EVP_sha3_256(void)
+    {
+        WOLFSSL_ENTER("EVP_sha3_256");
+        return EVP_get_digestbyname("SHA3_256");
+    }
+#endif /* WOLFSSL_NOSHA3_256 */
+
+    const WOLFSSL_EVP_MD* wolfSSL_EVP_sha3_384(void)
+    {
+        WOLFSSL_ENTER("EVP_sha3_384");
+        return EVP_get_digestbyname("SHA3_384");
+    }
+
+#ifndef WOLFSSL_NOSHA3_512
+    const WOLFSSL_EVP_MD* wolfSSL_EVP_sha3_512(void)
+    {
+        WOLFSSL_ENTER("EVP_sha3_512");
+        return EVP_get_digestbyname("SHA3_512");
+    }
+#endif /* WOLFSSL_NOSHA3_512 */
+#endif /* WOLFSSL_SHA3 */
+
+    WOLFSSL_EVP_MD_CTX *wolfSSL_EVP_MD_CTX_new(void)
+    {
+        WOLFSSL_EVP_MD_CTX* ctx;
+        WOLFSSL_ENTER("EVP_MD_CTX_new");
+        ctx = (WOLFSSL_EVP_MD_CTX*)XMALLOC(sizeof *ctx, NULL,
+                                                       DYNAMIC_TYPE_OPENSSL);
+        if (ctx){
+            wolfSSL_EVP_MD_CTX_init(ctx);
+        }
+        return ctx;
+    }
+
+    WOLFSSL_API void wolfSSL_EVP_MD_CTX_free(WOLFSSL_EVP_MD_CTX *ctx)
+    {
+        if (ctx) {
+            WOLFSSL_ENTER("EVP_MD_CTX_free");
+                wolfSSL_EVP_MD_CTX_cleanup(ctx);
+                XFREE(ctx, NULL, DYNAMIC_TYPE_OPENSSL);
+            }
+    }
+
+    /* returns the NID of message digest used by the ctx */
+    int wolfSSL_EVP_MD_CTX_type(const WOLFSSL_EVP_MD_CTX *ctx) {
+        const struct s_ent *ent;
+
+        WOLFSSL_ENTER("EVP_MD_CTX_type");
+
+        if (ctx) {
+            for(ent = md_tbl; ent->name != NULL; ent++) {
+                if (ctx->macType == ent->macType) {
+                    return ent->nid;
+                }
+            }
+            /* Return whatever we got */
+            return ctx->macType;
+        }
+        return 0;
+    }
+
+
+    /* returns WOLFSSL_SUCCESS on success */
+    int wolfSSL_EVP_MD_CTX_copy(WOLFSSL_EVP_MD_CTX *out, const WOLFSSL_EVP_MD_CTX *in)
+    {
+        return wolfSSL_EVP_MD_CTX_copy_ex(out, in);
+    }
+
+    /* returns digest size */
+    int wolfSSL_EVP_MD_CTX_size(const WOLFSSL_EVP_MD_CTX *ctx) {
+        return(wolfSSL_EVP_MD_size(wolfSSL_EVP_MD_CTX_md(ctx)));
+    }
+    /* returns block size */
+    int wolfSSL_EVP_MD_CTX_block_size(const WOLFSSL_EVP_MD_CTX *ctx) {
+        return(wolfSSL_EVP_MD_block_size(wolfSSL_EVP_MD_CTX_md(ctx)));
+    }
+
+    /* Deep copy of EVP_MD hasher
+     * return WOLFSSL_SUCCESS on success */
+    static int wolfSSL_EVP_MD_Copy_Hasher(WOLFSSL_EVP_MD_CTX* des,
+            const WOLFSSL_EVP_MD_CTX* src)
+    {
+        if (src->macType == NID_hmac) {
+            wolfSSL_HmacCopy(&des->hash.hmac, (Hmac*)&src->hash.hmac);
+        }
+        else {
+            switch (src->macType) {
+            #ifndef NO_MD5
+                case WC_HASH_TYPE_MD5:
+                    wc_Md5Copy((wc_Md5*)&src->hash.digest,
+                            (wc_Md5*)&des->hash.digest);
+                    break;
+            #endif /* !NO_MD5 */
+
+            #ifndef NO_SHA
+                case WC_HASH_TYPE_SHA:
+                    wc_ShaCopy((wc_Sha*)&src->hash.digest,
+                            (wc_Sha*)&des->hash.digest);
+                    break;
+            #endif /* !NO_SHA */
+
+            #ifdef WOLFSSL_SHA224
+                case WC_HASH_TYPE_SHA224:
+                    wc_Sha224Copy((wc_Sha224*)&src->hash.digest,
+                            (wc_Sha224*)&des->hash.digest);
+                    break;
+            #endif /* WOLFSSL_SHA224 */
+
+            #ifndef NO_SHA256
+                case WC_HASH_TYPE_SHA256:
+                    wc_Sha256Copy((wc_Sha256*)&src->hash.digest,
+                            (wc_Sha256*)&des->hash.digest);
+                    break;
+            #endif /* !NO_SHA256 */
+
+            #ifdef WOLFSSL_SHA384
+                case WC_HASH_TYPE_SHA384:
+                    wc_Sha384Copy((wc_Sha384*)&src->hash.digest,
+                            (wc_Sha384*)&des->hash.digest);
+                    break;
+            #endif /* WOLFSSL_SHA384 */
+            #ifdef WOLFSSL_SHA512
+                case WC_HASH_TYPE_SHA512:
+                    wc_Sha512Copy((wc_Sha512*)&src->hash.digest,
+                        (wc_Sha512*)&des->hash.digest);
+                    break;
+            #endif /* WOLFSSL_SHA512 */
+        #ifdef WOLFSSL_SHA3
+            #ifndef WOLFSSL_NOSHA3_224
+                case WC_HASH_TYPE_SHA3_224:
+                    wc_Sha3_224_Copy((wc_Sha3*)&src->hash.digest,
+                            (wc_Sha3*)&des->hash.digest);
+                    break;
+            #endif
+
+            #ifndef WOLFSSL_NOSHA3_256
+                case WC_HASH_TYPE_SHA3_256:
+                    wc_Sha3_256_Copy((wc_Sha3*)&src->hash.digest,
+                            (wc_Sha3*)&des->hash.digest);
+                    break;
+            #endif
+
+                case WC_HASH_TYPE_SHA3_384:
+                    wc_Sha3_384_Copy((wc_Sha3*)&src->hash.digest,
+                            (wc_Sha3*)&des->hash.digest);
+                    break;
+
+            #ifndef WOLFSSL_NOSHA3_512
+                case WC_HASH_TYPE_SHA3_512:
+                    wc_Sha3_512_Copy((wc_Sha3*)&src->hash.digest,
+                        (wc_Sha3*)&des->hash.digest);
+                    break;
+            #endif
+        #endif
+                default:
+                    return WOLFSSL_FAILURE;
+            }
+        }
+        return WOLFSSL_SUCCESS;
+    }
+
+    /* copies structure in to the structure out
+     *
+     * returns WOLFSSL_SUCCESS on success */
+    int wolfSSL_EVP_MD_CTX_copy_ex(WOLFSSL_EVP_MD_CTX *out, const WOLFSSL_EVP_MD_CTX *in)
+    {
+        if ((out == NULL) || (in == NULL)) return WOLFSSL_FAILURE;
+        WOLFSSL_ENTER("EVP_CIPHER_MD_CTX_copy_ex");
+        XMEMCPY(out, in, sizeof(WOLFSSL_EVP_MD_CTX));
+        if (in->pctx != NULL) {
+            out->pctx = wolfSSL_EVP_PKEY_CTX_new(in->pctx->pkey, NULL);
+            if (out->pctx == NULL)
+                return WOLFSSL_FAILURE;
+        }
+        return wolfSSL_EVP_MD_Copy_Hasher(out, (WOLFSSL_EVP_MD_CTX*)in);
+    }
+
+    void wolfSSL_EVP_MD_CTX_init(WOLFSSL_EVP_MD_CTX* ctx)
+    {
+        WOLFSSL_ENTER("EVP_CIPHER_MD_CTX_init");
+        XMEMSET(ctx, 0, sizeof(WOLFSSL_EVP_MD_CTX));
+    }
+
+    const WOLFSSL_EVP_MD *wolfSSL_EVP_MD_CTX_md(const WOLFSSL_EVP_MD_CTX *ctx)
+    {
+        const struct s_ent *ent;
+        if (ctx == NULL)
+            return NULL;
+        WOLFSSL_ENTER("EVP_MD_CTX_md");
+        for(ent = md_tbl; ent->name != NULL; ent++) {
+            if(ctx->macType == ent->macType) {
+                return (const WOLFSSL_EVP_MD *)ent->name;
+            }
+        }
+        return (WOLFSSL_EVP_MD *)NULL;
+    }
+
+    #ifndef NO_AES
+
+    #ifdef HAVE_AES_CBC
+    #ifdef WOLFSSL_AES_128
+    const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_aes_128_cbc(void)
+    {
+        WOLFSSL_ENTER("wolfSSL_EVP_aes_128_cbc");
+        if (EVP_AES_128_CBC == NULL)
+            wolfSSL_EVP_init();
+        return EVP_AES_128_CBC;
+    }
+    #endif /* WOLFSSL_AES_128 */
+
+
+    #ifdef WOLFSSL_AES_192
+    const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_aes_192_cbc(void)
+    {
+        WOLFSSL_ENTER("wolfSSL_EVP_aes_192_cbc");
+        if (EVP_AES_192_CBC == NULL)
+            wolfSSL_EVP_init();
+        return EVP_AES_192_CBC;
+    }
+    #endif /* WOLFSSL_AES_192 */
+
+
+    #ifdef WOLFSSL_AES_256
+    const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_aes_256_cbc(void)
+    {
+        WOLFSSL_ENTER("wolfSSL_EVP_aes_256_cbc");
+        if (EVP_AES_256_CBC == NULL)
+            wolfSSL_EVP_init();
+        return EVP_AES_256_CBC;
+    }
+    #endif /* WOLFSSL_AES_256 */
+    #endif /* HAVE_AES_CBC */
+
+    #ifdef WOLFSSL_AES_CFB
+#if !defined(HAVE_SELFTEST) && !defined(HAVE_FIPS)
+    #ifdef WOLFSSL_AES_128
+    const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_aes_128_cfb1(void)
+    {
+        WOLFSSL_ENTER("wolfSSL_EVP_aes_128_cfb1");
+        if (EVP_AES_128_CFB1 == NULL)
+            wolfSSL_EVP_init();
+        return EVP_AES_128_CFB1;
+    }
+    #endif /* WOLFSSL_AES_128 */
+
+    #ifdef WOLFSSL_AES_192
+    const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_aes_192_cfb1(void)
+    {
+        WOLFSSL_ENTER("wolfSSL_EVP_aes_192_cfb1");
+        if (EVP_AES_192_CFB1 == NULL)
+            wolfSSL_EVP_init();
+        return EVP_AES_192_CFB1;
+    }
+    #endif /* WOLFSSL_AES_192 */
+
+    #ifdef WOLFSSL_AES_256
+    const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_aes_256_cfb1(void)
+    {
+        WOLFSSL_ENTER("wolfSSL_EVP_aes_256_cfb1");
+        if (EVP_AES_256_CFB1 == NULL)
+            wolfSSL_EVP_init();
+        return EVP_AES_256_CFB1;
+    }
+    #endif /* WOLFSSL_AES_256 */
+
+    #ifdef WOLFSSL_AES_128
+    const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_aes_128_cfb8(void)
+    {
+        WOLFSSL_ENTER("wolfSSL_EVP_aes_128_cfb8");
+        if (EVP_AES_128_CFB8 == NULL)
+            wolfSSL_EVP_init();
+        return EVP_AES_128_CFB8;
+    }
+    #endif /* WOLFSSL_AES_128 */
+
+    #ifdef WOLFSSL_AES_192
+    const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_aes_192_cfb8(void)
+    {
+        WOLFSSL_ENTER("wolfSSL_EVP_aes_192_cfb8");
+        if (EVP_AES_192_CFB8 == NULL)
+            wolfSSL_EVP_init();
+        return EVP_AES_192_CFB8;
+    }
+    #endif /* WOLFSSL_AES_192 */
+
+    #ifdef WOLFSSL_AES_256
+    const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_aes_256_cfb8(void)
+    {
+        WOLFSSL_ENTER("wolfSSL_EVP_aes_256_cfb8");
+        if (EVP_AES_256_CFB8 == NULL)
+            wolfSSL_EVP_init();
+        return EVP_AES_256_CFB8;
+    }
+    #endif /* WOLFSSL_AES_256 */
+#endif /* !HAVE_SELFTEST && !HAVE_FIPS */
+
+    #ifdef WOLFSSL_AES_128
+    const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_aes_128_cfb128(void)
+    {
+        WOLFSSL_ENTER("wolfSSL_EVP_aes_128_cfb128");
+        if (EVP_AES_128_CFB128 == NULL)
+            wolfSSL_EVP_init();
+        return EVP_AES_128_CFB128;
+    }
+    #endif /* WOLFSSL_AES_128 */
+
+    #ifdef WOLFSSL_AES_192
+    const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_aes_192_cfb128(void)
+    {
+        WOLFSSL_ENTER("wolfSSL_EVP_aes_192_cfb128");
+        if (EVP_AES_192_CFB128 == NULL)
+            wolfSSL_EVP_init();
+        return EVP_AES_192_CFB128;
+    }
+    #endif /* WOLFSSL_AES_192 */
+
+    #ifdef WOLFSSL_AES_256
+    const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_aes_256_cfb128(void)
+    {
+        WOLFSSL_ENTER("wolfSSL_EVP_aes_256_cfb128");
+        if (EVP_AES_256_CFB128 == NULL)
+            wolfSSL_EVP_init();
+        return EVP_AES_256_CFB128;
+    }
+    #endif /* WOLFSSL_AES_256 */
+    #endif /* WOLFSSL_AES_CFB */
+
+    #ifdef WOLFSSL_AES_OFB
+    #ifdef WOLFSSL_AES_128
+    const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_aes_128_ofb(void)
+    {
+        WOLFSSL_ENTER("wolfSSL_EVP_aes_128_ofb");
+        if (EVP_AES_128_OFB == NULL)
+            wolfSSL_EVP_init();
+        return EVP_AES_128_OFB;
+    }
+    #endif /* WOLFSSL_AES_128 */
+
+    #ifdef WOLFSSL_AES_192
+    const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_aes_192_ofb(void)
+    {
+        WOLFSSL_ENTER("wolfSSL_EVP_aes_192_ofb");
+        if (EVP_AES_192_OFB == NULL)
+            wolfSSL_EVP_init();
+        return EVP_AES_192_OFB;
+    }
+    #endif /* WOLFSSL_AES_192 */
+
+    #ifdef WOLFSSL_AES_256
+    const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_aes_256_ofb(void)
+    {
+        WOLFSSL_ENTER("wolfSSL_EVP_aes_256_ofb");
+        if (EVP_AES_256_OFB == NULL)
+            wolfSSL_EVP_init();
+        return EVP_AES_256_OFB;
+    }
+    #endif /* WOLFSSL_AES_256 */
+    #endif /* WOLFSSL_AES_OFB */
+
+    #ifdef WOLFSSL_AES_XTS
+    #ifdef WOLFSSL_AES_128
+    const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_aes_128_xts(void)
+    {
+        WOLFSSL_ENTER("wolfSSL_EVP_aes_128_xts");
+        if (EVP_AES_128_XTS == NULL)
+            wolfSSL_EVP_init();
+        return EVP_AES_128_XTS;
+    }
+    #endif /* WOLFSSL_AES_128 */
+
+    #ifdef WOLFSSL_AES_256
+    const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_aes_256_xts(void)
+    {
+        WOLFSSL_ENTER("wolfSSL_EVP_aes_256_xts");
+        if (EVP_AES_256_XTS == NULL)
+            wolfSSL_EVP_init();
+        return EVP_AES_256_XTS;
+    }
+    #endif /* WOLFSSL_AES_256 */
+    #endif /* WOLFSSL_AES_XTS */
+
+    #ifdef HAVE_AESGCM
+    #ifdef WOLFSSL_AES_128
+    const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_aes_128_gcm(void)
+    {
+        WOLFSSL_ENTER("wolfSSL_EVP_aes_128_gcm");
+        if (EVP_AES_128_GCM == NULL)
+            wolfSSL_EVP_init();
+        return EVP_AES_128_GCM;
+    }
+    #endif /* WOLFSSL_GCM_128 */
+
+    #ifdef WOLFSSL_AES_192
+    const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_aes_192_gcm(void)
+    {
+        WOLFSSL_ENTER("wolfSSL_EVP_aes_192_gcm");
+        if (EVP_AES_192_GCM == NULL)
+            wolfSSL_EVP_init();
+        return EVP_AES_192_GCM;
+    }
+    #endif /* WOLFSSL_AES_192 */
+
+    #ifdef WOLFSSL_AES_256
+    const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_aes_256_gcm(void)
+    {
+        WOLFSSL_ENTER("wolfSSL_EVP_aes_256_gcm");
+        if (EVP_AES_256_GCM == NULL)
+            wolfSSL_EVP_init();
+        return EVP_AES_256_GCM;
+    }
+    #endif /* WOLFSSL_AES_256 */
+    #endif /* HAVE_AESGCM */
+
+    #ifdef WOLFSSL_AES_128
+    const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_aes_128_ctr(void)
+    {
+        WOLFSSL_ENTER("wolfSSL_EVP_aes_128_ctr");
+        if (EVP_AES_128_CTR == NULL)
+            wolfSSL_EVP_init();
+        return EVP_AES_128_CTR;
+    }
+    #endif /* WOLFSSL_AES_2128 */
+
+
+    #ifdef WOLFSSL_AES_192
+    const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_aes_192_ctr(void)
+    {
+        WOLFSSL_ENTER("wolfSSL_EVP_aes_192_ctr");
+        if (EVP_AES_192_CTR == NULL)
+            wolfSSL_EVP_init();
+        return EVP_AES_192_CTR;
+    }
+    #endif /* WOLFSSL_AES_192 */
+
+
+    #ifdef WOLFSSL_AES_256
+    const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_aes_256_ctr(void)
+    {
+        WOLFSSL_ENTER("wolfSSL_EVP_aes_256_ctr");
+        if (EVP_AES_256_CTR == NULL)
+            wolfSSL_EVP_init();
+        return EVP_AES_256_CTR;
+    }
+    #endif /* WOLFSSL_AES_256 */
+
+    #ifdef WOLFSSL_AES_128
+    const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_aes_128_ecb(void)
+    {
+        WOLFSSL_ENTER("wolfSSL_EVP_aes_128_ecb");
+        if (EVP_AES_128_ECB == NULL)
+            wolfSSL_EVP_init();
+        return EVP_AES_128_ECB;
+    }
+    #endif /* WOLFSSL_AES_128 */
+
+
+    #ifdef WOLFSSL_AES_192
+    const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_aes_192_ecb(void)
+    {
+        WOLFSSL_ENTER("wolfSSL_EVP_aes_192_ecb");
+        if (EVP_AES_192_ECB == NULL)
+            wolfSSL_EVP_init();
+        return EVP_AES_192_ECB;
+    }
+    #endif /* WOLFSSL_AES_192*/
+
+
+    #ifdef WOLFSSL_AES_256
+    const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_aes_256_ecb(void)
+    {
+        WOLFSSL_ENTER("wolfSSL_EVP_aes_256_ecb");
+        if (EVP_AES_256_ECB == NULL)
+            wolfSSL_EVP_init();
+        return EVP_AES_256_ECB;
+    }
+    #endif /* WOLFSSL_AES_256 */
+    #endif /* NO_AES */
+
+#ifndef NO_DES3
+    const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_des_cbc(void)
+    {
+        WOLFSSL_ENTER("wolfSSL_EVP_des_cbc");
+        if (EVP_DES_CBC == NULL)
+            wolfSSL_EVP_init();
+        return EVP_DES_CBC;
+    }
+#ifdef WOLFSSL_DES_ECB
+    const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_des_ecb(void)
+    {
+        WOLFSSL_ENTER("wolfSSL_EVP_des_ecb");
+        if (EVP_DES_ECB == NULL)
+            wolfSSL_EVP_init();
+        return EVP_DES_ECB;
+    }
+#endif
+    const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_des_ede3_cbc(void)
+    {
+        WOLFSSL_ENTER("wolfSSL_EVP_des_ede3_cbc");
+        if (EVP_DES_EDE3_CBC == NULL)
+            wolfSSL_EVP_init();
+        return EVP_DES_EDE3_CBC;
+    }
+#ifdef WOLFSSL_DES_ECB
+    const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_des_ede3_ecb(void)
+    {
+        WOLFSSL_ENTER("wolfSSL_EVP_des_ede3_ecb");
+        if (EVP_DES_EDE3_ECB == NULL)
+            wolfSSL_EVP_init();
+        return EVP_DES_EDE3_ECB;
+    }
+#endif
+#endif /* NO_DES3 */
+
+#ifndef NO_RC4
+    const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_rc4(void)
+    {
+        static const char* type = "ARC4";
+        WOLFSSL_ENTER("wolfSSL_EVP_rc4");
+        return type;
+    }
+#endif
+
+#ifdef HAVE_IDEA
+    const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_idea_cbc(void)
+    {
+        WOLFSSL_ENTER("wolfSSL_EVP_idea_cbc");
+        if (EVP_IDEA_CBC == NULL)
+            wolfSSL_EVP_init();
+        return EVP_IDEA_CBC;
+    }
+#endif
+    const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_enc_null(void)
+    {
+        static const char* type = "NULL";
+        WOLFSSL_ENTER("wolfSSL_EVP_enc_null");
+        return type;
+    }
+
+    int wolfSSL_EVP_MD_CTX_cleanup(WOLFSSL_EVP_MD_CTX* ctx)
+    {
+        WOLFSSL_ENTER("EVP_MD_CTX_cleanup");
+        if (ctx->pctx != NULL)
+            wolfSSL_EVP_PKEY_CTX_free(ctx->pctx);
+
+        if (ctx->macType == NID_hmac) {
+            wc_HmacFree(&ctx->hash.hmac);
+        }
+        else {
+            switch (ctx->macType) {
+            #ifndef NO_MD5
+                case WC_HASH_TYPE_MD5:
+                    wc_Md5Free((wc_Md5*)&ctx->hash.digest);
+                    break;
+            #endif /* !NO_MD5 */
+
+            #ifndef NO_SHA
+                case WC_HASH_TYPE_SHA:
+                    wc_ShaFree((wc_Sha*)&ctx->hash.digest);
+                    break;
+            #endif /* !NO_SHA */
+
+            #ifdef WOLFSSL_SHA224
+                case WC_HASH_TYPE_SHA224:
+                    wc_Sha224Free((wc_Sha224*)&ctx->hash.digest);
+                    break;
+            #endif /* WOLFSSL_SHA224 */
+
+            #ifndef NO_SHA256
+                case WC_HASH_TYPE_SHA256:
+                    wc_Sha256Free((wc_Sha256*)&ctx->hash.digest);
+                    break;
+            #endif /* !NO_SHA256 */
+
+            #ifdef WOLFSSL_SHA384
+                case WC_HASH_TYPE_SHA384:
+                    wc_Sha384Free((wc_Sha384*)&ctx->hash.digest);
+                    break;
+            #endif /* WOLFSSL_SHA384 */
+            #ifdef WOLFSSL_SHA512
+                case WC_HASH_TYPE_SHA512:
+                    wc_Sha512Free((wc_Sha512*)&ctx->hash.digest);
+                    break;
+            #endif /* WOLFSSL_SHA512 */
+        #ifdef WOLFSSL_SHA3
+            #ifndef WOLFSSL_NOSHA3_224
+                case WC_HASH_TYPE_SHA3_224:
+                    wc_Sha3_224_Free((wc_Sha3*)&ctx->hash.digest);
+                    break;
+            #endif
+
+            #ifndef WOLFSSL_NOSHA3_256
+                case WC_HASH_TYPE_SHA3_256:
+                    wc_Sha3_256_Free((wc_Sha3*)&ctx->hash.digest);
+                    break;
+            #endif
+
+                case WC_HASH_TYPE_SHA3_384:
+                    wc_Sha3_384_Free((wc_Sha3*)&ctx->hash.digest);
+                    break;
+
+            #ifndef WOLFSSL_NOSHA3_512
+                case WC_HASH_TYPE_SHA3_512:
+                    wc_Sha3_512_Free((wc_Sha3*)&ctx->hash.digest);
+                    break;
+            #endif
+        #endif
+                default:
+                    return WOLFSSL_FAILURE;
+            }
+        }
+        ForceZero(ctx, sizeof(*ctx));
+        ctx->macType = WC_HASH_TYPE_NONE;
+        return 1;
+    }
+
+    void wolfSSL_EVP_CIPHER_CTX_init(WOLFSSL_EVP_CIPHER_CTX* ctx)
+    {
+        WOLFSSL_ENTER("EVP_CIPHER_CTX_init");
+        if (ctx) {
+            XMEMSET(ctx, 0, sizeof(WOLFSSL_EVP_CIPHER_CTX));
+            ctx->cipherType = WOLFSSL_EVP_CIPH_TYPE_INIT;   /* not yet initialized */
+            ctx->keyLen     = 0;
+            ctx->enc        = 1;      /* start in encrypt mode */
+        }
+    }
+
+#if defined(HAVE_AESGCM) && !defined(HAVE_SELFTEST)
+    static WC_INLINE void IncCtr(byte* ctr, word32 ctrSz)
+    {
+        int i;
+        for (i = ctrSz-1; i >= 0; i--) {
+            if (++ctr[i])
+                break;
+        }
+    }
+#endif
+
+    /* This function allows cipher specific parameters to be
+    determined and set. */
+    int wolfSSL_EVP_CIPHER_CTX_ctrl(WOLFSSL_EVP_CIPHER_CTX *ctx, int type, \
+                                    int arg, void *ptr)
+    {
+        int ret = WOLFSSL_FAILURE;
+#if defined(HAVE_AESGCM) && !defined(HAVE_SELFTEST) && !defined(WC_NO_RNG)
+        WC_RNG rng;
+#endif
+        if (ctx == NULL)
+            return WOLFSSL_FAILURE;
+
+        (void)arg;
+        (void)ptr;
+
+        WOLFSSL_ENTER("EVP_CIPHER_CTX_ctrl");
+
+        switch(type) {
+            case EVP_CTRL_INIT:
+                wolfSSL_EVP_CIPHER_CTX_init(ctx);
+                if(ctx)
+                    ret = WOLFSSL_SUCCESS;
+                break;
+            case EVP_CTRL_SET_KEY_LENGTH:
+                ret = wolfSSL_EVP_CIPHER_CTX_set_key_length(ctx, arg);
+                break;
+#if defined(HAVE_AESGCM) && !defined(HAVE_SELFTEST) && !defined(WC_NO_RNG)
+            case EVP_CTRL_GCM_SET_IVLEN:
+                if(arg <= 0 || arg > 16)
+                    return WOLFSSL_FAILURE;
+                ret = wolfSSL_EVP_CIPHER_CTX_set_iv_length(ctx, arg);
+                break;
+            case EVP_CTRL_AEAD_SET_IV_FIXED:
+                if (arg == -1) {
+                    /* arg == -1 copies ctx->ivSz from ptr */
+                    ret = wolfSSL_EVP_CIPHER_CTX_set_iv(ctx, (byte*)ptr, ctx->ivSz);
+                }
+                else {
+                    /*
+                     * Fixed field must be at least 4 bytes and invocation
+                     * field at least 8.
+                     */
+                    if ((arg < 4) || (ctx->ivSz - arg) < 8) {
+                        WOLFSSL_MSG("Fixed field or invocation field too short");
+                        ret = WOLFSSL_FAILURE;
+                        break;
+                    }
+                    if (wc_InitRng(&rng) != 0) {
+                        WOLFSSL_MSG("wc_InitRng failed");
+                        ret = WOLFSSL_FAILURE;
+                        break;
+                    }
+                    if (arg) {
+                        XMEMCPY(ctx->iv, ptr, arg);
+                    }
+                    if (wc_RNG_GenerateBlock(&rng, ctx->iv   + arg,
+                                                   ctx->ivSz - arg) != 0) {
+                        /* rng is freed immediately after if block so no need
+                         * to do it here
+                         */
+                        WOLFSSL_MSG("wc_RNG_GenerateBlock failed");
+                        ret = WOLFSSL_FAILURE;
+                    }
+
+                    if (wc_FreeRng(&rng) != 0) {
+                        WOLFSSL_MSG("wc_FreeRng failed");
+                        ret = WOLFSSL_FAILURE;
+                        break;
+                    }
+                }
+                break;
+#if !defined(_WIN32) && !defined(HAVE_FIPS)
+            case EVP_CTRL_GCM_IV_GEN:
+                if (ctx->cipher.aes.keylen == 0 || ctx->ivSz == 0) {
+                    ret = WOLFSSL_FAILURE;
+                    WOLFSSL_MSG("Key or IV not set");
+                    break;
+                }
+                if ((ret = wc_AesGcmSetExtIV(&ctx->cipher.aes, ctx->iv, ctx->ivSz)) != 0) {
+                    WOLFSSL_MSG("wc_AesGcmSetIV failed");
+                    ret = WOLFSSL_FAILURE;
+                }
+                /* OpenSSL increments the IV. Not sure why */
+                IncCtr(ctx->iv, ctx->ivSz);
+                break;
+#endif
+            case EVP_CTRL_AEAD_SET_TAG:
+                if(arg <= 0 || arg > 16 || (ptr == NULL))
+                    return WOLFSSL_FAILURE;
+
+                XMEMCPY(ctx->authTag, ptr, arg);
+                ctx->authTagSz = arg;
+                ret = WOLFSSL_SUCCESS;
+
+                break;
+            case EVP_CTRL_AEAD_GET_TAG:
+                if(arg <= 0 || arg > 16)
+                    return WOLFSSL_FAILURE;
+
+                XMEMCPY(ptr, ctx->authTag, arg);
+                ret = WOLFSSL_SUCCESS;
+                break;
+#endif /* HAVE_AESGCM && !HAVE_SELFTEST && !WC_NO_RNG */
+            default:
+                WOLFSSL_MSG("EVP_CIPHER_CTX_ctrl operation not yet handled");
+                ret = WOLFSSL_FAILURE;
+        }
+        return ret;
+    }
+
+    /* WOLFSSL_SUCCESS on ok */
+    int wolfSSL_EVP_CIPHER_CTX_cleanup(WOLFSSL_EVP_CIPHER_CTX* ctx)
+    {
+        WOLFSSL_ENTER("EVP_CIPHER_CTX_cleanup");
+        if (ctx) {
+            ctx->cipherType = WOLFSSL_EVP_CIPH_TYPE_INIT;  /* not yet initialized  */
+            ctx->keyLen     = 0;
+        }
+
+        return WOLFSSL_SUCCESS;
+    }
+
+    /* Permanent stub for Qt compilation. */
+    #if defined(WOLFSSL_QT) && !defined(NO_WOLFSSL_STUB)
+    const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_rc2_cbc(void)
+    {
+        WOLFSSL_ENTER("wolfSSL_EVP_rc2_cbc");
+        WOLFSSL_STUB("EVP_rc2_cbc");
+        return NULL;
+    }
+    #endif
+
+#if defined(WOLFSSL_ENCRYPTED_KEYS) && !defined(NO_PWDBASED)
+
+    int wolfSSL_EVP_BytesToKey(const WOLFSSL_EVP_CIPHER* type,
+                       const WOLFSSL_EVP_MD* md, const byte* salt,
+                       const byte* data, int sz, int count, byte* key, byte* iv)
+    {
+        int ret;
+        int hashType = WC_HASH_TYPE_NONE;
+    #ifdef WOLFSSL_SMALL_STACK
+        EncryptedInfo* info;
+    #else
+        EncryptedInfo  info[1];
+    #endif
+
+    #ifdef WOLFSSL_SMALL_STACK
+        info = (EncryptedInfo*)XMALLOC(sizeof(EncryptedInfo), NULL,
+                                       DYNAMIC_TYPE_ENCRYPTEDINFO);
+        if (info == NULL) {
+            WOLFSSL_MSG("malloc failed");
+            return WOLFSSL_FAILURE;
+        }
+    #endif
+
+        XMEMSET(info, 0, sizeof(EncryptedInfo));
+
+        ret = wc_EncryptedInfoGet(info, type);
+        if (ret < 0)
+            goto end;
+
+        if (data == NULL) {
+            ret = info->keySz;
+            goto end;
+        }
+
+        ret = wolfSSL_EVP_get_hashinfo(md, &hashType, NULL);
+        if (ret == WOLFSSL_FAILURE)
+            goto end;
+
+        ret = wc_PBKDF1_ex(key, info->keySz, iv, info->ivSz, data, sz, salt,
+                           EVP_SALT_SIZE, count, hashType, NULL);
+        if (ret == 0)
+            ret = info->keySz;
+
+    end:
+    #ifdef WOLFSSL_SMALL_STACK
+        XFREE(info, NULL, DYNAMIC_TYPE_ENCRYPTEDINFO);
+    #endif
+        if (ret < 0)
+            return 0; /* failure - for compatibility */
+
+        return ret;
+    }
+
+#endif /* WOLFSSL_ENCRYPTED_KEYS && !NO_PWDBASED */
+
+#ifndef NO_AES
+    static int   AesSetKey_ex(Aes* aes, const byte* key, word32 len,
+                              const byte* iv, int dir, int direct)
+    {
+        int ret;
+        /* wc_AesSetKey clear aes.reg if iv == NULL.
+           Keep IV for openSSL compatibility */
+        if (iv == NULL)
+            XMEMCPY((byte *)aes->tmp, (byte *)aes->reg, AES_BLOCK_SIZE);
+        if (direct) {
+        #if defined(WOLFSSL_AES_DIRECT)
+            ret = wc_AesSetKeyDirect(aes, key, len, iv, dir);
+        #else
+            ret = NOT_COMPILED_IN;
+        #endif
+        }
+        else {
+            ret = wc_AesSetKey(aes, key, len, iv, dir);
+        }
+        if (iv == NULL)
+            XMEMCPY((byte *)aes->reg, (byte *)aes->tmp, AES_BLOCK_SIZE);
+        return ret;
+    }
+#endif
+
+    /* return WOLFSSL_SUCCESS on ok, 0 on failure to match API compatibility */
+    int  wolfSSL_EVP_CipherInit(WOLFSSL_EVP_CIPHER_CTX* ctx,
+                               const WOLFSSL_EVP_CIPHER* type, const byte* key,
+                               const byte* iv, int enc)
+    {
+        int ret = 0;
+        (void)key;
+        (void)iv;
+        (void)enc;
+
+        WOLFSSL_ENTER("wolfSSL_EVP_CipherInit");
+        if (ctx == NULL) {
+            WOLFSSL_MSG("no ctx");
+            return WOLFSSL_FAILURE;
+        }
+
+        if (type == NULL && ctx->cipherType == WOLFSSL_EVP_CIPH_TYPE_INIT) {
+            WOLFSSL_MSG("no type set");
+            return WOLFSSL_FAILURE;
+        }
+        if (ctx->cipherType == WOLFSSL_EVP_CIPH_TYPE_INIT){
+            /* only first EVP_CipherInit invoke. ctx->cipherType is set below */
+            XMEMSET(&ctx->cipher, 0, sizeof(ctx->cipher));
+            ctx->flags   = 0;
+        }
+        /* always clear buffer state */
+        ctx->bufUsed = 0;
+        ctx->lastUsed = 0;
+
+#ifdef HAVE_WOLFSSL_EVP_CIPHER_CTX_IV
+        if (!iv && ctx->ivSz) {
+            iv = ctx->iv;
+        }
+#endif
+
+#ifndef NO_AES
+    #ifdef HAVE_AES_CBC
+        #ifdef WOLFSSL_AES_128
+        if (ctx->cipherType == AES_128_CBC_TYPE ||
+            (type && XSTRNCMP(type, EVP_AES_128_CBC, EVP_AES_SIZE) == 0)) {
+            WOLFSSL_MSG("EVP_AES_128_CBC");
+            ctx->cipherType = AES_128_CBC_TYPE;
+            ctx->flags     &= ~WOLFSSL_EVP_CIPH_MODE;
+            ctx->flags     |= WOLFSSL_EVP_CIPH_CBC_MODE;
+            ctx->keyLen     = 16;
+            ctx->block_size = AES_BLOCK_SIZE;
+            ctx->ivSz       = AES_BLOCK_SIZE;
+            if (enc == 0 || enc == 1)
+                ctx->enc = enc ? 1 : 0;
+            if (key) {
+                ret = AesSetKey_ex(&ctx->cipher.aes, key, ctx->keyLen, iv,
+                                ctx->enc ? AES_ENCRYPTION : AES_DECRYPTION, 0);
+                if (ret != 0)
+                    return WOLFSSL_FAILURE;
+            }
+            if (iv && key == NULL) {
+                ret = wc_AesSetIV(&ctx->cipher.aes, iv);
+                if (ret != 0)
+                    return WOLFSSL_FAILURE;
+            }
+        }
+        #endif /* WOLFSSL_AES_128 */
+        #ifdef WOLFSSL_AES_192
+        if (ctx->cipherType == AES_192_CBC_TYPE ||
+                 (type && XSTRNCMP(type, EVP_AES_192_CBC, EVP_AES_SIZE) == 0)) {
+            WOLFSSL_MSG("EVP_AES_192_CBC");
+            ctx->cipherType = AES_192_CBC_TYPE;
+            ctx->flags     &= ~WOLFSSL_EVP_CIPH_MODE;
+            ctx->flags     |= WOLFSSL_EVP_CIPH_CBC_MODE;
+            ctx->keyLen     = 24;
+            ctx->block_size = AES_BLOCK_SIZE;
+            ctx->ivSz       = AES_BLOCK_SIZE;
+            if (enc == 0 || enc == 1)
+                ctx->enc = enc ? 1 : 0;
+            if (key) {
+                ret = AesSetKey_ex(&ctx->cipher.aes, key, ctx->keyLen, iv,
+                                ctx->enc ? AES_ENCRYPTION : AES_DECRYPTION, 0);
+                if (ret != 0)
+                    return WOLFSSL_FAILURE;
+            }
+            if (iv && key == NULL) {
+                ret = wc_AesSetIV(&ctx->cipher.aes, iv);
+                if (ret != 0)
+                    return WOLFSSL_FAILURE;
+            }
+        }
+        #endif /* WOLFSSL_AES_192 */
+        #ifdef WOLFSSL_AES_256
+        if (ctx->cipherType == AES_256_CBC_TYPE ||
+                 (type && XSTRNCMP(type, EVP_AES_256_CBC, EVP_AES_SIZE) == 0)) {
+            WOLFSSL_MSG("EVP_AES_256_CBC");
+            ctx->cipherType = AES_256_CBC_TYPE;
+            ctx->flags     &= ~WOLFSSL_EVP_CIPH_MODE;
+            ctx->flags     |= WOLFSSL_EVP_CIPH_CBC_MODE;
+            ctx->keyLen     = 32;
+            ctx->block_size = AES_BLOCK_SIZE;
+            ctx->ivSz       = AES_BLOCK_SIZE;
+            if (enc == 0 || enc == 1)
+                ctx->enc = enc ? 1 : 0;
+            if (key) {
+                ret = AesSetKey_ex(&ctx->cipher.aes, key, ctx->keyLen, iv,
+                                ctx->enc ? AES_ENCRYPTION : AES_DECRYPTION, 0);
+                if (ret != 0){
+                    WOLFSSL_MSG("AesSetKey() failed");
+                    return WOLFSSL_FAILURE;
+                }
+            }
+            if (iv && key == NULL) {
+                ret = wc_AesSetIV(&ctx->cipher.aes, iv);
+                if (ret != 0){
+                    WOLFSSL_MSG("wc_AesSetIV() failed");
+                    return WOLFSSL_FAILURE;
+                }
+            }
+        }
+        #endif /* WOLFSSL_AES_256 */
+    #endif /* HAVE_AES_CBC */
+#if !defined(_WIN32) && !defined(HAVE_FIPS) && !defined(HAVE_SELFTEST)
+    #ifdef HAVE_AESGCM
+        #ifdef WOLFSSL_AES_128
+        if (ctx->cipherType == AES_128_GCM_TYPE ||
+            (type && XSTRNCMP(type, EVP_AES_128_GCM, EVP_AES_SIZE) == 0)) {
+            WOLFSSL_MSG("EVP_AES_128_GCM");
+            ctx->cipherType = AES_128_GCM_TYPE;
+            ctx->flags     &= ~WOLFSSL_EVP_CIPH_MODE;
+            ctx->flags     |= WOLFSSL_EVP_CIPH_GCM_MODE;
+            ctx->keyLen     = 16;
+            ctx->block_size = AES_BLOCK_SIZE;
+            ctx->authTagSz  = AES_BLOCK_SIZE;
+            ctx->ivSz       = GCM_NONCE_MID_SZ;
+
+            XMEMSET(ctx->authTag, 0, ctx->authTagSz);
+            if (key && wc_AesGcmSetKey(&ctx->cipher.aes, key, ctx->keyLen)) {
+                WOLFSSL_MSG("wc_AesGcmSetKey() failed");
+                return WOLFSSL_FAILURE;
+            }
+            if (iv && wc_AesGcmSetExtIV(&ctx->cipher.aes, iv, GCM_NONCE_MID_SZ)) {
+                WOLFSSL_MSG("wc_AesGcmSetExtIV() failed");
+                return WOLFSSL_FAILURE;
+            }
+            if (enc == 0 || enc == 1)
+                ctx->enc = enc ? 1 : 0;
+        }
+        #endif /* WOLFSSL_AES_128 */
+        #ifdef WOLFSSL_AES_192
+        if (ctx->cipherType == AES_192_GCM_TYPE ||
+                 (type && XSTRNCMP(type, EVP_AES_192_GCM, EVP_AES_SIZE) == 0)) {
+            WOLFSSL_MSG("EVP_AES_192_GCM");
+            ctx->cipherType = AES_192_GCM_TYPE;
+            ctx->flags     &= ~WOLFSSL_EVP_CIPH_MODE;
+            ctx->flags     |= WOLFSSL_EVP_CIPH_GCM_MODE;
+            ctx->keyLen     = 24;
+            ctx->block_size = AES_BLOCK_SIZE;
+            ctx->authTagSz  = AES_BLOCK_SIZE;
+            ctx->ivSz       = GCM_NONCE_MID_SZ;
+
+            XMEMSET(ctx->authTag, 0, ctx->authTagSz);
+            if (key && wc_AesGcmSetKey(&ctx->cipher.aes, key, ctx->keyLen)) {
+                WOLFSSL_MSG("wc_AesGcmSetKey() failed");
+                return WOLFSSL_FAILURE;
+            }
+            if (iv && wc_AesGcmSetExtIV(&ctx->cipher.aes, iv, GCM_NONCE_MID_SZ)) {
+                WOLFSSL_MSG("wc_AesGcmSetExtIV() failed");
+                return WOLFSSL_FAILURE;
+            }
+            if (enc == 0 || enc == 1)
+                ctx->enc = enc ? 1 : 0;
+        }
+        #endif /* WOLFSSL_AES_192 */
+        #ifdef WOLFSSL_AES_256
+        if (ctx->cipherType == AES_256_GCM_TYPE ||
+                 (type && XSTRNCMP(type, EVP_AES_256_GCM, EVP_AES_SIZE) == 0)) {
+            WOLFSSL_MSG("EVP_AES_256_GCM");
+            ctx->cipherType = AES_256_GCM_TYPE;
+            ctx->flags     &= ~WOLFSSL_EVP_CIPH_MODE;
+            ctx->flags     |= WOLFSSL_EVP_CIPH_GCM_MODE;
+            ctx->keyLen     = 32;
+            ctx->block_size = AES_BLOCK_SIZE;
+            ctx->authTagSz  = AES_BLOCK_SIZE;
+            ctx->ivSz       = GCM_NONCE_MID_SZ;
+
+            XMEMSET(ctx->authTag, 0, ctx->authTagSz);
+            if (key && wc_AesGcmSetKey(&ctx->cipher.aes, key, ctx->keyLen)) {
+                WOLFSSL_MSG("wc_AesGcmSetKey() failed");
+                return WOLFSSL_FAILURE;
+            }
+            if (iv && wc_AesGcmSetExtIV(&ctx->cipher.aes, iv, GCM_NONCE_MID_SZ)) {
+                WOLFSSL_MSG("wc_AesGcmSetExtIV() failed");
+                return WOLFSSL_FAILURE;
+            }
+            if (enc == 0 || enc == 1)
+                ctx->enc = enc ? 1 : 0;
+        }
+        #endif /* WOLFSSL_AES_256 */
+    #endif /* HAVE_AESGCM */
+#endif /* !defined(_WIN32) && !defined(HAVE_FIPS) && !defined(HAVE_SELFTEST) */
+#ifdef WOLFSSL_AES_COUNTER
+        #ifdef WOLFSSL_AES_128
+        if (ctx->cipherType == AES_128_CTR_TYPE ||
+                 (type && XSTRNCMP(type, EVP_AES_128_CTR, EVP_AES_SIZE) == 0)) {
+            WOLFSSL_MSG("EVP_AES_128_CTR");
+            ctx->flags     &= ~WOLFSSL_EVP_CIPH_MODE;
+            ctx->cipherType = AES_128_CTR_TYPE;
+            ctx->flags     |= WOLFSSL_EVP_CIPH_CTR_MODE;
+            ctx->keyLen     = 16;
+            ctx->block_size = NO_PADDING_BLOCK_SIZE;
+            ctx->ivSz       = AES_BLOCK_SIZE;
+#if defined(WOLFSSL_AES_COUNTER) || defined(WOLFSSL_AES_CFB)
+            ctx->cipher.aes.left = 0;
+#endif
+            if (enc == 0 || enc == 1)
+                ctx->enc = enc ? 1 : 0;
+            if (key) {
+                ret =  AesSetKey_ex(&ctx->cipher.aes, key, ctx->keyLen, iv,
+                    AES_ENCRYPTION, 1);
+                if (ret != 0)
+                    return WOLFSSL_FAILURE;
+            }
+            if (iv && key == NULL) {
+                ret = wc_AesSetIV(&ctx->cipher.aes, iv);
+                if (ret != 0)
+                    return WOLFSSL_FAILURE;
+            }
+        }
+        #endif /* WOLFSSL_AES_128 */
+        #ifdef WOLFSSL_AES_192
+        if (ctx->cipherType == AES_192_CTR_TYPE ||
+                 (type && XSTRNCMP(type, EVP_AES_192_CTR, EVP_AES_SIZE) == 0)) {
+            WOLFSSL_MSG("EVP_AES_192_CTR");
+            ctx->cipherType = AES_192_CTR_TYPE;
+            ctx->flags     &= ~WOLFSSL_EVP_CIPH_MODE;
+            ctx->flags     |= WOLFSSL_EVP_CIPH_CTR_MODE;
+            ctx->keyLen     = 24;
+            ctx->block_size = NO_PADDING_BLOCK_SIZE;
+            ctx->ivSz       = AES_BLOCK_SIZE;
+#if defined(WOLFSSL_AES_COUNTER) || defined(WOLFSSL_AES_CFB)
+            ctx->cipher.aes.left = 0;
+#endif
+            if (enc == 0 || enc == 1)
+                ctx->enc = enc ? 1 : 0;
+            if (key) {
+                ret =  AesSetKey_ex(&ctx->cipher.aes, key, ctx->keyLen, iv,
+                      AES_ENCRYPTION, 1);
+                if (ret != 0)
+                    return WOLFSSL_FAILURE;
+            }
+            if (iv && key == NULL) {
+                ret = wc_AesSetIV(&ctx->cipher.aes, iv);
+                if (ret != 0)
+                    return WOLFSSL_FAILURE;
+            }
+        }
+        #endif /* WOLFSSL_AES_192 */
+        #ifdef WOLFSSL_AES_256
+        if (ctx->cipherType == AES_256_CTR_TYPE ||
+                 (type && XSTRNCMP(type, EVP_AES_256_CTR, EVP_AES_SIZE) == 0)) {
+            WOLFSSL_MSG("EVP_AES_256_CTR");
+            ctx->cipherType = AES_256_CTR_TYPE;
+            ctx->flags     &= ~WOLFSSL_EVP_CIPH_MODE;
+            ctx->flags     |= WOLFSSL_EVP_CIPH_CTR_MODE;
+            ctx->keyLen     = 32;
+            ctx->block_size = NO_PADDING_BLOCK_SIZE;
+            ctx->ivSz       = AES_BLOCK_SIZE;
+#if defined(WOLFSSL_AES_COUNTER) || defined(WOLFSSL_AES_CFB)
+            ctx->cipher.aes.left = 0;
+#endif
+            if (enc == 0 || enc == 1)
+                ctx->enc = enc ? 1 : 0;
+            if (key) {
+                ret =  AesSetKey_ex(&ctx->cipher.aes, key, ctx->keyLen, iv,
+                      AES_ENCRYPTION, 1);
+                if (ret != 0)
+                    return WOLFSSL_FAILURE;
+            }
+            if (iv && key == NULL) {
+                ret = wc_AesSetIV(&ctx->cipher.aes, iv);
+                if (ret != 0)
+                    return WOLFSSL_FAILURE;
+            }
+        }
+        #endif /* WOLFSSL_AES_256 */
+#endif /* WOLFSSL_AES_COUNTER */
+        #ifdef WOLFSSL_AES_128
+        if (ctx->cipherType == AES_128_ECB_TYPE ||
+            (type && XSTRNCMP(type, EVP_AES_128_ECB, EVP_AES_SIZE) == 0)) {
+            WOLFSSL_MSG("EVP_AES_128_ECB");
+            ctx->cipherType = AES_128_ECB_TYPE;
+            ctx->flags     &= ~WOLFSSL_EVP_CIPH_MODE;
+            ctx->flags     |= WOLFSSL_EVP_CIPH_ECB_MODE;
+            ctx->keyLen     = 16;
+            ctx->block_size = AES_BLOCK_SIZE;
+            if (enc == 0 || enc == 1)
+                ctx->enc = enc ? 1 : 0;
+            if (key) {
+                ret =  AesSetKey_ex(&ctx->cipher.aes, key, ctx->keyLen, NULL,
+                      ctx->enc ? AES_ENCRYPTION : AES_DECRYPTION, 1);
+            }
+            if (ret != 0)
+                return WOLFSSL_FAILURE;
+        }
+        #endif /* WOLFSSL_AES_128 */
+        #ifdef WOLFSSL_AES_192
+        if (ctx->cipherType == AES_192_ECB_TYPE ||
+                 (type && XSTRNCMP(type, EVP_AES_192_ECB, EVP_AES_SIZE) == 0)) {
+            WOLFSSL_MSG("EVP_AES_192_ECB");
+            ctx->cipherType = AES_192_ECB_TYPE;
+            ctx->flags     &= ~WOLFSSL_EVP_CIPH_MODE;
+            ctx->flags     |= WOLFSSL_EVP_CIPH_ECB_MODE;
+            ctx->keyLen     = 24;
+            ctx->block_size = AES_BLOCK_SIZE;
+            if (enc == 0 || enc == 1)
+                ctx->enc = enc ? 1 : 0;
+            if (key) {
+                ret =  AesSetKey_ex(&ctx->cipher.aes, key, ctx->keyLen, NULL,
+                      ctx->enc ? AES_ENCRYPTION : AES_DECRYPTION, 1);
+            }
+            if (ret != 0)
+                return WOLFSSL_FAILURE;
+        }
+        #endif /* WOLFSSL_AES_192 */
+        #ifdef WOLFSSL_AES_256
+        if (ctx->cipherType == AES_256_ECB_TYPE ||
+                 (type && XSTRNCMP(type, EVP_AES_256_ECB, EVP_AES_SIZE) == 0)) {
+            WOLFSSL_MSG("EVP_AES_256_ECB");
+            ctx->cipherType = AES_256_ECB_TYPE;
+            ctx->flags     &= ~WOLFSSL_EVP_CIPH_MODE;
+            ctx->flags     |= WOLFSSL_EVP_CIPH_ECB_MODE;
+            ctx->keyLen     = 32;
+            ctx->block_size = AES_BLOCK_SIZE;
+            if (enc == 0 || enc == 1)
+                ctx->enc = enc ? 1 : 0;
+            if (key) {
+                ret =  AesSetKey_ex(&ctx->cipher.aes, key, ctx->keyLen, NULL,
+                    ctx->enc ? AES_ENCRYPTION : AES_DECRYPTION, 1);
+            }
+            if (ret != 0)
+                return WOLFSSL_FAILURE;
+        }
+        #endif /* WOLFSSL_AES_256 */
+    #ifdef WOLFSSL_AES_CFB
+        #ifdef WOLFSSL_AES_128
+        if (ctx->cipherType == AES_128_CFB1_TYPE ||
+            (type && XSTRNCMP(type, EVP_AES_128_CFB1, EVP_AESCFB_SIZE) == 0)) {
+            WOLFSSL_MSG("EVP_AES_128_CFB1");
+            ctx->cipherType = AES_128_CFB1_TYPE;
+            ctx->flags     &= ~WOLFSSL_EVP_CIPH_MODE;
+            ctx->flags     |= WOLFSSL_EVP_CIPH_CFB_MODE;
+            ctx->keyLen     = 16;
+            ctx->block_size = 1;
+            if (enc == 0 || enc == 1)
+                ctx->enc = enc ? 1 : 0;
+            if (key) {
+                ret = AesSetKey_ex(&ctx->cipher.aes, key, ctx->keyLen, iv,
+                        AES_ENCRYPTION, 0);
+                if (ret != 0)
+                    return WOLFSSL_FAILURE;
+            }
+            if (iv && key == NULL) {
+                ret = wc_AesSetIV(&ctx->cipher.aes, iv);
+                if (ret != 0)
+                    return WOLFSSL_FAILURE;
+            }
+        }
+        #endif /* WOLFSSL_AES_128 */
+        #ifdef WOLFSSL_AES_192
+        if (ctx->cipherType == AES_192_CFB1_TYPE ||
+                 (type && XSTRNCMP(type, EVP_AES_192_CFB1, EVP_AESCFB_SIZE) == 0)) {
+            WOLFSSL_MSG("EVP_AES_192_CFB1");
+            ctx->cipherType = AES_192_CFB1_TYPE;
+            ctx->flags     &= ~WOLFSSL_EVP_CIPH_MODE;
+            ctx->flags     |= WOLFSSL_EVP_CIPH_CFB_MODE;
+            ctx->keyLen     = 24;
+            ctx->block_size = 1;
+            if (enc == 0 || enc == 1)
+                ctx->enc = enc ? 1 : 0;
+            if (key) {
+                ret = AesSetKey_ex(&ctx->cipher.aes, key, ctx->keyLen, iv,
+                            AES_ENCRYPTION, 0);
+                if (ret != 0)
+                    return WOLFSSL_FAILURE;
+            }
+            if (iv && key == NULL) {
+                ret = wc_AesSetIV(&ctx->cipher.aes, iv);
+                if (ret != 0)
+                    return WOLFSSL_FAILURE;
+            }
+        }
+        #endif /* WOLFSSL_AES_192 */
+        #ifdef WOLFSSL_AES_256
+        if (ctx->cipherType == AES_256_CFB1_TYPE ||
+                 (type && XSTRNCMP(type, EVP_AES_256_CFB1, EVP_AESCFB_SIZE) == 0)) {
+            WOLFSSL_MSG("EVP_AES_256_CFB1");
+            ctx->cipherType = AES_256_CFB1_TYPE;
+            ctx->flags     &= ~WOLFSSL_EVP_CIPH_MODE;
+            ctx->flags     |= WOLFSSL_EVP_CIPH_CFB_MODE;
+            ctx->keyLen     = 32;
+            ctx->block_size = 1;
+            if (enc == 0 || enc == 1)
+                ctx->enc = enc ? 1 : 0;
+            if (key) {
+                ret = AesSetKey_ex(&ctx->cipher.aes, key, ctx->keyLen, iv,
+                            AES_ENCRYPTION, 0);
+                if (ret != 0){
+                    WOLFSSL_MSG("AesSetKey() failed");
+                    return WOLFSSL_FAILURE;
+                }
+            }
+            if (iv && key == NULL) {
+                ret = wc_AesSetIV(&ctx->cipher.aes, iv);
+                if (ret != 0){
+                    WOLFSSL_MSG("wc_AesSetIV() failed");
+                    return WOLFSSL_FAILURE;
+                }
+            }
+        }
+        #endif /* WOLFSSL_AES_256 */
+        #ifdef WOLFSSL_AES_128
+        if (ctx->cipherType == AES_128_CFB8_TYPE ||
+            (type && XSTRNCMP(type, EVP_AES_128_CFB8, EVP_AESCFB_SIZE) == 0)) {
+            WOLFSSL_MSG("EVP_AES_128_CFB8");
+            ctx->cipherType = AES_128_CFB8_TYPE;
+            ctx->flags     &= ~WOLFSSL_EVP_CIPH_MODE;
+            ctx->flags     |= WOLFSSL_EVP_CIPH_CFB_MODE;
+            ctx->keyLen     = 16;
+            ctx->block_size = 1;
+            if (enc == 0 || enc == 1)
+                ctx->enc = enc ? 1 : 0;
+            if (key) {
+                ret = AesSetKey_ex(&ctx->cipher.aes, key, ctx->keyLen, iv,
+                        AES_ENCRYPTION, 0);
+                if (ret != 0)
+                    return WOLFSSL_FAILURE;
+            }
+            if (iv && key == NULL) {
+                ret = wc_AesSetIV(&ctx->cipher.aes, iv);
+                if (ret != 0)
+                    return WOLFSSL_FAILURE;
+            }
+        }
+        #endif /* WOLFSSL_AES_128 */
+        #ifdef WOLFSSL_AES_192
+        if (ctx->cipherType == AES_192_CFB8_TYPE ||
+                 (type && XSTRNCMP(type, EVP_AES_192_CFB8, EVP_AESCFB_SIZE) == 0)) {
+            WOLFSSL_MSG("EVP_AES_192_CFB8");
+            ctx->cipherType = AES_192_CFB8_TYPE;
+            ctx->flags     &= ~WOLFSSL_EVP_CIPH_MODE;
+            ctx->flags     |= WOLFSSL_EVP_CIPH_CFB_MODE;
+            ctx->keyLen     = 24;
+            ctx->block_size = 1;
+            if (enc == 0 || enc == 1)
+                ctx->enc = enc ? 1 : 0;
+            if (key) {
+                ret = AesSetKey_ex(&ctx->cipher.aes, key, ctx->keyLen, iv,
+                            AES_ENCRYPTION, 0);
+                if (ret != 0)
+                    return WOLFSSL_FAILURE;
+            }
+            if (iv && key == NULL) {
+                ret = wc_AesSetIV(&ctx->cipher.aes, iv);
+                if (ret != 0)
+                    return WOLFSSL_FAILURE;
+            }
+        }
+        #endif /* WOLFSSL_AES_192 */
+        #ifdef WOLFSSL_AES_256
+        if (ctx->cipherType == AES_256_CFB8_TYPE ||
+                 (type && XSTRNCMP(type, EVP_AES_256_CFB8, EVP_AESCFB_SIZE) == 0)) {
+            WOLFSSL_MSG("EVP_AES_256_CFB8");
+            ctx->cipherType = AES_256_CFB8_TYPE;
+            ctx->flags     &= ~WOLFSSL_EVP_CIPH_MODE;
+            ctx->flags     |= WOLFSSL_EVP_CIPH_CFB_MODE;
+            ctx->keyLen     = 32;
+            ctx->block_size = 1;
+            if (enc == 0 || enc == 1)
+                ctx->enc = enc ? 1 : 0;
+            if (key) {
+                ret = AesSetKey_ex(&ctx->cipher.aes, key, ctx->keyLen, iv,
+                            AES_ENCRYPTION, 0);
+                if (ret != 0){
+                    WOLFSSL_MSG("AesSetKey() failed");
+                    return WOLFSSL_FAILURE;
+                }
+            }
+            if (iv && key == NULL) {
+                ret = wc_AesSetIV(&ctx->cipher.aes, iv);
+                if (ret != 0){
+                    WOLFSSL_MSG("wc_AesSetIV() failed");
+                    return WOLFSSL_FAILURE;
+                }
+            }
+        }
+        #endif /* WOLFSSL_AES_256 */
+        #ifdef WOLFSSL_AES_128
+        if (ctx->cipherType == AES_128_CFB128_TYPE ||
+            (type && XSTRNCMP(type, EVP_AES_128_CFB128, EVP_AESCFB_SIZE) == 0)) {
+            WOLFSSL_MSG("EVP_AES_128_CFB128");
+            ctx->cipherType = AES_128_CFB128_TYPE;
+            ctx->flags     &= ~WOLFSSL_EVP_CIPH_MODE;
+            ctx->flags     |= WOLFSSL_EVP_CIPH_CFB_MODE;
+            ctx->keyLen     = 16;
+            ctx->block_size = 1;
+            if (enc == 0 || enc == 1)
+                ctx->enc = enc ? 1 : 0;
+            if (key) {
+                ret = AesSetKey_ex(&ctx->cipher.aes, key, ctx->keyLen, iv,
+                        AES_ENCRYPTION, 0);
+                if (ret != 0)
+                    return WOLFSSL_FAILURE;
+            }
+            if (iv && key == NULL) {
+                ret = wc_AesSetIV(&ctx->cipher.aes, iv);
+                if (ret != 0)
+                    return WOLFSSL_FAILURE;
+            }
+        }
+        #endif /* WOLFSSL_AES_128 */
+        #ifdef WOLFSSL_AES_192
+        if (ctx->cipherType == AES_192_CFB128_TYPE ||
+                 (type && XSTRNCMP(type, EVP_AES_192_CFB128, EVP_AESCFB_SIZE) == 0)) {
+            WOLFSSL_MSG("EVP_AES_192_CFB128");
+            ctx->cipherType = AES_192_CFB128_TYPE;
+            ctx->flags     &= ~WOLFSSL_EVP_CIPH_MODE;
+            ctx->flags     |= WOLFSSL_EVP_CIPH_CFB_MODE;
+            ctx->keyLen     = 24;
+            ctx->block_size = 1;
+            if (enc == 0 || enc == 1)
+                ctx->enc = enc ? 1 : 0;
+            if (key) {
+                ret = AesSetKey_ex(&ctx->cipher.aes, key, ctx->keyLen, iv,
+                            AES_ENCRYPTION, 0);
+                if (ret != 0)
+                    return WOLFSSL_FAILURE;
+            }
+            if (iv && key == NULL) {
+                ret = wc_AesSetIV(&ctx->cipher.aes, iv);
+                if (ret != 0)
+                    return WOLFSSL_FAILURE;
+            }
+        }
+        #endif /* WOLFSSL_AES_192 */
+        #ifdef WOLFSSL_AES_256
+        if (ctx->cipherType == AES_256_CFB128_TYPE ||
+                 (type && XSTRNCMP(type, EVP_AES_256_CFB128, EVP_AESCFB_SIZE) == 0)) {
+            WOLFSSL_MSG("EVP_AES_256_CFB128");
+            ctx->cipherType = AES_256_CFB128_TYPE;
+            ctx->flags     &= ~WOLFSSL_EVP_CIPH_MODE;
+            ctx->flags     |= WOLFSSL_EVP_CIPH_CFB_MODE;
+            ctx->keyLen     = 32;
+            ctx->block_size = 1;
+            if (enc == 0 || enc == 1)
+                ctx->enc = enc ? 1 : 0;
+            if (key) {
+                ret = AesSetKey_ex(&ctx->cipher.aes, key, ctx->keyLen, iv,
+                            AES_ENCRYPTION, 0);
+                if (ret != 0){
+                    WOLFSSL_MSG("AesSetKey() failed");
+                    return WOLFSSL_FAILURE;
+                }
+            }
+            if (iv && key == NULL) {
+                ret = wc_AesSetIV(&ctx->cipher.aes, iv);
+                if (ret != 0){
+                    WOLFSSL_MSG("wc_AesSetIV() failed");
+                    return WOLFSSL_FAILURE;
+                }
+            }
+        }
+        #endif /* WOLFSSL_AES_256 */
+    #endif /* HAVE_AES_CFB */
+    #ifdef WOLFSSL_AES_OFB
+        #ifdef WOLFSSL_AES_128
+        if (ctx->cipherType == AES_128_OFB_TYPE ||
+            (type && XSTRNCMP(type, EVP_AES_128_OFB, EVP_AES_SIZE) == 0)) {
+            WOLFSSL_MSG("EVP_AES_128_OFB");
+            ctx->cipherType = AES_128_OFB_TYPE;
+            ctx->flags     &= ~WOLFSSL_EVP_CIPH_MODE;
+            ctx->flags     |= WOLFSSL_EVP_CIPH_OFB_MODE;
+            ctx->keyLen     = 16;
+            ctx->block_size = 1;
+            if (enc == 0 || enc == 1)
+                ctx->enc = enc ? 1 : 0;
+            if (key) {
+                ret = AesSetKey_ex(&ctx->cipher.aes, key, ctx->keyLen, iv,
+                        AES_ENCRYPTION, 0);
+                if (ret != 0)
+                    return WOLFSSL_FAILURE;
+            }
+            if (iv && key == NULL) {
+                ret = wc_AesSetIV(&ctx->cipher.aes, iv);
+                if (ret != 0)
+                    return WOLFSSL_FAILURE;
+            }
+        }
+        #endif /* WOLFSSL_AES_128 */
+        #ifdef WOLFSSL_AES_192
+        if (ctx->cipherType == AES_192_OFB_TYPE ||
+                 (type && XSTRNCMP(type, EVP_AES_192_OFB, EVP_AES_SIZE) == 0)) {
+            WOLFSSL_MSG("EVP_AES_192_OFB");
+            ctx->cipherType = AES_192_OFB_TYPE;
+            ctx->flags     &= ~WOLFSSL_EVP_CIPH_MODE;
+            ctx->flags     |= WOLFSSL_EVP_CIPH_OFB_MODE;
+            ctx->keyLen     = 24;
+            ctx->block_size = 1;
+            if (enc == 0 || enc == 1)
+                ctx->enc = enc ? 1 : 0;
+            if (key) {
+                ret = AesSetKey_ex(&ctx->cipher.aes, key, ctx->keyLen, iv,
+                            AES_ENCRYPTION, 0);
+                if (ret != 0)
+                    return WOLFSSL_FAILURE;
+            }
+            if (iv && key == NULL) {
+                ret = wc_AesSetIV(&ctx->cipher.aes, iv);
+                if (ret != 0)
+                    return WOLFSSL_FAILURE;
+            }
+        }
+        #endif /* WOLFSSL_AES_192 */
+        #ifdef WOLFSSL_AES_256
+        if (ctx->cipherType == AES_256_OFB_TYPE ||
+                 (type && XSTRNCMP(type, EVP_AES_256_OFB, EVP_AES_SIZE) == 0)) {
+            WOLFSSL_MSG("EVP_AES_256_OFB");
+            ctx->cipherType = AES_256_OFB_TYPE;
+            ctx->flags     &= ~WOLFSSL_EVP_CIPH_MODE;
+            ctx->flags     |= WOLFSSL_EVP_CIPH_OFB_MODE;
+            ctx->keyLen     = 32;
+            ctx->block_size = 1;
+            if (enc == 0 || enc == 1)
+                ctx->enc = enc ? 1 : 0;
+            if (key) {
+                ret = AesSetKey_ex(&ctx->cipher.aes, key, ctx->keyLen, iv,
+                            AES_ENCRYPTION, 0);
+                if (ret != 0){
+                    WOLFSSL_MSG("AesSetKey() failed");
+                    return WOLFSSL_FAILURE;
+                }
+            }
+            if (iv && key == NULL) {
+                ret = wc_AesSetIV(&ctx->cipher.aes, iv);
+                if (ret != 0){
+                    WOLFSSL_MSG("wc_AesSetIV() failed");
+                    return WOLFSSL_FAILURE;
+                }
+            }
+        }
+        #endif /* WOLFSSL_AES_256 */
+    #endif /* HAVE_AES_OFB */
+    #ifdef WOLFSSL_AES_XTS
+        #ifdef WOLFSSL_AES_128
+        if (ctx->cipherType == AES_128_XTS_TYPE ||
+            (type && XSTRNCMP(type, EVP_AES_128_XTS, EVP_AES_SIZE) == 0)) {
+            WOLFSSL_MSG("EVP_AES_128_XTS");
+            ctx->cipherType = AES_128_XTS_TYPE;
+            ctx->flags     &= ~WOLFSSL_EVP_CIPH_MODE;
+            ctx->flags     |= WOLFSSL_EVP_CIPH_XTS_MODE;
+            ctx->keyLen     = 32;
+            ctx->block_size = 1;
+            ctx->ivSz       = AES_BLOCK_SIZE;
+
+            if (iv != NULL) {
+                if (iv != ctx->iv) /* Valgrind error when src == dst */
+                    XMEMCPY(ctx->iv, iv, ctx->ivSz);
+            }
+            else
+                XMEMSET(ctx->iv, 0, AES_BLOCK_SIZE);
+
+            if (enc == 0 || enc == 1)
+                ctx->enc = enc ? 1 : 0;
+            if (key) {
+                ret = wc_AesXtsSetKey(&ctx->cipher.xts, key, ctx->keyLen,
+                    ctx->enc ? AES_ENCRYPTION : AES_DECRYPTION, NULL, 0);
+                if (ret != 0) {
+                    WOLFSSL_MSG("wc_AesXtsSetKey() failed");
+                    return WOLFSSL_FAILURE;
+                }
+            }
+        }
+        #endif /* WOLFSSL_AES_128 */
+        #ifdef WOLFSSL_AES_256
+        if (ctx->cipherType == AES_256_XTS_TYPE ||
+                 (type && XSTRNCMP(type, EVP_AES_256_XTS, EVP_AES_SIZE) == 0)) {
+            WOLFSSL_MSG("EVP_AES_256_XTS");
+            ctx->cipherType = AES_256_XTS_TYPE;
+            ctx->flags     &= ~WOLFSSL_EVP_CIPH_MODE;
+            ctx->flags     |= WOLFSSL_EVP_CIPH_XTS_MODE;
+            ctx->keyLen     = 64;
+            ctx->block_size = 1;
+            ctx->ivSz       = AES_BLOCK_SIZE;
+
+            if (iv != NULL) {
+                if (iv != ctx->iv) /* Valgrind error when src == dst */
+                    XMEMCPY(ctx->iv, iv, ctx->ivSz);
+            }
+            else
+                XMEMSET(ctx->iv, 0, AES_BLOCK_SIZE);
+
+            if (enc == 0 || enc == 1)
+                ctx->enc = enc ? 1 : 0;
+            if (key) {
+                ret = wc_AesXtsSetKey(&ctx->cipher.xts, key, ctx->keyLen,
+                        ctx->enc ? AES_ENCRYPTION : AES_DECRYPTION, NULL, 0);
+                if (ret != 0) {
+                    WOLFSSL_MSG("wc_AesXtsSetKey() failed");
+                    return WOLFSSL_FAILURE;
+                }
+            }
+        }
+        #endif /* WOLFSSL_AES_256 */
+    #endif /* HAVE_AES_XTS */
+#endif /* NO_AES */
+
+#ifndef NO_DES3
+        if (ctx->cipherType == DES_CBC_TYPE ||
+                 (type && XSTRNCMP(type, EVP_DES_CBC, EVP_DES_SIZE) == 0)) {
+            WOLFSSL_MSG("EVP_DES_CBC");
+            ctx->cipherType = DES_CBC_TYPE;
+            ctx->flags     &= ~WOLFSSL_EVP_CIPH_MODE;
+            ctx->flags     |= WOLFSSL_EVP_CIPH_CBC_MODE;
+            ctx->keyLen     = 8;
+            ctx->block_size = DES_BLOCK_SIZE;
+            ctx->ivSz       = DES_BLOCK_SIZE;
+            if (enc == 0 || enc == 1)
+                ctx->enc = enc ? 1 : 0;
+            if (key) {
+                ret = wc_Des_SetKey(&ctx->cipher.des, key, iv,
+                          ctx->enc ? DES_ENCRYPTION : DES_DECRYPTION);
+                if (ret != 0)
+                    return WOLFSSL_FAILURE;
+            }
+
+            if (iv && key == NULL)
+                wc_Des_SetIV(&ctx->cipher.des, iv);
+        }
+#ifdef WOLFSSL_DES_ECB
+        else if (ctx->cipherType == DES_ECB_TYPE ||
+                 (type && XSTRNCMP(type, EVP_DES_ECB, EVP_DES_SIZE) == 0)) {
+            WOLFSSL_MSG("EVP_DES_ECB");
+            ctx->cipherType = DES_ECB_TYPE;
+            ctx->flags     &= ~WOLFSSL_EVP_CIPH_MODE;
+            ctx->flags     |= WOLFSSL_EVP_CIPH_ECB_MODE;
+            ctx->keyLen     = 8;
+            ctx->block_size = DES_BLOCK_SIZE;
+            if (enc == 0 || enc == 1)
+                ctx->enc = enc ? 1 : 0;
+            if (key) {
+                WOLFSSL_MSG("Des_SetKey");
+                ret = wc_Des_SetKey(&ctx->cipher.des, key, NULL,
+                          ctx->enc ? DES_ENCRYPTION : DES_DECRYPTION);
+                if (ret != 0)
+                    return WOLFSSL_FAILURE;
+            }
+        }
+#endif
+        else if (ctx->cipherType == DES_EDE3_CBC_TYPE ||
+                 (type &&
+                  XSTRNCMP(type, EVP_DES_EDE3_CBC, EVP_DES_EDE3_SIZE) == 0)) {
+            WOLFSSL_MSG("EVP_DES_EDE3_CBC");
+            ctx->cipherType = DES_EDE3_CBC_TYPE;
+            ctx->flags     &= ~WOLFSSL_EVP_CIPH_MODE;
+            ctx->flags     |= WOLFSSL_EVP_CIPH_CBC_MODE;
+            ctx->keyLen     = 24;
+            ctx->block_size = DES_BLOCK_SIZE;
+            ctx->ivSz       = DES_BLOCK_SIZE;
+            if (enc == 0 || enc == 1)
+                ctx->enc = enc ? 1 : 0;
+            if (key) {
+                ret = wc_Des3_SetKey(&ctx->cipher.des3, key, iv,
+                          ctx->enc ? DES_ENCRYPTION : DES_DECRYPTION);
+                if (ret != 0)
+                    return WOLFSSL_FAILURE;
+            }
+
+            if (iv && key == NULL) {
+                ret = wc_Des3_SetIV(&ctx->cipher.des3, iv);
+                if (ret != 0)
+                    return WOLFSSL_FAILURE;
+            }
+        }
+        else if (ctx->cipherType == DES_EDE3_ECB_TYPE ||
+                 (type &&
+                  XSTRNCMP(type, EVP_DES_EDE3_ECB, EVP_DES_EDE3_SIZE) == 0)) {
+            WOLFSSL_MSG("EVP_DES_EDE3_ECB");
+            ctx->cipherType = DES_EDE3_ECB_TYPE;
+            ctx->flags     &= ~WOLFSSL_EVP_CIPH_MODE;
+            ctx->flags     |= WOLFSSL_EVP_CIPH_ECB_MODE;
+            ctx->keyLen     = 24;
+            ctx->block_size = DES_BLOCK_SIZE;
+            if (enc == 0 || enc == 1)
+                ctx->enc = enc ? 1 : 0;
+            if (key) {
+                ret = wc_Des3_SetKey(&ctx->cipher.des3, key, NULL,
+                          ctx->enc ? DES_ENCRYPTION : DES_DECRYPTION);
+                if (ret != 0)
+                    return WOLFSSL_FAILURE;
+            }
+        }
+#endif /* NO_DES3 */
+#ifndef NO_RC4
+        if (ctx->cipherType == ARC4_TYPE || (type &&
+                                     XSTRNCMP(type, "ARC4", 4) == 0)) {
+            WOLFSSL_MSG("ARC4");
+            ctx->cipherType = ARC4_TYPE;
+            ctx->flags     &= ~WOLFSSL_EVP_CIPH_MODE;
+            ctx->flags     |= WOLFSSL_EVP_CIPH_STREAM_CIPHER;
+            ctx->block_size = 1;
+            if (ctx->keyLen == 0)  /* user may have already set */
+                ctx->keyLen = 16;  /* default to 128 */
+            if (key)
+                wc_Arc4SetKey(&ctx->cipher.arc4, key, ctx->keyLen);
+        }
+#endif /* NO_RC4 */
+#ifdef HAVE_IDEA
+        if (ctx->cipherType == IDEA_CBC_TYPE ||
+                 (type && XSTRNCMP(type, EVP_IDEA_CBC, EVP_IDEA_SIZE) == 0)) {
+            WOLFSSL_MSG("EVP_IDEA_CBC");
+            ctx->cipherType = IDEA_CBC_TYPE;
+            ctx->flags     &= ~WOLFSSL_EVP_CIPH_MODE;
+            ctx->flags     |= WOLFSSL_EVP_CIPH_CBC_MODE;
+            ctx->keyLen     = IDEA_KEY_SIZE;
+            ctx->block_size = 8;
+            ctx->ivSz       = IDEA_BLOCK_SIZE;
+            if (enc == 0 || enc == 1)
+                ctx->enc = enc ? 1 : 0;
+            if (key) {
+                ret = wc_IdeaSetKey(&ctx->cipher.idea, key, (word16)ctx->keyLen,
+                                    iv, ctx->enc ? IDEA_ENCRYPTION :
+                                                   IDEA_DECRYPTION);
+                if (ret != 0)
+                    return WOLFSSL_FAILURE;
+            }
+
+            if (iv && key == NULL)
+                wc_IdeaSetIV(&ctx->cipher.idea, iv);
+        }
+#endif /* HAVE_IDEA */
+        if (ctx->cipherType == NULL_CIPHER_TYPE || (type &&
+                                     XSTRNCMP(type, "NULL", 4) == 0)) {
+            WOLFSSL_MSG("NULL cipher");
+            ctx->cipherType = NULL_CIPHER_TYPE;
+            ctx->keyLen = 0;
+            ctx->block_size = 16;
+        }
+#ifdef HAVE_WOLFSSL_EVP_CIPHER_CTX_IV
+        if (iv && iv != ctx->iv) {
+            if (wolfSSL_StoreExternalIV(ctx) != WOLFSSL_SUCCESS) {
+                return WOLFSSL_FAILURE;
+            }
+        }
+#endif
+        (void)ret; /* remove warning. If execution reaches this point, ret=0 */
+        return WOLFSSL_SUCCESS;
+